From a3dab6a2b35eb8917c70cdaf40620798d1be846f Mon Sep 17 00:00:00 2001 From: joskfg Date: Mon, 26 Apr 2021 22:27:17 +0200 Subject: [PATCH] Upgrade (#4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Clean up W25QXXFlash class * Fix Creality RET6 env - RE (#19340) * [cron] Bump distribution date (2020-09-12) * Fix Print Stats appearance (#19348) * M872 wait for probe temperature (#19344) * [cron] Bump distribution date (2020-09-13) * Highlight Creality DWIN menu icons (#19368) * Update Italian language (#19365) * Fix EXP2 pin define for MKS SGEN_L (#19369) * Read from backup TMC StealthChop state (#19364) * Fix extra string substitution bug (#19351) * Touch UI "Leveling" menu, misc. fixes (#19349) * Allow SWD debug on Robin Nano (#19345) * heater_ind_t => heater_id_t * [cron] Bump distribution date (2020-09-14) * Improve temperature runaway, idle timeout (#19339) Co-authored-by: Scott Lahteine * Better choice of code Followup to #19344 * Always show Compiled: * M115 strings * Allow E3 V2 DWIN without EEPROM, POWER_LOSS_RECOVERY * Add missing FTDI EVE menu source (#19382) * More strict STATIC_ITEM_N (#19378) * Only set up SPI pins as needed (#19372) * [cron] Bump distribution date (2020-09-15) * [cron] Bump distribution date (2020-09-16) * E3 V2 DWIN cleanup * More DWIN cleanup * MarlinUI percent methods for all * [cron] Bump distribution date (2020-09-17) * Demo and test multiple PID defaults (#19413) * Fix missing spaces in info menu (#19404) * Add more DWIN commands, docs (#19395) * E3 V2 DWIN: Z-Offset, cleanup, versatility (#19384) Co-authored-by: Scott Lahteine * SHOW_REMAINING_TIME for HD44780 character LCD (#19416) * Add warning to ExtUI Bed Mesh Screen. (#19397) - Show a warning on the Mesh Bed Leveling screen if some points aren't probed. * Fix MKS UI SPI flash typo (#19410) * Expose JOYSTICK_DEBUG to the general user (#19394) Co-authored-by: Scott Lahteine * Update stale issue message and parameters (#19412) * Update stale issue bot * Update close-stale.yml * Update close-stale.yml Co-authored-by: Scott Lahteine * Host Action: Start (#19398) * Move screen for Color UI (#19386) * [cron] Bump distribution date (2020-09-18) * Fix missing include (#19418) Co-authored-by: ellensp <530024+ellensp@users.noreply.github.com> * [cron] Bump distribution date (2020-09-19) * Fix CoreXY compile with backlash cal. (#19422) * Change some dwin defines * Fix compile for Taz Pro (#19424) * Fix case light brightness save/load (#19436) * Optional Host Start menu item (#19443) * Ultratronics Pro SPI pins (#19444) * Fix Creality DWIN Control menu icons (#19441) * [cron] Bump distribution date (2020-09-20) * Whitespace cleanup * Add multi-extruder condition * Cleanup before MKS changes * Add HAS_ROTARY_ENCODER * [cron] Bump distribution date (2020-09-21) * Add MKS Robin E3P, improve LVGL UI (#19442) * Optional menu item for Assisted Tramming (#19447) * Replace Serial with Serial1 in pins files (#19459) * Update pins_ANET_10.h * [cron] Bump distribution date (2020-09-22) * Fix up K8800 pins (#19476) * Define ::softSPI (#19419) * MKS SGEN L V2 adaptable heaters/fans (#19462) * Update board/teensy comment (#19456) * Fix Teensy 4.1 include * [cron] Bump distribution date (2020-09-23) * Fix up tests, warnings * Catch a TMC address conflict early (#19458) * New Touch UI buttons (#19465) * Include pins.h in dependencies script (#19468) * MKS Robin Mini uses ONBOARD_SPI_DEVICE (#19460) * Teensy pins cleanup * Preserve brightness in EEPROM validate (#19485) Co-authored-by: Scott Lahteine * Define UART pins for LPC debug based on LPC_PINCFG_UART (#19475) * Whitespace cleanup * [cron] Bump distribution date (2020-09-24) * HAL and serial cleanup Co-Authored-By: Jason Smith <20053467+sjasonsmith@users.noreply.github.com> * HAL/serial followup * Fix some pin inits * [cron] Bump distribution date (2020-09-25) * Fix and improve STM32F1 serial (#19464) * BigTreeTech SKR E3 Turbo (#19500) * Sanity check old serial names * TFT: No timeout on Move Screen (#19426) * [cron] Bump distribution date (2020-09-26) * Escape the M33 string arg (#19515) * Fix MKS Robin undefined pins error (#19507) * Fix SKR 1.4 thermistor pin comments (#19510) * SKR E3 Turbo followup (#19513) * Fix MBL "Click to continue" on Color UI touchscreen (#19514) * Allow ColorUI color customization (#19484) * MMU2 S Mode spins the BMG gears during C0 (#19429) * [cron] Bump distribution date (2020-09-27) * Tweak MMU beeps, misc. cleanup * Drop extra Bed PID * Allow M524 between M23 and M24 * E3 DWIN: General cleanup * E3 DWIN: "No Media" message * CardReader cleanup * [cron] Bump distribution date (2020-09-28) * LVGL followup fixing "C", etc. (#19517) * Fix Allen Key Probe pin test (#19520) * Working LCD_USE_DMA_FSMC (#19522) * Thermistor: Kis3d Silicone heater + precision cast plate (#19528) * Update AnyCubic deps * Menu tweak * Prettier INI * Rename LCD conditionals (#19533) * MarlinUI for SPI/I2C TFT-GLCD character-based display bridge (#19375) * Update configs to 020007 * Tweaks to git helpers * Default E3 V2 to English * Change "Fr" on LCD to ">>" (#18830) * Multi-line comments cleanup (#19535) * Fix diveToFile with open Dir object (#19539) * Fix CardReader diveToFile * Add CardReader::fileExists * Improve Power-Loss Recovery (#19540) * Add extra CardReader debugging * Fetch longname when a file exists * Fix up E3 DWIN Power Panic * Anycubic Chiron full feature support (#19505) * [cron] Bump distribution date (2020-09-29) * Marlin 2.0.7 * Keep HAL tasks running during PID Autotune (#19671) * [cron] Bump distribution date (2020-09-30) * [cron] Bump distribution date (2020-10-01) * Fix Move Screen with disabled Touch (#19558) * Fix Buzzer (pin) init for uninitialized FastIO (#19559) * Update Slovak language (#19561) * No move on Park = No move on Resume (#19569) * Fix Anycubic i3 Mega target temperature display (#19572) Also includes a workaround for missing (probably un-fetched) long name in file listing * G35 workaround for Pronterface "feature" (#19577) * [cron] Bump distribution date (2020-10-02) * Minor SPI fixes, systick_callback for STM32F1 HAL compatibility (#19565) * Replace tabs with spaces * Adjust HAL platform defines, comments * Fix onboard SD card support for Teensy 3.6 & 4.1 (#19593) * Fix compile of MMU2 with S-mode disabled (#19584) * Fix TEMP_ADC_PROBE support for STM32F1 (#19582) Co-authored-by: ellensp * Fix wrappers on HAL/STM32F1 .cpp files (#19581) Co-authored-by: Scott Lahteine * Touch UI support for X2, Y2 and Z2 (#19538) * Fix 'bossac' upload on Windows (#19545) * [cron] Bump distribution date (2020-10-03) * [cron] Bump distribution date (2020-10-04) * Fix Tune/Fan edit items - Fixes #19617 - Followup to #18400 * Shared singlenozzle item * Fix German translation purging/unloading (#19615) * Move SF_ARC_FIX option * Fix Z_AFTER_HOMING without probe (#19607) * Add HAS_FAST_MOVES * Fix Archim1 stepper timing (with new variant) (#19596) * [cron] Bump distribution date (2020-10-05) * Allow bypass for cold E movement (#19606) * Z Probe Offset Wizard (#18866) * Sync config to examples * Trailing whitespace * [cron] Bump distribution date (2020-10-06) * Improve retract / unretract labels * Fix Ender-3 V2 DWIN Stop SD Print (#19642) Co-authored-by: Scott Lahteine * Add Chamber servo vent, auto fan (#19519) * Update language fonts * [cron] Bump distribution date (2020-10-07) * Fix small font section directive, mixer warning * Chamber vent/fan followup * Restore ° to 6x9 small info font (#19645) * More accessible PROBE_OFFSET_WIZARD (#19647) * [cron] Bump distribution date (2020-10-08) * Update PROBE_OFFSET_WIZARD comment (#19652) * Apply env:mega2560ext to relevant boards (#19624) * Use 0xFF (not 'ff') for byte transfer * Permit touch calibration override * Fix and improve Makefile / CMake (#19640) * [cron] Bump distribution date (2020-10-09) * Update Italian language (#19654) * Fix touch ifndefs (#19661) * Support for FLY MINI (#19185) * Support for Debug Codes - Dnnn (#19225) Co-authored-by: Scott Lahteine * Optional `M42`/`M226`; Add more features filters (#19664) * Batch appercase hex values * [cron] Bump distribution date (2020-10-10) * HAS_CHARACTER_LCD => HAS_MARLINUI_HD44780 (#19673) * Fixes for TFTGLCD Panel, FastIO (#19614) * Marlin 2.0.7.1 * TFT Refactoring (#19192) * split tft folder in two: tft for color ui; tft_io for shared tft code * after the files got moved, now the code was moved to the right place * classic ui using TFT IO init lcd codes * feature to compile tft_io when enabled * compiling fix * lvgl spi tft working with tft io init codes * there is no need for separeted fsmc and spi class in lvgl anymore, as tft io handle everything * remove debug * base for TFT rotation and mirroring API, and ILI9488 support * ST7796S rotate and mirror support * ST7789V rotate and mirror support * ST7735 rotate and mirror support * ILI9341 rotate and mirror support * ILI9328 rotate and mirror support * R61505 rotate and mirror support * MKS TFT definitions * more configs for mks tfts * update config * naming typo * to configure the user interface * ANYCUBIC_TFT35 * tft configs * support for SSD1963 * tft display types * updated conditionals lcd; first board fully working with the new code - all 3 ui! * compatiblity * changed name * move classic ui file name * rename TURN -> ROTATE * GRAPHICAL_TFT_ROTATE_180 deprecated * first fsmc board fully working - chitu v5 * mks robin nano v1.2 + tft 35 ok! * right pin name * anycubic tft tested in a TRIGORILLA_PRO * chitu v6 * nano 32 tft orientation * mks tft43 * mks tft43 rotation * fixed LONGER LK tft setup * GRAPHICAL_TFT_UPSCALE defined by the display type * better offsets defaults * Update Configuration.h * Update tft_fsmc.cpp * Update Conditionals_LCD.h * Tweak comments * update nano tests * Revert "update nano tests" This reverts commit a071ebbfad30e28855a4a5695ec8a726542a1a65. * default tft * outdated comments * to not break non-vscode builds * upscale tft 35 * support tft 180 rotation for color ui * Each TFT Driver is responsible for its default color mode. * use auto detect in mks displays, because some of them could be shipped with diferent drivers * extra s * unused code * wrong -1 * missing mirror options * Smaller regex pattern * Comment updates * Clean up old defines * Apply pins formatting * GRAPHICAL_TFT_ROTATE_180 => TFT_ROTATE_180 * MKS_ROBIN_TFT_V1_1R * merge fix * correct resolution * auto is default, dont need be there, and it will allow the user to configure it even for named displays * to not use rotation with MKS_ROBIN_TFT_V1_1R * i like () in macros * avoid sleepy commits * default for st7789 is rgb * nano follow up * to allow ili9328 rotation * default is rgb * boards merge follow up * to match bootloader orientation * HAS_TOUCH_XPT2046 is not hal specific anymore * lets not forget LPC * 180 rotation for ili9328 and R61505 * Clean up whitespace Co-authored-by: Scott Lahteine Co-authored-by: Scott Lahteine * G34 Mechanical Gantry Calibration (like Prusa M915) (#18972) Co-authored-by: Scott Lahteine * Sanity-check mutually-exclusive G34 features (#19706) * Fix screen click reading too often (#19696) Co-authored-by: andreibobirica <39415547+andreibobirica@users.noreply.github.com> * Option to prevent (extra) Watchdog init on STM32 (#19693) * Implement wait_for_user for Color UI (#19694) * Fix UTF8 handling for Color UI (#19708) * Fixes for TFTGLCD Panel, FastIO (#19614) * Restore correct STM32 port-bits code (#19678) * Save PLR on resume from pause (#19676) Co-Authored-By: shahab <32130261+SHBnik@users.noreply.github.com> * Digipots refactor / cleanup (#19690) * Fix at90usb1286 build (#19687) * Skip check for USBCON during dependency detection * Ignore incompatible Teensy_ADC library, which requires Teensy >= 3 * Add IS_AT90USB Co-authored-by: Scott Lahteine * Fix various errors, warnings in example config builds (#19686) Co-authored-by: Scott Lahteine * Fix I2C_ADDRESS sign warning (#19685) * Fix motion compile w/out probe-oriented settings (#19684) * Add REPORT_TRAMMING_MM option (#19682) Co-authored-by: Scott Lahteine * Allow MAX31865 resistance values configuration (#19695) * Add D100 Watchdog Test (#19697) * Add loose soft endstop state, apply to UBL fine-tune (#19681) Co-authored-by: Scott Lahteine * Fixes for TFTGLCD Panel, FastIO (#19614) * Restore correct STM32 port-bits code (#19678) * [cron] Bump distribution date (2020-10-11) * Fix various errors, warnings in example config builds (#19686) Co-authored-by: Scott Lahteine * [cron] Bump distribution date (2020-10-12) * [cron] Bump distribution date (2020-10-13) * Simple bool in soft_endstops_t * Fix SET_SOFT_ENDSTOP_LOOSE w/out soft endstops (#19734) * [cron] Bump distribution date (2020-10-14) * [cron] Bump distribution date (2020-10-15) * Fix mega2560ext environment (#19730) * Watchdog Refresh for LVGL Asset Load (#19724) * TFT followup fixes (#19710) * If needed, home before G34 (#19713) * Add NUCLEO-F767ZI dev board (#19373) Co-authored-by: Lorenzo Delana * Don't define IS_ULTIPANEL empty * Fix HAL/STM32 FastIO for analog pins (#19735) * Fix SAMD Serial name macro (#19765) * Marlin 2.0.7.2 * Update "Bug Report" template (#19906) * Fix bilinear_line_to_destination definition See #19431 * Fix extraneous Linear Advance DIR change (#20131) * Fix bad SET_FAST_PWM_FREQ calls (#20227) * Set "lcd_move_e" index to fix the label (#20263) * Help hosts when password-locked (#20348) * Fix TMC_HOME_PHASE divide by zero (#20368) * Fix TEMP_0_TR_ENABLE * Fixes for TFTGLCD (#20734) * Fix PR template, lock action Co-Authored-By: Jason Smith <20053467+sjasonsmith@users.noreply.github.com> * Ignore M22 during SD print * Trust XY after Quiet Probing short sleep (#21237) * Clean up labels on close * Token for "Clean Closed" action (#21320) * Remove one label at a time * Emojis and donate link * Add emojis * Change issue templates to YML * Enhance workflows * Auto-label Feature Requests (#21348) * Fix bool++ warning * Fix Hotend-abort-on-idle Check (#21535) * Sanity Check newer Configs too (#21550) Co-authored-by: Scott Lahteine * Keep 'confirmed bug' open * Fix check-pr action * 'issue_body' obsolete in templates * Update Issue Templates (#21702) * Fix SDIO buffer alignment (#21396) Co-authored-by: Scott Lahteine Co-authored-by: Keith Bennett <13375512+thisiskeithb@users.noreply.github.com> Co-authored-by: Haxk20 <16738302+Haxk20@users.noreply.github.com> Co-authored-by: Neskik Co-authored-by: Jesse S Co-authored-by: Giuliano Zaro <3684609+GMagician@users.noreply.github.com> Co-authored-by: Jason Smith Co-authored-by: ManuelMcLure Co-authored-by: ellensp Co-authored-by: Marcio T Co-authored-by: mmajoor Co-authored-by: Zachary Annand Co-authored-by: Victor Oliveira Co-authored-by: tovam Co-authored-by: enigmaquip Co-authored-by: cosmoderp <36945803+cosmoderp@users.noreply.github.com> Co-authored-by: deram Co-authored-by: jahartley <52391697+jahartley@users.noreply.github.com> Co-authored-by: InsanityAutomation <38436470+InsanityAutomation@users.noreply.github.com> Co-authored-by: ellensp <530024+ellensp@users.noreply.github.com> Co-authored-by: Cole Markham Co-authored-by: qwewer0 <57561110+qwewer0@users.noreply.github.com> Co-authored-by: makerbase <4164049@qq.com> Co-authored-by: Chris Pepper Co-authored-by: riodoro1 Co-authored-by: Jason Smith <20053467+sjasonsmith@users.noreply.github.com> Co-authored-by: Luke Harrison Co-authored-by: Trocololo Co-authored-by: Siana Gearz Co-authored-by: Tanguy Pruvot Co-authored-by: Emperor Co-authored-by: Serhiy-K <52166448+Serhiy-K@users.noreply.github.com> Co-authored-by: Pavel Melnikov Co-authored-by: Nick Co-authored-by: Roman Moravčík Co-authored-by: Ilya Co-authored-by: Stéphane <43587190+stef-ladefense@users.noreply.github.com> Co-authored-by: swissnorp <67485708+swissnorp@users.noreply.github.com> Co-authored-by: bilsef Co-authored-by: ellensp Co-authored-by: Ryan V1 <55478432+V1EngineeringInc@users.noreply.github.com> Co-authored-by: Scott Lahteine Co-authored-by: Speaka <48431623+Speaka@users.noreply.github.com> Co-authored-by: Cory Ory Co-authored-by: Mathew Winters Co-authored-by: signetica <66766598+signetica@users.noreply.github.com> Co-authored-by: ladismrkolj Co-authored-by: Samantaz Fox Co-authored-by: 石立枫 <49380822+FLYmaker@users.noreply.github.com> Co-authored-by: andreibobirica <39415547+andreibobirica@users.noreply.github.com> Co-authored-by: shahab <32130261+SHBnik@users.noreply.github.com> Co-authored-by: Earle F. Philhower, III Co-authored-by: Lorenzo Delana Co-authored-by: phcay <58492957+phcay@users.noreply.github.com> Co-authored-by: Simone Primarosa Co-authored-by: Luu Lac <45380455+shitcreek@users.noreply.github.com> Co-authored-by: ldursw <37294448+ldursw@users.noreply.github.com> --- .github/FUNDING.yml | 2 +- .github/ISSUE_TEMPLATE/bug_report.md | 43 - .github/ISSUE_TEMPLATE/bug_report.yml | 157 + .github/ISSUE_TEMPLATE/config.yml | 13 +- .github/ISSUE_TEMPLATE/feature_request.md | 35 - .github/ISSUE_TEMPLATE/feature_request.yml | 44 + .github/contributing.md | 21 +- .github/issue_template.md | 17 +- .github/lock.yml | 40 + .github/pull_request_template.md | 24 +- .github/workflows/bad-target.md | 7 - .github/workflows/bump-date.yml | 3 +- .github/workflows/check-pr.yml | 24 +- .github/workflows/clean-closed.yml | 39 + .github/workflows/close-stale.yml | 28 + .github/workflows/lock-closed.yml | 32 + .github/workflows/test-builds.yml | 54 +- .github/workflows/unlock-reopened.yml | 22 + .gitignore | 2 +- LICENSE | 9 +- Marlin/Configuration.h | 465 +- Marlin/Configuration_adv.h | 896 +- Marlin/Makefile | 296 +- Marlin/Marlin.ino | 26 +- Marlin/Version.h | 16 +- Marlin/lib/readme.txt | 2 +- Marlin/src/HAL/{HAL_AVR => AVR}/HAL.cpp | 3 +- Marlin/src/HAL/AVR/HAL.h | 191 + Marlin/src/HAL/{HAL_AVR => AVR}/HAL_SPI.cpp | 6 +- Marlin/src/HAL/AVR/MarlinSerial.cpp | 802 + .../src/HAL/{HAL_AVR => AVR}/MarlinSerial.h | 78 +- Marlin/src/HAL/{HAL_AVR => AVR}/Servo.cpp | 4 +- Marlin/src/HAL/{HAL_AVR => AVR}/ServoTimers.h | 10 +- .../eeprom.cpp} | 19 +- .../HAL/{HAL_AVR => AVR}/endstop_interrupts.h | 2 +- Marlin/src/HAL/{HAL_AVR => AVR}/fast_pwm.cpp | 14 +- Marlin/src/HAL/{HAL_AVR => AVR}/fastio.cpp | 52 +- Marlin/src/HAL/{HAL_AVR => AVR}/fastio.h | 24 +- .../HAL/{HAL_AVR => AVR}/fastio/fastio_1280.h | 4 +- .../HAL/{HAL_AVR => AVR}/fastio/fastio_1281.h | 2 +- .../HAL/{HAL_AVR => AVR}/fastio/fastio_168.h | 2 +- .../HAL/{HAL_AVR => AVR}/fastio/fastio_644.h | 2 +- .../{HAL_AVR => AVR}/fastio/fastio_AT90USB.h | 2 +- .../inc/Conditionals_LCD.h} | 8 +- .../{HAL_AVR => AVR}/inc/Conditionals_adv.h | 2 +- .../{HAL_DUE => AVR}/inc/Conditionals_post.h | 2 +- .../HAL/{HAL_AVR => AVR}/inc/SanityCheck.h | 21 +- Marlin/src/HAL/{HAL_AVR => AVR}/math.h | 2 +- Marlin/src/HAL/{HAL_AVR => AVR}/pinsDebug.h | 10 +- .../{HAL_AVR => AVR}/pinsDebug_Teensyduino.h | 2 +- .../HAL/{HAL_AVR => AVR}/pinsDebug_plus_70.h | 11 +- Marlin/src/HAL/{HAL_AVR => AVR}/spi_pins.h | 2 +- .../src/HAL/{HAL_AVR/HAL.h => AVR/timers.h} | 191 +- .../u8g_com_HAL_AVR_sw_spi.cpp | 10 +- Marlin/src/HAL/{HAL_AVR => AVR}/watchdog.cpp | 3 +- Marlin/src/HAL/{HAL_AVR => AVR}/watchdog.h | 2 +- .../src/HAL/{HAL_DUE => DUE}/DebugMonitor.cpp | 3 +- Marlin/src/HAL/{HAL_DUE => DUE}/HAL.cpp | 7 +- Marlin/src/HAL/{HAL_DUE => DUE}/HAL.h | 77 +- Marlin/src/HAL/{HAL_DUE => DUE}/HAL_SPI.cpp | 7 +- .../HAL/{HAL_DUE => DUE}/InterruptVectors.cpp | 2 +- .../HAL/{HAL_DUE => DUE}/InterruptVectors.h | 2 +- .../src/HAL/{HAL_DUE => DUE}/MarlinSerial.cpp | 26 +- .../src/HAL/{HAL_DUE => DUE}/MarlinSerial.h | 28 +- .../HAL/{HAL_DUE => DUE}/MarlinSerialUSB.cpp | 26 +- .../HAL/{HAL_DUE => DUE}/MarlinSerialUSB.h | 14 +- Marlin/src/HAL/{HAL_DUE => DUE}/Servo.cpp | 3 +- Marlin/src/HAL/{HAL_DUE => DUE}/ServoTimers.h | 0 Marlin/src/HAL/{HAL_DUE => DUE}/Tone.cpp | 5 +- .../dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp | 9 +- .../dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp | 2 +- .../dogm/u8g_com_HAL_DUE_sw_spi.cpp | 6 +- .../dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp | 10 +- .../dogm/u8g_com_HAL_DUE_sw_spi_shared.h | 2 +- .../eeprom_flash.cpp} | 237 +- .../eeprom_wired.cpp} | 37 +- .../endstop_interrupts.h | 46 +- Marlin/src/HAL/{HAL_DUE => DUE}/fastio.h | 8 +- Marlin/src/HAL/DUE/fastio/G2_PWM.cpp | 206 + .../src/HAL/{HAL_DUE => DUE}/fastio/G2_PWM.h | 4 +- .../src/HAL/{HAL_DUE => DUE}/fastio/G2_pins.h | 2 +- Marlin/src/HAL/DUE/inc/Conditionals_LCD.h | 26 + .../{HAL_DUE => DUE}/inc/Conditionals_adv.h | 2 +- Marlin/src/HAL/DUE/inc/Conditionals_post.h | 28 + .../HAL/{HAL_DUE => DUE}/inc/SanityCheck.h | 6 +- Marlin/src/HAL/{HAL_DUE => DUE}/pinsDebug.h | 3 +- Marlin/src/HAL/{HAL_DUE => DUE}/spi_pins.h | 2 +- Marlin/src/HAL/{HAL_DUE => DUE}/timers.cpp | 8 +- Marlin/src/HAL/{HAL_DUE => DUE}/timers.h | 28 +- Marlin/src/HAL/DUE/upload_extra_script.py | 18 + .../HAL/{HAL_DUE => DUE}/usb/arduino_due_x.h | 4 +- .../src/HAL/{HAL_DUE => DUE}/usb/compiler.h | 167 +- .../HAL/{HAL_DUE => DUE}/usb/conf_access.h | 2 +- .../src/HAL/{HAL_DUE => DUE}/usb/conf_clock.h | 2 +- .../src/HAL/{HAL_DUE => DUE}/usb/conf_usb.h | 6 +- .../HAL/{HAL_DUE => DUE}/usb/ctrl_access.c | 2 +- .../HAL/{HAL_DUE => DUE}/usb/ctrl_access.h | 2 +- Marlin/src/HAL/{HAL_DUE => DUE}/usb/genclk.h | 2 +- Marlin/src/HAL/{HAL_DUE => DUE}/usb/mrepeat.h | 2 +- Marlin/src/HAL/{HAL_DUE => DUE}/usb/osc.h | 2 +- Marlin/src/HAL/{HAL_DUE => DUE}/usb/pll.h | 2 +- .../HAL/{HAL_DUE => DUE}/usb/preprocessor.h | 2 +- .../HAL/{HAL_DUE => DUE}/usb/sbc_protocol.h | 2 +- .../{HAL_DUE => DUE}/usb/sd_mmc_spi_mem.cpp | 0 .../HAL/{HAL_DUE => DUE}/usb/sd_mmc_spi_mem.h | 2 +- .../HAL/{HAL_DUE => DUE}/usb/spc_protocol.h | 2 +- Marlin/src/HAL/{HAL_DUE => DUE}/usb/stringz.h | 2 +- Marlin/src/HAL/{HAL_DUE => DUE}/usb/sysclk.c | 2 +- Marlin/src/HAL/{HAL_DUE => DUE}/usb/sysclk.h | 2 +- Marlin/src/HAL/{HAL_DUE => DUE}/usb/tpaste.h | 2 +- Marlin/src/HAL/{HAL_DUE => DUE}/usb/udc.c | 2 +- Marlin/src/HAL/{HAL_DUE => DUE}/usb/udc.h | 2 +- .../src/HAL/{HAL_DUE => DUE}/usb/udc_desc.h | 2 +- Marlin/src/HAL/{HAL_DUE => DUE}/usb/udd.h | 2 +- Marlin/src/HAL/{HAL_DUE => DUE}/usb/udi.h | 2 +- Marlin/src/HAL/{HAL_DUE => DUE}/usb/udi_cdc.c | 2 +- Marlin/src/HAL/{HAL_DUE => DUE}/usb/udi_cdc.h | 4 +- .../HAL/{HAL_DUE => DUE}/usb/udi_cdc_conf.h | 2 +- .../HAL/{HAL_DUE => DUE}/usb/udi_cdc_desc.c | 2 +- .../{HAL_DUE => DUE}/usb/udi_composite_desc.c | 2 +- Marlin/src/HAL/{HAL_DUE => DUE}/usb/udi_msc.c | 2 +- Marlin/src/HAL/{HAL_DUE => DUE}/usb/udi_msc.h | 4 +- .../{HAL_DUE => DUE}/usb/uotghs_device_due.c | 2 +- .../{HAL_DUE => DUE}/usb/uotghs_device_due.h | 2 +- .../src/HAL/{HAL_DUE => DUE}/usb/uotghs_otg.h | 2 +- .../HAL/{HAL_DUE => DUE}/usb/usb_protocol.h | 2 +- .../{HAL_DUE => DUE}/usb/usb_protocol_cdc.h | 2 +- .../{HAL_DUE => DUE}/usb/usb_protocol_msc.h | 2 +- .../src/HAL/{HAL_DUE => DUE}/usb/usb_task.c | 2 +- .../src/HAL/{HAL_DUE => DUE}/usb/usb_task.h | 2 +- Marlin/src/HAL/{HAL_DUE => DUE}/watchdog.cpp | 3 +- Marlin/src/HAL/{HAL_DUE => DUE}/watchdog.h | 2 +- .../FlushableHardwareSerial.cpp | 2 +- .../FlushableHardwareSerial.h | 2 +- Marlin/src/HAL/{HAL_ESP32 => ESP32}/HAL.cpp | 61 +- Marlin/src/HAL/{HAL_ESP32 => ESP32}/HAL.h | 25 +- .../src/HAL/{HAL_ESP32 => ESP32}/HAL_SPI.cpp | 10 +- Marlin/src/HAL/{HAL_ESP32 => ESP32}/Servo.cpp | 6 +- Marlin/src/HAL/{HAL_ESP32 => ESP32}/Servo.h | 2 +- .../{HAL_ESP32 => ESP32}/WebSocketSerial.cpp | 7 +- .../{HAL_ESP32 => ESP32}/WebSocketSerial.h | 2 +- .../eeprom.cpp} | 26 +- .../{HAL_ESP32 => ESP32}/endstop_interrupts.h | 58 +- Marlin/src/HAL/{HAL_ESP32 => ESP32}/fastio.h | 4 +- Marlin/src/HAL/{HAL_ESP32 => ESP32}/i2s.cpp | 2 +- Marlin/src/HAL/{HAL_ESP32 => ESP32}/i2s.h | 2 +- Marlin/src/HAL/ESP32/inc/Conditionals_LCD.h | 26 + .../inc/Conditionals_adv.h | 2 +- .../inc/Conditionals_post.h | 2 +- .../{HAL_ESP32 => ESP32}/inc/SanityCheck.h | 6 +- Marlin/src/HAL/{HAL_ESP32 => ESP32}/ota.cpp | 3 +- Marlin/src/HAL/{HAL_ESP32 => ESP32}/ota.h | 3 +- .../HAL/{HAL_ESP32 => ESP32}/servotimers.h | 2 +- .../src/HAL/{HAL_ESP32 => ESP32}/spi_pins.h | 2 +- .../src/HAL/{HAL_ESP32 => ESP32}/spiffs.cpp | 3 +- Marlin/src/HAL/{HAL_ESP32 => ESP32}/spiffs.h | 2 +- .../src/HAL/{HAL_ESP32 => ESP32}/timers.cpp | 7 +- Marlin/src/HAL/{HAL_ESP32 => ESP32}/timers.h | 30 +- .../src/HAL/{HAL_ESP32 => ESP32}/watchdog.cpp | 3 +- .../src/HAL/{HAL_ESP32 => ESP32}/watchdog.h | 2 +- Marlin/src/HAL/{HAL_ESP32 => ESP32}/web.cpp | 3 +- Marlin/src/HAL/{HAL_ESP32 => ESP32}/web.h | 2 +- Marlin/src/HAL/{HAL_ESP32 => ESP32}/wifi.cpp | 3 +- Marlin/src/HAL/{HAL_ESP32 => ESP32}/wifi.h | 2 +- Marlin/src/HAL/HAL.h | 26 +- Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp | 792 - Marlin/src/HAL/HAL_DUE/fastio/G2_PWM.cpp | 145 - .../src/HAL/HAL_LINUX/inc/Conditionals_LCD.h | 22 - Marlin/src/HAL/HAL_LPC1768/HAL_SPI.cpp | 240 - .../HAL/HAL_LPC1768/inc/Conditionals_LCD.h | 22 - .../HAL/HAL_LPC1768/inc/Conditionals_adv.h | 22 - .../HAL/HAL_LPC1768/inc/Conditionals_post.h | 22 - Marlin/src/HAL/HAL_LPC1768/inc/SanityCheck.h | 127 - .../src/HAL/HAL_SAMD51/inc/Conditionals_LCD.h | 22 - .../src/HAL/HAL_SAMD51/inc/Conditionals_adv.h | 22 - .../HAL/HAL_SAMD51/inc/Conditionals_post.h | 22 - .../HAL_SAMD51/persistent_store_eeprom.cpp | 129 - .../HAL/HAL_STM32/Sd2Card_sdio_stm32duino.cpp | 274 - Marlin/src/HAL/HAL_STM32/SoftwareSerial.cpp | 395 - Marlin/src/HAL/HAL_STM32/SoftwareSerial.h | 119 - Marlin/src/HAL/HAL_STM32/endstop_interrupts.h | 70 - .../src/HAL/HAL_STM32/inc/Conditionals_LCD.h | 22 - .../src/HAL/HAL_STM32/inc/Conditionals_adv.h | 22 - .../src/HAL/HAL_STM32/inc/Conditionals_post.h | 22 - Marlin/src/HAL/HAL_STM32/inc/SanityCheck.h | 37 - .../HAL/HAL_STM32/persistent_store_impl.cpp | 97 - Marlin/src/HAL/HAL_STM32/timers.cpp | 139 - .../HAL/HAL_STM32F1/inc/Conditionals_LCD.h | 22 - .../HAL/HAL_STM32F1/inc/Conditionals_adv.h | 22 - .../HAL/HAL_STM32F1/inc/Conditionals_post.h | 22 - Marlin/src/HAL/HAL_STM32F1/msc_sd.h | 23 - .../HAL/HAL_STM32_F4_F7/endstop_interrupts.h | 70 - .../HAL_STM32_F4_F7/inc/Conditionals_LCD.h | 22 - .../HAL_STM32_F4_F7/inc/Conditionals_adv.h | 22 - .../HAL_STM32_F4_F7/inc/Conditionals_post.h | 22 - .../HAL_TEENSY31_32/inc/Conditionals_LCD.h | 22 - .../HAL_TEENSY31_32/inc/Conditionals_adv.h | 22 - .../HAL_TEENSY31_32/inc/Conditionals_post.h | 22 - .../HAL_TEENSY35_36/inc/Conditionals_LCD.h | 22 - .../HAL_TEENSY35_36/inc/Conditionals_adv.h | 22 - .../HAL_TEENSY35_36/inc/Conditionals_post.h | 22 - Marlin/src/HAL/{HAL_LINUX => LINUX}/HAL.cpp | 3 +- Marlin/src/HAL/{HAL_LINUX => LINUX}/HAL.h | 14 +- .../src/HAL/{HAL_LINUX => LINUX}/arduino.cpp | 17 +- .../eeprom.cpp} | 20 +- Marlin/src/HAL/{HAL_LINUX => LINUX}/fastio.h | 4 +- .../{HAL_LINUX => LINUX}/hardware/Clock.cpp | 3 +- .../HAL/{HAL_LINUX => LINUX}/hardware/Clock.h | 2 +- .../{HAL_LINUX => LINUX}/hardware/Gpio.cpp | 3 +- .../HAL/{HAL_LINUX => LINUX}/hardware/Gpio.h | 2 +- .../{HAL_LINUX => LINUX}/hardware/Heater.cpp | 3 +- .../{HAL_LINUX => LINUX}/hardware/Heater.h | 2 +- .../hardware/IOLoggerCSV.cpp | 3 +- .../hardware/IOLoggerCSV.h | 2 +- .../hardware/LinearAxis.cpp | 3 +- .../hardware/LinearAxis.h | 2 +- .../{HAL_LINUX => LINUX}/hardware/Timer.cpp | 3 +- .../HAL/{HAL_LINUX => LINUX}/hardware/Timer.h | 2 +- Marlin/src/HAL/LINUX/inc/Conditionals_LCD.h | 26 + .../inc/Conditionals_adv.h | 2 +- .../inc/Conditionals_post.h | 2 +- .../{HAL_LINUX => LINUX}/inc/SanityCheck.h | 6 +- .../{HAL_LINUX => LINUX}/include/Arduino.h | 8 +- .../include/pinmapping.cpp | 3 +- .../{HAL_LINUX => LINUX}/include/pinmapping.h | 2 +- .../HAL/{HAL_LINUX => LINUX}/include/serial.h | 6 +- Marlin/src/HAL/{HAL_LINUX => LINUX}/main.cpp | 5 +- .../src/HAL/{HAL_LINUX => LINUX}/pinsDebug.h | 2 +- .../HAL/{HAL_LINUX => LINUX}/servo_private.h | 3 +- .../src/HAL/{HAL_LINUX => LINUX}/spi_pins.h | 4 +- .../src/HAL/{HAL_LINUX => LINUX}/timers.cpp | 4 +- Marlin/src/HAL/{HAL_LINUX => LINUX}/timers.h | 22 +- .../src/HAL/{HAL_LINUX => LINUX}/watchdog.cpp | 3 +- .../src/HAL/{HAL_LINUX => LINUX}/watchdog.h | 2 +- .../{HAL_LPC1768 => LPC1768}/DebugMonitor.cpp | 9 +- .../src/HAL/{HAL_LPC1768 => LPC1768}/HAL.cpp | 11 +- Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/HAL.h | 72 +- Marlin/src/HAL/LPC1768/HAL_SPI.cpp | 405 + .../{HAL_LPC1768 => LPC1768}/MarlinSerial.cpp | 11 +- .../{HAL_LPC1768 => LPC1768}/MarlinSerial.h | 10 +- .../src/HAL/{HAL_LPC1768 => LPC1768}/Servo.h | 7 +- .../eeprom_flash.cpp} | 37 +- .../eeprom_sdcard.cpp} | 32 +- Marlin/src/HAL/LPC1768/eeprom_wired.cpp | 81 + .../endstop_interrupts.h | 2 +- .../HAL/{HAL_LPC1768 => LPC1768}/fast_pwm.cpp | 7 +- .../src/HAL/{HAL_LPC1768 => LPC1768}/fastio.h | 6 +- Marlin/src/HAL/LPC1768/inc/Conditionals_LCD.h | 26 + Marlin/src/HAL/LPC1768/inc/Conditionals_adv.h | 22 + .../src/HAL/LPC1768/inc/Conditionals_post.h | 28 + Marlin/src/HAL/LPC1768/inc/SanityCheck.h | 276 + Marlin/src/HAL/LPC1768/include/SPI.h | 176 + .../include/digipot_mcp4451_I2C_routines.c | 2 +- .../include/digipot_mcp4451_I2C_routines.h | 2 +- .../include/i2c_util.c | 2 +- .../include/i2c_util.h | 2 +- .../src/HAL/{HAL_LPC1768 => LPC1768}/main.cpp | 13 +- .../HAL/{HAL_LPC1768 => LPC1768}/pinsDebug.h | 2 +- .../HAL/{HAL_LPC1768 => LPC1768}/spi_pins.h | 4 +- Marlin/src/HAL/LPC1768/tft/tft_spi.cpp | 153 + Marlin/src/HAL/LPC1768/tft/tft_spi.h | 77 + Marlin/src/HAL/LPC1768/tft/xpt2046.cpp | 128 + Marlin/src/HAL/LPC1768/tft/xpt2046.h | 80 + .../HAL/{HAL_LPC1768 => LPC1768}/timers.cpp | 3 +- .../src/HAL/{HAL_LPC1768 => LPC1768}/timers.h | 47 +- .../u8g/LCD_I2C_routines.cpp | 2 +- .../u8g/LCD_I2C_routines.h | 2 +- .../u8g/LCD_defines.h | 2 +- .../{HAL_LPC1768 => LPC1768}/u8g/LCD_delay.h | 2 +- .../u8g/LCD_pin_routines.c | 2 +- .../u8g/LCD_pin_routines.h | 2 +- .../u8g/u8g_com_HAL_LPC1768_hw_spi.cpp | 6 +- .../u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp | 6 +- .../u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp | 6 +- .../u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp | 2 +- .../u8g/u8g_com_HAL_LPC1768_sw_spi.cpp | 22 +- .../upload_extra_script.py | 0 .../{HAL_LPC1768 => LPC1768}/usb_serial.cpp | 7 +- .../HAL/{HAL_LPC1768 => LPC1768}/watchdog.cpp | 3 +- .../HAL/{HAL_LPC1768 => LPC1768}/watchdog.h | 2 +- .../win_usb_driver/lpc176x_usb_driver.inf | 0 Marlin/src/HAL/{HAL_SAMD51 => SAMD51}/HAL.cpp | 106 +- Marlin/src/HAL/{HAL_SAMD51 => SAMD51}/HAL.h | 64 +- .../HAL/{HAL_SAMD51 => SAMD51}/HAL_SPI.cpp | 2 +- .../MarlinSerial_AGCM4.cpp | 3 +- .../MarlinSerial_AGCM4.h | 2 +- Marlin/src/HAL/SAMD51/QSPIFlash.cpp | 78 + Marlin/src/HAL/SAMD51/QSPIFlash.h | 50 + .../src/HAL/{HAL_SAMD51 => SAMD51}/SAMD51.h | 2 +- .../src/HAL/{HAL_SAMD51 => SAMD51}/Servo.cpp | 12 +- .../HAL/{HAL_SAMD51 => SAMD51}/ServoTimers.h | 2 +- Marlin/src/HAL/SAMD51/eeprom_flash.cpp | 95 + Marlin/src/HAL/SAMD51/eeprom_qspi.cpp | 71 + Marlin/src/HAL/SAMD51/eeprom_wired.cpp | 74 + .../endstop_interrupts.h | 29 +- .../src/HAL/{HAL_SAMD51 => SAMD51}/fastio.h | 8 +- Marlin/src/HAL/SAMD51/inc/Conditionals_LCD.h | 26 + Marlin/src/HAL/SAMD51/inc/Conditionals_adv.h | 22 + Marlin/src/HAL/SAMD51/inc/Conditionals_post.h | 28 + .../{HAL_SAMD51 => SAMD51}/inc/SanityCheck.h | 22 +- .../HAL/{HAL_SAMD51 => SAMD51}/pinsDebug.h | 3 +- .../src/HAL/{HAL_SAMD51 => SAMD51}/spi_pins.h | 2 +- .../src/HAL/{HAL_SAMD51 => SAMD51}/timers.cpp | 29 +- .../src/HAL/{HAL_SAMD51 => SAMD51}/timers.h | 35 +- .../HAL/{HAL_SAMD51 => SAMD51}/watchdog.cpp | 3 +- .../src/HAL/{HAL_SAMD51 => SAMD51}/watchdog.h | 2 +- Marlin/src/HAL/{HAL_STM32 => STM32}/HAL.cpp | 41 +- Marlin/src/HAL/{HAL_STM32 => STM32}/HAL.h | 112 +- .../src/HAL/{HAL_STM32 => STM32}/HAL_SPI.cpp | 16 +- Marlin/src/HAL/STM32/MarlinSerial.cpp | 86 + Marlin/src/HAL/STM32/MarlinSerial.h | 64 + Marlin/src/HAL/{HAL_STM32 => STM32}/README.md | 0 .../src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp | 321 + Marlin/src/HAL/STM32/Servo.cpp | 110 + Marlin/src/HAL/STM32/Servo.h | 54 + .../eeprom_flash.cpp} | 89 +- .../eeprom_sdcard.cpp} | 75 +- Marlin/src/HAL/STM32/eeprom_sram.cpp | 68 + Marlin/src/HAL/STM32/eeprom_wired.cpp | 81 + Marlin/src/HAL/STM32/endstop_interrupts.h | 49 + .../src/HAL/{HAL_STM32 => STM32}/fastio.cpp | 4 +- Marlin/src/HAL/{HAL_STM32 => STM32}/fastio.h | 23 +- .../inc/Conditionals_LCD.h | 2 +- Marlin/src/HAL/STM32/inc/Conditionals_adv.h | 22 + Marlin/src/HAL/STM32/inc/Conditionals_post.h | 29 + Marlin/src/HAL/STM32/inc/SanityCheck.h | 56 + .../src/HAL/{HAL_STM32 => STM32}/pinsDebug.h | 2 +- .../pinsDebug_STM32GENERIC.h | 8 +- .../pinsDebug_STM32duino.h | 12 +- .../src/HAL/{HAL_STM32 => STM32}/pins_Xref.h | 2 +- .../src/HAL/{HAL_STM32 => STM32}/spi_pins.h | 2 +- Marlin/src/HAL/STM32/tft/tft_fsmc.cpp | 180 + Marlin/src/HAL/STM32/tft/tft_fsmc.h | 160 + Marlin/src/HAL/STM32/tft/tft_spi.cpp | 212 + Marlin/src/HAL/STM32/tft/tft_spi.h | 67 + Marlin/src/HAL/STM32/tft/xpt2046.cpp | 185 + Marlin/src/HAL/STM32/tft/xpt2046.h | 86 + Marlin/src/HAL/STM32/timers.cpp | 280 + Marlin/src/HAL/{HAL_STM32 => STM32}/timers.h | 117 +- Marlin/src/HAL/STM32/usb_serial.cpp | 55 + Marlin/src/HAL/STM32/usb_serial.h | 21 + .../src/HAL/{HAL_STM32 => STM32}/watchdog.cpp | 9 +- .../src/HAL/{HAL_STM32 => STM32}/watchdog.h | 2 +- .../src/HAL/{HAL_STM32F1 => STM32F1}/HAL.cpp | 49 +- Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/HAL.h | 120 +- .../HAL/{HAL_STM32F1 => STM32F1}/HAL_SPI.cpp | 9 +- Marlin/src/HAL/STM32F1/MarlinSerial.cpp | 193 + Marlin/src/HAL/STM32F1/MarlinSerial.h | 71 + .../HAL/{HAL_STM32F1 => STM32F1}/README.md | 0 .../src/HAL/{HAL_STM32F1 => STM32F1}/SPI.cpp | 15 +- Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/SPI.h | 9 +- .../HAL/{HAL_STM32F1 => STM32F1}/Servo.cpp | 9 +- .../src/HAL/{HAL_STM32F1 => STM32F1}/Servo.h | 2 +- .../SoftwareSerial.cpp | 4 +- .../{HAL_STM32F1 => STM32F1}/SoftwareSerial.h | 2 +- .../{HAL_STM32F1 => STM32F1}/build_flags.py | 2 +- .../dogm/u8g_com_stm32duino_swspi.cpp | 23 +- Marlin/src/HAL/STM32F1/eeprom_bl24cxx.cpp | 84 + .../eeprom_flash.cpp} | 27 +- Marlin/src/HAL/STM32F1/eeprom_if_iic.cpp | 54 + .../eeprom_sdcard.cpp} | 74 +- .../eeprom_wired.cpp} | 26 +- .../endstop_interrupts.h | 59 +- .../src/HAL/{HAL_STM32F1 => STM32F1}/fastio.h | 2 +- Marlin/src/HAL/STM32F1/inc/Conditionals_LCD.h | 27 + Marlin/src/HAL/STM32F1/inc/Conditionals_adv.h | 22 + .../src/HAL/STM32F1/inc/Conditionals_post.h | 34 + .../inc/SanityCheck.h | 30 +- .../maple_win_usb_driver/maple_serial.inf | 0 .../HAL/{HAL_STM32F1 => STM32F1}/msc_sd.cpp | 28 +- Marlin/src/HAL/STM32F1/msc_sd.h | 42 + .../{HAL_STM32F1 => STM32F1}/onboard_sd.cpp | 26 +- .../HAL/{HAL_STM32F1 => STM32F1}/onboard_sd.h | 0 .../HAL/{HAL_STM32F1 => STM32F1}/pinsDebug.h | 6 +- .../src/HAL/{HAL_STM32F1 => STM32F1}/sdio.cpp | 27 +- .../src/HAL/{HAL_STM32F1 => STM32F1}/sdio.h | 12 +- .../HAL/{HAL_STM32F1 => STM32F1}/spi_pins.h | 2 +- .../tft/tft_fsmc.cpp} | 216 +- Marlin/src/HAL/STM32F1/tft/tft_fsmc.h | 71 + Marlin/src/HAL/STM32F1/tft/tft_spi.cpp | 149 + Marlin/src/HAL/STM32F1/tft/tft_spi.h | 72 + Marlin/src/HAL/STM32F1/tft/xpt2046.cpp | 141 + Marlin/src/HAL/STM32F1/tft/xpt2046.h | 80 + .../HAL/{HAL_STM32F1 => STM32F1}/timers.cpp | 20 +- .../src/HAL/{HAL_STM32F1 => STM32F1}/timers.h | 45 +- .../HAL/{HAL_STM32F1 => STM32F1}/watchdog.cpp | 6 +- .../HAL/{HAL_STM32F1 => STM32F1}/watchdog.h | 2 +- .../{HAL_STM32_F4_F7 => STM32_F4_F7}/HAL.cpp | 3 +- .../{HAL_STM32_F4_F7 => STM32_F4_F7}/HAL.h | 88 +- .../HAL_SPI.cpp | 11 +- .../README.md | 0 .../STM32F4/README.md | 0 .../STM32F4/timers.cpp | 6 +- .../STM32F4/timers.h | 32 +- .../STM32F7/README.md | 0 .../STM32F7/TMC2660.cpp | 62 +- .../STM32F7/TMC2660.h | 1 - .../STM32F7/timers.cpp | 6 +- .../STM32F7/timers.h | 22 +- .../Servo.cpp | 7 +- .../{HAL_STM32_F4_F7 => STM32_F4_F7}/Servo.h | 2 +- .../eeprom_emul.cpp | 14 +- .../eeprom_emul.h | 1 - .../eeprom_flash.cpp} | 123 +- .../eeprom_wired.cpp} | 28 +- .../src/HAL/STM32_F4_F7/endstop_interrupts.h | 49 + .../{HAL_STM32_F4_F7 => STM32_F4_F7}/fastio.h | 2 +- .../HAL/STM32_F4_F7/inc/Conditionals_LCD.h | 26 + .../HAL/STM32_F4_F7/inc/Conditionals_adv.h | 22 + .../HAL/STM32_F4_F7/inc/Conditionals_post.h | 29 + .../inc/SanityCheck.h | 6 +- .../pinsDebug.h | 6 +- .../spi_pins.h | 2 +- .../{HAL_STM32_F4_F7 => STM32_F4_F7}/timers.h | 2 +- .../watchdog.cpp | 3 +- .../watchdog.h | 2 +- .../{HAL_TEENSY31_32 => TEENSY31_32}/HAL.cpp | 5 +- .../{HAL_TEENSY31_32 => TEENSY31_32}/HAL.h | 33 +- .../HAL_SPI.cpp | 2 +- .../Servo.cpp | 7 +- .../{HAL_TEENSY31_32 => TEENSY31_32}/Servo.h | 2 +- .../eeprom.cpp} | 22 +- .../endstop_interrupts.h | 58 +- .../{HAL_TEENSY35_36 => TEENSY31_32}/fastio.h | 7 +- .../HAL/TEENSY31_32/inc/Conditionals_LCD.h | 26 + .../HAL/TEENSY31_32/inc/Conditionals_adv.h | 22 + .../inc/Conditionals_post.h | 6 +- .../inc/SanityCheck.h | 6 +- .../pinsDebug.h | 0 .../spi_pins.h | 2 +- .../timers.cpp | 7 +- .../{HAL_TEENSY31_32 => TEENSY31_32}/timers.h | 25 +- .../watchdog.cpp | 3 +- .../watchdog.h | 2 +- .../{HAL_TEENSY35_36 => TEENSY35_36}/HAL.cpp | 4 +- .../{HAL_TEENSY35_36 => TEENSY35_36}/HAL.h | 37 +- .../HAL_SPI.cpp | 9 +- .../Servo.cpp | 12 +- .../{HAL_TEENSY35_36 => TEENSY35_36}/Servo.h | 6 +- .../eeprom.cpp} | 24 +- .../endstop_interrupts.h | 60 +- .../{HAL_TEENSY31_32 => TEENSY35_36}/fastio.h | 7 +- .../HAL/TEENSY35_36/inc/Conditionals_LCD.h | 26 + .../HAL/TEENSY35_36/inc/Conditionals_adv.h | 22 + .../HAL/TEENSY35_36/inc/Conditionals_post.h | 26 + .../inc/SanityCheck.h | 6 +- .../pinsDebug.h | 6 +- .../spi_pins.h | 6 +- .../timers.cpp | 8 +- .../{HAL_TEENSY35_36 => TEENSY35_36}/timers.h | 27 +- .../watchdog.cpp | 3 +- .../watchdog.h | 2 +- Marlin/src/HAL/TEENSY40_41/HAL.cpp | 167 + Marlin/src/HAL/TEENSY40_41/HAL.h | 148 + Marlin/src/HAL/TEENSY40_41/HAL_SPI.cpp | 143 + .../HAL/{HAL_STM32 => TEENSY40_41}/Servo.cpp | 49 +- .../HAL/{HAL_STM32 => TEENSY40_41}/Servo.h | 24 +- Marlin/src/HAL/TEENSY40_41/eeprom.cpp | 76 + .../src/HAL/TEENSY40_41/endstop_interrupts.h | 66 + Marlin/src/HAL/TEENSY40_41/fastio.h | 58 + .../HAL/TEENSY40_41/inc/Conditionals_LCD.h | 26 + .../HAL/TEENSY40_41/inc/Conditionals_adv.h | 22 + .../HAL/TEENSY40_41/inc/Conditionals_post.h | 26 + Marlin/src/HAL/TEENSY40_41/inc/SanityCheck.h | 38 + Marlin/src/HAL/TEENSY40_41/pinsDebug.h | 150 + Marlin/src/HAL/TEENSY40_41/spi_pins.h | 31 + Marlin/src/HAL/TEENSY40_41/timers.cpp | 114 + Marlin/src/HAL/TEENSY40_41/timers.h | 119 + Marlin/src/HAL/TEENSY40_41/watchdog.cpp | 56 + Marlin/src/HAL/TEENSY40_41/watchdog.h | 30 + Marlin/src/HAL/platforms.h | 32 +- Marlin/src/HAL/shared/Delay.h | 5 +- Marlin/src/HAL/shared/HAL_SPI.h | 2 +- Marlin/src/HAL/shared/HAL_ST7920.h | 6 +- Marlin/src/HAL/shared/HAL_spi_L6470.cpp | 2 +- Marlin/src/HAL/shared/Marduino.h | 2 +- Marlin/src/HAL/shared/MarlinSerial.h | 67 - Marlin/src/HAL/shared/backtrace/backtrace.cpp | 3 +- Marlin/src/HAL/shared/backtrace/backtrace.h | 2 +- .../src/HAL/shared/backtrace/unwarm_thumb.cpp | 2 +- .../src/HAL/shared/backtrace/unwarmbytab.cpp | 2 +- .../src/HAL/shared/backtrace/unwmemaccess.cpp | 249 +- ...ersistent_store_api.cpp => eeprom_api.cpp} | 4 +- .../{persistent_store_api.h => eeprom_api.h} | 22 +- Marlin/src/HAL/shared/eeprom_i2c.cpp | 123 - Marlin/src/HAL/shared/eeprom_if.h | 29 + Marlin/src/HAL/shared/eeprom_if_i2c.cpp | 78 + .../{eeprom_spi.cpp => eeprom_if_spi.cpp} | 61 +- Marlin/src/HAL/shared/esp_wifi.cpp | 43 + .../Conditionals_LCD.h => shared/esp_wifi.h} | 4 +- Marlin/src/HAL/shared/math_32bit.h | 2 +- Marlin/src/HAL/shared/servo.cpp | 9 +- Marlin/src/HAL/shared/servo.h | 19 +- Marlin/src/HAL/shared/servo_private.h | 8 +- Marlin/src/MarlinCore.cpp | 833 +- Marlin/src/MarlinCore.h | 55 +- Marlin/src/core/boards.h | 228 +- Marlin/src/core/debug_out.h | 20 +- .../include/SPI.h => core/debug_section.h} | 43 +- Marlin/src/core/drivers.h | 164 +- Marlin/src/core/language.h | 51 +- Marlin/src/core/macros.h | 139 +- Marlin/src/core/millis_t.h | 6 +- Marlin/src/core/multi_language.cpp | 0 Marlin/src/core/multi_language.h | 10 +- Marlin/src/core/serial.cpp | 16 +- Marlin/src/core/serial.h | 47 +- Marlin/src/core/types.h | 53 +- Marlin/src/core/utility.cpp | 93 +- Marlin/src/core/utility.h | 5 +- Marlin/src/feature/babystep.cpp | 75 +- Marlin/src/feature/babystep.h | 9 +- Marlin/src/feature/backlash.cpp | 4 +- Marlin/src/feature/backlash.h | 24 +- Marlin/src/feature/baricuda.cpp | 2 +- Marlin/src/feature/baricuda.h | 2 +- Marlin/src/feature/bedlevel/abl/abl.cpp | 32 +- Marlin/src/feature/bedlevel/abl/abl.h | 2 +- Marlin/src/feature/bedlevel/bedlevel.cpp | 47 +- Marlin/src/feature/bedlevel/bedlevel.h | 2 +- .../bedlevel/mbl/mesh_bed_leveling.cpp | 12 +- .../feature/bedlevel/mbl/mesh_bed_leveling.h | 6 +- Marlin/src/feature/bedlevel/ubl/ubl.cpp | 47 +- Marlin/src/feature/bedlevel/ubl/ubl.h | 11 +- Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp | 502 +- .../src/feature/bedlevel/ubl/ubl_motion.cpp | 4 +- ...{binary_protocol.cpp => binary_stream.cpp} | 6 +- .../{binary_protocol.h => binary_stream.h} | 29 +- Marlin/src/feature/bltouch.cpp | 18 +- Marlin/src/feature/bltouch.h | 16 +- Marlin/src/feature/cancel_object.cpp | 4 +- Marlin/src/feature/cancel_object.h | 2 +- Marlin/src/feature/caselight.cpp | 50 +- Marlin/src/feature/caselight.h | 28 +- Marlin/src/feature/closedloop.cpp | 8 +- Marlin/src/feature/closedloop.h | 13 +- Marlin/src/feature/controllerfan.cpp | 91 +- Marlin/src/feature/controllerfan.h | 52 +- Marlin/src/feature/dac/dac_dac084s085.cpp | 6 +- Marlin/src/feature/dac/dac_dac084s085.h | 2 +- Marlin/src/feature/dac/dac_mcp4728.cpp | 58 +- Marlin/src/feature/dac/dac_mcp4728.h | 29 +- Marlin/src/feature/dac/stepper_dac.cpp | 69 +- Marlin/src/feature/dac/stepper_dac.h | 21 +- Marlin/src/feature/digipot/digipot.h | 14 +- .../src/feature/digipot/digipot_mcp4018.cpp | 85 +- .../src/feature/digipot/digipot_mcp4451.cpp | 48 +- Marlin/src/feature/direct_stepping.cpp | 262 + Marlin/src/feature/direct_stepping.h | 133 + .../{emergency_parser.cpp => e_parser.cpp} | 6 +- .../{emergency_parser.h => e_parser.h} | 22 +- ...I2CPositionEncoder.cpp => encoder_i2c.cpp} | 23 +- .../{I2CPositionEncoder.h => encoder_i2c.h} | 6 +- Marlin/src/feature/fanmux.cpp | 2 +- Marlin/src/feature/fanmux.h | 2 +- Marlin/src/feature/filwidth.cpp | 4 +- Marlin/src/feature/filwidth.h | 2 +- Marlin/src/feature/fwretract.cpp | 55 +- Marlin/src/feature/fwretract.h | 6 +- Marlin/src/feature/host_actions.cpp | 49 +- Marlin/src/feature/host_actions.h | 17 +- Marlin/src/feature/hotend_idle.cpp | 91 + Marlin/src/feature/hotend_idle.h | 37 + Marlin/src/feature/joystick.cpp | 9 +- Marlin/src/feature/joystick.h | 20 +- Marlin/src/feature/leds/blinkm.cpp | 2 +- Marlin/src/feature/leds/blinkm.h | 2 +- Marlin/src/feature/leds/leds.cpp | 88 +- Marlin/src/feature/leds/leds.h | 63 +- Marlin/src/feature/leds/neopixel.cpp | 89 +- Marlin/src/feature/leds/neopixel.h | 95 +- Marlin/src/feature/leds/pca9533.cpp | 127 + Marlin/src/feature/leds/pca9533.h | 59 + Marlin/src/feature/leds/pca9632.cpp | 6 +- Marlin/src/feature/leds/pca9632.h | 6 +- .../src/feature/leds/printer_event_leds.cpp | 12 +- Marlin/src/feature/leds/printer_event_leds.h | 4 +- Marlin/src/feature/leds/tempstat.cpp | 7 +- Marlin/src/feature/leds/tempstat.h | 2 +- .../{Max7219_Debug_LEDs.cpp => max7219.cpp} | 186 +- .../{Max7219_Debug_LEDs.h => max7219.h} | 17 +- Marlin/src/feature/mixing.cpp | 27 +- Marlin/src/feature/mixing.h | 52 +- .../src/feature/{prusa_MMU2 => mmu2}/mmu2.cpp | 464 +- .../src/feature/{prusa_MMU2 => mmu2}/mmu2.h | 34 +- .../{prusa_MMU2 => mmu2}/serial-protocol.md | 0 Marlin/src/feature/password/password.cpp | 58 + Marlin/src/feature/password/password.h | 57 + Marlin/src/feature/pause.cpp | 348 +- Marlin/src/feature/pause.h | 10 +- Marlin/src/feature/power.cpp | 37 +- Marlin/src/feature/power.h | 2 +- Marlin/src/feature/power_monitor.cpp | 75 + Marlin/src/feature/power_monitor.h | 142 + ...{power_loss_recovery.cpp => powerloss.cpp} | 294 +- .../{power_loss_recovery.h => powerloss.h} | 77 +- ...p_compensation.cpp => probe_temp_comp.cpp} | 67 +- ..._temp_compensation.h => probe_temp_comp.h} | 73 +- Marlin/src/feature/runout.cpp | 43 +- Marlin/src/feature/runout.h | 108 +- Marlin/src/feature/snmm.cpp | 2 +- Marlin/src/feature/snmm.h | 2 +- Marlin/src/feature/solenoid.cpp | 2 +- Marlin/src/feature/solenoid.h | 2 +- Marlin/src/feature/spindle_laser.cpp | 85 +- Marlin/src/feature/spindle_laser.h | 257 +- Marlin/src/feature/spindle_laser_types.h | 53 + Marlin/src/feature/tmc_util.cpp | 52 +- Marlin/src/feature/tmc_util.h | 66 +- Marlin/src/feature/touch/xpt2046.cpp | 146 - Marlin/src/feature/touch/xpt2046.h | 53 - Marlin/src/feature/twibus.cpp | 62 +- Marlin/src/feature/twibus.h | 14 +- Marlin/src/feature/z_stepper_align.cpp | 10 +- Marlin/src/feature/z_stepper_align.h | 2 +- Marlin/src/gcode/bedlevel/G26.cpp | 319 +- Marlin/src/gcode/bedlevel/G35.cpp | 190 + Marlin/src/gcode/bedlevel/G42.cpp | 2 +- Marlin/src/gcode/bedlevel/M420.cpp | 55 +- Marlin/src/gcode/bedlevel/abl/G29.cpp | 226 +- Marlin/src/gcode/bedlevel/abl/M421.cpp | 45 +- Marlin/src/gcode/bedlevel/mbl/G29.cpp | 33 +- Marlin/src/gcode/bedlevel/mbl/M421.cpp | 2 +- Marlin/src/gcode/bedlevel/ubl/G29.cpp | 2 +- Marlin/src/gcode/bedlevel/ubl/M421.cpp | 8 +- Marlin/src/gcode/calibrate/G28.cpp | 236 +- Marlin/src/gcode/calibrate/G33.cpp | 41 +- Marlin/src/gcode/calibrate/G34.cpp | 156 + Marlin/src/gcode/calibrate/G34_M422.cpp | 312 +- Marlin/src/gcode/calibrate/G425.cpp | 225 +- .../{G76_M871.cpp => G76_M192_M871.cpp} | 336 +- Marlin/src/gcode/calibrate/M100.cpp | 29 +- Marlin/src/gcode/calibrate/M12.cpp | 7 +- Marlin/src/gcode/calibrate/M425.cpp | 21 +- Marlin/src/gcode/calibrate/M48.cpp | 193 +- Marlin/src/gcode/calibrate/M665.cpp | 10 +- Marlin/src/gcode/calibrate/M666.cpp | 9 +- Marlin/src/gcode/calibrate/M852.cpp | 2 +- Marlin/src/gcode/config/M200-M205.cpp | 48 +- Marlin/src/gcode/config/M217.cpp | 116 +- Marlin/src/gcode/config/M218.cpp | 2 +- Marlin/src/gcode/config/M220.cpp | 9 +- Marlin/src/gcode/config/M221.cpp | 8 +- Marlin/src/gcode/config/M281.cpp | 9 +- Marlin/src/gcode/config/M301.cpp | 5 +- Marlin/src/gcode/config/M302.cpp | 4 +- Marlin/src/gcode/config/M304.cpp | 2 +- Marlin/src/gcode/config/M305.cpp | 4 +- Marlin/src/gcode/config/M43.cpp | 39 +- Marlin/src/gcode/config/M540.cpp | 2 +- Marlin/src/gcode/config/M575.cpp | 41 +- Marlin/src/gcode/config/M672.cpp | 27 +- Marlin/src/gcode/config/M92.cpp | 6 +- Marlin/src/gcode/control/M108_M112_M410.cpp | 6 +- Marlin/src/gcode/control/M111.cpp | 31 +- Marlin/src/gcode/control/M120_M121.cpp | 2 +- Marlin/src/gcode/control/M17_M18_M84.cpp | 20 +- Marlin/src/gcode/control/M211.cpp | 6 +- Marlin/src/gcode/control/M226.cpp | 8 +- Marlin/src/gcode/control/M280.cpp | 2 +- Marlin/src/gcode/control/M3-M5.cpp | 66 +- Marlin/src/gcode/control/M350_M351.cpp | 4 +- Marlin/src/gcode/control/M380_M381.cpp | 2 +- Marlin/src/gcode/control/M400.cpp | 2 +- Marlin/src/gcode/control/M42.cpp | 37 +- Marlin/src/gcode/control/M605.cpp | 8 +- Marlin/src/gcode/control/M7-M9.cpp | 2 +- Marlin/src/gcode/control/M80_M81.cpp | 31 +- Marlin/src/gcode/control/M85.cpp | 3 +- Marlin/src/gcode/control/M993_M994.cpp | 88 + Marlin/src/gcode/control/M997.cpp | 4 +- Marlin/src/gcode/control/M999.cpp | 7 +- Marlin/src/gcode/control/T.cpp | 22 +- Marlin/src/gcode/eeprom/M500-M504.cpp | 40 +- Marlin/src/gcode/feature/L6470/M122.cpp | 2 +- Marlin/src/gcode/feature/L6470/M906.cpp | 4 +- Marlin/src/gcode/feature/L6470/M916-918.cpp | 8 +- Marlin/src/gcode/feature/advance/M900.cpp | 123 +- .../src/gcode/feature/baricuda/M126-M129.cpp | 2 +- Marlin/src/gcode/feature/camera/M240.cpp | 20 +- Marlin/src/gcode/feature/cancel/M486.cpp | 2 +- Marlin/src/gcode/feature/caselight/M355.cpp | 78 +- Marlin/src/gcode/feature/clean/G12.cpp | 26 +- .../src/gcode/feature/controllerfan/M710.cpp | 81 + .../src/gcode/feature/digipot/M907-M910.cpp | 58 +- .../src/gcode/feature/filwidth/M404-M407.cpp | 2 +- .../src/gcode/feature/fwretract/G10_G11.cpp | 6 +- .../src/gcode/feature/fwretract/M207-M209.cpp | 2 +- Marlin/src/gcode/feature/i2c/M260_M261.cpp | 5 +- Marlin/src/gcode/feature/leds/M150.cpp | 35 +- Marlin/src/gcode/feature/leds/M7219.cpp | 6 +- Marlin/src/gcode/feature/macro/M810-M819.cpp | 2 +- Marlin/src/gcode/feature/mixing/M163-M165.cpp | 2 +- Marlin/src/gcode/feature/mixing/M166.cpp | 11 +- .../src/gcode/feature/password/M510-M512.cpp | 83 + Marlin/src/gcode/feature/pause/G27.cpp | 4 +- Marlin/src/gcode/feature/pause/G60.cpp | 3 +- Marlin/src/gcode/feature/pause/G61.cpp | 9 +- Marlin/src/gcode/feature/pause/M125.cpp | 33 +- Marlin/src/gcode/feature/pause/M600.cpp | 46 +- Marlin/src/gcode/feature/pause/M603.cpp | 5 +- Marlin/src/gcode/feature/pause/M701_M702.cpp | 54 +- .../src/gcode/feature/power_monitor/M430.cpp | 70 + Marlin/src/gcode/feature/powerloss/M1000.cpp | 16 +- Marlin/src/gcode/feature/powerloss/M413.cpp | 8 +- Marlin/src/gcode/feature/prusa_MMU2/M403.cpp | 4 +- Marlin/src/gcode/feature/runout/M412.cpp | 20 +- Marlin/src/gcode/feature/trinamic/M122.cpp | 16 +- Marlin/src/gcode/feature/trinamic/M569.cpp | 2 +- Marlin/src/gcode/feature/trinamic/M906.cpp | 6 +- .../src/gcode/feature/trinamic/M911-M914.cpp | 8 +- Marlin/src/gcode/gcode.cpp | 168 +- Marlin/src/gcode/gcode.h | 381 +- Marlin/src/gcode/gcode_d.cpp | 191 + Marlin/src/gcode/geometry/G17-G19.cpp | 2 +- Marlin/src/gcode/geometry/G53-G59.cpp | 2 +- Marlin/src/gcode/geometry/G92.cpp | 8 +- Marlin/src/gcode/geometry/M206_M428.cpp | 6 +- Marlin/src/gcode/host/M110.cpp | 7 +- Marlin/src/gcode/host/M113.cpp | 2 +- Marlin/src/gcode/host/M114.cpp | 39 +- Marlin/src/gcode/host/M115.cpp | 176 +- Marlin/src/gcode/host/M118.cpp | 12 +- Marlin/src/gcode/host/M119.cpp | 2 +- Marlin/src/gcode/host/M16.cpp | 4 +- Marlin/src/gcode/host/M360.cpp | 189 + Marlin/src/gcode/host/M876.cpp | 2 +- Marlin/src/gcode/lcd/M0_M1.cpp | 72 +- Marlin/src/gcode/lcd/M117.cpp | 2 +- Marlin/src/gcode/lcd/M145.cpp | 34 +- Marlin/src/gcode/lcd/M250.cpp | 2 +- Marlin/src/gcode/lcd/M300.cpp | 2 +- Marlin/src/gcode/lcd/M73.cpp | 5 +- Marlin/src/gcode/lcd/M995.cpp | 39 + Marlin/src/gcode/motion/G0_G1.cpp | 16 +- Marlin/src/gcode/motion/G2_G3.cpp | 59 +- Marlin/src/gcode/motion/G4.cpp | 2 +- Marlin/src/gcode/motion/G5.cpp | 4 +- Marlin/src/gcode/motion/G6.cpp | 61 + Marlin/src/gcode/motion/G80.cpp | 2 +- Marlin/src/gcode/motion/M290.cpp | 16 +- Marlin/src/gcode/parser.cpp | 86 +- Marlin/src/gcode/parser.h | 38 +- Marlin/src/gcode/probe/G30.cpp | 15 +- Marlin/src/gcode/probe/G31_G32.cpp | 2 +- Marlin/src/gcode/probe/G38.cpp | 6 +- Marlin/src/gcode/probe/M401_M402.cpp | 6 +- Marlin/src/gcode/probe/M851.cpp | 2 +- Marlin/src/gcode/probe/M951.cpp | 10 +- Marlin/src/gcode/queue.cpp | 174 +- Marlin/src/gcode/queue.h | 61 +- Marlin/src/gcode/scara/M360-M364.cpp | 2 +- Marlin/src/gcode/sd/M1001.cpp | 103 + Marlin/src/gcode/{sdcard => sd}/M20.cpp | 12 +- Marlin/src/gcode/{sdcard => sd}/M21_M22.cpp | 8 +- Marlin/src/gcode/{sdcard => sd}/M23.cpp | 6 +- Marlin/src/gcode/{sdcard => sd}/M24_M25.cpp | 32 +- Marlin/src/gcode/{sdcard => sd}/M26.cpp | 2 +- Marlin/src/gcode/{sdcard => sd}/M27.cpp | 2 +- Marlin/src/gcode/{sdcard => sd}/M28_M29.cpp | 8 +- Marlin/src/gcode/{sdcard => sd}/M30.cpp | 2 +- Marlin/src/gcode/{sdcard => sd}/M32.cpp | 3 +- Marlin/src/gcode/{sdcard => sd}/M33.cpp | 2 +- Marlin/src/gcode/{sdcard => sd}/M34.cpp | 2 +- Marlin/src/gcode/{sdcard => sd}/M524.cpp | 4 +- Marlin/src/gcode/{sdcard => sd}/M928.cpp | 2 +- Marlin/src/gcode/stats/M31.cpp | 2 +- Marlin/src/gcode/stats/M75-M78.cpp | 2 +- .../gcode/{temperature => temp}/M104_M109.cpp | 92 +- .../src/gcode/{temperature => temp}/M105.cpp | 2 +- .../gcode/{temperature => temp}/M106_M107.cpp | 38 +- Marlin/src/gcode/temp/M140_M190.cpp | 138 + .../gcode/{temperature => temp}/M141_M191.cpp | 21 +- .../src/gcode/{temperature => temp}/M155.cpp | 4 +- .../src/gcode/{temperature => temp}/M303.cpp | 52 +- Marlin/src/gcode/temperature/M140_M190.cpp | 88 - Marlin/src/gcode/units/G20_G21.cpp | 2 +- Marlin/src/gcode/units/M149.cpp | 2 +- Marlin/src/gcode/units/M82_M83.cpp | 2 +- Marlin/src/inc/Conditionals_LCD.h | 578 +- Marlin/src/inc/Conditionals_adv.h | 382 +- Marlin/src/inc/Conditionals_post.h | 1661 +- Marlin/src/inc/MarlinConfig.h | 34 +- Marlin/src/inc/MarlinConfigPre.h | 24 +- Marlin/src/inc/SanityCheck.h | 797 +- Marlin/src/inc/Version.h | 12 +- Marlin/src/lcd/HD44780/lcdprint_hd44780.cpp | 14 +- Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp | 232 +- Marlin/src/lcd/HD44780/ultralcd_HD44780.h | 33 +- Marlin/src/lcd/TFTGLCD/lcdprint_TFTGLCD.cpp | 1142 ++ Marlin/src/lcd/TFTGLCD/ultralcd_TFTGLCD.cpp | 964 + Marlin/src/lcd/TFTGLCD/ultralcd_TFTGLCD.h | 75 + Marlin/src/lcd/dogm/HAL_LCD_class_defines.h | 2 +- Marlin/src/lcd/dogm/HAL_LCD_com_defines.h | 14 +- Marlin/src/lcd/dogm/dogm_Bootscreen.h | 4 +- Marlin/src/lcd/dogm/dogm_Statusscreen.h | 100 +- .../lcd/dogm/fontdata/fontdata_6x9_marlin.h | 304 +- .../lcd/dogm/fontdata/fontdata_ISO10646_1.h | 512 +- Marlin/src/lcd/dogm/fontdata/langdata_bg.h | 74 +- Marlin/src/lcd/dogm/fontdata/langdata_cz.h | 48 +- Marlin/src/lcd/dogm/fontdata/langdata_el.h | 96 +- Marlin/src/lcd/dogm/fontdata/langdata_el_gr.h | 92 +- Marlin/src/lcd/dogm/fontdata/langdata_hr.h | 18 +- Marlin/src/lcd/dogm/fontdata/langdata_hu.h | 15 + .../src/lcd/dogm/fontdata/langdata_jp_kana.h | 130 +- Marlin/src/lcd/dogm/fontdata/langdata_ko_KR.h | 605 +- Marlin/src/lcd/dogm/fontdata/langdata_pl.h | 35 +- Marlin/src/lcd/dogm/fontdata/langdata_ro.h | 9 + Marlin/src/lcd/dogm/fontdata/langdata_ru.h | 107 +- Marlin/src/lcd/dogm/fontdata/langdata_sk.h | 62 +- Marlin/src/lcd/dogm/fontdata/langdata_test.h | 412 +- Marlin/src/lcd/dogm/fontdata/langdata_tr.h | 21 +- Marlin/src/lcd/dogm/fontdata/langdata_uk.h | 134 +- Marlin/src/lcd/dogm/fontdata/langdata_vi.h | 173 +- Marlin/src/lcd/dogm/fontdata/langdata_zh_CN.h | 2120 +- Marlin/src/lcd/dogm/fontdata/langdata_zh_TW.h | 1853 +- Marlin/src/lcd/dogm/lcdprint_u8g.cpp | 4 +- Marlin/src/lcd/dogm/status_screen_DOGM.cpp | 282 +- .../lcd/dogm/status_screen_lite_ST7920.cpp | 105 +- .../src/lcd/dogm/status_screen_lite_ST7920.h | 11 +- .../u8g_dev_ssd1306_sh1106_128x64_I2C.cpp | 6 +- .../lcd/dogm/u8g_dev_st7565_64128n_HAL.cpp | 6 +- .../lcd/dogm/u8g_dev_st7920_128x64_HAL.cpp | 10 +- ...8g_dev_tft_320x240_upscale_from_128x64.cpp | 718 - .../dogm/u8g_dev_tft_upscale_from_128x64.cpp | 480 + .../lcd/dogm/u8g_dev_uc1701_mini12864_HAL.cpp | 9 +- Marlin/src/lcd/dogm/u8g_fontutf8.cpp | 6 +- Marlin/src/lcd/dogm/ultralcd_DOGM.cpp | 154 +- Marlin/src/lcd/dogm/ultralcd_DOGM.h | 133 +- .../dogm/ultralcd_st7920_u8glib_rrd_AVR.cpp | 21 +- .../lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.h | 8 +- Marlin/src/lcd/dwin/dwin_lcd.cpp | 455 + Marlin/src/lcd/dwin/dwin_lcd.h | 213 + Marlin/src/lcd/dwin/e3v2/README.md | 7 + Marlin/src/lcd/dwin/e3v2/dwin.cpp | 3702 ++++ Marlin/src/lcd/dwin/e3v2/dwin.h | 373 + Marlin/src/lcd/dwin/e3v2/rotary_encoder.cpp | 254 + Marlin/src/lcd/dwin/e3v2/rotary_encoder.h | 104 + .../lib/dgus/DGUSDisplayDefinitionOrigin.cpp | 308 - .../lib/ftdi_eve_touch_ui/config.h | 124 - .../ftdi_eve_lib/basic/boards.h | 183 - .../extended/unicode/western_char_set.cpp | 449 - .../unicode/western_char_set_bitmap_31.h | 1315 -- .../lib/ftdi_eve_touch_ui/pin_mappings.h | 151 - .../screens/advanced_settings_menu.cpp | 205 - .../ftdi_eve_touch_ui/screens/main_menu.cpp | 148 - .../screens/stepper_current_screen.cpp | 86 - .../ftdi_eve_touch_ui/screens/tune_menu.cpp | 164 - .../lib/ftdi_eve_touch_ui/theme/colors.h | 149 - Marlin/src/lcd/extui/anycubic_chiron_lcd.cpp | 121 + Marlin/src/lcd/extui/anycubic_i3mega_lcd.cpp | 104 + .../dgus_lcd.cpp} | 60 +- .../{extui_example.cpp => extui/example.cpp} | 24 +- .../lib/anycubic_chiron/FileNavigator.cpp | 162 + .../extui/lib/anycubic_chiron/FileNavigator.h | 56 + .../lcd/extui/lib/anycubic_chiron/Tunes.cpp | 62 + .../src/lcd/extui/lib/anycubic_chiron/Tunes.h | 224 + .../extui/lib/anycubic_chiron/chiron_tft.cpp | 896 + .../extui/lib/anycubic_chiron/chiron_tft.h | 77 + .../lib/anycubic_chiron/chiron_tft_defs.h | 151 + .../anycubic_i3mega/anycubic_i3mega_lcd.cpp | 1032 + .../lib/anycubic_i3mega/anycubic_i3mega_lcd.h | 96 + Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.cpp | 263 + Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.h | 117 + .../lib/dgus/DGUSDisplayDef.h} | 12 +- .../lib/dgus/DGUSScreenHandler.cpp} | 487 +- .../lib/dgus/DGUSScreenHandler.h} | 115 +- .../lib/dgus/DGUSVPVariable.h | 4 +- .../lib/dgus/fysetc/DGUSDisplayDef.cpp} | 220 +- .../lib/dgus/fysetc/DGUSDisplayDef.h} | 20 +- .../lib/dgus/hiprecy/DGUSDisplayDef.cpp} | 211 +- .../lib/dgus/hiprecy/DGUSDisplayDef.h} | 3 +- .../extui/lib/dgus/origin/DGUSDisplayDef.cpp | 310 + .../lib/dgus/origin/DGUSDisplayDef.h} | 4 +- .../archim2-flash/flash_storage.cpp | 28 +- .../archim2-flash/flash_storage.h | 2 +- .../archim2-flash/media_file_reader.cpp | 2 +- .../archim2-flash/media_file_reader.h | 2 +- .../lib/ftdi_eve_touch_ui/compat.h | 2 +- .../lcd/extui/lib/ftdi_eve_touch_ui/config.h | 26 + .../ftdi_eve_lib/LICENSE.txt | 8 +- .../ftdi_eve_touch_ui/ftdi_eve_lib/README.md | 0 .../ftdi_eve_lib/basic/boards.h | 184 + .../ftdi_eve_lib/basic/commands.cpp | 160 +- .../ftdi_eve_lib/basic/commands.h | 3 +- .../ftdi_eve_lib/basic/constants.h | 2 +- .../ftdi_eve_lib/basic/display_list.h | 0 .../ftdi_eve_lib/basic/ftdi_basic.h | 2 +- .../ftdi_eve_lib/basic/registers_ft800.h | 4 +- .../ftdi_eve_lib/basic/registers_ft810.h | 4 +- .../ftdi_eve_lib/basic/resolutions.h | 13 +- .../ftdi_eve_lib/basic/spi.cpp | 52 +- .../ftdi_eve_lib/basic/spi.h | 14 +- .../ftdi_eve_touch_ui/ftdi_eve_lib/compat.h | 83 +- .../ftdi_eve_lib/extended/bitmap_info.h | 2 +- .../extended/command_processor.cpp | 2 +- .../ftdi_eve_lib/extended/command_processor.h | 13 +- .../ftdi_eve_lib/extended/dl_cache.cpp | 89 +- .../ftdi_eve_lib/extended/dl_cache.h | 26 +- .../ftdi_eve_lib/extended/event_loop.cpp | 20 +- .../ftdi_eve_lib/extended/event_loop.h | 2 +- .../ftdi_eve_lib/extended/ftdi_extended.h | 3 +- .../ftdi_eve_lib/extended/grid_layout.h | 6 +- .../ftdi_eve_lib/extended/polygon.h | 2 +- .../ftdi_eve_lib/extended/rgb_t.h | 2 +- .../ftdi_eve_lib/extended/screen_types.cpp | 7 +- .../ftdi_eve_lib/extended/screen_types.h | 20 +- .../ftdi_eve_lib/extended/sound_list.h | 6 +- .../ftdi_eve_lib/extended/sound_player.cpp | 5 +- .../ftdi_eve_lib/extended/sound_player.h | 2 +- .../ftdi_eve_lib/extended/text_box.cpp | 10 +- .../ftdi_eve_lib/extended/text_box.h | 2 +- .../ftdi_eve_lib/extended/text_ellipsis.cpp | 80 + .../ftdi_eve_lib/extended/text_ellipsis.h | 31 + .../ftdi_eve_lib/extended/tiny_timer.cpp | 2 +- .../ftdi_eve_lib/extended/tiny_timer.h | 2 +- .../ftdi_eve_lib/extended/unicode/README.txt | 0 .../extended/unicode/font_bitmaps.cpp | 5 +- .../extended/unicode/font_bitmaps.h | 2 +- .../unicode/font_bitmaps/romfont_31.pbm | Bin .../western_char_set_bitmap_31.png | Bin .../western_char_set_bitmap_31.svg | 0 .../extended/unicode/font_size_t.cpp | 4 +- .../extended/unicode/font_size_t.h | 2 +- .../extended/unicode/standard_char_set.cpp | 4 +- .../extended/unicode/standard_char_set.h | 2 +- .../ftdi_eve_lib/extended/unicode/unicode.cpp | 4 +- .../ftdi_eve_lib/extended/unicode/unicode.h | 2 +- .../extended/unicode/western_char_set.cpp | 450 + .../extended/unicode/western_char_set.h | 2 +- .../unicode/western_char_set_bitmap_31.h | 1315 ++ .../ftdi_eve_lib/extras/bitmap2cpp.py | 2 +- .../ftdi_eve_lib/extras/circular_progress.h | 2 +- .../ftdi_eve_lib/extras/poly_ui.h | 48 +- .../ftdi_eve_lib/extras/svg2cpp.py | 4 +- .../ftdi_eve_lib/ftdi_eve_lib.h | 2 +- .../ftdi_eve_touch_ui/language/language.cpp | 2 +- .../lib/ftdi_eve_touch_ui/language/language.h | 2 +- .../ftdi_eve_touch_ui/language/language_en.h | 26 +- .../lib/ftdi_eve_touch_ui/marlin_events.cpp | 46 +- .../lib/ftdi_eve_touch_ui/pin_mappings.h | 144 + .../screens/about_screen.cpp | 86 +- .../screens/advanced_settings_menu.cpp | 155 + .../screens/alert_dialog_box.cpp | 2 +- .../screens/backlash_compensation_screen.cpp | 2 +- .../base_numeric_adjustment_screen.cpp | 18 +- .../ftdi_eve_touch_ui/screens/base_screen.cpp | 10 +- .../screens/bed_mesh_screen.cpp | 353 + .../screens/bio_advanced_settings.cpp | 18 +- .../screens/bio_confirm_home_e.cpp | 14 +- .../screens/bio_confirm_home_xyz.cpp | 12 +- .../screens/bio_main_menu.cpp | 6 +- .../screens/bio_printer_ui_landscape.h | 2 +- .../screens/bio_printer_ui_portrait.h | 2 +- .../screens/bio_printing_dialog_box.cpp | 16 +- .../screens/bio_status_screen.cpp | 67 +- .../screens/bio_tune_menu.cpp | 8 +- .../ftdi_eve_touch_ui/screens/boot_screen.cpp | 20 +- .../screens/case_light_screen.cpp | 2 +- .../screens/change_filament_screen.cpp | 15 +- .../confirm_abort_print_dialog_box.cpp | 2 +- .../confirm_auto_calibration_dialog_box.cpp | 4 +- .../confirm_erase_flash_dialog_box.cpp | 2 +- .../confirm_start_print_dialog_box.cpp | 7 +- .../confirm_user_request_alert_box.cpp | 2 +- .../screens/default_acceleration_screen.cpp | 2 +- .../screens/developer_menu.cpp | 2 +- .../screens/dialog_box_base_class.cpp | 2 +- .../screens/display_tuning_screen.cpp | 2 +- .../screens/endstop_state_screen.cpp | 8 +- .../screens/feedrate_percent_screen.cpp | 2 +- .../screens/filament_menu.cpp | 67 +- .../screens/filament_runout_screen.cpp | 6 +- .../screens/files_screen.cpp | 28 +- .../screens/interface_settings_screen.cpp | 30 +- .../screens/interface_sounds_screen.cpp | 6 +- .../ftdi_eve_touch_ui/screens/jerk_screen.cpp | 2 +- .../screens/junction_deviation_screen.cpp | 4 +- .../ftdi_eve_touch_ui/screens/kill_screen.cpp | 2 +- .../screens/language_menu.cpp | 2 +- .../screens/leveling_menu.cpp | 125 + .../screens/linear_advance_screen.cpp | 6 +- .../ftdi_eve_touch_ui/screens/lock_screen.cpp | 20 +- .../ftdi_eve_touch_ui/screens/main_menu.cpp | 143 + .../screens/max_acceleration_screen.cpp | 16 +- .../screens/max_velocity_screen.cpp | 12 +- .../screens/media_player_screen.cpp | 2 +- .../screens/move_axis_screen.cpp | 8 +- .../screens/nozzle_offsets_screen.cpp | 4 +- .../screens/nudge_nozzle_screen.cpp | 16 +- .../screens/preheat_menu.cpp | 83 + .../screens/preheat_timer_screen.cpp | 5 +- .../screens/restore_failsafe_dialog_box.cpp | 2 +- .../screens/save_settings_dialog_box.cpp | 2 +- .../ftdi_eve_touch_ui/screens/screen_data.h | 59 +- .../lib/ftdi_eve_touch_ui/screens/screens.cpp | 23 +- .../lib/ftdi_eve_touch_ui/screens/screens.h | 178 +- .../screens/spinner_dialog_box.cpp | 2 +- .../screens/statistics_screen.cpp | 2 +- .../screens/status_screen.cpp | 265 +- .../stepper_bump_sensitivity_screen.cpp | 42 +- .../screens/stepper_current_screen.cpp | 127 + .../screens/steps_screen.cpp | 6 +- .../screens/stress_test_screen.cpp | 42 +- .../screens/string_format.cpp | 6 +- .../ftdi_eve_touch_ui/screens/string_format.h | 4 +- .../screens/temperature_screen.cpp | 20 +- .../screens/touch_calibration_screen.cpp | 8 +- .../screens/touch_registers_screen.cpp | 2 +- .../ftdi_eve_touch_ui/screens/tune_menu.cpp | 127 + .../screens/widget_demo_screen.cpp | 2 +- .../screens/z_offset_screen.cpp | 4 +- .../lib/ftdi_eve_touch_ui/theme/bitmaps.h | 2 +- .../theme/bootscreen_logo_portrait.h | 42 + .../lib/ftdi_eve_touch_ui/theme/colors.h | 183 + .../lib/ftdi_eve_touch_ui/theme/fonts.h | 2 +- .../theme/marlin_bootscreen_landscape.h | 6 +- .../theme/marlin_bootscreen_portrait.h | 6 +- .../lib/ftdi_eve_touch_ui/theme/sounds.cpp | 2 +- .../lib/ftdi_eve_touch_ui/theme/sounds.h | 2 +- .../lib/ftdi_eve_touch_ui/theme/theme.h | 2 +- .../lcd/extui/lib/mks_ui/SPIFlashStorage.cpp | 320 + .../lcd/extui/lib/mks_ui/SPIFlashStorage.h | 108 + Marlin/src/lcd/extui/lib/mks_ui/SPI_TFT.cpp | 88 + Marlin/src/lcd/extui/lib/mks_ui/SPI_TFT.h | 43 + .../src/lcd/extui/lib/mks_ui/draw_about.cpp | 125 + Marlin/src/lcd/extui/lib/mks_ui/draw_about.h | 34 + .../lib/mks_ui/draw_acceleration_settings.cpp | 449 + .../lib/mks_ui/draw_acceleration_settings.h | 33 + .../lib/mks_ui/draw_advance_settings.cpp | 334 + .../extui/lib/mks_ui/draw_advance_settings.h | 33 + .../draw_auto_level_offset_settings.cpp | 203 + .../mks_ui/draw_auto_level_offset_settings.h | 33 + .../extui/lib/mks_ui/draw_baby_stepping.cpp | 352 + .../lcd/extui/lib/mks_ui/draw_baby_stepping.h | 36 + .../extui/lib/mks_ui/draw_change_speed.cpp | 356 + .../lcd/extui/lib/mks_ui/draw_change_speed.h | 40 + .../src/lcd/extui/lib/mks_ui/draw_dialog.cpp | 703 + Marlin/src/lcd/extui/lib/mks_ui/draw_dialog.h | 88 + .../extui/lib/mks_ui/draw_eeprom_settings.cpp | 224 + .../extui/lib/mks_ui/draw_eeprom_settings.h | 33 + .../lib/mks_ui/draw_encoder_settings.cpp | 172 + .../extui/lib/mks_ui/draw_encoder_settings.h | 33 + .../extui/lib/mks_ui/draw_error_message.cpp | 86 + .../lcd/extui/lib/mks_ui/draw_error_message.h | 38 + .../lcd/extui/lib/mks_ui/draw_extrusion.cpp | 403 + .../src/lcd/extui/lib/mks_ui/draw_extrusion.h | 39 + Marlin/src/lcd/extui/lib/mks_ui/draw_fan.cpp | 265 + Marlin/src/lcd/extui/lib/mks_ui/draw_fan.h | 35 + .../extui/lib/mks_ui/draw_filament_change.cpp | 270 + .../extui/lib/mks_ui/draw_filament_change.h | 36 + .../lib/mks_ui/draw_filament_settings.cpp | 329 + .../extui/lib/mks_ui/draw_filament_settings.h | 33 + Marlin/src/lcd/extui/lib/mks_ui/draw_home.cpp | 252 + Marlin/src/lcd/extui/lib/mks_ui/draw_home.h | 34 + .../draw_homing_sensitivity_settings.cpp | 262 + .../mks_ui/draw_homing_sensitivity_settings.h | 33 + .../extui/lib/mks_ui/draw_jerk_settings.cpp | 237 + .../lcd/extui/lib/mks_ui/draw_jerk_settings.h | 33 + .../lcd/extui/lib/mks_ui/draw_keyboard.cpp | 286 + .../src/lcd/extui/lib/mks_ui/draw_keyboard.h | 33 + .../lcd/extui/lib/mks_ui/draw_language.cpp | 401 + .../src/lcd/extui/lib/mks_ui/draw_language.h | 34 + .../extui/lib/mks_ui/draw_level_settings.cpp | 261 + .../extui/lib/mks_ui/draw_level_settings.h | 33 + .../extui/lib/mks_ui/draw_machine_para.cpp | 290 + .../lcd/extui/lib/mks_ui/draw_machine_para.h | 33 + .../lib/mks_ui/draw_machine_settings.cpp | 254 + .../extui/lib/mks_ui/draw_machine_settings.h | 33 + .../lcd/extui/lib/mks_ui/draw_manuaLevel.cpp | 294 + .../lcd/extui/lib/mks_ui/draw_manuaLevel.h | 34 + .../mks_ui/draw_manual_level_pos_settings.cpp | 459 + .../mks_ui/draw_manual_level_pos_settings.h | 33 + .../lib/mks_ui/draw_max_feedrate_settings.cpp | 335 + .../lib/mks_ui/draw_max_feedrate_settings.h | 33 + .../extui/lib/mks_ui/draw_motor_settings.cpp | 343 + .../extui/lib/mks_ui/draw_motor_settings.h | 33 + .../lcd/extui/lib/mks_ui/draw_move_motor.cpp | 347 + .../lcd/extui/lib/mks_ui/draw_move_motor.h | 35 + .../lcd/extui/lib/mks_ui/draw_number_key.cpp | 981 + .../lcd/extui/lib/mks_ui/draw_number_key.h | 33 + .../lcd/extui/lib/mks_ui/draw_operation.cpp | 413 + .../src/lcd/extui/lib/mks_ui/draw_operation.h | 34 + .../extui/lib/mks_ui/draw_pause_message.cpp | 55 + .../lcd/extui/lib/mks_ui/draw_pause_message.h | 33 + .../extui/lib/mks_ui/draw_pause_position.cpp | 202 + .../extui/lib/mks_ui/draw_pause_position.h | 33 + .../src/lcd/extui/lib/mks_ui/draw_preHeat.cpp | 401 + .../src/lcd/extui/lib/mks_ui/draw_preHeat.h | 37 + .../lcd/extui/lib/mks_ui/draw_print_file.cpp | 640 + .../lcd/extui/lib/mks_ui/draw_print_file.h | 66 + .../lcd/extui/lib/mks_ui/draw_printing.cpp | 434 + .../src/lcd/extui/lib/mks_ui/draw_printing.h | 52 + .../lcd/extui/lib/mks_ui/draw_ready_print.cpp | 310 + .../lcd/extui/lib/mks_ui/draw_ready_print.h | 39 + Marlin/src/lcd/extui/lib/mks_ui/draw_set.cpp | 389 + Marlin/src/lcd/extui/lib/mks_ui/draw_set.h | 34 + .../extui/lib/mks_ui/draw_step_settings.cpp | 328 + .../lcd/extui/lib/mks_ui/draw_step_settings.h | 33 + .../lib/mks_ui/draw_tmc_current_settings.cpp | 387 + .../lib/mks_ui/draw_tmc_current_settings.h | 34 + .../mks_ui/draw_tmc_step_mode_settings.cpp | 586 + .../lib/mks_ui/draw_tmc_step_mode_settings.h | 33 + Marlin/src/lcd/extui/lib/mks_ui/draw_tool.cpp | 284 + Marlin/src/lcd/extui/lib/mks_ui/draw_tool.h | 34 + Marlin/src/lcd/extui/lib/mks_ui/draw_ui.cpp | 1631 ++ Marlin/src/lcd/extui/lib/mks_ui/draw_ui.h | 454 + Marlin/src/lcd/extui/lib/mks_ui/draw_wifi.cpp | 222 + Marlin/src/lcd/extui/lib/mks_ui/draw_wifi.h | 38 + .../lcd/extui/lib/mks_ui/draw_wifi_list.cpp | 235 + .../src/lcd/extui/lib/mks_ui/draw_wifi_list.h | 76 + .../extui/lib/mks_ui/draw_wifi_settings.cpp | 299 + .../lcd/extui/lib/mks_ui/draw_wifi_settings.h | 36 + .../lcd/extui/lib/mks_ui/draw_wifi_tips.cpp | 85 + .../src/lcd/extui/lib/mks_ui/draw_wifi_tips.h | 51 + .../lcd/extui/lib/mks_ui/gb2312_puhui16.cpp | 115 + .../src/lcd/extui/lib/mks_ui/irq_overrid.cpp | 69 + .../extui/lib/mks_ui/mks_hardware_test.cpp | 665 + .../lcd/extui/lib/mks_ui/mks_hardware_test.h | 33 + .../src/lcd/extui/lib/mks_ui/pic_manager.cpp | 626 + Marlin/src/lcd/extui/lib/mks_ui/pic_manager.h | 170 + .../extui/lib/mks_ui/printer_operation.cpp | 252 + .../lcd/extui/lib/mks_ui/printer_operation.h | 36 + .../lcd/extui/lib/mks_ui/tft_Language_en.h | 766 + .../lcd/extui/lib/mks_ui/tft_Language_fr.h | 281 + .../lcd/extui/lib/mks_ui/tft_Language_it.h | 276 + .../lcd/extui/lib/mks_ui/tft_Language_ru.h | 277 + .../lcd/extui/lib/mks_ui/tft_Language_s_cn.h | 499 + .../lcd/extui/lib/mks_ui/tft_Language_sp.h | 284 + .../lcd/extui/lib/mks_ui/tft_Language_t_cn.h | 499 + .../lib/mks_ui/tft_lvgl_configuration.cpp | 525 + .../extui/lib/mks_ui/tft_lvgl_configuration.h | 65 + .../extui/lib/mks_ui/tft_multi_language.cpp | 2631 +++ .../lcd/extui/lib/mks_ui/tft_multi_language.h | 837 + .../src/lcd/extui/lib/mks_ui/wifiSerial.cpp | 120 + Marlin/src/lcd/extui/lib/mks_ui/wifiSerial.h | 102 + .../src/lcd/extui/lib/mks_ui/wifi_module.cpp | 1927 ++ Marlin/src/lcd/extui/lib/mks_ui/wifi_module.h | 202 + .../src/lcd/extui/lib/mks_ui/wifi_upload.cpp | 829 + Marlin/src/lcd/extui/lib/mks_ui/wifi_upload.h | 74 + .../malyan_lcd.cpp} | 162 +- .../lcd/{extensible_ui => extui}/ui_api.cpp | 443 +- .../src/lcd/{extensible_ui => extui}/ui_api.h | 34 +- Marlin/src/lcd/fontutils.cpp | 5 +- Marlin/src/lcd/fontutils.h | 2 +- Marlin/src/lcd/language/language_an.h | 37 +- Marlin/src/lcd/language/language_bg.h | 38 +- Marlin/src/lcd/language/language_ca.h | 54 +- Marlin/src/lcd/language/language_cz.h | 83 +- Marlin/src/lcd/language/language_da.h | 49 +- Marlin/src/lcd/language/language_de.h | 217 +- Marlin/src/lcd/language/language_el.h | 46 +- Marlin/src/lcd/language/language_el_gr.h | 46 +- Marlin/src/lcd/language/language_en.h | 219 +- Marlin/src/lcd/language/language_es.h | 255 +- Marlin/src/lcd/language/language_eu.h | 55 +- Marlin/src/lcd/language/language_fi.h | 44 +- Marlin/src/lcd/language/language_fr.h | 121 +- Marlin/src/lcd/language/language_gl.h | 568 +- Marlin/src/lcd/language/language_hr.h | 38 +- Marlin/src/lcd/language/language_hu.h | 630 + Marlin/src/lcd/language/language_it.h | 172 +- Marlin/src/lcd/language/language_jp_kana.h | 52 +- Marlin/src/lcd/language/language_ko_KR.h | 26 +- Marlin/src/lcd/language/language_nl.h | 82 +- Marlin/src/lcd/language/language_pl.h | 160 +- Marlin/src/lcd/language/language_pt.h | 42 +- Marlin/src/lcd/language/language_pt_br.h | 149 +- Marlin/src/lcd/language/language_ro.h | 638 + Marlin/src/lcd/language/language_ru.h | 665 +- Marlin/src/lcd/language/language_sk.h | 171 +- Marlin/src/lcd/language/language_test.h | 5 +- Marlin/src/lcd/language/language_tr.h | 265 +- Marlin/src/lcd/language/language_uk.h | 770 +- Marlin/src/lcd/language/language_vi.h | 66 +- Marlin/src/lcd/language/language_zh_CN.h | 367 +- Marlin/src/lcd/language/language_zh_TW.h | 246 +- Marlin/src/lcd/lcdprint.cpp | 49 +- Marlin/src/lcd/lcdprint.h | 91 +- Marlin/src/lcd/menu/game/brickout.cpp | 8 +- Marlin/src/lcd/menu/game/brickout.h | 2 +- Marlin/src/lcd/menu/game/game.cpp | 2 +- Marlin/src/lcd/menu/game/game.h | 18 +- Marlin/src/lcd/menu/game/invaders.cpp | 8 +- Marlin/src/lcd/menu/game/invaders.h | 2 +- Marlin/src/lcd/menu/game/maze.cpp | 4 +- Marlin/src/lcd/menu/game/maze.h | 2 +- Marlin/src/lcd/menu/game/snake.cpp | 16 +- Marlin/src/lcd/menu/game/snake.h | 2 +- Marlin/src/lcd/menu/game/types.h | 2 +- Marlin/src/lcd/menu/menu.cpp | 261 +- Marlin/src/lcd/menu/menu.h | 421 +- Marlin/src/lcd/menu/menu_addon.h | 12 +- Marlin/src/lcd/menu/menu_advanced.cpp | 289 +- Marlin/src/lcd/menu/menu_backlash.cpp | 14 +- Marlin/src/lcd/menu/menu_bed_corners.cpp | 35 +- Marlin/src/lcd/menu/menu_bed_leveling.cpp | 41 +- Marlin/src/lcd/menu/menu_cancelobject.cpp | 26 +- Marlin/src/lcd/menu/menu_configuration.cpp | 200 +- Marlin/src/lcd/menu/menu_custom.cpp | 14 +- Marlin/src/lcd/menu/menu_delta_calibrate.cpp | 34 +- Marlin/src/lcd/menu/menu_filament.cpp | 150 +- Marlin/src/lcd/menu/menu_game.cpp | 12 +- Marlin/src/lcd/menu/menu_info.cpp | 196 +- Marlin/src/lcd/menu/menu_item.h | 492 + Marlin/src/lcd/menu/menu_job_recovery.cpp | 8 +- Marlin/src/lcd/menu/menu_led.cpp | 146 +- Marlin/src/lcd/menu/menu_main.cpp | 135 +- Marlin/src/lcd/menu/menu_media.cpp | 40 +- Marlin/src/lcd/menu/menu_mixer.cpp | 105 +- Marlin/src/lcd/menu/menu_mmu2.cpp | 17 +- Marlin/src/lcd/menu/menu_mmu2.h | 2 +- Marlin/src/lcd/menu/menu_motion.cpp | 272 +- Marlin/src/lcd/menu/menu_password.cpp | 184 + Marlin/src/lcd/menu/menu_power_monitor.cpp | 62 + Marlin/src/lcd/menu/menu_probe_offset.cpp | 138 + Marlin/src/lcd/menu/menu_spindle_laser.cpp | 26 +- Marlin/src/lcd/menu/menu_temperature.cpp | 281 +- Marlin/src/lcd/menu/menu_tmc.cpp | 26 +- Marlin/src/lcd/menu/menu_touch_screen.cpp | 36 + Marlin/src/lcd/menu/menu_tune.cpp | 112 +- Marlin/src/lcd/menu/menu_ubl.cpp | 506 +- Marlin/src/lcd/scaled_tft.h | 55 + Marlin/src/lcd/tft/bitmaps/back.bmp | Bin 0 -> 3126 bytes Marlin/src/lcd/tft/bitmaps/bed.bmp | Bin 0 -> 12342 bytes Marlin/src/lcd/tft/bitmaps/bed_heated.bmp | Bin 0 -> 12342 bytes .../src/lcd/tft/bitmaps/btn_64x52_rounded.bmp | Bin 0 -> 10040 bytes Marlin/src/lcd/tft/bitmaps/cancel.bmp | Bin 0 -> 12410 bytes Marlin/src/lcd/tft/bitmaps/chamber.bmp | Bin 0 -> 12342 bytes Marlin/src/lcd/tft/bitmaps/chamber_heated.bmp | Bin 0 -> 12342 bytes Marlin/src/lcd/tft/bitmaps/confirm.bmp | Bin 0 -> 12410 bytes Marlin/src/lcd/tft/bitmaps/decrease.bmp | Bin 0 -> 12410 bytes Marlin/src/lcd/tft/bitmaps/directory.bmp | Bin 0 -> 3194 bytes Marlin/src/lcd/tft/bitmaps/down.bmp | Bin 0 -> 3126 bytes Marlin/src/lcd/tft/bitmaps/fan0.bmp | Bin 0 -> 12410 bytes Marlin/src/lcd/tft/bitmaps/fan1.bmp | Bin 0 -> 12410 bytes Marlin/src/lcd/tft/bitmaps/fan_fast0.bmp | Bin 0 -> 12410 bytes Marlin/src/lcd/tft/bitmaps/fan_fast1.bmp | Bin 0 -> 12410 bytes Marlin/src/lcd/tft/bitmaps/fan_slow0.bmp | Bin 0 -> 12410 bytes Marlin/src/lcd/tft/bitmaps/fan_slow1.bmp | Bin 0 -> 12410 bytes Marlin/src/lcd/tft/bitmaps/feedrate.bmp | Bin 0 -> 3194 bytes Marlin/src/lcd/tft/bitmaps/flowrate.bmp | Bin 0 -> 3194 bytes Marlin/src/lcd/tft/bitmaps/home.bmp | Bin 0 -> 12344 bytes Marlin/src/lcd/tft/bitmaps/hotend.bmp | Bin 0 -> 12410 bytes Marlin/src/lcd/tft/bitmaps/increase.bmp | Bin 0 -> 12342 bytes Marlin/src/lcd/tft/bitmaps/left.bmp | Bin 0 -> 3194 bytes Marlin/src/lcd/tft/bitmaps/leveling.bmp | Bin 0 -> 3126 bytes .../bitmaps/marlin-logo/Marlin-1500x319.png | Bin 0 -> 387923 bytes .../tft/bitmaps/marlin-logo/Marlin-195x59.png | Bin 0 -> 18386 bytes .../marlin-logo/Marlin-228x255-greyscale.png | Bin 0 -> 7940 bytes .../bitmaps/marlin-logo/Marlin-228x255.png | Bin 0 -> 81470 bytes .../bitmaps/marlin-logo/Marlin-280x200.png | Bin 0 -> 46851 bytes .../bitmaps/marlin-logo/Marlin-320x240.png | Bin 0 -> 97523 bytes .../bitmaps/marlin-logo/Marlin-480x319.png | Bin 0 -> 168816 bytes .../bitmaps/marlin-logo/Marlin-480x320.png | Bin 0 -> 168834 bytes Marlin/src/lcd/tft/bitmaps/menu.bmp | Bin 0 -> 12342 bytes Marlin/src/lcd/tft/bitmaps/pause.bmp | Bin 0 -> 12410 bytes Marlin/src/lcd/tft/bitmaps/refresh.bmp | Bin 0 -> 3194 bytes Marlin/src/lcd/tft/bitmaps/right.bmp | Bin 0 -> 3194 bytes Marlin/src/lcd/tft/bitmaps/sd.bmp | Bin 0 -> 12410 bytes Marlin/src/lcd/tft/bitmaps/settings.bmp | Bin 0 -> 12342 bytes Marlin/src/lcd/tft/bitmaps/up.bmp | Bin 0 -> 3126 bytes Marlin/src/lcd/tft/canvas.cpp | 179 + Marlin/src/lcd/tft/canvas.h | 57 + .../src/lcd/tft/fontdata/fontdata_10x20.cpp | 257 + .../lcd/tft/fontdata/fontdata_ISO10646_1.cpp | 314 + .../lcd/tft/fontdata/helvetica_12_bold.cpp | 302 + Marlin/src/lcd/tft/fontdata/helvetica_14.cpp | 378 + Marlin/src/lcd/tft/fontdata/helvetica_18.cpp | 492 + Marlin/src/lcd/tft/fontdata/profont_22.cpp | 426 + Marlin/src/lcd/tft/images/back_32x32x4.cpp | 62 + .../lcd/tft/images/background_320x30x16.cpp | 60 + .../lcd/tft/images/bootscreen_112x38x1.cpp | 70 + .../lcd/tft/images/bootscreen_195x59x16.cpp | 89 + .../lcd/tft/images/bootscreen_228x255x2.cpp | 285 + .../lcd/tft/images/bootscreen_228x255x4.cpp | 285 + .../lcd/tft/images/bootscreen_320x240x16.cpp | 270 + .../lcd/tft/images/bootscreen_480x320x16.cpp | 350 + .../lcd/tft/images/btn_rounded_64x52x4.cpp | 82 + Marlin/src/lcd/tft/images/cancel_64x64x4.cpp | 94 + Marlin/src/lcd/tft/images/chamber_64x64x4.cpp | 161 + Marlin/src/lcd/tft/images/confirm_64x64x4.cpp | 94 + .../src/lcd/tft/images/decrease_64x64x4.cpp | 94 + .../src/lcd/tft/images/directory_32x32x4.cpp | 62 + Marlin/src/lcd/tft/images/down_32x32x4.cpp | 62 + Marlin/src/lcd/tft/images/fan_64x64x4.cpp | 161 + .../src/lcd/tft/images/fan_fast_64x64x4.cpp | 161 + .../src/lcd/tft/images/fan_slow_64x64x4.cpp | 161 + .../src/lcd/tft/images/feedrate_32x32x4.cpp | 62 + .../src/lcd/tft/images/flowrate_32x32x4.cpp | 62 + .../src/lcd/tft/images/heated_bed_64x64x4.cpp | 161 + Marlin/src/lcd/tft/images/home_64x64x4.cpp | 94 + Marlin/src/lcd/tft/images/hotend_64x64x4.cpp | 94 + .../src/lcd/tft/images/increase_64x64x4.cpp | 94 + Marlin/src/lcd/tft/images/left_32x32x4.cpp | 62 + .../src/lcd/tft/images/leveling_32x32x4.cpp | 62 + Marlin/src/lcd/tft/images/menu_64x64x4.cpp | 94 + Marlin/src/lcd/tft/images/pause_64x64x4.cpp | 94 + Marlin/src/lcd/tft/images/refresh_32x32x4.cpp | 62 + Marlin/src/lcd/tft/images/right_32x32x4.cpp | 62 + Marlin/src/lcd/tft/images/sd_64x64x4.cpp | 94 + .../src/lcd/tft/images/settings_64x64x4.cpp | 94 + Marlin/src/lcd/tft/images/slider_8x16x4.cpp | 46 + Marlin/src/lcd/tft/images/up_32x32x4.cpp | 62 + Marlin/src/lcd/tft/tft.cpp | 42 + Marlin/src/lcd/tft/tft.h | 91 + Marlin/src/lcd/tft/tft_color.h | 176 + Marlin/src/lcd/tft/tft_image.cpp | 71 + Marlin/src/lcd/tft/tft_image.h | 166 + Marlin/src/lcd/tft/tft_queue.cpp | 346 + Marlin/src/lcd/tft/tft_queue.h | 140 + Marlin/src/lcd/tft/tft_string.cpp | 169 + Marlin/src/lcd/tft/tft_string.h | 104 + Marlin/src/lcd/tft/touch.cpp | 316 + Marlin/src/lcd/tft/touch.h | 185 + Marlin/src/lcd/tft/ui_320x240.cpp | 656 + Marlin/src/lcd/tft/ui_320x240.h | 108 + Marlin/src/lcd/tft/ui_480x320.cpp | 1068 + Marlin/src/lcd/tft/ui_480x320.h | 108 + Marlin/src/lcd/tft_io/ili9328.h | 173 + Marlin/src/lcd/tft_io/ili9341.h | 170 + Marlin/src/lcd/tft_io/ili9488.h | 164 + Marlin/src/lcd/tft_io/r65105.h | 176 + Marlin/src/lcd/tft_io/ssd1963.h | 131 + Marlin/src/lcd/tft_io/st7735.h | 136 + Marlin/src/lcd/tft_io/st7789v.h | 156 + Marlin/src/lcd/tft_io/st7796s.h | 183 + Marlin/src/lcd/tft_io/tft_io.cpp | 226 + Marlin/src/lcd/tft_io/tft_io.h | 124 + Marlin/src/lcd/thermistornames.h | 14 +- Marlin/src/lcd/touch/touch_buttons.cpp | 112 + Marlin/src/lcd/touch/touch_buttons.h | 29 + Marlin/src/lcd/ultralcd.cpp | 790 +- Marlin/src/lcd/ultralcd.h | 378 +- Marlin/src/libs/BL24CXX.cpp | 273 + Marlin/src/libs/BL24CXX.h | 72 + Marlin/src/libs/L64XX/L64XX_Marlin.cpp | 8 +- Marlin/src/libs/L64XX/L64XX_Marlin.h | 2 +- Marlin/src/libs/W25Qxx.cpp | 388 + Marlin/src/libs/W25Qxx.h | 70 + Marlin/src/libs/bresenham.h | 2 +- Marlin/src/libs/buzzer.cpp | 7 +- Marlin/src/libs/buzzer.h | 6 +- Marlin/src/libs/circularqueue.h | 2 +- Marlin/src/libs/crc16.cpp | 2 +- Marlin/src/libs/crc16.h | 2 +- Marlin/src/libs/duration_t.h | 2 +- .../libs/heatshrink/heatshrink_decoder.cpp | 31 +- .../src/libs/heatshrink/heatshrink_decoder.h | 27 +- Marlin/src/libs/hex_print.cpp | 90 + .../{hex_print_routines.h => hex_print.h} | 8 +- Marlin/src/libs/hex_print_routines.cpp | 90 - Marlin/src/libs/least_squares_fit.cpp | 7 +- Marlin/src/libs/least_squares_fit.h | 3 +- Marlin/src/libs/nozzle.cpp | 115 +- Marlin/src/libs/nozzle.h | 2 +- Marlin/src/libs/numtostr.cpp | 132 +- Marlin/src/libs/numtostr.h | 45 +- Marlin/src/libs/private_spi.h | 4 +- Marlin/src/libs/softspi.h | 2 +- Marlin/src/libs/stopwatch.cpp | 39 +- Marlin/src/libs/stopwatch.h | 6 +- Marlin/src/libs/vector_3.cpp | 14 +- Marlin/src/libs/vector_3.h | 2 +- Marlin/src/module/delta.cpp | 45 +- Marlin/src/module/delta.h | 3 +- Marlin/src/module/endstops.cpp | 185 +- Marlin/src/module/endstops.h | 24 +- Marlin/src/module/motion.cpp | 582 +- Marlin/src/module/motion.h | 201 +- Marlin/src/module/planner.cpp | 968 +- Marlin/src/module/planner.h | 333 +- Marlin/src/module/planner_bezier.cpp | 4 +- Marlin/src/module/planner_bezier.h | 3 +- Marlin/src/module/printcounter.cpp | 47 +- Marlin/src/module/printcounter.h | 12 +- Marlin/src/module/probe.cpp | 239 +- Marlin/src/module/probe.h | 83 +- Marlin/src/module/scara.cpp | 10 +- Marlin/src/module/scara.h | 2 +- Marlin/src/module/servo.cpp | 6 +- Marlin/src/module/servo.h | 2 +- .../{configuration_store.cpp => settings.cpp} | 1243 +- .../{configuration_store.h => settings.h} | 12 +- Marlin/src/module/speed_lookuptable.h | 2 +- Marlin/src/module/stepper.cpp | 897 +- Marlin/src/module/stepper.h | 120 +- Marlin/src/module/stepper/L64xx.cpp | 2 +- Marlin/src/module/stepper/L64xx.h | 48 +- Marlin/src/module/stepper/TMC26X.cpp | 6 +- Marlin/src/module/stepper/TMC26X.h | 4 +- Marlin/src/module/stepper/indirection.cpp | 16 +- Marlin/src/module/stepper/indirection.h | 29 +- Marlin/src/module/stepper/trinamic.cpp | 294 +- Marlin/src/module/stepper/trinamic.h | 2 +- Marlin/src/module/temperature.cpp | 1317 +- Marlin/src/module/temperature.h | 329 +- Marlin/src/module/thermistor/thermistor_1.h | 4 +- Marlin/src/module/thermistor/thermistor_10.h | 4 +- .../src/module/thermistor/thermistor_1010.h | 6 +- .../src/module/thermistor/thermistor_1047.h | 12 +- Marlin/src/module/thermistor/thermistor_11.h | 4 +- Marlin/src/module/thermistor/thermistor_110.h | 6 +- Marlin/src/module/thermistor/thermistor_12.h | 4 +- Marlin/src/module/thermistor/thermistor_13.h | 4 +- Marlin/src/module/thermistor/thermistor_147.h | 6 +- Marlin/src/module/thermistor/thermistor_15.h | 4 +- Marlin/src/module/thermistor/thermistor_18.h | 4 +- Marlin/src/module/thermistor/thermistor_2.h | 6 +- Marlin/src/module/thermistor/thermistor_20.h | 6 +- Marlin/src/module/thermistor/thermistor_201.h | 6 +- Marlin/src/module/thermistor/thermistor_202.h | 69 + Marlin/src/module/thermistor/thermistor_21.h | 6 +- Marlin/src/module/thermistor/thermistor_22.h | 72 + Marlin/src/module/thermistor/thermistor_23.h | 128 + Marlin/src/module/thermistor/thermistor_3.h | 4 +- Marlin/src/module/thermistor/thermistor_30.h | 66 + Marlin/src/module/thermistor/thermistor_331.h | 4 +- Marlin/src/module/thermistor/thermistor_332.h | 4 +- Marlin/src/module/thermistor/thermistor_4.h | 4 +- Marlin/src/module/thermistor/thermistor_5.h | 6 +- Marlin/src/module/thermistor/thermistor_501.h | 4 +- Marlin/src/module/thermistor/thermistor_502.h | 60 + Marlin/src/module/thermistor/thermistor_51.h | 4 +- Marlin/src/module/thermistor/thermistor_512.h | 4 +- Marlin/src/module/thermistor/thermistor_52.h | 6 +- Marlin/src/module/thermistor/thermistor_55.h | 6 +- Marlin/src/module/thermistor/thermistor_6.h | 4 +- Marlin/src/module/thermistor/thermistor_60.h | 4 +- Marlin/src/module/thermistor/thermistor_61.h | 4 +- Marlin/src/module/thermistor/thermistor_66.h | 4 +- Marlin/src/module/thermistor/thermistor_666.h | 5 +- Marlin/src/module/thermistor/thermistor_67.h | 4 +- Marlin/src/module/thermistor/thermistor_7.h | 4 +- Marlin/src/module/thermistor/thermistor_70.h | 4 +- Marlin/src/module/thermistor/thermistor_71.h | 4 +- Marlin/src/module/thermistor/thermistor_75.h | 4 +- Marlin/src/module/thermistor/thermistor_8.h | 4 +- Marlin/src/module/thermistor/thermistor_9.h | 4 +- Marlin/src/module/thermistor/thermistor_99.h | 4 +- Marlin/src/module/thermistor/thermistor_998.h | 4 +- Marlin/src/module/thermistor/thermistor_999.h | 4 +- Marlin/src/module/thermistor/thermistors.h | 140 +- Marlin/src/module/tool_change.cpp | 784 +- Marlin/src/module/tool_change.h | 43 +- Marlin/src/pins/esp32/pins_E4D.h | 62 +- Marlin/src/pins/esp32/pins_ESP32.h | 60 +- Marlin/src/pins/esp32/pins_MRR_ESPA.h | 72 +- Marlin/src/pins/esp32/pins_MRR_ESPE.h | 140 +- Marlin/src/pins/linux/pins_RAMPS_LINUX.h | 468 +- Marlin/src/pins/lpc1768/pins_AZSMZ_MINI.h | 114 +- Marlin/src/pins/lpc1768/pins_BIQU_B300_V1.0.h | 101 +- Marlin/src/pins/lpc1768/pins_BIQU_BQ111_A4.h | 92 +- Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_1.h | 155 +- Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_3.h | 290 +- Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_4.h | 347 +- Marlin/src/pins/lpc1768/pins_BTT_SKR_common.h | 61 +- Marlin/src/pins/lpc1768/pins_GMARSH_X6_REV1.h | 140 +- Marlin/src/pins/lpc1768/pins_MKS_SBASE.h | 284 +- Marlin/src/pins/lpc1768/pins_MKS_SGEN_L.h | 274 +- Marlin/src/pins/lpc1768/pins_RAMPS_RE_ARM.h | 351 +- Marlin/src/pins/lpc1768/pins_SELENA_COMPACT.h | 95 +- Marlin/src/pins/lpc1769/pins_AZTEEG_X5_GT.h | 96 +- Marlin/src/pins/lpc1769/pins_AZTEEG_X5_MINI.h | 154 +- .../pins/lpc1769/pins_AZTEEG_X5_MINI_WIFI.h | 4 +- .../src/pins/lpc1769/pins_BTT_SKR_E3_TURBO.h | 260 + .../pins/lpc1769/pins_BTT_SKR_V1_4_TURBO.h | 4 +- .../src/pins/lpc1769/pins_COHESION3D_MINI.h | 131 +- .../src/pins/lpc1769/pins_COHESION3D_REMIX.h | 225 +- Marlin/src/pins/lpc1769/pins_MKS_SGEN.h | 45 +- Marlin/src/pins/lpc1769/pins_MKS_SGEN_L_V2.h | 367 + Marlin/src/pins/lpc1769/pins_SMOOTHIEBOARD.h | 163 +- Marlin/src/pins/lpc1769/pins_TH3D_EZBOARD.h | 129 +- Marlin/src/pins/mega/pins_CHEAPTRONIC.h | 52 +- Marlin/src/pins/mega/pins_CHEAPTRONICv2.h | 116 +- Marlin/src/pins/mega/pins_CNCONTROLS_11.h | 148 +- Marlin/src/pins/mega/pins_CNCONTROLS_12.h | 154 +- Marlin/src/pins/mega/pins_CNCONTROLS_15.h | 97 +- Marlin/src/pins/mega/pins_EINSTART-S.h | 72 +- Marlin/src/pins/mega/pins_ELEFU_3.h | 108 +- Marlin/src/pins/mega/pins_GT2560_REV_A.h | 138 +- Marlin/src/pins/mega/pins_GT2560_REV_A_PLUS.h | 6 +- Marlin/src/pins/mega/pins_GT2560_V3.h | 120 +- Marlin/src/pins/mega/pins_GT2560_V3_A20.h | 18 +- Marlin/src/pins/mega/pins_GT2560_V3_MC2.h | 10 +- Marlin/src/pins/mega/pins_HJC2560C_REV2.h | 137 +- Marlin/src/pins/mega/pins_INTAMSYS40.h | 151 + Marlin/src/pins/mega/pins_LEAPFROG.h | 70 +- Marlin/src/pins/mega/pins_LEAPFROG_XEED2015.h | 76 +- Marlin/src/pins/mega/pins_MEGACONTROLLER.h | 117 +- Marlin/src/pins/mega/pins_MEGATRONICS.h | 105 +- Marlin/src/pins/mega/pins_MEGATRONICS_2.h | 125 +- Marlin/src/pins/mega/pins_MEGATRONICS_3.h | 171 +- Marlin/src/pins/mega/pins_MIGHTYBOARD_REVE.h | 223 +- Marlin/src/pins/mega/pins_MINITRONICS.h | 113 +- Marlin/src/pins/mega/pins_OVERLORD.h | 106 +- Marlin/src/pins/mega/pins_PICA.h | 116 +- Marlin/src/pins/mega/pins_PICAOLD.h | 10 +- Marlin/src/pins/mega/pins_SILVER_GATE.h | 96 +- Marlin/src/pins/mega/pins_WANHAO_ONEPLUS.h | 74 +- Marlin/src/pins/pins.h | 523 +- Marlin/src/pins/pinsDebug.h | 154 +- Marlin/src/pins/pinsDebug_list.h | 147 +- Marlin/src/pins/rambo/pins_EINSY_RAMBO.h | 143 +- Marlin/src/pins/rambo/pins_EINSY_RETRO.h | 158 +- Marlin/src/pins/rambo/pins_MINIRAMBO.h | 158 +- Marlin/src/pins/rambo/pins_RAMBO.h | 218 +- Marlin/src/pins/rambo/pins_SCOOVO_X9H.h | 146 +- Marlin/src/pins/ramps/pins_3DRAG.h | 64 +- Marlin/src/pins/ramps/pins_AZTEEG_X3.h | 36 +- Marlin/src/pins/ramps/pins_AZTEEG_X3_PRO.h | 111 +- Marlin/src/pins/ramps/pins_BAM_DICE_DUE.h | 12 +- Marlin/src/pins/ramps/pins_BIQU_KFB_2.h | 2 +- Marlin/src/pins/ramps/pins_BQ_ZUM_MEGA_3D.h | 61 +- Marlin/src/pins/ramps/pins_COPYMASTER_3D.h | 34 + .../src/pins/ramps/pins_DUPLICATOR_I3_PLUS.h | 78 +- Marlin/src/pins/ramps/pins_FELIX2.h | 12 +- Marlin/src/pins/ramps/pins_FORMBOT_RAPTOR.h | 132 +- Marlin/src/pins/ramps/pins_FORMBOT_RAPTOR2.h | 30 +- .../src/pins/ramps/pins_FORMBOT_TREX2PLUS.h | 146 +- Marlin/src/pins/ramps/pins_FORMBOT_TREX3.h | 140 +- Marlin/src/pins/ramps/pins_FYSETC_F6_13.h | 259 +- Marlin/src/pins/ramps/pins_FYSETC_F6_14.h | 32 +- Marlin/src/pins/ramps/pins_K8200.h | 2 +- Marlin/src/pins/ramps/pins_K8400.h | 12 +- Marlin/src/pins/ramps/pins_K8600.h | 127 + Marlin/src/pins/ramps/pins_K8800.h | 109 +- Marlin/src/pins/ramps/pins_MAKEBOARD_MINI.h | 2 +- Marlin/src/pins/ramps/pins_MKS_BASE_10.h | 2 +- Marlin/src/pins/ramps/pins_MKS_BASE_14.h | 26 +- Marlin/src/pins/ramps/pins_MKS_BASE_15.h | 2 +- Marlin/src/pins/ramps/pins_MKS_BASE_16.h | 16 +- Marlin/src/pins/ramps/pins_MKS_BASE_HEROIC.h | 2 +- Marlin/src/pins/ramps/pins_MKS_BASE_common.h | 40 +- Marlin/src/pins/ramps/pins_MKS_GEN_13.h | 30 +- Marlin/src/pins/ramps/pins_MKS_GEN_L.h | 2 +- Marlin/src/pins/ramps/pins_MKS_GEN_L_V2.h | 34 +- Marlin/src/pins/ramps/pins_MKS_GEN_L_V21.h | 85 + Marlin/src/pins/ramps/pins_ORTUR_4.h | 116 + Marlin/src/pins/ramps/pins_RAMPS.h | 572 +- Marlin/src/pins/ramps/pins_RAMPS_13.h | 4 +- Marlin/src/pins/ramps/pins_RAMPS_CREALITY.h | 34 +- Marlin/src/pins/ramps/pins_RAMPS_DAGOMA.h | 14 +- Marlin/src/pins/ramps/pins_RAMPS_ENDER_4.h | 2 +- Marlin/src/pins/ramps/pins_RAMPS_OLD.h | 81 +- Marlin/src/pins/ramps/pins_RAMPS_PLUS.h | 29 +- Marlin/src/pins/ramps/pins_RIGIDBOARD.h | 59 +- Marlin/src/pins/ramps/pins_RIGIDBOARD_V2.h | 16 +- Marlin/src/pins/ramps/pins_RL200.h | 20 +- Marlin/src/pins/ramps/pins_RUMBA.h | 165 +- Marlin/src/pins/ramps/pins_RUMBA_RAISE3D.h | 2 +- Marlin/src/pins/ramps/pins_SAINSMART_2IN1.h | 2 +- Marlin/src/pins/ramps/pins_TANGO.h | 18 +- Marlin/src/pins/ramps/pins_TENLOG_D3_HERO.h | 185 + Marlin/src/pins/ramps/pins_TRIGORILLA_13.h | 11 +- Marlin/src/pins/ramps/pins_TRIGORILLA_14.h | 127 +- Marlin/src/pins/ramps/pins_TRONXY_V3_1_0.h | 4 +- Marlin/src/pins/ramps/pins_TT_OSCAR.h | 466 +- Marlin/src/pins/ramps/pins_ULTIMAIN_2.h | 106 +- Marlin/src/pins/ramps/pins_ULTIMAKER.h | 133 +- Marlin/src/pins/ramps/pins_ULTIMAKER_OLD.h | 182 +- Marlin/src/pins/ramps/pins_VORON.h | 20 +- Marlin/src/pins/ramps/pins_ZRIB_V20.h | 66 +- Marlin/src/pins/ramps/pins_Z_BOLT_X_SERIES.h | 192 +- Marlin/src/pins/sam/pins_ADSK.h | 71 +- Marlin/src/pins/sam/pins_ALLIGATOR_R2.h | 149 +- Marlin/src/pins/sam/pins_ARCHIM1.h | 167 +- Marlin/src/pins/sam/pins_ARCHIM2.h | 204 +- Marlin/src/pins/sam/pins_CNCONTROLS_15D.h | 111 +- Marlin/src/pins/sam/pins_DUE3DOM.h | 158 +- Marlin/src/pins/sam/pins_DUE3DOM_MINI.h | 162 +- Marlin/src/pins/sam/pins_PRINTRBOARD_G2.h | 121 +- Marlin/src/pins/sam/pins_RADDS.h | 251 +- Marlin/src/pins/sam/pins_RAMPS4DUE.h | 5 +- Marlin/src/pins/sam/pins_RAMPS_DUO.h | 43 +- Marlin/src/pins/sam/pins_RAMPS_FD_V1.h | 174 +- Marlin/src/pins/sam/pins_RAMPS_FD_V2.h | 4 +- Marlin/src/pins/sam/pins_RAMPS_SMART.h | 35 +- Marlin/src/pins/sam/pins_RURAMPS4D_11.h | 212 +- Marlin/src/pins/sam/pins_RURAMPS4D_13.h | 200 +- Marlin/src/pins/sam/pins_ULTRATRONICS_PRO.h | 151 +- Marlin/src/pins/samd/pins_RAMPS_144.h | 446 +- Marlin/src/pins/sanguino/pins_ANET_10.h | 99 +- Marlin/src/pins/sanguino/pins_AZTEEG_X1.h | 2 +- .../src/pins/sanguino/pins_GEN3_MONOLITHIC.h | 44 +- Marlin/src/pins/sanguino/pins_GEN3_PLUS.h | 49 +- Marlin/src/pins/sanguino/pins_GEN6.h | 63 +- Marlin/src/pins/sanguino/pins_GEN6_DELUXE.h | 4 +- Marlin/src/pins/sanguino/pins_GEN7_12.h | 85 +- Marlin/src/pins/sanguino/pins_GEN7_13.h | 4 +- Marlin/src/pins/sanguino/pins_GEN7_14.h | 65 +- Marlin/src/pins/sanguino/pins_GEN7_CUSTOM.h | 85 +- Marlin/src/pins/sanguino/pins_MELZI.h | 2 +- .../src/pins/sanguino/pins_MELZI_CREALITY.h | 57 +- Marlin/src/pins/sanguino/pins_MELZI_MAKR3D.h | 2 +- Marlin/src/pins/sanguino/pins_MELZI_MALYAN.h | 35 +- Marlin/src/pins/sanguino/pins_MELZI_TRONXY.h | 41 +- Marlin/src/pins/sanguino/pins_MELZI_V2.h | 39 + Marlin/src/pins/sanguino/pins_OMCA.h | 80 +- Marlin/src/pins/sanguino/pins_OMCA_A.h | 57 +- .../src/pins/sanguino/pins_SANGUINOLOLU_11.h | 227 +- .../src/pins/sanguino/pins_SANGUINOLOLU_12.h | 2 +- Marlin/src/pins/sanguino/pins_SETHI.h | 61 +- Marlin/src/pins/sanguino/pins_STB_11.h | 2 +- Marlin/src/pins/sanguino/pins_ZMIB_V2.h | 234 + Marlin/src/pins/sensitive_pins.h | 83 +- Marlin/src/pins/stm32/pins_ARMED.h | 201 - Marlin/src/pins/stm32/pins_BEAST.h | 285 - .../src/pins/stm32/pins_BLACK_STM32F407VE.h | 155 - Marlin/src/pins/stm32/pins_BTT_BTT002_V1_0.h | 253 - Marlin/src/pins/stm32/pins_BTT_GTR_V1_0.h | 391 - Marlin/src/pins/stm32/pins_BTT_SKR_E3_DIP.h | 233 - Marlin/src/pins/stm32/pins_BTT_SKR_MINI_E3.h | 191 - .../src/pins/stm32/pins_BTT_SKR_MINI_V1_1.h | 210 - Marlin/src/pins/stm32/pins_BTT_SKR_PRO_V1_1.h | 286 - Marlin/src/pins/stm32/pins_CHITU3D.h | 283 - Marlin/src/pins/stm32/pins_FLYF407ZG.h | 266 - Marlin/src/pins/stm32/pins_FYSETC_AIO_II.h | 189 - Marlin/src/pins/stm32/pins_FYSETC_CHEETAH.h | 151 - Marlin/src/pins/stm32/pins_FYSETC_S6.h | 262 - Marlin/src/pins/stm32/pins_GENERIC_STM32F4.h | 190 - Marlin/src/pins/stm32/pins_GTM32_MINI.h | 230 - Marlin/src/pins/stm32/pins_GTM32_PRO_VB.h | 230 - Marlin/src/pins/stm32/pins_GTM32_REV_B.h | 232 - Marlin/src/pins/stm32/pins_JGAURORA_A5S_A1.h | 130 - Marlin/src/pins/stm32/pins_LERDGE_K.h | 177 - Marlin/src/pins/stm32/pins_LERDGE_X.h | 174 - Marlin/src/pins/stm32/pins_LONGER3D_LK.h | 170 - Marlin/src/pins/stm32/pins_MALYAN_M200.h | 92 - Marlin/src/pins/stm32/pins_MKS_ROBIN.h | 159 - Marlin/src/pins/stm32/pins_MKS_ROBIN2.h | 102 - Marlin/src/pins/stm32/pins_MKS_ROBIN_LITE.h | 137 - Marlin/src/pins/stm32/pins_MKS_ROBIN_LITE3.h | 153 - Marlin/src/pins/stm32/pins_MKS_ROBIN_MINI.h | 154 - Marlin/src/pins/stm32/pins_MKS_ROBIN_NANO.h | 137 - Marlin/src/pins/stm32/pins_MKS_ROBIN_PRO.h | 274 - Marlin/src/pins/stm32/pins_MORPHEUS.h | 91 - Marlin/src/pins/stm32/pins_REMRAM_V1.h | 133 - Marlin/src/pins/stm32/pins_RUMBA32_AUS3D.h | 42 - Marlin/src/pins/stm32/pins_RUMBA32_common.h | 149 - Marlin/src/pins/stm32/pins_STM32F1R.h | 261 - Marlin/src/pins/stm32/pins_STM3R_MINI.h | 285 - Marlin/src/pins/stm32/pins_THE_BORG.h | 187 - Marlin/src/pins/stm32/pins_VAKE403D.h | 194 - Marlin/src/pins/stm32f0/pins_MALYAN_M200_V2.h | 31 + Marlin/src/pins/stm32f0/pins_MALYAN_M300.h | 91 + Marlin/src/pins/stm32f1/pins_BTT_SKR_E3_DIP.h | 289 + .../pins_BTT_SKR_MINI_E3_V1_0.h | 14 +- .../pins_BTT_SKR_MINI_E3_V1_2.h | 26 +- .../pins/stm32f1/pins_BTT_SKR_MINI_E3_V2_0.h | 59 + .../stm32f1/pins_BTT_SKR_MINI_E3_common.h | 276 + .../src/pins/stm32f1/pins_BTT_SKR_MINI_V1_1.h | 228 + .../src/pins/stm32f1/pins_CCROBOT_MEEB_3DP.h | 179 + Marlin/src/pins/stm32f1/pins_CHITU3D.h | 284 + Marlin/src/pins/stm32f1/pins_CHITU3D_V5.h | 203 + Marlin/src/pins/stm32f1/pins_CHITU3D_V6.h | 218 + Marlin/src/pins/stm32f1/pins_CREALITY_V4.h | 208 + Marlin/src/pins/stm32f1/pins_CREALITY_V427.h | 48 + Marlin/src/pins/stm32f1/pins_FLY_MINI.h | 172 + Marlin/src/pins/stm32f1/pins_FYSETC_AIO_II.h | 196 + Marlin/src/pins/stm32f1/pins_FYSETC_CHEETAH.h | 177 + .../pins_FYSETC_CHEETAH_V12.h | 24 +- Marlin/src/pins/stm32f1/pins_GTM32_MINI.h | 241 + .../{stm32 => stm32f1}/pins_GTM32_MINI_A30.h | 149 +- Marlin/src/pins/stm32f1/pins_GTM32_PRO_VB.h | 241 + Marlin/src/pins/stm32f1/pins_GTM32_REV_B.h | 238 + .../src/pins/stm32f1/pins_JGAURORA_A5S_A1.h | 132 + Marlin/src/pins/stm32f1/pins_LONGER3D_LK.h | 177 + Marlin/src/pins/stm32f1/pins_MALYAN_M200.h | 95 + Marlin/src/pins/stm32f1/pins_MKS_ROBIN.h | 213 + Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3.h | 36 + Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3D.h | 67 + Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3P.h | 376 + .../pins/stm32f1/pins_MKS_ROBIN_E3_common.h | 185 + Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE.h | 143 + .../src/pins/stm32f1/pins_MKS_ROBIN_LITE3.h | 155 + Marlin/src/pins/stm32f1/pins_MKS_ROBIN_MINI.h | 210 + Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO.h | 249 + .../src/pins/stm32f1/pins_MKS_ROBIN_NANO_V2.h | 392 + Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h | 275 + Marlin/src/pins/stm32f1/pins_MORPHEUS.h | 92 + Marlin/src/pins/stm32f1/pins_STM32F1R.h | 261 + Marlin/src/pins/stm32f1/pins_STM3R_MINI.h | 285 + Marlin/src/pins/stm32f1/pins_TRIGORILLA_PRO.h | 193 + Marlin/src/pins/stm32f4/pins_ARMED.h | 229 + Marlin/src/pins/stm32f4/pins_BEAST.h | 285 + .../src/pins/stm32f4/pins_BLACK_STM32F407VE.h | 159 + .../src/pins/stm32f4/pins_BTT_BTT002_V1_0.h | 268 + Marlin/src/pins/stm32f4/pins_BTT_GTR_V1_0.h | 411 + .../src/pins/stm32f4/pins_BTT_SKR_PRO_V1_1.h | 30 + .../src/pins/stm32f4/pins_BTT_SKR_PRO_V1_2.h | 30 + .../pins/stm32f4/pins_BTT_SKR_PRO_common.h | 394 + Marlin/src/pins/stm32f4/pins_FLYF407ZG.h | 292 + Marlin/src/pins/stm32f4/pins_FYSETC_S6.h | 289 + Marlin/src/pins/stm32f4/pins_FYSETC_S6_V2_0.h | 67 + .../src/pins/stm32f4/pins_GENERIC_STM32F4.h | 197 + Marlin/src/pins/stm32f4/pins_LERDGE_K.h | 180 + Marlin/src/pins/stm32f4/pins_LERDGE_S.h | 208 + Marlin/src/pins/stm32f4/pins_LERDGE_X.h | 151 + Marlin/src/pins/stm32f4/pins_MKS_ROBIN2.h | 101 + Marlin/src/pins/stm32f4/pins_RUMBA32_AUS3D.h | 78 + .../{stm32 => stm32f4}/pins_RUMBA32_MKS.h | 69 +- Marlin/src/pins/stm32f4/pins_RUMBA32_common.h | 183 + .../{stm32 => stm32f4}/pins_STEVAL_3DP001V1.h | 224 +- Marlin/src/pins/stm32f4/pins_VAKE403D.h | 195 + Marlin/src/pins/stm32f7/pins_NUCLEO_F767ZI.h | 201 + Marlin/src/pins/stm32f7/pins_REMRAM_V1.h | 137 + Marlin/src/pins/stm32f7/pins_THE_BORG.h | 183 + Marlin/src/pins/teensy2/pins_5DPRINT.h | 74 +- Marlin/src/pins/teensy2/pins_BRAINWAVE.h | 60 +- Marlin/src/pins/teensy2/pins_BRAINWAVE_PRO.h | 56 +- Marlin/src/pins/teensy2/pins_PRINTRBOARD.h | 100 +- .../src/pins/teensy2/pins_PRINTRBOARD_REVF.h | 170 +- Marlin/src/pins/teensy2/pins_SAV_MKI.h | 114 +- Marlin/src/pins/teensy2/pins_TEENSY2.h | 85 +- Marlin/src/pins/teensy2/pins_TEENSYLU.h | 85 +- Marlin/src/pins/teensy3/pins_TEENSY31_32.h | 93 +- Marlin/src/pins/teensy3/pins_TEENSY35_36.h | 194 +- Marlin/src/pins/teensy4/pins_T41U5XBB.h | 126 + Marlin/src/pins/teensy4/pins_TEENSY41.h | 131 + Marlin/src/sd/Sd2Card.cpp | 59 +- Marlin/src/sd/Sd2Card.h | 15 +- Marlin/src/sd/Sd2Card_sdio.h | 2 +- Marlin/src/sd/SdBaseFile.cpp | 54 +- Marlin/src/sd/SdBaseFile.h | 2 +- Marlin/src/sd/SdFatConfig.h | 2 +- Marlin/src/sd/SdFatStructs.h | 6 +- Marlin/src/sd/SdFatUtil.cpp | 2 +- Marlin/src/sd/SdFatUtil.h | 2 +- Marlin/src/sd/SdFile.cpp | 3 +- Marlin/src/sd/SdFile.h | 2 +- Marlin/src/sd/SdInfo.h | 4 +- Marlin/src/sd/SdVolume.cpp | 28 +- Marlin/src/sd/SdVolume.h | 2 +- Marlin/src/sd/cardreader.cpp | 365 +- Marlin/src/sd/cardreader.h | 40 +- .../sd/usb_flashdrive/Sd2Card_FlashDrive.cpp | 34 +- .../sd/usb_flashdrive/Sd2Card_FlashDrive.h | 15 +- Marlin/src/sd/usb_flashdrive/lib-uhs2/Usb.cpp | 15 +- Marlin/src/sd/usb_flashdrive/lib-uhs2/Usb.h | 2 +- .../src/sd/usb_flashdrive/lib-uhs2/UsbCore.h | 26 +- .../src/sd/usb_flashdrive/lib-uhs2/address.h | 2 +- .../usb_flashdrive/lib-uhs2/confdescparser.h | 16 +- .../src/sd/usb_flashdrive/lib-uhs2/hexdump.h | 2 +- .../src/sd/usb_flashdrive/lib-uhs2/macros.h | 20 +- .../sd/usb_flashdrive/lib-uhs2/masstorage.cpp | 24 +- .../sd/usb_flashdrive/lib-uhs2/masstorage.h | 10 +- .../src/sd/usb_flashdrive/lib-uhs2/max3421e.h | 28 +- .../sd/usb_flashdrive/lib-uhs2/message.cpp | 4 +- .../src/sd/usb_flashdrive/lib-uhs2/message.h | 2 +- .../sd/usb_flashdrive/lib-uhs2/parsetools.cpp | 2 +- .../sd/usb_flashdrive/lib-uhs2/parsetools.h | 2 +- .../src/sd/usb_flashdrive/lib-uhs2/printhex.h | 6 +- .../src/sd/usb_flashdrive/lib-uhs2/settings.h | 4 +- .../src/sd/usb_flashdrive/lib-uhs2/usb_ch9.h | 10 +- .../sd/usb_flashdrive/lib-uhs2/usbhost.cpp | 4 +- .../src/sd/usb_flashdrive/lib-uhs2/usbhost.h | 2 +- .../UHS_BULK_STORAGE/UHS_BULK_STORAGE.h | 4 +- .../UHS_BULK_STORAGE_INLINE.h | 19 +- .../UHS_host/UHS_BULK_STORAGE/UHS_SCSI.h | 6 +- .../lib-uhs3/UHS_host/UHS_UNOFFICIAL_IDs.h | 2 +- .../lib-uhs3/UHS_host/UHS_UsbCore.h | 6 +- .../lib-uhs3/UHS_host/UHS_address.h | 2 +- .../lib-uhs3/UHS_host/UHS_hexdump.h | 2 +- .../lib-uhs3/UHS_host/UHS_host.h | 2 +- .../lib-uhs3/UHS_host/UHS_host_INLINE.h | 38 +- .../lib-uhs3/UHS_host/UHS_macros.h | 20 +- .../lib-uhs3/UHS_host/UHS_message.h | 2 +- .../lib-uhs3/UHS_host/UHS_printf_HELPER.h | 2 +- .../lib-uhs3/UHS_host/UHS_printhex.h | 6 +- .../lib-uhs3/UHS_host/UHS_settings.h | 4 +- .../lib-uhs3/UHS_host/UHS_usb_ch9.h | 22 +- .../lib-uhs3/UHS_host/UHS_usbhost.h | 9 +- .../lib-uhs3/UHS_host/UHS_util_INLINE.h | 2 +- .../UHS_host/USB_HOST_SHIELD/UHS_max3421e.h | 28 +- .../USB_HOST_SHIELD/USB_HOST_SHIELD.h | 2 +- .../USB_HOST_SHIELD/USB_HOST_SHIELD_INLINE.h | 14 +- .../lib-uhs3/UHS_host/macro_logic.h | 1 - .../lib-uhs3/dyn_SWI/SWI_INLINE.h | 2 - .../usb_flashdrive/lib-uhs3/dyn_SWI/dyn_SWI.h | 2 +- README.md | 14 +- buildroot/bin/.gitattributes | 1 + buildroot/bin/format_code | 30 + buildroot/bin/generate_version | 2 +- buildroot/bin/opt_add | 2 +- buildroot/bin/opt_set | 4 +- buildroot/bin/uncrust | 16 + buildroot/bin/use_example_configs | 20 +- .../etc/udev/rules.d/99-platformio-udev.rules | 4 +- .../PlatformIO/boards/BigTree_Btt002.json | 12 +- .../PlatformIO/boards/BigTree_GTR_v1.json | 46 + .../PlatformIO/boards/BigTree_SKR_Pro.json | 4 +- .../share/PlatformIO/boards/CHITU_F103.json | 48 + .../share/PlatformIO/boards/FLYF407ZG.json | 3 +- buildroot/share/PlatformIO/boards/LERDGE.json | 65 + .../share/PlatformIO/boards/MEEB_3DP.json | 53 + buildroot/share/PlatformIO/boards/archim.json | 59 + .../PlatformIO/boards/blackSTM32F407VET6.json | 3 +- .../share/PlatformIO/boards/malyanM200.json | 3 +- .../share/PlatformIO/boards/malyanM200v2.json | 2 +- .../{fysetc_s6.json => marlin_fysetc_s6.json} | 4 +- .../ldscripts/STM32F103RC_MEEB_3DP.ld | 14 + .../share/PlatformIO/ldscripts/chitu_f103.ld | 4 +- .../share/PlatformIO/ldscripts/creality.ld | 14 + .../share/PlatformIO/ldscripts/fly_mini.ld | 14 + ...fysetc_aio_ii.ld => fysetc_stm32f103rc.ld} | 2 +- .../share/PlatformIO/ldscripts/lerdge.ld | 186 + .../PlatformIO/ldscripts/mks_robin_e3.ld | 14 + .../PlatformIO/ldscripts/mks_robin_e3p.ld | 14 + .../PlatformIO/ldscripts/mks_robin_nano.ld | 2 +- .../PlatformIO/scripts/STEVAL__F401XX.py | 2 - .../scripts/STM32F103RC_MEEB_3DP.py | 59 + .../PlatformIO/scripts/STM32F103RC_fysetc.py | 37 +- .../scripts/STM32F103RE_SKR_E3_DIP.py | 4 + .../scripts/STM32F1_create_variant.py | 34 + .../share/PlatformIO/scripts/chitu_crypt.py | 22 +- .../scripts/common-dependencies-post.py | 16 + .../PlatformIO/scripts/common-dependencies.h | 115 + .../PlatformIO/scripts/common-dependencies.py | 287 + .../copy_marlin_variant_to_framework.py | 58 + .../share/PlatformIO/scripts/creality.py | 17 + .../PlatformIO/scripts/download_mks_assets.py | 46 + .../share/PlatformIO/scripts/fly_mini.py | 16 + .../PlatformIO/scripts/fysetc_STM32S6.py | 55 - buildroot/share/PlatformIO/scripts/lerdge.py | 46 + .../share/PlatformIO/scripts/mks_encrypt.py | 32 + .../share/PlatformIO/scripts/mks_robin_e3.py | 40 + .../share/PlatformIO/scripts/mks_robin_e3p.py | 40 + .../PlatformIO/scripts/mks_robin_nano35.py | 40 + .../share/PlatformIO/scripts/random-bin.py | 5 + .../PlatformIO/scripts/stm32_bootloader.py | 30 + .../variants/BIGTREE_BTT002/PeripheralPins.c | 17 +- .../variants/BIGTREE_BTT002/PinNamesVar.h | 38 +- .../variants/BIGTREE_BTT002/variant.h | 8 +- .../variants/BIGTREE_GTR_V1/PeripheralPins.c | 380 + .../variants/BIGTREE_GTR_V1/PinNamesVar.h | 50 + .../variants/BIGTREE_GTR_V1/hal_conf_extra.h | 52 + .../variants/BIGTREE_GTR_V1/ldscript.ld | 204 + .../variants/BIGTREE_GTR_V1/variant.cpp | 260 + .../variants/BIGTREE_GTR_V1/variant.h | 322 + .../BIGTREE_SKR_PRO_1v1/PeripheralPins.c | 30 +- .../BIGTREE_SKR_PRO_1v1/PinNamesVar.h | 38 +- .../variants/BIGTREE_SKR_PRO_1v1/variant.h | 11 +- .../PlatformIO/variants/CHITU_F103/board.cpp | 233 + .../variants/CHITU_F103/board/board.h | 240 + .../variants/CHITU_F103/ld/common.inc | 220 + .../variants/CHITU_F103/ld/extra_libs.inc | 7 + .../variants/CHITU_F103/ld/stm32f103z_dfu.ld | 29 + .../variants/CHITU_F103/ld/stm32f103zc.ld | 27 + .../variants/CHITU_F103/ld/stm32f103zd.ld | 27 + .../variants/CHITU_F103/ld/stm32f103ze.ld | 29 + .../variants/CHITU_F103/ld/vector_symbols.inc | 78 + .../variants/CHITU_F103/pins_arduino.h | 2 + .../PlatformIO/variants/CHITU_F103/variant.h | 17 + .../variants/CHITU_F103/wirish/boards.cpp | 225 + .../CHITU_F103/wirish/boards_setup.cpp | 128 + .../variants/CHITU_F103/wirish/start.S | 57 + .../variants/CHITU_F103/wirish/start_c.c | 144 + .../variants/CHITU_F103/wirish/syscalls.c | 176 + .../variants/FLY_F407ZG/PeripheralPins.c | 431 +- .../variants/FLY_F407ZG/PinNamesVar.h | 60 +- .../variants/FLY_F407ZG/variant.cpp | 226 +- .../PlatformIO/variants/FLY_F407ZG/variant.h | 237 +- .../variants/LERDGE/PeripheralPins.c | 418 + .../PlatformIO/variants/LERDGE/PinNamesVar.h | 50 + .../PlatformIO/variants/LERDGE/variant.cpp | 297 + .../PlatformIO/variants/LERDGE/variant.h | 238 + .../variants/MARLIN_F103Vx/PeripheralPins.c | 425 + .../PinNamesVar.h | 20 +- .../variants/MARLIN_F103Vx/ldscript.ld | 200 + .../variants/MARLIN_F103Vx/variant.cpp | 235 + .../variants/MARLIN_F103Vx/variant.h | 181 + .../variants/MARLIN_F103Zx/PeripheralPins.c | 368 + .../variants/MARLIN_F103Zx/PinNamesVar.h | 30 + .../variants/MARLIN_F103Zx/hal_conf_custom.h | 412 + .../variants/MARLIN_F103Zx/ldscript.ld | 197 + .../variants/MARLIN_F103Zx/variant.cpp | 222 + .../variants/MARLIN_F103Zx/variant.h | 232 + .../variants/MARLIN_F407VE/PeripheralPins.c | 30 +- .../variants/MARLIN_F407VE/PinNamesVar.h | 60 +- .../PeripheralPins.c | 0 .../variants/MARLIN_FYSETC_S6/PinNamesVar.h | 30 + .../ldscript.ld | 0 .../variant.cpp | 0 .../{FYSETC_S6 => MARLIN_FYSETC_S6}/variant.h | 4 +- .../PlatformIO/variants/MEEB_3DP/board.cpp | 161 + .../variants/MEEB_3DP/board/board.h | 125 + .../variants/MEEB_3DP/ld/bootloader.ld | 18 + .../variants/MEEB_3DP/ld/common.inc | 220 + .../variants/MEEB_3DP/ld/extra_libs.inc | 7 + .../PlatformIO/variants/MEEB_3DP/ld/flash.ld | 26 + .../PlatformIO/variants/MEEB_3DP/ld/jtag.ld | 31 + .../variants/MEEB_3DP/ld/mem-flash.inc | 5 + .../variants/MEEB_3DP/ld/mem-jtag.inc | 5 + .../variants/MEEB_3DP/ld/mem-ram.inc | 5 + .../PlatformIO/variants/MEEB_3DP/ld/ram.ld | 25 + .../variants/MEEB_3DP/ld/stm32f103rb.ld | 18 + .../MEEB_3DP/ld/stm32f103rb_bootloader.ld | 17 + .../variants/MEEB_3DP/ld/stm32f103rc.ld | 18 + .../MEEB_3DP/ld/stm32f103rc_bootloader.ld | 18 + .../variants/MEEB_3DP/ld/stm32f103re.ld | 18 + .../variants/MEEB_3DP/ld/vector_symbols.inc | 78 + .../variants/MEEB_3DP/pins_arduino.h | 2 + .../PlatformIO/variants/MEEB_3DP/variant.h | 17 + .../variants/MEEB_3DP/wirish/boards.cpp | 225 + .../variants/MEEB_3DP/wirish/boards_setup.cpp | 106 + .../variants/MEEB_3DP/wirish/start.S | 57 + .../variants/MEEB_3DP/wirish/start_c.c | 95 + .../variants/MEEB_3DP/wirish/syscalls.c | 176 + .../variants/STEVAL_F401VE/PinNamesVar.h | 26 +- .../variants/STEVAL_F401VE/variant.cpp | 2 +- .../variants/STEVAL_F401VE/variant.h | 4 +- .../PlatformIO/variants/archim/.gitignore | 2 + .../variants/archim/build_gcc/Makefile | 42 + .../variants/archim/build_gcc/debug.mk | 25 + .../variants/archim/build_gcc/gcc.mk | 82 + .../build_gcc/libvariant_arduino_due_x.mk | 184 + .../variants/archim/build_gcc/release.mk | 25 + .../debug_scripts/gcc/arduino_due_x_flash.gdb | 37 + .../debug_scripts/gcc/arduino_due_x_sram.gdb | 37 + .../debug_scripts/iar/arduino_due_flash.mac | 44 + .../debug_scripts/iar/arduino_due_sram.mac | 44 + .../variants/archim/libsam_sam3x8e_gcc_rel.a | Bin 0 -> 117430 bytes .../archim/libsam_sam3x8e_gcc_rel.a.txt | 576 + .../archim/linker_scripts/gcc/flash.ld | 146 + .../archim/linker_scripts/gcc/sram.ld | 145 + .../archim/linker_scripts/iar/flash.icf | 49 + .../archim/linker_scripts/iar/sram.icf | 33 + .../PlatformIO/variants/archim/pins_arduino.h | 21 + .../PlatformIO/variants/archim/variant.cpp | 485 + .../PlatformIO/variants/archim/variant.h | 284 + .../variants/megaextendedpins/pins_arduino.h | 461 + buildroot/share/cmake/CMakeLists.txt | 8 +- .../share/extras/header.h | 8 +- buildroot/share/extras/uncrustify.cfg | 84 + buildroot/share/fonts/README.md | 8 +- buildroot/share/fonts/genallfont.sh | 4 +- buildroot/share/fonts/marlin-6x12-3.bdf | 17 +- buildroot/share/fonts/marlin-6x9.bdf | 16606 ++++++++++++++++ buildroot/share/fonts/uxggenpages.md | 6 +- buildroot/share/fonts/uxggenpages.sh | 4 +- buildroot/share/git/firstpush | 6 +- buildroot/share/git/ghtp | 22 +- buildroot/share/git/mfclean | 4 +- buildroot/share/git/mfinfo | 3 +- buildroot/share/git/mfpr | 4 +- buildroot/share/git/mfpub | 8 +- buildroot/share/git/mfrb | 7 +- buildroot/share/git/mftest | 16 +- buildroot/share/scripts/MarlinMesh.scad | 156 +- buildroot/share/scripts/config-labels.py | 201 + .../scripts/createTemperatureLookupMarlin.py | 4 +- buildroot/share/scripts/pinsformat.js | 170 + .../sublime/MarlinFirmware.sublime-project | 1 - .../RepRapTools/syntax_test_G-code.gcode | 2 +- buildroot/share/tests/BIGTREE_SKR_PRO-tests | 18 - .../share/tests/SAMD51_grandcentral_m4-tests | 17 - .../share/tests/STM32F103RC_bigtree-tests | 19 - buildroot/share/tests/megaatmega1280-tests | 27 - buildroot/share/tests/mks_robin_nano-tests | 14 - buildroot/share/tests/rambo-tests | 37 - buildroot/share/vscode/auto_build.py | 10 +- buildroot/share/vscode/avrdude.conf | 20 +- buildroot/share/vscode/avrdude_linux.conf | 20 +- buildroot/share/vscode/avrdude_macOS.conf | 10 +- buildroot/tests/.gitattributes | 1 + buildroot/{share => }/tests/ARMED-tests | 5 +- buildroot/tests/BIGTREE_BTT002-tests | 20 + buildroot/tests/BIGTREE_GTR_V1_0-tests | 46 + buildroot/tests/BIGTREE_SKR_PRO-tests | 32 + buildroot/{share => }/tests/DUE-tests | 9 +- buildroot/tests/FLYF407ZG-tests | 18 + .../{share => }/tests/FYSETC_F6_13-tests | 3 +- buildroot/{share => }/tests/FYSETC_S6-tests | 2 + .../LERDGEX-tests} | 6 +- buildroot/{share => }/tests/LPC1768-tests | 5 +- buildroot/{share => }/tests/LPC1769-tests | 23 +- buildroot/tests/SAMD51_grandcentral_m4-tests | 39 + buildroot/tests/STM32F070CB_malyan-tests | 15 + buildroot/tests/STM32F070RB_malyan-tests | 15 + .../tests/STM32F103CB_malyan-tests | 2 +- buildroot/tests/STM32F103RC_btt-tests | 28 + .../STM32F103RC_btt_USB-tests} | 0 .../tests/STM32F103RC_fysetc-tests | 2 +- buildroot/tests/STM32F103RC_meeb-tests | 23 + buildroot/{share => }/tests/STM32F103RE-tests | 0 buildroot/tests/STM32F103RET6_creality-tests | 16 + .../STM32F103RE_btt-tests} | 4 +- .../STM32F103RE_btt_USB-tests} | 0 .../tests/STM32F103VE_longer-tests | 0 buildroot/{share => }/tests/STM32F4-tests | 0 buildroot/tests/STM32F401VE_STEVAL-tests | 16 + .../{share => }/tests/STM32F407VE_black-tests | 1 + buildroot/{share => }/tests/STM32F7-tests | 0 .../{share => }/tests/at90usb1286_cdc-tests | 0 .../{share => }/tests/at90usb1286_dfu-tests | 0 buildroot/{share => }/tests/esp32-tests | 10 +- .../{share => }/tests/jgaurora_a5s_a1-tests | 0 .../{share => }/tests/linux_native-tests | 0 buildroot/tests/malyan_M300-tests | 16 + buildroot/tests/mega1280-tests | 59 + .../mega2560-tests} | 120 +- buildroot/tests/mks_robin-tests | 16 + .../{share => }/tests/mks_robin_lite-tests | 10 +- .../{share => }/tests/mks_robin_mini-tests | 5 +- buildroot/tests/mks_robin_nano35-tests | 46 + buildroot/tests/mks_robin_pro-tests | 19 + .../mks_robin_stm32-tests} | 4 +- buildroot/tests/rambo-tests | 75 + buildroot/tests/rumba32-tests | 39 + buildroot/{share => }/tests/run_tests | 0 .../sanguino1284p-tests} | 0 .../sanguino644p-tests} | 0 buildroot/{share => }/tests/teensy31-tests | 0 buildroot/{share => }/tests/teensy35-tests | 12 +- buildroot/tests/teensy41-tests | 124 + config/README.md | 2 +- platformio.ini | 1527 +- 2018 files changed, 156370 insertions(+), 48345 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100644 .github/lock.yml delete mode 100644 .github/workflows/bad-target.md create mode 100644 .github/workflows/clean-closed.yml create mode 100644 .github/workflows/close-stale.yml create mode 100644 .github/workflows/lock-closed.yml create mode 100644 .github/workflows/unlock-reopened.yml rename Marlin/src/HAL/{HAL_AVR => AVR}/HAL.cpp (96%) create mode 100644 Marlin/src/HAL/AVR/HAL.h rename Marlin/src/HAL/{HAL_AVR => AVR}/HAL_SPI.cpp (97%) create mode 100644 Marlin/src/HAL/AVR/MarlinSerial.cpp rename Marlin/src/HAL/{HAL_AVR => AVR}/MarlinSerial.h (82%) rename Marlin/src/HAL/{HAL_AVR => AVR}/Servo.cpp (98%) rename Marlin/src/HAL/{HAL_AVR => AVR}/ServoTimers.h (90%) rename Marlin/src/HAL/{HAL_AVR/persistent_store_eeprom.cpp => AVR/eeprom.cpp} (81%) rename Marlin/src/HAL/{HAL_AVR => AVR}/endstop_interrupts.h (99%) rename Marlin/src/HAL/{HAL_AVR => AVR}/fast_pwm.cpp (95%) rename Marlin/src/HAL/{HAL_AVR => AVR}/fastio.cpp (66%) rename Marlin/src/HAL/{HAL_AVR => AVR}/fastio.h (92%) rename Marlin/src/HAL/{HAL_AVR => AVR}/fastio/fastio_1280.h (99%) rename Marlin/src/HAL/{HAL_AVR => AVR}/fastio/fastio_1281.h (99%) rename Marlin/src/HAL/{HAL_AVR => AVR}/fastio/fastio_168.h (99%) rename Marlin/src/HAL/{HAL_AVR => AVR}/fastio/fastio_644.h (99%) rename Marlin/src/HAL/{HAL_AVR => AVR}/fastio/fastio_AT90USB.h (99%) rename Marlin/src/HAL/{HAL_LPC1768/persistent_store_api.h => AVR/inc/Conditionals_LCD.h} (82%) rename Marlin/src/HAL/{HAL_AVR => AVR}/inc/Conditionals_adv.h (91%) rename Marlin/src/HAL/{HAL_DUE => AVR}/inc/Conditionals_post.h (91%) rename Marlin/src/HAL/{HAL_AVR => AVR}/inc/SanityCheck.h (75%) rename Marlin/src/HAL/{HAL_AVR => AVR}/math.h (97%) rename Marlin/src/HAL/{HAL_AVR => AVR}/pinsDebug.h (97%) rename Marlin/src/HAL/{HAL_AVR => AVR}/pinsDebug_Teensyduino.h (97%) rename Marlin/src/HAL/{HAL_AVR => AVR}/pinsDebug_plus_70.h (97%) rename Marlin/src/HAL/{HAL_AVR => AVR}/spi_pins.h (96%) rename Marlin/src/HAL/{HAL_AVR/HAL.h => AVR/timers.h} (69%) rename Marlin/src/HAL/{HAL_AVR => AVR}/u8g_com_HAL_AVR_sw_spi.cpp (96%) rename Marlin/src/HAL/{HAL_AVR => AVR}/watchdog.cpp (97%) rename Marlin/src/HAL/{HAL_AVR => AVR}/watchdog.h (93%) rename Marlin/src/HAL/{HAL_DUE => DUE}/DebugMonitor.cpp (99%) rename Marlin/src/HAL/{HAL_DUE => DUE}/HAL.cpp (93%) rename Marlin/src/HAL/{HAL_DUE => DUE}/HAL.h (65%) rename Marlin/src/HAL/{HAL_DUE => DUE}/HAL_SPI.cpp (99%) rename Marlin/src/HAL/{HAL_DUE => DUE}/InterruptVectors.cpp (97%) rename Marlin/src/HAL/{HAL_DUE => DUE}/InterruptVectors.h (95%) rename Marlin/src/HAL/{HAL_DUE => DUE}/MarlinSerial.cpp (97%) rename Marlin/src/HAL/{HAL_DUE => DUE}/MarlinSerial.h (89%) rename Marlin/src/HAL/{HAL_DUE => DUE}/MarlinSerialUSB.cpp (93%) rename Marlin/src/HAL/{HAL_DUE => DUE}/MarlinSerialUSB.h (91%) rename Marlin/src/HAL/{HAL_DUE => DUE}/Servo.cpp (98%) rename Marlin/src/HAL/{HAL_DUE => DUE}/ServoTimers.h (100%) rename Marlin/src/HAL/{HAL_DUE => DUE}/Tone.cpp (90%) rename Marlin/src/HAL/{HAL_DUE => DUE}/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp (96%) rename Marlin/src/HAL/{HAL_DUE => DUE}/dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp (98%) rename Marlin/src/HAL/{HAL_DUE => DUE}/dogm/u8g_com_HAL_DUE_sw_spi.cpp (96%) rename Marlin/src/HAL/{HAL_DUE => DUE}/dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp (94%) rename Marlin/src/HAL/{HAL_DUE => DUE}/dogm/u8g_com_HAL_DUE_sw_spi_shared.h (94%) rename Marlin/src/HAL/{HAL_DUE/EepromEmulation.cpp => DUE/eeprom_flash.cpp} (88%) rename Marlin/src/HAL/{HAL_DUE/persistent_store_eeprom.cpp => DUE/eeprom_wired.cpp} (74%) rename Marlin/src/HAL/{HAL_TEENSY31_32 => DUE}/endstop_interrupts.h (68%) rename Marlin/src/HAL/{HAL_DUE => DUE}/fastio.h (97%) create mode 100644 Marlin/src/HAL/DUE/fastio/G2_PWM.cpp rename Marlin/src/HAL/{HAL_DUE => DUE}/fastio/G2_PWM.h (94%) rename Marlin/src/HAL/{HAL_DUE => DUE}/fastio/G2_pins.h (99%) create mode 100644 Marlin/src/HAL/DUE/inc/Conditionals_LCD.h rename Marlin/src/HAL/{HAL_DUE => DUE}/inc/Conditionals_adv.h (91%) create mode 100644 Marlin/src/HAL/DUE/inc/Conditionals_post.h rename Marlin/src/HAL/{HAL_DUE => DUE}/inc/SanityCheck.h (90%) rename Marlin/src/HAL/{HAL_DUE => DUE}/pinsDebug.h (98%) rename Marlin/src/HAL/{HAL_DUE => DUE}/spi_pins.h (95%) rename Marlin/src/HAL/{HAL_DUE => DUE}/timers.cpp (95%) rename Marlin/src/HAL/{HAL_DUE => DUE}/timers.h (85%) create mode 100644 Marlin/src/HAL/DUE/upload_extra_script.py rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/arduino_due_x.h (96%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/compiler.h (87%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/conf_access.h (97%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/conf_clock.h (97%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/conf_usb.h (98%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/ctrl_access.c (99%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/ctrl_access.h (99%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/genclk.h (98%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/mrepeat.h (99%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/osc.h (98%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/pll.h (98%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/preprocessor.h (95%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/sbc_protocol.h (98%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/sd_mmc_spi_mem.cpp (100%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/sd_mmc_spi_mem.h (98%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/spc_protocol.h (99%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/stringz.h (96%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/sysclk.c (97%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/sysclk.h (98%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/tpaste.h (97%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/udc.c (99%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/udc.h (99%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/udc_desc.h (97%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/udd.h (99%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/udi.h (97%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/udi_cdc.c (99%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/udi_cdc.h (99%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/udi_cdc_conf.h (98%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/udi_cdc_desc.c (98%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/udi_composite_desc.c (98%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/udi_msc.c (99%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/udi_msc.h (98%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/uotghs_device_due.c (99%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/uotghs_device_due.h (99%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/uotghs_otg.h (99%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/usb_protocol.h (99%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/usb_protocol_cdc.h (99%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/usb_protocol_msc.h (98%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/usb_task.c (99%) rename Marlin/src/HAL/{HAL_DUE => DUE}/usb/usb_task.h (97%) rename Marlin/src/HAL/{HAL_DUE => DUE}/watchdog.cpp (98%) rename Marlin/src/HAL/{HAL_DUE => DUE}/watchdog.h (93%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/FlushableHardwareSerial.cpp (93%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/FlushableHardwareSerial.h (93%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/HAL.cpp (84%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/HAL.h (89%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/HAL_SPI.cpp (95%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/Servo.cpp (93%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/Servo.h (95%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/WebSocketSerial.cpp (95%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/WebSocketSerial.h (96%) rename Marlin/src/HAL/{HAL_ESP32/persistent_store_impl.cpp => ESP32/eeprom.cpp} (75%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/endstop_interrupts.h (67%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/fastio.h (95%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/i2s.cpp (99%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/i2s.h (93%) create mode 100644 Marlin/src/HAL/ESP32/inc/Conditionals_LCD.h rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/inc/Conditionals_adv.h (91%) rename Marlin/src/HAL/{HAL_AVR => ESP32}/inc/Conditionals_post.h (91%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/inc/SanityCheck.h (82%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/ota.cpp (96%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/ota.h (91%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/servotimers.h (91%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/spi_pins.h (91%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/spiffs.cpp (94%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/spiffs.h (92%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/timers.cpp (98%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/timers.h (84%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/watchdog.cpp (93%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/watchdog.h (93%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/web.cpp (95%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/web.h (91%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/wifi.cpp (96%) rename Marlin/src/HAL/{HAL_ESP32 => ESP32}/wifi.h (92%) delete mode 100644 Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp delete mode 100644 Marlin/src/HAL/HAL_DUE/fastio/G2_PWM.cpp delete mode 100644 Marlin/src/HAL/HAL_LINUX/inc/Conditionals_LCD.h delete mode 100644 Marlin/src/HAL/HAL_LPC1768/HAL_SPI.cpp delete mode 100644 Marlin/src/HAL/HAL_LPC1768/inc/Conditionals_LCD.h delete mode 100644 Marlin/src/HAL/HAL_LPC1768/inc/Conditionals_adv.h delete mode 100644 Marlin/src/HAL/HAL_LPC1768/inc/Conditionals_post.h delete mode 100644 Marlin/src/HAL/HAL_LPC1768/inc/SanityCheck.h delete mode 100644 Marlin/src/HAL/HAL_SAMD51/inc/Conditionals_LCD.h delete mode 100644 Marlin/src/HAL/HAL_SAMD51/inc/Conditionals_adv.h delete mode 100644 Marlin/src/HAL/HAL_SAMD51/inc/Conditionals_post.h delete mode 100644 Marlin/src/HAL/HAL_SAMD51/persistent_store_eeprom.cpp delete mode 100644 Marlin/src/HAL/HAL_STM32/Sd2Card_sdio_stm32duino.cpp delete mode 100644 Marlin/src/HAL/HAL_STM32/SoftwareSerial.cpp delete mode 100644 Marlin/src/HAL/HAL_STM32/SoftwareSerial.h delete mode 100644 Marlin/src/HAL/HAL_STM32/endstop_interrupts.h delete mode 100644 Marlin/src/HAL/HAL_STM32/inc/Conditionals_LCD.h delete mode 100644 Marlin/src/HAL/HAL_STM32/inc/Conditionals_adv.h delete mode 100644 Marlin/src/HAL/HAL_STM32/inc/Conditionals_post.h delete mode 100644 Marlin/src/HAL/HAL_STM32/inc/SanityCheck.h delete mode 100644 Marlin/src/HAL/HAL_STM32/persistent_store_impl.cpp delete mode 100644 Marlin/src/HAL/HAL_STM32/timers.cpp delete mode 100644 Marlin/src/HAL/HAL_STM32F1/inc/Conditionals_LCD.h delete mode 100644 Marlin/src/HAL/HAL_STM32F1/inc/Conditionals_adv.h delete mode 100644 Marlin/src/HAL/HAL_STM32F1/inc/Conditionals_post.h delete mode 100644 Marlin/src/HAL/HAL_STM32F1/msc_sd.h delete mode 100644 Marlin/src/HAL/HAL_STM32_F4_F7/endstop_interrupts.h delete mode 100644 Marlin/src/HAL/HAL_STM32_F4_F7/inc/Conditionals_LCD.h delete mode 100644 Marlin/src/HAL/HAL_STM32_F4_F7/inc/Conditionals_adv.h delete mode 100644 Marlin/src/HAL/HAL_STM32_F4_F7/inc/Conditionals_post.h delete mode 100644 Marlin/src/HAL/HAL_TEENSY31_32/inc/Conditionals_LCD.h delete mode 100644 Marlin/src/HAL/HAL_TEENSY31_32/inc/Conditionals_adv.h delete mode 100644 Marlin/src/HAL/HAL_TEENSY31_32/inc/Conditionals_post.h delete mode 100644 Marlin/src/HAL/HAL_TEENSY35_36/inc/Conditionals_LCD.h delete mode 100644 Marlin/src/HAL/HAL_TEENSY35_36/inc/Conditionals_adv.h delete mode 100644 Marlin/src/HAL/HAL_TEENSY35_36/inc/Conditionals_post.h rename Marlin/src/HAL/{HAL_LINUX => LINUX}/HAL.cpp (96%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/HAL.h (90%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/arduino.cpp (85%) rename Marlin/src/HAL/{HAL_LINUX/persistent_store_impl.cpp => LINUX/eeprom.cpp} (85%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/fastio.h (94%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/hardware/Clock.cpp (93%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/hardware/Clock.h (97%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/hardware/Gpio.cpp (92%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/hardware/Gpio.h (97%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/hardware/Heater.cpp (95%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/hardware/Heater.h (94%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/hardware/IOLoggerCSV.cpp (95%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/hardware/IOLoggerCSV.h (93%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/hardware/LinearAxis.cpp (96%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/hardware/LinearAxis.h (94%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/hardware/Timer.cpp (97%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/hardware/Timer.h (96%) create mode 100644 Marlin/src/HAL/LINUX/inc/Conditionals_LCD.h rename Marlin/src/HAL/{HAL_LINUX => LINUX}/inc/Conditionals_adv.h (91%) rename Marlin/src/HAL/{HAL_ESP32 => LINUX}/inc/Conditionals_post.h (91%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/inc/SanityCheck.h (83%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/include/Arduino.h (90%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/include/pinmapping.cpp (96%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/include/pinmapping.h (95%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/include/serial.h (97%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/main.cpp (97%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/pinsDebug.h (96%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/servo_private.h (97%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/spi_pins.h (88%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/timers.cpp (95%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/timers.h (85%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/watchdog.cpp (93%) rename Marlin/src/HAL/{HAL_LINUX => LINUX}/watchdog.h (92%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/DebugMonitor.cpp (98%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/HAL.cpp (91%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/HAL.h (78%) create mode 100644 Marlin/src/HAL/LPC1768/HAL_SPI.cpp rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/MarlinSerial.cpp (76%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/MarlinSerial.h (87%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/Servo.h (94%) rename Marlin/src/HAL/{HAL_LPC1768/persistent_store_flash.cpp => LPC1768/eeprom_flash.cpp} (82%) rename Marlin/src/HAL/{HAL_LPC1768/persistent_store_sdcard.cpp => LPC1768/eeprom_sdcard.cpp} (89%) create mode 100644 Marlin/src/HAL/LPC1768/eeprom_wired.cpp rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/endstop_interrupts.h (98%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/fast_pwm.cpp (87%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/fastio.h (94%) create mode 100644 Marlin/src/HAL/LPC1768/inc/Conditionals_LCD.h create mode 100644 Marlin/src/HAL/LPC1768/inc/Conditionals_adv.h create mode 100644 Marlin/src/HAL/LPC1768/inc/Conditionals_post.h create mode 100644 Marlin/src/HAL/LPC1768/inc/SanityCheck.h create mode 100644 Marlin/src/HAL/LPC1768/include/SPI.h rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/include/digipot_mcp4451_I2C_routines.c (98%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/include/digipot_mcp4451_I2C_routines.h (94%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/include/i2c_util.c (96%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/include/i2c_util.h (94%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/main.cpp (93%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/pinsDebug.h (96%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/spi_pins.h (88%) create mode 100644 Marlin/src/HAL/LPC1768/tft/tft_spi.cpp create mode 100644 Marlin/src/HAL/LPC1768/tft/tft_spi.h create mode 100644 Marlin/src/HAL/LPC1768/tft/xpt2046.cpp create mode 100644 Marlin/src/HAL/LPC1768/tft/xpt2046.h rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/timers.cpp (95%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/timers.h (78%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/u8g/LCD_I2C_routines.cpp (98%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/u8g/LCD_I2C_routines.h (93%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/u8g/LCD_defines.h (96%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/u8g/LCD_delay.h (94%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/u8g/LCD_pin_routines.c (97%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/u8g/LCD_pin_routines.h (94%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp (96%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp (98%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp (97%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp (98%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp (92%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/upload_extra_script.py (100%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/usb_serial.cpp (90%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/watchdog.cpp (96%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/watchdog.h (92%) rename Marlin/src/HAL/{HAL_LPC1768 => LPC1768}/win_usb_driver/lpc176x_usb_driver.inf (100%) rename Marlin/src/HAL/{HAL_SAMD51 => SAMD51}/HAL.cpp (85%) rename Marlin/src/HAL/{HAL_SAMD51 => SAMD51}/HAL.h (65%) rename Marlin/src/HAL/{HAL_SAMD51 => SAMD51}/HAL_SPI.cpp (98%) rename Marlin/src/HAL/{HAL_SAMD51 => SAMD51}/MarlinSerial_AGCM4.cpp (96%) rename Marlin/src/HAL/{HAL_SAMD51 => SAMD51}/MarlinSerial_AGCM4.h (91%) create mode 100644 Marlin/src/HAL/SAMD51/QSPIFlash.cpp create mode 100644 Marlin/src/HAL/SAMD51/QSPIFlash.h rename Marlin/src/HAL/{HAL_SAMD51 => SAMD51}/SAMD51.h (98%) rename Marlin/src/HAL/{HAL_SAMD51 => SAMD51}/Servo.cpp (95%) rename Marlin/src/HAL/{HAL_SAMD51 => SAMD51}/ServoTimers.h (94%) create mode 100644 Marlin/src/HAL/SAMD51/eeprom_flash.cpp create mode 100644 Marlin/src/HAL/SAMD51/eeprom_qspi.cpp create mode 100644 Marlin/src/HAL/SAMD51/eeprom_wired.cpp rename Marlin/src/HAL/{HAL_SAMD51 => SAMD51}/endstop_interrupts.h (88%) rename Marlin/src/HAL/{HAL_SAMD51 => SAMD51}/fastio.h (98%) create mode 100644 Marlin/src/HAL/SAMD51/inc/Conditionals_LCD.h create mode 100644 Marlin/src/HAL/SAMD51/inc/Conditionals_adv.h create mode 100644 Marlin/src/HAL/SAMD51/inc/Conditionals_post.h rename Marlin/src/HAL/{HAL_SAMD51 => SAMD51}/inc/SanityCheck.h (81%) rename Marlin/src/HAL/{HAL_SAMD51 => SAMD51}/pinsDebug.h (98%) rename Marlin/src/HAL/{HAL_SAMD51 => SAMD51}/spi_pins.h (94%) rename Marlin/src/HAL/{HAL_SAMD51 => SAMD51}/timers.cpp (86%) rename Marlin/src/HAL/{HAL_SAMD51 => SAMD51}/timers.h (83%) rename Marlin/src/HAL/{HAL_SAMD51 => SAMD51}/watchdog.cpp (95%) rename Marlin/src/HAL/{HAL_SAMD51 => SAMD51}/watchdog.h (94%) rename Marlin/src/HAL/{HAL_STM32 => STM32}/HAL.cpp (78%) rename Marlin/src/HAL/{HAL_STM32 => STM32}/HAL.h (55%) rename Marlin/src/HAL/{HAL_STM32 => STM32}/HAL_SPI.cpp (93%) create mode 100644 Marlin/src/HAL/STM32/MarlinSerial.cpp create mode 100644 Marlin/src/HAL/STM32/MarlinSerial.h rename Marlin/src/HAL/{HAL_STM32 => STM32}/README.md (100%) create mode 100644 Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp create mode 100644 Marlin/src/HAL/STM32/Servo.cpp create mode 100644 Marlin/src/HAL/STM32/Servo.h rename Marlin/src/HAL/{HAL_STM32/persistent_store_flash.cpp => STM32/eeprom_flash.cpp} (73%) rename Marlin/src/HAL/{HAL_STM32/persistent_store_sdcard.cpp => STM32/eeprom_sdcard.cpp} (52%) create mode 100644 Marlin/src/HAL/STM32/eeprom_sram.cpp create mode 100644 Marlin/src/HAL/STM32/eeprom_wired.cpp create mode 100644 Marlin/src/HAL/STM32/endstop_interrupts.h rename Marlin/src/HAL/{HAL_STM32 => STM32}/fastio.cpp (89%) rename Marlin/src/HAL/{HAL_STM32 => STM32}/fastio.h (72%) rename Marlin/src/HAL/{HAL_ESP32 => STM32}/inc/Conditionals_LCD.h (91%) create mode 100644 Marlin/src/HAL/STM32/inc/Conditionals_adv.h create mode 100644 Marlin/src/HAL/STM32/inc/Conditionals_post.h create mode 100644 Marlin/src/HAL/STM32/inc/SanityCheck.h rename Marlin/src/HAL/{HAL_STM32 => STM32}/pinsDebug.h (94%) rename Marlin/src/HAL/{HAL_STM32 => STM32}/pinsDebug_STM32GENERIC.h (94%) rename Marlin/src/HAL/{HAL_STM32 => STM32}/pinsDebug_STM32duino.h (96%) rename Marlin/src/HAL/{HAL_STM32 => STM32}/pins_Xref.h (99%) rename Marlin/src/HAL/{HAL_STM32 => STM32}/spi_pins.h (92%) create mode 100644 Marlin/src/HAL/STM32/tft/tft_fsmc.cpp create mode 100644 Marlin/src/HAL/STM32/tft/tft_fsmc.h create mode 100644 Marlin/src/HAL/STM32/tft/tft_spi.cpp create mode 100644 Marlin/src/HAL/STM32/tft/tft_spi.h create mode 100644 Marlin/src/HAL/STM32/tft/xpt2046.cpp create mode 100644 Marlin/src/HAL/STM32/tft/xpt2046.h create mode 100644 Marlin/src/HAL/STM32/timers.cpp rename Marlin/src/HAL/{HAL_STM32 => STM32}/timers.h (61%) create mode 100644 Marlin/src/HAL/STM32/usb_serial.cpp create mode 100644 Marlin/src/HAL/STM32/usb_serial.h rename Marlin/src/HAL/{HAL_STM32 => STM32}/watchdog.cpp (85%) rename Marlin/src/HAL/{HAL_STM32 => STM32}/watchdog.h (92%) rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/HAL.cpp (91%) rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/HAL.h (61%) rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/HAL_SPI.cpp (95%) create mode 100644 Marlin/src/HAL/STM32F1/MarlinSerial.cpp create mode 100644 Marlin/src/HAL/STM32F1/MarlinSerial.h rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/README.md (100%) rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/SPI.cpp (98%) rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/SPI.h (97%) rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/Servo.cpp (97%) rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/Servo.h (96%) rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/SoftwareSerial.cpp (93%) rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/SoftwareSerial.h (93%) rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/build_flags.py (95%) rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/dogm/u8g_com_stm32duino_swspi.cpp (87%) create mode 100644 Marlin/src/HAL/STM32F1/eeprom_bl24cxx.cpp rename Marlin/src/HAL/{HAL_STM32F1/persistent_store_flash.cpp => STM32F1/eeprom_flash.cpp} (81%) create mode 100644 Marlin/src/HAL/STM32F1/eeprom_if_iic.cpp rename Marlin/src/HAL/{HAL_STM32F1/persistent_store_sdcard.cpp => STM32F1/eeprom_sdcard.cpp} (52%) rename Marlin/src/HAL/{HAL_STM32F1/persistent_store_eeprom.cpp => STM32F1/eeprom_wired.cpp} (82%) rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/endstop_interrupts.h (65%) rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/fastio.h (98%) create mode 100644 Marlin/src/HAL/STM32F1/inc/Conditionals_LCD.h create mode 100644 Marlin/src/HAL/STM32F1/inc/Conditionals_adv.h create mode 100644 Marlin/src/HAL/STM32F1/inc/Conditionals_post.h rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/inc/SanityCheck.h (53%) rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/maple_win_usb_driver/maple_serial.inf (100%) rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/msc_sd.cpp (67%) create mode 100644 Marlin/src/HAL/STM32F1/msc_sd.h rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/onboard_sd.cpp (97%) rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/onboard_sd.h (100%) rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/pinsDebug.h (84%) rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/sdio.cpp (93%) rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/sdio.h (96%) rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/spi_pins.h (95%) rename Marlin/src/HAL/{HAL_STM32F1/dogm/u8g_com_stm32duino_fsmc.cpp => STM32F1/tft/tft_fsmc.cpp} (52%) create mode 100644 Marlin/src/HAL/STM32F1/tft/tft_fsmc.h create mode 100644 Marlin/src/HAL/STM32F1/tft/tft_spi.cpp create mode 100644 Marlin/src/HAL/STM32F1/tft/tft_spi.h create mode 100644 Marlin/src/HAL/STM32F1/tft/xpt2046.cpp create mode 100644 Marlin/src/HAL/STM32F1/tft/xpt2046.h rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/timers.cpp (93%) rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/timers.h (84%) rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/watchdog.cpp (90%) rename Marlin/src/HAL/{HAL_STM32F1 => STM32F1}/watchdog.h (94%) rename Marlin/src/HAL/{HAL_STM32_F4_F7 => STM32_F4_F7}/HAL.cpp (97%) rename Marlin/src/HAL/{HAL_STM32_F4_F7 => STM32_F4_F7}/HAL.h (64%) rename Marlin/src/HAL/{HAL_STM32_F4_F7 => STM32_F4_F7}/HAL_SPI.cpp (96%) rename Marlin/src/HAL/{HAL_STM32_F4_F7 => STM32_F4_F7}/README.md (100%) rename Marlin/src/HAL/{HAL_STM32_F4_F7 => STM32_F4_F7}/STM32F4/README.md (100%) rename Marlin/src/HAL/{HAL_STM32_F4_F7 => STM32_F4_F7}/STM32F4/timers.cpp (97%) rename Marlin/src/HAL/{HAL_STM32_F4_F7 => STM32_F4_F7}/STM32F4/timers.h (85%) rename Marlin/src/HAL/{HAL_STM32_F4_F7 => STM32_F4_F7}/STM32F7/README.md (100%) rename Marlin/src/HAL/{HAL_STM32_F4_F7 => STM32_F4_F7}/STM32F7/TMC2660.cpp (96%) rename Marlin/src/HAL/{HAL_STM32_F4_F7 => STM32_F4_F7}/STM32F7/TMC2660.h (99%) rename Marlin/src/HAL/{HAL_STM32_F4_F7 => STM32_F4_F7}/STM32F7/timers.cpp (97%) rename Marlin/src/HAL/{HAL_STM32_F4_F7 => STM32_F4_F7}/STM32F7/timers.h (86%) rename Marlin/src/HAL/{HAL_STM32_F4_F7 => STM32_F4_F7}/Servo.cpp (91%) rename Marlin/src/HAL/{HAL_STM32_F4_F7 => STM32_F4_F7}/Servo.h (94%) rename Marlin/src/HAL/{HAL_STM32_F4_F7 => STM32_F4_F7}/eeprom_emul.cpp (99%) rename Marlin/src/HAL/{HAL_STM32_F4_F7 => STM32_F4_F7}/eeprom_emul.h (99%) rename Marlin/src/HAL/{HAL_STM32_F4_F7/EmulatedEeprom.cpp => STM32_F4_F7/eeprom_flash.cpp} (55%) rename Marlin/src/HAL/{HAL_STM32_F4_F7/persistent_store_eeprom.cpp => STM32_F4_F7/eeprom_wired.cpp} (76%) create mode 100644 Marlin/src/HAL/STM32_F4_F7/endstop_interrupts.h rename Marlin/src/HAL/{HAL_STM32_F4_F7 => STM32_F4_F7}/fastio.h (98%) create mode 100644 Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_LCD.h create mode 100644 Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_adv.h create mode 100644 Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_post.h rename Marlin/src/HAL/{HAL_STM32_F4_F7 => STM32_F4_F7}/inc/SanityCheck.h (84%) rename Marlin/src/HAL/{HAL_STM32_F4_F7 => STM32_F4_F7}/pinsDebug.h (84%) rename Marlin/src/HAL/{HAL_STM32_F4_F7 => STM32_F4_F7}/spi_pins.h (92%) rename Marlin/src/HAL/{HAL_STM32_F4_F7 => STM32_F4_F7}/timers.h (92%) rename Marlin/src/HAL/{HAL_STM32_F4_F7 => STM32_F4_F7}/watchdog.cpp (95%) rename Marlin/src/HAL/{HAL_STM32_F4_F7 => STM32_F4_F7}/watchdog.h (92%) rename Marlin/src/HAL/{HAL_TEENSY31_32 => TEENSY31_32}/HAL.cpp (95%) rename Marlin/src/HAL/{HAL_TEENSY31_32 => TEENSY31_32}/HAL.h (83%) rename Marlin/src/HAL/{HAL_TEENSY31_32 => TEENSY31_32}/HAL_SPI.cpp (97%) rename Marlin/src/HAL/{HAL_TEENSY31_32 => TEENSY31_32}/Servo.cpp (91%) rename Marlin/src/HAL/{HAL_TEENSY31_32 => TEENSY31_32}/Servo.h (94%) rename Marlin/src/HAL/{HAL_TEENSY31_32/persistent_store_impl.cpp => TEENSY31_32/eeprom.cpp} (78%) rename Marlin/src/HAL/{HAL_DUE => TEENSY31_32}/endstop_interrupts.h (68%) rename Marlin/src/HAL/{HAL_TEENSY35_36 => TEENSY31_32}/fastio.h (92%) create mode 100644 Marlin/src/HAL/TEENSY31_32/inc/Conditionals_LCD.h create mode 100644 Marlin/src/HAL/TEENSY31_32/inc/Conditionals_adv.h rename Marlin/src/HAL/{HAL_LINUX => TEENSY31_32}/inc/Conditionals_post.h (85%) rename Marlin/src/HAL/{HAL_TEENSY31_32 => TEENSY31_32}/inc/SanityCheck.h (81%) rename Marlin/src/HAL/{HAL_TEENSY31_32 => TEENSY31_32}/pinsDebug.h (100%) rename Marlin/src/HAL/{HAL_TEENSY31_32 => TEENSY31_32}/spi_pins.h (92%) rename Marlin/src/HAL/{HAL_TEENSY31_32 => TEENSY31_32}/timers.cpp (96%) rename Marlin/src/HAL/{HAL_TEENSY31_32 => TEENSY31_32}/timers.h (83%) rename Marlin/src/HAL/{HAL_TEENSY31_32 => TEENSY31_32}/watchdog.cpp (93%) rename Marlin/src/HAL/{HAL_TEENSY31_32 => TEENSY31_32}/watchdog.h (93%) rename Marlin/src/HAL/{HAL_TEENSY35_36 => TEENSY35_36}/HAL.cpp (96%) rename Marlin/src/HAL/{HAL_TEENSY35_36 => TEENSY35_36}/HAL.h (81%) rename Marlin/src/HAL/{HAL_TEENSY35_36 => TEENSY35_36}/HAL_SPI.cpp (94%) rename Marlin/src/HAL/{HAL_TEENSY35_36 => TEENSY35_36}/Servo.cpp (89%) rename Marlin/src/HAL/{HAL_TEENSY35_36 => TEENSY35_36}/Servo.h (88%) rename Marlin/src/HAL/{HAL_TEENSY35_36/persistent_store_eeprom.cpp => TEENSY35_36/eeprom.cpp} (81%) rename Marlin/src/HAL/{HAL_TEENSY35_36 => TEENSY35_36}/endstop_interrupts.h (66%) rename Marlin/src/HAL/{HAL_TEENSY31_32 => TEENSY35_36}/fastio.h (92%) create mode 100644 Marlin/src/HAL/TEENSY35_36/inc/Conditionals_LCD.h create mode 100644 Marlin/src/HAL/TEENSY35_36/inc/Conditionals_adv.h create mode 100644 Marlin/src/HAL/TEENSY35_36/inc/Conditionals_post.h rename Marlin/src/HAL/{HAL_TEENSY35_36 => TEENSY35_36}/inc/SanityCheck.h (81%) rename Marlin/src/HAL/{HAL_TEENSY35_36 => TEENSY35_36}/pinsDebug.h (94%) rename Marlin/src/HAL/{HAL_TEENSY35_36 => TEENSY35_36}/spi_pins.h (85%) rename Marlin/src/HAL/{HAL_TEENSY35_36 => TEENSY35_36}/timers.cpp (95%) rename Marlin/src/HAL/{HAL_TEENSY35_36 => TEENSY35_36}/timers.h (83%) rename Marlin/src/HAL/{HAL_TEENSY35_36 => TEENSY35_36}/watchdog.cpp (93%) rename Marlin/src/HAL/{HAL_TEENSY35_36 => TEENSY35_36}/watchdog.h (92%) create mode 100644 Marlin/src/HAL/TEENSY40_41/HAL.cpp create mode 100644 Marlin/src/HAL/TEENSY40_41/HAL.h create mode 100644 Marlin/src/HAL/TEENSY40_41/HAL_SPI.cpp rename Marlin/src/HAL/{HAL_STM32 => TEENSY40_41}/Servo.cpp (52%) rename Marlin/src/HAL/{HAL_STM32 => TEENSY40_41}/Servo.h (68%) create mode 100644 Marlin/src/HAL/TEENSY40_41/eeprom.cpp create mode 100644 Marlin/src/HAL/TEENSY40_41/endstop_interrupts.h create mode 100644 Marlin/src/HAL/TEENSY40_41/fastio.h create mode 100644 Marlin/src/HAL/TEENSY40_41/inc/Conditionals_LCD.h create mode 100644 Marlin/src/HAL/TEENSY40_41/inc/Conditionals_adv.h create mode 100644 Marlin/src/HAL/TEENSY40_41/inc/Conditionals_post.h create mode 100644 Marlin/src/HAL/TEENSY40_41/inc/SanityCheck.h create mode 100644 Marlin/src/HAL/TEENSY40_41/pinsDebug.h create mode 100644 Marlin/src/HAL/TEENSY40_41/spi_pins.h create mode 100644 Marlin/src/HAL/TEENSY40_41/timers.cpp create mode 100644 Marlin/src/HAL/TEENSY40_41/timers.h create mode 100644 Marlin/src/HAL/TEENSY40_41/watchdog.cpp create mode 100644 Marlin/src/HAL/TEENSY40_41/watchdog.h delete mode 100644 Marlin/src/HAL/shared/MarlinSerial.h rename Marlin/src/HAL/shared/{persistent_store_api.cpp => eeprom_api.cpp} (90%) rename Marlin/src/HAL/shared/{persistent_store_api.h => eeprom_api.h} (75%) delete mode 100644 Marlin/src/HAL/shared/eeprom_i2c.cpp create mode 100644 Marlin/src/HAL/shared/eeprom_if.h create mode 100644 Marlin/src/HAL/shared/eeprom_if_i2c.cpp rename Marlin/src/HAL/shared/{eeprom_spi.cpp => eeprom_if_spi.cpp} (57%) create mode 100644 Marlin/src/HAL/shared/esp_wifi.cpp rename Marlin/src/HAL/{HAL_DUE/inc/Conditionals_LCD.h => shared/esp_wifi.h} (89%) rename Marlin/src/{HAL/HAL_LPC1768/include/SPI.h => core/debug_section.h} (58%) delete mode 100644 Marlin/src/core/multi_language.cpp rename Marlin/src/feature/{binary_protocol.cpp => binary_stream.cpp} (90%) rename Marlin/src/feature/{binary_protocol.h => binary_stream.h} (95%) create mode 100644 Marlin/src/feature/direct_stepping.cpp create mode 100644 Marlin/src/feature/direct_stepping.h rename Marlin/src/feature/{emergency_parser.cpp => e_parser.cpp} (85%) rename Marlin/src/feature/{emergency_parser.h => e_parser.h} (88%) rename Marlin/src/feature/{I2CPositionEncoder.cpp => encoder_i2c.cpp} (98%) rename Marlin/src/feature/{I2CPositionEncoder.h => encoder_i2c.h} (98%) create mode 100644 Marlin/src/feature/hotend_idle.cpp create mode 100644 Marlin/src/feature/hotend_idle.h create mode 100644 Marlin/src/feature/leds/pca9533.cpp create mode 100644 Marlin/src/feature/leds/pca9533.h rename Marlin/src/feature/{Max7219_Debug_LEDs.cpp => max7219.cpp} (85%) rename Marlin/src/feature/{Max7219_Debug_LEDs.h => max7219.h} (91%) rename Marlin/src/feature/{prusa_MMU2 => mmu2}/mmu2.cpp (59%) rename Marlin/src/feature/{prusa_MMU2 => mmu2}/mmu2.h (71%) rename Marlin/src/feature/{prusa_MMU2 => mmu2}/serial-protocol.md (100%) create mode 100644 Marlin/src/feature/password/password.cpp create mode 100644 Marlin/src/feature/password/password.h create mode 100644 Marlin/src/feature/power_monitor.cpp create mode 100644 Marlin/src/feature/power_monitor.h rename Marlin/src/feature/{power_loss_recovery.cpp => powerloss.cpp} (65%) rename Marlin/src/feature/{power_loss_recovery.h => powerloss.h} (73%) rename Marlin/src/feature/{probe_temp_compensation.cpp => probe_temp_comp.cpp} (78%) rename Marlin/src/feature/{probe_temp_compensation.h => probe_temp_comp.h} (63%) create mode 100644 Marlin/src/feature/spindle_laser_types.h delete mode 100644 Marlin/src/feature/touch/xpt2046.cpp delete mode 100644 Marlin/src/feature/touch/xpt2046.h create mode 100755 Marlin/src/gcode/bedlevel/G35.cpp create mode 100644 Marlin/src/gcode/calibrate/G34.cpp rename Marlin/src/gcode/calibrate/{G76_M871.cpp => G76_M192_M871.cpp} (51%) create mode 100644 Marlin/src/gcode/control/M993_M994.cpp create mode 100644 Marlin/src/gcode/feature/controllerfan/M710.cpp create mode 100644 Marlin/src/gcode/feature/password/M510-M512.cpp create mode 100644 Marlin/src/gcode/feature/power_monitor/M430.cpp create mode 100644 Marlin/src/gcode/gcode_d.cpp create mode 100644 Marlin/src/gcode/host/M360.cpp create mode 100644 Marlin/src/gcode/lcd/M995.cpp create mode 100644 Marlin/src/gcode/motion/G6.cpp create mode 100644 Marlin/src/gcode/sd/M1001.cpp rename Marlin/src/gcode/{sdcard => sd}/M20.cpp (80%) rename Marlin/src/gcode/{sdcard => sd}/M21_M22.cpp (87%) rename Marlin/src/gcode/{sdcard => sd}/M23.cpp (89%) rename Marlin/src/gcode/{sdcard => sd}/M24_M25.cpp (78%) rename Marlin/src/gcode/{sdcard => sd}/M26.cpp (93%) rename Marlin/src/gcode/{sdcard => sd}/M27.cpp (95%) rename Marlin/src/gcode/{sdcard => sd}/M28_M29.cpp (89%) rename Marlin/src/gcode/{sdcard => sd}/M30.cpp (93%) rename Marlin/src/gcode/{sdcard => sd}/M32.cpp (95%) rename Marlin/src/gcode/{sdcard => sd}/M33.cpp (94%) rename Marlin/src/gcode/{sdcard => sd}/M34.cpp (94%) rename Marlin/src/gcode/{sdcard => sd}/M524.cpp (89%) rename Marlin/src/gcode/{sdcard => sd}/M928.cpp (93%) rename Marlin/src/gcode/{temperature => temp}/M104_M109.cpp (59%) rename Marlin/src/gcode/{temperature => temp}/M105.cpp (94%) rename Marlin/src/gcode/{temperature => temp}/M106_M107.cpp (64%) create mode 100644 Marlin/src/gcode/temp/M140_M190.cpp rename Marlin/src/gcode/{temperature => temp}/M141_M191.cpp (79%) rename Marlin/src/gcode/{temperature => temp}/M155.cpp (89%) rename Marlin/src/gcode/{temperature => temp}/M303.cpp (52%) delete mode 100644 Marlin/src/gcode/temperature/M140_M190.cpp create mode 100644 Marlin/src/lcd/TFTGLCD/lcdprint_TFTGLCD.cpp create mode 100644 Marlin/src/lcd/TFTGLCD/ultralcd_TFTGLCD.cpp create mode 100644 Marlin/src/lcd/TFTGLCD/ultralcd_TFTGLCD.h create mode 100644 Marlin/src/lcd/dogm/fontdata/langdata_hu.h create mode 100644 Marlin/src/lcd/dogm/fontdata/langdata_ro.h delete mode 100644 Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp create mode 100644 Marlin/src/lcd/dogm/u8g_dev_tft_upscale_from_128x64.cpp create mode 100644 Marlin/src/lcd/dwin/dwin_lcd.cpp create mode 100644 Marlin/src/lcd/dwin/dwin_lcd.h create mode 100644 Marlin/src/lcd/dwin/e3v2/README.md create mode 100644 Marlin/src/lcd/dwin/e3v2/dwin.cpp create mode 100644 Marlin/src/lcd/dwin/e3v2/dwin.h create mode 100644 Marlin/src/lcd/dwin/e3v2/rotary_encoder.cpp create mode 100644 Marlin/src/lcd/dwin/e3v2/rotary_encoder.h delete mode 100644 Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinitionOrigin.cpp delete mode 100644 Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/config.h delete mode 100644 Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/boards.h delete mode 100644 Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set.cpp delete mode 100644 Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set_bitmap_31.h delete mode 100644 Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/pin_mappings.h delete mode 100644 Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/advanced_settings_menu.cpp delete mode 100644 Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/main_menu.cpp delete mode 100644 Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/stepper_current_screen.cpp delete mode 100644 Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/tune_menu.cpp delete mode 100644 Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/colors.h create mode 100644 Marlin/src/lcd/extui/anycubic_chiron_lcd.cpp create mode 100644 Marlin/src/lcd/extui/anycubic_i3mega_lcd.cpp rename Marlin/src/lcd/{extui_dgus_lcd.cpp => extui/dgus_lcd.cpp} (74%) rename Marlin/src/lcd/{extui_example.cpp => extui/example.cpp} (86%) create mode 100644 Marlin/src/lcd/extui/lib/anycubic_chiron/FileNavigator.cpp create mode 100644 Marlin/src/lcd/extui/lib/anycubic_chiron/FileNavigator.h create mode 100644 Marlin/src/lcd/extui/lib/anycubic_chiron/Tunes.cpp create mode 100644 Marlin/src/lcd/extui/lib/anycubic_chiron/Tunes.h create mode 100644 Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft.cpp create mode 100644 Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft.h create mode 100644 Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft_defs.h create mode 100644 Marlin/src/lcd/extui/lib/anycubic_i3mega/anycubic_i3mega_lcd.cpp create mode 100644 Marlin/src/lcd/extui/lib/anycubic_i3mega/anycubic_i3mega_lcd.h create mode 100644 Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.cpp create mode 100644 Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.h rename Marlin/src/lcd/{extensible_ui/lib/dgus/DGUSDisplayDefinition.h => extui/lib/dgus/DGUSDisplayDef.h} (86%) rename Marlin/src/lcd/{extensible_ui/lib/dgus/DGUSDisplay.cpp => extui/lib/dgus/DGUSScreenHandler.cpp} (67%) rename Marlin/src/lcd/{extensible_ui/lib/dgus/DGUSDisplay.h => extui/lib/dgus/DGUSScreenHandler.h} (73%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/dgus/DGUSVPVariable.h (93%) rename Marlin/src/lcd/{extensible_ui/lib/dgus/DGUSDisplayDefinitionFYSETC.cpp => extui/lib/dgus/fysetc/DGUSDisplayDef.cpp} (54%) rename Marlin/src/lcd/{extensible_ui/lib/dgus/DGUSDisplayDefinitionFYSETC.h => extui/lib/dgus/fysetc/DGUSDisplayDef.h} (95%) rename Marlin/src/lcd/{extensible_ui/lib/dgus/DGUSDisplayDefinitionHIPRECY.cpp => extui/lib/dgus/hiprecy/DGUSDisplayDef.cpp} (55%) rename Marlin/src/lcd/{extensible_ui/lib/dgus/DGUSDisplayDefinitionHIPRECY.h => extui/lib/dgus/hiprecy/DGUSDisplayDef.h} (99%) create mode 100644 Marlin/src/lcd/extui/lib/dgus/origin/DGUSDisplayDef.cpp rename Marlin/src/lcd/{extensible_ui/lib/dgus/DGUSDisplayDefinitionOrigin.h => extui/lib/dgus/origin/DGUSDisplayDef.h} (98%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/archim2-flash/flash_storage.cpp (97%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/archim2-flash/flash_storage.h (97%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/archim2-flash/media_file_reader.cpp (97%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/archim2-flash/media_file_reader.h (95%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/compat.h (96%) create mode 100644 Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/config.h rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/LICENSE.txt (99%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/README.md (100%) create mode 100644 Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/boards.h rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.cpp (86%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.h (98%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/constants.h (99%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/display_list.h (100%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/ftdi_basic.h (95%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/registers_ft800.h (98%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/registers_ft810.h (99%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/resolutions.h (93%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/spi.cpp (77%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/spi.h (94%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/compat.h (65%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/bitmap_info.h (96%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.cpp (94%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.h (99%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/dl_cache.cpp (69%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/dl_cache.h (74%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/event_loop.cpp (92%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/event_loop.h (97%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/ftdi_extended.h (94%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/grid_layout.h (95%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/polygon.h (97%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/rgb_t.h (97%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/screen_types.cpp (93%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/screen_types.h (94%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_list.h (87%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_player.cpp (97%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_player.h (96%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.cpp (97%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.h (95%) create mode 100644 Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_ellipsis.cpp create mode 100644 Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_ellipsis.h rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/tiny_timer.cpp (95%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/tiny_timer.h (96%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/README.txt (100%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps.cpp (95%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps.h (95%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/romfont_31.pbm (100%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/western_char_set_bitmap_31.png (100%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/western_char_set_bitmap_31.svg (100%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_size_t.cpp (93%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_size_t.h (96%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/standard_char_set.cpp (96%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/standard_char_set.h (95%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.cpp (97%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.h (98%) create mode 100644 Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set.cpp rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set.h (94%) create mode 100644 Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set_bitmap_31.h rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/bitmap2cpp.py (98%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/circular_progress.h (97%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/poly_ui.h (91%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/svg2cpp.py (98%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/ftdi_eve_lib/ftdi_eve_lib.h (94%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/language/language.cpp (94%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/language/language.h (94%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/language/language_en.h (86%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/marlin_events.cpp (77%) create mode 100644 Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/pin_mappings.h rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/about_screen.cpp (53%) create mode 100644 Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/advanced_settings_menu.cpp rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/alert_dialog_box.cpp (96%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/backlash_compensation_screen.cpp (97%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/base_numeric_adjustment_screen.cpp (95%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/base_screen.cpp (92%) create mode 100644 Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bed_mesh_screen.cpp rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/bio_advanced_settings.cpp (93%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/bio_confirm_home_e.cpp (85%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/bio_confirm_home_xyz.cpp (88%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/bio_main_menu.cpp (96%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/bio_printer_ui_landscape.h (98%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/bio_printer_ui_portrait.h (98%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/bio_printing_dialog_box.cpp (94%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/bio_status_screen.cpp (89%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/bio_tune_menu.cpp (95%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/boot_screen.cpp (90%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/case_light_screen.cpp (96%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/change_filament_screen.cpp (96%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/confirm_abort_print_dialog_box.cpp (95%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/confirm_auto_calibration_dialog_box.cpp (93%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/confirm_erase_flash_dialog_box.cpp (96%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/confirm_start_print_dialog_box.cpp (93%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/confirm_user_request_alert_box.cpp (96%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/default_acceleration_screen.cpp (97%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/developer_menu.cpp (98%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/dialog_box_base_class.cpp (97%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/display_tuning_screen.cpp (97%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/endstop_state_screen.cpp (96%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/feedrate_percent_screen.cpp (96%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/filament_menu.cpp (60%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/filament_runout_screen.cpp (94%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/files_screen.cpp (91%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/interface_settings_screen.cpp (93%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/interface_sounds_screen.cpp (96%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/jerk_screen.cpp (97%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/junction_deviation_screen.cpp (93%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/kill_screen.cpp (96%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/language_menu.cpp (96%) create mode 100644 Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/leveling_menu.cpp rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/linear_advance_screen.cpp (95%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/lock_screen.cpp (94%) create mode 100644 Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/main_menu.cpp rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/max_acceleration_screen.cpp (91%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/max_velocity_screen.cpp (93%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/media_player_screen.cpp (98%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/move_axis_screen.cpp (96%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/nozzle_offsets_screen.cpp (95%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/nudge_nozzle_screen.cpp (94%) create mode 100644 Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/preheat_menu.cpp rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/preheat_timer_screen.cpp (95%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/restore_failsafe_dialog_box.cpp (96%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/save_settings_dialog_box.cpp (96%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/screen_data.h (75%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/screens.cpp (90%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/screens.h (85%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/spinner_dialog_box.cpp (96%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/statistics_screen.cpp (97%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/status_screen.cpp (54%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/stepper_bump_sensitivity_screen.cpp (73%) create mode 100644 Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/stepper_current_screen.cpp rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/steps_screen.cpp (96%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/stress_test_screen.cpp (86%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/string_format.cpp (93%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/string_format.h (91%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/temperature_screen.cpp (91%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/touch_calibration_screen.cpp (89%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/touch_registers_screen.cpp (98%) create mode 100644 Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/tune_menu.cpp rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/widget_demo_screen.cpp (98%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/screens/z_offset_screen.cpp (94%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/theme/bitmaps.h (98%) create mode 100644 Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/bootscreen_logo_portrait.h create mode 100644 Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/colors.h rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/theme/fonts.h (97%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/theme/marlin_bootscreen_landscape.h (96%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/theme/marlin_bootscreen_portrait.h (96%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/theme/sounds.cpp (99%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/theme/sounds.h (96%) rename Marlin/src/lcd/{extensible_ui => extui}/lib/ftdi_eve_touch_ui/theme/theme.h (94%) create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/SPIFlashStorage.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/SPIFlashStorage.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/SPI_TFT.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/SPI_TFT.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_about.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_about.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_acceleration_settings.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_acceleration_settings.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_advance_settings.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_advance_settings.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_auto_level_offset_settings.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_auto_level_offset_settings.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_baby_stepping.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_baby_stepping.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_change_speed.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_change_speed.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_dialog.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_dialog.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_eeprom_settings.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_eeprom_settings.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_encoder_settings.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_encoder_settings.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_error_message.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_error_message.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_extrusion.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_extrusion.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_fan.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_fan.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_filament_change.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_filament_change.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_filament_settings.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_filament_settings.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_home.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_home.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_homing_sensitivity_settings.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_homing_sensitivity_settings.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_jerk_settings.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_jerk_settings.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_keyboard.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_keyboard.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_language.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_language.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_level_settings.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_level_settings.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_machine_para.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_machine_para.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_machine_settings.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_machine_settings.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_manuaLevel.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_manuaLevel.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_manual_level_pos_settings.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_manual_level_pos_settings.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_max_feedrate_settings.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_max_feedrate_settings.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_motor_settings.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_motor_settings.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_move_motor.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_move_motor.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_number_key.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_number_key.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_operation.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_operation.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_pause_message.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_pause_message.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_pause_position.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_pause_position.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_preHeat.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_preHeat.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_print_file.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_print_file.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_printing.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_printing.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_ready_print.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_ready_print.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_set.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_set.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_step_settings.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_step_settings.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_current_settings.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_current_settings.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_step_mode_settings.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_step_mode_settings.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_tool.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_tool.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_ui.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_ui.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_wifi.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_wifi.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_list.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_list.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_settings.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_settings.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_tips.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_tips.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/gb2312_puhui16.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/irq_overrid.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/mks_hardware_test.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/mks_hardware_test.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/pic_manager.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/pic_manager.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/printer_operation.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/printer_operation.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/tft_Language_en.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/tft_Language_fr.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/tft_Language_it.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/tft_Language_ru.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/tft_Language_s_cn.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/tft_Language_sp.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/tft_Language_t_cn.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/tft_lvgl_configuration.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/tft_lvgl_configuration.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/wifiSerial.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/wifiSerial.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/wifi_module.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/wifi_module.h create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/wifi_upload.cpp create mode 100644 Marlin/src/lcd/extui/lib/mks_ui/wifi_upload.h rename Marlin/src/lcd/{extui_malyan_lcd.cpp => extui/malyan_lcd.cpp} (79%) rename Marlin/src/lcd/{extensible_ui => extui}/ui_api.cpp (76%) rename Marlin/src/lcd/{extensible_ui => extui}/ui_api.h (91%) create mode 100644 Marlin/src/lcd/language/language_hu.h create mode 100644 Marlin/src/lcd/language/language_ro.h create mode 100644 Marlin/src/lcd/menu/menu_item.h create mode 100644 Marlin/src/lcd/menu/menu_password.cpp create mode 100644 Marlin/src/lcd/menu/menu_power_monitor.cpp create mode 100644 Marlin/src/lcd/menu/menu_probe_offset.cpp create mode 100644 Marlin/src/lcd/menu/menu_touch_screen.cpp create mode 100644 Marlin/src/lcd/scaled_tft.h create mode 100644 Marlin/src/lcd/tft/bitmaps/back.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/bed.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/bed_heated.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/btn_64x52_rounded.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/cancel.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/chamber.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/chamber_heated.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/confirm.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/decrease.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/directory.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/down.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/fan0.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/fan1.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/fan_fast0.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/fan_fast1.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/fan_slow0.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/fan_slow1.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/feedrate.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/flowrate.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/home.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/hotend.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/increase.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/left.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/leveling.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/marlin-logo/Marlin-1500x319.png create mode 100644 Marlin/src/lcd/tft/bitmaps/marlin-logo/Marlin-195x59.png create mode 100644 Marlin/src/lcd/tft/bitmaps/marlin-logo/Marlin-228x255-greyscale.png create mode 100644 Marlin/src/lcd/tft/bitmaps/marlin-logo/Marlin-228x255.png create mode 100644 Marlin/src/lcd/tft/bitmaps/marlin-logo/Marlin-280x200.png create mode 100644 Marlin/src/lcd/tft/bitmaps/marlin-logo/Marlin-320x240.png create mode 100644 Marlin/src/lcd/tft/bitmaps/marlin-logo/Marlin-480x319.png create mode 100644 Marlin/src/lcd/tft/bitmaps/marlin-logo/Marlin-480x320.png create mode 100644 Marlin/src/lcd/tft/bitmaps/menu.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/pause.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/refresh.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/right.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/sd.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/settings.bmp create mode 100644 Marlin/src/lcd/tft/bitmaps/up.bmp create mode 100644 Marlin/src/lcd/tft/canvas.cpp create mode 100644 Marlin/src/lcd/tft/canvas.h create mode 100644 Marlin/src/lcd/tft/fontdata/fontdata_10x20.cpp create mode 100644 Marlin/src/lcd/tft/fontdata/fontdata_ISO10646_1.cpp create mode 100644 Marlin/src/lcd/tft/fontdata/helvetica_12_bold.cpp create mode 100644 Marlin/src/lcd/tft/fontdata/helvetica_14.cpp create mode 100644 Marlin/src/lcd/tft/fontdata/helvetica_18.cpp create mode 100644 Marlin/src/lcd/tft/fontdata/profont_22.cpp create mode 100644 Marlin/src/lcd/tft/images/back_32x32x4.cpp create mode 100644 Marlin/src/lcd/tft/images/background_320x30x16.cpp create mode 100644 Marlin/src/lcd/tft/images/bootscreen_112x38x1.cpp create mode 100644 Marlin/src/lcd/tft/images/bootscreen_195x59x16.cpp create mode 100644 Marlin/src/lcd/tft/images/bootscreen_228x255x2.cpp create mode 100644 Marlin/src/lcd/tft/images/bootscreen_228x255x4.cpp create mode 100644 Marlin/src/lcd/tft/images/bootscreen_320x240x16.cpp create mode 100644 Marlin/src/lcd/tft/images/bootscreen_480x320x16.cpp create mode 100644 Marlin/src/lcd/tft/images/btn_rounded_64x52x4.cpp create mode 100644 Marlin/src/lcd/tft/images/cancel_64x64x4.cpp create mode 100644 Marlin/src/lcd/tft/images/chamber_64x64x4.cpp create mode 100644 Marlin/src/lcd/tft/images/confirm_64x64x4.cpp create mode 100644 Marlin/src/lcd/tft/images/decrease_64x64x4.cpp create mode 100644 Marlin/src/lcd/tft/images/directory_32x32x4.cpp create mode 100644 Marlin/src/lcd/tft/images/down_32x32x4.cpp create mode 100644 Marlin/src/lcd/tft/images/fan_64x64x4.cpp create mode 100644 Marlin/src/lcd/tft/images/fan_fast_64x64x4.cpp create mode 100644 Marlin/src/lcd/tft/images/fan_slow_64x64x4.cpp create mode 100644 Marlin/src/lcd/tft/images/feedrate_32x32x4.cpp create mode 100644 Marlin/src/lcd/tft/images/flowrate_32x32x4.cpp create mode 100644 Marlin/src/lcd/tft/images/heated_bed_64x64x4.cpp create mode 100644 Marlin/src/lcd/tft/images/home_64x64x4.cpp create mode 100644 Marlin/src/lcd/tft/images/hotend_64x64x4.cpp create mode 100644 Marlin/src/lcd/tft/images/increase_64x64x4.cpp create mode 100644 Marlin/src/lcd/tft/images/left_32x32x4.cpp create mode 100644 Marlin/src/lcd/tft/images/leveling_32x32x4.cpp create mode 100644 Marlin/src/lcd/tft/images/menu_64x64x4.cpp create mode 100644 Marlin/src/lcd/tft/images/pause_64x64x4.cpp create mode 100644 Marlin/src/lcd/tft/images/refresh_32x32x4.cpp create mode 100644 Marlin/src/lcd/tft/images/right_32x32x4.cpp create mode 100644 Marlin/src/lcd/tft/images/sd_64x64x4.cpp create mode 100644 Marlin/src/lcd/tft/images/settings_64x64x4.cpp create mode 100644 Marlin/src/lcd/tft/images/slider_8x16x4.cpp create mode 100644 Marlin/src/lcd/tft/images/up_32x32x4.cpp create mode 100644 Marlin/src/lcd/tft/tft.cpp create mode 100644 Marlin/src/lcd/tft/tft.h create mode 100644 Marlin/src/lcd/tft/tft_color.h create mode 100644 Marlin/src/lcd/tft/tft_image.cpp create mode 100644 Marlin/src/lcd/tft/tft_image.h create mode 100644 Marlin/src/lcd/tft/tft_queue.cpp create mode 100644 Marlin/src/lcd/tft/tft_queue.h create mode 100644 Marlin/src/lcd/tft/tft_string.cpp create mode 100644 Marlin/src/lcd/tft/tft_string.h create mode 100644 Marlin/src/lcd/tft/touch.cpp create mode 100644 Marlin/src/lcd/tft/touch.h create mode 100644 Marlin/src/lcd/tft/ui_320x240.cpp create mode 100644 Marlin/src/lcd/tft/ui_320x240.h create mode 100644 Marlin/src/lcd/tft/ui_480x320.cpp create mode 100644 Marlin/src/lcd/tft/ui_480x320.h create mode 100644 Marlin/src/lcd/tft_io/ili9328.h create mode 100644 Marlin/src/lcd/tft_io/ili9341.h create mode 100644 Marlin/src/lcd/tft_io/ili9488.h create mode 100644 Marlin/src/lcd/tft_io/r65105.h create mode 100644 Marlin/src/lcd/tft_io/ssd1963.h create mode 100644 Marlin/src/lcd/tft_io/st7735.h create mode 100644 Marlin/src/lcd/tft_io/st7789v.h create mode 100644 Marlin/src/lcd/tft_io/st7796s.h create mode 100644 Marlin/src/lcd/tft_io/tft_io.cpp create mode 100644 Marlin/src/lcd/tft_io/tft_io.h create mode 100644 Marlin/src/lcd/touch/touch_buttons.cpp create mode 100644 Marlin/src/lcd/touch/touch_buttons.h create mode 100644 Marlin/src/libs/BL24CXX.cpp create mode 100644 Marlin/src/libs/BL24CXX.h create mode 100644 Marlin/src/libs/W25Qxx.cpp create mode 100644 Marlin/src/libs/W25Qxx.h create mode 100644 Marlin/src/libs/hex_print.cpp rename Marlin/src/libs/{hex_print_routines.h => hex_print.h} (89%) delete mode 100644 Marlin/src/libs/hex_print_routines.cpp rename Marlin/src/module/{configuration_store.cpp => settings.cpp} (77%) rename Marlin/src/module/{configuration_store.h => settings.h} (93%) create mode 100644 Marlin/src/module/thermistor/thermistor_202.h create mode 100644 Marlin/src/module/thermistor/thermistor_22.h create mode 100644 Marlin/src/module/thermistor/thermistor_23.h create mode 100644 Marlin/src/module/thermistor/thermistor_30.h create mode 100644 Marlin/src/module/thermistor/thermistor_502.h create mode 100644 Marlin/src/pins/lpc1769/pins_BTT_SKR_E3_TURBO.h create mode 100644 Marlin/src/pins/lpc1769/pins_MKS_SGEN_L_V2.h create mode 100644 Marlin/src/pins/mega/pins_INTAMSYS40.h create mode 100644 Marlin/src/pins/ramps/pins_COPYMASTER_3D.h create mode 100644 Marlin/src/pins/ramps/pins_K8600.h create mode 100644 Marlin/src/pins/ramps/pins_MKS_GEN_L_V21.h create mode 100644 Marlin/src/pins/ramps/pins_ORTUR_4.h create mode 100644 Marlin/src/pins/ramps/pins_TENLOG_D3_HERO.h create mode 100644 Marlin/src/pins/sanguino/pins_MELZI_V2.h create mode 100644 Marlin/src/pins/sanguino/pins_ZMIB_V2.h delete mode 100644 Marlin/src/pins/stm32/pins_ARMED.h delete mode 100644 Marlin/src/pins/stm32/pins_BEAST.h delete mode 100644 Marlin/src/pins/stm32/pins_BLACK_STM32F407VE.h delete mode 100644 Marlin/src/pins/stm32/pins_BTT_BTT002_V1_0.h delete mode 100644 Marlin/src/pins/stm32/pins_BTT_GTR_V1_0.h delete mode 100644 Marlin/src/pins/stm32/pins_BTT_SKR_E3_DIP.h delete mode 100644 Marlin/src/pins/stm32/pins_BTT_SKR_MINI_E3.h delete mode 100644 Marlin/src/pins/stm32/pins_BTT_SKR_MINI_V1_1.h delete mode 100644 Marlin/src/pins/stm32/pins_BTT_SKR_PRO_V1_1.h delete mode 100644 Marlin/src/pins/stm32/pins_CHITU3D.h delete mode 100644 Marlin/src/pins/stm32/pins_FLYF407ZG.h delete mode 100644 Marlin/src/pins/stm32/pins_FYSETC_AIO_II.h delete mode 100644 Marlin/src/pins/stm32/pins_FYSETC_CHEETAH.h delete mode 100644 Marlin/src/pins/stm32/pins_FYSETC_S6.h delete mode 100644 Marlin/src/pins/stm32/pins_GENERIC_STM32F4.h delete mode 100644 Marlin/src/pins/stm32/pins_GTM32_MINI.h delete mode 100644 Marlin/src/pins/stm32/pins_GTM32_PRO_VB.h delete mode 100644 Marlin/src/pins/stm32/pins_GTM32_REV_B.h delete mode 100644 Marlin/src/pins/stm32/pins_JGAURORA_A5S_A1.h delete mode 100644 Marlin/src/pins/stm32/pins_LERDGE_K.h delete mode 100644 Marlin/src/pins/stm32/pins_LERDGE_X.h delete mode 100644 Marlin/src/pins/stm32/pins_LONGER3D_LK.h delete mode 100644 Marlin/src/pins/stm32/pins_MALYAN_M200.h delete mode 100644 Marlin/src/pins/stm32/pins_MKS_ROBIN.h delete mode 100644 Marlin/src/pins/stm32/pins_MKS_ROBIN2.h delete mode 100644 Marlin/src/pins/stm32/pins_MKS_ROBIN_LITE.h delete mode 100644 Marlin/src/pins/stm32/pins_MKS_ROBIN_LITE3.h delete mode 100644 Marlin/src/pins/stm32/pins_MKS_ROBIN_MINI.h delete mode 100644 Marlin/src/pins/stm32/pins_MKS_ROBIN_NANO.h delete mode 100644 Marlin/src/pins/stm32/pins_MKS_ROBIN_PRO.h delete mode 100644 Marlin/src/pins/stm32/pins_MORPHEUS.h delete mode 100644 Marlin/src/pins/stm32/pins_REMRAM_V1.h delete mode 100644 Marlin/src/pins/stm32/pins_RUMBA32_AUS3D.h delete mode 100644 Marlin/src/pins/stm32/pins_RUMBA32_common.h delete mode 100644 Marlin/src/pins/stm32/pins_STM32F1R.h delete mode 100644 Marlin/src/pins/stm32/pins_STM3R_MINI.h delete mode 100644 Marlin/src/pins/stm32/pins_THE_BORG.h delete mode 100644 Marlin/src/pins/stm32/pins_VAKE403D.h create mode 100644 Marlin/src/pins/stm32f0/pins_MALYAN_M200_V2.h create mode 100644 Marlin/src/pins/stm32f0/pins_MALYAN_M300.h create mode 100644 Marlin/src/pins/stm32f1/pins_BTT_SKR_E3_DIP.h rename Marlin/src/pins/{stm32 => stm32f1}/pins_BTT_SKR_MINI_E3_V1_0.h (74%) rename Marlin/src/pins/{stm32 => stm32f1}/pins_BTT_SKR_MINI_E3_V1_2.h (60%) create mode 100644 Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_V2_0.h create mode 100644 Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h create mode 100644 Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_V1_1.h create mode 100644 Marlin/src/pins/stm32f1/pins_CCROBOT_MEEB_3DP.h create mode 100644 Marlin/src/pins/stm32f1/pins_CHITU3D.h create mode 100644 Marlin/src/pins/stm32f1/pins_CHITU3D_V5.h create mode 100644 Marlin/src/pins/stm32f1/pins_CHITU3D_V6.h create mode 100644 Marlin/src/pins/stm32f1/pins_CREALITY_V4.h create mode 100644 Marlin/src/pins/stm32f1/pins_CREALITY_V427.h create mode 100644 Marlin/src/pins/stm32f1/pins_FLY_MINI.h create mode 100644 Marlin/src/pins/stm32f1/pins_FYSETC_AIO_II.h create mode 100644 Marlin/src/pins/stm32f1/pins_FYSETC_CHEETAH.h rename Marlin/src/pins/{stm32 => stm32f1}/pins_FYSETC_CHEETAH_V12.h (69%) create mode 100644 Marlin/src/pins/stm32f1/pins_GTM32_MINI.h rename Marlin/src/pins/{stm32 => stm32f1}/pins_GTM32_MINI_A30.h (50%) create mode 100644 Marlin/src/pins/stm32f1/pins_GTM32_PRO_VB.h create mode 100644 Marlin/src/pins/stm32f1/pins_GTM32_REV_B.h create mode 100644 Marlin/src/pins/stm32f1/pins_JGAURORA_A5S_A1.h create mode 100644 Marlin/src/pins/stm32f1/pins_LONGER3D_LK.h create mode 100644 Marlin/src/pins/stm32f1/pins_MALYAN_M200.h create mode 100644 Marlin/src/pins/stm32f1/pins_MKS_ROBIN.h create mode 100644 Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3.h create mode 100644 Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3D.h create mode 100644 Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3P.h create mode 100644 Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3_common.h create mode 100644 Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE.h create mode 100644 Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE3.h create mode 100644 Marlin/src/pins/stm32f1/pins_MKS_ROBIN_MINI.h create mode 100644 Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO.h create mode 100644 Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO_V2.h create mode 100644 Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h create mode 100644 Marlin/src/pins/stm32f1/pins_MORPHEUS.h create mode 100644 Marlin/src/pins/stm32f1/pins_STM32F1R.h create mode 100644 Marlin/src/pins/stm32f1/pins_STM3R_MINI.h create mode 100644 Marlin/src/pins/stm32f1/pins_TRIGORILLA_PRO.h create mode 100644 Marlin/src/pins/stm32f4/pins_ARMED.h create mode 100644 Marlin/src/pins/stm32f4/pins_BEAST.h create mode 100644 Marlin/src/pins/stm32f4/pins_BLACK_STM32F407VE.h create mode 100644 Marlin/src/pins/stm32f4/pins_BTT_BTT002_V1_0.h create mode 100644 Marlin/src/pins/stm32f4/pins_BTT_GTR_V1_0.h create mode 100644 Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_V1_1.h create mode 100644 Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_V1_2.h create mode 100644 Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_common.h create mode 100644 Marlin/src/pins/stm32f4/pins_FLYF407ZG.h create mode 100644 Marlin/src/pins/stm32f4/pins_FYSETC_S6.h create mode 100644 Marlin/src/pins/stm32f4/pins_FYSETC_S6_V2_0.h create mode 100644 Marlin/src/pins/stm32f4/pins_GENERIC_STM32F4.h create mode 100644 Marlin/src/pins/stm32f4/pins_LERDGE_K.h create mode 100644 Marlin/src/pins/stm32f4/pins_LERDGE_S.h create mode 100644 Marlin/src/pins/stm32f4/pins_LERDGE_X.h create mode 100644 Marlin/src/pins/stm32f4/pins_MKS_ROBIN2.h create mode 100644 Marlin/src/pins/stm32f4/pins_RUMBA32_AUS3D.h rename Marlin/src/pins/{stm32 => stm32f4}/pins_RUMBA32_MKS.h (64%) create mode 100644 Marlin/src/pins/stm32f4/pins_RUMBA32_common.h rename Marlin/src/pins/{stm32 => stm32f4}/pins_STEVAL_3DP001V1.h (52%) create mode 100644 Marlin/src/pins/stm32f4/pins_VAKE403D.h create mode 100644 Marlin/src/pins/stm32f7/pins_NUCLEO_F767ZI.h create mode 100644 Marlin/src/pins/stm32f7/pins_REMRAM_V1.h create mode 100644 Marlin/src/pins/stm32f7/pins_THE_BORG.h create mode 100644 Marlin/src/pins/teensy4/pins_T41U5XBB.h create mode 100644 Marlin/src/pins/teensy4/pins_TEENSY41.h create mode 100644 buildroot/bin/.gitattributes create mode 100755 buildroot/bin/format_code create mode 100755 buildroot/bin/uncrust create mode 100644 buildroot/share/PlatformIO/boards/BigTree_GTR_v1.json create mode 100644 buildroot/share/PlatformIO/boards/CHITU_F103.json create mode 100644 buildroot/share/PlatformIO/boards/LERDGE.json create mode 100644 buildroot/share/PlatformIO/boards/MEEB_3DP.json create mode 100644 buildroot/share/PlatformIO/boards/archim.json rename buildroot/share/PlatformIO/boards/{fysetc_s6.json => marlin_fysetc_s6.json} (94%) create mode 100644 buildroot/share/PlatformIO/ldscripts/STM32F103RC_MEEB_3DP.ld create mode 100644 buildroot/share/PlatformIO/ldscripts/creality.ld create mode 100644 buildroot/share/PlatformIO/ldscripts/fly_mini.ld rename buildroot/share/PlatformIO/ldscripts/{fysetc_aio_ii.ld => fysetc_stm32f103rc.ld} (88%) create mode 100644 buildroot/share/PlatformIO/ldscripts/lerdge.ld create mode 100644 buildroot/share/PlatformIO/ldscripts/mks_robin_e3.ld create mode 100644 buildroot/share/PlatformIO/ldscripts/mks_robin_e3p.ld create mode 100644 buildroot/share/PlatformIO/scripts/STM32F103RC_MEEB_3DP.py create mode 100644 buildroot/share/PlatformIO/scripts/STM32F1_create_variant.py create mode 100644 buildroot/share/PlatformIO/scripts/common-dependencies-post.py create mode 100644 buildroot/share/PlatformIO/scripts/common-dependencies.h create mode 100644 buildroot/share/PlatformIO/scripts/common-dependencies.py create mode 100644 buildroot/share/PlatformIO/scripts/copy_marlin_variant_to_framework.py create mode 100644 buildroot/share/PlatformIO/scripts/creality.py create mode 100644 buildroot/share/PlatformIO/scripts/download_mks_assets.py create mode 100644 buildroot/share/PlatformIO/scripts/fly_mini.py delete mode 100644 buildroot/share/PlatformIO/scripts/fysetc_STM32S6.py create mode 100644 buildroot/share/PlatformIO/scripts/lerdge.py create mode 100644 buildroot/share/PlatformIO/scripts/mks_encrypt.py create mode 100644 buildroot/share/PlatformIO/scripts/mks_robin_e3.py create mode 100644 buildroot/share/PlatformIO/scripts/mks_robin_e3p.py create mode 100644 buildroot/share/PlatformIO/scripts/mks_robin_nano35.py create mode 100644 buildroot/share/PlatformIO/scripts/random-bin.py create mode 100644 buildroot/share/PlatformIO/scripts/stm32_bootloader.py create mode 100644 buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/PeripheralPins.c create mode 100644 buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/PinNamesVar.h create mode 100644 buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/hal_conf_extra.h create mode 100644 buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/ldscript.ld create mode 100644 buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/variant.cpp create mode 100644 buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/variant.h create mode 100755 buildroot/share/PlatformIO/variants/CHITU_F103/board.cpp create mode 100755 buildroot/share/PlatformIO/variants/CHITU_F103/board/board.h create mode 100755 buildroot/share/PlatformIO/variants/CHITU_F103/ld/common.inc create mode 100755 buildroot/share/PlatformIO/variants/CHITU_F103/ld/extra_libs.inc create mode 100755 buildroot/share/PlatformIO/variants/CHITU_F103/ld/stm32f103z_dfu.ld create mode 100755 buildroot/share/PlatformIO/variants/CHITU_F103/ld/stm32f103zc.ld create mode 100755 buildroot/share/PlatformIO/variants/CHITU_F103/ld/stm32f103zd.ld create mode 100755 buildroot/share/PlatformIO/variants/CHITU_F103/ld/stm32f103ze.ld create mode 100755 buildroot/share/PlatformIO/variants/CHITU_F103/ld/vector_symbols.inc create mode 100755 buildroot/share/PlatformIO/variants/CHITU_F103/pins_arduino.h create mode 100755 buildroot/share/PlatformIO/variants/CHITU_F103/variant.h create mode 100755 buildroot/share/PlatformIO/variants/CHITU_F103/wirish/boards.cpp create mode 100755 buildroot/share/PlatformIO/variants/CHITU_F103/wirish/boards_setup.cpp create mode 100755 buildroot/share/PlatformIO/variants/CHITU_F103/wirish/start.S create mode 100755 buildroot/share/PlatformIO/variants/CHITU_F103/wirish/start_c.c create mode 100755 buildroot/share/PlatformIO/variants/CHITU_F103/wirish/syscalls.c create mode 100644 buildroot/share/PlatformIO/variants/LERDGE/PeripheralPins.c create mode 100644 buildroot/share/PlatformIO/variants/LERDGE/PinNamesVar.h create mode 100644 buildroot/share/PlatformIO/variants/LERDGE/variant.cpp create mode 100644 buildroot/share/PlatformIO/variants/LERDGE/variant.h create mode 100644 buildroot/share/PlatformIO/variants/MARLIN_F103Vx/PeripheralPins.c rename buildroot/share/PlatformIO/variants/{FYSETC_S6 => MARLIN_F103Vx}/PinNamesVar.h (59%) create mode 100644 buildroot/share/PlatformIO/variants/MARLIN_F103Vx/ldscript.ld create mode 100644 buildroot/share/PlatformIO/variants/MARLIN_F103Vx/variant.cpp create mode 100644 buildroot/share/PlatformIO/variants/MARLIN_F103Vx/variant.h create mode 100644 buildroot/share/PlatformIO/variants/MARLIN_F103Zx/PeripheralPins.c create mode 100644 buildroot/share/PlatformIO/variants/MARLIN_F103Zx/PinNamesVar.h create mode 100644 buildroot/share/PlatformIO/variants/MARLIN_F103Zx/hal_conf_custom.h create mode 100644 buildroot/share/PlatformIO/variants/MARLIN_F103Zx/ldscript.ld create mode 100644 buildroot/share/PlatformIO/variants/MARLIN_F103Zx/variant.cpp create mode 100644 buildroot/share/PlatformIO/variants/MARLIN_F103Zx/variant.h rename buildroot/share/PlatformIO/variants/{FYSETC_S6 => MARLIN_FYSETC_S6}/PeripheralPins.c (100%) create mode 100644 buildroot/share/PlatformIO/variants/MARLIN_FYSETC_S6/PinNamesVar.h rename buildroot/share/PlatformIO/variants/{FYSETC_S6 => MARLIN_FYSETC_S6}/ldscript.ld (100%) rename buildroot/share/PlatformIO/variants/{FYSETC_S6 => MARLIN_FYSETC_S6}/variant.cpp (100%) rename buildroot/share/PlatformIO/variants/{FYSETC_S6 => MARLIN_FYSETC_S6}/variant.h (98%) create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/board.cpp create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/board/board.h create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/ld/bootloader.ld create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/ld/common.inc create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/ld/extra_libs.inc create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/ld/flash.ld create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/ld/jtag.ld create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/ld/mem-flash.inc create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/ld/mem-jtag.inc create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/ld/mem-ram.inc create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/ld/ram.ld create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rb.ld create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rb_bootloader.ld create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rc.ld create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rc_bootloader.ld create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103re.ld create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/ld/vector_symbols.inc create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/pins_arduino.h create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/variant.h create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/boards.cpp create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/boards_setup.cpp create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/start.S create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/start_c.c create mode 100644 buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/syscalls.c create mode 100644 buildroot/share/PlatformIO/variants/archim/.gitignore create mode 100644 buildroot/share/PlatformIO/variants/archim/build_gcc/Makefile create mode 100644 buildroot/share/PlatformIO/variants/archim/build_gcc/debug.mk create mode 100644 buildroot/share/PlatformIO/variants/archim/build_gcc/gcc.mk create mode 100644 buildroot/share/PlatformIO/variants/archim/build_gcc/libvariant_arduino_due_x.mk create mode 100644 buildroot/share/PlatformIO/variants/archim/build_gcc/release.mk create mode 100644 buildroot/share/PlatformIO/variants/archim/debug_scripts/gcc/arduino_due_x_flash.gdb create mode 100644 buildroot/share/PlatformIO/variants/archim/debug_scripts/gcc/arduino_due_x_sram.gdb create mode 100644 buildroot/share/PlatformIO/variants/archim/debug_scripts/iar/arduino_due_flash.mac create mode 100644 buildroot/share/PlatformIO/variants/archim/debug_scripts/iar/arduino_due_sram.mac create mode 100644 buildroot/share/PlatformIO/variants/archim/libsam_sam3x8e_gcc_rel.a create mode 100644 buildroot/share/PlatformIO/variants/archim/libsam_sam3x8e_gcc_rel.a.txt create mode 100644 buildroot/share/PlatformIO/variants/archim/linker_scripts/gcc/flash.ld create mode 100644 buildroot/share/PlatformIO/variants/archim/linker_scripts/gcc/sram.ld create mode 100644 buildroot/share/PlatformIO/variants/archim/linker_scripts/iar/flash.icf create mode 100644 buildroot/share/PlatformIO/variants/archim/linker_scripts/iar/sram.icf create mode 100644 buildroot/share/PlatformIO/variants/archim/pins_arduino.h create mode 100644 buildroot/share/PlatformIO/variants/archim/variant.cpp create mode 100644 buildroot/share/PlatformIO/variants/archim/variant.h create mode 100755 buildroot/share/PlatformIO/variants/megaextendedpins/pins_arduino.h rename Marlin/src/HAL/HAL_AVR/inc/Conditionals_LCD.h => buildroot/share/extras/header.h (88%) create mode 100644 buildroot/share/extras/uncrustify.cfg create mode 100644 buildroot/share/fonts/marlin-6x9.bdf create mode 100755 buildroot/share/scripts/config-labels.py create mode 100755 buildroot/share/scripts/pinsformat.js delete mode 100644 buildroot/share/tests/BIGTREE_SKR_PRO-tests delete mode 100644 buildroot/share/tests/SAMD51_grandcentral_m4-tests delete mode 100644 buildroot/share/tests/STM32F103RC_bigtree-tests delete mode 100644 buildroot/share/tests/megaatmega1280-tests delete mode 100644 buildroot/share/tests/mks_robin_nano-tests delete mode 100644 buildroot/share/tests/rambo-tests create mode 100644 buildroot/tests/.gitattributes rename buildroot/{share => }/tests/ARMED-tests (56%) create mode 100644 buildroot/tests/BIGTREE_BTT002-tests create mode 100644 buildroot/tests/BIGTREE_GTR_V1_0-tests create mode 100644 buildroot/tests/BIGTREE_SKR_PRO-tests rename buildroot/{share => }/tests/DUE-tests (85%) create mode 100644 buildroot/tests/FLYF407ZG-tests rename buildroot/{share => }/tests/FYSETC_F6_13-tests (75%) rename buildroot/{share => }/tests/FYSETC_S6-tests (77%) rename buildroot/{share/tests/BIGTREE_BTT002-tests => tests/LERDGEX-tests} (52%) rename buildroot/{share => }/tests/LPC1768-tests (91%) rename buildroot/{share => }/tests/LPC1769-tests (69%) create mode 100644 buildroot/tests/SAMD51_grandcentral_m4-tests create mode 100644 buildroot/tests/STM32F070CB_malyan-tests create mode 100644 buildroot/tests/STM32F070RB_malyan-tests rename buildroot/{share => }/tests/STM32F103CB_malyan-tests (79%) create mode 100644 buildroot/tests/STM32F103RC_btt-tests rename buildroot/{share/tests/STM32F103RC_bigtree_USB-tests => tests/STM32F103RC_btt_USB-tests} (100%) rename buildroot/{share => }/tests/STM32F103RC_fysetc-tests (76%) create mode 100644 buildroot/tests/STM32F103RC_meeb-tests rename buildroot/{share => }/tests/STM32F103RE-tests (100%) create mode 100644 buildroot/tests/STM32F103RET6_creality-tests rename buildroot/{share/tests/STM32F103RE_bigtree_USB-tests => tests/STM32F103RE_btt-tests} (67%) rename buildroot/{share/tests/STM32F103RE_bigtree-tests => tests/STM32F103RE_btt_USB-tests} (100%) rename buildroot/{share => }/tests/STM32F103VE_longer-tests (100%) rename buildroot/{share => }/tests/STM32F4-tests (100%) create mode 100644 buildroot/tests/STM32F401VE_STEVAL-tests rename buildroot/{share => }/tests/STM32F407VE_black-tests (94%) rename buildroot/{share => }/tests/STM32F7-tests (100%) rename buildroot/{share => }/tests/at90usb1286_cdc-tests (100%) rename buildroot/{share => }/tests/at90usb1286_dfu-tests (100%) rename buildroot/{share => }/tests/esp32-tests (71%) rename buildroot/{share => }/tests/jgaurora_a5s_a1-tests (100%) rename buildroot/{share => }/tests/linux_native-tests (100%) create mode 100755 buildroot/tests/malyan_M300-tests create mode 100644 buildroot/tests/mega1280-tests rename buildroot/{share/tests/megaatmega2560-tests => tests/mega2560-tests} (68%) create mode 100644 buildroot/tests/mks_robin-tests rename buildroot/{share => }/tests/mks_robin_lite-tests (52%) rename buildroot/{share => }/tests/mks_robin_mini-tests (67%) create mode 100644 buildroot/tests/mks_robin_nano35-tests create mode 100644 buildroot/tests/mks_robin_pro-tests rename buildroot/{share/tests/mks_robin-tests => tests/mks_robin_stm32-tests} (56%) create mode 100644 buildroot/tests/rambo-tests create mode 100644 buildroot/tests/rumba32-tests rename buildroot/{share => }/tests/run_tests (100%) rename buildroot/{share/tests/sanguino_atmega1284p-tests => tests/sanguino1284p-tests} (100%) rename buildroot/{share/tests/sanguino_atmega644p-tests => tests/sanguino644p-tests} (100%) rename buildroot/{share => }/tests/teensy31-tests (100%) rename buildroot/{share => }/tests/teensy35-tests (92%) create mode 100644 buildroot/tests/teensy41-tests diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 70734d4972cc..a9732429326e 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,3 +1,3 @@ github: [thinkyhead] patreon: thinkyhead -custom: ["http://www.thinkyhead.com/donate-to-marlin"] +custom: ["https://www.thinkyhead.com/donate-to-marlin"] diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 48beca2c2d18..000000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -name: Bug report -about: Report a bug in Marlin -title: "[BUG] (short description)" -labels: '' -assignees: '' - ---- - - - -### Bug Description - - - -### My Configurations - -**Required:** Please include a ZIP file containing your `Configuration.h` and `Configuration_adv.h` files. - -### Steps to Reproduce - - - -1. [First Step] -2. [Second Step] -3. [and so on...] - -**Expected behavior:** [What you expect to happen] - -**Actual behavior:** [What actually happens] - -#### Additional Information - -* Provide pictures or links to videos that clearly demonstrate the issue. -* See [How Can I Contribute](#how-can-i-contribute) for additional guidelines. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 000000000000..d1eb86105857 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,157 @@ +name: 🪲 Report a bug +description: Create a bug report to help improve Marlin Firmware +title: "[BUG] (bug summary)" +body: + - type: markdown + attributes: + value: > + Do you want to ask a question? Are you looking for support? Please use one of the [support links](https://github.com/MarlinFirmware/Marlin/issues/new/choose). + + - type: markdown + attributes: + value: | + **Thank you for reporting a bug in Marlin Firmware!** + + ## Before Reporting a Bug + + - Read and understand Marlin's [Code of Conduct](https://github.com/MarlinFirmware/Marlin/blob/master/.github/code_of_conduct.md). You are expected to comply with it, including treating everyone with respect. + + - Test with the [`bugfix-2.0.x` branch](https://github.com/MarlinFirmware/Marlin/archive/bugfix-2.0.x.zip) to see whether the issue still exists. + + ## Instructions + + Please follow the instructions below. Failure to do so may result in your issue being closed. See [Contributing to Marlin](https://github.com/MarlinFirmware/Marlin/blob/2.0.x/.github/contributing.md) for additional guidelines. + + 1. Provide a good title starting with [BUG]. + 2. Fill out all sections of this bug report form. + 3. Always attach configuration files so we can build and test your setup. + + - type: dropdown + attributes: + label: Did you test the latest `bugfix-2.0.x` code? + description: >- + Always try the latest code to make sure the issue you are reporting is not already fixed. To download + the latest code just [click this link](https://github.com/MarlinFirmware/Marlin/archive/bugfix-2.0.x.zip). + options: + - Yes, and the problem still exists. + - No, but I will test it now! + validations: + required: true + + - type: markdown + attributes: + value: | + # Bug Details + + - type: textarea + attributes: + label: Bug Description + description: >- + Describe the bug in this section. Tell us what you were trying to do and what + happened that you did not expect. Provide a clear and concise description of the + problem and include as many details as possible. + placeholder: | + Marlin doesn't work. + validations: + required: true + + - type: input + attributes: + label: Bug Timeline + description: Is this a new bug or an old issue? When did it first start? + + - type: textarea + attributes: + label: Expected behavior + description: >- + What did you expect to happen? + placeholder: I expected it to move left. + + - type: textarea + attributes: + label: Actual behavior + description: What actually happened instead? + placeholder: It moved right instead of left. + + - type: textarea + attributes: + label: Steps to Reproduce + description: >- + Please describe the steps needed to reproduce the issue. + placeholder: | + 1. [First Step] ... + 2. [Second Step] ... + 3. [and so on] ... + + - type: markdown + attributes: + value: | + # Your Setup + + - type: input + attributes: + label: Version of Marlin Firmware + description: "See the About Menu on the LCD or the output of `M115`. NOTE: For older releases we only patch critical bugs." + validations: + required: true + + - type: input + attributes: + label: Printer model + description: Creality Ender 3, Prusa mini, or Kossel Delta? + + - type: input + attributes: + label: Electronics + description: Stock electronics, upgrade board, or something else? + + - type: input + attributes: + label: Add-ons + description: Please list any hardware add-ons that could be involved. + + - type: dropdown + attributes: + label: Your Slicer + description: Do you use Slic3r, Prusa Slicer, Simplify3D, IdeaMaker...? + options: + - Slic3r + - Simplify3D + - Prusa Slicer + - IdeaMaker + - Cura + - Other (explain below) + + - type: dropdown + attributes: + label: Host Software + description: Do you use OctoPrint, Repetier Host, Pronterface...? + options: + - SD Card (headless) + - Repetier Host + - OctoPrint + - Pronterface + - Cura + - Same as my slicer + - Other (explain below) + + - type: markdown + attributes: + value: >- + ## Other things to include + + Please also be sure to include these items to help with troubleshooting: + + * **A ZIP file** containing your `Configuration.h` and `Configuration_adv.h`. + (Please don't paste lengthy configuration text here.) + * **Log output** from the host. (`M111 S247` for maximum logging.) + * **Images or videos** demonstrating the problem, if it helps to make it clear. + * **A G-Code file** that exposes the problem, if not affecting _all_ G-code. + + If you've made any other modifications to the firmware, please describe them in detail in the space provided. + + When pasting formatted text into the box below don't forget to put ` ``` ` (on its own line) before and after to make it readable. + + - type: textarea + attributes: + label: Additional information & file uploads diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 4b283d26005c..3f5d6fe5517d 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,17 +1,20 @@ blank_issues_enabled: false contact_links: - - name: Marlin Documentation + - name: 📖 Marlin Documentation url: http://marlinfw.org/ about: Lots of documentation on installing and using Marlin. - - name: MarlinFirmware Facebook group + - name: 👤 MarlinFirmware Facebook group url: https://www.facebook.com/groups/1049718498464482 about: Please ask and answer questions here. - - name: Marlin on Discord + - name: 🕹 Marlin on Discord url: https://discord.gg/n5NJ59y about: Join the Discord server for support and discussion. - - name: Marlin Discussion Forum + - name: 🔗 Marlin Discussion Forum url: http://forums.reprap.org/list.php?415 about: A searchable web forum hosted by RepRap dot org. - - name: Marlin Videos on YouTube + - name: 📺 Marlin Videos on YouTube url: https://www.youtube.com/results?search_query=marlin+firmware about: Tutorials and more from Marlin users all around the world. Great for new users! + - name: 💸 Want to donate? + url: https://www.thinkyhead.com/donate-to-marlin + about: Please take a look at the various options to support Marlin Firmware's development financially! diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index ff3b6b06d844..000000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -name: Feature request -about: Request a Feature -title: "[FR] (feature request title)" -labels: '' -assignees: '' - ---- - - - -### Description - - - -### Feature Workflow - - - -1. [First Action] -2. [Second Action] -3. [and so on...] - -#### Additional Information - -* Provide pictures or links that demonstrate a similar feature or concept. -* See [How Can I Contribute](#how-can-i-contribute) for additional guidelines. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 000000000000..df1938ccd84a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,44 @@ +name: ✨ Request a feature +description: Request a new Marlin Firmware feature +title: "[FR] (feature summary)" +labels: 'T: Feature Request' +body: + - type: markdown + attributes: + value: > + Do you want to ask a question? Are you looking for support? Please use one of the [support links](https://github.com/MarlinFirmware/Marlin/issues/new/choose). + + - type: markdown + attributes: + value: > + **Thank you for requesting a new Marlin Firmware feature!** + + ## Before Requesting a Feature + + - Read and understand Marlin's [Code of Conduct](https://github.com/MarlinFirmware/Marlin/blob/master/.github/code_of_conduct.md). You are expected to comply with it, including treating everyone with respect. + + - Check the latest [`bugfix-2.0.x` branch](https://github.com/MarlinFirmware/Marlin/archive/bugfix-2.0.x.zip) to see if the feature already exists. + + - Before you proceed with your request, please consider if it is necessary to make it into a firmware feature, or if it may be better suited for a slicer or host feature. + + - type: textarea + attributes: + label: Is your feature request related to a problem? Please describe. + description: A clear description of the problem (e.g., "I need X but Marlin can't do it [...]"). + + - type: textarea + attributes: + label: Are you looking for hardware support? + description: Tell us the printer, board, or peripheral that needs support. + + - type: textarea + attributes: + label: Describe the feature you want + description: A clear description of the feature and how you think it should work. + validations: + required: true + + - type: textarea + attributes: + label: Additional context + description: Add any other context or screenshots about the feature request here. diff --git a/.github/contributing.md b/.github/contributing.md index 808c87bb04ae..6bc7b5a00514 100644 --- a/.github/contributing.md +++ b/.github/contributing.md @@ -34,16 +34,15 @@ This project and everyone participating in it is governed by the [Marlin Code of We have a Message Board and a Facebook group where our knowledgable user community can provide helpful advice if you have questions. -* [Marlin RepRap forum](http://forums.reprap.org/list.php?415) +* [Marlin RepRap forum](https://reprap.org/forum/list.php?415) * [MarlinFirmware on Facebook](https://www.facebook.com/groups/1049718498464482/) -If chat is more your speed, you can join the MarlinFirmware Slack team: +If chat is more your speed, you can join the MarlinFirmware Discord server: -* Join the Marlin Slack Team - * To obtain group access, please [send a request](http://www.thinkyhead.com/contact/9) to @thinkyhead. - * Even though Slack is a chat service, sometimes it takes several hours for community members to respond — please be patient! - * Use the `#general` channel for general questions or discussion about Marlin. - * Other channels exist for certain topics. Check the channel list. +* Use the link https://discord.gg/n5NJ59y to join up as a General User. +* Even though our Discord is pretty active, it may take a while for community members to respond — please be patient! +* Use the `#general` channel for general questions or discussion about Marlin. +* Other channels exist for certain topics or are limited to Patrons. Check the channel list. ## How Can I Contribute? @@ -93,7 +92,7 @@ Before creating a suggestion, please check [this list](#before-submitting-a-sugg #### Before Submitting a Feature Request -* **Check the [Marlin website](http://marlinfw.org/)** for tips — you might discover that the feature is already included. Most importantly, check if you're using [the latest version of Marlin](https://github.com/MarlinFirmware/Marlin/releases) and if you can get the desired behavior by changing [Marlin's config settings](http://marlinfw.org/docs/configuration/configuration.html). +* **Check the [Marlin website](https://marlinfw.org/)** for tips — you might discover that the feature is already included. Most importantly, check if you're using [the latest version of Marlin](https://github.com/MarlinFirmware/Marlin/releases) and if you can get the desired behavior by changing [Marlin's config settings](https://marlinfw.org/docs/configuration/configuration.html). * **Perform a [cursory search](https://github.com/MarlinFirmware/Marlin/issues?q=is%3Aissue)** to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one. #### How Do I Submit A (Good) Feature Request? @@ -117,12 +116,12 @@ Unsure where to begin contributing to Marlin? You can start by looking through t ### Pull Requests -Pull Requests should always be targeted to working branches (e.g., `bugfix-1.1.x` and/or `bugfix-2.0.x`) and never to release branches (e.g., `1.1.x`). If this is your first Pull Request, please read our [Guide to Pull Requests](http://marlinfw.org/docs/development/getting_started_pull_requests.html) and Github's [Pull Request](https://help.github.com/articles/creating-a-pull-request/) documentation. +Pull Requests should always be targeted to working branches (e.g., `bugfix-1.1.x` and/or `bugfix-2.0.x`) and never to release branches (e.g., `1.1.x`). If this is your first Pull Request, please read our [Guide to Pull Requests](https://marlinfw.org/docs/development/getting_started_pull_requests.html) and Github's [Pull Request](https://help.github.com/articles/creating-a-pull-request/) documentation. * Fill in [the required template](pull_request_template.md). * Don't include issue numbers in the PR title. * Include pictures, diagrams, and links to videos in your Pull Request to demonstrate your changes, if needed. -* Follow the [Coding Standards](http://marlinfw.org/docs/development/coding_standards.html) posted on our website. +* Follow the [Coding Standards](https://marlinfw.org/docs/development/coding_standards.html) posted on our website. * Document new code with clear and concise comments. * End all files with a newline. @@ -137,7 +136,7 @@ Pull Requests should always be targeted to working branches (e.g., `bugfix-1.1.x ### C++ Coding Standards -* Please read and follow the [Coding Standards](http://marlinfw.org/docs/development/coding_standards.html) posted on our website. Failure to follow these guidelines will delay evaluation and acceptance of Pull Requests. +* Please read and follow the [Coding Standards](https://marlinfw.org/docs/development/coding_standards.html) posted on our website. Failure to follow these guidelines will delay evaluation and acceptance of Pull Requests. ### Documentation diff --git a/.github/issue_template.md b/.github/issue_template.md index f45bd71d09fb..a211ca5e2715 100644 --- a/.github/issue_template.md +++ b/.github/issue_template.md @@ -1,16 +1,11 @@ # NO SUPPORT REQUESTS PLEASE -Support Requests posted here will be automatically closed! +Do you want to ask a question? Are you looking for support? Please don't post here. Support Requests posted here will be automatically closed! -This Issue Queue is for Marlin bug reports and development-related issues, and we prefer not to handle user-support questions here. See https://github.com/MarlinFirmware/Marlin/blob/1.1.x/.github/contributing.md#i-dont-want-to-read-this-whole-thing-i-just-have-a-question. +Instead use one of the following options: -For best results getting help with configuration and troubleshooting, please use the following resources: +- The Marlin Firmware forum at https://reprap.org/forum/list.php?415 +- The MarlinFirmware Facebook Group at https://www.facebook.com/groups/1049718498464482/ +- The MarlinFirmware Discord Server at https://discord.gg/n5NJ59y. -- RepRap.org Marlin Forum http://forums.reprap.org/list.php?415 -- Tom's 3D Forums https://discuss.toms3d.org/ -- Facebook Group "Marlin Firmware" https://www.facebook.com/groups/1049718498464482/ -- Facebook Group "Marlin Firmware for 3D Printers" https://www.facebook.com/groups/3Dtechtalk/ -- Marlin Configuration https://www.youtube.com/results?search_query=marlin+configuration on YouTube -- Marlin Discord server. Join link: https://discord.gg/n5NJ59y - -After seeking help from the community, if the consensus points to to a bug in Marlin, then you should post a Bug Report at https://github.com/MarlinFirmware/Marlin/issues/new/choose). +Before filing an issue be sure to test the latest "bugfix" branch to see whether the issue is already addressed. diff --git a/.github/lock.yml b/.github/lock.yml new file mode 100644 index 000000000000..c5ceff66b0a7 --- /dev/null +++ b/.github/lock.yml @@ -0,0 +1,40 @@ +# +# Configuration for Lock Threads - https://github.com/dessant/lock-threads-app +# + +# Number of days of inactivity before a closed issue or pull request is locked +daysUntilLock: 60 + +# Skip issues and pull requests created before a given timestamp. Timestamp must +# follow ISO 8601 (`YYYY-MM-DD`). Set to `false` to disable +skipCreatedBefore: false + +# Issues and pull requests with these labels will be ignored. Set to `[]` to disable +exemptLabels: [ 'no-locking' ] + +# Label to add before locking, such as `outdated`. Set to `false` to disable +lockLabel: false + +# Comment to post before locking. Set to `false` to disable +lockComment: > + This thread has been automatically locked since there has not been + any recent activity after it was closed. Please open a new issue for + related bugs. + +# Assign `resolved` as the reason for locking. Set to `false` to disable +setLockReason: true + +# Limit to only `issues` or `pulls` +# only: issues + +# Optionally, specify configuration settings just for `issues` or `pulls` +# issues: +# exemptLabels: +# - help-wanted +# lockLabel: outdated + +# pulls: +# daysUntilLock: 30 + +# Repository to extend settings from +# _extends: repo diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 9298b2b96d36..cd5158b3ce8c 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,19 +1,33 @@ -### Requirements + ### Description +### Requirements + + + ### Benefits - + + +### Configurations + + ### Related Issues - + diff --git a/.github/workflows/bad-target.md b/.github/workflows/bad-target.md deleted file mode 100644 index 048e56cfd189..000000000000 --- a/.github/workflows/bad-target.md +++ /dev/null @@ -1,7 +0,0 @@ -Thanks for your contribution! Unfortunately we can't accept PRs directed at release branches. We make patches to the bugfix branches and only later do we push them out as releases. - -Please redo this PR starting with the `bugfix-2.0.x` branch and be careful to target `bugfix-2.0.x` when resubmitting the PR. - -It may help to set your fork's default branch to `bugfix-2.0.x`. - -See [this page](http://marlinfw.org/docs/development/getting_started_pull_requests.html) for full instructions. diff --git a/.github/workflows/bump-date.yml b/.github/workflows/bump-date.yml index ecf4a4f0ecba..54902da8c908 100644 --- a/.github/workflows/bump-date.yml +++ b/.github/workflows/bump-date.yml @@ -11,6 +11,8 @@ on: jobs: bump_date: + name: Bump Distribution Date + if: github.repository == 'MarlinFirmware/Marlin' runs-on: ubuntu-latest @@ -24,7 +26,6 @@ jobs: - name: Bump Distribution Date run: | # Inline Bump Script - [[ "$GITHUB_REPOSITORY" == "MarlinFirmware/Marlin" ]] || exit 0 DIST=$( date +"%Y-%m-%d" ) eval "sed -E -i 's/(#define +STRING_DISTRIBUTION_DATE) .*$/\1 \"$DIST\"/g' Marlin/src/inc/Version.h" && \ git config user.name "${GITHUB_ACTOR}" && \ diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index a6246a3786f5..aa4a2c59c9a4 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -1,6 +1,6 @@ # -# comment-pr.yml -# Add a comment to any PR directed to a release branch +# check-pr.yml +# Close PRs directed at release branches # name: PR Bad Target @@ -14,14 +14,20 @@ on: jobs: bad_target: - name: PR Bad Target + if: github.repository == 'MarlinFirmware/Marlin' + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - uses: harupy/comment-on-pr@master - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - filename: bad-target.md + - uses: peter-evans/close-pull@v1 + with: + delete-branch: false + comment: > + Thanks for your contribution! Unfortunately we can't accept PRs directed at release branches. We make patches to the bugfix branches and only later do we push them out as releases. + + Please redo this PR starting with the `bugfix-2.0.x` branch and be careful to target `bugfix-2.0.x` when resubmitting the PR. + + It may help to set your fork's default branch to `bugfix-2.0.x`. + + See [this page](http://marlinfw.org/docs/development/getting_started_pull_requests.html) for full instructions. diff --git a/.github/workflows/clean-closed.yml b/.github/workflows/clean-closed.yml new file mode 100644 index 000000000000..befec4498f25 --- /dev/null +++ b/.github/workflows/clean-closed.yml @@ -0,0 +1,39 @@ +# +# clean-closed.yml +# Remove obsolete labels when an Issue or PR is closed +# + +name: Clean Closed + +on: + pull_request: + types: [closed] + issues: + types: [closed] + +jobs: + remove_label: + runs-on: ubuntu-latest + + strategy: + matrix: + label: + - "S: Don't Merge" + - "S: Hold for 2.1" + - "S: Please Merge" + - "S: Please Test" + - "help wanted" + - "Needs: Discussion" + - "Needs: Documentation" + - "Needs: More Data" + - "Needs: Patch" + - "Needs: Testing" + - "Needs: Work" + + steps: + - uses: actions/checkout@v2 + - name: Remove Labels + uses: actions-ecosystem/action-remove-labels@v1 + with: + github_token: ${{ github.token }} + labels: ${{ matrix.label }} diff --git a/.github/workflows/close-stale.yml b/.github/workflows/close-stale.yml new file mode 100644 index 000000000000..f017907d2934 --- /dev/null +++ b/.github/workflows/close-stale.yml @@ -0,0 +1,28 @@ +# +# close-stale.yml +# Close open issues after a period of inactivity +# + +name: Close Stale Issues + +on: + schedule: + - cron: "22 1 * * *" + +jobs: + stale: + name: Close Stale Issues + if: github.repository == 'MarlinFirmware/Marlin' + + runs-on: ubuntu-latest + + steps: + - uses: actions/stale@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: 'This issue has had no activity in the last 60 days. Please add a reply if you want to keep this issue active, otherwise it will be automatically closed within 10 days.' + days-before-stale: 60 + days-before-close: 10 + stale-issue-label: 'stale-closing-soon' + exempt-all-assignees: true + exempt-issue-labels: 'Bug: Confirmed !,T: Feature Request,Needs: Discussion,Needs: Documentation,Needs: More Data,Needs: Patch,Needs: Work,Needs: Testing,help wanted,no-locking' diff --git a/.github/workflows/lock-closed.yml b/.github/workflows/lock-closed.yml new file mode 100644 index 000000000000..81145688288b --- /dev/null +++ b/.github/workflows/lock-closed.yml @@ -0,0 +1,32 @@ +# +# lock-closed.yml +# Lock closed issues after a period of inactivity +# + +name: Lock Closed Issues + +on: + schedule: + - cron: '0 1/13 * * *' + +jobs: + lock: + name: Lock Closed Issues + if: github.repository == 'MarlinFirmware/Marlin' + + runs-on: ubuntu-latest + + steps: + - uses: dessant/lock-threads@v2 + with: + github-token: ${{ github.token }} + process-only: 'issues' + issue-lock-inactive-days: '60' + issue-exclude-created-before: '2017-07-01T00:00:00Z' + issue-exclude-labels: 'no-locking' + issue-lock-labels: '' + issue-lock-comment: > + This issue has been automatically locked since there + has not been any recent activity after it was closed. + Please open a new issue for related bugs. + issue-lock-reason: '' diff --git a/.github/workflows/test-builds.yml b/.github/workflows/test-builds.yml index 59722e3ca5a3..b2287837998b 100644 --- a/.github/workflows/test-builds.yml +++ b/.github/workflows/test-builds.yml @@ -9,7 +9,14 @@ on: pull_request: branches: - bugfix-2.0.x - - dev-2.1.x + paths-ignore: + - config/** + - data/** + - docs/** + - '**/*.md' + push: + branches: + - bugfix-2.0.x paths-ignore: - config/** - data/** @@ -18,6 +25,8 @@ on: jobs: test_builds: + name: Run All Tests + if: github.repository == 'MarlinFirmware/Marlin' runs-on: ubuntu-latest @@ -29,33 +38,49 @@ jobs: - DUE - esp32 - linux_native - - megaatmega2560 + - mega2560 - teensy31 - teensy35 + - teensy41 - SAMD51_grandcentral_m4 # Extended AVR Environments - FYSETC_F6_13 - - megaatmega1280 + - mega1280 - rambo - - sanguino_atmega1284p - - sanguino_atmega644p + - sanguino1284p + - sanguino644p # Extended STM32 Environments - - STM32F103RC_bigtree - - STM32F103RC_bigtree_USB - - STM32F103RE_bigtree - - STM32F103RE_bigtree_USB + - STM32F103RC_btt + - STM32F103RC_btt_USB + - STM32F103RE_btt + - STM32F103RE_btt_USB - STM32F103RC_fysetc + - STM32F103RC_meeb - jgaurora_a5s_a1 - STM32F103VE_longer - STM32F407VE_black + - STM32F401VE_STEVAL + - BIGTREE_BTT002 - BIGTREE_SKR_PRO + - BIGTREE_GTR_V1_0 - mks_robin + - mks_robin_stm32 - ARMED - FYSETC_S6 + - STM32F070CB_malyan + - STM32F070RB_malyan + - malyan_M300 + - mks_robin_lite + - FLYF407ZG + - rumba32 + - mks_robin_pro + - STM32F103RET6_creality + - LERDGEX + - mks_robin_nano35 # Put lengthy tests last @@ -68,14 +93,10 @@ jobs: #- STM32F7 # Non-working environment tests - - #- BIGTREE_BTT002 #- at90usb1286_cdc #- at90usb1286_dfu #- STM32F103CB_malyan - #- mks_robin_lite #- mks_robin_mini - #- mks_robin_nano steps: @@ -87,7 +108,7 @@ jobs: - name: Install PlatformIO run: | - pip install -U https://github.com/platformio/platformio-core/archive/master.zip + pip install -U https://github.com/platformio/platformio-core/archive/develop.zip platformio update - name: Check out the PR @@ -96,8 +117,7 @@ jobs: - name: Run ${{ matrix.test-platform }} Tests run: | # Inline tests script - [[ "$GITHUB_REPOSITORY" == "MarlinFirmware/Marlin" ]] || exit 0 chmod +x buildroot/bin/* - chmod +x buildroot/share/tests/* - export PATH=./buildroot/bin/:./buildroot/share/tests/:${PATH} + chmod +x buildroot/tests/* + export PATH=./buildroot/bin/:./buildroot/tests/:${PATH} run_tests . ${{ matrix.test-platform }} diff --git a/.github/workflows/unlock-reopened.yml b/.github/workflows/unlock-reopened.yml new file mode 100644 index 000000000000..614ef3fab297 --- /dev/null +++ b/.github/workflows/unlock-reopened.yml @@ -0,0 +1,22 @@ +# +# unlock-reopened.yml +# Unlock an issue whenever it is re-opened +# + +name: "Unlock reopened issue" + +on: + issues: + types: [reopened] + +jobs: + unlock: + name: Unlock Reopened + if: github.repository == 'MarlinFirmware/Marlin' + + runs-on: ubuntu-latest + + steps: + - uses: OSDKDev/unlock-issues@v1.1 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.gitignore b/.gitignore index 80c76ee1e482..c163d339dff3 100755 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,7 @@ # 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 . +# along with this program. If not, see . # # Our automatic versioning scheme generates the following file diff --git a/LICENSE b/LICENSE index 7d917cf3d8f9..6c0e10f3b802 100644 --- a/LICENSE +++ b/LICENSE @@ -3,7 +3,7 @@ GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - Copyright (c) 2007 Free Software Foundation, Inc. + Copyright (c) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -647,7 +647,7 @@ the "copyright" line and a pointer to where the full notice is found. 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 . + along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. @@ -666,12 +666,11 @@ 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 -. +. 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 -. - +. diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 5679aa3093f7..db266b524b35 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -34,9 +34,8 @@ * - Extra features * * Advanced settings can be found in Configuration_adv.h - * */ -#define CONFIGURATION_H_VERSION 020004 +#define CONFIGURATION_H_VERSION 020007 //=========================================================================== //============================= Getting Started ============================= @@ -45,13 +44,13 @@ /** * Here are some standard links for getting your machine calibrated: * - * http://reprap.org/wiki/Calibration - * http://youtu.be/wAL9d7FgInk + * https://reprap.org/wiki/Calibration + * https://youtu.be/wAL9d7FgInk * http://calculator.josefprusa.cz - * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide - * http://www.thingiverse.com/thing:5573 + * https://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * https://www.thingiverse.com/thing:5573 * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap - * http://www.thingiverse.com/thing:298812 + * https://www.thingiverse.com/thing:298812 */ //=========================================================================== @@ -99,6 +98,7 @@ /** * Select the serial port on the board to use for communication with the host. * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port -1 is the USB emulated serial port, if available. * Note: The first serial port (-1 or 0) will always be used by the Arduino bootloader. * * :[-1, 0, 1, 2, 3, 4, 5, 6, 7] @@ -107,9 +107,6 @@ /** * Select a secondary serial port on the board to use for communication with the host. - * This allows the connection of wireless adapters (for instance) to non-default port pins. - * Serial port -1 is the USB emulated serial port, if available. - * * :[-1, 0, 1, 2, 3, 4, 5, 6, 7] */ //#define SERIAL_PORT_2 -1 @@ -137,21 +134,28 @@ //#define CUSTOM_MACHINE_NAME "3D Printer" // Printer's unique ID, used by some programs to differentiate between machines. -// Choose your own or use a service like http://www.uuidgenerator.net/version4 +// Choose your own or use a service like https://www.uuidgenerator.net/version4 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000" // @section extruder // This defines the number of extruders -// :[1, 2, 3, 4, 5, 6, 7, 8] +// :[0, 1, 2, 3, 4, 5, 6, 7, 8] #define EXTRUDERS 1 // Generally expected filament diameter (1.75, 2.85, 3.0, ...). Used for Volumetric, Filament Width Sensor, etc. -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.0 +#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE +// Save and restore temperature and fan speed on tool-change. +// Set standby for the unselected tool with M104/106/109 T... +#if ENABLED(SINGLENOZZLE) + //#define SINGLENOZZLE_STANDBY_TEMP + //#define SINGLENOZZLE_STANDBY_FAN +#endif + /** * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. * @@ -172,7 +176,7 @@ #endif /** - * Prusa Multi-Material Unit v2 + * Průša Multi-Material Unit v2 * * Requires NOZZLE_PARK_FEATURE to park print head in case MMU unit fails. * Requires EXTRUDERS = 5 @@ -230,8 +234,8 @@ #elif ENABLED(MAGNETIC_PARKING_EXTRUDER) - #define MPE_FAST_SPEED 9000 // (mm/m) Speed for travel before last distance point - #define MPE_SLOW_SPEED 4500 // (mm/m) Speed for last distance travel to park and couple + #define MPE_FAST_SPEED 9000 // (mm/min) Speed for travel before last distance point + #define MPE_SLOW_SPEED 4500 // (mm/min) Speed for last distance travel to park and couple #define MPE_TRAVEL_DISTANCE 10 // (mm) Last distance point #define MPE_COMPENSATION 0 // Offset Compensation -1 , 0 , 1 (multiplier) only for coupling @@ -279,8 +283,8 @@ #if ENABLED(PRIME_BEFORE_REMOVE) #define SWITCHING_TOOLHEAD_PRIME_MM 20 // (mm) Extruder prime length #define SWITCHING_TOOLHEAD_RETRACT_MM 10 // (mm) Retract after priming length - #define SWITCHING_TOOLHEAD_PRIME_FEEDRATE 300 // (mm/m) Extruder prime feedrate - #define SWITCHING_TOOLHEAD_RETRACT_FEEDRATE 2400 // (mm/m) Extruder retract feedrate + #define SWITCHING_TOOLHEAD_PRIME_FEEDRATE 300 // (mm/min) Extruder prime feedrate + #define SWITCHING_TOOLHEAD_RETRACT_FEEDRATE 2400 // (mm/min) Extruder retract feedrate #endif #elif ENABLED(ELECTROMAGNETIC_SWITCHING_TOOLHEAD) #define SWITCHING_TOOLHEAD_Z_HOP 2 // (mm) Z raise for switching @@ -325,10 +329,10 @@ //#define PSU_NAME "Power Supply" #if ENABLED(PSU_CONTROL) - #define PSU_ACTIVE_HIGH false // Set 'false' for ATX, 'true' for X-Box + #define PSU_ACTIVE_STATE LOW // Set 'LOW' for ATX, 'HIGH' for X-Box //#define PSU_DEFAULT_OFF // Keep power off until enabled directly with M80 - //#define PSU_POWERUP_DELAY 100 // (ms) Delay for the PSU to warm up to full power + //#define PSU_POWERUP_DELAY 250 // (ms) Delay for the PSU to warm up to full power //#define AUTO_POWER_CONTROL // Enable automatic control of the PS_ON pin #if ENABLED(AUTO_POWER_CONTROL) @@ -342,11 +346,10 @@ #endif #endif -// @section temperature - //=========================================================================== //============================= Thermal Settings ============================ //=========================================================================== +// @section temperature /** * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table @@ -363,10 +366,12 @@ * 331 : (3.3V scaled thermistor 1 table for MEGA) * 332 : (3.3V scaled thermistor 1 table for DUE) * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 202 : 200k thermistor - Copymaster 3D * 3 : Mendel-parts thermistor (4.7k pullup) * 4 : 10k thermistor !! do not use it for a hotend. It gives bad resolution at high temp. !! - * 5 : 100K thermistor - ATC Semitec 104GT-2/104NT-4-R025H42G (Used in ParCan & J-Head) (4.7k pullup) + * 5 : 100K thermistor - ATC Semitec 104GT-2/104NT-4-R025H42G (Used in ParCan, J-Head, and E3D) (4.7k pullup) * 501 : 100K Zonestar (Tronxy X3A) Thermistor + * 502 : 100K Zonestar Thermistor used by hot bed in Zonestar Průša P802M * 512 : 100k RPW-Ultra hotend thermistor (4.7k pullup) * 6 : 100k EPCOS - Not as accurate as table 1 (created using a fluke thermocouple) (4.7k pullup) * 7 : 100k Honeywell thermistor 135-104LAG-J01 (4.7k pullup) @@ -374,13 +379,16 @@ * 8 : 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) * 9 : 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup) * 10 : 100k RS thermistor 198-961 (4.7k pullup) - * 11 : 100k beta 3950 1% thermistor (4.7k pullup) + * 11 : 100k beta 3950 1% thermistor (Used in Keenovo AC silicone mats and most Wanhao i3 machines) (4.7k pullup) * 12 : 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed) * 13 : 100k Hisens 3950 1% up to 300°C for hotend "Simple ONE " & "Hotend "All In ONE" * 15 : 100k thermistor calibration for JGAurora A5 hotend * 18 : ATC Semitec 204GT-2 (4.7k pullup) Dagoma.Fr - MKS_Base_DKU001327 * 20 : Pt100 with circuit in the Ultimainboard V2.x with 5v excitation (AVR) * 21 : Pt100 with circuit in the Ultimainboard V2.x with 3.3v excitation (STM32 \ LPC176x....) + * 22 : 100k (hotend) with 4.7k pullup to 3.3V and 220R to analog input (as in GTM32 Pro vB) + * 23 : 100k (bed) with 4.7k pullup to 3.3v and 220R to analog input (as in GTM32 Pro vB) + * 30 : Kis3d Silicone heating mat 200W/300W with 6mm precision cast plate (EN AW 5083) NTC100K / B3950 (4.7k pullup) * 201 : Pt100 with circuit in Overlord, similar to Ultimainboard V2.x * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 * 61 : 100k Formbot / Vivedino 3950 350C thermistor 4.7k pullup @@ -396,7 +404,7 @@ * 52 : 200k thermistor - ATC Semitec 204GT-2 (1k pullup) * 55 : 100k thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (1k pullup) * - * 1047 : Pt1000 with 4k7 pullup + * 1047 : Pt1000 with 4k7 pullup (E3D) * 1010 : Pt1000 with 1k pullup (non standard) * 147 : Pt100 with 4k7 pullup * 110 : Pt100 with 1k pullup (non standard) @@ -423,6 +431,12 @@ #define DUMMY_THERMISTOR_998_VALUE 25 #define DUMMY_THERMISTOR_999_VALUE 100 +// Resistor values when using a MAX31865 (sensor -5) +// Sensor value is typically 100 (PT100) or 1000 (PT1000) +// Calibration value is typically 430 ohm for AdaFruit PT100 modules and 4300 ohm for AdaFruit PT1000 modules. +//#define MAX31865_SENSOR_OHMS 100 +//#define MAX31865_CALIBRATION_OHMS 430 + // Use temp sensor 1 as a redundant sensor with sensor 0. If the readings // from the two sensors differ too much the print will be aborted. //#define TEMP_SENSOR_1_AS_REDUNDANT @@ -464,41 +478,31 @@ //=========================================================================== //============================= PID Settings ================================ //=========================================================================== -// PID Tuning Guide here: http://reprap.org/wiki/PID_Tuning +// PID Tuning Guide here: https://reprap.org/wiki/PID_Tuning // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP #define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current #define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current #define PID_K1 0.95 // Smoothing factor within any PID loop + #if ENABLED(PIDTEMP) //#define PID_EDIT_MENU // Add PID editing to the "Advanced Settings" menu. (~700 bytes of PROGMEM) //#define PID_AUTOTUNE_MENU // Add PID auto-tuning to the "Advanced Settings" menu. (~250 bytes of PROGMEM) - //#define PID_DEBUG // Sends debug data to the serial port. - //#define PID_OPENLOOP 1 // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX - //#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay //#define PID_PARAMS_PER_HOTEND // Uses separate PID parameters for each extruder (useful for mismatched extruders) // Set/get with gcode: M301 E[extruder number, 0-2] - #define PID_FUNCTIONAL_RANGE 10 // If the temperature difference between the target temperature and the actual temperature - // is more than PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max. - - // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it - - // Ultimaker - #define DEFAULT_Kp 22.2 - #define DEFAULT_Ki 1.08 - #define DEFAULT_Kd 114 - - // MakerGear - //#define DEFAULT_Kp 7.0 - //#define DEFAULT_Ki 0.1 - //#define DEFAULT_Kd 12 - - // Mendel Parts V9 on 12V - //#define DEFAULT_Kp 63.0 - //#define DEFAULT_Ki 2.25 - //#define DEFAULT_Kd 440 + #if ENABLED(PID_PARAMS_PER_HOTEND) + // Specify between 1 and HOTENDS values per array. + // If fewer than EXTRUDER values are provided, the last element will be repeated. + #define DEFAULT_Kp_LIST { 22.20, 22.20 } + #define DEFAULT_Ki_LIST { 1.08, 1.08 } + #define DEFAULT_Kd_LIST { 114.00, 114.00 } + #else + #define DEFAULT_Kp 22.20 + #define DEFAULT_Ki 1.08 + #define DEFAULT_Kd 114.00 + #endif #endif // PIDTEMP //=========================================================================== @@ -534,21 +538,23 @@ //#define MIN_BED_POWER 0 //#define PID_BED_DEBUG // Sends debug data to the serial port. - //120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+) - //from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10) + // 120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+) + // from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10) #define DEFAULT_bedKp 10.00 #define DEFAULT_bedKi .023 #define DEFAULT_bedKd 305.4 - //120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+) - //from pidautotune - //#define DEFAULT_bedKp 97.1 - //#define DEFAULT_bedKi 1.41 - //#define DEFAULT_bedKd 1675.16 - // FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles. #endif // PIDTEMPBED +#if EITHER(PIDTEMP, PIDTEMPBED) + //#define PID_DEBUG // Sends debug data to the serial port. Use 'M303 D' to toggle activation. + //#define PID_OPENLOOP // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX + //#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay + #define PID_FUNCTIONAL_RANGE 10 // If the temperature difference between the target temperature and the actual temperature + // is more than PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max. +#endif + // @section extruder /** @@ -595,7 +601,7 @@ // @section machine -// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// Enable one of the options below for CoreXY, CoreXZ, or CoreYZ kinematics, // either in the usual order or reversed //#define COREXY //#define COREXZ @@ -603,6 +609,7 @@ //#define COREYX //#define COREZX //#define COREZY +//#define MARKFORGED_XY // MarkForged. See https://reprap.org/forum/read.php?152,504042 //=========================================================================== //============================== Endstop Settings =========================== @@ -698,7 +705,7 @@ * Enable if your probe or endstops falsely trigger due to noise. * * - Higher values may affect repeatability or accuracy of some bed probes. - * - To fix noise install a 100nF ceramic capacitor inline with the switch. + * - To fix noise install a 100nF ceramic capacitor in parallel with the switch. * - This feature is not required for common micro-switches mounted on PCBs * based on the Makerbot design, which already have the 100nF capacitor. * @@ -706,6 +713,9 @@ */ //#define ENDSTOP_NOISE_THRESHOLD 2 +// Check for stuck or disconnected endstops during homing moves. +//#define DETECT_BROKEN_ENDSTOP + //============================================================================= //============================== Movement Settings ============================ //============================================================================= @@ -799,10 +809,12 @@ * * See: * https://reprap.org/forum/read.php?1,739819 - * http://blog.kyneticcnc.com/2018/10/computing-junction-deviation-for-marlin.html + * https://blog.kyneticcnc.com/2018/10/computing-junction-deviation-for-marlin.html */ #if DISABLED(CLASSIC_JERK) #define JUNCTION_DEVIATION_MM 0.013 // (mm) Distance from real junction edge + #define JD_HANDLE_SMALL_SEGMENTS // Use curvature estimation instead of just the junction angle + // for small segments (< 1mm) with large junction angles (> 135°). #endif /** @@ -821,16 +833,19 @@ // @section probes // -// See http://marlinfw.org/docs/configuration/probes.html +// See https://marlinfw.org/docs/configuration/probes.html // /** - * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN - * - * Enable this option for a probe connected to the Z Min endstop pin. + * Enable this option for a probe connected to the Z-MIN pin. + * The probe replaces the Z-MIN endstop and is used for Z homing. + * (Automatically enables USE_PROBE_FOR_Z_HOMING.) */ #define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN +// Force the use of the probe for Z-axis homing +//#define USE_PROBE_FOR_Z_HOMING + /** * Z_MIN_PROBE_PIN * @@ -845,7 +860,6 @@ * - For simple switches connect... * - normally-closed switches to GND and D32. * - normally-open switches to 5V and D32. - * */ //#define Z_MIN_PROBE_PIN 32 // Pin 32 is the RAMPS default @@ -887,6 +901,11 @@ */ //#define BLTOUCH +/** + * Pressure sensor with a BLTouch-like interface + */ +//#define CREALITY_TOUCH + /** * Touch-MI Probe by hotends.fr * @@ -925,43 +944,61 @@ #define SMART_EFFECTOR_MOD_PIN -1 // Connect a GPIO pin to the Smart Effector MOD pin #endif +/** + * Use StallGuard2 to probe the bed with the nozzle. + * Requires stallGuard-capable Trinamic stepper drivers. + * CAUTION: This can damage machines with Z lead screws. + * Take extreme care when setting up this feature. + */ +//#define SENSORLESS_PROBING + // // For Z_PROBE_ALLEN_KEY see the Delta example configurations. // /** - * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * Nozzle-to-Probe offsets { X, Y, Z } + * + * - Use a caliper or ruler to measure the distance from the tip of + * the Nozzle to the center-point of the Probe in the X and Y axes. + * - For the Z offset use your best known value and adjust at runtime. + * - Probe Offsets can be tuned at runtime with 'M851', LCD menus, babystepping, etc. * - * In the following example the X and Y offsets are both positive: + * Assuming the typical work area orientation: + * - Probe to RIGHT of the Nozzle has a Positive X offset + * - Probe to LEFT of the Nozzle has a Negative X offset + * - Probe in BACK of the Nozzle has a Positive Y offset + * - Probe in FRONT of the Nozzle has a Negative Y offset * - * #define NOZZLE_TO_PROBE_OFFSET { 10, 10, 0 } + * Some examples: + * #define NOZZLE_TO_PROBE_OFFSET { 10, 10, -1 } // Example "1" + * #define NOZZLE_TO_PROBE_OFFSET {-10, 5, -1 } // Example "2" + * #define NOZZLE_TO_PROBE_OFFSET { 5, -5, -1 } // Example "3" + * #define NOZZLE_TO_PROBE_OFFSET {-15,-10, -1 } // Example "4" * * +-- BACK ---+ - * | | - * L | (+) P | R <-- probe (20,20) - * E | | I - * F | (-) N (+) | G <-- nozzle (10,10) - * T | | H - * | (-) | T - * | | + * | [+] | + * L | 1 | R <-- Example "1" (right+, back+) + * E | 2 | I <-- Example "2" ( left-, back+) + * F |[-] N [+]| G <-- Nozzle + * T | 3 | H <-- Example "3" (right+, front-) + * | 4 | T <-- Example "4" ( left-, front-) + * | [-] | * O-- FRONT --+ - * (0,0) - * - * Specify a Probe position as { X, Y, Z } */ #define NOZZLE_TO_PROBE_OFFSET { 10, 10, 0 } // Most probes should stay away from the edges of the bed, but // with NOZZLE_AS_PROBE this can be negative for a wider probing area. -#define MIN_PROBE_EDGE 10 +#define PROBING_MARGIN 10 -// X and Y axis travel speed (mm/m) between probes -#define XY_PROBE_SPEED 8000 +// X and Y axis travel speed (mm/min) between probes +#define XY_PROBE_SPEED (133*60) -// Feedrate (mm/m) for the first approach when double-probing (MULTIPLE_PROBING == 2) +// Feedrate (mm/min) for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z -// Feedrate (mm/m) for the "accurate" probe of each point +// Feedrate (mm/min) for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) /** @@ -1032,18 +1069,18 @@ #define Z_ENABLE_ON 0 #define E_ENABLE_ON 0 // For all extruders -// Disables axis stepper immediately when it's not being used. +// Disable axis steppers immediately when they're not being stepped. // WARNING: When motors turn off there is a chance of losing position accuracy! #define DISABLE_X false #define DISABLE_Y false #define DISABLE_Z false -// Warn on display about possibly reduced accuracy +// Turn off the display blinking that warns about possible accuracy reduction //#define DISABLE_REDUCED_ACCURACY_WARNING // @section extruder -#define DISABLE_E false // For all extruders +#define DISABLE_E false // Disable the extruder when not stepping #define DISABLE_INACTIVE_EXTRUDER // Keep only the active extruder enabled // @section machine @@ -1131,14 +1168,14 @@ * * RAMPS-based boards use SERVO3_PIN for the first runout sensor. * For other boards you may need to define FIL_RUNOUT_PIN, FIL_RUNOUT2_PIN, etc. - * By default the firmware assumes HIGH=FILAMENT PRESENT. */ //#define FILAMENT_RUNOUT_SENSOR #if ENABLED(FILAMENT_RUNOUT_SENSOR) - #define NUM_RUNOUT_SENSORS 1 // Number of sensors, up to one per extruder. Define a FIL_RUNOUT#_PIN for each. - #define FIL_RUNOUT_INVERTING false // Set to true to invert the logic of the sensor. - #define FIL_RUNOUT_PULLUP // Use internal pullup for filament runout pins. - //#define FIL_RUNOUT_PULLDOWN // Use internal pulldown for filament runout pins. + #define FIL_RUNOUT_ENABLED_DEFAULT true // Enable the sensor on startup. Override with M412 followed by M500. + #define NUM_RUNOUT_SENSORS 1 // Number of sensors, up to one per extruder. Define a FIL_RUNOUT#_PIN for each. + #define FIL_RUNOUT_STATE LOW // Pin state indicating that filament is NOT present. + #define FIL_RUNOUT_PULLUP // Use internal pullup for filament runout pins. + //#define FIL_RUNOUT_PULLDOWN // Use internal pulldown for filament runout pins. // Set one or more commands to execute on filament runout. // (After 'M412 H' Marlin will ask the host to handle the process.) @@ -1328,7 +1365,6 @@ */ //#define Z_PROBE_END_SCRIPT "G1 Z10 F12000\nG1 X15 Y330\nG1 Z0.5\nG1 Z10" - // @section homing // The center of the bed is at (X=0, Y=0) @@ -1346,17 +1382,17 @@ // // - Allow Z homing only after X and Y homing AND stepper drivers still enabled. // - If stepper drivers time out, it will need X and Y homing again before Z homing. -// - Move the Z probe (or nozzle) to a defined XY point before Z Homing when homing all axes (G28). +// - Move the Z probe (or nozzle) to a defined XY point before Z Homing. // - Prevent Z homing when the Z probe is outside bed area. // //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_X_POINT X_CENTER // X point for Z homing + #define Z_SAFE_HOMING_Y_POINT Y_CENTER // Y point for Z homing #endif -// Homing speeds (mm/m) +// Homing speeds (mm/min) #define HOMING_FEEDRATE_XY (50*60) #define HOMING_FEEDRATE_Z (4*60) @@ -1438,6 +1474,7 @@ //#define EEPROM_SETTINGS // Persistent storage with M500 and M501 //#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! #define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. +#define EEPROM_BOOT_SILENT // Keep M503 quiet and only give errors during first load #if ENABLED(EEPROM_SETTINGS) //#define EEPROM_AUTO_INIT // Init EEPROM automatically on any errors. #endif @@ -1491,8 +1528,11 @@ #if ENABLED(NOZZLE_PARK_FEATURE) // Specify a park position as { X, Y, Z_raise } #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } + //#define NOZZLE_PARK_X_ONLY // X move only is required to park + //#define NOZZLE_PARK_Y_ONLY // Y move only is required to park + #define NOZZLE_PARK_Z_RAISE_MIN 2 // (mm) Always raise Z by at least this distance #define NOZZLE_PARK_XY_FEEDRATE 100 // (mm/s) X and Y axes feedrate (also used for delta Z axis) - #define NOZZLE_PARK_Z_FEEDRATE 5 // (mm/s) Z axis feedrate (not used for delta printers) + #define NOZZLE_PARK_Z_FEEDRATE 5 // (mm/s) Z axis feedrate (not used for delta printers) #endif /** @@ -1531,7 +1571,6 @@ * * Caveats: The ending Z should be the same as starting Z. * Attention: EXPERIMENTAL. G-code arguments may change. - * */ //#define NOZZLE_CLEAN_FEATURE @@ -1557,8 +1596,15 @@ // Move the nozzle to the initial position after cleaning #define NOZZLE_CLEAN_GOBACK - // Enable for a purge/clean station that's always at the gantry height (thus no Z move) + // For a purge/clean station that's always at the gantry height (thus no Z move) //#define NOZZLE_CLEAN_NO_Z + + // For a purge/clean station mounted on the X axis + //#define NOZZLE_CLEAN_NO_Y + + // Explicit wipe G-code script applies to a G12 with no arguments. + //#define WIPE_SEQUENCE_COMMANDS "G1 X-17 Y25 Z10 F4000\nG1 Z1\nM114\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 Z15\nM400\nG0 X-10.0 Y-9.0" + #endif /** @@ -1592,6 +1638,37 @@ */ //#define PRINTCOUNTER +/** + * Password + * + * Set a numerical password for the printer which can be requested: + * + * - When the printer boots up + * - Upon opening the 'Print from Media' Menu + * - When SD printing is completed or aborted + * + * The following G-codes can be used: + * + * M510 - Lock Printer. Blocks all commands except M511. + * M511 - Unlock Printer. + * M512 - Set, Change and Remove Password. + * + * If you forget the password and get locked out you'll need to re-flash + * the firmware with the feature disabled, reset EEPROM, and (optionally) + * re-flash the firmware again with this feature enabled. + */ +//#define PASSWORD_FEATURE +#if ENABLED(PASSWORD_FEATURE) + #define PASSWORD_LENGTH 4 // (#) Number of digits (1-9). 3 or 4 is recommended + #define PASSWORD_ON_STARTUP + #define PASSWORD_UNLOCK_GCODE // Unlock with the M511 P command. Disable to prevent brute-force attack. + #define PASSWORD_CHANGE_GCODE // Change the password with M512 P S. + //#define PASSWORD_ON_SD_PRINT_MENU // This does not prevent gcodes from running + //#define PASSWORD_AFTER_SD_PRINT_END + //#define PASSWORD_AFTER_SD_PRINT_ABORT + //#include "Configuration_Secure.h" // External file with PASSWORD_DEFAULT_VALUE +#endif + //============================================================================= //============================= LCD and SD support ============================ //============================================================================= @@ -1603,10 +1680,10 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cz, da, de, el, el_gr, es, eu, fi, fr, gl, hr, it, jp_kana, - * ko_KR, nl, pl, pt, pt_br, ru, sk, tr, uk, vi, zh_CN, zh_TW, test + * en, an, bg, ca, cz, da, de, el, el_gr, es, eu, fi, fr, gl, hr, hu, it, + * jp_kana, ko_KR, nl, pl, pt, pt_br, ro, ru, sk, tr, uk, vi, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cz':'Czech', 'da':'Danish', 'de':'German', 'el':'Greek', 'el_gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'jp_kana':'Japanese', 'ko_KR':'Korean (South Korea)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt_br':'Portuguese (Brazilian)', 'ru':'Russian', 'sk':'Slovak', 'tr':'Turkish', 'uk':'Ukrainian', 'vi':'Vietnamese', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Traditional)', 'test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cz':'Czech', 'da':'Danish', 'de':'German', 'el':'Greek', 'el_gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'hu':'Hungarian', 'it':'Italian', 'jp_kana':'Japanese', 'ko_KR':'Korean (South Korea)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt_br':'Portuguese (Brazilian)', 'ro':'Romanian', 'ru':'Russian', 'sk':'Slovak', 'tr':'Turkish', 'uk':'Ukrainian', 'vi':'Vietnamese', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Traditional)', 'test':'TEST' } */ #define LCD_LANGUAGE en @@ -1628,16 +1705,16 @@ * - Click the controller to view the LCD menu * - The LCD will display Japanese, Western, or Cyrillic text * - * See http://marlinfw.org/docs/development/lcd_language.html + * See https://marlinfw.org/docs/development/lcd_language.html * * :['JAPANESE', 'WESTERN', 'CYRILLIC'] */ #define DISPLAY_CHARSET_HD44780 JAPANESE /** - * Info Screen Style (0:Classic, 1:Prusa) + * Info Screen Style (0:Classic, 1:Průša) * - * :[0:'Classic', 1:'Prusa'] + * :[0:'Classic', 1:'Průša'] */ #define LCD_INFO_SCREEN_STYLE 0 @@ -1646,7 +1723,6 @@ * * SD Card support is disabled by default. If your controller has an SD slot, * you must uncomment the following option or it won't work. - * */ //#define SDSUPPORT @@ -1755,7 +1831,7 @@ // // RepRapDiscount Smart Controller. -// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// https://reprap.org/wiki/RepRapDiscount_Smart_Controller // // Note: Usually sold with a white PCB. // @@ -1779,13 +1855,13 @@ // // PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) -// http://reprap.org/wiki/PanelOne +// https://reprap.org/wiki/PanelOne // //#define PANEL_ONE // // GADGETS3D G3D LCD/SD Controller -// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// https://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel // // Note: Usually sold with a blue PCB. // @@ -1872,7 +1948,7 @@ // // 2-wire Non-latching LCD SR from https://goo.gl/aJJ4sH -// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// LCD configuration: https://reprap.org/wiki/SAV_3D_LCD // //#define SAV_3DLCD @@ -1883,6 +1959,14 @@ // //#define FF_INTERFACEBOARD +// +// TFT GLCD Panel with Marlin UI +// Panel connected to main board by SPI or I2C interface. +// See https://github.com/Serhiy-K/TFTGLCDAdapter +// +//#define TFTGLCD_PANEL_SPI +//#define TFTGLCD_PANEL_I2C + //============================================================================= //======================= LCD / Controller Selection ======================= //========================= (Graphical LCDs) ======================== @@ -1894,10 +1978,12 @@ // IMPORTANT: The U8glib library is required for Graphical Display! // https://github.com/olikraus/U8glib_Arduino // +// NOTE: If the LCD is unresponsive you may need to reverse the plugs. +// // // RepRapDiscount FULL GRAPHIC Smart Controller -// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// https://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller // //#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER @@ -1910,20 +1996,20 @@ // // Activate one of these if you have a Panucatt Devices // Viki 2.0 or mini Viki with Graphic LCD -// http://panucatt.com +// https://www.panucatt.com // //#define VIKI2 //#define miniVIKI // // MakerLab Mini Panel with graphic -// controller and SD support - http://reprap.org/wiki/Mini_panel +// controller and SD support - https://reprap.org/wiki/Mini_panel // //#define MINIPANEL // // MaKr3d Makr-Panel with graphic controller and SD support. -// http://reprap.org/wiki/MaKr3d_MaKrPanel +// https://reprap.org/wiki/MaKr3d_MaKrPanel // //#define MAKRPANEL @@ -1962,6 +2048,12 @@ // //#define MKS_MINI_12864 +// +// MKS LCD12864A/B with graphic controller and SD support. Follows MKS_MINI_12864 pinout. +// https://www.aliexpress.com/item/33018110072.html +// +//#define MKS_LCD12864 + // // FYSETC variant of the MINI12864 graphic controller with SD support // https://wiki.fysetc.com/Mini12864_Panel/ @@ -1969,7 +2061,7 @@ //#define FYSETC_MINI_12864_X_X // Type C/D/E/F. No tunable RGB Backlight by default //#define FYSETC_MINI_12864_1_2 // Type C/D/E/F. Simple RGB Backlight (always on) //#define FYSETC_MINI_12864_2_0 // Type A/B. Discreet RGB Backlight -//#define FYSETC_MINI_12864_2_1 // Type A/B. Neopixel RGB Backlight +//#define FYSETC_MINI_12864_2_1 // Type A/B. NeoPixel RGB Backlight //#define FYSETC_GENERIC_12864_1_1 // Larger display with basic ON/OFF backlight. // @@ -2003,7 +2095,7 @@ // // Silvergate GLCD controller -// http://github.com/android444/Silvergate +// https://github.com/android444/Silvergate // //#define SILVER_GATE_GLCD_CONTROLLER @@ -2031,14 +2123,21 @@ //#define OLED_PANEL_TINYBOY2 // -// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER -// http://reprap.org/wiki/MKS_12864OLED +// MKS OLED 1.3" 128×64 FULL GRAPHICS CONTROLLER +// https://reprap.org/wiki/MKS_12864OLED // // Tiny, but very sharp OLED display // //#define MKS_12864OLED // Uses the SH1106 controller (default) //#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller +// +// Zonestar OLED 128×64 FULL GRAPHICS CONTROLLER +// +//#define ZONESTAR_12864LCD // Graphical (DOGM) with ST7920 controller +//#define ZONESTAR_12864OLED // 1.3" OLED with SH1106 controller (default) +//#define ZONESTAR_12864OLED_SSD1306 // 0.96" OLED with SSD1306 controller + // // Einstart S OLED SSD1306 // @@ -2049,21 +2148,31 @@ // //#define OVERLORD_OLED +// +// FYSETC OLED 2.42" 128×64 FULL GRAPHICS CONTROLLER with WS2812 RGB +// Where to find : https://www.aliexpress.com/item/4000345255731.html +//#define FYSETC_242_OLED_12864 // Uses the SSD1309 controller + //============================================================================= //========================== Extensible UI Displays =========================== //============================================================================= // // DGUS Touch Display with DWIN OS. (Choose one.) +// ORIGIN : https://www.aliexpress.com/item/32993409517.html +// FYSETC : https://www.aliexpress.com/item/32961471929.html // //#define DGUS_LCD_UI_ORIGIN //#define DGUS_LCD_UI_FYSETC //#define DGUS_LCD_UI_HIPRECY // -// Touch-screen LCD for Malyan M200 printers +// Touch-screen LCD for Malyan M200/M300 printers // //#define MALYAN_LCD +#if ENABLED(MALYAN_LCD) + #define LCD_SERIAL_PORT 1 // Default is 1 for Malyan M200 +#endif // // Touch UI for FTDI EVE (FT800/FT810) displays @@ -2071,42 +2180,100 @@ // //#define TOUCH_UI_FTDI_EVE +// +// Touch-screen LCD for Anycubic printers +// +//#define ANYCUBIC_LCD_I3MEGA +//#define ANYCUBIC_LCD_CHIRON +#if EITHER(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON) + #define LCD_SERIAL_PORT 3 // Default is 3 for Anycubic + //#define ANYCUBIC_LCD_DEBUG +#endif + // // Third-party or vendor-customized controller interfaces. // Sources should be installed in 'src/lcd/extensible_ui'. // //#define EXTENSIBLE_UI +#if ENABLED(EXTENSIBLE_UI) + //#define EXTUI_LOCAL_BEEPER // Enables use of local Beeper pin with external display +#endif + //============================================================================= //=============================== Graphical TFTs ============================== //============================================================================= -// -// FSMC display (MKS Robin, Alfawise U20, JGAurora A5S, REXYZ A1, etc.) -// -//#define FSMC_GRAPHICAL_TFT +/** + * TFT Type - Select your Display type + * + * Available options are: + * MKS_TS35_V2_0, + * MKS_ROBIN_TFT24, MKS_ROBIN_TFT28, MKS_ROBIN_TFT32, MKS_ROBIN_TFT35, + * MKS_ROBIN_TFT43, MKS_ROBIN_TFT_V1_1R + * TFT_TRONXY_X5SA, ANYCUBIC_TFT35, LONGER_LK_TFT28 + * TFT_GENERIC + * + * For TFT_GENERIC, you need to configure these 3 options: + * Driver: TFT_DRIVER + * Current Drivers are: AUTO, ST7735, ST7789, ST7796, R61505, ILI9328, ILI9341, ILI9488 + * Resolution: TFT_WIDTH and TFT_HEIGHT + * Interface: TFT_INTERFACE_FSMC or TFT_INTERFACE_SPI + */ +//#define TFT_GENERIC + +/** + * TFT UI - User Interface Selection. Enable one of the following options: + * + * TFT_CLASSIC_UI - Emulated DOGM - 128x64 Upscaled + * TFT_COLOR_UI - Marlin Default Menus, Touch Friendly, using full TFT capabilities + * TFT_LVGL_UI - A Modern UI using LVGL + * + * For LVGL_UI also copy the 'assets' folder from the build directory to the + * root of your SD card, together with the compiled firmware. + */ +//#define TFT_CLASSIC_UI +//#define TFT_COLOR_UI +//#define TFT_LVGL_UI + +/** + * TFT Rotation. Set to one of the following values: + * + * TFT_ROTATE_90, TFT_ROTATE_90_MIRROR_X, TFT_ROTATE_90_MIRROR_Y, + * TFT_ROTATE_180, TFT_ROTATE_180_MIRROR_X, TFT_ROTATE_180_MIRROR_Y, + * TFT_ROTATE_270, TFT_ROTATE_270_MIRROR_X, TFT_ROTATE_270_MIRROR_Y, + * TFT_MIRROR_X, TFT_MIRROR_Y, TFT_NO_ROTATION + */ +//#define TFT_ROTATION TFT_NO_ROTATION //============================================================================= //============================ Other Controllers ============================ //============================================================================= +// +// Ender-3 v2 OEM display. A DWIN display with Rotary Encoder. +// +//#define DWIN_CREALITY_LCD + // // ADS7843/XPT2046 ADC Touchscreen such as ILI9341 2.8 // -//#define TOUCH_BUTTONS -#if ENABLED(TOUCH_BUTTONS) +//#define TOUCH_SCREEN +#if ENABLED(TOUCH_SCREEN) #define BUTTON_DELAY_EDIT 50 // (ms) Button repeat delay for edit screens #define BUTTON_DELAY_MENU 250 // (ms) Button repeat delay for menus - #define XPT2046_X_CALIBRATION 12316 - #define XPT2046_Y_CALIBRATION -8981 - #define XPT2046_X_OFFSET -43 - #define XPT2046_Y_OFFSET 257 + #define TOUCH_SCREEN_CALIBRATION + + //#define XPT2046_X_CALIBRATION 12316 + //#define XPT2046_Y_CALIBRATION -8981 + //#define XPT2046_X_OFFSET -43 + //#define XPT2046_Y_OFFSET 257 #endif // // RepRapWorld REPRAPWORLD_KEYPAD v1.1 -// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// https://reprapworld.com/products/electronics/ramps/keypad_v1_0_fully_assembled/ // //#define REPRAPWORLD_KEYPAD //#define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0 // (mm) Distance to move per key-press @@ -2117,6 +2284,10 @@ // @section extras +// Set number of user-controlled fans. Disable to use all board-defined fans. +// :[1,2,3,4,5,6,7,8] +//#define NUM_M106_FANS 1 + // Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino //#define FAST_PWM_FAN @@ -2143,9 +2314,6 @@ // then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) //#define TEMP_STAT_LEDS -// SkeinForge sends the wrong arc g-codes when using Arc Point as fillet procedure -//#define SF_ARC_FIX - // Support for the BariCUDA Paste Extruder //#define BARICUDA @@ -2156,7 +2324,6 @@ //#define PCA9632 // Support for PCA9533 PWM LED driver -// https://github.com/mikeshub/SailfishRGB_LED //#define PCA9533 /** @@ -2168,18 +2335,17 @@ * Adds the M150 command to set the LED (or LED strip) color. * If pins are PWM capable (e.g., 4, 5, 6, 11) then a range of * luminance values can be set from 0 to 255. - * For Neopixel LED an overall brightness parameter is also available. + * For NeoPixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOSFET Chip between PWM lines and LEDs, * as the Arduino cannot handle the current the LEDs will require. * Failure to follow this precaution can destroy your Arduino! - * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * NOTE: A separate 5V power supply is required! The NeoPixel LED needs * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * * LED Type. Enable only one of the following two options. - * */ //#define RGB_LED //#define RGBW_LED @@ -2191,19 +2357,29 @@ //#define RGB_LED_W_PIN -1 #endif -// Support for Adafruit Neopixel LED driver +// Support for Adafruit NeoPixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin //#define NEOPIXEL2_TYPE NEOPIXEL_TYPE //#define NEOPIXEL2_PIN 5 - #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip, larger of 2 strips if 2 neopixel strips are used + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip. (Longest strip when NEOPIXEL2_SEPARATE is disabled.) #define NEOPIXEL_IS_SEQUENTIAL // Sequential display for temperature change - LED by LED. Disable to change all LEDs at once. #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness (0-255) //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup - // Use a single Neopixel LED for static (background) lighting + // Support for second Adafruit NeoPixel LED driver controlled with M150 S1 ... + //#define NEOPIXEL2_SEPARATE + #if ENABLED(NEOPIXEL2_SEPARATE) + #define NEOPIXEL2_PIXELS 15 // Number of LEDs in the second strip + #define NEOPIXEL2_BRIGHTNESS 127 // Initial brightness (0-255) + #define NEOPIXEL2_STARTUP_TEST // Cycle through colors at startup + #else + //#define NEOPIXEL2_INSERIES // Default behavior is NeoPixel 2 in parallel + #endif + + // Use a single NeoPixel LED for static (background) lighting //#define NEOPIXEL_BKGD_LED_INDEX 0 // Index of the LED to use //#define NEOPIXEL_BKGD_COLOR { 255, 255, 255, 0 } // R, G, B, W #endif @@ -2223,17 +2399,12 @@ #define PRINTER_EVENT_LEDS #endif -/** - * R/C SERVO support - * Sponsored by TrinityLabs, Reworked by codexmas - */ - /** * Number of servos * * For some servo-related options NUM_SERVOS will be set automatically. * Set this manually if there are extra servos needing manual control. - * Leave undefined or set to 0 to entirely disable the servo subsystem. + * Set to 0 to turn off servo support. */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command @@ -2245,5 +2416,5 @@ // Only power servos during movement, otherwise leave off to prevent jitter //#define DEACTIVATE_SERVOS_AFTER_MOVE -// Allow servo angle to be edited and saved to EEPROM +// Edit servo angles with M281 and save to EEPROM with M500 //#define EDITABLE_SERVO_ANGLES diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index ede35a561e08..bcacddd20d42 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -29,15 +29,26 @@ * Some of these settings can damage your printer if improperly set! * * Basic settings can be found in Configuration.h - * */ -#define CONFIGURATION_ADV_H_VERSION 020004 - -// @section temperature +#define CONFIGURATION_ADV_H_VERSION 020007 //=========================================================================== -//=============================Thermal Settings ============================ +//============================= Thermal Settings ============================ //=========================================================================== +// @section temperature + +/** + * Thermocouple sensors are quite sensitive to noise. Any noise induced in + * the sensor wires, such as by stepper motor wires run in parallel to them, + * may result in the thermocouple sensor reporting spurious errors. This + * value is the number of errors which can occur in a row before the error + * is reported. This allows us to ignore intermittent error conditions while + * still detecting an actual failure, which should result in a continuous + * stream of errors from the sensor. + * + * Set this value to 0 to fail on the first error to occur. + */ +#define THERMOCOUPLE_MAX_ERRORS 15 // // Custom Thermistor 1000 parameters @@ -113,9 +124,19 @@ #define HEATER_BED_INVERTING true #endif -/** - * Heated Chamber settings - */ +// +// Heated Bed Bang-Bang options +// +#if DISABLED(PIDTEMPBED) + #define BED_CHECK_INTERVAL 5000 // (ms) Interval between checks in bang-bang control + #if ENABLED(BED_LIMIT_SWITCHING) + #define BED_HYSTERESIS 2 // (°C) Only set the relevant heater state when ABS(T-target) > BED_HYSTERESIS + #endif +#endif + +// +// Heated Chamber options +// #if TEMP_SENSOR_CHAMBER #define CHAMBER_MINTEMP 5 #define CHAMBER_MAXTEMP 60 @@ -123,12 +144,28 @@ //#define CHAMBER_LIMIT_SWITCHING //#define HEATER_CHAMBER_PIN 44 // Chamber heater on/off pin //#define HEATER_CHAMBER_INVERTING false -#endif -#if DISABLED(PIDTEMPBED) - #define BED_CHECK_INTERVAL 5000 // ms between checks in bang-bang control - #if ENABLED(BED_LIMIT_SWITCHING) - #define BED_HYSTERESIS 2 // Only disable heating if T>target+BED_HYSTERESIS and enable heating if T>target-BED_HYSTERESIS + //#define CHAMBER_FAN // Enable a fan on the chamber + #if ENABLED(CHAMBER_FAN) + #define CHAMBER_FAN_MODE 2 // Fan control mode: 0=Static; 1=Linear increase when temp is higher than target; 2=V-shaped curve. + #if CHAMBER_FAN_MODE == 0 + #define CHAMBER_FAN_BASE 255 // Chamber fan PWM (0-255) + #elif CHAMBER_FAN_MODE == 1 + #define CHAMBER_FAN_BASE 128 // Base chamber fan PWM (0-255); turns on when chamber temperature is above the target + #define CHAMBER_FAN_FACTOR 25 // PWM increase per °C above target + #elif CHAMBER_FAN_MODE == 2 + #define CHAMBER_FAN_BASE 128 // Minimum chamber fan PWM (0-255) + #define CHAMBER_FAN_FACTOR 25 // PWM increase per °C difference from target + #endif + #endif + + //#define CHAMBER_VENT // Enable a servo-controlled vent on the chamber + #if ENABLED(CHAMBER_VENT) + #define CHAMBER_VENT_SERVO_NR 1 // Index of the vent servo + #define HIGH_EXCESS_HEAT_LIMIT 5 // How much above target temp to consider there is excess heat in the chamber + #define LOW_EXCESS_HEAT_LIMIT 3 + #define MIN_COOLING_SLOPE_TIME_CHAMBER_VENT 20 + #define MIN_COOLING_SLOPE_DEG_CHAMBER_VENT 1.5 #endif #endif @@ -206,7 +243,7 @@ // A well-chosen Kc value should add just enough power to melt the increased material volume. //#define PID_EXTRUSION_SCALING #if ENABLED(PID_EXTRUSION_SCALING) - #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define DEFAULT_Kc (100) // heating power = Kc * e_speed #define LPQ_MAX_LEN 50 #endif @@ -262,23 +299,30 @@ #endif /** - * Automatic Temperature: - * The hotend target temperature is calculated by all the buffered lines of gcode. - * The maximum buffered steps/sec of the extruder motor is called "se". - * Start autotemp mode with M109 S B F - * The target temperature is set to mintemp+factor*se[steps/sec] and is limited by - * mintemp and maxtemp. Turn this off by executing M109 without F* - * Also, if the temperature is set to a value below mintemp, it will not be changed by autotemp. - * On an Ultimaker, some initial testing worked with M109 S215 B260 F1 in the start.gcode + * Automatic Temperature Mode + * + * Dynamically adjust the hotend target temperature based on planned E moves. + * + * (Contrast with PID_EXTRUSION_SCALING, which tracks E movement and adjusts PID + * behavior using an additional kC value.) + * + * Autotemp is calculated by (mintemp + factor * mm_per_sec), capped to maxtemp. + * + * Enable Autotemp Mode with M104/M109 F S B. + * Disable by sending M104/M109 with no F parameter (or F0 with AUTOTEMP_PROPORTIONAL). */ #define AUTOTEMP #if ENABLED(AUTOTEMP) - #define AUTOTEMP_OLDWEIGHT 0.98 + #define AUTOTEMP_OLDWEIGHT 0.98 + // Turn on AUTOTEMP on M104/M109 by default using proportions set here + //#define AUTOTEMP_PROPORTIONAL + #if ENABLED(AUTOTEMP_PROPORTIONAL) + #define AUTOTEMP_MIN_P 0 // (°C) Added to the target temperature + #define AUTOTEMP_MAX_P 5 // (°C) Added to the target temperature + #define AUTOTEMP_FACTOR_P 1 // Apply this F parameter by default (overridden by M104/M109 F) + #endif #endif -// Show extra position information with 'M114 D' -//#define M114_DETAIL - // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -319,10 +363,22 @@ #if ENABLED(EXTRUDER_RUNOUT_PREVENT) #define EXTRUDER_RUNOUT_MINTEMP 190 #define EXTRUDER_RUNOUT_SECONDS 30 - #define EXTRUDER_RUNOUT_SPEED 1500 // (mm/m) + #define EXTRUDER_RUNOUT_SPEED 1500 // (mm/min) #define EXTRUDER_RUNOUT_EXTRUDE 5 // (mm) #endif +/** + * Hotend Idle Timeout + * Prevent filament in the nozzle from charring and causing a critical jam. + */ +//#define HOTEND_IDLE_TIMEOUT +#if ENABLED(HOTEND_IDLE_TIMEOUT) + #define HOTEND_IDLE_TIMEOUT_SEC (5*60) // (seconds) Time without extruder movement to trigger protection + #define HOTEND_IDLE_MIN_TRIGGER 180 // (°C) Minimum temperature to enable hotend protection + #define HOTEND_IDLE_NOZZLE_TARGET 0 // (°C) Safe temperature for the nozzle after timeout + #define HOTEND_IDLE_BED_TARGET 0 // (°C) Safe temperature for the bed after timeout +#endif + // @section temperature // Calibration for AD595 / AD8495 sensor to adjust temperature measurements. @@ -336,15 +392,22 @@ * Controller Fan * To cool down the stepper drivers and MOSFETs. * - * The fan will turn on automatically whenever any stepper is enabled - * and turn off after a set period after all steppers are turned off. + * The fan turns on automatically whenever any driver is enabled and turns + * off (or reduces to idle speed) shortly after drivers are turned off. */ //#define USE_CONTROLLER_FAN #if ENABLED(USE_CONTROLLER_FAN) - //#define CONTROLLER_FAN_PIN -1 // Set a custom pin for the controller fan - #define CONTROLLERFAN_SECS 60 // Duration in seconds for the fan to run after all motors are disabled - #define CONTROLLERFAN_SPEED 255 // 255 == full speed - //#define CONTROLLERFAN_SPEED_Z_ONLY 127 // Reduce noise on machines that keep Z enabled + //#define CONTROLLER_FAN_PIN -1 // Set a custom pin for the controller fan + //#define CONTROLLER_FAN_USE_Z_ONLY // With this option only the Z axis is considered + //#define CONTROLLER_FAN_IGNORE_Z // Ignore Z stepper. Useful when stepper timeout is disabled. + #define CONTROLLERFAN_SPEED_MIN 0 // (0-255) Minimum speed. (If set below this value the fan is turned off.) + #define CONTROLLERFAN_SPEED_ACTIVE 255 // (0-255) Active speed, used when any motor is enabled + #define CONTROLLERFAN_SPEED_IDLE 0 // (0-255) Idle speed, used when motors are disabled + #define CONTROLLERFAN_IDLE_TIME 60 // (seconds) Extra time to keep the fan running after disabling motors + //#define CONTROLLER_FAN_EDITABLE // Enable M710 configurable settings + #if ENABLED(CONTROLLER_FAN_EDITABLE) + #define CONTROLLER_FAN_MENU // Enable the Controller Fan submenu + #endif #endif // When first starting the main fan, run it at full speed for the @@ -417,6 +480,8 @@ #define E3_AUTO_FAN_PIN -1 #define E4_AUTO_FAN_PIN -1 #define E5_AUTO_FAN_PIN -1 +#define E6_AUTO_FAN_PIN -1 +#define E7_AUTO_FAN_PIN -1 #define CHAMBER_AUTO_FAN_PIN -1 #define EXTRUDER_AUTO_FAN_TEMPERATURE 50 @@ -447,7 +512,7 @@ //#define CASE_LIGHT_MAX_PWM 128 // Limit pwm //#define CASE_LIGHT_MENU // Add Case Light options to the LCD menu //#define CASE_LIGHT_NO_BRIGHTNESS // Disable brightness control. Enable for non-PWM lighting. - //#define CASE_LIGHT_USE_NEOPIXEL // Use Neopixel LED as case light, requires NEOPIXEL_LED. + //#define CASE_LIGHT_USE_NEOPIXEL // Use NeoPixel LED as case light, requires NEOPIXEL_LED. #if ENABLED(CASE_LIGHT_USE_NEOPIXEL) #define CASE_LIGHT_NEOPIXEL_COLOR { 255, 255, 255, 255 } // { Red, Green, Blue, White } #endif @@ -572,8 +637,7 @@ // Default x offset in duplication mode (typically set to half print bed width) #define DEFAULT_DUPLICATION_X_OFFSET 100 - -#endif // DUAL_X_CARRIAGE +#endif // Activate a solenoid on the active extruder with M380. Disable all with M381. // Define SOL0_PIN, SOL1_PIN, etc., for each extruder that has a solenoid. @@ -581,19 +645,24 @@ // @section homing -// Homing hits each endstop, retracts by these distances, then does a slower bump. -#define X_HOME_BUMP_MM 5 -#define Y_HOME_BUMP_MM 5 -#define Z_HOME_BUMP_MM 2 -#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) -//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially -//#define HOMING_BACKOFF_MM { 2, 2, 2 } // (mm) Move away from the endstops after homing +/** + * Homing Procedure + * Homing (G28) does an indefinite move towards the endstops to establish + * the position of the toolhead relative to the workspace. + */ -// When G28 is called, this option will make Y home before X -//#define HOME_Y_BEFORE_X +//#define SENSORLESS_BACKOFF_MM { 2, 2 } // (mm) Backoff from endstops before sensorless homing -// Enable this if X or Y can't home without homing the other axis first. -//#define CODEPENDENT_XY_HOMING +#define HOMING_BUMP_MM { 5, 5, 2 } // (mm) Backoff from endstops after first bump +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) + +//#define HOMING_BACKOFF_POST_MM { 2, 2, 2 } // (mm) Backoff from endstops after homing + +//#define QUICK_HOME // If G28 contains XY do a diagonal move first +//#define HOME_Y_BEFORE_X // If G28 contains XY home Y before X +//#define CODEPENDENT_XY_HOMING // If X/Y can't home without homing Y/X first + +// @section bltouch #if ENABLED(BLTOUCH) /** @@ -601,8 +670,8 @@ * Do not activate settings that the probe might not understand. Clones might misunderstand * advanced commands. * - * Note: If the probe is not deploying, check a "Cmd: Reset" and "Cmd: Self-Test" and then - * check the wiring of the BROWN, RED and ORANGE wires. + * Note: If the probe is not deploying, do a "Reset" and "Self-Test" and then check the + * wiring of the BROWN, RED and ORANGE wires. * * Note: If the trigger signal of your probe is not being recognized, it has been very often * because the BLACK and WHITE wires needed to be swapped. They are not "interchangeable" @@ -635,7 +704,7 @@ * Danger: Don't activate 5V mode unless attached to a 5V-tolerant controller! * V3.0 or 3.1: Set default mode to 5V mode at Marlin startup. * If disabled, OD mode is the hard-coded default on 3.0 - * On startup, Marlin will compare its eeprom to this vale. If the selected mode + * On startup, Marlin will compare its eeprom to this value. If the selected mode * differs, a mode set eeprom write will be completed at initialization. * Use the option below to force an eeprom write to a V3.1 probe regardless. */ @@ -662,6 +731,8 @@ #endif // BLTOUCH +// @section extras + /** * Z Steppers Auto-Alignment * Add the G34 command to align multiple Z steppers using a bed probe. @@ -691,7 +762,6 @@ * | 4 3 | 1 4 | 2 1 | 3 2 | * | | | | | * | 1 2 | 2 3 | 3 4 | 4 1 | - * */ #ifndef Z_STEPPER_ALIGN_XY //#define Z_STEPPERS_ORIENTATION 0 @@ -716,6 +786,38 @@ #define Z_STEPPER_ALIGN_ITERATIONS 5 // Number of iterations to apply during alignment #define Z_STEPPER_ALIGN_ACC 0.02 // Stop iterating early if the accuracy is better than this #define RESTORE_LEVELING_AFTER_G34 // Restore leveling after G34 is done? + // After G34, re-home Z (G28 Z) or just calculate it from the last probe heights? + // Re-homing might be more precise in reproducing the actual 'G28 Z' homing height, especially on an uneven bed. + #define HOME_AFTER_G34 +#endif + +// +// Add the G35 command to read bed corners to help adjust screws. Requires a bed probe. +// +//#define ASSISTED_TRAMMING +#if ENABLED(ASSISTED_TRAMMING) + + // Define positions for probing points, use the hotend as reference not the sensor. + #define TRAMMING_POINT_XY { { 20, 20 }, { 200, 20 }, { 200, 200 }, { 20, 200 } } + + // Define positions names for probing points. + #define TRAMMING_POINT_NAME_1 "Front-Left" + #define TRAMMING_POINT_NAME_2 "Front-Right" + #define TRAMMING_POINT_NAME_3 "Back-Right" + #define TRAMMING_POINT_NAME_4 "Back-Left" + + #define RESTORE_LEVELING_AFTER_G35 // Enable to restore leveling setup after operation + //#define REPORT_TRAMMING_MM // Report Z deviation (mm) for each point relative to the first + //#define ASSISTED_TRAMMING_MENU_ITEM // Add a menu item for Assisted Tramming + + /** + * Screw thread: + * M3: 30 = Clockwise, 31 = Counter-Clockwise + * M4: 40 = Clockwise, 41 = Counter-Clockwise + * M5: 50 = Clockwise, 51 = Counter-Clockwise + */ + #define TRAMMING_SCREW_THREAD 30 + #endif // @section motion @@ -731,30 +833,46 @@ #define INVERT_Z_STEP_PIN false #define INVERT_E_STEP_PIN false -// Default stepper release if idle. Set to 0 to deactivate. -// Steppers will shut down DEFAULT_STEPPER_DEACTIVE_TIME seconds after the last move when DISABLE_INACTIVE_? is true. -// Time can be set by M18 and M84. +/** + * Idle Stepper Shutdown + * Set DISABLE_INACTIVE_? 'true' to shut down axis steppers after an idle period. + * The Deactive Time can be overridden with M18 and M84. Set to 0 for No Timeout. + */ #define DEFAULT_STEPPER_DEACTIVE_TIME 120 #define DISABLE_INACTIVE_X true #define DISABLE_INACTIVE_Y true -#define DISABLE_INACTIVE_Z true // Set to false if the nozzle will fall down on your printed part when print has finished. +#define DISABLE_INACTIVE_Z true // Set 'false' if the nozzle could fall onto your printed part! #define DISABLE_INACTIVE_E true -#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate -#define DEFAULT_MINTRAVELFEEDRATE 0.0 +// If the Nozzle or Bed falls when the Z stepper is disabled, set its resting position here. +//#define Z_AFTER_DEACTIVATE Z_HOME_POS //#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated -// Minimum time that a segment needs to take if the buffer is emptied -#define DEFAULT_MINSEGMENTTIME 20000 // (ms) +// Default Minimum Feedrates for printing and travel moves +#define DEFAULT_MINIMUMFEEDRATE 0.0 // (mm/s) Minimum feedrate. Set with M205 S. +#define DEFAULT_MINTRAVELFEEDRATE 0.0 // (mm/s) Minimum travel feedrate. Set with M205 T. + +// Minimum time that a segment needs to take as the buffer gets emptied +#define DEFAULT_MINSEGMENTTIME 20000 // (µs) Set with M205 B. -// If defined the movements slow down when the look ahead buffer is only half full +// Slow down the machine if the lookahead buffer is (by default) half full. +// Increase the slowdown divisor for larger buffer sizes. #define SLOWDOWN +#if ENABLED(SLOWDOWN) + #define SLOWDOWN_DIVISOR 2 +#endif -// Frequency limit -// See nophead's blog for more info -// Not working O -//#define XY_FREQUENCY_LIMIT 15 +/** + * XY Frequency limit + * Reduce resonance by limiting the frequency of small zigzag infill moves. + * See https://hydraraptor.blogspot.com/2010/12/frequency-limit.html + * Use M201 F G to change limits at runtime. + */ +//#define XY_FREQUENCY_LIMIT 10 // (Hz) Maximum frequency of small zigzag infill moves. Set with M201 F. +#ifdef XY_FREQUENCY_LIMIT + #define XY_FREQUENCY_MIN_PERCENT 5 // (percent) Minimum FR percentage to apply. Set with M201 G. +#endif // Minimum planner junction speed. Sets the default minimum speed the planner plans for at the end // of the buffer and all stops. This should not be much greater than zero and should only be changed @@ -789,7 +907,7 @@ // increments while checking for the contact to be broken. #define BACKLASH_MEASUREMENT_LIMIT 0.5 // (mm) #define BACKLASH_MEASUREMENT_RESOLUTION 0.005 // (mm) - #define BACKLASH_MEASUREMENT_FEEDRATE Z_PROBE_SPEED_SLOW // (mm/m) + #define BACKLASH_MEASUREMENT_FEEDRATE Z_PROBE_SPEED_SLOW // (mm/min) #endif #endif #endif @@ -810,11 +928,14 @@ //#define CALIBRATION_GCODE #if ENABLED(CALIBRATION_GCODE) + //#define CALIBRATION_SCRIPT_PRE "M117 Starting Auto-Calibration\nT0\nG28\nG12\nM117 Calibrating..." + //#define CALIBRATION_SCRIPT_POST "M500\nM117 Calibration data saved" + #define CALIBRATION_MEASUREMENT_RESOLUTION 0.01 // mm - #define CALIBRATION_FEEDRATE_SLOW 60 // mm/m - #define CALIBRATION_FEEDRATE_FAST 1200 // mm/m - #define CALIBRATION_FEEDRATE_TRAVEL 3000 // mm/m + #define CALIBRATION_FEEDRATE_SLOW 60 // mm/min + #define CALIBRATION_FEEDRATE_FAST 1200 // mm/min + #define CALIBRATION_FEEDRATE_TRAVEL 3000 // mm/min // The following parameters refer to the conical section of the nozzle tip. #define CALIBRATION_NOZZLE_TIP_HEIGHT 1.0 // mm @@ -866,7 +987,7 @@ //#define MICROSTEP16 LOW,LOW,HIGH //#define MICROSTEP32 HIGH,LOW,HIGH -// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +// Microstep settings (Requires a board with pins named X_MS1, X_MS2, etc.) #define MICROSTEP_MODES { 16, 16, 16, 16, 16, 16 } // [1,2,4,8,16] /** @@ -893,9 +1014,20 @@ //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 } // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A) //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 } // Default drive percent - X, Y, Z, E axis -// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) -//#define DIGIPOT_I2C -#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) +/** + * I2C-based DIGIPOTs (e.g., Azteeg X3 Pro) + */ +//#define DIGIPOT_MCP4018 // Requires https://github.com/stawel/SlowSoftI2CMaster +//#define DIGIPOT_MCP4451 +#if EITHER(DIGIPOT_MCP4018, DIGIPOT_MCP4451) + #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT:4 AZTEEG_X3_PRO:8 MKS_SBASE:5 MIGHTYBOARD_REVE:5 + + // Actual motor currents in Amps. The number of entries must match DIGIPOT_I2C_NUM_CHANNELS. + // These correspond to the physical drivers, so be mindful if the order is changed. + #define DIGIPOT_I2C_MOTOR_CURRENTS { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 } // AZTEEG_X3_PRO + + //#define DIGIPOT_USE_RAW_VALUES // Use DIGIPOT_MOTOR_CURRENT raw wiper values (instead of A4988 motor currents) + /** * Common slave addresses: * @@ -906,16 +1038,10 @@ * AZTEEG_X5_MINI_WIFI 0x58 0x5C MCP4451 * MIGHTYBOARD_REVE 0x2F (0x5E) MCP4018 */ - #define DIGIPOT_I2C_ADDRESS_A 0x2C // unshifted slave address for first DIGIPOT - #define DIGIPOT_I2C_ADDRESS_B 0x2D // unshifted slave address for second DIGIPOT + //#define DIGIPOT_I2C_ADDRESS_A 0x2C // Unshifted slave address for first DIGIPOT + //#define DIGIPOT_I2C_ADDRESS_B 0x2D // Unshifted slave address for second DIGIPOT #endif -//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster -#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 MKS SBASE: 5 -// Actual motor currents in Amps. The number of entries must match DIGIPOT_I2C_NUM_CHANNELS. -// These correspond to the physical drivers, so be mindful if the order is changed. -#define DIGIPOT_I2C_MOTOR_CURRENTS { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 } // AZTEEG_X3_PRO - //=========================================================================== //=============================Additional Features=========================== //=========================================================================== @@ -923,7 +1049,7 @@ // @section lcd #if EITHER(ULTIPANEL, EXTENSIBLE_UI) - #define MANUAL_FEEDRATE { 50*60, 50*60, 4*60, 60 } // Feedrates for manual moves along X, Y, Z, E from panel + #define MANUAL_FEEDRATE { 50*60, 50*60, 4*60, 2*60 } // (mm/min) Feedrates for manual moves along X, Y, Z, E from panel #define SHORT_MANUAL_Z_MOVE 0.025 // (mm) Smallest manual Z move (< 0.1mm) #if ENABLED(ULTIPANEL) #define MANUAL_E_MOVES_RELATIVE // Display extruder move distance rather than "position" @@ -947,6 +1073,14 @@ #if HAS_LCD_MENU + // Add Probe Z Offset calibration to the Z Probe Offsets menu + #if HAS_BED_PROBE + //#define PROBE_OFFSET_WIZARD + #if ENABLED(PROBE_OFFSET_WIZARD) + #define PROBE_OFFSET_START -4.0 // Estimated nozzle-to-probe Z offset, plus a little extra + #endif + #endif + // Include a page of printer information in the LCD Main Menu //#define LCD_INFO_MENU #if ENABLED(LCD_INFO_MENU) @@ -963,6 +1097,7 @@ //#define LED_CONTROL_MENU #if ENABLED(LED_CONTROL_MENU) #define LED_COLOR_PRESETS // Enable the Preset Color menu option + //#define NEO2_COLOR_PRESETS // Enable a second NeoPixel Preset Color menu option #if ENABLED(LED_COLOR_PRESETS) #define LED_USER_PRESET_RED 255 // User defined RED value #define LED_USER_PRESET_GREEN 128 // User defined GREEN value @@ -971,6 +1106,14 @@ #define LED_USER_PRESET_BRIGHTNESS 255 // User defined intensity //#define LED_USER_PRESET_STARTUP // Have the printer display the user preset color on startup #endif + #if ENABLED(NEO2_COLOR_PRESETS) + #define NEO2_USER_PRESET_RED 255 // User defined RED value + #define NEO2_USER_PRESET_GREEN 128 // User defined GREEN value + #define NEO2_USER_PRESET_BLUE 0 // User defined BLUE value + #define NEO2_USER_PRESET_WHITE 255 // User defined WHITE value + #define NEO2_USER_PRESET_BRIGHTNESS 255 // User defined intensity + //#define NEO2_USER_PRESET_STARTUP // Have the printer display the user preset color on startup for the second strip + #endif #endif #endif // HAS_LCD_MENU @@ -990,37 +1133,45 @@ // Show the E position (filament used) during printing //#define LCD_SHOW_E_TOTAL -#if HAS_GRAPHICAL_LCD && HAS_PRINT_PROGRESS - //#define PRINT_PROGRESS_SHOW_DECIMALS // Show progress with decimal digits - //#define SHOW_REMAINING_TIME // Display estimated time to completion +#if ENABLED(SHOW_BOOTSCREEN) + #define BOOTSCREEN_TIMEOUT 4000 // (ms) Total Duration to display the boot screen(s) +#endif + +#if EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY) && ANY(HAS_MARLINUI_U8GLIB, HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL) + //#define SHOW_REMAINING_TIME // Display estimated time to completion #if ENABLED(SHOW_REMAINING_TIME) - //#define USE_M73_REMAINING_TIME // Use remaining time from M73 command instead of estimation - //#define ROTATE_PROGRESS_DISPLAY // Display (P)rogress, (E)lapsed, and (R)emaining time + //#define USE_M73_REMAINING_TIME // Use remaining time from M73 command instead of estimation + //#define ROTATE_PROGRESS_DISPLAY // Display (P)rogress, (E)lapsed, and (R)emaining time + #endif + + #if HAS_MARLINUI_U8GLIB + //#define PRINT_PROGRESS_SHOW_DECIMALS // Show progress with decimal digits #endif -#endif -#if HAS_CHARACTER_LCD && HAS_PRINT_PROGRESS - //#define LCD_PROGRESS_BAR // Show a progress bar on HD44780 LCDs for SD printing - #if ENABLED(LCD_PROGRESS_BAR) - #define PROGRESS_BAR_BAR_TIME 2000 // (ms) Amount of time to show the bar - #define PROGRESS_BAR_MSG_TIME 3000 // (ms) Amount of time to show the status message - #define PROGRESS_MSG_EXPIRE 0 // (ms) Amount of time to retain the status message (0=forever) - //#define PROGRESS_MSG_ONCE // Show the message for MSG_TIME then clear it - //#define LCD_PROGRESS_BAR_TEST // Add a menu item to test the progress bar + #if EITHER(HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL) + //#define LCD_PROGRESS_BAR // Show a progress bar on HD44780 LCDs for SD printing + #if ENABLED(LCD_PROGRESS_BAR) + #define PROGRESS_BAR_BAR_TIME 2000 // (ms) Amount of time to show the bar + #define PROGRESS_BAR_MSG_TIME 3000 // (ms) Amount of time to show the status message + #define PROGRESS_MSG_EXPIRE 0 // (ms) Amount of time to retain the status message (0=forever) + //#define PROGRESS_MSG_ONCE // Show the message for MSG_TIME then clear it + //#define LCD_PROGRESS_BAR_TEST // Add a menu item to test the progress bar + #endif #endif #endif #if ENABLED(SDSUPPORT) - // Some RAMPS and other boards don't detect when an SD card is inserted. You can work - // around this by connecting a push button or single throw switch to the pin defined - // as SD_DETECT_PIN in your board's pins definitions. - // This setting should be disabled unless you are using a push button, pulling the pin to ground. - // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). - #define SD_DETECT_INVERTED + // The standard SD detect circuit reads LOW when media is inserted and HIGH when empty. + // Enable this option and set to HIGH if your SD cards are incorrectly detected. + //#define SD_DETECT_STATE HIGH + + //#define SDCARD_READONLY // Read-only SD card (to save over 2K of flash) - #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished - #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the Z enabled so your bed stays in place. + #define SD_PROCEDURE_DEPTH 1 // Increase if you need more nested M32 calls + + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished + #define SD_FINISHED_RELEASECOMMAND "M84" // Use "M84XYE" to keep Z enabled so your bed stays in place // Reverse SD sort to show "more recent" files first, according to the card's FAT. // Since the FAT gets out of order with usage, SDCARD_SORT_ALPHA is recommended. @@ -1030,7 +1181,11 @@ //#define MENU_ADDAUTOSTART // Add a menu option to run auto#.g files - #define EVENT_GCODE_SD_STOP "G28XY" // G-code to run on Stop Print (e.g., "G28XY" or "G27") + #define EVENT_GCODE_SD_ABORT "G28XY" // G-code to run on SD Abort Print (e.g., "G28XY" or "G27") + + #if ENABLED(PRINTER_EVENT_LEDS) + #define PE_LEDS_COMPLETED_TIME (30*60) // (seconds) Time to keep the LED "done" color before restoring normal illumination + #endif /** * Continue after Power-Loss (Creality3D) @@ -1042,7 +1197,9 @@ */ //#define POWER_LOSS_RECOVERY #if ENABLED(POWER_LOSS_RECOVERY) + #define PLR_ENABLED_DEFAULT false // Power Loss Recovery enabled by default. (Set with 'M413 Sn' & M500) //#define BACKUP_POWER_SUPPLY // Backup power / UPS to move the steppers on power loss + //#define POWER_LOSS_RECOVER_ZHOME // Z homing is needed for proper recovery. 99.9% of the time this should be disabled! //#define POWER_LOSS_ZRAISE 2 // (mm) Z axis raise on resume (on power loss with UPS) //#define POWER_LOSS_PIN 44 // Pin to detect power loss. Set to -1 to disable default pin on boards without module. //#define POWER_LOSS_STATE HIGH // State of pin indicating power loss @@ -1084,7 +1241,7 @@ #if ENABLED(SDCARD_SORT_ALPHA) #define SDSORT_LIMIT 40 // Maximum number of sorted items (10-256). Costs 27 bytes each. #define FOLDER_SORTING -1 // -1=above 0=none 1=below - #define SDSORT_GCODE false // Allow turning sorting on/off with LCD and M34 g-code. + #define SDSORT_GCODE false // Allow turning sorting on/off with LCD and M34 G-code. #define SDSORT_USES_RAM false // Pre-allocate a static array for faster pre-sorting. #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. @@ -1203,11 +1360,12 @@ * controller events, as there is a trade-off between reliable * printing performance versus fast display updates. */ -#if HAS_GRAPHICAL_LCD +#if HAS_MARLINUI_U8GLIB // Show SD percentage next to the progress bar //#define DOGM_SD_PERCENT - // Enable to save many cycles by drawing a hollow frame on the Info Screen + // Save many cycles by drawing a hollow frame or no frame on the Info Screen + //#define XYZ_NO_FRAME #define XYZ_HOLLOW_FRAME // Enable to save many cycles by drawing a hollow frame on Menu Screens @@ -1217,14 +1375,10 @@ // Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese. //#define USE_BIG_EDIT_FONT - // A smaller font may be used on the Info Screen. Costs 2300 bytes of PROGMEM. + // A smaller font may be used on the Info Screen. Costs 2434 bytes of PROGMEM. // Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese. //#define USE_SMALL_INFOFONT - // Enable this option and reduce the value to optimize screen updates. - // The normal delay is 10µs. Use the lowest value that still gives a reliable display. - //#define DOGM_SPI_DELAY_US 5 - // Swap the CW/CCW indicators in the graphics overlay //#define OVERLAY_GFX_REVERSE @@ -1241,6 +1395,10 @@ * This will prevent position updates from being displayed. */ #if ENABLED(U8GLIB_ST7920) + // Enable this option and reduce the value to optimize screen updates. + // The normal delay is 10µs. Use the lowest value that still gives a reliable display. + //#define DOGM_SPI_DELAY_US 5 + //#define LIGHTWEIGHT_UI #if ENABLED(LIGHTWEIGHT_UI) #define STATUS_EXPIRE_SECONDS 20 @@ -1272,30 +1430,29 @@ //#define MARLIN_SNAKE //#define GAMES_EASTER_EGG // Add extra blank lines above the "Games" sub-menu -#endif // HAS_GRAPHICAL_LCD +#endif // HAS_MARLINUI_U8GLIB // // Additional options for DGUS / DWIN displays // #if HAS_DGUS_LCD - #define DGUS_SERIAL_PORT 2 - #define DGUS_BAUDRATE 115200 + #define LCD_SERIAL_PORT 3 + #define LCD_BAUDRATE 115200 #define DGUS_RX_BUFFER_SIZE 128 #define DGUS_TX_BUFFER_SIZE 48 - //#define DGUS_SERIAL_STATS_RX_BUFFER_OVERRUNS // Fix Rx overrun situation (Currently only for AVR) + //#define SERIAL_STATS_RX_BUFFER_OVERRUNS // Fix Rx overrun situation (Currently only for AVR) #define DGUS_UPDATE_INTERVAL_MS 500 // (ms) Interval between automatic screen updates - #define BOOTSCREEN_TIMEOUT 3000 // (ms) Duration to display the boot screen #if EITHER(DGUS_LCD_UI_FYSETC, DGUS_LCD_UI_HIPRECY) #define DGUS_PRINT_FILENAME // Display the filename during printing #define DGUS_PREHEAT_UI // Display a preheat screen during heatup #if ENABLED(DGUS_LCD_UI_FYSETC) - //#define DUGS_UI_MOVE_DIS_OPTION // Disabled by default for UI_FYSETC + //#define DGUS_UI_MOVE_DIS_OPTION // Disabled by default for UI_FYSETC #else - #define DUGS_UI_MOVE_DIS_OPTION // Enabled by default for UI_HIPRECY + #define DGUS_UI_MOVE_DIS_OPTION // Enabled by default for UI_HIPRECY #endif #define DGUS_FILAMENT_LOADUNLOAD @@ -1322,6 +1479,7 @@ //#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 + //#define LCD_FYSETC_TFT81050 // FYSETC with 5" (800x480) // Correct the resolution if not using the stock TFT panel. //#define TOUCH_UI_320x240 @@ -1329,10 +1487,11 @@ //#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 S6_TFT_PINMAP // FYSETC S6 pin mapping + //#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 S6_TFT_PINMAP // FYSETC S6 pin mapping + //#define F6_TFT_PINMAP // FYSETC F6 pin mapping //#define OTHER_PIN_LAYOUT // Define pins manually below #if ENABLED(OTHER_PIN_LAYOUT) @@ -1401,9 +1560,9 @@ #endif // -// FSMC Graphical TFT +// Classic UI Options // -#if ENABLED(FSMC_GRAPHICAL_TFT) +#if TFT_SCALED_DOGLCD //#define TFT_MARLINUI_COLOR 0xFFFF // White //#define TFT_MARLINBG_COLOR 0x0000 // Black //#define TFT_DISABLED_COLOR 0x0003 // Almost black @@ -1416,7 +1575,7 @@ // ADC Button Debounce // #if HAS_ADC_BUTTONS - #define ADC_BUTTON_DEBOUNCE_DELAY 16 // (ms) Increase if buttons bounce or repeat too fast + #define ADC_BUTTON_DEBOUNCE_DELAY 16 // Increase if buttons bounce or repeat too fast #endif // @section safety @@ -1448,16 +1607,17 @@ #if ENABLED(BABYSTEPPING) //#define INTEGRATED_BABYSTEPPING // EXPERIMENTAL integration of babystepping into the Stepper ISR //#define BABYSTEP_WITHOUT_HOMING + //#define BABYSTEP_ALWAYS_AVAILABLE // Allow babystepping at all times (not just during movement). //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR_Z 1 // Babysteps are very small. Increase for faster motion. - #define BABYSTEP_MULTIPLICATOR_XY 1 + //#define BABYSTEP_MILLIMETER_UNITS // Specify BABYSTEP_MULTIPLICATOR_(XY|Z) in mm instead of micro-steps + #define BABYSTEP_MULTIPLICATOR_Z 1 // (steps or mm) Steps or millimeter distance for each Z babystep + #define BABYSTEP_MULTIPLICATOR_XY 1 // (steps or mm) Steps or millimeter distance for each XY babystep //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #if ENABLED(DOUBLECLICK_FOR_Z_BABYSTEPPING) #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. - //#define BABYSTEP_ALWAYS_AVAILABLE // Allow babystepping at all times (not just during movement). //#define MOVE_Z_WHEN_IDLE // Jump to the move Z menu on doubleclick when printer is idle. #if ENABLED(MOVE_Z_WHEN_IDLE) #define MOVE_Z_IDLE_MULTIPLICATOR 1 // Multiply 1mm by this factor for the move step size. @@ -1488,14 +1648,14 @@ * If this algorithm produces a higher speed offset than the extruder can handle (compared to E jerk) * print acceleration will be reduced during the affected moves to keep within the limit. * - * See http://marlinfw.org/docs/features/lin_advance.html for full instructions. - * Mention @Sebastianv650 on GitHub to alert the author of any issues. + * See https://marlinfw.org/docs/features/lin_advance.html for full instructions. */ //#define LIN_ADVANCE #if ENABLED(LIN_ADVANCE) //#define EXTRA_LIN_ADVANCE_K // Enable for second linear advance constants #define LIN_ADVANCE_K 0.22 // Unit: mm compression per 1mm/s extruder speed //#define LA_DEBUG // If enabled, this will generate debug information output over USB. + //#define EXPERIMENTAL_SCURVE // Enable this option to permit S-Curve Acceleration #endif // @section leveling @@ -1514,7 +1674,9 @@ #endif /** - * Override MIN_PROBE_EDGE for each side of the build plate + * Probing Margins + * + * Override PROBING_MARGIN for each side of the build plate * Useful to get probe points to exact positions on targets or * to allow leveling to avoid plate clamps on only specific * sides of the bed. With NOZZLE_AS_PROBE negative values are @@ -1531,10 +1693,10 @@ * the probe to be unable to reach any points. */ #if PROBE_SELECTED && !IS_KINEMATIC - //#define MIN_PROBE_EDGE_LEFT MIN_PROBE_EDGE - //#define MIN_PROBE_EDGE_RIGHT MIN_PROBE_EDGE - //#define MIN_PROBE_EDGE_FRONT MIN_PROBE_EDGE - //#define MIN_PROBE_EDGE_BACK MIN_PROBE_EDGE + //#define PROBING_MARGIN_LEFT PROBING_MARGIN + //#define PROBING_MARGIN_RIGHT PROBING_MARGIN + //#define PROBING_MARGIN_FRONT PROBING_MARGIN + //#define PROBING_MARGIN_BACK PROBING_MARGIN #endif #if EITHER(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL) @@ -1576,22 +1738,46 @@ // Add additional compensation depending on hotend temperature // Note: this values cannot be calibrated and have to be set manually #if ENABLED(PROBE_TEMP_COMPENSATION) - // Max temperature that can be reached by heated bed. - // This is required only for the calibration process. - #define PTC_MAX_BED_TEMP 110 - // Park position to wait for probe cooldown - #define PTC_PARK_POS_X 0.0F - #define PTC_PARK_POS_Y 0.0F - #define PTC_PARK_POS_Z 100.0F + #define PTC_PARK_POS { 0, 0, 100 } // Probe position to probe and wait for probe to reach target temperature - #define PTC_PROBE_POS_X 90.0F - #define PTC_PROBE_POS_Y 100.0F + #define PTC_PROBE_POS { 90, 100 } // Enable additional compensation using hotend temperature // Note: this values cannot be calibrated automatically but have to be set manually //#define USE_TEMP_EXT_COMPENSATION + + // Probe temperature calibration generates a table of values starting at PTC_SAMPLE_START + // (e.g. 30), in steps of PTC_SAMPLE_RES (e.g. 5) with PTC_SAMPLE_COUNT (e.g. 10) samples. + + //#define PTC_SAMPLE_START 30.0f + //#define PTC_SAMPLE_RES 5.0f + //#define PTC_SAMPLE_COUNT 10U + + // Bed temperature calibration builds a similar table. + + //#define BTC_SAMPLE_START 60.0f + //#define BTC_SAMPLE_RES 5.0f + //#define BTC_SAMPLE_COUNT 10U + + // The temperature the probe should be at while taking measurements during bed temperature + // calibration. + //#define BTC_PROBE_TEMP 30.0f + + // Height above Z=0.0f to raise the nozzle. Lowering this can help the probe to heat faster. + // Note: the Z=0.0f offset is determined by the probe offset which can be set using M851. + //#define PTC_PROBE_HEATING_OFFSET 0.5f + + // Height to raise the Z-probe between heating and taking the next measurement. Some probes + // may fail to untrigger if they have been triggered for a long time, which can be solved by + // increasing the height the probe is raised to. + //#define PTC_PROBE_RAISE 15U + + // If the probe is outside of the defined range, use linear extrapolation using the closest + // point and the PTC_LINEAR_EXTRAPOLATION'th next point. E.g. if set to 4 it will use data[0] + // and data[4] to perform linear extrapolation for values below PTC_SAMPLE_START. + //#define PTC_LINEAR_EXTRAPOLATION 4 #endif #endif @@ -1614,11 +1800,22 @@ #define N_ARC_CORRECTION 25 // Number of interpolated segments between corrections //#define ARC_P_CIRCLES // Enable the 'P' parameter to specify complete circles //#define CNC_WORKSPACE_PLANES // Allow G2/G3 to operate in XY, ZX, or YZ planes + //#define SF_ARC_FIX // Enable only if using SkeinForge with "Arc Point" fillet procedure #endif // Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. //#define BEZIER_CURVE_SUPPORT +/** + * Direct Stepping + * + * Comparable to the method used by Klipper, G6 direct stepping significantly + * reduces motion calculations, increases top printing speeds, and results in + * less step aliasing by calculating all motions in advance. + * Preparing your G-code: https://github.com/colinrgodsey/step-daemon + */ +//#define DIRECT_STEPPING + /** * G38 Probe Target * @@ -1687,14 +1884,16 @@ //================================= Buffers ================================= //=========================================================================== -// @section hidden +// @section motion -// The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. -#if ENABLED(SDSUPPORT) - #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller +// The number of linear moves that can be in the planner at once. +// The value of BLOCK_BUFFER_SIZE must be a power of 2 (e.g. 8, 16, 32) +#if BOTH(SDSUPPORT, DIRECT_STEPPING) + #define BLOCK_BUFFER_SIZE 8 +#elif ENABLED(SDSUPPORT) + #define BLOCK_BUFFER_SIZE 16 #else - #define BLOCK_BUFFER_SIZE 16 // maximize block buffer + #define BLOCK_BUFFER_SIZE 16 #endif // @section serial @@ -1737,10 +1936,14 @@ //#define SERIAL_STATS_DROPPED_RX #endif -// Enable an emergency-command parser to intercept certain commands as they -// enter the serial receive buffer, so they cannot be blocked. -// Currently handles M108, M112, M410 -// Does not work on boards using AT90USB (USBCON) processors! +/** + * Emergency Command Parser + * + * Add a low-level parser to intercept certain commands as they + * enter the serial receive buffer, so they cannot be blocked. + * Currently handles M108, M112, M410, M876 + * NOTE: Not yet implemented for all platforms. + */ //#define EMERGENCY_PARSER // Bad Serial-connections can miss a received command by sending an 'ok' @@ -1756,6 +1959,9 @@ // This option inserts short delays between lines of serial output. #define SERIAL_OVERRUN_PROTECTION +// For serial echo, the number of digits after the decimal point +//#define SERIAL_FLOAT_PRECISION 4 + // @section extras /** @@ -1780,7 +1986,6 @@ * Be sure to turn off auto-retract during filament change. * * Note that M207 / M208 / M209 settings are saved to EEPROM. - * */ //#define FWRETRACT #if ENABLED(FWRETRACT) @@ -1806,21 +2011,57 @@ * Universal tool change settings. * Applies to all types of extruders except where explicitly noted. */ -#if EXTRUDERS > 1 +#if HAS_MULTI_EXTRUDER // Z raise distance for tool-change, as needed for some extruders - #define TOOLCHANGE_ZRAISE 2 // (mm) - //#define TOOLCHANGE_NO_RETURN // Never return to the previous position on tool-change + #define TOOLCHANGE_ZRAISE 2 // (mm) + //#define TOOLCHANGE_ZRAISE_BEFORE_RETRACT // Apply raise before swap retraction (if enabled) + //#define TOOLCHANGE_NO_RETURN // Never return to previous position on tool-change #if ENABLED(TOOLCHANGE_NO_RETURN) - //#define EVENT_GCODE_AFTER_TOOLCHANGE "G12X" // G-code to run after tool-change is complete + //#define EVENT_GCODE_AFTER_TOOLCHANGE "G12X" // Extra G-code to run after tool-change #endif - // Retract and prime filament on tool-change + /** + * Retract and prime filament on tool-change to reduce + * ooze and stringing and to get cleaner transitions. + */ //#define TOOLCHANGE_FILAMENT_SWAP #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) - #define TOOLCHANGE_FIL_SWAP_LENGTH 12 // (mm) - #define TOOLCHANGE_FIL_EXTRA_PRIME 2 // (mm) - #define TOOLCHANGE_FIL_SWAP_RETRACT_SPEED 3600 // (mm/m) - #define TOOLCHANGE_FIL_SWAP_PRIME_SPEED 3600 // (mm/m) + // Load / Unload + #define TOOLCHANGE_FS_LENGTH 12 // (mm) Load / Unload length + #define TOOLCHANGE_FS_EXTRA_RESUME_LENGTH 0 // (mm) Extra length for better restart, fine tune by LCD/Gcode) + #define TOOLCHANGE_FS_RETRACT_SPEED (50*60) // (mm/min) (Unloading) + #define TOOLCHANGE_FS_UNRETRACT_SPEED (25*60) // (mm/min) (On SINGLENOZZLE or Bowden loading must be slowed down) + + // Longer prime to clean out a SINGLENOZZLE + #define TOOLCHANGE_FS_EXTRA_PRIME 0 // (mm) Extra priming length + #define TOOLCHANGE_FS_PRIME_SPEED (4.6*60) // (mm/min) Extra priming feedrate + #define TOOLCHANGE_FS_WIPE_RETRACT 0 // (mm/min) Retract before cooling for less stringing, better wipe, etc. + + // Cool after prime to reduce stringing + #define TOOLCHANGE_FS_FAN -1 // Fan index or -1 to skip + #define TOOLCHANGE_FS_FAN_SPEED 255 // 0-255 + #define TOOLCHANGE_FS_FAN_TIME 10 // (seconds) + + // Swap uninitialized extruder with TOOLCHANGE_FS_PRIME_SPEED for all lengths (recover + prime) + // (May break filament if not retracted beforehand.) + //#define TOOLCHANGE_FS_INIT_BEFORE_SWAP + + // Prime on the first T0 (If other, TOOLCHANGE_FS_INIT_BEFORE_SWAP applied) + // Enable it (M217 V[0/1]) before printing, to avoid unwanted priming on host connect + //#define TOOLCHANGE_FS_PRIME_FIRST_USED + + /** + * Tool Change Migration + * This feature provides G-code and LCD options to switch tools mid-print. + * All applicable tool properties are migrated so the print can continue. + * Tools must be closely matching and other restrictions may apply. + * Useful to: + * - Change filament color without interruption + * - Switch spools automatically on filament runout + * - Switch to a different nozzle on an extruder jam + */ + #define TOOLCHANGE_MIGRATION_FEATURE + #endif /** @@ -1830,9 +2071,11 @@ //#define TOOLCHANGE_PARK #if ENABLED(TOOLCHANGE_PARK) #define TOOLCHANGE_PARK_XY { X_MIN_POS + 10, Y_MIN_POS + 10 } - #define TOOLCHANGE_PARK_XY_FEEDRATE 6000 // (mm/m) + #define TOOLCHANGE_PARK_XY_FEEDRATE 6000 // (mm/min) + //#define TOOLCHANGE_PARK_X_ONLY // X axis only move + //#define TOOLCHANGE_PARK_Y_ONLY // Y axis only move #endif -#endif +#endif // HAS_MULTI_EXTRUDER /** * Advanced Pause @@ -1883,7 +2126,7 @@ #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable for XYZ steppers to stay powered on during filament change. //#define PARK_HEAD_ON_PAUSE // Park the nozzle during pause and filament change. - //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change + //#define HOME_BEFORE_FILAMENT_CHANGE // If needed, home before parking for filament change //#define FILAMENT_LOAD_UNLOAD_GCODES // Add M701/M702 Load/Unload G-codes, plus Load/Unload in the LCD Prepare menu. //#define FILAMENT_UNLOAD_ALL_EXTRUDERS // Allow M702 to unload all extruders above a minimum target temp (as set by M302) @@ -2015,7 +2258,7 @@ * TMCStepper library is required to use TMC stepper drivers. * https://github.com/teemuatlut/TMCStepper */ -#if HAS_TRINAMIC +#if HAS_TRINAMIC_CONFIG #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 @@ -2224,7 +2467,8 @@ * CHOPPER_DEFAULT_19V * CHOPPER_DEFAULT_24V * CHOPPER_DEFAULT_36V - * CHOPPER_PRUSAMK3_24V // Imported parameters from the official Prusa firmware for MK3 (24V) + * CHOPPER_09STEP_24V // 0.9 degree steppers (24V) + * CHOPPER_PRUSAMK3_24V // Imported parameters from the official Průša firmware for MK3 (24V) * CHOPPER_MARLIN_119 // Old defaults from Marlin v1.1.9 * * Define you own with @@ -2233,11 +2477,11 @@ #define CHOPPER_TIMING CHOPPER_DEFAULT_12V /** - * Monitor Trinamic drivers for error conditions, - * like overtemperature and short to ground. - * In the case of overtemperature Marlin can decrease the driver current until error condition clears. + * Monitor Trinamic drivers + * for error conditions like overtemperature and short to ground. + * To manage over-temp Marlin can decrease the driver current until the error condition clears. * Other detected conditions can be used to stop the current print. - * Relevant g-codes: + * Relevant G-codes: * M906 - Set or get motor current in milliamps using axis codes X, Y, Z, E. Report values if no axis codes given. * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. @@ -2278,7 +2522,7 @@ #define E7_HYBRID_THRESHOLD 30 /** - * Use StallGuard2 to home / probe X, Y, Z. + * Use StallGuard to home / probe X, Y, Z. * * TMC2130, TMC2160, TMC2209, TMC2660, TMC5130, and TMC5160 only * Connect the stepper driver's DIAG1 pin to the X/Y endstop pin. @@ -2291,7 +2535,7 @@ * HIGHEST 255 -64 (Too sensitive => False positive) * LOWEST 0 63 (Too insensitive => No trigger) * - * It is recommended to set [XYZ]_HOME_BUMP_MM to 0. + * It is recommended to set HOMING_BUMP_MM to { 0, 0, 0 }. * * SPI_ENDSTOPS *** Beta feature! *** TMC2130 Only *** * Poll the driver through SPI to determine load when homing. @@ -2299,27 +2543,37 @@ * * IMPROVE_HOMING_RELIABILITY tunes acceleration and jerk when * homing and adds a guard period for endstop triggering. - */ - //#define SENSORLESS_HOMING // StallGuard capable drivers only - - /** - * Use StallGuard2 to probe the bed with the nozzle. * - * CAUTION: This could cause damage to machines that use a lead screw or threaded rod - * to move the Z axis. Take extreme care when attempting to enable this feature. + * Comment *_STALL_SENSITIVITY to disable sensorless homing for that axis. */ - //#define SENSORLESS_PROBING // StallGuard capable drivers only + //#define SENSORLESS_HOMING // StallGuard capable drivers only #if EITHER(SENSORLESS_HOMING, SENSORLESS_PROBING) // TMC2209: 0...255. TMC2130: -64...63 #define X_STALL_SENSITIVITY 8 #define X2_STALL_SENSITIVITY X_STALL_SENSITIVITY #define Y_STALL_SENSITIVITY 8 + #define Y2_STALL_SENSITIVITY Y_STALL_SENSITIVITY //#define Z_STALL_SENSITIVITY 8 + //#define Z2_STALL_SENSITIVITY Z_STALL_SENSITIVITY + //#define Z3_STALL_SENSITIVITY Z_STALL_SENSITIVITY + //#define Z4_STALL_SENSITIVITY Z_STALL_SENSITIVITY //#define SPI_ENDSTOPS // TMC2130 only //#define IMPROVE_HOMING_RELIABILITY #endif + /** + * TMC Homing stepper phase. + * + * Improve homing repeatability by homing to stepper coil's nearest absolute + * phase position. Trinamic drivers use a stepper phase table with 1024 values + * spanning 4 full steps with 256 positions each (ergo, 1024 positions). + * Full step positions (128, 384, 640, 896) have the highest holding torque. + * + * Values from 0..1023, -1 to disable homing phase for that axis. + */ + //#define TMC_HOME_PHASE { 896, 896, 896 } + /** * Beta feature! * Create a 50/50 square wave step pulse optimal for stepper drivers. @@ -2345,7 +2599,7 @@ */ #define TMC_ADV() { } -#endif // HAS_TRINAMIC +#endif // HAS_TRINAMIC_CONFIG // @section L64XX @@ -2520,7 +2774,7 @@ * Monitor L6470 drivers for error conditions like over temperature and over current. * In the case of over temperature Marlin can decrease the drive until the error condition clears. * Other detected conditions can be used to stop the current print. - * Relevant g-codes: + * Relevant G-codes: * M906 - I1/2/3/4/5 Set or get motor drive level using axis codes X, Y, Z, E. Report values if no axis codes given. * I not present or I0 or I1 - X, Y, Z or E0 * I2 - X2, Y2, Z2 or E1 @@ -2597,11 +2851,11 @@ //#define PHOTO_RETRACT_MM 6.5 // (mm) E retract/recover for the photo move (M240 R S) // Canon RC-1 or homebrew digital camera trigger - // Data from: http://www.doc-diy.net/photo/rc-1_hacked/ + // Data from: https://www.doc-diy.net/photo/rc-1_hacked/ //#define PHOTOGRAPH_PIN 23 // Canon Hack Development Kit - // http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ + // https://captain-slow.dk/2014/03/09/3d-printing-timelapses/ //#define CHDK_PIN 4 // Optional second move with delay to trigger the camera shutter @@ -2638,39 +2892,138 @@ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V * hardware PWM pin for the speed control and a pin for the rotation direction. * - * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details. + * See https://marlinfw.org/docs/configuration/laser_spindle.html for more config details. */ //#define SPINDLE_FEATURE //#define LASER_FEATURE #if EITHER(SPINDLE_FEATURE, LASER_FEATURE) - #define SPINDLE_LASER_ACTIVE_HIGH false // Set to "true" if the on/off function is active HIGH + #define SPINDLE_LASER_ACTIVE_STATE LOW // Set to "HIGH" if the on/off function is active HIGH #define SPINDLE_LASER_PWM true // Set to "true" if your controller supports setting the speed/power - #define SPINDLE_LASER_PWM_INVERT true // Set to "true" if the speed/power goes up when you want it to go slower - #define SPINDLE_LASER_POWERUP_DELAY 5000 // (ms) Delay to allow the spindle/laser to come up to speed/power - #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // (ms) Delay to allow the spindle to stop + #define SPINDLE_LASER_PWM_INVERT false // Set to "true" if the speed/power goes up when you want it to go slower + + #define SPINDLE_LASER_FREQUENCY 2500 // (Hz) Spindle/laser frequency (only on supported HALs: AVR and LPC) + + /** + * Speed / Power can be set ('M3 S') and displayed in terms of: + * - PWM255 (S0 - S255) + * - PERCENT (S0 - S100) + * - RPM (S0 - S50000) Best for use with a spindle + */ + #define CUTTER_POWER_UNIT PWM255 + + /** + * Relative Cutter Power + * Normally, 'M3 O' sets + * OCR power is relative to the range SPEED_POWER_MIN...SPEED_POWER_MAX. + * so input powers of 0...255 correspond to SPEED_POWER_MIN...SPEED_POWER_MAX + * instead of normal range (0 to SPEED_POWER_MAX). + * Best used with (e.g.) SuperPID router controller: S0 = 5,000 RPM and S255 = 30,000 RPM + */ + //#define CUTTER_POWER_RELATIVE // Set speed proportional to [SPEED_POWER_MIN...SPEED_POWER_MAX] #if ENABLED(SPINDLE_FEATURE) //#define SPINDLE_CHANGE_DIR // Enable if your spindle controller can change spindle direction #define SPINDLE_CHANGE_DIR_STOP // Enable if the spindle should stop before changing spin direction #define SPINDLE_INVERT_DIR false // Set to "true" if the spin direction is reversed + #define SPINDLE_LASER_POWERUP_DELAY 5000 // (ms) Delay to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // (ms) Delay to allow the spindle to stop + /** - * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * M3/M4 Power Equation * - * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT - * where PWM duty cycle varies from 0 to 255 + * Each tool uses different value ranges for speed / power control. + * These parameters are used to convert between tool power units and PWM. * - * set the following for your controller (ALL MUST BE SET) + * Speed/Power = (PWMDC / 255 * 100 - SPEED_POWER_INTERCEPT) / SPEED_POWER_SLOPE + * PWMDC = (spdpwr - SPEED_POWER_MIN) / (SPEED_POWER_MAX - SPEED_POWER_MIN) / SPEED_POWER_SLOPE */ - #define SPEED_POWER_SLOPE 118.4 - #define SPEED_POWER_INTERCEPT 0 - #define SPEED_POWER_MIN 5000 - #define SPEED_POWER_MAX 30000 // SuperPID router controller 0 - 30,000 RPM + #define SPEED_POWER_INTERCEPT 0 // (%) 0-100 i.e., Minimum power percentage + #define SPEED_POWER_MIN 5000 // (RPM) + #define SPEED_POWER_MAX 30000 // (RPM) SuperPID router controller 0 - 30,000 RPM + #define SPEED_POWER_STARTUP 25000 // (RPM) M3/M4 speed/power default (with no arguments) + #else - #define SPEED_POWER_SLOPE 0.3922 - #define SPEED_POWER_INTERCEPT 0 - #define SPEED_POWER_MIN 10 - #define SPEED_POWER_MAX 100 // 0-100% + + #define SPEED_POWER_INTERCEPT 0 // (%) 0-100 i.e., Minimum power percentage + #define SPEED_POWER_MIN 0 // (%) 0-100 + #define SPEED_POWER_MAX 100 // (%) 0-100 + #define SPEED_POWER_STARTUP 80 // (%) M3/M4 speed/power default (with no arguments) + + /** + * Enable inline laser power to be handled in the planner / stepper routines. + * Inline power is specified by the I (inline) flag in an M3 command (e.g., M3 S20 I) + * or by the 'S' parameter in G0/G1/G2/G3 moves (see LASER_MOVE_POWER). + * + * This allows the laser to keep in perfect sync with the planner and removes + * the powerup/down delay since lasers require negligible time. + */ + #define LASER_POWER_INLINE + + #if ENABLED(LASER_POWER_INLINE) + /** + * Scale the laser's power in proportion to the movement rate. + * + * - Sets the entry power proportional to the entry speed over the nominal speed. + * - Ramps the power up every N steps to approximate the speed trapezoid. + * - Due to the limited power resolution this is only approximate. + */ + #define LASER_POWER_INLINE_TRAPEZOID + + /** + * Continuously calculate the current power (nominal_power * current_rate / nominal_rate). + * Required for accurate power with non-trapezoidal acceleration (e.g., S_CURVE_ACCELERATION). + * This is a costly calculation so this option is discouraged on 8-bit AVR boards. + * + * LASER_POWER_INLINE_TRAPEZOID_CONT_PER defines how many step cycles there are between power updates. If your + * board isn't able to generate steps fast enough (and you are using LASER_POWER_INLINE_TRAPEZOID_CONT), increase this. + * Note that when this is zero it means it occurs every cycle; 1 means a delay wait one cycle then run, etc. + */ + //#define LASER_POWER_INLINE_TRAPEZOID_CONT + + /** + * Stepper iterations between power updates. Increase this value if the board + * can't keep up with the processing demands of LASER_POWER_INLINE_TRAPEZOID_CONT. + * Disable (or set to 0) to recalculate power on every stepper iteration. + */ + //#define LASER_POWER_INLINE_TRAPEZOID_CONT_PER 10 + + /** + * Include laser power in G0/G1/G2/G3/G5 commands with the 'S' parameter + */ + //#define LASER_MOVE_POWER + + #if ENABLED(LASER_MOVE_POWER) + // Turn off the laser on G0 moves with no power parameter. + // If a power parameter is provided, use that instead. + //#define LASER_MOVE_G0_OFF + + // Turn off the laser on G28 homing. + //#define LASER_MOVE_G28_OFF + #endif + + /** + * Inline flag inverted + * + * WARNING: M5 will NOT turn off the laser unless another move + * is done (so G-code files must end with 'M5 I'). + */ + //#define LASER_POWER_INLINE_INVERT + + /** + * Continuously apply inline power. ('M3 S3' == 'G1 S3' == 'M3 S3 I') + * + * The laser might do some weird things, so only enable this + * feature if you understand the implications. + */ + //#define LASER_POWER_INLINE_CONTINUOUS + + #else + + #define SPINDLE_LASER_POWERUP_DELAY 50 // (ms) Delay to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 50 // (ms) Delay to allow the spindle to stop + + #endif #endif #endif @@ -2722,6 +3075,24 @@ //#define FILAMENT_LCD_DISPLAY #endif +/** + * Power Monitor + * Monitor voltage (V) and/or current (A), and -when possible- power (W) + * + * Read and configure with M430 + * + * The current sensor feeds DC voltage (relative to the measured current) to an analog pin + * The voltage sensor feeds DC voltage (relative to the measured voltage) to an analog pin + */ +//#define POWER_MONITOR_CURRENT // Monitor the system current +//#define POWER_MONITOR_VOLTAGE // Monitor the system voltage +#if EITHER(POWER_MONITOR_CURRENT, POWER_MONITOR_VOLTAGE) + #define POWER_MONITOR_VOLTS_PER_AMP 0.05000 // Input voltage to the MCU analog pin per amp - DO NOT apply more than ADC_VREF! + #define POWER_MONITOR_CURRENT_OFFSET -1 // Offset value for current sensors with linear function output + #define POWER_MONITOR_VOLTS_PER_VOLT 0.11786 // Input voltage to the MCU analog pin per volt - DO NOT apply more than ADC_VREF! + #define POWER_MONITOR_FIXED_VOLTAGE 13.6 // Voltage for a current sensor with no voltage sensor (for power display) +#endif + /** * CNC Coordinate Systems * @@ -2739,6 +3110,9 @@ * Include capabilities in M115 output */ #define EXTENDED_CAPABILITIES_REPORT +#if ENABLED(EXTENDED_CAPABILITIES_REPORT) + //#define M115_GEOMETRY_REPORT +#endif /** * Expected Printer Check @@ -2758,9 +3132,21 @@ * Activate to make volumetric extrusion the default method, * with DEFAULT_NOMINAL_FILAMENT_DIA as the default diameter. * - * M200 D0 to disable, M200 Dn to set a new diameter. + * M200 D0 to disable, M200 Dn to set a new diameter (and enable volumetric). + * M200 S0/S1 to disable/enable volumetric extrusion. */ //#define VOLUMETRIC_DEFAULT_ON + + //#define VOLUMETRIC_EXTRUDER_LIMIT + #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) + /** + * Default volumetric extrusion limit in cubic mm per second (mm^3/sec). + * This factory setting applies to all extruders. + * Use 'M200 [T] L' to override and 'M502' to reset. + * A non-zero value activates Volume-based Extrusion Limiting. + */ + #define DEFAULT_VOLUMETRIC_EXTRUDER_LIMIT 0.00 // (mm^3/sec) + #endif #endif /** @@ -2772,6 +3158,13 @@ */ //#define NO_WORKSPACE_OFFSETS +// Extra options for the M114 "Current Position" report +//#define M114_DETAIL // Use 'M114` for details to check planner calculations +//#define M114_REALTIME // Real current position based on forward kinematics +//#define M114_LEGACY // M114 used to synchronize on every call. Enable if needed. + +//#define REPORT_FAN_CHANGE // Report the new fan speed when changed by M106 (and others) + /** * Set the number of proportional font spaces required to fill up a typical character space. * This can help to better align the output of commands like `G29 O` Mesh Output. @@ -2792,6 +3185,8 @@ //#define GCODE_CASE_INSENSITIVE // Accept G-code sent to the firmware in lowercase +//#define REPETIER_GCODE_M360 // Add commands originally from Repetier FW + /** * CNC G-code options * Support CNC-style G-code dialects used by laser cutters, drawing machine cams, etc. @@ -2802,7 +3197,7 @@ //#define GCODE_MOTION_MODES // Remember the motion mode (G0 G1 G2 G3 G5 G38.X) and apply for X Y Z E F, etc. // Enable and set a (default) feedrate for all G0 moves -//#define G0_FEEDRATE 3000 // (mm/m) +//#define G0_FEEDRATE 3000 // (mm/min) #ifdef G0_FEEDRATE //#define VARIABLE_G0_FEEDRATE // The G0 feedrate is set by F in G0 motion mode #endif @@ -2869,6 +3264,7 @@ //#define HOST_ACTION_COMMANDS #if ENABLED(HOST_ACTION_COMMANDS) //#define HOST_PROMPT_SUPPORT + //#define HOST_START_MENU_ITEM // Add a menu item that tells the host to start #endif /** @@ -2882,11 +3278,11 @@ * I2C position encoders for closed loop control. * Developed by Chris Barr at Aus3D. * - * Wiki: http://wiki.aus3d.com.au/Magnetic_Encoder + * Wiki: https://wiki.aus3d.com.au/Magnetic_Encoder * Github: https://github.com/Aus3D/MagneticEncoder * - * Supplier: http://aus3d.com.au/magnetic-encoder-module - * Alternative Supplier: http://reliabuild3d.com/ + * Supplier: https://aus3d.com.au/magnetic-encoder-module + * Alternative Supplier: https://reliabuild3d.com/ * * Reliabuild encoders have been modified to improve reliability. */ @@ -2976,6 +3372,26 @@ #define JOY_X_LIMITS { 5600, 8190-100, 8190+100, 10800 } // min, deadzone start, deadzone end, max #define JOY_Y_LIMITS { 5600, 8250-100, 8250+100, 11000 } #define JOY_Z_LIMITS { 4800, 8080-100, 8080+100, 11550 } + //#define JOYSTICK_DEBUG +#endif + +/** + * Mechanical Gantry Calibration + * Modern replacement for the Prusa TMC_Z_CALIBRATION. + * Adds capability to work with any adjustable current drivers. + * Implemented as G34 because M915 is deprecated. + */ +//#define MECHANICAL_GANTRY_CALIBRATION +#if ENABLED(MECHANICAL_GANTRY_CALIBRATION) + #define GANTRY_CALIBRATION_CURRENT 600 // Default calibration current in ma + #define GANTRY_CALIBRATION_EXTRA_HEIGHT 15 // Extra distance in mm past Z_###_POS to move + #define GANTRY_CALIBRATION_FEEDRATE 500 // Feedrate for correction move + //#define GANTRY_CALIBRATION_TO_MIN // Enable to calibrate Z in the MIN direction + + //#define GANTRY_CALIBRATION_SAFE_POSITION { X_CENTER, Y_CENTER } // Safe position for nozzle + //#define GANTRY_CALIBRATION_XY_PARK_FEEDRATE 3000 // XY Park Feedrate - MMM + //#define GANTRY_CALIBRATION_COMMANDS_PRE "" + #define GANTRY_CALIBRATION_COMMANDS_POST "G28" // G28 highly recommended to ensure an accurate position #endif /** @@ -2991,7 +3407,7 @@ #define MAX7219_LOAD_PIN 44 //#define MAX7219_GCODE // Add the M7219 G-code to control the LED matrix - #define MAX7219_INIT_TEST 2 // Do a test pattern at initialization (Set to 2 for spiral) + #define MAX7219_INIT_TEST 2 // Test pattern at startup: 0=none, 1=sweep, 2=spiral #define MAX7219_NUMBER_UNITS 1 // Number of Max7219 units in chain. #define MAX7219_ROTATE 0 // Rotate the display clockwise (in multiples of +/- 90°) // connector at: right=0 bottom=-90 top=90 left=180 @@ -3047,16 +3463,16 @@ #endif /** - * Prusa Multi-Material Unit v2 + * Průša Multi-Material Unit v2 * Enable in Configuration.h */ #if ENABLED(PRUSA_MMU2) // Serial port used for communication with MMU2. - // For AVR enable the UART port used for the MMU. (e.g., internalSerial) + // For AVR enable the UART port used for the MMU. (e.g., mmuSerial) // For 32-bit boards check your HAL for available serial ports. (e.g., Serial2) - #define INTERNAL_SERIAL_PORT 2 - #define MMU2_SERIAL internalSerial + #define MMU2_SERIAL_PORT 2 + #define MMU2_SERIAL mmuSerial // Use hardware reset for MMU if a pin is defined for it //#define MMU2_RST_PIN 23 @@ -3071,10 +3487,10 @@ //#define MMU2_MENUS #if ENABLED(MMU2_MENUS) // Settings for filament load / unload from the LCD menu. - // This is for Prusa MK3-style extruders. Customize for your hardware. + // This is for Průša MK3-style extruders. Customize for your hardware. #define MMU2_FILAMENTCHANGE_EJECT_FEED 80.0 #define MMU2_LOAD_TO_NOZZLE_SEQUENCE \ - { 7.2, 562 }, \ + { 7.2, 1145 }, \ { 14.4, 871 }, \ { 36.0, 1393 }, \ { 14.4, 871 }, \ @@ -3092,6 +3508,45 @@ { 10.0, 700 }, \ { -10.0, 400 }, \ { -50.0, 2000 } + #endif + + /** + * MMU Extruder Sensor + * + * Support for a Průša (or other) IR Sensor to detect filament near the extruder + * and make loading more reliable. Suitable for an extruder equipped with a filament + * sensor less than 38mm from the gears. + * + * During loading the extruder will stop when the sensor is triggered, then do a last + * move up to the gears. If no filament is detected, the MMU2 can make some more attempts. + * If all attempts fail, a filament runout will be triggered. + */ + //#define MMU_EXTRUDER_SENSOR + #if ENABLED(MMU_EXTRUDER_SENSOR) + #define MMU_LOADING_ATTEMPTS_NR 5 // max. number of attempts to load filament if first load fail + #endif + + /** + * Using a sensor like the MMU2S + * This mode requires a MK3S extruder with a sensor at the extruder idler, like the MMU2S. + * See https://help.prusa3d.com/en/guide/3b-mk3s-mk2-5s-extruder-upgrade_41560, step 11 + */ + //#define PRUSA_MMU2_S_MODE + #if ENABLED(PRUSA_MMU2_S_MODE) + #define MMU2_C0_RETRY 5 // Number of retries (total time = timeout*retries) + + #define MMU2_CAN_LOAD_FEEDRATE 800 // (mm/min) + #define MMU2_CAN_LOAD_SEQUENCE \ + { 0.1, MMU2_CAN_LOAD_FEEDRATE }, \ + { 60.0, MMU2_CAN_LOAD_FEEDRATE }, \ + { -52.0, MMU2_CAN_LOAD_FEEDRATE } + + #define MMU2_CAN_LOAD_RETRACT 6.0 // (mm) Keep under the distance between Load Sequence values + #define MMU2_CAN_LOAD_DEVIATION 0.8 // (mm) Acceptable deviation + + #define MMU2_CAN_LOAD_INCREMENT 0.2 // (mm) To reuse within MMU2 module + #define MMU2_CAN_LOAD_INCREMENT_SEQUENCE \ + { -MMU2_CAN_LOAD_INCREMENT, MMU2_CAN_LOAD_FEEDRATE } #endif @@ -3120,6 +3575,11 @@ // //#define M100_FREE_MEMORY_WATCHER +// +// M42 - Set pin states +// +//#define DIRECT_PIN_CONTROL + // // M43 - display pin status, toggle pins, watch pins, watch endstops & toggle LED, test servo probe // diff --git a/Marlin/Makefile b/Marlin/Makefile index fcd763881eef..49cb960b92fe 100644 --- a/Marlin/Makefile +++ b/Marlin/Makefile @@ -14,7 +14,7 @@ # Detailed instructions for using the makefile: # # 1. Modify the line containing "ARDUINO_INSTALL_DIR" to point to the directory that -# contains the Arduino installation (for example, under Mac OS X, this +# contains the Arduino installation (for example, under macOS, this # might be /Applications/Arduino.app/Contents/Resources/Java). # # 2. Modify the line containing "UPLOAD_PORT" to refer to the filename @@ -22,8 +22,10 @@ # (e.g. UPLOAD_PORT = /dev/tty.USB0). If the exact name of this file # changes, you can use * as a wild card (e.g. UPLOAD_PORT = /dev/tty.usb*). # -# 3. Set the line containing "MCU" to match your board's processor. -# Older one's are atmega8 based, newer ones like Arduino Mini, Bluetooth +# 3. Set the line containing "MCU" to match your board's processor. Set +# "PROG_MCU" as the AVR part name corresponding to "MCU". You can use the +# following command to get a list of correspondences: `avrdude -c alf -p x` +# Older boards are atmega8 based, newer ones like Arduino Mini, Bluetooth # or Diecimila have the atmega168. If you're using a LilyPad Arduino, # change F_CPU to 8000000. If you are using Gen7 electronics, you # probably need to use 20000000. Either way, you must regenerate @@ -34,18 +36,18 @@ # 5. Type "make upload", reset your Arduino board, and press enter to # upload your program to the Arduino board. # -# Note that all settings at the top of this file can be overriden from +# Note that all settings at the top of this file can be overridden from # the command line with, for example, "make HARDWARE_MOTHERBOARD=71" # # To compile for RAMPS (atmega2560) with Arduino 1.6.9 at root/arduino you would use... # # make ARDUINO_VERSION=10609 AVR_TOOLS_PATH=/root/arduino/hardware/tools/avr/bin/ \ -# HARDWARE_MOTHERBOARD=33 ARDUINO_INSTALL_DIR=/root/arduino +# HARDWARE_MOTHERBOARD=1200 ARDUINO_INSTALL_DIR=/root/arduino # # To compile and upload simply add "upload" to the end of the line... # # make ARDUINO_VERSION=10609 AVR_TOOLS_PATH=/root/arduino/hardware/tools/avr/bin/ \ -# HARDWARE_MOTHERBOARD=33 ARDUINO_INSTALL_DIR=/root/arduino upload +# HARDWARE_MOTHERBOARD=1200 ARDUINO_INSTALL_DIR=/root/arduino upload # # If uploading doesn't work try adding the parameter "AVRDUDE_PROGRAMMER=wiring" or # start upload manually (using stk500) like so: @@ -57,7 +59,26 @@ # # This defines the board to compile for (see boards.h for your board's ID) -HARDWARE_MOTHERBOARD ?= 11 +HARDWARE_MOTHERBOARD ?= 1020 + +ifeq ($(OS),Windows_NT) + # Windows + ARDUINO_INSTALL_DIR ?= ${HOME}/Arduino + ARDUINO_USER_DIR ?= ${HOME}/Arduino +else + UNAME_S := $(shell uname -s) + ifeq ($(UNAME_S),Linux) + # Linux + ARDUINO_INSTALL_DIR ?= /usr/share/arduino + ARDUINO_USER_DIR ?= ${HOME}/Arduino + endif + ifeq ($(UNAME_S),Darwin) + # Darwin (macOS) + ARDUINO_INSTALL_DIR ?= /Applications/Arduino.app/Contents/Java + ARDUINO_USER_DIR ?= ${HOME}/Documents/Arduino + AVR_TOOLS_PATH ?= /Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/ + endif +endif # Arduino source install directory, and version number # On most linuxes this will be /usr/share/arduino @@ -67,38 +88,44 @@ ARDUINO_VERSION ?= 106 # The installed Libraries are in the User folder ARDUINO_USER_DIR ?= ${HOME}/Arduino -# You can optionally set a path to the avr-gcc tools. Requires a trailing slash. (ex: /usr/local/avr-gcc/bin) +# You can optionally set a path to the avr-gcc tools. +# Requires a trailing slash. For example, /usr/local/avr-gcc/bin/ AVR_TOOLS_PATH ?= -#Programmer configuration +# Programmer configuration UPLOAD_RATE ?= 57600 AVRDUDE_PROGRAMMER ?= arduino -# on most linuxes this will be /dev/ttyACM0 or /dev/ttyACM1 +# On most linuxes this will be /dev/ttyACM0 or /dev/ttyACM1 UPLOAD_PORT ?= /dev/ttyUSB0 -#Directory used to build files in, contains all the build files, from object files to the final hex file -#on linux it is best to put an absolute path like /home/username/tmp . +# Directory used to build files in, contains all the build files, from object +# files to the final hex file on linux it is best to put an absolute path +# like /home/username/tmp . BUILD_DIR ?= applet # This defines whether Liquid_TWI2 support will be built LIQUID_TWI2 ?= 0 -# this defines if Wire is needed +# This defines if Wire is needed WIRE ?= 0 -# this defines if U8GLIB is needed (may require RELOC_WORKAROUND) -U8GLIB ?= 1 +# This defines if Tone is needed (i.e SPEAKER is defined in Configuration.h) +# Disabling this (and SPEAKER) saves approximatively 350 bytes of memory. +TONE ?= 1 + +# This defines if U8GLIB is needed (may require RELOC_WORKAROUND) +U8GLIB ?= 0 -# this defines whether to include the Trinamic TMCStepper library -TMC ?= 1 +# This defines whether to include the Trinamic TMCStepper library +TMC ?= 0 -# this defines whether to include the AdaFruit NeoPixel library +# This defines whether to include the AdaFruit NeoPixel library NEOPIXEL ?= 0 ############ # Try to automatically determine whether RELOC_WORKAROUND is needed based # on GCC versions: -# http://www.avrfreaks.net/comment/1789106#comment-1789106 +# https://www.avrfreaks.net/comment/1789106#comment-1789106 CC_MAJ:=$(shell $(CC) -dM -E - < /dev/null | grep __GNUC__ | cut -f3 -d\ ) CC_MIN:=$(shell $(CC) -dM -E - < /dev/null | grep __GNUC_MINOR__ | cut -f3 -d\ ) @@ -170,103 +197,115 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1100) else ifeq ($(HARDWARE_MOTHERBOARD),1101) # Velleman K8400 Controller (derived from 3Drag Controller) else ifeq ($(HARDWARE_MOTHERBOARD),1102) -# 2PrintBeta BAM&DICE with STK drivers +# Velleman K8600 Controller (Vertex Nano) else ifeq ($(HARDWARE_MOTHERBOARD),1103) -# 2PrintBeta BAM&DICE Due with STK drivers +# Velleman K8800 Controller (Vertex Delta) else ifeq ($(HARDWARE_MOTHERBOARD),1104) -# MKS BASE v1.0 +# 2PrintBeta BAM&DICE with STK drivers else ifeq ($(HARDWARE_MOTHERBOARD),1105) -# MKS v1.4 with A4982 stepper drivers +# 2PrintBeta BAM&DICE Due with STK drivers else ifeq ($(HARDWARE_MOTHERBOARD),1106) -# MKS v1.5 with Allegro A4982 stepper drivers +# MKS BASE v1.0 else ifeq ($(HARDWARE_MOTHERBOARD),1107) -# MKS v1.6 with Allegro A4982 stepper drivers +# MKS v1.4 with A4982 stepper drivers else ifeq ($(HARDWARE_MOTHERBOARD),1108) - -# MKS BASE 1.0 with Heroic HR4982 stepper drivers +# MKS v1.5 with Allegro A4982 stepper drivers else ifeq ($(HARDWARE_MOTHERBOARD),1109) -# MKS GEN v1.3 or 1.4 +# MKS v1.6 with Allegro A4982 stepper drivers else ifeq ($(HARDWARE_MOTHERBOARD),1110) -# MKS GEN L +# MKS BASE 1.0 with Heroic HR4982 stepper drivers else ifeq ($(HARDWARE_MOTHERBOARD),1111) -# zrib V2.0 control board (Chinese knock off RAMPS replica) +# MKS GEN v1.3 or 1.4 else ifeq ($(HARDWARE_MOTHERBOARD),1112) -# BigTreeTech or BIQU KFB2.0 +# MKS GEN L else ifeq ($(HARDWARE_MOTHERBOARD),1113) -# Felix 2.0+ Electronics Board (RAMPS like) +# zrib V2.0 control board (Chinese knock off RAMPS replica) else ifeq ($(HARDWARE_MOTHERBOARD),1114) -# Invent-A-Part RigidBoard +# BigTreeTech or BIQU KFB2.0 else ifeq ($(HARDWARE_MOTHERBOARD),1115) -# Invent-A-Part RigidBoard V2 +# Felix 2.0+ Electronics Board (RAMPS like) else ifeq ($(HARDWARE_MOTHERBOARD),1116) -# Sainsmart 2-in-1 board +# Invent-A-Part RigidBoard else ifeq ($(HARDWARE_MOTHERBOARD),1117) -# Ultimaker +# Invent-A-Part RigidBoard V2 else ifeq ($(HARDWARE_MOTHERBOARD),1118) -# Ultimaker (Older electronics. Pre 1.5.4. This is rare) +# Sainsmart 2-in-1 board else ifeq ($(HARDWARE_MOTHERBOARD),1119) - MCU ?= atmega1280 +# Ultimaker +else ifeq ($(HARDWARE_MOTHERBOARD),1120) +# Ultimaker (Older electronics. Pre 1.5.4. This is rare) +else ifeq ($(HARDWARE_MOTHERBOARD),1121) + MCU ?= atmega1280 + PROG_MCU ?= m1280 # Azteeg X3 -else ifeq ($(HARDWARE_MOTHERBOARD),1120) +else ifeq ($(HARDWARE_MOTHERBOARD),1122) # Azteeg X3 Pro -else ifeq ($(HARDWARE_MOTHERBOARD),1121) +else ifeq ($(HARDWARE_MOTHERBOARD),1123) # Ultimainboard 2.x (Uses TEMP_SENSOR 20) -else ifeq ($(HARDWARE_MOTHERBOARD),1122) +else ifeq ($(HARDWARE_MOTHERBOARD),1124) # Rumba -else ifeq ($(HARDWARE_MOTHERBOARD),1123) +else ifeq ($(HARDWARE_MOTHERBOARD),1125) # Raise3D Rumba -else ifeq ($(HARDWARE_MOTHERBOARD),1124) +else ifeq ($(HARDWARE_MOTHERBOARD),1126) # Rapide Lite RL200 Rumba -else ifeq ($(HARDWARE_MOTHERBOARD),1125) +else ifeq ($(HARDWARE_MOTHERBOARD),1127) # Formbot T-Rex 2 Plus -else ifeq ($(HARDWARE_MOTHERBOARD),1126) +else ifeq ($(HARDWARE_MOTHERBOARD),1128) # Formbot T-Rex 3 -else ifeq ($(HARDWARE_MOTHERBOARD),1127) +else ifeq ($(HARDWARE_MOTHERBOARD),1129) # Formbot Raptor -else ifeq ($(HARDWARE_MOTHERBOARD),1128) +else ifeq ($(HARDWARE_MOTHERBOARD),1130) # Formbot Raptor 2 -else ifeq ($(HARDWARE_MOTHERBOARD),1129) +else ifeq ($(HARDWARE_MOTHERBOARD),1131) # bq ZUM Mega 3D -else ifeq ($(HARDWARE_MOTHERBOARD),1130) +else ifeq ($(HARDWARE_MOTHERBOARD),1132) # MakeBoard Mini v2.1.2 is a control board sold by MicroMake -else ifeq ($(HARDWARE_MOTHERBOARD),1131) +else ifeq ($(HARDWARE_MOTHERBOARD),1133) # TriGorilla Anycubic version 1.3 based on RAMPS EFB -else ifeq ($(HARDWARE_MOTHERBOARD),1132) +else ifeq ($(HARDWARE_MOTHERBOARD),1134) # TriGorilla Anycubic version 1.4 based on RAMPS EFB -else ifeq ($(HARDWARE_MOTHERBOARD),1133) +else ifeq ($(HARDWARE_MOTHERBOARD),1135) # TriGorilla Anycubic version 1.4 Rev 1.1 -else ifeq ($(HARDWARE_MOTHERBOARD),1134) +else ifeq ($(HARDWARE_MOTHERBOARD),1136) # Creality: Ender-4, CR-8 -else ifeq ($(HARDWARE_MOTHERBOARD),1135) +else ifeq ($(HARDWARE_MOTHERBOARD),1137) # Creality: CR10S, CR20, CR-X -else ifeq ($(HARDWARE_MOTHERBOARD),1136) +else ifeq ($(HARDWARE_MOTHERBOARD),1138) # Dagoma F5 -else ifeq ($(HARDWARE_MOTHERBOARD),1137) +else ifeq ($(HARDWARE_MOTHERBOARD),1139) # FYSETC F6 1.3 -else ifeq ($(HARDWARE_MOTHERBOARD),1138) +else ifeq ($(HARDWARE_MOTHERBOARD),1140) # FYSETC F6 1.5 -else ifeq ($(HARDWARE_MOTHERBOARD),1139) +else ifeq ($(HARDWARE_MOTHERBOARD),1141) # Duplicator i3 Plus -else ifeq ($(HARDWARE_MOTHERBOARD),1140) +else ifeq ($(HARDWARE_MOTHERBOARD),1142) # VORON -else ifeq ($(HARDWARE_MOTHERBOARD),1141) +else ifeq ($(HARDWARE_MOTHERBOARD),1143) # TRONXY V3 1.0 -else ifeq ($(HARDWARE_MOTHERBOARD),1142) +else ifeq ($(HARDWARE_MOTHERBOARD),1144) # Z-Bolt X Series -else ifeq ($(HARDWARE_MOTHERBOARD),1143) +else ifeq ($(HARDWARE_MOTHERBOARD),1145) # TT OSCAR -else ifeq ($(HARDWARE_MOTHERBOARD),1144) +else ifeq ($(HARDWARE_MOTHERBOARD),1146) # Overlord/Overlord Pro -else ifeq ($(HARDWARE_MOTHERBOARD),1145) +else ifeq ($(HARDWARE_MOTHERBOARD),1147) # ADIMLab Gantry v1 -else ifeq ($(HARDWARE_MOTHERBOARD),1146) +else ifeq ($(HARDWARE_MOTHERBOARD),1148) # ADIMLab Gantry v2 -else ifeq ($(HARDWARE_MOTHERBOARD),1147) +else ifeq ($(HARDWARE_MOTHERBOARD),1149) # BIQU Tango V1 -else ifeq ($(HARDWARE_MOTHERBOARD),1148) +else ifeq ($(HARDWARE_MOTHERBOARD),1150) # MKS GEN L V2 -else ifeq ($(HARDWARE_MOTHERBOARD),1149) +else ifeq ($(HARDWARE_MOTHERBOARD),1151) +# MKS GEN L V2.1 +else ifeq ($(HARDWARE_MOTHERBOARD),1152) +# Copymaster 3D +else ifeq ($(HARDWARE_MOTHERBOARD),1153) +# Ortur 4 +else ifeq ($(HARDWARE_MOTHERBOARD),1154) +# Tenlog D3 Hero +else ifeq ($(HARDWARE_MOTHERBOARD),1155) # # RAMBo and derivatives @@ -339,9 +378,11 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1320) # Minitronics v1.0/1.1 else ifeq ($(HARDWARE_MOTHERBOARD),1400) MCU ?= atmega1281 + PROG_MCU ?= m1281 # Silvergate v1.0 else ifeq ($(HARDWARE_MOTHERBOARD),1401) MCU ?= atmega1281 + PROG_MCU ?= m1281 # # Sanguinololu and Derivatives - ATmega644P, ATmega1284P @@ -351,42 +392,57 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1401) else ifeq ($(HARDWARE_MOTHERBOARD),1500) HARDWARE_VARIANT ?= Sanguino MCU ?= atmega644p + PROG_MCU ?= m644p # Sanguinololu 1.2 and above else ifeq ($(HARDWARE_MOTHERBOARD),1501) HARDWARE_VARIANT ?= Sanguino MCU ?= atmega644p + PROG_MCU ?= m644p # Melzi else ifeq ($(HARDWARE_MOTHERBOARD),1502) HARDWARE_VARIANT ?= Sanguino MCU ?= atmega644p -# Melzi with ATmega1284 (MaKr3d version) + PROG_MCU ?= m644p +# Melzi V2.0 else ifeq ($(HARDWARE_MOTHERBOARD),1503) HARDWARE_VARIANT ?= Sanguino MCU ?= atmega1284p -# Melzi Creality3D board (for CR-10 etc) + PROG_MCU ?= m1284p +# Melzi with ATmega1284 (MaKr3d version) else ifeq ($(HARDWARE_MOTHERBOARD),1504) HARDWARE_VARIANT ?= Sanguino MCU ?= atmega1284p -# Melzi Malyan M150 board + PROG_MCU ?= m1284p +# Melzi Creality3D board (for CR-10 etc) else ifeq ($(HARDWARE_MOTHERBOARD),1505) HARDWARE_VARIANT ?= Sanguino MCU ?= atmega1284p -# Tronxy X5S + PROG_MCU ?= m1284p +# Melzi Malyan M150 board else ifeq ($(HARDWARE_MOTHERBOARD),1506) HARDWARE_VARIANT ?= Sanguino MCU ?= atmega1284p -# STB V1.1 + PROG_MCU ?= m1284p +# Tronxy X5S else ifeq ($(HARDWARE_MOTHERBOARD),1507) HARDWARE_VARIANT ?= Sanguino MCU ?= atmega1284p -# Azteeg X1 + PROG_MCU ?= m1284p +# STB V1.1 else ifeq ($(HARDWARE_MOTHERBOARD),1508) HARDWARE_VARIANT ?= Sanguino MCU ?= atmega1284p -# Anet 1.0 (Melzi clone) + PROG_MCU ?= m1284p +# Azteeg X1 else ifeq ($(HARDWARE_MOTHERBOARD),1509) HARDWARE_VARIANT ?= Sanguino MCU ?= atmega1284p + PROG_MCU ?= m1284p +# Anet 1.0 (Melzi clone) +else ifeq ($(HARDWARE_MOTHERBOARD),1510) + HARDWARE_VARIANT ?= Sanguino + MCU ?= atmega1284p + PROG_MCU ?= m1284p # # Other ATmega644P, ATmega644, ATmega1284P @@ -396,50 +452,61 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1509) else ifeq ($(HARDWARE_MOTHERBOARD),1600) HARDWARE_VARIANT ?= Sanguino MCU ?= atmega644p + PROG_MCU ?= m644p # Gen3+ else ifeq ($(HARDWARE_MOTHERBOARD),1601) HARDWARE_VARIANT ?= Sanguino MCU ?= atmega644p + PROG_MCU ?= m644p # Gen6 else ifeq ($(HARDWARE_MOTHERBOARD),1602) HARDWARE_VARIANT ?= Gen6 MCU ?= atmega644p + PROG_MCU ?= m644p # Gen6 deluxe else ifeq ($(HARDWARE_MOTHERBOARD),1603) HARDWARE_VARIANT ?= Gen6 MCU ?= atmega644p + PROG_MCU ?= m644p # Gen7 custom (Alfons3 Version) else ifeq ($(HARDWARE_MOTHERBOARD),1604) HARDWARE_VARIANT ?= Gen7 MCU ?= atmega644 + PROG_MCU ?= m644 F_CPU ?= 20000000 # Gen7 v1.1, v1.2 else ifeq ($(HARDWARE_MOTHERBOARD),1605) HARDWARE_VARIANT ?= Gen7 MCU ?= atmega644p + PROG_MCU ?= m644p F_CPU ?= 20000000 # Gen7 v1.3 else ifeq ($(HARDWARE_MOTHERBOARD),1606) HARDWARE_VARIANT ?= Gen7 MCU ?= atmega644p + PROG_MCU ?= m644p F_CPU ?= 20000000 # Gen7 v1.4 else ifeq ($(HARDWARE_MOTHERBOARD),1607) HARDWARE_VARIANT ?= Gen7 MCU ?= atmega1284p + PROG_MCU ?= m1284p F_CPU ?= 20000000 # Alpha OMCA board else ifeq ($(HARDWARE_MOTHERBOARD),1608) HARDWARE_VARIANT ?= SanguinoA MCU ?= atmega644 + PROG_MCU ?= m644 # Final OMCA board else ifeq ($(HARDWARE_MOTHERBOARD),1609) HARDWARE_VARIANT ?= Sanguino MCU ?= atmega644p + PROG_MCU ?= m644p # Sethi 3D_1 else ifeq ($(HARDWARE_MOTHERBOARD),1610) HARDWARE_VARIANT ?= Sanguino MCU ?= atmega644p + PROG_MCU ?= m644p # # Teensyduino - AT90USB1286, AT90USB1286P @@ -449,51 +516,60 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1610) else ifeq ($(HARDWARE_MOTHERBOARD),1700) HARDWARE_VARIANT ?= Teensy MCU ?= at90usb1286 + PROG_MCU ?= usb1286 # Printrboard (AT90USB1286) else ifeq ($(HARDWARE_MOTHERBOARD),1701) HARDWARE_VARIANT ?= Teensy MCU ?= at90usb1286 + PROG_MCU ?= usb1286 # Printrboard Revision F (AT90USB1286) else ifeq ($(HARDWARE_MOTHERBOARD),1702) HARDWARE_VARIANT ?= Teensy MCU ?= at90usb1286 + PROG_MCU ?= usb1286 # Brainwave (AT90USB646) else ifeq ($(HARDWARE_MOTHERBOARD),1703) HARDWARE_VARIANT ?= Teensy MCU ?= at90usb646 + PROG_MCU ?= usb646 # Brainwave Pro (AT90USB1286) else ifeq ($(HARDWARE_MOTHERBOARD),1704) HARDWARE_VARIANT ?= Teensy MCU ?= at90usb1286 + PROG_MCU ?= usb1286 # SAV Mk-I (AT90USB1286) else ifeq ($(HARDWARE_MOTHERBOARD),1705) HARDWARE_VARIANT ?= Teensy MCU ?= at90usb1286 + PROG_MCU ?= usb1286 # Teensy++2.0 (AT90USB1286) else ifeq ($(HARDWARE_MOTHERBOARD),1706) HARDWARE_VARIANT ?= Teensy MCU ?= at90usb1286 + PROG_MCU ?= usb1286 # 5DPrint D8 Driver Board else ifeq ($(HARDWARE_MOTHERBOARD),1707) HARDWARE_VARIANT ?= Teensy MCU ?= at90usb1286 + PROG_MCU ?= usb1286 # UltiMachine Archim1 (with DRV8825 drivers) else ifeq ($(HARDWARE_MOTHERBOARD),3023) HARDWARE_VARIANT ?= archim MCPU = cortex-m3 - F_CPU = 84000000L + F_CPU = 84000000 IS_MCU = 0 # UltiMachine Archim2 (with TMC2130 drivers) else ifeq ($(HARDWARE_MOTHERBOARD),3024) HARDWARE_VARIANT ?= archim MCPU = cortex-m3 - F_CPU = 84000000L + F_CPU = 84000000 IS_MCU = 0 endif # Be sure to regenerate speed_lookuptable.h with create_speed_lookuptable.py # if you are setting this to something other than 16MHz +# Do not put the UL suffix, it's done later on. # Set to 16Mhz if not yet set. F_CPU ?= 16000000 @@ -503,7 +579,8 @@ IS_MCU ?= 1 ifeq ($(IS_MCU),1) # Set to arduino, ATmega2560 if not yet set. HARDWARE_VARIANT ?= arduino - MCU ?= atmega2560 + MCU ?= atmega2560 + PROG_MCU ?= m2560 TOOL_PREFIX = avr MCU_FLAGS = -mmcu=$(MCU) @@ -534,27 +611,36 @@ VPATH += $(BUILD_DIR) VPATH += $(HARDWARE_SRC) ifeq ($(HARDWARE_VARIANT), $(filter $(HARDWARE_VARIANT),arduino Teensy Sanguino)) -VPATH += $(ARDUINO_INSTALL_DIR)/hardware/marlin/avr/libraries/LiquidCrystal/src -VPATH += $(ARDUINO_INSTALL_DIR)/hardware/marlin/avr/libraries/SPI + # Old libraries (avr-core 1.6.21 < / Arduino < 1.6.8) + VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI + # New libraries (avr-core >= 1.6.21 / Arduino >= 1.6.8) + VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI/src endif ifeq ($(IS_MCU),1) VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/cores/arduino + # Old libraries (avr-core 1.6.21 < / Arduino < 1.6.8) VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI + VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SoftwareSerial + # New libraries (avr-core >= 1.6.21 / Arduino >= 1.6.8) VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI/src VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SoftwareSerial/src endif VPATH += $(ARDUINO_INSTALL_DIR)/libraries/LiquidCrystal/src + ifeq ($(LIQUID_TWI2), 1) -VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire -VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire/utility -VPATH += $(ARDUINO_INSTALL_DIR)/libraries/LiquidTWI2 + WIRE = 1 + VPATH += $(ARDUINO_INSTALL_DIR)/libraries/LiquidTWI2 endif ifeq ($(WIRE), 1) -VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire -VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire/utility + # Old libraries (avr-core 1.6.21 / Arduino < 1.6.8) + VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/Wire + VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/Wire/utility + # New libraries (avr-core >= 1.6.21 / Arduino >= 1.6.8) + VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/Wire/src + VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/Wire/src/utility endif ifeq ($(NEOPIXEL), 1) VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Adafruit_NeoPixel @@ -626,13 +712,23 @@ ifeq ($(WIRE), 1) LIB_CXXSRC += Wire.cpp endif +ifeq ($(TONE), 1) + LIB_CXXSRC += Tone.cpp +endif + ifeq ($(U8GLIB), 1) LIB_CXXSRC += U8glib.cpp - LIB_SRC += u8g_ll_api.c u8g_bitmap.c u8g_clip.c u8g_com_null.c u8g_delay.c u8g_page.c u8g_pb.c u8g_pb16h1.c u8g_rect.c u8g_state.c u8g_font.c u8g_font_6x13.c u8g_font_04b_03.c u8g_font_5x8.c + LIB_SRC += u8g_ll_api.c u8g_bitmap.c u8g_clip.c u8g_com_null.c u8g_delay.c \ + u8g_page.c u8g_pb.c u8g_pb16h1.c u8g_rect.c u8g_state.c u8g_font.c \ + u8g_font_6x13.c u8g_font_04b_03.c u8g_font_5x8.c endif ifeq ($(TMC), 1) - LIB_CXXSRC += TMCStepper.cpp COOLCONF.cpp DRV_STATUS.cpp IHOLD_IRUN.cpp CHOPCONF.cpp GCONF.cpp PWMCONF.cpp DRV_CONF.cpp DRVCONF.cpp DRVCTRL.cpp DRVSTATUS.cpp ENCMODE.cpp RAMP_STAT.cpp SGCSCONF.cpp SHORT_CONF.cpp SMARTEN.cpp SW_MODE.cpp SW_SPI.cpp TMC2130Stepper.cpp TMC2208Stepper.cpp TMC2209Stepper.cpp TMC2660Stepper.cpp TMC5130Stepper.cpp TMC5160Stepper.cpp + LIB_CXXSRC += TMCStepper.cpp COOLCONF.cpp DRV_STATUS.cpp IHOLD_IRUN.cpp \ + CHOPCONF.cpp GCONF.cpp PWMCONF.cpp DRV_CONF.cpp DRVCONF.cpp DRVCTRL.cpp \ + DRVSTATUS.cpp ENCMODE.cpp RAMP_STAT.cpp SGCSCONF.cpp SHORT_CONF.cpp \ + SMARTEN.cpp SW_MODE.cpp SW_SPI.cpp TMC2130Stepper.cpp TMC2208Stepper.cpp \ + TMC2209Stepper.cpp TMC2660Stepper.cpp TMC5130Stepper.cpp TMC5160Stepper.cpp endif ifeq ($(RELOC_WORKAROUND), 1) @@ -674,17 +770,23 @@ REMOVE = rm -f MV = mv -f # Place -D or -U options here -CDEFS = -DF_CPU=$(F_CPU) ${addprefix -D , $(DEFINES)} -DARDUINO=$(ARDUINO_VERSION) +CDEFS = -DF_CPU=$(F_CPU)UL ${addprefix -D , $(DEFINES)} -DARDUINO=$(ARDUINO_VERSION) CXXDEFS = $(CDEFS) ifeq ($(HARDWARE_VARIANT), Teensy) - CDEFS += -DUSB_SERIAL + CDEFS += -DUSB_SERIAL LIB_SRC += usb.c pins_teensy.c LIB_CXXSRC += usb_api.cpp else ifeq ($(HARDWARE_VARIANT), archim) - CDEFS += -DARDUINO_SAM_ARCHIM -DARDUINO_ARCH_SAM -D__SAM3X8E__ -DUSB_VID=0x27b1 -DUSB_PID=0x0001 -DUSBCON '-DUSB_MANUFACTURER="UltiMachine"' '-DUSB_PRODUCT="Archim"' - LIB_CXXSRC += variant.cpp IPAddress.cpp Reset.cpp RingBuffer.cpp Stream.cpp UARTClass.cpp USARTClass.cpp abi.cpp new.cpp watchdog.cpp CDC.cpp PluggableUSB.cpp USBCore.cpp + CDEFS += -DARDUINO_SAM_ARCHIM -DARDUINO_ARCH_SAM -D__SAM3X8E__ + CDEFS += -DUSB_VID=0x27B1 -DUSB_PID=0x0001 -DUSBCON + CDEFS += '-DUSB_MANUFACTURER="UltiMachine"' '-DUSB_PRODUCT_STRING="Archim"' + + LIB_CXXSRC += variant.cpp IPAddress.cpp Reset.cpp RingBuffer.cpp Stream.cpp \ + UARTClass.cpp USARTClass.cpp abi.cpp new.cpp watchdog.cpp CDC.cpp \ + PluggableUSB.cpp USBCore.cpp + LIB_SRC += cortex_handlers.c iar_calls_sam3.c syscalls_sam3.c dtostrf.c itoa.c ifeq ($(U8GLIB), 1) @@ -710,16 +812,20 @@ CTUNING = -fsigned-char -funsigned-bitfields -fno-exceptions \ ifneq ($(HARDWARE_MOTHERBOARD),) CTUNING += -DMOTHERBOARD=${HARDWARE_MOTHERBOARD} endif + #CEXTRA = -Wa,-adhlns=$(<:.c=.lst) CXXEXTRA = -fno-use-cxa-atexit -fno-threadsafe-statics -fno-rtti CFLAGS := $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CEXTRA) $(CTUNING) $(CSTANDARD) CXXFLAGS := $(CDEFS) $(CINCS) -O$(OPT) $(CXXEXTRA) $(CTUNING) $(CXXSTANDARD) ASFLAGS := $(CDEFS) #ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + ifeq ($(HARDWARE_VARIANT), archim) LD_PREFIX = -Wl,--gc-sections,-Map,Marlin.ino.map,--cref,--check-sections,--entry=Reset_Handler,--unresolved-symbols=report-all,--warn-common,--warn-section-align LD_SUFFIX = $(LDLIBS) - LDFLAGS = -lm -T$(LDSCRIPT) -u _sbrk -u link -u _close -u _fstat -u _isatty -u _lseek -u _read -u _write -u _exit -u kill -u _getpid + + LDFLAGS = -lm -T$(LDSCRIPT) -u _sbrk -u link -u _close -u _fstat -u _isatty + LDFLAGS += -u _lseek -u _read -u _write -u _exit -u kill -u _getpid else LD_PREFIX = -Wl,--gc-sections,--relax LDFLAGS = -lm @@ -735,7 +841,7 @@ else AVRDUDE_CONF = $(ARDUINO_INSTALL_DIR)/hardware/tools/avr/etc/avrdude.conf endif AVRDUDE_FLAGS = -D -C$(AVRDUDE_CONF) \ - -p$(MCU) -P$(AVRDUDE_PORT) -c$(AVRDUDE_PROGRAMMER) \ + -p$(PROG_MCU) -P$(AVRDUDE_PORT) -c$(AVRDUDE_PROGRAMMER) \ -b$(UPLOAD_RATE) # Since Marlin 2.0, the source files may be distributed into several @@ -836,7 +942,7 @@ extcoff: $(TARGET).elf .elf.eep: -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ - --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ # Create extended listing file from ELF output file. .elf.lss: @@ -850,7 +956,7 @@ extcoff: $(TARGET).elf $(BUILD_DIR)/$(TARGET).elf: $(OBJ) Configuration.h $(Pecho) " CXX $@" - $P $(CC) $(LD_PREFIX) $(ALL_CXXFLAGS) -o $@ -L. $(OBJ) $(LDFLAGS) $(LD_SUFFIX) + $P $(CXX) $(LD_PREFIX) $(ALL_CXXFLAGS) -o $@ -L. $(OBJ) $(LDFLAGS) $(LD_SUFFIX) # Object files that were found in "src" will be stored in $(BUILD_DIR) # in directories that mirror the structure of "src" diff --git a/Marlin/Marlin.ino b/Marlin/Marlin.ino index ae5bca1dfed1..57c825445fb5 100644 --- a/Marlin/Marlin.ino +++ b/Marlin/Marlin.ino @@ -1,9 +1,8 @@ -/* -================================================================================ +/*============================================================================== Marlin Firmware - (c) 2011-2019 MarlinFirmware + (c) 2011-2020 MarlinFirmware Portions of Marlin are (c) by their respective authors. All code complies with GPLv2 and/or GPLv3 @@ -12,30 +11,33 @@ Greetings! Thank you for choosing Marlin 2 as your 3D printer firmware. To configure Marlin you must edit Configuration.h and Configuration_adv.h -located in the root 'Marlin' folder. Check the config/examples folder to see if -there's a more suitable starting-point for your specific hardware. +located in the root 'Marlin' folder. Check our Configurations repository to +see if there's a more suitable starting-point for your specific hardware. Before diving in, we recommend the following essential links: Marlin Firmware Official Website - - http://marlinfw.org/ + - https://marlinfw.org/ The official Marlin Firmware website contains the most up-to-date documentation. Contributions are always welcome! Configuration + - https://github.com/MarlinFirmware/Configurations + Example configurations for several printer models. + - https://www.youtube.com/watch?v=3gwWVFtdg-4 A good 20-minute overview of Marlin configuration by Tom Sanladerer. (Applies to Marlin 1.0.x, so Jerk and Acceleration should be halved.) Also... https://www.google.com/search?tbs=vid%3A1&q=configure+marlin - - http://marlinfw.org/docs/configuration/configuration.html + - https://marlinfw.org/docs/configuration/configuration.html Marlin's configuration options are explained in more detail here. Getting Help - - http://forums.reprap.org/list.php?415 + - https://reprap.org/forum/list.php?415 The Marlin Discussion Forum is a great place to get help from other Marlin users who may have experienced similar issues to your own. @@ -45,9 +47,11 @@ Getting Help Contributing - - http://marlinfw.org/docs/development/contributing.html + - https://marlinfw.org/docs/development/contributing.html If you'd like to contribute to Marlin, read this first! - - http://marlinfw.org/docs/development/coding_standards.html + - https://marlinfw.org/docs/development/coding_standards.html Before submitting code get to know the Coding Standards. -*/ + + +------------------------------------------------------------------------------*/ diff --git a/Marlin/Version.h b/Marlin/Version.h index 4cb589ea279c..60e068ba3521 100644 --- a/Marlin/Version.h +++ b/Marlin/Version.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -28,20 +28,20 @@ /** * Marlin release version identifier */ -//#define SHORT_BUILD_VERSION "2.0.4.4" +//#define SHORT_BUILD_VERSION "2.0.7.2" /** * Verbose version identifier which should contain a reference to the location * from where the binary was downloaded or the source code was compiled. */ -//#define DETAILED_BUILD_VERSION SHORT_BUILD_VERSION " (Github)" +//#define DETAILED_BUILD_VERSION SHORT_BUILD_VERSION /** * The STRING_DISTRIBUTION_DATE represents when the binary file was built, * here we define this default string as the date where the latest release * version was tagged. */ -//#define STRING_DISTRIBUTION_DATE "2020-01-31" +//#define STRING_DISTRIBUTION_DATE "2020-07-09" /** * Defines a generic printer name to be output to the LCD after booting Marlin. @@ -65,12 +65,12 @@ * The WEBSITE_URL is the location where users can get more information such as * documentation about a specific Marlin release. */ -//#define WEBSITE_URL "http://marlinfw.org" +//#define WEBSITE_URL "https://marlinfw.org" /** * Set the vendor info the serial USB interface, if changable * Currently only supported by DUE platform */ -//#define USB_DEVICE_VENDOR_ID 0x0000 -//#define USB_DEVICE_PRODUCT_ID 0x0000 -//#define USB_DEVICE_MANUFACTURE_NAME WEBSITE_URL +//#define USB_DEVICE_VENDOR_ID 0x0000 +//#define USB_DEVICE_PRODUCT_ID 0x0000 +//#define USB_DEVICE_MANUFACTURE_NAME WEBSITE_URL diff --git a/Marlin/lib/readme.txt b/Marlin/lib/readme.txt index dbadc3d6300d..5ec60aa85884 100644 --- a/Marlin/lib/readme.txt +++ b/Marlin/lib/readme.txt @@ -33,4 +33,4 @@ PlatformIO will find your libraries automatically, configure preprocessor's include paths and build them. More information about PlatformIO Library Dependency Finder -- http://docs.platformio.org/page/librarymanager/ldf.html +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/Marlin/src/HAL/HAL_AVR/HAL.cpp b/Marlin/src/HAL/AVR/HAL.cpp similarity index 96% rename from Marlin/src/HAL/HAL_AVR/HAL.cpp rename to Marlin/src/HAL/AVR/HAL.cpp index 317d13a5401b..58d57c8ee54b 100644 --- a/Marlin/src/HAL/HAL_AVR/HAL.cpp +++ b/Marlin/src/HAL/AVR/HAL.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef __AVR__ #include "../../inc/MarlinConfig.h" diff --git a/Marlin/src/HAL/AVR/HAL.h b/Marlin/src/HAL/AVR/HAL.h new file mode 100644 index 000000000000..6e0afa8f10ed --- /dev/null +++ b/Marlin/src/HAL/AVR/HAL.h @@ -0,0 +1,191 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com + * + * 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 . + * + */ +#pragma once + +#include "../shared/Marduino.h" +#include "../shared/HAL_SPI.h" +#include "fastio.h" +#include "watchdog.h" +#include "math.h" + +#ifdef IS_AT90USB + #include +#else + #define HardwareSerial_h // Hack to prevent HardwareSerial.h header inclusion + #include "MarlinSerial.h" +#endif + +#include +#include +#include +#include +#include +#include + +#ifndef pgm_read_ptr + // Compatibility for avr-libc 1.8.0-4.1 included with Ubuntu for + // Windows Subsystem for Linux on Windows 10 as of 10/18/2019 + #define pgm_read_ptr_far(address_long) (void*)__ELPM_word((uint32_t)(address_long)) + #define pgm_read_ptr_near(address_short) (void*)__LPM_word((uint16_t)(address_short)) + #define pgm_read_ptr(address_short) pgm_read_ptr_near(address_short) +#endif + +// ------------------------ +// Defines +// ------------------------ + +// AVR PROGMEM extension for sprintf_P +#define S_FMT "%S" + +// AVR PROGMEM extension for string define +#define PGMSTR(NAM,STR) const char NAM[] PROGMEM = STR + +#ifndef CRITICAL_SECTION_START + #define CRITICAL_SECTION_START() unsigned char _sreg = SREG; cli() + #define CRITICAL_SECTION_END() SREG = _sreg +#endif +#define ISRS_ENABLED() TEST(SREG, SREG_I) +#define ENABLE_ISRS() sei() +#define DISABLE_ISRS() cli() + +// ------------------------ +// Types +// ------------------------ + +typedef int8_t pin_t; + +#define SHARED_SERVOS HAS_SERVOS +#define HAL_SERVO_LIB Servo + +// ------------------------ +// Public Variables +// ------------------------ + +//extern uint8_t MCUSR; + +// Serial ports +#ifdef IS_AT90USB + #define MYSERIAL0 TERN(BLUETOOTH, bluetoothSerial, Serial) +#else + #if !WITHIN(SERIAL_PORT, -1, 3) + #error "SERIAL_PORT must be from -1 to 3. Please update your configuration." + #endif + #define MYSERIAL0 customizedSerial1 + + #ifdef SERIAL_PORT_2 + #if !WITHIN(SERIAL_PORT_2, -1, 3) + #error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration." + #endif + #define MYSERIAL1 customizedSerial2 + #endif +#endif + +#ifdef LCD_SERIAL_PORT + #if !WITHIN(LCD_SERIAL_PORT, -1, 3) + #error "LCD_SERIAL_PORT must be from -1 to 3. Please update your configuration." + #endif + #define LCD_SERIAL lcdSerial + #if HAS_DGUS_LCD + #define SERIAL_GET_TX_BUFFER_FREE() LCD_SERIAL.get_tx_buffer_free() + #endif +#endif + +// ------------------------ +// Public functions +// ------------------------ + +void HAL_init(); + +//void cli(); + +//void _delay_ms(const int delay); + +inline void HAL_clear_reset_source() { MCUSR = 0; } +inline uint8_t HAL_get_reset_source() { return MCUSR; } + +inline void HAL_reboot() {} // reboot the board or restart the bootloader + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +extern "C" { + int freeMemory(); +} +#pragma GCC diagnostic pop + +// ADC +#ifdef DIDR2 + #define HAL_ANALOG_SELECT(ind) do{ if (ind < 8) SBI(DIDR0, ind); else SBI(DIDR2, ind & 0x07); }while(0) +#else + #define HAL_ANALOG_SELECT(ind) SBI(DIDR0, ind); +#endif + +inline void HAL_adc_init() { + ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADIF) | 0x07; + DIDR0 = 0; + #ifdef DIDR2 + DIDR2 = 0; + #endif +} + +#define SET_ADMUX_ADCSRA(ch) ADMUX = _BV(REFS0) | (ch & 0x07); SBI(ADCSRA, ADSC) +#ifdef MUX5 + #define HAL_START_ADC(ch) if (ch > 7) ADCSRB = _BV(MUX5); else ADCSRB = 0; SET_ADMUX_ADCSRA(ch) +#else + #define HAL_START_ADC(ch) ADCSRB = 0; SET_ADMUX_ADCSRA(ch) +#endif + +#define HAL_ADC_VREF 5.0 +#define HAL_ADC_RESOLUTION 10 +#define HAL_READ_ADC() ADC +#define HAL_ADC_READY() !TEST(ADCSRA, ADSC) + +#define GET_PIN_MAP_PIN(index) index +#define GET_PIN_MAP_INDEX(pin) pin +#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval) + +#define HAL_SENSITIVE_PINS 0, 1 + +#ifdef __AVR_AT90USB1286__ + #define JTAG_DISABLE() do{ MCUCR = 0x80; MCUCR = 0x80; }while(0) +#endif + +// AVR compatibility +#define strtof strtod + +#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment + +/** + * set_pwm_frequency + * Sets the frequency of the timer corresponding to the provided pin + * as close as possible to the provided desired frequency. Internally + * calculates the required waveform generation mode, prescaler and + * resolution values required and sets the timer registers accordingly. + * NOTE that the frequency is applied to all pins on the timer (Ex OC3A, OC3B and OC3B) + * NOTE that there are limitations, particularly if using TIMER2. (see Configuration_adv.h -> FAST FAN PWM Settings) + */ +void set_pwm_frequency(const pin_t pin, int f_desired); + +/** + * set_pwm_duty + * Sets the PWM duty cycle of the provided pin to the provided value + * Optionally allows inverting the duty cycle [default = false] + * Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255] + */ +void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false); diff --git a/Marlin/src/HAL/HAL_AVR/HAL_SPI.cpp b/Marlin/src/HAL/AVR/HAL_SPI.cpp similarity index 97% rename from Marlin/src/HAL/HAL_AVR/HAL_SPI.cpp rename to Marlin/src/HAL/AVR/HAL_SPI.cpp index 29d5e3870027..31e589746cf2 100644 --- a/Marlin/src/HAL/HAL_AVR/HAL_SPI.cpp +++ b/Marlin/src/HAL/AVR/HAL_SPI.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -197,7 +197,7 @@ void spiBegin() { // output pin high - like sending 0xFF WRITE(MOSI_PIN, HIGH); - for (uint8_t i = 0; i < 8; i++) { + LOOP_L_N(i, 8) { WRITE(SCK_PIN, HIGH); nop; // adjust so SCK is nice @@ -224,7 +224,7 @@ void spiBegin() { void spiSend(uint8_t data) { // no interrupts during byte send - about 8µs cli(); - for (uint8_t i = 0; i < 8; i++) { + LOOP_L_N(i, 8) { WRITE(SCK_PIN, LOW); WRITE(MOSI_PIN, data & 0x80); data <<= 1; diff --git a/Marlin/src/HAL/AVR/MarlinSerial.cpp b/Marlin/src/HAL/AVR/MarlinSerial.cpp new file mode 100644 index 000000000000..8feac32aa74c --- /dev/null +++ b/Marlin/src/HAL/AVR/MarlinSerial.cpp @@ -0,0 +1,802 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * MarlinSerial.cpp - Hardware serial library for Wiring + * Copyright (c) 2006 Nicholas Zambetti. All right reserved. + * + * Modified 23 November 2006 by David A. Mellis + * Modified 28 September 2010 by Mark Sproul + * Modified 14 February 2016 by Andreas Hardtung (added tx buffer) + * Modified 01 October 2017 by Eduardo José Tagle (added XON/XOFF) + * Modified 10 June 2018 by Eduardo José Tagle (See #10991) + * Templatized 01 October 2018 by Eduardo José Tagle to allow multiple instances + */ + +#ifdef __AVR__ + +// Disable HardwareSerial.cpp to support chips without a UART (Attiny, etc.) + +#include "../../inc/MarlinConfig.h" + +#if !IS_AT90USB && (defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H)) + +#include "MarlinSerial.h" +#include "../../MarlinCore.h" + +#if ENABLED(DIRECT_STEPPING) + #include "../../feature/direct_stepping.h" +#endif + +template typename MarlinSerial::ring_buffer_r MarlinSerial::rx_buffer = { 0, 0, { 0 } }; +template typename MarlinSerial::ring_buffer_t MarlinSerial::tx_buffer = { 0 }; +template bool MarlinSerial::_written = false; +template uint8_t MarlinSerial::xon_xoff_state = MarlinSerial::XON_XOFF_CHAR_SENT | MarlinSerial::XON_CHAR; +template uint8_t MarlinSerial::rx_dropped_bytes = 0; +template uint8_t MarlinSerial::rx_buffer_overruns = 0; +template uint8_t MarlinSerial::rx_framing_errors = 0; +template typename MarlinSerial::ring_buffer_pos_t MarlinSerial::rx_max_enqueued = 0; + +// A SW memory barrier, to ensure GCC does not overoptimize loops +#define sw_barrier() asm volatile("": : :"memory"); + +#include "../../feature/e_parser.h" + +// "Atomically" read the RX head index value without disabling interrupts: +// This MUST be called with RX interrupts enabled, and CAN'T be called +// from the RX ISR itself! +template +FORCE_INLINE typename MarlinSerial::ring_buffer_pos_t MarlinSerial::atomic_read_rx_head() { + if (Cfg::RX_SIZE > 256) { + // Keep reading until 2 consecutive reads return the same value, + // meaning there was no update in-between caused by an interrupt. + // This works because serial RX interrupts happen at a slower rate + // than successive reads of a variable, so 2 consecutive reads with + // the same value means no interrupt updated it. + ring_buffer_pos_t vold, vnew = rx_buffer.head; + sw_barrier(); + do { + vold = vnew; + vnew = rx_buffer.head; + sw_barrier(); + } while (vold != vnew); + return vnew; + } + else { + // With an 8bit index, reads are always atomic. No need for special handling + return rx_buffer.head; + } +} + +template +volatile bool MarlinSerial::rx_tail_value_not_stable = false; +template +volatile uint16_t MarlinSerial::rx_tail_value_backup = 0; + +// Set RX tail index, taking into account the RX ISR could interrupt +// the write to this variable in the middle - So a backup strategy +// is used to ensure reads of the correct values. +// -Must NOT be called from the RX ISR - +template +FORCE_INLINE void MarlinSerial::atomic_set_rx_tail(typename MarlinSerial::ring_buffer_pos_t value) { + if (Cfg::RX_SIZE > 256) { + // Store the new value in the backup + rx_tail_value_backup = value; + sw_barrier(); + // Flag we are about to change the true value + rx_tail_value_not_stable = true; + sw_barrier(); + // Store the new value + rx_buffer.tail = value; + sw_barrier(); + // Signal the new value is completely stored into the value + rx_tail_value_not_stable = false; + sw_barrier(); + } + else + rx_buffer.tail = value; +} + +// Get the RX tail index, taking into account the read could be +// interrupting in the middle of the update of that index value +// -Called from the RX ISR - +template +FORCE_INLINE typename MarlinSerial::ring_buffer_pos_t MarlinSerial::atomic_read_rx_tail() { + if (Cfg::RX_SIZE > 256) { + // If the true index is being modified, return the backup value + if (rx_tail_value_not_stable) return rx_tail_value_backup; + } + // The true index is stable, return it + return rx_buffer.tail; +} + +// (called with RX interrupts disabled) +template +FORCE_INLINE void MarlinSerial::store_rxd_char() { + + static EmergencyParser::State emergency_state; // = EP_RESET + + // This must read the R_UCSRA register before reading the received byte to detect error causes + if (Cfg::DROPPED_RX && B_DOR && !++rx_dropped_bytes) --rx_dropped_bytes; + if (Cfg::RX_OVERRUNS && B_DOR && !++rx_buffer_overruns) --rx_buffer_overruns; + if (Cfg::RX_FRAMING_ERRORS && B_FE && !++rx_framing_errors) --rx_framing_errors; + + // Read the character from the USART + uint8_t c = R_UDR; + + #if ENABLED(DIRECT_STEPPING) + if (page_manager.maybe_store_rxd_char(c)) return; + #endif + + // Get the tail - Nothing can alter its value while this ISR is executing, but there's + // a chance that this ISR interrupted the main process while it was updating the index. + // The backup mechanism ensures the correct value is always returned. + const ring_buffer_pos_t t = atomic_read_rx_tail(); + + // Get the head pointer - This ISR is the only one that modifies its value, so it's safe to read here + ring_buffer_pos_t h = rx_buffer.head; + + // Get the next element + ring_buffer_pos_t i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); + + if (Cfg::EMERGENCYPARSER) emergency_parser.update(emergency_state, c); + + // If the character is to be stored at the index just before the tail + // (such that the head would advance to the current tail), the RX FIFO is + // full, so don't write the character or advance the head. + if (i != t) { + rx_buffer.buffer[h] = c; + h = i; + } + else if (Cfg::DROPPED_RX && !++rx_dropped_bytes) + --rx_dropped_bytes; + + if (Cfg::MAX_RX_QUEUED) { + // Calculate count of bytes stored into the RX buffer + const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); + + // Keep track of the maximum count of enqueued bytes + NOLESS(rx_max_enqueued, rx_count); + } + + if (Cfg::XONOFF) { + // If the last char that was sent was an XON + if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XON_CHAR) { + + // Bytes stored into the RX buffer + const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); + + // If over 12.5% of RX buffer capacity, send XOFF before running out of + // RX buffer space .. 325 bytes @ 250kbits/s needed to let the host react + // and stop sending bytes. This translates to 13mS propagation time. + if (rx_count >= (Cfg::RX_SIZE) / 8) { + + // At this point, definitely no TX interrupt was executing, since the TX ISR can't be preempted. + // Don't enable the TX interrupt here as a means to trigger the XOFF char, because if it happens + // to be in the middle of trying to disable the RX interrupt in the main program, eventually the + // enabling of the TX interrupt could be undone. The ONLY reliable thing this can do to ensure + // the sending of the XOFF char is to send it HERE AND NOW. + + // About to send the XOFF char + xon_xoff_state = XOFF_CHAR | XON_XOFF_CHAR_SENT; + + // Wait until the TX register becomes empty and send it - Here there could be a problem + // - While waiting for the TX register to empty, the RX register could receive a new + // character. This must also handle that situation! + while (!B_UDRE) { + + if (B_RXC) { + // A char arrived while waiting for the TX buffer to be empty - Receive and process it! + + i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); + + // Read the character from the USART + c = R_UDR; + + if (Cfg::EMERGENCYPARSER) emergency_parser.update(emergency_state, c); + + // If the character is to be stored at the index just before the tail + // (such that the head would advance to the current tail), the FIFO is + // full, so don't write the character or advance the head. + if (i != t) { + rx_buffer.buffer[h] = c; + h = i; + } + else if (Cfg::DROPPED_RX && !++rx_dropped_bytes) + --rx_dropped_bytes; + } + sw_barrier(); + } + + R_UDR = XOFF_CHAR; + + // Clear the TXC bit -- "can be cleared by writing a one to its bit + // location". This makes sure flush() won't return until the bytes + // actually got written + B_TXC = 1; + + // At this point there could be a race condition between the write() function + // and this sending of the XOFF char. This interrupt could happen between the + // wait to be empty TX buffer loop and the actual write of the character. Since + // the TX buffer is full because it's sending the XOFF char, the only way to be + // sure the write() function will succeed is to wait for the XOFF char to be + // completely sent. Since an extra character could be received during the wait + // it must also be handled! + while (!B_UDRE) { + + if (B_RXC) { + // A char arrived while waiting for the TX buffer to be empty - Receive and process it! + + i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); + + // Read the character from the USART + c = R_UDR; + + if (Cfg::EMERGENCYPARSER) + emergency_parser.update(emergency_state, c); + + // If the character is to be stored at the index just before the tail + // (such that the head would advance to the current tail), the FIFO is + // full, so don't write the character or advance the head. + if (i != t) { + rx_buffer.buffer[h] = c; + h = i; + } + else if (Cfg::DROPPED_RX && !++rx_dropped_bytes) + --rx_dropped_bytes; + } + sw_barrier(); + } + + // At this point everything is ready. The write() function won't + // have any issues writing to the UART TX register if it needs to! + } + } + } + + // Store the new head value - The main loop will retry until the value is stable + rx_buffer.head = h; +} + +// (called with TX irqs disabled) +template +FORCE_INLINE void MarlinSerial::_tx_udr_empty_irq() { + if (Cfg::TX_SIZE > 0) { + // Read positions + uint8_t t = tx_buffer.tail; + const uint8_t h = tx_buffer.head; + + if (Cfg::XONOFF) { + // If an XON char is pending to be sent, do it now + if (xon_xoff_state == XON_CHAR) { + + // Send the character + R_UDR = XON_CHAR; + + // clear the TXC bit -- "can be cleared by writing a one to its bit + // location". This makes sure flush() won't return until the bytes + // actually got written + B_TXC = 1; + + // Remember we sent it. + xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT; + + // If nothing else to transmit, just disable TX interrupts. + if (h == t) B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed) + + return; + } + } + + // If nothing to transmit, just disable TX interrupts. This could + // happen as the result of the non atomicity of the disabling of RX + // interrupts that could end reenabling TX interrupts as a side effect. + if (h == t) { + B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed) + return; + } + + // There is something to TX, Send the next byte + const uint8_t c = tx_buffer.buffer[t]; + t = (t + 1) & (Cfg::TX_SIZE - 1); + R_UDR = c; + tx_buffer.tail = t; + + // Clear the TXC bit (by writing a one to its bit location). + // Ensures flush() won't return until the bytes are actually written/ + B_TXC = 1; + + // Disable interrupts if there is nothing to transmit following this byte + if (h == t) B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed) + } +} + +// Public Methods +template +void MarlinSerial::begin(const long baud) { + uint16_t baud_setting; + bool useU2X = true; + + #if F_CPU == 16000000UL && SERIAL_PORT == 0 + // Hard-coded exception for compatibility with the bootloader shipped + // with the Duemilanove and previous boards, and the firmware on the + // 8U2 on the Uno and Mega 2560. + if (baud == 57600) useU2X = false; + #endif + + R_UCSRA = 0; + if (useU2X) { + B_U2X = 1; + baud_setting = (F_CPU / 4 / baud - 1) / 2; + } + else + baud_setting = (F_CPU / 8 / baud - 1) / 2; + + // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register) + R_UBRRH = baud_setting >> 8; + R_UBRRL = baud_setting; + + B_RXEN = 1; + B_TXEN = 1; + B_RXCIE = 1; + if (Cfg::TX_SIZE > 0) B_UDRIE = 0; + _written = false; +} + +template +void MarlinSerial::end() { + B_RXEN = 0; + B_TXEN = 0; + B_RXCIE = 0; + B_UDRIE = 0; +} + +template +int MarlinSerial::peek() { + const ring_buffer_pos_t h = atomic_read_rx_head(), t = rx_buffer.tail; + return h == t ? -1 : rx_buffer.buffer[t]; +} + +template +int MarlinSerial::read() { + const ring_buffer_pos_t h = atomic_read_rx_head(); + + // Read the tail. Main thread owns it, so it is safe to directly read it + ring_buffer_pos_t t = rx_buffer.tail; + + // If nothing to read, return now + if (h == t) return -1; + + // Get the next char + const int v = rx_buffer.buffer[t]; + t = (ring_buffer_pos_t)(t + 1) & (Cfg::RX_SIZE - 1); + + // Advance tail - Making sure the RX ISR will always get an stable value, even + // if it interrupts the writing of the value of that variable in the middle. + atomic_set_rx_tail(t); + + if (Cfg::XONOFF) { + // If the XOFF char was sent, or about to be sent... + if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) { + // Get count of bytes in the RX buffer + const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); + if (rx_count < (Cfg::RX_SIZE) / 10) { + if (Cfg::TX_SIZE > 0) { + // Signal we want an XON character to be sent. + xon_xoff_state = XON_CHAR; + // Enable TX ISR. Non atomic, but it will eventually enable them + B_UDRIE = 1; + } + else { + // If not using TX interrupts, we must send the XON char now + xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT; + while (!B_UDRE) sw_barrier(); + R_UDR = XON_CHAR; + } + } + } + } + + return v; +} + +template +typename MarlinSerial::ring_buffer_pos_t MarlinSerial::available() { + const ring_buffer_pos_t h = atomic_read_rx_head(), t = rx_buffer.tail; + return (ring_buffer_pos_t)(Cfg::RX_SIZE + h - t) & (Cfg::RX_SIZE - 1); +} + +template +void MarlinSerial::flush() { + + // Set the tail to the head: + // - Read the RX head index in a safe way. (See atomic_read_rx_head.) + // - Set the tail, making sure the RX ISR will always get a stable value, even + // if it interrupts the writing of the value of that variable in the middle. + atomic_set_rx_tail(atomic_read_rx_head()); + + if (Cfg::XONOFF) { + // If the XOFF char was sent, or about to be sent... + if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) { + if (Cfg::TX_SIZE > 0) { + // Signal we want an XON character to be sent. + xon_xoff_state = XON_CHAR; + // Enable TX ISR. Non atomic, but it will eventually enable it. + B_UDRIE = 1; + } + else { + // If not using TX interrupts, we must send the XON char now + xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT; + while (!B_UDRE) sw_barrier(); + R_UDR = XON_CHAR; + } + } + } +} + +template +void MarlinSerial::write(const uint8_t c) { + if (Cfg::TX_SIZE == 0) { + + _written = true; + while (!B_UDRE) sw_barrier(); + R_UDR = c; + + } + else { + + _written = true; + + // If the TX interrupts are disabled and the data register + // is empty, just write the byte to the data register and + // be done. This shortcut helps significantly improve the + // effective datarate at high (>500kbit/s) bitrates, where + // interrupt overhead becomes a slowdown. + // Yes, there is a race condition between the sending of the + // XOFF char at the RX ISR, but it is properly handled there + if (!B_UDRIE && B_UDRE) { + R_UDR = c; + + // clear the TXC bit -- "can be cleared by writing a one to its bit + // location". This makes sure flush() won't return until the bytes + // actually got written + B_TXC = 1; + return; + } + + const uint8_t i = (tx_buffer.head + 1) & (Cfg::TX_SIZE - 1); + + // If global interrupts are disabled (as the result of being called from an ISR)... + if (!ISRS_ENABLED()) { + + // Make room by polling if it is possible to transmit, and do so! + while (i == tx_buffer.tail) { + + // If we can transmit another byte, do it. + if (B_UDRE) _tx_udr_empty_irq(); + + // Make sure compiler rereads tx_buffer.tail + sw_barrier(); + } + } + else { + // Interrupts are enabled, just wait until there is space + while (i == tx_buffer.tail) sw_barrier(); + } + + // Store new char. head is always safe to move + tx_buffer.buffer[tx_buffer.head] = c; + tx_buffer.head = i; + + // Enable TX ISR - Non atomic, but it will eventually enable TX ISR + B_UDRIE = 1; + } +} + +template +void MarlinSerial::flushTX() { + + if (Cfg::TX_SIZE == 0) { + // No bytes written, no need to flush. This special case is needed since there's + // no way to force the TXC (transmit complete) bit to 1 during initialization. + if (!_written) return; + + // Wait until everything was transmitted + while (!B_TXC) sw_barrier(); + + // At this point nothing is queued anymore (DRIE is disabled) and + // the hardware finished transmission (TXC is set). + + } + else { + + // No bytes written, no need to flush. This special case is needed since there's + // no way to force the TXC (transmit complete) bit to 1 during initialization. + if (!_written) return; + + // If global interrupts are disabled (as the result of being called from an ISR)... + if (!ISRS_ENABLED()) { + + // Wait until everything was transmitted - We must do polling, as interrupts are disabled + while (tx_buffer.head != tx_buffer.tail || !B_TXC) { + + // If there is more space, send an extra character + if (B_UDRE) _tx_udr_empty_irq(); + + sw_barrier(); + } + + } + else { + // Wait until everything was transmitted + while (tx_buffer.head != tx_buffer.tail || !B_TXC) sw_barrier(); + } + + // At this point nothing is queued anymore (DRIE is disabled) and + // the hardware finished transmission (TXC is set). + } +} + +/** + * Imports from print.h + */ + +template +void MarlinSerial::print(char c, int base) { + print((long)c, base); +} + +template +void MarlinSerial::print(unsigned char b, int base) { + print((unsigned long)b, base); +} + +template +void MarlinSerial::print(int n, int base) { + print((long)n, base); +} + +template +void MarlinSerial::print(unsigned int n, int base) { + print((unsigned long)n, base); +} + +template +void MarlinSerial::print(long n, int base) { + if (base == 0) write(n); + else if (base == 10) { + if (n < 0) { print('-'); n = -n; } + printNumber(n, 10); + } + else + printNumber(n, base); +} + +template +void MarlinSerial::print(unsigned long n, int base) { + if (base == 0) write(n); + else printNumber(n, base); +} + +template +void MarlinSerial::print(double n, int digits) { + printFloat(n, digits); +} + +template +void MarlinSerial::println() { + print('\r'); + print('\n'); +} + +template +void MarlinSerial::println(const String& s) { + print(s); + println(); +} + +template +void MarlinSerial::println(const char c[]) { + print(c); + println(); +} + +template +void MarlinSerial::println(char c, int base) { + print(c, base); + println(); +} + +template +void MarlinSerial::println(unsigned char b, int base) { + print(b, base); + println(); +} + +template +void MarlinSerial::println(int n, int base) { + print(n, base); + println(); +} + +template +void MarlinSerial::println(unsigned int n, int base) { + print(n, base); + println(); +} + +template +void MarlinSerial::println(long n, int base) { + print(n, base); + println(); +} + +template +void MarlinSerial::println(unsigned long n, int base) { + print(n, base); + println(); +} + +template +void MarlinSerial::println(double n, int digits) { + print(n, digits); + println(); +} + +// Private Methods + +template +void MarlinSerial::printNumber(unsigned long n, uint8_t base) { + if (n) { + unsigned char buf[8 * sizeof(long)]; // Enough space for base 2 + int8_t i = 0; + while (n) { + buf[i++] = n % base; + n /= base; + } + while (i--) + print((char)(buf[i] + (buf[i] < 10 ? '0' : 'A' - 10))); + } + else + print('0'); +} + +template +void MarlinSerial::printFloat(double number, uint8_t digits) { + // Handle negative numbers + if (number < 0.0) { + print('-'); + number = -number; + } + + // Round correctly so that print(1.999, 2) prints as "2.00" + double rounding = 0.5; + LOOP_L_N(i, digits) rounding *= 0.1; + number += rounding; + + // Extract the integer part of the number and print it + unsigned long int_part = (unsigned long)number; + double remainder = number - (double)int_part; + print(int_part); + + // Print the decimal point, but only if there are digits beyond + if (digits) { + print('.'); + // Extract digits from the remainder one at a time + while (digits--) { + remainder *= 10.0; + int toPrint = int(remainder); + print(toPrint); + remainder -= toPrint; + } + } +} + +// Hookup ISR handlers +ISR(SERIAL_REGNAME(USART, SERIAL_PORT, _RX_vect)) { + MarlinSerial>::store_rxd_char(); +} + +ISR(SERIAL_REGNAME(USART, SERIAL_PORT, _UDRE_vect)) { + MarlinSerial>::_tx_udr_empty_irq(); +} + +// Preinstantiate +template class MarlinSerial>; + +// Instantiate +MarlinSerial> customizedSerial1; + +#ifdef SERIAL_PORT_2 + + // Hookup ISR handlers + ISR(SERIAL_REGNAME(USART, SERIAL_PORT_2, _RX_vect)) { + MarlinSerial>::store_rxd_char(); + } + + ISR(SERIAL_REGNAME(USART, SERIAL_PORT_2, _UDRE_vect)) { + MarlinSerial>::_tx_udr_empty_irq(); + } + + // Preinstantiate + template class MarlinSerial>; + + // Instantiate + MarlinSerial> customizedSerial2; + +#endif + +#ifdef MMU2_SERIAL_PORT + + ISR(SERIAL_REGNAME(USART, MMU2_SERIAL_PORT, _RX_vect)) { + MarlinSerial>::store_rxd_char(); + } + + ISR(SERIAL_REGNAME(USART, MMU2_SERIAL_PORT, _UDRE_vect)) { + MarlinSerial>::_tx_udr_empty_irq(); + } + + // Preinstantiate + template class MarlinSerial>; + + // Instantiate + MarlinSerial> mmuSerial; + +#endif + +#ifdef LCD_SERIAL_PORT + + ISR(SERIAL_REGNAME(USART, LCD_SERIAL_PORT, _RX_vect)) { + MarlinSerial>::store_rxd_char(); + } + + ISR(SERIAL_REGNAME(USART, LCD_SERIAL_PORT, _UDRE_vect)) { + MarlinSerial>::_tx_udr_empty_irq(); + } + + // Preinstantiate + template class MarlinSerial>; + + // Instantiate + MarlinSerial> lcdSerial; + + #if HAS_DGUS_LCD + template + typename MarlinSerial::ring_buffer_pos_t MarlinSerial::get_tx_buffer_free() { + const ring_buffer_pos_t t = tx_buffer.tail, // next byte to send. + h = tx_buffer.head; // next pos for queue. + int ret = t - h - 1; + if (ret < 0) ret += Cfg::TX_SIZE + 1; + return ret; + } + #endif + +#endif + +#endif // !IS_AT90USB && (UBRRH || UBRR0H || UBRR1H || UBRR2H || UBRR3H) + +// For AT90USB targets use the UART for BT interfacing +#if BOTH(IS_AT90USB, BLUETOOTH) + HardwareSerial bluetoothSerial; +#endif + +#endif // __AVR__ diff --git a/Marlin/src/HAL/HAL_AVR/MarlinSerial.h b/Marlin/src/HAL/AVR/MarlinSerial.h similarity index 82% rename from Marlin/src/HAL/HAL_AVR/MarlinSerial.h rename to Marlin/src/HAL/AVR/MarlinSerial.h index 33870e2ca657..3850e2a47e2a 100644 --- a/Marlin/src/HAL/HAL_AVR/MarlinSerial.h +++ b/Marlin/src/HAL/AVR/MarlinSerial.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -31,10 +31,10 @@ * Templatized 01 October 2018 by Eduardo José Tagle to allow multiple instances */ -#include "../shared/MarlinSerial.h" - #include +#include "../../inc/MarlinConfigPre.h" + #ifndef SERIAL_PORT #define SERIAL_PORT 0 #endif @@ -48,11 +48,11 @@ // These are macros to build serial port register names for the selected SERIAL_PORT (C preprocessor // requires two levels of indirection to expand macro values properly) - #define SERIAL_REGNAME(registerbase,number,suffix) SERIAL_REGNAME_INTERNAL(registerbase,number,suffix) + #define SERIAL_REGNAME(registerbase,number,suffix) _SERIAL_REGNAME(registerbase,number,suffix) #if SERIAL_PORT == 0 && (!defined(UBRR0H) || !defined(UDR0)) // use un-numbered registers if necessary - #define SERIAL_REGNAME_INTERNAL(registerbase,number,suffix) registerbase##suffix + #define _SERIAL_REGNAME(registerbase,number,suffix) registerbase##suffix #else - #define SERIAL_REGNAME_INTERNAL(registerbase,number,suffix) registerbase##number##suffix + #define _SERIAL_REGNAME(registerbase,number,suffix) registerbase##number##suffix #endif // Registers used by MarlinSerial class (expanded depending on selected serial port) @@ -217,10 +217,12 @@ static ring_buffer_pos_t available(); static void write(const uint8_t c); static void flushTX(); - #ifdef DGUS_SERIAL_PORT + #if HAS_DGUS_LCD static ring_buffer_pos_t get_tx_buffer_free(); #endif + static inline bool emergency_parser_enabled() { return Cfg::EMERGENCYPARSER; } + FORCE_INLINE static uint8_t dropped() { return Cfg::DROPPED_RX ? rx_dropped_bytes : 0; } FORCE_INLINE static uint8_t buffer_overruns() { return Cfg::RX_OVERRUNS ? rx_buffer_overruns : 0; } FORCE_INLINE static uint8_t framing_errors() { return Cfg::RX_FRAMING_ERRORS ? rx_framing_errors : 0; } @@ -261,12 +263,12 @@ static constexpr int PORT = serial; static constexpr unsigned int RX_SIZE = RX_BUFFER_SIZE; static constexpr unsigned int TX_SIZE = TX_BUFFER_SIZE; - static constexpr bool XONOFF = bSERIAL_XON_XOFF; - static constexpr bool EMERGENCYPARSER = bEMERGENCY_PARSER; - static constexpr bool DROPPED_RX = bSERIAL_STATS_DROPPED_RX; - static constexpr bool RX_OVERRUNS = bSERIAL_STATS_RX_BUFFER_OVERRUNS; - static constexpr bool RX_FRAMING_ERRORS = bSERIAL_STATS_RX_FRAMING_ERRORS; - static constexpr bool MAX_RX_QUEUED = bSERIAL_STATS_MAX_RX_QUEUED; + static constexpr bool XONOFF = ENABLED(SERIAL_XON_XOFF); + static constexpr bool EMERGENCYPARSER = ENABLED(EMERGENCY_PARSER); + static constexpr bool DROPPED_RX = ENABLED(SERIAL_STATS_DROPPED_RX); + static constexpr bool RX_OVERRUNS = ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS); + static constexpr bool RX_FRAMING_ERRORS = ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS); + static constexpr bool MAX_RX_QUEUED = ENABLED(SERIAL_STATS_MAX_RX_QUEUED); }; extern MarlinSerial> customizedSerial1; @@ -278,41 +280,53 @@ #endif // !USBCON -#ifdef INTERNAL_SERIAL_PORT +#ifdef MMU2_SERIAL_PORT template - struct MarlinInternalSerialCfg { + struct MMU2SerialCfg { static constexpr int PORT = serial; - static constexpr unsigned int RX_SIZE = 32; - static constexpr unsigned int TX_SIZE = 32; static constexpr bool XONOFF = false; static constexpr bool EMERGENCYPARSER = false; static constexpr bool DROPPED_RX = false; - static constexpr bool RX_OVERRUNS = false; static constexpr bool RX_FRAMING_ERRORS = false; static constexpr bool MAX_RX_QUEUED = false; + static constexpr unsigned int RX_SIZE = 32; + static constexpr unsigned int TX_SIZE = 32; + static constexpr bool RX_OVERRUNS = false; }; - extern MarlinSerial> internalSerial; + extern MarlinSerial> mmuSerial; #endif -#ifdef DGUS_SERIAL_PORT +#ifdef LCD_SERIAL_PORT + template - struct MarlinInternalSerialCfg { - static constexpr int PORT = serial; - static constexpr unsigned int RX_SIZE = 128; - static constexpr unsigned int TX_SIZE = 48; - static constexpr bool XONOFF = false; - static constexpr bool EMERGENCYPARSER = false; - static constexpr bool DROPPED_RX = false; - static constexpr bool RX_OVERRUNS = bDGUS_SERIAL_STATS_RX_BUFFER_OVERRUNS; - static constexpr bool RX_FRAMING_ERRORS = false; - static constexpr bool MAX_RX_QUEUED = false; + struct LCDSerialCfg { + static constexpr int PORT = serial; + static constexpr bool XONOFF = false; + static constexpr bool EMERGENCYPARSER = ENABLED(EMERGENCY_PARSER); + static constexpr bool DROPPED_RX = false; + static constexpr bool RX_FRAMING_ERRORS = false; + static constexpr bool MAX_RX_QUEUED = false; + #if HAS_DGUS_LCD + static constexpr unsigned int RX_SIZE = DGUS_RX_BUFFER_SIZE; + static constexpr unsigned int TX_SIZE = DGUS_TX_BUFFER_SIZE; + static constexpr bool RX_OVERRUNS = ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS); + #elif EITHER(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON) + static constexpr unsigned int RX_SIZE = 64; + static constexpr unsigned int TX_SIZE = 128; + static constexpr bool RX_OVERRUNS = false; + #else + static constexpr unsigned int RX_SIZE = 64; + static constexpr unsigned int TX_SIZE = 128; + static constexpr bool RX_OVERRUNS = false + #endif }; - extern MarlinSerial> internalDgusSerial; + extern MarlinSerial> lcdSerial; + #endif // Use the UART for Bluetooth in AT90USB configurations -#if defined(USBCON) && ENABLED(BLUETOOTH) +#if BOTH(IS_AT90USB, BLUETOOTH) extern HardwareSerial bluetoothSerial; #endif diff --git a/Marlin/src/HAL/HAL_AVR/Servo.cpp b/Marlin/src/HAL/AVR/Servo.cpp similarity index 98% rename from Marlin/src/HAL/HAL_AVR/Servo.cpp rename to Marlin/src/HAL/AVR/Servo.cpp index 02c131bd449a..526352b77339 100644 --- a/Marlin/src/HAL/HAL_AVR/Servo.cpp +++ b/Marlin/src/HAL/AVR/Servo.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -48,7 +48,6 @@ * readMicroseconds() - Get the last-written servo pulse width in microseconds. * attached() - Return true if a servo is attached. * detach() - Stop an attached servo from pulsing its i/o pin. - * */ #ifdef __AVR__ @@ -59,7 +58,6 @@ #include -#include "../shared/Marduino.h" #include "../shared/servo.h" #include "../shared/servo_private.h" diff --git a/Marlin/src/HAL/HAL_AVR/ServoTimers.h b/Marlin/src/HAL/AVR/ServoTimers.h similarity index 90% rename from Marlin/src/HAL/HAL_AVR/ServoTimers.h rename to Marlin/src/HAL/AVR/ServoTimers.h index 86007fd102c6..436b28141f95 100644 --- a/Marlin/src/HAL/HAL_AVR/ServoTimers.h +++ b/Marlin/src/HAL/AVR/ServoTimers.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -59,10 +59,12 @@ // Say which 16 bit timers can be used and in what order #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //#define _useTimer1 - #define _useTimer3 #define _useTimer4 - #if !HAS_MOTOR_CURRENT_PWM - #define _useTimer5 // Timer 5 is used for motor current PWM and can't be used for servos. + #if NUM_SERVOS > SERVOS_PER_TIMER + #define _useTimer3 + #if !HAS_MOTOR_CURRENT_PWM && SERVOS > 2 * SERVOS_PER_TIMER + #define _useTimer5 // Timer 5 is used for motor current PWM and can't be used for servos. + #endif #endif #elif defined(__AVR_ATmega32U4__) #define _useTimer3 diff --git a/Marlin/src/HAL/HAL_AVR/persistent_store_eeprom.cpp b/Marlin/src/HAL/AVR/eeprom.cpp similarity index 81% rename from Marlin/src/HAL/HAL_AVR/persistent_store_eeprom.cpp rename to Marlin/src/HAL/AVR/eeprom.cpp index 1ae37f892aa6..c7906985eb60 100644 --- a/Marlin/src/HAL/HAL_AVR/persistent_store_eeprom.cpp +++ b/Marlin/src/HAL/AVR/eeprom.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #ifdef __AVR__ @@ -25,9 +25,18 @@ #if EITHER(EEPROM_SETTINGS, SD_FIRMWARE_UPDATE) -#include "../shared/persistent_store_api.h" +/** + * PersistentStore for Arduino-style EEPROM interface + * with implementations supplied by the framework. + */ -bool PersistentStore::access_start() { return true; } +#include "../shared/eeprom_api.h" + +#ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE size_t(E2END + 1) +#endif +size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } +bool PersistentStore::access_start() { return true; } bool PersistentStore::access_finish() { return true; } bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { @@ -46,7 +55,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui crc16(crc, &v, 1); pos++; value++; - }; + } return false; } @@ -61,7 +70,5 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t return false; // always assume success for AVR's } -size_t PersistentStore::capacity() { return E2END + 1; } - #endif // EEPROM_SETTINGS || SD_FIRMWARE_UPDATE #endif // __AVR__ diff --git a/Marlin/src/HAL/HAL_AVR/endstop_interrupts.h b/Marlin/src/HAL/AVR/endstop_interrupts.h similarity index 99% rename from Marlin/src/HAL/HAL_AVR/endstop_interrupts.h rename to Marlin/src/HAL/AVR/endstop_interrupts.h index 8f89c69baf77..ae9a605accce 100644 --- a/Marlin/src/HAL/HAL_AVR/endstop_interrupts.h +++ b/Marlin/src/HAL/AVR/endstop_interrupts.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp similarity index 95% rename from Marlin/src/HAL/HAL_AVR/fast_pwm.cpp rename to Marlin/src/HAL/AVR/fast_pwm.cpp index 78a7ad883bd8..238c1124adeb 100644 --- a/Marlin/src/HAL/HAL_AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -16,14 +16,14 @@ * 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 . + * along with this program. If not, see . * */ #ifdef __AVR__ #include "../../inc/MarlinConfigPre.h" -#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_PWM +#if NEEDS_HARDWARE_PWM // Specific meta-flag for features that mandate PWM #include "HAL.h" @@ -167,7 +167,7 @@ void set_pwm_frequency(const pin_t pin, int f_desired) { uint16_t prescaler[] = { 0, 1, 8, /*TIMER2 ONLY*/32, 64, /*TIMER2 ONLY*/128, 256, 1024 }; // loop over prescaler values - for (uint8_t i = 1; i < 8; i++) { + LOOP_S_L_N(i, 1, 8) { uint16_t res_temp_fast = 255, res_temp_phase_correct = 255; if (timer.n == 2) { // No resolution calculation for TIMER2 unless enabled USE_OCR2A_AS_TOP @@ -185,8 +185,8 @@ void set_pwm_frequency(const pin_t pin, int f_desired) { res_temp_phase_correct = rtf / 2; } - LIMIT(res_temp_fast, 1u, size); - LIMIT(res_temp_phase_correct, 1u, size); + LIMIT(res_temp_fast, 1U, size); + LIMIT(res_temp_phase_correct, 1U, size); // Calculate frequencies of test prescaler and resolution values const int f_temp_fast = (F_CPU) / (prescaler[i] * (1 + res_temp_fast)), f_temp_phase_correct = (F_CPU) / (2 * prescaler[i] * res_temp_phase_correct), @@ -274,9 +274,9 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255 else top = *timer.ICRn; // top = ICRn - _SET_OCRnQ(timer.OCRnQ, timer.q, v * float(top / v_size)); // Scale 8/16-bit v to top value + _SET_OCRnQ(timer.OCRnQ, timer.q, v * float(top) / float(v_size)); // Scale 8/16-bit v to top value } } -#endif // FAST_PWM_FAN || SPINDLE_LASER_PWM +#endif // NEEDS_HARDWARE_PWM #endif // __AVR__ diff --git a/Marlin/src/HAL/HAL_AVR/fastio.cpp b/Marlin/src/HAL/AVR/fastio.cpp similarity index 66% rename from Marlin/src/HAL/HAL_AVR/fastio.cpp rename to Marlin/src/HAL/AVR/fastio.cpp index 9f70b50f7177..b51d7f97686a 100644 --- a/Marlin/src/HAL/HAL_AVR/fastio.cpp +++ b/Marlin/src/HAL/AVR/fastio.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -234,5 +234,55 @@ uint8_t extDigitalRead(const int8_t pin) { } } +#if 0 +/** + * Set Timer 5 PWM frequency in Hz, from 3.8Hz up to ~16MHz + * with a minimum resolution of 100 steps. + * + * DC values -1.0 to 1.0. Negative duty cycle inverts the pulse. + */ +uint16_t set_pwm_frequency_hz(const float &hz, const float dca, const float dcb, const float dcc) { + float count = 0; + if (hz > 0 && (dca || dcb || dcc)) { + count = float(F_CPU) / hz; // 1x prescaler, TOP for 16MHz base freq. + uint16_t prescaler; // Range of 30.5Hz (65535) 64.5KHz (>31) + + if (count >= 255. * 256.) { prescaler = 1024; SET_CS(5, PRESCALER_1024); } + else if (count >= 255. * 64.) { prescaler = 256; SET_CS(5, PRESCALER_256); } + else if (count >= 255. * 8.) { prescaler = 64; SET_CS(5, PRESCALER_64); } + else if (count >= 255.) { prescaler = 8; SET_CS(5, PRESCALER_8); } + else { prescaler = 1; SET_CS(5, PRESCALER_1); } + + count /= float(prescaler); + const float pwm_top = round(count); // Get the rounded count + + ICR5 = (uint16_t)pwm_top - 1; // Subtract 1 for TOP + OCR5A = pwm_top * ABS(dca); // Update and scale DCs + OCR5B = pwm_top * ABS(dcb); + OCR5C = pwm_top * ABS(dcc); + _SET_COM(5, A, dca ? (dca < 0 ? COM_SET_CLEAR : COM_CLEAR_SET) : COM_NORMAL); // Set compare modes + _SET_COM(5, B, dcb ? (dcb < 0 ? COM_SET_CLEAR : COM_CLEAR_SET) : COM_NORMAL); + _SET_COM(5, C, dcc ? (dcc < 0 ? COM_SET_CLEAR : COM_CLEAR_SET) : COM_NORMAL); + + SET_WGM(5, FAST_PWM_ICRn); // Fast PWM with ICR5 as TOP + + //SERIAL_ECHOLNPGM("Timer 5 Settings:"); + //SERIAL_ECHOLNPAIR(" Prescaler=", prescaler); + //SERIAL_ECHOLNPAIR(" TOP=", ICR5); + //SERIAL_ECHOLNPAIR(" OCR5A=", OCR5A); + //SERIAL_ECHOLNPAIR(" OCR5B=", OCR5B); + //SERIAL_ECHOLNPAIR(" OCR5C=", OCR5C); + } + else { + // Restore the default for Timer 5 + SET_WGM(5, PWM_PC_8); // PWM 8-bit (Phase Correct) + SET_COMS(5, NORMAL, NORMAL, NORMAL); // Do nothing + SET_CS(5, PRESCALER_64); // 16MHz / 64 = 250KHz + OCR5A = OCR5B = OCR5C = 0; + } + return round(count); +} +#endif + #endif // FASTIO_EXT_START #endif // __AVR__ diff --git a/Marlin/src/HAL/HAL_AVR/fastio.h b/Marlin/src/HAL/AVR/fastio.h similarity index 92% rename from Marlin/src/HAL/HAL_AVR/fastio.h rename to Marlin/src/HAL/AVR/fastio.h index 2246a0f9d09f..dd0163466110 100644 --- a/Marlin/src/HAL/HAL_AVR/fastio.h +++ b/Marlin/src/HAL/AVR/fastio.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -29,11 +29,17 @@ #include -#define AVR_AT90USB1286_FAMILY (defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1286P__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB646P__) || defined(__AVR_AT90USB647__)) -#define AVR_ATmega1284_FAMILY (defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__)) -#define AVR_ATmega2560_FAMILY (defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)) -#define AVR_ATmega2561_FAMILY (defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)) -#define AVR_ATmega328_FAMILY (defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__)) +#if defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1286P__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB646P__) || defined(__AVR_AT90USB647__) + #define AVR_AT90USB1286_FAMILY 1 +#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__) + #define AVR_ATmega1284_FAMILY 1 +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + #define AVR_ATmega2560_FAMILY 1 +#elif defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) + #define AVR_ATmega2561_FAMILY 1 +#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__) + #define AVR_ATmega328_FAMILY 1 +#endif /** * Include Ports and Functions @@ -57,7 +63,7 @@ * * Now you can simply SET_OUTPUT(PIN); WRITE(PIN, HIGH); WRITE(PIN, LOW); * - * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html + * Why double up on these macros? see https://gcc.gnu.org/onlinedocs/cpp/Stringification.html */ #define _READ(IO) TEST(DIO ## IO ## _RPORT, DIO ## IO ## _PIN) @@ -98,9 +104,9 @@ #define SET_INPUT(IO) _SET_INPUT(IO) #define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _WRITE(IO, HIGH); }while(0) +#define SET_INPUT_PULLDOWN SET_INPUT #define SET_OUTPUT(IO) _SET_OUTPUT(IO) - -#define SET_PWM(IO) SET_OUTPUT(IO) +#define SET_PWM SET_OUTPUT #define IS_INPUT(IO) _IS_INPUT(IO) #define IS_OUTPUT(IO) _IS_OUTPUT(IO) diff --git a/Marlin/src/HAL/HAL_AVR/fastio/fastio_1280.h b/Marlin/src/HAL/AVR/fastio/fastio_1280.h similarity index 99% rename from Marlin/src/HAL/HAL_AVR/fastio/fastio_1280.h rename to Marlin/src/HAL/AVR/fastio/fastio_1280.h index f9f0d3ceee10..f482f823e8b9 100644 --- a/Marlin/src/HAL/HAL_AVR/fastio/fastio_1280.h +++ b/Marlin/src/HAL/AVR/fastio/fastio_1280.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -26,7 +26,7 @@ * * Hardware Pin : 02 03 06 07 01 05 15 16 17 18 23 24 25 26 64 63 13 12 46 45 44 43 78 77 76 75 74 73 72 71 60 59 58 57 56 55 54 53 50 70 52 51 42 41 40 39 38 37 36 35 22 21 20 19 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 | 04 08 09 10 11 14 27 28 29 30 31 32 33 34 47 48 49 61 62 65 66 67 68 69 79 80 81 98 99 100 * Port : E0 E1 E4 E5 G5 E3 H3 H4 H5 H6 B4 B5 B6 B7 J1 J0 H1 H0 D3 D2 D1 D0 A0 A1 A2 A3 A4 A5 A6 A7 C7 C6 C5 C4 C3 C2 C1 C0 D7 G2 G1 G0 L7 L6 L5 L4 L3 L2 L1 L0 B3 B2 B1 B0 F0 F1 F2 F3 F4 F5 F6 F7 K0 K1 K2 K3 K4 K5 K6 K7 | E2 E6 E7 xx xx H2 H7 G3 G4 xx xx xx xx xx D4 D5 D6 xx xx J2 J3 J4 J5 J6 J7 xx xx xx xx xx - * Logical Pin : 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 78 79 80 xx xx 84 85 71 70 xx xx xx xx xx 81 82 83 xx xx 72 72 75 76 77 74 xx xx xx xx xx + * Logical Pin : 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 78 79 80 xx xx 84 85 71 70 xx xx xx xx xx 81 82 83 xx xx 72 73 75 76 77 74 xx xx xx xx xx */ #include "../fastio.h" diff --git a/Marlin/src/HAL/HAL_AVR/fastio/fastio_1281.h b/Marlin/src/HAL/AVR/fastio/fastio_1281.h similarity index 99% rename from Marlin/src/HAL/HAL_AVR/fastio/fastio_1281.h rename to Marlin/src/HAL/AVR/fastio/fastio_1281.h index 7552540ffee6..e0bc5e2995d1 100644 --- a/Marlin/src/HAL/HAL_AVR/fastio/fastio_1281.h +++ b/Marlin/src/HAL/AVR/fastio/fastio_1281.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_AVR/fastio/fastio_168.h b/Marlin/src/HAL/AVR/fastio/fastio_168.h similarity index 99% rename from Marlin/src/HAL/HAL_AVR/fastio/fastio_168.h rename to Marlin/src/HAL/AVR/fastio/fastio_168.h index 549e0246d5af..8cfdd1e8f825 100644 --- a/Marlin/src/HAL/HAL_AVR/fastio/fastio_168.h +++ b/Marlin/src/HAL/AVR/fastio/fastio_168.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_AVR/fastio/fastio_644.h b/Marlin/src/HAL/AVR/fastio/fastio_644.h similarity index 99% rename from Marlin/src/HAL/HAL_AVR/fastio/fastio_644.h rename to Marlin/src/HAL/AVR/fastio/fastio_644.h index 3a48c109e97e..f4a9427e0abf 100644 --- a/Marlin/src/HAL/HAL_AVR/fastio/fastio_644.h +++ b/Marlin/src/HAL/AVR/fastio/fastio_644.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_AVR/fastio/fastio_AT90USB.h b/Marlin/src/HAL/AVR/fastio/fastio_AT90USB.h similarity index 99% rename from Marlin/src/HAL/HAL_AVR/fastio/fastio_AT90USB.h rename to Marlin/src/HAL/AVR/fastio/fastio_AT90USB.h index 23d16a20e565..51d400b70565 100644 --- a/Marlin/src/HAL/HAL_AVR/fastio/fastio_AT90USB.h +++ b/Marlin/src/HAL/AVR/fastio/fastio_AT90USB.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_LPC1768/persistent_store_api.h b/Marlin/src/HAL/AVR/inc/Conditionals_LCD.h similarity index 82% rename from Marlin/src/HAL/HAL_LPC1768/persistent_store_api.h rename to Marlin/src/HAL/AVR/inc/Conditionals_LCD.h index 55a58fde1dfb..a611ccd7c4a9 100644 --- a/Marlin/src/HAL/HAL_LPC1768/persistent_store_api.h +++ b/Marlin/src/HAL/AVR/inc/Conditionals_LCD.h @@ -16,11 +16,11 @@ * 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 . + * along with this program. If not, see . * */ #pragma once -#include "../shared/persistent_store_api.h" - -#define FLASH_EEPROM_EMULATION +#if HAS_SPI_TFT || HAS_FSMC_TFT + #error "Sorry! TFT displays are not available for HAL/AVR." +#endif diff --git a/Marlin/src/HAL/HAL_AVR/inc/Conditionals_adv.h b/Marlin/src/HAL/AVR/inc/Conditionals_adv.h similarity index 91% rename from Marlin/src/HAL/HAL_AVR/inc/Conditionals_adv.h rename to Marlin/src/HAL/AVR/inc/Conditionals_adv.h index 0285c52ee365..5f1c4b16019d 100644 --- a/Marlin/src/HAL/HAL_AVR/inc/Conditionals_adv.h +++ b/Marlin/src/HAL/AVR/inc/Conditionals_adv.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_DUE/inc/Conditionals_post.h b/Marlin/src/HAL/AVR/inc/Conditionals_post.h similarity index 91% rename from Marlin/src/HAL/HAL_DUE/inc/Conditionals_post.h rename to Marlin/src/HAL/AVR/inc/Conditionals_post.h index 0285c52ee365..5f1c4b16019d 100644 --- a/Marlin/src/HAL/HAL_DUE/inc/Conditionals_post.h +++ b/Marlin/src/HAL/AVR/inc/Conditionals_post.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_AVR/inc/SanityCheck.h b/Marlin/src/HAL/AVR/inc/SanityCheck.h similarity index 75% rename from Marlin/src/HAL/HAL_AVR/inc/SanityCheck.h rename to Marlin/src/HAL/AVR/inc/SanityCheck.h index 87864bcaf67b..731cf9286582 100644 --- a/Marlin/src/HAL/HAL_AVR/inc/SanityCheck.h +++ b/Marlin/src/HAL/AVR/inc/SanityCheck.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,16 +25,6 @@ * Test AVR-specific configuration values for errors at compile-time. */ -/** - * Digipot requirement - */ - #if ENABLED(DIGIPOT_MCP4018) - #if !defined(DIGIPOTS_I2C_SDA_X) || !defined(DIGIPOTS_I2C_SDA_Y) || !defined(DIGIPOTS_I2C_SDA_Z) \ - || !defined(DIGIPOTS_I2C_SDA_E0) || !defined(DIGIPOTS_I2C_SDA_E1) - #error "DIGIPOT_MCP4018 requires DIGIPOTS_I2C_SDA_* pins to be defined." - #endif -#endif - /** * Checks for FAST PWM */ @@ -46,20 +36,23 @@ * Sanity checks for Spindle / Laser PWM */ #if ENABLED(SPINDLE_LASER_PWM) + #include "../ServoTimers.h" // Needed to check timer availability (_useTimer3) #if SPINDLE_LASER_PWM_PIN == 4 || WITHIN(SPINDLE_LASER_PWM_PIN, 11, 13) #error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by a system interrupt." - #elif NUM_SERVOS > 0 && (WITHIN(SPINDLE_LASER_PWM_PIN, 2, 3) || SPINDLE_LASER_PWM_PIN == 5) + #elif NUM_SERVOS > 0 && defined(_useTimer3) && (WITHIN(SPINDLE_LASER_PWM_PIN, 2, 3) || SPINDLE_LASER_PWM_PIN == 5) #error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by the servo system." #endif +#elif defined(SPINDLE_LASER_FREQUENCY) + #error "SPINDLE_LASER_FREQUENCY requires SPINDLE_LASER_PWM." #endif /** * The Trinamic library includes SoftwareSerial.h, leading to a compile error. */ -#if HAS_TRINAMIC && ENABLED(ENDSTOP_INTERRUPTS_FEATURE) +#if BOTH(HAS_TRINAMIC_CONFIG, ENDSTOP_INTERRUPTS_FEATURE) #error "TMCStepper includes SoftwareSerial.h which is incompatible with ENDSTOP_INTERRUPTS_FEATURE. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." #endif -#if HAS_TMC_SW_SERIAL && ENABLED(MONITOR_DRIVER_STATUS) +#if BOTH(HAS_TMC_SW_SERIAL, MONITOR_DRIVER_STATUS) #error "MONITOR_DRIVER_STATUS causes performance issues when used with SoftwareSerial-connected drivers. Disable MONITOR_DRIVER_STATUS or use hardware serial to continue." #endif diff --git a/Marlin/src/HAL/HAL_AVR/math.h b/Marlin/src/HAL/AVR/math.h similarity index 97% rename from Marlin/src/HAL/HAL_AVR/math.h rename to Marlin/src/HAL/AVR/math.h index e8be0a04bcf5..7ede4accc09e 100644 --- a/Marlin/src/HAL/HAL_AVR/math.h +++ b/Marlin/src/HAL/AVR/math.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_AVR/pinsDebug.h b/Marlin/src/HAL/AVR/pinsDebug.h similarity index 97% rename from Marlin/src/HAL/HAL_AVR/pinsDebug.h rename to Marlin/src/HAL/AVR/pinsDebug.h index cea82ef3fa28..dac6b1b150bd 100644 --- a/Marlin/src/HAL/HAL_AVR/pinsDebug.h +++ b/Marlin/src/HAL/AVR/pinsDebug.h @@ -13,7 +13,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -26,7 +26,9 @@ #define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS -#define AVR_ATmega2560_FAMILY_PLUS_70 MB(BQ_ZUM_MEGA_3D, MIGHTYBOARD_REVE, MINIRAMBO, SCOOVO_X9H) +#if MB(BQ_ZUM_MEGA_3D, MIGHTYBOARD_REVE, MINIRAMBO, SCOOVO_X9H, TRIGORILLA_14) + #define AVR_ATmega2560_FAMILY_PLUS_70 1 +#endif #if AVR_AT90USB1286_FAMILY @@ -70,12 +72,12 @@ void PRINT_ARRAY_NAME(uint8_t x) { char *name_mem_pointer = (char*)pgm_read_ptr(&pin_array[x].name); - for (uint8_t y = 0; y < MAX_NAME_LENGTH; y++) { + LOOP_L_N(y, MAX_NAME_LENGTH) { char temp_char = pgm_read_byte(name_mem_pointer + y); if (temp_char != 0) SERIAL_CHAR(temp_char); else { - for (uint8_t i = 0; i < MAX_NAME_LENGTH - y; i++) SERIAL_CHAR(' '); + LOOP_L_N(i, MAX_NAME_LENGTH - y) SERIAL_CHAR(' '); break; } } diff --git a/Marlin/src/HAL/HAL_AVR/pinsDebug_Teensyduino.h b/Marlin/src/HAL/AVR/pinsDebug_Teensyduino.h similarity index 97% rename from Marlin/src/HAL/HAL_AVR/pinsDebug_Teensyduino.h rename to Marlin/src/HAL/AVR/pinsDebug_Teensyduino.h index f6da0777436d..051972a861ad 100644 --- a/Marlin/src/HAL/HAL_AVR/pinsDebug_Teensyduino.h +++ b/Marlin/src/HAL/AVR/pinsDebug_Teensyduino.h @@ -13,7 +13,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_AVR/pinsDebug_plus_70.h b/Marlin/src/HAL/AVR/pinsDebug_plus_70.h similarity index 97% rename from Marlin/src/HAL/HAL_AVR/pinsDebug_plus_70.h rename to Marlin/src/HAL/AVR/pinsDebug_plus_70.h index 6e7b8fbaa952..db3fdf1f767b 100644 --- a/Marlin/src/HAL/HAL_AVR/pinsDebug_plus_70.h +++ b/Marlin/src/HAL/AVR/pinsDebug_plus_70.h @@ -13,7 +13,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -22,15 +22,12 @@ * Structures for 2560 family boards that use more than 70 pins */ -#undef NUM_DIGITAL_PINS -#if MB(BQ_ZUM_MEGA_3D) +#if MB(BQ_ZUM_MEGA_3D, MINIRAMBO, SCOOVO_X9H, TRIGORILLA_14) + #undef NUM_DIGITAL_PINS #define NUM_DIGITAL_PINS 85 #elif MB(MIGHTYBOARD_REVE) + #undef NUM_DIGITAL_PINS #define NUM_DIGITAL_PINS 80 -#elif MB(MINIRAMBO) - #define NUM_DIGITAL_PINS 85 -#elif MB(SCOOVO_X9H) - #define NUM_DIGITAL_PINS 85 #endif #define PA 1 diff --git a/Marlin/src/HAL/HAL_AVR/spi_pins.h b/Marlin/src/HAL/AVR/spi_pins.h similarity index 96% rename from Marlin/src/HAL/HAL_AVR/spi_pins.h rename to Marlin/src/HAL/AVR/spi_pins.h index daaebb76d701..f3fa78e2bfaf 100644 --- a/Marlin/src/HAL/HAL_AVR/spi_pins.h +++ b/Marlin/src/HAL/AVR/spi_pins.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_AVR/HAL.h b/Marlin/src/HAL/AVR/timers.h similarity index 69% rename from Marlin/src/HAL/HAL_AVR/HAL.h rename to Marlin/src/HAL/AVR/timers.h index 025516981955..82eb8b14b161 100644 --- a/Marlin/src/HAL/HAL_AVR/HAL.h +++ b/Marlin/src/HAL/AVR/timers.h @@ -14,54 +14,12 @@ * 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 . + * along with this program. If not, see . + * */ #pragma once -#include "../shared/Marduino.h" -#include "../shared/HAL_SPI.h" -#include "fastio.h" -#include "watchdog.h" -#include "math.h" - -#ifdef USBCON - #include -#else - #define HardwareSerial_h // Hack to prevent HardwareSerial.h header inclusion - #include "MarlinSerial.h" -#endif - #include -#include -#include -#include -#include -#include - -#ifndef pgm_read_ptr - // Compatibility for avr-libc 1.8.0-4.1 included with Ubuntu for - // Windows Subsystem for Linux on Windows 10 as of 10/18/2019 - #define pgm_read_ptr_far(address_long) (void*)__ELPM_word((uint32_t)(address_long)) - #define pgm_read_ptr_near(address_short) (void*)__LPM_word((uint16_t)(address_short)) - #define pgm_read_ptr(address_short) pgm_read_ptr_near(address_short) -#endif - -// ------------------------ -// Defines -// ------------------------ - -//#define analogInputToDigitalPin(IO) IO - -#ifndef CRITICAL_SECTION_START - #define CRITICAL_SECTION_START() unsigned char _sreg = SREG; cli() - #define CRITICAL_SECTION_END() SREG = _sreg -#endif -#define ISRS_ENABLED() TEST(SREG, SREG_I) -#define ENABLE_ISRS() sei() -#define DISABLE_ISRS() cli() - -// On AVR this is in math.h? -//#define square(x) ((x)*(x)) // ------------------------ // Types @@ -70,84 +28,21 @@ typedef uint16_t hal_timer_t; #define HAL_TIMER_TYPE_MAX 0xFFFF -typedef int8_t pin_t; - -#define SHARED_SERVOS HAS_SERVOS -#define HAL_SERVO_LIB Servo - // ------------------------ -// Public Variables +// Defines // ------------------------ -//extern uint8_t MCUSR; - -// Serial ports -#ifdef USBCON - #if ENABLED(BLUETOOTH) - #define MYSERIAL0 bluetoothSerial - #else - #define MYSERIAL0 Serial - #endif - #define NUM_SERIAL 1 -#else - #if !WITHIN(SERIAL_PORT, -1, 3) - #error "SERIAL_PORT must be from -1 to 3. Please update your configuration." - #endif - - #define MYSERIAL0 customizedSerial1 +#define HAL_TIMER_RATE ((F_CPU) / 8) // i.e., 2MHz or 2.5MHz - #ifdef SERIAL_PORT_2 - #if !WITHIN(SERIAL_PORT_2, -1, 3) - #error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration." - #elif SERIAL_PORT_2 == SERIAL_PORT - #error "SERIAL_PORT_2 must be different than SERIAL_PORT. Please update your configuration." - #endif - #define MYSERIAL1 customizedSerial2 - #define NUM_SERIAL 2 - #else - #define NUM_SERIAL 1 - #endif +#ifndef STEP_TIMER_NUM + #define STEP_TIMER_NUM 1 #endif - -#ifdef DGUS_SERIAL_PORT - #if !WITHIN(DGUS_SERIAL_PORT, -1, 3) - #error "DGUS_SERIAL_PORT must be from -1 to 3. Please update your configuration." - #elif DGUS_SERIAL_PORT == SERIAL_PORT - #error "DGUS_SERIAL_PORT must be different than SERIAL_PORT. Please update your configuration." - #elif defined(SERIAL_PORT_2) && DGUS_SERIAL_PORT == SERIAL_PORT_2 - #error "DGUS_SERIAL_PORT must be different than SERIAL_PORT_2. Please update your configuration." - #endif - #define DGUS_SERIAL internalDgusSerial - - #define DGUS_SERIAL_GET_TX_BUFFER_FREE DGUS_SERIAL.get_tx_buffer_free +#ifndef PULSE_TIMER_NUM + #define PULSE_TIMER_NUM STEP_TIMER_NUM +#endif +#ifndef TEMP_TIMER_NUM + #define TEMP_TIMER_NUM 0 #endif - -// ------------------------ -// Public functions -// ------------------------ - -void HAL_init(); - -//void cli(); - -//void _delay_ms(const int delay); - -inline void HAL_clear_reset_source() { MCUSR = 0; } -inline uint8_t HAL_get_reset_source() { return MCUSR; } - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-function" -extern "C" { - int freeMemory(); -} -#pragma GCC diagnostic pop - -// timers -#define HAL_TIMER_RATE ((F_CPU) / 8) // i.e., 2MHz or 2.5MHz - -#define STEP_TIMER_NUM 1 -#define TEMP_TIMER_NUM 0 -#define PULSE_TIMER_NUM STEP_TIMER_NUM #define TEMP_TIMER_FREQUENCY ((F_CPU) / 64.0 / 256.0) @@ -218,6 +113,8 @@ FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t) { #define HAL_timer_isr_epilogue(TIMER_NUM) /* 18 cycles maximum latency */ +#ifndef HAL_STEP_TIMER_ISR + #define HAL_STEP_TIMER_ISR() \ extern "C" void TIMER1_COMPA_vect() __attribute__ ((signal, naked, used, externally_visible)); \ extern "C" void TIMER1_COMPA_vect_bottom() asm ("TIMER1_COMPA_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \ @@ -290,6 +187,10 @@ void TIMER1_COMPA_vect() { \ } \ void TIMER1_COMPA_vect_bottom() +#endif // HAL_STEP_TIMER_ISR + +#ifndef HAL_TEMP_TIMER_ISR + /* 14 cycles maximum latency */ #define HAL_TEMP_TIMER_ISR() \ extern "C" void TIMER0_COMPB_vect() __attribute__ ((signal, naked, used, externally_visible)); \ @@ -356,60 +257,4 @@ void TIMER0_COMPB_vect() { \ } \ void TIMER0_COMPB_vect_bottom() -// ADC -#ifdef DIDR2 - #define HAL_ANALOG_SELECT(ind) do{ if (ind < 8) SBI(DIDR0, ind); else SBI(DIDR2, ind & 0x07); }while(0) -#else - #define HAL_ANALOG_SELECT(ind) SBI(DIDR0, ind); -#endif - -inline void HAL_adc_init() { - ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADIF) | 0x07; - DIDR0 = 0; - #ifdef DIDR2 - DIDR2 = 0; - #endif -} - -#define SET_ADMUX_ADCSRA(ch) ADMUX = _BV(REFS0) | (ch & 0x07); SBI(ADCSRA, ADSC) -#ifdef MUX5 - #define HAL_START_ADC(ch) if (ch > 7) ADCSRB = _BV(MUX5); else ADCSRB = 0; SET_ADMUX_ADCSRA(ch) -#else - #define HAL_START_ADC(ch) ADCSRB = 0; SET_ADMUX_ADCSRA(ch) -#endif - -#define HAL_ADC_RESOLUTION 10 -#define HAL_READ_ADC() ADC -#define HAL_ADC_READY() !TEST(ADCSRA, ADSC) - -#define GET_PIN_MAP_PIN(index) index -#define GET_PIN_MAP_INDEX(pin) pin -#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval) - -#define HAL_SENSITIVE_PINS 0, 1 - -#ifdef __AVR_AT90USB1286__ - #define JTAG_DISABLE() do{ MCUCR = 0x80; MCUCR = 0x80; }while(0) -#endif - -// AVR compatibility -#define strtof strtod - -/** - * set_pwm_frequency - * Sets the frequency of the timer corresponding to the provided pin - * as close as possible to the provided desired frequency. Internally - * calculates the required waveform generation mode, prescaler and - * resolution values required and sets the timer registers accordingly. - * NOTE that the frequency is applied to all pins on the timer (Ex OC3A, OC3B and OC3B) - * NOTE that there are limitations, particularly if using TIMER2. (see Configuration_adv.h -> FAST FAN PWM Settings) - */ -void set_pwm_frequency(const pin_t pin, int f_desired); - -/** - * set_pwm_duty - * Sets the PWM duty cycle of the provided pin to the provided value - * Optionally allows inverting the duty cycle [default = false] - * Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255] - */ -void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false); +#endif // HAL_TEMP_TIMER_ISR diff --git a/Marlin/src/HAL/HAL_AVR/u8g_com_HAL_AVR_sw_spi.cpp b/Marlin/src/HAL/AVR/u8g_com_HAL_AVR_sw_spi.cpp similarity index 96% rename from Marlin/src/HAL/HAL_AVR/u8g_com_HAL_AVR_sw_spi.cpp rename to Marlin/src/HAL/AVR/u8g_com_HAL_AVR_sw_spi.cpp index 60b4e8310496..cb95a48cccec 100644 --- a/Marlin/src/HAL/HAL_AVR/u8g_com_HAL_AVR_sw_spi.cpp +++ b/Marlin/src/HAL/AVR/u8g_com_HAL_AVR_sw_spi.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -57,7 +57,7 @@ #include "../../inc/MarlinConfigPre.h" -#if HAS_GRAPHICAL_LCD +#if HAS_MARLINUI_U8GLIB #include "../shared/Marduino.h" #include "../shared/Delay.h" @@ -88,7 +88,7 @@ void u8g_spiSend_sw_AVR_mode_0(uint8_t val) { volatile uint8_t *outData = u8g_outData, *outClock = u8g_outClock; U8G_ATOMIC_START(); - for (uint8_t i = 0; i < 8; i++) { + LOOP_L_N(i, 8) { if (val & 0x80) *outData |= bitData; else @@ -108,7 +108,7 @@ void u8g_spiSend_sw_AVR_mode_3(uint8_t val) { volatile uint8_t *outData = u8g_outData, *outClock = u8g_outClock; U8G_ATOMIC_START(); - for (uint8_t i = 0; i < 8; i++) { + LOOP_L_N(i, 8) { *outClock &= bitNotClock; if (val & 0x80) *outData |= bitData; @@ -189,5 +189,5 @@ uint8_t u8g_com_HAL_AVR_sw_sp_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void return 1; } -#endif // HAS_GRAPHICAL_LCD +#endif // HAS_MARLINUI_U8GLIB #endif // ARDUINO_ARCH_SAM diff --git a/Marlin/src/HAL/HAL_AVR/watchdog.cpp b/Marlin/src/HAL/AVR/watchdog.cpp similarity index 97% rename from Marlin/src/HAL/HAL_AVR/watchdog.cpp rename to Marlin/src/HAL/AVR/watchdog.cpp index e35a70f2ccbc..3f10c4adff81 100644 --- a/Marlin/src/HAL/HAL_AVR/watchdog.cpp +++ b/Marlin/src/HAL/AVR/watchdog.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef __AVR__ #include "../../inc/MarlinConfig.h" diff --git a/Marlin/src/HAL/HAL_AVR/watchdog.h b/Marlin/src/HAL/AVR/watchdog.h similarity index 93% rename from Marlin/src/HAL/HAL_AVR/watchdog.h rename to Marlin/src/HAL/AVR/watchdog.h index 57dfcfc0bf68..a16c88b35e87 100644 --- a/Marlin/src/HAL/HAL_AVR/watchdog.h +++ b/Marlin/src/HAL/AVR/watchdog.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_DUE/DebugMonitor.cpp b/Marlin/src/HAL/DUE/DebugMonitor.cpp similarity index 99% rename from Marlin/src/HAL/HAL_DUE/DebugMonitor.cpp rename to Marlin/src/HAL/DUE/DebugMonitor.cpp index 3ed9873e66ce..79759151d891 100644 --- a/Marlin/src/HAL/HAL_DUE/DebugMonitor.cpp +++ b/Marlin/src/HAL/DUE/DebugMonitor.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef ARDUINO_ARCH_SAM #include "../../core/macros.h" diff --git a/Marlin/src/HAL/HAL_DUE/HAL.cpp b/Marlin/src/HAL/DUE/HAL.cpp similarity index 93% rename from Marlin/src/HAL/HAL_DUE/HAL.cpp rename to Marlin/src/HAL/DUE/HAL.cpp index cb381ff4bb61..6ce85a4643bb 100644 --- a/Marlin/src/HAL/HAL_DUE/HAL.cpp +++ b/Marlin/src/HAL/DUE/HAL.cpp @@ -14,13 +14,12 @@ * 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 . + * along with this program. If not, see . + * */ /** - * Description: HAL for Arduino Due and compatible (SAM3X8E) - * - * For ARDUINO_ARCH_SAM + * HAL for Arduino Due and compatible (SAM3X8E) */ #ifdef ARDUINO_ARCH_SAM diff --git a/Marlin/src/HAL/HAL_DUE/HAL.h b/Marlin/src/HAL/DUE/HAL.h similarity index 65% rename from Marlin/src/HAL/HAL_DUE/HAL.h rename to Marlin/src/HAL/DUE/HAL.h index 97b94b5db234..88ace5957535 100644 --- a/Marlin/src/HAL/HAL_DUE/HAL.h +++ b/Marlin/src/HAL/DUE/HAL.h @@ -16,85 +16,59 @@ * 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 . + * along with this program. If not, see . * */ #pragma once /** - * Description: HAL for Arduino Due and compatible (SAM3X8E) - * - * For ARDUINO_ARCH_SAM + * HAL for Arduino Due and compatible (SAM3X8E) */ #define CPU_32_BIT #include "../shared/Marduino.h" +#include "../shared/eeprom_if.h" #include "../shared/math_32bit.h" #include "../shared/HAL_SPI.h" #include "fastio.h" #include "watchdog.h" -#include "timers.h" #include +#define _MSERIAL(X) Serial##X +#define MSERIAL(X) _MSERIAL(X) +#define Serial0 Serial + // Define MYSERIAL0/1 before MarlinSerial includes! -#if SERIAL_PORT == -1 +#if SERIAL_PORT == -1 || ENABLED(EMERGENCY_PARSER) #define MYSERIAL0 customizedSerial1 -#elif SERIAL_PORT == 0 - #define MYSERIAL0 Serial -#elif SERIAL_PORT == 1 - #define MYSERIAL0 Serial1 -#elif SERIAL_PORT == 2 - #define MYSERIAL0 Serial2 -#elif SERIAL_PORT == 3 - #define MYSERIAL0 Serial3 +#elif WITHIN(SERIAL_PORT, 0, 3) + #define MYSERIAL0 MSERIAL(SERIAL_PORT) #else #error "The required SERIAL_PORT must be from -1 to 3. Please update your configuration." #endif #ifdef SERIAL_PORT_2 - #if SERIAL_PORT_2 == SERIAL_PORT - #error "SERIAL_PORT_2 must be different from SERIAL_PORT. Please update your configuration." - #elif SERIAL_PORT_2 == -1 + #if SERIAL_PORT_2 == -1 || ENABLED(EMERGENCY_PARSER) #define MYSERIAL1 customizedSerial2 - #elif SERIAL_PORT_2 == 0 - #define MYSERIAL1 Serial - #elif SERIAL_PORT_2 == 1 - #define MYSERIAL1 Serial1 - #elif SERIAL_PORT_2 == 2 - #define MYSERIAL1 Serial2 - #elif SERIAL_PORT_2 == 3 - #define MYSERIAL1 Serial3 + #elif WITHIN(SERIAL_PORT_2, 0, 3) + #define MYSERIAL1 MSERIAL(SERIAL_PORT_2) #else #error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration." #endif - #define NUM_SERIAL 2 -#else - #define NUM_SERIAL 1 #endif -#ifdef DGUS_SERIAL_PORT - #if DGUS_SERIAL_PORT == SERIAL_PORT - #error "DGUS_SERIAL_PORT must be different from SERIAL_PORT. Please update your configuration." - #elif defined(SERIAL_PORT_2) && DGUS_SERIAL_PORT == SERIAL_PORT_2 - #error "DGUS_SERIAL_PORT must be different than SERIAL_PORT_2. Please update your configuration." - #elif DGUS_SERIAL_PORT == -1 - #define DGUS_SERIAL internalDgusSerial - #elif DGUS_SERIAL_PORT == 0 - #define DGUS_SERIAL Serial - #elif DGUS_SERIAL_PORT == 1 - #define DGUS_SERIAL Serial1 - #elif DGUS_SERIAL_PORT == 2 - #define DGUS_SERIAL Serial2 - #elif DGUS_SERIAL_PORT == 3 - #define DGUS_SERIAL Serial3 +#ifdef LCD_SERIAL_PORT + #if LCD_SERIAL_PORT == -1 + #define LCD_SERIAL lcdSerial + #elif WITHIN(LCD_SERIAL_PORT, 0, 3) + #define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT) #else - #error "DGUS_SERIAL_PORT must be from -1 to 3. Please update your configuration." + #error "LCD_SERIAL_PORT must be from -1 to 3. Please update your configuration." #endif #endif - #include "MarlinSerial.h" #include "MarlinSerialUSB.h" @@ -131,13 +105,7 @@ void sei(); // Enable interrupts void HAL_clear_reset_source(); // clear reset reason uint8_t HAL_get_reset_source(); // get reset reason -// -// EEPROM -// -void eeprom_write_byte(uint8_t *pos, unsigned char value); -uint8_t eeprom_read_byte(uint8_t *pos); -void eeprom_read_block (void *__dst, const void *__src, size_t __n); -void eeprom_update_block (const void *__src, void *__dst, size_t __n); +inline void HAL_reboot() {} // reboot the board or restart the bootloader // // ADC @@ -145,15 +113,16 @@ void eeprom_update_block (const void *__src, void *__dst, size_t __n); extern uint16_t HAL_adc_result; // result of last ADC conversion #ifndef analogInputToDigitalPin - #define analogInputToDigitalPin(p) ((p < 12u) ? (p) + 54u : -1) + #define analogInputToDigitalPin(p) ((p < 12U) ? (p) + 54U : -1) #endif #define HAL_ANALOG_SELECT(ch) inline void HAL_adc_init() {}//todo -#define HAL_START_ADC(ch) HAL_adc_start_conversion(ch) +#define HAL_ADC_VREF 3.3 #define HAL_ADC_RESOLUTION 10 +#define HAL_START_ADC(ch) HAL_adc_start_conversion(ch) #define HAL_READ_ADC() HAL_adc_result #define HAL_ADC_READY() true diff --git a/Marlin/src/HAL/HAL_DUE/HAL_SPI.cpp b/Marlin/src/HAL/DUE/HAL_SPI.cpp similarity index 99% rename from Marlin/src/HAL/HAL_DUE/HAL_SPI.cpp rename to Marlin/src/HAL/DUE/HAL_SPI.cpp index 97a6fa05a1f2..0451d8bcc4ff 100644 --- a/Marlin/src/HAL/HAL_DUE/HAL_SPI.cpp +++ b/Marlin/src/HAL/DUE/HAL_SPI.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -30,7 +30,7 @@ */ /** - * Description: HAL for Arduino Due and compatible (SAM3X8E) + * HAL for Arduino Due and compatible (SAM3X8E) * * For ARDUINO_ARCH_SAM */ @@ -595,7 +595,7 @@ SPI_Enable(SPI0); SET_OUTPUT(DAC0_SYNC); - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER SET_OUTPUT(DAC1_SYNC); WRITE(DAC1_SYNC, HIGH); #endif @@ -759,7 +759,6 @@ * * All of the above can be avoided by defining FORCE_SOFT_SPI to force the * display to use software SPI. - * */ void spiInit(uint8_t spiRate=6) { // Default to slowest rate if not specified) diff --git a/Marlin/src/HAL/HAL_DUE/InterruptVectors.cpp b/Marlin/src/HAL/DUE/InterruptVectors.cpp similarity index 97% rename from Marlin/src/HAL/HAL_DUE/InterruptVectors.cpp rename to Marlin/src/HAL/DUE/InterruptVectors.cpp index 7964f2d1f680..e4e0ce99f2b5 100644 --- a/Marlin/src/HAL/HAL_DUE/InterruptVectors.cpp +++ b/Marlin/src/HAL/DUE/InterruptVectors.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/HAL/HAL_DUE/InterruptVectors.h b/Marlin/src/HAL/DUE/InterruptVectors.h similarity index 95% rename from Marlin/src/HAL/HAL_DUE/InterruptVectors.h rename to Marlin/src/HAL/DUE/InterruptVectors.h index 534cd17f42bb..6faeb34b7a3e 100644 --- a/Marlin/src/HAL/HAL_DUE/InterruptVectors.h +++ b/Marlin/src/HAL/DUE/InterruptVectors.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_DUE/MarlinSerial.cpp b/Marlin/src/HAL/DUE/MarlinSerial.cpp similarity index 97% rename from Marlin/src/HAL/HAL_DUE/MarlinSerial.cpp rename to Marlin/src/HAL/DUE/MarlinSerial.cpp index 3cd6f7d5ed34..c9a372eeb14f 100644 --- a/Marlin/src/HAL/HAL_DUE/MarlinSerial.cpp +++ b/Marlin/src/HAL/DUE/MarlinSerial.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -45,7 +45,7 @@ template typename MarlinSerial::ring_buffer_pos_t MarlinSeria // A SW memory barrier, to ensure GCC does not overoptimize loops #define sw_barrier() asm volatile("": : :"memory"); -#include "../../feature/emergency_parser.h" +#include "../../feature/e_parser.h" // (called with RX interrupts disabled) template @@ -606,7 +606,7 @@ void MarlinSerial::printFloat(double number, uint8_t digits) { // Round correctly so that print(1.999, 2) prints as "2.00" double rounding = 0.5; - for (uint8_t i = 0; i < digits; ++i) rounding *= 0.1; + LOOP_L_N(i, digits) rounding *= 0.1; number += rounding; // Extract the integer part of the number and print it @@ -629,23 +629,13 @@ void MarlinSerial::printFloat(double number, uint8_t digits) { // If not using the USB port as serial port #if SERIAL_PORT >= 0 - - // Preinstantiate - template class MarlinSerial>; - - // Instantiate - MarlinSerial> customizedSerial1; - + template class MarlinSerial>; // Define + MarlinSerial> customizedSerial1; // Instantiate #endif -#ifdef SERIAL_PORT_2 - - // Preinstantiate - template class MarlinSerial>; - - // Instantiate - MarlinSerial> customizedSerial2; - +#if defined(SERIAL_PORT_2) && SERIAL_PORT_2 >= 0 + template class MarlinSerial>; // Define + MarlinSerial> customizedSerial2; // Instantiate #endif #endif // ARDUINO_ARCH_SAM diff --git a/Marlin/src/HAL/HAL_DUE/MarlinSerial.h b/Marlin/src/HAL/DUE/MarlinSerial.h similarity index 89% rename from Marlin/src/HAL/HAL_DUE/MarlinSerial.h rename to Marlin/src/HAL/DUE/MarlinSerial.h index af7d2b7adeef..a194eba2f386 100644 --- a/Marlin/src/HAL/HAL_DUE/MarlinSerial.h +++ b/Marlin/src/HAL/DUE/MarlinSerial.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -27,10 +27,10 @@ * Based on MarlinSerial for AVR, copyright (c) 2006 Nicholas Zambetti. All right reserved. */ -#include "../shared/MarlinSerial.h" - #include +#include "../../inc/MarlinConfigPre.h" + #define DEC 10 #define HEX 16 #define OCT 8 @@ -122,6 +122,8 @@ class MarlinSerial { static void write(const uint8_t c); static void flushTX(); + static inline bool emergency_parser_enabled() { return Cfg::EMERGENCYPARSER; } + FORCE_INLINE static uint8_t dropped() { return Cfg::DROPPED_RX ? rx_dropped_bytes : 0; } FORCE_INLINE static uint8_t buffer_overruns() { return Cfg::RX_OVERRUNS ? rx_buffer_overruns : 0; } FORCE_INLINE static uint8_t framing_errors() { return Cfg::RX_FRAMING_ERRORS ? rx_framing_errors : 0; } @@ -163,22 +165,18 @@ struct MarlinSerialCfg { static constexpr int PORT = serial; static constexpr unsigned int RX_SIZE = RX_BUFFER_SIZE; static constexpr unsigned int TX_SIZE = TX_BUFFER_SIZE; - static constexpr bool XONOFF = bSERIAL_XON_XOFF; - static constexpr bool EMERGENCYPARSER = bEMERGENCY_PARSER; - static constexpr bool DROPPED_RX = bSERIAL_STATS_DROPPED_RX; - static constexpr bool RX_OVERRUNS = bSERIAL_STATS_RX_BUFFER_OVERRUNS; - static constexpr bool RX_FRAMING_ERRORS = bSERIAL_STATS_RX_FRAMING_ERRORS; - static constexpr bool MAX_RX_QUEUED = bSERIAL_STATS_MAX_RX_QUEUED; + static constexpr bool XONOFF = ENABLED(SERIAL_XON_XOFF); + static constexpr bool EMERGENCYPARSER = ENABLED(EMERGENCY_PARSER); + static constexpr bool DROPPED_RX = ENABLED(SERIAL_STATS_DROPPED_RX); + static constexpr bool RX_OVERRUNS = ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS); + static constexpr bool RX_FRAMING_ERRORS = ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS); + static constexpr bool MAX_RX_QUEUED = ENABLED(SERIAL_STATS_MAX_RX_QUEUED); }; #if SERIAL_PORT >= 0 - extern MarlinSerial> customizedSerial1; +#endif -#endif // SERIAL_PORT >= 0 - -#ifdef SERIAL_PORT_2 - +#if defined(SERIAL_PORT_2) && SERIAL_PORT_2 >= 0 extern MarlinSerial> customizedSerial2; - #endif diff --git a/Marlin/src/HAL/HAL_DUE/MarlinSerialUSB.cpp b/Marlin/src/HAL/DUE/MarlinSerialUSB.cpp similarity index 93% rename from Marlin/src/HAL/HAL_DUE/MarlinSerialUSB.cpp rename to Marlin/src/HAL/DUE/MarlinSerialUSB.cpp index 38cdd8f8a15f..a41dbfeb7a57 100644 --- a/Marlin/src/HAL/HAL_DUE/MarlinSerialUSB.cpp +++ b/Marlin/src/HAL/DUE/MarlinSerialUSB.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -29,12 +29,12 @@ #include "../../inc/MarlinConfig.h" -#if SERIAL_PORT == -1 +#if HAS_USB_SERIAL #include "MarlinSerialUSB.h" #if ENABLED(EMERGENCY_PARSER) - #include "../../feature/emergency_parser.h" + #include "../../feature/e_parser.h" #endif // Imports from Atmel USB Stack/CDC implementation @@ -73,9 +73,7 @@ int MarlinSerialUSB::peek() { pending_char = udi_cdc_getc(); - #if ENABLED(EMERGENCY_PARSER) - emergency_parser.update(emergency_state, (char)pending_char); - #endif + TERN_(EMERGENCY_PARSER, emergency_parser.update(emergency_state, (char)pending_char)); return pending_char; } @@ -97,9 +95,7 @@ int MarlinSerialUSB::read() { int c = udi_cdc_getc(); - #if ENABLED(EMERGENCY_PARSER) - emergency_parser.update(emergency_state, (char)c); - #endif + TERN_(EMERGENCY_PARSER, emergency_parser.update(emergency_state, (char)c)); return c; } @@ -259,7 +255,7 @@ void MarlinSerialUSB::printFloat(double number, uint8_t digits) { // Round correctly so that print(1.999, 2) prints as "2.00" double rounding = 0.5; - for (uint8_t i = 0; i < digits; ++i) + LOOP_L_N(i, digits) rounding *= 0.1; number += rounding; @@ -283,8 +279,12 @@ void MarlinSerialUSB::printFloat(double number, uint8_t digits) { } // Preinstantiate -MarlinSerialUSB customizedSerial1; - -#endif // SERIAL_PORT == -1 +#if SERIAL_PORT == -1 + MarlinSerialUSB customizedSerial1; +#endif +#if SERIAL_PORT_2 == -1 + MarlinSerialUSB customizedSerial2; +#endif +#endif // HAS_USB_SERIAL #endif // ARDUINO_ARCH_SAM diff --git a/Marlin/src/HAL/HAL_DUE/MarlinSerialUSB.h b/Marlin/src/HAL/DUE/MarlinSerialUSB.h similarity index 91% rename from Marlin/src/HAL/HAL_DUE/MarlinSerialUSB.h rename to Marlin/src/HAL/DUE/MarlinSerialUSB.h index d8b051d37e01..2e3622e5534a 100644 --- a/Marlin/src/HAL/HAL_DUE/MarlinSerialUSB.h +++ b/Marlin/src/HAL/DUE/MarlinSerialUSB.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -28,7 +28,7 @@ #include "../../inc/MarlinConfig.h" -#if SERIAL_PORT == -1 +#if HAS_USB_SERIAL #include @@ -88,6 +88,12 @@ class MarlinSerialUSB { static void printFloat(double, uint8_t); }; -extern MarlinSerialUSB customizedSerial1; +#if SERIAL_PORT == -1 + extern MarlinSerialUSB customizedSerial1; +#endif + +#if SERIAL_PORT_2 == -1 + extern MarlinSerialUSB customizedSerial2; +#endif -#endif // SERIAL_PORT == -1 +#endif // HAS_USB_SERIAL diff --git a/Marlin/src/HAL/HAL_DUE/Servo.cpp b/Marlin/src/HAL/DUE/Servo.cpp similarity index 98% rename from Marlin/src/HAL/HAL_DUE/Servo.cpp rename to Marlin/src/HAL/DUE/Servo.cpp index 266158bbc6db..5524aa9cef47 100644 --- a/Marlin/src/HAL/HAL_DUE/Servo.cpp +++ b/Marlin/src/HAL/DUE/Servo.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -44,7 +44,6 @@ #if HAS_SERVOS -#include "../shared/Marduino.h" #include "../shared/servo.h" #include "../shared/servo_private.h" diff --git a/Marlin/src/HAL/HAL_DUE/ServoTimers.h b/Marlin/src/HAL/DUE/ServoTimers.h similarity index 100% rename from Marlin/src/HAL/HAL_DUE/ServoTimers.h rename to Marlin/src/HAL/DUE/ServoTimers.h diff --git a/Marlin/src/HAL/HAL_DUE/Tone.cpp b/Marlin/src/HAL/DUE/Tone.cpp similarity index 90% rename from Marlin/src/HAL/HAL_DUE/Tone.cpp rename to Marlin/src/HAL/DUE/Tone.cpp index 9b580b8b4c0b..9beb6022237f 100644 --- a/Marlin/src/HAL/HAL_DUE/Tone.cpp +++ b/Marlin/src/HAL/DUE/Tone.cpp @@ -18,20 +18,19 @@ * 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 . + * along with this program. If not, see . * */ /** * Description: Tone function for Arduino Due and compatible (SAM3X8E) - * Derived from http://forum.arduino.cc/index.php?topic=136500.msg2903012#msg2903012 + * Derived from https://forum.arduino.cc/index.php?topic=136500.msg2903012#msg2903012 */ #ifdef ARDUINO_ARCH_SAM #include "../../inc/MarlinConfig.h" #include "HAL.h" -#include "timers.h" static pin_t tone_pin; volatile static int32_t toggles; diff --git a/Marlin/src/HAL/HAL_DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp similarity index 96% rename from Marlin/src/HAL/HAL_DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp rename to Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp index 0fb8a782e5c4..be4b49c0f992 100644 --- a/Marlin/src/HAL/HAL_DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp +++ b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -52,14 +52,13 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * */ #ifdef __SAM3X8E__ #include "../../../inc/MarlinConfigPre.h" -#if HAS_GRAPHICAL_LCD +#if HAS_MARLINUI_U8GLIB #include @@ -145,6 +144,6 @@ uint8_t u8g_com_HAL_DUE_shared_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_va return 1; } -#endif // HAS_GRAPHICAL_LCD +#endif // HAS_MARLINUI_U8GLIB -#endif //__SAM3X8E__ +#endif // __SAM3X8E__ diff --git a/Marlin/src/HAL/HAL_DUE/dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp similarity index 98% rename from Marlin/src/HAL/HAL_DUE/dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp rename to Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp index 01320ba9b9a4..47060d6a5be2 100644 --- a/Marlin/src/HAL/HAL_DUE/dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp +++ b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/HAL/HAL_DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp similarity index 96% rename from Marlin/src/HAL/HAL_DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp rename to Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp index c4816c3db54d..ea7204fa366b 100644 --- a/Marlin/src/HAL/HAL_DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp +++ b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -57,7 +57,7 @@ #include "../../../inc/MarlinConfigPre.h" -#if HAS_GRAPHICAL_LCD && DISABLED(U8GLIB_ST7920) +#if HAS_MARLINUI_U8GLIB && DISABLED(U8GLIB_ST7920) #undef SPI_SPEED #define SPI_SPEED 2 // About 2 MHz @@ -144,5 +144,5 @@ uint8_t u8g_com_HAL_DUE_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void return 1; } -#endif // HAS_GRAPHICAL_LCD && !U8GLIB_ST7920 +#endif // HAS_MARLINUI_U8GLIB && !U8GLIB_ST7920 #endif // ARDUINO_ARCH_SAM diff --git a/Marlin/src/HAL/HAL_DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp similarity index 94% rename from Marlin/src/HAL/HAL_DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp rename to Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp index 2563cf110fa8..615a386c3542 100644 --- a/Marlin/src/HAL/HAL_DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp +++ b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -57,7 +57,7 @@ #include "../../../inc/MarlinConfigPre.h" -#if HAS_GRAPHICAL_LCD +#if HAS_MARLINUI_U8GLIB #include "../../shared/Delay.h" @@ -80,7 +80,7 @@ Pio *SCK_pPio, *MOSI_pPio; uint32_t SCK_dwMask, MOSI_dwMask; void u8g_spiSend_sw_DUE_mode_0(uint8_t val) { // 3MHz - for (uint8_t i = 0; i < 8; i++) { + LOOP_L_N(i, 8) { if (val & 0x80) MOSI_pPio->PIO_SODR = MOSI_dwMask; else @@ -94,7 +94,7 @@ void u8g_spiSend_sw_DUE_mode_0(uint8_t val) { // 3MHz } void u8g_spiSend_sw_DUE_mode_3(uint8_t val) { // 3.5MHz - for (uint8_t i = 0; i < 8; i++) { + LOOP_L_N(i, 8) { SCK_pPio->PIO_CODR = SCK_dwMask; DELAY_NS(50); if (val & 0x80) @@ -108,5 +108,5 @@ void u8g_spiSend_sw_DUE_mode_3(uint8_t val) { // 3.5MHz } } -#endif // HAS_GRAPHICAL_LCD +#endif // HAS_MARLINUI_U8GLIB #endif // ARDUINO_ARCH_SAM diff --git a/Marlin/src/HAL/HAL_DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.h b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.h similarity index 94% rename from Marlin/src/HAL/HAL_DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.h rename to Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.h index e0f15bfd810d..f076c503cac2 100644 --- a/Marlin/src/HAL/HAL_DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.h +++ b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_DUE/EepromEmulation.cpp b/Marlin/src/HAL/DUE/eeprom_flash.cpp similarity index 88% rename from Marlin/src/HAL/HAL_DUE/EepromEmulation.cpp rename to Marlin/src/HAL/DUE/eeprom_flash.cpp index 926307935863..6f38da0967cb 100644 --- a/Marlin/src/HAL/HAL_DUE/EepromEmulation.cpp +++ b/Marlin/src/HAL/DUE/eeprom_flash.cpp @@ -1,9 +1,10 @@ /** * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com + * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com + * Copyright (c) 2016 Victor Perez victor_pv@hotmail.com * * 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 @@ -16,9 +17,14 @@ * 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 . + * along with this program. If not, see . * */ +#ifdef ARDUINO_ARCH_SAM + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(FLASH_EEPROM_EMULATION) /* EEPROM emulation over flash with reduced wear * @@ -47,22 +53,14 @@ * per page. We can't emulate EE endurance with FLASH for all * bytes, but we can emulate endurance for a given percent of * bytes. - * */ -#ifdef ARDUINO_ARCH_SAM - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(EEPROM_SETTINGS) && NONE(I2C_EEPROM, SPI_EEPROM) - -#include "../shared/Marduino.h" -#include "../shared/persistent_store_api.h" +//#define EE_EMU_DEBUG #define EEPROMSize 4096 #define PagesPerGroup 128 #define GroupCount 2 -#define PageSize 256u +#define PageSize 256U /* Flash storage */ typedef struct FLASH_SECTOR { @@ -134,15 +132,18 @@ static uint8_t buffer[256] = {0}, // The RAM buffer to accumulate writes curPage = 0, // Current FLASH page inside the group curGroup = 0xFF; // Current FLASH group -//#define EE_EMU_DEBUG -#ifdef EE_EMU_DEBUG - static void ee_Dump(int page,const void* data) { +#define DEBUG_OUT ENABLED(EE_EMU_DEBUG) +#include "../../core/debug_out.h" + +static void ee_Dump(const int page, const void* data) { + + #ifdef EE_EMU_DEBUG const uint8_t* c = (const uint8_t*) data; char buffer[80]; sprintf_P(buffer, PSTR("Page: %d (0x%04x)\n"), page, page); - SERIAL_ECHO(buffer); + DEBUG_ECHO(buffer); char* p = &buffer[0]; for (int i = 0; i< PageSize; ++i) { @@ -152,12 +153,16 @@ static uint8_t buffer[256] = {0}, // The RAM buffer to accumulate writes if ((i & 0xF) == 0xF) { *p++ = '\n'; *p = 0; - SERIAL_ECHO(buffer); + DEBUG_ECHO(buffer); p = &buffer[0]; } } - } -#endif + + #else + UNUSED(page); + UNUSED(data); + #endif +} /* Flash Writing Protection Key */ #define FWP_KEY 0x5Au @@ -170,17 +175,16 @@ static uint8_t buffer[256] = {0}, // The RAM buffer to accumulate writes #define EEFC_ERROR_FLAGS (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE) #endif - /** * Writes the contents of the specified page (no previous erase) * @param page (page #) * @param data (pointer to the data buffer) */ __attribute__ ((long_call, section (".ramfunc"))) -static bool ee_PageWrite(uint16_t page,const void* data) { +static bool ee_PageWrite(uint16_t page, const void* data) { uint16_t i; - uint32_t addrflash = ((uint32_t)getFlashStorage(page)); + uint32_t addrflash = uint32_t(getFlashStorage(page)); // Read the flash contents uint32_t pageContents[PageSize>>2]; @@ -195,13 +199,11 @@ static bool ee_PageWrite(uint16_t page,const void* data) { for (i = 0; i > 2; i++) pageContents[i] = (((uint32_t*)data)[i]) | (~(pageContents[i] ^ ((uint32_t*)data)[i])); - #ifdef EE_EMU_DEBUG - SERIAL_ECHO_START(); - SERIAL_ECHOLNPAIR("EEPROM PageWrite ", page); - SERIAL_ECHOLNPAIR(" in FLASH address ", (uint32_t)addrflash); - SERIAL_ECHOLNPAIR(" base address ", (uint32_t)getFlashStorage(0)); - SERIAL_FLUSH(); - #endif + DEBUG_ECHO_START(); + DEBUG_ECHOLNPAIR("EEPROM PageWrite ", page); + DEBUG_ECHOLNPAIR(" in FLASH address ", (uint32_t)addrflash); + DEBUG_ECHOLNPAIR(" base address ", (uint32_t)getFlashStorage(0)); + DEBUG_FLUSH(); // Get the page relative to the start of the EFC controller, and the EFC controller to use Efc *efc; @@ -243,10 +245,8 @@ static bool ee_PageWrite(uint16_t page,const void* data) { // Reenable interrupts __enable_irq(); - #ifdef EE_EMU_DEBUG - SERIAL_ECHO_START(); - SERIAL_ECHOLNPAIR("EEPROM Unlock failure for page ", page); - #endif + DEBUG_ECHO_START(); + DEBUG_ECHOLNPAIR("EEPROM Unlock failure for page ", page); return false; } @@ -270,10 +270,9 @@ static bool ee_PageWrite(uint16_t page,const void* data) { // Reenable interrupts __enable_irq(); - #ifdef EE_EMU_DEBUG - SERIAL_ECHO_START(); - SERIAL_ECHOLNPAIR("EEPROM Write failure for page ", page); - #endif + DEBUG_ECHO_START(); + DEBUG_ECHOLNPAIR("EEPROM Write failure for page ", page); + return false; } @@ -287,11 +286,11 @@ static bool ee_PageWrite(uint16_t page,const void* data) { if (memcmp(getFlashStorage(page),data,PageSize)) { #ifdef EE_EMU_DEBUG - SERIAL_ECHO_START(); - SERIAL_ECHOLNPAIR("EEPROM Verify Write failure for page ", page); + DEBUG_ECHO_START(); + DEBUG_ECHOLNPAIR("EEPROM Verify Write failure for page ", page); - ee_Dump( page,(uint32_t *) addrflash); - ee_Dump(-page,data); + ee_Dump( page, (uint32_t *)addrflash); + ee_Dump(-page, data); // Calculate count of changed bits uint32_t* p1 = (uint32_t*)addrflash; @@ -307,7 +306,7 @@ static bool ee_PageWrite(uint16_t page,const void* data) { } } } - SERIAL_ECHOLNPAIR("--> Differing bits: ", count); + DEBUG_ECHOLNPAIR("--> Differing bits: ", count); #endif return false; @@ -324,15 +323,13 @@ __attribute__ ((long_call, section (".ramfunc"))) static bool ee_PageErase(uint16_t page) { uint16_t i; - uint32_t addrflash = ((uint32_t)getFlashStorage(page)); + uint32_t addrflash = uint32_t(getFlashStorage(page)); - #ifdef EE_EMU_DEBUG - SERIAL_ECHO_START(); - SERIAL_ECHOLNPAIR("EEPROM PageErase ", page); - SERIAL_ECHOLNPAIR(" in FLASH address ", (uint32_t)addrflash); - SERIAL_ECHOLNPAIR(" base address ", (uint32_t)getFlashStorage(0)); - SERIAL_FLUSH(); - #endif + DEBUG_ECHO_START(); + DEBUG_ECHOLNPAIR("EEPROM PageErase ", page); + DEBUG_ECHOLNPAIR(" in FLASH address ", (uint32_t)addrflash); + DEBUG_ECHOLNPAIR(" base address ", (uint32_t)getFlashStorage(0)); + DEBUG_FLUSH(); // Get the page relative to the start of the EFC controller, and the EFC controller to use Efc *efc; @@ -373,10 +370,9 @@ static bool ee_PageErase(uint16_t page) { // Reenable interrupts __enable_irq(); - #ifdef EE_EMU_DEBUG - SERIAL_ECHO_START(); - SERIAL_ECHOLNPAIR("EEPROM Unlock failure for page ",page); - #endif + DEBUG_ECHO_START(); + DEBUG_ECHOLNPAIR("EEPROM Unlock failure for page ",page); + return false; } @@ -398,10 +394,9 @@ static bool ee_PageErase(uint16_t page) { // Reenable interrupts __enable_irq(); - #ifdef EE_EMU_DEBUG - SERIAL_ECHO_START(); - SERIAL_ECHOLNPAIR("EEPROM Erase failure for page ",page); - #endif + DEBUG_ECHO_START(); + DEBUG_ECHOLNPAIR("EEPROM Erase failure for page ",page); + return false; } @@ -415,20 +410,17 @@ static bool ee_PageErase(uint16_t page) { uint32_t * aligned_src = (uint32_t *) addrflash; for (i = 0; i < PageSize >> 2; i++) { if (*aligned_src++ != 0xFFFFFFFF) { - - #ifdef EE_EMU_DEBUG - SERIAL_ECHO_START(); - SERIAL_ECHOLNPAIR("EEPROM Verify Erase failure for page ",page); - - ee_Dump( page,(uint32_t *) addrflash); - #endif + DEBUG_ECHO_START(); + DEBUG_ECHOLNPAIR("EEPROM Verify Erase failure for page ",page); + ee_Dump(page, (uint32_t *)addrflash); return false; } } return true; } -static uint8_t ee_Read(uint32_t address, bool excludeRAMBuffer = false) { + +static uint8_t ee_Read(uint32_t address, bool excludeRAMBuffer=false) { uint32_t baddr; uint32_t blen; @@ -511,7 +503,7 @@ static uint8_t ee_Read(uint32_t address, bool excludeRAMBuffer = false) { return 0xFF; } -static uint32_t ee_GetAddrRange(uint32_t address, bool excludeRAMBuffer = false) { +static uint32_t ee_GetAddrRange(uint32_t address, bool excludeRAMBuffer=false) { uint32_t baddr, blen, nextAddr = 0xFFFF, @@ -603,7 +595,7 @@ static bool ee_IsPageClean(int page) { return true; } -static bool ee_Flush(uint32_t overrideAddress = 0xFFFFFFFF, uint8_t overrideData = 0xFF) { +static bool ee_Flush(uint32_t overrideAddress = 0xFFFFFFFF, uint8_t overrideData=0xFF) { // Check if RAM buffer has something to be written bool isEmpty = true; @@ -929,11 +921,9 @@ static void ee_Init() { // If all groups seem to be used, default to first group if (curGroup >= GroupCount) curGroup = 0; - #ifdef EE_EMU_DEBUG - SERIAL_ECHO_START(); - SERIAL_ECHOLNPAIR("EEPROM Current Group: ",curGroup); - SERIAL_FLUSH(); - #endif + DEBUG_ECHO_START(); + DEBUG_ECHOLNPAIR("EEPROM Current Group: ",curGroup); + DEBUG_FLUSH(); // Now, validate that all the other group pages are empty for (int grp = 0; grp < GroupCount; grp++) { @@ -941,11 +931,9 @@ static void ee_Init() { for (int page = 0; page < PagesPerGroup; page++) { if (!ee_IsPageClean(grp * PagesPerGroup + page)) { - #ifdef EE_EMU_DEBUG - SERIAL_ECHO_START(); - SERIAL_ECHOLNPAIR("EEPROM Page ", page, " not clean on group ", grp); - SERIAL_FLUSH(); - #endif + DEBUG_ECHO_START(); + DEBUG_ECHOLNPAIR("EEPROM Page ", page, " not clean on group ", grp); + DEBUG_FLUSH(); ee_PageErase(grp * PagesPerGroup + page); } } @@ -955,66 +943,69 @@ static void ee_Init() { // and also validate that all the other ones are clean for (curPage = 0; curPage < PagesPerGroup; curPage++) { if (ee_IsPageClean(curGroup * PagesPerGroup + curPage)) { - #ifdef EE_EMU_DEBUG - ee_Dump(curGroup * PagesPerGroup + curPage, getFlashStorage(curGroup * PagesPerGroup + curPage)); - #endif + ee_Dump(curGroup * PagesPerGroup + curPage, getFlashStorage(curGroup * PagesPerGroup + curPage)); break; } } - #ifdef EE_EMU_DEBUG - SERIAL_ECHO_START(); - SERIAL_ECHOLNPAIR("EEPROM Active page: ", curPage); - SERIAL_FLUSH(); - #endif + DEBUG_ECHO_START(); + DEBUG_ECHOLNPAIR("EEPROM Active page: ", curPage); + DEBUG_FLUSH(); // Make sure the pages following the first clean one are also clean for (int page = curPage + 1; page < PagesPerGroup; page++) { if (!ee_IsPageClean(curGroup * PagesPerGroup + page)) { - #ifdef EE_EMU_DEBUG - SERIAL_ECHO_START(); - SERIAL_ECHOLNPAIR("EEPROM Page ", page, " not clean on active group ", curGroup); - SERIAL_FLUSH(); - ee_Dump(curGroup * PagesPerGroup + page, getFlashStorage(curGroup * PagesPerGroup + page)); - #endif + DEBUG_ECHO_START(); + DEBUG_ECHOLNPAIR("EEPROM Page ", page, " not clean on active group ", curGroup); + DEBUG_FLUSH(); + ee_Dump(curGroup * PagesPerGroup + page, getFlashStorage(curGroup * PagesPerGroup + page)); ee_PageErase(curGroup * PagesPerGroup + page); } } } -uint8_t eeprom_read_byte(uint8_t* addr) { - ee_Init(); - return ee_Read((uint32_t)addr); -} +/* PersistentStore -----------------------------------------------------------*/ -void eeprom_write_byte(uint8_t* addr, uint8_t value) { - ee_Init(); - ee_Write((uint32_t)addr, value); -} +#include "../shared/eeprom_api.h" -void eeprom_update_block(const void* __src, void* __dst, size_t __n) { - uint8_t* dst = (uint8_t*)__dst; - const uint8_t* src = (const uint8_t*)__src; - while (__n--) { - eeprom_write_byte(dst, *src); - ++dst; - ++src; - } -} - -void eeprom_read_block(void* __dst, const void* __src, size_t __n) { - uint8_t* dst = (uint8_t*)__dst; - uint8_t* src = (uint8_t*)__src; - while (__n--) { - *dst = eeprom_read_byte(src); - ++dst; - ++src; +#ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE 0x1000 // 4KB +#endif +size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } +bool PersistentStore::access_start() { ee_Init(); return true; } +bool PersistentStore::access_finish() { ee_Flush(); return true; } + +bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { + while (size--) { + uint8_t * const p = (uint8_t * const)pos; + uint8_t v = *value; + // EEPROM has only ~100,000 write cycles, + // so only write bytes that have changed! + if (v != ee_Read(uint32_t(p))) { + ee_Write(uint32_t(p), v); + delay(2); + if (ee_Read(uint32_t(p)) != v) { + SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE); + return true; + } + } + crc16(crc, &v, 1); + pos++; + value++; } + return false; } -void eeprom_flush() { - ee_Flush(); +bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) { + do { + uint8_t c = ee_Read(uint32_t(pos)); + if (writing) *value = c; + crc16(crc, &c, 1); + pos++; + value++; + } while (--size); + return false; } -#endif // EEPROM_SETTINGS && (!I2C_EEPROM && !SPI_EEPROM) -#endif // ARDUINO_ARCH_AVR +#endif // FLASH_EEPROM_EMULATION +#endif // ARDUINO_ARCH_SAM diff --git a/Marlin/src/HAL/HAL_DUE/persistent_store_eeprom.cpp b/Marlin/src/HAL/DUE/eeprom_wired.cpp similarity index 74% rename from Marlin/src/HAL/HAL_DUE/persistent_store_eeprom.cpp rename to Marlin/src/HAL/DUE/eeprom_wired.cpp index 9fdcca7850f1..4599d6a7cd44 100644 --- a/Marlin/src/HAL/HAL_DUE/persistent_store_eeprom.cpp +++ b/Marlin/src/HAL/DUE/eeprom_wired.cpp @@ -17,32 +17,29 @@ * 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 . + * along with this program. If not, see . * */ #ifdef ARDUINO_ARCH_SAM -#include "../../inc/MarlinConfigPre.h" - -#if ENABLED(EEPROM_SETTINGS) - #include "../../inc/MarlinConfig.h" -#include "../shared/persistent_store_api.h" -#if !defined(E2END) && NONE(I2C_EEPROM, SPI_EEPROM) - #define E2END 0xFFF // Default to Flash emulated EEPROM size (EepromEmulation_Due.cpp) -#endif +#if USE_WIRED_EEPROM -extern void eeprom_flush(); +/** + * PersistentStore for Arduino-style EEPROM interface + * with simple implementations supplied by Marlin. + */ -bool PersistentStore::access_start() { return true; } +#include "../shared/eeprom_if.h" +#include "../shared/eeprom_api.h" -bool PersistentStore::access_finish() { - #if NONE(I2C_EEPROM, SPI_EEPROM) - eeprom_flush(); - #endif - return true; -} +#ifndef MARLIN_EEPROM_SIZE + #error "MARLIN_EEPROM_SIZE is required for I2C / SPI EEPROM." +#endif +size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } +bool PersistentStore::access_start() { eeprom_init(); return true; } +bool PersistentStore::access_finish() { return true; } bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { while (size--) { @@ -61,7 +58,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui crc16(crc, &v, 1); pos++; value++; - }; + } return false; } @@ -76,7 +73,5 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t return false; } -size_t PersistentStore::capacity() { return E2END + 1; } - -#endif // EEPROM_SETTINGS +#endif // USE_WIRED_EEPROM #endif // ARDUINO_ARCH_SAM diff --git a/Marlin/src/HAL/HAL_TEENSY31_32/endstop_interrupts.h b/Marlin/src/HAL/DUE/endstop_interrupts.h similarity index 68% rename from Marlin/src/HAL/HAL_TEENSY31_32/endstop_interrupts.h rename to Marlin/src/HAL/DUE/endstop_interrupts.h index 21fea5bd0115..999ada512761 100644 --- a/Marlin/src/HAL/HAL_TEENSY31_32/endstop_interrupts.h +++ b/Marlin/src/HAL/DUE/endstop_interrupts.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -47,31 +47,21 @@ void endstop_ISR() { endstops.update(); } void setup_endstop_interrupts() { #define _ATTACH(P) attachInterrupt(digitalPinToInterrupt(P), endstop_ISR, CHANGE) - #if HAS_X_MAX - _ATTACH(X_MAX_PIN); - #endif - #if HAS_X_MIN - _ATTACH(X_MIN_PIN); - #endif - #if HAS_Y_MAX - _ATTACH(Y_MAX_PIN); - #endif - #if HAS_Y_MIN - _ATTACH(Y_MIN_PIN); - #endif - #if HAS_Z_MAX - _ATTACH(Z_MAX_PIN); - #endif - #if HAS_Z_MIN - _ATTACH(Z_MIN_PIN); - #endif - #if HAS_Z2_MAX - _ATTACH(Z2_MAX_PIN); - #endif - #if HAS_Z2_MIN - _ATTACH(Z2_MIN_PIN); - #endif - #if HAS_Z_MIN_PROBE_PIN - _ATTACH(Z_MIN_PROBE_PIN); - #endif + TERN_(HAS_X_MAX, _ATTACH(X_MAX_PIN)); + TERN_(HAS_X_MIN, _ATTACH(X_MIN_PIN)); + TERN_(HAS_Y_MAX, _ATTACH(Y_MAX_PIN)); + TERN_(HAS_Y_MIN, _ATTACH(Y_MIN_PIN)); + TERN_(HAS_Z_MAX, _ATTACH(Z_MAX_PIN)); + TERN_(HAS_Z_MIN, _ATTACH(Z_MIN_PIN)); + TERN_(HAS_X2_MAX, _ATTACH(X2_MAX_PIN)); + TERN_(HAS_X2_MIN, _ATTACH(X2_MIN_PIN)); + TERN_(HAS_Y2_MAX, _ATTACH(Y2_MAX_PIN)); + TERN_(HAS_Y2_MIN, _ATTACH(Y2_MIN_PIN)); + TERN_(HAS_Z2_MAX, _ATTACH(Z2_MAX_PIN)); + TERN_(HAS_Z2_MIN, _ATTACH(Z2_MIN_PIN)); + TERN_(HAS_Z3_MAX, _ATTACH(Z3_MAX_PIN)); + TERN_(HAS_Z3_MIN, _ATTACH(Z3_MIN_PIN)); + TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN)); + TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN)); + TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN)); } diff --git a/Marlin/src/HAL/HAL_DUE/fastio.h b/Marlin/src/HAL/DUE/fastio.h similarity index 97% rename from Marlin/src/HAL/HAL_DUE/fastio.h rename to Marlin/src/HAL/DUE/fastio.h index 6f1f8d8bf2a8..286319302dd2 100644 --- a/Marlin/src/HAL/HAL_DUE/fastio.h +++ b/Marlin/src/HAL/DUE/fastio.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -58,7 +58,7 @@ * * Now you can simply SET_OUTPUT(STEP); WRITE(STEP, HIGH); WRITE(STEP, LOW); * - * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html + * Why double up on these macros? see https://gcc.gnu.org/onlinedocs/cpp/Stringification.html */ // Read a pin @@ -166,7 +166,7 @@ // Set pin as output (wrapper) - reads the pin and sets the output to that value #define SET_OUTPUT(IO) _SET_OUTPUT(IO) // Set pin as PWM -#define SET_PWM(IO) SET_OUTPUT(IO) +#define SET_PWM SET_OUTPUT // Check if pin is an input #define IS_INPUT(IO) ((digitalPinToPort(IO)->PIO_OSR & digitalPinToBitMask(IO)) == 0) @@ -174,7 +174,7 @@ #define IS_OUTPUT(IO) ((digitalPinToPort(IO)->PIO_OSR & digitalPinToBitMask(IO)) != 0) // Shorthand -#define OUT_WRITE(IO,V) { SET_OUTPUT(IO); WRITE(IO,V); } +#define OUT_WRITE(IO,V) do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0) // digitalRead/Write wrappers #define extDigitalRead(IO) digitalRead(IO) diff --git a/Marlin/src/HAL/DUE/fastio/G2_PWM.cpp b/Marlin/src/HAL/DUE/fastio/G2_PWM.cpp new file mode 100644 index 000000000000..d9fbabce2148 --- /dev/null +++ b/Marlin/src/HAL/DUE/fastio/G2_PWM.cpp @@ -0,0 +1,206 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * The PWM module is only used to generate interrupts at specified times. It + * is NOT used to directly toggle pins. The ISR writes to the pin assigned to + * that interrupt. + * + * All PWMs use the same repetition rate. The G2 needs about 10KHz min in order to + * not have obvious ripple on the Vref signals. + * + * The data structures are setup to minimize the computation done by the ISR which + * minimizes ISR execution time. Execution times are 0.8 to 1.1 microseconds. + * + * FIve PWM interrupt sources are used. Channel 0 sets the base period. All Vref + * signals are set active when this counter overflows and resets to zero. The compare + * values in channels 1-4 are set to give the desired duty cycle for that Vref pin. + * When counter 0 matches the compare value then that channel generates an interrupt. + * The ISR checks the source of the interrupt and sets the corresponding pin inactive. + * + * Some jitter in the Vref signal is OK so the interrupt priority is left at its default value. + */ + +#include "../../../inc/MarlinConfig.h" + +#if MB(PRINTRBOARD_G2) + +#include "G2_PWM.h" + +#if PIN_EXISTS(MOTOR_CURRENT_PWM_X) + #define G2_PWM_X 1 +#else + #define G2_PWM_X 0 +#endif +#if PIN_EXISTS(MOTOR_CURRENT_PWM_Y) + #define G2_PWM_Y 1 +#else + #define G2_PWM_Y 0 +#endif +#if PIN_EXISTS(MOTOR_CURRENT_PWM_Z) + #define G2_PWM_Z 1 +#else + #define G2_PWM_Z 0 +#endif +#if PIN_EXISTS(MOTOR_CURRENT_PWM_E) + #define G2_PWM_E 1 +#else + #define G2_PWM_E 0 +#endif +#define G2_MASK_X(V) (G2_PWM_X * (V)) +#define G2_MASK_Y(V) (G2_PWM_Y * (V)) +#define G2_MASK_Z(V) (G2_PWM_Z * (V)) +#define G2_MASK_E(V) (G2_PWM_E * (V)) + +volatile uint32_t *SODR_A = &PIOA->PIO_SODR, + *SODR_B = &PIOB->PIO_SODR, + *CODR_A = &PIOA->PIO_CODR, + *CODR_B = &PIOB->PIO_CODR; + +PWM_map ISR_table[NUM_PWMS] = PWM_MAP_INIT; + +void Stepper::digipot_init() { + + #if PIN_EXISTS(MOTOR_CURRENT_PWM_X) + OUT_WRITE(MOTOR_CURRENT_PWM_X_PIN, 0); // init pins + #endif + #if PIN_EXISTS(MOTOR_CURRENT_PWM_Y) + OUT_WRITE(MOTOR_CURRENT_PWM_Y_PIN, 0); + #endif + #if G2_PWM_Z + OUT_WRITE(MOTOR_CURRENT_PWM_Z_PIN, 0); + #endif + #if G2_PWM_E + OUT_WRITE(MOTOR_CURRENT_PWM_E_PIN, 0); + #endif + + #define WPKEY (0x50574D << 8) // “PWM” in ASCII + #define WPCMD_DIS_SW 0 // command to disable Write Protect SW + #define WPRG_ALL (PWM_WPCR_WPRG0 | PWM_WPCR_WPRG1 | PWM_WPCR_WPRG2 | PWM_WPCR_WPRG3 | PWM_WPCR_WPRG4 | PWM_WPCR_WPRG5) // all Write Protect Groups + + #define PWM_CLOCK_F F_CPU / 1000000UL // set clock to 1MHz + + PMC->PMC_PCER1 = PMC_PCER1_PID36; // enable PWM controller clock (disabled on power up) + + PWM->PWM_WPCR = WPKEY | WPRG_ALL | WPCMD_DIS_SW; // enable setting of all PWM registers + PWM->PWM_CLK = PWM_CLOCK_F; // enable CLK_A and set it to 1MHz, leave CLK_B disabled + PWM->PWM_CH_NUM[0].PWM_CMR = 0b1011; // set channel 0 to Clock A input & to left aligned + if (G2_PWM_X) PWM->PWM_CH_NUM[1].PWM_CMR = 0b1011; // set channel 1 to Clock A input & to left aligned + if (G2_PWM_Y) PWM->PWM_CH_NUM[2].PWM_CMR = 0b1011; // set channel 2 to Clock A input & to left aligned + if (G2_PWM_Z) PWM->PWM_CH_NUM[3].PWM_CMR = 0b1011; // set channel 3 to Clock A input & to left aligned + if (G2_PWM_E) PWM->PWM_CH_NUM[4].PWM_CMR = 0b1011; // set channel 4 to Clock A input & to left aligned + + PWM->PWM_CH_NUM[0].PWM_CPRD = PWM_PERIOD_US; // set channel 0 Period + + PWM->PWM_IER2 = PWM_IER1_CHID0; // generate interrupt when counter0 overflows + PWM->PWM_IER2 = PWM_IER2_CMPM0 + | G2_MASK_X(PWM_IER2_CMPM1) + | G2_MASK_Y(PWM_IER2_CMPM2) + | G2_MASK_Z(PWM_IER2_CMPM3) + | G2_MASK_E(PWM_IER2_CMPM4) + ; // generate interrupt on compare event + + if (G2_PWM_X) PWM->PWM_CMP[1].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[0])); // interrupt when counter0 == CMPV - used to set Motor 1 PWM inactive + if (G2_PWM_Y) PWM->PWM_CMP[2].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[0])); // interrupt when counter0 == CMPV - used to set Motor 2 PWM inactive + if (G2_PWM_Z) PWM->PWM_CMP[3].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[1])); // interrupt when counter0 == CMPV - used to set Motor 3 PWM inactive + if (G2_PWM_E) PWM->PWM_CMP[4].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[2])); // interrupt when counter0 == CMPV - used to set Motor 4 PWM inactive + + if (G2_PWM_X) PWM->PWM_CMP[1].PWM_CMPM = 0x0001; // enable compare event + if (G2_PWM_Y) PWM->PWM_CMP[2].PWM_CMPM = 0x0001; // enable compare event + if (G2_PWM_Z) PWM->PWM_CMP[3].PWM_CMPM = 0x0001; // enable compare event + if (G2_PWM_E) PWM->PWM_CMP[4].PWM_CMPM = 0x0001; // enable compare event + + PWM->PWM_SCM = PWM_SCM_UPDM_MODE0 | PWM_SCM_SYNC0 + | G2_MASK_X(PWM_SCM_SYNC1) + | G2_MASK_Y(PWM_SCM_SYNC2) + | G2_MASK_Z(PWM_SCM_SYNC3) + | G2_MASK_E(PWM_SCM_SYNC4) + ; // sync 1-4 with 0, use mode 0 for updates + + PWM->PWM_ENA = PWM_ENA_CHID0 + | G2_MASK_X(PWM_ENA_CHID1) + | G2_MASK_Y(PWM_ENA_CHID2) + | G2_MASK_Z(PWM_ENA_CHID3) + | G2_MASK_E(PWM_ENA_CHID4) + ; // enable channels used by G2 + + PWM->PWM_IER1 = PWM_IER1_CHID0 + | G2_MASK_X(PWM_IER1_CHID1) + | G2_MASK_Y(PWM_IER1_CHID2) + | G2_MASK_Z(PWM_IER1_CHID3) + | G2_MASK_E(PWM_IER1_CHID4) + ; // enable interrupts for channels used by G2 + + NVIC_EnableIRQ(PWM_IRQn); // Enable interrupt handler + NVIC_SetPriority(PWM_IRQn, NVIC_EncodePriority(0, 10, 0)); // normal priority for PWM module (can stand some jitter on the Vref signals) +} + +void Stepper::set_digipot_current(const uint8_t driver, const int16_t current) { + + if (!(PWM->PWM_CH_NUM[0].PWM_CPRD == PWM_PERIOD_US)) digipot_init(); // Init PWM system if needed + + switch (driver) { + case 0: + if (G2_PWM_X) PWM->PWM_CMP[1].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update X & Y + if (G2_PWM_Y) PWM->PWM_CMP[2].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); + if (G2_PWM_X) PWM->PWM_CMP[1].PWM_CMPMUPD = 0x0001; // enable compare event + if (G2_PWM_Y) PWM->PWM_CMP[2].PWM_CMPMUPD = 0x0001; // enable compare event + if (G2_PWM_X || G2_PWM_Y) PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle + break; + case 1: + if (G2_PWM_Z) { + PWM->PWM_CMP[3].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update Z + PWM->PWM_CMP[3].PWM_CMPMUPD = 0x0001; // enable compare event + PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle + } + break; + default: + if (G2_PWM_E) { + PWM->PWM_CMP[4].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update E + PWM->PWM_CMP[4].PWM_CMPMUPD = 0x0001; // enable compare event + PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle + } + break; + } +} + +volatile uint32_t PWM_ISR1_STATUS, PWM_ISR2_STATUS; + +void PWM_Handler() { + PWM_ISR1_STATUS = PWM->PWM_ISR1; + PWM_ISR2_STATUS = PWM->PWM_ISR2; + if (PWM_ISR1_STATUS & PWM_IER1_CHID0) { // CHAN_0 interrupt + if (G2_PWM_X) *ISR_table[0].set_register = ISR_table[0].write_mask; // set X to active + if (G2_PWM_Y) *ISR_table[1].set_register = ISR_table[1].write_mask; // set Y to active + if (G2_PWM_Z) *ISR_table[2].set_register = ISR_table[2].write_mask; // set Z to active + if (G2_PWM_E) *ISR_table[3].set_register = ISR_table[3].write_mask; // set E to active + } + else { + if (G2_PWM_X && (PWM_ISR2_STATUS & PWM_IER2_CMPM1)) *ISR_table[0].clr_register = ISR_table[0].write_mask; // set X to inactive + if (G2_PWM_Y && (PWM_ISR2_STATUS & PWM_IER2_CMPM2)) *ISR_table[1].clr_register = ISR_table[1].write_mask; // set Y to inactive + if (G2_PWM_Z && (PWM_ISR2_STATUS & PWM_IER2_CMPM3)) *ISR_table[2].clr_register = ISR_table[2].write_mask; // set Z to inactive + if (G2_PWM_E && (PWM_ISR2_STATUS & PWM_IER2_CMPM4)) *ISR_table[3].clr_register = ISR_table[3].write_mask; // set E to inactive + } + return; +} + +#endif // PRINTRBOARD_G2 diff --git a/Marlin/src/HAL/HAL_DUE/fastio/G2_PWM.h b/Marlin/src/HAL/DUE/fastio/G2_PWM.h similarity index 94% rename from Marlin/src/HAL/HAL_DUE/fastio/G2_PWM.h rename to Marlin/src/HAL/DUE/fastio/G2_PWM.h index 1a802ed0f376..dc4edffff851 100644 --- a/Marlin/src/HAL/HAL_DUE/fastio/G2_PWM.h +++ b/Marlin/src/HAL/DUE/fastio/G2_PWM.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -63,7 +63,7 @@ extern PWM_map ISR_table[NUM_PWMS]; extern uint32_t motor_current_setting[3]; #define IR_BIT(p) (WITHIN(p, 0, 3) ? (p) : (p) + 4) -#define COPY_ACTIVE_TABLE() do{ for (uint8_t i = 0; i < 6 ; i++) work_table[i] = active_table[i]; }while(0) +#define COPY_ACTIVE_TABLE() do{ LOOP_L_N(i, 6) work_table[i] = active_table[i]; }while(0) #define PWM_MR0 19999 // base repetition rate minus one count - 20mS #define PWM_PR 24 // prescaler value - prescaler divide by 24 + 1 - 1 MHz output diff --git a/Marlin/src/HAL/HAL_DUE/fastio/G2_pins.h b/Marlin/src/HAL/DUE/fastio/G2_pins.h similarity index 99% rename from Marlin/src/HAL/HAL_DUE/fastio/G2_pins.h rename to Marlin/src/HAL/DUE/fastio/G2_pins.h index 44b9cb35ee3f..80c87bd39296 100644 --- a/Marlin/src/HAL/HAL_DUE/fastio/G2_pins.h +++ b/Marlin/src/HAL/DUE/fastio/G2_pins.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/DUE/inc/Conditionals_LCD.h b/Marlin/src/HAL/DUE/inc/Conditionals_LCD.h new file mode 100644 index 000000000000..58674144470c --- /dev/null +++ b/Marlin/src/HAL/DUE/inc/Conditionals_LCD.h @@ -0,0 +1,26 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if HAS_SPI_TFT || HAS_FSMC_TFT + #error "Sorry! TFT displays are not available for HAL/DUE." +#endif diff --git a/Marlin/src/HAL/HAL_DUE/inc/Conditionals_adv.h b/Marlin/src/HAL/DUE/inc/Conditionals_adv.h similarity index 91% rename from Marlin/src/HAL/HAL_DUE/inc/Conditionals_adv.h rename to Marlin/src/HAL/DUE/inc/Conditionals_adv.h index 0285c52ee365..5f1c4b16019d 100644 --- a/Marlin/src/HAL/HAL_DUE/inc/Conditionals_adv.h +++ b/Marlin/src/HAL/DUE/inc/Conditionals_adv.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/DUE/inc/Conditionals_post.h b/Marlin/src/HAL/DUE/inc/Conditionals_post.h new file mode 100644 index 000000000000..ce6d3fdde27f --- /dev/null +++ b/Marlin/src/HAL/DUE/inc/Conditionals_post.h @@ -0,0 +1,28 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if USE_FALLBACK_EEPROM + #define FLASH_EEPROM_EMULATION +#elif EITHER(I2C_EEPROM, SPI_EEPROM) + #define USE_SHARED_EEPROM 1 +#endif diff --git a/Marlin/src/HAL/HAL_DUE/inc/SanityCheck.h b/Marlin/src/HAL/DUE/inc/SanityCheck.h similarity index 90% rename from Marlin/src/HAL/HAL_DUE/inc/SanityCheck.h rename to Marlin/src/HAL/DUE/inc/SanityCheck.h index 0f7be7955fa8..688069650630 100644 --- a/Marlin/src/HAL/HAL_DUE/inc/SanityCheck.h +++ b/Marlin/src/HAL/DUE/inc/SanityCheck.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -52,8 +52,8 @@ #endif #endif -#if ENABLED(FAST_PWM_FAN) - #error "FAST_PWM_FAN is not yet implemented for this platform." +#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY + #error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on DUE." #endif #if HAS_TMC_SW_SERIAL diff --git a/Marlin/src/HAL/HAL_DUE/pinsDebug.h b/Marlin/src/HAL/DUE/pinsDebug.h similarity index 98% rename from Marlin/src/HAL/HAL_DUE/pinsDebug.h rename to Marlin/src/HAL/DUE/pinsDebug.h index 448c2391d3e9..a99ca8ecce90 100644 --- a/Marlin/src/HAL/HAL_DUE/pinsDebug.h +++ b/Marlin/src/HAL/DUE/pinsDebug.h @@ -13,7 +13,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -179,5 +179,4 @@ void pwm_details(int32_t pin) { * ----------------+-------- * ID | PB11 * VBOF | PB10 - * */ diff --git a/Marlin/src/HAL/HAL_DUE/spi_pins.h b/Marlin/src/HAL/DUE/spi_pins.h similarity index 95% rename from Marlin/src/HAL/HAL_DUE/spi_pins.h rename to Marlin/src/HAL/DUE/spi_pins.h index a205540bcd33..e28eaf827020 100644 --- a/Marlin/src/HAL/HAL_DUE/spi_pins.h +++ b/Marlin/src/HAL/DUE/spi_pins.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_DUE/timers.cpp b/Marlin/src/HAL/DUE/timers.cpp similarity index 95% rename from Marlin/src/HAL/HAL_DUE/timers.cpp rename to Marlin/src/HAL/DUE/timers.cpp index 74ae88284380..9b937d1a7c83 100644 --- a/Marlin/src/HAL/HAL_DUE/timers.cpp +++ b/Marlin/src/HAL/DUE/timers.cpp @@ -16,14 +16,12 @@ * 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 . + * along with this program. If not, see . * */ /** - * Description: HAL for Arduino Due and compatible (SAM3X8E) - * - * For ARDUINO_ARCH_SAM + * HAL Timers for Arduino Due and compatible (SAM3X8E) */ #ifdef ARDUINO_ARCH_SAM @@ -34,8 +32,6 @@ #include "../../inc/MarlinConfig.h" #include "HAL.h" -#include "timers.h" - // ------------------------ // Local defines // ------------------------ diff --git a/Marlin/src/HAL/HAL_DUE/timers.h b/Marlin/src/HAL/DUE/timers.h similarity index 85% rename from Marlin/src/HAL/HAL_DUE/timers.h rename to Marlin/src/HAL/DUE/timers.h index 514466011677..0e1ea07cc2e4 100644 --- a/Marlin/src/HAL/HAL_DUE/timers.h +++ b/Marlin/src/HAL/DUE/timers.h @@ -15,15 +15,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once /** - * HAL for Arduino Due and compatible (SAM3X8E) - * - * For ARDUINO_ARCH_SAM + * HAL Timers for Arduino Due and compatible (SAM3X8E) */ #include @@ -40,11 +38,17 @@ typedef uint32_t hal_timer_t; #define HAL_TIMER_RATE ((F_CPU) / 2) // frequency of timers peripherals #ifndef STEP_TIMER_NUM -#define STEP_TIMER_NUM 2 // index of timer to use for stepper + #define STEP_TIMER_NUM 2 // Timer Index for Stepper +#endif +#ifndef PULSE_TIMER_NUM + #define PULSE_TIMER_NUM STEP_TIMER_NUM +#endif +#ifndef TEMP_TIMER_NUM + #define TEMP_TIMER_NUM 4 // Timer Index for Temperature +#endif +#ifndef TONE_TIMER_NUM + #define TONE_TIMER_NUM 6 // index of timer to use for beeper tones #endif -#define TEMP_TIMER_NUM 4 // index of timer to use for temperature -#define PULSE_TIMER_NUM STEP_TIMER_NUM -#define TONE_TIMER_NUM 6 // index of timer to use for beeper tones #define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency @@ -66,8 +70,12 @@ typedef uint32_t hal_timer_t; #ifndef HAL_STEP_TIMER_ISR #define HAL_STEP_TIMER_ISR() void TC2_Handler() #endif -#define HAL_TEMP_TIMER_ISR() void TC4_Handler() -#define HAL_TONE_TIMER_ISR() void TC6_Handler() +#ifndef HAL_TEMP_TIMER_ISR + #define HAL_TEMP_TIMER_ISR() void TC4_Handler() +#endif +#ifndef HAL_TONE_TIMER_ISR + #define HAL_TONE_TIMER_ISR() void TC6_Handler() +#endif // ------------------------ // Types diff --git a/Marlin/src/HAL/DUE/upload_extra_script.py b/Marlin/src/HAL/DUE/upload_extra_script.py new file mode 100644 index 000000000000..d52a0a3642b4 --- /dev/null +++ b/Marlin/src/HAL/DUE/upload_extra_script.py @@ -0,0 +1,18 @@ +# +# Set upload_command +# +# Windows: bossac.exe +# Other: leave unchanged +# + +import platform +current_OS = platform.system() + +if current_OS == 'Windows': + + Import("env") + + # Use bossac.exe on Windows + env.Replace( + UPLOADCMD="bossac --info --unlock --write --verify --reset --erase -U false --boot $SOURCE" + ) diff --git a/Marlin/src/HAL/HAL_DUE/usb/arduino_due_x.h b/Marlin/src/HAL/DUE/usb/arduino_due_x.h similarity index 96% rename from Marlin/src/HAL/HAL_DUE/usb/arduino_due_x.h rename to Marlin/src/HAL/DUE/usb/arduino_due_x.h index 7355f74f6d9b..d3b333fb349a 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/arduino_due_x.h +++ b/Marlin/src/HAL/DUE/usb/arduino_due_x.h @@ -43,7 +43,7 @@ #pragma once /** - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ /** @@ -93,5 +93,5 @@ #define USB_VBOF_GPIO (PIO_PB10_IDX) #define USB_VBOF_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) /*! Active level of the USB_VBOF output pin. */ -#define USB_VBOF_ACTIVE_LEVEL LOW +#define USB_VBOF_ACTIVE_STATE LOW /* ------------------------------------------------------------------------ */ diff --git a/Marlin/src/HAL/HAL_DUE/usb/compiler.h b/Marlin/src/HAL/DUE/usb/compiler.h similarity index 87% rename from Marlin/src/HAL/HAL_DUE/usb/compiler.h rename to Marlin/src/HAL/DUE/usb/compiler.h index 33df080e2f89..f89e554c4562 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/compiler.h +++ b/Marlin/src/HAL/DUE/usb/compiler.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef UTILS_COMPILER_H @@ -173,11 +173,11 @@ # define __always_inline __forceinline #elif (defined __GNUC__) #ifdef __always_inline -# undef __always_inline +# undef __always_inline #endif -# define __always_inline inline __attribute__((__always_inline__)) +# define __always_inline inline __attribute__((__always_inline__)) #elif (defined __ICCARM__) -# define __always_inline _Pragma("inline=forced") +# define __always_inline _Pragma("inline=forced") #endif /** @@ -188,11 +188,11 @@ * heuristics and not inline the function. */ #ifdef __CC_ARM -# define __no_inline __attribute__((noinline)) +# define __no_inline __attribute__((noinline)) #elif (defined __GNUC__) -# define __no_inline __attribute__((__noinline__)) +# define __no_inline __attribute__((__noinline__)) #elif (defined __ICCARM__) -# define __no_inline _Pragma("inline=never") +# define __no_inline _Pragma("inline=never") #endif /*! \brief This macro is used to test fatal errors. @@ -211,9 +211,9 @@ # else #undef TEST_SUITE_DEFINE_ASSERT_MACRO # define Assert(expr) \ - {\ - if (!(expr)) while (true);\ - } + {\ + if (!(expr)) while (true);\ + } # endif #else # define Assert(expr) ((void) 0) @@ -609,37 +609,37 @@ typedef struct # define clz(u) ((u) ? __CLZ(u) : 32) #else # define clz(u) (((u) == 0) ? 32 : \ - ((u) & (1ul << 31)) ? 0 : \ - ((u) & (1ul << 30)) ? 1 : \ - ((u) & (1ul << 29)) ? 2 : \ - ((u) & (1ul << 28)) ? 3 : \ - ((u) & (1ul << 27)) ? 4 : \ - ((u) & (1ul << 26)) ? 5 : \ - ((u) & (1ul << 25)) ? 6 : \ - ((u) & (1ul << 24)) ? 7 : \ - ((u) & (1ul << 23)) ? 8 : \ - ((u) & (1ul << 22)) ? 9 : \ - ((u) & (1ul << 21)) ? 10 : \ - ((u) & (1ul << 20)) ? 11 : \ - ((u) & (1ul << 19)) ? 12 : \ - ((u) & (1ul << 18)) ? 13 : \ - ((u) & (1ul << 17)) ? 14 : \ - ((u) & (1ul << 16)) ? 15 : \ - ((u) & (1ul << 15)) ? 16 : \ - ((u) & (1ul << 14)) ? 17 : \ - ((u) & (1ul << 13)) ? 18 : \ - ((u) & (1ul << 12)) ? 19 : \ - ((u) & (1ul << 11)) ? 20 : \ - ((u) & (1ul << 10)) ? 21 : \ - ((u) & (1ul << 9)) ? 22 : \ - ((u) & (1ul << 8)) ? 23 : \ - ((u) & (1ul << 7)) ? 24 : \ - ((u) & (1ul << 6)) ? 25 : \ - ((u) & (1ul << 5)) ? 26 : \ - ((u) & (1ul << 4)) ? 27 : \ - ((u) & (1ul << 3)) ? 28 : \ - ((u) & (1ul << 2)) ? 29 : \ - ((u) & (1ul << 1)) ? 30 : \ + ((u) & (1UL << 31)) ? 0 : \ + ((u) & (1UL << 30)) ? 1 : \ + ((u) & (1UL << 29)) ? 2 : \ + ((u) & (1UL << 28)) ? 3 : \ + ((u) & (1UL << 27)) ? 4 : \ + ((u) & (1UL << 26)) ? 5 : \ + ((u) & (1UL << 25)) ? 6 : \ + ((u) & (1UL << 24)) ? 7 : \ + ((u) & (1UL << 23)) ? 8 : \ + ((u) & (1UL << 22)) ? 9 : \ + ((u) & (1UL << 21)) ? 10 : \ + ((u) & (1UL << 20)) ? 11 : \ + ((u) & (1UL << 19)) ? 12 : \ + ((u) & (1UL << 18)) ? 13 : \ + ((u) & (1UL << 17)) ? 14 : \ + ((u) & (1UL << 16)) ? 15 : \ + ((u) & (1UL << 15)) ? 16 : \ + ((u) & (1UL << 14)) ? 17 : \ + ((u) & (1UL << 13)) ? 18 : \ + ((u) & (1UL << 12)) ? 19 : \ + ((u) & (1UL << 11)) ? 20 : \ + ((u) & (1UL << 10)) ? 21 : \ + ((u) & (1UL << 9)) ? 22 : \ + ((u) & (1UL << 8)) ? 23 : \ + ((u) & (1UL << 7)) ? 24 : \ + ((u) & (1UL << 6)) ? 25 : \ + ((u) & (1UL << 5)) ? 26 : \ + ((u) & (1UL << 4)) ? 27 : \ + ((u) & (1UL << 3)) ? 28 : \ + ((u) & (1UL << 2)) ? 29 : \ + ((u) & (1UL << 1)) ? 30 : \ 31) #endif #endif @@ -654,38 +654,38 @@ typedef struct #if (defined __GNUC__) || (defined __CC_ARM) # define ctz(u) ((u) ? __builtin_ctz(u) : 32) #else -# define ctz(u) ((u) & (1ul << 0) ? 0 : \ - (u) & (1ul << 1) ? 1 : \ - (u) & (1ul << 2) ? 2 : \ - (u) & (1ul << 3) ? 3 : \ - (u) & (1ul << 4) ? 4 : \ - (u) & (1ul << 5) ? 5 : \ - (u) & (1ul << 6) ? 6 : \ - (u) & (1ul << 7) ? 7 : \ - (u) & (1ul << 8) ? 8 : \ - (u) & (1ul << 9) ? 9 : \ - (u) & (1ul << 10) ? 10 : \ - (u) & (1ul << 11) ? 11 : \ - (u) & (1ul << 12) ? 12 : \ - (u) & (1ul << 13) ? 13 : \ - (u) & (1ul << 14) ? 14 : \ - (u) & (1ul << 15) ? 15 : \ - (u) & (1ul << 16) ? 16 : \ - (u) & (1ul << 17) ? 17 : \ - (u) & (1ul << 18) ? 18 : \ - (u) & (1ul << 19) ? 19 : \ - (u) & (1ul << 20) ? 20 : \ - (u) & (1ul << 21) ? 21 : \ - (u) & (1ul << 22) ? 22 : \ - (u) & (1ul << 23) ? 23 : \ - (u) & (1ul << 24) ? 24 : \ - (u) & (1ul << 25) ? 25 : \ - (u) & (1ul << 26) ? 26 : \ - (u) & (1ul << 27) ? 27 : \ - (u) & (1ul << 28) ? 28 : \ - (u) & (1ul << 29) ? 29 : \ - (u) & (1ul << 30) ? 30 : \ - (u) & (1ul << 31) ? 31 : \ +# define ctz(u) ((u) & (1UL << 0) ? 0 : \ + (u) & (1UL << 1) ? 1 : \ + (u) & (1UL << 2) ? 2 : \ + (u) & (1UL << 3) ? 3 : \ + (u) & (1UL << 4) ? 4 : \ + (u) & (1UL << 5) ? 5 : \ + (u) & (1UL << 6) ? 6 : \ + (u) & (1UL << 7) ? 7 : \ + (u) & (1UL << 8) ? 8 : \ + (u) & (1UL << 9) ? 9 : \ + (u) & (1UL << 10) ? 10 : \ + (u) & (1UL << 11) ? 11 : \ + (u) & (1UL << 12) ? 12 : \ + (u) & (1UL << 13) ? 13 : \ + (u) & (1UL << 14) ? 14 : \ + (u) & (1UL << 15) ? 15 : \ + (u) & (1UL << 16) ? 16 : \ + (u) & (1UL << 17) ? 17 : \ + (u) & (1UL << 18) ? 18 : \ + (u) & (1UL << 19) ? 19 : \ + (u) & (1UL << 20) ? 20 : \ + (u) & (1UL << 21) ? 21 : \ + (u) & (1UL << 22) ? 22 : \ + (u) & (1UL << 23) ? 23 : \ + (u) & (1UL << 24) ? 24 : \ + (u) & (1UL << 25) ? 25 : \ + (u) & (1UL << 26) ? 26 : \ + (u) & (1UL << 27) ? 27 : \ + (u) & (1UL << 28) ? 28 : \ + (u) & (1UL << 29) ? 29 : \ + (u) & (1UL << 30) ? 30 : \ + (u) & (1UL << 31) ? 31 : \ 32) #endif #endif @@ -1106,17 +1106,16 @@ static inline uint16_t convert_byte_array_to_16_bit(uint8_t *data) /* Converts a 8 Byte array into a 32-Bit value */ static inline uint32_t convert_byte_array_to_32_bit(uint8_t *data) { - union - { - uint32_t u32; - uint8_t u8[8]; - }long_addr; - uint8_t index; - for (index = 0; index < 4; index++) - { - long_addr.u8[index] = *data++; - } - return long_addr.u32; + union + { + uint32_t u32; + uint8_t u8[8]; + }long_addr; + uint8_t index; + for (index = 0; index < 4; index++) { + long_addr.u8[index] = *data++; + } + return long_addr.u32; } /** diff --git a/Marlin/src/HAL/HAL_DUE/usb/conf_access.h b/Marlin/src/HAL/DUE/usb/conf_access.h similarity index 97% rename from Marlin/src/HAL/HAL_DUE/usb/conf_access.h rename to Marlin/src/HAL/DUE/usb/conf_access.h index fdac1ab7e848..f401685223cb 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/conf_access.h +++ b/Marlin/src/HAL/DUE/usb/conf_access.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef _CONF_ACCESS_H_ diff --git a/Marlin/src/HAL/HAL_DUE/usb/conf_clock.h b/Marlin/src/HAL/DUE/usb/conf_clock.h similarity index 97% rename from Marlin/src/HAL/HAL_DUE/usb/conf_clock.h rename to Marlin/src/HAL/DUE/usb/conf_clock.h index d0f68500ad71..97e70e99a5b9 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/conf_clock.h +++ b/Marlin/src/HAL/DUE/usb/conf_clock.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef CONF_CLOCK_H_INCLUDED diff --git a/Marlin/src/HAL/HAL_DUE/usb/conf_usb.h b/Marlin/src/HAL/DUE/usb/conf_usb.h similarity index 98% rename from Marlin/src/HAL/HAL_DUE/usb/conf_usb.h rename to Marlin/src/HAL/DUE/usb/conf_usb.h index 8d5924d375e8..4de9e347e213 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/conf_usb.h +++ b/Marlin/src/HAL/DUE/usb/conf_usb.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef _CONF_USB_H_ @@ -78,10 +78,6 @@ //! To define a Full speed device //#define USB_DEVICE_FULL_SPEED -#if MB(ARCHIM1) - #define USB_DEVICE_FULL_SPEED -#endif - //! To authorize the High speed #ifndef USB_DEVICE_FULL_SPEED #if (UC3A3||UC3A4) diff --git a/Marlin/src/HAL/HAL_DUE/usb/ctrl_access.c b/Marlin/src/HAL/DUE/usb/ctrl_access.c similarity index 99% rename from Marlin/src/HAL/HAL_DUE/usb/ctrl_access.c rename to Marlin/src/HAL/DUE/usb/ctrl_access.c index 0ec14e0b8f8d..99f97f62cb80 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/ctrl_access.c +++ b/Marlin/src/HAL/DUE/usb/ctrl_access.c @@ -53,7 +53,7 @@ * ******************************************************************************/ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifdef ARDUINO_ARCH_SAM diff --git a/Marlin/src/HAL/HAL_DUE/usb/ctrl_access.h b/Marlin/src/HAL/DUE/usb/ctrl_access.h similarity index 99% rename from Marlin/src/HAL/HAL_DUE/usb/ctrl_access.h rename to Marlin/src/HAL/DUE/usb/ctrl_access.h index af6c8ceb963e..b33839076eae 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/ctrl_access.h +++ b/Marlin/src/HAL/DUE/usb/ctrl_access.h @@ -53,7 +53,7 @@ * ******************************************************************************/ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ diff --git a/Marlin/src/HAL/HAL_DUE/usb/genclk.h b/Marlin/src/HAL/DUE/usb/genclk.h similarity index 98% rename from Marlin/src/HAL/HAL_DUE/usb/genclk.h rename to Marlin/src/HAL/DUE/usb/genclk.h index 895aba035229..cde03bc0d107 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/genclk.h +++ b/Marlin/src/HAL/DUE/usb/genclk.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef CHIP_GENCLK_H_INCLUDED diff --git a/Marlin/src/HAL/HAL_DUE/usb/mrepeat.h b/Marlin/src/HAL/DUE/usb/mrepeat.h similarity index 99% rename from Marlin/src/HAL/HAL_DUE/usb/mrepeat.h rename to Marlin/src/HAL/DUE/usb/mrepeat.h index 5a2017be99e9..8363d9cde380 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/mrepeat.h +++ b/Marlin/src/HAL/DUE/usb/mrepeat.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef _MREPEAT_H_ diff --git a/Marlin/src/HAL/HAL_DUE/usb/osc.h b/Marlin/src/HAL/DUE/usb/osc.h similarity index 98% rename from Marlin/src/HAL/HAL_DUE/usb/osc.h rename to Marlin/src/HAL/DUE/usb/osc.h index 3a9543507bb8..953bcbbed1d3 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/osc.h +++ b/Marlin/src/HAL/DUE/usb/osc.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef CHIP_OSC_H_INCLUDED diff --git a/Marlin/src/HAL/HAL_DUE/usb/pll.h b/Marlin/src/HAL/DUE/usb/pll.h similarity index 98% rename from Marlin/src/HAL/HAL_DUE/usb/pll.h rename to Marlin/src/HAL/DUE/usb/pll.h index d3d2174870e5..8eaf27672b25 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/pll.h +++ b/Marlin/src/HAL/DUE/usb/pll.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef CHIP_PLL_H_INCLUDED diff --git a/Marlin/src/HAL/HAL_DUE/usb/preprocessor.h b/Marlin/src/HAL/DUE/usb/preprocessor.h similarity index 95% rename from Marlin/src/HAL/HAL_DUE/usb/preprocessor.h rename to Marlin/src/HAL/DUE/usb/preprocessor.h index 184c03ae7103..c12d01cb642f 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/preprocessor.h +++ b/Marlin/src/HAL/DUE/usb/preprocessor.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef _PREPROCESSOR_H_ diff --git a/Marlin/src/HAL/HAL_DUE/usb/sbc_protocol.h b/Marlin/src/HAL/DUE/usb/sbc_protocol.h similarity index 98% rename from Marlin/src/HAL/HAL_DUE/usb/sbc_protocol.h rename to Marlin/src/HAL/DUE/usb/sbc_protocol.h index 082b735fa619..ab845739fd48 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/sbc_protocol.h +++ b/Marlin/src/HAL/DUE/usb/sbc_protocol.h @@ -52,7 +52,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef _SBC_PROTOCOL_H_ #define _SBC_PROTOCOL_H_ diff --git a/Marlin/src/HAL/HAL_DUE/usb/sd_mmc_spi_mem.cpp b/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp similarity index 100% rename from Marlin/src/HAL/HAL_DUE/usb/sd_mmc_spi_mem.cpp rename to Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp diff --git a/Marlin/src/HAL/HAL_DUE/usb/sd_mmc_spi_mem.h b/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.h similarity index 98% rename from Marlin/src/HAL/HAL_DUE/usb/sd_mmc_spi_mem.h rename to Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.h index 6df82c146b75..d77e4f95232b 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/sd_mmc_spi_mem.h +++ b/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.h @@ -42,7 +42,7 @@ * ******************************************************************************/ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ diff --git a/Marlin/src/HAL/HAL_DUE/usb/spc_protocol.h b/Marlin/src/HAL/DUE/usb/spc_protocol.h similarity index 99% rename from Marlin/src/HAL/HAL_DUE/usb/spc_protocol.h rename to Marlin/src/HAL/DUE/usb/spc_protocol.h index 6fadb9f36caa..d67cc5c78803 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/spc_protocol.h +++ b/Marlin/src/HAL/DUE/usb/spc_protocol.h @@ -45,7 +45,7 @@ */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef _SPC_PROTOCOL_H_ #define _SPC_PROTOCOL_H_ diff --git a/Marlin/src/HAL/HAL_DUE/usb/stringz.h b/Marlin/src/HAL/DUE/usb/stringz.h similarity index 96% rename from Marlin/src/HAL/HAL_DUE/usb/stringz.h rename to Marlin/src/HAL/DUE/usb/stringz.h index b914b7348933..fc9aaf38a4cf 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/stringz.h +++ b/Marlin/src/HAL/DUE/usb/stringz.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef _STRINGZ_H_ diff --git a/Marlin/src/HAL/HAL_DUE/usb/sysclk.c b/Marlin/src/HAL/DUE/usb/sysclk.c similarity index 97% rename from Marlin/src/HAL/HAL_DUE/usb/sysclk.c rename to Marlin/src/HAL/DUE/usb/sysclk.c index 899244dd88d0..cbb4e2c9ef22 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/sysclk.c +++ b/Marlin/src/HAL/DUE/usb/sysclk.c @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifdef ARDUINO_ARCH_SAM diff --git a/Marlin/src/HAL/HAL_DUE/usb/sysclk.h b/Marlin/src/HAL/DUE/usb/sysclk.h similarity index 98% rename from Marlin/src/HAL/HAL_DUE/usb/sysclk.h rename to Marlin/src/HAL/DUE/usb/sysclk.h index 48c99de2983e..16db8c86d373 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/sysclk.h +++ b/Marlin/src/HAL/DUE/usb/sysclk.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef CHIP_SYSCLK_H_INCLUDED diff --git a/Marlin/src/HAL/HAL_DUE/usb/tpaste.h b/Marlin/src/HAL/DUE/usb/tpaste.h similarity index 97% rename from Marlin/src/HAL/HAL_DUE/usb/tpaste.h rename to Marlin/src/HAL/DUE/usb/tpaste.h index f8ec44a41def..2ad3f2758e8a 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/tpaste.h +++ b/Marlin/src/HAL/DUE/usb/tpaste.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef _TPASTE_H_ diff --git a/Marlin/src/HAL/HAL_DUE/usb/udc.c b/Marlin/src/HAL/DUE/usb/udc.c similarity index 99% rename from Marlin/src/HAL/HAL_DUE/usb/udc.c rename to Marlin/src/HAL/DUE/usb/udc.c index 048a902d3b5e..60bf0cfff35c 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/udc.c +++ b/Marlin/src/HAL/DUE/usb/udc.c @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifdef ARDUINO_ARCH_SAM diff --git a/Marlin/src/HAL/HAL_DUE/usb/udc.h b/Marlin/src/HAL/DUE/usb/udc.h similarity index 99% rename from Marlin/src/HAL/HAL_DUE/usb/udc.h rename to Marlin/src/HAL/DUE/usb/udc.h index 885bdf04d651..8d92eb5c038a 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/udc.h +++ b/Marlin/src/HAL/DUE/usb/udc.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef _UDC_H_ diff --git a/Marlin/src/HAL/HAL_DUE/usb/udc_desc.h b/Marlin/src/HAL/DUE/usb/udc_desc.h similarity index 97% rename from Marlin/src/HAL/HAL_DUE/usb/udc_desc.h rename to Marlin/src/HAL/DUE/usb/udc_desc.h index 88ed08a96118..052ca08eca78 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/udc_desc.h +++ b/Marlin/src/HAL/DUE/usb/udc_desc.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef _UDC_DESC_H_ diff --git a/Marlin/src/HAL/HAL_DUE/usb/udd.h b/Marlin/src/HAL/DUE/usb/udd.h similarity index 99% rename from Marlin/src/HAL/HAL_DUE/usb/udd.h rename to Marlin/src/HAL/DUE/usb/udd.h index c87763de23fa..7ec8c03dee63 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/udd.h +++ b/Marlin/src/HAL/DUE/usb/udd.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef _UDD_H_ diff --git a/Marlin/src/HAL/HAL_DUE/usb/udi.h b/Marlin/src/HAL/DUE/usb/udi.h similarity index 97% rename from Marlin/src/HAL/HAL_DUE/usb/udi.h rename to Marlin/src/HAL/DUE/usb/udi.h index 709908cad947..febf03b7181e 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/udi.h +++ b/Marlin/src/HAL/DUE/usb/udi.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef _UDI_H_ diff --git a/Marlin/src/HAL/HAL_DUE/usb/udi_cdc.c b/Marlin/src/HAL/DUE/usb/udi_cdc.c similarity index 99% rename from Marlin/src/HAL/HAL_DUE/usb/udi_cdc.c rename to Marlin/src/HAL/DUE/usb/udi_cdc.c index 60c9546ce236..cbe23dbb68fb 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/udi_cdc.c +++ b/Marlin/src/HAL/DUE/usb/udi_cdc.c @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifdef ARDUINO_ARCH_SAM diff --git a/Marlin/src/HAL/HAL_DUE/usb/udi_cdc.h b/Marlin/src/HAL/DUE/usb/udi_cdc.h similarity index 99% rename from Marlin/src/HAL/HAL_DUE/usb/udi_cdc.h rename to Marlin/src/HAL/DUE/usb/udi_cdc.h index 526419c86002..0ecf7bb00e5e 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/udi_cdc.h +++ b/Marlin/src/HAL/DUE/usb/udi_cdc.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef _UDI_CDC_H_ @@ -701,7 +701,7 @@ iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t s * another "Composite Device" module, like "USB HID Mouse (Composite Device)". * * Also, you can refer to application note - * + * * AVR4902 ASF - USB Composite Device. * * \section udi_cdc_use_case_composite_setup Setup steps diff --git a/Marlin/src/HAL/HAL_DUE/usb/udi_cdc_conf.h b/Marlin/src/HAL/DUE/usb/udi_cdc_conf.h similarity index 98% rename from Marlin/src/HAL/HAL_DUE/usb/udi_cdc_conf.h rename to Marlin/src/HAL/DUE/usb/udi_cdc_conf.h index cbd3eb00ae71..d406a87743f3 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/udi_cdc_conf.h +++ b/Marlin/src/HAL/DUE/usb/udi_cdc_conf.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef _UDI_CDC_CONF_H_ diff --git a/Marlin/src/HAL/HAL_DUE/usb/udi_cdc_desc.c b/Marlin/src/HAL/DUE/usb/udi_cdc_desc.c similarity index 98% rename from Marlin/src/HAL/HAL_DUE/usb/udi_cdc_desc.c rename to Marlin/src/HAL/DUE/usb/udi_cdc_desc.c index 8f730ba823d1..97c334e2a854 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/udi_cdc_desc.c +++ b/Marlin/src/HAL/DUE/usb/udi_cdc_desc.c @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifdef ARDUINO_ARCH_SAM diff --git a/Marlin/src/HAL/HAL_DUE/usb/udi_composite_desc.c b/Marlin/src/HAL/DUE/usb/udi_composite_desc.c similarity index 98% rename from Marlin/src/HAL/HAL_DUE/usb/udi_composite_desc.c rename to Marlin/src/HAL/DUE/usb/udi_composite_desc.c index 07bdd1b9d692..da74fbe60dfe 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/udi_composite_desc.c +++ b/Marlin/src/HAL/DUE/usb/udi_composite_desc.c @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifdef ARDUINO_ARCH_SAM diff --git a/Marlin/src/HAL/HAL_DUE/usb/udi_msc.c b/Marlin/src/HAL/DUE/usb/udi_msc.c similarity index 99% rename from Marlin/src/HAL/HAL_DUE/usb/udi_msc.c rename to Marlin/src/HAL/DUE/usb/udi_msc.c index 627bca0d4f5a..b7c3bb5ea016 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/udi_msc.c +++ b/Marlin/src/HAL/DUE/usb/udi_msc.c @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifdef ARDUINO_ARCH_SAM diff --git a/Marlin/src/HAL/HAL_DUE/usb/udi_msc.h b/Marlin/src/HAL/DUE/usb/udi_msc.h similarity index 98% rename from Marlin/src/HAL/HAL_DUE/usb/udi_msc.h rename to Marlin/src/HAL/DUE/usb/udi_msc.h index c632ee4aacee..730dbc8eec56 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/udi_msc.h +++ b/Marlin/src/HAL/DUE/usb/udi_msc.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef _UDI_MSC_H_ @@ -290,7 +290,7 @@ bool udi_msc_trans_block(bool b_read, uint8_t * block, iram_size_t block_size, * another "Composite Device" module, like "USB HID Mouse (Composite Device)". * * Also, you can refer to application note - * + * * AVR4902 ASF - USB Composite Device. * * \section udi_msc_use_case_composite_setup Setup steps diff --git a/Marlin/src/HAL/HAL_DUE/usb/uotghs_device_due.c b/Marlin/src/HAL/DUE/usb/uotghs_device_due.c similarity index 99% rename from Marlin/src/HAL/HAL_DUE/usb/uotghs_device_due.c rename to Marlin/src/HAL/DUE/usb/uotghs_device_due.c index 2a10190c7eca..e13232a39c7d 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/uotghs_device_due.c +++ b/Marlin/src/HAL/DUE/usb/uotghs_device_due.c @@ -42,7 +42,7 @@ */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifdef ARDUINO_ARCH_SAM diff --git a/Marlin/src/HAL/HAL_DUE/usb/uotghs_device_due.h b/Marlin/src/HAL/DUE/usb/uotghs_device_due.h similarity index 99% rename from Marlin/src/HAL/HAL_DUE/usb/uotghs_device_due.h rename to Marlin/src/HAL/DUE/usb/uotghs_device_due.h index 97877994bf66..6df26d63dfd4 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/uotghs_device_due.h +++ b/Marlin/src/HAL/DUE/usb/uotghs_device_due.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef UOTGHS_DEVICE_DUE_H_INCLUDED diff --git a/Marlin/src/HAL/HAL_DUE/usb/uotghs_otg.h b/Marlin/src/HAL/DUE/usb/uotghs_otg.h similarity index 99% rename from Marlin/src/HAL/HAL_DUE/usb/uotghs_otg.h rename to Marlin/src/HAL/DUE/usb/uotghs_otg.h index 86c903b2c18f..eca5e938bbe1 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/uotghs_otg.h +++ b/Marlin/src/HAL/DUE/usb/uotghs_otg.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef UOTGHS_OTG_H_INCLUDED diff --git a/Marlin/src/HAL/HAL_DUE/usb/usb_protocol.h b/Marlin/src/HAL/DUE/usb/usb_protocol.h similarity index 99% rename from Marlin/src/HAL/HAL_DUE/usb/usb_protocol.h rename to Marlin/src/HAL/DUE/usb/usb_protocol.h index 31c783f974cf..ea51a8689649 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/usb_protocol.h +++ b/Marlin/src/HAL/DUE/usb/usb_protocol.h @@ -44,7 +44,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef _USB_PROTOCOL_H_ diff --git a/Marlin/src/HAL/HAL_DUE/usb/usb_protocol_cdc.h b/Marlin/src/HAL/DUE/usb/usb_protocol_cdc.h similarity index 99% rename from Marlin/src/HAL/HAL_DUE/usb/usb_protocol_cdc.h rename to Marlin/src/HAL/DUE/usb/usb_protocol_cdc.h index 49fc7387ef31..d594db52e33b 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/usb_protocol_cdc.h +++ b/Marlin/src/HAL/DUE/usb/usb_protocol_cdc.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef _USB_PROTOCOL_CDC_H_ #define _USB_PROTOCOL_CDC_H_ diff --git a/Marlin/src/HAL/HAL_DUE/usb/usb_protocol_msc.h b/Marlin/src/HAL/DUE/usb/usb_protocol_msc.h similarity index 98% rename from Marlin/src/HAL/HAL_DUE/usb/usb_protocol_msc.h rename to Marlin/src/HAL/DUE/usb/usb_protocol_msc.h index db8f9cafd081..0fef30804662 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/usb_protocol_msc.h +++ b/Marlin/src/HAL/DUE/usb/usb_protocol_msc.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef _USB_PROTOCOL_MSC_H_ diff --git a/Marlin/src/HAL/HAL_DUE/usb/usb_task.c b/Marlin/src/HAL/DUE/usb/usb_task.c similarity index 99% rename from Marlin/src/HAL/HAL_DUE/usb/usb_task.c rename to Marlin/src/HAL/DUE/usb/usb_task.c index 29d02faef703..66bdb265d881 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/usb_task.c +++ b/Marlin/src/HAL/DUE/usb/usb_task.c @@ -41,7 +41,7 @@ * */ -// Support and FAQ: visit Atmel Support +// Support and FAQ: visit Atmel Support #ifdef ARDUINO_ARCH_SAM diff --git a/Marlin/src/HAL/HAL_DUE/usb/usb_task.h b/Marlin/src/HAL/DUE/usb/usb_task.h similarity index 97% rename from Marlin/src/HAL/HAL_DUE/usb/usb_task.h rename to Marlin/src/HAL/DUE/usb/usb_task.h index fad62fda504b..e9831ae0628a 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/usb_task.h +++ b/Marlin/src/HAL/DUE/usb/usb_task.h @@ -41,7 +41,7 @@ * */ /* - * Support and FAQ: visit Atmel Support + * Support and FAQ: visit Atmel Support */ #ifndef _USB_TASK_H_ diff --git a/Marlin/src/HAL/HAL_DUE/watchdog.cpp b/Marlin/src/HAL/DUE/watchdog.cpp similarity index 98% rename from Marlin/src/HAL/HAL_DUE/watchdog.cpp rename to Marlin/src/HAL/DUE/watchdog.cpp index c245633d76a2..0f4697183056 100644 --- a/Marlin/src/HAL/HAL_DUE/watchdog.cpp +++ b/Marlin/src/HAL/DUE/watchdog.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef ARDUINO_ARCH_SAM #include "../../inc/MarlinConfig.h" diff --git a/Marlin/src/HAL/HAL_DUE/watchdog.h b/Marlin/src/HAL/DUE/watchdog.h similarity index 93% rename from Marlin/src/HAL/HAL_DUE/watchdog.h rename to Marlin/src/HAL/DUE/watchdog.h index 7d9665f20e3c..5725a10007a7 100644 --- a/Marlin/src/HAL/HAL_DUE/watchdog.h +++ b/Marlin/src/HAL/DUE/watchdog.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_ESP32/FlushableHardwareSerial.cpp b/Marlin/src/HAL/ESP32/FlushableHardwareSerial.cpp similarity index 93% rename from Marlin/src/HAL/HAL_ESP32/FlushableHardwareSerial.cpp rename to Marlin/src/HAL/ESP32/FlushableHardwareSerial.cpp index 4d70d34edb97..d4b2f42c5351 100644 --- a/Marlin/src/HAL/HAL_ESP32/FlushableHardwareSerial.cpp +++ b/Marlin/src/HAL/ESP32/FlushableHardwareSerial.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/HAL/HAL_ESP32/FlushableHardwareSerial.h b/Marlin/src/HAL/ESP32/FlushableHardwareSerial.h similarity index 93% rename from Marlin/src/HAL/HAL_ESP32/FlushableHardwareSerial.h rename to Marlin/src/HAL/ESP32/FlushableHardwareSerial.h index 703bcbeb73fa..b43caea13c1d 100644 --- a/Marlin/src/HAL/HAL_ESP32/FlushableHardwareSerial.h +++ b/Marlin/src/HAL/ESP32/FlushableHardwareSerial.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_ESP32/HAL.cpp b/Marlin/src/HAL/ESP32/HAL.cpp similarity index 84% rename from Marlin/src/HAL/HAL_ESP32/HAL.cpp rename to Marlin/src/HAL/ESP32/HAL.cpp index d9afa13ab8d2..1e00df5177ad 100644 --- a/Marlin/src/HAL/HAL_ESP32/HAL.cpp +++ b/Marlin/src/HAL/ESP32/HAL.cpp @@ -16,21 +16,18 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef ARDUINO_ARCH_ESP32 -#include "HAL.h" -#include "timers.h" +#include "../../inc/MarlinConfig.h" + #include #include #include #include -#include "../../inc/MarlinConfigPre.h" - #if ENABLED(WIFISUPPORT) #include #include "wifi.h" @@ -97,9 +94,7 @@ void HAL_init_board() { esp3dlib.init(); #elif ENABLED(WIFISUPPORT) wifi_init(); - #if ENABLED(OTASUPPORT) - OTA_init(); - #endif + TERN_(OTASUPPORT, OTA_init()); #if ENABLED(WEBSUPPORT) spiffs_init(); web_init(); @@ -133,9 +128,7 @@ void HAL_idletask() { #if BOTH(WIFISUPPORT, OTASUPPORT) OTA_handle(); #endif - #if ENABLED(ESP3D_WIFISUPPORT) - esp3dlib.idletask(); - #endif + TERN_(ESP3D_WIFISUPPORT, esp3dlib.idletask()); } void HAL_clear_reset_source() { } @@ -176,39 +169,17 @@ void HAL_adc_init() { adc1_config_width(ADC_WIDTH_12Bit); // Configure channels only if used as (re-)configuring a pin for ADC that is used elsewhere might have adverse effects - #if HAS_TEMP_ADC_0 - adc1_set_attenuation(get_channel(TEMP_0_PIN), ADC_ATTEN_11db); - #endif - #if HAS_TEMP_ADC_1 - adc1_set_attenuation(get_channel(TEMP_1_PIN), ADC_ATTEN_11db); - #endif - #if HAS_TEMP_ADC_2 - adc1_set_attenuation(get_channel(TEMP_2_PIN), ADC_ATTEN_11db); - #endif - #if HAS_TEMP_ADC_3 - adc1_set_attenuation(get_channel(TEMP_3_PIN), ADC_ATTEN_11db); - #endif - #if HAS_TEMP_ADC_4 - adc1_set_attenuation(get_channel(TEMP_4_PIN), ADC_ATTEN_11db); - #endif - #if HAS_TEMP_ADC_5 - adc1_set_attenuation(get_channel(TEMP_5_PIN), ADC_ATTEN_11db); - #endif - #if HAS_TEMP_ADC_6 - adc2_set_attenuation(get_channel(TEMP_6_PIN), ADC_ATTEN_11db); - #endif - #if HAS_TEMP_ADC_7 - adc3_set_attenuation(get_channel(TEMP_7_PIN), ADC_ATTEN_11db); - #endif - #if HAS_HEATED_BED - adc1_set_attenuation(get_channel(TEMP_BED_PIN), ADC_ATTEN_11db); - #endif - #if HAS_TEMP_CHAMBER - adc1_set_attenuation(get_channel(TEMP_CHAMBER_PIN), ADC_ATTEN_11db); - #endif - #if ENABLED(FILAMENT_WIDTH_SENSOR) - adc1_set_attenuation(get_channel(FILWIDTH_PIN), ADC_ATTEN_11db); - #endif + TERN_(HAS_TEMP_ADC_0, adc1_set_attenuation(get_channel(TEMP_0_PIN), ADC_ATTEN_11db)); + TERN_(HAS_TEMP_ADC_1, adc1_set_attenuation(get_channel(TEMP_1_PIN), ADC_ATTEN_11db)); + TERN_(HAS_TEMP_ADC_2, adc1_set_attenuation(get_channel(TEMP_2_PIN), ADC_ATTEN_11db)); + TERN_(HAS_TEMP_ADC_3, adc1_set_attenuation(get_channel(TEMP_3_PIN), ADC_ATTEN_11db)); + TERN_(HAS_TEMP_ADC_4, adc1_set_attenuation(get_channel(TEMP_4_PIN), ADC_ATTEN_11db)); + TERN_(HAS_TEMP_ADC_5, adc1_set_attenuation(get_channel(TEMP_5_PIN), ADC_ATTEN_11db)); + TERN_(HAS_TEMP_ADC_6, adc2_set_attenuation(get_channel(TEMP_6_PIN), ADC_ATTEN_11db)); + TERN_(HAS_TEMP_ADC_7, adc3_set_attenuation(get_channel(TEMP_7_PIN), ADC_ATTEN_11db)); + TERN_(HAS_HEATED_BED, adc1_set_attenuation(get_channel(TEMP_BED_PIN), ADC_ATTEN_11db)); + TERN_(HAS_TEMP_CHAMBER, adc1_set_attenuation(get_channel(TEMP_CHAMBER_PIN), ADC_ATTEN_11db)); + TERN_(FILAMENT_WIDTH_SENSOR, adc1_set_attenuation(get_channel(FILWIDTH_PIN), ADC_ATTEN_11db)); // Note that adc2 is shared with the WiFi module, which has higher priority, so the conversion may fail. // That's why we're not setting it up here. diff --git a/Marlin/src/HAL/HAL_ESP32/HAL.h b/Marlin/src/HAL/ESP32/HAL.h similarity index 89% rename from Marlin/src/HAL/HAL_ESP32/HAL.h rename to Marlin/src/HAL/ESP32/HAL.h index a04343b69e5a..ebc16c9525e7 100644 --- a/Marlin/src/HAL/HAL_ESP32/HAL.h +++ b/Marlin/src/HAL/ESP32/HAL.h @@ -14,12 +14,13 @@ * 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 . + * along with this program. If not, see . + * */ #pragma once /** - * Description: HAL for Espressif ESP32 WiFi + * HAL for Espressif ESP32 WiFi */ #define CPU_32_BIT @@ -34,8 +35,6 @@ #include "watchdog.h" #include "i2s.h" -#include "timers.h" - #if ENABLED(WIFISUPPORT) #include "WebSocketSerial.h" #endif @@ -60,9 +59,6 @@ extern portMUX_TYPE spinlock; #else #define MYSERIAL1 webSocketSerial #endif - #define NUM_SERIAL 2 -#else - #define NUM_SERIAL 1 #endif #define CRITICAL_SECTION_START() portENTER_CRITICAL(&spinlock) @@ -100,6 +96,8 @@ void HAL_clear_reset_source(); // reset reason uint8_t HAL_get_reset_source(); +inline void HAL_reboot() {} // reboot the board or restart the bootloader + void _delay_ms(int delay); #pragma GCC diagnostic push @@ -109,19 +107,14 @@ int freeMemory(); void analogWrite(pin_t pin, int value); -// EEPROM -void eeprom_write_byte(uint8_t *pos, unsigned char value); -uint8_t eeprom_read_byte(uint8_t *pos); -void eeprom_read_block (void *__dst, const void *__src, size_t __n); -void eeprom_update_block (const void *__src, void *__dst, size_t __n); - // ADC #define HAL_ANALOG_SELECT(pin) void HAL_adc_init(); -#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin) +#define HAL_ADC_VREF 3.3 #define HAL_ADC_RESOLUTION 10 +#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin) #define HAL_READ_ADC() HAL_adc_result #define HAL_ADC_READY() true @@ -164,14 +157,14 @@ FORCE_INLINE static void DELAY_CYCLES(uint32_t x) { if (stop >= start) { // no overflow, so only loop while in between start and stop: - // 0x00000000 -----------------start****stop-- 0xffffffff + // 0x00000000 -----------------start****stop-- 0xFFFFFFFF while (ccount >= start && ccount < stop) { __asm__ __volatile__ ( "rsr %0, ccount" : "=a" (ccount) ); } } else { // stop did overflow, so only loop while outside of stop and start: - // 0x00000000 **stop-------------------start** 0xffffffff + // 0x00000000 **stop-------------------start** 0xFFFFFFFF while (ccount >= start || ccount < stop) { __asm__ __volatile__ ( "rsr %0, ccount" : "=a" (ccount) ); } diff --git a/Marlin/src/HAL/HAL_ESP32/HAL_SPI.cpp b/Marlin/src/HAL/ESP32/HAL_SPI.cpp similarity index 95% rename from Marlin/src/HAL/HAL_ESP32/HAL_SPI.cpp rename to Marlin/src/HAL/ESP32/HAL_SPI.cpp index 981d9b49c1ff..8e5875fc388d 100644 --- a/Marlin/src/HAL/HAL_ESP32/HAL_SPI.cpp +++ b/Marlin/src/HAL/ESP32/HAL_SPI.cpp @@ -17,20 +17,18 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef ARDUINO_ARCH_ESP32 -#include "HAL.h" +#include "../../inc/MarlinConfig.h" + #include "../shared/HAL_SPI.h" + #include -#include "spi_pins.h" #include -#include "../../core/macros.h" - // ------------------------ // Public Variables // ------------------------ diff --git a/Marlin/src/HAL/HAL_ESP32/Servo.cpp b/Marlin/src/HAL/ESP32/Servo.cpp similarity index 93% rename from Marlin/src/HAL/HAL_ESP32/Servo.cpp rename to Marlin/src/HAL/ESP32/Servo.cpp index 68ee3d9098bf..fcf58485819e 100644 --- a/Marlin/src/HAL/HAL_ESP32/Servo.cpp +++ b/Marlin/src/HAL/ESP32/Servo.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #ifdef ARDUINO_ARCH_ESP32 @@ -61,9 +61,7 @@ void Servo::move(const int value) { if (attach(0) >= 0) { write(value); safe_delay(servo_delay[channel]); - #if ENABLED(DEACTIVATE_SERVOS_AFTER_MOVE) - detach(); - #endif + TERN_(DEACTIVATE_SERVOS_AFTER_MOVE, detach()); } } #endif // HAS_SERVOS diff --git a/Marlin/src/HAL/HAL_ESP32/Servo.h b/Marlin/src/HAL/ESP32/Servo.h similarity index 95% rename from Marlin/src/HAL/HAL_ESP32/Servo.h rename to Marlin/src/HAL/ESP32/Servo.h index 3f575150ebb1..b0d929452732 100644 --- a/Marlin/src/HAL/HAL_ESP32/Servo.h +++ b/Marlin/src/HAL/ESP32/Servo.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_ESP32/WebSocketSerial.cpp b/Marlin/src/HAL/ESP32/WebSocketSerial.cpp similarity index 95% rename from Marlin/src/HAL/HAL_ESP32/WebSocketSerial.cpp rename to Marlin/src/HAL/ESP32/WebSocketSerial.cpp index c7ee6951e11c..ca7f47a1f8bd 100644 --- a/Marlin/src/HAL/HAL_ESP32/WebSocketSerial.cpp +++ b/Marlin/src/HAL/ESP32/WebSocketSerial.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #ifdef ARDUINO_ARCH_ESP32 @@ -86,7 +86,7 @@ int RingBuffer::read() { ring_buffer_pos_t RingBuffer::read(uint8_t *buffer) { ring_buffer_pos_t len = available(); - for(ring_buffer_pos_t i = 0; read_index != write_index; i++) { + for (ring_buffer_pos_t i = 0; read_index != write_index; i++) { buffer[i] = data[read_index]; read_index = NEXT_INDEX(read_index, size); } @@ -139,9 +139,8 @@ size_t WebSocketSerial::write(const uint8_t c) { size_t WebSocketSerial::write(const uint8_t* buffer, size_t size) { size_t written = 0; - for(size_t i = 0; i < size; i++) { + for (size_t i = 0; i < size; i++) written += write(buffer[i]); - } return written; } diff --git a/Marlin/src/HAL/HAL_ESP32/WebSocketSerial.h b/Marlin/src/HAL/ESP32/WebSocketSerial.h similarity index 96% rename from Marlin/src/HAL/HAL_ESP32/WebSocketSerial.h rename to Marlin/src/HAL/ESP32/WebSocketSerial.h index e76a2bc68eff..7a25c6dc5e9c 100644 --- a/Marlin/src/HAL/HAL_ESP32/WebSocketSerial.h +++ b/Marlin/src/HAL/ESP32/WebSocketSerial.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_ESP32/persistent_store_impl.cpp b/Marlin/src/HAL/ESP32/eeprom.cpp similarity index 75% rename from Marlin/src/HAL/HAL_ESP32/persistent_store_impl.cpp rename to Marlin/src/HAL/ESP32/eeprom.cpp index 7113b684128e..1bf687c6fe09 100644 --- a/Marlin/src/HAL/HAL_ESP32/persistent_store_impl.cpp +++ b/Marlin/src/HAL/ESP32/eeprom.cpp @@ -16,29 +16,25 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef ARDUINO_ARCH_ESP32 #include "../../inc/MarlinConfig.h" -#if ENABLED(EEPROM_SETTINGS) && DISABLED(FLASH_EEPROM_EMULATION) +#if ENABLED(EEPROM_SETTINGS) -#include "../shared/persistent_store_api.h" -#include "EEPROM.h" +#include "../shared/eeprom_api.h" +#include -#define EEPROM_SIZE 4096 +#ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE 0x1000 // 4KB +#endif +size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } -bool PersistentStore::access_start() { - return EEPROM.begin(EEPROM_SIZE); -} - -bool PersistentStore::access_finish() { - EEPROM.end(); - return true; -} +bool PersistentStore::access_start() { return EEPROM.begin(MARLIN_EEPROM_SIZE); } +bool PersistentStore::access_finish() { EEPROM.end(); return true; } bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { for (size_t i = 0; i < size; i++) { @@ -57,7 +53,5 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t return false; } -size_t PersistentStore::capacity() { return EEPROM_SIZE; } - #endif // EEPROM_SETTINGS #endif // ARDUINO_ARCH_ESP32 diff --git a/Marlin/src/HAL/HAL_ESP32/endstop_interrupts.h b/Marlin/src/HAL/ESP32/endstop_interrupts.h similarity index 67% rename from Marlin/src/HAL/HAL_ESP32/endstop_interrupts.h rename to Marlin/src/HAL/ESP32/endstop_interrupts.h index 2da1cc7477cf..743ccd99c904 100644 --- a/Marlin/src/HAL/HAL_ESP32/endstop_interrupts.h +++ b/Marlin/src/HAL/ESP32/endstop_interrupts.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -42,43 +42,21 @@ void ICACHE_RAM_ATTR endstop_ISR() { endstops.update(); } void setup_endstop_interrupts() { #define _ATTACH(P) attachInterrupt(digitalPinToInterrupt(P), endstop_ISR, CHANGE) - #if HAS_X_MAX - _ATTACH(X_MAX_PIN); - #endif - #if HAS_X_MIN - _ATTACH(X_MIN_PIN); - #endif - #if HAS_Y_MAX - _ATTACH(Y_MAX_PIN); - #endif - #if HAS_Y_MIN - _ATTACH(Y_MIN_PIN); - #endif - #if HAS_Z_MAX - _ATTACH(Z_MAX_PIN); - #endif - #if HAS_Z_MIN - _ATTACH(Z_MIN_PIN); - #endif - #if HAS_Z2_MAX - _ATTACH(Z2_MAX_PIN); - #endif - #if HAS_Z2_MIN - _ATTACH(Z2_MIN_PIN); - #endif - #if HAS_Z3_MAX - _ATTACH(Z3_MAX_PIN); - #endif - #if HAS_Z3_MIN - _ATTACH(Z3_MIN_PIN); - #endif - #if HAS_Z4_MAX - _ATTACH(Z4_MAX_PIN); - #endif - #if HAS_Z4_MIN - _ATTACH(Z4_MIN_PIN); - #endif - #if HAS_Z_MIN_PROBE_PIN - _ATTACH(Z_MIN_PROBE_PIN); - #endif + TERN_(HAS_X_MAX, _ATTACH(X_MAX_PIN)); + TERN_(HAS_X_MIN, _ATTACH(X_MIN_PIN)); + TERN_(HAS_Y_MAX, _ATTACH(Y_MAX_PIN)); + TERN_(HAS_Y_MIN, _ATTACH(Y_MIN_PIN)); + TERN_(HAS_Z_MAX, _ATTACH(Z_MAX_PIN)); + TERN_(HAS_Z_MIN, _ATTACH(Z_MIN_PIN)); + TERN_(HAS_X2_MAX, _ATTACH(X2_MAX_PIN)); + TERN_(HAS_X2_MIN, _ATTACH(X2_MIN_PIN)); + TERN_(HAS_Y2_MAX, _ATTACH(Y2_MAX_PIN)); + TERN_(HAS_Y2_MIN, _ATTACH(Y2_MIN_PIN)); + TERN_(HAS_Z2_MAX, _ATTACH(Z2_MAX_PIN)); + TERN_(HAS_Z2_MIN, _ATTACH(Z2_MIN_PIN)); + TERN_(HAS_Z3_MAX, _ATTACH(Z3_MAX_PIN)); + TERN_(HAS_Z3_MIN, _ATTACH(Z3_MIN_PIN)); + TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN)); + TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN)); + TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN)); } diff --git a/Marlin/src/HAL/HAL_ESP32/fastio.h b/Marlin/src/HAL/ESP32/fastio.h similarity index 95% rename from Marlin/src/HAL/HAL_ESP32/fastio.h rename to Marlin/src/HAL/ESP32/fastio.h index 9c4efaee9de3..2ded3a5f62e8 100644 --- a/Marlin/src/HAL/HAL_ESP32/fastio.h +++ b/Marlin/src/HAL/ESP32/fastio.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -56,7 +56,7 @@ #define SET_OUTPUT(IO) do{ _SET_OUTPUT(IO); }while(0) // Set pin as PWM -#define SET_PWM(IO) SET_OUTPUT(IO) +#define SET_PWM SET_OUTPUT // Set pin as output and init #define OUT_WRITE(IO,V) do{ _SET_OUTPUT(IO); WRITE(IO,V); }while(0) diff --git a/Marlin/src/HAL/HAL_ESP32/i2s.cpp b/Marlin/src/HAL/ESP32/i2s.cpp similarity index 99% rename from Marlin/src/HAL/HAL_ESP32/i2s.cpp rename to Marlin/src/HAL/ESP32/i2s.cpp index d80c3c24e16f..99b2f755e578 100644 --- a/Marlin/src/HAL/HAL_ESP32/i2s.cpp +++ b/Marlin/src/HAL/ESP32/i2s.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #ifdef ARDUINO_ARCH_ESP32 diff --git a/Marlin/src/HAL/HAL_ESP32/i2s.h b/Marlin/src/HAL/ESP32/i2s.h similarity index 93% rename from Marlin/src/HAL/HAL_ESP32/i2s.h rename to Marlin/src/HAL/ESP32/i2s.h index 63a579a18457..573b983837f5 100644 --- a/Marlin/src/HAL/HAL_ESP32/i2s.h +++ b/Marlin/src/HAL/ESP32/i2s.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/ESP32/inc/Conditionals_LCD.h b/Marlin/src/HAL/ESP32/inc/Conditionals_LCD.h new file mode 100644 index 000000000000..4da600179d6c --- /dev/null +++ b/Marlin/src/HAL/ESP32/inc/Conditionals_LCD.h @@ -0,0 +1,26 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if HAS_SPI_TFT || HAS_FSMC_TFT + #error "Sorry! TFT displays are not available for HAL/ESP32." +#endif diff --git a/Marlin/src/HAL/HAL_ESP32/inc/Conditionals_adv.h b/Marlin/src/HAL/ESP32/inc/Conditionals_adv.h similarity index 91% rename from Marlin/src/HAL/HAL_ESP32/inc/Conditionals_adv.h rename to Marlin/src/HAL/ESP32/inc/Conditionals_adv.h index 0285c52ee365..5f1c4b16019d 100644 --- a/Marlin/src/HAL/HAL_ESP32/inc/Conditionals_adv.h +++ b/Marlin/src/HAL/ESP32/inc/Conditionals_adv.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_AVR/inc/Conditionals_post.h b/Marlin/src/HAL/ESP32/inc/Conditionals_post.h similarity index 91% rename from Marlin/src/HAL/HAL_AVR/inc/Conditionals_post.h rename to Marlin/src/HAL/ESP32/inc/Conditionals_post.h index 0285c52ee365..5f1c4b16019d 100644 --- a/Marlin/src/HAL/HAL_AVR/inc/Conditionals_post.h +++ b/Marlin/src/HAL/ESP32/inc/Conditionals_post.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_ESP32/inc/SanityCheck.h b/Marlin/src/HAL/ESP32/inc/SanityCheck.h similarity index 82% rename from Marlin/src/HAL/HAL_ESP32/inc/SanityCheck.h rename to Marlin/src/HAL/ESP32/inc/SanityCheck.h index b6ad7a3c4bff..f57a6c591028 100644 --- a/Marlin/src/HAL/HAL_ESP32/inc/SanityCheck.h +++ b/Marlin/src/HAL/ESP32/inc/SanityCheck.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,8 +25,8 @@ #error "EMERGENCY_PARSER is not yet implemented for ESP32. Disable EMERGENCY_PARSER to continue." #endif -#if ENABLED(FAST_PWM_FAN) - #error "FAST_PWM_FAN is not yet implemented for this platform." +#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY + #error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on ESP32." #endif #if HAS_TMC_SW_SERIAL diff --git a/Marlin/src/HAL/HAL_ESP32/ota.cpp b/Marlin/src/HAL/ESP32/ota.cpp similarity index 96% rename from Marlin/src/HAL/HAL_ESP32/ota.cpp rename to Marlin/src/HAL/ESP32/ota.cpp index 34a2482c9b64..69a3e25e5631 100644 --- a/Marlin/src/HAL/HAL_ESP32/ota.cpp +++ b/Marlin/src/HAL/ESP32/ota.cpp @@ -14,7 +14,8 @@ * 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 . + * along with this program. If not, see . + * */ #ifdef ARDUINO_ARCH_ESP32 diff --git a/Marlin/src/HAL/HAL_ESP32/ota.h b/Marlin/src/HAL/ESP32/ota.h similarity index 91% rename from Marlin/src/HAL/HAL_ESP32/ota.h rename to Marlin/src/HAL/ESP32/ota.h index 1780fb32c1b3..546ace82dbb8 100644 --- a/Marlin/src/HAL/HAL_ESP32/ota.h +++ b/Marlin/src/HAL/ESP32/ota.h @@ -14,7 +14,8 @@ * 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 . + * along with this program. If not, see . + * */ #pragma once diff --git a/Marlin/src/HAL/HAL_ESP32/servotimers.h b/Marlin/src/HAL/ESP32/servotimers.h similarity index 91% rename from Marlin/src/HAL/HAL_ESP32/servotimers.h rename to Marlin/src/HAL/ESP32/servotimers.h index 0285c52ee365..5f1c4b16019d 100644 --- a/Marlin/src/HAL/HAL_ESP32/servotimers.h +++ b/Marlin/src/HAL/ESP32/servotimers.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_ESP32/spi_pins.h b/Marlin/src/HAL/ESP32/spi_pins.h similarity index 91% rename from Marlin/src/HAL/HAL_ESP32/spi_pins.h rename to Marlin/src/HAL/ESP32/spi_pins.h index 0e67615a2bd3..15f8f2ab6b07 100644 --- a/Marlin/src/HAL/HAL_ESP32/spi_pins.h +++ b/Marlin/src/HAL/ESP32/spi_pins.h @@ -13,7 +13,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_ESP32/spiffs.cpp b/Marlin/src/HAL/ESP32/spiffs.cpp similarity index 94% rename from Marlin/src/HAL/HAL_ESP32/spiffs.cpp rename to Marlin/src/HAL/ESP32/spiffs.cpp index 0013dd6093ad..a0e713bff0bb 100644 --- a/Marlin/src/HAL/HAL_ESP32/spiffs.cpp +++ b/Marlin/src/HAL/ESP32/spiffs.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef ARDUINO_ARCH_ESP32 #include "../../inc/MarlinConfigPre.h" diff --git a/Marlin/src/HAL/HAL_ESP32/spiffs.h b/Marlin/src/HAL/ESP32/spiffs.h similarity index 92% rename from Marlin/src/HAL/HAL_ESP32/spiffs.h rename to Marlin/src/HAL/ESP32/spiffs.h index b9cbb23bdae4..64ec7dd11e14 100644 --- a/Marlin/src/HAL/HAL_ESP32/spiffs.h +++ b/Marlin/src/HAL/ESP32/spiffs.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_ESP32/timers.cpp b/Marlin/src/HAL/ESP32/timers.cpp similarity index 98% rename from Marlin/src/HAL/HAL_ESP32/timers.cpp rename to Marlin/src/HAL/ESP32/timers.cpp index ef181a438ca6..3300aea8a89c 100644 --- a/Marlin/src/HAL/HAL_ESP32/timers.cpp +++ b/Marlin/src/HAL/ESP32/timers.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef ARDUINO_ARCH_ESP32 #include @@ -28,9 +27,7 @@ #include #include -#include "HAL.h" - -#include "timers.h" +#include "../../inc/MarlinConfig.h" // ------------------------ // Local defines diff --git a/Marlin/src/HAL/HAL_ESP32/timers.h b/Marlin/src/HAL/ESP32/timers.h similarity index 84% rename from Marlin/src/HAL/HAL_ESP32/timers.h rename to Marlin/src/HAL/ESP32/timers.h index bc4306be20b4..d722670f33cf 100644 --- a/Marlin/src/HAL/HAL_ESP32/timers.h +++ b/Marlin/src/HAL/ESP32/timers.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -38,10 +38,18 @@ typedef uint64_t hal_timer_t; #define HAL_TIMER_TYPE_MAX 0xFFFFFFFFFFFFFFFFULL -#define STEP_TIMER_NUM 0 // index of timer to use for stepper -#define TEMP_TIMER_NUM 1 // index of timer to use for temperature -#define PWM_TIMER_NUM 2 // index of timer to use for PWM outputs -#define PULSE_TIMER_NUM STEP_TIMER_NUM +#ifndef STEP_TIMER_NUM + #define STEP_TIMER_NUM 0 // Timer Index for Stepper +#endif +#ifndef PULSE_TIMER_NUM + #define PULSE_TIMER_NUM STEP_TIMER_NUM +#endif +#ifndef TEMP_TIMER_NUM + #define TEMP_TIMER_NUM 1 // Timer Index for Temperature +#endif +#ifndef PWM_TIMER_NUM + #define PWM_TIMER_NUM 2 // index of timer to use for PWM outputs +#endif #define HAL_TIMER_RATE APB_CLK_FREQ // frequency of timer peripherals @@ -79,9 +87,15 @@ typedef uint64_t hal_timer_t; #define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM) #define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM) -#define HAL_TEMP_TIMER_ISR() extern "C" void tempTC_Handler() -#define HAL_STEP_TIMER_ISR() extern "C" void stepTC_Handler() -#define HAL_PWM_TIMER_ISR() extern "C" void pwmTC_Handler() +#ifndef HAL_TEMP_TIMER_ISR + #define HAL_TEMP_TIMER_ISR() extern "C" void tempTC_Handler() +#endif +#ifndef HAL_STEP_TIMER_ISR + #define HAL_STEP_TIMER_ISR() extern "C" void stepTC_Handler() +#endif +#ifndef HAL_PWM_TIMER_ISR + #define HAL_PWM_TIMER_ISR() extern "C" void pwmTC_Handler() +#endif extern "C" void tempTC_Handler(); extern "C" void stepTC_Handler(); diff --git a/Marlin/src/HAL/HAL_ESP32/watchdog.cpp b/Marlin/src/HAL/ESP32/watchdog.cpp similarity index 93% rename from Marlin/src/HAL/HAL_ESP32/watchdog.cpp rename to Marlin/src/HAL/ESP32/watchdog.cpp index 9f681e609585..f6fcfa3182c4 100644 --- a/Marlin/src/HAL/HAL_ESP32/watchdog.cpp +++ b/Marlin/src/HAL/ESP32/watchdog.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef ARDUINO_ARCH_ESP32 #include "../../inc/MarlinConfig.h" diff --git a/Marlin/src/HAL/HAL_ESP32/watchdog.h b/Marlin/src/HAL/ESP32/watchdog.h similarity index 93% rename from Marlin/src/HAL/HAL_ESP32/watchdog.h rename to Marlin/src/HAL/ESP32/watchdog.h index 7e079908658e..b6c169e34742 100644 --- a/Marlin/src/HAL/HAL_ESP32/watchdog.h +++ b/Marlin/src/HAL/ESP32/watchdog.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_ESP32/web.cpp b/Marlin/src/HAL/ESP32/web.cpp similarity index 95% rename from Marlin/src/HAL/HAL_ESP32/web.cpp rename to Marlin/src/HAL/ESP32/web.cpp index b795efe3c55d..7a27707a3e14 100644 --- a/Marlin/src/HAL/HAL_ESP32/web.cpp +++ b/Marlin/src/HAL/ESP32/web.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef ARDUINO_ARCH_ESP32 #include "../../inc/MarlinConfigPre.h" diff --git a/Marlin/src/HAL/HAL_ESP32/web.h b/Marlin/src/HAL/ESP32/web.h similarity index 91% rename from Marlin/src/HAL/HAL_ESP32/web.h rename to Marlin/src/HAL/ESP32/web.h index 8dbefd8eefc9..60023ac636a3 100644 --- a/Marlin/src/HAL/HAL_ESP32/web.h +++ b/Marlin/src/HAL/ESP32/web.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_ESP32/wifi.cpp b/Marlin/src/HAL/ESP32/wifi.cpp similarity index 96% rename from Marlin/src/HAL/HAL_ESP32/wifi.cpp rename to Marlin/src/HAL/ESP32/wifi.cpp index 9203dd62e73d..f4cf5a606a03 100644 --- a/Marlin/src/HAL/HAL_ESP32/wifi.cpp +++ b/Marlin/src/HAL/ESP32/wifi.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef ARDUINO_ARCH_ESP32 #include "../../core/serial.h" diff --git a/Marlin/src/HAL/HAL_ESP32/wifi.h b/Marlin/src/HAL/ESP32/wifi.h similarity index 92% rename from Marlin/src/HAL/HAL_ESP32/wifi.h rename to Marlin/src/HAL/ESP32/wifi.h index 580c6c87f416..759a73b25293 100644 --- a/Marlin/src/HAL/HAL_ESP32/wifi.h +++ b/Marlin/src/HAL/ESP32/wifi.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL.h b/Marlin/src/HAL/HAL.h index fa2782cfcbad..5eca2f7eacfe 100644 --- a/Marlin/src/HAL/HAL.h +++ b/Marlin/src/HAL/HAL.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,10 +25,28 @@ #include HAL_PATH(.,HAL.h) +#ifdef SERIAL_PORT_2 + #define NUM_SERIAL 2 +#else + #define NUM_SERIAL 1 +#endif + #define HAL_ADC_RANGE _BV(HAL_ADC_RESOLUTION) +#ifndef I2C_ADDRESS + #define I2C_ADDRESS(A) uint8_t(A) +#endif + +// Needed for AVR sprintf_P PROGMEM extension +#ifndef S_FMT + #define S_FMT "%s" +#endif + +// String helper +#ifndef PGMSTR + #define PGMSTR(NAM,STR) const char NAM[] = STR +#endif + inline void watchdog_refresh() { - #if ENABLED(USE_WATCHDOG) - HAL_watchdog_refresh(); - #endif + TERN_(USE_WATCHDOG, HAL_watchdog_refresh()); } diff --git a/Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp b/Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp deleted file mode 100644 index a0c636a9f976..000000000000 --- a/Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp +++ /dev/null @@ -1,792 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * MarlinSerial.cpp - Hardware serial library for Wiring - * Copyright (c) 2006 Nicholas Zambetti. All right reserved. - * - * Modified 23 November 2006 by David A. Mellis - * Modified 28 September 2010 by Mark Sproul - * Modified 14 February 2016 by Andreas Hardtung (added tx buffer) - * Modified 01 October 2017 by Eduardo José Tagle (added XON/XOFF) - * Modified 10 June 2018 by Eduardo José Tagle (See #10991) - * Templatized 01 October 2018 by Eduardo José Tagle to allow multiple instances - */ - -#ifdef __AVR__ - -// Disable HardwareSerial.cpp to support chips without a UART (Attiny, etc.) - -#include "../../inc/MarlinConfig.h" - -#if !defined(USBCON) && (defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H)) - - #include "MarlinSerial.h" - #include "../../MarlinCore.h" - - template typename MarlinSerial::ring_buffer_r MarlinSerial::rx_buffer = { 0, 0, { 0 } }; - template typename MarlinSerial::ring_buffer_t MarlinSerial::tx_buffer = { 0 }; - template bool MarlinSerial::_written = false; - template uint8_t MarlinSerial::xon_xoff_state = MarlinSerial::XON_XOFF_CHAR_SENT | MarlinSerial::XON_CHAR; - template uint8_t MarlinSerial::rx_dropped_bytes = 0; - template uint8_t MarlinSerial::rx_buffer_overruns = 0; - template uint8_t MarlinSerial::rx_framing_errors = 0; - template typename MarlinSerial::ring_buffer_pos_t MarlinSerial::rx_max_enqueued = 0; - - // A SW memory barrier, to ensure GCC does not overoptimize loops - #define sw_barrier() asm volatile("": : :"memory"); - - #include "../../feature/emergency_parser.h" - - // "Atomically" read the RX head index value without disabling interrupts: - // This MUST be called with RX interrupts enabled, and CAN'T be called - // from the RX ISR itself! - template - FORCE_INLINE typename MarlinSerial::ring_buffer_pos_t MarlinSerial::atomic_read_rx_head() { - if (Cfg::RX_SIZE > 256) { - // Keep reading until 2 consecutive reads return the same value, - // meaning there was no update in-between caused by an interrupt. - // This works because serial RX interrupts happen at a slower rate - // than successive reads of a variable, so 2 consecutive reads with - // the same value means no interrupt updated it. - ring_buffer_pos_t vold, vnew = rx_buffer.head; - sw_barrier(); - do { - vold = vnew; - vnew = rx_buffer.head; - sw_barrier(); - } while (vold != vnew); - return vnew; - } - else { - // With an 8bit index, reads are always atomic. No need for special handling - return rx_buffer.head; - } - } - - template - volatile bool MarlinSerial::rx_tail_value_not_stable = false; - template - volatile uint16_t MarlinSerial::rx_tail_value_backup = 0; - - // Set RX tail index, taking into account the RX ISR could interrupt - // the write to this variable in the middle - So a backup strategy - // is used to ensure reads of the correct values. - // -Must NOT be called from the RX ISR - - template - FORCE_INLINE void MarlinSerial::atomic_set_rx_tail(typename MarlinSerial::ring_buffer_pos_t value) { - if (Cfg::RX_SIZE > 256) { - // Store the new value in the backup - rx_tail_value_backup = value; - sw_barrier(); - // Flag we are about to change the true value - rx_tail_value_not_stable = true; - sw_barrier(); - // Store the new value - rx_buffer.tail = value; - sw_barrier(); - // Signal the new value is completely stored into the value - rx_tail_value_not_stable = false; - sw_barrier(); - } - else - rx_buffer.tail = value; - } - - // Get the RX tail index, taking into account the read could be - // interrupting in the middle of the update of that index value - // -Called from the RX ISR - - template - FORCE_INLINE typename MarlinSerial::ring_buffer_pos_t MarlinSerial::atomic_read_rx_tail() { - if (Cfg::RX_SIZE > 256) { - // If the true index is being modified, return the backup value - if (rx_tail_value_not_stable) return rx_tail_value_backup; - } - // The true index is stable, return it - return rx_buffer.tail; - } - - // (called with RX interrupts disabled) - template - FORCE_INLINE void MarlinSerial::store_rxd_char() { - - static EmergencyParser::State emergency_state; // = EP_RESET - - // Get the tail - Nothing can alter its value while this ISR is executing, but there's - // a chance that this ISR interrupted the main process while it was updating the index. - // The backup mechanism ensures the correct value is always returned. - const ring_buffer_pos_t t = atomic_read_rx_tail(); - - // Get the head pointer - This ISR is the only one that modifies its value, so it's safe to read here - ring_buffer_pos_t h = rx_buffer.head; - - // Get the next element - ring_buffer_pos_t i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); - - // This must read the R_UCSRA register before reading the received byte to detect error causes - if (Cfg::DROPPED_RX && B_DOR && !++rx_dropped_bytes) --rx_dropped_bytes; - if (Cfg::RX_OVERRUNS && B_DOR && !++rx_buffer_overruns) --rx_buffer_overruns; - if (Cfg::RX_FRAMING_ERRORS && B_FE && !++rx_framing_errors) --rx_framing_errors; - - // Read the character from the USART - uint8_t c = R_UDR; - - if (Cfg::EMERGENCYPARSER) emergency_parser.update(emergency_state, c); - - // If the character is to be stored at the index just before the tail - // (such that the head would advance to the current tail), the RX FIFO is - // full, so don't write the character or advance the head. - if (i != t) { - rx_buffer.buffer[h] = c; - h = i; - } - else if (Cfg::DROPPED_RX && !++rx_dropped_bytes) - --rx_dropped_bytes; - - if (Cfg::MAX_RX_QUEUED) { - // Calculate count of bytes stored into the RX buffer - const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); - - // Keep track of the maximum count of enqueued bytes - NOLESS(rx_max_enqueued, rx_count); - } - - if (Cfg::XONOFF) { - // If the last char that was sent was an XON - if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XON_CHAR) { - - // Bytes stored into the RX buffer - const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); - - // If over 12.5% of RX buffer capacity, send XOFF before running out of - // RX buffer space .. 325 bytes @ 250kbits/s needed to let the host react - // and stop sending bytes. This translates to 13mS propagation time. - if (rx_count >= (Cfg::RX_SIZE) / 8) { - - // At this point, definitely no TX interrupt was executing, since the TX ISR can't be preempted. - // Don't enable the TX interrupt here as a means to trigger the XOFF char, because if it happens - // to be in the middle of trying to disable the RX interrupt in the main program, eventually the - // enabling of the TX interrupt could be undone. The ONLY reliable thing this can do to ensure - // the sending of the XOFF char is to send it HERE AND NOW. - - // About to send the XOFF char - xon_xoff_state = XOFF_CHAR | XON_XOFF_CHAR_SENT; - - // Wait until the TX register becomes empty and send it - Here there could be a problem - // - While waiting for the TX register to empty, the RX register could receive a new - // character. This must also handle that situation! - while (!B_UDRE) { - - if (B_RXC) { - // A char arrived while waiting for the TX buffer to be empty - Receive and process it! - - i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); - - // Read the character from the USART - c = R_UDR; - - if (Cfg::EMERGENCYPARSER) emergency_parser.update(emergency_state, c); - - // If the character is to be stored at the index just before the tail - // (such that the head would advance to the current tail), the FIFO is - // full, so don't write the character or advance the head. - if (i != t) { - rx_buffer.buffer[h] = c; - h = i; - } - else if (Cfg::DROPPED_RX && !++rx_dropped_bytes) - --rx_dropped_bytes; - } - sw_barrier(); - } - - R_UDR = XOFF_CHAR; - - // Clear the TXC bit -- "can be cleared by writing a one to its bit - // location". This makes sure flush() won't return until the bytes - // actually got written - B_TXC = 1; - - // At this point there could be a race condition between the write() function - // and this sending of the XOFF char. This interrupt could happen between the - // wait to be empty TX buffer loop and the actual write of the character. Since - // the TX buffer is full because it's sending the XOFF char, the only way to be - // sure the write() function will succeed is to wait for the XOFF char to be - // completely sent. Since an extra character could be received during the wait - // it must also be handled! - while (!B_UDRE) { - - if (B_RXC) { - // A char arrived while waiting for the TX buffer to be empty - Receive and process it! - - i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); - - // Read the character from the USART - c = R_UDR; - - if (Cfg::EMERGENCYPARSER) - emergency_parser.update(emergency_state, c); - - // If the character is to be stored at the index just before the tail - // (such that the head would advance to the current tail), the FIFO is - // full, so don't write the character or advance the head. - if (i != t) { - rx_buffer.buffer[h] = c; - h = i; - } - else if (Cfg::DROPPED_RX && !++rx_dropped_bytes) - --rx_dropped_bytes; - } - sw_barrier(); - } - - // At this point everything is ready. The write() function won't - // have any issues writing to the UART TX register if it needs to! - } - } - } - - // Store the new head value - The main loop will retry until the value is stable - rx_buffer.head = h; - } - - // (called with TX irqs disabled) - template - FORCE_INLINE void MarlinSerial::_tx_udr_empty_irq() { - if (Cfg::TX_SIZE > 0) { - // Read positions - uint8_t t = tx_buffer.tail; - const uint8_t h = tx_buffer.head; - - if (Cfg::XONOFF) { - // If an XON char is pending to be sent, do it now - if (xon_xoff_state == XON_CHAR) { - - // Send the character - R_UDR = XON_CHAR; - - // clear the TXC bit -- "can be cleared by writing a one to its bit - // location". This makes sure flush() won't return until the bytes - // actually got written - B_TXC = 1; - - // Remember we sent it. - xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT; - - // If nothing else to transmit, just disable TX interrupts. - if (h == t) B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed) - - return; - } - } - - // If nothing to transmit, just disable TX interrupts. This could - // happen as the result of the non atomicity of the disabling of RX - // interrupts that could end reenabling TX interrupts as a side effect. - if (h == t) { - B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed) - return; - } - - // There is something to TX, Send the next byte - const uint8_t c = tx_buffer.buffer[t]; - t = (t + 1) & (Cfg::TX_SIZE - 1); - R_UDR = c; - tx_buffer.tail = t; - - // Clear the TXC bit (by writing a one to its bit location). - // Ensures flush() won't return until the bytes are actually written/ - B_TXC = 1; - - // Disable interrupts if there is nothing to transmit following this byte - if (h == t) B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed) - } - } - - // Public Methods - template - void MarlinSerial::begin(const long baud) { - uint16_t baud_setting; - bool useU2X = true; - - #if F_CPU == 16000000UL && SERIAL_PORT == 0 - // Hard-coded exception for compatibility with the bootloader shipped - // with the Duemilanove and previous boards, and the firmware on the - // 8U2 on the Uno and Mega 2560. - if (baud == 57600) useU2X = false; - #endif - - R_UCSRA = 0; - if (useU2X) { - B_U2X = 1; - baud_setting = (F_CPU / 4 / baud - 1) / 2; - } - else - baud_setting = (F_CPU / 8 / baud - 1) / 2; - - // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register) - R_UBRRH = baud_setting >> 8; - R_UBRRL = baud_setting; - - B_RXEN = 1; - B_TXEN = 1; - B_RXCIE = 1; - if (Cfg::TX_SIZE > 0) B_UDRIE = 0; - _written = false; - } - - template - void MarlinSerial::end() { - B_RXEN = 0; - B_TXEN = 0; - B_RXCIE = 0; - B_UDRIE = 0; - } - - template - int MarlinSerial::peek() { - const ring_buffer_pos_t h = atomic_read_rx_head(), t = rx_buffer.tail; - return h == t ? -1 : rx_buffer.buffer[t]; - } - - template - int MarlinSerial::read() { - const ring_buffer_pos_t h = atomic_read_rx_head(); - - // Read the tail. Main thread owns it, so it is safe to directly read it - ring_buffer_pos_t t = rx_buffer.tail; - - // If nothing to read, return now - if (h == t) return -1; - - // Get the next char - const int v = rx_buffer.buffer[t]; - t = (ring_buffer_pos_t)(t + 1) & (Cfg::RX_SIZE - 1); - - // Advance tail - Making sure the RX ISR will always get an stable value, even - // if it interrupts the writing of the value of that variable in the middle. - atomic_set_rx_tail(t); - - if (Cfg::XONOFF) { - // If the XOFF char was sent, or about to be sent... - if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) { - // Get count of bytes in the RX buffer - const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); - if (rx_count < (Cfg::RX_SIZE) / 10) { - if (Cfg::TX_SIZE > 0) { - // Signal we want an XON character to be sent. - xon_xoff_state = XON_CHAR; - // Enable TX ISR. Non atomic, but it will eventually enable them - B_UDRIE = 1; - } - else { - // If not using TX interrupts, we must send the XON char now - xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT; - while (!B_UDRE) sw_barrier(); - R_UDR = XON_CHAR; - } - } - } - } - - return v; - } - - template - typename MarlinSerial::ring_buffer_pos_t MarlinSerial::available() { - const ring_buffer_pos_t h = atomic_read_rx_head(), t = rx_buffer.tail; - return (ring_buffer_pos_t)(Cfg::RX_SIZE + h - t) & (Cfg::RX_SIZE - 1); - } - - template - void MarlinSerial::flush() { - - // Set the tail to the head: - // - Read the RX head index in a safe way. (See atomic_read_rx_head.) - // - Set the tail, making sure the RX ISR will always get a stable value, even - // if it interrupts the writing of the value of that variable in the middle. - atomic_set_rx_tail(atomic_read_rx_head()); - - if (Cfg::XONOFF) { - // If the XOFF char was sent, or about to be sent... - if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) { - if (Cfg::TX_SIZE > 0) { - // Signal we want an XON character to be sent. - xon_xoff_state = XON_CHAR; - // Enable TX ISR. Non atomic, but it will eventually enable it. - B_UDRIE = 1; - } - else { - // If not using TX interrupts, we must send the XON char now - xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT; - while (!B_UDRE) sw_barrier(); - R_UDR = XON_CHAR; - } - } - } - } - - template - void MarlinSerial::write(const uint8_t c) { - if (Cfg::TX_SIZE == 0) { - - _written = true; - while (!B_UDRE) sw_barrier(); - R_UDR = c; - - } - else { - - _written = true; - - // If the TX interrupts are disabled and the data register - // is empty, just write the byte to the data register and - // be done. This shortcut helps significantly improve the - // effective datarate at high (>500kbit/s) bitrates, where - // interrupt overhead becomes a slowdown. - // Yes, there is a race condition between the sending of the - // XOFF char at the RX ISR, but it is properly handled there - if (!B_UDRIE && B_UDRE) { - R_UDR = c; - - // clear the TXC bit -- "can be cleared by writing a one to its bit - // location". This makes sure flush() won't return until the bytes - // actually got written - B_TXC = 1; - return; - } - - const uint8_t i = (tx_buffer.head + 1) & (Cfg::TX_SIZE - 1); - - // If global interrupts are disabled (as the result of being called from an ISR)... - if (!ISRS_ENABLED()) { - - // Make room by polling if it is possible to transmit, and do so! - while (i == tx_buffer.tail) { - - // If we can transmit another byte, do it. - if (B_UDRE) _tx_udr_empty_irq(); - - // Make sure compiler rereads tx_buffer.tail - sw_barrier(); - } - } - else { - // Interrupts are enabled, just wait until there is space - while (i == tx_buffer.tail) sw_barrier(); - } - - // Store new char. head is always safe to move - tx_buffer.buffer[tx_buffer.head] = c; - tx_buffer.head = i; - - // Enable TX ISR - Non atomic, but it will eventually enable TX ISR - B_UDRIE = 1; - } - } - - template - void MarlinSerial::flushTX() { - - if (Cfg::TX_SIZE == 0) { - // No bytes written, no need to flush. This special case is needed since there's - // no way to force the TXC (transmit complete) bit to 1 during initialization. - if (!_written) return; - - // Wait until everything was transmitted - while (!B_TXC) sw_barrier(); - - // At this point nothing is queued anymore (DRIE is disabled) and - // the hardware finished transmission (TXC is set). - - } - else { - - // No bytes written, no need to flush. This special case is needed since there's - // no way to force the TXC (transmit complete) bit to 1 during initialization. - if (!_written) return; - - // If global interrupts are disabled (as the result of being called from an ISR)... - if (!ISRS_ENABLED()) { - - // Wait until everything was transmitted - We must do polling, as interrupts are disabled - while (tx_buffer.head != tx_buffer.tail || !B_TXC) { - - // If there is more space, send an extra character - if (B_UDRE) _tx_udr_empty_irq(); - - sw_barrier(); - } - - } - else { - // Wait until everything was transmitted - while (tx_buffer.head != tx_buffer.tail || !B_TXC) sw_barrier(); - } - - // At this point nothing is queued anymore (DRIE is disabled) and - // the hardware finished transmission (TXC is set). - } - } - - /** - * Imports from print.h - */ - - template - void MarlinSerial::print(char c, int base) { - print((long)c, base); - } - - template - void MarlinSerial::print(unsigned char b, int base) { - print((unsigned long)b, base); - } - - template - void MarlinSerial::print(int n, int base) { - print((long)n, base); - } - - template - void MarlinSerial::print(unsigned int n, int base) { - print((unsigned long)n, base); - } - - template - void MarlinSerial::print(long n, int base) { - if (base == 0) write(n); - else if (base == 10) { - if (n < 0) { print('-'); n = -n; } - printNumber(n, 10); - } - else - printNumber(n, base); - } - - template - void MarlinSerial::print(unsigned long n, int base) { - if (base == 0) write(n); - else printNumber(n, base); - } - - template - void MarlinSerial::print(double n, int digits) { - printFloat(n, digits); - } - - template - void MarlinSerial::println() { - print('\r'); - print('\n'); - } - - template - void MarlinSerial::println(const String& s) { - print(s); - println(); - } - - template - void MarlinSerial::println(const char c[]) { - print(c); - println(); - } - - template - void MarlinSerial::println(char c, int base) { - print(c, base); - println(); - } - - template - void MarlinSerial::println(unsigned char b, int base) { - print(b, base); - println(); - } - - template - void MarlinSerial::println(int n, int base) { - print(n, base); - println(); - } - - template - void MarlinSerial::println(unsigned int n, int base) { - print(n, base); - println(); - } - - template - void MarlinSerial::println(long n, int base) { - print(n, base); - println(); - } - - template - void MarlinSerial::println(unsigned long n, int base) { - print(n, base); - println(); - } - - template - void MarlinSerial::println(double n, int digits) { - print(n, digits); - println(); - } - - // Private Methods - - template - void MarlinSerial::printNumber(unsigned long n, uint8_t base) { - if (n) { - unsigned char buf[8 * sizeof(long)]; // Enough space for base 2 - int8_t i = 0; - while (n) { - buf[i++] = n % base; - n /= base; - } - while (i--) - print((char)(buf[i] + (buf[i] < 10 ? '0' : 'A' - 10))); - } - else - print('0'); - } - - template - void MarlinSerial::printFloat(double number, uint8_t digits) { - // Handle negative numbers - if (number < 0.0) { - print('-'); - number = -number; - } - - // Round correctly so that print(1.999, 2) prints as "2.00" - double rounding = 0.5; - for (uint8_t i = 0; i < digits; ++i) rounding *= 0.1; - number += rounding; - - // Extract the integer part of the number and print it - unsigned long int_part = (unsigned long)number; - double remainder = number - (double)int_part; - print(int_part); - - // Print the decimal point, but only if there are digits beyond - if (digits) { - print('.'); - // Extract digits from the remainder one at a time - while (digits--) { - remainder *= 10.0; - int toPrint = int(remainder); - print(toPrint); - remainder -= toPrint; - } - } - } - - // Hookup ISR handlers - ISR(SERIAL_REGNAME(USART,SERIAL_PORT,_RX_vect)) { - MarlinSerial>::store_rxd_char(); - } - - ISR(SERIAL_REGNAME(USART,SERIAL_PORT,_UDRE_vect)) { - MarlinSerial>::_tx_udr_empty_irq(); - } - - // Preinstantiate - template class MarlinSerial>; - - // Instantiate - MarlinSerial> customizedSerial1; - - #ifdef SERIAL_PORT_2 - - // Hookup ISR handlers - ISR(SERIAL_REGNAME(USART,SERIAL_PORT_2,_RX_vect)) { - MarlinSerial>::store_rxd_char(); - } - - ISR(SERIAL_REGNAME(USART,SERIAL_PORT_2,_UDRE_vect)) { - MarlinSerial>::_tx_udr_empty_irq(); - } - - // Preinstantiate - template class MarlinSerial>; - - // Instantiate - MarlinSerial> customizedSerial2; - - #endif - -#endif // !USBCON && (UBRRH || UBRR0H || UBRR1H || UBRR2H || UBRR3H) - -#ifdef INTERNAL_SERIAL_PORT - - ISR(SERIAL_REGNAME(USART,INTERNAL_SERIAL_PORT,_RX_vect)) { - MarlinSerial>::store_rxd_char(); - } - - ISR(SERIAL_REGNAME(USART,INTERNAL_SERIAL_PORT,_UDRE_vect)) { - MarlinSerial>::_tx_udr_empty_irq(); - } - - // Preinstantiate - template class MarlinSerial>; - - // Instantiate - MarlinSerial> internalSerial; - -#endif - -#ifdef DGUS_SERIAL_PORT - - template - typename MarlinSerial::ring_buffer_pos_t MarlinSerial::get_tx_buffer_free() { - const ring_buffer_pos_t t = tx_buffer.tail, // next byte to send. - h = tx_buffer.head; // next pos for queue. - int ret = t - h - 1; - if (ret < 0) ret += Cfg::TX_SIZE + 1; - return ret; - } - - ISR(SERIAL_REGNAME(USART,DGUS_SERIAL_PORT,_RX_vect)) { - MarlinSerial>::store_rxd_char(); - } - - ISR(SERIAL_REGNAME(USART,DGUS_SERIAL_PORT,_UDRE_vect)) { - MarlinSerial>::_tx_udr_empty_irq(); - } - - // Preinstantiate - template class MarlinSerial>; - - // Instantiate - MarlinSerial> internalDgusSerial; - -#endif - -// For AT90USB targets use the UART for BT interfacing -#if defined(USBCON) && ENABLED(BLUETOOTH) - HardwareSerial bluetoothSerial; -#endif - -#endif // __AVR__ diff --git a/Marlin/src/HAL/HAL_DUE/fastio/G2_PWM.cpp b/Marlin/src/HAL/HAL_DUE/fastio/G2_PWM.cpp deleted file mode 100644 index fd2c6ccf9770..000000000000 --- a/Marlin/src/HAL/HAL_DUE/fastio/G2_PWM.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * The PWM module is only used to generate interrupts at specified times. It - * is NOT used to directly toggle pins. The ISR writes to the pin assigned to - * that interrupt. - * - * All PWMs use the same repetition rate. The G2 needs about 10KHz min in order to - * not have obvious ripple on the Vref signals. - * - * The data structures are setup to minimize the computation done by the ISR which - * minimizes ISR execution time. Execution times are 0.8 to 1.1 microseconds. - * - * FIve PWM interrupt sources are used. Channel 0 sets the base period. All Vref - * signals are set active when this counter overflows and resets to zero. The compare - * values in channels 1-4 are set to give the desired duty cycle for that Vref pin. - * When counter 0 matches the compare value then that channel generates an interrupt. - * The ISR checks the source of the interrupt and sets the corresponding pin inactive. - * - * Some jitter in the Vref signal is OK so the interrupt priority is left at its default value. - */ - -#include "../../../inc/MarlinConfig.h" - -#if MB(PRINTRBOARD_G2) - -#include "G2_PWM.h" - -volatile uint32_t *SODR_A = &PIOA->PIO_SODR, - *SODR_B = &PIOB->PIO_SODR, - *CODR_A = &PIOA->PIO_CODR, - *CODR_B = &PIOB->PIO_CODR; - -PWM_map ISR_table[NUM_PWMS] = PWM_MAP_INIT; - -void Stepper::digipot_init() { - - OUT_WRITE(MOTOR_CURRENT_PWM_X_PIN, 0); // init pins - OUT_WRITE(MOTOR_CURRENT_PWM_Y_PIN, 0); - OUT_WRITE(MOTOR_CURRENT_PWM_Z_PIN, 0); - OUT_WRITE(MOTOR_CURRENT_PWM_E_PIN, 0); - - #define WPKEY (0x50574D << 8) // “PWM” in ASCII - #define WPCMD_DIS_SW 0 // command to disable Write Protect SW - #define WPRG_ALL (PWM_WPCR_WPRG0 | PWM_WPCR_WPRG1 | PWM_WPCR_WPRG2 | PWM_WPCR_WPRG3 | PWM_WPCR_WPRG4 | PWM_WPCR_WPRG5) // all Write Protect Groups - - #define PWM_CLOCK_F F_CPU / 1000000UL // set clock to 1MHz - - PMC->PMC_PCER1 = PMC_PCER1_PID36; // enable PWM controller clock (disabled on power up) - - PWM->PWM_WPCR = WPKEY | WPRG_ALL | WPCMD_DIS_SW; // enable setting of all PWM registers - PWM->PWM_CLK = PWM_CLOCK_F; // enable CLK_A and set it to 1MHz, leave CLK_B disabled - PWM->PWM_CH_NUM[0].PWM_CMR = 0b1011; // set channel 0 to Clock A input & to left aligned - PWM->PWM_CH_NUM[1].PWM_CMR = 0b1011; // set channel 1 to Clock A input & to left aligned - PWM->PWM_CH_NUM[2].PWM_CMR = 0b1011; // set channel 2 to Clock A input & to left aligned - PWM->PWM_CH_NUM[3].PWM_CMR = 0b1011; // set channel 3 to Clock A input & to left aligned - PWM->PWM_CH_NUM[4].PWM_CMR = 0b1011; // set channel 4 to Clock A input & to left aligned - - PWM->PWM_CH_NUM[0].PWM_CPRD = PWM_PERIOD_US; // set channel 0 Period - - PWM->PWM_IER2 = PWM_IER1_CHID0; // generate interrupt when counter0 overflows - PWM->PWM_IER2 = PWM_IER2_CMPM0 | PWM_IER2_CMPM1 | PWM_IER2_CMPM2 | PWM_IER2_CMPM3 | PWM_IER2_CMPM4; // generate interrupt on compare event - - PWM->PWM_CMP[1].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[0])); // interrupt when counter0 == CMPV - used to set Motor 1 PWM inactive - PWM->PWM_CMP[2].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[0])); // interrupt when counter0 == CMPV - used to set Motor 2 PWM inactive - PWM->PWM_CMP[3].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[1])); // interrupt when counter0 == CMPV - used to set Motor 3 PWM inactive - PWM->PWM_CMP[4].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[2])); // interrupt when counter0 == CMPV - used to set Motor 4 PWM inactive - - PWM->PWM_CMP[1].PWM_CMPM = 0x0001; // enable compare event - PWM->PWM_CMP[2].PWM_CMPM = 0x0001; // enable compare event - PWM->PWM_CMP[3].PWM_CMPM = 0x0001; // enable compare event - PWM->PWM_CMP[4].PWM_CMPM = 0x0001; // enable compare event - - PWM->PWM_SCM = PWM_SCM_UPDM_MODE0 | PWM_SCM_SYNC0 | PWM_SCM_SYNC1 | PWM_SCM_SYNC2 | PWM_SCM_SYNC3 | PWM_SCM_SYNC4; // sync 1-4 with 0, use mode 0 for updates - - PWM->PWM_ENA = PWM_ENA_CHID0 | PWM_ENA_CHID1 | PWM_ENA_CHID2 | PWM_ENA_CHID3 | PWM_ENA_CHID4; // enable the channels used by G2 - PWM->PWM_IER1 = PWM_IER1_CHID0 | PWM_IER1_CHID1 | PWM_IER1_CHID2 | PWM_IER1_CHID3 | PWM_IER1_CHID4; // enable interrupts for the channels used by G2 - - NVIC_EnableIRQ(PWM_IRQn); // Enable interrupt handler - NVIC_SetPriority(PWM_IRQn, NVIC_EncodePriority(0, 10, 0)); // normal priority for PWM module (can stand some jitter on the Vref signals) -} - -void Stepper::digipot_current(const uint8_t driver, const int16_t current) { - - if (!(PWM->PWM_CH_NUM[0].PWM_CPRD == PWM_PERIOD_US)) digipot_init(); // Init PWM system if needed - - switch (driver) { - case 0: PWM->PWM_CMP[1].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update X & Y - PWM->PWM_CMP[2].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); - PWM->PWM_CMP[1].PWM_CMPMUPD = 0x0001; // enable compare event - PWM->PWM_CMP[2].PWM_CMPMUPD = 0x0001; // enable compare event - PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle - break; - case 1: PWM->PWM_CMP[3].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update Z - PWM->PWM_CMP[3].PWM_CMPMUPD = 0x0001; // enable compare event - PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle - break; - default:PWM->PWM_CMP[4].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update E - PWM->PWM_CMP[4].PWM_CMPMUPD = 0x0001; // enable compare event - PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle - break; - } -} - -volatile uint32_t PWM_ISR1_STATUS, PWM_ISR2_STATUS; - -void PWM_Handler() { - PWM_ISR1_STATUS = PWM->PWM_ISR1; - PWM_ISR2_STATUS = PWM->PWM_ISR2; - if (PWM_ISR1_STATUS & PWM_IER1_CHID0) { // CHAN_0 interrupt - *ISR_table[0].set_register = ISR_table[0].write_mask; // set X to active - *ISR_table[1].set_register = ISR_table[1].write_mask; // set Y to active - *ISR_table[2].set_register = ISR_table[2].write_mask; // set Z to active - *ISR_table[3].set_register = ISR_table[3].write_mask; // set E to active - } - else { - if (PWM_ISR2_STATUS & PWM_IER2_CMPM1) *ISR_table[0].clr_register = ISR_table[0].write_mask; // set X to inactive - if (PWM_ISR2_STATUS & PWM_IER2_CMPM2) *ISR_table[1].clr_register = ISR_table[1].write_mask; // set Y to inactive - if (PWM_ISR2_STATUS & PWM_IER2_CMPM3) *ISR_table[2].clr_register = ISR_table[2].write_mask; // set Z to inactive - if (PWM_ISR2_STATUS & PWM_IER2_CMPM4) *ISR_table[3].clr_register = ISR_table[3].write_mask; // set E to inactive - } - return; -} - -#endif // PRINTRBOARD_G2 diff --git a/Marlin/src/HAL/HAL_LINUX/inc/Conditionals_LCD.h b/Marlin/src/HAL/HAL_LINUX/inc/Conditionals_LCD.h deleted file mode 100644 index 0285c52ee365..000000000000 --- a/Marlin/src/HAL/HAL_LINUX/inc/Conditionals_LCD.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL_SPI.cpp b/Marlin/src/HAL/HAL_LPC1768/HAL_SPI.cpp deleted file mode 100644 index 1c20e7f65225..000000000000 --- a/Marlin/src/HAL/HAL_LPC1768/HAL_SPI.cpp +++ /dev/null @@ -1,240 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Software SPI functions originally from Arduino Sd2Card Library - * Copyright (c) 2009 by William Greiman - */ - -/** - * For TARGET_LPC1768 - */ - -/** - * Hardware SPI and a software SPI implementations are included in this file. - * The hardware SPI runs faster and has higher throughput but is not compatible - * with some LCD interfaces/adapters. - * - * Control of the slave select pin(s) is handled by the calling routines. - * - * Some of the LCD interfaces/adapters result in the LCD SPI and the SD card - * SPI sharing pins. The SCK, MOSI & MISO pins can NOT be set/cleared with - * WRITE nor digitalWrite when the hardware SPI module within the LPC17xx is - * active. If any of these pins are shared then the software SPI must be used. - * - * A more sophisticated hardware SPI can be found at the following link. This - * implementation has not been fully debugged. - * https://github.com/MarlinFirmware/Marlin/tree/071c7a78f27078fd4aee9a3ef365fcf5e143531e - */ - -#ifdef TARGET_LPC1768 - -#include "../../inc/MarlinConfig.h" -#include - -// ------------------------ -// Public functions -// ------------------------ -#if ENABLED(LPC_SOFTWARE_SPI) - - #include - - // Software SPI - - static uint8_t SPI_speed = 0; - - static uint8_t spiTransfer(uint8_t b) { - return swSpiTransfer(b, SPI_speed, SCK_PIN, MISO_PIN, MOSI_PIN); - } - - void spiBegin() { - swSpiBegin(SCK_PIN, MISO_PIN, MOSI_PIN); - } - - void spiInit(uint8_t spiRate) { - SPI_speed = swSpiInit(spiRate, SCK_PIN, MOSI_PIN); - } - - uint8_t spiRec() { return spiTransfer(0xFF); } - - void spiRead(uint8_t*buf, uint16_t nbyte) { - for (int i = 0; i < nbyte; i++) - buf[i] = spiTransfer(0xFF); - } - - void spiSend(uint8_t b) { (void)spiTransfer(b); } - - void spiSend(const uint8_t* buf, size_t nbyte) { - for (uint16_t i = 0; i < nbyte; i++) - (void)spiTransfer(buf[i]); - } - - void spiSendBlock(uint8_t token, const uint8_t* buf) { - (void)spiTransfer(token); - for (uint16_t i = 0; i < 512; i++) - (void)spiTransfer(buf[i]); - } - -#else - - // Hardware SPI - - #include - #include - #include - - // decide which HW SPI device to use - #ifndef LPC_HW_SPI_DEV - #if (SCK_PIN == P0_07 && MISO_PIN == P0_08 && MOSI_PIN == P0_09) - #define LPC_HW_SPI_DEV 1 - #else - #if (SCK_PIN == P0_15 && MISO_PIN == P0_17 && MOSI_PIN == P0_18) - #define LPC_HW_SPI_DEV 0 - #else - #error "Invalid pins selected for hardware SPI" - #endif - #endif - #endif - #if (LPC_HW_SPI_DEV == 0) - #define LPC_SSPn LPC_SSP0 - #else - #define LPC_SSPn LPC_SSP1 - #endif - - void spiBegin() { // setup SCK, MOSI & MISO pins for SSP0 - PINSEL_CFG_Type PinCfg; // data structure to hold init values - PinCfg.Funcnum = 2; - PinCfg.OpenDrain = 0; - PinCfg.Pinmode = 0; - PinCfg.Pinnum = LPC176x::pin_bit(SCK_PIN); - PinCfg.Portnum = LPC176x::pin_port(SCK_PIN); - PINSEL_ConfigPin(&PinCfg); - SET_OUTPUT(SCK_PIN); - - PinCfg.Pinnum = LPC176x::pin_bit(MISO_PIN); - PinCfg.Portnum = LPC176x::pin_port(MISO_PIN); - PINSEL_ConfigPin(&PinCfg); - SET_INPUT(MISO_PIN); - - PinCfg.Pinnum = LPC176x::pin_bit(MOSI_PIN); - PinCfg.Portnum = LPC176x::pin_port(MOSI_PIN); - PINSEL_ConfigPin(&PinCfg); - SET_OUTPUT(MOSI_PIN); - // divide PCLK by 2 for SSP0 - CLKPWR_SetPCLKDiv(LPC_HW_SPI_DEV == 0 ? CLKPWR_PCLKSEL_SSP0 : CLKPWR_PCLKSEL_SSP1, CLKPWR_PCLKSEL_CCLK_DIV_2); - spiInit(0); - SSP_Cmd(LPC_SSPn, ENABLE); // start SSP running - } - - void spiInit(uint8_t spiRate) { - // table to convert Marlin spiRates (0-5 plus default) into bit rates - uint32_t Marlin_speed[7]; // CPSR is always 2 - Marlin_speed[0] = 8333333; //(SCR: 2) desired: 8,000,000 actual: 8,333,333 +4.2% SPI_FULL_SPEED - Marlin_speed[1] = 4166667; //(SCR: 5) desired: 4,000,000 actual: 4,166,667 +4.2% SPI_HALF_SPEED - Marlin_speed[2] = 2083333; //(SCR: 11) desired: 2,000,000 actual: 2,083,333 +4.2% SPI_QUARTER_SPEED - Marlin_speed[3] = 1000000; //(SCR: 24) desired: 1,000,000 actual: 1,000,000 SPI_EIGHTH_SPEED - Marlin_speed[4] = 500000; //(SCR: 49) desired: 500,000 actual: 500,000 SPI_SPEED_5 - Marlin_speed[5] = 250000; //(SCR: 99) desired: 250,000 actual: 250,000 SPI_SPEED_6 - Marlin_speed[6] = 125000; //(SCR:199) desired: 125,000 actual: 125,000 Default from HAL.h - // setup for SPI mode - SSP_CFG_Type HW_SPI_init; // data structure to hold init values - SSP_ConfigStructInit(&HW_SPI_init); // set values for SPI mode - HW_SPI_init.ClockRate = Marlin_speed[_MIN(spiRate, 6)]; // put in the specified bit rate - HW_SPI_init.Mode |= SSP_CR1_SSP_EN; - SSP_Init(LPC_SSPn, &HW_SPI_init); // puts the values into the proper bits in the SSP0 registers - } - - static uint8_t doio(uint8_t b) { - /* send and receive a single byte */ - SSP_SendData(LPC_SSPn, b & 0x00FF); - while (SSP_GetStatus(LPC_SSPn, SSP_STAT_BUSY)); // wait for it to finish - return SSP_ReceiveData(LPC_SSPn) & 0x00FF; - } - - void spiSend(uint8_t b) { doio(b); } - - void spiSend(const uint8_t* buf, size_t nbyte) { - for (uint16_t i = 0; i < nbyte; i++) doio(buf[i]); - } - - void spiSend(uint32_t chan, byte b) { - } - - void spiSend(uint32_t chan, const uint8_t* buf, size_t nbyte) { - } - - // Read single byte from SPI - uint8_t spiRec() { return doio(0xFF); } - - uint8_t spiRec(uint32_t chan) { return 0; } - - // Read from SPI into buffer - void spiRead(uint8_t *buf, uint16_t nbyte) { - for (uint16_t i = 0; i < nbyte; i++) buf[i] = doio(0xFF); - } - - static uint8_t spiTransfer(uint8_t b) { - return doio(b); - } - - // Write from buffer to SPI - void spiSendBlock(uint8_t token, const uint8_t* buf) { - (void)spiTransfer(token); - for (uint16_t i = 0; i < 512; i++) - (void)spiTransfer(buf[i]); - } - - /** Begin SPI transaction, set clock, bit order, data mode */ - void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) { - // TODO: to be implemented - - } - -#endif // ENABLED(LPC_SOFTWARE_SPI) - -void SPIClass::begin() { spiBegin(); } - -void SPIClass::beginTransaction(SPISettings cfg) { - uint8_t spiRate; - switch (cfg.spiRate()) { - case 8000000: spiRate = 0; break; - case 4000000: spiRate = 1; break; - case 2000000: spiRate = 2; break; - case 1000000: spiRate = 3; break; - case 500000: spiRate = 4; break; - case 250000: spiRate = 5; break; - case 125000: spiRate = 6; break; - default: spiRate = 2; break; - } - spiInit(spiRate); -} - -uint8_t SPIClass::transfer(const uint8_t B) { return spiTransfer(B); } - -uint16_t SPIClass::transfer16(const uint16_t data) { - return (transfer((data >> 8) & 0xFF) << 8) - | (transfer(data & 0xFF) & 0xFF); -} - -SPIClass SPI; - -#endif // TARGET_LPC1768 diff --git a/Marlin/src/HAL/HAL_LPC1768/inc/Conditionals_LCD.h b/Marlin/src/HAL/HAL_LPC1768/inc/Conditionals_LCD.h deleted file mode 100644 index 0285c52ee365..000000000000 --- a/Marlin/src/HAL/HAL_LPC1768/inc/Conditionals_LCD.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/Marlin/src/HAL/HAL_LPC1768/inc/Conditionals_adv.h b/Marlin/src/HAL/HAL_LPC1768/inc/Conditionals_adv.h deleted file mode 100644 index 0285c52ee365..000000000000 --- a/Marlin/src/HAL/HAL_LPC1768/inc/Conditionals_adv.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/Marlin/src/HAL/HAL_LPC1768/inc/Conditionals_post.h b/Marlin/src/HAL/HAL_LPC1768/inc/Conditionals_post.h deleted file mode 100644 index 0285c52ee365..000000000000 --- a/Marlin/src/HAL/HAL_LPC1768/inc/Conditionals_post.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/Marlin/src/HAL/HAL_LPC1768/inc/SanityCheck.h b/Marlin/src/HAL/HAL_LPC1768/inc/SanityCheck.h deleted file mode 100644 index a1fa34204013..000000000000 --- a/Marlin/src/HAL/HAL_LPC1768/inc/SanityCheck.h +++ /dev/null @@ -1,127 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if PIO_PLATFORM_VERSION < 1001 - #error "nxplpc-arduino-lpc176x package is out of date, Please update the PlatformIO platforms, frameworks and libraries. You may need to remove the platform and let it reinstall automatically." -#endif -#if PIO_FRAMEWORK_VERSION < 2002 - #error "framework-arduino-lpc176x package is out of date, Please update the PlatformIO platforms, frameworks and libraries." -#endif - -/** - * Detect an old pins file by checking for old ADC pins values. - */ -#define _OLD_TEMP_PIN(P) PIN_EXISTS(P) && _CAT(P,_PIN) <= 7 && _CAT(P,_PIN) != 2 && _CAT(P,_PIN) != 3 -#if _OLD_TEMP_PIN(TEMP_BED) - #error "TEMP_BED_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." -#elif _OLD_TEMP_PIN(TEMP_0) - #error "TEMP_0_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." -#elif _OLD_TEMP_PIN(TEMP_1) - #error "TEMP_1_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." -#elif _OLD_TEMP_PIN(TEMP_2) - #error "TEMP_2_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." -#elif _OLD_TEMP_PIN(TEMP_3) - #error "TEMP_3_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." -#elif _OLD_TEMP_PIN(TEMP_4) - #error "TEMP_4_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." -#elif _OLD_TEMP_PIN(TEMP_5) - #error "TEMP_5_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." -#elif _OLD_TEMP_PIN(TEMP_6) - #error "TEMP_6_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." -#elif _OLD_TEMP_PIN(TEMP_7) - #error "TEMP_7_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." -#endif -#undef _OLD_TEMP_PIN - -/** - * Because PWM hardware channels all share the same frequency, along with the - * fallback software channels, FAST_PWM_FAN is incompatible with Servos. - */ -#if NUM_SERVOS > 0 && ENABLED(FAST_PWM_FAN) - #error "BLTOUCH and Servos are incompatible with FAST_PWM_FAN on LPC176x boards." -#endif - -/** - * Test LPC176x-specific configuration values for errors at compile-time. - */ - -//#if ENABLED(SPINDLE_LASER_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11) -// #error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector" -//#endif - -#if IS_RE_ARM_BOARD && ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) && HAS_DRIVER(TMC2130) && DISABLED(TMC_USE_SW_SPI) - #error "Re-ARM with REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER and TMC2130 require TMC_USE_SW_SPI" -#endif - -#if ENABLED(BAUD_RATE_GCODE) - #error "BAUD_RATE_GCODE is not yet supported on LPC176x." -#endif - -/** - * Flag any serial port conflicts - * - * Port | TX | RX | - * --- | --- | --- | - * Serial | P0_02 | P0_03 | - * Serial1 | P0_15 | P0_16 | - * Serial2 | P0_10 | P0_11 | - * Serial3 | P0_00 | P0_01 | - */ -#if (defined(SERIAL_PORT) && SERIAL_PORT == 0) || (defined(SERIAL_PORT_2) && SERIAL_PORT_2 == 0) || (defined(DGUS_SERIAL_PORT) && DGUS_SERIAL_PORT == 0) - #if X_CS_PIN == P0_02 || TMC_SW_MISO == P0_02 || (E_STEPPERS && E_MUX1_PIN == P0_02) \ - || Y_CS_PIN == P0_03 || TMC_SW_MOSI == P0_03 || (E_STEPPERS && E_MUX0_PIN == P0_03) - #error "Serial port assignment (0) conflicts with other pins!" - #endif -#endif - -#if SERIAL_PORT == 1 || SERIAL_PORT_2 == 1 || DGUS_SERIAL_PORT == 1 - #if TMC_SW_SCK == P0_15 - #error "Serial port assignment (1) conflicts with other pins!" - #elif HAS_SPI_LCD - #if BTN_EN2 == P0_15 || SCK_PIN == P0_15 || LCD_PINS_D4 == P0_15 || DOGLCD_SCK == P0_15 || LCD_RESET_PIN == P0_15 || LCD_PINS_RS == P0_15 || SHIFT_CLK == P0_15 \ - || BTN_EN1 == P0_16 || LCD_SDSS == P0_16 || LCD_PINS_RS == P0_16 || MISO_PIN == P0_16 || DOGLCD_A0 == P0_16 || SS_PIN == P0_16 || LCD_SDSS == P0_16 || DOGLCD_CS == P0_16 || LCD_RESET_PIN == P0_16 || LCD_BACKLIGHT_PIN == P0_16 - #error "Serial port assignment (1) conflicts with other pins!" - #endif - #endif -#endif - -#if SERIAL_PORT == 2 || SERIAL_PORT_2 == 2 || DGUS_SERIAL_PORT == 2 - #if Y_MIN_PIN == P0_10 || Z_MIN_PROBE_PIN == P0_10 \ - || X_ENABLE_PIN == P0_10 || Y_ENABLE_PIN == P0_10 || X2_ENABLE_PIN == P0_10 || Y2_ENABLE_PIN == P0_10 || Z2_ENABLE_PIN == P0_10 || Z3_ENABLE_PIN == P0_10 || Z4_ENABLE_PIN == P0_10 \ - || X2_CS_PIN == P0_10 || Y2_CS_PIN == P0_10 || Z2_CS_PIN == P0_10 || Z3_CS_PIN == P0_10 || Z4_CS_PIN == P0_10 \ - || X_DIR_PIN == P0_11 || Y_DIR_PIN == P0_11 || X2_DIR_PIN == P0_11 || Y2_DIR_PIN == P0_11 || Z2_DIR_PIN == P0_11 || Z3_DIR_PIN == P0_11 || Z4_DIR_PIN == P0_11 \ - || X2_STEP_PIN == P0_11 || Y2_STEP_PIN == P0_11 || Z2_STEP_PIN == P0_11 || Z3_STEP_PIN == P0_11 || Z4_STEP_PIN == P0_11 - #error "Serial port assignment (2) conflicts with other pins!" - #elif (E_STEPPERS > 1 && (E1_ENABLE_PIN == P0_10 || E1_CS_PIN == P0_10)) || (E_STEPPERS > 0 && (E0_DIR_PIN == P0_11 || E0_STEP_PIN == P0_11)) - #error "Serial port assignment (2) conflicts with other pins!" - #endif -#endif - -#if SERIAL_PORT == 3 || SERIAL_PORT_2 == 3 || DGUS_SERIAL_PORT == 3 - #if X_MIN_PIN == P0_00 || Y_SERIAL_TX_PIN == P0_00 || Y_SERIAL_RX_PIN == P0_00 \ - || X_MAX_PIN == P0_01 || X_SERIAL_TX_PIN == P0_01 || X_SERIAL_RX_PIN == P0_01 - #error "Serial port assignment (2) conflicts with other pins!" - #elif E_STEPPERS > 1 && (E1_DIR_PIN == P0_00 || E1_STEP_PIN == P0_01) - #error "Serial port assignment (2) conflicts with other pins!" - #endif -#endif diff --git a/Marlin/src/HAL/HAL_SAMD51/inc/Conditionals_LCD.h b/Marlin/src/HAL/HAL_SAMD51/inc/Conditionals_LCD.h deleted file mode 100644 index 0285c52ee365..000000000000 --- a/Marlin/src/HAL/HAL_SAMD51/inc/Conditionals_LCD.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/Marlin/src/HAL/HAL_SAMD51/inc/Conditionals_adv.h b/Marlin/src/HAL/HAL_SAMD51/inc/Conditionals_adv.h deleted file mode 100644 index 0285c52ee365..000000000000 --- a/Marlin/src/HAL/HAL_SAMD51/inc/Conditionals_adv.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/Marlin/src/HAL/HAL_SAMD51/inc/Conditionals_post.h b/Marlin/src/HAL/HAL_SAMD51/inc/Conditionals_post.h deleted file mode 100644 index 0285c52ee365..000000000000 --- a/Marlin/src/HAL/HAL_SAMD51/inc/Conditionals_post.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/Marlin/src/HAL/HAL_SAMD51/persistent_store_eeprom.cpp b/Marlin/src/HAL/HAL_SAMD51/persistent_store_eeprom.cpp deleted file mode 100644 index c450599d7b16..000000000000 --- a/Marlin/src/HAL/HAL_SAMD51/persistent_store_eeprom.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) - * - * 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 . - * - */ - -#ifdef __SAMD51__ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(EEPROM_SETTINGS) - -#include "../shared/persistent_store_api.h" - -#if NONE(SPI_EEPROM, I2C_EEPROM) - #define NVMCTRL_CMD(c) do{ \ - SYNC(!NVMCTRL->STATUS.bit.READY); \ - NVMCTRL->INTFLAG.bit.DONE = true; \ - NVMCTRL->CTRLB.reg = c | NVMCTRL_CTRLB_CMDEX_KEY; \ - SYNC(NVMCTRL->INTFLAG.bit.DONE); \ - }while(0) - #define NVMCTRL_FLUSH() do{ \ - if (NVMCTRL->SEESTAT.bit.LOAD) \ - NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_SEEFLUSH); \ - }while(0) -#endif - -bool PersistentStore::access_start() { - #if NONE(SPI_EEPROM, I2C_EEPROM) - NVMCTRL->SEECFG.reg = NVMCTRL_SEECFG_WMODE_BUFFERED; // Buffered mode and segment reallocation active - #endif - - return true; -} - -bool PersistentStore::access_finish() { - #if NONE(SPI_EEPROM, I2C_EEPROM) - NVMCTRL_FLUSH(); - if (!NVMCTRL->SEESTAT.bit.LOCK) - NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_LSEE); // Lock E2P data write access - #endif - - return true; -} - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - #if NONE(SPI_EEPROM, I2C_EEPROM) - if (NVMCTRL->SEESTAT.bit.RLOCK) - NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_USEE); // Unlock E2P data write access - #endif - - while (size--) { - const uint8_t v = *value; - #if ANY(SPI_EEPROM, I2C_EEPROM) - uint8_t * const p = (uint8_t * const)pos; - if (v != eeprom_read_byte(p)) { - eeprom_write_byte(p, v); - delay(2); - if (eeprom_read_byte(p) != v) { - SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE); - return true; - } - } - #else - SYNC(NVMCTRL->SEESTAT.bit.BUSY); - if (NVMCTRL->INTFLAG.bit.SEESFULL) - NVMCTRL_FLUSH(); // Next write will trigger a sector reallocation. I need to flush 'pagebuffer' - ((volatile uint8_t *)SEEPROM_ADDR)[pos] = v; - SYNC(!NVMCTRL->INTFLAG.bit.SEEWRC); - #endif - crc16(crc, &v, 1); - pos++; - value++; - } - return false; -} - -bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) { - while (size--) { - uint8_t c; - #if ANY(SPI_EEPROM, I2C_EEPROM) - c = eeprom_read_byte((uint8_t*)pos); - #else - SYNC(NVMCTRL->SEESTAT.bit.BUSY); - c = ((volatile uint8_t *)SEEPROM_ADDR)[pos]; - #endif - if (writing) *value = c; - crc16(crc, &c, 1); - pos++; - value++; - } - return false; -} - -size_t PersistentStore::capacity() { - #if ANY(SPI_EEPROM, I2C_EEPROM) - return E2END + 1; - #else - const uint8_t psz = NVMCTRL->SEESTAT.bit.PSZ, - sblk = NVMCTRL->SEESTAT.bit.SBLK; - - if (!psz && !sblk) return 0; - else if (psz <= 2) return (0x200 << psz); - else if (sblk == 1 || psz == 3) return 4096; - else if (sblk == 2 || psz == 4) return 8192; - else if (sblk <= 4 || psz == 5) return 16384; - else if (sblk >= 9 && psz == 7) return 65536; - else return 32768; - #endif -} - -#endif // EEPROM_SETTINGS - -#endif // __SAMD51__ diff --git a/Marlin/src/HAL/HAL_STM32/Sd2Card_sdio_stm32duino.cpp b/Marlin/src/HAL/HAL_STM32/Sd2Card_sdio_stm32duino.cpp deleted file mode 100644 index ebe15f93915f..000000000000 --- a/Marlin/src/HAL/HAL_STM32/Sd2Card_sdio_stm32duino.cpp +++ /dev/null @@ -1,274 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(SDIO_SUPPORT) && !defined(STM32GENERIC) - -#include -#include - -//#include "SdMscDriver.h" - -//#include "usbd_msc_bot.h" -//#include "usbd_msc_scsi.h" -//#include "usbd_msc_composite.h" -//#include "usbd_msc_cdc_composite.h" - -//#include "usbd_msc_data.h" - -#if defined(STM32F103xE) || defined(STM32F103xG) - #include - #include -#elif defined(STM32F4xx) - #include - #include - #include - #include -#elif defined(STM32F7xx) - #include - #include - #include - #include -#else - #error "ERROR - Only STM32F103xE, STM32F103xG, STM32F4xx or STM32F7xx CPUs supported" -#endif - -SD_HandleTypeDef hsd; // create SDIO structure - -#define TRANSFER_CLOCK_DIV ((uint8_t)SDIO_INIT_CLK_DIV/40) - -#ifndef USBD_OK - #define USBD_OK 0 -#endif - -void go_to_transfer_speed() { - - SD_InitTypeDef Init; - - /* Default SDIO peripheral configuration for SD card initialization */ - Init.ClockEdge = hsd.Init.ClockEdge; - Init.ClockBypass = hsd.Init.ClockBypass; - Init.ClockPowerSave = hsd.Init.ClockPowerSave; - Init.BusWide = hsd.Init.BusWide; - Init.HardwareFlowControl = hsd.Init.HardwareFlowControl; - Init.ClockDiv = TRANSFER_CLOCK_DIV; - - /* Initialize SDIO peripheral interface with default configuration */ - SDIO_Init(hsd.Instance, Init); -} - -void SD_LowLevel_Init(void) { - - uint32_t tempreg; - - GPIO_InitTypeDef GPIO_InitStruct; - - __HAL_RCC_GPIOC_CLK_ENABLE(); //enable GPIO clocks - __HAL_RCC_GPIOD_CLK_ENABLE(); //enable GPIO clocks - - GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_12; // D0 & SCK - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = 1; //GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; - HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); - - #if defined(SDIO_D1_PIN) && defined(SDIO_D2_PIN) && defined(SDIO_D3_PIN) // define D1-D3 only if have a four bit wide SDIO bus - GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11; // D1-D3 - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = 1; //GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; - HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); - #endif - - // Configure PD.02 CMD line - GPIO_InitStruct.Pin = GPIO_PIN_2; - HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); - - RCC->APB2RSTR &= ~RCC_APB2RSTR_SDIORST_Msk; // take SDIO out of reset - RCC->APB2ENR |= RCC_APB2RSTR_SDIORST_Msk; // enable SDIO clock - - // Enable the DMA2 Clock - - //Initialize the SDIO (with initial <400Khz Clock) - tempreg = 0; //Reset value - tempreg |= SDIO_CLKCR_CLKEN; //Clock is enabled - tempreg |= (uint32_t)0x76; //Clock Divider. Clock = 48000/(118+2) = 400Khz - //Keep the rest at 0 => HW_Flow Disabled, Rising Clock Edge, Disable CLK ByPass, Bus Width = 0, Power save Disable - SDIO->CLKCR = tempreg; - - //Power up the SDIO - SDIO->POWER = 0x03; -} - - -void HAL_SD_MspInit(SD_HandleTypeDef *hsd) { // application specific init - UNUSED(hsd); /* Prevent unused argument(s) compilation warning */ - __HAL_RCC_SDIO_CLK_ENABLE(); // turn on SDIO clock -} - -constexpr uint8_t SD_RETRY_COUNT = (1 - #if ENABLED(SD_CHECK_AND_RETRY) - + 2 - #endif -); - -bool SDIO_Init() { - //init SDIO and get SD card info - - uint8_t retryCnt = SD_RETRY_COUNT; - - bool status; - hsd.Instance = SDIO; - hsd.State = (HAL_SD_StateTypeDef) 0; // HAL_SD_STATE_RESET - SD_LowLevel_Init(); - - uint8_t retry_Cnt = retryCnt; - for (;;) { - status = (bool) HAL_SD_Init(&hsd); - if (!status) break; - if (!--retry_Cnt) return false; // return failing status if retries are exhausted - } - - go_to_transfer_speed(); - - #if defined(SDIO_D1_PIN) && defined(SDIO_D2_PIN) && defined(SDIO_D3_PIN) // go to 4 bit wide mode if pins are defined - retry_Cnt = retryCnt; - for (;;) { - if (!HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B)) break; // some cards are only 1 bit wide so a pass here is not required - if (!--retry_Cnt) break; - } - if (!retry_Cnt) { // wide bus failed, go back to one bit wide mode - hsd.State = (HAL_SD_StateTypeDef) 0; // HAL_SD_STATE_RESET - SD_LowLevel_Init(); - retry_Cnt = retryCnt; - for (;;) { - status = (bool) HAL_SD_Init(&hsd); - if (!status) break; - if (!--retry_Cnt) return false; // return failing status if retries are exhausted - } - } - #endif - - return true; -} - -void init_SDIO_pins(void) { - GPIO_InitTypeDef GPIO_InitStruct = {0}; - - /**SDIO GPIO Configuration - PC8 ------> SDIO_D0 - PC12 ------> SDIO_CK - PD2 ------> SDIO_CMD - */ - GPIO_InitStruct.Pin = GPIO_PIN_8; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; - HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = GPIO_PIN_12; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; - HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = GPIO_PIN_2; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; - HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); -} - -//bool SDIO_init() { return (bool) (SD_SDIO_Init() ? 1 : 0);} -//bool SDIO_Init_C() { return (bool) (SD_SDIO_Init() ? 1 : 0);} - -bool SDIO_ReadBlock(uint32_t block, uint8_t *dst) { - bool status; - - hsd.Instance = SDIO; - - uint8_t retryCnt = SD_RETRY_COUNT; - - for (;;) { - bool status = (bool) HAL_SD_ReadBlocks(&hsd, (uint8_t*)dst, block, 1, 1000); // read one 512 byte block with 500mS timeout - status |= (bool) HAL_SD_GetCardState(&hsd); // make sure all is OK - if (!status) return false; // return passing status - if (!--retryCnt) return true; // return failing status if retries are exhausted - } - - /* - return (bool) ((status_read | status_card) ? 1 : 0); - - if (SDIO_GetCardState() != SDIO_CARD_TRANSFER) return false; - if (blockAddress >= SdCard.LogBlockNbr) return false; - if ((0x03 & (uint32_t)data)) return false; // misaligned data - - if (SdCard.CardType != CARD_SDHC_SDXC) { blockAddress *= 512U; } - - if (!SDIO_CmdReadSingleBlock(blockAddress)) { - SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS); - dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); - return false; - } - - while (!SDIO_GET_FLAG(SDIO_STA_DATAEND | SDIO_STA_TRX_ERROR_FLAGS)) {} - - dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); - - if (SDIO->STA & SDIO_STA_RXDAVL) { - while (SDIO->STA & SDIO_STA_RXDAVL) (void)SDIO->FIFO; - SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS); - return false; - } - - if (SDIO_GET_FLAG(SDIO_STA_TRX_ERROR_FLAGS)) { - SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS); - return false; - } - SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS); - */ - - return true; -} - -bool SDIO_WriteBlock(uint32_t block, const uint8_t *src) { - bool status; - - hsd.Instance = SDIO; - - uint8_t retryCnt = SD_RETRY_COUNT; - - for (;;) { - status = (bool) HAL_SD_WriteBlocks(&hsd, (uint8_t*)src, block, 1, 500); // write one 512 byte block with 500mS timeout - status |= (bool) HAL_SD_GetCardState(&hsd); // make sure all is OK - if (!status) return (bool) status; // return passing status - if (!--retryCnt) return (bool) status; // return failing status if retries are exhausted - } -} - -#endif // SDIO_SUPPORT diff --git a/Marlin/src/HAL/HAL_STM32/SoftwareSerial.cpp b/Marlin/src/HAL/HAL_STM32/SoftwareSerial.cpp deleted file mode 100644 index f6363aa1cf7d..000000000000 --- a/Marlin/src/HAL/HAL_STM32/SoftwareSerial.cpp +++ /dev/null @@ -1,395 +0,0 @@ -/* - * SoftwareSerial.cpp (formerly NewSoftSerial.cpp) - * - * Multi-instance software serial library for Arduino/Wiring - * -- Interrupt-driven receive and other improvements by ladyada - * (http://ladyada.net) - * -- Tuning, circular buffer, derivation from class Print/Stream, - * multi-instance support, porting to 8MHz processors, - * various optimizations, PROGMEM delay tables, inverse logic and - * direct port writing by Mikal Hart (http://www.arduiniana.org) - * -- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com) - * -- 20MHz processor support by Garrett Mace (http://www.macetech.com) - * -- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/) - * -- STM32 support by Armin van der Togt - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * The latest version of this library can always be found at - * http://arduiniana.org. - */ - -// -// Includes -// -#if defined(PLATFORMIO) && defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC) - -#include "SoftwareSerial.h" -#include "timers.h" - -#define OVERSAMPLE 3 // in RX, Timer will generate interruption OVERSAMPLE time during a bit. Thus OVERSAMPLE ticks in a bit. (interrupt not synchonized with edge). - -// defined in bit-periods -#define HALFDUPLEX_SWITCH_DELAY 5 -// It's best to define TIMER_SERIAL in variant.h. If not defined, we choose one here -// The order is based on (lack of) features and compare channels, we choose the simplest available -// because we only need an update interrupt -#if !defined(TIMER_SERIAL) -#if defined (TIM18_BASE) -#define TIMER_SERIAL TIM18 -#elif defined (TIM7_BASE) -#define TIMER_SERIAL TIM7 -#elif defined (TIM6_BASE) -#define TIMER_SERIAL TIM6 -#elif defined (TIM22_BASE) -#define TIMER_SERIAL TIM22 -#elif defined (TIM21_BASE) -#define TIMER_SERIAL TIM21 -#elif defined (TIM17_BASE) -#define TIMER_SERIAL TIM17 -#elif defined (TIM16_BASE) -#define TIMER_SERIAL TIM16 -#elif defined (TIM15_BASE) -#define TIMER_SERIAL TIM15 -#elif defined (TIM14_BASE) -#define TIMER_SERIAL TIM14 -#elif defined (TIM13_BASE) -#define TIMER_SERIAL TIM13 -#elif defined (TIM11_BASE) -#define TIMER_SERIAL TIM11 -#elif defined (TIM10_BASE) -#define TIMER_SERIAL TIM10 -#elif defined (TIM12_BASE) -#define TIMER_SERIAL TIM12 -#elif defined (TIM19_BASE) -#define TIMER_SERIAL TIM19 -#elif defined (TIM9_BASE) -#define TIMER_SERIAL TIM9 -#elif defined (TIM5_BASE) -#define TIMER_SERIAL TIM5 -#elif defined (TIM4_BASE) -#define TIMER_SERIAL TIM4 -#elif defined (TIM3_BASE) -#define TIMER_SERIAL TIM3 -#elif defined (TIM2_BASE) -#define TIMER_SERIAL TIM2 -#elif defined (TIM20_BASE) -#define TIMER_SERIAL TIM20 -#elif defined (TIM8_BASE) -#define TIMER_SERIAL TIM8 -#elif defined (TIM1_BASE) -#define TIMER_SERIAL TIM1 -#else -#error No suitable timer found for SoftwareSerial, define TIMER_SERIAL in variant.h -#endif -#endif -// -// Statics -// -HardwareTimer SoftwareSerial::timer(TIMER_SERIAL); -const IRQn_Type SoftwareSerial::timer_interrupt_number = static_cast(getTimerUpIrq(TIMER_SERIAL)); -uint32_t SoftwareSerial::timer_interrupt_priority = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), TIM_IRQ_PRIO, TIM_IRQ_SUBPRIO); -SoftwareSerial *SoftwareSerial::active_listener = nullptr; -SoftwareSerial *volatile SoftwareSerial::active_out = nullptr; -SoftwareSerial *volatile SoftwareSerial::active_in = nullptr; -int32_t SoftwareSerial::tx_tick_cnt = 0; // OVERSAMPLE ticks needed for a bit -int32_t volatile SoftwareSerial::rx_tick_cnt = 0; // OVERSAMPLE ticks needed for a bit -uint32_t SoftwareSerial::tx_buffer = 0; -int32_t SoftwareSerial::tx_bit_cnt = 0; -uint32_t SoftwareSerial::rx_buffer = 0; -int32_t SoftwareSerial::rx_bit_cnt = -1; // rx_bit_cnt = -1 : waiting for start bit -uint32_t SoftwareSerial::cur_speed = 0; - -void SoftwareSerial::setInterruptPriority(uint32_t preemptPriority, uint32_t subPriority) { - timer_interrupt_priority = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), preemptPriority, subPriority); -} - -// -// Private methods -// - -void SoftwareSerial::setSpeed(uint32_t speed) { - if (speed != cur_speed) { - timer.pause(); - if (speed != 0) { - // Disable the timer - uint32_t clock_rate, cmp_value; - // Get timer clock - clock_rate = timer.getTimerClkFreq(); - int pre = 1; - // Calculate prescale an compare value - do { - cmp_value = clock_rate / (speed * OVERSAMPLE); - if (cmp_value >= UINT16_MAX) { - clock_rate /= 2; - pre *= 2; - } - } while (cmp_value >= UINT16_MAX); - timer.setPrescaleFactor(pre); - timer.setOverflow(cmp_value); - timer.setCount(0); - timer.attachInterrupt(&handleInterrupt); - timer.resume(); - NVIC_SetPriority(timer_interrupt_number, timer_interrupt_priority); - } - else - timer.detachInterrupt(); - cur_speed = speed; - } -} - -// This function sets the current object as the "listening" -// one and returns true if it replaces another -bool SoftwareSerial::listen() { - if (active_listener != this) { - // wait for any transmit to complete as we may change speed - while (active_out); - active_listener->stopListening(); - rx_tick_cnt = 1; // 1 : next interrupt will decrease rx_tick_cnt to 0 which means RX pin level will be considered. - rx_bit_cnt = -1; // rx_bit_cnt = -1 : waiting for start bit - setSpeed(_speed); - active_listener = this; - if (!_half_duplex) active_in = this; - return true; - } - return false; -} - -// Stop listening. Returns true if we were actually listening. -bool SoftwareSerial::stopListening() { - if (active_listener == this) { - // wait for any output to complete - while (active_out); - if (_half_duplex) setRXTX(false); - active_listener = nullptr; - active_in = nullptr; - // turn off ints - setSpeed(0); - return true; - } - return false; -} - -inline void SoftwareSerial::setTX() { - if (_inverse_logic) - LL_GPIO_ResetOutputPin(_transmitPinPort, _transmitPinNumber); - else - LL_GPIO_SetOutputPin(_transmitPinPort, _transmitPinNumber); - pinMode(_transmitPin, OUTPUT); -} - -inline void SoftwareSerial::setRX() { - pinMode(_receivePin, _inverse_logic ? INPUT_PULLDOWN : INPUT_PULLUP); // pullup for normal logic! -} - -inline void SoftwareSerial::setRXTX(bool input) { - if (_half_duplex) { - if (input) { - if (active_in != this) { - setRX(); - rx_bit_cnt = -1; // rx_bit_cnt = -1 : waiting for start bit - rx_tick_cnt = 2; // 2 : next interrupt will be discarded. 2 interrupts required to consider RX pin level - active_in = this; - } - } - else { - if (active_in == this) { - setTX(); - active_in = nullptr; - } - } - } -} - -inline void SoftwareSerial::send() { - if (--tx_tick_cnt <= 0) { // if tx_tick_cnt > 0 interrupt is discarded. Only when tx_tick_cnt reaches 0 is TX pin set. - if (tx_bit_cnt++ < 10) { // tx_bit_cnt < 10 transmission is not finished (10 = 1 start +8 bits + 1 stop) - // Send data (including start and stop bits) - if (tx_buffer & 1) - LL_GPIO_SetOutputPin(_transmitPinPort, _transmitPinNumber); - else - LL_GPIO_ResetOutputPin(_transmitPinPort, _transmitPinNumber); - tx_buffer >>= 1; - tx_tick_cnt = OVERSAMPLE; // Wait OVERSAMPLE ticks to send next bit - } - else { // Transmission finished - tx_tick_cnt = 1; - if (_output_pending) { - active_out = nullptr; - - // In half-duplex mode wait HALFDUPLEX_SWITCH_DELAY bit-periods after the byte has - // been transmitted before allowing the switch to RX mode - } - else if (tx_bit_cnt > 10 + OVERSAMPLE * HALFDUPLEX_SWITCH_DELAY) { - if (_half_duplex && active_listener == this) setRXTX(true); - active_out = nullptr; - } - } - } -} - -// -// The receive routine called by the interrupt handler -// -inline void SoftwareSerial::recv() { - if (--rx_tick_cnt <= 0) { // if rx_tick_cnt > 0 interrupt is discarded. Only when rx_tick_cnt reaches 0 is RX pin considered - bool inbit = LL_GPIO_IsInputPinSet(_receivePinPort, _receivePinNumber) ^ _inverse_logic; - if (rx_bit_cnt == -1) { // rx_bit_cnt = -1 : waiting for start bit - if (!inbit) { - // got start bit - rx_bit_cnt = 0; // rx_bit_cnt == 0 : start bit received - rx_tick_cnt = OVERSAMPLE + 1; // Wait 1 bit (OVERSAMPLE ticks) + 1 tick in order to sample RX pin in the middle of the edge (and not too close to the edge) - rx_buffer = 0; - } - else - rx_tick_cnt = 1; // Waiting for start bit, but wrong level. Wait for next Interrupt to check RX pin level - } - else if (rx_bit_cnt >= 8) { // rx_bit_cnt >= 8 : waiting for stop bit - if (inbit) { - // Stop-bit read complete. Add to buffer. - uint8_t next = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF; - if (next != _receive_buffer_head) { - // save new data in buffer: tail points to byte destination - _receive_buffer[_receive_buffer_tail] = rx_buffer; // save new byte - _receive_buffer_tail = next; - } - else // rx_bit_cnt = x with x = [0..7] correspond to new bit x received - _buffer_overflow = true; - } - // Full trame received. Restart waiting for start bit at next interrupt - rx_tick_cnt = 1; - rx_bit_cnt = -1; - } - else { - // data bits - rx_buffer >>= 1; - if (inbit) rx_buffer |= 0x80; - rx_bit_cnt++; // Prepare for next bit - rx_tick_cnt = OVERSAMPLE; // Wait OVERSAMPLE ticks before sampling next bit - } - } -} - -// -// Interrupt handling -// - -/* static */ -inline void SoftwareSerial::handleInterrupt(HardwareTimer*) { - if (active_in) active_in->recv(); - if (active_out) active_out->send(); -} - -// -// Constructor -// -SoftwareSerial::SoftwareSerial(uint16_t receivePin, uint16_t transmitPin, bool inverse_logic /* = false */) : - _receivePin(receivePin), - _transmitPin(transmitPin), - _receivePinPort(digitalPinToPort(receivePin)), - _receivePinNumber(STM_LL_GPIO_PIN(digitalPinToPinName(receivePin))), - _transmitPinPort(digitalPinToPort(transmitPin)), - _transmitPinNumber(STM_LL_GPIO_PIN(digitalPinToPinName(transmitPin))), - _speed(0), - _buffer_overflow(false), - _inverse_logic(inverse_logic), - _half_duplex(receivePin == transmitPin), - _output_pending(0), - _receive_buffer_tail(0), - _receive_buffer_head(0) -{ - if ((receivePin < NUM_DIGITAL_PINS) || (transmitPin < NUM_DIGITAL_PINS)) { - /* Enable GPIO clock for tx and rx pin*/ - set_GPIO_Port_Clock(STM_PORT(digitalPinToPinName(transmitPin))); - set_GPIO_Port_Clock(STM_PORT(digitalPinToPinName(receivePin))); - } - else - _Error_Handler("ERROR: invalid pin number\n", -1); -} - -// -// Destructor -// -SoftwareSerial::~SoftwareSerial() { end(); } - -// -// Public methods -// - -void SoftwareSerial::begin(long speed) { - #ifdef FORCE_BAUD_RATE - speed = FORCE_BAUD_RATE; - #endif - _speed = speed; - if (!_half_duplex) { - setTX(); - setRX(); - listen(); - } - else - setTX(); -} - -void SoftwareSerial::end() { - stopListening(); -} - -// Read data from buffer -int SoftwareSerial::read() { - // Empty buffer? - if (_receive_buffer_head == _receive_buffer_tail) return -1; - - // Read from "head" - uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte - _receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF; - return d; -} - -int SoftwareSerial::available() { - return (_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head) % _SS_MAX_RX_BUFF; -} - -size_t SoftwareSerial::write(uint8_t b) { - // wait for previous transmit to complete - _output_pending = 1; - while (active_out) { /* nada */ } - // add start and stop bits. - tx_buffer = b << 1 | 0x200; - if (_inverse_logic) tx_buffer = ~tx_buffer; - tx_bit_cnt = 0; - tx_tick_cnt = OVERSAMPLE; - setSpeed(_speed); - if (_half_duplex) setRXTX(false); - _output_pending = 0; - // make us active - active_out = this; - return 1; -} - -void SoftwareSerial::flush() { - noInterrupts(); - _receive_buffer_head = _receive_buffer_tail = 0; - interrupts(); -} - -int SoftwareSerial::peek() { - // Empty buffer? - if (_receive_buffer_head == _receive_buffer_tail) return -1; - - // Read from "head" - return _receive_buffer[_receive_buffer_head]; -} - -#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC diff --git a/Marlin/src/HAL/HAL_STM32/SoftwareSerial.h b/Marlin/src/HAL/HAL_STM32/SoftwareSerial.h deleted file mode 100644 index 3799701cfe5b..000000000000 --- a/Marlin/src/HAL/HAL_STM32/SoftwareSerial.h +++ /dev/null @@ -1,119 +0,0 @@ -/** - * SoftwareSerial.h (formerly NewSoftSerial.h) - * - * Multi-instance software serial library for Arduino/Wiring - * -- Interrupt-driven receive and other improvements by ladyada - * (http://ladyada.net) - * -- Tuning, circular buffer, derivation from class Print/Stream, - * multi-instance support, porting to 8MHz processors, - * various optimizations, PROGMEM delay tables, inverse logic and - * direct port writing by Mikal Hart (http://www.arduiniana.org) - * -- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com) - * -- 20MHz processor support by Garrett Mace (http://www.macetech.com) - * -- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * The latest version of this library can always be found at - * http://arduiniana.org. - */ - -#ifndef SOFTWARESERIAL_H -#define SOFTWARESERIAL_H - -#include - -/****************************************************************************** - * Definitions - ******************************************************************************/ - -#define _SS_MAX_RX_BUFF 64 // RX buffer size - -class SoftwareSerial : public Stream { - private: - // per object data - uint16_t _receivePin; - uint16_t _transmitPin; - GPIO_TypeDef *_receivePinPort; - uint32_t _receivePinNumber; - GPIO_TypeDef *_transmitPinPort; - uint32_t _transmitPinNumber; - uint32_t _speed; - - uint16_t _buffer_overflow: 1; - uint16_t _inverse_logic: 1; - uint16_t _half_duplex: 1; - uint16_t _output_pending: 1; - - unsigned char _receive_buffer[_SS_MAX_RX_BUFF]; - volatile uint8_t _receive_buffer_tail; - volatile uint8_t _receive_buffer_head; - - uint32_t delta_start = 0; - - // static data - static bool initialised; - static HardwareTimer timer; - static const IRQn_Type timer_interrupt_number; - static uint32_t timer_interrupt_priority; - static SoftwareSerial *active_listener; - static SoftwareSerial *volatile active_out; - static SoftwareSerial *volatile active_in; - static int32_t tx_tick_cnt; - static volatile int32_t rx_tick_cnt; - static uint32_t tx_buffer; - static int32_t tx_bit_cnt; - static uint32_t rx_buffer; - static int32_t rx_bit_cnt; - static uint32_t cur_speed; - - // private methods - void send(); - void recv(); - void setTX(); - void setRX(); - void setSpeed(uint32_t speed); - void setRXTX(bool input); - static void handleInterrupt(HardwareTimer *timer); - - public: - // public methods - - SoftwareSerial(uint16_t receivePin, uint16_t transmitPin, bool inverse_logic = false); - virtual ~SoftwareSerial(); - void begin(long speed); - bool listen(); - void end(); - bool isListening() { return active_listener == this; } - bool stopListening(); - bool overflow() { - bool ret = _buffer_overflow; - if (ret) _buffer_overflow = false; - return ret; - } - int peek(); - - virtual size_t write(uint8_t byte); - virtual int read(); - virtual int available(); - virtual void flush(); - operator bool() { return true; } - - static void setInterruptPriority(uint32_t preemptPriority, uint32_t subPriority); - - using Print::write; -}; - -#endif // SOFTWARESERIAL_H diff --git a/Marlin/src/HAL/HAL_STM32/endstop_interrupts.h b/Marlin/src/HAL/HAL_STM32/endstop_interrupts.h deleted file mode 100644 index 0b97c3c77412..000000000000 --- a/Marlin/src/HAL/HAL_STM32/endstop_interrupts.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * Copyright (c) 2017 Victor Perez - * - * 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 . - * - */ -#pragma once - -#include "../../module/endstops.h" - -// One ISR for all EXT-Interrupts -void endstop_ISR() { endstops.update(); } - -void setup_endstop_interrupts() { - #if HAS_X_MAX - attachInterrupt(X_MAX_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_X_MIN - attachInterrupt(X_MIN_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Y_MAX - attachInterrupt(Y_MAX_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Y_MIN - attachInterrupt(Y_MIN_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z_MAX - attachInterrupt(Z_MAX_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z_MIN - attachInterrupt(Z_MIN_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z2_MAX - attachInterrupt(Z2_MAX_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z2_MIN - attachInterrupt(Z2_MIN_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z3_MAX - attachInterrupt(Z3_MAX_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z3_MIN - attachInterrupt(Z3_MIN_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z4_MAX - attachInterrupt(Z4_MAX_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z4_MIN - attachInterrupt(Z4_MIN_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z_MIN_PROBE_PIN - attachInterrupt(Z_MIN_PROBE_PIN, endstop_ISR, CHANGE); - #endif -} diff --git a/Marlin/src/HAL/HAL_STM32/inc/Conditionals_LCD.h b/Marlin/src/HAL/HAL_STM32/inc/Conditionals_LCD.h deleted file mode 100644 index 0285c52ee365..000000000000 --- a/Marlin/src/HAL/HAL_STM32/inc/Conditionals_LCD.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/Marlin/src/HAL/HAL_STM32/inc/Conditionals_adv.h b/Marlin/src/HAL/HAL_STM32/inc/Conditionals_adv.h deleted file mode 100644 index 0285c52ee365..000000000000 --- a/Marlin/src/HAL/HAL_STM32/inc/Conditionals_adv.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/Marlin/src/HAL/HAL_STM32/inc/Conditionals_post.h b/Marlin/src/HAL/HAL_STM32/inc/Conditionals_post.h deleted file mode 100644 index 0285c52ee365..000000000000 --- a/Marlin/src/HAL/HAL_STM32/inc/Conditionals_post.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/Marlin/src/HAL/HAL_STM32/inc/SanityCheck.h b/Marlin/src/HAL/HAL_STM32/inc/SanityCheck.h deleted file mode 100644 index b1d0029ba9d4..000000000000 --- a/Marlin/src/HAL/HAL_STM32/inc/SanityCheck.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Test STM32-specific configuration values for errors at compile-time. - */ -//#if ENABLED(SPINDLE_LASER_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11) -// #error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector" -//#endif - -#if ENABLED(EMERGENCY_PARSER) - #error "EMERGENCY_PARSER is not yet implemented for STM32. Disable EMERGENCY_PARSER to continue." -#endif - -#if ENABLED(FAST_PWM_FAN) - #error "FAST_PWM_FAN is not yet implemented for this platform." -#endif diff --git a/Marlin/src/HAL/HAL_STM32/persistent_store_impl.cpp b/Marlin/src/HAL/HAL_STM32/persistent_store_impl.cpp deleted file mode 100644 index b4e58a795e28..000000000000 --- a/Marlin/src/HAL/HAL_STM32/persistent_store_impl.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * Copyright (c) 2016 Victor Perez victor_pv@hotmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC) - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(EEPROM_SETTINGS) && ANY(SRAM_EEPROM_EMULATION, SPI_EEPROM, I2C_EEPROM) - -#include "../shared/persistent_store_api.h" - -bool PersistentStore::access_start() { - return true; -} - -bool PersistentStore::access_finish() { - return true; -} - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - while (size--) { - uint8_t v = *value; - - // Save to either external EEPROM, program flash or Backup SRAM - #if EITHER(SPI_EEPROM, I2C_EEPROM) - // EEPROM has only ~100,000 write cycles, - // so only write bytes that have changed! - uint8_t * const p = (uint8_t * const)pos; - if (v != eeprom_read_byte(p)) { - eeprom_write_byte(p, v); - if (eeprom_read_byte(p) != v) { - SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE); - return true; - } - } - #else - *(__IO uint8_t *)(BKPSRAM_BASE + (uint8_t * const)pos) = v; - #endif - - crc16(crc, &v, 1); - pos++; - value++; - }; - - return false; -} - -bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) { - do { - // Read from either external EEPROM, program flash or Backup SRAM - const uint8_t c = ( - #if EITHER(SPI_EEPROM, I2C_EEPROM) - eeprom_read_byte((uint8_t*)pos) - #else - (*(__IO uint8_t *)(BKPSRAM_BASE + ((uint8_t*)pos))) - #endif - ); - - if (writing) *value = c; - crc16(crc, &c, 1); - pos++; - value++; - } while (--size); - return false; -} - -size_t PersistentStore::capacity() { - return ( - #if ENABLED(SRAM_EEPROM_EMULATION) - 4096 // 4kB - #else - E2END + 1 - #endif - ); -} - -#endif // EEPROM_SETTINGS && (SRAM_EEPROM_EMULATION || SPI_EEPROM || I2C_EEPROM) -#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC diff --git a/Marlin/src/HAL/HAL_STM32/timers.cpp b/Marlin/src/HAL/HAL_STM32/timers.cpp deleted file mode 100644 index b7b65f714e84..000000000000 --- a/Marlin/src/HAL/HAL_STM32/timers.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC) - -#include "HAL.h" - -#include "timers.h" - -// ------------------------ -// Local defines -// ------------------------ - -#define NUM_HARDWARE_TIMERS 2 - -#define __TIMER_DEV(X) TIM##X -#define _TIMER_DEV(X) __TIMER_DEV(X) -#define STEP_TIMER_DEV _TIMER_DEV(STEP_TIMER) -#define TEMP_TIMER_DEV _TIMER_DEV(TEMP_TIMER) - -// ------------------------ -// Private Variables -// ------------------------ - -HardwareTimer *timer_instance[NUM_HARDWARE_TIMERS] = { NULL }; -bool timer_enabled[NUM_HARDWARE_TIMERS] = { false }; - -// ------------------------ -// Public functions -// ------------------------ - -// frequency is in Hertz -void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { - if (!HAL_timer_initialized(timer_num)) { - switch (timer_num) { - case STEP_TIMER_NUM: // STEPPER TIMER - use a 32bit timer if possible - timer_instance[timer_num] = new HardwareTimer(STEP_TIMER_DEV); - /* Set the prescaler to the final desired value. - * This will change the effective ISR callback frequency but when - * HAL_timer_start(timer_num=0) is called in the core for the first time - * the real frequency isn't important as long as, after boot, the ISR - * gets called with the correct prescaler and count register. So here - * we set the prescaler to the correct, final value and ignore the frequency - * asked. We will call back the ISR in 1 second to start at full speed. - * - * The proper fix, however, would be a correct initialization OR a - * HAL_timer_change(const uint8_t timer_num, const uint32_t frequency) - * which changes the prescaler when an IRQ frequency change is needed - * (for example when steppers are turned on) - */ - timer_instance[timer_num]->setPrescaleFactor(STEPPER_TIMER_PRESCALE); //the -1 is done internally - timer_instance[timer_num]->setOverflow(_MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE) /* /frequency */), TICK_FORMAT); - break; - case TEMP_TIMER_NUM: // TEMP TIMER - any available 16bit timer - timer_instance[timer_num] = new HardwareTimer(TEMP_TIMER_DEV); - // The prescale factor is computed automatically for HERTZ_FORMAT - timer_instance[timer_num]->setOverflow(frequency, HERTZ_FORMAT); - break; - } - - HAL_timer_enable_interrupt(timer_num); - - /* - * Initializes (and unfortunately starts) the timer. - * This is needed to set correct IRQ priority at the moment but causes - * no harm since every call to HAL_timer_start() is actually followed by - * a call to HAL_timer_enable_interrupt() which means that there isn't - * a case in which you want the timer to run without a callback. - */ - timer_instance[timer_num]->resume(); // First call to resume() MUST follow the attachInterrupt() - - // This is fixed in Arduino_Core_STM32 1.8. - // These calls can be removed and replaced with - // timer_instance[timer_num]->setInterruptPriority - switch (timer_num) { - case STEP_TIMER_NUM: - HAL_NVIC_SetPriority(STEP_TIMER_IRQ_NAME, STEP_TIMER_IRQ_PRIO, 0); - break; - case TEMP_TIMER_NUM: - HAL_NVIC_SetPriority(TEMP_TIMER_IRQ_NAME, TEMP_TIMER_IRQ_PRIO, 0); - break; - } - } -} - -void HAL_timer_enable_interrupt(const uint8_t timer_num) { - if (HAL_timer_initialized(timer_num) && !timer_enabled[timer_num]) { - timer_enabled[timer_num] = true; - switch (timer_num) { - case STEP_TIMER_NUM: - timer_instance[timer_num]->attachInterrupt(Step_Handler); - break; - case TEMP_TIMER_NUM: - timer_instance[timer_num]->attachInterrupt(Temp_Handler); - break; - } - } -} - -void HAL_timer_disable_interrupt(const uint8_t timer_num) { - if (HAL_timer_interrupt_enabled(timer_num)) { - timer_instance[timer_num]->detachInterrupt(); - timer_enabled[timer_num] = false; - } -} - -bool HAL_timer_interrupt_enabled(const uint8_t timer_num) { - return HAL_timer_initialized(timer_num) && timer_enabled[timer_num]; -} - -// Only for use within the HAL -TIM_TypeDef * HAL_timer_device(const uint8_t timer_num) { - switch (timer_num) { - case STEP_TIMER_NUM: return STEP_TIMER_DEV; - case TEMP_TIMER_NUM: return TEMP_TIMER_DEV; - } - return nullptr; -} - -#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC diff --git a/Marlin/src/HAL/HAL_STM32F1/inc/Conditionals_LCD.h b/Marlin/src/HAL/HAL_STM32F1/inc/Conditionals_LCD.h deleted file mode 100644 index 0285c52ee365..000000000000 --- a/Marlin/src/HAL/HAL_STM32F1/inc/Conditionals_LCD.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/Marlin/src/HAL/HAL_STM32F1/inc/Conditionals_adv.h b/Marlin/src/HAL/HAL_STM32F1/inc/Conditionals_adv.h deleted file mode 100644 index 0285c52ee365..000000000000 --- a/Marlin/src/HAL/HAL_STM32F1/inc/Conditionals_adv.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/Marlin/src/HAL/HAL_STM32F1/inc/Conditionals_post.h b/Marlin/src/HAL/HAL_STM32F1/inc/Conditionals_post.h deleted file mode 100644 index 0285c52ee365..000000000000 --- a/Marlin/src/HAL/HAL_STM32F1/inc/Conditionals_post.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/Marlin/src/HAL/HAL_STM32F1/msc_sd.h b/Marlin/src/HAL/HAL_STM32F1/msc_sd.h deleted file mode 100644 index 125ba3646634..000000000000 --- a/Marlin/src/HAL/HAL_STM32F1/msc_sd.h +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2019 BigTreeTech [https://github.com/bigtreetech] - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -extern USBMassStorage MarlinMSC; -extern USBCompositeSerial MarlinCompositeSerial; - -void MSC_SD_init(); diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/endstop_interrupts.h b/Marlin/src/HAL/HAL_STM32_F4_F7/endstop_interrupts.h deleted file mode 100644 index 0b97c3c77412..000000000000 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/endstop_interrupts.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * Copyright (c) 2017 Victor Perez - * - * 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 . - * - */ -#pragma once - -#include "../../module/endstops.h" - -// One ISR for all EXT-Interrupts -void endstop_ISR() { endstops.update(); } - -void setup_endstop_interrupts() { - #if HAS_X_MAX - attachInterrupt(X_MAX_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_X_MIN - attachInterrupt(X_MIN_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Y_MAX - attachInterrupt(Y_MAX_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Y_MIN - attachInterrupt(Y_MIN_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z_MAX - attachInterrupt(Z_MAX_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z_MIN - attachInterrupt(Z_MIN_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z2_MAX - attachInterrupt(Z2_MAX_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z2_MIN - attachInterrupt(Z2_MIN_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z3_MAX - attachInterrupt(Z3_MAX_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z3_MIN - attachInterrupt(Z3_MIN_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z4_MAX - attachInterrupt(Z4_MAX_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z4_MIN - attachInterrupt(Z4_MIN_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z_MIN_PROBE_PIN - attachInterrupt(Z_MIN_PROBE_PIN, endstop_ISR, CHANGE); - #endif -} diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/inc/Conditionals_LCD.h b/Marlin/src/HAL/HAL_STM32_F4_F7/inc/Conditionals_LCD.h deleted file mode 100644 index 0285c52ee365..000000000000 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/inc/Conditionals_LCD.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/inc/Conditionals_adv.h b/Marlin/src/HAL/HAL_STM32_F4_F7/inc/Conditionals_adv.h deleted file mode 100644 index 0285c52ee365..000000000000 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/inc/Conditionals_adv.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/inc/Conditionals_post.h b/Marlin/src/HAL/HAL_STM32_F4_F7/inc/Conditionals_post.h deleted file mode 100644 index 0285c52ee365..000000000000 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/inc/Conditionals_post.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/Marlin/src/HAL/HAL_TEENSY31_32/inc/Conditionals_LCD.h b/Marlin/src/HAL/HAL_TEENSY31_32/inc/Conditionals_LCD.h deleted file mode 100644 index 0285c52ee365..000000000000 --- a/Marlin/src/HAL/HAL_TEENSY31_32/inc/Conditionals_LCD.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/Marlin/src/HAL/HAL_TEENSY31_32/inc/Conditionals_adv.h b/Marlin/src/HAL/HAL_TEENSY31_32/inc/Conditionals_adv.h deleted file mode 100644 index 0285c52ee365..000000000000 --- a/Marlin/src/HAL/HAL_TEENSY31_32/inc/Conditionals_adv.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/Marlin/src/HAL/HAL_TEENSY31_32/inc/Conditionals_post.h b/Marlin/src/HAL/HAL_TEENSY31_32/inc/Conditionals_post.h deleted file mode 100644 index 0285c52ee365..000000000000 --- a/Marlin/src/HAL/HAL_TEENSY31_32/inc/Conditionals_post.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/inc/Conditionals_LCD.h b/Marlin/src/HAL/HAL_TEENSY35_36/inc/Conditionals_LCD.h deleted file mode 100644 index 0285c52ee365..000000000000 --- a/Marlin/src/HAL/HAL_TEENSY35_36/inc/Conditionals_LCD.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/inc/Conditionals_adv.h b/Marlin/src/HAL/HAL_TEENSY35_36/inc/Conditionals_adv.h deleted file mode 100644 index 0285c52ee365..000000000000 --- a/Marlin/src/HAL/HAL_TEENSY35_36/inc/Conditionals_adv.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/inc/Conditionals_post.h b/Marlin/src/HAL/HAL_TEENSY35_36/inc/Conditionals_post.h deleted file mode 100644 index 0285c52ee365..000000000000 --- a/Marlin/src/HAL/HAL_TEENSY35_36/inc/Conditionals_post.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/Marlin/src/HAL/HAL_LINUX/HAL.cpp b/Marlin/src/HAL/LINUX/HAL.cpp similarity index 96% rename from Marlin/src/HAL/HAL_LINUX/HAL.cpp rename to Marlin/src/HAL/LINUX/HAL.cpp index d38644f1a5e5..d7d7c2d2b4f0 100644 --- a/Marlin/src/HAL/HAL_LINUX/HAL.cpp +++ b/Marlin/src/HAL/LINUX/HAL.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef __PLAT_LINUX__ #include "../../inc/MarlinConfig.h" diff --git a/Marlin/src/HAL/HAL_LINUX/HAL.h b/Marlin/src/HAL/LINUX/HAL.h similarity index 90% rename from Marlin/src/HAL/HAL_LINUX/HAL.h rename to Marlin/src/HAL/LINUX/HAL.h index 0475c953c356..2e545e03d6f3 100644 --- a/Marlin/src/HAL/HAL_LINUX/HAL.h +++ b/Marlin/src/HAL/LINUX/HAL.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -56,14 +56,12 @@ uint8_t _getc(); #include "../shared/HAL_SPI.h" #include "fastio.h" #include "watchdog.h" -#include "timers.h" #include "serial.h" #define SHARED_SERVOS HAS_SERVOS extern HalSerial usb_serial; #define MYSERIAL0 usb_serial -#define NUM_SERIAL 1 #define ST7920_DELAY_1 DELAY_NS(600) #define ST7920_DELAY_2 DELAY_NS(750) @@ -87,9 +85,10 @@ int freeMemory(); #pragma GCC diagnostic pop // ADC +#define HAL_ADC_VREF 5.0 +#define HAL_ADC_RESOLUTION 10 #define HAL_ANALOG_SELECT(ch) HAL_adc_enable_channel(ch) #define HAL_START_ADC(ch) HAL_adc_start_conversion(ch) -#define HAL_ADC_RESOLUTION 10 #define HAL_READ_ADC() HAL_adc_get_result() #define HAL_ADC_READY() true @@ -102,7 +101,14 @@ uint16_t HAL_adc_get_result(); inline void HAL_clear_reset_source(void) {} inline uint8_t HAL_get_reset_source(void) { return RST_POWER_ON; } +inline void HAL_reboot() {} // reboot the board or restart the bootloader + /* ---------------- Delay in cycles */ FORCE_INLINE static void DELAY_CYCLES(uint64_t x) { Clock::delayCycles(x); } + +// Add strcmp_P if missing +#ifndef strcmp_P + #define strcmp_P(a, b) strcmp((a), (b)) +#endif diff --git a/Marlin/src/HAL/HAL_LINUX/arduino.cpp b/Marlin/src/HAL/LINUX/arduino.cpp similarity index 85% rename from Marlin/src/HAL/HAL_LINUX/arduino.cpp rename to Marlin/src/HAL/LINUX/arduino.cpp index 008db1559256..4b56d02a389c 100644 --- a/Marlin/src/HAL/HAL_LINUX/arduino.cpp +++ b/Marlin/src/HAL/LINUX/arduino.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef __PLAT_LINUX__ #include @@ -76,20 +75,6 @@ uint16_t analogRead(pin_t adc_pin) { return Gpio::get(DIGITAL_PIN_TO_ANALOG_PIN(adc_pin)); } -// ************************** -// Persistent Config Storage -// ************************** - -void eeprom_write_byte(unsigned char *pos, unsigned char value) { - -} - -unsigned char eeprom_read_byte(uint8_t * pos) { return '\0'; } - -void eeprom_read_block(void *__dst, const void *__src, size_t __n) { } - -void eeprom_update_block(const void *__src, void *__dst, size_t __n) { } - char *dtostrf(double __val, signed char __width, unsigned char __prec, char *__s) { char format_string[20]; snprintf(format_string, 20, "%%%d.%df", __width, __prec); diff --git a/Marlin/src/HAL/HAL_LINUX/persistent_store_impl.cpp b/Marlin/src/HAL/LINUX/eeprom.cpp similarity index 85% rename from Marlin/src/HAL/HAL_LINUX/persistent_store_impl.cpp rename to Marlin/src/HAL/LINUX/eeprom.cpp index 660ecd56f184..967ca851abc1 100644 --- a/Marlin/src/HAL/HAL_LINUX/persistent_store_impl.cpp +++ b/Marlin/src/HAL/LINUX/eeprom.cpp @@ -16,23 +16,27 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef __PLAT_LINUX__ #include "../../inc/MarlinConfig.h" #if ENABLED(EEPROM_SETTINGS) -#include "../shared/persistent_store_api.h" +#include "../shared/eeprom_api.h" #include -#define LINUX_EEPROM_SIZE (E2END + 1) -uint8_t buffer[LINUX_EEPROM_SIZE]; +#ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE 0x1000 // 4KB of Emulated EEPROM +#endif + +uint8_t buffer[MARLIN_EEPROM_SIZE]; char filename[] = "eeprom.dat"; +size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } + bool PersistentStore::access_start() { const char eeprom_erase_value = 0xFF; FILE * eeprom_file = fopen(filename, "rb"); @@ -41,8 +45,8 @@ bool PersistentStore::access_start() { fseek(eeprom_file, 0L, SEEK_END); std::size_t file_size = ftell(eeprom_file); - if (file_size < LINUX_EEPROM_SIZE) { - memset(buffer + file_size, eeprom_erase_value, LINUX_EEPROM_SIZE - file_size); + if (file_size < MARLIN_EEPROM_SIZE) { + memset(buffer + file_size, eeprom_erase_value, MARLIN_EEPROM_SIZE - file_size); } else { fseek(eeprom_file, 0L, SEEK_SET); @@ -96,7 +100,5 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, const size_t size, uin return bytes_read != size; // return true for any error } -size_t PersistentStore::capacity() { return 4096; } // 4KiB of Emulated EEPROM - #endif // EEPROM_SETTINGS #endif // __PLAT_LINUX__ diff --git a/Marlin/src/HAL/HAL_LINUX/fastio.h b/Marlin/src/HAL/LINUX/fastio.h similarity index 94% rename from Marlin/src/HAL/HAL_LINUX/fastio.h rename to Marlin/src/HAL/LINUX/fastio.h index 8b0526710dc7..4567c62a5106 100644 --- a/Marlin/src/HAL/HAL_LINUX/fastio.h +++ b/Marlin/src/HAL/LINUX/fastio.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -44,7 +44,7 @@ * * Now you can simply SET_OUTPUT(STEP); WRITE(STEP, HIGH); WRITE(STEP, LOW); * - * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html + * Why double up on these macros? see https://gcc.gnu.org/onlinedocs/gcc-4.8.5/cpp/Stringification.html */ /// Read a pin diff --git a/Marlin/src/HAL/HAL_LINUX/hardware/Clock.cpp b/Marlin/src/HAL/LINUX/hardware/Clock.cpp similarity index 93% rename from Marlin/src/HAL/HAL_LINUX/hardware/Clock.cpp rename to Marlin/src/HAL/LINUX/hardware/Clock.cpp index 8265fedbf0f4..1984a4a44e94 100644 --- a/Marlin/src/HAL/HAL_LINUX/hardware/Clock.cpp +++ b/Marlin/src/HAL/LINUX/hardware/Clock.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef __PLAT_LINUX__ #include "../../../inc/MarlinConfig.h" diff --git a/Marlin/src/HAL/HAL_LINUX/hardware/Clock.h b/Marlin/src/HAL/LINUX/hardware/Clock.h similarity index 97% rename from Marlin/src/HAL/HAL_LINUX/hardware/Clock.h rename to Marlin/src/HAL/LINUX/hardware/Clock.h index 17c2fd9501dc..072eacfd73db 100644 --- a/Marlin/src/HAL/HAL_LINUX/hardware/Clock.h +++ b/Marlin/src/HAL/LINUX/hardware/Clock.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_LINUX/hardware/Gpio.cpp b/Marlin/src/HAL/LINUX/hardware/Gpio.cpp similarity index 92% rename from Marlin/src/HAL/HAL_LINUX/hardware/Gpio.cpp rename to Marlin/src/HAL/LINUX/hardware/Gpio.cpp index e49fb13754a1..61a7be7da90c 100644 --- a/Marlin/src/HAL/HAL_LINUX/hardware/Gpio.cpp +++ b/Marlin/src/HAL/LINUX/hardware/Gpio.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef __PLAT_LINUX__ #include "Gpio.h" diff --git a/Marlin/src/HAL/HAL_LINUX/hardware/Gpio.h b/Marlin/src/HAL/LINUX/hardware/Gpio.h similarity index 97% rename from Marlin/src/HAL/HAL_LINUX/hardware/Gpio.h rename to Marlin/src/HAL/LINUX/hardware/Gpio.h index 33eea7773124..9255ec1dfc91 100644 --- a/Marlin/src/HAL/HAL_LINUX/hardware/Gpio.h +++ b/Marlin/src/HAL/LINUX/hardware/Gpio.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_LINUX/hardware/Heater.cpp b/Marlin/src/HAL/LINUX/hardware/Heater.cpp similarity index 95% rename from Marlin/src/HAL/HAL_LINUX/hardware/Heater.cpp rename to Marlin/src/HAL/LINUX/hardware/Heater.cpp index 7c9bfaf80f0a..70df8161829a 100644 --- a/Marlin/src/HAL/HAL_LINUX/hardware/Heater.cpp +++ b/Marlin/src/HAL/LINUX/hardware/Heater.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef __PLAT_LINUX__ #include "Clock.h" diff --git a/Marlin/src/HAL/HAL_LINUX/hardware/Heater.h b/Marlin/src/HAL/LINUX/hardware/Heater.h similarity index 94% rename from Marlin/src/HAL/HAL_LINUX/hardware/Heater.h rename to Marlin/src/HAL/LINUX/hardware/Heater.h index bb759da0905f..b17078d0b739 100644 --- a/Marlin/src/HAL/HAL_LINUX/hardware/Heater.h +++ b/Marlin/src/HAL/LINUX/hardware/Heater.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_LINUX/hardware/IOLoggerCSV.cpp b/Marlin/src/HAL/LINUX/hardware/IOLoggerCSV.cpp similarity index 95% rename from Marlin/src/HAL/HAL_LINUX/hardware/IOLoggerCSV.cpp rename to Marlin/src/HAL/LINUX/hardware/IOLoggerCSV.cpp index a79f14f6f5ca..c11fd1f55cd7 100644 --- a/Marlin/src/HAL/HAL_LINUX/hardware/IOLoggerCSV.cpp +++ b/Marlin/src/HAL/LINUX/hardware/IOLoggerCSV.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef __PLAT_LINUX__ #include "IOLoggerCSV.h" diff --git a/Marlin/src/HAL/HAL_LINUX/hardware/IOLoggerCSV.h b/Marlin/src/HAL/LINUX/hardware/IOLoggerCSV.h similarity index 93% rename from Marlin/src/HAL/HAL_LINUX/hardware/IOLoggerCSV.h rename to Marlin/src/HAL/LINUX/hardware/IOLoggerCSV.h index f8bca83e30ec..d8fe7383bdfc 100644 --- a/Marlin/src/HAL/HAL_LINUX/hardware/IOLoggerCSV.h +++ b/Marlin/src/HAL/LINUX/hardware/IOLoggerCSV.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_LINUX/hardware/LinearAxis.cpp b/Marlin/src/HAL/LINUX/hardware/LinearAxis.cpp similarity index 96% rename from Marlin/src/HAL/HAL_LINUX/hardware/LinearAxis.cpp rename to Marlin/src/HAL/LINUX/hardware/LinearAxis.cpp index ec58fe77e50c..c5b3ccc98656 100644 --- a/Marlin/src/HAL/HAL_LINUX/hardware/LinearAxis.cpp +++ b/Marlin/src/HAL/LINUX/hardware/LinearAxis.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef __PLAT_LINUX__ #include diff --git a/Marlin/src/HAL/HAL_LINUX/hardware/LinearAxis.h b/Marlin/src/HAL/LINUX/hardware/LinearAxis.h similarity index 94% rename from Marlin/src/HAL/HAL_LINUX/hardware/LinearAxis.h rename to Marlin/src/HAL/LINUX/hardware/LinearAxis.h index 04a5f3d0f7df..34541e79a1e4 100644 --- a/Marlin/src/HAL/HAL_LINUX/hardware/LinearAxis.h +++ b/Marlin/src/HAL/LINUX/hardware/LinearAxis.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_LINUX/hardware/Timer.cpp b/Marlin/src/HAL/LINUX/hardware/Timer.cpp similarity index 97% rename from Marlin/src/HAL/HAL_LINUX/hardware/Timer.cpp rename to Marlin/src/HAL/LINUX/hardware/Timer.cpp index e7136bbdeff7..9f0d6a8f3ae2 100644 --- a/Marlin/src/HAL/HAL_LINUX/hardware/Timer.cpp +++ b/Marlin/src/HAL/LINUX/hardware/Timer.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef __PLAT_LINUX__ #include "Timer.h" diff --git a/Marlin/src/HAL/HAL_LINUX/hardware/Timer.h b/Marlin/src/HAL/LINUX/hardware/Timer.h similarity index 96% rename from Marlin/src/HAL/HAL_LINUX/hardware/Timer.h rename to Marlin/src/HAL/LINUX/hardware/Timer.h index ebfe8e8b9bb3..757efdcdbd7e 100644 --- a/Marlin/src/HAL/HAL_LINUX/hardware/Timer.h +++ b/Marlin/src/HAL/LINUX/hardware/Timer.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/LINUX/inc/Conditionals_LCD.h b/Marlin/src/HAL/LINUX/inc/Conditionals_LCD.h new file mode 100644 index 000000000000..99a6fc27534a --- /dev/null +++ b/Marlin/src/HAL/LINUX/inc/Conditionals_LCD.h @@ -0,0 +1,26 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if HAS_SPI_TFT || HAS_FSMC_TFT + #error "Sorry! TFT displays are not available for HAL/LINUX." +#endif diff --git a/Marlin/src/HAL/HAL_LINUX/inc/Conditionals_adv.h b/Marlin/src/HAL/LINUX/inc/Conditionals_adv.h similarity index 91% rename from Marlin/src/HAL/HAL_LINUX/inc/Conditionals_adv.h rename to Marlin/src/HAL/LINUX/inc/Conditionals_adv.h index 0285c52ee365..5f1c4b16019d 100644 --- a/Marlin/src/HAL/HAL_LINUX/inc/Conditionals_adv.h +++ b/Marlin/src/HAL/LINUX/inc/Conditionals_adv.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_ESP32/inc/Conditionals_post.h b/Marlin/src/HAL/LINUX/inc/Conditionals_post.h similarity index 91% rename from Marlin/src/HAL/HAL_ESP32/inc/Conditionals_post.h rename to Marlin/src/HAL/LINUX/inc/Conditionals_post.h index 0285c52ee365..5f1c4b16019d 100644 --- a/Marlin/src/HAL/HAL_ESP32/inc/Conditionals_post.h +++ b/Marlin/src/HAL/LINUX/inc/Conditionals_post.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_LINUX/inc/SanityCheck.h b/Marlin/src/HAL/LINUX/inc/SanityCheck.h similarity index 83% rename from Marlin/src/HAL/HAL_LINUX/inc/SanityCheck.h rename to Marlin/src/HAL/LINUX/inc/SanityCheck.h index a3238b088b83..84167c97a144 100644 --- a/Marlin/src/HAL/HAL_LINUX/inc/SanityCheck.h +++ b/Marlin/src/HAL/LINUX/inc/SanityCheck.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -30,8 +30,8 @@ #error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector" #endif -#if ENABLED(FAST_PWM_FAN) - #error "FAST_PWM_FAN is not yet implemented for this platform." +#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY + #error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on LINUX." #endif #if HAS_TMC_SW_SERIAL diff --git a/Marlin/src/HAL/HAL_LINUX/include/Arduino.h b/Marlin/src/HAL/LINUX/include/Arduino.h similarity index 90% rename from Marlin/src/HAL/HAL_LINUX/include/Arduino.h rename to Marlin/src/HAL/LINUX/include/Arduino.h index 55bf0f95ee56..e28b474ede96 100644 --- a/Marlin/src/HAL/HAL_LINUX/include/Arduino.h +++ b/Marlin/src/HAL/LINUX/include/Arduino.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -106,12 +106,6 @@ bool digitalRead(pin_t); void analogWrite(pin_t, int); uint16_t analogRead(pin_t); -// EEPROM -void eeprom_write_byte(unsigned char *pos, unsigned char value); -unsigned char eeprom_read_byte(unsigned char *pos); -void eeprom_read_block(void *__dst, const void *__src, size_t __n); -void eeprom_update_block(const void *__src, void *__dst, size_t __n); - int32_t random(int32_t); int32_t random(int32_t, int32_t); void randomSeed(uint32_t); diff --git a/Marlin/src/HAL/HAL_LINUX/include/pinmapping.cpp b/Marlin/src/HAL/LINUX/include/pinmapping.cpp similarity index 96% rename from Marlin/src/HAL/HAL_LINUX/include/pinmapping.cpp rename to Marlin/src/HAL/LINUX/include/pinmapping.cpp index 0340e681fe44..870ab3a96e5f 100644 --- a/Marlin/src/HAL/HAL_LINUX/include/pinmapping.cpp +++ b/Marlin/src/HAL/LINUX/include/pinmapping.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef __PLAT_LINUX__ #include diff --git a/Marlin/src/HAL/HAL_LINUX/include/pinmapping.h b/Marlin/src/HAL/LINUX/include/pinmapping.h similarity index 95% rename from Marlin/src/HAL/HAL_LINUX/include/pinmapping.h rename to Marlin/src/HAL/LINUX/include/pinmapping.h index 0d99a3811667..98f4b812e873 100644 --- a/Marlin/src/HAL/HAL_LINUX/include/pinmapping.h +++ b/Marlin/src/HAL/LINUX/include/pinmapping.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_LINUX/include/serial.h b/Marlin/src/HAL/LINUX/include/serial.h similarity index 97% rename from Marlin/src/HAL/HAL_LINUX/include/serial.h rename to Marlin/src/HAL/LINUX/include/serial.h index 1036d6539df9..e91624938978 100644 --- a/Marlin/src/HAL/HAL_LINUX/include/serial.h +++ b/Marlin/src/HAL/LINUX/include/serial.h @@ -16,14 +16,14 @@ * 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 . + * along with this program. If not, see . * */ #pragma once #include "../../../inc/MarlinConfigPre.h" #if ENABLED(EMERGENCY_PARSER) - #include "../../../feature/emergency_parser.h" + #include "../../../feature/e_parser.h" #endif #include @@ -33,7 +33,6 @@ * Generic RingBuffer * T type of the buffer array * S size of the buffer (must be power of 2) - * */ template class RingBuffer { public: @@ -79,6 +78,7 @@ class HalSerial { #if ENABLED(EMERGENCY_PARSER) EmergencyParser::State emergency_state; + static inline bool emergency_parser_enabled() { return true; } #endif HalSerial() { host_connected = true; } diff --git a/Marlin/src/HAL/HAL_LINUX/main.cpp b/Marlin/src/HAL/LINUX/main.cpp similarity index 97% rename from Marlin/src/HAL/HAL_LINUX/main.cpp rename to Marlin/src/HAL/LINUX/main.cpp index 1155f2a87338..481f059030b7 100644 --- a/Marlin/src/HAL/HAL_LINUX/main.cpp +++ b/Marlin/src/HAL/LINUX/main.cpp @@ -14,10 +14,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef __PLAT_LINUX__ extern void setup(); @@ -108,7 +107,7 @@ int main() { std::thread write_serial (write_serial_thread); std::thread read_serial (read_serial_thread); - #if NUM_SERIAL > 0 + #ifdef MYSERIAL0 MYSERIAL0.begin(BAUDRATE); SERIAL_ECHOLNPGM("x86_64 Initialized"); SERIAL_FLUSHTX(); diff --git a/Marlin/src/HAL/HAL_LINUX/pinsDebug.h b/Marlin/src/HAL/LINUX/pinsDebug.h similarity index 96% rename from Marlin/src/HAL/HAL_LINUX/pinsDebug.h rename to Marlin/src/HAL/LINUX/pinsDebug.h index e373d3706784..a93ceddc61c3 100644 --- a/Marlin/src/HAL/HAL_LINUX/pinsDebug.h +++ b/Marlin/src/HAL/LINUX/pinsDebug.h @@ -13,7 +13,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/HAL/HAL_LINUX/servo_private.h b/Marlin/src/HAL/LINUX/servo_private.h similarity index 97% rename from Marlin/src/HAL/HAL_LINUX/servo_private.h rename to Marlin/src/HAL/LINUX/servo_private.h index d576ff9266bd..bcc8d2037f90 100644 --- a/Marlin/src/HAL/HAL_LINUX/servo_private.h +++ b/Marlin/src/HAL/LINUX/servo_private.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -45,7 +45,6 @@ * Version 2 Copyright (c) 2009 Michael Margolis. All right reserved. * * The only modification was to update/delete macros to match the LPC176x. - * */ #include diff --git a/Marlin/src/HAL/HAL_LINUX/spi_pins.h b/Marlin/src/HAL/LINUX/spi_pins.h similarity index 88% rename from Marlin/src/HAL/HAL_LINUX/spi_pins.h rename to Marlin/src/HAL/LINUX/spi_pins.h index 8abeb312f479..01ba28e5b604 100644 --- a/Marlin/src/HAL/HAL_LINUX/spi_pins.h +++ b/Marlin/src/HAL/LINUX/spi_pins.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -24,7 +24,7 @@ #include "../../core/macros.h" #include "../../inc/MarlinConfigPre.h" -#if HAS_GRAPHICAL_LCD && ENABLED(SDSUPPORT) && (LCD_PINS_D4 == SCK_PIN || LCD_PINS_ENABLE == MOSI_PIN || DOGLCD_SCK == SCK_PIN || DOGLCD_MOSI == MOSI_PIN) +#if BOTH(HAS_MARLINUI_U8GLIB, SDSUPPORT) && (LCD_PINS_D4 == SCK_PIN || LCD_PINS_ENABLE == MOSI_PIN || DOGLCD_SCK == SCK_PIN || DOGLCD_MOSI == MOSI_PIN) #define LPC_SOFTWARE_SPI // If the SD card and LCD adapter share the same SPI pins, then software SPI is currently // needed due to the speed and mode required for communicating with each device being different. // This requirement can be removed if the SPI access to these devices is updated to use diff --git a/Marlin/src/HAL/HAL_LINUX/timers.cpp b/Marlin/src/HAL/LINUX/timers.cpp similarity index 95% rename from Marlin/src/HAL/HAL_LINUX/timers.cpp rename to Marlin/src/HAL/LINUX/timers.cpp index ebfb9505950e..66d80f25185a 100644 --- a/Marlin/src/HAL/HAL_LINUX/timers.cpp +++ b/Marlin/src/HAL/LINUX/timers.cpp @@ -16,16 +16,14 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef __PLAT_LINUX__ #include "hardware/Timer.h" #include "../../inc/MarlinConfig.h" -#include "timers.h" /** * Use POSIX signals to attempt to emulate Interrupts diff --git a/Marlin/src/HAL/HAL_LINUX/timers.h b/Marlin/src/HAL/LINUX/timers.h similarity index 85% rename from Marlin/src/HAL/HAL_LINUX/timers.h rename to Marlin/src/HAL/LINUX/timers.h index b65758492283..1beaea95abc6 100644 --- a/Marlin/src/HAL/HAL_LINUX/timers.h +++ b/Marlin/src/HAL/LINUX/timers.h @@ -15,7 +15,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -37,9 +37,15 @@ typedef uint32_t hal_timer_t; #define HAL_TIMER_RATE ((SystemCoreClock) / 4) // frequency of timers peripherals -#define STEP_TIMER_NUM 0 // Timer Index for Stepper -#define TEMP_TIMER_NUM 1 // Timer Index for Temperature -#define PULSE_TIMER_NUM STEP_TIMER_NUM +#ifndef STEP_TIMER_NUM + #define STEP_TIMER_NUM 0 // Timer Index for Stepper +#endif +#ifndef PULSE_TIMER_NUM + #define PULSE_TIMER_NUM STEP_TIMER_NUM +#endif +#ifndef TEMP_TIMER_NUM + #define TEMP_TIMER_NUM 1 // Timer Index for Temperature +#endif #define TEMP_TIMER_RATE 1000000 #define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency @@ -59,8 +65,12 @@ typedef uint32_t hal_timer_t; #define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM) #define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM) -#define HAL_STEP_TIMER_ISR() extern "C" void TIMER0_IRQHandler() -#define HAL_TEMP_TIMER_ISR() extern "C" void TIMER1_IRQHandler() +#ifndef HAL_STEP_TIMER_ISR + #define HAL_STEP_TIMER_ISR() extern "C" void TIMER0_IRQHandler() +#endif +#ifndef HAL_TEMP_TIMER_ISR + #define HAL_TEMP_TIMER_ISR() extern "C" void TIMER1_IRQHandler() +#endif // PWM timer #define HAL_PWM_TIMER diff --git a/Marlin/src/HAL/HAL_LINUX/watchdog.cpp b/Marlin/src/HAL/LINUX/watchdog.cpp similarity index 93% rename from Marlin/src/HAL/HAL_LINUX/watchdog.cpp rename to Marlin/src/HAL/LINUX/watchdog.cpp index 5ffe860f055d..c15b0e311c56 100644 --- a/Marlin/src/HAL/HAL_LINUX/watchdog.cpp +++ b/Marlin/src/HAL/LINUX/watchdog.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef __PLAT_LINUX__ #include "../../inc/MarlinConfig.h" diff --git a/Marlin/src/HAL/HAL_LINUX/watchdog.h b/Marlin/src/HAL/LINUX/watchdog.h similarity index 92% rename from Marlin/src/HAL/HAL_LINUX/watchdog.h rename to Marlin/src/HAL/LINUX/watchdog.h index 4771426a0bc3..472624cc7845 100644 --- a/Marlin/src/HAL/HAL_LINUX/watchdog.h +++ b/Marlin/src/HAL/LINUX/watchdog.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_LPC1768/DebugMonitor.cpp b/Marlin/src/HAL/LPC1768/DebugMonitor.cpp similarity index 98% rename from Marlin/src/HAL/HAL_LPC1768/DebugMonitor.cpp rename to Marlin/src/HAL/LPC1768/DebugMonitor.cpp index 2a39e5616807..783b10cfac16 100644 --- a/Marlin/src/HAL/HAL_LPC1768/DebugMonitor.cpp +++ b/Marlin/src/HAL/LPC1768/DebugMonitor.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef TARGET_LPC1768 #include "../../core/macros.h" @@ -211,11 +210,7 @@ void HardFault_HandlerC(unsigned long *sp, unsigned long lr, unsigned long cause // Nothing below here is compiled because NVIC_SystemReset loops forever - for (;;) { - #if ENABLED(USE_WATCHDOG) - watchdog_init(); - #endif - } + for (;;) { TERN_(USE_WATCHDOG, watchdog_init()); } } extern "C" { diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL.cpp b/Marlin/src/HAL/LPC1768/HAL.cpp similarity index 91% rename from Marlin/src/HAL/HAL_LPC1768/HAL.cpp rename to Marlin/src/HAL/LPC1768/HAL.cpp index f0559d268a1c..939f1e8a9408 100644 --- a/Marlin/src/HAL/HAL_LPC1768/HAL.cpp +++ b/Marlin/src/HAL/LPC1768/HAL.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef TARGET_LPC1768 #include "../../inc/MarlinConfig.h" @@ -67,14 +66,10 @@ int16_t PARSED_PIN_INDEX(const char code, const int16_t dval) { return ind > -1 ? ind : dval; } -void flashFirmware(int16_t value) { - NVIC_SystemReset(); -} +void flashFirmware(const int16_t) { NVIC_SystemReset(); } void HAL_clear_reset_source(void) { - #if ENABLED(USE_WATCHDOG) - watchdog_clear_timeout_flag(); - #endif + TERN_(USE_WATCHDOG, watchdog_clear_timeout_flag()); } uint8_t HAL_get_reset_source(void) { diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL.h b/Marlin/src/HAL/LPC1768/HAL.h similarity index 78% rename from Marlin/src/HAL/HAL_LPC1768/HAL.h rename to Marlin/src/HAL/LPC1768/HAL.h index c727877ff372..cb637e715dda 100644 --- a/Marlin/src/HAL/HAL_LPC1768/HAL.h +++ b/Marlin/src/HAL/LPC1768/HAL.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -41,13 +41,15 @@ extern "C" volatile uint32_t _millis; #include "../shared/HAL_SPI.h" #include "fastio.h" #include "watchdog.h" -#include "timers.h" #include "MarlinSerial.h" #include #include #include +// i2c uses 8-bit shifted address +#define I2C_ADDRESS(A) uint8_t((A) << 1) + // // Default graphical display delays // @@ -61,58 +63,35 @@ extern "C" volatile uint32_t _millis; #define ST7920_DELAY_3 DELAY_NS(750) #endif +#define _MSERIAL(X) MSerial##X +#define MSERIAL(X) _MSERIAL(X) +#define MSerial0 MSerial + #if SERIAL_PORT == -1 #define MYSERIAL0 UsbSerial -#elif SERIAL_PORT == 0 - #define MYSERIAL0 MSerial -#elif SERIAL_PORT == 1 - #define MYSERIAL0 MSerial1 -#elif SERIAL_PORT == 2 - #define MYSERIAL0 MSerial2 -#elif SERIAL_PORT == 3 - #define MYSERIAL0 MSerial3 +#elif WITHIN(SERIAL_PORT, 0, 3) + #define MYSERIAL0 MSERIAL(SERIAL_PORT) #else #error "SERIAL_PORT must be from -1 to 3. Please update your configuration." #endif #ifdef SERIAL_PORT_2 - #if SERIAL_PORT_2 == SERIAL_PORT - #error "SERIAL_PORT_2 must be different than SERIAL_PORT. Please update your configuration." - #elif SERIAL_PORT_2 == -1 + #if SERIAL_PORT_2 == -1 #define MYSERIAL1 UsbSerial - #elif SERIAL_PORT_2 == 0 - #define MYSERIAL1 MSerial - #elif SERIAL_PORT_2 == 1 - #define MYSERIAL1 MSerial1 - #elif SERIAL_PORT_2 == 2 - #define MYSERIAL1 MSerial2 - #elif SERIAL_PORT_2 == 3 - #define MYSERIAL1 MSerial3 + #elif WITHIN(SERIAL_PORT_2, 0, 3) + #define MYSERIAL1 MSERIAL(SERIAL_PORT_2) #else #error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration." #endif - #define NUM_SERIAL 2 -#else - #define NUM_SERIAL 1 #endif -#ifdef DGUS_SERIAL_PORT - #if DGUS_SERIAL_PORT == SERIAL_PORT - #error "DGUS_SERIAL_PORT must be different than SERIAL_PORT. Please update your configuration." - #elif defined(SERIAL_PORT_2) && DGUS_SERIAL_PORT == SERIAL_PORT_2 - #error "DGUS_SERIAL_PORT must be different than SERIAL_PORT_2. Please update your configuration." - #elif DGUS_SERIAL_PORT == -1 - #define DGUS_SERIAL UsbSerial - #elif DGUS_SERIAL_PORT == 0 - #define DGUS_SERIAL MSerial - #elif DGUS_SERIAL_PORT == 1 - #define DGUS_SERIAL MSerial1 - #elif DGUS_SERIAL_PORT == 2 - #define DGUS_SERIAL MSerial2 - #elif DGUS_SERIAL_PORT == 3 - #define DGUS_SERIAL MSerial3 +#ifdef LCD_SERIAL_PORT + #if LCD_SERIAL_PORT == -1 + #define LCD_SERIAL UsbSerial + #elif WITHIN(LCD_SERIAL_PORT, 0, 3) + #define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT) #else - #error "DGUS_SERIAL_PORT must be from -1 to 3. Please update your configuration." + #error "LCD_SERIAL_PORT must be from -1 to 3. Please update your configuration." #endif #endif @@ -148,6 +127,8 @@ int freeMemory(); // K = 6, 565 samples, 500Hz sample rate, 1.13s convergence on full range step // Memory usage per ADC channel (bytes): 4 (32 Bytes for 8 channels) +#define HAL_ADC_VREF 3.3 // ADC voltage reference + #define HAL_ADC_RESOLUTION 12 // 15 bit maximum, raw temperature is stored as int16_t #define HAL_ADC_FILTERED // Disable oversampling done in Marlin as ADC values already filtered in HAL @@ -195,7 +176,9 @@ int16_t PARSED_PIN_INDEX(const char code, const int16_t dval); void HAL_idletask(); #define PLATFORM_M997_SUPPORT -void flashFirmware(int16_t value); +void flashFirmware(const int16_t); + +#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment /** * set_pwm_frequency @@ -216,3 +199,10 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, // Reset source void HAL_clear_reset_source(void); uint8_t HAL_get_reset_source(void); + +inline void HAL_reboot() {} // reboot the board or restart the bootloader + +// Add strcmp_P if missing +#ifndef strcmp_P + #define strcmp_P(a, b) strcmp((a), (b)) +#endif diff --git a/Marlin/src/HAL/LPC1768/HAL_SPI.cpp b/Marlin/src/HAL/LPC1768/HAL_SPI.cpp new file mode 100644 index 000000000000..b3d2908ac93e --- /dev/null +++ b/Marlin/src/HAL/LPC1768/HAL_SPI.cpp @@ -0,0 +1,405 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * Software SPI functions originally from Arduino Sd2Card Library + * Copyright (c) 2009 by William Greiman + */ + +/** + * For TARGET_LPC1768 + */ + +/** + * Hardware SPI and Software SPI implementations are included in this file. + * The hardware SPI runs faster and has higher throughput but is not compatible + * with some LCD interfaces/adapters. + * + * Control of the slave select pin(s) is handled by the calling routines. + * + * Some of the LCD interfaces/adapters result in the LCD SPI and the SD card + * SPI sharing pins. The SCK, MOSI & MISO pins can NOT be set/cleared with + * WRITE nor digitalWrite when the hardware SPI module within the LPC17xx is + * active. If any of these pins are shared then the software SPI must be used. + * + * A more sophisticated hardware SPI can be found at the following link. + * This implementation has not been fully debugged. + * https://github.com/MarlinFirmware/Marlin/tree/071c7a78f27078fd4aee9a3ef365fcf5e143531e + */ + +#ifdef TARGET_LPC1768 + +#include "../../inc/MarlinConfig.h" +#include + +// Hardware SPI and SPIClass +#include +#include + +// ------------------------ +// Public functions +// ------------------------ +#if ENABLED(LPC_SOFTWARE_SPI) + + #include + + // Software SPI + + static uint8_t SPI_speed = 0; + + static uint8_t spiTransfer(uint8_t b) { + return swSpiTransfer(b, SPI_speed, SCK_PIN, MISO_PIN, MOSI_PIN); + } + + void spiBegin() { + swSpiBegin(SCK_PIN, MISO_PIN, MOSI_PIN); + } + + void spiInit(uint8_t spiRate) { + SPI_speed = swSpiInit(spiRate, SCK_PIN, MOSI_PIN); + } + + uint8_t spiRec() { return spiTransfer(0xFF); } + + void spiRead(uint8_t*buf, uint16_t nbyte) { + for (int i = 0; i < nbyte; i++) + buf[i] = spiTransfer(0xFF); + } + + void spiSend(uint8_t b) { (void)spiTransfer(b); } + + void spiSend(const uint8_t* buf, size_t nbyte) { + for (uint16_t i = 0; i < nbyte; i++) + (void)spiTransfer(buf[i]); + } + + void spiSendBlock(uint8_t token, const uint8_t* buf) { + (void)spiTransfer(token); + for (uint16_t i = 0; i < 512; i++) + (void)spiTransfer(buf[i]); + } + +#else + + void spiBegin() { // setup SCK, MOSI & MISO pins for SSP0 + spiInit(SPI_SPEED); + } + + void spiInit(uint8_t spiRate) { + #if MISO_PIN == BOARD_SPI1_MISO_PIN + SPI.setModule(1); + #elif MISO_PIN == BOARD_SPI2_MISO_PIN + SPI.setModule(2); + #endif + SPI.setDataSize(DATA_SIZE_8BIT); + SPI.setDataMode(SPI_MODE0); + + SPI.setClock(SPISettings::spiRate2Clock(spiRate)); + SPI.begin(); + } + + static uint8_t doio(uint8_t b) { + return SPI.transfer(b & 0x00FF) & 0x00FF; + } + + void spiSend(uint8_t b) { doio(b); } + + void spiSend(const uint8_t* buf, size_t nbyte) { + for (uint16_t i = 0; i < nbyte; i++) doio(buf[i]); + } + + void spiSend(uint32_t chan, byte b) { + } + + void spiSend(uint32_t chan, const uint8_t* buf, size_t nbyte) { + } + + // Read single byte from SPI + uint8_t spiRec() { return doio(0xFF); } + + uint8_t spiRec(uint32_t chan) { return 0; } + + // Read from SPI into buffer + void spiRead(uint8_t *buf, uint16_t nbyte) { + for (uint16_t i = 0; i < nbyte; i++) buf[i] = doio(0xFF); + } + + uint8_t spiTransfer(uint8_t b) { + return doio(b); + } + + // Write from buffer to SPI + void spiSendBlock(uint8_t token, const uint8_t* buf) { + (void)spiTransfer(token); + for (uint16_t i = 0; i < 512; i++) + (void)spiTransfer(buf[i]); + } + + /** Begin SPI transaction, set clock, bit order, data mode */ + void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) { + // TODO: to be implemented + + } + +#endif // LPC_SOFTWARE_SPI + +/** + * @brief Wait until TXE (tx empty) flag is set and BSY (busy) flag unset. + */ +static inline void waitSpiTxEnd(LPC_SSP_TypeDef *spi_d) { + while (SSP_GetStatus(spi_d, SSP_STAT_TXFIFO_EMPTY) == RESET) { /* nada */ } // wait until TXE=1 + while (SSP_GetStatus(spi_d, SSP_STAT_BUSY) == SET) { /* nada */ } // wait until BSY=0 +} + +// Retain the pin init state of the SPI, to avoid init more than once, +// even if more instances of SPIClass exist +static bool spiInitialised[BOARD_NR_SPI] = { false }; + +SPIClass::SPIClass(uint8_t device) { + // Init things specific to each SPI device + // clock divider setup is a bit of hack, and needs to be improved at a later date. + + #if BOARD_NR_SPI >= 1 + _settings[0].spi_d = LPC_SSP0; + _settings[0].dataMode = SPI_MODE0; + _settings[0].dataSize = DATA_SIZE_8BIT; + _settings[0].clock = SPI_CLOCK_MAX; + //_settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock); + #endif + + #if BOARD_NR_SPI >= 2 + _settings[1].spi_d = LPC_SSP1; + _settings[1].dataMode = SPI_MODE0; + _settings[1].dataSize = DATA_SIZE_8BIT; + _settings[1].clock = SPI_CLOCK_MAX; + //_settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock); + #endif + + setModule(device); + + // Init the GPDMA controller + // TODO: call once in the constructor? or each time? + GPDMA_Init(); +} + +void SPIClass::begin() { + // Init the SPI pins in the first begin call + if ((_currentSetting->spi_d == LPC_SSP0 && spiInitialised[0] == false) || + (_currentSetting->spi_d == LPC_SSP1 && spiInitialised[1] == false)) { + pin_t sck, miso, mosi; + if (_currentSetting->spi_d == LPC_SSP0) { + sck = BOARD_SPI1_SCK_PIN; + miso = BOARD_SPI1_MISO_PIN; + mosi = BOARD_SPI1_MOSI_PIN; + spiInitialised[0] = true; + } + else if (_currentSetting->spi_d == LPC_SSP1) { + sck = BOARD_SPI2_SCK_PIN; + miso = BOARD_SPI2_MISO_PIN; + mosi = BOARD_SPI2_MOSI_PIN; + spiInitialised[1] = true; + } + PINSEL_CFG_Type PinCfg; // data structure to hold init values + PinCfg.Funcnum = 2; + PinCfg.OpenDrain = 0; + PinCfg.Pinmode = 0; + PinCfg.Pinnum = LPC176x::pin_bit(sck); + PinCfg.Portnum = LPC176x::pin_port(sck); + PINSEL_ConfigPin(&PinCfg); + SET_OUTPUT(sck); + + PinCfg.Pinnum = LPC176x::pin_bit(miso); + PinCfg.Portnum = LPC176x::pin_port(miso); + PINSEL_ConfigPin(&PinCfg); + SET_INPUT(miso); + + PinCfg.Pinnum = LPC176x::pin_bit(mosi); + PinCfg.Portnum = LPC176x::pin_port(mosi); + PINSEL_ConfigPin(&PinCfg); + SET_OUTPUT(mosi); + } + + updateSettings(); + SSP_Cmd(_currentSetting->spi_d, ENABLE); // start SSP running +} + +void SPIClass::beginTransaction(const SPISettings &cfg) { + setBitOrder(cfg.bitOrder); + setDataMode(cfg.dataMode); + setDataSize(cfg.dataSize); + //setClockDivider(determine_baud_rate(_currentSetting->spi_d, settings.clock)); + begin(); +} + +uint8_t SPIClass::transfer(const uint16_t b) { + // Send and receive a single byte + SSP_ReceiveData(_currentSetting->spi_d); // read any previous data + SSP_SendData(_currentSetting->spi_d, b); + waitSpiTxEnd(_currentSetting->spi_d); // wait for it to finish + return SSP_ReceiveData(_currentSetting->spi_d); +} + +uint16_t SPIClass::transfer16(const uint16_t data) { + return (transfer((data >> 8) & 0xFF) << 8) | (transfer(data & 0xFF) & 0xFF); +} + +void SPIClass::end() { + // SSP_Cmd(_currentSetting->spi_d, DISABLE); // stop device or SSP_DeInit? + SSP_DeInit(_currentSetting->spi_d); +} + +void SPIClass::send(uint8_t data) { + SSP_SendData(_currentSetting->spi_d, data); +} + +void SPIClass::dmaSend(void *buf, uint16_t length, bool minc) { + //TODO: LPC dma can only write 0xFFF bytes at once. + GPDMA_Channel_CFG_Type GPDMACfg; + + /* Configure GPDMA channel 0 -------------------------------------------------------------*/ + /* DMA Channel 0 */ + GPDMACfg.ChannelNum = 0; + // Source memory + GPDMACfg.SrcMemAddr = (uint32_t)buf; + // Destination memory - Not used + GPDMACfg.DstMemAddr = 0; + // Transfer size + GPDMACfg.TransferSize = length; + // Transfer width + GPDMACfg.TransferWidth = (_currentSetting->dataSize == DATA_SIZE_16BIT) ? GPDMA_WIDTH_HALFWORD : GPDMA_WIDTH_BYTE; + // Transfer type + GPDMACfg.TransferType = GPDMA_TRANSFERTYPE_M2P; + // Source connection - unused + GPDMACfg.SrcConn = 0; + // Destination connection + GPDMACfg.DstConn = (_currentSetting->spi_d == LPC_SSP0) ? GPDMA_CONN_SSP0_Tx : GPDMA_CONN_SSP1_Tx; + + GPDMACfg.DMALLI = 0; + + // Enable dma on SPI + SSP_DMACmd(_currentSetting->spi_d, SSP_DMA_TX, ENABLE); + + // Only increase memory if minc is true + GPDMACfg.MemoryIncrease = (minc ? GPDMA_DMACCxControl_SI : 0); + + // Setup channel with given parameter + GPDMA_Setup(&GPDMACfg); + + // Enable DMA + GPDMA_ChannelCmd(0, ENABLE); + + // Wait for data transfer + while (!GPDMA_IntGetStatus(GPDMA_STAT_RAWINTTC, 0) && !GPDMA_IntGetStatus(GPDMA_STAT_RAWINTERR, 0)) { } + + // Clear err and int + GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, 0); + GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, 0); + + // Disable DMA + GPDMA_ChannelCmd(0, DISABLE); + + waitSpiTxEnd(_currentSetting->spi_d); + + SSP_DMACmd(_currentSetting->spi_d, SSP_DMA_TX, DISABLE); +} + +uint16_t SPIClass::read() { + return SSP_ReceiveData(_currentSetting->spi_d); +} + +void SPIClass::read(uint8_t *buf, uint32_t len) { + for (uint16_t i = 0; i < len; i++) buf[i] = transfer(0xFF); +} + +void SPIClass::setClock(uint32_t clock) { + _currentSetting->clock = clock; +} + +void SPIClass::setModule(uint8_t device) { + _currentSetting = &_settings[device - 1];// SPI channels are called 1 2 and 3 but the array is zero indexed +} + +void SPIClass::setBitOrder(uint8_t bitOrder) { + _currentSetting->bitOrder = bitOrder; +} + +void SPIClass::setDataMode(uint8_t dataMode) { + _currentSetting->dataMode = dataMode; +} + +void SPIClass::setDataSize(uint32_t ds) { + _currentSetting->dataSize = ds; +} + +/** + * Set up/tear down + */ +void SPIClass::updateSettings() { + //SSP_DeInit(_currentSetting->spi_d); //todo: need force de init?! + + // divide PCLK by 2 for SSP0 + CLKPWR_SetPCLKDiv(_currentSetting->spi_d == LPC_SSP0 ? CLKPWR_PCLKSEL_SSP0 : CLKPWR_PCLKSEL_SSP1, CLKPWR_PCLKSEL_CCLK_DIV_2); + + SSP_CFG_Type HW_SPI_init; // data structure to hold init values + SSP_ConfigStructInit(&HW_SPI_init); // set values for SPI mode + HW_SPI_init.ClockRate = _currentSetting->clock; + HW_SPI_init.Databit = _currentSetting->dataSize; + + /** + * SPI Mode CPOL CPHA Shift SCK-edge Capture SCK-edge + * 0 0 0 Falling Rising + * 1 0 1 Rising Falling + * 2 1 0 Rising Falling + * 3 1 1 Falling Rising + */ + switch (_currentSetting->dataMode) { + case SPI_MODE0: + HW_SPI_init.CPHA = SSP_CPHA_FIRST; + HW_SPI_init.CPOL = SSP_CPOL_HI; + break; + case SPI_MODE1: + HW_SPI_init.CPHA = SSP_CPHA_SECOND; + HW_SPI_init.CPOL = SSP_CPOL_HI; + break; + case SPI_MODE2: + HW_SPI_init.CPHA = SSP_CPHA_FIRST; + HW_SPI_init.CPOL = SSP_CPOL_LO; + break; + case SPI_MODE3: + HW_SPI_init.CPHA = SSP_CPHA_SECOND; + HW_SPI_init.CPOL = SSP_CPOL_LO; + break; + default: + break; + } + + // TODO: handle bitOrder + SSP_Init(_currentSetting->spi_d, &HW_SPI_init); // puts the values into the proper bits in the SSP0 registers +} + +#if MISO_PIN == BOARD_SPI1_MISO_PIN + SPIClass SPI(1); +#elif MISO_PIN == BOARD_SPI2_MISO_PIN + SPIClass SPI(2); +#endif + +#endif // TARGET_LPC1768 diff --git a/Marlin/src/HAL/HAL_LPC1768/MarlinSerial.cpp b/Marlin/src/HAL/LPC1768/MarlinSerial.cpp similarity index 76% rename from Marlin/src/HAL/HAL_LPC1768/MarlinSerial.cpp rename to Marlin/src/HAL/LPC1768/MarlinSerial.cpp index 1b80b211fb73..5374e005d3da 100644 --- a/Marlin/src/HAL/HAL_LPC1768/MarlinSerial.cpp +++ b/Marlin/src/HAL/LPC1768/MarlinSerial.cpp @@ -16,37 +16,36 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef TARGET_LPC1768 #include "../../inc/MarlinConfigPre.h" #include "MarlinSerial.h" -#if (defined(SERIAL_PORT) && SERIAL_PORT == 0) || (defined(SERIAL_PORT_2) && SERIAL_PORT_2 == 0) || (defined(DGUS_SERIAL_PORT) && DGUS_SERIAL_PORT == 0) +#if USING_SERIAL_0 MarlinSerial MSerial(LPC_UART0); extern "C" void UART0_IRQHandler() { MSerial.IRQHandler(); } #endif -#if SERIAL_PORT == 1 || SERIAL_PORT_2 == 1 || DGUS_SERIAL_PORT == 1 +#if USING_SERIAL_1 MarlinSerial MSerial1((LPC_UART_TypeDef *) LPC_UART1); extern "C" void UART1_IRQHandler() { MSerial1.IRQHandler(); } #endif -#if SERIAL_PORT == 2 || SERIAL_PORT_2 == 2 || DGUS_SERIAL_PORT == 2 +#if USING_SERIAL_2 MarlinSerial MSerial2(LPC_UART2); extern "C" void UART2_IRQHandler() { MSerial2.IRQHandler(); } #endif -#if SERIAL_PORT == 3 || SERIAL_PORT_2 == 3 || DGUS_SERIAL_PORT == 3 +#if USING_SERIAL_3 MarlinSerial MSerial3(LPC_UART3); extern "C" void UART3_IRQHandler() { MSerial3.IRQHandler(); diff --git a/Marlin/src/HAL/HAL_LPC1768/MarlinSerial.h b/Marlin/src/HAL/LPC1768/MarlinSerial.h similarity index 87% rename from Marlin/src/HAL/HAL_LPC1768/MarlinSerial.h rename to Marlin/src/HAL/LPC1768/MarlinSerial.h index cfddc28406de..8d6b64378a0a 100644 --- a/Marlin/src/HAL/HAL_LPC1768/MarlinSerial.h +++ b/Marlin/src/HAL/LPC1768/MarlinSerial.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -26,7 +26,7 @@ #include "../../inc/MarlinConfigPre.h" #if ENABLED(EMERGENCY_PARSER) - #include "../../feature/emergency_parser.h" + #include "../../feature/e_parser.h" #endif #ifndef SERIAL_PORT @@ -44,10 +44,9 @@ class MarlinSerial : public HardwareSerial { MarlinSerial(LPC_UART_TypeDef *UARTx) : HardwareSerial(UARTx) #if ENABLED(EMERGENCY_PARSER) - , emergency_state(EmergencyParser::State::EP_RESET) + , emergency_state(EmergencyParser::State::EP_RESET) #endif - { - } + { } void end() {} @@ -58,6 +57,7 @@ class MarlinSerial : public HardwareSerial { } EmergencyParser::State emergency_state; + static inline bool emergency_parser_enabled() { return true; } #endif }; diff --git a/Marlin/src/HAL/HAL_LPC1768/Servo.h b/Marlin/src/HAL/LPC1768/Servo.h similarity index 94% rename from Marlin/src/HAL/HAL_LPC1768/Servo.h rename to Marlin/src/HAL/LPC1768/Servo.h index 71e2bb569541..eb12fd20f4d8 100644 --- a/Marlin/src/HAL/HAL_LPC1768/Servo.h +++ b/Marlin/src/HAL/LPC1768/Servo.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -46,7 +46,6 @@ * Version 2 Copyright (c) 2009 Michael Margolis. All right reserved. * * The only modification was to update/delete macros to match the LPC176x. - * */ #include @@ -60,9 +59,7 @@ class libServo: public Servo { if (attach(servo_info[servoIndex].Pin.nbr) >= 0) { // try to reattach write(value); safe_delay(servo_delay[servoIndex]); // delay to allow servo to reach position - #if ENABLED(DEACTIVATE_SERVOS_AFTER_MOVE) - detach(); - #endif + TERN_(DEACTIVATE_SERVOS_AFTER_MOVE, detach()); } } diff --git a/Marlin/src/HAL/HAL_LPC1768/persistent_store_flash.cpp b/Marlin/src/HAL/LPC1768/eeprom_flash.cpp similarity index 82% rename from Marlin/src/HAL/HAL_LPC1768/persistent_store_flash.cpp rename to Marlin/src/HAL/LPC1768/eeprom_flash.cpp index c7cad4d96c53..255848637520 100644 --- a/Marlin/src/HAL/HAL_LPC1768/persistent_store_flash.cpp +++ b/Marlin/src/HAL/LPC1768/eeprom_flash.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #ifdef TARGET_LPC1768 @@ -36,31 +36,33 @@ * 16Kb I/O buffers (intended to hold DMA USB and Ethernet data, but currently * unused). */ -#include "../../inc/MarlinConfigPre.h" - -#if ENABLED(EEPROM_SETTINGS) - -#include "persistent_store_api.h" #include "../../inc/MarlinConfig.h" #if ENABLED(FLASH_EEPROM_EMULATION) +#include "../shared/eeprom_api.h" + extern "C" { #include } -#define SECTOR_START(sector) ((sector < 16) ? (sector * 0x1000) : ((sector - 14) * 0x8000)) +#ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE 0x1000 // 4KB +#endif + +#define SECTOR_START(sector) ((sector < 16) ? (sector << 12) : ((sector - 14) << 15)) #define EEPROM_SECTOR 29 -#define EEPROM_SIZE (4096) -#define SECTOR_SIZE (32768) -#define EEPROM_SLOTS (SECTOR_SIZE/EEPROM_SIZE) -#define EEPROM_ERASE (0xFF) -#define SLOT_ADDRESS(sector, slot) (((uint8_t *)SECTOR_START(sector)) + slot * EEPROM_SIZE) +#define SECTOR_SIZE 32768 +#define EEPROM_SLOTS ((SECTOR_SIZE)/(MARLIN_EEPROM_SIZE)) +#define EEPROM_ERASE 0xFF +#define SLOT_ADDRESS(sector, slot) (((uint8_t *)SECTOR_START(sector)) + slot * (MARLIN_EEPROM_SIZE)) -static uint8_t ram_eeprom[EEPROM_SIZE] __attribute__((aligned(4))) = {0}; +static uint8_t ram_eeprom[MARLIN_EEPROM_SIZE] __attribute__((aligned(4))) = {0}; static bool eeprom_dirty = false; static int current_slot = 0; +size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } + bool PersistentStore::access_start() { uint32_t first_nblank_loc, first_nblank_val; IAP_STATUS_CODE status; @@ -72,15 +74,15 @@ bool PersistentStore::access_start() { if (status == CMD_SUCCESS) { // sector is blank so nothing stored yet - for (int i = 0; i < EEPROM_SIZE; i++) ram_eeprom[i] = EEPROM_ERASE; + for (int i = 0; i < MARLIN_EEPROM_SIZE; i++) ram_eeprom[i] = EEPROM_ERASE; current_slot = EEPROM_SLOTS; } else { // current slot is the first non blank one - current_slot = first_nblank_loc / EEPROM_SIZE; + current_slot = first_nblank_loc / (MARLIN_EEPROM_SIZE); uint8_t *eeprom_data = SLOT_ADDRESS(EEPROM_SECTOR, current_slot); // load current settings - for (int i = 0; i < EEPROM_SIZE; i++) ram_eeprom[i] = eeprom_data[i]; + for (int i = 0; i < MARLIN_EEPROM_SIZE; i++) ram_eeprom[i] = eeprom_data[i]; } eeprom_dirty = false; @@ -125,8 +127,5 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t return false; // return true for any error } -size_t PersistentStore::capacity() { return EEPROM_SIZE; } - #endif // FLASH_EEPROM_EMULATION -#endif // EEPROM_SETTINGS #endif // TARGET_LPC1768 diff --git a/Marlin/src/HAL/HAL_LPC1768/persistent_store_sdcard.cpp b/Marlin/src/HAL/LPC1768/eeprom_sdcard.cpp similarity index 89% rename from Marlin/src/HAL/HAL_LPC1768/persistent_store_sdcard.cpp rename to Marlin/src/HAL/LPC1768/eeprom_sdcard.cpp index 50d52fb8607d..9f2475f490ef 100644 --- a/Marlin/src/HAL/HAL_LPC1768/persistent_store_sdcard.cpp +++ b/Marlin/src/HAL/LPC1768/eeprom_sdcard.cpp @@ -17,19 +17,16 @@ * 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 . + * along with this program. If not, see . * */ #ifdef TARGET_LPC1768 -#include "../../inc/MarlinConfigPre.h" - -#if ENABLED(EEPROM_SETTINGS) - #include "../../inc/MarlinConfig.h" -#include "persistent_store_api.h" -#if DISABLED(FLASH_EEPROM_EMULATION) +#if ENABLED(SDCARD_EEPROM_EMULATION) + +#include "../shared/eeprom_api.h" #include #include @@ -41,6 +38,11 @@ FATFS fat_fs; FIL eeprom_file; bool eeprom_file_open = false; +#ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE size_t(0x1000) // 4KiB of Emulated EEPROM +#endif +size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } + bool PersistentStore::access_start() { const char eeprom_erase_value = 0xFF; MSC_Aquire_Lock(); @@ -82,21 +84,16 @@ static void debug_rw(const bool write, int &pos, const uint8_t *value, const siz PGM_P const rw_str = write ? PSTR("write") : PSTR("read"); SERIAL_CHAR(' '); serialprintPGM(rw_str); - SERIAL_ECHOPAIR("_data(", pos); - SERIAL_ECHOPAIR(",", (int)value); - SERIAL_ECHOPAIR(",", (int)size); - SERIAL_ECHOLNPGM(", ...)"); + SERIAL_ECHOLNPAIR("_data(", pos, ",", int(value), ",", int(size), ", ...)"); if (total) { SERIAL_ECHOPGM(" f_"); serialprintPGM(rw_str); - SERIAL_ECHOPAIR("()=", (int)s); - SERIAL_ECHOPAIR("\n size=", size); - SERIAL_ECHOPGM("\n bytes_"); + SERIAL_ECHOPAIR("()=", int(s), "\n size=", int(size), "\n bytes_"); serialprintPGM(write ? PSTR("written=") : PSTR("read=")); SERIAL_ECHOLN(total); } else - SERIAL_ECHOLNPAIR(" f_lseek()=", (int)s); + SERIAL_ECHOLNPAIR(" f_lseek()=", int(s)); } // File function return codes for type FRESULT. This goes away soon, but @@ -176,8 +173,5 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, const size_t size, uin return bytes_read != size; // return true for any error } -size_t PersistentStore::capacity() { return 4096; } // 4KiB of Emulated EEPROM - -#endif // !FLASH_EEPROM_EMULATION -#endif // EEPROM_SETTINGS +#endif // SDCARD_EEPROM_EMULATION #endif // TARGET_LPC1768 diff --git a/Marlin/src/HAL/LPC1768/eeprom_wired.cpp b/Marlin/src/HAL/LPC1768/eeprom_wired.cpp new file mode 100644 index 000000000000..16c15eaf0063 --- /dev/null +++ b/Marlin/src/HAL/LPC1768/eeprom_wired.cpp @@ -0,0 +1,81 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#ifdef TARGET_LPC1768 + +#include "../../inc/MarlinConfig.h" + +#if USE_WIRED_EEPROM + +/** + * PersistentStore for Arduino-style EEPROM interface + * with implementations supplied by the framework. + */ + +#include "../shared/eeprom_if.h" +#include "../shared/eeprom_api.h" + +#ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE 0x8000 // 32KB‬ +#endif +size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } + +bool PersistentStore::access_start() { eeprom_init(); return true; } +bool PersistentStore::access_finish() { return true; } + +bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { + while (size--) { + uint8_t v = *value; + + // EEPROM has only ~100,000 write cycles, + // so only write bytes that have changed! + uint8_t * const p = (uint8_t * const)pos; + if (v != eeprom_read_byte(p)) { + eeprom_write_byte(p, v); + if (eeprom_read_byte(p) != v) { + SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE); + return true; + } + } + + crc16(crc, &v, 1); + pos++; + value++; + }; + + return false; +} + +bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) { + do { + // Read from external EEPROM + const uint8_t c = eeprom_read_byte((uint8_t*)pos); + + if (writing) *value = c; + crc16(crc, &c, 1); + pos++; + value++; + } while (--size); + return false; +} + +#endif // USE_WIRED_EEPROM +#endif // TARGET_LPC1768 diff --git a/Marlin/src/HAL/HAL_LPC1768/endstop_interrupts.h b/Marlin/src/HAL/LPC1768/endstop_interrupts.h similarity index 98% rename from Marlin/src/HAL/HAL_LPC1768/endstop_interrupts.h rename to Marlin/src/HAL/LPC1768/endstop_interrupts.h index 4c4e9bd3f07d..b0d0c0ec5c0a 100644 --- a/Marlin/src/HAL/HAL_LPC1768/endstop_interrupts.h +++ b/Marlin/src/HAL/LPC1768/endstop_interrupts.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_LPC1768/fast_pwm.cpp b/Marlin/src/HAL/LPC1768/fast_pwm.cpp similarity index 87% rename from Marlin/src/HAL/HAL_LPC1768/fast_pwm.cpp rename to Marlin/src/HAL/LPC1768/fast_pwm.cpp index a1feb2590324..dd440b5e7730 100644 --- a/Marlin/src/HAL/HAL_LPC1768/fast_pwm.cpp +++ b/Marlin/src/HAL/LPC1768/fast_pwm.cpp @@ -16,15 +16,14 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef TARGET_LPC1768 #include "../../inc/MarlinConfigPre.h" -#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_PWM +#if NEEDS_HARDWARE_PWM // Specific meta-flag for features that mandate PWM #include @@ -36,5 +35,5 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255 LPC176x::pwm_write_ratio(pin, invert ? 1.0f - (float)v / v_size : (float)v / v_size); } -#endif // FAST_PWM_FAN || SPINDLE_LASER_PWM +#endif // NEEDS_HARDWARE_PWM #endif // TARGET_LPC1768 diff --git a/Marlin/src/HAL/HAL_LPC1768/fastio.h b/Marlin/src/HAL/LPC1768/fastio.h similarity index 94% rename from Marlin/src/HAL/HAL_LPC1768/fastio.h rename to Marlin/src/HAL/LPC1768/fastio.h index 48de5b8fa079..c553ffb1820d 100644 --- a/Marlin/src/HAL/HAL_LPC1768/fastio.h +++ b/Marlin/src/HAL/LPC1768/fastio.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -56,7 +56,7 @@ * * Now you can simply SET_OUTPUT(STEP); WRITE(STEP, HIGH); WRITE(STEP, LOW); * - * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html + * Why double up on these macros? see https://gcc.gnu.org/onlinedocs/gcc-4.8.5/cpp/Stringification.html */ /// Read a pin @@ -104,7 +104,7 @@ /// set pin as output wrapper - reads the pin and sets the output to that value #define SET_OUTPUT(IO) do{ _WRITE(IO, _READ(IO)); _SET_OUTPUT(IO); }while(0) // set pin as PWM -#define SET_PWM(IO) SET_OUTPUT(IO) +#define SET_PWM SET_OUTPUT /// check if pin is an input wrapper #define IS_INPUT(IO) _IS_INPUT(IO) diff --git a/Marlin/src/HAL/LPC1768/inc/Conditionals_LCD.h b/Marlin/src/HAL/LPC1768/inc/Conditionals_LCD.h new file mode 100644 index 000000000000..32ef908d633c --- /dev/null +++ b/Marlin/src/HAL/LPC1768/inc/Conditionals_LCD.h @@ -0,0 +1,26 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if HAS_FSMC_TFT + #error "Sorry! FSMC TFT displays are not current available for HAL/LPC1768." +#endif diff --git a/Marlin/src/HAL/LPC1768/inc/Conditionals_adv.h b/Marlin/src/HAL/LPC1768/inc/Conditionals_adv.h new file mode 100644 index 000000000000..5f1c4b16019d --- /dev/null +++ b/Marlin/src/HAL/LPC1768/inc/Conditionals_adv.h @@ -0,0 +1,22 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once diff --git a/Marlin/src/HAL/LPC1768/inc/Conditionals_post.h b/Marlin/src/HAL/LPC1768/inc/Conditionals_post.h new file mode 100644 index 000000000000..ce6d3fdde27f --- /dev/null +++ b/Marlin/src/HAL/LPC1768/inc/Conditionals_post.h @@ -0,0 +1,28 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if USE_FALLBACK_EEPROM + #define FLASH_EEPROM_EMULATION +#elif EITHER(I2C_EEPROM, SPI_EEPROM) + #define USE_SHARED_EEPROM 1 +#endif diff --git a/Marlin/src/HAL/LPC1768/inc/SanityCheck.h b/Marlin/src/HAL/LPC1768/inc/SanityCheck.h new file mode 100644 index 000000000000..f5051d32a168 --- /dev/null +++ b/Marlin/src/HAL/LPC1768/inc/SanityCheck.h @@ -0,0 +1,276 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if PIO_PLATFORM_VERSION < 1001 + #error "nxplpc-arduino-lpc176x package is out of date, Please update the PlatformIO platforms, frameworks and libraries. You may need to remove the platform and let it reinstall automatically." +#endif +#if PIO_FRAMEWORK_VERSION < 2005 + #error "framework-arduino-lpc176x package is out of date, Please update the PlatformIO platforms, frameworks and libraries." +#endif + +/** + * Detect an old pins file by checking for old ADC pins values. + */ +#define _OLD_TEMP_PIN(P) PIN_EXISTS(P) && _CAT(P,_PIN) <= 7 && _CAT(P,_PIN) != 2 && _CAT(P,_PIN) != 3 +#if _OLD_TEMP_PIN(TEMP_BED) + #error "TEMP_BED_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." +#elif _OLD_TEMP_PIN(TEMP_0) + #error "TEMP_0_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." +#elif _OLD_TEMP_PIN(TEMP_1) + #error "TEMP_1_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." +#elif _OLD_TEMP_PIN(TEMP_2) + #error "TEMP_2_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." +#elif _OLD_TEMP_PIN(TEMP_3) + #error "TEMP_3_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." +#elif _OLD_TEMP_PIN(TEMP_4) + #error "TEMP_4_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." +#elif _OLD_TEMP_PIN(TEMP_5) + #error "TEMP_5_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." +#elif _OLD_TEMP_PIN(TEMP_6) + #error "TEMP_6_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." +#elif _OLD_TEMP_PIN(TEMP_7) + #error "TEMP_7_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." +#endif +#undef _OLD_TEMP_PIN + +/** + * Because PWM hardware channels all share the same frequency, along with the + * fallback software channels, FAST_PWM_FAN is incompatible with Servos. + */ +static_assert(!(NUM_SERVOS && ENABLED(FAST_PWM_FAN)), "BLTOUCH and Servos are incompatible with FAST_PWM_FAN on LPC176x boards."); + +#if SPINDLE_LASER_FREQUENCY + static_assert(!NUM_SERVOS, "BLTOUCH and Servos are incompatible with SPINDLE_LASER_FREQUENCY on LPC176x boards."); +#endif + +/** + * Test LPC176x-specific configuration values for errors at compile-time. + */ + +//#if ENABLED(SPINDLE_LASER_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11) +// #error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector" +//#endif + +#if MB(RAMPS_14_RE_ARM_EFB, RAMPS_14_RE_ARM_EEB, RAMPS_14_RE_ARM_EFF, RAMPS_14_RE_ARM_EEF, RAMPS_14_RE_ARM_SF) + #if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) && HAS_DRIVER(TMC2130) && DISABLED(TMC_USE_SW_SPI) + #error "Re-ARM with REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER and TMC2130 requires TMC_USE_SW_SPI." + #endif +#endif + +static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported on LPC176x."); + +/** + * Flag any serial port conflicts + * + * Port | TX | RX | + * --- | --- | --- | + * Serial | P0_02 | P0_03 | + * Serial1 | P0_15 | P0_16 | + * Serial2 | P0_10 | P0_11 | + * Serial3 | P0_00 | P0_01 | + */ +#define ANY_TX(N,V...) DO(IS_TX##N,||,V) +#define ANY_RX(N,V...) DO(IS_RX##N,||,V) + +#if USING_SERIAL_0 + #define IS_TX0(P) (P == P0_02) + #define IS_RX0(P) (P == P0_03) + #if IS_TX0(TMC_SW_MISO) || IS_RX0(TMC_SW_MOSI) + #error "Serial port pins (0) conflict with Trinamic SPI pins!" + #elif ENABLED(MK2_MULTIPLEXER) && (IS_TX0(E_MUX1_PIN) || IS_RX0(E_MUX0_PIN)) + #error "Serial port pins (0) conflict with MK2 multiplexer pins!" + #elif (AXIS_HAS_SPI(X) && IS_TX0(X_CS_PIN)) || (AXIS_HAS_SPI(Y) && IS_RX0(Y_CS_PIN)) + #error "Serial port pins (0) conflict with X/Y axis SPI pins!" + #endif + #undef IS_TX0 + #undef IS_RX0 +#endif + +#if USING_SERIAL_1 + #define IS_TX1(P) (P == P0_15) + #define IS_RX1(P) (P == P0_16) + #define _IS_TX1_1 IS_TX1 + #define _IS_RX1_1 IS_RX1 + #if IS_TX1(TMC_SW_SCK) + #error "Serial port pins (1) conflict with other pins!" + #elif HAS_WIRED_LCD + #if IS_TX1(BTN_EN2) || IS_RX1(BTN_EN1) + #error "Serial port pins (1) conflict with Encoder Buttons!" + #elif ANY_TX(1, SCK_PIN, LCD_PINS_D4, DOGLCD_SCK, LCD_RESET_PIN, LCD_PINS_RS, SHIFT_CLK) \ + || ANY_RX(1, LCD_SDSS, LCD_PINS_RS, MISO_PIN, DOGLCD_A0, SS_PIN, LCD_SDSS, DOGLCD_CS, LCD_RESET_PIN, LCD_BACKLIGHT_PIN) + #error "Serial port pins (1) conflict with LCD pins!" + #endif + #endif + #undef IS_TX1 + #undef IS_RX1 + #undef _IS_TX1_1 + #undef _IS_RX1_1 +#endif + +#if USING_SERIAL_2 + #define IS_TX2(P) (P == P0_10) + #define IS_RX2(P) (P == P0_11) + #define _IS_TX2_1 IS_TX2 + #define _IS_RX2_1 IS_RX2 + #if IS_TX2(X2_ENABLE_PIN) || ANY_RX(2, X2_DIR_PIN, X2_STEP_PIN) || (AXIS_HAS_SPI(X2) && IS_TX2(X2_CS_PIN)) + #error "Serial port pins (2) conflict with X2 pins!" + #elif IS_TX2(Y2_ENABLE_PIN) || ANY_RX(2, Y2_DIR_PIN, Y2_STEP_PIN) || (AXIS_HAS_SPI(Y2) && IS_TX2(Y2_CS_PIN)) + #error "Serial port pins (2) conflict with Y2 pins!" + #elif IS_TX2(Z2_ENABLE_PIN) || ANY_RX(2, Z2_DIR_PIN, Z2_STEP_PIN) || (AXIS_HAS_SPI(Z2) && IS_TX2(Z2_CS_PIN)) + #error "Serial port pins (2) conflict with Z2 pins!" + #elif IS_TX2(Z3_ENABLE_PIN) || ANY_RX(2, Z3_DIR_PIN, Z3_STEP_PIN) || (AXIS_HAS_SPI(Z3) && IS_TX2(Z3_CS_PIN)) + #error "Serial port pins (2) conflict with Z3 pins!" + #elif IS_TX2(Z4_ENABLE_PIN) || ANY_RX(2, Z4_DIR_PIN, Z4_STEP_PIN) || (AXIS_HAS_SPI(Z4) && IS_TX2(Z4_CS_PIN)) + #error "Serial port pins (2) conflict with Z4 pins!" + #elif ANY_RX(2, X_DIR_PIN, Y_DIR_PIN) + #error "Serial port pins (2) conflict with other pins!" + #elif Y_HOME_DIR < 0 && IS_TX2(Y_STOP_PIN) + #error "Serial port pins (2) conflict with Y endstop pin!" + #elif HAS_CUSTOM_PROBE_PIN && IS_TX2(Z_MIN_PROBE_PIN) + #error "Serial port pins (2) conflict with probe pin!" + #elif ANY_TX(2, X_ENABLE_PIN, Y_ENABLE_PIN) || ANY_RX(2, X_DIR_PIN, Y_DIR_PIN) + #error "Serial port pins (2) conflict with X/Y stepper pins!" + #elif HAS_MULTI_EXTRUDER && (IS_TX2(E1_ENABLE_PIN) || (AXIS_HAS_SPI(E1) && IS_TX2(E1_CS_PIN))) + #error "Serial port pins (2) conflict with E1 stepper pins!" + #elif EXTRUDERS && ANY_RX(2, E0_DIR_PIN, E0_STEP_PIN) + #error "Serial port pins (2) conflict with E stepper pins!" + #endif + #undef IS_TX2 + #undef IS_RX2 + #undef _IS_TX2_1 + #undef _IS_RX2_1 +#endif + +#if USING_SERIAL_3 + #define PIN_IS_TX3(P) (PIN_EXISTS(P) && P##_PIN == P0_00) + #define PIN_IS_RX3(P) (P##_PIN == P0_01) + #if PIN_IS_TX3(X_MIN) || PIN_IS_RX3(X_MAX) + #error "Serial port pins (3) conflict with X endstop pins!" + #elif PIN_IS_TX3(Y_SERIAL_TX) || PIN_IS_TX3(Y_SERIAL_RX) || PIN_IS_RX3(X_SERIAL_TX) || PIN_IS_RX3(X_SERIAL_RX) + #error "Serial port pins (3) conflict with X/Y axis UART pins!" + #elif PIN_IS_TX3(X2_DIR) || PIN_IS_RX3(X2_STEP) + #error "Serial port pins (3) conflict with X2 pins!" + #elif PIN_IS_TX3(Y2_DIR) || PIN_IS_RX3(Y2_STEP) + #error "Serial port pins (3) conflict with Y2 pins!" + #elif PIN_IS_TX3(Z2_DIR) || PIN_IS_RX3(Z2_STEP) + #error "Serial port pins (3) conflict with Z2 pins!" + #elif PIN_IS_TX3(Z3_DIR) || PIN_IS_RX3(Z3_STEP) + #error "Serial port pins (3) conflict with Z3 pins!" + #elif PIN_IS_TX3(Z4_DIR) || PIN_IS_RX3(Z4_STEP) + #error "Serial port pins (3) conflict with Z4 pins!" + #elif HAS_MULTI_EXTRUDER && (PIN_IS_TX3(E1_DIR) || PIN_IS_RX3(E1_STEP)) + #error "Serial port pins (3) conflict with E1 pins!" + #endif + #undef PIN_IS_TX3 + #undef PIN_IS_RX3 +#endif + +#undef ANY_TX +#undef ANY_RX + +// +// Flag any i2c pin conflicts +// +#if ANY(HAS_MOTOR_CURRENT_I2C, HAS_MOTOR_CURRENT_DAC, EXPERIMENTAL_I2CBUS, I2C_POSITION_ENCODERS, PCA9632, I2C_EEPROM) + #define USEDI2CDEV_M 1 // /Wire.cpp + + #if USEDI2CDEV_M == 0 // P0_27 [D57] (AUX-1) .......... P0_28 [D58] (AUX-1) + #define PIN_IS_SDA0(P) (P##_PIN == P0_27) + #define IS_SCL0(P) (P == P0_28) + #if ENABLED(SDSUPPORT) && PIN_IS_SDA0(SD_DETECT) + #error "SDA0 overlaps with SD_DETECT_PIN!" + #elif PIN_IS_SDA0(E0_AUTO_FAN) + #error "SDA0 overlaps with E0_AUTO_FAN_PIN!" + #elif PIN_IS_SDA0(BEEPER) + #error "SDA0 overlaps with BEEPER_PIN!" + #elif IS_SCL0(BTN_ENC) + #error "SCL0 overlaps with Encoder Button!" + #elif IS_SCL0(SS_PIN) + #error "SCL0 overlaps with SS_PIN!" + #elif IS_SCL0(LCD_SDSS) + #error "SCL0 overlaps with LCD_SDSS!" + #endif + #undef PIN_IS_SDA0 + #undef IS_SCL0 + #elif USEDI2CDEV_M == 1 // P0_00 [D20] (SCA) ............ P0_01 [D21] (SCL) + #define PIN_IS_SDA1(P) (PIN_EXISTS(P) && P##_PIN == P0_00) + #define PIN_IS_SCL1(P) (P##_PIN == P0_01) + #if PIN_IS_SDA1(X_MIN) || PIN_IS_SCL1(X_MAX) + #error "One or more i2c (1) pins overlaps with X endstop pins! Disable i2c peripherals." + #elif PIN_IS_SDA1(X2_DIR) || PIN_IS_SCL1(X2_STEP) + #error "One or more i2c (1) pins overlaps with X2 pins! Disable i2c peripherals." + #elif PIN_IS_SDA1(Y2_DIR) || PIN_IS_SCL1(Y2_STEP) + #error "One or more i2c (1) pins overlaps with Y2 pins! Disable i2c peripherals." + #elif PIN_IS_SDA1(Z2_DIR) || PIN_IS_SCL1(Z2_STEP) + #error "One or more i2c (1) pins overlaps with Z2 pins! Disable i2c peripherals." + #elif PIN_IS_SDA1(Z3_DIR) || PIN_IS_SCL1(Z3_STEP) + #error "One or more i2c (1) pins overlaps with Z3 pins! Disable i2c peripherals." + #elif PIN_IS_SDA1(Z4_DIR) || PIN_IS_SCL1(Z4_STEP) + #error "One or more i2c (1) pins overlaps with Z4 pins! Disable i2c peripherals." + #elif HAS_MULTI_EXTRUDER && (PIN_IS_SDA1(E1_DIR) || PIN_IS_SCL1(E1_STEP)) + #error "One or more i2c (1) pins overlaps with E1 pins! Disable i2c peripherals." + #endif + #undef PIN_IS_SDA1 + #undef PIN_IS_SCL1 + #elif USEDI2CDEV_M == 2 // P0_10 [D38] (X_ENABLE_PIN) ... P0_11 [D55] (X_DIR_PIN) + #define PIN_IS_SDA2(P) (P##_PIN == P0_10) + #define PIN_IS_SCL2(P) (P##_PIN == P0_11) + #if PIN_IS_SDA2(Y_STOP) + #error "i2c SDA2 overlaps with Y endstop pin!" + #elif HAS_CUSTOM_PROBE_PIN && PIN_IS_SDA2(Z_MIN_PROBE) + #error "i2c SDA2 overlaps with Z probe pin!" + #elif PIN_IS_SDA2(X_ENABLE) || PIN_IS_SDA2(Y_ENABLE) + #error "i2c SDA2 overlaps with X/Y ENABLE pin!" + #elif AXIS_HAS_SPI(X) && PIN_IS_SDA2(X_CS) + #error "i2c SDA2 overlaps with X CS pin!" + #elif PIN_IS_SDA2(X2_ENABLE) + #error "i2c SDA2 overlaps with X2 enable pin! Disable i2c peripherals." + #elif PIN_IS_SDA2(Y2_ENABLE) + #error "i2c SDA2 overlaps with Y2 enable pin! Disable i2c peripherals." + #elif PIN_IS_SDA2(Z2_ENABLE) + #error "i2c SDA2 overlaps with Z2 enable pin! Disable i2c peripherals." + #elif PIN_IS_SDA2(Z3_ENABLE) + #error "i2c SDA2 overlaps with Z3 enable pin! Disable i2c peripherals." + #elif PIN_IS_SDA2(Z4_ENABLE) + #error "i2c SDA2 overlaps with Z4 enable pin! Disable i2c peripherals." + #elif HAS_MULTI_EXTRUDER && PIN_IS_SDA2(E1_ENABLE) + #error "i2c SDA2 overlaps with E1 enable pin! Disable i2c peripherals." + #elif HAS_MULTI_EXTRUDER && AXIS_HAS_SPI(E1) && PIN_IS_SDA2(E1_CS) + #error "i2c SDA2 overlaps with E1 CS pin! Disable i2c peripherals." + #elif EXTRUDERS && (PIN_IS_SDA2(E0_STEP) || PIN_IS_SDA2(E0_DIR)) + #error "i2c SCL2 overlaps with E0 STEP/DIR pin! Disable i2c peripherals." + #elif PIN_IS_SDA2(X_DIR) || PIN_IS_SDA2(Y_DIR) + #error "One or more i2c pins overlaps with X/Y DIR pin! Disable i2c peripherals." + #endif + #undef PIN_IS_SDA2 + #undef PIN_IS_SCL2 + #endif + + #undef USEDI2CDEV_M +#endif + +#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) + #error "SERIAL_STATS_MAX_RX_QUEUED is not supported on this platform." +#elif ENABLED(SERIAL_STATS_DROPPED_RX) + #error "SERIAL_STATS_DROPPED_RX is not supported on this platform." +#endif diff --git a/Marlin/src/HAL/LPC1768/include/SPI.h b/Marlin/src/HAL/LPC1768/include/SPI.h new file mode 100644 index 000000000000..9da2a32556e7 --- /dev/null +++ b/Marlin/src/HAL/LPC1768/include/SPI.h @@ -0,0 +1,176 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../../shared/HAL_SPI.h" + +#include +#include +#include + +//#define MSBFIRST 1 + +#define SPI_MODE0 0 +#define SPI_MODE1 1 +#define SPI_MODE2 2 +#define SPI_MODE3 3 + +#define DATA_SIZE_8BIT SSP_DATABIT_8 +#define DATA_SIZE_16BIT SSP_DATABIT_16 + +#define SPI_CLOCK_DIV2 8333333 //(SCR: 2) desired: 8,000,000 actual: 8,333,333 +4.2% SPI_FULL_SPEED +#define SPI_CLOCK_DIV4 4166667 //(SCR: 5) desired: 4,000,000 actual: 4,166,667 +4.2% SPI_HALF_SPEED +#define SPI_CLOCK_DIV8 2083333 //(SCR: 11) desired: 2,000,000 actual: 2,083,333 +4.2% SPI_QUARTER_SPEED +#define SPI_CLOCK_DIV16 1000000 //(SCR: 24) desired: 1,000,000 actual: 1,000,000 SPI_EIGHTH_SPEED +#define SPI_CLOCK_DIV32 500000 //(SCR: 49) desired: 500,000 actual: 500,000 SPI_SPEED_5 +#define SPI_CLOCK_DIV64 250000 //(SCR: 99) desired: 250,000 actual: 250,000 SPI_SPEED_6 +#define SPI_CLOCK_DIV128 125000 //(SCR:199) desired: 125,000 actual: 125,000 Default from HAL.h + +#define SPI_CLOCK_MAX SPI_CLOCK_DIV2 + +#define BOARD_NR_SPI 2 + +//#define BOARD_SPI1_NSS_PIN PA4 ?! +#define BOARD_SPI1_SCK_PIN P0_15 +#define BOARD_SPI1_MISO_PIN P0_17 +#define BOARD_SPI1_MOSI_PIN P0_18 + +//#define BOARD_SPI2_NSS_PIN PB12 ?! +#define BOARD_SPI2_SCK_PIN P0_07 +#define BOARD_SPI2_MISO_PIN P0_08 +#define BOARD_SPI2_MOSI_PIN P0_09 + +class SPISettings { +public: + SPISettings(uint32_t spiRate, int inBitOrder, int inDataMode) { + init_AlwaysInline(spiRate2Clock(spiRate), inBitOrder, inDataMode, DATA_SIZE_8BIT); + } + SPISettings(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) { + if (__builtin_constant_p(inClock)) + init_AlwaysInline(inClock, inBitOrder, inDataMode, inDataSize); + else + init_MightInline(inClock, inBitOrder, inDataMode, inDataSize); + } + SPISettings() { + init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT); + } + + //uint32_t spiRate() const { return spi_speed; } + + static inline uint32_t spiRate2Clock(uint32_t spiRate) { + uint32_t Marlin_speed[7]; // CPSR is always 2 + Marlin_speed[0] = 8333333; //(SCR: 2) desired: 8,000,000 actual: 8,333,333 +4.2% SPI_FULL_SPEED + Marlin_speed[1] = 4166667; //(SCR: 5) desired: 4,000,000 actual: 4,166,667 +4.2% SPI_HALF_SPEED + Marlin_speed[2] = 2083333; //(SCR: 11) desired: 2,000,000 actual: 2,083,333 +4.2% SPI_QUARTER_SPEED + Marlin_speed[3] = 1000000; //(SCR: 24) desired: 1,000,000 actual: 1,000,000 SPI_EIGHTH_SPEED + Marlin_speed[4] = 500000; //(SCR: 49) desired: 500,000 actual: 500,000 SPI_SPEED_5 + Marlin_speed[5] = 250000; //(SCR: 99) desired: 250,000 actual: 250,000 SPI_SPEED_6 + Marlin_speed[6] = 125000; //(SCR:199) desired: 125,000 actual: 125,000 Default from HAL.h + return Marlin_speed[spiRate > 6 ? 6 : spiRate]; + } + +private: + void init_MightInline(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) { + init_AlwaysInline(inClock, inBitOrder, inDataMode, inDataSize); + } + void init_AlwaysInline(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) __attribute__((__always_inline__)) { + clock = inClock; + bitOrder = inBitOrder; + dataMode = inDataMode; + dataSize = inDataSize; + } + + //uint32_t spi_speed; + uint32_t clock; + uint32_t dataSize; + //uint32_t clockDivider; + uint8_t bitOrder; + uint8_t dataMode; + LPC_SSP_TypeDef *spi_d; + + friend class SPIClass; +}; + +/** + * @brief Wirish SPI interface. + * + * This is the same interface is available across HAL + * + * This implementation uses software slave management, so the caller + * is responsible for controlling the slave select line. + */ +class SPIClass { +public: + /** + * @param spiPortNumber Number of the SPI port to manage. + */ + SPIClass(uint8_t spiPortNumber); + + /** + * Select and configure the current selected SPI device to use + */ + void begin(); + + /** + * Disable the current SPI device + */ + void end(); + + void beginTransaction(const SPISettings&); + void endTransaction() {} + + // Transfer using 1 "Data Size" + uint8_t transfer(uint16_t data); + // Transfer 2 bytes in 8 bit mode + uint16_t transfer16(uint16_t data); + + void send(uint8_t data); + + uint16_t read(); + void read(uint8_t *buf, uint32_t len); + + void dmaSend(void *buf, uint16_t length, bool minc); + + /** + * @brief Sets the number of the SPI peripheral to be used by + * this HardwareSPI instance. + * + * @param spi_num Number of the SPI port. 1-2 in low density devices + * or 1-3 in high density devices. + */ + void setModule(uint8_t device); + + void setClock(uint32_t clock); + void setBitOrder(uint8_t bitOrder); + void setDataMode(uint8_t dataMode); + void setDataSize(uint32_t ds); + + inline uint32_t getDataSize() { return _currentSetting->dataSize; } + +private: + SPISettings _settings[BOARD_NR_SPI]; + SPISettings *_currentSetting; + + void updateSettings(); +}; + +extern SPIClass SPI; diff --git a/Marlin/src/HAL/HAL_LPC1768/include/digipot_mcp4451_I2C_routines.c b/Marlin/src/HAL/LPC1768/include/digipot_mcp4451_I2C_routines.c similarity index 98% rename from Marlin/src/HAL/HAL_LPC1768/include/digipot_mcp4451_I2C_routines.c rename to Marlin/src/HAL/LPC1768/include/digipot_mcp4451_I2C_routines.c index 1e53be5f6226..f442ab71c0bd 100644 --- a/Marlin/src/HAL/HAL_LPC1768/include/digipot_mcp4451_I2C_routines.c +++ b/Marlin/src/HAL/LPC1768/include/digipot_mcp4451_I2C_routines.c @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/HAL/HAL_LPC1768/include/digipot_mcp4451_I2C_routines.h b/Marlin/src/HAL/LPC1768/include/digipot_mcp4451_I2C_routines.h similarity index 94% rename from Marlin/src/HAL/HAL_LPC1768/include/digipot_mcp4451_I2C_routines.h rename to Marlin/src/HAL/LPC1768/include/digipot_mcp4451_I2C_routines.h index 6e9ad6f179ee..9b6c62b052a3 100644 --- a/Marlin/src/HAL/HAL_LPC1768/include/digipot_mcp4451_I2C_routines.h +++ b/Marlin/src/HAL/LPC1768/include/digipot_mcp4451_I2C_routines.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_LPC1768/include/i2c_util.c b/Marlin/src/HAL/LPC1768/include/i2c_util.c similarity index 96% rename from Marlin/src/HAL/HAL_LPC1768/include/i2c_util.c rename to Marlin/src/HAL/LPC1768/include/i2c_util.c index b92f3f0453f7..e52fb7c4de92 100644 --- a/Marlin/src/HAL/HAL_LPC1768/include/i2c_util.c +++ b/Marlin/src/HAL/LPC1768/include/i2c_util.c @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/HAL/HAL_LPC1768/include/i2c_util.h b/Marlin/src/HAL/LPC1768/include/i2c_util.h similarity index 94% rename from Marlin/src/HAL/HAL_LPC1768/include/i2c_util.h rename to Marlin/src/HAL/LPC1768/include/i2c_util.h index eae275e0f957..a57f68a4071f 100644 --- a/Marlin/src/HAL/HAL_LPC1768/include/i2c_util.h +++ b/Marlin/src/HAL/LPC1768/include/i2c_util.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_LPC1768/main.cpp b/Marlin/src/HAL/LPC1768/main.cpp similarity index 93% rename from Marlin/src/HAL/HAL_LPC1768/main.cpp rename to Marlin/src/HAL/LPC1768/main.cpp index d7ba62fe5e98..0b4045cb9927 100644 --- a/Marlin/src/HAL/HAL_LPC1768/main.cpp +++ b/Marlin/src/HAL/LPC1768/main.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #ifdef TARGET_LPC1768 @@ -37,8 +37,7 @@ extern "C" { #include "../../sd/cardreader.h" #include "../../inc/MarlinConfig.h" -#include "HAL.h" -#include "timers.h" +#include "../../core/millis_t.h" extern uint32_t MSC_SD_Init(uint8_t pdrv); extern "C" int isLPC1769(); @@ -66,7 +65,7 @@ void HAL_init() { #endif // Flash status LED 3 times to indicate Marlin has started booting - for (uint8_t i = 0; i < 6; ++i) { + LOOP_L_N(i, 6) { TOGGLE(LED_PIN); delay(100); } @@ -89,7 +88,7 @@ void HAL_init() { //debug_frmwrk_init(); //_DBG("\n\nDebug running\n"); - // Initialise the SD card chip select pins as soon as possible + // Initialize the SD card chip select pins as soon as possible #if PIN_EXISTS(SS) OUT_WRITE(SS_PIN, HIGH); #endif @@ -123,7 +122,7 @@ void HAL_init() { delay(1000); // Give OS time to notice USB_Connect(TRUE); - #if !BOTH(SHARED_SD_CARD, INIT_SDCARD_ON_BOOT) && DISABLED(NO_SD_HOST_DRIVE) + #if DISABLED(NO_SD_HOST_DRIVE) MSC_SD_Init(0); // Enable USB SD card access #endif @@ -141,7 +140,7 @@ void HAL_init() { // HAL idle task void HAL_idletask() { - #if ENABLED(SHARED_SD_CARD) + #if HAS_SHARED_MEDIA // If Marlin is using the SD card we need to lock it to prevent access from // a PC via USB. // Other HALs use IS_SD_PRINTING() and IS_SD_FILE_OPEN() to check for access but diff --git a/Marlin/src/HAL/HAL_LPC1768/pinsDebug.h b/Marlin/src/HAL/LPC1768/pinsDebug.h similarity index 96% rename from Marlin/src/HAL/HAL_LPC1768/pinsDebug.h rename to Marlin/src/HAL/LPC1768/pinsDebug.h index 6cc824afa3aa..f80551604fa1 100644 --- a/Marlin/src/HAL/HAL_LPC1768/pinsDebug.h +++ b/Marlin/src/HAL/LPC1768/pinsDebug.h @@ -13,7 +13,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/HAL/HAL_LPC1768/spi_pins.h b/Marlin/src/HAL/LPC1768/spi_pins.h similarity index 88% rename from Marlin/src/HAL/HAL_LPC1768/spi_pins.h rename to Marlin/src/HAL/LPC1768/spi_pins.h index 9b983428bdb0..b4da5d4df234 100644 --- a/Marlin/src/HAL/HAL_LPC1768/spi_pins.h +++ b/Marlin/src/HAL/LPC1768/spi_pins.h @@ -16,14 +16,14 @@ * 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 . + * along with this program. If not, see . * */ #pragma once #include "../../core/macros.h" -#if ENABLED(SDSUPPORT) && HAS_GRAPHICAL_LCD && (LCD_PINS_D4 == SCK_PIN || LCD_PINS_ENABLE == MOSI_PIN || DOGLCD_SCK == SCK_PIN || DOGLCD_MOSI == MOSI_PIN) +#if BOTH(SDSUPPORT, HAS_MARLINUI_U8GLIB) && (LCD_PINS_D4 == SCK_PIN || LCD_PINS_ENABLE == MOSI_PIN || DOGLCD_SCK == SCK_PIN || DOGLCD_MOSI == MOSI_PIN) #define LPC_SOFTWARE_SPI // If the SD card and LCD adapter share the same SPI pins, then software SPI is currently // needed due to the speed and mode required for communicating with each device being different. // This requirement can be removed if the SPI access to these devices is updated to use diff --git a/Marlin/src/HAL/LPC1768/tft/tft_spi.cpp b/Marlin/src/HAL/LPC1768/tft/tft_spi.cpp new file mode 100644 index 000000000000..84907acd0702 --- /dev/null +++ b/Marlin/src/HAL/LPC1768/tft/tft_spi.cpp @@ -0,0 +1,153 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfig.h" + +#if HAS_SPI_TFT + +#include "tft_spi.h" + +//TFT_SPI tft; + +SPIClass TFT_SPI::SPIx(1); + +#define TFT_CS_H WRITE(TFT_CS_PIN, HIGH) +#define TFT_CS_L WRITE(TFT_CS_PIN, LOW) + +#define TFT_DC_H WRITE(TFT_DC_PIN, HIGH) +#define TFT_DC_L WRITE(TFT_DC_PIN, LOW) + +#define TFT_RST_H WRITE(TFT_RESET_PIN, HIGH) +#define TFT_RST_L WRITE(TFT_RESET_PIN, LOW) + +#define TFT_BLK_H WRITE(TFT_BACKLIGHT_PIN, HIGH) +#define TFT_BLK_L WRITE(TFT_BACKLIGHT_PIN, LOW) + +void TFT_SPI::Init() { + #if PIN_EXISTS(TFT_RESET) + SET_OUTPUT(TFT_RESET_PIN); + TFT_RST_H; + delay(100); + #endif + + #if PIN_EXISTS(TFT_BACKLIGHT) + SET_OUTPUT(TFT_BACKLIGHT_PIN); + TFT_BLK_H; + #endif + + SET_OUTPUT(TFT_DC_PIN); + SET_OUTPUT(TFT_CS_PIN); + + TFT_DC_H; + TFT_CS_H; + + /** + * STM32F1 APB2 = 72MHz, APB1 = 36MHz, max SPI speed of this MCU if 18Mhz + * STM32F1 has 3 SPI ports, SPI1 in APB2, SPI2/SPI3 in APB1 + * so the minimum prescale of SPI1 is DIV4, SPI2/SPI3 is DIV2 + */ + #if 0 + #if SPI_DEVICE == 1 + #define SPI_CLOCK_MAX SPI_CLOCK_DIV4 + #else + #define SPI_CLOCK_MAX SPI_CLOCK_DIV2 + #endif + uint8_t clock; + uint8_t spiRate = SPI_FULL_SPEED; + switch (spiRate) { + case SPI_FULL_SPEED: clock = SPI_CLOCK_MAX ; break; + case SPI_HALF_SPEED: clock = SPI_CLOCK_DIV4 ; break; + case SPI_QUARTER_SPEED: clock = SPI_CLOCK_DIV8 ; break; + case SPI_EIGHTH_SPEED: clock = SPI_CLOCK_DIV16; break; + case SPI_SPEED_5: clock = SPI_CLOCK_DIV32; break; + case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break; + default: clock = SPI_CLOCK_DIV2; // Default from the SPI library + } + #endif + + #if TFT_MISO_PIN == BOARD_SPI1_MISO_PIN + SPIx.setModule(1); + #elif TFT_MISO_PIN == BOARD_SPI2_MISO_PIN + SPIx.setModule(2); + #endif + SPIx.setClock(SPI_CLOCK_MAX); + SPIx.setBitOrder(MSBFIRST); + SPIx.setDataMode(SPI_MODE0); +} + +void TFT_SPI::DataTransferBegin(uint16_t DataSize) { + SPIx.setDataSize(DataSize); + SPIx.begin(); + TFT_CS_L; +} + +uint32_t TFT_SPI::GetID() { + uint32_t id; + id = ReadID(LCD_READ_ID); + if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF) + id = ReadID(LCD_READ_ID4); + return id; +} + +uint32_t TFT_SPI::ReadID(uint16_t Reg) { + uint32_t data = 0; + + #if PIN_EXISTS(TFT_MISO) + uint8_t d = 0; + SPIx.setDataSize(DATASIZE_8BIT); + SPIx.setClock(SPI_CLOCK_DIV64); + SPIx.begin(); + TFT_CS_L; + WriteReg(Reg); + + LOOP_L_N(i, 4) { + SPIx.read((uint8_t*)&d, 1); + data = (data << 8) | d; + } + + DataTransferEnd(); + SPIx.setClock(SPI_CLOCK_MAX); + #endif + + return data >> 7; +} + +bool TFT_SPI::isBusy() { + return false; +} + +void TFT_SPI::Abort() { + DataTransferEnd(); +} + +void TFT_SPI::Transmit(uint16_t Data) { + SPIx.transfer(Data); +} + +void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) { + DataTransferBegin(DATASIZE_16BIT); //16 + TFT_DC_H; + SPIx.dmaSend(Data, Count, MemoryIncrease); + DataTransferEnd(); +} + +#endif // HAS_SPI_TFT diff --git a/Marlin/src/HAL/LPC1768/tft/tft_spi.h b/Marlin/src/HAL/LPC1768/tft/tft_spi.h new file mode 100644 index 000000000000..4753fdbae9a0 --- /dev/null +++ b/Marlin/src/HAL/LPC1768/tft/tft_spi.h @@ -0,0 +1,77 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../../../inc/MarlinConfig.h" + +#include +#include +// #include + +#ifndef LCD_READ_ID + #define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341) +#endif +#ifndef LCD_READ_ID4 + #define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341) +#endif + +#define DATASIZE_8BIT SSP_DATABIT_8 +#define DATASIZE_16BIT SSP_DATABIT_16 +#define TFT_IO_DRIVER TFT_SPI + +#define DMA_MINC_ENABLE 1 +#define DMA_MINC_DISABLE 0 + +class TFT_SPI { +private: + static uint32_t ReadID(uint16_t Reg); + static void Transmit(uint16_t Data); + static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count); + +public: + static SPIClass SPIx; + + static void Init(); + static uint32_t GetID(); + static bool isBusy(); + static void Abort(); + + static void DataTransferBegin(uint16_t DataWidth = DATASIZE_16BIT); + static void DataTransferEnd() { OUT_WRITE(TFT_CS_PIN, HIGH); SPIx.end(); }; + static void DataTransferAbort(); + + static void WriteData(uint16_t Data) { Transmit(Data); } + static void WriteReg(uint16_t Reg) { OUT_WRITE(TFT_A0_PIN, LOW); Transmit(Reg); OUT_WRITE(TFT_A0_PIN, HIGH); } + + static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_MINC_ENABLE, Data, Count); } + // static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &Data, Count); } + static void WriteMultiple(uint16_t Color, uint32_t Count) { + static uint16_t Data; Data = Color; + //LPC dma can only write 0xFFF bytes at once. + #define MAX_DMA_SIZE (0xFFF - 1) + while (Count > 0) { + TransmitDMA(DMA_MINC_DISABLE, &Data, Count > MAX_DMA_SIZE ? MAX_DMA_SIZE : Count); + Count = Count > MAX_DMA_SIZE ? Count - MAX_DMA_SIZE : 0; + } + #undef MAX_DMA_SIZE + } +}; diff --git a/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp b/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp new file mode 100644 index 000000000000..5f96630043c1 --- /dev/null +++ b/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp @@ -0,0 +1,128 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfig.h" + +#if HAS_TFT_XPT2046 || HAS_TOUCH_XPT2046 + +#include "xpt2046.h" +#include + +uint16_t delta(uint16_t a, uint16_t b) { return a > b ? a - b : b - a; } + +#if ENABLED(TOUCH_BUTTONS_HW_SPI) + #include + + SPIClass XPT2046::SPIx(TOUCH_BUTTONS_HW_SPI_DEVICE); + + static void touch_spi_init(uint8_t spiRate) { + XPT2046::SPIx.setModule(TOUCH_BUTTONS_HW_SPI_DEVICE); + XPT2046::SPIx.setClock(SPI_CLOCK_DIV128); + XPT2046::SPIx.setBitOrder(MSBFIRST); + XPT2046::SPIx.setDataMode(SPI_MODE0); + XPT2046::SPIx.setDataSize(DATA_SIZE_8BIT); + } +#endif + +void XPT2046::Init() { + SET_INPUT(TOUCH_MISO_PIN); + SET_OUTPUT(TOUCH_MOSI_PIN); + SET_OUTPUT(TOUCH_SCK_PIN); + OUT_WRITE(TOUCH_CS_PIN, HIGH); + + #if PIN_EXISTS(TOUCH_INT) + // Optional Pendrive interrupt pin + SET_INPUT(TOUCH_INT_PIN); + #endif + + TERN_(TOUCH_BUTTONS_HW_SPI, touch_spi_init(SPI_SPEED_6)); + + // Read once to enable pendrive status pin + getRawData(XPT2046_X); +} + +bool XPT2046::isTouched() { + return isBusy() ? false : ( + #if PIN_EXISTS(TOUCH_INT) + READ(TOUCH_INT_PIN) != HIGH + #else + getRawData(XPT2046_Z1) >= XPT2046_Z1_THRESHOLD + #endif + ); +} + +bool XPT2046::getRawPoint(int16_t *x, int16_t *y) { + if (isBusy()) return false; + if (!isTouched()) return false; + *x = getRawData(XPT2046_X); + *y = getRawData(XPT2046_Y); + return isTouched(); +} + +uint16_t XPT2046::getRawData(const XPTCoordinate coordinate) { + uint16_t data[3]; + + DataTransferBegin(); + TERN_(TOUCH_BUTTONS_HW_SPI, SPIx.begin()); + + for (uint16_t i = 0; i < 3 ; i++) { + IO(coordinate); + data[i] = (IO() << 4) | (IO() >> 4); + } + + TERN_(TOUCH_BUTTONS_HW_SPI, SPIx.end()); + DataTransferEnd(); + + uint16_t delta01 = delta(data[0], data[1]), + delta02 = delta(data[0], data[2]), + delta12 = delta(data[1], data[2]); + + if (delta01 > delta02 || delta01 > delta12) + data[delta02 > delta12 ? 0 : 1] = data[2]; + + return (data[0] + data[1]) >> 1; +} + +uint16_t XPT2046::IO(uint16_t data) { + return TERN(TOUCH_BUTTONS_HW_SPI, HardwareIO, SoftwareIO)(data); +} + +extern uint8_t spiTransfer(uint8_t b); + +#if ENABLED(TOUCH_BUTTONS_HW_SPI) + uint16_t XPT2046::HardwareIO(uint16_t data) { + return SPIx.transfer(data & 0xFF); + } +#endif + +uint16_t XPT2046::SoftwareIO(uint16_t data) { + uint16_t result = 0; + + for (uint8_t j = 0x80; j; j >>= 1) { + WRITE(TOUCH_SCK_PIN, LOW); + WRITE(TOUCH_MOSI_PIN, data & j ? HIGH : LOW); + if (READ(TOUCH_MISO_PIN)) result |= j; + WRITE(TOUCH_SCK_PIN, HIGH); + } + WRITE(TOUCH_SCK_PIN, LOW); + + return result; +} + +#endif // HAS_TFT_XPT2046 diff --git a/Marlin/src/HAL/LPC1768/tft/xpt2046.h b/Marlin/src/HAL/LPC1768/tft/xpt2046.h new file mode 100644 index 000000000000..019f75efce12 --- /dev/null +++ b/Marlin/src/HAL/LPC1768/tft/xpt2046.h @@ -0,0 +1,80 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../../../inc/MarlinConfig.h" + +#if ENABLED(TOUCH_BUTTONS_HW_SPI) + #include +#endif + +#ifndef TOUCH_MISO_PIN + #define TOUCH_MISO_PIN MISO_PIN +#endif +#ifndef TOUCH_MOSI_PIN + #define TOUCH_MOSI_PIN MOSI_PIN +#endif +#ifndef TOUCH_SCK_PIN + #define TOUCH_SCK_PIN SCK_PIN +#endif +#ifndef TOUCH_CS_PIN + #define TOUCH_CS_PIN CS_PIN +#endif +#ifndef TOUCH_INT_PIN + #define TOUCH_INT_PIN -1 +#endif + +#define XPT2046_DFR_MODE 0x00 +#define XPT2046_SER_MODE 0x04 +#define XPT2046_CONTROL 0x80 + +enum XPTCoordinate : uint8_t { + XPT2046_X = 0x10 | XPT2046_CONTROL | XPT2046_DFR_MODE, + XPT2046_Y = 0x50 | XPT2046_CONTROL | XPT2046_DFR_MODE, + XPT2046_Z1 = 0x30 | XPT2046_CONTROL | XPT2046_DFR_MODE, + XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE, +}; + +#if !defined(XPT2046_Z1_THRESHOLD) + #define XPT2046_Z1_THRESHOLD 10 +#endif + +class XPT2046 { +private: + static bool isBusy() { return false; } + + static uint16_t getRawData(const XPTCoordinate coordinate); + static bool isTouched(); + + static inline void DataTransferBegin() { WRITE(TOUCH_CS_PIN, LOW); }; + static inline void DataTransferEnd() { WRITE(TOUCH_CS_PIN, HIGH); }; + #if ENABLED(TOUCH_BUTTONS_HW_SPI) + static uint16_t HardwareIO(uint16_t data); + #endif + static uint16_t SoftwareIO(uint16_t data); + static uint16_t IO(uint16_t data = 0); + +public: + #if ENABLED(TOUCH_BUTTONS_HW_SPI) + static SPIClass SPIx; + #endif + + static void Init(); + static bool getRawPoint(int16_t *x, int16_t *y); +}; diff --git a/Marlin/src/HAL/HAL_LPC1768/timers.cpp b/Marlin/src/HAL/LPC1768/timers.cpp similarity index 95% rename from Marlin/src/HAL/HAL_LPC1768/timers.cpp rename to Marlin/src/HAL/LPC1768/timers.cpp index 686b251c690d..a7a40584dabc 100644 --- a/Marlin/src/HAL/HAL_LPC1768/timers.cpp +++ b/Marlin/src/HAL/LPC1768/timers.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -29,7 +29,6 @@ #ifdef TARGET_LPC1768 #include "../../inc/MarlinConfig.h" -#include "timers.h" void HAL_timer_init() { SBI(LPC_SC->PCONP, SBIT_TIMER0); // Power ON Timer 0 diff --git a/Marlin/src/HAL/HAL_LPC1768/timers.h b/Marlin/src/HAL/LPC1768/timers.h similarity index 78% rename from Marlin/src/HAL/HAL_LPC1768/timers.h rename to Marlin/src/HAL/LPC1768/timers.h index 30da93352185..e6744fb005bf 100644 --- a/Marlin/src/HAL/HAL_LPC1768/timers.h +++ b/Marlin/src/HAL/LPC1768/timers.h @@ -15,13 +15,12 @@ * 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 . + * along with this program. If not, see . * */ #pragma once /** - * * HAL For LPC1768 */ @@ -61,10 +60,18 @@ typedef uint32_t hal_timer_t; #define HAL_TIMER_RATE ((F_CPU) / 4) // frequency of timers peripherals -#define STEP_TIMER_NUM 0 // Timer Index for Stepper -#define TEMP_TIMER_NUM 1 // Timer Index for Temperature -#define PULSE_TIMER_NUM STEP_TIMER_NUM -#define PWM_TIMER_NUM 3 // Timer Index for PWM +#ifndef STEP_TIMER_NUM + #define STEP_TIMER_NUM 0 // Timer Index for Stepper +#endif +#ifndef PULSE_TIMER_NUM + #define PULSE_TIMER_NUM STEP_TIMER_NUM +#endif +#ifndef TEMP_TIMER_NUM + #define TEMP_TIMER_NUM 1 // Timer Index for Temperature +#endif +#ifndef PWM_TIMER_NUM + #define PWM_TIMER_NUM 3 // Timer Index for PWM +#endif #define TEMP_TIMER_RATE 1000000 #define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency @@ -84,12 +91,16 @@ typedef uint32_t hal_timer_t; #define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM) #define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM) -#define HAL_STEP_TIMER_ISR() _HAL_TIMER_ISR(STEP_TIMER_NUM) -#define HAL_TEMP_TIMER_ISR() _HAL_TIMER_ISR(TEMP_TIMER_NUM) +#ifndef HAL_STEP_TIMER_ISR + #define HAL_STEP_TIMER_ISR() _HAL_TIMER_ISR(STEP_TIMER_NUM) +#endif +#ifndef HAL_TEMP_TIMER_ISR + #define HAL_TEMP_TIMER_ISR() _HAL_TIMER_ISR(TEMP_TIMER_NUM) +#endif // Timer references by index -#define STEP_TIMER _HAL_TIMER(STEP_TIMER_NUM) -#define TEMP_TIMER _HAL_TIMER(TEMP_TIMER_NUM) +#define STEP_TIMER_PTR _HAL_TIMER(STEP_TIMER_NUM) +#define TEMP_TIMER_PTR _HAL_TIMER(TEMP_TIMER_NUM) // ------------------------ // Public functions @@ -99,23 +110,23 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency); FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) { switch (timer_num) { - case 0: STEP_TIMER->MR0 = compare; break; // Stepper Timer Match Register 0 - case 1: TEMP_TIMER->MR0 = compare; break; // Temp Timer Match Register 0 + case 0: STEP_TIMER_PTR->MR0 = compare; break; // Stepper Timer Match Register 0 + case 1: TEMP_TIMER_PTR->MR0 = compare; break; // Temp Timer Match Register 0 } } FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) { switch (timer_num) { - case 0: return STEP_TIMER->MR0; // Stepper Timer Match Register 0 - case 1: return TEMP_TIMER->MR0; // Temp Timer Match Register 0 + case 0: return STEP_TIMER_PTR->MR0; // Stepper Timer Match Register 0 + case 1: return TEMP_TIMER_PTR->MR0; // Temp Timer Match Register 0 } return 0; } FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) { switch (timer_num) { - case 0: return STEP_TIMER->TC; // Stepper Timer Count - case 1: return TEMP_TIMER->TC; // Temp Timer Count + case 0: return STEP_TIMER_PTR->TC; // Stepper Timer Count + case 1: return TEMP_TIMER_PTR->TC; // Temp Timer Count } return 0; } @@ -154,8 +165,8 @@ FORCE_INLINE static bool HAL_timer_interrupt_enabled(const uint8_t timer_num) { FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) { switch (timer_num) { - case 0: SBI(STEP_TIMER->IR, SBIT_CNTEN); break; - case 1: SBI(TEMP_TIMER->IR, SBIT_CNTEN); break; + case 0: SBI(STEP_TIMER_PTR->IR, SBIT_CNTEN); break; + case 1: SBI(TEMP_TIMER_PTR->IR, SBIT_CNTEN); break; } } diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g/LCD_I2C_routines.cpp b/Marlin/src/HAL/LPC1768/u8g/LCD_I2C_routines.cpp similarity index 98% rename from Marlin/src/HAL/HAL_LPC1768/u8g/LCD_I2C_routines.cpp rename to Marlin/src/HAL/LPC1768/u8g/LCD_I2C_routines.cpp index 6d643f5bf6ed..a48a820dc433 100644 --- a/Marlin/src/HAL/HAL_LPC1768/u8g/LCD_I2C_routines.cpp +++ b/Marlin/src/HAL/LPC1768/u8g/LCD_I2C_routines.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g/LCD_I2C_routines.h b/Marlin/src/HAL/LPC1768/u8g/LCD_I2C_routines.h similarity index 93% rename from Marlin/src/HAL/HAL_LPC1768/u8g/LCD_I2C_routines.h rename to Marlin/src/HAL/LPC1768/u8g/LCD_I2C_routines.h index 9de3e9327490..2d976c92d20d 100644 --- a/Marlin/src/HAL/HAL_LPC1768/u8g/LCD_I2C_routines.h +++ b/Marlin/src/HAL/LPC1768/u8g/LCD_I2C_routines.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g/LCD_defines.h b/Marlin/src/HAL/LPC1768/u8g/LCD_defines.h similarity index 96% rename from Marlin/src/HAL/HAL_LPC1768/u8g/LCD_defines.h rename to Marlin/src/HAL/LPC1768/u8g/LCD_defines.h index e7518d698a83..d2260037b6a7 100644 --- a/Marlin/src/HAL/HAL_LPC1768/u8g/LCD_defines.h +++ b/Marlin/src/HAL/LPC1768/u8g/LCD_defines.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g/LCD_delay.h b/Marlin/src/HAL/LPC1768/u8g/LCD_delay.h similarity index 94% rename from Marlin/src/HAL/HAL_LPC1768/u8g/LCD_delay.h rename to Marlin/src/HAL/LPC1768/u8g/LCD_delay.h index 0d9b8d3dcc0f..0b9e2b4fd055 100644 --- a/Marlin/src/HAL/HAL_LPC1768/u8g/LCD_delay.h +++ b/Marlin/src/HAL/LPC1768/u8g/LCD_delay.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g/LCD_pin_routines.c b/Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.c similarity index 97% rename from Marlin/src/HAL/HAL_LPC1768/u8g/LCD_pin_routines.c rename to Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.c index 67e78f36f056..466fc8020335 100644 --- a/Marlin/src/HAL/HAL_LPC1768/u8g/LCD_pin_routines.c +++ b/Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.c @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g/LCD_pin_routines.h b/Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.h similarity index 94% rename from Marlin/src/HAL/HAL_LPC1768/u8g/LCD_pin_routines.h rename to Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.h index 8a73b69ded59..d60d93daddbd 100644 --- a/Marlin/src/HAL/HAL_LPC1768/u8g/LCD_pin_routines.h +++ b/Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp similarity index 96% rename from Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp rename to Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp index c0105bc129f8..057e10e0f545 100644 --- a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp +++ b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -57,7 +57,7 @@ #include "../../../inc/MarlinConfigPre.h" -#if HAS_GRAPHICAL_LCD +#if HAS_MARLINUI_U8GLIB #include #include "../../shared/HAL_SPI.h" @@ -124,6 +124,6 @@ uint8_t u8g_com_HAL_LPC1768_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, return 1; } -#endif // HAS_GRAPHICAL_LCD +#endif // HAS_MARLINUI_U8GLIB #endif // TARGET_LPC1768 diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp similarity index 98% rename from Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp rename to Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp index b99abb6867e9..6f7efba4ae20 100644 --- a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp +++ b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -77,7 +77,7 @@ #include "../../../inc/MarlinConfigPre.h" -#if HAS_GRAPHICAL_LCD +#if HAS_MARLINUI_U8GLIB #include @@ -193,6 +193,6 @@ uint8_t u8g_com_HAL_LPC1768_ssd_hw_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_v return 1; } -#endif // HAS_GRAPHICAL_LCD +#endif // HAS_MARLINUI_U8GLIB #endif // TARGET_LPC1768 diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp similarity index 97% rename from Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp rename to Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp index 5f3da457aa88..592e27f6c006 100644 --- a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp +++ b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -57,7 +57,7 @@ #include "../../../inc/MarlinConfigPre.h" -#if HAS_GRAPHICAL_LCD +#if HAS_MARLINUI_U8GLIB #include #include "../../shared/HAL_SPI.h" @@ -133,6 +133,6 @@ uint8_t u8g_com_HAL_LPC1768_ST7920_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t ar return 1; } -#endif // HAS_GRAPHICAL_LCD +#endif // HAS_MARLINUI_U8GLIB #endif // TARGET_LPC1768 diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp similarity index 98% rename from Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp rename to Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp index a1f8097e5251..10d84941625f 100644 --- a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp +++ b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp similarity index 92% rename from Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp rename to Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp index a98c5eea9cb9..ca9d6ecfbe25 100644 --- a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp +++ b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -57,7 +57,7 @@ #include "../../../inc/MarlinConfigPre.h" -#if HAS_GRAPHICAL_LCD && DISABLED(U8GLIB_ST7920) +#if HAS_MARLINUI_U8GLIB && DISABLED(U8GLIB_ST7920) #include @@ -73,7 +73,7 @@ uint8_t swSpiTransfer_mode_0(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin ) { - for (uint8_t i = 0; i < 8; i++) { + LOOP_L_N(i, 8) { if (spi_speed == 0) { LPC176x::gpio_set(mosi_pin, !!(b & 0x80)); LPC176x::gpio_set(sck_pin, HIGH); @@ -83,16 +83,16 @@ uint8_t swSpiTransfer_mode_0(uint8_t b, const uint8_t spi_speed, const pin_t sck } else { const uint8_t state = (b & 0x80) ? HIGH : LOW; - for (uint8_t j = 0; j < spi_speed; j++) + LOOP_L_N(j, spi_speed) LPC176x::gpio_set(mosi_pin, state); - for (uint8_t j = 0; j < spi_speed + (miso_pin >= 0 ? 0 : 1); j++) + LOOP_L_N(j, spi_speed + (miso_pin >= 0 ? 0 : 1)) LPC176x::gpio_set(sck_pin, HIGH); b <<= 1; if (miso_pin >= 0 && LPC176x::gpio_get(miso_pin)) b |= 1; - for (uint8_t j = 0; j < spi_speed; j++) + LOOP_L_N(j, spi_speed) LPC176x::gpio_set(sck_pin, LOW); } } @@ -102,7 +102,7 @@ uint8_t swSpiTransfer_mode_0(uint8_t b, const uint8_t spi_speed, const pin_t sck uint8_t swSpiTransfer_mode_3(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin ) { - for (uint8_t i = 0; i < 8; i++) { + LOOP_L_N(i, 8) { const uint8_t state = (b & 0x80) ? HIGH : LOW; if (spi_speed == 0) { LPC176x::gpio_set(sck_pin, LOW); @@ -111,13 +111,13 @@ uint8_t swSpiTransfer_mode_3(uint8_t b, const uint8_t spi_speed, const pin_t sck LPC176x::gpio_set(sck_pin, HIGH); } else { - for (uint8_t j = 0; j < spi_speed + (miso_pin >= 0 ? 0 : 1); j++) + LOOP_L_N(j, spi_speed + (miso_pin >= 0 ? 0 : 1)) LPC176x::gpio_set(sck_pin, LOW); - for (uint8_t j = 0; j < spi_speed; j++) + LOOP_L_N(j, spi_speed) LPC176x::gpio_set(mosi_pin, state); - for (uint8_t j = 0; j < spi_speed; j++) + LOOP_L_N(j, spi_speed) LPC176x::gpio_set(sck_pin, HIGH); } b <<= 1; @@ -203,5 +203,5 @@ uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, return 1; } -#endif // HAS_GRAPHICAL_LCD && !U8GLIB_ST7920 +#endif // HAS_MARLINUI_U8GLIB && !U8GLIB_ST7920 #endif // TARGET_LPC1768 diff --git a/Marlin/src/HAL/HAL_LPC1768/upload_extra_script.py b/Marlin/src/HAL/LPC1768/upload_extra_script.py similarity index 100% rename from Marlin/src/HAL/HAL_LPC1768/upload_extra_script.py rename to Marlin/src/HAL/LPC1768/upload_extra_script.py diff --git a/Marlin/src/HAL/HAL_LPC1768/usb_serial.cpp b/Marlin/src/HAL/LPC1768/usb_serial.cpp similarity index 90% rename from Marlin/src/HAL/HAL_LPC1768/usb_serial.cpp rename to Marlin/src/HAL/LPC1768/usb_serial.cpp index 0af2d8347bb0..d225ce418860 100644 --- a/Marlin/src/HAL/HAL_LPC1768/usb_serial.cpp +++ b/Marlin/src/HAL/LPC1768/usb_serial.cpp @@ -16,18 +16,19 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef TARGET_LPC1768 #include "../../inc/MarlinConfigPre.h" #if ENABLED(EMERGENCY_PARSER) -#include "../../feature/emergency_parser.h" +#include "../../feature/e_parser.h" + EmergencyParser::State emergency_state; + bool CDC_RecvCallback(const char buffer) { emergency_parser.update(emergency_state, buffer); return true; diff --git a/Marlin/src/HAL/HAL_LPC1768/watchdog.cpp b/Marlin/src/HAL/LPC1768/watchdog.cpp similarity index 96% rename from Marlin/src/HAL/HAL_LPC1768/watchdog.cpp rename to Marlin/src/HAL/LPC1768/watchdog.cpp index 73563a6baa13..3cd22d665168 100644 --- a/Marlin/src/HAL/HAL_LPC1768/watchdog.cpp +++ b/Marlin/src/HAL/LPC1768/watchdog.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef TARGET_LPC1768 #include "../../inc/MarlinConfig.h" diff --git a/Marlin/src/HAL/HAL_LPC1768/watchdog.h b/Marlin/src/HAL/LPC1768/watchdog.h similarity index 92% rename from Marlin/src/HAL/HAL_LPC1768/watchdog.h rename to Marlin/src/HAL/LPC1768/watchdog.h index e9e25e4f2af8..cc170881f375 100644 --- a/Marlin/src/HAL/HAL_LPC1768/watchdog.h +++ b/Marlin/src/HAL/LPC1768/watchdog.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_LPC1768/win_usb_driver/lpc176x_usb_driver.inf b/Marlin/src/HAL/LPC1768/win_usb_driver/lpc176x_usb_driver.inf similarity index 100% rename from Marlin/src/HAL/HAL_LPC1768/win_usb_driver/lpc176x_usb_driver.inf rename to Marlin/src/HAL/LPC1768/win_usb_driver/lpc176x_usb_driver.inf diff --git a/Marlin/src/HAL/HAL_SAMD51/HAL.cpp b/Marlin/src/HAL/SAMD51/HAL.cpp similarity index 85% rename from Marlin/src/HAL/HAL_SAMD51/HAL.cpp rename to Marlin/src/HAL/SAMD51/HAL.cpp index 4828c40ff705..9f24d30071a6 100644 --- a/Marlin/src/HAL/HAL_SAMD51/HAL.cpp +++ b/Marlin/src/HAL/SAMD51/HAL.cpp @@ -15,10 +15,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef __SAMD51__ #include "../../inc/MarlinConfig.h" @@ -29,71 +28,19 @@ // Local defines // ------------------------ -#if HAS_TEMP_ADC_0 - #define GET_TEMP_0_ADC() PIN_TO_ADC(TEMP_0_PIN) -#else - #define GET_TEMP_0_ADC() -1 -#endif -#if HAS_TEMP_ADC_1 - #define GET_TEMP_1_ADC() PIN_TO_ADC(TEMP_1_PIN) -#else - #define GET_TEMP_1_ADC() -1 -#endif -#if HAS_TEMP_ADC_2 - #define GET_TEMP_2_ADC() PIN_TO_ADC(TEMP_2_PIN) -#else - #define GET_TEMP_2_ADC() -1 -#endif -#if HAS_TEMP_ADC_3 - #define GET_TEMP_3_ADC() PIN_TO_ADC(TEMP_3_PIN) -#else - #define GET_TEMP_3_ADC() -1 -#endif -#if HAS_TEMP_ADC_4 - #define GET_TEMP_4_ADC() PIN_TO_ADC(TEMP_4_PIN) -#else - #define GET_TEMP_4_ADC() -1 -#endif -#if HAS_TEMP_ADC_5 - #define GET_TEMP_5_ADC() PIN_TO_ADC(TEMP_5_PIN) -#else - #define GET_TEMP_5_ADC() -1 -#endif -#if HAS_TEMP_ADC_6 - #define GET_TEMP_6_ADC() PIN_TO_ADC(TEMP_6_PIN) -#else - #define GET_TEMP_6_ADC() -1 -#endif -#if HAS_TEMP_ADC_7 - #define GET_TEMP_7_ADC() PIN_TO_ADC(TEMP_7_PIN) -#else - #define GET_TEMP_7_ADC() -1 -#endif -#if HAS_TEMP_PROBE - #define GET_PROBE_ADC() PIN_TO_ADC(TEMP_PROBE_PIN) -#else - #define GET_PROBE_ADC() -1 -#endif -#if HAS_TEMP_ADC_BED - #define GET_BED_ADC() PIN_TO_ADC(TEMP_BED_PIN) -#else - #define GET_BED_ADC() -1 -#endif -#if HAS_TEMP_ADC_CHAMBER - #define GET_CHAMBER_ADC() PIN_TO_ADC(TEMP_CHAMBER_PIN) -#else - #define GET_CHAMBER_ADC() -1 -#endif -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define GET_FILAMENT_WIDTH_ADC() PIN_TO_ADC(FILWIDTH_PIN) -#else - #define GET_FILAMENT_WIDTH_ADC() -1 -#endif -#if HAS_ADC_BUTTONS - #define GET_BUTTONS_ADC() PIN_TO_ADC(ADC_KEYPAD_PIN) -#else - #define GET_BUTTONS_ADC() -1 -#endif +#define GET_TEMP_0_ADC() TERN(HAS_TEMP_ADC_0, PIN_TO_ADC(TEMP_0_PIN), -1) +#define GET_TEMP_1_ADC() TERN(HAS_TEMP_ADC_1, PIN_TO_ADC(TEMP_1_PIN), -1) +#define GET_TEMP_2_ADC() TERN(HAS_TEMP_ADC_2, PIN_TO_ADC(TEMP_2_PIN), -1) +#define GET_TEMP_3_ADC() TERN(HAS_TEMP_ADC_3, PIN_TO_ADC(TEMP_3_PIN), -1) +#define GET_TEMP_4_ADC() TERN(HAS_TEMP_ADC_4, PIN_TO_ADC(TEMP_4_PIN), -1) +#define GET_TEMP_5_ADC() TERN(HAS_TEMP_ADC_5, PIN_TO_ADC(TEMP_5_PIN), -1) +#define GET_TEMP_6_ADC() TERN(HAS_TEMP_ADC_6, PIN_TO_ADC(TEMP_6_PIN), -1) +#define GET_TEMP_7_ADC() TERN(HAS_TEMP_ADC_7, PIN_TO_ADC(TEMP_7_PIN), -1) +#define GET_PROBE_ADC() TERN(HAS_TEMP_PROBE, PIN_TO_ADC(TEMP_PROBE_PIN), -1) +#define GET_BED_ADC() TERN(HAS_TEMP_ADC_BED, PIN_TO_ADC(TEMP_BED_PIN), -1) +#define GET_CHAMBER_ADC() TERN(HAS_TEMP_ADC_CHAMBER, PIN_TO_ADC(TEMP_CHAMBER_PIN), -1) +#define GET_FILAMENT_WIDTH_ADC() TERN(FILAMENT_WIDTH_SENSOR, PIN_TO_ADC(FILWIDTH_PIN), -1) +#define GET_BUTTONS_ADC() TERN(HAS_ADC_BUTTONS, PIN_TO_ADC(ADC_KEYPAD_PIN), -1) #define IS_ADC_REQUIRED(n) ( \ GET_TEMP_0_ADC() == n || GET_TEMP_1_ADC() == n || GET_TEMP_2_ADC() == n || GET_TEMP_3_ADC() == n \ @@ -105,21 +52,22 @@ || GET_BUTTONS_ADC() == n \ ) -#define ADC0_IS_REQUIRED IS_ADC_REQUIRED(0) -#define ADC1_IS_REQUIRED IS_ADC_REQUIRED(1) -#define ADC_IS_REQUIRED (ADC0_IS_REQUIRED || ADC1_IS_REQUIRED) -#if ADC0_IS_REQUIRED +#if IS_ADC_REQUIRED(0) + #define ADC0_IS_REQUIRED 1 #define FIRST_ADC 0 #else #define FIRST_ADC 1 #endif -#if ADC1_IS_REQUIRED +#if IS_ADC_REQUIRED(1) + #define ADC1_IS_REQUIRED 1 #define LAST_ADC 1 #else #define LAST_ADC 0 #endif - -#define DMA_IS_REQUIRED ADC_IS_REQUIRED +#if ADC0_IS_REQUIRED || ADC1_IS_REQUIRED + #define ADC_IS_REQUIRED 1 + #define DMA_IS_REQUIRED 1 +#endif // ------------------------ // Types @@ -423,9 +371,7 @@ uint16_t HAL_adc_result; // HAL initialization task void HAL_init() { - #if DMA_IS_REQUIRED - dma_init(); - #endif + TERN_(DMA_IS_REQUIRED, dma_init()); #if ENABLED(SDSUPPORT) #if SD_CONNECTION_IS(ONBOARD) && PIN_EXISTS(SD_DETECT) SET_INPUT_PULLUP(SD_DETECT_PIN); @@ -478,10 +424,10 @@ void HAL_adc_init() { #if ADC_IS_REQUIRED memset(HAL_adc_results, 0xFF, sizeof(HAL_adc_results)); // Fill result with invalid values - for (uint8_t pi = 0; pi < COUNT(adc_pins); ++pi) + LOOP_L_N(pi, COUNT(adc_pins)) pinPeripheral(adc_pins[pi], PIO_ANALOG); - for (uint8_t ai = FIRST_ADC; ai <= LAST_ADC; ++ai) { + LOOP_S_LE_N(ai, FIRST_ADC, LAST_ADC) { Adc* adc = ((Adc*[])ADC_INSTS)[ai]; // ADC clock setup @@ -513,7 +459,7 @@ void HAL_adc_init() { void HAL_adc_start_conversion(const uint8_t adc_pin) { #if ADC_IS_REQUIRED - for (uint8_t pi = 0; pi < COUNT(adc_pins); ++pi) { + LOOP_L_N(pi, COUNT(adc_pins)) { if (adc_pin == adc_pins[pi]) { HAL_adc_result = HAL_adc_results[pi]; return; diff --git a/Marlin/src/HAL/HAL_SAMD51/HAL.h b/Marlin/src/HAL/SAMD51/HAL.h similarity index 65% rename from Marlin/src/HAL/HAL_SAMD51/HAL.h rename to Marlin/src/HAL/SAMD51/HAL.h index f2ee02a22fcc..7cb3635bd7c9 100644 --- a/Marlin/src/HAL/HAL_SAMD51/HAL.h +++ b/Marlin/src/HAL/SAMD51/HAL.h @@ -15,7 +15,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -27,7 +27,6 @@ #include "../shared/HAL_SPI.h" #include "fastio.h" #include "watchdog.h" -#include "timers.h" #ifdef ADAFRUIT_GRAND_CENTRAL_M4 #include "MarlinSerial_AGCM4.h" @@ -36,58 +35,35 @@ // MYSERIAL0 required before MarlinSerial includes! + #define __MSERIAL(X) Serial##X + #define _MSERIAL(X) __MSERIAL(X) + #define MSERIAL(X) _MSERIAL(INCREMENT(X)) + #if SERIAL_PORT == -1 #define MYSERIAL0 Serial - #elif SERIAL_PORT == 0 - #define MYSERIAL0 Serial1 - #elif SERIAL_PORT == 1 - #define MYSERIAL0 Serial2 - #elif SERIAL_PORT == 2 - #define MYSERIAL0 Serial3 - #elif SERIAL_PORT == 3 - #define MYSERIAL0 Serial4 + #elif WITHIN(SERIAL_PORT, 0, 3) + #define MYSERIAL0 MSERIAL(SERIAL_PORT) #else #error "SERIAL_PORT must be from -1 to 3. Please update your configuration." #endif #ifdef SERIAL_PORT_2 - #if SERIAL_PORT_2 == SERIAL_PORT - #error "SERIAL_PORT_2 must be different than SERIAL_PORT. Please update your configuration." - #elif SERIAL_PORT_2 == -1 + #if SERIAL_PORT_2 == -1 #define MYSERIAL1 Serial - #elif SERIAL_PORT_2 == 0 - #define MYSERIAL1 Serial1 - #elif SERIAL_PORT_2 == 1 - #define MYSERIAL1 Serial2 - #elif SERIAL_PORT_2 == 2 - #define MYSERIAL1 Serial3 - #elif SERIAL_PORT_2 == 3 - #define MYSERIAL1 Serial4 + #elif WITHIN(SERIAL_PORT_2, 0, 3) + #define MYSERIAL1 MSERIAL(SERIAL_PORT_2) #else #error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration." #endif - #define NUM_SERIAL 2 - #else - #define NUM_SERIAL 1 #endif - #ifdef DGUS_SERIAL_PORT - #if DGUS_SERIAL_PORT == SERIAL_PORT - #error "DGUS_SERIAL_PORT must be different than SERIAL_PORT. Please update your configuration." - #elif defined(SERIAL_PORT_2) && DGUS_SERIAL_PORT == SERIAL_PORT_2 - #error "DGUS_SERIAL_PORT must be different than SERIAL_PORT_2. Please update your configuration." - #elif DGUS_SERIAL_PORT == -1 - #define DGUS_SERIAL Serial - #elif DGUS_SERIAL_PORT == 0 - #define DGUS_SERIAL Serial1 - #elif DGUS_SERIAL_PORT == 1 - #define DGUS_SERIAL Serial2 - #elif DGUS_SERIAL_PORT == 2 - #define DGUS_SERIAL Serial3 - #elif DGUS_SERIAL_PORT == 2 - #define DGUS_SERIAL Serial4 + #ifdef LCD_SERIAL_PORT + #if LCD_SERIAL_PORT == -1 + #define LCD_SERIAL Serial + #elif WITHIN(LCD_SERIAL_PORT, 0, 3) + #define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT) #else - #error "DGUS_SERIAL_PORT must be from -1 to 3. Please update your configuration." + #error "LCD_SERIAL_PORT must be from -1 to 3. Please update your configuration." #endif #endif @@ -113,11 +89,7 @@ typedef int8_t pin_t; void HAL_clear_reset_source(); // clear reset reason uint8_t HAL_get_reset_source(); // get reset reason -// -// EEPROM -// -void eeprom_write_byte(uint8_t *pos, unsigned char value); -uint8_t eeprom_read_byte(uint8_t *pos); +inline void HAL_reboot() {} // reboot the board or restart the bootloader // // ADC @@ -129,13 +101,13 @@ extern uint16_t HAL_adc_result; // Most recent ADC conversion void HAL_adc_init(); //#define HAL_ADC_FILTERED // Disable Marlin's oversampling. The HAL filters ADC values. +#define HAL_ADC_VREF 3.3 #define HAL_ADC_RESOLUTION 10 // ... 12 #define HAL_START_ADC(pin) HAL_adc_start_conversion(pin) #define HAL_READ_ADC() HAL_adc_result #define HAL_ADC_READY() true void HAL_adc_start_conversion(const uint8_t adc_pin); -inline uint16_t HAL_adc_get_result() { return HAL_adc_result; } // // Pin Map diff --git a/Marlin/src/HAL/HAL_SAMD51/HAL_SPI.cpp b/Marlin/src/HAL/SAMD51/HAL_SPI.cpp similarity index 98% rename from Marlin/src/HAL/HAL_SAMD51/HAL_SPI.cpp rename to Marlin/src/HAL/SAMD51/HAL_SPI.cpp index 83226daa481b..c3acd38237c6 100644 --- a/Marlin/src/HAL/HAL_SAMD51/HAL_SPI.cpp +++ b/Marlin/src/HAL/SAMD51/HAL_SPI.cpp @@ -15,7 +15,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/HAL/HAL_SAMD51/MarlinSerial_AGCM4.cpp b/Marlin/src/HAL/SAMD51/MarlinSerial_AGCM4.cpp similarity index 96% rename from Marlin/src/HAL/HAL_SAMD51/MarlinSerial_AGCM4.cpp rename to Marlin/src/HAL/SAMD51/MarlinSerial_AGCM4.cpp index f13b29555af7..abc5f3acbf77 100644 --- a/Marlin/src/HAL/HAL_SAMD51/MarlinSerial_AGCM4.cpp +++ b/Marlin/src/HAL/SAMD51/MarlinSerial_AGCM4.cpp @@ -15,10 +15,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef ADAFRUIT_GRAND_CENTRAL_M4 /** diff --git a/Marlin/src/HAL/HAL_SAMD51/MarlinSerial_AGCM4.h b/Marlin/src/HAL/SAMD51/MarlinSerial_AGCM4.h similarity index 91% rename from Marlin/src/HAL/HAL_SAMD51/MarlinSerial_AGCM4.h rename to Marlin/src/HAL/SAMD51/MarlinSerial_AGCM4.h index a9eb0470a24f..f3821d8d5a84 100644 --- a/Marlin/src/HAL/HAL_SAMD51/MarlinSerial_AGCM4.h +++ b/Marlin/src/HAL/SAMD51/MarlinSerial_AGCM4.h @@ -15,7 +15,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/SAMD51/QSPIFlash.cpp b/Marlin/src/HAL/SAMD51/QSPIFlash.cpp new file mode 100644 index 000000000000..307eb3fd45f2 --- /dev/null +++ b/Marlin/src/HAL/SAMD51/QSPIFlash.cpp @@ -0,0 +1,78 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(QSPI_EEPROM) + +#include "QSPIFlash.h" + +#define INVALID_ADDR 0xFFFFFFFF +#define SECTOR_OF(a) (a & ~(SFLASH_SECTOR_SIZE - 1)) +#define OFFSET_OF(a) (a & (SFLASH_SECTOR_SIZE - 1)) + +Adafruit_SPIFlashBase * QSPIFlash::_flashBase = nullptr; +uint8_t QSPIFlash::_buf[SFLASH_SECTOR_SIZE]; +uint32_t QSPIFlash::_addr = INVALID_ADDR; + +void QSPIFlash::begin() { + if (_flashBase != nullptr) return; + + _flashBase = new Adafruit_SPIFlashBase(new Adafruit_FlashTransport_QSPI()); + _flashBase->begin(NULL); +} + +size_t QSPIFlash::size() { + return _flashBase->size(); +} + +uint8_t QSPIFlash::readByte(const uint32_t address) { + if (SECTOR_OF(address) == _addr) return _buf[OFFSET_OF(address)]; + + return _flashBase->read8(address); +} + +void QSPIFlash::writeByte(const uint32_t address, const uint8_t value) { + uint32_t const sector_addr = SECTOR_OF(address); + + // Page changes, flush old and update new cache + if (sector_addr != _addr) { + flush(); + _addr = sector_addr; + + // read a whole page from flash + _flashBase->readBuffer(sector_addr, _buf, SFLASH_SECTOR_SIZE); + } + + _buf[OFFSET_OF(address)] = value; +} + +void QSPIFlash::flush() { + if (_addr == INVALID_ADDR) return; + + _flashBase->eraseSector(_addr / SFLASH_SECTOR_SIZE); + _flashBase->writeBuffer(_addr, _buf, SFLASH_SECTOR_SIZE); + + _addr = INVALID_ADDR; +} + +#endif // QSPI_EEPROM diff --git a/Marlin/src/HAL/SAMD51/QSPIFlash.h b/Marlin/src/HAL/SAMD51/QSPIFlash.h new file mode 100644 index 000000000000..db4abec91caf --- /dev/null +++ b/Marlin/src/HAL/SAMD51/QSPIFlash.h @@ -0,0 +1,50 @@ +/** + * @file QSPIFlash.h + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach and Dean Miller for Adafruit Industries LLC + * + * 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. + * + * Derived from Adafruit_SPIFlash class with no SdFat references + */ + +#pragma once + +#include + +// This class extends Adafruit_SPIFlashBase by adding caching support. +// +// This class will use 4096 Bytes of RAM as a block cache. +class QSPIFlash { + public: + static void begin(); + static size_t size(); + static uint8_t readByte(const uint32_t address); + static void writeByte(const uint32_t address, const uint8_t v); + static void flush(); + + private: + static Adafruit_SPIFlashBase * _flashBase; + static uint8_t _buf[SFLASH_SECTOR_SIZE]; + static uint32_t _addr; +}; + +extern QSPIFlash qspi; diff --git a/Marlin/src/HAL/HAL_SAMD51/SAMD51.h b/Marlin/src/HAL/SAMD51/SAMD51.h similarity index 98% rename from Marlin/src/HAL/HAL_SAMD51/SAMD51.h rename to Marlin/src/HAL/SAMD51/SAMD51.h index ef84a2082019..783956140d58 100644 --- a/Marlin/src/HAL/HAL_SAMD51/SAMD51.h +++ b/Marlin/src/HAL/SAMD51/SAMD51.h @@ -15,7 +15,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_SAMD51/Servo.cpp b/Marlin/src/HAL/SAMD51/Servo.cpp similarity index 95% rename from Marlin/src/HAL/HAL_SAMD51/Servo.cpp rename to Marlin/src/HAL/SAMD51/Servo.cpp index b39869ef324c..9bab8e89be23 100644 --- a/Marlin/src/HAL/HAL_SAMD51/Servo.cpp +++ b/Marlin/src/HAL/SAMD51/Servo.cpp @@ -15,7 +15,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -29,11 +29,9 @@ #if HAS_SERVOS -#include "../shared/Marduino.h" #include "../shared/servo.h" #include "../shared/servo_private.h" #include "SAMD51.h" -#include "timers.h" #define __TC_GCLK_ID(t) TC##t##_GCLK_ID #define _TC_GCLK_ID(t) __TC_GCLK_ID(t) @@ -55,7 +53,7 @@ static volatile int8_t currentServoIndex[_Nbr_16timers]; // index for the servo being pulsed for each timer (or -1 if refresh interval) FORCE_INLINE static uint16_t getTimerCount() { - Tc * const tc = TimerConfig[SERVO_TC].pTimer; + Tc * const tc = TimerConfig[SERVO_TC].pTc; tc->COUNT16.CTRLBSET.reg = TC_CTRLBCLR_CMD_READSYNC; SYNC(tc->COUNT16.SYNCBUSY.bit.CTRLB || tc->COUNT16.SYNCBUSY.bit.COUNT); @@ -67,7 +65,7 @@ FORCE_INLINE static uint16_t getTimerCount() { // Interrupt handler for the TC // ---------------------------- HAL_SERVO_TIMER_ISR() { - Tc * const tc = TimerConfig[SERVO_TC].pTimer; + Tc * const tc = TimerConfig[SERVO_TC].pTc; const timer16_Sequence_t timer = #ifndef _useTimer1 _timer2 @@ -127,7 +125,7 @@ HAL_SERVO_TIMER_ISR() { } void initISR(timer16_Sequence_t timer) { - Tc * const tc = TimerConfig[SERVO_TC].pTimer; + Tc * const tc = TimerConfig[SERVO_TC].pTc; const uint8_t tcChannel = TIMER_TCCHANNEL(timer); static bool initialized = false; // Servo TC has been initialized @@ -204,7 +202,7 @@ void initISR(timer16_Sequence_t timer) { } void finISR(timer16_Sequence_t timer) { - Tc * const tc = TimerConfig[SERVO_TC].pTimer; + Tc * const tc = TimerConfig[SERVO_TC].pTc; const uint8_t tcChannel = TIMER_TCCHANNEL(timer); // Disable the match channel interrupt request diff --git a/Marlin/src/HAL/HAL_SAMD51/ServoTimers.h b/Marlin/src/HAL/SAMD51/ServoTimers.h similarity index 94% rename from Marlin/src/HAL/HAL_SAMD51/ServoTimers.h rename to Marlin/src/HAL/SAMD51/ServoTimers.h index 3572c608d26d..948d515356fb 100644 --- a/Marlin/src/HAL/HAL_SAMD51/ServoTimers.h +++ b/Marlin/src/HAL/SAMD51/ServoTimers.h @@ -15,7 +15,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/SAMD51/eeprom_flash.cpp b/Marlin/src/HAL/SAMD51/eeprom_flash.cpp new file mode 100644 index 000000000000..429ef1c2d4f7 --- /dev/null +++ b/Marlin/src/HAL/SAMD51/eeprom_flash.cpp @@ -0,0 +1,95 @@ +/** + * Marlin 3D Printer Firmware + * + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) + * + * 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 . + * + */ +#ifdef __SAMD51__ + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(FLASH_EEPROM_EMULATION) + +#include "../shared/eeprom_api.h" + +#define NVMCTRL_CMD(c) do{ \ + SYNC(!NVMCTRL->STATUS.bit.READY); \ + NVMCTRL->INTFLAG.bit.DONE = true; \ + NVMCTRL->CTRLB.reg = c | NVMCTRL_CTRLB_CMDEX_KEY; \ + SYNC(NVMCTRL->INTFLAG.bit.DONE); \ + }while(0) +#define NVMCTRL_FLUSH() do{ \ + if (NVMCTRL->SEESTAT.bit.LOAD) \ + NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_SEEFLUSH); \ + }while(0) + +size_t PersistentStore::capacity() { + const uint8_t psz = NVMCTRL->SEESTAT.bit.PSZ, + sblk = NVMCTRL->SEESTAT.bit.SBLK; + + return (!psz && !sblk) ? 0 + : (psz <= 2) ? (0x200 << psz) + : (sblk == 1 || psz == 3) ? 4096 + : (sblk == 2 || psz == 4) ? 8192 + : (sblk <= 4 || psz == 5) ? 16384 + : (sblk >= 9 && psz == 7) ? 65536 + : 32768; +} + +bool PersistentStore::access_start() { + NVMCTRL->SEECFG.reg = NVMCTRL_SEECFG_WMODE_BUFFERED; // Buffered mode and segment reallocation active + if (NVMCTRL->SEESTAT.bit.RLOCK) + NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_USEE); // Unlock E2P data write access + return true; +} + +bool PersistentStore::access_finish() { + NVMCTRL_FLUSH(); + if (!NVMCTRL->SEESTAT.bit.LOCK) + NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_LSEE); // Lock E2P data write access + return true; +} + +bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { + while (size--) { + const uint8_t v = *value; + SYNC(NVMCTRL->SEESTAT.bit.BUSY); + if (NVMCTRL->INTFLAG.bit.SEESFULL) + NVMCTRL_FLUSH(); // Next write will trigger a sector reallocation. I need to flush 'pagebuffer' + ((volatile uint8_t *)SEEPROM_ADDR)[pos] = v; + SYNC(!NVMCTRL->INTFLAG.bit.SEEWRC); + crc16(crc, &v, 1); + pos++; + value++; + } + return false; +} + +bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) { + while (size--) { + SYNC(NVMCTRL->SEESTAT.bit.BUSY); + uint8_t c = ((volatile uint8_t *)SEEPROM_ADDR)[pos]; + if (writing) *value = c; + crc16(crc, &c, 1); + pos++; + value++; + } + return false; +} + +#endif // FLASH_EEPROM_EMULATION +#endif // __SAMD51__ diff --git a/Marlin/src/HAL/SAMD51/eeprom_qspi.cpp b/Marlin/src/HAL/SAMD51/eeprom_qspi.cpp new file mode 100644 index 000000000000..b403f7939fb9 --- /dev/null +++ b/Marlin/src/HAL/SAMD51/eeprom_qspi.cpp @@ -0,0 +1,71 @@ +/** + * Marlin 3D Printer Firmware + * + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) + * + * 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 . + * + */ +#ifdef __SAMD51__ + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(QSPI_EEPROM) + +#include "../shared/eeprom_api.h" + +#include "QSPIFlash.h" + +static bool initialized; + +size_t PersistentStore::capacity() { return qspi.size(); } + +bool PersistentStore::access_start() { + if (!initialized) { + qspi.begin(); + initialized = true; + } + return true; +} + +bool PersistentStore::access_finish() { + qspi.flush(); + return true; +} + +bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { + while (size--) { + const uint8_t v = *value; + qspi.writeByte(pos, v); + crc16(crc, &v, 1); + pos++; + value++; + } + return false; +} + +bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) { + while (size--) { + uint8_t c = qspi.readByte(pos); + if (writing) *value = c; + crc16(crc, &c, 1); + pos++; + value++; + } + return false; +} + +#endif // QSPI_EEPROM +#endif // __SAMD51__ diff --git a/Marlin/src/HAL/SAMD51/eeprom_wired.cpp b/Marlin/src/HAL/SAMD51/eeprom_wired.cpp new file mode 100644 index 000000000000..3283195897b0 --- /dev/null +++ b/Marlin/src/HAL/SAMD51/eeprom_wired.cpp @@ -0,0 +1,74 @@ +/** + * Marlin 3D Printer Firmware + * + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) + * + * 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 . + * + */ +#ifdef __SAMD51__ + +#include "../../inc/MarlinConfig.h" + +#if USE_WIRED_EEPROM + +/** + * PersistentStore for Arduino-style EEPROM interface + * with simple implementations supplied by Marlin. + */ + +#include "../shared/eeprom_if.h" +#include "../shared/eeprom_api.h" + +#ifndef MARLIN_EEPROM_SIZE + #error "MARLIN_EEPROM_SIZE is required for I2C / SPI EEPROM." +#endif +size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } + +bool PersistentStore::access_start() { eeprom_init(); return true; } +bool PersistentStore::access_finish() { return true; } + +bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { + while (size--) { + const uint8_t v = *value; + uint8_t * const p = (uint8_t * const)pos; + if (v != eeprom_read_byte(p)) { + eeprom_write_byte(p, v); + delay(2); + if (eeprom_read_byte(p) != v) { + SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE); + return true; + } + } + crc16(crc, &v, 1); + pos++; + value++; + } + return false; +} + +bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) { + while (size--) { + uint8_t c = eeprom_read_byte((uint8_t*)pos); + if (writing) *value = c; + crc16(crc, &c, 1); + pos++; + value++; + } + return false; +} + +#endif // USE_WIRED_EEPROM +#endif // __SAMD51__ diff --git a/Marlin/src/HAL/HAL_SAMD51/endstop_interrupts.h b/Marlin/src/HAL/SAMD51/endstop_interrupts.h similarity index 88% rename from Marlin/src/HAL/HAL_SAMD51/endstop_interrupts.h rename to Marlin/src/HAL/SAMD51/endstop_interrupts.h index 4c8f441ce22f..daac7733875b 100644 --- a/Marlin/src/HAL/HAL_SAMD51/endstop_interrupts.h +++ b/Marlin/src/HAL/SAMD51/endstop_interrupts.h @@ -15,7 +15,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -126,82 +126,83 @@ void endstop_ISR() { endstops.update(); } void setup_endstop_interrupts() { + #define _ATTACH(P) attachInterrupt(P, endstop_ISR, CHANGE) #if HAS_X_MAX #if !AVAILABLE_EILINE(X_MAX_PIN) #error "X_MAX_PIN has no EXTINT line available." #endif - attachInterrupt(X_MAX_PIN, endstop_ISR, CHANGE); + _ATTACH(X_MAX_PIN); #endif #if HAS_X_MIN #if !AVAILABLE_EILINE(X_MIN_PIN) #error "X_MIN_PIN has no EXTINT line available." #endif - attachInterrupt(X_MIN_PIN, endstop_ISR, CHANGE); + _ATTACH(X_MIN_PIN); #endif #if HAS_Y_MAX #if !AVAILABLE_EILINE(Y_MAX_PIN) #error "Y_MAX_PIN has no EXTINT line available." #endif - attachInterrupt(Y_MAX_PIN, endstop_ISR, CHANGE); + _ATTACH(Y_MAX_PIN); #endif #if HAS_Y_MIN #if !AVAILABLE_EILINE(Y_MIN_PIN) #error "Y_MIN_PIN has no EXTINT line available." #endif - attachInterrupt(Y_MIN_PIN, endstop_ISR, CHANGE); + _ATTACH(Y_MIN_PIN); #endif #if HAS_Z_MAX #if !AVAILABLE_EILINE(Z_MAX_PIN) #error "Z_MAX_PIN has no EXTINT line available." #endif - attachInterrupt(Z_MAX_PIN, endstop_ISR, CHANGE); + _ATTACH(Z_MAX_PIN); #endif #if HAS_Z_MIN #if !AVAILABLE_EILINE(Z_MIN_PIN) #error "Z_MIN_PIN has no EXTINT line available." #endif - attachInterrupt(Z_MIN_PIN, endstop_ISR, CHANGE); + _ATTACH(Z_MIN_PIN); #endif #if HAS_Z2_MAX #if !AVAILABLE_EILINE(Z2_MAX_PIN) #error "Z2_MAX_PIN has no EXTINT line available." #endif - attachInterrupt(Z2_MAX_PIN, endstop_ISR, CHANGE); + _ATTACH(Z2_MAX_PIN); #endif #if HAS_Z2_MIN #if !AVAILABLE_EILINE(Z2_MIN_PIN) #error "Z2_MIN_PIN has no EXTINT line available." #endif - attachInterrupt(Z2_MIN_PIN, endstop_ISR, CHANGE); + _ATTACH(Z2_MIN_PIN); #endif #if HAS_Z3_MAX #if !AVAILABLE_EILINE(Z3_MAX_PIN) #error "Z3_MAX_PIN has no EXTINT line available." #endif - attachInterrupt(Z3_MAX_PIN, endstop_ISR, CHANGE); + _ATTACH(Z3_MAX_PIN); #endif #if HAS_Z3_MIN #if !AVAILABLE_EILINE(Z3_MIN_PIN) #error "Z3_MIN_PIN has no EXTINT line available." #endif - attachInterrupt(Z3_MIN_PIN, endstop_ISR, CHANGE); + _ATTACH(Z3_MIN_PIN); #endif #if HAS_Z4_MAX #if !AVAILABLE_EILINE(Z4_MAX_PIN) #error "Z4_MAX_PIN has no EXTINT line available." #endif - attachInterrupt(Z4_MAX_PIN, endstop_ISR, CHANGE); + _ATTACH(Z4_MAX_PIN); #endif #if HAS_Z4_MIN #if !AVAILABLE_EILINE(Z4_MIN_PIN) #error "Z4_MIN_PIN has no EXTINT line available." #endif - attachInterrupt(Z4_MIN_PIN, endstop_ISR, CHANGE); + _ATTACH(Z4_MIN_PIN); #endif #if HAS_Z_MIN_PROBE_PIN #if !AVAILABLE_EILINE(Z_MIN_PROBE_PIN) #error "Z_MIN_PROBE_PIN has no EXTINT line available." #endif - attachInterrupt(Z_MIN_PROBE_PIN, endstop_ISR, CHANGE); + _ATTACH(Z_MIN_PROBE_PIN); #endif } diff --git a/Marlin/src/HAL/HAL_SAMD51/fastio.h b/Marlin/src/HAL/SAMD51/fastio.h similarity index 98% rename from Marlin/src/HAL/HAL_SAMD51/fastio.h rename to Marlin/src/HAL/SAMD51/fastio.h index e00fa77a7c1f..c456dfce30cb 100644 --- a/Marlin/src/HAL/HAL_SAMD51/fastio.h +++ b/Marlin/src/HAL/SAMD51/fastio.h @@ -15,7 +15,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -37,7 +37,7 @@ /** * Magic I/O routines * - * Now you can simply SET_OUTPUT(STEP); WRITE(STEP, HIGH); WRITE(STEP, LOW); + * Now you can simply SET_OUTPUT(IO); WRITE(IO, HIGH); WRITE(IO, LOW); */ // Read a pin @@ -100,9 +100,9 @@ PORT->Group[port].DIRCLR.reg = MASK(pin); \ }while(0) // Set pin as PWM (push pull) -#define SET_PWM(IO) SET_OUTPUT(IO) +#define SET_PWM SET_OUTPUT // Set pin as PWM (open drain) -#define SET_PWM_OD(IO) SET_OUTPUT_OD(IO) +#define SET_PWM_OD SET_OUTPUT_OD // check if pin is an output #define IS_OUTPUT(IO) ((PORT->Group[(EPortType)GET_SAMD_PORT(IO)].DIR.reg & MASK(GET_SAMD_PIN(IO))) \ diff --git a/Marlin/src/HAL/SAMD51/inc/Conditionals_LCD.h b/Marlin/src/HAL/SAMD51/inc/Conditionals_LCD.h new file mode 100644 index 000000000000..932348c52f40 --- /dev/null +++ b/Marlin/src/HAL/SAMD51/inc/Conditionals_LCD.h @@ -0,0 +1,26 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if HAS_SPI_TFT || HAS_FSMC_TFT + #error "Sorry! TFT displays are not available for HAL/SAMD51." +#endif diff --git a/Marlin/src/HAL/SAMD51/inc/Conditionals_adv.h b/Marlin/src/HAL/SAMD51/inc/Conditionals_adv.h new file mode 100644 index 000000000000..5f1c4b16019d --- /dev/null +++ b/Marlin/src/HAL/SAMD51/inc/Conditionals_adv.h @@ -0,0 +1,22 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once diff --git a/Marlin/src/HAL/SAMD51/inc/Conditionals_post.h b/Marlin/src/HAL/SAMD51/inc/Conditionals_post.h new file mode 100644 index 000000000000..ce6d3fdde27f --- /dev/null +++ b/Marlin/src/HAL/SAMD51/inc/Conditionals_post.h @@ -0,0 +1,28 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if USE_FALLBACK_EEPROM + #define FLASH_EEPROM_EMULATION +#elif EITHER(I2C_EEPROM, SPI_EEPROM) + #define USE_SHARED_EEPROM 1 +#endif diff --git a/Marlin/src/HAL/HAL_SAMD51/inc/SanityCheck.h b/Marlin/src/HAL/SAMD51/inc/SanityCheck.h similarity index 81% rename from Marlin/src/HAL/HAL_SAMD51/inc/SanityCheck.h rename to Marlin/src/HAL/SAMD51/inc/SanityCheck.h index ddea64f2d01f..5d610acac85c 100644 --- a/Marlin/src/HAL/HAL_SAMD51/inc/SanityCheck.h +++ b/Marlin/src/HAL/SAMD51/inc/SanityCheck.h @@ -15,7 +15,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -23,6 +23,10 @@ * Test SAMD51 specific configuration values for errors at compile-time. */ +#if ENABLED(FLASH_EEPROM_EMULATION) + #warning "Did you activate the SmartEEPROM? See https://github.com/GMagician/SAMD51-SmartEEprom-Manager/releases" +#endif + #if defined(ADAFRUIT_GRAND_CENTRAL_M4) && SD_CONNECTION_IS(CUSTOM_CABLE) #error "No custom SD drive cable defined for this board." #endif @@ -31,6 +35,10 @@ #error "OnBoard SPI BUS can't be shared with other devices." #endif +#if SERVO_TC == RTC_TIMER_NUM + #error "Servos can't use RTC timer" +#endif + #if ENABLED(EMERGENCY_PARSER) #error "EMERGENCY_PARSER is not yet implemented for SAMD51. Disable EMERGENCY_PARSER to continue." #endif @@ -39,14 +47,6 @@ #error "SDIO_SUPPORT is not supported on SAMD51." #endif -#if ENABLED(FAST_PWM_FAN) - #error "FAST_PWM_FAN is not yet implemented for this platform." -#endif - -#if ENABLED(EEPROM_SETTINGS) && NONE(SPI_EEPROM, I2C_EEPROM) - #warning "Did you activate the SmartEEPROM? See https://github.com/GMagician/SAMD51-SmartEEprom-Manager/releases" -#endif - -#if HAS_TMC_SW_SERIAL - #error "TMC220x Software Serial is not supported on this platform." +#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY + #error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on SAMD51." #endif diff --git a/Marlin/src/HAL/HAL_SAMD51/pinsDebug.h b/Marlin/src/HAL/SAMD51/pinsDebug.h similarity index 98% rename from Marlin/src/HAL/HAL_SAMD51/pinsDebug.h rename to Marlin/src/HAL/SAMD51/pinsDebug.h index 15b647338261..81376db79add 100644 --- a/Marlin/src/HAL/HAL_SAMD51/pinsDebug.h +++ b/Marlin/src/HAL/SAMD51/pinsDebug.h @@ -15,7 +15,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -150,5 +150,4 @@ void pwm_details(int32_t pin) { * 93 | PA10 | QSPI: IO2 * 94 | PA11 | QSPI: IO3 * 95 | PB31 | SD: DETECT - * */ diff --git a/Marlin/src/HAL/HAL_SAMD51/spi_pins.h b/Marlin/src/HAL/SAMD51/spi_pins.h similarity index 94% rename from Marlin/src/HAL/HAL_SAMD51/spi_pins.h rename to Marlin/src/HAL/SAMD51/spi_pins.h index 049aacb57a94..5a9b1275ef88 100644 --- a/Marlin/src/HAL/HAL_SAMD51/spi_pins.h +++ b/Marlin/src/HAL/SAMD51/spi_pins.h @@ -15,7 +15,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_SAMD51/timers.cpp b/Marlin/src/HAL/SAMD51/timers.cpp similarity index 86% rename from Marlin/src/HAL/HAL_SAMD51/timers.cpp rename to Marlin/src/HAL/SAMD51/timers.cpp index 99839cd48a10..a68af2e074ae 100644 --- a/Marlin/src/HAL/HAL_SAMD51/timers.cpp +++ b/Marlin/src/HAL/SAMD51/timers.cpp @@ -15,17 +15,17 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef __SAMD51__ // -------------------------------------------------------------------------- // Includes // -------------------------------------------------------------------------- + #include "../../inc/MarlinConfig.h" -#include "timers.h" +#include "ServoTimers.h" // for SERVO_TC // -------------------------------------------------------------------------- // Local defines @@ -38,15 +38,15 @@ // -------------------------------------------------------------------------- const tTimerConfig TimerConfig[NUM_HARDWARE_TIMERS+1] = { - { {.pTc=TC0}, TC0_IRQn, TC_PRIORITY(0) }, // 0 - stepper + { {.pTc=TC0}, TC0_IRQn, TC_PRIORITY(0) }, // 0 - stepper (assigned priority 2) { {.pTc=TC1}, TC1_IRQn, TC_PRIORITY(1) }, // 1 - stepper (needed by 32 bit timers) - { {.pTc=TC2}, TC2_IRQn, TC_PRIORITY(2) }, // 2 - tone (framework) - { {.pTc=TC3}, TC3_IRQn, TC_PRIORITY(3) }, // 3 - servo - { {.pTc=TC4}, TC4_IRQn, TC_PRIORITY(4) }, + { {.pTc=TC2}, TC2_IRQn, 5 }, // 2 - tone (reserved by framework and fixed assigned priority 5) + { {.pTc=TC3}, TC3_IRQn, TC_PRIORITY(3) }, // 3 - servo (assigned priority 1) + { {.pTc=TC4}, TC4_IRQn, TC_PRIORITY(4) }, // 4 - software serial (no interrupts used) { {.pTc=TC5}, TC5_IRQn, TC_PRIORITY(5) }, { {.pTc=TC6}, TC6_IRQn, TC_PRIORITY(6) }, { {.pTc=TC7}, TC7_IRQn, TC_PRIORITY(7) }, - { {.pRtc=RTC}, RTC_IRQn, TC_PRIORITY(8) } // 8 - temperature + { {.pRtc=RTC}, RTC_IRQn, TC_PRIORITY(8) } // 8 - temperature (assigned priority 6) }; // -------------------------------------------------------------------------- @@ -121,14 +121,15 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { tc->COUNT32.CTRLA.bit.SWRST = true; SYNC(tc->COUNT32.SYNCBUSY.bit.SWRST); - // Wave mode, reset counter on overflow on 0 (I use count down to prevent double buffer use) + // Wave mode, reset counter on compare match tc->COUNT32.WAVE.reg = TC_WAVE_WAVEGEN_MFRQ; tc->COUNT32.CTRLA.reg = TC_CTRLA_MODE_COUNT32 | TC_CTRLA_PRESCALER_DIV1; - tc->COUNT32.CTRLBSET.reg = TC_CTRLBCLR_DIR; + tc->COUNT32.CTRLBCLR.reg = TC_CTRLBCLR_DIR; SYNC(tc->COUNT32.SYNCBUSY.bit.CTRLB); // Set compare value - tc->COUNT32.COUNT.reg = tc->COUNT32.CC[0].reg = (HAL_TIMER_RATE) / frequency; + tc->COUNT32.CC[0].reg = (HAL_TIMER_RATE) / frequency; + tc->COUNT32.COUNT.reg = 0; // Enable interrupt on compare tc->COUNT32.INTFLAG.reg = TC_INTFLAG_OVF; // reset pending interrupt @@ -145,12 +146,12 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { } void HAL_timer_enable_interrupt(const uint8_t timer_num) { - IRQn_Type irq = TimerConfig[timer_num].IRQ_Id; + const IRQn_Type irq = TimerConfig[timer_num].IRQ_Id; NVIC_EnableIRQ(irq); } void HAL_timer_disable_interrupt(const uint8_t timer_num) { - IRQn_Type irq = TimerConfig[timer_num].IRQ_Id; + const IRQn_Type irq = TimerConfig[timer_num].IRQ_Id; Disable_Irq(irq); } @@ -160,7 +161,7 @@ static bool NVIC_GetEnabledIRQ(IRQn_Type IRQn) { } bool HAL_timer_interrupt_enabled(const uint8_t timer_num) { - IRQn_Type irq = TimerConfig[timer_num].IRQ_Id; + const IRQn_Type irq = TimerConfig[timer_num].IRQ_Id; return NVIC_GetEnabledIRQ(irq); } diff --git a/Marlin/src/HAL/HAL_SAMD51/timers.h b/Marlin/src/HAL/SAMD51/timers.h similarity index 83% rename from Marlin/src/HAL/HAL_SAMD51/timers.h rename to Marlin/src/HAL/SAMD51/timers.h index 073239c4311e..dc6e38b7307c 100644 --- a/Marlin/src/HAL/HAL_SAMD51/timers.h +++ b/Marlin/src/HAL/SAMD51/timers.h @@ -15,7 +15,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -32,9 +32,15 @@ typedef uint32_t hal_timer_t; #define HAL_TIMER_RATE F_CPU // frequency of timers peripherals -#define STEP_TIMER_NUM 0 // index of timer to use for stepper (also +1 for 32bits counter) -#define PULSE_TIMER_NUM STEP_TIMER_NUM -#define TEMP_TIMER_NUM RTC_TIMER_NUM // index of timer to use for temperature +#ifndef STEP_TIMER_NUM + #define STEP_TIMER_NUM 0 // Timer Index for Stepper +#endif +#ifndef PULSE_TIMER_NUM + #define PULSE_TIMER_NUM STEP_TIMER_NUM +#endif +#ifndef TEMP_TIMER_NUM + #define TEMP_TIMER_NUM RTC_TIMER_NUM // Timer Index for Temperature +#endif #define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency @@ -53,15 +59,18 @@ typedef uint32_t hal_timer_t; #define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM) #define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM) -#define TC_PRIORITY(t) (t == STEP_TIMER_NUM || t == PULSE_TIMER_NUM) ? 2 \ - : (t == TEMP_TIMER_NUM) ? 6 \ +#define TC_PRIORITY(t) t == SERVO_TC ? 1 \ + : (t == STEP_TIMER_NUM || t == PULSE_TIMER_NUM) ? 2 \ + : (t == TEMP_TIMER_NUM) ? 6 \ : 7 -#define _TC_HANDLER(t) void TC##t##_Handler() -#define TC_HANDLER(t) _TC_HANDLER(t) -#define HAL_STEP_TIMER_ISR() TC_HANDLER(STEP_TIMER_NUM) +#define _TC_HANDLER(t) void TC##t##_Handler() +#define TC_HANDLER(t) _TC_HANDLER(t) +#ifndef HAL_STEP_TIMER_ISR + #define HAL_STEP_TIMER_ISR() TC_HANDLER(STEP_TIMER_NUM) +#endif #if STEP_TIMER_NUM != PULSE_TIMER_NUM - #define HAL_PULSE_TIMER_ISR() TC_HANDLER(PULSE_TIMER_NUM) + #define HAL_PULSE_TIMER_ISR() TC_HANDLER(PULSE_TIMER_NUM) #endif #if TEMP_TIMER_NUM == RTC_TIMER_NUM #define HAL_TEMP_TIMER_ISR() void RTC_Handler() @@ -97,13 +106,13 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency); FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) { // Should never be called with timer RTC_TIMER_NUM Tc * const tc = TimerConfig[timer_num].pTc; - tc->COUNT32.CC[0].reg = HAL_TIMER_TYPE_MAX - compare; + tc->COUNT32.CC[0].reg = compare; } FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) { // Should never be called with timer RTC_TIMER_NUM Tc * const tc = TimerConfig[timer_num].pTc; - return (hal_timer_t)(HAL_TIMER_TYPE_MAX - tc->COUNT32.CC[0].reg); + return (hal_timer_t)tc->COUNT32.CC[0].reg; } FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) { @@ -111,7 +120,7 @@ FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) { Tc * const tc = TimerConfig[timer_num].pTc; tc->COUNT32.CTRLBSET.reg = TC_CTRLBCLR_CMD_READSYNC; SYNC(tc->COUNT32.SYNCBUSY.bit.CTRLB || tc->COUNT32.SYNCBUSY.bit.COUNT); - return HAL_TIMER_TYPE_MAX - tc->COUNT32.COUNT.reg; + return tc->COUNT32.COUNT.reg; } void HAL_timer_enable_interrupt(const uint8_t timer_num); diff --git a/Marlin/src/HAL/HAL_SAMD51/watchdog.cpp b/Marlin/src/HAL/SAMD51/watchdog.cpp similarity index 95% rename from Marlin/src/HAL/HAL_SAMD51/watchdog.cpp rename to Marlin/src/HAL/SAMD51/watchdog.cpp index 13539b4d704d..ebc8dffe1300 100644 --- a/Marlin/src/HAL/HAL_SAMD51/watchdog.cpp +++ b/Marlin/src/HAL/SAMD51/watchdog.cpp @@ -15,10 +15,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef __SAMD51__ #include "../../inc/MarlinConfig.h" diff --git a/Marlin/src/HAL/HAL_SAMD51/watchdog.h b/Marlin/src/HAL/SAMD51/watchdog.h similarity index 94% rename from Marlin/src/HAL/HAL_SAMD51/watchdog.h rename to Marlin/src/HAL/SAMD51/watchdog.h index aa8ef3537112..2cd4788229b0 100644 --- a/Marlin/src/HAL/HAL_SAMD51/watchdog.h +++ b/Marlin/src/HAL/SAMD51/watchdog.h @@ -15,7 +15,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_STM32/HAL.cpp b/Marlin/src/HAL/STM32/HAL.cpp similarity index 78% rename from Marlin/src/HAL/HAL_STM32/HAL.cpp rename to Marlin/src/HAL/STM32/HAL.cpp index 5d8c686af30e..83604b1104bb 100644 --- a/Marlin/src/HAL/HAL_STM32/HAL.cpp +++ b/Marlin/src/HAL/STM32/HAL.cpp @@ -17,21 +17,17 @@ * 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 . + * along with this program. If not, see . * */ - #if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC) #include "HAL.h" +#include "usb_serial.h" #include "../../inc/MarlinConfig.h" #include "../shared/Delay.h" -#if HAS_TMC_SW_SERIAL - #include "SoftwareSerial.h" -#endif - #if ENABLED(SRAM_EEPROM_EMULATION) #if STM32F7xx #include @@ -67,7 +63,7 @@ uint16_t HAL_adc_result; void HAL_init() { FastIO_init(); - #if ENABLED(SDSUPPORT) + #if ENABLED(SDSUPPORT) && DISABLED(SDIO_SUPPORT) && (defined(SDSS) && SDSS != -1) OUT_WRITE(SDSS, HIGH); // Try to set SDSS inactive before any other SPI users start up #endif @@ -76,20 +72,16 @@ void HAL_init() { #endif #if ENABLED(SRAM_EEPROM_EMULATION) - // Enable access to backup SRAM - __HAL_RCC_PWR_CLK_ENABLE(); - HAL_PWR_EnableBkUpAccess(); - __HAL_RCC_BKPSRAM_CLK_ENABLE(); - - // Enable backup regulator - LL_PWR_EnableBkUpRegulator(); - // Wait until backup regulator is initialized - while (!LL_PWR_IsActiveFlag_BRR()); - #endif // EEPROM_EMULATED_SRAM - - #if HAS_TMC_SW_SERIAL - SoftwareSerial::setInterruptPriority(SWSERIAL_TIMER_IRQ_PRIO, 0); + __HAL_RCC_PWR_CLK_ENABLE(); + HAL_PWR_EnableBkUpAccess(); // Enable access to backup SRAM + __HAL_RCC_BKPSRAM_CLK_ENABLE(); + LL_PWR_EnableBkUpRegulator(); // Enable backup regulator + while (!LL_PWR_IsActiveFlag_BRR()); // Wait until backup regulator is initialized #endif + + SetTimerInterruptPriorities(); + + TERN_(EMERGENCY_PARSER, USB_Hook_init()); } void HAL_clear_reset_source() { __HAL_RCC_CLEAR_RESET_FLAGS(); } @@ -130,9 +122,14 @@ extern "C" { // TODO: Make sure this doesn't cause any delay void HAL_adc_start_conversion(const uint8_t adc_pin) { HAL_adc_result = analogRead(adc_pin); } - uint16_t HAL_adc_get_result() { return HAL_adc_result; } -void flashFirmware(int16_t) { NVIC_SystemReset(); } +// Reset the system (to initiate a firmware flash) +void flashFirmware(const int16_t) { NVIC_SystemReset(); } + +// Maple Compatibility +systickCallback_t systick_user_callback; +void systick_attach_callback(systickCallback_t cb) { systick_user_callback = cb; } +void HAL_SYSTICK_Callback() { if (systick_user_callback) systick_user_callback(); } #endif // ARDUINO_ARCH_STM32 && !STM32GENERIC diff --git a/Marlin/src/HAL/HAL_STM32/HAL.h b/Marlin/src/HAL/STM32/HAL.h similarity index 55% rename from Marlin/src/HAL/HAL_STM32/HAL.h rename to Marlin/src/HAL/STM32/HAL.h index 9fb40d612187..a1f7515d6b98 100644 --- a/Marlin/src/HAL/HAL_STM32/HAL.h +++ b/Marlin/src/HAL/STM32/HAL.h @@ -17,7 +17,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -30,6 +30,7 @@ #include "../shared/HAL_SPI.h" #include "fastio.h" #include "watchdog.h" +#include "MarlinSerial.h" #include "../../inc/MarlinConfigPre.h" @@ -42,84 +43,40 @@ // ------------------------ // Defines // ------------------------ +#define _MSERIAL(X) MSerial##X +#define MSERIAL(X) _MSERIAL(X) -#if SERIAL_PORT == 0 - #error "SERIAL_PORT cannot be 0. (Port 0 does not exist.) Please update your configuration." -#elif SERIAL_PORT == -1 +#if SERIAL_PORT == -1 #define MYSERIAL0 SerialUSB -#elif SERIAL_PORT == 1 - #define MYSERIAL0 Serial1 -#elif SERIAL_PORT == 2 - #define MYSERIAL0 Serial2 -#elif SERIAL_PORT == 3 - #define MYSERIAL0 Serial3 -#elif SERIAL_PORT == 4 - #define MYSERIAL0 Serial4 -#elif SERIAL_PORT == 5 - #define MYSERIAL0 Serial5 -#elif SERIAL_PORT == 6 - #define MYSERIAL0 Serial6 +#elif WITHIN(SERIAL_PORT, 1, 6) + #define MYSERIAL0 MSERIAL(SERIAL_PORT) #else - #error "SERIAL_PORT must be from -1 to 6. Please update your configuration." + #error "SERIAL_PORT must be -1 or from 1 to 6. Please update your configuration." #endif #ifdef SERIAL_PORT_2 - #define NUM_SERIAL 2 - #if SERIAL_PORT_2 == 0 - #error "SERIAL_PORT_2 cannot be 0. (Port 0 does not exist.) Please update your configuration." - #elif SERIAL_PORT_2 == SERIAL_PORT - #error "SERIAL_PORT_2 must be different than SERIAL_PORT. Please update your configuration." - #elif SERIAL_PORT_2 == -1 + #if SERIAL_PORT_2 == -1 #define MYSERIAL1 SerialUSB - #elif SERIAL_PORT_2 == 1 - #define MYSERIAL1 Serial1 - #elif SERIAL_PORT_2 == 2 - #define MYSERIAL1 Serial2 - #elif SERIAL_PORT_2 == 3 - #define MYSERIAL1 Serial3 - #elif SERIAL_PORT_2 == 4 - #define MYSERIAL1 Serial4 - #elif SERIAL_PORT_2 == 5 - #define MYSERIAL1 Serial5 - #elif SERIAL_PORT_2 == 6 - #define MYSERIAL1 Serial6 + #elif WITHIN(SERIAL_PORT_2, 1, 6) + #define MYSERIAL1 MSERIAL(SERIAL_PORT_2) #else - #error "SERIAL_PORT_2 must be from -1 to 6. Please update your configuration." + #error "SERIAL_PORT_2 must be -1 or from 1 to 6. Please update your configuration." #endif -#else - #define NUM_SERIAL 1 #endif -#if HAS_DGUS_LCD - #if DGUS_SERIAL_PORT == 0 - #error "DGUS_SERIAL_PORT cannot be 0. (Port 0 does not exist.) Please update your configuration." - #elif DGUS_SERIAL_PORT == SERIAL_PORT - #error "DGUS_SERIAL_PORT must be different than SERIAL_PORT. Please update your configuration." - #elif defined(SERIAL_PORT_2) && DGUS_SERIAL_PORT == SERIAL_PORT_2 - #error "DGUS_SERIAL_PORT must be different than SERIAL_PORT_2. Please update your configuration." - #elif DGUS_SERIAL_PORT == -1 - #define DGUS_SERIAL SerialUSB - #elif DGUS_SERIAL_PORT == 1 - #define DGUS_SERIAL Serial1 - #elif DGUS_SERIAL_PORT == 2 - #define DGUS_SERIAL Serial2 - #elif DGUS_SERIAL_PORT == 3 - #define DGUS_SERIAL Serial3 - #elif DGUS_SERIAL_PORT == 4 - #define DGUS_SERIAL Serial4 - #elif DGUS_SERIAL_PORT == 5 - #define DGUS_SERIAL Serial5 - #elif DGUS_SERIAL_PORT == 6 - #define DGUS_SERIAL Serial6 +#ifdef LCD_SERIAL_PORT + #if LCD_SERIAL_PORT == -1 + #define LCD_SERIAL SerialUSB + #elif WITHIN(LCD_SERIAL_PORT, 1, 6) + #define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT) #else - #error "DGUS_SERIAL_PORT must be from -1 to 6. Please update your configuration." + #error "LCD_SERIAL_PORT must be -1 or from 1 to 6. Please update your configuration." + #endif + #if HAS_DGUS_LCD + #define SERIAL_GET_TX_BUFFER_FREE() LCD_SERIAL.availableForWrite() #endif - - #define DGUS_SERIAL_GET_TX_BUFFER_FREE DGUS_SERIAL.availableForWrite #endif -#include "timers.h" - /** * TODO: review this to return 1 for pins that are not analog input */ @@ -177,6 +134,8 @@ void HAL_clear_reset_source(); // Reset reason uint8_t HAL_get_reset_source(); +inline void HAL_reboot() {} // reboot the board or restart the bootloader + void _delay_ms(const int delay); extern "C" char* _sbrk(int incr); @@ -191,16 +150,6 @@ static inline int freeMemory() { #pragma GCC diagnostic pop -// -// EEPROM -// - -// Wire library should work for i2c EEPROMs -void eeprom_write_byte(uint8_t *pos, unsigned char value); -uint8_t eeprom_read_byte(uint8_t *pos); -void eeprom_read_block(void *__dst, const void *__src, size_t __n); -void eeprom_update_block(const void *__src, void *__dst, size_t __n); - // // ADC // @@ -209,8 +158,9 @@ void eeprom_update_block(const void *__src, void *__dst, size_t __n); inline void HAL_adc_init() {} -#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin) +#define HAL_ADC_VREF 3.3 #define HAL_ADC_RESOLUTION 10 +#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin) #define HAL_READ_ADC() HAL_adc_result #define HAL_ADC_READY() true @@ -222,5 +172,15 @@ uint16_t HAL_adc_get_result(); #define GET_PIN_MAP_INDEX(pin) pin #define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval) +#ifdef STM32F1xx + #define JTAG_DISABLE() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_JTAGDISABLE) + #define JTAGSWD_DISABLE() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_DISABLE) +#endif + #define PLATFORM_M997_SUPPORT -void flashFirmware(int16_t value); +void flashFirmware(const int16_t); + +// Maple Compatibility +typedef void (*systickCallback_t)(void); +void systick_attach_callback(systickCallback_t cb); +void HAL_SYSTICK_Callback(); diff --git a/Marlin/src/HAL/HAL_STM32/HAL_SPI.cpp b/Marlin/src/HAL/STM32/HAL_SPI.cpp similarity index 93% rename from Marlin/src/HAL/HAL_STM32/HAL_SPI.cpp rename to Marlin/src/HAL/STM32/HAL_SPI.cpp index 7b37fff9c249..f947e6ef3272 100644 --- a/Marlin/src/HAL/HAL_STM32/HAL_SPI.cpp +++ b/Marlin/src/HAL/STM32/HAL_SPI.cpp @@ -17,7 +17,7 @@ * 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 . + * along with this program. If not, see . * */ #if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC) @@ -132,11 +132,9 @@ static SPISettings spiConfig; * @details Only configures SS pin since stm32duino creates and initialize the SPI object */ void spiBegin() { - #if !PIN_EXISTS(SS) - #error "SS_PIN not defined!" + #if PIN_EXISTS(SS) + OUT_WRITE(SS_PIN, HIGH); #endif - - OUT_WRITE(SS_PIN, HIGH); } // Configure SPI for specified SPI speed @@ -173,9 +171,7 @@ static SPISettings spiConfig; * @details */ uint8_t spiRec() { - SPI.beginTransaction(spiConfig); uint8_t returnByte = SPI.transfer(0xFF); - SPI.endTransaction(); return returnByte; } @@ -191,9 +187,7 @@ static SPISettings spiConfig; void spiRead(uint8_t* buf, uint16_t nbyte) { if (nbyte == 0) return; memset(buf, 0xFF, nbyte); - SPI.beginTransaction(spiConfig); SPI.transfer(buf, nbyte); - SPI.endTransaction(); } /** @@ -204,9 +198,7 @@ static SPISettings spiConfig; * @details */ void spiSend(uint8_t b) { - SPI.beginTransaction(spiConfig); SPI.transfer(b); - SPI.endTransaction(); } /** @@ -219,10 +211,8 @@ static SPISettings spiConfig; */ void spiSendBlock(uint8_t token, const uint8_t* buf) { uint8_t rxBuf[512]; - SPI.beginTransaction(spiConfig); SPI.transfer(token); SPI.transfer((uint8_t*)buf, &rxBuf, 512); - SPI.endTransaction(); } #endif // SOFTWARE_SPI diff --git a/Marlin/src/HAL/STM32/MarlinSerial.cpp b/Marlin/src/HAL/STM32/MarlinSerial.cpp new file mode 100644 index 000000000000..a146664366df --- /dev/null +++ b/Marlin/src/HAL/STM32/MarlinSerial.cpp @@ -0,0 +1,86 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC) + +#include "../../inc/MarlinConfig.h" +#include "MarlinSerial.h" + +#if ENABLED(EMERGENCY_PARSER) + #include "../../feature/e_parser.h" +#endif + +#ifndef USART4 + #define USART4 UART4 +#endif + +#ifndef USART5 + #define USART5 UART5 +#endif + +#define DECLARE_SERIAL_PORT(ser_num) \ + void _rx_complete_irq_ ## ser_num (serial_t * obj); \ + MarlinSerial MSerial ## ser_num (USART ## ser_num, &_rx_complete_irq_ ## ser_num); \ + void _rx_complete_irq_ ## ser_num (serial_t * obj) { MSerial ## ser_num ._rx_complete_irq(obj); } + +#define DECLARE_SERIAL_PORT_EXP(ser_num) DECLARE_SERIAL_PORT(ser_num) + +#if defined(SERIAL_PORT) && SERIAL_PORT >= 0 + DECLARE_SERIAL_PORT_EXP(SERIAL_PORT) +#endif + +#if defined(SERIAL_PORT_2) && SERIAL_PORT_2 >= 0 + DECLARE_SERIAL_PORT_EXP(SERIAL_PORT_2) +#endif + +#if defined(LCD_SERIAL_PORT) && LCD_SERIAL_PORT >= 0 + DECLARE_SERIAL_PORT_EXP(LCD_SERIAL_PORT) +#endif + +void MarlinSerial::begin(unsigned long baud, uint8_t config) { + HardwareSerial::begin(baud, config); + // Replace the IRQ callback with the one we have defined + TERN_(EMERGENCY_PARSER, _serial.rx_callback = _rx_callback); +} + +// This function is Copyright (c) 2006 Nicholas Zambetti. +void MarlinSerial::_rx_complete_irq(serial_t *obj) { + // No Parity error, read byte and store it in the buffer if there is room + unsigned char c; + + if (uart_getc(obj, &c) == 0) { + + rx_buffer_index_t i = (unsigned int)(obj->rx_head + 1) % SERIAL_RX_BUFFER_SIZE; + + // if we should be storing the received character into the location + // just before the tail (meaning that the head would advance to the + // current location of the tail), we're about to overflow the buffer + // and so we don't write the character or advance the head. + if (i != obj->rx_tail) { + obj->rx_buff[obj->rx_head] = c; + obj->rx_head = i; + } + + #if ENABLED(EMERGENCY_PARSER) + emergency_parser.update(emergency_state, c); + #endif + } +} + +#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC diff --git a/Marlin/src/HAL/STM32/MarlinSerial.h b/Marlin/src/HAL/STM32/MarlinSerial.h new file mode 100644 index 000000000000..3611cc78d7ce --- /dev/null +++ b/Marlin/src/HAL/STM32/MarlinSerial.h @@ -0,0 +1,64 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../../inc/MarlinConfigPre.h" + +#if ENABLED(EMERGENCY_PARSER) + #include "../../feature/e_parser.h" +#endif + +typedef void (*usart_rx_callback_t)(serial_t * obj); + +class MarlinSerial : public HardwareSerial { +public: + MarlinSerial(void* peripheral, usart_rx_callback_t rx_callback) : + HardwareSerial(peripheral), _rx_callback(rx_callback) + #if ENABLED(EMERGENCY_PARSER) + , emergency_state(EmergencyParser::State::EP_RESET) + #endif + { } + + #if ENABLED(EMERGENCY_PARSER) + static inline bool emergency_parser_enabled() { return true; } + #endif + + void begin(unsigned long baud, uint8_t config); + inline void begin(unsigned long baud) { begin(baud, SERIAL_8N1); } + + void _rx_complete_irq(serial_t* obj); + +protected: + usart_rx_callback_t _rx_callback; + #if ENABLED(EMERGENCY_PARSER) + EmergencyParser::State emergency_state; + #endif +}; + +extern MarlinSerial MSerial1; +extern MarlinSerial MSerial2; +extern MarlinSerial MSerial3; +extern MarlinSerial MSerial4; +extern MarlinSerial MSerial5; +extern MarlinSerial MSerial6; +extern MarlinSerial MSerial7; +extern MarlinSerial MSerial8; +extern MarlinSerial MSerial9; +extern MarlinSerial MSerial10; +extern MarlinSerial MSerialLP1; diff --git a/Marlin/src/HAL/HAL_STM32/README.md b/Marlin/src/HAL/STM32/README.md similarity index 100% rename from Marlin/src/HAL/HAL_STM32/README.md rename to Marlin/src/HAL/STM32/README.md diff --git a/Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp b/Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp new file mode 100644 index 000000000000..6e73e87c2123 --- /dev/null +++ b/Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp @@ -0,0 +1,321 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(SDIO_SUPPORT) && !defined(STM32GENERIC) + +#include +#include + +#if NONE(STM32F103xE, STM32F103xG, STM32F4xx, STM32F7xx) + #error "ERROR - Only STM32F103xE, STM32F103xG, STM32F4xx or STM32F7xx CPUs supported" +#endif + +#ifdef USBD_USE_CDC_COMPOSITE + + // use USB drivers + + extern "C" { int8_t SD_MSC_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); + int8_t SD_MSC_Write(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); + extern SD_HandleTypeDef hsd; + } + + bool SDIO_Init() { + return hsd.State == HAL_SD_STATE_READY; // return pass/fail status + } + + bool SDIO_ReadBlock(uint32_t block, uint8_t *src) { + int8_t status = SD_MSC_Read(0, (uint8_t*)src, block, 1); // read one 512 byte block + return (bool) status; + } + + bool SDIO_WriteBlock(uint32_t block, const uint8_t *src) { + int8_t status = SD_MSC_Write(0, (uint8_t*)src, block, 1); // write one 512 byte block + return (bool) status; + } + +#else // !USBD_USE_CDC_COMPOSITE + + // use local drivers + #if defined(STM32F103xE) || defined(STM32F103xG) + #include + #include + #elif defined(STM32F4xx) + #include + #include + #include + #include + #elif defined(STM32F7xx) + #include + #include + #include + #include + #else + #error "ERROR - Only STM32F103xE, STM32F103xG, STM32F4xx or STM32F7xx CPUs supported" + #endif + + SD_HandleTypeDef hsd; // create SDIO structure + + /* + SDIO_INIT_CLK_DIV is 118 + SDIO clock frequency is 48MHz / (TRANSFER_CLOCK_DIV + 2) + SDIO init clock frequency should not exceed 400KHz = 48MHz / (118 + 2) + + Default TRANSFER_CLOCK_DIV is 2 (118 / 40) + Default SDIO clock frequency is 48MHz / (2 + 2) = 12 MHz + This might be too fast for stable SDIO operations + + MKS Robin board seems to have stable SDIO with BusWide 1bit and ClockDiv 8 i.e. 4.8MHz SDIO clock frequency + Additional testing is required as there are clearly some 4bit initialization problems + + Add -DTRANSFER_CLOCK_DIV=8 to build parameters to improve SDIO stability + */ + + #ifndef TRANSFER_CLOCK_DIV + #define TRANSFER_CLOCK_DIV (uint8_t(SDIO_INIT_CLK_DIV) / 40) + #endif + + #ifndef USBD_OK + #define USBD_OK 0 + #endif + + void go_to_transfer_speed() { + SD_InitTypeDef Init; + + /* Default SDIO peripheral configuration for SD card initialization */ + Init.ClockEdge = hsd.Init.ClockEdge; + Init.ClockBypass = hsd.Init.ClockBypass; + Init.ClockPowerSave = hsd.Init.ClockPowerSave; + Init.BusWide = hsd.Init.BusWide; + Init.HardwareFlowControl = hsd.Init.HardwareFlowControl; + Init.ClockDiv = TRANSFER_CLOCK_DIV; + + /* Initialize SDIO peripheral interface with default configuration */ + SDIO_Init(hsd.Instance, Init); + } + + void SD_LowLevel_Init(void) { + uint32_t tempreg; + + __HAL_RCC_SDIO_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); //enable GPIO clocks + __HAL_RCC_GPIOD_CLK_ENABLE(); //enable GPIO clocks + + GPIO_InitTypeDef GPIO_InitStruct; + + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = 1; //GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + + #if DISABLED(STM32F1xx) + GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; + #endif + + GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_12; // D0 & SCK + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + #if PINS_EXIST(SDIO_D1, SDIO_D2, SDIO_D3) // define D1-D3 only if have a four bit wide SDIO bus + GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11; // D1-D3 + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + #endif + + // Configure PD.02 CMD line + GPIO_InitStruct.Pin = GPIO_PIN_2; + HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); + + + #if DISABLED(STM32F1xx) + // TODO: use __HAL_RCC_SDIO_RELEASE_RESET() and __HAL_RCC_SDIO_CLK_ENABLE(); + RCC->APB2RSTR &= ~RCC_APB2RSTR_SDIORST_Msk; // take SDIO out of reset + RCC->APB2ENR |= RCC_APB2RSTR_SDIORST_Msk; // enable SDIO clock + // Enable the DMA2 Clock + #endif + + //Initialize the SDIO (with initial <400Khz Clock) + tempreg = 0; //Reset value + tempreg |= SDIO_CLKCR_CLKEN; // Clock enabled + tempreg |= (uint32_t)0x76; // Clock Divider. Clock = 48000 / (118 + 2) = 400Khz + // Keep the rest at 0 => HW_Flow Disabled, Rising Clock Edge, Disable CLK ByPass, Bus Width = 0, Power save Disable + SDIO->CLKCR = tempreg; + + // Power up the SDIO + SDIO->POWER = 0x03; + } + + void HAL_SD_MspInit(SD_HandleTypeDef *hsd) { // application specific init + UNUSED(hsd); /* Prevent unused argument(s) compilation warning */ + __HAL_RCC_SDIO_CLK_ENABLE(); // turn on SDIO clock + } + + constexpr uint8_t SD_RETRY_COUNT = TERN(SD_CHECK_AND_RETRY, 3, 1); + + bool SDIO_Init() { + //init SDIO and get SD card info + + uint8_t retryCnt = SD_RETRY_COUNT; + + bool status; + hsd.Instance = SDIO; + hsd.State = (HAL_SD_StateTypeDef) 0; // HAL_SD_STATE_RESET + + /* + hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING; + hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE; + hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE; + hsd.Init.BusWide = SDIO_BUS_WIDE_1B; + hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE; + hsd.Init.ClockDiv = 8; + */ + + SD_LowLevel_Init(); + + uint8_t retry_Cnt = retryCnt; + for (;;) { + TERN_(USE_WATCHDOG, HAL_watchdog_refresh()); + status = (bool) HAL_SD_Init(&hsd); + if (!status) break; + if (!--retry_Cnt) return false; // return failing status if retries are exhausted + } + + go_to_transfer_speed(); + + #if PINS_EXIST(SDIO_D1, SDIO_D2, SDIO_D3) // go to 4 bit wide mode if pins are defined + retry_Cnt = retryCnt; + for (;;) { + TERN_(USE_WATCHDOG, HAL_watchdog_refresh()); + if (!HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B)) break; // some cards are only 1 bit wide so a pass here is not required + if (!--retry_Cnt) break; + } + if (!retry_Cnt) { // wide bus failed, go back to one bit wide mode + hsd.State = (HAL_SD_StateTypeDef) 0; // HAL_SD_STATE_RESET + SD_LowLevel_Init(); + retry_Cnt = retryCnt; + for (;;) { + TERN_(USE_WATCHDOG, HAL_watchdog_refresh()); + status = (bool) HAL_SD_Init(&hsd); + if (!status) break; + if (!--retry_Cnt) return false; // return failing status if retries are exhausted + } + } + #endif + + return true; + } + /* + void init_SDIO_pins(void) { + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + // SDIO GPIO Configuration + // PC8 ------> SDIO_D0 + // PC12 ------> SDIO_CK + // PD2 ------> SDIO_CMD + + GPIO_InitStruct.Pin = GPIO_PIN_8; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_12; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_2; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; + HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); + } + */ + //bool SDIO_init() { return (bool) (SD_SDIO_Init() ? 1 : 0);} + //bool SDIO_Init_C() { return (bool) (SD_SDIO_Init() ? 1 : 0);} + + bool SDIO_ReadBlock(uint32_t block, uint8_t *dst) { + hsd.Instance = SDIO; + uint8_t retryCnt = SD_RETRY_COUNT; + + bool status; + for (;;) { + TERN_(USE_WATCHDOG, HAL_watchdog_refresh()); + status = (bool) HAL_SD_ReadBlocks(&hsd, (uint8_t*)dst, block, 1, 1000); // read one 512 byte block with 500mS timeout + status |= (bool) HAL_SD_GetCardState(&hsd); // make sure all is OK + if (!status) break; // return passing status + if (!--retryCnt) break; // return failing status if retries are exhausted + } + return status; + + /* + return (bool) ((status_read | status_card) ? 1 : 0); + + if (SDIO_GetCardState() != SDIO_CARD_TRANSFER) return false; + if (blockAddress >= SdCard.LogBlockNbr) return false; + if ((0x03 & (uint32_t)data)) return false; // misaligned data + + if (SdCard.CardType != CARD_SDHC_SDXC) { blockAddress *= 512U; } + + if (!SDIO_CmdReadSingleBlock(blockAddress)) { + SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS); + dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); + return false; + } + + while (!SDIO_GET_FLAG(SDIO_STA_DATAEND | SDIO_STA_TRX_ERROR_FLAGS)) {} + + dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); + + if (SDIO->STA & SDIO_STA_RXDAVL) { + while (SDIO->STA & SDIO_STA_RXDAVL) (void)SDIO->FIFO; + SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS); + return false; + } + + if (SDIO_GET_FLAG(SDIO_STA_TRX_ERROR_FLAGS)) { + SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS); + return false; + } + SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS); + */ + + return true; + } + + bool SDIO_WriteBlock(uint32_t block, const uint8_t *src) { + hsd.Instance = SDIO; + uint8_t retryCnt = SD_RETRY_COUNT; + bool status; + for (;;) { + status = (bool) HAL_SD_WriteBlocks(&hsd, (uint8_t*)src, block, 1, 500); // write one 512 byte block with 500mS timeout + status |= (bool) HAL_SD_GetCardState(&hsd); // make sure all is OK + if (!status) break; // return passing status + if (!--retryCnt) break; // return failing status if retries are exhausted + } + return status; + } + +#endif // !USBD_USE_CDC_COMPOSITE +#endif // SDIO_SUPPORT diff --git a/Marlin/src/HAL/STM32/Servo.cpp b/Marlin/src/HAL/STM32/Servo.cpp new file mode 100644 index 000000000000..1cf117a05694 --- /dev/null +++ b/Marlin/src/HAL/STM32/Servo.cpp @@ -0,0 +1,110 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * Copyright (c) 2017 Victor Perez + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC) + +#include "../../inc/MarlinConfig.h" + +#if HAS_SERVOS + +#include "Servo.h" + +static uint_fast8_t servoCount = 0; +static libServo *servos[NUM_SERVOS] = {0}; +constexpr millis_t servoDelay[] = SERVO_DELAY; +static_assert(COUNT(servoDelay) == NUM_SERVOS, "SERVO_DELAY must be an array NUM_SERVOS long."); + +// Initialize to the default timer priority. This will be overridden by a call from timers.cpp. +// This allows all timer interrupt priorities to be managed from a single location in the HAL. +static uint32_t servo_interrupt_priority = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), TIM_IRQ_PRIO, TIM_IRQ_SUBPRIO); + +// This must be called after the STM32 Servo class has intialized the timer. +// It may only be needed after the first call to attach(), but it is possible +// that is is necessary after every detach() call. To be safe this is currently +// called after every call to attach(). +static void fixServoTimerInterruptPriority() { + NVIC_SetPriority(getTimerUpIrq(TIMER_SERVO), servo_interrupt_priority); +} + +libServo::libServo() +: delay(servoDelay[servoCount]), + was_attached_before_pause(false), + value_before_pause(0) +{ + servos[servoCount++] = this; +} + +int8_t libServo::attach(const int pin) { + if (servoCount >= MAX_SERVOS) return -1; + if (pin > 0) servo_pin = pin; + auto result = stm32_servo.attach(servo_pin); + fixServoTimerInterruptPriority(); + return result; +} + +int8_t libServo::attach(const int pin, const int min, const int max) { + if (servoCount >= MAX_SERVOS) return -1; + if (pin > 0) servo_pin = pin; + auto result = stm32_servo.attach(servo_pin, min, max); + fixServoTimerInterruptPriority(); + return result; +} + +void libServo::move(const int value) { + if (attach(0) >= 0) { + stm32_servo.write(value); + safe_delay(delay); + TERN_(DEACTIVATE_SERVOS_AFTER_MOVE, detach()); + } +} + +void libServo::pause() { + was_attached_before_pause = stm32_servo.attached(); + if (was_attached_before_pause) { + value_before_pause = stm32_servo.read(); + stm32_servo.detach(); + } +} + +void libServo::resume() { + if (was_attached_before_pause) { + attach(); + move(value_before_pause); + } +} + +void libServo::pause_all_servos() { + for (auto& servo : servos) + if (servo) servo->pause(); +} + +void libServo::resume_all_servos() { + for (auto& servo : servos) + if (servo) servo->resume(); +} + +void libServo::setInterruptPriority(uint32_t preemptPriority, uint32_t subPriority) { + servo_interrupt_priority = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), preemptPriority, subPriority); +} + +#endif // HAS_SERVOS +#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC diff --git a/Marlin/src/HAL/STM32/Servo.h b/Marlin/src/HAL/STM32/Servo.h new file mode 100644 index 000000000000..1527e753b661 --- /dev/null +++ b/Marlin/src/HAL/STM32/Servo.h @@ -0,0 +1,54 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * Copyright (c) 2017 Victor Perez + * + * 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 . + * + */ +#pragma once + +#include + +#include "../../core/millis_t.h" + +// Inherit and expand on the official library +class libServo { + public: + libServo(); + int8_t attach(const int pin = 0); // pin == 0 uses value from previous call + int8_t attach(const int pin, const int min, const int max); + void detach() { stm32_servo.detach(); } + int read() { return stm32_servo.read(); } + void move(const int value); + + void pause(); + void resume(); + + static void pause_all_servos(); + static void resume_all_servos(); + static void setInterruptPriority(uint32_t preemptPriority, uint32_t subPriority); + + private: + Servo stm32_servo; + + int servo_pin = 0; + millis_t delay = 0; + + bool was_attached_before_pause; + int value_before_pause; +}; diff --git a/Marlin/src/HAL/HAL_STM32/persistent_store_flash.cpp b/Marlin/src/HAL/STM32/eeprom_flash.cpp similarity index 73% rename from Marlin/src/HAL/HAL_STM32/persistent_store_flash.cpp rename to Marlin/src/HAL/STM32/eeprom_flash.cpp index 80ef901ceba9..0933b9f4e8cb 100644 --- a/Marlin/src/HAL/HAL_STM32/persistent_store_flash.cpp +++ b/Marlin/src/HAL/STM32/eeprom_flash.cpp @@ -17,22 +17,24 @@ * 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 . + * along with this program. If not, see . * */ - #if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC) #include "../../inc/MarlinConfig.h" -#if BOTH(EEPROM_SETTINGS, FLASH_EEPROM_EMULATION) - -#include "../shared/persistent_store_api.h" +#if ENABLED(FLASH_EEPROM_EMULATION) +#include "../shared/eeprom_api.h" -// Only STM32F4 can support wear leveling at this time -#ifndef STM32F4xx - #undef FLASH_EEPROM_LEVELING +#if HAS_SERVOS + #include "Servo.h" + #define PAUSE_SERVO_OUTPUT() libServo::pause_all_servos() + #define RESUME_SERVO_OUTPUT() libServo::resume_all_servos() +#else + #define PAUSE_SERVO_OUTPUT() + #define RESUME_SERVO_OUTPUT() #endif /** @@ -57,8 +59,8 @@ #define DEBUG_OUT ENABLED(EEPROM_CHITCHAT) #include "src/core/debug_out.h" - #ifndef EEPROM_SIZE - #define EEPROM_SIZE 0x1000 // 4kB + #ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE 0x1000 // 4KB #endif #ifndef FLASH_SECTOR @@ -68,11 +70,11 @@ #define FLASH_UNIT_SIZE 0x20000 // 128kB #endif - #define FLASH_ADDRESS_START (FLASH_END - ((FLASH_SECTOR_TOTAL - FLASH_SECTOR) * FLASH_UNIT_SIZE) + 1) + #define FLASH_ADDRESS_START (FLASH_END - ((FLASH_SECTOR_TOTAL - (FLASH_SECTOR)) * (FLASH_UNIT_SIZE)) + 1) #define FLASH_ADDRESS_END (FLASH_ADDRESS_START + FLASH_UNIT_SIZE - 1) - #define EEPROM_SLOTS (FLASH_UNIT_SIZE/EEPROM_SIZE) - #define SLOT_ADDRESS(slot) (FLASH_ADDRESS_START + (slot * EEPROM_SIZE)) + #define EEPROM_SLOTS ((FLASH_UNIT_SIZE) / (MARLIN_EEPROM_SIZE)) + #define SLOT_ADDRESS(slot) (FLASH_ADDRESS_START + (slot * (MARLIN_EEPROM_SIZE))) #define UNLOCK_FLASH() if (!flash_unlocked) { \ HAL_FLASH_Unlock(); \ @@ -85,12 +87,12 @@ #define EMPTY_UINT32 ((uint32_t)-1) #define EMPTY_UINT8 ((uint8_t)-1) - static uint8_t ram_eeprom[EEPROM_SIZE] __attribute__((aligned(4))) = {0}; + static uint8_t ram_eeprom[MARLIN_EEPROM_SIZE] __attribute__((aligned(4))) = {0}; static int current_slot = -1; - static_assert(0 == EEPROM_SIZE % 4, "EEPROM_SIZE must be a multiple of 4"); // Ensure copying as uint32_t is safe - static_assert(0 == FLASH_UNIT_SIZE % EEPROM_SIZE, "EEPROM_SIZE must divide evenly into your FLASH_UNIT_SIZE"); - static_assert(FLASH_UNIT_SIZE >= EEPROM_SIZE, "FLASH_UNIT_SIZE must be greater than or equal to your EEPROM_SIZE"); + static_assert(0 == MARLIN_EEPROM_SIZE % 4, "MARLIN_EEPROM_SIZE must be a multiple of 4"); // Ensure copying as uint32_t is safe + static_assert(0 == FLASH_UNIT_SIZE % MARLIN_EEPROM_SIZE, "MARLIN_EEPROM_SIZE must divide evenly into your FLASH_UNIT_SIZE"); + static_assert(FLASH_UNIT_SIZE >= MARLIN_EEPROM_SIZE, "FLASH_UNIT_SIZE must be greater than or equal to your MARLIN_EEPROM_SIZE"); static_assert(IS_FLASH_SECTOR(FLASH_SECTOR), "FLASH_SECTOR is invalid"); static_assert(IS_POWER_OF_2(FLASH_UNIT_SIZE), "FLASH_UNIT_SIZE should be a power of 2, please check your chip's spec sheet"); @@ -98,6 +100,11 @@ static bool eeprom_data_written = false; +#ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE size_t(E2END + 1) +#endif +size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } + bool PersistentStore::access_start() { #if ENABLED(FLASH_EEPROM_LEVELING) @@ -111,20 +118,20 @@ bool PersistentStore::access_start() { while (address <= FLASH_ADDRESS_END) { uint32_t address_value = (*(__IO uint32_t*)address); if (address_value != EMPTY_UINT32) { - current_slot = (address - FLASH_ADDRESS_START) / EEPROM_SIZE; + current_slot = (address - (FLASH_ADDRESS_START)) / (MARLIN_EEPROM_SIZE); break; } address += sizeof(uint32_t); } if (current_slot == -1) { // We didn't find anything, so we'll just intialize to empty - for (int i = 0; i < EEPROM_SIZE; i++) ram_eeprom[i] = EMPTY_UINT8; + for (int i = 0; i < MARLIN_EEPROM_SIZE; i++) ram_eeprom[i] = EMPTY_UINT8; current_slot = EEPROM_SLOTS; } else { // load current settings uint8_t *eeprom_data = (uint8_t *)SLOT_ADDRESS(current_slot); - for (int i = 0; i < EEPROM_SIZE; i++) ram_eeprom[i] = eeprom_data[i]; + for (int i = 0; i < MARLIN_EEPROM_SIZE; i++) ram_eeprom[i] = eeprom_data[i]; DEBUG_ECHOLNPAIR("EEPROM loaded from slot ", current_slot, "."); } eeprom_data_written = false; @@ -140,6 +147,11 @@ bool PersistentStore::access_start() { bool PersistentStore::access_finish() { if (eeprom_data_written) { + #ifdef STM32F4xx + // MCU may come up with flash error bits which prevent some flash operations. + // Clear flags prior to flash operations to prevent errors. + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR); + #endif #if ENABLED(FLASH_EEPROM_LEVELING) @@ -160,7 +172,11 @@ bool PersistentStore::access_finish() { current_slot = EEPROM_SLOTS - 1; UNLOCK_FLASH(); + PAUSE_SERVO_OUTPUT(); + DISABLE_ISRS(); status = HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError); + ENABLE_ISRS(); + RESUME_SERVO_OUTPUT(); if (status != HAL_OK) { DEBUG_ECHOLNPAIR("HAL_FLASHEx_Erase=", status); DEBUG_ECHOLNPAIR("GetError=", HAL_FLASH_GetError()); @@ -174,7 +190,7 @@ bool PersistentStore::access_finish() { uint32_t offset = 0; uint32_t address = SLOT_ADDRESS(current_slot); - uint32_t address_end = address + EEPROM_SIZE; + uint32_t address_end = address + MARLIN_EEPROM_SIZE; uint32_t data = 0; bool success = true; @@ -205,7 +221,18 @@ bool PersistentStore::access_finish() { return success; #else + // The following was written for the STM32F4 but may work with other MCUs as well. + // Most STM32F4 flash does not allow reading from flash during erase operations. + // This takes about a second on a STM32F407 with a 128kB sector used as EEPROM. + // Interrupts during this time can have unpredictable results, such as killing Servo + // output. Servo output still glitches with interrupts disabled, but recovers after the + // erase. + PAUSE_SERVO_OUTPUT(); + DISABLE_ISRS(); eeprom_buffer_flush(); + ENABLE_ISRS(); + RESUME_SERVO_OUTPUT(); + eeprom_data_written = false; #endif } @@ -236,13 +263,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) { do { - const uint8_t c = ( - #if ENABLED(FLASH_EEPROM_LEVELING) - ram_eeprom[pos] - #else - eeprom_buffered_read_byte(pos) - #endif - ); + const uint8_t c = TERN(FLASH_EEPROM_LEVELING, ram_eeprom[pos], eeprom_buffered_read_byte(pos)); if (writing) *value = c; crc16(crc, &c, 1); pos++; @@ -251,15 +272,5 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t return false; } -size_t PersistentStore::capacity() { - return ( - #if ENABLED(FLASH_EEPROM_LEVELING) - EEPROM_SIZE - #else - E2END + 1 - #endif - ); -} - -#endif // EEPROM_SETTINGS && FLASH_EEPROM_EMULATION +#endif // FLASH_EEPROM_EMULATION #endif // ARDUINO_ARCH_STM32 && !STM32GENERIC diff --git a/Marlin/src/HAL/HAL_STM32/persistent_store_sdcard.cpp b/Marlin/src/HAL/STM32/eeprom_sdcard.cpp similarity index 52% rename from Marlin/src/HAL/HAL_STM32/persistent_store_sdcard.cpp rename to Marlin/src/HAL/STM32/eeprom_sdcard.cpp index 2df90d23288e..711a83ed5b6a 100644 --- a/Marlin/src/HAL/HAL_STM32/persistent_store_sdcard.cpp +++ b/Marlin/src/HAL/STM32/eeprom_sdcard.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -28,56 +28,47 @@ #include "../../inc/MarlinConfig.h" -#if ENABLED(EEPROM_SETTINGS) && NONE(FLASH_EEPROM_EMULATION, SRAM_EEPROM_EMULATION, SPI_EEPROM, I2C_EEPROM) +#if ENABLED(SDCARD_EEPROM_EMULATION) -#include "../shared/persistent_store_api.h" +#include "../shared/eeprom_api.h" +#include "../../sd/cardreader.h" -#ifndef E2END - #define E2END 0xFFF // 4KB +#define EEPROM_FILENAME "eeprom.dat" + +#ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE 0x1000 // 4KB #endif -#define HAL_EEPROM_SIZE int(E2END + 1) +size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } #define _ALIGN(x) __attribute__ ((aligned(x))) -static char _ALIGN(4) HAL_eeprom_data[HAL_EEPROM_SIZE]; - -#if ENABLED(SDSUPPORT) +static char _ALIGN(4) HAL_eeprom_data[MARLIN_EEPROM_SIZE]; - #include "../../sd/cardreader.h" +bool PersistentStore::access_start() { + if (!card.isMounted()) return false; - #define EEPROM_FILENAME "eeprom.dat" + SdFile file, root = card.getroot(); + if (!file.open(&root, EEPROM_FILENAME, O_RDONLY)) + return true; - bool PersistentStore::access_start() { - if (!card.isMounted()) return false; + int bytes_read = file.read(HAL_eeprom_data, MARLIN_EEPROM_SIZE); + if (bytes_read < 0) return false; + for (; bytes_read < MARLIN_EEPROM_SIZE; bytes_read++) + HAL_eeprom_data[bytes_read] = 0xFF; + file.close(); + return true; +} - SdFile file, root = card.getroot(); - if (!file.open(&root, EEPROM_FILENAME, O_RDONLY)) - return true; +bool PersistentStore::access_finish() { + if (!card.isMounted()) return false; - int bytes_read = file.read(HAL_eeprom_data, HAL_EEPROM_SIZE); - if (bytes_read < 0) return false; - for (; bytes_read < HAL_EEPROM_SIZE; bytes_read++) - HAL_eeprom_data[bytes_read] = 0xFF; + SdFile file, root = card.getroot(); + int bytes_written = 0; + if (file.open(&root, EEPROM_FILENAME, O_CREAT | O_WRITE | O_TRUNC)) { + bytes_written = file.write(HAL_eeprom_data, MARLIN_EEPROM_SIZE); file.close(); - return true; } - - bool PersistentStore::access_finish() { - if (!card.isMounted()) return false; - - SdFile file, root = card.getroot(); - int bytes_written = 0; - if (file.open(&root, EEPROM_FILENAME, O_CREAT | O_WRITE | O_TRUNC)) { - bytes_written = file.write(HAL_eeprom_data, HAL_EEPROM_SIZE); - file.close(); - } - return (bytes_written == HAL_EEPROM_SIZE); - } - -#else // !SDSUPPORT - - #error "Please define an EEPROM, a SDCARD or disable EEPROM_SETTINGS." - -#endif // !SDSUPPORT + return (bytes_written == MARLIN_EEPROM_SIZE); +} bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { for (size_t i = 0; i < size; i++) @@ -97,7 +88,5 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, const size_t size, uin return false; } -size_t PersistentStore::capacity() { return HAL_EEPROM_SIZE; } - -#endif // EEPROM_SETTINGS -#endif // STM32 +#endif // SDCARD_EEPROM_EMULATION +#endif // STM32 && !STM32GENERIC diff --git a/Marlin/src/HAL/STM32/eeprom_sram.cpp b/Marlin/src/HAL/STM32/eeprom_sram.cpp new file mode 100644 index 000000000000..5f6f26f9c61b --- /dev/null +++ b/Marlin/src/HAL/STM32/eeprom_sram.cpp @@ -0,0 +1,68 @@ +/** + * Marlin 3D Printer Firmware + * + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com + * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com + * Copyright (c) 2016 Victor Perez victor_pv@hotmail.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC) + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(SRAM_EEPROM_EMULATION) + +#include "../shared/eeprom_if.h" +#include "../shared/eeprom_api.h" + +#ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE 0x1000 // 4KB +#endif +size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } + +bool PersistentStore::access_start() { return true; } +bool PersistentStore::access_finish() { return true; } + +bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { + while (size--) { + uint8_t v = *value; + + // Save to Backup SRAM + *(__IO uint8_t *)(BKPSRAM_BASE + (uint8_t * const)pos) = v; + + crc16(crc, &v, 1); + pos++; + value++; + }; + + return false; +} + +bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) { + do { + // Read from either external EEPROM, program flash or Backup SRAM + const uint8_t c = ( *(__IO uint8_t *)(BKPSRAM_BASE + ((uint8_t*)pos)) ); + if (writing) *value = c; + crc16(crc, &c, 1); + pos++; + value++; + } while (--size); + return false; +} + +#endif // SRAM_EEPROM_EMULATION +#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC diff --git a/Marlin/src/HAL/STM32/eeprom_wired.cpp b/Marlin/src/HAL/STM32/eeprom_wired.cpp new file mode 100644 index 000000000000..8c46e45f0324 --- /dev/null +++ b/Marlin/src/HAL/STM32/eeprom_wired.cpp @@ -0,0 +1,81 @@ +/** + * Marlin 3D Printer Firmware + * + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com + * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com + * Copyright (c) 2016 Victor Perez victor_pv@hotmail.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC) + +#include "../../inc/MarlinConfig.h" + +#if USE_WIRED_EEPROM + +/** + * PersistentStore for Arduino-style EEPROM interface + * with simple implementations supplied by Marlin. + */ + +#include "../shared/eeprom_if.h" +#include "../shared/eeprom_api.h" + +#ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE size_t(E2END + 1) +#endif +size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } + +bool PersistentStore::access_start() { eeprom_init(); return true; } +bool PersistentStore::access_finish() { return true; } + +bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { + while (size--) { + uint8_t v = *value; + + // EEPROM has only ~100,000 write cycles, + // so only write bytes that have changed! + uint8_t * const p = (uint8_t * const)pos; + if (v != eeprom_read_byte(p)) { + eeprom_write_byte(p, v); + if (eeprom_read_byte(p) != v) { + SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE); + return true; + } + } + + crc16(crc, &v, 1); + pos++; + value++; + }; + + return false; +} + +bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) { + do { + // Read from either external EEPROM, program flash or Backup SRAM + const uint8_t c = eeprom_read_byte((uint8_t*)pos); + if (writing) *value = c; + crc16(crc, &c, 1); + pos++; + value++; + } while (--size); + return false; +} + +#endif // USE_WIRED_EEPROM +#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC diff --git a/Marlin/src/HAL/STM32/endstop_interrupts.h b/Marlin/src/HAL/STM32/endstop_interrupts.h new file mode 100644 index 000000000000..fdff8cc644cd --- /dev/null +++ b/Marlin/src/HAL/STM32/endstop_interrupts.h @@ -0,0 +1,49 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * Copyright (c) 2017 Victor Perez + * + * 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 . + * + */ +#pragma once + +#include "../../module/endstops.h" + +// One ISR for all EXT-Interrupts +void endstop_ISR() { endstops.update(); } + +void setup_endstop_interrupts() { + #define _ATTACH(P) attachInterrupt(P, endstop_ISR, CHANGE) + TERN_(HAS_X_MAX, _ATTACH(X_MAX_PIN)); + TERN_(HAS_X_MIN, _ATTACH(X_MIN_PIN)); + TERN_(HAS_Y_MAX, _ATTACH(Y_MAX_PIN)); + TERN_(HAS_Y_MIN, _ATTACH(Y_MIN_PIN)); + TERN_(HAS_Z_MAX, _ATTACH(Z_MAX_PIN)); + TERN_(HAS_Z_MIN, _ATTACH(Z_MIN_PIN)); + TERN_(HAS_X2_MAX, _ATTACH(X2_MAX_PIN)); + TERN_(HAS_X2_MIN, _ATTACH(X2_MIN_PIN)); + TERN_(HAS_Y2_MAX, _ATTACH(Y2_MAX_PIN)); + TERN_(HAS_Y2_MIN, _ATTACH(Y2_MIN_PIN)); + TERN_(HAS_Z2_MAX, _ATTACH(Z2_MAX_PIN)); + TERN_(HAS_Z2_MIN, _ATTACH(Z2_MIN_PIN)); + TERN_(HAS_Z3_MAX, _ATTACH(Z3_MAX_PIN)); + TERN_(HAS_Z3_MIN, _ATTACH(Z3_MIN_PIN)); + TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN)); + TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN)); + TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN)); +} diff --git a/Marlin/src/HAL/HAL_STM32/fastio.cpp b/Marlin/src/HAL/STM32/fastio.cpp similarity index 89% rename from Marlin/src/HAL/HAL_STM32/fastio.cpp rename to Marlin/src/HAL/STM32/fastio.cpp index 4c8b63fa1039..0d55579d8886 100644 --- a/Marlin/src/HAL/HAL_STM32/fastio.cpp +++ b/Marlin/src/HAL/STM32/fastio.cpp @@ -17,7 +17,7 @@ * 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 . + * along with this program. If not, see . * */ #if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC) @@ -27,7 +27,7 @@ GPIO_TypeDef* FastIOPortMap[LastPort + 1]; void FastIO_init() { - for (uint8_t i = 0; i < NUM_DIGITAL_PINS; i++) + LOOP_L_N(i, NUM_DIGITAL_PINS) FastIOPortMap[STM_PORT(digitalPin[i])] = get_GPIO_Port(STM_PORT(digitalPin[i])); } diff --git a/Marlin/src/HAL/HAL_STM32/fastio.h b/Marlin/src/HAL/STM32/fastio.h similarity index 72% rename from Marlin/src/HAL/HAL_STM32/fastio.h rename to Marlin/src/HAL/STM32/fastio.h index fa94d4703cfe..ea28b8f3bfaa 100644 --- a/Marlin/src/HAL/HAL_STM32/fastio.h +++ b/Marlin/src/HAL/STM32/fastio.h @@ -17,7 +17,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -51,29 +51,31 @@ void FastIO_init(); // Must be called before using fast io macros #if defined(STM32F0xx) || defined(STM32F1xx) || defined(STM32F3xx) || defined(STM32L0xx) || defined(STM32L4xx) #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])) ; \ + if (V) FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->BSRR = _BV32(STM_PIN(digitalPinToPinName(IO))) ; \ + else FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->BRR = _BV32(STM_PIN(digitalPinToPinName(IO))) ; \ }while(0) #else - #define _WRITE(IO, V) (FastIOPortMap[STM_PORT(digitalPin[IO])]->BSRR = _BV32(STM_PIN(digitalPin[IO]) + (V ? 0 : 16))) + #define _WRITE(IO, V) (FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->BSRR = _BV32(STM_PIN(digitalPinToPinName(IO)) + ((V) ? 0 : 16))) #endif -#define _READ(IO) bool(READ_BIT(FastIOPortMap[STM_PORT(digitalPin[IO])]->IDR, _BV32(STM_PIN(digitalPin[IO])))) -#define _TOGGLE(IO) (FastIOPortMap[STM_PORT(digitalPin[IO])]->ODR ^= _BV32(STM_PIN(digitalPin[IO]))) +#define _READ(IO) bool(READ_BIT(FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->IDR, _BV32(STM_PIN(digitalPinToPinName(IO))))) +#define _TOGGLE(IO) (FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->ODR ^= _BV32(STM_PIN(digitalPinToPinName(IO)))) #define _GET_MODE(IO) #define _SET_MODE(IO,M) pinMode(IO, M) -#define _SET_OUTPUT(IO) pinMode(IO, OUTPUT) /*!< Output Push Pull Mode & GPIO_NOPULL */ +#define _SET_OUTPUT(IO) pinMode(IO, OUTPUT) //!< Output Push Pull Mode & GPIO_NOPULL +#define _SET_OUTPUT_OD(IO) pinMode(IO, OUTPUT_OPEN_DRAIN) #define WRITE(IO,V) _WRITE(IO,V) #define READ(IO) _READ(IO) #define TOGGLE(IO) _TOGGLE(IO) #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, INPUT) /*!< Input Floating Mode */ -#define SET_INPUT_PULLUP(IO) _SET_MODE(IO, INPUT_PULLUP) /*!< Input with Pull-up activation */ -#define SET_INPUT_PULLDOWN(IO) _SET_MODE(IO, INPUT_PULLDOWN) /*!< Input with Pull-down activation */ +#define SET_INPUT(IO) _SET_MODE(IO, INPUT) //!< Input Floating Mode +#define SET_INPUT_PULLUP(IO) _SET_MODE(IO, INPUT_PULLUP) //!< Input with Pull-up activation +#define SET_INPUT_PULLDOWN(IO) _SET_MODE(IO, INPUT_PULLDOWN) //!< Input with Pull-down activation #define SET_OUTPUT(IO) OUT_WRITE(IO, LOW) #define SET_PWM(IO) _SET_MODE(IO, PWM) @@ -81,6 +83,7 @@ void FastIO_init(); // Must be called before using fast io macros #define IS_OUTPUT(IO) #define PWM_PIN(P) digitalPinHasPWM(P) +#define NO_COMPILE_TIME_PWM // digitalRead/Write wrappers #define extDigitalRead(IO) digitalRead(IO) diff --git a/Marlin/src/HAL/HAL_ESP32/inc/Conditionals_LCD.h b/Marlin/src/HAL/STM32/inc/Conditionals_LCD.h similarity index 91% rename from Marlin/src/HAL/HAL_ESP32/inc/Conditionals_LCD.h rename to Marlin/src/HAL/STM32/inc/Conditionals_LCD.h index 0285c52ee365..5f1c4b16019d 100644 --- a/Marlin/src/HAL/HAL_ESP32/inc/Conditionals_LCD.h +++ b/Marlin/src/HAL/STM32/inc/Conditionals_LCD.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/STM32/inc/Conditionals_adv.h b/Marlin/src/HAL/STM32/inc/Conditionals_adv.h new file mode 100644 index 000000000000..5f1c4b16019d --- /dev/null +++ b/Marlin/src/HAL/STM32/inc/Conditionals_adv.h @@ -0,0 +1,22 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once diff --git a/Marlin/src/HAL/STM32/inc/Conditionals_post.h b/Marlin/src/HAL/STM32/inc/Conditionals_post.h new file mode 100644 index 000000000000..18826e11d24a --- /dev/null +++ b/Marlin/src/HAL/STM32/inc/Conditionals_post.h @@ -0,0 +1,29 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +// If no real or emulated EEPROM selected, fall back to SD emulation +#if USE_FALLBACK_EEPROM + #define SDCARD_EEPROM_EMULATION +#elif EITHER(I2C_EEPROM, SPI_EEPROM) + #define USE_SHARED_EEPROM 1 +#endif diff --git a/Marlin/src/HAL/STM32/inc/SanityCheck.h b/Marlin/src/HAL/STM32/inc/SanityCheck.h new file mode 100644 index 000000000000..30d0750d90e0 --- /dev/null +++ b/Marlin/src/HAL/STM32/inc/SanityCheck.h @@ -0,0 +1,56 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * Test STM32-specific configuration values for errors at compile-time. + */ +//#if ENABLED(SPINDLE_LASER_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11) +// #error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector" +//#endif + +#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY + #error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on STM32." +#endif + +#if ENABLED(SDCARD_EEPROM_EMULATION) && DISABLED(SDSUPPORT) + #undef SDCARD_EEPROM_EMULATION // Avoid additional error noise + #if USE_FALLBACK_EEPROM + #warning "EEPROM type not specified. Fallback is SDCARD_EEPROM_EMULATION." + #endif + #error "SDCARD_EEPROM_EMULATION requires SDSUPPORT. Enable SDSUPPORT or choose another EEPROM emulation." +#endif + +#if defined(STM32F4xx) && BOTH(PRINTCOUNTER, FLASH_EEPROM_EMULATION) + #warning "FLASH_EEPROM_EMULATION may cause long delays when writing and should not be used while printing." + #error "Disable PRINTCOUNTER or choose another EEPROM emulation." +#endif + +#if !defined(STM32F4xx) && ENABLED(FLASH_EEPROM_LEVELING) + #error "FLASH_EEPROM_LEVELING is currently only supported on STM32F4 hardware." +#endif + +#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) + #error "SERIAL_STATS_MAX_RX_QUEUED is not supported on this platform." +#elif ENABLED(SERIAL_STATS_DROPPED_RX) + #error "SERIAL_STATS_DROPPED_RX is not supported on this platform." +#endif diff --git a/Marlin/src/HAL/HAL_STM32/pinsDebug.h b/Marlin/src/HAL/STM32/pinsDebug.h similarity index 94% rename from Marlin/src/HAL/HAL_STM32/pinsDebug.h rename to Marlin/src/HAL/STM32/pinsDebug.h index 8c5d1ec2b61e..ec08e3fd753f 100644 --- a/Marlin/src/HAL/HAL_STM32/pinsDebug.h +++ b/Marlin/src/HAL/STM32/pinsDebug.h @@ -13,7 +13,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_STM32/pinsDebug_STM32GENERIC.h b/Marlin/src/HAL/STM32/pinsDebug_STM32GENERIC.h similarity index 94% rename from Marlin/src/HAL/HAL_STM32/pinsDebug_STM32GENERIC.h rename to Marlin/src/HAL/STM32/pinsDebug_STM32GENERIC.h index 43f430a48f9d..9069d9f7bd8a 100644 --- a/Marlin/src/HAL/HAL_STM32/pinsDebug_STM32GENERIC.h +++ b/Marlin/src/HAL/STM32/pinsDebug_STM32GENERIC.h @@ -13,7 +13,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -29,9 +29,9 @@ #ifdef BOARD_NR_GPIO_PINS // Only in STM32GENERIC (Maple) #ifdef __STM32F1__ - #include "../HAL_STM32F1/fastio.h" + #include "../STM32F1/fastio.h" #elif defined(STM32F4) || defined(STM32F7) - #include "../HAL_STM32_F4_F7/fastio.h" + #include "../STM32_F4_F7/fastio.h" #else #include "fastio.h" #endif @@ -98,7 +98,7 @@ static inline void pwm_details(const pin_t pin) { timer_dev * const tdev = PIN_MAP[pin].timer_device; const uint8_t channel = PIN_MAP[pin].timer_channel; const char num = ( - #if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) + #if EITHER(STM32_HIGH_DENSITY, STM32_XL_DENSITY) tdev == &timer8 ? '8' : tdev == &timer5 ? '5' : #endif diff --git a/Marlin/src/HAL/HAL_STM32/pinsDebug_STM32duino.h b/Marlin/src/HAL/STM32/pinsDebug_STM32duino.h similarity index 96% rename from Marlin/src/HAL/HAL_STM32/pinsDebug_STM32duino.h rename to Marlin/src/HAL/STM32/pinsDebug_STM32duino.h index 58b8c32cc76c..71480153a717 100644 --- a/Marlin/src/HAL/HAL_STM32/pinsDebug_STM32duino.h +++ b/Marlin/src/HAL/STM32/pinsDebug_STM32duino.h @@ -13,7 +13,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -51,8 +51,8 @@ * It contains: * - name of the signal * - the Ard_num assigned by the pins_YOUR_BOARD.h file using the platform defines. - * EXAMPLE: "#define KILL_PIN PB1" results in Ard_num of 57. 57 is then used as an - * index into digitalPin[] to get the Port_pin number + * EXAMPLE: "#define KILL_PIN PB1" results in Ard_num of 57. 57 is then used as the + * argument to digitalPinToPinName(IO) to get the Port_pin number * - if it is a digital or analog signal. PWMs are considered digital here. * * pin_xref is a structure generated by this header file. It is generated by the @@ -68,8 +68,6 @@ * signal. The Arduino pin number is listed by the M43 I command. */ -extern const PinName digitalPin[]; // provided by the platform - //////////////////////////////////////////////////////// // // make a list of the Arduino pin numbers in the Port/Pin order @@ -137,7 +135,7 @@ const XrefInfo pin_xref[] PROGMEM = { uint8_t get_pin_mode(const pin_t Ard_num) { uint32_t mode_all = 0; - const PinName dp = digitalPin[Ard_num]; + const PinName dp = digitalPinToPinName(Ard_num); switch (PORT_ALPHA(dp)) { case 'A' : mode_all = GPIOA->MODER; break; case 'B' : mode_all = GPIOB->MODER; break; @@ -218,7 +216,7 @@ bool pwm_status(const pin_t Ard_num) { void pwm_details(const pin_t Ard_num) { if (pwm_status(Ard_num)) { uint32_t alt_all = 0; - const PinName dp = digitalPin[Ard_num]; + const PinName dp = digitalPinToPinName(Ard_num); pin_t pin_number = uint8_t(PIN_NUM(dp)); const bool over_7 = pin_number >= 8; const uint8_t ind = over_7 ? 1 : 0; diff --git a/Marlin/src/HAL/HAL_STM32/pins_Xref.h b/Marlin/src/HAL/STM32/pins_Xref.h similarity index 99% rename from Marlin/src/HAL/HAL_STM32/pins_Xref.h rename to Marlin/src/HAL/STM32/pins_Xref.h index 7e88ec76ba4b..890e561860e2 100644 --- a/Marlin/src/HAL/HAL_STM32/pins_Xref.h +++ b/Marlin/src/HAL/STM32/pins_Xref.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/HAL/HAL_STM32/spi_pins.h b/Marlin/src/HAL/STM32/spi_pins.h similarity index 92% rename from Marlin/src/HAL/HAL_STM32/spi_pins.h rename to Marlin/src/HAL/STM32/spi_pins.h index 8f46ca12c5fd..176e2a7b2063 100644 --- a/Marlin/src/HAL/HAL_STM32/spi_pins.h +++ b/Marlin/src/HAL/STM32/spi_pins.h @@ -13,7 +13,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/STM32/tft/tft_fsmc.cpp b/Marlin/src/HAL/STM32/tft/tft_fsmc.cpp new file mode 100644 index 000000000000..3a080d5e271e --- /dev/null +++ b/Marlin/src/HAL/STM32/tft/tft_fsmc.cpp @@ -0,0 +1,180 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfig.h" + +#if HAS_FSMC_TFT + +#include "tft_fsmc.h" +#include "pinconfig.h" + +SRAM_HandleTypeDef TFT_FSMC::SRAMx; +DMA_HandleTypeDef TFT_FSMC::DMAtx; +LCD_CONTROLLER_TypeDef *TFT_FSMC::LCD; + +void TFT_FSMC::Init() { + uint32_t controllerAddress; + + #if PIN_EXISTS(TFT_RESET) + OUT_WRITE(TFT_RESET_PIN, HIGH); + HAL_Delay(100); + #endif + + #if PIN_EXISTS(TFT_BACKLIGHT) + OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH); + #endif + + FSMC_NORSRAM_TimingTypeDef Timing, ExtTiming; + + uint32_t NSBank = (uint32_t)pinmap_peripheral(digitalPinToPinName(TFT_CS_PIN), PinMap_FSMC_CS); + + SRAMx.Instance = FSMC_NORSRAM_DEVICE; + SRAMx.Extended = FSMC_NORSRAM_EXTENDED_DEVICE; + /* SRAMx.Init */ + SRAMx.Init.NSBank = NSBank; + SRAMx.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE; + SRAMx.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM; + SRAMx.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16; + SRAMx.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE; + SRAMx.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW; + SRAMx.Init.WrapMode = FSMC_WRAP_MODE_DISABLE; + SRAMx.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS; + SRAMx.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE; + SRAMx.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE; + SRAMx.Init.ExtendedMode = FSMC_EXTENDED_MODE_ENABLE; + SRAMx.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE; + SRAMx.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE; + #ifdef STM32F4xx + SRAMx.Init.PageSize = FSMC_PAGE_SIZE_NONE; + #endif + /* Read Timing - relatively slow to ensure ID information is correctly read from TFT controller */ + /* Can be decreases from 15-15-24 to 4-4-8 with risk of stability loss */ + Timing.AddressSetupTime = 15; + Timing.AddressHoldTime = 15; + Timing.DataSetupTime = 24; + Timing.BusTurnAroundDuration = 0; + Timing.CLKDivision = 16; + Timing.DataLatency = 17; + Timing.AccessMode = FSMC_ACCESS_MODE_A; + /* Write Timing */ + /* Can be decreases from 8-15-8 to 0-0-1 with risk of stability loss */ + ExtTiming.AddressSetupTime = 8; + ExtTiming.AddressHoldTime = 15; + ExtTiming.DataSetupTime = 8; + ExtTiming.BusTurnAroundDuration = 0; + ExtTiming.CLKDivision = 16; + ExtTiming.DataLatency = 17; + ExtTiming.AccessMode = FSMC_ACCESS_MODE_A; + + __HAL_RCC_FSMC_CLK_ENABLE(); + + for (uint16_t i = 0; PinMap_FSMC[i].pin != NC; i++) + pinmap_pinout(PinMap_FSMC[i].pin, PinMap_FSMC); + pinmap_pinout(digitalPinToPinName(TFT_CS_PIN), PinMap_FSMC_CS); + pinmap_pinout(digitalPinToPinName(TFT_RS_PIN), PinMap_FSMC_RS); + + controllerAddress = FSMC_BANK1_1; + #ifdef PF0 + switch (NSBank) { + case FSMC_NORSRAM_BANK2: controllerAddress = FSMC_BANK1_2 ; break; + case FSMC_NORSRAM_BANK3: controllerAddress = FSMC_BANK1_3 ; break; + case FSMC_NORSRAM_BANK4: controllerAddress = FSMC_BANK1_4 ; break; + } + #endif + + controllerAddress |= (uint32_t)pinmap_peripheral(digitalPinToPinName(TFT_RS_PIN), PinMap_FSMC_RS); + + HAL_SRAM_Init(&SRAMx, &Timing, &ExtTiming); + + __HAL_RCC_DMA2_CLK_ENABLE(); + + #ifdef STM32F1xx + DMAtx.Instance = DMA2_Channel1; + #elif defined(STM32F4xx) + DMAtx.Instance = DMA2_Stream0; + DMAtx.Init.Channel = DMA_CHANNEL_0; + DMAtx.Init.FIFOMode = DMA_FIFOMODE_ENABLE; + DMAtx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; + DMAtx.Init.MemBurst = DMA_MBURST_SINGLE; + DMAtx.Init.PeriphBurst = DMA_PBURST_SINGLE; + #endif + + DMAtx.Init.Direction = DMA_MEMORY_TO_MEMORY; + DMAtx.Init.MemInc = DMA_MINC_DISABLE; + DMAtx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; + DMAtx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; + DMAtx.Init.Mode = DMA_NORMAL; + DMAtx.Init.Priority = DMA_PRIORITY_HIGH; + + LCD = (LCD_CONTROLLER_TypeDef *)controllerAddress; +} + +uint32_t TFT_FSMC::GetID() { + uint32_t id; + WriteReg(0x0000); + id = LCD->RAM; + + if (id == 0) + id = ReadID(LCD_READ_ID); + if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF) + id = ReadID(LCD_READ_ID4); + return id; +} + + uint32_t TFT_FSMC::ReadID(uint16_t Reg) { + uint32_t id; + WriteReg(Reg); + id = LCD->RAM; // dummy read + id = Reg << 24; + id |= (LCD->RAM & 0x00FF) << 16; + id |= (LCD->RAM & 0x00FF) << 8; + id |= LCD->RAM & 0x00FF; + return id; + } + +bool TFT_FSMC::isBusy() { + if (__IS_DMA_ENABLED(&DMAtx)) + if (__HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TC_FLAG_INDEX(&DMAtx)) != 0 || __HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TE_FLAG_INDEX(&DMAtx)) != 0) + Abort(); + return __IS_DMA_ENABLED(&DMAtx); +} + +void TFT_FSMC::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) { + DMAtx.Init.PeriphInc = MemoryIncrease; + HAL_DMA_Init(&DMAtx); + + __HAL_DMA_CLEAR_FLAG(&DMAtx, __HAL_DMA_GET_TC_FLAG_INDEX(&DMAtx)); + __HAL_DMA_CLEAR_FLAG(&DMAtx, __HAL_DMA_GET_TE_FLAG_INDEX(&DMAtx)); + + #ifdef STM32F1xx + DMAtx.Instance->CNDTR = Count; + DMAtx.Instance->CPAR = (uint32_t)Data; + DMAtx.Instance->CMAR = (uint32_t)&(LCD->RAM); + #elif defined(STM32F4xx) + DMAtx.Instance->NDTR = Count; + DMAtx.Instance->PAR = (uint32_t)Data; + DMAtx.Instance->M0AR = (uint32_t)&(LCD->RAM); + #endif + __HAL_DMA_ENABLE(&DMAtx); +} + +#endif // HAS_FSMC_TFT diff --git a/Marlin/src/HAL/STM32/tft/tft_fsmc.h b/Marlin/src/HAL/STM32/tft/tft_fsmc.h new file mode 100644 index 000000000000..cbec7613ef4a --- /dev/null +++ b/Marlin/src/HAL/STM32/tft/tft_fsmc.h @@ -0,0 +1,160 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef STM32F1xx + #include "stm32f1xx_hal.h" +#elif defined(STM32F4xx) + #include "stm32f4xx_hal.h" +#else + #error FSMC TFT is currently only supported on STM32F1 and STM32F4 hardware. +#endif + +#ifndef LCD_READ_ID + #define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341) +#endif +#ifndef LCD_READ_ID4 + #define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341) +#endif + +#define DATASIZE_8BIT SPI_DATASIZE_8BIT +#define DATASIZE_16BIT SPI_DATASIZE_16BIT +#define TFT_IO_DRIVER TFT_FSMC + +#ifdef STM32F1xx + #define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CCR & DMA_CCR_EN) +#elif defined(STM32F4xx) + #define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CR & DMA_SxCR_EN) +#endif + +typedef struct { + __IO uint16_t REG; + __IO uint16_t RAM; +} LCD_CONTROLLER_TypeDef; + +class TFT_FSMC { + private: + static SRAM_HandleTypeDef SRAMx; + static DMA_HandleTypeDef DMAtx; + + static LCD_CONTROLLER_TypeDef *LCD; + + static uint32_t ReadID(uint16_t Reg); + static void Transmit(uint16_t Data) { LCD->RAM = Data; __DSB(); } + static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count); + + public: + static void Init(); + static uint32_t GetID(); + static bool isBusy(); + static void Abort() { __HAL_DMA_DISABLE(&DMAtx); } + + static void DataTransferBegin(uint16_t DataWidth = DATASIZE_16BIT) {} + static void DataTransferEnd() {}; + + static void WriteData(uint16_t Data) { Transmit(Data); } + static void WriteReg(uint16_t Reg) { LCD->REG = Reg; __DSB(); } + + static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_PINC_ENABLE, Data, Count); } + static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_PINC_DISABLE, &Data, Count); } +}; + + +#ifdef STM32F1xx + #define FSMC_PIN_DATA STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, AFIO_NONE) +#elif defined(STM32F4xx) + #define FSMC_PIN_DATA STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FSMC) + #define FSMC_BANK1_1 0x60000000U + #define FSMC_BANK1_2 0x64000000U + #define FSMC_BANK1_3 0x68000000U + #define FSMC_BANK1_4 0x6C000000U +#else + #error No configuration for this MCU +#endif + +const PinMap PinMap_FSMC[] = { + {PD_14, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D00 + {PD_15, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D01 + {PD_0, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D02 + {PD_1, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D03 + {PE_7, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D04 + {PE_8, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D05 + {PE_9, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D06 + {PE_10, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D07 + {PE_11, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D08 + {PE_12, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D09 + {PE_13, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D10 + {PE_14, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D11 + {PE_15, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D12 + {PD_8, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D13 + {PD_9, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D14 + {PD_10, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D15 + {PD_4, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_NOE + {PD_5, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_NWE + {NC, NP, 0} +}; + +const PinMap PinMap_FSMC_CS[] = { + {PD_7, (void *)FSMC_NORSRAM_BANK1, FSMC_PIN_DATA}, // FSMC_NE1 + #ifdef PF0 + {PG_9, (void *)FSMC_NORSRAM_BANK2, FSMC_PIN_DATA}, // FSMC_NE2 + {PG_10, (void *)FSMC_NORSRAM_BANK3, FSMC_PIN_DATA}, // FSMC_NE3 + {PG_12, (void *)FSMC_NORSRAM_BANK4, FSMC_PIN_DATA}, // FSMC_NE4 + #endif + {NC, NP, 0} +}; + +#define FSMC_RS(A) (void *)((2 << A) - 2) + +const PinMap PinMap_FSMC_RS[] = { + #ifdef PF0 + {PF_0, FSMC_RS( 0), FSMC_PIN_DATA}, // FSMC_A0 + {PF_1, FSMC_RS( 1), FSMC_PIN_DATA}, // FSMC_A1 + {PF_2, FSMC_RS( 2), FSMC_PIN_DATA}, // FSMC_A2 + {PF_3, FSMC_RS( 3), FSMC_PIN_DATA}, // FSMC_A3 + {PF_4, FSMC_RS( 4), FSMC_PIN_DATA}, // FSMC_A4 + {PF_5, FSMC_RS( 5), FSMC_PIN_DATA}, // FSMC_A5 + {PF_12, FSMC_RS( 6), FSMC_PIN_DATA}, // FSMC_A6 + {PF_13, FSMC_RS( 7), FSMC_PIN_DATA}, // FSMC_A7 + {PF_14, FSMC_RS( 8), FSMC_PIN_DATA}, // FSMC_A8 + {PF_15, FSMC_RS( 9), FSMC_PIN_DATA}, // FSMC_A9 + {PG_0, FSMC_RS(10), FSMC_PIN_DATA}, // FSMC_A10 + {PG_1, FSMC_RS(11), FSMC_PIN_DATA}, // FSMC_A11 + {PG_2, FSMC_RS(12), FSMC_PIN_DATA}, // FSMC_A12 + {PG_3, FSMC_RS(13), FSMC_PIN_DATA}, // FSMC_A13 + {PG_4, FSMC_RS(14), FSMC_PIN_DATA}, // FSMC_A14 + {PG_5, FSMC_RS(15), FSMC_PIN_DATA}, // FSMC_A15 + #endif + {PD_11, FSMC_RS(16), FSMC_PIN_DATA}, // FSMC_A16 + {PD_12, FSMC_RS(17), FSMC_PIN_DATA}, // FSMC_A17 + {PD_13, FSMC_RS(18), FSMC_PIN_DATA}, // FSMC_A18 + {PE_3, FSMC_RS(19), FSMC_PIN_DATA}, // FSMC_A19 + {PE_4, FSMC_RS(20), FSMC_PIN_DATA}, // FSMC_A20 + {PE_5, FSMC_RS(21), FSMC_PIN_DATA}, // FSMC_A21 + {PE_6, FSMC_RS(22), FSMC_PIN_DATA}, // FSMC_A22 + {PE_2, FSMC_RS(23), FSMC_PIN_DATA}, // FSMC_A23 + #ifdef PF0 + {PG_13, FSMC_RS(24), FSMC_PIN_DATA}, // FSMC_A24 + {PG_14, FSMC_RS(25), FSMC_PIN_DATA}, // FSMC_A25 + #endif + {NC, NP, 0} +}; diff --git a/Marlin/src/HAL/STM32/tft/tft_spi.cpp b/Marlin/src/HAL/STM32/tft/tft_spi.cpp new file mode 100644 index 000000000000..d3eb4ba8db6a --- /dev/null +++ b/Marlin/src/HAL/STM32/tft/tft_spi.cpp @@ -0,0 +1,212 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfig.h" + +#if HAS_SPI_TFT + +#include "tft_spi.h" +#include "pinconfig.h" + +SPI_HandleTypeDef TFT_SPI::SPIx; +DMA_HandleTypeDef TFT_SPI::DMAtx; + +void TFT_SPI::Init() { + SPI_TypeDef *spiInstance; + + #if PIN_EXISTS(TFT_RESET) + OUT_WRITE(TFT_RESET_PIN, HIGH); + HAL_Delay(100); + #endif + + #if PIN_EXISTS(TFT_BACKLIGHT) + OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH); + #endif + + OUT_WRITE(TFT_A0_PIN, HIGH); + OUT_WRITE(TFT_CS_PIN, HIGH); + + if ((spiInstance = (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TFT_SCK_PIN), PinMap_SPI_SCLK)) == NP) return; + if (spiInstance != (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TFT_MOSI_PIN), PinMap_SPI_MOSI)) return; + + #if PIN_EXISTS(TFT_MISO) && (TFT_MISO_PIN != TFT_MOSI_PIN) + if (spiInstance != (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TFT_MISO_PIN), PinMap_SPI_MISO)) return; + #endif + + SPIx.Instance = spiInstance; + SPIx.State = HAL_SPI_STATE_RESET; + SPIx.Init.NSS = SPI_NSS_SOFT; + SPIx.Init.Mode = SPI_MODE_MASTER; + SPIx.Init.Direction = + #if TFT_MISO_PIN == TFT_MOSI_PIN + SPI_DIRECTION_1LINE; + #else + SPI_DIRECTION_2LINES; + #endif + SPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; + SPIx.Init.CLKPhase = SPI_PHASE_1EDGE; + SPIx.Init.CLKPolarity = SPI_POLARITY_LOW; + SPIx.Init.DataSize = SPI_DATASIZE_8BIT; + SPIx.Init.FirstBit = SPI_FIRSTBIT_MSB; + SPIx.Init.TIMode = SPI_TIMODE_DISABLE; + SPIx.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + SPIx.Init.CRCPolynomial = 10; + + pinmap_pinout(digitalPinToPinName(TFT_SCK_PIN), PinMap_SPI_SCLK); + pinmap_pinout(digitalPinToPinName(TFT_MOSI_PIN), PinMap_SPI_MOSI); + #if PIN_EXISTS(TFT_MISO) && (TFT_MISO_PIN != TFT_MOSI_PIN) + pinmap_pinout(digitalPinToPinName(TFT_MISO_PIN), PinMap_SPI_MISO); + #endif + pin_PullConfig(get_GPIO_Port(STM_PORT(digitalPinToPinName(TFT_SCK_PIN))), STM_LL_GPIO_PIN(digitalPinToPinName(TFT_SCK_PIN)), GPIO_PULLDOWN); + + #ifdef SPI1_BASE + if (SPIx.Instance == SPI1) { + __HAL_RCC_SPI1_CLK_ENABLE(); + __HAL_RCC_DMA1_CLK_ENABLE(); + SPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; + DMAtx.Instance = DMA1_Channel3; + } + #endif + #ifdef SPI2_BASE + if (SPIx.Instance == SPI2) { + __HAL_RCC_SPI2_CLK_ENABLE(); + __HAL_RCC_DMA1_CLK_ENABLE(); + DMAtx.Instance = DMA1_Channel5; + } + #endif + #ifdef SPI3_BASE + if (SPIx.Instance == SPI3) { + __HAL_RCC_SPI3_CLK_ENABLE(); + __HAL_RCC_DMA2_CLK_ENABLE(); + DMAtx.Instance = DMA2_Channel2; + } + #endif + + HAL_SPI_Init(&SPIx); + + DMAtx.Init.Direction = DMA_MEMORY_TO_PERIPH; + DMAtx.Init.PeriphInc = DMA_PINC_DISABLE; + DMAtx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; + DMAtx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; + DMAtx.Init.Mode = DMA_NORMAL; + DMAtx.Init.Priority = DMA_PRIORITY_LOW; +} + +void TFT_SPI::DataTransferBegin(uint16_t DataSize) { + SPIx.Init.DataSize = DataSize == DATASIZE_8BIT ? SPI_DATASIZE_8BIT : SPI_DATASIZE_16BIT; + HAL_SPI_Init(&SPIx); + WRITE(TFT_CS_PIN, LOW); +} + +uint32_t TFT_SPI::GetID() { + uint32_t id; + id = ReadID(LCD_READ_ID); + + if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF) + id = ReadID(LCD_READ_ID4); + return id; +} + +uint32_t TFT_SPI::ReadID(uint16_t Reg) { + #if !PIN_EXISTS(TFT_MISO) + return 0; + #else + uint32_t BaudRatePrescaler = SPIx.Init.BaudRatePrescaler; + uint32_t i, Data = 0; + + SPIx.Init.BaudRatePrescaler = SPIx.Instance == SPI1 ? SPI_BAUDRATEPRESCALER_8 : SPI_BAUDRATEPRESCALER_4; + DataTransferBegin(DATASIZE_8BIT); + WriteReg(Reg); + + if (SPIx.Init.Direction == SPI_DIRECTION_1LINE) SPI_1LINE_RX(&SPIx); + __HAL_SPI_ENABLE(&SPIx); + + for (i = 0; i < 4; i++) { + #if TFT_MISO_PIN != TFT_MOSI_PIN + //if (hspi->Init.Direction == SPI_DIRECTION_2LINES) { + while ((SPIx.Instance->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE) {} + SPIx.Instance->DR = 0; + //} + #endif + while ((SPIx.Instance->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE) {} + Data = (Data << 8) | SPIx.Instance->DR; + } + + __HAL_SPI_DISABLE(&SPIx); + DataTransferEnd(); + + SPIx.Init.BaudRatePrescaler = BaudRatePrescaler; + + return Data >> 7; + #endif +} + +bool TFT_SPI::isBusy() { + if (DMAtx.Instance->CCR & DMA_CCR_EN) + if (__HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TC_FLAG_INDEX(&DMAtx)) != 0 || __HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TE_FLAG_INDEX(&DMAtx)) != 0) + Abort(); + return DMAtx.Instance->CCR & DMA_CCR_EN; +} + +void TFT_SPI::Abort() { + __HAL_DMA_DISABLE(&DMAtx); + DataTransferEnd(); +} + +void TFT_SPI::Transmit(uint16_t Data) { + #if TFT_MISO_PIN == TFT_MOSI_PIN + SPI_1LINE_TX(&SPIx); + #endif + + __HAL_SPI_ENABLE(&SPIx); + + SPIx.Instance->DR = Data; + + while ((SPIx.Instance->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE) {} + while ((SPIx.Instance->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY) {} + + #if TFT_MISO_PIN != TFT_MOSI_PIN + __HAL_SPI_CLEAR_OVRFLAG(&SPIx); /* Clear overrun flag in 2 Lines communication mode because received is not read */ + #endif +} + +void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) { + DMAtx.Init.MemInc = MemoryIncrease; + HAL_DMA_Init(&DMAtx); + + DataTransferBegin(); + + #if TFT_MISO_PIN == TFT_MOSI_PIN + SPI_1LINE_TX(&SPIx); + #endif + + DMAtx.DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << DMAtx.ChannelIndex); + DMAtx.Instance->CNDTR = Count; + DMAtx.Instance->CPAR = (uint32_t)&(SPIx.Instance->DR); + DMAtx.Instance->CMAR = (uint32_t)Data; + __HAL_DMA_ENABLE(&DMAtx); + __HAL_SPI_ENABLE(&SPIx); + + SET_BIT(SPIx.Instance->CR2, SPI_CR2_TXDMAEN); /* Enable Tx DMA Request */ +} + +#endif // HAS_SPI_TFT diff --git a/Marlin/src/HAL/STM32/tft/tft_spi.h b/Marlin/src/HAL/STM32/tft/tft_spi.h new file mode 100644 index 000000000000..d477b58c004d --- /dev/null +++ b/Marlin/src/HAL/STM32/tft/tft_spi.h @@ -0,0 +1,67 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef STM32F1xx + #include "stm32f1xx_hal.h" +#elif defined(STM32F4xx) + #include "stm32f4xx_hal.h" +#else + #error SPI TFT is currently only supported on STM32F1 and STM32F4 hardware. +#endif + +#ifndef LCD_READ_ID + #define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341) +#endif +#ifndef LCD_READ_ID4 + #define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341) +#endif + +#define DATASIZE_8BIT SPI_DATASIZE_8BIT +#define DATASIZE_16BIT SPI_DATASIZE_16BIT +#define TFT_IO_DRIVER TFT_SPI + +class TFT_SPI { +private: + static SPI_HandleTypeDef SPIx; + static DMA_HandleTypeDef DMAtx; + + static uint32_t ReadID(uint16_t Reg); + static void Transmit(uint16_t Data); + static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count); + +public: + static void Init(); + static uint32_t GetID(); + static bool isBusy(); + static void Abort(); + + static void DataTransferBegin(uint16_t DataWidth = DATASIZE_16BIT); + static void DataTransferEnd() { WRITE(TFT_CS_PIN, HIGH); }; + static void DataTransferAbort(); + + static void WriteData(uint16_t Data) { Transmit(Data); } + static void WriteReg(uint16_t Reg) { WRITE(TFT_A0_PIN, LOW); Transmit(Reg); WRITE(TFT_A0_PIN, HIGH); } + + static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_MINC_ENABLE, Data, Count); } + static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &Data, Count); } +}; diff --git a/Marlin/src/HAL/STM32/tft/xpt2046.cpp b/Marlin/src/HAL/STM32/tft/xpt2046.cpp new file mode 100644 index 000000000000..921e377a9f4e --- /dev/null +++ b/Marlin/src/HAL/STM32/tft/xpt2046.cpp @@ -0,0 +1,185 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfig.h" + +#if HAS_TFT_XPT2046 + +#include "xpt2046.h" +#include "pinconfig.h" + +uint16_t delta(uint16_t a, uint16_t b) { return a > b ? a - b : b - a; } + +SPI_HandleTypeDef XPT2046::SPIx; +DMA_HandleTypeDef XPT2046::DMAtx; + +void XPT2046::Init() { + SPI_TypeDef *spiInstance; + + OUT_WRITE(TOUCH_CS_PIN, HIGH); + + #if PIN_EXISTS(TOUCH_INT) + // Optional Pendrive interrupt pin + SET_INPUT(TOUCH_INT_PIN); + #endif + + spiInstance = (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TOUCH_SCK_PIN), PinMap_SPI_SCLK); + if (spiInstance != (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TOUCH_MOSI_PIN), PinMap_SPI_MOSI)) spiInstance = NP; + if (spiInstance != (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TOUCH_MISO_PIN), PinMap_SPI_MISO)) spiInstance = NP; + + SPIx.Instance = spiInstance; + + if (SPIx.Instance) { + SPIx.State = HAL_SPI_STATE_RESET; + SPIx.Init.NSS = SPI_NSS_SOFT; + SPIx.Init.Mode = SPI_MODE_MASTER; + SPIx.Init.Direction = SPI_DIRECTION_2LINES; + SPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; + SPIx.Init.CLKPhase = SPI_PHASE_2EDGE; + SPIx.Init.CLKPolarity = SPI_POLARITY_HIGH; + SPIx.Init.DataSize = SPI_DATASIZE_8BIT; + SPIx.Init.FirstBit = SPI_FIRSTBIT_MSB; + SPIx.Init.TIMode = SPI_TIMODE_DISABLE; + SPIx.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + SPIx.Init.CRCPolynomial = 10; + + pinmap_pinout(digitalPinToPinName(TOUCH_SCK_PIN), PinMap_SPI_SCLK); + pinmap_pinout(digitalPinToPinName(TOUCH_MOSI_PIN), PinMap_SPI_MOSI); + pinmap_pinout(digitalPinToPinName(TOUCH_MISO_PIN), PinMap_SPI_MISO); + + #ifdef SPI1_BASE + if (SPIx.Instance == SPI1) { + __HAL_RCC_SPI1_CLK_ENABLE(); + SPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; + #ifdef STM32F1xx + DMAtx.Instance = DMA1_Channel3; + #elif defined(STM32F4xx) + DMAtx.Instance = DMA2_Stream3; // DMA2_Stream5 + #endif + //SERIAL_ECHO_MSG(" Touch Screen on SPI1"); + } + #endif + #ifdef SPI2_BASE + if (SPIx.Instance == SPI2) { + __HAL_RCC_SPI2_CLK_ENABLE(); + #ifdef STM32F1xx + DMAtx.Instance = DMA1_Channel5; + #elif defined(STM32F4xx) + DMAtx.Instance = DMA1_Stream4; + #endif + //SERIAL_ECHO_MSG(" Touch Screen on SPI2"); + } + #endif + #ifdef SPI3_BASE + if (SPIx.Instance == SPI3) { + __HAL_RCC_SPI3_CLK_ENABLE(); + #ifdef STM32F1xx + DMAtx.Instance = DMA2_Channel2; + #elif defined(STM32F4xx) + DMAtx.Instance = DMA1_Stream5; // DMA1_Stream7 + #endif + //SERIAL_ECHO_MSG(" Touch Screen on SPI3"); + } + #endif + } + else { + SPIx.Instance = NULL; + SET_INPUT(TOUCH_MISO_PIN); + SET_OUTPUT(TOUCH_MOSI_PIN); + SET_OUTPUT(TOUCH_SCK_PIN); + //SERIAL_ECHO_MSG(" Touch Screen on Software SPI"); + } + + getRawData(XPT2046_Z1); +} + +bool XPT2046::isTouched() { + return isBusy() ? false : ( + #if PIN_EXISTS(TOUCH_INT) + READ(TOUCH_INT_PIN) != HIGH + #else + getRawData(XPT2046_Z1) >= XPT2046_Z1_THRESHOLD + #endif + ); +} + +bool XPT2046::getRawPoint(int16_t *x, int16_t *y) { + if (isBusy()) return false; + if (!isTouched()) return false; + *x = getRawData(XPT2046_X); + *y = getRawData(XPT2046_Y); + return isTouched(); +} + +uint16_t XPT2046::getRawData(const XPTCoordinate coordinate) { + uint16_t data[3]; + + DataTransferBegin(); + + for (uint16_t i = 0; i < 3 ; i++) { + IO(coordinate); + data[i] = (IO() << 4) | (IO() >> 4); + } + + DataTransferEnd(); + + uint16_t delta01 = delta(data[0], data[1]); + uint16_t delta02 = delta(data[0], data[2]); + uint16_t delta12 = delta(data[1], data[2]); + + if (delta01 > delta02 || delta01 > delta12) { + if (delta02 > delta12) + data[0] = data[2]; + else + data[1] = data[2]; + } + + return (data[0] + data[1]) >> 1; +} + +uint16_t XPT2046::HardwareIO(uint16_t data) { + __HAL_SPI_ENABLE(&SPIx); + while ((SPIx.Instance->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE) {} + SPIx.Instance->DR = data; + while ((SPIx.Instance->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE) {} + __HAL_SPI_DISABLE(&SPIx); + + return SPIx.Instance->DR; +} + +uint16_t XPT2046::SoftwareIO(uint16_t data) { + uint16_t result = 0; + + for (uint8_t j = 0x80; j > 0; j >>= 1) { + WRITE(TOUCH_SCK_PIN, LOW); + __DSB(); + WRITE(TOUCH_MOSI_PIN, data & j ? HIGH : LOW); + __DSB(); + if (READ(TOUCH_MISO_PIN)) result |= j; + __DSB(); + WRITE(TOUCH_SCK_PIN, HIGH); + __DSB(); + } + WRITE(TOUCH_SCK_PIN, LOW); + __DSB(); + + return result; +} + +#endif // HAS_TFT_XPT2046 diff --git a/Marlin/src/HAL/STM32/tft/xpt2046.h b/Marlin/src/HAL/STM32/tft/xpt2046.h new file mode 100644 index 000000000000..7a6d8439c59c --- /dev/null +++ b/Marlin/src/HAL/STM32/tft/xpt2046.h @@ -0,0 +1,86 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef STM32F1xx + #include +#elif defined(STM32F4xx) + #include +#endif + +#include "../../../inc/MarlinConfig.h" + +// Not using regular SPI interface by default to avoid SPI mode conflicts with other SPI devices + +#if !PIN_EXISTS(TOUCH_MISO) + #error "TOUCH_MISO_PIN is not defined." +#elif !PIN_EXISTS(TOUCH_MOSI) + #error "TOUCH_MOSI_PIN is not defined." +#elif !PIN_EXISTS(TOUCH_SCK) + #error "TOUCH_SCK_PIN is not defined." +#elif !PIN_EXISTS(TOUCH_CS) + #error "TOUCH_CS_PIN is not defined." +#endif + +#ifndef TOUCH_INT_PIN + #define TOUCH_INT_PIN -1 +#endif + +#define XPT2046_DFR_MODE 0x00 +#define XPT2046_SER_MODE 0x04 +#define XPT2046_CONTROL 0x80 + +enum XPTCoordinate : uint8_t { + XPT2046_X = 0x10 | XPT2046_CONTROL | XPT2046_DFR_MODE, + XPT2046_Y = 0x50 | XPT2046_CONTROL | XPT2046_DFR_MODE, + XPT2046_Z1 = 0x30 | XPT2046_CONTROL | XPT2046_DFR_MODE, + XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE, +}; + +#if !defined(XPT2046_Z1_THRESHOLD) + #define XPT2046_Z1_THRESHOLD 10 +#endif + +#ifdef STM32F1xx + #define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CCR & DMA_CCR_EN) +#elif defined(STM32F4xx) + #define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CR & DMA_SxCR_EN) +#endif + + +class XPT2046 { +private: + static SPI_HandleTypeDef SPIx; + static DMA_HandleTypeDef DMAtx; + + static bool isBusy() { return SPIx.Instance ? __IS_DMA_ENABLED(&DMAtx) : false; } + + static uint16_t getRawData(const XPTCoordinate coordinate); + static bool isTouched(); + + static inline void DataTransferBegin() { if (SPIx.Instance) { HAL_SPI_Init(&SPIx); } WRITE(TOUCH_CS_PIN, LOW); }; + static inline void DataTransferEnd() { WRITE(TOUCH_CS_PIN, HIGH); }; + static uint16_t HardwareIO(uint16_t data); + static uint16_t SoftwareIO(uint16_t data); + static uint16_t IO(uint16_t data = 0) { return SPIx.Instance ? HardwareIO(data) : SoftwareIO(data); } + +public: + static void Init(); + static bool getRawPoint(int16_t *x, int16_t *y); +}; diff --git a/Marlin/src/HAL/STM32/timers.cpp b/Marlin/src/HAL/STM32/timers.cpp new file mode 100644 index 000000000000..c0ba19abe545 --- /dev/null +++ b/Marlin/src/HAL/STM32/timers.cpp @@ -0,0 +1,280 @@ +/** + * Marlin 3D Printer Firmware + * + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com + * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC) + +#include "../../inc/MarlinConfig.h" + +// ------------------------ +// Local defines +// ------------------------ + +#define NUM_HARDWARE_TIMERS 2 + +// Default timer priorities. Override by specifying alternate priorities in the board pins file. +// The TONE timer is not present here, as it currently cannot be set programmatically. It is set +// by defining TIM_IRQ_PRIO in the variant.h or platformio.ini file, which adjusts the default +// priority for STM32 HardwareTimer objects. +#define SWSERIAL_TIMER_IRQ_PRIO_DEFAULT 1 // Requires tight bit timing to communicate reliably with TMC drivers +#define SERVO_TIMER_IRQ_PRIO_DEFAULT 1 // Requires tight PWM timing to control a BLTouch reliably +#define STEP_TIMER_IRQ_PRIO_DEFAULT 2 +#define TEMP_TIMER_IRQ_PRIO_DEFAULT 14 // Low priority avoids interference with other hardware and timers + +#ifndef STEP_TIMER_IRQ_PRIO + #define STEP_TIMER_IRQ_PRIO STEP_TIMER_IRQ_PRIO_DEFAULT +#endif +#ifndef TEMP_TIMER_IRQ_PRIO + #define TEMP_TIMER_IRQ_PRIO TEMP_TIMER_IRQ_PRIO_DEFAULT +#endif +#if HAS_TMC_SW_SERIAL + #include + #ifndef SWSERIAL_TIMER_IRQ_PRIO + #define SWSERIAL_TIMER_IRQ_PRIO SWSERIAL_TIMER_IRQ_PRIO_DEFAULT + #endif +#endif +#if HAS_SERVOS + #include "Servo.h" + #ifndef SERVO_TIMER_IRQ_PRIO + #define SERVO_TIMER_IRQ_PRIO SERVO_TIMER_IRQ_PRIO_DEFAULT + #endif +#endif +#if ENABLED(SPEAKER) + // Ensure the default timer priority is somewhere between the STEP and TEMP priorities. + // The STM32 framework defaults to interrupt 14 for all timers. This should be increased so that + // timing-sensitive operations such as speaker output are not impacted by the long-running + // temperature ISR. This must be defined in the platformio.ini file or the board's variant.h, + // so that it will be consumed by framework code. + #if !(TIM_IRQ_PRIO > STEP_TIMER_IRQ_PRIO && TIM_IRQ_PRIO < TEMP_TIMER_IRQ_PRIO) + #error "Default timer interrupt priority is unspecified or set to a value which may degrade performance." + #endif +#endif + +#ifdef STM32F0xx + #define MCU_TIMER_RATE (F_CPU) // Frequency of timer peripherals + #define MCU_STEP_TIMER 16 + #define MCU_TEMP_TIMER 17 +#elif defined(STM32F1xx) + #define MCU_TIMER_RATE (F_CPU) + #define MCU_STEP_TIMER 4 + #define MCU_TEMP_TIMER 2 +#elif defined(STM32F401xC) || defined(STM32F401xE) + #define MCU_TIMER_RATE (F_CPU / 2) + #define MCU_STEP_TIMER 9 + #define MCU_TEMP_TIMER 10 +#elif defined(STM32F4xx) || defined(STM32F7xx) + #define MCU_TIMER_RATE (F_CPU / 2) + #define MCU_STEP_TIMER 6 // STM32F401 has no TIM6, TIM7, or TIM8 + #define MCU_TEMP_TIMER 14 // TIM7 is consumed by Software Serial if used. +#endif + +#ifndef HAL_TIMER_RATE + #define HAL_TIMER_RATE MCU_TIMER_RATE +#endif +#ifndef STEP_TIMER + #define STEP_TIMER MCU_STEP_TIMER +#endif +#ifndef TEMP_TIMER + #define TEMP_TIMER MCU_TEMP_TIMER +#endif + +#define __TIMER_DEV(X) TIM##X +#define _TIMER_DEV(X) __TIMER_DEV(X) +#define STEP_TIMER_DEV _TIMER_DEV(STEP_TIMER) +#define TEMP_TIMER_DEV _TIMER_DEV(TEMP_TIMER) + +#define __TIMER_IRQ_NAME(X) TIM##X##_IRQn +#define _TIMER_IRQ_NAME(X) __TIMER_IRQ_NAME(X) +#define STEP_TIMER_IRQ_NAME _TIMER_IRQ_NAME(STEP_TIMER) +#define TEMP_TIMER_IRQ_NAME _TIMER_IRQ_NAME(TEMP_TIMER) + +// ------------------------ +// Private Variables +// ------------------------ + +HardwareTimer *timer_instance[NUM_HARDWARE_TIMERS] = { NULL }; + +// ------------------------ +// Public functions +// ------------------------ + +// frequency is in Hertz +void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { + if (!HAL_timer_initialized(timer_num)) { + switch (timer_num) { + case STEP_TIMER_NUM: // STEPPER TIMER - use a 32bit timer if possible + timer_instance[timer_num] = new HardwareTimer(STEP_TIMER_DEV); + /* Set the prescaler to the final desired value. + * This will change the effective ISR callback frequency but when + * HAL_timer_start(timer_num=0) is called in the core for the first time + * the real frequency isn't important as long as, after boot, the ISR + * gets called with the correct prescaler and count register. So here + * we set the prescaler to the correct, final value and ignore the frequency + * asked. We will call back the ISR in 1 second to start at full speed. + * + * The proper fix, however, would be a correct initialization OR a + * HAL_timer_change(const uint8_t timer_num, const uint32_t frequency) + * which changes the prescaler when an IRQ frequency change is needed + * (for example when steppers are turned on) + */ + + timer_instance[timer_num]->setPrescaleFactor(STEPPER_TIMER_PRESCALE); //the -1 is done internally + timer_instance[timer_num]->setOverflow(_MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE) /* /frequency */), TICK_FORMAT); + break; + case TEMP_TIMER_NUM: // TEMP TIMER - any available 16bit timer + timer_instance[timer_num] = new HardwareTimer(TEMP_TIMER_DEV); + // The prescale factor is computed automatically for HERTZ_FORMAT + timer_instance[timer_num]->setOverflow(frequency, HERTZ_FORMAT); + break; + } + + // Disable preload. Leaving it default-enabled can cause the timer to stop if it happens + // to exit the ISR after the start time for the next interrupt has already passed. + timer_instance[timer_num]->setPreloadEnable(false); + + HAL_timer_enable_interrupt(timer_num); + + // Start the timer. + timer_instance[timer_num]->resume(); // First call to resume() MUST follow the attachInterrupt() + + // This is fixed in Arduino_Core_STM32 1.8. + // These calls can be removed and replaced with + // timer_instance[timer_num]->setInterruptPriority + switch (timer_num) { + case STEP_TIMER_NUM: + timer_instance[timer_num]->setInterruptPriority(STEP_TIMER_IRQ_PRIO, 0); + break; + case TEMP_TIMER_NUM: + timer_instance[timer_num]->setInterruptPriority(TEMP_TIMER_IRQ_PRIO, 0); + break; + } + } +} + +void HAL_timer_enable_interrupt(const uint8_t timer_num) { + if (HAL_timer_initialized(timer_num) && !timer_instance[timer_num]->hasInterrupt()) { + switch (timer_num) { + case STEP_TIMER_NUM: + timer_instance[timer_num]->attachInterrupt(Step_Handler); + break; + case TEMP_TIMER_NUM: + timer_instance[timer_num]->attachInterrupt(Temp_Handler); + break; + } + } +} + +void HAL_timer_disable_interrupt(const uint8_t timer_num) { + if (HAL_timer_initialized(timer_num)) timer_instance[timer_num]->detachInterrupt(); +} + +bool HAL_timer_interrupt_enabled(const uint8_t timer_num) { + return HAL_timer_initialized(timer_num) && timer_instance[timer_num]->hasInterrupt(); +} + +void SetTimerInterruptPriorities() { + TERN_(HAS_TMC_SW_SERIAL, SoftwareSerial::setInterruptPriority(SWSERIAL_TIMER_IRQ_PRIO, 0)); + TERN_(HAS_SERVOS, libServo::setInterruptPriority(SERVO_TIMER_IRQ_PRIO, 0)); +} + +// This is a terrible hack to replicate the behavior used in the framework's SoftwareSerial.cpp +// to choose a serial timer. It will select TIM7 on most boards used by Marlin, but this is more +// resiliant to new MCUs which may not have a TIM7. Best practice is to explicitly specify +// TIMER_SERIAL to avoid relying on framework selections which may not be predictable. +#if !defined(TIMER_SERIAL) + #if defined (TIM18_BASE) + #define TIMER_SERIAL TIM18 + #elif defined (TIM7_BASE) + #define TIMER_SERIAL TIM7 + #elif defined (TIM6_BASE) + #define TIMER_SERIAL TIM6 + #elif defined (TIM22_BASE) + #define TIMER_SERIAL TIM22 + #elif defined (TIM21_BASE) + #define TIMER_SERIAL TIM21 + #elif defined (TIM17_BASE) + #define TIMER_SERIAL TIM17 + #elif defined (TIM16_BASE) + #define TIMER_SERIAL TIM16 + #elif defined (TIM15_BASE) + #define TIMER_SERIAL TIM15 + #elif defined (TIM14_BASE) + #define TIMER_SERIAL TIM14 + #elif defined (TIM13_BASE) + #define TIMER_SERIAL TIM13 + #elif defined (TIM11_BASE) + #define TIMER_SERIAL TIM11 + #elif defined (TIM10_BASE) + #define TIMER_SERIAL TIM10 + #elif defined (TIM12_BASE) + #define TIMER_SERIAL TIM12 + #elif defined (TIM19_BASE) + #define TIMER_SERIAL TIM19 + #elif defined (TIM9_BASE) + #define TIMER_SERIAL TIM9 + #elif defined (TIM5_BASE) + #define TIMER_SERIAL TIM5 + #elif defined (TIM4_BASE) + #define TIMER_SERIAL TIM4 + #elif defined (TIM3_BASE) + #define TIMER_SERIAL TIM3 + #elif defined (TIM2_BASE) + #define TIMER_SERIAL TIM2 + #elif defined (TIM20_BASE) + #define TIMER_SERIAL TIM20 + #elif defined (TIM8_BASE) + #define TIMER_SERIAL TIM8 + #elif defined (TIM1_BASE) + #define TIMER_SERIAL TIM1 + #else + #error No suitable timer found for SoftwareSerial, define TIMER_SERIAL in variant.h + #endif +#endif + +// Place all timers used into an array, then recursively check for duplicates during compilation. +// This does not currently account for timers used for PWM, such as for fans. +// Timers are actually pointers. Convert to integers to simplify constexpr logic. +static constexpr uintptr_t timers_in_use[] = { + uintptr_t(TEMP_TIMER_DEV), // Override in pins file + uintptr_t(STEP_TIMER_DEV), // Override in pins file + #if HAS_TMC_SW_SERIAL + uintptr_t(TIMER_SERIAL), // Set in variant.h, or as a define in platformio.h if not present in variant.h + #endif + #if ENABLED(SPEAKER) + uintptr_t(TIMER_TONE), // Set in variant.h, or as a define in platformio.h if not present in variant.h + #endif + #if HAS_SERVOS + uintptr_t(TIMER_SERVO), // Set in variant.h, or as a define in platformio.h if not present in variant.h + #endif + }; + +static constexpr bool verify_no_duplicate_timers() { + LOOP_L_N(i, COUNT(timers_in_use)) + LOOP_S_L_N(j, i + 1, COUNT(timers_in_use)) + if (timers_in_use[i] == timers_in_use[j]) return false; + return true; +} + +// If this assertion fails at compile time, review the timers_in_use array. If default_envs is +// defined properly in platformio.ini, VS Code can evaluate the array when hovering over it, +// making it easy to identify the conflicting timers. +static_assert(verify_no_duplicate_timers(), "One or more timer conflict detected"); + +#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC diff --git a/Marlin/src/HAL/HAL_STM32/timers.h b/Marlin/src/HAL/STM32/timers.h similarity index 61% rename from Marlin/src/HAL/HAL_STM32/timers.h rename to Marlin/src/HAL/STM32/timers.h index 8a0950a4d755..5515219ead00 100644 --- a/Marlin/src/HAL/HAL_STM32/timers.h +++ b/Marlin/src/HAL/STM32/timers.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -30,87 +30,29 @@ #define FORCE_INLINE __attribute__((always_inline)) inline +// STM32 timers may be 16 or 32 bit. Limiting HAL_TIMER_TYPE_MAX to 16 bits +// avoids issues with STM32F0 MCUs, which seem to pause timers if UINT32_MAX +// is written to the register. STM32F4 timers do not manifest this issue, +// even when writing to 16 bit timers. +// +// The range of the timer can be queried at runtime using IS_TIM_32B_COUNTER_INSTANCE. +// This is a more expensive check than a simple compile-time constant, so its +// implementation is deferred until the desire for a 32-bit range outweighs the cost +// of adding a run-time check and HAL_TIMER_TYPE_MAX is refactored to allow unique +// values for each timer. #define hal_timer_t uint32_t -#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF // Timers can be 16 or 32 bit - -#ifdef STM32F0xx - - #define HAL_TIMER_RATE (F_CPU) // frequency of timer peripherals - - #ifndef STEP_TIMER - #define STEP_TIMER 16 - #endif - - #ifndef TEMP_TIMER - #define TEMP_TIMER 17 - #endif - -#elif defined(STM32F1xx) - - #define HAL_TIMER_RATE (F_CPU) // frequency of timer peripherals - - #ifndef STEP_TIMER - #define STEP_TIMER 4 - #endif - - #ifndef TEMP_TIMER - #define TEMP_TIMER 2 - #endif - -#elif defined(STM32F401xC) || defined(STM32F401xE) - - #define HAL_TIMER_RATE (F_CPU / 2) // frequency of timer peripherals - - #ifndef STEP_TIMER - #define STEP_TIMER 9 - #endif - - #ifndef TEMP_TIMER - #define TEMP_TIMER 10 - #endif - -#elif defined(STM32F4xx) - - #define HAL_TIMER_RATE (F_CPU / 2) // frequency of timer peripherals - - #ifndef STEP_TIMER - #define STEP_TIMER 6 // STM32F401 has no TIM6, TIM7, or TIM8 - #endif - - #ifndef TEMP_TIMER - #define TEMP_TIMER 14 // TIM7 is consumed by Software Serial if used. - #endif - -#elif defined(STM32F7xx) - - #define HAL_TIMER_RATE (F_CPU / 2) // frequency of timer peripherals - - #ifndef STEP_TIMER - #define STEP_TIMER 6 // the RIGHT timer! - #endif - - #ifndef TEMP_TIMER - #define TEMP_TIMER 14 - #endif +#define HAL_TIMER_TYPE_MAX UINT16_MAX +#ifndef STEP_TIMER_NUM + #define STEP_TIMER_NUM 0 // Timer Index for Stepper #endif - -#ifndef SWSERIAL_TIMER_IRQ_PRIO - #define SWSERIAL_TIMER_IRQ_PRIO 1 +#ifndef PULSE_TIMER_NUM + #define PULSE_TIMER_NUM STEP_TIMER_NUM #endif - -#ifndef STEP_TIMER_IRQ_PRIO - #define STEP_TIMER_IRQ_PRIO 2 +#ifndef TEMP_TIMER_NUM + #define TEMP_TIMER_NUM 1 // Timer Index for Temperature #endif -#ifndef TEMP_TIMER_IRQ_PRIO - #define TEMP_TIMER_IRQ_PRIO 14 // 14 = after hardware ISRs -#endif - -#define STEP_TIMER_NUM 0 // index of timer to use for stepper -#define TEMP_TIMER_NUM 1 // index of timer to use for temperature -#define PULSE_TIMER_NUM STEP_TIMER_NUM - #define TEMP_TIMER_FREQUENCY 1000 // Temperature::isr() is expected to be called at around 1kHz // TODO: get rid of manual rate/prescale/ticks/cycles taken for procedures in stepper.cpp @@ -122,12 +64,6 @@ #define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE #define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US -#define __TIMER_IRQ_NAME(X) TIM##X##_IRQn -#define _TIMER_IRQ_NAME(X) __TIMER_IRQ_NAME(X) - -#define STEP_TIMER_IRQ_NAME _TIMER_IRQ_NAME(STEP_TIMER) -#define TEMP_TIMER_IRQ_NAME _TIMER_IRQ_NAME(TEMP_TIMER) - #define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM) #define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM) #define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM) @@ -135,10 +71,15 @@ #define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM) #define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM) -extern void Step_Handler(HardwareTimer *htim); -extern void Temp_Handler(HardwareTimer *htim); -#define HAL_STEP_TIMER_ISR() void Step_Handler(HardwareTimer *htim) -#define HAL_TEMP_TIMER_ISR() void Temp_Handler(HardwareTimer *htim) +extern void Step_Handler(); +extern void Temp_Handler(); + +#ifndef HAL_STEP_TIMER_ISR + #define HAL_STEP_TIMER_ISR() void Step_Handler() +#endif +#ifndef HAL_TEMP_TIMER_ISR + #define HAL_TEMP_TIMER_ISR() void Temp_Handler() +#endif // ------------------------ // Public Variables @@ -155,7 +96,9 @@ void HAL_timer_enable_interrupt(const uint8_t timer_num); void HAL_timer_disable_interrupt(const uint8_t timer_num); bool HAL_timer_interrupt_enabled(const uint8_t timer_num); -//TIM_TypeDef* HAL_timer_device(const uint8_t timer_num); no need to be public for now. not public = not used externally +// Configure timer priorities for peripherals such as Software Serial or Servos. +// Exposed here to allow all timer priority information to reside in timers.cpp +void SetTimerInterruptPriorities(); // FORCE_INLINE because these are used in performance-critical situations FORCE_INLINE bool HAL_timer_initialized(const uint8_t timer_num) { diff --git a/Marlin/src/HAL/STM32/usb_serial.cpp b/Marlin/src/HAL/STM32/usb_serial.cpp new file mode 100644 index 000000000000..2dd1bef12c43 --- /dev/null +++ b/Marlin/src/HAL/STM32/usb_serial.cpp @@ -0,0 +1,55 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC) + +#include "../../inc/MarlinConfigPre.h" + +#if ENABLED(EMERGENCY_PARSER) + +#include "usb_serial.h" +#include "../../feature/e_parser.h" + +EmergencyParser::State emergency_state = EmergencyParser::State::EP_RESET; + +int8_t (*USBD_CDC_Receive_original) (uint8_t *Buf, uint32_t *Len) = nullptr; + +static int8_t USBD_CDC_Receive_hook(uint8_t *Buf, uint32_t *Len) { + for (uint32_t i = 0; i < *Len; i++) + emergency_parser.update(emergency_state, Buf[i]); + return USBD_CDC_Receive_original(Buf, Len); +} + +typedef struct _USBD_CDC_Itf { + int8_t (* Init)(void); + int8_t (* DeInit)(void); + int8_t (* Control)(uint8_t cmd, uint8_t *pbuf, uint16_t length); + int8_t (* Receive)(uint8_t *Buf, uint32_t *Len); + int8_t (* Transferred)(void); +} USBD_CDC_ItfTypeDef; + +extern USBD_CDC_ItfTypeDef USBD_CDC_fops; + +void USB_Hook_init() { + USBD_CDC_Receive_original = USBD_CDC_fops.Receive; + USBD_CDC_fops.Receive = USBD_CDC_Receive_hook; +} + +#endif // EMERGENCY_PARSER +#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC diff --git a/Marlin/src/HAL/STM32/usb_serial.h b/Marlin/src/HAL/STM32/usb_serial.h new file mode 100644 index 000000000000..ca61b9ed239f --- /dev/null +++ b/Marlin/src/HAL/STM32/usb_serial.h @@ -0,0 +1,21 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +void USB_Hook_init(); diff --git a/Marlin/src/HAL/HAL_STM32/watchdog.cpp b/Marlin/src/HAL/STM32/watchdog.cpp similarity index 85% rename from Marlin/src/HAL/HAL_STM32/watchdog.cpp rename to Marlin/src/HAL/STM32/watchdog.cpp index 2c6b583e83c8..cc1855314968 100644 --- a/Marlin/src/HAL/HAL_STM32/watchdog.cpp +++ b/Marlin/src/HAL/STM32/watchdog.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC) #include "../../inc/MarlinConfigPre.h" @@ -31,7 +30,11 @@ #include "watchdog.h" #include - void watchdog_init() { IWatchdog.begin(4000000); } // 4 sec timeout + void watchdog_init() { + #if DISABLED(DISABLE_WATCHDOG_INIT) + IWatchdog.begin(4000000); // 4 sec timeout + #endif + } void HAL_watchdog_refresh() { IWatchdog.reload(); diff --git a/Marlin/src/HAL/HAL_STM32/watchdog.h b/Marlin/src/HAL/STM32/watchdog.h similarity index 92% rename from Marlin/src/HAL/HAL_STM32/watchdog.h rename to Marlin/src/HAL/STM32/watchdog.h index efa7d2b3d038..49a0d9c631d8 100644 --- a/Marlin/src/HAL/HAL_STM32/watchdog.h +++ b/Marlin/src/HAL/STM32/watchdog.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_STM32F1/HAL.cpp b/Marlin/src/HAL/STM32F1/HAL.cpp similarity index 91% rename from Marlin/src/HAL/HAL_STM32F1/HAL.cpp rename to Marlin/src/HAL/STM32F1/HAL.cpp index bc5479b60ce0..cd1efc16591d 100644 --- a/Marlin/src/HAL/HAL_STM32F1/HAL.cpp +++ b/Marlin/src/HAL/STM32F1/HAL.cpp @@ -17,7 +17,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -97,10 +97,13 @@ const uint8_t adc_pins[] = { #if HAS_TEMP_ADC_0 TEMP_0_PIN, #endif + #if HAS_TEMP_ADC_PROBE + TEMP_PROBE_PIN, + #endif #if HAS_HEATED_BED TEMP_BED_PIN, #endif - #if HAS_HEATED_CHAMBER + #if HAS_TEMP_CHAMBER TEMP_CHAMBER_PIN, #endif #if HAS_TEMP_ADC_1 @@ -139,16 +142,25 @@ const uint8_t adc_pins[] = { #if HAS_JOY_ADC_Z JOY_Z_PIN, #endif + #if ENABLED(POWER_MONITOR_CURRENT) + POWER_MONITOR_CURRENT_PIN, + #endif + #if ENABLED(POWER_MONITOR_VOLTAGE) + POWER_MONITOR_VOLTAGE_PIN, + #endif }; -enum TEMP_PINS : char { +enum TempPinIndex : char { #if HAS_TEMP_ADC_0 TEMP_0, #endif + #if HAS_TEMP_ADC_PROBE + TEMP_PROBE, + #endif #if HAS_HEATED_BED TEMP_BED, #endif - #if HAS_HEATED_CHAMBER + #if HAS_TEMP_CHAMBER TEMP_CHAMBER, #endif #if HAS_TEMP_ADC_1 @@ -187,6 +199,12 @@ enum TEMP_PINS : char { #if HAS_JOY_ADC_Z JOY_Z, #endif + #if ENABLED(POWER_MONITOR_CURRENT) + POWERMON_CURRENT, + #endif + #if ENABLED(POWER_MONITOR_VOLTAGE) + POWERMON_VOLTS, + #endif ADC_PIN_COUNT }; @@ -246,7 +264,7 @@ void HAL_init() { // HAL idle task void HAL_idletask() { #ifdef USE_USB_COMPOSITE - #if ENABLED(SHARED_SD_CARD) + #if HAS_SHARED_MEDIA // If Marlin is using the SD card we need to lock it to prevent access from // a PC via USB. // Other HALs use IS_SD_PRINTING() and IS_SD_FILE_OPEN() to check for access but @@ -254,7 +272,7 @@ void HAL_idletask() { // the disk if Marlin has it mounted. Unfortunately there is currently no way // to unmount the disk from the LCD menu. // if (IS_SD_PRINTING() || IS_SD_FILE_OPEN()) - /* copy from lpc1768 framework, should be fixed later for process SHARED_SD_CARD*/ + /* copy from lpc1768 framework, should be fixed later for process HAS_SHARED_MEDIA*/ #endif // process USB mass storage device class loop MarlinMSC.loop(); @@ -265,9 +283,8 @@ void HAL_clear_reset_source() { } /** * TODO: Check this and change or remove. - * currently returns 1 that's equal to poweron reset. */ -uint8_t HAL_get_reset_source() { return 1; } +uint8_t HAL_get_reset_source() { return RST_POWER_ON; } void _delay_ms(const int delay_ms) { delay(delay_ms); } @@ -323,16 +340,20 @@ void HAL_adc_init() { } void HAL_adc_start_conversion(const uint8_t adc_pin) { - TEMP_PINS pin_index; + //TEMP_PINS pin_index; + TempPinIndex pin_index; switch (adc_pin) { default: return; #if HAS_TEMP_ADC_0 case TEMP_0_PIN: pin_index = TEMP_0; break; #endif + #if HAS_TEMP_ADC_PROBE + case TEMP_PROBE_PIN: pin_index = TEMP_PROBE; break; + #endif #if HAS_HEATED_BED case TEMP_BED_PIN: pin_index = TEMP_BED; break; #endif - #if HAS_HEATED_CHAMBER + #if HAS_TEMP_CHAMBER case TEMP_CHAMBER_PIN: pin_index = TEMP_CHAMBER; break; #endif #if HAS_TEMP_ADC_1 @@ -371,6 +392,12 @@ void HAL_adc_start_conversion(const uint8_t adc_pin) { #if ENABLED(ADC_KEYPAD) case ADC_KEYPAD_PIN: pin_index = ADC_KEY; break; #endif + #if ENABLED(POWER_MONITOR_CURRENT) + case POWER_MONITOR_CURRENT_PIN: pin_index = POWERMON_CURRENT; break; + #endif + #if ENABLED(POWER_MONITOR_VOLTAGE) + case POWER_MONITOR_VOLTAGE_PIN: pin_index = POWERMON_VOLTS; break; + #endif } HAL_adc_result = (HAL_adc_results[(int)pin_index] >> 2) & 0x3FF; // shift to get 10 bits only. } @@ -388,6 +415,6 @@ void analogWrite(pin_t pin, int pwm_val8) { analogWrite(uint8_t(pin), pwm_val8); } -void flashFirmware(int16_t value) { nvic_sys_reset(); } +void flashFirmware(const int16_t) { nvic_sys_reset(); } #endif // __STM32F1__ diff --git a/Marlin/src/HAL/HAL_STM32F1/HAL.h b/Marlin/src/HAL/STM32F1/HAL.h similarity index 61% rename from Marlin/src/HAL/HAL_STM32F1/HAL.h rename to Marlin/src/HAL/STM32F1/HAL.h index c97abf4bb1a8..c10dea0eafd1 100644 --- a/Marlin/src/HAL/HAL_STM32F1/HAL.h +++ b/Marlin/src/HAL/STM32F1/HAL.h @@ -17,7 +17,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -36,7 +36,6 @@ #include "fastio.h" #include "watchdog.h" -#include "timers.h" #include #include @@ -47,12 +46,14 @@ #include "msc_sd.h" #endif +#include "MarlinSerial.h" + // ------------------------ // Defines // ------------------------ #ifndef STM32_FLASH_SIZE - #ifdef MCU_STM32F103RE + #if EITHER(MCU_STM32F103RE, MCU_STM32F103VE) #define STM32_FLASH_SIZE 512 #else #define STM32_FLASH_SIZE 256 @@ -65,87 +66,51 @@ #else #define UsbSerial MarlinCompositeSerial #endif - #define MSerial1 Serial1 - #define MSerial2 Serial2 - #define MSerial3 Serial3 - #define MSerial4 Serial4 - #define MSerial5 Serial5 +#endif + +#define _MSERIAL(X) MSerial##X +#define MSERIAL(X) _MSERIAL(X) + +#if EITHER(STM32_HIGH_DENSITY, STM32_XL_DENSITY) + #define NUM_UARTS 5 #else - #define MSerial1 Serial - #define MSerial2 Serial1 - #define MSerial3 Serial2 - #define MSerial4 Serial3 - #define MSerial5 Serial4 + #define NUM_UARTS 3 #endif -#if SERIAL_PORT == 0 - #error "SERIAL_PORT cannot be 0. (Port 0 does not exist.) Please update your configuration." -#elif SERIAL_PORT == -1 +#if SERIAL_PORT == -1 #define MYSERIAL0 UsbSerial -#elif SERIAL_PORT == 1 - #define MYSERIAL0 MSerial1 -#elif SERIAL_PORT == 2 - #define MYSERIAL0 MSerial2 -#elif SERIAL_PORT == 3 - #define MYSERIAL0 MSerial3 -#elif SERIAL_PORT == 4 - #define MYSERIAL0 MSerial4 -#elif SERIAL_PORT == 5 - #define MYSERIAL0 MSerial5 +#elif WITHIN(SERIAL_PORT, 1, NUM_UARTS) + #define MYSERIAL0 MSERIAL(SERIAL_PORT) +#elif NUM_UARTS == 5 + #error "SERIAL_PORT must be -1 or from 1 to 5. Please update your configuration." #else - #error "SERIAL_PORT must be from -1 to 5. Please update your configuration." + #error "SERIAL_PORT must be -1 or from 1 to 3. Please update your configuration." #endif #ifdef SERIAL_PORT_2 - #if SERIAL_PORT_2 == 0 - #error "SERIAL_PORT_2 cannot be 0. (Port 0 does not exist.) Please update your configuration." - #elif SERIAL_PORT_2 == SERIAL_PORT - #error "SERIAL_PORT_2 must be different than SERIAL_PORT. Please update your configuration." - #elif SERIAL_PORT_2 == -1 + #if SERIAL_PORT_2 == -1 #define MYSERIAL1 UsbSerial - #elif SERIAL_PORT_2 == 1 - #define MYSERIAL1 MSerial1 - #elif SERIAL_PORT_2 == 2 - #define MYSERIAL1 MSerial2 - #elif SERIAL_PORT_2 == 3 - #define MYSERIAL1 MSerial3 - #elif SERIAL_PORT_2 == 4 - #define MYSERIAL1 MSerial4 - #elif SERIAL_PORT_2 == 5 - #define MYSERIAL1 MSerial5 + #elif WITHIN(SERIAL_PORT_2, 1, NUM_UARTS) + #define MYSERIAL1 MSERIAL(SERIAL_PORT_2) + #elif NUM_UARTS == 5 + #error "SERIAL_PORT_2 must be -1 or from 1 to 5. Please update your configuration." #else - #error "SERIAL_PORT_2 must be from -1 to 5. Please update your configuration." + #error "SERIAL_PORT_2 must be -1 or from 1 to 3. Please update your configuration." #endif - #define NUM_SERIAL 2 -#else - #define NUM_SERIAL 1 #endif -#ifdef DGUS_SERIAL - #if DGUS_SERIAL_PORT == 0 - #error "DGUS_SERIAL_PORT cannot be 0. (Port 0 does not exist.) Please update your configuration." - #elif DGUS_SERIAL_PORT == SERIAL_PORT - #error "DGUS_SERIAL_PORT must be different than SERIAL_PORT. Please update your configuration." - #elif defined(SERIAL_PORT_2) && DGUS_SERIAL_PORT == SERIAL_PORT_2 - #error "DGUS_SERIAL_PORT must be different than SERIAL_PORT_2. Please update your configuration." - #elif DGUS_SERIAL_PORT == -1 - #define DGUS_SERIAL UsbSerial - #elif DGUS_SERIAL_PORT == 1 - #define DGUS_SERIAL MSerial1 - #elif DGUS_SERIAL_PORT == 2 - #define DGUS_SERIAL MSerial2 - #elif DGUS_SERIAL_PORT == 3 - #define DGUS_SERIAL MSerial3 - #elif DGUS_SERIAL_PORT == 4 - #define DGUS_SERIAL MSerial4 - #elif DGUS_SERIAL_PORT == 5 - #define DGUS_SERIAL MSerial5 +#ifdef LCD_SERIAL_PORT + #if LCD_SERIAL_PORT == -1 + #define LCD_SERIAL UsbSerial + #elif WITHIN(LCD_SERIAL_PORT, 1, NUM_UARTS) + #define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT) + #elif NUM_UARTS == 5 + #error "LCD_SERIAL_PORT must be -1 or from 1 to 5. Please update your configuration." #else - #error "DGUS_SERIAL_PORT must be from -1 to 5. Please update your configuration." + #error "LCD_SERIAL_PORT must be -1 or from 1 to 3. Please update your configuration." #endif #endif - // Set interrupt grouping for this MCU void HAL_init(); #define HAL_IDLETASK 1 @@ -160,6 +125,7 @@ void HAL_idletask(); #ifndef digitalPinHasPWM #define digitalPinHasPWM(P) (PIN_MAP[P].timer_device != nullptr) + #define NO_COMPILE_TIME_PWM #endif #define CRITICAL_SECTION_START() uint32_t primask = __get_primask(); (void)__iCliRetVal() @@ -219,6 +185,8 @@ void HAL_clear_reset_source(); // Reset reason uint8_t HAL_get_reset_source(); +inline void HAL_reboot() {} // reboot the board or restart the bootloader + void _delay_ms(const int delay); #pragma GCC diagnostic push @@ -247,19 +215,6 @@ static int freeMemory() { #pragma GCC diagnostic pop -// -// EEPROM -// - -/** - * TODO: Write all this EEPROM stuff. Can emulate EEPROM in flash as last resort. - * Wire library should work for i2c EEPROMs. - */ -void eeprom_write_byte(uint8_t *pos, unsigned char value); -uint8_t eeprom_read_byte(uint8_t *pos); -void eeprom_read_block(void *__dst, const void *__src, size_t __n); -void eeprom_update_block(const void *__src, void *__dst, size_t __n); - // // ADC // @@ -268,8 +223,9 @@ void eeprom_update_block(const void *__src, void *__dst, size_t __n); void HAL_adc_init(); -#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin) +#define HAL_ADC_VREF 3.3 #define HAL_ADC_RESOLUTION 10 +#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin) #define HAL_READ_ADC() HAL_adc_result #define HAL_ADC_READY() true @@ -287,4 +243,4 @@ void analogWrite(pin_t pin, int pwm_val8); // PWM only! mul by 257 in maple!? #define JTAGSWD_DISABLE() afio_cfg_debug_ports(AFIO_DEBUG_NONE) #define PLATFORM_M997_SUPPORT -void flashFirmware(int16_t value); +void flashFirmware(const int16_t); diff --git a/Marlin/src/HAL/HAL_STM32F1/HAL_SPI.cpp b/Marlin/src/HAL/STM32F1/HAL_SPI.cpp similarity index 95% rename from Marlin/src/HAL/HAL_STM32F1/HAL_SPI.cpp rename to Marlin/src/HAL/STM32F1/HAL_SPI.cpp index bfbdf6af40fd..76b1c3e2468b 100644 --- a/Marlin/src/HAL/HAL_STM32F1/HAL_SPI.cpp +++ b/Marlin/src/HAL/STM32F1/HAL_SPI.cpp @@ -17,16 +17,13 @@ * 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 . + * along with this program. If not, see . * */ /** * Software SPI functions originally from Arduino Sd2Card Library * Copyright (c) 2009 by William Greiman - */ - -/** * Adapted to the STM32F1 HAL */ @@ -113,7 +110,7 @@ void spiInit(uint8_t spiRate) { * @details */ uint8_t spiRec() { - uint8_t returnByte = SPI.transfer(ff); + uint8_t returnByte = SPI.transfer(0xFF); return returnByte; } @@ -157,7 +154,7 @@ void spiSendBlock(uint8_t token, const uint8_t* buf) { #if ENABLED(SPI_EEPROM) // Read single byte from specified SPI channel -uint8_t spiRec(uint32_t chan) { return SPI.transfer(ff); } +uint8_t spiRec(uint32_t chan) { return SPI.transfer(0xFF); } // Write single byte to specified SPI channel void spiSend(uint32_t chan, byte b) { SPI.send(b); } diff --git a/Marlin/src/HAL/STM32F1/MarlinSerial.cpp b/Marlin/src/HAL/STM32F1/MarlinSerial.cpp new file mode 100644 index 000000000000..ebf11cb429fa --- /dev/null +++ b/Marlin/src/HAL/STM32F1/MarlinSerial.cpp @@ -0,0 +1,193 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#ifdef __STM32F1__ + +#include "../../inc/MarlinConfig.h" +#include "MarlinSerial.h" +#include + +// Copied from ~/.platformio/packages/framework-arduinoststm32-maple/STM32F1/system/libmaple/usart_private.h +// Changed to handle Emergency Parser +static inline __always_inline void my_usart_irq(ring_buffer *rb, ring_buffer *wb, usart_reg_map *regs, MarlinSerial &serial) { + /* Handle RXNEIE and TXEIE interrupts. + * RXNE signifies availability of a byte in DR. + * + * See table 198 (sec 27.4, p809) in STM document RM0008 rev 15. + * We enable RXNEIE. + */ + uint32_t srflags = regs->SR, cr1its = regs->CR1; + + if ((cr1its & USART_CR1_RXNEIE) && (srflags & USART_SR_RXNE)) { + if (srflags & USART_SR_FE || srflags & USART_SR_PE ) { + // framing error or parity error + regs->DR; // Read and throw away the data, which also clears FE and PE + } + else { + uint8_t c = (uint8)regs->DR; + #ifdef USART_SAFE_INSERT + // If the buffer is full and the user defines USART_SAFE_INSERT, + // ignore new bytes. + rb_safe_insert(rb, c); + #else + // By default, push bytes around in the ring buffer. + rb_push_insert(rb, c); + #endif + #if ENABLED(EMERGENCY_PARSER) + if (serial.emergency_parser_enabled()) + emergency_parser.update(serial.emergency_state, c); + #endif + } + } + else if (srflags & USART_SR_ORE) { + // overrun and empty data, just do a dummy read to clear ORE + // and prevent a raise condition where a continous interrupt stream (due to ORE set) occurs + // (see chapter "Overrun error" ) in STM32 reference manual + regs->DR; + } + + // TXE signifies readiness to send a byte to DR. + if ((cr1its & USART_CR1_TXEIE) && (srflags & USART_SR_TXE)) { + if (!rb_is_empty(wb)) + regs->DR=rb_remove(wb); + else + regs->CR1 &= ~((uint32)USART_CR1_TXEIE); // disable TXEIE + } +} + +// Not every MarlinSerial port should handle emergency parsing. +// It would not make sense to parse GCode from TMC responses, for example. +constexpr bool serial_handles_emergency(int port) { + return false + #ifdef SERIAL_PORT + || (SERIAL_PORT) == port + #endif + #ifdef SERIAL_PORT_2 + || (SERIAL_PORT_2) == port + #endif + #ifdef LCD_SERIAL_PORT + || (LCD_SERIAL_PORT) == port + #endif + ; +} + +#define DEFINE_HWSERIAL_MARLIN(name, n) \ + MarlinSerial name(USART##n, \ + BOARD_USART##n##_TX_PIN, \ + BOARD_USART##n##_RX_PIN, \ + serial_handles_emergency(n)); \ + extern "C" void __irq_usart##n(void) { \ + my_usart_irq(USART##n->rb, USART##n->wb, USART##n##_BASE, MSerial##n); \ + } + +#define DEFINE_HWSERIAL_UART_MARLIN(name, n) \ + MarlinSerial name(UART##n, \ + BOARD_USART##n##_TX_PIN, \ + BOARD_USART##n##_RX_PIN, \ + serial_handles_emergency(n)); \ + extern "C" void __irq_usart##n(void) { \ + my_usart_irq(UART##n->rb, UART##n->wb, UART##n##_BASE, MSerial##n); \ + } + +// Instantiate all UARTs even if they are not needed +// This avoids a bunch of logic to figure out every serial +// port which may be in use on the system. +DEFINE_HWSERIAL_MARLIN(MSerial1, 1); +DEFINE_HWSERIAL_MARLIN(MSerial2, 2); +DEFINE_HWSERIAL_MARLIN(MSerial3, 3); +#if EITHER(STM32_HIGH_DENSITY, STM32_XL_DENSITY) + DEFINE_HWSERIAL_UART_MARLIN(MSerial4, 4); + DEFINE_HWSERIAL_UART_MARLIN(MSerial5, 5); +#endif + +// Check the type of each serial port by passing it to a template function. +// HardwareSerial is known to sometimes hang the controller when an error occurs, +// so this case will fail the static assert. All other classes are assumed to be ok. +template +constexpr bool IsSerialClassAllowed(const T&) { return true; } +constexpr bool IsSerialClassAllowed(const HardwareSerial&) { return false; } + +#define CHECK_CFG_SERIAL(A) static_assert(IsSerialClassAllowed(A), STRINGIFY(A) " is defined incorrectly"); +#define CHECK_AXIS_SERIAL(A) static_assert(IsSerialClassAllowed(A##_HARDWARE_SERIAL), STRINGIFY(A) "_HARDWARE_SERIAL must be defined in the form MSerial1, rather than Serial1"); + +// If you encounter this error, replace SerialX with MSerialX, for example MSerial3. + +// Non-TMC ports were already validated in HAL.h, so do not require verbose error messages. +#ifdef MYSERIAL0 + CHECK_CFG_SERIAL(MYSERIAL0); +#endif +#ifdef MYSERIAL1 + CHECK_CFG_SERIAL(MYSERIAL1); +#endif +#ifdef LCD_SERIAL + CHECK_CFG_SERIAL(LCD_SERIAL); +#endif +#if AXIS_HAS_HW_SERIAL(X) + CHECK_AXIS_SERIAL(X); +#endif +#if AXIS_HAS_HW_SERIAL(X2) + CHECK_AXIS_SERIAL(X2); +#endif +#if AXIS_HAS_HW_SERIAL(Y) + CHECK_AXIS_SERIAL(Y); +#endif +#if AXIS_HAS_HW_SERIAL(Y2) + CHECK_AXIS_SERIAL(Y2); +#endif +#if AXIS_HAS_HW_SERIAL(Z) + CHECK_AXIS_SERIAL(Z); +#endif +#if AXIS_HAS_HW_SERIAL(Z2) + CHECK_AXIS_SERIAL(Z2); +#endif +#if AXIS_HAS_HW_SERIAL(Z3) + CHECK_AXIS_SERIAL(Z3); +#endif +#if AXIS_HAS_HW_SERIAL(Z4) + CHECK_AXIS_SERIAL(Z4); +#endif +#if AXIS_HAS_HW_SERIAL(E0) + CHECK_AXIS_SERIAL(E0); +#endif +#if AXIS_HAS_HW_SERIAL(E1) + CHECK_AXIS_SERIAL(E1); +#endif +#if AXIS_HAS_HW_SERIAL(E2) + CHECK_AXIS_SERIAL(E2); +#endif +#if AXIS_HAS_HW_SERIAL(E3) + CHECK_AXIS_SERIAL(E3); +#endif +#if AXIS_HAS_HW_SERIAL(E4) + CHECK_AXIS_SERIAL(E4); +#endif +#if AXIS_HAS_HW_SERIAL(E5) + CHECK_AXIS_SERIAL(E5); +#endif +#if AXIS_HAS_HW_SERIAL(E6) + CHECK_AXIS_SERIAL(E6); +#endif +#if AXIS_HAS_HW_SERIAL(E7) + CHECK_AXIS_SERIAL(E7); +#endif + +#endif // __STM32F1__ diff --git a/Marlin/src/HAL/STM32F1/MarlinSerial.h b/Marlin/src/HAL/STM32F1/MarlinSerial.h new file mode 100644 index 000000000000..6aa94b64fff7 --- /dev/null +++ b/Marlin/src/HAL/STM32F1/MarlinSerial.h @@ -0,0 +1,71 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include +#include +#include + +#include "../../inc/MarlinConfigPre.h" +#if ENABLED(EMERGENCY_PARSER) + #include "../../feature/e_parser.h" +#endif + +// Increase priority of serial interrupts, to reduce overflow errors +#define UART_IRQ_PRIO 1 + +class MarlinSerial : public HardwareSerial { +public: + #if ENABLED(EMERGENCY_PARSER) + const bool ep_enabled; + EmergencyParser::State emergency_state; + inline bool emergency_parser_enabled() { return ep_enabled; } + #endif + + MarlinSerial(struct usart_dev *usart_device, uint8 tx_pin, uint8 rx_pin, bool TERN_(EMERGENCY_PARSER, ep_capable)) : + HardwareSerial(usart_device, tx_pin, rx_pin) + #if ENABLED(EMERGENCY_PARSER) + , ep_enabled(ep_capable) + , emergency_state(EmergencyParser::State::EP_RESET) + #endif + { } + + #ifdef UART_IRQ_PRIO + // Shadow the parent methods to set IRQ priority after begin() + void begin(uint32 baud) { + MarlinSerial::begin(baud, SERIAL_8N1); + } + + void begin(uint32 baud, uint8_t config) { + HardwareSerial::begin(baud, config); + nvic_irq_set_priority(c_dev()->irq_num, UART_IRQ_PRIO); + } + #endif +}; + +extern MarlinSerial MSerial1; +extern MarlinSerial MSerial2; +extern MarlinSerial MSerial3; +#if EITHER(STM32_HIGH_DENSITY, STM32_XL_DENSITY) + extern MarlinSerial MSerial4; + extern MarlinSerial MSerial5; +#endif diff --git a/Marlin/src/HAL/HAL_STM32F1/README.md b/Marlin/src/HAL/STM32F1/README.md similarity index 100% rename from Marlin/src/HAL/HAL_STM32F1/README.md rename to Marlin/src/HAL/STM32F1/README.md diff --git a/Marlin/src/HAL/HAL_STM32F1/SPI.cpp b/Marlin/src/HAL/STM32F1/SPI.cpp similarity index 98% rename from Marlin/src/HAL/HAL_STM32F1/SPI.cpp rename to Marlin/src/HAL/STM32F1/SPI.cpp index 8eb8f9aa88c9..0452cf629390 100644 --- a/Marlin/src/HAL/HAL_STM32F1/SPI.cpp +++ b/Marlin/src/HAL/STM32F1/SPI.cpp @@ -40,6 +40,9 @@ #include #include +#include "../../inc/MarlinConfig.h" +#include "spi_pins.h" + /** Time in ms for DMA receive timeout */ #define DMA_TIMEOUT 100 @@ -216,7 +219,7 @@ void SPIClass::setDataMode(uint8_t dataMode) { /** * Notes: * As far as we know the AVR numbers for dataMode match the numbers required by the STM32. - * From the AVR doc http://www.atmel.com/images/doc2585.pdf section 2.4 + * From the AVR doc https://www.atmel.com/images/doc2585.pdf section 2.4 * * SPI Mode CPOL CPHA Shift SCK-edge Capture SCK-edge * 0 0 0 Falling Rising @@ -243,7 +246,7 @@ void SPIClass::setDataMode(uint8_t dataMode) { _currentSetting->spi_d->regs->CR1 = cr1 | (dataMode & (SPI_CR1_CPOL|SPI_CR1_CPHA)); } -void SPIClass::beginTransaction(uint8_t pin, SPISettings settings) { +void SPIClass::beginTransaction(uint8_t pin, const SPISettings &settings) { setBitOrder(settings.bitOrder); setDataMode(settings.dataMode); setDataSize(settings.dataSize); @@ -251,7 +254,7 @@ void SPIClass::beginTransaction(uint8_t pin, SPISettings settings) { begin(); } -void SPIClass::beginTransactionSlave(SPISettings settings) { +void SPIClass::beginTransactionSlave(const SPISettings &settings) { setBitOrder(settings.bitOrder); setDataMode(settings.dataMode); setDataSize(settings.dataSize); @@ -266,7 +269,7 @@ void SPIClass::endTransaction() { } uint16_t SPIClass::read() { while (!spi_is_rx_nonempty(_currentSetting->spi_d)) { /* nada */ } - return (uint16)spi_rx_reg(_currentSetting->spi_d); + return (uint16_t)spi_rx_reg(_currentSetting->spi_d); } void SPIClass::read(uint8_t *buf, uint32_t len) { @@ -277,7 +280,7 @@ void SPIClass::read(uint8_t *buf, uint32_t len) { regs->DR = 0x00FF; // write the first byte // main loop while (--len) { - while(!(regs->SR & SPI_SR_TXE)) { /* nada */ } // wait for TXE flag + while (!(regs->SR & SPI_SR_TXE)) { /* nada */ } // wait for TXE flag noInterrupts(); // go atomic level - avoid interrupts to surely get the previously received data regs->DR = 0x00FF; // write the next data item to be transmitted into the SPI_DR register. This clears the TXE flag. while (!(regs->SR & SPI_SR_RXNE)) { /* nada */ } // wait till data is available in the DR register @@ -710,6 +713,6 @@ static spi_baud_rate determine_baud_rate(spi_dev *dev, uint32_t freq) { return baud_rates[i]; } -SPIClass SPI(1); +SPIClass SPI(SPI_DEVICE); #endif // __STM32F1__ diff --git a/Marlin/src/HAL/HAL_STM32F1/SPI.h b/Marlin/src/HAL/STM32F1/SPI.h similarity index 97% rename from Marlin/src/HAL/HAL_STM32F1/SPI.h rename to Marlin/src/HAL/STM32F1/SPI.h index 0162ac13bb17..0d20a46577e7 100644 --- a/Marlin/src/HAL/HAL_STM32F1/SPI.h +++ b/Marlin/src/HAL/STM32F1/SPI.h @@ -126,6 +126,7 @@ class SPISettings { bitOrder = inBitOrder; dataMode = inDataMode; dataSize = inDataSize; + //state = SPI_STATE_IDLE; } uint32_t clock; uint32_t dataSize; @@ -187,11 +188,11 @@ class SPIClass { */ void end(); - void beginTransaction(SPISettings settings) { beginTransaction(BOARD_SPI_DEFAULT_SS, settings); } - void beginTransaction(uint8_t pin, SPISettings settings); + void beginTransaction(const SPISettings &settings) { beginTransaction(BOARD_SPI_DEFAULT_SS, settings); } + void beginTransaction(uint8_t pin, const SPISettings &settings); void endTransaction(); - void beginTransactionSlave(SPISettings settings); + void beginTransactionSlave(const SPISettings &settings); void setClockDivider(uint32_t clockDivider); void setBitOrder(BitOrder bitOrder); @@ -207,6 +208,8 @@ class SPIClass { */ void setDataSize(uint32_t ds); + uint32_t getDataSize() { return _currentSetting->dataSize; } + /* Victor Perez 2017. Added to set and clear callback functions for callback * on DMA transfer completion. * onReceive used to set the callback in case of dmaTransfer (tx/rx), once rx is completed diff --git a/Marlin/src/HAL/HAL_STM32F1/Servo.cpp b/Marlin/src/HAL/STM32F1/Servo.cpp similarity index 97% rename from Marlin/src/HAL/HAL_STM32F1/Servo.cpp rename to Marlin/src/HAL/STM32F1/Servo.cpp index 06abb2c2b907..e1ee83149374 100644 --- a/Marlin/src/HAL/HAL_STM32F1/Servo.cpp +++ b/Marlin/src/HAL/STM32F1/Servo.cpp @@ -17,10 +17,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef __STM32F1__ #include "../../inc/MarlinConfig.h" @@ -30,7 +29,6 @@ uint8_t ServoCount = 0; #include "Servo.h" -#include "timers.h" //#include "Servo.h" @@ -76,6 +74,7 @@ void libServo::servoWrite(uint8_t inPin, uint16_t duty_cycle) { libServo::libServo() { servoIndex = ServoCount < MAX_SERVOS ? ServoCount++ : INVALID_SERVO; + timer_set_interrupt_priority(SERVO0_TIMER_NUM, SERVO0_TIMER_IRQ_PRIO); } bool libServo::attach(const int32_t inPin, const int32_t inMinAngle, const int32_t inMaxAngle) { @@ -138,9 +137,7 @@ void libServo::move(const int32_t value) { angle = constrain(value, minAngle, maxAngle); servoWrite(pin, US_TO_COMPARE(ANGLE_TO_US(angle))); safe_delay(servo_delay[servoIndex]); - #if ENABLED(DEACTIVATE_SERVOS_AFTER_MOVE) - detach(); - #endif + TERN_(DEACTIVATE_SERVOS_AFTER_MOVE, detach()); } } diff --git a/Marlin/src/HAL/HAL_STM32F1/Servo.h b/Marlin/src/HAL/STM32F1/Servo.h similarity index 96% rename from Marlin/src/HAL/HAL_STM32F1/Servo.h rename to Marlin/src/HAL/STM32F1/Servo.h index b3ca09f23808..b6143de81d62 100644 --- a/Marlin/src/HAL/HAL_STM32F1/Servo.h +++ b/Marlin/src/HAL/STM32F1/Servo.h @@ -17,7 +17,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_STM32F1/SoftwareSerial.cpp b/Marlin/src/HAL/STM32F1/SoftwareSerial.cpp similarity index 93% rename from Marlin/src/HAL/HAL_STM32F1/SoftwareSerial.cpp rename to Marlin/src/HAL/STM32F1/SoftwareSerial.cpp index e9e4a162a59b..993403cf720d 100644 --- a/Marlin/src/HAL/HAL_STM32F1/SoftwareSerial.cpp +++ b/Marlin/src/HAL/STM32F1/SoftwareSerial.cpp @@ -13,7 +13,7 @@ * 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 . + * along with this program. If not, see . * */ #if defined(__STM32F1__) && !defined(HAVE_SW_SERIAL) @@ -57,4 +57,4 @@ void SoftwareSerial::stopListening() { listening = false; } -#endif //__STM32F1__ +#endif // __STM32F1__ diff --git a/Marlin/src/HAL/HAL_STM32F1/SoftwareSerial.h b/Marlin/src/HAL/STM32F1/SoftwareSerial.h similarity index 93% rename from Marlin/src/HAL/HAL_STM32F1/SoftwareSerial.h rename to Marlin/src/HAL/STM32F1/SoftwareSerial.h index 1899a2ae0b93..1c8058665a47 100644 --- a/Marlin/src/HAL/HAL_STM32F1/SoftwareSerial.h +++ b/Marlin/src/HAL/STM32F1/SoftwareSerial.h @@ -13,7 +13,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_STM32F1/build_flags.py b/Marlin/src/HAL/STM32F1/build_flags.py similarity index 95% rename from Marlin/src/HAL/HAL_STM32F1/build_flags.py rename to Marlin/src/HAL/STM32F1/build_flags.py index 6310740fe0d8..98c871a1d8f9 100755 --- a/Marlin/src/HAL/HAL_STM32F1/build_flags.py +++ b/Marlin/src/HAL/STM32F1/build_flags.py @@ -15,7 +15,7 @@ "--specs=nano.specs", "--specs=nosys.specs", - "-IMarlin/src/HAL/HAL_STM32F1", + "-IMarlin/src/HAL/STM32F1", "-MMD", "-MP", diff --git a/Marlin/src/HAL/HAL_STM32F1/dogm/u8g_com_stm32duino_swspi.cpp b/Marlin/src/HAL/STM32F1/dogm/u8g_com_stm32duino_swspi.cpp similarity index 87% rename from Marlin/src/HAL/HAL_STM32F1/dogm/u8g_com_stm32duino_swspi.cpp rename to Marlin/src/HAL/STM32F1/dogm/u8g_com_stm32duino_swspi.cpp index 8cf9099c8159..60596054e820 100644 --- a/Marlin/src/HAL/HAL_STM32F1/dogm/u8g_com_stm32duino_swspi.cpp +++ b/Marlin/src/HAL/STM32F1/dogm/u8g_com_stm32duino_swspi.cpp @@ -13,16 +13,15 @@ * 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 . + * along with this program. If not, see . * */ #ifdef __STM32F1__ #include "../../../inc/MarlinConfig.h" -#if HAS_GRAPHICAL_LCD && ENABLED(FORCE_SOFT_SPI) +#if BOTH(HAS_MARLINUI_U8GLIB, FORCE_SOFT_SPI) -#include "../HAL.h" #include #undef SPI_SPEED @@ -32,7 +31,7 @@ static uint8_t SPI_speed = SPI_SPEED; static inline uint8_t swSpiTransfer_mode_0(uint8_t b, const uint8_t spi_speed, const pin_t miso_pin=-1) { - for (uint8_t i = 0; i < 8; i++) { + LOOP_L_N(i, 8) { if (spi_speed == 0) { WRITE(DOGLCD_MOSI, !!(b & 0x80)); WRITE(DOGLCD_SCK, HIGH); @@ -42,16 +41,16 @@ static inline uint8_t swSpiTransfer_mode_0(uint8_t b, const uint8_t spi_speed, c } else { const uint8_t state = (b & 0x80) ? HIGH : LOW; - for (uint8_t j = 0; j < spi_speed; j++) + LOOP_L_N(j, spi_speed) WRITE(DOGLCD_MOSI, state); - for (uint8_t j = 0; j < spi_speed + (miso_pin >= 0 ? 0 : 1); j++) + LOOP_L_N(j, spi_speed + (miso_pin >= 0 ? 0 : 1)) WRITE(DOGLCD_SCK, HIGH); b <<= 1; if (miso_pin >= 0 && READ(miso_pin)) b |= 1; - for (uint8_t j = 0; j < spi_speed; j++) + LOOP_L_N(j, spi_speed) WRITE(DOGLCD_SCK, LOW); } } @@ -59,7 +58,7 @@ static inline uint8_t swSpiTransfer_mode_0(uint8_t b, const uint8_t spi_speed, c } static inline uint8_t swSpiTransfer_mode_3(uint8_t b, const uint8_t spi_speed, const pin_t miso_pin=-1) { - for (uint8_t i = 0; i < 8; i++) { + LOOP_L_N(i, 8) { const uint8_t state = (b & 0x80) ? HIGH : LOW; if (spi_speed == 0) { WRITE(DOGLCD_SCK, LOW); @@ -68,13 +67,13 @@ static inline uint8_t swSpiTransfer_mode_3(uint8_t b, const uint8_t spi_speed, c WRITE(DOGLCD_SCK, HIGH); } else { - for (uint8_t j = 0; j < spi_speed + (miso_pin >= 0 ? 0 : 1); j++) + LOOP_L_N(j, spi_speed + (miso_pin >= 0 ? 0 : 1)) WRITE(DOGLCD_SCK, LOW); - for (uint8_t j = 0; j < spi_speed; j++) + LOOP_L_N(j, spi_speed) WRITE(DOGLCD_MOSI, state); - for (uint8_t j = 0; j < spi_speed; j++) + LOOP_L_N(j, spi_speed) WRITE(DOGLCD_SCK, HIGH); } b <<= 1; @@ -161,5 +160,5 @@ uint8_t u8g_com_HAL_STM32F1_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, return 1; } -#endif // HAS_GRAPHICAL_LCD +#endif // HAS_MARLINUI_U8GLIB && FORCE_SOFT_SPI #endif // STM32F1 diff --git a/Marlin/src/HAL/STM32F1/eeprom_bl24cxx.cpp b/Marlin/src/HAL/STM32F1/eeprom_bl24cxx.cpp new file mode 100644 index 000000000000..658b7cd4a654 --- /dev/null +++ b/Marlin/src/HAL/STM32F1/eeprom_bl24cxx.cpp @@ -0,0 +1,84 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * PersistentStore for Arduino-style EEPROM interface + * with simple implementations supplied by Marlin. + */ + +#ifdef __STM32F1__ + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(IIC_BL24CXX_EEPROM) + +#include "../shared/eeprom_if.h" +#include "../shared/eeprom_api.h" + +// +// PersistentStore +// + +#ifndef MARLIN_EEPROM_SIZE + #error "MARLIN_EEPROM_SIZE is required for IIC_BL24CXX_EEPROM." +#endif + +size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } + +bool PersistentStore::access_start() { eeprom_init(); return true; } +bool PersistentStore::access_finish() { return true; } + +bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { + while (size--) { + uint8_t v = *value; + uint8_t * const p = (uint8_t * const)pos; + // EEPROM has only ~100,000 write cycles, + // so only write bytes that have changed! + if (v != eeprom_read_byte(p)) { + eeprom_write_byte(p, v); + delay(2); + if (eeprom_read_byte(p) != v) { + SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE); + return true; + } + } + crc16(crc, &v, 1); + pos++; + value++; + } + return false; +} + +bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) { + do { + uint8_t * const p = (uint8_t * const)pos; + uint8_t c = eeprom_read_byte(p); + if (writing) *value = c; + crc16(crc, &c, 1); + pos++; + value++; + } while (--size); + return false; +} + +#endif // IIC_BL24CXX_EEPROM +#endif // __STM32F1__ diff --git a/Marlin/src/HAL/HAL_STM32F1/persistent_store_flash.cpp b/Marlin/src/HAL/STM32F1/eeprom_flash.cpp similarity index 81% rename from Marlin/src/HAL/HAL_STM32F1/persistent_store_flash.cpp rename to Marlin/src/HAL/STM32F1/eeprom_flash.cpp index 3d6a3b4591f0..8db8c8638bb8 100644 --- a/Marlin/src/HAL/HAL_STM32F1/persistent_store_flash.cpp +++ b/Marlin/src/HAL/STM32F1/eeprom_flash.cpp @@ -17,7 +17,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -31,27 +31,28 @@ #include "../../inc/MarlinConfig.h" -// This is for EEPROM emulation in flash -#if BOTH(EEPROM_SETTINGS, FLASH_EEPROM_EMULATION) +#if ENABLED(FLASH_EEPROM_EMULATION) -#include "../shared/persistent_store_api.h" +#include "../shared/eeprom_api.h" #include #include // Store settings in the last two pages -#define EEPROM_SIZE (EEPROM_PAGE_SIZE * 2) -#define ACCESS_FINISHED(TF) do{ FLASH_Lock(); eeprom_dirty = false; return TF; }while(0) +#ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE ((EEPROM_PAGE_SIZE) * 2) +#endif +size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } -static uint8_t ram_eeprom[EEPROM_SIZE] __attribute__((aligned(4))) = {0}; +static uint8_t ram_eeprom[MARLIN_EEPROM_SIZE] __attribute__((aligned(4))) = {0}; static bool eeprom_dirty = false; bool PersistentStore::access_start() { const uint32_t* source = reinterpret_cast(EEPROM_PAGE0_BASE); uint32_t* destination = reinterpret_cast(ram_eeprom); - static_assert(0 == EEPROM_SIZE % 4, "EEPROM_SIZE is corrupted. (Must be a multiple of 4.)"); // Ensure copying as uint32_t is safe - constexpr size_t eeprom_size_u32 = EEPROM_SIZE / 4; + static_assert(0 == (MARLIN_EEPROM_SIZE) % 4, "MARLIN_EEPROM_SIZE is corrupted. (Must be a multiple of 4.)"); // Ensure copying as uint32_t is safe + constexpr size_t eeprom_size_u32 = (MARLIN_EEPROM_SIZE) / 4; for (size_t i = 0; i < eeprom_size_u32; ++i, ++destination, ++source) *destination = *source; @@ -73,13 +74,15 @@ bool PersistentStore::access_finish() { // page changes...either way, something to look at later. FLASH_Unlock(); + #define ACCESS_FINISHED(TF) { FLASH_Lock(); eeprom_dirty = false; return TF; } + status = FLASH_ErasePage(EEPROM_PAGE0_BASE); if (status != FLASH_COMPLETE) ACCESS_FINISHED(true); status = FLASH_ErasePage(EEPROM_PAGE1_BASE); if (status != FLASH_COMPLETE) ACCESS_FINISHED(true); const uint16_t *source = reinterpret_cast(ram_eeprom); - for (size_t i = 0; i < EEPROM_SIZE; i += 2, ++source) { + for (size_t i = 0; i < MARLIN_EEPROM_SIZE; i += 2, ++source) { if (FLASH_ProgramHalfWord(EEPROM_PAGE0_BASE + i, *source) != FLASH_COMPLETE) ACCESS_FINISHED(false); } @@ -106,7 +109,5 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, const size_t size, uin return false; // return true for any error } -size_t PersistentStore::capacity() { return EEPROM_SIZE; } - -#endif // EEPROM_SETTINGS && EEPROM FLASH +#endif // FLASH_EEPROM_EMULATION #endif // __STM32F1__ diff --git a/Marlin/src/HAL/STM32F1/eeprom_if_iic.cpp b/Marlin/src/HAL/STM32F1/eeprom_if_iic.cpp new file mode 100644 index 000000000000..ccc3fc537f1a --- /dev/null +++ b/Marlin/src/HAL/STM32F1/eeprom_if_iic.cpp @@ -0,0 +1,54 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * Platform-independent Arduino functions for I2C EEPROM. + * Enable USE_SHARED_EEPROM if not supplied by the framework. + */ + +#ifdef __STM32F1__ + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(IIC_BL24CXX_EEPROM) + +#include "../../libs/BL24CXX.h" +#include "../shared/eeprom_if.h" + +void eeprom_init() { BL24CXX::init(); } + +// ------------------------ +// Public functions +// ------------------------ + +void eeprom_write_byte(uint8_t *pos, unsigned char value) { + const unsigned eeprom_address = (unsigned)pos; + return BL24CXX::writeOneByte(eeprom_address, value); +} + +uint8_t eeprom_read_byte(uint8_t *pos) { + const unsigned eeprom_address = (unsigned)pos; + return BL24CXX::readOneByte(eeprom_address); +} + +#endif // IIC_BL24CXX_EEPROM +#endif // __STM32F1__ diff --git a/Marlin/src/HAL/HAL_STM32F1/persistent_store_sdcard.cpp b/Marlin/src/HAL/STM32F1/eeprom_sdcard.cpp similarity index 52% rename from Marlin/src/HAL/HAL_STM32F1/persistent_store_sdcard.cpp rename to Marlin/src/HAL/STM32F1/eeprom_sdcard.cpp index 0a0d71271822..11959191f6dd 100644 --- a/Marlin/src/HAL/HAL_STM32F1/persistent_store_sdcard.cpp +++ b/Marlin/src/HAL/STM32F1/eeprom_sdcard.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -29,56 +29,47 @@ #include "../../inc/MarlinConfig.h" -#if ENABLED(EEPROM_SETTINGS) && NONE(FLASH_EEPROM_EMULATION, SPI_EEPROM, I2C_EEPROM) +#if ENABLED(SDCARD_EEPROM_EMULATION) -#include "../shared/persistent_store_api.h" +#include "../shared/eeprom_api.h" +#include "../../sd/cardreader.h" -#ifndef E2END - #define E2END 0xFFF // 4KB +#define EEPROM_FILENAME "eeprom.dat" + +#ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE 0x1000 // 4KB #endif -#define HAL_EEPROM_SIZE (E2END + 1) +size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } #define _ALIGN(x) __attribute__ ((aligned(x))) // SDIO uint32_t* compat. -static char _ALIGN(4) HAL_eeprom_data[HAL_EEPROM_SIZE]; - -#if ENABLED(SDSUPPORT) +static char _ALIGN(4) HAL_eeprom_data[MARLIN_EEPROM_SIZE]; - #include "../../sd/cardreader.h" +bool PersistentStore::access_start() { + if (!card.isMounted()) return false; - #define EEPROM_FILENAME "eeprom.dat" + SdFile file, root = card.getroot(); + if (!file.open(&root, EEPROM_FILENAME, O_RDONLY)) + return true; // false aborts the save - bool PersistentStore::access_start() { - if (!card.isMounted()) return false; + int bytes_read = file.read(HAL_eeprom_data, MARLIN_EEPROM_SIZE); + if (bytes_read < 0) return false; + for (; bytes_read < MARLIN_EEPROM_SIZE; bytes_read++) + HAL_eeprom_data[bytes_read] = 0xFF; + file.close(); + return true; +} - SdFile file, root = card.getroot(); - if (!file.open(&root, EEPROM_FILENAME, O_RDONLY)) - return true; // false aborts the save +bool PersistentStore::access_finish() { + if (!card.isMounted()) return false; - int bytes_read = file.read(HAL_eeprom_data, HAL_EEPROM_SIZE); - if (bytes_read < 0) return false; - for (; bytes_read < HAL_EEPROM_SIZE; bytes_read++) - HAL_eeprom_data[bytes_read] = 0xFF; + SdFile file, root = card.getroot(); + int bytes_written = 0; + if (file.open(&root, EEPROM_FILENAME, O_CREAT | O_WRITE | O_TRUNC)) { + bytes_written = file.write(HAL_eeprom_data, MARLIN_EEPROM_SIZE); file.close(); - return true; - } - - bool PersistentStore::access_finish() { - if (!card.isMounted()) return false; - - SdFile file, root = card.getroot(); - int bytes_written = 0; - if (file.open(&root, EEPROM_FILENAME, O_CREAT | O_WRITE | O_TRUNC)) { - bytes_written = file.write(HAL_eeprom_data, HAL_EEPROM_SIZE); - file.close(); - } - return (bytes_written == HAL_EEPROM_SIZE); } - -#else // !SDSUPPORT - - #error "Please define SPI_EEPROM (in Configuration.h) or disable EEPROM_SETTINGS." - -#endif // !SDSUPPORT + return (bytes_written == MARLIN_EEPROM_SIZE); +} bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { for (size_t i = 0; i < size; i++) @@ -98,8 +89,5 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, const size_t size, uin return false; } -size_t PersistentStore::capacity() { return HAL_EEPROM_SIZE; } - -#endif // EEPROM_SETTINGS - +#endif // SDCARD_EEPROM_EMULATION #endif // __STM32F1__ diff --git a/Marlin/src/HAL/HAL_STM32F1/persistent_store_eeprom.cpp b/Marlin/src/HAL/STM32F1/eeprom_wired.cpp similarity index 82% rename from Marlin/src/HAL/HAL_STM32F1/persistent_store_eeprom.cpp rename to Marlin/src/HAL/STM32F1/eeprom_wired.cpp index f2a1cb031a0b..fffd6ccaf01e 100644 --- a/Marlin/src/HAL/HAL_STM32F1/persistent_store_eeprom.cpp +++ b/Marlin/src/HAL/STM32F1/eeprom_wired.cpp @@ -14,19 +14,32 @@ * 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 . + * along with this program. If not, see . * */ +/** + * HAL PersistentStore for STM32F1 + */ + #ifdef __STM32F1__ #include "../../inc/MarlinConfig.h" -#if ENABLED(EEPROM_SETTINGS) && EITHER(SPI_EEPROM, I2C_EEPROM) +#if USE_WIRED_EEPROM + +#include "../shared/eeprom_if.h" +#include "../shared/eeprom_api.h" -#include "../shared/persistent_store_api.h" +#ifndef MARLIN_EEPROM_SIZE + #error "MARLIN_EEPROM_SIZE is required for I2C / SPI EEPROM." +#endif +size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } + +bool PersistentStore::access_finish() { return true; } bool PersistentStore::access_start() { + eeprom_init(); #if ENABLED(SPI_EEPROM) #if SPI_CHAN_EEPROM1 == 1 SET_OUTPUT(BOARD_SPI1_SCK_PIN); @@ -38,7 +51,6 @@ bool PersistentStore::access_start() { #endif return true; } -bool PersistentStore::access_finish() { return true; } bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { while (size--) { @@ -56,7 +68,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui crc16(crc, &v, 1); pos++; value++; - }; + } return false; } @@ -71,7 +83,5 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t return false; } -size_t PersistentStore::capacity() { return E2END + 1; } - -#endif // EEPROM_SETTINGS && EITHER(SPI_EEPROM, I2C_EEPROM) +#endif // USE_WIRED_EEPROM #endif // __STM32F1__ diff --git a/Marlin/src/HAL/HAL_STM32F1/endstop_interrupts.h b/Marlin/src/HAL/STM32F1/endstop_interrupts.h similarity index 65% rename from Marlin/src/HAL/HAL_STM32F1/endstop_interrupts.h rename to Marlin/src/HAL/STM32F1/endstop_interrupts.h index 246e29298312..bcb07d991d75 100644 --- a/Marlin/src/HAL/HAL_STM32F1/endstop_interrupts.h +++ b/Marlin/src/HAL/STM32F1/endstop_interrupts.h @@ -17,7 +17,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -53,43 +53,22 @@ void endstop_ISR() { endstops.update(); } void setup_endstop_interrupts() { - #if HAS_X_MAX - attachInterrupt(X_MAX_PIN, endstop_ISR, CHANGE); // assign it - #endif - #if HAS_X_MIN - attachInterrupt(X_MIN_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Y_MAX - attachInterrupt(Y_MAX_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Y_MIN - attachInterrupt(Y_MIN_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z_MAX - attachInterrupt(Z_MAX_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z_MIN - attachInterrupt(Z_MIN_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z2_MAX - attachInterrupt(Z2_MAX_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z2_MIN - attachInterrupt(Z2_MIN_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z3_MAX - attachInterrupt(Z3_MAX_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z3_MIN - attachInterrupt(Z3_MIN_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z4_MAX - attachInterrupt(Z4_MAX_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z4_MIN - attachInterrupt(Z4_MIN_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_Z_MIN_PROBE_PIN - attachInterrupt(Z_MIN_PROBE_PIN, endstop_ISR, CHANGE); - #endif + #define _ATTACH(P) attachInterrupt(P, endstop_ISR, CHANGE) + TERN_(HAS_X_MAX, _ATTACH(X_MAX_PIN)); + TERN_(HAS_X_MIN, _ATTACH(X_MIN_PIN)); + TERN_(HAS_Y_MAX, _ATTACH(Y_MAX_PIN)); + TERN_(HAS_Y_MIN, _ATTACH(Y_MIN_PIN)); + TERN_(HAS_Z_MAX, _ATTACH(Z_MAX_PIN)); + TERN_(HAS_Z_MIN, _ATTACH(Z_MIN_PIN)); + TERN_(HAS_X2_MAX, _ATTACH(X2_MAX_PIN)); + TERN_(HAS_X2_MIN, _ATTACH(X2_MIN_PIN)); + TERN_(HAS_Y2_MAX, _ATTACH(Y2_MAX_PIN)); + TERN_(HAS_Y2_MIN, _ATTACH(Y2_MIN_PIN)); + TERN_(HAS_Z2_MAX, _ATTACH(Z2_MAX_PIN)); + TERN_(HAS_Z2_MIN, _ATTACH(Z2_MIN_PIN)); + TERN_(HAS_Z3_MAX, _ATTACH(Z3_MAX_PIN)); + TERN_(HAS_Z3_MIN, _ATTACH(Z3_MIN_PIN)); + TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN)); + TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN)); + TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN)); } diff --git a/Marlin/src/HAL/HAL_STM32F1/fastio.h b/Marlin/src/HAL/STM32F1/fastio.h similarity index 98% rename from Marlin/src/HAL/HAL_STM32F1/fastio.h rename to Marlin/src/HAL/STM32F1/fastio.h index 9bf78d4254b0..e0e2e03a1c47 100644 --- a/Marlin/src/HAL/HAL_STM32F1/fastio.h +++ b/Marlin/src/HAL/STM32F1/fastio.h @@ -17,7 +17,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/STM32F1/inc/Conditionals_LCD.h b/Marlin/src/HAL/STM32F1/inc/Conditionals_LCD.h new file mode 100644 index 000000000000..f52e6fec2b1e --- /dev/null +++ b/Marlin/src/HAL/STM32F1/inc/Conditionals_LCD.h @@ -0,0 +1,27 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if ENABLED(USE_USB_COMPOSITE) + //#warning "SD_CHECK_AND_RETRY isn't needed with USE_USB_COMPOSITE." + #undef SD_CHECK_AND_RETRY +#endif diff --git a/Marlin/src/HAL/STM32F1/inc/Conditionals_adv.h b/Marlin/src/HAL/STM32F1/inc/Conditionals_adv.h new file mode 100644 index 000000000000..5f1c4b16019d --- /dev/null +++ b/Marlin/src/HAL/STM32F1/inc/Conditionals_adv.h @@ -0,0 +1,22 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once diff --git a/Marlin/src/HAL/STM32F1/inc/Conditionals_post.h b/Marlin/src/HAL/STM32F1/inc/Conditionals_post.h new file mode 100644 index 000000000000..656fbe1ce259 --- /dev/null +++ b/Marlin/src/HAL/STM32F1/inc/Conditionals_post.h @@ -0,0 +1,34 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +// If no real EEPROM, Flash emulation, or SRAM emulation is available fall back to SD emulation +#if USE_FALLBACK_EEPROM + #define SDCARD_EEPROM_EMULATION +#elif EITHER(I2C_EEPROM, SPI_EEPROM) + #define USE_SHARED_EEPROM 1 +#endif + +// Allow SDSUPPORT to be disabled +#if DISABLED(SDSUPPORT) + #undef SDIO_SUPPORT +#endif diff --git a/Marlin/src/HAL/HAL_STM32F1/inc/SanityCheck.h b/Marlin/src/HAL/STM32F1/inc/SanityCheck.h similarity index 53% rename from Marlin/src/HAL/HAL_STM32F1/inc/SanityCheck.h rename to Marlin/src/HAL/STM32F1/inc/SanityCheck.h index b8ebc446d6db..9d5026fbab10 100644 --- a/Marlin/src/HAL/HAL_STM32F1/inc/SanityCheck.h +++ b/Marlin/src/HAL/STM32F1/inc/SanityCheck.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,19 +25,29 @@ * Test STM32F1-specific configuration values for errors at compile-time. */ -#if ENABLED(EMERGENCY_PARSER) - #error "EMERGENCY_PARSER is not yet implemented for STM32F1. Disable EMERGENCY_PARSER to continue." +#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY + #error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on STM32F1." #endif -#if ENABLED(SDIO_SUPPORT) && DISABLED(SDSUPPORT) - #error "SDIO_SUPPORT requires SDSUPPORT. Enable SDSUPPORT to continue." +#if !defined(HAVE_SW_SERIAL) && HAS_TMC_SW_SERIAL + #warning "With TMC2208/9 consider using SoftwareSerialM with HAVE_SW_SERIAL and appropriate SS_TIMER." + #error "Missing SoftwareSerial implementation." #endif -#if ENABLED(FAST_PWM_FAN) - #error "FAST_PWM_FAN is not yet implemented for this platform." +#if ENABLED(SDCARD_EEPROM_EMULATION) && DISABLED(SDSUPPORT) + #undef SDCARD_EEPROM_EMULATION // Avoid additional error noise + #if USE_FALLBACK_EEPROM + #warning "EEPROM type not specified. Fallback is SDCARD_EEPROM_EMULATION." + #endif + #error "SDCARD_EEPROM_EMULATION requires SDSUPPORT. Enable SDSUPPORT or choose another EEPROM emulation." #endif -#if !defined(HAVE_SW_SERIAL) && HAS_TMC_SW_SERIAL - #warning "With TMC2208/9 consider using SoftwareSerialM with HAVE_SW_SERIAL and appropriate SS_TIMER." - #error "Missing SoftwareSerial implementation." +#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) + #error "SERIAL_STATS_MAX_RX_QUEUED is not supported on this platform." +#elif ENABLED(SERIAL_STATS_DROPPED_RX) + #error "SERIAL_STATS_DROPPED_RX is not supported on this platform." +#endif + +#if ENABLED(NEOPIXEL_LED) + #error "NEOPIXEL_LED (Adafruit NeoPixel) is not supported for HAL/STM32F1. Comment out this line to proceed at your own risk!" #endif diff --git a/Marlin/src/HAL/HAL_STM32F1/maple_win_usb_driver/maple_serial.inf b/Marlin/src/HAL/STM32F1/maple_win_usb_driver/maple_serial.inf similarity index 100% rename from Marlin/src/HAL/HAL_STM32F1/maple_win_usb_driver/maple_serial.inf rename to Marlin/src/HAL/STM32F1/maple_win_usb_driver/maple_serial.inf diff --git a/Marlin/src/HAL/HAL_STM32F1/msc_sd.cpp b/Marlin/src/HAL/STM32F1/msc_sd.cpp similarity index 67% rename from Marlin/src/HAL/HAL_STM32F1/msc_sd.cpp rename to Marlin/src/HAL/STM32F1/msc_sd.cpp index a086b82bc36c..4f44f2ee905f 100644 --- a/Marlin/src/HAL/HAL_STM32F1/msc_sd.cpp +++ b/Marlin/src/HAL/STM32F1/msc_sd.cpp @@ -10,10 +10,10 @@ * (at your option) any later version. * * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * along with this program. If not, see . * */ -#ifdef USE_USB_COMPOSITE +#if defined(__STM32F1__) && defined(USE_USB_COMPOSITE) #include "msc_sd.h" #include "SPI.h" @@ -21,11 +21,11 @@ #define PRODUCT_ID 0x29 USBMassStorage MarlinMSC; -USBCompositeSerial MarlinCompositeSerial; +MarlinUSBCompositeSerial MarlinCompositeSerial; #include "../../inc/MarlinConfig.h" -#ifdef HAS_ONBOARD_SD +#if SD_CONNECTION_IS(ONBOARD) #include "onboard_sd.h" @@ -38,6 +38,17 @@ USBCompositeSerial MarlinCompositeSerial; #endif +#if ENABLED(EMERGENCY_PARSER) + void (*real_rx_callback)(void); + + void my_rx_callback(void) { + real_rx_callback(); + int len = MarlinCompositeSerial.available(); + while (len-- > 0) // >0 because available() may return a negative value + emergency_parser.update(MarlinCompositeSerial.emergency_state, MarlinCompositeSerial.peek()); + } +#endif + void MSC_SD_init() { USBComposite.setProductId(PRODUCT_ID); // Just set MarlinCompositeSerial enabled to true @@ -47,7 +58,7 @@ void MSC_SD_init() { USBComposite.end(); USBComposite.clear(); // Set api and register mass storage - #ifdef HAS_ONBOARD_SD + #if SD_CONNECTION_IS(ONBOARD) uint32_t cardSize; if (disk_initialize(0) == RES_OK) { if (disk_ioctl(0, GET_SECTOR_COUNT, (void *)(&cardSize)) == RES_OK) { @@ -59,6 +70,11 @@ void MSC_SD_init() { // Register composite Serial MarlinCompositeSerial.registerComponent(); USBComposite.begin(); + #if ENABLED(EMERGENCY_PARSER) + //rx is usbSerialPart.endpoints[2] + real_rx_callback = usbSerialPart.endpoints[2].callback; + usbSerialPart.endpoints[2].callback = my_rx_callback; + #endif } -#endif // USE_USB_COMPOSITE +#endif // __STM32F1__ && USE_USB_COMPOSITE diff --git a/Marlin/src/HAL/STM32F1/msc_sd.h b/Marlin/src/HAL/STM32F1/msc_sd.h new file mode 100644 index 000000000000..1e4e4c44b1b5 --- /dev/null +++ b/Marlin/src/HAL/STM32F1/msc_sd.h @@ -0,0 +1,42 @@ +/** + * Marlin 3D Printer Firmware + * + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * Copyright (c) 2019 BigTreeTech [https://github.com/bigtreetech] + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include + +#include "../../inc/MarlinConfigPre.h" +#if ENABLED(EMERGENCY_PARSER) + #include "../../feature/e_parser.h" +#endif + +class MarlinUSBCompositeSerial : public USBCompositeSerial { +public: + MarlinUSBCompositeSerial() : USBCompositeSerial() + #if ENABLED(EMERGENCY_PARSER) + , emergency_state(EmergencyParser::State::EP_RESET) + #endif + { } + + #if ENABLED(EMERGENCY_PARSER) + EmergencyParser::State emergency_state; + inline bool emergency_parser_enabled() { return true; } + #endif +}; + +extern USBMassStorage MarlinMSC; +extern MarlinUSBCompositeSerial MarlinCompositeSerial; + +void MSC_SD_init(); diff --git a/Marlin/src/HAL/HAL_STM32F1/onboard_sd.cpp b/Marlin/src/HAL/STM32F1/onboard_sd.cpp similarity index 97% rename from Marlin/src/HAL/HAL_STM32F1/onboard_sd.cpp rename to Marlin/src/HAL/STM32F1/onboard_sd.cpp index 0fd94a91993e..9c2b128ddc9a 100644 --- a/Marlin/src/HAL/HAL_STM32F1/onboard_sd.cpp +++ b/Marlin/src/HAL/STM32F1/onboard_sd.cpp @@ -9,35 +9,36 @@ * No restriction on use. You can use, modify and redistribute it for * personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. * Redistributions of source code must retain the above copyright notice. - * */ +#ifdef __STM32F1__ + #include "../../inc/MarlinConfig.h" -#ifdef HAS_ONBOARD_SD +#if SD_CONNECTION_IS(ONBOARD) #include "onboard_sd.h" #include "SPI.h" #include "fastio.h" -#ifdef SHARED_SD_CARD - #ifndef ON_BOARD_SPI_DEVICE - #define ON_BOARD_SPI_DEVICE SPI_DEVICE +#if HAS_SHARED_MEDIA + #ifndef ONBOARD_SPI_DEVICE + #define ONBOARD_SPI_DEVICE SPI_DEVICE #endif #define ONBOARD_SD_SPI SPI #else - SPIClass OnBoardSPI(ON_BOARD_SPI_DEVICE); - #define ONBOARD_SD_SPI OnBoardSPI + SPIClass OnboardSPI(ONBOARD_SPI_DEVICE); + #define ONBOARD_SD_SPI OnboardSPI #endif -#if ON_BOARD_SPI_DEVICE == 1 +#if ONBOARD_SPI_DEVICE == 1 #define SPI_CLOCK_MAX SPI_BAUD_PCLK_DIV_4 #else #define SPI_CLOCK_MAX SPI_BAUD_PCLK_DIV_2 #endif -#define CS_LOW() WRITE(ONBOARD_SD_CS_PIN, LOW) /* Set OnBoardSPI cs low */ -#define CS_HIGH() WRITE(ONBOARD_SD_CS_PIN, HIGH) /* Set OnBoardSPI cs high */ +#define CS_LOW() WRITE(ONBOARD_SD_CS_PIN, LOW) /* Set OnboardSPI cs low */ +#define CS_HIGH() WRITE(ONBOARD_SD_CS_PIN, HIGH) /* Set OnboardSPI cs high */ #define FCLK_FAST() ONBOARD_SD_SPI.setClockDivider(SPI_CLOCK_MAX) #define FCLK_SLOW() ONBOARD_SD_SPI.setClockDivider(SPI_BAUD_PCLK_DIV_256) @@ -152,7 +153,7 @@ static int select() { /* 1:OK, 0:Timeout */ /*-----------------------------------------------------------------------*/ static void power_on() { /* Enable SSP module and attach it to I/O pads */ - ONBOARD_SD_SPI.setModule(ON_BOARD_SPI_DEVICE); + ONBOARD_SD_SPI.setModule(ONBOARD_SPI_DEVICE); ONBOARD_SD_SPI.begin(); ONBOARD_SD_SPI.setBitOrder(MSBFIRST); ONBOARD_SD_SPI.setDataMode(SPI_MODE0); @@ -553,4 +554,5 @@ DRESULT disk_read ( #endif // _DISKIO_IOCTL -#endif // HAS_ONBOARD_SD +#endif // SD_CONNECTION_IS(ONBOARD) +#endif // __STM32F1__ diff --git a/Marlin/src/HAL/HAL_STM32F1/onboard_sd.h b/Marlin/src/HAL/STM32F1/onboard_sd.h similarity index 100% rename from Marlin/src/HAL/HAL_STM32F1/onboard_sd.h rename to Marlin/src/HAL/STM32F1/onboard_sd.h diff --git a/Marlin/src/HAL/HAL_STM32F1/pinsDebug.h b/Marlin/src/HAL/STM32F1/pinsDebug.h similarity index 84% rename from Marlin/src/HAL/HAL_STM32F1/pinsDebug.h rename to Marlin/src/HAL/STM32F1/pinsDebug.h index 8d3eed52d0ba..2d63ebd770f0 100644 --- a/Marlin/src/HAL/HAL_STM32F1/pinsDebug.h +++ b/Marlin/src/HAL/STM32F1/pinsDebug.h @@ -13,15 +13,15 @@ * 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 . + * along with this program. If not, see . * */ #pragma once #ifdef NUM_DIGITAL_PINS // Only in ST's Arduino core (STM32duino, STM32Core) - #include "../HAL_STM32/pinsDebug_STM32duino.h" + #include "../STM32/pinsDebug_STM32duino.h" #elif defined(BOARD_NR_GPIO_PINS) // Only in STM32GENERIC (Maple) - #include "../HAL_STM32/pinsDebug_STM32GENERIC.h" + #include "../STM32/pinsDebug_STM32GENERIC.h" #else #error "M43 not supported for this board" #endif diff --git a/Marlin/src/HAL/HAL_STM32F1/sdio.cpp b/Marlin/src/HAL/STM32F1/sdio.cpp similarity index 93% rename from Marlin/src/HAL/HAL_STM32F1/sdio.cpp rename to Marlin/src/HAL/STM32F1/sdio.cpp index da6beda85c79..ffa6db1206ae 100644 --- a/Marlin/src/HAL/HAL_STM32F1/sdio.cpp +++ b/Marlin/src/HAL/STM32F1/sdio.cpp @@ -17,17 +17,16 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef ARDUINO_ARCH_STM32F1 #include #include "../../inc/MarlinConfig.h" // Allow pins/pins.h to set density -#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) +#if EITHER(STM32_HIGH_DENSITY, STM32_XL_DENSITY) #include "sdio.h" @@ -102,7 +101,23 @@ bool SDIO_ReadBlock_DMA(uint32_t blockAddress, uint8_t *data) { return false; } - while (!SDIO_GET_FLAG(SDIO_STA_DATAEND | SDIO_STA_TRX_ERROR_FLAGS)) {} + while (!SDIO_GET_FLAG(SDIO_STA_DATAEND | SDIO_STA_TRX_ERROR_FLAGS)) { /* wait */ } + + //If there were SDIO errors, do not wait DMA. + if (SDIO->STA & SDIO_STA_TRX_ERROR_FLAGS) { + SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS); + dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); + return false; + } + + //Wait for DMA transaction to complete + while ((DMA2_BASE->ISR & (DMA_ISR_TEIF4|DMA_ISR_TCIF4)) == 0 ) { /* wait */ } + + if (DMA2_BASE->ISR & DMA_ISR_TEIF4) { + dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); + SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS); + return false; + } dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); @@ -121,7 +136,7 @@ bool SDIO_ReadBlock_DMA(uint32_t blockAddress, uint8_t *data) { } bool SDIO_ReadBlock(uint32_t blockAddress, uint8_t *data) { - uint32_t retries = 3; + uint32_t retries = SDIO_READ_RETRIES; while (retries--) if (SDIO_ReadBlock_DMA(blockAddress, data)) return true; return false; } @@ -147,7 +162,7 @@ bool SDIO_WriteBlock(uint32_t blockAddress, const uint8_t *data) { sdio_setup_transfer(SDIO_DATA_TIMEOUT * (F_CPU / 1000U), 512U, SDIO_BLOCKSIZE_512 | SDIO_DCTRL_DMAEN | SDIO_DCTRL_DTEN); - while (!SDIO_GET_FLAG(SDIO_STA_DATAEND | SDIO_STA_TRX_ERROR_FLAGS)) {} + while (!SDIO_GET_FLAG(SDIO_STA_DATAEND | SDIO_STA_TRX_ERROR_FLAGS)) { /* wait */ } dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); diff --git a/Marlin/src/HAL/HAL_STM32F1/sdio.h b/Marlin/src/HAL/STM32F1/sdio.h similarity index 96% rename from Marlin/src/HAL/HAL_STM32F1/sdio.h rename to Marlin/src/HAL/STM32F1/sdio.h index f51ba6d0a631..8777299f01bc 100644 --- a/Marlin/src/HAL/HAL_STM32F1/sdio.h +++ b/Marlin/src/HAL/STM32F1/sdio.h @@ -16,12 +16,12 @@ * 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 . + * along with this program. If not, see . * */ #pragma once -#include "../shared/Marduino.h" +#include "../../inc/MarlinConfig.h" // Allow pins/pins.h to override SDIO clock / retries #include #include @@ -100,7 +100,13 @@ #define SDIO_DATA_TIMEOUT 100U /* Read data transfer timeout */ #define SDIO_WRITE_TIMEOUT 200U /* Write data transfer timeout */ -#define SDIO_CLOCK 18000000 /* 18 MHz */ +#ifndef SDIO_CLOCK + #define SDIO_CLOCK 18000000 /* 18 MHz */ +#endif + +#ifndef SDIO_READ_RETRIES + #define SDIO_READ_RETRIES 3 +#endif // ------------------------ // Types diff --git a/Marlin/src/HAL/HAL_STM32F1/spi_pins.h b/Marlin/src/HAL/STM32F1/spi_pins.h similarity index 95% rename from Marlin/src/HAL/HAL_STM32F1/spi_pins.h rename to Marlin/src/HAL/STM32F1/spi_pins.h index e8e4cbba1167..8f2b324f6457 100644 --- a/Marlin/src/HAL/HAL_STM32F1/spi_pins.h +++ b/Marlin/src/HAL/STM32F1/spi_pins.h @@ -13,7 +13,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_STM32F1/dogm/u8g_com_stm32duino_fsmc.cpp b/Marlin/src/HAL/STM32F1/tft/tft_fsmc.cpp similarity index 52% rename from Marlin/src/HAL/HAL_STM32F1/dogm/u8g_com_stm32duino_fsmc.cpp rename to Marlin/src/HAL/STM32F1/tft/tft_fsmc.cpp index cc26a003d19a..5b52fb416fa3 100644 --- a/Marlin/src/HAL/HAL_STM32F1/dogm/u8g_com_stm32duino_fsmc.cpp +++ b/Marlin/src/HAL/STM32F1/tft/tft_fsmc.cpp @@ -16,100 +16,20 @@ * 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 . + * along with this program. If not, see . * */ -/** - * u8g_com_stm32duino_fsmc.cpp - * - * Communication interface for FSMC - */ - #include "../../../inc/MarlinConfig.h" -#if defined(ARDUINO_ARCH_STM32F1) && PIN_EXISTS(FSMC_CS) // FSMC on 100/144 pins SoCs - -#if HAS_GRAPHICAL_LCD +#if HAS_FSMC_TFT -#include +#include "tft_fsmc.h" #include #include #include -#include - -#ifndef LCD_READ_ID - #define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341) -#endif - -/* Timing configuration */ -#define FSMC_ADDRESS_SETUP_TIME 15 // AddressSetupTime -#define FSMC_DATA_SETUP_TIME 15 // DataSetupTime -void LCD_IO_Init(uint8_t cs, uint8_t rs); -void LCD_IO_WriteData(uint16_t RegValue); -void LCD_IO_WriteReg(uint16_t Reg); -uint16_t LCD_IO_ReadData(uint16_t RegValue); -uint32_t LCD_IO_ReadData(uint16_t RegValue, uint8_t ReadSize); -#ifdef LCD_USE_DMA_FSMC - void LCD_IO_WriteMultiple(uint16_t data, uint32_t count); - void LCD_IO_WriteSequence(uint16_t *data, uint16_t length); -#endif - -static uint8_t msgInitCount = 2; // Ignore all messages until 2nd U8G_COM_MSG_INIT - -uint8_t u8g_com_stm32duino_fsmc_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { - if (msgInitCount) { - if (msg == U8G_COM_MSG_INIT) msgInitCount--; - if (msgInitCount) return -1; - } - - static uint8_t isCommand; - - switch (msg) { - case U8G_COM_MSG_STOP: break; - case U8G_COM_MSG_INIT: - u8g_SetPIOutput(u8g, U8G_PI_RESET); - - #ifdef LCD_USE_DMA_FSMC - dma_init(FSMC_DMA_DEV); - dma_disable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL); - dma_set_priority(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, DMA_PRIORITY_MEDIUM); - #endif - - LCD_IO_Init(u8g->pin_list[U8G_PI_CS], u8g->pin_list[U8G_PI_A0]); - u8g_Delay(50); - - if (arg_ptr) { - *((uint32_t *)arg_ptr) = LCD_IO_ReadData(0x0000); - if (*((uint32_t *)arg_ptr) == 0) - *((uint32_t *)arg_ptr) = (LCD_READ_ID << 24) | LCD_IO_ReadData(LCD_READ_ID, 3); - } - isCommand = 0; - break; - - case U8G_COM_MSG_ADDRESS: // define cmd (arg_val = 0) or data mode (arg_val = 1) - isCommand = arg_val == 0 ? 1 : 0; - break; - - case U8G_COM_MSG_RESET: - u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val); - break; - - case U8G_COM_MSG_WRITE_BYTE: - if (isCommand) - LCD_IO_WriteReg(arg_val); - else - LCD_IO_WriteData((uint16_t)arg_val); - break; - - case U8G_COM_MSG_WRITE_SEQ: - for (uint8_t i = 0; i < arg_val; i += 2) - LCD_IO_WriteData(*(uint16_t *)(((uint32_t)arg_ptr) + i)); - break; - } - return 1; -} +LCD_CONTROLLER_TypeDef *TFT_FSMC::LCD; /** * FSMC LCD IO @@ -160,27 +80,32 @@ __attribute__((always_inline)) __STATIC_INLINE void __DSB() { #define FSMC_RS_A25 PG14 #endif -static uint8_t fsmcInit = 0; +/* Timing configuration */ +#define FSMC_ADDRESS_SETUP_TIME 15 // AddressSetupTime +#define FSMC_DATA_SETUP_TIME 15 // DataSetupTime -typedef struct { - __IO uint16_t REG; - __IO uint16_t RAM; -} LCD_CONTROLLER_TypeDef; +static uint8_t fsmcInit = 0; +void TFT_FSMC::Init() { + uint8_t cs = FSMC_CS_PIN, rs = FSMC_RS_PIN; + uint32_t controllerAddress; -LCD_CONTROLLER_TypeDef *LCD; + #if ENABLED(LCD_USE_DMA_FSMC) + dma_init(FSMC_DMA_DEV); + dma_disable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL); + dma_set_priority(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, DMA_PRIORITY_MEDIUM); + #endif -void LCD_IO_Init(uint8_t cs, uint8_t rs) { - uint32_t controllerAddress; + struct fsmc_nor_psram_reg_map* fsmcPsramRegion; if (fsmcInit) return; fsmcInit = 1; switch (cs) { - case FSMC_CS_NE1: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION1; break; + case FSMC_CS_NE1: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION1; fsmcPsramRegion = FSMC_NOR_PSRAM1_BASE; break; #if ENABLED(STM32_XL_DENSITY) - case FSMC_CS_NE2: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION2; break; - case FSMC_CS_NE3: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION3; break; - case FSMC_CS_NE4: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION4; break; + case FSMC_CS_NE2: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION2; fsmcPsramRegion = FSMC_NOR_PSRAM2_BASE; break; + case FSMC_CS_NE3: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION3; fsmcPsramRegion = FSMC_NOR_PSRAM3_BASE; break; + case FSMC_CS_NE4: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION4; fsmcPsramRegion = FSMC_NOR_PSRAM4_BASE; break; #endif default: return; } @@ -246,90 +171,67 @@ void LCD_IO_Init(uint8_t cs, uint8_t rs) { gpio_set_mode(PIN_MAP[cs].gpio_device, PIN_MAP[cs].gpio_bit, GPIO_AF_OUTPUT_PP); //FSMC_CS_NEx gpio_set_mode(PIN_MAP[rs].gpio_device, PIN_MAP[rs].gpio_bit, GPIO_AF_OUTPUT_PP); //FSMC_RS_Ax - #if ENABLED(STM32_XL_DENSITY) - FSMC_NOR_PSRAM4_BASE->BCR = FSMC_BCR_WREN | FSMC_BCR_MTYP_SRAM | FSMC_BCR_MWID_16BITS | FSMC_BCR_MBKEN; - FSMC_NOR_PSRAM4_BASE->BTR = (FSMC_DATA_SETUP_TIME << 8) | FSMC_ADDRESS_SETUP_TIME; - #else // PSRAM1 for STM32F103V (high density) - FSMC_NOR_PSRAM1_BASE->BCR = FSMC_BCR_WREN | FSMC_BCR_MTYP_SRAM | FSMC_BCR_MWID_16BITS | FSMC_BCR_MBKEN; - FSMC_NOR_PSRAM1_BASE->BTR = (FSMC_DATA_SETUP_TIME << 8) | FSMC_ADDRESS_SETUP_TIME; - #endif + fsmcPsramRegion->BCR = FSMC_BCR_WREN | FSMC_BCR_MTYP_SRAM | FSMC_BCR_MWID_16BITS | FSMC_BCR_MBKEN; + fsmcPsramRegion->BTR = (FSMC_DATA_SETUP_TIME << 8) | FSMC_ADDRESS_SETUP_TIME; afio_remap(AFIO_REMAP_FSMC_NADV); LCD = (LCD_CONTROLLER_TypeDef*)controllerAddress; } -void LCD_IO_WriteData(uint16_t RegValue) { - LCD->RAM = RegValue; +void TFT_FSMC::Transmit(uint16_t Data) { + LCD->RAM = Data; __DSB(); } -void LCD_IO_WriteReg(uint16_t Reg) { +void TFT_FSMC::WriteReg(uint16_t Reg) { LCD->REG = Reg; __DSB(); } -uint16_t LCD_IO_ReadData(uint16_t RegValue) { - LCD->REG = RegValue; - __DSB(); - - return LCD->RAM; +uint32_t TFT_FSMC::GetID() { + uint32_t id; + WriteReg(0x0000); + id = LCD->RAM; + + if (id == 0) + id = ReadID(LCD_READ_ID); + if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF) + id = ReadID(LCD_READ_ID4); + if ((id & 0xFF00) == 0 && (id & 0xFF) != 0) + id = ReadID(LCD_READ_ID4); + return id; } -uint32_t LCD_IO_ReadData(uint16_t RegValue, uint8_t ReadSize) { - volatile uint32_t data; - LCD->REG = RegValue; - __DSB(); + uint32_t TFT_FSMC::ReadID(uint16_t Reg) { + uint32_t id; + WriteReg(Reg); + id = LCD->RAM; // dummy read + id = Reg << 24; + id |= (LCD->RAM & 0x00FF) << 16; + id |= (LCD->RAM & 0x00FF) << 8; + id |= LCD->RAM & 0x00FF; + return id; + } + +bool TFT_FSMC::isBusy() { + return false; +} - data = LCD->RAM; // dummy read - data = LCD->RAM & 0x00FF; +void TFT_FSMC::Abort() { - while (--ReadSize) { - data <<= 8; - data |= (LCD->RAM & 0x00FF); - } - return uint32_t(data); } -#if ENABLED(LCD_USE_DMA_FSMC) - -void LCD_IO_WriteMultiple(uint16_t color, uint32_t count) { - while (count > 0) { - dma_setup_transfer(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, &color, DMA_SIZE_16BITS, &LCD->RAM, DMA_SIZE_16BITS, DMA_MEM_2_MEM); - dma_set_num_transfers(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, count > 65535 ? 65535 : count); +void TFT_FSMC::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) { + #if defined(FSMC_DMA_DEV) && defined(FSMC_DMA_CHANNEL) + dma_setup_transfer(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, Data, DMA_SIZE_16BITS, &LCD->RAM, DMA_SIZE_16BITS, DMA_MEM_2_MEM | MemoryIncrease); + dma_set_num_transfers(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, Count); dma_clear_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL); dma_enable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL); while ((dma_get_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL) & 0x0A) == 0) {}; dma_disable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL); - - count = count > 65535 ? count - 65535 : 0; - } -} - -void LCD_IO_WriteSequence(uint16_t *data, uint16_t length) { - dma_setup_transfer(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, data, DMA_SIZE_16BITS, &LCD->RAM, DMA_SIZE_16BITS, DMA_MEM_2_MEM | DMA_PINC_MODE); - dma_set_num_transfers(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, length); - dma_clear_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL); - dma_enable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL); - - while ((dma_get_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL) & 0x0A) == 0) {}; - dma_disable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL); -} - -void LCD_IO_WriteSequence_Async(uint16_t *data, uint16_t length) { - dma_setup_transfer(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, data, DMA_SIZE_16BITS, &LCD->RAM, DMA_SIZE_16BITS, DMA_MEM_2_MEM | DMA_PINC_MODE); - dma_set_num_transfers(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, length); - dma_clear_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL); - dma_enable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL); -} - -void LCD_IO_WaitSequence_Async() { - while ((dma_get_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL) & 0x0A) == 0) {}; - dma_disable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL); + #endif } -#endif // LCD_USE_DMA_FSMC - -#endif // HAS_GRAPHICAL_LCD -#endif // ARDUINO_ARCH_STM32F1 && FSMC_CS_PIN +#endif // HAS_FSMC_TFT diff --git a/Marlin/src/HAL/STM32F1/tft/tft_fsmc.h b/Marlin/src/HAL/STM32F1/tft/tft_fsmc.h new file mode 100644 index 000000000000..11eb1ffa8410 --- /dev/null +++ b/Marlin/src/HAL/STM32F1/tft/tft_fsmc.h @@ -0,0 +1,71 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifndef LCD_READ_ID + #define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341) +#endif +#ifndef LCD_READ_ID4 + #define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341) +#endif + +#include + +#define DATASIZE_8BIT DMA_SIZE_8BITS +#define DATASIZE_16BIT DMA_SIZE_16BITS +#define TFT_IO_DRIVER TFT_FSMC + +typedef struct { + __IO uint16_t REG; + __IO uint16_t RAM; +} LCD_CONTROLLER_TypeDef; + +class TFT_FSMC { + private: + static LCD_CONTROLLER_TypeDef *LCD; + + static uint32_t ReadID(uint16_t Reg); + static void Transmit(uint16_t Data); + static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count); + + public: + static void Init(); + static uint32_t GetID(); + static bool isBusy(); + static void Abort(); + + static void DataTransferBegin(uint16_t DataWidth = DATASIZE_16BIT) {}; + static void DataTransferEnd() {}; + + static void WriteData(uint16_t Data) { Transmit(Data); } + static void WriteReg(uint16_t Reg); + + static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_PINC_MODE, Data, Count); } + static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_CIRC_MODE, &Data, Count); } + static void WriteMultiple(uint16_t Color, uint32_t Count) { + static uint16_t Data; Data = Color; + while (Count > 0) { + TransmitDMA(DMA_CIRC_MODE, &Data, Count > 0xFFFF ? 0xFFFF : Count); + Count = Count > 0xFFFF ? Count - 0xFFFF : 0; + } + } +}; diff --git a/Marlin/src/HAL/STM32F1/tft/tft_spi.cpp b/Marlin/src/HAL/STM32F1/tft/tft_spi.cpp new file mode 100644 index 000000000000..1095389946ad --- /dev/null +++ b/Marlin/src/HAL/STM32F1/tft/tft_spi.cpp @@ -0,0 +1,149 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfig.h" + +#if HAS_SPI_TFT + +#include "tft_spi.h" + +// TFT_SPI tft; + +SPIClass TFT_SPI::SPIx(1); + +#define TFT_CS_H OUT_WRITE(TFT_CS_PIN, HIGH) +#define TFT_CS_L OUT_WRITE(TFT_CS_PIN, LOW) + +#define TFT_DC_H OUT_WRITE(TFT_DC_PIN, HIGH) +#define TFT_DC_L OUT_WRITE(TFT_DC_PIN, LOW) + +#define TFT_RST_H OUT_WRITE(TFT_RST_PIN, HIGH) +#define TFT_RST_L OUT_WRITE(TFT_RST_PIN, LOW) + +#define TFT_BLK_H OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH) +#define TFT_BLK_L OUT_WRITE(TFT_BACKLIGHT_PIN, LOW) + +void TFT_SPI::Init() { + #if PIN_EXISTS(TFT_RESET) + // OUT_WRITE(TFT_RESET_PIN, HIGH); + TFT_RST_H; + delay(100); + #endif + + #if PIN_EXISTS(TFT_BACKLIGHT) + // OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH); + TFT_BLK_H; + #endif + + TFT_DC_H; + TFT_CS_H; + + /** + * STM32F1 APB2 = 72MHz, APB1 = 36MHz, max SPI speed of this MCU if 18Mhz + * STM32F1 has 3 SPI ports, SPI1 in APB2, SPI2/SPI3 in APB1 + * so the minimum prescale of SPI1 is DIV4, SPI2/SPI3 is DIV2 + */ + #if SPI_DEVICE == 1 + #define SPI_CLOCK_MAX SPI_CLOCK_DIV4 + #else + #define SPI_CLOCK_MAX SPI_CLOCK_DIV2 + #endif + uint8_t clock; + uint8_t spiRate = SPI_FULL_SPEED; + switch (spiRate) { + case SPI_FULL_SPEED: clock = SPI_CLOCK_MAX ; break; + case SPI_HALF_SPEED: clock = SPI_CLOCK_DIV4 ; break; + case SPI_QUARTER_SPEED: clock = SPI_CLOCK_DIV8 ; break; + case SPI_EIGHTH_SPEED: clock = SPI_CLOCK_DIV16; break; + case SPI_SPEED_5: clock = SPI_CLOCK_DIV32; break; + case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break; + default: clock = SPI_CLOCK_DIV2; // Default from the SPI library + } + SPIx.setModule(1); + SPIx.setClockDivider(clock); + SPIx.setBitOrder(MSBFIRST); + SPIx.setDataMode(SPI_MODE0); +} + +void TFT_SPI::DataTransferBegin(uint16_t DataSize) { + SPIx.setDataSize(DataSize); + SPIx.begin(); + TFT_CS_L; +} + +uint32_t TFT_SPI::GetID() { + uint32_t id; + id = ReadID(LCD_READ_ID); + + if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF) + id = ReadID(LCD_READ_ID4); + return id; +} + +uint32_t TFT_SPI::ReadID(uint16_t Reg) { + #if !PIN_EXISTS(TFT_MISO) + return 0; + #else + uint8_t d = 0; + uint32_t data = 0; + SPIx.setClockDivider(SPI_CLOCK_DIV16); + DataTransferBegin(DATASIZE_8BIT); + WriteReg(Reg); + + LOOP_L_N(i, 4) { + SPIx.read((uint8_t*)&d, 1); + data = (data << 8) | d; + } + + DataTransferEnd(); + SPIx.setClockDivider(SPI_CLOCK_MAX); + + return data >> 7; + #endif +} + +bool TFT_SPI::isBusy() { + return false; +} + +void TFT_SPI::Abort() { + DataTransferEnd(); +} + +void TFT_SPI::Transmit(uint16_t Data) { + SPIx.send(Data); +} + +void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) { + DataTransferBegin(); + TFT_DC_H; + if (MemoryIncrease == DMA_MINC_ENABLE) { + SPIx.dmaSend(Data, Count, true); + } + else { + SPIx.dmaSend(Data, Count, false); + } + + DataTransferEnd(); +} + +#endif // HAS_SPI_TFT diff --git a/Marlin/src/HAL/STM32F1/tft/tft_spi.h b/Marlin/src/HAL/STM32F1/tft/tft_spi.h new file mode 100644 index 000000000000..da9a8e0c223e --- /dev/null +++ b/Marlin/src/HAL/STM32F1/tft/tft_spi.h @@ -0,0 +1,72 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../../../inc/MarlinConfig.h" + +#include + +#ifndef LCD_READ_ID + #define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341) +#endif +#ifndef LCD_READ_ID4 + #define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341) +#endif + +#define DATASIZE_8BIT DATA_SIZE_8BIT +#define DATASIZE_16BIT DATA_SIZE_16BIT +#define TFT_IO_DRIVER TFT_SPI + +#define DMA_MINC_ENABLE 1 +#define DMA_MINC_DISABLE 0 + +class TFT_SPI { +private: + static uint32_t ReadID(uint16_t Reg); + static void Transmit(uint16_t Data); + static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count); + +public: + static SPIClass SPIx; + + static void Init(); + static uint32_t GetID(); + static bool isBusy(); + static void Abort(); + + static void DataTransferBegin(uint16_t DataWidth = DATA_SIZE_16BIT); + static void DataTransferEnd() { WRITE(TFT_CS_PIN, HIGH); SPIx.end(); }; + static void DataTransferAbort(); + + static void WriteData(uint16_t Data) { Transmit(Data); } + static void WriteReg(uint16_t Reg) { WRITE(TFT_A0_PIN, LOW); Transmit(Reg); WRITE(TFT_A0_PIN, HIGH); } + + static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_MINC_ENABLE, Data, Count); } + static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &Data, Count); } + static void WriteMultiple(uint16_t Color, uint32_t Count) { + static uint16_t Data; Data = Color; + while (Count > 0) { + TransmitDMA(DMA_MINC_DISABLE, &Data, Count > 0xFFFF ? 0xFFFF : Count); + Count = Count > 0xFFFF ? Count - 0xFFFF : 0; + } + } +}; diff --git a/Marlin/src/HAL/STM32F1/tft/xpt2046.cpp b/Marlin/src/HAL/STM32F1/tft/xpt2046.cpp new file mode 100644 index 000000000000..616d05fead15 --- /dev/null +++ b/Marlin/src/HAL/STM32F1/tft/xpt2046.cpp @@ -0,0 +1,141 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfig.h" + +#if HAS_TFT_XPT2046 || HAS_TOUCH_XPT2046 + +#include "xpt2046.h" +#include + +uint16_t delta(uint16_t a, uint16_t b) { return a > b ? a - b : b - a; } + +#if ENABLED(TOUCH_BUTTONS_HW_SPI) + #include + + SPIClass XPT2046::SPIx(TOUCH_BUTTONS_HW_SPI_DEVICE); + + static void touch_spi_init(uint8_t spiRate) { + /** + * STM32F1 APB2 = 72MHz, APB1 = 36MHz, max SPI speed of this MCU if 18Mhz + * STM32F1 has 3 SPI ports, SPI1 in APB2, SPI2/SPI3 in APB1 + * so the minimum prescale of SPI1 is DIV4, SPI2/SPI3 is DIV2 + */ + uint8_t clock; + switch (spiRate) { + case SPI_FULL_SPEED: clock = SPI_CLOCK_DIV4; break; + case SPI_HALF_SPEED: clock = SPI_CLOCK_DIV4; break; + case SPI_QUARTER_SPEED: clock = SPI_CLOCK_DIV8; break; + case SPI_EIGHTH_SPEED: clock = SPI_CLOCK_DIV16; break; + case SPI_SPEED_5: clock = SPI_CLOCK_DIV32; break; + case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break; + default: clock = SPI_CLOCK_DIV2; // Default from the SPI library + } + XPT2046::SPIx.setModule(TOUCH_BUTTONS_HW_SPI_DEVICE); + XPT2046::SPIx.setClockDivider(clock); + XPT2046::SPIx.setBitOrder(MSBFIRST); + XPT2046::SPIx.setDataMode(SPI_MODE0); + } +#endif // TOUCH_BUTTONS_HW_SPI + +void XPT2046::Init() { + SET_INPUT(TOUCH_MISO_PIN); + SET_OUTPUT(TOUCH_MOSI_PIN); + SET_OUTPUT(TOUCH_SCK_PIN); + OUT_WRITE(TOUCH_CS_PIN, HIGH); + + #if PIN_EXISTS(TOUCH_INT) + // Optional Pendrive interrupt pin + SET_INPUT(TOUCH_INT_PIN); + #endif + + TERN_(TOUCH_BUTTONS_HW_SPI, touch_spi_init(SPI_SPEED_6)); + + // Read once to enable pendrive status pin + getRawData(XPT2046_X); +} + +bool XPT2046::isTouched() { + return isBusy() ? false : ( + #if PIN_EXISTS(TOUCH_INT) + READ(TOUCH_INT_PIN) != HIGH + #else + getRawData(XPT2046_Z1) >= XPT2046_Z1_THRESHOLD + #endif + ); +} + +bool XPT2046::getRawPoint(int16_t *x, int16_t *y) { + if (isBusy()) return false; + if (!isTouched()) return false; + *x = getRawData(XPT2046_X); + *y = getRawData(XPT2046_Y); + return isTouched(); +} + +uint16_t XPT2046::getRawData(const XPTCoordinate coordinate) { + uint16_t data[3]; + + DataTransferBegin(); + TERN_(TOUCH_BUTTONS_HW_SPI, SPIx.begin()); + + for (uint16_t i = 0; i < 3 ; i++) { + IO(coordinate); + data[i] = (IO() << 4) | (IO() >> 4); + } + + TERN_(TOUCH_BUTTONS_HW_SPI, SPIx.end()); + DataTransferEnd(); + + uint16_t delta01 = delta(data[0], data[1]), + delta02 = delta(data[0], data[2]), + delta12 = delta(data[1], data[2]); + + if (delta01 > delta02 || delta01 > delta12) + data[delta02 > delta12 ? 0 : 1] = data[2]; + + return (data[0] + data[1]) >> 1; +} + +uint16_t XPT2046::IO(uint16_t data) { + return TERN(TOUCH_BUTTONS_HW_SPI, HardwareIO, SoftwareIO)(data); +} + +#if ENABLED(TOUCH_BUTTONS_HW_SPI) + uint16_t XPT2046::HardwareIO(uint16_t data) { + uint16_t result = SPIx.transfer(data); + return result; + } +#endif + +uint16_t XPT2046::SoftwareIO(uint16_t data) { + uint16_t result = 0; + + for (uint8_t j = 0x80; j; j >>= 1) { + WRITE(TOUCH_SCK_PIN, LOW); + WRITE(TOUCH_MOSI_PIN, data & j ? HIGH : LOW); + if (READ(TOUCH_MISO_PIN)) result |= j; + WRITE(TOUCH_SCK_PIN, HIGH); + } + WRITE(TOUCH_SCK_PIN, LOW); + + return result; +} + +#endif // HAS_TFT_XPT2046 diff --git a/Marlin/src/HAL/STM32F1/tft/xpt2046.h b/Marlin/src/HAL/STM32F1/tft/xpt2046.h new file mode 100644 index 000000000000..019f75efce12 --- /dev/null +++ b/Marlin/src/HAL/STM32F1/tft/xpt2046.h @@ -0,0 +1,80 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../../../inc/MarlinConfig.h" + +#if ENABLED(TOUCH_BUTTONS_HW_SPI) + #include +#endif + +#ifndef TOUCH_MISO_PIN + #define TOUCH_MISO_PIN MISO_PIN +#endif +#ifndef TOUCH_MOSI_PIN + #define TOUCH_MOSI_PIN MOSI_PIN +#endif +#ifndef TOUCH_SCK_PIN + #define TOUCH_SCK_PIN SCK_PIN +#endif +#ifndef TOUCH_CS_PIN + #define TOUCH_CS_PIN CS_PIN +#endif +#ifndef TOUCH_INT_PIN + #define TOUCH_INT_PIN -1 +#endif + +#define XPT2046_DFR_MODE 0x00 +#define XPT2046_SER_MODE 0x04 +#define XPT2046_CONTROL 0x80 + +enum XPTCoordinate : uint8_t { + XPT2046_X = 0x10 | XPT2046_CONTROL | XPT2046_DFR_MODE, + XPT2046_Y = 0x50 | XPT2046_CONTROL | XPT2046_DFR_MODE, + XPT2046_Z1 = 0x30 | XPT2046_CONTROL | XPT2046_DFR_MODE, + XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE, +}; + +#if !defined(XPT2046_Z1_THRESHOLD) + #define XPT2046_Z1_THRESHOLD 10 +#endif + +class XPT2046 { +private: + static bool isBusy() { return false; } + + static uint16_t getRawData(const XPTCoordinate coordinate); + static bool isTouched(); + + static inline void DataTransferBegin() { WRITE(TOUCH_CS_PIN, LOW); }; + static inline void DataTransferEnd() { WRITE(TOUCH_CS_PIN, HIGH); }; + #if ENABLED(TOUCH_BUTTONS_HW_SPI) + static uint16_t HardwareIO(uint16_t data); + #endif + static uint16_t SoftwareIO(uint16_t data); + static uint16_t IO(uint16_t data = 0); + +public: + #if ENABLED(TOUCH_BUTTONS_HW_SPI) + static SPIClass SPIx; + #endif + + static void Init(); + static bool getRawPoint(int16_t *x, int16_t *y); +}; diff --git a/Marlin/src/HAL/HAL_STM32F1/timers.cpp b/Marlin/src/HAL/STM32F1/timers.cpp similarity index 93% rename from Marlin/src/HAL/HAL_STM32F1/timers.cpp rename to Marlin/src/HAL/STM32F1/timers.cpp index 720bd37ba490..8c2df1e216e7 100644 --- a/Marlin/src/HAL/HAL_STM32F1/timers.cpp +++ b/Marlin/src/HAL/STM32F1/timers.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -27,8 +27,6 @@ #ifdef __STM32F1__ #include "../../inc/MarlinConfig.h" -#include "HAL.h" -#include "timers.h" // ------------------------ // Local defines @@ -49,7 +47,10 @@ * TODO: Calculate Timer prescale value, so we get the 32bit to adjust */ -void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { + + + +void timer_set_interrupt_priority(uint_fast8_t timer_num, uint_fast8_t priority) { nvic_irq_num irq_num; switch (timer_num) { case 1: irq_num = NVIC_TIMER1_CC; break; @@ -66,9 +67,14 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { * This should never happen. Add a Sanitycheck for timer number. * Should be a general timer since basic timers have no CC channels. */ - break; + return; } + nvic_irq_set_priority(irq_num, priority); +} + + +void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { /** * Give the Stepper ISR a higher priority (lower number) * so it automatically preempts the Temperature ISR. @@ -85,7 +91,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { timer_set_compare(STEP_TIMER_DEV, STEP_TIMER_CHAN, _MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (STEPPER_TIMER_RATE) / frequency)); timer_no_ARR_preload_ARPE(STEP_TIMER_DEV); // Need to be sure no preload on ARR register timer_attach_interrupt(STEP_TIMER_DEV, STEP_TIMER_CHAN, stepTC_Handler); - nvic_irq_set_priority(irq_num, STEP_TIMER_IRQ_PRIO); + timer_set_interrupt_priority(STEP_TIMER_NUM, STEP_TIMER_IRQ_PRIO); timer_generate_update(STEP_TIMER_DEV); timer_resume(STEP_TIMER_DEV); break; @@ -97,7 +103,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { timer_set_reload(TEMP_TIMER_DEV, 0xFFFF); timer_set_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, _MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (F_CPU) / (TEMP_TIMER_PRESCALE) / frequency)); timer_attach_interrupt(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, tempTC_Handler); - nvic_irq_set_priority(irq_num, TEMP_TIMER_IRQ_PRIO); + timer_set_interrupt_priority(TEMP_TIMER_NUM, TEMP_TIMER_IRQ_PRIO); timer_generate_update(TEMP_TIMER_DEV); timer_resume(TEMP_TIMER_DEV); break; diff --git a/Marlin/src/HAL/HAL_STM32F1/timers.h b/Marlin/src/HAL/STM32F1/timers.h similarity index 84% rename from Marlin/src/HAL/HAL_STM32F1/timers.h rename to Marlin/src/HAL/STM32F1/timers.h index e5733cc563f5..6f360f6bfc39 100644 --- a/Marlin/src/HAL/HAL_STM32F1/timers.h +++ b/Marlin/src/HAL/STM32F1/timers.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -44,8 +44,12 @@ typedef uint16_t hal_timer_t; #define HAL_TIMER_RATE uint32_t(F_CPU) // frequency of timers peripherals -#define STEP_TIMER_CHAN 1 // Channel of the timer to use for compare and interrupts -#define TEMP_TIMER_CHAN 1 // Channel of the timer to use for compare and interrupts +#ifndef STEP_TIMER_CHAN + #define STEP_TIMER_CHAN 1 // Channel of the timer to use for compare and interrupts +#endif +#ifndef TEMP_TIMER_CHAN + #define TEMP_TIMER_CHAN 1 // Channel of the timer to use for compare and interrupts +#endif /** * Note: Timers may be used by platforms and libraries @@ -61,14 +65,20 @@ typedef uint16_t hal_timer_t; * - Otherwise it uses Timer 8 on boards with STM32_HIGH_DENSITY * or Timer 4 on other boards. */ -#if defined(MCU_STM32F103CB) || defined(MCU_STM32F103C8) - #define STEP_TIMER_NUM 4 // For C8/CB boards, use timer 4 -#else - #define STEP_TIMER_NUM 5 // for other boards, five is fine. +#ifndef STEP_TIMER_NUM + #if defined(MCU_STM32F103CB) || defined(MCU_STM32F103C8) + #define STEP_TIMER_NUM 4 // For C8/CB boards, use timer 4 + #else + #define STEP_TIMER_NUM 5 // for other boards, five is fine. + #endif +#endif +#ifndef PULSE_TIMER_NUM + #define PULSE_TIMER_NUM STEP_TIMER_NUM +#endif +#ifndef TEMP_TIMER_NUM + #define TEMP_TIMER_NUM 2 // Timer Index for Temperature + //#define TEMP_TIMER_NUM 4 // 2->4, Timer 2 for Stepper Current PWM #endif -#define TEMP_TIMER_NUM 2 // index of timer to use for temperature -//#define TEMP_TIMER_NUM 4 // 2->4, Timer 2 for Stepper Current PWM -#define PULSE_TIMER_NUM STEP_TIMER_NUM #if MB(BTT_SKR_MINI_E3_V1_0, BTT_SKR_E3_DIP, BTT_SKR_MINI_E3_V1_2, MKS_ROBIN_LITE) // SKR Mini E3 boards use PA8 as FAN_PIN, so TIMER 1 is used for Fan PWM. @@ -81,8 +91,9 @@ typedef uint16_t hal_timer_t; #define SERVO0_TIMER_NUM 1 // SERVO0 or BLTOUCH #endif -#define STEP_TIMER_IRQ_PRIO 1 -#define TEMP_TIMER_IRQ_PRIO 2 +#define STEP_TIMER_IRQ_PRIO 2 +#define TEMP_TIMER_IRQ_PRIO 3 +#define SERVO0_TIMER_IRQ_PRIO 1 #define TEMP_TIMER_PRESCALE 1000 // prescaler for setting Temp timer, 72Khz #define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency @@ -111,8 +122,12 @@ timer_dev* get_timer_dev(int number); // TODO change this -#define HAL_TEMP_TIMER_ISR() extern "C" void tempTC_Handler() -#define HAL_STEP_TIMER_ISR() extern "C" void stepTC_Handler() +#ifndef HAL_TEMP_TIMER_ISR + #define HAL_TEMP_TIMER_ISR() extern "C" void tempTC_Handler() +#endif +#ifndef HAL_STEP_TIMER_ISR + #define HAL_STEP_TIMER_ISR() extern "C" void stepTC_Handler() +#endif extern "C" void tempTC_Handler(); extern "C" void stepTC_Handler(); @@ -179,4 +194,6 @@ FORCE_INLINE static void timer_no_ARR_preload_ARPE(timer_dev *dev) { bb_peri_set_bit(&(dev->regs).gen->CR1, TIMER_CR1_ARPE_BIT, 0); } +void timer_set_interrupt_priority(uint_fast8_t timer_num, uint_fast8_t priority); + #define TIMER_OC_NO_PRELOAD 0 // Need to disable preload also on compare registers. diff --git a/Marlin/src/HAL/HAL_STM32F1/watchdog.cpp b/Marlin/src/HAL/STM32F1/watchdog.cpp similarity index 90% rename from Marlin/src/HAL/HAL_STM32F1/watchdog.cpp rename to Marlin/src/HAL/STM32F1/watchdog.cpp index 9556d1fa66e8..ca91a6fe4350 100644 --- a/Marlin/src/HAL/HAL_STM32F1/watchdog.cpp +++ b/Marlin/src/HAL/STM32F1/watchdog.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -52,7 +52,9 @@ void watchdogSetup() { * @details The watchdog clock is 40Khz. We need a 4 seconds interval, so use a /256 preescaler and 625 reload value (counts down to 0) */ void watchdog_init() { - //iwdg_init(IWDG_PRE_256, STM32F1_WD_RELOAD); + #if DISABLED(DISABLE_WATCHDOG_INIT) + iwdg_init(IWDG_PRE_256, STM32F1_WD_RELOAD); + #endif } #endif // USE_WATCHDOG diff --git a/Marlin/src/HAL/HAL_STM32F1/watchdog.h b/Marlin/src/HAL/STM32F1/watchdog.h similarity index 94% rename from Marlin/src/HAL/HAL_STM32F1/watchdog.h rename to Marlin/src/HAL/STM32F1/watchdog.h index 7218b1a72022..7185d6977521 100644 --- a/Marlin/src/HAL/HAL_STM32F1/watchdog.h +++ b/Marlin/src/HAL/STM32F1/watchdog.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/HAL.cpp b/Marlin/src/HAL/STM32_F4_F7/HAL.cpp similarity index 97% rename from Marlin/src/HAL/HAL_STM32_F4_F7/HAL.cpp rename to Marlin/src/HAL/STM32_F4_F7/HAL.cpp index 5acda8af41e8..b4629d2afd12 100644 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/HAL.cpp +++ b/Marlin/src/HAL/STM32_F4_F7/HAL.cpp @@ -17,10 +17,9 @@ * 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 . + * along with this program. If not, see . * */ - #if defined(STM32GENERIC) && (defined(STM32F4) || defined(STM32F7)) #include "HAL.h" diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/HAL.h b/Marlin/src/HAL/STM32_F4_F7/HAL.h similarity index 64% rename from Marlin/src/HAL/HAL_STM32_F4_F7/HAL.h rename to Marlin/src/HAL/STM32_F4_F7/HAL.h index b5d8ac29cf4f..00a65de7926f 100644 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/HAL.h +++ b/Marlin/src/HAL/STM32_F4_F7/HAL.h @@ -17,7 +17,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -31,7 +31,6 @@ #include "../shared/HAL_SPI.h" #include "fastio.h" -#include "timers.h" #include "watchdog.h" #include @@ -47,22 +46,16 @@ // Serial override //extern HalSerial usb_serial; +#define _MSERIAL(X) SerialUART##X +#define MSERIAL(X) _MSERIAL(X) +#define SerialUART0 Serial1 + #if defined(STM32F4) && SERIAL_PORT == 0 #error "SERIAL_PORT cannot be 0. (Port 0 does not exist.) Please update your configuration." #elif SERIAL_PORT == -1 #define MYSERIAL0 SerialUSB -#elif SERIAL_PORT == 1 - #define MYSERIAL0 SerialUART1 -#elif SERIAL_PORT == 2 - #define MYSERIAL0 SerialUART2 -#elif SERIAL_PORT == 3 - #define MYSERIAL0 SerialUART3 -#elif SERIAL_PORT == 4 - #define MYSERIAL0 SerialUART4 -#elif SERIAL_PORT == 5 - #define MYSERIAL0 SerialUART5 -#elif SERIAL_PORT == 6 - #define MYSERIAL0 SerialUART6 +#elif WITHIN(SERIAL_PORT, 0, 6) + #define MYSERIAL0 MSERIAL(SERIAL_PORT) #else #error "SERIAL_PORT must be from -1 to 6. Please update your configuration." #endif @@ -70,53 +63,24 @@ #ifdef SERIAL_PORT_2 #if defined(STM32F4) && SERIAL_PORT_2 == 0 #error "SERIAL_PORT_2 cannot be 0. (Port 0 does not exist.) Please update your configuration." - #elif SERIAL_PORT_2 == SERIAL_PORT - #error "SERIAL_PORT_2 must be different than SERIAL_PORT. Please update your configuration." #elif SERIAL_PORT_2 == -1 #define MYSERIAL1 SerialUSB - #elif SERIAL_PORT_2 == 1 - #define MYSERIAL1 SerialUART1 - #elif SERIAL_PORT_2 == 2 - #define MYSERIAL1 SerialUART2 - #elif SERIAL_PORT_2 == 3 - #define MYSERIAL1 SerialUART3 - #elif SERIAL_PORT_2 == 4 - #define MYSERIAL1 SerialUART4 - #elif SERIAL_PORT_2 == 5 - #define MYSERIAL1 SerialUART5 - #elif SERIAL_PORT_2 == 6 - #define MYSERIAL1 SerialUART6 + #elif WITHIN(SERIAL_PORT_2, 0, 6) + #define MYSERIAL1 MSERIAL(SERIAL_PORT_2) #else #error "SERIAL_PORT_2 must be from -1 to 6. Please update your configuration." #endif - #define NUM_SERIAL 2 -#else - #define NUM_SERIAL 1 #endif -#ifdef DGUS_SERIAL_PORT - #if defined(STM32F4) && DGUS_SERIAL_PORT == 0 - #error "DGUS_SERIAL_PORT cannot be 0. (Port 0 does not exist.) Please update your configuration." - #elif DGUS_SERIAL_PORT == SERIAL_PORT - #error "DGUS_SERIAL_PORT must be different than SERIAL_PORT. Please update your configuration." - #elif defined(SERIAL_PORT_2) && DGUS_SERIAL_PORT == SERIAL_PORT_2 - #error "DGUS_SERIAL_PORT must be different than SERIAL_PORT_2. Please update your configuration." - #elif DGUS_SERIAL_PORT == -1 - #define DGUS_SERIAL SerialUSB - #elif DGUS_SERIAL_PORT == 1 - #define DGUS_SERIAL SerialUART1 - #elif DGUS_SERIAL_PORT == 2 - #define DGUS_SERIAL SerialUART2 - #elif DGUS_SERIAL_PORT == 3 - #define DGUS_SERIAL SerialUART3 - #elif DGUS_SERIAL_PORT == 4 - #define DGUS_SERIAL SerialUART4 - #elif DGUS_SERIAL_PORT == 5 - #define DGUS_SERIAL SerialUART5 - #elif DGUS_SERIAL_PORT == 6 - #define DGUS_SERIAL SerialUART6 +#ifdef LCD_SERIAL_PORT + #if defined(STM32F4) && LCD_SERIAL_PORT == 0 + #error "LCD_SERIAL_PORT cannot be 0. (Port 0 does not exist.) Please update your configuration." + #elif LCD_SERIAL_PORT == -1 + #define LCD_SERIAL SerialUSB + #elif WITHIN(LCD_SERIAL_PORT, 0, 6) + #define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT) #else - #error "DGUS_SERIAL_PORT must be from -1 to 6. Please update your configuration." + #error "LCD_SERIAL_PORT must be from -1 to 6. Please update your configuration." #endif #endif @@ -178,6 +142,8 @@ void HAL_clear_reset_source(); // Reset reason uint8_t HAL_get_reset_source(); +inline void HAL_reboot() {} // reboot the board or restart the bootloader + void _delay_ms(const int delay); /* @@ -206,19 +172,6 @@ static inline int freeMemory() { #pragma GCC diagnostic pop -// -// EEPROM -// - -/** - * TODO: Write all this EEPROM stuff. Can emulate EEPROM in flash as last resort. - * Wire library should work for i2c EEPROMs. - */ -void eeprom_write_byte(uint8_t *pos, unsigned char value); -uint8_t eeprom_read_byte(uint8_t *pos); -void eeprom_read_block (void *__dst, const void *__src, size_t __n); -void eeprom_update_block (const void *__src, void *__dst, size_t __n); - // // ADC // @@ -227,8 +180,9 @@ void eeprom_update_block (const void *__src, void *__dst, size_t __n); inline void HAL_adc_init() {} -#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin) +#define HAL_ADC_VREF 3.3 #define HAL_ADC_RESOLUTION 10 +#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin) #define HAL_READ_ADC() HAL_adc_result #define HAL_ADC_READY() true diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/HAL_SPI.cpp b/Marlin/src/HAL/STM32_F4_F7/HAL_SPI.cpp similarity index 96% rename from Marlin/src/HAL/HAL_STM32_F4_F7/HAL_SPI.cpp rename to Marlin/src/HAL/STM32_F4_F7/HAL_SPI.cpp index deb14f2cfefc..ebd0b4cee7d0 100644 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/HAL_SPI.cpp +++ b/Marlin/src/HAL/STM32_F4_F7/HAL_SPI.cpp @@ -17,9 +17,10 @@ * 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 . + * along with this program. If not, see . * */ +#if defined(STM32GENERIC) && (defined(STM32F4) || defined(STM32F7)) /** * Software SPI functions originally from Arduino Sd2Card Library @@ -30,8 +31,6 @@ * Adapted to the Marlin STM32F4/7 HAL */ -#if defined(STM32GENERIC) && (defined(STM32F4) || defined(STM32F7)) - #include "../../inc/MarlinConfig.h" #include @@ -73,7 +72,7 @@ static SPISettings spiConfig; */ void spiBegin() { #if !defined(SS_PIN) || SS_PIN < 0 - #error SS_PIN not defined! + #error "SS_PIN not defined!" #endif OUT_WRITE(SS_PIN, HIGH); @@ -121,7 +120,7 @@ uint8_t spiRec() { */ void spiRead(uint8_t* buf, uint16_t nbyte) { SPI.beginTransaction(spiConfig); - #ifdef STM32GENERIC + #ifndef STM32GENERIC SPI.dmaTransfer(0, const_cast(buf), nbyte); #else SPI.transfer((uint8_t*)buf, nbyte); @@ -153,7 +152,7 @@ void spiSend(uint8_t b) { void spiSendBlock(uint8_t token, const uint8_t* buf) { SPI.beginTransaction(spiConfig); SPI.transfer(token); - #ifdef STM32GENERIC + #ifndef STM32GENERIC SPI.dmaSend(const_cast(buf), 512); #else SPI.transfer((uint8_t*)buf, nullptr, 512); diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/README.md b/Marlin/src/HAL/STM32_F4_F7/README.md similarity index 100% rename from Marlin/src/HAL/HAL_STM32_F4_F7/README.md rename to Marlin/src/HAL/STM32_F4_F7/README.md diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/STM32F4/README.md b/Marlin/src/HAL/STM32_F4_F7/STM32F4/README.md similarity index 100% rename from Marlin/src/HAL/HAL_STM32_F4_F7/STM32F4/README.md rename to Marlin/src/HAL/STM32_F4_F7/STM32F4/README.md diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/STM32F4/timers.cpp b/Marlin/src/HAL/STM32_F4_F7/STM32F4/timers.cpp similarity index 97% rename from Marlin/src/HAL/HAL_STM32_F4_F7/STM32F4/timers.cpp rename to Marlin/src/HAL/STM32_F4_F7/STM32F4/timers.cpp index ffd46dae6053..dc41f891318d 100644 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/STM32F4/timers.cpp +++ b/Marlin/src/HAL/STM32_F4_F7/STM32F4/timers.cpp @@ -16,14 +16,12 @@ * 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 . + * along with this program. If not, see . * */ - #if defined(STM32GENERIC) && defined(STM32F4) -#include "../HAL.h" -#include "timers.h" +#include "../../../inc/MarlinConfig.h" // ------------------------ // Local defines diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/STM32F4/timers.h b/Marlin/src/HAL/STM32_F4_F7/STM32F4/timers.h similarity index 85% rename from Marlin/src/HAL/HAL_STM32_F4_F7/STM32F4/timers.h rename to Marlin/src/HAL/STM32_F4_F7/STM32F4/timers.h index c52f5ea21c9b..a4a7ad82cca9 100644 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/STM32F4/timers.h +++ b/Marlin/src/HAL/STM32_F4_F7/STM32F4/timers.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -34,9 +34,15 @@ #define HAL_TIMER_RATE (HAL_RCC_GetSysClockFreq() / 2) // frequency of timer peripherals -#define STEP_TIMER_NUM 0 // index of timer to use for stepper -#define TEMP_TIMER_NUM 1 // index of timer to use for temperature -#define PULSE_TIMER_NUM STEP_TIMER_NUM +#ifndef STEP_TIMER_NUM + #define STEP_TIMER_NUM 0 // Timer Index for Stepper +#endif +#ifndef PULSE_TIMER_NUM + #define PULSE_TIMER_NUM STEP_TIMER_NUM +#endif +#ifndef TEMP_TIMER_NUM + #define TEMP_TIMER_NUM 1 // Timer Index for Temperature +#endif #define TEMP_TIMER_PRESCALE 1000 // prescaler for setting Temp timer, 72Khz #define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency @@ -59,17 +65,19 @@ // TODO change this #ifdef STM32GENERIC - extern void TC5_Handler(); - extern void TC7_Handler(); - #define HAL_STEP_TIMER_ISR() void TC5_Handler() - #define HAL_TEMP_TIMER_ISR() void TC7_Handler() + #define TC_TIMER_ARGS #else - extern void TC5_Handler(stimer_t *htim); - extern void TC7_Handler(stimer_t *htim); - #define HAL_STEP_TIMER_ISR() void TC5_Handler(stimer_t *htim) - #define HAL_TEMP_TIMER_ISR() void TC7_Handler(stimer_t *htim) + #define TC_TIMER_ARGS stimer_t *htim #endif +extern void TC5_Handler(TC_TIMER_ARGS); +extern void TC7_Handler(TC_TIMER_ARGS); +#ifndef HAL_STEP_TIMER_ISR + #define HAL_STEP_TIMER_ISR() void TC5_Handler(TC_TIMER_ARGS) +#endif +#ifndef HAL_TEMP_TIMER_ISR + #define HAL_TEMP_TIMER_ISR() void TC7_Handler(TC_TIMER_ARGS) +#endif // ------------------------ // Types diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/README.md b/Marlin/src/HAL/STM32_F4_F7/STM32F7/README.md similarity index 100% rename from Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/README.md rename to Marlin/src/HAL/STM32_F4_F7/STM32F7/README.md diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/TMC2660.cpp b/Marlin/src/HAL/STM32_F4_F7/STM32F7/TMC2660.cpp similarity index 96% rename from Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/TMC2660.cpp rename to Marlin/src/HAL/STM32_F4_F7/STM32F7/TMC2660.cpp index b03045902935..e67808c3c458 100644 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/TMC2660.cpp +++ b/Marlin/src/HAL/STM32_F4_F7/STM32F7/TMC2660.cpp @@ -22,7 +22,6 @@ * 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. - * */ #if defined(STM32GENERIC) && defined(STM32F7) @@ -40,14 +39,14 @@ #include "../../../module/stepper/indirection.h" #include "../../../module/printcounter.h" #include "../../../libs/duration_t.h" -#include "../../../libs/hex_print_routines.h" +#include "../../../libs/hex_print.h" //some default values used in initialization #define DEFAULT_MICROSTEPPING_VALUE 32 //TMC26X register definitions -#define DRIVER_CONTROL_REGISTER 0x0ul -#define CHOPPER_CONFIG_REGISTER 0x80000ul +#define DRIVER_CONTROL_REGISTER 0x0UL +#define CHOPPER_CONFIG_REGISTER 0x80000UL #define COOL_STEP_REGISTER 0xA0000ul #define STALL_GUARD2_LOAD_MEASURE_REGISTER 0xC0000ul #define DRIVER_CONFIG_REGISTER 0xE0000ul @@ -56,58 +55,58 @@ //definitions for the driver control register #define MICROSTEPPING_PATTERN 0xFul -#define STEP_INTERPOLATION 0x200ul -#define DOUBLE_EDGE_STEP 0x100ul -#define VSENSE 0x40ul -#define READ_MICROSTEP_POSTION 0x0ul -#define READ_STALL_GUARD_READING 0x10ul -#define READ_STALL_GUARD_AND_COOL_STEP 0x20ul -#define READ_SELECTION_PATTERN 0x30ul +#define STEP_INTERPOLATION 0x200UL +#define DOUBLE_EDGE_STEP 0x100UL +#define VSENSE 0x40UL +#define READ_MICROSTEP_POSTION 0x0UL +#define READ_STALL_GUARD_READING 0x10UL +#define READ_STALL_GUARD_AND_COOL_STEP 0x20UL +#define READ_SELECTION_PATTERN 0x30UL //definitions for the chopper config register -#define CHOPPER_MODE_STANDARD 0x0ul -#define CHOPPER_MODE_T_OFF_FAST_DECAY 0x4000ul +#define CHOPPER_MODE_STANDARD 0x0UL +#define CHOPPER_MODE_T_OFF_FAST_DECAY 0x4000UL #define T_OFF_PATTERN 0xFul -#define RANDOM_TOFF_TIME 0x2000ul -#define BLANK_TIMING_PATTERN 0x18000ul +#define RANDOM_TOFF_TIME 0x2000UL +#define BLANK_TIMING_PATTERN 0x18000UL #define BLANK_TIMING_SHIFT 15 -#define HYSTERESIS_DECREMENT_PATTERN 0x1800ul +#define HYSTERESIS_DECREMENT_PATTERN 0x1800UL #define HYSTERESIS_DECREMENT_SHIFT 11 -#define HYSTERESIS_LOW_VALUE_PATTERN 0x780ul +#define HYSTERESIS_LOW_VALUE_PATTERN 0x780UL #define HYSTERESIS_LOW_SHIFT 7 -#define HYSTERESIS_START_VALUE_PATTERN 0x78ul +#define HYSTERESIS_START_VALUE_PATTERN 0x78UL #define HYSTERESIS_START_VALUE_SHIFT 4 #define T_OFF_TIMING_PATERN 0xFul //definitions for cool step register -#define MINIMUM_CURRENT_FOURTH 0x8000ul -#define CURRENT_DOWN_STEP_SPEED_PATTERN 0x6000ul +#define MINIMUM_CURRENT_FOURTH 0x8000UL +#define CURRENT_DOWN_STEP_SPEED_PATTERN 0x6000UL #define SE_MAX_PATTERN 0xF00ul -#define SE_CURRENT_STEP_WIDTH_PATTERN 0x60ul +#define SE_CURRENT_STEP_WIDTH_PATTERN 0x60UL #define SE_MIN_PATTERN 0xFul //definitions for StallGuard2 current register -#define STALL_GUARD_FILTER_ENABLED 0x10000ul +#define STALL_GUARD_FILTER_ENABLED 0x10000UL #define STALL_GUARD_TRESHHOLD_VALUE_PATTERN 0x17F00ul #define CURRENT_SCALING_PATTERN 0x1Ful #define STALL_GUARD_CONFIG_PATTERN 0x17F00ul #define STALL_GUARD_VALUE_PATTERN 0x7F00ul //definitions for the input from the TMC2660 -#define STATUS_STALL_GUARD_STATUS 0x1ul -#define STATUS_OVER_TEMPERATURE_SHUTDOWN 0x2ul -#define STATUS_OVER_TEMPERATURE_WARNING 0x4ul -#define STATUS_SHORT_TO_GROUND_A 0x8ul -#define STATUS_SHORT_TO_GROUND_B 0x10ul -#define STATUS_OPEN_LOAD_A 0x20ul -#define STATUS_OPEN_LOAD_B 0x40ul -#define STATUS_STAND_STILL 0x80ul +#define STATUS_STALL_GUARD_STATUS 0x1UL +#define STATUS_OVER_TEMPERATURE_SHUTDOWN 0x2UL +#define STATUS_OVER_TEMPERATURE_WARNING 0x4UL +#define STATUS_SHORT_TO_GROUND_A 0x8UL +#define STATUS_SHORT_TO_GROUND_B 0x10UL +#define STATUS_OPEN_LOAD_A 0x20UL +#define STATUS_OPEN_LOAD_B 0x40UL +#define STATUS_STAND_STILL 0x80UL #define READOUT_VALUE_PATTERN 0xFFC00ul #define CPU_32_BIT //default values -#define INITIAL_MICROSTEPPING 0x3ul //32th microstepping +#define INITIAL_MICROSTEPPING 0x3UL //32th microstepping SPIClass SPI_6(SPI6, SPI6_MOSI_PIN, SPI6_MISO_PIN, SPI6_SCK_PIN); @@ -662,7 +661,6 @@ boolean TMC26XStepper::isEnabled() { return !!(chopper_config_register & T_OFF_P /** * reads a value from the TMC26X status register. The value is not obtained directly but can then * be read by the various status routines. - * */ void TMC26XStepper::readStatus(char read_value) { uint32_t old_driver_configuration_register_value = driver_configuration_register_value; diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/TMC2660.h b/Marlin/src/HAL/STM32_F4_F7/STM32F7/TMC2660.h similarity index 99% rename from Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/TMC2660.h rename to Marlin/src/HAL/STM32_F4_F7/STM32F7/TMC2660.h index f1d0133a3b14..208c3bc7e062 100644 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/TMC2660.h +++ b/Marlin/src/HAL/STM32_F4_F7/STM32F7/TMC2660.h @@ -22,7 +22,6 @@ * 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 diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/timers.cpp b/Marlin/src/HAL/STM32_F4_F7/STM32F7/timers.cpp similarity index 97% rename from Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/timers.cpp rename to Marlin/src/HAL/STM32_F4_F7/STM32F7/timers.cpp index d90f22e03af8..f7ded7454dd9 100644 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/timers.cpp +++ b/Marlin/src/HAL/STM32_F4_F7/STM32F7/timers.cpp @@ -16,14 +16,12 @@ * 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 . + * along with this program. If not, see . * */ - #if defined(STM32GENERIC) && defined(STM32F7) -#include "../HAL.h" -#include "timers.h" +#include "../../../inc/MarlinConfig.h" // ------------------------ // Local defines diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/timers.h b/Marlin/src/HAL/STM32_F4_F7/STM32F7/timers.h similarity index 86% rename from Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/timers.h rename to Marlin/src/HAL/STM32_F4_F7/STM32F7/timers.h index 00428c54f112..d2f78259d68d 100644 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/timers.h +++ b/Marlin/src/HAL/STM32_F4_F7/STM32F7/timers.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -34,9 +34,15 @@ #define HAL_TIMER_RATE (HAL_RCC_GetSysClockFreq() / 2) // frequency of timer peripherals -#define STEP_TIMER_NUM 0 // index of timer to use for stepper -#define TEMP_TIMER_NUM 1 // index of timer to use for temperature -#define PULSE_TIMER_NUM STEP_TIMER_NUM +#ifndef STEP_TIMER_NUM + #define STEP_TIMER_NUM 0 // Timer Index for Stepper +#endif +#ifndef PULSE_TIMER_NUM + #define PULSE_TIMER_NUM STEP_TIMER_NUM +#endif +#ifndef TEMP_TIMER_NUM + #define TEMP_TIMER_NUM 1 // Timer Index for Temperature +#endif #define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency #define TEMP_TIMER_PRESCALE 1000 // prescaler for setting Temp timer, 72Khz @@ -62,8 +68,12 @@ extern void TC5_Handler(); extern void TC7_Handler(); -#define HAL_STEP_TIMER_ISR() void TC5_Handler() -#define HAL_TEMP_TIMER_ISR() void TC7_Handler() +#ifndef HAL_STEP_TIMER_ISR + #define HAL_STEP_TIMER_ISR() void TC5_Handler() +#endif +#ifndef HAL_TEMP_TIMER_ISR + #define HAL_TEMP_TIMER_ISR() void TC7_Handler() +#endif // ------------------------ // Types diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/Servo.cpp b/Marlin/src/HAL/STM32_F4_F7/Servo.cpp similarity index 91% rename from Marlin/src/HAL/HAL_STM32_F4_F7/Servo.cpp rename to Marlin/src/HAL/STM32_F4_F7/Servo.cpp index e7fb15e6b17c..7185468f50a8 100644 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/Servo.cpp +++ b/Marlin/src/HAL/STM32_F4_F7/Servo.cpp @@ -17,10 +17,9 @@ * 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 . + * along with this program. If not, see . * */ - #if defined(STM32GENERIC) && (defined(STM32F4) || defined(STM32F7)) #include "../../inc/MarlinConfig.h" @@ -44,9 +43,7 @@ void libServo::move(const int value) { if (attach(0) >= 0) { write(value); safe_delay(servo_delay[servoIndex]); - #if ENABLED(DEACTIVATE_SERVOS_AFTER_MOVE) - detach(); - #endif + TERN_(DEACTIVATE_SERVOS_AFTER_MOVE, detach()); } } diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/Servo.h b/Marlin/src/HAL/STM32_F4_F7/Servo.h similarity index 94% rename from Marlin/src/HAL/HAL_STM32_F4_F7/Servo.h rename to Marlin/src/HAL/STM32_F4_F7/Servo.h index 076a547bb202..e42cc6084091 100644 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/Servo.h +++ b/Marlin/src/HAL/STM32_F4_F7/Servo.h @@ -17,7 +17,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/eeprom_emul.cpp b/Marlin/src/HAL/STM32_F4_F7/eeprom_emul.cpp similarity index 99% rename from Marlin/src/HAL/HAL_STM32_F4_F7/eeprom_emul.cpp rename to Marlin/src/HAL/STM32_F4_F7/eeprom_emul.cpp index 3358fa3df713..e0726c7cd592 100644 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/eeprom_emul.cpp +++ b/Marlin/src/HAL/STM32_F4_F7/eeprom_emul.cpp @@ -1,6 +1,6 @@ /** ****************************************************************************** - * @file EEPROM/EEPROM_Emulation/src/eeprom.c + * @file eeprom_emul.cpp * @author MCD Application Team * @version V1.2.6 * @date 04-November-2016 @@ -49,6 +49,10 @@ */ #if defined(STM32GENERIC) && (defined(STM32F4) || defined(STM32F7)) +#include "../../inc/MarlinConfig.h" + +#if ENABLED(FLASH_EEPROM_EMULATION) + /* Includes ------------------------------------------------------------------*/ #include "eeprom_emul.h" @@ -61,7 +65,7 @@ uint16_t DataVar = 0; uint16_t VirtAddVarTab[NB_OF_VAR]; /* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ + static HAL_StatusTypeDef EE_Format(); static uint16_t EE_FindValidPage(uint8_t Operation); static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data); @@ -75,6 +79,9 @@ static uint16_t EE_VerifyPageFullyErased(uint32_t Address); * @retval - Flash error code: on write Flash error * - FLASH_COMPLETE: on success */ + +/* Private functions ---------------------------------------------------------*/ + uint16_t EE_Initialize() { /* Get Page0 and Page1 status */ uint16_t PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS), @@ -329,7 +336,7 @@ uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data) { * @brief Erases PAGE and PAGE1 and writes VALID_PAGE header to PAGE * @param None * @retval Status of the last operation (Flash write or erase) done during - * EEPROM formating + * EEPROM formatting */ static HAL_StatusTypeDef EE_Format() { FLASH_EraseInitTypeDef pEraseInit; @@ -518,6 +525,7 @@ static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data) { return HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, NewPageAddress, VALID_PAGE); } +#endif // FLASH_EEPROM_EMULATION #endif // STM32GENERIC && (STM32F4 || STM32F7) /** diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/eeprom_emul.h b/Marlin/src/HAL/STM32_F4_F7/eeprom_emul.h similarity index 99% rename from Marlin/src/HAL/HAL_STM32_F4_F7/eeprom_emul.h rename to Marlin/src/HAL/STM32_F4_F7/eeprom_emul.h index e4094f8e134a..84c4c6e3d253 100644 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/eeprom_emul.h +++ b/Marlin/src/HAL/STM32_F4_F7/eeprom_emul.h @@ -50,7 +50,6 @@ // ------------------------ #include "../../inc/MarlinConfig.h" -#include "HAL.h" /* Exported constants --------------------------------------------------------*/ /* EEPROM emulation firmware error codes */ diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/EmulatedEeprom.cpp b/Marlin/src/HAL/STM32_F4_F7/eeprom_flash.cpp similarity index 55% rename from Marlin/src/HAL/HAL_STM32_F4_F7/EmulatedEeprom.cpp rename to Marlin/src/HAL/STM32_F4_F7/eeprom_flash.cpp index 4852234ba455..00b808fd4824 100644 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/EmulatedEeprom.cpp +++ b/Marlin/src/HAL/STM32_F4_F7/eeprom_flash.cpp @@ -13,39 +13,18 @@ * 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 . + * along with this program. If not, see . * */ - #if defined(STM32GENERIC) && (defined(STM32F4) || defined(STM32F7)) -/** - * Description: Functions for a Flash emulated EEPROM - * Not platform dependent. - */ - -// Include configs and pins to get all EEPROM flags #include "../../inc/MarlinConfig.h" -#ifdef STM32F7 - #define HAS_EMULATED_EEPROM 1 -#else - #define HAS_EMULATED_EEPROM NONE(I2C_EEPROM, SPI_EEPROM) -#endif - -#if HAS_EMULATED_EEPROM && ENABLED(EEPROM_SETTINGS) - -// ------------------------ -// Includes -// ------------------------ +#if ENABLED(FLASH_EEPROM_EMULATION) -#include "HAL.h" +#include "../shared/eeprom_api.h" #include "eeprom_emul.h" -// ------------------------ -// Local defines -// ------------------------ - // FLASH_FLAG_PGSERR (Programming Sequence Error) was renamed to // FLASH_FLAG_ERSERR (Erasing Sequence Error) in STM32F4/7 @@ -55,68 +34,78 @@ //#define FLASH_FLAG_PGSERR FLASH_FLAG_ERSERR #endif -// ------------------------ -// Private Variables -// ------------------------ - -static bool eeprom_initialized = false; - -// ------------------------ -// Public functions -// ------------------------ - -void eeprom_init() { - if (!eeprom_initialized) { - HAL_FLASH_Unlock(); - - __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR); - - /* EEPROM Init */ - if (EE_Initialize() != EE_OK) - for (;;) HAL_Delay(1); // Spin forever until watchdog reset - - HAL_FLASH_Lock(); - eeprom_initialized = true; - } -} - -void eeprom_write_byte(uint8_t *pos, unsigned char value) { - eeprom_init(); - +void ee_write_byte(uint8_t *pos, unsigned char value) { HAL_FLASH_Unlock(); __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR); - uint16_t eeprom_address = unsigned(pos); + const unsigned eeprom_address = (unsigned)pos; if (EE_WriteVariable(eeprom_address, uint16_t(value)) != EE_OK) for (;;) HAL_Delay(1); // Spin forever until watchdog reset HAL_FLASH_Lock(); } -uint8_t eeprom_read_byte(uint8_t *pos) { - eeprom_init(); - +uint8_t ee_read_byte(uint8_t *pos) { uint16_t data = 0xFF; - uint16_t eeprom_address = unsigned(pos); + const unsigned eeprom_address = (unsigned)pos; (void)EE_ReadVariable(eeprom_address, &data); // Data unchanged on error - return uint8_t(data); } -void eeprom_read_block(void *__dst, const void *__src, size_t __n) { - eeprom_init(); +#ifndef MARLIN_EEPROM_SIZE + #error "MARLIN_EEPROM_SIZE is required for Flash-based EEPROM." +#endif +size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } - uint16_t data = 0xFF; - uint16_t eeprom_address = unsigned(__src); - for (uint8_t c = 0; c < __n; c++) { - EE_ReadVariable(eeprom_address+c, &data); - *((uint8_t*)__dst + c) = data; +bool PersistentStore::access_finish() { return true; } + +bool PersistentStore::access_start() { + static bool ee_initialized = false; + if (!ee_initialized) { + HAL_FLASH_Unlock(); + + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR); + + /* EEPROM Init */ + if (EE_Initialize() != EE_OK) + for (;;) HAL_Delay(1); // Spin forever until watchdog reset + + HAL_FLASH_Lock(); + ee_initialized = true; } + return true; } -void eeprom_update_block(const void *__src, void *__dst, size_t __n) { +bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { + while (size--) { + uint8_t * const p = (uint8_t * const)pos; + uint8_t v = *value; + // EEPROM has only ~100,000 write cycles, + // so only write bytes that have changed! + if (v != ee_read_byte(p)) { + ee_write_byte(p, v); + if (ee_read_byte(p) != v) { + SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE); + return true; + } + } + crc16(crc, &v, 1); + pos++; + value++; + } + return false; +} +bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) { + do { + uint8_t c = ee_read_byte((uint8_t*)pos); + if (writing) *value = c; + crc16(crc, &c, 1); + pos++; + value++; + } while (--size); + return false; } -#endif // EEPROM_SETTINGS +#endif // FLASH_EEPROM_EMULATION #endif // STM32GENERIC && (STM32F4 || STM32F7) diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/persistent_store_eeprom.cpp b/Marlin/src/HAL/STM32_F4_F7/eeprom_wired.cpp similarity index 76% rename from Marlin/src/HAL/HAL_STM32_F4_F7/persistent_store_eeprom.cpp rename to Marlin/src/HAL/STM32_F4_F7/eeprom_wired.cpp index 2ffbc609ecf5..c0d82dbd0754 100644 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/persistent_store_eeprom.cpp +++ b/Marlin/src/HAL/STM32_F4_F7/eeprom_wired.cpp @@ -17,19 +17,29 @@ * 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 . + * along with this program. If not, see . * */ - #if defined(STM32GENERIC) && (defined(STM32F4) || defined(STM32F7)) -#include "../../inc/MarlinConfigPre.h" +#include "../../inc/MarlinConfig.h" + +#if USE_WIRED_EEPROM + +/** + * PersistentStore for Arduino-style EEPROM interface + * with simple implementations supplied by Marlin. + */ -#if ENABLED(EEPROM_SETTINGS) +#include "../shared/eeprom_if.h" +#include "../shared/eeprom_api.h" -#include "../shared/persistent_store_api.h" +#ifndef MARLIN_EEPROM_SIZE + #error "MARLIN_EEPROM_SIZE is required for I2C / SPI EEPROM." +#endif +size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } -bool PersistentStore::access_start() { return true; } +bool PersistentStore::access_start() { eeprom_init(); return true; } bool PersistentStore::access_finish() { return true; } bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { @@ -48,7 +58,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui crc16(crc, &v, 1); pos++; value++; - }; + } return false; } @@ -63,7 +73,5 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t return false; } -size_t PersistentStore::capacity() { return E2END + 1; } - -#endif // EEPROM_SETTINGS +#endif // USE_WIRED_EEPROM #endif // STM32GENERIC && (STM32F4 || STM32F7) diff --git a/Marlin/src/HAL/STM32_F4_F7/endstop_interrupts.h b/Marlin/src/HAL/STM32_F4_F7/endstop_interrupts.h new file mode 100644 index 000000000000..fdff8cc644cd --- /dev/null +++ b/Marlin/src/HAL/STM32_F4_F7/endstop_interrupts.h @@ -0,0 +1,49 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * Copyright (c) 2017 Victor Perez + * + * 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 . + * + */ +#pragma once + +#include "../../module/endstops.h" + +// One ISR for all EXT-Interrupts +void endstop_ISR() { endstops.update(); } + +void setup_endstop_interrupts() { + #define _ATTACH(P) attachInterrupt(P, endstop_ISR, CHANGE) + TERN_(HAS_X_MAX, _ATTACH(X_MAX_PIN)); + TERN_(HAS_X_MIN, _ATTACH(X_MIN_PIN)); + TERN_(HAS_Y_MAX, _ATTACH(Y_MAX_PIN)); + TERN_(HAS_Y_MIN, _ATTACH(Y_MIN_PIN)); + TERN_(HAS_Z_MAX, _ATTACH(Z_MAX_PIN)); + TERN_(HAS_Z_MIN, _ATTACH(Z_MIN_PIN)); + TERN_(HAS_X2_MAX, _ATTACH(X2_MAX_PIN)); + TERN_(HAS_X2_MIN, _ATTACH(X2_MIN_PIN)); + TERN_(HAS_Y2_MAX, _ATTACH(Y2_MAX_PIN)); + TERN_(HAS_Y2_MIN, _ATTACH(Y2_MIN_PIN)); + TERN_(HAS_Z2_MAX, _ATTACH(Z2_MAX_PIN)); + TERN_(HAS_Z2_MIN, _ATTACH(Z2_MIN_PIN)); + TERN_(HAS_Z3_MAX, _ATTACH(Z3_MAX_PIN)); + TERN_(HAS_Z3_MIN, _ATTACH(Z3_MIN_PIN)); + TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN)); + TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN)); + TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN)); +} diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/fastio.h b/Marlin/src/HAL/STM32_F4_F7/fastio.h similarity index 98% rename from Marlin/src/HAL/HAL_STM32_F4_F7/fastio.h rename to Marlin/src/HAL/STM32_F4_F7/fastio.h index ee64ca833d2e..f42be5835433 100644 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/fastio.h +++ b/Marlin/src/HAL/STM32_F4_F7/fastio.h @@ -17,7 +17,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_LCD.h b/Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_LCD.h new file mode 100644 index 000000000000..a9f1b5822215 --- /dev/null +++ b/Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_LCD.h @@ -0,0 +1,26 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if HAS_SPI_TFT || HAS_FSMC_TFT + #error "Sorry! TFT displays are not available for HAL/STM32F4_F7." +#endif diff --git a/Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_adv.h b/Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_adv.h new file mode 100644 index 000000000000..5f1c4b16019d --- /dev/null +++ b/Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_adv.h @@ -0,0 +1,22 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once diff --git a/Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_post.h b/Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_post.h new file mode 100644 index 000000000000..b5d808e21acc --- /dev/null +++ b/Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_post.h @@ -0,0 +1,29 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if ENABLED(EEPROM_SETTINGS) && defined(STM32F7) + #undef USE_WIRED_EEPROM + #undef SRAM_EEPROM_EMULATION + #undef SDCARD_EEPROM_EMULATION + #define FLASH_EEPROM_EMULATION +#endif diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/inc/SanityCheck.h b/Marlin/src/HAL/STM32_F4_F7/inc/SanityCheck.h similarity index 84% rename from Marlin/src/HAL/HAL_STM32_F4_F7/inc/SanityCheck.h rename to Marlin/src/HAL/STM32_F4_F7/inc/SanityCheck.h index e04258fa078a..9bb36f3bbbca 100644 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/inc/SanityCheck.h +++ b/Marlin/src/HAL/STM32_F4_F7/inc/SanityCheck.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -32,8 +32,8 @@ #error "EMERGENCY_PARSER is not yet implemented for STM32F4/7. Disable EMERGENCY_PARSER to continue." #endif -#if ENABLED(FAST_PWM_FAN) - #error "FAST_PWM_FAN is not yet implemented for this platform." +#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY + #error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on STM32F4/F7." #endif #if HAS_TMC_SW_SERIAL diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/pinsDebug.h b/Marlin/src/HAL/STM32_F4_F7/pinsDebug.h similarity index 84% rename from Marlin/src/HAL/HAL_STM32_F4_F7/pinsDebug.h rename to Marlin/src/HAL/STM32_F4_F7/pinsDebug.h index 8672dd0a1b05..973abb1b0185 100644 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/pinsDebug.h +++ b/Marlin/src/HAL/STM32_F4_F7/pinsDebug.h @@ -13,15 +13,15 @@ * 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 . + * along with this program. If not, see . * */ #pragma once #ifdef NUM_DIGITAL_PINS // Only in ST's Arduino core (STM32duino, STM32Core) - #include "../HAL_STM32/pinsDebug_STM32duino.h" + #include "../STM32/pinsDebug_STM32duino.h" #elif defined(BOARD_NR_GPIO_PINS) // Only in STM32GENERIC (Maple) - #include "../HAL_STM32/pinsDebug_STM32GENERIC.h" + #include "../STM32/pinsDebug_STM32GENERIC.h" #else #error "M43 Pins Debugging not supported for this board." #endif diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/spi_pins.h b/Marlin/src/HAL/STM32_F4_F7/spi_pins.h similarity index 92% rename from Marlin/src/HAL/HAL_STM32_F4_F7/spi_pins.h rename to Marlin/src/HAL/STM32_F4_F7/spi_pins.h index f120e7178b8b..75a6a2b250f6 100644 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/spi_pins.h +++ b/Marlin/src/HAL/STM32_F4_F7/spi_pins.h @@ -13,7 +13,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/timers.h b/Marlin/src/HAL/STM32_F4_F7/timers.h similarity index 92% rename from Marlin/src/HAL/HAL_STM32_F4_F7/timers.h rename to Marlin/src/HAL/STM32_F4_F7/timers.h index 632c05a5ade8..4e8c81783e59 100644 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/timers.h +++ b/Marlin/src/HAL/STM32_F4_F7/timers.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/watchdog.cpp b/Marlin/src/HAL/STM32_F4_F7/watchdog.cpp similarity index 95% rename from Marlin/src/HAL/HAL_STM32_F4_F7/watchdog.cpp rename to Marlin/src/HAL/STM32_F4_F7/watchdog.cpp index 347edcd49d21..cb12ec7aac3c 100644 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/watchdog.cpp +++ b/Marlin/src/HAL/STM32_F4_F7/watchdog.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #if defined(STM32GENERIC) && (defined(STM32F4) || defined(STM32F7)) #include "../../inc/MarlinConfig.h" diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/watchdog.h b/Marlin/src/HAL/STM32_F4_F7/watchdog.h similarity index 92% rename from Marlin/src/HAL/HAL_STM32_F4_F7/watchdog.h rename to Marlin/src/HAL/STM32_F4_F7/watchdog.h index ece6ef0162fa..3dbc2d08c139 100644 --- a/Marlin/src/HAL/HAL_STM32_F4_F7/watchdog.h +++ b/Marlin/src/HAL/STM32_F4_F7/watchdog.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_TEENSY31_32/HAL.cpp b/Marlin/src/HAL/TEENSY31_32/HAL.cpp similarity index 95% rename from Marlin/src/HAL/HAL_TEENSY31_32/HAL.cpp rename to Marlin/src/HAL/TEENSY31_32/HAL.cpp index f226a4a90ebe..8c3dd8337740 100644 --- a/Marlin/src/HAL/HAL_TEENSY31_32/HAL.cpp +++ b/Marlin/src/HAL/TEENSY31_32/HAL.cpp @@ -16,13 +16,12 @@ * 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 . + * along with this program. If not, see . * */ - /** - * Description: HAL for Teensy32 (MK20DX256) + * HAL for Teensy 3.2 (MK20DX256) */ #ifdef __MK20DX256__ diff --git a/Marlin/src/HAL/HAL_TEENSY31_32/HAL.h b/Marlin/src/HAL/TEENSY31_32/HAL.h similarity index 83% rename from Marlin/src/HAL/HAL_TEENSY31_32/HAL.h rename to Marlin/src/HAL/TEENSY31_32/HAL.h index 15e9ab71bb34..8ab358e9e1e5 100644 --- a/Marlin/src/HAL/HAL_TEENSY31_32/HAL.h +++ b/Marlin/src/HAL/TEENSY31_32/HAL.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once /** - * Description: HAL for Teensy 3.5 and Teensy 3.6 + * HAL for Teensy 3.2 (MK20DX256) */ #define CPU_32_BIT @@ -34,7 +34,6 @@ #include "fastio.h" #include "watchdog.h" -#include "timers.h" #include @@ -45,21 +44,20 @@ //#undef MOTHERBOARD //#define MOTHERBOARD BOARD_TEENSY31_32 -#define IS_32BIT_TEENSY defined(__MK20DX256__) -#define IS_TEENSY32 defined(__MK20DX256__) +#define IS_32BIT_TEENSY 1 +#define IS_TEENSY_31_32 1 +#ifndef IS_TEENSY31 + #define IS_TEENSY32 1 +#endif -#define NUM_SERIAL 1 +#define _MSERIAL(X) Serial##X +#define MSERIAL(X) _MSERIAL(X) +#define Serial0 Serial #if SERIAL_PORT == -1 #define MYSERIAL0 SerialUSB -#elif SERIAL_PORT == 0 - #define MYSERIAL0 Serial -#elif SERIAL_PORT == 1 - #define MYSERIAL0 Serial1 -#elif SERIAL_PORT == 2 - #define MYSERIAL0 Serial2 -#elif SERIAL_PORT == 3 - #define MYSERIAL0 Serial3 +#elif WITHIN(SERIAL_PORT, 0, 3) + #define MYSERIAL0 MSERIAL(SERIAL_PORT) #endif #define HAL_SERVO_LIB libServo @@ -67,7 +65,7 @@ typedef int8_t pin_t; #ifndef analogInputToDigitalPin - #define analogInputToDigitalPin(p) ((p < 12u) ? (p) + 54u : -1) + #define analogInputToDigitalPin(p) ((p < 12U) ? (p) + 54U : -1) #endif #define CRITICAL_SECTION_START() uint32_t primask = __get_PRIMASK(); __disable_irq() @@ -95,6 +93,8 @@ void HAL_clear_reset_source(); // Get the reason for the reset uint8_t HAL_get_reset_source(); +inline void HAL_reboot() {} // reboot the board or restart the bootloader + FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); } #pragma GCC diagnostic push @@ -108,8 +108,9 @@ extern "C" { void HAL_adc_init(); -#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin) +#define HAL_ADC_VREF 3.3 #define HAL_ADC_RESOLUTION 10 +#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin) #define HAL_READ_ADC() HAL_adc_get_result() #define HAL_ADC_READY() true diff --git a/Marlin/src/HAL/HAL_TEENSY31_32/HAL_SPI.cpp b/Marlin/src/HAL/TEENSY31_32/HAL_SPI.cpp similarity index 97% rename from Marlin/src/HAL/HAL_TEENSY31_32/HAL_SPI.cpp rename to Marlin/src/HAL/TEENSY31_32/HAL_SPI.cpp index 83d4d00bf265..cdb3f4701c03 100644 --- a/Marlin/src/HAL/HAL_TEENSY31_32/HAL_SPI.cpp +++ b/Marlin/src/HAL/TEENSY31_32/HAL_SPI.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #ifdef __MK20DX256__ diff --git a/Marlin/src/HAL/HAL_TEENSY31_32/Servo.cpp b/Marlin/src/HAL/TEENSY31_32/Servo.cpp similarity index 91% rename from Marlin/src/HAL/HAL_TEENSY31_32/Servo.cpp rename to Marlin/src/HAL/TEENSY31_32/Servo.cpp index 2b01d3d87589..19d57cf1b375 100644 --- a/Marlin/src/HAL/HAL_TEENSY31_32/Servo.cpp +++ b/Marlin/src/HAL/TEENSY31_32/Servo.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #ifdef __MK20DX256__ @@ -46,12 +46,9 @@ void libServo::move(const int value) { if (attach(0) >= 0) { write(value); safe_delay(servo_delay[servoIndex]); - #if ENABLED(DEACTIVATE_SERVOS_AFTER_MOVE) - detach(); - #endif + TERN_(DEACTIVATE_SERVOS_AFTER_MOVE, detach()); } } #endif // HAS_SERVOS - #endif // __MK20DX256__ diff --git a/Marlin/src/HAL/HAL_TEENSY31_32/Servo.h b/Marlin/src/HAL/TEENSY31_32/Servo.h similarity index 94% rename from Marlin/src/HAL/HAL_TEENSY31_32/Servo.h rename to Marlin/src/HAL/TEENSY31_32/Servo.h index 9243291e43b3..82b601d956be 100644 --- a/Marlin/src/HAL/HAL_TEENSY31_32/Servo.h +++ b/Marlin/src/HAL/TEENSY31_32/Servo.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_TEENSY31_32/persistent_store_impl.cpp b/Marlin/src/HAL/TEENSY31_32/eeprom.cpp similarity index 78% rename from Marlin/src/HAL/HAL_TEENSY31_32/persistent_store_impl.cpp rename to Marlin/src/HAL/TEENSY31_32/eeprom.cpp index 6a179cd962ea..cc5c56f7d550 100644 --- a/Marlin/src/HAL/HAL_TEENSY31_32/persistent_store_impl.cpp +++ b/Marlin/src/HAL/TEENSY31_32/eeprom.cpp @@ -13,18 +13,28 @@ * 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 . + * along with this program. If not, see . * */ #ifdef __MK20DX256__ #include "../../inc/MarlinConfig.h" -#if ENABLED(EEPROM_SETTINGS) +#if USE_WIRED_EEPROM -#include "../shared/persistent_store_api.h" +/** + * HAL PersistentStore for Teensy 3.2 (MK20DX256) + */ + +#include "../shared/eeprom_api.h" +#include + +#ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE size_t(E2END + 1) +#endif +size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } -bool PersistentStore::access_start() { return true; } +bool PersistentStore::access_start() { return true; } bool PersistentStore::access_finish() { return true; } bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { @@ -43,7 +53,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui crc16(crc, &v, 1); pos++; value++; - }; + } return false; } @@ -58,5 +68,5 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t return false; } -#endif // EEPROM_SETTINGS +#endif // USE_WIRED_EEPROM #endif // __MK20DX256__ diff --git a/Marlin/src/HAL/HAL_DUE/endstop_interrupts.h b/Marlin/src/HAL/TEENSY31_32/endstop_interrupts.h similarity index 68% rename from Marlin/src/HAL/HAL_DUE/endstop_interrupts.h rename to Marlin/src/HAL/TEENSY31_32/endstop_interrupts.h index f81d9055d5d0..999ada512761 100644 --- a/Marlin/src/HAL/HAL_DUE/endstop_interrupts.h +++ b/Marlin/src/HAL/TEENSY31_32/endstop_interrupts.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -47,43 +47,21 @@ void endstop_ISR() { endstops.update(); } void setup_endstop_interrupts() { #define _ATTACH(P) attachInterrupt(digitalPinToInterrupt(P), endstop_ISR, CHANGE) - #if HAS_X_MAX - _ATTACH(X_MAX_PIN); - #endif - #if HAS_X_MIN - _ATTACH(X_MIN_PIN); - #endif - #if HAS_Y_MAX - _ATTACH(Y_MAX_PIN); - #endif - #if HAS_Y_MIN - _ATTACH(Y_MIN_PIN); - #endif - #if HAS_Z_MAX - _ATTACH(Z_MAX_PIN); - #endif - #if HAS_Z_MIN - _ATTACH(Z_MIN_PIN); - #endif - #if HAS_Z2_MAX - _ATTACH(Z2_MAX_PIN); - #endif - #if HAS_Z2_MIN - _ATTACH(Z2_MIN_PIN); - #endif - #if HAS_Z3_MAX - _ATTACH(Z3_MAX_PIN); - #endif - #if HAS_Z3_MIN - _ATTACH(Z3_MIN_PIN); - #endif - #if HAS_Z4_MAX - _ATTACH(Z4_MAX_PIN); - #endif - #if HAS_Z4_MIN - _ATTACH(Z4_MIN_PIN); - #endif - #if HAS_Z_MIN_PROBE_PIN - _ATTACH(Z_MIN_PROBE_PIN); - #endif + TERN_(HAS_X_MAX, _ATTACH(X_MAX_PIN)); + TERN_(HAS_X_MIN, _ATTACH(X_MIN_PIN)); + TERN_(HAS_Y_MAX, _ATTACH(Y_MAX_PIN)); + TERN_(HAS_Y_MIN, _ATTACH(Y_MIN_PIN)); + TERN_(HAS_Z_MAX, _ATTACH(Z_MAX_PIN)); + TERN_(HAS_Z_MIN, _ATTACH(Z_MIN_PIN)); + TERN_(HAS_X2_MAX, _ATTACH(X2_MAX_PIN)); + TERN_(HAS_X2_MIN, _ATTACH(X2_MIN_PIN)); + TERN_(HAS_Y2_MAX, _ATTACH(Y2_MAX_PIN)); + TERN_(HAS_Y2_MIN, _ATTACH(Y2_MIN_PIN)); + TERN_(HAS_Z2_MAX, _ATTACH(Z2_MAX_PIN)); + TERN_(HAS_Z2_MIN, _ATTACH(Z2_MIN_PIN)); + TERN_(HAS_Z3_MAX, _ATTACH(Z3_MAX_PIN)); + TERN_(HAS_Z3_MIN, _ATTACH(Z3_MIN_PIN)); + TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN)); + TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN)); + TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN)); } diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/fastio.h b/Marlin/src/HAL/TEENSY31_32/fastio.h similarity index 92% rename from Marlin/src/HAL/HAL_TEENSY35_36/fastio.h rename to Marlin/src/HAL/TEENSY31_32/fastio.h index 8547fe2b7a81..9a299de9c763 100644 --- a/Marlin/src/HAL/HAL_TEENSY35_36/fastio.h +++ b/Marlin/src/HAL/TEENSY31_32/fastio.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -39,7 +39,7 @@ * * Now you can simply SET_OUTPUT(PIN); WRITE(PIN, HIGH); WRITE(PIN, LOW); * - * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html + * Why double up on these macros? see https://gcc.gnu.org/onlinedocs/gcc-4.8.5/cpp/Stringification.html */ #define _READ(P) bool(CORE_PIN ## P ## _PINREG & CORE_PIN ## P ## _BITMASK) @@ -76,8 +76,9 @@ #define SET_INPUT(IO) _SET_INPUT(IO) #define SET_INPUT_PULLUP(IO) _SET_INPUT_PULLUP(IO) +#define SET_INPUT_PULLDOWN SET_INPUT #define SET_OUTPUT(IO) _SET_OUTPUT(IO) -#define SET_PWM(IO) SET_OUTPUT(IO) +#define SET_PWM SET_OUTPUT #define IS_INPUT(IO) _IS_INPUT(IO) #define IS_OUTPUT(IO) _IS_OUTPUT(IO) diff --git a/Marlin/src/HAL/TEENSY31_32/inc/Conditionals_LCD.h b/Marlin/src/HAL/TEENSY31_32/inc/Conditionals_LCD.h new file mode 100644 index 000000000000..54ec16664354 --- /dev/null +++ b/Marlin/src/HAL/TEENSY31_32/inc/Conditionals_LCD.h @@ -0,0 +1,26 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if HAS_SPI_TFT || HAS_FSMC_TFT + #error "Sorry! TFT displays are not available for HAL/TEENSY31_32." +#endif diff --git a/Marlin/src/HAL/TEENSY31_32/inc/Conditionals_adv.h b/Marlin/src/HAL/TEENSY31_32/inc/Conditionals_adv.h new file mode 100644 index 000000000000..5f1c4b16019d --- /dev/null +++ b/Marlin/src/HAL/TEENSY31_32/inc/Conditionals_adv.h @@ -0,0 +1,22 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once diff --git a/Marlin/src/HAL/HAL_LINUX/inc/Conditionals_post.h b/Marlin/src/HAL/TEENSY31_32/inc/Conditionals_post.h similarity index 85% rename from Marlin/src/HAL/HAL_LINUX/inc/Conditionals_post.h rename to Marlin/src/HAL/TEENSY31_32/inc/Conditionals_post.h index 0285c52ee365..998f1dcc0d73 100644 --- a/Marlin/src/HAL/HAL_LINUX/inc/Conditionals_post.h +++ b/Marlin/src/HAL/TEENSY31_32/inc/Conditionals_post.h @@ -16,7 +16,11 @@ * 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 . + * along with this program. If not, see . * */ #pragma once + +#if USE_FALLBACK_EEPROM + #define USE_WIRED_EEPROM 1 +#endif diff --git a/Marlin/src/HAL/HAL_TEENSY31_32/inc/SanityCheck.h b/Marlin/src/HAL/TEENSY31_32/inc/SanityCheck.h similarity index 81% rename from Marlin/src/HAL/HAL_TEENSY31_32/inc/SanityCheck.h rename to Marlin/src/HAL/TEENSY31_32/inc/SanityCheck.h index 92688685966e..3932ee6a76c1 100644 --- a/Marlin/src/HAL/HAL_TEENSY31_32/inc/SanityCheck.h +++ b/Marlin/src/HAL/TEENSY31_32/inc/SanityCheck.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -29,8 +29,8 @@ #error "EMERGENCY_PARSER is not yet implemented for Teensy 3.1/3.2. Disable EMERGENCY_PARSER to continue." #endif -#if ENABLED(FAST_PWM_FAN) - #error "FAST_PWM_FAN is not yet implemented for this platform." +#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY + #error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on Teensy 3.1/3.2." #endif #if HAS_TMC_SW_SERIAL diff --git a/Marlin/src/HAL/HAL_TEENSY31_32/pinsDebug.h b/Marlin/src/HAL/TEENSY31_32/pinsDebug.h similarity index 100% rename from Marlin/src/HAL/HAL_TEENSY31_32/pinsDebug.h rename to Marlin/src/HAL/TEENSY31_32/pinsDebug.h diff --git a/Marlin/src/HAL/HAL_TEENSY31_32/spi_pins.h b/Marlin/src/HAL/TEENSY31_32/spi_pins.h similarity index 92% rename from Marlin/src/HAL/HAL_TEENSY31_32/spi_pins.h rename to Marlin/src/HAL/TEENSY31_32/spi_pins.h index 79230f3d4403..5754fbfeed11 100644 --- a/Marlin/src/HAL/HAL_TEENSY31_32/spi_pins.h +++ b/Marlin/src/HAL/TEENSY31_32/spi_pins.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_TEENSY31_32/timers.cpp b/Marlin/src/HAL/TEENSY31_32/timers.cpp similarity index 96% rename from Marlin/src/HAL/HAL_TEENSY31_32/timers.cpp rename to Marlin/src/HAL/TEENSY31_32/timers.cpp index 92641742f93d..7e01a38f8946 100644 --- a/Marlin/src/HAL/HAL_TEENSY31_32/timers.cpp +++ b/Marlin/src/HAL/TEENSY31_32/timers.cpp @@ -16,18 +16,17 @@ * 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 . + * along with this program. If not, see . * */ /** - * Teensy3.2 __MK20DX256__ + * HAL Timers for Teensy 3.2 (MK20DX256) */ #ifdef __MK20DX256__ -#include "HAL.h" -#include "timers.h" +#include "../../inc/MarlinConfig.h" /** \brief Instruction Synchronization Barrier Instruction Synchronization Barrier flushes the pipeline in the processor, diff --git a/Marlin/src/HAL/HAL_TEENSY31_32/timers.h b/Marlin/src/HAL/TEENSY31_32/timers.h similarity index 83% rename from Marlin/src/HAL/HAL_TEENSY31_32/timers.h rename to Marlin/src/HAL/TEENSY31_32/timers.h index 00f9f0740dce..135b32883084 100644 --- a/Marlin/src/HAL/HAL_TEENSY31_32/timers.h +++ b/Marlin/src/HAL/TEENSY31_32/timers.h @@ -16,14 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once /** - * Description: HAL for - * Teensy3.2 (__MK20DX256__) + * HAL Timers for Teensy 3.2 (MK20DX256) */ #include @@ -47,9 +46,15 @@ typedef uint32_t hal_timer_t; #define HAL_TIMER_RATE (FTM0_TIMER_RATE) -#define STEP_TIMER_NUM 0 -#define TEMP_TIMER_NUM 1 -#define PULSE_TIMER_NUM STEP_TIMER_NUM +#ifndef STEP_TIMER_NUM + #define STEP_TIMER_NUM 0 // Timer Index for Stepper +#endif +#ifndef PULSE_TIMER_NUM + #define PULSE_TIMER_NUM STEP_TIMER_NUM +#endif +#ifndef TEMP_TIMER_NUM + #define TEMP_TIMER_NUM 1 // Timer Index for Temperature +#endif #define TEMP_TIMER_FREQUENCY 1000 @@ -68,8 +73,12 @@ typedef uint32_t hal_timer_t; #define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM) #define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM) -#define HAL_STEP_TIMER_ISR() extern "C" void ftm0_isr() //void TC3_Handler() -#define HAL_TEMP_TIMER_ISR() extern "C" void ftm1_isr() //void TC4_Handler() +#ifndef HAL_STEP_TIMER_ISR + #define HAL_STEP_TIMER_ISR() extern "C" void ftm0_isr() //void TC3_Handler() +#endif +#ifndef HAL_TEMP_TIMER_ISR + #define HAL_TEMP_TIMER_ISR() extern "C" void ftm1_isr() //void TC4_Handler() +#endif void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency); diff --git a/Marlin/src/HAL/HAL_TEENSY31_32/watchdog.cpp b/Marlin/src/HAL/TEENSY31_32/watchdog.cpp similarity index 93% rename from Marlin/src/HAL/HAL_TEENSY31_32/watchdog.cpp rename to Marlin/src/HAL/TEENSY31_32/watchdog.cpp index 618294591b9d..9f7b70d9f961 100644 --- a/Marlin/src/HAL/HAL_TEENSY31_32/watchdog.cpp +++ b/Marlin/src/HAL/TEENSY31_32/watchdog.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #ifdef __MK20DX256__ #include "../../inc/MarlinConfig.h" diff --git a/Marlin/src/HAL/HAL_TEENSY31_32/watchdog.h b/Marlin/src/HAL/TEENSY31_32/watchdog.h similarity index 93% rename from Marlin/src/HAL/HAL_TEENSY31_32/watchdog.h rename to Marlin/src/HAL/TEENSY31_32/watchdog.h index cb881f859501..b8b46a403013 100644 --- a/Marlin/src/HAL/HAL_TEENSY31_32/watchdog.h +++ b/Marlin/src/HAL/TEENSY31_32/watchdog.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/HAL.cpp b/Marlin/src/HAL/TEENSY35_36/HAL.cpp similarity index 96% rename from Marlin/src/HAL/HAL_TEENSY35_36/HAL.cpp rename to Marlin/src/HAL/TEENSY35_36/HAL.cpp index 86ba40870f71..92907353b833 100644 --- a/Marlin/src/HAL/HAL_TEENSY35_36/HAL.cpp +++ b/Marlin/src/HAL/TEENSY35_36/HAL.cpp @@ -16,12 +16,12 @@ * 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 . + * along with this program. If not, see . * */ /** - * Description: HAL for Teensy35 (MK64FX512) + * HAL for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) */ #if defined(__MK64FX512__) || defined(__MK66FX1M0__) diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/HAL.h b/Marlin/src/HAL/TEENSY35_36/HAL.h similarity index 81% rename from Marlin/src/HAL/HAL_TEENSY35_36/HAL.h rename to Marlin/src/HAL/TEENSY35_36/HAL.h index 7e5be1081c01..2b735d6224f4 100644 --- a/Marlin/src/HAL/HAL_TEENSY35_36/HAL.h +++ b/Marlin/src/HAL/TEENSY35_36/HAL.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once /** - * Description: HAL for Teensy 3.5 and Teensy 3.6 + * HAL for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) */ #define CPU_32_BIT @@ -34,8 +34,6 @@ #include "fastio.h" #include "watchdog.h" -#include "timers.h" - #include #include @@ -47,22 +45,22 @@ // Defines // ------------------------ -#define IS_32BIT_TEENSY (defined(__MK64FX512__) || defined(__MK66FX1M0__)) -#define IS_TEENSY35 defined(__MK64FX512__) -#define IS_TEENSY36 defined(__MK66FX1M0__) +#define IS_32BIT_TEENSY 1 +#define IS_TEENSY_35_36 1 +#ifdef __MK66FX1M0__ + #define IS_TEENSY36 1 +#else // __MK64FX512__ + #define IS_TEENSY35 1 +#endif -#define NUM_SERIAL 1 +#define _MSERIAL(X) Serial##X +#define MSERIAL(X) _MSERIAL(X) +#define Serial0 Serial #if SERIAL_PORT == -1 #define MYSERIAL0 SerialUSB -#elif SERIAL_PORT == 0 - #define MYSERIAL0 Serial -#elif SERIAL_PORT == 1 - #define MYSERIAL0 Serial1 -#elif SERIAL_PORT == 2 - #define MYSERIAL0 Serial2 -#elif SERIAL_PORT == 3 - #define MYSERIAL0 Serial3 +#elif WITHIN(SERIAL_PORT, 0, 3) + #define MYSERIAL0 MSERIAL(SERIAL_PORT) #endif #define HAL_SERVO_LIB libServo @@ -70,7 +68,7 @@ typedef int8_t pin_t; #ifndef analogInputToDigitalPin - #define analogInputToDigitalPin(p) ((p < 12u) ? (p) + 54u : -1) + #define analogInputToDigitalPin(p) ((p < 12U) ? (p) + 54U : -1) #endif #define CRITICAL_SECTION_START() uint32_t primask = __get_primask(); __disable_irq() @@ -101,6 +99,8 @@ void HAL_clear_reset_source(); // Reset reason uint8_t HAL_get_reset_source(); +inline void HAL_reboot() {} // reboot the board or restart the bootloader + FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); } #pragma GCC diagnostic push @@ -114,8 +114,9 @@ extern "C" { void HAL_adc_init(); -#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin) +#define HAL_ADC_VREF 3.3 #define HAL_ADC_RESOLUTION 10 +#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin) #define HAL_READ_ADC() HAL_adc_get_result() #define HAL_ADC_READY() true diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/HAL_SPI.cpp b/Marlin/src/HAL/TEENSY35_36/HAL_SPI.cpp similarity index 94% rename from Marlin/src/HAL/HAL_TEENSY35_36/HAL_SPI.cpp rename to Marlin/src/HAL/TEENSY35_36/HAL_SPI.cpp index b35533aa9435..b36900a32195 100644 --- a/Marlin/src/HAL/HAL_TEENSY35_36/HAL_SPI.cpp +++ b/Marlin/src/HAL/TEENSY35_36/HAL_SPI.cpp @@ -16,9 +16,14 @@ * 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 . + * along with this program. If not, see . * */ + +/** + * HAL SPI for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) + */ + #if defined(__MK64FX512__) || defined(__MK66FX1M0__) #include "HAL.h" @@ -31,7 +36,7 @@ static SPISettings spiConfig; void spiBegin() { #if !PIN_EXISTS(SS) - #error SS_PIN not defined! + #error "SS_PIN not defined!" #endif OUT_WRITE(SS_PIN, HIGH); SET_OUTPUT(SCK_PIN); diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/Servo.cpp b/Marlin/src/HAL/TEENSY35_36/Servo.cpp similarity index 89% rename from Marlin/src/HAL/HAL_TEENSY35_36/Servo.cpp rename to Marlin/src/HAL/TEENSY35_36/Servo.cpp index f2fd5fe7ffed..033858594f6c 100644 --- a/Marlin/src/HAL/HAL_TEENSY35_36/Servo.cpp +++ b/Marlin/src/HAL/TEENSY35_36/Servo.cpp @@ -16,9 +16,14 @@ * 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 . + * along with this program. If not, see . * */ + +/** + * HAL Servo for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) + */ + #if defined(__MK64FX512__) || defined(__MK66FX1M0__) #include "../../inc/MarlinConfig.h" @@ -46,12 +51,9 @@ void libServo::move(const int value) { if (attach(0) >= 0) { write(value); safe_delay(servo_delay[servoIndex]); - #if ENABLED(DEACTIVATE_SERVOS_AFTER_MOVE) - detach(); - #endif + TERN_(DEACTIVATE_SERVOS_AFTER_MOVE, detach()); } } #endif // HAS_SERVOS - #endif // __MK64FX512__ || __MK66FX1M0__ diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/Servo.h b/Marlin/src/HAL/TEENSY35_36/Servo.h similarity index 88% rename from Marlin/src/HAL/HAL_TEENSY35_36/Servo.h rename to Marlin/src/HAL/TEENSY35_36/Servo.h index 4962105d79af..719011f102a0 100644 --- a/Marlin/src/HAL/HAL_TEENSY35_36/Servo.h +++ b/Marlin/src/HAL/TEENSY35_36/Servo.h @@ -16,11 +16,15 @@ * 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 . + * along with this program. If not, see . * */ #pragma once +/** + * HAL Servo for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) + */ + #include // Inherit and expand on core Servo library diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/persistent_store_eeprom.cpp b/Marlin/src/HAL/TEENSY35_36/eeprom.cpp similarity index 81% rename from Marlin/src/HAL/HAL_TEENSY35_36/persistent_store_eeprom.cpp rename to Marlin/src/HAL/TEENSY35_36/eeprom.cpp index 32b215ee6e12..ccbdc6b11600 100644 --- a/Marlin/src/HAL/HAL_TEENSY35_36/persistent_store_eeprom.cpp +++ b/Marlin/src/HAL/TEENSY35_36/eeprom.cpp @@ -17,20 +17,28 @@ * 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 . + * along with this program. If not, see . * */ - #if defined(__MK64FX512__) || defined(__MK66FX1M0__) +/** + * HAL PersistentStore for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) + */ + #include "../../inc/MarlinConfig.h" -#if ENABLED(EEPROM_SETTINGS) +#if USE_WIRED_EEPROM -#include "../shared/persistent_store_api.h" +#include "../shared/eeprom_api.h" #include -bool PersistentStore::access_start() { return true; } +#ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE size_t(E2END + 1) +#endif +size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } + +bool PersistentStore::access_start() { return true; } bool PersistentStore::access_finish() { return true; } bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { @@ -49,7 +57,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui crc16(crc, &v, 1); pos++; value++; - }; + } return false; } @@ -64,7 +72,5 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t return false; } -size_t PersistentStore::capacity() { return E2END + 1; } - -#endif // EEPROM_SETTINGS +#endif // USE_WIRED_EEPROM #endif // __MK64FX512__ || __MK66FX1M0__ diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/endstop_interrupts.h b/Marlin/src/HAL/TEENSY35_36/endstop_interrupts.h similarity index 66% rename from Marlin/src/HAL/HAL_TEENSY35_36/endstop_interrupts.h rename to Marlin/src/HAL/TEENSY35_36/endstop_interrupts.h index eaaf297ea2d3..87e6a7507abc 100644 --- a/Marlin/src/HAL/HAL_TEENSY35_36/endstop_interrupts.h +++ b/Marlin/src/HAL/TEENSY35_36/endstop_interrupts.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once /** - * Endstop Interrupts + * HAL Endstop Interrupts for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) * * Without endstop interrupts the endstop pins must be polled continually in * the temperature-ISR via endstops.update(), most of the time finding no change. @@ -46,43 +46,21 @@ void endstop_ISR() { endstops.update(); } */ void setup_endstop_interrupts() { #define _ATTACH(P) attachInterrupt(digitalPinToInterrupt(P), endstop_ISR, CHANGE) - #if HAS_X_MAX - _ATTACH(X_MAX_PIN); - #endif - #if HAS_X_MIN - _ATTACH(X_MIN_PIN); - #endif - #if HAS_Y_MAX - _ATTACH(Y_MAX_PIN); - #endif - #if HAS_Y_MIN - _ATTACH(Y_MIN_PIN); - #endif - #if HAS_Z_MAX - _ATTACH(Z_MAX_PIN); - #endif - #if HAS_Z_MIN - _ATTACH(Z_MIN_PIN); - #endif - #if HAS_Z2_MAX - _ATTACH(Z2_MAX_PIN); - #endif - #if HAS_Z2_MIN - _ATTACH(Z2_MIN_PIN); - #endif - #if HAS_Z3_MAX - _ATTACH(Z3_MAX_PIN); - #endif - #if HAS_Z3_MIN - _ATTACH(Z3_MIN_PIN); - #endif - #if HAS_Z4_MAX - _ATTACH(Z4_MAX_PIN); - #endif - #if HAS_Z4_MIN - _ATTACH(Z4_MIN_PIN); - #endif - #if HAS_Z_MIN_PROBE_PIN - _ATTACH(Z_MIN_PROBE_PIN); - #endif + TERN_(HAS_X_MAX, _ATTACH(X_MAX_PIN)); + TERN_(HAS_X_MIN, _ATTACH(X_MIN_PIN)); + TERN_(HAS_Y_MAX, _ATTACH(Y_MAX_PIN)); + TERN_(HAS_Y_MIN, _ATTACH(Y_MIN_PIN)); + TERN_(HAS_Z_MAX, _ATTACH(Z_MAX_PIN)); + TERN_(HAS_Z_MIN, _ATTACH(Z_MIN_PIN)); + TERN_(HAS_X2_MAX, _ATTACH(X2_MAX_PIN)); + TERN_(HAS_X2_MIN, _ATTACH(X2_MIN_PIN)); + TERN_(HAS_Y2_MAX, _ATTACH(Y2_MAX_PIN)); + TERN_(HAS_Y2_MIN, _ATTACH(Y2_MIN_PIN)); + TERN_(HAS_Z2_MAX, _ATTACH(Z2_MAX_PIN)); + TERN_(HAS_Z2_MIN, _ATTACH(Z2_MIN_PIN)); + TERN_(HAS_Z3_MAX, _ATTACH(Z3_MAX_PIN)); + TERN_(HAS_Z3_MIN, _ATTACH(Z3_MIN_PIN)); + TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN)); + TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN)); + TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN)); } diff --git a/Marlin/src/HAL/HAL_TEENSY31_32/fastio.h b/Marlin/src/HAL/TEENSY35_36/fastio.h similarity index 92% rename from Marlin/src/HAL/HAL_TEENSY31_32/fastio.h rename to Marlin/src/HAL/TEENSY35_36/fastio.h index 8547fe2b7a81..9a299de9c763 100644 --- a/Marlin/src/HAL/HAL_TEENSY31_32/fastio.h +++ b/Marlin/src/HAL/TEENSY35_36/fastio.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -39,7 +39,7 @@ * * Now you can simply SET_OUTPUT(PIN); WRITE(PIN, HIGH); WRITE(PIN, LOW); * - * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html + * Why double up on these macros? see https://gcc.gnu.org/onlinedocs/gcc-4.8.5/cpp/Stringification.html */ #define _READ(P) bool(CORE_PIN ## P ## _PINREG & CORE_PIN ## P ## _BITMASK) @@ -76,8 +76,9 @@ #define SET_INPUT(IO) _SET_INPUT(IO) #define SET_INPUT_PULLUP(IO) _SET_INPUT_PULLUP(IO) +#define SET_INPUT_PULLDOWN SET_INPUT #define SET_OUTPUT(IO) _SET_OUTPUT(IO) -#define SET_PWM(IO) SET_OUTPUT(IO) +#define SET_PWM SET_OUTPUT #define IS_INPUT(IO) _IS_INPUT(IO) #define IS_OUTPUT(IO) _IS_OUTPUT(IO) diff --git a/Marlin/src/HAL/TEENSY35_36/inc/Conditionals_LCD.h b/Marlin/src/HAL/TEENSY35_36/inc/Conditionals_LCD.h new file mode 100644 index 000000000000..632ee533acac --- /dev/null +++ b/Marlin/src/HAL/TEENSY35_36/inc/Conditionals_LCD.h @@ -0,0 +1,26 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if HAS_SPI_TFT || HAS_FSMC_TFT + #error "Sorry! TFT displays are not available for HAL/TEENSY35_36." +#endif diff --git a/Marlin/src/HAL/TEENSY35_36/inc/Conditionals_adv.h b/Marlin/src/HAL/TEENSY35_36/inc/Conditionals_adv.h new file mode 100644 index 000000000000..5f1c4b16019d --- /dev/null +++ b/Marlin/src/HAL/TEENSY35_36/inc/Conditionals_adv.h @@ -0,0 +1,22 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once diff --git a/Marlin/src/HAL/TEENSY35_36/inc/Conditionals_post.h b/Marlin/src/HAL/TEENSY35_36/inc/Conditionals_post.h new file mode 100644 index 000000000000..998f1dcc0d73 --- /dev/null +++ b/Marlin/src/HAL/TEENSY35_36/inc/Conditionals_post.h @@ -0,0 +1,26 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if USE_FALLBACK_EEPROM + #define USE_WIRED_EEPROM 1 +#endif diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/inc/SanityCheck.h b/Marlin/src/HAL/TEENSY35_36/inc/SanityCheck.h similarity index 81% rename from Marlin/src/HAL/HAL_TEENSY35_36/inc/SanityCheck.h rename to Marlin/src/HAL/TEENSY35_36/inc/SanityCheck.h index f42bd63b1781..ee80e42696fa 100644 --- a/Marlin/src/HAL/HAL_TEENSY35_36/inc/SanityCheck.h +++ b/Marlin/src/HAL/TEENSY35_36/inc/SanityCheck.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -29,8 +29,8 @@ #error "EMERGENCY_PARSER is not yet implemented for Teensy 3.5/3.6. Disable EMERGENCY_PARSER to continue." #endif -#if ENABLED(FAST_PWM_FAN) - #error "FAST_PWM_FAN is not yet implemented for this platform." +#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY + #error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on Teensy 3.5/3.6." #endif #if HAS_TMC_SW_SERIAL diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/pinsDebug.h b/Marlin/src/HAL/TEENSY35_36/pinsDebug.h similarity index 94% rename from Marlin/src/HAL/HAL_TEENSY35_36/pinsDebug.h rename to Marlin/src/HAL/TEENSY35_36/pinsDebug.h index 61a54f15ed35..e529fa93be16 100644 --- a/Marlin/src/HAL/HAL_TEENSY35_36/pinsDebug.h +++ b/Marlin/src/HAL/TEENSY35_36/pinsDebug.h @@ -13,11 +13,15 @@ * 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 . + * along with this program. If not, see . * */ #pragma once +/** + * HAL Pins Debugging for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) + */ + #define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS #define MULTI_NAME_PAD 16 // space needed to be pretty if not first name assigned to a pin diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/spi_pins.h b/Marlin/src/HAL/TEENSY35_36/spi_pins.h similarity index 85% rename from Marlin/src/HAL/HAL_TEENSY35_36/spi_pins.h rename to Marlin/src/HAL/TEENSY35_36/spi_pins.h index b29a9346a1dc..c76344d07546 100644 --- a/Marlin/src/HAL/HAL_TEENSY35_36/spi_pins.h +++ b/Marlin/src/HAL/TEENSY35_36/spi_pins.h @@ -16,11 +16,15 @@ * 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 . + * along with this program. If not, see . * */ #pragma once +/** + * HAL SPI Pins for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) + */ + #define SCK_PIN 13 #define MISO_PIN 12 #define MOSI_PIN 11 diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/timers.cpp b/Marlin/src/HAL/TEENSY35_36/timers.cpp similarity index 95% rename from Marlin/src/HAL/HAL_TEENSY35_36/timers.cpp rename to Marlin/src/HAL/TEENSY35_36/timers.cpp index 81e23e4d170f..8067d091dd01 100644 --- a/Marlin/src/HAL/HAL_TEENSY35_36/timers.cpp +++ b/Marlin/src/HAL/TEENSY35_36/timers.cpp @@ -16,19 +16,17 @@ * 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 . + * along with this program. If not, see . * */ /** - * Teensy3.5 __MK64FX512__ - * Teensy3.6 __MK66FX1M0__ + * HAL Timers for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) */ #if defined(__MK64FX512__) || defined(__MK66FX1M0__) -#include "HAL.h" -#include "timers.h" +#include "../../inc/MarlinConfig.h" /** \brief Instruction Synchronization Barrier Instruction Synchronization Barrier flushes the pipeline in the processor, diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/timers.h b/Marlin/src/HAL/TEENSY35_36/timers.h similarity index 83% rename from Marlin/src/HAL/HAL_TEENSY35_36/timers.h rename to Marlin/src/HAL/TEENSY35_36/timers.h index 6dc26a966511..5c623cd80192 100644 --- a/Marlin/src/HAL/HAL_TEENSY35_36/timers.h +++ b/Marlin/src/HAL/TEENSY35_36/timers.h @@ -15,14 +15,13 @@ * 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 . + * along with this program. If not, see . + * */ #pragma once /** - * Description: HAL for - * Teensy3.5 (__MK64FX512__) - * Teensy3.6 (__MK66FX1M0__) + * HAL Timers for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) */ #include @@ -46,9 +45,15 @@ typedef uint32_t hal_timer_t; #define HAL_TIMER_RATE (FTM0_TIMER_RATE) -#define STEP_TIMER_NUM 0 -#define TEMP_TIMER_NUM 1 -#define PULSE_TIMER_NUM STEP_TIMER_NUM +#ifndef STEP_TIMER_NUM + #define STEP_TIMER_NUM 0 // Timer Index for Stepper +#endif +#ifndef PULSE_TIMER_NUM + #define PULSE_TIMER_NUM STEP_TIMER_NUM +#endif +#ifndef TEMP_TIMER_NUM + #define TEMP_TIMER_NUM 1 // Timer Index for Temperature +#endif #define TEMP_TIMER_FREQUENCY 1000 @@ -67,8 +72,12 @@ typedef uint32_t hal_timer_t; #define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM) #define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM) -#define HAL_STEP_TIMER_ISR() extern "C" void ftm0_isr() //void TC3_Handler() -#define HAL_TEMP_TIMER_ISR() extern "C" void ftm1_isr() //void TC4_Handler() +#ifndef HAL_STEP_TIMER_ISR + #define HAL_STEP_TIMER_ISR() extern "C" void ftm0_isr() //void TC3_Handler() +#endif +#ifndef HAL_TEMP_TIMER_ISR + #define HAL_TEMP_TIMER_ISR() extern "C" void ftm1_isr() //void TC4_Handler() +#endif void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency); diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/watchdog.cpp b/Marlin/src/HAL/TEENSY35_36/watchdog.cpp similarity index 93% rename from Marlin/src/HAL/HAL_TEENSY35_36/watchdog.cpp rename to Marlin/src/HAL/TEENSY35_36/watchdog.cpp index 69afa04a5438..e735ee79238f 100644 --- a/Marlin/src/HAL/HAL_TEENSY35_36/watchdog.cpp +++ b/Marlin/src/HAL/TEENSY35_36/watchdog.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #if defined(__MK64FX512__) || defined(__MK66FX1M0__) #include "../../inc/MarlinConfig.h" diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/watchdog.h b/Marlin/src/HAL/TEENSY35_36/watchdog.h similarity index 92% rename from Marlin/src/HAL/HAL_TEENSY35_36/watchdog.h rename to Marlin/src/HAL/TEENSY35_36/watchdog.h index ec3f18f09452..981b1f0bd20b 100644 --- a/Marlin/src/HAL/HAL_TEENSY35_36/watchdog.h +++ b/Marlin/src/HAL/TEENSY35_36/watchdog.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/TEENSY40_41/HAL.cpp b/Marlin/src/HAL/TEENSY40_41/HAL.cpp new file mode 100644 index 000000000000..5b1b4272f5ee --- /dev/null +++ b/Marlin/src/HAL/TEENSY40_41/HAL.cpp @@ -0,0 +1,167 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * HAL for Teensy 4.0 / 4.1 (IMXRT1062) + */ + +#ifdef __IMXRT1062__ + +#include "HAL.h" +#include "../shared/Delay.h" +#include "timers.h" + +#include + +uint16_t HAL_adc_result, HAL_adc_select; + +static const uint8_t pin2sc1a[] = { + 0x07, // 0/A0 AD_B1_02 + 0x08, // 1/A1 AD_B1_03 + 0x0C, // 2/A2 AD_B1_07 + 0x0B, // 3/A3 AD_B1_06 + 0x06, // 4/A4 AD_B1_01 + 0x05, // 5/A5 AD_B1_00 + 0x0F, // 6/A6 AD_B1_10 + 0x00, // 7/A7 AD_B1_11 + 0x0D, // 8/A8 AD_B1_08 + 0x0E, // 9/A9 AD_B1_09 + 0x01, // 24/A10 AD_B0_12 + 0x02, // 25/A11 AD_B0_13 + 0x83, // 26/A12 AD_B1_14 - only on ADC2, 3 + 0x84, // 27/A13 AD_B1_15 - only on ADC2, 4 + 0x07, // 14/A0 AD_B1_02 + 0x08, // 15/A1 AD_B1_03 + 0x0C, // 16/A2 AD_B1_07 + 0x0B, // 17/A3 AD_B1_06 + 0x06, // 18/A4 AD_B1_01 + 0x05, // 19/A5 AD_B1_00 + 0x0F, // 20/A6 AD_B1_10 + 0x00, // 21/A7 AD_B1_11 + 0x0D, // 22/A8 AD_B1_08 + 0x0E, // 23/A9 AD_B1_09 + 0x01, // 24/A10 AD_B0_12 + 0x02, // 25/A11 AD_B0_13 + 0x83, // 26/A12 AD_B1_14 - only on ADC2, 3 + 0x84, // 27/A13 AD_B1_15 - only on ADC2, 4 + #ifdef ARDUINO_TEENSY41 + 0xFF, // 28 + 0xFF, // 29 + 0xFF, // 30 + 0xFF, // 31 + 0xFF, // 32 + 0xFF, // 33 + 0xFF, // 34 + 0xFF, // 35 + 0xFF, // 36 + 0xFF, // 37 + 0x81, // 38/A14 AD_B1_12 - only on ADC2, 1 + 0x82, // 39/A15 AD_B1_13 - only on ADC2, 2 + 0x09, // 40/A16 AD_B1_04 + 0x0A, // 41/A17 AD_B1_05 + #endif +}; + +/* +// disable interrupts +void cli() { noInterrupts(); } + +// enable interrupts +void sei() { interrupts(); } +*/ + +void HAL_adc_init() { + analog_init(); + while (ADC1_GC & ADC_GC_CAL) ; + while (ADC2_GC & ADC_GC_CAL) ; +} + +void HAL_clear_reset_source() { + uint32_t reset_source = SRC_SRSR; + SRC_SRSR = reset_source; + } + +uint8_t HAL_get_reset_source() { + switch (SRC_SRSR & 0xFF) { + case 1: return RST_POWER_ON; break; + case 2: return RST_SOFTWARE; break; + case 4: return RST_EXTERNAL; break; + // case 8: return RST_BROWN_OUT; break; + case 16: return RST_WATCHDOG; break; + case 64: return RST_JTAG; break; + // case 128: return RST_OVERTEMP; break; + } + return 0; +} + +#define __bss_end _ebss + +extern "C" { + extern char __bss_end; + extern char __heap_start; + extern void* __brkval; + + // Doesn't work on Teensy 4.x + uint32_t freeMemory() { + uint32_t free_memory; + if ((uint32_t)__brkval == 0) + free_memory = ((uint32_t)&free_memory) - ((uint32_t)&__bss_end); + else + free_memory = ((uint32_t)&free_memory) - ((uint32_t)__brkval); + return free_memory; + } +} + +void HAL_adc_start_conversion(const uint8_t adc_pin) { + const uint16_t pin = pin2sc1a[adc_pin]; + if (pin == 0xFF) { + HAL_adc_select = -1; // Digital only + } + else if (pin & 0x80) { + HAL_adc_select = 1; + ADC2_HC0 = pin & 0x7F; + } + else { + HAL_adc_select = 0; + ADC1_HC0 = pin; + } +} + +uint16_t HAL_adc_get_result() { + switch (HAL_adc_select) { + case 0: + while (!(ADC1_HS & ADC_HS_COCO0)) ; // wait + return ADC1_R0; + case 1: + while (!(ADC2_HS & ADC_HS_COCO0)) ; // wait + return ADC2_R0; + } + return 0; +} + +bool is_output(uint8_t pin) { + const struct digital_pin_bitband_and_config_table_struct *p; + p = digital_pin_to_info_PGM + pin; + return (*(p->reg + 1) & p->mask); +} + +#endif // __IMXRT1062__ diff --git a/Marlin/src/HAL/TEENSY40_41/HAL.h b/Marlin/src/HAL/TEENSY40_41/HAL.h new file mode 100644 index 000000000000..75c10e93958e --- /dev/null +++ b/Marlin/src/HAL/TEENSY40_41/HAL.h @@ -0,0 +1,148 @@ +/** + * Marlin 3D Printer Firmware + * + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com + * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com + * + * 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 . + * + */ +#pragma once + +/** + * HAL for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) + */ + +#define CPU_32_BIT + +#include "../shared/Marduino.h" +#include "../shared/math_32bit.h" +#include "../shared/HAL_SPI.h" + +#include "fastio.h" +#include "watchdog.h" + +#include +#include + +//#define ST7920_DELAY_1 DELAY_NS(600) +//#define ST7920_DELAY_2 DELAY_NS(750) +//#define ST7920_DELAY_3 DELAY_NS(750) + +// ------------------------ +// Defines +// ------------------------ + +#define IS_32BIT_TEENSY 1 +#define IS_TEENSY_40_41 1 +#ifndef IS_TEENSY40 + #define IS_TEENSY41 1 +#endif + +#define _MSERIAL(X) Serial##X +#define MSERIAL(X) _MSERIAL(X) +#define Serial0 Serial + +#if SERIAL_PORT == -1 + #define MYSERIAL0 SerialUSB +#elif WITHIN(SERIAL_PORT, 0, 8) + #define MYSERIAL0 MSERIAL(SERIAL_PORT) +#else + #error "The required SERIAL_PORT must be from -1 to 8. Please update your configuration." +#endif + +#ifdef SERIAL_PORT_2 + #if SERIAL_PORT_2 == -1 + #define MYSERIAL1 usbSerial + #elif WITHIN(SERIAL_PORT_2, 0, 8) + #define MYSERIAL1 MSERIAL(SERIAL_PORT_2) + #else + #error "SERIAL_PORT_2 must be from -1 to 8. Please update your configuration." + #endif +#endif + +#define HAL_SERVO_LIB libServo + +typedef int8_t pin_t; + +#ifndef analogInputToDigitalPin + #define analogInputToDigitalPin(p) ((p < 12U) ? (p) + 54U : -1) +#endif + +#define CRITICAL_SECTION_START() uint32_t primask = __get_primask(); __disable_irq() +#define CRITICAL_SECTION_END() if (!primask) __enable_irq() +#define ISRS_ENABLED() (!__get_primask()) +#define ENABLE_ISRS() __enable_irq() +#define DISABLE_ISRS() __disable_irq() + +#undef sq +#define sq(x) ((x)*(x)) + +#ifndef strncpy_P + #define strncpy_P(dest, src, num) strncpy((dest), (src), (num)) +#endif + +// Don't place string constants in PROGMEM +#undef PSTR +#define PSTR(str) ({static const char *data = (str); &data[0];}) + +// Fix bug in pgm_read_ptr +#undef pgm_read_ptr +#define pgm_read_ptr(addr) (*((void**)(addr))) +// Add type-checking to pgm_read_word +#undef pgm_read_word +#define pgm_read_word(addr) (*((uint16_t*)(addr))) + +// Enable hooks into idle and setup for HAL +#define HAL_IDLETASK 1 +FORCE_INLINE void HAL_idletask() {} +FORCE_INLINE void HAL_init() {} + +// Clear reset reason +void HAL_clear_reset_source(); + +// Reset reason +uint8_t HAL_get_reset_source(); + +FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); } + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +extern "C" { + uint32_t freeMemory(); +} +#pragma GCC diagnostic pop + +// ADC + +void HAL_adc_init(); + +#define HAL_ADC_VREF 3.3 +#define HAL_ADC_RESOLUTION 10 +#define HAL_ADC_FILTERED // turn off ADC oversampling +#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin) +#define HAL_READ_ADC() HAL_adc_get_result() +#define HAL_ADC_READY() true + +#define HAL_ANALOG_SELECT(pin) + +void HAL_adc_start_conversion(const uint8_t adc_pin); +uint16_t HAL_adc_get_result(); + +#define GET_PIN_MAP_PIN(index) index +#define GET_PIN_MAP_INDEX(pin) pin +#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval) + +bool is_output(uint8_t pin); diff --git a/Marlin/src/HAL/TEENSY40_41/HAL_SPI.cpp b/Marlin/src/HAL/TEENSY40_41/HAL_SPI.cpp new file mode 100644 index 000000000000..20b472aa3515 --- /dev/null +++ b/Marlin/src/HAL/TEENSY40_41/HAL_SPI.cpp @@ -0,0 +1,143 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * HAL SPI for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) + */ + +#ifdef __IMXRT1062__ + +#include "HAL.h" +#include +#include +#include "spi_pins.h" +#include "../../core/macros.h" + +static SPISettings spiConfig; + +// ------------------------ +// Public functions +// ------------------------ + +#if ENABLED(SOFTWARE_SPI) + // ------------------------ + // Software SPI + // ------------------------ + #error "Software SPI not supported for Teensy 4. Use Hardware SPI." +#else + +// ------------------------ +// Hardware SPI +// ------------------------ + +void spiBegin() { + #ifndef SS_PIN + #error "SS_PIN is not defined!" + #endif + + OUT_WRITE(SS_PIN, HIGH); + + //SET_OUTPUT(SCK_PIN); + //SET_INPUT(MISO_PIN); + //SET_OUTPUT(MOSI_PIN); + + #if 0 && DISABLED(SOFTWARE_SPI) + // set SS high - may be chip select for another SPI device + #if SET_SPI_SS_HIGH + WRITE(SS_PIN, HIGH); + #endif + // set a default rate + spiInit(SPI_HALF_SPEED); // 1 + #endif +} + +void spiInit(uint8_t spiRate) { + // Use Marlin data-rates + uint32_t clock; + switch (spiRate) { + case SPI_FULL_SPEED: clock = 10000000; break; + case SPI_HALF_SPEED: clock = 5000000; break; + case SPI_QUARTER_SPEED: clock = 2500000; break; + case SPI_EIGHTH_SPEED: clock = 1250000; break; + case SPI_SPEED_5: clock = 625000; break; + case SPI_SPEED_6: clock = 312500; break; + default: + clock = 4000000; // Default from the SPI libarary + } + spiConfig = SPISettings(clock, MSBFIRST, SPI_MODE0); + SPI.begin(); +} + +uint8_t spiRec() { + SPI.beginTransaction(spiConfig); + uint8_t returnByte = SPI.transfer(0xFF); + SPI.endTransaction(); + return returnByte; + //SPDR = 0xFF; + //while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } + //return SPDR; +} + +void spiRead(uint8_t* buf, uint16_t nbyte) { + SPI.beginTransaction(spiConfig); + SPI.transfer(buf, nbyte); + SPI.endTransaction(); + //if (nbyte-- == 0) return; + // SPDR = 0xFF; + //for (uint16_t i = 0; i < nbyte; i++) { + // while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } + // buf[i] = SPDR; + // SPDR = 0xFF; + //} + //while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } + //buf[nbyte] = SPDR; +} + +void spiSend(uint8_t b) { + SPI.beginTransaction(spiConfig); + SPI.transfer(b); + SPI.endTransaction(); + //SPDR = b; + //while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } +} + +void spiSendBlock(uint8_t token, const uint8_t* buf) { + SPI.beginTransaction(spiConfig); + SPDR = token; + for (uint16_t i = 0; i < 512; i += 2) { + while (!TEST(SPSR, SPIF)) { /* nada */ }; + SPDR = buf[i]; + while (!TEST(SPSR, SPIF)) { /* nada */ }; + SPDR = buf[i + 1]; + } + while (!TEST(SPSR, SPIF)) { /* nada */ }; + SPI.endTransaction(); +} + +// Begin SPI transaction, set clock, bit order, data mode +void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) { + spiConfig = SPISettings(spiClock, bitOrder, dataMode); + SPI.beginTransaction(spiConfig); +} + +#endif // SOFTWARE_SPI +#endif // __IMXRT1062__ diff --git a/Marlin/src/HAL/HAL_STM32/Servo.cpp b/Marlin/src/HAL/TEENSY40_41/Servo.cpp similarity index 52% rename from Marlin/src/HAL/HAL_STM32/Servo.cpp rename to Marlin/src/HAL/TEENSY40_41/Servo.cpp index 2dcadb88763f..ffb1102b14f9 100644 --- a/Marlin/src/HAL/HAL_STM32/Servo.cpp +++ b/Marlin/src/HAL/TEENSY40_41/Servo.cpp @@ -4,7 +4,6 @@ * * Based on Sprinter and grbl. * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * Copyright (c) 2017 Victor Perez * * 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 @@ -17,10 +16,15 @@ * 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 . + * along with this program. If not, see . * */ -#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC) + +/** + * HAL Servo for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) + */ + +#ifdef __IMXRT1062__ #include "../../inc/MarlinConfig.h" @@ -28,35 +32,30 @@ #include "Servo.h" -static uint_fast8_t servoCount = 0; -constexpr millis_t servoDelay[] = SERVO_DELAY; -static_assert(COUNT(servoDelay) == NUM_SERVOS, "SERVO_DELAY must be an array NUM_SERVOS long."); - -libServo::libServo() -: delay(servoDelay[servoCount++]) -{} - -int8_t libServo::attach(const int pin) { - if (servoCount >= MAX_SERVOS) return -1; - if (pin > 0) servo_pin = pin; - return super::attach(servo_pin); +int8_t libServo::attach(const int inPin) { + if (inPin > 0) servoPin = inPin; + return super::attach(servoPin); } -int8_t libServo::attach(const int pin, const int min, const int max) { - if (servoCount >= MAX_SERVOS) return -1; - if (pin > 0) servo_pin = pin; - return super::attach(servo_pin, min, max); +int8_t libServo::attach(const int inPin, const int inMin, const int inMax) { + if (inPin > 0) servoPin = inPin; + return super::attach(servoPin, inMin, inMax); } void libServo::move(const int value) { + constexpr uint16_t servo_delay[] = SERVO_DELAY; + static_assert(COUNT(servo_delay) == NUM_SERVOS, "SERVO_DELAY must be an array NUM_SERVOS long."); if (attach(0) >= 0) { write(value); - safe_delay(delay); - #if ENABLED(DEACTIVATE_SERVOS_AFTER_MOVE) - detach(); - #endif + safe_delay(servo_delay[servoIndex]); + TERN_(DEACTIVATE_SERVOS_AFTER_MOVE, detach()); } } -#endif // HAS_SERVOS -#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC +void libServo::detach() { + // PWMServo library does not have detach() function + //super::detach(); +} + +#endif // HAS_SERVOS +#endif // __IMXRT1062__ diff --git a/Marlin/src/HAL/HAL_STM32/Servo.h b/Marlin/src/HAL/TEENSY40_41/Servo.h similarity index 68% rename from Marlin/src/HAL/HAL_STM32/Servo.h rename to Marlin/src/HAL/TEENSY40_41/Servo.h index 1f841f8184aa..699fd700c943 100644 --- a/Marlin/src/HAL/HAL_STM32/Servo.h +++ b/Marlin/src/HAL/TEENSY40_41/Servo.h @@ -4,7 +4,6 @@ * * Based on Sprinter and grbl. * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * Copyright (c) 2017 Victor Perez * * 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 @@ -17,23 +16,28 @@ * 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 . + * along with this program. If not, see . * */ #pragma once -#include +/** + * HAL Servo for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) + */ -// Inherit and expand on the official library -class libServo : public Servo { +#include + +// Inherit and expand on core Servo library +class libServo : public PWMServo { public: - libServo(); int8_t attach(const int pin); int8_t attach(const int pin, const int min, const int max); void move(const int value); + void detach(void); private: - typedef Servo super; - - int servo_pin = 0; - millis_t delay = 0; + typedef PWMServo super; + uint8_t servoPin; + uint16_t min_ticks; + uint16_t max_ticks; + uint8_t servoIndex; // Index into the channel data for this servo }; diff --git a/Marlin/src/HAL/TEENSY40_41/eeprom.cpp b/Marlin/src/HAL/TEENSY40_41/eeprom.cpp new file mode 100644 index 000000000000..030a8c38af3f --- /dev/null +++ b/Marlin/src/HAL/TEENSY40_41/eeprom.cpp @@ -0,0 +1,76 @@ +/** + * Marlin 3D Printer Firmware + * + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com + * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com + * Copyright (c) 2016 Victor Perez victor_pv@hotmail.com + * + * 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 . + * + */ +#ifdef __IMXRT1062__ + +#include "../../inc/MarlinConfig.h" + +#if USE_WIRED_EEPROM + +/** + * HAL PersistentStore for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) + */ + +#include "../shared/eeprom_api.h" +#include + +#ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE size_t(E2END + 1) +#endif +size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } + +bool PersistentStore::access_start() { return true; } +bool PersistentStore::access_finish() { return true; } + +bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { + while (size--) { + uint8_t * const p = (uint8_t * const)pos; + uint8_t v = *value; + // EEPROM has only ~100,000 write cycles, + // so only write bytes that have changed! + if (v != eeprom_read_byte(p)) { + eeprom_write_byte(p, v); + if (eeprom_read_byte(p) != v) { + SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE); + return true; + } + } + crc16(crc, &v, 1); + pos++; + value++; + } + return false; +} + +bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) { + do { + uint8_t c = eeprom_read_byte((uint8_t*)pos); + if (writing) *value = c; + crc16(crc, &c, 1); + pos++; + value++; + } while (--size); + return false; +} + +#endif // USE_WIRED_EEPROM +#endif // __IMXRT1062__ diff --git a/Marlin/src/HAL/TEENSY40_41/endstop_interrupts.h b/Marlin/src/HAL/TEENSY40_41/endstop_interrupts.h new file mode 100644 index 000000000000..a05e911668a7 --- /dev/null +++ b/Marlin/src/HAL/TEENSY40_41/endstop_interrupts.h @@ -0,0 +1,66 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * HAL Endstop Interrupts for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) + * + * Without endstop interrupts the endstop pins must be polled continually in + * the temperature-ISR via endstops.update(), most of the time finding no change. + * With this feature endstops.update() is called only when we know that at + * least one endstop has changed state, saving valuable CPU cycles. + * + * This feature only works when all used endstop pins can generate an 'external interrupt'. + * + * Test whether pins issue interrupts on your board by flashing 'pin_interrupt_test.ino'. + * (Located in Marlin/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino) + */ + +#include "../../module/endstops.h" + +// One ISR for all EXT-Interrupts +void endstop_ISR() { endstops.update(); } + +/** + * Endstop interrupts for Due based targets. + * On Due, all pins support external interrupt capability. + */ +void setup_endstop_interrupts() { + #define _ATTACH(P) attachInterrupt(digitalPinToInterrupt(P), endstop_ISR, CHANGE) + TERN_(HAS_X_MAX, _ATTACH(X_MAX_PIN)); + TERN_(HAS_X_MIN, _ATTACH(X_MIN_PIN)); + TERN_(HAS_Y_MAX, _ATTACH(Y_MAX_PIN)); + TERN_(HAS_Y_MIN, _ATTACH(Y_MIN_PIN)); + TERN_(HAS_Z_MAX, _ATTACH(Z_MAX_PIN)); + TERN_(HAS_Z_MIN, _ATTACH(Z_MIN_PIN)); + TERN_(HAS_X2_MAX, _ATTACH(X2_MAX_PIN)); + TERN_(HAS_X2_MIN, _ATTACH(X2_MIN_PIN)); + TERN_(HAS_Y2_MAX, _ATTACH(Y2_MAX_PIN)); + TERN_(HAS_Y2_MIN, _ATTACH(Y2_MIN_PIN)); + TERN_(HAS_Z2_MAX, _ATTACH(Z2_MAX_PIN)); + TERN_(HAS_Z2_MIN, _ATTACH(Z2_MIN_PIN)); + TERN_(HAS_Z3_MAX, _ATTACH(Z3_MAX_PIN)); + TERN_(HAS_Z3_MIN, _ATTACH(Z3_MIN_PIN)); + TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN)); + TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN)); + TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN)); +} diff --git a/Marlin/src/HAL/TEENSY40_41/fastio.h b/Marlin/src/HAL/TEENSY40_41/fastio.h new file mode 100644 index 000000000000..52f991dfb85f --- /dev/null +++ b/Marlin/src/HAL/TEENSY40_41/fastio.h @@ -0,0 +1,58 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * Copyright (c) 2017 Victor Perez + * + * 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 . + * + */ +#pragma once + +/** + * Fast I/O interfaces for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) + * These use GPIO functions instead of Direct Port Manipulation, as on AVR. + */ + +#ifndef PWM + #define PWM OUTPUT +#endif + +#define READ(IO) digitalRead(IO) +#define WRITE(IO,V) digitalWrite(IO,V) + +#define _GET_MODE(IO) !is_output(IO) +#define _SET_MODE(IO,M) pinMode(IO, M) +#define _SET_OUTPUT(IO) pinMode(IO, OUTPUT) /*!< Output Push Pull Mode & GPIO_NOPULL */ + +#define OUT_WRITE(IO,V) do{ _SET_OUTPUT(IO); WRITE(IO,V); }while(0) + +#define SET_INPUT(IO) _SET_MODE(IO, INPUT) /*!< Input Floating Mode */ +#define SET_INPUT_PULLUP(IO) _SET_MODE(IO, INPUT_PULLUP) /*!< Input with Pull-up activation */ +#define SET_INPUT_PULLDOWN(IO) _SET_MODE(IO, INPUT_PULLDOWN) /*!< Input with Pull-down activation */ +#define SET_OUTPUT(IO) OUT_WRITE(IO, LOW) +#define SET_PWM(IO) _SET_MODE(IO, PWM) + +#define TOGGLE(IO) OUT_WRITE(IO, !READ(IO)) + +#define IS_INPUT(IO) !is_output(IO) +#define IS_OUTPUT(IO) is_output(IO) + +#define PWM_PIN(P) digitalPinHasPWM(P) + +// digitalRead/Write wrappers +#define extDigitalRead(IO) digitalRead(IO) +#define extDigitalWrite(IO,V) digitalWrite(IO,V) diff --git a/Marlin/src/HAL/TEENSY40_41/inc/Conditionals_LCD.h b/Marlin/src/HAL/TEENSY40_41/inc/Conditionals_LCD.h new file mode 100644 index 000000000000..6a8540927b97 --- /dev/null +++ b/Marlin/src/HAL/TEENSY40_41/inc/Conditionals_LCD.h @@ -0,0 +1,26 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if HAS_SPI_TFT || HAS_FSMC_TFT + #error "Sorry! TFT displays are not available for HAL/TEENSY40_41." +#endif diff --git a/Marlin/src/HAL/TEENSY40_41/inc/Conditionals_adv.h b/Marlin/src/HAL/TEENSY40_41/inc/Conditionals_adv.h new file mode 100644 index 000000000000..5f1c4b16019d --- /dev/null +++ b/Marlin/src/HAL/TEENSY40_41/inc/Conditionals_adv.h @@ -0,0 +1,22 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once diff --git a/Marlin/src/HAL/TEENSY40_41/inc/Conditionals_post.h b/Marlin/src/HAL/TEENSY40_41/inc/Conditionals_post.h new file mode 100644 index 000000000000..998f1dcc0d73 --- /dev/null +++ b/Marlin/src/HAL/TEENSY40_41/inc/Conditionals_post.h @@ -0,0 +1,26 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if USE_FALLBACK_EEPROM + #define USE_WIRED_EEPROM 1 +#endif diff --git a/Marlin/src/HAL/TEENSY40_41/inc/SanityCheck.h b/Marlin/src/HAL/TEENSY40_41/inc/SanityCheck.h new file mode 100644 index 000000000000..fbfe7b0fc3d4 --- /dev/null +++ b/Marlin/src/HAL/TEENSY40_41/inc/SanityCheck.h @@ -0,0 +1,38 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * Test TEENSY41 specific configuration values for errors at compile-time. + */ + +#if ENABLED(EMERGENCY_PARSER) + #error "EMERGENCY_PARSER is not yet implemented for Teensy 4.0/4.1. Disable EMERGENCY_PARSER to continue." +#endif + +#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY + #error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on Teensy 4.0/4.1." +#endif + +#if HAS_TMC_SW_SERIAL + #error "TMC220x Software Serial is not supported on this platform." +#endif diff --git a/Marlin/src/HAL/TEENSY40_41/pinsDebug.h b/Marlin/src/HAL/TEENSY40_41/pinsDebug.h new file mode 100644 index 000000000000..4ad62d00fea5 --- /dev/null +++ b/Marlin/src/HAL/TEENSY40_41/pinsDebug.h @@ -0,0 +1,150 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * HAL Pins Debugging for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) + */ + +#warning "PINS_DEBUGGING is not fully supported for Teensy 4.0 / 4.1 so 'M43' may cause hangs." + +#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS + +#define digitalRead_mod(p) extDigitalRead(p) // AVR digitalRead disabled PWM before it read the pin +#define PRINT_PORT(p) +#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) +#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%02d"), p); SERIAL_ECHO(buffer); }while(0) +#define GET_ARRAY_PIN(p) pin_array[p].pin +#define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital +#define VALID_PIN(pin) (pin >= 0 && pin < (int8_t)NUMBER_PINS_TOTAL ? 1 : 0) +#define DIGITAL_PIN_TO_ANALOG_PIN(p) int(p - analogInputToDigitalPin(0)) +#define IS_ANALOG(P) ((P) >= analogInputToDigitalPin(0) && (P) <= analogInputToDigitalPin(13)) || ((P) >= analogInputToDigitalPin(14) && (P) <= analogInputToDigitalPin(17)) +#define pwm_status(pin) HAL_pwm_status(pin) +#define GET_PINMODE(PIN) (VALID_PIN(pin) && IS_OUTPUT(pin)) +#define MULTI_NAME_PAD 16 // space needed to be pretty if not first name assigned to a pin + +struct pwm_pin_info_struct { + uint8_t type; // 0=no pwm, 1=flexpwm, 2=quad + uint8_t module; // 0-3, 0-3 + uint8_t channel; // 0=X, 1=A, 2=B + uint8_t muxval; // +}; + +#define M(a, b) ((((a) - 1) << 4) | (b)) + +const struct pwm_pin_info_struct pwm_pin_info[] = { + {1, M(1, 1), 0, 4}, // FlexPWM1_1_X 0 // AD_B0_03 + {1, M(1, 0), 0, 4}, // FlexPWM1_0_X 1 // AD_B0_02 + {1, M(4, 2), 1, 1}, // FlexPWM4_2_A 2 // EMC_04 + {1, M(4, 2), 2, 1}, // FlexPWM4_2_B 3 // EMC_05 + {1, M(2, 0), 1, 1}, // FlexPWM2_0_A 4 // EMC_06 + {1, M(2, 1), 1, 1}, // FlexPWM2_1_A 5 // EMC_08 + {1, M(2, 2), 1, 2}, // FlexPWM2_2_A 6 // B0_10 + {1, M(1, 3), 2, 6}, // FlexPWM1_3_B 7 // B1_01 + {1, M(1, 3), 1, 6}, // FlexPWM1_3_A 8 // B1_00 + {1, M(2, 2), 2, 2}, // FlexPWM2_2_B 9 // B0_11 + {2, M(1, 0), 0, 1}, // QuadTimer1_0 10 // B0_00 + {2, M(1, 2), 0, 1}, // QuadTimer1_2 11 // B0_02 + {2, M(1, 1), 0, 1}, // QuadTimer1_1 12 // B0_01 + {2, M(2, 0), 0, 1}, // QuadTimer2_0 13 // B0_03 + {2, M(3, 2), 0, 1}, // QuadTimer3_2 14 // AD_B1_02 + {2, M(3, 3), 0, 1}, // QuadTimer3_3 15 // AD_B1_03 + {0, M(1, 0), 0, 0}, + {0, M(1, 0), 0, 0}, + {2, M(3, 1), 0, 1}, // QuadTimer3_1 18 // AD_B1_01 + {2, M(3, 0), 0, 1}, // QuadTimer3_0 19 // AD_B1_00 + {0, M(1, 0), 0, 0}, + {0, M(1, 0), 0, 0}, + {1, M(4, 0), 1, 1}, // FlexPWM4_0_A 22 // AD_B1_08 + {1, M(4, 1), 1, 1}, // FlexPWM4_1_A 23 // AD_B1_09 + {1, M(1, 2), 0, 4}, // FlexPWM1_2_X 24 // AD_B0_12 + {1, M(1, 3), 0, 4}, // FlexPWM1_3_X 25 // AD_B0_13 + {0, M(1, 0), 0, 0}, + {0, M(1, 0), 0, 0}, + {1, M(3, 1), 2, 1}, // FlexPWM3_1_B 28 // EMC_32 + {1, M(3, 1), 1, 1}, // FlexPWM3_1_A 29 // EMC_31 + {0, M(1, 0), 0, 0}, + {0, M(1, 0), 0, 0}, + {0, M(1, 0), 0, 0}, + {1, M(2, 0), 2, 1}, // FlexPWM2_0_B 33 // EMC_07 + #ifdef ARDUINO_TEENSY40 + {1, M(1, 1), 2, 1}, // FlexPWM1_1_B 34 // SD_B0_03 + {1, M(1, 1), 1, 1}, // FlexPWM1_1_A 35 // SD_B0_02 + {1, M(1, 0), 2, 1}, // FlexPWM1_0_B 36 // SD_B0_01 + {1, M(1, 0), 1, 1}, // FlexPWM1_0_A 37 // SD_B0_00 + {1, M(1, 2), 2, 1}, // FlexPWM1_2_B 38 // SD_B0_05 + {1, M(1, 2), 1, 1}, // FlexPWM1_2_A 39 // SD_B0_04 + #endif + #ifdef ARDUINO_TEENSY41 + {0, M(1, 0), 0, 0}, + {0, M(1, 0), 0, 0}, + {1, M(2, 3), 1, 6}, // FlexPWM2_3_A 36 // B1_00 + {1, M(2, 3), 2, 6}, // FlexPWM2_3_B 37 // B1_01 + {0, M(1, 0), 0, 0}, + {0, M(1, 0), 0, 0}, + {0, M(1, 0), 0, 0}, + {0, M(1, 0), 0, 0}, + {1, M(1, 1), 2, 1}, // FlexPWM1_1_B 42 // SD_B0_03 + {1, M(1, 1), 1, 1}, // FlexPWM1_1_A 43 // SD_B0_02 + {1, M(1, 0), 2, 1}, // FlexPWM1_0_B 44 // SD_B0_01 + {1, M(1, 0), 1, 1}, // FlexPWM1_0_A 45 // SD_B0_00 + {1, M(1, 2), 2, 1}, // FlexPWM1_2_B 46 // SD_B0_05 + {1, M(1, 2), 1, 1}, // FlexPWM1_2_A 47 // SD_B0_04 + {0, M(1, 0), 0, 0}, // duplicate FlexPWM1_0_B + {0, M(1, 0), 0, 0}, // duplicate FlexPWM1_2_A + {0, M(1, 0), 0, 0}, // duplicate FlexPWM1_2_B + {1, M(3, 3), 2, 1}, // FlexPWM3_3_B 51 // EMC_22 + {0, M(1, 0), 0, 0}, // duplicate FlexPWM1_1_B + {0, M(1, 0), 0, 0}, // duplicate FlexPWM1_1_A + {1, M(3, 0), 1, 1}, // FlexPWM3_0_A 53 // EMC_29 + #endif +}; + +void HAL_print_analog_pin(char buffer[], int8_t pin) { + if (pin <= 23) sprintf_P(buffer, PSTR("(A%2d) "), int(pin - 14)); + else if (pin <= 41) sprintf_P(buffer, PSTR("(A%2d) "), int(pin - 24)); +} + +void HAL_analog_pin_state(char buffer[], int8_t pin) { + if (pin <= 23) sprintf_P(buffer, PSTR("Analog in =% 5d"), analogRead(pin - 14)); + else if (pin <= 41) sprintf_P(buffer, PSTR("Analog in =% 5d"), analogRead(pin - 24)); +} + +#define PWM_PRINT(V) do{ sprintf_P(buffer, PSTR("PWM: %4d"), V); SERIAL_ECHO(buffer); }while(0) + +/** + * Print a pin's PWM status. + * Return true if it's currently a PWM pin. + */ +bool HAL_pwm_status(int8_t pin) { + char buffer[20]; // for the sprintf statements + const struct pwm_pin_info_struct *info; + + if (pin >= CORE_NUM_DIGITAL) return 0; + info = pwm_pin_info + pin; + + if (info->type == 0) return 0; + + /* TODO decode pwm value from timers */ + // for now just indicate if output is set as pwm + PWM_PRINT(*(portConfigRegister(pin)) == info->muxval); + return (*(portConfigRegister(pin)) == info->muxval); +} + +static void pwm_details(uint8_t pin) { /* TODO */ } diff --git a/Marlin/src/HAL/TEENSY40_41/spi_pins.h b/Marlin/src/HAL/TEENSY40_41/spi_pins.h new file mode 100644 index 000000000000..d6f8d41bf6ce --- /dev/null +++ b/Marlin/src/HAL/TEENSY40_41/spi_pins.h @@ -0,0 +1,31 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * HAL SPI Pins for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) + */ + +#define SCK_PIN 13 +#define MISO_PIN 12 +#define MOSI_PIN 11 +#define SS_PIN 20 // SDSS // A.28, A.29, B.21, C.26, C.29 diff --git a/Marlin/src/HAL/TEENSY40_41/timers.cpp b/Marlin/src/HAL/TEENSY40_41/timers.cpp new file mode 100644 index 000000000000..81c9b08c17a5 --- /dev/null +++ b/Marlin/src/HAL/TEENSY40_41/timers.cpp @@ -0,0 +1,114 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * HAL Timers for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) + */ + +#ifdef __IMXRT1062__ + +#include "../../inc/MarlinConfig.h" + +void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { + switch (timer_num) { + case 0: + CCM_CSCMR1 &= ~CCM_CSCMR1_PERCLK_CLK_SEL; // turn off 24mhz mode + CCM_CCGR1 |= CCM_CCGR1_GPT1_BUS(CCM_CCGR_ON); + + GPT1_CR = 0; // disable timer + GPT1_SR = 0x3F; // clear all prior status + GPT1_PR = GPT1_TIMER_PRESCALE - 1; + GPT1_CR |= GPT_CR_CLKSRC(1); //clock selection #1 (peripheral clock = 150 MHz) + GPT1_CR |= GPT_CR_ENMOD; //reset count to zero before enabling + GPT1_CR |= GPT_CR_OM1(1); // toggle mode + GPT1_OCR1 = (GPT1_TIMER_RATE / frequency) -1; // Initial compare value + GPT1_IR = GPT_IR_OF1IE; // Compare3 value + GPT1_CR |= GPT_CR_EN; //enable GPT2 counting at 150 MHz + + OUT_WRITE(15, HIGH); + attachInterruptVector(IRQ_GPT1, &stepTC_Handler); + NVIC_SET_PRIORITY(IRQ_GPT1, 16); + break; + case 1: + CCM_CSCMR1 &= ~CCM_CSCMR1_PERCLK_CLK_SEL; // turn off 24mhz mode + CCM_CCGR0 |= CCM_CCGR0_GPT2_BUS(CCM_CCGR_ON); + + GPT2_CR = 0; // disable timer + GPT2_SR = 0x3F; // clear all prior status + GPT2_PR = GPT2_TIMER_PRESCALE - 1; + GPT2_CR |= GPT_CR_CLKSRC(1); //clock selection #1 (peripheral clock = 150 MHz) + GPT2_CR |= GPT_CR_ENMOD; //reset count to zero before enabling + GPT2_CR |= GPT_CR_OM1(1); // toggle mode + GPT2_OCR1 = (GPT2_TIMER_RATE / frequency) -1; // Initial compare value + GPT2_IR = GPT_IR_OF1IE; // Compare3 value + GPT2_CR |= GPT_CR_EN; //enable GPT2 counting at 150 MHz + + OUT_WRITE(14, HIGH); + attachInterruptVector(IRQ_GPT2, &tempTC_Handler); + NVIC_SET_PRIORITY(IRQ_GPT2, 32); + break; + } +} + +void HAL_timer_enable_interrupt(const uint8_t timer_num) { + switch (timer_num) { + case 0: + NVIC_ENABLE_IRQ(IRQ_GPT1); + break; + case 1: + NVIC_ENABLE_IRQ(IRQ_GPT2); + break; + } +} + +void HAL_timer_disable_interrupt(const uint8_t timer_num) { + switch (timer_num) { + case 0: NVIC_DISABLE_IRQ(IRQ_GPT1); break; + case 1: NVIC_DISABLE_IRQ(IRQ_GPT2); break; + } + + // We NEED memory barriers to ensure Interrupts are actually disabled! + // ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the ) + asm volatile("dsb"); +} + +bool HAL_timer_interrupt_enabled(const uint8_t timer_num) { + switch (timer_num) { + case 0: return (NVIC_IS_ENABLED(IRQ_GPT1)); + case 1: return (NVIC_IS_ENABLED(IRQ_GPT2)); + } + return false; +} + +void HAL_timer_isr_prologue(const uint8_t timer_num) { + switch (timer_num) { + case 0: + GPT1_SR = GPT_IR_OF1IE; // clear OF3 bit + break; + case 1: + GPT2_SR = GPT_IR_OF1IE; // clear OF3 bit + break; + } + asm volatile("dsb"); +} + +#endif // __IMXRT1062__ diff --git a/Marlin/src/HAL/TEENSY40_41/timers.h b/Marlin/src/HAL/TEENSY40_41/timers.h new file mode 100644 index 000000000000..7e4cd080cb88 --- /dev/null +++ b/Marlin/src/HAL/TEENSY40_41/timers.h @@ -0,0 +1,119 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com + * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com + * + * 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 . + * + */ +#pragma once + +/** + * HAL Timers for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) + */ + +#include + +// ------------------------ +// Defines +// ------------------------ + +#define FORCE_INLINE __attribute__((always_inline)) inline + +typedef uint32_t hal_timer_t; +#define HAL_TIMER_TYPE_MAX 0xFFFFFFFE + +#define GPT_TIMER_RATE F_BUS_ACTUAL // 150MHz + +#define GPT1_TIMER_PRESCALE 2 +#define GPT2_TIMER_PRESCALE 10 + +#define GPT1_TIMER_RATE (GPT_TIMER_RATE / GPT1_TIMER_PRESCALE) // 75MHz +#define GPT2_TIMER_RATE (GPT_TIMER_RATE / GPT2_TIMER_PRESCALE) // 15MHz + +#ifndef STEP_TIMER_NUM + #define STEP_TIMER_NUM 0 // Timer Index for Stepper +#endif +#ifndef PULSE_TIMER_NUM + #define PULSE_TIMER_NUM STEP_TIMER_NUM +#endif +#ifndef TEMP_TIMER_NUM + #define TEMP_TIMER_NUM 1 // Timer Index for Temperature +#endif + +#define TEMP_TIMER_RATE 1000000 +#define TEMP_TIMER_FREQUENCY 1000 + +#define STEPPER_TIMER_RATE GPT1_TIMER_RATE +#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) +#define STEPPER_TIMER_PRESCALE ((GPT_TIMER_RATE / 1000000) / STEPPER_TIMER_TICKS_PER_US) + +#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer +#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE +#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US + +#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM) +#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM) +#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM) + +#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM) +#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM) + +#ifndef HAL_STEP_TIMER_ISR + #define HAL_STEP_TIMER_ISR() extern "C" void stepTC_Handler() // GPT1_Handler() +#endif +#ifndef HAL_TEMP_TIMER_ISR + #define HAL_TEMP_TIMER_ISR() extern "C" void tempTC_Handler() // GPT2_Handler() +#endif + +extern "C" void stepTC_Handler(); +extern "C" void tempTC_Handler(); + +void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency); + +FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) { + switch (timer_num) { + case 0: + GPT1_OCR1 = compare - 1; + break; + case 1: + GPT2_OCR1 = compare - 1; + break; + } +} + +FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) { + switch (timer_num) { + case 0: return GPT1_OCR1; + case 1: return GPT2_OCR1; + } + return 0; +} + +FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) { + switch (timer_num) { + case 0: return GPT1_CNT; + case 1: return GPT2_CNT; + } + return 0; +} + +void HAL_timer_enable_interrupt(const uint8_t timer_num); +void HAL_timer_disable_interrupt(const uint8_t timer_num); +bool HAL_timer_interrupt_enabled(const uint8_t timer_num); + +void HAL_timer_isr_prologue(const uint8_t timer_num); +//void HAL_timer_isr_epilogue(const uint8_t timer_num) {} +#define HAL_timer_isr_epilogue(TIMER_NUM) diff --git a/Marlin/src/HAL/TEENSY40_41/watchdog.cpp b/Marlin/src/HAL/TEENSY40_41/watchdog.cpp new file mode 100644 index 000000000000..8b05ddb153eb --- /dev/null +++ b/Marlin/src/HAL/TEENSY40_41/watchdog.cpp @@ -0,0 +1,56 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * HAL Watchdog for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) + */ + +#ifdef __IMXRT1062__ + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(USE_WATCHDOG) + +#include "watchdog.h" + +// 4 seconds timeout +#define WDTO 4 //seconds + +uint8_t timeoutval = (WDTO - 0.5f) / 0.5f; + +void watchdog_init() { + + CCM_CCGR3 |= CCM_CCGR3_WDOG1(3); // enable WDOG1 clocks + WDOG1_WMCR = 0; // disable power down PDE + WDOG1_WCR |= WDOG_WCR_SRS | WDOG_WCR_WT(timeoutval); + WDOG1_WCR |= WDOG_WCR_WDE | WDOG_WCR_WDT | WDOG_WCR_SRE; + +} + +void HAL_watchdog_refresh() { + // Watchdog refresh sequence + WDOG1_WSR = 0x5555; + WDOG1_WSR = 0xAAAA; +} + +#endif // USE_WATCHDOG +#endif // __IMXRT1062__ diff --git a/Marlin/src/HAL/TEENSY40_41/watchdog.h b/Marlin/src/HAL/TEENSY40_41/watchdog.h new file mode 100644 index 000000000000..03ab151b0706 --- /dev/null +++ b/Marlin/src/HAL/TEENSY40_41/watchdog.h @@ -0,0 +1,30 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * HAL Watchdog for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) + */ + +void watchdog_init(); + +void HAL_watchdog_refresh(); diff --git a/Marlin/src/HAL/platforms.h b/Marlin/src/HAL/platforms.h index cbf8a9512bb9..ef17d19170cc 100644 --- a/Marlin/src/HAL/platforms.h +++ b/Marlin/src/HAL/platforms.h @@ -16,37 +16,37 @@ * 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 . + * along with this program. If not, see . * */ #pragma once +#define XSTR(V...) #V + #ifdef __AVR__ - #define HAL_PLATFORM HAL_AVR + #define HAL_PATH(PATH, NAME) XSTR(PATH/AVR/NAME) #elif defined(ARDUINO_ARCH_SAM) - #define HAL_PLATFORM HAL_DUE + #define HAL_PATH(PATH, NAME) XSTR(PATH/DUE/NAME) #elif defined(__MK20DX256__) - #define HAL_PLATFORM HAL_TEENSY31_32 + #define HAL_PATH(PATH, NAME) XSTR(PATH/TEENSY31_32/NAME) #elif defined(__MK64FX512__) || defined(__MK66FX1M0__) - #define HAL_PLATFORM HAL_TEENSY35_36 + #define HAL_PATH(PATH, NAME) XSTR(PATH/TEENSY35_36/NAME) +#elif defined(__IMXRT1062__) + #define HAL_PATH(PATH, NAME) XSTR(PATH/TEENSY40_41/NAME) #elif defined(TARGET_LPC1768) - #define HAL_PLATFORM HAL_LPC1768 + #define HAL_PATH(PATH, NAME) XSTR(PATH/LPC1768/NAME) #elif defined(__STM32F1__) || defined(TARGET_STM32F1) - #define HAL_PLATFORM HAL_STM32F1 + #define HAL_PATH(PATH, NAME) XSTR(PATH/STM32F1/NAME) #elif defined(STM32GENERIC) && (defined(STM32F4) || defined(STM32F7)) - #define HAL_PLATFORM HAL_STM32_F4_F7 + #define HAL_PATH(PATH, NAME) XSTR(PATH/STM32_F4_F7/NAME) #elif defined(ARDUINO_ARCH_STM32) - #define HAL_PLATFORM HAL_STM32 + #define HAL_PATH(PATH, NAME) XSTR(PATH/STM32/NAME) #elif defined(ARDUINO_ARCH_ESP32) - #define HAL_PLATFORM HAL_ESP32 + #define HAL_PATH(PATH, NAME) XSTR(PATH/ESP32/NAME) #elif defined(__PLAT_LINUX__) - #define HAL_PLATFORM HAL_LINUX + #define HAL_PATH(PATH, NAME) XSTR(PATH/LINUX/NAME) #elif defined(__SAMD51__) - #define HAL_PLATFORM HAL_SAMD51 + #define HAL_PATH(PATH, NAME) XSTR(PATH/SAMD51/NAME) #else #error "Unsupported Platform!" #endif - -#define XSTR_(M) #M -#define XSTR(M) XSTR_(M) -#define HAL_PATH(PATH, NAME) XSTR(PATH/HAL_PLATFORM/NAME) diff --git a/Marlin/src/HAL/shared/Delay.h b/Marlin/src/HAL/shared/Delay.h index 78bf6745ea54..d98e96084850 100644 --- a/Marlin/src/HAL/shared/Delay.h +++ b/Marlin/src/HAL/shared/Delay.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -29,7 +29,6 @@ * DELAY_US(count): Delay execution in microseconds */ -#include "../../core/millis_t.h" #include "../../core/macros.h" #if defined(__arm__) || defined(__thumb__) @@ -37,7 +36,7 @@ #if __CORTEX_M == 7 // Cortex-M3 through M7 can use the cycle counter of the DWT unit - // http://www.anthonyvh.com/2017/05/18/cortex_m-cycle_counter/ + // https://www.anthonyvh.com/2017/05/18/cortex_m-cycle_counter/ FORCE_INLINE static void enableCycleCounter() { CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; diff --git a/Marlin/src/HAL/shared/HAL_SPI.h b/Marlin/src/HAL/shared/HAL_SPI.h index 0410d70c9361..59af5548064c 100644 --- a/Marlin/src/HAL/shared/HAL_SPI.h +++ b/Marlin/src/HAL/shared/HAL_SPI.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/shared/HAL_ST7920.h b/Marlin/src/HAL/shared/HAL_ST7920.h index 12392a5ece23..4e362f96ba55 100644 --- a/Marlin/src/HAL/shared/HAL_ST7920.h +++ b/Marlin/src/HAL/shared/HAL_ST7920.h @@ -16,18 +16,18 @@ * 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 . + * along with this program. If not, see . * */ #pragma once /** - * HAL/HAL_ST7920.h + * HAL/ST7920.h * For the HALs that provide direct access to the ST7920 display * (bypassing U8G), it will allow the LIGHTWEIGHT_UI to operate. */ -#if HAS_GRAPHICAL_LCD && ENABLED(LIGHTWEIGHT_UI) +#if BOTH(HAS_MARLINUI_U8GLIB, LIGHTWEIGHT_UI) void ST7920_cs(); void ST7920_ncs(); void ST7920_set_cmd(); diff --git a/Marlin/src/HAL/shared/HAL_spi_L6470.cpp b/Marlin/src/HAL/shared/HAL_spi_L6470.cpp index 46e7b71f88d7..bd85dbe7bd7e 100644 --- a/Marlin/src/HAL/shared/HAL_spi_L6470.cpp +++ b/Marlin/src/HAL/shared/HAL_spi_L6470.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/HAL/shared/Marduino.h b/Marlin/src/HAL/shared/Marduino.h index c022fc72edd6..3003f3cc2891 100644 --- a/Marlin/src/HAL/shared/Marduino.h +++ b/Marlin/src/HAL/shared/Marduino.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/shared/MarlinSerial.h b/Marlin/src/HAL/shared/MarlinSerial.h deleted file mode 100644 index 3770f61b3c26..000000000000 --- a/Marlin/src/HAL/shared/MarlinSerial.h +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL/shared/MarlinSerial.h - */ - -#include "../../inc/MarlinConfigPre.h" - -constexpr bool - #if HAS_DGUS_LCD - bDGUS_SERIAL_STATS_RX_BUFFER_OVERRUNS = (false - #if ENABLED(DGUS_SERIAL_STATS_RX_BUFFER_OVERRUNS) - || true - #endif - ), - #endif - bSERIAL_XON_XOFF = (false - #if ENABLED(SERIAL_XON_XOFF) - || true - #endif - ), - bEMERGENCY_PARSER = (false - #if ENABLED(EMERGENCY_PARSER) - || true - #endif - ), - bSERIAL_STATS_DROPPED_RX = (false - #if ENABLED(SERIAL_STATS_DROPPED_RX) - || true - #endif - ), - bSERIAL_STATS_RX_BUFFER_OVERRUNS = (false - #if ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS) - || true - #endif - ), - bSERIAL_STATS_RX_FRAMING_ERRORS = (false - #if ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS) - || true - #endif - ), - bSERIAL_STATS_MAX_RX_QUEUED = (false - #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) - || true - #endif - ); diff --git a/Marlin/src/HAL/shared/backtrace/backtrace.cpp b/Marlin/src/HAL/shared/backtrace/backtrace.cpp index 7264969c7437..6cf5e055e151 100644 --- a/Marlin/src/HAL/shared/backtrace/backtrace.cpp +++ b/Marlin/src/HAL/shared/backtrace/backtrace.cpp @@ -16,10 +16,9 @@ * 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 . + * along with this program. If not, see . * */ - #if defined(__arm__) || defined(__thumb__) #include "backtrace.h" diff --git a/Marlin/src/HAL/shared/backtrace/backtrace.h b/Marlin/src/HAL/shared/backtrace/backtrace.h index 636eb09a7137..fccadedaa543 100644 --- a/Marlin/src/HAL/shared/backtrace/backtrace.h +++ b/Marlin/src/HAL/shared/backtrace/backtrace.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/shared/backtrace/unwarm_thumb.cpp b/Marlin/src/HAL/shared/backtrace/unwarm_thumb.cpp index d5449f863e08..26ca8b2604e9 100644 --- a/Marlin/src/HAL/shared/backtrace/unwarm_thumb.cpp +++ b/Marlin/src/HAL/shared/backtrace/unwarm_thumb.cpp @@ -807,7 +807,7 @@ UnwResult UnwStartThumb(UnwState * const state) { case 2: /* MOV */ UnwPrintd5("MOV r%d, r%d\t; r%d %s", rhd, rhs, rhd, M_Origin2Str(state->regData[rhs].o)); state->regData[rhd].v = state->regData[rhs].v; - state->regData[rhd].o = state->regData[rhd].o; + state->regData[rhd].o = state->regData[rhs].o; break; case 3: /* BX */ diff --git a/Marlin/src/HAL/shared/backtrace/unwarmbytab.cpp b/Marlin/src/HAL/shared/backtrace/unwarmbytab.cpp index 207cd56aa82e..bfc062af2090 100644 --- a/Marlin/src/HAL/shared/backtrace/unwarmbytab.cpp +++ b/Marlin/src/HAL/shared/backtrace/unwarmbytab.cpp @@ -4,7 +4,7 @@ * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * file, You can obtain one at https://www.mozilla.org/en-US/MPL/2.0/ * * This library was modified, some bugs fixed, stack address validated * and adapted to be used in Marlin 3D printer firmware as backtracer diff --git a/Marlin/src/HAL/shared/backtrace/unwmemaccess.cpp b/Marlin/src/HAL/shared/backtrace/unwmemaccess.cpp index 8cf31cadf556..c93494d485c3 100644 --- a/Marlin/src/HAL/shared/backtrace/unwmemaccess.cpp +++ b/Marlin/src/HAL/shared/backtrace/unwmemaccess.cpp @@ -20,124 +20,139 @@ /* Validate address */ #ifdef ARDUINO_ARCH_SAM -// For DUE, valid address ranges are -// SRAM (0x20070000 - 0x20088000) (96kb) -// FLASH (0x00080000 - 0x00100000) (512kb) -// -#define START_SRAM_ADDR 0x20070000 -#define END_SRAM_ADDR 0x20088000 -#define START_FLASH_ADDR 0x00080000 -#define END_FLASH_ADDR 0x00100000 -#endif - -#ifdef TARGET_LPC1768 -// For LPC1769: -// SRAM (0x10000000 - 0x10008000) (32kb) -// FLASH (0x00000000 - 0x00080000) (512kb) -// -#define START_SRAM_ADDR 0x10000000 -#define END_SRAM_ADDR 0x10008000 -#define START_FLASH_ADDR 0x00000000 -#define END_FLASH_ADDR 0x00080000 -#endif - -#if 0 -// For STM32F103CBT6 -// SRAM (0x20000000 - 0x20005000) (20kb) -// FLASH (0x00000000 - 0x00020000) (128kb) -// -#define START_SRAM_ADDR 0x20000000 -#define END_SRAM_ADDR 0x20005000 -#define START_FLASH_ADDR 0x00000000 -#define END_FLASH_ADDR 0x00020000 -#endif -#if defined(__STM32F1__) || defined(STM32F1xx) || defined(STM32F0xx) -// For STM32F103ZET6/STM32F103VET6/STM32F0xx -// SRAM (0x20000000 - 0x20010000) (64kb) -// FLASH (0x00000000 - 0x00080000) (512kb) -// -#define START_SRAM_ADDR 0x20000000 -#define END_SRAM_ADDR 0x20010000 -#define START_FLASH_ADDR 0x00000000 -#define END_FLASH_ADDR 0x00080000 -#endif - -#if defined(STM32F4) || defined(STM32F4xx) -// For STM32F407VET -// SRAM (0x20000000 - 0x20030000) (192kb) -// FLASH (0x08000000 - 0x08080000) (512kb) -// -#define START_SRAM_ADDR 0x20000000 -#define END_SRAM_ADDR 0x20030000 -#define START_FLASH_ADDR 0x08000000 -#define END_FLASH_ADDR 0x08080000 -#endif - -#if MB(THE_BORG) -// For STM32F765 in BORG -// SRAM (0x20000000 - 0x20080000) (512kb) -// FLASH (0x08000000 - 0x08100000) (1024kb) -// -#define START_SRAM_ADDR 0x20000000 -#define END_SRAM_ADDR 0x20080000 -#define START_FLASH_ADDR 0x08000000 -#define END_FLASH_ADDR 0x08100000 -#endif + // For DUE, valid address ranges are + // SRAM (0x20070000 - 0x20088000) (96kb) + // FLASH (0x00080000 - 0x00100000) (512kb) + // + #define START_SRAM_ADDR 0x20070000 + #define END_SRAM_ADDR 0x20088000 + #define START_FLASH_ADDR 0x00080000 + #define END_FLASH_ADDR 0x00100000 + +#elif defined(TARGET_LPC1768) + + // For LPC1769: + // SRAM (0x10000000 - 0x10008000) (32kb) + // FLASH (0x00000000 - 0x00080000) (512kb) + // + #define START_SRAM_ADDR 0x10000000 + #define END_SRAM_ADDR 0x10008000 + #define START_FLASH_ADDR 0x00000000 + #define END_FLASH_ADDR 0x00080000 + +#elif 0 + + // For STM32F103CBT6 + // SRAM (0x20000000 - 0x20005000) (20kb) + // FLASH (0x00000000 - 0x00020000) (128kb) + // + #define START_SRAM_ADDR 0x20000000 + #define END_SRAM_ADDR 0x20005000 + #define START_FLASH_ADDR 0x00000000 + #define END_FLASH_ADDR 0x00020000 + +#elif defined(__STM32F1__) || defined(STM32F1xx) || defined(STM32F0xx) + + // For STM32F103ZET6/STM32F103VET6/STM32F0xx + // SRAM (0x20000000 - 0x20010000) (64kb) + // FLASH (0x00000000 - 0x00080000) (512kb) + // + #define START_SRAM_ADDR 0x20000000 + #define END_SRAM_ADDR 0x20010000 + #define START_FLASH_ADDR 0x00000000 + #define END_FLASH_ADDR 0x00080000 + +#elif defined(STM32F4) || defined(STM32F4xx) + + // For STM32F407VET + // SRAM (0x20000000 - 0x20030000) (192kb) + // FLASH (0x08000000 - 0x08080000) (512kb) + // + #define START_SRAM_ADDR 0x20000000 + #define END_SRAM_ADDR 0x20030000 + #define START_FLASH_ADDR 0x08000000 + #define END_FLASH_ADDR 0x08080000 + +#elif MB(THE_BORG) + + // For STM32F765 in BORG + // SRAM (0x20000000 - 0x20080000) (512kb) + // FLASH (0x08000000 - 0x08100000) (1024kb) + // + #define START_SRAM_ADDR 0x20000000 + #define END_SRAM_ADDR 0x20080000 + #define START_FLASH_ADDR 0x08000000 + #define END_FLASH_ADDR 0x08100000 + +#elif MB(REMRAM_V1, NUCLEO_F767ZI) + + // For STM32F765VI in RemRam v1 + // SRAM (0x20000000 - 0x20080000) (512kb) + // FLASH (0x08000000 - 0x08200000) (2048kb) + // + #define START_SRAM_ADDR 0x20000000 + #define END_SRAM_ADDR 0x20080000 + #define START_FLASH_ADDR 0x08000000 + #define END_FLASH_ADDR 0x08200000 + +#elif defined(__MK20DX256__) + + // For MK20DX256 in TEENSY 3.1 or TEENSY 3.2 + // SRAM (0x1FFF8000 - 0x20008000) (64kb) + // FLASH (0x00000000 - 0x00040000) (256kb) + // + #define START_SRAM_ADDR 0x1FFF8000 + #define END_SRAM_ADDR 0x20008000 + #define START_FLASH_ADDR 0x00000000 + #define END_FLASH_ADDR 0x00040000 + +#elif defined(__MK64FX512__) + + // For MK64FX512 in TEENSY 3.5 + // SRAM (0x1FFF0000 - 0x20020000) (192kb) + // FLASH (0x00000000 - 0x00080000) (512kb) + // + #define START_SRAM_ADDR 0x1FFF0000 + #define END_SRAM_ADDR 0x20020000 + #define START_FLASH_ADDR 0x00000000 + #define END_FLASH_ADDR 0x00080000 + +#elif defined(__MK66FX1M0__) + + // For MK66FX1M0 in TEENSY 3.6 + // SRAM (0x1FFF0000 - 0x20030000) (256kb) + // FLASH (0x00000000 - 0x00140000) (1.25Mb) + // + #define START_SRAM_ADDR 0x1FFF0000 + #define END_SRAM_ADDR 0x20030000 + #define START_FLASH_ADDR 0x00000000 + #define END_FLASH_ADDR 0x00140000 + +#elif defined(__IMXRT1062__) + + // For IMXRT1062 in TEENSY 4.0/4/1 + // ITCM (rwx): ORIGIN = 0x00000000, LENGTH = 512K + // DTCM (rwx): ORIGIN = 0x20000000, LENGTH = 512K + // RAM (rwx): ORIGIN = 0x20200000, LENGTH = 512K + // FLASH (rwx): ORIGIN = 0x60000000, LENGTH = 1984K + // + #define START_SRAM_ADDR 0x00000000 + #define END_SRAM_ADDR 0x20280000 + #define START_FLASH_ADDR 0x60000000 + #define END_FLASH_ADDR 0x601F0000 + +#elif defined(__SAMD51P20A__) + + // For SAMD51x20, valid address ranges are + // SRAM (0x20000000 - 0x20040000) (256kb) + // FLASH (0x00000000 - 0x00100000) (1024kb) + // + #define START_SRAM_ADDR 0x20000000 + #define END_SRAM_ADDR 0x20040000 + #define START_FLASH_ADDR 0x00000000 + #define END_FLASH_ADDR 0x00100000 -#if MB(REMRAM_V1) -// For STM32F765VI in RemRam v1 -// SRAM (0x20000000 - 0x20080000) (512kb) -// FLASH (0x08000000 - 0x08200000) (2048kb) -// -#define START_SRAM_ADDR 0x20000000 -#define END_SRAM_ADDR 0x20080000 -#define START_FLASH_ADDR 0x08000000 -#define END_FLASH_ADDR 0x08200000 -#endif - -#ifdef __MK20DX256__ -// For MK20DX256 in TEENSY 3.1 or TEENSY 3.2 -// SRAM (0x1FFF8000 - 0x20008000) (64kb) -// FLASH (0x00000000 - 0x00040000) (256kb) -// -#define START_SRAM_ADDR 0x1FFF8000 -#define END_SRAM_ADDR 0x20008000 -#define START_FLASH_ADDR 0x00000000 -#define END_FLASH_ADDR 0x00040000 -#endif - -#ifdef __MK64FX512__ -// For MK64FX512 in TEENSY 3.5 -// SRAM (0x1FFF0000 - 0x20020000) (192kb) -// FLASH (0x00000000 - 0x00080000) (512kb) -// -#define START_SRAM_ADDR 0x1FFF0000 -#define END_SRAM_ADDR 0x20020000 -#define START_FLASH_ADDR 0x00000000 -#define END_FLASH_ADDR 0x00080000 -#endif - -#ifdef __MK66FX1M0__ -// For MK66FX1M0 in TEENSY 3.6 -// SRAM (0x1FFF0000 - 0x20030000) (256kb) -// FLASH (0x00000000 - 0x00140000) (1.25Mb) -// -#define START_SRAM_ADDR 0x1FFF0000 -#define END_SRAM_ADDR 0x20030000 -#define START_FLASH_ADDR 0x00000000 -#define END_FLASH_ADDR 0x00140000 -#endif - -#ifdef __SAMD51P20A__ -// For SAMD51x20, valid address ranges are -// SRAM (0x20000000 - 0x20040000) (256kb) -// FLASH (0x00000000 - 0x00100000) (1024kb) -// -#define START_SRAM_ADDR 0x20000000 -#define END_SRAM_ADDR 0x20040000 -#define START_FLASH_ADDR 0x00000000 -#define END_FLASH_ADDR 0x00100000 #endif static bool validate_addr(uint32_t addr) { @@ -177,4 +192,4 @@ bool UnwReadB(const uint32_t a, uint8_t *v) { return true; } -#endif +#endif // __arm__ || __thumb__ diff --git a/Marlin/src/HAL/shared/persistent_store_api.cpp b/Marlin/src/HAL/shared/eeprom_api.cpp similarity index 90% rename from Marlin/src/HAL/shared/persistent_store_api.cpp rename to Marlin/src/HAL/shared/eeprom_api.cpp index 735fa4278b7f..47cfa5a2dbe0 100644 --- a/Marlin/src/HAL/shared/persistent_store_api.cpp +++ b/Marlin/src/HAL/shared/eeprom_api.cpp @@ -17,14 +17,14 @@ * 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 . + * along with this program. If not, see . * */ #include "../../inc/MarlinConfigPre.h" #if EITHER(EEPROM_SETTINGS, SD_FIRMWARE_UPDATE) - #include "persistent_store_api.h" + #include "eeprom_api.h" PersistentStore persistentStore; #endif diff --git a/Marlin/src/HAL/shared/persistent_store_api.h b/Marlin/src/HAL/shared/eeprom_api.h similarity index 75% rename from Marlin/src/HAL/shared/persistent_store_api.h rename to Marlin/src/HAL/shared/eeprom_api.h index d7bee8a5f3da..6445f7a4aae4 100644 --- a/Marlin/src/HAL/shared/persistent_store_api.h +++ b/Marlin/src/HAL/shared/eeprom_api.h @@ -17,7 +17,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -29,20 +29,38 @@ class PersistentStore { public: + + // Total available persistent storage space (in bytes) + static size_t capacity(); + + // Prepare to read or write static bool access_start(); + + // Housecleaning after read or write static bool access_finish(); + + // Write one or more bytes of data and update the CRC + // Return 'true' on write error static bool write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc); + + // Read one or more bytes of data and update the CRC + // Return 'true' on read error static bool read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing=true); - static size_t capacity(); + // Write one or more bytes of data + // Return 'true' on write error static inline bool write_data(const int pos, const uint8_t* value, const size_t size=sizeof(uint8_t)) { int data_pos = pos; uint16_t crc = 0; return write_data(data_pos, value, size, &crc); } + // Write a single byte of data + // Return 'true' on write error static inline bool write_data(const int pos, const uint8_t value) { return write_data(pos, &value); } + // Read one or more bytes of data + // Return 'true' on read error static inline bool read_data(const int pos, uint8_t* value, const size_t size=1) { int data_pos = pos; uint16_t crc = 0; diff --git a/Marlin/src/HAL/shared/eeprom_i2c.cpp b/Marlin/src/HAL/shared/eeprom_i2c.cpp deleted file mode 100644 index 3eb72194acf2..000000000000 --- a/Marlin/src/HAL/shared/eeprom_i2c.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Description: functions for I2C connected external EEPROM. - * Not platform dependent. - * - * TODO: Some platform Arduino libraries define these functions - * so Marlin needs to add a glue layer to prevent the conflict. - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(I2C_EEPROM) - -#include "../HAL.h" -#include - -// ------------------------ -// Private Variables -// ------------------------ - -static uint8_t eeprom_device_address = 0x50; - -// ------------------------ -// Public functions -// ------------------------ - -static void eeprom_init() { - Wire.begin(); -} - -void eeprom_write_byte(uint8_t *pos, unsigned char value) { - unsigned eeprom_address = (unsigned) pos; - - eeprom_init(); - - Wire.beginTransmission(I2C_ADDRESS(eeprom_device_address)); - Wire.write((int)(eeprom_address >> 8)); // MSB - Wire.write((int)(eeprom_address & 0xFF)); // LSB - Wire.write(value); - Wire.endTransmission(); - - // wait for write cycle to complete - // this could be done more efficiently with "acknowledge polling" - delay(5); -} - -// WARNING: address is a page address, 6-bit end will wrap around -// also, data can be maximum of about 30 bytes, because the Wire library has a buffer of 32 bytes -void eeprom_update_block(const void *pos, void* eeprom_address, size_t n) { - eeprom_init(); - - Wire.beginTransmission(I2C_ADDRESS(eeprom_device_address)); - Wire.write((int)((unsigned)eeprom_address >> 8)); // MSB - Wire.write((int)((unsigned)eeprom_address & 0xFF)); // LSB - Wire.endTransmission(); - - uint8_t *ptr = (uint8_t*)pos; - uint8_t flag = 0; - Wire.requestFrom(eeprom_device_address, (byte)n); - for (byte c = 0; c < n && Wire.available(); c++) - flag |= Wire.read() ^ ptr[c]; - - if (flag) { - Wire.beginTransmission(I2C_ADDRESS(eeprom_device_address)); - Wire.write((int)((unsigned)eeprom_address >> 8)); // MSB - Wire.write((int)((unsigned)eeprom_address & 0xFF)); // LSB - Wire.write((uint8_t*)pos, n); - Wire.endTransmission(); - - // wait for write cycle to complete - // this could be done more efficiently with "acknowledge polling" - delay(5); - } -} - -uint8_t eeprom_read_byte(uint8_t *pos) { - unsigned eeprom_address = (unsigned)pos; - - eeprom_init(); - - Wire.beginTransmission(I2C_ADDRESS(eeprom_device_address)); - Wire.write((int)(eeprom_address >> 8)); // MSB - Wire.write((int)(eeprom_address & 0xFF)); // LSB - Wire.endTransmission(); - Wire.requestFrom(eeprom_device_address, (byte)1); - return Wire.available() ? Wire.read() : 0xFF; -} - -// Don't read more than 30..32 bytes at a time! -void eeprom_read_block(void* pos, const void* eeprom_address, size_t n) { - eeprom_init(); - - Wire.beginTransmission(I2C_ADDRESS(eeprom_device_address)); - Wire.write((int)((unsigned)eeprom_address >> 8)); // MSB - Wire.write((int)((unsigned)eeprom_address & 0xFF)); // LSB - Wire.endTransmission(); - Wire.requestFrom(eeprom_device_address, (byte)n); - for (byte c = 0; c < n; c++ ) - if (Wire.available()) *((uint8_t*)pos + c) = Wire.read(); -} - -#endif // I2C_EEPROM diff --git a/Marlin/src/HAL/shared/eeprom_if.h b/Marlin/src/HAL/shared/eeprom_if.h new file mode 100644 index 000000000000..e44da801dfbf --- /dev/null +++ b/Marlin/src/HAL/shared/eeprom_if.h @@ -0,0 +1,29 @@ +/** + * Marlin 3D Printer Firmware + * + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com + * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com + * + * 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 . + * + */ +#pragma once + +// +// EEPROM +// +void eeprom_init(); +void eeprom_write_byte(uint8_t *pos, unsigned char value); +uint8_t eeprom_read_byte(uint8_t *pos); diff --git a/Marlin/src/HAL/shared/eeprom_if_i2c.cpp b/Marlin/src/HAL/shared/eeprom_if_i2c.cpp new file mode 100644 index 000000000000..cc22bf7d986f --- /dev/null +++ b/Marlin/src/HAL/shared/eeprom_if_i2c.cpp @@ -0,0 +1,78 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * Platform-independent Arduino functions for I2C EEPROM. + * Enable USE_SHARED_EEPROM if not supplied by the framework. + */ + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(I2C_EEPROM) + +#include "eeprom_if.h" +#include + +void eeprom_init() { Wire.begin(); } + +#if ENABLED(USE_SHARED_EEPROM) + +#ifndef EEPROM_WRITE_DELAY + #define EEPROM_WRITE_DELAY 5 +#endif +#ifndef EEPROM_DEVICE_ADDRESS + #define EEPROM_DEVICE_ADDRESS 0x50 +#endif + +static constexpr uint8_t eeprom_device_address = I2C_ADDRESS(EEPROM_DEVICE_ADDRESS); + +// ------------------------ +// Public functions +// ------------------------ + +void eeprom_write_byte(uint8_t *pos, unsigned char value) { + const unsigned eeprom_address = (unsigned)pos; + + Wire.beginTransmission(eeprom_device_address); + Wire.write(int(eeprom_address >> 8)); // MSB + Wire.write(int(eeprom_address & 0xFF)); // LSB + Wire.write(value); + Wire.endTransmission(); + + // wait for write cycle to complete + // this could be done more efficiently with "acknowledge polling" + delay(EEPROM_WRITE_DELAY); +} + +uint8_t eeprom_read_byte(uint8_t *pos) { + const unsigned eeprom_address = (unsigned)pos; + + Wire.beginTransmission(eeprom_device_address); + Wire.write(int(eeprom_address >> 8)); // MSB + Wire.write(int(eeprom_address & 0xFF)); // LSB + Wire.endTransmission(); + Wire.requestFrom(eeprom_device_address, (byte)1); + return Wire.available() ? Wire.read() : 0xFF; +} + +#endif // USE_SHARED_EEPROM +#endif // I2C_EEPROM diff --git a/Marlin/src/HAL/shared/eeprom_spi.cpp b/Marlin/src/HAL/shared/eeprom_if_spi.cpp similarity index 57% rename from Marlin/src/HAL/shared/eeprom_spi.cpp rename to Marlin/src/HAL/shared/eeprom_if_spi.cpp index ce7479aedb41..a341fef9de97 100644 --- a/Marlin/src/HAL/shared/eeprom_spi.cpp +++ b/Marlin/src/HAL/shared/eeprom_if_spi.cpp @@ -16,25 +16,33 @@ * 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 . + * along with this program. If not, see . * */ /** - * Description: functions for SPI connected external EEPROM. - * Not platform dependent. + * Platform-independent Arduino functions for SPI EEPROM. + * Enable USE_SHARED_EEPROM if not supplied by the framework. */ #include "../../inc/MarlinConfig.h" #if ENABLED(SPI_EEPROM) -#include "../HAL.h" +#include "eeprom_if.h" + +void eeprom_init() {} + +#if ENABLED(USE_SHARED_EEPROM) #define CMD_WREN 6 // WREN #define CMD_READ 2 // WRITE #define CMD_WRITE 2 // WRITE +#ifndef EEPROM_WRITE_DELAY + #define EEPROM_WRITE_DELAY 7 +#endif + uint8_t eeprom_read_byte(uint8_t* pos) { uint8_t v; uint8_t eeprom_temp[3]; @@ -53,24 +61,6 @@ uint8_t eeprom_read_byte(uint8_t* pos) { return v; } -void eeprom_read_block(void* dest, const void* eeprom_address, size_t n) { - uint8_t eeprom_temp[3]; - - // set read location - // begin transmission from device - eeprom_temp[0] = CMD_READ; - eeprom_temp[1] = ((unsigned)eeprom_address>>8) & 0xFF; // addr High - eeprom_temp[2] = (unsigned)eeprom_address& 0xFF; // addr Low - WRITE(SPI_EEPROM1_CS, HIGH); - WRITE(SPI_EEPROM1_CS, LOW); - spiSend(SPI_CHAN_EEPROM1, eeprom_temp, 3); - - uint8_t *p_dest = (uint8_t *)dest; - while (n--) - *p_dest++ = spiRec(SPI_CHAN_EEPROM1); - WRITE(SPI_EEPROM1_CS, HIGH); -} - void eeprom_write_byte(uint8_t* pos, uint8_t value) { uint8_t eeprom_temp[3]; @@ -90,29 +80,8 @@ void eeprom_write_byte(uint8_t* pos, uint8_t value) { spiSend(SPI_CHAN_EEPROM1, value); WRITE(SPI_EEPROM1_CS, HIGH); - delay(7); // wait for page write to complete -} - -void eeprom_update_block(const void* src, void* eeprom_address, size_t n) { - uint8_t eeprom_temp[3]; - - /*write enable*/ - eeprom_temp[0] = CMD_WREN; - WRITE(SPI_EEPROM1_CS, LOW); - spiSend(SPI_CHAN_EEPROM1, eeprom_temp, 1); - WRITE(SPI_EEPROM1_CS, HIGH); - delay(1); - - /*write addr*/ - eeprom_temp[0] = CMD_WRITE; - eeprom_temp[1] = ((unsigned)eeprom_address>>8) & 0xFF; //addr High - eeprom_temp[2] = (unsigned)eeprom_address & 0xFF; //addr Low - WRITE(SPI_EEPROM1_CS, LOW); - spiSend(SPI_CHAN_EEPROM1, eeprom_temp, 3); - - spiSend(SPI_CHAN_EEPROM1, (const uint8_t*)src, n); - WRITE(SPI_EEPROM1_CS, HIGH); - delay(7); // wait for page write to complete + delay(EEPROM_WRITE_DELAY); // wait for page write to complete } -#endif // SPI_EEPROM +#endif // USE_SHARED_EEPROM +#endif // I2C_EEPROM diff --git a/Marlin/src/HAL/shared/esp_wifi.cpp b/Marlin/src/HAL/shared/esp_wifi.cpp new file mode 100644 index 000000000000..a55f5ca39f91 --- /dev/null +++ b/Marlin/src/HAL/shared/esp_wifi.cpp @@ -0,0 +1,43 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfig.h" +#include "Delay.h" + +void esp_wifi_init(void) { // init ESP01 WIFI module pins + #if PIN_EXISTS(ESP_WIFI_MODULE_GPIO0) + OUT_WRITE(ESP_WIFI_MODULE_GPIO0_PIN, HIGH); + #endif + #if PIN_EXISTS(ESP_WIFI_MODULE_GPIO2) + OUT_WRITE(ESP_WIFI_MODULE_GPIO2_PIN, HIGH); + #endif + #if PIN_EXISTS(ESP_WIFI_MODULE_RESET) + delay(1); // power up delay (0.1mS minimum) + OUT_WRITE(ESP_WIFI_MODULE_RESET_PIN, LOW); + delay(1); + OUT_WRITE(ESP_WIFI_MODULE_RESET_PIN, HIGH); + #endif + #if PIN_EXISTS(ESP_WIFI_MODULE_ENABLE) + delay(1); // delay after reset released (0.1mS minimum) + OUT_WRITE(ESP_WIFI_MODULE_ENABLE_PIN, HIGH); + #endif +} diff --git a/Marlin/src/HAL/HAL_DUE/inc/Conditionals_LCD.h b/Marlin/src/HAL/shared/esp_wifi.h similarity index 89% rename from Marlin/src/HAL/HAL_DUE/inc/Conditionals_LCD.h rename to Marlin/src/HAL/shared/esp_wifi.h index 0285c52ee365..84a50a941dcb 100644 --- a/Marlin/src/HAL/HAL_DUE/inc/Conditionals_LCD.h +++ b/Marlin/src/HAL/shared/esp_wifi.h @@ -16,7 +16,9 @@ * 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 . + * along with this program. If not, see . * */ #pragma once + +void esp_wifi_init(); diff --git a/Marlin/src/HAL/shared/math_32bit.h b/Marlin/src/HAL/shared/math_32bit.h index d93ab9caf6a8..87e9e6406ee4 100644 --- a/Marlin/src/HAL/shared/math_32bit.h +++ b/Marlin/src/HAL/shared/math_32bit.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/HAL/shared/servo.cpp b/Marlin/src/HAL/shared/servo.cpp index d03b80b20097..cfec6f301737 100644 --- a/Marlin/src/HAL/shared/servo.cpp +++ b/Marlin/src/HAL/shared/servo.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -48,7 +48,6 @@ * readMicroseconds() - Get the last-written servo pulse width in microseconds. * attached() - Return true if a servo is attached. * detach() - Stop an attached servo from pulsing its i/o pin. - * */ #include "../../inc/MarlinConfig.h" @@ -68,7 +67,7 @@ uint8_t ServoCount = 0; // the total number of attached static boolean isTimerActive(timer16_Sequence_t timer) { // returns true if any servo is active on this timer - for (uint8_t channel = 0; channel < SERVOS_PER_TIMER; channel++) { + LOOP_L_N(channel, SERVOS_PER_TIMER) { if (SERVO(timer, channel).Pin.isActive) return true; } @@ -150,9 +149,7 @@ void Servo::move(const int value) { if (attach(0) >= 0) { write(value); safe_delay(servo_delay[servoIndex]); - #if ENABLED(DEACTIVATE_SERVOS_AFTER_MOVE) - detach(); - #endif + TERN_(DEACTIVATE_SERVOS_AFTER_MOVE, detach()); } } diff --git a/Marlin/src/HAL/shared/servo.h b/Marlin/src/HAL/shared/servo.h index 4e12720553bb..6d850da851d2 100644 --- a/Marlin/src/HAL/shared/servo.h +++ b/Marlin/src/HAL/shared/servo.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -41,7 +41,6 @@ */ /** - * * A servo is activated by creating an instance of the Servo class passing the desired pin to the attach() method. * The servos are pulsed in the background using the value most recently written using the write() method * @@ -68,19 +67,21 @@ */ #if IS_TEENSY32 - #include "../HAL_TEENSY31_32/Servo.h" + #include "../TEENSY31_32/Servo.h" #elif IS_TEENSY35 || IS_TEENSY36 - #include "../HAL_TEENSY35_36/Servo.h" + #include "../TEENSY35_36/Servo.h" +#elif IS_TEENSY40 || IS_TEENSY41 + #include "../TEENSY40_41/Servo.h" #elif defined(TARGET_LPC1768) - #include "../HAL_LPC1768/Servo.h" + #include "../LPC1768/Servo.h" #elif defined(__STM32F1__) || defined(TARGET_STM32F1) - #include "../HAL_STM32F1/Servo.h" + #include "../STM32F1/Servo.h" #elif defined(STM32GENERIC) && defined(STM32F4) - #include "../HAL_STM32_F4_F7/Servo.h" + #include "../STM32_F4_F7/Servo.h" #elif defined(ARDUINO_ARCH_STM32) - #include "../HAL_STM32/Servo.h" + #include "../STM32/Servo.h" #elif defined(ARDUINO_ARCH_ESP32) - #include "../HAL_ESP32/Servo.h" + #include "../ESP32/Servo.h" #else #include diff --git a/Marlin/src/HAL/shared/servo_private.h b/Marlin/src/HAL/shared/servo_private.h index 63761ce0f40c..d85d8da8ba43 100644 --- a/Marlin/src/HAL/shared/servo_private.h +++ b/Marlin/src/HAL/shared/servo_private.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -44,11 +44,11 @@ // Architecture specific include #ifdef __AVR__ - #include "../HAL_AVR/ServoTimers.h" + #include "../AVR/ServoTimers.h" #elif defined(ARDUINO_ARCH_SAM) - #include "../HAL_DUE/ServoTimers.h" + #include "../DUE/ServoTimers.h" #elif defined(__SAMD51__) - #include "../HAL_SAMD51/ServoTimers.h" + #include "../SAMD51/ServoTimers.h" #else #error "This library only supports boards with an AVR, SAM3X or SAMD51 processor." #endif diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp index 5a527482ce09..3a20cf3ee330 100644 --- a/Marlin/src/MarlinCore.cpp +++ b/Marlin/src/MarlinCore.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -30,35 +30,59 @@ #include "MarlinCore.h" +#if ENABLED(MARLIN_DEV_MODE) + #warning "WARNING! Disable MARLIN_DEV_MODE for the final build!" +#endif + +#include "HAL/shared/Delay.h" +#include "HAL/shared/esp_wifi.h" + +#ifdef ARDUINO + #include +#endif +#include + #include "core/utility.h" -#include "lcd/ultralcd.h" #include "module/motion.h" #include "module/planner.h" -#include "module/stepper.h" #include "module/endstops.h" -#include "module/probe.h" #include "module/temperature.h" -#include "sd/cardreader.h" -#include "module/configuration_store.h" +#include "module/settings.h" #include "module/printcounter.h" // PrintCounter or Stopwatch -#include "feature/closedloop.h" - -#include "HAL/shared/Delay.h" +#include "module/stepper.h" #include "module/stepper/indirection.h" -#ifdef ARDUINO - #include -#endif -#include -#include "libs/nozzle.h" - #include "gcode/gcode.h" #include "gcode/parser.h" #include "gcode/queue.h" -#if ENABLED(TOUCH_BUTTONS) - #include "feature/touch/xpt2046.h" +#include "sd/cardreader.h" + +#include "lcd/ultralcd.h" +#if HAS_TOUCH_XPT2046 + #include "lcd/touch/touch_buttons.h" +#endif + +#if HAS_TFT_LVGL_UI + #include "lcd/extui/lib/mks_ui/tft_lvgl_configuration.h" + #include "lcd/extui/lib/mks_ui/draw_ui.h" + #include "lcd/extui/lib/mks_ui/mks_hardware_test.h" + #include +#endif + +#if ENABLED(DWIN_CREALITY_LCD) + #include "lcd/dwin/e3v2/dwin.h" + #include "lcd/dwin/dwin_lcd.h" + #include "lcd/dwin/e3v2/rotary_encoder.h" +#endif + +#if ENABLED(IIC_BL24CXX_EEPROM) + #include "libs/BL24CXX.h" +#endif + +#if ENABLED(DIRECT_STEPPING) + #include "feature/direct_stepping.h" #endif #if ENABLED(HOST_ACTION_COMMANDS) @@ -69,7 +93,11 @@ #include "libs/buzzer.h" #endif -#if ENABLED(DIGIPOT_I2C) +#if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER) + #include "feature/closedloop.h" +#endif + +#if HAS_MOTOR_CURRENT_I2C #include "feature/digipot/digipot.h" #endif @@ -78,7 +106,7 @@ #endif #if ENABLED(MAX7219_DEBUG) - #include "feature/Max7219_Debug_LEDs.h" + #include "feature/max7219.h" #endif #if HAS_COLOR_LEDS @@ -97,7 +125,7 @@ #include "module/servo.h" #endif -#if ENABLED(DAC_STEPPER_CURRENT) +#if ENABLED(HAS_MOTOR_CURRENT_DAC) #include "feature/dac/stepper_dac.h" #endif @@ -107,10 +135,10 @@ #endif #if ENABLED(I2C_POSITION_ENCODERS) - #include "feature/I2CPositionEncoder.h" + #include "feature/encoder_i2c.h" #endif -#if HAS_TRINAMIC && DISABLED(PSU_DEFAULT_OFF) +#if HAS_TRINAMIC_CONFIG && DISABLED(PSU_DEFAULT_OFF) #include "feature/tmc_util.h" #endif @@ -142,7 +170,7 @@ #endif #if ENABLED(POWER_LOSS_RECOVERY) - #include "feature/power_loss_recovery.h" + #include "feature/powerloss.h" #endif #if ENABLED(CANCEL_OBJECTS) @@ -153,11 +181,19 @@ #include "feature/runout.h" #endif +#if HAS_Z_SERVO_PROBE + #include "module/probe.h" +#endif + +#if ENABLED(HOTEND_IDLE_TIMEOUT) + #include "feature/hotend_idle.h" +#endif + #if ENABLED(TEMP_STAT_LEDS) #include "feature/leds/tempstat.h" #endif -#if HAS_CASE_LIGHT +#if ENABLED(CASE_LIGHT_ENABLE) #include "feature/caselight.h" #endif @@ -165,7 +201,7 @@ #include "feature/fanmux.h" #endif -#if DO_SWITCH_EXTRUDER || ANY(SWITCHING_NOZZLE, PARKING_EXTRUDER, MAGNETIC_PARKING_EXTRUDER, ELECTROMAGNETIC_SWITCHING_TOOLHEAD) +#if DO_SWITCH_EXTRUDER || ANY(SWITCHING_NOZZLE, PARKING_EXTRUDER, MAGNETIC_PARKING_EXTRUDER, ELECTROMAGNETIC_SWITCHING_TOOLHEAD, SWITCHING_TOOLHEAD) #include "module/tool_change.h" #endif @@ -174,27 +210,31 @@ #endif #if ENABLED(PRUSA_MMU2) - #include "feature/prusa_MMU2/mmu2.h" + #include "feature/mmu2/mmu2.h" #endif #if HAS_L64XX #include "libs/L64XX/L64XX_Marlin.h" #endif -const char NUL_STR[] PROGMEM = "", - M112_KILL_STR[] PROGMEM = "M112 Shutdown", - G28_STR[] PROGMEM = "G28", - M21_STR[] PROGMEM = "M21", - M23_STR[] PROGMEM = "M23 %s", - M24_STR[] PROGMEM = "M24", - SP_P_STR[] PROGMEM = " P", - SP_T_STR[] PROGMEM = " T", - SP_X_STR[] PROGMEM = " X", - SP_Y_STR[] PROGMEM = " Y", - SP_Z_STR[] PROGMEM = " Z", - SP_E_STR[] PROGMEM = " E"; - -bool Running = true; +#if ENABLED(PASSWORD_FEATURE) + #include "feature/password/password.h" +#endif + +PGMSTR(NUL_STR, ""); +PGMSTR(M112_KILL_STR, "M112 Shutdown"); +PGMSTR(G28_STR, "G28"); +PGMSTR(M21_STR, "M21"); +PGMSTR(M23_STR, "M23 %s"); +PGMSTR(M24_STR, "M24"); +PGMSTR(SP_P_STR, " P"); PGMSTR(SP_T_STR, " T"); +PGMSTR(X_STR, "X"); PGMSTR(Y_STR, "Y"); PGMSTR(Z_STR, "Z"); PGMSTR(E_STR, "E"); +PGMSTR(X_LBL, "X:"); PGMSTR(Y_LBL, "Y:"); PGMSTR(Z_LBL, "Z:"); PGMSTR(E_LBL, "E:"); +PGMSTR(SP_A_STR, " A"); PGMSTR(SP_B_STR, " B"); PGMSTR(SP_C_STR, " C"); +PGMSTR(SP_X_STR, " X"); PGMSTR(SP_Y_STR, " Y"); PGMSTR(SP_Z_STR, " Z"); PGMSTR(SP_E_STR, " E"); +PGMSTR(SP_X_LBL, " X:"); PGMSTR(SP_Y_LBL, " Y:"); PGMSTR(SP_Z_LBL, " Z:"); PGMSTR(SP_E_LBL, " E:"); + +MarlinState marlin_state = MF_INITIALIZING; // For M109 and M190, this flag may be cleared (by M108) to exit the wait loop bool wait_for_heatup = true; @@ -202,11 +242,18 @@ bool wait_for_heatup = true; // For M0/M1, this flag may be cleared (by M108) to exit the wait-for-user loop #if HAS_RESUME_CONTINUE bool wait_for_user; // = false; -#endif -// Inactivity shutdown -millis_t max_inactive_time, // = 0 - stepper_inactive_time = (DEFAULT_STEPPER_DEACTIVE_TIME) * 1000UL; + void wait_for_user_response(millis_t ms/*=0*/, const bool no_sleep/*=false*/) { + TERN(ADVANCED_PAUSE_FEATURE,,UNUSED(no_sleep)); + KEEPALIVE_STATE(PAUSED_FOR_USER); + wait_for_user = true; + if (ms) ms += millis(); // expire time + while (wait_for_user && !(ms && ELAPSED(millis(), ms))) + idle(TERN_(ADVANCED_PAUSE_FEATURE, no_sleep)); + wait_for_user = false; + } + +#endif #if PIN_EXISTS(CHDK) extern millis_t chdk_timeout; @@ -224,7 +271,11 @@ millis_t max_inactive_time, // = 0 void setup_killpin() { #if HAS_KILL - SET_INPUT_PULLUP(KILL_PIN); + #if KILL_PIN_STATE + SET_INPUT_PULLDOWN(KILL_PIN); + #else + SET_INPUT_PULLUP(KILL_PIN); + #endif #endif } @@ -233,11 +284,8 @@ void setup_powerhold() { OUT_WRITE(SUICIDE_PIN, !SUICIDE_PIN_INVERTING); #endif #if ENABLED(PSU_CONTROL) - #if ENABLED(PSU_DEFAULT_OFF) - powersupply_on = true; PSU_OFF(); - #else - powersupply_on = false; PSU_ON(); - #endif + powersupply_on = ENABLED(PSU_DEFAULT_OFF); + if (ENABLED(PSU_DEFAULT_OFF)) PSU_OFF(); else PSU_ON(); #endif } @@ -267,9 +315,12 @@ void setup_powerhold() { #include "pins/sensitive_pins.h" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnarrowing" + bool pin_is_protected(const pin_t pin) { static const pin_t sensitive_pins[] PROGMEM = SENSITIVE_PINS; - for (uint8_t i = 0; i < COUNT(sensitive_pins); i++) { + LOOP_L_N(i, COUNT(sensitive_pins)) { pin_t sensitive_pin; memcpy_P(&sensitive_pin, &sensitive_pins[i], sizeof(pin_t)); if (pin == sensitive_pin) return true; @@ -277,6 +328,8 @@ bool pin_is_protected(const pin_t pin) { return false; } +#pragma GCC diagnostic pop + void protected_pin_err() { SERIAL_ERROR_MSG(STR_ERR_PROTECTED_PIN); } @@ -294,9 +347,7 @@ void enable_e_steppers() { } void enable_all_steppers() { - #if ENABLED(AUTO_POWER_CONTROL) - powerManager.power_on(); - #endif + TERN_(AUTO_POWER_CONTROL, powerManager.power_on()); ENABLE_AXIS_X(); ENABLE_AXIS_Y(); ENABLE_AXIS_Z(); @@ -340,9 +391,7 @@ void disable_all_steppers() { } void event_probe_recover() { - #if ENABLED(HOST_PROMPT_SUPPORT) - host_prompt_do(PROMPT_INFO, PSTR("G29 Retrying"), DISMISS_STR); - #endif + TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_INFO, PSTR("G29 Retrying"), DISMISS_STR)); #ifdef ACTION_ON_G29_RECOVER host_action(PSTR(ACTION_ON_G29_RECOVER)); #endif @@ -359,6 +408,13 @@ void disable_all_steppers() { constexpr bool did_pause_print = false; #endif +/** + * A Print Job exists when the timer is running or SD printing + */ +bool printJobOngoing() { + return print_job_timer.isRunning() || IS_SD_PRINTING(); +} + /** * Printing is active when the print job timer is running */ @@ -375,12 +431,8 @@ bool printingIsPaused() { void startOrResumeJob() { if (!printingIsPaused()) { - #if ENABLED(CANCEL_OBJECTS) - cancelable.reset(); - #endif - #if ENABLED(LCD_SHOW_E_TOTAL) - e_move_accumulator = 0; - #endif + TERN_(CANCEL_OBJECTS, cancelable.reset()); + TERN_(LCD_SHOW_E_TOTAL, e_move_accumulator = 0); #if BOTH(LCD_SET_PROGRESS_MANUALLY, USE_M73_REMAINING_TIME) ui.reset_remaining_time(); #endif @@ -391,80 +443,38 @@ void startOrResumeJob() { #if ENABLED(SDSUPPORT) inline void abortSDPrinting() { - card.endFilePrint( - #if SD_RESORT - true - #endif - ); + card.endFilePrint(TERN_(SD_RESORT, true)); queue.clear(); quickstop_stepper(); print_job_timer.stop(); #if DISABLED(SD_ABORT_NO_COOLDOWN) thermalManager.disable_all_heaters(); #endif - thermalManager.zero_fan_speeds(); - wait_for_heatup = false; - #if ENABLED(POWER_LOSS_RECOVERY) - recovery.purge(); + #if !HAS_CUTTER + thermalManager.zero_fan_speeds(); + #else + cutter.kill(); // Full cutter shutdown including ISR control #endif - #ifdef EVENT_GCODE_SD_STOP - queue.inject_P(PSTR(EVENT_GCODE_SD_STOP)); + wait_for_heatup = false; + TERN_(POWER_LOSS_RECOVERY, recovery.purge()); + #ifdef EVENT_GCODE_SD_ABORT + queue.inject_P(PSTR(EVENT_GCODE_SD_ABORT)); #endif + + TERN_(PASSWORD_AFTER_SD_PRINT_ABORT, password.lock_machine()); } inline void finishSDPrinting() { - bool did_state = true; - switch (card.sdprinting_done_state) { - - #if HAS_RESUME_CONTINUE // Display "Click to Continue..." - case 1: - did_state = queue.enqueue_P(PSTR("M0Q1S" - #if HAS_LCD_MENU - "1800" // ...for 30 minutes with LCD - #else - "60" // ...for 1 minute with no LCD - #endif - )); - break; - #endif - - case 2: print_job_timer.stop(); break; - - case 3: - did_state = print_job_timer.duration() < 60 || queue.enqueue_P(PSTR("M31")); - break; - - case 4: - #if ENABLED(POWER_LOSS_RECOVERY) - recovery.purge(); - #endif - - #if ENABLED(SD_FINISHED_STEPPERRELEASE) && defined(SD_FINISHED_RELEASECOMMAND) - planner.finish_and_disable(); - #endif - - #if ENABLED(LCD_SET_PROGRESS_MANUALLY) - ui.set_progress_done(); - #endif - - #if ENABLED(SD_REPRINT_LAST_SELECTED_FILE) - ui.reselect_last_file(); - #endif - - SERIAL_ECHOLNPGM(STR_FILE_PRINTED); - - default: - did_state = false; - card.sdprinting_done_state = 0; + if (queue.enqueue_one_P(PSTR("M1001"))) { + marlin_state = MF_RUNNING; + TERN_(PASSWORD_AFTER_SD_PRINT_END, password.lock_machine()); } - if (did_state) ++card.sdprinting_done_state; } #endif // SDSUPPORT /** * Minimal management of Marlin's core activities: - * - Check for Filament Runout * - Keep the command buffer full * - Check for maximum inactive time between commands * - Check for maximum inactive time between stepper commands @@ -475,55 +485,46 @@ void startOrResumeJob() { * - Check if an idle but hot extruder needs filament extruded (EXTRUDER_RUNOUT_PREVENT) * - Pulse FET_SAFETY_PIN if it exists */ - inline void manage_inactivity(const bool ignore_stepper_queue=false) { - #if HAS_FILAMENT_SENSOR - runout.run(); - #endif - if (queue.length < BUFSIZE) queue.get_available_commands(); const millis_t ms = millis(); - if (max_inactive_time && ELAPSED(ms, gcode.previous_move_ms + max_inactive_time)) { + // Prevent steppers timing-out in the middle of M600 + // unless PAUSE_PARK_NO_STEPPER_TIMEOUT is disabled + const bool parked_or_ignoring = ignore_stepper_queue || + (BOTH(ADVANCED_PAUSE_FEATURE, PAUSE_PARK_NO_STEPPER_TIMEOUT) && did_pause_print); + + // Reset both the M18/M84 activity timeout and the M85 max 'kill' timeout + if (parked_or_ignoring) gcode.reset_stepper_timeout(ms); + + if (gcode.stepper_max_timed_out(ms)) { SERIAL_ERROR_START(); SERIAL_ECHOLNPAIR(STR_KILL_INACTIVE_TIME, parser.command_ptr); kill(); } - // Prevent steppers timing-out in the middle of M600 - #if BOTH(ADVANCED_PAUSE_FEATURE, PAUSE_PARK_NO_STEPPER_TIMEOUT) - #define MOVE_AWAY_TEST !did_pause_print - #else - #define MOVE_AWAY_TEST true - #endif + // M18 / M94 : Handle steppers inactive time timeout + if (gcode.stepper_inactive_time) { - if (stepper_inactive_time) { static bool already_shutdown_steppers; // = false + + // Any moves in the planner? Resets both the M18/M84 + // activity timeout and the M85 max 'kill' timeout if (planner.has_blocks_queued()) - gcode.reset_stepper_timeout(); - else if (MOVE_AWAY_TEST && !ignore_stepper_queue && ELAPSED(ms, gcode.previous_move_ms + stepper_inactive_time)) { + gcode.reset_stepper_timeout(ms); + else if (!parked_or_ignoring && gcode.stepper_inactive_timeout()) { if (!already_shutdown_steppers) { already_shutdown_steppers = true; // L6470 SPI will consume 99% of free time without this - #if ENABLED(DISABLE_INACTIVE_X) - DISABLE_AXIS_X(); - #endif - #if ENABLED(DISABLE_INACTIVE_Y) - DISABLE_AXIS_Y(); - #endif - #if ENABLED(DISABLE_INACTIVE_Z) - DISABLE_AXIS_Z(); - #endif - #if ENABLED(DISABLE_INACTIVE_E) - disable_e_steppers(); - #endif - #if HAS_LCD_MENU && ENABLED(AUTO_BED_LEVELING_UBL) - if (ubl.lcd_map_control) { - ubl.lcd_map_control = false; - ui.defer_status_screen(false); - } - #endif + + // Individual axes will be disabled if configured + if (ENABLED(DISABLE_INACTIVE_X)) DISABLE_AXIS_X(); + if (ENABLED(DISABLE_INACTIVE_Y)) DISABLE_AXIS_Y(); + if (ENABLED(DISABLE_INACTIVE_Z)) DISABLE_AXIS_Z(); + if (ENABLED(DISABLE_INACTIVE_E)) disable_e_steppers(); + + TERN_(AUTO_BED_LEVELING_UBL, ubl.steppers_were_disabled()); } } else @@ -544,7 +545,7 @@ inline void manage_inactivity(const bool ignore_stepper_queue=false) { // ------------------------------------------------------------------------------- static int killCount = 0; // make the inactivity button a bit less responsive const int KILL_DELAY = 750; - if (!READ(KILL_PIN)) + if (kill_state()) killCount++; else if (killCount > 0) killCount--; @@ -572,17 +573,15 @@ inline void manage_inactivity(const bool ignore_stepper_queue=false) { } #endif - #if ENABLED(USE_CONTROLLER_FAN) - controllerfan_update(); // Check if fan should be turned on to cool stepper drivers down - #endif + TERN_(USE_CONTROLLER_FAN, controllerFan.update()); // Check if fan should be turned on to cool stepper drivers down - #if ENABLED(AUTO_POWER_CONTROL) - powerManager.check(); - #endif + TERN_(AUTO_POWER_CONTROL, powerManager.check()); + + TERN_(HOTEND_IDLE_TIMEOUT, hotend_idle.check()); #if ENABLED(EXTRUDER_RUNOUT_PREVENT) if (thermalManager.degHotend(active_extruder) > EXTRUDER_RUNOUT_MINTEMP - && ELAPSED(ms, gcode.previous_move_ms + (EXTRUDER_RUNOUT_SECONDS) * 1000UL) + && ELAPSED(ms, gcode.previous_move_ms + SEC_TO_MS(EXTRUDER_RUNOUT_SECONDS)) && !planner.has_blocks_queued() ) { #if ENABLED(SWITCHING_EXTRUDER) @@ -632,7 +631,7 @@ inline void manage_inactivity(const bool ignore_stepper_queue=false) { } #endif // !SWITCHING_EXTRUDER - gcode.reset_stepper_timeout(); + gcode.reset_stepper_timeout(ms); } #endif // EXTRUDER_RUNOUT_PREVENT @@ -642,21 +641,15 @@ inline void manage_inactivity(const bool ignore_stepper_queue=false) { // travel moves have been received so enact them delayed_move_time = 0xFFFFFFFFUL; // force moves to be done destination = current_position; - prepare_move_to_destination(); + prepare_line_to_destination(); } #endif - #if ENABLED(TEMP_STAT_LEDS) - handle_status_leds(); - #endif + TERN_(TEMP_STAT_LEDS, handle_status_leds()); - #if ENABLED(MONITOR_DRIVER_STATUS) - monitor_tmc_drivers(); - #endif + TERN_(MONITOR_DRIVER_STATUS, monitor_tmc_drivers()); - #if ENABLED(MONITOR_L6470_DRIVER_STATUS) - L64xxManager.monitor_driver(); - #endif + TERN_(MONITOR_L6470_DRIVER_STATUS, L64xxManager.monitor_driver()); // Limit check_axes_activity frequency to 10Hz static millis_t next_check_axes_ms = 0; @@ -677,54 +670,81 @@ inline void manage_inactivity(const bool ignore_stepper_queue=false) { } /** - * Standard idle routine keeps the machine alive + * Standard idle routine keeps the machine alive: + * - Core Marlin activities + * - Manage heaters (and Watchdog) + * - Max7219 heartbeat, animation, etc. + * + * Only after setup() is complete: + * - Handle filament runout sensors + * - Run HAL idle tasks + * - Handle Power-Loss Recovery + * - Run StallGuard endstop checks + * - Handle SD Card insert / remove + * - Handle USB Flash Drive insert / remove + * - Announce Host Keepalive state (if any) + * - Update the Print Job Timer state + * - Update the Beeper queue + * - Read Buttons and Update the LCD + * - Run i2c Position Encoders + * - Auto-report Temperatures / SD Status + * - Update the Průša MMU2 + * - Handle Joystick jogging */ -void idle( - #if ENABLED(ADVANCED_PAUSE_FEATURE) - bool no_stepper_sleep/*=false*/ +void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep/*=false*/)) { + + // Core Marlin activities + manage_inactivity(TERN_(ADVANCED_PAUSE_FEATURE, no_stepper_sleep)); + + // Manage Heaters (and Watchdog) + thermalManager.manage_heater(); + + // Max7219 heartbeat, animation, etc + TERN_(MAX7219_DEBUG, max7219.idle_tasks()); + + // Return if setup() isn't completed + if (marlin_state == MF_INITIALIZING) return; + + // Handle filament runout sensors + TERN_(HAS_FILAMENT_SENSOR, runout.run()); + + // Run HAL idle tasks + #ifdef HAL_IDLETASK + HAL_idletask(); #endif -) { + + // Handle Power-Loss Recovery #if ENABLED(POWER_LOSS_RECOVERY) && PIN_EXISTS(POWER_LOSS) - recovery.outage(); + if (printJobOngoing()) recovery.outage(); #endif + // Run StallGuard endstop checks #if ENABLED(SPI_ENDSTOPS) if (endstops.tmc_spi_homing.any - #if ENABLED(IMPROVE_HOMING_RELIABILITY) - && ELAPSED(millis(), sg_guard_period) - #endif - ) { - for (uint8_t i = 4; i--;) // Read SGT 4 times per idle loop + && TERN1(IMPROVE_HOMING_RELIABILITY, ELAPSED(millis(), sg_guard_period)) + ) LOOP_L_N(i, 4) // Read SGT 4 times per idle loop if (endstops.tmc_spi_homing_check()) break; - } - #endif - - #if ENABLED(MAX7219_DEBUG) - max7219.idle_tasks(); #endif - ui.update(); + // Handle SD Card insert / remove + TERN_(SDSUPPORT, card.manage_media()); - #if ENABLED(HOST_KEEPALIVE_FEATURE) - gcode.host_keepalive(); - #endif + // Handle USB Flash Drive insert / remove + TERN_(USB_FLASH_DRIVE_SUPPORT, Sd2Card::idle()); - manage_inactivity( - #if ENABLED(ADVANCED_PAUSE_FEATURE) - no_stepper_sleep - #endif - ); + // Announce Host Keepalive state (if any) + TERN_(HOST_KEEPALIVE_FEATURE, gcode.host_keepalive()); - thermalManager.manage_heater(); + // Update the Print Job Timer state + TERN_(PRINTCOUNTER, print_job_timer.tick()); - #if ENABLED(PRINTCOUNTER) - print_job_timer.tick(); - #endif + // Update the Beeper queue + TERN_(USE_BEEPER, buzzer.tick()); - #if USE_BEEPER - buzzer.tick(); - #endif + // Handle UI input / draw events + TERN(DWIN_CREALITY_LCD, DWIN_Update(), ui.update()); + // Run i2c Position Encoders #if ENABLED(I2C_POSITION_ENCODERS) static millis_t i2cpem_next_update_ms; if (planner.has_blocks_queued()) { @@ -736,31 +756,25 @@ void idle( } #endif - #ifdef HAL_IDLETASK - HAL_idletask(); - #endif - + // Auto-report Temperatures / SD Status #if HAS_AUTO_REPORTING if (!gcode.autoreport_paused) { - #if ENABLED(AUTO_REPORT_TEMPERATURES) - thermalManager.auto_report_temperatures(); - #endif - #if ENABLED(AUTO_REPORT_SD_STATUS) - card.auto_report_sd_status(); - #endif + TERN_(AUTO_REPORT_TEMPERATURES, thermalManager.auto_report_temperatures()); + TERN_(AUTO_REPORT_SD_STATUS, card.auto_report_sd_status()); } #endif - #if ENABLED(USB_FLASH_DRIVE_SUPPORT) - Sd2Card::idle(); - #endif + // Update the Průša MMU2 + TERN_(PRUSA_MMU2, mmu2.mmu_loop()); - #if ENABLED(PRUSA_MMU2) - mmu2.mmu_loop(); - #endif + // Handle Joystick jogging + TERN_(POLL_JOG, joystick.inject_jog_moves()); + + // Direct Stepping + TERN_(DIRECT_STEPPING, page_manager.write_responses()); - #if ENABLED(POLL_JOG) - joystick.inject_jog_moves(); + #if HAS_TFT_LVGL_UI + LV_TASK_HANDLER(); #endif } @@ -771,6 +785,8 @@ void idle( void kill(PGM_P const lcd_error/*=nullptr*/, PGM_P const lcd_component/*=nullptr*/, const bool steppers_off/*=false*/) { thermalManager.disable_all_heaters(); + TERN_(HAS_CUTTER, cutter.kill()); // Full cutter shutdown including ISR control + SERIAL_ERROR_MSG(STR_ERR_KILLED); #if HAS_DISPLAY @@ -780,6 +796,10 @@ void kill(PGM_P const lcd_error/*=nullptr*/, PGM_P const lcd_component/*=nullptr UNUSED(lcd_component); #endif + #if HAS_TFT_LVGL_UI + lv_draw_error_message(lcd_error); + #endif + #ifdef ACTION_ON_KILL host_action_kill(); #endif @@ -800,33 +820,31 @@ void minkill(const bool steppers_off/*=false*/) { // Reiterate heaters off thermalManager.disable_all_heaters(); + TERN_(HAS_CUTTER, cutter.kill()); // Reiterate cutter shutdown + // Power off all steppers (for M112) or just the E steppers steppers_off ? disable_all_steppers() : disable_e_steppers(); - #if ENABLED(PSU_CONTROL) - PSU_OFF(); - #endif + TERN_(PSU_CONTROL, PSU_OFF()); - #if HAS_SUICIDE - suicide(); - #endif + TERN_(HAS_SUICIDE, suicide()); #if HAS_KILL // Wait for kill to be released - while (!READ(KILL_PIN)) watchdog_refresh(); + while (kill_state()) watchdog_refresh(); // Wait for kill to be pressed - while (READ(KILL_PIN)) watchdog_refresh(); + while (!kill_state()) watchdog_refresh(); - void (*resetFunc)() = 0; // Declare resetFunc() at address 0 + void (*resetFunc)() = 0; // Declare resetFunc() at address 0 resetFunc(); // Jump to address 0 - #else // !HAS_KILL + #else - for (;;) watchdog_refresh(); // Wait for reset + for (;;) watchdog_refresh(); // Wait for reset - #endif // !HAS_KILL + #endif } /** @@ -845,10 +863,61 @@ void stop() { SERIAL_ERROR_MSG(STR_ERR_STOPPED); LCD_MESSAGEPGM(MSG_STOPPED); safe_delay(350); // allow enough time for messages to get out before stopping - Running = false; + marlin_state = MF_STOPPED; } } +inline void tmc_standby_setup() { + #if PIN_EXISTS(X_STDBY) + SET_INPUT_PULLDOWN(X_STDBY_PIN); + #endif + #if PIN_EXISTS(X2_STDBY) + SET_INPUT_PULLDOWN(X2_STDBY_PIN); + #endif + #if PIN_EXISTS(Y_STDBY) + SET_INPUT_PULLDOWN(Y_STDBY_PIN); + #endif + #if PIN_EXISTS(Y2_STDBY) + SET_INPUT_PULLDOWN(Y2_STDBY_PIN); + #endif + #if PIN_EXISTS(Z_STDBY) + SET_INPUT_PULLDOWN(Z_STDBY_PIN); + #endif + #if PIN_EXISTS(Z2_STDBY) + SET_INPUT_PULLDOWN(Z2_STDBY_PIN); + #endif + #if PIN_EXISTS(Z3_STDBY) + SET_INPUT_PULLDOWN(Z3_STDBY_PIN); + #endif + #if PIN_EXISTS(Z4_STDBY) + SET_INPUT_PULLDOWN(Z4_STDBY_PIN); + #endif + #if PIN_EXISTS(E0_STDBY) + SET_INPUT_PULLDOWN(E0_STDBY_PIN); + #endif + #if PIN_EXISTS(E1_STDBY) + SET_INPUT_PULLDOWN(E1_STDBY_PIN); + #endif + #if PIN_EXISTS(E2_STDBY) + SET_INPUT_PULLDOWN(E2_STDBY_PIN); + #endif + #if PIN_EXISTS(E3_STDBY) + SET_INPUT_PULLDOWN(E3_STDBY_PIN); + #endif + #if PIN_EXISTS(E4_STDBY) + SET_INPUT_PULLDOWN(E4_STDBY_PIN); + #endif + #if PIN_EXISTS(E5_STDBY) + SET_INPUT_PULLDOWN(E5_STDBY_PIN); + #endif + #if PIN_EXISTS(E6_STDBY) + SET_INPUT_PULLDOWN(E6_STDBY_PIN); + #endif + #if PIN_EXISTS(E7_STDBY) + SET_INPUT_PULLDOWN(E7_STDBY_PIN); + #endif +} + /** * Marlin entry-point: Set up before the program loop * - Set up the kill pin, filament runout, power hold @@ -866,157 +935,183 @@ void stop() { * • Digipot I2C * • Z probe sled * • status LEDs + * • Max7219 */ void setup() { - HAL_init(); + tmc_standby_setup(); // TMC Low Power Standby pins must be set early or they're not usable - #if HAS_L64XX - L64xxManager.init(); // Set up SPI, init drivers - #endif - - #if ENABLED(SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD) - OUT_WRITE(SMART_EFFECTOR_MOD_PIN, LOW); // Put Smart Effector into NORMAL mode - #endif - - #if ENABLED(MAX7219_DEBUG) - max7219.init(); + #if ENABLED(MARLIN_DEV_MODE) + auto log_current_ms = [&](PGM_P const msg) { + SERIAL_ECHO_START(); + SERIAL_CHAR('['); SERIAL_ECHO(millis()); SERIAL_ECHOPGM("] "); + serialprintPGM(msg); + SERIAL_EOL(); + }; + #define SETUP_LOG(M) log_current_ms(PSTR(M)) + #else + #define SETUP_LOG(...) NOOP #endif + #define SETUP_RUN(C) do{ SETUP_LOG(STRINGIFY(C)); C; }while(0) - #if ENABLED(DISABLE_DEBUG) + #if EITHER(DISABLE_DEBUG, DISABLE_JTAG) // Disable any hardware debug to free up pins for IO - #ifdef JTAGSWD_DISABLE + #if ENABLED(DISABLE_DEBUG) && defined(JTAGSWD_DISABLE) JTAGSWD_DISABLE(); #elif defined(JTAG_DISABLE) JTAG_DISABLE(); #else - #error "DISABLE_DEBUG is not supported for the selected MCU/Board" - #endif - #elif ENABLED(DISABLE_JTAG) - // Disable JTAG to free up pins for IO - #ifdef JTAG_DISABLE - JTAG_DISABLE(); - #else - #error "DISABLE_JTAG is not supported for the selected MCU/Board" + #error "DISABLE_(DEBUG|JTAG) is not supported for the selected MCU/Board." #endif #endif + MYSERIAL0.begin(BAUDRATE); + uint32_t serial_connect_timeout = millis() + 1000UL; + while (!MYSERIAL0 && PENDING(millis(), serial_connect_timeout)) { /*nada*/ } + #if HAS_MULTI_SERIAL + MYSERIAL1.begin(BAUDRATE); + serial_connect_timeout = millis() + 1000UL; + while (!MYSERIAL1 && PENDING(millis(), serial_connect_timeout)) { /*nada*/ } + #endif + SERIAL_ECHO_MSG("start"); + + #if BOTH(HAS_TFT_LVGL_UI, USE_WIFI_FUNCTION) + mks_esp_wifi_init(); + WIFISERIAL.begin(WIFI_BAUDRATE); + serial_connect_timeout = millis() + 1000UL; + while (/*!WIFISERIAL && */PENDING(millis(), serial_connect_timeout)) { /*nada*/ } + #endif + + SETUP_RUN(HAL_init()); + + #if HAS_L64XX + SETUP_RUN(L64xxManager.init()); // Set up SPI, init drivers + #endif + + #if ENABLED(DUET_SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD) + OUT_WRITE(SMART_EFFECTOR_MOD_PIN, LOW); // Put Smart Effector into NORMAL mode + #endif + #if HAS_FILAMENT_SENSOR - runout.setup(); + SETUP_RUN(runout.setup()); #endif #if ENABLED(POWER_LOSS_RECOVERY) - recovery.setup(); + SETUP_RUN(recovery.setup()); #endif - setup_killpin(); + SETUP_RUN(setup_killpin()); #if HAS_TMC220x - tmc_serial_begin(); + SETUP_RUN(tmc_serial_begin()); #endif - setup_powerhold(); + SETUP_RUN(setup_powerhold()); #if HAS_STEPPER_RESET - disableStepperDrivers(); + SETUP_RUN(disableStepperDrivers()); #endif - #if NUM_SERIAL > 0 - MYSERIAL0.begin(BAUDRATE); - uint32_t serial_connect_timeout = millis() + 1000UL; - while (!MYSERIAL0 && PENDING(millis(), serial_connect_timeout)) { /*nada*/ } - #if NUM_SERIAL > 1 - MYSERIAL1.begin(BAUDRATE); - serial_connect_timeout = millis() + 1000UL; - while (!MYSERIAL1 && PENDING(millis(), serial_connect_timeout)) { /*nada*/ } - #endif - #endif - - SERIAL_ECHOLNPGM("start"); - SERIAL_ECHO_START(); - #if HAS_TMC_SPI #if DISABLED(TMC_USE_SW_SPI) - SPI.begin(); + SETUP_RUN(SPI.begin()); #endif - tmc_init_cs_pins(); + SETUP_RUN(tmc_init_cs_pins()); #endif #ifdef BOARD_INIT + SETUP_LOG("BOARD_INIT"); BOARD_INIT(); #endif + SETUP_RUN(esp_wifi_init()); + // Check startup - does nothing if bootloader sets MCUSR to 0 - byte mcu = HAL_get_reset_source(); - if (mcu & 1) SERIAL_ECHOLNPGM(STR_POWERUP); - if (mcu & 2) SERIAL_ECHOLNPGM(STR_EXTERNAL_RESET); - if (mcu & 4) SERIAL_ECHOLNPGM(STR_BROWNOUT_RESET); - if (mcu & 8) SERIAL_ECHOLNPGM(STR_WATCHDOG_RESET); - if (mcu & 32) SERIAL_ECHOLNPGM(STR_SOFTWARE_RESET); + const byte mcu = HAL_get_reset_source(); + if (mcu & RST_POWER_ON) SERIAL_ECHOLNPGM(STR_POWERUP); + if (mcu & RST_EXTERNAL) SERIAL_ECHOLNPGM(STR_EXTERNAL_RESET); + if (mcu & RST_BROWN_OUT) SERIAL_ECHOLNPGM(STR_BROWNOUT_RESET); + if (mcu & RST_WATCHDOG) SERIAL_ECHOLNPGM(STR_WATCHDOG_RESET); + if (mcu & RST_SOFTWARE) SERIAL_ECHOLNPGM(STR_SOFTWARE_RESET); HAL_clear_reset_source(); serialprintPGM(GET_TEXT(MSG_MARLIN)); SERIAL_CHAR(' '); SERIAL_ECHOLNPGM(SHORT_BUILD_VERSION); SERIAL_EOL(); - #if defined(STRING_DISTRIBUTION_DATE) && defined(STRING_CONFIG_H_AUTHOR) SERIAL_ECHO_MSG( - STR_CONFIGURATION_VER - STRING_DISTRIBUTION_DATE - STR_AUTHOR STRING_CONFIG_H_AUTHOR + " Last Updated: " STRING_DISTRIBUTION_DATE + " | Author: " STRING_CONFIG_H_AUTHOR ); - SERIAL_ECHO_MSG("Compiled: " __DATE__); #endif + SERIAL_ECHO_MSG("Compiled: " __DATE__); + SERIAL_ECHO_MSG(STR_FREE_MEMORY, freeMemory(), STR_PLANNER_BUFFER_BYTES, (int)sizeof(block_t) * (BLOCK_BUFFER_SIZE)); - SERIAL_ECHO_START(); - SERIAL_ECHOLNPAIR(STR_FREE_MEMORY, freeMemory(), STR_PLANNER_BUFFER_BYTES, (int)sizeof(block_t) * (BLOCK_BUFFER_SIZE)); - - // UI must be initialized before EEPROM - // (because EEPROM code calls the UI). + // Init buzzer pin(s) + #if USE_BEEPER + SETUP_RUN(buzzer.init()); + #endif // Set up LEDs early #if HAS_COLOR_LEDS - leds.setup(); + SETUP_RUN(leds.setup()); + #endif + + #if ENABLED(NEOPIXEL2_SEPARATE) + SETUP_RUN(leds2.setup()); #endif - ui.init(); - #if HAS_SPI_LCD && ENABLED(SHOW_BOOTSCREEN) - ui.show_bootscreen(); + #if ENABLED(USE_CONTROLLER_FAN) // Set up fan controller to initialize also the default configurations. + SETUP_RUN(controllerFan.setup()); #endif - ui.reset_status(); // Load welcome message early. (Retained if no errors exist.) + // UI must be initialized before EEPROM + // (because EEPROM code calls the UI). - #if ENABLED(SDSUPPORT) - card.mount(); // Mount the SD card before settings.first_load + #if ENABLED(DWIN_CREALITY_LCD) + delay(800); // Required delay (since boot?) + SERIAL_ECHOPGM("\nDWIN handshake "); + if (DWIN_Handshake()) SERIAL_ECHOLNPGM("ok."); else SERIAL_ECHOLNPGM("error."); + DWIN_Frame_SetDir(1); // Orientation 90° + DWIN_UpdateLCD(); // Show bootscreen (first image) + #else + SETUP_RUN(ui.init()); + #if HAS_WIRED_LCD && ENABLED(SHOW_BOOTSCREEN) + SETUP_RUN(ui.show_bootscreen()); + #endif + SETUP_RUN(ui.reset_status()); // Load welcome message early. (Retained if no errors exist.) #endif - // Load data from EEPROM if available (or use defaults) - settings.first_load(); // This also updates variables in the planner, elsewhere - #if ENABLED(TOUCH_BUTTONS) - touch.init(); + #if BOTH(SDSUPPORT, SDCARD_EEPROM_EMULATION) + SETUP_RUN(card.mount()); // Mount media with settings before first_load #endif - #if HAS_M206_COMMAND // Initialize current position based on home_offset - current_position += home_offset; + SETUP_RUN(settings.first_load()); // Load data from EEPROM if available (or use defaults) + // This also updates variables in the planner, elsewhere + + #if HAS_TOUCH_XPT2046 + SETUP_RUN(touch.init()); #endif - sync_plan_position(); // Vital to init stepper/planner equivalent for current_position + TERN_(HAS_M206_COMMAND, current_position += home_offset); // Init current position based on home_offset + + sync_plan_position(); // Vital to init stepper/planner equivalent for current_position - thermalManager.init(); // Initialize temperature loop + SETUP_RUN(thermalManager.init()); // Initialize temperature loop - print_job_timer.init(); // Initial setup of print job timer + SETUP_RUN(print_job_timer.init()); // Initial setup of print job timer - endstops.init(); // Init endstops and pullups + SETUP_RUN(endstops.init()); // Init endstops and pullups - stepper.init(); // Init stepper. This enables interrupts! + SETUP_RUN(stepper.init()); // Init stepper. This enables interrupts! #if HAS_SERVOS - servo_init(); + SETUP_RUN(servo_init()); #endif #if HAS_Z_SERVO_PROBE - probe.servo_probe_init(); + SETUP_RUN(probe.servo_probe_init()); #endif #if HAS_PHOTOGRAPH @@ -1024,7 +1119,7 @@ void setup() { #endif #if HAS_CUTTER - cutter.init(); + SETUP_RUN(cutter.init()); #endif #if ENABLED(COOLANT_MIST) @@ -1035,23 +1130,19 @@ void setup() { #endif #if HAS_BED_PROBE - endstops.enable_z_probe(false); - #endif - - #if ENABLED(USE_CONTROLLER_FAN) - SET_OUTPUT(CONTROLLER_FAN_PIN); + SETUP_RUN(endstops.enable_z_probe(false)); #endif #if HAS_STEPPER_RESET - enableStepperDrivers(); + SETUP_RUN(enableStepperDrivers()); #endif - #if ENABLED(DIGIPOT_I2C) - digipot_i2c_init(); + #if HAS_MOTOR_CURRENT_I2C + SETUP_RUN(digipot_i2c.init()); #endif - #if ENABLED(DAC_STEPPER_CURRENT) - dac_init(); + #if ENABLED(HAS_MOTOR_CURRENT_DAC) + SETUP_RUN(stepper_dac.init()); #endif #if EITHER(Z_PROBE_SLED, SOLENOID_PROBE) && HAS_SOLENOID_1 @@ -1070,45 +1161,48 @@ void setup() { OUT_WRITE(STAT_LED_BLUE_PIN, LOW); // OFF #endif - #if HAS_CASE_LIGHT + #if ENABLED(CASE_LIGHT_ENABLE) #if DISABLED(CASE_LIGHT_USE_NEOPIXEL) if (PWM_PIN(CASE_LIGHT_PIN)) SET_PWM(CASE_LIGHT_PIN); else SET_OUTPUT(CASE_LIGHT_PIN); #endif - update_case_light(); + SETUP_RUN(caselight.update_brightness()); #endif #if ENABLED(MK2_MULTIPLEXER) + SETUP_LOG("MK2_MULTIPLEXER"); SET_OUTPUT(E_MUX0_PIN); SET_OUTPUT(E_MUX1_PIN); SET_OUTPUT(E_MUX2_PIN); #endif #if HAS_FANMUX - fanmux_init(); + SETUP_RUN(fanmux_init()); #endif #if ENABLED(MIXING_EXTRUDER) - mixer.init(); + SETUP_RUN(mixer.init()); #endif #if ENABLED(BLTOUCH) - bltouch.init(/*set_voltage=*/true); + SETUP_RUN(bltouch.init(/*set_voltage=*/true)); #endif #if ENABLED(I2C_POSITION_ENCODERS) - I2CPEM.init(); + SETUP_RUN(I2CPEM.init()); #endif #if ENABLED(EXPERIMENTAL_I2CBUS) && I2C_SLAVE_ADDRESS > 0 + SETUP_LOG("i2c..."); i2c.onReceive(i2c_on_receive); i2c.onRequest(i2c_on_request); #endif #if DO_SWITCH_EXTRUDER - move_extruder_servo(0); // Initialize extruder servo + SETUP_RUN(move_extruder_servo(0)); // Initialize extruder servo #endif #if ENABLED(SWITCHING_NOZZLE) + SETUP_LOG("SWITCHING_NOZZLE"); // Initialize nozzle servo(s) #if SWITCHING_NOZZLE_TWO_SERVOS lower_nozzle(0); @@ -1119,52 +1213,84 @@ void setup() { #endif #if ENABLED(MAGNETIC_PARKING_EXTRUDER) - mpe_settings_init(); + SETUP_RUN(mpe_settings_init()); #endif #if ENABLED(PARKING_EXTRUDER) - pe_solenoid_init(); + SETUP_RUN(pe_solenoid_init()); #endif - #if ENABLED(ELECTROMAGNETIC_SWITCHING_TOOLHEAD) - est_init(); + #if ENABLED(SWITCHING_TOOLHEAD) + SETUP_RUN(swt_init()); #endif - #if ENABLED(POWER_LOSS_RECOVERY) - recovery.check(); + #if ENABLED(ELECTROMAGNETIC_SWITCHING_TOOLHEAD) + SETUP_RUN(est_init()); #endif #if ENABLED(USE_WATCHDOG) - watchdog_init(); // Reinit watchdog after HAL_get_reset_source call + SETUP_RUN(watchdog_init()); // Reinit watchdog after HAL_get_reset_source call #endif #if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER) - init_closedloop(); + SETUP_RUN(closedloop.init()); #endif #ifdef STARTUP_COMMANDS + SETUP_LOG("STARTUP_COMMANDS"); queue.inject_P(PSTR(STARTUP_COMMANDS)); #endif - #if ENABLED(INIT_SDCARD_ON_BOOT) && !HAS_SPI_LCD - card.beginautostart(); - #endif - #if ENABLED(HOST_PROMPT_SUPPORT) - host_action_prompt_end(); + SETUP_RUN(host_action_prompt_end()); #endif - #if HAS_TRINAMIC && DISABLED(PSU_DEFAULT_OFF) - test_tmc_connection(true, true, true, true); + #if HAS_TRINAMIC_CONFIG && DISABLED(PSU_DEFAULT_OFF) + SETUP_RUN(test_tmc_connection(true, true, true, true)); #endif #if ENABLED(PRUSA_MMU2) - mmu2.init(); + SETUP_RUN(mmu2.init()); #endif - #if HAS_SERVICE_INTERVALS + #if ENABLED(IIC_BL24CXX_EEPROM) + BL24CXX::init(); + const uint8_t err = BL24CXX::check(); + SERIAL_ECHO_TERNARY(err, "BL24CXX Check ", "failed", "succeeded", "!\n"); + #endif + + #if ENABLED(DWIN_CREALITY_LCD) + Encoder_Configuration(); + HMI_Init(); + HMI_StartFrame(true); + #endif + + #if HAS_SERVICE_INTERVALS && DISABLED(DWIN_CREALITY_LCD) ui.reset_status(true); // Show service messages or keep current status #endif + + #if ENABLED(MAX7219_DEBUG) + SETUP_RUN(max7219.init()); + #endif + + #if ENABLED(DIRECT_STEPPING) + SETUP_RUN(page_manager.init()); + #endif + + #if HAS_TFT_LVGL_UI + #if ENABLED(SDSUPPORT) + if (!card.isMounted()) SETUP_RUN(card.mount()); // Mount SD to load graphics and fonts + #endif + SETUP_RUN(tft_lvgl_init()); + #endif + + #if ENABLED(PASSWORD_ON_STARTUP) + SETUP_RUN(password.lock_machine()); // Will not proceed until correct password provided + #endif + + marlin_state = MF_RUNNING; + + SETUP_LOG("setup() completed."); } /** @@ -1182,22 +1308,19 @@ void setup() { */ void loop() { do { - idle(); #if ENABLED(SDSUPPORT) card.checkautostart(); if (card.flag.abort_sd_printing) abortSDPrinting(); - if (card.sdprinting_done_state) finishSDPrinting(); + if (marlin_state == MF_SD_COMPLETE) finishSDPrinting(); #endif queue.advance(); endstops.event_handler(); - } while (false // Return to caller for best compatibility - #ifdef __AVR__ - || true // Loop forever on slower (AVR) boards - #endif - ); + TERN_(HAS_TFT_LVGL_UI, printer_state_polling()); + + } while (ENABLED(__AVR__)); // Loop forever on slower (AVR) boards } diff --git a/Marlin/src/MarlinCore.h b/Marlin/src/MarlinCore.h index 5a8157bde1f6..69afc7f30e88 100644 --- a/Marlin/src/MarlinCore.h +++ b/Marlin/src/MarlinCore.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -31,18 +31,11 @@ #include #include -#if HAS_L64XX - #include "libs/L64XX/L64XX_Marlin.h" - extern uint8_t axis_known_position; -#endif - void stop(); -void idle( - #if ENABLED(ADVANCED_PAUSE_FEATURE) - bool no_stepper_sleep = false // pass true to keep steppers from disabling on timeout - #endif -); +// Pass true to keep steppers from timing out +void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep=false)); +inline void idle_no_sleep() { idle(TERN_(ADVANCED_PAUSE_FEATURE, true)); } #if ENABLED(EXPERIMENTAL_I2CBUS) #include "feature/twibus.h" @@ -68,9 +61,20 @@ void minkill(const bool steppers_off=false); void quickstop_stepper(); -extern bool Running; -inline bool IsRunning() { return Running; } -inline bool IsStopped() { return !Running; } +// Global State of the firmware +enum MarlinState : uint8_t { + MF_INITIALIZING = 0, + MF_RUNNING = _BV(0), + MF_PAUSED = _BV(1), + MF_WAITING = _BV(2), + MF_STOPPED = _BV(3), + MF_SD_COMPLETE = _BV(4), + MF_KILLED = _BV(7) +}; + +extern MarlinState marlin_state; +inline bool IsRunning() { return marlin_state == MF_RUNNING; } +inline bool IsStopped() { return marlin_state != MF_RUNNING; } bool printingIsActive(); bool printingIsPaused(); @@ -80,19 +84,13 @@ extern bool wait_for_heatup; #if HAS_RESUME_CONTINUE extern bool wait_for_user; -#endif - -// Inactivity shutdown timer -extern millis_t max_inactive_time, stepper_inactive_time; - -#if ENABLED(USE_CONTROLLER_FAN) - extern uint8_t controllerfan_speed; + void wait_for_user_response(millis_t ms=0, const bool no_sleep=false); #endif #if ENABLED(PSU_CONTROL) extern bool powersupply_on; - #define PSU_PIN_ON() do{ OUT_WRITE(PS_ON_PIN, PSU_ACTIVE_HIGH); powersupply_on = true; }while(0) - #define PSU_PIN_OFF() do{ OUT_WRITE(PS_ON_PIN, !PSU_ACTIVE_HIGH); powersupply_on = false; }while(0) + #define PSU_PIN_ON() do{ OUT_WRITE(PS_ON_PIN, PSU_ACTIVE_STATE); powersupply_on = true; }while(0) + #define PSU_PIN_OFF() do{ OUT_WRITE(PS_ON_PIN, !PSU_ACTIVE_STATE); powersupply_on = false; }while(0) #if ENABLED(AUTO_POWER_CONTROL) #define PSU_ON() powerManager.power_on() #define PSU_OFF() powerManager.power_off() @@ -109,10 +107,19 @@ void protected_pin_err(); inline void suicide() { OUT_WRITE(SUICIDE_PIN, SUICIDE_PIN_INVERTING); } #endif +#if HAS_KILL + #ifndef KILL_PIN_STATE + #define KILL_PIN_STATE LOW + #endif + inline bool kill_state() { return READ(KILL_PIN) == KILL_PIN_STATE; } +#endif + #if ENABLED(G29_RETRY_AND_RECOVER) void event_probe_recover(); void event_probe_failure(); #endif extern const char NUL_STR[], M112_KILL_STR[], G28_STR[], M21_STR[], M23_STR[], M24_STR[], - SP_P_STR[], SP_T_STR[], SP_X_STR[], SP_Y_STR[], SP_Z_STR[], SP_E_STR[]; + SP_A_STR[], SP_B_STR[], SP_C_STR[], + SP_P_STR[], SP_T_STR[], SP_X_STR[], SP_Y_STR[], SP_Z_STR[], SP_E_STR[], + X_LBL[], Y_LBL[], Z_LBL[], E_LBL[], SP_X_LBL[], SP_Y_LBL[], SP_Z_LBL[], SP_E_LBL[]; diff --git a/Marlin/src/core/boards.h b/Marlin/src/core/boards.h index 09b0eada1a17..da7d15ec33d5 100644 --- a/Marlin/src/core/boards.h +++ b/Marlin/src/core/boards.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -56,53 +56,59 @@ #define BOARD_3DRAG 1100 // 3Drag Controller #define BOARD_K8200 1101 // Velleman K8200 Controller (derived from 3Drag Controller) #define BOARD_K8400 1102 // Velleman K8400 Controller (derived from 3Drag Controller) -#define BOARD_BAM_DICE 1103 // 2PrintBeta BAM&DICE with STK drivers -#define BOARD_BAM_DICE_DUE 1104 // 2PrintBeta BAM&DICE Due with STK drivers -#define BOARD_MKS_BASE 1105 // MKS BASE v1.0 -#define BOARD_MKS_BASE_14 1106 // MKS BASE v1.4 with Allegro A4982 stepper drivers -#define BOARD_MKS_BASE_15 1107 // MKS BASE v1.5 with Allegro A4982 stepper drivers -#define BOARD_MKS_BASE_16 1108 // MKS BASE v1.6 with Allegro A4982 stepper drivers -#define BOARD_MKS_BASE_HEROIC 1109 // MKS BASE 1.0 with Heroic HR4982 stepper drivers -#define BOARD_MKS_GEN_13 1110 // MKS GEN v1.3 or 1.4 -#define BOARD_MKS_GEN_L 1111 // MKS GEN L -#define BOARD_KFB_2 1112 // BigTreeTech or BIQU KFB2.0 -#define BOARD_ZRIB_V20 1113 // zrib V2.0 control board (Chinese knock off RAMPS replica) -#define BOARD_FELIX2 1114 // Felix 2.0+ Electronics Board (RAMPS like) -#define BOARD_RIGIDBOARD 1115 // Invent-A-Part RigidBoard -#define BOARD_RIGIDBOARD_V2 1116 // Invent-A-Part RigidBoard V2 -#define BOARD_SAINSMART_2IN1 1117 // Sainsmart 2-in-1 board -#define BOARD_ULTIMAKER 1118 // Ultimaker -#define BOARD_ULTIMAKER_OLD 1119 // Ultimaker (Older electronics. Pre 1.5.4. This is rare) -#define BOARD_AZTEEG_X3 1120 // Azteeg X3 -#define BOARD_AZTEEG_X3_PRO 1121 // Azteeg X3 Pro -#define BOARD_ULTIMAIN_2 1122 // Ultimainboard 2.x (Uses TEMP_SENSOR 20) -#define BOARD_RUMBA 1123 // Rumba -#define BOARD_RUMBA_RAISE3D 1124 // Raise3D N series Rumba derivative -#define BOARD_RL200 1125 // Rapide Lite 200 (v1, low-cost RUMBA clone with drv) -#define BOARD_FORMBOT_TREX2PLUS 1126 // Formbot T-Rex 2 Plus -#define BOARD_FORMBOT_TREX3 1127 // Formbot T-Rex 3 -#define BOARD_FORMBOT_RAPTOR 1128 // Formbot Raptor -#define BOARD_FORMBOT_RAPTOR2 1129 // Formbot Raptor 2 -#define BOARD_BQ_ZUM_MEGA_3D 1130 // bq ZUM Mega 3D -#define BOARD_MAKEBOARD_MINI 1131 // MakeBoard Mini v2.1.2 is a control board sold by MicroMake -#define BOARD_TRIGORILLA_13 1132 // TriGorilla Anycubic version 1.3-based on RAMPS EFB -#define BOARD_TRIGORILLA_14 1133 // ... Ver 1.4 -#define BOARD_TRIGORILLA_14_11 1134 // ... Rev 1.1 (new servo pin order) -#define BOARD_RAMPS_ENDER_4 1135 // Creality: Ender-4, CR-8 -#define BOARD_RAMPS_CREALITY 1136 // Creality: CR10S, CR20, CR-X -#define BOARD_RAMPS_DAGOMA 1137 // Dagoma F5 -#define BOARD_FYSETC_F6_13 1138 // FYSETC F6 1.3 -#define BOARD_FYSETC_F6_14 1139 // FYSETC F6 1.4 -#define BOARD_DUPLICATOR_I3_PLUS 1140 // Wanhao Duplicator i3 Plus -#define BOARD_VORON 1141 // VORON Design -#define BOARD_TRONXY_V3_1_0 1142 // Tronxy TRONXY-V3-1.0 -#define BOARD_Z_BOLT_X_SERIES 1143 // Z-Bolt X Series -#define BOARD_TT_OSCAR 1144 // TT OSCAR -#define BOARD_OVERLORD 1145 // Overlord/Overlord Pro -#define BOARD_HJC2560C_REV1 1146 // ADIMLab Gantry v1 -#define BOARD_HJC2560C_REV2 1147 // ADIMLab Gantry v2 -#define BOARD_TANGO 1148 // BIQU Tango V1 -#define BOARD_MKS_GEN_L_V2 1149 // MKS GEN L V2 +#define BOARD_K8600 1103 // Velleman K8600 Controller (Vertex Nano) +#define BOARD_K8800 1104 // Velleman K8800 Controller (Vertex Delta) +#define BOARD_BAM_DICE 1105 // 2PrintBeta BAM&DICE with STK drivers +#define BOARD_BAM_DICE_DUE 1106 // 2PrintBeta BAM&DICE Due with STK drivers +#define BOARD_MKS_BASE 1107 // MKS BASE v1.0 +#define BOARD_MKS_BASE_14 1108 // MKS BASE v1.4 with Allegro A4982 stepper drivers +#define BOARD_MKS_BASE_15 1109 // MKS BASE v1.5 with Allegro A4982 stepper drivers +#define BOARD_MKS_BASE_16 1110 // MKS BASE v1.6 with Allegro A4982 stepper drivers +#define BOARD_MKS_BASE_HEROIC 1111 // MKS BASE 1.0 with Heroic HR4982 stepper drivers +#define BOARD_MKS_GEN_13 1112 // MKS GEN v1.3 or 1.4 +#define BOARD_MKS_GEN_L 1113 // MKS GEN L +#define BOARD_KFB_2 1114 // BigTreeTech or BIQU KFB2.0 +#define BOARD_ZRIB_V20 1115 // zrib V2.0 control board (Chinese knock off RAMPS replica) +#define BOARD_FELIX2 1116 // Felix 2.0+ Electronics Board (RAMPS like) +#define BOARD_RIGIDBOARD 1117 // Invent-A-Part RigidBoard +#define BOARD_RIGIDBOARD_V2 1118 // Invent-A-Part RigidBoard V2 +#define BOARD_SAINSMART_2IN1 1119 // Sainsmart 2-in-1 board +#define BOARD_ULTIMAKER 1120 // Ultimaker +#define BOARD_ULTIMAKER_OLD 1121 // Ultimaker (Older electronics. Pre 1.5.4. This is rare) +#define BOARD_AZTEEG_X3 1122 // Azteeg X3 +#define BOARD_AZTEEG_X3_PRO 1123 // Azteeg X3 Pro +#define BOARD_ULTIMAIN_2 1124 // Ultimainboard 2.x (Uses TEMP_SENSOR 20) +#define BOARD_RUMBA 1125 // Rumba +#define BOARD_RUMBA_RAISE3D 1126 // Raise3D N series Rumba derivative +#define BOARD_RL200 1127 // Rapide Lite 200 (v1, low-cost RUMBA clone with drv) +#define BOARD_FORMBOT_TREX2PLUS 1128 // Formbot T-Rex 2 Plus +#define BOARD_FORMBOT_TREX3 1129 // Formbot T-Rex 3 +#define BOARD_FORMBOT_RAPTOR 1130 // Formbot Raptor +#define BOARD_FORMBOT_RAPTOR2 1131 // Formbot Raptor 2 +#define BOARD_BQ_ZUM_MEGA_3D 1132 // bq ZUM Mega 3D +#define BOARD_MAKEBOARD_MINI 1133 // MakeBoard Mini v2.1.2 is a control board sold by MicroMake +#define BOARD_TRIGORILLA_13 1134 // TriGorilla Anycubic version 1.3-based on RAMPS EFB +#define BOARD_TRIGORILLA_14 1135 // ... Ver 1.4 +#define BOARD_TRIGORILLA_14_11 1136 // ... Rev 1.1 (new servo pin order) +#define BOARD_RAMPS_ENDER_4 1137 // Creality: Ender-4, CR-8 +#define BOARD_RAMPS_CREALITY 1138 // Creality: CR10S, CR20, CR-X +#define BOARD_RAMPS_DAGOMA 1139 // Dagoma F5 +#define BOARD_FYSETC_F6_13 1140 // FYSETC F6 1.3 +#define BOARD_FYSETC_F6_14 1141 // FYSETC F6 1.4 +#define BOARD_DUPLICATOR_I3_PLUS 1142 // Wanhao Duplicator i3 Plus +#define BOARD_VORON 1143 // VORON Design +#define BOARD_TRONXY_V3_1_0 1144 // Tronxy TRONXY-V3-1.0 +#define BOARD_Z_BOLT_X_SERIES 1145 // Z-Bolt X Series +#define BOARD_TT_OSCAR 1146 // TT OSCAR +#define BOARD_OVERLORD 1147 // Overlord/Overlord Pro +#define BOARD_HJC2560C_REV1 1148 // ADIMLab Gantry v1 +#define BOARD_HJC2560C_REV2 1149 // ADIMLab Gantry v2 +#define BOARD_TANGO 1150 // BIQU Tango V1 +#define BOARD_MKS_GEN_L_V2 1151 // MKS GEN L V2 +#define BOARD_MKS_GEN_L_V21 1152 // MKS GEN L V2.1 +#define BOARD_COPYMASTER_3D 1153 // Copymaster 3D +#define BOARD_ORTUR_4 1154 // Ortur 4 +#define BOARD_TENLOG_D3_HERO 1155 // Tenlog D3 Hero IDEX printer // // RAMBo and derivatives @@ -143,6 +149,7 @@ #define BOARD_LEAPFROG_XEED2015 1321 // Leapfrog Xeed 2015 #define BOARD_PICA_REVB 1322 // PICA Shield (original version) #define BOARD_PICA 1323 // PICA Shield (rev C or later) +#define BOARD_INTAMSYS40 1324 // Intamsys 4.0 (Funmat HT) // // ATmega1281, ATmega2561 @@ -158,13 +165,15 @@ #define BOARD_SANGUINOLOLU_11 1500 // Sanguinololu < 1.2 #define BOARD_SANGUINOLOLU_12 1501 // Sanguinololu 1.2 and above #define BOARD_MELZI 1502 // Melzi -#define BOARD_MELZI_MAKR3D 1503 // Melzi with ATmega1284 (MaKr3d version) -#define BOARD_MELZI_CREALITY 1504 // Melzi Creality3D board (for CR-10 etc) -#define BOARD_MELZI_MALYAN 1505 // Melzi Malyan M150 board -#define BOARD_MELZI_TRONXY 1506 // Tronxy X5S -#define BOARD_STB_11 1507 // STB V1.1 -#define BOARD_AZTEEG_X1 1508 // Azteeg X1 -#define BOARD_ANET_10 1509 // Anet 1.0 (Melzi clone) +#define BOARD_MELZI_V2 1503 // Melzi V2 +#define BOARD_MELZI_MAKR3D 1504 // Melzi with ATmega1284 (MaKr3d version) +#define BOARD_MELZI_CREALITY 1505 // Melzi Creality3D board (for CR-10 etc) +#define BOARD_MELZI_MALYAN 1506 // Melzi Malyan M150 board +#define BOARD_MELZI_TRONXY 1507 // Tronxy X5S +#define BOARD_STB_11 1508 // STB V1.1 +#define BOARD_AZTEEG_X1 1509 // Azteeg X1 +#define BOARD_ANET_10 1510 // Anet 1.0 (Melzi clone) +#define BOARD_ZMIB_V2 1511 // ZoneStar ZMIB V2 // // Other ATmega644P, ATmega644, ATmega1284P @@ -228,6 +237,8 @@ #define BOARD_SMOOTHIEBOARD 2506 // Smoothieboard #define BOARD_TH3D_EZBOARD 2507 // TH3D EZBoard v1.0 #define BOARD_BTT_SKR_V1_4_TURBO 2508 // BigTreeTech SKR v1.4 TURBO (Power outputs: Hotend0, Hotend1, Fan, Bed) +#define BOARD_MKS_SGEN_L_V2 2509 // MKS SGEN_L V2 (Power outputs: Hotend0, Hotend1, Bed, Fan) +#define BOARD_BTT_SKR_E3_TURBO 2510 // BigTreeTech SKR E3 Turbo (Power outputs: Hotend0, Hotend1, Bed, Fan0, Fan1) // // SAM3X8E ARM Cortex M3 @@ -272,30 +283,44 @@ // STM32 ARM Cortex-M3 // -#define BOARD_STM32F103RE 4000 // STM32F103RE Libmaple-based STM32F1 controller -#define BOARD_MALYAN_M200 4001 // STM32C8T6 Libmaple-based STM32F1 controller -#define BOARD_STM3R_MINI 4002 // STM32F103RE Libmaple-based STM32F1 controller -#define BOARD_GTM32_PRO_VB 4003 // STM32F103VET6 controller -#define BOARD_MORPHEUS 4004 // STM32F103C8 / STM32F103CB Libmaple-based STM32F1 controller -#define BOARD_CHITU3D 4005 // Chitu3D (STM32F103RET6) -#define BOARD_MKS_ROBIN 4006 // MKS Robin (STM32F103ZET6) -#define BOARD_MKS_ROBIN_MINI 4007 // MKS Robin Mini (STM32F103VET6) -#define BOARD_MKS_ROBIN_NANO 4008 // MKS Robin Nano (STM32F103VET6) -#define BOARD_MKS_ROBIN_LITE 4009 // MKS Robin Lite/Lite2 (STM32F103RCT6) -#define BOARD_MKS_ROBIN_LITE3 4010 // MKS Robin Lite3 (STM32F103RCT6) -#define BOARD_MKS_ROBIN_PRO 4011 // MKS Robin Pro (STM32F103ZET6) -#define BOARD_BTT_SKR_MINI_V1_1 4012 // BigTreeTech SKR Mini v1.1 (STM32F103RC) -#define BOARD_BTT_SKR_MINI_E3_V1_0 4013 // BigTreeTech SKR Mini E3 (STM32F103RC) -#define BOARD_BTT_SKR_MINI_E3_V1_2 4014 // BigTreeTech SKR Mini E3 V1.2 (STM32F103RC) -#define BOARD_BTT_SKR_E3_DIP 4015 // BigTreeTech SKR E3 DIP V1.0 (STM32F103RC / STM32F103RE) -#define BOARD_JGAURORA_A5S_A1 4016 // JGAurora A5S A1 (STM32F103ZET6) -#define BOARD_FYSETC_AIO_II 4017 // FYSETC AIO_II -#define BOARD_FYSETC_CHEETAH 4018 // FYSETC Cheetah -#define BOARD_FYSETC_CHEETAH_V12 4019 // FYSETC Cheetah V1.2 -#define BOARD_LONGER3D_LK 4020 // Alfawise U20/U20+/U30 (Longer3D LK1/2) / STM32F103VET6 -#define BOARD_GTM32_MINI 4021 // STM32F103VET6 controller -#define BOARD_GTM32_MINI_A30 4022 // STM32F103VET6 controller -#define BOARD_GTM32_REV_B 4023 // STM32F103VET6 controller +#define BOARD_MALYAN_M200_V2 4000 // STM32F070CB STM32F0 controller +#define BOARD_MALYAN_M300 4001 // STM32F070-based delta +#define BOARD_STM32F103RE 4002 // STM32F103RE Libmaple-based STM32F1 controller +#define BOARD_MALYAN_M200 4003 // STM32C8T6 Libmaple-based STM32F1 controller +#define BOARD_STM3R_MINI 4004 // STM32F103RE Libmaple-based STM32F1 controller +#define BOARD_GTM32_PRO_VB 4005 // STM32F103VET6 controller +#define BOARD_GTM32_MINI 4006 // STM32F103VET6 controller +#define BOARD_GTM32_MINI_A30 4007 // STM32F103VET6 controller +#define BOARD_GTM32_REV_B 4008 // STM32F103VET6 controller +#define BOARD_MORPHEUS 4009 // STM32F103C8 / STM32F103CB Libmaple-based STM32F1 controller +#define BOARD_CHITU3D 4010 // Chitu3D (STM32F103RET6) +#define BOARD_MKS_ROBIN 4011 // MKS Robin (STM32F103ZET6) +#define BOARD_MKS_ROBIN_MINI 4012 // MKS Robin Mini (STM32F103VET6) +#define BOARD_MKS_ROBIN_NANO 4013 // MKS Robin Nano (STM32F103VET6) +#define BOARD_MKS_ROBIN_NANO_V2 4014 // MKS Robin Nano V2 (STM32F103VET6) +#define BOARD_MKS_ROBIN_LITE 4015 // MKS Robin Lite/Lite2 (STM32F103RCT6) +#define BOARD_MKS_ROBIN_LITE3 4016 // MKS Robin Lite3 (STM32F103RCT6) +#define BOARD_MKS_ROBIN_PRO 4017 // MKS Robin Pro (STM32F103ZET6) +#define BOARD_MKS_ROBIN_E3 4018 // MKS Robin E3 (STM32F103RCT6) +#define BOARD_MKS_ROBIN_E3D 4019 // MKS Robin E3D (STM32F103RCT6) +#define BOARD_MKS_ROBIN_E3P 4020 // MKS Robin E3p (STM32F103VET6) +#define BOARD_BTT_SKR_MINI_V1_1 4021 // BigTreeTech SKR Mini v1.1 (STM32F103RC) +#define BOARD_BTT_SKR_MINI_E3_V1_0 4022 // BigTreeTech SKR Mini E3 (STM32F103RC) +#define BOARD_BTT_SKR_MINI_E3_V1_2 4023 // BigTreeTech SKR Mini E3 V1.2 (STM32F103RC) +#define BOARD_BTT_SKR_MINI_E3_V2_0 4024 // BigTreeTech SKR Mini E3 V2.0 (STM32F103RC) +#define BOARD_BTT_SKR_E3_DIP 4025 // BigTreeTech SKR E3 DIP V1.0 (STM32F103RC / STM32F103RE) +#define BOARD_JGAURORA_A5S_A1 4026 // JGAurora A5S A1 (STM32F103ZET6) +#define BOARD_FYSETC_AIO_II 4027 // FYSETC AIO_II +#define BOARD_FYSETC_CHEETAH 4028 // FYSETC Cheetah +#define BOARD_FYSETC_CHEETAH_V12 4029 // FYSETC Cheetah V1.2 +#define BOARD_LONGER3D_LK 4030 // Alfawise U20/U20+/U30 (Longer3D LK1/2) / STM32F103VET6 +#define BOARD_CCROBOT_MEEB_3DP 4031 // ccrobot-online.com MEEB_3DP (STM32F103RC) +#define BOARD_CHITU3D_V5 4032 // Chitu3D TronXY X5SA V5 Board +#define BOARD_CHITU3D_V6 4033 // Chitu3D TronXY X5SA V5 Board +#define BOARD_CREALITY_V4 4034 // Creality v4.x (STM32F103RE) +#define BOARD_CREALITY_V427 4035 // Creality v4.2.7 (STM32F103RE) +#define BOARD_TRIGORILLA_PRO 4036 // Trigorilla Pro (STM32F103ZET6) +#define BOARD_FLY_MINI 4037 // FLY MINI (STM32F103RCT6) // // ARM Cortex-M4F @@ -311,20 +336,24 @@ #define BOARD_BEAST 4200 // STM32F4xxVxT6 Libmaple-based STM32F4 controller #define BOARD_GENERIC_STM32F4 4201 // STM32 STM32GENERIC-based STM32F4 controller #define BOARD_ARMED 4202 // Arm'ed STM32F4-based controller -#define BOARD_RUMBA32_AUS3D 4203 // RUMBA32 STM32F446VET6 based controller from Aus3D -#define BOARD_RUMBA32_MKS 4204 // RUMBA32 STM32F446VET6 based controller from Makerbase -#define BOARD_BLACK_STM32F407VE 4205 // BLACK_STM32F407VE -#define BOARD_BLACK_STM32F407ZE 4206 // BLACK_STM32F407ZE -#define BOARD_STEVAL_3DP001V1 4207 // STEVAL-3DP001V1 3D PRINTER BOARD -#define BOARD_BTT_SKR_PRO_V1_1 4208 // BigTreeTech SKR Pro v1.1 (STM32F407ZG) -#define BOARD_BTT_BTT002_V1_0 4209 // BigTreeTech BTT002 v1.0 (STM32F407VE) -#define BOARD_BTT_GTR_V1_0 4210 // BigTreeTech GTR v1.0 (STM32F407IGT) -#define BOARD_LERDGE_K 4211 // Lerdge K (STM32F407ZG) -#define BOARD_LERDGE_X 4212 // Lerdge X (STM32F407VE) -#define BOARD_VAKE403D 4213 // VAkE 403D (STM32F446VET6) -#define BOARD_FYSETC_S6 4214 // FYSETC S6 board -#define BOARD_FLYF407ZG 4215 // FLYF407ZG board (STM32F407ZG) -#define BOARD_MKS_ROBIN2 4216 // MKS_ROBIN2 (STM32F407ZE) +#define BOARD_RUMBA32_V1_0 4203 // RUMBA32 STM32F446VET6 based controller from Aus3D +#define BOARD_RUMBA32_V1_1 4204 // RUMBA32 STM32F446VET6 based controller from Aus3D +#define BOARD_RUMBA32_MKS 4205 // RUMBA32 STM32F446VET6 based controller from Makerbase +#define BOARD_BLACK_STM32F407VE 4206 // BLACK_STM32F407VE +#define BOARD_BLACK_STM32F407ZE 4207 // BLACK_STM32F407ZE +#define BOARD_STEVAL_3DP001V1 4208 // STEVAL-3DP001V1 3D PRINTER BOARD +#define BOARD_BTT_SKR_PRO_V1_1 4209 // BigTreeTech SKR Pro v1.1 (STM32F407ZG) +#define BOARD_BTT_SKR_PRO_V1_2 4210 // BigTreeTech SKR Pro v1.2 (STM32F407ZG) +#define BOARD_BTT_BTT002_V1_0 4211 // BigTreeTech BTT002 v1.0 (STM32F407VG) +#define BOARD_BTT_GTR_V1_0 4212 // BigTreeTech GTR v1.0 (STM32F407IGT) +#define BOARD_LERDGE_K 4213 // Lerdge K (STM32F407ZG) +#define BOARD_LERDGE_S 4214 // Lerdge S (STM32F407VE) +#define BOARD_LERDGE_X 4215 // Lerdge X (STM32F407VE) +#define BOARD_VAKE403D 4216 // VAkE 403D (STM32F446VET6) +#define BOARD_FYSETC_S6 4217 // FYSETC S6 board +#define BOARD_FYSETC_S6_V2_0 4218 // FYSETC S6 v2.0 board +#define BOARD_FLYF407ZG 4219 // FLYF407ZG board (STM32F407ZG) +#define BOARD_MKS_ROBIN2 4220 // MKS_ROBIN2 (STM32F407ZE) // // ARM Cortex M7 @@ -332,10 +361,14 @@ #define BOARD_THE_BORG 5000 // THE-BORG (Power outputs: Hotend0, Hotend1, Bed, Fan) #define BOARD_REMRAM_V1 5001 // RemRam v1 +#define BOARD_TEENSY41 5002 // Teensy 4.1 +#define BOARD_T41U5XBB 5003 // T41U5XBB Teensy 4.1 breakout board +#define BOARD_NUCLEO_F767ZI 5004 // ST NUCLEO-F767ZI Dev Board // // Espressif ESP32 WiFi // + #define BOARD_ESPRESSIF_ESP32 6000 // Generic ESP32 #define BOARD_MRR_ESPA 6001 // MRR ESPA board based on ESP32 (native pins only) #define BOARD_MRR_ESPE 6002 // MRR ESPE board based on ESP32 (with I2S stepper stream) @@ -344,8 +377,15 @@ // // SAMD51 ARM Cortex M4 // + #define BOARD_AGCM4_RAMPS_144 6100 // RAMPS 1.4.4 +// +// Custom board +// + +#define BOARD_CUSTOM 9998 // Custom pins definition for development and/or rare boards + // // Simulations // @@ -355,4 +395,4 @@ #define _MB_1(B) (defined(BOARD_##B) && MOTHERBOARD==BOARD_##B) #define MB(V...) DO(MB,||,V) -#define IS_MELZI MB(MELZI, MELZI_CREALITY, MELZI_MAKR3D, MELZI_MALYAN, MELZI_TRONXY) +#define IS_MELZI MB(MELZI, MELZI_CREALITY, MELZI_MAKR3D, MELZI_MALYAN, MELZI_TRONXY, MELZI_V2) diff --git a/Marlin/src/core/debug_out.h b/Marlin/src/core/debug_out.h index 4b2cdf9f77d4..6ae1b9d8bb97 100644 --- a/Marlin/src/core/debug_out.h +++ b/Marlin/src/core/debug_out.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -26,11 +26,13 @@ // (or not) in a given .cpp file // +#undef DEBUG_SECTION #undef DEBUG_PRINT_P #undef DEBUG_ECHO_START #undef DEBUG_ERROR_START #undef DEBUG_CHAR #undef DEBUG_ECHO +#undef DEBUG_DECIMAL #undef DEBUG_ECHO_F #undef DEBUG_ECHOLN #undef DEBUG_ECHOPGM @@ -46,16 +48,23 @@ #undef DEBUG_ECHO_MSG #undef DEBUG_ERROR_MSG #undef DEBUG_EOL +#undef DEBUG_FLUSH #undef DEBUG_POS #undef DEBUG_XYZ #undef DEBUG_DELAY +#undef DEBUG_SYNCHRONIZE #if DEBUG_OUT + + #include "debug_section.h" + #define DEBUG_SECTION(N,S,D) SectionLog N(PSTR(S),D) + #define DEBUG_PRINT_P(P) serialprintPGM(P) #define DEBUG_ECHO_START SERIAL_ECHO_START #define DEBUG_ERROR_START SERIAL_ERROR_START #define DEBUG_CHAR SERIAL_CHAR #define DEBUG_ECHO SERIAL_ECHO + #define DEBUG_DECIMAL SERIAL_DECIMAL #define DEBUG_ECHO_F SERIAL_ECHO_F #define DEBUG_ECHOLN SERIAL_ECHOLN #define DEBUG_ECHOPGM SERIAL_ECHOPGM @@ -71,15 +80,21 @@ #define DEBUG_ECHO_MSG SERIAL_ECHO_MSG #define DEBUG_ERROR_MSG SERIAL_ERROR_MSG #define DEBUG_EOL SERIAL_EOL + #define DEBUG_FLUSH SERIAL_FLUSH #define DEBUG_POS SERIAL_POS #define DEBUG_XYZ SERIAL_XYZ #define DEBUG_DELAY(ms) serial_delay(ms) + #define DEBUG_SYNCHRONIZE() planner.synchronize() + #else + + #define DEBUG_SECTION(...) NOOP #define DEBUG_PRINT_P(P) NOOP #define DEBUG_ECHO_START() NOOP #define DEBUG_ERROR_START() NOOP #define DEBUG_CHAR(...) NOOP #define DEBUG_ECHO(...) NOOP + #define DEBUG_DECIMAL(...) NOOP #define DEBUG_ECHO_F(...) NOOP #define DEBUG_ECHOLN(...) NOOP #define DEBUG_ECHOPGM(...) NOOP @@ -95,9 +110,12 @@ #define DEBUG_ECHO_MSG(...) NOOP #define DEBUG_ERROR_MSG(...) NOOP #define DEBUG_EOL() NOOP + #define DEBUG_FLUSH() NOOP #define DEBUG_POS(...) NOOP #define DEBUG_XYZ(...) NOOP #define DEBUG_DELAY(...) NOOP + #define DEBUG_SYNCHRONIZE() NOOP + #endif #undef DEBUG_OUT diff --git a/Marlin/src/HAL/HAL_LPC1768/include/SPI.h b/Marlin/src/core/debug_section.h similarity index 58% rename from Marlin/src/HAL/HAL_LPC1768/include/SPI.h rename to Marlin/src/core/debug_section.h index af085f29a90b..7f39bc7424e7 100644 --- a/Marlin/src/HAL/HAL_LPC1768/include/SPI.h +++ b/Marlin/src/core/debug_section.h @@ -16,33 +16,34 @@ * 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 . + * along with this program. If not, see . * */ #pragma once -#include "../../shared/HAL_SPI.h" +#include "serial.h" +#include "../module/motion.h" -#include +class SectionLog { +public: + SectionLog(PGM_P const msg=nullptr, bool inbug=true) { + the_msg = msg; + if ((debug = inbug)) echo_msg(PSTR(">>>")); + } -#define MSBFIRST 1 -#define SPI_MODE3 0 + ~SectionLog() { if (debug) echo_msg(PSTR("<<<")); } -class SPISettings { - public: - SPISettings(uint32_t speed, int, int) : spi_speed(speed) {}; - uint32_t spiRate() { return spi_speed; } - private: - uint32_t spi_speed; -}; +private: + PGM_P the_msg; + bool debug; -class SPIClass { - public: - void begin(); - void beginTransaction(SPISettings); - void endTransaction() {}; - uint8_t transfer(uint8_t data); - uint16_t transfer16(uint16_t data); + void echo_msg(PGM_P const pre) { + serialprintPGM(pre); + if (the_msg) { + SERIAL_CHAR(' '); + serialprintPGM(the_msg); + } + SERIAL_CHAR(' '); + print_xyz(current_position); + } }; - -extern SPIClass SPI; diff --git a/Marlin/src/core/drivers.h b/Marlin/src/core/drivers.h index 306329d6fe98..3a0e620923ad 100644 --- a/Marlin/src/core/drivers.h +++ b/Marlin/src/core/drivers.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -82,108 +82,116 @@ #define _OR_ADTE(N,T) || AXIS_DRIVER_TYPE_E(N,T) #define HAS_E_DRIVER(T) (0 RREPEAT2(E_STEPPERS, _OR_ADTE, T)) -#define HAS_DRIVER(T) ( AXIS_DRIVER_TYPE_X(T) || AXIS_DRIVER_TYPE_X2(T) \ - || AXIS_DRIVER_TYPE_Y(T) || AXIS_DRIVER_TYPE_Y2(T) \ - || AXIS_DRIVER_TYPE_Z(T) || AXIS_DRIVER_TYPE_Z2(T) \ - || AXIS_DRIVER_TYPE_Z3(T) || AXIS_DRIVER_TYPE_Z4(T) \ - || HAS_E_DRIVER(T) ) +#define HAS_DRIVER(T) ( AXIS_DRIVER_TYPE_X(T) || AXIS_DRIVER_TYPE_Y(T) || AXIS_DRIVER_TYPE_Z(T) \ + || AXIS_DRIVER_TYPE_X2(T) || AXIS_DRIVER_TYPE_Y2(T) || AXIS_DRIVER_TYPE_Z2(T) \ + || AXIS_DRIVER_TYPE_Z3(T) || AXIS_DRIVER_TYPE_Z4(T) || HAS_E_DRIVER(T) ) + +// +// Trinamic Stepper Drivers +// // Test for supported TMC drivers that require advanced configuration // Does not match standalone configurations -#define HAS_TRINAMIC ( HAS_DRIVER(TMC2130) \ - || HAS_DRIVER(TMC2160) \ - || HAS_DRIVER(TMC2208) \ - || HAS_DRIVER(TMC2209) \ - || HAS_DRIVER(TMC2660) \ - || HAS_DRIVER(TMC5130) \ - || HAS_DRIVER(TMC5160) ) - -#define HAS_TRINAMIC_STANDALONE ( HAS_DRIVER(TMC2130_STANDALONE) \ - || HAS_DRIVER(TMC2208_STANDALONE) \ - || HAS_DRIVER(TMC2209_STANDALONE) \ - || HAS_DRIVER(TMC26X_STANDALONE) \ - || HAS_DRIVER(TMC2660_STANDALONE) \ - || HAS_DRIVER(TMC5130_STANDALONE) \ - || HAS_DRIVER(TMC5160_STANDALONE) \ - || HAS_DRIVER(TMC2160_STANDALONE) ) - -#define HAS_TMCX1X0 ( HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC2160) \ - || HAS_DRIVER(TMC5130) || HAS_DRIVER(TMC5160)) - -#define HAS_TMC220x (HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209)) - -#define AXIS_IS_TMC(A) ( AXIS_DRIVER_TYPE(A,TMC2130) \ - || AXIS_DRIVER_TYPE(A,TMC2160) \ - || AXIS_DRIVER_TYPE(A,TMC2208) \ - || AXIS_DRIVER_TYPE(A,TMC2209) \ +#if ( HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC2160) \ + || HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209) \ + || HAS_DRIVER(TMC2660) \ + || HAS_DRIVER(TMC5130) || HAS_DRIVER(TMC5160) ) + #define HAS_TRINAMIC_CONFIG 1 +#endif + +#define HAS_TRINAMIC HAS_TRINAMIC_CONFIG + +#if ( HAS_DRIVER(TMC2130_STANDALONE) || HAS_DRIVER(TMC2160_STANDALONE) \ + || HAS_DRIVER(TMC2208_STANDALONE) || HAS_DRIVER(TMC2209_STANDALONE) \ + || HAS_DRIVER(TMC26X_STANDALONE) || HAS_DRIVER(TMC2660_STANDALONE) \ + || HAS_DRIVER(TMC5130_STANDALONE) || HAS_DRIVER(TMC5160_STANDALONE) ) + #define HAS_TRINAMIC_STANDALONE 1 +#endif + +#if HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC2160) || HAS_DRIVER(TMC5130) || HAS_DRIVER(TMC5160) + #define HAS_TMCX1X0 1 +#endif + +#if HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209) + #define HAS_TMC220x 1 +#endif + +#define AXIS_IS_TMC(A) ( AXIS_DRIVER_TYPE(A,TMC2130) || AXIS_DRIVER_TYPE(A,TMC2160) \ + || AXIS_DRIVER_TYPE(A,TMC2208) || AXIS_DRIVER_TYPE(A,TMC2209) \ || AXIS_DRIVER_TYPE(A,TMC2660) \ - || AXIS_DRIVER_TYPE(A,TMC5130) \ - || AXIS_DRIVER_TYPE(A,TMC5160) ) + || AXIS_DRIVER_TYPE(A,TMC5130) || AXIS_DRIVER_TYPE(A,TMC5160) ) // Test for a driver that uses SPI - this allows checking whether a _CS_ pin // is considered sensitive -#define AXIS_HAS_SPI(A) ( AXIS_DRIVER_TYPE(A,TMC2130) \ - || AXIS_DRIVER_TYPE(A,TMC2160) \ +#define AXIS_HAS_SPI(A) ( AXIS_DRIVER_TYPE(A,TMC2130) || AXIS_DRIVER_TYPE(A,TMC2160) \ || AXIS_DRIVER_TYPE(A,TMC2660) \ - || AXIS_DRIVER_TYPE(A,TMC5130) \ - || AXIS_DRIVER_TYPE(A,TMC5160) ) + || AXIS_DRIVER_TYPE(A,TMC5130) || AXIS_DRIVER_TYPE(A,TMC5160) ) + +#define AXIS_HAS_UART(A) ( AXIS_DRIVER_TYPE(A,TMC2208) || AXIS_DRIVER_TYPE(A,TMC2209) ) -#define AXIS_HAS_UART(A) ( AXIS_DRIVER_TYPE(A,TMC2208) \ - || AXIS_DRIVER_TYPE(A,TMC2209) ) +#define AXIS_HAS_RXTX AXIS_HAS_UART -#define AXIS_HAS_SW_SERIAL(A) ((AXIS_HAS_UART(A) && !defined(A##_HARDWARE_SERIAL))) +#define AXIS_HAS_HW_SERIAL(A) ( AXIS_HAS_UART(A) && defined(A##_HARDWARE_SERIAL) ) +#define AXIS_HAS_SW_SERIAL(A) ( AXIS_HAS_UART(A) && !defined(A##_HARDWARE_SERIAL) ) -#define AXIS_HAS_STALLGUARD(A) ( AXIS_DRIVER_TYPE(A,TMC2130) \ - || AXIS_DRIVER_TYPE(A,TMC2160) \ +#define AXIS_HAS_STALLGUARD(A) ( AXIS_DRIVER_TYPE(A,TMC2130) || AXIS_DRIVER_TYPE(A,TMC2160) \ || AXIS_DRIVER_TYPE(A,TMC2209) \ || AXIS_DRIVER_TYPE(A,TMC2660) \ - || AXIS_DRIVER_TYPE(A,TMC5130) \ - || AXIS_DRIVER_TYPE(A,TMC5160) ) + || AXIS_DRIVER_TYPE(A,TMC5130) || AXIS_DRIVER_TYPE(A,TMC5160) ) -#define AXIS_HAS_STEALTHCHOP(A) ( AXIS_DRIVER_TYPE(A,TMC2130) \ - || AXIS_DRIVER_TYPE(A,TMC2160) \ - || AXIS_DRIVER_TYPE(A,TMC2208) \ - || AXIS_DRIVER_TYPE(A,TMC2209) \ - || AXIS_DRIVER_TYPE(A,TMC5130) \ - || AXIS_DRIVER_TYPE(A,TMC5160) ) +#define AXIS_HAS_STEALTHCHOP(A) ( AXIS_DRIVER_TYPE(A,TMC2130) || AXIS_DRIVER_TYPE(A,TMC2160) \ + || AXIS_DRIVER_TYPE(A,TMC2208) || AXIS_DRIVER_TYPE(A,TMC2209) \ + || AXIS_DRIVER_TYPE(A,TMC5130) || AXIS_DRIVER_TYPE(A,TMC5160) ) -#define AXIS_HAS_SG_RESULT(A) ( AXIS_DRIVER_TYPE(A,TMC2130) \ - || AXIS_DRIVER_TYPE(A,TMC2160) \ - || AXIS_DRIVER_TYPE(A,TMC2208) \ - || AXIS_DRIVER_TYPE(A,TMC2209) ) +#define AXIS_HAS_SG_RESULT(A) ( AXIS_DRIVER_TYPE(A,TMC2130) || AXIS_DRIVER_TYPE(A,TMC2160) \ + || AXIS_DRIVER_TYPE(A,TMC2208) || AXIS_DRIVER_TYPE(A,TMC2209) ) #define AXIS_HAS_COOLSTEP(A) ( AXIS_DRIVER_TYPE(A,TMC2130) \ || AXIS_DRIVER_TYPE(A,TMC2209) \ - || AXIS_DRIVER_TYPE(A,TMC5130) \ - || AXIS_DRIVER_TYPE(A,TMC5160) ) + || AXIS_DRIVER_TYPE(A,TMC5130) || AXIS_DRIVER_TYPE(A,TMC5160) ) #define _OR_EAH(N,T) || AXIS_HAS_##T(E##N) #define E_AXIS_HAS(T) (0 _OR_EAH(0,T) _OR_EAH(1,T) _OR_EAH(2,T) _OR_EAH(3,T) _OR_EAH(4,T) _OR_EAH(5,T) _OR_EAH(6,T) _OR_EAH(7,T)) -#define ANY_AXIS_HAS(T) ( AXIS_HAS_##T(X) || AXIS_HAS_##T(X2) \ - || AXIS_HAS_##T(Y) || AXIS_HAS_##T(Y2) \ - || AXIS_HAS_##T(Z) || AXIS_HAS_##T(Z2) \ - || AXIS_HAS_##T(Z3) || AXIS_HAS_##T(Z4) \ - || E_AXIS_HAS(T) ) +#define ANY_AXIS_HAS(T) ( AXIS_HAS_##T(X) || AXIS_HAS_##T(Y) || AXIS_HAS_##T(Z) \ + || AXIS_HAS_##T(X2) || AXIS_HAS_##T(Y2) || AXIS_HAS_##T(Z2) \ + || AXIS_HAS_##T(Z3) || AXIS_HAS_##T(Z4) || E_AXIS_HAS(T) ) + +#if ANY_AXIS_HAS(STEALTHCHOP) + #define HAS_STEALTHCHOP 1 +#endif +#if ANY_AXIS_HAS(STALLGUARD) + #define HAS_STALLGUARD 1 +#endif +#if ANY_AXIS_HAS(SG_RESULT) + #define HAS_SG_RESULT 1 +#endif +#if ANY_AXIS_HAS(COOLSTEP) + #define HAS_COOLSTEP 1 +#endif +#if ANY_AXIS_HAS(RXTX) + #define HAS_TMC_UART 1 +#endif +#if ANY_AXIS_HAS(SPI) + #define HAS_TMC_SPI 1 +#endif -#define HAS_STEALTHCHOP ANY_AXIS_HAS(STEALTHCHOP) -#define HAS_STALLGUARD ANY_AXIS_HAS(STALLGUARD) -#define HAS_SG_RESULT ANY_AXIS_HAS(SG_RESULT) -#define HAS_COOLSTEP ANY_AXIS_HAS(COOLSTEP) -#define HAS_TMC_UART ANY_AXIS_HAS(UART) -#define HAS_TMC_SPI ANY_AXIS_HAS(SPI) -#define HAS_TMC_SW_SERIAL ANY_AXIS_HAS(SW_SERIAL) +// +// TMC26XX Stepper Drivers +// +#if HAS_DRIVER(TMC26X) + #define HAS_TMC26X 1 +#endif // -// Stretching 'drivers.h' to include LPC/SAMD51 SD options +// L64XX Stepper Drivers // -#define _SDCARD_LCD 1 -#define _SDCARD_ONBOARD 2 -#define _SDCARD_CUSTOM_CABLE 3 -#define _SDCARD_ID(V) _CAT(_SDCARD_, V) -#define SD_CONNECTION_IS(V) (_SDCARD_ID(SDCARD_CONNECTION) == _SDCARD_ID(V)) - -#define HAS_L64XX (HAS_DRIVER(L6470) || HAS_DRIVER(L6474) || HAS_DRIVER(L6480) || HAS_DRIVER(POWERSTEP01)) -#define HAS_L64XX_NOT_L6474 (HAS_L64XX && !HAS_DRIVER(L6474)) + +#if HAS_DRIVER(L6470) || HAS_DRIVER(L6474) || HAS_DRIVER(L6480) || HAS_DRIVER(POWERSTEP01) + #define HAS_L64XX 1 +#endif +#if HAS_L64XX && !HAS_DRIVER(L6474) + #define HAS_L64XX_NOT_L6474 1 +#endif #define AXIS_IS_L64XX(A) (AXIS_DRIVER_TYPE_##A(L6470) || AXIS_DRIVER_TYPE_##A(L6474) || AXIS_DRIVER_TYPE_##A(L6480) || AXIS_DRIVER_TYPE_##A(POWERSTEP01)) diff --git a/Marlin/src/core/language.h b/Marlin/src/core/language.h index f58ace77091b..60d9aa6b720a 100644 --- a/Marlin/src/core/language.h +++ b/Marlin/src/core/language.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -39,7 +39,7 @@ // // ==> ALWAYS TRY TO COMPILE MARLIN WITH/WITHOUT "ULTIPANEL" / "ULTRA_LCD" / "SDSUPPORT" #define IN "Configuration.h" // ==> ALSO TRY ALL AVAILABLE LANGUAGE OPTIONS -// See also http://marlinfw.org/docs/development/lcd_language.html +// See also https://marlinfw.org/docs/development/lcd_language.html // Languages // an Aragonese @@ -57,6 +57,7 @@ // fr French // gl Galician // hr Croatian +// hu Hungarian // it Italian // jp_kana Japanese // ko_KR Korean (South Korea) @@ -64,6 +65,7 @@ // pl Polish // pt Portuguese // pt_br Portuguese (Brazilian) +// ro Romanian // ru Russian // sk Slovak // tr Turkish @@ -80,18 +82,16 @@ #ifdef CUSTOM_MACHINE_NAME #undef MACHINE_NAME #define MACHINE_NAME CUSTOM_MACHINE_NAME -#else - #ifdef DEFAULT_MACHINE_NAME - #undef MACHINE_NAME - #define MACHINE_NAME DEFAULT_MACHINE_NAME - #endif +#elif defined(DEFAULT_MACHINE_NAME) + #undef MACHINE_NAME + #define MACHINE_NAME DEFAULT_MACHINE_NAME #endif #ifndef MACHINE_UUID #define MACHINE_UUID DEFAULT_MACHINE_UUID #endif -#define MARLIN_WEBSITE_URL "http://marlinfw.org" +#define MARLIN_WEBSITE_URL "https://marlinfw.org" //#if !defined(STRING_SPLASH_LINE3) && defined(WEBSITE_URL) // #define STRING_SPLASH_LINE3 WEBSITE_URL @@ -108,8 +108,6 @@ #define STR_BROWNOUT_RESET " Brown out Reset" #define STR_WATCHDOG_RESET " Watchdog Reset" #define STR_SOFTWARE_RESET " Software Reset" -#define STR_AUTHOR " | Author: " -#define STR_CONFIGURATION_VER " Last Updated: " #define STR_FREE_MEMORY " Free Memory: " #define STR_PLANNER_BUFFER_BYTES " PlannerBufferBytes: " #define STR_OK "ok" @@ -120,13 +118,13 @@ #define STR_ERR_CHECKSUM_MISMATCH "checksum mismatch, Last Line: " #define STR_ERR_NO_CHECKSUM "No Checksum with line number, Last Line: " #define STR_FILE_PRINTED "Done printing file" +#define STR_NO_MEDIA "No media" #define STR_BEGIN_FILE_LIST "Begin file list" #define STR_END_FILE_LIST "End file list" #define STR_INVALID_EXTRUDER "Invalid extruder" #define STR_INVALID_E_STEPPER "Invalid E stepper" #define STR_E_STEPPER_NOT_SPECIFIED "E stepper not specified" #define STR_INVALID_SOLENOID "Invalid solenoid" -#define STR_M115_REPORT "FIRMWARE_NAME:Marlin " DETAILED_BUILD_VERSION " SOURCE_CODE_URL:" SOURCE_CODE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID #define STR_COUNT_X " Count X:" #define STR_COUNT_A " Count A:" #define STR_WATCHDOG_FIRED "Watchdog timeout. Reset required." @@ -163,7 +161,7 @@ #define STR_ERR_MATERIAL_INDEX "M145 S out of range (0-1)" #define STR_ERR_M421_PARAMETERS "M421 incorrect parameter usage" #define STR_ERR_BAD_PLANE_MODE "G5 requires XY plane mode" -#define STR_ERR_MESH_XY "Mesh point cannot be resolved" +#define STR_ERR_MESH_XY "Mesh point out of range" #define STR_ERR_ARC_ARGS "G2/G3 bad parameters" #define STR_ERR_PROTECTED_PIN "Protected Pin" #define STR_ERR_M420_FAILED "Failed to enable Bed Leveling" @@ -185,7 +183,7 @@ #define STR_INVALID_POS_SLOT "Invalid slot. Total: " #define STR_SD_CANT_OPEN_SUBDIR "Cannot open subdir " -#define STR_SD_INIT_FAIL "SD init fail" +#define STR_SD_INIT_FAIL "No SD card" #define STR_SD_VOL_INIT_FAIL "volume.init failed" #define STR_SD_OPENROOT_FAIL "openRoot failed" #define STR_SD_CARD_OK "SD card ok" @@ -205,7 +203,6 @@ #define STR_ERR_COLD_EXTRUDE_STOP " cold extrusion prevented" #define STR_ERR_LONG_EXTRUDE_STOP " too long extrusion prevented" #define STR_ERR_HOTEND_TOO_COLD "Hotend too cold" -#define STR_ERR_Z_HOMING_SER "Home XY first" #define STR_ERR_EEPROM_WRITE "Error writing to EEPROM!" #define STR_FILAMENT_CHANGE_HEAT_LCD "Press button to heat nozzle" @@ -221,12 +218,10 @@ #define STR_KILL_BUTTON "!! KILL caused by KILL button/pin" // temperature.cpp strings -#define STR_PID_AUTOTUNE_PREFIX "PID Autotune" -#define STR_PID_AUTOTUNE_START STR_PID_AUTOTUNE_PREFIX " start" -#define STR_PID_AUTOTUNE_FAILED STR_PID_AUTOTUNE_PREFIX " failed!" -#define STR_PID_BAD_EXTRUDER_NUM STR_PID_AUTOTUNE_FAILED " Bad extruder number" -#define STR_PID_TEMP_TOO_HIGH STR_PID_AUTOTUNE_FAILED " Temperature too high" -#define STR_PID_TIMEOUT STR_PID_AUTOTUNE_FAILED " timeout" +#define STR_PID_AUTOTUNE_START "PID Autotune start" +#define STR_PID_BAD_EXTRUDER_NUM "PID Autotune failed! Bad extruder number" +#define STR_PID_TEMP_TOO_HIGH "PID Autotune failed! Temperature too high" +#define STR_PID_TIMEOUT "PID Autotune failed! timeout" #define STR_BIAS " bias: " #define STR_D_COLON " d: " #define STR_T_MIN " min: " @@ -237,7 +232,7 @@ #define STR_KP " Kp: " #define STR_KI " Ki: " #define STR_KD " Kd: " -#define STR_PID_AUTOTUNE_FINISHED STR_PID_AUTOTUNE_PREFIX " finished! Put the last Kp, Ki and Kd constants from below into Configuration.h" +#define STR_PID_AUTOTUNE_FINISHED "PID Autotune finished! Put the last Kp, Ki and Kd constants from below into Configuration.h" #define STR_PID_DEBUG " PID_DEBUG " #define STR_PID_DEBUG_INPUT ": Input " #define STR_PID_DEBUG_OUTPUT " Output " @@ -269,6 +264,13 @@ #define STR_DEBUG_COMMUNICATION "COMMUNICATION" #define STR_DEBUG_LEVELING "LEVELING" +#define STR_PRINTER_LOCKED "Printer locked! (Unlock with M511 or LCD)" +#define STR_WRONG_PASSWORD "Incorrect Password" +#define STR_PASSWORD_TOO_LONG "Password too long" +#define STR_PASSWORD_REMOVED "Password removed" +#define STR_REMINDER_SAVE_SETTINGS "Remember to save!" +#define STR_PASSWORD_SET "Password is " + // LCD Menu Messages #define LANGUAGE_DATA_INCL_(M) STRINGIFY_(fontdata/langdata_##M.h) @@ -301,7 +303,7 @@ #define LCD_STR_C STR_C #define LCD_STR_E STR_E -#if HAS_CHARACTER_LCD +#if EITHER(HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL) // Custom characters defined in the first 8 characters of the LCD #define LCD_STR_BEDTEMP "\x00" // Print only as a char. This will have 'unexpected' results when used in a string! @@ -346,10 +348,9 @@ * However, internal to Marlin E0/T0 is the first tool, and * most board silkscreens say "E0." Zero-based labels will * make these indexes consistent but this defies expectation. - * */ #if ENABLED(NUMBER_TOOLS_FROM_0) - #define LCD_FIRST_TOOL '0' + #define LCD_FIRST_TOOL 0 #define LCD_STR_N0 "0" #define LCD_STR_N1 "1" #define LCD_STR_N2 "2" @@ -359,7 +360,7 @@ #define LCD_STR_N6 "6" #define LCD_STR_N7 "7" #else - #define LCD_FIRST_TOOL '1' + #define LCD_FIRST_TOOL 1 #define LCD_STR_N0 "1" #define LCD_STR_N1 "2" #define LCD_STR_N2 "3" diff --git a/Marlin/src/core/macros.h b/Marlin/src/core/macros.h index 5e0797d67c04..21bb32c4cf24 100644 --- a/Marlin/src/core/macros.h +++ b/Marlin/src/core/macros.h @@ -16,11 +16,15 @@ * 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 . + * along with this program. If not, see . * */ #pragma once +#if !defined(__has_include) + #define __has_include(...) 1 +#endif + #define ABCE 4 #define XYZE 4 #define ABC 3 @@ -72,13 +76,6 @@ // Nanoseconds per cycle #define NANOSECONDS_PER_CYCLE (1000000000.0 / F_CPU) -// Macros to make sprintf_P read from PROGMEM (AVR extension) -#ifdef __AVR__ - #define S_FMT "%S" -#else - #define S_FMT "%s" -#endif - // Macros to make a string from a macro #define STRINGIFY_(M) #M #define STRINGIFY(M) STRINGIFY_(M) @@ -100,12 +97,15 @@ #define CBI(A,B) (A &= ~(1 << (B))) #endif +#define TBI(N,B) (N ^= _BV(B)) + #define _BV32(b) (1UL << (b)) #define TEST32(n,b) !!((n)&_BV32(b)) #define SBI32(n,b) (n |= _BV32(b)) #define CBI32(n,b) (n &= ~_BV32(b)) +#define TBI32(N,B) (N ^= _BV32(B)) -#define cu(x) ((x)*(x)*(x)) +#define cu(x) ({__typeof__(x) _x = (x); (_x)*(_x)*(_x);}) #define RADIANS(d) ((d)*float(M_PI)/180.0f) #define DEGREES(r) ((r)*180.0f/float(M_PI)) #define HYPOT2(x,y) (sq(x)+sq(y)) @@ -113,7 +113,7 @@ #define CIRCLE_AREA(R) (float(M_PI) * sq(float(R))) #define CIRCLE_CIRC(R) (2 * float(M_PI) * float(R)) -#define SIGN(a) ((a>0)-(a<0)) +#define SIGN(a) ({__typeof__(a) _a = (a); (_a>0)-(_a<0);}) #define IS_POWER_OF_2(x) ((x) && !((x) & ((x) - 1))) // Macros to constrain values @@ -133,8 +133,6 @@ #else - // 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{ \ __typeof__(n) _n = (n); \ @@ -177,18 +175,26 @@ // Macros to support option testing #define _CAT(a,V...) a##V #define CAT(a,V...) _CAT(a,V) -#define SWITCH_ENABLED_false 0 -#define SWITCH_ENABLED_true 1 -#define SWITCH_ENABLED_0 0 -#define SWITCH_ENABLED_1 1 -#define SWITCH_ENABLED_0x0 0 -#define SWITCH_ENABLED_0x1 1 -#define SWITCH_ENABLED_ 1 -#define _ENA_1(O) _CAT(SWITCH_ENABLED_, O) -#define _DIS_1(O) !_ENA_1(O) + +#define _ISENA_ ~,1 +#define _ISENA_1 ~,1 +#define _ISENA_0x1 ~,1 +#define _ISENA_true ~,1 +#define _ISENA(V...) IS_PROBE(V) + +#define _ENA_1(O) _ISENA(CAT(_IS,CAT(ENA_, O))) +#define _DIS_1(O) NOT(_ENA_1(O)) #define ENABLED(V...) DO(ENA,&&,V) #define DISABLED(V...) DO(DIS,&&,V) +#define TERN(O,A,B) _TERN(_ENA_1(O),B,A) // OPTION converted to '0' or '1' +#define TERN0(O,A) _TERN(_ENA_1(O),0,A) // OPTION converted to A or '0' +#define TERN1(O,A) _TERN(_ENA_1(O),1,A) // OPTION converted to A or '1' +#define TERN_(O,A) _TERN(_ENA_1(O),,A) // OPTION converted to A or '' +#define _TERN(E,V...) __TERN(_CAT(T_,E),V) // Prepend 'T_' to get 'T_0' or 'T_1' +#define __TERN(T,V...) ___TERN(_CAT(_NO,T),V) // Prepend '_NO' to get '_NOT_0' or '_NOT_1' +#define ___TERN(P,V...) THIRD(P,V) // If first argument has a comma, A. Else B. + #define ANY(V...) !DISABLED(V) #define NONE(V...) DISABLED(V) #define ALL(V...) ENABLED(V) @@ -209,6 +215,7 @@ #define WITHIN(N,L,H) ((N) >= (L) && (N) <= (H)) #define NUMERIC(a) WITHIN(a, '0', '9') #define DECIMAL(a) (NUMERIC(a) || a == '.') +#define HEXCHR(a) (NUMERIC(a) ? (a) - '0' : WITHIN(a, 'a', 'f') ? ((a) - 'a' + 10) : WITHIN(a, 'A', 'F') ? ((a) - 'A' + 10) : -1) #define NUMERIC_SIGNED(a) (NUMERIC(a) || (a) == '-' || (a) == '+') #define DECIMAL_SIGNED(a) (DECIMAL(a) || (a) == '-' || (a) == '+') #define COUNT(a) (sizeof(a)/sizeof(*a)) @@ -243,6 +250,11 @@ #define _JOIN_1(O) (O) #define JOIN_N(N,C,V...) (DO(JOIN,C,LIST_N(N,V))) +#define LOOP_S_LE_N(VAR, S, N) for (uint8_t VAR=(S); VAR<=(N); VAR++) +#define LOOP_S_L_N(VAR, S, N) for (uint8_t VAR=(S); VAR<(N); VAR++) +#define LOOP_LE_N(VAR, N) LOOP_S_LE_N(VAR, 0, N) +#define LOOP_L_N(VAR, N) LOOP_S_L_N(VAR, 0, N) + #define NOOP (void(0)) #define CEILING(x,y) (((x) + (y) - 1) / (y)) @@ -259,7 +271,7 @@ #define NEAR(x,y) NEAR_ZERO((x)-(y)) #define RECIPROCAL(x) (NEAR_ZERO(x) ? 0 : (1 / float(x))) -#define FIXFLOAT(f) (f + (f < 0 ? -0.00005f : 0.00005f)) +#define FIXFLOAT(f) ({__typeof__(f) _f = (f); _f + (_f < 0 ? -0.0000005f : 0.0000005f);}) // // Maths macros that can be overridden by HAL @@ -275,12 +287,6 @@ #define FMOD(x, y) fmodf(x, y) #define HYPOT(x,y) SQRT(HYPOT2(x,y)) -#ifdef TARGET_LPC1768 - #define I2C_ADDRESS(A) ((A) << 1) -#else - #define I2C_ADDRESS(A) A -#endif - // Use NUM_ARGS(__VA_ARGS__) to get the number of variadic arguments #define _NUM_ARGS(_,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A,OUT,...) OUT #define NUM_ARGS(V...) _NUM_ARGS(0,V,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0) @@ -337,15 +343,22 @@ #endif // Macros for adding -#define INC_0 1 -#define INC_1 2 -#define INC_2 3 -#define INC_3 4 -#define INC_4 5 -#define INC_5 6 -#define INC_6 7 -#define INC_7 8 -#define INC_8 9 +#define INC_0 1 +#define INC_1 2 +#define INC_2 3 +#define INC_3 4 +#define INC_4 5 +#define INC_5 6 +#define INC_6 7 +#define INC_7 8 +#define INC_8 9 +#define INC_9 10 +#define INC_10 11 +#define INC_11 12 +#define INC_12 13 +#define INC_13 14 +#define INC_14 15 +#define INC_15 16 #define INCREMENT_(n) INC_##n #define INCREMENT(n) INCREMENT_(n) @@ -362,16 +375,22 @@ #define ADD10(N) ADD5(ADD5(N)) // Macros for subtracting -#define DEC_0 0 -#define DEC_1 0 -#define DEC_2 1 -#define DEC_3 2 -#define DEC_4 3 -#define DEC_5 4 -#define DEC_6 5 -#define DEC_7 6 -#define DEC_8 7 -#define DEC_9 8 +#define DEC_0 0 +#define DEC_1 0 +#define DEC_2 1 +#define DEC_3 2 +#define DEC_4 3 +#define DEC_5 4 +#define DEC_6 5 +#define DEC_7 6 +#define DEC_8 7 +#define DEC_9 8 +#define DEC_10 9 +#define DEC_11 10 +#define DEC_12 11 +#define DEC_13 12 +#define DEC_14 13 +#define DEC_15 14 #define DECREMENT_(n) DEC_##n #define DECREMENT(n) DECREMENT_(n) @@ -390,8 +409,9 @@ // // Primitives supporting precompiler REPEAT // -#define FIRST(a,...) a -#define SECOND(a,b,...) b +#define FIRST(a,...) a +#define SECOND(a,b,...) b +#define THIRD(a,b,c,...) c // Defer expansion #define EMPTY() @@ -432,6 +452,12 @@ #define HAS_ARGS(V...) _BOOL(FIRST(_END_OF_ARGUMENTS_ V)()) #define _END_OF_ARGUMENTS_() 0 + +// Simple Inline IF Macros, friendly to use in other macro definitions +#define IF(O, A, B) ((O) ? (A) : (B)) +#define IF_0(O, A) IF(O, A, 0) +#define IF_1(O, A) IF(O, A, 1) + // // REPEAT core macros. Recurse N times with ascending I. // @@ -473,7 +499,18 @@ ( DEFER2(__RREPEAT2)()(ADD1(_RPT_I),SUB1(_RPT_N),_RPT_OP,V) ) \ ( /* Do nothing */ ) #define __RREPEAT2() _RREPEAT2 -#define RREPEAT_S(S,N,OP) EVAL(_RREPEAT(S,SUB##S(N),OP)) +#define RREPEAT_S(S,N,OP) EVAL1024(_RREPEAT(S,SUB##S(N),OP)) #define RREPEAT(N,OP) RREPEAT_S(0,N,OP) -#define RREPEAT2_S(S,N,OP,V...) EVAL(_RREPEAT2(S,SUB##S(N),OP,V)) +#define RREPEAT2_S(S,N,OP,V...) EVAL1024(_RREPEAT2(S,SUB##S(N),OP,V)) #define RREPEAT2(N,OP,V...) RREPEAT2_S(0,N,OP,V) + +// See https://github.com/swansontec/map-macro +#define MAP_OUT +#define MAP_END(...) +#define MAP_GET_END() 0, MAP_END +#define MAP_NEXT0(test, next, ...) next MAP_OUT +#define MAP_NEXT1(test, next) MAP_NEXT0 (test, next, 0) +#define MAP_NEXT(test, next) MAP_NEXT1 (MAP_GET_END test, next) +#define MAP0(f, x, peek, ...) f(x) MAP_NEXT (peek, MAP1) (f, peek, __VA_ARGS__) +#define MAP1(f, x, peek, ...) f(x) MAP_NEXT (peek, MAP0) (f, peek, __VA_ARGS__) +#define MAP(f, ...) EVAL512 (MAP1 (f, __VA_ARGS__, (), 0)) diff --git a/Marlin/src/core/millis_t.h b/Marlin/src/core/millis_t.h index 39ea17b9f0c8..95bc40e1ecbb 100644 --- a/Marlin/src/core/millis_t.h +++ b/Marlin/src/core/millis_t.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,5 +25,9 @@ typedef uint32_t millis_t; +#define SEC_TO_MS(N) millis_t((N)*1000UL) +#define MIN_TO_MS(N) SEC_TO_MS((N)*60UL) +#define MS_TO_SEC(N) millis_t((N)/1000UL) + #define PENDING(NOW,SOON) ((int32_t)(NOW-(SOON))<0) #define ELAPSED(NOW,SOON) (!PENDING(NOW,SOON)) diff --git a/Marlin/src/core/multi_language.cpp b/Marlin/src/core/multi_language.cpp deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/Marlin/src/core/multi_language.h b/Marlin/src/core/multi_language.h index 98020b1e8d9c..5852c439a845 100644 --- a/Marlin/src/core/multi_language.h +++ b/Marlin/src/core/multi_language.h @@ -16,13 +16,13 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once typedef const char Language_Str[]; -#if defined(LCD_LANGUAGE_5) +#ifdef LCD_LANGUAGE_5 #define NUM_LANGUAGES 5 #elif defined(LCD_LANGUAGE_4) #define NUM_LANGUAGES 4 @@ -76,4 +76,8 @@ typedef const char Language_Str[]; #endif #define GET_TEXT_F(MSG) (const __FlashStringHelper*)GET_TEXT(MSG) -#define MSG_CONCAT(A,B) pgm_p_pair_t(GET_TEXT(A),GET_TEXT(B)) +#define GET_LANGUAGE_NAME(INDEX) GET_LANG(LCD_LANGUAGE_##INDEX)::LANGUAGE + +#define MSG_1_LINE(A) A "\0" "\0" +#define MSG_2_LINE(A,B) A "\0" B "\0" +#define MSG_3_LINE(A,B,C) A "\0" B "\0" C diff --git a/Marlin/src/core/serial.cpp b/Marlin/src/core/serial.cpp index 304aa09a8ae4..0d22f7bfc067 100644 --- a/Marlin/src/core/serial.cpp +++ b/Marlin/src/core/serial.cpp @@ -16,19 +16,19 @@ * 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 . + * along with this program. If not, see . * */ #include "serial.h" -#include "language.h" +#include "../inc/MarlinConfig.h" uint8_t marlin_debug_flags = MARLIN_DEBUG_NONE; -static const char errormagic[] PROGMEM = "Error:"; -static const char echomagic[] PROGMEM = "echo:"; +static PGMSTR(errormagic, "Error:"); +static PGMSTR(echomagic, "echo:"); -#if NUM_SERIAL > 1 +#if HAS_MULTI_SERIAL int8_t serial_port_index = 0; #endif @@ -42,8 +42,8 @@ void serial_echopair_PGM(PGM_P const s_P, const char *v) { serialprintPGM(s_P) void serial_echopair_PGM(PGM_P const s_P, char v) { serialprintPGM(s_P); SERIAL_CHAR(v); } void serial_echopair_PGM(PGM_P const s_P, int v) { serialprintPGM(s_P); SERIAL_ECHO(v); } void serial_echopair_PGM(PGM_P const s_P, long v) { serialprintPGM(s_P); SERIAL_ECHO(v); } -void serial_echopair_PGM(PGM_P const s_P, float v) { serialprintPGM(s_P); SERIAL_ECHO(v); } -void serial_echopair_PGM(PGM_P const s_P, double v) { serialprintPGM(s_P); SERIAL_ECHO(v); } +void serial_echopair_PGM(PGM_P const s_P, float v) { serialprintPGM(s_P); SERIAL_DECIMAL(v); } +void serial_echopair_PGM(PGM_P const s_P, double v) { serialprintPGM(s_P); SERIAL_DECIMAL(v); } void serial_echopair_PGM(PGM_P const s_P, unsigned int v) { serialprintPGM(s_P); SERIAL_ECHO(v); } void serial_echopair_PGM(PGM_P const s_P, unsigned long v) { serialprintPGM(s_P); SERIAL_ECHO(v); } @@ -68,7 +68,7 @@ void print_bin(uint16_t val) { extern const char SP_X_STR[], SP_Y_STR[], SP_Z_STR[]; void print_xyz(const float &x, const float &y, const float &z, PGM_P const prefix/*=nullptr*/, PGM_P const suffix/*=nullptr*/) { - serialprintPGM(prefix); + if (prefix) serialprintPGM(prefix); SERIAL_ECHOPAIR_P(SP_X_STR, x, SP_Y_STR, y, SP_Z_STR, z); if (suffix) serialprintPGM(suffix); else SERIAL_EOL(); } diff --git a/Marlin/src/core/serial.h b/Marlin/src/core/serial.h index 812ff5471fab..fc830736a5a6 100644 --- a/Marlin/src/core/serial.h +++ b/Marlin/src/core/serial.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -47,14 +47,20 @@ extern uint8_t marlin_debug_flags; #define DEBUGGING(F) (marlin_debug_flags & (MARLIN_DEBUG_## F)) #define SERIAL_BOTH 0x7F -#if NUM_SERIAL > 1 +#if HAS_MULTI_SERIAL extern int8_t serial_port_index; #define _PORT_REDIRECT(n,p) REMEMBER(n,serial_port_index,p) #define _PORT_RESTORE(n) RESTORE(n) - #define SERIAL_OUT(WHAT, V...) do{ \ - if (!serial_port_index || serial_port_index == SERIAL_BOTH) (void)MYSERIAL0.WHAT(V); \ - if ( serial_port_index) (void)MYSERIAL1.WHAT(V); \ - }while(0) + + #ifdef SERIAL_CATCHALL + #define SERIAL_OUT(WHAT, V...) (void)CAT(MYSERIAL,SERIAL_CATCHALL).WHAT(V) + #else + #define SERIAL_OUT(WHAT, V...) do{ \ + if (!serial_port_index || serial_port_index == SERIAL_BOTH) (void)MYSERIAL0.WHAT(V); \ + if ( serial_port_index) (void)MYSERIAL1.WHAT(V); \ + }while(0) + #endif + #define SERIAL_ASSERT(P) if(serial_port_index!=(P)){ debugger(); } #else #define _PORT_REDIRECT(n,p) NOOP @@ -184,7 +190,13 @@ extern uint8_t marlin_debug_flags; #define _SELP_21(a,b,V...) do{ _SEP_2(a,b); _SELP_19(V); }while(0) #define _SELP_22(a,b,V...) do{ _SEP_2(a,b); _SELP_20(V); }while(0) #define _SELP_23(a,b,V...) do{ _SEP_2(a,b); _SELP_21(V); }while(0) -#define _SELP_24(a,b,V...) do{ _SEP_2(a,b); _SELP_22(V); }while(0) // Eat two args, pass the rest up +#define _SELP_24(a,b,V...) do{ _SEP_2(a,b); _SELP_22(V); }while(0) +#define _SELP_25(a,b,V...) do{ _SEP_2(a,b); _SELP_23(V); }while(0) +#define _SELP_26(a,b,V...) do{ _SEP_2(a,b); _SELP_24(V); }while(0) +#define _SELP_27(a,b,V...) do{ _SEP_2(a,b); _SELP_25(V); }while(0) +#define _SELP_28(a,b,V...) do{ _SEP_2(a,b); _SELP_26(V); }while(0) +#define _SELP_29(a,b,V...) do{ _SEP_2(a,b); _SELP_27(V); }while(0) +#define _SELP_30(a,b,V...) do{ _SEP_2(a,b); _SELP_28(V); }while(0) // Eat two args, pass the rest up #define SERIAL_ECHOLNPAIR(V...) _SELP_N(NUM_ARGS(V),V) @@ -214,7 +226,13 @@ extern uint8_t marlin_debug_flags; #define _SELP_21_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_19_P(V); }while(0) #define _SELP_22_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_20_P(V); }while(0) #define _SELP_23_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_21_P(V); }while(0) -#define _SELP_24_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_22_P(V); }while(0) // Eat two args, pass the rest up +#define _SELP_24_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_22_P(V); }while(0) +#define _SELP_25_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_23_P(V); }while(0) +#define _SELP_26_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_24_P(V); }while(0) +#define _SELP_27_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_25_P(V); }while(0) +#define _SELP_28_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_26_P(V); }while(0) +#define _SELP_29_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_27_P(V); }while(0) +#define _SELP_30_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_28_P(V); }while(0) // Eat two args, pass the rest up #define SERIAL_ECHOLNPAIR_P(V...) _SELP_N_P(NUM_ARGS(V),V) @@ -245,10 +263,11 @@ extern uint8_t marlin_debug_flags; #define SERIAL_ECHOLIST(pre,V...) do{ SERIAL_ECHOPGM(pre); _SLST_N(NUM_ARGS(V),V); }while(0) #define SERIAL_ECHOLIST_N(N,V...) _SLST_N(N,LIST_N(N,V)) -#define SERIAL_ECHO_P(P) (serialprintPGM(P)) +#define SERIAL_ECHOPGM_P(P) (serialprintPGM(P)) +#define SERIAL_ECHOLNPGM_P(P) (serialprintPGM(P "\n")) -#define SERIAL_ECHOPGM(S) (SERIAL_ECHO_P(PSTR(S))) -#define SERIAL_ECHOLNPGM(S) (SERIAL_ECHO_P(PSTR(S "\n"))) +#define SERIAL_ECHOPGM(S) (serialprintPGM(PSTR(S))) +#define SERIAL_ECHOLNPGM(S) (serialprintPGM(PSTR(S "\n"))) #define SERIAL_ECHOPAIR_F_P(P,V...) do{ serialprintPGM(P); SERIAL_ECHO_F(V); }while(0) #define SERIAL_ECHOLNPAIR_F_P(V...) do{ SERIAL_ECHOPAIR_F_P(V); SERIAL_EOL(); }while(0) @@ -267,6 +286,12 @@ extern uint8_t marlin_debug_flags; #define SERIAL_ECHO_TERNARY(TF, PRE, ON, OFF, POST) serial_ternary(TF, PSTR(PRE), PSTR(ON), PSTR(OFF), PSTR(POST)) +#if SERIAL_FLOAT_PRECISION + #define SERIAL_DECIMAL(V) SERIAL_PRINT(V, SERIAL_FLOAT_PRECISION) +#else + #define SERIAL_DECIMAL(V) SERIAL_ECHO(V) +#endif + // // Functions for serial printing from PROGMEM. (Saves loads of SRAM.) // diff --git a/Marlin/src/core/types.h b/Marlin/src/core/types.h index d563963cf75c..a5b78caabbe4 100644 --- a/Marlin/src/core/types.h +++ b/Marlin/src/core/types.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -24,7 +24,7 @@ #include #include -#include "millis_t.h" +#include "../inc/MarlinConfigPre.h" class __FlashStringHelper; typedef const __FlashStringHelper *progmem_str; @@ -50,12 +50,6 @@ enum AxisEnum : uint8_t { // // Loop over XYZE axes // - -#define LOOP_S_LE_N(VAR, S, N) for (uint8_t VAR=(S); VAR<=(N); VAR++) -#define LOOP_S_L_N(VAR, S, N) for (uint8_t VAR=(S); VAR<(N); VAR++) -#define LOOP_LE_N(VAR, N) LOOP_S_LE_N(VAR, 0, N) -#define LOOP_L_N(VAR, N) LOOP_S_L_N(VAR, 0, N) - #define LOOP_XYZ(VAR) LOOP_S_LE_N(VAR, X_AXIS, Z_AXIS) #define LOOP_XYZE(VAR) LOOP_S_LE_N(VAR, X_AXIS, E_AXIS) #define LOOP_XYZE_N(VAR) LOOP_S_L_N(VAR, X_AXIS, XYZE_N) @@ -187,6 +181,12 @@ struct XYval { }; FI void set(const T px) { x = px; } FI void set(const T px, const T py) { x = px; y = py; } + FI void set(const T (&arr)[XY]) { x = arr[0]; y = arr[1]; } + FI void set(const T (&arr)[XYZ]) { x = arr[0]; y = arr[1]; } + FI void set(const T (&arr)[XYZE]) { x = arr[0]; y = arr[1]; } + #if XYZE_N > XYZE + FI void set(const T (&arr)[XYZE_N]) { x = arr[0]; y = arr[1]; } + #endif FI void reset() { x = y = 0; } FI T magnitude() const { return (T)sqrtf(x*x + y*y); } FI operator T* () { return pos; } @@ -197,6 +197,8 @@ struct XYval { FI XYval asInt() const { return { int16_t(x), int16_t(y) }; } FI XYval asLong() { return { int32_t(x), int32_t(y) }; } FI XYval asLong() const { return { int32_t(x), int32_t(y) }; } + FI XYval ROUNDL() { return { int32_t(LROUND(x)), int32_t(LROUND(y)) }; } + FI XYval ROUNDL() const { return { int32_t(LROUND(x)), int32_t(LROUND(y)) }; } FI XYval asFloat() { return { float(x), float(y) }; } FI XYval asFloat() const { return { float(x), float(y) }; } FI XYval reciprocal() const { return { _RECIP(x), _RECIP(y) }; } @@ -290,6 +292,12 @@ struct XYZval { FI void set(const T px, const T py) { x = px; y = py; } FI void set(const T px, const T py, const T pz) { x = px; y = py; z = pz; } FI void set(const XYval pxy, const T pz) { x = pxy.x; y = pxy.y; z = pz; } + FI void set(const T (&arr)[XY]) { x = arr[0]; y = arr[1]; } + FI void set(const T (&arr)[XYZ]) { x = arr[0]; y = arr[1]; z = arr[2]; } + FI void set(const T (&arr)[XYZE]) { x = arr[0]; y = arr[1]; z = arr[2]; } + #if XYZE_N > XYZE + FI void set(const T (&arr)[XYZE_N]) { x = arr[0]; y = arr[1]; z = arr[2]; } + #endif FI void reset() { x = y = z = 0; } FI T magnitude() const { return (T)sqrtf(x*x + y*y + z*z); } FI operator T* () { return pos; } @@ -300,6 +308,8 @@ struct XYZval { FI XYZval asInt() const { return { int16_t(x), int16_t(y), int16_t(z) }; } FI XYZval asLong() { return { int32_t(x), int32_t(y), int32_t(z) }; } FI XYZval asLong() const { return { int32_t(x), int32_t(y), int32_t(z) }; } + FI XYZval ROUNDL() { return { int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)) }; } + FI XYZval ROUNDL() const { return { int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)) }; } FI XYZval asFloat() { return { float(x), float(y), float(z) }; } FI XYZval asFloat() const { return { float(x), float(y), float(z) }; } FI XYZval reciprocal() const { return { _RECIP(x), _RECIP(y), _RECIP(z) }; } @@ -337,14 +347,14 @@ struct XYZval { FI XYZval operator* (const XYZEval &rs) { XYZval ls = *this; ls.x *= rs.x; ls.y *= rs.y; ls.z *= rs.z; return ls; } FI XYZval operator/ (const XYZEval &rs) const { XYZval ls = *this; ls.x /= rs.x; ls.y /= rs.y; ls.z /= rs.z; return ls; } FI XYZval operator/ (const XYZEval &rs) { XYZval ls = *this; ls.x /= rs.x; ls.y /= rs.y; ls.z /= rs.z; return ls; } - FI XYZval operator* (const float &v) const { XYZval ls = *this; ls.x *= v; ls.y *= v; ls.z *= z; return ls; } - FI XYZval operator* (const float &v) { XYZval ls = *this; ls.x *= v; ls.y *= v; ls.z *= z; return ls; } - FI XYZval operator* (const int &v) const { XYZval ls = *this; ls.x *= v; ls.y *= v; ls.z *= z; return ls; } - FI XYZval operator* (const int &v) { XYZval ls = *this; ls.x *= v; ls.y *= v; ls.z *= z; return ls; } - FI XYZval operator/ (const float &v) const { XYZval ls = *this; ls.x /= v; ls.y /= v; ls.z /= z; return ls; } - FI XYZval operator/ (const float &v) { XYZval ls = *this; ls.x /= v; ls.y /= v; ls.z /= z; return ls; } - FI XYZval operator/ (const int &v) const { XYZval ls = *this; ls.x /= v; ls.y /= v; ls.z /= z; return ls; } - FI XYZval operator/ (const int &v) { XYZval ls = *this; ls.x /= v; ls.y /= v; ls.z /= z; return ls; } + FI XYZval operator* (const float &v) const { XYZval ls = *this; ls.x *= v; ls.y *= v; ls.z *= v; return ls; } + FI XYZval operator* (const float &v) { XYZval ls = *this; ls.x *= v; ls.y *= v; ls.z *= v; return ls; } + FI XYZval operator* (const int &v) const { XYZval ls = *this; ls.x *= v; ls.y *= v; ls.z *= v; return ls; } + FI XYZval operator* (const int &v) { XYZval ls = *this; ls.x *= v; ls.y *= v; ls.z *= v; return ls; } + FI XYZval operator/ (const float &v) const { XYZval ls = *this; ls.x /= v; ls.y /= v; ls.z /= v; return ls; } + FI XYZval operator/ (const float &v) { XYZval ls = *this; ls.x /= v; ls.y /= v; ls.z /= v; return ls; } + FI XYZval operator/ (const int &v) const { XYZval ls = *this; ls.x /= v; ls.y /= v; ls.z /= v; return ls; } + FI XYZval operator/ (const int &v) { XYZval ls = *this; ls.x /= v; ls.y /= v; ls.z /= v; return ls; } FI XYZval operator>>(const int &v) const { XYZval ls = *this; _RS(ls.x); _RS(ls.y); _RS(ls.z); return ls; } FI XYZval operator>>(const int &v) { XYZval ls = *this; _RS(ls.x); _RS(ls.y); _RS(ls.z); return ls; } FI XYZval operator<<(const int &v) const { XYZval ls = *this; _LS(ls.x); _LS(ls.y); _LS(ls.z); return ls; } @@ -397,12 +407,20 @@ struct XYZEval { FI void set(const XYval pxy, const T pz, const T pe) { x = pxy.x; y = pxy.y; z = pz; e = pe; } FI void set(const XYval pxy, const XYval pze) { x = pxy.x; y = pxy.y; z = pze.z; e = pze.e; } FI void set(const XYZval pxyz, const T pe) { x = pxyz.x; y = pxyz.y; z = pxyz.z; e = pe; } + FI void set(const T (&arr)[XY]) { x = arr[0]; y = arr[1]; } + FI void set(const T (&arr)[XYZ]) { x = arr[0]; y = arr[1]; z = arr[2]; } + FI void set(const T (&arr)[XYZE]) { x = arr[0]; y = arr[1]; z = arr[2]; e = arr[3]; } + #if XYZE_N > XYZE + FI void set(const T (&arr)[XYZE_N]) { x = arr[0]; y = arr[1]; z = arr[2]; e = arr[3]; } + #endif FI XYZEval copy() const { return *this; } FI XYZEval ABS() const { return { T(_ABS(x)), T(_ABS(y)), T(_ABS(z)), T(_ABS(e)) }; } FI XYZEval asInt() { return { int16_t(x), int16_t(y), int16_t(z), int16_t(e) }; } FI XYZEval asInt() const { return { int16_t(x), int16_t(y), int16_t(z), int16_t(e) }; } - FI XYZEval asLong() const { return { int32_t(x), int32_t(y), int32_t(z), int32_t(e) }; } FI XYZEval asLong() { return { int32_t(x), int32_t(y), int32_t(z), int32_t(e) }; } + FI XYZEval asLong() const { return { int32_t(x), int32_t(y), int32_t(z), int32_t(e) }; } + FI XYZEval ROUNDL() { return { int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)), int32_t(LROUND(e)) }; } + FI XYZEval ROUNDL() const { return { int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)), int32_t(LROUND(e)) }; } FI XYZEval asFloat() { return { float(x), float(y), float(z), float(e) }; } FI XYZEval asFloat() const { return { float(x), float(y), float(z), float(e) }; } FI XYZEval reciprocal() const { return { _RECIP(x), _RECIP(y), _RECIP(z), _RECIP(e) }; } @@ -483,3 +501,4 @@ struct XYZEval { #undef FI const xyze_char_t axis_codes { 'X', 'Y', 'Z', 'E' }; +#define XYZ_CHAR(A) ((char)('X' + A)) diff --git a/Marlin/src/core/utility.cpp b/Marlin/src/core/utility.cpp index 64783d070f0a..f99956816778 100644 --- a/Marlin/src/core/utility.cpp +++ b/Marlin/src/core/utility.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -57,39 +57,23 @@ void safe_delay(millis_t ms) { void log_machine_info() { SERIAL_ECHOLNPGM("Machine Type: " - #if ENABLED(DELTA) - "Delta" - #elif IS_SCARA - "SCARA" - #elif IS_CORE - "Core" - #else - "Cartesian" - #endif + TERN_(DELTA, "Delta") + TERN_(IS_SCARA, "SCARA") + TERN_(IS_CORE, "Core") + TERN_(MARKFORGED_XY, "MarkForged") + TERN_(IS_CARTESIAN, "Cartesian") ); SERIAL_ECHOLNPGM("Probe: " - #if ENABLED(PROBE_MANUALLY) - "PROBE_MANUALLY" - #elif ENABLED(NOZZLE_AS_PROBE) - "NOZZLE_AS_PROBE" - #elif ENABLED(FIX_MOUNTED_PROBE) - "FIX_MOUNTED_PROBE" - #elif ENABLED(BLTOUCH) - "BLTOUCH" - #elif HAS_Z_SERVO_PROBE - "SERVO PROBE" - #elif ENABLED(TOUCH_MI_PROBE) - "TOUCH_MI_PROBE" - #elif ENABLED(Z_PROBE_SLED) - "Z_PROBE_SLED" - #elif ENABLED(Z_PROBE_ALLEN_KEY) - "Z_PROBE_ALLEN_KEY" - #elif ENABLED(SOLENOID_PROBE) - "SOLENOID_PROBE" - #else - "NONE" - #endif + TERN_(PROBE_MANUALLY, "PROBE_MANUALLY") + TERN_(NOZZLE_AS_PROBE, "NOZZLE_AS_PROBE") + TERN_(FIX_MOUNTED_PROBE, "FIX_MOUNTED_PROBE") + TERN_(HAS_Z_SERVO_PROBE, TERN(BLTOUCH, "BLTOUCH", "SERVO PROBE")) + TERN_(TOUCH_MI_PROBE, "TOUCH_MI_PROBE") + TERN_(Z_PROBE_SLED, "Z_PROBE_SLED") + TERN_(Z_PROBE_ALLEN_KEY, "Z_PROBE_ALLEN_KEY") + TERN_(SOLENOID_PROBE, "SOLENOID_PROBE") + TERN(PROBE_SELECTED, "", "NONE") ); #if HAS_BED_PROBE @@ -107,20 +91,10 @@ void safe_delay(millis_t ms) { else SERIAL_ECHOPGM(" (Aligned With"); - if (probe.offset_xy.y > 0) { - #if IS_SCARA - SERIAL_ECHOPGM("-Distal"); - #else - SERIAL_ECHOPGM("-Back"); - #endif - } - else if (probe.offset_xy.y < 0) { - #if IS_SCARA - SERIAL_ECHOPGM("-Proximal"); - #else - SERIAL_ECHOPGM("-Front"); - #endif - } + if (probe.offset_xy.y > 0) + serialprintPGM(ENABLED(IS_SCARA) ? PSTR("-Distal") : PSTR("-Back")); + else if (probe.offset_xy.y < 0) + serialprintPGM(ENABLED(IS_SCARA) ? PSTR("-Proximal") : PSTR("-Front")); else if (probe.offset_xy.x != 0) SERIAL_ECHOPGM("-Center"); @@ -128,28 +102,19 @@ void safe_delay(millis_t ms) { #endif - if (probe.offset.z < 0) - SERIAL_ECHOPGM("Below"); - else if (probe.offset.z > 0) - SERIAL_ECHOPGM("Above"); - else - SERIAL_ECHOPGM("Same Z as"); + serialprintPGM(probe.offset.z < 0 ? PSTR("Below") : probe.offset.z > 0 ? PSTR("Above") : PSTR("Same Z as")); SERIAL_ECHOLNPGM(" Nozzle)"); #endif #if HAS_ABL_OR_UBL - SERIAL_ECHOLNPGM("Auto Bed Leveling: " - #if ENABLED(AUTO_BED_LEVELING_LINEAR) - "LINEAR" - #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) - "BILINEAR" - #elif ENABLED(AUTO_BED_LEVELING_3POINT) - "3POINT" - #elif ENABLED(AUTO_BED_LEVELING_UBL) - "UBL" - #endif + SERIAL_ECHOPGM("Auto Bed Leveling: " + TERN_(AUTO_BED_LEVELING_LINEAR, "LINEAR") + TERN_(AUTO_BED_LEVELING_BILINEAR, "BILINEAR") + TERN_(AUTO_BED_LEVELING_3POINT, "3POINT") + TERN_(AUTO_BED_LEVELING_UBL, "UBL") ); + if (planner.leveling_active) { SERIAL_ECHOLNPGM(" (enabled)"); #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) @@ -159,10 +124,10 @@ void safe_delay(millis_t ms) { #if ABL_PLANAR SERIAL_ECHOPGM("ABL Adjustment X"); LOOP_XYZ(a) { - float v = planner.get_axis_position_mm(AxisEnum(a)) - current_position[a]; - SERIAL_CHAR(' ', 'X' + char(a)); + const float v = planner.get_axis_position_mm(AxisEnum(a)) - current_position[a]; + SERIAL_CHAR(' ', XYZ_CHAR(a)); if (v > 0) SERIAL_CHAR('+'); - SERIAL_ECHO(v); + SERIAL_DECIMAL(v); } #else #if ENABLED(AUTO_BED_LEVELING_UBL) diff --git a/Marlin/src/core/utility.h b/Marlin/src/core/utility.h index e34f9dd58a0e..645a4be80735 100644 --- a/Marlin/src/core/utility.h +++ b/Marlin/src/core/utility.h @@ -16,13 +16,14 @@ * 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 . + * along with this program. If not, see . * */ #pragma once #include "../inc/MarlinConfigPre.h" #include "../core/types.h" +#include "../core/millis_t.h" // Delay that ensures heaters and watchdog are kept alive void safe_delay(millis_t ms); @@ -70,7 +71,7 @@ class restorer { inline void restore() { ref_ = val_; } }; -#define REMEMBER(N,X,V...) const restorer restorer_##N(X, ##V) +#define REMEMBER(N,X,V...) restorer<__typeof__(X)> restorer_##N(X, ##V) #define RESTORE(N) restorer_##N.restore() // Converts from an uint8_t in the range of 0-255 to an uint8_t diff --git a/Marlin/src/feature/babystep.cpp b/Marlin/src/feature/babystep.cpp index bf9e9a78b551..b07688146110 100644 --- a/Marlin/src/feature/babystep.cpp +++ b/Marlin/src/feature/babystep.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -26,7 +26,8 @@ #include "babystep.h" #include "../MarlinCore.h" -#include "../module/planner.h" +#include "../module/motion.h" // for axes_should_home() +#include "../module/planner.h" // for axis_steps_per_mm[] #include "../module/stepper.h" #if ENABLED(BABYSTEP_ALWAYS_AVAILABLE) @@ -54,73 +55,13 @@ void Babystep::add_mm(const AxisEnum axis, const float &mm) { } void Babystep::add_steps(const AxisEnum axis, const int16_t distance) { - - #if ENABLED(BABYSTEP_WITHOUT_HOMING) - #define CAN_BABYSTEP(AXIS) true - #else - extern uint8_t axis_known_position; - #define CAN_BABYSTEP(AXIS) TEST(axis_known_position, AXIS) - #endif - - if (!CAN_BABYSTEP(axis)) return; + if (DISABLED(BABYSTEP_WITHOUT_HOMING) && axes_should_home(_BV(axis))) return; accum += distance; // Count up babysteps for the UI - #if ENABLED(BABYSTEP_DISPLAY_TOTAL) - axis_total[BS_TOTAL_IND(axis)] += distance; - #endif - - #if ENABLED(BABYSTEP_ALWAYS_AVAILABLE) - #define BSA_ENABLE(AXIS) do{ switch (AXIS) { case X_AXIS: ENABLE_AXIS_X(); break; case Y_AXIS: ENABLE_AXIS_Y(); break; case Z_AXIS: ENABLE_AXIS_Z(); break; default: break; } }while(0) - #else - #define BSA_ENABLE(AXIS) NOOP - #endif - - #if IS_CORE - #if ENABLED(BABYSTEP_XY) - switch (axis) { - case CORE_AXIS_1: // X on CoreXY and CoreXZ, Y on CoreYZ - BSA_ENABLE(CORE_AXIS_1); - BSA_ENABLE(CORE_AXIS_2); - steps[CORE_AXIS_1] += distance * 2; - steps[CORE_AXIS_2] += distance * 2; - break; - case CORE_AXIS_2: // Y on CoreXY, Z on CoreXZ and CoreYZ - BSA_ENABLE(CORE_AXIS_1); - BSA_ENABLE(CORE_AXIS_2); - steps[CORE_AXIS_1] += CORESIGN(distance * 2); - steps[CORE_AXIS_2] -= CORESIGN(distance * 2); - break; - case NORMAL_AXIS: // Z on CoreXY, Y on CoreXZ, X on CoreYZ - default: - BSA_ENABLE(NORMAL_AXIS); - steps[NORMAL_AXIS] += distance; - break; - } - #elif CORE_IS_XZ || CORE_IS_YZ - // Only Z stepping needs to be handled here - BSA_ENABLE(CORE_AXIS_1); - BSA_ENABLE(CORE_AXIS_2); - steps[CORE_AXIS_1] += CORESIGN(distance * 2); - steps[CORE_AXIS_2] -= CORESIGN(distance * 2); - #else - BSA_ENABLE(Z_AXIS); - steps[Z_AXIS] += distance; - #endif - #else - #if ENABLED(BABYSTEP_XY) - BSA_ENABLE(axis); - #else - BSA_ENABLE(Z_AXIS); - #endif - steps[BS_AXIS_IND(axis)] += distance; - #endif - #if ENABLED(BABYSTEP_ALWAYS_AVAILABLE) - gcode.reset_stepper_timeout(); - #endif - - #if ENABLED(INTEGRATED_BABYSTEPPING) - if (has_steps()) stepper.initiateBabystepping(); - #endif + steps[BS_AXIS_IND(axis)] += distance; + TERN_(BABYSTEP_DISPLAY_TOTAL, axis_total[BS_TOTAL_IND(axis)] += distance); + TERN_(BABYSTEP_ALWAYS_AVAILABLE, gcode.reset_stepper_timeout()); + TERN_(INTEGRATED_BABYSTEPPING, if (has_steps()) stepper.initiateBabystepping()); } #endif // BABYSTEPPING diff --git a/Marlin/src/feature/babystep.h b/Marlin/src/feature/babystep.h index 287664502cdb..f85e5909cad4 100644 --- a/Marlin/src/feature/babystep.h +++ b/Marlin/src/feature/babystep.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -55,11 +55,8 @@ class Babystep { #if ENABLED(BABYSTEP_DISPLAY_TOTAL) static int16_t axis_total[BS_TOTAL_IND(Z_AXIS) + 1]; // Total babysteps since G28 static inline void reset_total(const AxisEnum axis) { - if (true - #if ENABLED(BABYSTEP_XY) - && axis == Z_AXIS - #endif - ) axis_total[BS_TOTAL_IND(axis)] = 0; + if (TERN1(BABYSTEP_XY, axis == Z_AXIS)) + axis_total[BS_TOTAL_IND(axis)] = 0; } #endif diff --git a/Marlin/src/feature/backlash.cpp b/Marlin/src/feature/backlash.cpp index 84cd0a85b7d7..867e9cdd217c 100644 --- a/Marlin/src/feature/backlash.cpp +++ b/Marlin/src/feature/backlash.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -113,7 +113,7 @@ void Backlash::add_correction_steps(const int32_t &da, const int32_t &db, const error_correction = 0; // Don't take up any backlash in this segment, as it would subtract steps } #endif - // Making a correction reduces the residual error and modifies delta_mm + // Making a correction reduces the residual error and adds block steps if (error_correction) { block->steps[axis] += ABS(error_correction); residual_error[axis] -= error_correction; diff --git a/Marlin/src/feature/backlash.h b/Marlin/src/feature/backlash.h index 20666c540bb7..8d00570f991e 100644 --- a/Marlin/src/feature/backlash.h +++ b/Marlin/src/feature/backlash.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -55,26 +55,16 @@ class Backlash { static inline float get_measurement(const AxisEnum a) { // Return the measurement averaged over all readings - return ( - #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING) - measured_count[a] > 0 ? measured_mm[a] / measured_count[a] : - #endif - 0 + return TERN(MEASURE_BACKLASH_WHEN_PROBING + , measured_count[a] > 0 ? measured_mm[a] / measured_count[a] : 0 + , 0 ); - #if DISABLED(MEASURE_BACKLASH_WHEN_PROBING) - UNUSED(a); - #endif + TERN(MEASURE_BACKLASH_WHEN_PROBING,,UNUSED(a)); } static inline bool has_measurement(const AxisEnum a) { - return (false - #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING) - || (measured_count[a] > 0) - #endif - ); - #if DISABLED(MEASURE_BACKLASH_WHEN_PROBING) - UNUSED(a); - #endif + return TERN0(MEASURE_BACKLASH_WHEN_PROBING, measured_count[a] > 0); + TERN(MEASURE_BACKLASH_WHEN_PROBING,,UNUSED(a)); } static inline bool has_any_measurement() { diff --git a/Marlin/src/feature/baricuda.cpp b/Marlin/src/feature/baricuda.cpp index 3899348548fb..596891707e92 100644 --- a/Marlin/src/feature/baricuda.cpp +++ b/Marlin/src/feature/baricuda.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/feature/baricuda.h b/Marlin/src/feature/baricuda.h index 567d2253e635..f28d07d6427f 100644 --- a/Marlin/src/feature/baricuda.h +++ b/Marlin/src/feature/baricuda.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/feature/bedlevel/abl/abl.cpp b/Marlin/src/feature/bedlevel/abl/abl.cpp index 74821ba2ec5f..39d8815fad98 100644 --- a/Marlin/src/feature/bedlevel/abl/abl.cpp +++ b/Marlin/src/feature/bedlevel/abl/abl.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -32,7 +32,7 @@ #include "../../../core/debug_out.h" #if ENABLED(EXTENSIBLE_UI) - #include "../../../lcd/extensible_ui/ui_api.h" + #include "../../../lcd/extui/ui_api.h" #endif xy_pos_t bilinear_grid_spacing, bilinear_start; @@ -74,9 +74,7 @@ static void extrapolate_one_point(const uint8_t x, const uint8_t y, const int8_t // Take the average instead of the median z_values[x][y] = (a + b + c) / 3.0; - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(x, y, z_values[x][y]); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, z_values[x][y])); // Median is robust (ignores outliers). // z_values[x][y] = (a < b) ? ((b < c) ? b : (c < a) ? a : c) @@ -115,8 +113,8 @@ void extrapolate_unprobed_bed_level() { ylen = ctry1; #endif - for (uint8_t xo = 0; xo <= xlen; xo++) - for (uint8_t yo = 0; yo <= ylen; yo++) { + LOOP_LE_N(xo, xlen) + LOOP_LE_N(yo, ylen) { uint8_t x2 = ctrx2 + xo, y2 = ctry2 + yo; #ifndef HALF_IN_X const uint8_t x1 = ctrx1 - xo; @@ -209,8 +207,8 @@ void print_bilinear_leveling_grid() { static float bed_level_virt_2cmr(const uint8_t x, const uint8_t y, const float &tx, const float &ty) { float row[4], column[4]; - for (uint8_t i = 0; i < 4; i++) { - for (uint8_t j = 0; j < 4; j++) { + LOOP_L_N(i, 4) { + LOOP_L_N(j, 4) { column[j] = bed_level_virt_coord(i + x - 1, j + y - 1); } row[i] = bed_level_virt_cmr(column, 1, ty); @@ -221,11 +219,11 @@ void print_bilinear_leveling_grid() { void bed_level_virt_interpolate() { bilinear_grid_spacing_virt = bilinear_grid_spacing / (BILINEAR_SUBDIVISIONS); bilinear_grid_factor_virt = bilinear_grid_spacing_virt.reciprocal(); - for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) - for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) - for (uint8_t ty = 0; ty < BILINEAR_SUBDIVISIONS; ty++) - for (uint8_t tx = 0; tx < BILINEAR_SUBDIVISIONS; tx++) { - if ((ty && y == GRID_MAX_POINTS_Y - 1) || (tx && x == GRID_MAX_POINTS_X - 1)) + LOOP_L_N(y, GRID_MAX_POINTS_Y) + LOOP_L_N(x, GRID_MAX_POINTS_X) + LOOP_L_N(ty, BILINEAR_SUBDIVISIONS) + LOOP_L_N(tx, BILINEAR_SUBDIVISIONS) { + if ((ty && y == (GRID_MAX_POINTS_Y) - 1) || (tx && x == (GRID_MAX_POINTS_X) - 1)) continue; z_values_virt[x * (BILINEAR_SUBDIVISIONS) + tx][y * (BILINEAR_SUBDIVISIONS) + ty] = bed_level_virt_2cmr( @@ -241,9 +239,7 @@ void print_bilinear_leveling_grid() { // Refresh after other values have been updated void refresh_bed_level() { bilinear_grid_factor = bilinear_grid_spacing.reciprocal(); - #if ENABLED(ABL_BILINEAR_SUBDIVISION) - bed_level_virt_interpolate(); - #endif + TERN_(ABL_BILINEAR_SUBDIVISION, bed_level_virt_interpolate()); } #if ENABLED(ABL_BILINEAR_SUBDIVISION) @@ -352,7 +348,7 @@ float bilinear_z_offset(const xy_pos_t &raw) { * Prepare a bilinear-leveled linear move on Cartesian, * splitting the move where it crosses grid borders. */ - void bilinear_line_to_destination(const feedRate_t scaled_fr_mm_s, uint16_t x_splits, uint16_t y_splits) { + void bilinear_line_to_destination(const feedRate_t &scaled_fr_mm_s, uint16_t x_splits, uint16_t y_splits) { // Get current and destination cells for this line xy_int_t c1 { CELL_INDEX(x, current_position.x), CELL_INDEX(y, current_position.y) }, c2 { CELL_INDEX(x, destination.x), CELL_INDEX(y, destination.y) }; diff --git a/Marlin/src/feature/bedlevel/abl/abl.h b/Marlin/src/feature/bedlevel/abl/abl.h index 312dc0db80ef..bbe2411dc346 100644 --- a/Marlin/src/feature/bedlevel/abl/abl.h +++ b/Marlin/src/feature/bedlevel/abl/abl.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/feature/bedlevel/bedlevel.cpp b/Marlin/src/feature/bedlevel/bedlevel.cpp index f302d172bf9b..3e9225b7f932 100644 --- a/Marlin/src/feature/bedlevel/bedlevel.cpp +++ b/Marlin/src/feature/bedlevel/bedlevel.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -43,21 +43,13 @@ #include "../../core/debug_out.h" #if ENABLED(EXTENSIBLE_UI) - #include "../../lcd/extensible_ui/ui_api.h" + #include "../../lcd/extui/ui_api.h" #endif bool leveling_is_valid() { - return - #if ENABLED(MESH_BED_LEVELING) - mbl.has_mesh() - #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) - !!bilinear_grid_spacing.x - #elif ENABLED(AUTO_BED_LEVELING_UBL) - ubl.mesh_is_valid() - #else // 3POINT, LINEAR - true - #endif - ; + return TERN1(MESH_BED_LEVELING, mbl.has_mesh()) + && TERN1(AUTO_BED_LEVELING_BILINEAR, !!bilinear_grid_spacing.x) + && TERN1(AUTO_BED_LEVELING_UBL, ubl.mesh_is_valid()); } /** @@ -69,11 +61,7 @@ bool leveling_is_valid() { */ void set_bed_leveling_enabled(const bool enable/*=true*/) { - #if ENABLED(AUTO_BED_LEVELING_BILINEAR) - const bool can_change = (!enable || leveling_is_valid()); - #else - constexpr bool can_change = true; - #endif + const bool can_change = TERN1(AUTO_BED_LEVELING_BILINEAR, !enable || leveling_is_valid()); if (can_change && enable != planner.leveling_active) { @@ -143,13 +131,10 @@ void reset_bed_level() { #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) bilinear_start.reset(); bilinear_grid_spacing.reset(); - for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) - for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) { - z_values[x][y] = NAN; - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(x, y, 0); - #endif - } + GRID_LOOP(x, y) { + z_values[x][y] = NAN; + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, 0)); + } #elif ABL_PLANAR planner.bed_level_matrix.set_to_identity(); #endif @@ -173,7 +158,7 @@ void reset_bed_level() { */ void print_2d_array(const uint8_t sx, const uint8_t sy, const uint8_t precision, element_2d_fn fn) { #ifndef SCAD_MESH_OUTPUT - for (uint8_t x = 0; x < sx; x++) { + LOOP_L_N(x, sx) { serial_spaces(precision + (x < 10 ? 3 : 2)); SERIAL_ECHO(int(x)); } @@ -182,14 +167,14 @@ void reset_bed_level() { #ifdef SCAD_MESH_OUTPUT SERIAL_ECHOLNPGM("measured_z = ["); // open 2D array #endif - for (uint8_t y = 0; y < sy; y++) { + LOOP_L_N(y, sy) { #ifdef SCAD_MESH_OUTPUT SERIAL_ECHOPGM(" ["); // open sub-array #else if (y < 10) SERIAL_CHAR(' '); SERIAL_ECHO(int(y)); #endif - for (uint8_t x = 0; x < sx; x++) { + LOOP_L_N(x, sx) { SERIAL_CHAR(' '); const float offset = fn(x, y); if (!isnan(offset)) { @@ -202,7 +187,7 @@ void reset_bed_level() { SERIAL_CHAR(' '); SERIAL_ECHOPGM("NAN"); #else - for (uint8_t i = 0; i < precision + 3; i++) + LOOP_L_N(i, precision + 3) SERIAL_CHAR(i ? '=' : ' '); #endif } @@ -246,9 +231,7 @@ void reset_bed_level() { current_position = pos; - #if ENABLED(LCD_BED_LEVELING) - ui.wait_for_move = false; - #endif + TERN_(LCD_BED_LEVELING, ui.wait_for_move = false); } #endif diff --git a/Marlin/src/feature/bedlevel/bedlevel.h b/Marlin/src/feature/bedlevel/bedlevel.h index fd3ed82e5287..995e9d0dbcef 100644 --- a/Marlin/src/feature/bedlevel/bedlevel.h +++ b/Marlin/src/feature/bedlevel/bedlevel.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp b/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp index e80b9e9d2f15..1200c2a1b3b8 100644 --- a/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp +++ b/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -29,7 +29,7 @@ #include "../../../module/motion.h" #if ENABLED(EXTENSIBLE_UI) - #include "../../../lcd/extensible_ui/ui_api.h" + #include "../../../lcd/extui/ui_api.h" #endif mesh_bed_leveling mbl; @@ -40,9 +40,9 @@ mesh_bed_leveling::index_to_ypos[GRID_MAX_POINTS_Y]; mesh_bed_leveling::mesh_bed_leveling() { - for (uint8_t i = 0; i < GRID_MAX_POINTS_X; ++i) + LOOP_L_N(i, GRID_MAX_POINTS_X) index_to_xpos[i] = MESH_MIN_X + i * (MESH_X_DIST); - for (uint8_t i = 0; i < GRID_MAX_POINTS_Y; ++i) + LOOP_L_N(i, GRID_MAX_POINTS_Y) index_to_ypos[i] = MESH_MIN_Y + i * (MESH_Y_DIST); reset(); } @@ -51,9 +51,7 @@ z_offset = 0; ZERO(z_values); #if ENABLED(EXTENSIBLE_UI) - for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) - for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) - ExtUI::onMeshUpdate(x, y, 0); + GRID_LOOP(x, y) ExtUI::onMeshUpdate(x, y, 0); #endif } diff --git a/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.h b/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.h index 4c8773107f77..ade7a931401a 100644 --- a/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.h +++ b/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -52,9 +52,7 @@ class mesh_bed_leveling { static void reset(); FORCE_INLINE static bool has_mesh() { - for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) - for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) - if (z_values[x][y]) return true; + GRID_LOOP(x, y) if (z_values[x][y]) return true; return false; } diff --git a/Marlin/src/feature/bedlevel/ubl/ubl.cpp b/Marlin/src/feature/bedlevel/ubl/ubl.cpp index f1a67061335e..087fdf42b2ac 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl.cpp +++ b/Marlin/src/feature/bedlevel/ubl/ubl.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -31,13 +31,13 @@ #include "../../../MarlinCore.h" #include "../../../gcode/gcode.h" - #include "../../../module/configuration_store.h" + #include "../../../module/settings.h" #include "../../../module/planner.h" #include "../../../module/motion.h" #include "../../../module/probe.h" #if ENABLED(EXTENSIBLE_UI) - #include "../../../lcd/extensible_ui/ui_api.h" + #include "../../../lcd/extui/ui_api.h" #endif #include "math.h" @@ -48,15 +48,14 @@ void unified_bed_leveling::report_current_mesh() { if (!leveling_is_valid()) return; - SERIAL_ECHO_MSG(" G29 I99"); - for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) - for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) - if (!isnan(z_values[x][y])) { - SERIAL_ECHO_START(); - SERIAL_ECHOPAIR(" M421 I", int(x), " J", int(y)); - SERIAL_ECHOLNPAIR_F_P(SP_Z_STR, z_values[x][y], 4); - serial_delay(75); // Prevent Printrun from exploding - } + SERIAL_ECHO_MSG(" G29 I999"); + GRID_LOOP(x, y) + if (!isnan(z_values[x][y])) { + SERIAL_ECHO_START(); + SERIAL_ECHOPAIR(" M421 I", int(x), " J", int(y)); + SERIAL_ECHOLNPAIR_F_P(SP_Z_STR, z_values[x][y], 4); + serial_delay(75); // Prevent Printrun from exploding + } } void unified_bed_leveling::report_state() { @@ -85,11 +84,7 @@ _GRIDPOS(Y, 12), _GRIDPOS(Y, 13), _GRIDPOS(Y, 14), _GRIDPOS(Y, 15) ); - #if HAS_LCD_MENU - bool unified_bed_leveling::lcd_map_control = false; - #endif - - volatile int unified_bed_leveling::encoder_diff; + volatile int16_t unified_bed_leveling::encoder_diff; unified_bed_leveling::unified_bed_leveling() { reset(); @@ -101,9 +96,7 @@ storage_slot = -1; ZERO(z_values); #if ENABLED(EXTENSIBLE_UI) - for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) - for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) - ExtUI::onMeshUpdate(x, y, 0); + GRID_LOOP(x, y) ExtUI::onMeshUpdate(x, y, 0); #endif if (was_enabled) report_current_position(); } @@ -114,13 +107,9 @@ } void unified_bed_leveling::set_all_mesh_points_to_value(const float value) { - for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) { - for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) { - z_values[x][y] = value; - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(x, y, value); - #endif - } + GRID_LOOP(x, y) { + z_values[x][y] = value; + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, value)); } } @@ -190,7 +179,7 @@ } // Row Values (I indexes) - for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) { + LOOP_L_N(i, GRID_MAX_POINTS_X) { // Opening Brace or Space const bool is_current = i == curr.x && j == curr.y; @@ -213,7 +202,7 @@ if (human) SERIAL_CHAR(is_current ? ']' : ' '); SERIAL_FLUSHTX(); - idle(); + idle_no_sleep(); } if (!lcd) SERIAL_EOL(); diff --git a/Marlin/src/feature/bedlevel/ubl/ubl.h b/Marlin/src/feature/bedlevel/ubl/ubl.h index 370d792fc5d6..9ac9de180638 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl.h +++ b/Marlin/src/feature/bedlevel/ubl/ubl.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -111,9 +111,12 @@ class unified_bed_leveling { #if HAS_LCD_MENU static bool lcd_map_control; + static void steppers_were_disabled(); + #else + static inline void steppers_were_disabled() {} #endif - static volatile int encoder_diff; // Volatile because it's changed at interrupt time. + static volatile int16_t encoder_diff; // Volatile because buttons may changed it at interrupt time unified_bed_leveling(); @@ -298,9 +301,7 @@ class unified_bed_leveling { #endif static inline bool mesh_is_valid() { - for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) - for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) - if (isnan(z_values[x][y])) return false; + GRID_LOOP(x, y) if (isnan(z_values[x][y])) return false; return true; } diff --git a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp index a0a12ea621d2..e41af9f3cd23 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp +++ b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -27,9 +27,9 @@ #include "../bedlevel.h" #include "../../../MarlinCore.h" - #include "../../../HAL/shared/persistent_store_api.h" - #include "../../../libs/hex_print_routines.h" - #include "../../../module/configuration_store.h" + #include "../../../HAL/shared/eeprom_api.h" + #include "../../../libs/hex_print.h" + #include "../../../module/settings.h" #include "../../../lcd/ultralcd.h" #include "../../../module/stepper.h" #include "../../../module/planner.h" @@ -38,7 +38,7 @@ #include "../../../gcode/gcode.h" #include "../../../libs/least_squares_fit.h" - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND #include "../../../module/tool_change.h" #endif @@ -46,7 +46,7 @@ #include "../../../core/debug_out.h" #if ENABLED(EXTENSIBLE_UI) - #include "../../../lcd/extensible_ui/ui_api.h" + #include "../../../lcd/extui/ui_api.h" #endif #include @@ -54,7 +54,18 @@ #define UBL_G29_P31 #if HAS_LCD_MENU - void _lcd_ubl_output_map_lcd(); + + bool unified_bed_leveling::lcd_map_control = false; + + void unified_bed_leveling::steppers_were_disabled() { + if (lcd_map_control) { + lcd_map_control = false; + ui.defer_status_screen(false); + } + } + + void ubl_map_screen(); + #endif #define SIZE_OF_LITTLE_RAISE 1 @@ -305,17 +316,13 @@ const int8_t p_val = parser.intval('P', -1); const bool may_move = p_val == 1 || p_val == 2 || p_val == 4 || parser.seen('J'); - #if HOTENDS > 1 - const uint8_t old_tool_index = active_extruder; - #endif + TERN_(HAS_MULTI_HOTEND, const uint8_t old_tool_index = active_extruder); // Check for commands that require the printer to be homed if (may_move) { planner.synchronize(); - if (axes_need_homing()) gcode.home_all_axes(); - #if HOTENDS > 1 - if (active_extruder != 0) tool_change(0); - #endif + if (axes_should_home()) gcode.home_all_axes(); + TERN_(HAS_MULTI_HOTEND, if (active_extruder) tool_change(0)); } // Invalidate Mesh Points. This command is a little bit asymmetrical because @@ -340,9 +347,7 @@ break; // No more invalid Mesh Points to populate } z_values[cpos.x][cpos.y] = NAN; - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(cpos, 0.0f); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(cpos, 0.0f)); cnt++; } } @@ -365,25 +370,21 @@ #endif case 0: - for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) { // Create a bowl shape - similar to - for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) { // a poorly calibrated Delta. - const float p1 = 0.5f * (GRID_MAX_POINTS_X) - x, - p2 = 0.5f * (GRID_MAX_POINTS_Y) - y; - z_values[x][y] += 2.0f * HYPOT(p1, p2); - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(x, y, z_values[x][y]); - #endif - } + GRID_LOOP(x, y) { // Create a bowl shape similar to a poorly-calibrated Delta + const float p1 = 0.5f * (GRID_MAX_POINTS_X) - x, + p2 = 0.5f * (GRID_MAX_POINTS_Y) - y; + z_values[x][y] += 2.0f * HYPOT(p1, p2); + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, z_values[x][y])); } break; case 1: - for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) { // Create a diagonal line several Mesh cells thick that is raised + LOOP_L_N(x, GRID_MAX_POINTS_X) { // Create a diagonal line several Mesh cells thick that is raised z_values[x][x] += 9.999f; - z_values[x][x + (x < GRID_MAX_POINTS_Y - 1) ? 1 : -1] += 9.999f; // We want the altered line several mesh points thick + z_values[x][x + (x < (GRID_MAX_POINTS_Y) - 1) ? 1 : -1] += 9.999f; // We want the altered line several mesh points thick #if ENABLED(EXTENSIBLE_UI) ExtUI::onMeshUpdate(x, x, z_values[x][x]); - ExtUI::onMeshUpdate(x, (x + (x < GRID_MAX_POINTS_Y - 1) ? 1 : -1), z_values[x][x + (x < GRID_MAX_POINTS_Y - 1) ? 1 : -1]); + ExtUI::onMeshUpdate(x, (x + (x < (GRID_MAX_POINTS_Y) - 1) ? 1 : -1), z_values[x][x + (x < (GRID_MAX_POINTS_Y) - 1) ? 1 : -1]); #endif } @@ -394,9 +395,7 @@ for (uint8_t x = (GRID_MAX_POINTS_X) / 3; x < 2 * (GRID_MAX_POINTS_X) / 3; x++) // Create a rectangular raised area in for (uint8_t y = (GRID_MAX_POINTS_Y) / 3; y < 2 * (GRID_MAX_POINTS_Y) / 3; y++) { // the center of the bed z_values[x][y] += parser.seen('C') ? g29_constant : 9.99f; - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(x, y, z_values[x][y]); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, z_values[x][y])); } break; } @@ -405,17 +404,12 @@ #if HAS_BED_PROBE if (parser.seen('J')) { - if (g29_grid_size) { // if not 0 it is a normal n x n grid being probed - save_ubl_active_state_and_disable(); - tilt_mesh_based_on_probed_grid(false /* false says to do normal grid probing */ ); - restore_ubl_active_state_and_leave(); - } - else { // grid_size == 0 : A 3-Point leveling has been requested - save_ubl_active_state_and_disable(); - tilt_mesh_based_on_probed_grid(true /* true says to do 3-Point leveling */ ); - restore_ubl_active_state_and_leave(); - } - do_blocking_move_to_xy(0.5f * (MESH_MAX_X - (MESH_MIN_X)), 0.5f * (MESH_MAX_Y - (MESH_MIN_Y))); + save_ubl_active_state_and_disable(); + tilt_mesh_based_on_probed_grid(g29_grid_size == 0); // Zero size does 3-Point + restore_ubl_active_state_and_leave(); + #if ENABLED(UBL_G29_J_RECENTER) + do_blocking_move_to_xy(0.5f * ((MESH_MIN_X) + (MESH_MAX_X)), 0.5f * ((MESH_MIN_Y) + (MESH_MAX_Y))); + #endif report_current_position(); probe_deployed = true; } @@ -450,11 +444,11 @@ if (g29_verbose_level > 1) { SERIAL_ECHOPAIR("Probing around (", g29_pos.x); SERIAL_CHAR(','); - SERIAL_ECHO(g29_pos.y); + SERIAL_DECIMAL(g29_pos.y); SERIAL_ECHOLNPGM(").\n"); } - const xy_pos_t near = g29_pos + probe.offset_xy; - probe_entire_mesh(near, parser.seen('T'), parser.seen('E'), parser.seen('U')); + const xy_pos_t near_probe_xy = g29_pos + probe.offset_xy; + probe_entire_mesh(near_probe_xy, parser.seen('T'), parser.seen('E'), parser.seen('U')); report_current_position(); probe_deployed = true; @@ -467,8 +461,8 @@ // // Manually Probe Mesh in areas that can't be reached by the probe // - SERIAL_ECHOLNPGM("Manually probing unreachable mesh locations."); - do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); + SERIAL_ECHOLNPGM("Manually probing unreachable points."); + do_z_clearance(Z_CLEARANCE_BETWEEN_PROBES); if (parser.seen('C') && !xy_seen) { @@ -490,7 +484,7 @@ } if (parser.seen('B')) { - g29_card_thickness = parser.has_value() ? parser.value_float() : measure_business_card_thickness((float) Z_CLEARANCE_BETWEEN_PROBES); + g29_card_thickness = parser.has_value() ? parser.value_float() : measure_business_card_thickness(float(Z_CLEARANCE_BETWEEN_PROBES)); if (ABS(g29_card_thickness) > 1.5f) { SERIAL_ECHOLNPGM("?Error in Business Card measurement."); return; @@ -537,16 +531,12 @@ if (cpos.x < 0) { // No more REAL INVALID mesh points to populate, so we ASSUME // user meant to populate ALL INVALID mesh points to value - for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) - for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) - if (isnan(z_values[x][y])) z_values[x][y] = g29_constant; + GRID_LOOP(x, y) if (isnan(z_values[x][y])) z_values[x][y] = g29_constant; break; // No more invalid Mesh Points to populate } else { z_values[cpos.x][cpos.y] = g29_constant; - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(cpos, g29_constant); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(cpos, g29_constant)); } } } @@ -687,21 +677,18 @@ UNUSED(probe_deployed); #endif - #if HOTENDS > 1 - tool_change(old_tool_index); - #endif + TERN_(HAS_MULTI_HOTEND, tool_change(old_tool_index)); return; } void unified_bed_leveling::adjust_mesh_to_mean(const bool cflag, const float value) { float sum = 0; int n = 0; - for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) - for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) - if (!isnan(z_values[x][y])) { - sum += z_values[x][y]; - n++; - } + GRID_LOOP(x, y) + if (!isnan(z_values[x][y])) { + sum += z_values[x][y]; + n++; + } const float mean = sum / n; @@ -709,10 +696,9 @@ // Sum the squares of difference from mean // float sum_of_diff_squared = 0; - for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) - for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) - if (!isnan(z_values[x][y])) - sum_of_diff_squared += sq(z_values[x][y] - mean); + GRID_LOOP(x, y) + if (!isnan(z_values[x][y])) + sum_of_diff_squared += sq(z_values[x][y] - mean); SERIAL_ECHOLNPAIR("# of samples: ", n); SERIAL_ECHOLNPAIR_F("Mean Mesh Height: ", mean, 6); @@ -721,25 +707,19 @@ SERIAL_ECHOLNPAIR_F("Standard Deviation: ", sigma, 6); if (cflag) - for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) - for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) - if (!isnan(z_values[x][y])) { - z_values[x][y] -= mean + value; - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(x, y, z_values[x][y]); - #endif - } + GRID_LOOP(x, y) + if (!isnan(z_values[x][y])) { + z_values[x][y] -= mean + value; + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, z_values[x][y])); + } } void unified_bed_leveling::shift_mesh_height() { - for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) - for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) - if (!isnan(z_values[x][y])) { - z_values[x][y] += g29_constant; - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(x, y, z_values[x][y]); - #endif - } + GRID_LOOP(x, y) + if (!isnan(z_values[x][y])) { + z_values[x][y] += g29_constant; + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, z_values[x][y])); + } } #if HAS_BED_PROBE @@ -750,22 +730,19 @@ void unified_bed_leveling::probe_entire_mesh(const xy_pos_t &near, const bool do_ubl_mesh_map, const bool stow_probe, const bool do_furthest) { probe.deploy(); // Deploy before ui.capture() to allow for PAUSE_BEFORE_DEPLOY_STOW - #if HAS_LCD_MENU - ui.capture(); - #endif + TERN_(HAS_LCD_MENU, ui.capture()); save_ubl_active_state_and_disable(); // No bed level correction so only raw data is obtained uint8_t count = GRID_MAX_POINTS; mesh_index_pair best; + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(best.pos, ExtUI::MESH_START)); do { if (do_ubl_mesh_map) display_map(g29_map_type); const int point_num = (GRID_MAX_POINTS) - count + 1; SERIAL_ECHOLNPAIR("\nProbing mesh point ", point_num, "/", int(GRID_MAX_POINTS), ".\n"); - #if HAS_DISPLAY - ui.status_printf_P(0, PSTR(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_MESH), point_num, int(GRID_MAX_POINTS)); - #endif + TERN_(HAS_DISPLAY, ui.status_printf_P(0, PSTR(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_MESH), point_num, int(GRID_MAX_POINTS))); #if HAS_LCD_MENU if (ui.button_pressed()) { @@ -784,12 +761,14 @@ : find_closest_mesh_point_of_type(INVALID, near, true); if (best.pos.x >= 0) { // mesh point found and is reachable by probe + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(best.pos, ExtUI::PROBE_START)); const float measured_z = probe.probe_at_point( best.meshpos(), stow_probe ? PROBE_PT_STOW : PROBE_PT_RAISE, g29_verbose_level ); z_values[best.pos.x][best.pos.y] = measured_z; #if ENABLED(EXTENSIBLE_UI) + ExtUI::onMeshUpdate(best.pos, ExtUI::PROBE_FINISH); ExtUI::onMeshUpdate(best.pos, measured_z); #endif } @@ -797,17 +776,14 @@ } while (best.pos.x >= 0 && --count); - #if HAS_LCD_MENU - ui.release(); - #endif - probe.stow(); // Release UI during stow to allow for PAUSE_BEFORE_DEPLOY_STOW - #if HAS_LCD_MENU - ui.capture(); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(best.pos, ExtUI::MESH_FINISH)); - #ifdef Z_AFTER_PROBING - probe.move_z_after_probing(); - #endif + // Release UI during stow to allow for PAUSE_BEFORE_DEPLOY_STOW + TERN_(HAS_LCD_MENU, ui.release()); + probe.stow(); + TERN_(HAS_LCD_MENU, ui.capture()); + + probe.move_z_after_probing(); restore_ubl_active_state_and_leave(); @@ -825,11 +801,11 @@ bool click_and_hold(const clickFunc_t func=nullptr) { if (ui.button_pressed()) { - ui.quick_feedback(false); // Preserve button state for click-and-hold + ui.quick_feedback(false); // Preserve button state for click-and-hold const millis_t nxt = millis() + 1500UL; - while (ui.button_pressed()) { // Loop while the encoder is pressed. Uses hardware flag! - idle(); // idle, of course - if (ELAPSED(millis(), nxt)) { // After 1.5 seconds + while (ui.button_pressed()) { // Loop while the encoder is pressed. Uses hardware flag! + idle(); // idle, of course + if (ELAPSED(millis(), nxt)) { // After 1.5 seconds ui.quick_feedback(); if (func) (*func)(); ui.wait_for_release(); @@ -862,9 +838,7 @@ static void echo_and_take_a_measurement() { SERIAL_ECHOLNPGM(" and take a measurement."); } float unified_bed_leveling::measure_business_card_thickness(float in_height) { - #if HAS_LCD_MENU - ui.capture(); - #endif + ui.capture(); save_ubl_active_state_and_disable(); // Disable bed level correction for probing do_blocking_move_to(0.5f * (MESH_MAX_X - (MESH_MIN_X)), 0.5f * (MESH_MAX_Y - (MESH_MIN_Y)), in_height); @@ -885,7 +859,6 @@ echo_and_take_a_measurement(); const float z2 = measure_point_with_encoder(); - do_blocking_move_to_z(current_position.z + Z_CLEARANCE_BETWEEN_PROBES); const float thickness = ABS(z1 - z2); @@ -895,17 +868,13 @@ SERIAL_ECHOLNPGM("mm thick."); } - ui.release(); - restore_ubl_active_state_and_leave(); return thickness; } void unified_bed_leveling::manually_probe_remaining_mesh(const xy_pos_t &pos, const float &z_clearance, const float &thick, const bool do_ubl_mesh_map) { - #if HAS_LCD_MENU - ui.capture(); - #endif + ui.capture(); save_ubl_active_state_and_disable(); // No bed level correction so only raw data is obtained do_blocking_move_to_xy_z(current_position, z_clearance); @@ -930,12 +899,10 @@ LCD_MESSAGEPGM(MSG_UBL_MOVING_TO_NEXT); do_blocking_move_to(ppos); - do_blocking_move_to_z(z_clearance); + do_z_clearance(z_clearance); KEEPALIVE_STATE(PAUSED_FOR_USER); - #if HAS_LCD_MENU - ui.capture(); - #endif + ui.capture(); if (do_ubl_mesh_map) display_map(g29_map_type); // show user where we're probing @@ -948,15 +915,12 @@ if (click_and_hold()) { SERIAL_ECHOLNPGM("\nMesh only partially populated."); - do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE); - ui.release(); + do_z_clearance(Z_CLEARANCE_DEPLOY_PROBE); return restore_ubl_active_state_and_leave(); } z_values[lpos.x][lpos.y] = current_position.z - thick; - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(location, z_values[lpos.x][lpos.y]); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(location, z_values[lpos.x][lpos.y])); if (g29_verbose_level > 2) SERIAL_ECHOLNPAIR_F("Mesh Point Measured at: ", z_values[lpos.x][lpos.y], 6); @@ -976,7 +940,7 @@ void abort_fine_tune() { ui.return_to_status(); - do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); + do_z_clearance(Z_CLEARANCE_BETWEEN_PROBES); set_message_with_feedback(GET_TEXT(MSG_EDITING_STOPPED)); } @@ -1002,14 +966,11 @@ save_ubl_active_state_and_disable(); LCD_MESSAGEPGM(MSG_UBL_FINE_TUNE_MESH); - #if HAS_LCD_MENU - ui.capture(); // Take over control of the LCD encoder - #endif - do_blocking_move_to_xy_z(pos, Z_CLEARANCE_BETWEEN_PROBES); // Move to the given XY with probe clearance + ui.capture(); // Take over control of the LCD encoder - #if ENABLED(UBL_MESH_EDIT_MOVES_Z) - do_blocking_move_to_z(h_offset); // Move Z to the given 'H' offset - #endif + do_blocking_move_to_xy_z(pos, Z_CLEARANCE_BETWEEN_PROBES); // Move to the given XY with probe clearance + + TERN_(UBL_MESH_EDIT_MOVES_Z, do_blocking_move_to_z(h_offset)); // Move Z to the given 'H' offset MeshFlags done_flags{0}; const xy_int8_t &lpos = location.pos; @@ -1030,14 +991,16 @@ do_blocking_move_to(raw); // Move the nozzle to the edit point with probe clearance - #if ENABLED(UBL_MESH_EDIT_MOVES_Z) - do_blocking_move_to_z(h_offset); // Move Z to the given 'H' offset before editing - #endif + TERN_(UBL_MESH_EDIT_MOVES_Z, do_blocking_move_to_z(h_offset)); // Move Z to the given 'H' offset before editing KEEPALIVE_STATE(PAUSED_FOR_USER); if (do_ubl_mesh_map) display_map(g29_map_type); // Display the current point + #if IS_TFTGLCD_PANEL + ui.ubl_plot(lpos.x, lpos.y); // update plot screen + #endif + ui.refresh(); float new_z = z_values[lpos.x][lpos.y]; @@ -1046,31 +1009,29 @@ lcd_mesh_edit_setup(new_z); + SET_SOFT_ENDSTOP_LOOSE(true); + do { - new_z = lcd_mesh_edit(); - #if ENABLED(UBL_MESH_EDIT_MOVES_Z) - do_blocking_move_to_z(h_offset + new_z); // Move the nozzle as the point is edited - #endif idle(); + new_z = lcd_mesh_edit(); + TERN_(UBL_MESH_EDIT_MOVES_Z, do_blocking_move_to_z(h_offset + new_z)); // Move the nozzle as the point is edited SERIAL_FLUSH(); // Prevent host M105 buffer overrun. } while (!ui.button_pressed()); + SET_SOFT_ENDSTOP_LOOSE(false); + if (!lcd_map_control) ui.return_to_status(); // Just editing a single point? Return to status if (click_and_hold(abort_fine_tune)) break; // Button held down? Abort editing z_values[lpos.x][lpos.y] = new_z; // Save the updated Z value - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(location, new_z); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(location, new_z)); serial_delay(20); // No switch noise ui.refresh(); } while (lpos.x >= 0 && --g29_repetition_cnt > 0); - ui.release(); - if (do_ubl_mesh_map) display_map(g29_map_type); restore_ubl_active_state_and_leave(); @@ -1080,7 +1041,7 @@ SERIAL_ECHOLNPGM("Done Editing Mesh"); if (lcd_map_control) - ui.goto_screen(_lcd_ubl_output_map_lcd); + ui.goto_screen(ubl_map_screen); else ui.return_to_status(); } @@ -1090,9 +1051,7 @@ bool unified_bed_leveling::g29_parameter_parsing() { bool err_flag = false; - #if HAS_LCD_MENU - set_message_with_feedback(GET_TEXT(MSG_UBL_DOING_G29)); - #endif + TERN_(HAS_LCD_MENU, set_message_with_feedback(GET_TEXT(MSG_UBL_DOING_G29))); g29_constant = 0; g29_repetition_cnt = 0; @@ -1214,9 +1173,7 @@ ubl_state_recursion_chk++; if (ubl_state_recursion_chk != 1) { SERIAL_ECHOLNPGM("save_ubl_active_state_and_disabled() called multiple times in a row."); - #if HAS_LCD_MENU - set_message_with_feedback(GET_TEXT(MSG_UBL_SAVE_ERROR)); - #endif + TERN_(HAS_LCD_MENU, set_message_with_feedback(GET_TEXT(MSG_UBL_SAVE_ERROR))); return; } #endif @@ -1225,12 +1182,11 @@ } void unified_bed_leveling::restore_ubl_active_state_and_leave() { + TERN_(HAS_LCD_MENU, ui.release()); #if ENABLED(UBL_DEVEL_DEBUGGING) if (--ubl_state_recursion_chk) { SERIAL_ECHOLNPGM("restore_ubl_active_state_and_leave() called too many times."); - #if HAS_LCD_MENU - set_message_with_feedback(GET_TEXT(MSG_UBL_RESTORE_ERROR)); - #endif + TERN_(HAS_LCD_MENU, set_message_with_feedback(GET_TEXT(MSG_UBL_RESTORE_ERROR))); return; } #endif @@ -1243,52 +1199,46 @@ mesh_index_pair farthest { -1, -1, -99999.99 }; - for (int8_t i = 0; i < GRID_MAX_POINTS_X; i++) { - for (int8_t j = 0; j < GRID_MAX_POINTS_Y; j++) { + GRID_LOOP(i, j) { + if (!isnan(z_values[i][j])) continue; // Skip valid mesh points - if (isnan(z_values[i][j])) { // Invalid mesh point? + // Skip unreachable points + if (!probe.can_reach(mesh_index_to_xpos(i), mesh_index_to_ypos(j))) + continue; - // Skip points the probe can't reach - if (!position_is_reachable_by_probe(mesh_index_to_xpos(i), mesh_index_to_ypos(j))) - continue; + found_a_NAN = true; - found_a_NAN = true; + xy_int8_t near { -1, -1 }; + float d1, d2 = 99999.9f; + GRID_LOOP(k, l) { + if (isnan(z_values[k][l])) continue; - xy_int8_t near { -1, -1 }; - float d1, d2 = 99999.9f; - for (int8_t k = 0; k < GRID_MAX_POINTS_X; k++) { - for (int8_t l = 0; l < GRID_MAX_POINTS_Y; l++) { - if (!isnan(z_values[k][l])) { - found_a_real = true; + found_a_real = true; - // Add in a random weighting factor that scrambles the probing of the - // last half of the mesh (when every unprobed mesh point is one index - // from a probed location). + // Add in a random weighting factor that scrambles the probing of the + // last half of the mesh (when every unprobed mesh point is one index + // from a probed location). - d1 = HYPOT(i - k, j - l) + (1.0f / ((millis() % 47) + 13)); + d1 = HYPOT(i - k, j - l) + (1.0f / ((millis() % 47) + 13)); - if (d1 < d2) { // Invalid mesh point (i,j) is closer to the defined point (k,l) - d2 = d1; - near.set(i, j); - } - } - } - } + if (d1 < d2) { // Invalid mesh point (i,j) is closer to the defined point (k,l) + d2 = d1; + near.set(i, j); + } + } - // - // At this point d2 should have the near defined mesh point to invalid mesh point (i,j) - // + // + // At this point d2 should have the near defined mesh point to invalid mesh point (i,j) + // - if (found_a_real && near.x >= 0 && d2 > farthest.distance) { - farthest.pos = near; // Found an invalid location farther from the defined mesh point - farthest.distance = d2; - } - } - } // for j - } // for i + if (found_a_real && near.x >= 0 && d2 > farthest.distance) { + farthest.pos = near; // Found an invalid location farther from the defined mesh point + farthest.distance = d2; + } + } // GRID_LOOP if (!found_a_real && found_a_NAN) { // if the mesh is totally unpopulated, start the probing - farthest.pos.set(GRID_MAX_POINTS_X / 2, GRID_MAX_POINTS_Y / 2); + farthest.pos.set((GRID_MAX_POINTS_X) / 2, (GRID_MAX_POINTS_Y) / 2); farthest.distance = 1; } return farthest; @@ -1304,36 +1254,34 @@ float best_so_far = 99999.99f; - for (int8_t i = 0; i < GRID_MAX_POINTS_X; i++) { - for (int8_t j = 0; j < GRID_MAX_POINTS_Y; j++) { - if ( (type == (isnan(z_values[i][j]) ? INVALID : REAL)) - || (type == SET_IN_BITMAP && !done_flags->marked(i, j)) - ) { - // Found a Mesh Point of the specified type! - const xy_pos_t mpos = { mesh_index_to_xpos(i), mesh_index_to_ypos(j) }; + GRID_LOOP(i, j) { + if ( (type == (isnan(z_values[i][j]) ? INVALID : REAL)) + || (type == SET_IN_BITMAP && !done_flags->marked(i, j)) + ) { + // Found a Mesh Point of the specified type! + const xy_pos_t mpos = { mesh_index_to_xpos(i), mesh_index_to_ypos(j) }; - // If using the probe as the reference there are some unreachable locations. - // Also for round beds, there are grid points outside the bed the nozzle can't reach. - // Prune them from the list and ignore them till the next Phase (manual nozzle probing). + // If using the probe as the reference there are some unreachable locations. + // Also for round beds, there are grid points outside the bed the nozzle can't reach. + // Prune them from the list and ignore them till the next Phase (manual nozzle probing). - if (probe_relative ? !position_is_reachable_by_probe(mpos) : !position_is_reachable(mpos)) - continue; + if (!(probe_relative ? probe.can_reach(mpos) : position_is_reachable(mpos))) + continue; - // Reachable. Check if it's the best_so_far location to the nozzle. + // Reachable. Check if it's the best_so_far location to the nozzle. - const xy_pos_t diff = current_position - mpos; - const float distance = (ref - mpos).magnitude() + diff.magnitude() * 0.1f; + const xy_pos_t diff = current_position - mpos; + const float distance = (ref - mpos).magnitude() + diff.magnitude() * 0.1f; - // factor in the distance from the current location for the normal case - // so the nozzle isn't running all over the bed. - if (distance < best_so_far) { - best_so_far = distance; // Found a closer location with the desired value type. - closest.pos.set(i, j); - closest.distance = best_so_far; - } + // factor in the distance from the current location for the normal case + // so the nozzle isn't running all over the bed. + if (distance < best_so_far) { + best_so_far = distance; // Found a closer location with the desired value type. + closest.pos.set(i, j); + closest.distance = best_so_far; } - } // for j - } // for i + } + } // GRID_LOOP return closest; } @@ -1353,9 +1301,7 @@ const float v2 = z_values[dx + xdir][dy + ydir]; if (!isnan(v2)) { z_values[x][y] = v1 < v2 ? v1 : v1 + v1 - v2; - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(x, y, z_values[x][y]); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, z_values[x][y])); return true; } } @@ -1373,7 +1319,7 @@ info3 PROGMEM = { GRID_MAX_POINTS_X - 1, 0, 0, GRID_MAX_POINTS_Y, true }; // Right side of the mesh looking left static const smart_fill_info * const info[] PROGMEM = { &info0, &info1, &info2, &info3 }; - for (uint8_t i = 0; i < COUNT(info); ++i) { + LOOP_L_N(i, COUNT(info)) { const smart_fill_info *f = (smart_fill_info*)pgm_read_ptr(&info[i]); const int8_t sx = pgm_read_byte(&f->sx), sy = pgm_read_byte(&f->sy), ex = pgm_read_byte(&f->ex), ey = pgm_read_byte(&f->ey); @@ -1419,9 +1365,7 @@ if (do_3_pt_leveling) { SERIAL_ECHOLNPGM("Tilting mesh (1/3)"); - #if HAS_DISPLAY - ui.status_printf_P(0, PSTR(S_FMT " 1/3"), GET_TEXT(MSG_LCD_TILTING_MESH)); - #endif + TERN_(HAS_DISPLAY, ui.status_printf_P(0, PSTR(S_FMT " 1/3"), GET_TEXT(MSG_LCD_TILTING_MESH))); measured_z = probe.probe_at_point(points[0], PROBE_PT_RAISE, g29_verbose_level); if (isnan(measured_z)) @@ -1440,9 +1384,7 @@ if (!abort_flag) { SERIAL_ECHOLNPGM("Tilting mesh (2/3)"); - #if HAS_DISPLAY - ui.status_printf_P(0, PSTR(S_FMT " 2/3"), GET_TEXT(MSG_LCD_TILTING_MESH)); - #endif + TERN_(HAS_DISPLAY, ui.status_printf_P(0, PSTR(S_FMT " 2/3"), GET_TEXT(MSG_LCD_TILTING_MESH))); measured_z = probe.probe_at_point(points[1], PROBE_PT_RAISE, g29_verbose_level); #ifdef VALIDATE_MESH_TILT @@ -1462,9 +1404,7 @@ if (!abort_flag) { SERIAL_ECHOLNPGM("Tilting mesh (3/3)"); - #if HAS_DISPLAY - ui.status_printf_P(0, PSTR(S_FMT " 3/3"), GET_TEXT(MSG_LCD_TILTING_MESH)); - #endif + TERN_(HAS_DISPLAY, ui.status_printf_P(0, PSTR(S_FMT " 3/3"), GET_TEXT(MSG_LCD_TILTING_MESH))); measured_z = probe.probe_at_point(points[2], PROBE_PT_STOW, g29_verbose_level); #ifdef VALIDATE_MESH_TILT @@ -1483,9 +1423,7 @@ } probe.stow(); - #ifdef Z_AFTER_PROBING - probe.move_z_after_probing(); - #endif + probe.move_z_after_probing(); if (abort_flag) { SERIAL_ECHOLNPGM("?Error probing point. Aborting operation."); @@ -1496,19 +1434,18 @@ bool zig_zag = false; - uint16_t total_points = g29_grid_size * g29_grid_size, point_num = 1; + const uint16_t total_points = sq(g29_grid_size); + uint16_t point_num = 1; xy_pos_t rpos; - for (uint8_t ix = 0; ix < g29_grid_size; ix++) { + LOOP_L_N(ix, g29_grid_size) { rpos.x = x_min + ix * dx; - for (int8_t iy = 0; iy < g29_grid_size; iy++) { + LOOP_L_N(iy, g29_grid_size) { rpos.y = y_min + dy * (zig_zag ? g29_grid_size - 1 - iy : iy); if (!abort_flag) { SERIAL_ECHOLNPAIR("Tilting mesh point ", point_num, "/", total_points, "\n"); - #if HAS_DISPLAY - ui.status_printf_P(0, PSTR(S_FMT " %i/%i"), GET_TEXT(MSG_LCD_TILTING_MESH), point_num, total_points); - #endif + TERN_(HAS_DISPLAY, ui.status_printf_P(0, PSTR(S_FMT " %i/%i"), GET_TEXT(MSG_LCD_TILTING_MESH), point_num, total_points)); measured_z = probe.probe_at_point(rpos, parser.seen('E') ? PROBE_PT_STOW : PROBE_PT_RAISE, g29_verbose_level); // TODO: Needs error handling @@ -1547,9 +1484,7 @@ } } probe.stow(); - #ifdef Z_AFTER_PROBING - probe.move_z_after_probing(); - #endif + probe.move_z_after_probing(); if (abort_flag || finish_incremental_LSF(&lsf_results)) { SERIAL_ECHOPGM("Could not complete LSF!"); @@ -1569,39 +1504,35 @@ matrix_3x3 rotation = matrix_3x3::create_look_at(vector_3(lsf_results.A, lsf_results.B, 1)); - for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) { - for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) { - float mx = mesh_index_to_xpos(i), - my = mesh_index_to_ypos(j), - mz = z_values[i][j]; - - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOPAIR_F("before rotation = [", mx, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(my, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(mz, 7); - DEBUG_ECHOPGM("] ---> "); - DEBUG_DELAY(20); - } - - apply_rotation_xyz(rotation, mx, my, mz); + GRID_LOOP(i, j) { + float mx = mesh_index_to_xpos(i), + my = mesh_index_to_ypos(j), + mz = z_values[i][j]; + + if (DEBUGGING(LEVELING)) { + DEBUG_ECHOPAIR_F("before rotation = [", mx, 7); + DEBUG_CHAR(','); + DEBUG_ECHO_F(my, 7); + DEBUG_CHAR(','); + DEBUG_ECHO_F(mz, 7); + DEBUG_ECHOPGM("] ---> "); + DEBUG_DELAY(20); + } - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOPAIR_F("after rotation = [", mx, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(my, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(mz, 7); - DEBUG_ECHOLNPGM("]"); - DEBUG_DELAY(20); - } + apply_rotation_xyz(rotation, mx, my, mz); - z_values[i][j] = mz - lsf_results.D; - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(i, j, z_values[i][j]); - #endif + if (DEBUGGING(LEVELING)) { + DEBUG_ECHOPAIR_F("after rotation = [", mx, 7); + DEBUG_CHAR(','); + DEBUG_ECHO_F(my, 7); + DEBUG_CHAR(','); + DEBUG_ECHO_F(mz, 7); + DEBUG_ECHOLNPGM("]"); + DEBUG_DELAY(20); } + + z_values[i][j] = mz - lsf_results.D; + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(i, j, z_values[i][j])); } if (DEBUGGING(LEVELING)) { @@ -1628,7 +1559,7 @@ * numbers for those locations should be 0. */ #ifdef VALIDATE_MESH_TILT - auto d_from = []() { DEBUG_ECHOPGM("D from "); }; + auto d_from = []{ DEBUG_ECHOPGM("D from "); }; auto normed = [&](const xy_pos_t &pos, const float &zadd) { return normal.x * pos.x + normal.y * pos.y + zadd; }; @@ -1661,7 +1592,7 @@ // being extrapolated so that nearby points will have greater influence on // the point being extrapolated. Then extrapolate the mesh point from WLSF. - static_assert(GRID_MAX_POINTS_Y <= 16, "GRID_MAX_POINTS_Y too big"); + static_assert((GRID_MAX_POINTS_Y) <= 16, "GRID_MAX_POINTS_Y too big"); uint16_t bitmap[GRID_MAX_POINTS_X] = { 0 }; struct linear_fit_data lsf_results; @@ -1669,23 +1600,20 @@ const float weight_scaled = weight_factor * _MAX(MESH_X_DIST, MESH_Y_DIST); - for (uint8_t jx = 0; jx < GRID_MAX_POINTS_X; jx++) - for (uint8_t jy = 0; jy < GRID_MAX_POINTS_Y; jy++) - if (!isnan(z_values[jx][jy])) - SBI(bitmap[jx], jy); + GRID_LOOP(jx, jy) if (!isnan(z_values[jx][jy])) SBI(bitmap[jx], jy); xy_pos_t ppos; - for (uint8_t ix = 0; ix < GRID_MAX_POINTS_X; ix++) { + LOOP_L_N(ix, GRID_MAX_POINTS_X) { ppos.x = mesh_index_to_xpos(ix); - for (uint8_t iy = 0; iy < GRID_MAX_POINTS_Y; iy++) { + LOOP_L_N(iy, GRID_MAX_POINTS_Y) { ppos.y = mesh_index_to_ypos(iy); if (isnan(z_values[ix][iy])) { // undefined mesh point at (ppos.x,ppos.y), compute weighted LSF from original valid mesh points. incremental_LSF_reset(&lsf_results); xy_pos_t rpos; - for (uint8_t jx = 0; jx < GRID_MAX_POINTS_X; jx++) { + LOOP_L_N(jx, GRID_MAX_POINTS_X) { rpos.x = mesh_index_to_xpos(jx); - for (uint8_t jy = 0; jy < GRID_MAX_POINTS_Y; jy++) { + LOOP_L_N(jy, GRID_MAX_POINTS_Y) { if (TEST(bitmap[jx], jy)) { rpos.y = mesh_index_to_ypos(jy); const float rz = z_values[jx][jy], @@ -1700,9 +1628,7 @@ } const float ez = -lsf_results.D - lsf_results.A * ppos.x - lsf_results.B * ppos.y; z_values[ix][iy] = ez; - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(ix, iy, z_values[ix][iy]); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(ix, iy, z_values[ix][iy])); idle(); // housekeeping } } @@ -1747,7 +1673,7 @@ SERIAL_ECHOLNPAIR("MESH_Y_DIST ", MESH_Y_DIST); serial_delay(50); SERIAL_ECHOPGM("X-Axis Mesh Points at: "); - for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) { + LOOP_L_N(i, GRID_MAX_POINTS_X) { SERIAL_ECHO_F(LOGICAL_X_POSITION(mesh_index_to_xpos(i)), 3); SERIAL_ECHOPGM(" "); serial_delay(25); @@ -1755,7 +1681,7 @@ SERIAL_EOL(); SERIAL_ECHOPGM("Y-Axis Mesh Points at: "); - for (uint8_t i = 0; i < GRID_MAX_POINTS_Y; i++) { + LOOP_L_N(i, GRID_MAX_POINTS_Y) { SERIAL_ECHO_F(LOGICAL_Y_POSITION(mesh_index_to_ypos(i)), 3); SERIAL_ECHOPGM(" "); serial_delay(25); @@ -1763,8 +1689,9 @@ SERIAL_EOL(); #if HAS_KILL - SERIAL_ECHOLNPAIR("Kill pin on :", int(KILL_PIN), " state:", READ(KILL_PIN)); + SERIAL_ECHOLNPAIR("Kill pin on :", int(KILL_PIN), " state:", int(kill_state())); #endif + SERIAL_EOL(); serial_delay(50); @@ -1840,13 +1767,10 @@ SERIAL_ECHOLNPAIR("Subtracting mesh in slot ", g29_storage_slot, " from current mesh."); - for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) - for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) { - z_values[x][y] -= tmp_z_values[x][y]; - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(x, y, z_values[x][y]); - #endif - } + GRID_LOOP(x, y) { + z_values[x][y] -= tmp_z_values[x][y]; + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, z_values[x][y])); + } } #endif // UBL_DEVEL_DEBUGGING diff --git a/Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp b/Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp index 536410824069..010b5951be5f 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp +++ b/Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #include "../../../inc/MarlinConfig.h" @@ -236,9 +236,7 @@ } /** - * * Generic case of a line crossing both X and Y Mesh lines. - * */ xy_int8_t cnt = (istart - iend).ABS(); diff --git a/Marlin/src/feature/binary_protocol.cpp b/Marlin/src/feature/binary_stream.cpp similarity index 90% rename from Marlin/src/feature/binary_protocol.cpp rename to Marlin/src/feature/binary_stream.cpp index e555c0c46329..81e110339bda 100644 --- a/Marlin/src/feature/binary_protocol.cpp +++ b/Marlin/src/feature/binary_stream.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -25,7 +25,7 @@ #if ENABLED(BINARY_FILE_TRANSFER) #include "../sd/cardreader.h" -#include "binary_protocol.h" +#include "binary_stream.h" char* SDFileTransferProtocol::Packet::Open::data = nullptr; size_t SDFileTransferProtocol::data_waiting, SDFileTransferProtocol::transfer_timeout, SDFileTransferProtocol::idle_timeout; @@ -33,4 +33,4 @@ bool SDFileTransferProtocol::transfer_active, SDFileTransferProtocol::dummy_tran BinaryStream binaryStream[NUM_SERIAL]; -#endif // BINARY_FILE_TRANSFER +#endif diff --git a/Marlin/src/feature/binary_protocol.h b/Marlin/src/feature/binary_stream.h similarity index 95% rename from Marlin/src/feature/binary_protocol.h rename to Marlin/src/feature/binary_stream.h index 978d6a2c0217..ba5d4e8bceda 100644 --- a/Marlin/src/feature/binary_protocol.h +++ b/Marlin/src/feature/binary_stream.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -32,7 +32,7 @@ inline bool bs_serial_data_available(const uint8_t index) { switch (index) { case 0: return MYSERIAL0.available(); - #if NUM_SERIAL > 1 + #if HAS_MULTI_SERIAL case 1: return MYSERIAL1.available(); #endif } @@ -42,7 +42,7 @@ inline bool bs_serial_data_available(const uint8_t index) { inline int bs_read_serial(const uint8_t index) { switch (index) { case 0: return MYSERIAL0.read(); - #if NUM_SERIAL > 1 + #if HAS_MULTI_SERIAL case 1: return MYSERIAL1.read(); #endif } @@ -51,7 +51,12 @@ inline int bs_read_serial(const uint8_t index) { #if ENABLED(BINARY_STREAM_COMPRESSION) static heatshrink_decoder hsd; - static uint8_t decode_buffer[512] = {}; + #ifdef BOTH(ARDUINO_ARCH_STM32F1, SDIO_SUPPORT) + // STM32 requires a word-aligned buffer for SD card transfers via DMA + static __attribute__((aligned(sizeof(size_t)))) uint8_t decode_buffer[512] = {}; + #else + static uint8_t decode_buffer[512] = {}; + #endif #endif class SDFileTransferProtocol { @@ -82,9 +87,7 @@ class SDFileTransferProtocol { } transfer_active = true; data_waiting = 0; - #if ENABLED(BINARY_STREAM_COMPRESSION) - heatshrink_decoder_reset(&hsd); - #endif + TERN_(BINARY_STREAM_COMPRESSION, heatshrink_decoder_reset(&hsd)); return true; } @@ -127,9 +130,7 @@ class SDFileTransferProtocol { card.closefile(); card.release(); } - #if ENABLED(BINARY_STREAM_COMPRESSION) - heatshrink_decoder_finish(&hsd); - #endif + TERN_(BINARY_STREAM_COMPRESSION, heatshrink_decoder_finish(&hsd)); transfer_active = false; return true; } @@ -139,9 +140,7 @@ class SDFileTransferProtocol { card.closefile(); card.removeFile(card.filename); card.release(); - #if ENABLED(BINARY_STREAM_COMPRESSION) - heatshrink_decoder_finish(&hsd); - #endif + TERN_(BINARY_STREAM_COMPRESSION, heatshrink_decoder_finish(&hsd)); } transfer_active = false; return; @@ -447,9 +446,9 @@ class BinaryStream { } void dispatch() { - switch(static_cast(packet.header.protocol())) { + switch (static_cast(packet.header.protocol())) { case Protocol::CONTROL: - switch(static_cast(packet.header.type())) { + switch (static_cast(packet.header.type())) { case ProtocolControl::CLOSE: // revert back to ASCII mode card.flag.binary_mode = false; break; diff --git a/Marlin/src/feature/bltouch.cpp b/Marlin/src/feature/bltouch.cpp index 77d85c4195f4..d6b1f99c16b9 100644 --- a/Marlin/src/feature/bltouch.cpp +++ b/Marlin/src/feature/bltouch.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -73,20 +73,12 @@ void BLTouch::init(const bool set_voltage/*=false*/) { ); } - const bool should_set = last_written_mode != (false - #if ENABLED(BLTOUCH_SET_5V_MODE) - || true - #endif - ); + const bool should_set = last_written_mode != ENABLED(BLTOUCH_SET_5V_MODE); #endif if (should_set && set_voltage) - mode_conv_proc((false - #if ENABLED(BLTOUCH_SET_5V_MODE) - || true - #endif - )); + mode_conv_proc(ENABLED(BLTOUCH_SET_5V_MODE)); } void BLTouch::clear() { @@ -132,9 +124,7 @@ bool BLTouch::deploy_proc() { } // One of the recommended ANTClabs ways to probe, using SW MODE - #if ENABLED(BLTOUCH_FORCE_SW_MODE) - _set_SW_mode(); - #endif + TERN_(BLTOUCH_FORCE_SW_MODE, _set_SW_mode()); // Now the probe is ready to issue a 10ms pulse when the pin goes up. // The trigger STOW (see motion.cpp for example) will pull up the probes pin as soon as the pulse diff --git a/Marlin/src/feature/bltouch.h b/Marlin/src/feature/bltouch.h index af75fb8b2972..40685af1b357 100644 --- a/Marlin/src/feature/bltouch.h +++ b/Marlin/src/feature/bltouch.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -26,9 +26,17 @@ // BLTouch commands are sent as servo angles typedef unsigned char BLTCommand; -#define BLTOUCH_DEPLOY 10 +#if ENABLED(CREALITY_TOUCH) + #define STOW_ALARM false + #define BLTOUCH_DEPLOY 170 + #define BLTOUCH_STOW 20 +#else + #define STOW_ALARM true + #define BLTOUCH_DEPLOY 10 + #define BLTOUCH_STOW 90 +#endif + #define BLTOUCH_SW_MODE 60 -#define BLTOUCH_STOW 90 #define BLTOUCH_SELFTEST 120 #define BLTOUCH_MODE_STORE 130 #define BLTOUCH_5V_MODE 140 @@ -95,7 +103,7 @@ class BLTouch { private: FORCE_INLINE static bool _deploy_query_alarm() { return command(BLTOUCH_DEPLOY, BLTOUCH_DEPLOY_DELAY); } - FORCE_INLINE static bool _stow_query_alarm() { return command(BLTOUCH_STOW, BLTOUCH_STOW_DELAY); } + FORCE_INLINE static bool _stow_query_alarm() { return command(BLTOUCH_STOW, BLTOUCH_STOW_DELAY) == STOW_ALARM; } static void clear(); static bool command(const BLTCommand cmd, const millis_t &ms); diff --git a/Marlin/src/feature/cancel_object.cpp b/Marlin/src/feature/cancel_object.cpp index e2ee6452151d..16f876f13686 100644 --- a/Marlin/src/feature/cancel_object.cpp +++ b/Marlin/src/feature/cancel_object.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #include "../inc/MarlinConfig.h" @@ -45,7 +45,7 @@ void CancelObject::set_active_object(const int8_t obj) { #if HAS_DISPLAY if (active_object >= 0) - ui.status_printf_P(0, PSTR(S_FMT " %i"), GET_TEXT(MSG_PRINTING_OBJECT), int(active_object + 1)); + ui.status_printf_P(0, PSTR(S_FMT " %i"), GET_TEXT(MSG_PRINTING_OBJECT), int(active_object)); else ui.reset_status(); #endif diff --git a/Marlin/src/feature/cancel_object.h b/Marlin/src/feature/cancel_object.h index 41bbfb70fcfc..1d2d77f20334 100644 --- a/Marlin/src/feature/cancel_object.h +++ b/Marlin/src/feature/cancel_object.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/feature/caselight.cpp b/Marlin/src/feature/caselight.cpp index a135cac418d2..8a128bb12def 100644 --- a/Marlin/src/feature/caselight.cpp +++ b/Marlin/src/feature/caselight.cpp @@ -16,20 +16,23 @@ * 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 . + * along with this program. If not, see . * */ #include "../inc/MarlinConfig.h" -#if HAS_CASE_LIGHT +#if ENABLED(CASE_LIGHT_ENABLE) -uint8_t case_light_brightness = CASE_LIGHT_DEFAULT_BRIGHTNESS; -bool case_light_on = CASE_LIGHT_DEFAULT_ON; +#include "caselight.h" + +CaseLight caselight; + +uint8_t CaseLight::brightness = CASE_LIGHT_DEFAULT_BRIGHTNESS; +bool CaseLight::on = CASE_LIGHT_DEFAULT_ON; #if ENABLED(CASE_LIGHT_USE_NEOPIXEL) - #include "leds/leds.h" - LEDColor case_light_color = + LEDColor CaseLight::color = #ifdef CASE_LIGHT_NEOPIXEL_COLOR CASE_LIGHT_NEOPIXEL_COLOR #else @@ -38,34 +41,33 @@ bool case_light_on = CASE_LIGHT_DEFAULT_ON; ; #endif -/** - * The following are needed because ARM chips ignore a "WRITE(CASE_LIGHT_PIN,x)" command to the pins that - * are directly controlled by the PWM module. In order to turn them off the brightness level needs to be - * set to off. Since we can't use the pwm register to save the last brightness level we need a variable - * to save it. - */ -uint8_t case_light_brightness_sav; // saves brighness info so can restore when "M355 S1" received -bool case_light_arg_flag; // flag to notify if S or P argument type - #ifndef INVERT_CASE_LIGHT #define INVERT_CASE_LIGHT false #endif -void update_case_light() { +void CaseLight::update(const bool sflag) { + /** + * The brightness_sav (and sflag) is needed because ARM chips ignore + * a "WRITE(CASE_LIGHT_PIN,x)" command to the pins that are directly + * controlled by the PWM module. In order to turn them off the brightness + * level needs to be set to OFF. Since we can't use the PWM register to + * save the last brightness level we need a variable to save it. + */ + static uint8_t brightness_sav; // Save brightness info for restore on "M355 S1" - if (!(case_light_arg_flag && !case_light_on)) - case_light_brightness_sav = case_light_brightness; // save brightness except if this is an S0 argument - if (case_light_arg_flag && case_light_on) - case_light_brightness = case_light_brightness_sav; // restore last brightens if this is an S1 argument + if (on || !sflag) + brightness_sav = brightness; // Save brightness except for M355 S0 + if (sflag && on) + brightness = brightness_sav; // Restore last brightness for M355 S1 #if ENABLED(CASE_LIGHT_USE_NEOPIXEL) || DISABLED(CASE_LIGHT_NO_BRIGHTNESS) - const uint8_t i = case_light_on ? case_light_brightness : 0, n10ct = INVERT_CASE_LIGHT ? 255 - i : i; + const uint8_t i = on ? brightness : 0, n10ct = INVERT_CASE_LIGHT ? 255 - i : i; #endif #if ENABLED(CASE_LIGHT_USE_NEOPIXEL) leds.set_color( - MakeLEDColor(case_light_color.r, case_light_color.g, case_light_color.b, case_light_color.w, n10ct), + MakeLEDColor(color.r, color.g, color.b, color.w, n10ct), false ); @@ -83,11 +85,11 @@ void update_case_light() { else #endif { - const bool s = case_light_on ? !INVERT_CASE_LIGHT : INVERT_CASE_LIGHT; + const bool s = on ? !INVERT_CASE_LIGHT : INVERT_CASE_LIGHT; WRITE(CASE_LIGHT_PIN, s ? HIGH : LOW); } #endif // !CASE_LIGHT_USE_NEOPIXEL } -#endif // HAS_CASE_LIGHT +#endif // CASE_LIGHT_ENABLE diff --git a/Marlin/src/feature/caselight.h b/Marlin/src/feature/caselight.h index de77f0696b57..9d1e76da26ba 100644 --- a/Marlin/src/feature/caselight.h +++ b/Marlin/src/feature/caselight.h @@ -16,14 +16,30 @@ * 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 . + * along with this program. If not, see . * */ #pragma once -extern uint8_t case_light_brightness; -extern bool case_light_on; -extern uint8_t case_light_brightness_sav; // saves brighness info when case_light_on is false -extern bool case_light_arg_flag; // flag to notify if S or P argument type +#include "../inc/MarlinConfigPre.h" -void update_case_light(); +#if ENABLED(CASE_LIGHT_USE_NEOPIXEL) + #include "leds/leds.h" +#endif + +class CaseLight { +public: + static uint8_t brightness; + static bool on; + + static void update(const bool sflag); + static inline void update_brightness() { update(false); } + static inline void update_enabled() { update(true); } + +private: + #if ENABLED(CASE_LIGHT_USE_NEOPIXEL) + static LEDColor color; + #endif +}; + +extern CaseLight caselight; diff --git a/Marlin/src/feature/closedloop.cpp b/Marlin/src/feature/closedloop.cpp index b777243481ca..8a97f0c0cd7b 100644 --- a/Marlin/src/feature/closedloop.cpp +++ b/Marlin/src/feature/closedloop.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #include "../inc/MarlinConfig.h" @@ -29,12 +29,14 @@ #include "closedloop.h" -void init_closedloop() { +ClosedLoop closedloop; + +void ClosedLoop::init() { OUT_WRITE(CLOSED_LOOP_ENABLE_PIN, LOW); SET_INPUT_PULLUP(CLOSED_LOOP_MOVE_COMPLETE_PIN); } -void set_closedloop(const byte val) { +void ClosedLoop::set(const byte val) { OUT_WRITE(CLOSED_LOOP_ENABLE_PIN, val); } diff --git a/Marlin/src/feature/closedloop.h b/Marlin/src/feature/closedloop.h index 7e5594447d0e..e03400c35c7b 100644 --- a/Marlin/src/feature/closedloop.h +++ b/Marlin/src/feature/closedloop.h @@ -16,10 +16,17 @@ * 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 . + * along with this program. If not, see . * */ #pragma once -void init_closedloop(); -void set_closedloop(const byte val); +class ClosedLoop { +public: + static void init(); + static void set(const byte val); +}; + +extern ClosedLoop closedloop; + +#define CLOSED_LOOP_WAITING() (READ(CLOSED_LOOP_ENABLE_PIN) && !READ(CLOSED_LOOP_MOVE_COMPLETE_PIN)) diff --git a/Marlin/src/feature/controllerfan.cpp b/Marlin/src/feature/controllerfan.cpp index b9d8c394609b..fa5a86b0194e 100644 --- a/Marlin/src/feature/controllerfan.cpp +++ b/Marlin/src/feature/controllerfan.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -24,60 +24,71 @@ #if ENABLED(USE_CONTROLLER_FAN) +#include "controllerfan.h" #include "../module/stepper/indirection.h" #include "../module/temperature.h" -uint8_t controllerfan_speed; +ControllerFan controllerFan; -void controllerfan_update() { - static millis_t lastMotorOn = 0, // Last time a motor was turned on +uint8_t ControllerFan::speed; + +#if ENABLED(CONTROLLER_FAN_EDITABLE) + controllerFan_settings_t ControllerFan::settings; // {0} +#endif + +void ControllerFan::setup() { + SET_OUTPUT(CONTROLLER_FAN_PIN); + init(); +} + +void ControllerFan::set_fan_speed(const uint8_t s) { + speed = s < (CONTROLLERFAN_SPEED_MIN) ? 0 : s; // Fan OFF below minimum +} + +void ControllerFan::update() { + static millis_t lastMotorOn = 0, // Last time a motor was turned on nextMotorCheck = 0; // Last time the state was checked const millis_t ms = millis(); if (ELAPSED(ms, nextMotorCheck)) { nextMotorCheck = ms + 2500UL; // Not a time critical function, so only check every 2.5s - const bool xory = X_ENABLE_READ() == bool(X_ENABLE_ON) || Y_ENABLE_READ() == bool(Y_ENABLE_ON); + #define MOTOR_IS_ON(A,B) (A##_ENABLE_READ() == bool(B##_ENABLE_ON)) + #define _OR_ENABLED_E(N) || MOTOR_IS_ON(E##N,E) + + const bool motor_on = ( + ( DISABLED(CONTROLLER_FAN_IGNORE_Z) && + ( MOTOR_IS_ON(Z,Z) + || TERN0(HAS_Z2_ENABLE, MOTOR_IS_ON(Z2,Z)) + || TERN0(HAS_Z3_ENABLE, MOTOR_IS_ON(Z3,Z)) + || TERN0(HAS_Z4_ENABLE, MOTOR_IS_ON(Z4,Z)) + ) + ) || ( + DISABLED(CONTROLLER_FAN_USE_Z_ONLY) && + ( MOTOR_IS_ON(X,X) || MOTOR_IS_ON(Y,Y) + || TERN0(HAS_X2_ENABLE, MOTOR_IS_ON(X2,X)) + || TERN0(HAS_Y2_ENABLE, MOTOR_IS_ON(Y2,Y)) + #if E_STEPPERS + REPEAT(E_STEPPERS, _OR_ENABLED_E) + #endif + ) + ) + ); - // If any of the drivers or the bed are enabled... - if (xory || Z_ENABLE_READ() == bool(Z_ENABLE_ON) - #if HAS_HEATED_BED - || thermalManager.temp_bed.soft_pwm_amount > 0 - #endif - #if HAS_X2_ENABLE - || X2_ENABLE_READ() == bool(X_ENABLE_ON) - #endif - #if HAS_Y2_ENABLE - || Y2_ENABLE_READ() == bool(Y_ENABLE_ON) - #endif - #if HAS_Z2_ENABLE - || Z2_ENABLE_READ() == bool(Z_ENABLE_ON) - #endif - #if HAS_Z3_ENABLE - || Z3_ENABLE_READ() == bool(Z_ENABLE_ON) - #endif - #if HAS_Z4_ENABLE - || Z4_ENABLE_READ() == bool(Z_ENABLE_ON) - #endif - #if E_STEPPERS - #define _OR_ENABLED_E(N) || E##N##_ENABLE_READ() == bool(E_ENABLE_ON) - REPEAT(E_STEPPERS, _OR_ENABLED_E) - #endif - ) { + // If any of the drivers or the heated bed are enabled... + if (motor_on || TERN0(HAS_HEATED_BED, thermalManager.temp_bed.soft_pwm_amount > 0)) lastMotorOn = ms; //... set time to NOW so the fan will turn on - } - // Fan off if no steppers have been enabled for CONTROLLERFAN_SECS seconds - controllerfan_speed = (!lastMotorOn || ELAPSED(ms, lastMotorOn + (CONTROLLERFAN_SECS) * 1000UL)) ? 0 : ( - #ifdef CONTROLLERFAN_SPEED_Z_ONLY - xory ? CONTROLLERFAN_SPEED : CONTROLLERFAN_SPEED_Z_ONLY - #else - CONTROLLERFAN_SPEED - #endif + // Fan Settings. Set fan > 0: + // - If AutoMode is on and steppers have been enabled for CONTROLLERFAN_IDLE_TIME seconds. + // - If System is on idle and idle fan speed settings is activated. + set_fan_speed( + settings.auto_mode && lastMotorOn && PENDING(ms, lastMotorOn + SEC_TO_MS(settings.duration)) + ? settings.active_speed : settings.idle_speed ); // Allow digital or PWM fan output (see M42 handling) - WRITE(CONTROLLER_FAN_PIN, controllerfan_speed); - analogWrite(pin_t(CONTROLLER_FAN_PIN), controllerfan_speed); + WRITE(CONTROLLER_FAN_PIN, speed); + analogWrite(pin_t(CONTROLLER_FAN_PIN), speed); } } diff --git a/Marlin/src/feature/controllerfan.h b/Marlin/src/feature/controllerfan.h index f2facc288f30..d1d39f21f3f2 100644 --- a/Marlin/src/feature/controllerfan.h +++ b/Marlin/src/feature/controllerfan.h @@ -16,9 +16,57 @@ * 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 . + * along with this program. If not, see . * */ #pragma once -void controllerfan_update(); +#include "../inc/MarlinConfigPre.h" + +typedef struct { + uint8_t active_speed, // 0-255 (fullspeed); Speed with enabled stepper motors + idle_speed; // 0-255 (fullspeed); Speed after idle period with all motors are disabled + uint16_t duration; // Duration in seconds for the fan to run after all motors are disabled + bool auto_mode; // Default true +} controllerFan_settings_t; + +#ifndef CONTROLLERFAN_SPEED_ACTIVE + #define CONTROLLERFAN_SPEED_ACTIVE 255 +#endif +#ifndef CONTROLLERFAN_SPEED_IDLE + #define CONTROLLERFAN_SPEED_IDLE 0 +#endif +#ifndef CONTROLLERFAN_IDLE_TIME + #define CONTROLLERFAN_IDLE_TIME 60 +#endif + +static constexpr controllerFan_settings_t controllerFan_defaults = { + CONTROLLERFAN_SPEED_ACTIVE, + CONTROLLERFAN_SPEED_IDLE, + CONTROLLERFAN_IDLE_TIME, + true +}; + +#if ENABLED(USE_CONTROLLER_FAN) + +class ControllerFan { + private: + static uint8_t speed; + static void set_fan_speed(const uint8_t s); + + public: + #if ENABLED(CONTROLLER_FAN_EDITABLE) + static controllerFan_settings_t settings; + #else + static const controllerFan_settings_t constexpr &settings = controllerFan_defaults; + #endif + static inline bool state() { return speed > 0; } + static inline void init() { reset(); } + static inline void reset() { TERN_(CONTROLLER_FAN_EDITABLE, settings = controllerFan_defaults); } + static void setup(); + static void update(); +}; + +extern ControllerFan controllerFan; + +#endif diff --git a/Marlin/src/feature/dac/dac_dac084s085.cpp b/Marlin/src/feature/dac/dac_dac084s085.cpp index a07dc071dd43..82d17fa28f07 100644 --- a/Marlin/src/feature/dac/dac_dac084s085.cpp +++ b/Marlin/src/feature/dac/dac_dac084s085.cpp @@ -21,7 +21,7 @@ void dac084s085::begin() { // All SPI chip-select HIGH SET_OUTPUT(DAC0_SYNC); - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER SET_OUTPUT(DAC1_SYNC); #endif cshigh(); @@ -38,7 +38,7 @@ void dac084s085::begin() { spiSend(SPI_CHAN_DAC, externalDac_buf, COUNT(externalDac_buf)); WRITE(DAC0_SYNC, HIGH); - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER //init Piggy DAC DELAY_US(2); WRITE(DAC1_SYNC, LOW); @@ -86,7 +86,7 @@ void dac084s085::setValue(const uint8_t channel, const uint8_t value) { void dac084s085::cshigh() { WRITE(DAC0_SYNC, HIGH); - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER WRITE(DAC1_SYNC, HIGH); #endif WRITE(SPI_EEPROM1_CS, HIGH); diff --git a/Marlin/src/feature/dac/dac_dac084s085.h b/Marlin/src/feature/dac/dac_dac084s085.h index cccc9cbd4545..5be0129fc9e9 100644 --- a/Marlin/src/feature/dac/dac_dac084s085.h +++ b/Marlin/src/feature/dac/dac_dac084s085.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/feature/dac/dac_mcp4728.cpp b/Marlin/src/feature/dac/dac_mcp4728.cpp index 39f873f0cb82..81c465cf29e4 100644 --- a/Marlin/src/feature/dac/dac_mcp4728.cpp +++ b/Marlin/src/feature/dac/dac_mcp4728.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -24,33 +24,35 @@ * mcp4728.cpp - Arduino library for MicroChip MCP4728 I2C D/A converter * * For implementation details, please take a look at the datasheet: - * http://ww1.microchip.com/downloads/en/DeviceDoc/22187a.pdf + * https://ww1.microchip.com/downloads/en/DeviceDoc/22187a.pdf * * For discussion and feedback, please go to: - * http://arduino.cc/forum/index.php/topic,51842.0.html + * https://forum.arduino.cc/index.php/topic,51842.0.html */ #include "../../inc/MarlinConfig.h" -#if ENABLED(DAC_STEPPER_CURRENT) +#if ENABLED(HAS_MOTOR_CURRENT_DAC) #include "dac_mcp4728.h" -xyze_uint_t mcp4728_values; +MCP4728 mcp4728; + +xyze_uint_t dac_values; /** * Begin I2C, get current values (input register and eeprom) of mcp4728 */ -void mcp4728_init() { +void MCP4728::init() { Wire.begin(); - Wire.requestFrom(I2C_ADDRESS(DAC_DEV_ADDRESS), 24); + Wire.requestFrom(I2C_ADDRESS(DAC_DEV_ADDRESS), uint8_t(24)); while (Wire.available()) { char deviceID = Wire.read(), hiByte = Wire.read(), loByte = Wire.read(); if (!(deviceID & 0x08)) - mcp4728_values[(deviceID & 0x30) >> 4] = word((hiByte & 0x0F), loByte); + dac_values[(deviceID & 0x30) >> 4] = word((hiByte & 0x0F), loByte); } } @@ -58,9 +60,9 @@ void mcp4728_init() { * Write input resister value to specified channel using fastwrite method. * Channel : 0-3, Values : 0-4095 */ -uint8_t mcp4728_analogWrite(const uint8_t channel, const uint16_t value) { - mcp4728_values[channel] = value; - return mcp4728_fastWrite(); +uint8_t MCP4728::analogWrite(const uint8_t channel, const uint16_t value) { + dac_values[channel] = value; + return fastWrite(); } /** @@ -68,12 +70,12 @@ uint8_t mcp4728_analogWrite(const uint8_t channel, const uint16_t value) { * This will update both input register and EEPROM value * This will also write current Vref, PowerDown, Gain settings to EEPROM */ -uint8_t mcp4728_eepromWrite() { +uint8_t MCP4728::eepromWrite() { Wire.beginTransmission(I2C_ADDRESS(DAC_DEV_ADDRESS)); Wire.write(SEQWRITE); LOOP_XYZE(i) { - Wire.write(DAC_STEPPER_VREF << 7 | DAC_STEPPER_GAIN << 4 | highByte(mcp4728_values[i])); - Wire.write(lowByte(mcp4728_values[i])); + Wire.write(DAC_STEPPER_VREF << 7 | DAC_STEPPER_GAIN << 4 | highByte(dac_values[i])); + Wire.write(lowByte(dac_values[i])); } return Wire.endTransmission(); } @@ -81,7 +83,7 @@ uint8_t mcp4728_eepromWrite() { /** * Write Voltage reference setting to all input regiters */ -uint8_t mcp4728_setVref_all(const uint8_t value) { +uint8_t MCP4728::setVref_all(const uint8_t value) { Wire.beginTransmission(I2C_ADDRESS(DAC_DEV_ADDRESS)); Wire.write(VREFWRITE | (value ? 0x0F : 0x00)); return Wire.endTransmission(); @@ -89,7 +91,7 @@ uint8_t mcp4728_setVref_all(const uint8_t value) { /** * Write Gain setting to all input regiters */ -uint8_t mcp4728_setGain_all(const uint8_t value) { +uint8_t MCP4728::setGain_all(const uint8_t value) { Wire.beginTransmission(I2C_ADDRESS(DAC_DEV_ADDRESS)); Wire.write(GAINWRITE | (value ? 0x0F : 0x00)); return Wire.endTransmission(); @@ -98,16 +100,16 @@ uint8_t mcp4728_setGain_all(const uint8_t value) { /** * Return Input Register value */ -uint16_t mcp4728_getValue(const uint8_t channel) { return mcp4728_values[channel]; } +uint16_t MCP4728::getValue(const uint8_t channel) { return dac_values[channel]; } #if 0 /** * Steph: Might be useful in the future * Return Vout */ -uint16_t mcp4728_getVout(const uint8_t channel) { +uint16_t MCP4728::getVout(const uint8_t channel) { const uint32_t vref = 2048, - vOut = (vref * mcp4728_values[channel] * (_DAC_STEPPER_GAIN + 1)) / 4096; + vOut = (vref * dac_values[channel] * (_DAC_STEPPER_GAIN + 1)) / 4096; return _MIN(vOut, defaultVDD); } #endif @@ -115,15 +117,15 @@ uint16_t mcp4728_getVout(const uint8_t channel) { /** * Returns DAC values as a 0-100 percentage of drive strength */ -uint8_t mcp4728_getDrvPct(const uint8_t channel) { return uint8_t(100.0 * mcp4728_values[channel] / (DAC_STEPPER_MAX) + 0.5); } +uint8_t MCP4728::getDrvPct(const uint8_t channel) { return uint8_t(100.0 * dac_values[channel] / (DAC_STEPPER_MAX) + 0.5); } /** * Receives all Drive strengths as 0-100 percent values, updates * DAC Values array and calls fastwrite to update the DAC. */ -void mcp4728_setDrvPct(xyze_uint8_t &pct) { - mcp4728_values *= 0.01 * pct * (DAC_STEPPER_MAX); - mcp4728_fastWrite(); +void MCP4728::setDrvPct(xyze_uint8_t &pct) { + dac_values *= 0.01 * pct * (DAC_STEPPER_MAX); + fastWrite(); } /** @@ -131,11 +133,11 @@ void mcp4728_setDrvPct(xyze_uint8_t &pct) { * DAC Input and PowerDown bits update. * No EEPROM update */ -uint8_t mcp4728_fastWrite() { +uint8_t MCP4728::fastWrite() { Wire.beginTransmission(I2C_ADDRESS(DAC_DEV_ADDRESS)); LOOP_XYZE(i) { - Wire.write(highByte(mcp4728_values[i])); - Wire.write(lowByte(mcp4728_values[i])); + Wire.write(highByte(dac_values[i])); + Wire.write(lowByte(dac_values[i])); } return Wire.endTransmission(); } @@ -143,10 +145,10 @@ uint8_t mcp4728_fastWrite() { /** * Common function for simple general commands */ -uint8_t mcp4728_simpleCommand(const byte simpleCommand) { +uint8_t MCP4728::simpleCommand(const byte simpleCommand) { Wire.beginTransmission(I2C_ADDRESS(GENERALCALL)); Wire.write(simpleCommand); return Wire.endTransmission(); } -#endif // DAC_STEPPER_CURRENT +#endif // HAS_MOTOR_CURRENT_DAC diff --git a/Marlin/src/feature/dac/dac_mcp4728.h b/Marlin/src/feature/dac/dac_mcp4728.h index 8e8b25ca691a..571716d4834e 100644 --- a/Marlin/src/feature/dac/dac_mcp4728.h +++ b/Marlin/src/feature/dac/dac_mcp4728.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -40,7 +40,7 @@ #endif #ifndef lowByte - #define lowByte(w) ((uint8_t) ((w) & 0xff)) + #define lowByte(w) ((uint8_t) ((w) & 0xFF)) #endif #ifndef highByte @@ -65,13 +65,18 @@ // DAC_OR_ADDRESS defined in pins_BOARD.h file #define DAC_DEV_ADDRESS (BASE_ADDR | DAC_OR_ADDRESS) -void mcp4728_init(); -uint8_t mcp4728_analogWrite(const uint8_t channel, const uint16_t value); -uint8_t mcp4728_eepromWrite(); -uint8_t mcp4728_setVref_all(const uint8_t value); -uint8_t mcp4728_setGain_all(const uint8_t value); -uint16_t mcp4728_getValue(const uint8_t channel); -uint8_t mcp4728_fastWrite(); -uint8_t mcp4728_simpleCommand(const byte simpleCommand); -uint8_t mcp4728_getDrvPct(const uint8_t channel); -void mcp4728_setDrvPct(xyze_uint8_t &pct); +class MCP4728 { +public: + static void init(); + static uint8_t analogWrite(const uint8_t channel, const uint16_t value); + static uint8_t eepromWrite(); + static uint8_t setVref_all(const uint8_t value); + static uint8_t setGain_all(const uint8_t value); + static uint16_t getValue(const uint8_t channel); + static uint8_t fastWrite(); + static uint8_t simpleCommand(const byte simpleCommand); + static uint8_t getDrvPct(const uint8_t channel); + static void setDrvPct(xyze_uint8_t &pct); +}; + +extern MCP4728 mcp4728; diff --git a/Marlin/src/feature/dac/stepper_dac.cpp b/Marlin/src/feature/dac/stepper_dac.cpp index cb3856f28704..5f10b4ccfbdc 100644 --- a/Marlin/src/feature/dac/stepper_dac.cpp +++ b/Marlin/src/feature/dac/stepper_dac.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -26,79 +26,74 @@ #include "../../inc/MarlinConfig.h" -#if ENABLED(DAC_STEPPER_CURRENT) +#if ENABLED(HAS_MOTOR_CURRENT_DAC) #include "stepper_dac.h" +#include "../../MarlinCore.h" // for SP_X_LBL... bool dac_present = false; constexpr xyze_uint8_t dac_order = DAC_STEPPER_ORDER; xyze_uint8_t dac_channel_pct = DAC_MOTOR_CURRENT_DEFAULT; -int dac_init() { +StepperDAC stepper_dac; + +int StepperDAC::init() { #if PIN_EXISTS(DAC_DISABLE) OUT_WRITE(DAC_DISABLE_PIN, LOW); // set pin low to enable DAC #endif - mcp4728_init(); + mcp4728.init(); - if (mcp4728_simpleCommand(RESET)) return -1; + if (mcp4728.simpleCommand(RESET)) return -1; dac_present = true; - mcp4728_setVref_all(DAC_STEPPER_VREF); - mcp4728_setGain_all(DAC_STEPPER_GAIN); + mcp4728.setVref_all(DAC_STEPPER_VREF); + mcp4728.setGain_all(DAC_STEPPER_GAIN); - if (mcp4728_getDrvPct(0) < 1 || mcp4728_getDrvPct(1) < 1 || mcp4728_getDrvPct(2) < 1 || mcp4728_getDrvPct(3) < 1 ) { - mcp4728_setDrvPct(dac_channel_pct); - mcp4728_eepromWrite(); + if (mcp4728.getDrvPct(0) < 1 || mcp4728.getDrvPct(1) < 1 || mcp4728.getDrvPct(2) < 1 || mcp4728.getDrvPct(3) < 1 ) { + mcp4728.setDrvPct(dac_channel_pct); + mcp4728.eepromWrite(); } return 0; } -void dac_current_percent(uint8_t channel, float val) { +void StepperDAC::set_current_value(const uint8_t channel, uint16_t val) { if (!dac_present) return; - NOMORE(val, 100); + NOMORE(val, uint16_t(DAC_STEPPER_MAX)); - mcp4728_analogWrite(dac_order[channel], val * 0.01 * (DAC_STEPPER_MAX)); - mcp4728_simpleCommand(UPDATE); + mcp4728.analogWrite(dac_order[channel], val); + mcp4728.simpleCommand(UPDATE); } -void dac_current_raw(uint8_t channel, uint16_t val) { - if (!dac_present) return; - - NOMORE(val, uint16_t(DAC_STEPPER_MAX)); - - mcp4728_analogWrite(dac_order[channel], val); - mcp4728_simpleCommand(UPDATE); +void StepperDAC::set_current_percent(const uint8_t channel, float val) { + set_current_value(channel, _MIN(val, 100.0f) * (DAC_STEPPER_MAX) / 100.0f); } -static float dac_perc(int8_t n) { return 100.0 * mcp4728_getValue(dac_order[n]) * RECIPROCAL(DAC_STEPPER_MAX); } -static float dac_amps(int8_t n) { return mcp4728_getDrvPct(dac_order[n]) * (DAC_STEPPER_MAX) * 0.125 * RECIPROCAL(DAC_STEPPER_SENSE); } +static float dac_perc(int8_t n) { return 100.0 * mcp4728.getValue(dac_order[n]) * RECIPROCAL(DAC_STEPPER_MAX); } +static float dac_amps(int8_t n) { return mcp4728.getDrvPct(dac_order[n]) * (DAC_STEPPER_MAX) * 0.125 * RECIPROCAL(DAC_STEPPER_SENSE); } -uint8_t dac_current_get_percent(const AxisEnum axis) { return mcp4728_getDrvPct(dac_order[axis]); } -void dac_current_set_percents(xyze_uint8_t &pct) { +uint8_t StepperDAC::get_current_percent(const AxisEnum axis) { return mcp4728.getDrvPct(dac_order[axis]); } +void StepperDAC::set_current_percents(xyze_uint8_t &pct) { LOOP_XYZE(i) dac_channel_pct[i] = pct[dac_order[i]]; - mcp4728_setDrvPct(dac_channel_pct); + mcp4728.setDrvPct(dac_channel_pct); } -void dac_print_values() { +void StepperDAC::print_values() { if (!dac_present) return; - SERIAL_ECHO_MSG("Stepper current values in % (Amps):"); SERIAL_ECHO_START(); - SERIAL_ECHOLNPAIR( - " X:", dac_perc(X_AXIS), " (", dac_amps(X_AXIS), ")" - " Y:", dac_perc(Y_AXIS), " (", dac_amps(Y_AXIS), ")" - " Z:", dac_perc(Z_AXIS), " (", dac_amps(Z_AXIS), ")" - " E:", dac_perc(E_AXIS), " (", dac_amps(E_AXIS), ")" - ); + SERIAL_ECHOPAIR_P( SP_X_LBL, dac_perc(X_AXIS), PSTR(" ("), dac_amps(X_AXIS), PSTR(")")); + SERIAL_ECHOPAIR_P( SP_Y_LBL, dac_perc(Y_AXIS), PSTR(" ("), dac_amps(Y_AXIS), PSTR(")")); + SERIAL_ECHOPAIR_P( SP_Z_LBL, dac_perc(Z_AXIS), PSTR(" ("), dac_amps(Z_AXIS), PSTR(")")); + SERIAL_ECHOLNPAIR_P(SP_E_LBL, dac_perc(E_AXIS), PSTR(" ("), dac_amps(E_AXIS), PSTR(")")); } -void dac_commit_eeprom() { +void StepperDAC::commit_eeprom() { if (!dac_present) return; - mcp4728_eepromWrite(); + mcp4728.eepromWrite(); } -#endif // DAC_STEPPER_CURRENT +#endif // HAS_MOTOR_CURRENT_DAC diff --git a/Marlin/src/feature/dac/stepper_dac.h b/Marlin/src/feature/dac/stepper_dac.h index 3e77d471a672..6836335e9806 100644 --- a/Marlin/src/feature/dac/stepper_dac.h +++ b/Marlin/src/feature/dac/stepper_dac.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -27,10 +27,15 @@ #include "dac_mcp4728.h" -int dac_init(); -void dac_current_percent(uint8_t channel, float val); -void dac_current_raw(uint8_t channel, uint16_t val); -void dac_print_values(); -void dac_commit_eeprom(); -uint8_t dac_current_get_percent(AxisEnum axis); -void dac_current_set_percents(xyze_uint8_t &pct); +class StepperDAC { +public: + static int init(); + static void set_current_percent(const uint8_t channel, float val); + static void set_current_value(const uint8_t channel, uint16_t val); + static void print_values(); + static void commit_eeprom(); + static uint8_t get_current_percent(AxisEnum axis); + static void set_current_percents(xyze_uint8_t &pct); +}; + +extern StepperDAC stepper_dac; diff --git a/Marlin/src/feature/digipot/digipot.h b/Marlin/src/feature/digipot/digipot.h index b7c0b6503619..c53f8093dd52 100644 --- a/Marlin/src/feature/digipot/digipot.h +++ b/Marlin/src/feature/digipot/digipot.h @@ -16,10 +16,18 @@ * 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 . + * along with this program. If not, see . * */ #pragma once -void digipot_i2c_set_current(const uint8_t channel, const float current); -void digipot_i2c_init(); +// +// Header for MCP4018 and MCP4451 current control i2c devices +// +class DigipotI2C { +public: + static void init(); + static void set_current(const uint8_t channel, const float current); +}; + +DigipotI2C digipot_i2c; diff --git a/Marlin/src/feature/digipot/digipot_mcp4018.cpp b/Marlin/src/feature/digipot/digipot_mcp4018.cpp index 888acc55d050..6260185fc32d 100644 --- a/Marlin/src/feature/digipot/digipot_mcp4018.cpp +++ b/Marlin/src/feature/digipot/digipot_mcp4018.cpp @@ -16,67 +16,61 @@ * 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 . + * along with this program. If not, see . * */ #include "../../inc/MarlinConfig.h" -#if BOTH(DIGIPOT_I2C, DIGIPOT_MCP4018) +#if ENABLED(DIGIPOT_MCP4018) -#include "Stream.h" -#include "utility/twi.h" -#include //https://github.com/stawel/SlowSoftI2CMaster +#include "digipot.h" + +#include +#include // https://github.com/stawel/SlowSoftI2CMaster // Settings for the I2C based DIGIPOT (MCP4018) based on WT150 #define DIGIPOT_A4988_Rsx 0.250 #define DIGIPOT_A4988_Vrefmax 1.666 -#define DIGIPOT_A4988_MAX_VALUE 127 +#define DIGIPOT_MCP4018_MAX_VALUE 127 -#define DIGIPOT_A4988_Itripmax(Vref) ((Vref)/(8.0*DIGIPOT_A4988_Rsx)) +#define DIGIPOT_A4988_Itripmax(Vref) ((Vref) / (8.0 * DIGIPOT_A4988_Rsx)) -#define DIGIPOT_A4988_FACTOR ((DIGIPOT_A4988_MAX_VALUE)/DIGIPOT_A4988_Itripmax(DIGIPOT_A4988_Vrefmax)) +#define DIGIPOT_A4988_FACTOR ((DIGIPOT_MCP4018_MAX_VALUE) / DIGIPOT_A4988_Itripmax(DIGIPOT_A4988_Vrefmax)) #define DIGIPOT_A4988_MAX_CURRENT 2.0 static byte current_to_wiper(const float current) { - const int16_t value = ceil(float(DIGIPOT_A4988_FACTOR) * current); - return byte(constrain(value, 0, DIGIPOT_A4988_MAX_VALUE)); + const int16_t value = TERN(DIGIPOT_USE_RAW_VALUES, current, CEIL(current * DIGIPOT_A4988_FACTOR)); + return byte(constrain(value, 0, DIGIPOT_MCP4018_MAX_VALUE)); } -const uint8_t sda_pins[DIGIPOT_I2C_NUM_CHANNELS] = { - DIGIPOTS_I2C_SDA_X - #if DIGIPOT_I2C_NUM_CHANNELS > 1 - , DIGIPOTS_I2C_SDA_Y - #if DIGIPOT_I2C_NUM_CHANNELS > 2 - , DIGIPOTS_I2C_SDA_Z - #if DIGIPOT_I2C_NUM_CHANNELS > 3 - , DIGIPOTS_I2C_SDA_E0 - #if DIGIPOT_I2C_NUM_CHANNELS > 4 - , DIGIPOTS_I2C_SDA_E1 - #endif - #endif - #endif - #endif -}; - static SlowSoftI2CMaster pots[DIGIPOT_I2C_NUM_CHANNELS] = { - SlowSoftI2CMaster { sda_pins[X_AXIS], DIGIPOTS_I2C_SCL } + SlowSoftI2CMaster(DIGIPOTS_I2C_SDA_X, DIGIPOTS_I2C_SCL) #if DIGIPOT_I2C_NUM_CHANNELS > 1 - , SlowSoftI2CMaster { sda_pins[Y_AXIS], DIGIPOTS_I2C_SCL } + , SlowSoftI2CMaster(DIGIPOTS_I2C_SDA_Y, DIGIPOTS_I2C_SCL) #if DIGIPOT_I2C_NUM_CHANNELS > 2 - , SlowSoftI2CMaster { sda_pins[Z_AXIS], DIGIPOTS_I2C_SCL } + , SlowSoftI2CMaster(DIGIPOTS_I2C_SDA_Z, DIGIPOTS_I2C_SCL) #if DIGIPOT_I2C_NUM_CHANNELS > 3 - , SlowSoftI2CMaster { sda_pins[E_AXIS], DIGIPOTS_I2C_SCL } + , SlowSoftI2CMaster(DIGIPOTS_I2C_SDA_E0, DIGIPOTS_I2C_SCL) #if DIGIPOT_I2C_NUM_CHANNELS > 4 - , SlowSoftI2CMaster { sda_pins[E_AXIS + 1], DIGIPOTS_I2C_SCL } + , SlowSoftI2CMaster(DIGIPOTS_I2C_SDA_E1, DIGIPOTS_I2C_SCL) + #if DIGIPOT_I2C_NUM_CHANNELS > 5 + , SlowSoftI2CMaster(DIGIPOTS_I2C_SDA_E2, DIGIPOTS_I2C_SCL) + #if DIGIPOT_I2C_NUM_CHANNELS > 6 + , SlowSoftI2CMaster(DIGIPOTS_I2C_SDA_E3, DIGIPOTS_I2C_SCL) + #if DIGIPOT_I2C_NUM_CHANNELS > 7 + , SlowSoftI2CMaster(DIGIPOTS_I2C_SDA_E4, DIGIPOTS_I2C_SCL) + #endif + #endif + #endif #endif #endif #endif #endif }; -static void i2c_send(const uint8_t channel, const byte v) { +static void digipot_i2c_send(const uint8_t channel, const byte v) { if (WITHIN(channel, 0, DIGIPOT_I2C_NUM_CHANNELS - 1)) { pots[channel].i2c_start(((DIGIPOT_I2C_ADDRESS_A) << 1) | I2C_WRITE); pots[channel].i2c_write(v); @@ -85,19 +79,24 @@ static void i2c_send(const uint8_t channel, const byte v) { } // This is for the MCP4018 I2C based digipot -void digipot_i2c_set_current(const uint8_t channel, const float current) { - i2c_send(channel, current_to_wiper(_MIN(_MAX(current, 0), float(DIGIPOT_A4988_MAX_CURRENT)))); +void DigipotI2C::set_current(const uint8_t channel, const float current) { + const float ival = _MIN(_MAX(current, 0), float(DIGIPOT_MCP4018_MAX_VALUE)); + digipot_i2c_send(channel, current_to_wiper(ival)); } -void digipot_i2c_init() { - static const float digipot_motor_current[] PROGMEM = DIGIPOT_I2C_MOTOR_CURRENTS; - - for (uint8_t i = 0; i < DIGIPOT_I2C_NUM_CHANNELS; i++) - pots[i].i2c_init(); +void DigipotI2C::init() { + LOOP_L_N(i, DIGIPOT_I2C_NUM_CHANNELS) pots[i].i2c_init(); - // setup initial currents as defined in Configuration_adv.h - for (uint8_t i = 0; i < COUNT(digipot_motor_current); i++) - digipot_i2c_set_current(i, pgm_read_float(&digipot_motor_current[i])); + // Init currents according to Configuration_adv.h + static const float digipot_motor_current[] PROGMEM = + #if ENABLED(DIGIPOT_USE_RAW_VALUES) + DIGIPOT_MOTOR_CURRENT + #else + DIGIPOT_I2C_MOTOR_CURRENTS + #endif + ; + LOOP_L_N(i, COUNT(digipot_motor_current)) + set_current(i, pgm_read_float(&digipot_motor_current[i])); } -#endif // DIGIPOT_I2C && DIGIPOT_MCP4018 +#endif // DIGIPOT_MCP4018 diff --git a/Marlin/src/feature/digipot/digipot_mcp4451.cpp b/Marlin/src/feature/digipot/digipot_mcp4451.cpp index e84bd28d35c6..7e6ace49a06a 100644 --- a/Marlin/src/feature/digipot/digipot_mcp4451.cpp +++ b/Marlin/src/feature/digipot/digipot_mcp4451.cpp @@ -16,15 +16,17 @@ * 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 . + * along with this program. If not, see . * */ #include "../../inc/MarlinConfig.h" -#if ENABLED(DIGIPOT_I2C) && DISABLED(DIGIPOT_MCP4018) +#if ENABLED(DIGIPOT_MCP4451) -#include "Stream.h" +#include "digipot.h" + +#include #include #if MB(MKS_SBASE) @@ -33,18 +35,18 @@ // Settings for the I2C based DIGIPOT (MCP4451) on Azteeg X3 Pro #if MB(5DPRINT) - #define DIGIPOT_I2C_FACTOR 117.96 - #define DIGIPOT_I2C_MAX_CURRENT 1.736 + #define DIGIPOT_I2C_FACTOR 117.96f + #define DIGIPOT_I2C_MAX_CURRENT 1.736f #elif MB(AZTEEG_X5_MINI, AZTEEG_X5_MINI_WIFI) - #define DIGIPOT_I2C_FACTOR 113.5 - #define DIGIPOT_I2C_MAX_CURRENT 2.0 + #define DIGIPOT_I2C_FACTOR 113.5f + #define DIGIPOT_I2C_MAX_CURRENT 2.0f #else - #define DIGIPOT_I2C_FACTOR 106.7 - #define DIGIPOT_I2C_MAX_CURRENT 2.5 + #define DIGIPOT_I2C_FACTOR 106.7f + #define DIGIPOT_I2C_MAX_CURRENT 2.5f #endif static byte current_to_wiper(const float current) { - return byte(CEIL(float((DIGIPOT_I2C_FACTOR * current)))); + return byte(TERN(DIGIPOT_USE_RAW_VALUES, current, CEIL(DIGIPOT_I2C_FACTOR * current))); } static void digipot_i2c_send(const byte addr, const byte a, const byte b) { @@ -61,9 +63,9 @@ static void digipot_i2c_send(const byte addr, const byte a, const byte b) { } // This is for the MCP4451 I2C based digipot -void digipot_i2c_set_current(const uint8_t channel, const float current) { - // these addresses are specific to Azteeg X3 Pro, can be set to others, - // In this case first digipot is at address A0=0, A1= 0, second one is at A0=0, A1= 1 +void DigipotI2C::set_current(const uint8_t channel, const float current) { + // These addresses are specific to Azteeg X3 Pro, can be set to others. + // In this case first digipot is at address A0=0, A1=0, second one is at A0=0, A1=1 const byte addr = channel < 4 ? DIGIPOT_I2C_ADDRESS_A : DIGIPOT_I2C_ADDRESS_B; // channel 0-3 vs 4-7 // Initial setup @@ -75,16 +77,22 @@ void digipot_i2c_set_current(const uint8_t channel, const float current) { digipot_i2c_send(addr, addresses[channel & 0x3], current_to_wiper(_MIN(float(_MAX(current, 0)), DIGIPOT_I2C_MAX_CURRENT))); } -void digipot_i2c_init() { +void DigipotI2C::init() { #if MB(MKS_SBASE) - configure_i2c(16); // Setting clock_option to 16 ensure the I2C bus is initialized at 400kHz + configure_i2c(16); // Set clock_option to 16 ensure I2C is initialized at 400kHz #else Wire.begin(); #endif - // setup initial currents as defined in Configuration_adv.h - static const float digipot_motor_current[] PROGMEM = DIGIPOT_I2C_MOTOR_CURRENTS; - for (uint8_t i = 0; i < COUNT(digipot_motor_current); i++) - digipot_i2c_set_current(i, pgm_read_float(&digipot_motor_current[i])); + // Set up initial currents as defined in Configuration_adv.h + static const float digipot_motor_current[] PROGMEM = + #if ENABLED(DIGIPOT_USE_RAW_VALUES) + DIGIPOT_MOTOR_CURRENT + #else + DIGIPOT_I2C_MOTOR_CURRENTS + #endif + ; + LOOP_L_N(i, COUNT(digipot_motor_current)) + set_current(i, pgm_read_float(&digipot_motor_current[i])); } -#endif // DIGIPOT_I2C +#endif // DIGIPOT_MCP4451 diff --git a/Marlin/src/feature/direct_stepping.cpp b/Marlin/src/feature/direct_stepping.cpp new file mode 100644 index 000000000000..9766d1464053 --- /dev/null +++ b/Marlin/src/feature/direct_stepping.cpp @@ -0,0 +1,262 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../inc/MarlinConfigPre.h" + +#if ENABLED(DIRECT_STEPPING) + +#include "direct_stepping.h" + +#include "../MarlinCore.h" + +#define CHECK_PAGE(I, R) do{ \ + if (I >= sizeof(page_states) / sizeof(page_states[0])) { \ + fatal_error = true; \ + return R; \ + } \ +}while(0) + +#define CHECK_PAGE_STATE(I, R, S) do { \ + CHECK_PAGE(I, R); \ + if (page_states[I] != S) { \ + fatal_error = true; \ + return R; \ + } \ +}while(0) + +namespace DirectStepping { + + template + State SerialPageManager::state; + + template + volatile bool SerialPageManager::fatal_error; + + template + volatile PageState SerialPageManager::page_states[Cfg::NUM_PAGES]; + + template + volatile bool SerialPageManager::page_states_dirty; + + template + uint8_t SerialPageManager::pages[Cfg::NUM_PAGES][Cfg::PAGE_SIZE]; + + template + uint8_t SerialPageManager::checksum; + + template + typename Cfg::write_byte_idx_t SerialPageManager::write_byte_idx; + + template + typename Cfg::page_idx_t SerialPageManager::write_page_idx; + + template + typename Cfg::write_byte_idx_t SerialPageManager::write_page_size; + + template + void SerialPageManager::init() { + for (int i = 0 ; i < Cfg::NUM_PAGES ; i++) + page_states[i] = PageState::FREE; + + fatal_error = false; + state = State::NEWLINE; + + page_states_dirty = false; + + SERIAL_ECHOLNPGM("pages_ready"); + } + + template + FORCE_INLINE bool SerialPageManager::maybe_store_rxd_char(uint8_t c) { + switch (state) { + default: + case State::MONITOR: + switch (c) { + case '\n': + case '\r': + state = State::NEWLINE; + default: + return false; + } + case State::NEWLINE: + switch (c) { + case Cfg::CONTROL_CHAR: + state = State::ADDRESS; + return true; + case '\n': + case '\r': + state = State::NEWLINE; + return false; + default: + state = State::MONITOR; + return false; + } + case State::ADDRESS: + //TODO: 16 bit address, State::ADDRESS2 + write_page_idx = c; + write_byte_idx = 0; + checksum = 0; + + CHECK_PAGE(write_page_idx, true); + + if (page_states[write_page_idx] == PageState::FAIL) { + // Special case for fail + state = State::UNFAIL; + return true; + } + + set_page_state(write_page_idx, PageState::WRITING); + + state = Cfg::DIRECTIONAL ? State::COLLECT : State::SIZE; + + return true; + case State::SIZE: + // Zero means full page size + write_page_size = c; + state = State::COLLECT; + return true; + case State::COLLECT: + pages[write_page_idx][write_byte_idx++] = c; + checksum ^= c; + + // check if still collecting + if (Cfg::PAGE_SIZE == 256) { + // special case for 8-bit, check if rolled back to 0 + if (Cfg::DIRECTIONAL || !write_page_size) { // full 256 bytes + if (write_byte_idx) return true; + } else { + if (write_byte_idx < write_page_size) return true; + } + } else if (Cfg::DIRECTIONAL) { + if (write_byte_idx != Cfg::PAGE_SIZE) return true; + } else { + if (write_byte_idx < write_page_size) return true; + } + + state = State::CHECKSUM; + return true; + case State::CHECKSUM: { + const PageState page_state = (checksum == c) ? PageState::OK : PageState::FAIL; + set_page_state(write_page_idx, page_state); + state = State::MONITOR; + return true; + } + case State::UNFAIL: + if (c == 0) { + set_page_state(write_page_idx, PageState::FREE); + } else { + fatal_error = true; + } + state = State::MONITOR; + return true; + } + } + + template + void SerialPageManager::write_responses() { + if (fatal_error) { + kill(GET_TEXT(MSG_BAD_PAGE)); + return; + } + + if (!page_states_dirty) return; + page_states_dirty = false; + + SERIAL_ECHO(Cfg::CONTROL_CHAR); + constexpr int state_bits = 2; + constexpr int n_bytes = Cfg::NUM_PAGES >> state_bits; + volatile uint8_t bits_b[n_bytes] = { 0 }; + + for (page_idx_t i = 0 ; i < Cfg::NUM_PAGES ; i++) { + bits_b[i >> state_bits] |= page_states[i] << ((i * state_bits) & 0x7); + } + + uint8_t crc = 0; + for (uint8_t i = 0 ; i < n_bytes ; i++) { + crc ^= bits_b[i]; + SERIAL_ECHO(bits_b[i]); + } + + SERIAL_ECHO(crc); + SERIAL_EOL(); + } + + template + FORCE_INLINE void SerialPageManager::set_page_state(const page_idx_t page_idx, const PageState page_state) { + CHECK_PAGE(page_idx,); + + page_states[page_idx] = page_state; + page_states_dirty = true; + } + + template <> + FORCE_INLINE uint8_t *PageManager::get_page(const page_idx_t page_idx) { + CHECK_PAGE(page_idx, nullptr); + + return pages[page_idx]; + } + + template <> + FORCE_INLINE void PageManager::free_page(const page_idx_t page_idx) { + set_page_state(page_idx, PageState::FREE); + } + +}; + +DirectStepping::PageManager page_manager; + +const uint8_t segment_table[DirectStepping::Config::NUM_SEGMENTS][DirectStepping::Config::SEGMENT_STEPS] PROGMEM = { + + #if STEPPER_PAGE_FORMAT == SP_4x4D_128 + + { 1, 1, 1, 1, 1, 1, 1 }, // 0 = -7 + { 1, 1, 1, 0, 1, 1, 1 }, // 1 = -6 + { 1, 1, 1, 0, 1, 0, 1 }, // 2 = -5 + { 1, 1, 0, 1, 0, 1, 0 }, // 3 = -4 + { 1, 1, 0, 0, 1, 0, 0 }, // 4 = -3 + { 0, 0, 1, 0, 0, 0, 1 }, // 5 = -2 + { 0, 0, 0, 1, 0, 0, 0 }, // 6 = -1 + { 0, 0, 0, 0, 0, 0, 0 }, // 7 = 0 + { 0, 0, 0, 1, 0, 0, 0 }, // 8 = 1 + { 0, 0, 1, 0, 0, 0, 1 }, // 9 = 2 + { 1, 1, 0, 0, 1, 0, 0 }, // 10 = 3 + { 1, 1, 0, 1, 0, 1, 0 }, // 11 = 4 + { 1, 1, 1, 0, 1, 0, 1 }, // 12 = 5 + { 1, 1, 1, 0, 1, 1, 1 }, // 13 = 6 + { 1, 1, 1, 1, 1, 1, 1 }, // 14 = 7 + { 0 } + + #elif STEPPER_PAGE_FORMAT == SP_4x2_256 + + { 0, 0, 0 }, // 0 + { 0, 1, 0 }, // 1 + { 1, 0, 1 }, // 2 + { 1, 1, 1 }, // 3 + + #elif STEPPER_PAGE_FORMAT == SP_4x1_512 + + {0} // Uncompressed format, table not used + + #endif + +}; + +#endif // DIRECT_STEPPING diff --git a/Marlin/src/feature/direct_stepping.h b/Marlin/src/feature/direct_stepping.h new file mode 100644 index 000000000000..cde9d1a0b438 --- /dev/null +++ b/Marlin/src/feature/direct_stepping.h @@ -0,0 +1,133 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../inc/MarlinConfig.h" + +namespace DirectStepping { + + enum State : char { + MONITOR, NEWLINE, ADDRESS, SIZE, COLLECT, CHECKSUM, UNFAIL + }; + + enum PageState : uint8_t { + FREE, WRITING, OK, FAIL + }; + + // Static state used for stepping through direct stepping pages + struct page_step_state_t { + // Current page + uint8_t *page; + // Current segment + uint16_t segment_idx; + // Current steps within segment + uint8_t segment_steps; + // Segment delta + xyze_uint8_t sd; + // Block delta + xyze_int_t bd; + }; + + template + class SerialPageManager { + public: + + typedef typename Cfg::page_idx_t page_idx_t; + + static bool maybe_store_rxd_char(uint8_t c); + static void write_responses(); + + // common methods for page managers + static void init(); + static uint8_t *get_page(const page_idx_t page_idx); + static void free_page(const page_idx_t page_idx); + + protected: + + typedef typename Cfg::write_byte_idx_t write_byte_idx_t; + + static State state; + static volatile bool fatal_error; + + static volatile PageState page_states[Cfg::NUM_PAGES]; + static volatile bool page_states_dirty; + + static uint8_t pages[Cfg::NUM_PAGES][Cfg::PAGE_SIZE]; + static uint8_t checksum; + static write_byte_idx_t write_byte_idx; + static page_idx_t write_page_idx; + static write_byte_idx_t write_page_size; + + static void set_page_state(const page_idx_t page_idx, const PageState page_state); + }; + + template struct TypeSelector { typedef T type;} ; + template struct TypeSelector { typedef F type; }; + + template + struct config_t { + static constexpr char CONTROL_CHAR = '!'; + + static constexpr int NUM_PAGES = num_pages; + static constexpr int NUM_AXES = num_axes; + static constexpr int BITS_SEGMENT = bits_segment; + static constexpr int DIRECTIONAL = dir ? 1 : 0; + static constexpr int SEGMENTS = segments; + + static constexpr int NUM_SEGMENTS = 1 << BITS_SEGMENT; + static constexpr int SEGMENT_STEPS = (1 << (BITS_SEGMENT - DIRECTIONAL)) - 1; + static constexpr int TOTAL_STEPS = SEGMENT_STEPS * SEGMENTS; + static constexpr int PAGE_SIZE = (NUM_AXES * BITS_SEGMENT * SEGMENTS) / 8; + + typedef typename TypeSelector<(PAGE_SIZE>256), uint16_t, uint8_t>::type write_byte_idx_t; + typedef typename TypeSelector<(NUM_PAGES>256), uint16_t, uint8_t>::type page_idx_t; + }; + + template + using SP_4x4D_128 = config_t; + + template + using SP_4x2_256 = config_t; + + template + using SP_4x1_512 = config_t; + + // configured types + typedef STEPPER_PAGE_FORMAT Config; + + template class PAGE_MANAGER; + typedef PAGE_MANAGER PageManager; +}; + +#define SP_4x4D_128 1 +//#define SP_4x4_128 2 +//#define SP_4x2D_256 3 +#define SP_4x2_256 4 +#define SP_4x1_512 5 + +typedef typename DirectStepping::Config::page_idx_t page_idx_t; + +// TODO: use config +typedef DirectStepping::page_step_state_t page_step_state_t; + +extern const uint8_t segment_table[DirectStepping::Config::NUM_SEGMENTS][DirectStepping::Config::SEGMENT_STEPS]; +extern DirectStepping::PageManager page_manager; diff --git a/Marlin/src/feature/emergency_parser.cpp b/Marlin/src/feature/e_parser.cpp similarity index 85% rename from Marlin/src/feature/emergency_parser.cpp rename to Marlin/src/feature/e_parser.cpp index 60fba1f1b617..a4c2d0dac92c 100644 --- a/Marlin/src/feature/emergency_parser.cpp +++ b/Marlin/src/feature/e_parser.cpp @@ -16,19 +16,19 @@ * 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 . + * along with this program. If not, see . * */ /** - * emergency_parser.cpp - Intercept special commands directly in the serial stream + * e_parser.cpp - Intercept special commands directly in the serial stream */ #include "../inc/MarlinConfigPre.h" #if ENABLED(EMERGENCY_PARSER) -#include "emergency_parser.h" +#include "e_parser.h" // Static data members bool EmergencyParser::killed_by_M112, // = false diff --git a/Marlin/src/feature/emergency_parser.h b/Marlin/src/feature/e_parser.h similarity index 88% rename from Marlin/src/feature/emergency_parser.h rename to Marlin/src/feature/e_parser.h index 787c82407fc5..085cbd4eab0e 100644 --- a/Marlin/src/feature/emergency_parser.h +++ b/Marlin/src/feature/e_parser.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once /** - * emergency_parser.h - Intercept special commands directly in the serial stream + * e_parser.h - Intercept special commands directly in the serial stream */ #include "../inc/MarlinConfigPre.h" @@ -75,10 +75,11 @@ class EmergencyParser { FORCE_INLINE static void disable() { enabled = false; } FORCE_INLINE static void update(State &state, const uint8_t c) { + #define ISEOL(C) ((C) == '\n' || (C) == '\r') switch (state) { case EP_RESET: switch (c) { - case ' ': break; + case ' ': case '\n': case '\r': break; case 'N': state = EP_N; break; case 'M': state = EP_M; break; default: state = EP_IGNORE; @@ -87,10 +88,8 @@ class EmergencyParser { case EP_N: switch (c) { - case '0': case '1': case '2': - case '3': case '4': case '5': - case '6': case '7': case '8': - case '9': case '-': case ' ': break; + case '0' ... '9': + case '-': case ' ': break; case 'M': state = EP_M; break; default: state = EP_IGNORE; } @@ -152,10 +151,7 @@ class EmergencyParser { case EP_M876S: switch (c) { case ' ': break; - case '0': case '1': case '2': - case '3': case '4': case '5': - case '6': case '7': case '8': - case '9': + case '0' ... '9': state = EP_M876SN; M876_reason = (uint8_t)(c - '0'); break; @@ -164,11 +160,11 @@ class EmergencyParser { #endif case EP_IGNORE: - if (c == '\n') state = EP_RESET; + if (ISEOL(c)) state = EP_RESET; break; default: - if (c == '\n') { + if (ISEOL(c)) { if (enabled) switch (state) { case EP_M108: wait_for_user = wait_for_heatup = false; break; case EP_M112: killed_by_M112 = true; break; diff --git a/Marlin/src/feature/I2CPositionEncoder.cpp b/Marlin/src/feature/encoder_i2c.cpp similarity index 98% rename from Marlin/src/feature/I2CPositionEncoder.cpp rename to Marlin/src/feature/encoder_i2c.cpp index 9c1e53df74c4..c9641cb71a32 100644 --- a/Marlin/src/feature/I2CPositionEncoder.cpp +++ b/Marlin/src/feature/encoder_i2c.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -32,7 +32,7 @@ #if ENABLED(I2C_POSITION_ENCODERS) -#include "I2CPositionEncoder.h" +#include "encoder_i2c.h" #include "../module/temperature.h" #include "../module/stepper.h" @@ -46,7 +46,7 @@ void I2CPositionEncoder::init(const uint8_t address, const AxisEnum axis) { encoderAxis = axis; i2cAddress = address; - initialized++; + initialized = true; SERIAL_ECHOLNPAIR("Setting up encoder on ", axis_codes[encoderAxis], " axis, addr = ", address); @@ -107,7 +107,7 @@ void I2CPositionEncoder::update() { SERIAL_ECHOLNPAIR("New zero-offset of ", zeroOffset); SERIAL_ECHOPAIR("New position reads as ", get_position()); SERIAL_CHAR('('); - SERIAL_ECHO(mm_from_count(get_position())); + SERIAL_DECIMAL(mm_from_count(get_position())); SERIAL_ECHOLNPGM(")"); #endif } @@ -208,8 +208,7 @@ void I2CPositionEncoder::set_homed() { delay(10); zeroOffset = get_raw_count(); - homed++; - trusted++; + homed = trusted = true; #ifdef I2CPE_DEBUG SERIAL_ECHO(axis_codes[encoderAxis]); @@ -305,7 +304,7 @@ int32_t I2CPositionEncoder::get_raw_count() { encoderCount.val = 0x00; - if (Wire.requestFrom((int)i2cAddress, 3) != 3) { + if (Wire.requestFrom(I2C_ADDRESS(i2cAddress), uint8_t(3)) != 3) { //houston, we have a problem... H = I2CPE_MAG_SIG_NF; return 0; @@ -459,9 +458,7 @@ void I2CPositionEncoder::reset() { Wire.write(I2CPE_RESET_COUNT); Wire.endTransmission(); - #if ENABLED(I2CPE_ERR_ROLLING_AVERAGE) - ZERO(err); - #endif + TERN_(I2CPE_ERR_ROLLING_AVERAGE, ZERO(err)); } @@ -746,7 +743,7 @@ void I2CPositionEncodersMgr::report_module_firmware(const uint8_t address) { Wire.endTransmission(); // Read value - if (Wire.requestFrom((int)address, 32)) { + if (Wire.requestFrom(I2C_ADDRESS(address), uint8_t(32))) { char c; while (Wire.available() > 0 && (c = (char)Wire.read()) > 0) SERIAL_ECHO(c); @@ -818,7 +815,6 @@ int8_t I2CPositionEncodersMgr::parse() { * Y Report on Y axis encoder, if present. * Z Report on Z axis encoder, if present. * E Report on E axis encoder, if present. - * */ void I2CPositionEncodersMgr::M860() { if (parse()) return; @@ -848,7 +844,6 @@ void I2CPositionEncodersMgr::M860() { * Y Report on Y axis encoder, if present. * Z Report on Z axis encoder, if present. * E Report on E axis encoder, if present. - * */ void I2CPositionEncodersMgr::M861() { if (parse()) return; @@ -877,7 +872,6 @@ void I2CPositionEncodersMgr::M861() { * Y Report on Y axis encoder, if present. * Z Report on Z axis encoder, if present. * E Report on E axis encoder, if present. - * */ void I2CPositionEncodersMgr::M862() { if (parse()) return; @@ -907,7 +901,6 @@ void I2CPositionEncodersMgr::M862() { * Y Report on Y axis encoder, if present. * Z Report on Z axis encoder, if present. * E Report on E axis encoder, if present. - * */ void I2CPositionEncodersMgr::M863() { if (parse()) return; diff --git a/Marlin/src/feature/I2CPositionEncoder.h b/Marlin/src/feature/encoder_i2c.h similarity index 98% rename from Marlin/src/feature/I2CPositionEncoder.h rename to Marlin/src/feature/encoder_i2c.h index 0665ee809d41..511e560ba0ce 100644 --- a/Marlin/src/feature/I2CPositionEncoder.h +++ b/Marlin/src/feature/encoder_i2c.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -280,13 +280,13 @@ class I2CPositionEncodersMgr { static void set_ec_threshold(const int8_t idx, const float newThreshold, const AxisEnum axis) { CHECK_IDX(); encoders[idx].set_ec_threshold(newThreshold); - SERIAL_ECHOLNPAIR("Error correct threshold for ", axis_codes[axis], " axis set to ", FIXFLOAT(newThreshold), "mm."); + SERIAL_ECHOLNPAIR("Error correct threshold for ", axis_codes[axis], " axis set to ", newThreshold, "mm."); } static void get_ec_threshold(const int8_t idx, const AxisEnum axis) { CHECK_IDX(); const float threshold = encoders[idx].get_ec_threshold(); - SERIAL_ECHOLNPAIR("Error correct threshold for ", axis_codes[axis], " axis is ", FIXFLOAT(threshold), "mm."); + SERIAL_ECHOLNPAIR("Error correct threshold for ", axis_codes[axis], " axis is ", threshold, "mm."); } static int8_t idx_from_axis(const AxisEnum axis) { diff --git a/Marlin/src/feature/fanmux.cpp b/Marlin/src/feature/fanmux.cpp index b90c72c64813..43952ca8ee6c 100644 --- a/Marlin/src/feature/fanmux.cpp +++ b/Marlin/src/feature/fanmux.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/feature/fanmux.h b/Marlin/src/feature/fanmux.h index 2e5414447813..b1b0c67a55e0 100644 --- a/Marlin/src/feature/fanmux.h +++ b/Marlin/src/feature/fanmux.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/feature/filwidth.cpp b/Marlin/src/feature/filwidth.cpp index ae8c43d43091..2bd9c789808e 100644 --- a/Marlin/src/feature/filwidth.cpp +++ b/Marlin/src/feature/filwidth.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -42,7 +42,7 @@ int8_t FilamentWidthSensor::ratios[MAX_MEASUREMENT_DELAY + 1], // Ring void FilamentWidthSensor::init() { const int8_t ratio = sample_to_size_ratio(); - for (uint8_t i = 0; i < COUNT(ratios); ++i) ratios[i] = ratio; + LOOP_L_N(i, COUNT(ratios)) ratios[i] = ratio; index_r = index_w = 0; } diff --git a/Marlin/src/feature/filwidth.h b/Marlin/src/feature/filwidth.h index 335a49b74f1e..ef3859df719a 100644 --- a/Marlin/src/feature/filwidth.h +++ b/Marlin/src/feature/filwidth.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/feature/fwretract.cpp b/Marlin/src/feature/fwretract.cpp index 2436170b3542..e5c52562a9ad 100644 --- a/Marlin/src/feature/fwretract.cpp +++ b/Marlin/src/feature/fwretract.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -42,7 +42,7 @@ FWRetract fwretract; // Single instance - this calls the constructor // private: -#if EXTRUDERS > 1 +#if HAS_MULTI_EXTRUDER bool FWRetract::retracted_swap[EXTRUDERS]; // Which extruders are swap-retracted #endif @@ -60,9 +60,7 @@ float FWRetract::current_retract[EXTRUDERS], // Retract value used by p FWRetract::current_hop; void FWRetract::reset() { - #if ENABLED(FWRETRACT_AUTORETRACT) - autoretract_enabled = false; - #endif + TERN_(FWRETRACT_AUTORETRACT, autoretract_enabled = false); settings.retract_length = RETRACT_LENGTH; settings.retract_feedrate_mm_s = RETRACT_FEEDRATE; settings.retract_zraise = RETRACT_ZRAISE; @@ -73,11 +71,9 @@ void FWRetract::reset() { settings.swap_retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE_SWAP; current_hop = 0.0; - for (uint8_t i = 0; i < EXTRUDERS; ++i) { + LOOP_L_N(i, EXTRUDERS) { retracted[i] = false; - #if EXTRUDERS > 1 - retracted_swap[i] = false; - #endif + TERN_(HAS_MULTI_EXTRUDER, retracted_swap[i] = false); current_retract[i] = 0.0; } } @@ -94,15 +90,15 @@ void FWRetract::reset() { * included in the G-code. Use M207 Z0 to to prevent double hop. */ void FWRetract::retract(const bool retracting - #if EXTRUDERS > 1 - , bool swapping /* =false */ + #if HAS_MULTI_EXTRUDER + , bool swapping/*=false*/ #endif ) { // Prevent two retracts or recovers in a row if (retracted[active_extruder] == retracting) return; // Prevent two swap-retract or recovers in a row - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER // Allow G10 S1 only after G11 if (swapping && retracted_swap[active_extruder] == retracting) return; // G11 priority to recover the long retract if activated @@ -117,9 +113,9 @@ void FWRetract::retract(const bool retracting " swapping ", swapping, " active extruder ", active_extruder ); - for (uint8_t i = 0; i < EXTRUDERS; ++i) { + LOOP_L_N(i, EXTRUDERS) { SERIAL_ECHOLNPAIR("retracted[", i, "] ", retracted[i]); - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER SERIAL_ECHOLNPAIR("retracted_swap[", i, "] ", retracted_swap[i]); #endif } @@ -128,12 +124,8 @@ void FWRetract::retract(const bool retracting SERIAL_ECHOLNPAIR("current_hop ", current_hop); //*/ - const float base_retract = ( - (swapping ? settings.swap_retract_length : settings.retract_length) - #if ENABLED(RETRACT_SYNC_MIXING) - * (MIXING_STEPPERS) - #endif - ); + const float base_retract = TERN1(RETRACT_SYNC_MIXING, (MIXING_STEPPERS)) + * (swapping ? settings.swap_retract_length : settings.retract_length); // The current position will be the destination for E and Z moves destination = current_position; @@ -148,10 +140,7 @@ void FWRetract::retract(const bool retracting // Retract by moving from a faux E position back to the current E position current_retract[active_extruder] = base_retract; prepare_internal_move_to_destination( // set current to destination - settings.retract_feedrate_mm_s - #if ENABLED(RETRACT_SYNC_MIXING) - * (MIXING_STEPPERS) - #endif + settings.retract_feedrate_mm_s * TERN1(RETRACT_SYNC_MIXING, (MIXING_STEPPERS)) ); // Is a Z hop set, and has the hop not yet been done? @@ -177,23 +166,19 @@ void FWRetract::retract(const bool retracting current_retract[active_extruder] = 0; - const feedRate_t fr_mm_s = ( + // Recover E, set_current_to_destination + prepare_internal_move_to_destination( (swapping ? settings.swap_retract_recover_feedrate_mm_s : settings.retract_recover_feedrate_mm_s) - #if ENABLED(RETRACT_SYNC_MIXING) - * (MIXING_STEPPERS) - #endif + * TERN1(RETRACT_SYNC_MIXING, (MIXING_STEPPERS)) ); - prepare_internal_move_to_destination(fr_mm_s); // Recover E, set_current_to_destination } - #if ENABLED(RETRACT_SYNC_MIXING) - mixer.T(old_mixing_tool); // Restore original mixing tool - #endif + TERN_(RETRACT_SYNC_MIXING, mixer.T(old_mixing_tool)); // Restore original mixing tool retracted[active_extruder] = retracting; // Active extruder now retracted / recovered // If swap retract/recover update the retracted_swap flag too - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER if (swapping) retracted_swap[active_extruder] = retracting; #endif @@ -201,9 +186,9 @@ void FWRetract::retract(const bool retracting SERIAL_ECHOLNPAIR("retracting ", retracting); SERIAL_ECHOLNPAIR("swapping ", swapping); SERIAL_ECHOLNPAIR("active_extruder ", active_extruder); - for (uint8_t i = 0; i < EXTRUDERS; ++i) { + LOOP_L_N(i, EXTRUDERS) { SERIAL_ECHOLNPAIR("retracted[", i, "] ", retracted[i]); - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER SERIAL_ECHOLNPAIR("retracted_swap[", i, "] ", retracted_swap[i]); #endif } diff --git a/Marlin/src/feature/fwretract.h b/Marlin/src/feature/fwretract.h index e08f8f03af22..134851965dc4 100644 --- a/Marlin/src/feature/fwretract.h +++ b/Marlin/src/feature/fwretract.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -42,7 +42,7 @@ typedef struct { class FWRetract { private: - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER static bool retracted_swap[EXTRUDERS]; // Which extruders are swap-retracted #endif @@ -75,7 +75,7 @@ class FWRetract { } static void retract(const bool retracting - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER , bool swapping = false #endif ); diff --git a/Marlin/src/feature/host_actions.cpp b/Marlin/src/feature/host_actions.cpp index 2108f4e7f427..30126392207d 100644 --- a/Marlin/src/feature/host_actions.cpp +++ b/Marlin/src/feature/host_actions.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -37,7 +37,8 @@ #include "runout.h" #endif -void host_action(const char * const pstr, const bool eol) { +void host_action(PGM_P const pstr, const bool eol) { + PORT_REDIRECT(SERIAL_BOTH); SERIAL_ECHOPGM("//action:"); serialprintPGM(pstr); if (eol) SERIAL_EOL(); @@ -61,11 +62,14 @@ void host_action(const char * const pstr, const bool eol) { #ifdef ACTION_ON_CANCEL void host_action_cancel() { host_action(PSTR(ACTION_ON_CANCEL)); } #endif +#ifdef ACTION_ON_START + void host_action_start() { host_action(PSTR(ACTION_ON_START)); } +#endif #if ENABLED(HOST_PROMPT_SUPPORT) - const char CONTINUE_STR[] PROGMEM = "Continue", - DISMISS_STR[] PROGMEM = "Dismiss"; + PGMSTR(CONTINUE_STR, "Continue"); + PGMSTR(DISMISS_STR, "Dismiss"); #if HAS_RESUME_CONTINUE extern bool wait_for_user; @@ -74,33 +78,42 @@ void host_action(const char * const pstr, const bool eol) { PromptReason host_prompt_reason = PROMPT_NOT_DEFINED; void host_action_notify(const char * const message) { + PORT_REDIRECT(SERIAL_BOTH); + host_action(PSTR("notification "), false); + SERIAL_ECHOLN(message); + } + + void host_action_notify_P(PGM_P const message) { + PORT_REDIRECT(SERIAL_BOTH); host_action(PSTR("notification "), false); serialprintPGM(message); SERIAL_EOL(); } - void host_action_prompt(const char * const ptype, const bool eol=true) { + void host_action_prompt(PGM_P const ptype, const bool eol=true) { + PORT_REDIRECT(SERIAL_BOTH); host_action(PSTR("prompt_"), false); serialprintPGM(ptype); if (eol) SERIAL_EOL(); } - void host_action_prompt_plus(const char * const ptype, const char * const pstr, const char extra_char='\0') { + void host_action_prompt_plus(PGM_P const ptype, PGM_P const pstr, const char extra_char='\0') { host_action_prompt(ptype, false); + PORT_REDIRECT(SERIAL_BOTH); SERIAL_CHAR(' '); serialprintPGM(pstr); if (extra_char != '\0') SERIAL_CHAR(extra_char); SERIAL_EOL(); } - void host_action_prompt_begin(const PromptReason reason, const char * const pstr, const char extra_char/*='\0'*/) { + void host_action_prompt_begin(const PromptReason reason, PGM_P const pstr, const char extra_char/*='\0'*/) { host_action_prompt_end(); host_prompt_reason = reason; host_action_prompt_plus(PSTR("begin"), pstr, extra_char); } - void host_action_prompt_button(const char * const pstr) { host_action_prompt_plus(PSTR("button"), pstr); } + void host_action_prompt_button(PGM_P const pstr) { host_action_prompt_plus(PSTR("button"), pstr); } void host_action_prompt_end() { host_action_prompt(PSTR("end")); } void host_action_prompt_show() { host_action_prompt(PSTR("show")); } - void host_prompt_do(const PromptReason reason, const char * const pstr, const char * const btn1/*=nullptr*/, const char * const btn2/*=nullptr*/) { + void host_prompt_do(const PromptReason reason, PGM_P const pstr, PGM_P const btn1/*=nullptr*/, PGM_P const btn2/*=nullptr*/) { host_action_prompt_begin(reason, pstr); if (btn1) host_action_prompt_button(btn1); if (btn2) host_action_prompt_button(btn2); @@ -108,11 +121,7 @@ void host_action(const char * const pstr, const bool eol) { } void filament_load_host_prompt() { - const bool disable_to_continue = (false - #if HAS_FILAMENT_SENSOR - || runout.filament_ran_out - #endif - ); + const bool disable_to_continue = TERN0(HAS_FILAMENT_SENSOR, runout.filament_ran_out); host_prompt_do(PROMPT_FILAMENT_RUNOUT, PSTR("Paused"), PSTR("PurgeMore"), disable_to_continue ? PSTR("DisableRunout") : CONTINUE_STR ); @@ -127,11 +136,11 @@ void host_action(const char * const pstr, const bool eol) { // void host_response_handler(const uint8_t response) { #ifdef DEBUG_HOST_ACTIONS - static const char m876_prefix[] PROGMEM = "M876 Handle Re"; + static PGMSTR(m876_prefix, "M876 Handle Re"); serialprintPGM(m876_prefix); SERIAL_ECHOLNPAIR("ason: ", host_prompt_reason); serialprintPGM(m876_prefix); SERIAL_ECHOLNPAIR("sponse: ", response); #endif - const char *msg = PSTR("UNKNOWN STATE"); + PGM_P msg = PSTR("UNKNOWN STATE"); const PromptReason hpr = host_prompt_reason; host_prompt_reason = PROMPT_NOT_DEFINED; // Reset now ahead of logic switch (hpr) { @@ -140,14 +149,14 @@ void host_action(const char * const pstr, const bool eol) { switch (response) { case 0: // "Purge More" button - #if HAS_LCD_MENU && ENABLED(ADVANCED_PAUSE_FEATURE) + #if BOTH(HAS_LCD_MENU, ADVANCED_PAUSE_FEATURE) pause_menu_response = PAUSE_RESPONSE_EXTRUDE_MORE; // Simulate menu selection (menu exits, doesn't extrude more) #endif filament_load_host_prompt(); // Initiate another host prompt. (NOTE: The loop in load_filament may also do this!) break; case 1: // "Continue" / "Disable Runout" button - #if HAS_LCD_MENU && ENABLED(ADVANCED_PAUSE_FEATURE) + #if BOTH(HAS_LCD_MENU, ADVANCED_PAUSE_FEATURE) pause_menu_response = PAUSE_RESPONSE_RESUME_PRINT; // Simulate menu selection #endif #if HAS_FILAMENT_SENSOR @@ -160,9 +169,7 @@ void host_action(const char * const pstr, const bool eol) { } break; case PROMPT_USER_CONTINUE: - #if HAS_RESUME_CONTINUE - wait_for_user = false; - #endif + TERN_(HAS_RESUME_CONTINUE, wait_for_user = false); msg = PSTR("FILAMENT_RUNOUT_CONTINUE"); break; case PROMPT_PAUSE_RESUME: diff --git a/Marlin/src/feature/host_actions.h b/Marlin/src/feature/host_actions.h index 3667b7f4308e..09eeed23e215 100644 --- a/Marlin/src/feature/host_actions.h +++ b/Marlin/src/feature/host_actions.h @@ -16,14 +16,15 @@ * 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 . + * along with this program. If not, see . * */ #pragma once #include "../inc/MarlinConfigPre.h" +#include "../HAL/shared/Marduino.h" -void host_action(const char * const pstr, const bool eol=true); +void host_action(PGM_P const pstr, const bool eol=true); #ifdef ACTION_ON_KILL void host_action_kill(); @@ -43,6 +44,9 @@ void host_action(const char * const pstr, const bool eol=true); #ifdef ACTION_ON_CANCEL void host_action_cancel(); #endif +#ifdef ACTION_ON_START + void host_action_start(); +#endif #if ENABLED(HOST_PROMPT_SUPPORT) @@ -61,12 +65,13 @@ void host_action(const char * const pstr, const bool eol=true); void host_response_handler(const uint8_t response); void host_action_notify(const char * const message); - void host_action_prompt_begin(const PromptReason reason, const char * const pstr, const char extra_char='\0'); - void host_action_prompt_button(const char * const pstr); + void host_action_notify_P(PGM_P const message); + void host_action_prompt_begin(const PromptReason reason, PGM_P const pstr, const char extra_char='\0'); + void host_action_prompt_button(PGM_P const pstr); void host_action_prompt_end(); void host_action_prompt_show(); - void host_prompt_do(const PromptReason reason, const char * const pstr, const char * const btn1=nullptr, const char * const btn2=nullptr); - inline void host_prompt_open(const PromptReason reason, const char * const pstr, const char * const btn1=nullptr, const char * const btn2=nullptr) { + void host_prompt_do(const PromptReason reason, PGM_P const pstr, PGM_P const btn1=nullptr, PGM_P const btn2=nullptr); + inline void host_prompt_open(const PromptReason reason, PGM_P const pstr, PGM_P const btn1=nullptr, PGM_P const btn2=nullptr) { if (host_prompt_reason == PROMPT_NOT_DEFINED) host_prompt_do(reason, pstr, btn1, btn2); } diff --git a/Marlin/src/feature/hotend_idle.cpp b/Marlin/src/feature/hotend_idle.cpp new file mode 100644 index 000000000000..6d94f5f57e60 --- /dev/null +++ b/Marlin/src/feature/hotend_idle.cpp @@ -0,0 +1,91 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * Hotend Idle Timeout + * Prevent filament in the nozzle from charring and causing a critical jam. + */ + +#include "../inc/MarlinConfig.h" + +#if ENABLED(HOTEND_IDLE_TIMEOUT) + +#include "hotend_idle.h" +#include "../gcode/gcode.h" + +#include "../module/temperature.h" +#include "../module/motion.h" +#include "../lcd/ultralcd.h" +#include "../module/planner.h" + +extern HotendIdleProtection hotend_idle; + +millis_t HotendIdleProtection::next_protect_ms = 0; + +void HotendIdleProtection::check_hotends(const millis_t &ms) { + bool do_prot = false; + HOTEND_LOOP() { + const bool busy = (TERN0(HAS_RESUME_CONTINUE, wait_for_user) || planner.has_blocks_queued()); + if (thermalManager.degHotend(e) >= HOTEND_IDLE_MIN_TRIGGER && !busy) { + do_prot = true; break; + } + } + if (bool(next_protect_ms) != do_prot) + next_protect_ms = do_prot ? ms + hp_interval : 0; +} + +void HotendIdleProtection::check_e_motion(const millis_t &ms) { + static float old_e_position = 0; + if (old_e_position != current_position.e) { + old_e_position = current_position.e; // Track filament motion + if (next_protect_ms) // If some heater is on then... + next_protect_ms = ms + hp_interval; // ...delay the timeout till later + } +} + +void HotendIdleProtection::check() { + const millis_t ms = millis(); // Shared millis + + check_hotends(ms); // Any hotends need protection? + check_e_motion(ms); // Motion will protect them + + // Hot and not moving for too long... + if (next_protect_ms && ELAPSED(ms, next_protect_ms)) + timed_out(); +} + +// Lower (but don't raise) hotend / bed temperatures +void HotendIdleProtection::timed_out() { + next_protect_ms = 0; + SERIAL_ECHOLNPGM("Hotend Idle Timeout"); + LCD_MESSAGEPGM(MSG_HOTEND_IDLE_TIMEOUT); + HOTEND_LOOP() { + if ((HOTEND_IDLE_NOZZLE_TARGET) < thermalManager.degTargetHotend(e)) + thermalManager.setTargetHotend(HOTEND_IDLE_NOZZLE_TARGET, e); + } + #if HAS_HEATED_BED + if ((HOTEND_IDLE_BED_TARGET) < thermalManager.degTargetBed()) + thermalManager.setTargetBed(HOTEND_IDLE_BED_TARGET); + #endif +} + +#endif // HOTEND_IDLE_TIMEOUT diff --git a/Marlin/src/feature/hotend_idle.h b/Marlin/src/feature/hotend_idle.h new file mode 100644 index 000000000000..40f557d5ed4c --- /dev/null +++ b/Marlin/src/feature/hotend_idle.h @@ -0,0 +1,37 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../core/millis_t.h" + +class HotendIdleProtection { +public: + static void check(); +private: + static constexpr millis_t hp_interval = SEC_TO_MS(HOTEND_IDLE_TIMEOUT_SEC); + static millis_t next_protect_ms; + static void check_hotends(const millis_t &ms); + static void check_e_motion(const millis_t &ms); + static void timed_out(); +}; + +extern HotendIdleProtection hotend_idle; diff --git a/Marlin/src/feature/joystick.cpp b/Marlin/src/feature/joystick.cpp index 70c2812a37aa..d9c5ae7c1b1c 100644 --- a/Marlin/src/feature/joystick.cpp +++ b/Marlin/src/feature/joystick.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -37,7 +37,7 @@ Joystick joystick; #if ENABLED(EXTENSIBLE_UI) - #include "../lcd/extensible_ui/ui_api.h" + #include "../lcd/extui/ui_api.h" #endif #if HAS_JOY_ADC_X @@ -154,9 +154,7 @@ Joystick joystick; // Other non-joystick poll-based jogging could be implemented here // with "jogging" encapsulated as a more general class. - #if ENABLED(EXTENSIBLE_UI) - ExtUI::_joystick_update(norm_jog); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::_joystick_update(norm_jog)); // norm_jog values of [-1 .. 1] maps linearly to [-feedrate .. feedrate] xyz_float_t move_dist{0}; @@ -173,6 +171,7 @@ Joystick joystick; if (!UNEAR_ZERO(hypot2)) { current_position += move_dist; + apply_motion_limits(current_position); const float length = sqrt(hypot2); injecting_now = true; planner.buffer_line(current_position, length / seg_time, active_extruder, length); diff --git a/Marlin/src/feature/joystick.h b/Marlin/src/feature/joystick.h index 12f9554a714e..1d25a30cc24d 100644 --- a/Marlin/src/feature/joystick.h +++ b/Marlin/src/feature/joystick.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -30,24 +30,14 @@ #include "../core/macros.h" #include "../module/temperature.h" -//#define JOYSTICK_DEBUG - class Joystick { friend class Temperature; private: - #if HAS_JOY_ADC_X - static temp_info_t x; - #endif - #if HAS_JOY_ADC_Y - static temp_info_t y; - #endif - #if HAS_JOY_ADC_Z - static temp_info_t z; - #endif + TERN_(HAS_JOY_ADC_X, static temp_info_t x); + TERN_(HAS_JOY_ADC_Y, static temp_info_t y); + TERN_(HAS_JOY_ADC_Z, static temp_info_t z); public: - #if ENABLED(JOYSTICK_DEBUG) - static void report(); - #endif + TERN_(JOYSTICK_DEBUG, static void report()); static void calculate(xyz_float_t &norm_jog); static void inject_jog_moves(); }; diff --git a/Marlin/src/feature/leds/blinkm.cpp b/Marlin/src/feature/leds/blinkm.cpp index 1c7ceeb669df..868eb4b3d916 100644 --- a/Marlin/src/feature/leds/blinkm.cpp +++ b/Marlin/src/feature/leds/blinkm.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/feature/leds/blinkm.h b/Marlin/src/feature/leds/blinkm.h index c7c099d3a847..29a9e784120d 100644 --- a/Marlin/src/feature/leds/blinkm.h +++ b/Marlin/src/feature/leds/blinkm.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/feature/leds/leds.cpp b/Marlin/src/feature/leds/leds.cpp index 995693ffc50c..ef9099fb2093 100644 --- a/Marlin/src/feature/leds/leds.cpp +++ b/Marlin/src/feature/leds/leds.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -39,16 +39,13 @@ #endif #if ENABLED(PCA9533) - #include + #include "pca9533.h" #endif #if ENABLED(LED_COLOR_PRESETS) const LEDColor LEDLights::defaultLEDColor = MakeLEDColor( - LED_USER_PRESET_RED, - LED_USER_PRESET_GREEN, - LED_USER_PRESET_BLUE, - LED_USER_PRESET_WHITE, - LED_USER_PRESET_BRIGHTNESS + LED_USER_PRESET_RED, LED_USER_PRESET_GREEN, LED_USER_PRESET_BLUE, + LED_USER_PRESET_WHITE, LED_USER_PRESET_BRIGHTNESS ); #endif @@ -68,15 +65,9 @@ void LEDLights::setup() { if (PWM_PIN(RGB_LED_W_PIN)) SET_PWM(RGB_LED_W_PIN); else SET_OUTPUT(RGB_LED_W_PIN); #endif #endif - #if ENABLED(NEOPIXEL_LED) - neo.init(); - #endif - #if ENABLED(PCA9533) - RGBinit(); - #endif - #if ENABLED(LED_USER_PRESET_STARTUP) - set_default(); - #endif + TERN_(NEOPIXEL_LED, neo.init()); + TERN_(PCA9533, PCA9533_init()); + TERN_(LED_USER_PRESET_STARTUP, set_default()); } void LEDLights::set_color(const LEDColor &incol @@ -123,26 +114,22 @@ void LEDLights::set_color(const LEDColor &incol // This variant uses 3-4 separate pins for the RGB(W) components. // If the pins can do PWM then their intensity will be set. - #define UPDATE_RGBW(C,c) do { if (PWM_PIN(RGB_LED_##C##_PIN)) \ + #define UPDATE_RGBW(C,c) do { \ + if (PWM_PIN(RGB_LED_##C##_PIN)) \ analogWrite(pin_t(RGB_LED_##C##_PIN), incol.c); \ - else WRITE(RGB_LED_##C##_PIN, incol.c ? HIGH : LOW); }while(0) - UPDATE_RGBW(R,r); - UPDATE_RGBW(G,g); - UPDATE_RGBW(B,b); + else \ + WRITE(RGB_LED_##C##_PIN, incol.c ? HIGH : LOW); \ + }while(0) + UPDATE_RGBW(R,r); UPDATE_RGBW(G,g); UPDATE_RGBW(B,b); #if ENABLED(RGBW_LED) UPDATE_RGBW(W,w); #endif #endif - #if ENABLED(PCA9632) - // Update I2C LED driver - pca9632_set_led_color(incol); - #endif - - #if ENABLED(PCA9533) - RGBsetColor(incol.r, incol.g, incol.b, true); - #endif + // Update I2C LED driver + TERN_(PCA9632, PCA9632_set_led_color(incol)); + TERN_(PCA9533, PCA9533_set_rgb(incol.r, incol.g, incol.b)); #if EITHER(LED_CONTROL_MENU, PRINTER_EVENT_LEDS) // Don't update the color when OFF @@ -169,4 +156,45 @@ void LEDLights::set_color(const LEDColor &incol #endif -#endif // HAS_COLOR_LEDS +#if ENABLED(NEOPIXEL2_SEPARATE) + + #if ENABLED(NEO2_COLOR_PRESETS) + const LEDColor LEDLights2::defaultLEDColor = MakeLEDColor( + NEO2_USER_PRESET_RED, NEO2_USER_PRESET_GREEN, NEO2_USER_PRESET_BLUE, + NEO2_USER_PRESET_WHITE, NEO2_USER_PRESET_BRIGHTNESS + ); + #endif + + #if ENABLED(LED_CONTROL_MENU) + LEDColor LEDLights2::color; + bool LEDLights2::lights_on; + #endif + + LEDLights2 leds2; + + void LEDLights2::setup() { + neo2.init(); + TERN_(NEO2_USER_PRESET_STARTUP, set_default()); + } + + void LEDLights2::set_color(const LEDColor &incol) { + const uint32_t neocolor = LEDColorWhite() == incol + ? neo2.Color(NEO2_WHITE) + : neo2.Color(incol.r, incol.g, incol.b, incol.w); + neo2.set_brightness(incol.i); + neo2.set_color(neocolor); + + #if ENABLED(LED_CONTROL_MENU) + // Don't update the color when OFF + lights_on = !incol.is_off(); + if (lights_on) color = incol; + #endif + } + + #if ENABLED(LED_CONTROL_MENU) + void LEDLights2::toggle() { if (lights_on) set_off(); else update(); } + #endif + +#endif // NEOPIXEL2_SEPARATE + +#endif // HAS_COLOR_LEDS diff --git a/Marlin/src/feature/leds/leds.h b/Marlin/src/feature/leds/leds.h index 22184381fc4d..055ea0df37ad 100644 --- a/Marlin/src/feature/leds/leds.h +++ b/Marlin/src/feature/leds/leds.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -34,7 +34,9 @@ #endif // A white component can be passed -#define HAS_WHITE_LED EITHER(RGBW_LED, NEOPIXEL_LED) +#if EITHER(RGBW_LED, NEOPIXEL_LED) + #define HAS_WHITE_LED 1 +#endif /** * LEDcolor type for use with leds.set_color @@ -85,9 +87,7 @@ typedef struct LEDColor { LEDColor& operator=(const uint8_t (&rgbw)[4]) { r = rgbw[0]; g = rgbw[1]; b = rgbw[2]; - #if HAS_WHITE_LED - w = rgbw[3]; - #endif + TERN_(HAS_WHITE_LED, w = rgbw[3]); return *this; } @@ -104,11 +104,7 @@ typedef struct LEDColor { bool operator!=(const LEDColor &right) { return !operator==(right); } bool is_off() const { - return 3 > r + g + b - #if HAS_WHITE_LED - + w - #endif - ; + return 3 > r + g + b + TERN0(HAS_WHITE_LED, w); } } LEDColor; @@ -156,14 +152,12 @@ class LEDLights { #endif ); - inline void set_color(uint8_t r, uint8_t g, uint8_t b + static inline void set_color(uint8_t r, uint8_t g, uint8_t b #if HAS_WHITE_LED , uint8_t w=0 - #if ENABLED(NEOPIXEL_LED) - , uint8_t i=NEOPIXEL_BRIGHTNESS - #endif #endif #if ENABLED(NEOPIXEL_LED) + , uint8_t i=NEOPIXEL_BRIGHTNESS , bool isSequence=false #endif ) { @@ -216,3 +210,44 @@ class LEDLights { }; extern LEDLights leds; + +#if ENABLED(NEOPIXEL2_SEPARATE) + + class LEDLights2 { + public: + LEDLights2() {} + + static void setup(); // init() + + static void set_color(const LEDColor &color); + + inline void set_color(uint8_t r, uint8_t g, uint8_t b, uint8_t w=0, uint8_t i=NEOPIXEL2_BRIGHTNESS) { + set_color(MakeLEDColor(r, g, b, w, i)); + } + + static inline void set_off() { set_color(LEDColorOff()); } + static inline void set_green() { set_color(LEDColorGreen()); } + static inline void set_white() { set_color(LEDColorWhite()); } + + #if ENABLED(NEO2_COLOR_PRESETS) + static const LEDColor defaultLEDColor; + static inline void set_default() { set_color(defaultLEDColor); } + static inline void set_red() { set_color(LEDColorRed()); } + static inline void set_orange() { set_color(LEDColorOrange()); } + static inline void set_yellow() { set_color(LEDColorYellow()); } + static inline void set_blue() { set_color(LEDColorBlue()); } + static inline void set_indigo() { set_color(LEDColorIndigo()); } + static inline void set_violet() { set_color(LEDColorViolet()); } + #endif + + #if ENABLED(NEOPIXEL2_SEPARATE) + static LEDColor color; // last non-off color + static bool lights_on; // the last set color was "on" + static void toggle(); // swap "off" with color + static inline void update() { set_color(color); } + #endif + }; + + extern LEDLights2 leds2; + +#endif // NEOPIXEL2_SEPARATE diff --git a/Marlin/src/feature/leds/neopixel.cpp b/Marlin/src/feature/leds/neopixel.cpp index 892ebe15cbc7..27bbeb348c5d 100644 --- a/Marlin/src/feature/leds/neopixel.cpp +++ b/Marlin/src/feature/leds/neopixel.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -30,14 +30,15 @@ #include "neopixel.h" -#if ENABLED(NEOPIXEL_STARTUP_TEST) +#if EITHER(NEOPIXEL_STARTUP_TEST, NEOPIXEL2_STARTUP_TEST) #include "../../core/utility.h" #endif Marlin_NeoPixel neo; +int8_t Marlin_NeoPixel::neoindex; Adafruit_NeoPixel Marlin_NeoPixel::adaneo1(NEOPIXEL_PIXELS, NEOPIXEL_PIN, NEOPIXEL_TYPE + NEO_KHZ800) - #if MULTIPLE_NEOPIXEL_TYPES + #if CONJOINED_NEOPIXEL , Marlin_NeoPixel::adaneo2(NEOPIXEL_PIXELS, NEOPIXEL2_PIN, NEOPIXEL2_TYPE + NEO_KHZ800) #endif ; @@ -52,14 +53,20 @@ Adafruit_NeoPixel Marlin_NeoPixel::adaneo1(NEOPIXEL_PIXELS, NEOPIXEL_PIN, NEOPIX #endif void Marlin_NeoPixel::set_color(const uint32_t color) { - for (uint16_t i = 0; i < pixels(); ++i) { - #ifdef NEOPIXEL_BKGD_LED_INDEX - if (i == NEOPIXEL_BKGD_LED_INDEX && color != 0x000000) { - set_color_background(); - continue; - } - #endif - set_pixel_color(i, color); + if (neoindex >= 0) { + set_pixel_color(neoindex, color); + neoindex = -1; + } + else { + for (uint16_t i = 0; i < pixels(); ++i) { + #ifdef NEOPIXEL_BKGD_LED_INDEX + if (i == NEOPIXEL_BKGD_LED_INDEX && color != 0x000000) { + set_color_background(); + continue; + } + #endif + set_pixel_color(i, color); + } } show(); } @@ -71,19 +78,18 @@ void Marlin_NeoPixel::set_color_startup(const uint32_t color) { } void Marlin_NeoPixel::init() { - SET_OUTPUT(NEOPIXEL_PIN); - set_brightness(NEOPIXEL_BRIGHTNESS); // 0 - 255 range + neoindex = -1; // -1 .. NEOPIXEL_PIXELS-1 range + set_brightness(NEOPIXEL_BRIGHTNESS); // 0 .. 255 range begin(); show(); // initialize to all off #if ENABLED(NEOPIXEL_STARTUP_TEST) - safe_delay(1000); set_color_startup(adaneo1.Color(255, 0, 0, 0)); // red - safe_delay(1000); + safe_delay(500); set_color_startup(adaneo1.Color(0, 255, 0, 0)); // green - safe_delay(1000); + safe_delay(500); set_color_startup(adaneo1.Color(0, 0, 255, 0)); // blue - safe_delay(1000); + safe_delay(500); #endif #ifdef NEOPIXEL_BKGD_LED_INDEX @@ -114,4 +120,53 @@ bool Marlin_NeoPixel::set_led_color(const uint8_t r, const uint8_t g, const uint } #endif +#if ENABLED(NEOPIXEL2_SEPARATE) + + Marlin_NeoPixel2 neo2; + + int8_t Marlin_NeoPixel2::neoindex; + Adafruit_NeoPixel Marlin_NeoPixel2::adaneo(NEOPIXEL2_PIXELS, NEOPIXEL2_PIN, NEOPIXEL2_TYPE); + + void Marlin_NeoPixel2::set_color(const uint32_t color) { + if (neoindex >= 0) { + set_pixel_color(neoindex, color); + neoindex = -1; + } + else { + for (uint16_t i = 0; i < pixels(); ++i) + set_pixel_color(i, color); + } + show(); + } + + void Marlin_NeoPixel2::set_color_startup(const uint32_t color) { + for (uint16_t i = 0; i < pixels(); ++i) + set_pixel_color(i, color); + show(); + } + + void Marlin_NeoPixel2::init() { + neoindex = -1; // -1 .. NEOPIXEL2_PIXELS-1 range + set_brightness(NEOPIXEL2_BRIGHTNESS); // 0 .. 255 range + begin(); + show(); // initialize to all off + + #if ENABLED(NEOPIXEL2_STARTUP_TEST) + set_color_startup(adaneo.Color(255, 0, 0, 0)); // red + safe_delay(500); + set_color_startup(adaneo.Color(0, 255, 0, 0)); // green + safe_delay(500); + set_color_startup(adaneo.Color(0, 0, 255, 0)); // blue + safe_delay(500); + #endif + + #if ENABLED(NEO2_USER_PRESET_STARTUP) + set_color(adaneo.Color(NEO2_USER_PRESET_RED, NEO2_USER_PRESET_GREEN, NEO2_USER_PRESET_BLUE, NEO2_USER_PRESET_WHITE)); + #else + set_color(adaneo.Color(0, 0, 0, 0)); + #endif + } + +#endif // NEOPIXEL2_SEPARATE + #endif // NEOPIXEL_LED diff --git a/Marlin/src/feature/leds/neopixel.h b/Marlin/src/feature/leds/neopixel.h index 11e435b83048..42046fa5638f 100644 --- a/Marlin/src/feature/leds/neopixel.h +++ b/Marlin/src/feature/leds/neopixel.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once /** - * Neopixel support + * NeoPixel support */ // ------------------------ @@ -38,10 +38,19 @@ // Defines // ------------------------ -#define MULTIPLE_NEOPIXEL_TYPES (defined(NEOPIXEL2_TYPE) && (NEOPIXEL2_TYPE != NEOPIXEL_TYPE)) +#if defined(NEOPIXEL2_TYPE) && NEOPIXEL2_TYPE != NEOPIXEL_TYPE && DISABLED(NEOPIXEL2_SEPARATE) + #define MULTIPLE_NEOPIXEL_TYPES 1 +#endif + +#if EITHER(MULTIPLE_NEOPIXEL_TYPES, NEOPIXEL2_INSERIES) + #define CONJOINED_NEOPIXEL 1 +#endif -#define NEOPIXEL_IS_RGB (NEOPIXEL_TYPE == NEO_RGB || NEOPIXEL_TYPE == NEO_RBG || NEOPIXEL_TYPE == NEO_GRB || NEOPIXEL_TYPE == NEO_GBR || NEOPIXEL_TYPE == NEO_BRG || NEOPIXEL_TYPE == NEO_BGR) -#define NEOPIXEL_IS_RGBW !NEOPIXEL_IS_RGB +#if NEOPIXEL_TYPE == NEO_RGB || NEOPIXEL_TYPE == NEO_RBG || NEOPIXEL_TYPE == NEO_GRB || NEOPIXEL_TYPE == NEO_GBR || NEOPIXEL_TYPE == NEO_BRG || NEOPIXEL_TYPE == NEO_BGR + #define NEOPIXEL_IS_RGB 1 +#else + #define NEOPIXEL_IS_RGBW 1 +#endif #if NEOPIXEL_IS_RGB #define NEO_WHITE 255, 255, 255, 0 @@ -56,12 +65,14 @@ class Marlin_NeoPixel { private: static Adafruit_NeoPixel adaneo1 - #if MULTIPLE_NEOPIXEL_TYPES + #if CONJOINED_NEOPIXEL , adaneo2 #endif ; public: + static int8_t neoindex; + static void init(); static void set_color_startup(const uint32_t c); @@ -73,32 +84,33 @@ class Marlin_NeoPixel { static inline void begin() { adaneo1.begin(); - #if MULTIPLE_NEOPIXEL_TYPES - adaneo2.begin(); - #endif + TERN_(CONJOINED_NEOPIXEL, adaneo2.begin()); } static inline void set_pixel_color(const uint16_t n, const uint32_t c) { - adaneo1.setPixelColor(n, c); - #if MULTIPLE_NEOPIXEL_TYPES - adaneo2.setPixelColor(n, c); + #if ENABLED(NEOPIXEL2_INSERIES) + if (n >= NEOPIXEL_PIXELS) adaneo2.setPixelColor(n - (NEOPIXEL_PIXELS), c); + else adaneo1.setPixelColor(n, c); + #else + adaneo1.setPixelColor(n, c); + #if MULTIPLE_NEOPIXEL_TYPES + adaneo2.setPixelColor(n, c); + #endif #endif } static inline void set_brightness(const uint8_t b) { adaneo1.setBrightness(b); - #if MULTIPLE_NEOPIXEL_TYPES - adaneo2.setBrightness(b); - #endif + TERN_(CONJOINED_NEOPIXEL, adaneo2.setBrightness(b)); } static inline void show() { adaneo1.show(); #if PIN_EXISTS(NEOPIXEL2) - #if MULTIPLE_NEOPIXEL_TYPES + #if CONJOINED_NEOPIXEL adaneo2.show(); #else - adaneo1.setPin(NEOPIXEL2_PIN); + TERN(NEOPIXEL2_SEPARATE,,adaneo1.setPin(NEOPIXEL2_PIN)); adaneo1.show(); adaneo1.setPin(NEOPIXEL_PIN); #endif @@ -110,7 +122,7 @@ class Marlin_NeoPixel { #endif // Accessors - static inline uint16_t pixels() { return adaneo1.numPixels(); } + static inline uint16_t pixels() { TERN(NEOPIXEL2_INSERIES, return adaneo1.numPixels() * 2, return adaneo1.numPixels()); } static inline uint8_t brightness() { return adaneo1.getBrightness(); } static inline uint32_t Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w) { return adaneo1.Color(r, g, b, w); @@ -118,3 +130,50 @@ class Marlin_NeoPixel { }; extern Marlin_NeoPixel neo; + +// Neo pixel channel 2 +#if ENABLED(NEOPIXEL2_SEPARATE) + + #if NEOPIXEL2_TYPE == NEO_RGB || NEOPIXEL2_TYPE == NEO_RBG || NEOPIXEL2_TYPE == NEO_GRB || NEOPIXEL2_TYPE == NEO_GBR || NEOPIXEL2_TYPE == NEO_BRG || NEOPIXEL2_TYPE == NEO_BGR + #define NEOPIXEL2_IS_RGB 1 + #else + #define NEOPIXEL2_IS_RGBW 1 + #endif + + #if NEOPIXEL2_IS_RGB + #define NEO2_WHITE 255, 255, 255, 0 + #else + #define NEO2_WHITE 0, 0, 0, 255 + #endif + + class Marlin_NeoPixel2 { + private: + static Adafruit_NeoPixel adaneo; + + public: + static int8_t neoindex; + + static void init(); + static void set_color_startup(const uint32_t c); + + static void set_color(const uint32_t c); + + static inline void begin() { adaneo.begin(); } + static inline void set_pixel_color(const uint16_t n, const uint32_t c) { adaneo.setPixelColor(n, c); } + static inline void set_brightness(const uint8_t b) { adaneo.setBrightness(b); } + static inline void show() { + adaneo.show(); + adaneo.setPin(NEOPIXEL2_PIN); + } + + // Accessors + static inline uint16_t pixels() { return adaneo.numPixels();} + static inline uint8_t brightness() { return adaneo.getBrightness(); } + static inline uint32_t Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w) { + return adaneo.Color(r, g, b, w); + } + }; + + extern Marlin_NeoPixel2 neo2; + +#endif // NEOPIXEL2_SEPARATE diff --git a/Marlin/src/feature/leds/pca9533.cpp b/Marlin/src/feature/leds/pca9533.cpp new file mode 100644 index 000000000000..0fd4d6675771 --- /dev/null +++ b/Marlin/src/feature/leds/pca9533.cpp @@ -0,0 +1,127 @@ +/* + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * PCA9533 LED controller driver (MightyBoard, FlashForge Creator Pro, etc.) + * by @grauerfuchs - 1 Apr 2020 + */ +#include "../../inc/MarlinConfig.h" + +#if ENABLED(PCA9533) + +#include "pca9533.h" +#include + +void PCA9533_init() { + Wire.begin(); + PCA9533_reset(); +} + +static void PCA9533_writeAllRegisters(uint8_t psc0, uint8_t pwm0, uint8_t psc1, uint8_t pwm1, uint8_t ls0){ + uint8_t data[6] = { PCA9533_REG_PSC0 | PCA9533_REGM_AI, psc0, pwm0, psc1, pwm1, ls0 }; + Wire.beginTransmission(PCA9533_Addr >> 1); + Wire.write(data, 6); + Wire.endTransmission(); + delayMicroseconds(1); +} + +static void PCA9533_writeRegister(uint8_t reg, uint8_t val){ + uint8_t data[2] = { reg, val }; + Wire.beginTransmission(PCA9533_Addr >> 1); + Wire.write(data, 2); + Wire.endTransmission(); + delayMicroseconds(1); +} + +// Reset (clear) all registers +void PCA9533_reset() { + PCA9533_writeAllRegisters(0, 0, 0, 0, 0); +} + +// Turn all LEDs off +void PCA9533_setOff() { + PCA9533_writeRegister(PCA9533_REG_SEL, 0); +} + +void PCA9533_set_rgb(uint8_t red, uint8_t green, uint8_t blue) { + uint8_t r_pwm0 = 0; // Register data - PWM value + uint8_t r_pwm1 = 0; // Register data - PWM value + + uint8_t op_g = 0, op_r = 0, op_b = 0; // Opcodes - Green, Red, Blue + + // Light theory! GREEN takes priority because + // it's the most visible to the human eye. + if (green == 0) op_g = PCA9533_LED_OP_OFF; + else if (green == 255) op_g = PCA9533_LED_OP_ON; + else { r_pwm0 = green; op_g = PCA9533_LED_OP_PWM0; } + + // RED + if (red == 0) op_r = PCA9533_LED_OP_OFF; + else if (red == 255) op_r = PCA9533_LED_OP_ON; + else if (r_pwm0 == 0 || r_pwm0 == red) { + r_pwm0 = red; op_r = PCA9533_LED_OP_PWM0; + } + else { + r_pwm1 = red; op_r = PCA9533_LED_OP_PWM1; + } + + // BLUE + if (blue == 0) op_b = PCA9533_LED_OP_OFF; + else if (blue == 255) op_b = PCA9533_LED_OP_ON; + else if (r_pwm0 == 0 || r_pwm0 == blue) { + r_pwm0 = blue; op_b = PCA9533_LED_OP_PWM0; + } + else if (r_pwm1 == 0 || r_pwm1 == blue) { + r_pwm1 = blue; op_b = PCA9533_LED_OP_PWM1; + } + else { + /** + * Conflict. 3 values are requested but only 2 channels exist. + * G is on channel 0 and R is on channel 1, so work from there. + * Find the closest match, average the values, then use the free channel. + */ + uint8_t dgb = ABS(green - blue), + dgr = ABS(green - red), + dbr = ABS(blue - red); + if (dgb < dgr && dgb < dbr) { // Mix with G on channel 0. + op_b = PCA9533_LED_OP_PWM0; + r_pwm0 = uint8_t(((uint16_t)green + (uint16_t)blue) / 2); + } + else if (dbr <= dgr && dbr <= dgb) { // Mix with R on channel 1. + op_b = PCA9533_LED_OP_PWM1; + r_pwm1 = uint8_t(((uint16_t)red + (uint16_t)blue) / 2); + } + else { // Mix R+G on 0 and put B on 1. + op_r = PCA9533_LED_OP_PWM0; + r_pwm0 = uint8_t(((uint16_t)green + (uint16_t)red) / 2); + op_b = PCA9533_LED_OP_PWM1; + r_pwm1 = blue; + } + } + + // Write the changes to the hardware + PCA9533_writeAllRegisters(0, r_pwm0, 0, r_pwm1, + (op_g << PCA9533_LED_OFS_GRN) | (op_r << PCA9533_LED_OFS_RED) | (op_b << PCA9533_LED_OFS_BLU) + ); +} + +#endif // PCA9533 diff --git a/Marlin/src/feature/leds/pca9533.h b/Marlin/src/feature/leds/pca9533.h new file mode 100644 index 000000000000..431058c49136 --- /dev/null +++ b/Marlin/src/feature/leds/pca9533.h @@ -0,0 +1,59 @@ +/* + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/* + * Driver for the PCA9533 LED controller found on the MightyBoard + * used by FlashForge Creator Pro, MakerBot, etc. + * Written 2020 APR 01 by grauerfuchs + */ +#include + +#define ENABLE_I2C_PULLUPS + +// Chip address (for Wire) +#define PCA9533_Addr 0xC4 + +// Control registers +#define PCA9533_REG_READ 0x00 +#define PCA9533_REG_PSC0 0x01 +#define PCA9533_REG_PWM0 0x02 +#define PCA9533_REG_PSC1 0x03 +#define PCA9533_REG_PWM1 0x04 +#define PCA9533_REG_SEL 0x05 +#define PCA9533_REGM_AI 0x10 + +// LED selector operation +#define PCA9533_LED_OP_OFF 0B00 +#define PCA9533_LED_OP_ON 0B01 +#define PCA9533_LED_OP_PWM0 0B10 +#define PCA9533_LED_OP_PWM1 0B11 + +// Select register bit offsets for LED colors +#define PCA9533_LED_OFS_RED 0 +#define PCA9533_LED_OFS_GRN 2 +#define PCA9533_LED_OFS_BLU 4 + +void PCA9533_init(); +void PCA9533_reset(); +void PCA9533_set_rgb(uint8_t red, uint8_t green, uint8_t blue); +void PCA9533_setOff(); diff --git a/Marlin/src/feature/leds/pca9632.cpp b/Marlin/src/feature/leds/pca9632.cpp index af9e39b863bf..d8af31cb6ce4 100644 --- a/Marlin/src/feature/leds/pca9632.cpp +++ b/Marlin/src/feature/leds/pca9632.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -120,7 +120,7 @@ static void PCA9632_WriteAllRegisters(const byte addr, const byte regadd, const } #endif -void pca9632_set_led_color(const LEDColor &color) { +void PCA9632_set_led_color(const LEDColor &color) { Wire.begin(); if (!PCA_init) { PCA_init = 1; @@ -138,7 +138,7 @@ void pca9632_set_led_color(const LEDColor &color) { #if ENABLED(PCA9632_BUZZER) - void pca9632_buzz(const long, const uint16_t) { + void PCA9632_buzz(const long, const uint16_t) { uint8_t data[] = PCA9632_BUZZER_DATA; Wire.beginTransmission(I2C_ADDRESS(PCA9632_ADDRESS)); Wire.write(data, sizeof(data)); diff --git a/Marlin/src/feature/leds/pca9632.h b/Marlin/src/feature/leds/pca9632.h index 749230f6526f..fb59a8c18479 100644 --- a/Marlin/src/feature/leds/pca9632.h +++ b/Marlin/src/feature/leds/pca9632.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -29,9 +29,9 @@ struct LEDColor; typedef LEDColor LEDColor; -void pca9632_set_led_color(const LEDColor &color); +void PCA9632_set_led_color(const LEDColor &color); #if ENABLED(PCA9632_BUZZER) #include - void pca9632_buzz(const long, const uint16_t); + void PCA9632_buzz(const long, const uint16_t); #endif diff --git a/Marlin/src/feature/leds/printer_event_leds.cpp b/Marlin/src/feature/leds/printer_event_leds.cpp index 70eee76b3043..31c628c2816a 100644 --- a/Marlin/src/feature/leds/printer_event_leds.cpp +++ b/Marlin/src/feature/leds/printer_event_leds.cpp @@ -16,12 +16,12 @@ * 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 . + * along with this program. If not, see . * */ /** - * printer_event_leds.cpp - LED color changing based on printer status + * feature/leds/printer_event_leds.cpp - LED color changing based on printer status */ #include "../../inc/MarlinConfigPre.h" @@ -47,10 +47,10 @@ PrinterEventLEDs printerEventLEDs; inline void pel_set_rgb(const uint8_t r, const uint8_t g, const uint8_t b) { leds.set_color( MakeLEDColor(r, g, b, 0, neo.brightness()) - #if ENABLED(NEOPIXEL_IS_SEQUENTIAL) - , true - #endif - ); + #if ENABLED(NEOPIXEL_IS_SEQUENTIAL) + , true + #endif + ); } #endif diff --git a/Marlin/src/feature/leds/printer_event_leds.h b/Marlin/src/feature/leds/printer_event_leds.h index d2888705e7e0..86ec292aa3da 100644 --- a/Marlin/src/feature/leds/printer_event_leds.h +++ b/Marlin/src/feature/leds/printer_event_leds.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once /** - * printer_event_leds.h - LED color changing based on printer status + * feature/leds/printer_event_leds.h - LED color changing based on printer status */ #include "leds.h" diff --git a/Marlin/src/feature/leds/tempstat.cpp b/Marlin/src/feature/leds/tempstat.cpp index 2d7afdcf9e75..880258f85245 100644 --- a/Marlin/src/feature/leds/tempstat.cpp +++ b/Marlin/src/feature/leds/tempstat.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -36,10 +36,7 @@ void handle_status_leds() { static millis_t next_status_led_update_ms = 0; if (ELAPSED(millis(), next_status_led_update_ms)) { next_status_led_update_ms += 500; // Update every 0.5s - float max_temp = 0.0; - #if HAS_HEATED_BED - max_temp = _MAX(thermalManager.degTargetBed(), thermalManager.degBed()); - #endif + float max_temp = TERN0(HAS_HEATED_BED, _MAX(thermalManager.degTargetBed(), thermalManager.degBed())); HOTEND_LOOP() max_temp = _MAX(max_temp, thermalManager.degHotend(e), thermalManager.degTargetHotend(e)); const int8_t new_red = (max_temp > 55.0) ? HIGH : (max_temp < 54.0 || old_red < 0) ? LOW : old_red; diff --git a/Marlin/src/feature/leds/tempstat.h b/Marlin/src/feature/leds/tempstat.h index fefe776cfd7e..a8b919bd8c5c 100644 --- a/Marlin/src/feature/leds/tempstat.h +++ b/Marlin/src/feature/leds/tempstat.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/feature/Max7219_Debug_LEDs.cpp b/Marlin/src/feature/max7219.cpp similarity index 85% rename from Marlin/src/feature/Max7219_Debug_LEDs.cpp rename to Marlin/src/feature/max7219.cpp index 2b329db3b333..ebcb56490d4f 100644 --- a/Marlin/src/feature/Max7219_Debug_LEDs.cpp +++ b/Marlin/src/feature/max7219.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -41,31 +41,23 @@ #define MAX7219_ERRORS // Disable to save 406 bytes of Program Memory -#include "Max7219_Debug_LEDs.h" +#include "max7219.h" #include "../module/planner.h" #include "../module/stepper.h" #include "../MarlinCore.h" #include "../HAL/shared/Delay.h" -#define HAS_SIDE_BY_SIDE (ENABLED(MAX7219_SIDE_BY_SIDE) && MAX7219_NUMBER_UNITS > 1) +#if ENABLED(MAX7219_SIDE_BY_SIDE) && MAX7219_NUMBER_UNITS > 1 + #define HAS_SIDE_BY_SIDE 1 +#endif #if _ROT == 0 || _ROT == 180 - #if HAS_SIDE_BY_SIDE - #define MAX7219_X_LEDS 8 - #define MAX7219_Y_LEDS MAX7219_LINES - #else - #define MAX7219_Y_LEDS 8 - #define MAX7219_X_LEDS MAX7219_LINES - #endif + #define MAX7219_X_LEDS TERN(HAS_SIDE_BY_SIDE, 8, MAX7219_LINES) + #define MAX7219_Y_LEDS TERN(HAS_SIDE_BY_SIDE, MAX7219_LINES, 8) #elif _ROT == 90 || _ROT == 270 - #if HAS_SIDE_BY_SIDE - #define MAX7219_Y_LEDS 8 - #define MAX7219_X_LEDS MAX7219_LINES - #else - #define MAX7219_X_LEDS 8 - #define MAX7219_Y_LEDS MAX7219_LINES - #endif + #define MAX7219_X_LEDS TERN(HAS_SIDE_BY_SIDE, MAX7219_LINES, 8) + #define MAX7219_Y_LEDS TERN(HAS_SIDE_BY_SIDE, 8, MAX7219_LINES) #else #error "MAX7219_ROTATE must be a multiple of +/- 90°." #endif @@ -73,6 +65,7 @@ Max7219 max7219; uint8_t Max7219::led_line[MAX7219_LINES]; // = { 0 }; +uint8_t Max7219::suspended; // = 0; #define LINE_REG(Q) (max7219_reg_digit0 + ((Q) & 0x7)) @@ -128,7 +121,7 @@ uint8_t Max7219::led_line[MAX7219_LINES]; // = { 0 }; #define CRITICAL_SECTION_START() NOOP #define CRITICAL_SECTION_END() NOOP #else - #define SIG_DELAY() DELAY_NS(188) // Delay for 0.1875µs (16MHz AVR) or 0.15µs (20MHz AVR) + #define SIG_DELAY() DELAY_NS(250) #endif void Max7219::error(const char * const func, const int32_t v1, const int32_t v2/*=-1*/) { @@ -154,7 +147,7 @@ void Max7219::error(const char * const func, const int32_t v1, const int32_t v2/ */ inline uint32_t flipped(const uint32_t bits, const uint8_t n_bytes) { uint32_t mask = 1, outbits = 0; - for (uint8_t b = 0; b < n_bytes * 8; b++) { + LOOP_L_N(b, n_bytes * 8) { outbits <<= 1; if (bits & mask) outbits |= 1; mask <<= 1; @@ -212,6 +205,7 @@ void Max7219::send(const uint8_t reg, const uint8_t data) { // Send out a single native row of bits to just one unit void Max7219::refresh_unit_line(const uint8_t line) { + if (suspended) return; #if MAX7219_NUMBER_UNITS == 1 send(LINE_REG(line), led_line[line]); #else @@ -223,6 +217,7 @@ void Max7219::refresh_unit_line(const uint8_t line) { // Send out a single native row of bits to all units void Max7219::refresh_line(const uint8_t line) { + if (suspended) return; #if MAX7219_NUMBER_UNITS == 1 refresh_unit_line(line); #else @@ -241,9 +236,9 @@ void Max7219::set(const uint8_t line, const uint8_t bits) { // Draw an integer with optional leading zeros and optional decimal point void Max7219::print(const uint8_t start, int16_t value, uint8_t size, const bool leadzero=false, bool dec=false) { + if (suspended) return; constexpr uint8_t led_numeral[10] = { 0x7E, 0x60, 0x6D, 0x79, 0x63, 0x5B, 0x5F, 0x70, 0x7F, 0x7A }, led_decimal = 0x80, led_minus = 0x01; - bool blank = false, neg = value < 0; if (neg) value *= -1; while (size--) { @@ -295,6 +290,7 @@ void Max7219::led_toggle(const uint8_t x, const uint8_t y) { } void Max7219::send_row(const uint8_t row) { + if (suspended) return; #if _ROT == 0 || _ROT == 180 // Native Lines are horizontal too #if MAX7219_X_LEDS <= 8 refresh_unit_line(LED_IND(0, row)); // A single unit line @@ -308,6 +304,7 @@ void Max7219::send_row(const uint8_t row) { } void Max7219::send_column(const uint8_t col) { + if (suspended) return; #if _ROT == 90 || _ROT == 270 // Native Lines are vertical too #if MAX7219_Y_LEDS <= 8 refresh_unit_line(LED_IND(col, 0)); // A single unit line @@ -332,25 +329,25 @@ void Max7219::fill() { void Max7219::clear_row(const uint8_t row) { if (row >= MAX7219_Y_LEDS) return error(PSTR("clear_row"), row); - for (uint8_t x = 0; x < MAX7219_X_LEDS; x++) CLR_7219(x, row); + LOOP_L_N(x, MAX7219_X_LEDS) CLR_7219(x, row); send_row(row); } void Max7219::clear_column(const uint8_t col) { if (col >= MAX7219_X_LEDS) return error(PSTR("set_column"), col); - for (uint8_t y = 0; y < MAX7219_Y_LEDS; y++) CLR_7219(col, y); + LOOP_L_N(y, MAX7219_Y_LEDS) CLR_7219(col, y); send_column(col); } /** * Plot the low order bits of val to the specified row of the matrix. - * With 4 Max7219 units in the chain, it's possible to set 32 bits at once with - * one call to the function (if rotated 90° or 180°). + * With 4 Max7219 units in the chain, it's possible to set 32 bits at + * once with a single call to the function (if rotated 90° or 270°). */ void Max7219::set_row(const uint8_t row, const uint32_t val) { if (row >= MAX7219_Y_LEDS) return error(PSTR("set_row"), row); uint32_t mask = _BV32(MAX7219_X_LEDS - 1); - for (uint8_t x = 0; x < MAX7219_X_LEDS; x++) { + LOOP_L_N(x, MAX7219_X_LEDS) { if (val & mask) SET_7219(x, row); else CLR_7219(x, row); mask >>= 1; } @@ -359,13 +356,13 @@ void Max7219::set_row(const uint8_t row, const uint32_t val) { /** * Plot the low order bits of val to the specified column of the matrix. - * With 4 Max7219 units in the chain, it's possible to set 32 bits at once with - * one call to the function (if rotated 90° or 180°). + * With 4 Max7219 units in the chain, it's possible to set 32 bits at + * once with a single call to the function (if rotated 0° or 180°). */ void Max7219::set_column(const uint8_t col, const uint32_t val) { if (col >= MAX7219_X_LEDS) return error(PSTR("set_column"), col); uint32_t mask = _BV32(MAX7219_Y_LEDS - 1); - for (uint8_t y = 0; y < MAX7219_Y_LEDS; y++) { + LOOP_L_N(y, MAX7219_Y_LEDS) { if (val & mask) SET_7219(col, y); else CLR_7219(col, y); mask >>= 1; } @@ -430,58 +427,106 @@ void Max7219::set_columns_32bits(const uint8_t x, uint32_t val) { // Initialize the Max7219 void Max7219::register_setup() { - for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++) + LOOP_L_N(i, MAX7219_NUMBER_UNITS) send(max7219_reg_scanLimit, 0x07); pulse_load(); // Tell the chips to load the clocked out data - for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++) + LOOP_L_N(i, MAX7219_NUMBER_UNITS) send(max7219_reg_decodeMode, 0x00); // Using an led matrix (not digits) pulse_load(); // Tell the chips to load the clocked out data - for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++) + LOOP_L_N(i, MAX7219_NUMBER_UNITS) send(max7219_reg_shutdown, 0x01); // Not in shutdown mode pulse_load(); // Tell the chips to load the clocked out data - for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++) + LOOP_L_N(i, MAX7219_NUMBER_UNITS) send(max7219_reg_displayTest, 0x00); // No display test pulse_load(); // Tell the chips to load the clocked out data - for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++) + LOOP_L_N(i, MAX7219_NUMBER_UNITS) send(max7219_reg_intensity, 0x01 & 0x0F); // The first 0x0F is the value you can set // Range: 0x00 to 0x0F pulse_load(); // Tell the chips to load the clocked out data } #ifdef MAX7219_INIT_TEST -#if MAX7219_INIT_TEST == 2 - - #define MAX7219_LEDS (MAX7219_X_LEDS * MAX7219_Y_LEDS) - - void Max7219::spiral(const bool on, const uint16_t del) { - constexpr int8_t way[][2] = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } }; - int8_t px = 0, py = 0, dir = 0; - for (IF<(MAX7219_LEDS > 255), uint16_t, uint8_t>::type i = MAX7219_LEDS; i--;) { - led_set(px, py, on); - delay(del); - const int8_t x = px + way[dir][0], y = py + way[dir][1]; - if (!WITHIN(x, 0, MAX7219_X_LEDS - 1) || !WITHIN(y, 0, MAX7219_Y_LEDS - 1) || BIT_7219(x, y) == on) - dir = (dir + 1) & 0x3; - px += way[dir][0]; - py += way[dir][1]; + + uint8_t test_mode = 0; + millis_t next_patt_ms; + bool patt_on; + + #if MAX7219_INIT_TEST == 2 + + #define MAX7219_LEDS (MAX7219_X_LEDS * MAX7219_Y_LEDS) + + constexpr millis_t pattern_delay = 4; + + int8_t spiralx, spiraly, spiral_dir; + IF<(MAX7219_LEDS > 255), uint16_t, uint8_t>::type spiral_count; + + void Max7219::test_pattern() { + constexpr int8_t way[][2] = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } }; + led_set(spiralx, spiraly, patt_on); + const int8_t x = spiralx + way[spiral_dir][0], y = spiraly + way[spiral_dir][1]; + if (!WITHIN(x, 0, MAX7219_X_LEDS - 1) || !WITHIN(y, 0, MAX7219_Y_LEDS - 1) || BIT_7219(x, y) == patt_on) + spiral_dir = (spiral_dir + 1) & 0x3; + spiralx += way[spiral_dir][0]; + spiraly += way[spiral_dir][1]; + if (!spiral_count--) { + if (!patt_on) + test_mode = 0; + else { + spiral_count = MAX7219_LEDS; + spiralx = spiraly = spiral_dir = 0; + patt_on = false; + } + } } - } -#else + #else - void Max7219::sweep(const int8_t dir, const uint16_t ms, const bool on) { - uint8_t x = dir > 0 ? 0 : MAX7219_X_LEDS - 1; - for (uint8_t i = MAX7219_X_LEDS; i--; x += dir) { - set_column(x, on ? 0xFFFFFFFF : 0x00000000); - delay(ms); + constexpr millis_t pattern_delay = 20; + int8_t sweep_count, sweepx, sweep_dir; + + void Max7219::test_pattern() { + set_column(sweepx, patt_on ? 0xFFFFFFFF : 0x00000000); + sweepx += sweep_dir; + if (!WITHIN(sweepx, 0, MAX7219_X_LEDS - 1)) { + if (!patt_on) { + sweep_dir *= -1; + sweepx += sweep_dir; + } + else + sweepx -= MAX7219_X_LEDS * sweep_dir; + patt_on ^= true; + next_patt_ms += 100; + if (++test_mode > 4) test_mode = 0; + } } + + #endif + + void Max7219::run_test_pattern() { + const millis_t ms = millis(); + if (PENDING(ms, next_patt_ms)) return; + next_patt_ms = ms + pattern_delay; + test_pattern(); + } + + void Max7219::start_test_pattern() { + clear(); + test_mode = 1; + patt_on = true; + #if MAX7219_INIT_TEST == 2 + spiralx = spiraly = spiral_dir = 0; + spiral_count = MAX7219_LEDS; + #else + sweep_dir = 1; + sweepx = 0; + sweep_count = MAX7219_X_LEDS; + #endif } -#endif #endif // MAX7219_INIT_TEST void Max7219::init() { @@ -492,26 +537,14 @@ void Max7219::init() { register_setup(); - for (uint8_t i = 0; i <= 7; i++) { // Empty registers to turn all LEDs off + LOOP_LE_N(i, 7) { // Empty registers to turn all LEDs off led_line[i] = 0x00; send(max7219_reg_digit0 + i, 0); pulse_load(); // Tell the chips to load the clocked out data } #ifdef MAX7219_INIT_TEST - #if MAX7219_INIT_TEST == 2 - spiral(true, 8); - delay(150); - spiral(false, 8); - #else - // Do an aesthetically-pleasing pattern to fully test the Max7219 module and LEDs. - // Light up and turn off columns, both forward and backward. - sweep(1, 20, true); - sweep(1, 20, false); - delay(150); - sweep(-1, 20, true); - sweep(-1, 20, false); - #endif + start_test_pattern(); #endif } @@ -604,6 +637,13 @@ void Max7219::idle_tasks() { register_setup(); } + #ifdef MAX7219_INIT_TEST + if (test_mode) { + run_test_pattern(); + return; + } + #endif + #if ENABLED(MAX7219_DEBUG_PRINTER_ALIVE) if (do_blink) { led_toggle(MAX7219_X_LEDS - 1, MAX7219_Y_LEDS - 1); @@ -649,6 +689,12 @@ void Max7219::idle_tasks() { last_depth = current_depth; } #endif + + // After resume() automatically do a refresh() + if (suspended == 0x80) { + suspended = 0; + refresh(); + } } #endif // MAX7219_DEBUG diff --git a/Marlin/src/feature/Max7219_Debug_LEDs.h b/Marlin/src/feature/max7219.h similarity index 91% rename from Marlin/src/feature/Max7219_Debug_LEDs.h rename to Marlin/src/feature/max7219.h index d0b242454450..8e98c9456c3f 100644 --- a/Marlin/src/feature/Max7219_Debug_LEDs.h +++ b/Marlin/src/feature/max7219.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -88,6 +88,12 @@ class Max7219 { // Refresh all units static inline void refresh() { for (uint8_t i = 0; i < 8; i++) refresh_line(i); } + // Suspend / resume updates to the LED unit + // Use these methods to speed up multiple changes + // or to apply updates from interrupt context. + static inline void suspend() { suspended++; } + static inline void resume() { suspended--; suspended |= 0x80; } + // Update a single native line on all units static void refresh_line(const uint8_t line); @@ -126,6 +132,7 @@ class Max7219 { static void idle_tasks(); private: + static uint8_t suspended; static void error(const char * const func, const int32_t v1, const int32_t v2=-1); static void noop(); static void set(const uint8_t line, const uint8_t bits); @@ -136,11 +143,9 @@ class Max7219 { static void quantity16(const uint8_t y, const uint8_t ov, const uint8_t nv); #ifdef MAX7219_INIT_TEST - #if MAX7219_INIT_TEST == 2 - static void spiral(const bool on, const uint16_t del); - #else - static void sweep(const int8_t dir, const uint16_t ms, const bool on); - #endif + static void test_pattern(); + static void run_test_pattern(); + static void start_test_pattern(); #endif }; diff --git a/Marlin/src/feature/mixing.cpp b/Marlin/src/feature/mixing.cpp index de1cda14beca..b002e9808adc 100644 --- a/Marlin/src/feature/mixing.cpp +++ b/Marlin/src/feature/mixing.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -44,7 +44,7 @@ int_fast8_t Mixer::runner = 0; mixer_comp_t Mixer::s_color[MIXING_STEPPERS]; mixer_accu_t Mixer::accu[MIXING_STEPPERS] = { 0 }; -#if DUAL_MIXING_EXTRUDER || ENABLED(GRADIENT_MIX) +#if EITHER(HAS_DUAL_MIXING, GRADIENT_MIX) mixer_perc_t Mixer::mix[MIXING_STEPPERS]; #endif @@ -90,21 +90,19 @@ void Mixer::normalize(const uint8_t tool_index) { SERIAL_ECHOLNPGM("]"); #endif - #if ENABLED(GRADIENT_MIX) - refresh_gradient(); - #endif + TERN_(GRADIENT_MIX, refresh_gradient()); } void Mixer::reset_vtools() { // Virtual Tools 0, 1, 2, 3 = Filament 1, 2, 3, 4, etc. // Every virtual tool gets a pure filament - for (uint8_t t = 0; t < MIXING_VIRTUAL_TOOLS && t < MIXING_STEPPERS; t++) + LOOP_L_N(t, _MIN(MIXING_VIRTUAL_TOOLS, MIXING_STEPPERS)) MIXER_STEPPER_LOOP(i) color[t][i] = (t == i) ? COLOR_A_MASK : 0; // Remaining virtual tools are 100% filament 1 #if MIXING_VIRTUAL_TOOLS > MIXING_STEPPERS - for (uint8_t t = MIXING_STEPPERS; t < MIXING_VIRTUAL_TOOLS; t++) + LOOP_S_L_N(t, MIXING_STEPPERS, MIXING_VIRTUAL_TOOLS) MIXER_STEPPER_LOOP(i) color[t][i] = (i == 0) ? COLOR_A_MASK : 0; #endif @@ -115,7 +113,7 @@ void Mixer::init() { reset_vtools(); - #if ENABLED(RETRACT_SYNC_MIXING) + #if HAS_MIXER_SYNC_CHANNEL // AUTORETRACT_TOOL gets the same amount of all filaments MIXER_STEPPER_LOOP(i) color[MIXER_AUTORETRACT_TOOL][i] = COLOR_A_MASK; @@ -123,13 +121,11 @@ void Mixer::init() { ZERO(collector); - #if DUAL_MIXING_EXTRUDER || ENABLED(GRADIENT_MIX) + #if EITHER(HAS_DUAL_MIXING, GRADIENT_MIX) update_mix_from_vtool(); #endif - #if ENABLED(GRADIENT_MIX) - update_gradient_for_planner_z(); - #endif + TERN_(GRADIENT_MIX, update_gradient_for_planner_z()); } void Mixer::refresh_collector(const float proportion/*=1.0*/, const uint8_t t/*=selected_vtool*/, float (&c)[MIXING_STEPPERS]/*=collector*/) { @@ -184,7 +180,12 @@ void Mixer::refresh_collector(const float proportion/*=1.0*/, const uint8_t t/*= } void Mixer::update_gradient_for_planner_z() { - update_gradient_for_z(planner.get_axis_position_mm(Z_AXIS)); + #if ENABLED(DELTA) + get_cartesian_from_steppers(); + update_gradient_for_z(cartes.z); + #else + update_gradient_for_z(planner.get_axis_position_mm(Z_AXIS)); + #endif } #endif // GRADIENT_MIX diff --git a/Marlin/src/feature/mixing.h b/Marlin/src/feature/mixing.h index da5240995c74..7fe7062a7a52 100644 --- a/Marlin/src/feature/mixing.h +++ b/Marlin/src/feature/mixing.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ //#define MIXER_NORMALIZER_DEBUG -#ifndef __AVR__ // || DUAL_MIXING_EXTRUDER +#ifndef __AVR__ // || HAS_DUAL_MIXING // Use 16-bit (or fastest) data for the integer mix factors typedef uint_fast16_t mixer_comp_t; typedef uint_fast16_t mixer_accu_t; @@ -48,29 +48,23 @@ typedef int8_t mixer_perc_t; #endif enum MixTool { - FIRST_USER_VIRTUAL_TOOL = 0, - LAST_USER_VIRTUAL_TOOL = MIXING_VIRTUAL_TOOLS - 1, - NR_USER_VIRTUAL_TOOLS, - MIXER_DIRECT_SET_TOOL = NR_USER_VIRTUAL_TOOLS, - #if ENABLED(RETRACT_SYNC_MIXING) - MIXER_AUTORETRACT_TOOL, + FIRST_USER_VIRTUAL_TOOL = 0 + , LAST_USER_VIRTUAL_TOOL = MIXING_VIRTUAL_TOOLS - 1 + , NR_USER_VIRTUAL_TOOLS + , MIXER_DIRECT_SET_TOOL = NR_USER_VIRTUAL_TOOLS + #if HAS_MIXER_SYNC_CHANNEL + , MIXER_AUTORETRACT_TOOL #endif - NR_MIXING_VIRTUAL_TOOLS + , NR_MIXING_VIRTUAL_TOOLS }; -#if ENABLED(RETRACT_SYNC_MIXING) - #define MAX_VTOOLS 254 -#else - #define MAX_VTOOLS 255 -#endif +#define MAX_VTOOLS TERN(HAS_MIXER_SYNC_CHANNEL, 254, 255) static_assert(NR_MIXING_VIRTUAL_TOOLS <= MAX_VTOOLS, "MIXING_VIRTUAL_TOOLS must be <= " STRINGIFY(MAX_VTOOLS) "!"); -#define MIXER_STEPPER_LOOP(VAR) \ - for (uint_fast8_t VAR = 0; VAR < MIXING_STEPPERS; VAR++) - #define MIXER_BLOCK_FIELD mixer_comp_t b_color[MIXING_STEPPERS] #define MIXER_POPULATE_BLOCK() mixer.populate_block(block->b_color) #define MIXER_STEPPER_SETUP() mixer.stepper_setup(current_block->b_color) +#define MIXER_STEPPER_LOOP(VAR) for (uint_fast8_t VAR = 0; VAR < MIXING_STEPPERS; VAR++) #if ENABLED(GRADIENT_MIX) @@ -81,9 +75,7 @@ static_assert(NR_MIXING_VIRTUAL_TOOLS <= MAX_VTOOLS, "MIXING_VIRTUAL_TOOLS must int8_t start_vtool, end_vtool; // Start and end virtual tools mixer_perc_t start_mix[MIXING_STEPPERS], // Start and end mixes from those tools end_mix[MIXING_STEPPERS]; - #if ENABLED(GRADIENT_VTOOL) - int8_t vtool_index; // Use this virtual tool number as index - #endif + TERN_(GRADIENT_VTOOL, int8_t vtool_index); // Use this virtual tool number as index } gradient_t; #endif @@ -112,12 +104,8 @@ class Mixer { FORCE_INLINE static void T(const uint_fast8_t c) { selected_vtool = c; - #if ENABLED(GRADIENT_VTOOL) - refresh_gradient(); - #endif - #if DUAL_MIXING_EXTRUDER - update_mix_from_vtool(); - #endif + TERN_(GRADIENT_VTOOL, refresh_gradient()); + TERN_(HAS_DUAL_MIXING, update_mix_from_vtool()); } // Used when dealing with blocks @@ -135,7 +123,7 @@ class Mixer { MIXER_STEPPER_LOOP(i) s_color[i] = b_color[i]; } - #if DUAL_MIXING_EXTRUDER || ENABLED(GRADIENT_MIX) + #if EITHER(HAS_DUAL_MIXING, GRADIENT_MIX) static mixer_perc_t mix[MIXING_STEPPERS]; // Scratch array for the Mix in proportion to 100 @@ -173,21 +161,19 @@ class Mixer { #endif } - #endif // DUAL_MIXING_EXTRUDER || GRADIENT_MIX + #endif // HAS_DUAL_MIXING || GRADIENT_MIX - #if DUAL_MIXING_EXTRUDER + #if HAS_DUAL_MIXING // Update the virtual tool from an edited mix static inline void update_vtool_from_mix() { copy_mix_to_color(color[selected_vtool]); - #if ENABLED(GRADIENT_MIX) - refresh_gradient(); - #endif + TERN_(GRADIENT_MIX, refresh_gradient()); // MIXER_STEPPER_LOOP(i) collector[i] = mix[i]; // normalize(); } - #endif // DUAL_MIXING_EXTRUDER + #endif // HAS_DUAL_MIXING #if ENABLED(GRADIENT_MIX) diff --git a/Marlin/src/feature/prusa_MMU2/mmu2.cpp b/Marlin/src/feature/mmu2/mmu2.cpp similarity index 59% rename from Marlin/src/feature/prusa_MMU2/mmu2.cpp rename to Marlin/src/feature/mmu2/mmu2.cpp index d71edbac35f4..3d635369e438 100644 --- a/Marlin/src/feature/prusa_MMU2/mmu2.cpp +++ b/Marlin/src/feature/mmu2/mmu2.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -43,7 +43,7 @@ MMU2 mmu2; #endif #if ENABLED(EXTENSIBLE_UI) - #include "../../lcd/extensible_ui/ui_api.h" + #include "../../lcd/extui/ui_api.h" #endif #define DEBUG_OUT ENABLED(MMU2_DEBUG) @@ -51,8 +51,15 @@ MMU2 mmu2; #define MMU_TODELAY 100 #define MMU_TIMEOUT 10 -#define MMU_CMD_TIMEOUT 60000ul // 5min timeout for mmu commands (except P0) -#define MMU_P0_TIMEOUT 3000ul // Timeout for P0 command: 3seconds +#define MMU_CMD_TIMEOUT 45000UL // 45s timeout for mmu commands (except P0) +#define MMU_P0_TIMEOUT 3000UL // Timeout for P0 command: 3seconds + +#define MMU2_COMMAND(S) tx_str_P(PSTR(S "\n")) + +#if ENABLED(MMU_EXTRUDER_SENSOR) + uint8_t mmu_idl_sens = 0; + static bool mmu_loading_flag = false; +#endif #define MMU_CMD_NONE 0 #define MMU_CMD_T0 0x10 @@ -79,11 +86,7 @@ MMU2 mmu2; #define MMU_CMD_F3 0x73 #define MMU_CMD_F4 0x74 -#if ENABLED(MMU2_MODE_12V) - #define MMU_REQUIRED_FW_BUILDNR 132 -#else - #define MMU_REQUIRED_FW_BUILDNR 126 -#endif +#define MMU_REQUIRED_FW_BUILDNR TERN(MMU2_MODE_12V, 132, 126) #define MMU2_NO_TOOL 99 #define MMU_BAUD 115200 @@ -91,23 +94,32 @@ MMU2 mmu2; #define mmuSerial MMU2_SERIAL bool MMU2::enabled, MMU2::ready, MMU2::mmu_print_saved; +#if ENABLED(PRUSA_MMU2_S_MODE) + bool MMU2::mmu2s_triggered; +#endif uint8_t MMU2::cmd, MMU2::cmd_arg, MMU2::last_cmd, MMU2::extruder; int8_t MMU2::state = 0; volatile int8_t MMU2::finda = 1; volatile bool MMU2::finda_runout_valid; int16_t MMU2::version = -1, MMU2::buildnr = -1; -millis_t MMU2::last_request, MMU2::next_P0_request; +millis_t MMU2::prev_request, MMU2::prev_P0_request; char MMU2::rx_buffer[MMU_RX_SIZE], MMU2::tx_buffer[MMU_TX_SIZE]; -#if HAS_LCD_MENU && ENABLED(MMU2_MENUS) +#if BOTH(HAS_LCD_MENU, MMU2_MENUS) struct E_Step { float extrude; //!< extrude distance in mm feedRate_t feedRate; //!< feed rate in mm/s }; - static constexpr E_Step ramming_sequence[] PROGMEM = { MMU2_RAMMING_SEQUENCE }; - static constexpr E_Step load_to_nozzle_sequence[] PROGMEM = { MMU2_LOAD_TO_NOZZLE_SEQUENCE }; + static constexpr E_Step + ramming_sequence[] PROGMEM = { MMU2_RAMMING_SEQUENCE } + , load_to_nozzle_sequence[] PROGMEM = { MMU2_LOAD_TO_NOZZLE_SEQUENCE } + #if ENABLED(PRUSA_MMU2_S_MODE) + , can_load_sequence[] PROGMEM = { MMU2_CAN_LOAD_SEQUENCE } + , can_load_increment_sequence[] PROGMEM = { MMU2_CAN_LOAD_INCREMENT_SEQUENCE } + #endif + ; #endif // MMU2_MENUS @@ -142,7 +154,7 @@ void MMU2::reset() { safe_delay(20); WRITE(MMU2_RST_PIN, HIGH); #else - tx_str_P(PSTR("X0\n")); // Send soft reset + MMU2_COMMAND("X0"); // Send soft reset #endif } @@ -150,6 +162,10 @@ uint8_t MMU2::get_current_tool() { return extruder == MMU2_NO_TOOL ? -1 : extruder; } +#if EITHER(PRUSA_MMU2_S_MODE, MMU_EXTRUDER_SENSOR) + #define FILAMENT_PRESENT() (READ(FIL_RUNOUT_PIN) != FIL_RUNOUT_STATE) +#endif + void MMU2::mmu_loop() { switch (state) { @@ -161,9 +177,7 @@ void MMU2::mmu_loop() { DEBUG_ECHOLNPGM("MMU => 'start'"); DEBUG_ECHOLNPGM("MMU <= 'S1'"); - // send "read version" request - tx_str_P(PSTR("S1\n")); - + MMU2_COMMAND("S1"); // Read Version state = -2; } else if (millis() > 3000000) { @@ -178,7 +192,7 @@ void MMU2::mmu_loop() { DEBUG_ECHOLNPAIR("MMU => ", version, "\nMMU <= 'S2'"); - tx_str_P(PSTR("S2\n")); // read build number + MMU2_COMMAND("S2"); // Read Build Number state = -3; } break; @@ -194,13 +208,13 @@ void MMU2::mmu_loop() { #if ENABLED(MMU2_MODE_12V) DEBUG_ECHOLNPGM("MMU <= 'M1'"); - tx_str_P(PSTR("M1\n")); // switch to stealth mode + MMU2_COMMAND("M1"); // Stealth Mode state = -5; #else DEBUG_ECHOLNPGM("MMU <= 'P0'"); - tx_str_P(PSTR("P0\n")); // read finda + MMU2_COMMAND("P0"); // Read FINDA state = -4; #endif } @@ -214,7 +228,7 @@ void MMU2::mmu_loop() { DEBUG_ECHOLNPGM("MMU <= 'P0'"); - tx_str_P(PSTR("P0\n")); // read finda + MMU2_COMMAND("P0"); // Read FINDA state = -4; } break; @@ -228,6 +242,7 @@ void MMU2::mmu_loop() { enabled = true; state = 1; + TERN_(PRUSA_MMU2_S_MODE, mmu2s_triggered = false); } break; @@ -238,6 +253,7 @@ void MMU2::mmu_loop() { int filament = cmd - MMU_CMD_T0; DEBUG_ECHOLNPAIR("MMU <= T", filament); tx_printf_P(PSTR("T%d\n"), filament); + TERN_(MMU_EXTRUDER_SENSOR, mmu_idl_sens = 1); // enable idler sensor, if any state = 3; // wait for response } else if (WITHIN(cmd, MMU_CMD_L0, MMU_CMD_L4)) { @@ -250,14 +266,14 @@ void MMU2::mmu_loop() { else if (cmd == MMU_CMD_C0) { // continue loading DEBUG_ECHOLNPGM("MMU <= 'C0'"); - tx_str_P(PSTR("C0\n")); + MMU2_COMMAND("C0"); state = 3; // wait for response } else if (cmd == MMU_CMD_U0) { // unload current DEBUG_ECHOLNPGM("MMU <= 'U0'"); - tx_str_P(PSTR("U0\n")); + MMU2_COMMAND("U0"); state = 3; // wait for response } else if (WITHIN(cmd, MMU_CMD_E0, MMU_CMD_E4)) { @@ -270,7 +286,7 @@ void MMU2::mmu_loop() { else if (cmd == MMU_CMD_R0) { // recover after eject DEBUG_ECHOLNPGM("MMU <= 'R0'"); - tx_str_P(PSTR("R0\n")); + MMU2_COMMAND("R0"); state = 3; // wait for response } else if (WITHIN(cmd, MMU_CMD_F0, MMU_CMD_F4)) { @@ -286,11 +302,12 @@ void MMU2::mmu_loop() { last_cmd = cmd; cmd = MMU_CMD_NONE; } - else if (ELAPSED(millis(), next_P0_request)) { - // read FINDA - tx_str_P(PSTR("P0\n")); + else if (ELAPSED(millis(), prev_P0_request + 300)) { + MMU2_COMMAND("P0"); // Read FINDA state = 2; // wait for response } + + TERN_(PRUSA_MMU2_S_MODE, check_filament()); break; case 2: // response to command P0 @@ -300,25 +317,48 @@ void MMU2::mmu_loop() { // This is super annoying. Only activate if necessary // if (finda_runout_valid) DEBUG_ECHOLNPAIR_F("MMU <= 'P0'\nMMU => ", finda, 6); - state = 1; - - if (cmd == 0) ready = true; - if (!finda && finda_runout_valid) filament_runout(); + if (cmd == 0) ready = true; + state = 1; } - else if (ELAPSED(millis(), last_request + MMU_P0_TIMEOUT)) // Resend request after timeout (3s) + else if (ELAPSED(millis(), prev_request + MMU_P0_TIMEOUT)) // Resend request after timeout (3s) state = 1; + TERN_(PRUSA_MMU2_S_MODE, check_filament()); break; case 3: // response to mmu commands + #if ENABLED(MMU_EXTRUDER_SENSOR) + if (mmu_idl_sens) { + if (FILAMENT_PRESENT() && mmu_loading_flag) { + DEBUG_ECHOLNPGM("MMU <= 'A'"); + MMU2_COMMAND("A"); // send 'abort' request + mmu_idl_sens = 0; + DEBUG_ECHOLNPGM("MMU IDLER_SENSOR = 0 - ABORT"); + } + } + #endif + if (rx_ok()) { - DEBUG_ECHOLNPGM("MMU => 'ok'"); - ready = true; - state = 1; - last_cmd = MMU_CMD_NONE; + // Response to C0 mmu command in PRUSA_MMU2_S_MODE + bool can_reset = true; + #if ENABLED(PRUSA_MMU2_S_MODE) + if (!mmu2s_triggered && last_cmd == MMU_CMD_C0) { + can_reset = false; + // MMU ok received but filament sensor not triggered, retrying... + DEBUG_ECHOLNPGM("MMU => 'ok' (filament not present in gears)"); + DEBUG_ECHOLNPGM("MMU <= 'C0' (keep trying)"); + MMU2_COMMAND("C0"); + } + #endif + if (can_reset) { + DEBUG_ECHOLNPGM("MMU => 'ok'"); + ready = true; + state = 1; + last_cmd = MMU_CMD_NONE; + } } - else if (ELAPSED(millis(), last_request + MMU_CMD_TIMEOUT)) { + else if (ELAPSED(millis(), prev_request + MMU_CMD_TIMEOUT)) { // resend request after timeout if (last_cmd) { DEBUG_ECHOLNPGM("MMU retry"); @@ -327,6 +367,7 @@ void MMU2::mmu_loop() { } state = 1; } + TERN_(PRUSA_MMU2_S_MODE, check_filament()); break; } } @@ -337,7 +378,7 @@ void MMU2::mmu_loop() { bool MMU2::rx_start() { // check for start message if (rx_str_P(PSTR("start\n"))) { - next_P0_request = millis() + 300; + prev_P0_request = millis(); return true; } return false; @@ -381,9 +422,9 @@ bool MMU2::rx_str_P(const char* str) { void MMU2::tx_str_P(const char* str) { clear_rx_buffer(); uint8_t len = strlen_P(str); - for (uint8_t i = 0; i < len; i++) mmuSerial.write(pgm_read_byte(str++)); + LOOP_L_N(i, len) mmuSerial.write(pgm_read_byte(str++)); rx_buffer[0] = '\0'; - last_request = millis(); + prev_request = millis(); } /** @@ -392,9 +433,9 @@ void MMU2::tx_str_P(const char* str) { void MMU2::tx_printf_P(const char* format, int argument = -1) { clear_rx_buffer(); uint8_t len = sprintf_P(tx_buffer, format, argument); - for (uint8_t i = 0; i < len; i++) mmuSerial.write(tx_buffer[i]); + LOOP_L_N(i, len) mmuSerial.write(tx_buffer[i]); rx_buffer[0] = '\0'; - last_request = millis(); + prev_request = millis(); } /** @@ -403,9 +444,9 @@ void MMU2::tx_printf_P(const char* format, int argument = -1) { void MMU2::tx_printf_P(const char* format, int argument1, int argument2) { clear_rx_buffer(); uint8_t len = sprintf_P(tx_buffer, format, argument1, argument2); - for (uint8_t i = 0; i < len; i++) mmuSerial.write(tx_buffer[i]); + LOOP_L_N(i, len) mmuSerial.write(tx_buffer[i]); rx_buffer[0] = '\0'; - last_request = millis(); + prev_request = millis(); } /** @@ -421,7 +462,7 @@ void MMU2::clear_rx_buffer() { */ bool MMU2::rx_ok() { if (rx_str_P(PSTR("ok\n"))) { - next_P0_request = millis() + 300; + prev_P0_request = millis(); return true; } return false; @@ -433,37 +474,235 @@ bool MMU2::rx_ok() { void MMU2::check_version() { if (buildnr < MMU_REQUIRED_FW_BUILDNR) { SERIAL_ERROR_MSG("Invalid MMU2 firmware. Version >= " STRINGIFY(MMU_REQUIRED_FW_BUILDNR) " required."); - kill(GET_TEXT(MSG_MMU2_WRONG_FIRMWARE)); + kill(GET_TEXT(MSG_KILL_MMU2_FIRMWARE)); } } +static void mmu2_not_responding() { + LCD_MESSAGEPGM(MSG_MMU2_NOT_RESPONDING); + BUZZ(100, 659); + BUZZ(200, 698); + BUZZ(100, 659); + BUZZ(300, 440); + BUZZ(100, 659); +} + +#if ENABLED(PRUSA_MMU2_S_MODE) + + bool MMU2::load_to_gears() { + command(MMU_CMD_C0); + manage_response(true, true); + LOOP_L_N(i, MMU2_C0_RETRY) { // Keep loading until filament reaches gears + if (mmu2s_triggered) break; + command(MMU_CMD_C0); + manage_response(true, true); + check_filament(); + } + const bool success = mmu2s_triggered && can_load(); + if (!success) mmu2_not_responding(); + return success; + } + + /** + * Handle tool change + */ + void MMU2::tool_change(const uint8_t index) { + + if (!enabled) return; + + set_runout_valid(false); + + if (index != extruder) { + + DISABLE_AXIS_E0(); + ui.status_printf_P(0, GET_TEXT(MSG_MMU2_LOADING_FILAMENT), int(index + 1)); + + command(MMU_CMD_T0 + index); + manage_response(true, true); + + if (load_to_gears()) { + extruder = index; // filament change is finished + active_extruder = 0; + ENABLE_AXIS_E0(); + SERIAL_ECHO_START(); + SERIAL_ECHOLNPAIR(STR_ACTIVE_EXTRUDER, int(extruder)); + } + ui.reset_status(); + } + + set_runout_valid(true); + } + + /** + * Handle special T?/Tx/Tc commands + * + * T? Gcode to extrude shouldn't have to follow, load to extruder wheels is done automatically + * Tx Same as T?, except nozzle doesn't have to be preheated. Tc must be placed after extruder nozzle is preheated to finish filament load. + * Tc Load to nozzle after filament was prepared by Tx and extruder nozzle is already heated. + */ + void MMU2::tool_change(const char* special) { + + if (!enabled) return; + + #if ENABLED(MMU2_MENUS) + + set_runout_valid(false); + + switch (*special) { + case '?': { + uint8_t index = mmu2_choose_filament(); + while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100); + load_filament_to_nozzle(index); + } break; + + case 'x': { + planner.synchronize(); + uint8_t index = mmu2_choose_filament(); + DISABLE_AXIS_E0(); + command(MMU_CMD_T0 + index); + manage_response(true, true); + + if (load_to_gears()) { + mmu_loop(); + ENABLE_AXIS_E0(); + extruder = index; + active_extruder = 0; + } + } break; + + case 'c': { + while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100); + execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence)); + } break; + } + + set_runout_valid(true); + + #endif // MMU2_MENUS + } + +#elif ENABLED(MMU_EXTRUDER_SENSOR) + + /** + * Handle tool change + */ + void MMU2::tool_change(const uint8_t index) { + if (!enabled) return; + + set_runout_valid(false); + + if (index != extruder) { + DISABLE_AXIS_E0(); + if (FILAMENT_PRESENT()) { + DEBUG_ECHOLNPGM("Unloading\n"); + mmu_loading_flag = false; + command(MMU_CMD_U0); + manage_response(true, true); + } + ui.status_printf_P(0, GET_TEXT(MSG_MMU2_LOADING_FILAMENT), int(index + 1)); + mmu_loading_flag = true; + command(MMU_CMD_T0 + index); + manage_response(true, true); + mmu_continue_loading(); + command(MMU_CMD_C0); + extruder = index; + active_extruder = 0; + + ENABLE_AXIS_E0(); + SERIAL_ECHO_START(); + SERIAL_ECHOLNPAIR(STR_ACTIVE_EXTRUDER, int(extruder)); + + ui.reset_status(); + } + + set_runout_valid(true); + } + + /** + * Handle special T?/Tx/Tc commands + * + * T? Gcode to extrude shouldn't have to follow, load to extruder wheels is done automatically + * Tx Same as T?, except nozzle doesn't have to be preheated. Tc must be placed after extruder nozzle is preheated to finish filament load. + * Tc Load to nozzle after filament was prepared by Tx and extruder nozzle is already heated. + */ + void MMU2::tool_change(const char* special) { + if (!enabled) return; + + #if ENABLED(MMU2_MENUS) + + set_runout_valid(false); + + switch (*special) { + case '?': { + DEBUG_ECHOLNPGM("case ?\n"); + uint8_t index = mmu2_choose_filament(); + while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100); + load_filament_to_nozzle(index); + } break; + + case 'x': { + DEBUG_ECHOLNPGM("case x\n"); + planner.synchronize(); + uint8_t index = mmu2_choose_filament(); + DISABLE_AXIS_E0(); + command(MMU_CMD_T0 + index); + manage_response(true, true); + mmu_continue_loading(); + command(MMU_CMD_C0); + mmu_loop(); + + ENABLE_AXIS_E0(); + extruder = index; + active_extruder = 0; + } break; + + case 'c': { + DEBUG_ECHOLNPGM("case c\n"); + while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100); + execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence)); + } break; + } + + set_runout_valid(true); + + #endif // MMU2_MENUS + } + + void MMU2::mmu_continue_loading() { + for (uint8_t i = 0; i < MMU_LOADING_ATTEMPTS_NR; i++) { + DEBUG_ECHOLNPAIR("Additional load attempt #", i); + if (FILAMENT_PRESENT()) break; + command(MMU_CMD_C0); + manage_response(true, true); + } + if (!FILAMENT_PRESENT()) { + DEBUG_ECHOLNPGM("Filament never reached sensor, runout"); + filament_runout(); + } + mmu_idl_sens = 0; + } + +#elif DISABLED(MMU_EXTRUDER_SENSOR) && DISABLED(PRUSA_MMU2_S_MODE) + /** * Handle tool change */ -void MMU2::tool_change(uint8_t index) { - +void MMU2::tool_change(const uint8_t index) { if (!enabled) return; set_runout_valid(false); if (index != extruder) { - DISABLE_AXIS_E0(); ui.status_printf_P(0, GET_TEXT(MSG_MMU2_LOADING_FILAMENT), int(index + 1)); - command(MMU_CMD_T0 + index); - manage_response(true, true); - command(MMU_CMD_C0); extruder = index; //filament change is finished active_extruder = 0; - ENABLE_AXIS_E0(); - SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR(STR_ACTIVE_EXTRUDER, int(extruder)); - ui.reset_status(); } @@ -471,16 +710,13 @@ void MMU2::tool_change(uint8_t index) { } /** - * * Handle special T?/Tx/Tc commands * * T? Gcode to extrude shouldn't have to follow, load to extruder wheels is done automatically * Tx Same as T?, except nozzle doesn't have to be preheated. Tc must be placed after extruder nozzle is preheated to finish filament load. * Tc Load to nozzle after filament was prepared by Tx and extruder nozzle is already heated. - * */ void MMU2::tool_change(const char* special) { - if (!enabled) return; #if ENABLED(MMU2_MENUS) @@ -489,12 +725,14 @@ void MMU2::tool_change(const char* special) { switch (*special) { case '?': { + DEBUG_ECHOLNPGM("case ?\n"); uint8_t index = mmu2_choose_filament(); while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100); load_filament_to_nozzle(index); } break; case 'x': { + DEBUG_ECHOLNPGM("case x\n"); planner.synchronize(); uint8_t index = mmu2_choose_filament(); DISABLE_AXIS_E0(); @@ -509,6 +747,7 @@ void MMU2::tool_change(const char* special) { } break; case 'c': { + DEBUG_ECHOLNPGM("case c\n"); while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100); execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence)); } break; @@ -517,7 +756,9 @@ void MMU2::tool_change(const char* special) { set_runout_valid(true); #endif -} + } + +#endif // MMU_EXTRUDER_SENSOR /** * Set next command @@ -554,7 +795,7 @@ void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) { bool response = false; mmu_print_saved = false; xyz_pos_t resume_position; - int16_t resume_hotend_temp; + int16_t resume_hotend_temp = thermalManager.degTargetHotend(active_extruder); KEEPALIVE_STATE(PAUSED_FOR_USER); @@ -575,16 +816,11 @@ void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) { resume_position = current_position; if (move_axes && all_axes_homed()) - nozzle.park(2, park_point /*= NOZZLE_PARK_POINT*/); + nozzle.park(0, park_point /*= NOZZLE_PARK_POINT*/); if (turn_off_nozzle) thermalManager.setTargetHotend(0, active_extruder); - LCD_MESSAGEPGM(MSG_MMU2_NOT_RESPONDING); - BUZZ(100, 659); - BUZZ(200, 698); - BUZZ(100, 659); - BUZZ(300, 440); - BUZZ(100, 659); + mmu2_not_responding(); } } else if (mmu_print_saved) { @@ -600,8 +836,7 @@ void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) { if (move_axes && all_axes_homed()) { LCD_MESSAGEPGM(MSG_MMU2_RESUMING); - BUZZ(200, 404); - BUZZ(200, 404); + BUZZ(198, 404); BUZZ(4, 0); BUZZ(198, 404); // Move XY to starting position, then Z do_blocking_move_to_xy(resume_position, feedRate_t(NOZZLE_PARK_XY_FEEDRATE)); @@ -610,15 +845,14 @@ void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) { do_blocking_move_to_z(resume_position.z, feedRate_t(NOZZLE_PARK_Z_FEEDRATE)); } else { - BUZZ(200, 404); - BUZZ(200, 404); + BUZZ(198, 404); BUZZ(4, 0); BUZZ(198, 404); LCD_MESSAGEPGM(MSG_MMU2_RESUMING); } } } } -void MMU2::set_filament_type(uint8_t index, uint8_t filamentType) { +void MMU2::set_filament_type(const uint8_t index, const uint8_t filamentType) { if (!enabled) return; cmd_arg = filamentType; @@ -632,10 +866,53 @@ void MMU2::filament_runout() { planner.synchronize(); } -#if HAS_LCD_MENU && ENABLED(MMU2_MENUS) +#if ENABLED(PRUSA_MMU2_S_MODE) + + void MMU2::check_filament() { + const bool present = FILAMENT_PRESENT(); + if (cmd == MMU_CMD_NONE && last_cmd == MMU_CMD_C0) { + if (present && !mmu2s_triggered) { + DEBUG_ECHOLNPGM("MMU <= 'A'"); + tx_str_P(PSTR("A\n")); + } + // Slowly spin the extruder during C0 + else { + while (planner.movesplanned() < 3) { + current_position.e += 0.25; + line_to_current_position(MMM_TO_MMS(120)); + } + } + } + mmu2s_triggered = present; + } + + bool MMU2::can_load() { + execute_extruder_sequence((const E_Step *)can_load_sequence, COUNT(can_load_sequence)); + + int filament_detected_count = 0; + const int steps = (MMU2_CAN_LOAD_RETRACT) / (MMU2_CAN_LOAD_INCREMENT); + DEBUG_ECHOLNPGM("MMU can_load:"); + LOOP_L_N(i, steps) { + execute_extruder_sequence((const E_Step *)can_load_increment_sequence, COUNT(can_load_increment_sequence)); + check_filament(); // Don't trust the idle function + DEBUG_CHAR(mmu2s_triggered ? 'O' : 'o'); + if (mmu2s_triggered) ++filament_detected_count; + } + + if (filament_detected_count <= steps - (MMU2_CAN_LOAD_DEVIATION) / (MMU2_CAN_LOAD_INCREMENT)) { + DEBUG_ECHOLNPGM(" failed."); + return false; + } + + DEBUG_ECHOLNPGM(" succeeded."); + return true; + } +#endif + +#if BOTH(HAS_LCD_MENU, MMU2_MENUS) // Load filament into MMU2 - void MMU2::load_filament(uint8_t index) { + void MMU2::load_filament(const uint8_t index) { if (!enabled) return; command(MMU_CMD_L0 + index); manage_response(false, false); @@ -643,11 +920,9 @@ void MMU2::filament_runout() { } /** - * * Switch material and load to nozzle - * */ - bool MMU2::load_filament_to_nozzle(uint8_t index) { + bool MMU2::load_filament_to_nozzle(const uint8_t index) { if (!enabled) return false; @@ -656,24 +931,22 @@ void MMU2::filament_runout() { LCD_ALERTMESSAGEPGM(MSG_HOTEND_TOO_COLD); return false; } - else { - command(MMU_CMD_T0 + index); - manage_response(true, true); - command(MMU_CMD_C0); - mmu_loop(); + command(MMU_CMD_T0 + index); + manage_response(true, true); + + const bool success = load_to_gears(); + if (success) { + mmu_loop(); extruder = index; active_extruder = 0; - load_to_nozzle(); - BUZZ(200, 404); - return true; } + return success; } /** - * * Load filament to nozzle of multimaterial printer * * This function is used only only after T? (user select filament) and M600 (change filament). @@ -685,7 +958,7 @@ void MMU2::filament_runout() { execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence)); } - bool MMU2::eject_filament(uint8_t index, bool recover) { + bool MMU2::eject_filament(const uint8_t index, const bool recover) { if (!enabled) return false; @@ -707,14 +980,9 @@ void MMU2::filament_runout() { if (recover) { LCD_MESSAGEPGM(MSG_MMU2_EJECT_RECOVER); BUZZ(200, 404); - wait_for_user = true; - #if ENABLED(HOST_PROMPT_SUPPORT) - host_prompt_do(PROMPT_USER_CONTINUE, PSTR("MMU2 Eject Recover"), CONTINUE_STR); - #endif - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onUserConfirmRequired_P(PSTR("MMU2 Eject Recover")); - #endif - while (wait_for_user) idle(); + TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, PSTR("MMU2 Eject Recover"), CONTINUE_STR)); + TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(PSTR("MMU2 Eject Recover"))); + wait_for_user_response(); BUZZ(200, 404); BUZZ(200, 404); @@ -737,9 +1005,7 @@ void MMU2::filament_runout() { } /** - * - * unload from hotend and retract to MMU - * + * Unload from hotend and retract to MMU */ bool MMU2::unload() { @@ -780,7 +1046,7 @@ void MMU2::filament_runout() { const E_Step* step = sequence; - for (uint8_t i = 0; i < steps; i++) { + LOOP_L_N(i, steps) { const float es = pgm_read_float(&(step->extrude)); const feedRate_t fr_mm_m = pgm_read_float(&(step->feedRate)); diff --git a/Marlin/src/feature/prusa_MMU2/mmu2.h b/Marlin/src/feature/mmu2/mmu2.h similarity index 71% rename from Marlin/src/feature/prusa_MMU2/mmu2.h rename to Marlin/src/feature/mmu2/mmu2.h index 970b0b4338ff..678f65d0720d 100644 --- a/Marlin/src/feature/prusa_MMU2/mmu2.h +++ b/Marlin/src/feature/mmu2/mmu2.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -44,24 +44,24 @@ class MMU2 { static void init(); static void reset(); static void mmu_loop(); - static void tool_change(uint8_t index); + static void tool_change(const uint8_t index); static void tool_change(const char* special); static uint8_t get_current_tool(); - static void set_filament_type(uint8_t index, uint8_t type); + static void set_filament_type(const uint8_t index, const uint8_t type); - #if HAS_LCD_MENU && ENABLED(MMU2_MENUS) + #if BOTH(HAS_LCD_MENU, MMU2_MENUS) static bool unload(); static void load_filament(uint8_t); static void load_all(); - static bool load_filament_to_nozzle(uint8_t index); - static bool eject_filament(uint8_t index, bool recover); + static bool load_filament_to_nozzle(const uint8_t index); + static bool eject_filament(const uint8_t index, const bool recover); #endif private: static bool rx_str_P(const char* str); static void tx_str_P(const char* str); - static void tx_printf_P(const char* format, int argument); - static void tx_printf_P(const char* format, int argument1, int argument2); + static void tx_printf_P(const char* format, const int argument); + static void tx_printf_P(const char* format, const int argument1, const int argument2); static void clear_rx_buffer(); static bool rx_ok(); @@ -72,7 +72,7 @@ class MMU2 { static bool get_response(); static void manage_response(const bool move_axes, const bool turn_off_nozzle); - #if HAS_LCD_MENU && ENABLED(MMU2_MENUS) + #if BOTH(HAS_LCD_MENU, MMU2_MENUS) static void load_to_nozzle(); static void filament_ramming(); static void execute_extruder_sequence(const E_Step * sequence, int steps); @@ -80,13 +80,27 @@ class MMU2 { static void filament_runout(); + #if ENABLED(PRUSA_MMU2_S_MODE) + static bool mmu2s_triggered; + static void check_filament(); + static bool can_load(); + static bool load_to_gears(); + #else + FORCE_INLINE static bool load_to_gears() { return true; } + #endif + + #if ENABLED(MMU_EXTRUDER_SENSOR) + static void mmu_continue_loading(); + #endif + static bool enabled, ready, mmu_print_saved; + static uint8_t cmd, cmd_arg, last_cmd, extruder; static int8_t state; static volatile int8_t finda; static volatile bool finda_runout_valid; static int16_t version, buildnr; - static millis_t last_request, next_P0_request; + static millis_t prev_request, prev_P0_request; static char rx_buffer[MMU_RX_SIZE], tx_buffer[MMU_TX_SIZE]; static inline void set_runout_valid(const bool valid) { diff --git a/Marlin/src/feature/prusa_MMU2/serial-protocol.md b/Marlin/src/feature/mmu2/serial-protocol.md similarity index 100% rename from Marlin/src/feature/prusa_MMU2/serial-protocol.md rename to Marlin/src/feature/mmu2/serial-protocol.md diff --git a/Marlin/src/feature/password/password.cpp b/Marlin/src/feature/password/password.cpp new file mode 100644 index 000000000000..90bb647118b5 --- /dev/null +++ b/Marlin/src/feature/password/password.cpp @@ -0,0 +1,58 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfigPre.h" + +#if ENABLED(PASSWORD_FEATURE) + +#include "password.h" +#include "../../gcode/gcode.h" +#include "../../core/serial.h" + +Password password; + +// public: +bool Password::is_set, Password::is_locked; +uint32_t Password::value, Password::value_entry; + +// +// Authenticate user with password. +// Called from Setup, after SD Prinitng Stops/Aborts, and M510 +// +void Password::lock_machine() { + is_locked = true; + TERN_(HAS_LCD_MENU, authenticate_user(ui.status_screen, screen_password_entry)); +} + +// +// Authentication check +// +void Password::authentication_check() { + if (value_entry == value) + is_locked = false; + else + SERIAL_ECHOLNPGM(STR_WRONG_PASSWORD); + + TERN_(HAS_LCD_MENU, authentication_done()); +} + +#endif // PASSWORD_FEATURE diff --git a/Marlin/src/feature/password/password.h b/Marlin/src/feature/password/password.h new file mode 100644 index 000000000000..3ed584b29d5e --- /dev/null +++ b/Marlin/src/feature/password/password.h @@ -0,0 +1,57 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../../lcd/ultralcd.h" + +class Password { +public: + static bool is_set, is_locked; + static uint32_t value, value_entry; + + Password() { is_locked = false; } + + static void lock_machine(); + + #if HAS_LCD_MENU + static void access_menu_password(); + static void authentication_check(); + static void authentication_done(); + static void media_gatekeeper(); + + private: + static void authenticate_user(const screenFunc_t, const screenFunc_t); + static void menu_password(); + static void menu_password_entry(); + static void screen_password_entry(); + static void screen_set_password(); + static void start_over(); + + static void digit_entered(); + static void set_password_done(); + static void menu_password_report(); + + static void remove_password(); + #endif +}; + +extern Password password; diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp index 95b5cc953f86..0ab659402181 100644 --- a/Marlin/src/feature/pause.cpp +++ b/Marlin/src/feature/pause.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -29,6 +29,8 @@ #if ENABLED(ADVANCED_PAUSE_FEATURE) +//#define DEBUG_PAUSE_RESUME + #include "../MarlinCore.h" #include "../gcode/gcode.h" #include "../module/motion.h" @@ -50,19 +52,25 @@ #endif #if ENABLED(EXTENSIBLE_UI) - #include "../lcd/extensible_ui/ui_api.h" + #include "../lcd/extui/ui_api.h" #endif -#include "../core/language.h" #include "../lcd/ultralcd.h" #if HAS_BUZZER #include "../libs/buzzer.h" #endif +#if ENABLED(POWER_LOSS_RECOVERY) + #include "powerloss.h" +#endif + #include "../libs/nozzle.h" #include "pause.h" +#define DEBUG_OUT ENABLED(DEBUG_PAUSE_RESUME) +#include "../core/debug_out.h" + // private: static xyze_pos_t resume_position; @@ -85,26 +93,30 @@ fil_change_settings_t fc_settings[EXTRUDERS]; #endif #if HAS_BUZZER - static void filament_change_beep(const int8_t max_beep_count, const bool init=false) { + static void impatient_beep(const int8_t max_beep_count, const bool restart=false) { - #if HAS_LCD_MENU - if (pause_mode == PAUSE_MODE_PAUSE_PRINT) return; - #endif + if (TERN0(HAS_LCD_MENU, pause_mode == PAUSE_MODE_PAUSE_PRINT)) return; static millis_t next_buzz = 0; static int8_t runout_beep = 0; - if (init) next_buzz = runout_beep = 0; + if (restart) next_buzz = runout_beep = 0; + + const bool always = max_beep_count < 0; const millis_t ms = millis(); if (ELAPSED(ms, next_buzz)) { - if (max_beep_count < 0 || runout_beep < max_beep_count + 5) { // Only beep as long as we're supposed to - next_buzz = ms + ((max_beep_count < 0 || runout_beep < max_beep_count) ? 1000 : 500); + if (always || runout_beep < max_beep_count + 5) { // Only beep as long as we're supposed to + next_buzz = ms + ((always || runout_beep < max_beep_count) ? 1000 : 500); BUZZ(50, 880 - (runout_beep & 1) * 220); runout_beep++; } } } + inline void first_impatient_beep(const int8_t max_beep_count) { impatient_beep(max_beep_count, true); } +#else + inline void impatient_beep(const int8_t, const bool=false) {} + inline void first_impatient_beep(const int8_t) {} #endif /** @@ -116,31 +128,35 @@ fil_change_settings_t fc_settings[EXTRUDERS]; * * Returns 'true' if heating was completed, 'false' for abort */ -static bool ensure_safe_temperature(const PauseMode mode=PAUSE_MODE_SAME) { +static bool ensure_safe_temperature(const bool wait=true, const PauseMode mode=PAUSE_MODE_SAME) { + DEBUG_SECTION(est, "ensure_safe_temperature", true); + DEBUG_ECHOLNPAIR("... wait:", int(wait), " mode:", int(mode)); - #if ENABLED(PREVENT_COLD_EXTRUSION) - if (!DEBUGGING(DRYRUN) && thermalManager.targetTooColdToExtrude(active_extruder)) { - SERIAL_ECHO_MSG(STR_ERR_HOTEND_TOO_COLD); - return false; - } - #endif + if (!DEBUGGING(DRYRUN) && thermalManager.targetTooColdToExtrude(active_extruder)) + thermalManager.setTargetHotend(thermalManager.extrude_min_temp, active_extruder); #if HAS_LCD_MENU lcd_pause_show_message(PAUSE_MESSAGE_HEATING, mode); - #else - UNUSED(mode); #endif + UNUSED(mode); - return thermalManager.wait_for_hotend(active_extruder); -} + if (wait) + return thermalManager.wait_for_hotend(active_extruder); -void do_pause_e_move(const float &length, const feedRate_t &fr_mm_s) { - #if HAS_FILAMENT_SENSOR - runout.reset(); + wait_for_heatup = true; // Allow interruption by Emergency Parser M108 + while (wait_for_heatup && ABS(thermalManager.degHotend(active_extruder) - thermalManager.degTargetHotend(active_extruder)) > TEMP_WINDOW) + idle(); + wait_for_heatup = false; + + #if ENABLED(PREVENT_COLD_EXTRUSION) + // A user can cancel wait-for-heating with M108 + if (!DEBUGGING(DRYRUN) && thermalManager.targetTooColdToExtrude(active_extruder)) { + SERIAL_ECHO_MSG(STR_ERR_HOTEND_TOO_COLD); + return false; + } #endif - current_position.e += length / planner.e_factor[active_extruder]; - line_to_current_position(fr_mm_s); - planner.synchronize(); + + return true; } /** @@ -160,11 +176,12 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l const PauseMode mode/*=PAUSE_MODE_PAUSE_PRINT*/ DXC_ARGS ) { - #if !HAS_LCD_MENU - UNUSED(show_lcd); - #endif + DEBUG_SECTION(lf, "load_filament", true); + DEBUG_ECHOLNPAIR("... slowlen:", slow_load_length, " fastlen:", fast_load_length, " purgelen:", purge_length, " maxbeep:", int(max_beep_count), " showlcd:", int(show_lcd), " pauseforuser:", int(pause_for_user), " pausemode:", int(mode) DXC_SAY); + + UNUSED(show_lcd); - if (!ensure_safe_temperature(mode)) { + if (!ensure_safe_temperature(false, mode)) { #if HAS_LCD_MENU if (show_lcd) lcd_pause_show_message(PAUSE_MESSAGE_STATUS, mode); #endif @@ -177,14 +194,9 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l #endif SERIAL_ECHO_MSG(_PMSG(STR_FILAMENT_CHANGE_INSERT)); - #if HAS_BUZZER - filament_change_beep(max_beep_count, true); - #else - UNUSED(max_beep_count); - #endif + first_impatient_beep(max_beep_count); KEEPALIVE_STATE(PAUSED_FOR_USER); - wait_for_user = true; // LCD click or M108 will clear this #if ENABLED(HOST_PROMPT_SUPPORT) const char tool = '0' #if NUM_RUNOUT_SENSORS > 1 @@ -195,14 +207,10 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l host_action_prompt_button(CONTINUE_STR); host_action_prompt_show(); #endif - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onUserConfirmRequired_P(PSTR("Load Filament")); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(PSTR("Load Filament"))); while (wait_for_user) { - #if HAS_BUZZER - filament_change_beep(max_beep_count); - #endif - idle(true); + impatient_beep(max_beep_count); + idle_no_sleep(); } } @@ -218,7 +226,7 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l #endif // Slow Load filament - if (slow_load_length) do_pause_e_move(slow_load_length, FILAMENT_CHANGE_SLOW_LOAD_FEEDRATE); + if (slow_load_length) unscaled_e_move(slow_load_length, FILAMENT_CHANGE_SLOW_LOAD_FEEDRATE); // Fast Load Filament if (fast_load_length) { @@ -227,7 +235,7 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l planner.settings.retract_acceleration = FILAMENT_CHANGE_FAST_LOAD_ACCEL; #endif - do_pause_e_move(fast_load_length, FILAMENT_CHANGE_FAST_LOAD_FEEDRATE); + unscaled_e_move(fast_load_length, FILAMENT_CHANGE_FAST_LOAD_FEEDRATE); #if FILAMENT_CHANGE_FAST_LOAD_ACCEL > 0 planner.settings.retract_acceleration = saved_acceleration; @@ -246,15 +254,11 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l if (show_lcd) lcd_pause_show_message(PAUSE_MESSAGE_PURGE); #endif - wait_for_user = true; - #if ENABLED(HOST_PROMPT_SUPPORT) - host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Filament Purging..."), CONTINUE_STR); - #endif - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onUserConfirmRequired_P(PSTR("Filament Purging...")); - #endif + TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Filament Purging..."), CONTINUE_STR)); + TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(PSTR("Filament Purging..."))); + wait_for_user = true; // A click or M108 breaks the purge_length loop for (float purge_count = purge_length; purge_count > 0 && wait_for_user; --purge_count) - do_pause_e_move(1, ADVANCED_PAUSE_PURGE_FEEDRATE); + unscaled_e_move(1, ADVANCED_PAUSE_PURGE_FEEDRATE); wait_for_user = false; #else @@ -267,12 +271,10 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l #endif // Extrude filament to get into hotend - do_pause_e_move(purge_length, ADVANCED_PAUSE_PURGE_FEEDRATE); + unscaled_e_move(purge_length, ADVANCED_PAUSE_PURGE_FEEDRATE); } - #if ENABLED(HOST_PROMPT_SUPPORT) - filament_load_host_prompt(); // Initiate another host prompt. (NOTE: host_response_handler may also do this!) - #endif + TERN_(HOST_PROMPT_SUPPORT, filament_load_host_prompt()); // Initiate another host prompt. (NOTE: host_response_handler may also do this!) #if HAS_LCD_MENU if (show_lcd) { @@ -280,18 +282,15 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l KEEPALIVE_STATE(PAUSED_FOR_USER); wait_for_user = false; lcd_pause_show_message(PAUSE_MESSAGE_OPTION); - while (pause_menu_response == PAUSE_RESPONSE_WAIT_FOR) idle(true); + while (pause_menu_response == PAUSE_RESPONSE_WAIT_FOR) idle_no_sleep(); } #endif // Keep looping if "Purge More" was selected - } while (false - #if HAS_LCD_MENU - || (show_lcd && pause_menu_response == PAUSE_RESPONSE_EXTRUDE_MORE) - #endif - ); + } while (TERN0(HAS_LCD_MENU, show_lcd && pause_menu_response == PAUSE_RESPONSE_EXTRUDE_MORE)); #endif + TERN_(HOST_PROMPT_SUPPORT, host_action_prompt_end()); return true; } @@ -312,15 +311,20 @@ bool unload_filament(const float &unload_length, const bool show_lcd/*=false*/, , const float &mix_multiplier/*=1.0*/ #endif ) { - #if !HAS_LCD_MENU - UNUSED(show_lcd); - #endif + DEBUG_SECTION(uf, "unload_filament", true); + DEBUG_ECHOLNPAIR("... unloadlen:", unload_length, " showlcd:", int(show_lcd), " mode:", int(mode) + #if BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER) + , " mixmult:", mix_multiplier + #endif + ); + + UNUSED(show_lcd); #if !BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER) constexpr float mix_multiplier = 1.0; #endif - if (!ensure_safe_temperature(mode)) { + if (!ensure_safe_temperature(false, mode)) { #if HAS_LCD_MENU if (show_lcd) lcd_pause_show_message(PAUSE_MESSAGE_STATUS); #endif @@ -332,13 +336,13 @@ bool unload_filament(const float &unload_length, const bool show_lcd/*=false*/, #endif // Retract filament - do_pause_e_move(-(FILAMENT_UNLOAD_PURGE_RETRACT) * mix_multiplier, (PAUSE_PARK_RETRACT_FEEDRATE) * mix_multiplier); + unscaled_e_move(-(FILAMENT_UNLOAD_PURGE_RETRACT) * mix_multiplier, (PAUSE_PARK_RETRACT_FEEDRATE) * mix_multiplier); // Wait for filament to cool safe_delay(FILAMENT_UNLOAD_PURGE_DELAY); // Quickly purge - do_pause_e_move((FILAMENT_UNLOAD_PURGE_RETRACT + FILAMENT_UNLOAD_PURGE_LENGTH) * mix_multiplier, + unscaled_e_move((FILAMENT_UNLOAD_PURGE_RETRACT + FILAMENT_UNLOAD_PURGE_LENGTH) * mix_multiplier, (FILAMENT_UNLOAD_PURGE_FEEDRATE) * mix_multiplier); // Unload filament @@ -347,7 +351,7 @@ bool unload_filament(const float &unload_length, const bool show_lcd/*=false*/, planner.settings.retract_acceleration = FILAMENT_CHANGE_UNLOAD_ACCEL; #endif - do_pause_e_move(unload_length * mix_multiplier, (FILAMENT_CHANGE_UNLOAD_FEEDRATE) * mix_multiplier); + unscaled_e_move(unload_length * mix_multiplier, (FILAMENT_CHANGE_UNLOAD_FEEDRATE) * mix_multiplier); #if FILAMENT_CHANGE_FAST_LOAD_ACCEL > 0 planner.settings.retract_acceleration = saved_acceleration; @@ -380,10 +384,10 @@ bool unload_filament(const float &unload_length, const bool show_lcd/*=false*/, uint8_t did_pause_print = 0; bool pause_print(const float &retract, const xyz_pos_t &park_point, const float &unload_length/*=0*/, const bool show_lcd/*=false*/ DXC_ARGS) { + DEBUG_SECTION(pp, "pause_print", true); + DEBUG_ECHOLNPAIR("... park.x:", park_point.x, " y:", park_point.y, " z:", park_point.z, " unloadlen:", unload_length, " showlcd:", int(show_lcd) DXC_SAY); - #if !HAS_LCD_MENU - UNUSED(show_lcd); - #endif + UNUSED(show_lcd); if (did_pause_print) return false; // already paused @@ -395,22 +399,7 @@ bool pause_print(const float &retract, const xyz_pos_t &park_point, const float #endif #endif - #if ENABLED(HOST_PROMPT_SUPPORT) - host_prompt_open(PROMPT_INFO, PSTR("Pause"), DISMISS_STR); - #endif - - if (!DEBUGGING(DRYRUN) && unload_length && thermalManager.targetTooColdToExtrude(active_extruder)) { - SERIAL_ECHO_MSG(STR_ERR_HOTEND_TOO_COLD); - - #if HAS_LCD_MENU - if (show_lcd) { // Show status screen - lcd_pause_show_message(PAUSE_MESSAGE_STATUS); - LCD_MESSAGEPGM(MSG_M600_TOO_COLD); - } - #endif - - return false; // unable to reach safe temperature - } + TERN_(HOST_PROMPT_SUPPORT, host_prompt_open(PROMPT_INFO, PSTR("Pause"), DISMISS_STR)); // Indicate that the printer is paused ++did_pause_print; @@ -431,17 +420,19 @@ bool pause_print(const float &retract, const xyz_pos_t &park_point, const float // Wait for buffered blocks to complete planner.synchronize(); - #if ENABLED(ADVANCED_PAUSE_FANS_PAUSE) && FAN_COUNT > 0 + #if ENABLED(ADVANCED_PAUSE_FANS_PAUSE) && HAS_FAN thermalManager.set_fans_paused(true); #endif // Initial retract before move to filament change position - if (retract && thermalManager.hotEnoughToExtrude(active_extruder)) - do_pause_e_move(retract, PAUSE_PARK_RETRACT_FEEDRATE); + if (retract && thermalManager.hotEnoughToExtrude(active_extruder)) { + DEBUG_ECHOLNPAIR("... retract:", retract); + unscaled_e_move(retract, PAUSE_PARK_RETRACT_FEEDRATE); + } // Park the nozzle by moving up by z_lift and then moving to (x_pos, y_pos) - if (!axes_need_homing()) - nozzle.park(2, park_point); + if (!axes_should_home()) + nozzle.park(0, park_point); #if ENABLED(DUAL_X_CARRIAGE) const int8_t saved_ext = active_extruder; @@ -476,28 +467,28 @@ bool pause_print(const float &retract, const xyz_pos_t &park_point, const float */ void show_continue_prompt(const bool is_reload) { - #if HAS_LCD_MENU - lcd_pause_show_message(is_reload ? PAUSE_MESSAGE_INSERT : PAUSE_MESSAGE_WAITING); - #endif + DEBUG_SECTION(scp, "pause_print", true); + DEBUG_ECHOLNPAIR("... is_reload:", int(is_reload)); + + TERN_(HAS_LCD_MENU, lcd_pause_show_message(is_reload ? PAUSE_MESSAGE_INSERT : PAUSE_MESSAGE_WAITING)); SERIAL_ECHO_START(); serialprintPGM(is_reload ? PSTR(_PMSG(STR_FILAMENT_CHANGE_INSERT) "\n") : PSTR(_PMSG(STR_FILAMENT_CHANGE_WAIT) "\n")); } void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep_count/*=0*/ DXC_ARGS) { + DEBUG_SECTION(wfc, "wait_for_confirmation", true); + DEBUG_ECHOLNPAIR("... is_reload:", is_reload, " maxbeep:", int(max_beep_count) DXC_SAY); + bool nozzle_timed_out = false; show_continue_prompt(is_reload); - #if HAS_BUZZER - filament_change_beep(max_beep_count, true); - #else - UNUSED(max_beep_count); - #endif + first_impatient_beep(max_beep_count); // Start the heater idle timers - const millis_t nozzle_timeout = (millis_t)(PAUSE_PARK_NOZZLE_TIMEOUT) * 1000UL; + const millis_t nozzle_timeout = SEC_TO_MS(PAUSE_PARK_NOZZLE_TIMEOUT); - HOTEND_LOOP() thermalManager.hotend_idle[e].start(nozzle_timeout); + HOTEND_LOOP() thermalManager.heater_idle[e].start(nozzle_timeout); #if ENABLED(DUAL_X_CARRIAGE) const int8_t saved_ext = active_extruder; @@ -508,76 +499,53 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep // Wait for filament insert by user and press button KEEPALIVE_STATE(PAUSED_FOR_USER); + TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, GET_TEXT(MSG_NOZZLE_PARKED), CONTINUE_STR)); + TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(GET_TEXT(MSG_NOZZLE_PARKED))); wait_for_user = true; // LCD click or M108 will clear this - #if ENABLED(HOST_PROMPT_SUPPORT) - host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Nozzle Parked"), CONTINUE_STR); - #endif - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onUserConfirmRequired_P(PSTR("Nozzle Parked")); - #endif while (wait_for_user) { - #if HAS_BUZZER - filament_change_beep(max_beep_count); - #endif + impatient_beep(max_beep_count); // If the nozzle has timed out... if (!nozzle_timed_out) - HOTEND_LOOP() nozzle_timed_out |= thermalManager.hotend_idle[e].timed_out; + HOTEND_LOOP() nozzle_timed_out |= thermalManager.heater_idle[e].timed_out; // Wait for the user to press the button to re-heat the nozzle, then // re-heat the nozzle, re-show the continue prompt, restart idle timers, start over if (nozzle_timed_out) { - #if HAS_LCD_MENU - lcd_pause_show_message(PAUSE_MESSAGE_HEAT); - #endif + TERN_(HAS_LCD_MENU, lcd_pause_show_message(PAUSE_MESSAGE_HEAT)); SERIAL_ECHO_MSG(_PMSG(STR_FILAMENT_CHANGE_HEAT)); - #if ENABLED(HOST_PROMPT_SUPPORT) - host_prompt_do(PROMPT_USER_CONTINUE, PSTR("HeaterTimeout"), PSTR("Reheat")); - #endif + TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, GET_TEXT(MSG_HEATER_TIMEOUT), GET_TEXT(MSG_REHEAT))); - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onUserConfirmRequired_P(PSTR("HeaterTimeout")); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(GET_TEXT(MSG_HEATER_TIMEOUT))); - // Wait for LCD click or M108 - while (wait_for_user) idle(true); + wait_for_user_response(0, true); // Wait for LCD click or M108 - #if ENABLED(HOST_PROMPT_SUPPORT) - host_prompt_do(PROMPT_INFO, PSTR("Reheating")); - #endif - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onStatusChanged(PSTR("Reheating...")); - #endif + TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_INFO, GET_TEXT(MSG_REHEATING))); + + TERN_(EXTENSIBLE_UI, ExtUI::onStatusChanged_P(GET_TEXT(MSG_REHEATING))); // Re-enable the heaters if they timed out HOTEND_LOOP() thermalManager.reset_hotend_idle_timer(e); // Wait for the heaters to reach the target temperatures - ensure_safe_temperature(); + ensure_safe_temperature(false); // Show the prompt to continue show_continue_prompt(is_reload); // Start the heater idle timers - const millis_t nozzle_timeout = (millis_t)(PAUSE_PARK_NOZZLE_TIMEOUT) * 1000UL; + const millis_t nozzle_timeout = SEC_TO_MS(PAUSE_PARK_NOZZLE_TIMEOUT); - HOTEND_LOOP() thermalManager.hotend_idle[e].start(nozzle_timeout); - #if ENABLED(HOST_PROMPT_SUPPORT) - host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Reheat Done"), CONTINUE_STR); - #endif - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onUserConfirmRequired_P(PSTR("Reheat finished.")); - #endif + HOTEND_LOOP() thermalManager.heater_idle[e].start(nozzle_timeout); + TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Reheat Done"), CONTINUE_STR)); + TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(PSTR("Reheat finished."))); wait_for_user = true; nozzle_timed_out = false; - #if HAS_BUZZER - filament_change_beep(max_beep_count, true); - #endif + first_impatient_beep(max_beep_count); } - - idle(true); + idle_no_sleep(); } #if ENABLED(DUAL_X_CARRIAGE) active_extruder = saved_ext; @@ -595,16 +563,21 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep * - a nozzle timed out, or * - the nozzle is already heated. * - Display "wait for print to resume" + * - Retract to prevent oozing + * - Move the nozzle back to resume_position + * - Unretract * - Re-prime the nozzle... * - FWRETRACT: Recover/prime from the prior G10. * - !FWRETRACT: Retract by resume_position.e, if negative. * Not sure how this logic comes into use. - * - Move the nozzle back to resume_position * - Sync the planner E to resume_position.e * - Send host action for resume, if configured * - Resume the current SD print job, if any */ -void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_length/*=0*/, const float &purge_length/*=ADVANCED_PAUSE_PURGE_LENGTH*/, const int8_t max_beep_count/*=0*/ DXC_ARGS) { +void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_length/*=0*/, const float &purge_length/*=ADVANCED_PAUSE_PURGE_LENGTH*/, const int8_t max_beep_count/*=0*/, int16_t targetTemp/*=0*/ DXC_ARGS) { + DEBUG_SECTION(rp, "resume_print", true); + DEBUG_ECHOLNPAIR("... slowlen:", slow_load_length, " fastlen:", fast_load_length, " purgelen:", purge_length, " maxbeep:", int(max_beep_count), " targetTemp:", targetTemp DXC_SAY); + /* SERIAL_ECHOLNPAIR( "start of resume_print()\ndual_x_carriage_mode:", dual_x_carriage_mode, @@ -619,44 +592,62 @@ void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_le // Re-enable the heaters if they timed out bool nozzle_timed_out = false; HOTEND_LOOP() { - nozzle_timed_out |= thermalManager.hotend_idle[e].timed_out; + nozzle_timed_out |= thermalManager.heater_idle[e].timed_out; thermalManager.reset_hotend_idle_timer(e); } - if (nozzle_timed_out || thermalManager.hotEnoughToExtrude(active_extruder)) // Load the new filament - load_filament(slow_load_length, fast_load_length, purge_length, max_beep_count, true, nozzle_timed_out, PAUSE_MODE_SAME DXC_PASS); + if (targetTemp > thermalManager.degTargetHotend(active_extruder)) { + thermalManager.setTargetHotend(targetTemp, active_extruder); + } - #if HAS_LCD_MENU - lcd_pause_show_message(PAUSE_MESSAGE_RESUME); - #endif + // Load the new filament + load_filament(slow_load_length, fast_load_length, purge_length, max_beep_count, true, nozzle_timed_out, PAUSE_MODE_SAME DXC_PASS); + + if (targetTemp > 0) { + thermalManager.setTargetHotend(targetTemp, active_extruder); + thermalManager.wait_for_hotend(active_extruder, false); + } + + TERN_(HAS_LCD_MENU, lcd_pause_show_message(PAUSE_MESSAGE_RESUME)); + + // Check Temperature before moving hotend + ensure_safe_temperature(); + + // Retract to prevent oozing + unscaled_e_move(-(PAUSE_PARK_RETRACT_LENGTH), feedRate_t(PAUSE_PARK_RETRACT_FEEDRATE)); + + if (!axes_should_home()) { + // Move XY to starting position, then Z + do_blocking_move_to_xy(resume_position, feedRate_t(NOZZLE_PARK_XY_FEEDRATE)); + + // Move Z_AXIS to saved position + do_blocking_move_to_z(resume_position.z, feedRate_t(NOZZLE_PARK_Z_FEEDRATE)); + } + + // Unretract + unscaled_e_move(PAUSE_PARK_RETRACT_LENGTH, feedRate_t(PAUSE_PARK_RETRACT_FEEDRATE)); // Intelligent resuming #if ENABLED(FWRETRACT) // If retracted before goto pause if (fwretract.retracted[active_extruder]) - do_pause_e_move(-fwretract.settings.retract_length, fwretract.settings.retract_feedrate_mm_s); + unscaled_e_move(-fwretract.settings.retract_length, fwretract.settings.retract_feedrate_mm_s); #endif // If resume_position is negative - if (resume_position.e < 0) do_pause_e_move(resume_position.e, feedRate_t(PAUSE_PARK_RETRACT_FEEDRATE)); - - // Move XY to starting position, then Z - do_blocking_move_to_xy(resume_position, feedRate_t(NOZZLE_PARK_XY_FEEDRATE)); - - // Move Z_AXIS to saved position - do_blocking_move_to_z(resume_position.z, feedRate_t(NOZZLE_PARK_Z_FEEDRATE)); - + if (resume_position.e < 0) unscaled_e_move(resume_position.e, feedRate_t(PAUSE_PARK_RETRACT_FEEDRATE)); #if ADVANCED_PAUSE_RESUME_PRIME != 0 - do_pause_e_move(ADVANCED_PAUSE_RESUME_PRIME, feedRate_t(ADVANCED_PAUSE_PURGE_FEEDRATE)); + unscaled_e_move(ADVANCED_PAUSE_RESUME_PRIME, feedRate_t(ADVANCED_PAUSE_PURGE_FEEDRATE)); #endif // Now all extrusion positions are resumed and ready to be confirmed // Set extruder to saved position planner.set_e_position_mm((destination.e = current_position.e = resume_position.e)); - #if HAS_LCD_MENU - lcd_pause_show_message(PAUSE_MESSAGE_STATUS); - #endif + // Write PLR now to update the z axis value + TERN_(POWER_LOSS_RECOVERY, if (recovery.enabled) recovery.save(true)); + + TERN_(HAS_LCD_MENU, lcd_pause_show_message(PAUSE_MESSAGE_STATUS)); #ifdef ACTION_ON_RESUMED host_action_resumed(); @@ -666,34 +657,23 @@ void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_le --did_pause_print; - #if ENABLED(HOST_PROMPT_SUPPORT) - host_prompt_open(PROMPT_INFO, PSTR("Resuming"), DISMISS_STR); - #endif + TERN_(HOST_PROMPT_SUPPORT, host_prompt_open(PROMPT_INFO, PSTR("Resuming"), DISMISS_STR)); #if ENABLED(SDSUPPORT) - if (did_pause_print) { - card.startFileprint(); - --did_pause_print; - } + if (did_pause_print) { card.startFileprint(); --did_pause_print; } #endif - #if ENABLED(ADVANCED_PAUSE_FANS_PAUSE) && FAN_COUNT > 0 + #if ENABLED(ADVANCED_PAUSE_FANS_PAUSE) && HAS_FAN thermalManager.set_fans_paused(false); #endif - #if HAS_FILAMENT_SENSOR - runout.reset(); - #endif + TERN_(HAS_FILAMENT_SENSOR, runout.reset()); // Resume the print job timer if it was running if (print_job_timer.isPaused()) print_job_timer.start(); - #if HAS_DISPLAY - ui.reset_status(); - #if HAS_LCD_MENU - ui.return_to_status(); - #endif - #endif + TERN_(HAS_DISPLAY, ui.reset_status()); + TERN_(HAS_LCD_MENU, ui.return_to_status()); } #endif // ADVANCED_PAUSE_FEATURE diff --git a/Marlin/src/feature/pause.h b/Marlin/src/feature/pause.h index 5ac67a565c36..016b0ce3f7d9 100644 --- a/Marlin/src/feature/pause.h +++ b/Marlin/src/feature/pause.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -45,7 +45,7 @@ enum PauseMode : char { }; enum PauseMessage : char { - PAUSE_MESSAGE_PAUSING, + PAUSE_MESSAGE_PARKING, PAUSE_MESSAGE_CHANGING, PAUSE_MESSAGE_WAITING, PAUSE_MESSAGE_UNLOAD, @@ -77,19 +77,19 @@ extern uint8_t did_pause_print; #define DXC_PARAMS , const int8_t DXC_ext=-1 #define DXC_ARGS , const int8_t DXC_ext #define DXC_PASS , DXC_ext + #define DXC_SAY , " dxc:", int(DXC_ext) #else #define DXC_PARAMS #define DXC_ARGS #define DXC_PASS + #define DXC_SAY #endif -void do_pause_e_move(const float &length, const feedRate_t &fr_mm_s); - bool pause_print(const float &retract, const xyz_pos_t &park_point, const float &unload_length=0, const bool show_lcd=false DXC_PARAMS); void wait_for_confirmation(const bool is_reload=false, const int8_t max_beep_count=0 DXC_PARAMS); -void resume_print(const float &slow_load_length=0, const float &fast_load_length=0, const float &extrude_length=ADVANCED_PAUSE_PURGE_LENGTH, const int8_t max_beep_count=0 DXC_PARAMS); +void resume_print(const float &slow_load_length=0, const float &fast_load_length=0, const float &extrude_length=ADVANCED_PAUSE_PURGE_LENGTH, const int8_t max_beep_count=0, int16_t targetTemp=0 DXC_PARAMS); bool load_filament(const float &slow_load_length=0, const float &fast_load_length=0, const float &extrude_length=0, const int8_t max_beep_count=0, const bool show_lcd=false, const bool pause_for_user=false, const PauseMode mode=PAUSE_MODE_PAUSE_PRINT DXC_PARAMS); diff --git a/Marlin/src/feature/power.cpp b/Marlin/src/feature/power.cpp index f1979c376192..5be554e5e472 100644 --- a/Marlin/src/feature/power.cpp +++ b/Marlin/src/feature/power.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -33,6 +33,10 @@ #include "../module/stepper/indirection.h" #include "../MarlinCore.h" +#if BOTH(USE_CONTROLLER_FAN, AUTO_POWER_CONTROLLERFAN) + #include "controllerfan.h" +#endif + Power powerManager; millis_t Power::lastPowerOn; @@ -46,19 +50,15 @@ bool Power::is_power_needed() { HOTEND_LOOP() if (thermalManager.autofan_speed[e]) return true; #endif - #if ENABLED(AUTO_POWER_CONTROLLERFAN, USE_CONTROLLER_FAN) && HAS_CONTROLLER_FAN - if (controllerfan_speed) return true; + #if BOTH(USE_CONTROLLER_FAN, AUTO_POWER_CONTROLLERFAN) + if (controllerFan.state()) return true; #endif - #if ENABLED(AUTO_POWER_CHAMBER_FAN) - if (thermalManager.chamberfan_speed) return true; - #endif + if (TERN0(AUTO_POWER_CHAMBER_FAN, thermalManager.chamberfan_speed)) + return true; // If any of the drivers or the bed are enabled... if (X_ENABLE_READ() == X_ENABLE_ON || Y_ENABLE_READ() == Y_ENABLE_ON || Z_ENABLE_READ() == Z_ENABLE_ON - #if HAS_HEATED_BED - || thermalManager.temp_bed.soft_pwm_amount > 0 - #endif #if HAS_X2_ENABLE || X2_ENABLE_READ() == X_ENABLE_ON #endif @@ -74,13 +74,10 @@ bool Power::is_power_needed() { #endif ) return true; - HOTEND_LOOP() if (thermalManager.degTargetHotend(e) > 0) return true; + HOTEND_LOOP() if (thermalManager.degTargetHotend(e) > 0 || thermalManager.temp_hotend[e].soft_pwm_amount > 0) return true; + if (TERN0(HAS_HEATED_BED, thermalManager.degTargetBed() > 0 || thermalManager.temp_bed.soft_pwm_amount > 0)) return true; - #if HAS_HEATED_BED - if (thermalManager.degTargetBed() > 0) return true; - #endif - - #if HOTENDS && AUTO_POWER_E_TEMP + #if HAS_HOTEND && AUTO_POWER_E_TEMP HOTEND_LOOP() if (thermalManager.degHotend(e) >= AUTO_POWER_E_TEMP) return true; #endif @@ -98,7 +95,7 @@ void Power::check() { nextPowerCheck = ms + 2500UL; if (is_power_needed()) power_on(); - else if (!lastPowerOn || ELAPSED(ms, lastPowerOn + (POWER_TIMEOUT) * 1000UL)) + else if (!lastPowerOn || ELAPSED(ms, lastPowerOn + SEC_TO_MS(POWER_TIMEOUT))) power_off(); } } @@ -107,11 +104,9 @@ void Power::power_on() { lastPowerOn = millis(); if (!powersupply_on) { PSU_PIN_ON(); - - #if HAS_TRINAMIC - delay(PSU_POWERUP_DELAY); // Wait for power to settle - restore_stepper_drivers(); - #endif + safe_delay(PSU_POWERUP_DELAY); + restore_stepper_drivers(); + TERN_(HAS_TRINAMIC_CONFIG, safe_delay(PSU_POWERUP_DELAY)); } } diff --git a/Marlin/src/feature/power.h b/Marlin/src/feature/power.h index 0bad7736ef45..8b988907e6c6 100644 --- a/Marlin/src/feature/power.h +++ b/Marlin/src/feature/power.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/feature/power_monitor.cpp b/Marlin/src/feature/power_monitor.cpp new file mode 100644 index 000000000000..af31d156fc84 --- /dev/null +++ b/Marlin/src/feature/power_monitor.cpp @@ -0,0 +1,75 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../inc/MarlinConfigPre.h" + +#if HAS_POWER_MONITOR + +#include "power_monitor.h" + +#include "../lcd/ultralcd.h" +#include "../lcd/lcdprint.h" +#include "../libs/numtostr.h" + +uint8_t PowerMonitor::flags; // = 0 + +#if ENABLED(POWER_MONITOR_CURRENT) + pm_lpf_t PowerMonitor::amps; +#endif +#if ENABLED(POWER_MONITOR_VOLTAGE) + pm_lpf_t PowerMonitor::volts; +#endif + +millis_t PowerMonitor::display_item_ms; +uint8_t PowerMonitor::display_item; + +PowerMonitor power_monitor; // Single instance - this calls the constructor + +#if HAS_MARLINUI_U8GLIB + + #if ENABLED(POWER_MONITOR_CURRENT) + void PowerMonitor::draw_current() { + const float amps = getAmps(); + lcd_put_u8str(amps < 100 ? ftostr31ns(amps) : ui16tostr4rj((uint16_t)amps)); + lcd_put_wchar('A'); + } + #endif + + #if HAS_POWER_MONITOR_VREF + void PowerMonitor::draw_voltage() { + const float volts = getVolts(); + lcd_put_u8str(volts < 100 ? ftostr31ns(volts) : ui16tostr4rj((uint16_t)volts)); + lcd_put_wchar('V'); + } + #endif + + #if HAS_POWER_MONITOR_WATTS + void PowerMonitor::draw_power() { + const float power = getPower(); + lcd_put_u8str(power < 100 ? ftostr31ns(power) : ui16tostr4rj((uint16_t)power)); + lcd_put_wchar('W'); + } + #endif + +#endif // HAS_MARLINUI_U8GLIB + +#endif // HAS_POWER_MONITOR diff --git a/Marlin/src/feature/power_monitor.h b/Marlin/src/feature/power_monitor.h new file mode 100644 index 000000000000..a0eaf353f4c7 --- /dev/null +++ b/Marlin/src/feature/power_monitor.h @@ -0,0 +1,142 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../inc/MarlinConfig.h" + +#define PM_SAMPLE_RANGE 1024 +#define PM_K_VALUE 6 +#define PM_K_SCALE 6 + +template +struct pm_lpf_t { + uint32_t filter_buf; + float value; + void add_sample(const uint16_t sample) { + filter_buf = filter_buf - (filter_buf >> K_VALUE) + (uint32_t(sample) << K_SCALE); + } + void capture() { + value = filter_buf * (SCALE * (1.0f / (1UL << (PM_K_VALUE + PM_K_SCALE)))) + (POWER_MONITOR_CURRENT_OFFSET); + } + void reset(uint16_t reset_value = 0) { + filter_buf = uint32_t(reset_value) << (K_VALUE + K_SCALE); + capture(); + } +}; + +class PowerMonitor { +private: + #if ENABLED(POWER_MONITOR_CURRENT) + static constexpr float amps_adc_scale = float(ADC_VREF) / (POWER_MONITOR_VOLTS_PER_AMP * PM_SAMPLE_RANGE); + static pm_lpf_t amps; + #endif + #if ENABLED(POWER_MONITOR_VOLTAGE) + static constexpr float volts_adc_scale = float(ADC_VREF) / (POWER_MONITOR_VOLTS_PER_VOLT * PM_SAMPLE_RANGE); + static pm_lpf_t volts; + #endif + +public: + static uint8_t flags; // M430 flags to display current + + static millis_t display_item_ms; + static uint8_t display_item; + + PowerMonitor() { reset(); } + + enum PM_Display_Bit : uint8_t { + PM_DISP_BIT_I, // Current display enable bit + PM_DISP_BIT_V, // Voltage display enable bit + PM_DISP_BIT_P // Power display enable bit + }; + + #if ENABLED(POWER_MONITOR_CURRENT) + FORCE_INLINE static float getAmps() { return amps.value; } + void add_current_sample(const uint16_t value) { amps.add_sample(value); } + #endif + + #if HAS_POWER_MONITOR_VREF + #if ENABLED(POWER_MONITOR_VOLTAGE) + FORCE_INLINE static float getVolts() { return volts.value; } + #else + FORCE_INLINE static float getVolts() { return POWER_MONITOR_FIXED_VOLTAGE; } // using a specified fixed valtage as the voltage measurement + #endif + #if ENABLED(POWER_MONITOR_VOLTAGE) + void add_voltage_sample(const uint16_t value) { volts.add_sample(value); } + #endif + #endif + + #if HAS_POWER_MONITOR_WATTS + FORCE_INLINE static float getPower() { return getAmps() * getVolts(); } + #endif + + #if HAS_WIRED_LCD + #if HAS_MARLINUI_U8GLIB && DISABLED(LIGHTWEIGHT_UI) + FORCE_INLINE static bool display_enabled() { return flags != 0x00; } + #endif + #if ENABLED(POWER_MONITOR_CURRENT) + static void draw_current(); + FORCE_INLINE static bool current_display_enabled() { return TEST(flags, PM_DISP_BIT_I); } + FORCE_INLINE static void set_current_display(const bool b) { SET_BIT_TO(flags, PM_DISP_BIT_I, b); } + FORCE_INLINE static void toggle_current_display() { TBI(flags, PM_DISP_BIT_I); } + #endif + #if HAS_POWER_MONITOR_VREF + static void draw_voltage(); + FORCE_INLINE static bool voltage_display_enabled() { return TEST(flags, PM_DISP_BIT_V); } + FORCE_INLINE static void set_voltage_display(const bool b) { SET_BIT_TO(flags, PM_DISP_BIT_V, b); } + FORCE_INLINE static void toggle_voltage_display() { TBI(flags, PM_DISP_BIT_V); } + #endif + #if HAS_POWER_MONITOR_WATTS + static void draw_power(); + FORCE_INLINE static bool power_display_enabled() { return TEST(flags, PM_DISP_BIT_P); } + FORCE_INLINE static void set_power_display(const bool b) { SET_BIT_TO(flags, PM_DISP_BIT_P, b); } + FORCE_INLINE static void toggle_power_display() { TBI(flags, PM_DISP_BIT_P); } + #endif + #endif + + static void reset() { + flags = 0x00; + + #if ENABLED(POWER_MONITOR_CURRENT) + amps.reset(); + #endif + + #if ENABLED(POWER_MONITOR_VOLTAGE) + volts.reset(); + #endif + + #if ENABLED(SDSUPPORT) + display_item_ms = 0; + display_item = 0; + #endif + } + + static void capture_values() { + #if ENABLED(POWER_MONITOR_CURRENT) + amps.capture(); + #endif + #if ENABLED(POWER_MONITOR_VOLTAGE) + volts.capture(); + #endif + } +}; + +extern PowerMonitor power_monitor; diff --git a/Marlin/src/feature/power_loss_recovery.cpp b/Marlin/src/feature/powerloss.cpp similarity index 65% rename from Marlin/src/feature/power_loss_recovery.cpp rename to Marlin/src/feature/powerloss.cpp index f331a9f94d68..e4bc605bb55f 100644 --- a/Marlin/src/feature/power_loss_recovery.cpp +++ b/Marlin/src/feature/powerloss.cpp @@ -16,19 +16,19 @@ * 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 . + * along with this program. If not, see . * */ /** - * power_loss_recovery.cpp - Resume an SD print after power-loss + * feature/powerloss.cpp - Resume an SD print after power-loss */ #include "../inc/MarlinConfigPre.h" #if ENABLED(POWER_LOSS_RECOVERY) -#include "power_loss_recovery.h" +#include "powerloss.h" #include "../core/macros.h" bool PrintJobRecovery::enabled; // Initialized by settings.load() @@ -40,6 +40,10 @@ uint8_t PrintJobRecovery::queue_index_r; uint32_t PrintJobRecovery::cmd_sdpos, // = 0 PrintJobRecovery::sdpos[BUFSIZE]; +#if ENABLED(DWIN_CREALITY_LCD) + bool PrintJobRecovery::dwin_flag; // = false +#endif + #include "../sd/cardreader.h" #include "../lcd/ultralcd.h" #include "../gcode/queue.h" @@ -62,12 +66,16 @@ PrintJobRecovery recovery; #ifndef POWER_LOSS_PURGE_LEN #define POWER_LOSS_PURGE_LEN 0 #endif +#ifndef POWER_LOSS_ZRAISE + #define POWER_LOSS_ZRAISE 2 // Move on loss with backup power, or on resume without it +#endif + +#if DISABLED(BACKUP_POWER_SUPPLY) + #undef POWER_LOSS_RETRACT_LEN // No retract at outage without backup power +#endif #ifndef POWER_LOSS_RETRACT_LEN #define POWER_LOSS_RETRACT_LEN 0 #endif -#ifndef POWER_LOSS_ZRAISE - #define POWER_LOSS_ZRAISE 2 -#endif /** * Clear the recovery info @@ -100,13 +108,11 @@ void PrintJobRecovery::changed() { * If a saved state exists send 'M1000 S' to initiate job recovery. */ void PrintJobRecovery::check() { - if (enabled) { - if (!card.isMounted()) card.mount(); - if (card.isMounted()) { - load(); - if (!valid()) return purge(); - queue.inject_P(PSTR("M1000 S")); - } + //if (!card.isMounted()) card.mount(); + if (card.isMounted()) { + load(); + if (!valid()) return cancel(); + queue.inject_P(PSTR("M1000S")); } } @@ -141,7 +147,7 @@ void PrintJobRecovery::prepare() { /** * Save the current machine state to the power-loss recovery file */ -void PrintJobRecovery::save(const bool force/*=false*/) { +void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=0*/) { #if SAVE_INFO_INTERVAL_MS > 0 static millis_t next_save_ms; // = 0 @@ -174,24 +180,21 @@ void PrintJobRecovery::save(const bool force/*=false*/) { // Machine state info.current_position = current_position; - #if HAS_HOME_OFFSET - info.home_offset = home_offset; - #endif - #if HAS_POSITION_SHIFT - info.position_shift = position_shift; - #endif + info.zraise = zraise; + TERN_(HAS_HOME_OFFSET, info.home_offset = home_offset); + TERN_(HAS_POSITION_SHIFT, info.position_shift = position_shift); info.feedrate = uint16_t(feedrate_mm_s * 60.0f); - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER info.active_extruder = active_extruder; #endif #if DISABLED(NO_VOLUMETRICS) info.volumetric_enabled = parser.volumetric_enabled; - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER for (int8_t e = 0; e < EXTRUDERS; e++) info.filament_size[e] = planner.filament_size[e]; #else - if (parser.volumetric_enabled) info.filament_size = planner.filament_size[active_extruder]; + if (parser.volumetric_enabled) info.filament_size[0] = planner.filament_size[active_extruder]; #endif #endif @@ -199,28 +202,18 @@ void PrintJobRecovery::save(const bool force/*=false*/) { HOTEND_LOOP() info.target_temperature[e] = thermalManager.temp_hotend[e].target; #endif - #if HAS_HEATED_BED - info.target_temperature_bed = thermalManager.temp_bed.target; - #endif + TERN_(HAS_HEATED_BED, info.target_temperature_bed = thermalManager.temp_bed.target); - #if FAN_COUNT + #if HAS_FAN COPY(info.fan_speed, thermalManager.fan_speed); #endif #if HAS_LEVELING info.leveling = planner.leveling_active; - info.fade = ( - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - planner.z_fade_height - #else - 0 - #endif - ); + info.fade = TERN0(ENABLE_LEVELING_FADE_HEIGHT, planner.z_fade_height); #endif - #if ENABLED(GRADIENT_MIX) - memcpy(&info.gradient, &mixer.gradient, sizeof(info.gradient)); - #endif + TERN_(GRADIENT_MIX, memcpy(&info.gradient, &mixer.gradient, sizeof(info.gradient))); #if ENABLED(FWRETRACT) COPY(info.retract, fwretract.current_retract); @@ -233,38 +226,83 @@ void PrintJobRecovery::save(const bool force/*=false*/) { // Elapsed print job time info.print_job_elapsed = print_job_timer.duration(); + // Misc. Marlin flags + info.flag.dryrun = !!(marlin_debug_flags & MARLIN_DEBUG_DRYRUN); + info.flag.allow_cold_extrusion = TERN0(PREVENT_COLD_EXTRUSION, thermalManager.allow_cold_extrude); + write(); } } #if PIN_EXISTS(POWER_LOSS) + #if ENABLED(BACKUP_POWER_SUPPLY) + + void PrintJobRecovery::retract_and_lift(const float &zraise) { + #if POWER_LOSS_RETRACT_LEN || POWER_LOSS_ZRAISE + + gcode.set_relative_mode(true); // Use relative coordinates + + #if POWER_LOSS_RETRACT_LEN + // Retract filament now + gcode.process_subcommands_now_P(PSTR("G1 F3000 E-" STRINGIFY(POWER_LOSS_RETRACT_LEN))); + #endif + + #if POWER_LOSS_ZRAISE + // Raise the Z axis now + if (zraise) { + char cmd[20], str_1[16]; + sprintf_P(cmd, PSTR("G0 Z%s"), dtostrf(zraise, 1, 3, str_1)); + gcode.process_subcommands_now(cmd); + } + #else + UNUSED(zraise); + #endif + + //gcode.axis_relative = info.axis_relative; + planner.synchronize(); + #endif + } + + #endif + + /** + * An outage was detected by a sensor pin. + * - If not SD printing, let the machine turn off on its own with no "KILL" screen + * - Disable all heaters first to save energy + * - Save the recovery data for the current instant + * - If backup power is available Retract E and Raise Z + * - Go to the KILL screen + */ void PrintJobRecovery::_outage() { #if ENABLED(BACKUP_POWER_SUPPLY) static bool lock = false; - if (lock) return; // No re-entrance from idle() during raise_z() + if (lock) return; // No re-entrance from idle() during retract_and_lift() lock = true; #endif - if (IS_SD_PRINTING()) save(true); - #if ENABLED(BACKUP_POWER_SUPPLY) - raise_z(); + + #if POWER_LOSS_ZRAISE + // Get the limited Z-raise to do now or on resume + const float zraise = _MAX(0, _MIN(current_position.z + POWER_LOSS_ZRAISE, Z_MAX_POS - 1) - current_position.z); + #else + constexpr float zraise = 0; #endif - kill(GET_TEXT(MSG_OUTAGE_RECOVERY)); - } + // Save, including the limited Z raise + if (IS_SD_PRINTING()) save(true, zraise); - #if ENABLED(BACKUP_POWER_SUPPLY) + // Disable all heaters to reduce power loss + thermalManager.disable_all_heaters(); - void PrintJobRecovery::raise_z() { - // Disable all heaters to reduce power loss - thermalManager.disable_all_heaters(); + #if ENABLED(BACKUP_POWER_SUPPLY) + // Do a hard-stop of the steppers (with possibly a loud thud) quickstop_stepper(); - // Raise Z axis - gcode.process_subcommands_now_P(PSTR("G91\nG0 Z" STRINGIFY(POWER_LOSS_ZRAISE))); - planner.synchronize(); - } + // With backup power a retract and raise can be done now + retract_and_lift(zraise); + #endif - #endif + kill(GET_TEXT(MSG_OUTAGE_RECOVERY)); + } #endif @@ -287,62 +325,69 @@ void PrintJobRecovery::write() { */ void PrintJobRecovery::resume() { + char cmd[MAX_CMD_SIZE+16], str_1[16], str_2[16]; + const uint32_t resume_sdpos = info.sdpos; // Get here before the stepper ISR overwrites it + // Apply the dry-run flag if enabled + if (info.flag.dryrun) marlin_debug_flags |= MARLIN_DEBUG_DRYRUN; + + // Restore cold extrusion permission + TERN_(PREVENT_COLD_EXTRUSION, thermalManager.allow_cold_extrude = info.flag.allow_cold_extrusion); + #if HAS_LEVELING // Make sure leveling is off before any G92 and G28 gcode.process_subcommands_now_P(PSTR("M420 S0 Z0")); #endif // Reset E, raise Z, home XY... - gcode.process_subcommands_now_P(PSTR("G92.9 E0" - #if Z_HOME_DIR > 0 + #if Z_HOME_DIR > 0 - // If Z homing goes to max, just reset E and home all - "\n" + // If Z homing goes to max, just reset E and home all + gcode.process_subcommands_now_P(PSTR( + "G92.9 E0\n" "G28R0" - #if ENABLED(MARLIN_DEV_MODE) - "S" - #endif + )); - #else // "G92.9 E0 ..." + #else // "G92.9 E0 ..." - // Set Z to 0, raise Z by RECOVERY_ZRAISE, and Home (XY only for Cartesian) - // with no raise. (Only do simulated homing in Marlin Dev Mode.) - #if ENABLED(BACKUP_POWER_SUPPLY) - "Z" STRINGIFY(POWER_LOSS_ZRAISE) // Z-axis was already raised at outage - #else - "Z0\n" // Set Z=0 - "G1Z" STRINGIFY(POWER_LOSS_ZRAISE) // Raise Z - #endif - "\n" + // Set Z to 0, raise Z by info.zraise, and Home (XY only for Cartesian) + // with no raise. (Only do simulated homing in Marlin Dev Mode.) - "G28R0" - #if ENABLED(MARLIN_DEV_MODE) - "S" - #elif !IS_KINEMATIC - "XY" + sprintf_P(cmd, PSTR("G92.9 E0 " + #if ENABLED(BACKUP_POWER_SUPPLY) + "Z%s" // Z was already raised at outage + #else + "Z0\nG1Z%s" // Set Z=0 and Raise Z now + #endif + ), + dtostrf(info.zraise, 1, 3, str_1) + ); + gcode.process_subcommands_now(cmd); + + gcode.process_subcommands_now_P(PSTR( + "G28R0" // No raise during G28 + #if IS_CARTESIAN && DISABLED(POWER_LOSS_RECOVER_ZHOME) + "XY" // Don't home Z on Cartesian unless overridden #endif - #endif - )); + )); - // Pretend that all axes are homed - axis_homed = axis_known_position = xyz_bits; + #endif - char cmd[MAX_CMD_SIZE+16], str_1[16], str_2[16]; + // Pretend that all axes are homed + set_all_homed(); - // Select the previously active tool (with no_move) - #if EXTRUDERS > 1 - sprintf_P(cmd, PSTR("T%i S"), info.active_extruder); + #if ENABLED(POWER_LOSS_RECOVER_ZHOME) + // Z has been homed so restore Z to ZsavedPos + POWER_LOSS_ZRAISE + sprintf_P(cmd, PSTR("G1 F500 Z%s"), dtostrf(info.current_position.z + POWER_LOSS_ZRAISE, 1, 3, str_1)); gcode.process_subcommands_now(cmd); #endif // Recover volumetric extrusion state #if DISABLED(NO_VOLUMETRICS) - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER for (int8_t e = 0; e < EXTRUDERS; e++) { - dtostrf(info.filament_size[e], 1, 3, str_1); - sprintf_P(cmd, PSTR("M200 T%i D%s"), e, str_1); + sprintf_P(cmd, PSTR("M200 T%i D%s"), e, dtostrf(info.filament_size[e], 1, 3, str_1)); gcode.process_subcommands_now(cmd); } if (!info.volumetric_enabled) { @@ -351,8 +396,7 @@ void PrintJobRecovery::resume() { } #else if (info.volumetric_enabled) { - dtostrf(info.filament_size, 1, 3, str_1); - sprintf_P(cmd, PSTR("M200 D%s"), str_1); + sprintf_P(cmd, PSTR("M200 D%s"), dtostrf(info.filament_size[0], 1, 3, str_1)); gcode.process_subcommands_now(cmd); } #endif @@ -368,12 +412,12 @@ void PrintJobRecovery::resume() { #endif // Restore all hotend temperatures - #if HOTENDS + #if HAS_HOTEND HOTEND_LOOP() { const int16_t et = info.target_temperature[e]; if (et) { - #if HOTENDS > 1 - sprintf_P(cmd, PSTR("T%i"), e); + #if HAS_MULTI_HOTEND + sprintf_P(cmd, PSTR("T%i S"), e); gcode.process_subcommands_now(cmd); #endif sprintf_P(cmd, PSTR("M109 S%i"), et); @@ -382,6 +426,12 @@ void PrintJobRecovery::resume() { } #endif + // Select the previously active tool (with no_move) + #if HAS_MULTI_EXTRUDER + sprintf_P(cmd, PSTR("T%i S"), info.active_extruder); + gcode.process_subcommands_now(cmd); + #endif + // Restore print cooling fan speeds FANS_LOOP(i) { uint8_t f = info.fan_speed[i]; @@ -393,7 +443,7 @@ void PrintJobRecovery::resume() { // Restore retract and hop state #if ENABLED(FWRETRACT) - for (uint8_t e = 0; e < EXTRUDERS; e++) { + LOOP_L_N(e, EXTRUDERS) { if (info.retract[e] != 0.0) { fwretract.current_retract[e] = info.retract[e]; fwretract.retracted[e] = true; @@ -415,18 +465,21 @@ void PrintJobRecovery::resume() { memcpy(&mixer.gradient, &info.gradient, sizeof(info.gradient)); #endif - // Extrude and retract to clean the nozzle - #if POWER_LOSS_PURGE_LEN - //sprintf_P(cmd, PSTR("G1 E%d F200"), POWER_LOSS_PURGE_LEN); - //gcode.process_subcommands_now(cmd); - gcode.process_subcommands_now_P(PSTR("G1 E" STRINGIFY(POWER_LOSS_PURGE_LEN) " F200")); + // Un-retract if there was a retract at outage + #if POWER_LOSS_RETRACT_LEN + gcode.process_subcommands_now_P(PSTR("G1 E" STRINGIFY(POWER_LOSS_RETRACT_LEN) " F3000")); #endif - #if POWER_LOSS_RETRACT_LEN - sprintf_P(cmd, PSTR("G1 E%d F3000"), POWER_LOSS_PURGE_LEN - (POWER_LOSS_RETRACT_LEN)); + // Additional purge if configured + #if POWER_LOSS_PURGE_LEN + sprintf_P(cmd, PSTR("G1 E%d F200"), (POWER_LOSS_PURGE_LEN) + (POWER_LOSS_RETRACT_LEN)); gcode.process_subcommands_now(cmd); #endif + #if ENABLED(NOZZLE_CLEAN_FEATURE) + gcode.process_subcommands_now_P(PSTR("G12")); + #endif + // Move back to the saved XY sprintf_P(cmd, PSTR("G1 X%s Y%s F3000"), dtostrf(info.current_position.x, 1, 3, str_1), @@ -436,7 +489,7 @@ void PrintJobRecovery::resume() { // Move back to the saved Z dtostrf(info.current_position.z, 1, 3, str_1); - #if Z_HOME_DIR > 0 + #if Z_HOME_DIR > 0 || ENABLED(POWER_LOSS_RECOVER_ZHOME) sprintf_P(cmd, PSTR("G1 Z%s F200"), str_1); #else gcode.process_subcommands_now_P(PSTR("G1 Z0 F200")); @@ -444,13 +497,6 @@ void PrintJobRecovery::resume() { #endif gcode.process_subcommands_now(cmd); - // Un-retract - #if POWER_LOSS_PURGE_LEN - //sprintf_P(cmd, PSTR("G1 E%d F3000"), POWER_LOSS_PURGE_LEN); - //gcode.process_subcommands_now(cmd); - gcode.process_subcommands_now_P(PSTR("G1 E" STRINGIFY(POWER_LOSS_PURGE_LEN) " F3000")); - #endif - // Restore the feedrate sprintf_P(cmd, PSTR("G1 F%d"), info.feedrate); gcode.process_subcommands_now(cmd); @@ -462,16 +508,20 @@ void PrintJobRecovery::resume() { // Relative axis modes gcode.axis_relative = info.axis_relative; - #if HAS_HOME_OFFSET - home_offset = info.home_offset; - #endif - #if HAS_POSITION_SHIFT - position_shift = info.position_shift; - #endif + TERN_(HAS_HOME_OFFSET, home_offset = info.home_offset); + TERN_(HAS_POSITION_SHIFT, position_shift = info.position_shift); #if HAS_HOME_OFFSET || HAS_POSITION_SHIFT LOOP_XYZ(i) update_workspace_offset((AxisEnum)i); #endif + #if ENABLED(DEBUG_POWER_LOSS_RECOVERY) + const uint8_t old_flags = marlin_debug_flags; + marlin_debug_flags |= MARLIN_DEBUG_ECHO; + #endif + + // Continue to apply PLR when a file is resumed! + enable(true); + // Resume the SD file from the last position char *fn = info.sd_filename; extern const char M23_STR[]; @@ -479,6 +529,8 @@ void PrintJobRecovery::resume() { gcode.process_subcommands_now(cmd); sprintf_P(cmd, PSTR("M24 S%ld T%ld"), resume_sdpos, info.print_job_elapsed); gcode.process_subcommands_now(cmd); + + TERN_(DEBUG_POWER_LOSS_RECOVERY, marlin_debug_flags = old_flags); } #if ENABLED(DEBUG_POWER_LOSS_RECOVERY) @@ -491,15 +543,17 @@ void PrintJobRecovery::resume() { DEBUG_ECHOPGM("current_position: "); LOOP_XYZE(i) { if (i) DEBUG_CHAR(','); - DEBUG_ECHO(info.current_position[i]); + DEBUG_DECIMAL(info.current_position[i]); } DEBUG_EOL(); + DEBUG_ECHOLNPAIR("zraise: ", info.zraise); + #if HAS_HOME_OFFSET DEBUG_ECHOPGM("home_offset: "); LOOP_XYZ(i) { if (i) DEBUG_CHAR(','); - DEBUG_ECHO(info.home_offset[i]); + DEBUG_DECIMAL(info.home_offset[i]); } DEBUG_EOL(); #endif @@ -508,18 +562,18 @@ void PrintJobRecovery::resume() { DEBUG_ECHOPGM("position_shift: "); LOOP_XYZ(i) { if (i) DEBUG_CHAR(','); - DEBUG_ECHO(info.position_shift[i]); + DEBUG_DECIMAL(info.position_shift[i]); } DEBUG_EOL(); #endif DEBUG_ECHOLNPAIR("feedrate: ", info.feedrate); - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER DEBUG_ECHOLNPAIR("active_extruder: ", int(info.active_extruder)); #endif - #if HOTENDS + #if HAS_HOTEND DEBUG_ECHOPGM("target_temperature: "); HOTEND_LOOP() { DEBUG_ECHO(info.target_temperature[e]); @@ -532,7 +586,7 @@ void PrintJobRecovery::resume() { DEBUG_ECHOLNPAIR("target_temperature_bed: ", info.target_temperature_bed); #endif - #if FAN_COUNT + #if HAS_FAN DEBUG_ECHOPGM("fan_speed: "); FANS_LOOP(i) { DEBUG_ECHO(int(info.fan_speed[i])); @@ -542,7 +596,7 @@ void PrintJobRecovery::resume() { #endif #if HAS_LEVELING - DEBUG_ECHOLNPAIR("leveling: ", int(info.leveling), "\n fade: ", int(info.fade)); + DEBUG_ECHOLNPAIR("leveling: ", int(info.leveling), " fade: ", info.fade); #endif #if ENABLED(FWRETRACT) DEBUG_ECHOPGM("retract: "); @@ -556,6 +610,8 @@ void PrintJobRecovery::resume() { DEBUG_ECHOLNPAIR("sd_filename: ", info.sd_filename); DEBUG_ECHOLNPAIR("sdpos: ", info.sdpos); DEBUG_ECHOLNPAIR("print_job_elapsed: ", info.print_job_elapsed); + DEBUG_ECHOLNPAIR("dryrun: ", int(info.flag.dryrun)); + DEBUG_ECHOLNPAIR("allow_cold_extrusion: ", int(info.flag.allow_cold_extrusion)); } else DEBUG_ECHOLNPGM("INVALID DATA"); diff --git a/Marlin/src/feature/power_loss_recovery.h b/Marlin/src/feature/powerloss.h similarity index 73% rename from Marlin/src/feature/power_loss_recovery.h rename to Marlin/src/feature/powerloss.h index 6c4b5d5c3fbc..e31b2ec915c3 100644 --- a/Marlin/src/feature/power_loss_recovery.h +++ b/Marlin/src/feature/powerloss.h @@ -16,16 +16,18 @@ * 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 . + * along with this program. If not, see . * */ #pragma once /** - * power_loss_recovery.h - Resume an SD print after power-loss + * feature/powerloss.h - Resume an SD print after power-loss */ #include "../sd/cardreader.h" +#include "../gcode/gcode.h" + #include "../inc/MarlinConfig.h" #if ENABLED(MIXING_EXTRUDER) @@ -45,6 +47,7 @@ typedef struct { // Machine state xyze_pos_t current_position; + float zraise; #if HAS_HOME_OFFSET xyz_pos_t home_offset; @@ -55,20 +58,16 @@ typedef struct { uint16_t feedrate; - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER uint8_t active_extruder; #endif #if DISABLED(NO_VOLUMETRICS) bool volumetric_enabled; - #if EXTRUDERS > 1 - float filament_size[EXTRUDERS]; - #else - float filament_size; - #endif + float filament_size[EXTRUDERS]; #endif - #if HOTENDS + #if HAS_HOTEND int16_t target_temperature[HOTENDS]; #endif @@ -76,7 +75,7 @@ typedef struct { int16_t target_temperature_bed; #endif - #if FAN_COUNT + #if HAS_FAN uint8_t fan_speed[FAN_COUNT]; #endif @@ -108,8 +107,16 @@ typedef struct { // Job elapsed time millis_t print_job_elapsed; + // Misc. Marlin flags + struct { + bool dryrun:1; // M111 S8 + bool allow_cold_extrusion:1; // M302 P1 + } flag; + uint8_t valid_foot; + bool valid() { return valid_head && valid_head == valid_foot; } + } job_recovery_info_t; class PrintJobRecovery { @@ -123,6 +130,10 @@ class PrintJobRecovery { static uint32_t cmd_sdpos, //!< SD position of the next command sdpos[BUFSIZE]; //!< SD positions of queued commands + #if ENABLED(DWIN_CREALITY_LCD) + static bool dwin_flag; + #endif + static void init(); static void prepare(); @@ -159,37 +170,37 @@ class PrintJobRecovery { static inline void cancel() { purge(); card.autostart_index = 0; } static void load(); - static void save(const bool force=false - #if ENABLED(SAVE_EACH_CMD_MODE) - || true - #endif - ); + static void save(const bool force=ENABLED(SAVE_EACH_CMD_MODE), const float zraise=0); - #if PIN_EXISTS(POWER_LOSS) - static inline void outage() { - if (enabled && READ(POWER_LOSS_PIN) == POWER_LOSS_STATE) - _outage(); - } - #endif + #if PIN_EXISTS(POWER_LOSS) + static inline void outage() { + if (enabled && READ(POWER_LOSS_PIN) == POWER_LOSS_STATE) + _outage(); + } + #endif - static inline bool valid() { return info.valid_head && info.valid_head == info.valid_foot; } + // The referenced file exists + static inline bool interrupted_file_exists() { return card.fileExists(info.sd_filename); } - #if ENABLED(DEBUG_POWER_LOSS_RECOVERY) - static void debug(PGM_P const prefix); - #else - static inline void debug(PGM_P const) {} - #endif + static inline bool valid() { return info.valid() && interrupted_file_exists(); } + + #if ENABLED(DEBUG_POWER_LOSS_RECOVERY) + static void debug(PGM_P const prefix); + #else + static inline void debug(PGM_P const) {} + #endif private: static void write(); - #if ENABLED(BACKUP_POWER_SUPPLY) - static void raise_z(); - #endif + #if ENABLED(BACKUP_POWER_SUPPLY) + static void retract_and_lift(const float &zraise); + #endif - #if PIN_EXISTS(POWER_LOSS) - static void _outage(); - #endif + #if PIN_EXISTS(POWER_LOSS) + friend class GcodeSuite; + static void _outage(); + #endif }; extern PrintJobRecovery recovery; diff --git a/Marlin/src/feature/probe_temp_compensation.cpp b/Marlin/src/feature/probe_temp_comp.cpp similarity index 78% rename from Marlin/src/feature/probe_temp_compensation.cpp rename to Marlin/src/feature/probe_temp_comp.cpp index edb70ff268ad..af8039d8b110 100644 --- a/Marlin/src/feature/probe_temp_compensation.cpp +++ b/Marlin/src/feature/probe_temp_comp.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -24,16 +24,16 @@ #if ENABLED(PROBE_TEMP_COMPENSATION) -#include "probe_temp_compensation.h" +#include "probe_temp_comp.h" #include ProbeTempComp temp_comp; -int16_t ProbeTempComp::z_offsets_probe[ProbeTempComp::cali_info_init[TSI_PROBE].measurements], // = {0} - ProbeTempComp::z_offsets_bed[ProbeTempComp::cali_info_init[TSI_BED].measurements]; // = {0} +int16_t ProbeTempComp::z_offsets_probe[cali_info_init[TSI_PROBE].measurements], // = {0} + ProbeTempComp::z_offsets_bed[cali_info_init[TSI_BED].measurements]; // = {0} #if ENABLED(USE_TEMP_EXT_COMPENSATION) - int16_t ProbeTempComp::z_offsets_ext[ProbeTempComp::cali_info_init[TSI_EXT].measurements]; // = {0} + int16_t ProbeTempComp::z_offsets_ext[cali_info_init[TSI_EXT].measurements]; // = {0} #endif int16_t *ProbeTempComp::sensor_z_offsets[TSI_COUNT] = { @@ -44,17 +44,21 @@ int16_t *ProbeTempComp::sensor_z_offsets[TSI_COUNT] = { }; const temp_calib_t ProbeTempComp::cali_info[TSI_COUNT] = { - ProbeTempComp::cali_info_init[TSI_PROBE], ProbeTempComp::cali_info_init[TSI_BED] + cali_info_init[TSI_PROBE], cali_info_init[TSI_BED] #if ENABLED(USE_TEMP_EXT_COMPENSATION) - , ProbeTempComp::cali_info_init[TSI_EXT] + , cali_info_init[TSI_EXT] #endif }; +constexpr xyz_pos_t ProbeTempComp::park_point; +constexpr xy_pos_t ProbeTempComp::measure_point; +constexpr int ProbeTempComp::probe_calib_bed_temp; + uint8_t ProbeTempComp::calib_idx; // = 0 float ProbeTempComp::init_measurement; // = 0.0 void ProbeTempComp::clear_offsets(const TempSensorID tsi) { - for (uint8_t i = 0; i < cali_info[tsi].measurements; ++i) + LOOP_L_N(i, cali_info[tsi].measurements) sensor_z_offsets[tsi][i] = 0; calib_idx = 0; } @@ -66,7 +70,7 @@ bool ProbeTempComp::set_offset(const TempSensorID tsi, const uint8_t idx, const } void ProbeTempComp::print_offsets() { - for (uint8_t s = 0; s < TSI_COUNT; s++) { + LOOP_L_N(s, TSI_COUNT) { float temp = cali_info[s].start_temp; for (int16_t i = -1; i < cali_info[s].measurements; ++i) { serialprintPGM(s == TSI_BED ? PSTR("Bed") : @@ -161,28 +165,41 @@ void ProbeTempComp::compensate_measurement(const TempSensorID tsi, const float & } float ProbeTempComp::get_offset_for_temperature(const TempSensorID tsi, const float &temp) { - const uint8_t measurements = cali_info[tsi].measurements; const float start_temp = cali_info[tsi].start_temp, - end_temp = cali_info[tsi].end_temp, res_temp = cali_info[tsi].temp_res; const int16_t * const data = sensor_z_offsets[tsi]; - if (temp <= start_temp) return 0.0f; - if (temp >= end_temp) return static_cast(data[measurements - 1]) / 1000.0f; + auto point = [&](uint8_t i) { + return xy_float_t({start_temp + i*res_temp, static_cast(data[i])}); + }; + + auto linear_interp = [](float x, xy_float_t p1, xy_float_t p2) { + return (p2.y - p1.y) / (p2.x - p2.y) * (x - p1.x) + p1.y; + }; // Linear interpolation - int16_t val1 = 0, val2 = data[0]; - uint8_t idx = 0; - float meas_temp = start_temp + res_temp; - while (meas_temp < temp) { - if (++idx >= measurements) return static_cast(val2) / 1000.0f; - meas_temp += res_temp; - val1 = val2; - val2 = data[idx]; - } - const float factor = (meas_temp - temp) / static_cast(res_temp); - return (static_cast(val2) - static_cast(val2 - val1) * factor) / 1000.0f; + uint8_t idx = static_cast((temp - start_temp) / res_temp); + + // offset in um + float offset = 0.0f; + + #if !defined(PTC_LINEAR_EXTRAPOLATION) || PTC_LINEAR_EXTRAPOLATION <= 0 + if (idx < 0) + offset = 0.0f; + else if (idx > measurements - 2) + offset = static_cast(data[measurements - 1]); + #else + if (idx < 0) + offset = linear_interp(temp, point(0), point(PTC_LINEAR_EXTRAPOLATION)); + else if (idx > measurements - 2) + offset = linear_interp(temp, point(measurements - PTC_LINEAR_EXTRAPOLATION - 1), point(measurements - 1)); + #endif + else + offset = linear_interp(temp, point(idx), point(idx + 1)); + + // return offset in mm + return offset / 1000.0f; } bool ProbeTempComp::linear_regression(const TempSensorID tsi, float &k, float &d) { @@ -198,7 +215,7 @@ bool ProbeTempComp::linear_regression(const TempSensorID tsi, float &k, float &d sum_x2 = sq(start_temp), sum_xy = 0, sum_y = 0; - for (uint8_t i = 0; i < calib_idx; ++i) { + LOOP_L_N(i, calib_idx) { const float xi = start_temp + (i + 1) * res_temp, yi = static_cast(data[i]); sum_x += xi; diff --git a/Marlin/src/feature/probe_temp_compensation.h b/Marlin/src/feature/probe_temp_comp.h similarity index 63% rename from Marlin/src/feature/probe_temp_compensation.h rename to Marlin/src/feature/probe_temp_comp.h index c9ab93e4a99a..626dd87f945f 100644 --- a/Marlin/src/feature/probe_temp_compensation.h +++ b/Marlin/src/feature/probe_temp_comp.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -44,31 +44,64 @@ typedef struct { * Z-probes like the P.I.N.D.A V2 allow for compensation of * measurement errors/shifts due to changed temperature. */ + +// Probe temperature calibration constants +#ifndef PTC_SAMPLE_COUNT + #define PTC_SAMPLE_COUNT 10U +#endif +#ifndef PTC_SAMPLE_RES + #define PTC_SAMPLE_RES 5.0f +#endif +#ifndef PTC_SAMPLE_START + #define PTC_SAMPLE_START 30.0f +#endif +#define PTC_SAMPLE_END ((PTC_SAMPLE_START) + (PTC_SAMPLE_COUNT) * (PTC_SAMPLE_RES)) + +// Bed temperature calibration constants +#ifndef BTC_PROBE_TEMP + #define BTC_PROBE_TEMP 30.0f +#endif +#ifndef BTC_SAMPLE_COUNT + #define BTC_SAMPLE_COUNT 10U +#endif +#ifndef BTC_SAMPLE_STEP + #define BTC_SAMPLE_RES 5.0f +#endif +#ifndef BTC_SAMPLE_START + #define BTC_SAMPLE_START 60.0f +#endif +#define BTC_SAMPLE_END ((BTC_SAMPLE_START) + (BTC_SAMPLE_COUNT) * (BTC_SAMPLE_RES)) + +#ifndef PTC_PROBE_HEATING_OFFSET + #define PTC_PROBE_HEATING_OFFSET 0.5f +#endif + +#ifndef PTC_PROBE_RAISE + #define PTC_PROBE_RAISE 10.0f +#endif + +static constexpr temp_calib_t cali_info_init[TSI_COUNT] = { + { PTC_SAMPLE_COUNT, PTC_SAMPLE_RES, PTC_SAMPLE_START, PTC_SAMPLE_END }, // Probe + { BTC_SAMPLE_COUNT, BTC_SAMPLE_RES, BTC_SAMPLE_START, BTC_SAMPLE_END }, // Bed + #if ENABLED(USE_TEMP_EXT_COMPENSATION) + { 20, 5, 180, 180 + 5 * 20 } // Extruder + #endif +}; + class ProbeTempComp { public: - static constexpr temp_calib_t cali_info_init[TSI_COUNT] = { - { 10, 5, 30, 30 + 10 * 5 }, // Probe - { 10, 5, 60, 60 + 10 * 5 }, // Bed - #if ENABLED(USE_TEMP_EXT_COMPENSATION) - { 20, 5, 180, 180 + 5 * 20 } // Extruder - #endif - }; static const temp_calib_t cali_info[TSI_COUNT]; // Where to park nozzle to wait for probe cooldown - static constexpr xyz_pos_t park_point = xyz_pos_t({ PTC_PARK_POS_X, PTC_PARK_POS_Y, PTC_PARK_POS_Z }); - - static constexpr int max_bed_temp = PTC_MAX_BED_TEMP, // Max temperature to avoid heating errors + static constexpr xyz_pos_t park_point = PTC_PARK_POS; - // XY coordinates of nozzle for probing the bed - measure_point_x = PTC_PROBE_POS_X, // X-coordinate to probe - measure_point_y = PTC_PROBE_POS_Y, // Y-coordinate to probe - //measure_point_x = 12.0f, // X-coordinate to probe on MK52 magnetic heatbed - //measure_point_y = 7.3f, // Y-coordinate to probe on MK52 magnetic heatbed + // XY coordinates of nozzle for probing the bed + static constexpr xy_pos_t measure_point = PTC_PROBE_POS; // Coordinates to probe + //measure_point = { 12.0f, 7.3f }; // Coordinates for the MK52 magnetic heatbed - probe_calib_bed_temp = max_bed_temp, // Bed temperature while calibrating probe - bed_calib_probe_temp = 30; // Probe temperature while calibrating bed + static constexpr int probe_calib_bed_temp = BED_MAX_TARGET, // Bed temperature while calibrating probe + bed_calib_probe_temp = BTC_PROBE_TEMP; // Probe temperature while calibrating bed static int16_t *sensor_z_offsets[TSI_COUNT], z_offsets_probe[cali_info_init[TSI_PROBE].measurements], // (µm) @@ -84,9 +117,7 @@ class ProbeTempComp { static inline void clear_all_offsets() { clear_offsets(TSI_BED); clear_offsets(TSI_PROBE); - #if ENABLED(USE_TEMP_EXT_COMPENSATION) - clear_offsets(TSI_EXT); - #endif + TERN_(USE_TEMP_EXT_COMPENSATION, clear_offsets(TSI_EXT)); } static bool set_offset(const TempSensorID tsi, const uint8_t idx, const int16_t offset); static void print_offsets(); diff --git a/Marlin/src/feature/runout.cpp b/Marlin/src/feature/runout.cpp index 3cf81303ddbe..71f31f214559 100644 --- a/Marlin/src/feature/runout.cpp +++ b/Marlin/src/feature/runout.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -39,21 +39,17 @@ bool FilamentMonitorBase::enabled = true, bool FilamentMonitorBase::host_handling; // = false #endif -/** - * Called by FilamentSensorSwitch::run when filament is detected. - * Called by FilamentSensorEncoder::block_completed when motion is detected. - */ -void FilamentSensorBase::filament_present(const uint8_t extruder) { - runout.filament_present(extruder); // calls response.filament_present(extruder) -} - -#if ENABLED(FILAMENT_MOTION_SENSOR) - uint8_t FilamentSensorEncoder::motion_detected; +#if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) + //#define DEBUG_TOOLCHANGE_MIGRATION_FEATURE + #include "../module/tool_change.h" #endif -#ifdef FILAMENT_RUNOUT_DISTANCE_MM +#if HAS_FILAMENT_RUNOUT_DISTANCE float RunoutResponseDelayed::runout_distance_mm = FILAMENT_RUNOUT_DISTANCE_MM; volatile float RunoutResponseDelayed::runout_mm_countdown[EXTRUDERS]; + #if ENABLED(FILAMENT_MOTION_SENSOR) + uint8_t FilamentSensorEncoder::motion_detected; + #endif #else int8_t RunoutResponseDebounced::runout_count; // = 0 #endif @@ -69,19 +65,30 @@ void FilamentSensorBase::filament_present(const uint8_t extruder) { #endif #if ENABLED(EXTENSIBLE_UI) - #include "../lcd/extensible_ui/ui_api.h" + #include "../lcd/extui/ui_api.h" #endif void event_filament_runout() { - #if ENABLED(ADVANCED_PAUSE_FEATURE) - if (did_pause_print) return; // Action already in progress. Purge triggered repeated runout. - #endif + if (TERN0(ADVANCED_PAUSE_FEATURE, did_pause_print)) return; // Action already in progress. Purge triggered repeated runout. - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onFilamentRunout(ExtUI::getActiveTool()); + #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) + if (migration.in_progress) { + #if ENABLED(DEBUG_TOOLCHANGE_MIGRATION_FEATURE) + SERIAL_ECHOLN("Migration Already In Progress"); + #endif + return; // Action already in progress. Purge triggered repeated runout. + } + if (migration.automode) { + #if ENABLED(DEBUG_TOOLCHANGE_MIGRATION_FEATURE) + SERIAL_ECHOLN("Migration Starting"); + #endif + if (extruder_migration()) return; + } #endif + TERN_(EXTENSIBLE_UI, ExtUI::onFilamentRunout(ExtUI::getActiveTool())); + #if EITHER(HOST_PROMPT_SUPPORT, HOST_ACTION_COMMANDS) const char tool = '0' #if NUM_RUNOUT_SENSORS > 1 diff --git a/Marlin/src/feature/runout.h b/Marlin/src/feature/runout.h index 813f44e05e7d..a7f836684949 100644 --- a/Marlin/src/feature/runout.h +++ b/Marlin/src/feature/runout.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -34,7 +34,7 @@ #include "../inc/MarlinConfig.h" #if ENABLED(EXTENSIBLE_UI) - #include "../lcd/extensible_ui/ui_api.h" + #include "../lcd/extui/ui_api.h" #endif #if ENABLED(ADVANCED_PAUSE_FEATURE) @@ -48,6 +48,24 @@ void event_filament_runout(); +template +class TFilamentMonitor; +class FilamentSensorEncoder; +class FilamentSensorSwitch; +class RunoutResponseDelayed; +class RunoutResponseDebounced; + +/********************************* TEMPLATE SPECIALIZATION *********************************/ + +typedef TFilamentMonitor< + TERN(HAS_FILAMENT_RUNOUT_DISTANCE, RunoutResponseDelayed, RunoutResponseDebounced), + TERN(FILAMENT_MOTION_SENSOR, FilamentSensorEncoder, FilamentSensorSwitch) + > FilamentMonitor; + +extern FilamentMonitor runout; + +/*******************************************************************************************/ + class FilamentMonitorBase { public: static bool enabled, filament_ran_out; @@ -84,7 +102,7 @@ class TFilamentMonitor : public FilamentMonitorBase { response.filament_present(extruder); } - #ifdef FILAMENT_RUNOUT_DISTANCE_MM + #if HAS_FILAMENT_RUNOUT_DISTANCE static inline float& runout_distance() { return response.runout_distance_mm; } static inline void set_runout_distance(const float &mm) { response.runout_distance_mm = mm; } #endif @@ -100,20 +118,14 @@ class TFilamentMonitor : public FilamentMonitorBase { // Give the response a chance to update its counter. static inline void run() { - if (enabled && !filament_ran_out && (printingIsActive() - #if ENABLED(ADVANCED_PAUSE_FEATURE) - || did_pause_print - #endif - )) { - #ifdef FILAMENT_RUNOUT_DISTANCE_MM - cli(); // Prevent RunoutResponseDelayed::block_completed from accumulating here - #endif + if ( enabled && !filament_ran_out + && (printingIsActive() || TERN0(ADVANCED_PAUSE_FEATURE, did_pause_print)) + ) { + TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, cli()); // Prevent RunoutResponseDelayed::block_completed from accumulating here response.run(); sensor.run(); const bool ran_out = response.has_run_out(); - #ifdef FILAMENT_RUNOUT_DISTANCE_MM - sei(); - #endif + TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, sei()); if (ran_out) { filament_ran_out = true; event_filament_runout(); @@ -127,7 +139,13 @@ class TFilamentMonitor : public FilamentMonitorBase { class FilamentSensorBase { protected: - static void filament_present(const uint8_t extruder); + /** + * Called by FilamentSensorSwitch::run when filament is detected. + * Called by FilamentSensorEncoder::block_completed when motion is detected. + */ + static inline void filament_present(const uint8_t extruder) { + runout.filament_present(extruder); // ...which calls response.filament_present(extruder) + } public: static inline void setup() { @@ -142,6 +160,7 @@ class FilamentSensorBase { #define _INIT_RUNOUT(N) INIT_RUNOUT_PIN(FIL_RUNOUT##N##_PIN); REPEAT_S(1, INCREMENT(NUM_RUNOUT_SENSORS), _INIT_RUNOUT) #undef _INIT_RUNOUT + #undef INIT_RUNOUT_PIN } // Return a bitmask of runout pin states @@ -153,14 +172,12 @@ class FilamentSensorBase { // Return a bitmask of runout flag states (1 bits always indicates runout) static inline uint8_t poll_runout_states() { - return (poll_runout_pins() - #if DISABLED(FIL_RUNOUT_INVERTING) + return poll_runout_pins() + #if FIL_RUNOUT_STATE == LOW ^ uint8_t(_BV(NUM_RUNOUT_SENSORS) - 1) #endif - ); + ; } - - #undef INIT_RUNOUT_PIN }; #if ENABLED(FILAMENT_MOTION_SENSOR) @@ -184,7 +201,7 @@ class FilamentSensorBase { #ifdef FILAMENT_RUNOUT_SENSOR_DEBUG if (change) { SERIAL_ECHOPGM("Motion detected:"); - for (uint8_t e = 0; e < NUM_RUNOUT_SENSORS; e++) + LOOP_L_N(e, NUM_RUNOUT_SENSORS) if (TEST(change, e)) SERIAL_CHAR(' ', '0' + e); SERIAL_EOL(); } @@ -217,26 +234,14 @@ class FilamentSensorBase { private: static inline bool poll_runout_state(const uint8_t extruder) { const uint8_t runout_states = poll_runout_states(); - #if NUM_RUNOUT_SENSORS == 1 UNUSED(extruder); + #else + if ( !TERN0(DUAL_X_CARRIAGE, dxc_is_duplicating()) + && !TERN0(MULTI_NOZZLE_DUPLICATION, extruder_duplication_enabled) + ) return TEST(runout_states, extruder); // A specific extruder ran out #endif - - if (true - #if NUM_RUNOUT_SENSORS > 1 - #if ENABLED(DUAL_X_CARRIAGE) - && (dual_x_carriage_mode == DXC_DUPLICATION_MODE || dual_x_carriage_mode == DXC_MIRRORED_MODE) - #elif ENABLED(MULTI_NOZZLE_DUPLICATION) - && extruder_duplication_enabled - #else - && false - #endif - #endif - ) return runout_states; // Any extruder - - #if NUM_RUNOUT_SENSORS > 1 - return TEST(runout_states, extruder); // Specific extruder - #endif + return !!runout_states; // Any extruder ran out } public: @@ -261,7 +266,7 @@ class FilamentSensorBase { /********************************* RESPONSE TYPE *********************************/ -#ifdef FILAMENT_RUNOUT_DISTANCE_MM +#if HAS_FILAMENT_RUNOUT_DISTANCE // RunoutResponseDelayed triggers a runout event only if the length // of filament specified by FILAMENT_RUNOUT_DISTANCE_MM has been fed @@ -302,9 +307,7 @@ class FilamentSensorBase { static inline void block_completed(const block_t* const b) { if (b->steps.x || b->steps.y || b->steps.z - #if ENABLED(ADVANCED_PAUSE_FEATURE) - || did_pause_print // Allow pause purge move to re-trigger runout state - #endif + || TERN0(ADVANCED_PAUSE_FEATURE, did_pause_print) // Allow pause purge move to re-trigger runout state ) { // Only trigger on extrusion with XYZ movement to allow filament change and retract/recover. const uint8_t e = b->extruder; @@ -314,7 +317,7 @@ class FilamentSensorBase { } }; -#else // !FILAMENT_RUNOUT_DISTANCE_MM +#else // !HAS_FILAMENT_RUNOUT_DISTANCE // RunoutResponseDebounced triggers a runout event after a runout // condition has been detected runout_threshold times in a row. @@ -331,21 +334,4 @@ class FilamentSensorBase { static inline void filament_present(const uint8_t) { runout_count = runout_threshold; } }; -#endif // !FILAMENT_RUNOUT_DISTANCE_MM - -/********************************* TEMPLATE SPECIALIZATION *********************************/ - -typedef TFilamentMonitor< - #ifdef FILAMENT_RUNOUT_DISTANCE_MM - RunoutResponseDelayed, - #if ENABLED(FILAMENT_MOTION_SENSOR) - FilamentSensorEncoder - #else - FilamentSensorSwitch - #endif - #else - RunoutResponseDebounced, FilamentSensorSwitch - #endif -> FilamentMonitor; - -extern FilamentMonitor runout; +#endif // !HAS_FILAMENT_RUNOUT_DISTANCE diff --git a/Marlin/src/feature/snmm.cpp b/Marlin/src/feature/snmm.cpp index e994028d9e76..25723f7b38c3 100644 --- a/Marlin/src/feature/snmm.cpp +++ b/Marlin/src/feature/snmm.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/feature/snmm.h b/Marlin/src/feature/snmm.h index 671542e3bf4a..10805c8e26b7 100644 --- a/Marlin/src/feature/snmm.h +++ b/Marlin/src/feature/snmm.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/feature/solenoid.cpp b/Marlin/src/feature/solenoid.cpp index d53118fdd441..8646ec872f6f 100644 --- a/Marlin/src/feature/solenoid.cpp +++ b/Marlin/src/feature/solenoid.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/feature/solenoid.h b/Marlin/src/feature/solenoid.h index 5a503b1056a4..2ba4983fb000 100644 --- a/Marlin/src/feature/solenoid.h +++ b/Marlin/src/feature/solenoid.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/feature/spindle_laser.cpp b/Marlin/src/feature/spindle_laser.cpp index 0567ba5d3e2f..bc387a93348d 100644 --- a/Marlin/src/feature/spindle_laser.cpp +++ b/Marlin/src/feature/spindle_laser.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -31,71 +31,88 @@ #include "spindle_laser.h" SpindleLaser cutter; +uint8_t SpindleLaser::power; +bool SpindleLaser::isReady; // Ready to apply power setting from the UI to OCR +cutter_power_t SpindleLaser::menuPower, // Power set via LCD menu in PWM, PERCENT, or RPM + SpindleLaser::unitPower; // LCD status power in PWM, PERCENT, or RPM -cutter_power_t SpindleLaser::power; // = 0 - +#if ENABLED(MARLIN_DEV_MODE) + cutter_frequency_t SpindleLaser::frequency; // PWM frequency setting; range: 2K - 50K +#endif #define SPINDLE_LASER_PWM_OFF ((SPINDLE_LASER_PWM_INVERT) ? 255 : 0) +// +// Init the cutter to a safe OFF state +// void SpindleLaser::init() { - OUT_WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_HIGH); // Init spindle to off + OUT_WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_STATE); // Init spindle to off #if ENABLED(SPINDLE_CHANGE_DIR) - OUT_WRITE(SPINDLE_DIR_PIN, SPINDLE_INVERT_DIR ? 255 : 0); // Init rotation to clockwise (M3) + OUT_WRITE(SPINDLE_DIR_PIN, SPINDLE_INVERT_DIR ? 255 : 0); // Init rotation to clockwise (M3) #endif #if ENABLED(SPINDLE_LASER_PWM) SET_PWM(SPINDLE_LASER_PWM_PIN); - analogWrite(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_OFF); // set to lowest speed + analogWrite(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_OFF); // Set to lowest speed + #endif + #if ENABLED(HAL_CAN_SET_PWM_FREQ) && defined(SPINDLE_LASER_FREQUENCY) + set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_FREQUENCY); + TERN_(MARLIN_DEV_MODE, frequency = SPINDLE_LASER_FREQUENCY); #endif } #if ENABLED(SPINDLE_LASER_PWM) - /** - * ocr_val_mode() is used for debugging and to get the points needed to compute the RPM vs ocr_val line - * - * it accepts inputs of 0-255 + * Set the cutter PWM directly to the given ocr value */ void SpindleLaser::set_ocr(const uint8_t ocr) { - WRITE(SPINDLE_LASER_ENA_PIN, SPINDLE_LASER_ACTIVE_HIGH); // turn spindle on (active low) + WRITE(SPINDLE_LASER_ENA_PIN, SPINDLE_LASER_ACTIVE_STATE); // Turn spindle on analogWrite(pin_t(SPINDLE_LASER_PWM_PIN), ocr ^ SPINDLE_LASER_PWM_OFF); + #if NEEDS_HARDWARE_PWM && SPINDLE_LASER_FREQUENCY + set_pwm_duty(pin_t(SPINDLE_LASER_PWM_PIN), ocr ^ SPINDLE_LASER_PWM_OFF); + #endif + } + void SpindleLaser::ocr_off() { + WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_STATE); // Turn spindle off + analogWrite(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_OFF); // Only write low byte } - #endif -void SpindleLaser::apply_power(const cutter_power_t inpow) { - static cutter_power_t last_power_applied = 0; - if (inpow == last_power_applied) return; - last_power_applied = inpow; +// +// Set cutter ON/OFF state (and PWM) to the given cutter power value +// +void SpindleLaser::apply_power(const uint8_t opwr) { + static uint8_t last_power_applied = 0; + if (opwr == last_power_applied) return; + last_power_applied = opwr; + power = opwr; #if ENABLED(SPINDLE_LASER_PWM) - if (enabled()) { - #define _scaled(F) ((F - (SPEED_POWER_INTERCEPT)) * inv_slope) - constexpr float inv_slope = RECIPROCAL(SPEED_POWER_SLOPE), - min_ocr = _scaled(SPEED_POWER_MIN), - max_ocr = _scaled(SPEED_POWER_MAX); - int16_t ocr_val; - if (inpow <= SPEED_POWER_MIN) ocr_val = min_ocr; // Use minimum if set below - else if (inpow >= SPEED_POWER_MAX) ocr_val = max_ocr; // Use maximum if set above - else ocr_val = _scaled(inpow); // Use calculated OCR value - set_ocr(ocr_val & 0xFF); // ...limited to Atmel PWM max + if (cutter.unitPower == 0 && CUTTER_UNIT_IS(RPM)) { + ocr_off(); + isReady = false; + } + else if (enabled() || ENABLED(CUTTER_POWER_RELATIVE)) { + set_ocr(power); + isReady = true; } else { - WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_HIGH); // Turn spindle off (active low) - analogWrite(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_OFF); // Only write low byte + ocr_off(); + isReady = false; } #else - WRITE(SPINDLE_LASER_ENA_PIN, (SPINDLE_LASER_ACTIVE_HIGH) ? enabled() : !enabled()); + WRITE(SPINDLE_LASER_ENA_PIN, enabled() ? SPINDLE_LASER_ACTIVE_STATE : !SPINDLE_LASER_ACTIVE_STATE); + isReady = true; #endif } #if ENABLED(SPINDLE_CHANGE_DIR) - + // + // Set the spindle direction and apply immediately + // Stop on direction change if SPINDLE_STOP_ON_DIR_CHANGE is enabled + // void SpindleLaser::set_direction(const bool reverse) { const bool dir_state = (reverse == SPINDLE_INVERT_DIR); // Forward (M3) HIGH when not inverted - #if ENABLED(SPINDLE_STOP_ON_DIR_CHANGE) - if (enabled() && READ(SPINDLE_DIR_PIN) != dir_state) disable(); - #endif + if (TERN0(SPINDLE_STOP_ON_DIR_CHANGE, enabled()) && READ(SPINDLE_DIR_PIN) != dir_state) disable(); WRITE(SPINDLE_DIR_PIN, dir_state); } - #endif #endif // HAS_CUTTER diff --git a/Marlin/src/feature/spindle_laser.h b/Marlin/src/feature/spindle_laser.h index ea035299be3e..15ff661c73e6 100644 --- a/Marlin/src/feature/spindle_laser.h +++ b/Marlin/src/feature/spindle_laser.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -28,55 +28,159 @@ #include "../inc/MarlinConfig.h" -#if ENABLED(SPINDLE_FEATURE) - #define _MSG_CUTTER(M) MSG_SPINDLE_##M -#else - #define _MSG_CUTTER(M) MSG_LASER_##M +#include "spindle_laser_types.h" + +#if ENABLED(LASER_POWER_INLINE) + #include "../module/planner.h" #endif -#define MSG_CUTTER(M) _MSG_CUTTER(M) - -#if SPEED_POWER_MAX > 255 - typedef uint16_t cutter_power_t; - #define CUTTER_MENU_TYPE uint16_5 -#else - typedef uint8_t cutter_power_t; - #define CUTTER_MENU_TYPE uint8 + +#define PCT_TO_PWM(X) ((X) * 255 / 100) + +#ifndef SPEED_POWER_INTERCEPT + #define SPEED_POWER_INTERCEPT 0 #endif +#define SPEED_POWER_FLOOR TERN(CUTTER_POWER_RELATIVE, SPEED_POWER_MIN, 0) + +// #define _MAP(N,S1,S2,D1,D2) ((N)*_MAX((D2)-(D1),0)/_MAX((S2)-(S1),1)+(D1)) class SpindleLaser { public: - static cutter_power_t power; - static inline uint8_t powerPercent(const uint8_t pp) { return ui8_to_percent(pp); } // for display + static constexpr float + min_pct = round(TERN(CUTTER_POWER_RELATIVE, 0, (100 * float(SPEED_POWER_MIN) / TERN(SPINDLE_FEATURE, float(SPEED_POWER_MAX), 100)))), + max_pct = round(TERN(SPINDLE_FEATURE, 100, float(SPEED_POWER_MAX))); - static void init(); + static const inline uint8_t pct_to_ocr(const float pct) { return uint8_t(PCT_TO_PWM(pct)); } - static inline bool enabled() { return !!power; } + // cpower = configured values (ie SPEED_POWER_MAX) + static const inline uint8_t cpwr_to_pct(const cutter_cpower_t cpwr) { // configured value to pct + return unitPower ? round(100 * (cpwr - SPEED_POWER_FLOOR) / (SPEED_POWER_MAX - SPEED_POWER_FLOOR)) : 0; + } - static inline void set_power(const cutter_power_t pwr) { power = pwr; } + // Convert a configured value (cpower)(ie SPEED_POWER_STARTUP) to unit power (upwr, upower), + // which can be PWM, Percent, or RPM (rel/abs). + static const inline cutter_power_t cpwr_to_upwr(const cutter_cpower_t cpwr) { // STARTUP power to Unit power + const cutter_power_t upwr = ( + #if ENABLED(SPINDLE_FEATURE) + // Spindle configured values are in RPM + #if CUTTER_UNIT_IS(RPM) + cpwr // to RPM + #elif CUTTER_UNIT_IS(PERCENT) // to PCT + cpwr_to_pct(cpwr) + #else // to PWM + PCT_TO_PWM(cpwr_to_pct(cpwr)) + #endif + #else + // Laser configured values are in PCT + #if CUTTER_UNIT_IS(PWM255) + PCT_TO_PWM(cpwr) + #else + cpwr // to RPM/PCT + #endif + #endif + ); + return upwr; + } - static inline void refresh() { apply_power(power); } + static const cutter_power_t mpower_min() { return cpwr_to_upwr(SPEED_POWER_MIN); } + static const cutter_power_t mpower_max() { return cpwr_to_upwr(SPEED_POWER_MAX); } - static inline void set_enabled(const bool enable) { - const bool was = enabled(); - set_power(enable ? 255 : 0); - if (was != enable) power_delay(); - } + static bool isReady; // Ready to apply power setting from the UI to OCR + static uint8_t power; - static void apply_power(const cutter_power_t inpow); + #if ENABLED(MARLIN_DEV_MODE) + static cutter_frequency_t frequency; // Set PWM frequency; range: 2K-50K + #endif - //static bool active() { return READ(SPINDLE_LASER_ENA_PIN) == SPINDLE_LASER_ACTIVE_HIGH; } + static cutter_power_t menuPower, // Power as set via LCD menu in PWM, Percentage or RPM + unitPower; // Power as displayed status in PWM, Percentage or RPM - static void update_output(); + static void init(); + + #if ENABLED(MARLIN_DEV_MODE) + static inline void refresh_frequency() { set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), frequency); } + #endif + + // Modifying this function should update everywhere + static inline bool enabled(const cutter_power_t opwr) { return opwr > 0; } + static inline bool enabled() { return enabled(power); } + + static void apply_power(const uint8_t inpow); + + FORCE_INLINE static void refresh() { apply_power(power); } + FORCE_INLINE static void set_power(const uint8_t upwr) { power = upwr; refresh(); } #if ENABLED(SPINDLE_LASER_PWM) + static void set_ocr(const uint8_t ocr); - static inline void set_ocr_power(const cutter_power_t pwr) { power = pwr; set_ocr(pwr); } - #endif + static inline void set_ocr_power(const uint8_t ocr) { power = ocr; set_ocr(ocr); } + static void ocr_off(); + // Used to update output for power->OCR translation + static inline uint8_t upower_to_ocr(const cutter_power_t upwr) { + return ( + #if CUTTER_UNIT_IS(PWM255) + uint8_t(upwr) + #elif CUTTER_UNIT_IS(PERCENT) + pct_to_ocr(upwr) + #else + uint8_t(pct_to_ocr(cpwr_to_pct(upwr))) + #endif + ); + } + + // Correct power to configured range + static inline cutter_power_t power_to_range(const cutter_power_t pwr) { + return power_to_range(pwr, ( + #if CUTTER_UNIT_IS(PWM255) + 0 + #elif CUTTER_UNIT_IS(PERCENT) + 1 + #elif CUTTER_UNIT_IS(RPM) + 2 + #else + #error "???" + #endif + )); + } + static inline cutter_power_t power_to_range(const cutter_power_t pwr, const uint8_t pwrUnit) { + if (pwr <= 0) return 0; + cutter_power_t upwr; + switch (pwrUnit) { + case 0: // PWM + upwr = cutter_power_t( + (pwr < pct_to_ocr(min_pct)) ? pct_to_ocr(min_pct) // Use minimum if set below + : (pwr > pct_to_ocr(max_pct)) ? pct_to_ocr(max_pct) // Use maximum if set above + : pwr + ); + break; + case 1: // PERCENT + upwr = cutter_power_t( + (pwr < min_pct) ? min_pct // Use minimum if set below + : (pwr > max_pct) ? max_pct // Use maximum if set above + : pwr // PCT + ); + break; + case 2: // RPM + upwr = cutter_power_t( + (pwr < SPEED_POWER_MIN) ? SPEED_POWER_MIN // Use minimum if set below + : (pwr > SPEED_POWER_MAX) ? SPEED_POWER_MAX // Use maximum if set above + : pwr // Calculate OCR value + ); + break; + default: break; + } + return upwr; + } + + #endif // SPINDLE_LASER_PWM + + static inline void set_enabled(const bool enable) { + set_power(enable ? TERN(SPINDLE_LASER_PWM, (power ?: (unitPower ? upower_to_ocr(cpwr_to_upwr(SPEED_POWER_STARTUP)) : 0)), 255) : 0); + } // Wait for spindle to spin up or spin down - static inline void power_delay() { - #if SPINDLE_LASER_POWERUP_DELAY || SPINDLE_LASER_POWERDOWN_DELAY - safe_delay(enabled() ? SPINDLE_LASER_POWERUP_DELAY : SPINDLE_LASER_POWERDOWN_DELAY); + static inline void power_delay(const bool on) { + #if DISABLED(LASER_POWER_INLINE) + safe_delay(on ? SPINDLE_LASER_POWERUP_DELAY : SPINDLE_LASER_POWERDOWN_DELAY); #endif } @@ -86,10 +190,93 @@ class SpindleLaser { static inline void set_direction(const bool) {} #endif - static inline void disable() { set_enabled(false); } - static inline void enable_forward() { set_direction(false); set_enabled(true); } - static inline void enable_reverse() { set_direction(true); set_enabled(true); } + static inline void disable() { isReady = false; set_enabled(false); } + + #if HAS_LCD_MENU + + static inline void enable_with_dir(const bool reverse) { + isReady = true; + const uint8_t ocr = TERN(SPINDLE_LASER_PWM, upower_to_ocr(menuPower), 255); + if (menuPower) + power = ocr; + else + menuPower = cpwr_to_upwr(SPEED_POWER_STARTUP); + unitPower = menuPower; + set_direction(reverse); + set_enabled(true); + } + FORCE_INLINE static void enable_forward() { enable_with_dir(false); } + FORCE_INLINE static void enable_reverse() { enable_with_dir(true); } + + #if ENABLED(SPINDLE_LASER_PWM) + static inline void update_from_mpower() { + if (isReady) power = upower_to_ocr(menuPower); + unitPower = menuPower; + } + #endif + + #endif + + #if ENABLED(LASER_POWER_INLINE) + /** + * Inline power adds extra fields to the planner block + * to handle laser power and scale to movement speed. + */ + + // Force disengage planner power control + static inline void inline_disable() { + isReady = false; + unitPower = 0; + planner.laser_inline.status.isPlanned = false; + planner.laser_inline.status.isEnabled = false; + planner.laser_inline.power = 0; + } + + // Inline modes of all other functions; all enable planner inline power control + static inline void set_inline_enabled(const bool enable) { + if (enable) + inline_power(cpwr_to_upwr(SPEED_POWER_STARTUP)); + else { + isReady = false; + unitPower = menuPower = 0; + planner.laser_inline.status.isPlanned = false; + TERN(SPINDLE_LASER_PWM, inline_ocr_power, inline_power)(0); + } + } + + // Set the power for subsequent movement blocks + static void inline_power(const cutter_power_t upwr) { + unitPower = menuPower = upwr; + #if ENABLED(SPINDLE_LASER_PWM) + #if ENABLED(SPEED_POWER_RELATIVE) && !CUTTER_UNIT_IS(RPM) // relative mode does not turn laser off at 0, except for RPM + planner.laser_inline.status.isEnabled = true; + planner.laser_inline.power = upower_to_ocr(upwr); + isReady = true; + #else + inline_ocr_power(upower_to_ocr(upwr)); + #endif + #else + planner.laser_inline.status.isEnabled = enabled(upwr); + planner.laser_inline.power = upwr; + isReady = enabled(upwr); + #endif + } + static inline void inline_direction(const bool) { /* never */ } + + #if ENABLED(SPINDLE_LASER_PWM) + static inline void inline_ocr_power(const uint8_t ocrpwr) { + isReady = ocrpwr > 0; + planner.laser_inline.status.isEnabled = ocrpwr > 0; + planner.laser_inline.power = ocrpwr; + } + #endif + #endif // LASER_POWER_INLINE + + static inline void kill() { + TERN_(LASER_POWER_INLINE, inline_disable()); + disable(); + } }; extern SpindleLaser cutter; diff --git a/Marlin/src/feature/spindle_laser_types.h b/Marlin/src/feature/spindle_laser_types.h new file mode 100644 index 000000000000..181c4d73ac07 --- /dev/null +++ b/Marlin/src/feature/spindle_laser_types.h @@ -0,0 +1,53 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * feature/spindle_laser_types.h + * Support for Laser Power or Spindle Power & Direction + */ + +#include "../inc/MarlinConfigPre.h" + +#if ENABLED(SPINDLE_FEATURE) + #define _MSG_CUTTER(M) MSG_SPINDLE_##M +#else + #define _MSG_CUTTER(M) MSG_LASER_##M +#endif +#define MSG_CUTTER(M) _MSG_CUTTER(M) + +typedef IF<(SPEED_POWER_MAX > 255), uint16_t, uint8_t>::type cutter_cpower_t; + +#if CUTTER_UNIT_IS(RPM) && SPEED_POWER_MAX > 255 + typedef uint16_t cutter_power_t; + #define CUTTER_MENU_POWER_TYPE uint16_5 + #define cutter_power2str ui16tostr5rj +#else + typedef uint8_t cutter_power_t; + #define CUTTER_MENU_POWER_TYPE uint8 + #define cutter_power2str ui8tostr3rj +#endif + +#if ENABLED(MARLIN_DEV_MODE) + typedef uint16_t cutter_frequency_t; + #define CUTTER_MENU_FREQUENCY_TYPE uint16_5 +#endif diff --git a/Marlin/src/feature/tmc_util.cpp b/Marlin/src/feature/tmc_util.cpp index a2723fd3935b..781253079ed5 100644 --- a/Marlin/src/feature/tmc_util.cpp +++ b/Marlin/src/feature/tmc_util.cpp @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #include "../inc/MarlinConfig.h" -#if HAS_TRINAMIC +#if HAS_TRINAMIC_CONFIG #include "tmc_util.h" #include "../MarlinCore.h" @@ -34,7 +34,7 @@ #if ENABLED(TMC_DEBUG) #include "../module/planner.h" - #include "../libs/hex_print_routines.h" + #include "../libs/hex_print.h" #if ENABLED(MONITOR_DRIVER_STATUS) static uint16_t report_tmc_status_interval; // = 0 #endif @@ -63,9 +63,9 @@ , is_stall:1 , is_stealth:1 , is_standstill:1 - #if HAS_STALLGUARD - , sg_result_reasonable:1 - #endif + #if HAS_STALLGUARD + , sg_result_reasonable:1 + #endif #endif ; #if ENABLED(TMC_DEBUG) @@ -169,9 +169,7 @@ data.is_stealth = TEST(ds, STEALTH_bp); data.is_standstill = TEST(ds, STST_bp); #endif - #if HAS_STALLGUARD - data.sg_result_reasonable = false; - #endif + TERN_(HAS_STALLGUARD, data.sg_result_reasonable = false); #endif return data; } @@ -213,9 +211,7 @@ SERIAL_PRINTLN(data.drv_status, HEX); if (data.is_ot) SERIAL_ECHOLNPGM("overtemperature"); if (data.is_s2g) SERIAL_ECHOLNPGM("coil short circuit"); - #if ENABLED(TMC_DEBUG) - tmc_report_all(true, true, true, true); - #endif + TERN_(TMC_DEBUG, tmc_report_all(true, true, true, true)); kill(PSTR("Driver error")); } #endif @@ -446,9 +442,7 @@ (void)monitor_tmc_driver(stepperE7, need_update_error_counters, need_debug_reporting); #endif - #if ENABLED(TMC_DEBUG) - if (need_debug_reporting) SERIAL_EOL(); - #endif + if (TERN0(TMC_DEBUG, need_debug_reporting)) SERIAL_EOL(); } } @@ -486,6 +480,10 @@ TMC_GLOBAL_SCALER, TMC_CS_ACTUAL, TMC_PWM_SCALE, + TMC_PWM_SCALE_SUM, + TMC_PWM_SCALE_AUTO, + TMC_PWM_OFS_AUTO, + TMC_PWM_GRAD_AUTO, TMC_VSENSE, TMC_STEALTHCHOP, TMC_MICROSTEPS, @@ -498,7 +496,8 @@ TMC_TBL, TMC_HEND, TMC_HSTRT, - TMC_SGT + TMC_SGT, + TMC_MSCNT }; enum TMC_drv_status_enum : char { TMC_DRV_CODES, @@ -597,7 +596,10 @@ #if HAS_TMC220x static void _tmc_status(TMC2208Stepper &st, const TMC_debug_enum i) { switch (i) { - case TMC_PWM_SCALE: SERIAL_PRINT(st.pwm_scale_sum(), DEC); break; + case TMC_PWM_SCALE_SUM: SERIAL_PRINT(st.pwm_scale_sum(), DEC); break; + case TMC_PWM_SCALE_AUTO: SERIAL_PRINT(st.pwm_scale_auto(), DEC); break; + case TMC_PWM_OFS_AUTO: SERIAL_PRINT(st.pwm_ofs_auto(), DEC); break; + case TMC_PWM_GRAD_AUTO: SERIAL_PRINT(st.pwm_grad_auto(), DEC); break; case TMC_STEALTHCHOP: serialprint_truefalse(st.stealth()); break; case TMC_S2VSA: if (st.s2vsa()) SERIAL_CHAR('*'); break; case TMC_S2VSB: if (st.s2vsb()) SERIAL_CHAR('*'); break; @@ -686,6 +688,7 @@ case TMC_TBL: SERIAL_PRINT(st.blank_time(), DEC); break; case TMC_HEND: SERIAL_PRINT(st.hysteresis_end(), DEC); break; case TMC_HSTRT: SERIAL_PRINT(st.hysteresis_start(), DEC); break; + case TMC_MSCNT: SERIAL_PRINT(st.get_microstep_counter(), DEC); break; default: _tmc_status(st, i); break; } } @@ -906,11 +909,20 @@ #if ENABLED(MONITOR_DRIVER_STATUS) TMC_REPORT("triggered\n OTP\t", TMC_OTPW_TRIGGERED); #endif + + #if HAS_TMC220x + TMC_REPORT("pwm scale sum", TMC_PWM_SCALE_SUM); + TMC_REPORT("pwm scale auto", TMC_PWM_SCALE_AUTO); + TMC_REPORT("pwm offset auto", TMC_PWM_OFS_AUTO); + TMC_REPORT("pwm grad auto", TMC_PWM_GRAD_AUTO); + #endif + TMC_REPORT("off time", TMC_TOFF); TMC_REPORT("blank time", TMC_TBL); TMC_REPORT("hysteresis\n -end\t", TMC_HEND); TMC_REPORT(" -start\t", TMC_HSTRT); TMC_REPORT("Stallguard thrs", TMC_SGT); + TMC_REPORT("uStep count", TMC_MSCNT); DRV_REPORT("DRVSTATUS", TMC_DRV_CODES); #if HAS_TMCX1X0 || HAS_TMC220x DRV_REPORT("sg_result", TMC_SG_RESULT); @@ -954,7 +966,7 @@ static void tmc_get_ic_registers(TMC2208Stepper, const TMC_get_registers_enum) { SERIAL_CHAR('\t'); } #endif - #if HAS_TRINAMIC + #if HAS_TRINAMIC_CONFIG template static void tmc_get_registers(TMC &st, const TMC_get_registers_enum i) { switch (i) { @@ -1254,7 +1266,7 @@ void test_tmc_connection(const bool test_x, const bool test_y, const bool test_z #endif } - if (axis_connection) ui.set_status_P(GET_TEXT(MSG_ERROR_TMC)); + if (axis_connection) LCD_MESSAGEPGM(MSG_ERROR_TMC); } -#endif // HAS_TRINAMIC +#endif // HAS_TRINAMIC_CONFIG diff --git a/Marlin/src/feature/tmc_util.h b/Marlin/src/feature/tmc_util.h index 5102a9d5bfa0..b65a1254c656 100644 --- a/Marlin/src/feature/tmc_util.h +++ b/Marlin/src/feature/tmc_util.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -24,7 +24,7 @@ #include "../inc/MarlinConfig.h" #include "../lcd/ultralcd.h" -#if HAS_TRINAMIC +#if HAS_TRINAMIC_CONFIG #include #include "../module/planner.h" @@ -35,9 +35,10 @@ #define CHOPPER_DEFAULT_36V { 5, 2, 4 } #define CHOPPER_PRUSAMK3_24V { 3, -2, 6 } #define CHOPPER_MARLIN_119 { 5, 2, 3 } +#define CHOPPER_09STEP_24V { 3, -1, 5 } #if ENABLED(MONITOR_DRIVER_STATUS) && !defined(MONITOR_DRIVER_STATUS_INTERVAL_MS) - #define MONITOR_DRIVER_STATUS_INTERVAL_MS 500u + #define MONITOR_DRIVER_STATUS_INTERVAL_MS 500U #endif constexpr uint16_t _tmc_thrs(const uint16_t msteps, const uint32_t thrs, const uint32_t spmm) { @@ -69,15 +70,9 @@ class TMCStorage { } struct { - #if HAS_STEALTHCHOP - bool stealthChop_enabled = false; - #endif - #if ENABLED(HYBRID_THRESHOLD) - uint8_t hybrid_thrs = 0; - #endif - #if USE_SENSORLESS - int16_t homing_thrs = 0; - #endif + TERN_(HAS_STEALTHCHOP, bool stealthChop_enabled = false); + TERN_(HYBRID_THRESHOLD, uint8_t hybrid_thrs = 0); + TERN_(USE_SENSORLESS, int16_t homing_thrs = 0); } stored; }; @@ -105,10 +100,12 @@ class TMCMarlin : public TMC, public TMCStorage { this->val_mA = mA; TMC::rms_current(mA, mult); } + inline uint16_t get_microstep_counter() { return TMC::MSCNT(); } #if HAS_STEALTHCHOP inline void refresh_stepping_mode() { this->en_pwm_mode(this->stored.stealthChop_enabled); } inline bool get_stealthChop_status() { return this->en_pwm_mode(); } + inline bool get_stored_stealthChop_status() { return this->stored.stealthChop_enabled; } #endif #if ENABLED(HYBRID_THRESHOLD) @@ -117,9 +114,7 @@ class TMCMarlin : public TMC, public TMCStorage { } void set_pwm_thrs(const uint32_t thrs) { TMC::TPWMTHRS(_tmc_thrs(this->microsteps(), thrs, planner.settings.axis_steps_per_mm[AXIS_ID])); - #if HAS_LCD_MENU - this->stored.hybrid_thrs = thrs; - #endif + TERN_(HAS_LCD_MENU, this->stored.hybrid_thrs = thrs); } #endif @@ -128,9 +123,7 @@ class TMCMarlin : public TMC, public TMCStorage { void homing_threshold(int16_t sgt_val) { sgt_val = (int16_t)constrain(sgt_val, sgt_min, sgt_max); TMC::sgt(sgt_val); - #if HAS_LCD_MENU - this->stored.homing_thrs = sgt_val; - #endif + TERN_(HAS_LCD_MENU, this->stored.homing_thrs = sgt_val); } #if ENABLED(SPI_ENDSTOPS) bool test_stall_status(); @@ -158,9 +151,13 @@ class TMCMarlin : public TMC220 TMCMarlin(Stream * SerialPort, const float RS, const uint8_t) : TMC2208Stepper(SerialPort, RS) {} - TMCMarlin(const uint16_t RX, const uint16_t TX, const float RS, const uint8_t, const bool has_rx=true) : - TMC2208Stepper(RX, TX, RS, has_rx) + TMCMarlin(Stream * SerialPort, const float RS, uint8_t addr, const uint16_t mul_pin1, const uint16_t mul_pin2) : + TMC2208Stepper(SerialPort, RS, addr, mul_pin1, mul_pin2) + {} + TMCMarlin(const uint16_t RX, const uint16_t TX, const float RS, const uint8_t) : + TMC2208Stepper(RX, TX, RS) {} + uint16_t rms_current() { return TMC2208Stepper::rms_current(); } inline void rms_current(const uint16_t mA) { this->val_mA = mA; @@ -170,10 +167,12 @@ class TMCMarlin : public TMC220 this->val_mA = mA; TMC2208Stepper::rms_current(mA, mult); } + inline uint16_t get_microstep_counter() { return TMC2208Stepper::MSCNT(); } #if HAS_STEALTHCHOP inline void refresh_stepping_mode() { en_spreadCycle(!this->stored.stealthChop_enabled); } inline bool get_stealthChop_status() { return !this->en_spreadCycle(); } + inline bool get_stored_stealthChop_status() { return this->stored.stealthChop_enabled; } #endif #if ENABLED(HYBRID_THRESHOLD) @@ -182,9 +181,7 @@ class TMCMarlin : public TMC220 } void set_pwm_thrs(const uint32_t thrs) { TMC2208Stepper::TPWMTHRS(_tmc_thrs(this->microsteps(), thrs, planner.settings.axis_steps_per_mm[AXIS_ID])); - #if HAS_LCD_MENU - this->stored.hybrid_thrs = thrs; - #endif + TERN_(HAS_LCD_MENU, this->stored.hybrid_thrs = thrs); } #endif @@ -203,7 +200,7 @@ class TMCMarlin : public TMC220 TMCMarlin(Stream * SerialPort, const float RS, const uint8_t addr) : TMC2209Stepper(SerialPort, RS, addr) {} - TMCMarlin(const uint16_t RX, const uint16_t TX, const float RS, const uint8_t addr, const bool) : + TMCMarlin(const uint16_t RX, const uint16_t TX, const float RS, const uint8_t addr) : TMC2209Stepper(RX, TX, RS, addr) {} uint8_t get_address() { return slave_address; } @@ -216,10 +213,12 @@ class TMCMarlin : public TMC220 this->val_mA = mA; TMC2209Stepper::rms_current(mA, mult); } + inline uint16_t get_microstep_counter() { return TMC2209Stepper::MSCNT(); } #if HAS_STEALTHCHOP inline void refresh_stepping_mode() { en_spreadCycle(!this->stored.stealthChop_enabled); } inline bool get_stealthChop_status() { return !this->en_spreadCycle(); } + inline bool get_stored_stealthChop_status() { return this->stored.stealthChop_enabled; } #endif #if ENABLED(HYBRID_THRESHOLD) @@ -228,9 +227,7 @@ class TMCMarlin : public TMC220 } void set_pwm_thrs(const uint32_t thrs) { TMC2209Stepper::TPWMTHRS(_tmc_thrs(this->microsteps(), thrs, planner.settings.axis_steps_per_mm[AXIS_ID])); - #if HAS_LCD_MENU - this->stored.hybrid_thrs = thrs; - #endif + TERN_(HAS_LCD_MENU, this->stored.hybrid_thrs = thrs); } #endif #if USE_SENSORLESS @@ -238,9 +235,7 @@ class TMCMarlin : public TMC220 void homing_threshold(int16_t sgt_val) { sgt_val = (int16_t)constrain(sgt_val, sgt_min, sgt_max); TMC2209Stepper::SGTHRS(sgt_val); - #if HAS_LCD_MENU - this->stored.homing_thrs = sgt_val; - #endif + TERN_(HAS_LCD_MENU, this->stored.homing_thrs = sgt_val); } #endif @@ -273,15 +268,14 @@ class TMCMarlin : public TMC266 this->val_mA = mA; TMC2660Stepper::rms_current(mA); } + inline uint16_t get_microstep_counter() { return TMC2660Stepper::mstep(); } #if USE_SENSORLESS inline int16_t homing_threshold() { return TMC2660Stepper::sgt(); } void homing_threshold(int16_t sgt_val) { sgt_val = (int16_t)constrain(sgt_val, sgt_min, sgt_max); TMC2660Stepper::sgt(sgt_val); - #if HAS_LCD_MENU - this->stored.homing_thrs = sgt_val; - #endif + TERN_(HAS_LCD_MENU, this->stored.homing_thrs = sgt_val); } #endif @@ -363,9 +357,7 @@ void test_tmc_connection(const bool test_x, const bool test_y, const bool test_z struct slow_homing_t { xy_ulong_t acceleration; - #if HAS_CLASSIC_JERK - xy_float_t jerk_xy; - #endif + TERN_(HAS_CLASSIC_JERK, xy_float_t jerk_xy); }; #endif @@ -400,4 +392,4 @@ void test_tmc_connection(const bool test_x, const bool test_y, const bool test_z void tmc_init_cs_pins(); #endif -#endif // HAS_TRINAMIC +#endif // HAS_TRINAMIC_CONFIG diff --git a/Marlin/src/feature/touch/xpt2046.cpp b/Marlin/src/feature/touch/xpt2046.cpp deleted file mode 100644 index 26e25950d869..000000000000 --- a/Marlin/src/feature/touch/xpt2046.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfigPre.h" - -#if ENABLED(TOUCH_BUTTONS) - -#include "xpt2046.h" -#include "../../inc/MarlinConfig.h" - -#ifndef TOUCH_INT_PIN - #define TOUCH_INT_PIN -1 -#endif -#ifndef TOUCH_MISO_PIN - #define TOUCH_MISO_PIN MISO_PIN -#endif -#ifndef TOUCH_MOSI_PIN - #define TOUCH_MOSI_PIN MOSI_PIN -#endif -#ifndef TOUCH_SCK_PIN - #define TOUCH_SCK_PIN SCK_PIN -#endif -#ifndef TOUCH_CS_PIN - #define TOUCH_CS_PIN CS_PIN -#endif - -XPT2046 touch; -extern int8_t encoderDiff; - -void XPT2046::init() { - SET_INPUT(TOUCH_MISO_PIN); - SET_OUTPUT(TOUCH_MOSI_PIN); - SET_OUTPUT(TOUCH_SCK_PIN); - OUT_WRITE(TOUCH_CS_PIN, HIGH); - - #if PIN_EXISTS(TOUCH_INT) - // Optional Pendrive interrupt pin - SET_INPUT(TOUCH_INT_PIN); - #endif - - // Read once to enable pendrive status pin - getInTouch(XPT2046_X); -} - -#include "../../lcd/ultralcd.h" // For EN_C bit mask - -uint8_t XPT2046::read_buttons() { - int16_t tsoffsets[4] = { 0 }; - - if (tsoffsets[0] + tsoffsets[1] == 0) { - // Not yet set, so use defines as fallback... - tsoffsets[0] = XPT2046_X_CALIBRATION; - tsoffsets[1] = XPT2046_X_OFFSET; - tsoffsets[2] = XPT2046_Y_CALIBRATION; - tsoffsets[3] = XPT2046_Y_OFFSET; - } - - // We rely on XPT2046 compatible mode to ADS7843, hence no Z1 and Z2 measurements possible. - - if (!isTouched()) return 0; - const uint16_t x = uint16_t(((uint32_t(getInTouch(XPT2046_X))) * tsoffsets[0]) >> 16) + tsoffsets[1], - y = uint16_t(((uint32_t(getInTouch(XPT2046_Y))) * tsoffsets[2]) >> 16) + tsoffsets[3]; - if (!isTouched()) return 0; // Fingers must still be on the TS for a valid read. - - if (y < 175 || y > 234) return 0; - - return WITHIN(x, 14, 77) ? EN_D - : WITHIN(x, 90, 153) ? EN_A - : WITHIN(x, 166, 229) ? EN_B - : WITHIN(x, 242, 305) ? EN_C - : 0; -} - -bool XPT2046::isTouched() { - return ( - #if PIN_EXISTS(TOUCH_INT) - READ(TOUCH_INT_PIN) != HIGH - #else - getInTouch(XPT2046_Z1) >= XPT2046_Z1_THRESHOLD - #endif - ); -} - -uint16_t XPT2046::getInTouch(const XPTCoordinate coordinate) { - uint16_t data[3]; - - OUT_WRITE(TOUCH_CS_PIN, LOW); - - const uint8_t coord = uint8_t(coordinate) | XPT2046_CONTROL | XPT2046_DFR_MODE; - for (uint16_t i = 0; i < 3 ; i++) { - for (uint8_t j = 0x80; j; j >>= 1) { - WRITE(TOUCH_SCK_PIN, LOW); - WRITE(TOUCH_MOSI_PIN, bool(coord & j)); - WRITE(TOUCH_SCK_PIN, HIGH); - } - - data[i] = 0; - for (uint16_t j = 0x8000; j; j >>= 1) { - WRITE(TOUCH_SCK_PIN, LOW); - if (READ(TOUCH_MISO_PIN)) data[i] |= j; - WRITE(TOUCH_SCK_PIN, HIGH); - } - WRITE(TOUCH_SCK_PIN, LOW); - data[i] >>= 4; - } - - WRITE(TOUCH_CS_PIN, HIGH); - - uint16_t delta01 = _MAX(data[0], data[1]) - _MIN(data[0], data[1]), - delta02 = _MAX(data[0], data[2]) - _MIN(data[0], data[2]), - delta12 = _MAX(data[1], data[2]) - _MIN(data[1], data[2]); - - if (delta01 <= delta02 && delta01 <= delta12) - return (data[0] + data[1]) >> 1; - - if (delta02 <= delta12) - return (data[0] + data[2]) >> 1; - - return (data[1] + data[2]) >> 1; -} - -bool XPT2046::getTouchPoint(uint16_t &x, uint16_t &y) { - if (isTouched()) { - x = getInTouch(XPT2046_X); - y = getInTouch(XPT2046_Y); - } - return isTouched(); -} - -#endif // TOUCH_BUTTONS diff --git a/Marlin/src/feature/touch/xpt2046.h b/Marlin/src/feature/touch/xpt2046.h deleted file mode 100644 index 7f8eece1f497..000000000000 --- a/Marlin/src/feature/touch/xpt2046.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -// Relies on XPT2046-compatible mode of ADS7843, -// hence no Z1 / Z2 measurements are possible. - -#define XPT2046_DFR_MODE 0x00 -#define XPT2046_SER_MODE 0x04 -#define XPT2046_CONTROL 0x80 - -enum XPTCoordinate : uint8_t { - XPT2046_X = 0x10, - XPT2046_Y = 0x50, - XPT2046_Z1 = 0x30, - XPT2046_Z2 = 0x40 -}; - -#ifndef XPT2046_Z1_THRESHOLD - #define XPT2046_Z1_THRESHOLD 10 -#endif - -class XPT2046 { -public: - static void init(); - static uint8_t read_buttons(); - bool getTouchPoint(uint16_t &x, uint16_t &y); - static bool isTouched(); - inline void waitForRelease() { while (isTouched()) { /* nada */ } } - inline void waitForTouch(uint16_t &x, uint16_t &y) { while (!getTouchPoint(x, y)) { /* nada */ } } -private: - static uint16_t getInTouch(const XPTCoordinate coordinate); -}; - -extern XPT2046 touch; diff --git a/Marlin/src/feature/twibus.cpp b/Marlin/src/feature/twibus.cpp index f0687b34b318..3cc20579ac57 100644 --- a/Marlin/src/feature/twibus.cpp +++ b/Marlin/src/feature/twibus.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -49,37 +49,27 @@ void TWIBus::address(const uint8_t adr) { addr = adr; - #if ENABLED(DEBUG_TWIBUS) - debug(PSTR("address"), adr); - #endif + debug(PSTR("address"), adr); } void TWIBus::addbyte(const char c) { if (buffer_s >= COUNT(buffer)) return; buffer[buffer_s++] = c; - #if ENABLED(DEBUG_TWIBUS) - debug(PSTR("addbyte"), c); - #endif + debug(PSTR("addbyte"), c); } void TWIBus::addbytes(char src[], uint8_t bytes) { - #if ENABLED(DEBUG_TWIBUS) - debug(PSTR("addbytes"), bytes); - #endif + debug(PSTR("addbytes"), bytes); while (bytes--) addbyte(*src++); } void TWIBus::addstring(char str[]) { - #if ENABLED(DEBUG_TWIBUS) - debug(PSTR("addstring"), str); - #endif + debug(PSTR("addstring"), str); while (char c = *str++) addbyte(c); } void TWIBus::send() { - #if ENABLED(DEBUG_TWIBUS) - debug(PSTR("send"), addr); - #endif + debug(PSTR("send"), addr); Wire.beginTransmission(I2C_ADDRESS(addr)); Wire.write(buffer, buffer_s); @@ -89,37 +79,33 @@ void TWIBus::send() { } // static -void TWIBus::echoprefix(uint8_t bytes, const char prefix[], uint8_t adr) { +void TWIBus::echoprefix(uint8_t bytes, const char pref[], uint8_t adr) { SERIAL_ECHO_START(); - serialprintPGM(prefix); + serialprintPGM(pref); SERIAL_ECHOPAIR(": from:", adr, " bytes:", bytes, " data:"); } // static -void TWIBus::echodata(uint8_t bytes, const char prefix[], uint8_t adr) { - echoprefix(bytes, prefix, adr); +void TWIBus::echodata(uint8_t bytes, const char pref[], uint8_t adr) { + echoprefix(bytes, pref, adr); while (bytes-- && Wire.available()) SERIAL_CHAR(Wire.read()); SERIAL_EOL(); } -void TWIBus::echobuffer(const char prefix[], uint8_t adr) { - echoprefix(buffer_s, prefix, adr); - for (uint8_t i = 0; i < buffer_s; i++) SERIAL_CHAR(buffer[i]); +void TWIBus::echobuffer(const char pref[], uint8_t adr) { + echoprefix(buffer_s, pref, adr); + LOOP_L_N(i, buffer_s) SERIAL_CHAR(buffer[i]); SERIAL_EOL(); } bool TWIBus::request(const uint8_t bytes) { if (!addr) return false; - #if ENABLED(DEBUG_TWIBUS) - debug(PSTR("request"), bytes); - #endif + debug(PSTR("request"), bytes); // requestFrom() is a blocking function - if (Wire.requestFrom(addr, bytes) == 0) { - #if ENABLED(DEBUG_TWIBUS) - debug("request fail", addr); - #endif + if (Wire.requestFrom(I2C_ADDRESS(addr), bytes) == 0) { + debug("request fail", I2C_ADDRESS(addr)); return false; } @@ -127,9 +113,7 @@ bool TWIBus::request(const uint8_t bytes) { } void TWIBus::relay(const uint8_t bytes) { - #if ENABLED(DEBUG_TWIBUS) - debug(PSTR("relay"), bytes); - #endif + debug(PSTR("relay"), bytes); if (request(bytes)) echodata(bytes, PSTR("i2c-reply"), addr); @@ -141,9 +125,7 @@ uint8_t TWIBus::capture(char *dst, const uint8_t bytes) { while (count < bytes && Wire.available()) dst[count++] = Wire.read(); - #if ENABLED(DEBUG_TWIBUS) - debug(PSTR("capture"), count); - #endif + debug(PSTR("capture"), count); return count; } @@ -156,16 +138,12 @@ void TWIBus::flush() { #if I2C_SLAVE_ADDRESS > 0 void TWIBus::receive(uint8_t bytes) { - #if ENABLED(DEBUG_TWIBUS) - debug(PSTR("receive"), bytes); - #endif + debug(PSTR("receive"), bytes); echodata(bytes, PSTR("i2c-receive"), 0); } void TWIBus::reply(char str[]/*=nullptr*/) { - #if ENABLED(DEBUG_TWIBUS) - debug(PSTR("reply"), str); - #endif + debug(PSTR("reply"), str); if (str) { reset(); diff --git a/Marlin/src/feature/twibus.h b/Marlin/src/feature/twibus.h index faf9eb38cf18..82aa9aa16a2a 100644 --- a/Marlin/src/feature/twibus.h +++ b/Marlin/src/feature/twibus.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -46,9 +46,8 @@ typedef void (*twiRequestFunc_t)(); * for the host to interpret. * * For more information see - * - http://marlinfw.org/docs/gcode/M260.html - * - http://marlinfw.org/docs/gcode/M261.html - * + * - https://marlinfw.org/docs/gcode/M260.html + * - https://marlinfw.org/docs/gcode/M261.html */ class TWIBus { private: @@ -223,7 +222,6 @@ class TWIBus { #endif #if ENABLED(DEBUG_TWIBUS) - /** * @brief Prints a debug message * @details Prints a simple debug message "TWIBus::function: value" @@ -233,6 +231,10 @@ class TWIBus { static void debug(const char func[], char c); static void debug(const char func[], char adr[]); static inline void debug(const char func[], uint8_t v) { debug(func, (uint32_t)v); } - + #else + static inline void debug(const char[], uint32_t) {} + static inline void debug(const char[], char) {} + static inline void debug(const char[], char[]) {} + static inline void debug(const char[], uint8_t) {} #endif }; diff --git a/Marlin/src/feature/z_stepper_align.cpp b/Marlin/src/feature/z_stepper_align.cpp index 6fccff7cc917..87b1f6f25163 100644 --- a/Marlin/src/feature/z_stepper_align.cpp +++ b/Marlin/src/feature/z_stepper_align.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -56,10 +56,10 @@ void ZStepperAlign::reset_to_default() { constexpr xyz_pos_t dpo = NOZZLE_TO_PROBE_OFFSET; - #define LTEST(N) (xy_init[N].x >= _MAX(X_MIN_BED + MIN_PROBE_EDGE_LEFT, X_MIN_POS + dpo.x) - 0.00001f) - #define RTEST(N) (xy_init[N].x <= _MIN(X_MAX_BED - MIN_PROBE_EDGE_RIGHT, X_MAX_POS + dpo.x) + 0.00001f) - #define FTEST(N) (xy_init[N].y >= _MAX(Y_MIN_BED + MIN_PROBE_EDGE_FRONT, Y_MIN_POS + dpo.y) - 0.00001f) - #define BTEST(N) (xy_init[N].y <= _MIN(Y_MAX_BED - MIN_PROBE_EDGE_BACK, Y_MAX_POS + dpo.y) + 0.00001f) + #define LTEST(N) (xy_init[N].x >= _MAX(X_MIN_BED + PROBING_MARGIN_LEFT, X_MIN_POS + dpo.x) - 0.00001f) + #define RTEST(N) (xy_init[N].x <= _MIN(X_MAX_BED - PROBING_MARGIN_RIGHT, X_MAX_POS + dpo.x) + 0.00001f) + #define FTEST(N) (xy_init[N].y >= _MAX(Y_MIN_BED + PROBING_MARGIN_FRONT, Y_MIN_POS + dpo.y) - 0.00001f) + #define BTEST(N) (xy_init[N].y <= _MIN(Y_MAX_BED - PROBING_MARGIN_BACK, Y_MAX_POS + dpo.y) + 0.00001f) static_assert(LTEST(0) && RTEST(0), "The 1st Z_STEPPER_ALIGN_XY X is unreachable with the default probe X offset."); static_assert(FTEST(0) && BTEST(0), "The 1st Z_STEPPER_ALIGN_XY Y is unreachable with the default probe Y offset."); diff --git a/Marlin/src/feature/z_stepper_align.h b/Marlin/src/feature/z_stepper_align.h index ade3d6b575e2..e1b235b52cb3 100644 --- a/Marlin/src/feature/z_stepper_align.h +++ b/Marlin/src/feature/z_stepper_align.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/gcode/bedlevel/G26.cpp b/Marlin/src/gcode/bedlevel/G26.cpp index b8ec262693f6..661128b04ebe 100644 --- a/Marlin/src/gcode/bedlevel/G26.cpp +++ b/Marlin/src/gcode/bedlevel/G26.cpp @@ -16,58 +16,10 @@ * 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 . + * along with this program. If not, see . * */ -/** - * Marlin Firmware -- G26 - Mesh Validation Tool - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(G26_MESH_VALIDATION) - -#define G26_OK false -#define G26_ERR true - -#include "../../gcode/gcode.h" -#include "../../feature/bedlevel/bedlevel.h" - -#include "../../MarlinCore.h" -#include "../../module/planner.h" -#include "../../module/stepper.h" -#include "../../module/motion.h" -#include "../../module/tool_change.h" -#include "../../module/temperature.h" -#include "../../lcd/ultralcd.h" - -#define EXTRUSION_MULTIPLIER 1.0 -#define PRIME_LENGTH 10.0 -#define OOZE_AMOUNT 0.3 - -#define INTERSECTION_CIRCLE_RADIUS 5 -#define CROSSHAIRS_SIZE 3 - -#ifndef G26_RETRACT_MULTIPLIER - #define G26_RETRACT_MULTIPLIER 1.0 // x 1mm -#endif - -#ifndef G26_XY_FEEDRATE - #define G26_XY_FEEDRATE (PLANNER_XY_FEEDRATE() / 3.0) -#endif - -#if CROSSHAIRS_SIZE >= INTERSECTION_CIRCLE_RADIUS - #error "CROSSHAIRS_SIZE must be less than INTERSECTION_CIRCLE_RADIUS." -#endif - -#define G26_OK false -#define G26_ERR true - -#if ENABLED(ARC_SUPPORT) - void plan_arc(const xyze_pos_t &cart, const ab_float_t &offset, const uint8_t clockwise); -#endif - /** * G26 Mesh Validation Tool * @@ -95,6 +47,8 @@ * * H # Hotend Set the Nozzle Temperature. If not specified, a default of 205 C. will be assumed. * + * I # Preset Heat the Nozzle and Bed based on a Material Preset (if material presets are defined). + * * F # Filament Used to specify the diameter of the filament being used. If not specified * 1.75mm filament is assumed. If you are not getting acceptable results by using the * 'correct' numbers, you can scale this number up or down a little bit to change the amount @@ -141,13 +95,54 @@ * Y # Y Coord. Specify the starting location of the drawing activity. */ -// External references +#include "../../inc/MarlinConfig.h" + +#if ENABLED(G26_MESH_VALIDATION) + +#define G26_OK false +#define G26_ERR true + +#include "../../gcode/gcode.h" +#include "../../feature/bedlevel/bedlevel.h" -// Private functions +#include "../../MarlinCore.h" +#include "../../module/planner.h" +#include "../../module/stepper.h" +#include "../../module/motion.h" +#include "../../module/tool_change.h" +#include "../../module/temperature.h" +#include "../../lcd/ultralcd.h" + +#define EXTRUSION_MULTIPLIER 1.0 +#define PRIME_LENGTH 10.0 +#define OOZE_AMOUNT 0.3 + +#define INTERSECTION_CIRCLE_RADIUS 5 +#define CROSSHAIRS_SIZE 3 + +#ifndef G26_RETRACT_MULTIPLIER + #define G26_RETRACT_MULTIPLIER 1.0 // x 1mm +#endif + +#ifndef G26_XY_FEEDRATE + #define G26_XY_FEEDRATE (PLANNER_XY_FEEDRATE() / 3.0) +#endif + +#if CROSSHAIRS_SIZE >= INTERSECTION_CIRCLE_RADIUS + #error "CROSSHAIRS_SIZE must be less than INTERSECTION_CIRCLE_RADIUS." +#endif + +#define G26_OK false +#define G26_ERR true + +#if ENABLED(ARC_SUPPORT) + void plan_arc(const xyze_pos_t &cart, const ab_float_t &offset, const uint8_t clockwise); +#endif + +constexpr float g26_e_axis_feedrate = 0.025; static MeshFlags circle_flags, horizontal_mesh_line_flags, vertical_mesh_line_flags; -float g26_e_axis_feedrate = 0.025, - random_deviation = 0.0; +float g26_random_deviation = 0.0; static bool g26_retracted = false; // Track the retracted state of the nozzle so mismatched // retracts/recovers won't result in a bad state. @@ -157,7 +152,7 @@ float g26_extrusion_multiplier, g26_layer_height, g26_prime_length; -xy_pos_t g26_pos; // = { 0, 0 } +xy_pos_t g26_xy_pos; // = { 0, 0 } int16_t g26_bed_temp, g26_hotend_temp; @@ -172,9 +167,7 @@ int8_t g26_prime_flag; bool user_canceled() { if (!ui.button_pressed()) return false; // Return if the button isn't pressed ui.set_status_P(GET_TEXT(MSG_G26_CANCELED), 99); - #if HAS_LCD_MENU - ui.quick_feedback(); - #endif + TERN_(HAS_LCD_MENU, ui.quick_feedback()); ui.wait_for_release(); return true; } @@ -187,29 +180,27 @@ mesh_index_pair find_closest_circle_to_print(const xy_pos_t &pos) { out_point.pos = -1; - for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) { - for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) { - if (!circle_flags.marked(i, j)) { - // We found a circle that needs to be printed - const xy_pos_t m = { _GET_MESH_X(i), _GET_MESH_Y(j) }; + GRID_LOOP(i, j) { + if (!circle_flags.marked(i, j)) { + // We found a circle that needs to be printed + const xy_pos_t m = { _GET_MESH_X(i), _GET_MESH_Y(j) }; - // Get the distance to this intersection - float f = (pos - m).magnitude(); + // Get the distance to this intersection + float f = (pos - m).magnitude(); - // It is possible that we are being called with the values - // to let us find the closest circle to the start position. - // But if this is not the case, add a small weighting to the - // distance calculation to help it choose a better place to continue. - f += (g26_pos - m).magnitude() / 15.0f; + // It is possible that we are being called with the values + // to let us find the closest circle to the start position. + // But if this is not the case, add a small weighting to the + // distance calculation to help it choose a better place to continue. + f += (g26_xy_pos - m).magnitude() / 15.0f; - // Add the specified amount of Random Noise to our search - if (random_deviation > 1.0) f += random(0.0, random_deviation); + // Add the specified amount of Random Noise to our search + if (g26_random_deviation > 1.0) f += random(0.0, g26_random_deviation); - if (f < closest) { - closest = f; // Found a closer un-printed location - out_point.pos.set(i, j); // Save its data - out_point.distance = closest; - } + if (f < closest) { + closest = f; // Found a closer un-printed location + out_point.pos.set(i, j); // Save its data + out_point.distance = closest; } } } @@ -308,51 +299,47 @@ inline bool look_for_lines_to_connect() { xyz_pos_t s, e; s.z = e.z = g26_layer_height; - for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) { - for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) { + GRID_LOOP(i, j) { - #if HAS_LCD_MENU - if (user_canceled()) return true; - #endif + if (TERN0(HAS_LCD_MENU, user_canceled())) return true; - if (i < GRID_MAX_POINTS_X) { // Can't connect to anything farther to the right than GRID_MAX_POINTS_X. + if (i < (GRID_MAX_POINTS_X)) { // Can't connect to anything farther to the right than GRID_MAX_POINTS_X. // Already a half circle at the edge of the bed. - if (circle_flags.marked(i, j) && circle_flags.marked(i + 1, j)) { // Test whether a leftward line can be done - if (!horizontal_mesh_line_flags.marked(i, j)) { - // Two circles need a horizontal line to connect them - s.x = _GET_MESH_X( i ) + (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)); // right edge - e.x = _GET_MESH_X(i + 1) - (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)); // left edge + if (circle_flags.marked(i, j) && circle_flags.marked(i + 1, j)) { // Test whether a leftward line can be done + if (!horizontal_mesh_line_flags.marked(i, j)) { + // Two circles need a horizontal line to connect them + s.x = _GET_MESH_X( i ) + (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)); // right edge + e.x = _GET_MESH_X(i + 1) - (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)); // left edge - LIMIT(s.x, X_MIN_POS + 1, X_MAX_POS - 1); - s.y = e.y = constrain(_GET_MESH_Y(j), Y_MIN_POS + 1, Y_MAX_POS - 1); - LIMIT(e.x, X_MIN_POS + 1, X_MAX_POS - 1); + LIMIT(s.x, X_MIN_POS + 1, X_MAX_POS - 1); + s.y = e.y = constrain(_GET_MESH_Y(j), Y_MIN_POS + 1, Y_MAX_POS - 1); + LIMIT(e.x, X_MIN_POS + 1, X_MAX_POS - 1); - if (position_is_reachable(s.x, s.y) && position_is_reachable(e.x, e.y)) - print_line_from_here_to_there(s, e); + if (position_is_reachable(s.x, s.y) && position_is_reachable(e.x, e.y)) + print_line_from_here_to_there(s, e); - horizontal_mesh_line_flags.mark(i, j); // Mark done, even if skipped - } + horizontal_mesh_line_flags.mark(i, j); // Mark done, even if skipped } + } - if (j < GRID_MAX_POINTS_Y) { // Can't connect to anything further back than GRID_MAX_POINTS_Y. + if (j < (GRID_MAX_POINTS_Y)) { // Can't connect to anything further back than GRID_MAX_POINTS_Y. // Already a half circle at the edge of the bed. - if (circle_flags.marked(i, j) && circle_flags.marked(i, j + 1)) { // Test whether a downward line can be done - if (!vertical_mesh_line_flags.marked(i, j)) { - // Two circles that need a vertical line to connect them - s.y = _GET_MESH_Y( j ) + (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)); // top edge - e.y = _GET_MESH_Y(j + 1) - (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)); // bottom edge + if (circle_flags.marked(i, j) && circle_flags.marked(i, j + 1)) { // Test whether a downward line can be done + if (!vertical_mesh_line_flags.marked(i, j)) { + // Two circles that need a vertical line to connect them + s.y = _GET_MESH_Y( j ) + (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)); // top edge + e.y = _GET_MESH_Y(j + 1) - (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)); // bottom edge - s.x = e.x = constrain(_GET_MESH_X(i), X_MIN_POS + 1, X_MAX_POS - 1); - LIMIT(s.y, Y_MIN_POS + 1, Y_MAX_POS - 1); - LIMIT(e.y, Y_MIN_POS + 1, Y_MAX_POS - 1); + s.x = e.x = constrain(_GET_MESH_X(i), X_MIN_POS + 1, X_MAX_POS - 1); + LIMIT(s.y, Y_MIN_POS + 1, Y_MAX_POS - 1); + LIMIT(e.y, Y_MIN_POS + 1, Y_MAX_POS - 1); - if (position_is_reachable(s.x, s.y) && position_is_reachable(e.x, e.y)) - print_line_from_here_to_there(s, e); + if (position_is_reachable(s.x, s.y) && position_is_reachable(e.x, e.y)) + print_line_from_here_to_there(s, e); - vertical_mesh_line_flags.mark(i, j); // Mark done, even if skipped - } + vertical_mesh_line_flags.mark(i, j); // Mark done, even if skipped } } } @@ -372,12 +359,10 @@ inline bool turn_on_heaters() { #if HAS_HEATED_BED if (g26_bed_temp > 25) { - #if HAS_SPI_LCD + #if HAS_WIRED_LCD ui.set_status_P(GET_TEXT(MSG_G26_HEATING_BED), 99); ui.quick_feedback(); - #if HAS_LCD_MENU - ui.capture(); - #endif + TERN_(HAS_LCD_MENU, ui.capture()); #endif thermalManager.setTargetBed(g26_bed_temp); @@ -393,7 +378,7 @@ inline bool turn_on_heaters() { #endif // HAS_HEATED_BED // Start heating the active nozzle - #if HAS_SPI_LCD + #if HAS_WIRED_LCD ui.set_status_P(GET_TEXT(MSG_G26_HEATING_NOZZLE), 99); ui.quick_feedback(); #endif @@ -401,13 +386,12 @@ inline bool turn_on_heaters() { // Wait for the temperature to stabilize if (!thermalManager.wait_for_hotend(active_extruder, true - #if G26_CLICK_CAN_CANCEL - , true - #endif - ) - ) return G26_ERR; + #if G26_CLICK_CAN_CANCEL + , true + #endif + )) return G26_ERR; - #if HAS_SPI_LCD + #if HAS_WIRED_LCD ui.reset_status(); ui.quick_feedback(); #endif @@ -421,7 +405,7 @@ inline bool turn_on_heaters() { inline bool prime_nozzle() { const feedRate_t fr_slow_e = planner.settings.max_feedrate_mm_s[E_AXIS] / 15.0f; - #if HAS_LCD_MENU && DISABLED(TOUCH_BUTTONS) // ui.button_pressed issue with touchscreen + #if HAS_LCD_MENU && !HAS_TOUCH_XPT2046 // ui.button_pressed issue with touchscreen #if ENABLED(PREVENT_LENGTHY_EXTRUDE) float Total_Prime = 0.0; #endif @@ -462,7 +446,7 @@ inline bool prime_nozzle() { else #endif { - #if HAS_SPI_LCD + #if HAS_WIRED_LCD ui.set_status_P(GET_TEXT(MSG_G26_FIXED_LENGTH), 99); ui.quick_feedback(); #endif @@ -506,7 +490,7 @@ void GcodeSuite::G26() { // Don't allow Mesh Validation without homing first, // or if the parameter parsing did not go OK, abort - if (axis_unhomed_error()) return; + if (homing_needed_error()) return; // Change the tool first, if specified if (parser.seenval('T')) tool_change(parser.value_int()); @@ -526,15 +510,33 @@ void GcodeSuite::G26() { bool g26_continue_with_closest = parser.boolval('C'), g26_keep_heaters_on = parser.boolval('K'); + // Accept 'I' if temperature presets are defined + #if PREHEAT_COUNT + const uint8_t preset_index = parser.seenval('I') ? _MIN(parser.value_byte(), PREHEAT_COUNT - 1) + 1 : 0; + #endif + #if HAS_HEATED_BED - if (parser.seenval('B')) { - g26_bed_temp = parser.value_celsius(); - if (g26_bed_temp && !WITHIN(g26_bed_temp, 40, (BED_MAXTEMP - 10))) { - SERIAL_ECHOLNPAIR("?Specified bed temperature not plausible (40-", int(BED_MAXTEMP - 10), "C)."); + + // Get a temperature from 'I' or 'B' + int16_t bedtemp = 0; + + // Use the 'I' index if temperature presets are defined + #if PREHEAT_COUNT + if (preset_index) bedtemp = ui.material_preset[preset_index - 1].bed_temp; + #endif + + // Look for 'B' Bed Temperature + if (parser.seenval('B')) bedtemp = parser.value_celsius(); + + if (bedtemp) { + if (!WITHIN(bedtemp, 40, BED_MAX_TARGET)) { + SERIAL_ECHOLNPAIR("?Specified bed temperature not plausible (40-", int(BED_MAX_TARGET), "C)."); return; } + g26_bed_temp = bedtemp; } - #endif + + #endif // HAS_HEATED_BED if (parser.seenval('L')) { g26_layer_height = parser.value_linear_units(); @@ -598,20 +600,34 @@ void GcodeSuite::G26() { g26_extrusion_multiplier *= g26_filament_diameter * sq(g26_nozzle) / sq(0.3); // Scale up by nozzle size - if (parser.seenval('H')) { - g26_hotend_temp = parser.value_celsius(); - if (!WITHIN(g26_hotend_temp, 165, (HEATER_0_MAXTEMP - 15))) { + // Get a temperature from 'I' or 'H' + int16_t noztemp = 0; + + // Accept 'I' if temperature presets are defined + #if PREHEAT_COUNT + if (preset_index) noztemp = ui.material_preset[preset_index - 1].hotend_temp; + #endif + + // Look for 'H' Hotend Temperature + if (parser.seenval('H')) noztemp = parser.value_celsius(); + + // If any preset or temperature was specified + if (noztemp) { + if (!WITHIN(noztemp, 165, (HEATER_0_MAXTEMP) - (HOTEND_OVERSHOOT))) { SERIAL_ECHOLNPGM("?Specified nozzle temperature not plausible."); return; } + g26_hotend_temp = noztemp; } + // 'U' to Randomize and optionally set circle deviation if (parser.seen('U')) { randomSeed(millis()); // This setting will persist for the next G26 - random_deviation = parser.has_value() ? parser.value_float() : 50.0; + g26_random_deviation = parser.has_value() ? parser.value_float() : 50.0; } + // Get repeat from 'R', otherwise do one full circuit int16_t g26_repeats; #if HAS_LCD_MENU g26_repeats = parser.intval('R', GRID_MAX_POINTS + 1); @@ -628,9 +644,10 @@ void GcodeSuite::G26() { return; } - g26_pos.set(parser.seenval('X') ? RAW_X_POSITION(parser.value_linear_units()) : current_position.x, - parser.seenval('Y') ? RAW_Y_POSITION(parser.value_linear_units()) : current_position.y); - if (!position_is_reachable(g26_pos.x, g26_pos.y)) { + // Set a position with 'X' and/or 'Y'. Default: current_position + g26_xy_pos.set(parser.seenval('X') ? RAW_X_POSITION(parser.value_linear_units()) : current_position.x, + parser.seenval('Y') ? RAW_Y_POSITION(parser.value_linear_units()) : current_position.y); + if (!position_is_reachable(g26_xy_pos)) { SERIAL_ECHOLNPGM("?Specified X,Y coordinate out of bounds."); return; } @@ -640,10 +657,7 @@ void GcodeSuite::G26() { */ set_bed_leveling_enabled(!parser.seen('D')); - if (current_position.z < Z_CLEARANCE_BETWEEN_PROBES) { - do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); - current_position = destination; - } + do_z_clearance(Z_CLEARANCE_BETWEEN_PROBES); #if DISABLED(NO_VOLUMETRICS) bool volumetric_was_enabled = parser.volumetric_enabled; @@ -678,9 +692,7 @@ void GcodeSuite::G26() { move_to(destination, 0.0); move_to(destination, g26_ooze_amount); - #if HAS_LCD_MENU - ui.capture(); - #endif + TERN_(HAS_LCD_MENU, ui.capture()); #if DISABLED(ARC_SUPPORT) @@ -697,7 +709,7 @@ void GcodeSuite::G26() { #error "A_CNT must be a positive value. Please change A_INT." #endif float trig_table[A_CNT]; - for (uint8_t i = 0; i < A_CNT; i++) + LOOP_L_N(i, A_CNT) trig_table[i] = INTERSECTION_CIRCLE_RADIUS * cos(RADIANS(i * A_INT)); #endif // !ARC_SUPPORT @@ -705,7 +717,7 @@ void GcodeSuite::G26() { mesh_index_pair location; do { // Find the nearest confluence - location = find_closest_circle_to_print(g26_continue_with_closest ? xy_pos_t(current_position) : g26_pos); + location = find_closest_circle_to_print(g26_continue_with_closest ? xy_pos_t(current_position) : g26_xy_pos); if (location.valid()) { const xy_pos_t circle = _GET_MESH_POS(location.pos); @@ -775,9 +787,7 @@ void GcodeSuite::G26() { feedrate_mm_s = old_feedrate; destination = current_position; - #if HAS_LCD_MENU - if (user_canceled()) goto LEAVE; // Check if the user wants to stop the Mesh Validation - #endif + if (TERN0(HAS_LCD_MENU, user_canceled())) goto LEAVE; // Check if the user wants to stop the Mesh Validation #else // !ARC_SUPPORT @@ -801,9 +811,7 @@ void GcodeSuite::G26() { for (int8_t ind = start_ind; ind <= end_ind; ind++) { - #if HAS_LCD_MENU - if (user_canceled()) goto LEAVE; // Check if the user wants to stop the Mesh Validation - #endif + if (TERN0(HAS_LCD_MENU, user_canceled())) goto LEAVE; // Check if the user wants to stop the Mesh Validation xyz_float_t p = { circle.x + _COS(ind ), circle.y + _SIN(ind ), g26_layer_height }, q = { circle.x + _COS(ind + 1), circle.y + _SIN(ind + 1), g26_layer_height }; @@ -836,12 +844,9 @@ void GcodeSuite::G26() { retract_filament(destination); destination.z = Z_CLEARANCE_BETWEEN_PROBES; + move_to(destination, 0); // Raise the nozzle - move_to(destination, 0); // Raise the nozzle - - destination.set(g26_pos.x, g26_pos.y); // Move back to the starting position - //destination.z = Z_CLEARANCE_BETWEEN_PROBES; // Keep the nozzle where it is - + destination = g26_xy_pos; // Move back to the starting XY position move_to(destination, 0); // Move back to the starting position #if DISABLED(NO_VOLUMETRICS) @@ -849,14 +854,10 @@ void GcodeSuite::G26() { planner.calculate_volumetric_multipliers(); #endif - #if HAS_LCD_MENU - ui.release(); // Give back control of the LCD - #endif + TERN_(HAS_LCD_MENU, ui.release()); // Give back control of the LCD if (!g26_keep_heaters_on) { - #if HAS_HEATED_BED - thermalManager.setTargetBed(0); - #endif + TERN_(HAS_HEATED_BED, thermalManager.setTargetBed(0)); thermalManager.setTargetHotend(active_extruder, 0); } } diff --git a/Marlin/src/gcode/bedlevel/G35.cpp b/Marlin/src/gcode/bedlevel/G35.cpp new file mode 100755 index 000000000000..0ede4e79c680 --- /dev/null +++ b/Marlin/src/gcode/bedlevel/G35.cpp @@ -0,0 +1,190 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(ASSISTED_TRAMMING) + +#include "../gcode.h" +#include "../../module/planner.h" +#include "../../module/probe.h" +#include "../../feature/bedlevel/bedlevel.h" + +#if HAS_MULTI_HOTEND + #include "../../module/tool_change.h" +#endif + +#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) +#include "../../core/debug_out.h" + +constexpr xy_pos_t screws_tilt_adjust_pos[] = TRAMMING_POINT_XY; + +static PGMSTR(point_name_1, TRAMMING_POINT_NAME_1); +static PGMSTR(point_name_2, TRAMMING_POINT_NAME_2); +static PGMSTR(point_name_3, TRAMMING_POINT_NAME_3); +#ifdef TRAMMING_POINT_NAME_4 + static PGMSTR(point_name_4, TRAMMING_POINT_NAME_4); + #ifdef TRAMMING_POINT_NAME_5 + static PGMSTR(point_name_5, TRAMMING_POINT_NAME_5); + #endif +#endif + +static PGM_P const tramming_point_name[] PROGMEM = { + point_name_1, point_name_2, point_name_3 + #ifdef TRAMMING_POINT_NAME_4 + , point_name_4 + #ifdef TRAMMING_POINT_NAME_5 + , point_name_5 + #endif + #endif +}; + +#define G35_PROBE_COUNT COUNT(screws_tilt_adjust_pos) + +#if !WITHIN(TRAMMING_SCREW_THREAD, 30, 51) || TRAMMING_SCREW_THREAD % 10 > 1 + #error "TRAMMING_SCREW_THREAD must be equal to 30, 31, 40, 41, 50, or 51." +#endif + +static_assert(G35_PROBE_COUNT > 2, "TRAMMING_POINT_XY requires at least 3 XY positions."); + +/** + * G35: Read bed corners to help adjust bed screws + * + * S + * + * Screw thread: 30 - Clockwise M3 + * 31 - Counter-Clockwise M3 + * 40 - Clockwise M4 + * 41 - Counter-Clockwise M4 + * 50 - Clockwise M5 + * 51 - Counter-Clockwise M5 + **/ +void GcodeSuite::G35() { + DEBUG_SECTION(log_G35, "G35", DEBUGGING(LEVELING)); + + if (DEBUGGING(LEVELING)) log_machine_info(); + + float z_measured[G35_PROBE_COUNT] = { 0 }; + + const uint8_t screw_thread = parser.byteval('S', TRAMMING_SCREW_THREAD); + if (!WITHIN(screw_thread, 30, 51) || screw_thread % 10 > 1) { + SERIAL_ECHOLNPGM("?(S)crew thread must be 30, 31, 40, 41, 50, or 51."); + return; + } + + // Wait for planner moves to finish! + planner.synchronize(); + + // Disable the leveling matrix before auto-aligning + #if HAS_LEVELING + TERN_(RESTORE_LEVELING_AFTER_G35, const bool leveling_was_active = planner.leveling_active); + set_bed_leveling_enabled(false); + #endif + + #if ENABLED(CNC_WORKSPACE_PLANES) + workspace_plane = PLANE_XY; + #endif + + // Always home with tool 0 active + #if HAS_MULTI_HOTEND + const uint8_t old_tool_index = active_extruder; + tool_change(0, true); + #endif + + #if HAS_DUPLICATION_MODE + extruder_duplication_enabled = false; + #endif + + // Home all before this procedure + home_all_axes(); + + bool err_break = false; + + // Probe all positions + LOOP_L_N(i, G35_PROBE_COUNT) { + + // In BLTOUCH HS mode, the probe travels in a deployed state. + // Users of G35 might have a badly misaligned bed, so raise Z by the + // length of the deployed pin (BLTOUCH stroke < 7mm) + current_position.z = (Z_CLEARANCE_BETWEEN_PROBES) + (7 * ENABLED(BLTOUCH_HS_MODE)); + + const float z_probed_height = probe.probe_at_point(screws_tilt_adjust_pos[i], PROBE_PT_RAISE, 0, true); + + if (isnan(z_probed_height)) { + SERIAL_ECHOPAIR("G35 failed at point ", int(i), " (", tramming_point_name[i], ")"); + SERIAL_ECHOLNPAIR_P(SP_X_STR, screws_tilt_adjust_pos[i].x, SP_Y_STR, screws_tilt_adjust_pos[i].y); + err_break = true; + break; + } + + if (DEBUGGING(LEVELING)) { + DEBUG_ECHOPAIR("Probing point ", int(i), " (", tramming_point_name[i], ")"); + SERIAL_ECHOLNPAIR_P(SP_X_STR, screws_tilt_adjust_pos[i].x, SP_Y_STR, screws_tilt_adjust_pos[i].y, SP_Z_STR, z_probed_height); + } + + z_measured[i] = z_probed_height; + } + + if (!err_break) { + const float threads_factor[] = { 0.5, 0.7, 0.8 }; + + // Calculate adjusts + LOOP_S_L_N(i, 1, G35_PROBE_COUNT) { + const float diff = z_measured[0] - z_measured[i], + adjust = abs(diff) < 0.001f ? 0 : diff / threads_factor[(screw_thread - 30) / 10]; + + const int full_turns = trunc(adjust); + const float decimal_part = adjust - float(full_turns); + const int minutes = trunc(decimal_part * 60.0f); + + SERIAL_ECHOPAIR("Turn ", tramming_point_name[i], + " ", (screw_thread & 1) == (adjust > 0) ? "CCW" : "CW", + " by ", abs(full_turns), " turns"); + if (minutes) SERIAL_ECHOPAIR(" and ", abs(minutes), " minutes"); + if (ENABLED(REPORT_TRAMMING_MM)) SERIAL_ECHOPAIR(" (", -diff, "mm)"); + SERIAL_EOL(); + } + } + else + SERIAL_ECHOLNPGM("G35 aborted."); + + // Restore the active tool after homing + #if HAS_MULTI_HOTEND + tool_change(old_tool_index, DISABLED(PARKING_EXTRUDER)); // Fetch previous toolhead if not PARKING_EXTRUDER + #endif + + #if BOTH(HAS_LEVELING, RESTORE_LEVELING_AFTER_G35) + set_bed_leveling_enabled(leveling_was_active); + #endif + + // Stow the probe, as the last call to probe.probe_at_point(...) left + // the probe deployed if it was successful. + probe.stow(); + + // After this operation the Z position needs correction + set_axis_never_homed(Z_AXIS); + + // Home Z after the alignment procedure + process_subcommands_now_P(PSTR("G28Z")); +} + +#endif // ASSISTED_TRAMMING diff --git a/Marlin/src/gcode/bedlevel/G42.cpp b/Marlin/src/gcode/bedlevel/G42.cpp index 139bd1bb6628..a2896ed6c705 100644 --- a/Marlin/src/gcode/bedlevel/G42.cpp +++ b/Marlin/src/gcode/bedlevel/G42.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/bedlevel/M420.cpp b/Marlin/src/gcode/bedlevel/M420.cpp index b84c60a6ae87..96122c18f882 100644 --- a/Marlin/src/gcode/bedlevel/M420.cpp +++ b/Marlin/src/gcode/bedlevel/M420.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -30,11 +30,11 @@ #include "../../module/probe.h" #if ENABLED(EEPROM_SETTINGS) - #include "../../module/configuration_store.h" + #include "../../module/settings.h" #endif #if ENABLED(EXTENSIBLE_UI) - #include "../../lcd/extensible_ui/ui_api.h" + #include "../../lcd/extui/ui_api.h" #endif //#define M420_C_USE_MEAN @@ -71,13 +71,10 @@ void GcodeSuite::M420() { bilinear_grid_spacing.set((x_max - x_min) / (GRID_MAX_POINTS_X - 1), (y_max - y_min) / (GRID_MAX_POINTS_Y - 1)); #endif - for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) - for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) { - Z_VALUES(x, y) = 0.001 * random(-200, 200); - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(x, y, Z_VALUES(x, y)); - #endif - } + GRID_LOOP(x, y) { + Z_VALUES(x, y) = 0.001 * random(-200, 200); + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, Z_VALUES(x, y))); + } SERIAL_ECHOPGM("Simulated " STRINGIFY(GRID_MAX_POINTS_X) "x" STRINGIFY(GRID_MAX_POINTS_Y) " mesh "); SERIAL_ECHOPAIR(" (", x_min); SERIAL_CHAR(','); SERIAL_ECHO(y_min); @@ -87,12 +84,12 @@ void GcodeSuite::M420() { } #endif + xyz_pos_t oldpos = current_position; + // If disabling leveling do it right away // (Don't disable for just M420 or M420 V) if (seen_S && !to_enable) set_bed_leveling_enabled(false); - xyz_pos_t oldpos = current_position; - #if ENABLED(AUTO_BED_LEVELING_UBL) // L to load a mesh from the EEPROM @@ -156,21 +153,18 @@ void GcodeSuite::M420() { // Get the sum and average of all mesh values float mesh_sum = 0; - for (uint8_t x = GRID_MAX_POINTS_X; x--;) - for (uint8_t y = GRID_MAX_POINTS_Y; y--;) - mesh_sum += Z_VALUES(x, y); + GRID_LOOP(x, y) mesh_sum += Z_VALUES(x, y); const float zmean = mesh_sum / float(GRID_MAX_POINTS); #else // Find the low and high mesh values float lo_val = 100, hi_val = -100; - for (uint8_t x = GRID_MAX_POINTS_X; x--;) - for (uint8_t y = GRID_MAX_POINTS_Y; y--;) { - const float z = Z_VALUES(x, y); - NOMORE(lo_val, z); - NOLESS(hi_val, z); - } + GRID_LOOP(x, y) { + const float z = Z_VALUES(x, y); + NOMORE(lo_val, z); + NOLESS(hi_val, z); + } // Take the mean of the lowest and highest const float zmean = (lo_val + hi_val) / 2.0 + cval; @@ -180,16 +174,11 @@ void GcodeSuite::M420() { if (!NEAR_ZERO(zmean)) { set_bed_leveling_enabled(false); // Subtract the mean from all values - for (uint8_t x = GRID_MAX_POINTS_X; x--;) - for (uint8_t y = GRID_MAX_POINTS_Y; y--;) { - Z_VALUES(x, y) -= zmean; - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(x, y, Z_VALUES(x, y)); - #endif - } - #if ENABLED(ABL_BILINEAR_SUBDIVISION) - bed_level_virt_interpolate(); - #endif + GRID_LOOP(x, y) { + Z_VALUES(x, y) -= zmean; + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, Z_VALUES(x, y))); + } + TERN_(ABL_BILINEAR_SUBDIVISION, bed_level_virt_interpolate()); } #endif @@ -211,9 +200,7 @@ void GcodeSuite::M420() { if (leveling_is_valid()) { #if ENABLED(AUTO_BED_LEVELING_BILINEAR) print_bilinear_leveling_grid(); - #if ENABLED(ABL_BILINEAR_SUBDIVISION) - print_bilinear_leveling_grid_virt(); - #endif + TERN_(ABL_BILINEAR_SUBDIVISION, print_bilinear_leveling_grid_virt()); #elif ENABLED(MESH_BED_LEVELING) SERIAL_ECHOLNPGM("Mesh Bed Level data:"); mbl.report_mesh(); diff --git a/Marlin/src/gcode/bedlevel/abl/G29.cpp b/Marlin/src/gcode/bedlevel/abl/G29.cpp index 5173505164fb..f7de6c8cee57 100644 --- a/Marlin/src/gcode/bedlevel/abl/G29.cpp +++ b/Marlin/src/gcode/bedlevel/abl/G29.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -37,7 +37,7 @@ #include "../../queue.h" #if ENABLED(PROBE_TEMP_COMPENSATION) - #include "../../../feature/probe_temp_compensation.h" + #include "../../../feature/probe_temp_comp.h" #include "../../../module/temperature.h" #endif @@ -57,10 +57,14 @@ #include "../../../core/debug_out.h" #if ENABLED(EXTENSIBLE_UI) - #include "../../../lcd/extensible_ui/ui_api.h" + #include "../../../lcd/extui/ui_api.h" #endif -#if HOTENDS > 1 +#if ENABLED(DWIN_CREALITY_LCD) + #include "../../../lcd/dwin/e3v2/dwin.h" +#endif + +#if HAS_MULTI_HOTEND #include "../../../module/tool_change.h" #endif @@ -78,11 +82,7 @@ #endif #endif -#if ENABLED(G29_RETRY_AND_RECOVER) - #define G29_RETURN(b) return b; -#else - #define G29_RETURN(b) return; -#endif +#define G29_RETURN(b) return TERN_(G29_RETRY_AND_RECOVER, b) /** * G29: Detailed Z probe, probes the bed at 3 or more points. @@ -160,59 +160,37 @@ * E By default G29 will engage the Z probe, test the bed, then disengage. * Include "E" to engage/disengage the Z probe for each sample. * There's no extra effect if you have a fixed Z probe. - * */ G29_TYPE GcodeSuite::G29() { - #if EITHER(DEBUG_LEVELING_FEATURE, PROBE_MANUALLY) - const bool seenQ = parser.seen('Q'); - #else - constexpr bool seenQ = false; - #endif + reset_stepper_timeout(); + + const bool seenQ = EITHER(DEBUG_LEVELING_FEATURE, PROBE_MANUALLY) && parser.seen('Q'); // G29 Q is also available if debugging #if ENABLED(DEBUG_LEVELING_FEATURE) const uint8_t old_debug_flags = marlin_debug_flags; if (seenQ) marlin_debug_flags |= MARLIN_DEBUG_LEVELING; - if (DEBUGGING(LEVELING)) { - DEBUG_POS(">>> G29", current_position); - log_machine_info(); - } + DEBUG_SECTION(log_G29, "G29", DEBUGGING(LEVELING)); + if (DEBUGGING(LEVELING)) log_machine_info(); marlin_debug_flags = old_debug_flags; - #if DISABLED(PROBE_MANUALLY) - if (seenQ) G29_RETURN(false); - #endif - #endif - - #if ENABLED(PROBE_MANUALLY) - const bool seenA = parser.seen('A'); - #else - constexpr bool seenA = false; + if (DISABLED(PROBE_MANUALLY) && seenQ) G29_RETURN(false); #endif - const bool no_action = seenA || seenQ, - faux = - #if ENABLED(DEBUG_LEVELING_FEATURE) && DISABLED(PROBE_MANUALLY) - parser.boolval('C') - #else - no_action - #endif - ; + const bool seenA = TERN0(PROBE_MANUALLY, parser.seen('A')), + no_action = seenA || seenQ, + faux = ENABLED(DEBUG_LEVELING_FEATURE) && DISABLED(PROBE_MANUALLY) ? parser.boolval('C') : no_action; // Don't allow auto-leveling without homing first - if (axis_unhomed_error()) G29_RETURN(false); + if (homing_needed_error()) G29_RETURN(false); if (!no_action && planner.leveling_active && parser.boolval('O')) { // Auto-level only if needed - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> Auto-level not needed, skip\n<<< G29"); + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> Auto-level not needed, skip"); G29_RETURN(false); } // Define local vars 'static' for manual probing, 'auto' otherwise - #if ENABLED(PROBE_MANUALLY) - #define ABL_VAR static - #else - #define ABL_VAR - #endif + #define ABL_VAR TERN_(PROBE_MANUALLY, static) ABL_VAR int verbose_level; ABL_VAR xy_pos_t probePos; @@ -223,10 +201,6 @@ G29_TYPE GcodeSuite::G29() { ABL_VAR int abl_probe_index; #endif - #if HAS_SOFTWARE_ENDSTOPS && ENABLED(PROBE_MANUALLY) - ABL_VAR bool saved_soft_endstops_state = true; - #endif - #if ABL_GRID #if ENABLED(PROBE_MANUALLY) @@ -245,7 +219,7 @@ G29_TYPE GcodeSuite::G29() { #if ENABLED(AUTO_BED_LEVELING_LINEAR) ABL_VAR int abl_points; - #elif ENABLED(PROBE_MANUALLY) // Bilinear + #else int constexpr abl_points = GRID_MAX_POINTS; #endif @@ -283,9 +257,7 @@ G29_TYPE GcodeSuite::G29() { */ if (!g29_in_progress) { - #if HOTENDS > 1 - if (active_extruder != 0) tool_change(0); - #endif + TERN_(HAS_MULTI_HOTEND, if (active_extruder) tool_change(0)); #if EITHER(PROBE_MANUALLY, AUTO_BED_LEVELING_LINEAR) abl_probe_index = -1; @@ -322,12 +294,8 @@ G29_TYPE GcodeSuite::G29() { if (WITHIN(i, 0, GRID_MAX_POINTS_X - 1) && WITHIN(j, 0, GRID_MAX_POINTS_Y)) { set_bed_leveling_enabled(false); z_values[i][j] = rz; - #if ENABLED(ABL_BILINEAR_SUBDIVISION) - bed_level_virt_interpolate(); - #endif - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(i, j, rz); - #endif + TERN_(ABL_BILINEAR_SUBDIVISION, bed_level_virt_interpolate()); + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(i, j, rz)); set_bed_leveling_enabled(abl_should_enable); if (abl_should_enable) report_current_position(); } @@ -352,11 +320,7 @@ G29_TYPE GcodeSuite::G29() { G29_RETURN(false); } - dryrun = parser.boolval('D') - #if ENABLED(PROBE_MANUALLY) - || no_action - #endif - ; + dryrun = parser.boolval('D') || TERN0(PROBE_MANUALLY, no_action); #if ENABLED(AUTO_BED_LEVELING_LINEAR) @@ -417,17 +381,7 @@ G29_TYPE GcodeSuite::G29() { ); } - if ( - #if IS_SCARA || ENABLED(DELTA) - !position_is_reachable_by_probe(probe_position_lf.x, 0) - || !position_is_reachable_by_probe(probe_position_rb.x, 0) - || !position_is_reachable_by_probe(0, probe_position_lf.y) - || !position_is_reachable_by_probe(0, probe_position_rb.y) - #else - !position_is_reachable_by_probe(probe_position_lf) - || !position_is_reachable_by_probe(probe_position_rb) - #endif - ) { + if (!probe.good_bounds(probe_position_lf, probe_position_rb)) { SERIAL_ECHOLNPGM("? (L,R,F,B) out of bounds."); G29_RETURN(false); } @@ -446,26 +400,27 @@ G29_TYPE GcodeSuite::G29() { planner.synchronize(); + if (!faux) remember_feedrate_scaling_off(); + // Disable auto bed leveling during G29. // Be formal so G29 can be done successively without G28. if (!no_action) set_bed_leveling_enabled(false); + // Deploy certain probes before starting probing #if HAS_BED_PROBE - // Deploy the probe. Probe will raise if needed. - if (probe.deploy()) { + if (ENABLED(BLTOUCH)) + do_z_clearance(Z_CLEARANCE_DEPLOY_PROBE); + else if (probe.deploy()) { set_bed_leveling_enabled(abl_should_enable); G29_RETURN(false); } #endif - if (!faux) remember_feedrate_scaling_off(); - #if ENABLED(AUTO_BED_LEVELING_BILINEAR) - #if ENABLED(PROBE_MANUALLY) - if (!no_action) - #endif - if (gridSpacing != bilinear_grid_spacing || probe_position_lf != bilinear_start) { + if (TERN1(PROBE_MANUALLY, !no_action) + && (gridSpacing != bilinear_grid_spacing || probe_position_lf != bilinear_start) + ) { // Reset grid to 0.0 or "not probed". (Also disables ABL) reset_bed_level(); @@ -502,14 +457,10 @@ G29_TYPE GcodeSuite::G29() { // Abort current G29 procedure, go back to idle state if (seenA && g29_in_progress) { SERIAL_ECHOLNPGM("Manual G29 aborted"); - #if HAS_SOFTWARE_ENDSTOPS - soft_endstops_enabled = saved_soft_endstops_state; - #endif + SET_SOFT_ENDSTOP_LOOSE(false); set_bed_leveling_enabled(abl_should_enable); g29_in_progress = false; - #if ENABLED(LCD_BED_LEVELING) - ui.wait_for_move = false; - #endif + TERN_(LCD_BED_LEVELING, ui.wait_for_move = false); } // Query G29 status @@ -527,9 +478,7 @@ G29_TYPE GcodeSuite::G29() { if (abl_probe_index == 0) { // For the initial G29 S2 save software endstop state - #if HAS_SOFTWARE_ENDSTOPS - saved_soft_endstops_state = soft_endstops_enabled; - #endif + SET_SOFT_ENDSTOP_LOOSE(true); // Move close to the bed before the first point do_blocking_move_to_z(0); } @@ -561,9 +510,7 @@ G29_TYPE GcodeSuite::G29() { const float newz = measured_z + zoffset; z_values[meshCount.x][meshCount.y] = newz; - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(meshCount, newz); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(meshCount, newz)); if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR_P(PSTR("Save X"), meshCount.x, SP_Y_STR, meshCount.y, SP_Z_STR, measured_z + zoffset); @@ -584,15 +531,12 @@ G29_TYPE GcodeSuite::G29() { PR_INNER_VAR = abl_probe_index - (PR_OUTER_VAR * PR_INNER_END); // Probe in reverse order for every other row/column - bool zig = (PR_OUTER_VAR & 1); // != ((PR_OUTER_END) & 1); - + const bool zig = (PR_OUTER_VAR & 1); // != ((PR_OUTER_END) & 1); if (zig) PR_INNER_VAR = (PR_INNER_END - 1) - PR_INNER_VAR; probePos = probe_position_lf + gridSpacing * meshCount.asFloat(); - #if ENABLED(AUTO_BED_LEVELING_LINEAR) - indexIntoAB[meshCount.x][meshCount.y] = abl_probe_index; - #endif + TERN_(AUTO_BED_LEVELING_LINEAR, indexIntoAB[meshCount.x][meshCount.y] = abl_probe_index); // Keep looping till a reachable point is found if (position_is_reachable(probePos)) break; @@ -602,23 +546,16 @@ G29_TYPE GcodeSuite::G29() { // Is there a next point to move to? if (abl_probe_index < abl_points) { _manual_goto_xy(probePos); // Can be used here too! - #if HAS_SOFTWARE_ENDSTOPS - // Disable software endstops to allow manual adjustment - // If G29 is not completed, they will not be re-enabled - soft_endstops_enabled = false; - #endif + // Disable software endstops to allow manual adjustment + // If G29 is not completed, they will not be re-enabled + SET_SOFT_ENDSTOP_LOOSE(true); G29_RETURN(false); } else { - // Leveling done! Fall through to G29 finishing code below - SERIAL_ECHOLNPGM("Grid probing done."); - // Re-enable software endstops, if needed - #if HAS_SOFTWARE_ENDSTOPS - soft_endstops_enabled = saved_soft_endstops_state; - #endif + SET_SOFT_ENDSTOP_LOOSE(false); } #elif ENABLED(AUTO_BED_LEVELING_3POINT) @@ -627,11 +564,9 @@ G29_TYPE GcodeSuite::G29() { if (abl_probe_index < abl_points) { probePos = points[abl_probe_index]; _manual_goto_xy(probePos); - #if HAS_SOFTWARE_ENDSTOPS - // Disable software endstops to allow manual adjustment - // If G29 is not completed, they will not be re-enabled - soft_endstops_enabled = false; - #endif + // Disable software endstops to allow manual adjustment + // If G29 is not completed, they will not be re-enabled + SET_SOFT_ENDSTOP_LOOSE(true); G29_RETURN(false); } else { @@ -639,9 +574,7 @@ G29_TYPE GcodeSuite::G29() { SERIAL_ECHOLNPGM("3-point probing done."); // Re-enable software endstops, if needed - #if HAS_SOFTWARE_ENDSTOPS - soft_endstops_enabled = saved_soft_endstops_state; - #endif + SET_SOFT_ENDSTOP_LOOSE(false); if (!dryrun) { vector_3 planeNormal = vector_3::cross(points[0] - points[1], points[2] - points[1]).get_normal(); @@ -698,19 +631,13 @@ G29_TYPE GcodeSuite::G29() { probePos = probe_position_lf + gridSpacing * meshCount.asFloat(); - #if ENABLED(AUTO_BED_LEVELING_LINEAR) - indexIntoAB[meshCount.x][meshCount.y] = ++abl_probe_index; // 0... - #endif + TERN_(AUTO_BED_LEVELING_LINEAR, indexIntoAB[meshCount.x][meshCount.y] = ++abl_probe_index); // 0... - #if IS_KINEMATIC - // Avoid probing outside the round or hexagonal area - if (!position_is_reachable_by_probe(probePos)) continue; - #endif + // Avoid probing outside the round or hexagonal area + if (TERN0(IS_KINEMATIC, !probe.can_reach(probePos))) continue; - if (verbose_level) SERIAL_ECHOLNPAIR("Probing mesh point ", int(pt_index), "/", int(GRID_MAX_POINTS), "."); - #if HAS_DISPLAY - ui.status_printf_P(0, PSTR(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_MESH), int(pt_index), int(GRID_MAX_POINTS)); - #endif + if (verbose_level) SERIAL_ECHOLNPAIR("Probing mesh point ", int(pt_index), "/", abl_points, "."); + TERN_(HAS_DISPLAY, ui.status_printf_P(0, PSTR(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_MESH), int(pt_index), int(abl_points))); measured_z = faux ? 0.001f * random(-100, 101) : probe.probe_at_point(probePos, raise_after, verbose_level); @@ -722,9 +649,7 @@ G29_TYPE GcodeSuite::G29() { #if ENABLED(PROBE_TEMP_COMPENSATION) temp_comp.compensate_measurement(TSI_BED, thermalManager.degBed(), measured_z); temp_comp.compensate_measurement(TSI_PROBE, thermalManager.degProbe(), measured_z); - #if ENABLED(USE_TEMP_EXT_COMPENSATION) - temp_comp.compensate_measurement(TSI_EXT, thermalManager.degHotend(), measured_z); - #endif + TERN_(USE_TEMP_EXT_COMPENSATION, temp_comp.compensate_measurement(TSI_EXT, thermalManager.degHotend(), measured_z)); #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) @@ -740,14 +665,12 @@ G29_TYPE GcodeSuite::G29() { #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) z_values[meshCount.x][meshCount.y] = measured_z + zoffset; - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(meshCount, z_values[meshCount.x][meshCount.y]); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(meshCount, z_values[meshCount.x][meshCount.y])); #endif abl_should_enable = false; - idle(); + idle_no_sleep(); } // inner } // outer @@ -756,11 +679,9 @@ G29_TYPE GcodeSuite::G29() { // Probe at 3 arbitrary points - for (uint8_t i = 0; i < 3; ++i) { - if (verbose_level) SERIAL_ECHOLNPAIR("Probing point ", int(i), "/3."); - #if HAS_DISPLAY - ui.status_printf_P(0, PSTR(S_FMT " %i/3"), GET_TEXT(MSG_PROBING_MESH), int(i)); - #endif + LOOP_L_N(i, 3) { + if (verbose_level) SERIAL_ECHOLNPAIR("Probing point ", int(i + 1), "/3."); + TERN_(HAS_DISPLAY, ui.status_printf_P(0, PSTR(S_FMT " %i/3"), GET_TEXT(MSG_PROBING_MESH), int(i + 1))); // Retain the last probe position probePos = points[i]; @@ -783,9 +704,7 @@ G29_TYPE GcodeSuite::G29() { #endif // AUTO_BED_LEVELING_3POINT - #if HAS_DISPLAY - ui.reset_status(); - #endif + TERN_(HAS_DISPLAY, ui.reset_status()); // Stow the probe. No raise for FIX_MOUNTED_PROBE. if (probe.stow()) { @@ -809,9 +728,7 @@ G29_TYPE GcodeSuite::G29() { #if ENABLED(PROBE_MANUALLY) g29_in_progress = false; - #if ENABLED(LCD_BED_LEVELING) - ui.wait_for_move = false; - #endif + TERN_(LCD_BED_LEVELING, ui.wait_for_move = false); #endif // Calculate leveling, print reports, correct the position @@ -823,9 +740,7 @@ G29_TYPE GcodeSuite::G29() { refresh_bed_level(); - #if ENABLED(ABL_BILINEAR_SUBDIVISION) - print_bilinear_leveling_grid_virt(); - #endif + TERN_(ABL_BILINEAR_SUBDIVISION, print_bilinear_leveling_grid_virt()); #elif ENABLED(AUTO_BED_LEVELING_LINEAR) @@ -871,7 +786,7 @@ G29_TYPE GcodeSuite::G29() { auto print_topo_map = [&](PGM_P const title, const bool get_min) { serialprintPGM(title); for (int8_t yy = abl_grid_points.y - 1; yy >= 0; yy--) { - for (uint8_t xx = 0; xx < abl_grid_points.x; xx++) { + LOOP_L_N(xx, abl_grid_points.x) { const int ind = indexIntoAB[xx][yy]; xyz_float_t tmp = { eqnAMatrix[ind + 0 * abl_points], eqnAMatrix[ind + 1 * abl_points], 0 }; @@ -944,7 +859,8 @@ G29_TYPE GcodeSuite::G29() { // Unapply the offset because it is going to be immediately applied // and cause compensation movement in Z - current_position.z -= bilinear_z_offset(current_position); + const float fade_scaling_factor = TERN(ENABLE_LEVELING_FADE_HEIGHT, planner.fade_scaling_factor_for_z(current_position.z), 1); + current_position.z -= fade_scaling_factor * bilinear_z_offset(current_position); if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR(" corrected Z:", current_position.z); } @@ -961,7 +877,7 @@ G29_TYPE GcodeSuite::G29() { // Sync the planner from the current_position if (planner.leveling_active) sync_plan_position(); - #if HAS_BED_PROBE && defined(Z_AFTER_PROBING) + #if HAS_BED_PROBE probe.move_z_after_probing(); #endif @@ -971,9 +887,11 @@ G29_TYPE GcodeSuite::G29() { process_subcommands_now_P(PSTR(Z_PROBE_END_SCRIPT)); #endif - report_current_position(); + #if ENABLED(DWIN_CREALITY_LCD) + DWIN_CompletedLeveling(); + #endif - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("<<< G29"); + report_current_position(); G29_RETURN(isnan(measured_z)); } diff --git a/Marlin/src/gcode/bedlevel/abl/M421.cpp b/Marlin/src/gcode/bedlevel/abl/M421.cpp index 85ff70757514..182dc32515b6 100644 --- a/Marlin/src/gcode/bedlevel/abl/M421.cpp +++ b/Marlin/src/gcode/bedlevel/abl/M421.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -32,36 +32,43 @@ #include "../../../feature/bedlevel/bedlevel.h" #if ENABLED(EXTENSIBLE_UI) - #include "../../../lcd/extensible_ui/ui_api.h" + #include "../../../lcd/extui/ui_api.h" #endif /** - * M421: Set a single Mesh Bed Leveling Z coordinate + * M421: Set one or more Mesh Bed Leveling Z coordinates * * Usage: * M421 I J Z * M421 I J Q + * + * - If I is omitted, set the entire row + * - If J is omitted, set the entire column + * - If both I and J are omitted, set all */ void GcodeSuite::M421() { int8_t ix = parser.intval('I', -1), iy = parser.intval('J', -1); - const bool hasI = ix >= 0, - hasJ = iy >= 0, - hasZ = parser.seen('Z'), - hasQ = !hasZ && parser.seen('Q'); + const bool hasZ = parser.seenval('Z'), + hasQ = !hasZ && parser.seenval('Q'); - if (!hasI || !hasJ || !(hasZ || hasQ)) - SERIAL_ERROR_MSG(STR_ERR_M421_PARAMETERS); - else if (!WITHIN(ix, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(iy, 0, GRID_MAX_POINTS_Y - 1)) - SERIAL_ERROR_MSG(STR_ERR_MESH_XY); - else { - z_values[ix][iy] = parser.value_linear_units() + (hasQ ? z_values[ix][iy] : 0); - #if ENABLED(ABL_BILINEAR_SUBDIVISION) - bed_level_virt_interpolate(); - #endif - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(ix, iy, z_values[ix][iy]); - #endif + if (hasZ || hasQ) { + if (WITHIN(ix, -1, GRID_MAX_POINTS_X - 1) && WITHIN(iy, -1, GRID_MAX_POINTS_Y - 1)) { + const float zval = parser.value_linear_units(); + uint8_t sx = ix >= 0 ? ix : 0, ex = ix >= 0 ? ix : GRID_MAX_POINTS_X - 1, + sy = iy >= 0 ? iy : 0, ey = iy >= 0 ? iy : GRID_MAX_POINTS_Y - 1; + LOOP_S_LE_N(x, sx, ex) { + LOOP_S_LE_N(y, sy, ey) { + z_values[x][y] = zval + (hasQ ? z_values[x][y] : 0); + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, z_values[x][y])); + } + } + TERN_(ABL_BILINEAR_SUBDIVISION, bed_level_virt_interpolate()); + } + else + SERIAL_ERROR_MSG(STR_ERR_MESH_XY); } + else + SERIAL_ERROR_MSG(STR_ERR_M421_PARAMETERS); } #endif // AUTO_BED_LEVELING_BILINEAR diff --git a/Marlin/src/gcode/bedlevel/mbl/G29.cpp b/Marlin/src/gcode/bedlevel/mbl/G29.cpp index 0a9a7f439bfc..d94c16052bcf 100644 --- a/Marlin/src/gcode/bedlevel/mbl/G29.cpp +++ b/Marlin/src/gcode/bedlevel/mbl/G29.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -39,7 +39,7 @@ #include "../../../module/stepper.h" #if ENABLED(EXTENSIBLE_UI) - #include "../../../lcd/extensible_ui/ui_api.h" + #include "../../../lcd/extui/ui_api.h" #endif // Save 130 bytes with non-duplication of PSTR @@ -57,14 +57,10 @@ inline void echo_not_entered(const char c) { SERIAL_CHAR(c); SERIAL_ECHOLNPGM(" * S3 In Jn Zn.nn Manually modify a single point * S4 Zn.nn Set z offset. Positive away from bed, negative closer to bed. * S5 Reset and disable mesh - * */ void GcodeSuite::G29() { static int mbl_probe_index = -1; - #if HAS_SOFTWARE_ENDSTOPS - static bool saved_soft_endstops_state; - #endif MeshLevelingState state = (MeshLevelingState)parser.byteval('S', (int8_t)MeshReport); if (!WITHIN(state, 0, 5)) { @@ -101,28 +97,19 @@ void GcodeSuite::G29() { } // For each G29 S2... if (mbl_probe_index == 0) { - #if HAS_SOFTWARE_ENDSTOPS - // For the initial G29 S2 save software endstop state - saved_soft_endstops_state = soft_endstops_enabled; - #endif // Move close to the bed before the first point do_blocking_move_to_z(0); } else { // Save Z for the previous mesh position mbl.set_zigzag_z(mbl_probe_index - 1, current_position.z); - #if HAS_SOFTWARE_ENDSTOPS - soft_endstops_enabled = saved_soft_endstops_state; - #endif + SET_SOFT_ENDSTOP_LOOSE(false); } // If there's another point to sample, move there with optional lift. if (mbl_probe_index < GRID_MAX_POINTS) { - #if HAS_SOFTWARE_ENDSTOPS - // Disable software endstops to allow manual adjustment - // If G29 is not completed, they will not be re-enabled - soft_endstops_enabled = false; - #endif - + // Disable software endstops to allow manual adjustment + // If G29 is left hanging without completion they won't be re-enabled! + SET_SOFT_ENDSTOP_LOOSE(true); mbl.zigzag(mbl_probe_index++, ix, iy); _manual_goto_xy({ mbl.index_to_xpos[ix], mbl.index_to_ypos[iy] }); } @@ -147,9 +134,7 @@ void GcodeSuite::G29() { planner.synchronize(); #endif - #if ENABLED(LCD_BED_LEVELING) - ui.wait_for_move = false; - #endif + TERN_(LCD_BED_LEVELING, ui.wait_for_move = false); } break; @@ -178,9 +163,7 @@ void GcodeSuite::G29() { if (parser.seenval('Z')) { mbl.z_values[ix][iy] = parser.value_linear_units(); - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(ix, iy, mbl.z_values[ix][iy]); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(ix, iy, mbl.z_values[ix][iy])); } else return echo_not_entered('Z'); diff --git a/Marlin/src/gcode/bedlevel/mbl/M421.cpp b/Marlin/src/gcode/bedlevel/mbl/M421.cpp index 3997e5ad591c..1368ab0bef98 100644 --- a/Marlin/src/gcode/bedlevel/mbl/M421.cpp +++ b/Marlin/src/gcode/bedlevel/mbl/M421.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/bedlevel/ubl/G29.cpp b/Marlin/src/gcode/bedlevel/ubl/G29.cpp index 7b42e6dddf8e..2ef3ab4ceca9 100644 --- a/Marlin/src/gcode/bedlevel/ubl/G29.cpp +++ b/Marlin/src/gcode/bedlevel/ubl/G29.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/bedlevel/ubl/M421.cpp b/Marlin/src/gcode/bedlevel/ubl/M421.cpp index ca4af1e0c026..600c1fc8ba51 100644 --- a/Marlin/src/gcode/bedlevel/ubl/M421.cpp +++ b/Marlin/src/gcode/bedlevel/ubl/M421.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -32,7 +32,7 @@ #include "../../../feature/bedlevel/bedlevel.h" #if ENABLED(EXTENSIBLE_UI) - #include "../../../lcd/extensible_ui/ui_api.h" + #include "../../../lcd/extui/ui_api.h" #endif /** @@ -63,9 +63,7 @@ void GcodeSuite::M421() { else { float &zval = ubl.z_values[ij.x][ij.y]; zval = hasN ? NAN : parser.value_linear_units() + (hasQ ? zval : 0); - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(ij.x, ij.y, zval); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(ij.x, ij.y, zval)); } } diff --git a/Marlin/src/gcode/calibrate/G28.cpp b/Marlin/src/gcode/calibrate/G28.cpp index 6841636cf0a7..34209568035d 100644 --- a/Marlin/src/gcode/calibrate/G28.cpp +++ b/Marlin/src/gcode/calibrate/G28.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -27,7 +27,7 @@ #include "../../module/stepper.h" #include "../../module/endstops.h" -#if HOTENDS > 1 +#if HAS_MULTI_HOTEND #include "../../module/tool_change.h" #endif @@ -46,11 +46,18 @@ #endif #include "../../lcd/ultralcd.h" +#if ENABLED(DWIN_CREALITY_LCD) + #include "../../lcd/dwin/e3v2/dwin.h" +#endif #if HAS_L64XX // set L6470 absolute position registers to counts #include "../../libs/L64XX/L64XX_Marlin.h" #endif +#if ENABLED(LASER_MOVE_G28_OFF) + #include "../../feature/spindle_laser.h" +#endif + #define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) #include "../../core/debug_out.h" @@ -62,13 +69,7 @@ current_position.set(0.0, 0.0); sync_plan_position(); - const int x_axis_home_dir = - #if ENABLED(DUAL_X_CARRIAGE) - x_home_dir(active_extruder) - #else - home_dir(X_AXIS) - #endif - ; + const int x_axis_home_dir = x_home_dir(active_extruder); const float mlx = max_length(X_AXIS), mly = max_length(Y_AXIS), @@ -106,8 +107,6 @@ #if AXIS_HAS_STALLGUARD(Y2) tmc_disable_stallguard(stepperY2, stealth_states.y2); #endif - do_blocking_move_to_xy(-0.5 * x_axis_home_dir, -0.5 * home_dir(Y_AXIS), fr_mm_s / 2); - safe_delay(100); #endif } @@ -116,15 +115,10 @@ #if ENABLED(Z_SAFE_HOMING) inline void home_z_safely() { + DEBUG_SECTION(log_G28, "home_z_safely", DEBUGGING(LEVELING)); - // Disallow Z homing if X or Y are unknown - if (!TEST(axis_known_position, X_AXIS) || !TEST(axis_known_position, Y_AXIS)) { - LCD_MESSAGEPGM(MSG_ERR_Z_HOMING); - SERIAL_ECHO_MSG(STR_ERR_Z_HOMING_SER); - return; - } - - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("home_z_safely >>>"); + // Disallow Z homing if X or Y homing is needed + if (homing_needed_error(_BV(X_AXIS) | _BV(Y_AXIS))) return; sync_plan_position(); @@ -134,22 +128,16 @@ */ destination.set(safe_homing_xy, current_position.z); - #if HOMING_Z_WITH_PROBE - destination -= probe.offset_xy; - #endif + TERN_(HOMING_Z_WITH_PROBE, destination -= probe.offset_xy); if (position_is_reachable(destination)) { if (DEBUGGING(LEVELING)) DEBUG_POS("home_z_safely", destination); // This causes the carriage on Dual X to unpark - #if ENABLED(DUAL_X_CARRIAGE) - active_extruder_parked = false; - #endif + TERN_(DUAL_X_CARRIAGE, active_extruder_parked = false); - #if ENABLED(SENSORLESS_HOMING) - safe_delay(500); // Short delay needed to settle - #endif + TERN_(SENSORLESS_HOMING, safe_delay(500)); // Short delay needed to settle do_blocking_move_to_xy(destination); homeaxis(Z_AXIS); @@ -158,8 +146,6 @@ LCD_MESSAGEPGM(MSG_ZPROBE_OUT); SERIAL_ECHO_MSG(STR_ZPROBE_OUT_SER); } - - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("<<< home_z_safely"); } #endif // Z_SAFE_HOMING @@ -183,9 +169,7 @@ void end_slow_homing(const slow_homing_t &slow_homing) { planner.settings.max_acceleration_mm_per_s2[X_AXIS] = slow_homing.acceleration.x; planner.settings.max_acceleration_mm_per_s2[Y_AXIS] = slow_homing.acceleration.y; - #if HAS_CLASSIC_JERK - planner.max_jerk = slow_homing.jerk_xy; - #endif + TERN_(HAS_CLASSIC_JERK, planner.max_jerk = slow_homing.jerk_xy); planner.reset_acceleration_rates(); } @@ -208,13 +192,14 @@ * X Home to the X endstop * Y Home to the Y endstop * Z Home to the Z endstop - * */ -void GcodeSuite::G28(const bool always_home_all) { - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOLNPGM(">>> G28"); - log_machine_info(); - } +void GcodeSuite::G28() { + DEBUG_SECTION(log_G28, "G28", DEBUGGING(LEVELING)); + if (DEBUGGING(LEVELING)) log_machine_info(); + + TERN_(LASER_MOVE_G28_OFF, cutter.set_inline_enabled(false)); // turn off laser + + TERN_(DWIN_CREALITY_LCD, HMI_flag.home_flag = true); #if ENABLED(DUAL_X_CARRIAGE) bool IDEX_saved_duplication_state = extruder_duplication_enabled; @@ -227,82 +212,77 @@ void GcodeSuite::G28(const bool always_home_all) { sync_plan_position(); SERIAL_ECHOLNPGM("Simulated Homing"); report_current_position(); - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("<<< G28"); return; } #endif // Home (O)nly if position is unknown if (!homing_needed() && parser.boolval('O')) { - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> homing not needed, skip\n<<< G28"); + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> homing not needed, skip"); return; } - // Wait for planner moves to finish! - planner.synchronize(); + planner.synchronize(); // Wait for planner moves to finish! + + SET_SOFT_ENDSTOP_LOOSE(false); // Reset a leftover 'loose' motion state // Disable the leveling matrix before homing #if HAS_LEVELING // Cancel the active G29 session - #if ENABLED(PROBE_MANUALLY) - g29_in_progress = false; - #endif + TERN_(PROBE_MANUALLY, g29_in_progress = false); - #if ENABLED(RESTORE_LEVELING_AFTER_G28) - const bool leveling_was_active = planner.leveling_active; - #endif + TERN_(RESTORE_LEVELING_AFTER_G28, const bool leveling_was_active = planner.leveling_active); set_bed_leveling_enabled(false); #endif - #if ENABLED(CNC_WORKSPACE_PLANES) - workspace_plane = PLANE_XY; - #endif + TERN_(CNC_WORKSPACE_PLANES, workspace_plane = PLANE_XY); + + // Count this command as movement / activity + reset_stepper_timeout(); #define HAS_CURRENT_HOME(N) (defined(N##_CURRENT_HOME) && N##_CURRENT_HOME != N##_CURRENT) - #define HAS_HOMING_CURRENT (HAS_CURRENT_HOME(X) || HAS_CURRENT_HOME(X2) || HAS_CURRENT_HOME(Y) || HAS_CURRENT_HOME(Y2)) + #if HAS_CURRENT_HOME(X) || HAS_CURRENT_HOME(X2) || HAS_CURRENT_HOME(Y) || HAS_CURRENT_HOME(Y2) + #define HAS_HOMING_CURRENT 1 + #endif #if HAS_HOMING_CURRENT - auto debug_current = [](const char * const s, const int16_t a, const int16_t b){ - DEBUG_ECHO(s); DEBUG_ECHOLNPAIR(" current: ", a, " -> ", b); + auto debug_current = [](PGM_P const s, const int16_t a, const int16_t b){ + serialprintPGM(s); DEBUG_ECHOLNPAIR(" current: ", a, " -> ", b); }; #if HAS_CURRENT_HOME(X) const int16_t tmc_save_current_X = stepperX.getMilliamps(); stepperX.rms_current(X_CURRENT_HOME); - if (DEBUGGING(LEVELING)) debug_current("X", tmc_save_current_X, X_CURRENT_HOME); + if (DEBUGGING(LEVELING)) debug_current(PSTR("X"), tmc_save_current_X, X_CURRENT_HOME); #endif #if HAS_CURRENT_HOME(X2) const int16_t tmc_save_current_X2 = stepperX2.getMilliamps(); stepperX2.rms_current(X2_CURRENT_HOME); - if (DEBUGGING(LEVELING)) debug_current("X2", tmc_save_current_X2, X2_CURRENT_HOME); + if (DEBUGGING(LEVELING)) debug_current(PSTR("X2"), tmc_save_current_X2, X2_CURRENT_HOME); #endif #if HAS_CURRENT_HOME(Y) const int16_t tmc_save_current_Y = stepperY.getMilliamps(); stepperY.rms_current(Y_CURRENT_HOME); - if (DEBUGGING(LEVELING)) debug_current("Y", tmc_save_current_Y, Y_CURRENT_HOME); + if (DEBUGGING(LEVELING)) debug_current(PSTR("Y"), tmc_save_current_Y, Y_CURRENT_HOME); #endif #if HAS_CURRENT_HOME(Y2) const int16_t tmc_save_current_Y2 = stepperY2.getMilliamps(); stepperY2.rms_current(Y2_CURRENT_HOME); - if (DEBUGGING(LEVELING)) debug_current("Y2", tmc_save_current_Y2, Y2_CURRENT_HOME); + if (DEBUGGING(LEVELING)) debug_current(PSTR("Y2"), tmc_save_current_Y2, Y2_CURRENT_HOME); #endif #endif - #if ENABLED(IMPROVE_HOMING_RELIABILITY) - slow_homing_t slow_homing = begin_slow_homing(); - #endif + TERN_(IMPROVE_HOMING_RELIABILITY, slow_homing_t slow_homing = begin_slow_homing()); // Always home with tool 0 active - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND #if DISABLED(DELTA) || ENABLED(DELTA_HOME_TO_SAFE_ZONE) const uint8_t old_tool_index = active_extruder; #endif tool_change(0, true); #endif - #if HAS_DUPLICATION_MODE - extruder_duplication_enabled = false; - #endif + TERN_(HAS_DUPLICATION_MODE, extruder_duplication_enabled = false); remember_feedrate_scaling_off(); @@ -310,41 +290,36 @@ void GcodeSuite::G28(const bool always_home_all) { #if ENABLED(DELTA) + constexpr bool doZ = true; // for NANODLP_Z_SYNC if your DLP is on a DELTA + home_delta(); - UNUSED(always_home_all); - #if ENABLED(IMPROVE_HOMING_RELIABILITY) - end_slow_homing(slow_homing); - #endif + TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(slow_homing)); #else // NOT DELTA - const bool homeX = parser.seen('X'), homeY = parser.seen('Y'), homeZ = parser.seen('Z'), - home_all = always_home_all || (homeX == homeY && homeX == homeZ), + const bool homeZ = parser.seen('Z'), + needX = homeZ && TERN0(Z_SAFE_HOMING, axes_should_home(_BV(X_AXIS))), + needY = homeZ && TERN0(Z_SAFE_HOMING, axes_should_home(_BV(Y_AXIS))), + homeX = needX || parser.seen('X'), homeY = needY || parser.seen('Y'), + home_all = homeX == homeY && homeX == homeZ, // All or None doX = home_all || homeX, doY = home_all || homeY, doZ = home_all || homeZ; - destination = current_position; - #if Z_HOME_DIR > 0 // If homing away from BED do Z first if (doZ) homeaxis(Z_AXIS); #endif - const float z_homing_height = ( - #if ENABLED(UNKNOWN_Z_NO_RAISE) - !TEST(axis_known_position, Z_AXIS) ? 0 : - #endif - (parser.seenval('R') ? parser.value_linear_units() : Z_HOMING_HEIGHT) - ); + const float z_homing_height = + ENABLED(UNKNOWN_Z_NO_RAISE) && !TEST(axis_known_position, Z_AXIS) + ? 0 + : (parser.seenval('R') ? parser.value_linear_units() : Z_HOMING_HEIGHT); - if (z_homing_height && (doX || doY)) { + if (z_homing_height && (doX || doY || (ENABLED(Z_SAFE_HOMING) && doZ))) { // Raise Z before homing any other axes and z is not already high enough (never lower z) - destination.z = z_homing_height + (TEST(axis_known_position, Z_AXIS) ? 0.0f : current_position.z); - if (destination.z > current_position.z) { - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Raise Z (before homing) to ", destination.z); - do_blocking_move_to_z(destination.z); - } + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Raise Z (before homing) by ", z_homing_height); + do_z_clearance(z_homing_height, true, DISABLED(UNKNOWN_Z_NO_RAISE)); } #if ENABLED(QUICK_HOME) @@ -354,22 +329,11 @@ void GcodeSuite::G28(const bool always_home_all) { #endif // Home Y (before X) - #if ENABLED(HOME_Y_BEFORE_X) - - if (doY - #if ENABLED(CODEPENDENT_XY_HOMING) - || doX - #endif - ) homeaxis(Y_AXIS); - - #endif + if (ENABLED(HOME_Y_BEFORE_X) && (doY || (ENABLED(CODEPENDENT_XY_HOMING) && doX))) + homeaxis(Y_AXIS); // Home X - if (doX - #if ENABLED(CODEPENDENT_XY_HOMING) && DISABLED(HOME_Y_BEFORE_X) - || doY - #endif - ) { + if (doX || (doY && ENABLED(CODEPENDENT_XY_HOMING) && DISABLED(HOME_Y_BEFORE_X))) { #if ENABLED(DUAL_X_CARRIAGE) @@ -397,36 +361,20 @@ void GcodeSuite::G28(const bool always_home_all) { } // Home Y (after X) - #if DISABLED(HOME_Y_BEFORE_X) - if (doY) homeaxis(Y_AXIS); - #endif + if (DISABLED(HOME_Y_BEFORE_X) && doY) + homeaxis(Y_AXIS); - #if ENABLED(IMPROVE_HOMING_RELIABILITY) - end_slow_homing(slow_homing); - #endif + TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(slow_homing)); // Home Z last if homing towards the bed #if Z_HOME_DIR < 0 if (doZ) { - #if ENABLED(BLTOUCH) - bltouch.init(); - #endif - #if ENABLED(Z_SAFE_HOMING) - home_z_safely(); - #else - homeaxis(Z_AXIS); - #endif - - #if HOMING_Z_WITH_PROBE && defined(Z_AFTER_PROBING) - #if Z_AFTER_HOMING > Z_AFTER_PROBING - do_blocking_move_to_z(Z_AFTER_HOMING); - #else - probe.move_z_after_probing(); - #endif - #elif defined(Z_AFTER_HOMING) - do_blocking_move_to_z(Z_AFTER_HOMING); - #endif + TERN_(BLTOUCH, bltouch.init()); + + TERN(Z_SAFE_HOMING, home_z_safely(), homeaxis(Z_AXIS)); + + probe.move_z_after_homing(); } // doZ @@ -446,9 +394,7 @@ void GcodeSuite::G28(const bool always_home_all) { if (dxc_is_duplicating()) { - #if ENABLED(IMPROVE_HOMING_RELIABILITY) - slow_homing = begin_slow_homing(); - #endif + TERN_(IMPROVE_HOMING_RELIABILITY, slow_homing = begin_slow_homing()); // Always home the 2nd (right) extruder first active_extruder = 1; @@ -469,9 +415,7 @@ void GcodeSuite::G28(const bool always_home_all) { dual_x_carriage_mode = IDEX_saved_mode; stepper.set_directions(); - #if ENABLED(IMPROVE_HOMING_RELIABILITY) - end_slow_homing(slow_homing); - #endif + TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(slow_homing)); } #endif // DUAL_X_CARRIAGE @@ -479,29 +423,20 @@ void GcodeSuite::G28(const bool always_home_all) { endstops.not_homing(); // Clear endstop state for polled stallGuard endstops - #if ENABLED(SPI_ENDSTOPS) - endstops.clear_endstop_state(); - #endif + TERN_(SPI_ENDSTOPS, endstops.clear_endstop_state()); #if BOTH(DELTA, DELTA_HOME_TO_SAFE_ZONE) // move to a height where we can use the full xy-area do_blocking_move_to_z(delta_clip_start_height); #endif - #if HAS_LEVELING && ENABLED(RESTORE_LEVELING_AFTER_G28) - set_bed_leveling_enabled(leveling_was_active); - #endif + TERN_(RESTORE_LEVELING_AFTER_G28, set_bed_leveling_enabled(leveling_was_active)); restore_feedrate_and_scaling(); // Restore the active tool after homing - #if HOTENDS > 1 && (DISABLED(DELTA) || ENABLED(DELTA_HOME_TO_SAFE_ZONE)) - #if EITHER(PARKING_EXTRUDER, DUAL_X_CARRIAGE) - #define NO_FETCH false // fetch the previous toolhead - #else - #define NO_FETCH true - #endif - tool_change(old_tool_index, NO_FETCH); + #if HAS_MULTI_HOTEND && (DISABLED(DELTA) || ENABLED(DELTA_HOME_TO_SAFE_ZONE)) + tool_change(old_tool_index, NONE(PARKING_EXTRUDER, DUAL_X_CARRIAGE)); // Do move if one of these #endif #if HAS_HOMING_CURRENT @@ -522,19 +457,12 @@ void GcodeSuite::G28(const bool always_home_all) { ui.refresh(); - report_current_position(); + TERN_(DWIN_CREALITY_LCD, DWIN_CompletedHoming()); - #if ENABLED(NANODLP_Z_SYNC) - #if ENABLED(NANODLP_ALL_AXIS) - #define _HOME_SYNC true // For any axis, output sync text. - #else - #define _HOME_SYNC doZ // Only for Z-axis - #endif - if (_HOME_SYNC) - SERIAL_ECHOLNPGM(STR_Z_MOVE_COMP); - #endif + report_current_position(); - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("<<< G28"); + if (ENABLED(NANODLP_Z_SYNC) && (doZ || ENABLED(NANODLP_ALL_AXIS))) + SERIAL_ECHOLNPGM(STR_Z_MOVE_COMP); #if HAS_L64XX // Set L6470 absolute position registers to counts diff --git a/Marlin/src/gcode/calibrate/G33.cpp b/Marlin/src/gcode/calibrate/G33.cpp index ac2cdf7d4da8..53af04d52876 100644 --- a/Marlin/src/gcode/calibrate/G33.cpp +++ b/Marlin/src/gcode/calibrate/G33.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -35,7 +35,7 @@ #include "../../module/probe.h" #endif -#if HOTENDS > 1 +#if HAS_MULTI_HOTEND #include "../../module/tool_change.h" #endif @@ -63,12 +63,7 @@ enum CalEnum : char { // the 7 main calibration points - #define LOOP_CAL_RAD(VAR) LOOP_CAL_PT(VAR, __A, _7P_STEP) #define LOOP_CAL_ACT(VAR, _4P, _OP) LOOP_CAL_PT(VAR, _OP ? _AB : __A, _4P ? _4P_STEP : _7P_STEP) -#if HOTENDS > 1 - const uint8_t old_tool_index = active_extruder; - #define AC_CLEANUP() ac_cleanup(old_tool_index) -#else - #define AC_CLEANUP() ac_cleanup() -#endif +TERN_(HAS_MULTI_HOTEND, const uint8_t old_tool_index = active_extruder); float lcd_probe_pt(const xy_pos_t &xy); @@ -79,9 +74,7 @@ void ac_home() { } void ac_setup(const bool reset_bed) { - #if HOTENDS > 1 - tool_change(0, true); - #endif + TERN_(HAS_MULTI_HOTEND, tool_change(0, true)); planner.synchronize(); remember_feedrate_scaling_off(); @@ -91,21 +84,11 @@ void ac_setup(const bool reset_bed) { #endif } -void ac_cleanup( - #if HOTENDS > 1 - const uint8_t old_tool_index - #endif -) { - #if ENABLED(DELTA_HOME_TO_SAFE_ZONE) - do_blocking_move_to_z(delta_clip_start_height); - #endif - #if HAS_BED_PROBE - probe.stow(); - #endif +void ac_cleanup(TERN_(HAS_MULTI_HOTEND, const uint8_t old_tool_index)) { + TERN_(DELTA_HOME_TO_SAFE_ZONE, do_blocking_move_to_z(delta_clip_start_height)); + TERN_(HAS_BED_PROBE, probe.stow()); restore_feedrate_and_scaling(); - #if HOTENDS > 1 - tool_change(old_tool_index, true); - #endif + TERN_(HAS_MULTI_HOTEND, tool_change(old_tool_index, true)); } void print_signed_float(PGM_P const prefix, const float &f) { @@ -465,7 +448,7 @@ void GcodeSuite::G33() { } // Report settings - PGM_P checkingac = PSTR("Checking... AC"); + PGM_P const checkingac = PSTR("Checking... AC"); serialprintPGM(checkingac); if (verbose_level == 0) SERIAL_ECHOPGM(" (DRY-RUN)"); SERIAL_EOL(); @@ -488,7 +471,7 @@ void GcodeSuite::G33() { zero_std_dev_old = zero_std_dev; if (!probe_calibration_points(z_at_pt, probe_points, towers_set, stow_after_each)) { SERIAL_ECHOLNPGM("Correct delta settings with M665 and M666"); - return AC_CLEANUP(); + return ac_cleanup(TERN_(HAS_MULTI_HOTEND, old_tool_index)); } zero_std_dev = std_dev_points(z_at_pt, _0p_calibration, _1p_calibration, _4p_calibration, _4p_opposite_points); @@ -641,7 +624,7 @@ void GcodeSuite::G33() { } } else { // dry run - PGM_P enddryrun = PSTR("End DRY-RUN"); + PGM_P const enddryrun = PSTR("End DRY-RUN"); serialprintPGM(enddryrun); SERIAL_ECHO_SP(35); SERIAL_ECHOLNPAIR_F("std dev:", zero_std_dev, 3); @@ -659,7 +642,7 @@ void GcodeSuite::G33() { } while (((zero_std_dev < test_precision && iterations < 31) || iterations <= force_iterations) && zero_std_dev > calibration_precision); - AC_CLEANUP(); + ac_cleanup(TERN_(HAS_MULTI_HOTEND, old_tool_index)); } #endif // DELTA_AUTO_CALIBRATION diff --git a/Marlin/src/gcode/calibrate/G34.cpp b/Marlin/src/gcode/calibrate/G34.cpp new file mode 100644 index 000000000000..0ca4490eb6c1 --- /dev/null +++ b/Marlin/src/gcode/calibrate/G34.cpp @@ -0,0 +1,156 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfigPre.h" + +#if ENABLED(MECHANICAL_GANTRY_CALIBRATION) + +#include "../gcode.h" +#include "../../module/motion.h" +#include "../../module/stepper.h" +#include "../../module/endstops.h" + +#if HAS_LEVELING + #include "../../feature/bedlevel/bedlevel.h" +#endif + +#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) +#include "../../core/debug_out.h" + +void GcodeSuite::G34() { + + // Home before the alignment procedure + if (!all_axes_known()) home_all_axes(); + + SET_SOFT_ENDSTOP_LOOSE(true); + TEMPORARY_BED_LEVELING_STATE(false); + TemporaryGlobalEndstopsState unlock_z(false); + + #ifdef GANTRY_CALIBRATION_COMMANDS_PRE + gcode.process_subcommands_now_P(PSTR(GANTRY_CALIBRATION_COMMANDS_PRE)); + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Sub Commands Processed"); + #endif + + #ifdef GANTRY_CALIBRATION_SAFE_POSITION + // Move XY to safe position + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Parking XY"); + const xy_pos_t safe_pos = GANTRY_CALIBRATION_SAFE_POSITION; + do_blocking_move_to(safe_pos, MMM_TO_MMS(GANTRY_CALIBRATION_XY_PARK_FEEDRATE)); + #endif + + const float move_distance = parser.intval('Z', GANTRY_CALIBRATION_EXTRA_HEIGHT), + zbase = ENABLED(GANTRY_CALIBRATION_TO_MIN) ? Z_MIN_POS : Z_MAX_POS, + zpounce = zbase - move_distance, zgrind = zbase + move_distance; + + // Move Z to pounce position + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Setting Z Pounce"); + do_blocking_move_to_z(zpounce, MMM_TO_MMS(HOMING_FEEDRATE_Z)); + + // Store current motor settings, then apply reduced value + + #define _REDUCE_CURRENT ANY(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_PWM, HAS_MOTOR_CURRENT_DAC, HAS_MOTOR_CURRENT_I2C, HAS_TRINAMIC_CONFIG) + #if _REDUCE_CURRENT + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Reducing Current"); + #endif + + #if HAS_MOTOR_CURRENT_SPI + const uint16_t target_current = parser.intval('S', GANTRY_CALIBRATION_CURRENT); + const uint32_t previous_current = stepper.motor_current_setting[Z_AXIS]; + stepper.set_digipot_current(Z_AXIS, target_current); + #elif HAS_MOTOR_CURRENT_PWM + const uint16_t target_current = parser.intval('S', GANTRY_CALIBRATION_CURRENT); + const uint32_t previous_current = stepper.motor_current_setting[Z_AXIS]; + stepper.set_digipot_current(1, target_current); + #elif HAS_MOTOR_CURRENT_DAC + const float target_current = parser.floatval('S', GANTRY_CALIBRATION_CURRENT); + const float previous_current = dac_amps(Z_AXIS, target_current); + stepper_dac.set_current_value(Z_AXIS, target_current); + #elif ENABLED(HAS_MOTOR_CURRENT_I2C) + const uint16_t target_current = parser.intval('S', GANTRY_CALIBRATION_CURRENT); + previous_current = dac_amps(Z_AXIS); + digipot_i2c.set_current(Z_AXIS, target_current) + #elif HAS_TRINAMIC_CONFIG + const uint16_t target_current = parser.intval('S', GANTRY_CALIBRATION_CURRENT); + static uint16_t previous_current_arr[NUM_Z_STEPPER_DRIVERS]; + #if AXIS_IS_TMC(Z) + previous_current_arr[0] = stepperZ.getMilliamps(); + stepperZ.rms_current(target_current); + #endif + #if AXIS_IS_TMC(Z2) + previous_current_arr[1] = stepperZ2.getMilliamps(); + stepperZ2.rms_current(target_current); + #endif + #if AXIS_IS_TMC(Z3) + previous_current_arr[2] = stepperZ3.getMilliamps(); + stepperZ3.rms_current(target_current); + #endif + #if AXIS_IS_TMC(Z4) + previous_current_arr[3] = stepperZ4.getMilliamps(); + stepperZ4.rms_current(target_current); + #endif + #endif + + // Do Final Z move to adjust + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Final Z Move"); + do_blocking_move_to_z(zgrind, MMM_TO_MMS(GANTRY_CALIBRATION_FEEDRATE)); + + // Back off end plate, back to normal motion range + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Z Backoff"); + do_blocking_move_to_z(zpounce, MMM_TO_MMS(GANTRY_CALIBRATION_FEEDRATE)); + + #if _REDUCE_CURRENT + // Reset current to original values + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Restore Current"); + #endif + + #if HAS_MOTOR_CURRENT_SPI + stepper.set_digipot_current(Z_AXIS, previous_current); + #elif HAS_MOTOR_CURRENT_PWM + stepper.set_digipot_current(1, previous_current); + #elif HAS_MOTOR_CURRENT_DAC + stepper_dac.set_current_value(Z_AXIS, previous_current); + #elif ENABLED(HAS_MOTOR_CURRENT_I2C) + digipot_i2c.set_current(Z_AXIS, previous_current) + #elif HAS_TRINAMIC_CONFIG + #if AXIS_IS_TMC(Z) + stepperZ.rms_current(previous_current_arr[0]); + #endif + #if AXIS_IS_TMC(Z2) + stepperZ2.rms_current(previous_current_arr[1]); + #endif + #if AXIS_IS_TMC(Z3) + stepperZ3.rms_current(previous_current_arr[2]); + #endif + #if AXIS_IS_TMC(Z4) + stepperZ4.rms_current(previous_current_arr[3]); + #endif + #endif + + #ifdef GANTRY_CALIBRATION_COMMANDS_POST + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Running Post Commands"); + gcode.process_subcommands_now_P(PSTR(GANTRY_CALIBRATION_COMMANDS_POST)); + #endif + + SET_SOFT_ENDSTOP_LOOSE(false); +} + +#endif // MECHANICAL_GANTRY_CALIBRATION diff --git a/Marlin/src/gcode/calibrate/G34_M422.cpp b/Marlin/src/gcode/calibrate/G34_M422.cpp index e7bc63828f1f..24292477f9c1 100644 --- a/Marlin/src/gcode/calibrate/G34_M422.cpp +++ b/Marlin/src/gcode/calibrate/G34_M422.cpp @@ -16,65 +16,56 @@ * 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 . + * along with this program. If not, see . * */ -#include "../../inc/MarlinConfig.h" +#include "../../inc/MarlinConfigPre.h" #if ENABLED(Z_STEPPER_AUTO_ALIGN) #include "../../feature/z_stepper_align.h" #include "../gcode.h" -#include "../../module/planner.h" -#include "../../module/stepper.h" #include "../../module/motion.h" +#include "../../module/stepper.h" +#include "../../module/planner.h" #include "../../module/probe.h" - -#if HOTENDS > 1 - #include "../../module/tool_change.h" -#endif +#include "../../lcd/ultralcd.h" // for LCD_MESSAGEPGM #if HAS_LEVELING #include "../../feature/bedlevel/bedlevel.h" #endif +#if HAS_MULTI_HOTEND + #include "../../module/tool_change.h" +#endif + #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS) - #include "../../libs/least_squares_fit.h" + #include "../../libs/least_squares_fit.h" #endif #define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) #include "../../core/debug_out.h" -inline void set_all_z_lock(const bool lock) { - stepper.set_z_lock(lock); - stepper.set_z2_lock(lock); - #if NUM_Z_STEPPER_DRIVERS >= 3 - stepper.set_z3_lock(lock); - #if NUM_Z_STEPPER_DRIVERS >= 4 - stepper.set_z4_lock(lock); - #endif - #endif -} - /** * G34: Z-Stepper automatic alignment * * I * T * A + * R points based on current probe offsets */ void GcodeSuite::G34() { - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOLNPGM(">>> G34"); - log_machine_info(); - } + DEBUG_SECTION(log_G34, "G34", DEBUGGING(LEVELING)); + if (DEBUGGING(LEVELING)) log_machine_info(); do { // break out on error - #if NUM_Z_STEPPER_DRIVERS >= 4 - SERIAL_ECHOLNPGM("Alignment not supported for over 3 steppers"); + #if NUM_Z_STEPPER_DRIVERS == 4 + SERIAL_ECHOLNPGM("Alignment for 4 steppers is Experimental!"); + #elif NUM_Z_STEPPER_DRIVERS > 4 + SERIAL_ECHOLNPGM("Alignment not supported for over 4 steppers"); break; #endif @@ -101,6 +92,8 @@ void GcodeSuite::G34() { } #endif + if (parser.seen('R')) z_stepper_align.reset_to_default(); + const ProbePtRaise raise_after = parser.boolval('E') ? PROBE_PT_STOW : PROBE_PT_RAISE; // Wait for planner moves to finish! @@ -108,44 +101,39 @@ void GcodeSuite::G34() { // Disable the leveling matrix before auto-aligning #if HAS_LEVELING - #if ENABLED(RESTORE_LEVELING_AFTER_G34) - const bool leveling_was_active = planner.leveling_active; - #endif + TERN_(RESTORE_LEVELING_AFTER_G34, const bool leveling_was_active = planner.leveling_active); set_bed_leveling_enabled(false); #endif - #if ENABLED(CNC_WORKSPACE_PLANES) - workspace_plane = PLANE_XY; - #endif + TERN_(CNC_WORKSPACE_PLANES, workspace_plane = PLANE_XY); // Always home with tool 0 active - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND const uint8_t old_tool_index = active_extruder; tool_change(0, true); #endif - #if HAS_DUPLICATION_MODE - extruder_duplication_enabled = false; - #endif + TERN_(HAS_DUPLICATION_MODE, extruder_duplication_enabled = false); - #if BOTH(BLTOUCH, BLTOUCH_HS_MODE) - // In BLTOUCH HS mode, the probe travels in a deployed state. - // Users of G34 might have a badly misaligned bed, so raise Z by the - // length of the deployed pin (BLTOUCH stroke < 7mm) - #define Z_BASIC_CLEARANCE Z_CLEARANCE_BETWEEN_PROBES + 7.0f - #else - #define Z_BASIC_CLEARANCE Z_CLEARANCE_BETWEEN_PROBES - #endif + // In BLTOUCH HS mode, the probe travels in a deployed state. + // Users of G34 might have a badly misaligned bed, so raise Z by the + // length of the deployed pin (BLTOUCH stroke < 7mm) + #define Z_BASIC_CLEARANCE (Z_CLEARANCE_BETWEEN_PROBES + 7.0f * BOTH(BLTOUCH, BLTOUCH_HS_MODE)) // Compute a worst-case clearance height to probe from. After the first // iteration this will be re-calculated based on the actual bed position - float z_probe = Z_BASIC_CLEARANCE + (G34_MAX_GRADE) * 0.01f * ( + auto magnitude2 = [&](const uint8_t i, const uint8_t j) { + const xy_pos_t diff = z_stepper_align.xy[i] - z_stepper_align.xy[j]; + return HYPOT2(diff.x, diff.y); + }; + float z_probe = Z_BASIC_CLEARANCE + (G34_MAX_GRADE) * 0.01f * SQRT( #if NUM_Z_STEPPER_DRIVERS == 3 - SQRT(_MAX(HYPOT2(z_stepper_align.xy[0].x - z_stepper_align.xy[0].y, z_stepper_align.xy[1].x - z_stepper_align.xy[1].y), - HYPOT2(z_stepper_align.xy[1].x - z_stepper_align.xy[1].y, z_stepper_align.xy[2].x - z_stepper_align.xy[2].y), - HYPOT2(z_stepper_align.xy[2].x - z_stepper_align.xy[2].y, z_stepper_align.xy[0].x - z_stepper_align.xy[0].y))) + _MAX(magnitude2(0, 1), magnitude2(1, 2), magnitude2(2, 0)) + #elif NUM_Z_STEPPER_DRIVERS == 4 + _MAX(magnitude2(0, 1), magnitude2(1, 2), magnitude2(2, 3), + magnitude2(3, 0), magnitude2(0, 2), magnitude2(1, 3)) #else - HYPOT(z_stepper_align.xy[0].x - z_stepper_align.xy[0].y, z_stepper_align.xy[1].x - z_stepper_align.xy[1].y) + magnitude2(0, 1) #endif ); @@ -153,44 +141,66 @@ void GcodeSuite::G34() { if (!all_axes_known()) home_all_axes(); // Move the Z coordinate realm towards the positive - dirty trick - current_position.z -= z_probe * 0.5f; + current_position.z += z_probe * 0.5f; + sync_plan_position(); + // Now, the Z origin lies below the build plate. That allows to probe deeper, before run_z_probe throws an error. + // This hack is un-done at the end of G34 - either by re-homing, or by using the probed heights of the last iteration. - float last_z_align_move[NUM_Z_STEPPER_DRIVERS] = ARRAY_N(NUM_Z_STEPPER_DRIVERS, 10000.0f, 10000.0f, 10000.0f), - z_measured[NUM_Z_STEPPER_DRIVERS] = { 0 }, + #if DISABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS) + float last_z_align_move[NUM_Z_STEPPER_DRIVERS] = ARRAY_N(NUM_Z_STEPPER_DRIVERS, 10000.0f, 10000.0f, 10000.0f, 10000.0f); + #else + float last_z_align_level_indicator = 10000.0f; + #endif + float z_measured[NUM_Z_STEPPER_DRIVERS] = { 0 }, z_maxdiff = 0.0f, amplification = z_auto_align_amplification; - uint8_t iteration; - bool err_break = false; - #if DISABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS) bool adjustment_reverse = false; #endif - for (iteration = 0; iteration < z_auto_align_iterations; ++iteration) { + #if HAS_DISPLAY + PGM_P const msg_iteration = GET_TEXT(MSG_ITERATION); + const uint8_t iter_str_len = strlen_P(msg_iteration); + #endif + + // Final z and iteration values will be used after breaking the loop + float z_measured_min; + uint8_t iteration = 0; + bool err_break = false; // To break out of nested loops + while (iteration < z_auto_align_iterations) { if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> probing all positions."); - SERIAL_ECHOLNPAIR("\nITERATION: ", int(iteration + 1)); + const int iter = iteration + 1; + SERIAL_ECHOLNPAIR("\nG34 Iteration: ", iter); + #if HAS_DISPLAY + char str[iter_str_len + 2 + 1]; + sprintf_P(str, msg_iteration, iter); + ui.set_status(str); + #endif // Initialize minimum value - float z_measured_min = 100000.0f, - z_measured_max = -100000.0f; + z_measured_min = 100000.0f; + float z_measured_max = -100000.0f; // Probe all positions (one per Z-Stepper) - for (uint8_t i = 0; i < NUM_Z_STEPPER_DRIVERS; ++i) { + LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS) { // iteration odd/even --> downward / upward stepper sequence const uint8_t iprobe = (iteration & 1) ? NUM_Z_STEPPER_DRIVERS - 1 - i : i; // Safe clearance even on an incline - if (iteration == 0 || i > 0) do_blocking_move_to_z(z_probe); + if ((iteration == 0 || i > 0) && z_probe > current_position.z) do_blocking_move_to_z(z_probe); if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR_P(PSTR("Probing X"), z_stepper_align.xy[iprobe].x, SP_Y_STR, z_stepper_align.xy[iprobe].y); // Probe a Z height for each stepper. - const float z_probed_height = probe.probe_at_point(z_stepper_align.xy[iprobe], raise_after, 0, true); + // Probing sanity check is disabled, as it would trigger even in normal cases because + // current_position.z has been manually altered in the "dirty trick" above. + const float z_probed_height = probe.probe_at_point(z_stepper_align.xy[iprobe], raise_after, 0, true, false); if (isnan(z_probed_height)) { - SERIAL_ECHOLNPGM("Probing failed."); + SERIAL_ECHOLNPGM("Probing failed"); + LCD_MESSAGEPGM(MSG_LCD_PROBING_FAILED); err_break = true; break; } @@ -227,15 +237,15 @@ void GcodeSuite::G34() { // This allows the actual adjustment logic to be shared by both algorithms. linear_fit_data lfd; incremental_LSF_reset(&lfd); - for (uint8_t i = 0; i < NUM_Z_STEPPER_DRIVERS; ++i) { - SERIAL_ECHOLNPAIR("PROBEPT_", i + '1', ": ", z_measured[i]); + LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS) { + SERIAL_ECHOLNPAIR("PROBEPT_", int(i), ": ", z_measured[i]); incremental_LSF(&lfd, z_stepper_align.xy[i], z_measured[i]); } finish_incremental_LSF(&lfd); z_measured_min = 100000.0f; - for (uint8_t i = 0; i < NUM_Z_STEPPER_DRIVERS; ++i) { - z_measured[i] = -(lfd.A * z_stepper_align.stepper_xy[i].x + lfd.B * z_stepper_align.stepper_xy[i].y); + LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS) { + z_measured[i] = -(lfd.A * z_stepper_align.stepper_xy[i].x + lfd.B * z_stepper_align.stepper_xy[i].y + lfd.D); z_measured_min = _MIN(z_measured_min, z_measured[i]); } @@ -249,13 +259,66 @@ void GcodeSuite::G34() { , " Z3-Z1=", ABS(z_measured[2] - z_measured[0]) #endif ); + #if HAS_DISPLAY + char fstr1[10]; + #if NUM_Z_STEPPER_DRIVERS == 2 + char msg[6 + (6 + 5) * 1 + 1]; + #else + char msg[6 + (6 + 5) * 3 + 1], fstr2[10], fstr3[10]; + #endif + sprintf_P(msg, + PSTR("Diffs Z1-Z2=%s" + #if NUM_Z_STEPPER_DRIVERS == 3 + " Z2-Z3=%s" + " Z3-Z1=%s" + #endif + ), dtostrf(ABS(z_measured[0] - z_measured[1]), 1, 3, fstr1) + #if NUM_Z_STEPPER_DRIVERS == 3 + , dtostrf(ABS(z_measured[1] - z_measured[2]), 1, 3, fstr2) + , dtostrf(ABS(z_measured[2] - z_measured[0]), 1, 3, fstr3) + #endif + ); + ui.set_status(msg); + #endif + + auto decreasing_accuracy = [](const float &v1, const float &v2){ + if (v1 < v2 * 0.7f) { + SERIAL_ECHOLNPGM("Decreasing Accuracy Detected."); + LCD_MESSAGEPGM(MSG_DECREASING_ACCURACY); + return true; + } + return false; + }; + + #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS) + + // Check if the applied corrections go in the correct direction. + // Calculate the sum of the absolute deviations from the mean of the probe measurements. + // Compare to the last iteration to ensure it's getting better. + + // Calculate mean value as a reference + float z_measured_mean = 0.0f; + LOOP_L_N(zstepper, NUM_Z_STEPPER_DRIVERS) z_measured_mean += z_measured[zstepper]; + z_measured_mean /= NUM_Z_STEPPER_DRIVERS; + + // Calculate the sum of the absolute deviations from the mean value + float z_align_level_indicator = 0.0f; + LOOP_L_N(zstepper, NUM_Z_STEPPER_DRIVERS) + z_align_level_indicator += ABS(z_measured[zstepper] - z_measured_mean); + + // If it's getting worse, stop and throw an error + err_break = decreasing_accuracy(last_z_align_level_indicator, z_align_level_indicator); + if (err_break) break; + + last_z_align_level_indicator = z_align_level_indicator; + #endif // The following correction actions are to be enabled for select Z-steppers only stepper.set_separate_multi_axis(true); bool success_break = true; // Correct the individual stepper offsets - for (uint8_t zstepper = 0; zstepper < NUM_Z_STEPPER_DRIVERS; ++zstepper) { + LOOP_L_N(zstepper, NUM_Z_STEPPER_DRIVERS) { // Calculate current stepper move float z_align_move = z_measured[zstepper] - z_measured_min; const float z_align_abs = ABS(z_align_move); @@ -263,21 +326,18 @@ void GcodeSuite::G34() { #if DISABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS) // Optimize one iteration's correction based on the first measurements if (z_align_abs) amplification = (iteration == 1) ? _MIN(last_z_align_move[zstepper] / z_align_abs, 2.0f) : z_auto_align_amplification; - #endif - // Check for less accuracy compared to last move - if (last_z_align_move[zstepper] < z_align_abs * 0.7f) { - SERIAL_ECHOLNPGM("Decreasing accuracy detected."); - #if DISABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS) + // Check for less accuracy compared to last move + if (decreasing_accuracy(last_z_align_move[zstepper], z_align_abs)) { + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("> Z", int(zstepper + 1), " last_z_align_move = ", last_z_align_move[zstepper]); + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("> Z", int(zstepper + 1), " z_align_abs = ", z_align_abs); adjustment_reverse = !adjustment_reverse; - #else - err_break = true; - break; - #endif - } + } - // Remember the alignment for the next iteration - last_z_align_move[zstepper] = z_align_abs; + // Remember the alignment for the next iteration, but only if steppers move, + // otherwise it would be just zero (in case this stepper was at z_measured_min already) + if (z_align_abs > 0) last_z_align_move[zstepper] = z_align_abs; + #endif // Stop early if all measured points achieve accuracy target if (z_align_abs > z_auto_align_accuracy) success_break = false; @@ -285,20 +345,15 @@ void GcodeSuite::G34() { if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("> Z", int(zstepper + 1), " corrected by ", z_align_move); // Lock all steppers except one - set_all_z_lock(true); - switch (zstepper) { - case 0: stepper.set_z_lock(false); break; - case 1: stepper.set_z2_lock(false); break; - #if NUM_Z_STEPPER_DRIVERS == 3 - case 2: stepper.set_z3_lock(false); break; - #endif - } + stepper.set_all_z_lock(true, zstepper); #if DISABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS) // Decreasing accuracy was detected so move was inverted. // Will match reversed Z steppers on dual steppers. Triple will need more work to map. - if (adjustment_reverse) + if (adjustment_reverse) { z_align_move = -z_align_move; + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("> Z", int(zstepper + 1), " correction reversed to ", z_align_move); + } #endif // Do a move to correct part of the misalignment for the current stepper @@ -306,48 +361,52 @@ void GcodeSuite::G34() { } // for (zstepper) // Back to normal stepper operations - set_all_z_lock(false); + stepper.set_all_z_lock(false); stepper.set_separate_multi_axis(false); if (err_break) break; - if (success_break) { SERIAL_ECHOLNPGM("Target accuracy achieved."); break; } + if (success_break) { + SERIAL_ECHOLNPGM("Target accuracy achieved."); + LCD_MESSAGEPGM(MSG_ACCURACY_ACHIEVED); + break; + } + + iteration++; + } // while (iteration < z_auto_align_iterations) - } // for (iteration) + if (err_break) + SERIAL_ECHOLNPGM("G34 aborted."); + else { + SERIAL_ECHOLNPAIR("Did ", int(iteration + (iteration != z_auto_align_iterations)), " of ", int(z_auto_align_iterations)); + SERIAL_ECHOLNPAIR_F("Accuracy: ", z_maxdiff); + } - if (err_break) { SERIAL_ECHOLNPGM("G34 aborted."); break; } + // Stow the probe, as the last call to probe.probe_at_point(...) left + // the probe deployed if it was successful. + probe.stow(); - SERIAL_ECHOLNPAIR("Did ", int(iteration + (iteration != z_auto_align_iterations)), " iterations of ", int(z_auto_align_iterations)); - SERIAL_ECHOLNPAIR_F("Accuracy: ", z_maxdiff); + #if ENABLED(HOME_AFTER_G34) + // After this operation the z position needs correction + set_axis_never_homed(Z_AXIS); + // Home Z after the alignment procedure + process_subcommands_now_P(PSTR("G28Z")); + #else + // Use the probed height from the last iteration to determine the Z height. + // z_measured_min is used, because all steppers are aligned to z_measured_min. + // Ideally, this would be equal to the 'z_probe * 0.5f' which was added earlier. + current_position.z -= z_measured_min - (float)Z_CLEARANCE_BETWEEN_PROBES; + sync_plan_position(); + #endif // Restore the active tool after homing - #if HOTENDS > 1 - tool_change(old_tool_index, ( - #if ENABLED(PARKING_EXTRUDER) - false // Fetch the previous toolhead - #else - true - #endif - )); - #endif + TERN_(HAS_MULTI_HOTEND, tool_change(old_tool_index, DISABLED(PARKING_EXTRUDER))); // Fetch previous tool for parking extruder - #if HAS_LEVELING && ENABLED(RESTORE_LEVELING_AFTER_G34) + #if BOTH(HAS_LEVELING, RESTORE_LEVELING_AFTER_G34) set_bed_leveling_enabled(leveling_was_active); #endif - // After this operation the z position needs correction - set_axis_is_not_at_home(Z_AXIS); - - // Stow the probe, as the last call to probe.probe_at_point(...) left - // the probe deployed if it was successful. - probe.stow(); - - // Home Z after the alignment procedure - process_subcommands_now_P(PSTR("G28 Z")); - }while(0); - - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("<<< G34"); } /** @@ -363,15 +422,22 @@ void GcodeSuite::G34() { * S and W require an X and/or Y parameter * X : X position to set (Unchanged if omitted) * Y : Y position to set (Unchanged if omitted) + * + * R : Recalculate points based on current probe offsets */ void GcodeSuite::M422() { + if (parser.seen('R')) { + z_stepper_align.reset_to_default(); + return; + } + if (!parser.seen_any()) { - for (uint8_t i = 0; i < NUM_Z_STEPPER_DRIVERS; ++i) - SERIAL_ECHOLNPAIR_P(PSTR("M422 S"), i + '1', SP_X_STR, z_stepper_align.xy[i].x, SP_Y_STR, z_stepper_align.xy[i].y); + LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS) + SERIAL_ECHOLNPAIR_P(PSTR("M422 S"), int(i + 1), SP_X_STR, z_stepper_align.xy[i].x, SP_Y_STR, z_stepper_align.xy[i].y); #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS) - for (uint8_t i = 0; i < NUM_Z_STEPPER_DRIVERS; ++i) - SERIAL_ECHOLNPAIR_P(PSTR("M422 W"), i + '1', SP_X_STR, z_stepper_align.stepper_xy[i].x, SP_Y_STR, z_stepper_align.stepper_xy[i].y); + LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS) + SERIAL_ECHOLNPAIR_P(PSTR("M422 W"), int(i + 1), SP_X_STR, z_stepper_align.stepper_xy[i].x, SP_Y_STR, z_stepper_align.stepper_xy[i].y); #endif return; } @@ -432,11 +498,11 @@ void GcodeSuite::M422() { }; if (is_probe_point) { - if (!position_is_reachable_by_probe(pos.x, Y_CENTER)) { + if (!probe.can_reach(pos.x, Y_CENTER)) { SERIAL_ECHOLNPGM("?(X) out of bounds."); return; } - if (!position_is_reachable_by_probe(pos)) { + if (!probe.can_reach(pos)) { SERIAL_ECHOLNPGM("?(Y) out of bounds."); return; } diff --git a/Marlin/src/gcode/calibrate/G425.cpp b/Marlin/src/gcode/calibrate/G425.cpp index d2db4ce30869..8968f789995f 100644 --- a/Marlin/src/gcode/calibrate/G425.cpp +++ b/Marlin/src/gcode/calibrate/G425.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -37,6 +37,20 @@ #include "../../module/endstops.h" #include "../../feature/bedlevel/bedlevel.h" +#if !AXIS_CAN_CALIBRATE(X) + #undef CALIBRATION_MEASURE_LEFT + #undef CALIBRATION_MEASURE_RIGHT +#endif + +#if !AXIS_CAN_CALIBRATE(Y) + #undef CALIBRATION_MEASURE_FRONT + #undef CALIBRATION_MEASURE_BACK +#endif + +#if !AXIS_CAN_CALIBRATE(Z) + #undef CALIBRATION_MEASURE_AT_TOP_EDGES +#endif + /** * G425 backs away from the calibration object by various distances * depending on the confidence level: @@ -56,8 +70,12 @@ #define CALIBRATION_MEASUREMENT_CERTAIN 0.5 // mm #endif -#define HAS_X_CENTER BOTH(CALIBRATION_MEASURE_LEFT, CALIBRATION_MEASURE_RIGHT) -#define HAS_Y_CENTER BOTH(CALIBRATION_MEASURE_FRONT, CALIBRATION_MEASURE_BACK) +#if BOTH(CALIBRATION_MEASURE_LEFT, CALIBRATION_MEASURE_RIGHT) + #define HAS_X_CENTER 1 +#endif +#if BOTH(CALIBRATION_MEASURE_FRONT, CALIBRATION_MEASURE_BACK) + #define HAS_Y_CENTER 1 +#endif enum side_t : uint8_t { TOP, RIGHT, FRONT, LEFT, BACK, NUM_SIDES }; @@ -74,8 +92,6 @@ struct measurements_t { xy_float_t nozzle_outer_dimension = nod; }; -#define TEMPORARY_SOFT_ENDSTOP_STATE(enable) REMEMBER(tes, soft_endstops_enabled, enable); - #if ENABLED(BACKLASH_GCODE) #define TEMPORARY_BACKLASH_CORRECTION(value) REMEMBER(tbst, backlash.correction, value) #else @@ -108,7 +124,7 @@ inline void park_above_object(measurements_t &m, const float uncertainty) { calibration_move(); } -#if HOTENDS > 1 +#if HAS_MULTI_HOTEND inline void set_nozzle(measurements_t &m, const uint8_t extruder) { if (extruder != active_extruder) { park_above_object(m, CALIBRATION_MEASUREMENT_UNKNOWN); @@ -120,7 +136,7 @@ inline void park_above_object(measurements_t &m, const float uncertainty) { #if HAS_HOTEND_OFFSET inline void normalize_hotend_offsets() { - for (uint8_t e = 1; e < HOTENDS; e++) + LOOP_S_L_N(e, 1, HOTENDS) hotend_offset[e] -= hotend_offset[0]; hotend_offset[0].reset(); } @@ -203,42 +219,52 @@ inline float measure(const AxisEnum axis, const int dir, const bool stop_state, inline void probe_side(measurements_t &m, const float uncertainty, const side_t side, const bool probe_top_at_edge=false) { const xyz_float_t dimensions = CALIBRATION_OBJECT_DIMENSIONS; AxisEnum axis; - float dir; + float dir = 1; park_above_object(m, uncertainty); switch (side) { - case TOP: { - const float measurement = measure(Z_AXIS, -1, true, &m.backlash[TOP], uncertainty); - m.obj_center.z = measurement - dimensions.z / 2; - m.obj_side[TOP] = measurement; - return; - } - case RIGHT: axis = X_AXIS; dir = -1; break; - case FRONT: axis = Y_AXIS; dir = 1; break; - case LEFT: axis = X_AXIS; dir = 1; break; - case BACK: axis = Y_AXIS; dir = -1; break; + #if AXIS_CAN_CALIBRATE(Z) + case TOP: { + const float measurement = measure(Z_AXIS, -1, true, &m.backlash[TOP], uncertainty); + m.obj_center.z = measurement - dimensions.z / 2; + m.obj_side[TOP] = measurement; + return; + } + #endif + #if AXIS_CAN_CALIBRATE(X) + case LEFT: axis = X_AXIS; break; + case RIGHT: axis = X_AXIS; dir = -1; break; + #endif + #if AXIS_CAN_CALIBRATE(Y) + case FRONT: axis = Y_AXIS; break; + case BACK: axis = Y_AXIS; dir = -1; break; + #endif default: return; } if (probe_top_at_edge) { - // Probe top nearest the side we are probing - current_position[axis] = m.obj_center[axis] + (-dir) * (dimensions[axis] / 2 - m.nozzle_outer_dimension[axis]); - calibration_move(); - m.obj_side[TOP] = measure(Z_AXIS, -1, true, &m.backlash[TOP], uncertainty); - m.obj_center.z = m.obj_side[TOP] - dimensions.z / 2; + #if AXIS_CAN_CALIBRATE(Z) + // Probe top nearest the side we are probing + current_position[axis] = m.obj_center[axis] + (-dir) * (dimensions[axis] / 2 - m.nozzle_outer_dimension[axis]); + calibration_move(); + m.obj_side[TOP] = measure(Z_AXIS, -1, true, &m.backlash[TOP], uncertainty); + m.obj_center.z = m.obj_side[TOP] - dimensions.z / 2; + #endif } - // Move to safe distance to the side of the calibration object - current_position[axis] = m.obj_center[axis] + (-dir) * (dimensions[axis] / 2 + m.nozzle_outer_dimension[axis] / 2 + uncertainty); - calibration_move(); + if ((AXIS_CAN_CALIBRATE(X) && axis == X_AXIS) || (AXIS_CAN_CALIBRATE(Y) && axis == Y_AXIS)) { + // Move to safe distance to the side of the calibration object + current_position[axis] = m.obj_center[axis] + (-dir) * (dimensions[axis] / 2 + m.nozzle_outer_dimension[axis] / 2 + uncertainty); + calibration_move(); - // Plunge below the side of the calibration object and measure - current_position.z = m.obj_side[TOP] - CALIBRATION_NOZZLE_TIP_HEIGHT * 0.7; - calibration_move(); - const float measurement = measure(axis, dir, true, &m.backlash[side], uncertainty); - m.obj_center[axis] = measurement + dir * (dimensions[axis] / 2 + m.nozzle_outer_dimension[axis] / 2); - m.obj_side[side] = measurement; + // Plunge below the side of the calibration object and measure + current_position.z = m.obj_side[TOP] - (CALIBRATION_NOZZLE_TIP_HEIGHT) * 0.7f; + calibration_move(); + const float measurement = measure(axis, dir, true, &m.backlash[side], uncertainty); + m.obj_center[axis] = measurement + dir * (dimensions[axis] / 2 + m.nozzle_outer_dimension[axis] / 2); + m.obj_side[side] = measurement; + } } /** @@ -248,7 +274,7 @@ inline void probe_side(measurements_t &m, const float uncertainty, const side_t * uncertainty in - How far away from the calibration object to begin probing */ inline void probe_sides(measurements_t &m, const float uncertainty) { - #ifdef CALIBRATION_MEASURE_AT_TOP_EDGES + #if ENABLED(CALIBRATION_MEASURE_AT_TOP_EDGES) constexpr bool probe_top_at_edge = true; #else // Probing at the exact center only works if the center is flat. Probing on a washer @@ -257,37 +283,19 @@ inline void probe_sides(measurements_t &m, const float uncertainty) { probe_side(m, uncertainty, TOP); #endif - #ifdef CALIBRATION_MEASURE_RIGHT - probe_side(m, uncertainty, RIGHT, probe_top_at_edge); - #endif - - #ifdef CALIBRATION_MEASURE_FRONT - probe_side(m, uncertainty, FRONT, probe_top_at_edge); - #endif - - #ifdef CALIBRATION_MEASURE_LEFT - probe_side(m, uncertainty, LEFT, probe_top_at_edge); - #endif - #ifdef CALIBRATION_MEASURE_BACK - probe_side(m, uncertainty, BACK, probe_top_at_edge); - #endif + TERN_(CALIBRATION_MEASURE_RIGHT, probe_side(m, uncertainty, RIGHT, probe_top_at_edge)); + TERN_(CALIBRATION_MEASURE_FRONT, probe_side(m, uncertainty, FRONT, probe_top_at_edge)); + TERN_(CALIBRATION_MEASURE_LEFT, probe_side(m, uncertainty, LEFT, probe_top_at_edge)); + TERN_(CALIBRATION_MEASURE_BACK, probe_side(m, uncertainty, BACK, probe_top_at_edge)); // Compute the measured center of the calibration object. - #if HAS_X_CENTER - m.obj_center.x = (m.obj_side[LEFT] + m.obj_side[RIGHT]) / 2; - #endif - #if HAS_Y_CENTER - m.obj_center.y = (m.obj_side[FRONT] + m.obj_side[BACK]) / 2; - #endif + TERN_(HAS_X_CENTER, m.obj_center.x = (m.obj_side[LEFT] + m.obj_side[RIGHT]) / 2); + TERN_(HAS_Y_CENTER, m.obj_center.y = (m.obj_side[FRONT] + m.obj_side[BACK]) / 2); // Compute the outside diameter of the nozzle at the height // at which it makes contact with the calibration object - #if HAS_X_CENTER - m.nozzle_outer_dimension.x = m.obj_side[RIGHT] - m.obj_side[LEFT] - dimensions.x; - #endif - #if HAS_Y_CENTER - m.nozzle_outer_dimension.y = m.obj_side[BACK] - m.obj_side[FRONT] - dimensions.y; - #endif + TERN_(HAS_X_CENTER, m.nozzle_outer_dimension.x = m.obj_side[RIGHT] - m.obj_side[LEFT] - dimensions.x); + TERN_(HAS_Y_CENTER, m.nozzle_outer_dimension.y = m.obj_side[BACK] - m.obj_side[FRONT] - dimensions.y); park_above_object(m, uncertainty); @@ -309,7 +317,9 @@ inline void probe_sides(measurements_t &m, const float uncertainty) { #if ENABLED(CALIBRATION_REPORTING) inline void report_measured_faces(const measurements_t &m) { SERIAL_ECHOLNPGM("Sides:"); - SERIAL_ECHOLNPAIR(" Top: ", m.obj_side[TOP]); + #if AXIS_CAN_CALIBRATE(Z) + SERIAL_ECHOLNPAIR(" Top: ", m.obj_side[TOP]); + #endif #if ENABLED(CALIBRATION_MEASURE_LEFT) SERIAL_ECHOLNPAIR(" Left: ", m.obj_side[LEFT]); #endif @@ -339,19 +349,25 @@ inline void probe_sides(measurements_t &m, const float uncertainty) { inline void report_measured_backlash(const measurements_t &m) { SERIAL_ECHOLNPGM("Backlash:"); - #if ENABLED(CALIBRATION_MEASURE_LEFT) - SERIAL_ECHOLNPAIR(" Left: ", m.backlash[LEFT]); - #endif - #if ENABLED(CALIBRATION_MEASURE_RIGHT) - SERIAL_ECHOLNPAIR(" Right: ", m.backlash[RIGHT]); + #if AXIS_CAN_CALIBRATE(X) + #if ENABLED(CALIBRATION_MEASURE_LEFT) + SERIAL_ECHOLNPAIR(" Left: ", m.backlash[LEFT]); + #endif + #if ENABLED(CALIBRATION_MEASURE_RIGHT) + SERIAL_ECHOLNPAIR(" Right: ", m.backlash[RIGHT]); + #endif #endif - #if ENABLED(CALIBRATION_MEASURE_FRONT) - SERIAL_ECHOLNPAIR(" Front: ", m.backlash[FRONT]); + #if AXIS_CAN_CALIBRATE(Y) + #if ENABLED(CALIBRATION_MEASURE_FRONT) + SERIAL_ECHOLNPAIR(" Front: ", m.backlash[FRONT]); + #endif + #if ENABLED(CALIBRATION_MEASURE_BACK) + SERIAL_ECHOLNPAIR(" Back: ", m.backlash[BACK]); + #endif #endif - #if ENABLED(CALIBRATION_MEASURE_BACK) - SERIAL_ECHOLNPAIR(" Back: ", m.backlash[BACK]); + #if AXIS_CAN_CALIBRATE(Z) + SERIAL_ECHOLNPAIR(" Top: ", m.backlash[TOP]); #endif - SERIAL_ECHOLNPAIR(" Top: ", m.backlash[TOP]); SERIAL_EOL(); } @@ -365,7 +381,7 @@ inline void probe_sides(measurements_t &m, const float uncertainty) { #if HAS_Y_CENTER SERIAL_ECHOLNPAIR_P(SP_Y_STR, m.pos_error.y); #endif - SERIAL_ECHOLNPAIR_P(SP_Z_STR, m.pos_error.z); + if (AXIS_CAN_CALIBRATE(Z)) SERIAL_ECHOLNPAIR_P(SP_Z_STR, m.pos_error.z); SERIAL_EOL(); } @@ -389,7 +405,7 @@ inline void probe_sides(measurements_t &m, const float uncertainty) { // This function requires normalize_hotend_offsets() to be called // inline void report_hotend_offsets() { - for (uint8_t e = 1; e < HOTENDS; e++) + LOOP_S_L_N(e, 1, HOTENDS) SERIAL_ECHOLNPAIR_P(PSTR("T"), int(e), PSTR(" Hotend Offset X"), hotend_offset[e].x, SP_Y_STR, hotend_offset[e].y, SP_Z_STR, hotend_offset[e].z); } #endif @@ -413,6 +429,7 @@ inline void calibrate_backlash(measurements_t &m, const float uncertainty) { probe_sides(m, uncertainty); #if ENABLED(BACKLASH_GCODE) + #if HAS_X_CENTER backlash.distance_mm.x = (m.backlash[LEFT] + m.backlash[RIGHT]) / 2; #elif ENABLED(CALIBRATION_MEASURE_LEFT) @@ -429,18 +446,18 @@ inline void calibrate_backlash(measurements_t &m, const float uncertainty) { backlash.distance_mm.y = m.backlash[BACK]; #endif - backlash.distance_mm.z = m.backlash[TOP]; + if (AXIS_CAN_CALIBRATE(Z)) backlash.distance_mm.z = m.backlash[TOP]; #endif } #if ENABLED(BACKLASH_GCODE) // Turn on backlash compensation and move in all - // directions to take up any backlash + // allowed directions to take up any backlash { // New scope for TEMPORARY_BACKLASH_CORRECTION TEMPORARY_BACKLASH_CORRECTION(all_on); TEMPORARY_BACKLASH_SMOOTHING(0.0f); - const xyz_float_t move = { 3, 3, 3 }; + const xyz_float_t move = { AXIS_CAN_CALIBRATE(X) * 3, AXIS_CAN_CALIBRATE(Y) * 3, AXIS_CAN_CALIBRATE(Z) * 3 }; current_position += move; calibration_move(); current_position -= move; calibration_move(); } @@ -468,7 +485,7 @@ inline void calibrate_toolhead(measurements_t &m, const float uncertainty, const TEMPORARY_BACKLASH_CORRECTION(all_on); TEMPORARY_BACKLASH_SMOOTHING(0.0f); - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND set_nozzle(m, extruder); #else UNUSED(extruder); @@ -478,26 +495,18 @@ inline void calibrate_toolhead(measurements_t &m, const float uncertainty, const // Adjust the hotend offset #if HAS_HOTEND_OFFSET - #if HAS_X_CENTER - hotend_offset[extruder].x += m.pos_error.x; - #endif - #if HAS_Y_CENTER - hotend_offset[extruder].y += m.pos_error.y; - #endif - hotend_offset[extruder].z += m.pos_error.z; + if (ENABLED(HAS_X_CENTER) && AXIS_CAN_CALIBRATE(X)) hotend_offset[extruder].x += m.pos_error.x; + if (ENABLED(HAS_Y_CENTER) && AXIS_CAN_CALIBRATE(Y)) hotend_offset[extruder].y += m.pos_error.y; + if (AXIS_CAN_CALIBRATE(Z)) hotend_offset[extruder].z += m.pos_error.z; normalize_hotend_offsets(); #endif // Correct for positional error, so the object // is at the known actual spot planner.synchronize(); - #if HAS_X_CENTER - update_measurements(m, X_AXIS); - #endif - #if HAS_Y_CENTER - update_measurements(m, Y_AXIS); - #endif - update_measurements(m, Z_AXIS); + if (ENABLED(HAS_X_CENTER) && AXIS_CAN_CALIBRATE(X)) update_measurements(m, X_AXIS); + if (ENABLED(HAS_Y_CENTER) && AXIS_CAN_CALIBRATE(Y)) update_measurements(m, Y_AXIS); + if (AXIS_CAN_CALIBRATE(Z)) update_measurements(m, Z_AXIS); sync_plan_position(); } @@ -515,13 +524,9 @@ inline void calibrate_all_toolheads(measurements_t &m, const float uncertainty) HOTEND_LOOP() calibrate_toolhead(m, uncertainty, e); - #if HAS_HOTEND_OFFSET - normalize_hotend_offsets(); - #endif + TERN_(HAS_HOTEND_OFFSET, normalize_hotend_offsets()); - #if HOTENDS > 1 - set_nozzle(m, 0); - #endif + TERN_(HAS_MULTI_HOTEND, set_nozzle(m, 0)); } /** @@ -538,9 +543,7 @@ inline void calibrate_all_toolheads(measurements_t &m, const float uncertainty) inline void calibrate_all() { measurements_t m; - #if HAS_HOTEND_OFFSET - reset_hotend_offsets(); - #endif + TERN_(HAS_HOTEND_OFFSET, reset_hotend_offsets()); TEMPORARY_BACKLASH_CORRECTION(all_on); TEMPORARY_BACKLASH_SMOOTHING(0.0f); @@ -548,12 +551,10 @@ inline void calibrate_all() { // Do a fast and rough calibration of the toolheads calibrate_all_toolheads(m, CALIBRATION_MEASUREMENT_UNKNOWN); - #if ENABLED(BACKLASH_GCODE) - calibrate_backlash(m, CALIBRATION_MEASUREMENT_UNCERTAIN); - #endif + TERN_(BACKLASH_GCODE, calibrate_backlash(m, CALIBRATION_MEASUREMENT_UNCERTAIN)); // Cycle the toolheads so the servos settle into their "natural" positions - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND HOTEND_LOOP() set_nozzle(m, e); #endif @@ -575,13 +576,17 @@ inline void calibrate_all() { * no args - Perform entire calibration sequence (backlash + position on all toolheads) */ void GcodeSuite::G425() { - TEMPORARY_SOFT_ENDSTOP_STATE(false); - TEMPORARY_BED_LEVELING_STATE(false); - if (axis_unhomed_error()) return; + #ifdef CALIBRATION_SCRIPT_PRE + GcodeSuite::process_subcommands_now_P(PSTR(CALIBRATION_SCRIPT_PRE)); + #endif - measurements_t m; + if (homing_needed_error()) return; + + TEMPORARY_BED_LEVELING_STATE(false); + SET_SOFT_ENDSTOP_LOOSE(true); + measurements_t m; float uncertainty = parser.seenval('U') ? parser.value_float() : CALIBRATION_MEASUREMENT_UNCERTAIN; if (parser.seen('B')) @@ -605,6 +610,12 @@ void GcodeSuite::G425() { #endif else calibrate_all(); + + SET_SOFT_ENDSTOP_LOOSE(false); + + #ifdef CALIBRATION_SCRIPT_POST + GcodeSuite::process_subcommands_now_P(PSTR(CALIBRATION_SCRIPT_POST)); + #endif } #endif // CALIBRATION_GCODE diff --git a/Marlin/src/gcode/calibrate/G76_M871.cpp b/Marlin/src/gcode/calibrate/G76_M192_M871.cpp similarity index 51% rename from Marlin/src/gcode/calibrate/G76_M871.cpp rename to Marlin/src/gcode/calibrate/G76_M192_M871.cpp index 4340084ec6d4..89393b4582c1 100644 --- a/Marlin/src/gcode/calibrate/G76_M871.cpp +++ b/Marlin/src/gcode/calibrate/G76_M192_M871.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -35,7 +35,18 @@ #include "../../feature/bedlevel/bedlevel.h" #include "../../module/temperature.h" #include "../../module/probe.h" -#include "../../feature/probe_temp_compensation.h" +#include "../../feature/probe_temp_comp.h" + +#include "../../lcd/ultralcd.h" +#include "../../MarlinCore.h" // for wait_for_heatup and idle() + +#if ENABLED(PRINTJOB_TIMER_AUTOSTART) + #include "../../module/printcounter.h" +#endif + +#if ENABLED(PRINTER_EVENTS_LEDS) + #include "../../feature/leds/leds.h" +#endif /** * G76: calibrate probe and/or bed temperature offsets @@ -45,7 +56,7 @@ * - When calibrating bed, probe temperature is held constant. * Compensation values are deltas to first probe measurement at bed temp. = 60°C. * - The hotend will not be heated at any time. - * - On my Prusa MK3S clone I put a piece of paper between the probe and the hotend + * - On my Průša MK3S clone I put a piece of paper between the probe and the hotend * so the hotend fan would not cool my probe constantly. Alternativly you could just * make sure the fan is not running while running the calibration process. * @@ -86,163 +97,133 @@ void GcodeSuite::G76() { return; #endif + auto report_temps = [](millis_t &ntr, millis_t timeout=0) { + idle_no_sleep(); + const millis_t ms = millis(); + if (ELAPSED(ms, ntr)) { + ntr = ms + 1000; + thermalManager.print_heater_states(active_extruder); + } + return (timeout && ELAPSED(ms, timeout)); + }; + + auto wait_for_temps = [&](const float tb, const float tp, millis_t &ntr, const millis_t timeout=0) { + SERIAL_ECHOLNPGM("Waiting for bed and probe temperature."); + while (fabs(thermalManager.degBed() - tb) > 0.1f || thermalManager.degProbe() > tp) + if (report_temps(ntr, timeout)) return true; + return false; + }; + + auto g76_probe = [](const TempSensorID sid, uint16_t &targ, const xy_pos_t &nozpos) { + do_z_clearance(5.0); // Raise nozzle before probing + const float measured_z = probe.probe_at_point(nozpos, PROBE_PT_STOW, 0, false); // verbose=0, probe_relative=false + if (isnan(measured_z)) + SERIAL_ECHOLNPGM("!Received NAN. Aborting."); + else { + SERIAL_ECHOLNPAIR_F("Measured: ", measured_z); + if (targ == cali_info_init[sid].start_temp) + temp_comp.prepare_new_calibration(measured_z); + else + temp_comp.push_back_new_measurement(sid, measured_z); + targ += cali_info_init[sid].temp_res; + } + return measured_z; + }; + #if ENABLED(BLTOUCH) // Make sure any BLTouch error condition is cleared bltouch_command(BLTOUCH_RESET, BLTOUCH_RESET_DELAY); set_bltouch_deployed(false); #endif - bool do_bed_cal = parser.boolval('B'), - do_probe_cal = parser.boolval('P'); - if (!do_bed_cal && !do_probe_cal) - do_bed_cal = do_probe_cal = true; + bool do_bed_cal = parser.boolval('B'), do_probe_cal = parser.boolval('P'); + if (!do_bed_cal && !do_probe_cal) do_bed_cal = do_probe_cal = true; // Synchronize with planner planner.synchronize(); - // Report temperatures every second and handle heating timeouts - millis_t next_temp_report = millis() + 1000; + const xyz_pos_t parkpos = temp_comp.park_point, + probe_pos_xyz = xyz_pos_t(temp_comp.measure_point) + xyz_pos_t({ 0.0f, 0.0f, PTC_PROBE_HEATING_OFFSET }), + noz_pos_xyz = probe_pos_xyz - xy_pos_t(probe.offset_xy); // Nozzle position based on probe position if (do_bed_cal || do_probe_cal) { // Ensure park position is reachable - if (!position_is_reachable(ProbeTempComp::park_point.x, ProbeTempComp::park_point.y) - || !(WITHIN(ProbeTempComp::park_point.z, Z_MIN_POS - 0.001f, Z_MAX_POS + 0.001f)) - ) { - SERIAL_ECHOLNPGM("!Park position unreachable - aborting."); - return; + bool reachable = position_is_reachable(parkpos) || WITHIN(parkpos.z, Z_MIN_POS - fslop, Z_MAX_POS + fslop); + if (!reachable) + SERIAL_ECHOLNPGM("!Park"); + else { + // Ensure probe position is reachable + reachable = probe.can_reach(probe_pos_xyz); + if (!reachable) SERIAL_ECHOLNPGM("!Probe"); } - // Ensure probe position is reachable - destination.set( - temp_comp.measure_point_x - probe.offset_xy.x, - temp_comp.measure_point_y - probe.offset_xy.y - ); - if (!position_is_reachable_by_probe(destination)) { - SERIAL_ECHOLNPGM("!Probe position unreachable - aborting."); + + if (!reachable) { + SERIAL_ECHOLNPGM(" position unreachable - aborting."); return; } - G28(true); + process_subcommands_now_P(PSTR("G28")); } + remember_feedrate_scaling_off(); + + /****************************************** * Calibrate bed temperature offsets ******************************************/ + // Report temperatures every second and handle heating timeouts + millis_t next_temp_report = millis() + 1000; + + auto report_targets = [&](const uint16_t tb, const uint16_t tp) { + SERIAL_ECHOLNPAIR("Target Bed:", tb, " Probe:", tp); + }; + if (do_bed_cal) { - uint16_t target_bed = temp_comp.cali_info_init[TSI_BED].start_temp, + uint16_t target_bed = cali_info_init[TSI_BED].start_temp, target_probe = temp_comp.bed_calib_probe_temp; - SERIAL_ECHOLNPGM("Waiting for printer to cool down."); - while (thermalManager.degBed() > target_bed - || thermalManager.degProbe() > target_probe - ) { - idle( - #if ENABLED(ADVANCED_PAUSE_FEATURE) - true - #endif - ); - const millis_t ms = millis(); - if (ELAPSED(ms, next_temp_report)) { - thermalManager.print_heater_states(active_extruder); - next_temp_report = ms + 1000; - } - } + SERIAL_ECHOLNPGM("Waiting for cooling."); + while (thermalManager.degBed() > target_bed || thermalManager.degProbe() > target_probe) + report_temps(next_temp_report); // Disable leveling so it won't mess with us - #if HAS_LEVELING - set_bed_leveling_enabled(false); - #endif + TERN_(HAS_LEVELING, set_bed_leveling_enabled(false)); - bool timeout = false; - while (true) { + for (;;) { thermalManager.setTargetBed(target_bed); - SERIAL_ECHOLNPAIR("Target Bed: ", target_bed, "; Probe: ", target_probe); + report_targets(target_bed, target_probe); // Park nozzle - do_blocking_move_to(ProbeTempComp::park_point.x, ProbeTempComp::park_point.y, ProbeTempComp::park_point.z); + do_blocking_move_to(parkpos); // Wait for heatbed to reach target temp and probe to cool below target temp - SERIAL_ECHOLNPGM("Waiting for bed and probe to reach target temp."); - const millis_t probe_timeout_ms = millis() + 900UL * 1000UL; - while (fabs(thermalManager.degBed() - float(target_bed)) > 0.1 || thermalManager.degProbe() > target_probe) { - idle( - #if ENABLED(ADVANCED_PAUSE_FEATURE) - true - #endif - ); - const millis_t ms = millis(); - if (ELAPSED(ms, next_temp_report)) { - thermalManager.print_heater_states(active_extruder); - next_temp_report = ms + 1000; - } - if (ELAPSED(ms, probe_timeout_ms)) { - SERIAL_ECHOLNPGM("!Bed heating timeout."); - timeout = true; - break; - } - } - - if (timeout) break; - - // Move probe to probing point and wait for probe to reach target temp - destination.set(temp_comp.measure_point_x, temp_comp.measure_point_y, 0.5); - do_blocking_move_to(destination.x, destination.y, destination.z); - SERIAL_ECHOLNPGM("Waiting for probe heating."); - while (thermalManager.degProbe() < target_probe) { - idle( - #if ENABLED(ADVANCED_PAUSE_FEATURE) - true - #endif - ); - const millis_t ms = millis(); - if (ELAPSED(ms, next_temp_report)) { - thermalManager.print_heater_states(active_extruder); - next_temp_report = ms + 1000; - } - } - - // Raise nozzle before probing - destination.z = 5.0; - do_blocking_move_to_z(destination.z); - - // Do a single probe - remember_feedrate_scaling_off(); - const float measured_z = probe.probe_at_point( - destination.x + probe.offset_xy.x, - destination.y + probe.offset_xy.y, - PROBE_PT_NONE - ); - restore_feedrate_and_scaling(); - - if (isnan(measured_z)) { - SERIAL_ECHOLNPGM("!Received NAN measurement - aborting."); + if (wait_for_temps(target_bed, target_probe, next_temp_report, millis() + MIN_TO_MS(15))) { + SERIAL_ECHOLNPGM("!Bed heating timeout."); break; } - else - SERIAL_ECHOLNPAIR_F("Measured: ", measured_z); - if (target_bed == temp_comp.cali_info_init[TSI_BED].start_temp) - temp_comp.prepare_new_calibration(measured_z); - else - temp_comp.push_back_new_measurement(TSI_BED, measured_z); + // Move the nozzle to the probing point and wait for the probe to reach target temp + do_blocking_move_to(noz_pos_xyz); + SERIAL_ECHOLNPGM("Waiting for probe heating."); + while (thermalManager.degProbe() < target_probe) + report_temps(next_temp_report); - target_bed += temp_comp.cali_info_init[TSI_BED].temp_res; - if (target_bed > temp_comp.max_bed_temp) break; + const float measured_z = g76_probe(TSI_BED, target_bed, noz_pos_xyz); + if (isnan(measured_z) || target_bed > BED_MAX_TARGET) break; } SERIAL_ECHOLNPAIR("Retrieved measurements: ", temp_comp.get_index()); if (temp_comp.finish_calibration(TSI_BED)) SERIAL_ECHOLNPGM("Successfully calibrated bed."); else - SERIAL_ECHOLNPGM("!Failed to calibrated bed - reset calibration values."); + SERIAL_ECHOLNPGM("!Failed to calibrate bed. Values reset."); // Cleanup thermalManager.setTargetBed(0); - #if HAS_LEVELING - set_bed_leveling_enabled(true); - #endif + TERN_(HAS_LEVELING, set_bed_leveling_enabled(true)); } // do_bed_cal /******************************************** @@ -252,110 +233,58 @@ void GcodeSuite::G76() { if (do_probe_cal) { // Park nozzle - do_blocking_move_to(ProbeTempComp::park_point.x, ProbeTempComp::park_point.y, ProbeTempComp::park_point.z); + do_blocking_move_to(parkpos); // Initialize temperatures - uint16_t target_bed = temp_comp.probe_calib_bed_temp, - target_probe = temp_comp.cali_info_init[TSI_PROBE].start_temp; + const uint16_t target_bed = temp_comp.probe_calib_bed_temp; thermalManager.setTargetBed(target_bed); - SERIAL_ECHOLNPGM("Waiting for bed and probe temperature."); - while (fabs(thermalManager.degBed() - float(target_bed)) > 0.1f - || thermalManager.degProbe() > target_probe - ) { - idle( - #if ENABLED(ADVANCED_PAUSE_FEATURE) - true - #endif - ); - const millis_t ms = millis(); - if (ELAPSED(ms, next_temp_report)) { - thermalManager.print_heater_states(active_extruder); - next_temp_report = ms + 1000; - } - } + + uint16_t target_probe = cali_info_init[TSI_PROBE].start_temp; + + report_targets(target_bed, target_probe); + + // Wait for heatbed to reach target temp and probe to cool below target temp + wait_for_temps(target_bed, target_probe, next_temp_report); // Disable leveling so it won't mess with us - #if HAS_LEVELING - set_bed_leveling_enabled(false); - #endif + TERN_(HAS_LEVELING, set_bed_leveling_enabled(false)); bool timeout = false; - while (true) { + for (;;) { // Move probe to probing point and wait for it to reach target temperature - destination.set(temp_comp.measure_point_x, temp_comp.measure_point_y, 0.5); - do_blocking_move_to(destination); - - SERIAL_ECHOLNPAIR( - "Bed temp: ", target_bed, - "; Probe temp: ", target_probe, - " Waiting for probe heating." - ); + do_blocking_move_to(noz_pos_xyz); + SERIAL_ECHOLNPAIR("Waiting for probe heating. Bed:", target_bed, " Probe:", target_probe); const millis_t probe_timeout_ms = millis() + 900UL * 1000UL; while (thermalManager.degProbe() < target_probe) { - idle( - #if ENABLED(ADVANCED_PAUSE_FEATURE) - true - #endif - ); - const millis_t ms = millis(); - if (ELAPSED(ms, next_temp_report)) { - thermalManager.print_heater_states(active_extruder); - next_temp_report = ms + 1000; - } - if (ELAPSED(ms, probe_timeout_ms)) { - SERIAL_ECHOLNPGM("!Probe heating aborted due to timeout."); + if (report_temps(next_temp_report, probe_timeout_ms)) { + SERIAL_ECHOLNPGM("!Probe heating timed out."); timeout = true; break; } } - if (timeout) break; - // Raise nozzle before probing - destination.z = 5.0; - do_blocking_move_to_z(destination.z); - - // Do a single probe - remember_feedrate_scaling_off(); - const float measured_z = probe.probe_at_point( - destination.x + probe.offset_xy.x, - destination.y + probe.offset_xy.y, - PROBE_PT_NONE - ); - restore_feedrate_and_scaling(); - - if (isnan(measured_z)) { - SERIAL_ECHOLNPGM("!Received NAN measurement - aborting."); - break; - } - else - SERIAL_ECHOLNPAIR_F("Measured: ", measured_z); - - if (target_probe == temp_comp.cali_info_init[TSI_PROBE].start_temp) - temp_comp.prepare_new_calibration(measured_z); - else - temp_comp.push_back_new_measurement(TSI_PROBE, measured_z); - - target_probe += temp_comp.cali_info_init[TSI_PROBE].temp_res; - if (target_probe > temp_comp.cali_info_init[TSI_PROBE].end_temp) break; + const float measured_z = g76_probe(TSI_PROBE, target_probe, noz_pos_xyz); + if (isnan(measured_z) || target_probe > cali_info_init[TSI_PROBE].end_temp) break; } SERIAL_ECHOLNPAIR("Retrieved measurements: ", temp_comp.get_index()); if (temp_comp.finish_calibration(TSI_PROBE)) - SERIAL_ECHOLNPGM("Successfully calibrated probe."); + SERIAL_ECHOPGM("Successfully calibrated"); else - SERIAL_ECHOLNPGM("!Failed to calibrated probe."); + SERIAL_ECHOPGM("!Failed to calibrate"); + SERIAL_ECHOLNPGM(" probe."); // Cleanup thermalManager.setTargetBed(0); - #if HAS_LEVELING - set_bed_leveling_enabled(true); - #endif + TERN_(HAS_LEVELING, set_bed_leveling_enabled(true)); SERIAL_ECHOLNPGM("Final compensation values:"); temp_comp.print_offsets(); } // do_probe_cal + + restore_feedrate_and_scaling(); } /** @@ -385,17 +314,17 @@ void GcodeSuite::M871() { } else if (parser.seen("BPE")) { if (!parser.seenval('V')) return; - const int16_t val = parser.value_int(); + const int16_t offset_val = parser.value_int(); if (!parser.seenval('I')) return; const int16_t idx = parser.value_int(); const TempSensorID mod = (parser.seen('B') ? TSI_BED : - #if ENABLED(USE_TEMP_EXT_COMPENSATION) - parser.seen('E') ? TSI_EXT : - #endif - TSI_PROBE + #if ENABLED(USE_TEMP_EXT_COMPENSATION) + parser.seen('E') ? TSI_EXT : + #endif + TSI_PROBE ); - if (idx > 0 && temp_comp.set_offset(mod, idx - 1, val)) - SERIAL_ECHOLNPAIR("Set value: ", val); + if (idx > 0 && temp_comp.set_offset(mod, idx - 1, offset_val)) + SERIAL_ECHOLNPAIR("Set value: ", offset_val); else SERIAL_ECHOLNPGM("!Invalid index. Failed to set value (note: value at index 0 is constant)."); @@ -404,4 +333,25 @@ void GcodeSuite::M871() { temp_comp.print_offsets(); } +/** + * M192: Wait for probe temperature sensor to reach a target + * + * Select only one of these flags: + * R - Wait for heating or cooling + * S - Wait only for heating + */ +void GcodeSuite::M192() { + if (DEBUGGING(DRYRUN)) return; + + const bool no_wait_for_cooling = parser.seenval('S'); + if (!no_wait_for_cooling && ! parser.seenval('R')) { + SERIAL_ERROR_MSG("No target temperature set."); + return; + } + + const float target_temp = parser.value_celsius(); + ui.set_status_P(thermalManager.isProbeBelowTemp(target_temp) ? GET_TEXT(MSG_PROBE_HEATING) : GET_TEXT(MSG_PROBE_COOLING)); + thermalManager.wait_for_probe(target_temp, no_wait_for_cooling); +} + #endif // PROBE_TEMP_COMPENSATION diff --git a/Marlin/src/gcode/calibrate/M100.cpp b/Marlin/src/gcode/calibrate/M100.cpp index 274caeec1ddc..9ac2380e7964 100644 --- a/Marlin/src/gcode/calibrate/M100.cpp +++ b/Marlin/src/gcode/calibrate/M100.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -26,7 +26,7 @@ #include "../gcode.h" #include "../queue.h" -#include "../../libs/hex_print_routines.h" +#include "../../libs/hex_print.h" #include "../../MarlinCore.h" // for idle() @@ -60,7 +60,7 @@ #define TEST_BYTE ((char) 0xE5) -#if defined(__AVR__) || IS_32BIT_TEENSY +#if EITHER(__AVR__, IS_32BIT_TEENSY) extern char __bss_end; char *end_bss = &__bss_end, @@ -116,13 +116,18 @@ // Utility functions // -// Location of a variable on its stack frame. Returns a value above -// the stack (once the function returns to the caller). -char* top_of_stack() { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wreturn-local-addr" + +// Location of a variable in its stack frame. +// The returned address will be above the stack (after it returns). +char *top_of_stack() { char x; return &x + 1; // x is pulled on return; } +#pragma GCC diagnostic pop + // Count the number of test bytes at the specified location. inline int32_t count_test_bytes(const char * const start_free_memory) { for (uint32_t i = 0; i < 32000; i++) @@ -151,21 +156,21 @@ inline int32_t count_test_bytes(const char * const start_free_memory) { // Start and end the dump on a nice 16 byte boundary // (even though the values are not 16-byte aligned). // - start_free_memory = (char*)(ptr_int_t(uint32_t(start_free_memory) & ~0xFUL)); // Align to 16-byte boundary - end_free_memory = (char*)(ptr_int_t(uint32_t(end_free_memory) | 0xFUL)); // Align end_free_memory to the 15th byte (at or above end_free_memory) + start_free_memory = (char*)(uintptr_t(uint32_t(start_free_memory) & ~0xFUL)); // Align to 16-byte boundary + end_free_memory = (char*)(uintptr_t(uint32_t(end_free_memory) | 0xFUL)); // Align end_free_memory to the 15th byte (at or above end_free_memory) // Dump command main loop while (start_free_memory < end_free_memory) { print_hex_address(start_free_memory); // Print the address SERIAL_CHAR(':'); - for (uint8_t i = 0; i < 16; i++) { // and 16 data bytes + LOOP_L_N(i, 16) { // and 16 data bytes if (i == 8) SERIAL_CHAR('-'); print_hex_byte(start_free_memory[i]); SERIAL_CHAR(' '); } serial_delay(25); SERIAL_CHAR('|'); // Point out non test bytes - for (uint8_t i = 0; i < 16; i++) { + LOOP_L_N(i, 16) { char ccc = (char)start_free_memory[i]; // cast to char before automatically casting to char on assignment, in case the compiler is broken ccc = (ccc == TEST_BYTE) ? ' ' : '?'; SERIAL_CHAR(ccc); @@ -184,8 +189,8 @@ inline int32_t count_test_bytes(const char * const start_free_memory) { // Round the start and end locations to produce full lines of output // dump_free_memory( - (char*)(ptr_int_t(uint32_t(start) & ~0xFUL)), // Align to 16-byte boundary - (char*)(ptr_int_t(uint32_t(end) | 0xFUL)) // Align end_free_memory to the 15th byte (at or above end_free_memory) + (char*)(uintptr_t(uint32_t(start) & ~0xFUL)), // Align to 16-byte boundary + (char*)(uintptr_t(uint32_t(end) | 0xFUL)) // Align end_free_memory to the 15th byte (at or above end_free_memory) ); } diff --git a/Marlin/src/gcode/calibrate/M12.cpp b/Marlin/src/gcode/calibrate/M12.cpp index 26f15bb89213..da244543754d 100644 --- a/Marlin/src/gcode/calibrate/M12.cpp +++ b/Marlin/src/gcode/calibrate/M12.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #include "../../inc/MarlinConfigPre.h" @@ -28,9 +28,12 @@ #include "../../feature/closedloop.h" void GcodeSuite::M12() { + planner.synchronize(); + if (parser.seenval('S')) - set_closedloop(parser.value_int()); // Force a CLC set + closedloop.set(parser.value_int()); // Force a CLC set + } #endif diff --git a/Marlin/src/gcode/calibrate/M425.cpp b/Marlin/src/gcode/calibrate/M425.cpp index a54c7cf746fc..40441ac08d16 100644 --- a/Marlin/src/gcode/calibrate/M425.cpp +++ b/Marlin/src/gcode/calibrate/M425.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -46,8 +46,17 @@ void GcodeSuite::M425() { bool noArgs = true; + auto axis_can_calibrate = [](const uint8_t a) { + switch (a) { + default: + case X_AXIS: return AXIS_CAN_CALIBRATE(X); + case Y_AXIS: return AXIS_CAN_CALIBRATE(Y); + case Z_AXIS: return AXIS_CAN_CALIBRATE(Z); + } + }; + LOOP_XYZ(a) { - if (parser.seen(axis_codes[a])) { + if (axis_can_calibrate(a) && parser.seen(XYZ_CHAR(a))) { planner.synchronize(); backlash.distance_mm[a] = parser.has_value() ? parser.value_linear_units() : backlash.get_measurement(AxisEnum(a)); noArgs = false; @@ -74,8 +83,8 @@ void GcodeSuite::M425() { SERIAL_ECHOLNPGM("active:"); SERIAL_ECHOLNPAIR(" Correction Amount/Fade-out: F", backlash.get_correction(), " (F1.0 = full, F0.0 = none)"); SERIAL_ECHOPGM(" Backlash Distance (mm): "); - LOOP_XYZ(a) { - SERIAL_CHAR(' ', axis_codes[a]); + LOOP_XYZ(a) if (axis_can_calibrate(a)) { + SERIAL_CHAR(' ', XYZ_CHAR(a)); SERIAL_ECHO(backlash.distance_mm[a]); SERIAL_EOL(); } @@ -87,8 +96,8 @@ void GcodeSuite::M425() { #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING) SERIAL_ECHOPGM(" Average measured backlash (mm):"); if (backlash.has_any_measurement()) { - LOOP_XYZ(a) if (backlash.has_measurement(AxisEnum(a))) { - SERIAL_CHAR(' ', axis_codes[a]); + LOOP_XYZ(a) if (axis_can_calibrate(a) && backlash.has_measurement(AxisEnum(a))) { + SERIAL_CHAR(' ', XYZ_CHAR(a)); SERIAL_ECHO(backlash.get_measurement(AxisEnum(a))); } } diff --git a/Marlin/src/gcode/calibrate/M48.cpp b/Marlin/src/gcode/calibrate/M48.cpp index 8fba7a646fe9..8640dfa39166 100644 --- a/Marlin/src/gcode/calibrate/M48.cpp +++ b/Marlin/src/gcode/calibrate/M48.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -27,13 +27,10 @@ #include "../gcode.h" #include "../../module/motion.h" #include "../../module/probe.h" +#include "../../lcd/ultralcd.h" #include "../../feature/bedlevel/bedlevel.h" -#if HAS_SPI_LCD - #include "../../lcd/ultralcd.h" -#endif - #if HAS_LEVELING #include "../../module/planner.h" #endif @@ -58,7 +55,7 @@ extern const char SP_Y_STR[]; void GcodeSuite::M48() { - if (axis_unhomed_error()) return; + if (homing_needed_error()) return; const int8_t verbose_level = parser.byteval('V', 1); if (!WITHIN(verbose_level, 0, 4)) { @@ -77,61 +74,85 @@ void GcodeSuite::M48() { const ProbePtRaise raise_after = parser.boolval('E') ? PROBE_PT_STOW : PROBE_PT_RAISE; - xy_float_t next_pos = current_position; - - const xy_pos_t probe_pos = { - parser.linearval('X', next_pos.x + probe.offset_xy.x), - parser.linearval('Y', next_pos.y + probe.offset_xy.y) + // Test at the current position by default, overridden by X and Y + const xy_pos_t test_position = { + parser.linearval('X', current_position.x + probe.offset_xy.x), // If no X use the probe's current X position + parser.linearval('Y', current_position.y + probe.offset_xy.y) // If no Y, ditto }; - if (!position_is_reachable_by_probe(probe_pos)) { + if (!probe.can_reach(test_position)) { + ui.set_status_P(GET_TEXT(MSG_M48_OUT_OF_BOUNDS), 99); SERIAL_ECHOLNPGM("? (X,Y) out of bounds."); return; } + // Get the number of leg moves per test-point bool seen_L = parser.seen('L'); uint8_t n_legs = seen_L ? parser.value_byte() : 0; if (n_legs > 15) { - SERIAL_ECHOLNPGM("?Number of legs in movement not plausible (0-15)."); + SERIAL_ECHOLNPGM("?Legs of movement implausible (0-15)."); return; } if (n_legs == 1) n_legs = 2; + // Schizoid motion as an optional stress-test const bool schizoid_flag = parser.boolval('S'); if (schizoid_flag && !seen_L) n_legs = 7; - /** - * Now get everything to the specified probe point So we can safely do a - * probe to get us close to the bed. If the Z-Axis is far from the bed, - * we don't want to use that as a starting point for each probe. - */ if (verbose_level > 2) SERIAL_ECHOLNPGM("Positioning the probe..."); - // Disable bed level correction in M48 because we want the raw data when we probe + // Always disable Bed Level correction before probing... #if HAS_LEVELING const bool was_enabled = planner.leveling_active; set_bed_leveling_enabled(false); #endif + // Work with reasonable feedrates remember_feedrate_scaling_off(); - float mean = 0.0, sigma = 0.0, min = 99999.9, max = -99999.9, sample_set[n_samples]; + // Working variables + float mean = 0.0, // The average of all points so far, used to calculate deviation + sigma = 0.0, // Standard deviation of all points so far + min = 99999.9, // Smallest value sampled so far + max = -99999.9, // Largest value sampled so far + sample_set[n_samples]; // Storage for sampled values + + auto dev_report = [](const bool verbose, const float &mean, const float &sigma, const float &min, const float &max, const bool final=false) { + if (verbose) { + SERIAL_ECHOPAIR_F("Mean: ", mean, 6); + if (!final) SERIAL_ECHOPAIR_F(" Sigma: ", sigma, 6); + SERIAL_ECHOPAIR_F(" Min: ", min, 3); + SERIAL_ECHOPAIR_F(" Max: ", max, 3); + SERIAL_ECHOPAIR_F(" Range: ", max-min, 3); + if (final) SERIAL_EOL(); + } + if (final) { + SERIAL_ECHOLNPAIR_F("Standard Deviation: ", sigma, 6); + SERIAL_EOL(); + } + }; // Move to the first point, deploy, and probe - const float t = probe.probe_at_point(probe_pos, raise_after, verbose_level); + const float t = probe.probe_at_point(test_position, raise_after, verbose_level); bool probing_good = !isnan(t); if (probing_good) { randomSeed(millis()); - for (uint8_t n = 0; n < n_samples; n++) { - #if HAS_SPI_LCD + float sample_sum = 0.0; + + LOOP_L_N(n, n_samples) { + #if HAS_WIRED_LCD // Display M48 progress in the status bar ui.status_printf_P(0, PSTR(S_FMT ": %d/%d"), GET_TEXT(MSG_M48_POINT), int(n + 1), int(n_samples)); #endif + + // When there are "legs" of movement move around the point before probing if (n_legs) { + + // Pick a random direction, starting angle, and radius const int dir = (random(0, 10) > 5.0) ? -1 : 1; // clockwise or counter clockwise float angle = random(0, 360); const float radius = random( @@ -142,48 +163,51 @@ void GcodeSuite::M48() { int(5), int(0.125 * _MIN(X_BED_SIZE, Y_BED_SIZE)) #endif ); - if (verbose_level > 3) { SERIAL_ECHOPAIR("Start radius:", radius, " angle:", angle, " dir:"); if (dir > 0) SERIAL_CHAR('C'); SERIAL_ECHOLNPGM("CW"); } - for (uint8_t l = 0; l < n_legs - 1; l++) { - float delta_angle; + // Move from leg to leg in rapid succession + LOOP_L_N(l, n_legs - 1) { + // Move some distance around the perimeter + float delta_angle; if (schizoid_flag) { - // The points of a 5 point star are 72 degrees apart. We need to - // skip a point and go to the next one on the star. + // The points of a 5 point star are 72 degrees apart. + // Skip a point and go to the next one on the star. delta_angle = dir * 2.0 * 72.0; } else { - // If we do this line, we are just trying to move further - // around the circle. - delta_angle = dir * (float) random(25, 45); + // Just move further along the perimeter. + delta_angle = dir * (float)random(25, 45); } - angle += delta_angle; - while (angle > 360.0) angle -= 360.0; // We probably do not need to keep the angle between 0 and 2*PI, but the - // Arduino documentation says the trig functions should not be given values - while (angle < 0.0) angle += 360.0; // outside of this range. It looks like they behave correctly with - // numbers outside of the range, but just to be safe we clamp them. - const xy_pos_t noz_pos = probe_pos - probe.offset_xy; - next_pos.set(noz_pos.x + cos(RADIANS(angle)) * radius, - noz_pos.y + sin(RADIANS(angle)) * radius); + // Trig functions work without clamping, but just to be safe... + while (angle > 360.0) angle -= 360.0; + while (angle < 0.0) angle += 360.0; - #if DISABLED(DELTA) - LIMIT(next_pos.x, X_MIN_POS, X_MAX_POS); - LIMIT(next_pos.y, Y_MIN_POS, Y_MAX_POS); - #else - // If we have gone out too far, we can do a simple fix and scale the numbers - // back in closer to the origin. - while (!position_is_reachable_by_probe(next_pos)) { + // Choose the next position as an offset to chosen test position + const xy_pos_t noz_pos = test_position - probe.offset_xy; + xy_pos_t next_pos = { + noz_pos.x + float(cos(RADIANS(angle))) * radius, + noz_pos.y + float(sin(RADIANS(angle))) * radius + }; + + #if ENABLED(DELTA) + // If the probe can't reach the point on a round bed... + // Simply scale the numbers to bring them closer to origin. + while (!probe.can_reach(next_pos)) { next_pos *= 0.8f; if (verbose_level > 3) SERIAL_ECHOLNPAIR_P(PSTR("Moving inward: X"), next_pos.x, SP_Y_STR, next_pos.y); } + #else + // For a rectangular bed just keep the probe in bounds + LIMIT(next_pos.x, X_MIN_POS, X_MAX_POS); + LIMIT(next_pos.y, Y_MIN_POS, Y_MAX_POS); #endif if (verbose_level > 3) @@ -194,45 +218,35 @@ void GcodeSuite::M48() { } // n_legs // Probe a single point - sample_set[n] = probe.probe_at_point(probe_pos, raise_after, 0); + const float pz = probe.probe_at_point(test_position, raise_after, 0); // Break the loop if the probe fails - probing_good = !isnan(sample_set[n]); + probing_good = !isnan(pz); if (!probing_good) break; - /** - * Get the current mean for the data points we have so far - */ - float sum = 0.0; - for (uint8_t j = 0; j <= n; j++) sum += sample_set[j]; - mean = sum / (n + 1); - - NOMORE(min, sample_set[n]); - NOLESS(max, sample_set[n]); - - /** - * Now, use that mean to calculate the standard deviation for the - * data points we have so far - */ - sum = 0.0; - for (uint8_t j = 0; j <= n; j++) - sum += sq(sample_set[j] - mean); - - sigma = SQRT(sum / (n + 1)); - if (verbose_level > 0) { - if (verbose_level > 1) { - SERIAL_ECHO(n + 1); - SERIAL_ECHOPAIR(" of ", int(n_samples)); - SERIAL_ECHOPAIR_F(": z: ", sample_set[n], 3); - if (verbose_level > 2) { - SERIAL_ECHOPAIR_F(" mean: ", mean, 4); - SERIAL_ECHOPAIR_F(" sigma: ", sigma, 6); - SERIAL_ECHOPAIR_F(" min: ", min, 3); - SERIAL_ECHOPAIR_F(" max: ", max, 3); - SERIAL_ECHOPAIR_F(" range: ", max-min, 3); - } - SERIAL_EOL(); - } + // Store the new sample + sample_set[n] = pz; + + // Keep track of the largest and smallest samples + NOMORE(min, pz); + NOLESS(max, pz); + + // Get the mean value of all samples thus far + sample_sum += pz; + mean = sample_sum / (n + 1); + + // Calculate the standard deviation so far. + // The value after the last sample will be the final output. + float dev_sum = 0.0; + LOOP_LE_N(j, n) dev_sum += sq(sample_set[j] - mean); + sigma = SQRT(dev_sum / (n + 1)); + + if (verbose_level > 1) { + SERIAL_ECHO(n + 1); + SERIAL_ECHOPAIR(" of ", int(n_samples)); + SERIAL_ECHOPAIR_F(": z: ", pz, 3); + dev_report(verbose_level > 2, mean, sigma, min, max); + SERIAL_EOL(); } } // n_samples loop @@ -242,18 +256,9 @@ void GcodeSuite::M48() { if (probing_good) { SERIAL_ECHOLNPGM("Finished!"); + dev_report(verbose_level > 0, mean, sigma, min, max, true); - if (verbose_level > 0) { - SERIAL_ECHOPAIR_F("Mean: ", mean, 6); - SERIAL_ECHOPAIR_F(" Min: ", min, 3); - SERIAL_ECHOPAIR_F(" Max: ", max, 3); - SERIAL_ECHOLNPAIR_F(" Range: ", max-min, 3); - } - - SERIAL_ECHOLNPAIR_F("Standard Deviation: ", sigma, 6); - SERIAL_EOL(); - - #if HAS_SPI_LCD + #if HAS_WIRED_LCD // Display M48 results in the status bar char sigma_str[8]; ui.status_printf_P(0, PSTR(S_FMT ": %s"), GET_TEXT(MSG_M48_DEVIATION), dtostrf(sigma, 2, 6, sigma_str)); @@ -263,9 +268,7 @@ void GcodeSuite::M48() { restore_feedrate_and_scaling(); // Re-enable bed level correction if it had been on - #if HAS_LEVELING - set_bed_leveling_enabled(was_enabled); - #endif + TERN_(HAS_LEVELING, set_bed_leveling_enabled(was_enabled)); report_current_position(); } diff --git a/Marlin/src/gcode/calibrate/M665.cpp b/Marlin/src/gcode/calibrate/M665.cpp index 0436736b4a13..557204cc1102 100644 --- a/Marlin/src/gcode/calibrate/M665.cpp +++ b/Marlin/src/gcode/calibrate/M665.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -38,8 +38,11 @@ * R = delta radius * S = segments per second * X = Alpha (Tower 1) angle trim - * Y = Beta (Tower 2) angle trim + * Y = Beta (Tower 2) angle trim * Z = Gamma (Tower 3) angle trim + * A = Alpha (Tower 1) digonal rod trim + * B = Beta (Tower 2) digonal rod trim + * C = Gamma (Tower 3) digonal rod trim */ void GcodeSuite::M665() { if (parser.seen('H')) delta_height = parser.value_linear_units(); @@ -49,6 +52,9 @@ if (parser.seen('X')) delta_tower_angle_trim.a = parser.value_float(); if (parser.seen('Y')) delta_tower_angle_trim.b = parser.value_float(); if (parser.seen('Z')) delta_tower_angle_trim.c = parser.value_float(); + if (parser.seen('A')) delta_diagonal_rod_trim.a = parser.value_float(); + if (parser.seen('B')) delta_diagonal_rod_trim.b = parser.value_float(); + if (parser.seen('C')) delta_diagonal_rod_trim.c = parser.value_float(); recalc_delta_settings(); } diff --git a/Marlin/src/gcode/calibrate/M666.cpp b/Marlin/src/gcode/calibrate/M666.cpp index 094b32708b4d..e915aa8ff7b7 100644 --- a/Marlin/src/gcode/calibrate/M666.cpp +++ b/Marlin/src/gcode/calibrate/M666.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -38,15 +38,14 @@ * M666: Set delta endstop adjustment */ void GcodeSuite::M666() { - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM(">>> M666"); + DEBUG_SECTION(log_M666, "M666", DEBUGGING(LEVELING)); LOOP_XYZ(i) { - if (parser.seen(axis_codes[i])) { + if (parser.seen(XYZ_CHAR(i))) { const float v = parser.value_linear_units(); if (v * Z_HOME_DIR <= 0) delta_endstop_adj[i] = v; - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("delta_endstop_adj[", axis_codes[i], "] = ", delta_endstop_adj[i]); + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("delta_endstop_adj[", XYZ_CHAR(i), "] = ", delta_endstop_adj[i]); } } - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("<<< M666"); } #elif HAS_EXTRA_ENDSTOPS diff --git a/Marlin/src/gcode/calibrate/M852.cpp b/Marlin/src/gcode/calibrate/M852.cpp index 865b03def394..b60f41748fec 100644 --- a/Marlin/src/gcode/calibrate/M852.cpp +++ b/Marlin/src/gcode/calibrate/M852.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/config/M200-M205.cpp b/Marlin/src/gcode/config/M200-M205.cpp index b9192198bd04..cb17fc45a6e8 100644 --- a/Marlin/src/gcode/config/M200-M205.cpp +++ b/Marlin/src/gcode/config/M200-M205.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -30,21 +30,42 @@ * M200: Set filament diameter and set E axis units to cubic units * * T - Optional extruder number. Current extruder if omitted. - * D - Diameter of the filament. Use "D0" to switch back to linear units on the E axis. + * D - Set filament diameter and enable. D0 disables volumetric. + * S - Turn volumetric ON or OFF. + * L - Volumetric extruder limit (in mm^3/sec). L0 disables the limit. */ void GcodeSuite::M200() { const int8_t target_extruder = get_target_extruder_from_command(); if (target_extruder < 0) return; - if (parser.seen('D')) { - // setting any extruder filament size disables volumetric on the assumption that - // slicers either generate in extruder values as cubic mm or as as filament feeds - // for all extruders + bool vol_enable = parser.volumetric_enabled, + can_enable = true; + + if (parser.seenval('D')) { const float dval = parser.value_linear_units(); - if ( (parser.volumetric_enabled = (dval != 0)) ) + if (dval) { // Set filament size for volumetric calculation planner.set_filament_size(target_extruder, dval); + vol_enable = true; // Dn = enable for compatibility + } + else + can_enable = false; // D0 = disable for compatibility } + + // Enable or disable with S1 / S0 + parser.volumetric_enabled = can_enable && parser.boolval('S', vol_enable); + + #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) + if (parser.seenval('L')) { + // Set volumetric limit (in mm^3/sec) + const float lval = parser.value_float(); + if (WITHIN(lval, 0, 20)) + planner.set_volumetric_extruder_limit(target_extruder, lval); + else + SERIAL_ECHOLNPGM("?L value out of range (0-20)."); + } + #endif + planner.calculate_volumetric_multipliers(); } @@ -60,6 +81,11 @@ void GcodeSuite::M201() { const int8_t target_extruder = get_target_extruder_from_command(); if (target_extruder < 0) return; + #ifdef XY_FREQUENCY_LIMIT + if (parser.seenval('F')) planner.set_frequency_limit(parser.value_byte()); + if (parser.seenval('G')) planner.xy_freq_min_speed_factor = constrain(parser.value_float(), 1, 100) / 100; + #endif + LOOP_XYZE(i) { if (parser.seen(axis_codes[i])) { const uint8_t a = (i == E_AXIS ? uint8_t(E_AXIS_N(target_extruder)) : i); @@ -121,7 +147,7 @@ void GcodeSuite::M204() { * J = Junction Deviation (mm) (If not using CLASSIC_JERK) */ void GcodeSuite::M205() { - #if DISABLED(CLASSIC_JERK) + #if HAS_JUNCTION_DEVIATION #define J_PARAM "J" #else #define J_PARAM @@ -137,14 +163,12 @@ void GcodeSuite::M205() { if (parser.seen('B')) planner.settings.min_segment_time_us = parser.value_ulong(); if (parser.seen('S')) planner.settings.min_feedrate_mm_s = parser.value_linear_units(); if (parser.seen('T')) planner.settings.min_travel_feedrate_mm_s = parser.value_linear_units(); - #if DISABLED(CLASSIC_JERK) + #if HAS_JUNCTION_DEVIATION if (parser.seen('J')) { const float junc_dev = parser.value_linear_units(); if (WITHIN(junc_dev, 0.01f, 0.3f)) { planner.junction_deviation_mm = junc_dev; - #if ENABLED(LIN_ADVANCE) - planner.recalculate_max_e_jerk(); - #endif + TERN_(LIN_ADVANCE, planner.recalculate_max_e_jerk()); } else SERIAL_ERROR_MSG("?J out of range (0.01 to 0.3)"); diff --git a/Marlin/src/gcode/config/M217.cpp b/Marlin/src/gcode/config/M217.cpp index 44e69c429843..b57dec31f360 100644 --- a/Marlin/src/gcode/config/M217.cpp +++ b/Marlin/src/gcode/config/M217.cpp @@ -16,17 +16,21 @@ * 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 . + * along with this program. If not, see . * */ #include "../../inc/MarlinConfigPre.h" -#if EXTRUDERS > 1 +#if HAS_MULTI_EXTRUDER #include "../gcode.h" #include "../../module/tool_change.h" +#if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) + #include "../../module/motion.h" +#endif + #include "../../MarlinCore.h" // for SP_X_STR, etc. extern const char SP_X_STR[], SP_Y_STR[], SP_Z_STR[]; @@ -36,15 +40,29 @@ void M217_report(const bool eeprom=false) { #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) serialprintPGM(eeprom ? PSTR(" M217") : PSTR("Toolchange:")); SERIAL_ECHOPAIR(" S", LINEAR_UNIT(toolchange_settings.swap_length)); - SERIAL_ECHOPAIR_P(SP_E_STR, LINEAR_UNIT(toolchange_settings.extra_prime)); - SERIAL_ECHOPAIR_P(SP_P_STR, LINEAR_UNIT(toolchange_settings.prime_speed)); - SERIAL_ECHOPAIR(" R", LINEAR_UNIT(toolchange_settings.retract_speed)); + SERIAL_ECHOPAIR_P(SP_B_STR, LINEAR_UNIT(toolchange_settings.extra_resume), + SP_E_STR, LINEAR_UNIT(toolchange_settings.extra_prime), + SP_P_STR, LINEAR_UNIT(toolchange_settings.prime_speed)); + SERIAL_ECHOPAIR(" R", LINEAR_UNIT(toolchange_settings.retract_speed), + " U", LINEAR_UNIT(toolchange_settings.unretract_speed), + " F", toolchange_settings.fan_speed, + " G", toolchange_settings.fan_time); + + #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) + SERIAL_ECHOPAIR(" A", int(migration.automode)); + SERIAL_ECHOPAIR(" L", LINEAR_UNIT(migration.last)); + #endif #if ENABLED(TOOLCHANGE_PARK) + SERIAL_ECHOPAIR(" W", LINEAR_UNIT(toolchange_settings.enable_park)); SERIAL_ECHOPAIR_P(SP_X_STR, LINEAR_UNIT(toolchange_settings.change_point.x)); SERIAL_ECHOPAIR_P(SP_Y_STR, LINEAR_UNIT(toolchange_settings.change_point.y)); #endif + #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED) + SERIAL_ECHOPAIR(" V", LINEAR_UNIT(enable_first_prime)); + #endif + #else UNUSED(eeprom); @@ -58,48 +76,98 @@ void M217_report(const bool eeprom=false) { /** * M217 - Set SINGLENOZZLE toolchange parameters * + * // Tool change command + * Q Prime active tool and exit + * + * // Tool change settings * S[linear] Swap length - * E[linear] Purge length + * B[linear] Extra Swap length + * E[linear] Prime length * P[linear/m] Prime speed * R[linear/m] Retract speed + * U[linear/m] UnRetract speed + * V[linear] 0/1 Enable auto prime first extruder used + * W[linear] 0/1 Enable park & Z Raise * X[linear] Park X (Requires TOOLCHANGE_PARK) * Y[linear] Park Y (Requires TOOLCHANGE_PARK) * Z[linear] Z Raise + * F[linear] Fan Speed 0-255 + * G[linear/s] Fan time + * + * Tool migration settings + * A[0|1] Enable auto-migration on runout + * L[index] Last extruder to use for auto-migration + * + * Tool migration command + * T[index] Migrate to next extruder or the given extruder */ void GcodeSuite::M217() { - #define SPR_PARAM - #define XY_PARAM - #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) - #undef SPR_PARAM - #define SPR_PARAM "SPRE" + static constexpr float max_extrude = TERN(PREVENT_LENGTHY_EXTRUDE, EXTRUDE_MAXLENGTH, 500); - static constexpr float max_extrude = - #if ENABLED(PREVENT_LENGTHY_EXTRUDE) - EXTRUDE_MAXLENGTH - #else - 500 - #endif - ; + if (parser.seen('Q')) { tool_change_prime(); return; } if (parser.seenval('S')) { const float v = parser.value_linear_units(); toolchange_settings.swap_length = constrain(v, 0, max_extrude); } + if (parser.seenval('B')) { const float v = parser.value_linear_units(); toolchange_settings.extra_resume = constrain(v, -10, 10); } if (parser.seenval('E')) { const float v = parser.value_linear_units(); toolchange_settings.extra_prime = constrain(v, 0, max_extrude); } if (parser.seenval('P')) { const int16_t v = parser.value_linear_units(); toolchange_settings.prime_speed = constrain(v, 10, 5400); } if (parser.seenval('R')) { const int16_t v = parser.value_linear_units(); toolchange_settings.retract_speed = constrain(v, 10, 5400); } + if (parser.seenval('U')) { const int16_t v = parser.value_linear_units(); toolchange_settings.unretract_speed = constrain(v, 10, 5400); } + #if TOOLCHANGE_FS_FAN >= 0 && HAS_FAN + if (parser.seenval('F')) { const int16_t v = parser.value_linear_units(); toolchange_settings.fan_speed = constrain(v, 0, 255); } + if (parser.seenval('G')) { const int16_t v = parser.value_linear_units(); toolchange_settings.fan_time = constrain(v, 1, 30); } + #endif + #endif + + #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED) + if (parser.seenval('V')) { enable_first_prime = parser.value_linear_units(); } #endif #if ENABLED(TOOLCHANGE_PARK) - #undef XY_PARAM - #define XY_PARAM "XY" - if (parser.seenval('X')) { toolchange_settings.change_point.x = parser.value_linear_units(); } - if (parser.seenval('Y')) { toolchange_settings.change_point.y = parser.value_linear_units(); } + if (parser.seenval('W')) { toolchange_settings.enable_park = parser.value_linear_units(); } + if (parser.seenval('X')) { const int16_t v = parser.value_linear_units(); toolchange_settings.change_point.x = constrain(v, X_MIN_POS, X_MAX_POS); } + if (parser.seenval('Y')) { const int16_t v = parser.value_linear_units(); toolchange_settings.change_point.y = constrain(v, Y_MIN_POS, Y_MAX_POS); } #endif if (parser.seenval('Z')) { toolchange_settings.z_raise = parser.value_linear_units(); } - if (!parser.seen(SPR_PARAM XY_PARAM "Z")) M217_report(); + #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) + migration.target = 0; // 0 = disabled + + if (parser.seenval('L')) { // Last + const int16_t lval = parser.value_int(); + if (WITHIN(lval, 0, EXTRUDERS - 1)) { + migration.last = lval; + migration.automode = (active_extruder < migration.last); + } + } + + if (parser.seen('A')) // Auto on/off + migration.automode = parser.value_bool(); + + if (parser.seen('T')) { // Migrate now + if (parser.has_value()) { + const int16_t tval = parser.value_int(); + if (WITHIN(tval, 0, EXTRUDERS - 1) && tval != active_extruder) { + migration.target = tval + 1; + extruder_migration(); + migration.target = 0; // disable + return; + } + else + migration.target = 0; // disable + } + else { + extruder_migration(); + return; + } + } + + #endif + + M217_report(); } -#endif // EXTRUDERS > 1 +#endif // HAS_MULTI_EXTRUDER diff --git a/Marlin/src/gcode/config/M218.cpp b/Marlin/src/gcode/config/M218.cpp index 5c7d5eac719c..7701320e9eae 100644 --- a/Marlin/src/gcode/config/M218.cpp +++ b/Marlin/src/gcode/config/M218.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/config/M220.cpp b/Marlin/src/gcode/config/M220.cpp index e09a5f7534d6..1bec6a778204 100644 --- a/Marlin/src/gcode/config/M220.cpp +++ b/Marlin/src/gcode/config/M220.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -29,6 +29,8 @@ * Parameters * S : Set the feed rate percentage factor * + * Report the current speed percentage factor if no parameter is specified + * * With PRUSA_MMU2... * B : Flag to back up the current factor * R : Flag to restore the last-saved factor @@ -43,4 +45,9 @@ void GcodeSuite::M220() { if (parser.seenval('S')) feedrate_percentage = parser.value_int(); + if (!parser.seen_any()) { + SERIAL_ECHOPAIR("FR:", feedrate_percentage); + SERIAL_CHAR('%'); + SERIAL_EOL(); + } } diff --git a/Marlin/src/gcode/config/M221.cpp b/Marlin/src/gcode/config/M221.cpp index 8522b544fc8b..7ba22d1901d5 100644 --- a/Marlin/src/gcode/config/M221.cpp +++ b/Marlin/src/gcode/config/M221.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -33,10 +33,8 @@ void GcodeSuite::M221() { const int8_t target_extruder = get_target_extruder_from_command(); if (target_extruder < 0) return; - if (parser.seenval('S')) { - planner.flow_percentage[target_extruder] = parser.value_int(); - planner.refresh_e_factor(target_extruder); - } + if (parser.seenval('S')) + planner.set_flow(target_extruder, parser.value_int()); else { SERIAL_ECHO_START(); SERIAL_CHAR('E', '0' + target_extruder); diff --git a/Marlin/src/gcode/config/M281.cpp b/Marlin/src/gcode/config/M281.cpp index e925cd5b1215..018ca1c0928d 100644 --- a/Marlin/src/gcode/config/M281.cpp +++ b/Marlin/src/gcode/config/M281.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #include "../../inc/MarlinConfig.h" @@ -26,6 +26,13 @@ #include "../gcode.h" #include "../../module/servo.h" +/** + * M281 - Edit / Report Servo Angles + * + * P - Servo to update + * L - Deploy Angle + * U - Stowed Angle + */ void GcodeSuite::M281() { if (!parser.seenval('P')) return; const int servo_index = parser.value_int(); diff --git a/Marlin/src/gcode/config/M301.cpp b/Marlin/src/gcode/config/M301.cpp index 54d32c865074..7b3f57608bad 100644 --- a/Marlin/src/gcode/config/M301.cpp +++ b/Marlin/src/gcode/config/M301.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -30,6 +30,8 @@ /** * M301: Set PID parameters P I D (and optionally C, L) * + * E[extruder] Default: 0 + * * P[float] Kp term * I[float] Ki term (unscaled) * D[float] Kd term (unscaled) @@ -65,6 +67,7 @@ void GcodeSuite::M301() { #endif thermalManager.updatePID(); + SERIAL_ECHO_START(); #if ENABLED(PID_PARAMS_PER_HOTEND) SERIAL_ECHOPAIR(" e:", e); // specify extruder in serial output diff --git a/Marlin/src/gcode/config/M302.cpp b/Marlin/src/gcode/config/M302.cpp index aa178ea206e6..afdc6c9e8506 100644 --- a/Marlin/src/gcode/config/M302.cpp +++ b/Marlin/src/gcode/config/M302.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -37,7 +37,7 @@ * * M302 ; report current cold extrusion state * M302 P0 ; enable cold extrusion checking - * M302 P1 ; disables cold extrusion checking + * M302 P1 ; disable cold extrusion checking * M302 S0 ; always allow extrusion (disables checking) * M302 S170 ; only allow extrusion above 170 * M302 S170 P1 ; set min extrude temp to 170 but leave disabled diff --git a/Marlin/src/gcode/config/M304.cpp b/Marlin/src/gcode/config/M304.cpp index 2a851494244c..10739be3f8c3 100644 --- a/Marlin/src/gcode/config/M304.cpp +++ b/Marlin/src/gcode/config/M304.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/config/M305.cpp b/Marlin/src/gcode/config/M305.cpp index 47a81cdb6c81..3e7206aee49d 100644 --- a/Marlin/src/gcode/config/M305.cpp +++ b/Marlin/src/gcode/config/M305.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -71,7 +71,7 @@ void GcodeSuite::M305() { SERIAL_ECHO_MSG("!Invalid Steinhart-Hart C coeff. (-0.01 < C < +0.01)"); } // If not setting then report parameters else if (t_index < 0) { // ...all user thermistors - for (uint8_t i = 0; i < USER_THERMISTORS; i++) + LOOP_L_N(i, USER_THERMISTORS) thermalManager.log_user_thermistor(i); } else // ...one user thermistor diff --git a/Marlin/src/gcode/config/M43.cpp b/Marlin/src/gcode/config/M43.cpp index 0dd0013e05ea..1e780ca05afd 100644 --- a/Marlin/src/gcode/config/M43.cpp +++ b/Marlin/src/gcode/config/M43.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -43,7 +43,11 @@ #endif #if ENABLED(EXTENSIBLE_UI) - #include "../../lcd/extensible_ui/ui_api.h" + #include "../../lcd/extui/ui_api.h" +#endif + +#if HAS_RESUME_CONTINUE + #include "../../lcd/ultralcd.h" #endif #ifndef GET_PIN_MAP_PIN_M43 @@ -57,16 +61,21 @@ inline void toggle_pins() { end = PARSED_PIN_INDEX('L', NUM_DIGITAL_PINS - 1), wait = parser.intval('W', 500); - for (uint8_t i = start; i <= end; i++) { + LOOP_S_LE_N(i, start, end) { pin_t pin = GET_PIN_MAP_PIN_M43(i); if (!VALID_PIN(pin)) continue; if (M43_NEVER_TOUCH(i) || (!ignore_protection && pin_is_protected(pin))) { - report_pin_state_extended(pin, ignore_protection, true, "Untouched "); + report_pin_state_extended(pin, ignore_protection, true, PSTR("Untouched ")); SERIAL_EOL(); } else { watchdog_refresh(); - report_pin_state_extended(pin, ignore_protection, true, "Pulsing "); + report_pin_state_extended(pin, ignore_protection, true, PSTR("Pulsing ")); + #ifdef __STM32F1__ + const auto prior_mode = _GET_MODE(i); + #else + const bool prior_mode = GET_PINMODE(pin); + #endif #if AVR_AT90USB1286_FAMILY // Teensy IDEs don't know about these pins so must use FASTIO if (pin == TEENSY_E2) { SET_OUTPUT(TEENSY_E2); @@ -95,6 +104,11 @@ inline void toggle_pins() { watchdog_refresh(); } } + #ifdef __STM32F1__ + _SET_MODE(i, prior_mode); + #else + pinMode(pin, prior_mode); + #endif } SERIAL_EOL(); } @@ -313,7 +327,7 @@ void GcodeSuite::M43() { NOLESS(first_pin, 2); // Don't hijack the UART pins #endif uint8_t pin_state[last_pin - first_pin + 1]; - for (uint8_t i = first_pin; i <= last_pin; i++) { + LOOP_S_LE_N(i, first_pin, last_pin) { pin_t pin = GET_PIN_MAP_PIN_M43(i); if (!VALID_PIN(pin)) continue; if (M43_NEVER_TOUCH(i) || (!ignore_protection && pin_is_protected(pin))) continue; @@ -330,16 +344,12 @@ void GcodeSuite::M43() { #if HAS_RESUME_CONTINUE KEEPALIVE_STATE(PAUSED_FOR_USER); wait_for_user = true; - #if ENABLED(HOST_PROMPT_SUPPORT) - host_prompt_do(PROMPT_USER_CONTINUE, PSTR("M43 Wait Called"), CONTINUE_STR); - #endif - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onUserConfirmRequired_P(PSTR("M43 Wait Called")); - #endif + TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, PSTR("M43 Wait Called"), CONTINUE_STR)); + TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(PSTR("M43 Wait Called"))); #endif for (;;) { - for (uint8_t i = first_pin; i <= last_pin; i++) { + LOOP_S_LE_N(i, first_pin, last_pin) { pin_t pin = GET_PIN_MAP_PIN_M43(i); if (!VALID_PIN(pin)) continue; if (M43_NEVER_TOUCH(i) || (!ignore_protection && pin_is_protected(pin))) continue; @@ -357,6 +367,7 @@ void GcodeSuite::M43() { } #if HAS_RESUME_CONTINUE + ui.update(); if (!wait_for_user) break; #endif @@ -365,7 +376,7 @@ void GcodeSuite::M43() { } else { // Report current state of selected pin(s) - for (uint8_t i = first_pin; i <= last_pin; i++) { + LOOP_S_LE_N(i, first_pin, last_pin) { pin_t pin = GET_PIN_MAP_PIN_M43(i); if (VALID_PIN(pin)) report_pin_state_extended(pin, ignore_protection, true); } diff --git a/Marlin/src/gcode/config/M540.cpp b/Marlin/src/gcode/config/M540.cpp index a8ec628d5a2f..54d52f3a31e2 100644 --- a/Marlin/src/gcode/config/M540.cpp +++ b/Marlin/src/gcode/config/M540.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/config/M575.cpp b/Marlin/src/gcode/config/M575.cpp index 947af14e30ab..44723b7f2fe6 100644 --- a/Marlin/src/gcode/config/M575.cpp +++ b/Marlin/src/gcode/config/M575.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -33,36 +33,37 @@ * B - Baud rate (bits per second) */ void GcodeSuite::M575() { - const int32_t baud = parser.ulongval('B'); + int32_t baud = parser.ulongval('B'); + switch (baud) { + case 24: + case 96: + case 192: + case 384: + case 576: + case 1152: baud *= 100; break; + case 250: + case 500: baud *= 1000; break; + case 19: baud = 19200; break; + case 38: baud = 38400; break; + case 57: baud = 57600; break; + case 115: baud = 115200; break; + } switch (baud) { case 2400: case 9600: case 19200: case 38400: case 57600: case 115200: case 250000: case 500000: case 1000000: { const int8_t port = parser.intval('P', -99); const bool set0 = (port == -99 || port == 0); - if (set0) { - SERIAL_ECHO_START(); - SERIAL_ECHOLNPAIR(" Serial " - #if NUM_SERIAL > 1 - , '0', - #else - "0" - #endif - " baud rate set to ", baud - ); - } - #if NUM_SERIAL > 1 + if (set0) SERIAL_ECHO_MSG(" Serial ", '0', " baud rate set to ", baud); + #if HAS_MULTI_SERIAL const bool set1 = (port == -99 || port == 1); - if (set1) { - SERIAL_ECHO_START(); - SERIAL_ECHOLNPAIR(" Serial ", '1', " baud rate set to ", baud); - } + if (set1) SERIAL_ECHO_MSG(" Serial ", '1', " baud rate set to ", baud); #endif SERIAL_FLUSH(); if (set0) { MYSERIAL0.end(); MYSERIAL0.begin(baud); } - #if NUM_SERIAL > 1 + #if HAS_MULTI_SERIAL if (set1) { MYSERIAL1.end(); MYSERIAL1.begin(baud); } #endif @@ -71,4 +72,4 @@ void GcodeSuite::M575() { } } -#endif // NUM_SERIAL > 0 && BAUD_RATE_GCODE +#endif // BAUD_RATE_GCODE diff --git a/Marlin/src/gcode/config/M672.cpp b/Marlin/src/gcode/config/M672.cpp index ca4b028dc7da..af74230516e1 100644 --- a/Marlin/src/gcode/config/M672.cpp +++ b/Marlin/src/gcode/config/M672.cpp @@ -16,26 +16,18 @@ * 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 . + * along with this program. If not, see . * */ #include "../../inc/MarlinConfig.h" -#if ENABLED(SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD) +#if ENABLED(DUET_SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD) #include "../gcode.h" #include "../../HAL/shared/Delay.h" #include "../parser.h" -/** - * M672 - Set/reset Duet Smart Effector sensitivity - * - * One of these is required: - * S - 0-255 - * R - Flag to reset sensitivity to default - */ - /** * The Marlin format for the M672 command is different than shown in the Duet Smart Effector * documentation https://duet3d.dozuki.com/Wiki/Smart_effector_and_carriage_adapters_for_delta_printer @@ -51,8 +43,8 @@ * Marlin: M672 R */ -#define M672_PROGBYTE 105 // magic byte to start programming custom sensitivity -#define M672_ERASEBYTE 131 // magic byte to clear custom sensitivity +#define M672_PROGBYTE 105 // magic byte to start programming custom sensitivity +#define M672_ERASEBYTE 131 // magic byte to clear custom sensitivity // // Smart Effector byte send protocol: @@ -62,7 +54,7 @@ // b3 b2 b1 b0 ~b0 ... lo bits, NOT last bit // void M672_send(uint8_t b) { // bit rate requirement: 1KHz +/- 30% - for (uint8_t bits = 0; bits < 14; bits++) { + LOOP_L_N(bits, 14) { switch (bits) { default: { OUT_WRITE(SMART_EFFECTOR_MOD_PIN, !!(b & 0x80)); b <<= 1; break; } // send bit, shift next into place case 7: @@ -77,6 +69,13 @@ void M672_send(uint8_t b) { // bit rate requirement: 1KHz +/- 30% } } +/** + * M672 - Set/reset Duet Smart Effector sensitivity + * + * One of these is required: + * S - 0-255 + * R - Flag to reset sensitivity to default + */ void GcodeSuite::M672() { if (parser.seen('R')) { M672_send(M672_ERASEBYTE); @@ -96,4 +95,4 @@ void GcodeSuite::M672() { OUT_WRITE(SMART_EFFECTOR_MOD_PIN, LOW); // Keep Smart Effector in NORMAL mode } -#endif // SMART_EFFECTOR && SMART_EFFECTOR_MOD_PIN +#endif // DUET_SMART_EFFECTOR && SMART_EFFECTOR_MOD_PIN diff --git a/Marlin/src/gcode/config/M92.cpp b/Marlin/src/gcode/config/M92.cpp index 642de9672579..0a7d52b633cc 100644 --- a/Marlin/src/gcode/config/M92.cpp +++ b/Marlin/src/gcode/config/M92.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -34,7 +34,7 @@ void report_M92(const bool echo=true, const int8_t e=-1) { SERIAL_EOL(); #if ENABLED(DISTINCT_E_FACTORS) - for (uint8_t i = 0; i < E_STEPPERS; i++) { + LOOP_L_N(i, E_STEPPERS) { if (e >= 0 && i != e) continue; if (echo) SERIAL_ECHO_START(); else SERIAL_CHAR(' '); SERIAL_ECHOLNPAIR_P(PSTR(" M92 T"), (int)i, @@ -105,7 +105,7 @@ void GcodeSuite::M92() { if (wanted) { const float best = uint16_t(wanted / z_full_step_mm) * z_full_step_mm; SERIAL_ECHOPAIR(", best:[", best); - if (best != wanted) { SERIAL_CHAR(','); SERIAL_ECHO(best + z_full_step_mm); } + if (best != wanted) { SERIAL_CHAR(','); SERIAL_DECIMAL(best + z_full_step_mm); } SERIAL_CHAR(']'); } SERIAL_ECHOLNPGM(" }"); diff --git a/Marlin/src/gcode/control/M108_M112_M410.cpp b/Marlin/src/gcode/control/M108_M112_M410.cpp index cb4220507d85..df145d5d11c9 100644 --- a/Marlin/src/gcode/control/M108_M112_M410.cpp +++ b/Marlin/src/gcode/control/M108_M112_M410.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -31,9 +31,7 @@ * M108: Stop the waiting for heaters in M109, M190, M303. Does not affect the target temperature. */ void GcodeSuite::M108() { - #if HAS_RESUME_CONTINUE - wait_for_user = false; - #endif + TERN_(HAS_RESUME_CONTINUE, wait_for_user = false); wait_for_heatup = false; } diff --git a/Marlin/src/gcode/control/M111.cpp b/Marlin/src/gcode/control/M111.cpp index bb1a77836be1..cc871bf38b52 100644 --- a/Marlin/src/gcode/control/M111.cpp +++ b/Marlin/src/gcode/control/M111.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -28,28 +28,25 @@ void GcodeSuite::M111() { if (parser.seen('S')) marlin_debug_flags = parser.byteval('S'); - static const char str_debug_1[] PROGMEM = STR_DEBUG_ECHO, - str_debug_2[] PROGMEM = STR_DEBUG_INFO, - str_debug_4[] PROGMEM = STR_DEBUG_ERRORS, - str_debug_8[] PROGMEM = STR_DEBUG_DRYRUN, - str_debug_16[] PROGMEM = STR_DEBUG_COMMUNICATION - #if ENABLED(DEBUG_LEVELING_FEATURE) - , str_debug_lvl[] PROGMEM = STR_DEBUG_LEVELING - #endif - ; + static PGMSTR(str_debug_1, STR_DEBUG_ECHO); + static PGMSTR(str_debug_2, STR_DEBUG_INFO); + static PGMSTR(str_debug_4, STR_DEBUG_ERRORS); + static PGMSTR(str_debug_8, STR_DEBUG_DRYRUN); + static PGMSTR(str_debug_16, STR_DEBUG_COMMUNICATION); + #if ENABLED(DEBUG_LEVELING_FEATURE) + static PGMSTR(str_debug_lvl, STR_DEBUG_LEVELING); + #endif static PGM_P const debug_strings[] PROGMEM = { - str_debug_1, str_debug_2, str_debug_4, str_debug_8, str_debug_16 - #if ENABLED(DEBUG_LEVELING_FEATURE) - , str_debug_lvl - #endif + str_debug_1, str_debug_2, str_debug_4, str_debug_8, str_debug_16, + TERN_(DEBUG_LEVELING_FEATURE, str_debug_lvl) }; SERIAL_ECHO_START(); SERIAL_ECHOPGM(STR_DEBUG_PREFIX); if (marlin_debug_flags) { uint8_t comma = 0; - for (uint8_t i = 0; i < COUNT(debug_strings); i++) { + LOOP_L_N(i, COUNT(debug_strings)) { if (TEST(marlin_debug_flags, i)) { if (comma++) SERIAL_CHAR(','); serialprintPGM((char*)pgm_read_ptr(&debug_strings[i])); @@ -58,7 +55,7 @@ void GcodeSuite::M111() { } else { SERIAL_ECHOPGM(STR_DEBUG_OFF); - #if !defined(__AVR__) || !defined(USBCON) + #if !IS_AT90USB #if ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS) SERIAL_ECHOPAIR("\nBuffer Overruns: ", MYSERIAL0.buffer_overruns()); #endif @@ -74,7 +71,7 @@ void GcodeSuite::M111() { #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) SERIAL_ECHOPAIR("\nMax RX Queue Size: ", MYSERIAL0.rxMaxEnqueued()); #endif - #endif // !defined(__AVR__) || !defined(USBCON) + #endif // !IS_AT90USB } SERIAL_EOL(); } diff --git a/Marlin/src/gcode/control/M120_M121.cpp b/Marlin/src/gcode/control/M120_M121.cpp index b25834cbda4f..570f2e935bb4 100644 --- a/Marlin/src/gcode/control/M120_M121.cpp +++ b/Marlin/src/gcode/control/M120_M121.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/control/M17_M18_M84.cpp b/Marlin/src/gcode/control/M17_M18_M84.cpp index d69654a95910..499feef71586 100644 --- a/Marlin/src/gcode/control/M17_M18_M84.cpp +++ b/Marlin/src/gcode/control/M17_M18_M84.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -25,7 +25,7 @@ #include "../../lcd/ultralcd.h" #include "../../module/stepper.h" -#if BOTH(AUTO_BED_LEVELING_UBL, ULTRA_LCD) +#if ENABLED(AUTO_BED_LEVELING_UBL) #include "../../feature/bedlevel/bedlevel.h" #endif @@ -37,9 +37,7 @@ void GcodeSuite::M17() { if (parser.seen('X')) ENABLE_AXIS_X(); if (parser.seen('Y')) ENABLE_AXIS_Y(); if (parser.seen('Z')) ENABLE_AXIS_Z(); - #if HAS_E_STEPPER_ENABLE - if (parser.seen('E')) enable_e_steppers(); - #endif + if (TERN0(HAS_E_STEPPER_ENABLE, parser.seen('E'))) enable_e_steppers(); } else { LCD_MESSAGEPGM(MSG_NO_MOVE); @@ -52,6 +50,7 @@ void GcodeSuite::M17() { */ void GcodeSuite::M18_M84() { if (parser.seenval('S')) { + reset_stepper_timeout(); stepper_inactive_time = parser.value_millis_from_seconds(); } else { @@ -60,18 +59,11 @@ void GcodeSuite::M18_M84() { if (parser.seen('X')) DISABLE_AXIS_X(); if (parser.seen('Y')) DISABLE_AXIS_Y(); if (parser.seen('Z')) DISABLE_AXIS_Z(); - #if HAS_E_STEPPER_ENABLE - if (parser.seen('E')) disable_e_steppers(); - #endif + if (TERN0(HAS_E_STEPPER_ENABLE, parser.seen('E'))) disable_e_steppers(); } else planner.finish_and_disable(); - #if HAS_LCD_MENU && ENABLED(AUTO_BED_LEVELING_UBL) - if (ubl.lcd_map_control) { - ubl.lcd_map_control = false; - ui.defer_status_screen(false); - } - #endif + TERN_(AUTO_BED_LEVELING_UBL, ubl.steppers_were_disabled()); } } diff --git a/Marlin/src/gcode/control/M211.cpp b/Marlin/src/gcode/control/M211.cpp index 3b0a928b8f13..2049f1eb6955 100644 --- a/Marlin/src/gcode/control/M211.cpp +++ b/Marlin/src/gcode/control/M211.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -37,8 +37,8 @@ void GcodeSuite::M211() { l_soft_max = soft_endstop.max.asLogical(); SERIAL_ECHO_START(); SERIAL_ECHOPGM(STR_SOFT_ENDSTOPS); - if (parser.seen('S')) soft_endstops_enabled = parser.value_bool(); - serialprint_onoff(soft_endstops_enabled); + if (parser.seen('S')) soft_endstop._enabled = parser.value_bool(); + serialprint_onoff(soft_endstop._enabled); print_xyz(l_soft_min, PSTR(STR_SOFT_MIN), PSTR(" ")); print_xyz(l_soft_max, PSTR(STR_SOFT_MAX)); } diff --git a/Marlin/src/gcode/control/M226.cpp b/Marlin/src/gcode/control/M226.cpp index 0dfbfd62528e..ad717e614d8a 100644 --- a/Marlin/src/gcode/control/M226.cpp +++ b/Marlin/src/gcode/control/M226.cpp @@ -16,10 +16,14 @@ * 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 . + * along with this program. If not, see . * */ +#include "../../inc/MarlinConfig.h" + +#if ENABLED(DIRECT_PIN_CONTROL) + #include "../gcode.h" #include "../../MarlinCore.h" // for pin_is_protected and idle() #include "../../module/stepper.h" @@ -50,3 +54,5 @@ void GcodeSuite::M226() { } // pin_state -1 0 1 && pin > -1 } // parser.seen('P') } + +#endif // DIRECT_PIN_CONTROL diff --git a/Marlin/src/gcode/control/M280.cpp b/Marlin/src/gcode/control/M280.cpp index 21a6c9890d9c..6ccbb7becc2f 100644 --- a/Marlin/src/gcode/control/M280.cpp +++ b/Marlin/src/gcode/control/M280.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/control/M3-M5.cpp b/Marlin/src/gcode/control/M3-M5.cpp index 56e1e0e4ec9d..1326c30669a2 100644 --- a/Marlin/src/gcode/control/M3-M5.cpp +++ b/Marlin/src/gcode/control/M3-M5.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -30,20 +30,16 @@ /** * Laser: - * * M3 - Laser ON/Power (Ramped power) * M4 - Laser ON/Power (Continuous power) * - * S - Set power. S0 will turn the laser off. - * O - Set power and OCR - * * Spindle: - * * M3 - Spindle ON (Clockwise) * M4 - Spindle ON (Counter-clockwise) * - * S - Set power. S0 will turn the spindle off. - * O - Set power and OCR + * Parameters: + * S - Set power. S0 will turn the spindle/laser off, except in relative mode. + * O - Set power and OCR (oscillator count register) * * If no PWM pin is defined then M3/M4 just turns it on. * @@ -70,31 +66,69 @@ * PWM duty cycle goes from 0 (off) to 255 (always on). */ void GcodeSuite::M3_M4(const bool is_M4) { + auto get_s_power = [] { + if (parser.seenval('S')) { + const float spwr = parser.value_float(); + cutter.unitPower = TERN(SPINDLE_LASER_PWM, + cutter.power_to_range(cutter_power_t(round(spwr))), + spwr > 0 ? 255 : 0); + } + else + cutter.unitPower = cutter.cpwr_to_upwr(SPEED_POWER_STARTUP); + return cutter.unitPower; + }; - #if ENABLED(SPINDLE_FEATURE) - planner.synchronize(); // Wait for movement to complete before changing power + #if ENABLED(LASER_POWER_INLINE) + if (parser.seen('I') == DISABLED(LASER_POWER_INLINE_INVERT)) { + // Laser power in inline mode + cutter.inline_direction(is_M4); // Should always be unused + #if ENABLED(SPINDLE_LASER_PWM) + if (parser.seen('O')) { + cutter.unitPower = cutter.power_to_range(parser.value_byte(), 0); + cutter.inline_ocr_power(cutter.unitPower); // The OCR is a value from 0 to 255 (uint8_t) + } + else + cutter.inline_power(cutter.upower_to_ocr(get_s_power())); + #else + cutter.set_inline_enabled(true); + #endif + return; + } + // Non-inline, standard case + cutter.inline_disable(); // Prevent future blocks re-setting the power #endif + planner.synchronize(); // Wait for previous movement commands (G0/G0/G2/G3) to complete before changing power cutter.set_direction(is_M4); #if ENABLED(SPINDLE_LASER_PWM) - if (parser.seenval('O')) - cutter.set_ocr_power(parser.value_byte()); // The OCR is a value from 0 to 255 (uint8_t) + if (parser.seenval('O')) { + cutter.unitPower = cutter.power_to_range(parser.value_byte(), 0); + cutter.set_ocr_power(cutter.unitPower); // The OCR is a value from 0 to 255 (uint8_t) + } else - cutter.set_power(parser.intval('S', 255)); + cutter.set_power(cutter.upower_to_ocr(get_s_power())); #else cutter.set_enabled(true); #endif + cutter.menuPower = cutter.unitPower; } /** - * M5 - Cutter OFF + * M5 - Cutter OFF (when moves are complete) */ void GcodeSuite::M5() { - #if ENABLED(SPINDLE_FEATURE) - planner.synchronize(); + #if ENABLED(LASER_POWER_INLINE) + if (parser.seen('I') == DISABLED(LASER_POWER_INLINE_INVERT)) { + cutter.set_inline_enabled(false); // Laser power in inline mode + return; + } + // Non-inline, standard case + cutter.inline_disable(); // Prevent future blocks re-setting the power #endif + planner.synchronize(); cutter.set_enabled(false); + cutter.menuPower = cutter.unitPower; } #endif // HAS_CUTTER diff --git a/Marlin/src/gcode/control/M350_M351.cpp b/Marlin/src/gcode/control/M350_M351.cpp index ae448a63ec18..463bd2ad5815 100644 --- a/Marlin/src/gcode/control/M350_M351.cpp +++ b/Marlin/src/gcode/control/M350_M351.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -33,7 +33,7 @@ * Warning: Steps-per-unit remains unchanged. */ void GcodeSuite::M350() { - if (parser.seen('S')) for (uint8_t i = 0; i <= 4; i++) stepper.microstep_mode(i, parser.value_byte()); + if (parser.seen('S')) LOOP_LE_N(i, 4) stepper.microstep_mode(i, parser.value_byte()); LOOP_XYZE(i) if (parser.seen(axis_codes[i])) stepper.microstep_mode(i, parser.value_byte()); if (parser.seen('B')) stepper.microstep_mode(4, parser.value_byte()); stepper.microstep_readings(); diff --git a/Marlin/src/gcode/control/M380_M381.cpp b/Marlin/src/gcode/control/M380_M381.cpp index 756021a59b0b..3f5b25246543 100644 --- a/Marlin/src/gcode/control/M380_M381.cpp +++ b/Marlin/src/gcode/control/M380_M381.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/control/M400.cpp b/Marlin/src/gcode/control/M400.cpp index 3926299807bb..9a5ad4e9df80 100644 --- a/Marlin/src/gcode/control/M400.cpp +++ b/Marlin/src/gcode/control/M400.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/control/M42.cpp b/Marlin/src/gcode/control/M42.cpp index 7106ce55027b..c635c06ec63b 100644 --- a/Marlin/src/gcode/control/M42.cpp +++ b/Marlin/src/gcode/control/M42.cpp @@ -16,15 +16,18 @@ * 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 . + * along with this program. If not, see . * */ +#include "../../inc/MarlinConfig.h" + +#if ENABLED(DIRECT_PIN_CONTROL) + #include "../gcode.h" #include "../../MarlinCore.h" // for pin_is_protected -#include "../../inc/MarlinConfig.h" -#if FAN_COUNT > 0 +#if HAS_FAN #include "../../module/temperature.h" #endif @@ -37,17 +40,33 @@ * * S Pin status from 0 - 255 * I Flag to ignore Marlin's pin protection + * + * M Pin mode: 0=INPUT 1=OUTPUT 2=INPUT_PULLUP 3=INPUT_PULLDOWN */ void GcodeSuite::M42() { - if (!parser.seenval('S')) return; - const byte pin_status = parser.value_byte(); - const int pin_index = PARSED_PIN_INDEX('P', GET_PIN_MAP_INDEX(LED_PIN)); if (pin_index < 0) return; const pin_t pin = GET_PIN_MAP_PIN(pin_index); - #if FAN_COUNT > 0 + if (!parser.boolval('I') && pin_is_protected(pin)) return protected_pin_err(); + + if (parser.seenval('M')) { + switch (parser.value_byte()) { + case 0: pinMode(pin, INPUT); break; + case 1: pinMode(pin, OUTPUT); break; + case 2: pinMode(pin, INPUT_PULLUP); break; + #ifdef INPUT_PULLDOWN + case 3: pinMode(pin, INPUT_PULLDOWN); break; + #endif + default: SERIAL_ECHOLNPGM("Invalid Pin Mode"); return; + } + } + + if (!parser.seenval('S')) return; + const byte pin_status = parser.value_byte(); + + #if HAS_FAN switch (pin) { #if HAS_FAN0 case FAN0_PIN: thermalManager.fan_speed[0] = pin_status; return; @@ -76,9 +95,9 @@ void GcodeSuite::M42() { } #endif - if (!parser.boolval('I') && pin_is_protected(pin)) return protected_pin_err(); - pinMode(pin, OUTPUT); extDigitalWrite(pin, pin_status); analogWrite(pin, pin_status); } + +#endif // DIRECT_PIN_CONTROL diff --git a/Marlin/src/gcode/control/M605.cpp b/Marlin/src/gcode/control/M605.cpp index 99bab4ddc960..5dc36428b503 100644 --- a/Marlin/src/gcode/control/M605.cpp +++ b/Marlin/src/gcode/control/M605.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -92,8 +92,10 @@ case DXC_AUTO_PARK_MODE: break; case DXC_DUPLICATION_MODE: - if (parser.seen('X')) duplicate_extruder_x_offset = _MAX(parser.value_linear_units(), X2_MIN_POS - x_home_pos(0)); + // Set the X offset, but no less than the safety gap + if (parser.seen('X')) duplicate_extruder_x_offset = _MAX(parser.value_linear_units(), (X2_MIN_POS) - (X1_MIN_POS)); if (parser.seen('R')) duplicate_extruder_temp_offset = parser.value_celsius_diff(); + // Always switch back to tool 0 if (active_extruder != 0) tool_change(0); break; default: @@ -138,7 +140,7 @@ HOTEND_LOOP() { DEBUG_ECHOPAIR_P(SP_T_STR, int(e)); - LOOP_XYZ(a) DEBUG_ECHOPAIR(" hotend_offset[", int(e), "].", axis_codes[a] | 0x20, "=", hotend_offset[e][a]); + LOOP_XYZ(a) DEBUG_ECHOPAIR(" hotend_offset[", int(e), "].", XYZ_CHAR(a) | 0x20, "=", hotend_offset[e][a]); DEBUG_EOL(); } DEBUG_EOL(); diff --git a/Marlin/src/gcode/control/M7-M9.cpp b/Marlin/src/gcode/control/M7-M9.cpp index 1fc8a93e2e92..a33e43288b75 100644 --- a/Marlin/src/gcode/control/M7-M9.cpp +++ b/Marlin/src/gcode/control/M7-M9.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/control/M80_M81.cpp b/Marlin/src/gcode/control/M80_M81.cpp index f9c40a20a9ce..6302bb5c6787 100644 --- a/Marlin/src/gcode/control/M80_M81.cpp +++ b/Marlin/src/gcode/control/M80_M81.cpp @@ -16,21 +16,19 @@ * 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 . + * along with this program. If not, see . * */ #include "../gcode.h" + #include "../../module/temperature.h" -#include "../../module/stepper.h" -#include "../../module/printcounter.h" // for print_job_timer +#include "../../module/planner.h" // for planner.finish_and_disable +#include "../../module/printcounter.h" // for print_job_timer.stop +#include "../../lcd/ultralcd.h" // for LCD_MESSAGEPGM_P #include "../../inc/MarlinConfig.h" -#if HAS_LCD_MENU - #include "../../lcd/ultralcd.h" -#endif - #if HAS_SUICIDE #include "../../MarlinCore.h" #endif @@ -39,12 +37,14 @@ #if ENABLED(AUTO_POWER_CONTROL) #include "../../feature/power.h" + #else + void restore_stepper_drivers(); #endif // Could be moved to a feature, but this is all the data bool powersupply_on; - #if HAS_TRINAMIC + #if HAS_TRINAMIC_CONFIG #include "../../feature/tmc_util.h" #endif @@ -72,16 +72,15 @@ #endif #if DISABLED(AUTO_POWER_CONTROL) - delay(PSU_POWERUP_DELAY); // Wait for power to settle + safe_delay(PSU_POWERUP_DELAY); restore_stepper_drivers(); + TERN_(HAS_TRINAMIC_CONFIG, safe_delay(PSU_POWERUP_DELAY)); #endif - #if HAS_LCD_MENU - ui.reset_status(); - #endif + TERN_(HAS_LCD_MENU, ui.reset_status()); } -#endif // ENABLED(PSU_CONTROL) +#endif // PSU_CONTROL /** * M81: Turn off Power, including Power Supply, if there is one. @@ -93,7 +92,7 @@ void GcodeSuite::M81() { print_job_timer.stop(); planner.finish_and_disable(); - #if FAN_COUNT > 0 + #if HAS_FAN thermalManager.zero_fan_speeds(); #if ENABLED(PROBING_FANS_OFF) thermalManager.fans_paused = false; @@ -109,7 +108,5 @@ void GcodeSuite::M81() { PSU_OFF(); #endif - #if HAS_LCD_MENU - LCD_MESSAGEPGM_P(PSTR(MACHINE_NAME " " STR_OFF ".")); - #endif + LCD_MESSAGEPGM_P(PSTR(MACHINE_NAME " " STR_OFF ".")); } diff --git a/Marlin/src/gcode/control/M85.cpp b/Marlin/src/gcode/control/M85.cpp index 1cdf49f6096c..9c8c02c59aa0 100644 --- a/Marlin/src/gcode/control/M85.cpp +++ b/Marlin/src/gcode/control/M85.cpp @@ -16,12 +16,11 @@ * 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 . + * along with this program. If not, see . * */ #include "../gcode.h" -#include "../../MarlinCore.h" // for max_inactive_time /** * M85: Set inactivity shutdown timer with parameter S. To disable set zero (default) diff --git a/Marlin/src/gcode/control/M993_M994.cpp b/Marlin/src/gcode/control/M993_M994.cpp new file mode 100644 index 000000000000..ff9ff85bf5bd --- /dev/null +++ b/Marlin/src/gcode/control/M993_M994.cpp @@ -0,0 +1,88 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfig.h" + +#if ALL(HAS_SPI_FLASH, SDSUPPORT, MARLIN_DEV_MODE) + +#include "../gcode.h" +#include "../../sd/cardreader.h" +#include "../../libs/W25Qxx.h" + +/** + * M993: Backup SPI Flash to SD + */ +void GcodeSuite::M993() { + if (!card.isMounted()) card.mount(); + + char fname[] = "spiflash.bin"; + card.openFileWrite(fname); + if (!card.isFileOpen()) { + SERIAL_ECHOLNPAIR("Failed to open ", fname, " to write."); + return; + } + + uint8_t buf[1024]; + uint32_t addr = 0; + W25QXX.init(SPI_QUARTER_SPEED); + SERIAL_ECHOPGM("Save SPI Flash"); + while (addr < SPI_FLASH_SIZE) { + W25QXX.SPI_FLASH_BufferRead(buf, addr, COUNT(buf)); + addr += COUNT(buf); + card.write(buf, COUNT(buf)); + if (addr % (COUNT(buf) * 10) == 0) SERIAL_CHAR('.'); + } + SERIAL_ECHOLNPGM(" done"); + + card.closefile(); +} + +/** + * M994: Load a backup from SD to SPI Flash + */ +void GcodeSuite::M994() { + if (!card.isMounted()) card.mount(); + + char fname[] = "spiflash.bin"; + card.openFileRead(fname); + if (!card.isFileOpen()) { + SERIAL_ECHOLNPAIR("Failed to open ", fname, " to read."); + return; + } + + uint8_t buf[1024]; + uint32_t addr = 0; + W25QXX.init(SPI_QUARTER_SPEED); + W25QXX.SPI_FLASH_BulkErase(); + SERIAL_ECHOPGM("Load SPI Flash"); + while (addr < SPI_FLASH_SIZE) { + card.read(buf, COUNT(buf)); + W25QXX.SPI_FLASH_BufferWrite(buf, addr, COUNT(buf)); + addr += COUNT(buf); + if (addr % (COUNT(buf) * 10) == 0) SERIAL_CHAR('.'); + } + SERIAL_ECHOLNPGM(" done"); + + card.closefile(); +} + +#endif // HAS_SPI_FLASH && SDSUPPORT && MARLIN_DEV_MODE diff --git a/Marlin/src/gcode/control/M997.cpp b/Marlin/src/gcode/control/M997.cpp index 1d9b12204db8..cdff96f1acd8 100644 --- a/Marlin/src/gcode/control/M997.cpp +++ b/Marlin/src/gcode/control/M997.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -28,7 +28,9 @@ * M997: Perform in-application firmware update */ void GcodeSuite::M997() { + flashFirmware(parser.intval('S')); + } #endif diff --git a/Marlin/src/gcode/control/M999.cpp b/Marlin/src/gcode/control/M999.cpp index c498e66cabf0..3bd908cad640 100644 --- a/Marlin/src/gcode/control/M999.cpp +++ b/Marlin/src/gcode/control/M999.cpp @@ -16,14 +16,14 @@ * 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 . + * along with this program. If not, see . * */ #include "../gcode.h" #include "../../lcd/ultralcd.h" // for lcd_reset_alert_level -#include "../../MarlinCore.h" // for Running +#include "../../MarlinCore.h" // for marlin_state #include "../queue.h" // for flush_and_request_resend /** @@ -34,10 +34,9 @@ * * Sending "M999 S1" will resume printing without flushing the * existing command buffer. - * */ void GcodeSuite::M999() { - Running = true; + marlin_state = MF_RUNNING; ui.reset_alert_level(); if (parser.boolval('S')) return; diff --git a/Marlin/src/gcode/control/T.cpp b/Marlin/src/gcode/control/T.cpp index cb2fce6c25e7..d95e60ff8d70 100644 --- a/Marlin/src/gcode/control/T.cpp +++ b/Marlin/src/gcode/control/T.cpp @@ -16,19 +16,19 @@ * 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 . + * along with this program. If not, see . * */ #include "../gcode.h" #include "../../module/tool_change.h" -#if ENABLED(DEBUG_LEVELING_FEATURE) || EXTRUDERS > 1 +#if EITHER(HAS_MULTI_EXTRUDER, DEBUG_LEVELING_FEATURE) #include "../../module/motion.h" #endif #if ENABLED(PRUSA_MMU2) - #include "../../feature/prusa_MMU2/mmu2.h" + #include "../../feature/mmu2/mmu2.h" #endif #define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) @@ -46,12 +46,13 @@ * Tx Same as T?, but nozzle doesn't have to be preheated. Tc requires a preheated nozzle to finish filament load. * Tc Load to nozzle after filament was prepared by Tc and nozzle is already heated. */ -void GcodeSuite::T(const uint8_t tool_index) { +void GcodeSuite::T(const int8_t tool_index) { - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOLNPAIR(">>> T(", tool_index, ")"); - DEBUG_POS("BEFORE", current_position); - } + DEBUG_SECTION(log_T, "T", DEBUGGING(LEVELING)); + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("...(", tool_index, ")"); + + // Count this command as movement / activity + reset_stepper_timeout(); #if ENABLED(PRUSA_MMU2) if (parser.string_arg) { @@ -72,9 +73,4 @@ void GcodeSuite::T(const uint8_t tool_index) { ); #endif - - if (DEBUGGING(LEVELING)) { - DEBUG_POS("AFTER", current_position); - DEBUG_ECHOLNPGM("<<< T()"); - } } diff --git a/Marlin/src/gcode/eeprom/M500-M504.cpp b/Marlin/src/gcode/eeprom/M500-M504.cpp index 17f9ff71faa6..26c50a6129a0 100644 --- a/Marlin/src/gcode/eeprom/M500-M504.cpp +++ b/Marlin/src/gcode/eeprom/M500-M504.cpp @@ -16,12 +16,12 @@ * 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 . + * along with this program. If not, see . * */ #include "../gcode.h" -#include "../../module/configuration_store.h" +#include "../../module/settings.h" #include "../../core/serial.h" #include "../../inc/MarlinConfig.h" @@ -58,11 +58,47 @@ void GcodeSuite::M502() { #endif // !DISABLE_M503 #if ENABLED(EEPROM_SETTINGS) + + #if ENABLED(MARLIN_DEV_MODE) + #include "../../libs/hex_print.h" + #endif + /** * M504: Validate EEPROM Contents */ void GcodeSuite::M504() { + #if ENABLED(MARLIN_DEV_MODE) + const bool dowrite = parser.seenval('W'); + if (dowrite || parser.seenval('R')) { + uint8_t val = 0; + int addr = parser.value_ushort(); + if (dowrite) { + val = parser.byteval('V'); + persistentStore.write_data(addr, &val); + SERIAL_ECHOLNPAIR("Wrote address ", addr, " with ", int(val)); + } + else { + if (parser.seenval('T')) { + const int endaddr = parser.value_ushort(); + while (addr <= endaddr) { + persistentStore.read_data(addr, &val); + SERIAL_ECHOLNPAIR("0x", hex_word(addr), ":", hex_byte(val)); + addr++; + safe_delay(10); + } + SERIAL_EOL(); + } + else { + persistentStore.read_data(addr, &val); + SERIAL_ECHOLNPAIR("Read address ", addr, " and got ", int(val)); + } + } + return; + } + #endif + if (settings.validate()) SERIAL_ECHO_MSG("EEPROM OK"); } + #endif diff --git a/Marlin/src/gcode/feature/L6470/M122.cpp b/Marlin/src/gcode/feature/L6470/M122.cpp index ec5f9aea287d..d2b7f73997f8 100644 --- a/Marlin/src/gcode/feature/L6470/M122.cpp +++ b/Marlin/src/gcode/feature/L6470/M122.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/feature/L6470/M906.cpp b/Marlin/src/gcode/feature/L6470/M906.cpp index 497fa7562295..7bd446a1ab77 100644 --- a/Marlin/src/gcode/feature/L6470/M906.cpp +++ b/Marlin/src/gcode/feature/L6470/M906.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -33,7 +33,6 @@ #include "../../../core/debug_out.h" /** - * * M906: report or set KVAL_HOLD which sets the maximum effective voltage provided by the * PWMs to the steppers * @@ -56,7 +55,6 @@ * * L6470 is used in the STEP-CLOCK mode. KVAL_HOLD is the only KVAL_xxx * that affects the effective voltage seen by the stepper. - * */ /** diff --git a/Marlin/src/gcode/feature/L6470/M916-918.cpp b/Marlin/src/gcode/feature/L6470/M916-918.cpp index a3eaf7b26a6b..8165b71e4490 100644 --- a/Marlin/src/gcode/feature/L6470/M916-918.cpp +++ b/Marlin/src/gcode/feature/L6470/M916-918.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -37,7 +37,6 @@ #include "../../../core/debug_out.h" /** - * * M916: increase KVAL_HOLD until get thermal warning * NOTE - on L6474 it is TVAL that is used * @@ -62,7 +61,6 @@ * * D - time (in seconds) to run each setting of KVAL_HOLD/TVAL * optional - defaults to zero (runs each setting once) - * */ /** @@ -187,7 +185,6 @@ void GcodeSuite::M916() { } /** - * * M917: Find minimum current thresholds * * Decrease OCD current until overcurrent error @@ -214,7 +211,6 @@ void GcodeSuite::M916() { * * K - value for KVAL_HOLD (0 - 255) (ignored for L6474) * optional - will report current value from driver if not specified - * */ void GcodeSuite::M917() { @@ -522,7 +518,6 @@ void GcodeSuite::M917() { } /** - * * M918: increase speed until error or max feedrate achieved (as shown in configuration.h)) * * J - select which driver(s) to monitor on multi-driver axis @@ -543,7 +538,6 @@ void GcodeSuite::M917() { * * M - value for microsteps (1 - 128) (optional) * optional - will report current value from driver if not specified - * */ void GcodeSuite::M918() { diff --git a/Marlin/src/gcode/feature/advance/M900.cpp b/Marlin/src/gcode/feature/advance/M900.cpp index fd500261b6ee..5c7155d7c9b5 100644 --- a/Marlin/src/gcode/feature/advance/M900.cpp +++ b/Marlin/src/gcode/feature/advance/M900.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -29,11 +29,10 @@ #include "../../../module/stepper.h" #if ENABLED(EXTRA_LIN_ADVANCE_K) - float saved_extruder_advance_K[EXTRUDERS]; + float other_extruder_advance_K[EXTRUDERS]; uint8_t lin_adv_slot = 0; #endif - /** * M900: Get or Set Linear Advance K-factor * T Which tool to address @@ -43,100 +42,106 @@ */ void GcodeSuite::M900() { + auto echo_value_oor = [](const char ltr, const bool ten=true) { + SERIAL_CHAR('?'); SERIAL_CHAR(ltr); + SERIAL_ECHOPGM(" value out of range"); + if (ten) SERIAL_ECHOPGM(" (0-10)"); + SERIAL_ECHOLNPGM("."); + }; + #if EXTRUDERS < 2 constexpr uint8_t tool_index = 0; #else const uint8_t tool_index = parser.intval('T', active_extruder); if (tool_index >= EXTRUDERS) { - SERIAL_ECHOLNPGM("?T value out of range."); + echo_value_oor('T', false); return; } #endif + float &kref = planner.extruder_advance_K[tool_index], newK = kref; + const float oldK = newK; + #if ENABLED(EXTRA_LIN_ADVANCE_K) - bool ext_slot = TEST(lin_adv_slot, tool_index); - - if (parser.seenval('S')) { - const bool slot = parser.value_bool(); - if (ext_slot != slot) { - ext_slot = slot; - SET_BIT_TO(lin_adv_slot, tool_index, slot); - planner.synchronize(); - const float temp = planner.extruder_advance_K[tool_index]; - planner.extruder_advance_K[tool_index] = saved_extruder_advance_K[tool_index]; - saved_extruder_advance_K[tool_index] = temp; - } + float &lref = other_extruder_advance_K[tool_index]; + + const bool old_slot = TEST(lin_adv_slot, tool_index), // The tool's current slot (0 or 1) + new_slot = parser.boolval('S', old_slot); // The passed slot (default = current) + + // If a new slot is being selected swap the current and + // saved K values. Do here so K/L will apply correctly. + if (new_slot != old_slot) { // Not the same slot? + SET_BIT_TO(lin_adv_slot, tool_index, new_slot); // Update the slot for the tool + newK = lref; // Get new K value from backup + lref = oldK; // Save K to backup } + // Set the main K value. Apply if the main slot is active. if (parser.seenval('K')) { - const float newK = parser.value_float(); - if (WITHIN(newK, 0, 10)) { - if (ext_slot) - saved_extruder_advance_K[tool_index] = newK; - else { - planner.synchronize(); - planner.extruder_advance_K[tool_index] = newK; - } - } - else - SERIAL_ECHOLNPGM("?K value out of range (0-10)."); + const float K = parser.value_float(); + if (!WITHIN(K, 0, 10)) echo_value_oor('K'); + else if (new_slot) lref = K; // S1 Knn + else newK = K; // S0 Knn } + // Set the extra K value. Apply if the extra slot is active. if (parser.seenval('L')) { - const float newL = parser.value_float(); - if (WITHIN(newL, 0, 10)) { - if (!ext_slot) - saved_extruder_advance_K[tool_index] = newL; - else { - planner.synchronize(); - planner.extruder_advance_K[tool_index] = newL; - } - } + const float L = parser.value_float(); + if (!WITHIN(L, 0, 10)) echo_value_oor('L'); + else if (!new_slot) lref = L; // S0 Lnn + else newK = L; // S1 Lnn + } + + #else + + if (parser.seenval('K')) { + const float K = parser.value_float(); + if (WITHIN(K, 0, 10)) + newK = K; else - SERIAL_ECHOLNPGM("?L value out of range (0-10)."); + echo_value_oor('K'); } - if (!parser.seen_any()) { + #endif + + if (newK != oldK) { + planner.synchronize(); + kref = newK; + } + + if (!parser.seen_any()) { + + #if ENABLED(EXTRA_LIN_ADVANCE_K) + #if EXTRUDERS < 2 - SERIAL_ECHOLNPAIR("Advance S", ext_slot, " K", planner.extruder_advance_K[0], - "(Slot ", 1 - ext_slot, " K", saved_extruder_advance_K[0], ")"); + SERIAL_ECHOLNPAIR("Advance S", int(new_slot), " K", kref, "(S", int(!new_slot), " K", lref, ")"); #else LOOP_L_N(i, EXTRUDERS) { - const int slot = (int)TEST(lin_adv_slot, i); - SERIAL_ECHOLNPAIR("Advance T", int(i), " S", slot, " K", planner.extruder_advance_K[i], - "(Slot ", 1 - slot, " K", saved_extruder_advance_K[i], ")"); + const bool slot = TEST(lin_adv_slot, i); + SERIAL_ECHOLNPAIR("Advance T", int(i), " S", int(slot), " K", planner.extruder_advance_K[i], + "(S", int(!slot), " K", other_extruder_advance_K[i], ")"); SERIAL_EOL(); } #endif - } - #else + #else - if (parser.seenval('K')) { - const float newK = parser.value_float(); - if (WITHIN(newK, 0, 10)) { - planner.synchronize(); - planner.extruder_advance_K[tool_index] = newK; - } - else - SERIAL_ECHOLNPGM("?K value out of range (0-10)."); - } - else { SERIAL_ECHO_START(); #if EXTRUDERS < 2 SERIAL_ECHOLNPAIR("Advance K=", planner.extruder_advance_K[0]); #else SERIAL_ECHOPGM("Advance K"); LOOP_L_N(i, EXTRUDERS) { - SERIAL_CHAR(' '); SERIAL_ECHO(int(i)); - SERIAL_CHAR('='); SERIAL_ECHO(planner.extruder_advance_K[i]); + SERIAL_CHAR(' ', '0' + i, ':'); + SERIAL_DECIMAL(planner.extruder_advance_K[i]); } SERIAL_EOL(); #endif - } - #endif + #endif + } + } #endif // LIN_ADVANCE diff --git a/Marlin/src/gcode/feature/baricuda/M126-M129.cpp b/Marlin/src/gcode/feature/baricuda/M126-M129.cpp index d96ee03af165..edeba0d270b8 100644 --- a/Marlin/src/gcode/feature/baricuda/M126-M129.cpp +++ b/Marlin/src/gcode/feature/baricuda/M126-M129.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/feature/camera/M240.cpp b/Marlin/src/gcode/feature/camera/M240.cpp index 804eec205f63..fc350d8a558c 100644 --- a/Marlin/src/gcode/feature/camera/M240.cpp +++ b/Marlin/src/gcode/feature/camera/M240.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -48,14 +48,8 @@ #ifdef PHOTO_RETRACT_MM inline void e_move_m240(const float length, const feedRate_t &fr_mm_s) { - if (length && thermalManager.hotEnoughToExtrude(active_extruder)) { - #if ENABLED(ADVANCED_PAUSE_FEATURE) - do_pause_e_move(length, fr_mm_s); - #else - current_position.e += length / planner.e_factor[active_extruder]; - line_to_current_position(fr_mm_s); - #endif - } + if (length && thermalManager.hotEnoughToExtrude(active_extruder)) + unscaled_e_move(length, fr_mm_s); } #endif @@ -90,7 +84,7 @@ inline void spin_photo_pin() { static constexpr uint32_t sequence[] = PHOTO_PULSES_US; - for (uint8_t i = 0; i < COUNT(sequence); i++) + LOOP_L_N(i, COUNT(sequence)) pulse_photo_pin(sequence[i], !(i & 1)); } @@ -106,9 +100,9 @@ * M240: Trigger a camera by... * * - CHDK : Emulate a Canon RC-1 with a configurable ON duration. - * http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ + * https://captain-slow.dk/2014/03/09/3d-printing-timelapses/ * - PHOTOGRAPH_PIN : Pulse a digital pin 16 times. - * See http://www.doc-diy.net/photo/rc-1_hacked/ + * See https://www.doc-diy.net/photo/rc-1_hacked/ * - PHOTO_SWITCH_POSITION : Bump a physical switch with the X-carriage using a * configured position, delay, and retract length. * @@ -132,7 +126,7 @@ void GcodeSuite::M240() { #ifdef PHOTO_POSITION - if (axis_unhomed_error()) return; + if (homing_needed_error()) return; const xyz_pos_t old_pos = { current_position.x + parser.linearval('A'), diff --git a/Marlin/src/gcode/feature/cancel/M486.cpp b/Marlin/src/gcode/feature/cancel/M486.cpp index 19216b2cb901..1f14ae0fd26c 100644 --- a/Marlin/src/gcode/feature/cancel/M486.cpp +++ b/Marlin/src/gcode/feature/cancel/M486.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/feature/caselight/M355.cpp b/Marlin/src/gcode/feature/caselight/M355.cpp index ff793451bde8..bb6b57f666e3 100644 --- a/Marlin/src/gcode/feature/caselight/M355.cpp +++ b/Marlin/src/gcode/feature/caselight/M355.cpp @@ -16,49 +16,51 @@ * 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 . + * along with this program. If not, see . * */ -#include "../../gcode.h" - #include "../../../inc/MarlinConfig.h" -#if HAS_CASE_LIGHT - #include "../../../feature/caselight.h" +#if ENABLED(CASE_LIGHT_ENABLE) - /** - * M355: Turn case light on/off and set brightness - * - * P Set case light brightness (PWM pin required - ignored otherwise) - * - * S Set case light on/off - * - * When S turns on the light on a PWM pin then the current brightness level is used/restored - * - * M355 P200 S0 turns off the light & sets the brightness level - * M355 S1 turns on the light with a brightness of 200 (assuming a PWM pin) - */ - void GcodeSuite::M355() { - uint8_t args = 0; - if (parser.seenval('P')) { - ++args, case_light_brightness = parser.value_byte(); - case_light_arg_flag = false; - } - if (parser.seenval('S')) { - ++args, case_light_on = parser.value_bool(); - case_light_arg_flag = true; - } - if (args) update_case_light(); +#include "../../../feature/caselight.h" +#include "../../gcode.h" - // always report case light status - SERIAL_ECHO_START(); - if (!case_light_on) { - SERIAL_ECHOLNPGM("Case light: off"); - } - else { - if (!PWM_PIN(CASE_LIGHT_PIN)) SERIAL_ECHOLNPGM("Case light: on"); - else SERIAL_ECHOLNPAIR("Case light: ", case_light_brightness); - } +/** + * M355: Turn case light on/off and set brightness + * + * P Set case light brightness (PWM pin required - ignored otherwise) + * + * S Set case light on/off + * + * When S turns on the light on a PWM pin then the current brightness level is used/restored + * + * M355 P200 S0 turns off the light & sets the brightness level + * M355 S1 turns on the light with a brightness of 200 (assuming a PWM pin) + */ +void GcodeSuite::M355() { + bool didset = false; + if (parser.seenval('P')) { + didset = true; + caselight.brightness = parser.value_byte(); + } + const bool sflag = parser.seenval('S'); + if (sflag) { + didset = true; + caselight.on = parser.value_bool(); } -#endif // HAS_CASE_LIGHT + if (didset) caselight.update(sflag); + + // Always report case light status + SERIAL_ECHO_START(); + SERIAL_ECHOPGM("Case light: "); + if (!caselight.on) + SERIAL_ECHOLNPGM(STR_OFF); + else { + if (!PWM_PIN(CASE_LIGHT_PIN)) SERIAL_ECHOLNPGM(STR_ON); + else SERIAL_ECHOLN(int(caselight.brightness)); + } +} + +#endif // CASE_LIGHT_ENABLE diff --git a/Marlin/src/gcode/feature/clean/G12.cpp b/Marlin/src/gcode/feature/clean/G12.cpp index 6d13a010be95..216db5bae374 100644 --- a/Marlin/src/gcode/feature/clean/G12.cpp +++ b/Marlin/src/gcode/feature/clean/G12.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -37,22 +37,32 @@ /** * G12: Clean the nozzle + * + * E : 0=Never or 1=Always apply the "software endstop" limits + * P0 S : Stroke cleaning with S strokes + * P1 Sn T : Zigzag cleaning with S repeats and T zigzags + * P2 Sn R : Circle cleaning with S repeats and R radius */ void GcodeSuite::G12() { // Don't allow nozzle cleaning without homing first - if (axis_unhomed_error()) return; + if (homing_needed_error()) return; + + #ifdef WIPE_SEQUENCE_COMMANDS + if (!parser.seen_any()) { + gcode.process_subcommands_now_P(PSTR(WIPE_SEQUENCE_COMMANDS)); + return; + } + #endif const uint8_t pattern = parser.ushortval('P', 0), strokes = parser.ushortval('S', NOZZLE_CLEAN_STROKES), objects = parser.ushortval('T', NOZZLE_CLEAN_TRIANGLES); - const float radius = parser.floatval('R', NOZZLE_CLEAN_CIRCLE_RADIUS); + const float radius = parser.linearval('R', NOZZLE_CLEAN_CIRCLE_RADIUS); const bool seenxyz = parser.seen("XYZ"); const uint8_t cleans = (!seenxyz || parser.boolval('X') ? _BV(X_AXIS) : 0) | (!seenxyz || parser.boolval('Y') ? _BV(Y_AXIS) : 0) - #if DISABLED(NOZZLE_CLEAN_NO_Z) - | (!seenxyz || parser.boolval('Z') ? _BV(Z_AXIS) : 0) - #endif + | TERN(NOZZLE_CLEAN_NO_Z, 0, (!seenxyz || parser.boolval('Z') ? _BV(Z_AXIS) : 0)) ; #if HAS_LEVELING @@ -60,7 +70,11 @@ void GcodeSuite::G12() { TEMPORARY_BED_LEVELING_STATE(!TEST(cleans, Z_AXIS) && planner.leveling_active); #endif + SET_SOFT_ENDSTOP_LOOSE(!parser.boolval('E')); + nozzle.clean(pattern, strokes, radius, objects, cleans); + + SET_SOFT_ENDSTOP_LOOSE(false); } #endif // NOZZLE_CLEAN_FEATURE diff --git a/Marlin/src/gcode/feature/controllerfan/M710.cpp b/Marlin/src/gcode/feature/controllerfan/M710.cpp new file mode 100644 index 000000000000..67d4ad8abf54 --- /dev/null +++ b/Marlin/src/gcode/feature/controllerfan/M710.cpp @@ -0,0 +1,81 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if ENABLED(CONTROLLER_FAN_EDITABLE) + +#include "../../gcode.h" +#include "../../../feature/controllerfan.h" + +void M710_report(const bool forReplay) { + if (!forReplay) { SERIAL_ECHOLNPGM("; Controller Fan"); SERIAL_ECHO_START(); } + SERIAL_ECHOLNPAIR(" M710" + " S", int(controllerFan.settings.active_speed), + " I", int(controllerFan.settings.idle_speed), + " A", int(controllerFan.settings.auto_mode), + " D", controllerFan.settings.duration, + " ; (", (int(controllerFan.settings.active_speed) * 100) / 255, "%" + " ", (int(controllerFan.settings.idle_speed) * 100) / 255, "%)" + ); +} + +/** + * M710: Set controller fan settings + * + * R : Reset to defaults + * S[0-255] : Fan speed when motors are active + * I[0-255] : Fan speed when motors are idle + * A[0|1] : Turn auto mode on or off + * D : Set auto mode idle duration + * + * Examples: + * M710 ; Report current Settings + * M710 R ; Reset SIAD to defaults + * M710 I64 ; Set controller fan Idle Speed to 25% + * M710 S255 ; Set controller fan Active Speed to 100% + * M710 S0 ; Set controller fan Active Speed to OFF + * M710 I255 A0 ; Set controller fan Idle Speed to 100% with Auto Mode OFF + * M710 I127 A1 S255 D160 ; Set controller fan idle speed 50%, AutoMode On, Fan speed 100%, duration to 160 Secs + */ +void GcodeSuite::M710() { + + const bool seenR = parser.seen('R'); + if (seenR) controllerFan.reset(); + + const bool seenS = parser.seenval('S'); + if (seenS) controllerFan.settings.active_speed = parser.value_byte(); + + const bool seenI = parser.seenval('I'); + if (seenI) controllerFan.settings.idle_speed = parser.value_byte(); + + const bool seenA = parser.seenval('A'); + if (seenA) controllerFan.settings.auto_mode = parser.value_bool(); + + const bool seenD = parser.seenval('D'); + if (seenD) controllerFan.settings.duration = parser.value_ushort(); + + if (!(seenR || seenS || seenI || seenA || seenD)) + M710_report(false); +} + +#endif // CONTROLLER_FAN_EDITABLE diff --git a/Marlin/src/gcode/feature/digipot/M907-M910.cpp b/Marlin/src/gcode/feature/digipot/M907-M910.cpp index a8ded07d774a..e46366620798 100644 --- a/Marlin/src/gcode/feature/digipot/M907-M910.cpp +++ b/Marlin/src/gcode/feature/digipot/M907-M910.cpp @@ -16,25 +16,25 @@ * 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 . + * along with this program. If not, see . * */ #include "../../../inc/MarlinConfig.h" -#if HAS_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM || EITHER(DIGIPOT_I2C, DAC_STEPPER_CURRENT) +#if ANY(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_PWM, HAS_MOTOR_CURRENT_I2C, HAS_MOTOR_CURRENT_DAC) #include "../../gcode.h" -#if HAS_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM +#if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM #include "../../../module/stepper.h" #endif -#if ENABLED(DIGIPOT_I2C) +#if HAS_MOTOR_CURRENT_I2C #include "../../../feature/digipot/digipot.h" #endif -#if ENABLED(DAC_STEPPER_CURRENT) +#if ENABLED(HAS_MOTOR_CURRENT_DAC) #include "../../../feature/dac/stepper_dac.h" #endif @@ -42,65 +42,61 @@ * M907: Set digital trimpot motor current using axis codes X, Y, Z, E, B, S */ void GcodeSuite::M907() { - #if HAS_DIGIPOTSS + #if HAS_MOTOR_CURRENT_SPI - LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) stepper.digipot_current(i, parser.value_int()); - if (parser.seenval('B')) stepper.digipot_current(4, parser.value_int()); - if (parser.seenval('S')) for (uint8_t i = 0; i <= 4; i++) stepper.digipot_current(i, parser.value_int()); + LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) stepper.set_digipot_current(i, parser.value_int()); + if (parser.seenval('B')) stepper.set_digipot_current(4, parser.value_int()); + if (parser.seenval('S')) LOOP_LE_N(i, 4) stepper.set_digipot_current(i, parser.value_int()); #elif HAS_MOTOR_CURRENT_PWM #if ANY_PIN(MOTOR_CURRENT_PWM_X, MOTOR_CURRENT_PWM_Y, MOTOR_CURRENT_PWM_XY) - if (parser.seenval('X') || parser.seenval('Y')) stepper.digipot_current(0, parser.value_int()); + if (parser.seenval('X') || parser.seenval('Y')) stepper.set_digipot_current(0, parser.value_int()); #endif #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z) - if (parser.seenval('Z')) stepper.digipot_current(1, parser.value_int()); + if (parser.seenval('Z')) stepper.set_digipot_current(1, parser.value_int()); #endif #if PIN_EXISTS(MOTOR_CURRENT_PWM_E) - if (parser.seenval('E')) stepper.digipot_current(2, parser.value_int()); + if (parser.seenval('E')) stepper.set_digipot_current(2, parser.value_int()); #endif #endif - #if ENABLED(DIGIPOT_I2C) + #if HAS_MOTOR_CURRENT_I2C // this one uses actual amps in floating point - LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) digipot_i2c_set_current(i, parser.value_float()); + LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) digipot_i2c.set_current(i, parser.value_float()); // Additional extruders use B,C,D for channels 4,5,6. // TODO: Change these parameters because 'E' is used. B? for (uint8_t i = E_AXIS + 1; i < DIGIPOT_I2C_NUM_CHANNELS; i++) - if (parser.seenval('B' + i - (E_AXIS + 1))) digipot_i2c_set_current(i, parser.value_float()); + if (parser.seenval('B' + i - (E_AXIS + 1))) digipot_i2c.set_current(i, parser.value_float()); #endif - #if ENABLED(DAC_STEPPER_CURRENT) + #if ENABLED(HAS_MOTOR_CURRENT_DAC) if (parser.seenval('S')) { const float dac_percent = parser.value_float(); - for (uint8_t i = 0; i <= 4; i++) dac_current_percent(i, dac_percent); + LOOP_LE_N(i, 4) stepper_dac.set_current_percent(i, dac_percent); } - LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) dac_current_percent(i, parser.value_float()); + LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) stepper_dac.set_current_percent(i, parser.value_float()); #endif } -#if HAS_DIGIPOTSS || ENABLED(DAC_STEPPER_CURRENT) +#if EITHER(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_DAC) /** * M908: Control digital trimpot directly (M908 P S) */ void GcodeSuite::M908() { - #if HAS_DIGIPOTSS - stepper.digitalPotWrite(parser.intval('P'), parser.intval('S')); - #endif - #if ENABLED(DAC_STEPPER_CURRENT) - dac_current_raw(parser.byteval('P', -1), parser.ushortval('S', 0)); - #endif + TERN_(HAS_MOTOR_CURRENT_SPI, stepper.set_digipot_value_spi(parser.intval('P'), parser.intval('S'))); + TERN_(HAS_MOTOR_CURRENT_DAC, stepper_dac.set_current_value(parser.byteval('P', -1), parser.ushortval('S', 0))); } -#endif // HAS_DIGIPOTSS || DAC_STEPPER_CURRENT + #if ENABLED(HAS_MOTOR_CURRENT_DAC) -#if ENABLED(DAC_STEPPER_CURRENT) + void GcodeSuite::M909() { stepper_dac.print_values(); } + void GcodeSuite::M910() { stepper_dac.commit_eeprom(); } - void GcodeSuite::M909() { dac_print_values(); } - void GcodeSuite::M910() { dac_commit_eeprom(); } + #endif // HAS_MOTOR_CURRENT_DAC -#endif // DAC_STEPPER_CURRENT +#endif // HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_DAC -#endif // HAS_DIGIPOTSS || DAC_STEPPER_CURRENT || HAS_MOTOR_CURRENT_PWM || DIGIPOT_I2C +#endif // HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM || HAS_MOTOR_CURRENT_I2C || HAS_MOTOR_CURRENT_DAC diff --git a/Marlin/src/gcode/feature/filwidth/M404-M407.cpp b/Marlin/src/gcode/feature/filwidth/M404-M407.cpp index 41e6e90aa167..516289fe2779 100644 --- a/Marlin/src/gcode/feature/filwidth/M404-M407.cpp +++ b/Marlin/src/gcode/feature/filwidth/M404-M407.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/feature/fwretract/G10_G11.cpp b/Marlin/src/gcode/feature/fwretract/G10_G11.cpp index 75e5b6a5886e..219502f28a8e 100644 --- a/Marlin/src/gcode/feature/fwretract/G10_G11.cpp +++ b/Marlin/src/gcode/feature/fwretract/G10_G11.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -33,11 +33,11 @@ * TODO: Handle 'G10 P' for tool settings and 'G10 L' for workspace settings */ void GcodeSuite::G10() { - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER const bool rs = parser.boolval('S'); #endif fwretract.retract(true - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER , rs #endif ); diff --git a/Marlin/src/gcode/feature/fwretract/M207-M209.cpp b/Marlin/src/gcode/feature/fwretract/M207-M209.cpp index 6c48774c307c..538f16cde60b 100644 --- a/Marlin/src/gcode/feature/fwretract/M207-M209.cpp +++ b/Marlin/src/gcode/feature/fwretract/M207-M209.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/feature/i2c/M260_M261.cpp b/Marlin/src/gcode/feature/i2c/M260_M261.cpp index ea04d2a293d5..526d9101e1c7 100644 --- a/Marlin/src/gcode/feature/i2c/M260_M261.cpp +++ b/Marlin/src/gcode/feature/i2c/M260_M261.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -31,7 +31,7 @@ /** * M260: Send data to a I2C slave device * - * This is a PoC, the formating and arguments for the GCODE will + * This is a PoC, the formatting and arguments for the GCODE will * change to be more compatible, the current proposal is: * * M260 A ; Sets the I2C slave address the data will be sent to @@ -42,7 +42,6 @@ * * M260 S1 ; Send the buffered data and reset the buffer * M260 R1 ; Reset the buffer without sending data - * */ void GcodeSuite::M260() { // Set the target address diff --git a/Marlin/src/gcode/feature/leds/M150.cpp b/Marlin/src/gcode/feature/leds/M150.cpp index 656b7e5f9035..cf09bf14ead7 100644 --- a/Marlin/src/gcode/feature/leds/M150.cpp +++ b/Marlin/src/gcode/feature/leds/M150.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -34,6 +34,12 @@ * Always sets all 3 or 4 components. If a component is left out, set to 0. * If brightness is left out, no value changed * + * With NEOPIXEL_LED: + * I Set the NeoPixel index to affect. Default: All + * + * With NEOPIXEL2_SEPARATE: + * S The NeoPixel strip to set. Default is index 0. + * * Examples: * * M150 R255 ; Turn LED red @@ -43,15 +49,36 @@ * M150 W ; Turn LED white using a white LED * M150 P127 ; Set LED 50% brightness * M150 P ; Set LED full brightness + * M150 I1 R ; Set NEOPIXEL index 1 to red + * M150 S1 I1 R ; Set SEPARATE index 1 to red */ + void GcodeSuite::M150() { - leds.set_color(MakeLEDColor( + #if ENABLED(NEOPIXEL_LED) + const uint8_t index = parser.intval('I', -1); + #if ENABLED(NEOPIXEL2_SEPARATE) + const uint8_t unit = parser.intval('S'), + brightness = unit ? neo2.brightness() : neo.brightness(); + *(unit ? &neo2.neoindex : &neo.neoindex) = index; + #else + const uint8_t brightness = neo.brightness(); + neo.neoindex = index; + #endif + #endif + + const LEDColor color = MakeLEDColor( parser.seen('R') ? (parser.has_value() ? parser.value_byte() : 255) : 0, parser.seen('U') ? (parser.has_value() ? parser.value_byte() : 255) : 0, parser.seen('B') ? (parser.has_value() ? parser.value_byte() : 255) : 0, parser.seen('W') ? (parser.has_value() ? parser.value_byte() : 255) : 0, - parser.seen('P') ? (parser.has_value() ? parser.value_byte() : 255) : neo.brightness() - )); + parser.seen('P') ? (parser.has_value() ? parser.value_byte() : 255) : brightness + ); + + #if ENABLED(NEOPIXEL2_SEPARATE) + if (unit == 1) { leds2.set_color(color); return; } + #endif + + leds.set_color(color); } #endif // HAS_COLOR_LEDS diff --git a/Marlin/src/gcode/feature/leds/M7219.cpp b/Marlin/src/gcode/feature/leds/M7219.cpp index a02ea0cc3078..a6ee71174b54 100644 --- a/Marlin/src/gcode/feature/leds/M7219.cpp +++ b/Marlin/src/gcode/feature/leds/M7219.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -25,7 +25,7 @@ #if ENABLED(MAX7219_GCODE) #include "../../gcode.h" -#include "../../../feature/Max7219_Debug_LEDs.h" +#include "../../../feature/max7219.h" /** * M7219: Control the Max7219 LED matrix @@ -79,7 +79,7 @@ void GcodeSuite::M7219() { } if (parser.seen('P')) { - for (uint8_t r = 0; r < MAX7219_LINES; r++) { + LOOP_L_N(r, MAX7219_LINES) { SERIAL_ECHOPGM("led_line["); if (r < 10) SERIAL_CHAR(' '); SERIAL_ECHO(int(r)); diff --git a/Marlin/src/gcode/feature/macro/M810-M819.cpp b/Marlin/src/gcode/feature/macro/M810-M819.cpp index c106de298aa2..7b9e1a13f1f5 100644 --- a/Marlin/src/gcode/feature/macro/M810-M819.cpp +++ b/Marlin/src/gcode/feature/macro/M810-M819.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/feature/mixing/M163-M165.cpp b/Marlin/src/gcode/feature/mixing/M163-M165.cpp index 61be64edec9d..a4cb64e7d62c 100644 --- a/Marlin/src/gcode/feature/mixing/M163-M165.cpp +++ b/Marlin/src/gcode/feature/mixing/M163-M165.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/feature/mixing/M166.cpp b/Marlin/src/gcode/feature/mixing/M166.cpp index b4618c811191..9e071a47ec27 100644 --- a/Marlin/src/gcode/feature/mixing/M166.cpp +++ b/Marlin/src/gcode/feature/mixing/M166.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -86,7 +86,14 @@ void GcodeSuite::M166() { echo_zt(mixer.gradient.end_vtool, mixer.gradient.end_z); mixer.update_mix_from_gradient(); - SERIAL_ECHOPAIR(" ; Current Z", planner.get_axis_position_mm(Z_AXIS)); + + SERIAL_ECHOPGM(" ; Current Z"); + #if ENABLED(DELTA) + get_cartesian_from_steppers(); + SERIAL_ECHO(cartes.z); + #else + SERIAL_ECHO(planner.get_axis_position_mm(Z_AXIS)); + #endif echo_mix(); } diff --git a/Marlin/src/gcode/feature/password/M510-M512.cpp b/Marlin/src/gcode/feature/password/M510-M512.cpp new file mode 100644 index 000000000000..79f1da065b3c --- /dev/null +++ b/Marlin/src/gcode/feature/password/M510-M512.cpp @@ -0,0 +1,83 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if ENABLED(PASSWORD_FEATURE) + +#include "../../../feature/password/password.h" +#include "../../../core/serial.h" +#include "../../gcode.h" + +// +// M510: Lock Printer +// +void GcodeSuite::M510() { + password.lock_machine(); +} + +// +// M511: Unlock Printer +// +#if ENABLED(PASSWORD_UNLOCK_GCODE) + + void GcodeSuite::M511() { + if (password.is_locked) { + password.value_entry = parser.ulongval('P'); + password.authentication_check(); + } + } + +#endif // PASSWORD_UNLOCK_GCODE + +// +// M512: Set/Change/Remove Password +// +#if ENABLED(PASSWORD_CHANGE_GCODE) + + void GcodeSuite::M512() { + if (password.is_set && parser.ulongval('P') != password.value) { + SERIAL_ECHOLNPGM(STR_WRONG_PASSWORD); + return; + } + + if (parser.seenval('S')) { + password.value_entry = parser.ulongval('S'); + + if (password.value_entry < CAT(1e, PASSWORD_LENGTH)) { + password.is_set = true; + password.value = password.value_entry; + SERIAL_ECHOLNPAIR(STR_PASSWORD_SET, password.value); // TODO: Update password.string + } + else + SERIAL_ECHOLNPGM(STR_PASSWORD_TOO_LONG); + } + else { + password.is_set = false; + SERIAL_ECHOLNPGM(STR_PASSWORD_REMOVED); + } + SERIAL_ECHOLNPGM(STR_REMINDER_SAVE_SETTINGS); + } + +#endif // PASSWORD_CHANGE_GCODE + +#endif // PASSWORD_FEATURE diff --git a/Marlin/src/gcode/feature/pause/G27.cpp b/Marlin/src/gcode/feature/pause/G27.cpp index 7f2f0d48b7df..3ce618d67568 100644 --- a/Marlin/src/gcode/feature/pause/G27.cpp +++ b/Marlin/src/gcode/feature/pause/G27.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -34,7 +34,7 @@ */ void GcodeSuite::G27() { // Don't allow nozzle parking without homing first - if (axis_unhomed_error()) return; + if (homing_needed_error()) return; nozzle.park(parser.ushortval('P')); } diff --git a/Marlin/src/gcode/feature/pause/G60.cpp b/Marlin/src/gcode/feature/pause/G60.cpp index 45a8734ca3b3..6f695b99a942 100644 --- a/Marlin/src/gcode/feature/pause/G60.cpp +++ b/Marlin/src/gcode/feature/pause/G60.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -24,7 +24,6 @@ #if SAVED_POSITIONS -#include "../../../core/language.h" #include "../../gcode.h" #include "../../../module/motion.h" diff --git a/Marlin/src/gcode/feature/pause/G61.cpp b/Marlin/src/gcode/feature/pause/G61.cpp index e6e5180192e6..d8049f02bcef 100644 --- a/Marlin/src/gcode/feature/pause/G61.cpp +++ b/Marlin/src/gcode/feature/pause/G61.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -24,7 +24,6 @@ #if SAVED_POSITIONS -#include "../../../core/language.h" #include "../../../module/planner.h" #include "../../gcode.h" #include "../../../module/motion.h" @@ -56,16 +55,16 @@ void GcodeSuite::G61(void) { SERIAL_ECHOPAIR(STR_RESTORING_POS " S", int(slot)); LOOP_XYZ(i) { - destination[i] = parser.seen(axis_codes[i]) + destination[i] = parser.seen(XYZ_CHAR(i)) ? stored_position[slot][i] + parser.value_axis_units((AxisEnum)i) : current_position[i]; - SERIAL_CHAR(' ', axis_codes[i]); + SERIAL_CHAR(' ', XYZ_CHAR(i)); SERIAL_ECHO_F(destination[i]); } SERIAL_EOL(); // Move to the saved position - prepare_move_to_destination(); + prepare_line_to_destination(); } #endif // SAVED_POSITIONS diff --git a/Marlin/src/gcode/feature/pause/M125.cpp b/Marlin/src/gcode/feature/pause/M125.cpp index 6cf0847a9dc4..db78e870d71a 100644 --- a/Marlin/src/gcode/feature/pause/M125.cpp +++ b/Marlin/src/gcode/feature/pause/M125.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -36,7 +36,7 @@ #endif #if ENABLED(POWER_LOSS_RECOVERY) - #include "../../../feature/power_loss_recovery.h" + #include "../../../feature/powerloss.h" #endif /** @@ -56,11 +56,7 @@ */ void GcodeSuite::M125() { // Initial retract before move to filament change position - const float retract = -ABS(parser.seen('L') ? parser.value_axis_units(E_AXIS) : 0 - #ifdef PAUSE_PARK_RETRACT_LENGTH - + (PAUSE_PARK_RETRACT_LENGTH) - #endif - ); + const float retract = -ABS(parser.seen('L') ? parser.value_axis_units(E_AXIS) : (PAUSE_PARK_RETRACT_LENGTH)); xyz_pos_t park_point = NOZZLE_PARK_POINT; @@ -75,26 +71,17 @@ void GcodeSuite::M125() { park_point += hotend_offset[active_extruder]; #endif - #if ENABLED(SDSUPPORT) - const bool sd_printing = IS_SD_PRINTING(); - #else - constexpr bool sd_printing = false; - #endif + const bool sd_printing = TERN0(SDSUPPORT, IS_SD_PRINTING()); - #if HAS_LCD_MENU - lcd_pause_show_message(PAUSE_MESSAGE_PAUSING, PAUSE_MODE_PAUSE_PRINT); - const bool show_lcd = parser.seenval('P'); - #else - constexpr bool show_lcd = false; - #endif + TERN_(HAS_LCD_MENU, lcd_pause_show_message(PAUSE_MESSAGE_PARKING, PAUSE_MODE_PAUSE_PRINT)); + + const bool show_lcd = TERN0(HAS_LCD_MENU, parser.seenval('P')); if (pause_print(retract, park_point, 0, show_lcd)) { - #if ENABLED(POWER_LOSS_RECOVERY) - if (recovery.enabled) recovery.save(true); - #endif - if (!sd_printing || show_lcd) { + TERN_(POWER_LOSS_RECOVERY, if (recovery.enabled) recovery.save(true)); + if (ENABLED(EXTENSIBLE_UI) || !sd_printing || show_lcd) { wait_for_confirmation(false, 0); - resume_print(0, 0, PAUSE_PARK_RETRACT_LENGTH, 0); + resume_print(0, 0, -retract, 0); } } } diff --git a/Marlin/src/gcode/feature/pause/M600.cpp b/Marlin/src/gcode/feature/pause/M600.cpp index fc7702796be1..7c9be54b2916 100644 --- a/Marlin/src/gcode/feature/pause/M600.cpp +++ b/Marlin/src/gcode/feature/pause/M600.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -29,7 +29,7 @@ #include "../../../module/motion.h" #include "../../../module/printcounter.h" -#if EXTRUDERS > 1 +#if HAS_MULTI_EXTRUDER #include "../../../module/tool_change.h" #endif @@ -45,6 +45,10 @@ #include "../../../feature/mixing.h" #endif +#if HAS_FILAMENT_SENSOR + #include "../../../feature/runout.h" +#endif + /** * M600: Pause for filament change * @@ -56,6 +60,7 @@ * L[distance] - Extrude distance for insertion (manual reload) * B[count] - Number of times to beep, -1 for indefinite (if equipped with a buzzer) * T[toolhead] - Select extruder for filament change + * R[temp] - Resume temperature (in current units) * * Default values are used for omitted arguments. */ @@ -83,7 +88,7 @@ void GcodeSuite::M600() { // In this case, for duplicating modes set DXC_ext to the extruder that ran out. #if HAS_FILAMENT_SENSOR && NUM_RUNOUT_SENSORS > 1 if (dxc_is_duplicating()) - DXC_ext = (READ(FIL_RUNOUT2_PIN) == FIL_RUNOUT_INVERTING) ? 1 : 0; + DXC_ext = (READ(FIL_RUNOUT2_PIN) == FIL_RUNOUT_STATE) ? 1 : 0; #else DXC_ext = active_extruder; #endif @@ -96,27 +101,19 @@ void GcodeSuite::M600() { #endif #if ENABLED(HOME_BEFORE_FILAMENT_CHANGE) - // Don't allow filament change without homing first - if (axes_need_homing()) home_all_axes(); + // If needed, home before parking for filament change + if (!all_axes_known()) home_all_axes(); #endif - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER // Change toolhead if specified const uint8_t active_extruder_before_filament_change = active_extruder; - if ( - active_extruder != target_extruder - #if ENABLED(DUAL_X_CARRIAGE) - && dual_x_carriage_mode != DXC_DUPLICATION_MODE && dual_x_carriage_mode != DXC_MIRRORED_MODE - #endif - ) tool_change(target_extruder, false); + if (active_extruder != target_extruder && TERN1(DUAL_X_CARRIAGE, !dxc_is_duplicating())) + tool_change(target_extruder, false); #endif // Initial retract before move to filament change position - const float retract = -ABS(parser.seen('E') ? parser.value_axis_units(E_AXIS) : 0 - #ifdef PAUSE_PARK_RETRACT_LENGTH - + (PAUSE_PARK_RETRACT_LENGTH) - #endif - ); + const float retract = -ABS(parser.seen('E') ? parser.value_axis_units(E_AXIS) : (PAUSE_PARK_RETRACT_LENGTH)); xyz_pos_t park_point NOZZLE_PARK_POINT; @@ -149,11 +146,9 @@ void GcodeSuite::M600() { : fc_settings[active_extruder].load_length); #endif - const int beep_count = parser.intval('B', + const int beep_count = parser.intval('B', -1 #ifdef FILAMENT_CHANGE_ALERT_BEEPS - FILAMENT_CHANGE_ALERT_BEEPS - #else - -1 + + 1 + FILAMENT_CHANGE_ALERT_BEEPS #endif ); @@ -163,19 +158,18 @@ void GcodeSuite::M600() { resume_print(slow_load_length, fast_load_length, 0, beep_count DXC_PASS); #else wait_for_confirmation(true, beep_count DXC_PASS); - resume_print(slow_load_length, fast_load_length, ADVANCED_PAUSE_PURGE_LENGTH, beep_count DXC_PASS); + resume_print(slow_load_length, fast_load_length, ADVANCED_PAUSE_PURGE_LENGTH, + beep_count, (parser.seenval('R') ? parser.value_celsius() : 0) DXC_PASS); #endif } - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER // Restore toolhead if it was changed if (active_extruder_before_filament_change != active_extruder) tool_change(active_extruder_before_filament_change, false); #endif - #if ENABLED(MIXING_EXTRUDER) - mixer.T(old_mixing_tool); // Restore original mixing tool - #endif + TERN_(MIXING_EXTRUDER, mixer.T(old_mixing_tool)); // Restore original mixing tool } #endif // ADVANCED_PAUSE_FEATURE diff --git a/Marlin/src/gcode/feature/pause/M603.cpp b/Marlin/src/gcode/feature/pause/M603.cpp index 620b8f4f27d5..9c3b774bd2b2 100644 --- a/Marlin/src/gcode/feature/pause/M603.cpp +++ b/Marlin/src/gcode/feature/pause/M603.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -29,7 +29,7 @@ #include "../../../module/motion.h" #include "../../../module/printcounter.h" -#if EXTRUDERS > 1 +#if HAS_MULTI_EXTRUDER #include "../../../module/tool_change.h" #endif @@ -39,7 +39,6 @@ * T[toolhead] - Select extruder to configure, active extruder if not specified * U[distance] - Retract distance for removal, for the specified extruder * L[distance] - Extrude distance for insertion, for the specified extruder - * */ void GcodeSuite::M603() { diff --git a/Marlin/src/gcode/feature/pause/M701_M702.cpp b/Marlin/src/gcode/feature/pause/M701_M702.cpp index be76814c0d9a..c1f7223142c3 100644 --- a/Marlin/src/gcode/feature/pause/M701_M702.cpp +++ b/Marlin/src/gcode/feature/pause/M701_M702.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -30,7 +30,7 @@ #include "../../../module/temperature.h" #include "../../../feature/pause.h" -#if EXTRUDERS > 1 +#if HAS_MULTI_EXTRUDER #include "../../../module/tool_change.h" #endif @@ -39,7 +39,7 @@ #endif #if ENABLED(PRUSA_MMU2) - #include "../../../feature/prusa_MMU2/mmu2.h" + #include "../../../feature/mmu2/mmu2.h" #endif #if ENABLED(MIXING_EXTRUDER) @@ -61,7 +61,7 @@ void GcodeSuite::M701() { #if ENABLED(NO_MOTION_BEFORE_HOMING) // Don't raise Z if the machine isn't homed - if (axes_need_homing()) park_point.z = 0; + if (axes_should_home()) park_point.z = 0; #endif #if ENABLED(MIXING_EXTRUDER) @@ -84,11 +84,9 @@ void GcodeSuite::M701() { if (parser.seenval('Z')) park_point.z = parser.linearval('Z'); // Show initial "wait for load" message - #if HAS_LCD_MENU - lcd_pause_show_message(PAUSE_MESSAGE_LOAD, PAUSE_MODE_LOAD_FILAMENT, target_extruder); - #endif + TERN_(HAS_LCD_MENU, lcd_pause_show_message(PAUSE_MESSAGE_LOAD, PAUSE_MODE_LOAD_FILAMENT, target_extruder)); - #if EXTRUDERS > 1 && DISABLED(PRUSA_MMU2) + #if HAS_MULTI_EXTRUDER && DISABLED(PRUSA_MMU2) // Change toolhead if specified uint8_t active_extruder_before_filament_change = active_extruder; if (active_extruder != target_extruder) @@ -123,20 +121,16 @@ void GcodeSuite::M701() { if (park_point.z > 0) do_blocking_move_to_z(_MAX(current_position.z - park_point.z, 0), feedRate_t(NOZZLE_PARK_Z_FEEDRATE)); - #if EXTRUDERS > 1 && DISABLED(PRUSA_MMU2) + #if HAS_MULTI_EXTRUDER && DISABLED(PRUSA_MMU2) // Restore toolhead if it was changed if (active_extruder_before_filament_change != active_extruder) tool_change(active_extruder_before_filament_change, false); #endif - #if ENABLED(MIXING_EXTRUDER) - mixer.T(old_mixing_tool); // Restore original mixing tool - #endif + TERN_(MIXING_EXTRUDER, mixer.T(old_mixing_tool)); // Restore original mixing tool // Show status screen - #if HAS_LCD_MENU - lcd_pause_show_message(PAUSE_MESSAGE_STATUS); - #endif + TERN_(HAS_LCD_MENU, lcd_pause_show_message(PAUSE_MESSAGE_STATUS)); } /** @@ -155,7 +149,7 @@ void GcodeSuite::M702() { #if ENABLED(NO_MOTION_BEFORE_HOMING) // Don't raise Z if the machine isn't homed - if (axes_need_homing()) park_point.z = 0; + if (axes_should_home()) park_point.z = 0; #endif #if ENABLED(MIXING_EXTRUDER) @@ -163,16 +157,18 @@ void GcodeSuite::M702() { #if ENABLED(FILAMENT_UNLOAD_ALL_EXTRUDERS) float mix_multiplier = 1.0; - if (!parser.seenval('T')) { + const bool seenT = parser.seenval('T'); + if (!seenT) { mixer.T(MIXER_AUTORETRACT_TOOL); mix_multiplier = MIXING_STEPPERS; } - else + #else + constexpr bool seenT = true; #endif - { + + if (seenT) { const int8_t target_e_stepper = get_target_e_stepper_from_command(); if (target_e_stepper < 0) return; - mixer.T(MIXER_DIRECT_SET_TOOL); MIXER_STEPPER_LOOP(i) mixer.set_collector(i, (i == (uint8_t)target_e_stepper) ? 1.0 : 0.0); mixer.normalize(); @@ -188,11 +184,9 @@ void GcodeSuite::M702() { if (parser.seenval('Z')) park_point.z = parser.linearval('Z'); // Show initial "wait for unload" message - #if HAS_LCD_MENU - lcd_pause_show_message(PAUSE_MESSAGE_UNLOAD, PAUSE_MODE_UNLOAD_FILAMENT, target_extruder); - #endif + TERN_(HAS_LCD_MENU, lcd_pause_show_message(PAUSE_MESSAGE_UNLOAD, PAUSE_MODE_UNLOAD_FILAMENT, target_extruder)); - #if EXTRUDERS > 1 && DISABLED(PRUSA_MMU2) + #if HAS_MULTI_EXTRUDER && DISABLED(PRUSA_MMU2) // Change toolhead if specified uint8_t active_extruder_before_filament_change = active_extruder; if (active_extruder != target_extruder) @@ -207,7 +201,7 @@ void GcodeSuite::M702() { #if ENABLED(PRUSA_MMU2) mmu2.unload(); #else - #if EXTRUDERS > 1 && ENABLED(FILAMENT_UNLOAD_ALL_EXTRUDERS) + #if BOTH(HAS_MULTI_EXTRUDER, FILAMENT_UNLOAD_ALL_EXTRUDERS) if (!parser.seenval('T')) { HOTEND_LOOP() { if (e != active_extruder) tool_change(e, false); @@ -233,20 +227,16 @@ void GcodeSuite::M702() { if (park_point.z > 0) do_blocking_move_to_z(_MAX(current_position.z - park_point.z, 0), feedRate_t(NOZZLE_PARK_Z_FEEDRATE)); - #if EXTRUDERS > 1 && DISABLED(PRUSA_MMU2) + #if HAS_MULTI_EXTRUDER && DISABLED(PRUSA_MMU2) // Restore toolhead if it was changed if (active_extruder_before_filament_change != active_extruder) tool_change(active_extruder_before_filament_change, false); #endif - #if ENABLED(MIXING_EXTRUDER) - mixer.T(old_mixing_tool); // Restore original mixing tool - #endif + TERN_(MIXING_EXTRUDER, mixer.T(old_mixing_tool)); // Restore original mixing tool // Show status screen - #if HAS_LCD_MENU - lcd_pause_show_message(PAUSE_MESSAGE_STATUS); - #endif + TERN_(HAS_LCD_MENU, lcd_pause_show_message(PAUSE_MESSAGE_STATUS)); } #endif // ADVANCED_PAUSE_FEATURE diff --git a/Marlin/src/gcode/feature/power_monitor/M430.cpp b/Marlin/src/gcode/feature/power_monitor/M430.cpp new file mode 100644 index 000000000000..7639ea962d9b --- /dev/null +++ b/Marlin/src/gcode/feature/power_monitor/M430.cpp @@ -0,0 +1,70 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfig.h" + +#if HAS_POWER_MONITOR + +#include "../../../feature/power_monitor.h" +#include "../../../MarlinCore.h" +#include "../../gcode.h" + +/** + * M430: Enable/disable current LCD display + * With no parameters report the system current draw (in Amps) + * + * I[bool] - Set Display of current on the LCD + * V[bool] - Set Display of voltage on the LCD + * W[bool] - Set Display of power on the LCD + */ +void GcodeSuite::M430() { + bool do_report = true; + #if HAS_WIRED_LCD + #if ENABLED(POWER_MONITOR_CURRENT) + if (parser.seen('I')) { power_monitor.set_current_display(parser.value_bool()); do_report = false; } + #endif + #if HAS_POWER_MONITOR_VREF + if (parser.seen('V')) { power_monitor.set_voltage_display(parser.value_bool()); do_report = false; } + #endif + #if HAS_POWER_MONITOR_WATTS + if (parser.seen('W')) { power_monitor.set_power_display(parser.value_bool()); do_report = false; } + #endif + #endif + if (do_report) { + SERIAL_ECHOLNPAIR( + #if ENABLED(POWER_MONITOR_CURRENT) + "Current: ", power_monitor.getAmps(), "A" + #if HAS_POWER_MONITOR_VREF + " " + #endif + #endif + #if HAS_POWER_MONITOR_VREF + "Voltage: ", power_monitor.getVolts(), "V" + #endif + #if HAS_POWER_MONITOR_WATTS + " Power: ", power_monitor.getPower(), "W" + #endif + ); + } +} + +#endif // HAS_POWER_MONITOR diff --git a/Marlin/src/gcode/feature/powerloss/M1000.cpp b/Marlin/src/gcode/feature/powerloss/M1000.cpp index 546fea9bdeb5..e9477dd2fbf3 100644 --- a/Marlin/src/gcode/feature/powerloss/M1000.cpp +++ b/Marlin/src/gcode/feature/powerloss/M1000.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -25,11 +25,11 @@ #if ENABLED(POWER_LOSS_RECOVERY) #include "../../gcode.h" -#include "../../../feature/power_loss_recovery.h" +#include "../../../feature/powerloss.h" #include "../../../module/motion.h" #include "../../../lcd/ultralcd.h" #if ENABLED(EXTENSIBLE_UI) - #include "../../../lcd/extensible_ui/ui_api.h" + #include "../../../lcd/extui/ui_api.h" #endif #define DEBUG_OUT ENABLED(DEBUG_POWER_LOSS_RECOVERY) @@ -41,7 +41,7 @@ inline void plr_error(PGM_P const prefix) { #if ENABLED(DEBUG_POWER_LOSS_RECOVERY) DEBUG_ECHO_START(); serialprintPGM(prefix); - DEBUG_ECHOLNPGM(" Power-Loss Recovery Data"); + DEBUG_ECHOLNPGM(" Job Recovery Data"); #else UNUSED(prefix); #endif @@ -62,8 +62,10 @@ void GcodeSuite::M1000() { if (parser.seen('S')) { #if HAS_LCD_MENU ui.goto_screen(menu_job_recovery); + #elif ENABLED(DWIN_CREALITY_LCD) + recovery.dwin_flag = true; #elif ENABLED(EXTENSIBLE_UI) - ExtUI::OnPowerLossResume(); + ExtUI::onPowerLossResume(); #else SERIAL_ECHO_MSG("Resume requires LCD."); #endif @@ -74,9 +76,7 @@ void GcodeSuite::M1000() { #else recovery.cancel(); #endif - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onPrintTimerStopped(); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onPrintTimerStopped()); } else recovery.resume(); diff --git a/Marlin/src/gcode/feature/powerloss/M413.cpp b/Marlin/src/gcode/feature/powerloss/M413.cpp index 2b3f478b203a..3538ccaa6e07 100644 --- a/Marlin/src/gcode/feature/powerloss/M413.cpp +++ b/Marlin/src/gcode/feature/powerloss/M413.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -25,7 +25,7 @@ #if ENABLED(POWER_LOSS_RECOVERY) #include "../../gcode.h" -#include "../../../feature/power_loss_recovery.h" +#include "../../../feature/powerloss.h" #include "../../../module/motion.h" #include "../../../lcd/ultralcd.h" @@ -50,6 +50,10 @@ void GcodeSuite::M413() { if (parser.seen("RL")) recovery.load(); if (parser.seen('W')) recovery.save(true); if (parser.seen('P')) recovery.purge(); + if (parser.seen('D')) recovery.debug(PSTR("M413")); + #if PIN_EXISTS(POWER_LOSS) + if (parser.seen('O')) recovery._outage(); + #endif if (parser.seen('E')) serialprintPGM(recovery.exists() ? PSTR("PLR Exists\n") : PSTR("No PLR\n")); if (parser.seen('V')) serialprintPGM(recovery.valid() ? PSTR("Valid\n") : PSTR("Invalid\n")); #endif diff --git a/Marlin/src/gcode/feature/prusa_MMU2/M403.cpp b/Marlin/src/gcode/feature/prusa_MMU2/M403.cpp index b9b74ebf71dd..91e35dbf657c 100644 --- a/Marlin/src/gcode/feature/prusa_MMU2/M403.cpp +++ b/Marlin/src/gcode/feature/prusa_MMU2/M403.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -25,7 +25,7 @@ #if ENABLED(PRUSA_MMU2) #include "../../gcode.h" -#include "../../../feature/prusa_MMU2/mmu2.h" +#include "../../../feature/mmu2/mmu2.h" /** * M403: Set filament type for MMU2 diff --git a/Marlin/src/gcode/feature/runout/M412.cpp b/Marlin/src/gcode/feature/runout/M412.cpp index f746dddfa1ea..130f9c83e3ac 100644 --- a/Marlin/src/gcode/feature/runout/M412.cpp +++ b/Marlin/src/gcode/feature/runout/M412.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -29,15 +29,17 @@ /** * M412: Enable / Disable filament runout detection + * + * Parameters + * R : Reset the runout sensor + * S : Reset and enable/disable the runout sensor + * H : Enable/disable host handling of filament runout + * D : Extra distance to continue after runout is triggered */ void GcodeSuite::M412() { if (parser.seen("RS" - #ifdef FILAMENT_RUNOUT_DISTANCE_MM - "D" - #endif - #if ENABLED(HOST_ACTION_COMMANDS) - "H" - #endif + TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, "D") + TERN_(HOST_ACTION_COMMANDS, "H") )) { #if ENABLED(HOST_ACTION_COMMANDS) if (parser.seen('H')) runout.host_handling = parser.value_bool(); @@ -45,7 +47,7 @@ void GcodeSuite::M412() { const bool seenR = parser.seen('R'), seenS = parser.seen('S'); if (seenR || seenS) runout.reset(); if (seenS) runout.enabled = parser.value_bool(); - #ifdef FILAMENT_RUNOUT_DISTANCE_MM + #if HAS_FILAMENT_RUNOUT_DISTANCE if (parser.seen('D')) runout.set_runout_distance(parser.value_linear_units()); #endif } @@ -53,7 +55,7 @@ void GcodeSuite::M412() { SERIAL_ECHO_START(); SERIAL_ECHOPGM("Filament runout "); serialprintln_onoff(runout.enabled); - #ifdef FILAMENT_RUNOUT_DISTANCE_MM + #if HAS_FILAMENT_RUNOUT_DISTANCE SERIAL_ECHOLNPAIR("Filament runout distance (mm): ", runout.runout_distance()); #endif } diff --git a/Marlin/src/gcode/feature/trinamic/M122.cpp b/Marlin/src/gcode/feature/trinamic/M122.cpp index bba6e7e752aa..46e4365f38c2 100644 --- a/Marlin/src/gcode/feature/trinamic/M122.cpp +++ b/Marlin/src/gcode/feature/trinamic/M122.cpp @@ -16,16 +16,17 @@ * 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 . + * along with this program. If not, see . * */ #include "../../../inc/MarlinConfig.h" -#if HAS_TRINAMIC +#if HAS_TRINAMIC_CONFIG #include "../../gcode.h" #include "../../../feature/tmc_util.h" +#include "../../../module/stepper/indirection.h" /** * M122: Debug TMC drivers @@ -37,11 +38,14 @@ void GcodeSuite::M122() { if (print_all) LOOP_XYZE(i) print_axis[i] = true; + if (parser.boolval('I')) restore_stepper_drivers(); + #if ENABLED(TMC_DEBUG) #if ENABLED(MONITOR_DRIVER_STATUS) - const bool sflag = parser.seen('S'), s0 = sflag && !parser.value_bool(); - if (sflag) tmc_set_report_interval(s0 ? 0 : MONITOR_DRIVER_STATUS_INTERVAL_MS); - if (!s0 && parser.seenval('P')) tmc_set_report_interval(_MIN(parser.value_ushort(), MONITOR_DRIVER_STATUS_INTERVAL_MS)); + uint16_t interval = MONITOR_DRIVER_STATUS_INTERVAL_MS; + if (parser.seen('S') && !parser.value_bool()) interval = 0; + if (parser.seenval('P')) NOMORE(interval, parser.value_ushort()); + tmc_set_report_interval(interval); #endif if (parser.seen('V')) @@ -53,4 +57,4 @@ void GcodeSuite::M122() { test_tmc_connection(print_axis.x, print_axis.y, print_axis.z, print_axis.e); } -#endif // HAS_TRINAMIC +#endif // HAS_TRINAMIC_CONFIG diff --git a/Marlin/src/gcode/feature/trinamic/M569.cpp b/Marlin/src/gcode/feature/trinamic/M569.cpp index f88e116839d6..e72d03e76728 100644 --- a/Marlin/src/gcode/feature/trinamic/M569.cpp +++ b/Marlin/src/gcode/feature/trinamic/M569.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/feature/trinamic/M906.cpp b/Marlin/src/gcode/feature/trinamic/M906.cpp index bb2659913ac7..e834ebd67d95 100644 --- a/Marlin/src/gcode/feature/trinamic/M906.cpp +++ b/Marlin/src/gcode/feature/trinamic/M906.cpp @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #include "../../../inc/MarlinConfig.h" -#if HAS_TRINAMIC +#if HAS_TRINAMIC_CONFIG #include "../../gcode.h" #include "../../../feature/tmc_util.h" @@ -170,4 +170,4 @@ void GcodeSuite::M906() { } } -#endif // HAS_TRINAMIC +#endif // HAS_TRINAMIC_CONFIG diff --git a/Marlin/src/gcode/feature/trinamic/M911-M914.cpp b/Marlin/src/gcode/feature/trinamic/M911-M914.cpp index 505ac14d8777..8c840db5bf9c 100644 --- a/Marlin/src/gcode/feature/trinamic/M911-M914.cpp +++ b/Marlin/src/gcode/feature/trinamic/M911-M914.cpp @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #include "../../../inc/MarlinConfig.h" -#if HAS_TRINAMIC +#if HAS_TRINAMIC_CONFIG #include "../../gcode.h" #include "../../../feature/tmc_util.h" @@ -348,7 +348,7 @@ bool report = true; const uint8_t index = parser.byteval('I'); - LOOP_XYZ(i) if (parser.seen(axis_codes[i])) { + LOOP_XYZ(i) if (parser.seen(XYZ_CHAR(i))) { const int16_t value = parser.value_int(); report = false; switch (i) { @@ -426,4 +426,4 @@ } #endif // USE_SENSORLESS -#endif // HAS_TRINAMIC +#endif // HAS_TRINAMIC_CONFIG diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp index 0d2b656dd6e7..f2eb37b304e5 100644 --- a/Marlin/src/gcode/gcode.cpp +++ b/Marlin/src/gcode/gcode.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -46,16 +46,27 @@ GcodeSuite gcode; #if ENABLED(POWER_LOSS_RECOVERY) #include "../sd/cardreader.h" - #include "../feature/power_loss_recovery.h" + #include "../feature/powerloss.h" #endif #if ENABLED(CANCEL_OBJECTS) #include "../feature/cancel_object.h" #endif +#if ENABLED(LASER_MOVE_POWER) + #include "../feature/spindle_laser.h" +#endif + +#if ENABLED(PASSWORD_FEATURE) + #include "../feature/password/password.h" +#endif + #include "../MarlinCore.h" // for idle() -millis_t GcodeSuite::previous_move_ms; +// Inactivity shutdown +millis_t GcodeSuite::previous_move_ms = 0, + GcodeSuite::max_inactive_time = 0, + GcodeSuite::stepper_inactive_time = SEC_TO_MS(DEFAULT_STEPPER_DEACTIVE_TIME); // Relative motion mode for each logical axis static constexpr xyze_bool_t ar_init = AXIS_RELATIVE_MODES; @@ -66,7 +77,7 @@ uint8_t GcodeSuite::axis_relative = ( | (ar_init.e ? _BV(REL_E) : 0) ); -#if HAS_AUTO_REPORTING || ENABLED(HOST_KEEPALIVE_FEATURE) +#if EITHER(HAS_AUTO_REPORTING, HOST_KEEPALIVE_FEATURE) bool GcodeSuite::autoreport_paused; // = false #endif @@ -135,7 +146,7 @@ void GcodeSuite::get_destination_from_command() { // Get new XYZ position, whether absolute or relative LOOP_XYZ(i) { - if ( (seen[i] = parser.seenval(axis_codes[i])) ) { + if ( (seen[i] = parser.seenval(XYZ_CHAR(i))) ) { const float v = parser.value_axis_units((AxisEnum)i); if (skip_move) destination[i] = current_position[i]; @@ -172,6 +183,16 @@ void GcodeSuite::get_destination_from_command() { #if BOTH(MIXING_EXTRUDER, DIRECT_MIXING_IN_G1) M165(); #endif + + #if ENABLED(LASER_MOVE_POWER) + // Set the laser power in the planner to configure this move + if (parser.seen('S')) { + const float spwr = parser.value_float(); + cutter.inline_power(TERN(SPINDLE_LASER_PWM, cutter.power_to_range(cutter_power_t(round(spwr))), spwr > 0 ? 255 : 0)); + } + else if (ENABLED(LASER_MOVE_G0_OFF) && parser.codenum == 0) // G0 + cutter.set_inline_enabled(false); + #endif } /** @@ -186,7 +207,7 @@ void GcodeSuite::dwell(millis_t time) { * When G29_RETRY_AND_RECOVER is enabled, call G29() in * a loop with recovery and retry handling. */ -#if HAS_LEVELING && ENABLED(G29_RETRY_AND_RECOVER) +#if BOTH(HAS_LEVELING, G29_RETRY_AND_RECOVER) #ifndef G29_MAX_RETRIES #define G29_MAX_RETRIES 0 @@ -202,9 +223,7 @@ void GcodeSuite::dwell(millis_t time) { } } - #if ENABLED(HOST_PROMPT_SUPPORT) - host_action_prompt_end(); - #endif + TERN_(HOST_PROMPT_SUPPORT, host_action_prompt_end()); #ifdef G29_SUCCESS_COMMANDS process_subcommands_now_P(PSTR(G29_SUCCESS_COMMANDS)); @@ -226,16 +245,24 @@ void GcodeSuite::dwell(millis_t time) { void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { KEEPALIVE_STATE(IN_HANDLER); + /** + * Block all Gcodes except M511 Unlock Printer, if printer is locked + * Will still block Gcodes if M511 is disabled, in which case the printer should be unlocked via LCD Menu + */ + #if ENABLED(PASSWORD_FEATURE) + if (password.is_locked && !(parser.command_letter == 'M' && parser.codenum == 511)) { + SERIAL_ECHO_MSG(STR_PRINTER_LOCKED); + if (!no_ok) queue.ok_to_send(); + return; + } + #endif + // Handle a known G, M, or T switch (parser.command_letter) { case 'G': switch (parser.codenum) { - case 0: case 1: G0_G1( // G0: Fast Move, G1: Linear Move - #if IS_SCARA || defined(G0_FEEDRATE) - parser.codenum == 0 - #endif - ); - break; + case 0: case 1: // G0: Fast Move, G1: Linear Move + G0_G1(TERN_(HAS_FAST_MOVES, parser.codenum == 0)); break; #if ENABLED(ARC_SUPPORT) && DISABLED(SCARA) case 2: case 3: G2_G3(parser.codenum == 2); break; // G2: CW ARC, G3: CCW ARC @@ -247,6 +274,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 5: G5(); break; // G5: Cubic B_spline #endif + #if ENABLED(DIRECT_STEPPING) + case 6: G6(); break; // G6: Direct Stepper Move + #endif + #if ENABLED(FWRETRACT) case 10: G10(); break; // G10: Retract / Swap Retract case 11: G11(); break; // G11: Recover / Swap Recover @@ -277,17 +308,13 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 27: G27(); break; // G27: Nozzle Park #endif - case 28: G28(false); break; // G28: Home all axes, one at a time + case 28: G28(); break; // G28: Home one or more axes #if HAS_LEVELING case 29: // G29: Bed leveling calibration - #if ENABLED(G29_RETRY_AND_RECOVER) - G29_with_retry(); - #else - G29(); - #endif + TERN(G29_RETRY_AND_RECOVER, G29_with_retry, G29)(); break; - #endif // HAS_LEVELING + #endif #if HAS_BED_PROBE case 30: G30(); break; // G30: Single Z probe @@ -301,19 +328,18 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 33: G33(); break; // G33: Delta Auto-Calibration #endif - #if ENABLED(Z_STEPPER_AUTO_ALIGN) + #if EITHER(Z_STEPPER_AUTO_ALIGN, MECHANICAL_GANTRY_CALIBRATION) case 34: G34(); break; // G34: Z Stepper automatic alignment using probe #endif + #if ENABLED(ASSISTED_TRAMMING) + case 35: G35(); break; // G35: Read four bed corners to help adjust bed screws + #endif + #if ENABLED(G38_PROBE_TARGET) case 38: // G38.2, G38.3: Probe towards target - if (WITHIN(parser.subcode, 2, - #if ENABLED(G38_PROBE_AWAY) - 5 - #else - 3 - #endif - )) G38(parser.subcode); // G38.4, G38.5: Probe away from target + if (WITHIN(parser.subcode, 2, TERN(G38_PROBE_AWAY, 5, 3))) + G38(parser.subcode); // G38.4, G38.5: Probe away from target break; #endif @@ -420,7 +446,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { #endif // SDSUPPORT case 31: M31(); break; // M31: Report time since the start of SD print or last M109 - case 42: M42(); break; // M42: Change pin state + + #if ENABLED(DIRECT_PIN_CONTROL) + case 42: M42(); break; // M42: Change pin state + #endif #if ENABLED(PINS_DEBUGGING) case 43: M43(); break; // M43: Read pin state @@ -453,7 +482,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 105: M105(); return; // M105: Report Temperatures (and say "ok") - #if FAN_COUNT > 0 + #if HAS_FAN case 106: M106(); break; // M106: Fan On case 107: M107(); break; // M107: Fan Off #endif @@ -465,14 +494,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 108: M108(); break; // M108: Cancel Waiting case 112: M112(); break; // M112: Full Shutdown case 410: M410(); break; // M410: Quickstop - Abort all the planned moves. - #if ENABLED(HOST_PROMPT_SUPPORT) - case 876: M876(); break; // M876: Handle Host prompt responses - #endif + TERN_(HOST_PROMPT_SUPPORT, case 876:) // M876: Handle Host prompt responses #else case 108: case 112: case 410: - #if ENABLED(HOST_PROMPT_SUPPORT) - case 876: - #endif + TERN_(HOST_PROMPT_SUPPORT, case 876:) break; #endif @@ -490,7 +515,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 191: M191(); break; // M191: Wait for chamber temperature to reach target #endif - #if ENABLED(AUTO_REPORT_TEMPERATURES) && HAS_TEMP_SENSOR + #if BOTH(AUTO_REPORT_TEMPERATURES, HAS_TEMP_SENSOR) case 155: M155(); break; // M155: Set temperature auto-report interval #endif @@ -530,7 +555,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 120: M120(); break; // M120: Enable endstops case 121: M121(); break; // M121: Disable endstops - #if HOTENDS && HAS_LCD_MENU + #if PREHEAT_COUNT case 145: M145(); break; // M145: Set material heatup parameters #endif @@ -585,7 +610,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 211: M211(); break; // M211: Enable, Disable, and/or Report software endstops #endif - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER case 217: M217(); break; // M217: Set filament swap parameters #endif @@ -599,7 +624,9 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 221: M221(); break; // M221: Set Flow Percentage #endif - case 226: M226(); break; // M226: Wait until a pin reaches a state + #if ENABLED(DIRECT_PIN_CONTROL) + case 226: M226(); break; // M226: Wait until a pin reaches a state + #endif #if HAS_SERVOS case 280: M280(); break; // M280: Set servo position absolute @@ -649,6 +676,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 305: M305(); break; // M305: Set user thermistor parameters #endif + #if ENABLED(REPETIER_GCODE_M360) + case 360: M360(); break; // M360: Firmware settings + #endif + #if ENABLED(MORGAN_SCARA) case 360: if (M360()) return; break; // M360: SCARA Theta pos1 case 361: if (M361()) return; break; // M361: SCARA Theta pos2 @@ -700,6 +731,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 428: M428(); break; // M428: Apply current_position to home_offset #endif + #if HAS_POWER_MONITOR + case 430: M430(); break; // M430: Read the system current (A), voltage (V), and power (W) + #endif + #if ENABLED(CANCEL_OBJECTS) case 486: M486(); break; // M486: Identify and cancel objects #endif @@ -714,6 +749,16 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 504: M504(); break; // M504: Validate EEPROM contents #endif + #if ENABLED(PASSWORD_FEATURE) + case 510: M510(); break; // M510: Lock Printer + #if ENABLED(PASSWORD_UNLOCK_GCODE) + case 511: M511(); break; // M511: Unlock Printer + #endif + #if ENABLED(PASSWORD_CHANGE_GCODE) + case 512: M512(); break; + #endif // M512: Set/Change/Remove Password + #endif + #if ENABLED(SDSUPPORT) case 524: M524(); break; // M524: Abort the current SD print job #endif @@ -743,7 +788,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 666: M666(); break; // M666: Set delta or multiple endstop adjustment #endif - #if ENABLED(SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD) + #if ENABLED(DUET_SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD) case 672: M672(); break; // M672: Set/clear Duet Smart Effector sensitivity #endif @@ -752,6 +797,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 702: M702(); break; // M702: Unload Filament #endif + #if ENABLED(CONTROLLER_FAN_EDITABLE) + case 710: M710(); break; // M710: Set Controller Fan settings + #endif + #if ENABLED(GCODE_MACROS) case 810: case 811: case 812: case 813: case 814: case 815: case 816: case 817: case 818: case 819: @@ -767,6 +816,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { #endif #if ENABLED(PROBE_TEMP_COMPENSATION) + case 192: M192(); break; // M192: Wait for probe temp case 871: M871(); break; // M871: Print/reset/clear first layer temperature offset values #endif @@ -774,18 +824,18 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 900: M900(); break; // M900: Set advance K factor. #endif - #if HAS_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM || EITHER(DIGIPOT_I2C, DAC_STEPPER_CURRENT) + #if ANY(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_PWM, HAS_MOTOR_CURRENT_I2C, HAS_MOTOR_CURRENT_DAC) case 907: M907(); break; // M907: Set digital trimpot motor current using axis codes. - #if HAS_DIGIPOTSS || ENABLED(DAC_STEPPER_CURRENT) + #if EITHER(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_DAC) case 908: M908(); break; // M908: Control digital trimpot directly. - #if ENABLED(DAC_STEPPER_CURRENT) + #if ENABLED(HAS_MOTOR_CURRENT_DAC) case 909: M909(); break; // M909: Print digipot/DAC current value case 910: M910(); break; // M910: Commit digipot/DAC value to external EEPROM #endif #endif #endif - #if HAS_TRINAMIC + #if HAS_TRINAMIC_CONFIG case 122: M122(); break; // M122: Report driver configuration and status case 906: M906(); break; // M906: Set motor current in milliamps using axis codes X, Y, Z, E #if HAS_STEALTHCHOP @@ -816,7 +866,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 351: M351(); break; // M351: Toggle MS1 MS2 pins directly, S# determines MS1 or MS2, X# sets the pin high/low. #endif - #if HAS_CASE_LIGHT + #if ENABLED(CASE_LIGHT_ENABLE) case 355: M355(); break; // M355: Set case light brightness #endif @@ -845,6 +895,15 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 422: M422(); break; // M422: Set Z Stepper automatic alignment position using probe #endif + #if ALL(HAS_SPI_FLASH, SDSUPPORT, MARLIN_DEV_MODE) + case 993: M993(); break; // M993: Backup SPI Flash to SD + case 994: M994(); break; // M994: Load a Backup from SD to SPI Flash + #endif + + #if ENABLED(TOUCH_SCREEN_CALIBRATION) + case 995: M995(); break; // M995: Touch screen calibration for TFT display + #endif + #if ENABLED(PLATFORM_M997_SUPPORT) case 997: M997(); break; // M997: Perform in-application firmware update #endif @@ -853,7 +912,11 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { #if ENABLED(POWER_LOSS_RECOVERY) case 413: M413(); break; // M413: Enable/disable/query Power-Loss Recovery - case 1000: M1000(); break; // M1000: Resume from power-loss + case 1000: M1000(); break; // M1000: [INTERNAL] Resume from power-loss + #endif + + #if ENABLED(SDSUPPORT) + case 1001: M1001(); break; // M1001: [INTERNAL] Handle SD completion #endif #if ENABLED(MAX7219_GCODE) @@ -866,6 +929,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 'T': T(parser.codenum); break; // Tn: Tool Change + #if ENABLED(MARLIN_DEV_MODE) + case 'D': D(parser.codenum); break; // Dn: Debug codes + #endif + default: #if ENABLED(WIFI_CUSTOM_COMMAND) if (wifi_custom_command(parser.command_ptr)) break; @@ -930,6 +997,7 @@ void GcodeSuite::process_subcommands_now(char * gcode) { char * const delim = strchr(gcode, '\n'); // Get address of next newline if (delim) *delim = '\0'; // Replace with nul parser.parse(gcode); // Parse the current command + if (delim) *delim = '\n'; // Put back the newline process_parsed_command(true); // Process it if (!delim) break; // Last command? gcode = delim + 1; // Get the next command @@ -963,7 +1031,7 @@ void GcodeSuite::process_subcommands_now(char * gcode) { break; } } - next_busy_signal_ms = ms + host_keepalive_interval * 1000UL; + next_busy_signal_ms = ms + SEC_TO_MS(host_keepalive_interval); } #endif // HOST_KEEPALIVE_FEATURE diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h index c44c17081131..3d745eff8939 100644 --- a/Marlin/src/gcode/gcode.h +++ b/Marlin/src/gcode/gcode.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -31,9 +31,9 @@ * ----------------- * * Helpful G-code references: - * - http://marlinfw.org/meta/gcode + * - https://marlinfw.org/meta/gcode * - https://reprap.org/wiki/G-code - * - http://linuxcnc.org/docs/html/gcode.html + * - https://linuxcnc.org/docs/html/gcode.html * * Help to document Marlin's G-codes online: * - https://github.com/MarlinFirmware/MarlinDocumentation @@ -65,6 +65,7 @@ * G32 - Undock sled (Z_PROBE_SLED only) * G33 - Delta Auto-Calibration (Requires DELTA_AUTO_CALIBRATION) * G34 - Z Stepper automatic alignment using probe: I T A (Requires Z_STEPPER_AUTO_ALIGN) + * G35 - Read bed corners to help adjust bed screws: T (Requires ASSISTED_TRAMMING) * G38 - Probe in any direction using the Z_MIN_PROBE (Requires G38_PROBE_TARGET) * G42 - Coordinated move to a mesh point (Requires MESH_BED_LEVELING, AUTO_BED_LEVELING_BLINEAR, or AUTO_BED_LEVELING_UBL) * G60 - Save current position. (Requires SAVED_POSITIONS) @@ -108,7 +109,7 @@ * The '#' is necessary when calling from within sd files, as it stops buffer prereading * M33 - Get the longname version of a path. (Requires LONG_FILENAME_HOST_SUPPORT) * M34 - Set SD Card sorting options. (Requires SDCARD_SORT_ALPHA) - * M42 - Change pin status via gcode: M42 P S. LED pin assumed if P is omitted. + * M42 - Change pin status via gcode: M42 P S. LED pin assumed if P is omitted. (Requires DIRECT_PIN_CONTROL) * M43 - Display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins * M48 - Measure Z Probe repeatability: M48 P X Y V E L S. (Requires Z_MIN_PROBE_REPEATABILITY_TEST) * M73 - Set the progress percentage. (Requires LCD_SET_PROGRESS_MANUALLY) @@ -154,7 +155,7 @@ * M141 - Set heated chamber target temp. S (Requires a chamber heater) * M145 - Set heatup values for materials on the LCD. H B F for S (0=PLA, 1=ABS) * M149 - Set temperature units. (Requires TEMPERATURE_UNITS_SUPPORT) - * M150 - Set Status LED Color as R U B P. Values 0-255. (Requires BLINKM, RGB_LED, RGBW_LED, NEOPIXEL_LED, PCA9533, or PCA9632). + * M150 - Set Status LED Color as R U B W P. Values 0-255. (Requires BLINKM, RGB_LED, RGBW_LED, NEOPIXEL_LED, PCA9533, or PCA9632). * M155 - Auto-report temperatures with interval of S. (Requires AUTO_REPORT_TEMPERATURES) * M163 - Set a single proportion for a mixing extruder. (Requires MIXING_EXTRUDER) * M164 - Commit the mix and save to a virtual tool (current, or as specified by 'S'). (Requires MIXING_EXTRUDER) @@ -182,7 +183,7 @@ * M220 - Set Feedrate Percentage: "M220 S" (i.e., "FR" on the LCD) * Use "M220 B" to back up the Feedrate Percentage and "M220 R" to restore it. (Requires PRUSA_MMU2) * M221 - Set Flow Percentage: "M221 S" - * M226 - Wait until a pin is in a given state: "M226 P S" + * M226 - Wait until a pin is in a given state: "M226 P S" (Requires DIRECT_PIN_CONTROL) * M240 - Trigger a camera to take a photograph. (Requires PHOTO_GCODE) * M250 - Set LCD contrast: "M250 C" (0-63). (Requires LCD support) * M260 - i2c Send Data (Requires EXPERIMENTAL_I2CBUS) @@ -217,12 +218,16 @@ * M422 - Set Z Stepper automatic alignment position using probe. X Y A (Requires Z_STEPPER_AUTO_ALIGN) * M425 - Enable/Disable and tune backlash correction. (Requires BACKLASH_COMPENSATION and BACKLASH_GCODE) * M428 - Set the home_offset based on the current_position. Nearest edge applies. (Disabled by NO_WORKSPACE_OFFSETS or DELTA) + * M430 - Read the system current, voltage, and power (Requires POWER_MONITOR_CURRENT, POWER_MONITOR_VOLTAGE, or POWER_MONITOR_FIXED_VOLTAGE) * M486 - Identify and cancel objects. (Requires CANCEL_OBJECTS) * M500 - Store parameters in EEPROM. (Requires EEPROM_SETTINGS) * M501 - Restore parameters from EEPROM. (Requires EEPROM_SETTINGS) * M502 - Revert to the default "factory settings". ** Does not write them to EEPROM! ** * M503 - Print the current settings (in memory): "M503 S". S0 specifies compact output. * M504 - Validate EEPROM contents. (Requires EEPROM_SETTINGS) + * M510 - Lock Printer + * M511 - Unlock Printer + * M512 - Set/Change/Remove Password * M524 - Abort the current SD print job started with M24. (Requires SDSUPPORT) * M540 - Enable/disable SD card abort on endstop hit: "M540 S". (Requires SD_ABORT_ON_ENDSTOP_HIT) * M569 - Enable stealthChop on an axis. (Requires at least one _DRIVER_TYPE to be TMC2130/2160/2208/2209/5130/5160) @@ -231,7 +236,7 @@ * M605 - Set Dual X-Carriage movement mode: "M605 S [X] [R]". (Requires DUAL_X_CARRIAGE) * M665 - Set delta configurations: "M665 H L R S B X Y Z (Requires DELTA) * M666 - Set/get offsets for delta (Requires DELTA) or dual endstops. (Requires [XYZ]_DUAL_ENDSTOPS) - * M672 - Set/Reset Duet Smart Effector's sensitivity. (Requires SMART_EFFECTOR and SMART_EFFECTOR_MOD_PIN) + * M672 - Set/Reset Duet Smart Effector's sensitivity. (Requires DUET_SMART_EFFECTOR and SMART_EFFECTOR_MOD_PIN) * M701 - Load filament (Requires FILAMENT_LOAD_UNLOAD_GCODES) * M702 - Unload filament (Requires FILAMENT_LOAD_UNLOAD_GCODES) * M810-M819 - Define/execute a G-code macro (Requires GCODE_MACROS) @@ -248,13 +253,14 @@ * M868 - Report or set position encoder module error correction threshold. * M869 - Report position encoder module error. * M871 - Print/reset/clear first layer temperature offset values. (Requires PROBE_TEMP_COMPENSATION) + * M192 - Wait for probe temp (Requires PROBE_TEMP_COMPENSATION) * M876 - Handle Prompt Response. (Requires HOST_PROMPT_SUPPORT and not EMERGENCY_PARSER) * M900 - Get or Set Linear Advance K-factor. (Requires LIN_ADVANCE) * M906 - Set or get motor current in milliamps using axis codes X, Y, Z, E. Report values if no axis codes given. (Requires at least one _DRIVER_TYPE defined as TMC2130/2160/5130/5160/2208/2209/2660 or L6470) * M907 - Set digital trimpot motor current using axis codes. (Requires a board with digital trimpots) - * M908 - Control digital trimpot directly. (Requires DAC_STEPPER_CURRENT or DIGIPOTSS_PIN) - * M909 - Print digipot/DAC current value. (Requires DAC_STEPPER_CURRENT) - * M910 - Commit digipot/DAC value to external EEPROM via I2C. (Requires DAC_STEPPER_CURRENT) + * M908 - Control digital trimpot directly. (Requires HAS_MOTOR_CURRENT_DAC or DIGIPOTSS_PIN) + * M909 - Print digipot/DAC current value. (Requires HAS_MOTOR_CURRENT_DAC) + * M910 - Commit digipot/DAC value to external EEPROM via I2C. (Requires HAS_MOTOR_CURRENT_DAC) * M911 - Report stepper driver overtemperature pre-warn condition. (Requires at least one _DRIVER_TYPE defined as TMC2130/2160/5130/5160/2208/2209/2660) * M912 - Clear stepper driver overtemperature pre-warn condition flag. (Requires at least one _DRIVER_TYPE defined as TMC2130/2160/5130/5160/2208/2209/2660) * M913 - Set HYBRID_THRESHOLD speed. (Requires HYBRID_THRESHOLD) @@ -274,20 +280,27 @@ * ************ Custom codes - This can change to suit future G-code regulations * G425 - Calibrate using a conductive object. (Requires CALIBRATION_GCODE) * M928 - Start SD logging: "M928 filename.gco". Stop with M29. (Requires SDSUPPORT) + * M993 - Backup SPI Flash to SD + * M994 - Load a Backup from SD to SPI Flash + * M995 - Touch screen calibration for TFT display * M997 - Perform in-application firmware update * M999 - Restart after being stopped by error + * D... - Custom Development G-code. Add hooks to 'gcode_D.cpp' for developers to test features. (Requires MARLIN_DEV_MODE) * * "T" Codes * * T0-T3 - Select an extruder (tool) by index: "T F" - * */ #include "../inc/MarlinConfig.h" #include "parser.h" #if ENABLED(I2C_POSITION_ENCODERS) - #include "../feature/I2CPositionEncoder.h" + #include "../feature/encoder_i2c.h" +#endif + +#if IS_SCARA || defined(G0_FEEDRATE) + #define HAS_FAST_MOVES 1 #endif enum AxisRelative : uint8_t { REL_X, REL_Y, REL_Z, REL_E, E_MODE_ABS, E_MODE_REL }; @@ -332,8 +345,14 @@ class GcodeSuite { static bool select_coordinate_system(const int8_t _new); #endif - static millis_t previous_move_ms; - FORCE_INLINE static void reset_stepper_timeout() { previous_move_ms = millis(); } + static millis_t previous_move_ms, max_inactive_time, stepper_inactive_time; + FORCE_INLINE static void reset_stepper_timeout(const millis_t ms=millis()) { previous_move_ms = ms; } + FORCE_INLINE static bool stepper_max_timed_out(const millis_t ms=millis()) { + return max_inactive_time && ELAPSED(ms, previous_move_ms + max_inactive_time); + } + FORCE_INLINE static bool stepper_inactive_timeout(const millis_t ms=millis()) { + return ELAPSED(ms, previous_move_ms + stepper_inactive_time); + } static int8_t get_target_extruder_from_command(); static int8_t get_target_e_stepper_from_command(); @@ -351,7 +370,7 @@ class GcodeSuite { process_subcommands_now_P(G28_STR); } - #if HAS_AUTO_REPORTING || ENABLED(HOST_KEEPALIVE_FEATURE) + #if EITHER(HAS_AUTO_REPORTING, HOST_KEEPALIVE_FEATURE) static bool autoreport_paused; static inline bool set_autoreport_paused(const bool p) { const bool was = autoreport_paused; @@ -390,30 +409,24 @@ class GcodeSuite { private: - static void G0_G1( - #if IS_SCARA || defined(G0_FEEDRATE) - const bool fast_move=false - #endif - ); + TERN_(MARLIN_DEV_MODE, static void D(const int16_t dcode)); - #if ENABLED(ARC_SUPPORT) - static void G2_G3(const bool clockwise); - #endif + static void G0_G1(TERN_(HAS_FAST_MOVES, const bool fast_move=false)); + + TERN_(ARC_SUPPORT, static void G2_G3(const bool clockwise)); static void G4(); - #if ENABLED(BEZIER_CURVE_SUPPORT) - static void G5(); - #endif + TERN_(BEZIER_CURVE_SUPPORT, static void G5()); + + TERN_(DIRECT_STEPPING, static void G6()); #if ENABLED(FWRETRACT) static void G10(); static void G11(); #endif - #if ENABLED(NOZZLE_CLEAN_FEATURE) - static void G12(); - #endif + TERN_(NOZZLE_CLEAN_FEATURE, static void G12()); #if ENABLED(CNC_WORKSPACE_PLANES) static void G17(); @@ -426,15 +439,11 @@ class GcodeSuite { static void G21(); #endif - #if ENABLED(G26_MESH_VALIDATION) - static void G26(); - #endif + TERN_(G26_MESH_VALIDATION, static void G26()); - #if ENABLED(NOZZLE_PARK_FEATURE) - static void G27(); - #endif + TERN_(NOZZLE_PARK_FEATURE, static void G27()); - static void G28(const bool always_home_all); + static void G28(); #if HAS_LEVELING #if ENABLED(G29_RETRY_AND_RECOVER) @@ -454,22 +463,19 @@ class GcodeSuite { #endif #endif - #if ENABLED(DELTA_AUTO_CALIBRATION) - static void G33(); - #endif + TERN_(DELTA_AUTO_CALIBRATION, static void G33()); - #if ENABLED(Z_STEPPER_AUTO_ALIGN) + #if EITHER(Z_STEPPER_AUTO_ALIGN, MECHANICAL_GANTRY_CALIBRATION) static void G34(); - static void M422(); #endif - #if ENABLED(G38_PROBE_TARGET) - static void G38(const int8_t subcode); - #endif + TERN_(Z_STEPPER_AUTO_ALIGN, static void M422()); - #if HAS_MESH - static void G42(); - #endif + TERN_(ASSISTED_TRAMMING, static void G35()); + + TERN_(G38_PROBE_TARGET, static void G38(const int8_t subcode)); + + TERN_(HAS_MESH, static void G42()); #if ENABLED(CNC_COORDINATE_SYSTEMS) static void G53(); @@ -481,28 +487,20 @@ class GcodeSuite { static void G59(); #endif - #if ENABLED(PROBE_TEMP_COMPENSATION) - static void G76(); - #endif + TERN_(PROBE_TEMP_COMPENSATION, static void G76()); #if SAVED_POSITIONS static void G60(); static void G61(); #endif - #if ENABLED(GCODE_MOTION_MODES) - static void G80(); - #endif + TERN_(GCODE_MOTION_MODES, static void G80()); static void G92(); - #if ENABLED(CALIBRATION_GCODE) - static void G425(); - #endif + TERN_(CALIBRATION_GCODE, static void G425()); - #if HAS_RESUME_CONTINUE - static void M0_M1(); - #endif + TERN_(HAS_RESUME_CONTINUE, static void M0_M1()); #if HAS_CUTTER static void M3_M4(const bool is_M4); @@ -510,22 +508,14 @@ class GcodeSuite { #endif #if ENABLED(COOLANT_CONTROL) - #if ENABLED(COOLANT_MIST) - static void M7(); - #endif - #if ENABLED(COOLANT_FLOOD) - static void M8(); - #endif + TERN_(COOLANT_MIST, static void M7()); + TERN_(COOLANT_FLOOD, static void M8()); static void M9(); #endif - #if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER) - static void M12(); - #endif + TERN_(EXTERNAL_CLOSED_LOOP_CONTROLLER, static void M12()); - #if ENABLED(EXPECTED_PRINTER_CHECK) - static void M16(); - #endif + TERN_(EXPECTED_PRINTER_CHECK, static void M16()); static void M17(); @@ -549,39 +539,26 @@ class GcodeSuite { #if ENABLED(SDSUPPORT) static void M32(); - #if ENABLED(LONG_FILENAME_HOST_SUPPORT) - static void M33(); - #endif + TERN_(LONG_FILENAME_HOST_SUPPORT, static void M33()); #if BOTH(SDCARD_SORT_ALPHA, SDSORT_GCODE) static void M34(); #endif #endif - static void M42(); + TERN_(DIRECT_PIN_CONTROL, static void M42()); + TERN_(PINS_DEBUGGING, static void M43()); - #if ENABLED(PINS_DEBUGGING) - static void M43(); - #endif + TERN_(Z_MIN_PROBE_REPEATABILITY_TEST, static void M48()); - #if ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST) - static void M48(); - #endif - - #if ENABLED(LCD_SET_PROGRESS_MANUALLY) - static void M73(); - #endif + TERN_(LCD_SET_PROGRESS_MANUALLY, static void M73()); static void M75(); static void M76(); static void M77(); - #if ENABLED(PRINTCOUNTER) - static void M78(); - #endif + TERN_(PRINTCOUNTER, static void M78()); - #if ENABLED(PSU_CONTROL) - static void M80(); - #endif + TERN_(PSU_CONTROL, static void M80()); static void M81(); static void M82(); @@ -589,9 +566,7 @@ class GcodeSuite { static void M85(); static void M92(); - #if ENABLED(M100_FREE_MEMORY_WATCHER) - static void M100(); - #endif + TERN_(M100_FREE_MEMORY_WATCHER, static void M100()); #if EXTRUDERS static void M104(); @@ -600,7 +575,7 @@ class GcodeSuite { static void M105(); - #if FAN_COUNT > 0 + #if HAS_FAN static void M106(); static void M107(); #endif @@ -609,17 +584,13 @@ class GcodeSuite { static void M108(); static void M112(); static void M410(); - #if ENABLED(HOST_PROMPT_SUPPORT) - static void M876(); - #endif + TERN_(HOST_PROMPT_SUPPORT, static void M876()); #endif static void M110(); static void M111(); - #if ENABLED(HOST_KEEPALIVE_FEATURE) - static void M113(); - #endif + TERN_(HOST_KEEPALIVE_FEATURE, static void M113()); static void M114(); static void M115(); @@ -629,9 +600,7 @@ class GcodeSuite { static void M120(); static void M121(); - #if ENABLED(PARK_HEAD_ON_PAUSE) - static void M125(); - #endif + TERN_(PARK_HEAD_ON_PAUSE, static void M125()); #if ENABLED(BARICUDA) #if HAS_HEATER_1 @@ -654,31 +623,23 @@ class GcodeSuite { static void M191(); #endif - #if HOTENDS && HAS_LCD_MENU + #if PREHEAT_COUNT static void M145(); #endif - #if ENABLED(TEMPERATURE_UNITS_SUPPORT) - static void M149(); - #endif + TERN_(TEMPERATURE_UNITS_SUPPORT, static void M149()); - #if HAS_COLOR_LEDS - static void M150(); - #endif + TERN_(HAS_COLOR_LEDS, static void M150()); - #if ENABLED(AUTO_REPORT_TEMPERATURES) && HAS_TEMP_SENSOR + #if BOTH(AUTO_REPORT_TEMPERATURES, HAS_TEMP_SENSOR) static void M155(); #endif #if ENABLED(MIXING_EXTRUDER) static void M163(); static void M164(); - #if ENABLED(DIRECT_MIXING_IN_G1) - static void M165(); - #endif - #if ENABLED(GRADIENT_MIX) - static void M166(); - #endif + TERN_(DIRECT_MIXING_IN_G1, static void M165()); + TERN_(GRADIENT_MIX, static void M166()); #endif static void M200(); @@ -692,27 +653,19 @@ class GcodeSuite { static void M204(); static void M205(); - #if HAS_M206_COMMAND - static void M206(); - #endif + TERN_(HAS_M206_COMMAND, static void M206()); #if ENABLED(FWRETRACT) static void M207(); static void M208(); - #if ENABLED(FWRETRACT_AUTORETRACT) - static void M209(); - #endif + TERN_(FWRETRACT_AUTORETRACT, static void M209()); #endif static void M211(); - #if EXTRUDERS > 1 - static void M217(); - #endif + TERN_(HAS_MULTI_EXTRUDER, static void M217()); - #if HAS_HOTEND_OFFSET - static void M218(); - #endif + TERN_(HAS_HOTEND_OFFSET, static void M218()); static void M220(); @@ -720,15 +673,11 @@ class GcodeSuite { static void M221(); #endif - static void M226(); + TERN_(DIRECT_PIN_CONTROL, static void M226()); - #if ENABLED(PHOTO_GCODE) - static void M240(); - #endif + TERN_(PHOTO_GCODE, static void M240()); - #if HAS_LCD_CONTRAST - static void M250(); - #endif + TERN_(HAS_LCD_CONTRAST, static void M250()); #if ENABLED(EXPERIMENTAL_I2CBUS) static void M260(); @@ -737,47 +686,31 @@ class GcodeSuite { #if HAS_SERVOS static void M280(); - #if ENABLED(EDITABLE_SERVO_ANGLES) - static void M281(); - #endif + TERN_(EDITABLE_SERVO_ANGLES, static void M281()); #endif - #if ENABLED(BABYSTEPPING) - static void M290(); - #endif + TERN_(BABYSTEPPING, static void M290()); - #if HAS_BUZZER - static void M300(); - #endif + TERN_(HAS_BUZZER, static void M300()); - #if ENABLED(PIDTEMP) - static void M301(); - #endif + TERN_(PIDTEMP, static void M301()); - #if ENABLED(PREVENT_COLD_EXTRUSION) - static void M302(); - #endif + TERN_(PREVENT_COLD_EXTRUSION, static void M302()); - #if HAS_PID_HEATING - static void M303(); - #endif + TERN_(HAS_PID_HEATING, static void M303()); - #if ENABLED(PIDTEMPBED) - static void M304(); - #endif + TERN_(PIDTEMPBED, static void M304()); - #if HAS_USER_THERMISTORS - static void M305(); - #endif + TERN_(HAS_USER_THERMISTORS, static void M305()); #if HAS_MICROSTEPS static void M350(); static void M351(); #endif - #if HAS_CASE_LIGHT - static void M355(); - #endif + TERN_(CASE_LIGHT_ENABLE, static void M355()); + + TERN_(REPETIER_GCODE_M360, static void M360()); #if ENABLED(MORGAN_SCARA) static bool M360(); @@ -799,9 +732,7 @@ class GcodeSuite { static void M402(); #endif - #if ENABLED(PRUSA_MMU2) - static void M403(); - #endif + TERN_(PRUSA_MMU2, static void M403()); #if ENABLED(FILAMENT_WIDTH_SENSOR) static void M404(); @@ -810,26 +741,20 @@ class GcodeSuite { static void M407(); #endif - #if HAS_FILAMENT_SENSOR - static void M412(); - #endif + TERN_(HAS_FILAMENT_SENSOR, static void M412()); #if HAS_LEVELING static void M420(); static void M421(); #endif - #if ENABLED(BACKLASH_GCODE) - static void M425(); - #endif + TERN_(BACKLASH_GCODE, static void M425()); - #if HAS_M206_COMMAND - static void M428(); - #endif + TERN_(HAS_M206_COMMAND, static void M428()); - #if ENABLED(CANCEL_OBJECTS) - static void M486(); - #endif + TERN_(HAS_POWER_MONITOR, static void M430()); + + TERN_(CANCEL_OBJECTS, static void M486()); static void M500(); static void M501(); @@ -837,40 +762,38 @@ class GcodeSuite { #if DISABLED(DISABLE_M503) static void M503(); #endif - #if ENABLED(EEPROM_SETTINGS) - static void M504(); - #endif + TERN_(EEPROM_SETTINGS, static void M504()); - #if ENABLED(SDSUPPORT) - static void M524(); + #if ENABLED(PASSWORD_FEATURE) + static void M510(); + #if ENABLED(PASSWORD_UNLOCK_GCODE) + static void M511(); + #endif + #if ENABLED(PASSWORD_CHANGE_GCODE) + static void M512(); + #endif #endif - #if ENABLED(SD_ABORT_ON_ENDSTOP_HIT) - static void M540(); - #endif + TERN_(SDSUPPORT, static void M524()); - #if ENABLED(BAUD_RATE_GCODE) - static void M575(); - #endif + TERN_(SD_ABORT_ON_ENDSTOP_HIT, static void M540()); + + TERN_(BAUD_RATE_GCODE, static void M575()); #if ENABLED(ADVANCED_PAUSE_FEATURE) static void M600(); static void M603(); #endif - #if HAS_DUPLICATION_MODE - static void M605(); - #endif + TERN_(HAS_DUPLICATION_MODE, static void M605()); - #if IS_KINEMATIC - static void M665(); - #endif + TERN_(IS_KINEMATIC, static void M665()); #if ENABLED(DELTA) || HAS_EXTRA_ENDSTOPS static void M666(); #endif - #if ENABLED(SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD) + #if ENABLED(DUET_SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD) static void M672(); #endif @@ -879,17 +802,11 @@ class GcodeSuite { static void M702(); #endif - #if ENABLED(GCODE_MACROS) - static void M810_819(); - #endif + TERN_(GCODE_MACROS, static void M810_819()); - #if HAS_BED_PROBE - static void M851(); - #endif + TERN_(HAS_BED_PROBE, static void M851()); - #if ENABLED(SKEW_CORRECTION_GCODE) - static void M852(); - #endif + TERN_(SKEW_CORRECTION_GCODE, static void M852()); #if ENABLED(I2C_POSITION_ENCODERS) FORCE_INLINE static void M860() { I2CPEM.M860(); } @@ -905,29 +822,22 @@ class GcodeSuite { #endif #if ENABLED(PROBE_TEMP_COMPENSATION) + static void M192(); static void M871(); #endif - #if ENABLED(LIN_ADVANCE) - static void M900(); - #endif + TERN_(LIN_ADVANCE, static void M900()); - #if HAS_TRINAMIC + #if HAS_TRINAMIC_CONFIG static void M122(); static void M906(); - #if HAS_STEALTHCHOP - static void M569(); - #endif + TERN_(HAS_STEALTHCHOP, static void M569()); #if ENABLED(MONITOR_DRIVER_STATUS) static void M911(); static void M912(); #endif - #if ENABLED(HYBRID_THRESHOLD) - static void M913(); - #endif - #if USE_SENSORLESS - static void M914(); - #endif + TERN_(HYBRID_THRESHOLD, static void M913()); + TERN_(USE_SENSORLESS, static void M914()); #endif #if HAS_L64XX @@ -938,29 +848,30 @@ class GcodeSuite { static void M918(); #endif - #if HAS_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM || EITHER(DIGIPOT_I2C, DAC_STEPPER_CURRENT) + #if ANY(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_PWM, HAS_MOTOR_CURRENT_I2C, HAS_MOTOR_CURRENT_DAC) static void M907(); - #if HAS_DIGIPOTSS || ENABLED(DAC_STEPPER_CURRENT) + #if EITHER(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_DAC) static void M908(); - #if ENABLED(DAC_STEPPER_CURRENT) + #if ENABLED(HAS_MOTOR_CURRENT_DAC) static void M909(); static void M910(); #endif #endif #endif - #if ENABLED(SDSUPPORT) - static void M928(); - #endif + TERN_(SDSUPPORT, static void M928()); - #if ENABLED(MAGNETIC_PARKING_EXTRUDER) - static void M951(); - #endif + TERN_(MAGNETIC_PARKING_EXTRUDER, static void M951()); - #if ENABLED(PLATFORM_M997_SUPPORT) - static void M997(); + TERN_(TOUCH_SCREEN_CALIBRATION, static void M995()); + + #if BOTH(HAS_SPI_FLASH, SDSUPPORT) + static void M993(); + static void M994(); #endif + TERN_(PLATFORM_M997_SUPPORT, static void M997()); + static void M999(); #if ENABLED(POWER_LOSS_RECOVERY) @@ -968,11 +879,13 @@ class GcodeSuite { static void M1000(); #endif - #if ENABLED(MAX7219_GCODE) - static void M7219(); - #endif + TERN_(SDSUPPORT, static void M1001()); + + TERN_(MAX7219_GCODE, static void M7219()); + + TERN_(CONTROLLER_FAN_EDITABLE, static void M710()); - static void T(const uint8_t tool_index); + static void T(const int8_t tool_index); }; diff --git a/Marlin/src/gcode/gcode_d.cpp b/Marlin/src/gcode/gcode_d.cpp new file mode 100644 index 000000000000..1f38a85b9135 --- /dev/null +++ b/Marlin/src/gcode/gcode_d.cpp @@ -0,0 +1,191 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../inc/MarlinConfigPre.h" + +#if ENABLED(MARLIN_DEV_MODE) + + #include "gcode.h" + #include "../module/settings.h" + #include "../module/temperature.h" + #include "../libs/hex_print.h" + #include "../HAL/shared/eeprom_if.h" + #include "../HAL/shared/Delay.h" + + /** + * Dn: G-code for development and testing + * + * See https://reprap.org/wiki/G-code#D:_Debug_codes + * + * Put whatever else you need here to test ongoing development. + */ + void GcodeSuite::D(const int16_t dcode) { + switch (dcode) { + + case -1: + for (;;); // forever + + case 0: + HAL_reboot(); + break; + + case 1: { + // Zero or pattern-fill the EEPROM data + #if ENABLED(EEPROM_SETTINGS) + persistentStore.access_start(); + size_t total = persistentStore.capacity(); + int pos = 0; + const uint8_t value = 0x0; + while(total--) { + persistentStore.write_data(pos, &value, 1); + } + persistentStore.access_finish(); + #else + settings.reset(); + settings.save(); + #endif + HAL_reboot(); + } break; + + case 2: { // D2 Read / Write SRAM + #define SRAM_SIZE 8192 + uint8_t *pointer = parser.hex_adr_val('A'); + uint16_t len = parser.ushortval('C', 1); + uintptr_t addr = (uintptr_t)pointer; + NOMORE(addr, (size_t)(SRAM_SIZE - 1)); + NOMORE(len, SRAM_SIZE - addr); + if (parser.seenval('X')) { + // Write the hex bytes after the X + uint16_t val = parser.hex_val('X'); + while (len--) { + *pointer = val; + pointer++; + } + } + else { + while (len--) print_hex_byte(*(pointer++)); + SERIAL_EOL(); + } + } break; + + #if ENABLED(EEPROM_SETTINGS) + case 3: { // D3 Read / Write EEPROM + uint8_t *pointer = parser.hex_adr_val('A'); + uint16_t len = parser.ushortval('C', 1); + uintptr_t addr = (uintptr_t)pointer; + #ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE size_t(E2END + 1) + #endif + NOMORE(addr, (size_t)(MARLIN_EEPROM_SIZE - 1)); + NOMORE(len, MARLIN_EEPROM_SIZE - addr); + if (parser.seenval('X')) { + uint16_t val = parser.hex_val('X'); + #if ENABLED(EEPROM_SETTINGS) + persistentStore.access_start(); + while(len--) { + int pos = 0; + persistentStore.write_data(pos, (uint8_t *)&val, sizeof(val)); + } + SERIAL_EOL(); + persistentStore.access_finish(); + #else + SERIAL_ECHOLN("NO EEPROM"); + #endif + } + else { + while (len--) { + // Read bytes from EEPROM + #if ENABLED(EEPROM_SETTINGS) + persistentStore.access_start(); + uint8_t val; + while(len--) { + int pos = 0; + if (!persistentStore.read_data(pos, (uint8_t *)&val, sizeof(val))) { + print_hex_byte(val); + } + } + SERIAL_EOL(); + persistentStore.access_finish(); + #else + SERIAL_ECHOLN("NO EEPROM"); + #endif + } + SERIAL_EOL(); + } + } break; + #endif + + case 4: { // D4 Read / Write PIN + // const uint8_t pin = parser.byteval('P'); + // const bool is_out = parser.boolval('F'), + // val = parser.byteval('V', LOW); + if (parser.seenval('X')) { + // TODO: Write the hex bytes after the X + //while (len--) { + //} + } + else { + // while (len--) { + // TODO: Read bytes from EEPROM + // print_hex_byte(eeprom_read_byte(*(adr++)); + // } + SERIAL_EOL(); + } + } break; + + case 5: { // D4 Read / Write onboard Flash + #define FLASH_SIZE 1024 + uint8_t *pointer = parser.hex_adr_val('A'); + uint16_t len = parser.ushortval('C', 1); + uintptr_t addr = (uintptr_t)pointer; + NOMORE(addr, (size_t)(FLASH_SIZE - 1)); + NOMORE(len, FLASH_SIZE - addr); + if (parser.seenval('X')) { + // TODO: Write the hex bytes after the X + //while (len--) { + //} + } + else { + // while (len--) { + // TODO: Read bytes from EEPROM + // print_hex_byte(eeprom_read_byte(adr++)); + // } + SERIAL_EOL(); + } + } break; + + case 100: { // D100 Disable heaters and attempt a hard hang (Watchdog Test) + SERIAL_ECHOLN("Disabling heaters and attempting to trigger Watchdog"); + SERIAL_ECHOLN("(USE_WATCHDOG " TERN(USE_WATCHDOG, "ENABLED", "DISABLED") ")"); + thermalManager.disable_all_heaters(); + delay(1000); // Allow time to print + DISABLE_ISRS(); + // Use a low-level delay that does not rely on interrupts to function + // Do not spin forever, to avoid thermal risks if heaters are enabled and + // watchdog does not work. + DELAY_US(10000000); + ENABLE_ISRS(); + SERIAL_ECHOLN("FAILURE: Watchdog did not trigger board reset."); + } + } + } + +#endif diff --git a/Marlin/src/gcode/geometry/G17-G19.cpp b/Marlin/src/gcode/geometry/G17-G19.cpp index 14f3e80bbc79..7510eaba8c3d 100644 --- a/Marlin/src/gcode/geometry/G17-G19.cpp +++ b/Marlin/src/gcode/geometry/G17-G19.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/geometry/G53-G59.cpp b/Marlin/src/gcode/geometry/G53-G59.cpp index e24247b2c5c3..05bc522768a2 100644 --- a/Marlin/src/gcode/geometry/G53-G59.cpp +++ b/Marlin/src/gcode/geometry/G53-G59.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/geometry/G92.cpp b/Marlin/src/gcode/geometry/G92.cpp index 0ed10beb54c2..1a0382ed7c2b 100644 --- a/Marlin/src/gcode/geometry/G92.cpp +++ b/Marlin/src/gcode/geometry/G92.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -25,7 +25,7 @@ #include "../../module/stepper.h" #if ENABLED(I2C_POSITION_ENCODERS) - #include "../../feature/I2CPositionEncoder.h" + #include "../../feature/encoder_i2c.h" #endif /** @@ -99,5 +99,7 @@ void GcodeSuite::G92() { if (sync_XYZ) sync_plan_position(); else if (sync_E) sync_plan_position_e(); - report_current_position(); + #if DISABLED(DIRECT_STEPPING) + report_current_position(); + #endif } diff --git a/Marlin/src/gcode/geometry/M206_M428.cpp b/Marlin/src/gcode/geometry/M206_M428.cpp index e4cac5174bf7..a477a1a526ef 100644 --- a/Marlin/src/gcode/geometry/M206_M428.cpp +++ b/Marlin/src/gcode/geometry/M206_M428.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -38,7 +38,7 @@ */ void GcodeSuite::M206() { LOOP_XYZ(i) - if (parser.seen(axis_codes[i])) + if (parser.seen(XYZ_CHAR(i))) set_home_offset((AxisEnum)i, parser.value_linear_units()); #if ENABLED(MORGAN_SCARA) @@ -61,7 +61,7 @@ void GcodeSuite::M206() { * Use M206 to set these values directly. */ void GcodeSuite::M428() { - if (axis_unhomed_error()) return; + if (homing_needed_error()) return; xyz_float_t diff; LOOP_XYZ(i) { diff --git a/Marlin/src/gcode/host/M110.cpp b/Marlin/src/gcode/host/M110.cpp index f7b6dfd4f44b..b12b38ea0f12 100644 --- a/Marlin/src/gcode/host/M110.cpp +++ b/Marlin/src/gcode/host/M110.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -27,5 +27,8 @@ * M110: Set Current Line Number */ void GcodeSuite::M110() { - if (parser.seenval('N')) queue.last_N = parser.value_long(); + + if (parser.seenval('N')) + queue.last_N[queue.command_port()] = parser.value_long(); + } diff --git a/Marlin/src/gcode/host/M113.cpp b/Marlin/src/gcode/host/M113.cpp index 872986561d79..ce826d6acde6 100644 --- a/Marlin/src/gcode/host/M113.cpp +++ b/Marlin/src/gcode/host/M113.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/host/M114.cpp b/Marlin/src/gcode/host/M114.cpp index acdd925301a7..85a38f6462a8 100644 --- a/Marlin/src/gcode/host/M114.cpp +++ b/Marlin/src/gcode/host/M114.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -34,40 +34,45 @@ #include "../../core/debug_out.h" #endif - void report_xyze(const xyze_pos_t &pos, const uint8_t n=4, const uint8_t precision=3) { + void report_xyze(const xyze_pos_t &pos, const uint8_t n=XYZE, const uint8_t precision=3) { char str[12]; - for (uint8_t a = 0; a < n; a++) { + LOOP_L_N(a, n) { SERIAL_CHAR(' ', axis_codes[a], ':'); + if (pos[a] >= 0) SERIAL_CHAR(' '); SERIAL_ECHO(dtostrf(pos[a], 1, precision, str)); } SERIAL_EOL(); } + inline void report_xyz(const xyze_pos_t &pos) { report_xyze(pos, XYZ); } void report_xyz(const xyz_pos_t &pos, const uint8_t precision=3) { char str[12]; - for (uint8_t a = X_AXIS; a <= Z_AXIS; a++) { - SERIAL_CHAR(' ', axis_codes[a], ':'); + LOOP_XYZ(a) { + SERIAL_CHAR(' ', XYZ_CHAR(a), ':'); SERIAL_ECHO(dtostrf(pos[a], 1, precision, str)); } SERIAL_EOL(); } - inline void report_xyz(const xyze_pos_t &pos) { report_xyze(pos, 3); } void report_current_position_detail() { + // Position as sent by G-code SERIAL_ECHOPGM("\nLogical:"); report_xyz(current_position.asLogical()); + // Cartesian position in native machine space SERIAL_ECHOPGM("Raw: "); report_xyz(current_position); xyze_pos_t leveled = current_position; #if HAS_LEVELING + // Current position with leveling applied SERIAL_ECHOPGM("Leveled:"); planner.apply_leveling(leveled); report_xyz(leveled); + // Test planner un-leveling. This should match the Raw result. SERIAL_ECHOPGM("UnLevel:"); xyze_pos_t unleveled = leveled; planner.unapply_leveling(unleveled); @@ -75,6 +80,7 @@ #endif #if IS_KINEMATIC + // Kinematics applied to the leveled position #if IS_SCARA SERIAL_ECHOPGM("ScaraK: "); #else @@ -173,19 +179,28 @@ report_xyze(from_steppers); const xyze_float_t diff = from_steppers - leveled; - SERIAL_ECHOPGM("Diff: "); + SERIAL_ECHOPGM("Diff: "); report_xyze(diff); } #endif // M114_DETAIL /** - * M114: Report current position to host + * M114: Report the current position to host. + * Since steppers are moving, the count positions are + * projected by using planner calculations. + * D - Report more detail. This syncs the planner. (Requires M114_DETAIL) + * E - Report E stepper position (Requires M114_DETAIL) + * R - Report the realtime position instead of projected. */ void GcodeSuite::M114() { #if ENABLED(M114_DETAIL) if (parser.seen('D')) { + #if DISABLED(M114_LEGACY) + planner.synchronize(); + #endif + report_current_position(); report_current_position_detail(); return; } @@ -195,6 +210,10 @@ void GcodeSuite::M114() { } #endif - planner.synchronize(); - report_current_position(); + #if ENABLED(M114_REALTIME) + if (parser.seen('R')) { report_real_position(); return; } + #endif + + TERN_(M114_LEGACY, planner.synchronize()); + report_current_position_projected(); } diff --git a/Marlin/src/gcode/host/M115.cpp b/Marlin/src/gcode/host/M115.cpp index 4d2c5d5d6996..53c5163bbaf6 100644 --- a/Marlin/src/gcode/host/M115.cpp +++ b/Marlin/src/gcode/host/M115.cpp @@ -16,13 +16,17 @@ * 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 . + * along with this program. If not, see . * */ #include "../gcode.h" #include "../../inc/MarlinConfig.h" +#if ENABLED(M115_GEOMETRY_REPORT) + #include "../../module/motion.h" +#endif + #if ENABLED(EXTENDED_CAPABILITIES_REPORT) static void cap_line(PGM_P const name, bool ena=false) { SERIAL_ECHOPGM("Cap:"); @@ -38,55 +42,39 @@ * the capability is not present. */ void GcodeSuite::M115() { - - SERIAL_ECHOLNPGM(STR_M115_REPORT); + SERIAL_ECHOLNPGM( + "FIRMWARE_NAME:Marlin " DETAILED_BUILD_VERSION " (" __DATE__ " " __TIME__ ") " + "SOURCE_CODE_URL:" SOURCE_CODE_URL " " + "PROTOCOL_VERSION:" PROTOCOL_VERSION " " + "MACHINE_TYPE:" MACHINE_NAME " " + "EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " " + #ifdef MACHINE_UUID + "UUID:" MACHINE_UUID + #endif + ); #if ENABLED(EXTENDED_CAPABILITIES_REPORT) // PAREN_COMMENTS - #if ENABLED(PAREN_COMMENTS) - cap_line(PSTR("PAREN_COMMENTS"), true); - #endif + TERN_(PAREN_COMMENTS, cap_line(PSTR("PAREN_COMMENTS"), true)); // QUOTED_STRINGS - #if ENABLED(GCODE_QUOTED_STRINGS) - cap_line(PSTR("QUOTED_STRINGS"), true); - #endif + TERN_(GCODE_QUOTED_STRINGS, cap_line(PSTR("QUOTED_STRINGS"), true)); // SERIAL_XON_XOFF - cap_line(PSTR("SERIAL_XON_XOFF") - #if ENABLED(SERIAL_XON_XOFF) - , true - #endif - ); + cap_line(PSTR("SERIAL_XON_XOFF"), ENABLED(SERIAL_XON_XOFF)); // BINARY_FILE_TRANSFER (M28 B1) - cap_line(PSTR("BINARY_FILE_TRANSFER") - #if ENABLED(BINARY_FILE_TRANSFER) - , true - #endif - ); + cap_line(PSTR("BINARY_FILE_TRANSFER"), ENABLED(BINARY_FILE_TRANSFER)); // EEPROM (M500, M501) - cap_line(PSTR("EEPROM") - #if ENABLED(EEPROM_SETTINGS) - , true - #endif - ); + cap_line(PSTR("EEPROM"), ENABLED(EEPROM_SETTINGS)); // Volumetric Extrusion (M200) - cap_line(PSTR("VOLUMETRIC") - #if DISABLED(NO_VOLUMETRICS) - , true - #endif - ); + cap_line(PSTR("VOLUMETRIC"), DISABLED(NO_VOLUMETRICS)); // AUTOREPORT_TEMP (M155) - cap_line(PSTR("AUTOREPORT_TEMP") - #if ENABLED(AUTO_REPORT_TEMPERATURES) - , true - #endif - ); + cap_line(PSTR("AUTOREPORT_TEMP"), ENABLED(AUTO_REPORT_TEMPERATURES)); // PROGRESS (M530 S L, M531 , M532 X L) cap_line(PSTR("PROGRESS")); @@ -95,93 +83,79 @@ void GcodeSuite::M115() { cap_line(PSTR("PRINT_JOB"), true); // AUTOLEVEL (G29) - cap_line(PSTR("AUTOLEVEL") - #if HAS_AUTOLEVEL - , true - #endif - ); + cap_line(PSTR("AUTOLEVEL"), ENABLED(HAS_AUTOLEVEL)); + + // RUNOUT (M412, M600) + cap_line(PSTR("RUNOUT"), ENABLED(FILAMENT_RUNOUT_SENSOR)); // Z_PROBE (G30) - cap_line(PSTR("Z_PROBE") - #if HAS_BED_PROBE - , true - #endif - ); + cap_line(PSTR("Z_PROBE"), ENABLED(HAS_BED_PROBE)); // MESH_REPORT (M420 V) - cap_line(PSTR("LEVELING_DATA") - #if HAS_LEVELING - , true - #endif - ); + cap_line(PSTR("LEVELING_DATA"), ENABLED(HAS_LEVELING)); // BUILD_PERCENT (M73) - cap_line(PSTR("BUILD_PERCENT") - #if ENABLED(LCD_SET_PROGRESS_MANUALLY) - , true - #endif - ); + cap_line(PSTR("BUILD_PERCENT"), ENABLED(LCD_SET_PROGRESS_MANUALLY)); // SOFTWARE_POWER (M80, M81) - cap_line(PSTR("SOFTWARE_POWER") - #if ENABLED(PSU_CONTROL) - , true - #endif - ); - - // CASE LIGHTS (M355) - cap_line(PSTR("TOGGLE_LIGHTS") - #if HAS_CASE_LIGHT - , true - #endif - ); - cap_line(PSTR("CASE_LIGHT_BRIGHTNESS") - #if HAS_CASE_LIGHT - , PWM_PIN(CASE_LIGHT_PIN) - #endif - ); + cap_line(PSTR("SOFTWARE_POWER"), ENABLED(PSU_CONTROL)); + + // TOGGLE_LIGHTS (M355) + cap_line(PSTR("TOGGLE_LIGHTS"), ENABLED(CASE_LIGHT_ENABLE)); + cap_line(PSTR("CASE_LIGHT_BRIGHTNESS"), TERN0(CASE_LIGHT_ENABLE, PWM_PIN(CASE_LIGHT_PIN))); // EMERGENCY_PARSER (M108, M112, M410, M876) - cap_line(PSTR("EMERGENCY_PARSER") - #if ENABLED(EMERGENCY_PARSER) - , true - #endif - ); + cap_line(PSTR("EMERGENCY_PARSER"), ENABLED(EMERGENCY_PARSER)); // PROMPT SUPPORT (M876) - cap_line(PSTR("PROMPT_SUPPORT") - #if ENABLED(HOST_PROMPT_SUPPORT) - , true - #endif - ); + cap_line(PSTR("PROMPT_SUPPORT"), ENABLED(HOST_PROMPT_SUPPORT)); + + // SDCARD (M20, M23, M24, etc.) + cap_line(PSTR("SDCARD"), ENABLED(SDSUPPORT)); // AUTOREPORT_SD_STATUS (M27 extension) - cap_line(PSTR("AUTOREPORT_SD_STATUS") - #if ENABLED(AUTO_REPORT_SD_STATUS) - , true - #endif - ); + cap_line(PSTR("AUTOREPORT_SD_STATUS"), ENABLED(AUTO_REPORT_SD_STATUS)); + + // LONG_FILENAME_HOST_SUPPORT (M33) + cap_line(PSTR("LONG_FILENAME"), ENABLED(LONG_FILENAME_HOST_SUPPORT)); // THERMAL_PROTECTION - cap_line(PSTR("THERMAL_PROTECTION") - #if (ENABLED(THERMAL_PROTECTION_HOTENDS) || !EXTRUDERS) && (ENABLED(THERMAL_PROTECTION_BED) || !HAS_HEATED_BED) && (ENABLED(THERMAL_PROTECTION_CHAMBER) || !HAS_HEATED_CHAMBER) - , true - #endif - ); + cap_line(PSTR("THERMAL_PROTECTION"), ENABLED(THERMALLY_SAFE)); // MOTION_MODES (M80-M89) - cap_line(PSTR("MOTION_MODES") - #if ENABLED(GCODE_MOTION_MODES) - , true - #endif - ); + cap_line(PSTR("MOTION_MODES"), ENABLED(GCODE_MOTION_MODES)); + + // ARC_SUPPORT (G2-G3) + cap_line(PSTR("ARCS"), ENABLED(ARC_SUPPORT)); + + // BABYSTEPPING (M290) + cap_line(PSTR("BABYSTEPPING"), ENABLED(BABYSTEPPING)); // CHAMBER_TEMPERATURE (M141, M191) - cap_line(PSTR("CHAMBER_TEMPERATURE") - #if HAS_HEATED_CHAMBER - , true - #endif - ); + cap_line(PSTR("CHAMBER_TEMPERATURE"), ENABLED(HAS_HEATED_CHAMBER)); + + // Machine Geometry + #if ENABLED(M115_GEOMETRY_REPORT) + const xyz_pos_t dmin = { X_MIN_POS, Y_MIN_POS, Z_MIN_POS }, + dmax = { X_MAX_POS, Y_MAX_POS, Z_MAX_POS }; + xyz_pos_t cmin = dmin, cmax = dmax; + apply_motion_limits(cmin); + apply_motion_limits(cmax); + const xyz_pos_t lmin = dmin.asLogical(), lmax = dmax.asLogical(), + wmin = cmin.asLogical(), wmax = cmax.asLogical(); + SERIAL_ECHOLNPAIR( + "area:{" + "full:{" + "min:{x:", lmin.x, ",y:", lmin.y, ",z:", lmin.z, "}," + "max:{x:", lmax.x, ",y:", lmax.y, ",z:", lmax.z, "}" + "}," + "work:{" + "min:{x:", wmin.x, ",y:", wmin.y, ",z:", wmin.z, "}," + "max:{x:", wmax.x, ",y:", wmax.y, ",z:", wmax.z, "}", + "}" + "}" + ); + #endif #endif // EXTENDED_CAPABILITIES_REPORT } diff --git a/Marlin/src/gcode/host/M118.cpp b/Marlin/src/gcode/host/M118.cpp index ba52a4f81601..3be290254125 100644 --- a/Marlin/src/gcode/host/M118.cpp +++ b/Marlin/src/gcode/host/M118.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -34,7 +34,7 @@ */ void GcodeSuite::M118() { bool hasE = false, hasA = false; - #if NUM_SERIAL > 1 + #if HAS_MULTI_SERIAL int8_t port = -1; // Assume no redirect #endif char *p = parser.string_arg; @@ -44,7 +44,7 @@ void GcodeSuite::M118() { switch (p[0]) { case 'A': hasA = true; break; case 'E': hasE = true; break; - #if NUM_SERIAL > 1 + #if HAS_MULTI_SERIAL case 'P': port = p[1] - '0'; break; #endif } @@ -52,7 +52,7 @@ void GcodeSuite::M118() { while (*p == ' ') ++p; } - #if NUM_SERIAL > 1 + #if HAS_MULTI_SERIAL const int8_t old_serial = serial_port_index; if (WITHIN(port, 0, NUM_SERIAL)) serial_port_index = ( @@ -69,7 +69,5 @@ void GcodeSuite::M118() { if (hasA) SERIAL_ECHOPGM("// "); SERIAL_ECHOLN(p); - #if NUM_SERIAL > 1 - serial_port_index = old_serial; - #endif + TERN_(HAS_MULTI_SERIAL, serial_port_index = old_serial); } diff --git a/Marlin/src/gcode/host/M119.cpp b/Marlin/src/gcode/host/M119.cpp index b3cb7290b33f..f0066bddffee 100644 --- a/Marlin/src/gcode/host/M119.cpp +++ b/Marlin/src/gcode/host/M119.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/host/M16.cpp b/Marlin/src/gcode/host/M16.cpp index fd3320db934b..1ac85803961d 100644 --- a/Marlin/src/gcode/host/M16.cpp +++ b/Marlin/src/gcode/host/M16.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -33,7 +33,7 @@ void GcodeSuite::M16() { if (strcmp_P(parser.string_arg, PSTR(MACHINE_NAME))) - kill(GET_TEXT(MSG_EXPECTED_PRINTER)); + kill(GET_TEXT(MSG_KILL_EXPECTED_PRINTER)); } diff --git a/Marlin/src/gcode/host/M360.cpp b/Marlin/src/gcode/host/M360.cpp new file mode 100644 index 000000000000..9970dc4df95c --- /dev/null +++ b/Marlin/src/gcode/host/M360.cpp @@ -0,0 +1,189 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../inc/MarlinConfig.h" + +#if ENABLED(REPETIER_GCODE_M360) + +#include "../gcode.h" + +#include "../../module/motion.h" +#include "../../module/planner.h" + +static void config_prefix(PGM_P const name, PGM_P const pref=nullptr) { + SERIAL_ECHOPGM("Config:"); + if (pref) serialprintPGM(pref); + serialprintPGM(name); + SERIAL_CHAR(':'); +} +static void config_line(PGM_P const name, const float val, PGM_P const pref=nullptr) { + config_prefix(name, pref); + SERIAL_ECHOLN(val); +} + +/** + * M360: Report Firmware configuration + * in RepRapFirmware-compatible format + */ +void GcodeSuite::M360() { + PGMSTR(X_STR, "X"); + PGMSTR(Y_STR, "Y"); + PGMSTR(Z_STR, "Z"); + PGMSTR(JERK_STR, "Jerk"); + + // + // Basics and Enabled items + // + config_line(PSTR("Baudrate"), BAUDRATE); + config_line(PSTR("InputBuffer"), MAX_CMD_SIZE); + config_line(PSTR("PrintlineCache"), BUFSIZE); + config_line(PSTR("MixingExtruder"), ENABLED(MIXING_EXTRUDER)); + config_line(PSTR("SDCard"), ENABLED(SDSUPPORT)); + config_line(PSTR("Fan"), ENABLED(HAS_FAN)); + config_line(PSTR("LCD"), ENABLED(HAS_DISPLAY)); + config_line(PSTR("SoftwarePowerSwitch"), 1); + config_line(PSTR("SupportLocalFilamentchange"), ENABLED(ADVANCED_PAUSE_FEATURE)); + config_line(PSTR("CaseLights"), ENABLED(CASE_LIGHT_ENABLE)); + config_line(PSTR("ZProbe"), ENABLED(HAS_BED_PROBE)); + config_line(PSTR("Autolevel"), ENABLED(HAS_LEVELING)); + config_line(PSTR("EEPROM"), ENABLED(EEPROM_SETTINGS)); + + // + // Homing Directions + // + PGMSTR(H_DIR_STR, "HomeDir"); + config_line(H_DIR_STR, X_HOME_DIR, X_STR); + config_line(H_DIR_STR, Y_HOME_DIR, Y_STR); + config_line(H_DIR_STR, Z_HOME_DIR, Z_STR); + + // + // XYZ Axis Jerk + // + #if HAS_CLASSIC_JERK + if (planner.max_jerk.x == planner.max_jerk.y) + config_line(PSTR("XY"), planner.max_jerk.x, JERK_STR); + else { + config_line(X_STR, planner.max_jerk.x, JERK_STR); + config_line(Y_STR, planner.max_jerk.y, JERK_STR); + } + config_line(Z_STR, planner.max_jerk.z, JERK_STR); + #endif + + // + // Firmware Retraction + // + config_line(PSTR("SupportG10G11"), ENABLED(FWRETRACT)); + #if ENABLED(FWRETRACT) + PGMSTR(RET_STR, "Retraction"); + PGMSTR(UNRET_STR, "RetractionUndo"); + PGMSTR(SPEED_STR, "Speed"); + // M10 Retract with swap (long) moves + config_line(PSTR("Length"), fwretract.settings.retract_length, RET_STR); + config_line(SPEED_STR, fwretract.settings.retract_feedrate_mm_s, RET_STR); + config_line(PSTR("ZLift"), fwretract.settings.retract_zraise, RET_STR); + config_line(PSTR("LongLength"), fwretract.settings.swap_retract_length, RET_STR); + // M11 Recover (undo) with swap (long) moves + config_line(SPEED_STR, fwretract.settings.retract_recover_feedrate_mm_s, UNRET_STR); + config_line(PSTR("ExtraLength"), fwretract.settings.retract_recover_extra, UNRET_STR); + config_line(PSTR("ExtraLongLength"), fwretract.settings.swap_retract_recover_extra, UNRET_STR); + config_line(PSTR("LongSpeed"), fwretract.settings.swap_retract_recover_feedrate_mm_s, UNRET_STR); + #endif + + // + // Workspace boundaries + // + const xyz_pos_t dmin = { X_MIN_POS, Y_MIN_POS, Z_MIN_POS }, + dmax = { X_MAX_POS, Y_MAX_POS, Z_MAX_POS }; + xyz_pos_t cmin = dmin, cmax = dmax; + apply_motion_limits(cmin); + apply_motion_limits(cmax); + const xyz_pos_t wmin = cmin.asLogical(), wmax = cmax.asLogical(); + + PGMSTR(MIN_STR, "Min"); + PGMSTR(MAX_STR, "Max"); + PGMSTR(SIZE_STR, "Size"); + config_line(MIN_STR, wmin.x, X_STR); + config_line(MIN_STR, wmin.y, Y_STR); + config_line(MIN_STR, wmin.z, Z_STR); + config_line(MAX_STR, wmax.x, X_STR); + config_line(MAX_STR, wmax.y, Y_STR); + config_line(MAX_STR, wmax.z, Z_STR); + config_line(SIZE_STR, wmax.x - wmin.x, X_STR); + config_line(SIZE_STR, wmax.y - wmin.y, Y_STR); + config_line(SIZE_STR, wmax.z - wmin.z, Z_STR); + + // + // Print and Travel Acceleration + // + #define _ACCEL(A,B) _MIN(planner.settings.max_acceleration_mm_per_s2[A##_AXIS], planner.settings.B) + PGMSTR(P_ACC_STR, "PrintAccel"); + PGMSTR(T_ACC_STR, "TravelAccel"); + config_line(P_ACC_STR, _ACCEL(X, acceleration), X_STR); + config_line(P_ACC_STR, _ACCEL(Y, acceleration), Y_STR); + config_line(P_ACC_STR, _ACCEL(Z, acceleration), Z_STR); + config_line(T_ACC_STR, _ACCEL(X, travel_acceleration), X_STR); + config_line(T_ACC_STR, _ACCEL(Y, travel_acceleration), Y_STR); + config_line(T_ACC_STR, _ACCEL(Z, travel_acceleration), Z_STR); + + config_prefix(PSTR("PrinterType")); + SERIAL_ECHOLNPGM( + TERN_(DELTA, "Delta") + TERN_(IS_SCARA, "SCARA") + TERN_(IS_CORE, "Core") + TERN_(MARKFORGED_XY, "MarkForged") + TERN_(IS_CARTESIAN, "Cartesian") + ); + + // + // Heated Bed + // + config_line(PSTR("HeatedBed"), ENABLED(HAS_HEATED_BED)); + #if HAS_HEATED_BED + config_line(PSTR("MaxBedTemp"), BED_MAX_TARGET); + #endif + + // + // Per-Extruder settings + // + config_line(PSTR("NumExtruder"), EXTRUDERS); + #if EXTRUDERS + #define DIAM_VALUE(N) TERN(NO_VOLUMETRICS, DEFAULT_NOMINAL_FILAMENT_DIA, planner.filament_size[N]) + #if HAS_LINEAR_E_JERK + #define E_JERK_VAL(N) planner.max_e_jerk[E_INDEX_N(N)] + #elif HAS_CLASSIC_JERK + #define E_JERK_VAL(N) planner.max_jerk.e + #else + #define E_JERK_VAL(N) DEFAULT_EJERK + #endif + #define _EXTR_ITEM(N) do{ \ + PGMSTR(EXTR_STR, "Extr." STRINGIFY(INCREMENT(N)) ":"); \ + config_line(JERK_STR, E_JERK_VAL(N), EXTR_STR); \ + config_line(PSTR("MaxSpeed"), planner.settings.max_feedrate_mm_s[E_AXIS_N(N)], EXTR_STR); \ + config_line(PSTR("Acceleration"), planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(N)], EXTR_STR); \ + config_line(PSTR("Diameter"), DIAM_VALUE(N), EXTR_STR); \ + config_line(PSTR("MaxTemp"), (HEATER_##N##_MAXTEMP) - (HOTEND_OVERSHOOT), EXTR_STR); \ + }while(0) + + REPEAT(EXTRUDERS, _EXTR_ITEM); + #endif +} + +#endif diff --git a/Marlin/src/gcode/host/M876.cpp b/Marlin/src/gcode/host/M876.cpp index fe0ca1541abe..0d8256cf0874 100644 --- a/Marlin/src/gcode/host/M876.cpp +++ b/Marlin/src/gcode/host/M876.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #include "../../inc/MarlinConfig.h" diff --git a/Marlin/src/gcode/lcd/M0_M1.cpp b/Marlin/src/gcode/lcd/M0_M1.cpp index 2b35ddf3ff53..1d18b706029c 100644 --- a/Marlin/src/gcode/lcd/M0_M1.cpp +++ b/Marlin/src/gcode/lcd/M0_M1.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -24,21 +24,17 @@ #if HAS_RESUME_CONTINUE +#include "../../inc/MarlinConfig.h" + #include "../gcode.h" -#include "../../module/planner.h" -#include "../../inc/MarlinConfig.h" +#include "../../module/planner.h" // for synchronize() +#include "../../MarlinCore.h" // for wait_for_user_response() #if HAS_LCD_MENU #include "../../lcd/ultralcd.h" -#endif - -#if ENABLED(EXTENSIBLE_UI) - #include "../../lcd/extensible_ui/ui_api.h" -#endif - -#if HAS_LEDS_OFF_FLAG - #include "../../feature/leds/printer_event_leds.h" +#elif ENABLED(EXTENSIBLE_UI) + #include "../../lcd/extui/ui_api.h" #endif #if ENABLED(HOST_PROMPT_SUPPORT) @@ -50,32 +46,16 @@ * M1: Conditional stop - Wait for user button press on LCD */ void GcodeSuite::M0_M1() { - const char * const args = parser.string_arg; - millis_t ms = 0; - bool hasP = false, hasS = false; - if (parser.seenval('P')) { - ms = parser.value_millis(); // milliseconds to wait - hasP = ms > 0; - } - if (parser.seenval('S')) { - ms = parser.value_millis_from_seconds(); // seconds to wait - hasS = ms > 0; - } - - const bool has_message = !hasP && !hasS && args && *args; + if (parser.seenval('P')) ms = parser.value_millis(); // Milliseconds to wait + if (parser.seenval('S')) ms = parser.value_millis_from_seconds(); // Seconds to wait planner.synchronize(); - #if HAS_LEDS_OFF_FLAG - if (parser.seen('Q')) - printerEventLEDs.onPrintCompleted(); // Change LED color for Print Completed - #endif - #if HAS_LCD_MENU - if (has_message) - ui.set_status(args, true); + if (parser.string_arg) + ui.set_status(parser.string_arg, true); else { LCD_MESSAGEPGM(MSG_USERWAIT); #if ENABLED(LCD_PROGRESS_BAR) && PROGRESS_MSG_EXPIRE > 0 @@ -84,40 +64,24 @@ void GcodeSuite::M0_M1() { } #elif ENABLED(EXTENSIBLE_UI) - - if (has_message) - ExtUI::onUserConfirmRequired(args); // Can this take an SRAM string?? + if (parser.string_arg) + ExtUI::onUserConfirmRequired(parser.string_arg); // Can this take an SRAM string?? else ExtUI::onUserConfirmRequired_P(GET_TEXT(MSG_USERWAIT)); - #else - if (has_message) { + if (parser.string_arg) { SERIAL_ECHO_START(); - SERIAL_ECHOLN(args); + SERIAL_ECHOLN(parser.string_arg); } #endif - KEEPALIVE_STATE(PAUSED_FOR_USER); - wait_for_user = true; - - #if ENABLED(HOST_PROMPT_SUPPORT) - host_prompt_do(PROMPT_USER_CONTINUE, parser.codenum ? PSTR("M1 Stop") : PSTR("M0 Stop"), CONTINUE_STR); - #endif - - if (ms > 0) ms += millis(); // wait until this time for a click - while (wait_for_user && (ms == 0 || PENDING(millis(), ms))) idle(); + TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, parser.codenum ? PSTR("M1 Stop") : PSTR("M0 Stop"), CONTINUE_STR)); - #if HAS_LEDS_OFF_FLAG - printerEventLEDs.onResumeAfterWait(); - #endif - - #if HAS_LCD_MENU - ui.reset_status(); - #endif + wait_for_user_response(ms); - wait_for_user = false; + TERN_(HAS_LCD_MENU, ui.reset_status()); } #endif // HAS_RESUME_CONTINUE diff --git a/Marlin/src/gcode/lcd/M117.cpp b/Marlin/src/gcode/lcd/M117.cpp index 7e314731f8d3..8459135f3018 100644 --- a/Marlin/src/gcode/lcd/M117.cpp +++ b/Marlin/src/gcode/lcd/M117.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/lcd/M145.cpp b/Marlin/src/gcode/lcd/M145.cpp index 31167275338b..abd4dcc7439b 100644 --- a/Marlin/src/gcode/lcd/M145.cpp +++ b/Marlin/src/gcode/lcd/M145.cpp @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #include "../../inc/MarlinConfig.h" -#if HOTENDS && HAS_LCD_MENU +#if PREHEAT_COUNT #include "../gcode.h" #include "../../lcd/ultralcd.h" @@ -37,25 +37,23 @@ */ void GcodeSuite::M145() { const uint8_t material = (uint8_t)parser.intval('S'); - if (material >= COUNT(ui.preheat_hotend_temp)) + if (material >= PREHEAT_COUNT) SERIAL_ERROR_MSG(STR_ERR_MATERIAL_INDEX); else { - int v; - if (parser.seenval('H')) { - v = parser.value_int(); - ui.preheat_hotend_temp[material] = constrain(v, EXTRUDE_MINTEMP, HEATER_0_MAXTEMP - 15); - } - if (parser.seenval('F')) { - v = parser.value_int(); - ui.preheat_fan_speed[material] = (uint8_t)constrain(v, 0, 255); - } - #if TEMP_SENSOR_BED != 0 - if (parser.seenval('B')) { - v = parser.value_int(); - ui.preheat_bed_temp[material] = constrain(v, BED_MINTEMP, BED_MAXTEMP - 10); - } + preheat_t &mat = ui.material_preset[material]; + #if HAS_HOTEND + if (parser.seenval('H')) + mat.hotend_temp = constrain(parser.value_int(), EXTRUDE_MINTEMP, (HEATER_0_MAXTEMP) - (HOTEND_OVERSHOOT)); + #endif + #if HAS_HEATED_BED + if (parser.seenval('B')) + mat.bed_temp = constrain(parser.value_int(), BED_MINTEMP, BED_MAX_TARGET); + #endif + #if HAS_FAN + if (parser.seenval('F')) + mat.fan_speed = constrain(parser.value_int(), 0, 255); #endif } } -#endif // HOTENDS && HAS_LCD_MENU +#endif // PREHEAT_COUNT diff --git a/Marlin/src/gcode/lcd/M250.cpp b/Marlin/src/gcode/lcd/M250.cpp index 839fd259697c..f42daaeac428 100644 --- a/Marlin/src/gcode/lcd/M250.cpp +++ b/Marlin/src/gcode/lcd/M250.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/lcd/M300.cpp b/Marlin/src/gcode/lcd/M300.cpp index 5d7e766b2de5..56d9ee5d7350 100644 --- a/Marlin/src/gcode/lcd/M300.cpp +++ b/Marlin/src/gcode/lcd/M300.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/lcd/M73.cpp b/Marlin/src/gcode/lcd/M73.cpp index 347c42c442c4..7a5454419da9 100644 --- a/Marlin/src/gcode/lcd/M73.cpp +++ b/Marlin/src/gcode/lcd/M73.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -33,9 +33,6 @@ * * Example: * M73 P25 ; Set progress to 25% - * - * Notes: - * This has no effect during an SD print job */ void GcodeSuite::M73() { if (parser.seen('P')) diff --git a/Marlin/src/gcode/lcd/M995.cpp b/Marlin/src/gcode/lcd/M995.cpp new file mode 100644 index 000000000000..72d0d29f7683 --- /dev/null +++ b/Marlin/src/gcode/lcd/M995.cpp @@ -0,0 +1,39 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(TOUCH_SCREEN_CALIBRATION) + +#include "../gcode.h" +#include "../../lcd/menu/menu.h" + +/** + * M995: Touch screen calibration for TFT display + */ +void GcodeSuite::M995() { + + ui.goto_screen(touch_screen_calibration); + +} + +#endif // TOUCH_SCREEN_CALIBRATION diff --git a/Marlin/src/gcode/motion/G0_G1.cpp b/Marlin/src/gcode/motion/G0_G1.cpp index 8f0dfc71b2f6..9ac49bd93cf1 100644 --- a/Marlin/src/gcode/motion/G0_G1.cpp +++ b/Marlin/src/gcode/motion/G0_G1.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -44,15 +44,11 @@ extern xyze_pos_t destination; /** * G0, G1: Coordinated movement of X Y Z E axes */ -void GcodeSuite::G0_G1( - #if IS_SCARA || defined(G0_FEEDRATE) - const bool fast_move/*=false*/ - #endif -) { +void GcodeSuite::G0_G1(TERN_(HAS_FAST_MOVES, const bool fast_move/*=false*/)) { if (IsRunning() #if ENABLED(NO_MOTION_BEFORE_HOMING) - && !axis_unhomed_error( + && !homing_needed_error( (parser.seen('X') ? _BV(X_AXIS) : 0) | (parser.seen('Y') ? _BV(Y_AXIS) : 0) | (parser.seen('Z') ? _BV(Z_AXIS) : 0) ) @@ -69,7 +65,7 @@ void GcodeSuite::G0_G1( #endif #endif - get_destination_from_command(); // Process X Y Z E F parameters + get_destination_from_command(); // Get X Y Z E F (and set cutter power) #ifdef G0_FEEDRATE if (fast_move) { @@ -100,9 +96,9 @@ void GcodeSuite::G0_G1( #endif // FWRETRACT #if IS_SCARA - fast_move ? prepare_fast_move_to_destination() : prepare_move_to_destination(); + fast_move ? prepare_fast_move_to_destination() : prepare_line_to_destination(); #else - prepare_move_to_destination(); + prepare_line_to_destination(); #endif #ifdef G0_FEEDRATE diff --git a/Marlin/src/gcode/motion/G2_G3.cpp b/Marlin/src/gcode/motion/G2_G3.cpp index b11b1136b6e1..61d9f1d3a66d 100644 --- a/Marlin/src/gcode/motion/G2_G3.cpp +++ b/Marlin/src/gcode/motion/G2_G3.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -70,14 +70,12 @@ void plan_arc( ab_float_t rvec = -offset; const float radius = HYPOT(rvec.a, rvec.b), - #if ENABLED(AUTO_BED_LEVELING_UBL) - start_L = current_position[l_axis], - #endif center_P = current_position[p_axis] - rvec.a, center_Q = current_position[q_axis] - rvec.b, rt_X = cart[p_axis] - center_P, rt_Y = cart[q_axis] - center_Q, - linear_travel = cart[l_axis] - current_position[l_axis], + start_L = current_position[l_axis], + linear_travel = cart[l_axis] - start_L, extruder_travel = cart.e - current_position.e; // CCW angle of rotation between position and target from the circle center. Only one atan2() trig computation required. @@ -105,17 +103,20 @@ void plan_arc( const feedRate_t scaled_fr_mm_s = MMS_SCALED(feedrate_mm_s); - #ifdef ARC_SEGMENTS_PER_R - float seg_length = MM_PER_ARC_SEGMENT * radius; - LIMIT(seg_length, MM_PER_ARC_SEGMENT, ARC_SEGMENTS_PER_R); - #elif ARC_SEGMENTS_PER_SEC - float seg_length = scaled_fr_mm_s * RECIPROCAL(ARC_SEGMENTS_PER_SEC); - NOLESS(seg_length, MM_PER_ARC_SEGMENT); - #else - constexpr float seg_length = MM_PER_ARC_SEGMENT; - #endif + // Start with a nominal segment length + float seg_length = ( + #ifdef ARC_SEGMENTS_PER_R + constrain(MM_PER_ARC_SEGMENT * radius, MM_PER_ARC_SEGMENT, ARC_SEGMENTS_PER_R) + #elif ARC_SEGMENTS_PER_SEC + _MAX(scaled_fr_mm_s * RECIPROCAL(ARC_SEGMENTS_PER_SEC), MM_PER_ARC_SEGMENT) + #else + MM_PER_ARC_SEGMENT + #endif + ); + // Divide total travel by nominal segment length uint16_t segments = FLOOR(mm_of_travel / seg_length); - NOLESS(segments, min_segments); + NOLESS(segments, min_segments); // At least some segments + seg_length = mm_of_travel / segments; /** * Vector rotation by transformation matrix: r is the original vector, r_T is the rotated vector, @@ -148,8 +149,9 @@ void plan_arc( const float theta_per_segment = angular_travel / segments, linear_per_segment = linear_travel / segments, extruder_per_segment = extruder_travel / segments, - sin_T = theta_per_segment, - cos_T = 1 - 0.5f * sq(theta_per_segment); // Small angle approximation + sq_theta_per_segment = sq(theta_per_segment), + sin_T = theta_per_segment - sq_theta_per_segment*theta_per_segment/6, + cos_T = 1 - 0.5f * sq_theta_per_segment; // Small angle approximation // Initialize the linear axis raw[l_axis] = current_position[l_axis]; @@ -157,7 +159,6 @@ void plan_arc( // Initialize the extruder axis raw.e = current_position.e; - #if ENABLED(SCARA_FEEDRATE_SCALING) const float inv_duration = scaled_fr_mm_s / seg_length; #endif @@ -216,19 +217,16 @@ void plan_arc( planner.apply_leveling(raw); #endif - if (!planner.buffer_line(raw, scaled_fr_mm_s, active_extruder, seg_length + if (!planner.buffer_line(raw, scaled_fr_mm_s, active_extruder, 0 #if ENABLED(SCARA_FEEDRATE_SCALING) , inv_duration #endif - )) - break; + )) break; } // Ensure last segment arrives at target location. raw = cart; - #if ENABLED(AUTO_BED_LEVELING_UBL) - raw[l_axis] = start_L; - #endif + TERN_(AUTO_BED_LEVELING_UBL, raw[l_axis] = start_L); apply_motion_limits(raw); @@ -236,16 +234,15 @@ void plan_arc( planner.apply_leveling(raw); #endif - planner.buffer_line(raw, scaled_fr_mm_s, active_extruder, seg_length + planner.buffer_line(raw, scaled_fr_mm_s, active_extruder, 0 #if ENABLED(SCARA_FEEDRATE_SCALING) , inv_duration #endif ); - #if ENABLED(AUTO_BED_LEVELING_UBL) - raw[l_axis] = start_L; - #endif + TERN_(AUTO_BED_LEVELING_UBL, raw[l_axis] = start_L); current_position = raw; + } // plan_arc /** @@ -283,11 +280,9 @@ void GcodeSuite::G2_G3(const bool clockwise) { relative_mode = true; #endif - get_destination_from_command(); + get_destination_from_command(); // Get X Y Z E F (and set cutter power) - #if ENABLED(SF_ARC_FIX) - relative_mode = relative_mode_backup; - #endif + TERN_(SF_ARC_FIX, relative_mode = relative_mode_backup); ab_float_t arc_offset = { 0, 0 }; if (parser.seenval('R')) { diff --git a/Marlin/src/gcode/motion/G4.cpp b/Marlin/src/gcode/motion/G4.cpp index d157face9002..3a37fe5b2c4e 100644 --- a/Marlin/src/gcode/motion/G4.cpp +++ b/Marlin/src/gcode/motion/G4.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/motion/G5.cpp b/Marlin/src/gcode/motion/G5.cpp index 5d289e11d815..2c98fae84522 100644 --- a/Marlin/src/gcode/motion/G5.cpp +++ b/Marlin/src/gcode/motion/G5.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -29,7 +29,7 @@ /** * Parameters interpreted according to: - * http://linuxcnc.org/docs/2.6/html/gcode/parser.html#sec:G5-Cubic-Spline + * https://linuxcnc.org/docs/2.7/html/gcode/g-code.html#gcode:g5 * However I, J omission is not supported at this point; all * parameters can be omitted and default to zero. */ diff --git a/Marlin/src/gcode/motion/G6.cpp b/Marlin/src/gcode/motion/G6.cpp new file mode 100644 index 000000000000..168dc28abd23 --- /dev/null +++ b/Marlin/src/gcode/motion/G6.cpp @@ -0,0 +1,61 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../inc/MarlinConfig.h" + +#if ENABLED(DIRECT_STEPPING) + +#include "../../feature/direct_stepping.h" + +#include "../gcode.h" +#include "../../module/planner.h" + +/** + * G6: Direct Stepper Move + */ +void GcodeSuite::G6() { + // TODO: feedrate support? + if (parser.seen('R')) + planner.last_page_step_rate = parser.value_ulong(); + + if (!DirectStepping::Config::DIRECTIONAL) { + if (parser.seen('X')) planner.last_page_dir.x = !!parser.value_byte(); + if (parser.seen('Y')) planner.last_page_dir.y = !!parser.value_byte(); + if (parser.seen('Z')) planner.last_page_dir.z = !!parser.value_byte(); + if (parser.seen('E')) planner.last_page_dir.e = !!parser.value_byte(); + } + + // No index means we just set the state + if (!parser.seen('I')) return; + + // No speed is set, can't schedule the move + if (!planner.last_page_step_rate) return; + + const page_idx_t page_idx = (page_idx_t) parser.value_ulong(); + + uint16_t num_steps = DirectStepping::Config::TOTAL_STEPS; + if (parser.seen('S')) num_steps = parser.value_ushort(); + + planner.buffer_page(page_idx, 0, num_steps); + reset_stepper_timeout(); +} + +#endif // DIRECT_STEPPING diff --git a/Marlin/src/gcode/motion/G80.cpp b/Marlin/src/gcode/motion/G80.cpp index 700038df0f22..f674596ddd51 100644 --- a/Marlin/src/gcode/motion/G80.cpp +++ b/Marlin/src/gcode/motion/G80.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/motion/M290.cpp b/Marlin/src/gcode/motion/M290.cpp index 4f6489d3b912..18cc161fce29 100644 --- a/Marlin/src/gcode/motion/M290.cpp +++ b/Marlin/src/gcode/motion/M290.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -41,14 +41,10 @@ #if ENABLED(BABYSTEP_ZPROBE_OFFSET) FORCE_INLINE void mod_probe_offset(const float &offs) { - if (true - #if ENABLED(BABYSTEP_HOTEND_Z_OFFSET) - && active_extruder == 0 - #endif - ) { + if (TERN1(BABYSTEP_HOTEND_Z_OFFSET, active_extruder == 0)) { probe.offset.z += offs; SERIAL_ECHO_START(); - SERIAL_ECHOLNPAIR(STR_PROBE_OFFSET STR_Z ": ", probe.offset.z); + SERIAL_ECHOLNPAIR(STR_PROBE_OFFSET " " STR_Z, probe.offset.z); } else { #if ENABLED(BABYSTEP_HOTEND_Z_OFFSET) @@ -76,8 +72,8 @@ */ void GcodeSuite::M290() { #if ENABLED(BABYSTEP_XY) - for (uint8_t a = X_AXIS; a <= Z_AXIS; a++) - if (parser.seenval(axis_codes[a]) || (a == Z_AXIS && parser.seenval('S'))) { + LOOP_XYZ(a) + if (parser.seenval(XYZ_CHAR(a)) || (a == Z_AXIS && parser.seenval('S'))) { const float offs = constrain(parser.value_axis_units((AxisEnum)a), -2, 2); babystep.add_mm((AxisEnum)a, offs); #if ENABLED(BABYSTEP_ZPROBE_OFFSET) @@ -131,7 +127,7 @@ void GcodeSuite::M290() { #else PSTR("Babystep Z") #endif - , babystep.axis_total[BS_AXIS_IND(Z_AXIS)] + , babystep.axis_total[BS_TOTAL_IND(Z_AXIS)] ); } #endif diff --git a/Marlin/src/gcode/parser.cpp b/Marlin/src/gcode/parser.cpp index 0fac65300fb4..9c5085b97eca 100644 --- a/Marlin/src/gcode/parser.cpp +++ b/Marlin/src/gcode/parser.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -28,7 +28,7 @@ #include "../MarlinCore.h" -#if NUM_SERIAL > 1 +#if HAS_MULTI_SERIAL #include "queue.h" #endif @@ -83,9 +83,7 @@ void GCodeParser::reset() { string_arg = nullptr; // No whole line argument command_letter = '?'; // No command letter codenum = 0; // No command code - #if ENABLED(USE_GCODE_SUBCODES) - subcode = 0; // No command sub-code - #endif + TERN_(USE_GCODE_SUBCODES, subcode = 0); // No command sub-code #if ENABLED(FASTER_GCODE_PARSER) codebits = 0; // No codes yet //ZERO(param); // No parameters (should be safe to comment out this line) @@ -119,9 +117,8 @@ void GCodeParser::parse(char *p) { reset(); // No codes to report auto uppercase = [](char c) { - #if ENABLED(GCODE_CASE_INSENSITIVE) - if (WITHIN(c, 'a', 'z')) c += 'A' - 'a'; - #endif + if (TERN0(GCODE_CASE_INSENSITIVE, WITHIN(c, 'a', 'z'))) + c += 'A' - 'a'; return c; }; @@ -130,9 +127,7 @@ void GCodeParser::parse(char *p) { // Skip N[-0-9] if included in the command line if (uppercase(*p) == 'N' && NUMERIC_SIGNED(p[1])) { - #if ENABLED(FASTER_GCODE_PARSER) - //set('N', p + 1); // (optional) Set the 'N' parameter value - #endif + //TERN_(FASTER_GCODE_PARSER, set('N', p + 1)); // (optional) Set the 'N' parameter value p += 2; // skip N[-0-9] while (NUMERIC(*p)) ++p; // skip [0-9]* while (*p == ' ') ++p; // skip [ ]* @@ -152,22 +147,15 @@ void GCodeParser::parse(char *p) { starpos[1] = '\0'; } - #if ENABLED(GCODE_MOTION_MODES) - #if ENABLED(ARC_SUPPORT) - #define GTOP 3 - #else - #define GTOP 1 - #endif + #if ANY(MARLIN_DEV_MODE, SWITCHING_TOOLHEAD, MAGNETIC_SWITCHING_TOOLHEAD, ELECTROMAGNETIC_SWITCHING_TOOLHEAD) + #define SIGNED_CODENUM 1 #endif // Bail if the letter is not G, M, or T // (or a valid parameter for the current motion mode) switch (letter) { - case 'G': case 'M': case 'T': - #if ENABLED(CANCEL_OBJECTS) - case 'O': - #endif + case 'G': case 'M': case 'T': TERN_(MARLIN_DEV_MODE, case 'D':) // Skip spaces to get the numeric part while (*p == ' ') p++; @@ -183,22 +171,33 @@ void GCodeParser::parse(char *p) { #endif // Bail if there's no command code number - if (!NUMERIC(*p)) return; + if (!TERN(SIGNED_CODENUM, NUMERIC_SIGNED(*p), NUMERIC(*p))) return; // Save the command letter at this point // A '?' signifies an unknown command command_letter = letter; - // Get the code number - integer digits only - codenum = 0; - do { codenum *= 10, codenum += *p++ - '0'; } while (NUMERIC(*p)); + { + #if ENABLED(SIGNED_CODENUM) + int sign = 1; // Allow for a negative code like D-1 or T-1 + if (*p == '-') { sign = -1; ++p; } + #endif + + // Get the code number - integer digits only + codenum = 0; + + do { codenum = codenum * 10 + *p++ - '0'; } while (NUMERIC(*p)); + + // Apply the sign, if any + TERN_(SIGNED_CODENUM, codenum *= sign); + } // Allow for decimal point in command #if ENABLED(USE_GCODE_SUBCODES) if (*p == '.') { p++; while (NUMERIC(*p)) - subcode *= 10, subcode += *p++ - '0'; + subcode = subcode * 10 + *p++ - '0'; } #endif @@ -206,16 +205,11 @@ void GCodeParser::parse(char *p) { while (*p == ' ') p++; #if ENABLED(GCODE_MOTION_MODES) - if (letter == 'G' && (codenum <= GTOP || codenum == 5 - #if ENABLED(G38_PROBE_TARGET) - || codenum == 38 - #endif - ) + if (letter == 'G' + && (codenum <= TERN(ARC_SUPPORT, 3, 1) || codenum == 5 || TERN0(G38_PROBE_TARGET, codenum == 38)) ) { motion_mode_codenum = codenum; - #if ENABLED(USE_GCODE_SUBCODES) - motion_mode_subcode = subcode; - #endif + TERN_(USE_GCODE_SUBCODES, motion_mode_subcode = subcode); } #endif @@ -223,18 +217,16 @@ void GCodeParser::parse(char *p) { #if ENABLED(GCODE_MOTION_MODES) #if ENABLED(ARC_SUPPORT) - case 'I': case 'J': case 'R': + case 'I' ... 'J': case 'R': if (motion_mode_codenum != 2 && motion_mode_codenum != 3) return; #endif - case 'P': case 'Q': + case 'P' ... 'Q': if (motion_mode_codenum != 5) return; - case 'X': case 'Y': case 'Z': case 'E': case 'F': + case 'X' ... 'Z': case 'E' ... 'F': if (motion_mode_codenum < 0) return; command_letter = 'G'; codenum = motion_mode_codenum; - #if ENABLED(USE_GCODE_SUBCODES) - subcode = motion_mode_subcode; - #endif + TERN_(USE_GCODE_SUBCODES, subcode = motion_mode_subcode); p--; // Back up one character to use the current parameter break; #endif // GCODE_MOTION_MODES @@ -256,7 +248,7 @@ void GCodeParser::parse(char *p) { #if ENABLED(EXPECTED_PRINTER_CHECK) case 16: #endif - case 23: case 28: case 30: case 117: case 118: case 928: + case 23: case 28: case 30: case 117 ... 118: case 928: string_arg = unescape_string(p); return; default: break; @@ -312,7 +304,9 @@ void GCodeParser::parse(char *p) { char * const valptr = has_val ? is_str ? unescape_string(p) : p : nullptr; #else const bool has_val = valid_float(p); - char * const valptr = has_val ? p : nullptr; + #if ENABLED(FASTER_GCODE_PARSER) + char * const valptr = has_val ? p : nullptr; + #endif #endif #if ENABLED(DEBUG_GCODE_PARSER) @@ -329,13 +323,9 @@ void GCodeParser::parse(char *p) { #endif } - #if ENABLED(DEBUG_GCODE_PARSER) - if (debug) SERIAL_EOL(); - #endif + if (TERN0(DEBUG_GCODE_PARSER, debug)) SERIAL_EOL(); - #if ENABLED(FASTER_GCODE_PARSER) - set(param, valptr); // Set parameter exists and pointer (nullptr for no value) - #endif + TERN_(FASTER_GCODE_PARSER, set(param, valptr)); // Set parameter exists and pointer (nullptr for no value) } else if (!string_arg) { // Not A-Z? First time, keep as the string_arg string_arg = p - 1; diff --git a/Marlin/src/gcode/parser.h b/Marlin/src/gcode/parser.h index 06e41ccf13d8..42b85ca27195 100644 --- a/Marlin/src/gcode/parser.h +++ b/Marlin/src/gcode/parser.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -31,7 +31,7 @@ //#define DEBUG_GCODE_PARSER #if ENABLED(DEBUG_GCODE_PARSER) - #include "../libs/hex_print_routines.h" + #include "../libs/hex_print.h" #endif #if ENABLED(TEMPERATURE_UNITS_SUPPORT) @@ -114,6 +114,11 @@ class GCodeParser { return valid_signless(p) || ((p[0] == '-' || p[0] == '+') && valid_signless(&p[1])); // [-+]?.?[0-9] } + FORCE_INLINE static bool valid_number(const char * const p) { + // TODO: With MARLIN_DEV_MODE allow HEX values starting with "x" + return valid_float(p); + } + #if ENABLED(FASTER_GCODE_PARSER) FORCE_INLINE static bool valid_int(const char * const p) { @@ -142,8 +147,12 @@ class GCodeParser { if (ind >= COUNT(param)) return false; // Only A-Z const bool b = TEST32(codebits, ind); if (b) { - char * const ptr = command_ptr + param[ind]; - value_ptr = param[ind] && valid_float(ptr) ? ptr : nullptr; + if (param[ind]) { + char * const ptr = command_ptr + param[ind]; + value_ptr = valid_number(ptr) ? ptr : nullptr; + } + else + value_ptr = nullptr; } return b; } @@ -198,7 +207,7 @@ class GCodeParser { static inline bool seen(const char c) { char *p = strgchr(command_args, c); const bool b = !!p; - if (b) value_ptr = valid_float(&p[1]) ? &p[1] : nullptr; + if (b) value_ptr = valid_number(&p[1]) ? &p[1] : nullptr; return b; } @@ -401,6 +410,25 @@ class GCodeParser { static inline float linearval(const char c, const float dval=0) { return seenval(c) ? value_linear_units() : dval; } static inline float celsiusval(const char c, const float dval=0) { return seenval(c) ? value_celsius() : dval; } + #if ENABLED(MARLIN_DEV_MODE) + + static inline uint8_t* hex_adr_val(const char c, uint8_t * const dval=nullptr) { + if (!seen(c) || *value_ptr != 'x') return dval; + uint8_t *out = nullptr; + for (char *vp = value_ptr + 1; HEXCHR(*vp) >= 0; vp++) + out = (uint8_t*)((uintptr_t(out) << 8) | HEXCHR(*vp)); + return out; + } + + static inline uint16_t hex_val(const char c, uint16_t const dval=0) { + if (!seen(c) || *value_ptr != 'x') return dval; + uint16_t out = 0; + for (char *vp = value_ptr + 1; HEXCHR(*vp) >= 0; vp++) + out = ((out) << 8) | HEXCHR(*vp); + return out; + } + + #endif }; extern GCodeParser parser; diff --git a/Marlin/src/gcode/probe/G30.cpp b/Marlin/src/gcode/probe/G30.cpp index 8b2ada9ceca8..4347f55aa8f8 100644 --- a/Marlin/src/gcode/probe/G30.cpp +++ b/Marlin/src/gcode/probe/G30.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -43,25 +43,22 @@ void GcodeSuite::G30() { const xy_pos_t pos = { parser.linearval('X', current_position.x + probe.offset_xy.x), parser.linearval('Y', current_position.y + probe.offset_xy.y) }; - if (!position_is_reachable_by_probe(pos)) return; + if (!probe.can_reach(pos)) return; // Disable leveling so the planner won't mess with us - #if HAS_LEVELING - set_bed_leveling_enabled(false); - #endif + TERN_(HAS_LEVELING, set_bed_leveling_enabled(false)); remember_feedrate_scaling_off(); const ProbePtRaise raise_after = parser.boolval('E', true) ? PROBE_PT_STOW : PROBE_PT_NONE; const float measured_z = probe.probe_at_point(pos, raise_after, 1); if (!isnan(measured_z)) - SERIAL_ECHOLNPAIR("Bed X: ", FIXFLOAT(pos.x), " Y: ", FIXFLOAT(pos.y), " Z: ", FIXFLOAT(measured_z)); + SERIAL_ECHOLNPAIR("Bed X: ", pos.x, " Y: ", pos.y, " Z: ", measured_z); restore_feedrate_and_scaling(); - #ifdef Z_AFTER_PROBING - if (raise_after == PROBE_PT_STOW) probe.move_z_after_probing(); - #endif + if (raise_after == PROBE_PT_STOW) + probe.move_z_after_probing(); report_current_position(); } diff --git a/Marlin/src/gcode/probe/G31_G32.cpp b/Marlin/src/gcode/probe/G31_G32.cpp index e2e43e35edc9..af44257d6195 100644 --- a/Marlin/src/gcode/probe/G31_G32.cpp +++ b/Marlin/src/gcode/probe/G31_G32.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/probe/G38.cpp b/Marlin/src/gcode/probe/G38.cpp index 11b7ce5af74d..b06cd47359c7 100644 --- a/Marlin/src/gcode/probe/G38.cpp +++ b/Marlin/src/gcode/probe/G38.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -34,7 +34,7 @@ inline void G38_single_probe(const uint8_t move_value) { endstops.enable(true); G38_move = move_value; - prepare_move_to_destination(); + prepare_line_to_destination(); planner.synchronize(); G38_move = 0; endstops.hit_on_purpose(); @@ -77,7 +77,7 @@ inline bool G38_run_probe() { // Move away by the retract distance destination = current_position + retract_mm; endstops.enable(false); - prepare_move_to_destination(); + prepare_line_to_destination(); planner.synchronize(); REMEMBER(fr, feedrate_mm_s, feedrate_mm_s * 0.25); diff --git a/Marlin/src/gcode/probe/M401_M402.cpp b/Marlin/src/gcode/probe/M401_M402.cpp index a0a6c1cec5d5..8e9bd11b81d7 100644 --- a/Marlin/src/gcode/probe/M401_M402.cpp +++ b/Marlin/src/gcode/probe/M401_M402.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -41,9 +41,7 @@ void GcodeSuite::M401() { */ void GcodeSuite::M402() { probe.stow(); - #ifdef Z_AFTER_PROBING - probe.move_z_after_probing(); - #endif + probe.move_z_after_probing(); report_current_position(); } diff --git a/Marlin/src/gcode/probe/M851.cpp b/Marlin/src/gcode/probe/M851.cpp index c2e746cf0b5c..ee60e9ebc011 100644 --- a/Marlin/src/gcode/probe/M851.cpp +++ b/Marlin/src/gcode/probe/M851.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/probe/M951.cpp b/Marlin/src/gcode/probe/M951.cpp index c7e4ea8a705c..f461fc2b079d 100644 --- a/Marlin/src/gcode/probe/M951.cpp +++ b/Marlin/src/gcode/probe/M951.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -46,9 +46,7 @@ void mpe_settings_init() { mpe_settings.parking_xpos[0] = pex[0]; // M951 L mpe_settings.parking_xpos[1] = pex[1]; // M951 R mpe_settings.grab_distance = PARKING_EXTRUDER_GRAB_DISTANCE; // M951 I - #if HAS_HOME_OFFSET - set_home_offset(X_AXIS, mpe_settings.grab_distance * -1); - #endif + TERN_(HAS_HOME_OFFSET, set_home_offset(X_AXIS, mpe_settings.grab_distance * -1)); mpe_settings.slow_feedrate = MMM_TO_MMS(MPE_SLOW_SPEED); // M951 J mpe_settings.fast_feedrate = MMM_TO_MMS(MPE_FAST_SPEED); // M951 H mpe_settings.travel_distance = MPE_TRAVEL_DISTANCE; // M951 D @@ -61,9 +59,7 @@ void GcodeSuite::M951() { if (parser.seenval('R')) mpe_settings.parking_xpos[1] = parser.value_linear_units(); if (parser.seenval('I')) { mpe_settings.grab_distance = parser.value_linear_units(); - #if HAS_HOME_OFFSET - set_home_offset(X_AXIS, mpe_settings.grab_distance * -1); - #endif + TERN_(HAS_HOME_OFFSET, set_home_offset(X_AXIS, mpe_settings.grab_distance * -1)); } if (parser.seenval('J')) mpe_settings.slow_feedrate = MMM_TO_MMS(parser.value_linear_units()); if (parser.seenval('H')) mpe_settings.fast_feedrate = MMM_TO_MMS(parser.value_linear_units()); diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp index 7d17ca602b6f..a02d2c016042 100644 --- a/Marlin/src/gcode/queue.cpp +++ b/Marlin/src/gcode/queue.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -40,11 +40,11 @@ GCodeQueue queue; #endif #if ENABLED(BINARY_FILE_TRANSFER) - #include "../feature/binary_protocol.h" + #include "../feature/binary_stream.h" #endif #if ENABLED(POWER_LOSS_RECOVERY) - #include "../feature/power_loss_recovery.h" + #include "../feature/powerloss.h" #endif /** @@ -52,7 +52,7 @@ GCodeQueue queue; * sending commands to Marlin, and lines will be checked for sequentiality. * M110 N sets the current line number. */ -long gcode_N, GCodeQueue::last_N; +long GCodeQueue::last_N[NUM_SERIAL]; /** * GCode Command Queue @@ -72,7 +72,7 @@ char GCodeQueue::command_buffer[BUFSIZE][MAX_CMD_SIZE]; /* * The port that the command was received on */ -#if NUM_SERIAL > 1 +#if HAS_MULTI_SERIAL int16_t GCodeQueue::port[BUFSIZE]; #endif @@ -86,22 +86,26 @@ static int serial_count[NUM_SERIAL] = { 0 }; bool send_ok[BUFSIZE]; /** - * Next Injected Command pointer. nullptr if no commands are being injected. - * Used by Marlin internally to ensure that commands initiated from within - * are enqueued ahead of any pending serial or sd card commands. + * Next Injected PROGMEM Command pointer. (nullptr == empty) + * Internal commands are enqueued ahead of serial / SD commands. */ -static PGM_P injected_commands_P = nullptr; +PGM_P GCodeQueue::injected_commands_P; // = nullptr + +/** + * Injected SRAM Commands + */ +char GCodeQueue::injected_commands[64]; // = { 0 } GCodeQueue::GCodeQueue() { // Send "ok" after commands by default - for (uint8_t i = 0; i < COUNT(send_ok); i++) send_ok[i] = true; + LOOP_L_N(i, COUNT(send_ok)) send_ok[i] = true; } /** * Check whether there are any commands yet to be executed */ bool GCodeQueue::has_commands_queued() { - return queue.length || injected_commands_P; + return queue.length || injected_commands_P || injected_commands[0]; } /** @@ -115,17 +119,13 @@ void GCodeQueue::clear() { * Once a new command is in the ring buffer, call this to commit it */ void GCodeQueue::_commit_command(bool say_ok - #if NUM_SERIAL > 1 + #if HAS_MULTI_SERIAL , int16_t p/*=-1*/ #endif ) { send_ok[index_w] = say_ok; - #if NUM_SERIAL > 1 - port[index_w] = p; - #endif - #if ENABLED(POWER_LOSS_RECOVERY) - recovery.commit_sdpos(index_w); - #endif + TERN_(HAS_MULTI_SERIAL, port[index_w] = p); + TERN_(POWER_LOSS_RECOVERY, recovery.commit_sdpos(index_w)); if (++index_w >= BUFSIZE) index_w = 0; length++; } @@ -136,20 +136,22 @@ void GCodeQueue::_commit_command(bool say_ok * Return false for a full buffer, or if the 'command' is a comment. */ bool GCodeQueue::_enqueue(const char* cmd, bool say_ok/*=false*/ - #if NUM_SERIAL > 1 + #if HAS_MULTI_SERIAL , int16_t pn/*=-1*/ #endif ) { if (*cmd == ';' || length >= BUFSIZE) return false; strcpy(command_buffer[index_w], cmd); _commit_command(say_ok - #if NUM_SERIAL > 1 + #if HAS_MULTI_SERIAL , pn #endif ); return true; } +#define ISEOL(C) ((C) == '\n' || (C) == '\r') + /** * Enqueue with Serial Echo * Return true if the command was consumed @@ -160,7 +162,7 @@ bool GCodeQueue::enqueue_one(const char* cmd) { //SERIAL_ECHO(cmd); //SERIAL_ECHOPGM("\") \n"); - if (*cmd == 0 || *cmd == '\n' || *cmd == '\r') return true; + if (*cmd == 0 || ISEOL(*cmd)) return true; if (_enqueue(cmd)) { SERIAL_ECHO_MSG(STR_ENQUEUEING, cmd, "\""); @@ -170,11 +172,10 @@ bool GCodeQueue::enqueue_one(const char* cmd) { } /** - * Process the next "immediate" command. - * Return 'true' if any commands were processed, - * or remain to process. + * Process the next "immediate" command from PROGMEM. + * Return 'true' if any commands were processed. */ -bool GCodeQueue::process_injected_command() { +bool GCodeQueue::process_injected_command_P() { if (injected_commands_P == nullptr) return false; char c; @@ -196,12 +197,32 @@ bool GCodeQueue::process_injected_command() { } /** - * Enqueue one or many commands to run from program memory. - * Do not inject a comment or use leading spaces! - * Aborts the current queue, if any. - * Note: process_injected_command() will be called to drain any commands afterwards + * Process the next "immediate" command from SRAM. + * Return 'true' if any commands were processed. */ -void GCodeQueue::inject_P(PGM_P const pgcode) { injected_commands_P = pgcode; } +bool GCodeQueue::process_injected_command() { + if (injected_commands[0] == '\0') return false; + + char c; + size_t i = 0; + while ((c = injected_commands[i]) && c != '\n') i++; + + // Execute a non-blank command + if (i) { + injected_commands[i] = '\0'; + parser.parse(injected_commands); + gcode.process_parsed_command(); + } + + // Copy the next command into place + for ( + uint8_t d = 0, s = i + !!c; // dst, src + (injected_commands[d] = injected_commands[s]); // copy, exit if 0 + d++, s++ // next dst, src + ); + + return true; +} /** * Enqueue and return only when commands are actually enqueued. @@ -209,6 +230,21 @@ void GCodeQueue::inject_P(PGM_P const pgcode) { injected_commands_P = pgcode; } */ void GCodeQueue::enqueue_one_now(const char* cmd) { while (!enqueue_one(cmd)) idle(); } +/** + * Attempt to enqueue a single G-code command + * and return 'true' if successful. + */ +bool GCodeQueue::enqueue_one_P(PGM_P const pgcode) { + size_t i = 0; + PGM_P p = pgcode; + char c; + while ((c = pgm_read_byte(&p[i])) && c != '\n') i++; + char cmd[i + 1]; + memcpy_P(cmd, p, i); + cmd[i] = '\0'; + return _enqueue(cmd); +} + /** * Enqueue from program memory and return only when commands are actually enqueued * Never call this from a G-code handler! @@ -238,8 +274,8 @@ void GCodeQueue::enqueue_now_P(PGM_P const pgcode) { * B Block queue space remaining */ void GCodeQueue::ok_to_send() { - #if NUM_SERIAL > 1 - const int16_t pn = port[index_r]; + #if HAS_MULTI_SERIAL + const int16_t pn = command_port(); if (pn < 0) return; PORT_REDIRECT(pn); // Reply to the serial port that sent the command #endif @@ -253,8 +289,8 @@ void GCodeQueue::ok_to_send() { while (NUMERIC_SIGNED(*p)) SERIAL_ECHO(*p++); } - SERIAL_ECHOPAIR_P(SP_P_STR, int(planner.moves_free())); - SERIAL_ECHOPAIR(" B", int(BUFSIZE - length)); + SERIAL_ECHOPAIR_P(SP_P_STR, int(planner.moves_free()), + SP_B_STR, int(BUFSIZE - length)); #endif SERIAL_EOL(); } @@ -264,30 +300,25 @@ void GCodeQueue::ok_to_send() { * indicate that a command needs to be re-sent. */ void GCodeQueue::flush_and_request_resend() { - #if NUM_SERIAL > 1 - const int16_t pn = port[index_r]; + const int16_t pn = command_port(); + #if HAS_MULTI_SERIAL if (pn < 0) return; PORT_REDIRECT(pn); // Reply to the serial port that sent the command #endif SERIAL_FLUSH(); SERIAL_ECHOPGM(STR_RESEND); - SERIAL_ECHOLN(last_N + 1); + SERIAL_ECHOLN(last_N[pn] + 1); ok_to_send(); } inline bool serial_data_available() { - return false - || MYSERIAL0.available() - #if NUM_SERIAL > 1 - || MYSERIAL1.available() - #endif - ; + return MYSERIAL0.available() || TERN0(HAS_MULTI_SERIAL, MYSERIAL1.available()); } inline int read_serial(const uint8_t index) { switch (index) { case 0: return MYSERIAL0.read(); - #if NUM_SERIAL > 1 + #if HAS_MULTI_SERIAL case 1: return MYSERIAL1.read(); #endif default: return -1; @@ -298,7 +329,7 @@ void GCodeQueue::gcode_line_error(PGM_P const err, const int8_t pn) { PORT_REDIRECT(pn); // Reply to the serial port that sent the command SERIAL_ERROR_START(); serialprintPGM(err); - SERIAL_ECHOLN(last_N); + SERIAL_ECHOLN(last_N[pn]); while (read_serial(pn) != -1); // Clear out the RX buffer flush_and_request_resend(); serial_count[pn] = 0; @@ -356,11 +387,21 @@ inline void process_stream_char(const char c, uint8_t &sis, char (&buff)[MAX_CMD } #endif - buff[ind++] = c; - if (ind >= MAX_CMD_SIZE - 1) - sis = PS_EOL; // Skip the rest on overflow + // Backspace erases previous characters + if (c == 0x08) { + if (ind) buff[--ind] = '\0'; + } + else { + buff[ind++] = c; + if (ind >= MAX_CMD_SIZE - 1) + sis = PS_EOL; // Skip the rest on overflow + } } +/** + * Handle a line being completed. For an empty line + * keep sensor readings going and watchdog alive. + */ inline bool process_line_done(uint8_t &sis, char (&buff)[MAX_CMD_SIZE], int &ind) { sis = PS_NORMAL; buff[ind] = 0; @@ -406,14 +447,14 @@ void GCodeQueue::get_serial_commands() { * Loop while serial characters are incoming and the queue is not full */ while (length < BUFSIZE && serial_data_available()) { - for (uint8_t i = 0; i < NUM_SERIAL; ++i) { + LOOP_L_N(i, NUM_SERIAL) { const int c = read_serial(i); if (c < 0) continue; const char serial_char = c; - if (serial_char == '\n' || serial_char == '\r') { + if (ISEOL(serial_char)) { // Reset our state, continue if the line was empty if (process_line_done(serial_input_state[i], serial_line_buffer[i], serial_count[i])) @@ -433,9 +474,9 @@ void GCodeQueue::get_serial_commands() { if (n2pos) npos = n2pos; } - gcode_N = strtol(npos + 1, nullptr, 10); + const long gcode_N = strtol(npos + 1, nullptr, 10); - if (gcode_N != last_N + 1 && !M110) + if (gcode_N != last_N[i] + 1 && !M110) return gcode_line_error(PSTR(STR_ERR_LINE_NO), i); char *apos = strrchr(command, '*'); @@ -448,7 +489,7 @@ void GCodeQueue::get_serial_commands() { else return gcode_line_error(PSTR(STR_ERR_NO_CHECKSUM), i); - last_N = gcode_N; + last_N[i] = gcode_N; } #if ENABLED(SDSUPPORT) // Pronterface "M29" and "M29 " has no line number @@ -481,14 +522,12 @@ void GCodeQueue::get_serial_commands() { #if DISABLED(EMERGENCY_PARSER) // Process critical commands early - if (strcmp(command, "M108") == 0) { + if (strcmp_P(command, PSTR("M108")) == 0) { wait_for_heatup = false; - #if HAS_LCD_MENU - wait_for_user = false; - #endif + TERN_(HAS_LCD_MENU, wait_for_user = false); } - if (strcmp(command, "M112") == 0) kill(M112_KILL_STR, nullptr, true); - if (strcmp(command, "M410") == 0) quickstop_stepper(); + if (strcmp_P(command, PSTR("M112")) == 0) kill(M112_KILL_STR, nullptr, true); + if (strcmp_P(command, PSTR("M410")) == 0) quickstop_stepper(); #endif #if defined(NO_TIMEOUTS) && NO_TIMEOUTS > 0 @@ -497,7 +536,7 @@ void GCodeQueue::get_serial_commands() { // Add the command to the queue _enqueue(serial_line_buffer[i], true - #if NUM_SERIAL > 1 + #if HAS_MULTI_SERIAL , i #endif ); @@ -530,7 +569,7 @@ void GCodeQueue::get_serial_commands() { if (n < 0 && !card_eof) { SERIAL_ERROR_MSG(STR_SD_ERR_READ); continue; } const char sd_char = (char)n; - const bool is_eol = sd_char == '\n' || sd_char == '\r'; + const bool is_eol = ISEOL(sd_char); if (is_eol || card_eof) { // Reset stream state, terminate the buffer, and commit a non-empty command @@ -554,7 +593,7 @@ void GCodeQueue::get_serial_commands() { /** * Add to the circular command queue the next command from: - * - The command-injection queue (injected_commands_P) + * - The command-injection queues (injected_commands_P, injected_commands) * - The active serial input (usually USB) * - The SD card file being actively printed */ @@ -562,9 +601,7 @@ void GCodeQueue::get_available_commands() { get_serial_commands(); - #if ENABLED(SDSUPPORT) - get_sdcard_commands(); - #endif + TERN_(SDSUPPORT, get_sdcard_commands()); } /** @@ -573,7 +610,7 @@ void GCodeQueue::get_available_commands() { void GCodeQueue::advance() { // Process immediate commands - if (process_injected_command()) return; + if (process_injected_command_P() || process_injected_command()) return; // Return if the G-code buffer is empty if (!length) return; @@ -587,15 +624,14 @@ void GCodeQueue::advance() { card.closefile(); SERIAL_ECHOLNPGM(STR_FILE_SAVED); - #if !defined(__AVR__) || !defined(USBCON) + #if !IS_AT90USB #if ENABLED(SERIAL_STATS_DROPPED_RX) SERIAL_ECHOLNPAIR("Dropped bytes: ", MYSERIAL0.dropped()); #endif - #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) SERIAL_ECHOLNPAIR("Max RX Queue Size: ", MYSERIAL0.rxMaxEnqueued()); #endif - #endif // !defined(__AVR__) || !defined(USBCON) + #endif ok_to_send(); } diff --git a/Marlin/src/gcode/queue.h b/Marlin/src/gcode/queue.h index 1ce64590c367..966af2871ffe 100644 --- a/Marlin/src/gcode/queue.h +++ b/Marlin/src/gcode/queue.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -35,7 +35,8 @@ class GCodeQueue { * commands to Marlin, and lines will be checked for sequentiality. * M110 N sets the current line number. */ - static long last_N; + + static long last_N[NUM_SERIAL]; /** * GCode Command Queue @@ -51,13 +52,17 @@ class GCodeQueue { static char command_buffer[BUFSIZE][MAX_CMD_SIZE]; - /* + /** * The port that the command was received on */ - #if NUM_SERIAL > 1 + #if HAS_MULTI_SERIAL static int16_t port[BUFSIZE]; #endif + static int16_t command_port() { + return TERN0(HAS_MULTI_SERIAL, port[index_r]); + } + GCodeQueue(); /** @@ -66,17 +71,42 @@ class GCodeQueue { static void clear(); /** - * Enqueue one or many commands to run from program memory. - * Aborts the current queue, if any. - * Note: process_injected_command() will process them. + * Next Injected Command (PROGMEM) pointer. (nullptr == empty) + * Internal commands are enqueued ahead of serial / SD commands. + */ + static PGM_P injected_commands_P; + + /** + * Injected Commands (SRAM) + */ + static char injected_commands[64]; + + /** + * Enqueue command(s) to run from PROGMEM. Drained by process_injected_command_P(). + * Don't inject comments or use leading spaces! + * Aborts the current PROGMEM queue so only use for one or two commands. + */ + static inline void inject_P(PGM_P const pgcode) { injected_commands_P = pgcode; } + + /** + * Enqueue command(s) to run from SRAM. Drained by process_injected_command(). + * Aborts the current SRAM queue so only use for one or two commands. */ - static void inject_P(PGM_P const pgcode); + static inline void inject(char * const gcode) { + strncpy(injected_commands, gcode, sizeof(injected_commands) - 1); + } /** * Enqueue and return only when commands are actually enqueued */ static void enqueue_one_now(const char* cmd); + /** + * Attempt to enqueue a single G-code command + * and return 'true' if successful. + */ + static bool enqueue_one_P(PGM_P const pgcode); + /** * Enqueue from program memory and return only when commands are actually enqueued */ @@ -117,12 +147,6 @@ class GCodeQueue { */ static void flush_and_request_resend(); - /** - * Attempt to enqueue a single G-code command - * and return 'true' if successful. - */ - FORCE_INLINE static bool enqueue_P(const char* cmd) { return _enqueue(cmd); } - private: static uint8_t index_w; // Ring buffer write position @@ -134,18 +158,21 @@ class GCodeQueue { #endif static void _commit_command(bool say_ok - #if NUM_SERIAL > 1 + #if HAS_MULTI_SERIAL , int16_t p=-1 #endif ); static bool _enqueue(const char* cmd, bool say_ok=false - #if NUM_SERIAL > 1 + #if HAS_MULTI_SERIAL , int16_t p=-1 #endif ); - // Process the next "immediate" command + // Process the next "immediate" command (PROGMEM) + static bool process_injected_command_P(); + + // Process the next "immediate" command (SRAM) static bool process_injected_command(); /** diff --git a/Marlin/src/gcode/scara/M360-M364.cpp b/Marlin/src/gcode/scara/M360-M364.cpp index cd901d5dd45f..562beee4f98e 100644 --- a/Marlin/src/gcode/scara/M360-M364.cpp +++ b/Marlin/src/gcode/scara/M360-M364.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/sd/M1001.cpp b/Marlin/src/gcode/sd/M1001.cpp new file mode 100644 index 000000000000..b28429f6315d --- /dev/null +++ b/Marlin/src/gcode/sd/M1001.cpp @@ -0,0 +1,103 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(SDSUPPORT) + +#include "../gcode.h" +#include "../../module/printcounter.h" + +#ifdef SD_FINISHED_RELEASECOMMAND + #include "../queue.h" +#endif + +#if EITHER(LCD_SET_PROGRESS_MANUALLY, SD_REPRINT_LAST_SELECTED_FILE) + #include "../../lcd/ultralcd.h" +#endif + +#if ENABLED(POWER_LOSS_RECOVERY) + #include "../../feature/powerloss.h" +#endif + +#if HAS_LEDS_OFF_FLAG + #include "../../MarlinCore.h" // for wait_for_user_response + #include "../../feature/leds/printer_event_leds.h" +#endif + +#if ENABLED(EXTENSIBLE_UI) + #include "../../lcd/extui/ui_api.h" +#endif + +#if ENABLED(HOST_ACTION_COMMANDS) + #include "../../feature/host_actions.h" +#endif + +#ifndef PE_LEDS_COMPLETED_TIME + #define PE_LEDS_COMPLETED_TIME (30*60) +#endif + +/** + * M1001: Execute actions for SD print completion + */ +void GcodeSuite::M1001() { + + // Report total print time + const bool long_print = print_job_timer.duration() > 60; + if (long_print) gcode.process_subcommands_now_P(PSTR("M31")); + + // Stop the print job timer + gcode.process_subcommands_now_P(PSTR("M77")); + + // Set the progress bar "done" state + TERN_(LCD_SET_PROGRESS_MANUALLY, ui.set_progress_done()); + + // Purge the recovery file + TERN_(POWER_LOSS_RECOVERY, recovery.purge()); + + // Announce SD file completion + { + PORT_REDIRECT(SERIAL_BOTH); + SERIAL_ECHOLNPGM(STR_FILE_PRINTED); + } + + // Update the status LED color + #if HAS_LEDS_OFF_FLAG + if (long_print) { + printerEventLEDs.onPrintCompleted(); + TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(GET_TEXT(MSG_PRINT_DONE))); + TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, GET_TEXT(MSG_PRINT_DONE), CONTINUE_STR)); + wait_for_user_response(1000UL * TERN(HAS_LCD_MENU, PE_LEDS_COMPLETED_TIME, 30)); + printerEventLEDs.onResumeAfterWait(); + } + #endif + + // Inject SD_FINISHED_RELEASECOMMAND, if any + #ifdef SD_FINISHED_RELEASECOMMAND + queue.inject_P(PSTR(SD_FINISHED_RELEASECOMMAND)); + #endif + + // Re-select the last printed file in the UI + TERN_(SD_REPRINT_LAST_SELECTED_FILE, ui.reselect_last_file()); +} + +#endif // SDSUPPORT diff --git a/Marlin/src/gcode/sdcard/M20.cpp b/Marlin/src/gcode/sd/M20.cpp similarity index 80% rename from Marlin/src/gcode/sdcard/M20.cpp rename to Marlin/src/gcode/sd/M20.cpp index c45fcb038a97..7ac4affdae9c 100644 --- a/Marlin/src/gcode/sdcard/M20.cpp +++ b/Marlin/src/gcode/sd/M20.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -31,9 +31,13 @@ * M20: List SD card to serial output */ void GcodeSuite::M20() { - SERIAL_ECHOLNPGM(STR_BEGIN_FILE_LIST); - card.ls(); - SERIAL_ECHOLNPGM(STR_END_FILE_LIST); + if (card.flag.mounted) { + SERIAL_ECHOLNPGM(STR_BEGIN_FILE_LIST); + card.ls(); + SERIAL_ECHOLNPGM(STR_END_FILE_LIST); + } + else + SERIAL_ECHO_MSG(STR_NO_MEDIA); } #endif // SDSUPPORT diff --git a/Marlin/src/gcode/sdcard/M21_M22.cpp b/Marlin/src/gcode/sd/M21_M22.cpp similarity index 87% rename from Marlin/src/gcode/sdcard/M21_M22.cpp rename to Marlin/src/gcode/sd/M21_M22.cpp index 2d5bccaf8438..a618bc0be31c 100644 --- a/Marlin/src/gcode/sdcard/M21_M22.cpp +++ b/Marlin/src/gcode/sd/M21_M22.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -35,6 +35,10 @@ void GcodeSuite::M21() { card.mount(); } /** * M22: Release SD Card */ -void GcodeSuite::M22() { card.release(); } +void GcodeSuite::M22() { + + if (!IS_SD_PRINTING()) card.release(); + +} #endif // SDSUPPORT diff --git a/Marlin/src/gcode/sdcard/M23.cpp b/Marlin/src/gcode/sd/M23.cpp similarity index 89% rename from Marlin/src/gcode/sdcard/M23.cpp rename to Marlin/src/gcode/sd/M23.cpp index 4bf8105f605d..b88f66b59162 100644 --- a/Marlin/src/gcode/sdcard/M23.cpp +++ b/Marlin/src/gcode/sd/M23.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -38,9 +38,7 @@ void GcodeSuite::M23() { for (char *fn = parser.string_arg; *fn; ++fn) if (*fn == ' ') *fn = '\0'; card.openFileRead(parser.string_arg); - #if ENABLED(LCD_SET_PROGRESS_MANUALLY) - ui.set_progress(0); - #endif + TERN_(LCD_SET_PROGRESS_MANUALLY, ui.set_progress(0)); } #endif // SDSUPPORT diff --git a/Marlin/src/gcode/sdcard/M24_M25.cpp b/Marlin/src/gcode/sd/M24_M25.cpp similarity index 78% rename from Marlin/src/gcode/sdcard/M24_M25.cpp rename to Marlin/src/gcode/sd/M24_M25.cpp index db1a671fe406..bdb37f605cbf 100644 --- a/Marlin/src/gcode/sdcard/M24_M25.cpp +++ b/Marlin/src/gcode/sd/M24_M25.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -31,7 +31,6 @@ #if ENABLED(PARK_HEAD_ON_PAUSE) #include "../../feature/pause.h" - #include "../queue.h" #endif #if ENABLED(HOST_ACTION_COMMANDS) @@ -39,7 +38,7 @@ #endif #if ENABLED(POWER_LOSS_RECOVERY) - #include "../../feature/power_loss_recovery.h" + #include "../../feature/powerloss.h" #endif #include "../../MarlinCore.h" // for startOrResumeJob @@ -64,18 +63,14 @@ void GcodeSuite::M24() { if (card.isFileOpen()) { card.startFileprint(); // SD card will now be read for commands startOrResumeJob(); // Start (or resume) the print job timer - #if ENABLED(POWER_LOSS_RECOVERY) - recovery.prepare(); - #endif + TERN_(POWER_LOSS_RECOVERY, recovery.prepare()); } #if ENABLED(HOST_ACTION_COMMANDS) #ifdef ACTION_ON_RESUME host_action_resume(); #endif - #if ENABLED(HOST_PROMPT_SUPPORT) - host_prompt_open(PROMPT_INFO, PSTR("Resuming SD"), DISMISS_STR); - #endif + TERN_(HOST_PROMPT_SUPPORT, host_prompt_open(PROMPT_INFO, PSTR("Resuming SD"), DISMISS_STR)); #endif ui.reset_status(); @@ -86,28 +81,29 @@ void GcodeSuite::M24() { */ void GcodeSuite::M25() { - // Set initial pause flag to prevent more commands from landing in the queue while we try to pause - #if ENABLED(SDSUPPORT) - if (IS_SD_PRINTING()) card.pauseSDPrint(); - #endif - #if ENABLED(PARK_HEAD_ON_PAUSE) M125(); #else + // Set initial pause flag to prevent more commands from landing in the queue while we try to pause + #if ENABLED(SDSUPPORT) + if (IS_SD_PRINTING()) card.pauseSDPrint(); + #endif + #if ENABLED(POWER_LOSS_RECOVERY) if (recovery.enabled) recovery.save(true); #endif print_job_timer.pause(); - ui.reset_status(); + + #if DISABLED(DWIN_CREALITY_LCD) + ui.reset_status(); + #endif #if ENABLED(HOST_ACTION_COMMANDS) - #if ENABLED(HOST_PROMPT_SUPPORT) - host_prompt_open(PROMPT_PAUSE_RESUME, PSTR("Pause SD"), PSTR("Resume")); - #endif + TERN_(HOST_PROMPT_SUPPORT, host_prompt_open(PROMPT_PAUSE_RESUME, PSTR("Pause SD"), PSTR("Resume"))); #ifdef ACTION_ON_PAUSE host_action_pause(); #endif diff --git a/Marlin/src/gcode/sdcard/M26.cpp b/Marlin/src/gcode/sd/M26.cpp similarity index 93% rename from Marlin/src/gcode/sdcard/M26.cpp rename to Marlin/src/gcode/sd/M26.cpp index d2e9e8e72a9d..e0557bfa14fa 100644 --- a/Marlin/src/gcode/sdcard/M26.cpp +++ b/Marlin/src/gcode/sd/M26.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/sdcard/M27.cpp b/Marlin/src/gcode/sd/M27.cpp similarity index 95% rename from Marlin/src/gcode/sdcard/M27.cpp rename to Marlin/src/gcode/sd/M27.cpp index 9c71e510a69e..8592b8af2582 100644 --- a/Marlin/src/gcode/sdcard/M27.cpp +++ b/Marlin/src/gcode/sd/M27.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/sdcard/M28_M29.cpp b/Marlin/src/gcode/sd/M28_M29.cpp similarity index 89% rename from Marlin/src/gcode/sdcard/M28_M29.cpp rename to Marlin/src/gcode/sd/M28_M29.cpp index 9dc192c09b26..6f3f2450a195 100644 --- a/Marlin/src/gcode/sdcard/M28_M29.cpp +++ b/Marlin/src/gcode/sd/M28_M29.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -27,7 +27,7 @@ #include "../gcode.h" #include "../../sd/cardreader.h" -#if NUM_SERIAL > 1 +#if HAS_MULTI_SERIAL #include "../queue.h" #endif @@ -49,9 +49,7 @@ void GcodeSuite::M28() { // Binary transfer mode if ((card.flag.binary_mode = binary_mode)) { SERIAL_ECHO_MSG("Switching to Binary Protocol"); - #if NUM_SERIAL > 1 - card.transfer_port_index = queue.port[queue.index_r]; - #endif + TERN_(HAS_MULTI_SERIAL, card.transfer_port_index = queue.port[queue.index_r]); } else card.openFileWrite(p); diff --git a/Marlin/src/gcode/sdcard/M30.cpp b/Marlin/src/gcode/sd/M30.cpp similarity index 93% rename from Marlin/src/gcode/sdcard/M30.cpp rename to Marlin/src/gcode/sd/M30.cpp index 2fd407341b30..b95a895f1e92 100644 --- a/Marlin/src/gcode/sdcard/M30.cpp +++ b/Marlin/src/gcode/sd/M30.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/sdcard/M32.cpp b/Marlin/src/gcode/sd/M32.cpp similarity index 95% rename from Marlin/src/gcode/sdcard/M32.cpp rename to Marlin/src/gcode/sd/M32.cpp index 35a6fb1d641b..55ec6ea49741 100644 --- a/Marlin/src/gcode/sdcard/M32.cpp +++ b/Marlin/src/gcode/sd/M32.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -38,7 +38,6 @@ * M32 !PATH/TO/FILE.GCO# ; Start FILE.GCO * M32 P !PATH/TO/FILE.GCO# ; Start FILE.GCO as a procedure * M32 S60 !PATH/TO/FILE.GCO# ; Start FILE.GCO at byte 60 - * */ void GcodeSuite::M32() { if (IS_SD_PRINTING()) planner.synchronize(); diff --git a/Marlin/src/gcode/sdcard/M33.cpp b/Marlin/src/gcode/sd/M33.cpp similarity index 94% rename from Marlin/src/gcode/sdcard/M33.cpp rename to Marlin/src/gcode/sd/M33.cpp index 7c6654a02e93..b611c8bc0863 100644 --- a/Marlin/src/gcode/sdcard/M33.cpp +++ b/Marlin/src/gcode/sd/M33.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/sdcard/M34.cpp b/Marlin/src/gcode/sd/M34.cpp similarity index 94% rename from Marlin/src/gcode/sdcard/M34.cpp rename to Marlin/src/gcode/sd/M34.cpp index ff1a8939a0f2..2dd7dc580c93 100644 --- a/Marlin/src/gcode/sdcard/M34.cpp +++ b/Marlin/src/gcode/sd/M34.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/sdcard/M524.cpp b/Marlin/src/gcode/sd/M524.cpp similarity index 89% rename from Marlin/src/gcode/sdcard/M524.cpp rename to Marlin/src/gcode/sd/M524.cpp index 401330361494..089d2e2f0c41 100644 --- a/Marlin/src/gcode/sdcard/M524.cpp +++ b/Marlin/src/gcode/sd/M524.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -34,6 +34,8 @@ void GcodeSuite::M524() { if (IS_SD_PRINTING()) card.flag.abort_sd_printing = true; + else if (card.isMounted()) + card.closefile(); } diff --git a/Marlin/src/gcode/sdcard/M928.cpp b/Marlin/src/gcode/sd/M928.cpp similarity index 93% rename from Marlin/src/gcode/sdcard/M928.cpp rename to Marlin/src/gcode/sd/M928.cpp index b8b9175f02d3..03a7877a90d0 100644 --- a/Marlin/src/gcode/sdcard/M928.cpp +++ b/Marlin/src/gcode/sd/M928.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/stats/M31.cpp b/Marlin/src/gcode/stats/M31.cpp index 019598cb8336..b39108bb903e 100644 --- a/Marlin/src/gcode/stats/M31.cpp +++ b/Marlin/src/gcode/stats/M31.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/stats/M75-M78.cpp b/Marlin/src/gcode/stats/M75-M78.cpp index 41d550cb59ac..908e6e5a31ee 100644 --- a/Marlin/src/gcode/stats/M75-M78.cpp +++ b/Marlin/src/gcode/stats/M75-M78.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/temperature/M104_M109.cpp b/Marlin/src/gcode/temp/M104_M109.cpp similarity index 59% rename from Marlin/src/gcode/temperature/M104_M109.cpp rename to Marlin/src/gcode/temp/M104_M109.cpp index ab99ea940ced..a289983b9294 100644 --- a/Marlin/src/gcode/temperature/M104_M109.cpp +++ b/Marlin/src/gcode/temp/M104_M109.cpp @@ -16,12 +16,12 @@ * 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 . + * along with this program. If not, see . * */ /** - * gcode/temperature/M104_M109.cpp + * gcode/temp/M104_M109.cpp * * Hotend target temperature control */ @@ -50,7 +50,12 @@ #endif /** - * M104: Set hot end temperature + * M104: Set Hotend Temperature target and return immediately + * + * Parameters: + * I : Material Preset index (if material presets are defined) + * T : Tool index. If omitted, applies to the active tool + * S : The target temperature in current units */ void GcodeSuite::M104() { @@ -63,9 +68,26 @@ void GcodeSuite::M104() { if (target_extruder < 0) return; #endif - if (parser.seenval('S')) { - const int16_t temp = parser.value_celsius(); - #if ENABLED(SINGLENOZZLE) + bool got_temp = false; + int16_t temp = 0; + + // Accept 'I' if temperature presets are defined + #if PREHEAT_COUNT + got_temp = parser.seenval('I'); + if (got_temp) { + const uint8_t index = parser.value_byte(); + temp = ui.material_preset[_MIN(index, PREHEAT_COUNT - 1)].hotend_temp; + } + #endif + + // If no 'I' get the temperature from 'S' + if (!got_temp) { + got_temp = parser.seenval('S'); + if (got_temp) temp = parser.value_celsius(); + } + + if (got_temp) { + #if ENABLED(SINGLENOZZLE_STANDBY_TEMP) singlenozzle_temp[target_extruder] = temp; if (target_extruder != active_extruder) return; #endif @@ -87,16 +109,29 @@ void GcodeSuite::M104() { #endif } - #if ENABLED(AUTOTEMP) - planner.autotemp_M104_M109(); - #endif + TERN_(AUTOTEMP, planner.autotemp_M104_M109()); } /** - * M109: Sxxx Wait for hotend(s) to reach temperature. Waits only when heating. - * Rxxx Wait for hotend(s) to reach temperature. Waits when heating and cooling. + * M109: Set Hotend Temperature target and wait + * + * Parameters + * I : Material Preset index (if material presets are defined) + * T : Tool index. If omitted, applies to the active tool + * S : The target temperature in current units. Wait for heating only. + * R : The target temperature in current units. Wait for heating and cooling. * - * With PRINTJOB_TIMER_AUTOSTART also start the job timer on heating and stop it if turned off. + * With AUTOTEMP... + * F : Autotemp Scaling Factor. Set non-zero to enable Auto-temp. + * S : Minimum temperature, in current units. + * B : Maximum temperature, in current units. + * + * Examples + * M109 S100 : Set target to 100°. Wait until the hotend is at or above 100°. + * M109 R150 : Set target to 150°. Wait until the hotend gets close to 150°. + * + * With PRINTJOB_TIMER_AUTOSTART turning on heaters will start the print job timer + * (used by printingIsActive, etc.) and turning off heaters will stop the timer. */ void GcodeSuite::M109() { @@ -109,11 +144,28 @@ void GcodeSuite::M109() { if (target_extruder < 0) return; #endif - const bool no_wait_for_cooling = parser.seenval('S'), - set_temp = no_wait_for_cooling || parser.seenval('R'); - if (set_temp) { - const int16_t temp = parser.value_celsius(); - #if ENABLED(SINGLENOZZLE) + bool got_temp = false; + int16_t temp = 0; + + // Accept 'I' if temperature presets are defined + #if PREHEAT_COUNT + got_temp = parser.seenval('I'); + if (got_temp) { + const uint8_t index = parser.value_byte(); + temp = ui.material_preset[_MIN(index, PREHEAT_COUNT - 1)].hotend_temp; + } + #endif + + // Get the temperature from 'S' or 'R' + bool no_wait_for_cooling = false; + if (!got_temp) { + no_wait_for_cooling = parser.seenval('S'); + got_temp = no_wait_for_cooling || parser.seenval('R'); + if (got_temp) temp = int16_t(parser.value_celsius()); + } + + if (got_temp) { + #if ENABLED(SINGLENOZZLE_STANDBY_TEMP) singlenozzle_temp[target_extruder] = temp; if (target_extruder != active_extruder) return; #endif @@ -139,11 +191,9 @@ void GcodeSuite::M109() { #endif } - #if ENABLED(AUTOTEMP) - planner.autotemp_M104_M109(); - #endif + TERN_(AUTOTEMP, planner.autotemp_M104_M109()); - if (set_temp) + if (got_temp) (void)thermalManager.wait_for_hotend(target_extruder, no_wait_for_cooling); } diff --git a/Marlin/src/gcode/temperature/M105.cpp b/Marlin/src/gcode/temp/M105.cpp similarity index 94% rename from Marlin/src/gcode/temperature/M105.cpp rename to Marlin/src/gcode/temp/M105.cpp index 7d68ccadc0f1..eefc3ae9f17f 100644 --- a/Marlin/src/gcode/temperature/M105.cpp +++ b/Marlin/src/gcode/temp/M105.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/temperature/M106_M107.cpp b/Marlin/src/gcode/temp/M106_M107.cpp similarity index 64% rename from Marlin/src/gcode/temperature/M106_M107.cpp rename to Marlin/src/gcode/temp/M106_M107.cpp index 2415484d5135..17ff8c3c8f60 100644 --- a/Marlin/src/gcode/temperature/M106_M107.cpp +++ b/Marlin/src/gcode/temp/M106_M107.cpp @@ -16,18 +16,22 @@ * 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 . + * along with this program. If not, see . * */ #include "../../inc/MarlinConfig.h" -#if FAN_COUNT > 0 +#if HAS_FAN #include "../gcode.h" #include "../../module/motion.h" #include "../../module/temperature.h" +#if PREHEAT_COUNT + #include "../../lcd/ultralcd.h" +#endif + #if ENABLED(SINGLENOZZLE) #define _ALT_P active_extruder #define _CNT_P EXTRUDERS @@ -39,6 +43,7 @@ /** * M106: Set Fan Speed * + * I Material Preset index (if material presets are defined) * S Speed between 0-255 * P Fan index, if more than one fan * @@ -50,19 +55,32 @@ * 3-255 = Set the speed for use with T2 */ void GcodeSuite::M106() { - const uint8_t p = parser.byteval('P', _ALT_P); + const uint8_t pfan = parser.byteval('P', _ALT_P); - if (p < _CNT_P) { + if (pfan < _CNT_P) { #if ENABLED(EXTRA_FAN_SPEED) const uint16_t t = parser.intval('T'); - if (t > 0) return thermalManager.set_temp_fan_speed(p, t); + if (t > 0) return thermalManager.set_temp_fan_speed(pfan, t); + #endif + + const uint16_t dspeed = parser.seen('A') ? thermalManager.fan_speed[active_extruder] : 255; + + uint16_t speed = dspeed; + + // Accept 'I' if temperature presets are defined + #if PREHEAT_COUNT + const bool got_preset = parser.seenval('I'); + if (got_preset) speed = ui.material_preset[_MIN(parser.value_byte(), PREHEAT_COUNT - 1)].fan_speed; + #else + constexpr bool got_preset = false; #endif - uint16_t d = parser.seen('A') ? thermalManager.fan_speed[active_extruder] : 255; - uint16_t s = parser.ushortval('S', d); - NOMORE(s, 255U); - thermalManager.set_fan_speed(p, s); + if (!got_preset && parser.seenval('S')) + speed = parser.value_ushort(); + + // Set speed, with constraint + thermalManager.set_fan_speed(pfan, speed); } } @@ -74,4 +92,4 @@ void GcodeSuite::M107() { thermalManager.set_fan_speed(p, 0); } -#endif // FAN_COUNT > 0 +#endif // HAS_FAN diff --git a/Marlin/src/gcode/temp/M140_M190.cpp b/Marlin/src/gcode/temp/M140_M190.cpp new file mode 100644 index 000000000000..9438b9e0c23c --- /dev/null +++ b/Marlin/src/gcode/temp/M140_M190.cpp @@ -0,0 +1,138 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * gcode/temp/M140_M190.cpp + * + * Bed target temperature control + */ + +#include "../../inc/MarlinConfig.h" + +#if HAS_HEATED_BED + +#include "../gcode.h" +#include "../../module/temperature.h" +#include "../../module/motion.h" +#include "../../lcd/ultralcd.h" + +#if ENABLED(PRINTJOB_TIMER_AUTOSTART) + #include "../../module/printcounter.h" +#endif + +#if ENABLED(PRINTER_EVENT_LEDS) + #include "../../feature/leds/leds.h" +#endif + +#include "../../MarlinCore.h" // for wait_for_heatup, idle, startOrResumeJob + +/** + * M140: Set bed temperature + * + * I : Preset index (if material presets are defined) + * S : The target temperature in current units + */ +void GcodeSuite::M140() { + if (DEBUGGING(DRYRUN)) return; + + bool got_temp = false; + int16_t temp = 0; + + // Accept 'I' if temperature presets are defined + #if PREHEAT_COUNT + got_temp = parser.seenval('I'); + if (got_temp) { + const uint8_t index = parser.value_byte(); + temp = ui.material_preset[_MIN(index, PREHEAT_COUNT - 1)].bed_temp; + } + #endif + + // If no 'I' get the temperature from 'S' + if (!got_temp) { + got_temp = parser.seenval('S'); + if (got_temp) temp = parser.value_celsius(); + } + + if (got_temp) { + thermalManager.setTargetBed(temp); + + #if ENABLED(PRINTJOB_TIMER_AUTOSTART) + /** + * Stop the timer at the end of print. Hotend, bed target, and chamber + * temperatures need to be set below mintemp. Order of M140, M104, and M141 + * at the end of the print does not matter. + */ + thermalManager.check_timer_autostart(false, true); + #endif + } +} + +/** + * M190 - Set Bed Temperature target and wait + * + * Parameters: + * I : Preset index (if material presets are defined) + * S : The target temperature in current units. Wait for heating only. + * R : The target temperature in current units. Wait for heating and cooling. + * + * Examples: + * M190 S60 : Set target to 60°. Wait until the bed is at or above 60°. + * M190 R40 : Set target to 40°. Wait until the bed gets close to 40°. + * + * With PRINTJOB_TIMER_AUTOSTART turning on heaters will start the print job timer + * (used by printingIsActive, etc.) and turning off heaters will stop the timer. + */ +void GcodeSuite::M190() { + if (DEBUGGING(DRYRUN)) return; + + bool got_temp = false; + int16_t temp = 0; + + // Accept 'I' if temperature presets are defined + #if PREHEAT_COUNT + got_temp = parser.seenval('I'); + if (got_temp) { + const uint8_t index = parser.value_byte(); + temp = ui.material_preset[_MIN(index, PREHEAT_COUNT - 1)].bed_temp; + } + #endif + + // Get the temperature from 'S' or 'R' + bool no_wait_for_cooling = false; + if (!got_temp) { + no_wait_for_cooling = parser.seenval('S'); + got_temp = no_wait_for_cooling || parser.seenval('R'); + if (got_temp) temp = int16_t(parser.value_celsius()); + } + + if (!got_temp) return; + + thermalManager.setTargetBed(temp); + + TERN_(PRINTJOB_TIMER_AUTOSTART, thermalManager.check_timer_autostart(true, false)); + + ui.set_status_P(thermalManager.isHeatingBed() ? GET_TEXT(MSG_BED_HEATING) : GET_TEXT(MSG_BED_COOLING)); + + thermalManager.wait_for_bed(no_wait_for_cooling); +} + +#endif // HAS_HEATED_BED diff --git a/Marlin/src/gcode/temperature/M141_M191.cpp b/Marlin/src/gcode/temp/M141_M191.cpp similarity index 79% rename from Marlin/src/gcode/temperature/M141_M191.cpp rename to Marlin/src/gcode/temp/M141_M191.cpp index 66849b99e6be..41a79825aa3b 100644 --- a/Marlin/src/gcode/temperature/M141_M191.cpp +++ b/Marlin/src/gcode/temp/M141_M191.cpp @@ -16,12 +16,12 @@ * 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 . + * along with this program. If not, see . * */ /** - * gcode/temperature/M141_M191.cpp + * gcode/temp/M141_M191.cpp * * Chamber target temperature control */ @@ -51,7 +51,18 @@ */ void GcodeSuite::M141() { if (DEBUGGING(DRYRUN)) return; - if (parser.seenval('S')) thermalManager.setTargetChamber(parser.value_celsius()); + if (parser.seenval('S')) { + thermalManager.setTargetChamber(parser.value_celsius()); + + #if ENABLED(PRINTJOB_TIMER_AUTOSTART) + /** + * Stop the timer at the end of print. Hotend, bed target, and chamber + * temperatures need to be set below mintemp. Order of M140, M104, and M141 + * at the end of the print does not matter. + */ + thermalManager.check_timer_autostart(false, true); + #endif + } } /** @@ -64,9 +75,7 @@ void GcodeSuite::M191() { const bool no_wait_for_cooling = parser.seenval('S'); if (no_wait_for_cooling || parser.seenval('R')) { thermalManager.setTargetChamber(parser.value_celsius()); - #if ENABLED(PRINTJOB_TIMER_AUTOSTART) - thermalManager.check_timer_autostart(true, false); - #endif + TERN_(PRINTJOB_TIMER_AUTOSTART, thermalManager.check_timer_autostart(true, false)); } else return; diff --git a/Marlin/src/gcode/temperature/M155.cpp b/Marlin/src/gcode/temp/M155.cpp similarity index 89% rename from Marlin/src/gcode/temperature/M155.cpp rename to Marlin/src/gcode/temp/M155.cpp index 52f9ef2be50a..30129a0e6ff7 100644 --- a/Marlin/src/gcode/temperature/M155.cpp +++ b/Marlin/src/gcode/temp/M155.cpp @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #include "../../inc/MarlinConfig.h" -#if ENABLED(AUTO_REPORT_TEMPERATURES) && HAS_TEMP_SENSOR +#if BOTH(AUTO_REPORT_TEMPERATURES, HAS_TEMP_SENSOR) #include "../gcode.h" #include "../../module/temperature.h" diff --git a/Marlin/src/gcode/temperature/M303.cpp b/Marlin/src/gcode/temp/M303.cpp similarity index 52% rename from Marlin/src/gcode/temperature/M303.cpp rename to Marlin/src/gcode/temp/M303.cpp index 31f7bf350117..ccce09b4f1ee 100644 --- a/Marlin/src/gcode/temperature/M303.cpp +++ b/Marlin/src/gcode/temp/M303.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -25,49 +25,61 @@ #if HAS_PID_HEATING #include "../gcode.h" +#include "../../lcd/ultralcd.h" #include "../../module/temperature.h" #if ENABLED(EXTENSIBLE_UI) - #include "../../lcd/extensible_ui/ui_api.h" + #include "../../lcd/extui/ui_api.h" #endif /** * M303: PID relay autotune * - * S sets the target temperature. (default 150C / 70C) - * E (-1 for the bed) (default 0) - * C Minimum 3. Default 5. - * U with a non-zero value will apply the result to current settings + * S Set the target temperature. (Default: 150C / 70C) + * E Extruder number to tune, or -1 for the bed. (Default: E0) + * C Number of times to repeat the procedure. (Minimum: 3, Default: 5) + * U Flag to apply the result to the current PID values + * + * With PID_DEBUG: + * D Toggle PID debugging and EXIT without further action. */ + +#if ENABLED(PID_DEBUG) + bool pid_debug_flag = 0; +#endif + void GcodeSuite::M303() { - #if ENABLED(PIDTEMPBED) - #define SI H_BED - #else - #define SI H_E0 - #endif - #if ENABLED(PIDTEMP) - #define EI HOTENDS - 1 - #else - #define EI H_BED + + #if ENABLED(PID_DEBUG) + if (parser.seen('D')) { + pid_debug_flag = !pid_debug_flag; + SERIAL_ECHO_START(); + SERIAL_ECHOPGM("PID Debug "); + serialprintln_onoff(pid_debug_flag); + return; + } #endif - const heater_ind_t e = (heater_ind_t)parser.intval('E'); + + #define SI TERN(PIDTEMPBED, H_BED, H_E0) + #define EI TERN(PIDTEMP, HOTENDS - 1, H_BED) + const heater_id_t e = (heater_id_t)parser.intval('E'); if (!WITHIN(e, SI, EI)) { SERIAL_ECHOLNPGM(STR_PID_BAD_EXTRUDER_NUM); - #if ENABLED(EXTENSIBLE_UI) - ExtUI::OnPidTuning(ExtUI::result_t::PID_BAD_EXTRUDER_NUM); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_BAD_EXTRUDER_NUM)); return; } const int c = parser.intval('C', 5); const bool u = parser.boolval('U'); - const int16_t temp = parser.celsiusval('S', e < 0 ? 70 : 150); + const int16_t temp = parser.celsiusval('S', e < 0 ? PREHEAT_1_TEMP_BED : PREHEAT_1_TEMP_HOTEND); #if DISABLED(BUSY_WHILE_HEATING) KEEPALIVE_STATE(NOT_BUSY); #endif + ui.set_status(GET_TEXT(MSG_PID_AUTOTUNE)); thermalManager.PID_autotune(temp, e, c, u); + ui.reset_status(); } #endif // HAS_PID_HEATING diff --git a/Marlin/src/gcode/temperature/M140_M190.cpp b/Marlin/src/gcode/temperature/M140_M190.cpp deleted file mode 100644 index ad7608705a34..000000000000 --- a/Marlin/src/gcode/temperature/M140_M190.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * gcode/temperature/M140_M190.cpp - * - * Bed target temperature control - */ - -#include "../../inc/MarlinConfig.h" - -#if HAS_HEATED_BED - -#include "../gcode.h" -#include "../../module/temperature.h" -#include "../../module/motion.h" -#include "../../lcd/ultralcd.h" - -#if ENABLED(PRINTJOB_TIMER_AUTOSTART) - #include "../../module/printcounter.h" -#endif - -#if ENABLED(PRINTER_EVENT_LEDS) - #include "../../feature/leds/leds.h" -#endif - -#include "../../MarlinCore.h" // for wait_for_heatup, idle, startOrResumeJob - -/** - * M140: Set bed temperature - */ -void GcodeSuite::M140() { - if (DEBUGGING(DRYRUN)) return; - if (parser.seenval('S')) thermalManager.setTargetBed(parser.value_celsius()); - - #if ENABLED(PRINTJOB_TIMER_AUTOSTART) - /** - * Stop the timer at the end of print. Both hotend and bed target - * temperatures need to be set below mintemp. Order of M140 and M104 - * at the end of the print does not matter. - */ - thermalManager.check_timer_autostart(false, true); - #endif -} - -/** - * M190: Sxxx Wait for bed current temp to reach target temp. Waits only when heating - * Rxxx Wait for bed current temp to reach target temp. Waits when heating and cooling - * - * With PRINTJOB_TIMER_AUTOSTART also start the job timer on heating. - */ -void GcodeSuite::M190() { - if (DEBUGGING(DRYRUN)) return; - - const bool no_wait_for_cooling = parser.seenval('S'); - if (no_wait_for_cooling || parser.seenval('R')) { - thermalManager.setTargetBed(parser.value_celsius()); - #if ENABLED(PRINTJOB_TIMER_AUTOSTART) - thermalManager.check_timer_autostart(true, false); - #endif - } - else return; - - ui.set_status_P(thermalManager.isHeatingBed() ? GET_TEXT(MSG_BED_HEATING) : GET_TEXT(MSG_BED_COOLING)); - - thermalManager.wait_for_bed(no_wait_for_cooling); -} - -#endif // HAS_HEATED_BED diff --git a/Marlin/src/gcode/units/G20_G21.cpp b/Marlin/src/gcode/units/G20_G21.cpp index 4961ae160148..6f1d5adbccbd 100644 --- a/Marlin/src/gcode/units/G20_G21.cpp +++ b/Marlin/src/gcode/units/G20_G21.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/units/M149.cpp b/Marlin/src/gcode/units/M149.cpp index d8d962c5be35..5d9f83206980 100644 --- a/Marlin/src/gcode/units/M149.cpp +++ b/Marlin/src/gcode/units/M149.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/gcode/units/M82_M83.cpp b/Marlin/src/gcode/units/M82_M83.cpp index bf5aff0b8526..d93f0ea5adf3 100644 --- a/Marlin/src/gcode/units/M82_M83.cpp +++ b/Marlin/src/gcode/units/M82_M83.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h index 9227f2c81a0e..45921f7be3b0 100644 --- a/Marlin/src/inc/Conditionals_LCD.h +++ b/Marlin/src/inc/Conditionals_LCD.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -26,10 +26,49 @@ * Conditionals that need to be set before Configuration_adv.h or pins.h */ -#if ENABLED(CARTESIO_UI) +// Kinematics +#if ENABLED(MORGAN_SCARA) + #define IS_SCARA 1 + #define IS_KINEMATIC 1 +#elif ENABLED(DELTA) + #define IS_KINEMATIC 1 +#else + #define IS_CARTESIAN 1 +#endif + +// MKS_LCD12864 is a variant of MKS_MINI_12864 +#if ENABLED(MKS_LCD12864) + #define MKS_MINI_12864 +#endif + +/** + * General Flags that may be set below by specific LCDs + * + * DOGLCD : Run a Graphical LCD through U8GLib (with MarlinUI) + * IS_ULTIPANEL : Define LCD_PINS_D5/6/7 for direct-connected "Ultipanel" LCDs + * IS_ULTRA_LCD : Ultra LCD, not necessarily Ultipanel. Used most often with NEWPANEL. + * IS_RRD_SC : Common RRD Smart Controller digital interface pins + * IS_RRD_FG_SC : Common RRD Full Graphical Smart Controller digital interface pins + * U8GLIB_ST7920 : Most common DOGM display SPI interface, supporting a "lightweight" display mode. + * U8GLIB_SH1106 : SH1106 OLED with I2C interface via U8GLib + * IS_U8GLIB_SSD1306 : SSD1306 OLED with I2C interface via U8GLib + * U8GLIB_SSD1309 : SSD1309 OLED with I2C interface via U8GLib + * U8GLIB_ST7565_64128N : ST7565 128x64 LCD with SPI interface via U8GLib + * U8GLIB_LM6059_AF : LM6059 with Hardware SPI via U8GLib + */ +#if EITHER(MKS_MINI_12864, ENDER2_STOCKDISPLAY) + + #define MINIPANEL + +#elif ENABLED(CARTESIO_UI) #define DOGLCD - #define IS_ULTIPANEL + #define IS_ULTIPANEL 1 + +#elif EITHER(DWIN_MARLINUI_PORTRAIT, DWIN_MARLINUI_LANDSCAPE) + + #define IS_DWIN_MARLINUI 1 + #define IS_ULTIPANEL 1 #elif ENABLED(ZONESTAR_LCD) @@ -37,7 +76,7 @@ #define IS_RRW_KEYPAD #define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0 #define ADC_KEY_NUM 8 - #define IS_ULTIPANEL + #define IS_ULTIPANEL 1 // This helps to implement ADC_KEYPAD menus #define REVERSE_MENU_DIRECTION @@ -45,8 +84,21 @@ #define ENCODER_STEPS_PER_MENU_ITEM 1 #define ENCODER_FEEDRATE_DEADZONE 2 +#elif ENABLED(ZONESTAR_12864LCD) + #define DOGLCD + #define IS_RRD_SC + #define U8GLIB_ST7920 + +#elif ENABLED(ZONESTAR_12864OLED) + #define IS_RRD_SC + #define U8GLIB_SH1106 + +#elif ENABLED(ZONESTAR_12864OLED_SSD1306) + #define IS_RRD_SC + #define IS_U8GLIB_SSD1306 + #elif ENABLED(RADDS_DISPLAY) - #define IS_ULTIPANEL + #define IS_ULTIPANEL 1 #define ENCODER_PULSES_PER_STEP 2 #elif EITHER(ANET_FULL_GRAPHICS_LCD, BQ_LCD_SMART_CONTROLLER) @@ -55,9 +107,8 @@ #elif ANY(miniVIKI, VIKI2, ELB_FULL_GRAPHIC_CONTROLLER, AZSMZ_12864) - #define IS_ULTRA_LCD #define DOGLCD - #define IS_ULTIPANEL + #define IS_ULTIPANEL 1 #if ENABLED(miniVIKI) #define U8GLIB_ST7565_64128N @@ -65,7 +116,6 @@ #define U8GLIB_ST7565_64128N #elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) #define U8GLIB_LM6059_AF - #define SD_DETECT_INVERTED #elif ENABLED(AZSMZ_12864) #define U8GLIB_ST7565_64128N #endif @@ -73,32 +123,26 @@ #elif ENABLED(OLED_PANEL_TINYBOY2) #define IS_U8GLIB_SSD1306 - #define IS_ULTIPANEL + #define IS_ULTIPANEL 1 #elif ENABLED(RA_CONTROL_PANEL) #define LCD_I2C_TYPE_PCA8574 #define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander - #define IS_ULTIPANEL + #define IS_ULTIPANEL 1 #elif ENABLED(REPRAPWORLD_GRAPHICAL_LCD) #define DOGLCD #define U8GLIB_ST7920 - #define IS_ULTIPANEL + #define IS_ULTIPANEL 1 #elif ENABLED(CR10_STOCKDISPLAY) #define IS_RRD_FG_SC - #ifndef ST7920_DELAY_1 - #define ST7920_DELAY_1 DELAY_NS(125) - #endif - #ifndef ST7920_DELAY_2 - #define ST7920_DELAY_2 DELAY_NS(125) - #endif - #ifndef ST7920_DELAY_3 - #define ST7920_DELAY_3 DELAY_NS(125) - #endif + #define BOARD_ST7920_DELAY_1 DELAY_NS(125) + #define BOARD_ST7920_DELAY_2 DELAY_NS(125) + #define BOARD_ST7920_DELAY_3 DELAY_NS(125) #elif ENABLED(MKS_12864OLED) @@ -110,15 +154,32 @@ #define IS_RRD_SC #define IS_U8GLIB_SSD1306 -#elif EITHER(MKS_MINI_12864, ENDER2_STOCKDISPLAY) +#elif ENABLED(FYSETC_242_OLED_12864) - #define MINIPANEL + #define IS_RRD_SC + #define U8GLIB_SH1106 + + #define LED_CONTROL_MENU + #define NEOPIXEL_LED + #undef NEOPIXEL_TYPE + #define NEOPIXEL_TYPE NEO_RGB + #if NEOPIXEL_PIXELS < 3 + #undef NEOPIXELS_PIXELS + #define NEOPIXEL_PIXELS 3 + #endif + #ifndef NEOPIXEL_BRIGHTNESS + #define NEOPIXEL_BRIGHTNESS 127 + #endif + + #if ENABLED(PSU_CONTROL) + #define LED_BACKLIGHT_TIMEOUT 10000 + #endif #elif ANY(FYSETC_MINI_12864_X_X, FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0, FYSETC_MINI_12864_2_1, FYSETC_GENERIC_12864_1_1) #define FYSETC_MINI_12864 #define DOGLCD - #define IS_ULTIPANEL + #define IS_ULTIPANEL 1 #define LED_COLORS_REDUCE_GREEN #if ENABLED(PSU_CONTROL) && EITHER(FYSETC_MINI_12864_2_0, FYSETC_MINI_12864_2_1) #define LED_BACKLIGHT_TIMEOUT 10000 @@ -144,7 +205,7 @@ #elif ENABLED(ULTI_CONTROLLER) - #define IS_ULTIPANEL + #define IS_ULTIPANEL 1 #define U8GLIB_SSD1309 #define LCD_RESET_PIN LCD_PINS_D6 // This controller need a reset pin #define ENCODER_PULSES_PER_STEP 2 @@ -156,6 +217,28 @@ #define LCD_WIDTH 16 #define LCD_HEIGHT 2 +#elif EITHER(TFTGLCD_PANEL_SPI, TFTGLCD_PANEL_I2C) + + #define IS_TFTGLCD_PANEL 1 + #define IS_ULTIPANEL 1 // Note that IS_ULTIPANEL leads to HAS_WIRED_LCD + + #if ENABLED(SDSUPPORT) && DISABLED(LCD_PROGRESS_BAR) + #define LCD_PROGRESS_BAR + #endif + #if ENABLED(TFTGLCD_PANEL_I2C) + #define LCD_I2C_ADDRESS 0x27 // Must be equal to panel's I2C slave addres + #endif + #define LCD_USE_I2C_BUZZER // Enable buzzer on LCD, used for both I2C and SPI buses (LiquidTWI2 not required) + #define STD_ENCODER_PULSES_PER_STEP 2 + #define STD_ENCODER_STEPS_PER_MENU_ITEM 1 + #define LCD_WIDTH 20 // 20 or 24 chars in line + #define LCD_HEIGHT 10 // Character lines + #define LCD_CONTRAST_MIN 127 + #define LCD_CONTRAST_MAX 255 + #define DEFAULT_LCD_CONTRAST 250 + #define CONVERT_TO_EXT_ASCII // Use extended 128-255 symbols from ASCII table. + // At this time present conversion only for cyrillic - bg, ru and uk languages. + // First 7 ASCII symbols in panel font must be replaced with Marlin's special symbols. #endif #if ENABLED(IS_RRD_FG_SC) @@ -163,7 +246,7 @@ #endif #if EITHER(MAKRPANEL, MINIPANEL) - #define IS_ULTIPANEL + #define IS_ULTIPANEL 1 #define DOGLCD #if ENABLED(MAKRPANEL) #define U8GLIB_ST7565_64128N @@ -175,7 +258,7 @@ #endif #if ENABLED(OVERLORD_OLED) - #define IS_ULTIPANEL + #define IS_ULTIPANEL 1 #define U8GLIB_SH1106 /** * PCA9632 for buzzer and LEDs via i2c @@ -193,8 +276,10 @@ #endif // 128x64 I2C OLED LCDs - SSD1306/SSD1309/SH1106 -#define HAS_SSD1306_OLED_I2C ANY(U8GLIB_SSD1306, U8GLIB_SSD1309, U8GLIB_SH1106) -#if HAS_SSD1306_OLED_I2C +#if ANY(U8GLIB_SSD1306, U8GLIB_SSD1309, U8GLIB_SH1106) + #define HAS_U8GLIB_I2C_OLED 1 +#endif +#if HAS_U8GLIB_I2C_OLED #define IS_ULTRA_LCD #define DOGLCD #endif @@ -217,22 +302,66 @@ // Basic Ultipanel-like displays #if ANY(ULTIMAKERCONTROLLER, REPRAP_DISCOUNT_SMART_CONTROLLER, G3D_PANEL, RIGIDBOT_PANEL, PANEL_ONE, U8GLIB_SH1106) - #define IS_ULTIPANEL + #define IS_ULTIPANEL 1 #endif // Einstart OLED has Cardinal nav via pins defined in pins_EINSTART-S.h #if ENABLED(U8GLIB_SH1106_EINSTART) #define DOGLCD - #define IS_ULTIPANEL + #define IS_ULTIPANEL 1 #endif -// FSMC/SPI TFT Panels +// Compatibility #if ENABLED(FSMC_GRAPHICAL_TFT) + #define TFT_CLASSIC_UI + #define TFT_INTERFACE_FSMC + #define TFT_GENERIC +#elif ENABLED(SPI_GRAPHICAL_TFT) + #define TFT_CLASSIC_UI + #define TFT_INTERFACE_SPI + #define TFT_GENERIC +#elif EITHER(TFT_320x240, TFT_480x320) + #define TFT_COLOR_UI + #define TFT_INTERFACE_FSMC + #define TFT_GENERIC +#elif EITHER(TFT_320x240_SPI, TFT_480x320_SPI) + #define TFT_COLOR_UI + #define TFT_INTERFACE_SPI + #define TFT_GENERIC +#elif ENABLED(TFT_LVGL_UI_FSMC) + #define TFT_LVGL_UI + #define TFT_INTERFACE_FSMC + #define TFT_GENERIC +#elif ENABLED(TFT_LVGL_UI_SPI) + #define TFT_LVGL_UI + #define TFT_INTERFACE_SPI + #define TFT_GENERIC +#endif + +// FSMC/SPI TFT Panels (LVGL) +#if ENABLED(TFT_LVGL_UI) + #define HAS_TFT_LVGL_UI 1 +#endif + +// FSMC/SPI TFT Panels +#if ENABLED(TFT_CLASSIC_UI) + #define TFT_SCALED_DOGLCD 1 +#endif + +#if TFT_SCALED_DOGLCD #define DOGLCD - #define IS_ULTIPANEL + #define IS_ULTIPANEL 1 + #define DELAYED_BACKLIGHT_INIT +#elif ENABLED(TFT_LVGL_UI) #define DELAYED_BACKLIGHT_INIT #endif +// Color UI +#if ENABLED(TFT_COLOR_UI) + #define HAS_GRAPHICAL_TFT 1 + #define IS_ULTIPANEL 1 +#endif + /** * I2C Panels */ @@ -254,7 +383,7 @@ #define LCD_I2C_TYPE_MCP23017 #define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander #define LCD_USE_I2C_BUZZER // Enable buzzer on LCD (optional) - #define IS_ULTIPANEL + #define IS_ULTIPANEL 1 #elif ENABLED(LCD_I2C_VIKI) @@ -269,7 +398,7 @@ #define LCD_I2C_TYPE_MCP23017 #define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander #define LCD_USE_I2C_BUZZER // Enable buzzer on LCD (requires LiquidTWI2 v1.2.3 or later) - #define IS_ULTIPANEL + #define IS_ULTIPANEL 1 #define ENCODER_FEEDRATE_DEADZONE 4 @@ -289,7 +418,7 @@ #endif #ifndef STD_ENCODER_PULSES_PER_STEP - #if ENABLED(TOUCH_BUTTONS) + #if ENABLED(TOUCH_SCREEN) #define STD_ENCODER_PULSES_PER_STEP 2 #else #define STD_ENCODER_PULSES_PER_STEP 5 @@ -314,10 +443,10 @@ // https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection #if ENABLED(FF_INTERFACEBOARD) #define SR_LCD_3W_NL // Non latching 3 wire shift register - #define IS_ULTIPANEL + #define IS_ULTIPANEL 1 #elif ENABLED(SAV_3DLCD) #define SR_LCD_2W_NL // Non latching 2 wire shift register - #define IS_ULTIPANEL + #define IS_ULTIPANEL 1 #endif #if ENABLED(IS_ULTIPANEL) @@ -325,11 +454,8 @@ #endif #if ENABLED(ULTIPANEL) #define IS_ULTRA_LCD - #ifndef NEWPANEL - #define NEWPANEL - #endif + #define NEWPANEL #endif - #if ENABLED(IS_ULTRA_LCD) #define ULTRA_LCD #endif @@ -346,22 +472,41 @@ #endif #endif -// Extensible UI serial touch screens. (See src/lcd/extensible_ui) -#if ANY(MALYAN_LCD, DGUS_LCD, TOUCH_UI_FTDI_EVE) +// Aliases for LCD features +#if ANY(DGUS_LCD_UI_ORIGIN, DGUS_LCD_UI_FYSETC, DGUS_LCD_UI_HIPRECY) + #define HAS_DGUS_LCD 1 +#endif + +// Extensible UI serial touch screens. (See src/lcd/extui) +#if ANY(HAS_DGUS_LCD, MALYAN_LCD, TOUCH_UI_FTDI_EVE, ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON) #define IS_EXTUI #define EXTENSIBLE_UI #endif // Aliases for LCD features -#define HAS_SPI_LCD ENABLED(ULTRA_LCD) -#define HAS_DISPLAY (HAS_SPI_LCD || ENABLED(EXTENSIBLE_UI)) -#define HAS_GRAPHICAL_LCD ENABLED(DOGLCD) -#define HAS_CHARACTER_LCD (HAS_SPI_LCD && !HAS_GRAPHICAL_LCD) -#define HAS_LCD_MENU (ENABLED(ULTIPANEL) && DISABLED(NO_LCD_MENUS)) -#define HAS_ADC_BUTTONS ENABLED(ADC_KEYPAD) -#define HAS_DGUS_LCD ANY(DGUS_LCD_UI_ORIGIN, DGUS_LCD_UI_FYSETC, DGUS_LCD_UI_HIPRECY) - -#if HAS_GRAPHICAL_LCD +#if EITHER(ULTRA_LCD, EXTENSIBLE_UI) + #define HAS_DISPLAY 1 +#endif + +#if ENABLED(ULTRA_LCD) + #define HAS_WIRED_LCD 1 + #if ENABLED(DOGLCD) + #define HAS_MARLINUI_U8GLIB 1 + #elif IS_TFTGLCD_PANEL + // Neither DOGM nor HD44780. Fully customized interface. + #elif DISABLED(HAS_GRAPHICAL_TFT) + #define HAS_MARLINUI_HD44780 1 + #endif +#endif + +#if ENABLED(ULTIPANEL) && DISABLED(NO_LCD_MENUS) + #define HAS_LCD_MENU 1 +#endif +#if ENABLED(ADC_KEYPAD) + #define HAS_ADC_BUTTONS 1 +#endif + +#if HAS_MARLINUI_U8GLIB #ifndef LCD_PIXEL_WIDTH #define LCD_PIXEL_WIDTH 128 #endif @@ -378,17 +523,20 @@ * HOTENDS - Number of hotends, whether connected or separate * E_STEPPERS - Number of actual E stepper motors * E_MANUAL - Number of E steppers for LCD move options - * */ #if EXTRUDERS == 0 - #undef DISTINCT_E_FACTORS + #undef EXTRUDERS + #define EXTRUDERS 0 #undef SINGLENOZZLE #undef SWITCHING_EXTRUDER #undef SWITCHING_NOZZLE #undef MIXING_EXTRUDER #undef MK2_MULTIPLEXER #undef PRUSA_MMU2 + #undef HOTEND_IDLE_TIMEOUT +#elif EXTRUDERS > 1 + #define HAS_MULTI_EXTRUDER 1 #endif #if ENABLED(SWITCHING_EXTRUDER) // One stepper for every two EXTRUDERS @@ -405,7 +553,9 @@ #elif ENABLED(MIXING_EXTRUDER) #define E_STEPPERS MIXING_STEPPERS #define E_MANUAL 1 - #define DUAL_MIXING_EXTRUDER (MIXING_STEPPERS == 2) + #if MIXING_STEPPERS == 2 + #define HAS_DUAL_MIXING 1 + #endif #elif ENABLED(SWITCHING_TOOLHEAD) #define E_STEPPERS EXTRUDERS #define E_MANUAL EXTRUDERS @@ -418,7 +568,7 @@ #undef DISABLE_INACTIVE_EXTRUDER #endif -// Prusa MK2 Multiplexer and MMU 2.0 force SINGLENOZZLE +// Průša MK2 Multiplexer and MMU 2.0 force SINGLENOZZLE #if EITHER(MK2_MULTIPLEXER, PRUSA_MMU2) #define SINGLENOZZLE #endif @@ -433,37 +583,79 @@ #ifndef HOTENDS #define HOTENDS EXTRUDERS #endif - #ifndef E_STEPPERS #define E_STEPPERS EXTRUDERS #endif - #ifndef E_MANUAL #define E_MANUAL EXTRUDERS #endif +#if HOTENDS + #define HAS_HOTEND 1 + #ifndef HOTEND_OVERSHOOT + #define HOTEND_OVERSHOOT 15 + #endif + #if HOTENDS > 1 + #define HAS_MULTI_HOTEND 1 + #define HAS_HOTEND_OFFSET 1 + #endif +#else + #undef PID_PARAMS_PER_HOTEND +#endif + +// Helper macros for extruder and hotend arrays #define HOTEND_LOOP() for (int8_t e = 0; e < HOTENDS; e++) +#define ARRAY_BY_EXTRUDERS(V...) ARRAY_N(EXTRUDERS, V) +#define ARRAY_BY_EXTRUDERS1(v1) ARRAY_BY_EXTRUDERS(v1, v1, v1, v1, v1, v1, v1, v1) +#define ARRAY_BY_HOTENDS(V...) ARRAY_N(HOTENDS, V) +#define ARRAY_BY_HOTENDS1(v1) ARRAY_BY_HOTENDS(v1, v1, v1, v1, v1, v1, v1, v1) -#define DO_SWITCH_EXTRUDER (ENABLED(SWITCHING_EXTRUDER) && (DISABLED(SWITCHING_NOZZLE) || SWITCHING_EXTRUDER_SERVO_NR != SWITCHING_NOZZLE_SERVO_NR)) -#define SWITCHING_NOZZLE_TWO_SERVOS defined(SWITCHING_NOZZLE_E1_SERVO_NR) +#if ENABLED(SWITCHING_EXTRUDER) && (DISABLED(SWITCHING_NOZZLE) || SWITCHING_EXTRUDER_SERVO_NR != SWITCHING_NOZZLE_SERVO_NR) + #define DO_SWITCH_EXTRUDER 1 +#endif -#define HAS_HOTEND_OFFSET (HOTENDS > 1) -#define HAS_DUPLICATION_MODE EITHER(DUAL_X_CARRIAGE, MULTI_NOZZLE_DUPLICATION) +/** + * Default hotend offsets, if not defined + */ +#if HAS_HOTEND_OFFSET + #ifndef HOTEND_OFFSET_X + #define HOTEND_OFFSET_X { 0 } // X offsets for each extruder + #endif + #ifndef HOTEND_OFFSET_Y + #define HOTEND_OFFSET_Y { 0 } // Y offsets for each extruder + #endif + #ifndef HOTEND_OFFSET_Z + #define HOTEND_OFFSET_Z { 0 } // Z offsets for each extruder + #endif +#endif /** * DISTINCT_E_FACTORS affects how some E factors are accessed */ #if ENABLED(DISTINCT_E_FACTORS) && E_STEPPERS > 1 + #define DISTINCT_E E_STEPPERS #define XYZE_N (XYZ + E_STEPPERS) + #define E_INDEX_N(E) (E) #define E_AXIS_N(E) AxisEnum(E_AXIS + E) #define UNUSED_E(E) NOOP #else #undef DISTINCT_E_FACTORS + #define DISTINCT_E 1 #define XYZE_N XYZE + #define E_INDEX_N(E) 0 #define E_AXIS_N(E) E_AXIS #define UNUSED_E(E) UNUSED(E) #endif +#if ENABLED(DWIN_CREALITY_LCD) + #define SERIAL_CATCHALL 0 +#endif + +// Pressure sensor with a BLTouch-like interface +#if ENABLED(CREALITY_TOUCH) + #define BLTOUCH +#endif + /** * The BLTouch Probe emulates a servo probe * and uses "special" angles for its state. @@ -472,14 +664,7 @@ #ifndef Z_PROBE_SERVO_NR #define Z_PROBE_SERVO_NR 0 #endif - #ifndef NUM_SERVOS - #define NUM_SERVOS (Z_PROBE_SERVO_NR + 1) - #endif #undef DEACTIVATE_SERVOS_AFTER_MOVE - #if NUM_SERVOS == 1 - #undef SERVO_DELAY - #define SERVO_DELAY { 50 } - #endif // Always disable probe pin inverting for BLTouch #undef Z_MIN_PROBE_ENDSTOP_INVERTING @@ -490,19 +675,15 @@ #endif #endif -#ifndef PREHEAT_1_LABEL - #define PREHEAT_1_LABEL "PLA" -#endif - -#ifndef PREHEAT_2_LABEL - #define PREHEAT_2_LABEL "ABS" -#endif - /** * Set a flag for a servo probe (or BLTouch) */ -#define HAS_Z_SERVO_PROBE (defined(Z_PROBE_SERVO_NR) && Z_PROBE_SERVO_NR >= 0) -#define HAS_SERVO_ANGLES (HAS_Z_SERVO_PROBE || EITHER(SWITCHING_EXTRUDER, SWITCHING_NOZZLE)) +#ifdef Z_PROBE_SERVO_NR + #define HAS_Z_SERVO_PROBE 1 +#endif +#if ANY(HAS_Z_SERVO_PROBE, SWITCHING_EXTRUDER, SWITCHING_NOZZLE) + #define HAS_SERVO_ANGLES 1 +#endif #if !HAS_SERVO_ANGLES #undef EDITABLE_SERVO_ANGLES #endif @@ -510,21 +691,32 @@ /** * Set flags for enabled probes */ -#define HAS_BED_PROBE (HAS_Z_SERVO_PROBE || ANY(FIX_MOUNTED_PROBE, NOZZLE_AS_PROBE, TOUCH_MI_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, SOLENOID_PROBE, SENSORLESS_PROBING, RACK_AND_PINION_PROBE)) -#define PROBE_SELECTED (HAS_BED_PROBE || EITHER(PROBE_MANUALLY, MESH_BED_LEVELING)) +#if ANY(HAS_Z_SERVO_PROBE, FIX_MOUNTED_PROBE, NOZZLE_AS_PROBE, TOUCH_MI_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, SOLENOID_PROBE, SENSORLESS_PROBING, RACK_AND_PINION_PROBE) + #define HAS_BED_PROBE 1 +#endif + +#if ANY(HAS_BED_PROBE, PROBE_MANUALLY, MESH_BED_LEVELING) + #define PROBE_SELECTED 1 +#endif #if HAS_BED_PROBE - #define HAS_PROBE_XY_OFFSET DISABLED(NOZZLE_AS_PROBE) - #define HAS_CUSTOM_PROBE_PIN DISABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) - #define HOMING_Z_WITH_PROBE (Z_HOME_DIR < 0 && !HAS_CUSTOM_PROBE_PIN) + #if DISABLED(NOZZLE_AS_PROBE) + #define HAS_PROBE_XY_OFFSET 1 + #endif + #if DISABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) + #define HAS_CUSTOM_PROBE_PIN 1 + #endif + #if Z_HOME_DIR < 0 && (!HAS_CUSTOM_PROBE_PIN || ENABLED(USE_PROBE_FOR_Z_HOMING)) + #define HOMING_Z_WITH_PROBE 1 + #endif #ifndef Z_PROBE_LOW_POINT #define Z_PROBE_LOW_POINT -5 #endif #if ENABLED(Z_PROBE_ALLEN_KEY) - #define PROBE_TRIGGERED_WHEN_STOWED_TEST // Extra test for Allen Key Probe + #define PROBE_TRIGGERED_WHEN_STOWED_TEST 1 // Extra test for Allen Key Probe #endif - #ifdef MULTIPLE_PROBING - #if EXTRA_PROBING + #if MULTIPLE_PROBING > 1 + #if EXTRA_PROBING > 0 #define TOTAL_PROBING (MULTIPLE_PROBING + EXTRA_PROBING) #else #define TOTAL_PROBING MULTIPLE_PROBING @@ -535,27 +727,54 @@ #undef Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN #endif +/** + * Set granular options based on the specific type of leveling + */ +#if ENABLED(AUTO_BED_LEVELING_UBL) + #undef LCD_BED_LEVELING + #if ENABLED(DELTA) + #define UBL_SEGMENTED 1 + #endif +#endif +#if EITHER(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_3POINT) + #define ABL_PLANAR 1 +#endif +#if EITHER(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_BILINEAR) + #define ABL_GRID 1 +#endif +#if ANY(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_3POINT) + #define HAS_ABL_NOT_UBL 1 +#endif +#if ANY(AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_UBL, MESH_BED_LEVELING) + #define HAS_MESH 1 +#endif +#if EITHER(AUTO_BED_LEVELING_UBL, AUTO_BED_LEVELING_3POINT) + #define NEEDS_THREE_PROBE_POINTS 1 +#endif +#if EITHER(HAS_ABL_NOT_UBL, AUTO_BED_LEVELING_UBL) + #define HAS_ABL_OR_UBL 1 + #if DISABLED(PROBE_MANUALLY) + #define HAS_AUTOLEVEL 1 + #endif +#endif +#if EITHER(HAS_ABL_OR_UBL, MESH_BED_LEVELING) + #define HAS_LEVELING 1 + #if DISABLED(AUTO_BED_LEVELING_UBL) + #define PLANNER_LEVELING 1 + #endif +#endif +#if EITHER(HAS_ABL_OR_UBL, Z_MIN_PROBE_REPEATABILITY_TEST) + #define HAS_PROBING_PROCEDURE 1 +#endif +#if !HAS_LEVELING + #undef RESTORE_LEVELING_AFTER_G28 +#endif + #ifdef GRID_MAX_POINTS_X #define GRID_MAX_POINTS ((GRID_MAX_POINTS_X) * (GRID_MAX_POINTS_Y)) + #define GRID_LOOP(A,B) LOOP_L_N(A, GRID_MAX_POINTS_X) LOOP_L_N(B, GRID_MAX_POINTS_Y) #endif -#define HAS_EXTRA_ENDSTOPS ANY(X_DUAL_ENDSTOPS, Y_DUAL_ENDSTOPS, Z_MULTI_ENDSTOPS) -#define HAS_SOFTWARE_ENDSTOPS EITHER(MIN_SOFTWARE_ENDSTOPS, MAX_SOFTWARE_ENDSTOPS) -#define HAS_RESUME_CONTINUE ANY(EXTENSIBLE_UI, NEWPANEL, EMERGENCY_PARSER) -#define HAS_COLOR_LEDS ANY(BLINKM, RGB_LED, RGBW_LED, PCA9632, PCA9533, NEOPIXEL_LED) -#define HAS_LEDS_OFF_FLAG (BOTH(PRINTER_EVENT_LEDS, SDSUPPORT) && HAS_RESUME_CONTINUE) -#define HAS_PRINT_PROGRESS EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY) -#define HAS_PRINT_PROGRESS_PERMYRIAD (HAS_PRINT_PROGRESS && EITHER(PRINT_PROGRESS_SHOW_DECIMALS, SHOW_REMAINING_TIME)) -#define HAS_SERVICE_INTERVALS (ENABLED(PRINTCOUNTER) && (SERVICE_INTERVAL_1 > 0 || SERVICE_INTERVAL_2 > 0 || SERVICE_INTERVAL_3 > 0)) -#define HAS_FILAMENT_SENSOR ENABLED(FILAMENT_RUNOUT_SENSOR) - -#define HAS_GAMES ANY(MARLIN_BRICKOUT, MARLIN_INVADERS, MARLIN_SNAKE, MARLIN_MAZE) -#define HAS_GAME_MENU (1 < ENABLED(MARLIN_BRICKOUT) + ENABLED(MARLIN_INVADERS) + ENABLED(MARLIN_SNAKE) + ENABLED(MARLIN_MAZE)) - -#define IS_SCARA ENABLED(MORGAN_SCARA) -#define IS_KINEMATIC (ENABLED(DELTA) || IS_SCARA) -#define IS_CARTESIAN !IS_KINEMATIC - #ifndef INVERT_X_DIR #define INVERT_X_DIR false #endif @@ -573,10 +792,157 @@ #define BOOT_MARLIN_LOGO_SMALL #endif -#define IS_RE_ARM_BOARD MB(RAMPS_14_RE_ARM_EFB, RAMPS_14_RE_ARM_EEB, RAMPS_14_RE_ARM_EFF, RAMPS_14_RE_ARM_EEF, RAMPS_14_RE_ARM_SF) +// This flag indicates some kind of jerk storage is needed +#if EITHER(CLASSIC_JERK, IS_KINEMATIC) + #define HAS_CLASSIC_JERK 1 +#endif -#define HAS_LINEAR_E_JERK (DISABLED(CLASSIC_JERK) && ENABLED(LIN_ADVANCE)) +#if DISABLED(CLASSIC_JERK) + #define HAS_JUNCTION_DEVIATION 1 +#endif + +// E jerk exists with JD disabled (of course) but also when Linear Advance is disabled on Delta/SCARA +#if ENABLED(CLASSIC_JERK) || (IS_KINEMATIC && DISABLED(LIN_ADVANCE)) + #define HAS_CLASSIC_E_JERK 1 +#endif #ifndef SPI_SPEED #define SPI_SPEED SPI_FULL_SPEED #endif + +#if SERIAL_PORT == -1 || SERIAL_PORT_2 == -1 + #define HAS_USB_SERIAL 1 +#endif + +/** + * This setting is also used by M109 when trying to calculate + * a ballpark safe margin to prevent wait-forever situation. + */ +#ifndef EXTRUDE_MINTEMP + #define EXTRUDE_MINTEMP 170 +#endif + +/** + * TFT Displays + * + * Configure parameters for TFT displays: + * - TFT_DEFAULT_ORIENTATION + * - TFT_DRIVER + * - TFT_WIDTH + * - TFT_HEIGHT + * - TFT_INTERFACE_(SPI|FSMC) + * - TFT_COLOR + * - GRAPHICAL_TFT_UPSCALE + */ +#if ENABLED(MKS_TS35_V2_0) + // Most common: ST7796 + #define TFT_DEFAULT_ORIENTATION (TFT_EXCHANGE_XY) + #define TFT_WIDTH 480 + #define TFT_HEIGHT 320 + #define TFT_INTERFACE_SPI + #define GRAPHICAL_TFT_UPSCALE 3 +#elif ENABLED(MKS_ROBIN_TFT24) + // Most common: ST7789 + #define TFT_DEFAULT_ORIENTATION (TFT_EXCHANGE_XY | TFT_INVERT_Y) + #define TFT_WIDTH 320 + #define TFT_HEIGHT 240 + #define TFT_INTERFACE_FSMC + #define GRAPHICAL_TFT_UPSCALE 2 +#elif ENABLED(MKS_ROBIN_TFT28) + // Most common: ST7789 + #define TFT_DEFAULT_ORIENTATION (TFT_EXCHANGE_XY | TFT_INVERT_Y) + #define TFT_WIDTH 320 + #define TFT_HEIGHT 240 + #define TFT_INTERFACE_FSMC + #define GRAPHICAL_TFT_UPSCALE 2 +#elif ENABLED(MKS_ROBIN_TFT32) + // Most common: ST7789 + #define TFT_DEFAULT_ORIENTATION (TFT_EXCHANGE_XY | TFT_INVERT_Y) + #define TFT_WIDTH 320 + #define TFT_HEIGHT 240 + #define TFT_INTERFACE_FSMC + #define GRAPHICAL_TFT_UPSCALE 2 +#elif ENABLED(MKS_ROBIN_TFT35) + // Most common: ILI9488 + #define TFT_DEFAULT_ORIENTATION (TFT_EXCHANGE_XY | TFT_INVERT_X | TFT_INVERT_Y) + #define TFT_WIDTH 480 + #define TFT_HEIGHT 320 + #define TFT_INTERFACE_FSMC + #define GRAPHICAL_TFT_UPSCALE 3 +#elif ENABLED(MKS_ROBIN_TFT43) + #define TFT_DEFAULT_ORIENTATION 0 + #define TFT_DRIVER SSD1963 + #define TFT_WIDTH 480 + #define TFT_HEIGHT 272 + #define TFT_INTERFACE_FSMC + #define GRAPHICAL_TFT_UPSCALE 2 +#elif ENABLED(MKS_ROBIN_TFT_V1_1R) + // ILI9328 or R61505 + #define TFT_DEFAULT_ORIENTATION (TFT_INVERT_X | TFT_INVERT_Y | TFT_EXCHANGE_XY) + #define TFT_WIDTH 320 + #define TFT_HEIGHT 240 + #define TFT_INTERFACE_FSMC + #define GRAPHICAL_TFT_UPSCALE 2 +#elif EITHER(TFT_TRONXY_X5SA, ANYCUBIC_TFT35) + #define TFT_DEFAULT_ORIENTATION (TFT_EXCHANGE_XY | TFT_INVERT_X | TFT_INVERT_Y) + #define TFT_DRIVER ILI9488 + #define TFT_WIDTH 480 + #define TFT_HEIGHT 320 + #define TFT_INTERFACE_FSMC + #define GRAPHICAL_TFT_UPSCALE 3 +#elif ENABLED(LONGER_LK_TFT28) + #define TFT_DEFAULT_ORIENTATION (TFT_EXCHANGE_XY | TFT_INVERT_X | TFT_INVERT_Y) + #define TFT_WIDTH 320 + #define TFT_HEIGHT 240 + #define TFT_INTERFACE_FSMC + #define GRAPHICAL_TFT_UPSCALE 2 +#elif ENABLED(TFT_GENERIC) + #define TFT_DEFAULT_ORIENTATION (TFT_EXCHANGE_XY | TFT_INVERT_X | TFT_INVERT_Y) +#endif + +// FSMC/SPI TFT Panels using standard HAL/tft/tft_(fsmc|spi).h +#if ENABLED(TFT_INTERFACE_FSMC) + #define HAS_FSMC_TFT 1 + #if ENABLED(TFT_CLASSIC_UI) + #define FSMC_GRAPHICAL_TFT + #elif ENABLED(TFT_LVGL_UI) + #define TFT_LVGL_UI_FSMC + #endif +#elif ENABLED(TFT_INTERFACE_SPI) + #define HAS_SPI_TFT 1 + #if ENABLED(TFT_CLASSIC_UI) + #define SPI_GRAPHICAL_TFT + #elif ENABLED(TFT_LVGL_UI) + #define TFT_LVGL_UI_SPI + #endif +#endif + +#if ENABLED(TFT_COLOR_UI) && TFT_HEIGHT == 240 + #if ENABLED(TFT_INTERFACE_SPI) + #define TFT_320x240_SPI + #elif ENABLED(TFT_INTERFACE_FSMC) + #define TFT_320x240 + #endif +#elif ENABLED(TFT_COLOR_UI) && TFT_HEIGHT == 320 + #if ENABLED(TFT_INTERFACE_SPI) + #define TFT_480x320_SPI + #elif ENABLED(TFT_INTERFACE_FSMC) + #define TFT_480x320 + #endif +#endif + +// Fewer lines with touch buttons on-screen +#if EITHER(TFT_320x240, TFT_320x240_SPI) + #define HAS_UI_320x240 1 + #define LCD_HEIGHT TERN(TOUCH_SCREEN, 6, 7) +#elif EITHER(TFT_480x320, TFT_480x320_SPI) + #define HAS_UI_480x320 1 + #define LCD_HEIGHT TERN(TOUCH_SCREEN, 6, 7) +#endif + +// This emulated DOGM has 'touch/xpt2046', not 'tft/xpt2046' +#if ENABLED(TOUCH_SCREEN) && !HAS_GRAPHICAL_TFT + #undef TOUCH_SCREEN + #undef TOUCH_SCREEN_CALIBRATION + #define HAS_TOUCH_XPT2046 1 +#endif diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h index e5cb00c11228..bab05e5ff60d 100644 --- a/Marlin/src/inc/Conditionals_adv.h +++ b/Marlin/src/inc/Conditionals_adv.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -26,6 +26,51 @@ * Defines that depend on advanced configuration. */ +#ifdef SWITCHING_NOZZLE_E1_SERVO_NR + #define SWITCHING_NOZZLE_TWO_SERVOS 1 +#endif + +// Determine NUM_SERVOS if none was supplied +#ifndef NUM_SERVOS + #define NUM_SERVOS 0 + #if ANY(CHAMBER_VENT, HAS_Z_SERVO_PROBE, SWITCHING_EXTRUDER, SWITCHING_NOZZLE) + #if NUM_SERVOS <= Z_PROBE_SERVO_NR + #undef NUM_SERVOS + #define NUM_SERVOS (Z_PROBE_SERVO_NR + 1) + #endif + #if NUM_SERVOS <= CHAMBER_VENT_SERVO_NR + #undef NUM_SERVOS + #define NUM_SERVOS (CHAMBER_VENT_SERVO_NR + 1) + #endif + #if NUM_SERVOS <= SWITCHING_TOOLHEAD_SERVO_NR + #undef NUM_SERVOS + #define NUM_SERVOS (SWITCHING_TOOLHEAD_SERVO_NR + 1) + #endif + #if NUM_SERVOS <= SWITCHING_NOZZLE_SERVO_NR + #undef NUM_SERVOS + #define NUM_SERVOS (SWITCHING_NOZZLE_SERVO_NR + 1) + #endif + #if NUM_SERVOS <= SWITCHING_NOZZLE_E1_SERVO_NR + #undef NUM_SERVOS + #define NUM_SERVOS (SWITCHING_NOZZLE_E1_SERVO_NR + 1) + #endif + #if NUM_SERVOS <= SWITCHING_EXTRUDER_SERVO_NR + #undef NUM_SERVOS + #define NUM_SERVOS (SWITCHING_EXTRUDER_SERVO_NR + 1) + #endif + #if NUM_SERVOS <= SWITCHING_EXTRUDER_E23_SERVO_NR + #undef NUM_SERVOS + #define NUM_SERVOS (SWITCHING_EXTRUDER_E23_SERVO_NR + 1) + #endif + #endif +#endif + +// Convenience override for a BLTouch alone +#if ENABLED(BLTOUCH) && NUM_SERVOS == 1 + #undef SERVO_DELAY + #define SERVO_DELAY { 50 } +#endif + #if EXTRUDERS == 0 #define NO_VOLUMETRICS #undef TEMP_SENSOR_0 @@ -56,14 +101,117 @@ #undef SHOW_TEMP_ADC_VALUES #endif +#if TEMP_SENSOR_BED == 0 + #undef THERMAL_PROTECTION_BED + #undef THERMAL_PROTECTION_BED_PERIOD +#endif + +#if TEMP_SENSOR_CHAMBER == 0 + #undef THERMAL_PROTECTION_CHAMBER +#endif + +#if ENABLED(MIXING_EXTRUDER) && (ENABLED(RETRACT_SYNC_MIXING) || BOTH(FILAMENT_LOAD_UNLOAD_GCODES, FILAMENT_UNLOAD_ALL_EXTRUDERS)) + #define HAS_MIXER_SYNC_CHANNEL 1 +#endif + +#if EITHER(DUAL_X_CARRIAGE, MULTI_NOZZLE_DUPLICATION) + #define HAS_DUPLICATION_MODE 1 +#endif + +#if ENABLED(PRINTCOUNTER) && (SERVICE_INTERVAL_1 > 0 || SERVICE_INTERVAL_2 > 0 || SERVICE_INTERVAL_3 > 0) + #define HAS_SERVICE_INTERVALS 1 +#endif + +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define HAS_FILAMENT_SENSOR 1 + #ifdef FILAMENT_RUNOUT_DISTANCE_MM + #define HAS_FILAMENT_RUNOUT_DISTANCE 1 + #endif +#endif + +// Let SD_FINISHED_RELEASECOMMAND stand in for SD_FINISHED_STEPPERRELEASE +#if ENABLED(SD_FINISHED_STEPPERRELEASE) + #ifndef SD_FINISHED_RELEASECOMMAND + #define SD_FINISHED_RELEASECOMMAND "M84" // planner.finish_and_disable() + #endif +#else + #undef SD_FINISHED_RELEASECOMMAND +#endif + +#if EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY) + #define HAS_PRINT_PROGRESS 1 +#endif + +#if HAS_PRINT_PROGRESS && EITHER(PRINT_PROGRESS_SHOW_DECIMALS, SHOW_REMAINING_TIME) + #define HAS_PRINT_PROGRESS_PERMYRIAD 1 +#endif + +#if ANY(MARLIN_BRICKOUT, MARLIN_INVADERS, MARLIN_SNAKE, MARLIN_MAZE) + #define HAS_GAMES 1 + #if (1 < ENABLED(MARLIN_BRICKOUT) + ENABLED(MARLIN_INVADERS) + ENABLED(MARLIN_SNAKE) + ENABLED(MARLIN_MAZE)) + #define HAS_GAME_MENU 1 + #endif +#endif + +#if ANY(FWRETRACT, HAS_LEVELING, SKEW_CORRECTION) + #define HAS_POSITION_MODIFIERS 1 +#endif + +#if ANY(X_DUAL_ENDSTOPS, Y_DUAL_ENDSTOPS, Z_MULTI_ENDSTOPS) + #define HAS_EXTRA_ENDSTOPS 1 +#endif +#if EITHER(MIN_SOFTWARE_ENDSTOPS, MAX_SOFTWARE_ENDSTOPS) + #define HAS_SOFTWARE_ENDSTOPS 1 +#endif +#if ANY(EXTENSIBLE_UI, NEWPANEL, EMERGENCY_PARSER, HAS_ADC_BUTTONS, DWIN_CREALITY_LCD) + #define HAS_RESUME_CONTINUE 1 +#endif + +#if ANY(BLINKM, RGB_LED, RGBW_LED, PCA9632, PCA9533, NEOPIXEL_LED) + #define HAS_COLOR_LEDS 1 +#endif +#if ALL(HAS_RESUME_CONTINUE, PRINTER_EVENT_LEDS, SDSUPPORT) + #define HAS_LEDS_OFF_FLAG 1 +#endif + +#if EITHER(DIGIPOT_MCP4018, DIGIPOT_MCP4451) + #define HAS_MOTOR_CURRENT_I2C 1 +#endif + // Multiple Z steppers #ifndef NUM_Z_STEPPER_DRIVERS #define NUM_Z_STEPPER_DRIVERS 1 #endif -#define HAS_CUTTER EITHER(SPINDLE_FEATURE, LASER_FEATURE) +#if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS) + #undef Z_STEPPER_ALIGN_AMP +#endif +#ifndef Z_STEPPER_ALIGN_AMP + #define Z_STEPPER_ALIGN_AMP 1.0 +#endif + +// +// Spindle/Laser power display types +// Defined here so sanity checks can use them +// +#if EITHER(SPINDLE_FEATURE, LASER_FEATURE) + #define HAS_CUTTER 1 + #define _CUTTER_POWER_PWM255 1 + #define _CUTTER_POWER_PERCENT 2 + #define _CUTTER_POWER_RPM 3 + #define _CUTTER_POWER(V) _CAT(_CUTTER_POWER_, V) + #define CUTTER_UNIT_IS(V) (_CUTTER_POWER(CUTTER_POWER_UNIT) == _CUTTER_POWER(V)) +#endif + +// Add features that need hardware PWM here +#if ANY(FAST_PWM_FAN, SPINDLE_LASER_PWM) + #define NEEDS_HARDWARE_PWM 1 +#endif -#if !defined(__AVR__) || !defined(USBCON) +#if defined(__AVR__) && defined(USBCON) + #define IS_AT90USB 1 + #undef SERIAL_XON_XOFF // Not supported on USB-native devices +#else // Define constants and variables for buffering serial data. // Use only 0 or powers of 2 greater than 1 // : [0, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, ...] @@ -75,9 +223,6 @@ #ifndef TX_BUFFER_SIZE #define TX_BUFFER_SIZE 32 #endif -#else - // SERIAL_XON_XOFF not supported on USB-native devices - #undef SERIAL_XON_XOFF #endif #if ENABLED(HOST_ACTION_COMMANDS) @@ -96,6 +241,9 @@ #ifndef ACTION_ON_CANCEL #define ACTION_ON_CANCEL "cancel" #endif + #ifndef ACTION_ON_START + #define ACTION_ON_START "start" + #endif #ifndef ACTION_ON_KILL #define ACTION_ON_KILL "poweroff" #endif @@ -117,13 +265,10 @@ #endif #endif -#if ENABLED(FYSETC_MINI_12864_2_1) +#if EITHER(FYSETC_MINI_12864_2_1, FYSETC_242_OLED_12864) #define LED_CONTROL_MENU #define LED_USER_PRESET_STARTUP #define LED_COLOR_PRESETS - #ifndef LED_USER_PRESET_RED - #define LED_USER_PRESET_RED 255 - #endif #ifndef LED_USER_PRESET_GREEN #define LED_USER_PRESET_GREEN 128 #endif @@ -135,15 +280,224 @@ #endif #endif +// Set defaults for unspecified LED user colors +#if ENABLED(LED_CONTROL_MENU) + #ifndef LED_USER_PRESET_RED + #define LED_USER_PRESET_RED 255 + #endif + #ifndef LED_USER_PRESET_GREEN + #define LED_USER_PRESET_GREEN 255 + #endif + #ifndef LED_USER_PRESET_BLUE + #define LED_USER_PRESET_BLUE 255 + #endif + #ifndef LED_USER_PRESET_WHITE + #define LED_USER_PRESET_WHITE 0 + #endif + #ifndef LED_USER_PRESET_BRIGHTNESS + #ifdef NEOPIXEL_BRIGHTNESS + #define LED_USER_PRESET_BRIGHTNESS NEOPIXEL_BRIGHTNESS + #else + #define LED_USER_PRESET_BRIGHTNESS 255 + #endif + #endif +#endif + +#if BOTH(LED_CONTROL_MENU, NEOPIXEL2_SEPARATE) + #ifndef LED2_USER_PRESET_RED + #define LED2_USER_PRESET_RED 255 + #endif + #ifndef LED2_USER_PRESET_GREEN + #define LED2_USER_PRESET_GREEN 255 + #endif + #ifndef LED2_USER_PRESET_BLUE + #define LED2_USER_PRESET_BLUE 255 + #endif + #ifndef LED2_USER_PRESET_WHITE + #define LED2_USER_PRESET_WHITE 0 + #endif + #ifndef LED2_USER_PRESET_BRIGHTNESS + #ifdef NEOPIXEL2_BRIGHTNESS + #define LED2_USER_PRESET_BRIGHTNESS NEOPIXEL2_BRIGHTNESS + #else + #define LED2_USER_PRESET_BRIGHTNESS 255 + #endif + #endif +#endif + +// If platform requires early initialization of watchdog to properly boot +#if ENABLED(USE_WATCHDOG) && defined(ARDUINO_ARCH_SAM) + #define EARLY_WATCHDOG 1 +#endif + +// Full Touch Screen needs 'tft/xpt2046' +#if EITHER(TOUCH_SCREEN, HAS_TFT_LVGL_UI) + #define HAS_TFT_XPT2046 1 +#endif + +// Touch Screen or "Touch Buttons" need XPT2046 pins +// but they use different components +#if EITHER(HAS_TFT_XPT2046, HAS_TOUCH_XPT2046) + #define NEED_TOUCH_PINS 1 +#endif + // Extensible UI pin mapping for RepRapDiscount -#define TOUCH_UI_ULTIPANEL ENABLED(TOUCH_UI_FTDI_EVE) && ANY(AO_EXP1_PINMAP, AO_EXP2_PINMAP, CR10_TFT_PINMAP) +#if ENABLED(TOUCH_UI_FTDI_EVE) && ANY(AO_EXP1_PINMAP, AO_EXP2_PINMAP, CR10_TFT_PINMAP) + #define TOUCH_UI_ULTIPANEL 1 +#endif // Poll-based jogging for joystick and other devices #if ENABLED(JOYSTICK) #define POLL_JOG #endif -// G60/G61 Position Save -#if SAVED_POSITIONS > 256 - #error "SAVED_POSITIONS must be an integer from 0 to 256." +/** + * Driver Timings (in nanoseconds) + * NOTE: Driver timing order is longest-to-shortest duration. + * Preserve this ordering when adding new drivers. + */ +#ifndef MINIMUM_STEPPER_POST_DIR_DELAY + #if HAS_DRIVER(TB6560) + #define MINIMUM_STEPPER_POST_DIR_DELAY 15000 + #elif HAS_DRIVER(TB6600) + #define MINIMUM_STEPPER_POST_DIR_DELAY 1500 + #elif HAS_DRIVER(DRV8825) + #define MINIMUM_STEPPER_POST_DIR_DELAY 650 + #elif HAS_DRIVER(LV8729) + #define MINIMUM_STEPPER_POST_DIR_DELAY 500 + #elif HAS_DRIVER(A5984) + #define MINIMUM_STEPPER_POST_DIR_DELAY 400 + #elif HAS_DRIVER(A4988) + #define MINIMUM_STEPPER_POST_DIR_DELAY 200 + #elif HAS_TRINAMIC_CONFIG || HAS_TRINAMIC_STANDALONE + #define MINIMUM_STEPPER_POST_DIR_DELAY 60 + #else + #define MINIMUM_STEPPER_POST_DIR_DELAY 0 // Expect at least 10µS since one Stepper ISR must transpire + #endif +#endif + +#ifndef MINIMUM_STEPPER_PRE_DIR_DELAY + #define MINIMUM_STEPPER_PRE_DIR_DELAY MINIMUM_STEPPER_POST_DIR_DELAY +#endif + +#ifndef MINIMUM_STEPPER_PULSE + #if HAS_DRIVER(TB6560) + #define MINIMUM_STEPPER_PULSE 30 + #elif HAS_DRIVER(TB6600) + #define MINIMUM_STEPPER_PULSE 3 + #elif HAS_DRIVER(DRV8825) + #define MINIMUM_STEPPER_PULSE 2 + #elif HAS_DRIVER(A4988) || HAS_DRIVER(A5984) + #define MINIMUM_STEPPER_PULSE 1 + #elif HAS_TRINAMIC_CONFIG || HAS_TRINAMIC_STANDALONE + #define MINIMUM_STEPPER_PULSE 0 + #elif HAS_DRIVER(LV8729) + #define MINIMUM_STEPPER_PULSE 0 + #else + #define MINIMUM_STEPPER_PULSE 2 + #endif +#endif + +#ifndef MAXIMUM_STEPPER_RATE + #if HAS_DRIVER(TB6560) + #define MAXIMUM_STEPPER_RATE 15000 + #elif HAS_DRIVER(TB6600) + #define MAXIMUM_STEPPER_RATE 150000 + #elif HAS_DRIVER(DRV8825) + #define MAXIMUM_STEPPER_RATE 250000 + #elif HAS_DRIVER(A4988) + #define MAXIMUM_STEPPER_RATE 500000 + #elif HAS_DRIVER(LV8729) + #define MAXIMUM_STEPPER_RATE 1000000 + #elif HAS_TRINAMIC_CONFIG || HAS_TRINAMIC_STANDALONE + #define MAXIMUM_STEPPER_RATE 5000000 + #else + #define MAXIMUM_STEPPER_RATE 250000 + #endif +#endif + +#if ENABLED(DIRECT_STEPPING) + #ifndef STEPPER_PAGES + #define STEPPER_PAGES 16 + #endif + #ifndef STEPPER_PAGE_FORMAT + #define STEPPER_PAGE_FORMAT SP_4x2_256 + #endif + #ifndef PAGE_MANAGER + #define PAGE_MANAGER SerialPageManager + #endif +#endif + +// +// SD Card connection methods +// Defined here so pins and sanity checks can use them +// +#if ENABLED(SDSUPPORT) + #define _SDCARD_LCD 1 + #define _SDCARD_ONBOARD 2 + #define _SDCARD_CUSTOM_CABLE 3 + #define _SDCARD_ID(V) _CAT(_SDCARD_, V) + #define SD_CONNECTION_IS(V) (_SDCARD_ID(SDCARD_CONNECTION) == _SDCARD_ID(V)) +#else + #define SD_CONNECTION_IS(...) 0 +#endif + +// Power Monitor sensors +#if EITHER(POWER_MONITOR_CURRENT, POWER_MONITOR_VOLTAGE) + #define HAS_POWER_MONITOR 1 +#endif +#if ENABLED(POWER_MONITOR_CURRENT) && defined(POWER_MONITOR_FIXED_VOLTAGE) + #define HAS_POWER_MONITOR_VREF 1 +#endif +#if BOTH(HAS_POWER_MONITOR_VREF, POWER_MONITOR_CURRENT) + #define HAS_POWER_MONITOR_WATTS 1 +#endif + +// Flag if an EEPROM type is pre-selected +#if ENABLED(EEPROM_SETTINGS) && NONE(I2C_EEPROM, SPI_EEPROM, QSPI_EEPROM, FLASH_EEPROM_EMULATION, SRAM_EEPROM_EMULATION, SDCARD_EEPROM_EMULATION) + #define NO_EEPROM_SELECTED 1 +#endif + +// Flag whether hex_print.cpp is used +#if ANY(AUTO_BED_LEVELING_UBL, M100_FREE_MEMORY_WATCHER, DEBUG_GCODE_PARSER, TMC_DEBUG, MARLIN_DEV_MODE) + #define NEED_HEX_PRINT 1 +#endif + +// Flag whether least_squares_fit.cpp is used +#if ANY(AUTO_BED_LEVELING_UBL, AUTO_BED_LEVELING_LINEAR, Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS) + #define NEED_LSF 1 +#endif + +// Flag the indexed serial ports that are in use +#define ANY_SERIAL_IS(N) (defined(SERIAL_PORT) && SERIAL_PORT == (N)) || (defined(SERIAL_PORT_2) && SERIAL_PORT_2 == (N)) || (defined(LCD_SERIAL_PORT) && LCD_SERIAL_PORT == (N)) +#if ANY_SERIAL_IS(-1) + #define USING_SERIAL_DEFAULT +#endif +#if ANY_SERIAL_IS(0) + #define USING_SERIAL_0 1 +#endif +#if ANY_SERIAL_IS(1) + #define USING_SERIAL_1 1 +#endif +#if ANY_SERIAL_IS(2) + #define USING_SERIAL_2 1 +#endif +#if ANY_SERIAL_IS(3) + #define USING_SERIAL_3 1 +#endif +#if ANY_SERIAL_IS(4) + #define USING_SERIAL_4 1 +#endif +#if ANY_SERIAL_IS(5) + #define USING_SERIAL_5 1 +#endif +#if ANY_SERIAL_IS(6) + #define USING_SERIAL_6 1 +#endif +#if ANY_SERIAL_IS(7) + #define USING_SERIAL_7 1 +#endif +#if ANY_SERIAL_IS(8) + #define USING_SERIAL_8 1 #endif +#undef ANY_SERIAL_IS diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index 159aefa5d5fd..798bf009c639 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -30,6 +30,41 @@ // Extras for CI testing #endif +// ADC +#ifdef BOARD_ADC_VREF + #define ADC_VREF BOARD_ADC_VREF +#else + #define ADC_VREF HAL_ADC_VREF +#endif + +// Linear advance uses Jerk since E is an isolated axis +#if BOTH(HAS_JUNCTION_DEVIATION, LIN_ADVANCE) + #define HAS_LINEAR_E_JERK 1 +#endif + +// Determine which type of 'EEPROM' is in use +#if ENABLED(EEPROM_SETTINGS) + // EEPROM type may be defined by compile flags, configs, HALs, or pins + // Set additional flags to let HALs choose in their Conditionals_post.h + #if ANY(FLASH_EEPROM_EMULATION, SRAM_EEPROM_EMULATION, SDCARD_EEPROM_EMULATION, QSPI_EEPROM) + #define USE_EMULATED_EEPROM 1 + #elif ANY(I2C_EEPROM, SPI_EEPROM) + #define USE_WIRED_EEPROM 1 + #elif ENABLED(IIC_BL24CXX_EEPROM) + // nothing + #else + #define USE_FALLBACK_EEPROM 1 + #endif +#else + #undef I2C_EEPROM + #undef SPI_EEPROM + #undef QSPI_EEPROM + #undef SDCARD_EEPROM_EMULATION + #undef SRAM_EEPROM_EMULATION + #undef FLASH_EEPROM_EMULATION + #undef IIC_BL24CXX_EEPROM +#endif + #ifdef TEENSYDUINO #undef max #define max(a,b) ((a)>(b)?(a):(b)) @@ -40,9 +75,6 @@ #define NOT_A_PIN 0 // For PINS_DEBUGGING #endif -#define HAS_CLASSIC_JERK (ENABLED(CLASSIC_JERK) || IS_KINEMATIC) -#define HAS_CLASSIC_E_JERK (ENABLED(CLASSIC_JERK) || DISABLED(LIN_ADVANCE)) - /** * Axis lengths and center */ @@ -66,13 +98,8 @@ // Define center values for future use #define _X_HALF_BED ((X_BED_SIZE) / 2) #define _Y_HALF_BED ((Y_BED_SIZE) / 2) -#if ENABLED(BED_CENTER_AT_0_0) - #define X_CENTER 0 - #define Y_CENTER 0 -#else - #define X_CENTER _X_HALF_BED - #define Y_CENTER _Y_HALF_BED -#endif +#define X_CENTER TERN(BED_CENTER_AT_0_0, 0, _X_HALF_BED) +#define Y_CENTER TERN(BED_CENTER_AT_0_0, 0, _Y_HALF_BED) // Get the linear boundaries of the bed #define X_MIN_BED (X_CENTER - _X_HALF_BED) @@ -95,10 +122,18 @@ /** * CoreXY, CoreXZ, and CoreYZ - and their reverse */ -#define CORE_IS_XY EITHER(COREXY, COREYX) -#define CORE_IS_XZ EITHER(COREXZ, COREZX) -#define CORE_IS_YZ EITHER(COREYZ, COREZY) -#define IS_CORE (CORE_IS_XY || CORE_IS_XZ || CORE_IS_YZ) +#if EITHER(COREXY, COREYX) + #define CORE_IS_XY 1 +#endif +#if EITHER(COREXZ, COREZX) + #define CORE_IS_XZ 1 +#endif +#if EITHER(COREYZ, COREZY) + #define CORE_IS_YZ 1 +#endif +#if CORE_IS_XY || CORE_IS_XZ || CORE_IS_YZ + #define IS_CORE 1 +#endif #if IS_CORE #if CORE_IS_XY #define CORE_AXIS_1 A_AXIS @@ -113,12 +148,23 @@ #define CORE_AXIS_1 B_AXIS #define CORE_AXIS_2 C_AXIS #endif - #if ANY(COREYX, COREZX, COREZY) - #define CORESIGN(n) (-(n)) + #define CORESIGN(n) (ANY(COREYX, COREZX, COREZY) ? (-(n)) : (n)) +#elif ENABLED(MARKFORGED_XY) + // Markforged kinematics + #define CORE_AXIS_1 A_AXIS + #define CORE_AXIS_2 B_AXIS + #define NORMAL_AXIS Z_AXIS +#endif + +// Calibration codes only for non-core axes +#if EITHER(BACKLASH_GCODE, CALIBRATION_GCODE) + #if EITHER(IS_CORE, MARKFORGED_XY) + #define CAN_CALIBRATE(A,B) (_AXIS(A) == B) #else - #define CORESIGN(n) (n) + #define CAN_CALIBRATE(A,B) 1 #endif #endif +#define AXIS_CAN_CALIBRATE(A) CAN_CALIBRATE(A,NORMAL_AXIS) /** * No adjustable bed on non-cartesians @@ -142,33 +188,23 @@ */ #ifdef MANUAL_X_HOME_POS #define X_HOME_POS MANUAL_X_HOME_POS -#elif ENABLED(BED_CENTER_AT_0_0) - #if ENABLED(DELTA) - #define X_HOME_POS 0 - #else - #define X_HOME_POS (X_HOME_DIR < 0 ? X_MIN_POS : X_MAX_POS) - #endif #else - #if ENABLED(DELTA) - #define X_HOME_POS (X_MIN_POS + (X_BED_SIZE) * 0.5) + #define X_END_POS (X_HOME_DIR < 0 ? X_MIN_POS : X_MAX_POS) + #if ENABLED(BED_CENTER_AT_0_0) + #define X_HOME_POS TERN(DELTA, 0, X_END_POS) #else - #define X_HOME_POS (X_HOME_DIR < 0 ? X_MIN_POS : X_MAX_POS) + #define X_HOME_POS TERN(DELTA, X_MIN_POS + (X_BED_SIZE) * 0.5, X_END_POS) #endif #endif #ifdef MANUAL_Y_HOME_POS #define Y_HOME_POS MANUAL_Y_HOME_POS -#elif ENABLED(BED_CENTER_AT_0_0) - #if ENABLED(DELTA) - #define Y_HOME_POS 0 - #else - #define Y_HOME_POS (Y_HOME_DIR < 0 ? Y_MIN_POS : Y_MAX_POS) - #endif #else - #if ENABLED(DELTA) - #define Y_HOME_POS (Y_MIN_POS + (Y_BED_SIZE) * 0.5) + #define Y_END_POS (Y_HOME_DIR < 0 ? Y_MIN_POS : Y_MAX_POS) + #if ENABLED(BED_CENTER_AT_0_0) + #define Y_HOME_POS TERN(DELTA, 0, Y_END_POS) #else - #define Y_HOME_POS (Y_HOME_DIR < 0 ? Y_MIN_POS : Y_MAX_POS) + #define Y_HOME_POS TERN(DELTA, Y_MIN_POS + (Y_BED_SIZE) * 0.5, Y_END_POS) #endif #endif @@ -236,6 +272,13 @@ #define MAX_AUTORETRACT 99 #endif +/** + * Provide a DEFAULT_VOLUMETRIC_EXTRUDER_LIMIT in case NO_VOLUMETRICS is enabled + */ +#ifndef DEFAULT_VOLUMETRIC_EXTRUDER_LIMIT + #define DEFAULT_VOLUMETRIC_EXTRUDER_LIMIT 0.00 +#endif + /** * LCD Contrast for Graphical Displays */ @@ -256,7 +299,7 @@ #elif ENABLED(AZSMZ_12864) #define _LCD_CONTRAST_MIN 120 #define _LCD_CONTRAST_INIT 190 -#elif ENABLED(MKS_LCD12864B) +#elif ENABLED(MKS_LCD12864) #define _LCD_CONTRAST_MIN 120 #define _LCD_CONTRAST_INIT 205 #elif EITHER(MKS_MINI_12864, ENDER2_STOCKDISPLAY) @@ -267,11 +310,24 @@ #elif ENABLED(ULTI_CONTROLLER) #define _LCD_CONTRAST_INIT 127 #define _LCD_CONTRAST_MAX 254 -#elif EITHER(MAKRPANEL, MINIPANEL) +#elif ENABLED(MAKRPANEL) #define _LCD_CONTRAST_INIT 17 +#elif ENABLED(MINIPANEL) + #define _LCD_CONTRAST_INIT 150 +#elif ENABLED(ZONESTAR_12864OLED) + #define _LCD_CONTRAST_MIN 64 + #define _LCD_CONTRAST_INIT 128 + #define _LCD_CONTRAST_MAX 255 +#elif IS_TFTGLCD_PANEL + #define _LCD_CONTRAST_MIN 0 + #define _LCD_CONTRAST_INIT 250 + #define _LCD_CONTRAST_MAX 255 +#endif + +#ifdef _LCD_CONTRAST_INIT + #define HAS_LCD_CONTRAST 1 #endif -#define HAS_LCD_CONTRAST defined(_LCD_CONTRAST_INIT) #if HAS_LCD_CONTRAST #ifndef LCD_CONTRAST_MIN #ifdef _LCD_CONTRAST_MIN @@ -298,10 +354,37 @@ #endif /** - * Override here because this is set in Configuration_adv.h + * Override the SD_DETECT_STATE set in Configuration_adv.h + * and enable sharing of onboard SD host drives (all platforms but AGCM4) */ -#if HAS_LCD_MENU && DISABLED(ELB_FULL_GRAPHIC_CONTROLLER) && !(defined(ARDUINO_GRAND_CENTRAL_M4) && SD_CONNECTION_IS(ONBOARD)) - #undef SD_DETECT_INVERTED +#if ENABLED(SDSUPPORT) + + #if SD_CONNECTION_IS(ONBOARD) && DISABLED(NO_SD_HOST_DRIVE) && !defined(ARDUINO_GRAND_CENTRAL_M4) + // + // The external SD card is not used. Hardware SPI is used to access the card. + // When sharing the SD card with a PC we want the menu options to + // mount/unmount the card and refresh it. So we disable card detect. + // + #undef SD_DETECT_PIN + #define HAS_SHARED_MEDIA 1 + #endif + + #if PIN_EXISTS(SD_DETECT) + #if HAS_LCD_MENU && (SD_CONNECTION_IS(LCD) || !defined(SDCARD_CONNECTION)) + #undef SD_DETECT_STATE + #if ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) + #define SD_DETECT_STATE HIGH + #endif + #endif + #ifndef SD_DETECT_STATE + #define SD_DETECT_STATE LOW + #endif + #endif + +#endif + +#if ANY(HAS_GRAPHICAL_TFT, LCD_USE_DMA_FSMC, FSMC_GRAPHICAL_TFT, SPI_GRAPHICAL_TFT) || !PIN_EXISTS(SD_DETECT) + #define NO_LCD_REINIT 1 // Suppress LCD re-initialization #endif /** @@ -326,7 +409,7 @@ #ifndef PSU_NAME #if DISABLED(PSU_CONTROL) #define PSU_NAME "Generic" // No control - #elif PSU_ACTIVE_HIGH + #elif PSU_ACTIVE_STATE #define PSU_NAME "XBox" // X-Box 360 (203W) #else #define PSU_NAME "ATX" // ATX style @@ -334,7 +417,7 @@ #endif #if !defined(PSU_POWERUP_DELAY) && ENABLED(PSU_CONTROL) - #define PSU_POWERUP_DELAY 100 + #define PSU_POWERUP_DELAY 250 #endif /** @@ -343,7 +426,9 @@ #define ANY_TEMP_SENSOR_IS(n) (TEMP_SENSOR_0 == (n) || TEMP_SENSOR_1 == (n) || TEMP_SENSOR_2 == (n) || TEMP_SENSOR_3 == (n) || TEMP_SENSOR_4 == (n) || TEMP_SENSOR_5 == (n) || TEMP_SENSOR_6 == (n) || TEMP_SENSOR_7 == (n) || TEMP_SENSOR_BED == (n) || TEMP_SENSOR_PROBE == (n) || TEMP_SENSOR_CHAMBER == (n)) -#define HAS_USER_THERMISTORS ANY_TEMP_SENSOR_IS(1000) +#if ANY_TEMP_SENSOR_IS(1000) + #define HAS_USER_THERMISTORS 1 +#endif #if TEMP_SENSOR_0 == -5 || TEMP_SENSOR_0 == -3 || TEMP_SENSOR_0 == -2 #define HEATER_0_USES_MAX6675 @@ -579,118 +664,27 @@ HEATER_0_USES_THERMISTOR, HEATER_1_USES_THERMISTOR, HEATER_2_USES_THERMISTOR, HEATER_3_USES_THERMISTOR, \ HEATER_4_USES_THERMISTOR, HEATER_5_USES_THERMISTOR, HEATER_6_USES_THERMISTOR, HEATER_7_USES_THERMISTOR ) -/** - * Default hotend offsets, if not defined - */ -#if HAS_HOTEND_OFFSET - #ifndef HOTEND_OFFSET_X - #define HOTEND_OFFSET_X { 0 } // X offsets for each extruder - #endif - #ifndef HOTEND_OFFSET_Y - #define HOTEND_OFFSET_Y { 0 } // Y offsets for each extruder - #endif - #ifndef HOTEND_OFFSET_Z - #define HOTEND_OFFSET_Z { 0 } // Z offsets for each extruder - #endif -#endif - -/** - * ARRAY_BY_EXTRUDERS based on EXTRUDERS - */ -#define ARRAY_BY_EXTRUDERS(V...) ARRAY_N(EXTRUDERS, V) -#define ARRAY_BY_EXTRUDERS1(v1) ARRAY_BY_EXTRUDERS(v1, v1, v1, v1, v1, v1) - -/** - * ARRAY_BY_HOTENDS based on HOTENDS - */ -#define ARRAY_BY_HOTENDS(V...) ARRAY_N(HOTENDS, V) -#define ARRAY_BY_HOTENDS1(v1) ARRAY_BY_HOTENDS(v1, v1, v1, v1, v1, v1) - -/** - * Driver Timings - * NOTE: Driver timing order is longest-to-shortest duration. - * Preserve this ordering when adding new drivers. - */ - -#ifndef MINIMUM_STEPPER_POST_DIR_DELAY - #if HAS_DRIVER(TB6560) - #define MINIMUM_STEPPER_POST_DIR_DELAY 15000 - #elif HAS_DRIVER(TB6600) - #define MINIMUM_STEPPER_POST_DIR_DELAY 1500 - #elif HAS_DRIVER(DRV8825) - #define MINIMUM_STEPPER_POST_DIR_DELAY 650 - #elif HAS_DRIVER(LV8729) - #define MINIMUM_STEPPER_POST_DIR_DELAY 500 - #elif HAS_DRIVER(A5984) - #define MINIMUM_STEPPER_POST_DIR_DELAY 400 - #elif HAS_DRIVER(A4988) - #define MINIMUM_STEPPER_POST_DIR_DELAY 200 - #elif HAS_TRINAMIC || HAS_TRINAMIC_STANDALONE - #define MINIMUM_STEPPER_POST_DIR_DELAY 20 - #else - #define MINIMUM_STEPPER_POST_DIR_DELAY 0 // Expect at least 10µS since one Stepper ISR must transpire - #endif -#endif - -#ifndef MINIMUM_STEPPER_PRE_DIR_DELAY - #define MINIMUM_STEPPER_PRE_DIR_DELAY MINIMUM_STEPPER_POST_DIR_DELAY -#endif - -#ifndef MINIMUM_STEPPER_PULSE - #if HAS_DRIVER(TB6560) - #define MINIMUM_STEPPER_PULSE 30 - #elif HAS_DRIVER(TB6600) - #define MINIMUM_STEPPER_PULSE 3 - #elif HAS_DRIVER(DRV8825) - #define MINIMUM_STEPPER_PULSE 2 - #elif HAS_DRIVER(A4988) || HAS_DRIVER(A5984) - #define MINIMUM_STEPPER_PULSE 1 - #elif HAS_TRINAMIC || HAS_TRINAMIC_STANDALONE - #define MINIMUM_STEPPER_PULSE 0 - #elif HAS_DRIVER(LV8729) - #define MINIMUM_STEPPER_PULSE 0 - #else - #define MINIMUM_STEPPER_PULSE 2 - #endif -#endif - -#ifndef MAXIMUM_STEPPER_RATE - #if HAS_DRIVER(TB6560) - #define MAXIMUM_STEPPER_RATE 15000 - #elif HAS_DRIVER(TB6600) - #define MAXIMUM_STEPPER_RATE 150000 - #elif HAS_DRIVER(DRV8825) - #define MAXIMUM_STEPPER_RATE 250000 - #elif HAS_DRIVER(A4988) - #define MAXIMUM_STEPPER_RATE 500000 - #elif HAS_DRIVER(LV8729) - #define MAXIMUM_STEPPER_RATE 1000000 - #elif HAS_TRINAMIC || HAS_TRINAMIC_STANDALONE - #define MAXIMUM_STEPPER_RATE 5000000 - #else - #define MAXIMUM_STEPPER_RATE 250000 - #endif -#endif - /** * X_DUAL_ENDSTOPS endstop reassignment */ #if ENABLED(X_DUAL_ENDSTOPS) #if X_HOME_DIR > 0 - #if X2_USE_ENDSTOP == _XMIN_ - #define X2_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING - #elif X2_USE_ENDSTOP == _XMAX_ - #define X2_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING - #elif X2_USE_ENDSTOP == _YMIN_ - #define X2_MAX_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING - #elif X2_USE_ENDSTOP == _YMAX_ - #define X2_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING - #elif X2_USE_ENDSTOP == _ZMIN_ - #define X2_MAX_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING - #elif X2_USE_ENDSTOP == _ZMAX_ - #define X2_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING - #else - #define X2_MAX_ENDSTOP_INVERTING false + #ifndef X2_MAX_ENDSTOP_INVERTING + #if X2_USE_ENDSTOP == _XMIN_ + #define X2_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING + #elif X2_USE_ENDSTOP == _XMAX_ + #define X2_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING + #elif X2_USE_ENDSTOP == _YMIN_ + #define X2_MAX_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING + #elif X2_USE_ENDSTOP == _YMAX_ + #define X2_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING + #elif X2_USE_ENDSTOP == _ZMIN_ + #define X2_MAX_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING + #elif X2_USE_ENDSTOP == _ZMAX_ + #define X2_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING + #else + #define X2_MAX_ENDSTOP_INVERTING false + #endif #endif #ifndef X2_MAX_PIN #if X2_USE_ENDSTOP == _XMIN_ @@ -729,23 +723,27 @@ #define X2_MAX_PIN E7_DIAG_PIN #endif #endif - #define X2_MIN_ENDSTOP_INVERTING false - #else - #if X2_USE_ENDSTOP == _XMIN_ - #define X2_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING - #elif X2_USE_ENDSTOP == _XMAX_ - #define X2_MIN_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING - #elif X2_USE_ENDSTOP == _YMIN_ - #define X2_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING - #elif X2_USE_ENDSTOP == _YMAX_ - #define X2_MIN_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING - #elif X2_USE_ENDSTOP == _ZMIN_ - #define X2_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING - #elif X2_USE_ENDSTOP == _ZMAX_ - #define X2_MIN_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING - #else + #ifndef X2_MIN_ENDSTOP_INVERTING #define X2_MIN_ENDSTOP_INVERTING false #endif + #else + #ifndef X2_MIN_ENDSTOP_INVERTING + #if X2_USE_ENDSTOP == _XMIN_ + #define X2_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING + #elif X2_USE_ENDSTOP == _XMAX_ + #define X2_MIN_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING + #elif X2_USE_ENDSTOP == _YMIN_ + #define X2_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING + #elif X2_USE_ENDSTOP == _YMAX_ + #define X2_MIN_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING + #elif X2_USE_ENDSTOP == _ZMIN_ + #define X2_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING + #elif X2_USE_ENDSTOP == _ZMAX_ + #define X2_MIN_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING + #else + #define X2_MIN_ENDSTOP_INVERTING false + #endif + #endif #ifndef X2_MIN_PIN #if X2_USE_ENDSTOP == _XMIN_ #define X2_MIN_PIN X_MIN_PIN @@ -783,7 +781,9 @@ #define X2_MIN_PIN E7_DIAG_PIN #endif #endif - #define X2_MAX_ENDSTOP_INVERTING false + #ifndef X2_MAX_ENDSTOP_INVERTING + #define X2_MAX_ENDSTOP_INVERTING false + #endif #endif #endif @@ -792,20 +792,22 @@ */ #if ENABLED(Y_DUAL_ENDSTOPS) #if Y_HOME_DIR > 0 - #if Y2_USE_ENDSTOP == _XMIN_ - #define Y2_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING - #elif Y2_USE_ENDSTOP == _XMAX_ - #define Y2_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING - #elif Y2_USE_ENDSTOP == _YMIN_ - #define Y2_MAX_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING - #elif Y2_USE_ENDSTOP == _YMAX_ - #define Y2_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING - #elif Y2_USE_ENDSTOP == _ZMIN_ - #define Y2_MAX_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING - #elif Y2_USE_ENDSTOP == _ZMAX_ - #define Y2_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING - #else - #define Y2_MAX_ENDSTOP_INVERTING false + #ifndef Y2_MAX_ENDSTOP_INVERTING + #if Y2_USE_ENDSTOP == _XMIN_ + #define Y2_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING + #elif Y2_USE_ENDSTOP == _XMAX_ + #define Y2_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING + #elif Y2_USE_ENDSTOP == _YMIN_ + #define Y2_MAX_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING + #elif Y2_USE_ENDSTOP == _YMAX_ + #define Y2_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING + #elif Y2_USE_ENDSTOP == _ZMIN_ + #define Y2_MAX_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING + #elif Y2_USE_ENDSTOP == _ZMAX_ + #define Y2_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING + #else + #define Y2_MAX_ENDSTOP_INVERTING false + #endif #endif #ifndef Y2_MAX_PIN #if Y2_USE_ENDSTOP == _XMIN_ @@ -844,23 +846,27 @@ #define Y2_MAX_PIN E7_DIAG_PIN #endif #endif - #define Y2_MIN_ENDSTOP_INVERTING false - #else - #if Y2_USE_ENDSTOP == _XMIN_ - #define Y2_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING - #elif Y2_USE_ENDSTOP == _XMAX_ - #define Y2_MIN_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING - #elif Y2_USE_ENDSTOP == _YMIN_ - #define Y2_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING - #elif Y2_USE_ENDSTOP == _YMAX_ - #define Y2_MIN_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING - #elif Y2_USE_ENDSTOP == _ZMIN_ - #define Y2_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING - #elif Y2_USE_ENDSTOP == _ZMAX_ - #define Y2_MIN_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING - #else + #ifndef Y2_MIN_ENDSTOP_INVERTING #define Y2_MIN_ENDSTOP_INVERTING false #endif + #else + #ifndef Y2_MIN_ENDSTOP_INVERTING + #if Y2_USE_ENDSTOP == _XMIN_ + #define Y2_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING + #elif Y2_USE_ENDSTOP == _XMAX_ + #define Y2_MIN_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING + #elif Y2_USE_ENDSTOP == _YMIN_ + #define Y2_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING + #elif Y2_USE_ENDSTOP == _YMAX_ + #define Y2_MIN_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING + #elif Y2_USE_ENDSTOP == _ZMIN_ + #define Y2_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING + #elif Y2_USE_ENDSTOP == _ZMAX_ + #define Y2_MIN_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING + #else + #define Y2_MIN_ENDSTOP_INVERTING false + #endif + #endif #ifndef Y2_MIN_PIN #if Y2_USE_ENDSTOP == _XMIN_ #define Y2_MIN_PIN X_MIN_PIN @@ -898,7 +904,9 @@ #define Y2_MIN_PIN E7_DIAG_PIN #endif #endif - #define Y2_MAX_ENDSTOP_INVERTING false + #ifndef Y2_MAX_ENDSTOP_INVERTING + #define Y2_MAX_ENDSTOP_INVERTING false + #endif #endif #endif @@ -908,20 +916,22 @@ #if ENABLED(Z_MULTI_ENDSTOPS) #if Z_HOME_DIR > 0 - #if Z2_USE_ENDSTOP == _XMIN_ - #define Z2_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING - #elif Z2_USE_ENDSTOP == _XMAX_ - #define Z2_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING - #elif Z2_USE_ENDSTOP == _YMIN_ - #define Z2_MAX_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING - #elif Z2_USE_ENDSTOP == _YMAX_ - #define Z2_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING - #elif Z2_USE_ENDSTOP == _ZMIN_ - #define Z2_MAX_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING - #elif Z2_USE_ENDSTOP == _ZMAX_ - #define Z2_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING - #else - #define Z2_MAX_ENDSTOP_INVERTING false + #ifndef Z2_MAX_ENDSTOP_INVERTING + #if Z2_USE_ENDSTOP == _XMIN_ + #define Z2_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING + #elif Z2_USE_ENDSTOP == _XMAX_ + #define Z2_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING + #elif Z2_USE_ENDSTOP == _YMIN_ + #define Z2_MAX_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING + #elif Z2_USE_ENDSTOP == _YMAX_ + #define Z2_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING + #elif Z2_USE_ENDSTOP == _ZMIN_ + #define Z2_MAX_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING + #elif Z2_USE_ENDSTOP == _ZMAX_ + #define Z2_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING + #else + #define Z2_MAX_ENDSTOP_INVERTING false + #endif #endif #ifndef Z2_MAX_PIN #if Z2_USE_ENDSTOP == _XMIN_ @@ -960,23 +970,27 @@ #define Z2_MAX_PIN E7_DIAG_PIN #endif #endif - #define Z2_MIN_ENDSTOP_INVERTING false - #else - #if Z2_USE_ENDSTOP == _XMIN_ - #define Z2_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING - #elif Z2_USE_ENDSTOP == _XMAX_ - #define Z2_MIN_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING - #elif Z2_USE_ENDSTOP == _YMIN_ - #define Z2_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING - #elif Z2_USE_ENDSTOP == _YMAX_ - #define Z2_MIN_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING - #elif Z2_USE_ENDSTOP == _ZMIN_ - #define Z2_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING - #elif Z2_USE_ENDSTOP == _ZMAX_ - #define Z2_MIN_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING - #else + #ifndef Z2_MIN_ENDSTOP_INVERTING #define Z2_MIN_ENDSTOP_INVERTING false #endif + #else + #ifndef Z2_MIN_ENDSTOP_INVERTING + #if Z2_USE_ENDSTOP == _XMIN_ + #define Z2_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING + #elif Z2_USE_ENDSTOP == _XMAX_ + #define Z2_MIN_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING + #elif Z2_USE_ENDSTOP == _YMIN_ + #define Z2_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING + #elif Z2_USE_ENDSTOP == _YMAX_ + #define Z2_MIN_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING + #elif Z2_USE_ENDSTOP == _ZMIN_ + #define Z2_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING + #elif Z2_USE_ENDSTOP == _ZMAX_ + #define Z2_MIN_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING + #else + #define Z2_MIN_ENDSTOP_INVERTING false + #endif + #endif #ifndef Z2_MIN_PIN #if Z2_USE_ENDSTOP == _XMIN_ #define Z2_MIN_PIN X_MIN_PIN @@ -1014,25 +1028,29 @@ #define Z2_MIN_PIN E7_DIAG_PIN #endif #endif - #define Z2_MAX_ENDSTOP_INVERTING false + #ifndef Z2_MAX_ENDSTOP_INVERTING + #define Z2_MAX_ENDSTOP_INVERTING false + #endif #endif #if NUM_Z_STEPPER_DRIVERS >= 3 #if Z_HOME_DIR > 0 - #if Z3_USE_ENDSTOP == _XMIN_ - #define Z3_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING - #elif Z3_USE_ENDSTOP == _XMAX_ - #define Z3_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING - #elif Z3_USE_ENDSTOP == _YMIN_ - #define Z3_MAX_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING - #elif Z3_USE_ENDSTOP == _YMAX_ - #define Z3_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING - #elif Z3_USE_ENDSTOP == _ZMIN_ - #define Z3_MAX_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING - #elif Z3_USE_ENDSTOP == _ZMAX_ - #define Z3_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING - #else - #define Z3_MAX_ENDSTOP_INVERTING false + #ifndef Z3_MAX_ENDSTOP_INVERTING + #if Z3_USE_ENDSTOP == _XMIN_ + #define Z3_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING + #elif Z3_USE_ENDSTOP == _XMAX_ + #define Z3_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING + #elif Z3_USE_ENDSTOP == _YMIN_ + #define Z3_MAX_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING + #elif Z3_USE_ENDSTOP == _YMAX_ + #define Z3_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING + #elif Z3_USE_ENDSTOP == _ZMIN_ + #define Z3_MAX_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING + #elif Z3_USE_ENDSTOP == _ZMAX_ + #define Z3_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING + #else + #define Z3_MAX_ENDSTOP_INVERTING false + #endif #endif #ifndef Z3_MAX_PIN #if Z3_USE_ENDSTOP == _XMIN_ @@ -1071,23 +1089,27 @@ #define Z3_MAX_PIN E7_DIAG_PIN #endif #endif - #define Z3_MIN_ENDSTOP_INVERTING false - #else - #if Z3_USE_ENDSTOP == _XMIN_ - #define Z3_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING - #elif Z3_USE_ENDSTOP == _XMAX_ - #define Z3_MIN_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING - #elif Z3_USE_ENDSTOP == _YMIN_ - #define Z3_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING - #elif Z3_USE_ENDSTOP == _YMAX_ - #define Z3_MIN_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING - #elif Z3_USE_ENDSTOP == _ZMIN_ - #define Z3_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING - #elif Z3_USE_ENDSTOP == _ZMAX_ - #define Z3_MIN_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING - #else + #ifndef Z3_MIN_ENDSTOP_INVERTING #define Z3_MIN_ENDSTOP_INVERTING false #endif + #else + #ifndef Z3_MIN_ENDSTOP_INVERTING + #if Z3_USE_ENDSTOP == _XMIN_ + #define Z3_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING + #elif Z3_USE_ENDSTOP == _XMAX_ + #define Z3_MIN_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING + #elif Z3_USE_ENDSTOP == _YMIN_ + #define Z3_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING + #elif Z3_USE_ENDSTOP == _YMAX_ + #define Z3_MIN_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING + #elif Z3_USE_ENDSTOP == _ZMIN_ + #define Z3_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING + #elif Z3_USE_ENDSTOP == _ZMAX_ + #define Z3_MIN_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING + #else + #define Z3_MIN_ENDSTOP_INVERTING false + #endif + #endif #ifndef Z3_MIN_PIN #if Z3_USE_ENDSTOP == _XMIN_ #define Z3_MIN_PIN X_MIN_PIN @@ -1125,26 +1147,30 @@ #define Z3_MIN_PIN E7_DIAG_PIN #endif #endif - #define Z3_MAX_ENDSTOP_INVERTING false + #ifndef Z3_MAX_ENDSTOP_INVERTING + #define Z3_MAX_ENDSTOP_INVERTING false + #endif #endif #endif #if NUM_Z_STEPPER_DRIVERS >= 4 #if Z_HOME_DIR > 0 - #if Z4_USE_ENDSTOP == _XMIN_ - #define Z4_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING - #elif Z4_USE_ENDSTOP == _XMAX_ - #define Z4_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING - #elif Z4_USE_ENDSTOP == _YMIN_ - #define Z4_MAX_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING - #elif Z4_USE_ENDSTOP == _YMAX_ - #define Z4_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING - #elif Z4_USE_ENDSTOP == _ZMIN_ - #define Z4_MAX_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING - #elif Z4_USE_ENDSTOP == _ZMAX_ - #define Z4_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING - #else - #define Z4_MAX_ENDSTOP_INVERTING false + #ifndef Z4_MAX_ENDSTOP_INVERTING + #if Z4_USE_ENDSTOP == _XMIN_ + #define Z4_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING + #elif Z4_USE_ENDSTOP == _XMAX_ + #define Z4_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING + #elif Z4_USE_ENDSTOP == _YMIN_ + #define Z4_MAX_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING + #elif Z4_USE_ENDSTOP == _YMAX_ + #define Z4_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING + #elif Z4_USE_ENDSTOP == _ZMIN_ + #define Z4_MAX_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING + #elif Z4_USE_ENDSTOP == _ZMAX_ + #define Z4_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING + #else + #define Z4_MAX_ENDSTOP_INVERTING false + #endif #endif #ifndef Z4_MAX_PIN #if Z4_USE_ENDSTOP == _XMIN_ @@ -1183,23 +1209,27 @@ #define Z4_MAX_PIN E7_DIAG_PIN #endif #endif - #define Z4_MIN_ENDSTOP_INVERTING false - #else - #if Z4_USE_ENDSTOP == _XMIN_ - #define Z4_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING - #elif Z4_USE_ENDSTOP == _XMAX_ - #define Z4_MIN_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING - #elif Z4_USE_ENDSTOP == _YMIN_ - #define Z4_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING - #elif Z4_USE_ENDSTOP == _YMAX_ - #define Z4_MIN_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING - #elif Z4_USE_ENDSTOP == _ZMIN_ - #define Z4_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING - #elif Z4_USE_ENDSTOP == _ZMAX_ - #define Z4_MIN_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING - #else + #ifndef Z4_MIN_ENDSTOP_INVERTING #define Z4_MIN_ENDSTOP_INVERTING false #endif + #else + #ifndef Z4_MIN_ENDSTOP_INVERTING + #if Z4_USE_ENDSTOP == _XMIN_ + #define Z4_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING + #elif Z4_USE_ENDSTOP == _XMAX_ + #define Z4_MIN_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING + #elif Z4_USE_ENDSTOP == _YMIN_ + #define Z4_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING + #elif Z4_USE_ENDSTOP == _YMAX_ + #define Z4_MIN_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING + #elif Z4_USE_ENDSTOP == _ZMIN_ + #define Z4_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING + #elif Z4_USE_ENDSTOP == _ZMAX_ + #define Z4_MIN_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING + #else + #define Z4_MIN_ENDSTOP_INVERTING false + #endif + #endif #ifndef Z4_MIN_PIN #if Z4_USE_ENDSTOP == _XMIN_ #define Z4_MIN_PIN X_MIN_PIN @@ -1237,7 +1267,9 @@ #define Z4_MIN_PIN E7_DIAG_PIN #endif #endif - #define Z4_MAX_ENDSTOP_INVERTING false + #ifndef Z4_MAX_ENDSTOP_INVERTING + #define Z4_MAX_ENDSTOP_INVERTING false + #endif #endif #endif @@ -1296,111 +1328,281 @@ */ // Steppers -#define HAS_X_ENABLE (PIN_EXISTS(X_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(X))) -#define HAS_X_DIR (PIN_EXISTS(X_DIR)) -#define HAS_X_STEP (PIN_EXISTS(X_STEP)) -#define HAS_X_MICROSTEPS (PIN_EXISTS(X_MS1)) - -#define HAS_X2_ENABLE (PIN_EXISTS(X2_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(X2))) -#define HAS_X2_DIR (PIN_EXISTS(X2_DIR)) -#define HAS_X2_STEP (PIN_EXISTS(X2_STEP)) -#define HAS_X2_MICROSTEPS (PIN_EXISTS(X2_MS1)) - -#define HAS_Y_ENABLE (PIN_EXISTS(Y_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Y))) -#define HAS_Y_DIR (PIN_EXISTS(Y_DIR)) -#define HAS_Y_STEP (PIN_EXISTS(Y_STEP)) -#define HAS_Y_MICROSTEPS (PIN_EXISTS(Y_MS1)) - -#define HAS_Y2_ENABLE (PIN_EXISTS(Y2_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Y2))) -#define HAS_Y2_DIR (PIN_EXISTS(Y2_DIR)) -#define HAS_Y2_STEP (PIN_EXISTS(Y2_STEP)) -#define HAS_Y2_MICROSTEPS (PIN_EXISTS(Y2_MS1)) - -#define HAS_Z_ENABLE (PIN_EXISTS(Z_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Z))) -#define HAS_Z_DIR (PIN_EXISTS(Z_DIR)) -#define HAS_Z_STEP (PIN_EXISTS(Z_STEP)) -#define HAS_Z_MICROSTEPS (PIN_EXISTS(Z_MS1)) - -#define HAS_Z2_ENABLE (PIN_EXISTS(Z2_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Z2))) -#define HAS_Z2_DIR (PIN_EXISTS(Z2_DIR)) -#define HAS_Z2_STEP (PIN_EXISTS(Z2_STEP)) -#define HAS_Z2_MICROSTEPS (PIN_EXISTS(Z2_MS1)) - -#define HAS_Z3_ENABLE (PIN_EXISTS(Z3_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Z3))) -#define HAS_Z3_DIR (PIN_EXISTS(Z3_DIR)) -#define HAS_Z3_STEP (PIN_EXISTS(Z3_STEP)) -#define HAS_Z3_MICROSTEPS (PIN_EXISTS(Z3_MS1)) - -#define HAS_Z4_ENABLE (PIN_EXISTS(Z4_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Z4))) -#define HAS_Z4_DIR (PIN_EXISTS(Z4_DIR)) -#define HAS_Z4_STEP (PIN_EXISTS(Z4_STEP)) -#define HAS_Z4_MICROSTEPS (PIN_EXISTS(Z4_MS1)) +#if PIN_EXISTS(X_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(X)) + #define HAS_X_ENABLE 1 +#endif +#if PIN_EXISTS(X_DIR) + #define HAS_X_DIR 1 +#endif +#if PIN_EXISTS(X_STEP) + #define HAS_X_STEP 1 +#endif +#if PIN_EXISTS(X_MS1) + #define HAS_X_MS_PINS 1 +#endif + +#if PIN_EXISTS(X2_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(X2)) + #define HAS_X2_ENABLE 1 +#endif +#if PIN_EXISTS(X2_DIR) + #define HAS_X2_DIR 1 +#endif +#if PIN_EXISTS(X2_STEP) + #define HAS_X2_STEP 1 +#endif +#if PIN_EXISTS(X2_MS1) + #define HAS_X2_MS_PINS 1 +#endif + +#if PIN_EXISTS(Y_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Y)) + #define HAS_Y_ENABLE 1 +#endif +#if PIN_EXISTS(Y_DIR) + #define HAS_Y_DIR 1 +#endif +#if PIN_EXISTS(Y_STEP) + #define HAS_Y_STEP 1 +#endif +#if PIN_EXISTS(Y_MS1) + #define HAS_Y_MS_PINS 1 +#endif + +#if PIN_EXISTS(Y2_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Y2)) + #define HAS_Y2_ENABLE 1 +#endif +#if PIN_EXISTS(Y2_DIR) + #define HAS_Y2_DIR 1 +#endif +#if PIN_EXISTS(Y2_STEP) + #define HAS_Y2_STEP 1 +#endif +#if PIN_EXISTS(Y2_MS1) + #define HAS_Y2_MS_PINS 1 +#endif + +#if PIN_EXISTS(Z_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Z)) + #define HAS_Z_ENABLE 1 +#endif +#if PIN_EXISTS(Z_DIR) + #define HAS_Z_DIR 1 +#endif +#if PIN_EXISTS(Z_STEP) + #define HAS_Z_STEP 1 +#endif +#if PIN_EXISTS(Z_MS1) + #define HAS_Z_MS_PINS 1 +#endif + +#if PIN_EXISTS(Z2_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Z2)) + #define HAS_Z2_ENABLE 1 +#endif +#if PIN_EXISTS(Z2_DIR) + #define HAS_Z2_DIR 1 +#endif +#if PIN_EXISTS(Z2_STEP) + #define HAS_Z2_STEP 1 +#endif +#if PIN_EXISTS(Z2_MS1) + #define HAS_Z2_MS_PINS 1 +#endif + +#if PIN_EXISTS(Z3_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Z3)) + #define HAS_Z3_ENABLE 1 +#endif +#if PIN_EXISTS(Z3_DIR) + #define HAS_Z3_DIR 1 +#endif +#if PIN_EXISTS(Z3_STEP) + #define HAS_Z3_STEP 1 +#endif +#if PIN_EXISTS(Z3_MS1) + #define HAS_Z3_MS_PINS 1 +#endif + +#if PIN_EXISTS(Z4_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Z4)) + #define HAS_Z4_ENABLE 1 +#endif +#if PIN_EXISTS(Z4_DIR) + #define HAS_Z4_DIR 1 +#endif +#if PIN_EXISTS(Z4_STEP) + #define HAS_Z4_STEP 1 +#endif +#if PIN_EXISTS(Z4_MS1) + #define HAS_Z4_MS_PINS 1 +#endif // Extruder steppers and solenoids -#define HAS_E0_ENABLE (PIN_EXISTS(E0_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E0))) -#define HAS_E0_DIR (PIN_EXISTS(E0_DIR)) -#define HAS_E0_STEP (PIN_EXISTS(E0_STEP)) -#define HAS_E0_MICROSTEPS (PIN_EXISTS(E0_MS1)) -#define HAS_SOLENOID_0 (PIN_EXISTS(SOL0)) - -#define HAS_E1_ENABLE (PIN_EXISTS(E1_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E1))) -#define HAS_E1_DIR (PIN_EXISTS(E1_DIR)) -#define HAS_E1_STEP (PIN_EXISTS(E1_STEP)) -#define HAS_E1_MICROSTEPS (PIN_EXISTS(E1_MS1)) -#define HAS_SOLENOID_1 (PIN_EXISTS(SOL1)) - -#define HAS_E2_ENABLE (PIN_EXISTS(E2_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E2))) -#define HAS_E2_DIR (PIN_EXISTS(E2_DIR)) -#define HAS_E2_STEP (PIN_EXISTS(E2_STEP)) -#define HAS_E2_MICROSTEPS (PIN_EXISTS(E2_MS1)) -#define HAS_SOLENOID_2 (PIN_EXISTS(SOL2)) - -#define HAS_E3_ENABLE (PIN_EXISTS(E3_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E3))) -#define HAS_E3_DIR (PIN_EXISTS(E3_DIR)) -#define HAS_E3_STEP (PIN_EXISTS(E3_STEP)) -#define HAS_E3_MICROSTEPS (PIN_EXISTS(E3_MS1)) -#define HAS_SOLENOID_3 (PIN_EXISTS(SOL3)) - -#define HAS_E4_ENABLE (PIN_EXISTS(E4_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E4))) -#define HAS_E4_DIR (PIN_EXISTS(E4_DIR)) -#define HAS_E4_STEP (PIN_EXISTS(E4_STEP)) -#define HAS_E4_MICROSTEPS (PIN_EXISTS(E4_MS1)) -#define HAS_SOLENOID_4 (PIN_EXISTS(SOL4)) - -#define HAS_E5_ENABLE (PIN_EXISTS(E5_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E5))) -#define HAS_E5_DIR (PIN_EXISTS(E5_DIR)) -#define HAS_E5_STEP (PIN_EXISTS(E5_STEP)) -#define HAS_E5_MICROSTEPS (PIN_EXISTS(E5_MS1)) -#define HAS_SOLENOID_5 (PIN_EXISTS(SOL5)) - -#define HAS_E6_ENABLE (PIN_EXISTS(E6_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E6))) -#define HAS_E6_DIR (PIN_EXISTS(E6_DIR)) -#define HAS_E6_STEP (PIN_EXISTS(E6_STEP)) -#define HAS_E6_MICROSTEPS (PIN_EXISTS(E6_MS1)) -#define HAS_SOLENOID_6 (PIN_EXISTS(SOL6)) - -#define HAS_E7_ENABLE (PIN_EXISTS(E7_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E7))) -#define HAS_E7_DIR (PIN_EXISTS(E7_DIR)) -#define HAS_E7_STEP (PIN_EXISTS(E7_STEP)) -#define HAS_E7_MICROSTEPS (PIN_EXISTS(E7_MS1)) -#define HAS_SOLENOID_7 (PIN_EXISTS(SOL7)) +#if PIN_EXISTS(E0_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E0)) + #define HAS_E0_ENABLE 1 +#endif +#if PIN_EXISTS(E0_DIR) + #define HAS_E0_DIR 1 +#endif +#if PIN_EXISTS(E0_STEP) + #define HAS_E0_STEP 1 +#endif +#if PIN_EXISTS(E0_MS1) + #define HAS_E0_MS_PINS 1 +#endif +#if PIN_EXISTS(SOL0) + #define HAS_SOLENOID_0 1 +#endif + +#if PIN_EXISTS(E1_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E1)) + #define HAS_E1_ENABLE 1 +#endif +#if PIN_EXISTS(E1_DIR) + #define HAS_E1_DIR 1 +#endif +#if PIN_EXISTS(E1_STEP) + #define HAS_E1_STEP 1 +#endif +#if PIN_EXISTS(E1_MS1) + #define HAS_E1_MS_PINS 1 +#endif +#if PIN_EXISTS(SOL1) + #define HAS_SOLENOID_1 1 +#endif + +#if PIN_EXISTS(E2_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E2)) + #define HAS_E2_ENABLE 1 +#endif +#if PIN_EXISTS(E2_DIR) + #define HAS_E2_DIR 1 +#endif +#if PIN_EXISTS(E2_STEP) + #define HAS_E2_STEP 1 +#endif +#if PIN_EXISTS(E2_MS1) + #define HAS_E2_MS_PINS 1 +#endif +#if PIN_EXISTS(SOL2) + #define HAS_SOLENOID_2 1 +#endif + +#if PIN_EXISTS(E3_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E3)) + #define HAS_E3_ENABLE 1 +#endif +#if PIN_EXISTS(E3_DIR) + #define HAS_E3_DIR 1 +#endif +#if PIN_EXISTS(E3_STEP) + #define HAS_E3_STEP 1 +#endif +#if PIN_EXISTS(E3_MS1) + #define HAS_E3_MS_PINS 1 +#endif +#if PIN_EXISTS(SOL3) + #define HAS_SOLENOID_3 1 +#endif + +#if PIN_EXISTS(E4_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E4)) + #define HAS_E4_ENABLE 1 +#endif +#if PIN_EXISTS(E4_DIR) + #define HAS_E4_DIR 1 +#endif +#if PIN_EXISTS(E4_STEP) + #define HAS_E4_STEP 1 +#endif +#if PIN_EXISTS(E4_MS1) + #define HAS_E4_MS_PINS 1 +#endif +#if PIN_EXISTS(SOL4) + #define HAS_SOLENOID_4 1 +#endif + +#if PIN_EXISTS(E5_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E5)) + #define HAS_E5_ENABLE 1 +#endif +#if PIN_EXISTS(E5_DIR) + #define HAS_E5_DIR 1 +#endif +#if PIN_EXISTS(E5_STEP) + #define HAS_E5_STEP 1 +#endif +#if PIN_EXISTS(E5_MS1) + #define HAS_E5_MS_PINS 1 +#endif +#if PIN_EXISTS(SOL5) + #define HAS_SOLENOID_5 1 +#endif +#if PIN_EXISTS(E6_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E6)) + #define HAS_E6_ENABLE 1 +#endif +#if PIN_EXISTS(E6_DIR) + #define HAS_E6_DIR 1 +#endif +#if PIN_EXISTS(E6_STEP) + #define HAS_E6_STEP 1 +#endif +#if PIN_EXISTS(E6_MS1) + #define HAS_E6_MS_PINS 1 +#endif +#if PIN_EXISTS(SOL6) + #define HAS_SOLENOID_6 1 +#endif + +#if PIN_EXISTS(E7_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E7)) + #define HAS_E7_ENABLE 1 +#endif +#if PIN_EXISTS(E7_DIR) + #define HAS_E7_DIR 1 +#endif +#if PIN_EXISTS(E7_STEP) + #define HAS_E7_STEP 1 +#endif +#if PIN_EXISTS(E7_MS1) + #define HAS_E7_MS_PINS 1 +#endif +#if PIN_EXISTS(SOL7) + #define HAS_SOLENOID_7 1 +#endif + +// // Trinamic Stepper Drivers -#if HAS_TRINAMIC - #define STEALTHCHOP_ENABLED ANY(STEALTHCHOP_XY, STEALTHCHOP_Z, STEALTHCHOP_E) - #define USE_SENSORLESS EITHER(SENSORLESS_HOMING, SENSORLESS_PROBING) +// + +#if HAS_TRINAMIC_CONFIG + #if ANY(STEALTHCHOP_XY, STEALTHCHOP_Z, STEALTHCHOP_E) + #define STEALTHCHOP_ENABLED 1 + #endif + #if EITHER(SENSORLESS_HOMING, SENSORLESS_PROBING) + #define USE_SENSORLESS 1 + #endif // Disable Z axis sensorless homing if a probe is used to home the Z axis #if HOMING_Z_WITH_PROBE #undef Z_STALL_SENSITIVITY + #undef Z2_STALL_SENSITIVITY + #undef Z3_STALL_SENSITIVITY + #undef Z4_STALL_SENSITIVITY + #endif + #if defined(X_STALL_SENSITIVITY) && AXIS_HAS_STALLGUARD(X) + #define X_SENSORLESS 1 + #endif + #if defined(X2_STALL_SENSITIVITY) && AXIS_HAS_STALLGUARD(X2) + #define X2_SENSORLESS 1 + #endif + #if defined(Y_STALL_SENSITIVITY) && AXIS_HAS_STALLGUARD(Y) + #define Y_SENSORLESS 1 + #endif + #if defined(Y2_STALL_SENSITIVITY) && AXIS_HAS_STALLGUARD(Y2) + #define Y2_SENSORLESS 1 + #endif + #if defined(Z_STALL_SENSITIVITY) && AXIS_HAS_STALLGUARD(Z) + #define Z_SENSORLESS 1 + #endif + #if defined(Z2_STALL_SENSITIVITY) && AXIS_HAS_STALLGUARD(Z2) + #define Z2_SENSORLESS 1 + #endif + #if defined(Z3_STALL_SENSITIVITY) && AXIS_HAS_STALLGUARD(Z3) + #define Z3_SENSORLESS 1 + #endif + #if defined(Z4_STALL_SENSITIVITY) && AXIS_HAS_STALLGUARD(Z4) + #define Z4_SENSORLESS 1 #endif - #define X_SENSORLESS (AXIS_HAS_STALLGUARD(X) && defined(X_STALL_SENSITIVITY)) - #define X2_SENSORLESS (AXIS_HAS_STALLGUARD(X2) && defined(X2_STALL_SENSITIVITY)) - #define Y_SENSORLESS (AXIS_HAS_STALLGUARD(Y) && defined(Y_STALL_SENSITIVITY)) - #define Y2_SENSORLESS (AXIS_HAS_STALLGUARD(Y2) && defined(Y2_STALL_SENSITIVITY)) - #define Z_SENSORLESS (AXIS_HAS_STALLGUARD(Z) && defined(Z_STALL_SENSITIVITY)) - #define Z2_SENSORLESS (AXIS_HAS_STALLGUARD(Z2) && defined(Z2_STALL_SENSITIVITY)) - #define Z3_SENSORLESS (AXIS_HAS_STALLGUARD(Z3) && defined(Z3_STALL_SENSITIVITY)) - #define Z4_SENSORLESS (AXIS_HAS_STALLGUARD(Z4) && defined(Z4_STALL_SENSITIVITY)) #if ENABLED(SPI_ENDSTOPS) #define X_SPI_SENSORLESS X_SENSORLESS #define Y_SPI_SENSORLESS Y_SENSORLESS @@ -1408,17 +1610,25 @@ #endif #endif -#define HAS_E_STEPPER_ENABLE (HAS_E_DRIVER(TMC2660) \ +#if (HAS_E_DRIVER(TMC2660) \ || ( E0_ENABLE_PIN != X_ENABLE_PIN && E1_ENABLE_PIN != X_ENABLE_PIN \ - && E0_ENABLE_PIN != Y_ENABLE_PIN && E1_ENABLE_PIN != Y_ENABLE_PIN ) \ -) + && E0_ENABLE_PIN != Y_ENABLE_PIN && E1_ENABLE_PIN != Y_ENABLE_PIN ) ) + #define HAS_E_STEPPER_ENABLE 1 +#endif + +#if ANY_AXIS_HAS(HW_SERIAL) + #define HAS_TMC_HW_SERIAL 1 +#endif +#if ANY_AXIS_HAS(SW_SERIAL) + #define HAS_TMC_SW_SERIAL 1 +#endif // // Endstops and bed probe // // Is an endstop plug used for extra Z endstops or the probe? -#define IS_PROBE_PIN(A,M) (HAS_CUSTOM_PROBE_PIN && Z_MIN_PROBE_PIN == P) +#define IS_PROBE_PIN(A,M) (HAS_CUSTOM_PROBE_PIN && Z_MIN_PROBE_PIN == A##_##M##_PIN) #define IS_X2_ENDSTOP(A,M) (ENABLED(X_DUAL_ENDSTOPS) && X2_USE_ENDSTOP == _##A##M##_) #define IS_Y2_ENDSTOP(A,M) (ENABLED(Y_DUAL_ENDSTOPS) && Y2_USE_ENDSTOP == _##A##M##_) #define IS_Z2_ENDSTOP(A,M) (ENABLED(Z_MULTI_ENDSTOPS) && Z2_USE_ENDSTOP == _##A##M##_) @@ -1426,146 +1636,361 @@ #define IS_Z4_ENDSTOP(A,M) (ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPER_DRIVERS >= 4 && Z4_USE_ENDSTOP == _##A##M##_) #define _HAS_STOP(A,M) (PIN_EXISTS(A##_##M) && !IS_PROBE_PIN(A,M) && !IS_X2_ENDSTOP(A,M) && !IS_Y2_ENDSTOP(A,M) && !IS_Z2_ENDSTOP(A,M) && !IS_Z3_ENDSTOP(A,M) && !IS_Z4_ENDSTOP(A,M)) -#define HAS_X_MIN _HAS_STOP(X,MIN) -#define HAS_X_MAX _HAS_STOP(X,MAX) -#define HAS_Y_MIN _HAS_STOP(Y,MIN) -#define HAS_Y_MAX _HAS_STOP(Y,MAX) -#define HAS_Z_MIN _HAS_STOP(Z,MIN) -#define HAS_Z_MAX _HAS_STOP(Z,MAX) -#define HAS_X2_MIN (PIN_EXISTS(X2_MIN)) -#define HAS_X2_MAX (PIN_EXISTS(X2_MAX)) -#define HAS_Y2_MIN (PIN_EXISTS(Y2_MIN)) -#define HAS_Y2_MAX (PIN_EXISTS(Y2_MAX)) -#define HAS_Z2_MIN (PIN_EXISTS(Z2_MIN)) -#define HAS_Z2_MAX (PIN_EXISTS(Z2_MAX)) -#define HAS_Z3_MIN (PIN_EXISTS(Z3_MIN)) -#define HAS_Z3_MAX (PIN_EXISTS(Z3_MAX)) -#define HAS_Z4_MIN (PIN_EXISTS(Z4_MIN)) -#define HAS_Z4_MAX (PIN_EXISTS(Z4_MAX)) -#define HAS_Z_MIN_PROBE_PIN (HAS_CUSTOM_PROBE_PIN && PIN_EXISTS(Z_MIN_PROBE)) +#if _HAS_STOP(X,MIN) + #define HAS_X_MIN 1 +#endif +#if _HAS_STOP(X,MAX) + #define HAS_X_MAX 1 +#endif +#if _HAS_STOP(Y,MIN) + #define HAS_Y_MIN 1 +#endif +#if _HAS_STOP(Y,MAX) + #define HAS_Y_MAX 1 +#endif +#if _HAS_STOP(Z,MIN) + #define HAS_Z_MIN 1 +#endif +#if _HAS_STOP(Z,MAX) + #define HAS_Z_MAX 1 +#endif +#if _HAS_STOP(X,STOP) + #define HAS_X_STOP 1 +#endif +#if _HAS_STOP(Y,STOP) + #define HAS_Y_STOP 1 +#endif +#if _HAS_STOP(Z,STOP) + #define HAS_Z_STOP 1 +#endif +#if PIN_EXISTS(X2_MIN) + #define HAS_X2_MIN 1 +#endif +#if PIN_EXISTS(X2_MAX) + #define HAS_X2_MAX 1 +#endif +#if PIN_EXISTS(Y2_MIN) + #define HAS_Y2_MIN 1 +#endif +#if PIN_EXISTS(Y2_MAX) + #define HAS_Y2_MAX 1 +#endif +#if PIN_EXISTS(Z2_MIN) + #define HAS_Z2_MIN 1 +#endif +#if PIN_EXISTS(Z2_MAX) + #define HAS_Z2_MAX 1 +#endif +#if PIN_EXISTS(Z3_MIN) + #define HAS_Z3_MIN 1 +#endif +#if PIN_EXISTS(Z3_MAX) + #define HAS_Z3_MAX 1 +#endif +#if PIN_EXISTS(Z4_MIN) + #define HAS_Z4_MIN 1 +#endif +#if PIN_EXISTS(Z4_MAX) + #define HAS_Z4_MAX 1 +#endif +#if HAS_CUSTOM_PROBE_PIN && PIN_EXISTS(Z_MIN_PROBE) + #define HAS_Z_MIN_PROBE_PIN 1 +#endif // // ADC Temp Sensors (Thermistor or Thermocouple with amplifier ADC interface) // #define HAS_ADC_TEST(P) (PIN_EXISTS(TEMP_##P) && TEMP_SENSOR_##P != 0 && DISABLED(HEATER_##P##_USES_MAX6675)) -#define HAS_TEMP_ADC_0 HAS_ADC_TEST(0) -#define HAS_TEMP_ADC_1 HAS_ADC_TEST(1) -#define HAS_TEMP_ADC_2 HAS_ADC_TEST(2) -#define HAS_TEMP_ADC_3 HAS_ADC_TEST(3) -#define HAS_TEMP_ADC_4 HAS_ADC_TEST(4) -#define HAS_TEMP_ADC_5 HAS_ADC_TEST(5) -#define HAS_TEMP_ADC_6 HAS_ADC_TEST(6) -#define HAS_TEMP_ADC_7 HAS_ADC_TEST(7) -#define HAS_TEMP_ADC_BED HAS_ADC_TEST(BED) -#define HAS_TEMP_ADC_PROBE HAS_ADC_TEST(PROBE) -#define HAS_TEMP_ADC_CHAMBER HAS_ADC_TEST(CHAMBER) - -#define HAS_TEMP_HOTEND ((HAS_TEMP_ADC_0 || ENABLED(HEATER_0_USES_MAX6675)) && HOTENDS) +#if HAS_ADC_TEST(0) + #define HAS_TEMP_ADC_0 1 +#endif +#if HAS_ADC_TEST(1) + #define HAS_TEMP_ADC_1 1 +#endif +#if HAS_ADC_TEST(2) + #define HAS_TEMP_ADC_2 1 +#endif +#if HAS_ADC_TEST(3) + #define HAS_TEMP_ADC_3 1 +#endif +#if HAS_ADC_TEST(4) + #define HAS_TEMP_ADC_4 1 +#endif +#if HAS_ADC_TEST(5) + #define HAS_TEMP_ADC_5 1 +#endif +#if HAS_ADC_TEST(6) + #define HAS_TEMP_ADC_6 1 +#endif +#if HAS_ADC_TEST(7) + #define HAS_TEMP_ADC_7 1 +#endif +#if HAS_ADC_TEST(BED) + #define HAS_TEMP_ADC_BED 1 +#endif +#if HAS_ADC_TEST(PROBE) + #define HAS_TEMP_ADC_PROBE 1 +#endif +#if HAS_ADC_TEST(CHAMBER) + #define HAS_TEMP_ADC_CHAMBER 1 +#endif + +#if HAS_HOTEND && EITHER(HAS_TEMP_ADC_0, HEATER_0_USES_MAX6675) + #define HAS_TEMP_HOTEND 1 +#endif #define HAS_TEMP_BED HAS_TEMP_ADC_BED #define HAS_TEMP_PROBE HAS_TEMP_ADC_PROBE #define HAS_TEMP_CHAMBER HAS_TEMP_ADC_CHAMBER #if ENABLED(JOYSTICK) - #define HAS_JOY_ADC_X PIN_EXISTS(JOY_X) - #define HAS_JOY_ADC_Y PIN_EXISTS(JOY_Y) - #define HAS_JOY_ADC_Z PIN_EXISTS(JOY_Z) - #define HAS_JOY_ADC_EN PIN_EXISTS(JOY_EN) + #if PIN_EXISTS(JOY_X) + #define HAS_JOY_ADC_X 1 + #endif + #if PIN_EXISTS(JOY_Y) + #define HAS_JOY_ADC_Y 1 + #endif + #if PIN_EXISTS(JOY_Z) + #define HAS_JOY_ADC_Z 1 + #endif + #if PIN_EXISTS(JOY_EN) + #define HAS_JOY_ADC_EN 1 + #endif #endif // Heaters -#define HAS_HEATER_0 (PIN_EXISTS(HEATER_0)) -#define HAS_HEATER_1 (PIN_EXISTS(HEATER_1)) -#define HAS_HEATER_2 (PIN_EXISTS(HEATER_2)) -#define HAS_HEATER_3 (PIN_EXISTS(HEATER_3)) -#define HAS_HEATER_4 (PIN_EXISTS(HEATER_4)) -#define HAS_HEATER_5 (PIN_EXISTS(HEATER_5)) -#define HAS_HEATER_6 (PIN_EXISTS(HEATER_6)) -#define HAS_HEATER_7 (PIN_EXISTS(HEATER_7)) -#define HAS_HEATER_BED (PIN_EXISTS(HEATER_BED)) +#if PIN_EXISTS(HEATER_0) + #define HAS_HEATER_0 1 +#endif +#if PIN_EXISTS(HEATER_1) + #define HAS_HEATER_1 1 +#endif +#if PIN_EXISTS(HEATER_2) + #define HAS_HEATER_2 1 +#endif +#if PIN_EXISTS(HEATER_3) + #define HAS_HEATER_3 1 +#endif +#if PIN_EXISTS(HEATER_4) + #define HAS_HEATER_4 1 +#endif +#if PIN_EXISTS(HEATER_5) + #define HAS_HEATER_5 1 +#endif +#if PIN_EXISTS(HEATER_6) + #define HAS_HEATER_6 1 +#endif +#if PIN_EXISTS(HEATER_7) + #define HAS_HEATER_7 1 +#endif +#if PIN_EXISTS(HEATER_BED) + #define HAS_HEATER_BED 1 +#endif // Shorthand for common combinations -#define HAS_HEATED_BED (HAS_TEMP_BED && HAS_HEATER_BED) -#define BED_OR_CHAMBER (HAS_HEATED_BED || HAS_TEMP_CHAMBER) -#define HAS_TEMP_SENSOR (HAS_TEMP_HOTEND || BED_OR_CHAMBER || HAS_TEMP_PROBE) -#define HAS_HEATED_CHAMBER (HAS_TEMP_CHAMBER && PIN_EXISTS(HEATER_CHAMBER)) +#if HAS_TEMP_BED && HAS_HEATER_BED + #define HAS_HEATED_BED 1 + #ifndef BED_OVERSHOOT + #define BED_OVERSHOOT 10 + #endif + #define BED_MAX_TARGET (BED_MAXTEMP - (BED_OVERSHOOT)) +#endif +#if HAS_HEATED_BED || HAS_TEMP_CHAMBER + #define BED_OR_CHAMBER 1 +#endif +#if HAS_TEMP_HOTEND || BED_OR_CHAMBER || HAS_TEMP_PROBE + #define HAS_TEMP_SENSOR 1 +#endif +#if HAS_TEMP_CHAMBER && PIN_EXISTS(HEATER_CHAMBER) + #define HAS_HEATED_CHAMBER 1 +#endif // PID heating #if !HAS_HEATED_BED #undef PIDTEMPBED #endif -#define HAS_PID_HEATING EITHER(PIDTEMP, PIDTEMPBED) -#define HAS_PID_FOR_BOTH BOTH(PIDTEMP, PIDTEMPBED) +#if EITHER(PIDTEMP, PIDTEMPBED) + #define HAS_PID_HEATING 1 +#endif +#if BOTH(PIDTEMP, PIDTEMPBED) + #define HAS_PID_FOR_BOTH 1 +#endif // Thermal protection -#define HAS_THERMALLY_PROTECTED_BED (HAS_HEATED_BED && ENABLED(THERMAL_PROTECTION_BED)) -#define WATCH_HOTENDS (ENABLED(THERMAL_PROTECTION_HOTENDS) && WATCH_TEMP_PERIOD > 0) -#define WATCH_BED (HAS_THERMALLY_PROTECTED_BED && WATCH_BED_TEMP_PERIOD > 0) -#define WATCH_CHAMBER (HAS_HEATED_CHAMBER && ENABLED(THERMAL_PROTECTION_CHAMBER) && WATCH_CHAMBER_TEMP_PERIOD > 0) +#if BOTH(HAS_HEATED_BED, THERMAL_PROTECTION_BED) + #define HAS_THERMALLY_PROTECTED_BED 1 +#endif +#if ENABLED(THERMAL_PROTECTION_HOTENDS) && WATCH_TEMP_PERIOD > 0 + #define WATCH_HOTENDS 1 +#endif +#if HAS_THERMALLY_PROTECTED_BED && WATCH_BED_TEMP_PERIOD > 0 + #define WATCH_BED 1 +#endif +#if BOTH(HAS_HEATED_CHAMBER, THERMAL_PROTECTION_CHAMBER) && WATCH_CHAMBER_TEMP_PERIOD > 0 + #define WATCH_CHAMBER 1 +#endif +#if (ENABLED(THERMAL_PROTECTION_HOTENDS) || !EXTRUDERS) \ + && (ENABLED(THERMAL_PROTECTION_BED) || !HAS_HEATED_BED) \ + && (ENABLED(THERMAL_PROTECTION_CHAMBER) || !HAS_HEATED_CHAMBER) + #define THERMALLY_SAFE 1 +#endif // Auto fans -#define HAS_AUTO_FAN_0 (HOTENDS > 0 && PIN_EXISTS(E0_AUTO_FAN)) -#define HAS_AUTO_FAN_1 (HOTENDS > 1 && PIN_EXISTS(E1_AUTO_FAN)) -#define HAS_AUTO_FAN_2 (HOTENDS > 2 && PIN_EXISTS(E2_AUTO_FAN)) -#define HAS_AUTO_FAN_3 (HOTENDS > 3 && PIN_EXISTS(E3_AUTO_FAN)) -#define HAS_AUTO_FAN_4 (HOTENDS > 4 && PIN_EXISTS(E4_AUTO_FAN)) -#define HAS_AUTO_FAN_5 (HOTENDS > 5 && PIN_EXISTS(E5_AUTO_FAN)) -#define HAS_AUTO_FAN_6 (HOTENDS > 6 && PIN_EXISTS(E6_AUTO_FAN)) -#define HAS_AUTO_FAN_7 (HOTENDS > 7 && PIN_EXISTS(E7_AUTO_FAN)) -#define HAS_AUTO_CHAMBER_FAN (HAS_TEMP_CHAMBER && PIN_EXISTS(CHAMBER_AUTO_FAN)) - -#define HAS_AUTO_FAN (HAS_AUTO_FAN_0 || HAS_AUTO_FAN_1 || HAS_AUTO_FAN_2 || HAS_AUTO_FAN_3 || HAS_AUTO_FAN_4 || HAS_AUTO_FAN_5 || HAS_AUTO_FAN_6 || HAS_AUTO_FAN_7 || HAS_AUTO_CHAMBER_FAN) +#if HAS_HOTEND && PIN_EXISTS(E0_AUTO_FAN) + #define HAS_AUTO_FAN_0 1 +#endif +#if HAS_MULTI_HOTEND && PIN_EXISTS(E1_AUTO_FAN) + #define HAS_AUTO_FAN_1 1 +#endif +#if HOTENDS > 2 && PIN_EXISTS(E2_AUTO_FAN) + #define HAS_AUTO_FAN_2 1 +#endif +#if HOTENDS > 3 && PIN_EXISTS(E3_AUTO_FAN) + #define HAS_AUTO_FAN_3 1 +#endif +#if HOTENDS > 4 && PIN_EXISTS(E4_AUTO_FAN) + #define HAS_AUTO_FAN_4 1 +#endif +#if HOTENDS > 5 && PIN_EXISTS(E5_AUTO_FAN) + #define HAS_AUTO_FAN_5 1 +#endif +#if HOTENDS > 6 && PIN_EXISTS(E6_AUTO_FAN) + #define HAS_AUTO_FAN_6 1 +#endif +#if HOTENDS > 7 && PIN_EXISTS(E7_AUTO_FAN) + #define HAS_AUTO_FAN_7 1 +#endif +#if HAS_TEMP_CHAMBER && PIN_EXISTS(CHAMBER_AUTO_FAN) + #define HAS_AUTO_CHAMBER_FAN 1 +#endif + +#if ANY(HAS_AUTO_FAN_0, HAS_AUTO_FAN_1, HAS_AUTO_FAN_2, HAS_AUTO_FAN_3, HAS_AUTO_FAN_4, HAS_AUTO_FAN_5, HAS_AUTO_FAN_6, HAS_AUTO_FAN_7, HAS_AUTO_CHAMBER_FAN) + #define HAS_AUTO_FAN 1 +#endif #define _FANOVERLAP(A,B) (A##_AUTO_FAN_PIN == E##B##_AUTO_FAN_PIN) -#if HAS_AUTO_FAN - #define AUTO_CHAMBER_IS_E (_FANOVERLAP(CHAMBER,0) || _FANOVERLAP(CHAMBER,1) || _FANOVERLAP(CHAMBER,2) || _FANOVERLAP(CHAMBER,3) || _FANOVERLAP(CHAMBER,4) || _FANOVERLAP(CHAMBER,5) || _FANOVERLAP(CHAMBER,6) || _FANOVERLAP(CHAMBER,7)) +#if HAS_AUTO_FAN && (_FANOVERLAP(CHAMBER,0) || _FANOVERLAP(CHAMBER,1) || _FANOVERLAP(CHAMBER,2) || _FANOVERLAP(CHAMBER,3) || _FANOVERLAP(CHAMBER,4) || _FANOVERLAP(CHAMBER,5) || _FANOVERLAP(CHAMBER,6) || _FANOVERLAP(CHAMBER,7)) + #define AUTO_CHAMBER_IS_E 1 #endif #if !HAS_TEMP_SENSOR #undef AUTO_REPORT_TEMPERATURES #endif +#if EITHER(AUTO_REPORT_TEMPERATURES, AUTO_REPORT_SD_STATUS) + #define HAS_AUTO_REPORTING 1 +#endif #if !HAS_AUTO_CHAMBER_FAN || AUTO_CHAMBER_IS_E #undef AUTO_POWER_CHAMBER_FAN #endif -// Other fans -#define HAS_FAN0 (PIN_EXISTS(FAN)) -#define _HAS_FAN(P) (PIN_EXISTS(FAN##P) && CONTROLLER_FAN_PIN != FAN##P##_PIN && E0_AUTO_FAN_PIN != FAN##P##_PIN && E1_AUTO_FAN_PIN != FAN##P##_PIN && E2_AUTO_FAN_PIN != FAN##P##_PIN && E3_AUTO_FAN_PIN != FAN##P##_PIN && E4_AUTO_FAN_PIN != FAN##P##_PIN && E5_AUTO_FAN_PIN != FAN##P##_PIN && E6_AUTO_FAN_PIN != FAN##P##_PIN && E7_AUTO_FAN_PIN != FAN##P##_PIN) -#define HAS_FAN1 _HAS_FAN(1) -#define HAS_FAN2 _HAS_FAN(2) -#define HAS_FAN3 _HAS_FAN(3) -#define HAS_FAN4 _HAS_FAN(4) -#define HAS_FAN5 _HAS_FAN(5) -#define HAS_FAN6 _HAS_FAN(6) -#define HAS_FAN7 _HAS_FAN(7) -#define HAS_CONTROLLER_FAN (PIN_EXISTS(CONTROLLER_FAN)) +// Print Cooling fans (limit) +#ifdef NUM_M106_FANS + #define MAX_FANS NUM_M106_FANS +#else + #define MAX_FANS 8 // Max supported fans +#endif + +#define _NOT_E_AUTO(N,F) (E##N##_AUTO_FAN_PIN != FAN##F##_PIN) +#define _HAS_FAN(F) (PIN_EXISTS(FAN##F) \ + && CONTROLLER_FAN_PIN != FAN##F##_PIN \ + && _NOT_E_AUTO(0,F) \ + && _NOT_E_AUTO(1,F) \ + && _NOT_E_AUTO(2,F) \ + && _NOT_E_AUTO(3,F) \ + && _NOT_E_AUTO(4,F) \ + && _NOT_E_AUTO(5,F) \ + && _NOT_E_AUTO(6,F) \ + && _NOT_E_AUTO(7,F) \ + && F < MAX_FANS) +#if PIN_EXISTS(FAN) + #define HAS_FAN0 1 +#endif +#if _HAS_FAN(1) + #define HAS_FAN1 1 +#endif +#if _HAS_FAN(2) + #define HAS_FAN2 1 +#endif +#if _HAS_FAN(3) + #define HAS_FAN3 1 +#endif +#if _HAS_FAN(4) + #define HAS_FAN4 1 +#endif +#if _HAS_FAN(5) + #define HAS_FAN5 1 +#endif +#if _HAS_FAN(6) + #define HAS_FAN6 1 +#endif +#if _HAS_FAN(7) + #define HAS_FAN7 1 +#endif +#undef _NOT_E_AUTO +#undef _HAS_FAN +#if PIN_EXISTS(CONTROLLER_FAN) + #define HAS_CONTROLLER_FAN 1 +#endif + +#if BED_OR_CHAMBER || HAS_FAN0 + #define BED_OR_CHAMBER_OR_FAN 1 +#endif // Servos -#define HAS_SERVO_0 (PIN_EXISTS(SERVO0) && NUM_SERVOS > 0) -#define HAS_SERVO_1 (PIN_EXISTS(SERVO1) && NUM_SERVOS > 1) -#define HAS_SERVO_2 (PIN_EXISTS(SERVO2) && NUM_SERVOS > 2) -#define HAS_SERVO_3 (PIN_EXISTS(SERVO3) && NUM_SERVOS > 3) -#define HAS_SERVOS (NUM_SERVOS > 0) +#if PIN_EXISTS(SERVO0) && NUM_SERVOS > 0 + #define HAS_SERVO_0 1 +#endif +#if PIN_EXISTS(SERVO1) && NUM_SERVOS > 1 + #define HAS_SERVO_1 1 +#endif +#if PIN_EXISTS(SERVO2) && NUM_SERVOS > 2 + #define HAS_SERVO_2 1 +#endif +#if PIN_EXISTS(SERVO3) && NUM_SERVOS > 3 + #define HAS_SERVO_3 1 +#endif +#if NUM_SERVOS > 0 + #define HAS_SERVOS 1 +#endif // Sensors -#define HAS_FILAMENT_WIDTH_SENSOR (PIN_EXISTS(FILWIDTH)) +#if PIN_EXISTS(FILWIDTH) + #define HAS_FILAMENT_WIDTH_SENSOR 1 +#endif // User Interface -#define HAS_HOME (PIN_EXISTS(HOME)) -#define HAS_KILL (PIN_EXISTS(KILL)) -#define HAS_SUICIDE (PIN_EXISTS(SUICIDE)) -#define HAS_PHOTOGRAPH (PIN_EXISTS(PHOTOGRAPH)) -#define HAS_BUZZER (PIN_EXISTS(BEEPER) || EITHER(LCD_USE_I2C_BUZZER, PCA9632_BUZZER)) -#define USE_BEEPER (HAS_BUZZER && DISABLED(LCD_USE_I2C_BUZZER, PCA9632_BUZZER)) -#define HAS_CASE_LIGHT (PIN_EXISTS(CASE_LIGHT) && ENABLED(CASE_LIGHT_ENABLE)) +#if PIN_EXISTS(HOME) + #define HAS_HOME 1 +#endif +#if PIN_EXISTS(KILL) + #define HAS_KILL 1 +#endif +#if PIN_EXISTS(SUICIDE) + #define HAS_SUICIDE 1 +#endif +#if PIN_EXISTS(PHOTOGRAPH) + #define HAS_PHOTOGRAPH 1 +#endif // Digital control -#define HAS_STEPPER_RESET (PIN_EXISTS(STEPPER_RESET)) -#define HAS_DIGIPOTSS (PIN_EXISTS(DIGIPOTSS)) -#define HAS_MOTOR_CURRENT_PWM ANY_PIN(MOTOR_CURRENT_PWM_X, MOTOR_CURRENT_PWM_Y, MOTOR_CURRENT_PWM_XY, MOTOR_CURRENT_PWM_Z, MOTOR_CURRENT_PWM_E) +#if PIN_EXISTS(STEPPER_RESET) + #define HAS_STEPPER_RESET 1 +#endif +#if PIN_EXISTS(DIGIPOTSS) + #define HAS_MOTOR_CURRENT_SPI 1 +#endif +#if ANY_PIN(MOTOR_CURRENT_PWM_X, MOTOR_CURRENT_PWM_Y, MOTOR_CURRENT_PWM_XY, MOTOR_CURRENT_PWM_Z, MOTOR_CURRENT_PWM_E) + #define HAS_MOTOR_CURRENT_PWM 1 +#endif -#define HAS_SOME_Z_MICROSTEPS (HAS_Z_MICROSTEPS || HAS_Z2_MICROSTEPS || HAS_Z3_MICROSTEPS || HAS_Z4_MICROSTEPS) -#define HAS_SOME_E_MICROSTEPS (HAS_E0_MICROSTEPS || HAS_E1_MICROSTEPS || HAS_E2_MICROSTEPS || HAS_E3_MICROSTEPS || HAS_E4_MICROSTEPS || HAS_E5_MICROSTEPS || HAS_E6_MICROSTEPS || HAS_E7_MICROSTEPS) -#define HAS_MICROSTEPS (HAS_X_MICROSTEPS || HAS_X2_MICROSTEPS || HAS_Y_MICROSTEPS || HAS_Y2_MICROSTEPS || HAS_SOME_Z_MICROSTEPS || HAS_SOME_E_MICROSTEPS) +#if ANY(HAS_Z_MS_PINS, HAS_Z2_MS_PINS, HAS_Z3_MS_PINS, HAS_Z4_MS_PINS) + #define HAS_SOME_Z_MS_PINS 1 +#endif +#if ANY(HAS_E0_MS_PINS, HAS_E1_MS_PINS, HAS_E2_MS_PINS, HAS_E3_MS_PINS, HAS_E4_MS_PINS, HAS_E5_MS_PINS, HAS_E6_MS_PINS, HAS_E7_MS_PINS) + #define HAS_SOME_E_MS_PINS 1 +#endif +#if ANY(HAS_X_MS_PINS, HAS_X2_MS_PINS, HAS_Y_MS_PINS, HAS_Y2_MS_PINS, HAS_SOME_Z_MS_PINS, HAS_SOME_E_MS_PINS) + #define HAS_MICROSTEPS 1 +#endif #if HAS_MICROSTEPS @@ -1607,31 +2032,33 @@ #endif #endif - #define HAS_MICROSTEP1 defined(MICROSTEP1) - #define HAS_MICROSTEP2 defined(MICROSTEP2) - #define HAS_MICROSTEP4 defined(MICROSTEP4) - #define HAS_MICROSTEP8 defined(MICROSTEP8) - #define HAS_MICROSTEP16 defined(MICROSTEP16) - #define HAS_MICROSTEP32 defined(MICROSTEP32) - #define HAS_MICROSTEP64 defined(MICROSTEP64) - #define HAS_MICROSTEP128 defined(MICROSTEP128) + #ifdef MICROSTEP1 + #define HAS_MICROSTEP1 1 + #endif + #ifdef MICROSTEP2 + #define HAS_MICROSTEP2 1 + #endif + #ifdef MICROSTEP4 + #define HAS_MICROSTEP4 1 + #endif + #ifdef MICROSTEP8 + #define HAS_MICROSTEP8 1 + #endif + #ifdef MICROSTEP16 + #define HAS_MICROSTEP16 1 + #endif + #ifdef MICROSTEP32 + #define HAS_MICROSTEP32 1 + #endif + #ifdef MICROSTEP64 + #define HAS_MICROSTEP64 1 + #endif + #ifdef MICROSTEP128 + #define HAS_MICROSTEP128 1 + #endif #endif // HAS_MICROSTEPS -#if !HAS_TEMP_SENSOR - #undef AUTO_REPORT_TEMPERATURES -#endif - -#define HAS_AUTO_REPORTING EITHER(AUTO_REPORT_TEMPERATURES, AUTO_REPORT_SD_STATUS) - -/** - * This setting is also used by M109 when trying to calculate - * a ballpark safe margin to prevent wait-forever situation. - */ -#ifndef EXTRUDE_MINTEMP - #define EXTRUDE_MINTEMP 170 -#endif - /** * Heater signal inversion defaults */ @@ -1666,7 +2093,7 @@ */ #define WRITE_HEATER_0P(v) WRITE(HEATER_0_PIN, (v) ^ HEATER_0_INVERTING) -#if HOTENDS > 1 || ENABLED(HEATERS_PARALLEL) +#if EITHER(HAS_MULTI_HOTEND, HEATERS_PARALLEL) #define WRITE_HEATER_1(v) WRITE(HEATER_1_PIN, (v) ^ HEATER_1_INVERTING) #if HOTENDS > 2 #define WRITE_HEATER_2(v) WRITE(HEATER_2_PIN, (v) ^ HEATER_2_INVERTING) @@ -1686,7 +2113,7 @@ #endif // HOTENDS > 4 #endif // HOTENDS > 3 #endif // HOTENDS > 2 -#endif // HOTENDS > 1 +#endif // HAS_MULTI_HOTEND || HEATERS_PARALLEL #if ENABLED(HEATERS_PARALLEL) #define WRITE_HEATER_0(v) { WRITE_HEATER_0P(v); WRITE_HEATER_1(v); } #else @@ -1726,6 +2153,24 @@ #define WRITE_HEATER_CHAMBER(v) WRITE(HEATER_CHAMBER_PIN, (v) ^ HEATER_CHAMBER_INVERTING) #endif +#if HAS_HOTEND || HAS_HEATED_BED || HAS_HEATED_CHAMBER + #define HAS_TEMPERATURE 1 +#endif + +#if HAS_TEMPERATURE && EITHER(HAS_LCD_MENU, DWIN_CREALITY_LCD) + #ifdef PREHEAT_5_LABEL + #define PREHEAT_COUNT 5 + #elif defined(PREHEAT_4_LABEL) + #define PREHEAT_COUNT 4 + #elif defined(PREHEAT_3_LABEL) + #define PREHEAT_COUNT 3 + #elif defined(PREHEAT_2_LABEL) + #define PREHEAT_COUNT 2 + #elif defined(PREHEAT_1_LABEL) + #define PREHEAT_COUNT 1 + #endif +#endif + /** * Up to 3 PWM fans */ @@ -1754,13 +2199,16 @@ #endif #if FAN_COUNT > 0 + #define HAS_FAN 1 #define WRITE_FAN(n, v) WRITE(FAN##n##_PIN, (v) ^ FAN_INVERTING) #endif /** * Part Cooling fan multipliexer */ -#define HAS_FANMUX PIN_EXISTS(FANMUX0) +#if PIN_EXISTS(FANMUX0) + #define HAS_FANMUX 1 +#endif /** * MIN/MAX fan PWM scaling @@ -1798,7 +2246,7 @@ /** * MIN/MAX case light PWM scaling */ -#if HAS_CASE_LIGHT +#if ENABLED(CASE_LIGHT_ENABLE) #ifndef CASE_LIGHT_MAX_PWM #define CASE_LIGHT_MAX_PWM 255 #elif !WITHIN(CASE_LIGHT_MAX_PWM, 1, 255) @@ -1810,7 +2258,7 @@ * Bed Probe dependencies */ #if HAS_BED_PROBE - #if ENABLED(ENDSTOPPULLUPS) && HAS_Z_MIN_PROBE_PIN + #if BOTH(ENDSTOPPULLUPS, HAS_Z_MIN_PROBE_PIN) #define ENDSTOPPULLUP_ZMIN_PROBE #endif #ifndef Z_PROBE_OFFSET_RANGE_MIN @@ -1870,26 +2318,6 @@ #endif #endif // SKEW_CORRECTION -/** - * Set granular options based on the specific type of leveling - */ -#define UBL_SEGMENTED BOTH(AUTO_BED_LEVELING_UBL, DELTA) -#define ABL_PLANAR EITHER(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_3POINT) -#define ABL_GRID EITHER(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_BILINEAR) -#define HAS_ABL_NOT_UBL (ABL_PLANAR || ABL_GRID) -#define HAS_ABL_OR_UBL (HAS_ABL_NOT_UBL || ENABLED(AUTO_BED_LEVELING_UBL)) -#define HAS_LEVELING (HAS_ABL_OR_UBL || ENABLED(MESH_BED_LEVELING)) -#define HAS_AUTOLEVEL (HAS_ABL_OR_UBL && DISABLED(PROBE_MANUALLY)) -#define HAS_MESH ANY(AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_UBL, MESH_BED_LEVELING) -#define PLANNER_LEVELING (HAS_LEVELING && DISABLED(AUTO_BED_LEVELING_UBL)) -#define HAS_PROBING_PROCEDURE (HAS_ABL_OR_UBL || ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST)) -#define HAS_POSITION_MODIFIERS (ENABLED(FWRETRACT) || HAS_LEVELING || ENABLED(SKEW_CORRECTION)) -#define NEEDS_THREE_PROBE_POINTS EITHER(AUTO_BED_LEVELING_UBL, AUTO_BED_LEVELING_3POINT) - -#if ENABLED(AUTO_BED_LEVELING_UBL) - #undef LCD_BED_LEVELING -#endif - /** * Heater, Fan, and Probe interactions */ @@ -1899,15 +2327,19 @@ #undef NO_FAN_SLOWING_IN_PID_TUNING #endif -#define QUIET_PROBING (HAS_BED_PROBE && (EITHER(PROBING_HEATERS_OFF, PROBING_FANS_OFF) || DELAY_BEFORE_PROBING > 0)) -#define HEATER_IDLE_HANDLER EITHER(ADVANCED_PAUSE_FEATURE, PROBING_HEATERS_OFF) +#if HAS_BED_PROBE && (EITHER(PROBING_HEATERS_OFF, PROBING_FANS_OFF) || DELAY_BEFORE_PROBING > 0) + #define QUIET_PROBING 1 +#endif +#if EITHER(ADVANCED_PAUSE_FEATURE, PROBING_HEATERS_OFF) + #define HEATER_IDLE_HANDLER 1 +#endif #if ENABLED(ADVANCED_PAUSE_FEATURE) && !defined(FILAMENT_CHANGE_SLOW_LOAD_LENGTH) #define FILAMENT_CHANGE_SLOW_LOAD_LENGTH 0 #endif -#if EXTRUDERS > 1 && !defined(TOOLCHANGE_FIL_EXTRA_PRIME) - #define TOOLCHANGE_FIL_EXTRA_PRIME 0 +#if HAS_MULTI_EXTRUDER && !defined(TOOLCHANGE_FS_EXTRA_PRIME) + #define TOOLCHANGE_FS_EXTRA_PRIME 0 #endif /** @@ -1924,31 +2356,31 @@ * Bed Probing bounds */ -#ifndef MIN_PROBE_EDGE - #define MIN_PROBE_EDGE 0 +#ifndef PROBING_MARGIN + #define PROBING_MARGIN 0 #endif #if IS_KINEMATIC - #undef MIN_PROBE_EDGE_LEFT - #undef MIN_PROBE_EDGE_RIGHT - #undef MIN_PROBE_EDGE_FRONT - #undef MIN_PROBE_EDGE_BACK - #define MIN_PROBE_EDGE_LEFT 0 - #define MIN_PROBE_EDGE_RIGHT 0 - #define MIN_PROBE_EDGE_FRONT 0 - #define MIN_PROBE_EDGE_BACK 0 + #undef PROBING_MARGIN_LEFT + #undef PROBING_MARGIN_RIGHT + #undef PROBING_MARGIN_FRONT + #undef PROBING_MARGIN_BACK + #define PROBING_MARGIN_LEFT 0 + #define PROBING_MARGIN_RIGHT 0 + #define PROBING_MARGIN_FRONT 0 + #define PROBING_MARGIN_BACK 0 #else - #ifndef MIN_PROBE_EDGE_LEFT - #define MIN_PROBE_EDGE_LEFT MIN_PROBE_EDGE + #ifndef PROBING_MARGIN_LEFT + #define PROBING_MARGIN_LEFT PROBING_MARGIN #endif - #ifndef MIN_PROBE_EDGE_RIGHT - #define MIN_PROBE_EDGE_RIGHT MIN_PROBE_EDGE + #ifndef PROBING_MARGIN_RIGHT + #define PROBING_MARGIN_RIGHT PROBING_MARGIN #endif - #ifndef MIN_PROBE_EDGE_FRONT - #define MIN_PROBE_EDGE_FRONT MIN_PROBE_EDGE + #ifndef PROBING_MARGIN_FRONT + #define PROBING_MARGIN_FRONT PROBING_MARGIN #endif - #ifndef MIN_PROBE_EDGE_BACK - #define MIN_PROBE_EDGE_BACK MIN_PROBE_EDGE + #ifndef PROBING_MARGIN_BACK + #define PROBING_MARGIN_BACK PROBING_MARGIN #endif #endif @@ -2014,13 +2446,24 @@ #undef MESH_MAX_Y #endif -#if (defined(PROBE_PT_1_X) && defined(PROBE_PT_2_X) && defined(PROBE_PT_3_X) && defined(PROBE_PT_1_Y) && defined(PROBE_PT_2_Y) && defined(PROBE_PT_3_Y)) - #define HAS_FIXED_3POINT +#define _POINT_COUNT (defined(PROBE_PT_1_X) + defined(PROBE_PT_2_X) + defined(PROBE_PT_3_X) + defined(PROBE_PT_1_Y) + defined(PROBE_PT_2_Y) + defined(PROBE_PT_3_Y)) +#if _POINT_COUNT == 6 + #define HAS_FIXED_3POINT 1 +#elif _POINT_COUNT > 0 + #error "For 3-Point Leveling all XY points must be defined (or none for the defaults)." #endif +#undef _POINT_COUNT /** * Buzzer/Speaker */ +#if PIN_EXISTS(BEEPER) || ANY(LCD_USE_I2C_BUZZER, PCA9632_BUZZER) + #define HAS_BUZZER 1 + #if PIN_EXISTS(BEEPER) + #define USE_BEEPER 1 + #endif +#endif + #if ENABLED(LCD_USE_I2C_BUZZER) #ifndef LCD_FEEDBACK_FREQUENCY_HZ #define LCD_FEEDBACK_FREQUENCY_HZ 1000 @@ -2037,10 +2480,14 @@ #endif #endif +#if HAS_BUZZER && LCD_FEEDBACK_FREQUENCY_DURATION_MS && LCD_FEEDBACK_FREQUENCY_HZ + #define HAS_CHIRP 1 +#endif + /** * Make sure DOGLCD_SCK and DOGLCD_MOSI are defined. */ -#if HAS_GRAPHICAL_LCD +#if HAS_MARLINUI_U8GLIB #ifndef DOGLCD_SCK #define DOGLCD_SCK SCK_PIN #endif @@ -2053,10 +2500,10 @@ * Z_HOMING_HEIGHT / Z_CLEARANCE_BETWEEN_PROBES */ #ifndef Z_HOMING_HEIGHT - #ifndef Z_CLEARANCE_BETWEEN_PROBES - #define Z_HOMING_HEIGHT 0 - #else + #ifdef Z_CLEARANCE_BETWEEN_PROBES #define Z_HOMING_HEIGHT Z_CLEARANCE_BETWEEN_PROBES + #else + #define Z_HOMING_HEIGHT 0 #endif #endif @@ -2084,15 +2531,16 @@ #endif // Updated G92 behavior shifts the workspace -#define HAS_POSITION_SHIFT DISABLED(NO_WORKSPACE_OFFSETS) -// The home offset also shifts the coordinate space -#define HAS_HOME_OFFSET (DISABLED(NO_WORKSPACE_OFFSETS) && IS_CARTESIAN) -// The SCARA home offset applies only on G28 -#define HAS_SCARA_OFFSET (DISABLED(NO_WORKSPACE_OFFSETS) && IS_SCARA) -// Cumulative offset to workspace to save some calculation -#define HAS_WORKSPACE_OFFSET (HAS_POSITION_SHIFT && HAS_HOME_OFFSET) -// M206 sets the home offset for Cartesian machines -#define HAS_M206_COMMAND (HAS_HOME_OFFSET && !IS_SCARA) +#if DISABLED(NO_WORKSPACE_OFFSETS) + #define HAS_POSITION_SHIFT 1 + #if IS_CARTESIAN + #define HAS_HOME_OFFSET 1 // The home offset also shifts the coordinate space + #define HAS_WORKSPACE_OFFSET 1 // Cumulative offset to workspace to save some calculation + #define HAS_M206_COMMAND 1 // M206 sets the home offset for Cartesian machines + #elif IS_SCARA + #define HAS_SCARA_OFFSET 1 // The SCARA home offset applies only on G28 + #endif +#endif // LCD timeout to status screen default is 15s #ifndef LCD_TIMEOUT_TO_STATUS @@ -2115,35 +2563,12 @@ #endif // Number of VFAT entries used. Each entry has 13 UTF-16 characters -#if ENABLED(SCROLL_LONG_FILENAMES) +#if EITHER(SCROLL_LONG_FILENAMES, DWIN_CREALITY_LCD) #define MAX_VFAT_ENTRIES (5) #else #define MAX_VFAT_ENTRIES (2) #endif -// Set defaults for unspecified LED user colors -#if ENABLED(LED_CONTROL_MENU) - #ifndef LED_USER_PRESET_RED - #define LED_USER_PRESET_RED 255 - #endif - #ifndef LED_USER_PRESET_GREEN - #define LED_USER_PRESET_GREEN 255 - #endif - #ifndef LED_USER_PRESET_BLUE - #define LED_USER_PRESET_BLUE 255 - #endif - #ifndef LED_USER_PRESET_WHITE - #define LED_USER_PRESET_WHITE 0 - #endif - #ifndef LED_USER_PRESET_BRIGHTNESS - #ifdef NEOPIXEL_BRIGHTNESS - #define LED_USER_PRESET_BRIGHTNESS NEOPIXEL_BRIGHTNESS - #else - #define LED_USER_PRESET_BRIGHTNESS 255 - #endif - #endif -#endif - // Nozzle park for Delta #if BOTH(NOZZLE_PARK_FEATURE, DELTA) #undef NOZZLE_PARK_Z_FEEDRATE @@ -2154,9 +2579,8 @@ // on boards where SD card and LCD display share the same SPI bus // because of a bug in the shared SPI implementation. (See #8122) #if defined(TARGET_LPC1768) && ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) && (SCK_PIN == LCD_PINS_D4) - #define SDCARD_SORT_ALPHA // Keeps one directory level in RAM. Changing - // directory levels still glitches the screen, - // but the following LCD update cleans it up. + #define SDCARD_SORT_ALPHA // Keep one directory level in RAM. Changing directory levels + // may still glitch the screen, but LCD updates clean it up. #undef SDSORT_LIMIT #undef SDSORT_USES_RAM #undef SDSORT_USES_STACK @@ -2180,57 +2604,34 @@ #endif // Defined here to catch the above defines -#if ENABLED(SDCARD_SORT_ALPHA) - #define HAS_FOLDER_SORTING (FOLDER_SORTING || ENABLED(SDSORT_GCODE)) +#if ENABLED(SDCARD_SORT_ALPHA) && (FOLDER_SORTING || ENABLED(SDSORT_GCODE)) + #define HAS_FOLDER_SORTING 1 #endif -// If platform requires early initialization of watchdog to properly boot -#define EARLY_WATCHDOG (ENABLED(USE_WATCHDOG) && defined(ARDUINO_ARCH_SAM)) - -#if HAS_SPI_LCD +#if HAS_WIRED_LCD // Get LCD character width/height, which may be overridden by pins, configs, etc. #ifndef LCD_WIDTH - #if HAS_GRAPHICAL_LCD + #if HAS_MARLINUI_U8GLIB #define LCD_WIDTH 21 - #elif ENABLED(ULTIPANEL) - #define LCD_WIDTH 20 #else - #define LCD_WIDTH 16 + #define LCD_WIDTH TERN(ULTIPANEL, 20, 16) #endif #endif #ifndef LCD_HEIGHT - #if HAS_GRAPHICAL_LCD + #if HAS_MARLINUI_U8GLIB #define LCD_HEIGHT 5 - #elif ENABLED(ULTIPANEL) - #define LCD_HEIGHT 4 #else - #define LCD_HEIGHT 2 + #define LCD_HEIGHT TERN(ULTIPANEL, 4, 2) #endif #endif #endif -#if ENABLED(SDSUPPORT) - #if SD_CONNECTION_IS(ONBOARD) && DISABLED(NO_SD_HOST_DRIVE) && !defined(ARDUINO_GRAND_CENTRAL_M4) - // - // The external SD card is not used. Hardware SPI is used to access the card. - // When sharing the SD card with a PC we want the menu options to - // mount/unmount the card and refresh it. So we disable card detect. - // - #undef SD_DETECT_PIN - #define SHARED_SD_CARD - #endif - #if DISABLED(SHARED_SD_CARD) - #define INIT_SDCARD_ON_BOOT - #endif +#if BUTTONS_EXIST(EN1, EN2, ENC) + #define HAS_ROTARY_ENCODER 1 #endif #if !NUM_SERIAL #undef BAUD_RATE_GCODE -#endif - -#if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS) - #undef Z_STEPPER_ALIGN_AMP -#endif -#ifndef Z_STEPPER_ALIGN_AMP - #define Z_STEPPER_ALIGN_AMP 1.0 +#elif NUM_SERIAL > 1 + #define HAS_MULTI_SERIAL 1 #endif diff --git a/Marlin/src/inc/MarlinConfig.h b/Marlin/src/inc/MarlinConfig.h index d32506702e2f..2eafa2b4171f 100644 --- a/Marlin/src/inc/MarlinConfig.h +++ b/Marlin/src/inc/MarlinConfig.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -27,19 +27,31 @@ #include "MarlinConfigPre.h" -#include "../HAL/HAL.h" +#ifndef __MARLIN_DEPS__ + #include "../HAL/HAL.h" +#endif #include "../pins/pins.h" -#include HAL_PATH(../HAL, spi_pins.h) + +#ifndef __MARLIN_DEPS__ + #include HAL_PATH(../HAL, timers.h) + #include HAL_PATH(../HAL, spi_pins.h) +#endif #include "Conditionals_post.h" -#include HAL_PATH(../HAL, inc/Conditionals_post.h) -#include "SanityCheck.h" -#include HAL_PATH(../HAL, inc/SanityCheck.h) +#ifndef __MARLIN_DEPS__ + + #include HAL_PATH(../HAL, inc/Conditionals_post.h) + + #include "../core/types.h" // Ahead of sanity-checks + + #include "SanityCheck.h" + #include HAL_PATH(../HAL, inc/SanityCheck.h) + + // Include all core headers + #include "../core/language.h" + #include "../core/utility.h" + #include "../core/serial.h" -// Include all core headers -#include "../core/types.h" -#include "../core/language.h" -#include "../core/utility.h" -#include "../core/serial.h" +#endif diff --git a/Marlin/src/inc/MarlinConfigPre.h b/Marlin/src/inc/MarlinConfigPre.h index 1385f9e19fa1..dfa0adba1bd7 100644 --- a/Marlin/src/inc/MarlinConfigPre.h +++ b/Marlin/src/inc/MarlinConfigPre.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -30,29 +30,33 @@ // #include -#include "../HAL/platforms.h" +#ifndef __MARLIN_DEPS__ + #include "../HAL/platforms.h" +#endif #include "../core/boards.h" #include "../core/macros.h" #include "../../Configuration.h" #ifdef CUSTOM_VERSION_FILE - #if defined(__has_include) - #if __has_include(XSTR(../../CUSTOM_VERSION_FILE)) - #include XSTR(../../CUSTOM_VERSION_FILE) - #endif - #else - #include XSTR(../../CUSTOM_VERSION_FILE) + #if __has_include(STRINGIFY(../../CUSTOM_VERSION_FILE)) + #include STRINGIFY(../../CUSTOM_VERSION_FILE) #endif #endif #include "Version.h" #include "Conditionals_LCD.h" -#include HAL_PATH(../HAL, inc/Conditionals_LCD.h) + +#ifndef __MARLIN_DEPS__ + #include HAL_PATH(../HAL, inc/Conditionals_LCD.h) +#endif #include "../core/drivers.h" #include "../../Configuration_adv.h" #include "Conditionals_adv.h" -#include HAL_PATH(../HAL, inc/Conditionals_adv.h) + +#ifndef __MARLIN_DEPS__ + #include HAL_PATH(../HAL, inc/Conditionals_adv.h) +#endif diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index f340e758abef..ec9b0a852da1 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -34,19 +34,49 @@ #error "Marlin requires C++11 support (gcc >= 4.7, Arduino IDE >= 1.6.8). Please upgrade your toolchain." #endif +// Make sure macros aren't borked +#define TEST1 +#define TEST2 1 +#define TEST3 0 +#define TEST4 true +#if ENABLED(TEST0) || !ENABLED(TEST2) || ENABLED(TEST3) + #error "ENABLED is borked!" +#endif +#if BOTH(TEST0, TEST1) + #error "BOTH is borked!" +#endif +#if DISABLED(TEST1) || !DISABLED(TEST3) || DISABLED(TEST4) || DISABLED(TEST0, TEST1, TEST2, TEST4) || !DISABLED(TEST0, TEST3) + #error "DISABLED is borked!" +#endif +#if !ANY(TEST1, TEST2, TEST3, TEST4) || ANY(TEST0, TEST3) + #error "ANY is borked!" +#endif +#if NONE(TEST0, TEST1, TEST2, TEST4) || !NONE(TEST0, TEST3) + #error "NONE is borked!" +#endif +#undef TEST1 +#undef TEST2 +#undef TEST3 +#undef TEST4 + /** - * We try our best to include sanity checks for all changed configuration - * directives because users have a tendency to use outdated config files with - * the bleeding-edge source code, but sometimes this is not enough. This check - * forces a minimum config file revision. Otherwise Marlin will not build. + * This is to alert you about non-matching versions of config files. + * + * You can edit the version tag in your old config files and try the build again. + * The checks below will alert you about options that need to be changed, but they won't + * tell you about new options that you might find useful. So it's recommended to transfer + * your settings to new Configuration files matching your Marlin version as soon as possible. */ #define HEXIFY(H) _CAT(0x,H) #if !defined(CONFIGURATION_H_VERSION) || HEXIFY(CONFIGURATION_H_VERSION) < HEXIFY(REQUIRED_CONFIGURATION_H_VERSION) - #error "You are using an old Configuration.h file, update it before building Marlin." + #error "Your Configuration.h file is for an old version of Marlin. Downgrade Marlin or upgrade your Configuration.h." +#elif HEXIFY(CONFIGURATION_H_VERSION) > HEXIFY(REQUIRED_CONFIGURATION_H_VERSION) + #error "Your Configuration.h file is for a newer version of Marlin. Upgrade Marlin or downgrade your Configuration.h." #endif - #if !defined(CONFIGURATION_ADV_H_VERSION) || HEXIFY(CONFIGURATION_ADV_H_VERSION) < HEXIFY(REQUIRED_CONFIGURATION_ADV_H_VERSION) - #error "You are using an old Configuration_adv.h file, update it before building Marlin." + #error "Your Configuration_adv.h file is for an old version of Marlin. Downgrade Marlin or upgrade your Configuration_adv.h." +#elif HEXIFY(CONFIGURATION_ADV_H_VERSION) > HEXIFY(REQUIRED_CONFIGURATION_ADV_H_VERSION) + #error "Your Configuration_adv.h file is for a newer version of Marlin. Upgrade Marlin or downgrade your Configuration_adv.h." #endif #undef HEXIFY @@ -68,7 +98,9 @@ #elif defined(X_HOME_RETRACT_MM) #error "[XYZ]_HOME_RETRACT_MM settings have been renamed [XYZ]_HOME_BUMP_MM." #elif defined(SDCARDDETECTINVERTED) - #error "SDCARDDETECTINVERTED is now SD_DETECT_INVERTED. Please update your configuration." + #error "SDCARDDETECTINVERTED is now SD_DETECT_STATE (HIGH). Please update your configuration." +#elif defined(SD_DETECT_INVERTED) + #error "SD_DETECT_INVERTED is now SD_DETECT_STATE (HIGH). Please update your configuration." #elif defined(BTENABLED) #error "BTENABLED is now BLUETOOTH. Please update your configuration." #elif defined(CUSTOM_MENDEL_NAME) @@ -229,7 +261,7 @@ #error "LCD_PIN_RESET is now LCD_RESET_PIN. Please update your pins definitions." #elif defined(EXTRUDER_0_AUTO_FAN_PIN) || defined(EXTRUDER_1_AUTO_FAN_PIN) || defined(EXTRUDER_2_AUTO_FAN_PIN) || defined(EXTRUDER_3_AUTO_FAN_PIN) #error "EXTRUDER_[0123]_AUTO_FAN_PIN is now E[0123]_AUTO_FAN_PIN. Please update your Configuration_adv.h." -#elif defined(PID_FAN_SCALING) && FAN_COUNT <= 0 +#elif defined(PID_FAN_SCALING) && !HAS_FAN #error "PID_FAN_SCALING needs at least one fan enabled." #elif defined(min_software_endstops) || defined(max_software_endstops) #error "(min|max)_software_endstops are now (MIN|MAX)_SOFTWARE_ENDSTOPS. Please update your configuration." @@ -237,6 +269,10 @@ #error "Replace SLED_PIN with SOL1_PIN (applies to both Z_PROBE_SLED and SOLENOID_PROBE)." #elif defined(CONTROLLERFAN_PIN) #error "CONTROLLERFAN_PIN is now CONTROLLER_FAN_PIN, enabled with USE_CONTROLLER_FAN. Please update your Configuration_adv.h." +#elif defined(CONTROLLERFAN_SPEED) + #error "CONTROLLERFAN_SPEED is now CONTROLLERFAN_SPEED_ACTIVE. Please update your Configuration_adv.h." +#elif defined(CONTROLLERFAN_SECS) + #error "CONTROLLERFAN_SECS is now CONTROLLERFAN_IDLE_TIME. Please update your Configuration_adv.h." #elif defined(MIN_RETRACT) #error "MIN_RETRACT is now MIN_AUTORETRACT and MAX_AUTORETRACT. Please update your Configuration_adv.h." #elif defined(ADVANCE) @@ -246,9 +282,9 @@ #elif defined(NEOPIXEL_RGBW_LED) #error "NEOPIXEL_RGBW_LED is now NEOPIXEL_LED. Please update your configuration." #elif ENABLED(DELTA) && defined(DELTA_PROBEABLE_RADIUS) - #error "Remove DELTA_PROBEABLE_RADIUS and use MIN_PROBE_EDGE to inset the probe area instead." + #error "Remove DELTA_PROBEABLE_RADIUS and use PROBING_MARGIN to inset the probe area instead." #elif ENABLED(DELTA) && defined(DELTA_CALIBRATION_RADIUS) - #error "Remove DELTA_CALIBRATION_RADIUS and use MIN_PROBE_EDGE to inset the probe area instead." + #error "Remove DELTA_CALIBRATION_RADIUS and use PROBING_MARGIN to inset the probe area instead." #elif defined(UBL_MESH_INSET) #error "UBL_MESH_INSET is now just MESH_INSET. Please update your configuration." #elif defined(UBL_MESH_MIN_X) || defined(UBL_MESH_MIN_Y) || defined(UBL_MESH_MAX_X) || defined(UBL_MESH_MAX_Y) @@ -257,14 +293,24 @@ #error "ABL_PROBE_PT_[123]_[XY] is no longer required. Please remove it from Configuration.h." #elif defined(UBL_PROBE_PT_1_X) || defined(UBL_PROBE_PT_1_Y) || defined(UBL_PROBE_PT_2_X) || defined(UBL_PROBE_PT_2_Y) || defined(UBL_PROBE_PT_3_X) || defined(UBL_PROBE_PT_3_Y) #error "UBL_PROBE_PT_[123]_[XY] is no longer required. Please remove it from Configuration.h." +#elif defined(MIN_PROBE_EDGE) + #error "MIN_PROBE_EDGE is now called PROBING_MARGIN. Please update your configuration." +#elif defined(MIN_PROBE_EDGE_LEFT) + #error "MIN_PROBE_EDGE_LEFT is now called PROBING_MARGIN_LEFT. Please update your configuration." +#elif defined(MIN_PROBE_EDGE_RIGHT) + #error "MIN_PROBE_EDGE_RIGHT is now called PROBING_MARGIN_RIGHT. Please update your configuration." +#elif defined(MIN_PROBE_EDGE_FRONT) + #error "MIN_PROBE_EDGE_FRONT is now called PROBING_MARGIN_FRONT. Please update your configuration." +#elif defined(MIN_PROBE_EDGE_BACK) + #error "MIN_PROBE_EDGE_BACK is now called PROBING_MARGIN_BACK. Please update your configuration." #elif defined(LEFT_PROBE_BED_POSITION) - #error "LEFT_PROBE_BED_POSITION has been replaced by MIN_PROBE_EDGE_LEFT. Please update your configuration." + #error "LEFT_PROBE_BED_POSITION is obsolete. Set a margin with PROBING_MARGIN or PROBING_MARGIN_LEFT instead." #elif defined(RIGHT_PROBE_BED_POSITION) - #error "RIGHT_PROBE_BED_POSITION has been replaced by MIN_PROBE_EDGE_RIGHT. Please update your configuration." + #error "RIGHT_PROBE_BED_POSITION is obsolete. Set a margin with PROBING_MARGIN or PROBING_MARGIN_RIGHT instead." #elif defined(FRONT_PROBE_BED_POSITION) - #error "FRONT_PROBE_BED_POSITION has been replaced by MIN_PROBE_EDGE_FRONT. Please update your configuration." + #error "FRONT_PROBE_BED_POSITION is obsolete. Set a margin with PROBING_MARGIN or PROBING_MARGIN_FRONT instead." #elif defined(BACK_PROBE_BED_POSITION) - #error "BACK_PROBE_BED_POSITION has been replaced by MIN_PROBE_EDGE_BACK. Please update your configuration." + #error "BACK_PROBE_BED_POSITION is obsolete. Set a margin with PROBING_MARGIN or PROBING_MARGIN_BACK instead." #elif defined(ENABLE_MESH_EDIT_GFX_OVERLAY) #error "ENABLE_MESH_EDIT_GFX_OVERLAY is now MESH_EDIT_GFX_OVERLAY. Please update your configuration." #elif defined(BABYSTEP_ZPROBE_GFX_REVERSE) @@ -318,7 +364,7 @@ #error "LEVEL_BED_CORNERS requires LEVEL_CORNERS_INSET_LFRB values. Please update your Configuration.h." #elif defined(BEZIER_JERK_CONTROL) #error "BEZIER_JERK_CONTROL is now S_CURVE_ACCELERATION. Please update your configuration." -#elif DISABLED(CLASSIC_JERK) && defined(JUNCTION_DEVIATION_FACTOR) +#elif HAS_JUNCTION_DEVIATION && defined(JUNCTION_DEVIATION_FACTOR) #error "JUNCTION_DEVIATION_FACTOR is now JUNCTION_DEVIATION_MM. Please update your configuration." #elif defined(JUNCTION_ACCELERATION_FACTOR) #error "JUNCTION_ACCELERATION_FACTOR is obsolete. Delete it from Configuration_adv.h." @@ -372,12 +418,16 @@ #error "SPINDLE_DIR_CHANGE is now SPINDLE_CHANGE_DIR. Please update your Configuration_adv.h." #elif defined(SPINDLE_STOP_ON_DIR_CHANGE) #error "SPINDLE_STOP_ON_DIR_CHANGE is now SPINDLE_CHANGE_DIR_STOP. Please update your Configuration_adv.h." +#elif defined(SPINDLE_LASER_ACTIVE_HIGH) + #error "SPINDLE_LASER_ACTIVE_HIGH is now SPINDLE_LASER_ACTIVE_STATE. Please update your Configuration_adv.h." #elif defined(SPINDLE_LASER_ENABLE_INVERT) - #error "SPINDLE_LASER_ENABLE_INVERT is now SPINDLE_LASER_ACTIVE_HIGH. Please update your Configuration_adv.h." + #error "SPINDLE_LASER_ENABLE_INVERT is now SPINDLE_LASER_ACTIVE_STATE. Please update your Configuration_adv.h." +#elif defined(CUTTER_POWER_DISPLAY) + #error "CUTTER_POWER_DISPLAY is now CUTTER_POWER_UNIT. Please update your Configuration_adv.h." #elif defined(CHAMBER_HEATER_PIN) #error "CHAMBER_HEATER_PIN is now HEATER_CHAMBER_PIN. Please update your configuration and/or pins." #elif defined(TMC_Z_CALIBRATION) - #error "TMC_Z_CALIBRATION has been deprecated in favor of Z_STEPPER_AUTO_ALIGN. Please update your configuration." + #error "TMC_Z_CALIBRATION has been deprecated in favor of MECHANICAL_GANTRY_CALIBRATION. Please update your configuration." #elif defined(Z_MIN_PROBE_ENDSTOP) #error "Z_MIN_PROBE_ENDSTOP is no longer required. Please remove it from Configuration.h." #elif defined(DUAL_NOZZLE_DUPLICATION_MODE) @@ -392,10 +442,12 @@ #error "USB_SD_DISABLED is now NO_SD_HOST_DRIVE. Please update your Configuration_adv.h." #elif defined(USB_SD_ONBOARD) #error "USB_SD_ONBOARD is obsolete. Disable NO_SD_HOST_DRIVE instead." +#elif defined(PSU_ACTIVE_HIGH) + #error "PSU_ACTIVE_HIGH is now PSU_ACTIVE_STATE. Please update your configuration." #elif POWER_SUPPLY == 1 - #error "Replace POWER_SUPPLY 1 by enabling PSU_CONTROL and setting PSU_ACTIVE_HIGH to 'false'." + #error "Replace POWER_SUPPLY 1 by enabling PSU_CONTROL and setting PSU_ACTIVE_STATE to 'LOW'." #elif POWER_SUPPLY == 2 - #error "Replace POWER_SUPPLY 2 by enabling PSU_CONTROL and setting PSU_ACTIVE_HIGH to 'true'." + #error "Replace POWER_SUPPLY 2 by enabling PSU_CONTROL and setting PSU_ACTIVE_STATE to 'HIGH'." #elif defined(POWER_SUPPLY) #error "POWER_SUPPLY is now obsolete. Please remove it from Configuration.h." #elif defined(MKS_ROBIN_TFT) @@ -428,6 +480,18 @@ #error "HOME_USING_SPREADCYCLE is now obsolete. Please remove it from Configuration_adv.h." #elif defined(DGUS_LCD) #error "DGUS_LCD is now DGUS_LCD_UI_(ORIGIN|FYSETC|HIPRECY). Please update your configuration." +#elif defined(DGUS_SERIAL_PORT) + #error "DGUS_SERIAL_PORT is now LCD_SERIAL_PORT. Please update your configuration." +#elif defined(DGUS_BAUDRATE) + #error "DGUS_BAUDRATE is now LCD_BAUDRATE. Please update your configuration." +#elif defined(DGUS_STATS_RX_BUFFER_OVERRUNS) + #error "DGUS_STATS_RX_BUFFER_OVERRUNS is now STATS_RX_BUFFER_OVERRUNS. Please update your configuration." +#elif defined(DGUS_SERIAL_PORT) + #error "DGUS_SERIAL_PORT is now LCD_SERIAL_PORT. Please update your configuration." +#elif defined(ANYCUBIC_LCD_SERIAL_PORT) + #error "ANYCUBIC_LCD_SERIAL_PORT is now LCD_SERIAL_PORT. Please update your configuration." +#elif defined(INTERNAL_SERIAL_PORT) + #error "INTERNAL_SERIAL_PORT is now MMU2_SERIAL_PORT. Please update your configuration." #elif defined(X_DUAL_ENDSTOPS_ADJUSTMENT) #error "X_DUAL_ENDSTOPS_ADJUSTMENT is now X2_ENDSTOP_ADJUSTMENT. Please update Configuration_adv.h." #elif defined(Y_DUAL_ENDSTOPS_ADJUSTMENT) @@ -450,6 +514,53 @@ #error "Z_TRIPLE_ENDSTOPS is now Z_MULTI_ENDSTOPS. Please update Configuration_adv.h." #elif defined(Z_QUAD_ENDSTOPS) #error "Z_QUAD_ENDSTOPS is now Z_MULTI_ENDSTOPS. Please update Configuration_adv.h." +#elif defined(DUGS_UI_MOVE_DIS_OPTION) + #error "DUGS_UI_MOVE_DIS_OPTION is spelled DGUS_UI_MOVE_DIS_OPTION. Please update Configuration_adv.h." +#elif defined(ORIG_E0_AUTO_FAN_PIN) || defined(ORIG_E1_AUTO_FAN_PIN) || defined(ORIG_E2_AUTO_FAN_PIN) || defined(ORIG_E3_AUTO_FAN_PIN) || defined(ORIG_E4_AUTO_FAN_PIN) || defined(ORIG_E5_AUTO_FAN_PIN) || defined(ORIG_E6_AUTO_FAN_PIN) || defined(ORIG_E7_AUTO_FAN_PIN) + #error "ORIG_Ex_AUTO_FAN_PIN is now just Ex_AUTO_FAN_PIN. Make sure your pins are up to date." +#elif defined(ORIG_CHAMBER_AUTO_FAN_PIN) + #error "ORIG_CHAMBER_AUTO_FAN_PIN is now just CHAMBER_AUTO_FAN_PIN. Make sure your pins are up to date." +#elif defined(HOMING_BACKOFF_MM) + #error "HOMING_BACKOFF_MM is now HOMING_BACKOFF_POST_MM. Please update Configuration_adv.h." +#elif defined(X_HOME_BUMP_MM) || defined(Y_HOME_BUMP_MM) || defined(Z_HOME_BUMP_MM) + #error "[XYZ]_HOME_BUMP_MM is now HOMING_BUMP_MM. Please update Configuration_adv.h." +#elif defined(DIGIPOT_I2C) + #error "DIGIPOT_I2C is now DIGIPOT_MCP4451 (or DIGIPOT_MCP4018). Please update Configuration_adv.h." +#elif defined(TOUCH_BUTTONS) + #error "TOUCH_BUTTONS is now TOUCH_SCREEN. Please update your Configuration.h." +#elif defined(LCD_FULL_PIXEL_HEIGHT) + #error "LCD_FULL_PIXEL_HEIGHT is deprecated and should be removed. Please update your Configuration.h." +#elif defined(LCD_FULL_PIXEL_WIDTH) + #error "LCD_FULL_PIXEL_WIDTH is deprecated and should be removed. Please update your Configuration.h." +#elif defined(FSMC_UPSCALE) + #error "FSMC_UPSCALE is now GRAPHICAL_TFT_UPSCALE. Please update your Configuration.h." +#elif defined(ANYCUBIC_TFT_MODEL) + #error "ANYCUBIC_TFT_MODEL is now ANYCUBIC_LCD_I3MEGA. Please update your Configuration.h." +#elif defined(EVENT_GCODE_SD_STOP) + #error "EVENT_GCODE_SD_STOP is now EVENT_GCODE_SD_ABORT. Please update your Configuration.h." +#elif defined(GRAPHICAL_TFT_ROTATE_180) + #error "GRAPHICAL_TFT_ROTATE_180 is now TFT_ROTATION set to TFT_ROTATE_180. Please update your Configuration.h." +#elif defined(FIL_RUNOUT_INVERTING) + #if FIL_RUNOUT_INVERTING + #error "FIL_RUNOUT_INVERTING true is now FIL_RUNOUT_STATE HIGH. Please update your Configuration.h." + #else + #error "FIL_RUNOUT_INVERTING false is now FIL_RUNOUT_STATE LOW. Please update your Configuration.h." + #endif +#endif + +/** + * Probe temp compensation requirements + */ +#if ENABLED(PROBE_TEMP_COMPENSATION) + #if defined(PTC_PARK_POS_X) || defined(PTC_PARK_POS_Y) || defined(PTC_PARK_POS_Z) + #error "PTC_PARK_POS_[XYZ] is now PTC_PARK_POS (array). Please update Configuration_adv.h." + #elif !defined(PTC_PARK_POS) + #error "PROBE_TEMP_COMPENSATION requires PTC_PARK_POS." + #elif defined(PTC_PROBE_POS_X) || defined(PTC_PROBE_POS_Y) + #error "PTC_PROBE_POS_[XY] is now PTC_PROBE_POS (array). Please update Configuration_adv.h." + #elif !defined(PTC_PROBE_POS) + #error "PROBE_TEMP_COMPENSATION requires PTC_PROBE_POS." + #endif #endif /** @@ -476,7 +587,7 @@ /** * Serial */ -#if !(defined(__AVR__) && defined(USBCON)) +#if !IS_AT90USB #if ENABLED(SERIAL_XON_XOFF) && RX_BUFFER_SIZE < 1024 #error "SERIAL_XON_XOFF requires RX_BUFFER_SIZE >= 1024 for reliable transfers without drops." #elif RX_BUFFER_SIZE && (RX_BUFFER_SIZE < 2 || !IS_POWER_OF_2(RX_BUFFER_SIZE)) @@ -488,12 +599,10 @@ #error "SERIAL_XON_XOFF and SERIAL_STATS_* features not supported on USB-native AVR devices." #endif -#if SERIAL_PORT > 7 - #error "Set SERIAL_PORT to the port on your board. Usually this is 0." -#endif - -#if defined(SERIAL_PORT_2) && NUM_SERIAL < 2 - #error "SERIAL_PORT_2 is not supported for your MOTHERBOARD. Disable it to continue." +#ifndef SERIAL_PORT + #error "SERIAL_PORT must be defined in Configuration.h" +#elif defined(SERIAL_PORT_2) && SERIAL_PORT_2 == SERIAL_PORT + #error "SERIAL_PORT_2 cannot be the same as SERIAL_PORT. Please update your configuration." #endif /** @@ -576,7 +685,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS * LCD Info Screen Style */ #if LCD_INFO_SCREEN_STYLE > 0 - #if HAS_GRAPHICAL_LCD || LCD_WIDTH < 20 || LCD_HEIGHT < 4 + #if HAS_MARLINUI_U8GLIB || LCD_WIDTH < 20 || LCD_HEIGHT < 4 #error "Alternative LCD_INFO_SCREEN_STYLE requires 20x4 Character LCD." #elif LCD_INFO_SCREEN_STYLE > 1 #error "LCD_INFO_SCREEN_STYLE only has options 0 and 1 at this time." @@ -589,17 +698,17 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #if ENABLED(LCD_PROGRESS_BAR) #if NONE(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY) #error "LCD_PROGRESS_BAR requires SDSUPPORT or LCD_SET_PROGRESS_MANUALLY." - #elif !HAS_CHARACTER_LCD - #error "LCD_PROGRESS_BAR requires a character LCD." - #elif HAS_GRAPHICAL_LCD + #elif NONE(HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL) + #error "LCD_PROGRESS_BAR only applies to HD44780 character LCD and TFTGLCD_PANEL_(SPI|I2C)." + #elif HAS_MARLINUI_U8GLIB #error "LCD_PROGRESS_BAR does not apply to graphical displays." #elif ENABLED(FILAMENT_LCD_DISPLAY) #error "LCD_PROGRESS_BAR and FILAMENT_LCD_DISPLAY are not fully compatible. Comment out this line to use both." #elif PROGRESS_MSG_EXPIRE < 0 #error "PROGRESS_MSG_EXPIRE must be greater than or equal to 0." #endif -#elif ENABLED(LCD_SET_PROGRESS_MANUALLY) && !HAS_GRAPHICAL_LCD && DISABLED(EXTENSIBLE_UI) - #error "LCD_SET_PROGRESS_MANUALLY requires LCD_PROGRESS_BAR, Graphical LCD, or EXTENSIBLE_UI." +#elif ENABLED(LCD_SET_PROGRESS_MANUALLY) && NONE(HAS_MARLINUI_U8GLIB, HAS_GRAPHICAL_TFT, HAS_MARLINUI_HD44780, EXTENSIBLE_UI) + #error "LCD_SET_PROGRESS_MANUALLY requires LCD_PROGRESS_BAR, Character LCD, Graphical LCD, TFT, or EXTENSIBLE_UI." #endif #if !HAS_LCD_MENU && ENABLED(SD_REPRINT_LAST_SELECTED_FILE) @@ -609,9 +718,9 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS /** * Custom Boot and Status screens */ -#if ENABLED(SHOW_CUSTOM_BOOTSCREEN) && !(HAS_GRAPHICAL_LCD || ENABLED(TOUCH_UI_FTDI_EVE)) +#if ENABLED(SHOW_CUSTOM_BOOTSCREEN) && NONE(HAS_MARLINUI_U8GLIB, TOUCH_UI_FTDI_EVE) #error "SHOW_CUSTOM_BOOTSCREEN requires Graphical LCD or TOUCH_UI_FTDI_EVE." -#elif ENABLED(CUSTOM_STATUS_SCREEN_IMAGE) && !HAS_GRAPHICAL_LCD +#elif ENABLED(CUSTOM_STATUS_SCREEN_IMAGE) && !HAS_MARLINUI_U8GLIB #error "CUSTOM_STATUS_SCREEN_IMAGE requires a Graphical LCD." #endif @@ -649,8 +758,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #endif #endif -#if defined(EVENT_GCODE_SD_STOP) && DISABLED(NOZZLE_PARK_FEATURE) - static_assert(nullptr == strstr(EVENT_GCODE_SD_STOP, "G27"), "NOZZLE_PARK_FEATURE is required to use G27 in EVENT_GCODE_SD_STOP."); +#if defined(EVENT_GCODE_SD_ABORT) && DISABLED(NOZZLE_PARK_FEATURE) + static_assert(nullptr == strstr(EVENT_GCODE_SD_ABORT, "G27"), "NOZZLE_PARK_FEATURE is required to use G27 in EVENT_GCODE_SD_ABORT."); #endif /** @@ -670,13 +779,15 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #if ENABLED(BABYSTEPPING) #if ENABLED(SCARA) #error "BABYSTEPPING is not implemented for SCARA yet." + #elif BOTH(MARKFORGED_XY, BABYSTEP_XY) + #error "BABYSTEPPING only implemented for Z axis on MarkForged." #elif BOTH(DELTA, BABYSTEP_XY) #error "BABYSTEPPING only implemented for Z axis on deltabots." #elif BOTH(BABYSTEP_ZPROBE_OFFSET, MESH_BED_LEVELING) #error "MESH_BED_LEVELING and BABYSTEP_ZPROBE_OFFSET is not a valid combination" #elif ENABLED(BABYSTEP_ZPROBE_OFFSET) && !HAS_BED_PROBE #error "BABYSTEP_ZPROBE_OFFSET requires a probe." - #elif ENABLED(BABYSTEP_ZPROBE_GFX_OVERLAY) && !HAS_GRAPHICAL_LCD + #elif ENABLED(BABYSTEP_ZPROBE_GFX_OVERLAY) && !HAS_MARLINUI_U8GLIB #error "BABYSTEP_ZPROBE_GFX_OVERLAY requires a Graphical LCD." #elif ENABLED(BABYSTEP_ZPROBE_GFX_OVERLAY) && DISABLED(BABYSTEP_ZPROBE_OFFSET) #error "BABYSTEP_ZPROBE_GFX_OVERLAY requires a BABYSTEP_ZPROBE_OFFSET." @@ -684,6 +795,17 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "BABYSTEP_HOTEND_Z_OFFSET requires 2 or more HOTENDS." #elif BOTH(BABYSTEP_ALWAYS_AVAILABLE, MOVE_Z_WHEN_IDLE) #error "BABYSTEP_ALWAYS_AVAILABLE and MOVE_Z_WHEN_IDLE are incompatible." + #elif !defined(BABYSTEP_MULTIPLICATOR_Z) + #error "BABYSTEPPING requires BABYSTEP_MULTIPLICATOR_Z." + #elif ENABLED(BABYSTEP_XY) && !defined(BABYSTEP_MULTIPLICATOR_XY) + #error "BABYSTEP_XY requires BABYSTEP_MULTIPLICATOR_XY." + #elif ENABLED(BABYSTEP_MILLIMETER_UNITS) + static_assert(BABYSTEP_MULTIPLICATOR_Z <= 0.1f, "BABYSTEP_MULTIPLICATOR_Z must be less or equal to 0.1mm."); + #if ENABLED(BABYSTEP_XY) + static_assert(BABYSTEP_MULTIPLICATOR_XY <= 0.25f, "BABYSTEP_MULTIPLICATOR_XY must be less than or equal to 0.25mm."); + #endif + #elif ENABLED(BABYSTEP_DISPLAY_TOTAL) && ANY(TFT_320x240, TFT_320x240_SPI, TFT_480x320, TFT_480x320_SPI) + #error "New Color UI (TFT_320x240, TFT_320x240_SPI, TFT_480x320, TFT_480x320_SPI) does not support BABYSTEP_DISPLAY_TOTAL yet." #endif #endif @@ -719,7 +841,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS */ #if ENABLED(ADVANCED_PAUSE_FEATURE) #if !HAS_RESUME_CONTINUE - #error "ADVANCED_PAUSE_FEATURE currently requires an LCD controller or EMERGENCY_PARSER." + #error "ADVANCED_PAUSE_FEATURE requires a supported LCD controller (or EMERGENCY_PARSER)." #elif DISABLED(NOZZLE_PARK_FEATURE) #error "ADVANCED_PAUSE_FEATURE requires NOZZLE_PARK_FEATURE." #elif !defined(FILAMENT_UNLOAD_PURGE_FEEDRATE) @@ -742,6 +864,10 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #if ENABLED(NOZZLE_PARK_FEATURE) constexpr float npp[] = NOZZLE_PARK_POINT; static_assert(COUNT(npp) == XYZ, "NOZZLE_PARK_POINT requires X, Y, and Z values."); + constexpr xyz_pos_t npp_xyz = NOZZLE_PARK_POINT; + static_assert(WITHIN(npp_xyz.x, X_MIN_POS, X_MAX_POS), "NOZZLE_PARK_POINT.X is out of bounds (X_MIN_POS, X_MAX_POS)."); + static_assert(WITHIN(npp_xyz.y, Y_MIN_POS, Y_MAX_POS), "NOZZLE_PARK_POINT.Y is out of bounds (Y_MIN_POS, Y_MAX_POS)."); + static_assert(WITHIN(npp_xyz.z, Z_MIN_POS, Z_MAX_POS), "NOZZLE_PARK_POINT.Z is out of bounds (Z_MIN_POS, Z_MAX_POS)."); #endif /** @@ -754,7 +880,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS /** * Options only for EXTRUDERS > 1 */ -#if EXTRUDERS > 1 +#if HAS_MULTI_EXTRUDER #if EXTRUDERS > 8 #error "Marlin supports a maximum of 8 EXTRUDERS." @@ -765,14 +891,15 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #endif #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) - #ifndef TOOLCHANGE_FIL_SWAP_LENGTH - #error "TOOLCHANGE_FILAMENT_SWAP requires TOOLCHANGE_FIL_SWAP_LENGTH. Please update your Configuration." - #elif !defined(TOOLCHANGE_FIL_SWAP_RETRACT_SPEED) - #error "TOOLCHANGE_FILAMENT_SWAP requires TOOLCHANGE_FIL_SWAP_RETRACT_SPEED. Please update your Configuration." - #elif !defined(TOOLCHANGE_FIL_SWAP_PRIME_SPEED) - #error "TOOLCHANGE_FILAMENT_SWAP requires TOOLCHANGE_FIL_SWAP_PRIME_SPEED. Please update your Configuration." + #ifndef TOOLCHANGE_FS_LENGTH + #error "TOOLCHANGE_FILAMENT_SWAP requires TOOLCHANGE_FS_LENGTH. Please update your Configuration_adv.h." + #elif !defined(TOOLCHANGE_FS_RETRACT_SPEED) + #error "TOOLCHANGE_FILAMENT_SWAP requires TOOLCHANGE_FS_RETRACT_SPEED. Please update your Configuration_adv.h." + #elif !defined(TOOLCHANGE_FS_PRIME_SPEED) + #error "TOOLCHANGE_FILAMENT_SWAP requires TOOLCHANGE_FS_PRIME_SPEED. Please update your Configuration_adv.h." #endif #endif + #if ENABLED(TOOLCHANGE_PARK) #ifndef TOOLCHANGE_PARK_XY #error "TOOLCHANGE_PARK requires TOOLCHANGE_PARK_XY. Please update your Configuration." @@ -875,7 +1002,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS * Mixing Extruder requirements */ #if ENABLED(MIXING_EXTRUDER) - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER #error "For MIXING_EXTRUDER set MIXING_STEPPERS > 1 instead of EXTRUDERS > 1." #elif MIXING_STEPPERS < 2 #error "You must set MIXING_STEPPERS >= 2 for a mixing extruder." @@ -896,6 +1023,9 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS WITHIN(LIN_ADVANCE_K, 0, 10), "LIN_ADVANCE_K must be a value from 0 to 10 (Changed in LIN_ADVANCE v1.5, Marlin 1.1.9)." ); + #if ENABLED(S_CURVE_ACCELERATION) && DISABLED(EXPERIMENTAL_SCURVE) + #error "LIN_ADVANCE and S_CURVE_ACCELERATION may not play well together! Enable EXPERIMENTAL_SCURVE to continue." + #endif #endif /** @@ -994,6 +1124,13 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "FANMUX0_PIN and FANMUX1_PIN must be set before FANMUX2_PIN can be set." #endif +/** + * Limited user-controlled fans + */ +#if NUM_M106_FANS > FAN_COUNT + #error "The selected board doesn't support enough user-controlled fans. Reduce NUM_M106_FANS." +#endif + /** * Limited number of servos */ @@ -1011,7 +1148,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS /** * Required LCD language */ -#if HAS_CHARACTER_LCD && !defined(DISPLAY_CHARSET_HD44780) +#if HAS_MARLINUI_HD44780 && !defined(DISPLAY_CHARSET_HD44780) #error "You must set DISPLAY_CHARSET_HD44780 to JAPANESE, WESTERN or CYRILLIC for your LCD controller." #endif @@ -1037,8 +1174,9 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS + ENABLED(COREYZ) \ + ENABLED(COREYX) \ + ENABLED(COREZX) \ - + ENABLED(COREZY) - #error "Please enable only one of DELTA, MORGAN_SCARA, COREXY, COREYX, COREXZ, COREZX, COREYZ, or COREZY." + + ENABLED(COREZY) \ + + ENABLED(MARKFORGED_XY) + #error "Please enable only one of DELTA, MORGAN_SCARA, COREXY, COREYX, COREXZ, COREZX, COREYZ, COREZY, or MARKFORGED_XY." #endif /** @@ -1065,7 +1203,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS /** * Junction deviation is incompatible with kinematic systems. */ -#if DISABLED(CLASSIC_JERK) && IS_KINEMATIC +#if HAS_JUNCTION_DEVIATION && IS_KINEMATIC #error "CLASSIC_JERK is required for DELTA and SCARA." #endif @@ -1081,7 +1219,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS + ENABLED(FIX_MOUNTED_PROBE) \ + ENABLED(NOZZLE_AS_PROBE) \ + (HAS_Z_SERVO_PROBE && DISABLED(BLTOUCH)) \ - + ENABLED(BLTOUCH) \ + + ENABLED(BLTOUCH) && DISABLED(CREALITY_TOUCH) \ + + ENABLED(CREALITY_TOUCH) \ + ENABLED(TOUCH_MI_PROBE) \ + ENABLED(SOLENOID_PROBE) \ + ENABLED(Z_PROBE_ALLEN_KEY) \ @@ -1115,8 +1254,10 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS * NUM_SERVOS is required for a Z servo probe */ #if HAS_Z_SERVO_PROBE - #ifndef NUM_SERVOS - #error "You must set NUM_SERVOS for a Z servo probe (Z_PROBE_SERVO_NR)." + #if !NUM_SERVOS + #error "NUM_SERVOS is required for a Z servo probe (Z_PROBE_SERVO_NR)." + #elif Z_PROBE_SERVO_NR >= NUM_SERVOS + #error "Z_PROBE_SERVO_NR must be smaller than NUM_SERVOS." #elif Z_PROBE_SERVO_NR == 0 && !PIN_EXISTS(SERVO0) #error "SERVO0_PIN must be defined for your servo or BLTOUCH probe." #elif Z_PROBE_SERVO_NR == 1 && !PIN_EXISTS(SERVO1) @@ -1125,8 +1266,6 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "SERVO2_PIN must be defined for your servo or BLTOUCH probe." #elif Z_PROBE_SERVO_NR == 3 && !PIN_EXISTS(SERVO3) #error "SERVO3_PIN must be defined for your servo or BLTOUCH probe." - #elif Z_PROBE_SERVO_NR >= NUM_SERVOS - #error "Z_PROBE_SERVO_NR must be smaller than NUM_SERVOS." #endif #endif @@ -1191,13 +1330,21 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #endif #if DISABLED(NOZZLE_AS_PROBE) - static_assert(MIN_PROBE_EDGE >= 0, "MIN_PROBE_EDGE must be >= 0."); - static_assert(MIN_PROBE_EDGE_BACK >= 0, "MIN_PROBE_EDGE_BACK must be >= 0."); - static_assert(MIN_PROBE_EDGE_FRONT >= 0, "MIN_PROBE_EDGE_FRONT must be >= 0."); - static_assert(MIN_PROBE_EDGE_LEFT >= 0, "MIN_PROBE_EDGE_LEFT must be >= 0."); - static_assert(MIN_PROBE_EDGE_RIGHT >= 0, "MIN_PROBE_EDGE_RIGHT must be >= 0."); + static_assert(PROBING_MARGIN >= 0, "PROBING_MARGIN must be >= 0."); + static_assert(PROBING_MARGIN_BACK >= 0, "PROBING_MARGIN_BACK must be >= 0."); + static_assert(PROBING_MARGIN_FRONT >= 0, "PROBING_MARGIN_FRONT must be >= 0."); + static_assert(PROBING_MARGIN_LEFT >= 0, "PROBING_MARGIN_LEFT must be >= 0."); + static_assert(PROBING_MARGIN_RIGHT >= 0, "PROBING_MARGIN_RIGHT must be >= 0."); #endif + #define _MARGIN(A) TERN(IS_SCARA, SCARA_PRINTABLE_RADIUS, TERN(DELTA, DELTA_PRINTABLE_RADIUS, ((A##_BED_SIZE) / 2))) + static_assert(PROBING_MARGIN < _MARGIN(X), "PROBING_MARGIN is too large."); + static_assert(PROBING_MARGIN_BACK < _MARGIN(Y), "PROBING_MARGIN_BACK is too large."); + static_assert(PROBING_MARGIN_FRONT < _MARGIN(Y), "PROBING_MARGIN_FRONT is too large."); + static_assert(PROBING_MARGIN_LEFT < _MARGIN(X), "PROBING_MARGIN_LEFT is too large."); + static_assert(PROBING_MARGIN_RIGHT < _MARGIN(X), "PROBING_MARGIN_RIGHT is too large."); + #undef _MARGIN + /** * Make sure Z raise values are set */ @@ -1213,8 +1360,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "Probes need Z_AFTER_PROBING >= 0." #endif - #if MULTIPLE_PROBING || EXTRA_PROBING - #if !MULTIPLE_PROBING + #if MULTIPLE_PROBING > 0 || EXTRA_PROBING > 0 + #if MULTIPLE_PROBING == 0 #error "EXTRA_PROBING requires MULTIPLE_PROBING." #elif MULTIPLE_PROBING < 2 #error "MULTIPLE_PROBING must be 2 or more." @@ -1237,7 +1384,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS * Require some kind of probe for bed leveling and probe testing */ #if HAS_ABL_NOT_UBL && !PROBE_SELECTED - #error "Auto Bed Leveling requires one of these: PROBE_MANUALLY, FIX_MOUNTED_PROBE, NOZZLE_AS_PROBE, BLTOUCH, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, or a Z Servo." + #error "Auto Bed Leveling requires one of these: PROBE_MANUALLY, SENSORLESS_PROBING, BLTOUCH, FIX_MOUNTED_PROBE, NOZZLE_AS_PROBE, TOUCH_MI_PROBE, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, or a Z Servo." #endif #if ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST) @@ -1311,15 +1458,19 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #endif -#if HAS_MESH - #if HAS_CLASSIC_JERK - static_assert(DEFAULT_ZJERK > 0.1, "Low DEFAULT_ZJERK values are incompatible with mesh-based leveling."); +#if HAS_MESH && HAS_CLASSIC_JERK + static_assert(DEFAULT_ZJERK > 0.1, "Low DEFAULT_ZJERK values are incompatible with mesh-based leveling."); +#endif + +#if ENABLED(G26_MESH_VALIDATION) + #if !EXTRUDERS + #error "G26_MESH_VALIDATION requires at least one extruder." + #elif !HAS_MESH + #error "G26_MESH_VALIDATION requires MESH_BED_LEVELING, AUTO_BED_LEVELING_BILINEAR, or AUTO_BED_LEVELING_UBL." #endif -#elif ENABLED(G26_MESH_VALIDATION) - #error "G26_MESH_VALIDATION requires MESH_BED_LEVELING, AUTO_BED_LEVELING_BILINEAR, or AUTO_BED_LEVELING_UBL." #endif -#if ENABLED(MESH_EDIT_GFX_OVERLAY) && !(ENABLED(AUTO_BED_LEVELING_UBL) && HAS_GRAPHICAL_LCD) +#if ENABLED(MESH_EDIT_GFX_OVERLAY) && !BOTH(AUTO_BED_LEVELING_UBL, HAS_MARLINUI_U8GLIB) #error "MESH_EDIT_GFX_OVERLAY requires AUTO_BED_LEVELING_UBL and a Graphical LCD." #endif @@ -1345,9 +1496,11 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS /** * Homing */ -#if X_HOME_BUMP_MM < 0 || Y_HOME_BUMP_MM < 0 || Z_HOME_BUMP_MM < 0 - #error "[XYZ]_HOME_BUMP_MM must be greater than or equal to 0." -#endif +constexpr float hbm[] = HOMING_BUMP_MM; +static_assert(COUNT(hbm) == XYZ, "HOMING_BUMP_MM requires X, Y, and Z elements."); +static_assert(hbm[X_AXIS] >= 0, "HOMING_BUMP_MM.X must be greater than or equal to 0."); +static_assert(hbm[Y_AXIS] >= 0, "HOMING_BUMP_MM.Y must be greater than or equal to 0."); +static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal to 0."); #if ENABLED(CODEPENDENT_XY_HOMING) #if ENABLED(QUICK_HOME) @@ -1385,6 +1538,28 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #endif #endif +/** + * System Power Sensor + */ +#if ENABLED(POWER_MONITOR_CURRENT) && !PIN_EXISTS(POWER_MONITOR_CURRENT) + #error "POWER_MONITOR_CURRENT requires a valid POWER_MONITOR_CURRENT_PIN." +#elif ENABLED(POWER_MONITOR_VOLTAGE) && !PIN_EXISTS(POWER_MONITOR_VOLTAGE) + #error "POWER_MONITOR_VOLTAGE requires POWER_MONITOR_VOLTAGE_PIN to be defined." +#elif BOTH(POWER_MONITOR_CURRENT, POWER_MONITOR_VOLTAGE) && POWER_MONITOR_CURRENT_PIN == POWER_MONITOR_VOLTAGE_PIN + #error "POWER_MONITOR_CURRENT_PIN and POWER_MONITOR_VOLTAGE_PIN must be different." +#endif + +/** + * Volumetric Extruder Limit + */ +#if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) + #if ENABLED(NO_VOLUMETRICS) + #error "VOLUMETRIC_EXTRUDER_LIMIT requires NO_VOLUMETRICS to be disabled." + #elif MIN_STEPS_PER_SEGMENT > 1 + #error "VOLUMETRIC_EXTRUDER_LIMIT is not compatible with MIN_STEPS_PER_SEGMENT greater than 1." + #endif +#endif + /** * ULTIPANEL encoder */ @@ -1412,7 +1587,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS * Deploying the Allen Key probe uses big moves in z direction. Too dangerous for an unhomed z-axis. */ #if ENABLED(Z_PROBE_ALLEN_KEY) && (Z_HOME_DIR < 0) && ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) - #error "You can't home to a z min endstop with a Z_PROBE_ALLEN_KEY" + #error "You can't home to a z min endstop with a Z_PROBE_ALLEN_KEY." #endif /** @@ -1421,8 +1596,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #if ENABLED(DUAL_X_CARRIAGE) #if EXTRUDERS < 2 #error "DUAL_X_CARRIAGE requires 2 (or more) extruders." - #elif CORE_IS_XY || CORE_IS_XZ - #error "DUAL_X_CARRIAGE cannot be used with COREXY, COREYX, COREXZ, or COREZX." + #elif ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY) + #error "DUAL_X_CARRIAGE cannot be used with COREXY, COREYX, COREXZ, COREZX, or MARKFORGED_XY." #elif !GOOD_AXIS_PINS(X2) #error "DUAL_X_CARRIAGE requires X2 stepper pins to be defined." #elif !HAS_X_MAX @@ -1508,28 +1683,10 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #endif /** - * Test Heater, Temp Sensor, and Extruder Pins; Sensor Type must also be set. + * A Sensor ID has to be set for each heater */ -#if !HAS_HEATER_0 - #error "HEATER_0_PIN not defined for this board." -#elif !ANY_PIN(TEMP_0, MAX6675_SS) - #error "TEMP_0_PIN not defined for this board." -#elif ((defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)) && !PINS_EXIST(E0_STEP, E0_DIR)) - #error "E0_STEP_PIN or E0_DIR_PIN not defined for this board." -#elif ( !(defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)) && (!PINS_EXIST(E0_STEP, E0_DIR) || !HAS_E0_ENABLE)) - #error "E0_STEP_PIN, E0_DIR_PIN, or E0_ENABLE_PIN not defined for this board." -#elif EXTRUDERS && TEMP_SENSOR_0 == 0 - #error "TEMP_SENSOR_0 is required with any extruders." -#endif -// Pins are required for heaters -#if ENABLED(HEATER_0_USES_MAX6675) && !PIN_EXISTS(MAX6675_SS) - #error "MAX6675_SS_PIN (required for TEMP_SENSOR_0) not defined for this board." -#elif (HOTENDS > 1 || ENABLED(HEATERS_PARALLEL)) && !HAS_HEATER_1 - #error "HEATER_1_PIN not defined for this board." -#endif - -#if HOTENDS > 1 +#if HAS_MULTI_HOTEND #if ENABLED(HEATER_1_USES_MAX6675) && !PIN_EXISTS(MAX6675_SS2) #error "MAX6675_SS2_PIN (required for TEMP_SENSOR_1) not defined for this board." #elif TEMP_SENSOR_1 == 0 @@ -1651,9 +1808,37 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "TEMP_SENSOR_7 shouldn't be set with only 1 HOTEND." #endif +#if TEMP_SENSOR_CHAMBER && !PIN_EXISTS(TEMP_CHAMBER) + #error "TEMP_SENSOR_CHAMBER requires TEMP_CHAMBER_PIN. Please add it to your configuration." +#endif + +#if ENABLED(CHAMBER_FAN) && !(defined(CHAMBER_FAN_MODE) && WITHIN(CHAMBER_FAN_MODE, 0, 2)) + #error "CHAMBER_FAN_MODE must be between 0 and 2. Please update your Configuration_adv.h." +#endif + +#if ENABLED(CHAMBER_VENT) + #ifndef CHAMBER_VENT_SERVO_NR + #error "CHAMBER_VENT_SERVO_NR is required for CHAMBER SERVO. Update your Configuration_adv.h." + #elif !NUM_SERVOS + #error "NUM_SERVOS is required for a Heated Chamber vent servo (CHAMBER_VENT_SERVO_NR)." + #elif CHAMBER_VENT_SERVO_NR >= NUM_SERVOS + #error "CHAMBER_VENT_SERVO_NR must be smaller than NUM_SERVOS." + #elif HAS_Z_SERVO_PROBE && CHAMBER_VENT_SERVO_NR == Z_PROBE_SERVO_NR + #error "CHAMBER SERVO is already used by BLTOUCH. Please change." + #elif CHAMBER_VENT_SERVO_NR == 0 && !PIN_EXISTS(SERVO0) + #error "SERVO0_PIN must be defined for your Heated Chamber vent servo." + #elif CHAMBER_VENT_SERVO_NR == 1 && !PIN_EXISTS(SERVO1) + #error "SERVO1_PIN must be defined for your Heated Chamber vent servo." + #elif CHAMBER_VENT_SERVO_NR == 2 && !PIN_EXISTS(SERVO2) + #error "SERVO2_PIN must be defined for your Heated Chamber vent servo." + #elif CHAMBER_VENT_SERVO_NR == 3 && !PIN_EXISTS(SERVO3) + #error "SERVO3_PIN must be defined for your Heated Chamber vent servo." + #endif +#endif + #if TEMP_SENSOR_PROBE #if !PIN_EXISTS(TEMP_PROBE) - #error "TEMP_SENSOR_PROBE requires TEMP_PROBE_PIN." + #error "TEMP_SENSOR_PROBE requires TEMP_PROBE_PIN. Please add it to your configuration." #elif !HAS_TEMP_ADC_PROBE #error "TEMP_PROBE_PIN must be an ADC pin." #elif !ENABLED(FIX_MOUNTED_PROBE) @@ -1665,6 +1850,34 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "TEMP_SENSOR_1 is required with TEMP_SENSOR_1_AS_REDUNDANT." #endif +#if ENABLED(MAX6675_IS_MAX31865) && (!defined(MAX31865_SENSOR_OHMS) || !defined(MAX31865_CALIBRATION_OHMS)) + #error "MAX31865_SENSOR_OHMS and MAX31865_CALIBRATION_OHMS must be set in Configuration.h when using a MAX31865 temperature sensor." +#endif + +/** + * Test Heater, Temp Sensor, and Extruder Pins + */ +#if !HAS_HEATER_0 && EXTRUDERS + #error "HEATER_0_PIN not defined for this board." +#elif !ANY_PIN(TEMP_0, MAX6675_SS) + #error "TEMP_0_PIN not defined for this board." +#elif ((defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)) && !PINS_EXIST(E0_STEP, E0_DIR)) + #error "E0_STEP_PIN or E0_DIR_PIN not defined for this board." +#elif ( !(defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)) && (!PINS_EXIST(E0_STEP, E0_DIR) || !HAS_E0_ENABLE)) + #error "E0_STEP_PIN, E0_DIR_PIN, or E0_ENABLE_PIN not defined for this board." +#elif EXTRUDERS && TEMP_SENSOR_0 == 0 + #error "TEMP_SENSOR_0 is required if there are any extruders." +#endif + +// Pins are required for heaters +#if ENABLED(HEATER_0_USES_MAX6675) && !PIN_EXISTS(MAX6675_SS) + #error "MAX6675_SS_PIN (required for TEMP_SENSOR_0) not defined for this board." +#elif HAS_HOTEND && !HAS_TEMP_HOTEND + #error "TEMP_0_PIN (required for TEMP_SENSOR_0) not defined for this board." +#elif EITHER(HAS_MULTI_HOTEND, HEATERS_PARALLEL) && !HAS_HEATER_1 + #error "HEATER_1_PIN is not defined. TEMP_SENSOR_1 might not be set, or the board (not EEB / EEF?) doesn't define a pin." +#endif + /** * Temperature status LEDs */ @@ -1753,8 +1966,10 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS * Endstop Tests */ -#define _PLUG_UNUSED_TEST(AXIS,PLUG) (DISABLED(USE_##PLUG##MIN_PLUG, USE_##PLUG##MAX_PLUG) && !(ENABLED(AXIS##_DUAL_ENDSTOPS) && WITHIN(AXIS##2_USE_ENDSTOP, _##PLUG##MAX_, _##PLUG##MIN_))) -#define _AXIS_PLUG_UNUSED_TEST(AXIS) (_PLUG_UNUSED_TEST(AXIS,X) && _PLUG_UNUSED_TEST(AXIS,Y) && _PLUG_UNUSED_TEST(AXIS,Z)) +#define _PLUG_UNUSED_TEST(A,P) (DISABLED(USE_##P##MIN_PLUG, USE_##P##MAX_PLUG) \ + && !(ENABLED(A##_DUAL_ENDSTOPS) && WITHIN(A##2_USE_ENDSTOP, _##P##MAX_, _##P##MIN_)) \ + && !(ENABLED(A##_MULTI_ENDSTOPS) && WITHIN(A##2_USE_ENDSTOP, _##P##MAX_, _##P##MIN_)) ) +#define _AXIS_PLUG_UNUSED_TEST(A) (_PLUG_UNUSED_TEST(A,X) && _PLUG_UNUSED_TEST(A,Y) && _PLUG_UNUSED_TEST(A,Z)) // At least 3 endstop plugs must be used #if _AXIS_PLUG_UNUSED_TEST(X) @@ -1779,8 +1994,12 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "Enable USE_YMAX_PLUG when homing Y to MAX." #endif #endif -#if Z_HOME_DIR < 0 && DISABLED(USE_ZMIN_PLUG) + +// Z homing direction and plug usage flags +#if Z_HOME_DIR < 0 && NONE(USE_ZMIN_PLUG, HOMING_Z_WITH_PROBE) #error "Enable USE_ZMIN_PLUG when homing Z to MIN." +#elif Z_HOME_DIR > 0 && ENABLED(USE_PROBE_FOR_Z_HOMING) + #error "Z_HOME_DIR must be -1 when homing Z with the probe." #elif Z_HOME_DIR > 0 && DISABLED(USE_ZMAX_PLUG) #error "Enable USE_ZMAX_PLUG when homing Z to MAX." #endif @@ -1894,9 +2113,9 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #endif /** - * emergency-command parser + * Emergency Command Parser */ -#if ENABLED(EMERGENCY_PARSER) && defined(__AVR__) && defined(USBCON) +#if BOTH(IS_AT90USB, EMERGENCY_PARSER) #error "EMERGENCY_PARSER does not work on boards with AT90USB processors (USBCON)." #endif @@ -1911,6 +2130,13 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #endif #endif +/** + * G35 Assisted Tramming + */ +#if ENABLED(ASSISTED_TRAMMING) && !HAS_BED_PROBE + #error "ASSISTED_TRAMMING requires a bed probe." +#endif + /** * G38 Probe Target */ @@ -1938,12 +2164,25 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #if !(_RGB_TEST && PIN_EXISTS(RGB_LED_W)) #error "RGBW_LED requires RGB_LED_R_PIN, RGB_LED_G_PIN, RGB_LED_B_PIN, and RGB_LED_W_PIN." #endif -#elif ENABLED(NEOPIXEL_LED) - #if !(PIN_EXISTS(NEOPIXEL) && NEOPIXEL_PIXELS > 0) +#endif +#undef _RGB_TEST + +// NeoPixel requirements +#if ENABLED(NEOPIXEL_LED) + #if !PIN_EXISTS(NEOPIXEL) || NEOPIXEL_PIXELS == 0 #error "NEOPIXEL_LED requires NEOPIXEL_PIN and NEOPIXEL_PIXELS." + #elif ENABLED(NEOPIXEL2_SEPARATE) && !(defined(NEOPIXEL2_TYPE) && PIN_EXISTS(NEOPIXEL2) && NEOPIXEL2_PIXELS > 0) + #error "NEOPIXEL2_SEPARATE requires NEOPIXEL2_TYPE, NEOPIXEL2_PIN and NEOPIXEL2_PIXELS." + #elif ENABLED(NEO2_COLOR_PRESETS) && DISABLED(NEOPIXEL2_SEPARATE) + #error "NEO2_COLOR_PRESETS requires NEOPIXEL2_SEPARATE to be enabled." #endif #endif -#undef _RGB_TEST + +#if DISABLED(NO_COMPILE_TIME_PWM) + #define _TEST_PWM(P) PWM_PIN(P) +#else + #define _TEST_PWM(P) 1 // pass +#endif /** * Auto Fan check for PWM pins @@ -1951,13 +2190,51 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #if HAS_AUTO_FAN && EXTRUDER_AUTO_FAN_SPEED != 255 #define AF_ERR_SUFF "_AUTO_FAN_PIN is not a PWM pin. Set EXTRUDER_AUTO_FAN_SPEED to 255." #if HAS_AUTO_FAN_0 - static_assert(PWM_PIN(E0_AUTO_FAN_PIN), "E0" AF_ERR_SUFF); + static_assert(_TEST_PWM(E0_AUTO_FAN_PIN), "E0" AF_ERR_SUFF); #elif HAS_AUTO_FAN_1 - static_assert(PWM_PIN(E1_AUTO_FAN_PIN), "E1" AF_ERR_SUFF); + static_assert(_TEST_PWM(E1_AUTO_FAN_PIN), "E1" AF_ERR_SUFF); #elif HAS_AUTO_FAN_2 - static_assert(PWM_PIN(E2_AUTO_FAN_PIN), "E2" AF_ERR_SUFF); + static_assert(_TEST_PWM(E2_AUTO_FAN_PIN), "E2" AF_ERR_SUFF); #elif HAS_AUTO_FAN_3 - static_assert(PWM_PIN(E3_AUTO_FAN_PIN), "E3" AF_ERR_SUFF); + static_assert(_TEST_PWM(E3_AUTO_FAN_PIN), "E3" AF_ERR_SUFF); + #elif HAS_AUTO_FAN_4 + static_assert(_TEST_PWM(E4_AUTO_FAN_PIN), "E4" AF_ERR_SUFF); + #elif HAS_AUTO_FAN_5 + static_assert(_TEST_PWM(E5_AUTO_FAN_PIN), "E5" AF_ERR_SUFF); + #elif HAS_AUTO_FAN_6 + static_assert(_TEST_PWM(E6_AUTO_FAN_PIN), "E6" AF_ERR_SUFF); + #elif HAS_AUTO_FAN_7 + static_assert(_TEST_PWM(E7_AUTO_FAN_PIN), "E7" AF_ERR_SUFF); + #endif +#endif + +/** + * Make sure only one EEPROM type is enabled + */ +#if ENABLED(EEPROM_SETTINGS) + #if 1 < 0 \ + + ENABLED(I2C_EEPROM) \ + + ENABLED(SPI_EEPROM) \ + + ENABLED(QSPI_EEPROM) \ + + ENABLED(SDCARD_EEPROM_EMULATION) \ + + ENABLED(FLASH_EEPROM_EMULATION) \ + + ENABLED(SRAM_EEPROM_EMULATION) \ + + ENABLED(IIC_BL24CXX_EEPROM) + #error "Please select only one method of EEPROM Persistent Storage." + #endif +#endif + +/** + * Make sure features that need to write to the SD card can + */ +#if ENABLED(SDCARD_READONLY) && ANY(POWER_LOSS_RECOVERY, BINARY_FILE_TRANSFER, SDCARD_EEPROM_EMULATION) + #undef SDCARD_READONLY + #if ENABLED(POWER_LOSS_RECOVERY) + #warning "Either disable SDCARD_READONLY or disable POWER_LOSS_RECOVERY." + #elif ENABLED(BINARY_FILE_TRANSFER) + #warning "Either disable SDCARD_READONLY or disable BINARY_FILE_TRANSFER." + #elif ENABLED(SDCARD_EEPROM_EMULATION) + #warning "Either disable SDCARD_READONLY or disable SDCARD_EEPROM_EMULATION." #endif #endif @@ -1969,7 +2246,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS + (ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) && DISABLED(IS_RRD_FG_SC)) \ + (ENABLED(ULTRA_LCD) && DISABLED(IS_ULTRA_LCD)) \ + (ENABLED(U8GLIB_SSD1306) && DISABLED(IS_U8GLIB_SSD1306)) \ - + (ENABLED(MINIPANEL) && DISABLED(MKS_MINI_12864, ENDER2_STOCKDISPLAY)) \ + + (ENABLED(MINIPANEL) && NONE(MKS_MINI_12864, ENDER2_STOCKDISPLAY)) \ + + (ENABLED(MKS_MINI_12864) && DISABLED(MKS_LCD12864)) \ + (ENABLED(EXTENSIBLE_UI) && DISABLED(IS_EXTUI)) \ + (ENABLED(ULTIPANEL) && DISABLED(IS_ULTIPANEL)) \ + ENABLED(RADDS_DISPLAY) \ @@ -1996,7 +2274,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS + ENABLED(CARTESIO_UI) \ + ENABLED(LCD_FOR_MELZI) \ + ENABLED(ULTI_CONTROLLER) \ - + ENABLED(MKS_MINI_12864) \ + + ENABLED(MKS_LCD12864) \ + ENABLED(ENDER2_STOCKDISPLAY) \ + ENABLED(FYSETC_MINI_12864_X_X) \ + ENABLED(FYSETC_MINI_12864_1_2) \ @@ -2004,6 +2282,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS + ENABLED(FYSETC_MINI_12864_2_1) \ + ENABLED(FYSETC_GENERIC_12864_1_1) \ + ENABLED(CR10_STOCKDISPLAY) \ + + ENABLED(DWIN_CREALITY_LCD) \ + ENABLED(ANET_FULL_GRAPHICS_LCD) \ + ENABLED(AZSMZ_12864) \ + ENABLED(SILVER_GATE_GLCD_CONTROLLER) \ @@ -2011,15 +2290,27 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS + ENABLED(OLED_PANEL_TINYBOY2) \ + ENABLED(MKS_12864OLED) \ + ENABLED(MKS_12864OLED_SSD1306) \ + + ENABLED(ZONESTAR_12864LCD) \ + + ENABLED(ZONESTAR_12864OLED) \ + + ENABLED(ZONESTAR_12864OLED_SSD1306) \ + ENABLED(U8GLIB_SH1106_EINSTART) \ + ENABLED(OVERLORD_OLED) \ + + ENABLED(FYSETC_242_OLED_12864) \ + ENABLED(DGUS_LCD_UI_ORIGIN) \ + ENABLED(DGUS_LCD_UI_FYSETC) \ + ENABLED(DGUS_LCD_UI_HIPRECY) \ + ENABLED(MALYAN_LCD) \ + ENABLED(TOUCH_UI_FTDI_EVE) \ - + ENABLED(FSMC_GRAPHICAL_TFT) - #error "Please select no more than one LCD controller option." + + ENABLED(TFT_320x240) \ + + ENABLED(TFT_320x240_SPI) \ + + ENABLED(FSMC_GRAPHICAL_TFT) \ + + ENABLED(TFT_LVGL_UI_FSMC) \ + + ENABLED(TFT_LVGL_UI_SPI) \ + + ENABLED(ANYCUBIC_LCD_I3MEGA) \ + + ENABLED(ANYCUBIC_LCD_CHIRON) \ + + ENABLED(TFTGLCD_PANEL_SPI) \ + + ENABLED(TFTGLCD_PANEL_I2C) + #error "Please select only one LCD controller option." #endif #undef IS_RRD_SC @@ -2030,6 +2321,29 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #undef IS_EXTUI #undef IS_ULTIPANEL +#if 1 < ENABLED(LCD_SCREEN_ROT_0) + ENABLED(LCD_SCREEN_ROT_90) + ENABLED(LCD_SCREEN_ROT_180) + ENABLED(LCD_SCREEN_ROT_270) + #error "Please enable only one LCD_SCREEN_ROT_* option: 0, 90, 180, or 270." +#endif + +/** + * Serial displays require a dedicated serial port + */ +#ifdef LCD_SERIAL_PORT + #if LCD_SERIAL_PORT == SERIAL_PORT + #error "LCD_SERIAL_PORT cannot be the same as SERIAL_PORT. Please update your configuration." + #elif defined(SERIAL_PORT_2) && LCD_SERIAL_PORT == SERIAL_PORT_2 + #error "LCD_SERIAL_PORT cannot be the same as SERIAL_PORT_2. Please update your configuration." + #endif +#else + #if HAS_DGUS_LCD + #error "The DGUS LCD requires LCD_SERIAL_PORT to be defined in Configuration.h" + #elif EITHER(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON) + #error "The ANYCUBIC LCD requires LCD_SERIAL_PORT to be defined in Configuration.h" + #elif ENABLED(MALYAN_LCD) + #error "MALYAN_LCD requires LCD_SERIAL_PORT to be defined in Configuration.h" + #endif +#endif + /** * FYSETC Mini 12864 RGB backlighting required */ @@ -2057,6 +2371,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "An SPI driven TMC driver on Z2 requires Z2_CS_PIN." #elif INVALID_TMC_SPI(Z3) #error "An SPI driven TMC driver on Z3 requires Z3_CS_PIN." +#elif INVALID_TMC_SPI(Z4) + #error "An SPI driven TMC driver on Z4 requires Z4_CS_PIN." #elif INVALID_TMC_SPI(E0) #error "An SPI driven TMC driver on E0 requires E0_CS_PIN." #elif INVALID_TMC_SPI(E1) @@ -2094,6 +2410,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "TMC2208 or TMC2209 on Z2 requires Z2_HARDWARE_SERIAL or Z2_SERIAL_(RX|TX)_PIN." #elif INVALID_TMC_UART(Z3) #error "TMC2208 or TMC2209 on Z3 requires Z3_HARDWARE_SERIAL or Z3_SERIAL_(RX|TX)_PIN." +#elif INVALID_TMC_UART(Z4) + #error "TMC2208 or TMC2209 on Z4 requires Z4_HARDWARE_SERIAL or Z4_SERIAL_(RX|TX)_PIN." #elif INVALID_TMC_UART(E0) #error "TMC2208 or TMC2209 on E0 requires E0_HARDWARE_SERIAL or E0_SERIAL_(RX|TX)_PIN." #elif INVALID_TMC_UART(E1) @@ -2131,6 +2449,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS INVALID_TMC_ADDRESS(Z2); #elif AXIS_DRIVER_TYPE_Z3(TMC2209) INVALID_TMC_ADDRESS(Z3); +#elif AXIS_DRIVER_TYPE_Z4(TMC2209) + INVALID_TMC_ADDRESS(Z4); #elif AXIS_DRIVER_TYPE_E0(TMC2209) INVALID_TMC_ADDRESS(E0); #elif AXIS_DRIVER_TYPE_E1(TMC2209) @@ -2150,6 +2470,47 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #endif #undef INVALID_TMC_ADDRESS +#define _TMC_MICROSTEP_IS_VALID(MS) (MS == 0 || MS == 2 || MS == 4 || MS == 8 || MS == 16 || MS == 32 || MS == 64 || MS == 128 || MS == 256) +#define TMC_MICROSTEP_IS_VALID(M) (!AXIS_IS_TMC(M) || _TMC_MICROSTEP_IS_VALID(M##_MICROSTEPS)) +#define INVALID_TMC_MS(ST) static_assert(0, "Invalid " STRINGIFY(ST) "_MICROSTEPS. Valid values are 0, 2, 4, 8, 16, 32, 64, 128, and 256.") + +#if !TMC_MICROSTEP_IS_VALID(X) + INVALID_TMC_MS(X); +#elif !TMC_MICROSTEP_IS_VALID(Y) + INVALID_TMC_MS(Y) +#elif !TMC_MICROSTEP_IS_VALID(Z) + INVALID_TMC_MS(Z) +#elif !TMC_MICROSTEP_IS_VALID(X2) + INVALID_TMC_MS(X2); +#elif !TMC_MICROSTEP_IS_VALID(Y2) + INVALID_TMC_MS(Y2) +#elif !TMC_MICROSTEP_IS_VALID(Z2) + INVALID_TMC_MS(Z2) +#elif !TMC_MICROSTEP_IS_VALID(Z3) + INVALID_TMC_MS(Z3) +#elif !TMC_MICROSTEP_IS_VALID(Z4) + INVALID_TMC_MS(Z4) +#elif !TMC_MICROSTEP_IS_VALID(E0) + INVALID_TMC_MS(E0) +#elif !TMC_MICROSTEP_IS_VALID(E1) + INVALID_TMC_MS(E1) +#elif !TMC_MICROSTEP_IS_VALID(E2) + INVALID_TMC_MS(E2) +#elif !TMC_MICROSTEP_IS_VALID(E3) + INVALID_TMC_MS(E3) +#elif !TMC_MICROSTEP_IS_VALID(E4) + INVALID_TMC_MS(E4) +#elif !TMC_MICROSTEP_IS_VALID(E5) + INVALID_TMC_MS(E5) +#elif !TMC_MICROSTEP_IS_VALID(E6) + INVALID_TMC_MS(E6) +#elif !TMC_MICROSTEP_IS_VALID(E7) + INVALID_TMC_MS(E7) +#endif +#undef INVALID_TMC_MS +#undef TMC_MICROSTEP_IS_VALID +#undef _TMC_MICROSTEP_IS_VALID + #if ENABLED(DELTA) && (ENABLED(STEALTHCHOP_XY) != ENABLED(STEALTHCHOP_Z)) #error "STEALTHCHOP_XY and STEALTHCHOP_Z must be the same on DELTA." #endif @@ -2243,6 +2604,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "CoreXZ requires both X and Z to use sensorless homing if either one does." #elif CORE_IS_YZ && Y_SENSORLESS != Z_SENSORLESS && !HOMING_Z_WITH_PROBE #error "CoreYZ requires both Y and Z to use sensorless homing if either one does." +#elif ENABLED(MARKFORGED_XY) && X_SENSORLESS != Y_SENSORLESS + #error "MARKFORGED_XY requires both X and Y to use sensorless homing if either one does." #endif // Other TMC feature requirements @@ -2256,17 +2619,15 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "STEALTHCHOP requires TMC2130, TMC2160, TMC2208, TMC2209, or TMC5160 stepper drivers." #endif +/** + * TMC SPI Chaining + */ #define IN_CHAIN(A) ((A##_CHAIN_POS > 0) && !HAS_L64XX) -// TMC SPI Chaining -#if IN_CHAIN(X) || IN_CHAIN(Y) || IN_CHAIN(Z) || IN_CHAIN(X2) || IN_CHAIN(Y2) || IN_CHAIN(Z2) || IN_CHAIN(Z3) || IN_CHAIN(E0) || IN_CHAIN(E1) || IN_CHAIN(E2) || IN_CHAIN(E3) || IN_CHAIN(E4) || IN_CHAIN(E5) - #if (IN_CHAIN(X) && !PIN_EXISTS(X_CS) ) || (IN_CHAIN(Y) && !PIN_EXISTS(Y_CS) ) \ - || (IN_CHAIN(Z) && !PIN_EXISTS(Z_CS) ) || (IN_CHAIN(X2) && !PIN_EXISTS(X2_CS)) \ - || (IN_CHAIN(Y2) && !PIN_EXISTS(Y2_CS)) || (IN_CHAIN(Z2) && !PIN_EXISTS(Z2_CS)) \ - || (IN_CHAIN(Z3) && !PIN_EXISTS(Z3_CS)) || (IN_CHAIN(E0) && !PIN_EXISTS(E0_CS)) \ - || (IN_CHAIN(E1) && !PIN_EXISTS(E1_CS)) || (IN_CHAIN(E2) && !PIN_EXISTS(E2_CS)) \ - || (IN_CHAIN(E3) && !PIN_EXISTS(E3_CS)) || (IN_CHAIN(E4) && !PIN_EXISTS(E4_CS)) \ - || (IN_CHAIN(E5) && !PIN_EXISTS(E5_CS)) || (IN_CHAIN(E6) && !PIN_EXISTS(E6_CS)) \ - || (IN_CHAIN(E7) && !PIN_EXISTS(E7_CS)) +#if IN_CHAIN(X ) || IN_CHAIN(Y ) || IN_CHAIN(Z ) || IN_CHAIN(X2) || IN_CHAIN(Y2) || IN_CHAIN(Z2) || IN_CHAIN(Z3) || IN_CHAIN(Z4) \ + || IN_CHAIN(E0) || IN_CHAIN(E1) || IN_CHAIN(E2) || IN_CHAIN(E3) || IN_CHAIN(E4) || IN_CHAIN(E5) || IN_CHAIN(E6) || IN_CHAIN(E7) + #define BAD_CHAIN(A) (IN_CHAIN(A) && !PIN_EXISTS(A##_CS)) + #if BAD_CHAIN(X ) || BAD_CHAIN(Y ) || BAD_CHAIN(Z ) || BAD_CHAIN(X2) || BAD_CHAIN(Y2) || BAD_CHAIN(Z2) || BAD_CHAIN(Z3) || BAD_CHAIN(Z4) \ + || BAD_CHAIN(E0) || BAD_CHAIN(E1) || BAD_CHAIN(E2) || BAD_CHAIN(E3) || BAD_CHAIN(E4) || BAD_CHAIN(E5) || BAD_CHAIN(E6) || BAD_CHAIN(E7) #error "All chained TMC drivers need a CS pin." #else #if IN_CHAIN(X) @@ -2300,28 +2661,27 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #elif IN_CHAIN(E7) #define CS_COMPARE E7_CS_PIN #endif - #if (IN_CHAIN(X) && X_CS_PIN != CS_COMPARE) || (IN_CHAIN(Y) && Y_CS_PIN != CS_COMPARE) \ - || (IN_CHAIN(Z) && Z_CS_PIN != CS_COMPARE) || (IN_CHAIN(X2) && X2_CS_PIN != CS_COMPARE) \ - || (IN_CHAIN(Y2) && Y2_CS_PIN != CS_COMPARE) || (IN_CHAIN(Z2) && Z2_CS_PIN != CS_COMPARE) \ - || (IN_CHAIN(Z3) && Z3_CS_PIN != CS_COMPARE) || (IN_CHAIN(E0) && E0_CS_PIN != CS_COMPARE) \ - || (IN_CHAIN(E1) && E1_CS_PIN != CS_COMPARE) || (IN_CHAIN(E2) && E2_CS_PIN != CS_COMPARE) \ - || (IN_CHAIN(E3) && E3_CS_PIN != CS_COMPARE) || (IN_CHAIN(E4) && E4_CS_PIN != CS_COMPARE) \ - || (IN_CHAIN(E5) && E5_CS_PIN != CS_COMPARE) || (IN_CHAIN(E6) && E6_CS_PIN != CS_COMPARE) \ - || (IN_CHAIN(E7) && E7_CS_PIN != CS_COMPARE) + #define BAD_CS_PIN(A) (IN_CHAIN(A) && A##_CS_PIN != CS_COMPARE) + #if BAD_CS_PIN(X ) || BAD_CS_PIN(Y ) || BAD_CS_PIN(Z ) || BAD_CS_PIN(X2) || BAD_CS_PIN(Y2) || BAD_CS_PIN(Z2) || BAD_CS_PIN(Z3) || BAD_CS_PIN(Z4) \ + || BAD_CS_PIN(E0) || BAD_CS_PIN(E1) || BAD_CS_PIN(E2) || BAD_CS_PIN(E3) || BAD_CS_PIN(E4) || BAD_CS_PIN(E5) || BAD_CS_PIN(E6) || BAD_CS_PIN(E7) #error "All chained TMC drivers must use the same CS pin." #endif + #undef BAD_CS_PIN + #undef CS_COMPARE #endif - #undef CS_COMPARE + #undef BAD_CHAIN #endif #undef IN_CHAIN /** * Digipot requirement */ -#if ENABLED(DIGIPOT_MCP4018) - #if !defined(DIGIPOTS_I2C_SDA_X) || !defined(DIGIPOTS_I2C_SDA_Y) || !defined(DIGIPOTS_I2C_SDA_Z) \ - || !defined(DIGIPOTS_I2C_SDA_E0) || !defined(DIGIPOTS_I2C_SDA_E1) - #error "DIGIPOT_MCP4018 requires DIGIPOTS_I2C_SDA_* pins to be defined." +#if HAS_MOTOR_CURRENT_I2C + #if BOTH(DIGIPOT_MCP4018, DIGIPOT_MCP4451) + #error "Enable only one of DIGIPOT_MCP4018 or DIGIPOT_MCP4451." + #elif !MB(MKS_SBASE) \ + && (!defined(DIGIPOTS_I2C_SDA_X) || !defined(DIGIPOTS_I2C_SDA_Y) || !defined(DIGIPOTS_I2C_SDA_Z) || !defined(DIGIPOTS_I2C_SDA_E0) || !defined(DIGIPOTS_I2C_SDA_E1)) + #error "DIGIPOT_MCP4018/4451 requires DIGIPOTS_I2C_SDA_* pins to be defined." #endif #endif @@ -2432,9 +2792,28 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2) #error "Z_STEPPER_AUTO_ALIGN requires NUM_Z_STEPPER_DRIVERS greater than 1." #elif !HAS_BED_PROBE #error "Z_STEPPER_AUTO_ALIGN requires a Z-bed probe." - #elif ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS) && NUM_Z_STEPPER_DRIVERS != 3 - #error "Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS requires NUM_Z_STEPPER_DRIVERS to be 3." + #elif ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS) && NUM_Z_STEPPER_DRIVERS < 3 + #error "Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS requires NUM_Z_STEPPER_DRIVERS to be 3 or 4." + #endif +#endif + +#if ENABLED(MECHANICAL_GANTRY_CALIBRATION) + #if NONE(HAS_MOTOR_CURRENT_DAC, HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_DAC, HAS_TRINAMIC_CONFIG, HAS_MOTOR_CURRENT_PWM) + #error "It is highly recommended to have adjustable current drivers to prevent damage. Disable this line to continue anyway." + #elif !defined(GANTRY_CALIBRATION_CURRENT) + #error "MECHANICAL_GANTRY_CALIBRATION Requires GANTRY_CALIBRATION_CURRENT to be set." + #elif !defined(GANTRY_CALIBRATION_EXTRA_HEIGHT) + #error "MECHANICAL_GANTRY_CALIBRATION Requires GANTRY_CALIBRATION_EXTRA_HEIGHT to be set." + #elif !defined(GANTRY_CALIBRATION_FEEDRATE) + #error "MECHANICAL_GANTRY_CALIBRATION Requires GANTRY_CALIBRATION_FEEDRATE to be set." #endif + #if defined(GANTRY_CALIBRATION_SAFE_POSITION) && !defined(GANTRY_CALIBRATION_XY_PARK_FEEDRATE) + #error "GANTRY_CALIBRATION_SAFE_POSITION Requires GANTRY_CALIBRATION_XY_PARK_FEEDRATE to be set." + #endif +#endif + +#if BOTH(Z_STEPPER_AUTO_ALIGN, MECHANICAL_GANTRY_CALIBRATION) + #error "You cannot use Z_STEPPER_AUTO_ALIGN and MECHANICAL_GANTRY_CALIBRATION at the same time." #endif #if ENABLED(PRINTCOUNTER) && DISABLED(EEPROM_SETTINGS) @@ -2557,14 +2936,18 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2) #endif #if ENABLED(BACKLASH_COMPENSATION) - #if IS_CORE - #error "BACKLASH_COMPENSATION is incompatible with CORE kinematics." - #endif #ifndef BACKLASH_DISTANCE_MM - #error "BACKLASH_COMPENSATION requires BACKLASH_DISTANCE_MM" - #endif - #ifndef BACKLASH_CORRECTION - #error "BACKLASH_COMPENSATION requires BACKLASH_CORRECTION" + #error "BACKLASH_COMPENSATION requires BACKLASH_DISTANCE_MM." + #elif !defined(BACKLASH_CORRECTION) + #error "BACKLASH_COMPENSATION requires BACKLASH_CORRECTION." + #elif ENABLED(MARKFORGED_XY) + constexpr float backlash_arr[] = BACKLASH_DISTANCE_MM; + static_assert(!backlash_arr[CORE_AXIS_1] && !backlash_arr[CORE_AXIS_2], + "BACKLASH_COMPENSATION can only apply to " STRINGIFY(NORMAL_AXIS) " on a MarkForged system."); + #elif IS_CORE + constexpr float backlash_arr[] = BACKLASH_DISTANCE_MM; + static_assert(!backlash_arr[CORE_AXIS_1] && !backlash_arr[CORE_AXIS_2], + "BACKLASH_COMPENSATION can only apply to " STRINGIFY(NORMAL_AXIS) " with your CORE system."); #endif #endif @@ -2590,13 +2973,17 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2) #endif /** - * Prusa MMU2 requirements + * Průša MMU2 requirements */ #if ENABLED(PRUSA_MMU2) - #if DISABLED(NOZZLE_PARK_FEATURE) - #error "PRUSA_MMU2 requires NOZZLE_PARK_FEATURE." - #elif EXTRUDERS != 5 + #if EXTRUDERS != 5 #error "PRUSA_MMU2 requires EXTRUDERS = 5." + #elif DISABLED(NOZZLE_PARK_FEATURE) + #error "PRUSA_MMU2 requires NOZZLE_PARK_FEATURE. Enable it to continue." + #elif EITHER(PRUSA_MMU2_S_MODE, MMU_EXTRUDER_SENSOR) && DISABLED(FILAMENT_RUNOUT_SENSOR) + #error "PRUSA_MMU2_S_MODE or MMU_EXTRUDER_SENSOR requires FILAMENT_RUNOUT_SENSOR. Enable it to continue." + #elif BOTH(PRUSA_MMU2_S_MODE, MMU_EXTRUDER_SENSOR) + #error "Enable only one of PRUSA_MMU2_S_MODE or MMU_EXTRUDER_SENSOR." #elif DISABLED(ADVANCED_PAUSE_FEATURE) static_assert(nullptr == strstr(MMU2_FILAMENT_RUNOUT_SCRIPT, "M600"), "ADVANCED_PAUSE_FEATURE is required to use M600 with PRUSA_MMU2."); #endif @@ -2630,8 +3017,8 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2) * Ensure this option is set intentionally */ #if ENABLED(PSU_CONTROL) - #ifndef PSU_ACTIVE_HIGH - #error "PSU_CONTROL requires PSU_ACTIVE_HIGH to be defined as 'true' or 'false'." + #ifndef PSU_ACTIVE_STATE + #error "PSU_CONTROL requires PSU_ACTIVE_STATE to be defined as 'HIGH' or 'LOW'." #elif !PIN_EXISTS(PS_ON) #error "PSU_CONTROL requires PS_ON_PIN." #endif @@ -2640,6 +3027,45 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2) #endif #if HAS_CUTTER + #ifndef CUTTER_POWER_UNIT + #error "CUTTER_POWER_UNIT is required with a spindle or laser. Please update your Configuration_adv.h." + #elif !CUTTER_UNIT_IS(PWM255) && !CUTTER_UNIT_IS(PERCENT) && !CUTTER_UNIT_IS(RPM) + #error "CUTTER_POWER_UNIT must be PWM255, PERCENT, or RPM. Please update your Configuration_adv.h." + #endif + + #if ENABLED(LASER_POWER_INLINE) + #if ENABLED(SPINDLE_CHANGE_DIR) + #error "SPINDLE_CHANGE_DIR and LASER_POWER_INLINE are incompatible." + #elif ENABLED(LASER_MOVE_G0_OFF) && DISABLED(LASER_MOVE_POWER) + #error "LASER_MOVE_G0_OFF requires LASER_MOVE_POWER. Please update your Configuration_adv.h." + #endif + #if ENABLED(LASER_POWER_INLINE_TRAPEZOID) + #if DISABLED(SPINDLE_LASER_PWM) + #error "LASER_POWER_INLINE_TRAPEZOID requires SPINDLE_LASER_PWM to function." + #elif ENABLED(S_CURVE_ACCELERATION) + //#ifndef LASER_POWER_INLINE_S_CURVE_ACCELERATION_WARN + // #define LASER_POWER_INLINE_S_CURVE_ACCELERATION_WARN + // #warning "Combining LASER_POWER_INLINE_TRAPEZOID with S_CURVE_ACCELERATION may result in unintended behavior." + //#endif + #endif + #endif + #if ENABLED(LASER_POWER_INLINE_INVERT) + //#ifndef LASER_POWER_INLINE_INVERT_WARN + // #define LASER_POWER_INLINE_INVERT_WARN + // #warning "Enabling LASER_POWER_INLINE_INVERT means that `M5` won't kill the laser immediately; use `M5 I` instead." + //#endif + #endif + #else + #if SPINDLE_LASER_POWERUP_DELAY < 1 + #error "SPINDLE_LASER_POWERUP_DELAY must be greater than 0." + #elif SPINDLE_LASER_POWERDOWN_DELAY < 1 + #error "SPINDLE_LASER_POWERDOWN_DELAY must be greater than 0." + #elif ENABLED(LASER_MOVE_POWER) + #error "LASER_MOVE_POWER requires LASER_POWER_INLINE." + #elif ANY(LASER_POWER_INLINE_TRAPEZOID, LASER_POWER_INLINE_INVERT, LASER_MOVE_G0_OFF, LASER_MOVE_POWER) + #error "Enabled an inline laser feature without inline laser power being enabled." + #endif + #endif #define _PIN_CONFLICT(P) (PIN_EXISTS(P) && P##_PIN == SPINDLE_LASER_PWM_PIN) #if BOTH(SPINDLE_FEATURE, LASER_FEATURE) #error "Enable only one of SPINDLE_FEATURE or LASER_FEATURE." @@ -2650,15 +3076,11 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2) #elif ENABLED(SPINDLE_LASER_PWM) #if !defined(SPINDLE_LASER_PWM_PIN) || SPINDLE_LASER_PWM_PIN < 0 #error "SPINDLE_LASER_PWM_PIN is required for SPINDLE_LASER_PWM." - #elif !PWM_PIN(SPINDLE_LASER_PWM_PIN) + #elif !_TEST_PWM(SPINDLE_LASER_PWM_PIN) #error "SPINDLE_LASER_PWM_PIN not assigned to a PWM pin." - #elif SPINDLE_LASER_POWERUP_DELAY < 1 - #error "SPINDLE_LASER_POWERUP_DELAY must be greater than 0." - #elif SPINDLE_LASER_POWERDOWN_DELAY < 1 - #error "SPINDLE_LASER_POWERDOWN_DELAY must be greater than 0." #elif !defined(SPINDLE_LASER_PWM_INVERT) #error "SPINDLE_LASER_PWM_INVERT is required for (SPINDLE|LASER)_FEATURE." - #elif !defined(SPEED_POWER_SLOPE) || !defined(SPEED_POWER_INTERCEPT) || !defined(SPEED_POWER_MIN) || !defined(SPEED_POWER_MAX) + #elif !(defined(SPEED_POWER_INTERCEPT) && defined(SPEED_POWER_MIN) && defined(SPEED_POWER_MAX) && defined(SPEED_POWER_STARTUP)) #error "SPINDLE_LASER_PWM equation constant(s) missing." #elif _PIN_CONFLICT(X_MIN) #error "SPINDLE_LASER_PWM pin conflicts with X_MIN_PIN." @@ -2713,16 +3135,14 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2) #undef _PIN_CONFLICT #endif -#if !HAS_GRAPHICAL_LCD +#if !HAS_MARLINUI_U8GLIB #if ENABLED(PRINT_PROGRESS_SHOW_DECIMALS) #error "PRINT_PROGRESS_SHOW_DECIMALS currently requires a Graphical LCD." - #elif ENABLED(SHOW_REMAINING_TIME) - #error "SHOW_REMAINING_TIME currently requires a Graphical LCD." #endif #endif -#if HAS_ADC_BUTTONS && defined(ADC_BUTTON_DEBOUNCE_DELAY) && !WITHIN(ADC_BUTTON_DEBOUNCE_DELAY, 16, 255) - #error "ADC_BUTTON_DEBOUNCE_DELAY must be an integer from 16 to 255." +#if HAS_ADC_BUTTONS && defined(ADC_BUTTON_DEBOUNCE_DELAY) && ADC_BUTTON_DEBOUNCE_DELAY < 16 + #error "ADC_BUTTON_DEBOUNCE_DELAY must be greater than 16." #endif /** @@ -2732,3 +3152,54 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2) #if HAS_TMC_SPI && ALL(MONITOR_DRIVER_STATUS, SDSUPPORT, USES_SHARED_SPI) #error "MONITOR_DRIVER_STATUS and SDSUPPORT cannot be used together on boards with shared SPI." #endif + +// G60/G61 Position Save +#if SAVED_POSITIONS > 256 + #error "SAVED_POSITIONS must be an integer from 0 to 256." +#endif + +/** + * Stepper Chunk support + */ +#if BOTH(DIRECT_STEPPING, LIN_ADVANCE) + #error "DIRECT_STEPPING is incompatible with LIN_ADVANCE. Enable in external planner if possible." +#endif + +/** + * Touch Buttons + */ +#if ENABLED(TOUCH_SCREEN) + #ifndef XPT2046_X_CALIBRATION + #error "XPT2046_X_CALIBRATION must be defined with TOUCH_SCREEN." + #endif + #ifndef XPT2046_Y_CALIBRATION + #error "XPT2046_Y_CALIBRATION must be defined with TOUCH_SCREEN." + #endif + #ifndef XPT2046_X_OFFSET + #error "XPT2046_X_OFFSET must be defined with TOUCH_SCREEN." + #endif + #ifndef XPT2046_Y_OFFSET + #error "XPT2046_Y_OFFSET must be defined with TOUCH_SCREEN." + #endif +#endif + +/** + * Sanity check for WIFI + */ +#if EITHER(ESP3D_WIFISUPPORT, WIFISUPPORT) && DISABLED(ARDUINO_ARCH_ESP32) + #error "ESP3D_WIFISUPPORT or WIFISUPPORT requires an ESP32 MOTHERBOARD." +#endif + +/** + * Sanity Check for Password Feature + */ +#if ENABLED(PASSWORD_FEATURE) + #if NONE(HAS_LCD_MENU, PASSWORD_UNLOCK_GCODE, PASSWORD_CHANGE_GCODE) + #error "Without PASSWORD_UNLOCK_GCODE, PASSWORD_CHANGE_GCODE, or a supported LCD there's no way to unlock the printer or set a password." + #elif DISABLED(EEPROM_SETTINGS) + #warning "PASSWORD_FEATURE settings will be lost on power-off without EEPROM_SETTINGS." + #endif +#endif + +// Misc. Cleanup +#undef _TEST_PWM diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index d2415b94a9fd..00ca940662e9 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Release version. Leave the Marlin version or apply a custom scheme. */ #ifndef SHORT_BUILD_VERSION - #define SHORT_BUILD_VERSION "2.0.4.4" + #define SHORT_BUILD_VERSION "2.0.7.2" #endif /** @@ -33,7 +33,7 @@ * vendor name, download location, GitHub account, etc. */ #ifndef DETAILED_BUILD_VERSION - #define DETAILED_BUILD_VERSION SHORT_BUILD_VERSION " (GitHub)" + #define DETAILED_BUILD_VERSION SHORT_BUILD_VERSION #endif /** @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2020-02-27" + #define STRING_DISTRIBUTION_DATE "2020-10-15" #endif /** @@ -52,7 +52,7 @@ * to alert users to major changes. */ -#define MARLIN_HEX_VERSION 020004 +#define MARLIN_HEX_VERSION 020007 #ifndef REQUIRED_CONFIGURATION_H_VERSION #define REQUIRED_CONFIGURATION_H_VERSION MARLIN_HEX_VERSION #endif @@ -97,7 +97,7 @@ * documentation about a specific Marlin release. Displayed in the Info Menu. */ #ifndef WEBSITE_URL - #define WEBSITE_URL "http://marlinfw.org" + #define WEBSITE_URL "https://marlinfw.org" #endif /** diff --git a/Marlin/src/lcd/HD44780/lcdprint_hd44780.cpp b/Marlin/src/lcd/HD44780/lcdprint_hd44780.cpp index a1258a3b1035..aa3c3c04a123 100644 --- a/Marlin/src/lcd/HD44780/lcdprint_hd44780.cpp +++ b/Marlin/src/lcd/HD44780/lcdprint_hd44780.cpp @@ -14,7 +14,7 @@ #include "../../inc/MarlinConfigPre.h" -#if HAS_CHARACTER_LCD +#if HAS_MARLINUI_HD44780 #include "../ultralcd.h" #include "../../MarlinCore.h" @@ -23,10 +23,6 @@ #include -#ifndef LCD_CLASS - #include - #define LCD_CLASS LiquidCrystal -#endif extern LCD_CLASS lcd; int lcd_glyph_height() { return 1; } @@ -678,6 +674,8 @@ static const hd44780_charmap_t g_hd44780_charmap_common[] PROGMEM = { {IV('ď'), 'd', 0}, // 010F {IV('đ'), 'd', 0}, // 0111 {IV('ę'), 'e', 0}, // 0119 + {IV('Ě'), 'E', 0}, // 011A + {IV('ě'), 'e', 0}, // 011B {IV('ğ'), 'g', 0}, // 011F {IV('İ'), 'I', 0}, // 0130 {IV('ı'), 'i', 0}, // 0131 @@ -688,6 +686,7 @@ static const hd44780_charmap_t g_hd44780_charmap_common[] PROGMEM = { {IV('ń'), 'n', 0}, // 0144 {IV('ň'), 'n', 0}, // 0148 + {IV('Ř'), 'R', 0}, // 0158 {IV('ř'), 'r', 0}, // 0159 {IV('Ś'), 'S', 0}, // 015A {IV('ś'), 's', 0}, // 015B @@ -924,6 +923,7 @@ static const hd44780_charmap_t g_hd44780_charmap_common[] PROGMEM = { {IV('ю'), '|', 'o'}, {IV('я'), 'g', 0}, // 044F {IV('ё'), 'e', 0}, // 0451 + #endif {IV('•'), '.', 0}, // 2022 · @@ -982,7 +982,7 @@ int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) { if (max_length < 1) return 0; - // TODO: fix the '\\' that doesnt exist in the HD44870 + // TODO: fix the '\\' that doesn't exist in the HD44870 if (c < 128) { lcd.write((uint8_t)c); return 1; @@ -1119,4 +1119,4 @@ int lcd_put_u8str_max_P(PGM_P utf8_str_P, pixel_len_t max_length) { #endif // DEBUG_LCDPRINT -#endif // HAS_CHARACTER_LCD +#endif // HAS_MARLINUI_HD44780 diff --git a/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp b/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp index 7cee7db4b4df..e6cc22746571 100644 --- a/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp +++ b/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #include "../../inc/MarlinConfigPre.h" -#if HAS_CHARACTER_LCD +#if HAS_MARLINUI_HD44780 /** * ultralcd_HD44780.cpp @@ -102,7 +102,7 @@ static void createChar_P(const char c, const byte * const ptr) { byte temp[8]; - for (uint8_t i = 0; i < 8; i++) + LOOP_L_N(i, 8) temp[i] = pgm_read_byte(&ptr[i]); lcd.createChar(c, temp); } @@ -275,7 +275,7 @@ void MarlinUI::set_custom_characters(const HD44780CharSet screen_charset/*=CHARS #endif // LCD_PROGRESS_BAR - #if ENABLED(SDSUPPORT) && HAS_LCD_MENU + #if BOTH(SDSUPPORT, HAS_LCD_MENU) // CHARSET_MENU const static PROGMEM byte refresh[8] = { @@ -325,7 +325,7 @@ void MarlinUI::set_custom_characters(const HD44780CharSet screen_charset/*=CHARS #endif { createChar_P(LCD_STR_UPLEVEL[0], uplevel); - #if ENABLED(SDSUPPORT) && HAS_LCD_MENU + #if BOTH(SDSUPPORT, HAS_LCD_MENU) // SD Card sub-menu special characters createChar_P(LCD_STR_REFRESH[0], refresh); createChar_P(LCD_STR_FOLDER[0], folder); @@ -367,11 +367,11 @@ void MarlinUI::init_lcd() { } bool MarlinUI::detected() { - return true + return (true #if EITHER(LCD_I2C_TYPE_MCP23017, LCD_I2C_TYPE_MCP23008) && defined(DETECT_DEVICE) && lcd.LcdDetected() == 1 #endif - ; + ); } #if HAS_SLOW_BUTTONS @@ -414,7 +414,7 @@ void MarlinUI::clear_lcd() { lcd.clear(); } else { PGM_P p = text; int dly = time / _MAX(slen, 1); - for (uint8_t i = 0; i <= slen; i++) { + LOOP_LE_N(i, slen) { // Print the text at the correct place lcd_put_u8str_max_P(col, line, p, len); @@ -519,31 +519,24 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const } } -FORCE_INLINE void _draw_heater_status(const heater_ind_t heater, const char prefix, const bool blink) { +FORCE_INLINE void _draw_heater_status(const heater_id_t heater_id, const char prefix, const bool blink) { #if HAS_HEATED_BED - const bool isBed = heater < 0; - const float t1 = (isBed ? thermalManager.degBed() : thermalManager.degHotend(heater)), - t2 = (isBed ? thermalManager.degTargetBed() : thermalManager.degTargetHotend(heater)); + const bool isBed = TERN(HAS_HEATED_CHAMBER, heater_id == H_BED, heater_id < 0); + const float t1 = (isBed ? thermalManager.degBed() : thermalManager.degHotend(heater_id)), + t2 = (isBed ? thermalManager.degTargetBed() : thermalManager.degTargetHotend(heater_id)); #else - const float t1 = thermalManager.degHotend(heater), t2 = thermalManager.degTargetHotend(heater); + const float t1 = thermalManager.degHotend(heater_id), t2 = thermalManager.degTargetHotend(heater_id); #endif if (prefix >= 0) lcd_put_wchar(prefix); - lcd_put_u8str(i16tostr3(t1 + 0.5)); + lcd_put_u8str(i16tostr3rj(t1 + 0.5)); lcd_put_wchar('/'); #if !HEATER_IDLE_HANDLER UNUSED(blink); #else - const bool is_idle = ( - #if HAS_HEATED_BED - isBed ? thermalManager.bed_idle.timed_out : - #endif - thermalManager.hotend_idle[heater].timed_out - ); - - if (!blink && is_idle) { + if (!blink && thermalManager.heater_idle[thermalManager.idle_index_for_id(heater_id)].timed_out) { lcd_put_wchar(' '); if (t2 >= 10) lcd_put_wchar(' '); if (t2 >= 100) lcd_put_wchar(' '); @@ -560,29 +553,16 @@ FORCE_INLINE void _draw_heater_status(const heater_ind_t heater, const char pref } FORCE_INLINE void _draw_bed_status(const bool blink) { - _draw_heater_status(H_BED, ( - #if HAS_LEVELING - planner.leveling_active && blink ? '_' : - #endif - LCD_STR_BEDTEMP[0] - ), - blink - ); + _draw_heater_status(H_BED, TERN0(HAS_LEVELING, blink && planner.leveling_active) ? '_' : LCD_STR_BEDTEMP[0], blink); } #if HAS_PRINT_PROGRESS FORCE_INLINE void _draw_print_progress() { const uint8_t progress = ui.get_progress_percent(); - lcd_put_u8str_P(PSTR( - #if ENABLED(SDSUPPORT) - "SD" - #elif ENABLED(LCD_SET_PROGRESS_MANUALLY) - "P:" - #endif - )); + lcd_put_u8str_P(PSTR(TERN(SDSUPPORT, "SD", "P:"))); if (progress) - lcd_put_u8str(ui8tostr3(progress)); + lcd_put_u8str(ui8tostr3rj(progress)); else lcd_put_u8str_P(PSTR("---")); lcd_put_wchar('%'); @@ -631,7 +611,7 @@ void MarlinUI::draw_status_message(const bool blink) { lcd_put_u8str_P(PSTR("Dia ")); lcd_put_u8str(ftostr12ns(filwidth.measured_mm)); lcd_put_u8str_P(PSTR(" V")); - lcd_put_u8str(i16tostr3(planner.volumetric_percent(parser.volumetric_enabled))); + lcd_put_u8str(i16tostr3rj(planner.volumetric_percent(parser.volumetric_enabled))); lcd_put_wchar('%'); return; } @@ -745,7 +725,7 @@ void MarlinUI::draw_status_screen() { // // Hotend 1 or Bed Temperature // - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND lcd_moveto(8, 0); _draw_heater_status(H_E1, LCD_STR_THERMOMETER[0], blink); #elif HAS_HEATED_BED @@ -763,7 +743,7 @@ void MarlinUI::draw_status_screen() { // // Hotend 1 or Bed Temperature // - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND lcd_moveto(10, 0); _draw_heater_status(H_E1, LCD_STR_THERMOMETER[0], blink); #elif HAS_HEATED_BED @@ -791,7 +771,7 @@ void MarlinUI::draw_status_screen() { // If the first line has two extruder temps, // show more temperatures on the next line - #if HOTENDS > 2 || (HOTENDS > 1 && HAS_HEATED_BED) + #if HOTENDS > 2 || (HAS_MULTI_HOTEND && HAS_HEATED_BED) #if HOTENDS > 2 _draw_heater_status(H_E2, LCD_STR_THERMOMETER[0], blink); @@ -802,7 +782,7 @@ void MarlinUI::draw_status_screen() { #else // HOTENDS <= 2 && (HOTENDS <= 1 || !HAS_HEATED_BED) - #if DUAL_MIXING_EXTRUDER + #if HAS_DUAL_MIXING // Two-component mix / gradient instead of XY @@ -822,19 +802,11 @@ void MarlinUI::draw_status_screen() { sprintf_P(mixer_messages, PSTR("%s %d;%d%% "), mix_label, int(mixer.mix[0]), int(mixer.mix[1])); lcd_put_u8str(mixer_messages); - #else // !DUAL_MIXING_EXTRUDER + #else // !HAS_DUAL_MIXING - if (true - #if ENABLED(LCD_SHOW_E_TOTAL) - && !printingIsActive() - #endif - ) { - xy_pos_t lpos = current_position; toLogical(lpos); - _draw_axis_value(X_AXIS, ftostr4sign(lpos.x), blink); - lcd_put_wchar(' '); - _draw_axis_value(Y_AXIS, ftostr4sign(lpos.y), blink); - } - else { + const bool show_e_total = TERN0(LCD_SHOW_E_TOTAL, printingIsActive() || marlin_state == MF_SD_COMPLETE); + + if (show_e_total) { #if ENABLED(LCD_SHOW_E_TOTAL) char tmp[20]; const uint8_t escale = e_move_accumulator >= 100000.0f ? 10 : 1; // After 100m switch to cm @@ -842,8 +814,14 @@ void MarlinUI::draw_status_screen() { lcd_put_u8str(tmp); #endif } + else { + const xy_pos_t lpos = current_position.asLogical(); + _draw_axis_value(X_AXIS, ftostr4sign(lpos.x), blink); + lcd_put_wchar(' '); + _draw_axis_value(Y_AXIS, ftostr4sign(lpos.y), blink); + } - #endif // !DUAL_MIXING_EXTRUDER + #endif // !HAS_DUAL_MIXING #endif // HOTENDS <= 2 && (HOTENDS <= 1 || !HAS_HEATED_BED) @@ -863,14 +841,35 @@ void MarlinUI::draw_status_screen() { #if LCD_HEIGHT > 3 lcd_put_wchar(0, 2, LCD_STR_FEEDRATE[0]); - lcd_put_u8str(i16tostr3(feedrate_percentage)); + lcd_put_u8str(i16tostr3rj(feedrate_percentage)); lcd_put_wchar('%'); char buffer[14]; - duration_t elapsed = print_job_timer.duration(); - const uint8_t len = elapsed.toDigital(buffer), - timepos = LCD_WIDTH - len - 1; - lcd_put_wchar(timepos, 2, LCD_STR_CLOCK[0]); + uint8_t timepos = 0; + #if ENABLED(SHOW_REMAINING_TIME) + const bool show_remain = TERN1(ROTATE_PROGRESS_DISPLAY, blink) && (printingIsActive() || marlin_state == MF_SD_COMPLETE); + if (show_remain) { + #if ENABLED(USE_M73_REMAINING_TIME) + duration_t remaining = get_remaining_time(); + #else + uint8_t progress = get_progress_percent(); + uint32_t elapsed = print_job_timer.duration(); + duration_t remaining = (progress > 0) ? ((elapsed * 25600 / progress) >> 8) - elapsed : 0; + #endif + const uint8_t len = remaining.toDigital(buffer); + timepos = LCD_WIDTH - 1 - len; + lcd_put_wchar(timepos, 2, 'R'); + } + #else + constexpr bool show_remain = false; + #endif + + if (!show_remain) { + duration_t elapsed = print_job_timer.duration(); + const uint8_t len = elapsed.toDigital(buffer); + timepos = LCD_WIDTH - 1 - len; + lcd_put_wchar(timepos, 2, LCD_STR_CLOCK[0]); + } lcd_put_u8str(buffer); #if LCD_WIDTH >= 20 @@ -902,7 +901,7 @@ void MarlinUI::draw_status_screen() { #endif } lcd_put_wchar(c); - lcd_put_u8str(i16tostr3(per)); + lcd_put_u8str(i16tostr3rj(per)); lcd_put_wchar('%'); #endif #endif @@ -924,7 +923,7 @@ void MarlinUI::draw_status_screen() { lcd_moveto(LCD_WIDTH - 9, 0); _draw_axis_value(Z_AXIS, ftostr52sp(LOGICAL_Z_POSITION(current_position.z)), blink); - #if HAS_LEVELING && (HOTENDS > 1 || !HAS_HEATED_BED) + #if HAS_LEVELING && (HAS_MULTI_HOTEND || !HAS_HEATED_BED) lcd_put_wchar(LCD_WIDTH - 1, 0, planner.leveling_active || blink ? '_' : ' '); #endif @@ -934,14 +933,14 @@ void MarlinUI::draw_status_screen() { // Hotend 1 or Bed Temperature // lcd_moveto(0, 1); - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND _draw_heater_status(H_E1, LCD_STR_THERMOMETER[0], blink); #elif HAS_HEATED_BED _draw_bed_status(blink); #endif lcd_put_wchar(LCD_WIDTH - 9, 1, LCD_STR_FEEDRATE[0]); - lcd_put_u8str(i16tostr3(feedrate_percentage)); + lcd_put_u8str(i16tostr3rj(feedrate_percentage)); lcd_put_wchar('%'); // ========== Line 3 ========== @@ -952,7 +951,7 @@ void MarlinUI::draw_status_screen() { lcd_moveto(0, 2); #if HOTENDS > 2 _draw_heater_status(H_E2, LCD_STR_THERMOMETER[0], blink); - #elif HOTENDS > 1 && HAS_HEATED_BED + #elif HAS_MULTI_HOTEND && HAS_HEATED_BED _draw_bed_status(blink); #elif HAS_PRINT_PROGRESS #define DREW_PRINT_PROGRESS @@ -992,55 +991,56 @@ void MarlinUI::draw_status_screen() { void MarlinUI::draw_hotend_status(const uint8_t row, const uint8_t extruder) { if (row < LCD_HEIGHT) { lcd_moveto(LCD_WIDTH - 9, row); - _draw_heater_status((heater_ind_t)extruder, LCD_STR_THERMOMETER[0], get_blink()); + _draw_heater_status((heater_id_t)extruder, LCD_STR_THERMOMETER[0], get_blink()); } } #endif // ADVANCED_PAUSE_FEATURE // Draw a static item with no left-right margin required. Centered by default. - void MenuItem_static::draw(const uint8_t row, PGM_P const pstr, const uint8_t style/*=SS_DEFAULT*/, const char * const valstr/*=nullptr*/) { + void MenuItem_static::draw(const uint8_t row, PGM_P const pstr, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) { int8_t n = LCD_WIDTH; lcd_moveto(0, row); - if ((style & SS_CENTER) && !valstr) { - int8_t pad = (LCD_WIDTH - utf8_strlen_P(pstr)) / 2; + const int8_t plen = pstr ? utf8_strlen_P(pstr) : 0, + vlen = vstr ? utf8_strlen(vstr) : 0; + if (style & SS_CENTER) { + int8_t pad = (LCD_WIDTH - plen - vlen) / 2; while (--pad >= 0) { lcd_put_wchar(' '); n--; } } - n = lcd_put_u8str_ind_P(pstr, itemIndex, n); - if (valstr) n -= lcd_put_u8str_max(valstr, n); + if (plen) n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, n); + if (vlen) n -= lcd_put_u8str_max(vstr, n); for (; n > 0; --n) lcd_put_wchar(' '); } // Draw a generic menu item with pre_char (if selected) and post_char void MenuItemBase::_draw(const bool sel, const uint8_t row, PGM_P const pstr, const char pre_char, const char post_char) { lcd_put_wchar(0, row, sel ? pre_char : ' '); - uint8_t n = lcd_put_u8str_ind_P(pstr, itemIndex, LCD_WIDTH - 2); + uint8_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 2); for (; n; --n) lcd_put_wchar(' '); lcd_put_wchar(post_char); } // Draw a menu item with a (potentially) editable value - void MenuEditItemBase::draw(const bool sel, const uint8_t row, PGM_P const pstr, const char* const data, const bool pgm) { - const uint8_t vlen = data ? (pgm ? utf8_strlen_P(data) : utf8_strlen(data)) : 0; + void MenuEditItemBase::draw(const bool sel, const uint8_t row, PGM_P const pstr, const char* const inStr, const bool pgm) { + const uint8_t vlen = inStr ? (pgm ? utf8_strlen_P(inStr) : utf8_strlen(inStr)) : 0; lcd_put_wchar(0, row, sel ? LCD_STR_ARROW_RIGHT[0] : ' '); - uint8_t n = lcd_put_u8str_ind_P(pstr, itemIndex, LCD_WIDTH - 2 - vlen); + uint8_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 2 - vlen); if (vlen) { lcd_put_wchar(':'); for (; n; --n) lcd_put_wchar(' '); - if (pgm) lcd_put_u8str_P(data); else lcd_put_u8str(data); + if (pgm) lcd_put_u8str_P(inStr); else lcd_put_u8str(inStr); } } // Low-level draw_edit_screen can be used to draw an edit screen from anyplace void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char* const value/*=nullptr*/) { ui.encoder_direction_normal(); - - uint8_t n = lcd_put_u8str_ind_P(0, 1, pstr, itemIndex, LCD_WIDTH - 1); + uint8_t n = lcd_put_u8str_ind_P(0, 1, pstr, itemIndex, itemString, LCD_WIDTH - 1); if (value != nullptr) { - lcd_put_wchar(':'); - int len = utf8_strlen(value); - const lcd_uint_t valrow = (n < len + 1) ? 2 : 1; // Value on the next row if it won't fit - lcd_put_wchar((LCD_WIDTH - 1) - (len + 1), valrow, ' '); // Right-justified, padded, leading space + lcd_put_wchar(':'); n--; + const uint8_t len = utf8_strlen(value) + 1; // Plus one for a leading space + const lcd_uint_t valrow = n < len ? 2 : 1; // Value on the next row if it won't fit + lcd_put_wchar(LCD_WIDTH - len, valrow, ' '); // Right-justified, padded, leading space lcd_put_u8str(value); } } @@ -1073,46 +1073,22 @@ void MarlinUI::draw_status_screen() { static uint8_t ledsprev = 0; uint8_t leds = 0; - #if HAS_HEATED_BED - if (thermalManager.degTargetBed() > 0) leds |= LED_A; - #endif - - #if HOTENDS - if (thermalManager.degTargetHotend(0) > 0) leds |= LED_B; - #endif - - #if FAN_COUNT > 0 - if (0 - #if HAS_FAN0 - || thermalManager.fan_speed[0] - #endif - #if HAS_FAN1 - || thermalManager.fan_speed[1] - #endif - #if HAS_FAN2 - || thermalManager.fan_speed[2] - #endif - #if HAS_FAN3 - || thermalManager.fan_speed[3] - #endif - #if HAS_FAN4 - || thermalManager.fan_speed[4] - #endif - #if HAS_FAN5 - || thermalManager.fan_speed[5] - #endif - #if HAS_FAN6 - || thermalManager.fan_speed[6] - #endif - #if HAS_FAN7 - || thermalManager.fan_speed[7] - #endif + if (TERN0(HAS_HEATED_BED, thermalManager.degTargetBed() > 0)) leds |= LED_A; + if (TERN0(HAS_HOTEND, thermalManager.degTargetHotend(0) > 0)) leds |= LED_B; + + #if HAS_FAN + if ( TERN0(HAS_FAN0, thermalManager.fan_speed[0]) + || TERN0(HAS_FAN1, thermalManager.fan_speed[1]) + || TERN0(HAS_FAN2, thermalManager.fan_speed[2]) + || TERN0(HAS_FAN3, thermalManager.fan_speed[3]) + || TERN0(HAS_FAN4, thermalManager.fan_speed[4]) + || TERN0(HAS_FAN5, thermalManager.fan_speed[5]) + || TERN0(HAS_FAN6, thermalManager.fan_speed[6]) + || TERN0(HAS_FAN7, thermalManager.fan_speed[7]) ) leds |= LED_C; - #endif // FAN_COUNT > 0 + #endif // HAS_FAN - #if HOTENDS > 1 - if (thermalManager.degTargetHotend(1) > 0) leds |= LED_C; - #endif + if (TERN0(HAS_MULTI_HOTEND, thermalManager.degTargetHotend(1) > 0)) leds |= LED_C; if (leds != ledsprev) { lcd.setBacklight(leds); @@ -1212,10 +1188,10 @@ void MarlinUI::draw_status_screen() { #define _LCD_W_POS 12 #define _PLOT_X 1 #define _MAP_X 3 - #define _LABEL(C,X,Y) lcd_put_u8str(X, Y, C) - #define _XLABEL(X,Y) _LABEL("X:",X,Y) - #define _YLABEL(X,Y) _LABEL("Y:",X,Y) - #define _ZLABEL(X,Y) _LABEL("Z:",X,Y) + #define _LABEL(C,X,Y) lcd_put_u8str_P(X, Y, C) + #define _XLABEL(X,Y) _LABEL(X_LBL,X,Y) + #define _YLABEL(X,Y) _LABEL(Y_LBL,X,Y) + #define _ZLABEL(X,Y) _LABEL(Z_LBL,X,Y) #else #define _LCD_W_POS 8 #define _PLOT_X 0 @@ -1415,9 +1391,9 @@ void MarlinUI::draw_status_screen() { * Print plot position */ lcd_put_wchar(_LCD_W_POS, 0, '('); - lcd_put_u8str(ui8tostr3(x_plot)); + lcd_put_u8str(ui8tostr3rj(x_plot)); lcd_put_wchar(','); - lcd_put_u8str(ui8tostr3(y_plot)); + lcd_put_u8str(ui8tostr3rj(y_plot)); lcd_put_wchar(')'); #if LCD_HEIGHT <= 3 // 16x2 or 20x2 display @@ -1541,4 +1517,4 @@ void MarlinUI::draw_status_screen() { #endif // HAS_LCD_MENU -#endif // HAS_CHARACTER_LCD +#endif // HAS_MARLINUI_HD44780 diff --git a/Marlin/src/lcd/HD44780/ultralcd_HD44780.h b/Marlin/src/lcd/HD44780/ultralcd_HD44780.h index 12bf86a1618c..604d26a029b4 100644 --- a/Marlin/src/lcd/HD44780/ultralcd_HD44780.h +++ b/Marlin/src/lcd/HD44780/ultralcd_HD44780.h @@ -16,32 +16,19 @@ * 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 . + * along with this program. If not, see . * */ #pragma once /** - * Implementation of the LCD display routines for a Hitachi HD44780 display. - * These are the most common LCD character displays. + * Hitachi HD44780 display defines and headers */ #include "../../inc/MarlinConfig.h" -#if LCD_HEIGHT > 3 - #include "../../libs/duration_t.h" -#endif - -//////////////////////////////////// -// Setup button and encode mappings for each panel (into 'buttons' variable -// -// This is just to map common functions (across different panels) onto the same -// macro name. The mapping is independent of whether the button is directly connected or -// via a shift/i2c register. - -//////////////////////////////////// -// Create LCD class instance and chipset-specific information #if ENABLED(LCD_I2C_TYPE_PCF8575) + // NOTE: These are register-mapped pins on the PCF8575 controller, not Arduino pins. #define LCD_I2C_PIN_BL 3 #define LCD_I2C_PIN_EN 2 @@ -58,6 +45,7 @@ #define LCD_CLASS LiquidCrystal_I2C #elif ENABLED(LCD_I2C_TYPE_MCP23017) + // For the LED indicators (which may be mapped to different events in update_indicators()) #define LCD_HAS_STATUS_INDICATORS #define LED_A 0x04 //100 @@ -69,40 +57,45 @@ #define LCD_CLASS LiquidTWI2 #elif ENABLED(LCD_I2C_TYPE_MCP23008) + #include #include #define LCD_CLASS LiquidTWI2 #elif ENABLED(LCD_I2C_TYPE_PCA8574) + #include #define LCD_CLASS LiquidCrystal_I2C #elif ENABLED(SR_LCD_2W_NL) + // 2 wire Non-latching LCD SR from: // https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection -// extern "C" void __cxa_pure_virtual() { while (1); } #include #include #define LCD_CLASS LiquidCrystal_SR + #elif ENABLED(SR_LCD_3W_NL) -//NewLiquidCrystal was not working for me, but this worked first try -//https://github.com/mikeshub/SailfishLCD -//uses the code directly from Sailfish + // NewLiquidCrystal didn't work, so this uses + // https://github.com/mikeshub/SailfishLCD #include #define LCD_CLASS LiquidCrystalSerial #elif ENABLED(LCM1602) + #include #include #include #define LCD_CLASS LiquidCrystal_I2C #else + // Standard directly connected LCD implementations #include #define LCD_CLASS LiquidCrystal + #endif #include "../fontutils.h" diff --git a/Marlin/src/lcd/TFTGLCD/lcdprint_TFTGLCD.cpp b/Marlin/src/lcd/TFTGLCD/lcdprint_TFTGLCD.cpp new file mode 100644 index 000000000000..51681a800953 --- /dev/null +++ b/Marlin/src/lcd/TFTGLCD/lcdprint_TFTGLCD.cpp @@ -0,0 +1,1142 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * @file lcdprint_TFTGLCD.cpp + * @brief LCD print API for TFT-GLCD interface + * @author Yunhui Fu (yhfudev@gmail.com) + * @version 1.0 + * @date 2016-08-19 + * @copyright GPL/BSD + */ + +/** + * The TFTGLCD only supports ??? languages. + */ + +#include "../../inc/MarlinConfigPre.h" + +#if IS_TFTGLCD_PANEL + +#include "../ultralcd.h" +#include "../../MarlinCore.h" +#include "../../libs/numtostr.h" + +#include "ultralcd_TFTGLCD.h" + +#include + +int lcd_glyph_height(void) { return 1; } + +typedef struct _TFTGLCD_charmap_t { + wchar_t uchar; // the unicode char + uint8_t idx; // the glyph of the char in the ROM + uint8_t idx2; // the char used to be combined with the idx to simulate a single char +} TFTGLCD_charmap_t; + +#ifdef __AVR__ + #define IV(a) U##a +#else + #define IV(a) L##a +#endif + +static const TFTGLCD_charmap_t g_TFTGLCD_charmap_device[] PROGMEM = { + // sorted by uchar: + #if DISPLAY_CHARSET_HD44780 == JAPANESE + + {IV('¢'), 0xEC, 0}, // A2 + {IV('°'), 0xDF, 0}, // B0, Marlin special: '°' LCD_STR_DEGREE (0x09) + {IV('ä'), 0xE1, 0}, // E4 + {IV('ö'), 0xEF, 0}, // F6 + {IV('÷'), 0xFD, 0}, // 00F7 + {IV('ü'), 0xF5, 0}, // 00FC + {IV('ˣ'), 0xEB, 0}, // 02E3 + + {IV('·'), 0xA5, 0}, // 0387 + {IV('Ώ'), 0xF4, 0}, // 038F + {IV('Θ'), 0xF2, 0}, // 0398, Theta + {IV('Ξ'), 0xE3, 0}, // 039E, Xi + {IV('Σ'), 0xF6, 0}, // 03A3, Sigma + {IV('Ω'), 0xF4, 0}, // 03A9, Omega + {IV('ά'), 0xE0, 0}, // 03AC + {IV('έ'), 0xE3, 0}, // 03AD + {IV('α'), 0xE0, 0}, // 03B1, alpha + {IV('β'), 0xE2, 0}, // 03B2, beta + {IV('ε'), 0xE3, 0}, // 03B5, epsilon + {IV('θ'), 0xF2, 0}, // 03B8, theta + {IV('μ'), 0xE4, 0}, // 03BC, mu + {IV('ξ'), 0xE3, 0}, // 03BE, xi + {IV('π'), 0xF7, 0}, // 03C0, pi + {IV('ρ'), 0xE6, 0}, // 03C1, rho + {IV('σ'), 0xE5, 0}, // 03C3, sigma + + {IV('←'), 0x7F, 0}, // 2190 + {IV('→'), 0x7E, 0}, // 2192, Marlin special: '⮈⮉⮊⮋➤→' LCD_STR_ARROW_RIGHT (0x03) + {IV('√'), 0xE8, 0}, // 221A + {IV('∞'), 0xF3, 0}, // 221E + {IV('█'), 0xFF, 0}, // 2588 + + //{IV(''), 0xA0, 0}, + {IV('。'), 0xA1, 0}, + {IV('「'), 0xA2, 0}, + {IV('」'), 0xA3, 0}, + {IV('゛'), 0xDE, 0}, // ‶ + {IV('゜'), 0xDF, 0}, // '〫' + {IV('゠'), '=', 0}, + {IV('ァ'), 0xA7, 0}, + {IV('ア'), 0xB1, 0}, + {IV('ィ'), 0xA8, 0}, + {IV('イ'), 0xB2, 0}, + {IV('ゥ'), 0xA9, 0}, + {IV('ウ'), 0xB3, 0}, + {IV('ェ'), 0xAA, 0}, + {IV('エ'), 0xB4, 0}, + {IV('ォ'), 0xAB, 0}, + + {IV('オ'), 0xB5, 0}, + {IV('カ'), 0xB6, 0}, + {IV('ガ'), 0xB6, 0xDE}, + {IV('キ'), 0xB7, 0}, + {IV('ギ'), 0xB7, 0xDE}, // + {IV('ク'), 0xB8, 0}, + {IV('グ'), 0xB8, 0xDE}, + {IV('ケ'), 0xB9, 0}, + {IV('ゲ'), 0xB9, 0xDE}, + {IV('コ'), 0xBA, 0}, + {IV('ゴ'), 0xBA, 0xDE}, + {IV('サ'), 0xBB, 0}, + {IV('ザ'), 0xBB, 0xDE}, + {IV('シ'), 0xBC, 0}, + {IV('ジ'), 0xBC, 0xDE}, + {IV('ス'), 0xBD, 0}, + {IV('ズ'), 0xBD, 0xDE}, + {IV('セ'), 0xBE, 0}, + {IV('ゼ'), 0xBE, 0xDE}, + {IV('ソ'), 0xBF, 0}, + {IV('ゾ'), 0xBF, 0xDE}, + + {IV('タ'), 0xC0, 0}, + {IV('ダ'), 0xC0, 0xDE}, + {IV('チ'), 0xC1, 0}, + {IV('ヂ'), 0xC1, 0xDE}, + {IV('ッ'), 0xAF, 0}, + {IV('ツ'), 0xC2, 0}, + {IV('ヅ'), 0xC2, 0xDE}, + {IV('テ'), 0xC3, 0}, + {IV('デ'), 0xC3, 0xDE}, + {IV('ト'), 0xC4, 0}, + {IV('ド'), 0xC4, 0xDE}, + {IV('ナ'), 0xC5, 0}, + {IV('ニ'), 0xC6, 0}, + {IV('ヌ'), 0xC7, 0}, + {IV('ネ'), 0xC8, 0}, + {IV('ノ'), 0xC9, 0}, + {IV('ハ'), 0xCA, 0}, + {IV('バ'), 0xCA, 0xDE}, + {IV('パ'), 0xCA, 0xDF}, + {IV('ヒ'), 0xCB, 0}, + {IV('ビ'), 0xCB, 0xDE}, + {IV('ピ'), 0xCB, 0xDF}, + {IV('フ'), 0xCC, 0}, + {IV('ブ'), 0xCC, 0xDE}, + {IV('プ'), 0xCC, 0xDF}, + {IV('ヘ'), 0xCD, 0}, + {IV('ベ'), 0xCD, 0xDE}, + {IV('ペ'), 0xCD, 0xDF}, + {IV('ホ'), 0xCE, 0}, + {IV('ボ'), 0xCE, 0xDE}, + {IV('ポ'), 0xCE, 0xDF}, + {IV('マ'), 0xCF, 0}, + + {IV('ミ'), 0xD0, 0}, + {IV('ム'), 0xD1, 0}, + {IV('メ'), 0xD2, 0}, + {IV('モ'), 0xD3, 0}, + {IV('ャ'), 0xAC, 0}, + {IV('ヤ'), 0xD4, 0}, + {IV('ュ'), 0xAD, 0}, + {IV('ユ'), 0xD5, 0}, + {IV('ョ'), 0xAE, 0}, + {IV('ヨ'), 0xD6, 0}, + {IV('ラ'), 0xD7, 0}, + {IV('リ'), 0xD8, 0}, + {IV('ル'), 0xD9, 0}, + {IV('レ'), 0xDA, 0}, + {IV('ロ'), 0xDB, 0}, + {IV('ワ'), 0xDC, 0}, + {IV('ヲ'), 0xA6, 0}, + {IV('ン'), 0xDD, 0}, + {IV('ヴ'), 0xB3, 0xDE}, + {IV('ヷ'), 0xDC, 0xDE}, + {IV('ヺ'), 0xA6, 0xDE}, + {IV('・'), 0xA5, 0}, + {IV('ー'), 0xB0, 0}, + {IV('ヽ'), 0xA4, 0}, + + //{IV('g'), 0xE7, 0}, // error + //{IV(''), 0xE9, 0}, + //{IV('j'), 0xEA, 0}, // error + //{IV(''), 0xED, 0}, + //{IV(''), 0xEE, 0}, + + //{IV('p'), 0xF0, 0}, // error + //{IV('q'), 0xF1, 0}, // error + //{IV(''), 0xF8, 0}, + //{IV('y'), 0xF9, 0}, // error + {IV('万'), 0xFB, 0}, + {IV('円'), 0xFC, 0}, + {IV('千'), 0xFA, 0}, + //{IV(''), 0xFE, 0}, + + //、・ヲァィゥェォャュョッー + {IV('、'), 0xA4, 0}, //ヽ + {IV('・'), 0xA5, 0}, //・ + {IV('ヲ'), 0xA6, 0}, //ヲ + {IV('ァ'), 0xA7, 0}, //ァ + {IV('ィ'), 0xA8, 0}, //ィ + {IV('ゥ'), 0xA9, 0}, //ゥ + {IV('ェ'), 0xAA, 0}, //ェ + {IV('ォ'), 0xAB, 0}, //ォ + {IV('ャ'), 0xAC, 0}, //ャ + {IV('ュ'), 0xAD, 0}, //ュ + {IV('ョ'), 0xAE, 0}, //ョ + {IV('ッ'), 0xAF, 0}, //ッ + {IV('ー'), 0xB0, 0}, //ー + + //アイウエオカキクケコサシスセ + {IV('ア'), 0xB1, 0}, //ア + {IV('イ'), 0xB2, 0}, //イ + {IV('ウ'), 0xB3, 0}, //ウ + {IV('エ'), 0xB4, 0}, //エ + {IV('オ'), 0xB5, 0}, //オ + {IV('カ'), 0xB6, 0}, //カ + {IV('キ'), 0xB7, 0}, //キ + {IV('ク'), 0xB8, 0}, //ク + {IV('ケ'), 0xB9, 0}, //ケ + {IV('コ'), 0xBA, 0}, //コ + {IV('サ'), 0xBB, 0}, //サ + {IV('シ'), 0xBC, 0}, //シ + {IV('ス'), 0xBD, 0}, //ス + {IV('セ'), 0xBE, 0}, //セ + + //ソタチツテトナニヌネノハヒフ + {IV('ソ'), 0xBF, 0}, //ソ + {IV('タ'), 0xC0, 0}, //タ + {IV('チ'), 0xC1, 0}, //チ + {IV('ツ'), 0xC2, 0}, //ツ + {IV('テ'), 0xC3, 0}, //テ + {IV('ト'), 0xC4, 0}, //ト + {IV('ナ'), 0xC5, 0}, //ナ + {IV('ニ'), 0xC6, 0}, //ニ + {IV('ヌ'), 0xC7, 0}, //ヌ + {IV('ネ'), 0xC8, 0}, //ネ + {IV('ノ'), 0xC9, 0}, //ノ + {IV('ハ'), 0xCA, 0}, //ハ + {IV('ヒ'), 0xCB, 0}, //ヒ + {IV('フ'), 0xCC, 0}, //フ + + //ヘホマミムメモヤユヨラリルレロワン゙゚ + {IV('ヘ'), 0xCD, 0}, //ヘ + {IV('ホ'), 0xCE, 0}, //ホ + {IV('マ'), 0xCF, 0}, //マ + {IV('ミ'), 0xD0, 0}, //ミ + {IV('ム'), 0xD1, 0}, //ム + {IV('メ'), 0xD2, 0}, //メ + {IV('モ'), 0xD3, 0}, //モ + {IV('ヤ'), 0xD4, 0}, //ヤ + {IV('ユ'), 0xD5, 0}, //ユ + {IV('ヨ'), 0xD6, 0}, //ヨ + {IV('ラ'), 0xD7, 0}, //ラ + {IV('リ'), 0xD8, 0}, //リ + {IV('ル'), 0xD9, 0}, //ル + {IV('レ'), 0xDA, 0}, //レ + {IV('ロ'), 0xDB, 0}, //ロ + {IV('ワ'), 0xDC, 0}, //ワ + {IV('ン'), 0xDD, 0}, //ン + {IV('゙'), 0xDE, 0}, // ゛ + {IV('゚'), 0xDF, 0}, // ゜ + + {IV('¥'), 0x5C, 0}, + + #elif DISPLAY_CHARSET_HD44780 == WESTERN + // 0x10 -- 0x1F (except 0x1C) + // 0x80 -- 0xFF (except 0xA7,0xB0,0xB1,0xB3,0xB4,0xBF,0xD1,0xF8,0xFA,0xFC-0xFF) + + {IV('¡'), 0xA9, 0}, + {IV('¢'), 0xA4, 0}, + {IV('£'), 0xA5, 0}, + {IV('¥'), 0xA6, 0}, + {IV('§'), 0xD2, 0}, // section sign + {IV('©'), 0xCF, 0}, + + {IV('ª'), 0x9D, 0}, + {IV('«'), 0xBB, 0}, + {IV('®'), 0xCE, 0}, + + {IV('°'), 0xB2, 0}, // Marlin special: '°' LCD_STR_DEGREE (0x09) + //{IV(''), 0xD1, 0}, + {IV('±'), 0x10, 0}, //∓± + //{'='), 0x1C, 0}, // error + {IV('²'), 0x1E, 0}, + {IV('³'), 0x1F, 0}, + {IV('¶'), 0xD3, 0}, // pilcrow sign + {IV('º'), 0x9E, 0}, + {IV('»'), 0xBC, 0}, // 00BB + //{IV(''), 0xB3, 0}, // error + //{IV(''), 0xB4, 0}, // error + {IV('¼'), 0xB6, 0}, // 00BC + {IV('½'), 0xB5, 0}, // 00BD + //{IV('¾'), '3', 0}, // 00BE + {IV('¿'), 0x9F, 0}, // 00BF + + {IV('Â'), 0x8F, 0}, + {IV('Ã'), 0xAA, 0}, + {IV('Ä'), 0x8E, 0}, + {IV('Æ'), 0x92, 0}, + {IV('Ç'), 0x80, 0}, + {IV('É'), 0x90, 0}, + {IV('Ñ'), 0x9C, 0}, + {IV('Õ'), 0xAC, 0}, + {IV('Ö'), 0x99, 0}, + {IV('×'), 0xB7, 0}, + {IV('Ø'), 0xAE, 0}, + {IV('Ü'), 0x9A, 0}, + {IV('à'), 0x85, 0}, + {IV('á'), 0xA0, 0}, + {IV('â'), 0x83, 0}, + {IV('ã'), 0xAB, 0}, + {IV('ä'), 0x84, 0}, + {IV('å'), 0x86, 0}, + {IV('æ'), 0x91, 0}, + {IV('ç'), 0x87, 0}, + {IV('è'), 0x8A, 0}, + {IV('é'), 0x82, 0}, + {IV('ê'), 0x88, 0}, + {IV('ë'), 0x89, 0}, + {IV('ì'), 0x8D, 0}, + {IV('í'), 0xA1, 0}, + {IV('î'), 0x8C, 0}, + {IV('ï'), 0x8B, 0}, + + {IV('ñ'), 0x9B, 0}, + {IV('ò'), 0x95, 0}, + {IV('ó'), 0xA2, 0}, + {IV('ô'), 0x93, 0}, + {IV('õ'), 0xAD, 0}, + {IV('ö'), 0x94, 0}, + {IV('÷'), 0xB8, 0}, + {IV('ø'), 0xAF, 0}, + {IV('ù'), 0x97, 0}, + {IV('ú'), 0xA3, 0}, + {IV('û'), 0x96, 0}, + {IV('ü'), 0x81, 0}, + {IV('ÿ'), 0x98, 0}, + + //{IV(''), 0xB0, 0}, // error + //{IV(''), 0xB1, 0}, // error + {IV('ƒ'), 0xA8, 0}, // 0192 + + {IV('Ύ'), 0xDB, 0}, // 038E + {IV('Ώ'), 0xDE, 0}, // 038F + {IV('ΐ'), 0xE7, 0}, // 0390 + + {IV('Γ'), 0xD4, 0}, // 0393, Gamma + {IV('Δ'), 0xD5, 0}, // 0394, Delta, ◿ + {IV('Θ'), 0xD6, 0}, // 0398, Theta + {IV('Λ'), 0xD7, 0}, // 039B, Lambda + {IV('Ξ'), 0xD8, 0}, // 039E, Xi + {IV('Π'), 0xD9, 0}, // Pi + {IV('Σ'), 0xDA, 0}, // Sigma + {IV('Υ'), 0xDB, 0}, // Upsilon + {IV('Φ'), 0xDC, 0}, // Phi + {IV('Ψ'), 0xDD, 0}, // Psi + {IV('Ω'), 0xDE, 0}, // Omega + + {IV('ά'), 0xDF, 0}, // 03AC + {IV('έ'), 0xE3, 0}, // 03AD + {IV('ή'), 0xE5, 0}, // 03AE + {IV('ί'), 0xE7, 0}, // 03AF + {IV('ΰ'), 0xF1, 0}, // 03B0 + + {IV('α'), 0xDF, 0}, // alpha + {IV('β'), 0xE0, 0}, // beta + {IV('γ'), 0xE1, 0}, // gamma + {IV('δ'), 0xE2, 0}, // delta + {IV('ε'), 0xE3, 0}, // epsilon + {IV('ζ'), 0xE4, 0}, // zeta + {IV('η'), 0xE5, 0}, // eta + {IV('θ'), 0xE6, 0}, // theta + {IV('ι'), 0xE7, 0}, // lota + {IV('κ'), 0xE8, 0}, // kappa + {IV('λ'), 0xE9, 0}, // lambda + {IV('μ'), 0xEA, 0}, // mu + {IV('ν'), 0xEB, 0}, // nu + {IV('ξ'), 0xEC, 0}, // xi + {IV('π'), 0xED, 0}, // pi + {IV('ρ'), 0xEE, 0}, // rho + {IV('σ'), 0xEF, 0}, // sigma + + {IV('τ'), 0xF0, 0}, // tau + {IV('υ'), 0xF1, 0}, // upsilon + {IV('χ'), 0xF2, 0}, // chi + {IV('ψ'), 0xF3, 0}, // psi + {IV('ω'), 0xF4, 0}, // 03C9, omega + {IV('ϊ'), 0xE7, 0}, // 03CA + {IV('ϋ'), 0xF1, 0}, // 03CB + {IV('ύ'), 0xF1, 0}, // 03CD + {IV('ώ'), 0xF4, 0}, // 03CE + + {IV('•'), 0xCD, 0}, // · + {IV('℞'), 0xA7, 0}, // ℞ Pt ASCII 158 + {IV('™'), 0xD0, 0}, + {IV('↤'), 0xF9, 0}, // ⟻ + {IV('↵'), 0xC4, 0}, + {IV('↻'), 0x04, 0}, // Marlin special: '↻↺⟳⟲' LCD_STR_REFRESH (0x01) + {IV('⇥'), 0xFB, 0}, + {IV('√'), 0xBE, 0}, // √ + {IV('∞'), 0xC2, 0}, // infinity + {IV('∫'), 0x1B, 0}, + {IV('∼'), 0x1D, 0}, + {IV('≈'), 0x1A, 0}, + {IV('≠'), 0xBD, 0}, + {IV('≡'), 0x11, 0}, + {IV('≤'), 0xB9, 0},// ≤≥ ⩽⩾ + {IV('≥'), 0xBA, 0}, + //{IV(''), 0xBF, 0}, // error + + {IV('⌠'), 0xC0, 0}, + {IV('⌡'), 0xC1, 0}, + + {IV('⎧'), 0x14, 0}, + {IV('⎩'), 0x15, 0}, + {IV('⎫'), 0x16, 0}, + {IV('⎭'), 0x17, 0}, + {IV('⎰'), 0x18, 0}, + {IV('⎱'), 0x19, 0}, + {IV('⎲'), 0x12, 0}, + {IV('⎳'), 0x13, 0}, + + {IV('⏱'), 0x07, 0}, // Marlin special: '🕐🕑🕒🕓🕔🕕🕖🕗🕘🕙🕚🕛🕜🕝🕞🕟🕠🕡🕢🕣🕤🕥🕦🕧 ⌚⌛⏰⏱⏳⧖⧗' LCD_STR_CLOCK (0x05) + {IV('┌'), 0xC9, 0}, + {IV('┐'), 0xCA, 0}, + {IV('└'), 0xCB, 0}, + {IV('┘'), 0xCC, 0}, + {IV('◸'), 0xC3, 0}, // ◿ + {IV('⭠'), 0xC8, 0}, + {IV('⭡'), 0xC5, 0}, + {IV('⭢'), 0xC7, 0}, + {IV('⭣'), 0xC6, 0}, + + + {IV('⯆'), 0xF5, 0}, + {IV('⯇'), 0xF7, 0}, // ⯅ + {IV('⯈'), 0xF6, 0}, + //{IV(''), 0xF8, 0}, // error + //{IV(''), 0xFA, 0}, // error + //{IV(''), 0xFC, 0}, // error + //{IV(''), 0xFD, 0}, // error + //{IV(''), 0xFE, 0}, // error + //{IV(''), 0xFF, 0}, // error + + #elif DISPLAY_CHARSET_HD44780 == CYRILLIC + + #ifdef CONVERT_TO_EXT_ASCII + {IV('°'), 0x01, 0}, // 00B0, Marlin special: '°' LCD_STR_DEGREE (0x09) + {IV('²'), 0x0E, 0}, // 0x32 if no special symbol in panel font + {IV('³'), 0x0F, 0}, // 0x33 if no special symbol in panel font + + // translate to cp866 codepage + //first ASCII symbols in panel font must be replaced with Marlin special symbols + {IV('Ё'), 0xF0, 0}, // 0401 + {IV('Є'), 0xF2, 0}, // 0404 + {IV('І'), 'I', 0}, // 0406 + {IV('Ї'), 0xF4, 0}, // 0407 + {IV('Ў'), 0xF6, 0}, // 040E + {IV('А'), 0x80, 0}, // 0410 + {IV('Б'), 0x81, 0}, + {IV('В'), 0x82, 0}, + {IV('Г'), 0x83, 0}, + {IV('Д'), 0x84, 0}, + {IV('Е'), 0x85, 0}, + {IV('Ж'), 0x86, 0}, + {IV('З'), 0x87, 0}, + {IV('И'), 0x88, 0}, + {IV('Й'), 0x89, 0}, + {IV('К'), 0x8A, 0}, + {IV('Л'), 0x8B, 0}, + {IV('М'), 0x8C, 0}, + {IV('Н'), 0x8D, 0}, + {IV('О'), 0x8E, 0}, + {IV('П'), 0x8F, 0}, + {IV('Р'), 0x90, 0}, + {IV('С'), 0x91, 0}, + {IV('Т'), 0x92, 0}, + {IV('У'), 0x93, 0}, + {IV('Ф'), 0x94, 0}, + {IV('Х'), 0x95, 0}, + {IV('Ц'), 0x96, 0}, + {IV('Ч'), 0x97, 0}, + {IV('Ш'), 0x98, 0}, + {IV('Щ'), 0x99, 0}, + {IV('Ъ'), 0x9A, 0}, + {IV('Ы'), 0x9B, 0}, + {IV('Ь'), 0x9C, 0}, + {IV('Э'), 0x9D, 0}, + {IV('Ю'), 0x9E, 0}, + {IV('Я'), 0x9F, 0}, + + {IV('а'), 0xA0, 0}, + {IV('б'), 0xA1, 0}, + {IV('в'), 0xA2, 0}, + {IV('г'), 0xA3, 0}, + {IV('д'), 0xA4, 0}, + {IV('е'), 0xA5, 0}, + {IV('ж'), 0xA6, 0}, + {IV('з'), 0xA7, 0}, + {IV('и'), 0xA8, 0}, + {IV('й'), 0xA9, 0}, + {IV('к'), 0xAA, 0}, + {IV('л'), 0xAB, 0}, + {IV('м'), 0xAC, 0}, + {IV('н'), 0xAD, 0}, + {IV('о'), 0xAE, 0}, + {IV('п'), 0xAF, 0}, + {IV('р'), 0xE0, 0}, + {IV('с'), 0xE1, 0}, + {IV('т'), 0xE2, 0}, + {IV('у'), 0xE3, 0}, + {IV('ф'), 0xE4, 0}, + {IV('х'), 0xE5, 0}, + {IV('ц'), 0xE6, 0}, + {IV('ч'), 0xE7, 0}, + {IV('ш'), 0xE8, 0}, + {IV('щ'), 0xE9, 0}, + {IV('ъ'), 0xEA, 0}, + {IV('ы'), 0xEB, 0}, + {IV('ь'), 0xEC, 0}, + {IV('э'), 0xED, 0}, + {IV('ю'), 0xEE, 0}, + {IV('я'), 0xEF, 0}, // 044F + {IV('ё'), 0xF1, 0}, // 0451 + {IV('є'), 0xF3, 0}, // 0454 + {IV('і'), 'i', 0}, // 0456 + {IV('ї'), 0xF5, 0}, // 0457 + {IV('ў'), 0xF7, 0}, // 045E + + #else + + {IV('¢'), 0x5C, 0}, // 00A2 + {IV('£'), 0xCF, 0}, // 00A3 + {IV('°'), 0x01, 0}, // 00B0, Marlin special: '°' LCD_STR_DEGREE (0x09) + + //{IV(''), 0x80, 0}, + //{IV(''), 0x81, 0}, + //{IV(''), 0x82, 0}, + //{IV(''), 0x83, 0}, + //{IV(''), 0x84, 0}, + //{IV(''), 0x85, 0}, + //{IV(''), 0x86, 0}, + //{IV(''), 0x87, 0}, + //{IV(''), 0x88, 0}, + //{IV(''), 0x89, 0}, + //{IV(''), 0x8A, 0}, + //{IV(''), 0x8B, 0}, + //{IV(''), 0x8C, 0}, + //{IV(''), 0x8D, 0}, + //{IV(''), 0x8E, 0}, + //{IV(''), 0x8F, 0}, + + //{IV(''), 0x90, 0}, + //{IV(''), 0x91, 0}, + //{IV(''), 0x92, 0}, + //{IV(''), 0x93, 0}, + //{IV(''), 0x94, 0}, + //{IV(''), 0x95, 0}, + //{IV(''), 0x96, 0}, + //{IV(''), 0x97, 0}, + //{IV(''), 0x98, 0}, + //{IV(''), 0x99, 0}, + //{IV(''), 0x9A, 0}, + //{IV(''), 0x9B, 0}, + //{IV(''), 0x9C, 0}, + //{IV(''), 0x9D, 0}, + //{IV(''), 0x9E, 0}, + //{IV(''), 0x9F, 0}, + + {IV('¼'), 0xF0, 0}, // 00BC + {IV('⅓'), 0xF1, 0}, + {IV('½'), 0xF2, 0}, // 00BD + {IV('¾'), 0xF3, 0}, // 00BE + {IV('¿'), 0xCD, 0}, // 00BF + + {IV('Ё'), 0xA2, 0}, // 0401 + {IV('А'), 'A', 0}, // 0410 + {IV('Б'), 0xA0, 0}, + {IV('В'), 'B', 0}, + {IV('Г'), 0xA1, 0}, + {IV('Д'), 0xE0, 0}, + {IV('Е'), 'E', 0}, + {IV('Ж'), 0xA3, 0}, + {IV('З'), 0xA4, 0}, + {IV('И'), 0xA5, 0}, + {IV('Й'), 0xA6, 0}, + {IV('К'), 'K', 0}, + {IV('Л'), 0xA7, 0}, + {IV('М'), 'M', 0}, + {IV('Н'), 'H', 0}, + {IV('О'), 'O', 0}, + {IV('П'), 0xA8, 0}, + {IV('Р'), 'P', 0}, + {IV('С'), 'C', 0}, + {IV('Т'), 'T', 0}, + {IV('У'), 0xA9, 0}, + {IV('Ф'), 0xAA, 0}, + {IV('Х'), 'X', 0}, + {IV('Ц'), 0xE1, 0}, + {IV('Ч'), 0xAB, 0}, + {IV('Ш'), 0xAC, 0}, + {IV('Щ'), 0xE2, 0}, + {IV('Ъ'), 0xAD, 0}, + {IV('Ы'), 0xAE, 0}, + {IV('Ь'), 'b', 0}, + {IV('Э'), 0xAF, 0}, + {IV('Ю'), 0xB0, 0}, + {IV('Я'), 0xB1, 0}, + {IV('а'), 'a', 0}, + + {IV('б'), 0xB2, 0}, + {IV('в'), 0xB3, 0}, + {IV('г'), 0xB4, 0}, + {IV('д'), 0xE3, 0}, + {IV('е'), 'e', 0}, + {IV('ж'), 0xB6, 0}, + {IV('з'), 0xB7, 0}, + {IV('и'), 0xB8, 0}, + {IV('й'), 0xB9, 0}, + {IV('к'), 0xBA, 0}, + {IV('л'), 0xBB, 0}, + {IV('м'), 0xBC, 0}, + {IV('н'), 0xBD, 0}, + {IV('о'), 'o', 0}, + {IV('п'), 0xBE, 0}, + {IV('р'), 'p', 0}, + {IV('с'), 'c', 0}, + {IV('т'), 0xBF, 0}, + + {IV('у'), 'y', 0}, + {IV('ф'), 0xE4, 0}, + {IV('х'), 'x', 0}, + {IV('ц'), 0xE5, 0}, + {IV('ч'), 0xC0, 0}, + {IV('ш'), 0xC1, 0}, + {IV('щ'), 0xE6, 0}, + {IV('ъ'), 0xC2, 0}, + {IV('ы'), 0xC3, 0}, + {IV('ь'), 0xC4, 0}, + {IV('э'), 0xC5, 0}, + {IV('ю'), 0xC6, 0}, + {IV('я'), 0xC7, 0}, // 044F + {IV('ё'), 0xB5, 0}, // 0451 + //{IV(''), 0xC8, 0}, + //{IV(''), 0xC9, 0}, + //{IV(''), 0xCA, 0}, + //{IV(''), 0xCB, 0}, + //{IV(''), 0xCC, 0}, + //{IV(''), 0xCD, 0}, + //{IV(''), 0xCE, 0}, + + //{IV(''), 0xD0, 0}, + //{IV(''), 0xD1, 0}, + //{IV(''), 0xD2, 0}, + //{IV(''), 0xD3, 0}, + //{IV(''), 0xD4, 0}, + //{IV(''), 0xD5, 0}, + //{IV(''), 0xD6, 0}, + //{IV(''), 0xD7, 0}, + //{IV(''), 0xD8, 0}, + //{IV(''), 0xDB, 0}, + //{IV(''), 0xDC, 0}, + //{IV(''), 0xDD, 0}, + //{IV(''), 0xDE, 0}, + //{IV(''), 0xDF, 0}, + + //{IV(''), 0xE7, 0}, + //{IV(''), 0xE8, 0}, + //{IV(''), 0xE9, 0}, + //{IV(''), 0xEA, 0}, + //{IV(''), 0xEB, 0}, + //{IV(''), 0xEC, 0}, + //{IV(''), 0xED, 0}, + //{IV(''), 0xEE, 0}, + //{IV(''), 0xEF, 0}, + + //{IV(''), 0xF4, 0}, + //{IV(''), 0xF5, 0}, + //{IV(''), 0xF6, 0}, + //{IV(''), 0xF7, 0}, + //{IV(''), 0xF8, 0}, + //{IV(''), 0xF9, 0}, + //{IV(''), 0xFA, 0}, + //{IV(''), 0xFB, 0}, + //{IV(''), 0xFC, 0}, + //{IV(''), 0xFD, 0}, + //{IV(''), 0xFE, 0}, + //{IV(''), 0xFF, 0}, + + {IV('↑'), 0xD9, 0}, // 2191 ←↑→↓ + {IV('↓'), 0xDA, 0}, // 2193 + + #endif + + #endif +}; + +// the plain ASCII replacement for various char +static const TFTGLCD_charmap_t g_TFTGLCD_charmap_common[] PROGMEM = { + {IV('¡'), 'i', 0}, // A1 + {IV('¢'), 'c', 0}, // A2 + {IV('°'), 0x09, 0}, // B0 Marlin special: '°' LCD_STR_DEGREE (0x09) + + #ifndef CONVERT_TO_EXT_ASCII //this time CONVERT_TO_EXT_ASCII works only with en, ru and uk languages + + // map WESTERN code to the plain ASCII + {IV('Á'), 'A', 0}, // C1 + {IV('Â'), 'A', 0}, // C2 + {IV('Ã'), 'A', 0}, // C3 + {IV('Ä'), 'A', 0}, // C4 + {IV('Å'), 'A', 0}, // C5 + {IV('Æ'), 'A', 'E'}, // C6 + {IV('Ç'), 'C', 0}, // C7 + {IV('È'), 'E', 0}, // C8 + {IV('É'), 'E', 0}, // C9 + {IV('Í'), 'I', 0}, // CD + {IV('Ñ'), 'N', 0}, // D1 + {IV('Õ'), 'O', 0}, // D5 + {IV('Ö'), 'O', 0}, // D6 + {IV('×'), 'x', 0}, // D7 + {IV('Ü'), 'U', 0}, // DC + {IV('Ý'), 'Y', 0}, // DD + {IV('à'), 'a', 0}, // E0 + {IV('á'), 'a', 0}, + {IV('â'), 'a', 0}, + {IV('ã'), 'a', 0}, + {IV('ä'), 'a', 0}, + {IV('å'), 'a', 0}, + {IV('æ'), 'a', 'e'}, + {IV('ç'), 'c', 0}, + {IV('è'), 'e', 0}, // 00E8 + {IV('é'), 'e', 0}, + {IV('ê'), 'e', 0}, + {IV('ë'), 'e', 0}, + {IV('ì'), 'i', 0}, // 00EC + {IV('í'), 'i', 0}, + {IV('î'), 'i', 0}, + {IV('ï'), 'i', 0}, // 00EF + + {IV('ñ'), 'n', 0}, // 00F1 + {IV('ò'), 'o', 0}, + {IV('ó'), 'o', 0}, + {IV('ô'), 'o', 0}, + {IV('õ'), 'o', 0}, + {IV('ö'), 'o', 0}, + //{IV('÷'), 0xB8, 0}, + {IV('ø'), 'o', 0}, + {IV('ù'), 'u', 0}, + {IV('ú'), 'u', 0}, + {IV('û'), 'u', 0}, + {IV('ü'), 'u', 0}, // FC + {IV('ý'), 'y', 0}, // FD + {IV('ÿ'), 'y', 0}, // FF + + {IV('Ą'), 'A', 0}, // 0104 + {IV('ą'), 'a', 0}, // 0105 + {IV('Ć'), 'C', 0}, // 0106 + {IV('ć'), 'c', 0}, // 0107 + {IV('Č'), 'C', 0}, // 010C + {IV('č'), 'c', 0}, // 010D + {IV('Ď'), 'D', 0}, // 010E + {IV('ď'), 'd', 0}, // 010F + {IV('đ'), 'd', 0}, // 0111 + {IV('ę'), 'e', 0}, // 0119 + {IV('ğ'), 'g', 0}, // 011F + {IV('İ'), 'I', 0}, // 0130 + {IV('ı'), 'i', 0}, // 0131 + + {IV('Ł'), 'L', 0}, // 0141 + {IV('ł'), 'l', 0}, // 0142 + {IV('Ń'), 'N', 0}, // 0143 + {IV('ń'), 'n', 0}, // 0144 + {IV('ň'), 'n', 0}, // 0148 + + {IV('ř'), 'r', 0}, // 0159 + {IV('Ś'), 'S', 0}, // 015A + {IV('ś'), 's', 0}, // 015B + {IV('ş'), 's', 0}, // 015F + {IV('Š'), 'S', 0}, // 0160 + {IV('š'), 's', 0}, // 0161 + {IV('ť'), 't', 0}, // 0165 + {IV('ů'), 'u', 0}, // 016F + {IV('ż'), 'z', 0}, // 017C + {IV('Ž'), 'Z', 0}, // 017D + {IV('ž'), 'z', 0}, // 017E + {IV('ƒ'), 'f', 0}, // 0192 + + {IV('ˣ'), 'x', 0}, // 02E3 + + {IV('΄'), '\'', 0}, // 0384 + {IV('΅'), '\'', 0}, // 0385 + {IV('Ά'), 'A', 0}, // 0386 + {IV('·'), '.', 0}, // 0387 + {IV('Έ'), 'E', 0}, // 0388 + {IV('Ή'), 'H', 0}, // 0389 + {IV('Ί'), 'I', 0}, // 038A + {IV('Ό'), 'O', 0}, // 038C + {IV('Ύ'), 'Y', 0}, // 038E + {IV('Ώ'), 'O', 0}, // 038F + {IV('ΐ'), 'i', 0}, // 0390 + {IV('Α'), 'A', 0}, // 0391 + {IV('Β'), 'B', 0}, // 0392 + {IV('Γ'), 'T', 0}, // 0393, Gamma + {IV('Δ'), '4', 0}, // 0394, Delta, ◿ + {IV('Ε'), 'E', 0}, // 0395 + {IV('Ζ'), 'Z', 0}, // 0396 + {IV('Η'), 'H', 0}, // 0397 + {IV('Θ'), '0', 0}, // 0398, Theta + {IV('Ι'), 'I', 0}, // 0399 + {IV('Κ'), 'K', 0}, // 039A + {IV('Λ'), '^', 0}, // 039B, Lambda + {IV('Μ'), 'M', 0}, // 039C + {IV('Ν'), 'N', 0}, // 039D + {IV('Ξ'), '3', 0}, // 039E, Xi + {IV('Ο'), 'O', 0}, // 039F + {IV('Π'), 'n', 0}, // 03A0, Pi + {IV('Ρ'), 'P', 0}, // 03A1 + {IV('Σ'), 'E', 0}, // 03A3, Sigma + {IV('Τ'), 'T', 0}, // 03A4 + {IV('Υ'), 'Y', 0}, // 03A5, Upsilon + {IV('Φ'), 'p', 0}, // 03A6, Phi + {IV('Χ'), 'X', 0}, // 03A7 + {IV('Ψ'), 'P', 0}, // 03A8, Psi + {IV('Ω'), 'O', 0}, // 03A9, Omega + {IV('Ϊ'), 'I', 0}, // 03AA + {IV('Ϋ'), 'Y', 0}, // 03AB + {IV('ά'), 'a', 0}, // 03AC + {IV('έ'), 'e', 0}, // 03AD + {IV('ή'), 'n', 0}, // 03AE + {IV('ί'), 'i', 0}, // 03AF + {IV('ΰ'), 'v', 0}, // 03B0 + {IV('α'), 'a', 0}, // 03B1, alpha + {IV('β'), 'B', 0}, // 03B2, beta + {IV('γ'), 'v', 0}, // 03B3, gamma + {IV('δ'), 'd', 0}, // 03B4, delta + {IV('ε'), 'e', 0}, // 03B5, epsilon + {IV('ζ'), 'Z', 0}, // 03B6, zeta + {IV('η'), 'n', 0}, // 03B7, eta + {IV('θ'), '0', 0}, // 03B8, theta + {IV('ι'), 'i', 0}, // 03B9, lota + {IV('κ'), 'k', 0}, // 03BA, kappa + {IV('λ'), 'L', 0}, // 03BB, lambda + {IV('μ'), 'u', 0}, // 03BC, mu + {IV('ν'), 'v', 0}, // 03BD, nu + {IV('ξ'), 'e', 0}, // 03BE, xi + {IV('ο'), 'o', 0}, // 03BF + {IV('π'), 'n', 0}, // 03C0, pi + {IV('ρ'), 'p', 0}, // 03C1, rho + {IV('ς'), 'c', 0}, // 03C2 + {IV('σ'), 'o', 0}, // 03C3, sigma + {IV('τ'), 't', 0}, // 03C4, tau + {IV('υ'), 'v', 0}, // 03C5, upsilon + {IV('φ'), 'p', 0}, // 03C6 + {IV('χ'), 'X', 0}, // 03C7, chi + {IV('ψ'), 'W', 0}, // 03C8, psi + {IV('ω'), 'w', 0}, // 03C9, omega + {IV('ϊ'), 'i', 0}, // 03CA + {IV('ϋ'), 'v', 0}, // 03CB + {IV('ό'), 'o', 0}, // 03CC + {IV('ύ'), 'v', 0}, // 03CD + {IV('ώ'), 'w', 0}, // 03CE + + // map CYRILLIC code to the plain ASCII + {IV('А'), 'A', 0}, // 0410 + {IV('Б'), 'b', 0}, // 0411 + {IV('В'), 'B', 0}, // 0412 + {IV('Г'), 'T', 0}, // 0413 + {IV('Д'), 'Q', 0}, // 0414 + {IV('Е'), 'E', 0}, // 0415 + {IV('Ж'), '*', 0}, // 0416 + {IV('З'), 'E', 0}, // 0417 + {IV('И'), 'N', 0}, // 0418 + {IV('Й'), 'N', 0}, // 0419 + {IV('К'), 'K', 0}, // 041A + {IV('Л'), 'T', 0}, // 041B + {IV('М'), 'M', 0}, // 041C + {IV('Н'), 'H', 0}, // 041D + {IV('О'), 'O', 0}, // 041E + {IV('П'), 'n', 0}, // 041F + {IV('Р'), 'P', 0}, // 0420 + {IV('С'), 'C', 0}, // 0421 + {IV('Т'), 'T', 0}, // 0422 + {IV('У'), 'Y', 0}, + {IV('Ф'), 'o', 0}, + {IV('Х'), 'X', 0}, + {IV('Ц'), 'U', 0}, + {IV('Ч'), 'y', 0}, + {IV('Ш'), 'W', 0}, + {IV('Щ'), 'W', 0}, + {IV('Ъ'), 'b', 0}, + {IV('Ы'), 'b', '|'}, + {IV('Ь'), 'b'}, + {IV('Э'), 'e'}, + {IV('Ю'), '|', 'O'}, + {IV('Я'), '9', '|'}, // 042F + + {IV('а'), 'a', 0}, // 0430 + {IV('б'), '6', 0}, // 0431 + {IV('в'), 'B', 0}, // 0432, + {IV('г'), 'r', 0}, // 0433 + {IV('д'), 'a', 0}, // 0434, + {IV('е'), 'e', 0}, // 0435 + {IV('ж'), '*', 0}, // 0436 + {IV('з'), 'e', 0}, // 0437, + {IV('и'), 'u', 0}, // 0438 + {IV('й'), 'u', 0}, // 0439, + {IV('к'), 'k', 0}, // 043A + {IV('л'), 'n', 0}, + {IV('м'), 'm', 0}, + {IV('н'), 'H', 0}, + {IV('о'), 'o', 0}, + {IV('п'), 'n', 0}, + {IV('р'), 'p', 0}, + {IV('с'), 'c', 0}, + {IV('т'), 't', 0}, + {IV('у'), 'y', 0}, + {IV('ф'), 'q', 'p'}, + {IV('х'), 'x', 0}, + {IV('ц'), 'u', 0}, + {IV('ч'), 'y', 0}, + {IV('ш'), 'w', 0}, + {IV('щ'), 'w', 0}, + {IV('ъ'), 'b', 0}, + {IV('ы'), 'b', '|'}, + {IV('ь'), 'b', 0}, + {IV('э'), 'e', 0}, + {IV('ю'), '|', 'o'}, + {IV('я'), 'g', 0}, // 044F + + #endif + + {IV('•'), '.', 0}, // 2022 · + {IV('℞'), 'P', 'x'}, // 211E ℞ Pt ASCII 158 + {IV('™'), 'T', 'M'}, // 2122 + {IV('←'), '<', '-'}, // 2190 + {IV('→'), '-', '>'}, // 2192, Marlin special: '⮈⮉⮊⮋➤→⏵➟➠➡' LCD_STR_ARROW_RIGHT (0x03) + //{IV('↰'), '<', 0}, // 21B0, Marlin special: '⮥⮭⮉⇧↑↰⤴' LCD_STR_UPLEVEL (0x04) + {IV('↰'), 0x03, 0}, // 21B0, Marlin special: '⮥⮭⮉⇧↑↰⤴' LCD_STR_UPLEVEL (0x04) + {IV('↻'), 0x04, 0}, // 21BB Marlin special: '↻↺⟳⟲' LCD_STR_REFRESH (0x01) + {IV('∼'), '~', 0}, // 223C + {IV('≈'), '~', '='}, // 2248 + {IV('≠'), '!', '='}, // 2260 + {IV('≡'), '=', 0}, // 2261 + {IV('≤'), '<', '='},// 2264, ≤≥ ⩽⩾ + {IV('≥'), '>', '='}, // 2265 + {IV('⏱'), 0x07, 0}, // 23F1, Marlin special: '🕐🕑🕒🕓🕔🕕🕖🕗🕘🕙🕚🕛🕜🕝🕞🕟🕠🕡🕢🕣🕤🕥🕦🕧 ⌚⌛⏰⏱⏳⧖⧗' LCD_STR_CLOCK (0x05) + + {IV('゠'), '=', 0}, // 30A0 + + // ⏰⏱⏲⏳◴◵◶◷ + // ⏻⏼♁♂ + //{IV(''), 0x00, 0}, // Marlin special: '' LCD_STR_BEDTEMP (0x07) + {IV('🌡'), 0x02, 0}, // D83CDF21 Marlin special: '🌡' LCD_STR_THERMOMETER (0x08) + {IV('📂'), 0x05, 0}, // D83DDCC2 Marlin special: '📁📂' LCD_STR_FOLDER (0x02) + //{IV(''), 0x06, 0}, // Marlin special: '' LCD_STR_FEEDRATE (0x06) +}; + +/* return v1 - v2 */ +static int TFTGLCD_charmap_compare(TFTGLCD_charmap_t * v1, TFTGLCD_charmap_t * v2) { + return (v1->uchar < v2->uchar) ? -1 : (v1->uchar > v2->uchar) ? 1 : 0; +} + +static int pf_bsearch_cb_comp_hd4map_pgm(void *userdata, size_t idx, void * data_pin) { + TFTGLCD_charmap_t localval; + TFTGLCD_charmap_t *p_TFTGLCD_charmap = (TFTGLCD_charmap_t *)userdata; + memcpy_P(&localval, p_TFTGLCD_charmap + idx, sizeof(localval)); + return TFTGLCD_charmap_compare(&localval, (TFTGLCD_charmap_t *)data_pin); +} + +void lcd_moveto(const lcd_uint_t col, const lcd_uint_t row) { lcd.setCursor(col, row); } + +void lcd_put_int(const int i) { + const char* str = i16tostr3left(i); + while (*str) lcd.write(*str++); +} + +// return < 0 on error +// return the advanced cols +int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) { + + // find the HD44780 internal ROM first + int ret; + size_t idx = 0; + TFTGLCD_charmap_t pinval; + TFTGLCD_charmap_t *copy_address = nullptr; + pinval.uchar = c; + pinval.idx = -1; + + if (max_length < 1) return 0; + + if (c < 128) { + lcd.write((uint8_t)c); + return 1; + } + copy_address = nullptr; + ret = pf_bsearch_r((void *)g_TFTGLCD_charmap_device, COUNT(g_TFTGLCD_charmap_device), pf_bsearch_cb_comp_hd4map_pgm, (void *)&pinval, &idx); + if (ret >= 0) { + copy_address = (TFTGLCD_charmap_t *)(g_TFTGLCD_charmap_device + idx); + } + else { + ret = pf_bsearch_r((void *)g_TFTGLCD_charmap_common, COUNT(g_TFTGLCD_charmap_common), pf_bsearch_cb_comp_hd4map_pgm, (void *)&pinval, &idx); + if (ret >= 0) copy_address = (TFTGLCD_charmap_t *)(g_TFTGLCD_charmap_common + idx); + } + + if (ret >= 0) { + TFTGLCD_charmap_t localval; + // found + memcpy_P(&localval, copy_address, sizeof(localval)); + lcd.write(localval.idx); + if (max_length >= 2 && localval.idx2 > 0) { + lcd.write(localval.idx2); + return 2; + } + return 1; + } + + // Not found, print '?' instead + lcd.write((uint8_t)'?'); + return 1; +} + +/** + * @brief Draw a UTF-8 string + * + * @param utf8_str : the UTF-8 string + * @param cb_read_byte : the callback function to read one byte from the utf8_str (from RAM or ROM) + * @param max_length : the pixel length of the string allowed (or number of slots in HD44780) + * + * @return the number of pixels advanced + * + * Draw a UTF-8 string + */ +static int lcd_put_u8str_max_cb(const char * utf8_str, uint8_t (*cb_read_byte)(uint8_t * str), pixel_len_t max_length) { + pixel_len_t ret = 0; + uint8_t *p = (uint8_t *)utf8_str; + while (ret < max_length) { + wchar_t ch = 0; + p = get_utf8_value_cb(p, cb_read_byte, &ch); + if (!ch) break; + ret += lcd_put_wchar_max(ch, max_length - ret); + } + return (int)ret; +} + +int lcd_put_u8str_max(const char * utf8_str, pixel_len_t max_length) { + return lcd_put_u8str_max_cb(utf8_str, read_byte_ram, max_length); +} + +int lcd_put_u8str_max_P(PGM_P utf8_str_P, pixel_len_t max_length) { + return lcd_put_u8str_max_cb(utf8_str_P, read_byte_rom, max_length); +} + +#if ENABLED(DEBUG_LCDPRINT) + + int test_TFTGLCD_charmap(TFTGLCD_charmap_t *data, size_t size, char *name, char flg_show_contents) { + int ret; + size_t idx = 0; + TFTGLCD_charmap_t preval = {0, 0, 0}; + TFTGLCD_charmap_t pinval = {0, 0, 0}; + char flg_error = 0; + + int i; + + TRACE("Test %s\n", name); + + for (i = 0; i < size; i ++) { + memcpy_P(&pinval, &(data[i]), sizeof(pinval)); + + if (flg_show_contents) { + #if 1 + TRACE("[% 4d] % 6" PRIu32 "(0x%04" PRIX32 ") --> 0x%02X,0x%02X%s\n", i, pinval.uchar, pinval.uchar, (unsigned int)(pinval.idx), (unsigned int)(pinval.idx2), (preval.uchar < pinval.uchar?"":" <--- ERROR")); + #else + TRACE("[% 4d]", i); + TRACE("% 6" PRIu32 "(0x%04" PRIX32 "),", pinval.uchar, pinval.uchar); + TRACE("0x%02X,", (unsigned int)(pinval.idx)); + TRACE("0x%02X,", (unsigned int)(pinval.idx2)); + TRACE("%s", (preval.uchar < pinval.uchar?"":" <--- ERROR")); + #endif + } + if (preval.uchar >= pinval.uchar) { + flg_error = 1; + //TRACE("Error: out of order in array %s: idx=%d, val=%d(0x%x)\n", name, i, pinval.uchar, pinval.uchar); + //return -1; + } + memcpy(&preval, &pinval, sizeof(pinval)); + + ret = pf_bsearch_r((void *)data, size, pf_bsearch_cb_comp_hd4map_pgm, (void *)&pinval, &idx); + if (ret < 0) { + flg_error = 1; + TRACE("Error: not found item in array %s: idx=%d, val=%d(0x%x)\n", name, i, pinval.uchar, pinval.uchar); + //return -1; + } + if (idx != i) { + flg_error = 1; + TRACE("Error: wrong index found item in array %s: idx=%d, val=%d(0x%x)\n", name, i, pinval.uchar, pinval.uchar); + //return -1; + } + } + if (flg_error) { + TRACE("\nError: in array %s\n\n", name); + return -1; + } + TRACE("\nPASS array %s\n\n", name); + return 0; + } + + int test_TFTGLCD_charmap_all(void) { + int flg_error = 0; + if (test_TFTGLCD_charmap(g_TFTGLCD_charmap_device, COUNT(g_TFTGLCD_charmap_device), "g_TFTGLCD_charmap_device", 0) < 0) { + flg_error = 1; + test_TFTGLCD_charmap(g_TFTGLCD_charmap_device, COUNT(g_TFTGLCD_charmap_device), "g_TFTGLCD_charmap_device", 1); + } + if (test_TFTGLCD_charmap(g_TFTGLCD_charmap_common, COUNT(g_TFTGLCD_charmap_common), "g_TFTGLCD_charmap_common", 0) < 0) { + flg_error = 1; + test_TFTGLCD_charmap(g_TFTGLCD_charmap_common, COUNT(g_TFTGLCD_charmap_common), "g_TFTGLCD_charmap_common", 1); + } + if (flg_error) { + TRACE("\nFAILED in hd44780 tests!\n"); + return -1; + } + TRACE("\nPASS in hd44780 tests.\n"); + return 0; + } + +#endif // DEBUG_LCDPRINT + +#endif // IS_TFTGLCD_PANEL diff --git a/Marlin/src/lcd/TFTGLCD/ultralcd_TFTGLCD.cpp b/Marlin/src/lcd/TFTGLCD/ultralcd_TFTGLCD.cpp new file mode 100644 index 000000000000..c02a55362076 --- /dev/null +++ b/Marlin/src/lcd/TFTGLCD/ultralcd_TFTGLCD.cpp @@ -0,0 +1,964 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfigPre.h" + +#if IS_TFTGLCD_PANEL + +/** + * ultralcd_TFTGLCD.cpp + * + * Implementation of the LCD display routines for a TFT GLCD displays with external controller. + * This display looks as a REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER but has good text font + * and supports color output. + */ + +#if NONE(__AVR__, TARGET_LPC1768, __STM32F1__, STM32F4xx) + #warning "Selected platform not yet tested. Please contribute your good pin mappings." +#endif + +#if ENABLED(TFTGLCD_PANEL_SPI) + #include +#else + #include +#endif + +#include "ultralcd_TFTGLCD.h" +#include "../ultralcd.h" +#include "../../libs/numtostr.h" + +#include "../../sd/cardreader.h" +#include "../../module/temperature.h" +#include "../../module/printcounter.h" +#include "../../module/planner.h" +#include "../../module/motion.h" + +#if DISABLED(LCD_PROGRESS_BAR) && BOTH(FILAMENT_LCD_DISPLAY, SDSUPPORT) + #include "../../feature/filwidth.h" + #include "../../gcode/parser.h" +#endif + +#if ENABLED(AUTO_BED_LEVELING_UBL) + #include "../../feature/bedlevel/bedlevel.h" +#endif + +TFTGLCD lcd; + +#define ICON_LOGO B00000001 +#define ICON_TEMP1 B00000010 //hotend 1 +#define ICON_TEMP2 B00000100 //hotend 2 +#define ICON_TEMP3 B00001000 //hotend 3 +#define ICON_BED B00010000 +#define ICON_FAN B00100000 +#define ICON_HOT B01000000 //when any T > 50deg +#define PIC_MASK 0x7F + +// LEDs not used, for compatibility with Smoothieware +#define LED_HOTEND_ON B00000001 +#define LED_BED_ON B00000010 +#define LED_FAN_ON B00000100 +#define LED_HOT B00001000 +#define LED_MASK 0x0F + +#define FBSIZE (LCD_WIDTH * LCD_HEIGHT + 2) +#define MIDDLE_Y ((LCD_HEIGHT - 1) / 2) + +// Markers for change line colors +#define COLOR_EDIT '#' +#define COLOR_ERROR '!' + +#ifdef CONVERT_TO_EXT_ASCII //use standart pseudographic symbols in ASCII table + #define LR 179 //vertical line + #define TRC 191 //top right corner + #define BLC 192 //bottom left corner + #define GL 196 //horizontal line + #define BRC 217 //bottom right corner, should be replaced to 12 for some languages + #define TLC 218 //top left corner, should be replaced to 13 for some languages +#else //next symbols must be present in panel font + #define LR 8 //equal to 179 + #define TRC 9 //equal to 191 + #define BLC 10 //equal to 192 + #define GL 11 //equal to 196 + #define BRC 12 //equal to 217 + #define TLC 13 //equal to 218 +#endif + +#define Marlin 0x01 + +enum Commands { // based on Smoothieware commands + GET_SPI_DATA = 0, + READ_BUTTONS, // read buttons + READ_ENCODER, // read encoder + LCD_WRITE, // write all screen to LCD + BUZZER, // beep buzzer + CONTRAST, // set contrast (brightnes) + // Other commands... 0xE0 thru 0xFF + GET_LCD_ROW = 0xE0, // for detect panel + GET_LCD_COL, // reserved for compatibility with Smoothieware, not used + LCD_PUT, // write one line to LCD + CLR_SCREEN, + INIT_SCREEN = 0xFE // clear panel buffer +}; + +static unsigned char framebuffer[FBSIZE]; +static unsigned char *fb; +static uint8_t cour_line; +static uint8_t picBits, ledBits, hotBits; +static uint8_t PanelDetected = 0; + +// Different platforms use different SPI methods +#if ANY(__AVR__, TARGET_LPC1768, __STM32F1__, ARDUINO_ARCH_SAM, __SAMD51__, __MK20DX256__, __MK64FX512__) + #define SPI_SEND_ONE(V) SPI.transfer(V); + #define SPI_SEND_TWO(V) SPI.transfer16(V); +#elif defined(STM32F4xx) + #define SPI_SEND_ONE(V) SPI.transfer(V, SPI_CONTINUE); + #define SPI_SEND_TWO(V) SPI.transfer16(V, SPI_CONTINUE); +#elif defined(ARDUINO_ARCH_ESP32) + #define SPI_SEND_ONE(V) SPI.write(V); + #define SPI_SEND_TWO(V) SPI.write16(V); +#endif + +#if ANY(__AVR__, ARDUINO_ARCH_SAM, __SAMD51__, __MK20DX256__, __MK64FX512__) + #define SPI_SEND_SOME(V,L,Z) SPI.transfer(&V[Z], L); +#elif defined(STM32F4xx) + #define SPI_SEND_SOME(V,L,Z) SPI.transfer(&V[Z], L, SPI_CONTINUE); +#elif ANY(TARGET_LPC1768, __STM32F1__, ARDUINO_ARCH_ESP32) + #define SPI_SEND_SOME(V,L,Z) do{ for (uint16_t i = 0; i < L; i++) SPI_SEND_ONE(V[(Z)+i]); }while(0) +#endif + +// Constructor +TFTGLCD::TFTGLCD() {} + +// Clear local buffer +void TFTGLCD::clear_buffer() { + memset(&framebuffer[0], ' ', FBSIZE - 2); + framebuffer[FBSIZE - 1] = framebuffer[FBSIZE - 2] = 0; + picBits = ledBits = 0; +} + +// Clear panel's screen +void TFTGLCD::clr_screen() { + if (!PanelDetected) return; + #if ENABLED(TFTGLCD_PANEL_SPI) + WRITE(TFTGLCD_CS, LOW); + SPI_SEND_ONE(CLR_SCREEN); + WRITE(TFTGLCD_CS, HIGH); + #else + Wire.beginTransmission((uint8_t)LCD_I2C_ADDRESS); //set I2C device address + Wire.write(CLR_SCREEN); + Wire.endTransmission(); //transmit data + #endif +} + +// Set new text cursor position +void TFTGLCD::setCursor(uint8_t col, uint8_t row) { + fb = &framebuffer[0] + col + row * LCD_WIDTH; + cour_line = row; +} + +// Send char to buffer +void TFTGLCD::write(char c) { + *fb++ = c; +} + +// Send text line to buffer +void TFTGLCD::print(const char *line) { + while (*line) *fb++ = *line++; +} + +// For menu +void TFTGLCD::print_line() { + if (!PanelDetected) return; + #if ENABLED(TFTGLCD_PANEL_SPI) + WRITE(TFTGLCD_CS, LOW); + SPI_SEND_ONE(LCD_PUT); + SPI_SEND_ONE(cour_line); + SPI_SEND_SOME(framebuffer, LCD_WIDTH, cour_line * LCD_WIDTH); + WRITE(TFTGLCD_CS, HIGH); + #else + Wire.beginTransmission((uint8_t)LCD_I2C_ADDRESS); //set I2C device address + Wire.write(LCD_PUT); + Wire.write(cour_line); + Wire.write(&framebuffer[cour_line * LCD_WIDTH], LCD_WIDTH); //transfer 1 line to txBuffer + Wire.endTransmission(); //transmit data + safe_delay(1); + #endif +} + +void TFTGLCD::print_screen(){ + if (!PanelDetected) return; + framebuffer[FBSIZE - 2] = picBits & PIC_MASK; + framebuffer[FBSIZE - 1] = ledBits; + #if ENABLED(TFTGLCD_PANEL_SPI) + // Send all framebuffer to panel + WRITE(TFTGLCD_CS, LOW); + SPI_SEND_ONE(LCD_WRITE); + SPI_SEND_SOME(framebuffer, FBSIZE, 0); + WRITE(TFTGLCD_CS, HIGH); + #else + uint8_t r; + // Send framebuffer to panel by line + Wire.beginTransmission((uint8_t)LCD_I2C_ADDRESS); + // First line + Wire.write(LCD_WRITE); + Wire.write(&framebuffer[0], LCD_WIDTH); + Wire.endTransmission(); + for (r = 1; r < (LCD_HEIGHT - 1); r++) { + Wire.beginTransmission((uint8_t)LCD_I2C_ADDRESS); + Wire.write(&framebuffer[r * LCD_WIDTH], LCD_WIDTH); + Wire.endTransmission(); + } + // Last line + Wire.beginTransmission((uint8_t)LCD_I2C_ADDRESS); + Wire.write(&framebuffer[r * LCD_WIDTH], LCD_WIDTH); + Wire.write(&framebuffer[FBSIZE - 2], 2); + Wire.endTransmission(); + #endif +} + +void TFTGLCD::setContrast(uint16_t contrast) { + if (!PanelDetected) return; + #if ENABLED(TFTGLCD_PANEL_SPI) + WRITE(TFTGLCD_CS, LOW); + SPI_SEND_ONE(CONTRAST); + SPI_SEND_ONE((uint8_t)contrast); + WRITE(TFTGLCD_CS, HIGH); + #else + Wire.beginTransmission((uint8_t)LCD_I2C_ADDRESS); + Wire.write(CONTRAST); + Wire.write((uint8_t)contrast); + Wire.endTransmission(); + #endif +} + +extern volatile int8_t encoderDiff; + +// Read buttons and encoder states +uint8_t MarlinUI::read_slow_buttons(void) { + if (!PanelDetected) return 0; + #if ENABLED(TFTGLCD_PANEL_SPI) + uint8_t b = 0; + WRITE(TFTGLCD_CS, LOW); + SPI_SEND_ONE(READ_ENCODER); + #ifndef STM32F4xx + WRITE(TFTGLCD_CS, LOW); // for delay + #endif + encoderDiff += SPI_SEND_ONE(READ_BUTTONS); + #ifndef STM32F4xx + WRITE(TFTGLCD_CS, LOW); // for delay + WRITE(TFTGLCD_CS, LOW); + #endif + b = SPI_SEND_ONE(GET_SPI_DATA); + WRITE(TFTGLCD_CS, HIGH); + return b; + #else + Wire.beginTransmission((uint8_t)LCD_I2C_ADDRESS); + Wire.write(READ_ENCODER); + Wire.endTransmission(); + #ifdef __AVR__ + Wire.requestFrom((uint8_t)LCD_I2C_ADDRESS, 2, 0, 0, 1); + #elif defined(__STM32F1__) + Wire.requestFrom((uint8_t)LCD_I2C_ADDRESS, (uint8_t)2); + #elif EITHER(STM32F4xx, TARGET_LPC1768) + Wire.requestFrom(LCD_I2C_ADDRESS, 2); + #endif + encoderDiff += Wire.read(); + return Wire.read(); //buttons + #endif +} + +// Duration in ms, freq in Hz +void MarlinUI::buzz(const long duration, const uint16_t freq) { + if (!PanelDetected) return; + #if ENABLED(TFTGLCD_PANEL_SPI) + WRITE(TFTGLCD_CS, LOW); + SPI_SEND_ONE(BUZZER); + SPI_SEND_TWO((uint16_t)duration); + SPI_SEND_TWO(freq); + WRITE(TFTGLCD_CS, HIGH); + #else + Wire.beginTransmission((uint8_t)LCD_I2C_ADDRESS); + Wire.write(BUZZER); + Wire.write((uint8_t)(duration >> 8)); + Wire.write((uint8_t)duration); + Wire.write((uint8_t)(freq >> 8)); + Wire.write((uint8_t)freq); + Wire.endTransmission(); + #endif +} + +void MarlinUI::init_lcd() { + uint8_t t; + lcd.clear_buffer(); + t = 0; + #if ENABLED(TFTGLCD_PANEL_SPI) + // SPI speed must be less 10MHz + SET_OUTPUT(TFTGLCD_CS); + WRITE(TFTGLCD_CS, HIGH); + spiInit(TERN(__STM32F1__, SPI_QUARTER_SPEED, SPI_FULL_SPEED)); + WRITE(TFTGLCD_CS, LOW); + SPI_SEND_ONE(GET_LCD_ROW); + t = SPI_SEND_ONE(GET_SPI_DATA); + #else + #ifdef TARGET_LPC1768 + Wire.begin(); //init twi/I2C + #else + Wire.begin((uint8_t)LCD_I2C_ADDRESS); //init twi/I2C + #endif + Wire.beginTransmission((uint8_t)LCD_I2C_ADDRESS); + Wire.write((uint8_t)GET_LCD_ROW); // put command to buffer + Wire.endTransmission(); // send buffer + #ifdef __AVR__ + Wire.requestFrom((uint8_t)LCD_I2C_ADDRESS, 1, 0, 0, 1); + #elif ANY(__STM32F1__, STM32F4xx, TARGET_LPC1768) + Wire.requestFrom(LCD_I2C_ADDRESS, 1); + #endif + t = (uint8_t)Wire.read(); + #endif + + if (t == LCD_HEIGHT) { + PanelDetected = 1; + #if ENABLED(TFTGLCD_PANEL_SPI) + SPI_SEND_ONE(INIT_SCREEN); + SPI_SEND_ONE(Marlin); + WRITE(TFTGLCD_CS, HIGH); + #else + Wire.beginTransmission((uint8_t)LCD_I2C_ADDRESS); + Wire.write((uint8_t)INIT_SCREEN); + Wire.write(Marlin); + Wire.endTransmission(); + #endif + } + else + PanelDetected = 0; + safe_delay(100); +} + +bool MarlinUI::detected() { + return PanelDetected; +} + +void MarlinUI::clear_lcd() { + if (!PanelDetected) return; + lcd.clr_screen(); + lcd.clear_buffer(); +} + +int16_t MarlinUI::contrast; // Initialized by settings.load() + +void MarlinUI::set_contrast(const int16_t value) { + contrast = constrain(value, LCD_CONTRAST_MIN, LCD_CONTRAST_MAX); + lcd.setContrast(contrast); +} + +static void center_text_P(PGM_P pstart, uint8_t y) { + uint8_t len = utf8_strlen_P(pstart); + if (len < LCD_WIDTH) + lcd.setCursor((LCD_WIDTH - len) / 2, y); + else + lcd.setCursor(0, y); + lcd_put_u8str_P(pstart); +} + +#if ENABLED(SHOW_BOOTSCREEN) + + void MarlinUI::show_bootscreen() { + if (!PanelDetected) return; + // + // Show the Marlin logo, splash line1, and splash line 2 + // + uint8_t indent = (LCD_WIDTH - 8) / 2; + // symbols 217 (bottom right corner) and 218 (top left corner) are using for letters in some languages + // and they should be moved to begining ASCII table as spetial symbols + lcd.setCursor(indent, 0); lcd.write(TLC); lcd_put_u8str_P(PSTR("------")); lcd.write(TRC); + lcd.setCursor(indent, 1); lcd.write(LR); lcd_put_u8str_P(PSTR("Marlin")); lcd.write(LR); + lcd.setCursor(indent, 2); lcd.write(BLC); lcd_put_u8str_P(PSTR("------")); lcd.write(BRC); + center_text_P(PSTR(SHORT_BUILD_VERSION), 3); + center_text_P(PSTR(MARLIN_WEBSITE_URL), 4); + picBits = ICON_LOGO; + lcd.print_screen(); + safe_delay(1500); + } + +#endif // SHOW_BOOTSCREEN + +void MarlinUI::draw_kill_screen() { + if (!PanelDetected) return; + lcd.clear_buffer(); + lcd.setCursor(0, 3); lcd.write(COLOR_ERROR); + lcd.setCursor((LCD_WIDTH - utf8_strlen(status_message)) / 2 + 1, 3); + lcd_put_u8str(status_message); + center_text_P(GET_TEXT(MSG_HALTED), 5); + center_text_P(GET_TEXT(MSG_PLEASE_RESET), 6); + lcd.print_screen(); +} + +// +// Before homing, blink '123' <-> '???'. +// Homed but unknown... '123' <-> ' '. +// Homed and known, display constantly. +// +FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const bool blink) { + lcd.write('X' + uint8_t(axis)); + if (blink) + lcd.print(value); + else { + if (!TEST(axis_homed, axis)) + while (const char c = *value++) lcd.write(c <= '.' ? c : '?'); + else { + #if NONE(HOME_AFTER_DEACTIVATE, DISABLE_REDUCED_ACCURACY_WARNING) + if (!TEST(axis_known_position, axis)) + lcd_put_u8str_P(axis == Z_AXIS ? PSTR(" ") : PSTR(" ")); + else + #endif + lcd_put_u8str(value); + } + } +} + +FORCE_INLINE void _draw_heater_status(const heater_id_t heater_id, const char *prefix, const bool blink) { + uint8_t pic_hot_bits; + #if HAS_HEATED_BED + const bool isBed = heater_id < 0; + const float t1 = (isBed ? thermalManager.degBed() : thermalManager.degHotend(heater_id)); + const float t2 = (isBed ? thermalManager.degTargetBed() : thermalManager.degTargetHotend(heater_id)); + #else + const float t1 = thermalManager.degHotend(heater_id); + const float t2 = thermalManager.degTargetHotend(heater_id); + #endif + + #if HOTENDS < 2 + if (heater_id == H_E0) { + lcd.setCursor(2, 5); lcd.print(prefix); //HE + lcd.setCursor(1, 6); lcd.print(i16tostr3rj(t1 + 0.5)); + lcd.setCursor(1, 7); + } + else { + lcd.setCursor(6, 5); lcd.print(prefix); //BED + lcd.setCursor(6, 6); lcd.print(i16tostr3rj(t1 + 0.5)); + lcd.setCursor(6, 7); + } + #else + if (heater_id > H_BED) { + lcd.setCursor(heater_id * 4, 5); lcd.print(prefix); //HE1 or HE2 or HE3 + lcd.setCursor(heater_id * 4, 6); lcd.print(i16tostr3rj(t1 + 0.5)); + lcd.setCursor(heater_id * 4, 7); + } + else { + lcd.setCursor(13, 5); lcd.print(prefix); //BED + lcd.setCursor(13, 6); lcd.print(i16tostr3rj(t1 + 0.5)); + lcd.setCursor(13, 7); + } + #endif // HOTENDS <= 1 + + #if !HEATER_IDLE_HANDLER + UNUSED(blink); + #else + if (!blink && thermalManager.heater_idle[thermalManager.idle_index_for_id(heater_id)].timed_out) { + lcd.write(' '); + if (t2 >= 10) lcd.write(' '); + if (t2 >= 100) lcd.write(' '); + } + else + #endif // !HEATER_IDLE_HANDLER + lcd.print(i16tostr3rj(t2 + 0.5)); + + switch (heater_id) { + case H_BED: pic_hot_bits = ICON_BED; break; + case H_E0: pic_hot_bits = ICON_TEMP1; break; + case H_E1: pic_hot_bits = ICON_TEMP2; break; + case H_E2: pic_hot_bits = ICON_TEMP3; + default: break; + } + + if (t2) picBits |= pic_hot_bits; + else picBits &= ~pic_hot_bits; + + if (t1 > 50) hotBits |= pic_hot_bits; + else hotBits &= ~pic_hot_bits; + + if (hotBits) picBits |= ICON_HOT; + else picBits &= ~ICON_HOT; +} + +#if HAS_PRINT_PROGRESS + + FORCE_INLINE void _draw_print_progress() { + if (!PanelDetected) return; + const uint8_t progress = ui._get_progress(); + #if ENABLED(SDSUPPORT) + lcd_put_u8str_P(PSTR("SD")); + #elif ENABLED(LCD_SET_PROGRESS_MANUALLY) + lcd_put_u8str_P(PSTR("P:")); + #endif + if (progress) + lcd.print(ui8tostr3rj(progress)); + else + lcd_put_u8str_P(PSTR("---")); + lcd.write('%'); + } + +#endif // HAS_PRINT_PROGRESS + +#if ENABLED(LCD_PROGRESS_BAR) + + void MarlinUI::draw_progress_bar(const uint8_t percent) { + if (!PanelDetected) return; + if (fb == &framebuffer[0] + LCD_WIDTH * 2) { // For status screen + lcd.write('%'); lcd.write(percent); + } + else { // For progress bar test + lcd.setCursor(LCD_WIDTH / 2 - 2, MIDDLE_Y); + lcd.print(i16tostr3rj(percent)); lcd.write('%'); + lcd.print_line(); + lcd.setCursor(0, MIDDLE_Y + 1); + lcd.write('%'); lcd.write(percent); + lcd.print_line(); + } + } + +#endif + +void MarlinUI::draw_status_message(const bool blink) { + if (!PanelDetected) return; + lcd.setCursor(0, 3); + #if BOTH(FILAMENT_LCD_DISPLAY, SDSUPPORT) + + // Alternate Status message and Filament display + if (ELAPSED(millis(), next_filament_display)) { + lcd_put_u8str_P(PSTR("Dia ")); + lcd.print(ftostr12ns(filament_width_meas)); + lcd_put_u8str_P(PSTR(" V")); + lcd.print(i16tostr3rj(100.0 * ( + parser.volumetric_enabled + ? planner.volumetric_area_nominal / planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] + : planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] + ) + )); + lcd.write('%'); + return; + } + + #endif // FILAMENT_LCD_DISPLAY && SDSUPPORT + + // Get the UTF8 character count of the string + uint8_t slen = utf8_strlen(status_message); + + #if ENABLED(STATUS_MESSAGE_SCROLLING) + + static bool last_blink = false; + + // If the string fits into the LCD, just print it and do not scroll it + if (slen <= LCD_WIDTH) { + + // The string isn't scrolling and may not fill the screen + lcd_put_u8str(status_message); + + // Fill the rest with spaces + while (slen < LCD_WIDTH) { lcd.write(' '); ++slen; } + } + else { + // String is larger than the available space in screen. + + // Get a pointer to the next valid UTF8 character + // and the string remaining length + uint8_t rlen; + const char *stat = status_and_len(rlen); + lcd_put_u8str_max(stat, LCD_WIDTH); // The string leaves space + + // If the remaining string doesn't completely fill the screen + if (rlen < LCD_WIDTH) { + lcd.write('.'); // Always at 1+ spaces left, draw a dot + uint8_t chars = LCD_WIDTH - rlen; // Amount of space left in characters + if (--chars) { // Draw a second dot if there's space + lcd.write('.'); + if (--chars) + lcd_put_u8str_max(status_message, chars); // Print a second copy of the message + } + } + if (last_blink != blink) { + last_blink = blink; + advance_status_scroll(); + } + } + + #else + + UNUSED(blink); + + // Just print the string to the LCD + lcd_put_u8str_max(status_message, LCD_WIDTH); + + // Fill the rest with spaces if there are missing spaces + while (slen < LCD_WIDTH) { + lcd.write(' '); + ++slen; + } + + #endif +} + +/** +Possible status screens: + +Equal to 20x10 text LCD + +|X 000 Y 000 Z 000.00| +|FR100% SD100% C--:--| +| Progress bar line | +|Status message | +| | +| HE BED FAN | +| ttc ttc % | ttc - current temperature +| tts tts %%% | tts - setted temperature, %%% - percent for FAN +| ICO ICO ICO ICO | ICO - icon 48x48, placed in 2 text lines +| ICO ICO ICO ICO | ICO / + +or + +|X 000 Y 000 Z 000.00| +|FR100% SD100% C--:--| +| Progress bar line | +|Status message | +| | +|HE1 HE2 HE3 BED ICO| +|ttc ttc ttc ttc ICO| +|tts tts tts tts %%%| +|ICO ICO ICO ICO ICO| +|ICO ICO ICO ICO ICO| + +or + +Equal to 24x10 text LCD + +|X 000 Y 000 Z 000.00 | +|FR100% SD100% C--:--| +| Progress bar line | +|Status message | +| | +|HE1 HE2 HE3 BED FAN | +|ttc ttc ttc ttc % | +|tts tts tts tts %%% | +|ICO ICO ICO ICO ICO ICO| +|ICO ICO ICO ICO ICO ICO| +*/ + +void MarlinUI::draw_status_screen() { + if (!PanelDetected) return; + + const bool blink = get_blink(); + + lcd.clear_buffer(); + + // + // Line 1 - XYZ coordinates + // + + lcd.setCursor(0, 0); + _draw_axis_value(X_AXIS, ftostr4sign(LOGICAL_X_POSITION(current_position[X_AXIS])), blink); lcd.write(' '); + _draw_axis_value(Y_AXIS, ftostr4sign(LOGICAL_Y_POSITION(current_position[Y_AXIS])), blink); lcd.write(' '); + _draw_axis_value(Z_AXIS, ftostr52sp(LOGICAL_Z_POSITION(current_position[Z_AXIS])), blink); + + #if HAS_LEVELING && !HAS_HEATED_BED + lcd.write(planner.leveling_active || blink ? '_' : ' '); + #endif + + // + // Line 2 - feedrate, , time + // + + lcd.setCursor(0, 1); + lcd_put_u8str_P(PSTR("FR")); lcd.print(i16tostr3rj(feedrate_percentage)); lcd.write('%'); + + #if BOTH(SDSUPPORT, HAS_PRINT_PROGRESS) + lcd.setCursor(LCD_WIDTH / 2 - 3, 1); + _draw_print_progress(); + #endif + + char buffer[10]; + duration_t elapsed = print_job_timer.duration(); + uint8_t len = elapsed.toDigital(buffer); + + lcd.setCursor((LCD_WIDTH - 1) - len, 1); + lcd.write(0x07); lcd.print(buffer); // LCD_CLOCK_CHAR + + // + // Line 3 - progressbar + // + + lcd.setCursor(0, 2); + #if ENABLED(LCD_PROGRESS_BAR) + draw_progress_bar(_get_progress()); + #else + lcd.write('%'); lcd.write(0); + #endif + + // + // Line 4 - Status Message (which may be a Filament display) + // + + draw_status_message(blink); + + // + // Line 5 + // + + #if HOTENDS <= 1 || (HOTENDS <= 2 && !HAS_HEATED_BED) + #if DUAL_MIXING_EXTRUDER + lcd.setCursor(0, 4); + // Two-component mix / gradient instead of XY + char mixer_messages[12]; + const char *mix_label; + #if ENABLED(GRADIENT_MIX) + if (mixer.gradient.enabled) { + mixer.update_mix_from_gradient(); + mix_label = "Gr"; + } + else + #endif + { + mixer.update_mix_from_vtool(); + mix_label = "Mx"; + } + sprintf_P(mixer_messages, PSTR("%s %d;%d%% "), mix_label, int(mixer.mix[0]), int(mixer.mix[1])); + lcd_put_u8str(mixer_messages); + #endif + #endif + + // + // Line 6..8 Temperatures, FAN + // + + #if HOTENDS < 2 + _draw_heater_status(H_E0, "HE", blink); // Hotend Temperature + #else + _draw_heater_status(H_E0, "HE1", blink); // Hotend 1 Temperature + _draw_heater_status(H_E1, "HE2", blink); // Hotend 2 Temperature + #if HOTENDS > 2 + _draw_heater_status(H_E2, "HE3", blink); // Hotend 3 Temperature + #endif + #endif // HOTENDS <= 1 + + #if HAS_HEATED_BED + #if HAS_LEVELING + _draw_heater_status(H_BED, (planner.leveling_active && blink ? "___" : "BED"), blink); + #else + _draw_heater_status(H_BED, "BED", blink); + #endif + #endif // HAS_HEATED_BED + + #if FAN_COUNT > 0 + uint16_t spd = thermalManager.fan_speed[0]; + + #if ENABLED(ADAPTIVE_FAN_SLOWING) + if (!blink) spd = thermalManager.scaledFanSpeed(0, spd); + #endif + + uint16_t per = thermalManager.fanPercent(spd); + #if HOTENDS < 2 + #define FANX 11 + #else + #define FANX 17 + #endif + lcd.setCursor(FANX, 5); lcd_put_u8str_P(PSTR("FAN")); + lcd.setCursor(FANX + 1, 6); lcd.write('%'); + lcd.setCursor(FANX, 7); + lcd.print(i16tostr3rj(per)); + + if (TERN0(HAS_FAN0, thermalManager.fan_speed[0]) || TERN0(HAS_FAN1, thermalManager.fan_speed[1]) || TERN0(HAS_FAN2, thermalManager.fan_speed[2])) + picBits |= ICON_FAN; + else + picBits &= ~ICON_FAN; + + #endif // FAN_COUNT > 0 + + // + // Line 9, 10 - icons + // + lcd.print_screen(); +} + +#if HAS_LCD_MENU + + #include "../menu/menu.h" + + #if ENABLED(ADVANCED_PAUSE_FEATURE) + + void MarlinUI::draw_hotend_status(const uint8_t row, const uint8_t extruder) { + if (!PanelDetected) return; + lcd.setCursor((LCD_WIDTH - 14) / 2, row + 1); + lcd.write(0x02); lcd_put_u8str_P(" E"); lcd.write('1' + extruder); lcd.write(' '); + lcd.print(i16tostr3rj(thermalManager.degHotend(extruder))); lcd.write(0x01); lcd.write('/'); + lcd.print(i16tostr3rj(thermalManager.degTargetHotend(extruder))); lcd.write(0x01); + lcd.print_line(); + } + + #endif // ADVANCED_PAUSE_FEATURE + + // Draw a static item with no left-right margin required. Centered by default. + void MenuItem_static::draw(const uint8_t row, PGM_P const pstr, const uint8_t style/*=SS_DEFAULT*/, const char * const valstr/*=nullptr*/) { + if (!PanelDetected) return; + uint8_t n = LCD_WIDTH; + lcd.setCursor(0, row); + if ((style & SS_CENTER) && !valstr) { + int8_t pad = (LCD_WIDTH - utf8_strlen_P(pstr)) / 2; + while (--pad >= 0) { lcd.write(' '); n--; } + } + n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, n); + if (valstr) n -= lcd_put_u8str_max(valstr, n); + for (; n; --n) lcd.write(' '); + lcd.print_line(); + } + + // Draw a generic menu item with pre_char (if selected) and post_char + void MenuItemBase::_draw(const bool sel, const uint8_t row, PGM_P const pstr, const char pre_char, const char post_char) { + if (!PanelDetected) return; + lcd.setCursor(0, row); + lcd.write(sel ? pre_char : ' '); + uint8_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 2); + for (; n; --n) lcd.write(' '); + lcd.write(post_char); + lcd.print_line(); + } + + // Draw a menu item with a (potentially) editable value + void MenuEditItemBase::draw(const bool sel, const uint8_t row, PGM_P const pstr, const char* const data, const bool pgm) { + if (!PanelDetected) return; + const uint8_t vlen = data ? (pgm ? utf8_strlen_P(data) : utf8_strlen(data)) : 0; + lcd.setCursor(0, row); + lcd.write(sel ? LCD_STR_ARROW_RIGHT[0] : ' '); + uint8_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 2 - vlen); + if (vlen) { + lcd.write(':'); + for (; n; --n) lcd.write(' '); + if (pgm) lcd_put_u8str_P(data); else lcd_put_u8str(data); + } + lcd.print_line(); + } + + // Low-level draw_edit_screen can be used to draw an edit screen from anyplace + // This line moves to the last line of the screen for UBL plot screen on the panel side + void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char* const value/*=nullptr*/) { + if (!PanelDetected) return; + ui.encoder_direction_normal(); + const uint8_t y = TERN0(AUTO_BED_LEVELING_UBL, ui.external_control) ? LCD_HEIGHT - 1 : MIDDLE_Y; + lcd.setCursor(0, y); + lcd.write(COLOR_EDIT); + lcd_put_u8str_P(pstr); + if (value != nullptr) { + lcd.write(':'); + lcd.setCursor((LCD_WIDTH - 1) - (utf8_strlen(value) + 1), y); // Right-justified, padded by spaces + lcd.write(' '); // Overwrite char if value gets shorter + lcd.print(value); + lcd.write(' '); + lcd.print_line(); + } + } + + // The Select Screen presents a prompt and two "buttons" + void MenuItem_confirm::draw_select_screen(PGM_P const yes, PGM_P const no, const bool yesno, PGM_P const pref, const char * const string, PGM_P const suff) { + if (!PanelDetected) return; + ui.draw_select_screen_prompt(pref, string, suff); + lcd.setCursor(0, MIDDLE_Y); + lcd.write(COLOR_EDIT); + lcd.write(yesno ? ' ' : '['); lcd_put_u8str_P(no); lcd.write(yesno ? ' ' : ']'); + lcd.setCursor(LCD_WIDTH - utf8_strlen_P(yes) - 3, MIDDLE_Y); + lcd.write(yesno ? '[' : ' '); lcd_put_u8str_P(yes); lcd.write(yesno ? ']' : ' '); + lcd.print_line(); + } + + #if ENABLED(SDSUPPORT) + + void MenuItem_sdbase::draw(const bool sel, const uint8_t row, PGM_P const, CardReader &theCard, const bool isDir) { + if (!PanelDetected) return; + lcd.setCursor(0, row); + lcd.write(sel ? LCD_STR_ARROW_RIGHT[0] : ' '); + constexpr uint8_t maxlen = LCD_WIDTH - 2; + uint8_t n = maxlen - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, row, sel), maxlen); + for (; n; --n) lcd.write(' '); + lcd.write(isDir ? LCD_STR_FOLDER[0] : ' '); + lcd.print_line(); + } + + #endif // SDSUPPORT + + #if ENABLED(LCD_HAS_STATUS_INDICATORS) + + void MarlinUI::update_indicators() {} + + #endif // LCD_HAS_STATUS_INDICATORS + + #if ENABLED(AUTO_BED_LEVELING_UBL) + /** + * Map screen: + * |/---------\ (00,00) | + * || . . . . | X:000.00| + * || . . . . | Y:000.00| + * || . . . . | Z:00.000| + * || . . . . | | + * || . . . . | | + * || . . . . | | + * |+---------/ | + * | | + * |____________________| + */ + void MarlinUI::ubl_plot(const uint8_t x_plot, const uint8_t y_plot) { + if (!PanelDetected) return; + + #define _LCD_W_POS 12 + + lcd.clear_buffer(); + + //print only top left corner. All frame with grid points will be printed by panel + lcd.setCursor(0, 0); + *fb++ = TLC; //top left corner - marker for plot parameters + *fb = (GRID_MAX_POINTS_X << 4) + GRID_MAX_POINTS_Y; //set mesh size + + // Print plot position + lcd.setCursor(_LCD_W_POS, 0); + *fb++ = '('; lcd.print(i16tostr3left(x_plot)); + *fb++ = ','; lcd.print(i16tostr3left(y_plot)); *fb = ')'; + + // Show all values + lcd.setCursor(_LCD_W_POS, 1); lcd_put_u8str_P(PSTR("X:")); + lcd.print(ftostr52(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot])))); + lcd.setCursor(_LCD_W_POS, 2); lcd_put_u8str_P(PSTR("Y:")); + lcd.print(ftostr52(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot])))); + + // Show the location value + lcd.setCursor(_LCD_W_POS, 3); lcd_put_u8str_P(PSTR("Z:")); + + if (!isnan(ubl.z_values[x_plot][y_plot])) + lcd.print(ftostr43sign(ubl.z_values[x_plot][y_plot])); + else + lcd_put_u8str_P(PSTR(" -----")); + + center_text_P(GET_TEXT(MSG_UBL_FINE_TUNE_MESH), 8); + + lcd.print_screen(); + } + + #endif // AUTO_BED_LEVELING_UBL + +#endif // HAS_LCD_MENU + +#endif // IS_TFTGLCD_PANEL diff --git a/Marlin/src/lcd/TFTGLCD/ultralcd_TFTGLCD.h b/Marlin/src/lcd/TFTGLCD/ultralcd_TFTGLCD.h new file mode 100644 index 000000000000..eedcc4afa073 --- /dev/null +++ b/Marlin/src/lcd/TFTGLCD/ultralcd_TFTGLCD.h @@ -0,0 +1,75 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * Implementation of the LCD display routines for a TFT GLCD displays with external controller. + */ + +#include "../../inc/MarlinConfig.h" + +#if IS_TFTGLCD_PANEL + +#include "../../libs/duration_t.h" + +//////////////////////////////////// +// Set up button and encode mappings for each panel (into 'buttons' variable) +// +// This is just to map common functions (across different panels) onto the same +// macro name. The mapping is independent of whether the button is directly connected or +// via a shift/i2c register. + +//////////////////////////////////// +// Create LCD class instance and chipset-specific information +class TFTGLCD { + private: + public: + TFTGLCD(); + void clear_buffer(); + void clr_screen(); + void setCursor(uint8_t col, uint8_t row); + void write(char c); + void print(const char *line); + void print_line(); + void print_screen(); + void redraw_screen(); + void setContrast(uint16_t contrast); +}; + +extern TFTGLCD lcd; + +#include "../fontutils.h" +#include "../lcdprint.h" + +// Use panel encoder - free old encoder pins +#undef BTN_EN1 +#undef BTN_EN2 +#undef BTN_ENC +#define BTN_EN1 -1 +#define BTN_EN2 -1 +#define BTN_ENC -1 + +#ifndef EN_C + #define EN_C 4 //for click +#endif + +#endif // IS_TFTGLCD_PANEL diff --git a/Marlin/src/lcd/dogm/HAL_LCD_class_defines.h b/Marlin/src/lcd/dogm/HAL_LCD_class_defines.h index 4ab165c7a0b6..1511c6993323 100644 --- a/Marlin/src/lcd/dogm/HAL_LCD_class_defines.h +++ b/Marlin/src/lcd/dogm/HAL_LCD_class_defines.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/lcd/dogm/HAL_LCD_com_defines.h b/Marlin/src/lcd/dogm/HAL_LCD_com_defines.h index 25224934c50c..da7d4f6f1ec0 100644 --- a/Marlin/src/lcd/dogm/HAL_LCD_com_defines.h +++ b/Marlin/src/lcd/dogm/HAL_LCD_com_defines.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -82,11 +82,6 @@ #define U8G_COM_SSD_I2C_HAL u8g_com_arduino_ssd_i2c_fn - #if PIN_EXISTS(FSMC_CS) - uint8_t u8g_com_stm32duino_fsmc_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); - #define U8G_COM_HAL_FSMC_FN u8g_com_stm32duino_fsmc_fn - #endif - #elif defined(TARGET_LPC1768) uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); @@ -117,6 +112,9 @@ #ifndef U8G_COM_SSD_I2C_HAL #define U8G_COM_SSD_I2C_HAL u8g_com_null_fn #endif -#ifndef U8G_COM_HAL_FSMC_FN - #define U8G_COM_HAL_FSMC_FN u8g_com_null_fn +#if EITHER(FSMC_GRAPHICAL_TFT, SPI_GRAPHICAL_TFT) + uint8_t u8g_com_hal_tft_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + #define U8G_COM_HAL_TFT_FN u8g_com_hal_tft_fn +#else + #define U8G_COM_HAL_TFT_FN u8g_com_null_fn #endif diff --git a/Marlin/src/lcd/dogm/dogm_Bootscreen.h b/Marlin/src/lcd/dogm/dogm_Bootscreen.h index f4bf5f5f692b..c9001119d9d4 100644 --- a/Marlin/src/lcd/dogm/dogm_Bootscreen.h +++ b/Marlin/src/lcd/dogm/dogm_Bootscreen.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Standard Marlin Boot Screen bitmaps * * Use the Marlin Bitmap Converter to make your own: - * http://marlinfw.org/tools/u8glib/converter.html + * https://marlinfw.org/tools/u8glib/converter.html */ #include "../../inc/MarlinConfig.h" diff --git a/Marlin/src/lcd/dogm/dogm_Statusscreen.h b/Marlin/src/lcd/dogm/dogm_Statusscreen.h index 3656b02e0860..c6ad566cffaf 100644 --- a/Marlin/src/lcd/dogm/dogm_Statusscreen.h +++ b/Marlin/src/lcd/dogm/dogm_Statusscreen.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Standard Marlin Status Screen bitmaps * * Use the Marlin Bitmap Converter to make your own: - * http://marlinfw.org/tools/u8glib/converter.html + * https://marlinfw.org/tools/u8glib/converter.html */ #include "../../inc/MarlinConfig.h" @@ -278,7 +278,7 @@ // // Status Screen Hotends bitmaps // - #if HOTENDS + #if HAS_HOTEND #define STATUS_HOTEND1_WIDTH 16 @@ -854,16 +854,16 @@ }; #endif -#else // HAS_HEATED_CHAMBER - #define STATUS_CHAMBER_WIDTH 0 #endif -#define BED_OR_CHAMBER_OR_FAN (BED_OR_CHAMBER || HAS_FAN0) +#ifndef STATUS_CHAMBER_WIDTH + #define STATUS_CHAMBER_WIDTH 0 +#endif // Can also be overridden in Configuration_adv.h // If you can afford it, try the 3-frame fan animation! // Don't compile in the fan animation with no fan -#if !HAS_FAN0 || (HOTENDS == 5 || (HOTENDS == 4 && BED_OR_CHAMBER) || (ENABLED(STATUS_COMBINE_HEATERS) && HAS_HEATED_CHAMBER)) +#if !HAS_FAN0 || (HOTENDS == 5 || (HOTENDS == 4 && BED_OR_CHAMBER) || BOTH(STATUS_COMBINE_HEATERS, HAS_HEATED_CHAMBER)) #undef STATUS_FAN_FRAMES #elif !STATUS_FAN_FRAMES #define STATUS_FAN_FRAMES 2 @@ -1341,7 +1341,7 @@ #undef STATUS_LOGO_WIDTH #endif - #if (HOTENDS > 1 && STATUS_LOGO_WIDTH && BED_OR_CHAMBER_OR_FAN) || (HOTENDS >= 3 && !BED_OR_CHAMBER_OR_FAN) + #if !defined(STATUS_HEATERS_X) && ((HAS_MULTI_HOTEND && STATUS_LOGO_WIDTH && BED_OR_CHAMBER_OR_FAN) || (HOTENDS >= 3 && !BED_OR_CHAMBER_OR_FAN)) #define _STATUS_HEATERS_X(H,S,N) ((LCD_PIXEL_WIDTH - (H * (S + N)) - (_EXTRA_WIDTH) + (STATUS_LOGO_WIDTH)) / 2) #if STATUS_HOTEND1_WIDTH #if HOTENDS > 2 @@ -1370,7 +1370,7 @@ #define STATUS_LOGO_X 0 #endif #ifndef STATUS_LOGO_Y - #define STATUS_LOGO_Y _MIN(0U, (10 - (STATUS_LOGO_HEIGHT) / 2)) + #define STATUS_LOGO_Y _MIN(0U, (20 - (STATUS_LOGO_HEIGHT)) / 2) #endif #ifndef STATUS_LOGO_HEIGHT #define STATUS_LOGO_HEIGHT (sizeof(status_logo_bmp) / (STATUS_LOGO_BYTEWIDTH)) @@ -1391,7 +1391,7 @@ ((STATUS_CHAMBER_WIDTH || STATUS_FAN_WIDTH || STATUS_BED_WIDTH) && STATUS_HOTEND_BITMAPS == 4) #define STATUS_HEATERS_X 5 #else - #if ENABLED(STATUS_COMBINE_HEATERS) && HAS_HEATED_BED && HOTENDS <= 4 + #if BOTH(STATUS_COMBINE_HEATERS, HAS_HEATED_BED) && HOTENDS <= 4 #define STATUS_HEATERS_X 5 #else #define STATUS_HEATERS_X 8 // Like the included bitmaps @@ -1423,8 +1423,14 @@ #ifndef STATUS_HOTEND6_WIDTH #define STATUS_HOTEND6_WIDTH STATUS_HOTEND5_WIDTH #endif + #ifndef STATUS_HOTEND7_WIDTH + #define STATUS_HOTEND7_WIDTH STATUS_HOTEND6_WIDTH + #endif + #ifndef STATUS_HOTEND8_WIDTH + #define STATUS_HOTEND8_WIDTH STATUS_HOTEND7_WIDTH + #endif - constexpr uint8_t status_hotend_width[HOTENDS] = ARRAY_N(HOTENDS, STATUS_HOTEND1_WIDTH, STATUS_HOTEND2_WIDTH, STATUS_HOTEND3_WIDTH, STATUS_HOTEND4_WIDTH, STATUS_HOTEND5_WIDTH, STATUS_HOTEND6_WIDTH); + constexpr uint8_t status_hotend_width[HOTENDS] = ARRAY_N(HOTENDS, STATUS_HOTEND1_WIDTH, STATUS_HOTEND2_WIDTH, STATUS_HOTEND3_WIDTH, STATUS_HOTEND4_WIDTH, STATUS_HOTEND5_WIDTH, STATUS_HOTEND6_WIDTH, STATUS_HOTEND7_WIDTH, STATUS_HOTEND8_WIDTH); #define STATUS_HOTEND_WIDTH(N) status_hotend_width[N] #ifndef STATUS_HOTEND1_BYTEWIDTH @@ -1445,8 +1451,14 @@ #ifndef STATUS_HOTEND6_BYTEWIDTH #define STATUS_HOTEND6_BYTEWIDTH BW(STATUS_HOTEND6_WIDTH) #endif + #ifndef STATUS_HOTEND7_BYTEWIDTH + #define STATUS_HOTEND7_BYTEWIDTH BW(STATUS_HOTEND7_WIDTH) + #endif + #ifndef STATUS_HOTEND8_BYTEWIDTH + #define STATUS_HOTEND8_BYTEWIDTH BW(STATUS_HOTEND8_WIDTH) + #endif - constexpr uint8_t status_hotend_bytewidth[HOTENDS] = ARRAY_N(HOTENDS, STATUS_HOTEND1_BYTEWIDTH, STATUS_HOTEND2_BYTEWIDTH, STATUS_HOTEND3_BYTEWIDTH, STATUS_HOTEND4_BYTEWIDTH, STATUS_HOTEND5_BYTEWIDTH, STATUS_HOTEND6_BYTEWIDTH); + constexpr uint8_t status_hotend_bytewidth[HOTENDS] = ARRAY_N(HOTENDS, STATUS_HOTEND1_BYTEWIDTH, STATUS_HOTEND2_BYTEWIDTH, STATUS_HOTEND3_BYTEWIDTH, STATUS_HOTEND4_BYTEWIDTH, STATUS_HOTEND5_BYTEWIDTH, STATUS_HOTEND6_BYTEWIDTH, STATUS_HOTEND7_BYTEWIDTH, STATUS_HOTEND8_BYTEWIDTH); #define STATUS_HOTEND_BYTEWIDTH(N) status_hotend_bytewidth[N] #ifndef STATUS_HOTEND1_X @@ -1469,10 +1481,16 @@ #ifndef STATUS_HOTEND6_X #define STATUS_HOTEND6_X STATUS_HOTEND5_X + STATUS_HEATERS_XSPACE #endif + #ifndef STATUS_HOTEND7_X + #define STATUS_HOTEND7_X STATUS_HOTEND6_X + STATUS_HEATERS_XSPACE + #endif + #ifndef STATUS_HOTEND8_X + #define STATUS_HOTEND8_X STATUS_HOTEND7_X + STATUS_HEATERS_XSPACE + #endif - constexpr uint8_t status_hotend_x[HOTENDS] = ARRAY_N(HOTENDS, STATUS_HOTEND1_X, STATUS_HOTEND2_X, STATUS_HOTEND3_X, STATUS_HOTEND4_X, STATUS_HOTEND5_X, STATUS_HOTEND6_X); + constexpr uint8_t status_hotend_x[HOTENDS] = ARRAY_N(HOTENDS, STATUS_HOTEND1_X, STATUS_HOTEND2_X, STATUS_HOTEND3_X, STATUS_HOTEND4_X, STATUS_HOTEND5_X, STATUS_HOTEND6_X, STATUS_HOTEND7_X, STATUS_HOTEND8_X); #define STATUS_HOTEND_X(N) status_hotend_x[N] - #elif HOTENDS > 1 + #elif HAS_MULTI_HOTEND #define STATUS_HOTEND_X(N) ((N) ? STATUS_HOTEND2_X : STATUS_HOTEND1_X) #else #define STATUS_HOTEND_X(N) STATUS_HOTEND1_X @@ -1495,7 +1513,13 @@ #ifndef STATUS_HOTEND6_TEXT_X #define STATUS_HOTEND6_TEXT_X STATUS_HOTEND5_TEXT_X + STATUS_HEATERS_XSPACE #endif - constexpr uint8_t status_hotend_text_x[] = ARRAY_N(HOTENDS, STATUS_HOTEND1_TEXT_X, STATUS_HOTEND2_TEXT_X, STATUS_HOTEND3_TEXT_X, STATUS_HOTEND4_TEXT_X, STATUS_HOTEND5_TEXT_X, STATUS_HOTEND6_TEXT_X); + #ifndef STATUS_HOTEND7_TEXT_X + #define STATUS_HOTEND7_TEXT_X STATUS_HOTEND6_TEXT_X + STATUS_HEATERS_XSPACE + #endif + #ifndef STATUS_HOTEND8_TEXT_X + #define STATUS_HOTEND8_TEXT_X STATUS_HOTEND7_TEXT_X + STATUS_HEATERS_XSPACE + #endif + constexpr uint8_t status_hotend_text_x[] = ARRAY_N(HOTENDS, STATUS_HOTEND1_TEXT_X, STATUS_HOTEND2_TEXT_X, STATUS_HOTEND3_TEXT_X, STATUS_HOTEND4_TEXT_X, STATUS_HOTEND5_TEXT_X, STATUS_HOTEND6_TEXT_X, STATUS_HOTEND7_TEXT_X, STATUS_HOTEND8_TEXT_X); #define STATUS_HOTEND_TEXT_X(N) status_hotend_text_x[N] #else #define STATUS_HOTEND_TEXT_X(N) (STATUS_HOTEND1_X + 6 + (N) * (STATUS_HEATERS_XSPACE)) @@ -1729,16 +1753,36 @@ #endif #endif -#define DO_DRAW_LOGO (STATUS_LOGO_WIDTH && ENABLED(CUSTOM_STATUS_SCREEN_IMAGE)) -#define DO_DRAW_HOTENDS (HOTENDS > 0) -#define DO_DRAW_BED (HAS_HEATED_BED && HOTENDS <= 4) -#define DO_DRAW_CUTTER (HAS_CUTTER && !DO_DRAW_BED) -#define DO_DRAW_CHAMBER (HAS_TEMP_CHAMBER && STATUS_CHAMBER_WIDTH && HOTENDS <= 4) -#define DO_DRAW_FAN (HAS_FAN0 && STATUS_FAN_WIDTH && HOTENDS <= 4 && defined(STATUS_FAN_FRAMES)) - -#define ANIM_HOTEND (HOTENDS && ENABLED(STATUS_HOTEND_ANIM)) -#define ANIM_BED (DO_DRAW_BED && ENABLED(STATUS_BED_ANIM)) -#define ANIM_CHAMBER (DO_DRAW_CHAMBER && ENABLED(STATUS_CHAMBER_ANIM)) -#define ANIM_CUTTER (DO_DRAW_CUTTER && ENABLED(STATUS_CUTTER_ANIM)) - -#define ANIM_HBCC (ANIM_HOTEND || ANIM_BED || ANIM_CHAMBER || ANIM_CUTTER) +#if STATUS_LOGO_WIDTH && ENABLED(CUSTOM_STATUS_SCREEN_IMAGE) + #define DO_DRAW_LOGO 1 +#endif +#if HOTENDS > 0 + #define DO_DRAW_HOTENDS 1 +#endif +#if HAS_HEATED_BED && HOTENDS <= 4 + #define DO_DRAW_BED 1 +#endif +#if HAS_CUTTER && !DO_DRAW_BED + #define DO_DRAW_CUTTER 1 +#endif +#if HAS_TEMP_CHAMBER && STATUS_CHAMBER_WIDTH && HOTENDS <= 4 + #define DO_DRAW_CHAMBER 1 +#endif +#if HAS_FAN0 && STATUS_FAN_WIDTH && HOTENDS <= 4 && defined(STATUS_FAN_FRAMES) + #define DO_DRAW_FAN 1 +#endif +#if BOTH(HAS_HOTEND, STATUS_HOTEND_ANIM) + #define ANIM_HOTEND 1 +#endif +#if BOTH(DO_DRAW_BED, STATUS_BED_ANIM) + #define ANIM_BED 1 +#endif +#if BOTH(DO_DRAW_CHAMBER, STATUS_CHAMBER_ANIM) + #define ANIM_CHAMBER 1 +#endif +#if BOTH(DO_DRAW_CUTTER, STATUS_CUTTER_ANIM) + #define ANIM_CUTTER 1 +#endif +#if ANIM_HOTEND || ANIM_BED || ANIM_CHAMBER || ANIM_CUTTER + #define ANIM_HBCC 1 +#endif diff --git a/Marlin/src/lcd/dogm/fontdata/fontdata_6x9_marlin.h b/Marlin/src/lcd/dogm/fontdata/fontdata_6x9_marlin.h index fd07e4af1e13..cd9cb3cdc968 100644 --- a/Marlin/src/lcd/dogm/fontdata/fontdata_6x9_marlin.h +++ b/Marlin/src/lcd/dogm/fontdata/fontdata_6x9_marlin.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ Fontname: -Misc-Fixed-Medium-R-Normal--9-90-75-75-C-60-ISO10646-1 Copyright: Public domain font. Share and enjoy. Capital A Height: 6, '1' Height: 6 - Calculated Max Values w= 6 h= 9 x= 2 y= 7 dx= 6 dy= 0 ascent= 7 len= 9 + Calculated Max Values w= 6 h= 9 x= 5 y= 5 dx= 6 dy= 0 ascent= 7 len= 9 Font Bounding box w= 6 h= 9 x= 0 y=-2 Calculated Min Values x= 0 y=-2 dx= 0 dy= 0 Pure Font ascent = 6 descent=-2 @@ -33,149 +33,157 @@ Max Font ascent = 7 descent=-2 */ #include -const u8g_fntpgm_uint8_t u8g_font_6x9[2300] U8G_SECTION(".progmem.u8g_font_6x9") = { - 0, 6, 9, 0, 254, 6, 1, 137, 2, 254, 32, 255, 254, 7, 254, 6, - 254, 0, 0, 0, 6, 0, 7, 1, 6, 6, 6, 2, 0, 128, 128, 128, - 128, 0, 128, 3, 3, 3, 6, 1, 3, 160, 160, 160, 5, 7, 7, 6, - 0, 255, 80, 80, 248, 80, 248, 80, 80, 5, 9, 9, 6, 0, 254, 32, - 112, 168, 160, 112, 40, 168, 112, 32, 6, 8, 8, 6, 0, 255, 64, 168, - 72, 16, 32, 72, 84, 8, 5, 7, 7, 6, 0, 255, 96, 144, 144, 96, - 152, 144, 104, 1, 3, 3, 6, 2, 3, 128, 128, 128, 2, 7, 7, 6, - 2, 255, 64, 128, 128, 128, 128, 128, 64, 2, 7, 7, 6, 2, 255, 128, - 64, 64, 64, 64, 64, 128, 5, 5, 5, 6, 0, 0, 136, 80, 248, 80, - 136, 5, 5, 5, 6, 0, 0, 32, 32, 248, 32, 32, 2, 4, 4, 6, - 2, 254, 192, 64, 64, 128, 5, 1, 1, 6, 0, 2, 248, 2, 2, 2, - 6, 2, 0, 192, 192, 4, 6, 6, 6, 1, 0, 16, 16, 32, 64, 128, - 128, 4, 6, 6, 6, 1, 0, 96, 144, 144, 144, 144, 96, 3, 6, 6, - 6, 1, 0, 64, 192, 64, 64, 64, 224, 4, 6, 6, 6, 1, 0, 96, - 144, 16, 32, 64, 240, 4, 6, 6, 6, 1, 0, 240, 32, 96, 16, 16, - 224, 5, 6, 6, 6, 0, 0, 16, 48, 80, 144, 248, 16, 4, 6, 6, - 6, 1, 0, 240, 128, 224, 16, 16, 224, 4, 6, 6, 6, 1, 0, 96, - 128, 224, 144, 144, 96, 4, 6, 6, 6, 1, 0, 240, 16, 16, 32, 64, - 64, 4, 6, 6, 6, 1, 0, 96, 144, 96, 144, 144, 96, 4, 6, 6, - 6, 1, 0, 96, 144, 144, 112, 16, 96, 2, 5, 5, 6, 2, 0, 192, - 192, 0, 192, 192, 2, 7, 7, 6, 2, 254, 192, 192, 0, 192, 64, 64, - 128, 5, 5, 5, 6, 0, 0, 24, 96, 128, 96, 24, 5, 3, 3, 6, - 0, 1, 248, 0, 248, 5, 5, 5, 6, 0, 0, 192, 48, 8, 48, 192, - 4, 7, 7, 6, 1, 0, 96, 144, 16, 96, 64, 0, 64, 5, 6, 6, - 6, 0, 0, 112, 144, 168, 176, 128, 112, 5, 6, 6, 6, 0, 0, 32, - 80, 136, 248, 136, 136, 5, 6, 6, 6, 0, 0, 240, 136, 240, 136, 136, - 240, 4, 6, 6, 6, 1, 0, 96, 144, 128, 128, 144, 96, 4, 6, 6, - 6, 1, 0, 224, 144, 144, 144, 144, 224, 4, 6, 6, 6, 1, 0, 240, - 128, 224, 128, 128, 240, 4, 6, 6, 6, 1, 0, 240, 128, 224, 128, 128, - 128, 4, 6, 6, 6, 1, 0, 96, 144, 128, 176, 144, 96, 4, 6, 6, - 6, 1, 0, 144, 144, 240, 144, 144, 144, 3, 6, 6, 6, 1, 0, 224, - 64, 64, 64, 64, 224, 5, 6, 6, 6, 0, 0, 56, 16, 16, 16, 144, - 96, 4, 6, 6, 6, 1, 0, 144, 160, 192, 160, 144, 144, 4, 6, 6, - 6, 1, 0, 128, 128, 128, 128, 128, 240, 5, 6, 6, 6, 0, 0, 136, - 216, 168, 168, 136, 136, 4, 6, 6, 6, 1, 0, 144, 208, 176, 144, 144, - 144, 5, 6, 6, 6, 0, 0, 112, 136, 136, 136, 136, 112, 4, 6, 6, - 6, 1, 0, 224, 144, 144, 224, 128, 128, 4, 7, 7, 6, 1, 255, 96, - 144, 144, 208, 176, 96, 16, 4, 6, 6, 6, 1, 0, 224, 144, 144, 224, - 144, 144, 4, 6, 6, 6, 1, 0, 96, 144, 64, 32, 144, 96, 5, 6, - 6, 6, 0, 0, 248, 32, 32, 32, 32, 32, 4, 6, 6, 6, 1, 0, - 144, 144, 144, 144, 144, 96, 4, 6, 6, 6, 1, 0, 144, 144, 144, 240, - 96, 96, 5, 6, 6, 6, 0, 0, 136, 136, 168, 168, 216, 136, 5, 6, - 6, 6, 0, 0, 136, 80, 32, 32, 80, 136, 5, 6, 6, 6, 0, 0, - 136, 136, 80, 32, 32, 32, 4, 6, 6, 6, 1, 0, 240, 16, 32, 64, - 128, 240, 3, 6, 6, 6, 1, 0, 224, 128, 128, 128, 128, 224, 4, 6, - 6, 6, 1, 0, 128, 128, 64, 32, 16, 16, 3, 6, 6, 6, 1, 0, - 224, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 3, 32, 80, 136, 5, - 1, 1, 6, 0, 254, 248, 2, 2, 2, 6, 2, 4, 128, 64, 4, 4, - 4, 6, 1, 0, 112, 144, 144, 112, 4, 6, 6, 6, 1, 0, 128, 128, - 224, 144, 144, 224, 4, 4, 4, 6, 1, 0, 112, 128, 128, 112, 4, 6, - 6, 6, 1, 0, 16, 16, 112, 144, 144, 112, 4, 4, 4, 6, 1, 0, - 96, 176, 192, 112, 4, 6, 6, 6, 1, 0, 32, 80, 64, 224, 64, 64, - 4, 6, 6, 6, 1, 254, 96, 144, 144, 112, 16, 96, 4, 6, 6, 6, - 1, 0, 128, 128, 224, 144, 144, 144, 3, 6, 6, 6, 1, 0, 64, 0, - 192, 64, 64, 224, 3, 8, 8, 6, 1, 254, 32, 0, 96, 32, 32, 32, - 160, 64, 4, 6, 6, 6, 1, 0, 128, 128, 160, 192, 160, 144, 3, 6, - 6, 6, 1, 0, 192, 64, 64, 64, 64, 224, 5, 4, 4, 6, 0, 0, - 208, 168, 168, 136, 4, 4, 4, 6, 1, 0, 224, 144, 144, 144, 4, 4, - 4, 6, 1, 0, 96, 144, 144, 96, 4, 6, 6, 6, 1, 254, 224, 144, - 144, 224, 128, 128, 4, 6, 6, 6, 1, 254, 112, 144, 144, 112, 16, 16, - 4, 4, 4, 6, 1, 0, 160, 208, 128, 128, 4, 4, 4, 6, 1, 0, - 112, 192, 48, 224, 4, 6, 6, 6, 1, 0, 64, 64, 224, 64, 80, 32, - 4, 4, 4, 6, 1, 0, 144, 144, 144, 112, 4, 4, 4, 6, 1, 0, - 144, 144, 96, 96, 5, 4, 4, 6, 0, 0, 136, 168, 168, 80, 4, 4, - 4, 6, 1, 0, 144, 96, 96, 144, 4, 6, 6, 6, 1, 254, 144, 144, - 144, 112, 144, 96, 4, 4, 4, 6, 1, 0, 240, 32, 64, 240, 3, 7, - 7, 6, 1, 0, 32, 64, 64, 128, 64, 64, 32, 1, 7, 7, 6, 2, - 255, 128, 128, 128, 128, 128, 128, 128, 3, 7, 7, 6, 1, 0, 128, 64, - 64, 32, 64, 64, 128, 4, 2, 2, 6, 1, 3, 80, 160, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, - 0, 6, 0, 7, 1, 6, 6, 6, 2, 0, 128, 0, 128, 128, 128, 128, - 4, 6, 6, 6, 1, 255, 32, 112, 160, 160, 112, 32, 5, 7, 7, 6, - 0, 255, 48, 72, 64, 240, 64, 64, 248, 5, 5, 5, 6, 0, 0, 168, - 80, 136, 80, 168, 5, 6, 6, 6, 0, 0, 136, 80, 248, 32, 248, 32, - 1, 7, 7, 6, 2, 255, 128, 128, 128, 0, 128, 128, 128, 4, 7, 7, - 6, 1, 255, 112, 128, 96, 144, 96, 16, 224, 3, 1, 1, 6, 1, 5, - 160, 6, 7, 7, 6, 0, 0, 120, 132, 148, 164, 148, 132, 120, 3, 5, - 5, 6, 1, 1, 96, 160, 96, 0, 224, 5, 5, 5, 6, 0, 0, 40, - 80, 160, 80, 40, 4, 3, 3, 6, 1, 0, 240, 16, 16, 4, 1, 1, - 6, 1, 2, 240, 6, 7, 7, 6, 0, 0, 120, 132, 180, 164, 164, 132, - 120, 4, 1, 1, 6, 1, 5, 240, 4, 3, 3, 6, 1, 2, 96, 144, - 96, 5, 7, 7, 6, 0, 255, 32, 32, 248, 32, 32, 0, 248, 3, 5, - 5, 6, 1, 1, 64, 160, 32, 64, 224, 3, 5, 5, 6, 1, 1, 192, - 32, 64, 32, 192, 2, 2, 2, 6, 2, 4, 64, 128, 4, 5, 5, 6, - 1, 255, 144, 144, 176, 208, 128, 5, 6, 6, 6, 0, 0, 120, 232, 232, - 104, 40, 40, 1, 1, 1, 6, 2, 2, 128, 2, 2, 2, 6, 2, 254, - 64, 128, 3, 5, 5, 6, 1, 1, 64, 192, 64, 64, 224, 3, 5, 5, - 6, 1, 1, 64, 160, 64, 0, 224, 5, 5, 5, 6, 0, 0, 160, 80, - 40, 80, 160, 5, 8, 8, 6, 0, 255, 64, 192, 64, 80, 112, 48, 120, - 16, 5, 8, 8, 6, 0, 255, 64, 192, 64, 80, 104, 8, 16, 56, 5, - 8, 8, 6, 0, 255, 192, 32, 64, 48, 240, 48, 120, 16, 4, 7, 7, - 6, 1, 0, 32, 0, 32, 96, 128, 144, 96, 5, 7, 7, 6, 0, 0, - 64, 32, 32, 80, 112, 136, 136, 5, 7, 7, 6, 0, 0, 16, 32, 32, - 80, 112, 136, 136, 5, 7, 7, 6, 0, 0, 32, 80, 32, 80, 112, 136, - 136, 5, 7, 7, 6, 0, 0, 40, 80, 32, 80, 112, 136, 136, 5, 7, - 7, 6, 0, 0, 80, 0, 32, 80, 112, 136, 136, 5, 7, 7, 6, 0, - 0, 32, 80, 32, 80, 112, 136, 136, 5, 6, 6, 6, 0, 0, 120, 160, - 240, 160, 160, 184, 4, 8, 8, 6, 1, 254, 96, 144, 128, 128, 144, 96, - 32, 64, 4, 7, 7, 6, 1, 0, 64, 32, 240, 128, 224, 128, 240, 4, - 7, 7, 6, 1, 0, 32, 64, 240, 128, 224, 128, 240, 4, 7, 7, 6, - 1, 0, 32, 80, 240, 128, 224, 128, 240, 4, 7, 7, 6, 1, 0, 80, - 0, 240, 128, 224, 128, 240, 3, 7, 7, 6, 1, 0, 128, 64, 224, 64, - 64, 64, 224, 3, 7, 7, 6, 1, 0, 32, 64, 224, 64, 64, 64, 224, - 3, 7, 7, 6, 1, 0, 64, 160, 224, 64, 64, 64, 224, 3, 7, 7, - 6, 1, 0, 160, 0, 224, 64, 64, 64, 224, 5, 6, 6, 6, 0, 0, - 112, 72, 232, 72, 72, 112, 4, 7, 7, 6, 1, 0, 80, 160, 144, 208, - 176, 144, 144, 4, 7, 7, 6, 1, 0, 64, 32, 96, 144, 144, 144, 96, - 4, 7, 7, 6, 1, 0, 32, 64, 96, 144, 144, 144, 96, 4, 7, 7, - 6, 1, 0, 32, 80, 96, 144, 144, 144, 96, 4, 7, 7, 6, 1, 0, - 80, 160, 96, 144, 144, 144, 96, 4, 7, 7, 6, 1, 0, 80, 0, 96, - 144, 144, 144, 96, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136, 4, - 8, 8, 6, 1, 255, 16, 112, 176, 176, 208, 208, 224, 128, 4, 7, 7, - 6, 1, 0, 64, 32, 144, 144, 144, 144, 96, 4, 7, 7, 6, 1, 0, - 32, 64, 144, 144, 144, 144, 96, 4, 7, 7, 6, 1, 0, 32, 80, 144, - 144, 144, 144, 96, 4, 7, 7, 6, 1, 0, 80, 0, 144, 144, 144, 144, - 96, 5, 7, 7, 6, 0, 0, 16, 32, 136, 80, 32, 32, 32, 4, 6, - 6, 6, 1, 0, 128, 224, 144, 144, 224, 128, 4, 6, 6, 6, 1, 0, - 96, 144, 160, 160, 144, 160, 4, 7, 7, 6, 1, 0, 64, 32, 0, 112, - 144, 144, 112, 4, 7, 7, 6, 1, 0, 32, 64, 0, 112, 144, 144, 112, - 4, 7, 7, 6, 1, 0, 32, 80, 0, 112, 144, 144, 112, 4, 7, 7, - 6, 1, 0, 80, 160, 0, 112, 144, 144, 112, 4, 6, 6, 6, 1, 0, - 80, 0, 112, 144, 144, 112, 4, 7, 7, 6, 1, 0, 32, 80, 32, 112, - 144, 144, 112, 5, 4, 4, 6, 0, 0, 112, 168, 176, 120, 4, 6, 6, - 6, 1, 254, 112, 128, 128, 112, 32, 64, 4, 7, 7, 6, 1, 0, 64, - 32, 0, 96, 176, 192, 112, 4, 7, 7, 6, 1, 0, 32, 64, 0, 96, - 176, 192, 112, 4, 7, 7, 6, 1, 0, 32, 80, 0, 96, 176, 192, 112, - 4, 6, 6, 6, 1, 0, 80, 0, 96, 176, 192, 112, 3, 7, 7, 6, - 1, 0, 128, 64, 0, 192, 64, 64, 224, 3, 7, 7, 6, 1, 0, 32, - 64, 0, 192, 64, 64, 224, 3, 7, 7, 6, 1, 0, 64, 160, 0, 192, - 64, 64, 224, 3, 6, 6, 6, 1, 0, 160, 0, 192, 64, 64, 224, 4, - 7, 7, 6, 1, 0, 48, 96, 16, 112, 144, 144, 96, 4, 7, 7, 6, - 1, 0, 80, 160, 0, 224, 144, 144, 144, 4, 7, 7, 6, 1, 0, 64, - 32, 0, 96, 144, 144, 96, 4, 7, 7, 6, 1, 0, 32, 64, 0, 96, - 144, 144, 96, 4, 7, 7, 6, 1, 0, 32, 80, 0, 96, 144, 144, 96, - 4, 7, 7, 6, 1, 0, 80, 160, 0, 96, 144, 144, 96, 4, 6, 6, - 6, 1, 0, 80, 0, 96, 144, 144, 96, 5, 5, 5, 6, 0, 0, 32, - 0, 248, 0, 32, 4, 4, 4, 6, 1, 0, 112, 176, 208, 224, 4, 7, - 7, 6, 1, 0, 64, 32, 0, 144, 144, 144, 112, 4, 7, 7, 6, 1, - 0, 32, 64, 0, 144, 144, 144, 112, 4, 7, 7, 6, 1, 0, 32, 80, - 0, 144, 144, 144, 112, 4, 6, 6, 6, 1, 0, 80, 0, 144, 144, 144, - 112, 4, 9, 9, 6, 1, 254, 32, 64, 0, 144, 144, 144, 112, 144, 96, - 4, 8, 8, 6, 1, 254, 128, 128, 224, 144, 144, 224, 128, 128, 4, 8, - 8, 6, 1, 254, 80, 0, 144, 144, 144, 112, 144, 96 -}; +const u8g_fntpgm_uint8_t u8g_font_6x9[2434] U8G_FONT_SECTION(".progmem.u8g_font_6x9") = { + 0x00,0x06,0x09,0x00,0xFE,0x06,0x02,0x0F,0x03,0x84,0x01,0xFF,0xFE,0x07,0xFE,0x06, + 0xFE,0x05,0x07,0x07,0x00,0x00,0x00,0x40,0xF0,0xC8,0x88,0x98,0x78,0x10,0x05,0x07, + 0x07,0x00,0x00,0x00,0xC0,0xF8,0x88,0x88,0x88,0x88,0xF8,0x05,0x05,0x05,0x00,0x00, + 0x01,0x20,0x30,0xF8,0x30,0x20,0x05,0x07,0x07,0x00,0x00,0x00,0x20,0x70,0xF8,0x20, + 0x20,0x20,0xE0,0x05,0x07,0x07,0x00,0x00,0x00,0x20,0x70,0xA8,0xB8,0x88,0x70,0x20, + 0x06,0x05,0x05,0x00,0x00,0x00,0xB0,0xD8,0x6C,0xD8,0xB0,0x05,0x08,0x08,0x00,0x00, + 0xFF,0xF8,0xA8,0x88,0x88,0x88,0x88,0xA8,0xF8,0x05,0x09,0x09,0x00,0x00,0xFE,0x20, + 0x50,0x50,0x50,0x50,0x88,0xA8,0x88,0x70,0x03,0x03,0x03,0x00,0x00,0x03,0x40,0xA0, + 0x40,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x06,0x05,0xFF,0x01,0x06,0x06, + 0x06,0x02,0x00,0x80,0x80,0x80,0x80,0x00,0x80,0x03,0x03,0x03,0x06,0x01,0x03,0xA0, + 0xA0,0xA0,0x05,0x07,0x07,0x06,0x00,0xFF,0x50,0x50,0xF8,0x50,0xF8,0x50,0x50,0x05, + 0x09,0x09,0x06,0x00,0xFE,0x20,0x70,0xA8,0xA0,0x70,0x28,0xA8,0x70,0x20,0x06,0x08, + 0x08,0x06,0x00,0xFF,0x40,0xA8,0x48,0x10,0x20,0x48,0x54,0x08,0x05,0x07,0x07,0x06, + 0x00,0xFF,0x60,0x90,0x90,0x60,0x98,0x90,0x68,0x01,0x03,0x03,0x06,0x02,0x03,0x80, + 0x80,0x80,0x02,0x07,0x07,0x06,0x02,0xFF,0x40,0x80,0x80,0x80,0x80,0x80,0x40,0x02, + 0x07,0x07,0x06,0x02,0xFF,0x80,0x40,0x40,0x40,0x40,0x40,0x80,0x05,0x05,0x05,0x06, + 0x00,0x00,0x88,0x50,0xF8,0x50,0x88,0x05,0x05,0x05,0x06,0x00,0x00,0x20,0x20,0xF8, + 0x20,0x20,0x02,0x04,0x04,0x06,0x02,0xFE,0xC0,0x40,0x40,0x80,0x05,0x01,0x01,0x06, + 0x00,0x02,0xF8,0x02,0x02,0x02,0x06,0x02,0x00,0xC0,0xC0,0x04,0x06,0x06,0x06,0x01, + 0x00,0x10,0x10,0x20,0x40,0x80,0x80,0x04,0x06,0x06,0x06,0x01,0x00,0x60,0x90,0x90, + 0x90,0x90,0x60,0x03,0x06,0x06,0x06,0x01,0x00,0x40,0xC0,0x40,0x40,0x40,0xE0,0x04, + 0x06,0x06,0x06,0x01,0x00,0x60,0x90,0x10,0x20,0x40,0xF0,0x04,0x06,0x06,0x06,0x01, + 0x00,0xF0,0x20,0x60,0x10,0x10,0xE0,0x05,0x06,0x06,0x06,0x00,0x00,0x10,0x30,0x50, + 0x90,0xF8,0x10,0x04,0x06,0x06,0x06,0x01,0x00,0xF0,0x80,0xE0,0x10,0x10,0xE0,0x04, + 0x06,0x06,0x06,0x01,0x00,0x60,0x80,0xE0,0x90,0x90,0x60,0x04,0x06,0x06,0x06,0x01, + 0x00,0xF0,0x10,0x10,0x20,0x40,0x40,0x04,0x06,0x06,0x06,0x01,0x00,0x60,0x90,0x60, + 0x90,0x90,0x60,0x04,0x06,0x06,0x06,0x01,0x00,0x60,0x90,0x90,0x70,0x10,0x60,0x02, + 0x05,0x05,0x06,0x02,0x00,0xC0,0xC0,0x00,0xC0,0xC0,0x02,0x07,0x07,0x06,0x02,0xFE, + 0xC0,0xC0,0x00,0xC0,0x40,0x40,0x80,0x05,0x05,0x05,0x06,0x00,0x00,0x18,0x60,0x80, + 0x60,0x18,0x05,0x03,0x03,0x06,0x00,0x01,0xF8,0x00,0xF8,0x05,0x05,0x05,0x06,0x00, + 0x00,0xC0,0x30,0x08,0x30,0xC0,0x04,0x07,0x07,0x06,0x01,0x00,0x60,0x90,0x10,0x60, + 0x40,0x00,0x40,0x05,0x06,0x06,0x06,0x00,0x00,0x70,0x90,0xA8,0xB0,0x80,0x70,0x05, + 0x06,0x06,0x06,0x00,0x00,0x20,0x50,0x88,0xF8,0x88,0x88,0x05,0x06,0x06,0x06,0x00, + 0x00,0xF0,0x88,0xF0,0x88,0x88,0xF0,0x04,0x06,0x06,0x06,0x01,0x00,0x60,0x90,0x80, + 0x80,0x90,0x60,0x04,0x06,0x06,0x06,0x01,0x00,0xE0,0x90,0x90,0x90,0x90,0xE0,0x04, + 0x06,0x06,0x06,0x01,0x00,0xF0,0x80,0xE0,0x80,0x80,0xF0,0x04,0x06,0x06,0x06,0x01, + 0x00,0xF0,0x80,0xE0,0x80,0x80,0x80,0x04,0x06,0x06,0x06,0x01,0x00,0x60,0x90,0x80, + 0xB0,0x90,0x60,0x04,0x06,0x06,0x06,0x01,0x00,0x90,0x90,0xF0,0x90,0x90,0x90,0x03, + 0x06,0x06,0x06,0x01,0x00,0xE0,0x40,0x40,0x40,0x40,0xE0,0x05,0x06,0x06,0x06,0x00, + 0x00,0x38,0x10,0x10,0x10,0x90,0x60,0x04,0x06,0x06,0x06,0x01,0x00,0x90,0xA0,0xC0, + 0xA0,0x90,0x90,0x04,0x06,0x06,0x06,0x01,0x00,0x80,0x80,0x80,0x80,0x80,0xF0,0x05, + 0x06,0x06,0x06,0x00,0x00,0x88,0xD8,0xA8,0xA8,0x88,0x88,0x04,0x06,0x06,0x06,0x01, + 0x00,0x90,0xD0,0xB0,0x90,0x90,0x90,0x05,0x06,0x06,0x06,0x00,0x00,0x70,0x88,0x88, + 0x88,0x88,0x70,0x04,0x06,0x06,0x06,0x01,0x00,0xE0,0x90,0x90,0xE0,0x80,0x80,0x04, + 0x07,0x07,0x06,0x01,0xFF,0x60,0x90,0x90,0xD0,0xB0,0x60,0x10,0x04,0x06,0x06,0x06, + 0x01,0x00,0xE0,0x90,0x90,0xE0,0x90,0x90,0x04,0x06,0x06,0x06,0x01,0x00,0x60,0x90, + 0x40,0x20,0x90,0x60,0x05,0x06,0x06,0x06,0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x20, + 0x04,0x06,0x06,0x06,0x01,0x00,0x90,0x90,0x90,0x90,0x90,0x60,0x04,0x06,0x06,0x06, + 0x01,0x00,0x90,0x90,0x90,0xF0,0x60,0x60,0x05,0x06,0x06,0x06,0x00,0x00,0x88,0x88, + 0xA8,0xA8,0xD8,0x88,0x05,0x06,0x06,0x06,0x00,0x00,0x88,0x50,0x20,0x20,0x50,0x88, + 0x05,0x06,0x06,0x06,0x00,0x00,0x88,0x88,0x50,0x20,0x20,0x20,0x04,0x06,0x06,0x06, + 0x01,0x00,0xF0,0x10,0x20,0x40,0x80,0xF0,0x03,0x06,0x06,0x06,0x01,0x00,0xE0,0x80, + 0x80,0x80,0x80,0xE0,0x04,0x06,0x06,0x06,0x01,0x00,0x80,0x80,0x40,0x20,0x10,0x10, + 0x03,0x06,0x06,0x06,0x01,0x00,0xE0,0x20,0x20,0x20,0x20,0xE0,0x05,0x03,0x03,0x06, + 0x00,0x03,0x20,0x50,0x88,0x05,0x01,0x01,0x06,0x00,0xFE,0xF8,0x02,0x02,0x02,0x06, + 0x02,0x04,0x80,0x40,0x04,0x04,0x04,0x06,0x01,0x00,0x70,0x90,0x90,0x70,0x04,0x06, + 0x06,0x06,0x01,0x00,0x80,0x80,0xE0,0x90,0x90,0xE0,0x04,0x04,0x04,0x06,0x01,0x00, + 0x70,0x80,0x80,0x70,0x04,0x06,0x06,0x06,0x01,0x00,0x10,0x10,0x70,0x90,0x90,0x70, + 0x04,0x04,0x04,0x06,0x01,0x00,0x60,0xB0,0xC0,0x70,0x04,0x06,0x06,0x06,0x01,0x00, + 0x20,0x50,0x40,0xE0,0x40,0x40,0x04,0x06,0x06,0x06,0x01,0xFE,0x60,0x90,0x90,0x70, + 0x10,0x60,0x04,0x06,0x06,0x06,0x01,0x00,0x80,0x80,0xE0,0x90,0x90,0x90,0x03,0x06, + 0x06,0x06,0x01,0x00,0x40,0x00,0xC0,0x40,0x40,0xE0,0x03,0x08,0x08,0x06,0x01,0xFE, + 0x20,0x00,0x60,0x20,0x20,0x20,0xA0,0x40,0x04,0x06,0x06,0x06,0x01,0x00,0x80,0x80, + 0xA0,0xC0,0xA0,0x90,0x03,0x06,0x06,0x06,0x01,0x00,0xC0,0x40,0x40,0x40,0x40,0xE0, + 0x05,0x04,0x04,0x06,0x00,0x00,0xD0,0xA8,0xA8,0x88,0x04,0x04,0x04,0x06,0x01,0x00, + 0xE0,0x90,0x90,0x90,0x04,0x04,0x04,0x06,0x01,0x00,0x60,0x90,0x90,0x60,0x04,0x06, + 0x06,0x06,0x01,0xFE,0xE0,0x90,0x90,0xE0,0x80,0x80,0x04,0x06,0x06,0x06,0x01,0xFE, + 0x70,0x90,0x90,0x70,0x10,0x10,0x04,0x04,0x04,0x06,0x01,0x00,0xA0,0xD0,0x80,0x80, + 0x04,0x04,0x04,0x06,0x01,0x00,0x70,0xC0,0x30,0xE0,0x04,0x06,0x06,0x06,0x01,0x00, + 0x40,0x40,0xE0,0x40,0x50,0x20,0x04,0x04,0x04,0x06,0x01,0x00,0x90,0x90,0x90,0x70, + 0x04,0x04,0x04,0x06,0x01,0x00,0x90,0x90,0x60,0x60,0x05,0x04,0x04,0x06,0x00,0x00, + 0x88,0xA8,0xA8,0x50,0x04,0x04,0x04,0x06,0x01,0x00,0x90,0x60,0x60,0x90,0x04,0x06, + 0x06,0x06,0x01,0xFE,0x90,0x90,0x90,0x70,0x90,0x60,0x04,0x04,0x04,0x06,0x01,0x00, + 0xF0,0x20,0x40,0xF0,0x03,0x07,0x07,0x06,0x01,0x00,0x20,0x40,0x40,0x80,0x40,0x40, + 0x20,0x01,0x07,0x07,0x06,0x02,0xFF,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x03,0x07, + 0x07,0x06,0x01,0x00,0x80,0x40,0x40,0x20,0x40,0x40,0x80,0x04,0x02,0x02,0x06,0x01, + 0x03,0x50,0xA0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x06,0x05,0xFF,0x01,0x06,0x06,0x06,0x02,0x00, + 0x80,0x00,0x80,0x80,0x80,0x80,0x04,0x06,0x06,0x06,0x01,0xFF,0x20,0x70,0xA0,0xA0, + 0x70,0x20,0x05,0x07,0x07,0x06,0x00,0xFF,0x30,0x48,0x40,0xF0,0x40,0x40,0xF8,0x05, + 0x05,0x05,0x06,0x00,0x00,0xA8,0x50,0x88,0x50,0xA8,0x05,0x06,0x06,0x06,0x00,0x00, + 0x88,0x50,0xF8,0x20,0xF8,0x20,0x01,0x07,0x07,0x06,0x02,0xFF,0x80,0x80,0x80,0x00, + 0x80,0x80,0x80,0x04,0x07,0x07,0x06,0x01,0xFF,0x70,0x80,0x60,0x90,0x60,0x10,0xE0, + 0x03,0x01,0x01,0x06,0x01,0x05,0xA0,0x06,0x07,0x07,0x06,0x00,0x00,0x78,0x84,0x94, + 0xA4,0x94,0x84,0x78,0x03,0x05,0x05,0x06,0x01,0x01,0x60,0xA0,0x60,0x00,0xE0,0x05, + 0x05,0x05,0x06,0x00,0x00,0x28,0x50,0xA0,0x50,0x28,0x04,0x03,0x03,0x06,0x01,0x00, + 0xF0,0x10,0x10,0x04,0x01,0x01,0x06,0x01,0x02,0xF0,0x06,0x07,0x07,0x06,0x00,0x00, + 0x78,0x84,0xB4,0xA4,0xA4,0x84,0x78,0x04,0x01,0x01,0x06,0x01,0x05,0xF0,0x04,0x03, + 0x03,0x06,0x01,0x02,0x60,0x90,0x60,0x05,0x07,0x07,0x06,0x00,0xFF,0x20,0x20,0xF8, + 0x20,0x20,0x00,0xF8,0x03,0x05,0x05,0x06,0x01,0x01,0x40,0xA0,0x20,0x40,0xE0,0x03, + 0x05,0x05,0x06,0x01,0x01,0xC0,0x20,0x40,0x20,0xC0,0x02,0x02,0x02,0x06,0x02,0x04, + 0x40,0x80,0x04,0x05,0x05,0x06,0x01,0xFF,0x90,0x90,0xB0,0xD0,0x80,0x05,0x06,0x06, + 0x06,0x00,0x00,0x78,0xE8,0xE8,0x68,0x28,0x28,0x01,0x01,0x01,0x06,0x02,0x02,0x80, + 0x02,0x02,0x02,0x06,0x02,0xFE,0x40,0x80,0x03,0x05,0x05,0x06,0x01,0x01,0x40,0xC0, + 0x40,0x40,0xE0,0x03,0x05,0x05,0x06,0x01,0x01,0x40,0xA0,0x40,0x00,0xE0,0x05,0x05, + 0x05,0x06,0x00,0x00,0xA0,0x50,0x28,0x50,0xA0,0x05,0x08,0x08,0x06,0x00,0xFF,0x40, + 0xC0,0x40,0x50,0x70,0x30,0x78,0x10,0x05,0x08,0x08,0x06,0x00,0xFF,0x40,0xC0,0x40, + 0x50,0x68,0x08,0x10,0x38,0x05,0x08,0x08,0x06,0x00,0xFF,0xC0,0x20,0x40,0x30,0xF0, + 0x30,0x78,0x10,0x04,0x07,0x07,0x06,0x01,0x00,0x20,0x00,0x20,0x60,0x80,0x90,0x60, + 0x05,0x07,0x07,0x06,0x00,0x00,0x40,0x20,0x20,0x50,0x70,0x88,0x88,0x05,0x07,0x07, + 0x06,0x00,0x00,0x10,0x20,0x20,0x50,0x70,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00, + 0x20,0x50,0x20,0x50,0x70,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x28,0x50,0x20, + 0x50,0x70,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x50,0x00,0x20,0x50,0x70,0x88, + 0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x50,0x20,0x50,0x70,0x88,0x88,0x05,0x06, + 0x06,0x06,0x00,0x00,0x78,0xA0,0xF0,0xA0,0xA0,0xB8,0x04,0x08,0x08,0x06,0x01,0xFE, + 0x60,0x90,0x80,0x80,0x90,0x60,0x20,0x40,0x04,0x07,0x07,0x06,0x01,0x00,0x40,0x20, + 0xF0,0x80,0xE0,0x80,0xF0,0x04,0x07,0x07,0x06,0x01,0x00,0x20,0x40,0xF0,0x80,0xE0, + 0x80,0xF0,0x04,0x07,0x07,0x06,0x01,0x00,0x20,0x50,0xF0,0x80,0xE0,0x80,0xF0,0x04, + 0x07,0x07,0x06,0x01,0x00,0x50,0x00,0xF0,0x80,0xE0,0x80,0xF0,0x03,0x07,0x07,0x06, + 0x01,0x00,0x80,0x40,0xE0,0x40,0x40,0x40,0xE0,0x03,0x07,0x07,0x06,0x01,0x00,0x20, + 0x40,0xE0,0x40,0x40,0x40,0xE0,0x03,0x07,0x07,0x06,0x01,0x00,0x40,0xA0,0xE0,0x40, + 0x40,0x40,0xE0,0x03,0x07,0x07,0x06,0x01,0x00,0xA0,0x00,0xE0,0x40,0x40,0x40,0xE0, + 0x05,0x06,0x06,0x06,0x00,0x00,0x70,0x48,0xE8,0x48,0x48,0x70,0x04,0x07,0x07,0x06, + 0x01,0x00,0x50,0xA0,0x90,0xD0,0xB0,0x90,0x90,0x04,0x07,0x07,0x06,0x01,0x00,0x40, + 0x20,0x60,0x90,0x90,0x90,0x60,0x04,0x07,0x07,0x06,0x01,0x00,0x20,0x40,0x60,0x90, + 0x90,0x90,0x60,0x04,0x07,0x07,0x06,0x01,0x00,0x20,0x50,0x60,0x90,0x90,0x90,0x60, + 0x04,0x07,0x07,0x06,0x01,0x00,0x50,0xA0,0x60,0x90,0x90,0x90,0x60,0x04,0x07,0x07, + 0x06,0x01,0x00,0x50,0x00,0x60,0x90,0x90,0x90,0x60,0x05,0x05,0x05,0x06,0x00,0x00, + 0x88,0x50,0x20,0x50,0x88,0x04,0x08,0x08,0x06,0x01,0xFF,0x10,0x70,0xB0,0xB0,0xD0, + 0xD0,0xE0,0x80,0x04,0x07,0x07,0x06,0x01,0x00,0x40,0x20,0x90,0x90,0x90,0x90,0x60, + 0x04,0x07,0x07,0x06,0x01,0x00,0x20,0x40,0x90,0x90,0x90,0x90,0x60,0x04,0x07,0x07, + 0x06,0x01,0x00,0x20,0x50,0x90,0x90,0x90,0x90,0x60,0x04,0x07,0x07,0x06,0x01,0x00, + 0x50,0x00,0x90,0x90,0x90,0x90,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x10,0x20,0x88, + 0x50,0x20,0x20,0x20,0x04,0x06,0x06,0x06,0x01,0x00,0x80,0xE0,0x90,0x90,0xE0,0x80, + 0x04,0x06,0x06,0x06,0x01,0x00,0x60,0x90,0xA0,0xA0,0x90,0xA0,0x04,0x07,0x07,0x06, + 0x01,0x00,0x40,0x20,0x00,0x70,0x90,0x90,0x70,0x04,0x07,0x07,0x06,0x01,0x00,0x20, + 0x40,0x00,0x70,0x90,0x90,0x70,0x04,0x07,0x07,0x06,0x01,0x00,0x20,0x50,0x00,0x70, + 0x90,0x90,0x70,0x04,0x07,0x07,0x06,0x01,0x00,0x50,0xA0,0x00,0x70,0x90,0x90,0x70, + 0x04,0x06,0x06,0x06,0x01,0x00,0x50,0x00,0x70,0x90,0x90,0x70,0x04,0x07,0x07,0x06, + 0x01,0x00,0x20,0x50,0x20,0x70,0x90,0x90,0x70,0x05,0x04,0x04,0x06,0x00,0x00,0x70, + 0xA8,0xB0,0x78,0x04,0x06,0x06,0x06,0x01,0xFE,0x70,0x80,0x80,0x70,0x20,0x40,0x04, + 0x07,0x07,0x06,0x01,0x00,0x40,0x20,0x00,0x60,0xB0,0xC0,0x70,0x04,0x07,0x07,0x06, + 0x01,0x00,0x20,0x40,0x00,0x60,0xB0,0xC0,0x70,0x04,0x07,0x07,0x06,0x01,0x00,0x20, + 0x50,0x00,0x60,0xB0,0xC0,0x70,0x04,0x06,0x06,0x06,0x01,0x00,0x50,0x00,0x60,0xB0, + 0xC0,0x70,0x03,0x07,0x07,0x06,0x01,0x00,0x80,0x40,0x00,0xC0,0x40,0x40,0xE0,0x03, + 0x07,0x07,0x06,0x01,0x00,0x20,0x40,0x00,0xC0,0x40,0x40,0xE0,0x03,0x07,0x07,0x06, + 0x01,0x00,0x40,0xA0,0x00,0xC0,0x40,0x40,0xE0,0x03,0x06,0x06,0x06,0x01,0x00,0xA0, + 0x00,0xC0,0x40,0x40,0xE0,0x04,0x07,0x07,0x06,0x01,0x00,0x30,0x60,0x10,0x70,0x90, + 0x90,0x60,0x04,0x07,0x07,0x06,0x01,0x00,0x50,0xA0,0x00,0xE0,0x90,0x90,0x90,0x04, + 0x07,0x07,0x06,0x01,0x00,0x40,0x20,0x00,0x60,0x90,0x90,0x60,0x04,0x07,0x07,0x06, + 0x01,0x00,0x20,0x40,0x00,0x60,0x90,0x90,0x60,0x04,0x07,0x07,0x06,0x01,0x00,0x20, + 0x50,0x00,0x60,0x90,0x90,0x60,0x04,0x07,0x07,0x06,0x01,0x00,0x50,0xA0,0x00,0x60, + 0x90,0x90,0x60,0x04,0x06,0x06,0x06,0x01,0x00,0x50,0x00,0x60,0x90,0x90,0x60,0x05, + 0x05,0x05,0x06,0x00,0x00,0x20,0x00,0xF8,0x00,0x20,0x04,0x04,0x04,0x06,0x01,0x00, + 0x70,0xB0,0xD0,0xE0,0x04,0x07,0x07,0x06,0x01,0x00,0x40,0x20,0x00,0x90,0x90,0x90, + 0x70,0x04,0x07,0x07,0x06,0x01,0x00,0x20,0x40,0x00,0x90,0x90,0x90,0x70,0x04,0x07, + 0x07,0x06,0x01,0x00,0x20,0x50,0x00,0x90,0x90,0x90,0x70,0x04,0x06,0x06,0x06,0x01, + 0x00,0x50,0x00,0x90,0x90,0x90,0x70,0x04,0x09,0x09,0x06,0x01,0xFE,0x20,0x40,0x00, + 0x90,0x90,0x90,0x70,0x90,0x60,0x04,0x08,0x08,0x06,0x01,0xFE,0x80,0x80,0xE0,0x90, + 0x90,0xE0,0x80,0x80,0x04,0x08,0x08,0x06,0x01,0xFE,0x50,0x00,0x90,0x90,0x90,0x70, + 0x90,0x60}; diff --git a/Marlin/src/lcd/dogm/fontdata/fontdata_ISO10646_1.h b/Marlin/src/lcd/dogm/fontdata/fontdata_ISO10646_1.h index e3087a55dfe5..b4b615da4d0f 100644 --- a/Marlin/src/lcd/dogm/fontdata/fontdata_ISO10646_1.h +++ b/Marlin/src/lcd/dogm/fontdata/fontdata_ISO10646_1.h @@ -13,7 +13,7 @@ * 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 . + * along with this program. If not, see . * */ #include @@ -25,97 +25,97 @@ Fontname: -Marlin6x12-Fixed-Medium-R-SemiCondensed--12-90-100-100-C-111-ISO10646-1 Copyright: Public domain terminal emulator font. Share and enjoy. original font -Misc-Fixed-Medium-R-SemiCondensed--12-110-75-75-C-60-ISO10646-1 Capital A Height: 7, '1' Height: 7 - Calculated Max Values w= 5 h=10 x= 5 y= 5 dx= 6 dy= 0 ascent= 8 len=10 - Font Bounding box w=12 h=13 x= 0 y=-2 + Calculated Max Values w= 7 h=10 x= 5 y= 5 dx= 7 dy= 0 ascent= 8 len=10 + Font Bounding box w=12 h=15 x= 0 y=-2 Calculated Min Values x= 0 y=-2 dx= 0 dy= 0 Pure Font ascent = 7 descent=-2 X Font ascent = 8 descent=-2 Max Font ascent = 8 descent=-2 */ -const u8g_fntpgm_uint8_t ISO10646_1_5x7[1325] U8G_FONT_SECTION("ISO10646_1_5x7") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x07,0x02,0x26,0x03,0xbc,0x01,0x7f,0xfe,0x08,0xfe,0x08, - 0xfe,0x05,0x08,0x08,0x06,0x00,0x00,0x40,0xf0,0xc8,0x88,0x88,0x98,0x78,0x10,0x05, - 0x08,0x08,0x06,0x00,0x00,0xc0,0xf8,0x88,0x88,0x88,0x88,0x88,0xf8,0x05,0x05,0x05, - 0x06,0x00,0x01,0x20,0x30,0xf8,0x30,0x20,0x05,0x08,0x08,0x06,0x00,0x00,0x20,0x70, - 0xf8,0x20,0x20,0x20,0x20,0xe0,0x05,0x09,0x09,0x06,0x00,0xff,0x20,0x70,0xa8,0xa8, - 0xb8,0x88,0x88,0x70,0x20,0x05,0x06,0x06,0x06,0x00,0x01,0xe0,0x8c,0xea,0x8c,0x8a, - 0x0a,0x05,0x09,0x09,0x06,0x00,0xff,0xf8,0xa8,0x88,0x88,0x88,0x88,0x88,0xa8,0xf8, - 0x05,0x0a,0x0a,0x06,0x00,0xfe,0x20,0x50,0x50,0x50,0x50,0x88,0xa8,0xa8,0x88,0x70, - 0x03,0x03,0x03,0x06,0x00,0x03,0x40,0xa0,0x40,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, - 0x00,0x00,0x06,0x05,0xff,0x01,0x07,0x07,0x06,0x02,0x00,0x80,0x80,0x80,0x80,0x80, - 0x00,0x80,0x03,0x03,0x03,0x06,0x01,0x05,0xa0,0xa0,0xa0,0x05,0x06,0x06,0x06,0x00, - 0x00,0x50,0xf8,0x50,0x50,0xf8,0x50,0x05,0x09,0x09,0x06,0x00,0xff,0x20,0x70,0xa8, - 0xa0,0x70,0x28,0xa8,0x70,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0xc8,0xc8,0x10,0x20, - 0x40,0x98,0x98,0x05,0x07,0x07,0x06,0x00,0x00,0x40,0xa0,0xa0,0x40,0xa8,0x90,0x68, - 0x01,0x03,0x03,0x06,0x02,0x05,0x80,0x80,0x80,0x03,0x09,0x09,0x06,0x01,0xff,0x20, - 0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x20,0x03,0x09,0x09,0x06,0x01,0xff,0x80,0x40, - 0x40,0x20,0x20,0x20,0x40,0x40,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0xa8,0x70, - 0x20,0x70,0xa8,0x20,0x05,0x05,0x05,0x06,0x00,0x01,0x20,0x20,0xf8,0x20,0x20,0x02, - 0x03,0x03,0x06,0x01,0xff,0xc0,0x40,0x80,0x05,0x01,0x01,0x06,0x00,0x03,0xf8,0x02, - 0x02,0x02,0x06,0x01,0x00,0xc0,0xc0,0x05,0x07,0x07,0x06,0x00,0x00,0x08,0x10,0x10, - 0x20,0x40,0x40,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x98,0xa8,0xc8,0x88, - 0x70,0x03,0x07,0x07,0x06,0x01,0x00,0x40,0xc0,0x40,0x40,0x40,0x40,0xe0,0x05,0x07, - 0x07,0x06,0x00,0x00,0x70,0x88,0x08,0x10,0x20,0x40,0xf8,0x05,0x07,0x07,0x06,0x00, - 0x00,0xf8,0x08,0x10,0x30,0x08,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x10,0x30, - 0x50,0x90,0xf8,0x10,0x10,0x05,0x07,0x07,0x06,0x00,0x00,0xf8,0x80,0xf0,0x08,0x08, - 0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x30,0x40,0x80,0xf0,0x88,0x88,0x70,0x05, - 0x07,0x07,0x06,0x00,0x00,0xf8,0x08,0x10,0x10,0x20,0x20,0x20,0x05,0x07,0x07,0x06, - 0x00,0x00,0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x70, - 0x88,0x88,0x78,0x08,0x10,0x60,0x02,0x05,0x05,0x06,0x01,0x00,0xc0,0xc0,0x00,0xc0, - 0xc0,0x02,0x06,0x06,0x06,0x01,0xff,0xc0,0xc0,0x00,0xc0,0x40,0x80,0x03,0x05,0x05, - 0x06,0x01,0x01,0x20,0x40,0x80,0x40,0x20,0x05,0x03,0x03,0x06,0x00,0x02,0xf8,0x00, - 0xf8,0x03,0x05,0x05,0x06,0x01,0x01,0x80,0x40,0x20,0x40,0x80,0x05,0x07,0x07,0x06, - 0x00,0x00,0x70,0x88,0x10,0x20,0x20,0x00,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x70, - 0x88,0xb8,0xa8,0xb8,0x80,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0xf8, - 0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0xf0,0x48,0x48,0x70,0x48,0x48,0xf0, - 0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x05,0x07,0x07, - 0x06,0x00,0x00,0xf0,0x48,0x48,0x48,0x48,0x48,0xf0,0x05,0x07,0x07,0x06,0x00,0x00, - 0xf8,0x80,0x80,0xf0,0x80,0x80,0xf8,0x05,0x07,0x07,0x06,0x00,0x00,0xf8,0x80,0x80, - 0xf0,0x80,0x80,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x80,0x80,0x98,0x88, - 0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x03,0x07, - 0x07,0x06,0x01,0x00,0xe0,0x40,0x40,0x40,0x40,0x40,0xe0,0x05,0x07,0x07,0x06,0x00, - 0x00,0x38,0x10,0x10,0x10,0x10,0x90,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x90, - 0xa0,0xc0,0xa0,0x90,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x80,0x80,0x80,0x80, - 0x80,0xf8,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0xd8,0xa8,0x88,0x88,0x88,0x88,0x05, - 0x07,0x07,0x06,0x00,0x00,0x88,0x88,0xc8,0xa8,0x98,0x88,0x88,0x05,0x07,0x07,0x06, - 0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0xf0, - 0x88,0x88,0xf0,0x80,0x80,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0x88, - 0xa8,0x90,0x68,0x05,0x07,0x07,0x06,0x00,0x00,0xf0,0x88,0x88,0xf0,0xa0,0x90,0x88, - 0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x05,0x07,0x07, - 0x06,0x00,0x00,0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0x00, - 0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88, - 0x88,0x50,0x50,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0x88,0xa8,0xa8, - 0x50,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x05,0x07, - 0x07,0x06,0x00,0x00,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00, - 0x00,0xf8,0x08,0x10,0x20,0x40,0x80,0xf8,0x03,0x09,0x09,0x06,0x01,0xff,0xe0,0x80, - 0x80,0x80,0x80,0x80,0x80,0x80,0xe0,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x40,0x40, - 0x20,0x10,0x10,0x08,0x03,0x09,0x09,0x06,0x01,0xff,0xe0,0x20,0x20,0x20,0x20,0x20, - 0x20,0x20,0xe0,0x05,0x03,0x03,0x06,0x00,0x05,0x20,0x50,0x88,0x05,0x01,0x01,0x06, - 0x00,0xfe,0xf8,0x03,0x03,0x03,0x06,0x01,0x05,0x80,0x40,0x20,0x05,0x05,0x05,0x06, - 0x00,0x00,0x70,0x08,0x78,0x88,0x78,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x80,0xf0, - 0x88,0x88,0x88,0xf0,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x80,0x80,0x88,0x70,0x05, - 0x07,0x07,0x06,0x00,0x00,0x08,0x08,0x78,0x88,0x88,0x88,0x78,0x05,0x05,0x05,0x06, - 0x00,0x00,0x70,0x88,0xf0,0x80,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x30,0x48,0x40, - 0xe0,0x40,0x40,0x40,0x05,0x07,0x07,0x06,0x00,0xfe,0x70,0x88,0x88,0x88,0x78,0x08, - 0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x80,0xf0,0x88,0x88,0x88,0x88,0x03,0x07, - 0x07,0x06,0x01,0x00,0x40,0x00,0xc0,0x40,0x40,0x40,0xe0,0x04,0x09,0x09,0x06,0x01, - 0xfe,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x90,0x60,0x05,0x07,0x07,0x06,0x00,0x00, - 0x80,0x80,0x88,0x90,0xe0,0x90,0x88,0x03,0x07,0x07,0x06,0x01,0x00,0xc0,0x40,0x40, - 0x40,0x40,0x40,0xe0,0x05,0x05,0x05,0x06,0x00,0x00,0xd0,0xa8,0xa8,0xa8,0xa8,0x05, - 0x05,0x05,0x06,0x00,0x00,0xb0,0xc8,0x88,0x88,0x88,0x05,0x05,0x05,0x06,0x00,0x00, - 0x70,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0xfe,0xf0,0x88,0x88,0x88,0xf0, - 0x80,0x80,0x05,0x07,0x07,0x06,0x00,0xfe,0x78,0x88,0x88,0x88,0x78,0x08,0x08,0x05, - 0x05,0x05,0x06,0x00,0x00,0xb0,0xc8,0x80,0x80,0x80,0x05,0x05,0x05,0x06,0x00,0x00, - 0x78,0x80,0x70,0x08,0xf0,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x20,0xf8,0x20,0x20, - 0x20,0x18,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x88,0x88,0x98,0x68,0x05,0x05,0x05, - 0x06,0x00,0x00,0x88,0x88,0x88,0x50,0x20,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x88, - 0xa8,0xa8,0x50,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x05,0x07, - 0x07,0x06,0x00,0xfe,0x88,0x88,0x88,0x50,0x20,0x40,0x80,0x05,0x05,0x05,0x06,0x00, - 0x00,0xf8,0x10,0x20,0x40,0xf8,0x03,0x09,0x09,0x06,0x01,0xff,0x20,0x40,0x40,0x40, - 0x80,0x40,0x40,0x40,0x20,0x01,0x09,0x09,0x06,0x02,0xff,0x80,0x80,0x80,0x80,0x80, - 0x80,0x80,0x80,0x80,0x03,0x09,0x09,0x06,0x01,0xff,0x80,0x40,0x40,0x40,0x20,0x40, - 0x40,0x40,0x80,0x05,0x03,0x03,0x06,0x00,0x02,0x48,0xa8,0x90,0xff}; +const u8g_fntpgm_uint8_t ISO10646_1_5x7[1324] U8G_FONT_SECTION("ISO10646_1_5x7") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x07,0x02,0x25,0x03,0xBB,0x01,0x7F,0xFE,0x08,0xFE,0x08, + 0xFE,0x05,0x08,0x08,0x06,0x00,0x00,0x40,0xF0,0xC8,0x88,0x88,0x98,0x78,0x10,0x05, + 0x08,0x08,0x06,0x00,0x00,0xC0,0xF8,0x88,0x88,0x88,0x88,0x88,0xF8,0x05,0x05,0x05, + 0x06,0x00,0x01,0x20,0x30,0xF8,0x30,0x20,0x05,0x08,0x08,0x06,0x00,0x00,0x20,0x70, + 0xF8,0x20,0x20,0x20,0x20,0xE0,0x05,0x09,0x09,0x06,0x00,0xFF,0x20,0x70,0xA8,0xA8, + 0xB8,0x88,0x88,0x70,0x20,0x07,0x05,0x05,0x07,0x00,0x01,0xD8,0x6C,0x36,0x6C,0xD8, + 0x05,0x09,0x09,0x06,0x00,0xFF,0xF8,0xA8,0x88,0x88,0x88,0x88,0x88,0xA8,0xF8,0x05, + 0x0A,0x0A,0x06,0x00,0xFE,0x20,0x50,0x50,0x50,0x50,0x88,0xA8,0xA8,0x88,0x70,0x03, + 0x03,0x03,0x06,0x00,0x03,0x40,0xA0,0x40,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00, + 0x00,0x06,0x05,0xFF,0x01,0x07,0x07,0x06,0x02,0x00,0x80,0x80,0x80,0x80,0x80,0x00, + 0x80,0x03,0x03,0x03,0x06,0x01,0x05,0xA0,0xA0,0xA0,0x05,0x06,0x06,0x06,0x00,0x00, + 0x50,0xF8,0x50,0x50,0xF8,0x50,0x05,0x09,0x09,0x06,0x00,0xFF,0x20,0x70,0xA8,0xA0, + 0x70,0x28,0xA8,0x70,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0xC8,0xC8,0x10,0x20,0x40, + 0x98,0x98,0x05,0x07,0x07,0x06,0x00,0x00,0x40,0xA0,0xA0,0x40,0xA8,0x90,0x68,0x01, + 0x03,0x03,0x06,0x02,0x05,0x80,0x80,0x80,0x03,0x09,0x09,0x06,0x01,0xFF,0x20,0x40, + 0x40,0x80,0x80,0x80,0x40,0x40,0x20,0x03,0x09,0x09,0x06,0x01,0xFF,0x80,0x40,0x40, + 0x20,0x20,0x20,0x40,0x40,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0xA8,0x70,0x20, + 0x70,0xA8,0x20,0x05,0x05,0x05,0x06,0x00,0x01,0x20,0x20,0xF8,0x20,0x20,0x02,0x03, + 0x03,0x06,0x01,0xFF,0xC0,0x40,0x80,0x05,0x01,0x01,0x06,0x00,0x03,0xF8,0x02,0x02, + 0x02,0x06,0x01,0x00,0xC0,0xC0,0x05,0x07,0x07,0x06,0x00,0x00,0x08,0x10,0x10,0x20, + 0x40,0x40,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x98,0xA8,0xC8,0x88,0x70, + 0x03,0x07,0x07,0x06,0x01,0x00,0x40,0xC0,0x40,0x40,0x40,0x40,0xE0,0x05,0x07,0x07, + 0x06,0x00,0x00,0x70,0x88,0x08,0x10,0x20,0x40,0xF8,0x05,0x07,0x07,0x06,0x00,0x00, + 0xF8,0x08,0x10,0x30,0x08,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x10,0x30,0x50, + 0x90,0xF8,0x10,0x10,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x80,0xF0,0x08,0x08,0x88, + 0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x30,0x40,0x80,0xF0,0x88,0x88,0x70,0x05,0x07, + 0x07,0x06,0x00,0x00,0xF8,0x08,0x10,0x10,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00, + 0x00,0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88, + 0x88,0x78,0x08,0x10,0x60,0x02,0x05,0x05,0x06,0x01,0x00,0xC0,0xC0,0x00,0xC0,0xC0, + 0x02,0x06,0x06,0x06,0x01,0xFF,0xC0,0xC0,0x00,0xC0,0x40,0x80,0x03,0x05,0x05,0x06, + 0x01,0x01,0x20,0x40,0x80,0x40,0x20,0x05,0x03,0x03,0x06,0x00,0x02,0xF8,0x00,0xF8, + 0x03,0x05,0x05,0x06,0x01,0x01,0x80,0x40,0x20,0x40,0x80,0x05,0x07,0x07,0x06,0x00, + 0x00,0x70,0x88,0x10,0x20,0x20,0x00,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88, + 0xB8,0xA8,0xB8,0x80,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0xF8,0x88, + 0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0xF0,0x48,0x48,0x70,0x48,0x48,0xF0,0x05, + 0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x05,0x07,0x07,0x06, + 0x00,0x00,0xF0,0x48,0x48,0x48,0x48,0x48,0xF0,0x05,0x07,0x07,0x06,0x00,0x00,0xF8, + 0x80,0x80,0xF0,0x80,0x80,0xF8,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x80,0x80,0xF0, + 0x80,0x80,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x80,0x80,0x98,0x88,0x70, + 0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x03,0x07,0x07, + 0x06,0x01,0x00,0xE0,0x40,0x40,0x40,0x40,0x40,0xE0,0x05,0x07,0x07,0x06,0x00,0x00, + 0x38,0x10,0x10,0x10,0x10,0x90,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x90,0xA0, + 0xC0,0xA0,0x90,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80, + 0xF8,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0xD8,0xA8,0x88,0x88,0x88,0x88,0x05,0x07, + 0x07,0x06,0x00,0x00,0x88,0x88,0xC8,0xA8,0x98,0x88,0x88,0x05,0x07,0x07,0x06,0x00, + 0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0xF0,0x88, + 0x88,0xF0,0x80,0x80,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0x88,0xA8, + 0x90,0x68,0x05,0x07,0x07,0x06,0x00,0x00,0xF0,0x88,0x88,0xF0,0xA0,0x90,0x88,0x05, + 0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x05,0x07,0x07,0x06, + 0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x88, + 0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0x88, + 0x50,0x50,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0x88,0xA8,0xA8,0x50, + 0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x05,0x07,0x07, + 0x06,0x00,0x00,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0x00, + 0xF8,0x08,0x10,0x20,0x40,0x80,0xF8,0x03,0x09,0x09,0x06,0x01,0xFF,0xE0,0x80,0x80, + 0x80,0x80,0x80,0x80,0x80,0xE0,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x40,0x40,0x20, + 0x10,0x10,0x08,0x03,0x09,0x09,0x06,0x01,0xFF,0xE0,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0xE0,0x05,0x03,0x03,0x06,0x00,0x05,0x20,0x50,0x88,0x05,0x01,0x01,0x06,0x00, + 0xFE,0xF8,0x03,0x03,0x03,0x06,0x01,0x05,0x80,0x40,0x20,0x05,0x05,0x05,0x06,0x00, + 0x00,0x70,0x08,0x78,0x88,0x78,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x80,0xF0,0x88, + 0x88,0x88,0xF0,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x80,0x80,0x88,0x70,0x05,0x07, + 0x07,0x06,0x00,0x00,0x08,0x08,0x78,0x88,0x88,0x88,0x78,0x05,0x05,0x05,0x06,0x00, + 0x00,0x70,0x88,0xF0,0x80,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x30,0x48,0x40,0xE0, + 0x40,0x40,0x40,0x05,0x07,0x07,0x06,0x00,0xFE,0x70,0x88,0x88,0x88,0x78,0x08,0x70, + 0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x88,0x03,0x07,0x07, + 0x06,0x01,0x00,0x40,0x00,0xC0,0x40,0x40,0x40,0xE0,0x04,0x09,0x09,0x06,0x01,0xFE, + 0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x90,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x80, + 0x80,0x88,0x90,0xE0,0x90,0x88,0x03,0x07,0x07,0x06,0x01,0x00,0xC0,0x40,0x40,0x40, + 0x40,0x40,0xE0,0x05,0x05,0x05,0x06,0x00,0x00,0xD0,0xA8,0xA8,0xA8,0xA8,0x05,0x05, + 0x05,0x06,0x00,0x00,0xB0,0xC8,0x88,0x88,0x88,0x05,0x05,0x05,0x06,0x00,0x00,0x70, + 0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0xFE,0xF0,0x88,0x88,0x88,0xF0,0x80, + 0x80,0x05,0x07,0x07,0x06,0x00,0xFE,0x78,0x88,0x88,0x88,0x78,0x08,0x08,0x05,0x05, + 0x05,0x06,0x00,0x00,0xB0,0xC8,0x80,0x80,0x80,0x05,0x05,0x05,0x06,0x00,0x00,0x78, + 0x80,0x70,0x08,0xF0,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x20, + 0x18,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x88,0x88,0x98,0x68,0x05,0x05,0x05,0x06, + 0x00,0x00,0x88,0x88,0x88,0x50,0x20,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x88,0xA8, + 0xA8,0x50,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x05,0x07,0x07, + 0x06,0x00,0xFE,0x88,0x88,0x88,0x50,0x20,0x40,0x80,0x05,0x05,0x05,0x06,0x00,0x00, + 0xF8,0x10,0x20,0x40,0xF8,0x03,0x09,0x09,0x06,0x01,0xFF,0x20,0x40,0x40,0x40,0x80, + 0x40,0x40,0x40,0x20,0x01,0x09,0x09,0x06,0x02,0xFF,0x80,0x80,0x80,0x80,0x80,0x80, + 0x80,0x80,0x80,0x03,0x09,0x09,0x06,0x01,0xFF,0x80,0x40,0x40,0x40,0x20,0x40,0x40, + 0x40,0x80,0x05,0x03,0x03,0x06,0x00,0x02,0x48,0xA8,0x90,0xFF}; #else // extended (original) font (symbols 1 - 255) @@ -123,179 +123,179 @@ const u8g_fntpgm_uint8_t ISO10646_1_5x7[1325] U8G_FONT_SECTION("ISO10646_1_5x7") Fontname: -Marlin6x12-Fixed-Medium-R-SemiCondensed--12-90-100-100-C-111-ISO10646-1 Copyright: Public domain terminal emulator font. Share and enjoy. original font -Misc-Fixed-Medium-R-SemiCondensed--12-110-75-75-C-60-ISO10646-1 Capital A Height: 7, '1' Height: 7 - Calculated Max Values w= 6 h=10 x= 5 y= 7 dx= 6 dy= 0 ascent=10 len=10 - Font Bounding box w=12 h=13 x= 0 y=-2 + Calculated Max Values w= 7 h=10 x= 5 y= 7 dx= 7 dy= 0 ascent=10 len=10 + Font Bounding box w=12 h=15 x= 0 y=-2 Calculated Min Values x= 0 y=-2 dx= 0 dy= 0 Pure Font ascent = 7 descent=-2 X Font ascent = 8 descent=-2 Max Font ascent =10 descent=-2 */ -const u8g_fntpgm_uint8_t ISO10646_1_5x7[2648] U8G_FONT_SECTION("ISO10646_1_5x7") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x07,0x02,0x26,0x03,0xbc,0x01,0xff,0xfe,0x0a,0xfe,0x08, - 0xfe,0x05,0x08,0x08,0x06,0x00,0x00,0x40,0xf0,0xc8,0x88,0x88,0x98,0x78,0x10,0x05, - 0x08,0x08,0x06,0x00,0x00,0xc0,0xf8,0x88,0x88,0x88,0x88,0x88,0xf8,0x05,0x05,0x05, - 0x06,0x00,0x01,0x20,0x30,0xf8,0x30,0x20,0x05,0x08,0x08,0x06,0x00,0x00,0x20,0x70, - 0xf8,0x20,0x20,0x20,0x20,0xe0,0x05,0x09,0x09,0x06,0x00,0xff,0x20,0x70,0xa8,0xa8, - 0xb8,0x88,0x88,0x70,0x20,0x05,0x06,0x06,0x06,0x00,0x01,0xe0,0x8c,0xea,0x8c,0x8a, - 0x0a,0x05,0x09,0x09,0x06,0x00,0xff,0xf8,0xa8,0x88,0x88,0x88,0x88,0x88,0xa8,0xf8, - 0x05,0x0a,0x0a,0x06,0x00,0xfe,0x20,0x50,0x50,0x50,0x50,0x88,0xa8,0xa8,0x88,0x70, - 0x03,0x03,0x03,0x06,0x00,0x03,0x40,0xa0,0x40,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, - 0x00,0x00,0x06,0x05,0xff,0x01,0x07,0x07,0x06,0x02,0x00,0x80,0x80,0x80,0x80,0x80, - 0x00,0x80,0x03,0x03,0x03,0x06,0x01,0x05,0xa0,0xa0,0xa0,0x05,0x06,0x06,0x06,0x00, - 0x00,0x50,0xf8,0x50,0x50,0xf8,0x50,0x05,0x09,0x09,0x06,0x00,0xff,0x20,0x70,0xa8, - 0xa0,0x70,0x28,0xa8,0x70,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0xc8,0xc8,0x10,0x20, - 0x40,0x98,0x98,0x05,0x07,0x07,0x06,0x00,0x00,0x40,0xa0,0xa0,0x40,0xa8,0x90,0x68, - 0x01,0x03,0x03,0x06,0x02,0x05,0x80,0x80,0x80,0x03,0x09,0x09,0x06,0x01,0xff,0x20, - 0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x20,0x03,0x09,0x09,0x06,0x01,0xff,0x80,0x40, - 0x40,0x20,0x20,0x20,0x40,0x40,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0xa8,0x70, - 0x20,0x70,0xa8,0x20,0x05,0x05,0x05,0x06,0x00,0x01,0x20,0x20,0xf8,0x20,0x20,0x02, - 0x03,0x03,0x06,0x01,0xff,0xc0,0x40,0x80,0x05,0x01,0x01,0x06,0x00,0x03,0xf8,0x02, - 0x02,0x02,0x06,0x01,0x00,0xc0,0xc0,0x05,0x07,0x07,0x06,0x00,0x00,0x08,0x10,0x10, - 0x20,0x40,0x40,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x98,0xa8,0xc8,0x88, - 0x70,0x03,0x07,0x07,0x06,0x01,0x00,0x40,0xc0,0x40,0x40,0x40,0x40,0xe0,0x05,0x07, - 0x07,0x06,0x00,0x00,0x70,0x88,0x08,0x10,0x20,0x40,0xf8,0x05,0x07,0x07,0x06,0x00, - 0x00,0xf8,0x08,0x10,0x30,0x08,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x10,0x30, - 0x50,0x90,0xf8,0x10,0x10,0x05,0x07,0x07,0x06,0x00,0x00,0xf8,0x80,0xf0,0x08,0x08, - 0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x30,0x40,0x80,0xf0,0x88,0x88,0x70,0x05, - 0x07,0x07,0x06,0x00,0x00,0xf8,0x08,0x10,0x10,0x20,0x20,0x20,0x05,0x07,0x07,0x06, - 0x00,0x00,0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x70, - 0x88,0x88,0x78,0x08,0x10,0x60,0x02,0x05,0x05,0x06,0x01,0x00,0xc0,0xc0,0x00,0xc0, - 0xc0,0x02,0x06,0x06,0x06,0x01,0xff,0xc0,0xc0,0x00,0xc0,0x40,0x80,0x03,0x05,0x05, - 0x06,0x01,0x01,0x20,0x40,0x80,0x40,0x20,0x05,0x03,0x03,0x06,0x00,0x02,0xf8,0x00, - 0xf8,0x03,0x05,0x05,0x06,0x01,0x01,0x80,0x40,0x20,0x40,0x80,0x05,0x07,0x07,0x06, - 0x00,0x00,0x70,0x88,0x10,0x20,0x20,0x00,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x70, - 0x88,0xb8,0xa8,0xb8,0x80,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0xf8, - 0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0xf0,0x48,0x48,0x70,0x48,0x48,0xf0, - 0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x05,0x07,0x07, - 0x06,0x00,0x00,0xf0,0x48,0x48,0x48,0x48,0x48,0xf0,0x05,0x07,0x07,0x06,0x00,0x00, - 0xf8,0x80,0x80,0xf0,0x80,0x80,0xf8,0x05,0x07,0x07,0x06,0x00,0x00,0xf8,0x80,0x80, - 0xf0,0x80,0x80,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x80,0x80,0x98,0x88, - 0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x03,0x07, - 0x07,0x06,0x01,0x00,0xe0,0x40,0x40,0x40,0x40,0x40,0xe0,0x05,0x07,0x07,0x06,0x00, - 0x00,0x38,0x10,0x10,0x10,0x10,0x90,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x90, - 0xa0,0xc0,0xa0,0x90,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x80,0x80,0x80,0x80, - 0x80,0xf8,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0xd8,0xa8,0x88,0x88,0x88,0x88,0x05, - 0x07,0x07,0x06,0x00,0x00,0x88,0x88,0xc8,0xa8,0x98,0x88,0x88,0x05,0x07,0x07,0x06, - 0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0xf0, - 0x88,0x88,0xf0,0x80,0x80,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0x88, - 0xa8,0x90,0x68,0x05,0x07,0x07,0x06,0x00,0x00,0xf0,0x88,0x88,0xf0,0xa0,0x90,0x88, - 0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x05,0x07,0x07, - 0x06,0x00,0x00,0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0x00, - 0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88, - 0x88,0x50,0x50,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0x88,0xa8,0xa8, - 0x50,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x05,0x07, - 0x07,0x06,0x00,0x00,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00, - 0x00,0xf8,0x08,0x10,0x20,0x40,0x80,0xf8,0x03,0x09,0x09,0x06,0x01,0xff,0xe0,0x80, - 0x80,0x80,0x80,0x80,0x80,0x80,0xe0,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x40,0x40, - 0x20,0x10,0x10,0x08,0x03,0x09,0x09,0x06,0x01,0xff,0xe0,0x20,0x20,0x20,0x20,0x20, - 0x20,0x20,0xe0,0x05,0x03,0x03,0x06,0x00,0x05,0x20,0x50,0x88,0x05,0x01,0x01,0x06, - 0x00,0xfe,0xf8,0x03,0x03,0x03,0x06,0x01,0x05,0x80,0x40,0x20,0x05,0x05,0x05,0x06, - 0x00,0x00,0x70,0x08,0x78,0x88,0x78,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x80,0xf0, - 0x88,0x88,0x88,0xf0,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x80,0x80,0x88,0x70,0x05, - 0x07,0x07,0x06,0x00,0x00,0x08,0x08,0x78,0x88,0x88,0x88,0x78,0x05,0x05,0x05,0x06, - 0x00,0x00,0x70,0x88,0xf0,0x80,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x30,0x48,0x40, - 0xe0,0x40,0x40,0x40,0x05,0x07,0x07,0x06,0x00,0xfe,0x70,0x88,0x88,0x88,0x78,0x08, - 0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x80,0xf0,0x88,0x88,0x88,0x88,0x03,0x07, - 0x07,0x06,0x01,0x00,0x40,0x00,0xc0,0x40,0x40,0x40,0xe0,0x04,0x09,0x09,0x06,0x01, - 0xfe,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x90,0x60,0x05,0x07,0x07,0x06,0x00,0x00, - 0x80,0x80,0x88,0x90,0xe0,0x90,0x88,0x03,0x07,0x07,0x06,0x01,0x00,0xc0,0x40,0x40, - 0x40,0x40,0x40,0xe0,0x05,0x05,0x05,0x06,0x00,0x00,0xd0,0xa8,0xa8,0xa8,0xa8,0x05, - 0x05,0x05,0x06,0x00,0x00,0xb0,0xc8,0x88,0x88,0x88,0x05,0x05,0x05,0x06,0x00,0x00, - 0x70,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0xfe,0xf0,0x88,0x88,0x88,0xf0, - 0x80,0x80,0x05,0x07,0x07,0x06,0x00,0xfe,0x78,0x88,0x88,0x88,0x78,0x08,0x08,0x05, - 0x05,0x05,0x06,0x00,0x00,0xb0,0xc8,0x80,0x80,0x80,0x05,0x05,0x05,0x06,0x00,0x00, - 0x78,0x80,0x70,0x08,0xf0,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x20,0xf8,0x20,0x20, - 0x20,0x18,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x88,0x88,0x98,0x68,0x05,0x05,0x05, - 0x06,0x00,0x00,0x88,0x88,0x88,0x50,0x20,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x88, - 0xa8,0xa8,0x50,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x05,0x07, - 0x07,0x06,0x00,0xfe,0x88,0x88,0x88,0x50,0x20,0x40,0x80,0x05,0x05,0x05,0x06,0x00, - 0x00,0xf8,0x10,0x20,0x40,0xf8,0x03,0x09,0x09,0x06,0x01,0xff,0x20,0x40,0x40,0x40, - 0x80,0x40,0x40,0x40,0x20,0x01,0x09,0x09,0x06,0x02,0xff,0x80,0x80,0x80,0x80,0x80, - 0x80,0x80,0x80,0x80,0x03,0x09,0x09,0x06,0x01,0xff,0x80,0x40,0x40,0x40,0x20,0x40, - 0x40,0x40,0x80,0x05,0x03,0x03,0x06,0x00,0x02,0x48,0xa8,0x90,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00, - 0x06,0x05,0xff,0x01,0x07,0x07,0x06,0x02,0x00,0x80,0x00,0x80,0x80,0x80,0x80,0x80, - 0x05,0x07,0x07,0x06,0x00,0xff,0x20,0x70,0xa8,0xa0,0xa8,0x70,0x20,0x05,0x07,0x07, - 0x06,0x00,0x00,0x30,0x48,0x40,0xe0,0x40,0x48,0xb0,0x05,0x05,0x05,0x06,0x00,0x00, - 0xa8,0x50,0x88,0x50,0xa8,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x50,0xf8,0x20,0xf8, - 0x20,0x20,0x01,0x07,0x07,0x06,0x02,0x00,0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x04, - 0x08,0x08,0x06,0x01,0x00,0x70,0x80,0x60,0x90,0x90,0x60,0x10,0xe0,0x03,0x01,0x01, - 0x06,0x01,0x07,0xa0,0x06,0x07,0x07,0x06,0x00,0x00,0x78,0x84,0xb4,0xa4,0xb4,0x84, - 0x78,0x03,0x05,0x05,0x06,0x01,0x04,0x60,0xa0,0x60,0x00,0xe0,0x05,0x05,0x05,0x06, - 0x00,0x00,0x28,0x50,0xa0,0x50,0x28,0x05,0x03,0x03,0x06,0x00,0x01,0xf8,0x08,0x08, - 0x03,0x01,0x01,0x06,0x01,0x03,0xe0,0x06,0x07,0x07,0x06,0x00,0x00,0x78,0x84,0xb4, - 0xa4,0xa4,0x84,0x78,0x05,0x01,0x01,0x06,0x00,0x07,0xf8,0x04,0x04,0x04,0x06,0x01, - 0x05,0x60,0x90,0x90,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x20,0xf8,0x20,0x20, - 0x00,0xf8,0x03,0x05,0x05,0x06,0x01,0x04,0x40,0xa0,0x20,0x40,0xe0,0x03,0x05,0x05, - 0x06,0x01,0x04,0xc0,0x20,0x40,0x20,0xc0,0x03,0x03,0x03,0x06,0x01,0x05,0x20,0x40, - 0x80,0x05,0x07,0x07,0x06,0x00,0xfe,0x88,0x88,0x88,0x98,0xe8,0x80,0x80,0x05,0x08, - 0x08,0x06,0x00,0x00,0x78,0xe8,0xe8,0xe8,0x68,0x28,0x28,0x28,0x02,0x02,0x02,0x06, - 0x02,0x03,0xc0,0xc0,0x03,0x02,0x02,0x06,0x01,0xfe,0x20,0xc0,0x03,0x05,0x05,0x06, - 0x01,0x04,0x40,0xc0,0x40,0x40,0xe0,0x03,0x05,0x05,0x06,0x01,0x05,0x40,0xa0,0x40, - 0x00,0xe0,0x05,0x05,0x05,0x06,0x00,0x00,0xa0,0x50,0x28,0x50,0xa0,0x05,0x0a,0x0a, - 0x06,0x00,0x00,0x40,0xc0,0x48,0x50,0x60,0x50,0xb0,0x50,0x78,0x10,0x05,0x0a,0x0a, - 0x06,0x00,0x00,0x40,0xc0,0x48,0x50,0x60,0x50,0xa8,0x08,0x10,0x38,0x05,0x0a,0x0a, - 0x06,0x00,0x00,0xc0,0x20,0x48,0x30,0xe0,0x50,0xb0,0x50,0x78,0x10,0x05,0x07,0x07, - 0x06,0x00,0x00,0x20,0x00,0x20,0x20,0x40,0x88,0x70,0x05,0x0a,0x0a,0x06,0x00,0x00, - 0x40,0x20,0x00,0x70,0x88,0x88,0xf8,0x88,0x88,0x88,0x05,0x0a,0x0a,0x06,0x00,0x00, - 0x10,0x20,0x00,0x70,0x88,0x88,0xf8,0x88,0x88,0x88,0x05,0x0a,0x0a,0x06,0x00,0x00, - 0x20,0x50,0x00,0x70,0x88,0x88,0xf8,0x88,0x88,0x88,0x05,0x0a,0x0a,0x06,0x00,0x00, - 0x68,0xb0,0x00,0x70,0x88,0x88,0xf8,0x88,0x88,0x88,0x05,0x09,0x09,0x06,0x00,0x00, - 0x50,0x00,0x70,0x88,0x88,0xf8,0x88,0x88,0x88,0x05,0x0a,0x0a,0x06,0x00,0x00,0x20, - 0x50,0x20,0x70,0x88,0x88,0xf8,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x78, - 0xa0,0xa0,0xf0,0xa0,0xa0,0xb8,0x05,0x09,0x09,0x06,0x00,0xfe,0x70,0x88,0x80,0x80, - 0x80,0x88,0x70,0x10,0x60,0x05,0x0a,0x0a,0x06,0x00,0x00,0x40,0x20,0x00,0xf8,0x80, - 0x80,0xf0,0x80,0x80,0xf8,0x05,0x0a,0x0a,0x06,0x00,0x00,0x10,0x20,0x00,0xf8,0x80, - 0x80,0xf0,0x80,0x80,0xf8,0x05,0x0a,0x0a,0x06,0x00,0x00,0x20,0x50,0x00,0xf8,0x80, - 0x80,0xf0,0x80,0x80,0xf8,0x05,0x09,0x09,0x06,0x00,0x00,0x50,0x00,0xf8,0x80,0x80, - 0xf0,0x80,0x80,0xf8,0x03,0x0a,0x0a,0x06,0x01,0x00,0x80,0x40,0x00,0xe0,0x40,0x40, - 0x40,0x40,0x40,0xe0,0x03,0x0a,0x0a,0x06,0x01,0x00,0x20,0x40,0x00,0xe0,0x40,0x40, - 0x40,0x40,0x40,0xe0,0x03,0x0a,0x0a,0x06,0x01,0x00,0x40,0xa0,0x00,0xe0,0x40,0x40, - 0x40,0x40,0x40,0xe0,0x03,0x09,0x09,0x06,0x01,0x00,0xa0,0x00,0xe0,0x40,0x40,0x40, - 0x40,0x40,0xe0,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x48,0x48,0xe8,0x48,0x48,0x70, - 0x05,0x0a,0x0a,0x06,0x00,0x00,0x68,0xb0,0x00,0x88,0x88,0xc8,0xa8,0x98,0x88,0x88, - 0x05,0x0a,0x0a,0x06,0x00,0x00,0x40,0x20,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70, - 0x05,0x0a,0x0a,0x06,0x00,0x00,0x10,0x20,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70, - 0x05,0x0a,0x0a,0x06,0x00,0x00,0x20,0x50,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70, - 0x05,0x0a,0x0a,0x06,0x00,0x00,0x68,0xb0,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70, - 0x05,0x09,0x09,0x06,0x00,0x00,0x50,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x05, - 0x05,0x05,0x06,0x00,0x01,0x88,0x50,0x20,0x50,0x88,0x05,0x09,0x09,0x06,0x00,0xff, - 0x08,0x70,0x98,0xa8,0xa8,0xa8,0xc8,0x70,0x80,0x05,0x0a,0x0a,0x06,0x00,0x00,0x40, - 0x20,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x0a,0x0a,0x06,0x00,0x00,0x10, - 0x20,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x0a,0x0a,0x06,0x00,0x00,0x20, - 0x50,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x09,0x09,0x06,0x00,0x00,0x50, - 0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x0a,0x0a,0x06,0x00,0x00,0x10,0x20, - 0x00,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x04,0x07,0x07,0x06,0x01,0x00,0x80,0xe0, - 0x90,0x90,0x90,0xe0,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x90,0xa0,0x90, - 0x88,0xb0,0x05,0x08,0x08,0x06,0x00,0x00,0x40,0x20,0x00,0x70,0x08,0x78,0x88,0x78, - 0x05,0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0x70,0x08,0x78,0x88,0x78,0x05,0x08, - 0x08,0x06,0x00,0x00,0x20,0x50,0x00,0x70,0x08,0x78,0x88,0x78,0x05,0x08,0x08,0x06, - 0x00,0x00,0x68,0xb0,0x00,0x70,0x08,0x78,0x88,0x78,0x05,0x07,0x07,0x06,0x00,0x00, - 0x50,0x00,0x70,0x08,0x78,0x88,0x78,0x05,0x08,0x08,0x06,0x00,0x00,0x20,0x50,0x20, - 0x70,0x08,0x78,0x88,0x78,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x28,0x70,0xa0,0x78, - 0x05,0x07,0x07,0x06,0x00,0xfe,0x70,0x88,0x80,0x88,0x70,0x10,0x60,0x05,0x08,0x08, - 0x06,0x00,0x00,0x40,0x20,0x00,0x70,0x88,0xf0,0x80,0x70,0x05,0x08,0x08,0x06,0x00, - 0x00,0x10,0x20,0x00,0x70,0x88,0xf0,0x80,0x70,0x05,0x08,0x08,0x06,0x00,0x00,0x20, - 0x50,0x00,0x70,0x88,0xf0,0x80,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x50,0x00,0x70, - 0x88,0xf0,0x80,0x70,0x03,0x08,0x08,0x06,0x01,0x00,0x80,0x40,0x00,0xc0,0x40,0x40, - 0x40,0xe0,0x03,0x08,0x08,0x06,0x01,0x00,0x20,0x40,0x00,0xc0,0x40,0x40,0x40,0xe0, - 0x03,0x08,0x08,0x06,0x01,0x00,0x40,0xa0,0x00,0xc0,0x40,0x40,0x40,0xe0,0x03,0x07, - 0x07,0x06,0x01,0x00,0xa0,0x00,0xc0,0x40,0x40,0x40,0xe0,0x05,0x09,0x09,0x06,0x00, - 0x00,0x50,0x20,0x50,0x08,0x78,0x88,0x88,0x88,0x70,0x05,0x08,0x08,0x06,0x00,0x00, - 0x68,0xb0,0x00,0xb0,0xc8,0x88,0x88,0x88,0x05,0x08,0x08,0x06,0x00,0x00,0x40,0x20, - 0x00,0x70,0x88,0x88,0x88,0x70,0x05,0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0x70, - 0x88,0x88,0x88,0x70,0x05,0x08,0x08,0x06,0x00,0x00,0x20,0x50,0x00,0x70,0x88,0x88, - 0x88,0x70,0x05,0x08,0x08,0x06,0x00,0x00,0x68,0xb0,0x00,0x70,0x88,0x88,0x88,0x70, - 0x05,0x07,0x07,0x06,0x00,0x00,0x50,0x00,0x70,0x88,0x88,0x88,0x70,0x05,0x05,0x05, - 0x06,0x00,0x01,0x20,0x00,0xf8,0x00,0x20,0x05,0x05,0x05,0x06,0x00,0x00,0x78,0x98, - 0xa8,0xc8,0xf0,0x05,0x08,0x08,0x06,0x00,0x00,0x40,0x20,0x00,0x88,0x88,0x88,0x88, - 0x70,0x05,0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0x88,0x88,0x88,0x88,0x70,0x05, - 0x08,0x08,0x06,0x00,0x00,0x20,0x50,0x00,0x88,0x88,0x88,0x88,0x70,0x05,0x07,0x07, - 0x06,0x00,0x00,0x50,0x00,0x88,0x88,0x88,0x88,0x70,0x05,0x0a,0x0a,0x06,0x00,0xfe, - 0x10,0x20,0x00,0x88,0x88,0x88,0x50,0x20,0x40,0x80,0x05,0x09,0x09,0x06,0x00,0xfe, - 0x80,0x80,0xf0,0x88,0x88,0x88,0xf0,0x80,0x80,0x05,0x09,0x09,0x06,0x00,0xfe,0x50, - 0x00,0x88,0x88,0x88,0x50,0x20,0x40,0x80}; +const u8g_fntpgm_uint8_t ISO10646_1_5x7[2647] U8G_FONT_SECTION("ISO10646_1_5x7") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x07,0x02,0x25,0x03,0xBB,0x01,0xFF,0xFE,0x0A,0xFE,0x08, + 0xFE,0x05,0x08,0x08,0x06,0x00,0x00,0x40,0xF0,0xC8,0x88,0x88,0x98,0x78,0x10,0x05, + 0x08,0x08,0x06,0x00,0x00,0xC0,0xF8,0x88,0x88,0x88,0x88,0x88,0xF8,0x05,0x05,0x05, + 0x06,0x00,0x01,0x20,0x30,0xF8,0x30,0x20,0x05,0x08,0x08,0x06,0x00,0x00,0x20,0x70, + 0xF8,0x20,0x20,0x20,0x20,0xE0,0x05,0x09,0x09,0x06,0x00,0xFF,0x20,0x70,0xA8,0xA8, + 0xB8,0x88,0x88,0x70,0x20,0x07,0x05,0x05,0x07,0x00,0x01,0xD8,0x6C,0x36,0x6C,0xD8, + 0x05,0x09,0x09,0x06,0x00,0xFF,0xF8,0xA8,0x88,0x88,0x88,0x88,0x88,0xA8,0xF8,0x05, + 0x0A,0x0A,0x06,0x00,0xFE,0x20,0x50,0x50,0x50,0x50,0x88,0xA8,0xA8,0x88,0x70,0x03, + 0x03,0x03,0x06,0x00,0x03,0x40,0xA0,0x40,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00, + 0x00,0x06,0x05,0xFF,0x01,0x07,0x07,0x06,0x02,0x00,0x80,0x80,0x80,0x80,0x80,0x00, + 0x80,0x03,0x03,0x03,0x06,0x01,0x05,0xA0,0xA0,0xA0,0x05,0x06,0x06,0x06,0x00,0x00, + 0x50,0xF8,0x50,0x50,0xF8,0x50,0x05,0x09,0x09,0x06,0x00,0xFF,0x20,0x70,0xA8,0xA0, + 0x70,0x28,0xA8,0x70,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0xC8,0xC8,0x10,0x20,0x40, + 0x98,0x98,0x05,0x07,0x07,0x06,0x00,0x00,0x40,0xA0,0xA0,0x40,0xA8,0x90,0x68,0x01, + 0x03,0x03,0x06,0x02,0x05,0x80,0x80,0x80,0x03,0x09,0x09,0x06,0x01,0xFF,0x20,0x40, + 0x40,0x80,0x80,0x80,0x40,0x40,0x20,0x03,0x09,0x09,0x06,0x01,0xFF,0x80,0x40,0x40, + 0x20,0x20,0x20,0x40,0x40,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0xA8,0x70,0x20, + 0x70,0xA8,0x20,0x05,0x05,0x05,0x06,0x00,0x01,0x20,0x20,0xF8,0x20,0x20,0x02,0x03, + 0x03,0x06,0x01,0xFF,0xC0,0x40,0x80,0x05,0x01,0x01,0x06,0x00,0x03,0xF8,0x02,0x02, + 0x02,0x06,0x01,0x00,0xC0,0xC0,0x05,0x07,0x07,0x06,0x00,0x00,0x08,0x10,0x10,0x20, + 0x40,0x40,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x98,0xA8,0xC8,0x88,0x70, + 0x03,0x07,0x07,0x06,0x01,0x00,0x40,0xC0,0x40,0x40,0x40,0x40,0xE0,0x05,0x07,0x07, + 0x06,0x00,0x00,0x70,0x88,0x08,0x10,0x20,0x40,0xF8,0x05,0x07,0x07,0x06,0x00,0x00, + 0xF8,0x08,0x10,0x30,0x08,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x10,0x30,0x50, + 0x90,0xF8,0x10,0x10,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x80,0xF0,0x08,0x08,0x88, + 0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x30,0x40,0x80,0xF0,0x88,0x88,0x70,0x05,0x07, + 0x07,0x06,0x00,0x00,0xF8,0x08,0x10,0x10,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00, + 0x00,0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88, + 0x88,0x78,0x08,0x10,0x60,0x02,0x05,0x05,0x06,0x01,0x00,0xC0,0xC0,0x00,0xC0,0xC0, + 0x02,0x06,0x06,0x06,0x01,0xFF,0xC0,0xC0,0x00,0xC0,0x40,0x80,0x03,0x05,0x05,0x06, + 0x01,0x01,0x20,0x40,0x80,0x40,0x20,0x05,0x03,0x03,0x06,0x00,0x02,0xF8,0x00,0xF8, + 0x03,0x05,0x05,0x06,0x01,0x01,0x80,0x40,0x20,0x40,0x80,0x05,0x07,0x07,0x06,0x00, + 0x00,0x70,0x88,0x10,0x20,0x20,0x00,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88, + 0xB8,0xA8,0xB8,0x80,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0xF8,0x88, + 0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0xF0,0x48,0x48,0x70,0x48,0x48,0xF0,0x05, + 0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x05,0x07,0x07,0x06, + 0x00,0x00,0xF0,0x48,0x48,0x48,0x48,0x48,0xF0,0x05,0x07,0x07,0x06,0x00,0x00,0xF8, + 0x80,0x80,0xF0,0x80,0x80,0xF8,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x80,0x80,0xF0, + 0x80,0x80,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x80,0x80,0x98,0x88,0x70, + 0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x03,0x07,0x07, + 0x06,0x01,0x00,0xE0,0x40,0x40,0x40,0x40,0x40,0xE0,0x05,0x07,0x07,0x06,0x00,0x00, + 0x38,0x10,0x10,0x10,0x10,0x90,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x90,0xA0, + 0xC0,0xA0,0x90,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80, + 0xF8,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0xD8,0xA8,0x88,0x88,0x88,0x88,0x05,0x07, + 0x07,0x06,0x00,0x00,0x88,0x88,0xC8,0xA8,0x98,0x88,0x88,0x05,0x07,0x07,0x06,0x00, + 0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0xF0,0x88, + 0x88,0xF0,0x80,0x80,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0x88,0xA8, + 0x90,0x68,0x05,0x07,0x07,0x06,0x00,0x00,0xF0,0x88,0x88,0xF0,0xA0,0x90,0x88,0x05, + 0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x05,0x07,0x07,0x06, + 0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x88, + 0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0x88, + 0x50,0x50,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0x88,0xA8,0xA8,0x50, + 0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x05,0x07,0x07, + 0x06,0x00,0x00,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0x00, + 0xF8,0x08,0x10,0x20,0x40,0x80,0xF8,0x03,0x09,0x09,0x06,0x01,0xFF,0xE0,0x80,0x80, + 0x80,0x80,0x80,0x80,0x80,0xE0,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x40,0x40,0x20, + 0x10,0x10,0x08,0x03,0x09,0x09,0x06,0x01,0xFF,0xE0,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0xE0,0x05,0x03,0x03,0x06,0x00,0x05,0x20,0x50,0x88,0x05,0x01,0x01,0x06,0x00, + 0xFE,0xF8,0x03,0x03,0x03,0x06,0x01,0x05,0x80,0x40,0x20,0x05,0x05,0x05,0x06,0x00, + 0x00,0x70,0x08,0x78,0x88,0x78,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x80,0xF0,0x88, + 0x88,0x88,0xF0,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x80,0x80,0x88,0x70,0x05,0x07, + 0x07,0x06,0x00,0x00,0x08,0x08,0x78,0x88,0x88,0x88,0x78,0x05,0x05,0x05,0x06,0x00, + 0x00,0x70,0x88,0xF0,0x80,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x30,0x48,0x40,0xE0, + 0x40,0x40,0x40,0x05,0x07,0x07,0x06,0x00,0xFE,0x70,0x88,0x88,0x88,0x78,0x08,0x70, + 0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x88,0x03,0x07,0x07, + 0x06,0x01,0x00,0x40,0x00,0xC0,0x40,0x40,0x40,0xE0,0x04,0x09,0x09,0x06,0x01,0xFE, + 0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x90,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x80, + 0x80,0x88,0x90,0xE0,0x90,0x88,0x03,0x07,0x07,0x06,0x01,0x00,0xC0,0x40,0x40,0x40, + 0x40,0x40,0xE0,0x05,0x05,0x05,0x06,0x00,0x00,0xD0,0xA8,0xA8,0xA8,0xA8,0x05,0x05, + 0x05,0x06,0x00,0x00,0xB0,0xC8,0x88,0x88,0x88,0x05,0x05,0x05,0x06,0x00,0x00,0x70, + 0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0xFE,0xF0,0x88,0x88,0x88,0xF0,0x80, + 0x80,0x05,0x07,0x07,0x06,0x00,0xFE,0x78,0x88,0x88,0x88,0x78,0x08,0x08,0x05,0x05, + 0x05,0x06,0x00,0x00,0xB0,0xC8,0x80,0x80,0x80,0x05,0x05,0x05,0x06,0x00,0x00,0x78, + 0x80,0x70,0x08,0xF0,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x20, + 0x18,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x88,0x88,0x98,0x68,0x05,0x05,0x05,0x06, + 0x00,0x00,0x88,0x88,0x88,0x50,0x20,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x88,0xA8, + 0xA8,0x50,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x05,0x07,0x07, + 0x06,0x00,0xFE,0x88,0x88,0x88,0x50,0x20,0x40,0x80,0x05,0x05,0x05,0x06,0x00,0x00, + 0xF8,0x10,0x20,0x40,0xF8,0x03,0x09,0x09,0x06,0x01,0xFF,0x20,0x40,0x40,0x40,0x80, + 0x40,0x40,0x40,0x20,0x01,0x09,0x09,0x06,0x02,0xFF,0x80,0x80,0x80,0x80,0x80,0x80, + 0x80,0x80,0x80,0x03,0x09,0x09,0x06,0x01,0xFF,0x80,0x40,0x40,0x40,0x20,0x40,0x40, + 0x40,0x80,0x05,0x03,0x03,0x06,0x00,0x02,0x48,0xA8,0x90,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x06, + 0x05,0xFF,0x01,0x07,0x07,0x06,0x02,0x00,0x80,0x00,0x80,0x80,0x80,0x80,0x80,0x05, + 0x07,0x07,0x06,0x00,0xFF,0x20,0x70,0xA8,0xA0,0xA8,0x70,0x20,0x05,0x07,0x07,0x06, + 0x00,0x00,0x30,0x48,0x40,0xE0,0x40,0x48,0xB0,0x05,0x05,0x05,0x06,0x00,0x00,0xA8, + 0x50,0x88,0x50,0xA8,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x50,0xF8,0x20,0xF8,0x20, + 0x20,0x01,0x07,0x07,0x06,0x02,0x00,0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x04,0x08, + 0x08,0x06,0x01,0x00,0x70,0x80,0x60,0x90,0x90,0x60,0x10,0xE0,0x03,0x01,0x01,0x06, + 0x01,0x07,0xA0,0x06,0x07,0x07,0x06,0x00,0x00,0x78,0x84,0xB4,0xA4,0xB4,0x84,0x78, + 0x03,0x05,0x05,0x06,0x01,0x04,0x60,0xA0,0x60,0x00,0xE0,0x05,0x05,0x05,0x06,0x00, + 0x00,0x28,0x50,0xA0,0x50,0x28,0x05,0x03,0x03,0x06,0x00,0x01,0xF8,0x08,0x08,0x03, + 0x01,0x01,0x06,0x01,0x03,0xE0,0x06,0x07,0x07,0x06,0x00,0x00,0x78,0x84,0xB4,0xA4, + 0xA4,0x84,0x78,0x05,0x01,0x01,0x06,0x00,0x07,0xF8,0x04,0x04,0x04,0x06,0x01,0x05, + 0x60,0x90,0x90,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00, + 0xF8,0x03,0x05,0x05,0x06,0x01,0x04,0x40,0xA0,0x20,0x40,0xE0,0x03,0x05,0x05,0x06, + 0x01,0x04,0xC0,0x20,0x40,0x20,0xC0,0x03,0x03,0x03,0x06,0x01,0x05,0x20,0x40,0x80, + 0x05,0x07,0x07,0x06,0x00,0xFE,0x88,0x88,0x88,0x98,0xE8,0x80,0x80,0x05,0x08,0x08, + 0x06,0x00,0x00,0x78,0xE8,0xE8,0xE8,0x68,0x28,0x28,0x28,0x02,0x02,0x02,0x06,0x02, + 0x03,0xC0,0xC0,0x03,0x02,0x02,0x06,0x01,0xFE,0x20,0xC0,0x03,0x05,0x05,0x06,0x01, + 0x04,0x40,0xC0,0x40,0x40,0xE0,0x03,0x05,0x05,0x06,0x01,0x05,0x40,0xA0,0x40,0x00, + 0xE0,0x05,0x05,0x05,0x06,0x00,0x00,0xA0,0x50,0x28,0x50,0xA0,0x05,0x0A,0x0A,0x06, + 0x00,0x00,0x40,0xC0,0x48,0x50,0x60,0x50,0xB0,0x50,0x78,0x10,0x05,0x0A,0x0A,0x06, + 0x00,0x00,0x40,0xC0,0x48,0x50,0x60,0x50,0xA8,0x08,0x10,0x38,0x05,0x0A,0x0A,0x06, + 0x00,0x00,0xC0,0x20,0x48,0x30,0xE0,0x50,0xB0,0x50,0x78,0x10,0x05,0x07,0x07,0x06, + 0x00,0x00,0x20,0x00,0x20,0x20,0x40,0x88,0x70,0x05,0x0A,0x0A,0x06,0x00,0x00,0x40, + 0x20,0x00,0x70,0x88,0x88,0xF8,0x88,0x88,0x88,0x05,0x0A,0x0A,0x06,0x00,0x00,0x10, + 0x20,0x00,0x70,0x88,0x88,0xF8,0x88,0x88,0x88,0x05,0x0A,0x0A,0x06,0x00,0x00,0x20, + 0x50,0x00,0x70,0x88,0x88,0xF8,0x88,0x88,0x88,0x05,0x0A,0x0A,0x06,0x00,0x00,0x68, + 0xB0,0x00,0x70,0x88,0x88,0xF8,0x88,0x88,0x88,0x05,0x09,0x09,0x06,0x00,0x00,0x50, + 0x00,0x70,0x88,0x88,0xF8,0x88,0x88,0x88,0x05,0x0A,0x0A,0x06,0x00,0x00,0x20,0x50, + 0x20,0x70,0x88,0x88,0xF8,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x78,0xA0, + 0xA0,0xF0,0xA0,0xA0,0xB8,0x05,0x09,0x09,0x06,0x00,0xFE,0x70,0x88,0x80,0x80,0x80, + 0x88,0x70,0x10,0x60,0x05,0x0A,0x0A,0x06,0x00,0x00,0x40,0x20,0x00,0xF8,0x80,0x80, + 0xF0,0x80,0x80,0xF8,0x05,0x0A,0x0A,0x06,0x00,0x00,0x10,0x20,0x00,0xF8,0x80,0x80, + 0xF0,0x80,0x80,0xF8,0x05,0x0A,0x0A,0x06,0x00,0x00,0x20,0x50,0x00,0xF8,0x80,0x80, + 0xF0,0x80,0x80,0xF8,0x05,0x09,0x09,0x06,0x00,0x00,0x50,0x00,0xF8,0x80,0x80,0xF0, + 0x80,0x80,0xF8,0x03,0x0A,0x0A,0x06,0x01,0x00,0x80,0x40,0x00,0xE0,0x40,0x40,0x40, + 0x40,0x40,0xE0,0x03,0x0A,0x0A,0x06,0x01,0x00,0x20,0x40,0x00,0xE0,0x40,0x40,0x40, + 0x40,0x40,0xE0,0x03,0x0A,0x0A,0x06,0x01,0x00,0x40,0xA0,0x00,0xE0,0x40,0x40,0x40, + 0x40,0x40,0xE0,0x03,0x09,0x09,0x06,0x01,0x00,0xA0,0x00,0xE0,0x40,0x40,0x40,0x40, + 0x40,0xE0,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x48,0x48,0xE8,0x48,0x48,0x70,0x05, + 0x0A,0x0A,0x06,0x00,0x00,0x68,0xB0,0x00,0x88,0x88,0xC8,0xA8,0x98,0x88,0x88,0x05, + 0x0A,0x0A,0x06,0x00,0x00,0x40,0x20,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x05, + 0x0A,0x0A,0x06,0x00,0x00,0x10,0x20,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x05, + 0x0A,0x0A,0x06,0x00,0x00,0x20,0x50,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x05, + 0x0A,0x0A,0x06,0x00,0x00,0x68,0xB0,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x05, + 0x09,0x09,0x06,0x00,0x00,0x50,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x05, + 0x05,0x06,0x00,0x01,0x88,0x50,0x20,0x50,0x88,0x05,0x09,0x09,0x06,0x00,0xFF,0x08, + 0x70,0x98,0xA8,0xA8,0xA8,0xC8,0x70,0x80,0x05,0x0A,0x0A,0x06,0x00,0x00,0x40,0x20, + 0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x0A,0x0A,0x06,0x00,0x00,0x10,0x20, + 0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x0A,0x0A,0x06,0x00,0x00,0x20,0x50, + 0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x09,0x09,0x06,0x00,0x00,0x50,0x00, + 0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x0A,0x0A,0x06,0x00,0x00,0x10,0x20,0x00, + 0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x04,0x07,0x07,0x06,0x01,0x00,0x80,0xE0,0x90, + 0x90,0x90,0xE0,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x90,0xA0,0x90,0x88, + 0xB0,0x05,0x08,0x08,0x06,0x00,0x00,0x40,0x20,0x00,0x70,0x08,0x78,0x88,0x78,0x05, + 0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0x70,0x08,0x78,0x88,0x78,0x05,0x08,0x08, + 0x06,0x00,0x00,0x20,0x50,0x00,0x70,0x08,0x78,0x88,0x78,0x05,0x08,0x08,0x06,0x00, + 0x00,0x68,0xB0,0x00,0x70,0x08,0x78,0x88,0x78,0x05,0x07,0x07,0x06,0x00,0x00,0x50, + 0x00,0x70,0x08,0x78,0x88,0x78,0x05,0x08,0x08,0x06,0x00,0x00,0x20,0x50,0x20,0x70, + 0x08,0x78,0x88,0x78,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x28,0x70,0xA0,0x78,0x05, + 0x07,0x07,0x06,0x00,0xFE,0x70,0x88,0x80,0x88,0x70,0x10,0x60,0x05,0x08,0x08,0x06, + 0x00,0x00,0x40,0x20,0x00,0x70,0x88,0xF0,0x80,0x70,0x05,0x08,0x08,0x06,0x00,0x00, + 0x10,0x20,0x00,0x70,0x88,0xF0,0x80,0x70,0x05,0x08,0x08,0x06,0x00,0x00,0x20,0x50, + 0x00,0x70,0x88,0xF0,0x80,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x50,0x00,0x70,0x88, + 0xF0,0x80,0x70,0x03,0x08,0x08,0x06,0x01,0x00,0x80,0x40,0x00,0xC0,0x40,0x40,0x40, + 0xE0,0x03,0x08,0x08,0x06,0x01,0x00,0x20,0x40,0x00,0xC0,0x40,0x40,0x40,0xE0,0x03, + 0x08,0x08,0x06,0x01,0x00,0x40,0xA0,0x00,0xC0,0x40,0x40,0x40,0xE0,0x03,0x07,0x07, + 0x06,0x01,0x00,0xA0,0x00,0xC0,0x40,0x40,0x40,0xE0,0x05,0x09,0x09,0x06,0x00,0x00, + 0x50,0x20,0x50,0x08,0x78,0x88,0x88,0x88,0x70,0x05,0x08,0x08,0x06,0x00,0x00,0x68, + 0xB0,0x00,0xB0,0xC8,0x88,0x88,0x88,0x05,0x08,0x08,0x06,0x00,0x00,0x40,0x20,0x00, + 0x70,0x88,0x88,0x88,0x70,0x05,0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0x70,0x88, + 0x88,0x88,0x70,0x05,0x08,0x08,0x06,0x00,0x00,0x20,0x50,0x00,0x70,0x88,0x88,0x88, + 0x70,0x05,0x08,0x08,0x06,0x00,0x00,0x68,0xB0,0x00,0x70,0x88,0x88,0x88,0x70,0x05, + 0x07,0x07,0x06,0x00,0x00,0x50,0x00,0x70,0x88,0x88,0x88,0x70,0x05,0x05,0x05,0x06, + 0x00,0x01,0x20,0x00,0xF8,0x00,0x20,0x05,0x05,0x05,0x06,0x00,0x00,0x78,0x98,0xA8, + 0xC8,0xF0,0x05,0x08,0x08,0x06,0x00,0x00,0x40,0x20,0x00,0x88,0x88,0x88,0x88,0x70, + 0x05,0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0x88,0x88,0x88,0x88,0x70,0x05,0x08, + 0x08,0x06,0x00,0x00,0x20,0x50,0x00,0x88,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06, + 0x00,0x00,0x50,0x00,0x88,0x88,0x88,0x88,0x70,0x05,0x0A,0x0A,0x06,0x00,0xFE,0x10, + 0x20,0x00,0x88,0x88,0x88,0x50,0x20,0x40,0x80,0x05,0x09,0x09,0x06,0x00,0xFE,0x80, + 0x80,0xF0,0x88,0x88,0x88,0xF0,0x80,0x80,0x05,0x09,0x09,0x06,0x00,0xFE,0x50,0x00, + 0x88,0x88,0x88,0x50,0x20,0x40,0x80}; #endif diff --git a/Marlin/src/lcd/dogm/fontdata/langdata_bg.h b/Marlin/src/lcd/dogm/fontdata/langdata_bg.h index 81444d99692a..c506f879335b 100644 --- a/Marlin/src/lcd/dogm/fontdata/langdata_bg.h +++ b/Marlin/src/lcd/dogm/fontdata/langdata_bg.h @@ -6,62 +6,62 @@ #include const u8g_fntpgm_uint8_t fontpage_8_144_149[96] U8G_FONT_SECTION("fontpage_8_144_149") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x90,0x95,0x00,0x07,0xff,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0xf8,0x88,0x88,0x88,0x05,0x07, - 0x07,0x06,0x00,0x00,0xf0,0x80,0x80,0xf0,0x88,0x88,0xf0,0x05,0x07,0x07,0x06,0x00, - 0x00,0xf0,0x88,0x88,0xf0,0x88,0x88,0xf0,0x05,0x07,0x07,0x06,0x00,0x00,0xf8,0x80, - 0x80,0x80,0x80,0x80,0x80,0x05,0x08,0x08,0x06,0x00,0xff,0x30,0x50,0x50,0x50,0x50, - 0x50,0xf8,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0xf8,0x80,0x80,0xf0,0x80,0x80,0xf8 + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x90,0x95,0x00,0x07,0xFF,0x00, + 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0xF8,0x88,0x88,0x88,0x05,0x07, + 0x07,0x06,0x00,0x00,0xF0,0x80,0x80,0xF0,0x88,0x88,0xF0,0x05,0x07,0x07,0x06,0x00, + 0x00,0xF0,0x88,0x88,0xF0,0x88,0x88,0xF0,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x80, + 0x80,0x80,0x80,0x80,0x80,0x05,0x08,0x08,0x06,0x00,0xFF,0x30,0x50,0x50,0x50,0x50, + 0x50,0xF8,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8 }; const u8g_fntpgm_uint8_t fontpage_8_151_152[43] U8G_FONT_SECTION("fontpage_8_151_152") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x97,0x98,0x00,0x07,0x00,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x97,0x98,0x00,0x07,0x00,0x00, 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x08,0x70,0x08,0x88,0x70,0x05,0x07, - 0x07,0x06,0x00,0x00,0x88,0x88,0x98,0xa8,0xc8,0x88,0x88}; + 0x07,0x06,0x00,0x00,0x88,0x88,0x98,0xA8,0xC8,0x88,0x88}; const u8g_fntpgm_uint8_t fontpage_8_154_164[160] U8G_FONT_SECTION("fontpage_8_154_164") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9a,0xa4,0x00,0x07,0x00,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x90,0xa0,0xc0,0xa0,0x90,0x88,0x05,0x07, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9A,0xA4,0x00,0x07,0x00,0x00, + 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x90,0xA0,0xC0,0xA0,0x90,0x88,0x05,0x07, 0x07,0x06,0x00,0x00,0x38,0x48,0x48,0x48,0x48,0x48,0x88,0x05,0x07,0x07,0x06,0x00, - 0x00,0x88,0xd8,0xa8,0x88,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88, - 0x88,0xf8,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0x88,0x88, - 0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0xf8,0x88,0x88,0x88,0x88,0x88,0x88,0x05, - 0x07,0x07,0x06,0x00,0x00,0xf0,0x88,0x88,0xf0,0x80,0x80,0x80,0x05,0x07,0x07,0x06, - 0x00,0x00,0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0xf8, + 0x00,0x88,0xD8,0xA8,0x88,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88, + 0x88,0xF8,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0x88,0x88, + 0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0x88,0x88,0x05, + 0x07,0x07,0x06,0x00,0x00,0xF0,0x88,0x88,0xF0,0x80,0x80,0x80,0x05,0x07,0x07,0x06, + 0x00,0x00,0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0xF8, 0x20,0x20,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0x88, - 0x78,0x08,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x70,0xa8,0xa8,0xa8,0x70,0x20 + 0x78,0x08,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x70,0xA8,0xA8,0xA8,0x70,0x20 }; const u8g_fntpgm_uint8_t fontpage_8_166_166[32] U8G_FONT_SECTION("fontpage_8_166_166") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa6,0xa6,0x00,0x07,0xfe,0x00, - 0x00,0x05,0x09,0x09,0x06,0x00,0xfe,0x90,0x90,0x90,0x90,0x90,0x90,0xf8,0x08,0x08 + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA6,0xA6,0x00,0x07,0xFE,0x00, + 0x00,0x05,0x09,0x09,0x06,0x00,0xFE,0x90,0x90,0x90,0x90,0x90,0x90,0xF8,0x08,0x08 }; const u8g_fntpgm_uint8_t fontpage_8_175_195[260] U8G_FONT_SECTION("fontpage_8_175_195") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xaf,0xc3,0x00,0x08,0xfe,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAF,0xC3,0x00,0x08,0xFE,0x00, 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x78,0x88,0x88,0x78,0x28,0x48,0x88,0x05,0x05, 0x05,0x06,0x00,0x00,0x70,0x08,0x78,0x88,0x78,0x05,0x07,0x07,0x06,0x00,0x00,0x70, - 0x80,0xf0,0x88,0x88,0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xf0,0x88,0xf0,0x88, - 0xf0,0x05,0x05,0x05,0x06,0x00,0x00,0xf8,0x80,0x80,0x80,0x80,0x05,0x06,0x06,0x06, - 0x00,0xff,0x30,0x50,0x50,0x50,0xf8,0x88,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x88, - 0xf0,0x80,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xa8,0x70,0x20,0x70,0xa8,0x05,0x05, + 0x80,0xF0,0x88,0x88,0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xF0,0x88,0xF0,0x88, + 0xF0,0x05,0x05,0x05,0x06,0x00,0x00,0xF8,0x80,0x80,0x80,0x80,0x05,0x06,0x06,0x06, + 0x00,0xFF,0x30,0x50,0x50,0x50,0xF8,0x88,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x88, + 0xF0,0x80,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xA8,0x70,0x20,0x70,0xA8,0x05,0x05, 0x05,0x06,0x00,0x00,0x70,0x88,0x30,0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0x88, - 0x98,0xa8,0xc8,0x88,0x05,0x08,0x08,0x06,0x00,0x00,0x88,0x70,0x00,0x88,0x98,0xa8, - 0xc8,0x88,0x04,0x05,0x05,0x06,0x01,0x00,0x90,0xa0,0xc0,0xa0,0x90,0x05,0x05,0x05, - 0x06,0x00,0x00,0x38,0x48,0x48,0x48,0x88,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0xd8, - 0xa8,0x88,0x88,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x88,0xf8,0x88,0x88,0x05,0x05, - 0x05,0x06,0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xf8, - 0x88,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0xfe,0xf0,0x88,0x88,0x88,0xf0,0x80, + 0x98,0xA8,0xC8,0x88,0x05,0x08,0x08,0x06,0x00,0x00,0x88,0x70,0x00,0x88,0x98,0xA8, + 0xC8,0x88,0x04,0x05,0x05,0x06,0x01,0x00,0x90,0xA0,0xC0,0xA0,0x90,0x05,0x05,0x05, + 0x06,0x00,0x00,0x38,0x48,0x48,0x48,0x88,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0xD8, + 0xA8,0x88,0x88,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x88,0xF8,0x88,0x88,0x05,0x05, + 0x05,0x06,0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xF8, + 0x88,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0xFE,0xF0,0x88,0x88,0x88,0xF0,0x80, 0x80,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x88,0x80,0x88,0x70,0x05,0x05,0x05,0x06, - 0x00,0x00,0xf8,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0xfe,0x88,0x88,0x88, + 0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0xFE,0x88,0x88,0x88, 0x88,0x78,0x08,0x70}; const u8g_fntpgm_uint8_t fontpage_8_197_200[63] U8G_FONT_SECTION("fontpage_8_197_200") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc5,0xc8,0x00,0x05,0xfe,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC5,0xC8,0x00,0x05,0xFE,0x00, 0x00,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x05,0x07,0x07,0x06, - 0x00,0xfe,0x90,0x90,0x90,0x90,0xf8,0x08,0x08,0x05,0x05,0x05,0x06,0x00,0x00,0x88, - 0x88,0x78,0x08,0x08,0x05,0x05,0x05,0x06,0x00,0x00,0xa8,0xa8,0xa8,0xa8,0xf8}; + 0x00,0xFE,0x90,0x90,0x90,0x90,0xF8,0x08,0x08,0x05,0x05,0x05,0x06,0x00,0x00,0x88, + 0x88,0x78,0x08,0x08,0x05,0x05,0x05,0x06,0x00,0x00,0xA8,0xA8,0xA8,0xA8,0xF8}; const u8g_fntpgm_uint8_t fontpage_8_202_202[28] U8G_FONT_SECTION("fontpage_8_202_202") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xca,0xca,0x00,0x05,0x00,0x00, - 0x00,0x05,0x05,0x05,0x06,0x00,0x00,0xc0,0x40,0x70,0x48,0x70}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCA,0xCA,0x00,0x05,0x00,0x00, + 0x00,0x05,0x05,0x05,0x06,0x00,0x00,0xC0,0x40,0x70,0x48,0x70}; const u8g_fntpgm_uint8_t fontpage_8_206_207[39] U8G_FONT_SECTION("fontpage_8_206_207") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xce,0xcf,0x00,0x05,0x00,0x00, - 0x00,0x05,0x05,0x05,0x06,0x00,0x00,0x90,0xa8,0xe8,0xa8,0x90,0x04,0x05,0x05,0x06, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCE,0xCF,0x00,0x05,0x00,0x00, + 0x00,0x05,0x05,0x05,0x06,0x00,0x00,0x90,0xA8,0xE8,0xA8,0x90,0x04,0x05,0x05,0x06, 0x01,0x00,0x70,0x90,0x70,0x50,0x90}; #define FONTDATA_ITEM(page, begin, end, data) { page, begin, end, COUNT(data), data } diff --git a/Marlin/src/lcd/dogm/fontdata/langdata_cz.h b/Marlin/src/lcd/dogm/fontdata/langdata_cz.h index e132dc816058..754459d9af2a 100644 --- a/Marlin/src/lcd/dogm/fontdata/langdata_cz.h +++ b/Marlin/src/lcd/dogm/fontdata/langdata_cz.h @@ -6,46 +6,48 @@ #include const u8g_fntpgm_uint8_t fontpage_2_140_141[47] U8G_FONT_SECTION("fontpage_2_140_141") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8c,0x8d,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x06,0x00,0x00,0x50,0x20,0x00,0x70,0x88,0x80,0x80,0x80,0x88, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8C,0x8D,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x0A,0x0A,0x06,0x00,0x00,0x50,0x20,0x00,0x70,0x88,0x80,0x80,0x80,0x88, 0x70,0x05,0x08,0x08,0x06,0x00,0x00,0x50,0x20,0x00,0x70,0x88,0x80,0x88,0x70}; const u8g_fntpgm_uint8_t fontpage_2_143_143[33] U8G_FONT_SECTION("fontpage_2_143_143") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8f,0x8f,0x00,0x0a,0x00,0x00, - 0x00,0x06,0x0a,0x0a,0x06,0x00,0x00,0x14,0x08,0x00,0x08,0x08,0x78,0x88,0x88,0x88, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8F,0x8F,0x00,0x0A,0x00,0x00, + 0x00,0x06,0x0A,0x0A,0x06,0x00,0x00,0x14,0x08,0x00,0x08,0x08,0x78,0x88,0x88,0x88, 0x78}; -const u8g_fntpgm_uint8_t fontpage_2_155_155[31] U8G_FONT_SECTION("fontpage_2_155_155") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9b,0x9b,0x00,0x08,0x00,0x00, - 0x00,0x05,0x08,0x08,0x06,0x00,0x00,0x50,0x20,0x00,0x70,0x88,0xf0,0x80,0x70}; +const u8g_fntpgm_uint8_t fontpage_2_154_155[47] U8G_FONT_SECTION("fontpage_2_154_155") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9A,0x9B,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x0A,0x0A,0x06,0x00,0x00,0x50,0x20,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80, + 0xF8,0x05,0x08,0x08,0x06,0x00,0x00,0x50,0x20,0x00,0x70,0x88,0xF0,0x80,0x70}; const u8g_fntpgm_uint8_t fontpage_2_200_200[31] U8G_FONT_SECTION("fontpage_2_200_200") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x08,0x00,0x00, - 0x00,0x05,0x08,0x08,0x06,0x00,0x00,0x50,0x20,0x00,0xb0,0xc8,0x88,0x88,0x88}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC8,0xC8,0x00,0x08,0x00,0x00, + 0x00,0x05,0x08,0x08,0x06,0x00,0x00,0x50,0x20,0x00,0xB0,0xC8,0x88,0x88,0x88}; const u8g_fntpgm_uint8_t fontpage_2_216_217[47] U8G_FONT_SECTION("fontpage_2_216_217") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd8,0xd9,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x06,0x00,0x00,0x50,0x20,0x00,0xf0,0x88,0x88,0xf0,0xa0,0x90, - 0x88,0x05,0x08,0x08,0x06,0x00,0x00,0x50,0x20,0x00,0xb0,0xc8,0x80,0x80,0x80}; -const u8g_fntpgm_uint8_t fontpage_2_225_225[31] U8G_FONT_SECTION("fontpage_2_225_225") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe1,0xe1,0x00,0x08,0x00,0x00, - 0x00,0x05,0x08,0x08,0x06,0x00,0x00,0x50,0x20,0x00,0x78,0x80,0x70,0x08,0xf0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD8,0xD9,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x0A,0x0A,0x06,0x00,0x00,0x50,0x20,0x00,0xF0,0x88,0x88,0xF0,0xA0,0x90, + 0x88,0x05,0x08,0x08,0x06,0x00,0x00,0x50,0x20,0x00,0xB0,0xC8,0x80,0x80,0x80}; +const u8g_fntpgm_uint8_t fontpage_2_224_225[47] U8G_FONT_SECTION("fontpage_2_224_225") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE0,0xE1,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x0A,0x0A,0x06,0x00,0x00,0x50,0x20,0x00,0x70,0x88,0x80,0x70,0x08,0x88, + 0x70,0x05,0x08,0x08,0x06,0x00,0x00,0x50,0x20,0x00,0x78,0x80,0x70,0x08,0xF0}; const u8g_fntpgm_uint8_t fontpage_2_229_229[33] U8G_FONT_SECTION("fontpage_2_229_229") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe5,0xe5,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x06,0x00,0x00,0x50,0x20,0x00,0x20,0x20,0xf8,0x20,0x20,0x20, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE5,0xE5,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x0A,0x0A,0x06,0x00,0x00,0x50,0x20,0x00,0x20,0x20,0xF8,0x20,0x20,0x20, 0x18}; const u8g_fntpgm_uint8_t fontpage_2_239_239[31] U8G_FONT_SECTION("fontpage_2_239_239") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xef,0xef,0x00,0x08,0x00,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xEF,0xEF,0x00,0x08,0x00,0x00, 0x00,0x05,0x08,0x08,0x06,0x00,0x00,0x20,0x50,0x20,0x88,0x88,0x88,0x88,0x70}; const u8g_fntpgm_uint8_t fontpage_2_253_254[47] U8G_FONT_SECTION("fontpage_2_253_254") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfd,0xfe,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x06,0x00,0x00,0x50,0x20,0x00,0xf8,0x08,0x10,0x20,0x40,0x80, - 0xf8,0x05,0x08,0x08,0x06,0x00,0x00,0x50,0x20,0x00,0xf8,0x10,0x20,0x40,0xf8}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFD,0xFE,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x0A,0x0A,0x06,0x00,0x00,0x50,0x20,0x00,0xF8,0x08,0x10,0x20,0x40,0x80, + 0xF8,0x05,0x08,0x08,0x06,0x00,0x00,0x50,0x20,0x00,0xF8,0x10,0x20,0x40,0xF8}; #define FONTDATA_ITEM(page, begin, end, data) { page, begin, end, COUNT(data), data } static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(2, 140, 141, fontpage_2_140_141), // 'Č' -- 'č' FONTDATA_ITEM(2, 143, 143, fontpage_2_143_143), // 'ď' -- 'ď' - FONTDATA_ITEM(2, 155, 155, fontpage_2_155_155), // 'ě' -- 'ě' + FONTDATA_ITEM(2, 154, 155, fontpage_2_154_155), // 'Ě' -- 'ě' FONTDATA_ITEM(2, 200, 200, fontpage_2_200_200), // 'ň' -- 'ň' FONTDATA_ITEM(2, 216, 217, fontpage_2_216_217), // 'Ř' -- 'ř' - FONTDATA_ITEM(2, 225, 225, fontpage_2_225_225), // 'š' -- 'š' + FONTDATA_ITEM(2, 224, 225, fontpage_2_224_225), // 'Š' -- 'š' FONTDATA_ITEM(2, 229, 229, fontpage_2_229_229), // 'ť' -- 'ť' FONTDATA_ITEM(2, 239, 239, fontpage_2_239_239), // 'ů' -- 'ů' FONTDATA_ITEM(2, 253, 254, fontpage_2_253_254), // 'Ž' -- 'ž' diff --git a/Marlin/src/lcd/dogm/fontdata/langdata_el.h b/Marlin/src/lcd/dogm/fontdata/langdata_el.h index 858ec0f84f1b..4b545f228436 100644 --- a/Marlin/src/lcd/dogm/fontdata/langdata_el.h +++ b/Marlin/src/lcd/dogm/fontdata/langdata_el.h @@ -6,77 +6,74 @@ #include const u8g_fntpgm_uint8_t fontpage_7_136_136[33] U8G_FONT_SECTION("fontpage_7_136_136") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x06,0x00,0x00,0x40,0x80,0x00,0xf8,0x80,0x80,0xf0,0x80,0x80, - 0xf8}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x0A,0x0A,0x06,0x00,0x00,0x40,0x80,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80, + 0xF8}; const u8g_fntpgm_uint8_t fontpage_7_145_157[186] U8G_FONT_SECTION("fontpage_7_145_157") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x91,0x9d,0x00,0x07,0x00,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0xf8,0x88,0x88,0x88,0x05,0x07, - 0x07,0x06,0x00,0x00,0xf0,0x88,0x88,0xf0,0x88,0x88,0xf0,0x05,0x07,0x07,0x06,0x00, - 0x00,0xf8,0x80,0x80,0x80,0x80,0x80,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x20, - 0x50,0x50,0x88,0x88,0xf8,0x05,0x07,0x07,0x06,0x00,0x00,0xf8,0x80,0x80,0xf0,0x80, - 0x80,0xf8,0x05,0x07,0x07,0x06,0x00,0x00,0xf8,0x08,0x10,0x20,0x40,0x80,0xf8,0x05, - 0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x05,0x07,0x07,0x06, - 0x00,0x00,0x70,0x88,0x88,0xf8,0x88,0x88,0x70,0x03,0x07,0x07,0x06,0x01,0x00,0xe0, - 0x40,0x40,0x40,0x40,0x40,0xe0,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x90,0xa0,0xc0, - 0xa0,0x90,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x20,0x50,0x50,0x88,0x88,0x88, - 0x05,0x07,0x07,0x06,0x00,0x00,0x88,0xd8,0xa8,0x88,0x88,0x88,0x88,0x05,0x07,0x07, - 0x06,0x00,0x00,0x88,0x88,0xc8,0xa8,0x98,0x88,0x88}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x91,0x9D,0x00,0x07,0x00,0x00, + 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0xF8,0x88,0x88,0x88,0x05,0x07, + 0x07,0x06,0x00,0x00,0xF0,0x88,0x88,0xF0,0x88,0x88,0xF0,0x05,0x07,0x07,0x06,0x00, + 0x00,0xF8,0x80,0x80,0x80,0x80,0x80,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x20, + 0x50,0x50,0x88,0x88,0xF8,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x80,0x80,0xF0,0x80, + 0x80,0xF8,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x08,0x10,0x20,0x40,0x80,0xF8,0x05, + 0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x05,0x07,0x07,0x06, + 0x00,0x00,0x70,0x88,0x88,0xF8,0x88,0x88,0x70,0x03,0x07,0x07,0x06,0x01,0x00,0xE0, + 0x40,0x40,0x40,0x40,0x40,0xE0,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x90,0xA0,0xC0, + 0xA0,0x90,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x20,0x50,0x50,0x88,0x88,0x88, + 0x05,0x07,0x07,0x06,0x00,0x00,0x88,0xD8,0xA8,0x88,0x88,0x88,0x88,0x05,0x07,0x07, + 0x06,0x00,0x00,0x88,0x88,0xC8,0xA8,0x98,0x88,0x88}; const u8g_fntpgm_uint8_t fontpage_7_159_161[56] U8G_FONT_SECTION("fontpage_7_159_161") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9f,0xa1,0x00,0x07,0x00,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9F,0xA1,0x00,0x07,0x00,0x00, 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x07, - 0x07,0x06,0x00,0x00,0xf8,0x88,0x88,0x88,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00, - 0x00,0xf0,0x88,0x88,0xf0,0x80,0x80,0x80}; + 0x07,0x06,0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00, + 0x00,0xF0,0x88,0x88,0xF0,0x80,0x80,0x80}; const u8g_fntpgm_uint8_t fontpage_7_163_167[82] U8G_FONT_SECTION("fontpage_7_163_167") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa3,0xa7,0x00,0x07,0x00,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0xf8,0x40,0x20,0x10,0x20,0x40,0xf8,0x05,0x07, - 0x07,0x06,0x00,0x00,0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA3,0xA7,0x00,0x07,0x00,0x00, + 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x40,0x20,0x10,0x20,0x40,0xF8,0x05,0x07, + 0x07,0x06,0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00, 0x00,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x70, - 0xa8,0xa8,0xa8,0x70,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x50,0x20,0x50, + 0xA8,0xA8,0xA8,0x70,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x50,0x20,0x50, 0x88,0x88}; -const u8g_fntpgm_uint8_t fontpage_7_169_169[30] U8G_FONT_SECTION("fontpage_7_169_169") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa9,0xa9,0x00,0x07,0x00,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x50,0xd8}; const u8g_fntpgm_uint8_t fontpage_7_172_175[75] U8G_FONT_SECTION("fontpage_7_172_175") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xac,0xaf,0x00,0x08,0xfe,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAC,0xAF,0x00,0x08,0xFE,0x00, 0x00,0x05,0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0x68,0x90,0x90,0x90,0x68,0x05, - 0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0x70,0x88,0x60,0x88,0x70,0x05,0x0a,0x0a, - 0x06,0x00,0xfe,0x10,0x20,0x00,0xb0,0xc8,0x88,0x88,0x88,0x08,0x08,0x03,0x08,0x08, - 0x06,0x01,0x00,0x40,0x80,0x00,0x80,0x80,0x80,0xa0,0x40}; + 0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0x70,0x88,0x60,0x88,0x70,0x05,0x0A,0x0A, + 0x06,0x00,0xFE,0x10,0x20,0x00,0xB0,0xC8,0x88,0x88,0x88,0x08,0x08,0x03,0x08,0x08, + 0x06,0x01,0x00,0x40,0x80,0x00,0x80,0x80,0x80,0xA0,0x40}; const u8g_fntpgm_uint8_t fontpage_7_177_181[80] U8G_FONT_SECTION("fontpage_7_177_181") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb1,0xb5,0x00,0x07,0xfe,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB1,0xB5,0x00,0x07,0xFE,0x00, 0x00,0x05,0x05,0x05,0x06,0x00,0x00,0x68,0x90,0x90,0x90,0x68,0x05,0x09,0x09,0x06, - 0x00,0xfe,0x60,0x90,0x90,0xb0,0x88,0x88,0xf0,0x80,0x80,0x05,0x07,0x07,0x06,0x00, - 0xfe,0x88,0x88,0x50,0x50,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x80, + 0x00,0xFE,0x60,0x90,0x90,0xB0,0x88,0x88,0xF0,0x80,0x80,0x05,0x07,0x07,0x06,0x00, + 0xFE,0x88,0x88,0x50,0x50,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x80, 0x70,0x88,0x88,0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x88,0x60,0x88,0x70 }; const u8g_fntpgm_uint8_t fontpage_7_183_199[226] U8G_FONT_SECTION("fontpage_7_183_199") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb7,0xc7,0x00,0x09,0xfe,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0xfe,0xb0,0xc8,0x88,0x88,0x88,0x08,0x08,0x04,0x07, - 0x07,0x06,0x01,0x00,0x60,0x90,0x90,0xf0,0x90,0x90,0x60,0x03,0x05,0x05,0x06,0x02, - 0x00,0x80,0x80,0x80,0xa0,0x40,0x04,0x05,0x05,0x06,0x01,0x00,0x90,0xa0,0xc0,0xa0, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB7,0xC7,0x00,0x09,0xFE,0x00, + 0x00,0x05,0x07,0x07,0x06,0x00,0xFE,0xB0,0xC8,0x88,0x88,0x88,0x08,0x08,0x04,0x07, + 0x07,0x06,0x01,0x00,0x60,0x90,0x90,0xF0,0x90,0x90,0x60,0x03,0x05,0x05,0x06,0x02, + 0x00,0x80,0x80,0x80,0xA0,0x40,0x04,0x05,0x05,0x06,0x01,0x00,0x90,0xA0,0xC0,0xA0, 0x90,0x05,0x09,0x09,0x06,0x00,0x00,0x80,0x40,0x40,0x20,0x20,0x50,0x50,0x88,0x88, - 0x05,0x07,0x07,0x06,0x00,0xfe,0x88,0x88,0x88,0x98,0xe8,0x80,0x80,0x05,0x05,0x05, - 0x06,0x00,0x00,0x88,0x88,0x50,0x50,0x20,0x05,0x09,0x09,0x06,0x00,0xfe,0xf8,0x20, + 0x05,0x07,0x07,0x06,0x00,0xFE,0x88,0x88,0x88,0x98,0xE8,0x80,0x80,0x05,0x05,0x05, + 0x06,0x00,0x00,0x88,0x88,0x50,0x50,0x20,0x05,0x09,0x09,0x06,0x00,0xFE,0xF8,0x20, 0x40,0x70,0x80,0x80,0x70,0x08,0x10,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x88,0x88, - 0x88,0x70,0x06,0x05,0x05,0x06,0x00,0x00,0xf8,0x50,0x50,0x54,0x48,0x05,0x07,0x07, - 0x06,0x00,0xfe,0x70,0x88,0x88,0xc8,0xb0,0x80,0x80,0x05,0x07,0x07,0x06,0x00,0xfe, + 0x88,0x70,0x06,0x05,0x05,0x06,0x00,0x00,0xF8,0x50,0x50,0x54,0x48,0x05,0x07,0x07, + 0x06,0x00,0xFE,0x70,0x88,0x88,0xC8,0xB0,0x80,0x80,0x05,0x07,0x07,0x06,0x00,0xFE, 0x70,0x88,0x80,0x80,0x70,0x08,0x30,0x05,0x05,0x05,0x06,0x00,0x00,0x78,0x90,0x88, - 0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xf8,0x20,0x20,0x28,0x10,0x05,0x05,0x05, - 0x06,0x00,0x00,0x90,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0xfe,0x10,0xa8, - 0xa8,0xa8,0x70,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0xfe,0x88,0x88,0x50,0x20,0x50, + 0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xF8,0x20,0x20,0x28,0x10,0x05,0x05,0x05, + 0x06,0x00,0x00,0x90,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0xFE,0x10,0xA8, + 0xA8,0xA8,0x70,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0xFE,0x88,0x88,0x50,0x20,0x50, 0x88,0x88}; const u8g_fntpgm_uint8_t fontpage_7_201_201[28] U8G_FONT_SECTION("fontpage_7_201_201") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc9,0xc9,0x00,0x05,0x00,0x00, - 0x00,0x05,0x05,0x05,0x06,0x00,0x00,0x50,0x88,0xa8,0xa8,0x50}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC9,0xC9,0x00,0x05,0x00,0x00, + 0x00,0x05,0x05,0x05,0x06,0x00,0x00,0x50,0x88,0xA8,0xA8,0x50}; const u8g_fntpgm_uint8_t fontpage_7_204_206[59] U8G_FONT_SECTION("fontpage_7_204_206") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcc,0xce,0x00,0x08,0x00,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCC,0xCE,0x00,0x08,0x00,0x00, 0x00,0x05,0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0x70,0x88,0x88,0x88,0x70,0x05, 0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0x90,0x88,0x88,0x88,0x70,0x05,0x08,0x08, - 0x06,0x00,0x00,0x10,0x20,0x00,0x50,0x88,0xa8,0xa8,0x50}; + 0x06,0x00,0x00,0x10,0x20,0x00,0x50,0x88,0xA8,0xA8,0x50}; const u8g_fntpgm_uint8_t fontpage_64_166_166[24] U8G_FONT_SECTION("fontpage_64_166_166") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa6,0xa6,0x00,0x01,0x00,0x00, - 0x00,0x05,0x01,0x01,0x06,0x00,0x00,0xa8}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA6,0xA6,0x00,0x01,0x00,0x00, + 0x00,0x05,0x01,0x01,0x06,0x00,0x00,0xA8}; #define FONTDATA_ITEM(page, begin, end, data) { page, begin, end, COUNT(data), data } static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { @@ -84,7 +81,6 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(7, 145, 157, fontpage_7_145_157), // 'Α' -- 'Ν' FONTDATA_ITEM(7, 159, 161, fontpage_7_159_161), // 'Ο' -- 'Ρ' FONTDATA_ITEM(7, 163, 167, fontpage_7_163_167), // 'Σ' -- 'Χ' - FONTDATA_ITEM(7, 169, 169, fontpage_7_169_169), // 'Ω' -- 'Ω' FONTDATA_ITEM(7, 172, 175, fontpage_7_172_175), // 'ά' -- 'ί' FONTDATA_ITEM(7, 177, 181, fontpage_7_177_181), // 'α' -- 'ε' FONTDATA_ITEM(7, 183, 199, fontpage_7_183_199), // 'η' -- 'χ' diff --git a/Marlin/src/lcd/dogm/fontdata/langdata_el_gr.h b/Marlin/src/lcd/dogm/fontdata/langdata_el_gr.h index 76a5c66cd952..4b545f228436 100644 --- a/Marlin/src/lcd/dogm/fontdata/langdata_el_gr.h +++ b/Marlin/src/lcd/dogm/fontdata/langdata_el_gr.h @@ -6,74 +6,74 @@ #include const u8g_fntpgm_uint8_t fontpage_7_136_136[33] U8G_FONT_SECTION("fontpage_7_136_136") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x06,0x00,0x00,0x40,0x80,0x00,0xf8,0x80,0x80,0xf0,0x80,0x80, - 0xf8}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x0A,0x0A,0x06,0x00,0x00,0x40,0x80,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80, + 0xF8}; const u8g_fntpgm_uint8_t fontpage_7_145_157[186] U8G_FONT_SECTION("fontpage_7_145_157") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x91,0x9d,0x00,0x07,0x00,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0xf8,0x88,0x88,0x88,0x05,0x07, - 0x07,0x06,0x00,0x00,0xf0,0x88,0x88,0xf0,0x88,0x88,0xf0,0x05,0x07,0x07,0x06,0x00, - 0x00,0xf8,0x80,0x80,0x80,0x80,0x80,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x20, - 0x50,0x50,0x88,0x88,0xf8,0x05,0x07,0x07,0x06,0x00,0x00,0xf8,0x80,0x80,0xf0,0x80, - 0x80,0xf8,0x05,0x07,0x07,0x06,0x00,0x00,0xf8,0x08,0x10,0x20,0x40,0x80,0xf8,0x05, - 0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x05,0x07,0x07,0x06, - 0x00,0x00,0x70,0x88,0x88,0xf8,0x88,0x88,0x70,0x03,0x07,0x07,0x06,0x01,0x00,0xe0, - 0x40,0x40,0x40,0x40,0x40,0xe0,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x90,0xa0,0xc0, - 0xa0,0x90,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x20,0x50,0x50,0x88,0x88,0x88, - 0x05,0x07,0x07,0x06,0x00,0x00,0x88,0xd8,0xa8,0x88,0x88,0x88,0x88,0x05,0x07,0x07, - 0x06,0x00,0x00,0x88,0x88,0xc8,0xa8,0x98,0x88,0x88}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x91,0x9D,0x00,0x07,0x00,0x00, + 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0xF8,0x88,0x88,0x88,0x05,0x07, + 0x07,0x06,0x00,0x00,0xF0,0x88,0x88,0xF0,0x88,0x88,0xF0,0x05,0x07,0x07,0x06,0x00, + 0x00,0xF8,0x80,0x80,0x80,0x80,0x80,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x20, + 0x50,0x50,0x88,0x88,0xF8,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x80,0x80,0xF0,0x80, + 0x80,0xF8,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x08,0x10,0x20,0x40,0x80,0xF8,0x05, + 0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x05,0x07,0x07,0x06, + 0x00,0x00,0x70,0x88,0x88,0xF8,0x88,0x88,0x70,0x03,0x07,0x07,0x06,0x01,0x00,0xE0, + 0x40,0x40,0x40,0x40,0x40,0xE0,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x90,0xA0,0xC0, + 0xA0,0x90,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x20,0x50,0x50,0x88,0x88,0x88, + 0x05,0x07,0x07,0x06,0x00,0x00,0x88,0xD8,0xA8,0x88,0x88,0x88,0x88,0x05,0x07,0x07, + 0x06,0x00,0x00,0x88,0x88,0xC8,0xA8,0x98,0x88,0x88}; const u8g_fntpgm_uint8_t fontpage_7_159_161[56] U8G_FONT_SECTION("fontpage_7_159_161") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9f,0xa1,0x00,0x07,0x00,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9F,0xA1,0x00,0x07,0x00,0x00, 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x07, - 0x07,0x06,0x00,0x00,0xf8,0x88,0x88,0x88,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00, - 0x00,0xf0,0x88,0x88,0xf0,0x80,0x80,0x80}; + 0x07,0x06,0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00, + 0x00,0xF0,0x88,0x88,0xF0,0x80,0x80,0x80}; const u8g_fntpgm_uint8_t fontpage_7_163_167[82] U8G_FONT_SECTION("fontpage_7_163_167") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa3,0xa7,0x00,0x07,0x00,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0xf8,0x40,0x20,0x10,0x20,0x40,0xf8,0x05,0x07, - 0x07,0x06,0x00,0x00,0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA3,0xA7,0x00,0x07,0x00,0x00, + 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x40,0x20,0x10,0x20,0x40,0xF8,0x05,0x07, + 0x07,0x06,0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00, 0x00,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x70, - 0xa8,0xa8,0xa8,0x70,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x50,0x20,0x50, + 0xA8,0xA8,0xA8,0x70,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x50,0x20,0x50, 0x88,0x88}; const u8g_fntpgm_uint8_t fontpage_7_172_175[75] U8G_FONT_SECTION("fontpage_7_172_175") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xac,0xaf,0x00,0x08,0xfe,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAC,0xAF,0x00,0x08,0xFE,0x00, 0x00,0x05,0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0x68,0x90,0x90,0x90,0x68,0x05, - 0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0x70,0x88,0x60,0x88,0x70,0x05,0x0a,0x0a, - 0x06,0x00,0xfe,0x10,0x20,0x00,0xb0,0xc8,0x88,0x88,0x88,0x08,0x08,0x03,0x08,0x08, - 0x06,0x01,0x00,0x40,0x80,0x00,0x80,0x80,0x80,0xa0,0x40}; + 0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0x70,0x88,0x60,0x88,0x70,0x05,0x0A,0x0A, + 0x06,0x00,0xFE,0x10,0x20,0x00,0xB0,0xC8,0x88,0x88,0x88,0x08,0x08,0x03,0x08,0x08, + 0x06,0x01,0x00,0x40,0x80,0x00,0x80,0x80,0x80,0xA0,0x40}; const u8g_fntpgm_uint8_t fontpage_7_177_181[80] U8G_FONT_SECTION("fontpage_7_177_181") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb1,0xb5,0x00,0x07,0xfe,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB1,0xB5,0x00,0x07,0xFE,0x00, 0x00,0x05,0x05,0x05,0x06,0x00,0x00,0x68,0x90,0x90,0x90,0x68,0x05,0x09,0x09,0x06, - 0x00,0xfe,0x60,0x90,0x90,0xb0,0x88,0x88,0xf0,0x80,0x80,0x05,0x07,0x07,0x06,0x00, - 0xfe,0x88,0x88,0x50,0x50,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x80, + 0x00,0xFE,0x60,0x90,0x90,0xB0,0x88,0x88,0xF0,0x80,0x80,0x05,0x07,0x07,0x06,0x00, + 0xFE,0x88,0x88,0x50,0x50,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x80, 0x70,0x88,0x88,0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x88,0x60,0x88,0x70 }; const u8g_fntpgm_uint8_t fontpage_7_183_199[226] U8G_FONT_SECTION("fontpage_7_183_199") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb7,0xc7,0x00,0x09,0xfe,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0xfe,0xb0,0xc8,0x88,0x88,0x88,0x08,0x08,0x04,0x07, - 0x07,0x06,0x01,0x00,0x60,0x90,0x90,0xf0,0x90,0x90,0x60,0x03,0x05,0x05,0x06,0x02, - 0x00,0x80,0x80,0x80,0xa0,0x40,0x04,0x05,0x05,0x06,0x01,0x00,0x90,0xa0,0xc0,0xa0, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB7,0xC7,0x00,0x09,0xFE,0x00, + 0x00,0x05,0x07,0x07,0x06,0x00,0xFE,0xB0,0xC8,0x88,0x88,0x88,0x08,0x08,0x04,0x07, + 0x07,0x06,0x01,0x00,0x60,0x90,0x90,0xF0,0x90,0x90,0x60,0x03,0x05,0x05,0x06,0x02, + 0x00,0x80,0x80,0x80,0xA0,0x40,0x04,0x05,0x05,0x06,0x01,0x00,0x90,0xA0,0xC0,0xA0, 0x90,0x05,0x09,0x09,0x06,0x00,0x00,0x80,0x40,0x40,0x20,0x20,0x50,0x50,0x88,0x88, - 0x05,0x07,0x07,0x06,0x00,0xfe,0x88,0x88,0x88,0x98,0xe8,0x80,0x80,0x05,0x05,0x05, - 0x06,0x00,0x00,0x88,0x88,0x50,0x50,0x20,0x05,0x09,0x09,0x06,0x00,0xfe,0xf8,0x20, + 0x05,0x07,0x07,0x06,0x00,0xFE,0x88,0x88,0x88,0x98,0xE8,0x80,0x80,0x05,0x05,0x05, + 0x06,0x00,0x00,0x88,0x88,0x50,0x50,0x20,0x05,0x09,0x09,0x06,0x00,0xFE,0xF8,0x20, 0x40,0x70,0x80,0x80,0x70,0x08,0x10,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x88,0x88, - 0x88,0x70,0x06,0x05,0x05,0x06,0x00,0x00,0xf8,0x50,0x50,0x54,0x48,0x05,0x07,0x07, - 0x06,0x00,0xfe,0x70,0x88,0x88,0xc8,0xb0,0x80,0x80,0x05,0x07,0x07,0x06,0x00,0xfe, + 0x88,0x70,0x06,0x05,0x05,0x06,0x00,0x00,0xF8,0x50,0x50,0x54,0x48,0x05,0x07,0x07, + 0x06,0x00,0xFE,0x70,0x88,0x88,0xC8,0xB0,0x80,0x80,0x05,0x07,0x07,0x06,0x00,0xFE, 0x70,0x88,0x80,0x80,0x70,0x08,0x30,0x05,0x05,0x05,0x06,0x00,0x00,0x78,0x90,0x88, - 0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xf8,0x20,0x20,0x28,0x10,0x05,0x05,0x05, - 0x06,0x00,0x00,0x90,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0xfe,0x10,0xa8, - 0xa8,0xa8,0x70,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0xfe,0x88,0x88,0x50,0x20,0x50, + 0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xF8,0x20,0x20,0x28,0x10,0x05,0x05,0x05, + 0x06,0x00,0x00,0x90,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0xFE,0x10,0xA8, + 0xA8,0xA8,0x70,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0xFE,0x88,0x88,0x50,0x20,0x50, 0x88,0x88}; const u8g_fntpgm_uint8_t fontpage_7_201_201[28] U8G_FONT_SECTION("fontpage_7_201_201") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc9,0xc9,0x00,0x05,0x00,0x00, - 0x00,0x05,0x05,0x05,0x06,0x00,0x00,0x50,0x88,0xa8,0xa8,0x50}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC9,0xC9,0x00,0x05,0x00,0x00, + 0x00,0x05,0x05,0x05,0x06,0x00,0x00,0x50,0x88,0xA8,0xA8,0x50}; const u8g_fntpgm_uint8_t fontpage_7_204_206[59] U8G_FONT_SECTION("fontpage_7_204_206") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcc,0xce,0x00,0x08,0x00,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCC,0xCE,0x00,0x08,0x00,0x00, 0x00,0x05,0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0x70,0x88,0x88,0x88,0x70,0x05, 0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0x90,0x88,0x88,0x88,0x70,0x05,0x08,0x08, - 0x06,0x00,0x00,0x10,0x20,0x00,0x50,0x88,0xa8,0xa8,0x50}; + 0x06,0x00,0x00,0x10,0x20,0x00,0x50,0x88,0xA8,0xA8,0x50}; const u8g_fntpgm_uint8_t fontpage_64_166_166[24] U8G_FONT_SECTION("fontpage_64_166_166") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa6,0xa6,0x00,0x01,0x00,0x00, - 0x00,0x05,0x01,0x01,0x06,0x00,0x00,0xa8}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA6,0xA6,0x00,0x01,0x00,0x00, + 0x00,0x05,0x01,0x01,0x06,0x00,0x00,0xA8}; #define FONTDATA_ITEM(page, begin, end, data) { page, begin, end, COUNT(data), data } static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { diff --git a/Marlin/src/lcd/dogm/fontdata/langdata_hr.h b/Marlin/src/lcd/dogm/fontdata/langdata_hr.h index 63fea945b2f7..cdb2cc7d1ade 100644 --- a/Marlin/src/lcd/dogm/fontdata/langdata_hr.h +++ b/Marlin/src/lcd/dogm/fontdata/langdata_hr.h @@ -6,21 +6,21 @@ #include const u8g_fntpgm_uint8_t fontpage_2_135_135[31] U8G_FONT_SECTION("fontpage_2_135_135") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x87,0x87,0x00,0x08,0x00,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x87,0x87,0x00,0x08,0x00,0x00, 0x00,0x05,0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0x70,0x88,0x80,0x88,0x70}; const u8g_fntpgm_uint8_t fontpage_2_140_141[47] U8G_FONT_SECTION("fontpage_2_140_141") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8c,0x8d,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x06,0x00,0x00,0x50,0x20,0x00,0x70,0x88,0x80,0x80,0x80,0x88, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8C,0x8D,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x0A,0x0A,0x06,0x00,0x00,0x50,0x20,0x00,0x70,0x88,0x80,0x80,0x80,0x88, 0x70,0x05,0x08,0x08,0x06,0x00,0x00,0x50,0x20,0x00,0x70,0x88,0x80,0x88,0x70}; const u8g_fntpgm_uint8_t fontpage_2_145_145[31] U8G_FONT_SECTION("fontpage_2_145_145") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x91,0x91,0x00,0x08,0x00,0x00, - 0x00,0x06,0x08,0x08,0x06,0x00,0x00,0x08,0x1c,0x08,0x78,0x88,0x88,0x88,0x78}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x91,0x91,0x00,0x08,0x00,0x00, + 0x00,0x06,0x08,0x08,0x06,0x00,0x00,0x08,0x1C,0x08,0x78,0x88,0x88,0x88,0x78}; const u8g_fntpgm_uint8_t fontpage_2_225_225[31] U8G_FONT_SECTION("fontpage_2_225_225") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe1,0xe1,0x00,0x08,0x00,0x00, - 0x00,0x05,0x08,0x08,0x06,0x00,0x00,0x50,0x20,0x00,0x78,0x80,0x70,0x08,0xf0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE1,0xE1,0x00,0x08,0x00,0x00, + 0x00,0x05,0x08,0x08,0x06,0x00,0x00,0x50,0x20,0x00,0x78,0x80,0x70,0x08,0xF0}; const u8g_fntpgm_uint8_t fontpage_2_254_254[31] U8G_FONT_SECTION("fontpage_2_254_254") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfe,0xfe,0x00,0x08,0x00,0x00, - 0x00,0x05,0x08,0x08,0x06,0x00,0x00,0x50,0x20,0x00,0xf8,0x10,0x20,0x40,0xf8}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x00,0x08,0x00,0x00, + 0x00,0x05,0x08,0x08,0x06,0x00,0x00,0x50,0x20,0x00,0xF8,0x10,0x20,0x40,0xF8}; #define FONTDATA_ITEM(page, begin, end, data) { page, begin, end, COUNT(data), data } static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { diff --git a/Marlin/src/lcd/dogm/fontdata/langdata_hu.h b/Marlin/src/lcd/dogm/fontdata/langdata_hu.h new file mode 100644 index 000000000000..8c15a3890ab0 --- /dev/null +++ b/Marlin/src/lcd/dogm/fontdata/langdata_hu.h @@ -0,0 +1,15 @@ +/** + * Generated automatically by buildroot/share/fonts/uxggenpages.sh + * Contents will be REPLACED by future processing! + * Use genallfont.sh to generate font data for updated languages. + */ +#include + +const u8g_fntpgm_uint8_t fontpage_2_241_241[31] U8G_FONT_SECTION("fontpage_2_241_241") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF1,0xF1,0x00,0x08,0x00,0x00, + 0x00,0x05,0x08,0x08,0x06,0x00,0x00,0x48,0x90,0x00,0x88,0x88,0x88,0x88,0x70}; + +#define FONTDATA_ITEM(page, begin, end, data) { page, begin, end, COUNT(data), data } +static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { + FONTDATA_ITEM(2, 241, 241, fontpage_2_241_241), // 'ű' -- 'ű' +}; diff --git a/Marlin/src/lcd/dogm/fontdata/langdata_jp_kana.h b/Marlin/src/lcd/dogm/fontdata/langdata_jp_kana.h index 97d82c0293dc..01316d4c1311 100644 --- a/Marlin/src/lcd/dogm/fontdata/langdata_jp_kana.h +++ b/Marlin/src/lcd/dogm/fontdata/langdata_jp_kana.h @@ -6,92 +6,92 @@ #include const u8g_fntpgm_uint8_t fontpage_97_161_164[65] U8G_FONT_SECTION("fontpage_97_161_164") = { - 0x00,0x0c,0x0f,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa1,0xa4,0x00,0x07,0x00,0x00, - 0x00,0x04,0x05,0x05,0x06,0x00,0x00,0xf0,0x10,0x60,0x40,0x80,0x05,0x07,0x07,0x06, - 0x00,0x00,0xf8,0x08,0x28,0x30,0x20,0x20,0x40,0x04,0x05,0x05,0x06,0x00,0x00,0x10, - 0x20,0x60,0xa0,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x08,0x10,0x20,0x60,0xa0,0x20, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA1,0xA4,0x00,0x07,0x00,0x00, + 0x00,0x04,0x05,0x05,0x06,0x00,0x00,0xF0,0x10,0x60,0x40,0x80,0x05,0x07,0x07,0x06, + 0x00,0x00,0xF8,0x08,0x28,0x30,0x20,0x20,0x40,0x04,0x05,0x05,0x06,0x00,0x00,0x10, + 0x20,0x60,0xA0,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x08,0x10,0x20,0x60,0xA0,0x20, 0x20}; const u8g_fntpgm_uint8_t fontpage_97_166_166[30] U8G_FONT_SECTION("fontpage_97_166_166") = { - 0x00,0x0c,0x0f,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa6,0xa6,0x00,0x07,0x00,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0xf8,0x88,0x88,0x08,0x10,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA6,0xA6,0x00,0x07,0x00,0x00, + 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0xF8,0x88,0x88,0x08,0x10,0x60}; const u8g_fntpgm_uint8_t fontpage_97_168_168[29] U8G_FONT_SECTION("fontpage_97_168_168") = { - 0x00,0x0c,0x0f,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa8,0xa8,0x00,0x06,0x00,0x00, - 0x00,0x05,0x06,0x06,0x06,0x00,0x00,0xf8,0x20,0x20,0x20,0x20,0xf8}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA8,0xA8,0x00,0x06,0x00,0x00, + 0x00,0x05,0x06,0x06,0x06,0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0xF8}; const u8g_fntpgm_uint8_t fontpage_97_170_187[268] U8G_FONT_SECTION("fontpage_97_170_187") = { - 0x00,0x0c,0x0f,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xaa,0xbb,0x00,0x0d,0x00,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x10,0xf8,0x10,0x30,0x50,0x90,0x10,0x05,0x07, - 0x07,0x06,0x00,0x00,0x40,0xf8,0x48,0x48,0x48,0x48,0x98,0x05,0x09,0x09,0x06,0x00, - 0x00,0x28,0x08,0x40,0xf8,0x48,0x48,0x48,0x48,0x98,0x05,0x07,0x07,0x06,0x00,0x00, - 0x20,0xf8,0x20,0x20,0xf8,0x10,0x10,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x08,0x20, - 0xf8,0x20,0x20,0xf8,0x10,0x10,0x05,0x07,0x07,0x06,0x00,0x00,0x40,0x78,0x48,0x88, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAA,0xBB,0x00,0x0D,0x00,0x00, + 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x10,0xF8,0x10,0x30,0x50,0x90,0x10,0x05,0x07, + 0x07,0x06,0x00,0x00,0x40,0xF8,0x48,0x48,0x48,0x48,0x98,0x05,0x09,0x09,0x06,0x00, + 0x00,0x28,0x08,0x40,0xF8,0x48,0x48,0x48,0x48,0x98,0x05,0x07,0x07,0x06,0x00,0x00, + 0x20,0xF8,0x20,0x20,0xF8,0x10,0x10,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x08,0x20, + 0xF8,0x20,0x20,0xF8,0x10,0x10,0x05,0x07,0x07,0x06,0x00,0x00,0x40,0x78,0x48,0x88, 0x08,0x10,0x60,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x08,0x40,0x78,0x48,0x88,0x08, - 0x10,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0xf8,0x90,0x90,0x10,0x10,0x20,0x05, - 0x09,0x09,0x06,0x00,0x00,0x28,0x28,0x80,0xf8,0x90,0x90,0x10,0x10,0x20,0x05,0x06, - 0x06,0x06,0x00,0x00,0xf8,0x08,0x08,0x08,0x08,0xf8,0x05,0x09,0x09,0x06,0x00,0x00, - 0x28,0x28,0x00,0xf8,0x08,0x08,0x08,0x08,0xf8,0x05,0x07,0x07,0x06,0x00,0x00,0x50, - 0xf8,0x50,0x50,0x50,0x10,0x20,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x08,0x50,0xf8, - 0x50,0x50,0x50,0x10,0x20,0x05,0x06,0x06,0x06,0x00,0x00,0xc0,0x08,0xc8,0x08,0x10, - 0xe0,0x07,0x0d,0x0d,0x06,0x00,0x00,0x02,0x00,0x00,0x00,0x28,0x28,0x00,0xc0,0x08, - 0xc8,0x08,0x10,0xe0,0x05,0x06,0x06,0x06,0x00,0x00,0x70,0x10,0x10,0x20,0x50,0x88, + 0x10,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0xF8,0x90,0x90,0x10,0x10,0x20,0x05, + 0x09,0x09,0x06,0x00,0x00,0x28,0x28,0x80,0xF8,0x90,0x90,0x10,0x10,0x20,0x05,0x06, + 0x06,0x06,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x05,0x09,0x09,0x06,0x00,0x00, + 0x28,0x28,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x05,0x07,0x07,0x06,0x00,0x00,0x50, + 0xF8,0x50,0x50,0x50,0x10,0x20,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x08,0x50,0xF8, + 0x50,0x50,0x50,0x10,0x20,0x05,0x06,0x06,0x06,0x00,0x00,0xC0,0x08,0xC8,0x08,0x10, + 0xE0,0x07,0x0D,0x0D,0x06,0x00,0x00,0x02,0x00,0x00,0x00,0x28,0x28,0x00,0xC0,0x08, + 0xC8,0x08,0x10,0xE0,0x05,0x06,0x06,0x06,0x00,0x00,0x70,0x10,0x10,0x20,0x50,0x88, 0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x28,0x00,0x70,0x10,0x10,0x20,0x50,0x88,0x05, - 0x07,0x07,0x06,0x00,0x00,0x40,0x40,0xf8,0x48,0x50,0x40,0x38}; + 0x07,0x07,0x06,0x00,0x00,0x40,0x40,0xF8,0x48,0x50,0x40,0x38}; const u8g_fntpgm_uint8_t fontpage_97_189_193[85] U8G_FONT_SECTION("fontpage_97_189_193") = { - 0x00,0x0c,0x0f,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbd,0xc1,0x00,0x09,0x00,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBD,0xC1,0x00,0x09,0x00,0x00, 0x00,0x05,0x06,0x06,0x06,0x00,0x00,0x88,0x48,0x48,0x10,0x10,0x20,0x05,0x09,0x09, 0x06,0x00,0x00,0x28,0x28,0x00,0x88,0x48,0x48,0x10,0x10,0x20,0x05,0x07,0x07,0x06, - 0x00,0x00,0x40,0x78,0x48,0xa8,0x18,0x10,0x60,0x05,0x09,0x09,0x06,0x00,0x00,0x28, - 0x08,0x40,0x78,0x48,0xa8,0x18,0x10,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x10,0x60, - 0x20,0xf8,0x20,0x20,0x40}; + 0x00,0x00,0x40,0x78,0x48,0xA8,0x18,0x10,0x60,0x05,0x09,0x09,0x06,0x00,0x00,0x28, + 0x08,0x40,0x78,0x48,0xA8,0x18,0x10,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x10,0x60, + 0x20,0xF8,0x20,0x20,0x40}; const u8g_fntpgm_uint8_t fontpage_97_195_211[241] U8G_FONT_SECTION("fontpage_97_195_211") = { - 0x00,0x0c,0x0f,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc3,0xd3,0x00,0x09,0x00,0x00, - 0x00,0x05,0x04,0x04,0x06,0x00,0x00,0xa8,0xa8,0x08,0x30,0x05,0x06,0x06,0x06,0x00, - 0x00,0xa8,0xa8,0xa8,0x08,0x10,0x60,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x28,0x00, - 0xa8,0xa8,0xa8,0x08,0x10,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x00,0xf8,0x20, - 0x20,0x20,0x40,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x08,0x70,0x00,0xf8,0x20,0x20, - 0x20,0x40,0x04,0x07,0x07,0x06,0x01,0x00,0x80,0x80,0xc0,0xa0,0x90,0x80,0x80,0x04, - 0x09,0x09,0x06,0x01,0x00,0x50,0x10,0x80,0x80,0xc0,0xa0,0x90,0x80,0x80,0x05,0x07, - 0x07,0x06,0x00,0x00,0x20,0x20,0xf8,0x20,0x20,0x40,0x80,0x05,0x06,0x06,0x06,0x00, - 0x00,0x70,0x00,0x00,0x00,0x00,0xf8,0x05,0x06,0x06,0x06,0x00,0x00,0x78,0x08,0x28, - 0x10,0x28,0xc0,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x70,0x10,0x20,0x70,0xa8,0x20, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC3,0xD3,0x00,0x09,0x00,0x00, + 0x00,0x05,0x04,0x04,0x06,0x00,0x00,0xA8,0xA8,0x08,0x30,0x05,0x06,0x06,0x06,0x00, + 0x00,0xA8,0xA8,0xA8,0x08,0x10,0x60,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x28,0x00, + 0xA8,0xA8,0xA8,0x08,0x10,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x00,0xF8,0x20, + 0x20,0x20,0x40,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x08,0x70,0x00,0xF8,0x20,0x20, + 0x20,0x40,0x04,0x07,0x07,0x06,0x01,0x00,0x80,0x80,0xC0,0xA0,0x90,0x80,0x80,0x04, + 0x09,0x09,0x06,0x01,0x00,0x50,0x10,0x80,0x80,0xC0,0xA0,0x90,0x80,0x80,0x05,0x07, + 0x07,0x06,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x40,0x80,0x05,0x06,0x06,0x06,0x00, + 0x00,0x70,0x00,0x00,0x00,0x00,0xF8,0x05,0x06,0x06,0x06,0x00,0x00,0x78,0x08,0x28, + 0x10,0x28,0xC0,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x70,0x10,0x20,0x70,0xA8,0x20, 0x03,0x06,0x06,0x06,0x01,0x00,0x20,0x20,0x20,0x40,0x40,0x80,0x05,0x06,0x06,0x06, 0x00,0x00,0x10,0x50,0x50,0x48,0x88,0x88,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x28, 0x00,0x10,0x50,0x50,0x48,0x88,0x88,0x05,0x09,0x09,0x06,0x00,0x00,0x18,0x18,0x00, - 0x10,0x50,0x50,0x48,0x88,0x88,0x04,0x06,0x06,0x06,0x00,0x00,0x80,0x90,0xe0,0x80, - 0x80,0x70,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x28,0x00,0x80,0x90,0xe0,0x80,0x80, + 0x10,0x50,0x50,0x48,0x88,0x88,0x04,0x06,0x06,0x06,0x00,0x00,0x80,0x90,0xE0,0x80, + 0x80,0x70,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x28,0x00,0x80,0x90,0xE0,0x80,0x80, 0x70}; const u8g_fntpgm_uint8_t fontpage_97_213_217[84] U8G_FONT_SECTION("fontpage_97_213_217") = { - 0x00,0x0c,0x0f,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd5,0xd9,0x00,0x09,0x00,0x00, - 0x00,0x05,0x06,0x06,0x06,0x00,0x00,0xf8,0x08,0x08,0x08,0x10,0x60,0x05,0x09,0x09, - 0x06,0x00,0x00,0x28,0x28,0x00,0xf8,0x08,0x08,0x08,0x10,0x60,0x05,0x09,0x09,0x06, - 0x00,0x00,0x18,0x18,0x00,0xf8,0x08,0x08,0x08,0x10,0x60,0x05,0x05,0x05,0x06,0x00, - 0x01,0x60,0xa0,0x10,0x10,0x08,0x05,0x08,0x08,0x06,0x00,0x01,0x28,0x28,0x00,0x60, - 0xa0,0x10,0x10,0x08}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD5,0xD9,0x00,0x09,0x00,0x00, + 0x00,0x05,0x06,0x06,0x06,0x00,0x00,0xF8,0x08,0x08,0x08,0x10,0x60,0x05,0x09,0x09, + 0x06,0x00,0x00,0x28,0x28,0x00,0xF8,0x08,0x08,0x08,0x10,0x60,0x05,0x09,0x09,0x06, + 0x00,0x00,0x18,0x18,0x00,0xF8,0x08,0x08,0x08,0x10,0x60,0x05,0x05,0x05,0x06,0x00, + 0x01,0x60,0xA0,0x10,0x10,0x08,0x05,0x08,0x08,0x06,0x00,0x01,0x28,0x28,0x00,0x60, + 0xA0,0x10,0x10,0x08}; const u8g_fntpgm_uint8_t fontpage_97_219_220[45] U8G_FONT_SECTION("fontpage_97_219_220") = { - 0x00,0x0c,0x0f,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xdb,0xdc,0x00,0x09,0x00,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0xf8,0x20,0xa8,0xa8,0xa8,0x20,0x05,0x09, - 0x09,0x06,0x00,0x00,0x28,0x08,0x20,0xf8,0x20,0xa8,0xa8,0xa8,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDB,0xDC,0x00,0x09,0x00,0x00, + 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0xF8,0x20,0xA8,0xA8,0xA8,0x20,0x05,0x09, + 0x09,0x06,0x00,0x00,0x28,0x08,0x20,0xF8,0x20,0xA8,0xA8,0xA8,0x20}; const u8g_fntpgm_uint8_t fontpage_97_222_223[41] U8G_FONT_SECTION("fontpage_97_222_223") = { - 0x00,0x0c,0x0f,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xde,0xdf,0x00,0x06,0x00,0x00, - 0x00,0x05,0x06,0x06,0x06,0x00,0x00,0xf8,0x08,0x08,0x50,0x20,0x10,0x04,0x06,0x06, - 0x06,0x01,0x00,0xe0,0x00,0xe0,0x00,0xc0,0x30}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDE,0xDF,0x00,0x06,0x00,0x00, + 0x00,0x05,0x06,0x06,0x06,0x00,0x00,0xF8,0x08,0x08,0x50,0x20,0x10,0x04,0x06,0x06, + 0x06,0x01,0x00,0xE0,0x00,0xE0,0x00,0xC0,0x30}; const u8g_fntpgm_uint8_t fontpage_97_225_237[174] U8G_FONT_SECTION("fontpage_97_225_237") = { - 0x00,0x0c,0x0f,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe1,0xed,0x00,0x07,0x00,0x00, - 0x00,0x05,0x06,0x06,0x06,0x00,0x00,0x08,0x48,0x30,0x10,0x28,0xc0,0x05,0x06,0x06, - 0x06,0x00,0x00,0xf0,0x40,0xf8,0x40,0x40,0x38,0x05,0x05,0x05,0x06,0x00,0x00,0x40, - 0xf8,0x48,0x50,0x40,0x05,0x07,0x07,0x06,0x00,0x00,0x40,0x40,0xf8,0x48,0x50,0x40, - 0x40,0x04,0x05,0x05,0x06,0x00,0x00,0x60,0x20,0x20,0x20,0xf0,0x05,0x06,0x06,0x06, - 0x00,0x00,0x70,0x10,0x10,0x10,0x10,0xf8,0x04,0x05,0x05,0x06,0x00,0x00,0xf0,0x10, - 0xf0,0x10,0xf0,0x05,0x06,0x06,0x06,0x00,0x00,0xf8,0x08,0xf8,0x08,0x08,0xf8,0x05, - 0x07,0x07,0x06,0x00,0x00,0x70,0x00,0xf8,0x08,0x08,0x10,0x60,0x04,0x07,0x07,0x06, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE1,0xED,0x00,0x07,0x00,0x00, + 0x00,0x05,0x06,0x06,0x06,0x00,0x00,0x08,0x48,0x30,0x10,0x28,0xC0,0x05,0x06,0x06, + 0x06,0x00,0x00,0xF0,0x40,0xF8,0x40,0x40,0x38,0x05,0x05,0x05,0x06,0x00,0x00,0x40, + 0xF8,0x48,0x50,0x40,0x05,0x07,0x07,0x06,0x00,0x00,0x40,0x40,0xF8,0x48,0x50,0x40, + 0x40,0x04,0x05,0x05,0x06,0x00,0x00,0x60,0x20,0x20,0x20,0xF0,0x05,0x06,0x06,0x06, + 0x00,0x00,0x70,0x10,0x10,0x10,0x10,0xF8,0x04,0x05,0x05,0x06,0x00,0x00,0xF0,0x10, + 0xF0,0x10,0xF0,0x05,0x06,0x06,0x06,0x00,0x00,0xF8,0x08,0xF8,0x08,0x08,0xF8,0x05, + 0x07,0x07,0x06,0x00,0x00,0x70,0x00,0xF8,0x08,0x08,0x10,0x60,0x04,0x07,0x07,0x06, 0x00,0x00,0x10,0x90,0x90,0x90,0x90,0x10,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x20, - 0x20,0xa0,0xa0,0xa8,0xa8,0xb0,0x05,0x06,0x06,0x06,0x00,0x00,0x80,0x80,0x80,0x88, - 0xb0,0xc0,0x05,0x06,0x06,0x06,0x00,0x00,0xf8,0x88,0x88,0x88,0x88,0xf8}; + 0x20,0xA0,0xA0,0xA8,0xA8,0xB0,0x05,0x06,0x06,0x06,0x00,0x00,0x80,0x80,0x80,0x88, + 0xB0,0xC0,0x05,0x06,0x06,0x06,0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0xF8}; const u8g_fntpgm_uint8_t fontpage_97_242_243[41] U8G_FONT_SECTION("fontpage_97_242_243") = { - 0x00,0x0c,0x0f,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf2,0xf3,0x00,0x06,0x00,0x00, - 0x00,0x05,0x06,0x06,0x06,0x00,0x00,0xf8,0x08,0xf8,0x08,0x10,0x60,0x05,0x06,0x06, - 0x06,0x00,0x00,0xc0,0x08,0x08,0x08,0x10,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF2,0xF3,0x00,0x06,0x00,0x00, + 0x00,0x05,0x06,0x06,0x06,0x00,0x00,0xF8,0x08,0xF8,0x08,0x10,0x60,0x05,0x06,0x06, + 0x06,0x00,0x00,0xC0,0x08,0x08,0x08,0x10,0xE0}; const u8g_fntpgm_uint8_t fontpage_97_252_252[25] U8G_FONT_SECTION("fontpage_97_252_252") = { - 0x00,0x0c,0x0f,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfc,0xfc,0x00,0x05,0x00,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFC,0xFC,0x00,0x05,0x00,0x00, 0x00,0x05,0x02,0x02,0x06,0x00,0x03,0x80,0x78}; #define FONTDATA_ITEM(page, begin, end, data) { page, begin, end, COUNT(data), data } diff --git a/Marlin/src/lcd/dogm/fontdata/langdata_ko_KR.h b/Marlin/src/lcd/dogm/fontdata/langdata_ko_KR.h index 9f20e7b40134..6b48434a6f58 100644 --- a/Marlin/src/lcd/dogm/fontdata/langdata_ko_KR.h +++ b/Marlin/src/lcd/dogm/fontdata/langdata_ko_KR.h @@ -6,422 +6,434 @@ #include const u8g_fntpgm_uint8_t fontpage_344_240_240[34] U8G_FONT_SECTION("fontpage_344_240_240") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xf0,0xf0,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0xf9,0x09,0x09,0x11,0x17,0x21,0x41,0x81,0x01, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF9,0x09,0x09,0x11,0x17,0x21,0x41,0x81,0x01, 0x01,0x01}; const u8g_fntpgm_uint8_t fontpage_345_224_224[41] U8G_FONT_SECTION("fontpage_345_224_224") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xe0,0xe0,0x00,0x09,0x00,0x00, - 0x00,0x0a,0x09,0x12,0x0a,0x00,0x00,0x3f,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x08, - 0x80,0x08,0x80,0x09,0x00,0x08,0x00,0xff,0xc0}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x00,0x09,0x00,0x00, + 0x00,0x0A,0x09,0x12,0x0A,0x00,0x00,0x3F,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x08, + 0x80,0x08,0x80,0x09,0x00,0x08,0x00,0xFF,0xC0}; const u8g_fntpgm_uint8_t fontpage_347_248_248[41] U8G_FONT_SECTION("fontpage_347_248_248") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xf8,0xf8,0x00,0x09,0x00,0x00, - 0x00,0x0a,0x09,0x12,0x0a,0x00,0x00,0x3f,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00, - 0x80,0x01,0x00,0x01,0x00,0x01,0x00,0xff,0xc0}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0x00,0x09,0x00,0x00, + 0x00,0x0A,0x09,0x12,0x0A,0x00,0x00,0x3F,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00, + 0x80,0x01,0x00,0x01,0x00,0x01,0x00,0xFF,0xC0}; const u8g_fntpgm_uint8_t fontpage_348_137_137[45] U8G_FONT_SECTION("fontpage_348_137_137") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x09,0xfe,0x00, - 0x00,0x0a,0x0b,0x16,0x0a,0x00,0xfe,0x3f,0x00,0x00,0x80,0x00,0x80,0x01,0x00,0xff, - 0xc0,0x00,0x00,0x20,0x80,0x20,0x80,0x3f,0x00,0x20,0x80,0x3f,0x00}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x09,0xFE,0x00, + 0x00,0x0A,0x0B,0x16,0x0A,0x00,0xFE,0x3F,0x00,0x00,0x80,0x00,0x80,0x01,0x00,0xFF, + 0xC0,0x00,0x00,0x20,0x80,0x20,0x80,0x3F,0x00,0x20,0x80,0x3F,0x00}; const u8g_fntpgm_uint8_t fontpage_348_176_176[34] U8G_FONT_SECTION("fontpage_348_176_176") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xb0,0xb0,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0xf9,0x09,0x09,0x11,0x11,0x21,0x41,0x81,0x01, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xB0,0xB0,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF9,0x09,0x09,0x11,0x11,0x21,0x41,0x81,0x01, 0x01,0x01}; const u8g_fntpgm_uint8_t fontpage_348_197_197[34] U8G_FONT_SECTION("fontpage_348_197_197") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xc5,0xc5,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0xf9,0x09,0x09,0x11,0x21,0xc1,0x1e,0x21,0x41, - 0x21,0x1e}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xC5,0xC5,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF9,0x09,0x09,0x11,0x21,0xC1,0x1E,0x21,0x41, + 0x21,0x1E}; const u8g_fntpgm_uint8_t fontpage_352_196_196[41] U8G_FONT_SECTION("fontpage_352_196_196") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xc4,0xc4,0x00,0x09,0x00,0x00, - 0x00,0x0a,0x09,0x12,0x0a,0x00,0x00,0x7f,0x80,0x08,0x80,0x08,0x80,0x08,0x80,0x08, - 0x80,0x08,0x80,0x10,0x80,0x11,0x00,0xff,0xc0}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xC4,0xC4,0x00,0x09,0x00,0x00, + 0x00,0x0A,0x09,0x12,0x0A,0x00,0x00,0x7F,0x80,0x08,0x80,0x08,0x80,0x08,0x80,0x08, + 0x80,0x08,0x80,0x10,0x80,0x11,0x00,0xFF,0xC0}; const u8g_fntpgm_uint8_t fontpage_353_180_180[34] U8G_FONT_SECTION("fontpage_353_180_180") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xb4,0xb4,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x85,0x85,0x85,0x85,0x87,0x85,0x85,0xfd,0x05, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xB4,0xB4,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0x85,0x85,0x85,0x85,0x87,0x85,0x85,0xFD,0x05, 0x05,0x05}; const u8g_fntpgm_uint8_t fontpage_354_248_248[41] U8G_FONT_SECTION("fontpage_354_248_248") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xf8,0xf8,0x00,0x09,0x00,0x00, - 0x00,0x0a,0x09,0x12,0x0a,0x00,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x3f, - 0x80,0x04,0x00,0x04,0x00,0x04,0x00,0xff,0xc0}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0x00,0x09,0x00,0x00, + 0x00,0x0A,0x09,0x12,0x0A,0x00,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x3F, + 0x80,0x04,0x00,0x04,0x00,0x04,0x00,0xFF,0xC0}; const u8g_fntpgm_uint8_t fontpage_356_132_132[43] U8G_FONT_SECTION("fontpage_356_132_132") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x84,0x84,0x00,0x09,0xff,0x00, - 0x00,0x0a,0x0a,0x14,0x0a,0x00,0xff,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x3f, - 0x80,0x00,0x00,0xff,0xc0,0x04,0x00,0x04,0x00,0x04,0x00}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x84,0x84,0x00,0x09,0xFF,0x00, + 0x00,0x0A,0x0A,0x14,0x0A,0x00,0xFF,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x3F, + 0x80,0x00,0x00,0xFF,0xC0,0x04,0x00,0x04,0x00,0x04,0x00}; const u8g_fntpgm_uint8_t fontpage_356_244_244[43] U8G_FONT_SECTION("fontpage_356_244_244") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xf4,0xf4,0x00,0x09,0xff,0x00, - 0x00,0x0a,0x0a,0x14,0x0a,0x00,0xff,0x20,0x00,0x20,0x00,0x20,0x00,0x3f,0x80,0x00, - 0x00,0x00,0x00,0xff,0xc0,0x12,0x00,0x12,0x00,0x12,0x00}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xF4,0xF4,0x00,0x09,0xFF,0x00, + 0x00,0x0A,0x0A,0x14,0x0A,0x00,0xFF,0x20,0x00,0x20,0x00,0x20,0x00,0x3F,0x80,0x00, + 0x00,0x00,0x00,0xFF,0xC0,0x12,0x00,0x12,0x00,0x12,0x00}; const u8g_fntpgm_uint8_t fontpage_357_200_200[34] U8G_FONT_SECTION("fontpage_357_200_200") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x7d,0x01, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xC8,0xC8,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x7D,0x01, 0x01,0x01}; const u8g_fntpgm_uint8_t fontpage_357_228_228[45] U8G_FONT_SECTION("fontpage_357_228_228") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xe4,0xe4,0x00,0x09,0xfe,0x00, - 0x00,0x09,0x0b,0x16,0x0a,0x01,0xfe,0xf9,0x00,0x81,0x00,0x81,0x00,0x81,0x00,0x81, - 0x80,0x81,0x00,0x81,0x00,0xfd,0x00,0x01,0x00,0x01,0x00,0x01,0x00}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xE4,0xE4,0x00,0x09,0xFE,0x00, + 0x00,0x09,0x0B,0x16,0x0A,0x01,0xFE,0xF9,0x00,0x81,0x00,0x81,0x00,0x81,0x00,0x81, + 0x80,0x81,0x00,0x81,0x00,0xFD,0x00,0x01,0x00,0x01,0x00,0x01,0x00}; const u8g_fntpgm_uint8_t fontpage_357_249_249[45] U8G_FONT_SECTION("fontpage_357_249_249") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xf9,0xf9,0x00,0x09,0xfe,0x00, - 0x00,0x09,0x0b,0x16,0x0a,0x01,0xfe,0xf9,0x00,0x81,0x00,0x81,0x00,0x81,0x80,0x81, - 0x00,0xfd,0x00,0x00,0x00,0x3e,0x00,0x41,0x00,0x41,0x00,0x3e,0x00}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xF9,0xF9,0x00,0x09,0xFE,0x00, + 0x00,0x09,0x0B,0x16,0x0A,0x01,0xFE,0xF9,0x00,0x81,0x00,0x81,0x00,0x81,0x80,0x81, + 0x00,0xFD,0x00,0x00,0x00,0x3E,0x00,0x41,0x00,0x41,0x00,0x3E,0x00}; const u8g_fntpgm_uint8_t fontpage_359_196_196[41] U8G_FONT_SECTION("fontpage_359_196_196") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xc4,0xc4,0x00,0x09,0x00,0x00, - 0x00,0x0a,0x09,0x12,0x0a,0x00,0x00,0x3f,0x80,0x20,0x00,0x20,0x00,0x20,0x00,0x3f, - 0x80,0x04,0x00,0x04,0x00,0x04,0x00,0xff,0xc0}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xC4,0xC4,0x00,0x09,0x00,0x00, + 0x00,0x0A,0x09,0x12,0x0A,0x00,0x00,0x3F,0x80,0x20,0x00,0x20,0x00,0x20,0x00,0x3F, + 0x80,0x04,0x00,0x04,0x00,0x04,0x00,0xFF,0xC0}; const u8g_fntpgm_uint8_t fontpage_359_204_204[45] U8G_FONT_SECTION("fontpage_359_204_204") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xcc,0xcc,0x00,0x09,0xfe,0x00, - 0x00,0x0a,0x0b,0x16,0x0a,0x00,0xfe,0x3f,0x00,0x20,0x00,0x3f,0x80,0x04,0x00,0xff, - 0xc0,0x00,0x00,0x3f,0x00,0x00,0x80,0x3f,0x00,0x20,0x00,0x3f,0x80}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0x00,0x09,0xFE,0x00, + 0x00,0x0A,0x0B,0x16,0x0A,0x00,0xFE,0x3F,0x00,0x20,0x00,0x3F,0x80,0x04,0x00,0xFF, + 0xC0,0x00,0x00,0x3F,0x00,0x00,0x80,0x3F,0x00,0x20,0x00,0x3F,0x80}; const u8g_fntpgm_uint8_t fontpage_359_217_217[45] U8G_FONT_SECTION("fontpage_359_217_217") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xd9,0xd9,0x00,0x09,0xfe,0x00, - 0x00,0x0a,0x0b,0x16,0x0a,0x00,0xfe,0x3f,0x00,0x20,0x00,0x20,0x00,0x3f,0x80,0x04, - 0x00,0xff,0xc0,0x00,0x00,0x1f,0x00,0x20,0x80,0x20,0x80,0x1f,0x00}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xD9,0xD9,0x00,0x09,0xFE,0x00, + 0x00,0x0A,0x0B,0x16,0x0A,0x00,0xFE,0x3F,0x00,0x20,0x00,0x20,0x00,0x3F,0x80,0x04, + 0x00,0xFF,0xC0,0x00,0x00,0x1F,0x00,0x20,0x80,0x20,0x80,0x1F,0x00}; const u8g_fntpgm_uint8_t fontpage_360_152_152[45] U8G_FONT_SECTION("fontpage_360_152_152") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x98,0x98,0x00,0x09,0xfe,0x00, - 0x00,0x09,0x0b,0x16,0x0a,0x00,0xfe,0x7c,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x7e, - 0x80,0x10,0x80,0x10,0x80,0xff,0x80,0x00,0x80,0x00,0x80,0x00,0x80}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x98,0x98,0x00,0x09,0xFE,0x00, + 0x00,0x09,0x0B,0x16,0x0A,0x00,0xFE,0x7C,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x7E, + 0x80,0x10,0x80,0x10,0x80,0xFF,0x80,0x00,0x80,0x00,0x80,0x00,0x80}; +const u8g_fntpgm_uint8_t fontpage_360_156_156[45] U8G_FONT_SECTION("fontpage_360_156_156") = { + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x9C,0x9C,0x00,0x09,0xFE,0x00, + 0x00,0x09,0x0B,0x16,0x0A,0x00,0xFE,0x7C,0x80,0x40,0x80,0x40,0x80,0x7C,0x80,0x10, + 0x80,0x10,0x80,0xFF,0x80,0x00,0x80,0x20,0x00,0x20,0x00,0x3F,0x80}; const u8g_fntpgm_uint8_t fontpage_360_168_168[34] U8G_FONT_SECTION("fontpage_360_168_168") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xa8,0xa8,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0xf9,0x81,0x81,0xf9,0x21,0xff,0x00,0x7f,0x41, - 0x41,0x7f}; -const u8g_fntpgm_uint8_t fontpage_360_208_208[43] U8G_FONT_SECTION("fontpage_360_208_208") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xd0,0xd0,0x00,0x09,0xff,0x00, - 0x00,0x0a,0x0a,0x14,0x0a,0x00,0xff,0x3f,0x80,0x20,0x00,0x20,0x00,0x20,0x00,0x3f, - 0x80,0x00,0x00,0xff,0xc0,0x04,0x00,0x04,0x00,0x04,0x00}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xA8,0xA8,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF9,0x81,0x81,0xF9,0x21,0xFF,0x00,0x7F,0x41, + 0x41,0x7F}; const u8g_fntpgm_uint8_t fontpage_361_164_164[45] U8G_FONT_SECTION("fontpage_361_164_164") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xa4,0xa4,0x00,0x09,0xfe,0x00, - 0x00,0x09,0x0b,0x16,0x0a,0x00,0xfe,0x7c,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x7c, - 0x80,0x00,0x80,0xfe,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xA4,0xA4,0x00,0x09,0xFE,0x00, + 0x00,0x09,0x0B,0x16,0x0A,0x00,0xFE,0x7C,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x7C, + 0x80,0x00,0x80,0xFE,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80}; const u8g_fntpgm_uint8_t fontpage_361_220_220[41] U8G_FONT_SECTION("fontpage_361_220_220") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xdc,0xdc,0x00,0x09,0x00,0x00, - 0x00,0x0a,0x09,0x12,0x0a,0x00,0x00,0x3f,0x80,0x20,0x00,0x20,0x00,0x20,0x00,0x20, - 0x00,0x3f,0x80,0x00,0x00,0x00,0x00,0xff,0xc0}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xDC,0xDC,0x00,0x09,0x00,0x00, + 0x00,0x0A,0x09,0x12,0x0A,0x00,0x00,0x3F,0x80,0x20,0x00,0x20,0x00,0x20,0x00,0x20, + 0x00,0x3F,0x80,0x00,0x00,0x00,0x00,0xFF,0xC0}; const u8g_fntpgm_uint8_t fontpage_362_148_148[34] U8G_FONT_SECTION("fontpage_362_148_148") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x94,0x94,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0xf9,0x81,0x81,0x81,0x81,0x81,0x81,0xfd,0x01, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x94,0x94,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF9,0x81,0x81,0x81,0x81,0x81,0x81,0xFD,0x01, 0x01,0x01}; const u8g_fntpgm_uint8_t fontpage_366_252_252[45] U8G_FONT_SECTION("fontpage_366_252_252") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xfc,0xfc,0x00,0x09,0xfe,0x00, - 0x00,0x09,0x0b,0x16,0x0a,0x01,0xfe,0xf9,0x00,0x09,0x00,0x09,0x00,0xf9,0x00,0x81, - 0x80,0x81,0x00,0x81,0x00,0xfd,0x00,0x01,0x00,0x01,0x00,0x01,0x00}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xFC,0xFC,0x00,0x09,0xFE,0x00, + 0x00,0x09,0x0B,0x16,0x0A,0x01,0xFE,0xF9,0x00,0x09,0x00,0x09,0x00,0xF9,0x00,0x81, + 0x80,0x81,0x00,0x81,0x00,0xFD,0x00,0x01,0x00,0x01,0x00,0x01,0x00}; +const u8g_fntpgm_uint8_t fontpage_367_236_236[34] U8G_FONT_SECTION("fontpage_367_236_236") = { + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xEC,0xEC,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF1,0x09,0x09,0xF1,0x87,0x81,0x81,0xF9,0x01, + 0x01,0x01}; const u8g_fntpgm_uint8_t fontpage_368_136_136[34] U8G_FONT_SECTION("fontpage_368_136_136") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0xf5,0x15,0x15,0xf5,0x8d,0x85,0x85,0xfd,0x05, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF5,0x15,0x15,0xF5,0x8D,0x85,0x85,0xFD,0x05, 0x05,0x05}; const u8g_fntpgm_uint8_t fontpage_368_165_165[34] U8G_FONT_SECTION("fontpage_368_165_165") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xa5,0xa5,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0xf1,0x17,0xf1,0x87,0x81,0xf9,0x00,0x7f,0x01, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xA5,0xA5,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF1,0x17,0xF1,0x87,0x81,0xF9,0x00,0x7F,0x01, 0x01,0x01}; const u8g_fntpgm_uint8_t fontpage_368_220_220[41] U8G_FONT_SECTION("fontpage_368_220_220") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xdc,0xdc,0x00,0x09,0x00,0x00, - 0x00,0x0a,0x09,0x12,0x0a,0x00,0x00,0x3f,0x80,0x00,0x80,0x3f,0x80,0x20,0x00,0x20, - 0x00,0x3f,0x80,0x04,0x00,0x04,0x00,0xff,0xc0}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xDC,0xDC,0x00,0x09,0x00,0x00, + 0x00,0x0A,0x09,0x12,0x0A,0x00,0x00,0x3F,0x80,0x00,0x80,0x3F,0x80,0x20,0x00,0x20, + 0x00,0x3F,0x80,0x04,0x00,0x04,0x00,0xFF,0xC0}; const u8g_fntpgm_uint8_t fontpage_369_204_204[41] U8G_FONT_SECTION("fontpage_369_204_204") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xcc,0xcc,0x00,0x09,0x00,0x00, - 0x00,0x0a,0x09,0x12,0x0a,0x00,0x00,0x3f,0x80,0x00,0x80,0x3f,0x80,0x20,0x00,0x20, - 0x00,0x3f,0x80,0x12,0x00,0x12,0x00,0xff,0xc0}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0x00,0x09,0x00,0x00, + 0x00,0x0A,0x09,0x12,0x0A,0x00,0x00,0x3F,0x80,0x00,0x80,0x3F,0x80,0x20,0x00,0x20, + 0x00,0x3F,0x80,0x12,0x00,0x12,0x00,0xFF,0xC0}; const u8g_fntpgm_uint8_t fontpage_370_244_244[41] U8G_FONT_SECTION("fontpage_370_244_244") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xf4,0xf4,0x00,0x09,0x00,0x00, - 0x00,0x0a,0x09,0x12,0x0a,0x00,0x00,0x3f,0x80,0x00,0x80,0x3f,0x80,0x20,0x00,0x20, - 0x00,0x3f,0x80,0x00,0x00,0x00,0x00,0xff,0xc0}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xF4,0xF4,0x00,0x09,0x00,0x00, + 0x00,0x0A,0x09,0x12,0x0A,0x00,0x00,0x3F,0x80,0x00,0x80,0x3F,0x80,0x20,0x00,0x20, + 0x00,0x3F,0x80,0x00,0x00,0x00,0x00,0xFF,0xC0}; const u8g_fntpgm_uint8_t fontpage_371_172_172[34] U8G_FONT_SECTION("fontpage_371_172_172") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xac,0xac,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0xf9,0x09,0x09,0xf9,0x81,0x81,0x81,0xfd,0x01, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xAC,0xAC,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF9,0x09,0x09,0xF9,0x81,0x81,0x81,0xFD,0x01, 0x01,0x01}; +const u8g_fntpgm_uint8_t fontpage_371_176_176[34] U8G_FONT_SECTION("fontpage_371_176_176") = { + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xB0,0xB0,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF9,0x09,0x09,0xF9,0x81,0x81,0xFD,0x01,0x20, + 0x20,0x3F}; const u8g_fntpgm_uint8_t fontpage_371_189_189[34] U8G_FONT_SECTION("fontpage_371_189_189") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xbd,0xbd,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0xf9,0x09,0xf9,0x81,0x81,0xfd,0x00,0x41,0x3f, - 0x41,0x3f}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xBD,0xBD,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF9,0x09,0xF9,0x81,0x81,0xFD,0x00,0x41,0x3F, + 0x41,0x3F}; const u8g_fntpgm_uint8_t fontpage_371_193_193[34] U8G_FONT_SECTION("fontpage_371_193_193") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xc1,0xc1,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0xf9,0x09,0xf9,0x81,0x81,0xfd,0x01,0x3e,0x21, - 0x21,0x3e}; -const u8g_fntpgm_uint8_t fontpage_371_204_204[45] U8G_FONT_SECTION("fontpage_371_204_204") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xcc,0xcc,0x00,0x09,0xfe,0x00, - 0x00,0x09,0x0b,0x16,0x0a,0x01,0xfe,0xf9,0x00,0x89,0x00,0x89,0x00,0x89,0x80,0x89, - 0x00,0xf9,0x00,0x01,0x00,0x41,0x00,0x40,0x00,0x40,0x00,0x7f,0x00}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xC1,0xC1,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF9,0x09,0xF9,0x81,0x81,0xFD,0x01,0x3E,0x21, + 0x21,0x3E}; const u8g_fntpgm_uint8_t fontpage_372_200_200[34] U8G_FONT_SECTION("fontpage_372_200_200") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0xf9,0x89,0x89,0x8f,0x89,0xf9,0x00,0x3f,0x41, - 0x41,0x3f}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xC8,0xC8,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF9,0x89,0x89,0x8F,0x89,0xF9,0x00,0x3F,0x41, + 0x41,0x3F}; const u8g_fntpgm_uint8_t fontpage_372_212_212[34] U8G_FONT_SECTION("fontpage_372_212_212") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xd4,0xd4,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0xf5,0x95,0x95,0x9d,0x95,0x95,0x95,0xf5,0x05, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xD4,0xD4,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF5,0x95,0x95,0x9D,0x95,0x95,0x95,0xF5,0x05, 0x05,0x05}; const u8g_fntpgm_uint8_t fontpage_372_244_244[34] U8G_FONT_SECTION("fontpage_372_244_244") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xf4,0xf4,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0xf9,0x89,0x8f,0x89,0x8f,0xf9,0x01,0x21,0x20, - 0x20,0x3f}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xF4,0xF4,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF9,0x89,0x8F,0x89,0x8F,0xF9,0x01,0x21,0x20, + 0x20,0x3F}; const u8g_fntpgm_uint8_t fontpage_373_168_168[41] U8G_FONT_SECTION("fontpage_373_168_168") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xa8,0xa8,0x00,0x09,0x00,0x00, - 0x00,0x0a,0x09,0x12,0x0a,0x00,0x00,0x3f,0x80,0x20,0x80,0x20,0x80,0x20,0x80,0x3f, - 0x80,0x04,0x00,0x04,0x00,0x04,0x00,0xff,0xc0}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xA8,0xA8,0x00,0x09,0x00,0x00, + 0x00,0x0A,0x09,0x12,0x0A,0x00,0x00,0x3F,0x80,0x20,0x80,0x20,0x80,0x20,0x80,0x3F, + 0x80,0x04,0x00,0x04,0x00,0x04,0x00,0xFF,0xC0}; +const u8g_fntpgm_uint8_t fontpage_373_187_187[45] U8G_FONT_SECTION("fontpage_373_187_187") = { + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xBB,0xBB,0x00,0x09,0xFE,0x00, + 0x00,0x0A,0x0B,0x16,0x0A,0x00,0xFE,0x3F,0x00,0x20,0x80,0x20,0x80,0x3F,0x00,0x04, + 0x00,0xFF,0xC0,0x00,0x00,0x04,0x00,0x0C,0x00,0x1A,0x00,0x61,0x80}; +const u8g_fntpgm_uint8_t fontpage_375_248_248[34] U8G_FONT_SECTION("fontpage_375_248_248") = { + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF9,0x89,0x89,0x89,0x89,0x89,0x89,0xF9,0x01, + 0x01,0x01}; const u8g_fntpgm_uint8_t fontpage_376_128_128[34] U8G_FONT_SECTION("fontpage_376_128_128") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0xf9,0x89,0x89,0x89,0xf9,0x00,0x3f,0x01,0x3f, - 0x40,0x3f}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF9,0x89,0x89,0x89,0xF9,0x00,0x3F,0x01,0x3F, + 0x40,0x3F}; const u8g_fntpgm_uint8_t fontpage_376_148_148[45] U8G_FONT_SECTION("fontpage_376_148_148") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x94,0x94,0x00,0x09,0xfe,0x00, - 0x00,0x09,0x0b,0x16,0x0a,0x01,0xfe,0x89,0x00,0x89,0x00,0x89,0x00,0xf9,0x00,0x89, - 0x80,0x89,0x00,0x89,0x00,0xf9,0x00,0x01,0x00,0x01,0x00,0x01,0x00}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x94,0x94,0x00,0x09,0xFE,0x00, + 0x00,0x09,0x0B,0x16,0x0A,0x01,0xFE,0x89,0x00,0x89,0x00,0x89,0x00,0xF9,0x00,0x89, + 0x80,0x89,0x00,0x89,0x00,0xF9,0x00,0x01,0x00,0x01,0x00,0x01,0x00}; const u8g_fntpgm_uint8_t fontpage_377_132_132[34] U8G_FONT_SECTION("fontpage_377_132_132") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x84,0x84,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x89,0x89,0x89,0xff,0x89,0x89,0x89,0xf9,0x01, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x84,0x84,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0x89,0x89,0x89,0xFF,0x89,0x89,0x89,0xF9,0x01, 0x01,0x01}; const u8g_fntpgm_uint8_t fontpage_377_160_160[34] U8G_FONT_SECTION("fontpage_377_160_160") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xa0,0xa0,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x95,0x95,0x95,0xf5,0x9d,0x95,0x95,0xf5,0x05, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xA0,0xA0,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0x95,0x95,0x95,0xF5,0x9D,0x95,0x95,0xF5,0x05, 0x05,0x05}; const u8g_fntpgm_uint8_t fontpage_377_168_168[34] U8G_FONT_SECTION("fontpage_377_168_168") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xa8,0xa8,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x95,0x95,0xfd,0x95,0xf5,0x00,0x3f,0x01,0x3f, - 0x40,0x3f}; -const u8g_fntpgm_uint8_t fontpage_380_140_140[41] U8G_FONT_SECTION("fontpage_380_140_140") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x8c,0x8c,0x00,0x09,0x00,0x00, - 0x00,0x0a,0x09,0x12,0x0a,0x00,0x00,0x20,0x80,0x20,0x80,0x3f,0x80,0x20,0x80,0x20, - 0x80,0x3f,0x80,0x00,0x00,0x00,0x00,0xff,0xc0}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xA8,0xA8,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0x95,0x95,0xFD,0x95,0xF5,0x00,0x3F,0x01,0x3F, + 0x40,0x3F}; +const u8g_fntpgm_uint8_t fontpage_377_248_248[45] U8G_FONT_SECTION("fontpage_377_248_248") = { + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0x00,0x09,0xFE,0x00, + 0x00,0x0A,0x0B,0x16,0x0A,0x00,0xFE,0x20,0x80,0x20,0x80,0x3F,0x00,0x20,0x80,0x3F, + 0x00,0x04,0x00,0xFF,0xC0,0x00,0x00,0x20,0x00,0x20,0x00,0x3F,0x80}; const u8g_fntpgm_uint8_t fontpage_380_196_196[34] U8G_FONT_SECTION("fontpage_380_196_196") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xc4,0xc4,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x89,0x89,0x89,0xf9,0x89,0x89,0x89,0xf9,0x01, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xC4,0xC4,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0x89,0x89,0x89,0xF9,0x89,0x89,0x89,0xF9,0x01, 0x01,0x01}; +const u8g_fntpgm_uint8_t fontpage_385_172_172[45] U8G_FONT_SECTION("fontpage_385_172_172") = { + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xAC,0xAC,0x00,0x09,0xFE,0x00, + 0x00,0x09,0x0B,0x16,0x0A,0x01,0xFE,0x21,0x00,0x21,0x00,0x21,0x00,0x21,0x00,0x61, + 0x80,0x51,0x00,0x99,0x00,0x89,0x00,0x01,0x00,0x01,0x00,0x01,0x00}; const u8g_fntpgm_uint8_t fontpage_385_189_189[45] U8G_FONT_SECTION("fontpage_385_189_189") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xbd,0xbd,0x00,0x09,0xfe,0x00, - 0x00,0x09,0x0b,0x16,0x0a,0x01,0xfe,0x21,0x00,0x21,0x00,0x21,0x00,0x51,0x80,0xd9, - 0x00,0x89,0x00,0x00,0x00,0x41,0x00,0x7e,0x00,0x41,0x00,0x7e,0x00}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xBD,0xBD,0x00,0x09,0xFE,0x00, + 0x00,0x09,0x0B,0x16,0x0A,0x01,0xFE,0x21,0x00,0x21,0x00,0x21,0x00,0x51,0x80,0xD9, + 0x00,0x89,0x00,0x00,0x00,0x41,0x00,0x7E,0x00,0x41,0x00,0x7E,0x00}; const u8g_fntpgm_uint8_t fontpage_385_200_200[34] U8G_FONT_SECTION("fontpage_385_200_200") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x25,0x25,0x25,0x45,0x67,0x65,0x95,0x95,0x05, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xC8,0xC8,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0x25,0x25,0x25,0x45,0x67,0x65,0x95,0x95,0x05, 0x05,0x05}; const u8g_fntpgm_uint8_t fontpage_386_164_164[34] U8G_FONT_SECTION("fontpage_386_164_164") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xa4,0xa4,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x21,0x21,0x27,0x51,0x89,0x00,0x3f,0x01,0x3f, - 0x40,0x3f}; -const u8g_fntpgm_uint8_t fontpage_386_216_216[34] U8G_FONT_SECTION("fontpage_386_216_216") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xd8,0xd8,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x21,0x27,0x21,0x67,0xd1,0x89,0x01,0x21,0x20, - 0x20,0x3f}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xA4,0xA4,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0x21,0x21,0x27,0x51,0x89,0x00,0x3F,0x01,0x3F, + 0x40,0x3F}; const u8g_fntpgm_uint8_t fontpage_387_140_141[69] U8G_FONT_SECTION("fontpage_387_140_141") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x8c,0x8d,0x00,0x09,0xfe,0x00, - 0x00,0x0a,0x09,0x12,0x0a,0x00,0x00,0x04,0x00,0x0c,0x00,0x0c,0x00,0x12,0x00,0x31, - 0x00,0x44,0x80,0x04,0x00,0x04,0x00,0xff,0xc0,0x0a,0x0b,0x16,0x0a,0x00,0xfe,0x04, - 0x00,0x0c,0x00,0x13,0x00,0x65,0x80,0x04,0x00,0xff,0xc0,0x00,0x00,0x3f,0x00,0x00, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x8C,0x8D,0x00,0x09,0xFE,0x00, + 0x00,0x0A,0x09,0x12,0x0A,0x00,0x00,0x04,0x00,0x0C,0x00,0x0C,0x00,0x12,0x00,0x31, + 0x00,0x44,0x80,0x04,0x00,0x04,0x00,0xFF,0xC0,0x0A,0x0B,0x16,0x0A,0x00,0xFE,0x04, + 0x00,0x0C,0x00,0x13,0x00,0x65,0x80,0x04,0x00,0xFF,0xC0,0x00,0x00,0x3F,0x00,0x00, 0x80,0x00,0x80,0x00,0x80}; const u8g_fntpgm_uint8_t fontpage_389_164_164[41] U8G_FONT_SECTION("fontpage_389_164_164") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xa4,0xa4,0x00,0x09,0x00,0x00, - 0x00,0x0a,0x09,0x12,0x0a,0x00,0x00,0x04,0x00,0x0c,0x00,0x0c,0x00,0x12,0x00,0x31, - 0x00,0x40,0x80,0x00,0x00,0x00,0x00,0xff,0xc0}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xA4,0xA4,0x00,0x09,0x00,0x00, + 0x00,0x0A,0x09,0x12,0x0A,0x00,0x00,0x04,0x00,0x0C,0x00,0x0C,0x00,0x12,0x00,0x31, + 0x00,0x40,0x80,0x00,0x00,0x00,0x00,0xFF,0xC0}; const u8g_fntpgm_uint8_t fontpage_389_172_172[45] U8G_FONT_SECTION("fontpage_389_172_172") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xac,0xac,0x00,0x09,0xfe,0x00, - 0x00,0x0a,0x0b,0x16,0x0a,0x00,0xfe,0x04,0x00,0x1a,0x00,0x61,0x80,0x00,0x00,0xff, - 0xc0,0x00,0x00,0x3f,0x00,0x00,0x80,0x3f,0x00,0x20,0x00,0x3f,0x80}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xAC,0xAC,0x00,0x09,0xFE,0x00, + 0x00,0x0A,0x0B,0x16,0x0A,0x00,0xFE,0x04,0x00,0x1A,0x00,0x61,0x80,0x00,0x00,0xFF, + 0xC0,0x00,0x00,0x3F,0x00,0x00,0x80,0x3F,0x00,0x20,0x00,0x3F,0x80}; const u8g_fntpgm_uint8_t fontpage_389_220_221[51] U8G_FONT_SECTION("fontpage_389_220_221") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xdc,0xdd,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x21,0x21,0x21,0x21,0x21,0x51,0xc9,0x89,0x01, - 0x01,0x01,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x21,0x21,0x21,0x51,0xd9,0x89,0x00,0x7f, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xDC,0xDD,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0x21,0x21,0x21,0x21,0x21,0x51,0xC9,0x89,0x01, + 0x01,0x01,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0x21,0x21,0x21,0x51,0xD9,0x89,0x00,0x7F, 0x01,0x01,0x01}; const u8g_fntpgm_uint8_t fontpage_395_180_180[34] U8G_FONT_SECTION("fontpage_395_180_180") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xb4,0xb4,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x71,0x89,0x89,0x8f,0x89,0x89,0x89,0x71,0x01, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xB4,0xB4,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0x71,0x89,0x89,0x8F,0x89,0x89,0x89,0x71,0x01, 0x01,0x01}; const u8g_fntpgm_uint8_t fontpage_395_198_198[45] U8G_FONT_SECTION("fontpage_395_198_198") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0x00,0x09,0xfe,0x00, - 0x00,0x09,0x0b,0x16,0x0a,0x01,0xfe,0x71,0x00,0x89,0x00,0x8f,0x00,0x89,0x00,0x89, - 0x00,0x71,0x00,0x00,0x00,0x4a,0x00,0x72,0x00,0x4d,0x00,0x74,0x80}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0x00,0x09,0xFE,0x00, + 0x00,0x09,0x0B,0x16,0x0A,0x01,0xFE,0x71,0x00,0x89,0x00,0x8F,0x00,0x89,0x00,0x89, + 0x00,0x71,0x00,0x00,0x00,0x4A,0x00,0x72,0x00,0x4D,0x00,0x74,0x80}; const u8g_fntpgm_uint8_t fontpage_395_209_209[34] U8G_FONT_SECTION("fontpage_395_209_209") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xd1,0xd1,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x65,0x95,0x95,0x9d,0x95,0x65,0x00,0x7f,0x01, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xD1,0xD1,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0x65,0x95,0x95,0x9D,0x95,0x65,0x00,0x7F,0x01, 0x01,0x01}; const u8g_fntpgm_uint8_t fontpage_395_212_212[45] U8G_FONT_SECTION("fontpage_395_212_212") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xd4,0xd4,0x00,0x09,0xfe,0x00, - 0x00,0x09,0x0b,0x16,0x0a,0x01,0xfe,0x65,0x00,0x95,0x00,0x95,0x00,0x9d,0x00,0x95, - 0x00,0x65,0x00,0x05,0x00,0x25,0x00,0x20,0x00,0x20,0x00,0x3f,0x80}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xD4,0xD4,0x00,0x09,0xFE,0x00, + 0x00,0x09,0x0B,0x16,0x0A,0x01,0xFE,0x65,0x00,0x95,0x00,0x95,0x00,0x9D,0x00,0x95, + 0x00,0x65,0x00,0x05,0x00,0x25,0x00,0x20,0x00,0x20,0x00,0x3F,0x80}; const u8g_fntpgm_uint8_t fontpage_395_244_244[34] U8G_FONT_SECTION("fontpage_395_244_244") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xf4,0xf4,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x71,0x8f,0x89,0x8f,0x71,0x00,0x3f,0x01,0x3f, - 0x40,0x3f}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xF4,0xF4,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0x71,0x8F,0x89,0x8F,0x71,0x00,0x3F,0x01,0x3F, + 0x40,0x3F}; const u8g_fntpgm_uint8_t fontpage_396_136_136[34] U8G_FONT_SECTION("fontpage_396_136_136") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x65,0x95,0x9d,0x95,0x95,0x9d,0x95,0x65,0x05, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0x65,0x95,0x9D,0x95,0x95,0x9D,0x95,0x65,0x05, 0x05,0x05}; const u8g_fntpgm_uint8_t fontpage_396_164_164[41] U8G_FONT_SECTION("fontpage_396_164_164") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xa4,0xa4,0x00,0x09,0x00,0x00, - 0x00,0x0a,0x09,0x12,0x0a,0x00,0x00,0x1e,0x00,0x21,0x00,0x20,0x80,0x20,0x80,0x21, - 0x00,0x1e,0x00,0x04,0x00,0x04,0x00,0xff,0xc0}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xA4,0xA4,0x00,0x09,0x00,0x00, + 0x00,0x0A,0x09,0x12,0x0A,0x00,0x00,0x1E,0x00,0x21,0x00,0x20,0x80,0x20,0x80,0x21, + 0x00,0x1E,0x00,0x04,0x00,0x04,0x00,0xFF,0xC0}; const u8g_fntpgm_uint8_t fontpage_396_168_168[45] U8G_FONT_SECTION("fontpage_396_168_168") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xa8,0xa8,0x00,0x09,0xfe,0x00, - 0x00,0x0a,0x0b,0x16,0x0a,0x00,0xfe,0x1f,0x00,0x20,0x80,0x20,0x80,0x1f,0x00,0x04, - 0x00,0x04,0x00,0xff,0xc0,0x00,0x00,0x20,0x00,0x20,0x00,0x3f,0x80}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xA8,0xA8,0x00,0x09,0xFE,0x00, + 0x00,0x0A,0x0B,0x16,0x0A,0x00,0xFE,0x1F,0x00,0x20,0x80,0x20,0x80,0x1F,0x00,0x04, + 0x00,0x04,0x00,0xFF,0xC0,0x00,0x00,0x20,0x00,0x20,0x00,0x3F,0x80}; const u8g_fntpgm_uint8_t fontpage_396_196_196[45] U8G_FONT_SECTION("fontpage_396_196_196") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xc4,0xc4,0x00,0x09,0xfe,0x00, - 0x00,0x0a,0x0b,0x16,0x0a,0x00,0xfe,0x38,0x80,0x44,0x80,0x44,0x80,0x44,0x80,0x38, - 0xc0,0x10,0x80,0xfe,0x80,0x00,0x80,0x20,0x00,0x20,0x00,0x3f,0x80}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xC4,0xC4,0x00,0x09,0xFE,0x00, + 0x00,0x0A,0x0B,0x16,0x0A,0x00,0xFE,0x38,0x80,0x44,0x80,0x44,0x80,0x44,0x80,0x38, + 0xC0,0x10,0x80,0xFE,0x80,0x00,0x80,0x20,0x00,0x20,0x00,0x3F,0x80}; const u8g_fntpgm_uint8_t fontpage_397_208_208[34] U8G_FONT_SECTION("fontpage_397_208_208") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xd0,0xd0,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x71,0x89,0x89,0x71,0x01,0xff,0x21,0x27,0x41, - 0x40,0x7f}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xD0,0xD0,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0x71,0x89,0x89,0x71,0x01,0xFF,0x21,0x27,0x41, + 0x40,0x7F}; const u8g_fntpgm_uint8_t fontpage_398_132_132[45] U8G_FONT_SECTION("fontpage_398_132_132") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x84,0x84,0x00,0x09,0xfe,0x00, - 0x00,0x09,0x0b,0x16,0x0a,0x00,0xfe,0x38,0x80,0x44,0x80,0x42,0x80,0x44,0x80,0x38, - 0x80,0x00,0x80,0xfe,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x84,0x84,0x00,0x09,0xFE,0x00, + 0x00,0x09,0x0B,0x16,0x0A,0x00,0xFE,0x38,0x80,0x44,0x80,0x42,0x80,0x44,0x80,0x38, + 0x80,0x00,0x80,0xFE,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80}; const u8g_fntpgm_uint8_t fontpage_398_188_188[41] U8G_FONT_SECTION("fontpage_398_188_188") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xbc,0xbc,0x00,0x09,0x00,0x00, - 0x00,0x0a,0x09,0x12,0x0a,0x00,0x00,0x1e,0x00,0x21,0x00,0x20,0x80,0x20,0x80,0x21, - 0x00,0x1e,0x00,0x00,0x00,0x00,0x00,0xff,0xc0}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xBC,0xBC,0x00,0x09,0x00,0x00, + 0x00,0x0A,0x09,0x12,0x0A,0x00,0x00,0x1E,0x00,0x21,0x00,0x20,0x80,0x20,0x80,0x21, + 0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0xFF,0xC0}; const u8g_fntpgm_uint8_t fontpage_398_204_204[45] U8G_FONT_SECTION("fontpage_398_204_204") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xcc,0xcc,0x00,0x09,0xfe,0x00, - 0x00,0x0a,0x0b,0x16,0x0a,0x00,0xfe,0x1e,0x00,0x21,0x00,0x21,0x00,0x1e,0x00,0x00, - 0x00,0xff,0xc0,0x00,0x00,0x3f,0x00,0x20,0x80,0x20,0x80,0x3f,0x00}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0x00,0x09,0xFE,0x00, + 0x00,0x0A,0x0B,0x16,0x0A,0x00,0xFE,0x1E,0x00,0x21,0x00,0x21,0x00,0x1E,0x00,0x00, + 0x00,0xFF,0xC0,0x00,0x00,0x3F,0x00,0x20,0x80,0x20,0x80,0x3F,0x00}; const u8g_fntpgm_uint8_t fontpage_398_244_244[34] U8G_FONT_SECTION("fontpage_398_244_244") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xf4,0xf4,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x71,0x49,0x89,0x89,0x89,0x89,0x49,0x71,0x01, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xF4,0xF4,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0x71,0x49,0x89,0x89,0x89,0x89,0x49,0x71,0x01, 0x01,0x01}; const u8g_fntpgm_uint8_t fontpage_398_252_253[51] U8G_FONT_SECTION("fontpage_398_252_253") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xfc,0xfd,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x71,0x89,0x89,0x89,0x71,0x00,0x3f,0x01,0x3f, - 0x40,0x3f,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x71,0x89,0x89,0x89,0x71,0x00,0x77,0x11, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xFC,0xFD,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0x71,0x89,0x89,0x89,0x71,0x00,0x3F,0x01,0x3F, + 0x40,0x3F,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0x71,0x89,0x89,0x89,0x71,0x00,0x77,0x11, 0x71,0x41,0x79}; const u8g_fntpgm_uint8_t fontpage_399_133_133[34] U8G_FONT_SECTION("fontpage_399_133_133") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x85,0x85,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x71,0x89,0x89,0x89,0x89,0x71,0x00,0x41,0x3f, - 0x41,0x3f}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x85,0x85,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0x71,0x89,0x89,0x89,0x89,0x71,0x00,0x41,0x3F, + 0x41,0x3F}; const u8g_fntpgm_uint8_t fontpage_399_144_145[73] U8G_FONT_SECTION("fontpage_399_144_145") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x90,0x91,0x00,0x09,0xfe,0x00, - 0x00,0x09,0x0b,0x16,0x0a,0x01,0xfe,0xf9,0x00,0x09,0x00,0x11,0x00,0x11,0x00,0x21, - 0x80,0x71,0x00,0xc9,0x00,0x85,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x09,0x0b,0x16, - 0x0a,0x01,0xfe,0xf9,0x00,0x09,0x00,0x11,0x00,0x31,0x80,0x49,0x00,0x85,0x00,0x00, - 0x00,0x7e,0x00,0x01,0x00,0x01,0x00,0x01,0x00}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x90,0x91,0x00,0x09,0xFE,0x00, + 0x00,0x09,0x0B,0x16,0x0A,0x01,0xFE,0xF9,0x00,0x09,0x00,0x11,0x00,0x11,0x00,0x21, + 0x80,0x71,0x00,0xC9,0x00,0x85,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x09,0x0B,0x16, + 0x0A,0x01,0xFE,0xF9,0x00,0x09,0x00,0x11,0x00,0x31,0x80,0x49,0x00,0x85,0x00,0x00, + 0x00,0x7E,0x00,0x01,0x00,0x01,0x00,0x01,0x00}; +const u8g_fntpgm_uint8_t fontpage_399_152_152[45] U8G_FONT_SECTION("fontpage_399_152_152") = { + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x98,0x98,0x00,0x09,0xFE,0x00, + 0x00,0x09,0x0B,0x16,0x0A,0x01,0xFE,0xF9,0x00,0x11,0x00,0x11,0x80,0x79,0x00,0x85, + 0x00,0x00,0x00,0x7E,0x00,0x01,0x00,0x7E,0x00,0x40,0x00,0x7F,0x00}; const u8g_fntpgm_uint8_t fontpage_399_165_165[45] U8G_FONT_SECTION("fontpage_399_165_165") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xa5,0xa5,0x00,0x09,0xfe,0x00, - 0x00,0x09,0x0b,0x16,0x0a,0x01,0xfe,0xf9,0x00,0x09,0x00,0x11,0x00,0x31,0x80,0x79, - 0x00,0x85,0x00,0x00,0x00,0x3e,0x00,0x41,0x00,0x41,0x00,0x3e,0x00}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xA5,0xA5,0x00,0x09,0xFE,0x00, + 0x00,0x09,0x0B,0x16,0x0A,0x01,0xFE,0xF9,0x00,0x09,0x00,0x11,0x00,0x31,0x80,0x79, + 0x00,0x85,0x00,0x00,0x00,0x3E,0x00,0x41,0x00,0x41,0x00,0x3E,0x00}; const u8g_fntpgm_uint8_t fontpage_399_172_172[45] U8G_FONT_SECTION("fontpage_399_172_172") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xac,0xac,0x00,0x09,0xfe,0x00, - 0x00,0x09,0x0b,0x16,0x0a,0x00,0xfe,0x7a,0x80,0x0a,0x80,0x0a,0x80,0x12,0x80,0x13, - 0x80,0x2a,0x80,0x6a,0x80,0xc6,0x80,0x02,0x80,0x02,0x80,0x02,0x80}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xAC,0xAC,0x00,0x09,0xFE,0x00, + 0x00,0x09,0x0B,0x16,0x0A,0x00,0xFE,0x7A,0x80,0x0A,0x80,0x0A,0x80,0x12,0x80,0x13, + 0x80,0x2A,0x80,0x6A,0x80,0xC6,0x80,0x02,0x80,0x02,0x80,0x02,0x80}; const u8g_fntpgm_uint8_t fontpage_400_128_128[34] U8G_FONT_SECTION("fontpage_400_128_128") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0xf9,0x09,0x11,0x17,0x31,0x71,0xc9,0x85,0x01, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF9,0x09,0x11,0x17,0x31,0x71,0xC9,0x85,0x01, 0x01,0x01}; const u8g_fntpgm_uint8_t fontpage_400_132_132[34] U8G_FONT_SECTION("fontpage_400_132_132") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x84,0x84,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0xf9,0x09,0x17,0x31,0x49,0x85,0x01,0x21,0x20, - 0x20,0x3f}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x84,0x84,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF9,0x09,0x17,0x31,0x49,0x85,0x01,0x21,0x20, + 0x20,0x3F}; const u8g_fntpgm_uint8_t fontpage_400_149_149[34] U8G_FONT_SECTION("fontpage_400_149_149") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x95,0x95,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0xf9,0x09,0x17,0x31,0x49,0x85,0x00,0x3e,0x21, - 0x21,0x3e}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x95,0x95,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF9,0x09,0x17,0x31,0x49,0x85,0x00,0x3E,0x21, + 0x21,0x3E}; const u8g_fntpgm_uint8_t fontpage_400_156_156[45] U8G_FONT_SECTION("fontpage_400_156_156") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x9c,0x9c,0x00,0x09,0xfe,0x00, - 0x00,0x09,0x0b,0x16,0x0a,0x00,0xfe,0x7a,0x80,0x0a,0x80,0x0a,0x80,0x16,0x80,0x12, - 0x80,0x2a,0x80,0x4a,0x80,0x86,0x80,0x02,0x80,0x02,0x80,0x02,0x80}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x9C,0x9C,0x00,0x09,0xFE,0x00, + 0x00,0x09,0x0B,0x16,0x0A,0x00,0xFE,0x7A,0x80,0x0A,0x80,0x0A,0x80,0x16,0x80,0x12, + 0x80,0x2A,0x80,0x4A,0x80,0x86,0x80,0x02,0x80,0x02,0x80,0x02,0x80}; const u8g_fntpgm_uint8_t fontpage_401_253_253[45] U8G_FONT_SECTION("fontpage_401_253_253") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xfd,0xfd,0x00,0x09,0xfe,0x00, - 0x00,0x0a,0x0b,0x16,0x0a,0x00,0xfe,0x3f,0x00,0x01,0x00,0x0e,0x00,0x71,0x80,0x00, - 0x00,0xff,0xc0,0x04,0x00,0x3f,0x00,0x00,0x80,0x00,0x80,0x00,0x80}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xFD,0xFD,0x00,0x09,0xFE,0x00, + 0x00,0x0A,0x0B,0x16,0x0A,0x00,0xFE,0x3F,0x00,0x01,0x00,0x0E,0x00,0x71,0x80,0x00, + 0x00,0xFF,0xC0,0x04,0x00,0x3F,0x00,0x00,0x80,0x00,0x80,0x00,0x80}; const u8g_fntpgm_uint8_t fontpage_402_128_128[45] U8G_FONT_SECTION("fontpage_402_128_128") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x09,0xfe,0x00, - 0x00,0x0a,0x0b,0x16,0x0a,0x00,0xfe,0x3f,0x00,0x01,0x00,0x0e,0x00,0x71,0x80,0x00, - 0x00,0xff,0xc0,0x04,0x00,0x24,0x00,0x24,0x00,0x20,0x00,0x3f,0x80}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x09,0xFE,0x00, + 0x00,0x0A,0x0B,0x16,0x0A,0x00,0xFE,0x3F,0x00,0x01,0x00,0x0E,0x00,0x71,0x80,0x00, + 0x00,0xFF,0xC0,0x04,0x00,0x24,0x00,0x24,0x00,0x20,0x00,0x3F,0x80}; const u8g_fntpgm_uint8_t fontpage_402_145_145[45] U8G_FONT_SECTION("fontpage_402_145_145") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x91,0x91,0x00,0x09,0xfe,0x00, - 0x00,0x0a,0x0b,0x16,0x0a,0x00,0xfe,0x3f,0x00,0x01,0x00,0x0e,0x00,0x71,0x80,0x00, - 0x00,0xff,0xc0,0x04,0x00,0x1f,0x00,0x20,0x80,0x20,0x80,0x1f,0x00}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x91,0x91,0x00,0x09,0xFE,0x00, + 0x00,0x0A,0x0B,0x16,0x0A,0x00,0xFE,0x3F,0x00,0x01,0x00,0x0E,0x00,0x71,0x80,0x00, + 0x00,0xFF,0xC0,0x04,0x00,0x1F,0x00,0x20,0x80,0x20,0x80,0x1F,0x00}; const u8g_fntpgm_uint8_t fontpage_403_144_144[45] U8G_FONT_SECTION("fontpage_403_144_144") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x90,0x90,0x00,0x09,0xfe,0x00, - 0x00,0x0a,0x0b,0x16,0x0a,0x00,0xfe,0x3f,0x00,0x0e,0x00,0x71,0x80,0x00,0x00,0xff, - 0xc0,0x00,0x00,0x3f,0x00,0x00,0x80,0x3f,0x00,0x20,0x00,0x3f,0x80}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x90,0x90,0x00,0x09,0xFE,0x00, + 0x00,0x0A,0x0B,0x16,0x0A,0x00,0xFE,0x3F,0x00,0x0E,0x00,0x71,0x80,0x00,0x00,0xFF, + 0xC0,0x00,0x00,0x3F,0x00,0x00,0x80,0x3F,0x00,0x20,0x00,0x3F,0x80}; const u8g_fntpgm_uint8_t fontpage_403_192_192[34] U8G_FONT_SECTION("fontpage_403_192_192") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xc0,0xc0,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0xf9,0x09,0x09,0x11,0x31,0x31,0xc9,0x85,0x01, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF9,0x09,0x09,0x11,0x31,0x31,0xC9,0x85,0x01, 0x01,0x01}; const u8g_fntpgm_uint8_t fontpage_409_152_152[34] U8G_FONT_SECTION("fontpage_409_152_152") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x98,0x98,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x71,0x01,0xf9,0x11,0x17,0x31,0x49,0x85,0x01, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x98,0x98,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0x71,0x01,0xF9,0x11,0x17,0x31,0x49,0x85,0x01, 0x01,0x01}; const u8g_fntpgm_uint8_t fontpage_410_136_136[41] U8G_FONT_SECTION("fontpage_410_136_136") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x09,0x00,0x00, - 0x00,0x0a,0x09,0x12,0x0a,0x00,0x00,0x1e,0x00,0x00,0x00,0x3f,0x00,0x02,0x00,0x0e, - 0x00,0x71,0x80,0x04,0x00,0x04,0x00,0xff,0xc0}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x09,0x00,0x00, + 0x00,0x0A,0x09,0x12,0x0A,0x00,0x00,0x1E,0x00,0x00,0x00,0x3F,0x00,0x02,0x00,0x0E, + 0x00,0x71,0x80,0x04,0x00,0x04,0x00,0xFF,0xC0}; const u8g_fntpgm_uint8_t fontpage_411_149_149[45] U8G_FONT_SECTION("fontpage_411_149_149") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x95,0x95,0x00,0x09,0xfe,0x00, - 0x00,0x0a,0x0b,0x16,0x0a,0x00,0xfe,0x1e,0x00,0x00,0x00,0x3f,0x00,0x0c,0x00,0x73, - 0x80,0x00,0x00,0xff,0xc0,0x04,0x00,0x3f,0x00,0x00,0x80,0x00,0x80}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x95,0x95,0x00,0x09,0xFE,0x00, + 0x00,0x0A,0x0B,0x16,0x0A,0x00,0xFE,0x1E,0x00,0x00,0x00,0x3F,0x00,0x0C,0x00,0x73, + 0x80,0x00,0x00,0xFF,0xC0,0x04,0x00,0x3F,0x00,0x00,0x80,0x00,0x80}; const u8g_fntpgm_uint8_t fontpage_411_156_156[47] U8G_FONT_SECTION("fontpage_411_156_156") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x9c,0x9c,0x00,0x09,0xfd,0x00, - 0x00,0x0a,0x0c,0x18,0x0a,0x00,0xfd,0x1e,0x00,0x00,0x00,0x3f,0x00,0x1a,0x00,0x21, - 0x00,0xff,0xc0,0x04,0x00,0x3f,0x00,0x00,0x80,0x3f,0x00,0x20,0x00,0x3f,0x80}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x9C,0x9C,0x00,0x09,0xFD,0x00, + 0x00,0x0A,0x0C,0x18,0x0A,0x00,0xFD,0x1E,0x00,0x00,0x00,0x3F,0x00,0x1A,0x00,0x21, + 0x00,0xFF,0xC0,0x04,0x00,0x3F,0x00,0x00,0x80,0x3F,0x00,0x20,0x00,0x3F,0x80}; const u8g_fntpgm_uint8_t fontpage_411_164_164[45] U8G_FONT_SECTION("fontpage_411_164_164") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xa4,0xa4,0x00,0x09,0xfe,0x00, - 0x00,0x0a,0x0b,0x16,0x0a,0x00,0xfe,0x1e,0x00,0x00,0x00,0x3f,0x00,0x0c,0x00,0x73, - 0x80,0x00,0x00,0xff,0xc0,0x04,0x00,0x3f,0x00,0x20,0x80,0x3f,0x00}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xA4,0xA4,0x00,0x09,0xFE,0x00, + 0x00,0x0A,0x0B,0x16,0x0A,0x00,0xFE,0x1E,0x00,0x00,0x00,0x3F,0x00,0x0C,0x00,0x73, + 0x80,0x00,0x00,0xFF,0xC0,0x04,0x00,0x3F,0x00,0x20,0x80,0x3F,0x00}; const u8g_fntpgm_uint8_t fontpage_411_232_232[45] U8G_FONT_SECTION("fontpage_411_232_232") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xe8,0xe8,0x00,0x09,0xfe,0x00, - 0x00,0x09,0x0b,0x16,0x0a,0x00,0xfe,0x38,0x80,0x00,0x80,0x7c,0x80,0x18,0x80,0x66, - 0x80,0x00,0x80,0xfe,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xE8,0xE8,0x00,0x09,0xFE,0x00, + 0x00,0x09,0x0B,0x16,0x0A,0x00,0xFE,0x38,0x80,0x00,0x80,0x7C,0x80,0x18,0x80,0x66, + 0x80,0x00,0x80,0xFE,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80}; const u8g_fntpgm_uint8_t fontpage_412_216_216[34] U8G_FONT_SECTION("fontpage_412_216_216") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xd8,0xd8,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x71,0x01,0xf9,0x09,0x11,0x31,0x49,0x85,0x01, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xD8,0xD8,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0x71,0x01,0xF9,0x09,0x11,0x31,0x49,0x85,0x01, 0x01,0x01}; const u8g_fntpgm_uint8_t fontpage_412_232_232[34] U8G_FONT_SECTION("fontpage_412_232_232") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xe8,0xe8,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x71,0x01,0xf9,0x09,0x31,0xcd,0x00,0x3f,0x41, - 0x41,0x3f}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xE8,0xE8,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0x71,0x01,0xF9,0x09,0x31,0xCD,0x00,0x3F,0x41, + 0x41,0x3F}; const u8g_fntpgm_uint8_t fontpage_412_244_244[45] U8G_FONT_SECTION("fontpage_412_244_244") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xf4,0xf4,0x00,0x09,0xfe,0x00, - 0x00,0x09,0x0b,0x16,0x0a,0x01,0xfe,0xf9,0x00,0x09,0x00,0x09,0x00,0xf1,0x00,0x11, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xF4,0xF4,0x00,0x09,0xFE,0x00, + 0x00,0x09,0x0B,0x16,0x0A,0x01,0xFE,0xF9,0x00,0x09,0x00,0x09,0x00,0xF1,0x00,0x11, 0x80,0x21,0x00,0x41,0x00,0x81,0x00,0x01,0x00,0x01,0x00,0x01,0x00}; -const u8g_fntpgm_uint8_t fontpage_413_152_152[34] U8G_FONT_SECTION("fontpage_413_152_152") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x98,0x98,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0xf5,0x15,0xf7,0x25,0xc5,0x00,0x3f,0x01,0x3f, - 0x40,0x3f}; const u8g_fntpgm_uint8_t fontpage_414_156_156[34] U8G_FONT_SECTION("fontpage_414_156_156") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x9c,0x9c,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0xf9,0x09,0x0f,0xf1,0x11,0x2f,0x41,0x81,0x01, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x9C,0x9C,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF9,0x09,0x0F,0xF1,0x11,0x2F,0x41,0x81,0x01, 0x01,0x01}; const u8g_fntpgm_uint8_t fontpage_417_209_209[45] U8G_FONT_SECTION("fontpage_417_209_209") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xd1,0xd1,0x00,0x09,0xfe,0x00, - 0x00,0x09,0x0b,0x16,0x0a,0x01,0xfe,0xf9,0x00,0x81,0x00,0xf9,0x80,0x81,0x00,0x81, - 0x00,0xfd,0x00,0x00,0x00,0x41,0x00,0x7e,0x00,0x41,0x00,0x7e,0x00}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xD1,0xD1,0x00,0x09,0xFE,0x00, + 0x00,0x09,0x0B,0x16,0x0A,0x01,0xFE,0xF9,0x00,0x81,0x00,0xF9,0x80,0x81,0x00,0x81, + 0x00,0xFD,0x00,0x00,0x00,0x41,0x00,0x7E,0x00,0x41,0x00,0x7E,0x00}; const u8g_fntpgm_uint8_t fontpage_418_176_176[34] U8G_FONT_SECTION("fontpage_418_176_176") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xb0,0xb0,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0xf9,0x81,0x81,0xf7,0x81,0x81,0x81,0xf9,0x01, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xB0,0xB0,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF9,0x81,0x81,0xF7,0x81,0x81,0x81,0xF9,0x01, 0x01,0x01}; const u8g_fntpgm_uint8_t fontpage_418_204_204[34] U8G_FONT_SECTION("fontpage_418_204_204") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xcc,0xcc,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0xf5,0x85,0x85,0xed,0x85,0x85,0x85,0xfd,0x05, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0xF5,0x85,0x85,0xED,0x85,0x85,0x85,0xFD,0x05, 0x05,0x05}; const u8g_fntpgm_uint8_t fontpage_419_160_160[41] U8G_FONT_SECTION("fontpage_419_160_160") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xa0,0xa0,0x00,0x09,0x00,0x00, - 0x00,0x0a,0x09,0x12,0x0a,0x00,0x00,0x3f,0x80,0x20,0x00,0x3f,0x00,0x20,0x00,0x20, - 0x00,0x3f,0x80,0x04,0x00,0x04,0x00,0xff,0xc0}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xA0,0xA0,0x00,0x09,0x00,0x00, + 0x00,0x0A,0x09,0x12,0x0A,0x00,0x00,0x3F,0x80,0x20,0x00,0x3F,0x00,0x20,0x00,0x20, + 0x00,0x3F,0x80,0x04,0x00,0x04,0x00,0xFF,0xC0}; const u8g_fntpgm_uint8_t fontpage_421_184_184[41] U8G_FONT_SECTION("fontpage_421_184_184") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xb8,0xb8,0x00,0x09,0x00,0x00, - 0x00,0x0a,0x09,0x12,0x0a,0x00,0x00,0x3f,0x80,0x20,0x00,0x3f,0x00,0x20,0x00,0x20, - 0x00,0x3f,0x80,0x00,0x00,0x00,0x00,0xff,0xc0}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xB8,0xB8,0x00,0x09,0x00,0x00, + 0x00,0x0A,0x09,0x12,0x0A,0x00,0x00,0x3F,0x80,0x20,0x00,0x3F,0x00,0x20,0x00,0x20, + 0x00,0x3F,0x80,0x00,0x00,0x00,0x00,0xFF,0xC0}; const u8g_fntpgm_uint8_t fontpage_423_156_156[45] U8G_FONT_SECTION("fontpage_423_156_156") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x9c,0x9c,0x00,0x09,0xfe,0x00, - 0x00,0x0a,0x0b,0x16,0x0a,0x00,0xfe,0xfa,0x80,0x4a,0x80,0x4e,0x80,0x4a,0x80,0x4a, - 0x80,0xfe,0x80,0x02,0x80,0x12,0x80,0x10,0x00,0x10,0x00,0x1f,0xc0}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x9C,0x9C,0x00,0x09,0xFE,0x00, + 0x00,0x0A,0x0B,0x16,0x0A,0x00,0xFE,0xFA,0x80,0x4A,0x80,0x4E,0x80,0x4A,0x80,0x4A, + 0x80,0xFE,0x80,0x02,0x80,0x12,0x80,0x10,0x00,0x10,0x00,0x1F,0xC0}; const u8g_fntpgm_uint8_t fontpage_426_132_132[41] U8G_FONT_SECTION("fontpage_426_132_132") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x84,0x84,0x00,0x09,0x00,0x00, - 0x00,0x0a,0x09,0x12,0x0a,0x00,0x00,0x3f,0x80,0x12,0x00,0x12,0x00,0x12,0x00,0x12, - 0x00,0x7f,0x80,0x00,0x00,0x00,0x00,0xff,0xc0}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x84,0x84,0x00,0x09,0x00,0x00, + 0x00,0x0A,0x09,0x12,0x0A,0x00,0x00,0x3F,0x80,0x12,0x00,0x12,0x00,0x12,0x00,0x12, + 0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0xFF,0xC0}; const u8g_fntpgm_uint8_t fontpage_426_216_216[45] U8G_FONT_SECTION("fontpage_426_216_216") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xd8,0xd8,0x00,0x09,0xfe,0x00, - 0x00,0x09,0x0b,0x16,0x0a,0x01,0xfe,0x71,0x00,0x01,0x00,0xfd,0x00,0x01,0x00,0x71, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xD8,0xD8,0x00,0x09,0xFE,0x00, + 0x00,0x09,0x0B,0x16,0x0A,0x01,0xFE,0x71,0x00,0x01,0x00,0xFD,0x00,0x01,0x00,0x71, 0x80,0x89,0x00,0x89,0x00,0x89,0x00,0x71,0x00,0x01,0x00,0x01,0x00}; const u8g_fntpgm_uint8_t fontpage_426_233_233[45] U8G_FONT_SECTION("fontpage_426_233_233") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xe9,0xe9,0x00,0x09,0xfe,0x00, - 0x00,0x09,0x0b,0x16,0x0a,0x01,0xfe,0x71,0x00,0x01,0x00,0xfd,0x00,0x49,0x80,0x89, - 0x00,0x79,0x00,0x00,0x00,0x41,0x00,0x7e,0x00,0x41,0x00,0x7e,0x00}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xE9,0xE9,0x00,0x09,0xFE,0x00, + 0x00,0x09,0x0B,0x16,0x0A,0x01,0xFE,0x71,0x00,0x01,0x00,0xFD,0x00,0x49,0x80,0x89, + 0x00,0x79,0x00,0x00,0x00,0x41,0x00,0x7E,0x00,0x41,0x00,0x7E,0x00}; const u8g_fntpgm_uint8_t fontpage_428_200_200[45] U8G_FONT_SECTION("fontpage_428_200_200") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x09,0xfe,0x00, - 0x00,0x0a,0x0b,0x16,0x0a,0x00,0xfe,0x0e,0x00,0x00,0x00,0x7f,0x80,0x21,0x00,0x1e, - 0x00,0x04,0x00,0xff,0xc0,0x00,0x00,0x3f,0x00,0x20,0x80,0x3f,0x00}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xC8,0xC8,0x00,0x09,0xFE,0x00, + 0x00,0x0A,0x0B,0x16,0x0A,0x00,0xFE,0x0E,0x00,0x00,0x00,0x7F,0x80,0x21,0x00,0x1E, + 0x00,0x04,0x00,0xFF,0xC0,0x00,0x00,0x3F,0x00,0x20,0x80,0x3F,0x00}; const u8g_fntpgm_uint8_t fontpage_428_212_212[45] U8G_FONT_SECTION("fontpage_428_212_212") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xd4,0xd4,0x00,0x09,0xfe,0x00, - 0x00,0x0a,0x0b,0x16,0x0a,0x00,0xfe,0x38,0x80,0x00,0x80,0x7e,0x80,0x00,0x80,0x38, - 0x80,0x44,0xc0,0x3c,0x80,0x10,0x80,0xfe,0x80,0x00,0x80,0x00,0x80}; + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0xD4,0xD4,0x00,0x09,0xFE,0x00, + 0x00,0x0A,0x0B,0x16,0x0A,0x00,0xFE,0x38,0x80,0x00,0x80,0x7E,0x80,0x00,0x80,0x38, + 0x80,0x44,0xC0,0x3C,0x80,0x10,0x80,0xFE,0x80,0x00,0x80,0x00,0x80}; const u8g_fntpgm_uint8_t fontpage_431_136_136[34] U8G_FONT_SECTION("fontpage_431_136_136") = { - 0x00,0x0b,0x0d,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x09,0xfe,0x00, - 0x00,0x08,0x0b,0x0b,0x0a,0x01,0xfe,0x71,0x01,0xfd,0x01,0x71,0x49,0x89,0x49,0x71, + 0x00,0x0B,0x0D,0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x09,0xFE,0x00, + 0x00,0x08,0x0B,0x0B,0x0A,0x01,0xFE,0x71,0x01,0xFD,0x01,0x71,0x49,0x89,0x49,0x71, 0x01,0x01}; #define FONTDATA_ITEM(page, begin, end, data) { page, begin, end, COUNT(data), data } @@ -444,36 +456,39 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(359, 204, 204, fontpage_359_204_204), // '돌' -- '돌' FONTDATA_ITEM(359, 217, 217, fontpage_359_217_217), // '동' -- '동' FONTDATA_ITEM(360, 152, 152, fontpage_360_152_152), // '되' -- '되' + FONTDATA_ITEM(360, 156, 156, fontpage_360_156_156), // '된' -- '된' FONTDATA_ITEM(360, 168, 168, fontpage_360_168_168), // '됨' -- '됨' - FONTDATA_ITEM(360, 208, 208, fontpage_360_208_208), // '두' -- '두' FONTDATA_ITEM(361, 164, 164, fontpage_361_164_164), // '뒤' -- '뒤' FONTDATA_ITEM(361, 220, 220, fontpage_361_220_220), // '드' -- '드' FONTDATA_ITEM(362, 148, 148, fontpage_362_148_148), // '디' -- '디' FONTDATA_ITEM(366, 252, 252, fontpage_366_252_252), // '라' -- '라' + FONTDATA_ITEM(367, 236, 236, fontpage_367_236_236), // '러' -- '러' FONTDATA_ITEM(368, 136, 136, fontpage_368_136_136), // '레' -- '레' FONTDATA_ITEM(368, 165, 165, fontpage_368_165_165), // '력' -- '력' FONTDATA_ITEM(368, 220, 220, fontpage_368_220_220), // '로' -- '로' FONTDATA_ITEM(369, 204, 204, fontpage_369_204_204), // '료' -- '료' FONTDATA_ITEM(370, 244, 244, fontpage_370_244_244), // '르' -- '르' FONTDATA_ITEM(371, 172, 172, fontpage_371_172_172), // '리' -- '리' + FONTDATA_ITEM(371, 176, 176, fontpage_371_176_176), // '린' -- '린' FONTDATA_ITEM(371, 189, 189, fontpage_371_189_189), // '립' -- '립' FONTDATA_ITEM(371, 193, 193, fontpage_371_193_193), // '링' -- '링' - FONTDATA_ITEM(371, 204, 204, fontpage_371_204_204), // '만' -- '만' FONTDATA_ITEM(372, 200, 200, fontpage_372_200_200), // '멈' -- '멈' FONTDATA_ITEM(372, 212, 212, fontpage_372_212_212), // '메' -- '메' FONTDATA_ITEM(372, 244, 244, fontpage_372_244_244), // '면' -- '면' FONTDATA_ITEM(373, 168, 168, fontpage_373_168_168), // '모' -- '모' + FONTDATA_ITEM(373, 187, 187, fontpage_373_187_187), // '못' -- '못' + FONTDATA_ITEM(375, 248, 248, fontpage_375_248_248), // '미' -- '미' FONTDATA_ITEM(376, 128, 128, fontpage_376_128_128), // '밀' -- '밀' FONTDATA_ITEM(376, 148, 148, fontpage_376_148_148), // '바' -- '바' FONTDATA_ITEM(377, 132, 132, fontpage_377_132_132), // '버' -- '버' FONTDATA_ITEM(377, 160, 160, fontpage_377_160_160), // '베' -- '베' FONTDATA_ITEM(377, 168, 168, fontpage_377_168_168), // '벨' -- '벨' - FONTDATA_ITEM(380, 140, 140, fontpage_380_140_140), // '브' -- '브' + FONTDATA_ITEM(377, 248, 248, fontpage_377_248_248), // '본' -- '본' FONTDATA_ITEM(380, 196, 196, fontpage_380_196_196), // '비' -- '비' + FONTDATA_ITEM(385, 172, 172, fontpage_385_172_172), // '사' -- '사' FONTDATA_ITEM(385, 189, 189, fontpage_385_189_189), // '삽' -- '삽' FONTDATA_ITEM(385, 200, 200, fontpage_385_200_200), // '새' -- '새' FONTDATA_ITEM(386, 164, 164, fontpage_386_164_164), // '설' -- '설' - FONTDATA_ITEM(386, 216, 216, fontpage_386_216_216), // '션' -- '션' FONTDATA_ITEM(387, 140, 141, fontpage_387_140_141), // '소' -- '속' FONTDATA_ITEM(389, 164, 164, fontpage_389_164_164), // '스' -- '스' FONTDATA_ITEM(389, 172, 172, fontpage_389_172_172), // '슬' -- '슬' @@ -495,6 +510,7 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(398, 252, 253, fontpage_398_252_253), // '일' -- '읽' FONTDATA_ITEM(399, 133, 133, fontpage_399_133_133), // '입' -- '입' FONTDATA_ITEM(399, 144, 145, fontpage_399_144_145), // '자' -- '작' + FONTDATA_ITEM(399, 152, 152, fontpage_399_152_152), // '잘' -- '잘' FONTDATA_ITEM(399, 165, 165, fontpage_399_165_165), // '장' -- '장' FONTDATA_ITEM(399, 172, 172, fontpage_399_172_172), // '재' -- '재' FONTDATA_ITEM(400, 128, 128, fontpage_400_128_128), // '저' -- '저' @@ -515,7 +531,6 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(412, 216, 216, fontpage_412_216_216), // '치' -- '치' FONTDATA_ITEM(412, 232, 232, fontpage_412_232_232), // '침' -- '침' FONTDATA_ITEM(412, 244, 244, fontpage_412_244_244), // '카' -- '카' - FONTDATA_ITEM(413, 152, 152, fontpage_413_152_152), // '캘' -- '캘' FONTDATA_ITEM(414, 156, 156, fontpage_414_156_156), // '켜' -- '켜' FONTDATA_ITEM(417, 209, 209, fontpage_417_209_209), // '탑' -- '탑' FONTDATA_ITEM(418, 176, 176, fontpage_418_176_176), // '터' -- '터' diff --git a/Marlin/src/lcd/dogm/fontdata/langdata_pl.h b/Marlin/src/lcd/dogm/fontdata/langdata_pl.h index 0cc607468e19..926f07529537 100644 --- a/Marlin/src/lcd/dogm/fontdata/langdata_pl.h +++ b/Marlin/src/lcd/dogm/fontdata/langdata_pl.h @@ -5,32 +5,33 @@ */ #include -const u8g_fntpgm_uint8_t fontpage_2_133_133[30] U8G_FONT_SECTION("fontpage_2_133_133") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x85,0x85,0x00,0x05,0xfe,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0xfe,0x70,0x08,0x78,0x88,0x78,0x20,0x30}; +const u8g_fntpgm_uint8_t fontpage_2_132_133[45] U8G_FONT_SECTION("fontpage_2_132_133") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x84,0x85,0x00,0x07,0xFE,0x00, + 0x00,0x05,0x09,0x09,0x06,0x00,0xFE,0x70,0x88,0x88,0xF8,0x88,0x88,0x88,0x10,0x08, + 0x05,0x07,0x07,0x06,0x00,0xFE,0x70,0x08,0x78,0x88,0x78,0x20,0x30}; const u8g_fntpgm_uint8_t fontpage_2_135_135[31] U8G_FONT_SECTION("fontpage_2_135_135") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x87,0x87,0x00,0x08,0x00,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x87,0x87,0x00,0x08,0x00,0x00, 0x00,0x05,0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0x70,0x88,0x80,0x88,0x70}; const u8g_fntpgm_uint8_t fontpage_2_153_153[30] U8G_FONT_SECTION("fontpage_2_153_153") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x99,0x99,0x00,0x05,0xfe,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0xfe,0x70,0x88,0xf0,0x80,0x70,0x20,0x30}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x99,0x99,0x00,0x05,0xFE,0x00, + 0x00,0x05,0x07,0x07,0x06,0x00,0xFE,0x70,0x88,0xF0,0x80,0x70,0x20,0x30}; const u8g_fntpgm_uint8_t fontpage_2_193_196[73] U8G_FONT_SECTION("fontpage_2_193_196") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc1,0xc4,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x40,0x40,0x60,0xc0,0x40,0x40,0x78,0x03,0x07, - 0x07,0x06,0x01,0x00,0xc0,0x40,0x60,0xc0,0x40,0x40,0xe0,0x05,0x0a,0x0a,0x06,0x00, - 0x00,0x10,0x20,0x00,0x88,0x88,0xc8,0xa8,0x98,0x88,0x88,0x05,0x08,0x08,0x06,0x00, - 0x00,0x10,0x20,0x00,0xb0,0xc8,0x88,0x88,0x88}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC1,0xC4,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x40,0x40,0x60,0xC0,0x40,0x40,0x78,0x03,0x07, + 0x07,0x06,0x01,0x00,0xC0,0x40,0x60,0xC0,0x40,0x40,0xE0,0x05,0x0A,0x0A,0x06,0x00, + 0x00,0x10,0x20,0x00,0x88,0x88,0xC8,0xA8,0x98,0x88,0x88,0x05,0x08,0x08,0x06,0x00, + 0x00,0x10,0x20,0x00,0xB0,0xC8,0x88,0x88,0x88}; const u8g_fntpgm_uint8_t fontpage_2_218_219[47] U8G_FONT_SECTION("fontpage_2_218_219") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xda,0xdb,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x06,0x00,0x00,0x10,0x20,0x00,0x70,0x88,0x80,0x70,0x08,0x88, - 0x70,0x05,0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0x78,0x80,0x70,0x08,0xf0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDA,0xDB,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x0A,0x0A,0x06,0x00,0x00,0x10,0x20,0x00,0x70,0x88,0x80,0x70,0x08,0x88, + 0x70,0x05,0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0x78,0x80,0x70,0x08,0xF0}; const u8g_fntpgm_uint8_t fontpage_2_252_252[30] U8G_FONT_SECTION("fontpage_2_252_252") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfc,0xfc,0x00,0x07,0x00,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x00,0xf8,0x10,0x20,0x40,0xf8}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFC,0xFC,0x00,0x07,0x00,0x00, + 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x00,0xF8,0x10,0x20,0x40,0xF8}; #define FONTDATA_ITEM(page, begin, end, data) { page, begin, end, COUNT(data), data } static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { - FONTDATA_ITEM(2, 133, 133, fontpage_2_133_133), // 'ą' -- 'ą' + FONTDATA_ITEM(2, 132, 133, fontpage_2_132_133), // 'Ą' -- 'ą' FONTDATA_ITEM(2, 135, 135, fontpage_2_135_135), // 'ć' -- 'ć' FONTDATA_ITEM(2, 153, 153, fontpage_2_153_153), // 'ę' -- 'ę' FONTDATA_ITEM(2, 193, 196, fontpage_2_193_196), // 'Ł' -- 'ń' diff --git a/Marlin/src/lcd/dogm/fontdata/langdata_ro.h b/Marlin/src/lcd/dogm/fontdata/langdata_ro.h new file mode 100644 index 000000000000..ffda82764fa2 --- /dev/null +++ b/Marlin/src/lcd/dogm/fontdata/langdata_ro.h @@ -0,0 +1,9 @@ +/** + * Generated automatically by buildroot/share/fonts/uxggenpages.sh + * Contents will be REPLACED by future processing! + * Use genallfont.sh to generate font data for updated languages. + */ +#include + +#define FONTDATA_ITEM(page, begin, end, data) { page, begin, end, COUNT(data), data } +static const uxg_fontinfo_t g_fontinfo[] PROGMEM = {}; diff --git a/Marlin/src/lcd/dogm/fontdata/langdata_ru.h b/Marlin/src/lcd/dogm/fontdata/langdata_ru.h index 85a0bde3abdc..4edd6e74e304 100644 --- a/Marlin/src/lcd/dogm/fontdata/langdata_ru.h +++ b/Marlin/src/lcd/dogm/fontdata/langdata_ru.h @@ -5,74 +5,69 @@ */ #include -const u8g_fntpgm_uint8_t fontpage_8_144_152[135] U8G_FONT_SECTION("fontpage_8_144_152") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x90,0x98,0x00,0x07,0xff,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0xf8,0x88,0x88,0x88,0x05,0x07, - 0x07,0x06,0x00,0x00,0xf0,0x80,0x80,0xf0,0x88,0x88,0xf0,0x05,0x07,0x07,0x06,0x00, - 0x00,0xf0,0x88,0x88,0xf0,0x88,0x88,0xf0,0x05,0x07,0x07,0x06,0x00,0x00,0xf8,0x80, - 0x80,0x80,0x80,0x80,0x80,0x05,0x08,0x08,0x06,0x00,0xff,0x30,0x50,0x50,0x50,0x50, - 0x50,0xf8,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0xf8,0x80,0x80,0xf0,0x80,0x80,0xf8, - 0x05,0x07,0x07,0x06,0x00,0x00,0xa8,0xa8,0x70,0x20,0x70,0xa8,0xa8,0x05,0x07,0x07, +const u8g_fntpgm_uint8_t fontpage_8_144_168[348] U8G_FONT_SECTION("fontpage_8_144_168") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x90,0xA8,0x00,0x0A,0xFE,0x00, + 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0xF8,0x88,0x88,0x88,0x05,0x07, + 0x07,0x06,0x00,0x00,0xF0,0x80,0x80,0xF0,0x88,0x88,0xF0,0x05,0x07,0x07,0x06,0x00, + 0x00,0xF0,0x88,0x88,0xF0,0x88,0x88,0xF0,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x80, + 0x80,0x80,0x80,0x80,0x80,0x05,0x08,0x08,0x06,0x00,0xFF,0x30,0x50,0x50,0x50,0x50, + 0x50,0xF8,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8, + 0x05,0x07,0x07,0x06,0x00,0x00,0xA8,0xA8,0x70,0x20,0x70,0xA8,0xA8,0x05,0x07,0x07, 0x06,0x00,0x00,0x70,0x88,0x08,0x70,0x08,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00, - 0x88,0x88,0x98,0xa8,0xc8,0x88,0x88}; -const u8g_fntpgm_uint8_t fontpage_8_154_168[214] U8G_FONT_SECTION("fontpage_8_154_168") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9a,0xa8,0x00,0x07,0xfe,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x90,0xa0,0xc0,0xa0,0x90,0x88,0x05,0x07, - 0x07,0x06,0x00,0x00,0x38,0x48,0x48,0x48,0x48,0x48,0x88,0x05,0x07,0x07,0x06,0x00, - 0x00,0x88,0xd8,0xa8,0x88,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88, - 0x88,0xf8,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0x88,0x88, - 0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0xf8,0x88,0x88,0x88,0x88,0x88,0x88,0x05, - 0x07,0x07,0x06,0x00,0x00,0xf0,0x88,0x88,0xf0,0x80,0x80,0x80,0x05,0x07,0x07,0x06, - 0x00,0x00,0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0xf8, - 0x20,0x20,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0x88, - 0x78,0x08,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x70,0xa8,0xa8,0xa8,0x70,0x20, - 0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x05,0x09,0x09, - 0x06,0x00,0xfe,0x90,0x90,0x90,0x90,0x90,0x90,0xf8,0x08,0x08,0x05,0x07,0x07,0x06, - 0x00,0x00,0x88,0x88,0x88,0x78,0x08,0x08,0x08,0x05,0x07,0x07,0x06,0x00,0x00,0xa8, - 0xa8,0xa8,0xa8,0xa8,0xa8,0xf8}; + 0x88,0x88,0x98,0xA8,0xC8,0x88,0x88,0x05,0x0A,0x0A,0x06,0x00,0x00,0x88,0x70,0x00, + 0x88,0x88,0x98,0xA8,0xC8,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x90,0xA0, + 0xC0,0xA0,0x90,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x38,0x48,0x48,0x48,0x48,0x48, + 0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0xD8,0xA8,0x88,0x88,0x88,0x88,0x05,0x07, + 0x07,0x06,0x00,0x00,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00, + 0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x88, + 0x88,0x88,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0xF0,0x88,0x88,0xF0,0x80, + 0x80,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x05, + 0x07,0x07,0x06,0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06, + 0x00,0x00,0x88,0x88,0x88,0x88,0x78,0x08,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x20, + 0x70,0xA8,0xA8,0xA8,0x70,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x50,0x20, + 0x50,0x88,0x88,0x05,0x09,0x09,0x06,0x00,0xFE,0x90,0x90,0x90,0x90,0x90,0x90,0xF8, + 0x08,0x08,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0x78,0x08,0x08,0x08,0x05, + 0x07,0x07,0x06,0x00,0x00,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xF8}; const u8g_fntpgm_uint8_t fontpage_8_171_173[56] U8G_FONT_SECTION("fontpage_8_171_173") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xab,0xad,0x00,0x07,0x00,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0xc8,0xa8,0xa8,0xc8,0x04,0x07, - 0x07,0x06,0x01,0x00,0x80,0x80,0x80,0xe0,0x90,0x90,0xe0,0x05,0x07,0x07,0x06,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAB,0xAD,0x00,0x07,0x00,0x00, + 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0xC8,0xA8,0xA8,0xC8,0x04,0x07, + 0x07,0x06,0x01,0x00,0x80,0x80,0x80,0xE0,0x90,0x90,0xE0,0x05,0x07,0x07,0x06,0x00, 0x00,0x70,0x88,0x08,0x78,0x08,0x88,0x70}; -const u8g_fntpgm_uint8_t fontpage_8_175_201[334] U8G_FONT_SECTION("fontpage_8_175_201") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xaf,0xc9,0x00,0x08,0xfe,0x00, +const u8g_fntpgm_uint8_t fontpage_8_175_207[400] U8G_FONT_SECTION("fontpage_8_175_207") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAF,0xCF,0x00,0x08,0xFE,0x00, 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x78,0x88,0x88,0x78,0x28,0x48,0x88,0x05,0x05, 0x05,0x06,0x00,0x00,0x70,0x08,0x78,0x88,0x78,0x05,0x07,0x07,0x06,0x00,0x00,0x70, - 0x80,0xf0,0x88,0x88,0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xf0,0x88,0xf0,0x88, - 0xf0,0x05,0x05,0x05,0x06,0x00,0x00,0xf8,0x80,0x80,0x80,0x80,0x05,0x06,0x06,0x06, - 0x00,0xff,0x30,0x50,0x50,0x50,0xf8,0x88,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x88, - 0xf0,0x80,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xa8,0x70,0x20,0x70,0xa8,0x05,0x05, + 0x80,0xF0,0x88,0x88,0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xF0,0x88,0xF0,0x88, + 0xF0,0x05,0x05,0x05,0x06,0x00,0x00,0xF8,0x80,0x80,0x80,0x80,0x05,0x06,0x06,0x06, + 0x00,0xFF,0x30,0x50,0x50,0x50,0xF8,0x88,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x88, + 0xF0,0x80,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xA8,0x70,0x20,0x70,0xA8,0x05,0x05, 0x05,0x06,0x00,0x00,0x70,0x88,0x30,0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0x88, - 0x98,0xa8,0xc8,0x88,0x05,0x08,0x08,0x06,0x00,0x00,0x88,0x70,0x00,0x88,0x98,0xa8, - 0xc8,0x88,0x04,0x05,0x05,0x06,0x01,0x00,0x90,0xa0,0xc0,0xa0,0x90,0x05,0x05,0x05, - 0x06,0x00,0x00,0x38,0x48,0x48,0x48,0x88,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0xd8, - 0xa8,0x88,0x88,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x88,0xf8,0x88,0x88,0x05,0x05, - 0x05,0x06,0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xf8, - 0x88,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0xfe,0xf0,0x88,0x88,0x88,0xf0,0x80, + 0x98,0xA8,0xC8,0x88,0x05,0x08,0x08,0x06,0x00,0x00,0x88,0x70,0x00,0x88,0x98,0xA8, + 0xC8,0x88,0x04,0x05,0x05,0x06,0x01,0x00,0x90,0xA0,0xC0,0xA0,0x90,0x05,0x05,0x05, + 0x06,0x00,0x00,0x38,0x48,0x48,0x48,0x88,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0xD8, + 0xA8,0x88,0x88,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x88,0xF8,0x88,0x88,0x05,0x05, + 0x05,0x06,0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xF8, + 0x88,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0xFE,0xF0,0x88,0x88,0x88,0xF0,0x80, 0x80,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x88,0x80,0x88,0x70,0x05,0x05,0x05,0x06, - 0x00,0x00,0xf8,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0xfe,0x88,0x88,0x88, - 0x88,0x78,0x08,0x70,0x05,0x09,0x09,0x06,0x00,0xfe,0x20,0x20,0x70,0xa8,0xa8,0xa8, + 0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0xFE,0x88,0x88,0x88, + 0x88,0x78,0x08,0x70,0x05,0x09,0x09,0x06,0x00,0xFE,0x20,0x20,0x70,0xA8,0xA8,0xA8, 0x70,0x20,0x20,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x05,0x07, - 0x07,0x06,0x00,0xfe,0x90,0x90,0x90,0x90,0xf8,0x08,0x08,0x05,0x05,0x05,0x06,0x00, - 0x00,0x88,0x88,0x78,0x08,0x08,0x05,0x05,0x05,0x06,0x00,0x00,0xa8,0xa8,0xa8,0xa8, - 0xf8,0x05,0x07,0x07,0x06,0x00,0xfe,0xa8,0xa8,0xa8,0xa8,0xf8,0x08,0x08}; -const u8g_fntpgm_uint8_t fontpage_8_203_207[72] U8G_FONT_SECTION("fontpage_8_203_207") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcb,0xcf,0x00,0x05,0x00,0x00, - 0x00,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x88,0xc8,0xa8,0xc8,0x04,0x05,0x05,0x06, - 0x01,0x00,0x80,0x80,0xe0,0x90,0xe0,0x04,0x05,0x05,0x06,0x01,0x00,0xe0,0x10,0x70, - 0x10,0xe0,0x05,0x05,0x05,0x06,0x00,0x00,0x90,0xa8,0xe8,0xa8,0x90,0x04,0x05,0x05, - 0x06,0x01,0x00,0x70,0x90,0x70,0x50,0x90}; + 0x07,0x06,0x00,0xFE,0x90,0x90,0x90,0x90,0xF8,0x08,0x08,0x05,0x05,0x05,0x06,0x00, + 0x00,0x88,0x88,0x78,0x08,0x08,0x05,0x05,0x05,0x06,0x00,0x00,0xA8,0xA8,0xA8,0xA8, + 0xF8,0x05,0x07,0x07,0x06,0x00,0xFE,0xA8,0xA8,0xA8,0xA8,0xF8,0x08,0x08,0x05,0x05, + 0x05,0x06,0x00,0x00,0xC0,0x40,0x70,0x48,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0x88, + 0x88,0xC8,0xA8,0xC8,0x04,0x05,0x05,0x06,0x01,0x00,0x80,0x80,0xE0,0x90,0xE0,0x04, + 0x05,0x05,0x06,0x01,0x00,0xE0,0x10,0x70,0x10,0xE0,0x05,0x05,0x05,0x06,0x00,0x00, + 0x90,0xA8,0xE8,0xA8,0x90,0x04,0x05,0x05,0x06,0x01,0x00,0x70,0x90,0x70,0x50,0x90 + }; const u8g_fntpgm_uint8_t fontpage_8_209_209[30] U8G_FONT_SECTION("fontpage_8_209_209") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd1,0xd1,0x00,0x07,0x00,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x50,0x00,0x70,0x88,0xf0,0x80,0x70}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD1,0xD1,0x00,0x07,0x00,0x00, + 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x50,0x00,0x70,0x88,0xF0,0x80,0x70}; #define FONTDATA_ITEM(page, begin, end, data) { page, begin, end, COUNT(data), data } static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { - FONTDATA_ITEM(8, 144, 152, fontpage_8_144_152), // 'А' -- 'И' - FONTDATA_ITEM(8, 154, 168, fontpage_8_154_168), // 'К' -- 'Ш' + FONTDATA_ITEM(8, 144, 168, fontpage_8_144_168), // 'А' -- 'Ш' FONTDATA_ITEM(8, 171, 173, fontpage_8_171_173), // 'Ы' -- 'Э' - FONTDATA_ITEM(8, 175, 201, fontpage_8_175_201), // 'Я' -- 'щ' - FONTDATA_ITEM(8, 203, 207, fontpage_8_203_207), // 'ы' -- 'я' + FONTDATA_ITEM(8, 175, 207, fontpage_8_175_207), // 'Я' -- 'я' FONTDATA_ITEM(8, 209, 209, fontpage_8_209_209), // 'ё' -- 'ё' }; diff --git a/Marlin/src/lcd/dogm/fontdata/langdata_sk.h b/Marlin/src/lcd/dogm/fontdata/langdata_sk.h index a75fa2c92647..d2e7ec2c56db 100644 --- a/Marlin/src/lcd/dogm/fontdata/langdata_sk.h +++ b/Marlin/src/lcd/dogm/fontdata/langdata_sk.h @@ -6,51 +6,43 @@ #include const u8g_fntpgm_uint8_t fontpage_2_140_143[79] U8G_FONT_SECTION("fontpage_2_140_143") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8c,0x8f,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x06,0x00,0x00,0x50,0x20,0x00,0x70,0x88,0x80,0x80,0x80,0x88, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8C,0x8F,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x0A,0x0A,0x06,0x00,0x00,0x50,0x20,0x00,0x70,0x88,0x80,0x80,0x80,0x88, 0x70,0x05,0x08,0x08,0x06,0x00,0x00,0x50,0x20,0x00,0x70,0x88,0x80,0x88,0x70,0x05, - 0x0a,0x0a,0x06,0x00,0x00,0x50,0x20,0x00,0xf0,0x48,0x48,0x48,0x48,0x48,0xf0,0x06, - 0x0a,0x0a,0x06,0x00,0x00,0x14,0x08,0x00,0x08,0x08,0x78,0x88,0x88,0x88,0x78}; -const u8g_fntpgm_uint8_t fontpage_2_185_186[49] U8G_FONT_SECTION("fontpage_2_185_186") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb9,0xba,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x06,0x00,0x00,0x10,0x20,0x00,0x80,0x80,0x80,0x80,0x80,0x80, - 0xf8,0x03,0x0a,0x0a,0x06,0x01,0x00,0x20,0x40,0x00,0xc0,0x40,0x40,0x40,0x40,0x40, - 0xe0}; -const u8g_fntpgm_uint8_t fontpage_2_189_190[49] U8G_FONT_SECTION("fontpage_2_189_190") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbd,0xbe,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x06,0x00,0x00,0x50,0x20,0x00,0x80,0x80,0x80,0x80,0x80,0x80, - 0xf8,0x03,0x0a,0x0a,0x06,0x01,0x00,0xa0,0x40,0x00,0xc0,0x40,0x40,0x40,0x40,0x40, - 0xe0}; + 0x0A,0x0A,0x06,0x00,0x00,0x50,0x20,0x00,0xF0,0x48,0x48,0x48,0x48,0x48,0xF0,0x06, + 0x0A,0x0A,0x06,0x00,0x00,0x14,0x08,0x00,0x08,0x08,0x78,0x88,0x88,0x88,0x78}; +const u8g_fntpgm_uint8_t fontpage_2_186_186[33] U8G_FONT_SECTION("fontpage_2_186_186") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBA,0xBA,0x00,0x0A,0x00,0x00, + 0x00,0x03,0x0A,0x0A,0x06,0x01,0x00,0x20,0x40,0x00,0xC0,0x40,0x40,0x40,0x40,0x40, + 0xE0}; +const u8g_fntpgm_uint8_t fontpage_2_190_190[33] U8G_FONT_SECTION("fontpage_2_190_190") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBE,0xBE,0x00,0x0A,0x00,0x00, + 0x00,0x03,0x0A,0x0A,0x06,0x01,0x00,0xA0,0x40,0x00,0xC0,0x40,0x40,0x40,0x40,0x40, + 0xE0}; const u8g_fntpgm_uint8_t fontpage_2_199_200[47] U8G_FONT_SECTION("fontpage_2_199_200") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc7,0xc8,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x06,0x00,0x00,0x50,0x20,0x00,0x88,0x88,0xc8,0xa8,0x98,0x88, - 0x88,0x05,0x08,0x08,0x06,0x00,0x00,0x50,0x20,0x00,0xb0,0xc8,0x88,0x88,0x88}; -const u8g_fntpgm_uint8_t fontpage_2_212_213[47] U8G_FONT_SECTION("fontpage_2_212_213") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd4,0xd5,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x06,0x00,0x00,0x10,0x20,0x00,0xf0,0x88,0x88,0xf0,0xa0,0x90, - 0x88,0x05,0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0xb0,0xc8,0x80,0x80,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC7,0xC8,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x0A,0x0A,0x06,0x00,0x00,0x50,0x20,0x00,0x88,0x88,0xC8,0xA8,0x98,0x88, + 0x88,0x05,0x08,0x08,0x06,0x00,0x00,0x50,0x20,0x00,0xB0,0xC8,0x88,0x88,0x88}; const u8g_fntpgm_uint8_t fontpage_2_224_225[47] U8G_FONT_SECTION("fontpage_2_224_225") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe0,0xe1,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x06,0x00,0x00,0x50,0x20,0x00,0x70,0x88,0x80,0x70,0x08,0x88, - 0x70,0x05,0x08,0x08,0x06,0x00,0x00,0x50,0x20,0x00,0x78,0x80,0x70,0x08,0xf0}; -const u8g_fntpgm_uint8_t fontpage_2_228_229[49] U8G_FONT_SECTION("fontpage_2_228_229") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe4,0xe5,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x06,0x00,0x00,0x50,0x20,0x00,0xf8,0x20,0x20,0x20,0x20,0x20, - 0x20,0x05,0x0a,0x0a,0x06,0x00,0x00,0x50,0x20,0x00,0x20,0x20,0xf8,0x20,0x20,0x20, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE0,0xE1,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x0A,0x0A,0x06,0x00,0x00,0x50,0x20,0x00,0x70,0x88,0x80,0x70,0x08,0x88, + 0x70,0x05,0x08,0x08,0x06,0x00,0x00,0x50,0x20,0x00,0x78,0x80,0x70,0x08,0xF0}; +const u8g_fntpgm_uint8_t fontpage_2_229_229[33] U8G_FONT_SECTION("fontpage_2_229_229") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE5,0xE5,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x0A,0x0A,0x06,0x00,0x00,0x50,0x20,0x00,0x20,0x20,0xF8,0x20,0x20,0x20, 0x18}; const u8g_fntpgm_uint8_t fontpage_2_253_254[47] U8G_FONT_SECTION("fontpage_2_253_254") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfd,0xfe,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x06,0x00,0x00,0x50,0x20,0x00,0xf8,0x08,0x10,0x20,0x40,0x80, - 0xf8,0x05,0x08,0x08,0x06,0x00,0x00,0x50,0x20,0x00,0xf8,0x10,0x20,0x40,0xf8}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFD,0xFE,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x0A,0x0A,0x06,0x00,0x00,0x50,0x20,0x00,0xF8,0x08,0x10,0x20,0x40,0x80, + 0xF8,0x05,0x08,0x08,0x06,0x00,0x00,0x50,0x20,0x00,0xF8,0x10,0x20,0x40,0xF8}; #define FONTDATA_ITEM(page, begin, end, data) { page, begin, end, COUNT(data), data } static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(2, 140, 143, fontpage_2_140_143), // 'Č' -- 'ď' - FONTDATA_ITEM(2, 185, 186, fontpage_2_185_186), // 'Ĺ' -- 'ĺ' - FONTDATA_ITEM(2, 189, 190, fontpage_2_189_190), // 'Ľ' -- 'ľ' + FONTDATA_ITEM(2, 186, 186, fontpage_2_186_186), // 'ĺ' -- 'ĺ' + FONTDATA_ITEM(2, 190, 190, fontpage_2_190_190), // 'ľ' -- 'ľ' FONTDATA_ITEM(2, 199, 200, fontpage_2_199_200), // 'Ň' -- 'ň' - FONTDATA_ITEM(2, 212, 213, fontpage_2_212_213), // 'Ŕ' -- 'ŕ' FONTDATA_ITEM(2, 224, 225, fontpage_2_224_225), // 'Š' -- 'š' - FONTDATA_ITEM(2, 228, 229, fontpage_2_228_229), // 'Ť' -- 'ť' + FONTDATA_ITEM(2, 229, 229, fontpage_2_229_229), // 'ť' -- 'ť' FONTDATA_ITEM(2, 253, 254, fontpage_2_253_254), // 'Ž' -- 'ž' }; diff --git a/Marlin/src/lcd/dogm/fontdata/langdata_test.h b/Marlin/src/lcd/dogm/fontdata/langdata_test.h index 033188359d13..c397d8b4b95b 100644 --- a/Marlin/src/lcd/dogm/fontdata/langdata_test.h +++ b/Marlin/src/lcd/dogm/fontdata/langdata_test.h @@ -6,216 +6,222 @@ #include const u8g_fntpgm_uint8_t fontpage_8_128_255[1677] U8G_FONT_SECTION("fontpage_8_128_255") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0x00,0x0a,0xfe,0x00, - 0x00,0x05,0x0a,0x0a,0x06,0x00,0x00,0x40,0x20,0x00,0xf8,0x80,0x80,0xf0,0x80,0x80, - 0xf8,0x05,0x09,0x09,0x06,0x00,0x00,0x50,0x00,0xf8,0x80,0x80,0xf0,0x80,0x80,0xf8, - 0x05,0x09,0x09,0x06,0x00,0xfe,0xe0,0x40,0x40,0x70,0x48,0x48,0x48,0x08,0x30,0x05, - 0x0a,0x0a,0x06,0x00,0x00,0x10,0x20,0x00,0xf8,0x80,0x80,0x80,0x80,0x80,0x80,0x05, - 0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x80,0xf0,0x80,0x88,0x70,0x05,0x07,0x07,0x06, - 0x00,0x00,0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x03,0x07,0x07,0x06,0x01,0x00,0xe0, - 0x40,0x40,0x40,0x40,0x40,0xe0,0x03,0x09,0x09,0x06,0x01,0x00,0xa0,0x00,0xe0,0x40, - 0x40,0x40,0x40,0x40,0xe0,0x05,0x07,0x07,0x06,0x00,0x00,0x38,0x10,0x10,0x10,0x10, - 0x90,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x60,0xa0,0xa0,0xb0,0xa8,0xa8,0xb0,0x05, - 0x07,0x07,0x06,0x00,0x00,0xa0,0xa0,0xa0,0xf0,0xa8,0xa8,0xb0,0x05,0x07,0x07,0x06, - 0x00,0x00,0xe0,0x40,0x40,0x70,0x48,0x48,0x48,0x05,0x0a,0x0a,0x06,0x00,0x00,0x10, - 0x20,0x00,0x88,0x90,0xa0,0xc0,0xa0,0x90,0x88,0x05,0x0a,0x0a,0x06,0x00,0x00,0x40, - 0x20,0x00,0x88,0x88,0x98,0xa8,0xc8,0x88,0x88,0x05,0x0a,0x0a,0x06,0x00,0x00,0x88, - 0x70,0x00,0x88,0x88,0x88,0x88,0x78,0x08,0x70,0x05,0x09,0x09,0x06,0x00,0xfe,0x88, - 0x88,0x88,0x88,0x88,0x88,0xf8,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88, - 0x88,0xf8,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0xf0,0x80,0x80,0xf0,0x88, - 0x88,0xf0,0x05,0x07,0x07,0x06,0x00,0x00,0xf0,0x88,0x88,0xf0,0x88,0x88,0xf0,0x05, - 0x07,0x07,0x06,0x00,0x00,0xf8,0x80,0x80,0x80,0x80,0x80,0x80,0x05,0x08,0x08,0x06, - 0x00,0xff,0x30,0x50,0x50,0x50,0x50,0x50,0xf8,0x88,0x05,0x07,0x07,0x06,0x00,0x00, - 0xf8,0x80,0x80,0xf0,0x80,0x80,0xf8,0x05,0x07,0x07,0x06,0x00,0x00,0xa8,0xa8,0x70, - 0x20,0x70,0xa8,0xa8,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x08,0x70,0x08,0x88, - 0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x98,0xa8,0xc8,0x88,0x88,0x05,0x0a, - 0x0a,0x06,0x00,0x00,0x88,0x70,0x00,0x88,0x88,0x98,0xa8,0xc8,0x88,0x88,0x05,0x07, - 0x07,0x06,0x00,0x00,0x88,0x90,0xa0,0xc0,0xa0,0x90,0x88,0x05,0x07,0x07,0x06,0x00, - 0x00,0x38,0x48,0x48,0x48,0x48,0x48,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0xd8, - 0xa8,0x88,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0xf8,0x88, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0x00,0x0A,0xFE,0x00, + 0x00,0x05,0x0A,0x0A,0x06,0x00,0x00,0x40,0x20,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80, + 0xF8,0x05,0x09,0x09,0x06,0x00,0x00,0x50,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8, + 0x05,0x09,0x09,0x06,0x00,0xFE,0xE0,0x40,0x40,0x70,0x48,0x48,0x48,0x08,0x30,0x05, + 0x0A,0x0A,0x06,0x00,0x00,0x10,0x20,0x00,0xF8,0x80,0x80,0x80,0x80,0x80,0x80,0x05, + 0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x80,0xF0,0x80,0x88,0x70,0x05,0x07,0x07,0x06, + 0x00,0x00,0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x03,0x07,0x07,0x06,0x01,0x00,0xE0, + 0x40,0x40,0x40,0x40,0x40,0xE0,0x03,0x09,0x09,0x06,0x01,0x00,0xA0,0x00,0xE0,0x40, + 0x40,0x40,0x40,0x40,0xE0,0x05,0x07,0x07,0x06,0x00,0x00,0x38,0x10,0x10,0x10,0x10, + 0x90,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x60,0xA0,0xA0,0xB0,0xA8,0xA8,0xB0,0x05, + 0x07,0x07,0x06,0x00,0x00,0xA0,0xA0,0xA0,0xF0,0xA8,0xA8,0xB0,0x05,0x07,0x07,0x06, + 0x00,0x00,0xE0,0x40,0x40,0x70,0x48,0x48,0x48,0x05,0x0A,0x0A,0x06,0x00,0x00,0x10, + 0x20,0x00,0x88,0x90,0xA0,0xC0,0xA0,0x90,0x88,0x05,0x0A,0x0A,0x06,0x00,0x00,0x40, + 0x20,0x00,0x88,0x88,0x98,0xA8,0xC8,0x88,0x88,0x05,0x0A,0x0A,0x06,0x00,0x00,0x88, + 0x70,0x00,0x88,0x88,0x88,0x88,0x78,0x08,0x70,0x05,0x09,0x09,0x06,0x00,0xFE,0x88, + 0x88,0x88,0x88,0x88,0x88,0xF8,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88, + 0x88,0xF8,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0xF0,0x80,0x80,0xF0,0x88, + 0x88,0xF0,0x05,0x07,0x07,0x06,0x00,0x00,0xF0,0x88,0x88,0xF0,0x88,0x88,0xF0,0x05, + 0x07,0x07,0x06,0x00,0x00,0xF8,0x80,0x80,0x80,0x80,0x80,0x80,0x05,0x08,0x08,0x06, + 0x00,0xFF,0x30,0x50,0x50,0x50,0x50,0x50,0xF8,0x88,0x05,0x07,0x07,0x06,0x00,0x00, + 0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x05,0x07,0x07,0x06,0x00,0x00,0xA8,0xA8,0x70, + 0x20,0x70,0xA8,0xA8,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x08,0x70,0x08,0x88, + 0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x98,0xA8,0xC8,0x88,0x88,0x05,0x0A, + 0x0A,0x06,0x00,0x00,0x88,0x70,0x00,0x88,0x88,0x98,0xA8,0xC8,0x88,0x88,0x05,0x07, + 0x07,0x06,0x00,0x00,0x88,0x90,0xA0,0xC0,0xA0,0x90,0x88,0x05,0x07,0x07,0x06,0x00, + 0x00,0x38,0x48,0x48,0x48,0x48,0x48,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0xD8, + 0xA8,0x88,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0xF8,0x88, 0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x05, - 0x07,0x07,0x06,0x00,0x00,0xf8,0x88,0x88,0x88,0x88,0x88,0x88,0x05,0x07,0x07,0x06, - 0x00,0x00,0xf0,0x88,0x88,0xf0,0x80,0x80,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70, - 0x88,0x80,0x80,0x80,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0xf8,0x20,0x20,0x20, + 0x07,0x07,0x06,0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0x88,0x88,0x05,0x07,0x07,0x06, + 0x00,0x00,0xF0,0x88,0x88,0xF0,0x80,0x80,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70, + 0x88,0x80,0x80,0x80,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x20,0x20,0x20, 0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0x88,0x78,0x08,0x70, - 0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x70,0xa8,0xa8,0xa8,0x70,0x20,0x05,0x07,0x07, - 0x06,0x00,0x00,0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x05,0x09,0x09,0x06,0x00,0xfe, - 0x90,0x90,0x90,0x90,0x90,0x90,0xf8,0x08,0x08,0x05,0x07,0x07,0x06,0x00,0x00,0x88, - 0x88,0x88,0x78,0x08,0x08,0x08,0x05,0x07,0x07,0x06,0x00,0x00,0xa8,0xa8,0xa8,0xa8, - 0xa8,0xa8,0xf8,0x05,0x09,0x09,0x06,0x00,0xfe,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xf8, - 0x08,0x08,0x05,0x07,0x07,0x06,0x00,0x00,0xc0,0x40,0x40,0x70,0x48,0x48,0x70,0x05, - 0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0xc8,0xa8,0xa8,0xc8,0x04,0x07,0x07,0x06, - 0x01,0x00,0x80,0x80,0x80,0xe0,0x90,0x90,0xe0,0x05,0x07,0x07,0x06,0x00,0x00,0x70, - 0x88,0x08,0x78,0x08,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x90,0xa8,0xa8,0xe8, - 0xa8,0xa8,0x90,0x05,0x07,0x07,0x06,0x00,0x00,0x78,0x88,0x88,0x78,0x28,0x48,0x88, + 0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x70,0xA8,0xA8,0xA8,0x70,0x20,0x05,0x07,0x07, + 0x06,0x00,0x00,0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x05,0x09,0x09,0x06,0x00,0xFE, + 0x90,0x90,0x90,0x90,0x90,0x90,0xF8,0x08,0x08,0x05,0x07,0x07,0x06,0x00,0x00,0x88, + 0x88,0x88,0x78,0x08,0x08,0x08,0x05,0x07,0x07,0x06,0x00,0x00,0xA8,0xA8,0xA8,0xA8, + 0xA8,0xA8,0xF8,0x05,0x09,0x09,0x06,0x00,0xFE,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xF8, + 0x08,0x08,0x05,0x07,0x07,0x06,0x00,0x00,0xC0,0x40,0x40,0x70,0x48,0x48,0x70,0x05, + 0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0xC8,0xA8,0xA8,0xC8,0x04,0x07,0x07,0x06, + 0x01,0x00,0x80,0x80,0x80,0xE0,0x90,0x90,0xE0,0x05,0x07,0x07,0x06,0x00,0x00,0x70, + 0x88,0x08,0x78,0x08,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x90,0xA8,0xA8,0xE8, + 0xA8,0xA8,0x90,0x05,0x07,0x07,0x06,0x00,0x00,0x78,0x88,0x88,0x78,0x28,0x48,0x88, 0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x08,0x78,0x88,0x78,0x05,0x07,0x07,0x06,0x00, - 0x00,0x70,0x80,0xf0,0x88,0x88,0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xf0,0x88, - 0xf0,0x88,0xf0,0x05,0x05,0x05,0x06,0x00,0x00,0xf8,0x80,0x80,0x80,0x80,0x05,0x06, - 0x06,0x06,0x00,0xff,0x30,0x50,0x50,0x50,0xf8,0x88,0x05,0x05,0x05,0x06,0x00,0x00, - 0x70,0x88,0xf0,0x80,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xa8,0x70,0x20,0x70,0xa8, + 0x00,0x70,0x80,0xF0,0x88,0x88,0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xF0,0x88, + 0xF0,0x88,0xF0,0x05,0x05,0x05,0x06,0x00,0x00,0xF8,0x80,0x80,0x80,0x80,0x05,0x06, + 0x06,0x06,0x00,0xFF,0x30,0x50,0x50,0x50,0xF8,0x88,0x05,0x05,0x05,0x06,0x00,0x00, + 0x70,0x88,0xF0,0x80,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xA8,0x70,0x20,0x70,0xA8, 0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x88,0x30,0x88,0x70,0x05,0x05,0x05,0x06,0x00, - 0x00,0x88,0x98,0xa8,0xc8,0x88,0x05,0x08,0x08,0x06,0x00,0x00,0x88,0x70,0x00,0x88, - 0x98,0xa8,0xc8,0x88,0x04,0x05,0x05,0x06,0x01,0x00,0x90,0xa0,0xc0,0xa0,0x90,0x05, + 0x00,0x88,0x98,0xA8,0xC8,0x88,0x05,0x08,0x08,0x06,0x00,0x00,0x88,0x70,0x00,0x88, + 0x98,0xA8,0xC8,0x88,0x04,0x05,0x05,0x06,0x01,0x00,0x90,0xA0,0xC0,0xA0,0x90,0x05, 0x05,0x05,0x06,0x00,0x00,0x38,0x48,0x48,0x48,0x88,0x05,0x05,0x05,0x06,0x00,0x00, - 0x88,0xd8,0xa8,0x88,0x88,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x88,0xf8,0x88,0x88, + 0x88,0xD8,0xA8,0x88,0x88,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x88,0xF8,0x88,0x88, 0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x05,0x05,0x05,0x06,0x00, - 0x00,0xf8,0x88,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0xfe,0xf0,0x88,0x88,0x88, - 0xf0,0x80,0x80,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x88,0x80,0x88,0x70,0x05,0x05, - 0x05,0x06,0x00,0x00,0xf8,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0xfe,0x88, - 0x88,0x88,0x88,0x78,0x08,0x70,0x05,0x09,0x09,0x06,0x00,0xfe,0x20,0x20,0x70,0xa8, - 0xa8,0xa8,0x70,0x20,0x20,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x50,0x20,0x50,0x88, - 0x05,0x07,0x07,0x06,0x00,0xfe,0x90,0x90,0x90,0x90,0xf8,0x08,0x08,0x05,0x05,0x05, - 0x06,0x00,0x00,0x88,0x88,0x78,0x08,0x08,0x05,0x05,0x05,0x06,0x00,0x00,0xa8,0xa8, - 0xa8,0xa8,0xf8,0x05,0x07,0x07,0x06,0x00,0xfe,0xa8,0xa8,0xa8,0xa8,0xf8,0x08,0x08, - 0x05,0x05,0x05,0x06,0x00,0x00,0xc0,0x40,0x70,0x48,0x70,0x05,0x05,0x05,0x06,0x00, - 0x00,0x88,0x88,0xc8,0xa8,0xc8,0x04,0x05,0x05,0x06,0x01,0x00,0x80,0x80,0xe0,0x90, - 0xe0,0x04,0x05,0x05,0x06,0x01,0x00,0xe0,0x10,0x70,0x10,0xe0,0x05,0x05,0x05,0x06, - 0x00,0x00,0x90,0xa8,0xe8,0xa8,0x90,0x04,0x05,0x05,0x06,0x01,0x00,0x70,0x90,0x70, - 0x50,0x90,0x05,0x08,0x08,0x06,0x00,0x00,0x40,0x20,0x00,0x70,0x88,0xf0,0x80,0x70, - 0x05,0x07,0x07,0x06,0x00,0x00,0x50,0x00,0x70,0x88,0xf0,0x80,0x70,0x05,0x09,0x09, - 0x06,0x00,0xfe,0x40,0xe0,0x40,0x70,0x48,0x48,0x48,0x08,0x10,0x05,0x08,0x08,0x06, - 0x00,0x00,0x10,0x20,0x00,0xf8,0x80,0x80,0x80,0x80,0x04,0x05,0x05,0x06,0x01,0x00, - 0x70,0x80,0xe0,0x80,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0x78,0x80,0x70,0x08,0xf0, - 0x03,0x06,0x06,0x06,0x01,0x00,0x40,0x00,0xc0,0x40,0x40,0xe0,0x03,0x06,0x06,0x06, - 0x01,0x00,0xa0,0x00,0xc0,0x40,0x40,0xe0,0x04,0x08,0x08,0x06,0x01,0xfe,0x10,0x00, - 0x30,0x10,0x10,0x10,0x90,0x60,0x05,0x05,0x05,0x06,0x00,0x00,0x60,0xa0,0xb0,0xa8, - 0xb0,0x05,0x05,0x05,0x06,0x00,0x00,0xa0,0xa0,0xf0,0xa8,0xb0,0x05,0x07,0x07,0x06, - 0x00,0x00,0x40,0xe0,0x40,0x70,0x48,0x48,0x48,0x04,0x08,0x08,0x06,0x01,0x00,0x20, - 0x40,0x00,0x90,0xa0,0xc0,0xa0,0x90,0x05,0x08,0x08,0x06,0x00,0x00,0x40,0x20,0x00, - 0x88,0x98,0xa8,0xc8,0x88,0x05,0x0a,0x0a,0x06,0x00,0xfe,0x88,0x70,0x00,0x88,0x88, - 0x88,0x88,0x78,0x08,0x70,0x05,0x07,0x07,0x06,0x00,0xfe,0x88,0x88,0x88,0x88,0xf8, - 0x20,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x50,0x88,0x88,0xa8,0xa8,0xa8,0x50,0x05, - 0x05,0x05,0x06,0x00,0x00,0x50,0x88,0xa8,0xa8,0x50,0x05,0x07,0x07,0x06,0x00,0x00, - 0x40,0xf0,0x40,0x70,0x48,0x48,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x40,0x40,0xf0, - 0x40,0x70,0x48,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x98,0xa0,0xa0,0xf8,0xa0,0xa0, - 0x98,0x05,0x05,0x05,0x06,0x00,0x00,0x98,0xa0,0xf8,0xa0,0x98,0x05,0x07,0x07,0x06, - 0x00,0x00,0x20,0x50,0x50,0x88,0xf8,0xa8,0xa8,0x05,0x06,0x06,0x06,0x00,0x00,0x20, - 0x50,0x50,0x88,0xf8,0xa8,0x05,0x07,0x07,0x06,0x00,0x00,0x90,0x90,0xb8,0xf8,0xb8, - 0xb8,0xb8,0x05,0x05,0x05,0x06,0x00,0x00,0x90,0x90,0xf8,0xb8,0xb8,0x05,0x08,0x08, - 0x06,0x00,0x00,0xf8,0x88,0x50,0x50,0x70,0xa8,0xa8,0xa8,0x05,0x06,0x06,0x06,0x00, - 0x00,0xf8,0x88,0x50,0x70,0xa8,0xa8,0x06,0x08,0x08,0x06,0x00,0x00,0xfc,0xc4,0xa8, - 0x90,0xf8,0xb8,0xb8,0xa8,0x06,0x06,0x06,0x06,0x00,0x00,0xfc,0xa8,0x90,0xf8,0xb8, - 0xa8,0x05,0x0c,0x0c,0x06,0x00,0xfe,0x50,0x20,0x00,0x70,0x88,0x08,0x30,0x08,0x08, - 0x70,0x80,0x70,0x05,0x0a,0x0a,0x06,0x00,0xfe,0x50,0x20,0x00,0x70,0x88,0x30,0x08, - 0x70,0x80,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0xa8,0xa8,0xa8,0x70,0x20,0x20,0x20, - 0x05,0x05,0x05,0x06,0x00,0x00,0xa8,0xa8,0x70,0x20,0x20,0x05,0x07,0x07,0x06,0x00, - 0x00,0x70,0x88,0x88,0xf8,0x88,0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x88, - 0xf8,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x90,0x90,0x50,0x50,0x50,0x20, - 0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x90,0x50,0x50,0x20,0x05,0x0a,0x0a,0x06,0x00, + 0x00,0xF8,0x88,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0xFE,0xF0,0x88,0x88,0x88, + 0xF0,0x80,0x80,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x88,0x80,0x88,0x70,0x05,0x05, + 0x05,0x06,0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0xFE,0x88, + 0x88,0x88,0x88,0x78,0x08,0x70,0x05,0x09,0x09,0x06,0x00,0xFE,0x20,0x20,0x70,0xA8, + 0xA8,0xA8,0x70,0x20,0x20,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x50,0x20,0x50,0x88, + 0x05,0x07,0x07,0x06,0x00,0xFE,0x90,0x90,0x90,0x90,0xF8,0x08,0x08,0x05,0x05,0x05, + 0x06,0x00,0x00,0x88,0x88,0x78,0x08,0x08,0x05,0x05,0x05,0x06,0x00,0x00,0xA8,0xA8, + 0xA8,0xA8,0xF8,0x05,0x07,0x07,0x06,0x00,0xFE,0xA8,0xA8,0xA8,0xA8,0xF8,0x08,0x08, + 0x05,0x05,0x05,0x06,0x00,0x00,0xC0,0x40,0x70,0x48,0x70,0x05,0x05,0x05,0x06,0x00, + 0x00,0x88,0x88,0xC8,0xA8,0xC8,0x04,0x05,0x05,0x06,0x01,0x00,0x80,0x80,0xE0,0x90, + 0xE0,0x04,0x05,0x05,0x06,0x01,0x00,0xE0,0x10,0x70,0x10,0xE0,0x05,0x05,0x05,0x06, + 0x00,0x00,0x90,0xA8,0xE8,0xA8,0x90,0x04,0x05,0x05,0x06,0x01,0x00,0x70,0x90,0x70, + 0x50,0x90,0x05,0x08,0x08,0x06,0x00,0x00,0x40,0x20,0x00,0x70,0x88,0xF0,0x80,0x70, + 0x05,0x07,0x07,0x06,0x00,0x00,0x50,0x00,0x70,0x88,0xF0,0x80,0x70,0x05,0x09,0x09, + 0x06,0x00,0xFE,0x40,0xE0,0x40,0x70,0x48,0x48,0x48,0x08,0x10,0x05,0x08,0x08,0x06, + 0x00,0x00,0x10,0x20,0x00,0xF8,0x80,0x80,0x80,0x80,0x04,0x05,0x05,0x06,0x01,0x00, + 0x70,0x80,0xE0,0x80,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0x78,0x80,0x70,0x08,0xF0, + 0x03,0x06,0x06,0x06,0x01,0x00,0x40,0x00,0xC0,0x40,0x40,0xE0,0x03,0x06,0x06,0x06, + 0x01,0x00,0xA0,0x00,0xC0,0x40,0x40,0xE0,0x04,0x08,0x08,0x06,0x01,0xFE,0x10,0x00, + 0x30,0x10,0x10,0x10,0x90,0x60,0x05,0x05,0x05,0x06,0x00,0x00,0x60,0xA0,0xB0,0xA8, + 0xB0,0x05,0x05,0x05,0x06,0x00,0x00,0xA0,0xA0,0xF0,0xA8,0xB0,0x05,0x07,0x07,0x06, + 0x00,0x00,0x40,0xE0,0x40,0x70,0x48,0x48,0x48,0x04,0x08,0x08,0x06,0x01,0x00,0x20, + 0x40,0x00,0x90,0xA0,0xC0,0xA0,0x90,0x05,0x08,0x08,0x06,0x00,0x00,0x40,0x20,0x00, + 0x88,0x98,0xA8,0xC8,0x88,0x05,0x0A,0x0A,0x06,0x00,0xFE,0x88,0x70,0x00,0x88,0x88, + 0x88,0x88,0x78,0x08,0x70,0x05,0x07,0x07,0x06,0x00,0xFE,0x88,0x88,0x88,0x88,0xF8, + 0x20,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x50,0x88,0x88,0xA8,0xA8,0xA8,0x50,0x05, + 0x05,0x05,0x06,0x00,0x00,0x50,0x88,0xA8,0xA8,0x50,0x05,0x07,0x07,0x06,0x00,0x00, + 0x40,0xF0,0x40,0x70,0x48,0x48,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x40,0x40,0xF0, + 0x40,0x70,0x48,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x98,0xA0,0xA0,0xF8,0xA0,0xA0, + 0x98,0x05,0x05,0x05,0x06,0x00,0x00,0x98,0xA0,0xF8,0xA0,0x98,0x05,0x07,0x07,0x06, + 0x00,0x00,0x20,0x50,0x50,0x88,0xF8,0xA8,0xA8,0x05,0x06,0x06,0x06,0x00,0x00,0x20, + 0x50,0x50,0x88,0xF8,0xA8,0x05,0x07,0x07,0x06,0x00,0x00,0x90,0x90,0xB8,0xF8,0xB8, + 0xB8,0xB8,0x05,0x05,0x05,0x06,0x00,0x00,0x90,0x90,0xF8,0xB8,0xB8,0x05,0x08,0x08, + 0x06,0x00,0x00,0xF8,0x88,0x50,0x50,0x70,0xA8,0xA8,0xA8,0x05,0x06,0x06,0x06,0x00, + 0x00,0xF8,0x88,0x50,0x70,0xA8,0xA8,0x06,0x08,0x08,0x06,0x00,0x00,0xFC,0xC4,0xA8, + 0x90,0xF8,0xB8,0xB8,0xA8,0x06,0x06,0x06,0x06,0x00,0x00,0xFC,0xA8,0x90,0xF8,0xB8, + 0xA8,0x05,0x0C,0x0C,0x06,0x00,0xFE,0x50,0x20,0x00,0x70,0x88,0x08,0x30,0x08,0x08, + 0x70,0x80,0x70,0x05,0x0A,0x0A,0x06,0x00,0xFE,0x50,0x20,0x00,0x70,0x88,0x30,0x08, + 0x70,0x80,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0xA8,0xA8,0xA8,0x70,0x20,0x20,0x20, + 0x05,0x05,0x05,0x06,0x00,0x00,0xA8,0xA8,0x70,0x20,0x20,0x05,0x07,0x07,0x06,0x00, + 0x00,0x70,0x88,0x88,0xF8,0x88,0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x88, + 0xF8,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x90,0x90,0x50,0x50,0x50,0x20, + 0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x90,0x50,0x50,0x20,0x05,0x0A,0x0A,0x06,0x00, 0x00,0x90,0x48,0x00,0x88,0x90,0x90,0x50,0x50,0x50,0x20,0x05,0x08,0x08,0x06,0x00, - 0x00,0x90,0x48,0x00,0x88,0x90,0x50,0x50,0x20,0x05,0x09,0x09,0x06,0x00,0xfe,0x40, - 0xa0,0xa0,0xb8,0xb8,0xb8,0x58,0x08,0x10,0x05,0x07,0x07,0x06,0x00,0xfe,0x58,0xb8, - 0xb8,0xb8,0x58,0x08,0x10,0x05,0x0a,0x0a,0x06,0x00,0xff,0x20,0x70,0xa8,0x88,0x88, - 0x88,0x88,0xa8,0x70,0x20,0x05,0x08,0x08,0x06,0x00,0xff,0x20,0x70,0xa8,0x88,0x88, - 0xa8,0x70,0x20,0x05,0x09,0x09,0x06,0x00,0x00,0x70,0x00,0x20,0x20,0x88,0x88,0x88, - 0xa8,0x50,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x00,0x20,0xa8,0x88,0xa8,0x50,0x05, - 0x0a,0x0a,0x06,0x00,0x00,0xf8,0xa8,0x00,0x50,0x88,0x88,0xa8,0xa8,0xa8,0x50,0x05, - 0x08,0x08,0x06,0x00,0x00,0xf8,0xa8,0x00,0x50,0x88,0xa8,0xa8,0x50}; -const u8g_fntpgm_uint8_t fontpage_97_129_191[870] U8G_FONT_SECTION("fontpage_97_129_191") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x81,0xbf,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x08,0x00,0x04,0x00,0x4e,0x00,0x55,0x00,0x64, - 0x80,0x48,0x40,0xa8,0x40,0x90,0x40,0x90,0x80,0x61,0x00,0x06,0x00,0x08,0x0b,0x0b, - 0x0c,0x01,0xff,0x20,0x10,0x70,0x1c,0x28,0xe2,0x39,0x21,0x21,0x12,0x0c,0x08,0x07, - 0x07,0x0c,0x02,0xff,0x28,0x2e,0xf5,0x21,0x16,0x10,0x10,0x0b,0x0b,0x16,0x0c,0x00, - 0xff,0x02,0x00,0x37,0x00,0x20,0x00,0x13,0xc0,0x9c,0x20,0x70,0x20,0x09,0xc0,0x08, - 0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x07,0x07,0x07,0x0c,0x03,0xff,0x10,0x9c,0xb2, - 0xd2,0x9c,0x10,0x20,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x82,0x00,0x47,0x80, - 0x4a,0x40,0x52,0x20,0x62,0x20,0x6a,0x40,0x47,0x80,0x42,0x00,0x04,0x00,0x08,0x00, - 0x07,0x07,0x07,0x0c,0x02,0xff,0x10,0x1c,0x10,0x10,0x78,0x96,0x60,0x09,0x0b,0x16, - 0x0c,0x01,0xff,0x10,0x00,0x08,0x00,0x09,0x80,0x0e,0x00,0x08,0x00,0x08,0x00,0x08, - 0x00,0x78,0x00,0x8e,0x00,0x89,0x80,0x70,0x00,0x07,0x0b,0x0b,0x0c,0x02,0xff,0x20, - 0x18,0x40,0x80,0x80,0xbc,0xc2,0x82,0x02,0x0c,0x70,0x07,0x0b,0x0b,0x0c,0x02,0xff, - 0x88,0x54,0x52,0x62,0x62,0x42,0x42,0x04,0x04,0x08,0x10,0x08,0x0a,0x0a,0x0c,0x01, - 0xff,0x4e,0x34,0x08,0x10,0x3e,0x61,0x81,0x19,0x26,0x1c,0x0b,0x0b,0x16,0x0c,0x00, - 0xff,0x20,0x00,0x10,0x00,0x13,0x00,0x34,0x80,0xd8,0x80,0x10,0x80,0x10,0x80,0x30, - 0x80,0x50,0x80,0xb0,0x60,0x10,0x00,0x08,0x0a,0x0a,0x0c,0x01,0xff,0x4e,0x34,0x08, - 0x10,0x3e,0x61,0x81,0x01,0x06,0x18,0x08,0x07,0x07,0x0c,0x02,0xff,0x40,0x30,0xee, - 0x31,0x61,0xa2,0x24,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x00,0x10,0x00,0x10,0x00, - 0x9b,0x80,0x7c,0x40,0x10,0x20,0x10,0x20,0x30,0x20,0x50,0x40,0xb1,0x80,0x10,0x00, - 0x0a,0x0a,0x14,0x0c,0x01,0xff,0x4e,0x00,0x34,0x00,0x04,0x00,0x1f,0x00,0x28,0x80, - 0x48,0x40,0x90,0x40,0x96,0x40,0x69,0x80,0x47,0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff, - 0x20,0x00,0x1f,0x00,0x04,0x00,0x1f,0x00,0x20,0x80,0x4c,0x80,0x13,0x00,0x0c,0x00, - 0x00,0x00,0x59,0x80,0x86,0x40,0x09,0x0b,0x16,0x0c,0x01,0xff,0x08,0x00,0x08,0x00, - 0x9e,0x00,0x70,0x00,0x21,0x80,0x72,0x00,0x8c,0x00,0x14,0x00,0x24,0x00,0x20,0x00, - 0x1f,0x00,0x0a,0x0a,0x14,0x0c,0x01,0xff,0x10,0x00,0x08,0x00,0x08,0x00,0x10,0x00, - 0x10,0x00,0x38,0x00,0x24,0x00,0x44,0x40,0x44,0x80,0x83,0x00,0x0a,0x0b,0x16,0x0c, - 0x00,0xff,0x10,0x00,0x0c,0x80,0x00,0x40,0x1d,0x00,0xe2,0x80,0x02,0x00,0x02,0x00, - 0x04,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0xff,0xff,0xff,0xff,0x04,0x03,0x03,0x0c, - 0x00,0x07,0x20,0x90,0x40,0xff,0x04,0x03,0x03,0x0c,0x00,0x06,0x20,0x90,0x40,0x03, - 0x03,0x03,0x0c,0x00,0x06,0x40,0xa0,0x40,0xff,0xff,0xff,0x05,0x03,0x03,0x06,0x00, - 0x01,0xf8,0x00,0xf8,0x04,0x04,0x04,0x06,0x00,0x00,0xf0,0x10,0x60,0x40,0x05,0x06, - 0x06,0x06,0x00,0x00,0xf8,0x08,0x28,0x30,0x20,0x40,0x03,0x04,0x04,0x06,0x01,0x00, - 0x20,0x40,0xc0,0x40,0x04,0x06,0x06,0x06,0x00,0x00,0x10,0x20,0x60,0xa0,0x20,0x20, - 0x04,0x04,0x04,0x06,0x00,0x00,0x20,0xf0,0x90,0x20,0x05,0x06,0x06,0x06,0x00,0x00, - 0x20,0xf8,0x88,0x08,0x10,0x20,0x03,0x04,0x04,0x06,0x01,0x00,0xe0,0x40,0x40,0xe0, - 0x05,0x05,0x05,0x06,0x00,0x00,0xf8,0x20,0x20,0x20,0xf8,0x04,0x04,0x04,0x06,0x00, - 0x00,0x20,0xf0,0x60,0xa0,0x05,0x06,0x06,0x06,0x00,0x00,0x10,0xf8,0x30,0x50,0x90, - 0x10,0x05,0x06,0x06,0x06,0x00,0x00,0x40,0xf8,0x48,0x48,0x48,0x90,0x05,0x08,0x08, - 0x06,0x00,0x00,0x28,0x00,0x40,0xf8,0x48,0x48,0x48,0x90,0x05,0x06,0x06,0x06,0x00, - 0x00,0x20,0xf8,0x20,0xf8,0x20,0x20,0x05,0x08,0x08,0x06,0x00,0x00,0x28,0x00,0x20, - 0xf8,0x20,0xf8,0x20,0x20,0x04,0x05,0x05,0x06,0x00,0x00,0x70,0x90,0x10,0x20,0xc0, - 0x05,0x07,0x07,0x06,0x00,0x00,0x28,0x00,0x70,0x90,0x10,0x20,0xc0,0x05,0x06,0x06, - 0x06,0x00,0x00,0x40,0x78,0x90,0x10,0x10,0x20,0x05,0x08,0x08,0x06,0x00,0x00,0x28, - 0x00,0x40,0x78,0x90,0x10,0x10,0x20,0x05,0x05,0x05,0x06,0x00,0x00,0xf8,0x08,0x08, - 0x08,0xf8,0x05,0x07,0x07,0x06,0x00,0x00,0x28,0x00,0xf8,0x08,0x08,0x08,0xf8,0x05, - 0x06,0x06,0x06,0x00,0x00,0x50,0xf8,0x50,0x10,0x20,0x40,0x05,0x08,0x08,0x06,0x00, - 0x00,0x28,0x00,0x50,0xf8,0x50,0x10,0x20,0x40,0x05,0x05,0x05,0x06,0x00,0x00,0xc0, - 0x08,0xc8,0x10,0xe0,0x05,0x07,0x07,0x06,0x00,0x00,0x28,0x00,0xc0,0x08,0xc8,0x10, - 0xe0,0x05,0x05,0x05,0x06,0x00,0x00,0xf8,0x10,0x20,0x50,0x88,0x05,0x07,0x07,0x06, - 0x00,0x00,0x28,0x00,0xf8,0x10,0x20,0x50,0x88,0x05,0x06,0x06,0x06,0x00,0x00,0x40, - 0xf8,0x48,0x50,0x40,0x38,0x05,0x08,0x08,0x06,0x00,0x00,0x28,0x00,0x40,0xf8,0x48, - 0x50,0x40,0x38,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x88,0x48,0x10,0x60,0x05,0x07, - 0x07,0x06,0x00,0x00,0x28,0x00,0x88,0x88,0x48,0x10,0x60,0x05,0x05,0x05,0x06,0x00, - 0x00,0x78,0x48,0xa8,0x10,0x60}; -const u8g_fntpgm_uint8_t fontpage_97_193_255[753] U8G_FONT_SECTION("fontpage_97_193_255") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc1,0xff,0x00,0x08,0x00,0x00, - 0x00,0x05,0x06,0x06,0x06,0x00,0x00,0x10,0xe0,0x20,0xf8,0x20,0x40,0x05,0x08,0x08, - 0x06,0x00,0x00,0x28,0x00,0x10,0xe0,0x20,0xf8,0x20,0x40,0x05,0x04,0x04,0x06,0x00, - 0x00,0xa8,0xa8,0x08,0x30,0x05,0x05,0x05,0x06,0x00,0x00,0xa8,0xa8,0x08,0x10,0x20, - 0x05,0x07,0x07,0x06,0x00,0x00,0x28,0x00,0xa8,0xa8,0x08,0x10,0x20,0x05,0x06,0x06, - 0x06,0x00,0x00,0x70,0x00,0xf8,0x20,0x20,0x40,0x05,0x08,0x08,0x06,0x00,0x00,0x28, - 0x00,0x70,0x00,0xf8,0x20,0x20,0x40,0x03,0x06,0x06,0x06,0x01,0x00,0x80,0x80,0xc0, - 0xa0,0x80,0x80,0x04,0x08,0x08,0x06,0x01,0x00,0x50,0x00,0x80,0x80,0xc0,0xa0,0x80, - 0x80,0x05,0x06,0x06,0x06,0x00,0x00,0x20,0xf8,0x20,0x20,0x40,0x80,0x05,0x05,0x05, - 0x06,0x00,0x00,0x70,0x00,0x00,0x00,0xf8,0x05,0x05,0x05,0x06,0x00,0x00,0xf8,0x08, - 0x50,0x20,0xd0,0x05,0x06,0x06,0x06,0x00,0x00,0x20,0xf8,0x10,0x20,0x70,0xa8,0x03, - 0x06,0x06,0x06,0x01,0x00,0x20,0x20,0x20,0x20,0x40,0x80,0x05,0x05,0x05,0x06,0x00, - 0x00,0x10,0x88,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x28,0x00,0x10,0x88, - 0x88,0x88,0x88,0x05,0x08,0x08,0x06,0x00,0x00,0x18,0x18,0x00,0x10,0x88,0x88,0x88, - 0x88,0x05,0x06,0x06,0x06,0x00,0x00,0x80,0x80,0xf8,0x80,0x80,0x78,0x05,0x07,0x07, - 0x06,0x00,0x00,0x28,0x80,0x80,0xf8,0x80,0x80,0x78,0x05,0x07,0x07,0x06,0x00,0x00, - 0x18,0x98,0x80,0xf8,0x80,0x80,0x78,0x05,0x05,0x05,0x06,0x00,0x00,0xf8,0x08,0x08, - 0x10,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x28,0x00,0xf8,0x08,0x08,0x10,0x60,0x05, - 0x08,0x08,0x06,0x00,0x00,0x18,0x18,0x00,0xf8,0x08,0x08,0x10,0x60,0x05,0x04,0x04, - 0x06,0x00,0x01,0x40,0xa0,0x10,0x08,0x05,0x06,0x06,0x06,0x00,0x01,0x28,0x00,0x40, - 0xa0,0x10,0x08,0x05,0x06,0x06,0x06,0x00,0x01,0x18,0x18,0x40,0xa0,0x10,0x08,0x05, - 0x06,0x06,0x06,0x00,0x00,0x20,0xf8,0x20,0xa8,0xa8,0x20,0x05,0x08,0x08,0x06,0x00, - 0x00,0x28,0x00,0x20,0xf8,0x20,0xa8,0xa8,0x20,0x05,0x08,0x08,0x06,0x00,0x00,0x18, - 0x18,0x20,0xf8,0x20,0xa8,0xa8,0x20,0x05,0x05,0x05,0x06,0x00,0x00,0xf8,0x08,0x50, - 0x20,0x10,0x04,0x05,0x05,0x06,0x01,0x00,0xe0,0x00,0xe0,0x00,0xf0,0x05,0x05,0x05, - 0x06,0x00,0x00,0x20,0x40,0x88,0xf8,0x08,0x05,0x05,0x05,0x06,0x00,0x00,0x08,0x28, - 0x10,0x28,0xc0,0x05,0x05,0x05,0x06,0x00,0x00,0xf8,0x40,0xf8,0x40,0x38,0x05,0x04, - 0x04,0x06,0x00,0x00,0x40,0xf8,0x50,0x40,0x05,0x06,0x06,0x06,0x00,0x00,0x40,0xf8, - 0x48,0x50,0x40,0x40,0x04,0x04,0x04,0x06,0x00,0x00,0x60,0x20,0x20,0xf0,0x05,0x05, - 0x05,0x06,0x00,0x00,0x70,0x10,0x10,0x10,0xf8,0x04,0x05,0x05,0x06,0x00,0x00,0xf0, - 0x10,0xf0,0x10,0xf0,0x05,0x05,0x05,0x06,0x00,0x00,0xf8,0x08,0xf8,0x08,0xf8,0x05, - 0x06,0x06,0x06,0x00,0x00,0x70,0x00,0xf8,0x08,0x10,0x20,0x04,0x06,0x06,0x06,0x00, - 0x00,0x90,0x90,0x90,0x90,0x10,0x20,0x05,0x05,0x05,0x06,0x00,0x00,0x20,0xa0,0xa8, - 0xa8,0xb0,0x04,0x05,0x05,0x06,0x00,0x00,0x80,0x80,0x90,0xa0,0xc0,0x05,0x05,0x05, - 0x06,0x00,0x00,0xf8,0x88,0x88,0x88,0xf8,0x04,0x04,0x04,0x06,0x00,0x00,0xf0,0x90, - 0x10,0x20,0x05,0x05,0x05,0x06,0x00,0x00,0xf8,0x88,0x08,0x10,0x20,0x05,0x06,0x06, - 0x06,0x00,0x00,0x10,0xf8,0x50,0x50,0xf8,0x10,0x05,0x05,0x05,0x06,0x00,0x00,0xf8, - 0x08,0x30,0x20,0xf8,0x05,0x05,0x05,0x06,0x00,0x00,0xf8,0x08,0xf8,0x08,0x30,0x05, - 0x05,0x05,0x06,0x00,0x00,0xc0,0x08,0x08,0x10,0xe0,0x05,0x08,0x08,0x06,0x00,0x00, - 0x28,0x00,0x20,0xf8,0x88,0x08,0x10,0x20,0x04,0x04,0x04,0x06,0x00,0x00,0x40,0xf0, - 0x50,0xa0,0x04,0x04,0x04,0x06,0x00,0x00,0x40,0xf0,0x20,0x40,0x05,0x07,0x07,0x06, - 0x00,0x00,0x28,0x00,0xf8,0x88,0x08,0x10,0x60,0x05,0x08,0x08,0x06,0x00,0x00,0x28, - 0x00,0x10,0xf8,0x50,0x50,0xf8,0x10,0x05,0x07,0x07,0x06,0x00,0x00,0x28,0x00,0xf8, - 0x08,0x30,0x20,0xf8,0x05,0x07,0x07,0x06,0x00,0x00,0x28,0x00,0xf8,0x08,0xf8,0x08, - 0x30,0x02,0x02,0x02,0x06,0x02,0x02,0xc0,0xc0,0x05,0x01,0x01,0x06,0x00,0x02,0xf8, - 0x05,0x04,0x04,0x06,0x00,0x01,0x80,0x60,0x10,0x08,0x05,0x05,0x05,0x06,0x00,0x01, - 0x28,0x80,0x60,0x10,0x08,0x05,0x06,0x06,0x06,0x00,0x00,0xf8,0x08,0x08,0x08,0x08, - 0x08}; + 0x00,0x90,0x48,0x00,0x88,0x90,0x50,0x50,0x20,0x05,0x09,0x09,0x06,0x00,0xFE,0x40, + 0xA0,0xA0,0xB8,0xB8,0xB8,0x58,0x08,0x10,0x05,0x07,0x07,0x06,0x00,0xFE,0x58,0xB8, + 0xB8,0xB8,0x58,0x08,0x10,0x05,0x0A,0x0A,0x06,0x00,0xFF,0x20,0x70,0xA8,0x88,0x88, + 0x88,0x88,0xA8,0x70,0x20,0x05,0x08,0x08,0x06,0x00,0xFF,0x20,0x70,0xA8,0x88,0x88, + 0xA8,0x70,0x20,0x05,0x09,0x09,0x06,0x00,0x00,0x70,0x00,0x20,0x20,0x88,0x88,0x88, + 0xA8,0x50,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x00,0x20,0xA8,0x88,0xA8,0x50,0x05, + 0x0A,0x0A,0x06,0x00,0x00,0xF8,0xA8,0x00,0x50,0x88,0x88,0xA8,0xA8,0xA8,0x50,0x05, + 0x08,0x08,0x06,0x00,0x00,0xF8,0xA8,0x00,0x50,0x88,0xA8,0xA8,0x50}; +const u8g_fntpgm_uint8_t fontpage_97_129_191[911] U8G_FONT_SECTION("fontpage_97_129_191") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x81,0xBF,0x00,0x0D,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x08,0x00,0x04,0x00,0x4E,0x00,0x55,0x00,0x64, + 0x80,0x48,0x40,0xA8,0x40,0x90,0x40,0x90,0x80,0x61,0x00,0x06,0x00,0x08,0x0B,0x0B, + 0x0C,0x01,0xFF,0x20,0x10,0x70,0x1C,0x28,0xE2,0x39,0x21,0x21,0x12,0x0C,0x08,0x07, + 0x07,0x0C,0x02,0xFF,0x28,0x2E,0xF5,0x21,0x16,0x10,0x10,0x0B,0x0B,0x16,0x0C,0x00, + 0xFF,0x02,0x00,0x37,0x00,0x20,0x00,0x13,0xC0,0x9C,0x20,0x70,0x20,0x09,0xC0,0x08, + 0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x07,0x07,0x07,0x0C,0x03,0xFF,0x10,0x9C,0xB2, + 0xD2,0x9C,0x10,0x20,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x82,0x00,0x47,0x80, + 0x4A,0x40,0x52,0x20,0x62,0x20,0x6A,0x40,0x47,0x80,0x42,0x00,0x04,0x00,0x08,0x00, + 0x07,0x07,0x07,0x0C,0x02,0xFF,0x10,0x1C,0x10,0x10,0x78,0x96,0x60,0x09,0x0B,0x16, + 0x0C,0x01,0xFF,0x10,0x00,0x08,0x00,0x09,0x80,0x0E,0x00,0x08,0x00,0x08,0x00,0x08, + 0x00,0x78,0x00,0x8E,0x00,0x89,0x80,0x70,0x00,0x07,0x0B,0x0B,0x0C,0x02,0xFF,0x20, + 0x18,0x40,0x80,0x80,0xBC,0xC2,0x82,0x02,0x0C,0x70,0x07,0x0B,0x0B,0x0C,0x02,0xFF, + 0x88,0x54,0x52,0x62,0x62,0x42,0x42,0x04,0x04,0x08,0x10,0x08,0x0A,0x0A,0x0C,0x01, + 0xFF,0x4E,0x34,0x08,0x10,0x3E,0x61,0x81,0x19,0x26,0x1C,0x0B,0x0B,0x16,0x0C,0x00, + 0xFF,0x20,0x00,0x10,0x00,0x13,0x00,0x34,0x80,0xD8,0x80,0x10,0x80,0x10,0x80,0x30, + 0x80,0x50,0x80,0xB0,0x60,0x10,0x00,0x08,0x0A,0x0A,0x0C,0x01,0xFF,0x4E,0x34,0x08, + 0x10,0x3E,0x61,0x81,0x01,0x06,0x18,0x08,0x07,0x07,0x0C,0x02,0xFF,0x40,0x30,0xEE, + 0x31,0x61,0xA2,0x24,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x00,0x10,0x00,0x10,0x00, + 0x9B,0x80,0x7C,0x40,0x10,0x20,0x10,0x20,0x30,0x20,0x50,0x40,0xB1,0x80,0x10,0x00, + 0x0A,0x0A,0x14,0x0C,0x01,0xFF,0x4E,0x00,0x34,0x00,0x04,0x00,0x1F,0x00,0x28,0x80, + 0x48,0x40,0x90,0x40,0x96,0x40,0x69,0x80,0x47,0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF, + 0x20,0x00,0x1F,0x00,0x04,0x00,0x1F,0x00,0x20,0x80,0x4C,0x80,0x13,0x00,0x0C,0x00, + 0x00,0x00,0x59,0x80,0x86,0x40,0x09,0x0B,0x16,0x0C,0x01,0xFF,0x08,0x00,0x08,0x00, + 0x9E,0x00,0x70,0x00,0x21,0x80,0x72,0x00,0x8C,0x00,0x14,0x00,0x24,0x00,0x20,0x00, + 0x1F,0x00,0x0A,0x0A,0x14,0x0C,0x01,0xFF,0x10,0x00,0x08,0x00,0x08,0x00,0x10,0x00, + 0x10,0x00,0x38,0x00,0x24,0x00,0x44,0x40,0x44,0x80,0x83,0x00,0x0A,0x0B,0x16,0x0C, + 0x00,0xFF,0x10,0x00,0x0C,0x80,0x00,0x40,0x1D,0x00,0xE2,0x80,0x02,0x00,0x02,0x00, + 0x04,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0xFF,0xFF,0xFF,0xFF,0x04,0x03,0x03,0x06, + 0x00,0x05,0x20,0x90,0x40,0xFF,0x04,0x03,0x03,0x06,0x00,0x05,0x20,0x90,0x40,0x03, + 0x03,0x03,0x06,0x00,0x05,0x40,0xA0,0x40,0xFF,0xFF,0xFF,0x05,0x03,0x03,0x06,0x00, + 0x03,0xF8,0x00,0xF8,0x04,0x05,0x05,0x06,0x00,0x00,0xF0,0x10,0x60,0x40,0x80,0x05, + 0x07,0x07,0x06,0x00,0x00,0xF8,0x08,0x28,0x30,0x20,0x20,0x40,0x04,0x05,0x05,0x06, + 0x00,0x00,0x10,0x20,0x60,0xA0,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x08,0x10,0x20, + 0x60,0xA0,0x20,0x20,0x04,0x05,0x05,0x06,0x00,0x00,0x20,0xF0,0x90,0x10,0x20,0x05, + 0x07,0x07,0x06,0x00,0x00,0x20,0xF8,0x88,0x88,0x08,0x10,0x60,0x03,0x04,0x04,0x06, + 0x00,0x00,0xE0,0x40,0x40,0xE0,0x05,0x06,0x06,0x06,0x00,0x00,0xF8,0x20,0x20,0x20, + 0x20,0xF8,0x04,0x05,0x05,0x06,0x00,0x00,0x20,0xF0,0x20,0x60,0xA0,0x05,0x07,0x07, + 0x06,0x00,0x00,0x10,0xF8,0x10,0x30,0x50,0x90,0x10,0x05,0x07,0x07,0x06,0x00,0x00, + 0x40,0xF8,0x48,0x48,0x48,0x48,0x98,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x08,0x40, + 0xF8,0x48,0x48,0x48,0x48,0x98,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0xF8,0x20,0x20, + 0xF8,0x10,0x10,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x08,0x20,0xF8,0x20,0x20,0xF8, + 0x10,0x10,0x05,0x07,0x07,0x06,0x00,0x00,0x40,0x78,0x48,0x88,0x08,0x10,0x60,0x05, + 0x09,0x09,0x06,0x00,0x00,0x28,0x08,0x40,0x78,0x48,0x88,0x08,0x10,0x60,0x05,0x07, + 0x07,0x06,0x00,0x00,0x80,0xF8,0x90,0x90,0x10,0x10,0x20,0x05,0x09,0x09,0x06,0x00, + 0x00,0x28,0x28,0x80,0xF8,0x90,0x90,0x10,0x10,0x20,0x05,0x06,0x06,0x06,0x00,0x00, + 0xF8,0x08,0x08,0x08,0x08,0xF8,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x28,0x00,0xF8, + 0x08,0x08,0x08,0x08,0xF8,0x05,0x07,0x07,0x06,0x00,0x00,0x50,0xF8,0x50,0x50,0x50, + 0x10,0x20,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x08,0x50,0xF8,0x50,0x50,0x50,0x10, + 0x20,0x05,0x06,0x06,0x06,0x00,0x00,0xC0,0x08,0xC8,0x08,0x10,0xE0,0x07,0x0D,0x0D, + 0x06,0x00,0x00,0x02,0x00,0x00,0x00,0x28,0x28,0x00,0xC0,0x08,0xC8,0x08,0x10,0xE0, + 0x05,0x06,0x06,0x06,0x00,0x00,0x70,0x10,0x10,0x20,0x50,0x88,0x05,0x09,0x09,0x06, + 0x00,0x00,0x28,0x28,0x00,0x70,0x10,0x10,0x20,0x50,0x88,0x05,0x07,0x07,0x06,0x00, + 0x00,0x40,0x40,0xF8,0x48,0x50,0x40,0x38,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x08, + 0x40,0x40,0xF8,0x48,0x50,0x40,0x38,0x05,0x06,0x06,0x06,0x00,0x00,0x88,0x48,0x48, + 0x10,0x10,0x20,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x28,0x00,0x88,0x48,0x48,0x10, + 0x10,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x40,0x78,0x48,0xA8,0x18,0x10,0x60}; +const u8g_fntpgm_uint8_t fontpage_97_193_255[822] U8G_FONT_SECTION("fontpage_97_193_255") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC1,0xFF,0x00,0x09,0x00,0x00, + 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x10,0x60,0x20,0xF8,0x20,0x20,0x40,0x05,0x09, + 0x09,0x06,0x00,0x00,0x28,0x08,0x10,0x60,0x20,0xF8,0x20,0x20,0x40,0x05,0x04,0x04, + 0x06,0x00,0x00,0xA8,0xA8,0x08,0x30,0x05,0x06,0x06,0x06,0x00,0x00,0xA8,0xA8,0xA8, + 0x08,0x10,0x60,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x28,0x00,0xA8,0xA8,0xA8,0x08, + 0x10,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x00,0xF8,0x20,0x20,0x20,0x40,0x05, + 0x09,0x09,0x06,0x00,0x00,0x28,0x08,0x70,0x00,0xF8,0x20,0x20,0x20,0x40,0x04,0x07, + 0x07,0x06,0x01,0x00,0x80,0x80,0xC0,0xA0,0x90,0x80,0x80,0x04,0x09,0x09,0x06,0x01, + 0x00,0x50,0x10,0x80,0x80,0xC0,0xA0,0x90,0x80,0x80,0x05,0x07,0x07,0x06,0x00,0x00, + 0x20,0x20,0xF8,0x20,0x20,0x40,0x80,0x05,0x06,0x06,0x06,0x00,0x00,0x70,0x00,0x00, + 0x00,0x00,0xF8,0x05,0x06,0x06,0x06,0x00,0x00,0x78,0x08,0x28,0x10,0x28,0xC0,0x05, + 0x07,0x07,0x06,0x00,0x00,0x20,0x70,0x10,0x20,0x70,0xA8,0x20,0x03,0x06,0x06,0x06, + 0x01,0x00,0x20,0x20,0x20,0x40,0x40,0x80,0x05,0x06,0x06,0x06,0x00,0x00,0x10,0x50, + 0x50,0x48,0x88,0x88,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x28,0x00,0x10,0x50,0x50, + 0x48,0x88,0x88,0x05,0x09,0x09,0x06,0x00,0x00,0x18,0x18,0x00,0x10,0x50,0x50,0x48, + 0x88,0x88,0x04,0x06,0x06,0x06,0x00,0x00,0x80,0x90,0xE0,0x80,0x80,0x70,0x05,0x09, + 0x09,0x06,0x00,0x00,0x28,0x28,0x00,0x80,0x90,0xE0,0x80,0x80,0x70,0x05,0x09,0x09, + 0x06,0x00,0x00,0x18,0x18,0x00,0x80,0x90,0xE0,0x80,0x80,0x70,0x05,0x06,0x06,0x06, + 0x00,0x00,0xF8,0x08,0x08,0x08,0x10,0x60,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x28, + 0x00,0xF8,0x08,0x08,0x08,0x10,0x60,0x05,0x09,0x09,0x06,0x00,0x00,0x18,0x18,0x00, + 0xF8,0x08,0x08,0x08,0x10,0x60,0x05,0x05,0x05,0x06,0x00,0x01,0x60,0xA0,0x10,0x10, + 0x08,0x05,0x08,0x08,0x06,0x00,0x01,0x28,0x28,0x00,0x60,0xA0,0x10,0x10,0x08,0x05, + 0x08,0x08,0x06,0x00,0x01,0x18,0x18,0x00,0x60,0xA0,0x10,0x10,0x08,0x05,0x07,0x07, + 0x06,0x00,0x00,0x20,0xF8,0x20,0xA8,0xA8,0xA8,0x20,0x05,0x09,0x09,0x06,0x00,0x00, + 0x28,0x08,0x20,0xF8,0x20,0xA8,0xA8,0xA8,0x20,0x05,0x09,0x09,0x06,0x00,0x00,0x18, + 0x18,0x20,0xF8,0x20,0xA8,0xA8,0xA8,0x20,0x05,0x06,0x06,0x06,0x00,0x00,0xF8,0x08, + 0x08,0x50,0x20,0x10,0x04,0x06,0x06,0x06,0x01,0x00,0xE0,0x00,0xE0,0x00,0xC0,0x30, + 0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x20,0x20,0x40,0x48,0xF8,0x08,0x05,0x06,0x06, + 0x06,0x00,0x00,0x08,0x48,0x30,0x10,0x28,0xC0,0x05,0x06,0x06,0x06,0x00,0x00,0xF0, + 0x40,0xF8,0x40,0x40,0x38,0x05,0x05,0x05,0x06,0x00,0x00,0x40,0xF8,0x48,0x50,0x40, + 0x05,0x07,0x07,0x06,0x00,0x00,0x40,0x40,0xF8,0x48,0x50,0x40,0x40,0x04,0x05,0x05, + 0x06,0x00,0x00,0x60,0x20,0x20,0x20,0xF0,0x05,0x06,0x06,0x06,0x00,0x00,0x70,0x10, + 0x10,0x10,0x10,0xF8,0x04,0x05,0x05,0x06,0x00,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x05, + 0x06,0x06,0x06,0x00,0x00,0xF8,0x08,0xF8,0x08,0x08,0xF8,0x05,0x07,0x07,0x06,0x00, + 0x00,0x70,0x00,0xF8,0x08,0x08,0x10,0x60,0x04,0x07,0x07,0x06,0x00,0x00,0x10,0x90, + 0x90,0x90,0x90,0x10,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x20,0xA0,0xA0,0xA8, + 0xA8,0xB0,0x05,0x06,0x06,0x06,0x00,0x00,0x80,0x80,0x80,0x88,0xB0,0xC0,0x05,0x06, + 0x06,0x06,0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0xF8,0x04,0x05,0x05,0x06,0x00,0x00, + 0xF0,0x90,0x10,0x10,0x60,0x05,0x06,0x06,0x06,0x00,0x00,0xF8,0x88,0x88,0x08,0x10, + 0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x10,0xF8,0x50,0x50,0xF8,0x10,0x10,0x05,0x06, + 0x06,0x06,0x00,0x00,0x70,0x10,0x20,0x20,0x20,0xF8,0x05,0x06,0x06,0x06,0x00,0x00, + 0xF8,0x08,0xF8,0x08,0x10,0x60,0x05,0x06,0x06,0x06,0x00,0x00,0xC0,0x08,0x08,0x08, + 0x10,0xE0,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x08,0x20,0xF8,0x88,0x88,0x08,0x10, + 0x60,0x04,0x05,0x05,0x06,0x00,0x00,0x40,0xF0,0x50,0x50,0xB0,0x04,0x05,0x05,0x06, + 0x00,0x00,0x80,0xF0,0xA0,0x20,0x40,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x28,0x00, + 0xF8,0x88,0x88,0x08,0x10,0x60,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x08,0x10,0xF8, + 0x50,0x50,0xF8,0x10,0x10,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x28,0x00,0x70,0x10, + 0x20,0x20,0x20,0xF8,0x05,0x09,0x09,0x06,0x00,0x00,0x28,0x28,0x00,0xF8,0x08,0xF8, + 0x08,0x10,0x60,0x02,0x02,0x02,0x06,0x02,0x03,0xC0,0xC0,0x05,0x02,0x02,0x06,0x00, + 0x03,0x80,0x78,0x05,0x04,0x04,0x06,0x00,0x02,0x80,0x60,0x10,0x08,0x05,0x07,0x07, + 0x06,0x00,0x02,0x28,0x28,0x00,0x80,0x60,0x10,0x08,0x05,0x06,0x06,0x06,0x00,0x00, + 0xF8,0x08,0x08,0x08,0x08,0x08}; #define FONTDATA_ITEM(page, begin, end, data) { page, begin, end, COUNT(data), data } static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { diff --git a/Marlin/src/lcd/dogm/fontdata/langdata_tr.h b/Marlin/src/lcd/dogm/fontdata/langdata_tr.h index b85a19f54785..a4068e10d092 100644 --- a/Marlin/src/lcd/dogm/fontdata/langdata_tr.h +++ b/Marlin/src/lcd/dogm/fontdata/langdata_tr.h @@ -5,22 +5,23 @@ */ #include -const u8g_fntpgm_uint8_t fontpage_2_159_159[33] U8G_FONT_SECTION("fontpage_2_159_159") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9f,0x9f,0x00,0x08,0xfe,0x00, - 0x00,0x05,0x0a,0x0a,0x06,0x00,0xfe,0x88,0x70,0x00,0x70,0x88,0x88,0x88,0x78,0x08, +const u8g_fntpgm_uint8_t fontpage_2_158_159[49] U8G_FONT_SECTION("fontpage_2_158_159") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9E,0x9F,0x00,0x0A,0xFE,0x00, + 0x00,0x05,0x0A,0x0A,0x06,0x00,0x00,0x88,0x70,0x00,0x70,0x88,0x80,0x80,0x98,0x88, + 0x70,0x05,0x0A,0x0A,0x06,0x00,0xFE,0x88,0x70,0x00,0x70,0x88,0x88,0x88,0x78,0x08, 0x70}; const u8g_fntpgm_uint8_t fontpage_2_176_177[43] U8G_FONT_SECTION("fontpage_2_176_177") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb0,0xb1,0x00,0x09,0x00,0x00, - 0x00,0x03,0x09,0x09,0x06,0x01,0x00,0x40,0x00,0xe0,0x40,0x40,0x40,0x40,0x40,0xe0, - 0x03,0x05,0x05,0x06,0x01,0x00,0xc0,0x40,0x40,0x40,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB0,0xB1,0x00,0x09,0x00,0x00, + 0x00,0x03,0x09,0x09,0x06,0x01,0x00,0x40,0x00,0xE0,0x40,0x40,0x40,0x40,0x40,0xE0, + 0x03,0x05,0x05,0x06,0x01,0x00,0xC0,0x40,0x40,0x40,0xE0}; const u8g_fntpgm_uint8_t fontpage_2_222_223[45] U8G_FONT_SECTION("fontpage_2_222_223") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xde,0xdf,0x00,0x07,0xfe,0x00, - 0x00,0x05,0x09,0x09,0x06,0x00,0xfe,0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x10,0x60, - 0x05,0x07,0x07,0x06,0x00,0xfe,0x78,0x80,0x70,0x08,0xf0,0x10,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDE,0xDF,0x00,0x07,0xFE,0x00, + 0x00,0x05,0x09,0x09,0x06,0x00,0xFE,0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x10,0x60, + 0x05,0x07,0x07,0x06,0x00,0xFE,0x78,0x80,0x70,0x08,0xF0,0x10,0x60}; #define FONTDATA_ITEM(page, begin, end, data) { page, begin, end, COUNT(data), data } static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { - FONTDATA_ITEM(2, 159, 159, fontpage_2_159_159), // 'ğ' -- 'ğ' + FONTDATA_ITEM(2, 158, 159, fontpage_2_158_159), // 'Ğ' -- 'ğ' FONTDATA_ITEM(2, 176, 177, fontpage_2_176_177), // 'İ' -- 'ı' FONTDATA_ITEM(2, 222, 223, fontpage_2_222_223), // 'Ş' -- 'ş' }; diff --git a/Marlin/src/lcd/dogm/fontdata/langdata_uk.h b/Marlin/src/lcd/dogm/fontdata/langdata_uk.h index d6e8337fd8f9..47ec93992fc2 100644 --- a/Marlin/src/lcd/dogm/fontdata/langdata_uk.h +++ b/Marlin/src/lcd/dogm/fontdata/langdata_uk.h @@ -6,88 +6,80 @@ #include const u8g_fntpgm_uint8_t fontpage_8_134_134[30] U8G_FONT_SECTION("fontpage_8_134_134") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x86,0x86,0x00,0x07,0x00,0x00, - 0x00,0x03,0x07,0x07,0x06,0x01,0x00,0xe0,0x40,0x40,0x40,0x40,0x40,0xe0}; -const u8g_fntpgm_uint8_t fontpage_8_144_146[56] U8G_FONT_SECTION("fontpage_8_144_146") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x90,0x92,0x00,0x07,0x00,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0xf8,0x88,0x88,0x88,0x05,0x07, - 0x07,0x06,0x00,0x00,0xf0,0x80,0x80,0xf0,0x88,0x88,0xf0,0x05,0x07,0x07,0x06,0x00, - 0x00,0xf0,0x88,0x88,0xf0,0x88,0x88,0xf0}; -const u8g_fntpgm_uint8_t fontpage_8_148_149[44] U8G_FONT_SECTION("fontpage_8_148_149") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x94,0x95,0x00,0x07,0xff,0x00, - 0x00,0x05,0x08,0x08,0x06,0x00,0xff,0x30,0x50,0x50,0x50,0x50,0x50,0xf8,0x88,0x05, - 0x07,0x07,0x06,0x00,0x00,0xf8,0x80,0x80,0xf0,0x80,0x80,0xf8}; -const u8g_fntpgm_uint8_t fontpage_8_151_154[72] U8G_FONT_SECTION("fontpage_8_151_154") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x97,0x9a,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x08,0x70,0x08,0x88,0x70,0x05,0x07, - 0x07,0x06,0x00,0x00,0x88,0x88,0x98,0xa8,0xc8,0x88,0x88,0x05,0x0a,0x0a,0x06,0x00, - 0x00,0x88,0x70,0x00,0x88,0x88,0x98,0xa8,0xc8,0x88,0x88,0x05,0x07,0x07,0x06,0x00, - 0x00,0x88,0x90,0xa0,0xc0,0xa0,0x90,0x88}; -const u8g_fntpgm_uint8_t fontpage_8_156_164[134] U8G_FONT_SECTION("fontpage_8_156_164") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9c,0xa4,0x00,0x07,0x00,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0xd8,0xa8,0x88,0x88,0x88,0x88,0x05,0x07, - 0x07,0x06,0x00,0x00,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00, - 0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0xf8,0x88, - 0x88,0x88,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0xf0,0x88,0x88,0xf0,0x80, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x86,0x86,0x00,0x07,0x00,0x00, + 0x00,0x03,0x07,0x07,0x06,0x01,0x00,0xE0,0x40,0x40,0x40,0x40,0x40,0xE0}; +const u8g_fntpgm_uint8_t fontpage_8_144_169[363] U8G_FONT_SECTION("fontpage_8_144_169") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x90,0xA9,0x00,0x0A,0xFE,0x00, + 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0xF8,0x88,0x88,0x88,0x05,0x07, + 0x07,0x06,0x00,0x00,0xF0,0x80,0x80,0xF0,0x88,0x88,0xF0,0x05,0x07,0x07,0x06,0x00, + 0x00,0xF0,0x88,0x88,0xF0,0x88,0x88,0xF0,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x80, + 0x80,0x80,0x80,0x80,0x80,0x05,0x08,0x08,0x06,0x00,0xFF,0x30,0x50,0x50,0x50,0x50, + 0x50,0xF8,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8, + 0x05,0x07,0x07,0x06,0x00,0x00,0xA8,0xA8,0x70,0x20,0x70,0xA8,0xA8,0x05,0x07,0x07, + 0x06,0x00,0x00,0x70,0x88,0x08,0x70,0x08,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00, + 0x88,0x88,0x98,0xA8,0xC8,0x88,0x88,0x05,0x0A,0x0A,0x06,0x00,0x00,0x88,0x70,0x00, + 0x88,0x88,0x98,0xA8,0xC8,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x90,0xA0, + 0xC0,0xA0,0x90,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x38,0x48,0x48,0x48,0x48,0x48, + 0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0xD8,0xA8,0x88,0x88,0x88,0x88,0x05,0x07, + 0x07,0x06,0x00,0x00,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00, + 0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x88, + 0x88,0x88,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0xF0,0x88,0x88,0xF0,0x80, 0x80,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x05, - 0x07,0x07,0x06,0x00,0x00,0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06, + 0x07,0x07,0x06,0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06, 0x00,0x00,0x88,0x88,0x88,0x88,0x78,0x08,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x20, - 0x70,0xa8,0xa8,0xa8,0x70,0x20}; -const u8g_fntpgm_uint8_t fontpage_8_166_166[32] U8G_FONT_SECTION("fontpage_8_166_166") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa6,0xa6,0x00,0x07,0xfe,0x00, - 0x00,0x05,0x09,0x09,0x06,0x00,0xfe,0x90,0x90,0x90,0x90,0x90,0x90,0xf8,0x08,0x08 - }; -const u8g_fntpgm_uint8_t fontpage_8_168_168[30] U8G_FONT_SECTION("fontpage_8_168_168") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa8,0xa8,0x00,0x07,0x00,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xf8}; -const u8g_fntpgm_uint8_t fontpage_8_176_201[321] U8G_FONT_SECTION("fontpage_8_176_201") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb0,0xc9,0x00,0x08,0xfe,0x00, - 0x00,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x08,0x78,0x88,0x78,0x05,0x07,0x07,0x06, - 0x00,0x00,0x70,0x80,0xf0,0x88,0x88,0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xf0, - 0x88,0xf0,0x88,0xf0,0x05,0x05,0x05,0x06,0x00,0x00,0xf8,0x80,0x80,0x80,0x80,0x05, - 0x06,0x06,0x06,0x00,0xff,0x30,0x50,0x50,0x50,0xf8,0x88,0x05,0x05,0x05,0x06,0x00, - 0x00,0x70,0x88,0xf0,0x80,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xa8,0x70,0x20,0x70, - 0xa8,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x88,0x30,0x88,0x70,0x05,0x05,0x05,0x06, - 0x00,0x00,0x88,0x98,0xa8,0xc8,0x88,0x05,0x08,0x08,0x06,0x00,0x00,0x88,0x70,0x00, - 0x88,0x98,0xa8,0xc8,0x88,0x04,0x05,0x05,0x06,0x01,0x00,0x90,0xa0,0xc0,0xa0,0x90, - 0x05,0x05,0x05,0x06,0x00,0x00,0x38,0x48,0x48,0x48,0x88,0x05,0x05,0x05,0x06,0x00, - 0x00,0x88,0xd8,0xa8,0x88,0x88,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x88,0xf8,0x88, - 0x88,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x05,0x05,0x05,0x06, - 0x00,0x00,0xf8,0x88,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0xfe,0xf0,0x88,0x88, - 0x88,0xf0,0x80,0x80,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x88,0x80,0x88,0x70,0x05, - 0x05,0x05,0x06,0x00,0x00,0xf8,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0xfe, - 0x88,0x88,0x88,0x88,0x78,0x08,0x70,0x05,0x09,0x09,0x06,0x00,0xfe,0x20,0x20,0x70, - 0xa8,0xa8,0xa8,0x70,0x20,0x20,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x50,0x20,0x50, - 0x88,0x05,0x07,0x07,0x06,0x00,0xfe,0x90,0x90,0x90,0x90,0xf8,0x08,0x08,0x05,0x05, - 0x05,0x06,0x00,0x00,0x88,0x88,0x78,0x08,0x08,0x05,0x05,0x05,0x06,0x00,0x00,0xa8, - 0xa8,0xa8,0xa8,0xf8,0x05,0x07,0x07,0x06,0x00,0xfe,0xa8,0xa8,0xa8,0xa8,0xf8,0x08, - 0x08}; + 0x70,0xA8,0xA8,0xA8,0x70,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x50,0x20, + 0x50,0x88,0x88,0x05,0x09,0x09,0x06,0x00,0xFE,0x90,0x90,0x90,0x90,0x90,0x90,0xF8, + 0x08,0x08,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0x78,0x08,0x08,0x08,0x05, + 0x07,0x07,0x06,0x00,0x00,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xF8,0x05,0x09,0x09,0x06, + 0x00,0xFE,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xF8,0x08,0x08}; +const u8g_fntpgm_uint8_t fontpage_8_172_172[30] U8G_FONT_SECTION("fontpage_8_172_172") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAC,0xAC,0x00,0x07,0x00,0x00, + 0x00,0x04,0x07,0x07,0x06,0x01,0x00,0x80,0x80,0x80,0xE0,0x90,0x90,0xE0}; +const u8g_fntpgm_uint8_t fontpage_8_175_201[334] U8G_FONT_SECTION("fontpage_8_175_201") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAF,0xC9,0x00,0x08,0xFE,0x00, + 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x78,0x88,0x88,0x78,0x28,0x48,0x88,0x05,0x05, + 0x05,0x06,0x00,0x00,0x70,0x08,0x78,0x88,0x78,0x05,0x07,0x07,0x06,0x00,0x00,0x70, + 0x80,0xF0,0x88,0x88,0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xF0,0x88,0xF0,0x88, + 0xF0,0x05,0x05,0x05,0x06,0x00,0x00,0xF8,0x80,0x80,0x80,0x80,0x05,0x06,0x06,0x06, + 0x00,0xFF,0x30,0x50,0x50,0x50,0xF8,0x88,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x88, + 0xF0,0x80,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xA8,0x70,0x20,0x70,0xA8,0x05,0x05, + 0x05,0x06,0x00,0x00,0x70,0x88,0x30,0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0x88, + 0x98,0xA8,0xC8,0x88,0x05,0x08,0x08,0x06,0x00,0x00,0x88,0x70,0x00,0x88,0x98,0xA8, + 0xC8,0x88,0x04,0x05,0x05,0x06,0x01,0x00,0x90,0xA0,0xC0,0xA0,0x90,0x05,0x05,0x05, + 0x06,0x00,0x00,0x38,0x48,0x48,0x48,0x88,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0xD8, + 0xA8,0x88,0x88,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x88,0xF8,0x88,0x88,0x05,0x05, + 0x05,0x06,0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x05,0x05,0x05,0x06,0x00,0x00,0xF8, + 0x88,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0xFE,0xF0,0x88,0x88,0x88,0xF0,0x80, + 0x80,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x88,0x80,0x88,0x70,0x05,0x05,0x05,0x06, + 0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0xFE,0x88,0x88,0x88, + 0x88,0x78,0x08,0x70,0x05,0x09,0x09,0x06,0x00,0xFE,0x20,0x20,0x70,0xA8,0xA8,0xA8, + 0x70,0x20,0x20,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x05,0x07, + 0x07,0x06,0x00,0xFE,0x90,0x90,0x90,0x90,0xF8,0x08,0x08,0x05,0x05,0x05,0x06,0x00, + 0x00,0x88,0x88,0x78,0x08,0x08,0x05,0x05,0x05,0x06,0x00,0x00,0xA8,0xA8,0xA8,0xA8, + 0xF8,0x05,0x07,0x07,0x06,0x00,0xFE,0xA8,0xA8,0xA8,0xA8,0xF8,0x08,0x08}; const u8g_fntpgm_uint8_t fontpage_8_204_204[28] U8G_FONT_SECTION("fontpage_8_204_204") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcc,0xcc,0x00,0x05,0x00,0x00, - 0x00,0x04,0x05,0x05,0x06,0x01,0x00,0x80,0x80,0xe0,0x90,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0x00,0x05,0x00,0x00, + 0x00,0x04,0x05,0x05,0x06,0x01,0x00,0x80,0x80,0xE0,0x90,0xE0}; const u8g_fntpgm_uint8_t fontpage_8_206_207[39] U8G_FONT_SECTION("fontpage_8_206_207") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xce,0xcf,0x00,0x05,0x00,0x00, - 0x00,0x05,0x05,0x05,0x06,0x00,0x00,0x90,0xa8,0xe8,0xa8,0x90,0x04,0x05,0x05,0x06, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCE,0xCF,0x00,0x05,0x00,0x00, + 0x00,0x05,0x05,0x05,0x06,0x00,0x00,0x90,0xA8,0xE8,0xA8,0x90,0x04,0x05,0x05,0x06, 0x01,0x00,0x70,0x90,0x70,0x50,0x90}; const u8g_fntpgm_uint8_t fontpage_8_212_212[28] U8G_FONT_SECTION("fontpage_8_212_212") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd4,0xd4,0x00,0x05,0x00,0x00, - 0x00,0x04,0x05,0x05,0x06,0x01,0x00,0x70,0x80,0xe0,0x80,0x70}; -const u8g_fntpgm_uint8_t fontpage_8_214_214[29] U8G_FONT_SECTION("fontpage_8_214_214") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd6,0xd6,0x00,0x06,0x00,0x00, - 0x00,0x03,0x06,0x06,0x06,0x01,0x00,0x40,0x00,0xc0,0x40,0x40,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD4,0xD4,0x00,0x05,0x00,0x00, + 0x00,0x04,0x05,0x05,0x06,0x01,0x00,0x70,0x80,0xE0,0x80,0x70}; +const u8g_fntpgm_uint8_t fontpage_8_214_215[41] U8G_FONT_SECTION("fontpage_8_214_215") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD6,0xD7,0x00,0x06,0x00,0x00, + 0x00,0x03,0x06,0x06,0x06,0x01,0x00,0x40,0x00,0xC0,0x40,0x40,0xE0,0x03,0x06,0x06, + 0x06,0x01,0x00,0xA0,0x00,0xC0,0x40,0x40,0xE0}; #define FONTDATA_ITEM(page, begin, end, data) { page, begin, end, COUNT(data), data } static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(8, 134, 134, fontpage_8_134_134), // 'І' -- 'І' - FONTDATA_ITEM(8, 144, 146, fontpage_8_144_146), // 'А' -- 'В' - FONTDATA_ITEM(8, 148, 149, fontpage_8_148_149), // 'Д' -- 'Е' - FONTDATA_ITEM(8, 151, 154, fontpage_8_151_154), // 'З' -- 'К' - FONTDATA_ITEM(8, 156, 164, fontpage_8_156_164), // 'М' -- 'Ф' - FONTDATA_ITEM(8, 166, 166, fontpage_8_166_166), // 'Ц' -- 'Ц' - FONTDATA_ITEM(8, 168, 168, fontpage_8_168_168), // 'Ш' -- 'Ш' - FONTDATA_ITEM(8, 176, 201, fontpage_8_176_201), // 'а' -- 'щ' + FONTDATA_ITEM(8, 144, 169, fontpage_8_144_169), // 'А' -- 'Щ' + FONTDATA_ITEM(8, 172, 172, fontpage_8_172_172), // 'Ь' -- 'Ь' + FONTDATA_ITEM(8, 175, 201, fontpage_8_175_201), // 'Я' -- 'щ' FONTDATA_ITEM(8, 204, 204, fontpage_8_204_204), // 'ь' -- 'ь' FONTDATA_ITEM(8, 206, 207, fontpage_8_206_207), // 'ю' -- 'я' FONTDATA_ITEM(8, 212, 212, fontpage_8_212_212), // 'є' -- 'є' - FONTDATA_ITEM(8, 214, 214, fontpage_8_214_214), // 'і' -- 'і' + FONTDATA_ITEM(8, 214, 215, fontpage_8_214_215), // 'і' -- 'ї' }; diff --git a/Marlin/src/lcd/dogm/fontdata/langdata_vi.h b/Marlin/src/lcd/dogm/fontdata/langdata_vi.h index 7c309907cdcd..a8a0c5c121e6 100644 --- a/Marlin/src/lcd/dogm/fontdata/langdata_vi.h +++ b/Marlin/src/lcd/dogm/fontdata/langdata_vi.h @@ -6,179 +6,175 @@ #include const u8g_fntpgm_uint8_t fontpage_2_131_131[31] U8G_FONT_SECTION("fontpage_2_131_131") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x83,0x83,0x00,0x08,0x00,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x83,0x83,0x00,0x08,0x00,0x00, 0x00,0x05,0x08,0x08,0x06,0x00,0x00,0x88,0x70,0x00,0x70,0x08,0x78,0x88,0x78}; const u8g_fntpgm_uint8_t fontpage_2_144_145[44] U8G_FONT_SECTION("fontpage_2_144_145") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x90,0x91,0x00,0x08,0x00,0x00, - 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0xf0,0x48,0x48,0xe8,0x48,0x48,0xf0,0x06,0x08, - 0x08,0x06,0x00,0x00,0x08,0x1c,0x08,0x78,0x88,0x88,0x88,0x78}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x90,0x91,0x00,0x08,0x00,0x00, + 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0xF0,0x48,0x48,0xE8,0x48,0x48,0xF0,0x06,0x08, + 0x08,0x06,0x00,0x00,0x08,0x1C,0x08,0x78,0x88,0x88,0x88,0x78}; const u8g_fntpgm_uint8_t fontpage_2_169_169[31] U8G_FONT_SECTION("fontpage_2_169_169") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa9,0xa9,0x00,0x08,0x00,0x00, - 0x00,0x04,0x08,0x08,0x06,0x00,0x00,0x50,0xa0,0x00,0x60,0x20,0x20,0x20,0x70}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA9,0xA9,0x00,0x08,0x00,0x00, + 0x00,0x04,0x08,0x08,0x06,0x00,0x00,0x50,0xA0,0x00,0x60,0x20,0x20,0x20,0x70}; const u8g_fntpgm_uint8_t fontpage_3_161_161[30] U8G_FONT_SECTION("fontpage_3_161_161") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa1,0xa1,0x00,0x07,0x00,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA1,0xA1,0x00,0x07,0x00,0x00, 0x00,0x05,0x07,0x07,0x06,0x00,0x00,0x08,0x08,0x70,0x88,0x88,0x88,0x70}; const u8g_fntpgm_uint8_t fontpage_3_175_176[43] U8G_FONT_SECTION("fontpage_3_175_176") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xaf,0xb0,0x00,0x08,0x00,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAF,0xB0,0x00,0x08,0x00,0x00, 0x00,0x05,0x08,0x08,0x06,0x00,0x00,0x08,0x98,0x90,0x90,0x90,0x90,0x90,0x60,0x05, - 0x06,0x06,0x06,0x00,0x00,0x08,0x98,0x90,0x90,0xb0,0x50}; + 0x06,0x06,0x06,0x00,0x00,0x08,0x98,0x90,0x90,0xB0,0x50}; const u8g_fntpgm_uint8_t fontpage_6_131_131[25] U8G_FONT_SECTION("fontpage_6_131_131") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x83,0x83,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x02,0x02,0x06,0x00,0x08,0x68,0xb0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x83,0x83,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x02,0x02,0x06,0x00,0x08,0x68,0xB0}; const u8g_fntpgm_uint8_t fontpage_6_137_137[26] U8G_FONT_SECTION("fontpage_6_137_137") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0a,0x00,0x00, - 0x00,0x03,0x03,0x03,0x06,0x01,0x07,0xc0,0x20,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0A,0x00,0x00, + 0x00,0x03,0x03,0x03,0x06,0x01,0x07,0xC0,0x20,0x40}; const u8g_fntpgm_uint8_t fontpage_6_163_163[24] U8G_FONT_SECTION("fontpage_6_163_163") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa3,0xa3,0x00,0x00,0xfe,0x00, - 0x00,0x01,0x01,0x01,0x06,0x02,0xfe,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA3,0xA3,0x00,0x00,0xFE,0x00, + 0x00,0x01,0x01,0x01,0x06,0x02,0xFE,0x80}; const u8g_fntpgm_uint8_t fontpage_6_192_193[33] U8G_FONT_SECTION("fontpage_6_192_193") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc0,0xc1,0x00,0x0a,0x00,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC0,0xC1,0x00,0x0A,0x00,0x00, 0x00,0x02,0x02,0x02,0x06,0x01,0x08,0x80,0x40,0x02,0x02,0x02,0x06,0x02,0x08,0x40, 0x80}; const u8g_fntpgm_uint8_t fontpage_61_161_161[30] U8G_FONT_SECTION("fontpage_61_161_161") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa1,0xa1,0x00,0x05,0xfe,0x00, - 0x00,0x05,0x07,0x07,0x07,0x00,0xfe,0x70,0x08,0x78,0x88,0x78,0x00,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA1,0xA1,0x00,0x05,0xFE,0x00, + 0x00,0x05,0x07,0x07,0x07,0x00,0xFE,0x70,0x08,0x78,0x88,0x78,0x00,0x20}; const u8g_fntpgm_uint8_t fontpage_61_163_163[32] U8G_FONT_SECTION("fontpage_61_163_163") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa3,0xa3,0x00,0x09,0x00,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA3,0xA3,0x00,0x09,0x00,0x00, 0x00,0x05,0x09,0x09,0x07,0x00,0x00,0x30,0x10,0x20,0x00,0x70,0x08,0x78,0x88,0x78 }; const u8g_fntpgm_uint8_t fontpage_61_165_165[33] U8G_FONT_SECTION("fontpage_61_165_165") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa5,0xa5,0x00,0x0a,0x00,0x00, - 0x00,0x06,0x0a,0x0a,0x07,0x00,0x00,0x04,0x08,0x30,0x48,0x00,0x70,0x08,0x78,0x88, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA5,0xA5,0x00,0x0A,0x00,0x00, + 0x00,0x06,0x0A,0x0A,0x07,0x00,0x00,0x04,0x08,0x30,0x48,0x00,0x70,0x08,0x78,0x88, 0x78}; const u8g_fntpgm_uint8_t fontpage_61_167_167[33] U8G_FONT_SECTION("fontpage_61_167_167") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa7,0xa7,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x07,0x00,0x00,0x10,0x08,0x30,0x48,0x00,0x70,0x08,0x78,0x88, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA7,0xA7,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x0A,0x0A,0x07,0x00,0x00,0x10,0x08,0x30,0x48,0x00,0x70,0x08,0x78,0x88, 0x78}; const u8g_fntpgm_uint8_t fontpage_61_169_169[34] U8G_FONT_SECTION("fontpage_61_169_169") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa9,0xa9,0x00,0x0b,0x00,0x00, - 0x00,0x06,0x0b,0x0b,0x07,0x00,0x00,0x0c,0x04,0x08,0x30,0x48,0x00,0x70,0x08,0x78, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA9,0xA9,0x00,0x0B,0x00,0x00, + 0x00,0x06,0x0B,0x0B,0x07,0x00,0x00,0x0C,0x04,0x08,0x30,0x48,0x00,0x70,0x08,0x78, 0x88,0x78}; const u8g_fntpgm_uint8_t fontpage_61_173_173[33] U8G_FONT_SECTION("fontpage_61_173_173") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xad,0xad,0x00,0x08,0xfe,0x00, - 0x00,0x05,0x0a,0x0a,0x07,0x00,0xfe,0x30,0x48,0x00,0x70,0x08,0x78,0x88,0x78,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAD,0xAD,0x00,0x08,0xFE,0x00, + 0x00,0x05,0x0A,0x0A,0x07,0x00,0xFE,0x30,0x48,0x00,0x70,0x08,0x78,0x88,0x78,0x00, 0x20}; const u8g_fntpgm_uint8_t fontpage_61_175_175[33] U8G_FONT_SECTION("fontpage_61_175_175") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xaf,0xaf,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x07,0x00,0x00,0x08,0x10,0x48,0x30,0x00,0x70,0x08,0x78,0x88, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAF,0xAF,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x0A,0x0A,0x07,0x00,0x00,0x08,0x10,0x48,0x30,0x00,0x70,0x08,0x78,0x88, 0x78}; const u8g_fntpgm_uint8_t fontpage_61_177_177[33] U8G_FONT_SECTION("fontpage_61_177_177") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb1,0xb1,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x07,0x00,0x00,0x40,0x20,0x48,0x30,0x00,0x70,0x08,0x78,0x88, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB1,0xB1,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x0A,0x0A,0x07,0x00,0x00,0x40,0x20,0x48,0x30,0x00,0x70,0x08,0x78,0x88, 0x78}; const u8g_fntpgm_uint8_t fontpage_61_179_179[34] U8G_FONT_SECTION("fontpage_61_179_179") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb3,0xb3,0x00,0x0b,0x00,0x00, - 0x00,0x05,0x0b,0x0b,0x07,0x00,0x00,0x18,0x08,0x10,0x48,0x30,0x00,0x70,0x08,0x78, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB3,0xB3,0x00,0x0B,0x00,0x00, + 0x00,0x05,0x0B,0x0B,0x07,0x00,0x00,0x18,0x08,0x10,0x48,0x30,0x00,0x70,0x08,0x78, 0x88,0x78}; const u8g_fntpgm_uint8_t fontpage_61_181_181[34] U8G_FONT_SECTION("fontpage_61_181_181") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb5,0xb5,0x00,0x0b,0x00,0x00, - 0x00,0x06,0x0b,0x0b,0x07,0x00,0x00,0x14,0x28,0x00,0x48,0x30,0x00,0x70,0x08,0x78, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB5,0xB5,0x00,0x0B,0x00,0x00, + 0x00,0x06,0x0B,0x0B,0x07,0x00,0x00,0x14,0x28,0x00,0x48,0x30,0x00,0x70,0x08,0x78, 0x88,0x78}; const u8g_fntpgm_uint8_t fontpage_61_183_183[33] U8G_FONT_SECTION("fontpage_61_183_183") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb7,0xb7,0x00,0x08,0xfe,0x00, - 0x00,0x05,0x0a,0x0a,0x07,0x00,0xfe,0x48,0x30,0x00,0x70,0x08,0x78,0x88,0x78,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB7,0xB7,0x00,0x08,0xFE,0x00, + 0x00,0x05,0x0A,0x0A,0x07,0x00,0xFE,0x48,0x30,0x00,0x70,0x08,0x78,0x88,0x78,0x00, 0x20}; -const u8g_fntpgm_uint8_t fontpage_61_187_187[32] U8G_FONT_SECTION("fontpage_61_187_187") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbb,0xbb,0x00,0x09,0x00,0x00, - 0x00,0x05,0x09,0x09,0x07,0x00,0x00,0x30,0x10,0x20,0x00,0x70,0x88,0xf0,0x80,0x78 - }; const u8g_fntpgm_uint8_t fontpage_61_191_191[33] U8G_FONT_SECTION("fontpage_61_191_191") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbf,0xbf,0x00,0x0a,0x00,0x00, - 0x00,0x06,0x0a,0x0a,0x07,0x00,0x00,0x04,0x08,0x20,0x50,0x00,0x70,0x88,0xf0,0x80, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBF,0xBF,0x00,0x0A,0x00,0x00, + 0x00,0x06,0x0A,0x0A,0x07,0x00,0x00,0x04,0x08,0x20,0x50,0x00,0x70,0x88,0xF0,0x80, 0x78}; const u8g_fntpgm_uint8_t fontpage_61_193_193[33] U8G_FONT_SECTION("fontpage_61_193_193") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc1,0xc1,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x07,0x00,0x00,0x10,0x08,0x20,0x50,0x00,0x70,0x88,0xf0,0x80, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC1,0xC1,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x0A,0x0A,0x07,0x00,0x00,0x10,0x08,0x20,0x50,0x00,0x70,0x88,0xF0,0x80, 0x78}; const u8g_fntpgm_uint8_t fontpage_61_195_195[34] U8G_FONT_SECTION("fontpage_61_195_195") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc3,0xc3,0x00,0x0b,0x00,0x00, - 0x00,0x05,0x0b,0x0b,0x07,0x00,0x00,0x18,0x08,0x10,0x60,0x90,0x00,0x60,0x90,0xf0, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC3,0xC3,0x00,0x0B,0x00,0x00, + 0x00,0x05,0x0B,0x0B,0x07,0x00,0x00,0x18,0x08,0x10,0x60,0x90,0x00,0x60,0x90,0xF0, 0x80,0x70}; const u8g_fntpgm_uint8_t fontpage_61_199_199[33] U8G_FONT_SECTION("fontpage_61_199_199") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc7,0xc7,0x00,0x08,0xfe,0x00, - 0x00,0x05,0x0a,0x0a,0x07,0x00,0xfe,0x20,0x50,0x00,0x70,0x88,0xf0,0x80,0x78,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC7,0xC7,0x00,0x08,0xFE,0x00, + 0x00,0x05,0x0A,0x0A,0x07,0x00,0xFE,0x20,0x50,0x00,0x70,0x88,0xF0,0x80,0x78,0x00, 0x20}; const u8g_fntpgm_uint8_t fontpage_61_201_201[32] U8G_FONT_SECTION("fontpage_61_201_201") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc9,0xc9,0x00,0x09,0x00,0x00, - 0x00,0x03,0x09,0x09,0x07,0x02,0x00,0x60,0x20,0x40,0x00,0xc0,0x40,0x40,0x40,0xe0 + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC9,0xC9,0x00,0x09,0x00,0x00, + 0x00,0x03,0x09,0x09,0x07,0x02,0x00,0x60,0x20,0x40,0x00,0xC0,0x40,0x40,0x40,0xE0 }; const u8g_fntpgm_uint8_t fontpage_61_203_203[32] U8G_FONT_SECTION("fontpage_61_203_203") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcb,0xcb,0x00,0x07,0xfe,0x00, - 0x00,0x03,0x09,0x09,0x07,0x02,0xfe,0x40,0x00,0xc0,0x40,0x40,0x40,0xe0,0x00,0x40 + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCB,0xCB,0x00,0x07,0xFE,0x00, + 0x00,0x03,0x09,0x09,0x07,0x02,0xFE,0x40,0x00,0xC0,0x40,0x40,0x40,0xE0,0x00,0x40 }; const u8g_fntpgm_uint8_t fontpage_61_205_205[30] U8G_FONT_SECTION("fontpage_61_205_205") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcd,0xcd,0x00,0x05,0xfe,0x00, - 0x00,0x05,0x07,0x07,0x07,0x00,0xfe,0x70,0x88,0x88,0x88,0x70,0x00,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCD,0xCD,0x00,0x05,0xFE,0x00, + 0x00,0x05,0x07,0x07,0x07,0x00,0xFE,0x70,0x88,0x88,0x88,0x70,0x00,0x20}; const u8g_fntpgm_uint8_t fontpage_61_207_207[32] U8G_FONT_SECTION("fontpage_61_207_207") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcf,0xcf,0x00,0x09,0x00,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCF,0xCF,0x00,0x09,0x00,0x00, 0x00,0x05,0x09,0x09,0x07,0x00,0x00,0x30,0x10,0x20,0x00,0x70,0x88,0x88,0x88,0x70 }; const u8g_fntpgm_uint8_t fontpage_61_209_209[33] U8G_FONT_SECTION("fontpage_61_209_209") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd1,0xd1,0x00,0x0a,0x00,0x00, - 0x00,0x06,0x0a,0x0a,0x07,0x00,0x00,0x04,0x08,0x20,0x50,0x00,0x70,0x88,0x88,0x88, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD1,0xD1,0x00,0x0A,0x00,0x00, + 0x00,0x06,0x0A,0x0A,0x07,0x00,0x00,0x04,0x08,0x20,0x50,0x00,0x70,0x88,0x88,0x88, 0x70}; const u8g_fntpgm_uint8_t fontpage_61_211_211[33] U8G_FONT_SECTION("fontpage_61_211_211") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd3,0xd3,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x07,0x00,0x00,0x10,0x08,0x20,0x50,0x00,0x70,0x88,0x88,0x88, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD3,0xD3,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x0A,0x0A,0x07,0x00,0x00,0x10,0x08,0x20,0x50,0x00,0x70,0x88,0x88,0x88, 0x70}; const u8g_fntpgm_uint8_t fontpage_61_213_213[33] U8G_FONT_SECTION("fontpage_61_213_213") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd5,0xd5,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x07,0x00,0x00,0x18,0x08,0x30,0x50,0x00,0x70,0x88,0x88,0x88, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD5,0xD5,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x0A,0x0A,0x07,0x00,0x00,0x18,0x08,0x30,0x50,0x00,0x70,0x88,0x88,0x88, 0x70}; const u8g_fntpgm_uint8_t fontpage_61_215_215[34] U8G_FONT_SECTION("fontpage_61_215_215") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd7,0xd7,0x00,0x0b,0x00,0x00, - 0x00,0x05,0x0b,0x0b,0x07,0x00,0x00,0x28,0x50,0x00,0x20,0x50,0x00,0x70,0x88,0x88, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD7,0xD7,0x00,0x0B,0x00,0x00, + 0x00,0x05,0x0B,0x0B,0x07,0x00,0x00,0x28,0x50,0x00,0x20,0x50,0x00,0x70,0x88,0x88, 0x88,0x70}; const u8g_fntpgm_uint8_t fontpage_61_217_217[33] U8G_FONT_SECTION("fontpage_61_217_217") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd9,0xd9,0x00,0x08,0xfe,0x00, - 0x00,0x05,0x0a,0x0a,0x07,0x00,0xfe,0x20,0x50,0x00,0x70,0x88,0x88,0x88,0x70,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD9,0xD9,0x00,0x08,0xFE,0x00, + 0x00,0x05,0x0A,0x0A,0x07,0x00,0xFE,0x20,0x50,0x00,0x70,0x88,0x88,0x88,0x70,0x00, 0x20}; const u8g_fntpgm_uint8_t fontpage_61_219_219[32] U8G_FONT_SECTION("fontpage_61_219_219") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xdb,0xdb,0x00,0x09,0x00,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDB,0xDB,0x00,0x09,0x00,0x00, 0x00,0x05,0x09,0x09,0x07,0x00,0x00,0x20,0x40,0x10,0x08,0x70,0x88,0x88,0x88,0x70 }; const u8g_fntpgm_uint8_t fontpage_61_221_221[32] U8G_FONT_SECTION("fontpage_61_221_221") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xdd,0xdd,0x00,0x09,0x00,0x00, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDD,0xDD,0x00,0x09,0x00,0x00, 0x00,0x05,0x09,0x09,0x07,0x00,0x00,0x80,0x40,0x10,0x08,0x70,0x88,0x88,0x88,0x70 }; const u8g_fntpgm_uint8_t fontpage_61_223_223[33] U8G_FONT_SECTION("fontpage_61_223_223") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xdf,0xdf,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x07,0x00,0x00,0x60,0x20,0x40,0x10,0x08,0x70,0x88,0x88,0x88, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDF,0xDF,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x0A,0x0A,0x07,0x00,0x00,0x60,0x20,0x40,0x10,0x08,0x70,0x88,0x88,0x88, 0x70}; const u8g_fntpgm_uint8_t fontpage_61_225_225[32] U8G_FONT_SECTION("fontpage_61_225_225") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe1,0xe1,0x00,0x09,0x00,0x00, - 0x00,0x05,0x09,0x09,0x07,0x00,0x00,0x50,0xa0,0x10,0x08,0x70,0x88,0x88,0x88,0x70 + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE1,0xE1,0x00,0x09,0x00,0x00, + 0x00,0x05,0x09,0x09,0x07,0x00,0x00,0x50,0xA0,0x10,0x08,0x70,0x88,0x88,0x88,0x70 }; const u8g_fntpgm_uint8_t fontpage_61_227_227[32] U8G_FONT_SECTION("fontpage_61_227_227") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe3,0xe3,0x00,0x07,0xfe,0x00, - 0x00,0x05,0x09,0x09,0x00,0x00,0xfe,0x10,0x08,0x70,0x88,0x88,0x88,0x70,0x00,0x20 + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE3,0xE3,0x00,0x07,0xFE,0x00, + 0x00,0x05,0x09,0x09,0x00,0x00,0xFE,0x10,0x08,0x70,0x88,0x88,0x88,0x70,0x00,0x20 }; const u8g_fntpgm_uint8_t fontpage_61_229_229[30] U8G_FONT_SECTION("fontpage_61_229_229") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe5,0xe5,0x00,0x05,0xfe,0x00, - 0x00,0x05,0x07,0x07,0x07,0x00,0xfe,0x88,0x88,0x88,0x88,0x70,0x00,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE5,0xE5,0x00,0x05,0xFE,0x00, + 0x00,0x05,0x07,0x07,0x07,0x00,0xFE,0x88,0x88,0x88,0x88,0x70,0x00,0x20}; const u8g_fntpgm_uint8_t fontpage_61_231_231[33] U8G_FONT_SECTION("fontpage_61_231_231") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe7,0xe7,0x00,0x0a,0x00,0x00, - 0x00,0x05,0x0a,0x0a,0x07,0x00,0x00,0x30,0x10,0x20,0x00,0x00,0x88,0x88,0x88,0x88, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE7,0xE7,0x00,0x0A,0x00,0x00, + 0x00,0x05,0x0A,0x0A,0x07,0x00,0x00,0x30,0x10,0x20,0x00,0x00,0x88,0x88,0x88,0x88, 0x70}; const u8g_fntpgm_uint8_t fontpage_61_233_233[32] U8G_FONT_SECTION("fontpage_61_233_233") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe9,0xe9,0x00,0x09,0x00,0x00, - 0x00,0x06,0x09,0x09,0x07,0x00,0x00,0x10,0x20,0x0c,0x04,0x88,0x88,0x88,0x88,0x70 + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE9,0xE9,0x00,0x09,0x00,0x00, + 0x00,0x06,0x09,0x09,0x07,0x00,0x00,0x10,0x20,0x0C,0x04,0x88,0x88,0x88,0x88,0x70 }; const u8g_fntpgm_uint8_t fontpage_61_235_235[32] U8G_FONT_SECTION("fontpage_61_235_235") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xeb,0xeb,0x00,0x09,0x00,0x00, - 0x00,0x06,0x09,0x09,0x07,0x00,0x00,0x40,0x20,0x0c,0x04,0x88,0x88,0x88,0x88,0x70 + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xEB,0xEB,0x00,0x09,0x00,0x00, + 0x00,0x06,0x09,0x09,0x07,0x00,0x00,0x40,0x20,0x0C,0x04,0x88,0x88,0x88,0x88,0x70 }; const u8g_fntpgm_uint8_t fontpage_61_237_237[33] U8G_FONT_SECTION("fontpage_61_237_237") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xed,0xed,0x00,0x0a,0x00,0x00, - 0x00,0x06,0x0a,0x0a,0x07,0x00,0x00,0x30,0x10,0x20,0x0c,0x04,0x88,0x88,0x88,0x88, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xED,0xED,0x00,0x0A,0x00,0x00, + 0x00,0x06,0x0A,0x0A,0x07,0x00,0x00,0x30,0x10,0x20,0x0C,0x04,0x88,0x88,0x88,0x88, 0x70}; const u8g_fntpgm_uint8_t fontpage_61_239_239[32] U8G_FONT_SECTION("fontpage_61_239_239") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xef,0xef,0x00,0x09,0x00,0x00, - 0x00,0x06,0x09,0x09,0x07,0x00,0x00,0x28,0x50,0x0c,0x04,0x88,0x88,0x88,0x88,0x70 + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xEF,0xEF,0x00,0x09,0x00,0x00, + 0x00,0x06,0x09,0x09,0x07,0x00,0x00,0x28,0x50,0x0C,0x04,0x88,0x88,0x88,0x88,0x70 }; const u8g_fntpgm_uint8_t fontpage_61_241_241[32] U8G_FONT_SECTION("fontpage_61_241_241") = { - 0x00,0x0c,0x0d,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf1,0xf1,0x00,0x07,0xfe,0x00, - 0x00,0x06,0x09,0x09,0x07,0x00,0xfe,0x0c,0x04,0x88,0x88,0x88,0x88,0x70,0x00,0x20 + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF1,0xF1,0x00,0x07,0xFE,0x00, + 0x00,0x06,0x09,0x09,0x07,0x00,0xFE,0x0C,0x04,0x88,0x88,0x88,0x88,0x70,0x00,0x20 }; #define FONTDATA_ITEM(page, begin, end, data) { page, begin, end, COUNT(data), data } @@ -203,7 +199,6 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(61, 179, 179, fontpage_61_179_179), // 'ẳ' -- 'ẳ' FONTDATA_ITEM(61, 181, 181, fontpage_61_181_181), // 'ẵ' -- 'ẵ' FONTDATA_ITEM(61, 183, 183, fontpage_61_183_183), // 'ặ' -- 'ặ' - FONTDATA_ITEM(61, 187, 187, fontpage_61_187_187), // 'ẻ' -- 'ẻ' FONTDATA_ITEM(61, 191, 191, fontpage_61_191_191), // 'ế' -- 'ế' FONTDATA_ITEM(61, 193, 193, fontpage_61_193_193), // 'ề' -- 'ề' FONTDATA_ITEM(61, 195, 195, fontpage_61_195_195), // 'ể' -- 'ể' diff --git a/Marlin/src/lcd/dogm/fontdata/langdata_zh_CN.h b/Marlin/src/lcd/dogm/fontdata/langdata_zh_CN.h index 87183cd5df61..491d480a0150 100644 --- a/Marlin/src/lcd/dogm/fontdata/langdata_zh_CN.h +++ b/Marlin/src/lcd/dogm/fontdata/langdata_zh_CN.h @@ -6,1033 +6,1461 @@ #include const u8g_fntpgm_uint8_t fontpage_64_157_157[26] U8G_FONT_SECTION("fontpage_64_157_157") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9d,0x9d,0x00,0x07,0x00,0x00, - 0x00,0x05,0x03,0x03,0x06,0x00,0x04,0xd8,0x48,0x90}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9D,0x9D,0x00,0x07,0x00,0x00, + 0x00,0x05,0x03,0x03,0x06,0x00,0x04,0xD8,0x48,0x90}; const u8g_fntpgm_uint8_t fontpage_69_191_191[28] U8G_FONT_SECTION("fontpage_69_191_191") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbf,0xbf,0x00,0x05,0x00,0x00, - 0x00,0x05,0x05,0x05,0x06,0x00,0x00,0x08,0x18,0x28,0x48,0xf8}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBF,0xBF,0x00,0x05,0x00,0x00, + 0x00,0x05,0x05,0x05,0x06,0x00,0x00,0x08,0x18,0x28,0x48,0xF8}; const u8g_fntpgm_uint8_t fontpage_156_128_128[27] U8G_FONT_SECTION("fontpage_156_128_128") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x06,0x00,0x00, - 0x00,0x0b,0x02,0x04,0x0c,0x00,0x04,0x00,0x40,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x06,0x00,0x00, + 0x00,0x0B,0x02,0x04,0x0C,0x00,0x04,0x00,0x40,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_156_137_139[97] U8G_FONT_SECTION("fontpage_156_137_139") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x89,0x8b,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0a,0x14,0x0c,0x00,0xff,0x7f,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x3f, - 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xe0,0x0b,0x0b,0x16,0x0c,0x00, - 0xff,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x07,0xc0,0x04,0x00,0x04,0x00,0x04, - 0x00,0x04,0x00,0x04,0x00,0xff,0xe0,0x0b,0x0a,0x14,0x0c,0x00,0xff,0xff,0xe0,0x04, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x89,0x8B,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0A,0x14,0x0C,0x00,0xFF,0x7F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x3F, + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xE0,0x0B,0x0B,0x16,0x0C,0x00, + 0xFF,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x07,0xC0,0x04,0x00,0x04,0x00,0x04, + 0x00,0x04,0x00,0x04,0x00,0xFF,0xE0,0x0B,0x0A,0x14,0x0C,0x00,0xFF,0xFF,0xE0,0x04, 0x00,0x04,0x00,0x06,0x00,0x05,0x00,0x04,0x80,0x04,0x80,0x04,0x00,0x04,0x00,0x04, 0x00}; +const u8g_fntpgm_uint8_t fontpage_156_141_141[45] U8G_FONT_SECTION("fontpage_156_141_141") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8D,0x8D,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xFF,0xE0,0x02,0x00,0x02,0x00,0x04,0x00,0x0D, + 0x00,0x14,0x80,0x24,0x40,0x44,0x20,0x84,0x00,0x04,0x00,0x04,0x00}; +const u8g_fntpgm_uint8_t fontpage_156_147_147[45] U8G_FONT_SECTION("fontpage_156_147_147") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x93,0x93,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x3F,0xC0,0x04,0x00,0x04,0x00,0xFF, + 0xE0,0x08,0x00,0x1F,0xC0,0x00,0x80,0x0D,0x00,0x02,0x00,0x01,0x00}; const u8g_fntpgm_uint8_t fontpage_156_157_157[45] U8G_FONT_SECTION("fontpage_156_157_157") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9d,0x9d,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x21,0x00,0x29,0x40,0x4a,0x40,0xf7, - 0x80,0x10,0x80,0x21,0x00,0x42,0x00,0xf7,0xc0,0x00,0x00,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9D,0x9D,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x21,0x00,0x29,0x40,0x4A,0x40,0xF7, + 0x80,0x10,0x80,0x21,0x00,0x42,0x00,0xF7,0xC0,0x00,0x00,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_156_170_170[45] U8G_FONT_SECTION("fontpage_156_170_170") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xaa,0xaa,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x08,0x00,0x08,0x00,0x14,0x00,0x22,0x00,0x49, - 0x00,0x88,0xc0,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAA,0xAA,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x08,0x00,0x08,0x00,0x14,0x00,0x22,0x00,0x49, + 0x00,0x88,0xC0,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00}; const u8g_fntpgm_uint8_t fontpage_156_173_173[45] U8G_FONT_SECTION("fontpage_156_173_173") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xad,0xad,0x00,0x0a,0xff,0x00, - 0x00,0x09,0x0b,0x16,0x0c,0x01,0xff,0x08,0x00,0x08,0x00,0xff,0x80,0x88,0x80,0x88, - 0x80,0x88,0x80,0xff,0x80,0x88,0x80,0x08,0x00,0x08,0x00,0x08,0x00}; -const u8g_fntpgm_uint8_t fontpage_156_187_187[45] U8G_FONT_SECTION("fontpage_156_187_187") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbb,0xbb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x08,0x00,0x04,0x00,0xff,0xe0,0x04,0x00,0x04, - 0x00,0x04,0x00,0x7f,0xc0,0x04,0x00,0x04,0x00,0x04,0x00,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAD,0xAD,0x00,0x0A,0xFF,0x00, + 0x00,0x09,0x0B,0x16,0x0C,0x01,0xFF,0x08,0x00,0x08,0x00,0xFF,0x80,0x88,0x80,0x88, + 0x80,0x88,0x80,0xFF,0x80,0x88,0x80,0x08,0x00,0x08,0x00,0x08,0x00}; +const u8g_fntpgm_uint8_t fontpage_156_186_187[73] U8G_FONT_SECTION("fontpage_156_186_187") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBA,0xBB,0x00,0x0A,0xFF,0x00, + 0x00,0x09,0x0B,0x16,0x0C,0x01,0xFF,0x48,0x00,0x28,0x00,0x08,0x00,0xFF,0x80,0x08, + 0x80,0x0C,0x80,0x12,0x80,0x12,0x80,0x20,0x80,0x44,0x80,0x83,0x00,0x0B,0x0B,0x16, + 0x0C,0x00,0xFF,0x08,0x00,0x04,0x00,0xFF,0xE0,0x04,0x00,0x04,0x00,0x04,0x00,0x7F, + 0xC0,0x04,0x00,0x04,0x00,0x04,0x00,0xFF,0xE0}; +const u8g_fntpgm_uint8_t fontpage_156_201_201[45] U8G_FONT_SECTION("fontpage_156_201_201") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC9,0xC9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x08,0x80,0x24,0x80,0x24,0x80,0x21,0x00,0x11, + 0x00,0x12,0x00,0x0A,0x00,0x04,0x00,0x0A,0x00,0x31,0x80,0xC0,0x60}; const u8g_fntpgm_uint8_t fontpage_156_203_203[45] U8G_FONT_SECTION("fontpage_156_203_203") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcb,0xcb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x08,0x00,0x04,0x00,0x7f,0xc0,0x00,0x80,0x01, - 0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x30,0x00,0x48,0x00,0x87,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCB,0xCB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x08,0x00,0x04,0x00,0x7F,0xC0,0x00,0x80,0x01, + 0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x30,0x00,0x48,0x00,0x87,0xE0}; const u8g_fntpgm_uint8_t fontpage_157_134_134[45] U8G_FONT_SECTION("fontpage_157_134_134") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x86,0x86,0x00,0x0a,0xff,0x00, - 0x00,0x09,0x0b,0x16,0x0c,0x01,0xff,0xff,0x80,0x01,0x00,0x02,0x00,0x0c,0x00,0x08, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x86,0x86,0x00,0x0A,0xFF,0x00, + 0x00,0x09,0x0B,0x16,0x0C,0x01,0xFF,0xFF,0x80,0x01,0x00,0x02,0x00,0x0C,0x00,0x08, 0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x28,0x00,0x10,0x00}; +const u8g_fntpgm_uint8_t fontpage_157_140_140[39] U8G_FONT_SECTION("fontpage_157_140_140") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8C,0x8C,0x00,0x08,0x00,0x00, + 0x00,0x0B,0x08,0x10,0x0C,0x00,0x00,0x7F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_157_142_142[45] U8G_FONT_SECTION("fontpage_157_142_142") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8e,0x8e,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x7f,0xc0,0x04,0x00,0x04,0x00,0x04,0x00,0xff, - 0xe0,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x1c,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8E,0x8E,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0xC0,0x04,0x00,0x04,0x00,0x04,0x00,0xFF, + 0xE0,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x1C,0x00}; +const u8g_fntpgm_uint8_t fontpage_157_164_164[45] U8G_FONT_SECTION("fontpage_157_164_164") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA4,0xA4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0xFF,0xE0,0x00,0x00,0x11,0x00,0x20, + 0x80,0x51,0x40,0x11,0x00,0x0A,0x00,0x04,0x00,0x1B,0x00,0x60,0xE0}; const u8g_fntpgm_uint8_t fontpage_157_174_174[45] U8G_FONT_SECTION("fontpage_157_174_174") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xae,0xae,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0xff,0xe0,0x11,0x00,0x1f,0x00,0x00, - 0x00,0xff,0xe0,0x80,0x20,0x1f,0x00,0x11,0x00,0x21,0x20,0xc0,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAE,0xAE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0xFF,0xE0,0x11,0x00,0x1F,0x00,0x00, + 0x00,0xFF,0xE0,0x80,0x20,0x1F,0x00,0x11,0x00,0x21,0x20,0xC0,0xE0}; const u8g_fntpgm_uint8_t fontpage_157_206_206[45] U8G_FONT_SECTION("fontpage_157_206_206") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xce,0xce,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x11, - 0x00,0x11,0x00,0x2a,0x80,0x2a,0x80,0x44,0x40,0x88,0x40,0x10,0x20}; -const u8g_fntpgm_uint8_t fontpage_157_228_228[45] U8G_FONT_SECTION("fontpage_157_228_228") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe4,0xe4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x04,0x00,0x0a,0x00,0x11,0x00,0x24, - 0x80,0xc2,0x60,0x3f,0x80,0x01,0x00,0x0a,0x00,0x04,0x00,0x02,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCE,0xCE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x11, + 0x00,0x11,0x00,0x2A,0x80,0x2A,0x80,0x44,0x40,0x88,0x40,0x10,0x20}; +const u8g_fntpgm_uint8_t fontpage_157_228_229[73] U8G_FONT_SECTION("fontpage_157_228_229") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE4,0xE5,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x04,0x00,0x0A,0x00,0x11,0x00,0x24, + 0x80,0xC2,0x60,0x3F,0x80,0x01,0x00,0x0A,0x00,0x04,0x00,0x02,0x00,0x0A,0x0B,0x16, + 0x0C,0x01,0xFF,0x01,0x00,0x81,0x00,0x91,0x00,0x89,0x00,0x89,0x00,0x81,0x00,0x91, + 0x00,0xA1,0x00,0xC2,0x80,0x84,0x40,0x18,0x40}; +const u8g_fntpgm_uint8_t fontpage_157_246_246[45] U8G_FONT_SECTION("fontpage_157_246_246") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF6,0xF6,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x15,0x00,0x25,0x00,0x2F,0xC0,0x71, + 0x00,0xA1,0x00,0x2F,0xE0,0x21,0x00,0x21,0x00,0x21,0x00,0x21,0x00}; const u8g_fntpgm_uint8_t fontpage_157_253_253[45] U8G_FONT_SECTION("fontpage_157_253_253") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfd,0xfd,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x10,0x80,0x12,0x80,0x22,0x40,0x24,0x40,0x68, - 0x20,0xa7,0xc0,0x22,0x40,0x22,0x40,0x22,0x40,0x24,0x40,0x28,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFD,0xFD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x10,0x80,0x12,0x80,0x22,0x40,0x24,0x40,0x68, + 0x20,0xA7,0xC0,0x22,0x40,0x22,0x40,0x22,0x40,0x24,0x40,0x28,0xC0}; const u8g_fntpgm_uint8_t fontpage_158_145_145[45] U8G_FONT_SECTION("fontpage_158_145_145") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x91,0x91,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0x11,0x00,0x21,0x00,0x3f,0xe0,0x61, - 0x00,0xa3,0x80,0x23,0x80,0x25,0x40,0x29,0x20,0x31,0x00,0x21,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x91,0x91,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x11,0x00,0x21,0x00,0x3F,0xE0,0x61, + 0x00,0xA3,0x80,0x23,0x80,0x25,0x40,0x29,0x20,0x31,0x00,0x21,0x00}; +const u8g_fntpgm_uint8_t fontpage_158_160_160[45] U8G_FONT_SECTION("fontpage_158_160_160") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA0,0xA0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x11,0x00,0x27,0xE0,0x21,0x00,0x6F, + 0xE0,0xA2,0x00,0x27,0xE0,0x20,0x40,0x22,0x80,0x21,0x00,0x20,0x80}; const u8g_fntpgm_uint8_t fontpage_158_205_206[73] U8G_FONT_SECTION("fontpage_158_205_206") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcd,0xce,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x12,0x00,0x11,0x00,0x20,0x00,0x2f,0xe0,0x60, - 0x00,0xa4,0x40,0x22,0x40,0x22,0x80,0x20,0x80,0x21,0x00,0x2f,0xe0,0x0b,0x0b,0x16, - 0x0c,0x00,0xff,0x10,0xc0,0x1f,0x00,0x29,0x00,0x29,0x00,0x69,0x00,0xaf,0xe0,0x29, - 0x00,0x29,0x20,0x2a,0xa0,0x2d,0x60,0x28,0xa0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCD,0xCE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x12,0x00,0x11,0x00,0x20,0x00,0x2F,0xE0,0x60, + 0x00,0xA4,0x40,0x22,0x40,0x22,0x80,0x20,0x80,0x21,0x00,0x2F,0xE0,0x0B,0x0B,0x16, + 0x0C,0x00,0xFF,0x10,0xC0,0x1F,0x00,0x29,0x00,0x29,0x00,0x69,0x00,0xAF,0xE0,0x29, + 0x00,0x29,0x20,0x2A,0xA0,0x2D,0x60,0x28,0xA0}; +const u8g_fntpgm_uint8_t fontpage_158_211_211[45] U8G_FONT_SECTION("fontpage_158_211_211") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD3,0xD3,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0x22,0x00,0x5F,0xC0,0x42,0x00,0xC7, + 0x00,0x4A,0x80,0x52,0x40,0x62,0x20,0x4F,0x80,0x42,0x00,0x42,0x00}; +const u8g_fntpgm_uint8_t fontpage_158_217_217[45] U8G_FONT_SECTION("fontpage_158_217_217") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD9,0xD9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0xDF, + 0x60,0x04,0x00,0x7F,0xC0,0x04,0x00,0x15,0x00,0x24,0x80,0x4C,0x40}; const u8g_fntpgm_uint8_t fontpage_158_220_220[45] U8G_FONT_SECTION("fontpage_158_220_220") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xdc,0xdc,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x14,0x00,0x14,0x00,0x27,0xe0,0x2a,0x00,0x72, - 0x00,0xa3,0xc0,0x22,0x00,0x22,0x00,0x23,0xe0,0x22,0x00,0x22,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDC,0xDC,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x14,0x00,0x14,0x00,0x27,0xE0,0x2A,0x00,0x72, + 0x00,0xA3,0xC0,0x22,0x00,0x22,0x00,0x23,0xE0,0x22,0x00,0x22,0x00}; +const u8g_fntpgm_uint8_t fontpage_158_255_255[45] U8G_FONT_SECTION("fontpage_158_255_255") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x1F,0xE0,0x21,0x00,0x2F,0xE0,0x69, + 0x20,0xAF,0xE0,0x29,0x00,0x25,0x00,0x22,0x00,0x25,0x80,0x38,0x60}; const u8g_fntpgm_uint8_t fontpage_159_155_155[45] U8G_FONT_SECTION("fontpage_159_155_155") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9b,0x9b,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x14,0x80,0x14,0x80,0x24,0x80,0x2f,0xe0,0x64, - 0x80,0xa4,0x80,0x3f,0xe0,0x20,0x00,0x24,0x80,0x28,0x40,0x30,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9B,0x9B,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x14,0x80,0x14,0x80,0x24,0x80,0x2F,0xE0,0x64, + 0x80,0xA4,0x80,0x3F,0xE0,0x20,0x00,0x24,0x80,0x28,0x40,0x30,0x20}; +const u8g_fntpgm_uint8_t fontpage_159_181_181[45] U8G_FONT_SECTION("fontpage_159_181_181") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB5,0xB5,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x2F,0xC0,0x20,0x40,0x4F,0xC0,0x40,0x40,0xDF, + 0xE0,0x50,0x20,0x4F,0xC0,0x44,0x80,0x43,0x00,0x44,0x80,0x58,0x60}; const u8g_fntpgm_uint8_t fontpage_159_221_221[45] U8G_FONT_SECTION("fontpage_159_221_221") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xdd,0xdd,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x17,0xc0,0x14,0x40,0x24,0x40,0x27,0xc0,0x61, - 0x00,0xaf,0xe0,0x21,0x00,0x23,0x80,0x25,0x40,0x29,0x20,0x21,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDD,0xDD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x17,0xC0,0x14,0x40,0x24,0x40,0x27,0xC0,0x61, + 0x00,0xAF,0xE0,0x21,0x00,0x23,0x80,0x25,0x40,0x29,0x20,0x21,0x00}; const u8g_fntpgm_uint8_t fontpage_159_225_225[45] U8G_FONT_SECTION("fontpage_159_225_225") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe1,0xe1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x12,0x00,0x11,0x00,0x2f,0xe0,0x20,0x00,0x67, - 0xc0,0xa0,0x00,0x27,0xc0,0x20,0x00,0x27,0xc0,0x24,0x40,0x27,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE1,0xE1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x12,0x00,0x11,0x00,0x2F,0xE0,0x20,0x00,0x67, + 0xC0,0xA0,0x00,0x27,0xC0,0x20,0x00,0x27,0xC0,0x24,0x40,0x27,0xC0}; const u8g_fntpgm_uint8_t fontpage_160_188_188[45] U8G_FONT_SECTION("fontpage_160_188_188") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbc,0xbc,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0x1f,0xe0,0x22,0x00,0x27,0xc0,0x64, - 0x40,0xa7,0xc0,0x24,0x40,0x27,0x40,0x25,0xc0,0x24,0x40,0x2f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBC,0xBC,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x1F,0xE0,0x22,0x00,0x27,0xC0,0x64, + 0x40,0xA7,0xC0,0x24,0x40,0x27,0x40,0x25,0xC0,0x24,0x40,0x2F,0xE0}; +const u8g_fntpgm_uint8_t fontpage_160_190_190[45] U8G_FONT_SECTION("fontpage_160_190_190") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBE,0xBE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x13,0xE0,0x19,0x00,0x2B,0xE0,0x2E,0x20,0x6A, + 0xA0,0xAA,0xA0,0x2A,0xA0,0x2E,0xA0,0x2A,0xA0,0x21,0x40,0x26,0x20}; const u8g_fntpgm_uint8_t fontpage_160_207_207[45] U8G_FONT_SECTION("fontpage_160_207_207") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcf,0xcf,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x2f,0xe0,0x28,0x20,0x2f,0xe0,0x68, - 0x00,0xaf,0xe0,0x2a,0xa0,0x2f,0xe0,0x2a,0xa0,0x3a,0xa0,0x28,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCF,0xCF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x2F,0xE0,0x28,0x20,0x2F,0xE0,0x68, + 0x00,0xAF,0xE0,0x2A,0xA0,0x2F,0xE0,0x2A,0xA0,0x3A,0xA0,0x28,0x60}; const u8g_fntpgm_uint8_t fontpage_160_220_220[45] U8G_FONT_SECTION("fontpage_160_220_220") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xdc,0xdc,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x00,0x3f,0xe0,0x20,0x00,0x4f,0xc0,0x48, - 0x40,0xdf,0xe0,0x50,0x20,0x4f,0xc0,0x41,0x00,0x41,0x00,0x47,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDC,0xDC,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0x3F,0xE0,0x20,0x00,0x4F,0xC0,0x48, + 0x40,0xDF,0xE0,0x50,0x20,0x4F,0xC0,0x41,0x00,0x41,0x00,0x47,0x00}; const u8g_fntpgm_uint8_t fontpage_161_168_168[45] U8G_FONT_SECTION("fontpage_161_168_168") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa8,0xa8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x61,0x20,0x57,0xc0,0x41,0x40,0x77,0xe0,0xd1, - 0x00,0x53,0xc0,0x56,0x40,0x53,0xc0,0x5a,0x40,0x52,0x40,0x43,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA8,0xA8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x61,0x20,0x57,0xC0,0x41,0x40,0x77,0xE0,0xD1, + 0x00,0x53,0xC0,0x56,0x40,0x53,0xC0,0x5A,0x40,0x52,0x40,0x43,0xC0}; +const u8g_fntpgm_uint8_t fontpage_161_207_207[45] U8G_FONT_SECTION("fontpage_161_207_207") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCF,0xCF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x13,0xC0,0x14,0x80,0x2F,0xE0,0x35,0x20,0x67, + 0xE0,0xA2,0x20,0x2D,0x40,0x22,0x80,0x2D,0xC0,0x22,0xA0,0x2D,0x80}; const u8g_fntpgm_uint8_t fontpage_162_197_197[45] U8G_FONT_SECTION("fontpage_162_197_197") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc5,0xc5,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x04,0x00,0xff,0xc0,0x08,0x00,0x11,0x00,0x7f, - 0x80,0x12,0x80,0x12,0x00,0x12,0x00,0x22,0x40,0x22,0x40,0xc1,0xc0}; -const u8g_fntpgm_uint8_t fontpage_162_200_200[45] U8G_FONT_SECTION("fontpage_162_200_200") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x24,0x00,0x3f,0xc0,0x44,0x00,0x84, - 0x00,0xff,0xe0,0x12,0x00,0x12,0x00,0x12,0x20,0x22,0x20,0xc1,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC5,0xC5,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x04,0x00,0xFF,0xC0,0x08,0x00,0x11,0x00,0x7F, + 0x80,0x12,0x80,0x12,0x00,0x12,0x00,0x22,0x40,0x22,0x40,0xC1,0xC0}; +const u8g_fntpgm_uint8_t fontpage_162_200_201[73] U8G_FONT_SECTION("fontpage_162_200_201") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC8,0xC9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x24,0x00,0x3F,0xC0,0x44,0x00,0x84, + 0x00,0xFF,0xE0,0x12,0x00,0x12,0x00,0x12,0x20,0x22,0x20,0xC1,0xE0,0x0B,0x0B,0x16, + 0x0C,0x00,0xFF,0x04,0x00,0x44,0x40,0x24,0x80,0x04,0x00,0xFF,0xE0,0x12,0x00,0x12, + 0x00,0x12,0x20,0x12,0x20,0x22,0x20,0xC1,0xE0}; const u8g_fntpgm_uint8_t fontpage_162_229_229[45] U8G_FONT_SECTION("fontpage_162_229_229") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe5,0xe5,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x18,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x0a, - 0x00,0x0a,0x00,0x11,0x00,0x11,0x00,0x20,0x80,0x40,0x40,0x80,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE5,0xE5,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x18,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x0A, + 0x00,0x0A,0x00,0x11,0x00,0x11,0x00,0x20,0x80,0x40,0x40,0x80,0x20}; const u8g_fntpgm_uint8_t fontpage_162_232_232[45] U8G_FONT_SECTION("fontpage_162_232_232") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe8,0xe8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x0a,0x00,0x11,0x00,0x20,0x80,0xdf, - 0x60,0x04,0x00,0x04,0x00,0x1f,0x00,0x04,0x00,0x04,0x00,0x7f,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE8,0xE8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0xDF, + 0x60,0x04,0x00,0x04,0x00,0x1F,0x00,0x04,0x00,0x04,0x00,0x7F,0xC0}; const u8g_fntpgm_uint8_t fontpage_162_241_241[45] U8G_FONT_SECTION("fontpage_162_241_241") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf1,0xf1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0x11,0x00,0x7f,0xc0,0x11,0x00,0x11, - 0x00,0x11,0x00,0xff,0xe0,0x00,0x00,0x11,0x00,0x20,0x80,0x40,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF1,0xF1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x11,0x00,0x7F,0xC0,0x11,0x00,0x11, + 0x00,0x11,0x00,0xFF,0xE0,0x00,0x00,0x11,0x00,0x20,0x80,0x40,0x40}; const u8g_fntpgm_uint8_t fontpage_162_243_243[45] U8G_FONT_SECTION("fontpage_162_243_243") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf3,0xf3,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x80,0x11,0x00,0x7f,0xc0,0x04,0x00,0x04, - 0x00,0xff,0xc0,0x04,0x00,0x0a,0x00,0x11,0x00,0x20,0x80,0xc0,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF3,0xF3,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x80,0x11,0x00,0x7F,0xC0,0x04,0x00,0x04, + 0x00,0xFF,0xC0,0x04,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0xC0,0x60}; const u8g_fntpgm_uint8_t fontpage_162_247_247[45] U8G_FONT_SECTION("fontpage_162_247_247") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf7,0xf7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x3f,0x80,0x20,0x80,0x3f,0x80,0x20,0x80,0x3f, - 0x80,0x20,0x80,0x3f,0x80,0x20,0x80,0xff,0xe0,0x11,0x00,0xe0,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF7,0xF7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x3F,0x80,0x20,0x80,0x3F,0x80,0x20,0x80,0x3F, + 0x80,0x20,0x80,0x3F,0x80,0x20,0x80,0xFF,0xE0,0x11,0x00,0xE0,0xE0}; +const u8g_fntpgm_uint8_t fontpage_163_151_151[43] U8G_FONT_SECTION("fontpage_163_151_151") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x97,0x97,0x00,0x09,0xFF,0x00, + 0x00,0x0B,0x0A,0x14,0x0C,0x00,0xFF,0x7F,0xE0,0x40,0x20,0x9F,0x40,0x11,0x00,0x11, + 0x00,0x11,0x00,0x11,0x00,0x21,0x20,0x41,0x20,0x80,0xE0}; const u8g_fntpgm_uint8_t fontpage_163_183_183[45] U8G_FONT_SECTION("fontpage_163_183_183") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb7,0xb7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x82,0x00,0x42,0x00,0x05,0x00,0x28,0x80,0x32, - 0x60,0x41,0x00,0x4f,0xc0,0x80,0x80,0x87,0x00,0x81,0x00,0x00,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB7,0xB7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x82,0x00,0x42,0x00,0x05,0x00,0x28,0x80,0x32, + 0x60,0x41,0x00,0x4F,0xC0,0x80,0x80,0x87,0x00,0x81,0x00,0x00,0x80}; const u8g_fntpgm_uint8_t fontpage_163_198_198[45] U8G_FONT_SECTION("fontpage_163_198_198") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x0a,0x00,0x89,0x00,0x4f,0xe0,0x59,0x00,0x09, - 0x00,0x2f,0xc0,0x29,0x00,0xcf,0xc0,0x49,0x00,0x49,0x00,0x4f,0xe0}; -const u8g_fntpgm_uint8_t fontpage_163_201_201[45] U8G_FONT_SECTION("fontpage_163_201_201") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc9,0xc9,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x81,0x00,0x4f,0xe0,0x40,0x00,0x07,0xc0,0x24, - 0x40,0x24,0x40,0x27,0xc0,0xc1,0x00,0x45,0x40,0x49,0x20,0x53,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x0A,0x00,0x89,0x00,0x4F,0xE0,0x59,0x00,0x09, + 0x00,0x2F,0xC0,0x29,0x00,0xCF,0xC0,0x49,0x00,0x49,0x00,0x4F,0xE0}; const u8g_fntpgm_uint8_t fontpage_163_250_251[73] U8G_FONT_SECTION("fontpage_163_250_251") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfa,0xfb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x44,0x40,0x44,0x40,0x44,0x40,0x7f, - 0xc0,0x04,0x00,0x84,0x20,0x84,0x20,0x84,0x20,0x84,0x20,0xff,0xe0,0x0b,0x0b,0x16, - 0x0c,0x00,0xff,0x04,0x00,0x04,0x00,0x7f,0xc0,0x04,0x00,0x04,0x00,0xff,0xe0,0x04, - 0x00,0x44,0x40,0x44,0x40,0x44,0x40,0x7f,0xc0}; -const u8g_fntpgm_uint8_t fontpage_164_134_134[45] U8G_FONT_SECTION("fontpage_164_134_134") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x86,0x86,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0x11,0x00,0x20,0x80,0x20,0x80,0x40, - 0x40,0xbf,0xa0,0x08,0x80,0x08,0x80,0x10,0x80,0x20,0x80,0xc3,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFA,0xFB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x44,0x40,0x44,0x40,0x44,0x40,0x7F, + 0xC0,0x04,0x00,0x84,0x20,0x84,0x20,0x84,0x20,0x84,0x20,0xFF,0xE0,0x0B,0x0B,0x16, + 0x0C,0x00,0xFF,0x04,0x00,0x04,0x00,0x7F,0xC0,0x04,0x00,0x04,0x00,0xFF,0xE0,0x04, + 0x00,0x44,0x40,0x44,0x40,0x44,0x40,0x7F,0xC0}; +const u8g_fntpgm_uint8_t fontpage_164_134_135[73] U8G_FONT_SECTION("fontpage_164_134_135") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x86,0x87,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x11,0x00,0x20,0x80,0x20,0x80,0x40, + 0x40,0xBF,0xA0,0x08,0x80,0x08,0x80,0x10,0x80,0x20,0x80,0xC3,0x00,0x0B,0x0B,0x16, + 0x0C,0x00,0xFF,0x20,0x00,0x27,0xE0,0x21,0x20,0x39,0x20,0xE1,0x20,0x21,0x20,0x29, + 0x20,0x32,0x20,0x22,0x20,0x04,0x20,0x08,0xC0}; const u8g_fntpgm_uint8_t fontpage_164_155_155[45] U8G_FONT_SECTION("fontpage_164_155_155") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9b,0x9b,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x10,0x20,0x18,0x20,0x24,0xa0,0x42,0xa0,0xbc, - 0xa0,0x24,0xa0,0x24,0xa0,0x38,0xa0,0x22,0x20,0x22,0x20,0x1e,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9B,0x9B,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x10,0x20,0x18,0x20,0x24,0xA0,0x42,0xA0,0xBC, + 0xA0,0x24,0xA0,0x24,0xA0,0x38,0xA0,0x22,0x20,0x22,0x20,0x1E,0x60}; const u8g_fntpgm_uint8_t fontpage_164_157_157[45] U8G_FONT_SECTION("fontpage_164_157_157") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9d,0x9d,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x40,0x00,0x27,0xe0,0xf9,0x20,0x11,0x20,0x21, - 0x20,0x69,0x20,0xb1,0x20,0x29,0x20,0x22,0x20,0x24,0x20,0x28,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9D,0x9D,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x40,0x00,0x27,0xE0,0xF9,0x20,0x11,0x20,0x21, + 0x20,0x69,0x20,0xB1,0x20,0x29,0x20,0x22,0x20,0x24,0x20,0x28,0xC0}; +const u8g_fntpgm_uint8_t fontpage_164_171_171[45] U8G_FONT_SECTION("fontpage_164_171_171") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAB,0xAB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7C,0x20,0x44,0x20,0x44,0xA0,0x7C,0xA0,0x10, + 0xA0,0xFE,0xA0,0x12,0xA0,0x22,0xA0,0x22,0x20,0x42,0x20,0x8C,0xE0}; const u8g_fntpgm_uint8_t fontpage_164_176_176[45] U8G_FONT_SECTION("fontpage_164_176_176") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb0,0xb0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xfe,0x20,0x10,0x20,0x20,0xa0,0x44,0xa0,0xfe, - 0xa0,0x10,0xa0,0x7c,0xa0,0x10,0xa0,0x10,0x20,0x1e,0x20,0xe0,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB0,0xB0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xFE,0x20,0x10,0x20,0x20,0xA0,0x44,0xA0,0xFE, + 0xA0,0x10,0xA0,0x7C,0xA0,0x10,0xA0,0x10,0x20,0x1E,0x20,0xE0,0xE0}; const u8g_fntpgm_uint8_t fontpage_164_182_183[73] U8G_FONT_SECTION("fontpage_164_182_183") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb6,0xb7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x10,0x20,0x50,0xa0,0x7e,0xa0,0x90,0xa0,0xfe, - 0xa0,0x10,0xa0,0x7e,0xa0,0x52,0xa0,0x52,0x20,0x56,0x20,0x10,0xe0,0x0b,0x0b,0x16, - 0x0c,0x00,0xff,0x7e,0x20,0x42,0x20,0x7e,0xa0,0x48,0xa0,0x48,0xa0,0x7e,0xa0,0x6a, - 0xa0,0xaa,0xa0,0xaa,0xa0,0x2e,0x20,0x08,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB6,0xB7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x10,0x20,0x50,0xA0,0x7E,0xA0,0x90,0xA0,0xFE, + 0xA0,0x10,0xA0,0x7E,0xA0,0x52,0xA0,0x52,0x20,0x56,0x20,0x10,0xE0,0x0B,0x0B,0x16, + 0x0C,0x00,0xFF,0x7E,0x20,0x42,0x20,0x7E,0xA0,0x48,0xA0,0x48,0xA0,0x7E,0xA0,0x6A, + 0xA0,0xAA,0xA0,0xAA,0xA0,0x2E,0x20,0x08,0xE0}; +const u8g_fntpgm_uint8_t fontpage_164_242_242[45] U8G_FONT_SECTION("fontpage_164_242_242") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF2,0xF2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x10,0x20,0xFE,0x20,0x92,0xA0,0x7C,0xA0,0x10, + 0xA0,0x7C,0xA0,0x10,0xA0,0xFE,0xA0,0x44,0x20,0x44,0x20,0x7C,0xE0}; const u8g_fntpgm_uint8_t fontpage_165_155_155[45] U8G_FONT_SECTION("fontpage_165_155_155") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9b,0x9b,0x00,0x0a,0xff,0x00, - 0x00,0x09,0x0b,0x16,0x0c,0x01,0xff,0x08,0x00,0x08,0x00,0x08,0x00,0xff,0x80,0x08, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9B,0x9B,0x00,0x0A,0xFF,0x00, + 0x00,0x09,0x0B,0x16,0x0C,0x01,0xFF,0x08,0x00,0x08,0x00,0x08,0x00,0xFF,0x80,0x08, 0x80,0x08,0x80,0x10,0x80,0x10,0x80,0x20,0x80,0x40,0x80,0x87,0x00}; -const u8g_fntpgm_uint8_t fontpage_165_160_160[45] U8G_FONT_SECTION("fontpage_165_160_160") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa0,0xa0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x00,0x20,0x00,0xfd,0xe0,0x25,0x20,0x25, - 0x20,0x25,0x20,0x25,0x20,0x25,0x20,0x45,0x20,0x55,0xe0,0x89,0x20}; +const u8g_fntpgm_uint8_t fontpage_165_159_160[73] U8G_FONT_SECTION("fontpage_165_159_160") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9F,0xA0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x01,0x00,0x01,0x00,0xF9,0x00,0x27,0xE0,0x21, + 0x20,0x21,0x20,0x21,0x20,0x3A,0x20,0xC2,0x20,0x04,0x20,0x18,0xC0,0x0B,0x0B,0x16, + 0x0C,0x00,0xFF,0x20,0x00,0x20,0x00,0xFD,0xE0,0x25,0x20,0x25,0x20,0x25,0x20,0x25, + 0x20,0x25,0x20,0x45,0x20,0x55,0xE0,0x89,0x20}; const u8g_fntpgm_uint8_t fontpage_165_168_168[45] U8G_FONT_SECTION("fontpage_165_168_168") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa8,0xa8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x01,0x00,0x79,0x00,0x01,0x00,0x03,0xe0,0xfd, - 0x20,0x21,0x20,0x21,0x20,0x49,0x20,0xfa,0x20,0x0a,0x20,0x04,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA8,0xA8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x01,0x00,0x79,0x00,0x01,0x00,0x03,0xE0,0xFD, + 0x20,0x21,0x20,0x21,0x20,0x49,0x20,0xFA,0x20,0x0A,0x20,0x04,0xC0}; const u8g_fntpgm_uint8_t fontpage_166_150_150[45] U8G_FONT_SECTION("fontpage_166_150_150") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x96,0x96,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x12,0x00,0x12,0x00,0x22,0x40,0x22,0x80,0x63, - 0x00,0xa2,0x00,0x26,0x00,0x2a,0x00,0x22,0x20,0x22,0x20,0x21,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x96,0x96,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x12,0x00,0x12,0x00,0x22,0x40,0x22,0x80,0x63, + 0x00,0xA2,0x00,0x26,0x00,0x2A,0x00,0x22,0x20,0x22,0x20,0x21,0xE0}; +const u8g_fntpgm_uint8_t fontpage_166_199_199[45] U8G_FONT_SECTION("fontpage_166_199_199") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC7,0xC7,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x0D,0x00,0x71,0x00,0x11,0x00,0x11,0x00,0x11, + 0x00,0xFF,0xC0,0x11,0x00,0x11,0x00,0x21,0x00,0x41,0x00,0x81,0x00}; const u8g_fntpgm_uint8_t fontpage_166_202_202[45] U8G_FONT_SECTION("fontpage_166_202_202") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xca,0xca,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x44,0x40,0x24,0x80,0x15,0x00,0x7f, - 0xc0,0x04,0x00,0x04,0x00,0xff,0xe0,0x04,0x00,0x04,0x00,0x04,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCA,0xCA,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x44,0x40,0x24,0x80,0x15,0x00,0x7F, + 0xC0,0x04,0x00,0x04,0x00,0xFF,0xE0,0x04,0x00,0x04,0x00,0x04,0x00}; const u8g_fntpgm_uint8_t fontpage_166_207_207[45] U8G_FONT_SECTION("fontpage_166_207_207") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcf,0xcf,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x42,0x00,0x42,0x00,0x4f,0x80,0xe2,0x80,0x42, - 0x80,0x4a,0xc0,0x52,0xa0,0x44,0x80,0x44,0x80,0x4a,0x80,0x51,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCF,0xCF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x42,0x00,0x42,0x00,0x4F,0x80,0xE2,0x80,0x42, + 0x80,0x4A,0xC0,0x52,0xA0,0x44,0x80,0x44,0x80,0x4A,0x80,0x51,0x00}; const u8g_fntpgm_uint8_t fontpage_166_213_213[45] U8G_FONT_SECTION("fontpage_166_213_213") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd5,0xd5,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0x0a,0x00,0x7f,0xc0,0x44,0x40,0x7f, - 0xc0,0x44,0x40,0x7f,0xc0,0x04,0x00,0xff,0xe0,0x04,0x00,0x04,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD5,0xD5,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x0A,0x00,0x7F,0xC0,0x44,0x40,0x7F, + 0xC0,0x44,0x40,0x7F,0xC0,0x04,0x00,0xFF,0xE0,0x04,0x00,0x04,0x00}; const u8g_fntpgm_uint8_t fontpage_166_225_225[45] U8G_FONT_SECTION("fontpage_166_225_225") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe1,0xe1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x08,0x00,0x0f,0x80,0x08,0x00,0x08,0x00,0xff, - 0xe0,0x08,0x00,0x0a,0x00,0x09,0x00,0x08,0x80,0x08,0x00,0x08,0x00}; -const u8g_fntpgm_uint8_t fontpage_166_240_240[45] U8G_FONT_SECTION("fontpage_166_240_240") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf0,0xf0,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x10,0x00,0xe7,0xc0,0x84,0x40,0x84,0x40,0xf4, - 0x40,0x84,0x40,0x84,0x40,0x94,0x40,0xe5,0x80,0x84,0x00,0x04,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE1,0xE1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x08,0x00,0x0F,0x80,0x08,0x00,0x08,0x00,0xFF, + 0xE0,0x08,0x00,0x0A,0x00,0x09,0x00,0x08,0x80,0x08,0x00,0x08,0x00}; +const u8g_fntpgm_uint8_t fontpage_166_240_241[73] U8G_FONT_SECTION("fontpage_166_240_241") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF0,0xF1,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x10,0x00,0xE7,0xC0,0x84,0x40,0x84,0x40,0xF4, + 0x40,0x84,0x40,0x84,0x40,0x94,0x40,0xE5,0x80,0x84,0x00,0x04,0x00,0x0B,0x0B,0x16, + 0x0C,0x00,0xFF,0x10,0x00,0x1F,0x80,0x21,0x00,0x7F,0xE0,0x20,0x00,0x2F,0x80,0x28, + 0x80,0x28,0x80,0x2B,0x20,0x48,0x20,0x87,0xE0}; +const u8g_fntpgm_uint8_t fontpage_166_244_244[45] U8G_FONT_SECTION("fontpage_166_244_244") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF4,0xF4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x10,0x00,0x11,0xE0,0x7D,0x20,0x11,0x20,0x11, + 0x20,0xFF,0x20,0x11,0x20,0x21,0x20,0x4D,0x60,0x75,0x00,0x01,0x00}; const u8g_fntpgm_uint8_t fontpage_166_248_248[45] U8G_FONT_SECTION("fontpage_166_248_248") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf8,0xf8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x40,0x00,0x7d,0xe0,0x91,0x20,0x11,0x20,0xff, - 0x20,0x11,0x20,0x5d,0x20,0x51,0x20,0x51,0xa0,0x5d,0x40,0xe1,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x40,0x00,0x7D,0xE0,0x91,0x20,0x11,0x20,0xFF, + 0x20,0x11,0x20,0x5D,0x20,0x51,0x20,0x51,0xA0,0x5D,0x40,0xE1,0x00}; +const u8g_fntpgm_uint8_t fontpage_167_139_139[45] U8G_FONT_SECTION("fontpage_167_139_139") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8B,0x8B,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x3F,0xE0,0x20,0x00,0x22,0x00,0x22,0x00,0x22, + 0x00,0x3F,0xC0,0x22,0x00,0x22,0x80,0x42,0x40,0x42,0x00,0xBF,0xE0}; const u8g_fntpgm_uint8_t fontpage_167_159_159[45] U8G_FONT_SECTION("fontpage_167_159_159") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9f,0x9f,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x3f,0xe0,0x22,0x00,0x2f,0xc0,0x28,0x40,0x2f, - 0xc0,0x28,0x40,0x2f,0xc0,0x22,0x00,0x2a,0x80,0x52,0x60,0xa6,0x20}; -const u8g_fntpgm_uint8_t fontpage_167_204_204[43] U8G_FONT_SECTION("fontpage_167_204_204") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcc,0xcc,0x00,0x09,0xff,0x00, - 0x00,0x0b,0x0a,0x14,0x0c,0x00,0xff,0xff,0xe0,0x0a,0x40,0x4a,0x40,0x2a,0x40,0x11, - 0x40,0x11,0x40,0x28,0x80,0x45,0x80,0x82,0x40,0x04,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9F,0x9F,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x3F,0xE0,0x22,0x00,0x2F,0xC0,0x28,0x40,0x2F, + 0xC0,0x28,0x40,0x2F,0xC0,0x22,0x00,0x2A,0x80,0x52,0x60,0xA6,0x20}; +const u8g_fntpgm_uint8_t fontpage_167_204_205[71] U8G_FONT_SECTION("fontpage_167_204_205") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCC,0xCD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0A,0x14,0x0C,0x00,0xFF,0xFF,0xE0,0x0A,0x40,0x4A,0x40,0x2A,0x40,0x11, + 0x40,0x11,0x40,0x28,0x80,0x45,0x80,0x82,0x40,0x04,0x20,0x0B,0x0B,0x16,0x0C,0x00, + 0xFF,0x01,0xC0,0x3E,0x00,0x20,0x00,0x20,0x00,0x3F,0xC0,0x28,0x80,0x25,0x00,0x22, + 0x00,0x45,0x00,0x48,0x80,0xB0,0x60}; const u8g_fntpgm_uint8_t fontpage_167_214_214[45] U8G_FONT_SECTION("fontpage_167_214_214") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd6,0xd6,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xfc,0x00,0x4b,0xe0,0x4a,0x20,0x7a,0x20,0x49, - 0x40,0x79,0x40,0x48,0x80,0x4c,0x80,0xf9,0x40,0x0a,0x40,0x0c,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD6,0xD6,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xFC,0x00,0x4B,0xE0,0x4A,0x20,0x7A,0x20,0x49, + 0x40,0x79,0x40,0x48,0x80,0x4C,0x80,0xF9,0x40,0x0A,0x40,0x0C,0x20}; const u8g_fntpgm_uint8_t fontpage_167_216_216[45] U8G_FONT_SECTION("fontpage_167_216_216") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd8,0xd8,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x08,0x00,0xff,0xc0,0x12,0x00,0x52,0x80,0x92, - 0x40,0x00,0x00,0x7f,0x80,0x12,0x00,0x0c,0x00,0x12,0x00,0xe1,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD8,0xD8,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x08,0x00,0xFF,0xC0,0x12,0x00,0x52,0x80,0x92, + 0x40,0x00,0x00,0x7F,0x80,0x12,0x00,0x0C,0x00,0x12,0x00,0xE1,0xC0}; const u8g_fntpgm_uint8_t fontpage_167_240_240[45] U8G_FONT_SECTION("fontpage_167_240_240") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf0,0xf0,0x00,0x0a,0xff,0x00, - 0x00,0x09,0x0b,0x16,0x0c,0x01,0xff,0x08,0x00,0x10,0x00,0x22,0x00,0x41,0x00,0xff, - 0x80,0x00,0x80,0x7f,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x7f,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x0A,0xFF,0x00, + 0x00,0x09,0x0B,0x16,0x0C,0x01,0xFF,0x08,0x00,0x10,0x00,0x22,0x00,0x41,0x00,0xFF, + 0x80,0x00,0x80,0x7F,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x7F,0x00}; +const u8g_fntpgm_uint8_t fontpage_168_131_131[45] U8G_FONT_SECTION("fontpage_168_131_131") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x83,0x83,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x02,0x00,0xF2,0x00,0x97,0xE0,0x98,0x00,0x97, + 0xC0,0x90,0x80,0x91,0x00,0xF2,0x00,0x94,0x20,0x04,0x20,0x03,0xE0}; const u8g_fntpgm_uint8_t fontpage_168_136_136[45] U8G_FONT_SECTION("fontpage_168_136_136") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x0a,0x00,0x11,0x00,0x20,0x80,0xdf, - 0x60,0x00,0x00,0x3f,0x80,0x20,0x80,0x20,0x80,0x3f,0x80,0x20,0x80}; -const u8g_fntpgm_uint8_t fontpage_168_142_142[45] U8G_FONT_SECTION("fontpage_168_142_142") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8e,0x8e,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x01,0xc0,0x3e,0x00,0x20,0x00,0x3f,0xe0,0x20, - 0x00,0x20,0x00,0x2f,0xc0,0x28,0x40,0x48,0x40,0x4f,0xc0,0x88,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0xDF, + 0x60,0x00,0x00,0x3F,0x80,0x20,0x80,0x20,0x80,0x3F,0x80,0x20,0x80}; +const u8g_fntpgm_uint8_t fontpage_168_141_142[73] U8G_FONT_SECTION("fontpage_168_141_142") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8D,0x8E,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x00,0xFF,0x10,0x00,0x1F,0xC0,0x10,0x80,0x29,0x00,0x46, + 0x00,0x04,0x00,0x1F,0xC0,0xF0,0x40,0x10,0x40,0x10,0x40,0x1F,0xC0,0x0B,0x0B,0x16, + 0x0C,0x00,0xFF,0x01,0xC0,0x3E,0x00,0x20,0x00,0x3F,0xE0,0x20,0x00,0x20,0x00,0x2F, + 0xC0,0x28,0x40,0x48,0x40,0x4F,0xC0,0x88,0x40}; +const u8g_fntpgm_uint8_t fontpage_168_145_145[45] U8G_FONT_SECTION("fontpage_168_145_145") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x91,0x91,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x00,0xFF,0x08,0x00,0x10,0x00,0xFF,0xC0,0x80,0x40,0x9E, + 0x40,0x92,0x40,0x92,0x40,0x9E,0x40,0x80,0x40,0x80,0x40,0x81,0xC0}; +const u8g_fntpgm_uint8_t fontpage_168_166_166[45] U8G_FONT_SECTION("fontpage_168_166_166") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA6,0xA6,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xFF,0xE0,0x04,0x00,0x0D,0x80,0x34,0x40,0xC4, + 0x20,0x04,0x00,0x3F,0xC0,0x20,0x40,0x20,0x40,0x3F,0xC0,0x20,0x40}; const u8g_fntpgm_uint8_t fontpage_168_175_175[45] U8G_FONT_SECTION("fontpage_168_175_175") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xaf,0xaf,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x3f,0xc0,0x20,0x40,0x20,0x40,0x3f, - 0xc0,0x20,0x00,0x3f,0xc0,0x30,0x40,0x50,0x40,0x5f,0xc0,0x90,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAF,0xAF,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x3F,0xC0,0x20,0x40,0x20,0x40,0x3F, + 0xC0,0x20,0x00,0x3F,0xC0,0x30,0x40,0x50,0x40,0x5F,0xC0,0x90,0x40}; +const u8g_fntpgm_uint8_t fontpage_168_202_202[45] U8G_FONT_SECTION("fontpage_168_202_202") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCA,0xCA,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x24,0x00,0x24,0x00,0x3F,0xC0,0x44,0x00,0x04, + 0x00,0xFF,0xE0,0x00,0x00,0x3F,0x80,0x20,0x80,0x20,0x80,0x3F,0x80}; +const u8g_fntpgm_uint8_t fontpage_168_232_232[45] U8G_FONT_SECTION("fontpage_168_232_232") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE8,0xE8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x3F,0xE0,0x22,0x20,0x2F,0xA0,0x22,0x20,0x3F, + 0xE0,0x20,0x20,0x2F,0xA0,0x28,0xA0,0x4F,0xA0,0x40,0x20,0x80,0x60}; const u8g_fntpgm_uint8_t fontpage_168_253_253[45] U8G_FONT_SECTION("fontpage_168_253_253") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfd,0xfd,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x0a,0x00,0x11,0x00,0xee,0xe0,0x00, - 0x00,0x7b,0xc0,0x4a,0x40,0x4a,0x40,0x7a,0x40,0x4a,0xc0,0x02,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFD,0xFD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x0A,0x00,0x11,0x00,0xEE,0xE0,0x00, + 0x00,0x7B,0xC0,0x4A,0x40,0x4A,0x40,0x7A,0x40,0x4A,0xC0,0x02,0x00}; const u8g_fntpgm_uint8_t fontpage_169_140_140[45] U8G_FONT_SECTION("fontpage_169_140_140") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8c,0x8c,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x0c,0x00,0x70,0x00,0x11,0xe0,0xfd,0x20,0x11, - 0x20,0x39,0x20,0x35,0x20,0x55,0x20,0x91,0x20,0x11,0xe0,0x10,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8C,0x8C,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x0C,0x00,0x70,0x00,0x11,0xE0,0xFD,0x20,0x11, + 0x20,0x39,0x20,0x35,0x20,0x55,0x20,0x91,0x20,0x11,0xE0,0x10,0x00}; +const u8g_fntpgm_uint8_t fontpage_169_205_205[45] U8G_FONT_SECTION("fontpage_169_205_205") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCD,0xCD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x01,0x00,0x02,0x00,0xEF,0xE0,0xA8,0x20,0xAB, + 0xA0,0xAA,0xA0,0xAA,0xA0,0xEB,0xA0,0x08,0x20,0x08,0x20,0x08,0x60}; const u8g_fntpgm_uint8_t fontpage_171_183_183[45] U8G_FONT_SECTION("fontpage_171_183_183") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb7,0xb7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x01,0x00,0xef,0xe0,0xa5,0x40,0xaf,0xe0,0xa4, - 0x40,0xaf,0xe0,0xe8,0x20,0xa9,0x20,0x09,0x20,0x02,0x80,0x0c,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB7,0xB7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x01,0x00,0xEF,0xE0,0xA5,0x40,0xAF,0xE0,0xA4, + 0x40,0xAF,0xE0,0xE8,0x20,0xA9,0x20,0x09,0x20,0x02,0x80,0x0C,0x60}; const u8g_fntpgm_uint8_t fontpage_172_180_180[45] U8G_FONT_SECTION("fontpage_172_180_180") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb4,0xb4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x02,0xa0,0xeb,0xc0,0xaa,0xa0,0xbf,0xe0,0xa4, - 0x80,0xaf,0xe0,0xf9,0x20,0x0f,0xe0,0x09,0x20,0x0f,0xe0,0x11,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB4,0xB4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x02,0xA0,0xEB,0xC0,0xAA,0xA0,0xBF,0xE0,0xA4, + 0x80,0xAF,0xE0,0xF9,0x20,0x0F,0xE0,0x09,0x20,0x0F,0xE0,0x11,0x20}; +const u8g_fntpgm_uint8_t fontpage_172_232_232[45] U8G_FONT_SECTION("fontpage_172_232_232") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE8,0xE8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7B,0xC0,0x4A,0x40,0x4A,0x40,0x7B,0xC0,0x04, + 0x80,0xFF,0xE0,0x11,0x00,0xFB,0xE0,0x4A,0x40,0x4A,0x40,0x7B,0xC0}; const u8g_fntpgm_uint8_t fontpage_172_244_244[45] U8G_FONT_SECTION("fontpage_172_244_244") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf4,0xf4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x01,0x00,0xef,0xe0,0xa5,0x40,0xaf,0xe0,0xa4, - 0x40,0xa7,0xc0,0xe4,0x40,0x07,0xc0,0x04,0x40,0x07,0xc0,0x0c,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF4,0xF4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x01,0x00,0xEF,0xE0,0xA5,0x40,0xAF,0xE0,0xA4, + 0x40,0xA7,0xC0,0xE4,0x40,0x07,0xC0,0x04,0x40,0x07,0xC0,0x0C,0x60}; const u8g_fntpgm_uint8_t fontpage_173_222_222[45] U8G_FONT_SECTION("fontpage_173_222_222") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xde,0xde,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0xff,0xc0,0x80,0x40,0x80,0x40,0x9e,0x40,0x92, - 0x40,0x92,0x40,0x9e,0x40,0x92,0x40,0x80,0x40,0xff,0xc0,0x80,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDE,0xDE,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0xFF,0xC0,0x80,0x40,0x80,0x40,0x9E,0x40,0x92, + 0x40,0x92,0x40,0x9E,0x40,0x92,0x40,0x80,0x40,0xFF,0xC0,0x80,0x40}; const u8g_fntpgm_uint8_t fontpage_173_224_224[45] U8G_FONT_SECTION("fontpage_173_224_224") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe0,0xe0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xff,0xe0,0x84,0x20,0x84,0x20,0xbf,0xa0,0x84, - 0x20,0x84,0x20,0x8a,0x20,0x91,0x20,0xa0,0xa0,0x80,0x20,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xFF,0xE0,0x84,0x20,0x84,0x20,0xBF,0xA0,0x84, + 0x20,0x84,0x20,0x8A,0x20,0x91,0x20,0xA0,0xA0,0x80,0x20,0xFF,0xE0}; +const u8g_fntpgm_uint8_t fontpage_173_250_250[45] U8G_FONT_SECTION("fontpage_173_250_250") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFA,0xFA,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0xFF,0xC0,0x88,0x40,0x88,0x40,0xFF,0x40,0x88, + 0x40,0xBE,0x40,0xA2,0x40,0xA2,0x40,0xBE,0x40,0x80,0x40,0xFF,0xC0}; const u8g_fntpgm_uint8_t fontpage_173_254_254[45] U8G_FONT_SECTION("fontpage_173_254_254") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfe,0xfe,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0xff,0xc0,0x90,0x40,0x9f,0x40,0xb2,0x40,0xcc, - 0x40,0x92,0x40,0xe9,0xc0,0x84,0x40,0x88,0x40,0x84,0x40,0xff,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0xFF,0xC0,0x90,0x40,0x9F,0x40,0xB2,0x40,0xCC, + 0x40,0x92,0x40,0xE9,0xC0,0x84,0x40,0x88,0x40,0x84,0x40,0xFF,0xC0}; const u8g_fntpgm_uint8_t fontpage_174_168_168[45] U8G_FONT_SECTION("fontpage_174_168_168") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa8,0xa8,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x08,0x00,0x08,0x00,0xff,0xc0,0x10,0x00,0x22, - 0x00,0x62,0x00,0xaf,0x80,0x22,0x00,0x22,0x00,0x22,0x00,0x3f,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA8,0xA8,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x08,0x00,0x08,0x00,0xFF,0xC0,0x10,0x00,0x22, + 0x00,0x62,0x00,0xAF,0x80,0x22,0x00,0x22,0x00,0x22,0x00,0x3F,0xC0}; +const u8g_fntpgm_uint8_t fontpage_174_207_207[45] U8G_FONT_SECTION("fontpage_174_207_207") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCF,0xCF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x00,0x2F,0xE0,0x20,0x80,0xF8,0x80,0x21, + 0x00,0x21,0x80,0x23,0x40,0x35,0x20,0xC9,0x20,0x01,0x00,0x01,0x00}; const u8g_fntpgm_uint8_t fontpage_174_215_215[45] U8G_FONT_SECTION("fontpage_174_215_215") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd7,0xd7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x21,0x00,0x27,0xc0,0xf9,0x40,0x21, - 0x40,0x21,0x40,0x2f,0xe0,0x31,0x00,0xc2,0x80,0x04,0x40,0x18,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD7,0xD7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x21,0x00,0x27,0xC0,0xF9,0x40,0x21, + 0x40,0x21,0x40,0x2F,0xE0,0x31,0x00,0xC2,0x80,0x04,0x40,0x18,0x20}; const u8g_fntpgm_uint8_t fontpage_175_139_139[45] U8G_FONT_SECTION("fontpage_175_139_139") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8b,0x8b,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x7e,0x40,0x29,0x40,0x29,0x40,0xff,0x40,0x29, - 0x40,0x28,0x40,0x4c,0xc0,0x04,0x00,0x3f,0x80,0x04,0x00,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8B,0x8B,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7E,0x40,0x29,0x40,0x29,0x40,0xFF,0x40,0x29, + 0x40,0x28,0x40,0x4C,0xC0,0x04,0x00,0x3F,0x80,0x04,0x00,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_175_171_171[45] U8G_FONT_SECTION("fontpage_175_171_171") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xab,0xab,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x00,0xff,0x80,0x22,0x80,0x36,0xa0,0xe3, - 0xa0,0x2c,0xe0,0x64,0x00,0x04,0x00,0x3f,0xc0,0x04,0x00,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAB,0xAB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0xFF,0x80,0x22,0x80,0x36,0xA0,0xE3, + 0xA0,0x2C,0xE0,0x64,0x00,0x04,0x00,0x3F,0xC0,0x04,0x00,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_176_235_235[45] U8G_FONT_SECTION("fontpage_176_235_235") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xeb,0xeb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x2f,0xe0,0x21,0x00,0xf7,0xc0,0x24, - 0x40,0x27,0x40,0x25,0xc0,0x34,0x40,0xef,0xe0,0x02,0x80,0x0c,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xEB,0xEB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x2F,0xE0,0x21,0x00,0xF7,0xC0,0x24, + 0x40,0x27,0x40,0x25,0xC0,0x34,0x40,0xEF,0xE0,0x02,0x80,0x0C,0x60}; const u8g_fntpgm_uint8_t fontpage_177_243_243[45] U8G_FONT_SECTION("fontpage_177_243_243") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf3,0xf3,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0xff,0xe0,0x04,0x00,0x3f,0xc0,0x00, - 0x00,0xff,0xe0,0x80,0x20,0x1f,0x00,0x11,0x20,0x21,0x20,0xc0,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF3,0xF3,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0xFF,0xE0,0x04,0x00,0x3F,0xC0,0x00, + 0x00,0xFF,0xE0,0x80,0x20,0x1F,0x00,0x11,0x20,0x21,0x20,0xC0,0xE0}; const u8g_fntpgm_uint8_t fontpage_178_135_135[45] U8G_FONT_SECTION("fontpage_178_135_135") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x87,0x87,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x10,0x00,0x1f,0x80,0x31,0x00,0x4e,0x00,0x0b, - 0x00,0x30,0xe0,0xff,0x80,0x24,0x80,0x3f,0x80,0x24,0x80,0x3f,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x87,0x87,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x10,0x00,0x1F,0x80,0x31,0x00,0x4E,0x00,0x0B, + 0x00,0x30,0xE0,0xFF,0x80,0x24,0x80,0x3F,0x80,0x24,0x80,0x3F,0x80}; const u8g_fntpgm_uint8_t fontpage_178_141_141[45] U8G_FONT_SECTION("fontpage_178_141_141") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8d,0x8d,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x00,0x3f,0xe0,0x60,0x80,0xbf,0x80,0x20, - 0x80,0x3f,0x80,0x10,0x00,0x3f,0x80,0xc9,0x00,0x06,0x00,0xf9,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8D,0x8D,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x00,0x3F,0xE0,0x60,0x80,0xBF,0x80,0x20, + 0x80,0x3F,0x80,0x10,0x00,0x3F,0x80,0xC9,0x00,0x06,0x00,0xF9,0xE0}; const u8g_fntpgm_uint8_t fontpage_178_150_150[45] U8G_FONT_SECTION("fontpage_178_150_150") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x96,0x96,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x21,0x00,0x3d,0x00,0x25,0x00,0x45, - 0x80,0xa5,0x40,0x19,0x20,0x09,0x00,0x11,0x00,0x21,0x00,0x41,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x96,0x96,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x21,0x00,0x3D,0x00,0x25,0x00,0x45, + 0x80,0xA5,0x40,0x19,0x20,0x09,0x00,0x11,0x00,0x21,0x00,0x41,0x00}; const u8g_fntpgm_uint8_t fontpage_178_154_154[45] U8G_FONT_SECTION("fontpage_178_154_154") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9a,0x9a,0x00,0x0a,0xff,0x00, - 0x00,0x09,0x0b,0x16,0x0c,0x01,0xff,0x08,0x00,0x1f,0x00,0x21,0x00,0x52,0x00,0x0c, - 0x00,0x34,0x00,0xcf,0x80,0x10,0x80,0x69,0x00,0x06,0x00,0xf8,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9A,0x9A,0x00,0x0A,0xFF,0x00, + 0x00,0x09,0x0B,0x16,0x0C,0x01,0xFF,0x08,0x00,0x1F,0x00,0x21,0x00,0x52,0x00,0x0C, + 0x00,0x34,0x00,0xCF,0x80,0x10,0x80,0x69,0x00,0x06,0x00,0xF8,0x00}; const u8g_fntpgm_uint8_t fontpage_178_167_167[45] U8G_FONT_SECTION("fontpage_178_167_167") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa7,0xa7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x04,0x00,0x04,0x00,0xff,0xe0,0x04, - 0x00,0x04,0x00,0x0a,0x00,0x0a,0x00,0x11,0x00,0x20,0x80,0xc0,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA7,0xA7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x04,0x00,0x04,0x00,0xFF,0xE0,0x04, + 0x00,0x04,0x00,0x0A,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0xC0,0x60}; const u8g_fntpgm_uint8_t fontpage_178_169_170[73] U8G_FONT_SECTION("fontpage_178_169_170") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa9,0xaa,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x7f,0xc0,0x04,0x00,0x04,0x00,0x04,0x00,0xff, - 0xe0,0x04,0x00,0x0a,0x00,0x0a,0x00,0x11,0x00,0x20,0x80,0xc0,0x60,0x0b,0x0b,0x16, - 0x0c,0x00,0xff,0x04,0x00,0x04,0x00,0x04,0x00,0xff,0xe0,0x04,0x00,0x0a,0x00,0x0a, - 0x00,0x11,0x00,0x19,0x00,0x24,0x80,0xc4,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA9,0xAA,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0xC0,0x04,0x00,0x04,0x00,0x04,0x00,0xFF, + 0xE0,0x04,0x00,0x0A,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0xC0,0x60,0x0B,0x0B,0x16, + 0x0C,0x00,0xFF,0x04,0x00,0x04,0x00,0x04,0x00,0xFF,0xE0,0x04,0x00,0x0A,0x00,0x0A, + 0x00,0x11,0x00,0x19,0x00,0x24,0x80,0xC4,0x60}; const u8g_fntpgm_uint8_t fontpage_178_177_177[45] U8G_FONT_SECTION("fontpage_178_177_177") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb1,0xb1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x24,0x00,0x24,0x00,0x3f,0xc0,0x44,0x00,0x04, - 0x00,0xff,0xe0,0x04,0x00,0x0a,0x00,0x11,0x00,0x20,0x80,0xc0,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB1,0xB1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x24,0x00,0x24,0x00,0x3F,0xC0,0x44,0x00,0x04, + 0x00,0xFF,0xE0,0x04,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0xC0,0x60}; +const u8g_fntpgm_uint8_t fontpage_178_180_180[45] U8G_FONT_SECTION("fontpage_178_180_180") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB4,0xB4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x12,0x00,0x0A,0x00,0x22,0x00,0x12,0x00,0x02, + 0x00,0xFF,0xE0,0x02,0x00,0x05,0x00,0x08,0x80,0x10,0x40,0x60,0x20}; +const u8g_fntpgm_uint8_t fontpage_178_253_253[45] U8G_FONT_SECTION("fontpage_178_253_253") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFD,0xFD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x00,0x23,0xE0,0xF8,0x40,0x28,0x80,0x28, + 0x80,0x4F,0xE0,0x50,0x80,0x30,0x80,0x28,0x80,0x48,0x80,0x83,0x80}; const u8g_fntpgm_uint8_t fontpage_179_203_203[45] U8G_FONT_SECTION("fontpage_179_203_203") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcb,0xcb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x21,0x00,0xfa,0x40,0x2a,0x20,0x2f, - 0xe0,0x48,0x00,0x53,0xe0,0x32,0x20,0x2a,0x20,0x4b,0xe0,0x82,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCB,0xCB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x21,0x00,0xFA,0x40,0x2A,0x20,0x2F, + 0xE0,0x48,0x00,0x53,0xE0,0x32,0x20,0x2A,0x20,0x4B,0xE0,0x82,0x20}; const u8g_fntpgm_uint8_t fontpage_182_208_208[45] U8G_FONT_SECTION("fontpage_182_208_208") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd0,0xd0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x3f,0x80,0x01,0x00,0x02,0x00,0x04,0x00,0x04, - 0x00,0xff,0xe0,0x04,0x00,0x04,0x00,0x04,0x00,0x14,0x00,0x08,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD0,0xD0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x3F,0x80,0x01,0x00,0x02,0x00,0x04,0x00,0x04, + 0x00,0xFF,0xE0,0x04,0x00,0x04,0x00,0x04,0x00,0x14,0x00,0x08,0x00}; const u8g_fntpgm_uint8_t fontpage_182_216_216[45] U8G_FONT_SECTION("fontpage_182_216_216") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd8,0xd8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x08,0x00,0xff,0xe0,0x10,0x00,0x2f,0xc0,0x20, - 0x80,0x61,0x00,0xbf,0xe0,0x21,0x00,0x21,0x00,0x21,0x00,0x27,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD8,0xD8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x08,0x00,0xFF,0xE0,0x10,0x00,0x2F,0xC0,0x20, + 0x80,0x61,0x00,0xBF,0xE0,0x21,0x00,0x21,0x00,0x21,0x00,0x27,0x00}; const u8g_fntpgm_uint8_t fontpage_183_137_137[45] U8G_FONT_SECTION("fontpage_183_137_137") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x7f,0xe0,0x40,0x20,0x88,0x40,0x08, - 0x00,0xff,0xe0,0x11,0x00,0x31,0x00,0x0e,0x00,0x09,0x80,0x70,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x7F,0xE0,0x40,0x20,0x88,0x40,0x08, + 0x00,0xFF,0xE0,0x11,0x00,0x31,0x00,0x0E,0x00,0x09,0x80,0x70,0x60}; const u8g_fntpgm_uint8_t fontpage_183_140_140[45] U8G_FONT_SECTION("fontpage_183_140_140") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8c,0x8c,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x7f,0xe0,0x40,0x20,0x9f,0x40,0x00, - 0x00,0x7f,0xe0,0x0a,0x00,0x12,0x00,0x12,0x20,0x22,0x20,0x41,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8C,0x8C,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x7F,0xE0,0x40,0x20,0x9F,0x40,0x00, + 0x00,0x7F,0xE0,0x0A,0x00,0x12,0x00,0x12,0x20,0x22,0x20,0x41,0xE0}; const u8g_fntpgm_uint8_t fontpage_183_154_154[45] U8G_FONT_SECTION("fontpage_183_154_154") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9a,0x9a,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x7f,0xe0,0x40,0x20,0x80,0x40,0x3f, - 0xc0,0x04,0x00,0x24,0x00,0x27,0x80,0x24,0x00,0x54,0x00,0x8f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9A,0x9A,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x7F,0xE0,0x40,0x20,0x80,0x40,0x3F, + 0xC0,0x04,0x00,0x24,0x00,0x27,0x80,0x24,0x00,0x54,0x00,0x8F,0xE0}; const u8g_fntpgm_uint8_t fontpage_183_162_162[45] U8G_FONT_SECTION("fontpage_183_162_162") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa2,0xa2,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x08,0x00,0xff,0xc0,0x90,0x40,0x3f,0x00,0x52, - 0x00,0x8c,0x00,0x33,0x00,0xff,0xc0,0x21,0x00,0x21,0x00,0x3f,0x00}; -const u8g_fntpgm_uint8_t fontpage_183_185_185[45] U8G_FONT_SECTION("fontpage_183_185_185") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb9,0xb9,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0xff,0xe0,0x91,0x20,0x24,0x80,0x4a, - 0x40,0x11,0x00,0x20,0x80,0xdf,0x60,0x11,0x00,0x11,0x00,0x1f,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA2,0xA2,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x08,0x00,0xFF,0xC0,0x90,0x40,0x3F,0x00,0x52, + 0x00,0x8C,0x00,0x33,0x00,0xFF,0xC0,0x21,0x00,0x21,0x00,0x3F,0x00}; +const u8g_fntpgm_uint8_t fontpage_183_171_171[45] U8G_FONT_SECTION("fontpage_183_171_171") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAB,0xAB,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x08,0x00,0xFF,0xC0,0x80,0x40,0x3F,0x00,0x21, + 0x00,0x3F,0x00,0x00,0x00,0x7F,0x80,0x40,0x80,0x7F,0x80,0x40,0x80}; const u8g_fntpgm_uint8_t fontpage_183_249_249[45] U8G_FONT_SECTION("fontpage_183_249_249") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf9,0xf9,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x00,0x80,0xf0,0x80,0x1f,0xe0,0x90,0x80,0x50, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF9,0xF9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x00,0x80,0xF0,0x80,0x1F,0xE0,0x90,0x80,0x50, 0x80,0x24,0x80,0x22,0x80,0x50,0x80,0x50,0x80,0x82,0x80,0x01,0x00}; +const u8g_fntpgm_uint8_t fontpage_184_134_134[45] U8G_FONT_SECTION("fontpage_184_134_134") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x86,0x86,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0x27,0xC0,0xA4,0x80,0x6B,0x00,0x22, + 0x80,0x24,0x80,0x6F,0xE0,0xA4,0x80,0x22,0x80,0x20,0x80,0x21,0x80}; const u8g_fntpgm_uint8_t fontpage_184_143_143[45] U8G_FONT_SECTION("fontpage_184_143_143") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8f,0x8f,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x04,0x00,0x04,0x00,0x24,0x80,0x24, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8F,0x8F,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x04,0x00,0x04,0x00,0x24,0x80,0x24, 0x40,0x44,0x40,0x44,0x20,0x84,0x20,0x04,0x00,0x14,0x00,0x08,0x00}; const u8g_fntpgm_uint8_t fontpage_184_177_177[45] U8G_FONT_SECTION("fontpage_184_177_177") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb1,0xb1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0xfd,0x40,0x01,0x20,0x7f,0xe0,0x4a, - 0x80,0x7a,0x80,0x12,0x80,0x5a,0xa0,0x56,0xa0,0x92,0xa0,0x34,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB1,0xB1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0xFD,0x40,0x01,0x20,0x7F,0xE0,0x4A, + 0x80,0x7A,0x80,0x12,0x80,0x5A,0xA0,0x56,0xA0,0x92,0xA0,0x34,0x60}; const u8g_fntpgm_uint8_t fontpage_184_207_207[45] U8G_FONT_SECTION("fontpage_184_207_207") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcf,0xcf,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x3f,0xe0,0x20,0x20,0x3f,0xe0,0x28,0x40,0x24, - 0x80,0x3f,0xe0,0x24,0x80,0x3f,0xe0,0x24,0x80,0x48,0x80,0x90,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCF,0xCF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x3F,0xE0,0x20,0x20,0x3F,0xE0,0x28,0x40,0x24, + 0x80,0x3F,0xE0,0x24,0x80,0x3F,0xE0,0x24,0x80,0x48,0x80,0x90,0x80}; const u8g_fntpgm_uint8_t fontpage_187_229_229[41] U8G_FONT_SECTION("fontpage_187_229_229") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe5,0xe5,0x00,0x09,0x00,0x00, - 0x00,0x0b,0x09,0x12,0x0c,0x00,0x00,0x7f,0xc0,0x04,0x00,0x04,0x00,0x04,0x00,0x04, - 0x00,0x04,0x00,0x04,0x00,0x04,0x00,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE5,0xE5,0x00,0x09,0x00,0x00, + 0x00,0x0B,0x09,0x12,0x0C,0x00,0x00,0x7F,0xC0,0x04,0x00,0x04,0x00,0x04,0x00,0x04, + 0x00,0x04,0x00,0x04,0x00,0x04,0x00,0xFF,0xE0}; +const u8g_fntpgm_uint8_t fontpage_187_238_238[45] U8G_FONT_SECTION("fontpage_187_238_238") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xEE,0xEE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x10,0x80,0x09,0x00,0xFF,0xE0,0x04,0x00,0x7F, + 0xC0,0x08,0x00,0xFF,0xE0,0x10,0x00,0x2F,0x80,0x42,0x00,0xBF,0xE0}; const u8g_fntpgm_uint8_t fontpage_187_242_242[43] U8G_FONT_SECTION("fontpage_187_242_242") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf2,0xf2,0x00,0x09,0xff,0x00, - 0x00,0x0a,0x0a,0x14,0x0c,0x01,0xff,0xff,0x00,0x01,0x00,0x01,0x00,0x81,0x00,0xff, - 0x00,0x80,0x00,0x80,0x40,0x80,0x40,0x80,0x40,0x7f,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF2,0xF2,0x00,0x09,0xFF,0x00, + 0x00,0x0A,0x0A,0x14,0x0C,0x01,0xFF,0xFF,0x00,0x01,0x00,0x01,0x00,0x81,0x00,0xFF, + 0x00,0x80,0x00,0x80,0x40,0x80,0x40,0x80,0x40,0x7F,0xC0}; const u8g_fntpgm_uint8_t fontpage_188_243_243[45] U8G_FONT_SECTION("fontpage_188_243_243") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf3,0xf3,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x7f,0xc0,0x04,0x00,0x24,0x80,0x15,0x00,0x04, - 0x00,0xff,0xe0,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF3,0xF3,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0xC0,0x04,0x00,0x24,0x80,0x15,0x00,0x04, + 0x00,0xFF,0xE0,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00}; const u8g_fntpgm_uint8_t fontpage_188_246_246[45] U8G_FONT_SECTION("fontpage_188_246_246") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf6,0xf6,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x80,0x11,0x00,0x7f,0xc0,0x11,0x00,0x11, - 0x00,0x11,0x00,0xff,0xe0,0x11,0x00,0x11,0x00,0x21,0x00,0x41,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF6,0xF6,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x80,0x11,0x00,0x7F,0xC0,0x11,0x00,0x11, + 0x00,0x11,0x00,0xFF,0xE0,0x11,0x00,0x11,0x00,0x21,0x00,0x41,0x00}; const u8g_fntpgm_uint8_t fontpage_189_138_138[45] U8G_FONT_SECTION("fontpage_189_138_138") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8a,0x8a,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x02,0x00,0x7f,0xe0,0x42,0x00,0x42,0x00,0x7f, - 0xe0,0x42,0x00,0x47,0x00,0x4a,0x80,0x52,0x40,0xa2,0x20,0x82,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8A,0x8A,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x02,0x00,0x7F,0xE0,0x42,0x00,0x42,0x00,0x7F, + 0xE0,0x42,0x00,0x47,0x00,0x4A,0x80,0x52,0x40,0xA2,0x20,0x82,0x00}; const u8g_fntpgm_uint8_t fontpage_189_148_148[45] U8G_FONT_SECTION("fontpage_189_148_148") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x94,0x94,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x02,0x00,0x7f,0xe0,0x40,0x00,0x44, - 0x40,0x52,0x40,0x4a,0x40,0x48,0x80,0x40,0x80,0x81,0x00,0x9f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x94,0x94,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x02,0x00,0x7F,0xE0,0x40,0x00,0x44, + 0x40,0x52,0x40,0x4A,0x40,0x48,0x80,0x40,0x80,0x81,0x00,0x9F,0xE0}; const u8g_fntpgm_uint8_t fontpage_189_159_159[45] U8G_FONT_SECTION("fontpage_189_159_159") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9f,0x9f,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x02,0x00,0x3f,0xe0,0x2a,0x80,0x2a,0x40,0x3f, - 0xe0,0x24,0x00,0x27,0xc0,0x2a,0x40,0x31,0x80,0x42,0x40,0x8c,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9F,0x9F,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x02,0x00,0x3F,0xE0,0x2A,0x80,0x2A,0x40,0x3F, + 0xE0,0x24,0x00,0x27,0xC0,0x2A,0x40,0x31,0x80,0x42,0x40,0x8C,0x20}; const u8g_fntpgm_uint8_t fontpage_189_166_166[45] U8G_FONT_SECTION("fontpage_189_166_166") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa6,0xa6,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x7f,0xe0,0x49,0x00,0x7f,0xc0,0x49, - 0x00,0x4f,0x00,0x40,0x00,0x5f,0x80,0x49,0x00,0x86,0x00,0xb9,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA6,0xA6,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x7F,0xE0,0x49,0x00,0x7F,0xC0,0x49, + 0x00,0x4F,0x00,0x40,0x00,0x5F,0x80,0x49,0x00,0x86,0x00,0xB9,0xC0}; const u8g_fntpgm_uint8_t fontpage_190_128_128[45] U8G_FONT_SECTION("fontpage_190_128_128") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x7f,0xc0,0x11,0x00,0x11,0x00,0x11,0x00,0x11, - 0x00,0xff,0xe0,0x11,0x00,0x21,0x00,0x21,0x00,0x41,0x00,0x81,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0xC0,0x11,0x00,0x11,0x00,0x11,0x00,0x11, + 0x00,0xFF,0xE0,0x11,0x00,0x21,0x00,0x21,0x00,0x41,0x00,0x81,0x00}; +const u8g_fntpgm_uint8_t fontpage_190_131_131[45] U8G_FONT_SECTION("fontpage_190_131_131") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x83,0x83,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0xFF,0xE0,0x08,0x00,0x10,0x80,0x3F, + 0xC0,0x11,0x00,0xFF,0xE0,0x11,0x00,0x11,0x00,0x21,0x00,0x41,0x00}; +const u8g_fntpgm_uint8_t fontpage_190_143_143[45] U8G_FONT_SECTION("fontpage_190_143_143") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8F,0x8F,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x02,0x80,0x02,0x40,0x02,0x00,0xFF,0xE0,0x02, + 0x00,0x7A,0x00,0x12,0x00,0x11,0x00,0x11,0x20,0x18,0xA0,0xE0,0x60}; +const u8g_fntpgm_uint8_t fontpage_190_149_149[45] U8G_FONT_SECTION("fontpage_190_149_149") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x95,0x95,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0xFC,0x40,0x04,0x40,0x04,0x40,0x7C,0x40,0x40, + 0x40,0xFC,0x40,0x04,0x40,0x04,0x40,0x04,0x40,0x28,0x40,0x10,0x40}; +const u8g_fntpgm_uint8_t fontpage_190_185_185[45] U8G_FONT_SECTION("fontpage_190_185_185") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB9,0xB9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xE4,0x40,0x22,0x80,0x2F,0xE0,0xE9,0x20,0x8F, + 0xE0,0x89,0x20,0xEF,0xE0,0x21,0x00,0x2F,0xE0,0xA1,0x00,0x41,0x00}; const u8g_fntpgm_uint8_t fontpage_190_210_210[45] U8G_FONT_SECTION("fontpage_190_210_210") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd2,0xd2,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x10,0x00,0x17,0xc0,0x90,0x40,0x90,0x40,0x90, - 0x40,0x97,0xc0,0x90,0x40,0x90,0x40,0x20,0x40,0x4f,0xc0,0x80,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD2,0xD2,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x10,0x00,0x17,0xC0,0x90,0x40,0x90,0x40,0x90, + 0x40,0x97,0xC0,0x90,0x40,0x90,0x40,0x20,0x40,0x4F,0xC0,0x80,0x40}; const u8g_fntpgm_uint8_t fontpage_191_132_133[73] U8G_FONT_SECTION("fontpage_191_132_133") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x84,0x85,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x17,0xc0,0x20,0x80,0x49,0x00,0x92,0x80,0x24, - 0x40,0x68,0x20,0xa7,0xc0,0x21,0x00,0x21,0x00,0x21,0x00,0x2f,0xe0,0x0b,0x0b,0x16, - 0x0c,0x00,0xff,0x11,0x00,0x21,0x00,0x47,0xc0,0x91,0x00,0x1f,0xe0,0x20,0x80,0x6f, - 0xe0,0xa4,0x80,0x22,0x80,0x20,0x80,0x21,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x84,0x85,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x17,0xC0,0x20,0x80,0x49,0x00,0x92,0x80,0x24, + 0x40,0x68,0x20,0xA7,0xC0,0x21,0x00,0x21,0x00,0x21,0x00,0x2F,0xE0,0x0B,0x0B,0x16, + 0x0C,0x00,0xFF,0x11,0x00,0x21,0x00,0x47,0xC0,0x91,0x00,0x1F,0xE0,0x20,0x80,0x6F, + 0xE0,0xA4,0x80,0x22,0x80,0x20,0x80,0x21,0x80}; +const u8g_fntpgm_uint8_t fontpage_191_170_170[45] U8G_FONT_SECTION("fontpage_191_170_170") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAA,0xAA,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x1F,0xE0,0x28,0x80,0x4F,0xE0,0x98,0x80,0x2B, + 0xE0,0x6A,0x20,0xAB,0xE0,0x2A,0x20,0x2B,0xE0,0x2A,0x20,0x33,0xE0}; const u8g_fntpgm_uint8_t fontpage_191_174_174[45] U8G_FONT_SECTION("fontpage_191_174_174") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xae,0xae,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x2a,0x80,0x6a,0x80,0xbe,0x80,0x01,0xe0,0x5d, - 0x40,0xc3,0x40,0x5d,0x40,0x54,0x80,0x56,0x80,0x55,0x40,0x62,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAE,0xAE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x2A,0x80,0x6A,0x80,0xBE,0x80,0x01,0xE0,0x5D, + 0x40,0xC3,0x40,0x5D,0x40,0x54,0x80,0x56,0x80,0x55,0x40,0x62,0x20}; const u8g_fntpgm_uint8_t fontpage_191_195_195[45] U8G_FONT_SECTION("fontpage_191_195_195") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc3,0xc3,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x02,0x00,0x12,0x00,0x12,0x00,0x10, - 0x40,0x50,0x20,0x50,0x20,0x50,0xa0,0x90,0x80,0x10,0x80,0x0f,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC3,0xC3,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x02,0x00,0x12,0x00,0x12,0x00,0x10, + 0x40,0x50,0x20,0x50,0x20,0x50,0xA0,0x90,0x80,0x10,0x80,0x0F,0x80}; +const u8g_fntpgm_uint8_t fontpage_191_253_253[45] U8G_FONT_SECTION("fontpage_191_253_253") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFD,0xFD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x00,0x3F,0xC0,0x2A,0x40,0x4A,0x40,0x14, + 0x40,0x28,0x40,0x05,0x80,0x12,0x40,0x50,0xA0,0x50,0xA0,0x8F,0x80}; const u8g_fntpgm_uint8_t fontpage_192_167_167[45] U8G_FONT_SECTION("fontpage_192_167_167") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa7,0xa7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x25,0x00,0xb5,0x00,0xaf,0xe0,0xa9, - 0x00,0xb1,0x00,0x27,0xc0,0x21,0x00,0x21,0x00,0x21,0x00,0x2f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA7,0xA7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x25,0x00,0xB5,0x00,0xAF,0xE0,0xA9, + 0x00,0xB1,0x00,0x27,0xC0,0x21,0x00,0x21,0x00,0x21,0x00,0x2F,0xE0}; const u8g_fntpgm_uint8_t fontpage_192_187_187[45] U8G_FONT_SECTION("fontpage_192_187_187") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbb,0xbb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0x0a,0x00,0x3f,0x80,0x20,0x80,0x20, - 0x80,0x3f,0x80,0x20,0x80,0x04,0x40,0x52,0xa0,0x50,0xa0,0x8f,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBB,0xBB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x0A,0x00,0x3F,0x80,0x20,0x80,0x20, + 0x80,0x3F,0x80,0x20,0x80,0x04,0x40,0x52,0xA0,0x50,0xA0,0x8F,0x80}; const u8g_fntpgm_uint8_t fontpage_192_226_226[45] U8G_FONT_SECTION("fontpage_192_226_226") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe2,0xe2,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x00,0x2f,0xe0,0xb2,0x00,0xaa,0x80,0xa4, - 0x80,0xa5,0xa0,0x2a,0xc0,0x30,0x80,0x21,0x40,0x22,0x40,0x24,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE2,0xE2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0x2F,0xE0,0xB2,0x00,0xAA,0x80,0xA4, + 0x80,0xA5,0xA0,0x2A,0xC0,0x30,0x80,0x21,0x40,0x22,0x40,0x24,0x20}; const u8g_fntpgm_uint8_t fontpage_192_239_239[45] U8G_FONT_SECTION("fontpage_192_239_239") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xef,0xef,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x08,0x00,0x3f,0x80,0x20,0x80,0x3f,0x80,0x20, - 0x80,0x3f,0x80,0x20,0x80,0x3f,0x80,0x54,0x40,0x52,0xa0,0x8f,0x80}; -const u8g_fntpgm_uint8_t fontpage_196_144_144[45] U8G_FONT_SECTION("fontpage_196_144_144") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x90,0x90,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x02,0x80,0x02,0x40,0x7f,0xe0,0x42,0x00,0x42, - 0x00,0x7a,0x40,0x4a,0x40,0x4a,0x80,0x49,0x20,0x52,0xa0,0x84,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xEF,0xEF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x08,0x00,0x3F,0x80,0x20,0x80,0x3F,0x80,0x20, + 0x80,0x3F,0x80,0x20,0x80,0x3F,0x80,0x54,0x40,0x52,0xA0,0x8F,0x80}; +const u8g_fntpgm_uint8_t fontpage_194_159_159[45] U8G_FONT_SECTION("fontpage_194_159_159") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9F,0x9F,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x01,0x40,0x7F,0xE0,0x41,0x00,0x7F,0x40,0x5D, + 0x40,0x52,0x80,0x9D,0xA0,0x82,0x60,0x24,0x40,0xA2,0xA0,0x9F,0x80}; +const u8g_fntpgm_uint8_t fontpage_196_143_144[73] U8G_FONT_SECTION("fontpage_196_143_144") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8F,0x90,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x02,0x80,0x7A,0x40,0x0A,0x00,0x4F,0xE0,0x2A, + 0x00,0x12,0x40,0x12,0x80,0x29,0x00,0x41,0x20,0x86,0xA0,0x00,0x60,0x0B,0x0B,0x16, + 0x0C,0x00,0xFF,0x02,0x80,0x02,0x40,0x7F,0xE0,0x42,0x00,0x42,0x00,0x7A,0x40,0x4A, + 0x40,0x4A,0x80,0x49,0x20,0x52,0xA0,0x84,0x60}; const u8g_fntpgm_uint8_t fontpage_196_183_183[45] U8G_FONT_SECTION("fontpage_196_183_183") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb7,0xb7,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x02,0x00,0x3f,0xc0,0x20,0x40,0x20, - 0x40,0x3f,0xc0,0x20,0x00,0x20,0x00,0x20,0x00,0x40,0x00,0x80,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB7,0xB7,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x02,0x00,0x3F,0xC0,0x20,0x40,0x20, + 0x40,0x3F,0xC0,0x20,0x00,0x20,0x00,0x20,0x00,0x40,0x00,0x80,0x00}; const u8g_fntpgm_uint8_t fontpage_196_192_192[45] U8G_FONT_SECTION("fontpage_196_192_192") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc0,0xc0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x18,0x60,0x63,0x80,0x42,0x00,0x7a,0x00,0x4b, - 0xe0,0x4a,0x40,0x7a,0x40,0x42,0x40,0x42,0x40,0x44,0x40,0x88,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x18,0x60,0x63,0x80,0x42,0x00,0x7A,0x00,0x4B, + 0xE0,0x4A,0x40,0x7A,0x40,0x42,0x40,0x42,0x40,0x44,0x40,0x88,0x40}; const u8g_fntpgm_uint8_t fontpage_196_199_199[45] U8G_FONT_SECTION("fontpage_196_199_199") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc7,0xc7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x7f,0xe0,0x40,0x20,0x7f,0xe0,0x40, - 0x00,0x7d,0xe0,0x44,0x20,0x54,0xa0,0x4c,0x60,0x54,0xa0,0xa9,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC7,0xC7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x7F,0xE0,0x40,0x20,0x7F,0xE0,0x40, + 0x00,0x7D,0xE0,0x44,0x20,0x54,0xA0,0x4C,0x60,0x54,0xA0,0xA9,0x60}; const u8g_fntpgm_uint8_t fontpage_196_203_203[45] U8G_FONT_SECTION("fontpage_196_203_203") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcb,0xcb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x03,0xc0,0x7c,0x00,0x04,0x00,0x7f,0xc0,0x04, - 0x00,0x04,0x00,0xff,0xe0,0x04,0x00,0x04,0x00,0x04,0x00,0x0c,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCB,0xCB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x03,0xC0,0x7C,0x00,0x04,0x00,0x7F,0xC0,0x04, + 0x00,0x04,0x00,0xFF,0xE0,0x04,0x00,0x04,0x00,0x04,0x00,0x0C,0x00}; const u8g_fntpgm_uint8_t fontpage_196_211_211[45] U8G_FONT_SECTION("fontpage_196_211_211") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd3,0xd3,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x00,0x27,0xe0,0xf8,0x80,0x20,0x80,0x28, - 0x80,0x30,0x80,0x60,0x80,0xa0,0x80,0x20,0x80,0x20,0x80,0xe3,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD3,0xD3,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x00,0x27,0xE0,0xF8,0x80,0x20,0x80,0x28, + 0x80,0x30,0x80,0x60,0x80,0xA0,0x80,0x20,0x80,0x20,0x80,0xE3,0x80}; const u8g_fntpgm_uint8_t fontpage_196_231_231[45] U8G_FONT_SECTION("fontpage_196_231_231") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe7,0xe7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x00,0x22,0x00,0xff,0x80,0x22,0x80,0x2a, - 0x80,0x36,0x80,0x62,0x80,0xa7,0xa0,0x24,0xa0,0xa8,0xa0,0x50,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE7,0xE7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0x22,0x00,0xFF,0x80,0x22,0x80,0x2A, + 0x80,0x36,0x80,0x62,0x80,0xA7,0xA0,0x24,0xA0,0xA8,0xA0,0x50,0x60}; const u8g_fntpgm_uint8_t fontpage_196_249_249[45] U8G_FONT_SECTION("fontpage_196_249_249") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf9,0xf9,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x24,0x80,0x24,0x80,0xfc,0x80,0x24,0xa0,0x2f, - 0xc0,0x34,0x80,0x64,0x80,0xa4,0x80,0x25,0xa0,0x26,0xa0,0xe4,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF9,0xF9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x24,0x80,0x24,0x80,0xFC,0x80,0x24,0xA0,0x2F, + 0xC0,0x34,0x80,0x64,0x80,0xA4,0x80,0x25,0xA0,0x26,0xA0,0xE4,0x60}; const u8g_fntpgm_uint8_t fontpage_197_150_150[45] U8G_FONT_SECTION("fontpage_197_150_150") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x96,0x96,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x40,0x22,0x40,0xf9,0x40,0x20,0x40,0x2a, - 0x40,0x31,0x40,0x60,0xe0,0xaf,0x40,0x20,0x40,0x20,0x40,0xe0,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x96,0x96,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x40,0x22,0x40,0xF9,0x40,0x20,0x40,0x2A, + 0x40,0x31,0x40,0x60,0xE0,0xAF,0x40,0x20,0x40,0x20,0x40,0xE0,0x40}; +const u8g_fntpgm_uint8_t fontpage_197_165_165[45] U8G_FONT_SECTION("fontpage_197_165_165") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA5,0xA5,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x27,0xC0,0x24,0x40,0xFC,0x40,0x25,0x80,0x2C, + 0x00,0x37,0xE0,0x65,0x40,0xA5,0x40,0x24,0x80,0x25,0x40,0xE6,0x20}; +const u8g_fntpgm_uint8_t fontpage_197_172_172[45] U8G_FONT_SECTION("fontpage_197_172_172") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAC,0xAC,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x21,0x00,0xFA,0x40,0x27,0xA0,0x28, + 0x20,0x30,0x00,0x67,0xE0,0xA4,0x20,0x24,0x20,0x27,0xE0,0xE4,0x20}; const u8g_fntpgm_uint8_t fontpage_197_189_189[45] U8G_FONT_SECTION("fontpage_197_189_189") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbd,0xbd,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x80,0x20,0x80,0xf8,0x80,0x27,0xe0,0x2c, - 0xa0,0x34,0xa0,0x67,0xe0,0xa4,0xa0,0x24,0xa0,0x27,0xe0,0xe4,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBD,0xBD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x80,0x20,0x80,0xF8,0x80,0x27,0xE0,0x2C, + 0xA0,0x34,0xA0,0x67,0xE0,0xA4,0xA0,0x24,0xA0,0x27,0xE0,0xE4,0x20}; const u8g_fntpgm_uint8_t fontpage_197_212_212[45] U8G_FONT_SECTION("fontpage_197_212_212") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd4,0xd4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x80,0x22,0x40,0xff,0xe0,0x22,0x00,0x2b, - 0xc0,0x32,0x40,0x65,0x40,0xa4,0x80,0x28,0x80,0x29,0x40,0xe6,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD4,0xD4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x80,0x22,0x40,0xFF,0xE0,0x22,0x00,0x2B, + 0xC0,0x32,0x40,0x65,0x40,0xA4,0x80,0x28,0x80,0x29,0x40,0xE6,0x20}; const u8g_fntpgm_uint8_t fontpage_197_233_233[45] U8G_FONT_SECTION("fontpage_197_233_233") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe9,0xe9,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x2f,0xe0,0x22,0x40,0xf9,0x80,0x22,0x40,0x2c, - 0x20,0x31,0x00,0x67,0xc0,0xa1,0x00,0x2f,0xe0,0x21,0x00,0xe1,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE9,0xE9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x2F,0xE0,0x22,0x40,0xF9,0x80,0x22,0x40,0x2C, + 0x20,0x31,0x00,0x67,0xC0,0xA1,0x00,0x2F,0xE0,0x21,0x00,0xE1,0x00}; const u8g_fntpgm_uint8_t fontpage_198_137_137[45] U8G_FONT_SECTION("fontpage_198_137_137") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x20,0x80,0xff,0xe0,0x25,0x20,0x29, - 0x00,0x37,0xe0,0x62,0x40,0xa6,0x40,0x21,0x80,0x22,0x80,0xec,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x20,0x80,0xFF,0xE0,0x25,0x20,0x29, + 0x00,0x37,0xE0,0x62,0x40,0xA6,0x40,0x21,0x80,0x22,0x80,0xEC,0x60}; const u8g_fntpgm_uint8_t fontpage_198_161_161[45] U8G_FONT_SECTION("fontpage_198_161_161") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa1,0xa1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x25,0x20,0xfb,0x40,0x21,0x00,0x2f, - 0xe0,0x30,0x20,0x60,0x20,0xa7,0xe0,0x20,0x20,0x20,0x20,0xef,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA1,0xA1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x25,0x20,0xFB,0x40,0x21,0x00,0x2F, + 0xE0,0x30,0x20,0x60,0x20,0xA7,0xE0,0x20,0x20,0x20,0x20,0xEF,0xE0}; const u8g_fntpgm_uint8_t fontpage_198_164_164[45] U8G_FONT_SECTION("fontpage_198_164_164") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa4,0xa4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x27,0xe0,0xfa,0x40,0x21,0x80,0x2e, - 0x60,0x30,0x00,0x62,0x40,0xa2,0x40,0x22,0x40,0x24,0x40,0xe8,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA4,0xA4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x27,0xE0,0xFA,0x40,0x21,0x80,0x2E, + 0x60,0x30,0x00,0x62,0x40,0xA2,0x40,0x22,0x40,0x24,0x40,0xE8,0x40}; +const u8g_fntpgm_uint8_t fontpage_198_223_223[45] U8G_FONT_SECTION("fontpage_198_223_223") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDF,0xDF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x23,0xC0,0x22,0x40,0xFB,0xC0,0x20,0x00,0x2F, + 0xE0,0x34,0x20,0x65,0x20,0xA5,0x20,0x25,0x20,0x22,0x80,0xEC,0x60}; const u8g_fntpgm_uint8_t fontpage_198_226_226[45] U8G_FONT_SECTION("fontpage_198_226_226") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe2,0xe2,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x00,0x23,0xc0,0xfc,0x80,0x27,0xc0,0x2d, - 0x40,0x35,0x40,0x6f,0xe0,0xa1,0x00,0x22,0x80,0x24,0x40,0xe8,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE2,0xE2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0x23,0xC0,0xFC,0x80,0x27,0xC0,0x2D, + 0x40,0x35,0x40,0x6F,0xE0,0xA1,0x00,0x22,0x80,0x24,0x40,0xE8,0x20}; const u8g_fntpgm_uint8_t fontpage_199_137_137[45] U8G_FONT_SECTION("fontpage_199_137_137") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x21,0xe0,0xf9,0x00,0x27,0xc0,0x2c, - 0x40,0x37,0xc0,0x64,0x40,0xa7,0xc0,0x21,0x00,0x2f,0xe0,0xe1,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x21,0xE0,0xF9,0x00,0x27,0xC0,0x2C, + 0x40,0x37,0xC0,0x64,0x40,0xA7,0xC0,0x21,0x00,0x2F,0xE0,0xE1,0x00}; const u8g_fntpgm_uint8_t fontpage_199_162_162[45] U8G_FONT_SECTION("fontpage_199_162_162") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa2,0xa2,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x2f,0xe0,0x28,0x20,0xf2,0x80,0x24,0x40,0x29, - 0x20,0x31,0x00,0x6f,0xe0,0xa1,0x00,0x25,0x80,0x29,0x40,0xf1,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA2,0xA2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x2F,0xE0,0x28,0x20,0xF2,0x80,0x24,0x40,0x29, + 0x20,0x31,0x00,0x6F,0xE0,0xA1,0x00,0x25,0x80,0x29,0x40,0xF1,0x20}; +const u8g_fntpgm_uint8_t fontpage_199_165_165[45] U8G_FONT_SECTION("fontpage_199_165_165") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA5,0xA5,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x2F,0xE0,0xF4,0x40,0x22,0x80,0x2F, + 0xE0,0x31,0x00,0x6F,0xE0,0xA2,0x40,0x26,0x80,0x21,0x40,0xEE,0x20}; const u8g_fntpgm_uint8_t fontpage_199_167_167[45] U8G_FONT_SECTION("fontpage_199_167_167") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa7,0xa7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x2f,0xe0,0xf8,0x20,0x22,0x80,0x24, - 0x40,0x38,0x20,0x67,0xc0,0xa1,0x00,0x21,0x00,0x21,0x00,0xef,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA7,0xA7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x2F,0xE0,0xF8,0x20,0x22,0x80,0x24, + 0x40,0x38,0x20,0x67,0xC0,0xA1,0x00,0x21,0x00,0x21,0x00,0xEF,0xE0}; +const u8g_fntpgm_uint8_t fontpage_199_208_208[45] U8G_FONT_SECTION("fontpage_199_208_208") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD0,0xD0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x27,0xC0,0x24,0x40,0xFF,0xC0,0x24,0x40,0x27, + 0xC0,0x30,0x00,0x6F,0xE0,0xA5,0x00,0x25,0xE0,0x2B,0x00,0xF1,0xE0}; const u8g_fntpgm_uint8_t fontpage_199_210_210[45] U8G_FONT_SECTION("fontpage_199_210_210") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd2,0xd2,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0xc0,0x27,0x00,0xf1,0x00,0x2f,0xe0,0x21, - 0x00,0x35,0x60,0x69,0x20,0xad,0x60,0x29,0x20,0x29,0x20,0xef,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD2,0xD2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0xC0,0x27,0x00,0xF1,0x00,0x2F,0xE0,0x21, + 0x00,0x35,0x60,0x69,0x20,0xAD,0x60,0x29,0x20,0x29,0x20,0xEF,0xE0}; const u8g_fntpgm_uint8_t fontpage_202_182_182[45] U8G_FONT_SECTION("fontpage_202_182_182") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb6,0xb6,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x12,0x00,0x12,0x00,0x93,0xe0,0x94,0x40,0x9a, - 0x40,0x92,0x40,0xb2,0x80,0xd1,0x00,0x91,0x80,0x12,0x40,0x14,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB6,0xB6,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x12,0x00,0x12,0x00,0x93,0xE0,0x94,0x40,0x9A, + 0x40,0x92,0x40,0xB2,0x80,0xD1,0x00,0x91,0x80,0x12,0x40,0x14,0x20}; const u8g_fntpgm_uint8_t fontpage_202_190_190[45] U8G_FONT_SECTION("fontpage_202_190_190") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbe,0xbe,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x11,0x00,0xfd,0xe0,0x22,0x40,0x25, - 0x40,0x39,0x40,0x29,0x40,0x28,0x80,0x49,0x80,0x4a,0x40,0x94,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBE,0xBE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x11,0x00,0xFD,0xE0,0x22,0x40,0x25, + 0x40,0x39,0x40,0x29,0x40,0x28,0x80,0x49,0x80,0x4A,0x40,0x94,0x20}; const u8g_fntpgm_uint8_t fontpage_202_240_240[45] U8G_FONT_SECTION("fontpage_202_240_240") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf0,0xf0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x95,0x00,0x59,0x00,0xfd,0xe0,0x33,0x40,0x59, - 0x40,0x95,0x40,0xfd,0x40,0x29,0x40,0x68,0x80,0x11,0x40,0xee,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x95,0x00,0x59,0x00,0xFD,0xE0,0x33,0x40,0x59, + 0x40,0x95,0x40,0xFD,0x40,0x29,0x40,0x68,0x80,0x11,0x40,0xEE,0x20}; +const u8g_fntpgm_uint8_t fontpage_202_242_242[45] U8G_FONT_SECTION("fontpage_202_242_242") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF2,0xF2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x10,0x80,0xFE,0xE0,0x00,0x80,0x78,0x80,0x4B, + 0xE0,0x79,0x40,0x01,0x40,0xFF,0x40,0xAA,0x80,0xBB,0x40,0x86,0x20}; const u8g_fntpgm_uint8_t fontpage_202_244_244[45] U8G_FONT_SECTION("fontpage_202_244_244") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf4,0xf4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0xff,0xe0,0x55,0x40,0x7c,0x80,0x39, - 0x40,0x56,0x20,0x7f,0xc0,0x04,0x00,0x27,0x80,0x24,0x00,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF4,0xF4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0xFF,0xE0,0x55,0x40,0x7C,0x80,0x39, + 0x40,0x56,0x20,0x7F,0xC0,0x04,0x00,0x27,0x80,0x24,0x00,0xFF,0xE0}; +const u8g_fntpgm_uint8_t fontpage_203_135_135[45] U8G_FONT_SECTION("fontpage_203_135_135") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x87,0x87,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x08,0x00,0x04,0x00,0xFF,0xE0,0x11,0x00,0x11, + 0x00,0x11,0x00,0x0A,0x00,0x0A,0x00,0x04,0x00,0x1B,0x00,0xE0,0xE0}; const u8g_fntpgm_uint8_t fontpage_203_153_153[45] U8G_FONT_SECTION("fontpage_203_153_153") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x99,0x99,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x80,0xac,0x80,0x72,0x80,0x20,0x80,0xfc, - 0x80,0x22,0x80,0x30,0xe0,0x6f,0x80,0xa0,0x80,0x20,0x80,0x20,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x99,0x99,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x80,0xAC,0x80,0x72,0x80,0x20,0x80,0xFC, + 0x80,0x22,0x80,0x30,0xE0,0x6F,0x80,0xA0,0x80,0x20,0x80,0x20,0x80}; const u8g_fntpgm_uint8_t fontpage_203_156_156[45] U8G_FONT_SECTION("fontpage_203_156_156") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9c,0x9c,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x10,0x40,0x29,0x40,0x44,0xc0,0xb8,0x40,0x12, - 0x40,0x7d,0x40,0x10,0x60,0x55,0xc0,0x52,0x40,0x92,0x40,0x30,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9C,0x9C,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x10,0x40,0x29,0x40,0x44,0xC0,0xB8,0x40,0x12, + 0x40,0x7D,0x40,0x10,0x60,0x55,0xC0,0x52,0x40,0x92,0x40,0x30,0x40}; +const u8g_fntpgm_uint8_t fontpage_203_173_173[45] U8G_FONT_SECTION("fontpage_203_173_173") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAD,0xAD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x10,0x60,0xD5,0x80,0xB9,0x00,0x91,0x00,0xFD, + 0xE0,0xB1,0x40,0xD9,0x40,0xD5,0x40,0x91,0x40,0xFA,0x40,0x04,0x40}; const u8g_fntpgm_uint8_t fontpage_203_176_176[45] U8G_FONT_SECTION("fontpage_203_176_176") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb0,0xb0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x10,0x60,0xfd,0x80,0x45,0x00,0x29,0x00,0xfd, - 0xe0,0x11,0x40,0xfd,0x40,0x11,0x40,0x55,0x40,0x92,0x40,0x34,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB0,0xB0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x10,0x60,0xFD,0x80,0x45,0x00,0x29,0x00,0xFD, + 0xE0,0x11,0x40,0xFD,0x40,0x11,0x40,0x55,0x40,0x92,0x40,0x34,0x40}; +const u8g_fntpgm_uint8_t fontpage_203_185_185[45] U8G_FONT_SECTION("fontpage_203_185_185") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB9,0xB9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x08,0x00,0x04,0x00,0xFF,0xE0,0x08,0x00,0x08, + 0x00,0x0F,0x80,0x10,0x80,0x10,0x80,0x20,0x80,0x40,0x80,0x87,0x00}; const u8g_fntpgm_uint8_t fontpage_203_224_224[45] U8G_FONT_SECTION("fontpage_203_224_224") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe0,0xe0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x7f,0xc0,0x04,0x00,0x04,0x00,0x04,0x00,0xff, - 0xe0,0x0a,0x00,0x0a,0x00,0x12,0x00,0x12,0x20,0x22,0x20,0xc1,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0xC0,0x04,0x00,0x04,0x00,0x04,0x00,0xFF, + 0xE0,0x0A,0x00,0x0A,0x00,0x12,0x00,0x12,0x20,0x22,0x20,0xC1,0xE0}; const u8g_fntpgm_uint8_t fontpage_203_246_246[45] U8G_FONT_SECTION("fontpage_203_246_246") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf6,0xf6,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x00,0x80,0xf0,0x80,0x9f,0xe0,0x90,0x80,0x94, - 0x80,0xf2,0x80,0x92,0x80,0x90,0x80,0x90,0x80,0xf0,0x80,0x03,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF6,0xF6,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x00,0x80,0xF0,0x80,0x9F,0xE0,0x90,0x80,0x94, + 0x80,0xF2,0x80,0x92,0x80,0x90,0x80,0x90,0x80,0xF0,0x80,0x03,0x80}; const u8g_fntpgm_uint8_t fontpage_204_142_142[45] U8G_FONT_SECTION("fontpage_204_142_142") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8e,0x8e,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x03,0xe0,0xf2,0x20,0x92,0x20,0x93,0xe0,0xf2, - 0x20,0x92,0x20,0x93,0xe0,0xf2,0x20,0x04,0x20,0x08,0xa0,0x30,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8E,0x8E,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x03,0xE0,0xF2,0x20,0x92,0x20,0x93,0xE0,0xF2, + 0x20,0x92,0x20,0x93,0xE0,0xF2,0x20,0x04,0x20,0x08,0xA0,0x30,0x40}; +const u8g_fntpgm_uint8_t fontpage_204_175_175[45] U8G_FONT_SECTION("fontpage_204_175_175") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAF,0xAF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x1F,0x80,0x10,0x80,0x1F,0x80,0x10,0x80,0x1F, + 0x80,0x00,0x00,0xFF,0xE0,0x24,0x00,0x27,0x80,0x54,0x00,0x8F,0xE0}; const u8g_fntpgm_uint8_t fontpage_205_130_130[45] U8G_FONT_SECTION("fontpage_205_130_130") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x82,0x82,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x40,0xfb,0x80,0x52,0x00,0xfb,0xe0,0x12, - 0x80,0xf4,0x80,0x3f,0x80,0x20,0x80,0x3f,0x80,0x20,0x80,0x3f,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x82,0x82,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x40,0xFB,0x80,0x52,0x00,0xFB,0xE0,0x12, + 0x80,0xF4,0x80,0x3F,0x80,0x20,0x80,0x3F,0x80,0x20,0x80,0x3F,0x80}; const u8g_fntpgm_uint8_t fontpage_205_171_171[45] U8G_FONT_SECTION("fontpage_205_171_171") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xab,0xab,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0xe0,0xff,0x00,0x55,0xe0,0x7d,0x40,0x55, - 0x40,0xff,0xc0,0x10,0x40,0x1f,0xc0,0x10,0x40,0x1f,0xc0,0x10,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAB,0xAB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0xE0,0xFF,0x00,0x55,0xE0,0x7D,0x40,0x55, + 0x40,0xFF,0xC0,0x10,0x40,0x1F,0xC0,0x10,0x40,0x1F,0xC0,0x10,0x40}; const u8g_fntpgm_uint8_t fontpage_205_244_244[45] U8G_FONT_SECTION("fontpage_205_244_244") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf4,0xf4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x7f,0xe0,0x02,0x00,0x3f,0xc0,0x22,0x40,0x3f, - 0xc0,0x22,0x40,0x3f,0xc0,0x0a,0x00,0x04,0x00,0x1b,0x00,0xe0,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF4,0xF4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0xE0,0x02,0x00,0x3F,0xC0,0x22,0x40,0x3F, + 0xC0,0x22,0x40,0x3F,0xC0,0x0A,0x00,0x04,0x00,0x1B,0x00,0xE0,0xE0}; const u8g_fntpgm_uint8_t fontpage_206_128_128[45] U8G_FONT_SECTION("fontpage_206_128_128") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x3f,0x80,0x20,0x80,0x3f,0x80,0x20,0x80,0xff, - 0xe0,0x48,0x00,0x7f,0xc0,0x4a,0x40,0x79,0x80,0xc9,0x80,0x0e,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x3F,0x80,0x20,0x80,0x3F,0x80,0x20,0x80,0xFF, + 0xE0,0x48,0x00,0x7F,0xC0,0x4A,0x40,0x79,0x80,0xC9,0x80,0x0E,0x60}; const u8g_fntpgm_uint8_t fontpage_206_137_137[45] U8G_FONT_SECTION("fontpage_206_137_137") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x08,0x00,0xff,0xe0,0x10,0x00,0x1f,0x80,0x30, - 0x80,0x5f,0x80,0x90,0x80,0x1f,0x80,0x10,0x80,0x10,0x80,0x11,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x08,0x00,0xFF,0xE0,0x10,0x00,0x1F,0x80,0x30, + 0x80,0x5F,0x80,0x90,0x80,0x1F,0x80,0x10,0x80,0x10,0x80,0x11,0x80}; +const u8g_fntpgm_uint8_t fontpage_206_159_159[45] U8G_FONT_SECTION("fontpage_206_159_159") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9F,0x9F,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x49,0xE0,0xFD,0x20,0x49,0x20,0x79,0xE0,0x49, + 0x20,0x79,0x20,0x49,0xE0,0xFD,0x20,0x01,0x20,0x49,0x20,0x86,0x60}; const u8g_fntpgm_uint8_t fontpage_206_186_186[45] U8G_FONT_SECTION("fontpage_206_186_186") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xba,0xba,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x00,0x27,0x80,0x24,0x80,0xfc,0x80,0x24, - 0x80,0x74,0x80,0x6c,0x80,0xa4,0x80,0xa4,0x80,0x28,0xa0,0x30,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBA,0xBA,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x00,0x27,0x80,0x24,0x80,0xFC,0x80,0x24, + 0x80,0x74,0x80,0x6C,0x80,0xA4,0x80,0xA4,0x80,0x28,0xA0,0x30,0xE0}; const u8g_fntpgm_uint8_t fontpage_206_192_192[45] U8G_FONT_SECTION("fontpage_206_192_192") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc0,0xc0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x80,0x19,0x00,0x06,0x00,0x19,0x00,0x64, - 0xc0,0x04,0x00,0xff,0xe0,0x15,0x00,0x24,0x80,0xc4,0x60,0x0c,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x80,0x19,0x00,0x06,0x00,0x19,0x00,0x64, + 0xC0,0x04,0x00,0xFF,0xE0,0x15,0x00,0x24,0x80,0xC4,0x60,0x0C,0x00}; +const u8g_fntpgm_uint8_t fontpage_206_223_223[45] U8G_FONT_SECTION("fontpage_206_223_223") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDF,0xDF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0xFF,0xE0,0x04,0x00,0x3F,0x80,0x24, + 0x80,0x24,0x80,0x3F,0x80,0x0E,0x00,0x15,0x00,0x24,0x80,0xC4,0x60}; const u8g_fntpgm_uint8_t fontpage_206_225_225[45] U8G_FONT_SECTION("fontpage_206_225_225") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe1,0xe1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x10,0x00,0x1f,0x80,0x29,0x00,0x46,0x00,0x0a, - 0x00,0x35,0x80,0xc4,0x60,0x3f,0x80,0x15,0x00,0x24,0x80,0xdc,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE1,0xE1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x10,0x00,0x1F,0x80,0x29,0x00,0x46,0x00,0x0A, + 0x00,0x35,0x80,0xC4,0x60,0x3F,0x80,0x15,0x00,0x24,0x80,0xDC,0x40}; const u8g_fntpgm_uint8_t fontpage_206_229_229[45] U8G_FONT_SECTION("fontpage_206_229_229") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe5,0xe5,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x7f,0xc0,0x24,0x80,0x15,0x00,0xff, - 0xe0,0x04,0x00,0x0e,0x00,0x15,0x00,0x24,0x80,0xc4,0x60,0x04,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE5,0xE5,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x7F,0xC0,0x24,0x80,0x15,0x00,0xFF, + 0xE0,0x04,0x00,0x0E,0x00,0x15,0x00,0x24,0x80,0xC4,0x60,0x04,0x00}; const u8g_fntpgm_uint8_t fontpage_206_255_255[45] U8G_FONT_SECTION("fontpage_206_255_255") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0xc0,0x27,0x00,0xfc,0x00,0x24,0x00,0x27, - 0xc0,0x74,0x40,0x6e,0x40,0xa5,0x80,0x28,0x80,0x29,0x40,0x36,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0xC0,0x27,0x00,0xFC,0x00,0x24,0x00,0x27, + 0xC0,0x74,0x40,0x6E,0x40,0xA5,0x80,0x28,0x80,0x29,0x40,0x36,0x20}; +const u8g_fntpgm_uint8_t fontpage_207_151_151[45] U8G_FONT_SECTION("fontpage_207_151_151") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x97,0x97,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x21,0x00,0xFF,0xE0,0x21,0x00,0x71, + 0x00,0x6B,0x80,0xA5,0x40,0xA9,0x20,0x21,0x00,0x21,0x00,0x21,0x00}; const u8g_fntpgm_uint8_t fontpage_207_241_241[45] U8G_FONT_SECTION("fontpage_207_241_241") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf1,0xf1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x00,0x21,0x00,0xff,0xe0,0x21,0x00,0x71, - 0x00,0x69,0x00,0xa7,0xc0,0xa1,0x00,0x21,0x00,0x21,0x00,0x2f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF1,0xF1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0x21,0x00,0xFF,0xE0,0x21,0x00,0x71, + 0x00,0x69,0x00,0xA7,0xC0,0xA1,0x00,0x21,0x00,0x21,0x00,0x2F,0xE0}; const u8g_fntpgm_uint8_t fontpage_208_161_161[45] U8G_FONT_SECTION("fontpage_208_161_161") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa1,0xa1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x00,0x21,0x00,0x2f,0xe0,0xf0,0x00,0x22, - 0x80,0x74,0x40,0x6a,0xa0,0xa2,0x80,0x21,0x00,0x22,0x80,0x2c,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA1,0xA1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0x21,0x00,0x2F,0xE0,0xF0,0x00,0x22, + 0x80,0x74,0x40,0x6A,0xA0,0xA2,0x80,0x21,0x00,0x22,0x80,0x2C,0x60}; const u8g_fntpgm_uint8_t fontpage_208_188_188[45] U8G_FONT_SECTION("fontpage_208_188_188") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbc,0xbc,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x00,0x23,0xc0,0xf4,0x40,0x2a,0x80,0x21, - 0x00,0x72,0x80,0x6c,0x60,0xa7,0xc0,0x24,0x40,0x24,0x40,0x27,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBC,0xBC,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0x23,0xC0,0xF4,0x40,0x2A,0x80,0x21, + 0x00,0x72,0x80,0x6C,0x60,0xA7,0xC0,0x24,0x40,0x24,0x40,0x27,0xC0}; +const u8g_fntpgm_uint8_t fontpage_209_175_175[45] U8G_FONT_SECTION("fontpage_209_175_175") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAF,0xAF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x24,0x40,0x22,0x80,0x27,0xC0,0xF9,0x40,0x27, + 0xC0,0x75,0x00,0x6F,0xE0,0xA3,0x20,0x25,0x20,0x29,0xC0,0x21,0x00}; const u8g_fntpgm_uint8_t fontpage_209_192_192[45] U8G_FONT_SECTION("fontpage_209_192_192") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc0,0xc0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x22,0x80,0xfc,0x40,0x28,0x20,0x27, - 0xc0,0x70,0x00,0x69,0x20,0xa4,0xa0,0x22,0x40,0x22,0x80,0x2f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x22,0x80,0xFC,0x40,0x28,0x20,0x27, + 0xC0,0x70,0x00,0x69,0x20,0xA4,0xA0,0x22,0x40,0x22,0x80,0x2F,0xE0}; const u8g_fntpgm_uint8_t fontpage_211_253_253[45] U8G_FONT_SECTION("fontpage_211_253_253") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfd,0xfd,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x80,0x2f,0xe0,0xfa,0xa0,0x2f,0xe0,0x2a, - 0xa0,0x3f,0xe0,0x64,0x40,0xa7,0xc0,0x24,0x40,0x27,0xc0,0x24,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFD,0xFD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x80,0x2F,0xE0,0xFA,0xA0,0x2F,0xE0,0x2A, + 0xA0,0x3F,0xE0,0x64,0x40,0xA7,0xC0,0x24,0x40,0x27,0xC0,0x24,0x40}; +const u8g_fntpgm_uint8_t fontpage_212_161_161[45] U8G_FONT_SECTION("fontpage_212_161_161") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA1,0xA1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x80,0x2F,0xE0,0xF2,0x80,0x27,0xC0,0x34, + 0x40,0x6F,0xC0,0x64,0x40,0xAF,0xE0,0x21,0x00,0x22,0x80,0x2C,0x60}; const u8g_fntpgm_uint8_t fontpage_212_217_217[45] U8G_FONT_SECTION("fontpage_212_217_217") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd9,0xd9,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x2f,0x40,0x2a,0xa0,0xf4,0x40,0x27,0xc0,0x38, - 0x20,0x27,0xc0,0x64,0x40,0xa7,0xc0,0x24,0x40,0x22,0x80,0x2f,0xe0}; -const u8g_fntpgm_uint8_t fontpage_214_226_226[45] U8G_FONT_SECTION("fontpage_214_226_226") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe2,0xe2,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x04,0x00,0x04,0x00,0x04,0x00,0x24,0x00,0x27, - 0x80,0x24,0x00,0x24,0x00,0x24,0x00,0x24,0x00,0x24,0x00,0xff,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD9,0xD9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x2F,0x40,0x2A,0xA0,0xF4,0x40,0x27,0xC0,0x38, + 0x20,0x27,0xC0,0x64,0x40,0xA7,0xC0,0x24,0x40,0x22,0x80,0x2F,0xE0}; +const u8g_fntpgm_uint8_t fontpage_214_226_227[71] U8G_FONT_SECTION("fontpage_214_226_227") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE2,0xE3,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x04,0x00,0x04,0x00,0x04,0x00,0x24,0x00,0x27, + 0x80,0x24,0x00,0x24,0x00,0x24,0x00,0x24,0x00,0x24,0x00,0xFF,0xC0,0x0B,0x0A,0x14, + 0x0C,0x00,0xFF,0xFF,0xE0,0x04,0x00,0x04,0x00,0x24,0x00,0x27,0xC0,0x24,0x00,0x24, + 0x00,0x24,0x00,0x24,0x00,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_214_229_229[45] U8G_FONT_SECTION("fontpage_214_229_229") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe5,0xe5,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x27,0xc0,0x24,0x00,0x24,0x00,0xff, - 0xe0,0x04,0x00,0x14,0x40,0x24,0x80,0x41,0x00,0x06,0x00,0xf8,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE5,0xE5,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x27,0xC0,0x24,0x00,0x24,0x00,0xFF, + 0xE0,0x04,0x00,0x14,0x40,0x24,0x80,0x41,0x00,0x06,0x00,0xF8,0x00}; const u8g_fntpgm_uint8_t fontpage_215_212_212[45] U8G_FONT_SECTION("fontpage_215_212_212") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd4,0xd4,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x84,0x00,0x84,0x00,0x84,0x80,0x85,0x00,0xf6, - 0x00,0x84,0x00,0x84,0x00,0x84,0x00,0xb4,0x40,0xc4,0x40,0x83,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD4,0xD4,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x84,0x00,0x84,0x00,0x84,0x80,0x85,0x00,0xF6, + 0x00,0x84,0x00,0x84,0x00,0x84,0x00,0xB4,0x40,0xC4,0x40,0x83,0xC0}; const u8g_fntpgm_uint8_t fontpage_217_161_161[45] U8G_FONT_SECTION("fontpage_217_161_161") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa1,0xa1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x47,0x80,0x24,0x80,0x84,0x80,0x48,0xe0,0x10, - 0x00,0x2f,0xc0,0x24,0x80,0x42,0x80,0xc3,0x00,0x44,0x80,0x58,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA1,0xA1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x47,0x80,0x24,0x80,0x84,0x80,0x48,0xE0,0x10, + 0x00,0x2F,0xC0,0x24,0x80,0x42,0x80,0xC3,0x00,0x44,0x80,0x58,0x60}; const u8g_fntpgm_uint8_t fontpage_217_226_226[45] U8G_FONT_SECTION("fontpage_217_226_226") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe2,0xe2,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x41,0x00,0x21,0x00,0x8f,0xe0,0x49,0x20,0x19, - 0x00,0x2f,0xc0,0x28,0x40,0xca,0x80,0x49,0x00,0x52,0x80,0x6c,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE2,0xE2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x41,0x00,0x21,0x00,0x8F,0xE0,0x49,0x20,0x19, + 0x00,0x2F,0xC0,0x28,0x40,0xCA,0x80,0x49,0x00,0x52,0x80,0x6C,0x60}; +const u8g_fntpgm_uint8_t fontpage_217_232_232[45] U8G_FONT_SECTION("fontpage_217_232_232") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE8,0xE8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x42,0x00,0x21,0x00,0x8F,0xE0,0x51,0x00,0x11, + 0x00,0x21,0x00,0x27,0xC0,0xC1,0x00,0x41,0x00,0x41,0x00,0x4F,0xE0}; +const u8g_fntpgm_uint8_t fontpage_218_151_151[45] U8G_FONT_SECTION("fontpage_218_151_151") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x97,0x97,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x41,0x00,0x25,0x00,0x87,0xC0,0x49,0x00,0x21, + 0x00,0x3F,0xE0,0x42,0x80,0xC2,0x80,0x44,0xA0,0x48,0xA0,0x50,0xE0}; const u8g_fntpgm_uint8_t fontpage_218_187_187[45] U8G_FONT_SECTION("fontpage_218_187_187") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbb,0xbb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x40,0xc0,0x27,0x00,0x81,0x00,0x5f,0xe0,0x11, - 0x00,0x21,0x00,0x27,0xc0,0xc4,0x40,0x44,0x40,0x47,0xc0,0x44,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBB,0xBB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x40,0xC0,0x27,0x00,0x81,0x00,0x5F,0xE0,0x11, + 0x00,0x21,0x00,0x27,0xC0,0xC4,0x40,0x44,0x40,0x47,0xC0,0x44,0x40}; +const u8g_fntpgm_uint8_t fontpage_218_193_193[45] U8G_FONT_SECTION("fontpage_218_193_193") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC1,0xC1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x82,0x00,0x5F,0xE0,0x04,0x00,0x88,0x80,0x5F, + 0xC0,0x20,0x40,0x2A,0x80,0xCA,0x80,0x4A,0xA0,0x4A,0xA0,0x52,0x60}; const u8g_fntpgm_uint8_t fontpage_218_203_203[45] U8G_FONT_SECTION("fontpage_218_203_203") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcb,0xcb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xbe,0x20,0x62,0xa0,0x2a,0xa0,0xaa,0xa0,0x6a, - 0xa0,0x2a,0xa0,0x2a,0xa0,0xc8,0xa0,0x54,0x20,0x62,0x20,0x40,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCB,0xCB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xBE,0x20,0x62,0xA0,0x2A,0xA0,0xAA,0xA0,0x6A, + 0xA0,0x2A,0xA0,0x2A,0xA0,0xC8,0xA0,0x54,0x20,0x62,0x20,0x40,0xE0}; const u8g_fntpgm_uint8_t fontpage_219_136_136[45] U8G_FONT_SECTION("fontpage_219_136_136") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x49,0x20,0x25,0x40,0x81,0x00,0x57,0xe0,0x14, - 0x20,0x27,0xe0,0x24,0x20,0xc7,0xe0,0x44,0x20,0x44,0x20,0x44,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x49,0x20,0x25,0x40,0x81,0x00,0x57,0xE0,0x14, + 0x20,0x27,0xE0,0x24,0x20,0xC7,0xE0,0x44,0x20,0x44,0x20,0x44,0x60}; const u8g_fntpgm_uint8_t fontpage_219_225_225[45] U8G_FONT_SECTION("fontpage_219_225_225") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe1,0xe1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x41,0x00,0x25,0x40,0x09,0x80,0x82,0x80,0x54, - 0x40,0x29,0x20,0x25,0x40,0xc5,0x80,0x49,0x00,0x42,0x80,0x5c,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE1,0xE1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x41,0x00,0x25,0x40,0x09,0x80,0x82,0x80,0x54, + 0x40,0x29,0x20,0x25,0x40,0xC5,0x80,0x49,0x00,0x42,0x80,0x5C,0x60}; +const u8g_fntpgm_uint8_t fontpage_219_247_247[45] U8G_FONT_SECTION("fontpage_219_247_247") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF7,0xF7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x4F,0xC0,0x28,0x40,0x0F,0xC0,0x88,0x40,0x5F, + 0xC0,0x29,0x20,0x29,0x40,0xCF,0x80,0x49,0x20,0x4B,0x20,0x4C,0xE0}; const u8g_fntpgm_uint8_t fontpage_220_133_133[45] U8G_FONT_SECTION("fontpage_220_133_133") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x85,0x85,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x41,0x00,0x2f,0xe0,0x01,0x00,0x97,0xc0,0x51, - 0x00,0x2f,0xe0,0x24,0x40,0xc7,0x40,0x45,0xc0,0x44,0x40,0x44,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x85,0x85,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x41,0x00,0x2F,0xE0,0x01,0x00,0x97,0xC0,0x51, + 0x00,0x2F,0xE0,0x24,0x40,0xC7,0x40,0x45,0xC0,0x44,0x40,0x44,0xC0}; const u8g_fntpgm_uint8_t fontpage_220_169_169[45] U8G_FONT_SECTION("fontpage_220_169_169") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa9,0xa9,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x47,0xc0,0x24,0x40,0x07,0xc0,0x94,0x40,0x57, - 0xc0,0x20,0x00,0x2f,0xe0,0xca,0xa0,0x4a,0xa0,0x4a,0xa0,0x5f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA9,0xA9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x47,0xC0,0x24,0x40,0x07,0xC0,0x94,0x40,0x57, + 0xC0,0x20,0x00,0x2F,0xE0,0xCA,0xA0,0x4A,0xA0,0x4A,0xA0,0x5F,0xE0}; +const u8g_fntpgm_uint8_t fontpage_220_184_184[45] U8G_FONT_SECTION("fontpage_220_184_184") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB8,0xB8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x48,0x80,0x24,0xE0,0x1F,0x00,0x88,0xE0,0x5E, + 0x20,0x2A,0x40,0x2B,0xE0,0xCA,0x40,0x4A,0x40,0x52,0x40,0x66,0xC0}; const u8g_fntpgm_uint8_t fontpage_221_144_144[45] U8G_FONT_SECTION("fontpage_221_144_144") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x90,0x90,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x4f,0xe0,0x28,0x80,0x8b,0xe0,0x4a,0x20,0x1b, - 0xe0,0x2a,0x20,0x2b,0xe0,0xc8,0x80,0x4a,0xc0,0x54,0xa0,0x69,0xa0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x90,0x90,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x4F,0xE0,0x28,0x80,0x8B,0xE0,0x4A,0x20,0x1B, + 0xE0,0x2A,0x20,0x2B,0xE0,0xC8,0x80,0x4A,0xC0,0x54,0xA0,0x69,0xA0}; +const u8g_fntpgm_uint8_t fontpage_221_162_162[45] U8G_FONT_SECTION("fontpage_221_162_162") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA2,0xA2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x44,0x40,0x22,0x80,0x0F,0xE0,0x82,0x80,0x44, + 0x40,0x28,0x20,0x3F,0xE0,0xCA,0xA0,0x4A,0xA0,0x4A,0xA0,0x5F,0xE0}; +const u8g_fntpgm_uint8_t fontpage_221_209_209[45] U8G_FONT_SECTION("fontpage_221_209_209") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD1,0xD1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x47,0xC0,0x24,0x40,0x07,0x40,0x85,0x40,0x5F, + 0xE0,0x34,0x60,0x27,0xC0,0xC4,0x40,0x47,0xC0,0x44,0x40,0x44,0xC0}; +const u8g_fntpgm_uint8_t fontpage_222_143_143[45] U8G_FONT_SECTION("fontpage_222_143_143") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8F,0x8F,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x4F,0xE0,0x28,0x20,0x0F,0xE0,0x98,0x00,0x5F, + 0xE0,0x29,0x00,0x2F,0xE0,0xCD,0xA0,0x4B,0x60,0x5D,0xA0,0x49,0x60}; const u8g_fntpgm_uint8_t fontpage_223_192_192[45] U8G_FONT_SECTION("fontpage_223_192_192") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc0,0xc0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x44,0x80,0x3e,0x80,0x12,0xe0,0x9e,0xa0,0x53, - 0xa0,0x3e,0xa0,0x28,0xa0,0xdf,0xa0,0x4a,0x40,0x52,0xa0,0x65,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x44,0x80,0x3E,0x80,0x12,0xE0,0x9E,0xA0,0x53, + 0xA0,0x3E,0xA0,0x28,0xA0,0xDF,0xA0,0x4A,0x40,0x52,0xA0,0x65,0x20}; const u8g_fntpgm_uint8_t fontpage_224_239_239[45] U8G_FONT_SECTION("fontpage_224_239_239") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xef,0xef,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x10,0x00,0x17,0xe0,0x54,0x80,0x58,0x80,0x50, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xEF,0xEF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x10,0x00,0x17,0xE0,0x54,0x80,0x58,0x80,0x50, 0x80,0x90,0x80,0x10,0x80,0x10,0x80,0x28,0x80,0x44,0x80,0x81,0x80}; const u8g_fntpgm_uint8_t fontpage_225_185_185[45] U8G_FONT_SECTION("fontpage_225_185_185") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb9,0xb9,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x04,0x00,0x07,0xc0,0x04,0x00,0x3f, - 0x80,0x20,0x80,0x20,0x80,0x3f,0x80,0x00,0x00,0x52,0x40,0x89,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB9,0xB9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x04,0x00,0x07,0xC0,0x04,0x00,0x3F, + 0x80,0x20,0x80,0x20,0x80,0x3F,0x80,0x00,0x00,0x52,0x40,0x89,0x20}; const u8g_fntpgm_uint8_t fontpage_225_237_237[45] U8G_FONT_SECTION("fontpage_225_237_237") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xed,0xed,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x00,0xf7,0x80,0x22,0x80,0x32,0x80,0x66, - 0x80,0xa3,0x80,0x24,0xa0,0x68,0x60,0x00,0x00,0x52,0x40,0x89,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xED,0xED,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0xF7,0x80,0x22,0x80,0x32,0x80,0x66, + 0x80,0xA3,0x80,0x24,0xA0,0x68,0x60,0x00,0x00,0x52,0x40,0x89,0x20}; const u8g_fntpgm_uint8_t fontpage_228_199_199[45] U8G_FONT_SECTION("fontpage_228_199_199") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc7,0xc7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x21,0x00,0x21,0x00,0x3f,0xe0,0x20, - 0x00,0x20,0x00,0x3f,0x80,0x20,0x80,0x20,0x80,0x40,0x80,0x80,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC7,0xC7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x21,0x00,0x21,0x00,0x3F,0xE0,0x20, + 0x00,0x20,0x00,0x3F,0x80,0x20,0x80,0x20,0x80,0x40,0x80,0x80,0x80}; +const u8g_fntpgm_uint8_t fontpage_228_233_233[45] U8G_FONT_SECTION("fontpage_228_233_233") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE9,0xE9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0xA2,0x00,0xA7,0xE0,0xFA,0xA0,0xA2, + 0xA0,0x32,0xA0,0x64,0xA0,0xA9,0x20,0x22,0x20,0x25,0x20,0x28,0xC0}; const u8g_fntpgm_uint8_t fontpage_228_249_249[45] U8G_FONT_SECTION("fontpage_228_249_249") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf9,0xf9,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0xa7,0xc0,0xf1,0x00,0xa1,0x00,0xaf, - 0xe0,0x30,0x80,0x6f,0xe0,0xa4,0x80,0x22,0x80,0x20,0x80,0x23,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF9,0xF9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0xA7,0xC0,0xF1,0x00,0xA1,0x00,0xAF, + 0xE0,0x30,0x80,0x6F,0xE0,0xA4,0x80,0x22,0x80,0x20,0x80,0x23,0x80}; const u8g_fntpgm_uint8_t fontpage_231_135_135[45] U8G_FONT_SECTION("fontpage_231_135_135") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x87,0x87,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0xff,0xe0,0x88,0x40,0x52,0x80,0x0c, - 0x00,0x2a,0x80,0xdf,0x40,0x04,0x00,0xff,0xe0,0x04,0x00,0x04,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x87,0x87,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0xFF,0xE0,0x88,0x40,0x52,0x80,0x0C, + 0x00,0x2A,0x80,0xDF,0x40,0x04,0x00,0xFF,0xE0,0x04,0x00,0x04,0x00}; +const u8g_fntpgm_uint8_t fontpage_231_175_175[45] U8G_FONT_SECTION("fontpage_231_175_175") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAF,0xAF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x07,0xE0,0xF9,0x00,0x21,0x00,0x23,0x00,0x73, + 0x80,0x25,0x40,0x25,0x20,0x39,0x20,0xC1,0x00,0x01,0x00,0x01,0x00}; const u8g_fntpgm_uint8_t fontpage_234_168_168[45] U8G_FONT_SECTION("fontpage_234_168_168") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa8,0xa8,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x00,0xff,0x7f,0xc0,0x44,0x40,0x44,0x40,0x7f,0xc0,0x44, - 0x40,0x44,0x40,0x7f,0xc0,0x44,0x40,0x44,0x40,0x84,0x40,0x84,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA8,0xA8,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0xC0,0x44,0x40,0x44,0x40,0x7F,0xC0,0x44, + 0x40,0x44,0x40,0x7F,0xC0,0x44,0x40,0x44,0x40,0x84,0x40,0x84,0xC0}; const u8g_fntpgm_uint8_t fontpage_234_181_181[45] U8G_FONT_SECTION("fontpage_234_181_181") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb5,0xb5,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x08,0x00,0x08,0x00,0xff,0x80,0x88,0x80,0xff, - 0x80,0x88,0x80,0x88,0x80,0xff,0x80,0x08,0x40,0x08,0x40,0x07,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB5,0xB5,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x08,0x00,0x08,0x00,0xFF,0x80,0x88,0x80,0xFF, + 0x80,0x88,0x80,0x88,0x80,0xFF,0x80,0x08,0x40,0x08,0x40,0x07,0xC0}; +const u8g_fntpgm_uint8_t fontpage_234_229_229[45] U8G_FONT_SECTION("fontpage_234_229_229") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE5,0xE5,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x02,0x00,0xFB,0xC0,0xAE,0x40,0xA9,0x80,0xFA, + 0x40,0xAC,0x20,0xAB,0xC0,0xAA,0x40,0xFA,0x40,0x8B,0xC0,0x02,0x40}; const u8g_fntpgm_uint8_t fontpage_236_253_253[34] U8G_FONT_SECTION("fontpage_236_253_253") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfd,0xfd,0x00,0x0a,0xff,0x00, - 0x00,0x08,0x0b,0x0b,0x0c,0x02,0xff,0x10,0x20,0xff,0x81,0x81,0xff,0x81,0x81,0x81, - 0xff,0x81}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFD,0xFD,0x00,0x0A,0xFF,0x00, + 0x00,0x08,0x0B,0x0B,0x0C,0x02,0xFF,0x10,0x20,0xFF,0x81,0x81,0xFF,0x81,0x81,0x81, + 0xFF,0x81}; const u8g_fntpgm_uint8_t fontpage_237_132_132[45] U8G_FONT_SECTION("fontpage_237_132_132") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x84,0x84,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x22,0x00,0x42,0x00,0xf7,0xc0,0x98,0x40,0x90, - 0x40,0xf4,0x40,0x92,0x40,0x92,0x40,0x90,0x40,0xf0,0x40,0x91,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x84,0x84,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x22,0x00,0x42,0x00,0xF7,0xC0,0x98,0x40,0x90, + 0x40,0xF4,0x40,0x92,0x40,0x92,0x40,0x90,0x40,0xF0,0x40,0x91,0x80}; +const u8g_fntpgm_uint8_t fontpage_237_209_209[45] U8G_FONT_SECTION("fontpage_237_209_209") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD1,0xD1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x0A,0x00,0x4A,0x00,0x4B,0xE0,0x4A,0x00,0x4C, + 0x80,0x48,0x40,0x08,0x00,0x7F,0xC0,0x4A,0x40,0x4A,0x40,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_237_244_244[45] U8G_FONT_SECTION("fontpage_237_244_244") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf4,0xf4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0xff,0xe0,0x04,0x00,0x3f,0x80,0x20, - 0x80,0x3f,0x80,0x20,0x80,0x3f,0x80,0x20,0x80,0x20,0x80,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF4,0xF4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0xFF,0xE0,0x04,0x00,0x3F,0x80,0x20, + 0x80,0x3F,0x80,0x20,0x80,0x3F,0x80,0x20,0x80,0x20,0x80,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_238_129_129[45] U8G_FONT_SECTION("fontpage_238_129_129") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x81,0x81,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x14,0x80,0x25,0x60,0x46,0x20,0x1f, - 0x80,0x30,0x80,0xdf,0x80,0x10,0x80,0x1f,0x80,0x10,0x80,0x1f,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x81,0x81,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x14,0x80,0x25,0x60,0x46,0x20,0x1F, + 0x80,0x30,0x80,0xDF,0x80,0x10,0x80,0x1F,0x80,0x10,0x80,0x1F,0x80}; const u8g_fntpgm_uint8_t fontpage_238_160_160[45] U8G_FONT_SECTION("fontpage_238_160_160") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa0,0xa0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x07,0xe0,0xf4,0x20,0x97,0xe0,0xf4,0x80,0x94, - 0x80,0x97,0xe0,0xf4,0x80,0x94,0x80,0xf4,0xa0,0x96,0x60,0x04,0x20}; -const u8g_fntpgm_uint8_t fontpage_243_239_239[45] U8G_FONT_SECTION("fontpage_243_239_239") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xef,0xef,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x18,0x00,0xe3,0xe0,0x22,0x20,0xfa,0x20,0x22, - 0x20,0x73,0xe0,0x68,0x00,0xa2,0x40,0xa2,0x40,0x24,0x20,0x28,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA0,0xA0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x07,0xE0,0xF4,0x20,0x97,0xE0,0xF4,0x80,0x94, + 0x80,0x97,0xE0,0xF4,0x80,0x94,0x80,0xF4,0xA0,0x96,0x60,0x04,0x20}; +const u8g_fntpgm_uint8_t fontpage_240_238_238[45] U8G_FONT_SECTION("fontpage_240_238_238") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xEE,0xEE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x02,0x00,0xF3,0xC0,0x24,0x80,0x4F,0xE0,0xF5, + 0x20,0x57,0xE0,0x55,0x20,0x57,0xE0,0x75,0x20,0x45,0x20,0x08,0x60}; +const u8g_fntpgm_uint8_t fontpage_243_187_187[45] U8G_FONT_SECTION("fontpage_243_187_187") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBB,0xBB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0xFF,0xE0,0x2A,0x80,0x24,0x80,0x2A, + 0x80,0x3F,0x80,0x04,0x00,0x7F,0xC0,0x49,0x40,0x5F,0x40,0x40,0xC0}; const u8g_fntpgm_uint8_t fontpage_243_251_251[45] U8G_FONT_SECTION("fontpage_243_251_251") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfb,0xfb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0xe3,0xe0,0x24,0x20,0xfa,0x40,0x21, - 0x80,0x36,0x80,0x29,0xe0,0x62,0x20,0xa5,0x40,0x20,0x80,0x27,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFB,0xFB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0xE3,0xE0,0x24,0x20,0xFA,0x40,0x21, + 0x80,0x36,0x80,0x29,0xE0,0x62,0x20,0xA5,0x40,0x20,0x80,0x27,0x00}; +const u8g_fntpgm_uint8_t fontpage_244_250_250[45] U8G_FONT_SECTION("fontpage_244_250_250") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFA,0xFA,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x7F,0xE0,0x40,0x20,0x89,0x00,0x10, + 0x80,0x60,0x40,0x1F,0x80,0x04,0x00,0x04,0x00,0x04,0x00,0x7F,0xE0}; const u8g_fntpgm_uint8_t fontpage_245_239_239[45] U8G_FONT_SECTION("fontpage_245_239_239") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xef,0xef,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x81,0x00,0x45,0x20,0xf7,0xe0,0x00,0x00,0xaf, - 0xe0,0xa1,0x00,0xaf,0xe0,0x4a,0xa0,0x6a,0xa0,0x8a,0xa0,0x08,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xEF,0xEF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x81,0x00,0x45,0x20,0xF7,0xE0,0x00,0x00,0xAF, + 0xE0,0xA1,0x00,0xAF,0xE0,0x4A,0xA0,0x6A,0xA0,0x8A,0xA0,0x08,0x60}; +const u8g_fntpgm_uint8_t fontpage_246_172_172[45] U8G_FONT_SECTION("fontpage_246_172_172") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAC,0xAC,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x42,0x00,0x7B,0xE0,0x54,0x80,0xBF,0xC0,0x04, + 0x40,0x7F,0xC0,0x44,0x00,0x7F,0xE0,0x14,0x20,0x24,0xC0,0xC4,0x00}; const u8g_fntpgm_uint8_t fontpage_246_201_201[45] U8G_FONT_SECTION("fontpage_246_201_201") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc9,0xc9,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x42,0x00,0x7b,0xe0,0x94,0x80,0x7f,0xc0,0x04, - 0x00,0xff,0xe0,0x01,0x00,0x7f,0xc0,0x11,0x00,0x09,0x00,0x03,0x00}; -const u8g_fntpgm_uint8_t fontpage_247_161_161[45] U8G_FONT_SECTION("fontpage_247_161_161") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa1,0xa1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x3d,0xe0,0x52,0x80,0xff,0xe0,0x80, - 0x20,0x3f,0x80,0x20,0x80,0x3f,0xc0,0x20,0x40,0x20,0x40,0x3f,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC9,0xC9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x42,0x00,0x7B,0xE0,0x94,0x80,0x7F,0xC0,0x04, + 0x00,0xFF,0xE0,0x01,0x00,0x7F,0xC0,0x11,0x00,0x09,0x00,0x03,0x00}; +const u8g_fntpgm_uint8_t fontpage_247_128_128[45] U8G_FONT_SECTION("fontpage_247_128_128") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x42,0x00,0x7B,0xE0,0x94,0x80,0x27,0xC0,0x50, + 0x40,0x4F,0x40,0x49,0x40,0x4F,0x40,0x49,0x40,0x4F,0x40,0x40,0xC0}; +const u8g_fntpgm_uint8_t fontpage_247_177_177[45] U8G_FONT_SECTION("fontpage_247_177_177") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB1,0xB1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x3D,0xE0,0x4A,0x80,0x94,0x40,0x7F, + 0xC0,0x12,0x40,0x3B,0xC0,0x56,0x40,0x93,0xC0,0x12,0x40,0x13,0xC0}; const u8g_fntpgm_uint8_t fontpage_248_251_251[45] U8G_FONT_SECTION("fontpage_248_251_251") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfb,0xfb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x24,0x80,0x15,0x00,0xff,0xe0,0x15,0x00,0x24, - 0x80,0x40,0x40,0x04,0x00,0xff,0xe0,0x0a,0x00,0x11,0x00,0xe0,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFB,0xFB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x24,0x80,0x15,0x00,0xFF,0xE0,0x15,0x00,0x24, + 0x80,0x40,0x40,0x04,0x00,0xFF,0xE0,0x0A,0x00,0x11,0x00,0xE0,0xE0}; +const u8g_fntpgm_uint8_t fontpage_250_162_162[45] U8G_FONT_SECTION("fontpage_250_162_162") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA2,0xA2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x7F,0xC0,0x04,0x00,0xFF,0xE0,0x91, + 0x20,0x3E,0x00,0x08,0x80,0x7F,0xC0,0x04,0x40,0x24,0x80,0xCC,0x60}; const u8g_fntpgm_uint8_t fontpage_250_171_171[45] U8G_FONT_SECTION("fontpage_250_171_171") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xab,0xab,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0x51,0x40,0x5d,0x80,0x51,0x20,0xfd, - 0xe0,0x08,0x80,0x3f,0x00,0x08,0x80,0x7f,0xc0,0x24,0x80,0xcc,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAB,0xAB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x51,0x40,0x5D,0x80,0x51,0x20,0xFD, + 0xE0,0x08,0x80,0x3F,0x00,0x08,0x80,0x7F,0xC0,0x24,0x80,0xCC,0x60}; const u8g_fntpgm_uint8_t fontpage_253_162_162[45] U8G_FONT_SECTION("fontpage_253_162_162") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa2,0xa2,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x00,0x27,0xc0,0x41,0x00,0x51,0x00,0xe1, - 0x00,0x21,0x00,0x41,0x00,0xf1,0x00,0x01,0x00,0x31,0x00,0xcf,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA2,0xA2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x00,0x27,0xC0,0x41,0x00,0x51,0x00,0xE1, + 0x00,0x21,0x00,0x41,0x00,0xF1,0x00,0x01,0x00,0x31,0x00,0xCF,0xE0}; +const u8g_fntpgm_uint8_t fontpage_253_167_167[45] U8G_FONT_SECTION("fontpage_253_167_167") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA7,0xA7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x2F,0xC0,0x22,0x40,0x4A,0x40,0x52,0x80,0xE2, + 0xE0,0x22,0x20,0x42,0x20,0xF5,0x40,0x0C,0x80,0x35,0x40,0xCA,0x20}; const u8g_fntpgm_uint8_t fontpage_253_191_191[45] U8G_FONT_SECTION("fontpage_253_191_191") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbf,0xbf,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x80,0x22,0x40,0x43,0xc0,0x4e,0x00,0xe3, - 0xe0,0x2e,0x00,0x42,0x40,0xf2,0x80,0x09,0x20,0x32,0xa0,0xcc,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBF,0xBF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x80,0x22,0x40,0x43,0xC0,0x4E,0x00,0xE3, + 0xE0,0x2E,0x00,0x42,0x40,0xF2,0x80,0x09,0x20,0x32,0xA0,0xCC,0x60}; const u8g_fntpgm_uint8_t fontpage_253_198_198[45] U8G_FONT_SECTION("fontpage_253_198_198") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x00,0x27,0xe0,0x44,0xa0,0x54,0xa0,0xe4, - 0xa0,0x27,0xe0,0x44,0xa0,0xf4,0xa0,0x04,0xa0,0x37,0xe0,0xc4,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x00,0x27,0xE0,0x44,0xA0,0x54,0xA0,0xE4, + 0xA0,0x27,0xE0,0x44,0xA0,0xF4,0xA0,0x04,0xA0,0x37,0xE0,0xC4,0x20}; const u8g_fntpgm_uint8_t fontpage_253_200_200[45] U8G_FONT_SECTION("fontpage_253_200_200") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x00,0x23,0xc0,0x54,0x40,0xea,0x80,0x21, - 0x00,0x42,0x80,0xec,0x60,0x01,0x00,0x30,0xc0,0xc3,0x00,0x00,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC8,0xC8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0x23,0xC0,0x54,0x40,0xEA,0x80,0x21, + 0x00,0x42,0x80,0xEC,0x60,0x01,0x00,0x30,0xC0,0xC3,0x00,0x00,0xC0}; +const u8g_fntpgm_uint8_t fontpage_253_211_211[45] U8G_FONT_SECTION("fontpage_253_211_211") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD3,0xD3,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x21,0x00,0x4F,0xE0,0x51,0x00,0xE7, + 0xC0,0x20,0x00,0x47,0xC0,0xF4,0x40,0x0C,0x40,0x37,0xC0,0xC4,0x40}; +const u8g_fntpgm_uint8_t fontpage_253_217_217[45] U8G_FONT_SECTION("fontpage_253_217_217") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD9,0xD9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x21,0x00,0x42,0x80,0x54,0x40,0xE8, + 0x20,0x27,0xC0,0x40,0x00,0xF7,0xC0,0x0C,0x40,0x34,0x40,0xC7,0xC0}; const u8g_fntpgm_uint8_t fontpage_253_223_223[45] U8G_FONT_SECTION("fontpage_253_223_223") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xdf,0xdf,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x2f,0xe0,0x42,0x00,0x54,0x40,0xef, - 0xe0,0x22,0xa0,0x42,0x80,0xf2,0x80,0x02,0xa0,0x34,0xa0,0xc8,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDF,0xDF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x2F,0xE0,0x42,0x00,0x54,0x40,0xEF, + 0xE0,0x22,0xA0,0x42,0x80,0xF2,0x80,0x02,0xA0,0x34,0xA0,0xC8,0xE0}; const u8g_fntpgm_uint8_t fontpage_253_231_231[45] U8G_FONT_SECTION("fontpage_253_231_231") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe7,0xe7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x24,0x80,0x26,0xa0,0x45,0xc0,0x54,0x80,0xe7, - 0xe0,0x24,0x80,0x45,0xc0,0xf6,0xa0,0x04,0x80,0x34,0x80,0xc7,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE7,0xE7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x24,0x80,0x26,0xA0,0x45,0xC0,0x54,0x80,0xE7, + 0xE0,0x24,0x80,0x45,0xC0,0xF6,0xA0,0x04,0x80,0x34,0x80,0xC7,0xE0}; const u8g_fntpgm_uint8_t fontpage_253_234_234[45] U8G_FONT_SECTION("fontpage_253_234_234") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xea,0xea,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x27,0xa0,0x49,0x40,0x57,0xe0,0xe1, - 0x00,0x23,0xe0,0x46,0x20,0xf3,0xe0,0x0a,0x20,0x33,0xe0,0xc2,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xEA,0xEA,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x27,0xA0,0x49,0x40,0x57,0xE0,0xE1, + 0x00,0x23,0xE0,0x46,0x20,0xF3,0xE0,0x0A,0x20,0x33,0xE0,0xC2,0x20}; const u8g_fntpgm_uint8_t fontpage_253_237_237[45] U8G_FONT_SECTION("fontpage_253_237_237") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xed,0xed,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x27,0xc0,0x41,0x00,0x57,0xe0,0xe4, - 0xa0,0x2a,0x80,0x44,0x80,0xef,0xe0,0x01,0x00,0x32,0xc0,0xcc,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xED,0xED,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x27,0xC0,0x41,0x00,0x57,0xE0,0xE4, + 0xA0,0x2A,0x80,0x44,0x80,0xEF,0xE0,0x01,0x00,0x32,0xC0,0xCC,0x20}; const u8g_fntpgm_uint8_t fontpage_253_255_255[45] U8G_FONT_SECTION("fontpage_253_255_255") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x27,0xc0,0x20,0x40,0x43,0xc0,0xf0,0x40,0x2f, - 0xe0,0x41,0x20,0xf5,0x40,0x03,0x80,0x35,0x40,0xc9,0x20,0x03,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x27,0xC0,0x20,0x40,0x43,0xC0,0xF0,0x40,0x2F, + 0xE0,0x41,0x20,0xF5,0x40,0x03,0x80,0x35,0x40,0xC9,0x20,0x03,0x00}; const u8g_fntpgm_uint8_t fontpage_254_150_150[45] U8G_FONT_SECTION("fontpage_254_150_150") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x96,0x96,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x2f,0xe0,0x48,0x20,0x5f,0xe0,0xe8, - 0x00,0x2f,0xe0,0x4a,0xa0,0xff,0xe0,0x0a,0xa0,0x3a,0xa0,0xc8,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x96,0x96,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x2F,0xE0,0x48,0x20,0x5F,0xE0,0xE8, + 0x00,0x2F,0xE0,0x4A,0xA0,0xFF,0xE0,0x0A,0xA0,0x3A,0xA0,0xC8,0x60}; const u8g_fntpgm_uint8_t fontpage_254_186_186[45] U8G_FONT_SECTION("fontpage_254_186_186") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xba,0xba,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x41,0x00,0x41,0x00,0x7b,0xc0,0xa1,0x40,0x21, - 0x40,0xff,0xe0,0x21,0x00,0xa9,0x00,0xaa,0x80,0xfa,0x40,0x04,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBA,0xBA,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x41,0x00,0x41,0x00,0x7B,0xC0,0xA1,0x40,0x21, + 0x40,0xFF,0xE0,0x21,0x00,0xA9,0x00,0xAA,0x80,0xFA,0x40,0x04,0x20}; const u8g_fntpgm_uint8_t fontpage_254_209_209[45] U8G_FONT_SECTION("fontpage_254_209_209") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd1,0xd1,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0xff,0xc0,0x80,0x40,0x91,0x40,0xd5,0x40,0xa2, - 0x40,0x92,0x40,0xad,0x40,0xc5,0x40,0x88,0x40,0x80,0x40,0x81,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD1,0xD1,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0xFF,0xC0,0x80,0x40,0x91,0x40,0xD5,0x40,0xA2, + 0x40,0x92,0x40,0xAD,0x40,0xC5,0x40,0x88,0x40,0x80,0x40,0x81,0xC0}; const u8g_fntpgm_uint8_t fontpage_254_238_238[45] U8G_FONT_SECTION("fontpage_254_238_238") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xee,0xee,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x7f,0xc0,0x4a,0x40,0x7f,0xc0,0x04,0x00,0xff, - 0xe0,0x20,0x80,0x3f,0x80,0x20,0x80,0x3f,0x80,0x20,0x80,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xEE,0xEE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0xC0,0x4A,0x40,0x7F,0xC0,0x04,0x00,0xFF, + 0xE0,0x20,0x80,0x3F,0x80,0x20,0x80,0x3F,0x80,0x20,0x80,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_254_242_242[45] U8G_FONT_SECTION("fontpage_254_242_242") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf2,0xf2,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x7f,0xe0,0x49,0x20,0x7f,0xe0,0x04,0x40,0x3f, - 0x80,0x05,0x00,0xff,0xe0,0x30,0x80,0xdf,0x80,0x10,0x80,0x1f,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF2,0xF2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0xE0,0x49,0x20,0x7F,0xE0,0x04,0x40,0x3F, + 0x80,0x05,0x00,0xFF,0xE0,0x30,0x80,0xDF,0x80,0x10,0x80,0x1F,0x80}; +const u8g_fntpgm_uint8_t fontpage_256_133_133[45] U8G_FONT_SECTION("fontpage_256_133_133") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x85,0x85,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x3F,0x40,0x04,0x80,0x05,0x00,0xFF, + 0xE0,0x08,0x00,0x3F,0x80,0xD0,0x80,0x1F,0x80,0x10,0x80,0x1F,0x80}; const u8g_fntpgm_uint8_t fontpage_256_234_234[45] U8G_FONT_SECTION("fontpage_256_234_234") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xea,0xea,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x40,0xfa,0x80,0x57,0xc0,0x54,0x40,0x74, - 0x40,0x57,0xc0,0x71,0x00,0x5a,0xa0,0xf6,0xa0,0x1a,0x40,0x11,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xEA,0xEA,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x40,0xFA,0x80,0x57,0xC0,0x54,0x40,0x74, + 0x40,0x57,0xC0,0x71,0x00,0x5A,0xA0,0xF6,0xA0,0x1A,0x40,0x11,0xC0}; +const u8g_fntpgm_uint8_t fontpage_257_253_253[45] U8G_FONT_SECTION("fontpage_257_253_253") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFD,0xFD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x49,0x40,0xFD,0x80,0x01,0x20,0x7D, + 0xE0,0x44,0x00,0x7D,0x40,0x45,0x80,0x7D,0x20,0x45,0x20,0x4D,0xE0}; const u8g_fntpgm_uint8_t fontpage_259_234_234[34] U8G_FONT_SECTION("fontpage_259_234_234") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xea,0xea,0x00,0x0a,0xff,0x00, - 0x00,0x07,0x0b,0x0b,0x0c,0x02,0xff,0x20,0xfe,0x82,0x82,0xfe,0x82,0xfe,0x82,0x82, - 0xfe,0x82}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xEA,0xEA,0x00,0x0A,0xFF,0x00, + 0x00,0x07,0x0B,0x0B,0x0C,0x02,0xFF,0x20,0xFE,0x82,0x82,0xFE,0x82,0xFE,0x82,0x82, + 0xFE,0x82}; +const u8g_fntpgm_uint8_t fontpage_259_243_243[45] U8G_FONT_SECTION("fontpage_259_243_243") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF3,0xF3,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0xC0,0x08,0x00,0x11,0x00,0x20,0x80,0x7F, + 0xC0,0x04,0x00,0x04,0x00,0x3F,0x80,0x04,0x00,0x04,0x00,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_263_220_220[45] U8G_FONT_SECTION("fontpage_263_220_220") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xdc,0xdc,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0xff,0xe0,0x11,0x00,0x01,0xc0,0x7e, - 0x80,0x28,0x80,0x15,0x00,0xff,0xe0,0x15,0x00,0x24,0x80,0xc4,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDC,0xDC,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0xFF,0xE0,0x11,0x00,0x01,0xC0,0x7E, + 0x80,0x28,0x80,0x15,0x00,0xFF,0xE0,0x15,0x00,0x24,0x80,0xC4,0x60}; const u8g_fntpgm_uint8_t fontpage_265_221_221[45] U8G_FONT_SECTION("fontpage_265_221_221") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xdd,0xdd,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0xff,0xe0,0x11,0x00,0x52,0x00,0x53, - 0xc0,0x55,0x00,0x10,0x80,0x7f,0xc0,0x4a,0x40,0x4a,0x40,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDD,0xDD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0xFF,0xE0,0x11,0x00,0x52,0x00,0x53, + 0xC0,0x55,0x00,0x10,0x80,0x7F,0xC0,0x4A,0x40,0x4A,0x40,0xFF,0xE0}; +const u8g_fntpgm_uint8_t fontpage_269_199_199[45] U8G_FONT_SECTION("fontpage_269_199_199") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC7,0xC7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x20,0x80,0x27,0xE0,0xFC,0x20,0xAA, + 0x00,0xAA,0x40,0xFB,0x80,0x22,0x00,0x2A,0x20,0x3A,0x20,0xC9,0xE0}; const u8g_fntpgm_uint8_t fontpage_272_204_204[45] U8G_FONT_SECTION("fontpage_272_204_204") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcc,0xcc,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x27,0xc0,0x40,0x00,0x80,0x00,0x10,0x00,0x2f, - 0xe0,0x60,0x80,0xa0,0x80,0x20,0x80,0x20,0x80,0x20,0x80,0x23,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x27,0xC0,0x40,0x00,0x80,0x00,0x10,0x00,0x2F, + 0xE0,0x60,0x80,0xA0,0x80,0x20,0x80,0x20,0x80,0x20,0x80,0x23,0x80}; const u8g_fntpgm_uint8_t fontpage_273_171_171[45] U8G_FONT_SECTION("fontpage_273_171_171") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xab,0xab,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x40,0x80,0x20,0x80,0xff,0xe0,0x14,0xa0,0x2c, - 0x80,0x77,0xe0,0xad,0x40,0x25,0x40,0x24,0x80,0x29,0x40,0x36,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAB,0xAB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x40,0x80,0x20,0x80,0xFF,0xE0,0x14,0xA0,0x2C, + 0x80,0x77,0xE0,0xAD,0x40,0x25,0x40,0x24,0x80,0x29,0x40,0x36,0x20}; const u8g_fntpgm_uint8_t fontpage_273_197_197[45] U8G_FONT_SECTION("fontpage_273_197_197") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc5,0xc5,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0x9f,0xe0,0x51,0x00,0x31,0x00,0xd7, - 0xc0,0x12,0x00,0xff,0xe0,0x0c,0x40,0x32,0x80,0xd1,0x00,0x18,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC5,0xC5,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x9F,0xE0,0x51,0x00,0x31,0x00,0xD7, + 0xC0,0x12,0x00,0xFF,0xE0,0x0C,0x40,0x32,0x80,0xD1,0x00,0x18,0xE0}; +const u8g_fntpgm_uint8_t fontpage_275_129_129[45] U8G_FONT_SECTION("fontpage_275_129_129") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x81,0x81,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xFF,0xE0,0x0A,0x00,0x7F,0xC0,0x4A,0x40,0x7F, + 0xC0,0x08,0x00,0xFF,0xE0,0x11,0x00,0x3A,0x00,0x0F,0x00,0x70,0xC0}; const u8g_fntpgm_uint8_t fontpage_275_210_210[45] U8G_FONT_SECTION("fontpage_275_210_210") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd2,0xd2,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x00,0xff,0x10,0x00,0x1f,0x00,0x22,0x00,0x7f,0xc0,0xa4, - 0x40,0x3f,0xc0,0x24,0x40,0x3f,0xc0,0x24,0x40,0x45,0x40,0x80,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD2,0xD2,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x00,0xFF,0x10,0x00,0x1F,0x00,0x22,0x00,0x7F,0xC0,0xA4, + 0x40,0x3F,0xC0,0x24,0x40,0x3F,0xC0,0x24,0x40,0x45,0x40,0x80,0x80}; const u8g_fntpgm_uint8_t fontpage_279_161_161[45] U8G_FONT_SECTION("fontpage_279_161_161") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa1,0xa1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x41,0x00,0x21,0x00,0x01,0x00,0x0f,0xe0,0xe1, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA1,0xA1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x41,0x00,0x21,0x00,0x01,0x00,0x0F,0xE0,0xE1, 0x00,0x21,0x00,0x21,0x00,0x29,0x00,0x31,0x00,0x21,0x00,0x01,0x00}; const u8g_fntpgm_uint8_t fontpage_279_174_174[45] U8G_FONT_SECTION("fontpage_279_174_174") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xae,0xae,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x42,0x00,0x21,0x40,0x05,0x40,0x04,0x40,0xe4, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAE,0xAE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x42,0x00,0x21,0x40,0x05,0x40,0x04,0x40,0xE4, 0x40,0x22,0x80,0x22,0x80,0x29,0x00,0x32,0x80,0x24,0x40,0x08,0x20}; const u8g_fntpgm_uint8_t fontpage_279_190_190[45] U8G_FONT_SECTION("fontpage_279_190_190") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbe,0xbe,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x47,0x80,0x24,0x80,0x04,0x80,0x08,0xe0,0xe0, - 0x00,0x2f,0xc0,0x24,0x40,0x22,0x80,0x31,0x00,0x22,0x80,0x1c,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBE,0xBE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x47,0x80,0x24,0x80,0x04,0x80,0x08,0xE0,0xE0, + 0x00,0x2F,0xC0,0x24,0x40,0x22,0x80,0x31,0x00,0x22,0x80,0x1C,0x60}; const u8g_fntpgm_uint8_t fontpage_279_213_213[45] U8G_FONT_SECTION("fontpage_279_213_213") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd5,0xd5,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x41,0x40,0x21,0x20,0x1f,0xe0,0x01,0x00,0xef, - 0x00,0x25,0x00,0x25,0x00,0x24,0xa0,0x26,0xa0,0x38,0x60,0x20,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD5,0xD5,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x41,0x40,0x21,0x20,0x1F,0xE0,0x01,0x00,0xEF, + 0x00,0x25,0x00,0x25,0x00,0x24,0xA0,0x26,0xA0,0x38,0x60,0x20,0x20}; const u8g_fntpgm_uint8_t fontpage_279_239_239[45] U8G_FONT_SECTION("fontpage_279_239_239") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xef,0xef,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x47,0xc0,0x24,0x40,0x04,0x40,0x07,0xc0,0xe0, - 0x00,0x27,0xc0,0x21,0x00,0x2f,0xe0,0x32,0x80,0x24,0x40,0x08,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xEF,0xEF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x47,0xC0,0x24,0x40,0x04,0x40,0x07,0xC0,0xE0, + 0x00,0x27,0xC0,0x21,0x00,0x2F,0xE0,0x32,0x80,0x24,0x40,0x08,0x20}; const u8g_fntpgm_uint8_t fontpage_279_247_247[45] U8G_FONT_SECTION("fontpage_279_247_247") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf7,0xf7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x41,0x00,0x2f,0xe0,0x21,0x00,0x07,0xc0,0xe1, - 0x00,0x2f,0xe0,0x24,0x40,0x27,0xc0,0x24,0x40,0x37,0xc0,0x24,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF7,0xF7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x41,0x00,0x2F,0xE0,0x21,0x00,0x07,0xC0,0xE1, + 0x00,0x2F,0xE0,0x24,0x40,0x27,0xC0,0x24,0x40,0x37,0xC0,0x24,0x40}; +const u8g_fntpgm_uint8_t fontpage_279_251_251[45] U8G_FONT_SECTION("fontpage_279_251_251") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFB,0xFB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x41,0x00,0x27,0xC0,0x01,0x00,0xEF,0xE0,0x22, + 0xA0,0x25,0x80,0x22,0x80,0x2F,0xE0,0x31,0x80,0x22,0x40,0x0C,0x20}; const u8g_fntpgm_uint8_t fontpage_280_131_131[45] U8G_FONT_SECTION("fontpage_280_131_131") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x83,0x83,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x4f,0xe0,0x29,0x20,0x0b,0xa0,0xe9,0x20,0x2f, - 0xe0,0x28,0x20,0x2b,0xa0,0x2a,0xa0,0x3b,0xa0,0x28,0x20,0x10,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x83,0x83,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x4F,0xE0,0x29,0x20,0x0B,0xA0,0xE9,0x20,0x2F, + 0xE0,0x28,0x20,0x2B,0xA0,0x2A,0xA0,0x3B,0xA0,0x28,0x20,0x10,0xE0}; const u8g_fntpgm_uint8_t fontpage_282_165_165[45] U8G_FONT_SECTION("fontpage_282_165_165") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa5,0xa5,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xf9,0x00,0x89,0x00,0xa9,0xe0,0xa9,0x40,0xab, - 0x40,0xad,0x40,0xa9,0x40,0x21,0x40,0x50,0x80,0x49,0x40,0x8a,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA5,0xA5,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xF9,0x00,0x89,0x00,0xA9,0xE0,0xA9,0x40,0xAB, + 0x40,0xAD,0x40,0xA9,0x40,0x21,0x40,0x50,0x80,0x49,0x40,0x8A,0x20}; +const u8g_fntpgm_uint8_t fontpage_282_170_170[45] U8G_FONT_SECTION("fontpage_282_170_170") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAA,0xAA,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x0A,0x00,0x35,0x80,0xDF,0x60,0x01, + 0x00,0x3F,0x80,0x24,0x80,0x24,0x80,0x2A,0x80,0x11,0x00,0x60,0xC0}; +const u8g_fntpgm_uint8_t fontpage_282_247_247[45] U8G_FONT_SECTION("fontpage_282_247_247") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF7,0xF7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x10,0x00,0x13,0xC0,0x7C,0x40,0x10,0x40,0xFF, + 0xC0,0x12,0x00,0x52,0x20,0x5E,0x20,0x53,0xE0,0xB0,0x00,0x8F,0xE0}; +const u8g_fntpgm_uint8_t fontpage_283_133_133[45] U8G_FONT_SECTION("fontpage_283_133_133") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x85,0x85,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x17,0xC0,0x11,0x40,0x7D,0x40,0x12,0xC0,0xFC, + 0x00,0x13,0xC0,0x5E,0x40,0x52,0x40,0x73,0xC0,0x98,0x00,0x87,0xE0}; +const u8g_fntpgm_uint8_t fontpage_283_221_221[45] U8G_FONT_SECTION("fontpage_283_221_221") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDD,0xDD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7B,0xE0,0x4A,0x00,0x4A,0x00,0x7B,0xE0,0x12, + 0x20,0x52,0x20,0x5A,0x20,0x53,0xE0,0x52,0x00,0x5E,0x00,0xE3,0xE0}; +const u8g_fntpgm_uint8_t fontpage_286_236_236[45] U8G_FONT_SECTION("fontpage_286_236_236") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xEC,0xEC,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0xF7,0xC0,0x41,0x00,0x6F,0xE0,0xA2, + 0x00,0xF7,0xC0,0x20,0x40,0x3A,0x80,0xE1,0x00,0x20,0x80,0x20,0x80}; +const u8g_fntpgm_uint8_t fontpage_286_239_239[45] U8G_FONT_SECTION("fontpage_286_239_239") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xEF,0xEF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x42,0x00,0x42,0x00,0xFB,0xE0,0x42,0x20,0xA5, + 0x40,0xF9,0x00,0x21,0x00,0x3A,0x80,0xE2,0x80,0x24,0x40,0x28,0x20}; const u8g_fntpgm_uint8_t fontpage_286_244_244[45] U8G_FONT_SECTION("fontpage_286_244_244") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf4,0xf4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x80,0xf8,0x80,0x47,0xe0,0x64,0xa0,0xa4, - 0xa0,0xfc,0xa0,0x27,0xe0,0x3c,0xa0,0xe4,0xa0,0x27,0xe0,0x24,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF4,0xF4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x80,0xF8,0x80,0x47,0xE0,0x64,0xA0,0xA4, + 0xA0,0xFC,0xA0,0x27,0xE0,0x3C,0xA0,0xE4,0xA0,0x27,0xE0,0x24,0x20}; const u8g_fntpgm_uint8_t fontpage_286_253_253[45] U8G_FONT_SECTION("fontpage_286_253_253") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfd,0xfd,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0x7d,0x40,0x11,0x20,0xff,0xe0,0x21, - 0x00,0xfd,0x20,0x51,0x40,0x7c,0x80,0x10,0xa0,0xfd,0x60,0x12,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFD,0xFD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x7D,0x40,0x11,0x20,0xFF,0xE0,0x21, + 0x00,0xFD,0x20,0x51,0x40,0x7C,0x80,0x10,0xA0,0xFD,0x60,0x12,0x20}; const u8g_fntpgm_uint8_t fontpage_287_145_145[45] U8G_FONT_SECTION("fontpage_287_145_145") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x91,0x91,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x23,0xc0,0xfa,0x40,0x43,0xc0,0x60,0x00,0xa7, - 0xe0,0xfa,0x40,0x23,0x40,0x3a,0xc0,0xe2,0x60,0x2f,0xc0,0x20,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x91,0x91,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x23,0xC0,0xFA,0x40,0x43,0xC0,0x60,0x00,0xA7, + 0xE0,0xFA,0x40,0x23,0x40,0x3A,0xC0,0xE2,0x60,0x2F,0xC0,0x20,0x40}; const u8g_fntpgm_uint8_t fontpage_287_147_147[45] U8G_FONT_SECTION("fontpage_287_147_147") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x93,0x93,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x41,0x00,0x42,0x80,0xf4,0x40,0x4b,0xa0,0xa0, - 0x00,0xfe,0x20,0x2a,0xa0,0x3e,0xa0,0xea,0xa0,0x2e,0xa0,0x2a,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x93,0x93,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x41,0x00,0x42,0x80,0xF4,0x40,0x4B,0xA0,0xA0, + 0x00,0xFE,0x20,0x2A,0xA0,0x3E,0xA0,0xEA,0xA0,0x2E,0xA0,0x2A,0x60}; const u8g_fntpgm_uint8_t fontpage_287_185_185[45] U8G_FONT_SECTION("fontpage_287_185_185") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb9,0xb9,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x41,0x00,0x21,0x00,0x2f,0xe0,0x01,0x20,0xe1, - 0x20,0x21,0x20,0x22,0x20,0x24,0x20,0x28,0xc0,0x50,0x00,0x8f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB9,0xB9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x41,0x00,0x21,0x00,0x2F,0xE0,0x01,0x20,0xE1, + 0x20,0x21,0x20,0x22,0x20,0x24,0x20,0x28,0xC0,0x50,0x00,0x8F,0xE0}; +const u8g_fntpgm_uint8_t fontpage_287_193_193[45] U8G_FONT_SECTION("fontpage_287_193_193") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC1,0xC1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x40,0xC0,0x27,0x00,0x21,0x00,0x01,0x00,0xEF, + 0xE0,0x21,0x00,0x21,0x00,0x21,0x00,0x21,0x00,0x50,0x00,0x8F,0xE0}; const u8g_fntpgm_uint8_t fontpage_287_208_209[73] U8G_FONT_SECTION("fontpage_287_208_209") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd0,0xd1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x47,0xc0,0x20,0x00,0x20,0x00,0x0f,0xe0,0xe2, - 0x00,0x22,0x80,0x24,0x40,0x2f,0xa0,0x24,0x20,0x50,0x00,0x8f,0xe0,0x0b,0x0b,0x16, - 0x0c,0x00,0xff,0x40,0xc0,0x27,0x00,0x24,0x00,0x07,0xe0,0xe4,0x80,0x24,0x80,0x24, - 0x80,0x24,0x80,0x28,0x80,0x50,0x00,0x8f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD0,0xD1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x47,0xC0,0x20,0x00,0x20,0x00,0x0F,0xE0,0xE2, + 0x00,0x22,0x80,0x24,0x40,0x2F,0xA0,0x24,0x20,0x50,0x00,0x8F,0xE0,0x0B,0x0B,0x16, + 0x0C,0x00,0xFF,0x40,0xC0,0x27,0x00,0x24,0x00,0x07,0xE0,0xE4,0x80,0x24,0x80,0x24, + 0x80,0x24,0x80,0x28,0x80,0x50,0x00,0x8F,0xE0}; const u8g_fntpgm_uint8_t fontpage_287_212_212[45] U8G_FONT_SECTION("fontpage_287_212_212") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd4,0xd4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x40,0x60,0x27,0x80,0x24,0x00,0x07,0xe0,0xe6, - 0x20,0x25,0x40,0x24,0x80,0x29,0x40,0x26,0x20,0x50,0x00,0x8f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD4,0xD4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x40,0x60,0x27,0x80,0x24,0x00,0x07,0xE0,0xE6, + 0x20,0x25,0x40,0x24,0x80,0x29,0x40,0x26,0x20,0x50,0x00,0x8F,0xE0}; const u8g_fntpgm_uint8_t fontpage_287_216_216[45] U8G_FONT_SECTION("fontpage_287_216_216") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd8,0xd8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x4f,0xe0,0x20,0x80,0x21,0x00,0x01,0x00,0xe3, - 0x40,0x25,0x20,0x29,0x20,0x21,0x00,0x21,0x00,0x50,0x00,0x8f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD8,0xD8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x4F,0xE0,0x20,0x80,0x21,0x00,0x01,0x00,0xE3, + 0x40,0x25,0x20,0x29,0x20,0x21,0x00,0x21,0x00,0x50,0x00,0x8F,0xE0}; const u8g_fntpgm_uint8_t fontpage_287_219_219[45] U8G_FONT_SECTION("fontpage_287_219_219") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xdb,0xdb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x44,0x80,0x24,0x80,0x2f,0xc0,0x04,0x80,0xe4, - 0x80,0x3f,0xe0,0x24,0x80,0x24,0x80,0x28,0x80,0x50,0x80,0x8f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDB,0xDB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x44,0x80,0x24,0x80,0x2F,0xC0,0x04,0x80,0xE4, + 0x80,0x3F,0xE0,0x24,0x80,0x24,0x80,0x28,0x80,0x50,0x80,0x8F,0xE0}; +const u8g_fntpgm_uint8_t fontpage_287_222_222[45] U8G_FONT_SECTION("fontpage_287_222_222") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDE,0xDE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x42,0x00,0x2F,0xE0,0x22,0x00,0x05,0x00,0xEF, + 0xC0,0x21,0x00,0x2F,0xE0,0x21,0x00,0x21,0x00,0x51,0x00,0x8F,0xE0}; +const u8g_fntpgm_uint8_t fontpage_287_247_247[45] U8G_FONT_SECTION("fontpage_287_247_247") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF7,0xF7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x41,0x00,0x29,0x20,0x25,0x40,0x01,0x00,0xEF, + 0xE0,0x21,0x00,0x23,0x80,0x25,0x40,0x29,0x20,0x51,0x00,0x8F,0xE0}; const u8g_fntpgm_uint8_t fontpage_288_128_128[45] U8G_FONT_SECTION("fontpage_288_128_128") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x8f,0xc0,0x48,0x40,0x4f,0xc0,0x08,0x40,0xcf, - 0xc0,0x48,0x00,0x4b,0x40,0x48,0x80,0x4e,0x40,0xb0,0x00,0x8f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x8F,0xC0,0x48,0x40,0x4F,0xC0,0x08,0x40,0xCF, + 0xC0,0x48,0x00,0x4B,0x40,0x48,0x80,0x4E,0x40,0xB0,0x00,0x8F,0xE0}; const u8g_fntpgm_uint8_t fontpage_288_137_137[45] U8G_FONT_SECTION("fontpage_288_137_137") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x45,0x00,0x25,0x00,0x27,0xc0,0x09,0x00,0xef, - 0xe0,0x22,0x80,0x22,0xa0,0x24,0xa0,0x28,0x60,0x50,0x00,0x8f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x45,0x00,0x25,0x00,0x27,0xC0,0x09,0x00,0xEF, + 0xE0,0x22,0x80,0x22,0xA0,0x24,0xA0,0x28,0x60,0x50,0x00,0x8F,0xE0}; const u8g_fntpgm_uint8_t fontpage_288_159_159[45] U8G_FONT_SECTION("fontpage_288_159_159") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9f,0x9f,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x41,0x00,0x3f,0xe0,0x21,0x00,0x0f,0xe0,0xe9, - 0x20,0x2f,0xe0,0x23,0x80,0x25,0x40,0x29,0x20,0x51,0x00,0x8f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9F,0x9F,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x41,0x00,0x3F,0xE0,0x21,0x00,0x0F,0xE0,0xE9, + 0x20,0x2F,0xE0,0x23,0x80,0x25,0x40,0x29,0x20,0x51,0x00,0x8F,0xE0}; const u8g_fntpgm_uint8_t fontpage_289_232_232[45] U8G_FONT_SECTION("fontpage_289_232_232") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe8,0xe8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0xe0,0xff,0x20,0x45,0x20,0x29,0x40,0xff, - 0x80,0x01,0x40,0x7d,0x20,0x45,0x20,0x45,0xa0,0x7d,0x40,0x45,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE8,0xE8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0xE0,0xFF,0x20,0x45,0x20,0x29,0x40,0xFF, + 0x80,0x01,0x40,0x7D,0x20,0x45,0x20,0x45,0xA0,0x7D,0x40,0x45,0x00}; +const u8g_fntpgm_uint8_t fontpage_290_205_205[45] U8G_FONT_SECTION("fontpage_290_205_205") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCD,0xCD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xFB,0xE0,0x50,0x20,0x50,0x20,0xF8,0x20,0xAB, + 0xE0,0xDA,0x00,0x8A,0x00,0xFA,0x00,0x8A,0x20,0xFA,0x20,0x8B,0xE0}; const u8g_fntpgm_uint8_t fontpage_291_202_202[45] U8G_FONT_SECTION("fontpage_291_202_202") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xca,0xca,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x1f,0xc0,0xe2,0x80,0xa9,0x00,0x72,0x80,0xfd, - 0x60,0x31,0x00,0x6f,0xc0,0xa1,0x00,0xaf,0xe0,0x21,0x00,0x21,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCA,0xCA,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x1F,0xC0,0xE2,0x80,0xA9,0x00,0x72,0x80,0xFD, + 0x60,0x31,0x00,0x6F,0xC0,0xA1,0x00,0xAF,0xE0,0x21,0x00,0x21,0x00}; const u8g_fntpgm_uint8_t fontpage_291_205_205[45] U8G_FONT_SECTION("fontpage_291_205_205") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcd,0xcd,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x7f,0xc0,0x04,0x00,0xff,0xe0,0x24,0x80,0x3f, - 0x80,0x24,0x80,0x3f,0x80,0x04,0x00,0x7f,0xc0,0x04,0x00,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCD,0xCD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0xC0,0x04,0x00,0xFF,0xE0,0x24,0x80,0x3F, + 0x80,0x24,0x80,0x3F,0x80,0x04,0x00,0x7F,0xC0,0x04,0x00,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_291_207_207[45] U8G_FONT_SECTION("fontpage_291_207_207") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcf,0xcf,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x3f,0x80,0x20,0x80,0x3f,0x80,0x20,0x80,0xff, - 0xe0,0x24,0x80,0x3f,0x80,0x24,0x80,0x7f,0xc0,0x04,0x00,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCF,0xCF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x3F,0x80,0x20,0x80,0x3F,0x80,0x20,0x80,0xFF, + 0xE0,0x24,0x80,0x3F,0x80,0x24,0x80,0x7F,0xC0,0x04,0x00,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_297_136_136[45] U8G_FONT_SECTION("fontpage_297_136_136") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x40,0x80,0x40,0x80,0x78,0x80,0x80,0x80,0xfb, - 0xe0,0x20,0x80,0xf8,0x80,0x20,0x80,0x28,0x80,0x30,0x80,0x20,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x40,0x80,0x40,0x80,0x78,0x80,0x80,0x80,0xFB, + 0xE0,0x20,0x80,0xF8,0x80,0x20,0x80,0x28,0x80,0x30,0x80,0x20,0x80}; const u8g_fntpgm_uint8_t fontpage_297_174_174[45] U8G_FONT_SECTION("fontpage_297_174_174") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xae,0xae,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x40,0x00,0x47,0xc0,0x79,0x40,0x81,0x40,0xf9, - 0x40,0x27,0xc0,0xfa,0x40,0x22,0x40,0x2a,0x40,0x32,0x40,0x2f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAE,0xAE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x40,0x00,0x47,0xC0,0x79,0x40,0x81,0x40,0xF9, + 0x40,0x27,0xC0,0xFA,0x40,0x22,0x40,0x2A,0x40,0x32,0x40,0x2F,0xE0}; const u8g_fntpgm_uint8_t fontpage_298_153_153[45] U8G_FONT_SECTION("fontpage_298_153_153") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x99,0x99,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x42,0x80,0x4f,0xe0,0x72,0x80,0x82,0x80,0xef, - 0xe0,0x40,0x00,0xf7,0xc0,0x44,0x40,0x47,0xc0,0x54,0x40,0x67,0xc0}; -const u8g_fntpgm_uint8_t fontpage_298_174_174[45] U8G_FONT_SECTION("fontpage_298_174_174") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xae,0xae,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x5c,0x80,0x47,0xe0,0x68,0xa0,0x8b,0xe0,0xfc, - 0xa0,0x47,0xe0,0xe4,0x80,0x57,0xe0,0x48,0x80,0x6c,0x80,0x53,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x99,0x99,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x42,0x80,0x4F,0xE0,0x72,0x80,0x82,0x80,0xEF, + 0xE0,0x40,0x00,0xF7,0xC0,0x44,0x40,0x47,0xC0,0x54,0x40,0x67,0xC0}; +const u8g_fntpgm_uint8_t fontpage_298_220_220[45] U8G_FONT_SECTION("fontpage_298_220_220") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDC,0xDC,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x41,0x00,0x4F,0xE0,0x72,0x80,0x8F,0xE0,0xF4, + 0x40,0x27,0xC0,0xF4,0x40,0x27,0xC0,0x2A,0x80,0x32,0xA0,0x2C,0x60}; const u8g_fntpgm_uint8_t fontpage_298_255_255[45] U8G_FONT_SECTION("fontpage_298_255_255") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x21,0x00,0x22,0x00,0x24,0x00,0x28,0x00,0x30, - 0x00,0xff,0xc0,0x28,0x00,0x24,0x00,0x22,0x00,0x29,0x00,0x30,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x21,0x00,0x22,0x00,0x24,0x00,0x28,0x00,0x30, + 0x00,0xFF,0xC0,0x28,0x00,0x24,0x00,0x22,0x00,0x29,0x00,0x30,0xC0}; const u8g_fntpgm_uint8_t fontpage_299_237_237[45] U8G_FONT_SECTION("fontpage_299_237_237") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xed,0xed,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x47,0xe0,0x20,0x20,0x82,0x20,0x82,0x20,0xbf, - 0xa0,0x86,0x20,0x8a,0x20,0x92,0x20,0xa2,0x20,0x86,0x20,0x80,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xED,0xED,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x47,0xE0,0x20,0x20,0x82,0x20,0x82,0x20,0xBF, + 0xA0,0x86,0x20,0x8A,0x20,0x92,0x20,0xA2,0x20,0x86,0x20,0x80,0xE0}; +const u8g_fntpgm_uint8_t fontpage_299_242_242[45] U8G_FONT_SECTION("fontpage_299_242_242") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF2,0xF2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x4F,0xE0,0x20,0x20,0x84,0x20,0x84,0x20,0xBF, + 0xA0,0x84,0x20,0x8E,0x20,0x95,0x20,0xA4,0xA0,0x84,0x20,0x80,0xE0}; const u8g_fntpgm_uint8_t fontpage_299_244_244[45] U8G_FONT_SECTION("fontpage_299_244_244") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf4,0xf4,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x4f,0xc0,0x20,0x40,0x80,0x40,0x9e,0x40,0x92, - 0x40,0x9e,0x40,0x92,0x40,0x92,0x40,0x9e,0x40,0x80,0x40,0x81,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF4,0xF4,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x4F,0xC0,0x20,0x40,0x80,0x40,0x9E,0x40,0x92, + 0x40,0x9E,0x40,0x92,0x40,0x92,0x40,0x9E,0x40,0x80,0x40,0x81,0xC0}; +const u8g_fntpgm_uint8_t fontpage_300_136_136[45] U8G_FONT_SECTION("fontpage_300_136_136") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x27,0xE0,0x11,0x20,0x82,0xA0,0xBF,0xE0,0x82, + 0x20,0xBA,0xA0,0xAA,0xA0,0xB9,0x20,0x81,0x20,0xBA,0xA0,0x84,0x60}; const u8g_fntpgm_uint8_t fontpage_300_205_205[45] U8G_FONT_SECTION("fontpage_300_205_205") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcd,0xcd,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xf2,0x00,0x93,0xe0,0xa6,0x40,0xc1,0x80,0xa6, - 0x60,0x91,0x00,0x97,0xe0,0xd5,0x00,0xaf,0xe0,0x81,0x00,0x81,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCD,0xCD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xF2,0x00,0x93,0xE0,0xA6,0x40,0xC1,0x80,0xA6, + 0x60,0x91,0x00,0x97,0xE0,0xD5,0x00,0xAF,0xE0,0x81,0x00,0x81,0x00}; +const u8g_fntpgm_uint8_t fontpage_300_208_208[45] U8G_FONT_SECTION("fontpage_300_208_208") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD0,0xD0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xF7,0xC0,0x94,0x40,0xA7,0xC0,0xC4,0x40,0xA7, + 0xC0,0x95,0x00,0x95,0x20,0xD5,0x40,0xA4,0x80,0x85,0x40,0x86,0x20}; const u8g_fntpgm_uint8_t fontpage_300_228_228[45] U8G_FONT_SECTION("fontpage_300_228_228") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe4,0xe4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xf1,0x00,0x92,0x80,0xa4,0x40,0xcb,0xa0,0xa1, - 0x00,0x9f,0xe0,0x91,0x00,0xe5,0x40,0x89,0x20,0x91,0x20,0x83,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE4,0xE4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xF1,0x00,0x92,0x80,0xA4,0x40,0xCB,0xA0,0xA1, + 0x00,0x9F,0xE0,0x91,0x00,0xE5,0x40,0x89,0x20,0x91,0x20,0x83,0x00}; +const u8g_fntpgm_uint8_t fontpage_300_233_233[45] U8G_FONT_SECTION("fontpage_300_233_233") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE9,0xE9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xF1,0x00,0x92,0x80,0xA4,0x40,0xC8,0x20,0xA7, + 0xC0,0x90,0x00,0x9A,0x40,0xD5,0x40,0xA5,0x40,0x80,0x80,0x8F,0xE0}; +const u8g_fntpgm_uint8_t fontpage_301_246_246[45] U8G_FONT_SECTION("fontpage_301_246_246") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF6,0xF6,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0xC0,0x04,0x00,0xFF,0xE0,0x95,0x20,0x0E, + 0x00,0x31,0x80,0xC4,0x60,0x3F,0x80,0x01,0x00,0x0E,0x00,0x03,0x00}; +const u8g_fntpgm_uint8_t fontpage_302_128_128[45] U8G_FONT_SECTION("fontpage_302_128_128") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0xC0,0x04,0x00,0xFF,0xE0,0xB5,0xA0,0x04, + 0x00,0xFF,0xE0,0x08,0x00,0x7F,0xC0,0x4A,0x40,0x4A,0x40,0x4A,0xC0}; const u8g_fntpgm_uint8_t fontpage_302_210_210[45] U8G_FONT_SECTION("fontpage_302_210_210") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd2,0xd2,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x7f,0xc0,0x04,0x00,0x3f,0x80,0x04, - 0x00,0xff,0xe0,0x10,0x80,0x1f,0x80,0x10,0x80,0x1f,0x80,0x10,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD2,0xD2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x7F,0xC0,0x04,0x00,0x3F,0x80,0x04, + 0x00,0xFF,0xE0,0x10,0x80,0x1F,0x80,0x10,0x80,0x1F,0x80,0x10,0x80}; const u8g_fntpgm_uint8_t fontpage_302_222_222[45] U8G_FONT_SECTION("fontpage_302_222_222") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xde,0xde,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x0a,0x00,0x0a,0x00,0xfb,0xe0,0x0a,0x00,0x0a, - 0x00,0x7b,0xc0,0x0a,0x00,0x0a,0x00,0xfb,0xe0,0x0a,0x00,0x0a,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDE,0xDE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x0A,0x00,0x0A,0x00,0xFB,0xE0,0x0A,0x00,0x0A, + 0x00,0x7B,0xC0,0x0A,0x00,0x0A,0x00,0xFB,0xE0,0x0A,0x00,0x0A,0x00}; +const u8g_fntpgm_uint8_t fontpage_302_224_224[45] U8G_FONT_SECTION("fontpage_302_224_224") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x24,0x00,0x3F,0xC0,0x44,0x00,0xFF,0xE0,0x20, + 0x80,0x3F,0x80,0x0A,0x00,0xFB,0xE0,0x0A,0x00,0xFB,0xE0,0x0A,0x00}; +const u8g_fntpgm_uint8_t fontpage_302_226_226[45] U8G_FONT_SECTION("fontpage_302_226_226") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE2,0xE2,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0xFF,0xC0,0x08,0x00,0x10,0x00,0xFF,0xC0,0x92, + 0x40,0x9E,0x40,0x92,0x40,0x9E,0x40,0x92,0x40,0xFF,0xC0,0x80,0x40}; +const u8g_fntpgm_uint8_t fontpage_304_245_245[45] U8G_FONT_SECTION("fontpage_304_245_245") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF5,0xF5,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xFF,0xE0,0x04,0x00,0x3F,0x80,0x20,0x80,0x24, + 0x80,0x24,0x80,0x24,0x80,0x26,0x80,0x09,0x00,0x10,0xC0,0x60,0x40}; const u8g_fntpgm_uint8_t fontpage_304_249_249[45] U8G_FONT_SECTION("fontpage_304_249_249") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf9,0xf9,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x07,0xe0,0xf9,0x00,0x27,0xe0,0x24,0x20,0x25, - 0x20,0x25,0x20,0x25,0x20,0x3d,0x20,0xc1,0x80,0x02,0x40,0x0c,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF9,0xF9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x07,0xE0,0xF9,0x00,0x27,0xE0,0x24,0x20,0x25, + 0x20,0x25,0x20,0x25,0x20,0x3D,0x20,0xC1,0x80,0x02,0x40,0x0C,0x20}; const u8g_fntpgm_uint8_t fontpage_305_132_132[45] U8G_FONT_SECTION("fontpage_305_132_132") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x84,0x84,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xfb,0xe0,0x10,0x80,0x63,0xe0,0x22,0x20,0xfa, - 0xa0,0x2a,0xa0,0x22,0xa0,0x22,0xa0,0x22,0xa0,0x21,0x40,0x66,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x84,0x84,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xFB,0xE0,0x10,0x80,0x63,0xE0,0x22,0x20,0xFA, + 0xA0,0x2A,0xA0,0x22,0xA0,0x22,0xA0,0x22,0xA0,0x21,0x40,0x66,0x20}; +const u8g_fntpgm_uint8_t fontpage_305_145_145[45] U8G_FONT_SECTION("fontpage_305_145_145") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x91,0x91,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x13,0xE0,0x50,0x80,0x5F,0xE0,0x52,0x20,0xFE, + 0xA0,0x12,0xA0,0x56,0xA0,0x5A,0xA0,0x92,0xA0,0x21,0x40,0xC6,0x20}; const u8g_fntpgm_uint8_t fontpage_305_157_157[45] U8G_FONT_SECTION("fontpage_305_157_157") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9d,0x9d,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x23,0xe0,0xfc,0x80,0x87,0xe0,0x7a,0x20,0xca, - 0xa0,0x32,0xa0,0x4a,0xa0,0xfe,0xa0,0x4a,0xa0,0x79,0x40,0x4e,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9D,0x9D,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x23,0xE0,0xFC,0x80,0x87,0xE0,0x7A,0x20,0xCA, + 0xA0,0x32,0xA0,0x4A,0xA0,0xFE,0xA0,0x4A,0xA0,0x79,0x40,0x4E,0x20}; const u8g_fntpgm_uint8_t fontpage_305_206_206[45] U8G_FONT_SECTION("fontpage_305_206_206") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xce,0xce,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x7f,0x80,0x40,0x80,0x42,0x80,0x52,0x80,0x4c, - 0x80,0x44,0x80,0x4c,0x80,0x52,0x80,0x62,0xa0,0x80,0x60,0x80,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCE,0xCE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0x80,0x40,0x80,0x42,0x80,0x52,0x80,0x4C, + 0x80,0x44,0x80,0x4C,0x80,0x52,0x80,0x62,0xA0,0x80,0x60,0x80,0x20}; const u8g_fntpgm_uint8_t fontpage_306_241_241[45] U8G_FONT_SECTION("fontpage_306_241_241") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf1,0xf1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x44,0x00,0x47,0xc0,0x7c,0x40,0x97,0x40,0xad, - 0x40,0x25,0x40,0x27,0x40,0x24,0xc0,0x2c,0x20,0x34,0x20,0x23,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF1,0xF1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x44,0x00,0x47,0xC0,0x7C,0x40,0x97,0x40,0xAD, + 0x40,0x25,0x40,0x27,0x40,0x24,0xC0,0x2C,0x20,0x34,0x20,0x23,0xE0}; +const u8g_fntpgm_uint8_t fontpage_308_236_236[45] U8G_FONT_SECTION("fontpage_308_236_236") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xEC,0xEC,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0x80,0x00,0x80,0x10,0x80,0x11,0x00,0x21, + 0x00,0x3F,0xE0,0x00,0x20,0x00,0x20,0xFF,0x20,0x00,0x20,0x00,0xC0}; const u8g_fntpgm_uint8_t fontpage_308_241_241[45] U8G_FONT_SECTION("fontpage_308_241_241") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf1,0xf1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xf3,0xe0,0x12,0x00,0x52,0x20,0x53,0x20,0x52, - 0xa0,0x7a,0x40,0x0a,0x40,0xea,0xa0,0x0b,0x20,0x0a,0x00,0x33,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF1,0xF1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xF3,0xE0,0x12,0x00,0x52,0x20,0x53,0x20,0x52, + 0xA0,0x7A,0x40,0x0A,0x40,0xEA,0xA0,0x0B,0x20,0x0A,0x00,0x33,0xE0}; const u8g_fntpgm_uint8_t fontpage_309_216_216[45] U8G_FONT_SECTION("fontpage_309_216_216") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd8,0xd8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0xff,0xe0,0x00,0x00,0x1f,0x00,0x11, - 0x00,0x7f,0xc0,0x40,0x40,0x5f,0x40,0x51,0x40,0x5f,0x40,0x40,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD8,0xD8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0xFF,0xE0,0x00,0x00,0x1F,0x00,0x11, + 0x00,0x7F,0xC0,0x40,0x40,0x5F,0x40,0x51,0x40,0x5F,0x40,0x40,0xC0}; const u8g_fntpgm_uint8_t fontpage_317_196_196[45] U8G_FONT_SECTION("fontpage_317_196_196") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc4,0xc4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0x7f,0xc0,0x11,0x00,0xff,0xe0,0x04, - 0x00,0x3f,0x80,0x24,0x80,0x3f,0x80,0x24,0x80,0x3f,0x80,0x60,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC4,0xC4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x7F,0xC0,0x11,0x00,0xFF,0xE0,0x04, + 0x00,0x3F,0x80,0x24,0x80,0x3F,0x80,0x24,0x80,0x3F,0x80,0x60,0xC0}; +const u8g_fntpgm_uint8_t fontpage_317_222_222[45] U8G_FONT_SECTION("fontpage_317_222_222") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDE,0xDE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xF8,0x80,0xA8,0x80,0xF8,0xE0,0xA8,0x80,0xF8, + 0x80,0x23,0xE0,0xFA,0x20,0x22,0x20,0xFA,0x20,0x52,0x20,0xAB,0xE0}; +const u8g_fntpgm_uint8_t fontpage_318_208_208[45] U8G_FONT_SECTION("fontpage_318_208_208") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD0,0xD0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0xFF,0xE0,0x10,0x80,0x09,0x00,0x06, + 0x00,0x19,0x80,0xE0,0x60,0x09,0x00,0x09,0x00,0x11,0x00,0x61,0x00}; const u8g_fntpgm_uint8_t fontpage_510_154_154[30] U8G_FONT_SECTION("fontpage_510_154_154") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9a,0x9a,0x00,0x08,0x00,0x00, - 0x00,0x02,0x07,0x07,0x0c,0x06,0x01,0xc0,0xc0,0x00,0x00,0x00,0xc0,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9A,0x9A,0x00,0x08,0x00,0x00, + 0x00,0x02,0x07,0x07,0x0C,0x06,0x01,0xC0,0xC0,0x00,0x00,0x00,0xC0,0xC0}; #define FONTDATA_ITEM(page, begin, end, data) { page, begin, end, COUNT(data), data } static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { @@ -1040,70 +1468,97 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(69, 191, 191, fontpage_69_191_191), // '⊿' -- '⊿' FONTDATA_ITEM(156, 128, 128, fontpage_156_128_128), // '一' -- '一' FONTDATA_ITEM(156, 137, 139, fontpage_156_137_139), // '三' -- '下' + FONTDATA_ITEM(156, 141, 141, fontpage_156_141_141), // '不' -- '不' + FONTDATA_ITEM(156, 147, 147, fontpage_156_147_147), // '专' -- '专' FONTDATA_ITEM(156, 157, 157, fontpage_156_157_157), // '丝' -- '丝' FONTDATA_ITEM(156, 170, 170, fontpage_156_170_170), // '个' -- '个' FONTDATA_ITEM(156, 173, 173, fontpage_156_173_173), // '中' -- '中' - FONTDATA_ITEM(156, 187, 187, fontpage_156_187_187), // '主' -- '主' + FONTDATA_ITEM(156, 186, 187, fontpage_156_186_187), // '为' -- '主' + FONTDATA_ITEM(156, 201, 201, fontpage_156_201_201), // '义' -- '义' FONTDATA_ITEM(156, 203, 203, fontpage_156_203_203), // '之' -- '之' FONTDATA_ITEM(157, 134, 134, fontpage_157_134_134), // '了' -- '了' + FONTDATA_ITEM(157, 140, 140, fontpage_157_140_140), // '二' -- '二' FONTDATA_ITEM(157, 142, 142, fontpage_157_142_142), // '于' -- '于' + FONTDATA_ITEM(157, 164, 164, fontpage_157_164_164), // '交' -- '交' FONTDATA_ITEM(157, 174, 174, fontpage_157_174_174), // '亮' -- '亮' FONTDATA_ITEM(157, 206, 206, fontpage_157_206_206), // '从' -- '从' - FONTDATA_ITEM(157, 228, 228, fontpage_157_228_228), // '令' -- '令' + FONTDATA_ITEM(157, 228, 229, fontpage_157_228_229), // '令' -- '以' + FONTDATA_ITEM(157, 246, 246, fontpage_157_246_246), // '件' -- '件' FONTDATA_ITEM(157, 253, 253, fontpage_157_253_253), // '份' -- '份' FONTDATA_ITEM(158, 145, 145, fontpage_158_145_145), // '休' -- '休' + FONTDATA_ITEM(158, 160, 160, fontpage_158_160_160), // '传' -- '传' FONTDATA_ITEM(158, 205, 206, fontpage_158_205_206), // '位' -- '低' + FONTDATA_ITEM(158, 211, 211, fontpage_158_211_211), // '体' -- '体' + FONTDATA_ITEM(158, 217, 217, fontpage_158_217_217), // '余' -- '余' FONTDATA_ITEM(158, 220, 220, fontpage_158_220_220), // '作' -- '作' + FONTDATA_ITEM(158, 255, 255, fontpage_158_255_255), // '使' -- '使' FONTDATA_ITEM(159, 155, 155, fontpage_159_155_155), // '供' -- '供' + FONTDATA_ITEM(159, 181, 181, fontpage_159_181_181), // '侵' -- '侵' FONTDATA_ITEM(159, 221, 221, fontpage_159_221_221), // '保' -- '保' FONTDATA_ITEM(159, 225, 225, fontpage_159_225_225), // '信' -- '信' FONTDATA_ITEM(160, 188, 188, fontpage_160_188_188), // '值' -- '值' + FONTDATA_ITEM(160, 190, 190, fontpage_160_190_190), // '倾' -- '倾' FONTDATA_ITEM(160, 207, 207, fontpage_160_207_207), // '偏' -- '偏' FONTDATA_ITEM(160, 220, 220, fontpage_160_220_220), // '停' -- '停' FONTDATA_ITEM(161, 168, 168, fontpage_161_168_168), // '储' -- '储' + FONTDATA_ITEM(161, 207, 207, fontpage_161_207_207), // '像' -- '像' FONTDATA_ITEM(162, 197, 197, fontpage_162_197_197), // '充' -- '充' - FONTDATA_ITEM(162, 200, 200, fontpage_162_200_200), // '先' -- '先' + FONTDATA_ITEM(162, 200, 201, fontpage_162_200_201), // '先' -- '光' FONTDATA_ITEM(162, 229, 229, fontpage_162_229_229), // '入' -- '入' FONTDATA_ITEM(162, 232, 232, fontpage_162_232_232), // '全' -- '全' FONTDATA_ITEM(162, 241, 241, fontpage_162_241_241), // '共' -- '共' FONTDATA_ITEM(162, 243, 243, fontpage_162_243_243), // '关' -- '关' FONTDATA_ITEM(162, 247, 247, fontpage_162_247_247), // '具' -- '具' + FONTDATA_ITEM(163, 151, 151, fontpage_163_151_151), // '冗' -- '冗' FONTDATA_ITEM(163, 183, 183, fontpage_163_183_183), // '冷' -- '冷' FONTDATA_ITEM(163, 198, 198, fontpage_163_198_198), // '准' -- '准' - FONTDATA_ITEM(163, 201, 201, fontpage_163_201_201), // '凉' -- '凉' FONTDATA_ITEM(163, 250, 251, fontpage_163_250_251), // '出' -- '击' - FONTDATA_ITEM(164, 134, 134, fontpage_164_134_134), // '分' -- '分' + FONTDATA_ITEM(164, 134, 135, fontpage_164_134_135), // '分' -- '切' FONTDATA_ITEM(164, 155, 155, fontpage_164_155_155), // '创' -- '创' FONTDATA_ITEM(164, 157, 157, fontpage_164_157_157), // '初' -- '初' + FONTDATA_ITEM(164, 171, 171, fontpage_164_171_171), // '别' -- '别' FONTDATA_ITEM(164, 176, 176, fontpage_164_176_176), // '到' -- '到' FONTDATA_ITEM(164, 182, 183, fontpage_164_182_183), // '制' -- '刷' + FONTDATA_ITEM(164, 242, 242, fontpage_164_242_242), // '割' -- '割' FONTDATA_ITEM(165, 155, 155, fontpage_165_155_155), // '力' -- '力' - FONTDATA_ITEM(165, 160, 160, fontpage_165_160_160), // '加' -- '加' + FONTDATA_ITEM(165, 159, 160, fontpage_165_159_160), // '功' -- '加' FONTDATA_ITEM(165, 168, 168, fontpage_165_168_168), // '动' -- '动' FONTDATA_ITEM(166, 150, 150, fontpage_166_150_150), // '化' -- '化' + FONTDATA_ITEM(166, 199, 199, fontpage_166_199_199), // '升' -- '升' FONTDATA_ITEM(166, 202, 202, fontpage_166_202_202), // '半' -- '半' FONTDATA_ITEM(166, 207, 207, fontpage_166_207_207), // '协' -- '协' FONTDATA_ITEM(166, 213, 213, fontpage_166_213_213), // '单' -- '单' FONTDATA_ITEM(166, 225, 225, fontpage_166_225_225), // '卡' -- '卡' - FONTDATA_ITEM(166, 240, 240, fontpage_166_240_240), // '印' -- '印' + FONTDATA_ITEM(166, 240, 241, fontpage_166_240_241), // '印' -- '危' + FONTDATA_ITEM(166, 244, 244, fontpage_166_244_244), // '却' -- '却' FONTDATA_ITEM(166, 248, 248, fontpage_166_248_248), // '卸' -- '卸' + FONTDATA_ITEM(167, 139, 139, fontpage_167_139_139), // '压' -- '压' FONTDATA_ITEM(167, 159, 159, fontpage_167_159_159), // '原' -- '原' - FONTDATA_ITEM(167, 204, 204, fontpage_167_204_204), // '双' -- '双' + FONTDATA_ITEM(167, 204, 205, fontpage_167_204_205), // '双' -- '反' FONTDATA_ITEM(167, 214, 214, fontpage_167_214_214), // '取' -- '取' FONTDATA_ITEM(167, 216, 216, fontpage_167_216_216), // '变' -- '变' FONTDATA_ITEM(167, 240, 240, fontpage_167_240_240), // '台' -- '台' + FONTDATA_ITEM(168, 131, 131, fontpage_168_131_131), // '吃' -- '吃' FONTDATA_ITEM(168, 136, 136, fontpage_168_136_136), // '合' -- '合' - FONTDATA_ITEM(168, 142, 142, fontpage_168_142_142), // '后' -- '后' + FONTDATA_ITEM(168, 141, 142, fontpage_168_141_142), // '名' -- '后' + FONTDATA_ITEM(168, 145, 145, fontpage_168_145_145), // '向' -- '向' + FONTDATA_ITEM(168, 166, 166, fontpage_168_166_166), // '否' -- '否' FONTDATA_ITEM(168, 175, 175, fontpage_168_175_175), // '启' -- '启' + FONTDATA_ITEM(168, 202, 202, fontpage_168_202_202), // '告' -- '告' + FONTDATA_ITEM(168, 232, 232, fontpage_168_232_232), // '周' -- '周' FONTDATA_ITEM(168, 253, 253, fontpage_168_253_253), // '命' -- '命' FONTDATA_ITEM(169, 140, 140, fontpage_169_140_140), // '和' -- '和' + FONTDATA_ITEM(169, 205, 205, fontpage_169_205_205), // '响' -- '响' FONTDATA_ITEM(171, 183, 183, fontpage_171_183_183), // '喷' -- '喷' FONTDATA_ITEM(172, 180, 180, fontpage_172_180_180), // '嘴' -- '嘴' + FONTDATA_ITEM(172, 232, 232, fontpage_172_232_232), // '器' -- '器' FONTDATA_ITEM(172, 244, 244, fontpage_172_244_244), // '噴' -- '噴' FONTDATA_ITEM(173, 222, 222, fontpage_173_222_222), // '回' -- '回' FONTDATA_ITEM(173, 224, 224, fontpage_173_224_224), // '因' -- '因' + FONTDATA_ITEM(173, 250, 250, fontpage_173_250_250), // '固' -- '固' FONTDATA_ITEM(173, 254, 254, fontpage_173_254_254), // '图' -- '图' FONTDATA_ITEM(174, 168, 168, fontpage_174_168_168), // '在' -- '在' + FONTDATA_ITEM(174, 207, 207, fontpage_174_207_207), // '坏' -- '坏' FONTDATA_ITEM(174, 215, 215, fontpage_174_215_215), // '块' -- '块' FONTDATA_ITEM(175, 139, 139, fontpage_175_139_139), // '型' -- '型' FONTDATA_ITEM(175, 171, 171, fontpage_175_171_171), // '垫' -- '垫' @@ -1116,6 +1571,8 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(178, 167, 167, fontpage_178_167_167), // '大' -- '大' FONTDATA_ITEM(178, 169, 170, fontpage_178_169_170), // '天' -- '太' FONTDATA_ITEM(178, 177, 177, fontpage_178_177_177), // '失' -- '失' + FONTDATA_ITEM(178, 180, 180, fontpage_178_180_180), // '头' -- '头' + FONTDATA_ITEM(178, 253, 253, fontpage_178_253_253), // '好' -- '好' FONTDATA_ITEM(179, 203, 203, fontpage_179_203_203), // '始' -- '始' FONTDATA_ITEM(182, 208, 208, fontpage_182_208_208), // '子' -- '子' FONTDATA_ITEM(182, 216, 216, fontpage_182_216_216), // '存' -- '存' @@ -1123,12 +1580,14 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(183, 140, 140, fontpage_183_140_140), // '完' -- '完' FONTDATA_ITEM(183, 154, 154, fontpage_183_154_154), // '定' -- '定' FONTDATA_ITEM(183, 162, 162, fontpage_183_162_162), // '客' -- '客' - FONTDATA_ITEM(183, 185, 185, fontpage_183_185_185), // '容' -- '容' + FONTDATA_ITEM(183, 171, 171, fontpage_183_171_171), // '宫' -- '宫' FONTDATA_ITEM(183, 249, 249, fontpage_183_249_249), // '对' -- '对' + FONTDATA_ITEM(184, 134, 134, fontpage_184_134_134), // '将' -- '将' FONTDATA_ITEM(184, 143, 143, fontpage_184_143_143), // '小' -- '小' FONTDATA_ITEM(184, 177, 177, fontpage_184_177_177), // '就' -- '就' FONTDATA_ITEM(184, 207, 207, fontpage_184_207_207), // '屏' -- '屏' FONTDATA_ITEM(187, 229, 229, fontpage_187_229_229), // '工' -- '工' + FONTDATA_ITEM(187, 238, 238, fontpage_187_238_238), // '差' -- '差' FONTDATA_ITEM(187, 242, 242, fontpage_187_242_242), // '已' -- '已' FONTDATA_ITEM(188, 243, 243, fontpage_188_243_243), // '平' -- '平' FONTDATA_ITEM(188, 246, 246, fontpage_188_246_246), // '并' -- '并' @@ -1137,15 +1596,22 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(189, 159, 159, fontpage_189_159_159), // '废' -- '废' FONTDATA_ITEM(189, 166, 166, fontpage_189_166_166), // '度' -- '度' FONTDATA_ITEM(190, 128, 128, fontpage_190_128_128), // '开' -- '开' + FONTDATA_ITEM(190, 131, 131, fontpage_190_131_131), // '弃' -- '弃' + FONTDATA_ITEM(190, 143, 143, fontpage_190_143_143), // '式' -- '式' + FONTDATA_ITEM(190, 149, 149, fontpage_190_149_149), // '引' -- '引' + FONTDATA_ITEM(190, 185, 185, fontpage_190_185_185), // '弹' -- '弹' FONTDATA_ITEM(190, 210, 210, fontpage_190_210_210), // '归' -- '归' FONTDATA_ITEM(191, 132, 133, fontpage_191_132_133), // '径' -- '待' + FONTDATA_ITEM(191, 170, 170, fontpage_191_170_170), // '循' -- '循' FONTDATA_ITEM(191, 174, 174, fontpage_191_174_174), // '微' -- '微' FONTDATA_ITEM(191, 195, 195, fontpage_191_195_195), // '心' -- '心' + FONTDATA_ITEM(191, 253, 253, fontpage_191_253_253), // '忽' -- '忽' FONTDATA_ITEM(192, 167, 167, fontpage_192_167_167), // '性' -- '性' FONTDATA_ITEM(192, 187, 187, fontpage_192_187_187), // '总' -- '总' FONTDATA_ITEM(192, 226, 226, fontpage_192_226_226), // '恢' -- '恢' FONTDATA_ITEM(192, 239, 239, fontpage_192_239_239), // '息' -- '息' - FONTDATA_ITEM(196, 144, 144, fontpage_196_144_144), // '成' -- '成' + FONTDATA_ITEM(194, 159, 159, fontpage_194_159_159), // '感' -- '感' + FONTDATA_ITEM(196, 143, 144, fontpage_196_143_144), // '戏' -- '成' FONTDATA_ITEM(196, 183, 183, fontpage_196_183_183), // '户' -- '户' FONTDATA_ITEM(196, 192, 192, fontpage_196_192_192), // '所' -- '所' FONTDATA_ITEM(196, 199, 199, fontpage_196_199_199), // '扇' -- '扇' @@ -1154,80 +1620,115 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(196, 231, 231, fontpage_196_231_231), // '执' -- '执' FONTDATA_ITEM(196, 249, 249, fontpage_196_249_249), // '批' -- '批' FONTDATA_ITEM(197, 150, 150, fontpage_197_150_150), // '抖' -- '抖' + FONTDATA_ITEM(197, 165, 165, fontpage_197_165_165), // '报' -- '报' + FONTDATA_ITEM(197, 172, 172, fontpage_197_172_172), // '抬' -- '抬' FONTDATA_ITEM(197, 189, 189, fontpage_197_189_189), // '抽' -- '抽' FONTDATA_ITEM(197, 212, 212, fontpage_197_212_212), // '拔' -- '拔' FONTDATA_ITEM(197, 233, 233, fontpage_197_233_233), // '择' -- '择' FONTDATA_ITEM(198, 137, 137, fontpage_198_137_137), // '按' -- '按' FONTDATA_ITEM(198, 161, 161, fontpage_198_161_161), // '挡' -- '挡' FONTDATA_ITEM(198, 164, 164, fontpage_198_164_164), // '挤' -- '挤' + FONTDATA_ITEM(198, 223, 223, fontpage_198_223_223), // '损' -- '损' FONTDATA_ITEM(198, 226, 226, fontpage_198_226_226), // '换' -- '换' FONTDATA_ITEM(199, 137, 137, fontpage_199_137_137), // '掉' -- '掉' FONTDATA_ITEM(199, 162, 162, fontpage_199_162_162), // '探' -- '探' + FONTDATA_ITEM(199, 165, 165, fontpage_199_165_165), // '接' -- '接' FONTDATA_ITEM(199, 167, 167, fontpage_199_167_167), // '控' -- '控' + FONTDATA_ITEM(199, 208, 208, fontpage_199_208_208), // '提' -- '提' FONTDATA_ITEM(199, 210, 210, fontpage_199_210_210), // '插' -- '插' FONTDATA_ITEM(202, 182, 182, fontpage_202_182_182), // '收' -- '收' FONTDATA_ITEM(202, 190, 190, fontpage_202_190_190), // '放' -- '放' FONTDATA_ITEM(202, 240, 240, fontpage_202_240_240), // '数' -- '数' + FONTDATA_ITEM(202, 242, 242, fontpage_202_242_242), // '敲' -- '敲' FONTDATA_ITEM(202, 244, 244, fontpage_202_244_244), // '整' -- '整' + FONTDATA_ITEM(203, 135, 135, fontpage_203_135_135), // '文' -- '文' FONTDATA_ITEM(203, 153, 153, fontpage_203_153_153), // '料' -- '料' FONTDATA_ITEM(203, 156, 156, fontpage_203_156_156), // '斜' -- '斜' + FONTDATA_ITEM(203, 173, 173, fontpage_203_173_173), // '断' -- '断' FONTDATA_ITEM(203, 176, 176, fontpage_203_176_176), // '新' -- '新' + FONTDATA_ITEM(203, 185, 185, fontpage_203_185_185), // '方' -- '方' FONTDATA_ITEM(203, 224, 224, fontpage_203_224_224), // '无' -- '无' FONTDATA_ITEM(203, 246, 246, fontpage_203_246_246), // '时' -- '时' FONTDATA_ITEM(204, 142, 142, fontpage_204_142_142), // '明' -- '明' + FONTDATA_ITEM(204, 175, 175, fontpage_204_175_175), // '是' -- '是' FONTDATA_ITEM(205, 130, 130, fontpage_205_130_130), // '暂' -- '暂' FONTDATA_ITEM(205, 171, 171, fontpage_205_171_171), // '暫' -- '暫' FONTDATA_ITEM(205, 244, 244, fontpage_205_244_244), // '更' -- '更' FONTDATA_ITEM(206, 128, 128, fontpage_206_128_128), // '最' -- '最' FONTDATA_ITEM(206, 137, 137, fontpage_206_137_137), // '有' -- '有' + FONTDATA_ITEM(206, 159, 159, fontpage_206_159_159), // '期' -- '期' FONTDATA_ITEM(206, 186, 186, fontpage_206_186_186), // '机' -- '机' FONTDATA_ITEM(206, 192, 192, fontpage_206_192_192), // '杀' -- '杀' + FONTDATA_ITEM(206, 223, 223, fontpage_206_223_223), // '束' -- '束' FONTDATA_ITEM(206, 225, 225, fontpage_206_225_225), // '条' -- '条' FONTDATA_ITEM(206, 229, 229, fontpage_206_229_229), // '来' -- '来' FONTDATA_ITEM(206, 255, 255, fontpage_206_255_255), // '板' -- '板' + FONTDATA_ITEM(207, 151, 151, fontpage_207_151_151), // '林' -- '林' FONTDATA_ITEM(207, 241, 241, fontpage_207_241_241), // '柱' -- '柱' FONTDATA_ITEM(208, 161, 161, fontpage_208_161_161), // '校' -- '校' FONTDATA_ITEM(208, 188, 188, fontpage_208_188_188), // '格' -- '格' + FONTDATA_ITEM(209, 175, 175, fontpage_209_175_175), // '梯' -- '梯' FONTDATA_ITEM(209, 192, 192, fontpage_209_192_192), // '检' -- '检' FONTDATA_ITEM(211, 253, 253, fontpage_211_253_253), // '槽' -- '槽' + FONTDATA_ITEM(212, 161, 161, fontpage_212_161_161), // '模' -- '模' FONTDATA_ITEM(212, 217, 217, fontpage_212_217_217), // '橙' -- '橙' - FONTDATA_ITEM(214, 226, 226, fontpage_214_226_226), // '止' -- '止' + FONTDATA_ITEM(214, 226, 227, fontpage_214_226_227), // '止' -- '正' FONTDATA_ITEM(214, 229, 229, fontpage_214_229_229), // '步' -- '步' FONTDATA_ITEM(215, 212, 212, fontpage_215_212_212), // '比' -- '比' FONTDATA_ITEM(217, 161, 161, fontpage_217_161_161), // '没' -- '没' FONTDATA_ITEM(217, 226, 226, fontpage_217_226_226), // '波' -- '波' + FONTDATA_ITEM(217, 232, 232, fontpage_217_232_232), // '注' -- '注' + FONTDATA_ITEM(218, 151, 151, fontpage_218_151_151), // '洗' -- '洗' FONTDATA_ITEM(218, 187, 187, fontpage_218_187_187), // '活' -- '活' + FONTDATA_ITEM(218, 193, 193, fontpage_218_193_193), // '流' -- '流' FONTDATA_ITEM(218, 203, 203, fontpage_218_203_203), // '测' -- '测' FONTDATA_ITEM(219, 136, 136, fontpage_219_136_136), // '消' -- '消' FONTDATA_ITEM(219, 225, 225, fontpage_219_225_225), // '淡' -- '淡' + FONTDATA_ITEM(219, 247, 247, fontpage_219_247_247), // '混' -- '混' FONTDATA_ITEM(220, 133, 133, fontpage_220_133_133), // '清' -- '清' FONTDATA_ITEM(220, 169, 169, fontpage_220_169_169), // '温' -- '温' + FONTDATA_ITEM(220, 184, 184, fontpage_220_184_184), // '游' -- '游' FONTDATA_ITEM(221, 144, 144, fontpage_221_144_144), // '源' -- '源' + FONTDATA_ITEM(221, 162, 162, fontpage_221_162_162), // '溢' -- '溢' + FONTDATA_ITEM(221, 209, 209, fontpage_221_209_209), // '滑' -- '滑' + FONTDATA_ITEM(222, 143, 143, fontpage_222_143_143), // '漏' -- '漏' FONTDATA_ITEM(223, 192, 192, fontpage_223_192_192), // '激' -- '激' FONTDATA_ITEM(224, 239, 239, fontpage_224_239_239), // '灯' -- '灯' FONTDATA_ITEM(225, 185, 185, fontpage_225_185_185), // '点' -- '点' FONTDATA_ITEM(225, 237, 237, fontpage_225_237_237), // '热' -- '热' FONTDATA_ITEM(228, 199, 199, fontpage_228_199_199), // '片' -- '片' + FONTDATA_ITEM(228, 233, 233, fontpage_228_233_233), // '物' -- '物' FONTDATA_ITEM(228, 249, 249, fontpage_228_249_249), // '特' -- '特' FONTDATA_ITEM(231, 135, 135, fontpage_231_135_135), // '率' -- '率' + FONTDATA_ITEM(231, 175, 175, fontpage_231_175_175), // '环' -- '环' FONTDATA_ITEM(234, 168, 168, fontpage_234_168_168), // '用' -- '用' FONTDATA_ITEM(234, 181, 181, fontpage_234_181_181), // '电' -- '电' + FONTDATA_ITEM(234, 229, 229, fontpage_234_229_229), // '略' -- '略' FONTDATA_ITEM(236, 253, 253, fontpage_236_253_253), // '白' -- '白' FONTDATA_ITEM(237, 132, 132, fontpage_237_132_132), // '的' -- '的' + FONTDATA_ITEM(237, 209, 209, fontpage_237_209_209), // '监' -- '监' FONTDATA_ITEM(237, 244, 244, fontpage_237_244_244), // '直' -- '直' FONTDATA_ITEM(238, 129, 129, fontpage_238_129_129), // '省' -- '省' FONTDATA_ITEM(238, 160, 160, fontpage_238_160_160), // '眠' -- '眠' - FONTDATA_ITEM(243, 239, 239, fontpage_243_239_239), // '积' -- '积' + FONTDATA_ITEM(240, 238, 238, fontpage_240_238_238), // '确' -- '确' + FONTDATA_ITEM(243, 187, 187, fontpage_243_187_187), // '离' -- '离' FONTDATA_ITEM(243, 251, 251, fontpage_243_251_251), // '移' -- '移' + FONTDATA_ITEM(244, 250, 250, fontpage_244_250_250), // '空' -- '空' FONTDATA_ITEM(245, 239, 239, fontpage_245_239_239), // '端' -- '端' + FONTDATA_ITEM(246, 172, 172, fontpage_246_172_172), // '第' -- '第' FONTDATA_ITEM(246, 201, 201, fontpage_246_201_201), // '等' -- '等' - FONTDATA_ITEM(247, 161, 161, fontpage_247_161_161), // '管' -- '管' + FONTDATA_ITEM(247, 128, 128, fontpage_247_128_128), // '简' -- '简' + FONTDATA_ITEM(247, 177, 177, fontpage_247_177_177), // '箱' -- '箱' FONTDATA_ITEM(248, 251, 251, fontpage_248_251_251), // '类' -- '类' + FONTDATA_ITEM(250, 162, 162, fontpage_250_162_162), // '索' -- '索' FONTDATA_ITEM(250, 171, 171, fontpage_250_171_171), // '紫' -- '紫' FONTDATA_ITEM(253, 162, 162, fontpage_253_162_162), // '红' -- '红' + FONTDATA_ITEM(253, 167, 167, fontpage_253_167_167), // '级' -- '级' FONTDATA_ITEM(253, 191, 191, fontpage_253_191_191), // '线' -- '线' FONTDATA_ITEM(253, 198, 198, fontpage_253_198_198), // '细' -- '细' FONTDATA_ITEM(253, 200, 200, fontpage_253_200_200), // '终' -- '终' + FONTDATA_ITEM(253, 211, 211, fontpage_253_211_211), // '结' -- '结' + FONTDATA_ITEM(253, 217, 217, fontpage_253_217_217), // '给' -- '给' FONTDATA_ITEM(253, 223, 223, fontpage_253_223_223), // '统' -- '统' FONTDATA_ITEM(253, 231, 231, fontpage_253_231_231), // '继' -- '继' FONTDATA_ITEM(253, 234, 234, fontpage_253_234_234), // '绪' -- '绪' @@ -1238,13 +1739,18 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(254, 209, 209, fontpage_254_209_209), // '网' -- '网' FONTDATA_ITEM(254, 238, 238, fontpage_254_238_238), // '置' -- '置' FONTDATA_ITEM(254, 242, 242, fontpage_254_242_242), // '署' -- '署' + FONTDATA_ITEM(256, 133, 133, fontpage_256_133_133), // '者' -- '者' FONTDATA_ITEM(256, 234, 234, fontpage_256_234_234), // '聪' -- '聪' + FONTDATA_ITEM(257, 253, 253, fontpage_257_253_253), // '能' -- '能' FONTDATA_ITEM(259, 234, 234, fontpage_259_234_234), // '自' -- '自' + FONTDATA_ITEM(259, 243, 243, fontpage_259_243_243), // '至' -- '至' FONTDATA_ITEM(263, 220, 220, fontpage_263_220_220), // '菜' -- '菜' FONTDATA_ITEM(265, 221, 221, fontpage_265_221_221), // '蓝' -- '蓝' + FONTDATA_ITEM(269, 199, 199, fontpage_269_199_199), // '蛇' -- '蛇' FONTDATA_ITEM(272, 204, 204, fontpage_272_204_204), // '行' -- '行' FONTDATA_ITEM(273, 171, 171, fontpage_273_171_171), // '被' -- '被' FONTDATA_ITEM(273, 197, 197, fontpage_273_197_197), // '装' -- '装' + FONTDATA_ITEM(275, 129, 129, fontpage_275_129_129), // '要' -- '要' FONTDATA_ITEM(275, 210, 210, fontpage_275_210_210), // '角' -- '角' FONTDATA_ITEM(279, 161, 161, fontpage_279_161_161), // '计' -- '计' FONTDATA_ITEM(279, 174, 174, fontpage_279_174_174), // '议' -- '议' @@ -1252,42 +1758,66 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(279, 213, 213, fontpage_279_213_213), // '试' -- '试' FONTDATA_ITEM(279, 239, 239, fontpage_279_239_239), // '误' -- '误' FONTDATA_ITEM(279, 247, 247, fontpage_279_247_247), // '请' -- '请' + FONTDATA_ITEM(279, 251, 251, fontpage_279_251_251), // '读' -- '读' FONTDATA_ITEM(280, 131, 131, fontpage_280_131_131), // '调' -- '调' FONTDATA_ITEM(282, 165, 165, fontpage_282_165_165), // '败' -- '败' + FONTDATA_ITEM(282, 170, 170, fontpage_282_170_170), // '贪' -- '贪' + FONTDATA_ITEM(282, 247, 247, fontpage_282_247_247), // '起' -- '起' + FONTDATA_ITEM(283, 133, 133, fontpage_283_133_133), // '超' -- '超' + FONTDATA_ITEM(283, 221, 221, fontpage_283_221_221), // '距' -- '距' + FONTDATA_ITEM(286, 236, 236, fontpage_286_236_236), // '转' -- '转' + FONTDATA_ITEM(286, 239, 239, fontpage_286_239_239), // '软' -- '软' FONTDATA_ITEM(286, 244, 244, fontpage_286_244_244), // '轴' -- '轴' FONTDATA_ITEM(286, 253, 253, fontpage_286_253_253), // '载' -- '载' FONTDATA_ITEM(287, 145, 145, fontpage_287_145_145), // '辑' -- '辑' FONTDATA_ITEM(287, 147, 147, fontpage_287_147_147), // '输' -- '输' FONTDATA_ITEM(287, 185, 185, fontpage_287_185_185), // '边' -- '边' + FONTDATA_ITEM(287, 193, 193, fontpage_287_193_193), // '迁' -- '迁' FONTDATA_ITEM(287, 208, 209, fontpage_287_208_209), // '运' -- '近' FONTDATA_ITEM(287, 212, 212, fontpage_287_212_212), // '返' -- '返' FONTDATA_ITEM(287, 216, 216, fontpage_287_216_216), // '还' -- '还' FONTDATA_ITEM(287, 219, 219, fontpage_287_219_219), // '进' -- '进' + FONTDATA_ITEM(287, 222, 222, fontpage_287_222_222), // '连' -- '连' + FONTDATA_ITEM(287, 247, 247, fontpage_287_247_247), // '迷' -- '迷' FONTDATA_ITEM(288, 128, 128, fontpage_288_128_128), // '退' -- '退' FONTDATA_ITEM(288, 137, 137, fontpage_288_137_137), // '选' -- '选' FONTDATA_ITEM(288, 159, 159, fontpage_288_159_159), // '速' -- '速' FONTDATA_ITEM(289, 232, 232, fontpage_289_232_232), // '部' -- '部' + FONTDATA_ITEM(290, 205, 205, fontpage_290_205_205), // '配' -- '配' FONTDATA_ITEM(291, 202, 202, fontpage_291_202_202), // '释' -- '释' FONTDATA_ITEM(291, 205, 205, fontpage_291_205_205), // '重' -- '重' FONTDATA_ITEM(291, 207, 207, fontpage_291_207_207), // '量' -- '量' FONTDATA_ITEM(297, 136, 136, fontpage_297_136_136), // '针' -- '针' FONTDATA_ITEM(297, 174, 174, fontpage_297_174_174), // '钮' -- '钮' FONTDATA_ITEM(298, 153, 153, fontpage_298_153_153), // '错' -- '错' - FONTDATA_ITEM(298, 174, 174, fontpage_298_174_174), // '键' -- '键' + FONTDATA_ITEM(298, 220, 220, fontpage_298_220_220), // '镜' -- '镜' FONTDATA_ITEM(298, 255, 255, fontpage_298_255_255), // '长' -- '长' FONTDATA_ITEM(299, 237, 237, fontpage_299_237_237), // '闭' -- '闭' + FONTDATA_ITEM(299, 242, 242, fontpage_299_242_242), // '闲' -- '闲' FONTDATA_ITEM(299, 244, 244, fontpage_299_244_244), // '间' -- '间' + FONTDATA_ITEM(300, 136, 136, fontpage_300_136_136), // '阈' -- '阈' FONTDATA_ITEM(300, 205, 205, fontpage_300_205_205), // '降' -- '降' + FONTDATA_ITEM(300, 208, 208, fontpage_300_208_208), // '限' -- '限' FONTDATA_ITEM(300, 228, 228, fontpage_300_228_228), // '除' -- '除' + FONTDATA_ITEM(300, 233, 233, fontpage_300_233_233), // '险' -- '险' + FONTDATA_ITEM(301, 246, 246, fontpage_301_246_246), // '零' -- '零' + FONTDATA_ITEM(302, 128, 128, fontpage_302_128_128), // '需' -- '需' FONTDATA_ITEM(302, 210, 210, fontpage_302_210_210), // '青' -- '青' FONTDATA_ITEM(302, 222, 222, fontpage_302_222_222), // '非' -- '非' + FONTDATA_ITEM(302, 224, 224, fontpage_302_224_224), // '靠' -- '靠' + FONTDATA_ITEM(302, 226, 226, fontpage_302_226_226), // '面' -- '面' + FONTDATA_ITEM(304, 245, 245, fontpage_304_245_245), // '页' -- '页' FONTDATA_ITEM(304, 249, 249, fontpage_304_249_249), // '项' -- '项' FONTDATA_ITEM(305, 132, 132, fontpage_305_132_132), // '预' -- '预' + FONTDATA_ITEM(305, 145, 145, fontpage_305_145_145), // '频' -- '频' FONTDATA_ITEM(305, 157, 157, fontpage_305_157_157), // '额' -- '额' FONTDATA_ITEM(305, 206, 206, fontpage_305_206_206), // '风' -- '风' FONTDATA_ITEM(306, 241, 241, fontpage_306_241_241), // '饱' -- '饱' + FONTDATA_ITEM(308, 236, 236, fontpage_308_236_236), // '马' -- '马' FONTDATA_ITEM(308, 241, 241, fontpage_308_241_241), // '驱' -- '驱' FONTDATA_ITEM(309, 216, 216, fontpage_309_216_216), // '高' -- '高' FONTDATA_ITEM(317, 196, 196, fontpage_317_196_196), // '黄' -- '黄' + FONTDATA_ITEM(317, 222, 222, fontpage_317_222_222), // '點' -- '點' + FONTDATA_ITEM(318, 208, 208, fontpage_318_208_208), // '齐' -- '齐' FONTDATA_ITEM(510, 154, 154, fontpage_510_154_154), // ':' -- ':' }; diff --git a/Marlin/src/lcd/dogm/fontdata/langdata_zh_TW.h b/Marlin/src/lcd/dogm/fontdata/langdata_zh_TW.h index e1bb97ea3d64..8eee544ec81b 100644 --- a/Marlin/src/lcd/dogm/fontdata/langdata_zh_TW.h +++ b/Marlin/src/lcd/dogm/fontdata/langdata_zh_TW.h @@ -5,1111 +5,1236 @@ */ #include -const u8g_fntpgm_uint8_t fontpage_64_157_157[26] U8G_FONT_SECTION("fontpage_64_157_157") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9d,0x9d,0x00,0x07,0x00,0x00, - 0x00,0x05,0x03,0x03,0x06,0x00,0x04,0xd8,0x48,0x90}; const u8g_fntpgm_uint8_t fontpage_69_191_191[28] U8G_FONT_SECTION("fontpage_69_191_191") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbf,0xbf,0x00,0x05,0x00,0x00, - 0x00,0x05,0x05,0x05,0x06,0x00,0x00,0x08,0x18,0x28,0x48,0xf8}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBF,0xBF,0x00,0x05,0x00,0x00, + 0x00,0x05,0x05,0x05,0x06,0x00,0x00,0x08,0x18,0x28,0x48,0xF8}; const u8g_fntpgm_uint8_t fontpage_156_128_128[27] U8G_FONT_SECTION("fontpage_156_128_128") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x06,0x00,0x00, - 0x00,0x0b,0x02,0x04,0x0c,0x00,0x04,0x00,0x40,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x06,0x00,0x00, + 0x00,0x0B,0x02,0x04,0x0C,0x00,0x04,0x00,0x40,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_156_137_139[97] U8G_FONT_SECTION("fontpage_156_137_139") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x89,0x8b,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0a,0x14,0x0c,0x00,0xff,0x7f,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x3f, - 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xe0,0x0b,0x0b,0x16,0x0c,0x00, - 0xff,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x07,0xc0,0x04,0x00,0x04,0x00,0x04, - 0x00,0x04,0x00,0x04,0x00,0xff,0xe0,0x0b,0x0a,0x14,0x0c,0x00,0xff,0xff,0xe0,0x04, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x89,0x8B,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0A,0x14,0x0C,0x00,0xFF,0x7F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x3F, + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xE0,0x0B,0x0B,0x16,0x0C,0x00, + 0xFF,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x07,0xC0,0x04,0x00,0x04,0x00,0x04, + 0x00,0x04,0x00,0x04,0x00,0xFF,0xE0,0x0B,0x0A,0x14,0x0C,0x00,0xFF,0xFF,0xE0,0x04, 0x00,0x04,0x00,0x06,0x00,0x05,0x00,0x04,0x80,0x04,0x80,0x04,0x00,0x04,0x00,0x04, 0x00}; +const u8g_fntpgm_uint8_t fontpage_156_141_141[45] U8G_FONT_SECTION("fontpage_156_141_141") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8D,0x8D,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xFF,0xE0,0x02,0x00,0x02,0x00,0x04,0x00,0x0D, + 0x00,0x14,0x80,0x24,0x40,0x44,0x20,0x84,0x00,0x04,0x00,0x04,0x00}; const u8g_fntpgm_uint8_t fontpage_156_166_166[45] U8G_FONT_SECTION("fontpage_156_166_166") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa6,0xa6,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x80,0x11,0x00,0xff,0xe0,0x0a,0x00,0x4a, - 0x40,0x4a,0x40,0x2a,0x40,0x2a,0x80,0x0a,0x00,0x0a,0x00,0xff,0xe0}; -const u8g_fntpgm_uint8_t fontpage_156_170_170[45] U8G_FONT_SECTION("fontpage_156_170_170") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xaa,0xaa,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x08,0x00,0x08,0x00,0x14,0x00,0x22,0x00,0x49, - 0x00,0x88,0xc0,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA6,0xA6,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x80,0x11,0x00,0xFF,0xE0,0x0A,0x00,0x4A, + 0x40,0x4A,0x40,0x2A,0x40,0x2A,0x80,0x0A,0x00,0x0A,0x00,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_156_173_173[45] U8G_FONT_SECTION("fontpage_156_173_173") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xad,0xad,0x00,0x0a,0xff,0x00, - 0x00,0x09,0x0b,0x16,0x0c,0x01,0xff,0x08,0x00,0x08,0x00,0xff,0x80,0x88,0x80,0x88, - 0x80,0x88,0x80,0xff,0x80,0x88,0x80,0x08,0x00,0x08,0x00,0x08,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAD,0xAD,0x00,0x0A,0xFF,0x00, + 0x00,0x09,0x0B,0x16,0x0C,0x01,0xFF,0x08,0x00,0x08,0x00,0xFF,0x80,0x88,0x80,0x88, + 0x80,0x88,0x80,0xFF,0x80,0x88,0x80,0x08,0x00,0x08,0x00,0x08,0x00}; const u8g_fntpgm_uint8_t fontpage_156_187_187[45] U8G_FONT_SECTION("fontpage_156_187_187") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbb,0xbb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x08,0x00,0x04,0x00,0xff,0xe0,0x04,0x00,0x04, - 0x00,0x04,0x00,0x7f,0xc0,0x04,0x00,0x04,0x00,0x04,0x00,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBB,0xBB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x08,0x00,0x04,0x00,0xFF,0xE0,0x04,0x00,0x04, + 0x00,0x04,0x00,0x7F,0xC0,0x04,0x00,0x04,0x00,0x04,0x00,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_156_203_203[45] U8G_FONT_SECTION("fontpage_156_203_203") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcb,0xcb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x08,0x00,0x04,0x00,0x7f,0xc0,0x00,0x80,0x01, - 0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x30,0x00,0x48,0x00,0x87,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCB,0xCB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x08,0x00,0x04,0x00,0x7F,0xC0,0x00,0x80,0x01, + 0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x30,0x00,0x48,0x00,0x87,0xE0}; +const u8g_fntpgm_uint8_t fontpage_157_164_164[45] U8G_FONT_SECTION("fontpage_157_164_164") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA4,0xA4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0xFF,0xE0,0x00,0x00,0x11,0x00,0x20, + 0x80,0x51,0x40,0x11,0x00,0x0A,0x00,0x04,0x00,0x1B,0x00,0x60,0xE0}; const u8g_fntpgm_uint8_t fontpage_157_174_174[45] U8G_FONT_SECTION("fontpage_157_174_174") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xae,0xae,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0xff,0xe0,0x11,0x00,0x1f,0x00,0x00, - 0x00,0xff,0xe0,0x80,0x20,0x1f,0x00,0x11,0x00,0x21,0x20,0xc0,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAE,0xAE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0xFF,0xE0,0x11,0x00,0x1F,0x00,0x00, + 0x00,0xFF,0xE0,0x80,0x20,0x1F,0x00,0x11,0x00,0x21,0x20,0xC0,0xE0}; const u8g_fntpgm_uint8_t fontpage_157_228_228[45] U8G_FONT_SECTION("fontpage_157_228_228") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe4,0xe4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x04,0x00,0x0a,0x00,0x11,0x00,0x24, - 0x80,0xc2,0x60,0x3f,0x80,0x01,0x00,0x0a,0x00,0x04,0x00,0x02,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE4,0xE4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x04,0x00,0x0A,0x00,0x11,0x00,0x24, + 0x80,0xC2,0x60,0x3F,0x80,0x01,0x00,0x0A,0x00,0x04,0x00,0x02,0x00}; +const u8g_fntpgm_uint8_t fontpage_157_246_246[45] U8G_FONT_SECTION("fontpage_157_246_246") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF6,0xF6,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x15,0x00,0x25,0x00,0x2F,0xC0,0x71, + 0x00,0xA1,0x00,0x2F,0xE0,0x21,0x00,0x21,0x00,0x21,0x00,0x21,0x00}; const u8g_fntpgm_uint8_t fontpage_157_253_253[45] U8G_FONT_SECTION("fontpage_157_253_253") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfd,0xfd,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x10,0x80,0x12,0x80,0x22,0x40,0x24,0x40,0x68, - 0x20,0xa7,0xc0,0x22,0x40,0x22,0x40,0x22,0x40,0x24,0x40,0x28,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFD,0xFD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x10,0x80,0x12,0x80,0x22,0x40,0x24,0x40,0x68, + 0x20,0xA7,0xC0,0x22,0x40,0x22,0x40,0x22,0x40,0x24,0x40,0x28,0xC0}; const u8g_fntpgm_uint8_t fontpage_158_145_145[45] U8G_FONT_SECTION("fontpage_158_145_145") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x91,0x91,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0x11,0x00,0x21,0x00,0x3f,0xe0,0x61, - 0x00,0xa3,0x80,0x23,0x80,0x25,0x40,0x29,0x20,0x31,0x00,0x21,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x91,0x91,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x11,0x00,0x21,0x00,0x3F,0xE0,0x61, + 0x00,0xA3,0x80,0x23,0x80,0x25,0x40,0x29,0x20,0x31,0x00,0x21,0x00}; const u8g_fntpgm_uint8_t fontpage_158_205_206[73] U8G_FONT_SECTION("fontpage_158_205_206") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcd,0xce,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x12,0x00,0x11,0x00,0x20,0x00,0x2f,0xe0,0x60, - 0x00,0xa4,0x40,0x22,0x40,0x22,0x80,0x20,0x80,0x21,0x00,0x2f,0xe0,0x0b,0x0b,0x16, - 0x0c,0x00,0xff,0x10,0xc0,0x1f,0x00,0x29,0x00,0x29,0x00,0x69,0x00,0xaf,0xe0,0x29, - 0x00,0x29,0x20,0x2a,0xa0,0x2d,0x60,0x28,0xa0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCD,0xCE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x12,0x00,0x11,0x00,0x20,0x00,0x2F,0xE0,0x60, + 0x00,0xA4,0x40,0x22,0x40,0x22,0x80,0x20,0x80,0x21,0x00,0x2F,0xE0,0x0B,0x0B,0x16, + 0x0C,0x00,0xFF,0x10,0xC0,0x1F,0x00,0x29,0x00,0x29,0x00,0x69,0x00,0xAF,0xE0,0x29, + 0x00,0x29,0x20,0x2A,0xA0,0x2D,0x60,0x28,0xA0}; const u8g_fntpgm_uint8_t fontpage_158_220_220[45] U8G_FONT_SECTION("fontpage_158_220_220") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xdc,0xdc,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x14,0x00,0x14,0x00,0x27,0xe0,0x2a,0x00,0x72, - 0x00,0xa3,0xc0,0x22,0x00,0x22,0x00,0x23,0xe0,0x22,0x00,0x22,0x00}; -const u8g_fntpgm_uint8_t fontpage_159_134_134[45] U8G_FONT_SECTION("fontpage_159_134_134") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x86,0x86,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0xff,0xe0,0x04,0x00,0x24,0x80,0x24, - 0x80,0x55,0x40,0x8e,0x20,0x15,0x00,0x24,0x80,0xc4,0x60,0x04,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDC,0xDC,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x14,0x00,0x14,0x00,0x27,0xE0,0x2A,0x00,0x72, + 0x00,0xA3,0xC0,0x22,0x00,0x22,0x00,0x23,0xE0,0x22,0x00,0x22,0x00}; const u8g_fntpgm_uint8_t fontpage_159_155_155[45] U8G_FONT_SECTION("fontpage_159_155_155") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9b,0x9b,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x14,0x80,0x14,0x80,0x24,0x80,0x2f,0xe0,0x64, - 0x80,0xa4,0x80,0x3f,0xe0,0x20,0x00,0x24,0x80,0x28,0x40,0x30,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9B,0x9B,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x14,0x80,0x14,0x80,0x24,0x80,0x2F,0xE0,0x64, + 0x80,0xA4,0x80,0x3F,0xE0,0x20,0x00,0x24,0x80,0x28,0x40,0x30,0x20}; const u8g_fntpgm_uint8_t fontpage_159_221_221[45] U8G_FONT_SECTION("fontpage_159_221_221") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xdd,0xdd,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x17,0xc0,0x14,0x40,0x24,0x40,0x27,0xc0,0x61, - 0x00,0xaf,0xe0,0x21,0x00,0x23,0x80,0x25,0x40,0x29,0x20,0x21,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDD,0xDD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x17,0xC0,0x14,0x40,0x24,0x40,0x27,0xC0,0x61, + 0x00,0xAF,0xE0,0x21,0x00,0x23,0x80,0x25,0x40,0x29,0x20,0x21,0x00}; const u8g_fntpgm_uint8_t fontpage_159_225_225[45] U8G_FONT_SECTION("fontpage_159_225_225") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe1,0xe1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x12,0x00,0x11,0x00,0x2f,0xe0,0x20,0x00,0x67, - 0xc0,0xa0,0x00,0x27,0xc0,0x20,0x00,0x27,0xc0,0x24,0x40,0x27,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE1,0xE1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x12,0x00,0x11,0x00,0x2F,0xE0,0x20,0x00,0x67, + 0xC0,0xA0,0x00,0x27,0xC0,0x20,0x00,0x27,0xC0,0x24,0x40,0x27,0xC0}; const u8g_fntpgm_uint8_t fontpage_160_139_139[45] U8G_FONT_SECTION("fontpage_160_139_139") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8b,0x8b,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x2f,0xe0,0x29,0x20,0x29,0x20,0x2f,0xe0,0x69, - 0x20,0xab,0xa0,0x2a,0xa0,0x2b,0xa0,0x28,0x20,0x2f,0xe0,0x28,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8B,0x8B,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x2F,0xE0,0x29,0x20,0x29,0x20,0x2F,0xE0,0x69, + 0x20,0xAB,0xA0,0x2A,0xA0,0x2B,0xA0,0x28,0x20,0x2F,0xE0,0x28,0x20}; const u8g_fntpgm_uint8_t fontpage_160_188_188[45] U8G_FONT_SECTION("fontpage_160_188_188") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbc,0xbc,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0x1f,0xe0,0x22,0x00,0x27,0xc0,0x64, - 0x40,0xa7,0xc0,0x24,0x40,0x27,0x40,0x25,0xc0,0x24,0x40,0x2f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBC,0xBC,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x1F,0xE0,0x22,0x00,0x27,0xC0,0x64, + 0x40,0xA7,0xC0,0x24,0x40,0x27,0x40,0x25,0xC0,0x24,0x40,0x2F,0xE0}; const u8g_fntpgm_uint8_t fontpage_160_207_207[45] U8G_FONT_SECTION("fontpage_160_207_207") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcf,0xcf,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x2f,0xe0,0x28,0x20,0x2f,0xe0,0x68, - 0x00,0xaf,0xe0,0x2a,0xa0,0x2f,0xe0,0x2a,0xa0,0x3a,0xa0,0x28,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCF,0xCF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x2F,0xE0,0x28,0x20,0x2F,0xE0,0x68, + 0x00,0xAF,0xE0,0x2A,0xA0,0x2F,0xE0,0x2A,0xA0,0x3A,0xA0,0x28,0x60}; const u8g_fntpgm_uint8_t fontpage_160_220_220[45] U8G_FONT_SECTION("fontpage_160_220_220") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xdc,0xdc,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x00,0x3f,0xe0,0x20,0x00,0x4f,0xc0,0x48, - 0x40,0xdf,0xe0,0x50,0x20,0x4f,0xc0,0x41,0x00,0x41,0x00,0x47,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDC,0xDC,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0x3F,0xE0,0x20,0x00,0x4F,0xC0,0x48, + 0x40,0xDF,0xE0,0x50,0x20,0x4F,0xC0,0x41,0x00,0x41,0x00,0x47,0x00}; +const u8g_fntpgm_uint8_t fontpage_160_245_245[45] U8G_FONT_SECTION("fontpage_160_245_245") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF5,0xF5,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0x23,0xE0,0x22,0x00,0x2F,0xC0,0x68, + 0x40,0xAF,0xC0,0x28,0x40,0x2F,0xC0,0x28,0x40,0x2F,0xC0,0x38,0x60}; const u8g_fntpgm_uint8_t fontpage_161_153_153[45] U8G_FONT_SECTION("fontpage_161_153_153") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x99,0x99,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x24,0x80,0x2f,0xc0,0x24,0x80,0x3f,0xe0,0x64, - 0x00,0xaf,0xe0,0x29,0x20,0x3f,0xe0,0x29,0x20,0x2f,0xe0,0x29,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x99,0x99,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x24,0x80,0x2F,0xC0,0x24,0x80,0x3F,0xE0,0x64, + 0x00,0xAF,0xE0,0x29,0x20,0x3F,0xE0,0x29,0x20,0x2F,0xE0,0x29,0x20}; const u8g_fntpgm_uint8_t fontpage_161_179_179[45] U8G_FONT_SECTION("fontpage_161_179_179") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb3,0xb3,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x00,0x3f,0xe0,0x2a,0x40,0x2f,0xc0,0x6a, - 0x40,0xbf,0xc0,0x22,0x80,0x3f,0xe0,0x28,0x80,0x24,0x80,0x21,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB3,0xB3,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0x3F,0xE0,0x2A,0x40,0x2F,0xC0,0x6A, + 0x40,0xBF,0xC0,0x22,0x80,0x3F,0xE0,0x28,0x80,0x24,0x80,0x21,0x80}; +const u8g_fntpgm_uint8_t fontpage_161_190_190[45] U8G_FONT_SECTION("fontpage_161_190_190") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBE,0xBE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x13,0xE0,0x10,0x80,0x2B,0xE0,0x2A,0x20,0x6F, + 0xE0,0xAA,0x20,0x2B,0xE0,0x2E,0x20,0x2B,0xE0,0x31,0x40,0x26,0x20}; const u8g_fntpgm_uint8_t fontpage_162_178_178[45] U8G_FONT_SECTION("fontpage_162_178_178") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb2,0xb2,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x28,0x80,0x3d,0xe0,0x40,0xa0,0x5d,0xe0,0xc0, - 0x80,0x5d,0xe0,0x43,0x20,0x5d,0xe0,0x55,0x20,0x5d,0xe0,0x55,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB2,0xB2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x28,0x80,0x3D,0xE0,0x40,0xA0,0x5D,0xE0,0xC0, + 0x80,0x5D,0xE0,0x43,0x20,0x5D,0xE0,0x55,0x20,0x5D,0xE0,0x55,0x20}; const u8g_fntpgm_uint8_t fontpage_162_197_197[45] U8G_FONT_SECTION("fontpage_162_197_197") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc5,0xc5,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x04,0x00,0xff,0xc0,0x08,0x00,0x11,0x00,0x7f, - 0x80,0x12,0x80,0x12,0x00,0x12,0x00,0x22,0x40,0x22,0x40,0xc1,0xc0}; -const u8g_fntpgm_uint8_t fontpage_162_200_200[45] U8G_FONT_SECTION("fontpage_162_200_200") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x24,0x00,0x3f,0xc0,0x44,0x00,0x84, - 0x00,0xff,0xe0,0x12,0x00,0x12,0x00,0x12,0x20,0x22,0x20,0xc1,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC5,0xC5,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x04,0x00,0xFF,0xC0,0x08,0x00,0x11,0x00,0x7F, + 0x80,0x12,0x80,0x12,0x00,0x12,0x00,0x22,0x40,0x22,0x40,0xC1,0xC0}; +const u8g_fntpgm_uint8_t fontpage_162_200_201[73] U8G_FONT_SECTION("fontpage_162_200_201") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC8,0xC9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x24,0x00,0x3F,0xC0,0x44,0x00,0x84, + 0x00,0xFF,0xE0,0x12,0x00,0x12,0x00,0x12,0x20,0x22,0x20,0xC1,0xE0,0x0B,0x0B,0x16, + 0x0C,0x00,0xFF,0x04,0x00,0x44,0x40,0x24,0x80,0x04,0x00,0xFF,0xE0,0x12,0x00,0x12, + 0x00,0x12,0x20,0x12,0x20,0x22,0x20,0xC1,0xE0}; const u8g_fntpgm_uint8_t fontpage_162_229_229[45] U8G_FONT_SECTION("fontpage_162_229_229") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe5,0xe5,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x18,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x0a, - 0x00,0x0a,0x00,0x11,0x00,0x11,0x00,0x20,0x80,0x40,0x40,0x80,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE5,0xE5,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x18,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x0A, + 0x00,0x0A,0x00,0x11,0x00,0x11,0x00,0x20,0x80,0x40,0x40,0x80,0x20}; const u8g_fntpgm_uint8_t fontpage_162_232_232[45] U8G_FONT_SECTION("fontpage_162_232_232") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe8,0xe8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x0a,0x00,0x11,0x00,0x20,0x80,0xdf, - 0x60,0x04,0x00,0x04,0x00,0x1f,0x00,0x04,0x00,0x04,0x00,0x7f,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE8,0xE8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0xDF, + 0x60,0x04,0x00,0x04,0x00,0x1F,0x00,0x04,0x00,0x04,0x00,0x7F,0xC0}; const u8g_fntpgm_uint8_t fontpage_162_241_241[45] U8G_FONT_SECTION("fontpage_162_241_241") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf1,0xf1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0x11,0x00,0x7f,0xc0,0x11,0x00,0x11, - 0x00,0x11,0x00,0xff,0xe0,0x00,0x00,0x11,0x00,0x20,0x80,0x40,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF1,0xF1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x11,0x00,0x7F,0xC0,0x11,0x00,0x11, + 0x00,0x11,0x00,0xFF,0xE0,0x00,0x00,0x11,0x00,0x20,0x80,0x40,0x40}; const u8g_fntpgm_uint8_t fontpage_162_247_247[45] U8G_FONT_SECTION("fontpage_162_247_247") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf7,0xf7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x3f,0x80,0x20,0x80,0x3f,0x80,0x20,0x80,0x3f, - 0x80,0x20,0x80,0x3f,0x80,0x20,0x80,0xff,0xe0,0x11,0x00,0xe0,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF7,0xF7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x3F,0x80,0x20,0x80,0x3F,0x80,0x20,0x80,0x3F, + 0x80,0x20,0x80,0x3F,0x80,0x20,0x80,0xFF,0xE0,0x11,0x00,0xE0,0xE0}; +const u8g_fntpgm_uint8_t fontpage_163_151_151[43] U8G_FONT_SECTION("fontpage_163_151_151") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x97,0x97,0x00,0x09,0xFF,0x00, + 0x00,0x0B,0x0A,0x14,0x0C,0x00,0xFF,0x7F,0xE0,0x40,0x20,0x9F,0x40,0x11,0x00,0x11, + 0x00,0x11,0x00,0x11,0x00,0x21,0x20,0x41,0x20,0x80,0xE0}; const u8g_fntpgm_uint8_t fontpage_163_183_183[45] U8G_FONT_SECTION("fontpage_163_183_183") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb7,0xb7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x82,0x00,0x42,0x00,0x05,0x00,0x28,0x80,0x32, - 0x60,0x41,0x00,0x4f,0xc0,0x80,0x80,0x87,0x00,0x81,0x00,0x00,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB7,0xB7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x82,0x00,0x42,0x00,0x05,0x00,0x28,0x80,0x32, + 0x60,0x41,0x00,0x4F,0xC0,0x80,0x80,0x87,0x00,0x81,0x00,0x00,0x80}; const u8g_fntpgm_uint8_t fontpage_163_198_198[45] U8G_FONT_SECTION("fontpage_163_198_198") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x0a,0x00,0x89,0x00,0x4f,0xe0,0x59,0x00,0x09, - 0x00,0x2f,0xc0,0x29,0x00,0xcf,0xc0,0x49,0x00,0x49,0x00,0x4f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x0A,0x00,0x89,0x00,0x4F,0xE0,0x59,0x00,0x09, + 0x00,0x2F,0xC0,0x29,0x00,0xCF,0xC0,0x49,0x00,0x49,0x00,0x4F,0xE0}; const u8g_fntpgm_uint8_t fontpage_163_250_250[45] U8G_FONT_SECTION("fontpage_163_250_250") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfa,0xfa,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x44,0x40,0x44,0x40,0x44,0x40,0x7f, - 0xc0,0x04,0x00,0x84,0x20,0x84,0x20,0x84,0x20,0x84,0x20,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFA,0xFA,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x44,0x40,0x44,0x40,0x44,0x40,0x7F, + 0xC0,0x04,0x00,0x84,0x20,0x84,0x20,0x84,0x20,0x84,0x20,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_164_134_134[45] U8G_FONT_SECTION("fontpage_164_134_134") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x86,0x86,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0x11,0x00,0x20,0x80,0x20,0x80,0x40, - 0x40,0xbf,0xa0,0x08,0x80,0x08,0x80,0x10,0x80,0x20,0x80,0xc3,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x86,0x86,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x11,0x00,0x20,0x80,0x20,0x80,0x40, + 0x40,0xBF,0xA0,0x08,0x80,0x08,0x80,0x10,0x80,0x20,0x80,0xC3,0x00}; const u8g_fntpgm_uint8_t fontpage_164_151_151[45] U8G_FONT_SECTION("fontpage_164_151_151") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x97,0x97,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x7e,0x20,0x10,0x20,0x11,0x20,0x3d,0x20,0x25, - 0x20,0x65,0x20,0x99,0x20,0x09,0x20,0x10,0x20,0x20,0x20,0xc0,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x97,0x97,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7E,0x20,0x10,0x20,0x11,0x20,0x3D,0x20,0x25, + 0x20,0x65,0x20,0x99,0x20,0x09,0x20,0x10,0x20,0x20,0x20,0xC0,0xE0}; const u8g_fntpgm_uint8_t fontpage_164_157_157[45] U8G_FONT_SECTION("fontpage_164_157_157") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9d,0x9d,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x40,0x00,0x27,0xe0,0xf9,0x20,0x11,0x20,0x21, - 0x20,0x69,0x20,0xb1,0x20,0x29,0x20,0x22,0x20,0x24,0x20,0x28,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9D,0x9D,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x40,0x00,0x27,0xE0,0xF9,0x20,0x11,0x20,0x21, + 0x20,0x69,0x20,0xB1,0x20,0x29,0x20,0x22,0x20,0x24,0x20,0x28,0xC0}; const u8g_fntpgm_uint8_t fontpage_164_176_176[45] U8G_FONT_SECTION("fontpage_164_176_176") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb0,0xb0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xfe,0x20,0x10,0x20,0x20,0xa0,0x44,0xa0,0xfe, - 0xa0,0x10,0xa0,0x7c,0xa0,0x10,0xa0,0x10,0x20,0x1e,0x20,0xe0,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB0,0xB0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xFE,0x20,0x10,0x20,0x20,0xA0,0x44,0xA0,0xFE, + 0xA0,0x10,0xA0,0x7C,0xA0,0x10,0xA0,0x10,0x20,0x1E,0x20,0xE0,0xE0}; const u8g_fntpgm_uint8_t fontpage_164_182_183[73] U8G_FONT_SECTION("fontpage_164_182_183") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb6,0xb7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x10,0x20,0x50,0xa0,0x7e,0xa0,0x90,0xa0,0xfe, - 0xa0,0x10,0xa0,0x7e,0xa0,0x52,0xa0,0x52,0x20,0x56,0x20,0x10,0xe0,0x0b,0x0b,0x16, - 0x0c,0x00,0xff,0x7e,0x20,0x42,0x20,0x7e,0xa0,0x48,0xa0,0x48,0xa0,0x7e,0xa0,0x6a, - 0xa0,0xaa,0xa0,0xaa,0xa0,0x2e,0x20,0x08,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB6,0xB7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x10,0x20,0x50,0xA0,0x7E,0xA0,0x90,0xA0,0xFE, + 0xA0,0x10,0xA0,0x7E,0xA0,0x52,0xA0,0x52,0x20,0x56,0x20,0x10,0xE0,0x0B,0x0B,0x16, + 0x0C,0x00,0xFF,0x7E,0x20,0x42,0x20,0x7E,0xA0,0x48,0xA0,0x48,0xA0,0x7E,0xA0,0x6A, + 0xA0,0xAA,0xA0,0xAA,0xA0,0x2E,0x20,0x08,0xE0}; const u8g_fntpgm_uint8_t fontpage_164_245_245[45] U8G_FONT_SECTION("fontpage_164_245_245") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf5,0xf5,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x10,0x20,0x28,0x20,0x54,0xa0,0xfe,0xa0,0x44, - 0xa0,0x7c,0xa0,0x44,0xa0,0x7c,0xa0,0xc4,0x20,0x44,0x20,0x7c,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF5,0xF5,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x10,0x20,0x28,0x20,0x54,0xA0,0xFE,0xA0,0x44, + 0xA0,0x7C,0xA0,0x44,0xA0,0x7C,0xA0,0xC4,0x20,0x44,0x20,0x7C,0xE0}; const u8g_fntpgm_uint8_t fontpage_165_155_155[45] U8G_FONT_SECTION("fontpage_165_155_155") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9b,0x9b,0x00,0x0a,0xff,0x00, - 0x00,0x09,0x0b,0x16,0x0c,0x01,0xff,0x08,0x00,0x08,0x00,0x08,0x00,0xff,0x80,0x08, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9B,0x9B,0x00,0x0A,0xFF,0x00, + 0x00,0x09,0x0B,0x16,0x0C,0x01,0xFF,0x08,0x00,0x08,0x00,0x08,0x00,0xFF,0x80,0x08, 0x80,0x08,0x80,0x10,0x80,0x10,0x80,0x20,0x80,0x40,0x80,0x87,0x00}; const u8g_fntpgm_uint8_t fontpage_165_160_160[45] U8G_FONT_SECTION("fontpage_165_160_160") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa0,0xa0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x00,0x20,0x00,0xfd,0xe0,0x25,0x20,0x25, - 0x20,0x25,0x20,0x25,0x20,0x25,0x20,0x45,0x20,0x55,0xe0,0x89,0x20}; -const u8g_fntpgm_uint8_t fontpage_165_168_168[45] U8G_FONT_SECTION("fontpage_165_168_168") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa8,0xa8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x01,0x00,0x79,0x00,0x01,0x00,0x03,0xe0,0xfd, - 0x20,0x21,0x20,0x21,0x20,0x49,0x20,0xfa,0x20,0x0a,0x20,0x04,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA0,0xA0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x00,0x20,0x00,0xFD,0xE0,0x25,0x20,0x25, + 0x20,0x25,0x20,0x25,0x20,0x25,0x20,0x45,0x20,0x55,0xE0,0x89,0x20}; const u8g_fntpgm_uint8_t fontpage_165_213_213[45] U8G_FONT_SECTION("fontpage_165_213_213") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd5,0xd5,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x78,0x80,0x10,0x80,0xfe,0x80,0x55,0xe0,0x7c, - 0xa0,0x54,0xa0,0x7c,0xa0,0x10,0xa0,0x7d,0x20,0x11,0x20,0xfe,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD5,0xD5,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x78,0x80,0x10,0x80,0xFE,0x80,0x55,0xE0,0x7C, + 0xA0,0x54,0xA0,0x7C,0xA0,0x10,0xA0,0x7D,0x20,0x11,0x20,0xFE,0x60}; const u8g_fntpgm_uint8_t fontpage_166_150_150[45] U8G_FONT_SECTION("fontpage_166_150_150") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x96,0x96,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x12,0x00,0x12,0x00,0x22,0x40,0x22,0x80,0x63, - 0x00,0xa2,0x00,0x26,0x00,0x2a,0x00,0x22,0x20,0x22,0x20,0x21,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x96,0x96,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x12,0x00,0x12,0x00,0x22,0x40,0x22,0x80,0x63, + 0x00,0xA2,0x00,0x26,0x00,0x2A,0x00,0x22,0x20,0x22,0x20,0x21,0xE0}; const u8g_fntpgm_uint8_t fontpage_166_202_202[45] U8G_FONT_SECTION("fontpage_166_202_202") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xca,0xca,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x44,0x40,0x24,0x80,0x15,0x00,0x7f, - 0xc0,0x04,0x00,0x04,0x00,0xff,0xe0,0x04,0x00,0x04,0x00,0x04,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCA,0xCA,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x44,0x40,0x24,0x80,0x15,0x00,0x7F, + 0xC0,0x04,0x00,0x04,0x00,0xFF,0xE0,0x04,0x00,0x04,0x00,0x04,0x00}; const u8g_fntpgm_uint8_t fontpage_166_212_212[45] U8G_FONT_SECTION("fontpage_166_212_212") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd4,0xd4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x00,0x27,0xc0,0x22,0x40,0xfa,0x40,0x24, - 0x80,0x24,0x80,0x3f,0xe0,0x2a,0xa0,0x2a,0xa0,0x33,0x20,0x24,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD4,0xD4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0x27,0xC0,0x22,0x40,0xFA,0x40,0x24, + 0x80,0x24,0x80,0x3F,0xE0,0x2A,0xA0,0x2A,0xA0,0x33,0x20,0x24,0x40}; const u8g_fntpgm_uint8_t fontpage_166_225_225[45] U8G_FONT_SECTION("fontpage_166_225_225") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe1,0xe1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x08,0x00,0x0f,0x80,0x08,0x00,0x08,0x00,0xff, - 0xe0,0x08,0x00,0x0a,0x00,0x09,0x00,0x08,0x80,0x08,0x00,0x08,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE1,0xE1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x08,0x00,0x0F,0x80,0x08,0x00,0x08,0x00,0xFF, + 0xE0,0x08,0x00,0x0A,0x00,0x09,0x00,0x08,0x80,0x08,0x00,0x08,0x00}; const u8g_fntpgm_uint8_t fontpage_166_240_240[45] U8G_FONT_SECTION("fontpage_166_240_240") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf0,0xf0,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x10,0x00,0xe7,0xc0,0x84,0x40,0x84,0x40,0xf4, - 0x40,0x84,0x40,0x84,0x40,0x94,0x40,0xe5,0x80,0x84,0x00,0x04,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x10,0x00,0xE7,0xC0,0x84,0x40,0x84,0x40,0xF4, + 0x40,0x84,0x40,0x84,0x40,0x94,0x40,0xE5,0x80,0x84,0x00,0x04,0x00}; const u8g_fntpgm_uint8_t fontpage_166_248_248[45] U8G_FONT_SECTION("fontpage_166_248_248") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf8,0xf8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x40,0x00,0x7d,0xe0,0x91,0x20,0x11,0x20,0xff, - 0x20,0x11,0x20,0x5d,0x20,0x51,0x20,0x51,0xa0,0x5d,0x40,0xe1,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x40,0x00,0x7D,0xE0,0x91,0x20,0x11,0x20,0xFF, + 0x20,0x11,0x20,0x5D,0x20,0x51,0x20,0x51,0xA0,0x5D,0x40,0xE1,0x00}; +const u8g_fntpgm_uint8_t fontpage_166_251_251[45] U8G_FONT_SECTION("fontpage_166_251_251") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFB,0xFB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x28,0x00,0x25,0xE0,0x53,0x20,0x99,0x20,0x25, + 0x20,0x43,0x20,0xBD,0x20,0x25,0xA0,0x25,0x40,0x3D,0x00,0x25,0x00}; const u8g_fntpgm_uint8_t fontpage_167_159_159[45] U8G_FONT_SECTION("fontpage_167_159_159") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9f,0x9f,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x3f,0xe0,0x22,0x00,0x2f,0xc0,0x28,0x40,0x2f, - 0xc0,0x28,0x40,0x2f,0xc0,0x22,0x00,0x2a,0x80,0x52,0x60,0xa6,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9F,0x9F,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x3F,0xE0,0x22,0x00,0x2F,0xC0,0x28,0x40,0x2F, + 0xC0,0x28,0x40,0x2F,0xC0,0x22,0x00,0x2A,0x80,0x52,0x60,0xA6,0x20}; +const u8g_fntpgm_uint8_t fontpage_167_205_205[45] U8G_FONT_SECTION("fontpage_167_205_205") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCD,0xCD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x01,0xC0,0x3E,0x00,0x20,0x00,0x20,0x00,0x3F, + 0xC0,0x28,0x80,0x25,0x00,0x22,0x00,0x45,0x00,0x48,0x80,0xB0,0x60}; const u8g_fntpgm_uint8_t fontpage_167_214_214[45] U8G_FONT_SECTION("fontpage_167_214_214") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd6,0xd6,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xfc,0x00,0x4b,0xe0,0x4a,0x20,0x7a,0x20,0x49, - 0x40,0x79,0x40,0x48,0x80,0x4c,0x80,0xf9,0x40,0x0a,0x40,0x0c,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD6,0xD6,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xFC,0x00,0x4B,0xE0,0x4A,0x20,0x7A,0x20,0x49, + 0x40,0x79,0x40,0x48,0x80,0x4C,0x80,0xF9,0x40,0x0A,0x40,0x0C,0x20}; const u8g_fntpgm_uint8_t fontpage_167_240_240[45] U8G_FONT_SECTION("fontpage_167_240_240") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf0,0xf0,0x00,0x0a,0xff,0x00, - 0x00,0x09,0x0b,0x16,0x0c,0x01,0xff,0x08,0x00,0x10,0x00,0x22,0x00,0x41,0x00,0xff, - 0x80,0x00,0x80,0x7f,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x7f,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x0A,0xFF,0x00, + 0x00,0x09,0x0B,0x16,0x0C,0x01,0xFF,0x08,0x00,0x10,0x00,0x22,0x00,0x41,0x00,0xFF, + 0x80,0x00,0x80,0x7F,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x7F,0x00}; const u8g_fntpgm_uint8_t fontpage_168_136_136[45] U8G_FONT_SECTION("fontpage_168_136_136") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x0a,0x00,0x11,0x00,0x20,0x80,0xdf, - 0x60,0x00,0x00,0x3f,0x80,0x20,0x80,0x20,0x80,0x3f,0x80,0x20,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0xDF, + 0x60,0x00,0x00,0x3F,0x80,0x20,0x80,0x20,0x80,0x3F,0x80,0x20,0x80}; +const u8g_fntpgm_uint8_t fontpage_168_166_166[45] U8G_FONT_SECTION("fontpage_168_166_166") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA6,0xA6,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xFF,0xE0,0x04,0x00,0x0D,0x80,0x34,0x40,0xC4, + 0x20,0x04,0x00,0x3F,0xC0,0x20,0x40,0x20,0x40,0x3F,0xC0,0x20,0x40}; +const u8g_fntpgm_uint8_t fontpage_168_202_202[45] U8G_FONT_SECTION("fontpage_168_202_202") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCA,0xCA,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x24,0x00,0x24,0x00,0x3F,0xC0,0x44,0x00,0x04, + 0x00,0xFF,0xE0,0x00,0x00,0x3F,0x80,0x20,0x80,0x20,0x80,0x3F,0x80}; const u8g_fntpgm_uint8_t fontpage_168_253_253[45] U8G_FONT_SECTION("fontpage_168_253_253") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfd,0xfd,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x0a,0x00,0x11,0x00,0xee,0xe0,0x00, - 0x00,0x7b,0xc0,0x4a,0x40,0x4a,0x40,0x7a,0x40,0x4a,0xc0,0x02,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFD,0xFD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x0A,0x00,0x11,0x00,0xEE,0xE0,0x00, + 0x00,0x7B,0xC0,0x4A,0x40,0x4A,0x40,0x7A,0x40,0x4A,0xC0,0x02,0x00}; const u8g_fntpgm_uint8_t fontpage_169_140_140[45] U8G_FONT_SECTION("fontpage_169_140_140") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8c,0x8c,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x0c,0x00,0x70,0x00,0x11,0xe0,0xfd,0x20,0x11, - 0x20,0x39,0x20,0x35,0x20,0x55,0x20,0x91,0x20,0x11,0xe0,0x10,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8C,0x8C,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x0C,0x00,0x70,0x00,0x11,0xE0,0xFD,0x20,0x11, + 0x20,0x39,0x20,0x35,0x20,0x55,0x20,0x91,0x20,0x11,0xE0,0x10,0x00}; const u8g_fntpgm_uint8_t fontpage_170_223_223[45] U8G_FONT_SECTION("fontpage_170_223_223") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xdf,0xdf,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0x7d,0x00,0x45,0xe0,0x7d,0x40,0x43, - 0x40,0x5d,0x40,0x55,0x40,0x54,0x80,0x94,0x80,0x9d,0x40,0x82,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDF,0xDF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x7D,0x00,0x45,0xE0,0x7D,0x40,0x43, + 0x40,0x5D,0x40,0x55,0x40,0x54,0x80,0x94,0x80,0x9D,0x40,0x82,0x20}; const u8g_fntpgm_uint8_t fontpage_171_174_174[45] U8G_FONT_SECTION("fontpage_171_174_174") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xae,0xae,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0xf3,0xc0,0x92,0x40,0x92,0x40,0xff,0xc0,0x44, - 0x80,0x7f,0x80,0x44,0x80,0x7f,0x80,0x04,0x00,0xff,0xc0,0x04,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAE,0xAE,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0xF3,0xC0,0x92,0x40,0x92,0x40,0xFF,0xC0,0x44, + 0x80,0x7F,0x80,0x44,0x80,0x7F,0x80,0x04,0x00,0xFF,0xC0,0x04,0x00}; const u8g_fntpgm_uint8_t fontpage_172_180_180[45] U8G_FONT_SECTION("fontpage_172_180_180") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb4,0xb4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x02,0xa0,0xeb,0xc0,0xaa,0xa0,0xbf,0xe0,0xa4, - 0x80,0xaf,0xe0,0xf9,0x20,0x0f,0xe0,0x09,0x20,0x0f,0xe0,0x11,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB4,0xB4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x02,0xA0,0xEB,0xC0,0xAA,0xA0,0xBF,0xE0,0xA4, + 0x80,0xAF,0xE0,0xF9,0x20,0x0F,0xE0,0x09,0x20,0x0F,0xE0,0x11,0x20}; +const u8g_fntpgm_uint8_t fontpage_172_232_232[45] U8G_FONT_SECTION("fontpage_172_232_232") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE8,0xE8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7B,0xC0,0x4A,0x40,0x4A,0x40,0x7B,0xC0,0x04, + 0x80,0xFF,0xE0,0x11,0x00,0xFB,0xE0,0x4A,0x40,0x4A,0x40,0x7B,0xC0}; const u8g_fntpgm_uint8_t fontpage_172_244_244[45] U8G_FONT_SECTION("fontpage_172_244_244") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf4,0xf4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x01,0x00,0xef,0xe0,0xa5,0x40,0xaf,0xe0,0xa4, - 0x40,0xa7,0xc0,0xe4,0x40,0x07,0xc0,0x04,0x40,0x07,0xc0,0x0c,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF4,0xF4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x01,0x00,0xEF,0xE0,0xA5,0x40,0xAF,0xE0,0xA4, + 0x40,0xA7,0xC0,0xE4,0x40,0x07,0xC0,0x04,0x40,0x07,0xC0,0x0C,0x60}; const u8g_fntpgm_uint8_t fontpage_173_222_222[45] U8G_FONT_SECTION("fontpage_173_222_222") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xde,0xde,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0xff,0xc0,0x80,0x40,0x80,0x40,0x9e,0x40,0x92, - 0x40,0x92,0x40,0x9e,0x40,0x92,0x40,0x80,0x40,0xff,0xc0,0x80,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDE,0xDE,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0xFF,0xC0,0x80,0x40,0x80,0x40,0x9E,0x40,0x92, + 0x40,0x92,0x40,0x9E,0x40,0x92,0x40,0x80,0x40,0xFF,0xC0,0x80,0x40}; const u8g_fntpgm_uint8_t fontpage_173_224_224[45] U8G_FONT_SECTION("fontpage_173_224_224") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe0,0xe0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xff,0xe0,0x84,0x20,0x84,0x20,0xbf,0xa0,0x84, - 0x20,0x84,0x20,0x8a,0x20,0x91,0x20,0xa0,0xa0,0x80,0x20,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xFF,0xE0,0x84,0x20,0x84,0x20,0xBF,0xA0,0x84, + 0x20,0x84,0x20,0x8A,0x20,0x91,0x20,0xA0,0xA0,0x80,0x20,0xFF,0xE0}; +const u8g_fntpgm_uint8_t fontpage_173_250_250[45] U8G_FONT_SECTION("fontpage_173_250_250") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFA,0xFA,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0xFF,0xC0,0x88,0x40,0x88,0x40,0xFF,0x40,0x88, + 0x40,0xBE,0x40,0xA2,0x40,0xA2,0x40,0xBE,0x40,0x80,0x40,0xFF,0xC0}; const u8g_fntpgm_uint8_t fontpage_174_150_150[45] U8G_FONT_SECTION("fontpage_174_150_150") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x96,0x96,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xff,0xe0,0x91,0x20,0x9f,0x20,0x84,0x20,0xff, - 0xe0,0xaa,0xa0,0xae,0xa0,0xa0,0xa0,0xbf,0xa0,0x80,0x20,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x96,0x96,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xFF,0xE0,0x91,0x20,0x9F,0x20,0x84,0x20,0xFF, + 0xE0,0xAA,0xA0,0xAE,0xA0,0xA0,0xA0,0xBF,0xA0,0x80,0x20,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_174_168_168[45] U8G_FONT_SECTION("fontpage_174_168_168") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa8,0xa8,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x08,0x00,0x08,0x00,0xff,0xc0,0x10,0x00,0x22, - 0x00,0x62,0x00,0xaf,0x80,0x22,0x00,0x22,0x00,0x22,0x00,0x3f,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA8,0xA8,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x08,0x00,0x08,0x00,0xFF,0xC0,0x10,0x00,0x22, + 0x00,0x62,0x00,0xAF,0x80,0x22,0x00,0x22,0x00,0x22,0x00,0x3F,0xC0}; const u8g_fntpgm_uint8_t fontpage_175_139_139[45] U8G_FONT_SECTION("fontpage_175_139_139") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8b,0x8b,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x7e,0x40,0x29,0x40,0x29,0x40,0xff,0x40,0x29, - 0x40,0x28,0x40,0x4c,0xc0,0x04,0x00,0x3f,0x80,0x04,0x00,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8B,0x8B,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7E,0x40,0x29,0x40,0x29,0x40,0xFF,0x40,0x29, + 0x40,0x28,0x40,0x4C,0xC0,0x04,0x00,0x3F,0x80,0x04,0x00,0xFF,0xE0}; +const u8g_fntpgm_uint8_t fontpage_175_247_247[45] U8G_FONT_SECTION("fontpage_175_247_247") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF7,0xF7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0xF9,0x00,0x27,0xC0,0xF9,0x40,0x55, + 0x40,0xFB,0x40,0x21,0x40,0xF9,0xC0,0x22,0x40,0x24,0x20,0x28,0x20}; const u8g_fntpgm_uint8_t fontpage_176_202_202[45] U8G_FONT_SECTION("fontpage_176_202_202") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xca,0xca,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x00,0x2f,0xe0,0x29,0x20,0xff,0xe0,0x29, - 0x20,0x2f,0xe0,0x21,0x40,0x33,0xa0,0xe5,0xe0,0x09,0x20,0x10,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCA,0xCA,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0x2F,0xE0,0x29,0x20,0xFF,0xE0,0x29, + 0x20,0x2F,0xE0,0x21,0x40,0x33,0xA0,0xE5,0xE0,0x09,0x20,0x10,0xE0}; const u8g_fntpgm_uint8_t fontpage_176_235_235[45] U8G_FONT_SECTION("fontpage_176_235_235") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xeb,0xeb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x2f,0xe0,0x21,0x00,0xf7,0xc0,0x24, - 0x40,0x27,0x40,0x25,0xc0,0x34,0x40,0xef,0xe0,0x02,0x80,0x0c,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xEB,0xEB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x2F,0xE0,0x21,0x00,0xF7,0xC0,0x24, + 0x40,0x27,0x40,0x25,0xC0,0x34,0x40,0xEF,0xE0,0x02,0x80,0x0C,0x60}; const u8g_fntpgm_uint8_t fontpage_177_138_138[45] U8G_FONT_SECTION("fontpage_177_138_138") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8a,0x8a,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xf9,0x00,0x23,0xc0,0xf9,0x40,0x51,0x40,0xfb, - 0x40,0x22,0xc0,0xfc,0x20,0x24,0x20,0x7f,0xc0,0x04,0x00,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8A,0x8A,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xF9,0x00,0x23,0xC0,0xF9,0x40,0x51,0x40,0xFB, + 0x40,0x22,0xC0,0xFC,0x20,0x24,0x20,0x7F,0xC0,0x04,0x00,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_178_150_150[45] U8G_FONT_SECTION("fontpage_178_150_150") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x96,0x96,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x21,0x00,0x3d,0x00,0x25,0x00,0x45, - 0x80,0xa5,0x40,0x19,0x20,0x09,0x00,0x11,0x00,0x21,0x00,0x41,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x96,0x96,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x21,0x00,0x3D,0x00,0x25,0x00,0x45, + 0x80,0xA5,0x40,0x19,0x20,0x09,0x00,0x11,0x00,0x21,0x00,0x41,0x00}; const u8g_fntpgm_uint8_t fontpage_178_154_154[45] U8G_FONT_SECTION("fontpage_178_154_154") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9a,0x9a,0x00,0x0a,0xff,0x00, - 0x00,0x09,0x0b,0x16,0x0c,0x01,0xff,0x08,0x00,0x1f,0x00,0x21,0x00,0x52,0x00,0x0c, - 0x00,0x34,0x00,0xcf,0x80,0x10,0x80,0x69,0x00,0x06,0x00,0xf8,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9A,0x9A,0x00,0x0A,0xFF,0x00, + 0x00,0x09,0x0B,0x16,0x0C,0x01,0xFF,0x08,0x00,0x1F,0x00,0x21,0x00,0x52,0x00,0x0C, + 0x00,0x34,0x00,0xCF,0x80,0x10,0x80,0x69,0x00,0x06,0x00,0xF8,0x00}; +const u8g_fntpgm_uint8_t fontpage_178_160_160[45] U8G_FONT_SECTION("fontpage_178_160_160") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA0,0xA0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x79,0xE0,0x8A,0x20,0x50,0x20,0x23, + 0xA0,0xFA,0xA0,0x2A,0xA0,0xCB,0xA0,0x28,0x20,0x11,0x20,0xE0,0xC0}; const u8g_fntpgm_uint8_t fontpage_178_167_167[45] U8G_FONT_SECTION("fontpage_178_167_167") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa7,0xa7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x04,0x00,0x04,0x00,0xff,0xe0,0x04, - 0x00,0x04,0x00,0x0a,0x00,0x0a,0x00,0x11,0x00,0x20,0x80,0xc0,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA7,0xA7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x04,0x00,0x04,0x00,0xFF,0xE0,0x04, + 0x00,0x04,0x00,0x0A,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0xC0,0x60}; const u8g_fntpgm_uint8_t fontpage_178_169_170[73] U8G_FONT_SECTION("fontpage_178_169_170") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa9,0xaa,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x7f,0xc0,0x04,0x00,0x04,0x00,0x04,0x00,0xff, - 0xe0,0x04,0x00,0x0a,0x00,0x0a,0x00,0x11,0x00,0x20,0x80,0xc0,0x60,0x0b,0x0b,0x16, - 0x0c,0x00,0xff,0x04,0x00,0x04,0x00,0x04,0x00,0xff,0xe0,0x04,0x00,0x0a,0x00,0x0a, - 0x00,0x11,0x00,0x19,0x00,0x24,0x80,0xc4,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA9,0xAA,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0xC0,0x04,0x00,0x04,0x00,0x04,0x00,0xFF, + 0xE0,0x04,0x00,0x0A,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0xC0,0x60,0x0B,0x0B,0x16, + 0x0C,0x00,0xFF,0x04,0x00,0x04,0x00,0x04,0x00,0xFF,0xE0,0x04,0x00,0x0A,0x00,0x0A, + 0x00,0x11,0x00,0x19,0x00,0x24,0x80,0xC4,0x60}; const u8g_fntpgm_uint8_t fontpage_178_177_177[45] U8G_FONT_SECTION("fontpage_178_177_177") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb1,0xb1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x24,0x00,0x24,0x00,0x3f,0xc0,0x44,0x00,0x04, - 0x00,0xff,0xe0,0x04,0x00,0x0a,0x00,0x11,0x00,0x20,0x80,0xc0,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB1,0xB1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x24,0x00,0x24,0x00,0x3F,0xC0,0x44,0x00,0x04, + 0x00,0xFF,0xE0,0x04,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0xC0,0x60}; const u8g_fntpgm_uint8_t fontpage_179_203_203[45] U8G_FONT_SECTION("fontpage_179_203_203") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcb,0xcb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x21,0x00,0xfa,0x40,0x2a,0x20,0x2f, - 0xe0,0x48,0x00,0x53,0xe0,0x32,0x20,0x2a,0x20,0x4b,0xe0,0x82,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCB,0xCB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x21,0x00,0xFA,0x40,0x2A,0x20,0x2F, + 0xE0,0x48,0x00,0x53,0xE0,0x32,0x20,0x2A,0x20,0x4B,0xE0,0x82,0x20}; +const u8g_fntpgm_uint8_t fontpage_181_146_146[45] U8G_FONT_SECTION("fontpage_181_146_146") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x92,0x92,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x24,0x40,0x2F,0xE0,0x24,0x40,0xF7,0xC0,0x54, + 0x40,0x57,0xC0,0x51,0x00,0x2F,0xE0,0x33,0x80,0x4D,0x40,0x89,0x20}; const u8g_fntpgm_uint8_t fontpage_182_208_208[45] U8G_FONT_SECTION("fontpage_182_208_208") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd0,0xd0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x3f,0x80,0x01,0x00,0x02,0x00,0x04,0x00,0x04, - 0x00,0xff,0xe0,0x04,0x00,0x04,0x00,0x04,0x00,0x14,0x00,0x08,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD0,0xD0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x3F,0x80,0x01,0x00,0x02,0x00,0x04,0x00,0x04, + 0x00,0xFF,0xE0,0x04,0x00,0x04,0x00,0x04,0x00,0x14,0x00,0x08,0x00}; const u8g_fntpgm_uint8_t fontpage_182_216_216[45] U8G_FONT_SECTION("fontpage_182_216_216") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd8,0xd8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x08,0x00,0xff,0xe0,0x10,0x00,0x2f,0xc0,0x20, - 0x80,0x61,0x00,0xbf,0xe0,0x21,0x00,0x21,0x00,0x21,0x00,0x27,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD8,0xD8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x08,0x00,0xFF,0xE0,0x10,0x00,0x2F,0xC0,0x20, + 0x80,0x61,0x00,0xBF,0xE0,0x21,0x00,0x21,0x00,0x21,0x00,0x27,0x00}; const u8g_fntpgm_uint8_t fontpage_183_137_137[45] U8G_FONT_SECTION("fontpage_183_137_137") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x7f,0xe0,0x40,0x20,0x88,0x40,0x08, - 0x00,0xff,0xe0,0x11,0x00,0x31,0x00,0x0e,0x00,0x09,0x80,0x70,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x7F,0xE0,0x40,0x20,0x88,0x40,0x08, + 0x00,0xFF,0xE0,0x11,0x00,0x31,0x00,0x0E,0x00,0x09,0x80,0x70,0x60}; const u8g_fntpgm_uint8_t fontpage_183_140_140[45] U8G_FONT_SECTION("fontpage_183_140_140") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8c,0x8c,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x7f,0xe0,0x40,0x20,0x9f,0x40,0x00, - 0x00,0x7f,0xe0,0x0a,0x00,0x12,0x00,0x12,0x20,0x22,0x20,0x41,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8C,0x8C,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x7F,0xE0,0x40,0x20,0x9F,0x40,0x00, + 0x00,0x7F,0xE0,0x0A,0x00,0x12,0x00,0x12,0x20,0x22,0x20,0x41,0xE0}; const u8g_fntpgm_uint8_t fontpage_183_154_154[45] U8G_FONT_SECTION("fontpage_183_154_154") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9a,0x9a,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x7f,0xe0,0x40,0x20,0x80,0x40,0x3f, - 0xc0,0x04,0x00,0x24,0x00,0x27,0x80,0x24,0x00,0x54,0x00,0x8f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9A,0x9A,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x7F,0xE0,0x40,0x20,0x80,0x40,0x3F, + 0xC0,0x04,0x00,0x24,0x00,0x27,0x80,0x24,0x00,0x54,0x00,0x8F,0xE0}; const u8g_fntpgm_uint8_t fontpage_183_162_162[45] U8G_FONT_SECTION("fontpage_183_162_162") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa2,0xa2,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x08,0x00,0xff,0xc0,0x90,0x40,0x3f,0x00,0x52, - 0x00,0x8c,0x00,0x33,0x00,0xff,0xc0,0x21,0x00,0x21,0x00,0x3f,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA2,0xA2,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x08,0x00,0xFF,0xC0,0x90,0x40,0x3F,0x00,0x52, + 0x00,0x8C,0x00,0x33,0x00,0xFF,0xC0,0x21,0x00,0x21,0x00,0x3F,0x00}; const u8g_fntpgm_uint8_t fontpage_183_185_185[45] U8G_FONT_SECTION("fontpage_183_185_185") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb9,0xb9,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0xff,0xe0,0x91,0x20,0x24,0x80,0x4a, - 0x40,0x11,0x00,0x20,0x80,0xdf,0x60,0x11,0x00,0x11,0x00,0x1f,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB9,0xB9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0xFF,0xE0,0x91,0x20,0x24,0x80,0x4A, + 0x40,0x11,0x00,0x20,0x80,0xDF,0x60,0x11,0x00,0x11,0x00,0x1F,0x00}; const u8g_fntpgm_uint8_t fontpage_184_141_141[45] U8G_FONT_SECTION("fontpage_184_141_141") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8d,0x8d,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x28,0x40,0xaa,0x40,0x6c,0x40,0xff,0xe0,0x28, - 0x40,0x7d,0x40,0x10,0xc0,0x7c,0x40,0x10,0x40,0x1d,0x40,0xe0,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8D,0x8D,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x28,0x40,0xAA,0x40,0x6C,0x40,0xFF,0xE0,0x28, + 0x40,0x7D,0x40,0x10,0xC0,0x7C,0x40,0x10,0x40,0x1D,0x40,0xE0,0x80}; const u8g_fntpgm_uint8_t fontpage_184_143_143[45] U8G_FONT_SECTION("fontpage_184_143_143") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8f,0x8f,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x04,0x00,0x04,0x00,0x24,0x80,0x24, + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8F,0x8F,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x04,0x00,0x04,0x00,0x24,0x80,0x24, 0x40,0x44,0x40,0x44,0x20,0x84,0x20,0x04,0x00,0x14,0x00,0x08,0x00}; const u8g_fntpgm_uint8_t fontpage_184_177_177[45] U8G_FONT_SECTION("fontpage_184_177_177") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb1,0xb1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0xfd,0x40,0x01,0x20,0x7f,0xe0,0x4a, - 0x80,0x7a,0x80,0x12,0x80,0x5a,0xa0,0x56,0xa0,0x92,0xa0,0x34,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB1,0xB1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0xFD,0x40,0x01,0x20,0x7F,0xE0,0x4A, + 0x80,0x7A,0x80,0x12,0x80,0x5A,0xA0,0x56,0xA0,0x92,0xA0,0x34,0x60}; const u8g_fntpgm_uint8_t fontpage_187_229_229[41] U8G_FONT_SECTION("fontpage_187_229_229") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe5,0xe5,0x00,0x09,0x00,0x00, - 0x00,0x0b,0x09,0x12,0x0c,0x00,0x00,0x7f,0xc0,0x04,0x00,0x04,0x00,0x04,0x00,0x04, - 0x00,0x04,0x00,0x04,0x00,0x04,0x00,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE5,0xE5,0x00,0x09,0x00,0x00, + 0x00,0x0B,0x09,0x12,0x0C,0x00,0x00,0x7F,0xC0,0x04,0x00,0x04,0x00,0x04,0x00,0x04, + 0x00,0x04,0x00,0x04,0x00,0x04,0x00,0xFF,0xE0}; +const u8g_fntpgm_uint8_t fontpage_187_238_238[45] U8G_FONT_SECTION("fontpage_187_238_238") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xEE,0xEE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x10,0x80,0x09,0x00,0xFF,0xE0,0x04,0x00,0x7F, + 0xC0,0x08,0x00,0xFF,0xE0,0x10,0x00,0x2F,0x80,0x42,0x00,0xBF,0xE0}; const u8g_fntpgm_uint8_t fontpage_187_242_242[43] U8G_FONT_SECTION("fontpage_187_242_242") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf2,0xf2,0x00,0x09,0xff,0x00, - 0x00,0x0a,0x0a,0x14,0x0c,0x01,0xff,0xff,0x00,0x01,0x00,0x01,0x00,0x81,0x00,0xff, - 0x00,0x80,0x00,0x80,0x40,0x80,0x40,0x80,0x40,0x7f,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF2,0xF2,0x00,0x09,0xFF,0x00, + 0x00,0x0A,0x0A,0x14,0x0C,0x01,0xFF,0xFF,0x00,0x01,0x00,0x01,0x00,0x81,0x00,0xFF, + 0x00,0x80,0x00,0x80,0x40,0x80,0x40,0x80,0x40,0x7F,0xC0}; const u8g_fntpgm_uint8_t fontpage_188_243_243[45] U8G_FONT_SECTION("fontpage_188_243_243") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf3,0xf3,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x7f,0xc0,0x04,0x00,0x24,0x80,0x15,0x00,0x04, - 0x00,0xff,0xe0,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF3,0xF3,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0xC0,0x04,0x00,0x24,0x80,0x15,0x00,0x04, + 0x00,0xFF,0xE0,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00}; const u8g_fntpgm_uint8_t fontpage_189_138_138[45] U8G_FONT_SECTION("fontpage_189_138_138") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8a,0x8a,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x02,0x00,0x7f,0xe0,0x42,0x00,0x42,0x00,0x7f, - 0xe0,0x42,0x00,0x47,0x00,0x4a,0x80,0x52,0x40,0xa2,0x20,0x82,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8A,0x8A,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x02,0x00,0x7F,0xE0,0x42,0x00,0x42,0x00,0x7F, + 0xE0,0x42,0x00,0x47,0x00,0x4A,0x80,0x52,0x40,0xA2,0x20,0x82,0x00}; const u8g_fntpgm_uint8_t fontpage_189_166_166[45] U8G_FONT_SECTION("fontpage_189_166_166") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa6,0xa6,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x7f,0xe0,0x49,0x00,0x7f,0xc0,0x49, - 0x00,0x4f,0x00,0x40,0x00,0x5f,0x80,0x49,0x00,0x86,0x00,0xb9,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA6,0xA6,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x7F,0xE0,0x49,0x00,0x7F,0xC0,0x49, + 0x00,0x4F,0x00,0x40,0x00,0x5F,0x80,0x49,0x00,0x86,0x00,0xB9,0xC0}; const u8g_fntpgm_uint8_t fontpage_189_226_226[45] U8G_FONT_SECTION("fontpage_189_226_226") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe2,0xe2,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x7f,0xe0,0x55,0x40,0x48,0xa0,0x7d, - 0xc0,0x45,0x20,0x5e,0x00,0x51,0xc0,0x5d,0x40,0x84,0x80,0x9b,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE2,0xE2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x7F,0xE0,0x55,0x40,0x48,0xA0,0x7D, + 0xC0,0x45,0x20,0x5E,0x00,0x51,0xC0,0x5D,0x40,0x84,0x80,0x9B,0x60}; const u8g_fntpgm_uint8_t fontpage_189_250_250[45] U8G_FONT_SECTION("fontpage_189_250_250") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfa,0xfa,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x02,0x00,0xef,0xc0,0x22,0x40,0x5f,0xe0,0xe2, - 0x40,0x2f,0xc0,0xa2,0x00,0x6f,0xe0,0x22,0x00,0x52,0x00,0x8f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFA,0xFA,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x02,0x00,0xEF,0xC0,0x22,0x40,0x5F,0xE0,0xE2, + 0x40,0x2F,0xC0,0xA2,0x00,0x6F,0xE0,0x22,0x00,0x52,0x00,0x8F,0xE0}; +const u8g_fntpgm_uint8_t fontpage_190_149_149[45] U8G_FONT_SECTION("fontpage_190_149_149") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x95,0x95,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0xFC,0x40,0x04,0x40,0x04,0x40,0x7C,0x40,0x40, + 0x40,0xFC,0x40,0x04,0x40,0x04,0x40,0x04,0x40,0x28,0x40,0x10,0x40}; const u8g_fntpgm_uint8_t fontpage_191_133_133[45] U8G_FONT_SECTION("fontpage_191_133_133") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x85,0x85,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0x21,0x00,0x47,0xc0,0x91,0x00,0x1f, - 0xe0,0x20,0x80,0x6f,0xe0,0xa4,0x80,0x22,0x80,0x20,0x80,0x21,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x85,0x85,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x21,0x00,0x47,0xC0,0x91,0x00,0x1F, + 0xE0,0x20,0x80,0x6F,0xE0,0xA4,0x80,0x22,0x80,0x20,0x80,0x21,0x80}; const u8g_fntpgm_uint8_t fontpage_191_140_140[45] U8G_FONT_SECTION("fontpage_191_140_140") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8c,0x8c,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x12,0x00,0x24,0x80,0x47,0x00,0x92,0x40,0x2f, - 0xe0,0x64,0x20,0xa7,0xc0,0x2c,0x40,0x32,0x80,0x23,0x80,0x2c,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8C,0x8C,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x12,0x00,0x24,0x80,0x47,0x00,0x92,0x40,0x2F, + 0xE0,0x64,0x20,0xA7,0xC0,0x2C,0x40,0x32,0x80,0x23,0x80,0x2C,0x60}; const u8g_fntpgm_uint8_t fontpage_191_145_145[45] U8G_FONT_SECTION("fontpage_191_145_145") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x91,0x91,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x1f,0xe0,0x25,0x40,0x45,0x40,0x9a,0x80,0x25, - 0x40,0x65,0x40,0xa0,0x00,0x27,0xc0,0x21,0x00,0x21,0x00,0x2f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x91,0x91,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x1F,0xE0,0x25,0x40,0x45,0x40,0x9A,0x80,0x25, + 0x40,0x65,0x40,0xA0,0x00,0x27,0xC0,0x21,0x00,0x21,0x00,0x2F,0xE0}; const u8g_fntpgm_uint8_t fontpage_191_158_158[45] U8G_FONT_SECTION("fontpage_191_158_158") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9e,0x9e,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x12,0x40,0x22,0x40,0x45,0xa0,0x99,0x20,0x20, - 0x00,0x65,0x00,0xa5,0x00,0x25,0xe0,0x25,0x00,0x2b,0x00,0x31,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9E,0x9E,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x12,0x40,0x22,0x40,0x45,0xA0,0x99,0x20,0x20, + 0x00,0x65,0x00,0xA5,0x00,0x25,0xE0,0x25,0x00,0x2B,0x00,0x31,0xE0}; const u8g_fntpgm_uint8_t fontpage_191_169_169[45] U8G_FONT_SECTION("fontpage_191_169_169") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa9,0xa9,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x14,0x00,0x27,0xe0,0x4c,0x40,0x97,0xc0,0x24, - 0x40,0x67,0xc0,0xa4,0x00,0x27,0xc0,0x2c,0x80,0x33,0x00,0x2c,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA9,0xA9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x14,0x00,0x27,0xE0,0x4C,0x40,0x97,0xC0,0x24, + 0x40,0x67,0xC0,0xA4,0x00,0x27,0xC0,0x2C,0x80,0x33,0x00,0x2C,0xE0}; const u8g_fntpgm_uint8_t fontpage_191_174_174[45] U8G_FONT_SECTION("fontpage_191_174_174") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xae,0xae,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x2a,0x80,0x6a,0x80,0xbe,0x80,0x01,0xe0,0x5d, - 0x40,0xc3,0x40,0x5d,0x40,0x54,0x80,0x56,0x80,0x55,0x40,0x62,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAE,0xAE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x2A,0x80,0x6A,0x80,0xBE,0x80,0x01,0xE0,0x5D, + 0x40,0xC3,0x40,0x5D,0x40,0x54,0x80,0x56,0x80,0x55,0x40,0x62,0x20}; const u8g_fntpgm_uint8_t fontpage_191_195_195[45] U8G_FONT_SECTION("fontpage_191_195_195") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc3,0xc3,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x02,0x00,0x12,0x00,0x12,0x00,0x10, - 0x40,0x50,0x20,0x50,0x20,0x50,0xa0,0x90,0x80,0x10,0x80,0x0f,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC3,0xC3,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x02,0x00,0x12,0x00,0x12,0x00,0x10, + 0x40,0x50,0x20,0x50,0x20,0x50,0xA0,0x90,0x80,0x10,0x80,0x0F,0x80}; const u8g_fntpgm_uint8_t fontpage_192_167_167[45] U8G_FONT_SECTION("fontpage_192_167_167") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa7,0xa7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x25,0x00,0xb5,0x00,0xaf,0xe0,0xa9, - 0x00,0xb1,0x00,0x27,0xc0,0x21,0x00,0x21,0x00,0x21,0x00,0x2f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA7,0xA7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x25,0x00,0xB5,0x00,0xAF,0xE0,0xA9, + 0x00,0xB1,0x00,0x27,0xC0,0x21,0x00,0x21,0x00,0x21,0x00,0x2F,0xE0}; const u8g_fntpgm_uint8_t fontpage_192_226_226[45] U8G_FONT_SECTION("fontpage_192_226_226") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe2,0xe2,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x00,0x2f,0xe0,0xb2,0x00,0xaa,0x80,0xa4, - 0x80,0xa5,0xa0,0x2a,0xc0,0x30,0x80,0x21,0x40,0x22,0x40,0x24,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE2,0xE2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0x2F,0xE0,0xB2,0x00,0xAA,0x80,0xA4, + 0x80,0xA5,0xA0,0x2A,0xC0,0x30,0x80,0x21,0x40,0x22,0x40,0x24,0x20}; const u8g_fntpgm_uint8_t fontpage_192_239_239[45] U8G_FONT_SECTION("fontpage_192_239_239") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xef,0xef,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x08,0x00,0x3f,0x80,0x20,0x80,0x3f,0x80,0x20, - 0x80,0x3f,0x80,0x20,0x80,0x3f,0x80,0x54,0x40,0x52,0xa0,0x8f,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xEF,0xEF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x08,0x00,0x3F,0x80,0x20,0x80,0x3F,0x80,0x20, + 0x80,0x3F,0x80,0x20,0x80,0x3F,0x80,0x54,0x40,0x52,0xA0,0x8F,0x80}; const u8g_fntpgm_uint8_t fontpage_195_182_182[45] U8G_FONT_SECTION("fontpage_195_182_182") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb6,0xb6,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x27,0xe0,0xb2,0x80,0xaf,0xe0,0xa4, - 0x40,0x27,0xc0,0x24,0x40,0x27,0xc0,0x25,0x40,0x2c,0xa0,0x33,0xa0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB6,0xB6,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x27,0xE0,0xB2,0x80,0xAF,0xE0,0xA4, + 0x40,0x27,0xC0,0x24,0x40,0x27,0xC0,0x25,0x40,0x2C,0xA0,0x33,0xA0}; const u8g_fntpgm_uint8_t fontpage_195_201_201[45] U8G_FONT_SECTION("fontpage_195_201_201") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc9,0xc9,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x02,0x00,0x7f,0xe0,0x4a,0x80,0x57,0xe0,0x7c, - 0x80,0x57,0xc0,0x54,0x80,0x57,0xe0,0x4a,0x40,0xa8,0xa0,0x4f,0xa0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC9,0xC9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x02,0x00,0x7F,0xE0,0x4A,0x80,0x57,0xE0,0x7C, + 0x80,0x57,0xC0,0x54,0x80,0x57,0xE0,0x4A,0x40,0xA8,0xA0,0x4F,0xA0}; const u8g_fntpgm_uint8_t fontpage_196_144_144[45] U8G_FONT_SECTION("fontpage_196_144_144") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x90,0x90,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x02,0x80,0x02,0x40,0x7f,0xe0,0x42,0x00,0x42, - 0x00,0x7a,0x40,0x4a,0x40,0x4a,0x80,0x49,0x20,0x52,0xa0,0x84,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x90,0x90,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x02,0x80,0x02,0x40,0x7F,0xE0,0x42,0x00,0x42, + 0x00,0x7A,0x40,0x4A,0x40,0x4A,0x80,0x49,0x20,0x52,0xA0,0x84,0x60}; const u8g_fntpgm_uint8_t fontpage_196_182_182[45] U8G_FONT_SECTION("fontpage_196_182_182") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb6,0xb6,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x00,0xff,0x01,0xc0,0x3e,0x00,0x20,0x00,0x3f,0xc0,0x20, - 0x40,0x20,0x40,0x3f,0xc0,0x20,0x00,0x20,0x00,0x40,0x00,0x80,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB6,0xB6,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x00,0xFF,0x01,0xC0,0x3E,0x00,0x20,0x00,0x3F,0xC0,0x20, + 0x40,0x20,0x40,0x3F,0xC0,0x20,0x00,0x20,0x00,0x40,0x00,0x80,0x00}; const u8g_fntpgm_uint8_t fontpage_196_192_192[45] U8G_FONT_SECTION("fontpage_196_192_192") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc0,0xc0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x18,0x60,0x63,0x80,0x42,0x00,0x7a,0x00,0x4b, - 0xe0,0x4a,0x40,0x7a,0x40,0x42,0x40,0x42,0x40,0x44,0x40,0x88,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x18,0x60,0x63,0x80,0x42,0x00,0x7A,0x00,0x4B, + 0xE0,0x4A,0x40,0x7A,0x40,0x42,0x40,0x42,0x40,0x44,0x40,0x88,0x40}; const u8g_fntpgm_uint8_t fontpage_196_199_199[45] U8G_FONT_SECTION("fontpage_196_199_199") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc7,0xc7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x7f,0xe0,0x40,0x20,0x7f,0xe0,0x40, - 0x00,0x7d,0xe0,0x44,0x20,0x54,0xa0,0x4c,0x60,0x54,0xa0,0xa9,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC7,0xC7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x7F,0xE0,0x40,0x20,0x7F,0xE0,0x40, + 0x00,0x7D,0xE0,0x44,0x20,0x54,0xA0,0x4C,0x60,0x54,0xA0,0xA9,0x60}; const u8g_fntpgm_uint8_t fontpage_196_203_203[45] U8G_FONT_SECTION("fontpage_196_203_203") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcb,0xcb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x03,0xc0,0x7c,0x00,0x04,0x00,0x7f,0xc0,0x04, - 0x00,0x04,0x00,0xff,0xe0,0x04,0x00,0x04,0x00,0x04,0x00,0x0c,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCB,0xCB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x03,0xC0,0x7C,0x00,0x04,0x00,0x7F,0xC0,0x04, + 0x00,0x04,0x00,0xFF,0xE0,0x04,0x00,0x04,0x00,0x04,0x00,0x0C,0x00}; const u8g_fntpgm_uint8_t fontpage_196_211_211[45] U8G_FONT_SECTION("fontpage_196_211_211") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd3,0xd3,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x00,0x27,0xe0,0xf8,0x80,0x20,0x80,0x28, - 0x80,0x30,0x80,0x60,0x80,0xa0,0x80,0x20,0x80,0x20,0x80,0xe3,0x80}; -const u8g_fntpgm_uint8_t fontpage_196_231_231[45] U8G_FONT_SECTION("fontpage_196_231_231") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe7,0xe7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x00,0x22,0x00,0xff,0x80,0x22,0x80,0x2a, - 0x80,0x36,0x80,0x62,0x80,0xa7,0xa0,0x24,0xa0,0xa8,0xa0,0x50,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD3,0xD3,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x00,0x27,0xE0,0xF8,0x80,0x20,0x80,0x28, + 0x80,0x30,0x80,0x60,0x80,0xA0,0x80,0x20,0x80,0x20,0x80,0xE3,0x80}; const u8g_fntpgm_uint8_t fontpage_196_249_249[45] U8G_FONT_SECTION("fontpage_196_249_249") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf9,0xf9,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x24,0x80,0x24,0x80,0xfc,0x80,0x24,0xa0,0x2f, - 0xc0,0x34,0x80,0x64,0x80,0xa4,0x80,0x25,0xa0,0x26,0xa0,0xe4,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF9,0xF9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x24,0x80,0x24,0x80,0xFC,0x80,0x24,0xA0,0x2F, + 0xC0,0x34,0x80,0x64,0x80,0xA4,0x80,0x25,0xA0,0x26,0xA0,0xE4,0x60}; const u8g_fntpgm_uint8_t fontpage_197_150_150[45] U8G_FONT_SECTION("fontpage_197_150_150") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x96,0x96,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x40,0x22,0x40,0xf9,0x40,0x20,0x40,0x2a, - 0x40,0x31,0x40,0x60,0xe0,0xaf,0x40,0x20,0x40,0x20,0x40,0xe0,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x96,0x96,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x40,0x22,0x40,0xF9,0x40,0x20,0x40,0x2A, + 0x40,0x31,0x40,0x60,0xE0,0xAF,0x40,0x20,0x40,0x20,0x40,0xE0,0x40}; const u8g_fntpgm_uint8_t fontpage_197_189_189[45] U8G_FONT_SECTION("fontpage_197_189_189") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbd,0xbd,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x80,0x20,0x80,0xf8,0x80,0x27,0xe0,0x2c, - 0xa0,0x34,0xa0,0x67,0xe0,0xa4,0xa0,0x24,0xa0,0x27,0xe0,0xe4,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBD,0xBD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x80,0x20,0x80,0xF8,0x80,0x27,0xE0,0x2C, + 0xA0,0x34,0xA0,0x67,0xE0,0xA4,0xA0,0x24,0xA0,0x27,0xE0,0xE4,0x20}; const u8g_fntpgm_uint8_t fontpage_197_212_212[45] U8G_FONT_SECTION("fontpage_197_212_212") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd4,0xd4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x80,0x22,0x40,0xff,0xe0,0x22,0x00,0x2b, - 0xc0,0x32,0x40,0x65,0x40,0xa4,0x80,0x28,0x80,0x29,0x40,0xe6,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD4,0xD4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x80,0x22,0x40,0xFF,0xE0,0x22,0x00,0x2B, + 0xC0,0x32,0x40,0x65,0x40,0xA4,0x80,0x28,0x80,0x29,0x40,0xE6,0x20}; const u8g_fntpgm_uint8_t fontpage_198_137_137[45] U8G_FONT_SECTION("fontpage_198_137_137") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x20,0x80,0xff,0xe0,0x25,0x20,0x29, - 0x00,0x37,0xe0,0x62,0x40,0xa6,0x40,0x21,0x80,0x22,0x80,0xec,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x20,0x80,0xFF,0xE0,0x25,0x20,0x29, + 0x00,0x37,0xE0,0x62,0x40,0xA6,0x40,0x21,0x80,0x22,0x80,0xEC,0x60}; const u8g_fntpgm_uint8_t fontpage_199_137_137[45] U8G_FONT_SECTION("fontpage_199_137_137") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x21,0xe0,0xf9,0x00,0x27,0xc0,0x2c, - 0x40,0x37,0xc0,0x64,0x40,0xa7,0xc0,0x21,0x00,0x2f,0xe0,0xe1,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x21,0xE0,0xF9,0x00,0x27,0xC0,0x2C, + 0x40,0x37,0xC0,0x64,0x40,0xA7,0xC0,0x21,0x00,0x2F,0xE0,0xE1,0x00}; const u8g_fntpgm_uint8_t fontpage_199_162_162[45] U8G_FONT_SECTION("fontpage_199_162_162") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa2,0xa2,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x2f,0xe0,0x28,0x20,0xf2,0x80,0x24,0x40,0x29, - 0x20,0x31,0x00,0x6f,0xe0,0xa1,0x00,0x25,0x80,0x29,0x40,0xf1,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA2,0xA2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x2F,0xE0,0x28,0x20,0xF2,0x80,0x24,0x40,0x29, + 0x20,0x31,0x00,0x6F,0xE0,0xA1,0x00,0x25,0x80,0x29,0x40,0xF1,0x20}; +const u8g_fntpgm_uint8_t fontpage_199_165_165[45] U8G_FONT_SECTION("fontpage_199_165_165") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA5,0xA5,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x2F,0xE0,0xF4,0x40,0x22,0x80,0x2F, + 0xE0,0x31,0x00,0x6F,0xE0,0xA2,0x40,0x26,0x80,0x21,0x40,0xEE,0x20}; const u8g_fntpgm_uint8_t fontpage_199_167_167[45] U8G_FONT_SECTION("fontpage_199_167_167") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa7,0xa7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x2f,0xe0,0xf8,0x20,0x22,0x80,0x24, - 0x40,0x38,0x20,0x67,0xc0,0xa1,0x00,0x21,0x00,0x21,0x00,0xef,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA7,0xA7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x2F,0xE0,0xF8,0x20,0x22,0x80,0x24, + 0x40,0x38,0x20,0x67,0xC0,0xA1,0x00,0x21,0x00,0x21,0x00,0xEF,0xE0}; +const u8g_fntpgm_uint8_t fontpage_199_208_208[45] U8G_FONT_SECTION("fontpage_199_208_208") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD0,0xD0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x27,0xC0,0x24,0x40,0xFF,0xC0,0x24,0x40,0x27, + 0xC0,0x30,0x00,0x6F,0xE0,0xA5,0x00,0x25,0xE0,0x2B,0x00,0xF1,0xE0}; const u8g_fntpgm_uint8_t fontpage_199_210_210[45] U8G_FONT_SECTION("fontpage_199_210_210") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd2,0xd2,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0xc0,0x27,0x00,0xf1,0x00,0x2f,0xe0,0x21, - 0x00,0x35,0x60,0x69,0x20,0xad,0x60,0x29,0x20,0x29,0x20,0xef,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD2,0xD2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0xC0,0x27,0x00,0xF1,0x00,0x2F,0xE0,0x21, + 0x00,0x35,0x60,0x69,0x20,0xAD,0x60,0x29,0x20,0x29,0x20,0xEF,0xE0}; const u8g_fntpgm_uint8_t fontpage_199_219_219[45] U8G_FONT_SECTION("fontpage_199_219_219") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xdb,0xdb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x00,0x23,0xc0,0xf4,0x80,0x2f,0xe0,0x2a, - 0xa0,0x3a,0xa0,0x6c,0x60,0xa1,0x00,0x2f,0xe0,0x22,0x80,0xec,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDB,0xDB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0x23,0xC0,0xF4,0x80,0x2F,0xE0,0x2A, + 0xA0,0x3A,0xA0,0x6C,0x60,0xA1,0x00,0x2F,0xE0,0x22,0x80,0xEC,0x60}; const u8g_fntpgm_uint8_t fontpage_201_199_199[45] U8G_FONT_SECTION("fontpage_201_199_199") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc7,0xc7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x2f,0xe0,0x2a,0xa0,0xff,0xe0,0x21,0x00,0x2f, - 0xe0,0x32,0x80,0xe7,0xc0,0x21,0x00,0x2f,0xe0,0xa1,0x00,0x61,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC7,0xC7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x2F,0xE0,0x2A,0xA0,0xFF,0xE0,0x21,0x00,0x2F, + 0xE0,0x32,0x80,0xE7,0xC0,0x21,0x00,0x2F,0xE0,0xA1,0x00,0x61,0x00}; const u8g_fntpgm_uint8_t fontpage_201_202_203[73] U8G_FONT_SECTION("fontpage_201_202_203") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xca,0xcb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xfd,0xc0,0xa9,0x40,0xf9,0x60,0xab,0xc0,0xfd, - 0x40,0xa9,0x80,0xab,0x60,0xfe,0x00,0x04,0x00,0xff,0xe0,0x04,0x00,0x0b,0x0b,0x16, - 0x0c,0x00,0xff,0x29,0x20,0x25,0x40,0xff,0xe0,0x2a,0xa0,0x2b,0x80,0x30,0x00,0xef, - 0xe0,0x29,0x20,0x2f,0xe0,0xa9,0x20,0x6f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCA,0xCB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xFD,0xC0,0xA9,0x40,0xF9,0x60,0xAB,0xC0,0xFD, + 0x40,0xA9,0x80,0xAB,0x60,0xFE,0x00,0x04,0x00,0xFF,0xE0,0x04,0x00,0x0B,0x0B,0x16, + 0x0C,0x00,0xFF,0x29,0x20,0x25,0x40,0xFF,0xE0,0x2A,0xA0,0x2B,0x80,0x30,0x00,0xEF, + 0xE0,0x29,0x20,0x2F,0xE0,0xA9,0x20,0x6F,0xE0}; const u8g_fntpgm_uint8_t fontpage_201_224_224[45] U8G_FONT_SECTION("fontpage_201_224_224") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe0,0xe0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x2f,0xe0,0xfa,0xa0,0x25,0x40,0x2d, - 0x60,0x35,0x40,0xe4,0x40,0x27,0xc0,0x24,0x40,0xa7,0xc0,0x68,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x2F,0xE0,0xFA,0xA0,0x25,0x40,0x2D, + 0x60,0x35,0x40,0xE4,0x40,0x27,0xC0,0x24,0x40,0xA7,0xC0,0x68,0x40}; +const u8g_fntpgm_uint8_t fontpage_202_182_182[45] U8G_FONT_SECTION("fontpage_202_182_182") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB6,0xB6,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x12,0x00,0x12,0x00,0x93,0xE0,0x94,0x40,0x9A, + 0x40,0x92,0x40,0xB2,0x80,0xD1,0x00,0x91,0x80,0x12,0x40,0x14,0x20}; const u8g_fntpgm_uint8_t fontpage_202_190_190[45] U8G_FONT_SECTION("fontpage_202_190_190") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbe,0xbe,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x11,0x00,0xfd,0xe0,0x22,0x40,0x25, - 0x40,0x39,0x40,0x29,0x40,0x28,0x80,0x49,0x80,0x4a,0x40,0x94,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBE,0xBE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x11,0x00,0xFD,0xE0,0x22,0x40,0x25, + 0x40,0x39,0x40,0x29,0x40,0x28,0x80,0x49,0x80,0x4A,0x40,0x94,0x20}; const u8g_fntpgm_uint8_t fontpage_202_215_215[45] U8G_FONT_SECTION("fontpage_202_215_215") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd7,0xd7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x7d,0x00,0x45,0x00,0x7d,0xe0,0x47,0x40,0x7d, - 0x40,0x45,0x40,0x7d,0x40,0x45,0x40,0x28,0x80,0x45,0x40,0x86,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD7,0xD7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7D,0x00,0x45,0x00,0x7D,0xE0,0x47,0x40,0x7D, + 0x40,0x45,0x40,0x7D,0x40,0x45,0x40,0x28,0x80,0x45,0x40,0x86,0x20}; const u8g_fntpgm_uint8_t fontpage_202_244_244[45] U8G_FONT_SECTION("fontpage_202_244_244") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf4,0xf4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0xff,0xe0,0x55,0x40,0x7c,0x80,0x39, - 0x40,0x56,0x20,0x7f,0xc0,0x04,0x00,0x27,0x80,0x24,0x00,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF4,0xF4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0xFF,0xE0,0x55,0x40,0x7C,0x80,0x39, + 0x40,0x56,0x20,0x7F,0xC0,0x04,0x00,0x27,0x80,0x24,0x00,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_202_248_248[45] U8G_FONT_SECTION("fontpage_202_248_248") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf8,0xf8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0x7d,0x00,0x55,0xe0,0xff,0x40,0x55, - 0x40,0xfd,0x40,0x95,0x40,0xff,0x40,0x28,0x80,0x19,0x40,0xe6,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x7D,0x00,0x55,0xE0,0xFF,0x40,0x55, + 0x40,0xFD,0x40,0x95,0x40,0xFF,0x40,0x28,0x80,0x19,0x40,0xE6,0x20}; const u8g_fntpgm_uint8_t fontpage_203_153_153[45] U8G_FONT_SECTION("fontpage_203_153_153") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x99,0x99,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x80,0xac,0x80,0x72,0x80,0x20,0x80,0xfc, - 0x80,0x22,0x80,0x30,0xe0,0x6f,0x80,0xa0,0x80,0x20,0x80,0x20,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x99,0x99,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x80,0xAC,0x80,0x72,0x80,0x20,0x80,0xFC, + 0x80,0x22,0x80,0x30,0xE0,0x6F,0x80,0xA0,0x80,0x20,0x80,0x20,0x80}; const u8g_fntpgm_uint8_t fontpage_203_156_156[45] U8G_FONT_SECTION("fontpage_203_156_156") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9c,0x9c,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x10,0x40,0x29,0x40,0x44,0xc0,0xb8,0x40,0x12, - 0x40,0x7d,0x40,0x10,0x60,0x55,0xc0,0x52,0x40,0x92,0x40,0x30,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9C,0x9C,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x10,0x40,0x29,0x40,0x44,0xC0,0xB8,0x40,0x12, + 0x40,0x7D,0x40,0x10,0x60,0x55,0xC0,0x52,0x40,0x92,0x40,0x30,0x40}; const u8g_fntpgm_uint8_t fontpage_203_176_176[45] U8G_FONT_SECTION("fontpage_203_176_176") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb0,0xb0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x10,0x60,0xfd,0x80,0x45,0x00,0x29,0x00,0xfd, - 0xe0,0x11,0x40,0xfd,0x40,0x11,0x40,0x55,0x40,0x92,0x40,0x34,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB0,0xB0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x10,0x60,0xFD,0x80,0x45,0x00,0x29,0x00,0xFD, + 0xE0,0x11,0x40,0xFD,0x40,0x11,0x40,0x55,0x40,0x92,0x40,0x34,0x40}; +const u8g_fntpgm_uint8_t fontpage_203_183_183[45] U8G_FONT_SECTION("fontpage_203_183_183") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB7,0xB7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xAA,0x40,0xFD,0x80,0x95,0x00,0xAB,0x00,0xFF, + 0xE0,0xA9,0x40,0xAB,0x40,0xFD,0x40,0x95,0x40,0xAB,0x40,0xFE,0x40}; const u8g_fntpgm_uint8_t fontpage_203_188_188[45] U8G_FONT_SECTION("fontpage_203_188_188") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbc,0xbc,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x80,0x10,0x80,0xfd,0x40,0x21,0x40,0x3a, - 0x20,0x2c,0x80,0x28,0x40,0x28,0x40,0x49,0x00,0x48,0x80,0x98,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBC,0xBC,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x80,0x10,0x80,0xFD,0x40,0x21,0x40,0x3A, + 0x20,0x2C,0x80,0x28,0x40,0x28,0x40,0x49,0x00,0x48,0x80,0x98,0x40}; +const u8g_fntpgm_uint8_t fontpage_204_135_135[45] U8G_FONT_SECTION("fontpage_204_135_135") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x87,0x87,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x3F,0xC0,0x20,0x40,0x3F,0xC0,0x20,0x40,0x3F, + 0xC0,0x79,0x00,0x11,0x00,0xFF,0xE0,0x11,0x00,0x21,0x00,0xC1,0x00}; const u8g_fntpgm_uint8_t fontpage_204_142_142[45] U8G_FONT_SECTION("fontpage_204_142_142") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8e,0x8e,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x03,0xe0,0xf2,0x20,0x92,0x20,0x93,0xe0,0xf2, - 0x20,0x92,0x20,0x93,0xe0,0xf2,0x20,0x04,0x20,0x08,0xa0,0x30,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8E,0x8E,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x03,0xE0,0xF2,0x20,0x92,0x20,0x93,0xE0,0xF2, + 0x20,0x92,0x20,0x93,0xE0,0xF2,0x20,0x04,0x20,0x08,0xA0,0x30,0x40}; +const u8g_fntpgm_uint8_t fontpage_204_175_175[45] U8G_FONT_SECTION("fontpage_204_175_175") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAF,0xAF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x1F,0x80,0x10,0x80,0x1F,0x80,0x10,0x80,0x1F, + 0x80,0x00,0x00,0xFF,0xE0,0x24,0x00,0x27,0x80,0x54,0x00,0x8F,0xE0}; const u8g_fntpgm_uint8_t fontpage_204_194_194[45] U8G_FONT_SECTION("fontpage_204_194_194") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc2,0xc2,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x01,0x00,0xf7,0xc0,0x91,0x00,0x91,0x00,0xff, - 0xe0,0x90,0x80,0x9f,0xe0,0x94,0x80,0xf2,0x80,0x00,0x80,0x03,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC2,0xC2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x01,0x00,0xF7,0xC0,0x91,0x00,0x91,0x00,0xFF, + 0xE0,0x90,0x80,0x9F,0xE0,0x94,0x80,0xF2,0x80,0x00,0x80,0x03,0x80}; const u8g_fntpgm_uint8_t fontpage_205_171_171[45] U8G_FONT_SECTION("fontpage_205_171_171") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xab,0xab,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0xe0,0xff,0x00,0x55,0xe0,0x7d,0x40,0x55, - 0x40,0xff,0xc0,0x10,0x40,0x1f,0xc0,0x10,0x40,0x1f,0xc0,0x10,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAB,0xAB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0xE0,0xFF,0x00,0x55,0xE0,0x7D,0x40,0x55, + 0x40,0xFF,0xC0,0x10,0x40,0x1F,0xC0,0x10,0x40,0x1F,0xC0,0x10,0x40}; const u8g_fntpgm_uint8_t fontpage_205_244_244[45] U8G_FONT_SECTION("fontpage_205_244_244") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf4,0xf4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x7f,0xe0,0x02,0x00,0x3f,0xc0,0x22,0x40,0x3f, - 0xc0,0x22,0x40,0x3f,0xc0,0x0a,0x00,0x04,0x00,0x1b,0x00,0xe0,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF4,0xF4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0xE0,0x02,0x00,0x3F,0xC0,0x22,0x40,0x3F, + 0xC0,0x22,0x40,0x3F,0xC0,0x0A,0x00,0x04,0x00,0x1B,0x00,0xE0,0xE0}; const u8g_fntpgm_uint8_t fontpage_206_128_128[45] U8G_FONT_SECTION("fontpage_206_128_128") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x3f,0x80,0x20,0x80,0x3f,0x80,0x20,0x80,0xff, - 0xe0,0x48,0x00,0x7f,0xc0,0x4a,0x40,0x79,0x80,0xc9,0x80,0x0e,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x3F,0x80,0x20,0x80,0x3F,0x80,0x20,0x80,0xFF, + 0xE0,0x48,0x00,0x7F,0xC0,0x4A,0x40,0x79,0x80,0xC9,0x80,0x0E,0x60}; const u8g_fntpgm_uint8_t fontpage_206_137_137[45] U8G_FONT_SECTION("fontpage_206_137_137") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x08,0x00,0xff,0xe0,0x10,0x00,0x1f,0x80,0x30, - 0x80,0x5f,0x80,0x90,0x80,0x1f,0x80,0x10,0x80,0x10,0x80,0x11,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x08,0x00,0xFF,0xE0,0x10,0x00,0x1F,0x80,0x30, + 0x80,0x5F,0x80,0x90,0x80,0x1F,0x80,0x10,0x80,0x10,0x80,0x11,0x80}; const u8g_fntpgm_uint8_t fontpage_206_255_255[45] U8G_FONT_SECTION("fontpage_206_255_255") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0xc0,0x27,0x00,0xfc,0x00,0x24,0x00,0x27, - 0xc0,0x74,0x40,0x6e,0x40,0xa5,0x80,0x28,0x80,0x29,0x40,0x36,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0xC0,0x27,0x00,0xFC,0x00,0x24,0x00,0x27, + 0xC0,0x74,0x40,0x6E,0x40,0xA5,0x80,0x28,0x80,0x29,0x40,0x36,0x20}; const u8g_fntpgm_uint8_t fontpage_207_241_241[45] U8G_FONT_SECTION("fontpage_207_241_241") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf1,0xf1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x00,0x21,0x00,0xff,0xe0,0x21,0x00,0x71, - 0x00,0x69,0x00,0xa7,0xc0,0xa1,0x00,0x21,0x00,0x21,0x00,0x2f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF1,0xF1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0x21,0x00,0xFF,0xE0,0x21,0x00,0x71, + 0x00,0x69,0x00,0xA7,0xC0,0xA1,0x00,0x21,0x00,0x21,0x00,0x2F,0xE0}; const u8g_fntpgm_uint8_t fontpage_208_161_161[45] U8G_FONT_SECTION("fontpage_208_161_161") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa1,0xa1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x00,0x21,0x00,0x2f,0xe0,0xf0,0x00,0x22, - 0x80,0x74,0x40,0x6a,0xa0,0xa2,0x80,0x21,0x00,0x22,0x80,0x2c,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA1,0xA1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0x21,0x00,0x2F,0xE0,0xF0,0x00,0x22, + 0x80,0x74,0x40,0x6A,0xA0,0xA2,0x80,0x21,0x00,0x22,0x80,0x2C,0x60}; const u8g_fntpgm_uint8_t fontpage_208_188_188[45] U8G_FONT_SECTION("fontpage_208_188_188") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbc,0xbc,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x00,0x23,0xc0,0xf4,0x40,0x2a,0x80,0x21, - 0x00,0x72,0x80,0x6c,0x60,0xa7,0xc0,0x24,0x40,0x24,0x40,0x27,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBC,0xBC,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0x23,0xC0,0xF4,0x40,0x2A,0x80,0x21, + 0x00,0x72,0x80,0x6C,0x60,0xA7,0xC0,0x24,0x40,0x24,0x40,0x27,0xC0}; const u8g_fntpgm_uint8_t fontpage_209_157_157[45] U8G_FONT_SECTION("fontpage_209_157_157") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9d,0x9d,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x24,0x00,0x27,0xe0,0x5a,0x40,0x51,0x80,0xde, - 0x60,0x51,0x00,0x5f,0xe0,0x51,0x00,0x45,0x40,0x49,0x20,0x53,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9D,0x9D,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x24,0x00,0x27,0xE0,0x5A,0x40,0x51,0x80,0xDE, + 0x60,0x51,0x00,0x5F,0xE0,0x51,0x00,0x45,0x40,0x49,0x20,0x53,0x20}; +const u8g_fntpgm_uint8_t fontpage_209_196_196[45] U8G_FONT_SECTION("fontpage_209_196_196") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC4,0xC4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0xFF,0xE0,0x20,0x80,0x7F,0xC0,0x24, + 0x80,0xFF,0xE0,0x24,0x80,0xFF,0xE0,0x15,0x00,0x24,0x80,0xC4,0x60}; const u8g_fntpgm_uint8_t fontpage_211_253_253[45] U8G_FONT_SECTION("fontpage_211_253_253") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfd,0xfd,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x80,0x2f,0xe0,0xfa,0xa0,0x2f,0xe0,0x2a, - 0xa0,0x3f,0xe0,0x64,0x40,0xa7,0xc0,0x24,0x40,0x27,0xc0,0x24,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFD,0xFD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x80,0x2F,0xE0,0xFA,0xA0,0x2F,0xE0,0x2A, + 0xA0,0x3F,0xE0,0x64,0x40,0xA7,0xC0,0x24,0x40,0x27,0xC0,0x24,0x40}; const u8g_fntpgm_uint8_t fontpage_212_217_217[45] U8G_FONT_SECTION("fontpage_212_217_217") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd9,0xd9,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x2f,0x40,0x2a,0xa0,0xf4,0x40,0x27,0xc0,0x38, - 0x20,0x27,0xc0,0x64,0x40,0xa7,0xc0,0x24,0x40,0x22,0x80,0x2f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD9,0xD9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x2F,0x40,0x2A,0xA0,0xF4,0x40,0x27,0xC0,0x38, + 0x20,0x27,0xC0,0x64,0x40,0xA7,0xC0,0x24,0x40,0x22,0x80,0x2F,0xE0}; const u8g_fntpgm_uint8_t fontpage_212_223_223[45] U8G_FONT_SECTION("fontpage_212_223_223") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xdf,0xdf,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x25,0x40,0x29,0xa0,0xff,0x40,0x25,0x20,0x6f, - 0xe0,0x75,0x40,0xaf,0xe0,0xa5,0x40,0x26,0xa0,0x29,0x60,0x32,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDF,0xDF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x25,0x40,0x29,0xA0,0xFF,0x40,0x25,0x20,0x6F, + 0xE0,0x75,0x40,0xAF,0xE0,0xA5,0x40,0x26,0xA0,0x29,0x60,0x32,0x20}; const u8g_fntpgm_uint8_t fontpage_213_162_162[45] U8G_FONT_SECTION("fontpage_213_162_162") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa2,0xa2,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x22,0x80,0xf4,0x40,0x2b,0xa0,0x60, - 0x00,0x7e,0xe0,0xaa,0xa0,0xae,0xe0,0x24,0x40,0x2a,0xc0,0x31,0x20}; -const u8g_fntpgm_uint8_t fontpage_214_226_226[45] U8G_FONT_SECTION("fontpage_214_226_226") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe2,0xe2,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x04,0x00,0x04,0x00,0x04,0x00,0x24,0x00,0x27, - 0x80,0x24,0x00,0x24,0x00,0x24,0x00,0x24,0x00,0x24,0x00,0xff,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA2,0xA2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x22,0x80,0xF4,0x40,0x2B,0xA0,0x60, + 0x00,0x7E,0xE0,0xAA,0xA0,0xAE,0xE0,0x24,0x40,0x2A,0xC0,0x31,0x20}; +const u8g_fntpgm_uint8_t fontpage_214_226_227[71] U8G_FONT_SECTION("fontpage_214_226_227") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE2,0xE3,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x04,0x00,0x04,0x00,0x04,0x00,0x24,0x00,0x27, + 0x80,0x24,0x00,0x24,0x00,0x24,0x00,0x24,0x00,0x24,0x00,0xFF,0xC0,0x0B,0x0A,0x14, + 0x0C,0x00,0xFF,0xFF,0xE0,0x04,0x00,0x04,0x00,0x24,0x00,0x27,0xC0,0x24,0x00,0x24, + 0x00,0x24,0x00,0x24,0x00,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_214_229_229[45] U8G_FONT_SECTION("fontpage_214_229_229") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe5,0xe5,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x27,0xc0,0x24,0x00,0x24,0x00,0xff, - 0xe0,0x04,0x00,0x14,0x40,0x24,0x80,0x41,0x00,0x06,0x00,0xf8,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE5,0xE5,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x27,0xC0,0x24,0x00,0x24,0x00,0xFF, + 0xE0,0x04,0x00,0x14,0x40,0x24,0x80,0x41,0x00,0x06,0x00,0xF8,0x00}; const u8g_fntpgm_uint8_t fontpage_214_248_248[45] U8G_FONT_SECTION("fontpage_214_248_248") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf8,0xf8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x43,0xc0,0xf0,0x40,0x93,0xc0,0xf8,0x40,0x8f, - 0xe0,0xfc,0xa0,0x20,0x80,0xbb,0xe0,0xa2,0xa0,0xba,0xe0,0xe0,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x43,0xC0,0xF0,0x40,0x93,0xC0,0xF8,0x40,0x8F, + 0xE0,0xFC,0xA0,0x20,0x80,0xBB,0xE0,0xA2,0xA0,0xBA,0xE0,0xE0,0x80}; const u8g_fntpgm_uint8_t fontpage_215_188_188[45] U8G_FONT_SECTION("fontpage_215_188_188") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbc,0xbc,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0xc0,0xfd,0x40,0x11,0x40,0xff,0x60,0x84, - 0x00,0x7b,0xe0,0x01,0x40,0x79,0x40,0x4a,0x80,0x4d,0x40,0x82,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBC,0xBC,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0xC0,0xFD,0x40,0x11,0x40,0xFF,0x60,0x84, + 0x00,0x7B,0xE0,0x01,0x40,0x79,0x40,0x4A,0x80,0x4D,0x40,0x82,0x20}; const u8g_fntpgm_uint8_t fontpage_215_212_212[45] U8G_FONT_SECTION("fontpage_215_212_212") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd4,0xd4,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x84,0x00,0x84,0x00,0x84,0x80,0x85,0x00,0xf6, - 0x00,0x84,0x00,0x84,0x00,0x84,0x00,0xb4,0x40,0xc4,0x40,0x83,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD4,0xD4,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x84,0x00,0x84,0x00,0x84,0x80,0x85,0x00,0xF6, + 0x00,0x84,0x00,0x84,0x00,0x84,0x00,0xB4,0x40,0xC4,0x40,0x83,0xC0}; const u8g_fntpgm_uint8_t fontpage_217_146_146[45] U8G_FONT_SECTION("fontpage_217_146_146") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x92,0x92,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x42,0x00,0x23,0xc0,0x84,0x40,0x59,0x40,0x10, - 0x80,0x27,0xc0,0x24,0x40,0xc2,0x80,0x41,0x00,0x46,0x80,0x58,0x60}; -const u8g_fntpgm_uint8_t fontpage_218_187_187[45] U8G_FONT_SECTION("fontpage_218_187_187") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbb,0xbb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x40,0xc0,0x27,0x00,0x81,0x00,0x5f,0xe0,0x11, - 0x00,0x21,0x00,0x27,0xc0,0xc4,0x40,0x44,0x40,0x47,0xc0,0x44,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x92,0x92,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x42,0x00,0x23,0xC0,0x84,0x40,0x59,0x40,0x10, + 0x80,0x27,0xC0,0x24,0x40,0xC2,0x80,0x41,0x00,0x46,0x80,0x58,0x60}; const u8g_fntpgm_uint8_t fontpage_219_136_136[45] U8G_FONT_SECTION("fontpage_219_136_136") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x49,0x20,0x25,0x40,0x81,0x00,0x57,0xe0,0x14, - 0x20,0x27,0xe0,0x24,0x20,0xc7,0xe0,0x44,0x20,0x44,0x20,0x44,0x60}; -const u8g_fntpgm_uint8_t fontpage_219_188_188[45] U8G_FONT_SECTION("fontpage_219_188_188") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbc,0xbc,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x42,0x00,0x21,0x00,0x8f,0xe0,0x50,0x00,0x17, - 0xc0,0x24,0x40,0x27,0xc0,0xc1,0x00,0x45,0x40,0x49,0x20,0x53,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x49,0x20,0x25,0x40,0x81,0x00,0x57,0xE0,0x14, + 0x20,0x27,0xE0,0x24,0x20,0xC7,0xE0,0x44,0x20,0x44,0x20,0x44,0x60}; const u8g_fntpgm_uint8_t fontpage_219_225_225[45] U8G_FONT_SECTION("fontpage_219_225_225") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe1,0xe1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x41,0x00,0x25,0x40,0x09,0x80,0x82,0x80,0x54, - 0x40,0x29,0x20,0x25,0x40,0xc5,0x80,0x49,0x00,0x42,0x80,0x5c,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE1,0xE1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x41,0x00,0x25,0x40,0x09,0x80,0x82,0x80,0x54, + 0x40,0x29,0x20,0x25,0x40,0xC5,0x80,0x49,0x00,0x42,0x80,0x5C,0x60}; const u8g_fntpgm_uint8_t fontpage_220_133_133[45] U8G_FONT_SECTION("fontpage_220_133_133") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x85,0x85,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x41,0x00,0x2f,0xe0,0x01,0x00,0x97,0xc0,0x51, - 0x00,0x2f,0xe0,0x24,0x40,0xc7,0x40,0x45,0xc0,0x44,0x40,0x44,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x85,0x85,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x41,0x00,0x2F,0xE0,0x01,0x00,0x97,0xC0,0x51, + 0x00,0x2F,0xE0,0x24,0x40,0xC7,0x40,0x45,0xC0,0x44,0x40,0x44,0xC0}; const u8g_fntpgm_uint8_t fontpage_220_172_172[45] U8G_FONT_SECTION("fontpage_220_172_172") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xac,0xac,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x4e,0x20,0x2a,0xa0,0x0a,0xa0,0x8e,0xa0,0x5a, - 0xa0,0x2e,0xa0,0x2a,0xa0,0xca,0xa0,0x4e,0x20,0x4a,0x20,0x51,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAC,0xAC,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x4E,0x20,0x2A,0xA0,0x0A,0xA0,0x8E,0xA0,0x5A, + 0xA0,0x2E,0xA0,0x2A,0xA0,0xCA,0xA0,0x4E,0x20,0x4A,0x20,0x51,0x60}; const u8g_fntpgm_uint8_t fontpage_221_144_144[45] U8G_FONT_SECTION("fontpage_221_144_144") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x90,0x90,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x4f,0xe0,0x28,0x80,0x8b,0xe0,0x4a,0x20,0x1b, - 0xe0,0x2a,0x20,0x2b,0xe0,0xc8,0x80,0x4a,0xc0,0x54,0xa0,0x69,0xa0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x90,0x90,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x4F,0xE0,0x28,0x80,0x8B,0xE0,0x4A,0x20,0x1B, + 0xE0,0x2A,0x20,0x2B,0xE0,0xC8,0x80,0x4A,0xC0,0x54,0xA0,0x69,0xA0}; const u8g_fntpgm_uint8_t fontpage_221_150_150[45] U8G_FONT_SECTION("fontpage_221_150_150") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x96,0x96,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x85,0x00,0x4f,0xe0,0x99,0x00,0x4f,0xc0,0x49, - 0x00,0xcf,0xc0,0x49,0x00,0x4f,0xe0,0x04,0x00,0xff,0xe0,0x04,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x96,0x96,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x85,0x00,0x4F,0xE0,0x99,0x00,0x4F,0xC0,0x49, + 0x00,0xCF,0xC0,0x49,0x00,0x4F,0xE0,0x04,0x00,0xFF,0xE0,0x04,0x00}; const u8g_fntpgm_uint8_t fontpage_221_171_171[45] U8G_FONT_SECTION("fontpage_221_171_171") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xab,0xab,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x47,0xc0,0x25,0x40,0x06,0xc0,0x84,0x40,0x47, - 0xc0,0x20,0x00,0x2f,0xe0,0xca,0xa0,0x4a,0xa0,0x4a,0xa0,0x5f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAB,0xAB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x47,0xC0,0x25,0x40,0x06,0xC0,0x84,0x40,0x47, + 0xC0,0x20,0x00,0x2F,0xE0,0xCA,0xA0,0x4A,0xA0,0x4A,0xA0,0x5F,0xE0}; const u8g_fntpgm_uint8_t fontpage_223_192_192[45] U8G_FONT_SECTION("fontpage_223_192_192") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc0,0xc0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x44,0x80,0x3e,0x80,0x12,0xe0,0x9e,0xa0,0x53, - 0xa0,0x3e,0xa0,0x28,0xa0,0xdf,0xa0,0x4a,0x40,0x52,0xa0,0x65,0x20}; -const u8g_fntpgm_uint8_t fontpage_224_239_239[45] U8G_FONT_SECTION("fontpage_224_239_239") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xef,0xef,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x10,0x00,0x17,0xe0,0x54,0x80,0x58,0x80,0x50, - 0x80,0x90,0x80,0x10,0x80,0x10,0x80,0x28,0x80,0x44,0x80,0x81,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x44,0x80,0x3E,0x80,0x12,0xE0,0x9E,0xA0,0x53, + 0xA0,0x3E,0xA0,0x28,0xA0,0xDF,0xA0,0x4A,0x40,0x52,0xA0,0x65,0x20}; const u8g_fntpgm_uint8_t fontpage_226_161_161[45] U8G_FONT_SECTION("fontpage_226_161_161") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa1,0xa1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x40,0x00,0x7f,0xe0,0xaa,0x80,0x2a,0x80,0xff, - 0xe0,0x2a,0x80,0x2a,0x80,0xff,0xe0,0x12,0x40,0x49,0x20,0x89,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA1,0xA1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x40,0x00,0x7F,0xE0,0xAA,0x80,0x2A,0x80,0xFF, + 0xE0,0x2A,0x80,0x2A,0x80,0xFF,0xE0,0x12,0x40,0x49,0x20,0x89,0x20}; const u8g_fntpgm_uint8_t fontpage_227_177_177[45] U8G_FONT_SECTION("fontpage_227_177_177") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb1,0xb1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0xf9,0x00,0x23,0xc0,0xfd,0x40,0x53, - 0x40,0xa9,0x40,0xfa,0xe0,0x22,0x20,0xfa,0x40,0x49,0x20,0x89,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB1,0xB1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0xF9,0x00,0x23,0xC0,0xFD,0x40,0x53, + 0x40,0xA9,0x40,0xFA,0xE0,0x22,0x20,0xFA,0x40,0x49,0x20,0x89,0x20}; const u8g_fntpgm_uint8_t fontpage_227_200_200[45] U8G_FONT_SECTION("fontpage_227_200_200") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x2f,0xa0,0x2b,0x40,0xac,0x80,0xb7,0xc0,0xa8, - 0x20,0x37,0xc0,0x24,0x40,0x27,0xc0,0x52,0x80,0x49,0x00,0x8f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC8,0xC8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x2F,0xA0,0x2B,0x40,0xAC,0x80,0xB7,0xC0,0xA8, + 0x20,0x37,0xC0,0x24,0x40,0x27,0xC0,0x52,0x80,0x49,0x00,0x8F,0xE0}; const u8g_fntpgm_uint8_t fontpage_228_199_199[45] U8G_FONT_SECTION("fontpage_228_199_199") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc7,0xc7,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x21,0x00,0x21,0x00,0x3f,0xe0,0x20, - 0x00,0x20,0x00,0x3f,0x80,0x20,0x80,0x20,0x80,0x40,0x80,0x80,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC7,0xC7,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x21,0x00,0x21,0x00,0x3F,0xE0,0x20, + 0x00,0x20,0x00,0x3F,0x80,0x20,0x80,0x20,0x80,0x40,0x80,0x80,0x80}; +const u8g_fntpgm_uint8_t fontpage_228_233_233[45] U8G_FONT_SECTION("fontpage_228_233_233") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE9,0xE9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0xA2,0x00,0xA7,0xE0,0xFA,0xA0,0xA2, + 0xA0,0x32,0xA0,0x64,0xA0,0xA9,0x20,0x22,0x20,0x25,0x20,0x28,0xC0}; const u8g_fntpgm_uint8_t fontpage_231_135_135[45] U8G_FONT_SECTION("fontpage_231_135_135") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x87,0x87,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0xff,0xe0,0x88,0x40,0x52,0x80,0x0c, - 0x00,0x2a,0x80,0xdf,0x40,0x04,0x00,0xff,0xe0,0x04,0x00,0x04,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x87,0x87,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0xFF,0xE0,0x88,0x40,0x52,0x80,0x0C, + 0x00,0x2A,0x80,0xDF,0x40,0x04,0x00,0xFF,0xE0,0x04,0x00,0x04,0x00}; const u8g_fntpgm_uint8_t fontpage_234_168_168[45] U8G_FONT_SECTION("fontpage_234_168_168") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa8,0xa8,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x00,0xff,0x7f,0xc0,0x44,0x40,0x44,0x40,0x7f,0xc0,0x44, - 0x40,0x44,0x40,0x7f,0xc0,0x44,0x40,0x44,0x40,0x84,0x40,0x84,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA8,0xA8,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0xC0,0x44,0x40,0x44,0x40,0x7F,0xC0,0x44, + 0x40,0x44,0x40,0x7F,0xC0,0x44,0x40,0x44,0x40,0x84,0x40,0x84,0xC0}; const u8g_fntpgm_uint8_t fontpage_234_204_204[45] U8G_FONT_SECTION("fontpage_234_204_204") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcc,0xcc,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x7f,0xc0,0x44,0x40,0x7f,0xc0,0x44,0x40,0x7f, - 0xc0,0x0a,0x00,0x31,0x80,0xd1,0x60,0x11,0x00,0x21,0x00,0x41,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0xC0,0x44,0x40,0x7F,0xC0,0x44,0x40,0x7F, + 0xC0,0x0A,0x00,0x31,0x80,0xD1,0x60,0x11,0x00,0x21,0x00,0x41,0x00}; const u8g_fntpgm_uint8_t fontpage_236_253_253[34] U8G_FONT_SECTION("fontpage_236_253_253") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfd,0xfd,0x00,0x0a,0xff,0x00, - 0x00,0x08,0x0b,0x0b,0x0c,0x02,0xff,0x10,0x20,0xff,0x81,0x81,0xff,0x81,0x81,0x81, - 0xff,0x81}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFD,0xFD,0x00,0x0A,0xFF,0x00, + 0x00,0x08,0x0B,0x0B,0x0C,0x02,0xFF,0x10,0x20,0xFF,0x81,0x81,0xFF,0x81,0x81,0x81, + 0xFF,0x81}; const u8g_fntpgm_uint8_t fontpage_237_132_132[45] U8G_FONT_SECTION("fontpage_237_132_132") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x84,0x84,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x22,0x00,0x42,0x00,0xf7,0xc0,0x98,0x40,0x90, - 0x40,0xf4,0x40,0x92,0x40,0x92,0x40,0x90,0x40,0xf0,0x40,0x91,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x84,0x84,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x22,0x00,0x42,0x00,0xF7,0xC0,0x98,0x40,0x90, + 0x40,0xF4,0x40,0x92,0x40,0x92,0x40,0x90,0x40,0xF0,0x40,0x91,0x80}; +const u8g_fntpgm_uint8_t fontpage_237_227_227[45] U8G_FONT_SECTION("fontpage_237_227_227") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE3,0xE3,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xF9,0x00,0xA1,0x00,0xF9,0xE0,0x8A,0x00,0xFA, + 0x80,0xA0,0x40,0xFC,0x00,0x00,0x00,0x7F,0xC0,0x4A,0x40,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_237_244_244[45] U8G_FONT_SECTION("fontpage_237_244_244") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf4,0xf4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0xff,0xe0,0x04,0x00,0x3f,0x80,0x20, - 0x80,0x3f,0x80,0x20,0x80,0x3f,0x80,0x20,0x80,0x20,0x80,0xff,0xe0}; -const u8g_fntpgm_uint8_t fontpage_238_129_129[45] U8G_FONT_SECTION("fontpage_238_129_129") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x81,0x81,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x14,0x80,0x25,0x60,0x46,0x20,0x1f, - 0x80,0x30,0x80,0xdf,0x80,0x10,0x80,0x1f,0x80,0x10,0x80,0x1f,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF4,0xF4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0xFF,0xE0,0x04,0x00,0x3F,0x80,0x20, + 0x80,0x3F,0x80,0x20,0x80,0x3F,0x80,0x20,0x80,0x20,0x80,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_238_160_160[45] U8G_FONT_SECTION("fontpage_238_160_160") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa0,0xa0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x07,0xe0,0xf4,0x20,0x97,0xe0,0xf4,0x80,0x94, - 0x80,0x97,0xe0,0xf4,0x80,0x94,0x80,0xf4,0xa0,0x96,0x60,0x04,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA0,0xA0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x07,0xE0,0xF4,0x20,0x97,0xE0,0xF4,0x80,0x94, + 0x80,0x97,0xE0,0xF4,0x80,0x94,0x80,0xF4,0xA0,0x96,0x60,0x04,0x20}; const u8g_fntpgm_uint8_t fontpage_240_141_141[45] U8G_FONT_SECTION("fontpage_240_141_141") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8d,0x8d,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x02,0x00,0xfa,0x00,0x23,0xe0,0x24,0x20,0x79, - 0x40,0xc9,0x00,0x49,0x00,0x49,0x00,0x7a,0x80,0x4c,0x40,0x08,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8D,0x8D,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x02,0x00,0xFA,0x00,0x23,0xE0,0x24,0x20,0x79, + 0x40,0xC9,0x00,0x49,0x00,0x49,0x00,0x7A,0x80,0x4C,0x40,0x08,0x20}; +const u8g_fntpgm_uint8_t fontpage_241_186_186[45] U8G_FONT_SECTION("fontpage_241_186_186") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBA,0xBA,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x01,0x00,0xFF,0xE0,0x2A,0x20,0x22,0x80,0x77, + 0xE0,0xD4,0x80,0x5F,0xE0,0x54,0x80,0x77,0xE0,0x54,0x80,0x07,0xE0}; const u8g_fntpgm_uint8_t fontpage_243_251_251[45] U8G_FONT_SECTION("fontpage_243_251_251") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfb,0xfb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0xe3,0xe0,0x24,0x20,0xfa,0x40,0x21, - 0x80,0x36,0x80,0x29,0xe0,0x62,0x20,0xa5,0x40,0x20,0x80,0x27,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFB,0xFB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0xE3,0xE0,0x24,0x20,0xFA,0x40,0x21, + 0x80,0x36,0x80,0x29,0xE0,0x62,0x20,0xA5,0x40,0x20,0x80,0x27,0x00}; const u8g_fntpgm_uint8_t fontpage_244_205_205[45] U8G_FONT_SECTION("fontpage_244_205_205") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcd,0xcd,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0xef,0xe0,0x21,0x00,0xff,0xc0,0x21, - 0x00,0x2f,0xe0,0x34,0x40,0x6f,0xc0,0xa4,0x40,0x27,0xc0,0x2c,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCD,0xCD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0xEF,0xE0,0x21,0x00,0xFF,0xC0,0x21, + 0x00,0x2F,0xE0,0x34,0x40,0x6F,0xC0,0xA4,0x40,0x27,0xC0,0x2C,0x60}; const u8g_fntpgm_uint8_t fontpage_245_239_239[45] U8G_FONT_SECTION("fontpage_245_239_239") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xef,0xef,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x81,0x00,0x45,0x20,0xf7,0xe0,0x00,0x00,0xaf, - 0xe0,0xa1,0x00,0xaf,0xe0,0x4a,0xa0,0x6a,0xa0,0x8a,0xa0,0x08,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xEF,0xEF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x81,0x00,0x45,0x20,0xF7,0xE0,0x00,0x00,0xAF, + 0xE0,0xA1,0x00,0xAF,0xE0,0x4A,0xA0,0x6A,0xA0,0x8A,0xA0,0x08,0x60}; const u8g_fntpgm_uint8_t fontpage_246_201_201[45] U8G_FONT_SECTION("fontpage_246_201_201") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc9,0xc9,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x42,0x00,0x7b,0xe0,0x94,0x80,0x7f,0xc0,0x04, - 0x00,0xff,0xe0,0x01,0x00,0x7f,0xc0,0x11,0x00,0x09,0x00,0x03,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC9,0xC9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x42,0x00,0x7B,0xE0,0x94,0x80,0x7F,0xC0,0x04, + 0x00,0xFF,0xE0,0x01,0x00,0x7F,0xC0,0x11,0x00,0x09,0x00,0x03,0x00}; const u8g_fntpgm_uint8_t fontpage_247_161_161[45] U8G_FONT_SECTION("fontpage_247_161_161") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa1,0xa1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x3d,0xe0,0x52,0x80,0xff,0xe0,0x80, - 0x20,0x3f,0x80,0x20,0x80,0x3f,0xc0,0x20,0x40,0x20,0x40,0x3f,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA1,0xA1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x3D,0xE0,0x52,0x80,0xFF,0xE0,0x80, + 0x20,0x3F,0x80,0x20,0x80,0x3F,0xC0,0x20,0x40,0x20,0x40,0x3F,0xC0}; +const u8g_fntpgm_uint8_t fontpage_247_177_177[45] U8G_FONT_SECTION("fontpage_247_177_177") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB1,0xB1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x3D,0xE0,0x4A,0x80,0x94,0x40,0x7F, + 0xC0,0x12,0x40,0x3B,0xC0,0x56,0x40,0x93,0xC0,0x12,0x40,0x13,0xC0}; const u8g_fntpgm_uint8_t fontpage_249_251_251[45] U8G_FONT_SECTION("fontpage_249_251_251") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfb,0xfb,0x00,0x0a,0xff,0x00, - 0x00,0x09,0x0b,0x16,0x0c,0x01,0xff,0x03,0x80,0xfc,0x00,0x11,0x00,0x7e,0x00,0x08, - 0x00,0x11,0x00,0xff,0x80,0x08,0x80,0x2a,0x00,0x49,0x00,0x98,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFB,0xFB,0x00,0x0A,0xFF,0x00, + 0x00,0x09,0x0B,0x16,0x0C,0x01,0xFF,0x03,0x80,0xFC,0x00,0x11,0x00,0x7E,0x00,0x08, + 0x00,0x11,0x00,0xFF,0x80,0x08,0x80,0x2A,0x00,0x49,0x00,0x98,0x80}; +const u8g_fntpgm_uint8_t fontpage_250_133_133[45] U8G_FONT_SECTION("fontpage_250_133_133") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x85,0x85,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x00,0x27,0xC0,0x41,0x00,0xF1,0x00,0x21, + 0x00,0x51,0x00,0xE9,0x00,0x01,0x00,0x51,0x00,0xA9,0x00,0xAF,0xE0}; +const u8g_fntpgm_uint8_t fontpage_250_162_162[45] U8G_FONT_SECTION("fontpage_250_162_162") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA2,0xA2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x7F,0xC0,0x04,0x00,0xFF,0xE0,0x91, + 0x20,0x3E,0x00,0x08,0x80,0x7F,0xC0,0x04,0x40,0x24,0x80,0xCC,0x60}; const u8g_fntpgm_uint8_t fontpage_250_171_171[45] U8G_FONT_SECTION("fontpage_250_171_171") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xab,0xab,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0x51,0x40,0x5d,0x80,0x51,0x20,0xfd, - 0xe0,0x08,0x80,0x3f,0x00,0x08,0x80,0x7f,0xc0,0x24,0x80,0xcc,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAB,0xAB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x51,0x40,0x5D,0x80,0x51,0x20,0xFD, + 0xE0,0x08,0x80,0x3F,0x00,0x08,0x80,0x7F,0xC0,0x24,0x80,0xCC,0x60}; const u8g_fntpgm_uint8_t fontpage_250_176_176[45] U8G_FONT_SECTION("fontpage_250_176_176") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb0,0xb0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x00,0x27,0xe0,0x55,0x20,0xf5,0x20,0x25, - 0x20,0x57,0xe0,0xed,0x20,0x05,0x20,0x55,0x20,0xaf,0xe0,0xac,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB0,0xB0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x00,0x27,0xE0,0x55,0x20,0xF5,0x20,0x25, + 0x20,0x57,0xE0,0xED,0x20,0x05,0x20,0x55,0x20,0xAF,0xE0,0xAC,0x20}; const u8g_fntpgm_uint8_t fontpage_250_194_194[45] U8G_FONT_SECTION("fontpage_250_194_194") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc2,0xc2,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x00,0x23,0xc0,0x54,0x40,0xf2,0x80,0x21, - 0x00,0x52,0x80,0xec,0x60,0x01,0x00,0x50,0x80,0xab,0x00,0x80,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC2,0xC2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0x23,0xC0,0x54,0x40,0xF2,0x80,0x21, + 0x00,0x52,0x80,0xEC,0x60,0x01,0x00,0x50,0x80,0xAB,0x00,0x80,0xC0}; const u8g_fntpgm_uint8_t fontpage_250_241_242[73] U8G_FONT_SECTION("fontpage_250_241_242") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf1,0xf2,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x20,0x80,0x57,0xe0,0xf1,0x00,0x22, - 0x40,0x57,0xa0,0xe8,0x00,0x02,0x80,0x52,0xa0,0xac,0xa0,0xa8,0x60,0x0b,0x0b,0x16, - 0x0c,0x00,0xff,0x21,0x00,0x21,0x00,0x52,0x40,0xf7,0x80,0x21,0x40,0x57,0xe0,0xe8, - 0x80,0x02,0xc0,0x54,0xa0,0xa8,0xa0,0xa9,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF1,0xF2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x20,0x80,0x57,0xE0,0xF1,0x00,0x22, + 0x40,0x57,0xA0,0xE8,0x00,0x02,0x80,0x52,0xA0,0xAC,0xA0,0xA8,0x60,0x0B,0x0B,0x16, + 0x0C,0x00,0xFF,0x21,0x00,0x21,0x00,0x52,0x40,0xF7,0x80,0x21,0x40,0x57,0xE0,0xE8, + 0x80,0x02,0xC0,0x54,0xA0,0xA8,0xA0,0xA9,0x80}; +const u8g_fntpgm_uint8_t fontpage_251_160_160[45] U8G_FONT_SECTION("fontpage_251_160_160") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA0,0xA0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x23,0xC0,0x22,0x40,0x57,0x80,0xF0,0x80,0x2F, + 0xE0,0x51,0x20,0xED,0x40,0x03,0x80,0x55,0x40,0xA9,0x20,0xAF,0x20}; const u8g_fntpgm_uint8_t fontpage_251_178_178[45] U8G_FONT_SECTION("fontpage_251_178_178") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb2,0xb2,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x27,0xe0,0x24,0x20,0x55,0x60,0xf4,0xa0,0x27, - 0xe0,0x54,0xa0,0xef,0xe0,0x05,0x20,0x55,0xe0,0xac,0x20,0xac,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB2,0xB2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x27,0xE0,0x24,0x20,0x55,0x60,0xF4,0xA0,0x27, + 0xE0,0x54,0xA0,0xEF,0xE0,0x05,0x20,0x55,0xE0,0xAC,0x20,0xAC,0x60}; const u8g_fntpgm_uint8_t fontpage_251_210_210[45] U8G_FONT_SECTION("fontpage_251_210_210") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd2,0xd2,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x20,0x27,0xa0,0x51,0x40,0xff,0xe0,0x21, - 0x00,0x53,0xe0,0xee,0x20,0x03,0xe0,0x52,0x20,0xab,0xe0,0xaa,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD2,0xD2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x20,0x27,0xA0,0x51,0x40,0xFF,0xE0,0x21, + 0x00,0x53,0xE0,0xEE,0x20,0x03,0xE0,0x52,0x20,0xAB,0xE0,0xAA,0x20}; const u8g_fntpgm_uint8_t fontpage_251_218_218[45] U8G_FONT_SECTION("fontpage_251_218_218") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xda,0xda,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x27,0xc0,0x54,0x40,0xf7,0xc0,0x24, - 0x40,0x57,0xc0,0xe9,0x20,0x07,0x40,0x53,0x80,0xad,0x40,0xab,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDA,0xDA,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x27,0xC0,0x54,0x40,0xF7,0xC0,0x24, + 0x40,0x57,0xC0,0xE9,0x20,0x07,0x40,0x53,0x80,0xAD,0x40,0xAB,0x20}; const u8g_fntpgm_uint8_t fontpage_251_232_232[45] U8G_FONT_SECTION("fontpage_251_232_232") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe8,0xe8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x2f,0xe0,0x58,0x20,0xff,0xe0,0x28, - 0x00,0x5f,0xe0,0xea,0xa0,0x0f,0xe0,0x5a,0xa0,0xaa,0xa0,0xaa,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE8,0xE8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x2F,0xE0,0x58,0x20,0xFF,0xE0,0x28, + 0x00,0x5F,0xE0,0xEA,0xA0,0x0F,0xE0,0x5A,0xA0,0xAA,0xA0,0xAA,0x60}; const u8g_fntpgm_uint8_t fontpage_252_174_174[45] U8G_FONT_SECTION("fontpage_252_174_174") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xae,0xae,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x27,0xe0,0x44,0x20,0xfb,0xe0,0x24, - 0x80,0x5d,0xe0,0xf5,0x20,0x05,0xe0,0x55,0x20,0xad,0xe0,0xa5,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAE,0xAE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x27,0xE0,0x44,0x20,0xFB,0xE0,0x24, + 0x80,0x5D,0xE0,0xF5,0x20,0x05,0xE0,0x55,0x20,0xAD,0xE0,0xA5,0x20}; const u8g_fntpgm_uint8_t fontpage_252_189_189[45] U8G_FONT_SECTION("fontpage_252_189_189") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbd,0xbd,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0x27,0xe0,0x55,0x60,0xf6,0xa0,0x25, - 0x20,0x56,0xa0,0xef,0xe0,0x01,0x40,0x56,0xa0,0xaa,0x60,0xa9,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBD,0xBD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x27,0xE0,0x55,0x60,0xF6,0xA0,0x25, + 0x20,0x56,0xA0,0xEF,0xE0,0x01,0x40,0x56,0xA0,0xAA,0x60,0xA9,0xC0}; const u8g_fntpgm_uint8_t fontpage_252_252_252[45] U8G_FONT_SECTION("fontpage_252_252_252") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfc,0xfc,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x4a,0x40,0x4d,0xa0,0x8a,0x40,0xfd,0xa0,0x28, - 0x00,0x4f,0xe0,0xfa,0x40,0x0d,0xa0,0x5a,0x40,0xad,0xa0,0xaf,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFC,0xFC,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x4A,0x40,0x4D,0xA0,0x8A,0x40,0xFD,0xA0,0x28, + 0x00,0x4F,0xE0,0xFA,0x40,0x0D,0xA0,0x5A,0x40,0xAD,0xA0,0xAF,0xE0}; const u8g_fntpgm_uint8_t fontpage_253_140_140[45] U8G_FONT_SECTION("fontpage_253_140_140") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8c,0x8c,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x41,0x00,0x4f,0xe0,0x91,0x00,0xef,0xe0,0x2a, - 0xa0,0x5f,0xe0,0xf4,0x40,0x07,0xc0,0x54,0x40,0xaf,0xc0,0xac,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8C,0x8C,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x41,0x00,0x4F,0xE0,0x91,0x00,0xEF,0xE0,0x2A, + 0xA0,0x5F,0xE0,0xF4,0x40,0x07,0xC0,0x54,0x40,0xAF,0xC0,0xAC,0x60}; const u8g_fntpgm_uint8_t fontpage_253_162_162[45] U8G_FONT_SECTION("fontpage_253_162_162") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa2,0xa2,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x00,0x27,0xc0,0x41,0x00,0x51,0x00,0xe1, - 0x00,0x21,0x00,0x41,0x00,0xf1,0x00,0x01,0x00,0x31,0x00,0xcf,0xe0}; -const u8g_fntpgm_uint8_t fontpage_253_255_255[45] U8G_FONT_SECTION("fontpage_253_255_255") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x27,0xc0,0x20,0x40,0x43,0xc0,0xf0,0x40,0x2f, - 0xe0,0x41,0x20,0xf5,0x40,0x03,0x80,0x35,0x40,0xc9,0x20,0x03,0x00}; -const u8g_fntpgm_uint8_t fontpage_254_186_186[45] U8G_FONT_SECTION("fontpage_254_186_186") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xba,0xba,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x41,0x00,0x41,0x00,0x7b,0xc0,0xa1,0x40,0x21, - 0x40,0xff,0xe0,0x21,0x00,0xa9,0x00,0xaa,0x80,0xfa,0x40,0x04,0x20}; -const u8g_fntpgm_uint8_t fontpage_254_209_209[45] U8G_FONT_SECTION("fontpage_254_209_209") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd1,0xd1,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0xff,0xc0,0x80,0x40,0x91,0x40,0xd5,0x40,0xa2, - 0x40,0x92,0x40,0xad,0x40,0xc5,0x40,0x88,0x40,0x80,0x40,0x81,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA2,0xA2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x00,0x27,0xC0,0x41,0x00,0x51,0x00,0xE1, + 0x00,0x21,0x00,0x41,0x00,0xF1,0x00,0x01,0x00,0x31,0x00,0xCF,0xE0}; const u8g_fntpgm_uint8_t fontpage_254_238_238[45] U8G_FONT_SECTION("fontpage_254_238_238") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xee,0xee,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x7f,0xc0,0x4a,0x40,0x7f,0xc0,0x04,0x00,0xff, - 0xe0,0x20,0x80,0x3f,0x80,0x20,0x80,0x3f,0x80,0x20,0x80,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xEE,0xEE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0xC0,0x4A,0x40,0x7F,0xC0,0x04,0x00,0xFF, + 0xE0,0x20,0x80,0x3F,0x80,0x20,0x80,0x3F,0x80,0x20,0x80,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_254_242_242[45] U8G_FONT_SECTION("fontpage_254_242_242") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf2,0xf2,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x7f,0xe0,0x49,0x20,0x7f,0xe0,0x04,0x40,0x3f, - 0x80,0x05,0x00,0xff,0xe0,0x30,0x80,0xdf,0x80,0x10,0x80,0x1f,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF2,0xF2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0xE0,0x49,0x20,0x7F,0xE0,0x04,0x40,0x3F, + 0x80,0x05,0x00,0xFF,0xE0,0x30,0x80,0xDF,0x80,0x10,0x80,0x1F,0x80}; const u8g_fntpgm_uint8_t fontpage_256_240_240[45] U8G_FONT_SECTION("fontpage_256_240_240") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf0,0xf0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xf9,0x00,0x57,0xe0,0x56,0xa0,0x75,0x20,0x56, - 0xa0,0x77,0xe0,0x51,0x00,0x52,0xc0,0xfe,0x20,0x12,0x60,0x11,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xF9,0x00,0x57,0xE0,0x56,0xA0,0x75,0x20,0x56, + 0xA0,0x77,0xE0,0x51,0x00,0x52,0xC0,0xFE,0x20,0x12,0x60,0x11,0xC0}; const u8g_fntpgm_uint8_t fontpage_259_234_234[34] U8G_FONT_SECTION("fontpage_259_234_234") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xea,0xea,0x00,0x0a,0xff,0x00, - 0x00,0x07,0x0b,0x0b,0x0c,0x02,0xff,0x20,0xfe,0x82,0x82,0xfe,0x82,0xfe,0x82,0x82, - 0xfe,0x82}; -const u8g_fntpgm_uint8_t fontpage_265_221_221[45] U8G_FONT_SECTION("fontpage_265_221_221") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xdd,0xdd,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0xff,0xe0,0x11,0x00,0x52,0x00,0x53, - 0xc0,0x55,0x00,0x10,0x80,0x7f,0xc0,0x4a,0x40,0x4a,0x40,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xEA,0xEA,0x00,0x0A,0xFF,0x00, + 0x00,0x07,0x0B,0x0B,0x0C,0x02,0xFF,0x20,0xFE,0x82,0x82,0xFE,0x82,0xFE,0x82,0x82, + 0xFE,0x82}; +const u8g_fntpgm_uint8_t fontpage_267_205_205[45] U8G_FONT_SECTION("fontpage_267_205_205") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCD,0xCD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0xFF,0xE0,0x91,0x00,0xF9,0xE0,0x8A, + 0x80,0xFC,0x40,0x90,0x00,0xFF,0xC0,0x4A,0x40,0x4A,0x40,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_272_204_204[45] U8G_FONT_SECTION("fontpage_272_204_204") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcc,0xcc,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x27,0xc0,0x40,0x00,0x80,0x00,0x10,0x00,0x2f, - 0xe0,0x60,0x80,0xa0,0x80,0x20,0x80,0x20,0x80,0x20,0x80,0x23,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x27,0xC0,0x40,0x00,0x80,0x00,0x10,0x00,0x2F, + 0xE0,0x60,0x80,0xA0,0x80,0x20,0x80,0x20,0x80,0x20,0x80,0x23,0x80}; const u8g_fntpgm_uint8_t fontpage_272_232_232[45] U8G_FONT_SECTION("fontpage_272_232_232") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe8,0xe8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x7f,0xc0,0x04,0x00,0x3f,0x80,0x04, - 0x00,0xff,0xe0,0x0a,0x40,0x12,0x80,0x31,0x00,0xd4,0x80,0x18,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE8,0xE8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x7F,0xC0,0x04,0x00,0x3F,0x80,0x04, + 0x00,0xFF,0xE0,0x0A,0x40,0x12,0x80,0x31,0x00,0xD4,0x80,0x18,0x60}; const u8g_fntpgm_uint8_t fontpage_273_171_171[45] U8G_FONT_SECTION("fontpage_273_171_171") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xab,0xab,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x40,0x80,0x20,0x80,0xff,0xe0,0x14,0xa0,0x2c, - 0x80,0x77,0xe0,0xad,0x40,0x25,0x40,0x24,0x80,0x29,0x40,0x36,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAB,0xAB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x40,0x80,0x20,0x80,0xFF,0xE0,0x14,0xA0,0x2C, + 0x80,0x77,0xE0,0xAD,0x40,0x25,0x40,0x24,0x80,0x29,0x40,0x36,0x20}; const u8g_fntpgm_uint8_t fontpage_273_197_197[45] U8G_FONT_SECTION("fontpage_273_197_197") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc5,0xc5,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0x9f,0xe0,0x51,0x00,0x31,0x00,0xd7, - 0xc0,0x12,0x00,0xff,0xe0,0x0c,0x40,0x32,0x80,0xd1,0x00,0x18,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC5,0xC5,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0x9F,0xE0,0x51,0x00,0x31,0x00,0xD7, + 0xC0,0x12,0x00,0xFF,0xE0,0x0C,0x40,0x32,0x80,0xD1,0x00,0x18,0xE0}; const u8g_fntpgm_uint8_t fontpage_273_221_221[45] U8G_FONT_SECTION("fontpage_273_221_221") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xdd,0xdd,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x51,0x00,0x7f,0xe0,0x11,0x00,0xf1,0x00,0x57, - 0xc0,0x84,0x00,0xff,0xe0,0x14,0x80,0x33,0x00,0xd5,0x80,0x18,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDD,0xDD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x51,0x00,0x7F,0xE0,0x11,0x00,0xF1,0x00,0x57, + 0xC0,0x84,0x00,0xFF,0xE0,0x14,0x80,0x33,0x00,0xD5,0x80,0x18,0x60}; const u8g_fntpgm_uint8_t fontpage_274_135_135[45] U8G_FONT_SECTION("fontpage_274_135_135") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x87,0x87,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x44,0x00,0x27,0xe0,0xf8,0x00,0x17,0xc0,0x2c, - 0x40,0x77,0xc0,0xac,0x40,0x27,0xc0,0x2c,0x40,0x33,0x80,0x2c,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x87,0x87,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x44,0x00,0x27,0xE0,0xF8,0x00,0x17,0xC0,0x2C, + 0x40,0x77,0xC0,0xAC,0x40,0x27,0xC0,0x2C,0x40,0x33,0x80,0x2C,0x60}; const u8g_fntpgm_uint8_t fontpage_275_210_210[45] U8G_FONT_SECTION("fontpage_275_210_210") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd2,0xd2,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x00,0xff,0x10,0x00,0x1f,0x00,0x22,0x00,0x7f,0xc0,0xa4, - 0x40,0x3f,0xc0,0x24,0x40,0x3f,0xc0,0x24,0x40,0x45,0x40,0x80,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD2,0xD2,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x00,0xFF,0x10,0x00,0x1F,0x00,0x22,0x00,0x7F,0xC0,0xA4, + 0x40,0x3F,0xC0,0x24,0x40,0x3F,0xC0,0x24,0x40,0x45,0x40,0x80,0x80}; const u8g_fntpgm_uint8_t fontpage_276_136_136[45] U8G_FONT_SECTION("fontpage_276_136_136") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x80,0x10,0x80,0xfc,0x80,0x00,0x80,0x7f, - 0xe0,0x00,0x80,0x78,0x80,0x00,0x80,0x78,0x80,0x48,0x80,0x78,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x80,0x10,0x80,0xFC,0x80,0x00,0x80,0x7F, + 0xE0,0x00,0x80,0x78,0x80,0x00,0x80,0x78,0x80,0x48,0x80,0x78,0x80}; const u8g_fntpgm_uint8_t fontpage_276_138_138[45] U8G_FONT_SECTION("fontpage_276_138_138") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8a,0x8a,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x4f,0xc0,0xf2,0x40,0x02,0x40,0xf2,0x40,0x02, - 0x40,0xff,0xc0,0x02,0x40,0xf2,0x40,0x92,0x60,0xf2,0x60,0x92,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8A,0x8A,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x4F,0xC0,0xF2,0x40,0x02,0x40,0xF2,0x40,0x02, + 0x40,0xFF,0xC0,0x02,0x40,0xF2,0x40,0x92,0x60,0xF2,0x60,0x92,0x20}; const u8g_fntpgm_uint8_t fontpage_276_152_152[45] U8G_FONT_SECTION("fontpage_276_152_152") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x98,0x98,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x40,0x00,0xf7,0xc0,0x00,0x40,0xf0,0x40,0x07, - 0xc0,0xf4,0x40,0x04,0x00,0xf4,0x00,0x94,0x20,0xf4,0x20,0x93,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x98,0x98,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x40,0x00,0xF7,0xC0,0x00,0x40,0xF0,0x40,0x07, + 0xC0,0xF4,0x40,0x04,0x00,0xF4,0x00,0x94,0x20,0xF4,0x20,0x93,0xE0}; const u8g_fntpgm_uint8_t fontpage_276_173_173[45] U8G_FONT_SECTION("fontpage_276_173_173") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xad,0xad,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x47,0x80,0xf4,0x80,0x04,0x80,0xf4,0xe0,0x08, - 0x00,0xf7,0xc0,0x04,0x40,0xf2,0x80,0x91,0x00,0xf2,0x80,0x9c,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAD,0xAD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x47,0x80,0xF4,0x80,0x04,0x80,0xF4,0xE0,0x08, + 0x00,0xF7,0xC0,0x04,0x40,0xF2,0x80,0x91,0x00,0xF2,0x80,0x9C,0x60}; const u8g_fntpgm_uint8_t fontpage_276_230_230[45] U8G_FONT_SECTION("fontpage_276_230_230") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe6,0xe6,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x40,0xc0,0xf0,0xa0,0x0f,0xe0,0xf0,0x80,0x07, - 0x80,0xf2,0x80,0x02,0x80,0xf2,0x80,0x93,0xa0,0xfc,0x60,0x90,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE6,0xE6,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x40,0xC0,0xF0,0xA0,0x0F,0xE0,0xF0,0x80,0x07, + 0x80,0xF2,0x80,0x02,0x80,0xF2,0x80,0x93,0xA0,0xFC,0x60,0x90,0x20}; +const u8g_fntpgm_uint8_t fontpage_277_141_141[45] U8G_FONT_SECTION("fontpage_277_141_141") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8D,0x8D,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x47,0xE0,0xF9,0x20,0x05,0x20,0xF5,0x20,0x02, + 0xE0,0xF4,0x40,0x03,0x00,0xF2,0xA0,0x96,0x20,0xFA,0x40,0x91,0xC0}; const u8g_fntpgm_uint8_t fontpage_277_164_164[45] U8G_FONT_SECTION("fontpage_277_164_164") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa4,0xa4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x47,0xc0,0xf4,0x40,0x04,0x40,0xf7,0xc0,0x00, - 0x00,0xf7,0xc0,0x01,0x00,0xff,0xe0,0x92,0x80,0xf4,0x40,0x98,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA4,0xA4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x47,0xC0,0xF4,0x40,0x04,0x40,0xF7,0xC0,0x00, + 0x00,0xF7,0xC0,0x01,0x00,0xFF,0xE0,0x92,0x80,0xF4,0x40,0x98,0x20}; const u8g_fntpgm_uint8_t fontpage_277_191_191[45] U8G_FONT_SECTION("fontpage_277_191_191") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xbf,0xbf,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x47,0xe0,0xf4,0x20,0x05,0x20,0xf7,0xa0,0x05, - 0x20,0xf7,0xe0,0x04,0x20,0xf7,0xa0,0x96,0xa0,0xf7,0xa0,0x98,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xBF,0xBF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x47,0xE0,0xF4,0x20,0x05,0x20,0xF7,0xA0,0x05, + 0x20,0xF7,0xE0,0x04,0x20,0xF7,0xA0,0x96,0xA0,0xF7,0xA0,0x98,0x60}; const u8g_fntpgm_uint8_t fontpage_277_203_203[45] U8G_FONT_SECTION("fontpage_277_203_203") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcb,0xcb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x41,0x00,0xff,0xe0,0x01,0x00,0xf7,0xc0,0x01, - 0x00,0xff,0xe0,0x04,0x40,0xf7,0xc0,0x94,0x40,0xf7,0xc0,0x94,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCB,0xCB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x41,0x00,0xFF,0xE0,0x01,0x00,0xF7,0xC0,0x01, + 0x00,0xFF,0xE0,0x04,0x40,0xF7,0xC0,0x94,0x40,0xF7,0xC0,0x94,0x40}; const u8g_fntpgm_uint8_t fontpage_278_240_240[45] U8G_FONT_SECTION("fontpage_278_240_240") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf0,0xf0,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x42,0x40,0xff,0xe0,0x01,0x00,0xf7,0xc0,0x01, - 0x00,0xff,0xe0,0x04,0xa0,0xff,0xe0,0x94,0xa0,0xfe,0x40,0x95,0xa0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x42,0x40,0xFF,0xE0,0x01,0x00,0xF7,0xC0,0x01, + 0x00,0xFF,0xE0,0x04,0xA0,0xFF,0xE0,0x94,0xA0,0xFE,0x40,0x95,0xA0}; +const u8g_fntpgm_uint8_t fontpage_279_128_128[45] U8G_FONT_SECTION("fontpage_279_128_128") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x41,0x00,0xFF,0xE0,0x01,0x00,0xFF,0xE0,0x0A, + 0xA0,0xFF,0xE0,0x04,0x40,0xF7,0xC0,0x94,0x40,0xF7,0xC0,0x9C,0x60}; const u8g_fntpgm_uint8_t fontpage_279_138_138[45] U8G_FONT_SECTION("fontpage_279_138_138") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8a,0x8a,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x44,0x40,0xae,0xa0,0x40,0x40,0xae,0xa0,0xea, - 0xe0,0x5e,0x40,0xa0,0xa0,0x1f,0xc0,0x69,0x00,0x06,0x00,0x79,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8A,0x8A,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x44,0x40,0xAE,0xA0,0x40,0x40,0xAE,0xA0,0xEA, + 0xE0,0x5E,0x40,0xA0,0xA0,0x1F,0xC0,0x69,0x00,0x06,0x00,0x79,0xE0}; const u8g_fntpgm_uint8_t fontpage_281_199_199[45] U8G_FONT_SECTION("fontpage_281_199_199") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc7,0xc7,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x88,0x00,0x5f,0xc0,0x22,0x40,0xff,0x00,0x61, - 0xc0,0x3f,0x00,0x21,0x00,0x3f,0x00,0x21,0x00,0x3f,0x00,0xe1,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC7,0xC7,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x88,0x00,0x5F,0xC0,0x22,0x40,0xFF,0x00,0x61, + 0xC0,0x3F,0x00,0x21,0x00,0x3F,0x00,0x21,0x00,0x3F,0x00,0xE1,0xC0}; +const u8g_fntpgm_uint8_t fontpage_283_221_221[45] U8G_FONT_SECTION("fontpage_283_221_221") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDD,0xDD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7B,0xE0,0x4A,0x00,0x4A,0x00,0x7B,0xE0,0x12, + 0x20,0x52,0x20,0x5A,0x20,0x53,0xE0,0x52,0x00,0x5E,0x00,0xE3,0xE0}; +const u8g_fntpgm_uint8_t fontpage_285_202_202[45] U8G_FONT_SECTION("fontpage_285_202_202") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCA,0xCA,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x7F,0xC0,0x04,0x00,0x3F,0x80,0x24, + 0x80,0x3F,0x80,0x24,0x80,0x3F,0x80,0x04,0x00,0xFF,0xE0,0x04,0x00}; +const u8g_fntpgm_uint8_t fontpage_285_223_223[45] U8G_FONT_SECTION("fontpage_285_223_223") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDF,0xDF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0xFA,0x00,0x23,0xE0,0xFD,0x20,0xA9, + 0x40,0xF9,0x00,0xA9,0x00,0xF9,0x80,0x22,0x80,0xFA,0x40,0x24,0x20}; const u8g_fntpgm_uint8_t fontpage_285_248_248[45] U8G_FONT_SECTION("fontpage_285_248_248") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf8,0xf8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x80,0xf8,0x80,0x23,0xe0,0xfa,0xa0,0xaa, - 0xa0,0xfa,0xa0,0xab,0xe0,0xfa,0xa0,0x22,0xa0,0xfb,0xe0,0x22,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x80,0xF8,0x80,0x23,0xE0,0xFA,0xA0,0xAA, + 0xA0,0xFA,0xA0,0xAB,0xE0,0xFA,0xA0,0x22,0xA0,0xFB,0xE0,0x22,0x20}; const u8g_fntpgm_uint8_t fontpage_286_137_137[45] U8G_FONT_SECTION("fontpage_286_137_137") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x80,0x7d,0x40,0x11,0x00,0xff,0xe0,0x11, - 0x00,0xff,0x20,0x55,0x40,0x7c,0x80,0x54,0xa0,0xff,0x60,0x12,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x80,0x7D,0x40,0x11,0x00,0xFF,0xE0,0x11, + 0x00,0xFF,0x20,0x55,0x40,0x7C,0x80,0x54,0xA0,0xFF,0x60,0x12,0x20}; const u8g_fntpgm_uint8_t fontpage_286_175_175[45] U8G_FONT_SECTION("fontpage_286_175_175") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xaf,0xaf,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x23,0xc0,0xfa,0x40,0x23,0xc0,0xf8,0x00,0xaf, - 0xe0,0xfa,0x40,0xab,0xc0,0xfa,0x40,0x22,0xe0,0xff,0x40,0x20,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAF,0xAF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x23,0xC0,0xFA,0x40,0x23,0xC0,0xF8,0x00,0xAF, + 0xE0,0xFA,0x40,0xAB,0xC0,0xFA,0x40,0x22,0xE0,0xFF,0x40,0x20,0x40}; const u8g_fntpgm_uint8_t fontpage_286_184_184[45] U8G_FONT_SECTION("fontpage_286_184_184") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb8,0xb8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x21,0x00,0xfa,0x80,0x24,0x60,0xfb,0x80,0xae, - 0x20,0xfa,0xa0,0xae,0xa0,0xfa,0xa0,0x2e,0xa0,0xfa,0x20,0x2a,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB8,0xB8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0xFA,0x80,0x24,0x60,0xFB,0x80,0xAE, + 0x20,0xFA,0xA0,0xAE,0xA0,0xFA,0xA0,0x2E,0xA0,0xFA,0x20,0x2A,0x60}; +const u8g_fntpgm_uint8_t fontpage_286_201_201[45] U8G_FONT_SECTION("fontpage_286_201_201") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC9,0xC9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0xFF,0xE0,0x25,0x40,0xFF,0xC0,0xAD, + 0x40,0xFF,0xC0,0xA9,0x60,0xFF,0xE0,0x24,0x40,0xFA,0x40,0x20,0xC0}; const u8g_fntpgm_uint8_t fontpage_287_209_209[45] U8G_FONT_SECTION("fontpage_287_209_209") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd1,0xd1,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x40,0xc0,0x27,0x00,0x24,0x00,0x07,0xe0,0xe4, - 0x80,0x24,0x80,0x24,0x80,0x24,0x80,0x28,0x80,0x50,0x00,0x8f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD1,0xD1,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x40,0xC0,0x27,0x00,0x24,0x00,0x07,0xE0,0xE4, + 0x80,0x24,0x80,0x24,0x80,0x24,0x80,0x28,0x80,0x50,0x00,0x8F,0xE0}; const u8g_fntpgm_uint8_t fontpage_287_212_212[45] U8G_FONT_SECTION("fontpage_287_212_212") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd4,0xd4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x40,0x60,0x27,0x80,0x24,0x00,0x07,0xe0,0xe6, - 0x20,0x25,0x40,0x24,0x80,0x29,0x40,0x26,0x20,0x50,0x00,0x8f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD4,0xD4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x40,0x60,0x27,0x80,0x24,0x00,0x07,0xE0,0xE6, + 0x20,0x25,0x40,0x24,0x80,0x29,0x40,0x26,0x20,0x50,0x00,0x8F,0xE0}; const u8g_fntpgm_uint8_t fontpage_288_128_128[45] U8G_FONT_SECTION("fontpage_288_128_128") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x8f,0xc0,0x48,0x40,0x4f,0xc0,0x08,0x40,0xcf, - 0xc0,0x48,0x00,0x4b,0x40,0x48,0x80,0x4e,0x40,0xb0,0x00,0x8f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x8F,0xC0,0x48,0x40,0x4F,0xC0,0x08,0x40,0xCF, + 0xC0,0x48,0x00,0x4B,0x40,0x48,0x80,0x4E,0x40,0xB0,0x00,0x8F,0xE0}; const u8g_fntpgm_uint8_t fontpage_288_159_159[45] U8G_FONT_SECTION("fontpage_288_159_159") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9f,0x9f,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x41,0x00,0x3f,0xe0,0x21,0x00,0x0f,0xe0,0xe9, - 0x20,0x2f,0xe0,0x23,0x80,0x25,0x40,0x29,0x20,0x51,0x00,0x8f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9F,0x9F,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x41,0x00,0x3F,0xE0,0x21,0x00,0x0F,0xE0,0xE9, + 0x20,0x2F,0xE0,0x23,0x80,0x25,0x40,0x29,0x20,0x51,0x00,0x8F,0xE0}; +const u8g_fntpgm_uint8_t fontpage_288_163_163[45] U8G_FONT_SECTION("fontpage_288_163_163") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA3,0xA3,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x41,0x00,0x2F,0xE0,0x25,0x40,0x07,0xC0,0xE5, + 0x40,0x27,0xC0,0x21,0x00,0x2F,0xE0,0x21,0x00,0x50,0x00,0x8F,0xE0}; const u8g_fntpgm_uint8_t fontpage_288_178_178[45] U8G_FONT_SECTION("fontpage_288_178_178") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xb2,0xb2,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x43,0x00,0x24,0x80,0x27,0xe0,0x0c,0x80,0xf7, - 0xe0,0x24,0x80,0x27,0xe0,0x24,0x80,0x27,0xe0,0x54,0x00,0x8f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xB2,0xB2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x43,0x00,0x24,0x80,0x27,0xE0,0x0C,0x80,0xF7, + 0xE0,0x24,0x80,0x27,0xE0,0x24,0x80,0x27,0xE0,0x54,0x00,0x8F,0xE0}; const u8g_fntpgm_uint8_t fontpage_288_203_203[45] U8G_FONT_SECTION("fontpage_288_203_203") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcb,0xcb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x4f,0xe0,0x29,0x20,0x2f,0xe0,0x05,0x40,0xe7, - 0xc0,0x25,0x40,0x27,0xc0,0x21,0x00,0x2f,0xe0,0x51,0x00,0x8f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCB,0xCB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x4F,0xE0,0x29,0x20,0x2F,0xE0,0x05,0x40,0xE7, + 0xC0,0x25,0x40,0x27,0xC0,0x21,0x00,0x2F,0xE0,0x51,0x00,0x8F,0xE0}; const u8g_fntpgm_uint8_t fontpage_288_212_212[45] U8G_FONT_SECTION("fontpage_288_212_212") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd4,0xd4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x41,0x00,0x27,0xc0,0x21,0x00,0x0f,0xe0,0xe2, - 0x80,0x2f,0xe0,0x21,0x00,0x2f,0xe0,0x21,0x00,0x51,0x00,0x8f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD4,0xD4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x41,0x00,0x27,0xC0,0x21,0x00,0x0F,0xE0,0xE2, + 0x80,0x2F,0xE0,0x21,0x00,0x2F,0xE0,0x21,0x00,0x51,0x00,0x8F,0xE0}; const u8g_fntpgm_uint8_t fontpage_288_248_248[45] U8G_FONT_SECTION("fontpage_288_248_248") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf8,0xf8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x4e,0xe0,0x2a,0xa0,0x2e,0xe0,0x08,0x80,0xea, - 0xa0,0x2f,0xe0,0x22,0x80,0x2f,0xe0,0x22,0x40,0x54,0x20,0x8f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x4E,0xE0,0x2A,0xA0,0x2E,0xE0,0x08,0x80,0xEA, + 0xA0,0x2F,0xE0,0x22,0x80,0x2F,0xE0,0x22,0x40,0x54,0x20,0x8F,0xE0}; const u8g_fntpgm_uint8_t fontpage_289_132_132[45] U8G_FONT_SECTION("fontpage_289_132_132") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x84,0x84,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x9f,0xc0,0x55,0x40,0x5f,0xc0,0x00,0x00,0xff, - 0xe0,0x28,0x80,0x2f,0xa0,0x27,0x40,0x2a,0x80,0x52,0x40,0x8f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x84,0x84,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x9F,0xC0,0x55,0x40,0x5F,0xC0,0x00,0x00,0xFF, + 0xE0,0x28,0x80,0x2F,0xA0,0x27,0x40,0x2A,0x80,0x52,0x40,0x8F,0xE0}; const u8g_fntpgm_uint8_t fontpage_289_138_138[45] U8G_FONT_SECTION("fontpage_289_138_138") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8a,0x8a,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x42,0x00,0x2f,0xc0,0x28,0x40,0x1f,0xe0,0xf4, - 0xa0,0x29,0x40,0x3f,0xe0,0x22,0x00,0x27,0xc0,0x58,0xc0,0x8f,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8A,0x8A,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x42,0x00,0x2F,0xC0,0x28,0x40,0x1F,0xE0,0xF4, + 0xA0,0x29,0x40,0x3F,0xE0,0x22,0x00,0x27,0xC0,0x58,0xC0,0x8F,0xE0}; const u8g_fntpgm_uint8_t fontpage_289_232_232[45] U8G_FONT_SECTION("fontpage_289_232_232") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe8,0xe8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0xe0,0xff,0x20,0x45,0x20,0x29,0x40,0xff, - 0x80,0x01,0x40,0x7d,0x20,0x45,0x20,0x45,0xa0,0x7d,0x40,0x45,0x00}; -const u8g_fntpgm_uint8_t fontpage_291_202_202[45] U8G_FONT_SECTION("fontpage_291_202_202") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xca,0xca,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x1f,0xc0,0xe2,0x80,0xa9,0x00,0x72,0x80,0xfd, - 0x60,0x31,0x00,0x6f,0xc0,0xa1,0x00,0xaf,0xe0,0x21,0x00,0x21,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE8,0xE8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0xE0,0xFF,0x20,0x45,0x20,0x29,0x40,0xFF, + 0x80,0x01,0x40,0x7D,0x20,0x45,0x20,0x45,0xA0,0x7D,0x40,0x45,0x00}; +const u8g_fntpgm_uint8_t fontpage_291_203_203[45] U8G_FONT_SECTION("fontpage_291_203_203") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCB,0xCB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xFF,0xE0,0x2A,0xA0,0xAF,0xE0,0x71,0x00,0xFF, + 0xE0,0x22,0x80,0x77,0xE0,0x69,0x00,0xA7,0xE0,0xA1,0x00,0x21,0x00}; const u8g_fntpgm_uint8_t fontpage_291_205_205[45] U8G_FONT_SECTION("fontpage_291_205_205") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcd,0xcd,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x7f,0xc0,0x04,0x00,0xff,0xe0,0x24,0x80,0x3f, - 0x80,0x24,0x80,0x3f,0x80,0x04,0x00,0x7f,0xc0,0x04,0x00,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCD,0xCD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0xC0,0x04,0x00,0xFF,0xE0,0x24,0x80,0x3F, + 0x80,0x24,0x80,0x3F,0x80,0x04,0x00,0x7F,0xC0,0x04,0x00,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_291_207_207[45] U8G_FONT_SECTION("fontpage_291_207_207") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcf,0xcf,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x3f,0x80,0x20,0x80,0x3f,0x80,0x20,0x80,0xff, - 0xe0,0x24,0x80,0x3f,0x80,0x24,0x80,0x7f,0xc0,0x04,0x00,0xff,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCF,0xCF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x3F,0x80,0x20,0x80,0x3F,0x80,0x20,0x80,0xFF, + 0xE0,0x24,0x80,0x3F,0x80,0x24,0x80,0x7F,0xC0,0x04,0x00,0xFF,0xE0}; const u8g_fntpgm_uint8_t fontpage_291_221_221[45] U8G_FONT_SECTION("fontpage_291_221_221") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xdd,0xdd,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x20,0x80,0x50,0x80,0x88,0x80,0x78,0x80,0x27, - 0xe0,0xf8,0x80,0x20,0x80,0xa8,0x80,0x70,0x80,0x38,0x80,0xc0,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDD,0xDD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x20,0x80,0x50,0x80,0x88,0x80,0x78,0x80,0x27, + 0xE0,0xF8,0x80,0x20,0x80,0xA8,0x80,0x70,0x80,0x38,0x80,0xC0,0x80}; const u8g_fntpgm_uint8_t fontpage_292_149_149[45] U8G_FONT_SECTION("fontpage_292_149_149") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x95,0x95,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x27,0xc0,0x31,0x40,0x49,0x40,0xf9,0x40,0x21, - 0x40,0xff,0xc0,0x22,0x40,0xaa,0x40,0x72,0x40,0x3a,0x40,0xc7,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x95,0x95,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x27,0xC0,0x31,0x40,0x49,0x40,0xF9,0x40,0x21, + 0x40,0xFF,0xC0,0x22,0x40,0xAA,0x40,0x72,0x40,0x3A,0x40,0xC7,0xE0}; const u8g_fntpgm_uint8_t fontpage_294_175_175[45] U8G_FONT_SECTION("fontpage_294_175_175") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xaf,0xaf,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x40,0x57,0xe0,0x8a,0x40,0x7a,0x40,0x27, - 0xe0,0xf8,0x00,0x23,0xe0,0xaa,0x20,0x73,0xe0,0x3a,0x20,0xe3,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAF,0xAF,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x40,0x57,0xE0,0x8A,0x40,0x7A,0x40,0x27, + 0xE0,0xF8,0x00,0x23,0xE0,0xAA,0x20,0x73,0xE0,0x3A,0x20,0xE3,0xE0}; const u8g_fntpgm_uint8_t fontpage_294_245_245[45] U8G_FONT_SECTION("fontpage_294_245_245") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf5,0xf5,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x2c,0x80,0x25,0xe0,0x54,0xa0,0xfb,0xe0,0x2c, - 0xa0,0xf7,0xe0,0x24,0x80,0xb7,0xe0,0x6c,0x80,0x34,0x80,0xcb,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF5,0xF5,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x2C,0x80,0x25,0xE0,0x54,0xA0,0xFB,0xE0,0x2C, + 0xA0,0xF7,0xE0,0x24,0x80,0xB7,0xE0,0x6C,0x80,0x34,0x80,0xCB,0xE0}; const u8g_fntpgm_uint8_t fontpage_298_247_247[45] U8G_FONT_SECTION("fontpage_298_247_247") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xf7,0xf7,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0x3f,0x80,0x20,0x00,0x3f,0x00,0x20,0x00,0x3f, - 0x00,0x20,0x00,0xff,0xc0,0x24,0x80,0x23,0x00,0x29,0x00,0x30,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF7,0xF7,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0x3F,0x80,0x20,0x00,0x3F,0x00,0x20,0x00,0x3F, + 0x00,0x20,0x00,0xFF,0xC0,0x24,0x80,0x23,0x00,0x29,0x00,0x30,0xC0}; const u8g_fntpgm_uint8_t fontpage_299_137_137[45] U8G_FONT_SECTION("fontpage_299_137_137") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xfb,0xe0,0x8a,0x20,0xfb,0xe0,0x8a,0x20,0xfb, - 0xe0,0x82,0x20,0xbf,0xa0,0x8a,0x20,0x92,0x20,0xa2,0x20,0x86,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x89,0x89,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xFB,0xE0,0x8A,0x20,0xFB,0xE0,0x8A,0x20,0xFB, + 0xE0,0x82,0x20,0xBF,0xA0,0x8A,0x20,0x92,0x20,0xA2,0x20,0x86,0xE0}; const u8g_fntpgm_uint8_t fontpage_299_139_139[45] U8G_FONT_SECTION("fontpage_299_139_139") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x8b,0x8b,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xfb,0xe0,0x8a,0x20,0xfb,0xe0,0x8a,0x20,0xfb, - 0xe0,0x80,0x20,0x9f,0x20,0x8a,0x20,0xbf,0xa0,0x8a,0x20,0x92,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8B,0x8B,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xFB,0xE0,0x8A,0x20,0xFB,0xE0,0x8A,0x20,0xFB, + 0xE0,0x80,0x20,0x9F,0x20,0x8A,0x20,0xBF,0xA0,0x8A,0x20,0x92,0xE0}; const u8g_fntpgm_uint8_t fontpage_299_147_147[45] U8G_FONT_SECTION("fontpage_299_147_147") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x93,0x93,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xfb,0xe0,0x8a,0x20,0xfb,0xe0,0x8a,0x20,0xfb, - 0xe0,0x9f,0x20,0x91,0x20,0x9f,0x20,0x91,0x20,0x9f,0x20,0x80,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x93,0x93,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xFB,0xE0,0x8A,0x20,0xFB,0xE0,0x8A,0x20,0xFB, + 0xE0,0x9F,0x20,0x91,0x20,0x9F,0x20,0x91,0x20,0x9F,0x20,0x80,0xE0}; const u8g_fntpgm_uint8_t fontpage_299_220_220[45] U8G_FONT_SECTION("fontpage_299_220_220") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xdc,0xdc,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xfb,0xe0,0x8a,0x20,0xfb,0xe0,0x8a,0x20,0xf5, - 0xe0,0xaa,0xa0,0xbb,0xa0,0xaa,0xa0,0xbb,0xa0,0x8a,0x20,0xb2,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDC,0xDC,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xFB,0xE0,0x8A,0x20,0xFB,0xE0,0x8A,0x20,0xF5, + 0xE0,0xAA,0xA0,0xBB,0xA0,0xAA,0xA0,0xBB,0xA0,0x8A,0x20,0xB2,0x60}; const u8g_fntpgm_uint8_t fontpage_300_205_205[45] U8G_FONT_SECTION("fontpage_300_205_205") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcd,0xcd,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xf2,0x00,0x93,0xe0,0xa6,0x40,0xc1,0x80,0xa6, - 0x60,0x91,0x00,0x97,0xe0,0xd5,0x00,0xaf,0xe0,0x81,0x00,0x81,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCD,0xCD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xF2,0x00,0x93,0xE0,0xA6,0x40,0xC1,0x80,0xA6, + 0x60,0x91,0x00,0x97,0xE0,0xD5,0x00,0xAF,0xE0,0x81,0x00,0x81,0x00}; const u8g_fntpgm_uint8_t fontpage_300_228_228[45] U8G_FONT_SECTION("fontpage_300_228_228") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe4,0xe4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xf1,0x00,0x92,0x80,0xa4,0x40,0xcb,0xa0,0xa1, - 0x00,0x9f,0xe0,0x91,0x00,0xe5,0x40,0x89,0x20,0x91,0x20,0x83,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE4,0xE4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xF1,0x00,0x92,0x80,0xA4,0x40,0xCB,0xA0,0xA1, + 0x00,0x9F,0xE0,0x91,0x00,0xE5,0x40,0x89,0x20,0x91,0x20,0x83,0x00}; +const u8g_fntpgm_uint8_t fontpage_301_142_142[45] U8G_FONT_SECTION("fontpage_301_142_142") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x8E,0x8E,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xF8,0x80,0x98,0xA0,0xAE,0xC0,0xC8,0xA0,0xAE, + 0xE0,0x92,0x00,0x97,0xC0,0xF4,0x40,0xA7,0xC0,0x84,0x40,0x87,0xC0}; const u8g_fntpgm_uint8_t fontpage_301_217_217[45] U8G_FONT_SECTION("fontpage_301_217_217") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd9,0xd9,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x2a,0x80,0x3f,0xe0,0x6a,0x80,0xbf,0xc0,0x2a, - 0x80,0x3f,0xe0,0x00,0x00,0x3f,0xc0,0x08,0x80,0x07,0x00,0x78,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD9,0xD9,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x2A,0x80,0x3F,0xE0,0x6A,0x80,0xBF,0xC0,0x2A, + 0x80,0x3F,0xE0,0x00,0x00,0x3F,0xC0,0x08,0x80,0x07,0x00,0x78,0xE0}; +const u8g_fntpgm_uint8_t fontpage_301_226_226[45] U8G_FONT_SECTION("fontpage_301_226_226") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE2,0xE2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x80,0xFD,0x40,0x55,0xE0,0x6F,0x40,0x55, + 0xE0,0x7D,0x40,0x21,0x40,0xFD,0xE0,0xAD,0x40,0xB5,0x40,0x8D,0xE0}; const u8g_fntpgm_uint8_t fontpage_301_251_251[45] U8G_FONT_SECTION("fontpage_301_251_251") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfb,0xfb,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x7f,0xc0,0x04,0x00,0xff,0xe0,0xa4,0xa0,0x7f, - 0xc0,0x44,0x40,0x7f,0xc0,0x44,0x40,0x7f,0xc0,0x04,0x20,0x07,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFB,0xFB,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0xC0,0x04,0x00,0xFF,0xE0,0xA4,0xA0,0x7F, + 0xC0,0x44,0x40,0x7F,0xC0,0x44,0x40,0x7F,0xC0,0x04,0x20,0x07,0xE0}; const u8g_fntpgm_uint8_t fontpage_302_210_210[45] U8G_FONT_SECTION("fontpage_302_210_210") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd2,0xd2,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0x7f,0xc0,0x04,0x00,0x3f,0x80,0x04, - 0x00,0xff,0xe0,0x10,0x80,0x1f,0x80,0x10,0x80,0x1f,0x80,0x10,0x80}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD2,0xD2,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0x7F,0xC0,0x04,0x00,0x3F,0x80,0x04, + 0x00,0xFF,0xE0,0x10,0x80,0x1F,0x80,0x10,0x80,0x1F,0x80,0x10,0x80}; const u8g_fntpgm_uint8_t fontpage_302_222_222[45] U8G_FONT_SECTION("fontpage_302_222_222") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xde,0xde,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x0a,0x00,0x0a,0x00,0xfb,0xe0,0x0a,0x00,0x0a, - 0x00,0x7b,0xc0,0x0a,0x00,0x0a,0x00,0xfb,0xe0,0x0a,0x00,0x0a,0x00}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDE,0xDE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x0A,0x00,0x0A,0x00,0xFB,0xE0,0x0A,0x00,0x0A, + 0x00,0x7B,0xC0,0x0A,0x00,0x0A,0x00,0xFB,0xE0,0x0A,0x00,0x0A,0x00}; const u8g_fntpgm_uint8_t fontpage_302_226_226[45] U8G_FONT_SECTION("fontpage_302_226_226") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xe2,0xe2,0x00,0x0a,0xff,0x00, - 0x00,0x0a,0x0b,0x16,0x0c,0x01,0xff,0xff,0xc0,0x08,0x00,0x10,0x00,0xff,0xc0,0x92, - 0x40,0x9e,0x40,0x92,0x40,0x9e,0x40,0x92,0x40,0xff,0xc0,0x80,0x40}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xE2,0xE2,0x00,0x0A,0xFF,0x00, + 0x00,0x0A,0x0B,0x16,0x0C,0x01,0xFF,0xFF,0xC0,0x08,0x00,0x10,0x00,0xFF,0xC0,0x92, + 0x40,0x9E,0x40,0x92,0x40,0x9E,0x40,0x92,0x40,0xFF,0xC0,0x80,0x40}; const u8g_fntpgm_uint8_t fontpage_304_133_133[45] U8G_FONT_SECTION("fontpage_304_133_133") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x85,0x85,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x07,0xe0,0xf9,0x00,0x27,0xe0,0x24,0x20,0x27, - 0xe0,0x24,0x20,0x3f,0xe0,0xc4,0x20,0x07,0xe0,0x02,0x40,0x0c,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x85,0x85,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x07,0xE0,0xF9,0x00,0x27,0xE0,0x24,0x20,0x27, + 0xE0,0x24,0x20,0x3F,0xE0,0xC4,0x20,0x07,0xE0,0x02,0x40,0x0C,0x20}; const u8g_fntpgm_uint8_t fontpage_304_144_144[45] U8G_FONT_SECTION("fontpage_304_144_144") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x90,0x90,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xff,0xe0,0x91,0x00,0x67,0xc0,0x24,0x40,0xff, - 0xc0,0x24,0x40,0x27,0xc0,0x24,0x40,0x27,0xc0,0x22,0x80,0xec,0x60}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x90,0x90,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xFF,0xE0,0x91,0x00,0x67,0xC0,0x24,0x40,0xFF, + 0xC0,0x24,0x40,0x27,0xC0,0x24,0x40,0x27,0xC0,0x22,0x80,0xEC,0x60}; const u8g_fntpgm_uint8_t fontpage_304_205_205[45] U8G_FONT_SECTION("fontpage_304_205_205") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xcd,0xcd,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x23,0xe0,0xfc,0x80,0xa7,0xe0,0x3a,0x20,0x4b, - 0xe0,0xb2,0x20,0x4b,0xe0,0xfe,0x20,0x4b,0xe0,0x79,0x40,0x4e,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCD,0xCD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x23,0xE0,0xFC,0x80,0xA7,0xE0,0x3A,0x20,0x4B, + 0xE0,0xB2,0x20,0x4B,0xE0,0xFE,0x20,0x4B,0xE0,0x79,0x40,0x4E,0x20}; const u8g_fntpgm_uint8_t fontpage_304_222_222[45] U8G_FONT_SECTION("fontpage_304_222_222") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xde,0xde,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xab,0xe0,0x70,0x80,0x23,0xe0,0xfa,0x20,0x73, - 0xe0,0xaa,0x20,0x23,0xe0,0xfa,0x20,0x23,0xe0,0x51,0x40,0x8e,0x20}; -const u8g_fntpgm_uint8_t fontpage_305_132_132[45] U8G_FONT_SECTION("fontpage_305_132_132") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x84,0x84,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xfb,0xe0,0x10,0x80,0x63,0xe0,0x22,0x20,0xfa, - 0xa0,0x2a,0xa0,0x22,0xa0,0x22,0xa0,0x22,0xa0,0x21,0x40,0x66,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDE,0xDE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xAB,0xE0,0x70,0x80,0x23,0xE0,0xFA,0x20,0x73, + 0xE0,0xAA,0x20,0x23,0xE0,0xFA,0x20,0x23,0xE0,0x51,0x40,0x8E,0x20}; const u8g_fntpgm_uint8_t fontpage_305_168_168[45] U8G_FONT_SECTION("fontpage_305_168_168") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xa8,0xa8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x3f,0xc0,0x21,0x40,0x2e,0x40,0x24,0x40,0x3f, - 0x40,0x35,0x40,0x3f,0x40,0x25,0x40,0x27,0x60,0x5c,0xa0,0x88,0x20}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xA8,0xA8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x3F,0xC0,0x21,0x40,0x2E,0x40,0x24,0x40,0x3F, + 0x40,0x35,0x40,0x3F,0x40,0x25,0x40,0x27,0x60,0x5C,0xA0,0x88,0x20}; const u8g_fntpgm_uint8_t fontpage_305_253_253[45] U8G_FONT_SECTION("fontpage_305_253_253") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xfd,0xfd,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x22,0x00,0x52,0x00,0xab,0xe0,0xfc,0x20,0x8b, - 0xa0,0xfa,0xa0,0x8b,0xa0,0xfa,0x40,0x92,0x20,0xaa,0x20,0xc9,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xFD,0xFD,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x22,0x00,0x52,0x00,0xAB,0xE0,0xFC,0x20,0x8B, + 0xA0,0xFA,0xA0,0x8B,0xA0,0xFA,0x40,0x92,0x20,0xAA,0x20,0xC9,0xE0}; +const u8g_fntpgm_uint8_t fontpage_306_152_152[45] U8G_FONT_SECTION("fontpage_306_152_152") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x98,0x98,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x21,0x00,0x52,0x80,0xAC,0x40,0xF8,0x20,0x8F, + 0xC0,0xF9,0x00,0x8F,0xE0,0xF9,0x00,0x95,0x40,0xB9,0x20,0xCB,0x00}; const u8g_fntpgm_uint8_t fontpage_307_172_172[45] U8G_FONT_SECTION("fontpage_307_172_172") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xac,0xac,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x3f,0xc0,0x24,0x00,0x3f,0x80,0x24,0x00,0x3f, - 0x80,0x24,0x00,0x3f,0xe0,0x00,0x20,0x55,0x20,0x4a,0xa0,0x8a,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xAC,0xAC,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x3F,0xC0,0x24,0x00,0x3F,0x80,0x24,0x00,0x3F, + 0x80,0x24,0x00,0x3F,0xE0,0x00,0x20,0x55,0x20,0x4A,0xA0,0x8A,0xC0}; const u8g_fntpgm_uint8_t fontpage_308_197_197[45] U8G_FONT_SECTION("fontpage_308_197_197") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc5,0xc5,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x7f,0xe0,0x54,0x00,0x7d,0xc0,0x55,0x40,0x7d, - 0xc0,0x54,0x00,0x7f,0xe0,0x5e,0xa0,0xaf,0xe0,0xac,0x00,0x17,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC5,0xC5,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x7F,0xE0,0x54,0x00,0x7D,0xC0,0x55,0x40,0x7D, + 0xC0,0x54,0x00,0x7F,0xE0,0x5E,0xA0,0xAF,0xE0,0xAC,0x00,0x17,0xE0}; +const u8g_fntpgm_uint8_t fontpage_309_212_212[45] U8G_FONT_SECTION("fontpage_309_212_212") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD4,0xD4,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x79,0x40,0x6B,0xE0,0x5A,0xA0,0xFF,0xE0,0x86, + 0xA0,0x7F,0xE0,0x4A,0x40,0x7B,0xC0,0x4A,0x40,0x79,0x80,0x4F,0xE0}; const u8g_fntpgm_uint8_t fontpage_309_216_216[45] U8G_FONT_SECTION("fontpage_309_216_216") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xd8,0xd8,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x04,0x00,0xff,0xe0,0x00,0x00,0x1f,0x00,0x11, - 0x00,0x7f,0xc0,0x40,0x40,0x5f,0x40,0x51,0x40,0x5f,0x40,0x40,0xc0}; -const u8g_fntpgm_uint8_t fontpage_317_196_196[45] U8G_FONT_SECTION("fontpage_317_196_196") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xc4,0xc4,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0x11,0x00,0x7f,0xc0,0x11,0x00,0xff,0xe0,0x04, - 0x00,0x3f,0x80,0x24,0x80,0x3f,0x80,0x24,0x80,0x3f,0x80,0x60,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xD8,0xD8,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0xFF,0xE0,0x00,0x00,0x1F,0x00,0x11, + 0x00,0x7F,0xC0,0x40,0x40,0x5F,0x40,0x51,0x40,0x5F,0x40,0x40,0xC0}; +const u8g_fntpgm_uint8_t fontpage_317_195_195[45] U8G_FONT_SECTION("fontpage_317_195_195") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xC3,0xC3,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x11,0x00,0xFF,0xE0,0x11,0x00,0x1F,0x00,0x00, + 0x00,0xFF,0xE0,0x24,0x80,0x3F,0x80,0x24,0x80,0x3F,0x80,0xC0,0x60}; const u8g_fntpgm_uint8_t fontpage_317_222_222[45] U8G_FONT_SECTION("fontpage_317_222_222") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0xde,0xde,0x00,0x0a,0xff,0x00, - 0x00,0x0b,0x0b,0x16,0x0c,0x00,0xff,0xf8,0x80,0xa8,0x80,0xf8,0xe0,0xa8,0x80,0xf8, - 0x80,0x23,0xe0,0xfa,0x20,0x22,0x20,0xfa,0x20,0x52,0x20,0xab,0xe0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xDE,0xDE,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0xF8,0x80,0xA8,0x80,0xF8,0xE0,0xA8,0x80,0xF8, + 0x80,0x23,0xE0,0xFA,0x20,0x22,0x20,0xFA,0x20,0x52,0x20,0xAB,0xE0}; +const u8g_fntpgm_uint8_t fontpage_318_202_202[45] U8G_FONT_SECTION("fontpage_318_202_202") = { + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xCA,0xCA,0x00,0x0A,0xFF,0x00, + 0x00,0x0B,0x0B,0x16,0x0C,0x00,0xFF,0x04,0x00,0xFF,0xE0,0x0A,0x40,0xF5,0x80,0x55, + 0x40,0x95,0xA0,0x20,0x80,0x3F,0x80,0x20,0x80,0x3F,0x80,0xC0,0x80}; const u8g_fntpgm_uint8_t fontpage_510_154_154[30] U8G_FONT_SECTION("fontpage_510_154_154") = { - 0x00,0x06,0x0c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x9a,0x9a,0x00,0x08,0x00,0x00, - 0x00,0x02,0x07,0x07,0x0c,0x06,0x01,0xc0,0xc0,0x00,0x00,0x00,0xc0,0xc0}; + 0x00,0x0C,0x0F,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x9A,0x9A,0x00,0x08,0x00,0x00, + 0x00,0x02,0x07,0x07,0x0C,0x06,0x01,0xC0,0xC0,0x00,0x00,0x00,0xC0,0xC0}; #define FONTDATA_ITEM(page, begin, end, data) { page, begin, end, COUNT(data), data } static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { - FONTDATA_ITEM(64, 157, 157, fontpage_64_157_157), // '”' -- '”' FONTDATA_ITEM(69, 191, 191, fontpage_69_191_191), // '⊿' -- '⊿' FONTDATA_ITEM(156, 128, 128, fontpage_156_128_128), // '一' -- '一' FONTDATA_ITEM(156, 137, 139, fontpage_156_137_139), // '三' -- '下' + FONTDATA_ITEM(156, 141, 141, fontpage_156_141_141), // '不' -- '不' FONTDATA_ITEM(156, 166, 166, fontpage_156_166_166), // '並' -- '並' - FONTDATA_ITEM(156, 170, 170, fontpage_156_170_170), // '个' -- '个' FONTDATA_ITEM(156, 173, 173, fontpage_156_173_173), // '中' -- '中' FONTDATA_ITEM(156, 187, 187, fontpage_156_187_187), // '主' -- '主' FONTDATA_ITEM(156, 203, 203, fontpage_156_203_203), // '之' -- '之' + FONTDATA_ITEM(157, 164, 164, fontpage_157_164_164), // '交' -- '交' FONTDATA_ITEM(157, 174, 174, fontpage_157_174_174), // '亮' -- '亮' FONTDATA_ITEM(157, 228, 228, fontpage_157_228_228), // '令' -- '令' + FONTDATA_ITEM(157, 246, 246, fontpage_157_246_246), // '件' -- '件' FONTDATA_ITEM(157, 253, 253, fontpage_157_253_253), // '份' -- '份' FONTDATA_ITEM(158, 145, 145, fontpage_158_145_145), // '休' -- '休' FONTDATA_ITEM(158, 205, 206, fontpage_158_205_206), // '位' -- '低' FONTDATA_ITEM(158, 220, 220, fontpage_158_220_220), // '作' -- '作' - FONTDATA_ITEM(159, 134, 134, fontpage_159_134_134), // '來' -- '來' FONTDATA_ITEM(159, 155, 155, fontpage_159_155_155), // '供' -- '供' FONTDATA_ITEM(159, 221, 221, fontpage_159_221_221), // '保' -- '保' FONTDATA_ITEM(159, 225, 225, fontpage_159_225_225), // '信' -- '信' @@ -1117,15 +1242,18 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(160, 188, 188, fontpage_160_188_188), // '值' -- '值' FONTDATA_ITEM(160, 207, 207, fontpage_160_207_207), // '偏' -- '偏' FONTDATA_ITEM(160, 220, 220, fontpage_160_220_220), // '停' -- '停' + FONTDATA_ITEM(160, 245, 245, fontpage_160_245_245), // '偵' -- '偵' FONTDATA_ITEM(161, 153, 153, fontpage_161_153_153), // '備' -- '備' FONTDATA_ITEM(161, 179, 179, fontpage_161_179_179), // '傳' -- '傳' + FONTDATA_ITEM(161, 190, 190, fontpage_161_190_190), // '傾' -- '傾' FONTDATA_ITEM(162, 178, 178, fontpage_162_178_178), // '儲' -- '儲' FONTDATA_ITEM(162, 197, 197, fontpage_162_197_197), // '充' -- '充' - FONTDATA_ITEM(162, 200, 200, fontpage_162_200_200), // '先' -- '先' + FONTDATA_ITEM(162, 200, 201, fontpage_162_200_201), // '先' -- '光' FONTDATA_ITEM(162, 229, 229, fontpage_162_229_229), // '入' -- '入' FONTDATA_ITEM(162, 232, 232, fontpage_162_232_232), // '全' -- '全' FONTDATA_ITEM(162, 241, 241, fontpage_162_241_241), // '共' -- '共' FONTDATA_ITEM(162, 247, 247, fontpage_162_247_247), // '具' -- '具' + FONTDATA_ITEM(163, 151, 151, fontpage_163_151_151), // '冗' -- '冗' FONTDATA_ITEM(163, 183, 183, fontpage_163_183_183), // '冷' -- '冷' FONTDATA_ITEM(163, 198, 198, fontpage_163_198_198), // '准' -- '准' FONTDATA_ITEM(163, 250, 250, fontpage_163_250_250), // '出' -- '出' @@ -1137,7 +1265,6 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(164, 245, 245, fontpage_164_245_245), // '創' -- '創' FONTDATA_ITEM(165, 155, 155, fontpage_165_155_155), // '力' -- '力' FONTDATA_ITEM(165, 160, 160, fontpage_165_160_160), // '加' -- '加' - FONTDATA_ITEM(165, 168, 168, fontpage_165_168_168), // '动' -- '动' FONTDATA_ITEM(165, 213, 213, fontpage_165_213_213), // '動' -- '動' FONTDATA_ITEM(166, 150, 150, fontpage_166_150_150), // '化' -- '化' FONTDATA_ITEM(166, 202, 202, fontpage_166_202_202), // '半' -- '半' @@ -1145,30 +1272,39 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(166, 225, 225, fontpage_166_225_225), // '卡' -- '卡' FONTDATA_ITEM(166, 240, 240, fontpage_166_240_240), // '印' -- '印' FONTDATA_ITEM(166, 248, 248, fontpage_166_248_248), // '卸' -- '卸' + FONTDATA_ITEM(166, 251, 251, fontpage_166_251_251), // '卻' -- '卻' FONTDATA_ITEM(167, 159, 159, fontpage_167_159_159), // '原' -- '原' + FONTDATA_ITEM(167, 205, 205, fontpage_167_205_205), // '反' -- '反' FONTDATA_ITEM(167, 214, 214, fontpage_167_214_214), // '取' -- '取' FONTDATA_ITEM(167, 240, 240, fontpage_167_240_240), // '台' -- '台' FONTDATA_ITEM(168, 136, 136, fontpage_168_136_136), // '合' -- '合' + FONTDATA_ITEM(168, 166, 166, fontpage_168_166_166), // '否' -- '否' + FONTDATA_ITEM(168, 202, 202, fontpage_168_202_202), // '告' -- '告' FONTDATA_ITEM(168, 253, 253, fontpage_168_253_253), // '命' -- '命' FONTDATA_ITEM(169, 140, 140, fontpage_169_140_140), // '和' -- '和' FONTDATA_ITEM(170, 223, 223, fontpage_170_223_223), // '啟' -- '啟' FONTDATA_ITEM(171, 174, 174, fontpage_171_174_174), // '單' -- '單' FONTDATA_ITEM(172, 180, 180, fontpage_172_180_180), // '嘴' -- '嘴' + FONTDATA_ITEM(172, 232, 232, fontpage_172_232_232), // '器' -- '器' FONTDATA_ITEM(172, 244, 244, fontpage_172_244_244), // '噴' -- '噴' FONTDATA_ITEM(173, 222, 222, fontpage_173_222_222), // '回' -- '回' FONTDATA_ITEM(173, 224, 224, fontpage_173_224_224), // '因' -- '因' + FONTDATA_ITEM(173, 250, 250, fontpage_173_250_250), // '固' -- '固' FONTDATA_ITEM(174, 150, 150, fontpage_174_150_150), // '圖' -- '圖' FONTDATA_ITEM(174, 168, 168, fontpage_174_168_168), // '在' -- '在' FONTDATA_ITEM(175, 139, 139, fontpage_175_139_139), // '型' -- '型' + FONTDATA_ITEM(175, 247, 247, fontpage_175_247_247), // '執' -- '執' FONTDATA_ITEM(176, 202, 202, fontpage_176_202_202), // '塊' -- '塊' FONTDATA_ITEM(176, 235, 235, fontpage_176_235_235), // '填' -- '填' FONTDATA_ITEM(177, 138, 138, fontpage_177_138_138), // '墊' -- '墊' FONTDATA_ITEM(178, 150, 150, fontpage_178_150_150), // '外' -- '外' FONTDATA_ITEM(178, 154, 154, fontpage_178_154_154), // '多' -- '多' + FONTDATA_ITEM(178, 160, 160, fontpage_178_160_160), // '夠' -- '夠' FONTDATA_ITEM(178, 167, 167, fontpage_178_167_167), // '大' -- '大' FONTDATA_ITEM(178, 169, 170, fontpage_178_169_170), // '天' -- '太' FONTDATA_ITEM(178, 177, 177, fontpage_178_177_177), // '失' -- '失' FONTDATA_ITEM(179, 203, 203, fontpage_179_203_203), // '始' -- '始' + FONTDATA_ITEM(181, 146, 146, fontpage_181_146_146), // '媒' -- '媒' FONTDATA_ITEM(182, 208, 208, fontpage_182_208_208), // '子' -- '子' FONTDATA_ITEM(182, 216, 216, fontpage_182_216_216), // '存' -- '存' FONTDATA_ITEM(183, 137, 137, fontpage_183_137_137), // '安' -- '安' @@ -1180,12 +1316,14 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(184, 143, 143, fontpage_184_143_143), // '小' -- '小' FONTDATA_ITEM(184, 177, 177, fontpage_184_177_177), // '就' -- '就' FONTDATA_ITEM(187, 229, 229, fontpage_187_229_229), // '工' -- '工' + FONTDATA_ITEM(187, 238, 238, fontpage_187_238_238), // '差' -- '差' FONTDATA_ITEM(187, 242, 242, fontpage_187_242_242), // '已' -- '已' FONTDATA_ITEM(188, 243, 243, fontpage_188_243_243), // '平' -- '平' FONTDATA_ITEM(189, 138, 138, fontpage_189_138_138), // '床' -- '床' FONTDATA_ITEM(189, 166, 166, fontpage_189_166_166), // '度' -- '度' FONTDATA_ITEM(189, 226, 226, fontpage_189_226_226), // '廢' -- '廢' FONTDATA_ITEM(189, 250, 250, fontpage_189_250_250), // '建' -- '建' + FONTDATA_ITEM(190, 149, 149, fontpage_190_149_149), // '引' -- '引' FONTDATA_ITEM(191, 133, 133, fontpage_191_133_133), // '待' -- '待' FONTDATA_ITEM(191, 140, 140, fontpage_191_140_140), // '後' -- '後' FONTDATA_ITEM(191, 145, 145, fontpage_191_145_145), // '徑' -- '徑' @@ -1204,7 +1342,6 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(196, 199, 199, fontpage_196_199_199), // '扇' -- '扇' FONTDATA_ITEM(196, 203, 203, fontpage_196_203_203), // '手' -- '手' FONTDATA_ITEM(196, 211, 211, fontpage_196_211_211), // '打' -- '打' - FONTDATA_ITEM(196, 231, 231, fontpage_196_231_231), // '执' -- '执' FONTDATA_ITEM(196, 249, 249, fontpage_196_249_249), // '批' -- '批' FONTDATA_ITEM(197, 150, 150, fontpage_197_150_150), // '抖' -- '抖' FONTDATA_ITEM(197, 189, 189, fontpage_197_189_189), // '抽' -- '抽' @@ -1212,12 +1349,15 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(198, 137, 137, fontpage_198_137_137), // '按' -- '按' FONTDATA_ITEM(199, 137, 137, fontpage_199_137_137), // '掉' -- '掉' FONTDATA_ITEM(199, 162, 162, fontpage_199_162_162), // '探' -- '探' + FONTDATA_ITEM(199, 165, 165, fontpage_199_165_165), // '接' -- '接' FONTDATA_ITEM(199, 167, 167, fontpage_199_167_167), // '控' -- '控' + FONTDATA_ITEM(199, 208, 208, fontpage_199_208_208), // '提' -- '提' FONTDATA_ITEM(199, 210, 210, fontpage_199_210_210), // '插' -- '插' FONTDATA_ITEM(199, 219, 219, fontpage_199_219_219), // '換' -- '換' FONTDATA_ITEM(201, 199, 199, fontpage_201_199_199), // '擇' -- '擇' FONTDATA_ITEM(201, 202, 203, fontpage_201_202_203), // '擊' -- '擋' FONTDATA_ITEM(201, 224, 224, fontpage_201_224_224), // '擠' -- '擠' + FONTDATA_ITEM(202, 182, 182, fontpage_202_182_182), // '收' -- '收' FONTDATA_ITEM(202, 190, 190, fontpage_202_190_190), // '放' -- '放' FONTDATA_ITEM(202, 215, 215, fontpage_202_215_215), // '敗' -- '敗' FONTDATA_ITEM(202, 244, 244, fontpage_202_244_244), // '整' -- '整' @@ -1225,8 +1365,11 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(203, 153, 153, fontpage_203_153_153), // '料' -- '料' FONTDATA_ITEM(203, 156, 156, fontpage_203_156_156), // '斜' -- '斜' FONTDATA_ITEM(203, 176, 176, fontpage_203_176_176), // '新' -- '新' + FONTDATA_ITEM(203, 183, 183, fontpage_203_183_183), // '斷' -- '斷' FONTDATA_ITEM(203, 188, 188, fontpage_203_188_188), // '於' -- '於' + FONTDATA_ITEM(204, 135, 135, fontpage_204_135_135), // '昇' -- '昇' FONTDATA_ITEM(204, 142, 142, fontpage_204_142_142), // '明' -- '明' + FONTDATA_ITEM(204, 175, 175, fontpage_204_175_175), // '是' -- '是' FONTDATA_ITEM(204, 194, 194, fontpage_204_194_194), // '時' -- '時' FONTDATA_ITEM(205, 171, 171, fontpage_205_171_171), // '暫' -- '暫' FONTDATA_ITEM(205, 244, 244, fontpage_205_244_244), // '更' -- '更' @@ -1237,19 +1380,18 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(208, 161, 161, fontpage_208_161_161), // '校' -- '校' FONTDATA_ITEM(208, 188, 188, fontpage_208_188_188), // '格' -- '格' FONTDATA_ITEM(209, 157, 157, fontpage_209_157_157), // '條' -- '條' + FONTDATA_ITEM(209, 196, 196, fontpage_209_196_196), // '棄' -- '棄' FONTDATA_ITEM(211, 253, 253, fontpage_211_253_253), // '槽' -- '槽' FONTDATA_ITEM(212, 217, 217, fontpage_212_217_217), // '橙' -- '橙' FONTDATA_ITEM(212, 223, 223, fontpage_212_223_223), // '機' -- '機' FONTDATA_ITEM(213, 162, 162, fontpage_213_162_162), // '檢' -- '檢' - FONTDATA_ITEM(214, 226, 226, fontpage_214_226_226), // '止' -- '止' + FONTDATA_ITEM(214, 226, 227, fontpage_214_226_227), // '止' -- '正' FONTDATA_ITEM(214, 229, 229, fontpage_214_229_229), // '步' -- '步' FONTDATA_ITEM(214, 248, 248, fontpage_214_248_248), // '歸' -- '歸' FONTDATA_ITEM(215, 188, 188, fontpage_215_188_188), // '殼' -- '殼' FONTDATA_ITEM(215, 212, 212, fontpage_215_212_212), // '比' -- '比' FONTDATA_ITEM(217, 146, 146, fontpage_217_146_146), // '沒' -- '沒' - FONTDATA_ITEM(218, 187, 187, fontpage_218_187_187), // '活' -- '活' FONTDATA_ITEM(219, 136, 136, fontpage_219_136_136), // '消' -- '消' - FONTDATA_ITEM(219, 188, 188, fontpage_219_188_188), // '涼' -- '涼' FONTDATA_ITEM(219, 225, 225, fontpage_219_225_225), // '淡' -- '淡' FONTDATA_ITEM(220, 133, 133, fontpage_220_133_133), // '清' -- '清' FONTDATA_ITEM(220, 172, 172, fontpage_220_172_172), // '測' -- '測' @@ -1257,30 +1399,35 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(221, 150, 150, fontpage_221_150_150), // '準' -- '準' FONTDATA_ITEM(221, 171, 171, fontpage_221_171_171), // '溫' -- '溫' FONTDATA_ITEM(223, 192, 192, fontpage_223_192_192), // '激' -- '激' - FONTDATA_ITEM(224, 239, 239, fontpage_224_239_239), // '灯' -- '灯' FONTDATA_ITEM(226, 161, 161, fontpage_226_161_161), // '無' -- '無' FONTDATA_ITEM(227, 177, 177, fontpage_227_177_177), // '熱' -- '熱' FONTDATA_ITEM(227, 200, 200, fontpage_227_200_200), // '燈' -- '燈' FONTDATA_ITEM(228, 199, 199, fontpage_228_199_199), // '片' -- '片' + FONTDATA_ITEM(228, 233, 233, fontpage_228_233_233), // '物' -- '物' FONTDATA_ITEM(231, 135, 135, fontpage_231_135_135), // '率' -- '率' FONTDATA_ITEM(234, 168, 168, fontpage_234_168_168), // '用' -- '用' FONTDATA_ITEM(234, 204, 204, fontpage_234_204_204), // '界' -- '界' FONTDATA_ITEM(236, 253, 253, fontpage_236_253_253), // '白' -- '白' FONTDATA_ITEM(237, 132, 132, fontpage_237_132_132), // '的' -- '的' + FONTDATA_ITEM(237, 227, 227, fontpage_237_227_227), // '監' -- '監' FONTDATA_ITEM(237, 244, 244, fontpage_237_244_244), // '直' -- '直' - FONTDATA_ITEM(238, 129, 129, fontpage_238_129_129), // '省' -- '省' FONTDATA_ITEM(238, 160, 160, fontpage_238_160_160), // '眠' -- '眠' FONTDATA_ITEM(240, 141, 141, fontpage_240_141_141), // '砍' -- '砍' + FONTDATA_ITEM(241, 186, 186, fontpage_241_186_186), // '確' -- '確' FONTDATA_ITEM(243, 251, 251, fontpage_243_251_251), // '移' -- '移' FONTDATA_ITEM(244, 205, 205, fontpage_244_205_205), // '積' -- '積' FONTDATA_ITEM(245, 239, 239, fontpage_245_239_239), // '端' -- '端' FONTDATA_ITEM(246, 201, 201, fontpage_246_201_201), // '等' -- '等' FONTDATA_ITEM(247, 161, 161, fontpage_247_161_161), // '管' -- '管' + FONTDATA_ITEM(247, 177, 177, fontpage_247_177_177), // '箱' -- '箱' FONTDATA_ITEM(249, 251, 251, fontpage_249_251_251), // '系' -- '系' + FONTDATA_ITEM(250, 133, 133, fontpage_250_133_133), // '紅' -- '紅' + FONTDATA_ITEM(250, 162, 162, fontpage_250_162_162), // '索' -- '索' FONTDATA_ITEM(250, 171, 171, fontpage_250_171_171), // '紫' -- '紫' FONTDATA_ITEM(250, 176, 176, fontpage_250_176_176), // '細' -- '細' FONTDATA_ITEM(250, 194, 194, fontpage_250_194_194), // '終' -- '終' FONTDATA_ITEM(250, 241, 242, fontpage_250_241_242), // '統' -- '絲' + FONTDATA_ITEM(251, 160, 160, fontpage_251_160_160), // '綠' -- '綠' FONTDATA_ITEM(251, 178, 178, fontpage_251_178_178), // '網' -- '網' FONTDATA_ITEM(251, 210, 210, fontpage_251_210_210), // '緒' -- '緒' FONTDATA_ITEM(251, 218, 218, fontpage_251_218_218), // '線' -- '線' @@ -1290,14 +1437,11 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(252, 252, 252, fontpage_252_252_252), // '繼' -- '繼' FONTDATA_ITEM(253, 140, 140, fontpage_253_140_140), // '續' -- '續' FONTDATA_ITEM(253, 162, 162, fontpage_253_162_162), // '红' -- '红' - FONTDATA_ITEM(253, 255, 255, fontpage_253_255_255), // '绿' -- '绿' - FONTDATA_ITEM(254, 186, 186, fontpage_254_186_186), // '缺' -- '缺' - FONTDATA_ITEM(254, 209, 209, fontpage_254_209_209), // '网' -- '网' FONTDATA_ITEM(254, 238, 238, fontpage_254_238_238), // '置' -- '置' FONTDATA_ITEM(254, 242, 242, fontpage_254_242_242), // '署' -- '署' FONTDATA_ITEM(256, 240, 240, fontpage_256_240_240), // '聰' -- '聰' FONTDATA_ITEM(259, 234, 234, fontpage_259_234_234), // '自' -- '自' - FONTDATA_ITEM(265, 221, 221, fontpage_265_221_221), // '蓝' -- '蓝' + FONTDATA_ITEM(267, 205, 205, fontpage_267_205_205), // '藍' -- '藍' FONTDATA_ITEM(272, 204, 204, fontpage_272_204_204), // '行' -- '行' FONTDATA_ITEM(272, 232, 232, fontpage_272_232_232), // '表' -- '表' FONTDATA_ITEM(273, 171, 171, fontpage_273_171_171), // '被' -- '被' @@ -1310,20 +1454,27 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(276, 152, 152, fontpage_276_152_152), // '記' -- '記' FONTDATA_ITEM(276, 173, 173, fontpage_276_173_173), // '設' -- '設' FONTDATA_ITEM(276, 230, 230, fontpage_276_230_230), // '試' -- '試' + FONTDATA_ITEM(277, 141, 141, fontpage_277_141_141), // '認' -- '認' FONTDATA_ITEM(277, 164, 164, fontpage_277_164_164), // '誤' -- '誤' FONTDATA_ITEM(277, 191, 191, fontpage_277_191_191), // '調' -- '調' FONTDATA_ITEM(277, 203, 203, fontpage_277_203_203), // '請' -- '請' FONTDATA_ITEM(278, 240, 240, fontpage_278_240_240), // '議' -- '議' + FONTDATA_ITEM(279, 128, 128, fontpage_279_128_128), // '讀' -- '讀' FONTDATA_ITEM(279, 138, 138, fontpage_279_138_138), // '變' -- '變' FONTDATA_ITEM(281, 199, 199, fontpage_281_199_199), // '資' -- '資' + FONTDATA_ITEM(283, 221, 221, fontpage_283_221_221), // '距' -- '距' + FONTDATA_ITEM(285, 202, 202, fontpage_285_202_202), // '車' -- '車' + FONTDATA_ITEM(285, 223, 223, fontpage_285_223_223), // '軟' -- '軟' FONTDATA_ITEM(285, 248, 248, fontpage_285_248_248), // '軸' -- '軸' FONTDATA_ITEM(286, 137, 137, fontpage_286_137_137), // '載' -- '載' FONTDATA_ITEM(286, 175, 175, fontpage_286_175_175), // '輯' -- '輯' FONTDATA_ITEM(286, 184, 184, fontpage_286_184_184), // '輸' -- '輸' + FONTDATA_ITEM(286, 201, 201, fontpage_286_201_201), // '轉' -- '轉' FONTDATA_ITEM(287, 209, 209, fontpage_287_209_209), // '近' -- '近' FONTDATA_ITEM(287, 212, 212, fontpage_287_212_212), // '返' -- '返' FONTDATA_ITEM(288, 128, 128, fontpage_288_128_128), // '退' -- '退' FONTDATA_ITEM(288, 159, 159, fontpage_288_159_159), // '速' -- '速' + FONTDATA_ITEM(288, 163, 163, fontpage_288_163_163), // '連' -- '連' FONTDATA_ITEM(288, 178, 178, fontpage_288_178_178), // '進' -- '進' FONTDATA_ITEM(288, 203, 203, fontpage_288_203_203), // '運' -- '運' FONTDATA_ITEM(288, 212, 212, fontpage_288_212_212), // '達' -- '達' @@ -1331,7 +1482,7 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(289, 132, 132, fontpage_289_132_132), // '還' -- '還' FONTDATA_ITEM(289, 138, 138, fontpage_289_138_138), // '邊' -- '邊' FONTDATA_ITEM(289, 232, 232, fontpage_289_232_232), // '部' -- '部' - FONTDATA_ITEM(291, 202, 202, fontpage_291_202_202), // '释' -- '释' + FONTDATA_ITEM(291, 203, 203, fontpage_291_203_203), // '釋' -- '釋' FONTDATA_ITEM(291, 205, 205, fontpage_291_205_205), // '重' -- '重' FONTDATA_ITEM(291, 207, 207, fontpage_291_207_207), // '量' -- '量' FONTDATA_ITEM(291, 221, 221, fontpage_291_221_221), // '針' -- '針' @@ -1345,7 +1496,9 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(299, 220, 220, fontpage_299_220_220), // '關' -- '關' FONTDATA_ITEM(300, 205, 205, fontpage_300_205_205), // '降' -- '降' FONTDATA_ITEM(300, 228, 228, fontpage_300_228_228), // '除' -- '除' + FONTDATA_ITEM(301, 142, 142, fontpage_301_142_142), // '階' -- '階' FONTDATA_ITEM(301, 217, 217, fontpage_301_217_217), // '雙' -- '雙' + FONTDATA_ITEM(301, 226, 226, fontpage_301_226_226), // '離' -- '離' FONTDATA_ITEM(301, 251, 251, fontpage_301_251_251), // '電' -- '電' FONTDATA_ITEM(302, 210, 210, fontpage_302_210_210), // '青' -- '青' FONTDATA_ITEM(302, 222, 222, fontpage_302_222_222), // '非' -- '非' @@ -1354,13 +1507,15 @@ static const uxg_fontinfo_t g_fontinfo[] PROGMEM = { FONTDATA_ITEM(304, 144, 144, fontpage_304_144_144), // '預' -- '預' FONTDATA_ITEM(304, 205, 205, fontpage_304_205_205), // '額' -- '額' FONTDATA_ITEM(304, 222, 222, fontpage_304_222_222), // '類' -- '類' - FONTDATA_ITEM(305, 132, 132, fontpage_305_132_132), // '预' -- '预' FONTDATA_ITEM(305, 168, 168, fontpage_305_168_168), // '風' -- '風' FONTDATA_ITEM(305, 253, 253, fontpage_305_253_253), // '飽' -- '飽' + FONTDATA_ITEM(306, 152, 152, fontpage_306_152_152), // '餘' -- '餘' FONTDATA_ITEM(307, 172, 172, fontpage_307_172_172), // '馬' -- '馬' FONTDATA_ITEM(308, 197, 197, fontpage_308_197_197), // '驅' -- '驅' + FONTDATA_ITEM(309, 212, 212, fontpage_309_212_212), // '體' -- '體' FONTDATA_ITEM(309, 216, 216, fontpage_309_216_216), // '高' -- '高' - FONTDATA_ITEM(317, 196, 196, fontpage_317_196_196), // '黄' -- '黄' + FONTDATA_ITEM(317, 195, 195, fontpage_317_195_195), // '黃' -- '黃' FONTDATA_ITEM(317, 222, 222, fontpage_317_222_222), // '點' -- '點' + FONTDATA_ITEM(318, 202, 202, fontpage_318_202_202), // '齊' -- '齊' FONTDATA_ITEM(510, 154, 154, fontpage_510_154_154), // ':' -- ':' }; diff --git a/Marlin/src/lcd/dogm/lcdprint_u8g.cpp b/Marlin/src/lcd/dogm/lcdprint_u8g.cpp index c9a55a16e3b4..a6bdb373dd70 100644 --- a/Marlin/src/lcd/dogm/lcdprint_u8g.cpp +++ b/Marlin/src/lcd/dogm/lcdprint_u8g.cpp @@ -9,7 +9,7 @@ #include "../../inc/MarlinConfigPre.h" -#if HAS_GRAPHICAL_LCD +#if HAS_MARLINUI_U8GLIB #include "ultralcd_DOGM.h" @@ -53,4 +53,4 @@ int lcd_put_u8str_max_P(PGM_P utf8_str_P, pixel_len_t max_length) { return ret; } -#endif // HAS_GRAPHICAL_LCD +#endif // HAS_MARLINUI_U8GLIB diff --git a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp index 1ea1424d306b..987924201a80 100644 --- a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp +++ b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -27,7 +27,7 @@ #include "../../inc/MarlinConfigPre.h" -#if HAS_GRAPHICAL_LCD && DISABLED(LIGHTWEIGHT_UI) +#if HAS_MARLINUI_U8GLIB && DISABLED(LIGHTWEIGHT_UI) #include "dogm_Statusscreen.h" #include "ultralcd_DOGM.h" @@ -48,6 +48,10 @@ #include "../../feature/spindle_laser.h" #endif +#if HAS_POWER_MONITOR + #include "../../feature/power_monitor.h" +#endif + #if ENABLED(SDSUPPORT) #include "../../sd/cardreader.h" #endif @@ -56,7 +60,7 @@ #include "../../module/printcounter.h" #endif -#if DUAL_MIXING_EXTRUDER +#if HAS_DUAL_MIXING #include "../../feature/mixing.h" #endif @@ -103,11 +107,69 @@ #define STATUS_HEATERS_BOT (STATUS_HEATERS_Y + STATUS_HEATERS_HEIGHT - 1) #endif +#if HAS_POWER_MONITOR + + void display_power_monitor(const uint8_t x, const uint8_t y) { + + lcd_moveto(x, y); + + #if HAS_POWER_MONITOR_WATTS + const bool wflag = power_monitor.power_display_enabled(); + #endif + #if ENABLED(POWER_MONITOR_CURRENT) + const bool iflag = power_monitor.current_display_enabled(); + #endif + #if HAS_POWER_MONITOR_VREF + const bool vflag = power_monitor.voltage_display_enabled(); + #endif + + #if HAS_POWER_MONITOR_WATTS + // Cycle between current, voltage, and power + if (ELAPSED(millis(), power_monitor.display_item_ms)) { + power_monitor.display_item_ms = millis() + 1000UL; + ++power_monitor.display_item; + } + #elif ENABLED(POWER_MONITOR_CURRENT) + power_monitor.display_item = 0; + #elif HAS_POWER_MONITOR_VREF + power_monitor.display_item = 1; + #endif + + // ensure we have the right one selected for display + for (uint8_t i = 0; i < 3; i++) { + #if ENABLED(POWER_MONITOR_CURRENT) + if (power_monitor.display_item == 0 && !iflag) ++power_monitor.display_item; + #endif + #if HAS_POWER_MONITOR_VREF + if (power_monitor.display_item == 1 && !vflag) ++power_monitor.display_item; + #endif + #if HAS_POWER_MONITOR_WATTS + if (power_monitor.display_item == 2 && !wflag) ++power_monitor.display_item; + #endif + if (power_monitor.display_item >= 3) power_monitor.display_item = 0; + } + + switch (power_monitor.display_item) { + #if ENABLED(POWER_MONITOR_CURRENT) // Current + case 0: if (iflag) power_monitor.draw_current(); break; + #endif + #if HAS_POWER_MONITOR_VREF // Voltage + case 1: if (vflag) power_monitor.draw_voltage(); break; + #endif + #if HAS_POWER_MONITOR_WATTS // Power + case 2: if (wflag) power_monitor.draw_power(); break; + #endif + default: break; + } + } +#endif + #define PROGRESS_BAR_X 54 +#define PROGRESS_BAR_Y (EXTRAS_BASELINE + 1) #define PROGRESS_BAR_WIDTH (LCD_PIXEL_WIDTH - PROGRESS_BAR_X) FORCE_INLINE void _draw_centered_temp(const int16_t temp, const uint8_t tx, const uint8_t ty) { - const char *str = i16tostr3(temp); + const char *str = i16tostr3rj(temp); const uint8_t len = str[0] != ' ' ? 3 : str[1] != ' ' ? 2 : 1; lcd_put_u8str(tx - len * (INFO_FONT_WIDTH) / 2 + 1, ty, &str[3-len]); lcd_put_wchar(LCD_STR_DEGREE[0]); @@ -116,17 +178,17 @@ FORCE_INLINE void _draw_centered_temp(const int16_t temp, const uint8_t tx, cons #if DO_DRAW_HOTENDS // Draw hotend bitmap with current and target temperatures - FORCE_INLINE void _draw_hotend_status(const heater_ind_t heater, const bool blink) { + FORCE_INLINE void _draw_hotend_status(const heater_id_t heater_id, const bool blink) { #if !HEATER_IDLE_HANDLER UNUSED(blink); #endif - const bool isHeat = HOTEND_ALT(heater); + const bool isHeat = HOTEND_ALT(heater_id); - const uint8_t tx = STATUS_HOTEND_TEXT_X(heater); + const uint8_t tx = STATUS_HOTEND_TEXT_X(heater_id); - const float temp = thermalManager.degHotend(heater), - target = thermalManager.degTargetHotend(heater); + const float temp = thermalManager.degHotend(heater_id), + target = thermalManager.degTargetHotend(heater_id); #if DISABLED(STATUS_HOTEND_ANIM) #define STATIC_HOTEND true @@ -142,7 +204,7 @@ FORCE_INLINE void _draw_centered_temp(const int16_t temp, const uint8_t tx, cons #elif ANIM_HOTEND && DISABLED(STATUS_HOTEND_INVERTED) && ENABLED(STATUS_HOTEND_NUMBERLESS) #define OFF_BMP(N) status_hotend_a_bmp #define ON_BMP(N) status_hotend_b_bmp - #elif ANIM_HOTEND && ENABLED(STATUS_HOTEND_INVERTED) + #elif BOTH(ANIM_HOTEND, STATUS_HOTEND_INVERTED) #define OFF_BMP(N) status_hotend##N##_b_bmp #define ON_BMP(N) status_hotend##N##_a_bmp #else @@ -175,24 +237,24 @@ FORCE_INLINE void _draw_centered_temp(const int16_t temp, const uint8_t tx, cons #if ANIM_HOTEND // Draw hotend bitmap, either whole or split by the heating percent - const uint8_t hx = STATUS_HOTEND_X(heater), - bw = STATUS_HOTEND_BYTEWIDTH(heater); + const uint8_t hx = STATUS_HOTEND_X(heater_id), + bw = STATUS_HOTEND_BYTEWIDTH(heater_id); #if ENABLED(STATUS_HEAT_PERCENT) if (isHeat && tall <= BAR_TALL) { const uint8_t ph = STATUS_HEATERS_HEIGHT - 1 - tall; - u8g.drawBitmapP(hx, STATUS_HEATERS_Y, bw, ph, HOTEND_BITMAP(heater, false)); - u8g.drawBitmapP(hx, STATUS_HEATERS_Y + ph, bw, tall + 1, HOTEND_BITMAP(heater, true) + ph * bw); + u8g.drawBitmapP(hx, STATUS_HEATERS_Y, bw, ph, HOTEND_BITMAP(heater_id, false)); + u8g.drawBitmapP(hx, STATUS_HEATERS_Y + ph, bw, tall + 1, HOTEND_BITMAP(heater_id, true) + ph * bw); } else #endif - u8g.drawBitmapP(hx, STATUS_HEATERS_Y, bw, STATUS_HEATERS_HEIGHT, HOTEND_BITMAP(heater, isHeat)); + u8g.drawBitmapP(hx, STATUS_HEATERS_Y, bw, STATUS_HEATERS_HEIGHT, HOTEND_BITMAP(heater_id, isHeat)); #endif } // PAGE_CONTAINS if (PAGE_UNDER(7)) { #if HEATER_IDLE_HANDLER - const bool dodraw = (blink || !thermalManager.hotend_idle[heater].timed_out); + const bool dodraw = (blink || !thermalManager.heater_idle[heater_id].timed_out); #else constexpr bool dodraw = true; #endif @@ -265,7 +327,7 @@ FORCE_INLINE void _draw_centered_temp(const int16_t temp, const uint8_t tx, cons if (PAGE_UNDER(7)) { #if HEATER_IDLE_HANDLER - const bool dodraw = (blink || !thermalManager.bed_idle.timed_out); + const bool dodraw = (blink || !thermalManager.heater_idle[thermalManager.IDLE_INDEX_BED].timed_out); #else constexpr bool dodraw = true; #endif @@ -305,12 +367,7 @@ FORCE_INLINE void _draw_centered_temp(const int16_t temp, const uint8_t tx, cons // Homed and known, display constantly. // FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const bool blink) { - const AxisEnum a = ( - #if ENABLED(LCD_SHOW_E_TOTAL) - axis == E_AXIS ? X_AXIS : - #endif - axis - ); + const AxisEnum a = TERN(LCD_SHOW_E_TOTAL, axis == E_AXIS ? X_AXIS : axis, axis); const uint8_t offs = (XYZ_SPACING) * a; lcd_put_wchar(X_LABEL_POS + offs, XYZ_BASELINE, axis_codes[axis]); lcd_moveto(X_VALUE_POS + offs, XYZ_BASELINE); @@ -332,11 +389,7 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const void MarlinUI::draw_status_screen() { - static char xstring[5 - #if ENABLED(LCD_SHOW_E_TOTAL) - + 7 - #endif - ], ystring[5], zstring[8]; + static char xstring[TERN(LCD_SHOW_E_TOTAL, 12, 5)], ystring[5], zstring[8]; #if ENABLED(FILAMENT_LCD_DISPLAY) static char wstring[5], mstring[4]; #endif @@ -365,11 +418,7 @@ void MarlinUI::draw_status_screen() { #endif #endif - const bool showxy = (true - #if ENABLED(LCD_SHOW_E_TOTAL) - && !printingIsActive() - #endif - ); + const bool show_e_total = TERN0(LCD_SHOW_E_TOTAL, printingIsActive() || marlin_state == MF_SD_COMPLETE); // At the first page, generate new display values if (first_page) { @@ -378,46 +427,36 @@ void MarlinUI::draw_status_screen() { #if ANIM_HOTEND HOTEND_LOOP() if (thermalManager.isHeatingHotend(e)) SBI(new_bits, HEATBIT_HOTEND + e); #endif - #if ANIM_BED - if (thermalManager.isHeatingBed()) SBI(new_bits, HEATBIT_BED); - #endif + if (TERN0(ANIM_BED, thermalManager.isHeatingBed())) SBI(new_bits, HEATBIT_BED); #if DO_DRAW_CHAMBER && HAS_HEATED_CHAMBER if (thermalManager.isHeatingChamber()) SBI(new_bits, HEATBIT_CHAMBER); #endif - #if ANIM_CUTTER - if (cutter.enabled()) SBI(new_bits, HEATBIT_CUTTER); - #endif + if (TERN0(ANIM_CUTTER, cutter.enabled())) SBI(new_bits, HEATBIT_CUTTER); heat_bits = new_bits; #endif const xyz_pos_t lpos = current_position.asLogical(); strcpy(zstring, ftostr52sp(lpos.z)); - if (showxy) { - strcpy(xstring, ftostr4sign(lpos.x)); - strcpy(ystring, ftostr4sign(lpos.y)); - } - else { + if (show_e_total) { #if ENABLED(LCD_SHOW_E_TOTAL) const uint8_t escale = e_move_accumulator >= 100000.0f ? 10 : 1; // After 100m switch to cm sprintf_P(xstring, PSTR("%ld%cm"), uint32_t(_MAX(e_move_accumulator, 0.0f)) / escale, escale == 10 ? 'c' : 'm'); // 1234567mm #endif } + else { + strcpy(xstring, ftostr4sign(lpos.x)); + strcpy(ystring, ftostr4sign(lpos.y)); + } #if ENABLED(FILAMENT_LCD_DISPLAY) strcpy(wstring, ftostr12ns(filwidth.measured_mm)); - strcpy(mstring, i16tostr3(planner.volumetric_percent(parser.volumetric_enabled))); + strcpy(mstring, i16tostr3rj(planner.volumetric_percent(parser.volumetric_enabled))); #endif // Progress / elapsed / estimation updates and string formatting to avoid float math on each LCD draw #if HAS_PRINT_PROGRESS - const progress_t progress = - #if HAS_PRINT_PROGRESS_PERMYRIAD - get_progress_permyriad() - #else - get_progress_percent() - #endif - ; + const progress_t progress = TERN(HAS_PRINT_PROGRESS_PERMYRIAD, get_progress_permyriad, get_progress_percent)(); duration_t elapsed = print_job_timer.duration(); const uint8_t p = progress & 0xFF, ev = elapsed.value & 0xFF; if (p != lastProgress) { @@ -433,25 +472,19 @@ void MarlinUI::draw_status_screen() { estimation_x_pos = _SD_INFO_X(0); #endif } - else { - strcpy(progress_string, ( - #if ENABLED(PRINT_PROGRESS_SHOW_DECIMALS) - permyriadtostr4(progress) - #else - ui8tostr3(progress / (PROGRESS_SCALE)) - #endif - )); - } + else + strcpy(progress_string, TERN(PRINT_PROGRESS_SHOW_DECIMALS, permyriadtostr4(progress), ui8tostr3rj(progress / (PROGRESS_SCALE)))); + #if BOTH(SHOW_REMAINING_TIME, ROTATE_PROGRESS_DISPLAY) // Tri-state progress display mode progress_x_pos = _SD_INFO_X(strlen(progress_string) + 1); #endif #endif } + constexpr bool can_show_days = DISABLED(DOGM_SD_PERCENT) || ENABLED(ROTATE_PROGRESS_DISPLAY); if (ev != lastElapsed) { lastElapsed = ev; - const bool has_days = (elapsed.value >= 60*60*24L); - const uint8_t len = elapsed.toDigital(elapsed_string, has_days); + const uint8_t len = elapsed.toDigital(elapsed_string, can_show_days && elapsed.value >= 60*60*24L); elapsed_x_pos = _SD_INFO_X(len); #if ENABLED(SHOW_REMAINING_TIME) @@ -468,8 +501,7 @@ void MarlinUI::draw_status_screen() { } else { duration_t estimation = timeval; - const bool has_days = (estimation.value >= 60*60*24L); - const uint8_t len = estimation.toDigital(estimation_string, has_days); + const uint8_t len = estimation.toDigital(estimation_string, can_show_days && estimation.value >= 60*60*24L); estimation_x_pos = _SD_INFO_X(len #if !BOTH(DOGM_SD_PERCENT, ROTATE_PROGRESS_DISPLAY) + 1 @@ -564,27 +596,30 @@ void MarlinUI::draw_status_screen() { if (PAGE_UNDER(6 + 1 + 12 + 1 + 6 + 1)) { // Extruders #if DO_DRAW_HOTENDS - for (uint8_t e = 0; e < MAX_HOTEND_DRAW; ++e) - _draw_hotend_status((heater_ind_t)e, blink); + LOOP_L_N(e, MAX_HOTEND_DRAW) + _draw_hotend_status((heater_id_t)e, blink); #endif // Laser / Spindle #if DO_DRAW_CUTTER - if (cutter.power && PAGE_CONTAINS(STATUS_CUTTER_TEXT_Y - INFO_FONT_ASCENT, STATUS_CUTTER_TEXT_Y - 1)) { - lcd_put_u8str(STATUS_CUTTER_TEXT_X, STATUS_CUTTER_TEXT_Y, i16tostr3(cutter.powerPercent(cutter.power))); - lcd_put_wchar('%'); + if (cutter.isReady && PAGE_CONTAINS(STATUS_CUTTER_TEXT_Y - INFO_FONT_ASCENT, STATUS_CUTTER_TEXT_Y - 1)) { + #if CUTTER_UNIT_IS(PERCENT) + lcd_put_u8str(STATUS_CUTTER_TEXT_X, STATUS_CUTTER_TEXT_Y, cutter_power2str(cutter.unitPower)); + lcd_put_wchar('%'); + #elif CUTTER_UNIT_IS(RPM) + lcd_put_u8str(STATUS_CUTTER_TEXT_X - 2, STATUS_CUTTER_TEXT_Y, ftostr51rj(float(cutter.unitPower) / 1000)); + lcd_put_wchar('K'); + #else + lcd_put_u8str(STATUS_CUTTER_TEXT_X, STATUS_CUTTER_TEXT_Y, cutter_power2str(cutter.unitPower)); + #endif } #endif // Heated Bed - #if DO_DRAW_BED - _draw_bed_status(blink); - #endif + TERN_(DO_DRAW_BED, _draw_bed_status(blink)); // Heated Chamber - #if DO_DRAW_CHAMBER - _draw_chamber_status(); - #endif + TERN_(DO_DRAW_CHAMBER, _draw_chamber_status()); // Fan, if a bitmap was provided #if DO_DRAW_FAN @@ -598,7 +633,7 @@ void MarlinUI::draw_status_screen() { c = '*'; } #endif - lcd_put_u8str(STATUS_FAN_TEXT_X, STATUS_FAN_TEXT_Y, i16tostr3(thermalManager.fanPercent(spd))); + lcd_put_u8str(STATUS_FAN_TEXT_X, STATUS_FAN_TEXT_Y, i16tostr3rj(thermalManager.fanPercent(spd))); lcd_put_wchar(c); } } @@ -626,15 +661,15 @@ void MarlinUI::draw_status_screen() { // Progress bar frame // - if (PAGE_CONTAINS(49, 52)) - u8g.drawFrame(PROGRESS_BAR_X, 49, PROGRESS_BAR_WIDTH, 4); + if (PAGE_CONTAINS(PROGRESS_BAR_Y, PROGRESS_BAR_Y + 3)) + u8g.drawFrame(PROGRESS_BAR_X, PROGRESS_BAR_Y, PROGRESS_BAR_WIDTH, 4); // // Progress bar solid part // - if (PAGE_CONTAINS(50, 51)) // 50-51 (or just 50) - u8g.drawBox(PROGRESS_BAR_X + 1, 50, progress_bar_solid_width, 2); + if (PAGE_CONTAINS(PROGRESS_BAR_Y + 1, PROGRESS_BAR_Y + 2)) + u8g.drawBox(PROGRESS_BAR_X + 1, PROGRESS_BAR_Y + 1, progress_bar_solid_width, 2); if (PAGE_CONTAINS(EXTRAS_BASELINE - INFO_FONT_ASCENT, EXTRAS_BASELINE - 1)) { @@ -652,11 +687,11 @@ void MarlinUI::draw_status_screen() { } } else if (progress_state == 2 && estimation_string[0]) { - lcd_put_u8str(PROGRESS_BAR_X, EXTRAS_BASELINE, "R:"); + lcd_put_u8str_P(PROGRESS_BAR_X, EXTRAS_BASELINE, PSTR("R:")); lcd_put_u8str(estimation_x_pos, EXTRAS_BASELINE, estimation_string); } else if (elapsed_string[0]) { - lcd_put_u8str(PROGRESS_BAR_X, EXTRAS_BASELINE, "E:"); + lcd_put_u8str_P(PROGRESS_BAR_X, EXTRAS_BASELINE, E_LBL); lcd_put_u8str(elapsed_x_pos, EXTRAS_BASELINE, elapsed_string); } @@ -668,7 +703,7 @@ void MarlinUI::draw_status_screen() { #if ENABLED(DOGM_SD_PERCENT) if (progress_string[0]) { - lcd_put_u8str(55, 48, progress_string); // Percent complete + lcd_put_u8str(55, EXTRAS_BASELINE, progress_string); // Percent complete lcd_put_wchar('%'); } #endif @@ -695,7 +730,7 @@ void MarlinUI::draw_status_screen() { // XYZ Coordinates // - #if ENABLED(XYZ_HOLLOW_FRAME) + #if EITHER(XYZ_NO_FRAME, XYZ_HOLLOW_FRAME) #define XYZ_FRAME_TOP 29 #define XYZ_FRAME_HEIGHT INFO_FONT_ASCENT + 3 #else @@ -705,54 +740,56 @@ void MarlinUI::draw_status_screen() { if (PAGE_CONTAINS(XYZ_FRAME_TOP, XYZ_FRAME_TOP + XYZ_FRAME_HEIGHT - 1)) { - #if ENABLED(XYZ_HOLLOW_FRAME) - u8g.drawFrame(0, XYZ_FRAME_TOP, LCD_PIXEL_WIDTH, XYZ_FRAME_HEIGHT); // 8: 29-40 7: 29-39 - #else - u8g.drawBox(0, XYZ_FRAME_TOP, LCD_PIXEL_WIDTH, XYZ_FRAME_HEIGHT); // 8: 30-39 7: 30-37 + #if DISABLED(XYZ_NO_FRAME) + #if ENABLED(XYZ_HOLLOW_FRAME) + u8g.drawFrame(0, XYZ_FRAME_TOP, LCD_PIXEL_WIDTH, XYZ_FRAME_HEIGHT); // 8: 29-40 7: 29-39 + #else + u8g.drawBox(0, XYZ_FRAME_TOP, LCD_PIXEL_WIDTH, XYZ_FRAME_HEIGHT); // 8: 30-39 7: 30-37 + #endif #endif if (PAGE_CONTAINS(XYZ_BASELINE - (INFO_FONT_ASCENT - 1), XYZ_BASELINE)) { - #if DISABLED(XYZ_HOLLOW_FRAME) + #if NONE(XYZ_NO_FRAME, XYZ_HOLLOW_FRAME) u8g.setColorIndex(0); // white on black #endif - #if DUAL_MIXING_EXTRUDER + #if HAS_DUAL_MIXING // Two-component mix / gradient instead of XY - char mixer_messages[12]; - const char *mix_label; + char mixer_messages[15]; + PGM_P mix_label; #if ENABLED(GRADIENT_MIX) if (mixer.gradient.enabled) { mixer.update_mix_from_gradient(); - mix_label = "Gr"; + mix_label = PSTR("Gr"); } else #endif { mixer.update_mix_from_vtool(); - mix_label = "Mx"; + mix_label = PSTR("Mx"); } - sprintf_P(mixer_messages, PSTR("%s %d;%d%% "), mix_label, int(mixer.mix[0]), int(mixer.mix[1])); + sprintf_P(mixer_messages, PSTR(S_FMT " %d;%d%% "), mix_label, int(mixer.mix[0]), int(mixer.mix[1])); lcd_put_u8str(X_LABEL_POS, XYZ_BASELINE, mixer_messages); #else - if (showxy) { - _draw_axis_value(X_AXIS, xstring, blink); - _draw_axis_value(Y_AXIS, ystring, blink); - } - else { + if (show_e_total) { _draw_axis_value(E_AXIS, xstring, true); lcd_put_u8str_P(PSTR(" ")); } + else { + _draw_axis_value(X_AXIS, xstring, blink); + _draw_axis_value(Y_AXIS, ystring, blink); + } #endif _draw_axis_value(Z_AXIS, zstring, blink); - #if DISABLED(XYZ_HOLLOW_FRAME) + #if NONE(XYZ_NO_FRAME, XYZ_HOLLOW_FRAME) u8g.setColorIndex(1); // black on white #endif } @@ -768,7 +805,7 @@ void MarlinUI::draw_status_screen() { lcd_put_wchar(3, EXTRAS_2_BASELINE, LCD_STR_FEEDRATE[0]); set_font(FONT_STATUSMENU); - lcd_put_u8str(12, EXTRAS_2_BASELINE, i16tostr3(feedrate_percentage)); + lcd_put_u8str(12, EXTRAS_2_BASELINE, i16tostr3rj(feedrate_percentage)); lcd_put_wchar('%'); // @@ -800,26 +837,36 @@ void MarlinUI::draw_status_screen() { lcd_put_wchar(':'); lcd_put_u8str(mstring); lcd_put_wchar('%'); + return; } - else #endif - draw_status_message(blink); + + draw_status_message(blink); } } void MarlinUI::draw_status_message(const bool blink) { // Get the UTF8 character count of the string - uint8_t slen = utf8_strlen(status_message); + uint8_t lcd_width = LCD_WIDTH, pixel_width = LCD_PIXEL_WIDTH, + slen = utf8_strlen(status_message); + + #if HAS_POWER_MONITOR + if (power_monitor.display_enabled()) { + // make room at the end of the status line for the power monitor reading + lcd_width -= 6; + pixel_width -= (MENU_FONT_WIDTH) * 6; + } + #endif #if ENABLED(STATUS_MESSAGE_SCROLLING) static bool last_blink = false; - if (slen <= LCD_WIDTH) { + if (slen <= lcd_width) { // The string fits within the line. Print with no scrolling lcd_put_u8str(status_message); - while (slen < LCD_WIDTH) { lcd_put_wchar(' '); ++slen; } + while (slen < lcd_width) { lcd_put_wchar(' '); ++slen; } } else { // String is longer than the available space @@ -828,20 +875,21 @@ void MarlinUI::draw_status_message(const bool blink) { // and the string remaining length uint8_t rlen; const char *stat = status_and_len(rlen); - lcd_put_u8str_max(stat, LCD_PIXEL_WIDTH); + lcd_put_u8str_max(stat, pixel_width); // If the remaining string doesn't completely fill the screen - if (rlen < LCD_WIDTH) { + if (rlen < lcd_width) { lcd_put_wchar('.'); // Always at 1+ spaces left, draw a dot - uint8_t chars = LCD_WIDTH - rlen; // Amount of space left in characters + uint8_t chars = lcd_width - rlen; // Amount of space left in characters if (--chars) { // Draw a second dot if there's space lcd_put_wchar('.'); if (--chars) { // Print a second copy of the message - lcd_put_u8str_max(status_message, LCD_PIXEL_WIDTH - (rlen + 2) * (MENU_FONT_WIDTH)); + lcd_put_u8str_max(status_message, pixel_width - (rlen + 2) * (MENU_FONT_WIDTH)); lcd_put_wchar(' '); } } } + if (last_blink != blink) { last_blink = blink; advance_status_scroll(); @@ -853,12 +901,16 @@ void MarlinUI::draw_status_message(const bool blink) { UNUSED(blink); // Just print the string to the LCD - lcd_put_u8str_max(status_message, LCD_PIXEL_WIDTH); + lcd_put_u8str_max(status_message, pixel_width); // Fill the rest with spaces - for (; slen < LCD_WIDTH; ++slen) lcd_put_wchar(' '); + for (; slen < lcd_width; ++slen) lcd_put_wchar(' '); #endif // !STATUS_MESSAGE_SCROLLING + + #if HAS_POWER_MONITOR + display_power_monitor(pixel_width + MENU_FONT_WIDTH, STATUS_BASELINE); + #endif } -#endif // HAS_GRAPHICAL_LCD && !LIGHTWEIGHT_UI +#endif // HAS_MARLINUI_U8GLIB && !LIGHTWEIGHT_UI diff --git a/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp b/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp index f5931917ae08..806f370db327 100644 --- a/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp +++ b/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp @@ -11,7 +11,6 @@ * any later version. The code is distributed WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU GPL for more details. - * */ /** @@ -209,7 +208,7 @@ void ST7920_Lite_Status_Screen::clear_ddram() { /* This fills the entire graphics buffer with zeros */ void ST7920_Lite_Status_Screen::clear_gdram() { - for (uint8_t y = 0; y < BUFFER_HEIGHT; y++) { + LOOP_L_N(y, BUFFER_HEIGHT) { set_gdram_address(0, y); begin_data(); for (uint8_t i = (BUFFER_WIDTH) / 16; i--;) write_word(0); @@ -407,7 +406,7 @@ void ST7920_Lite_Status_Screen::draw_degree_symbol(uint8_t x, uint8_t y, const b const uint8_t x_word = x >> 1, y_top = degree_symbol_y_top, y_bot = y_top + COUNT(degree_symbol); - for (uint8_t i = y_top; i < y_bot; i++) { + LOOP_S_L_N(i, y_top, y_bot) { uint8_t byte = pgm_read_byte(p_bytes++); set_gdram_address(x_word, i + y * 16); begin_data(); @@ -431,7 +430,7 @@ void ST7920_Lite_Status_Screen::draw_static_elements() { // Draw the static icons in GDRAM draw_gdram_icon(0, 0, nozzle_icon); - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND draw_gdram_icon(0, 1, nozzle_icon); draw_gdram_icon(0, 2, bed_icon); #else @@ -467,10 +466,10 @@ void ST7920_Lite_Status_Screen::draw_progress_bar(const uint8_t value) { const uint8_t char_pcnt = 100 / width; // How many percent does each 16-bit word represent? // Draw the progress bar as a bitmap in CGRAM - for (uint8_t y = top; y <= bottom; y++) { + LOOP_S_LE_N(y, top, bottom) { set_gdram_address(left, y); begin_data(); - for (uint8_t x = 0; x < width; x++) { + LOOP_L_N(x, width) { uint16_t gfx_word = 0x0000; if ((x + 1) * char_pcnt <= value) gfx_word = 0xFFFF; // Draw completely filled bytes @@ -537,14 +536,9 @@ void ST7920_Lite_Status_Screen::draw_heat_icon(const bool whichIcon, const bool static struct { bool E1_show_target : 1; bool E2_show_target : 1; - #if HAS_HEATED_BED - bool bed_show_target : 1; - #endif + TERN_(HAS_HEATED_BED, bool bed_show_target : 1); } display_state = { - true, true - #if HAS_HEATED_BED - , true - #endif + true, true, TERN_(HAS_HEATED_BED, true) }; void ST7920_Lite_Status_Screen::draw_temps(uint8_t line, const int16_t temp, const int16_t target, bool showTarget, bool targetStateChange) { @@ -584,7 +578,7 @@ void ST7920_Lite_Status_Screen::draw_extruder_2_temp(const int16_t temp, const i #if HAS_HEATED_BED void ST7920_Lite_Status_Screen::draw_bed_temp(const int16_t temp, const int16_t target, bool forceUpdate) { const bool show_target = target && FAR(temp, target); - draw_temps(HOTENDS > 1 ? 2 : 1, temp, target, show_target, display_state.bed_show_target != show_target || forceUpdate); + draw_temps(TERN(HAS_MULTI_HOTEND, 2, 1), temp, target, show_target, display_state.bed_show_target != show_target || forceUpdate); display_state.bed_show_target = show_target; } #endif @@ -596,16 +590,17 @@ void ST7920_Lite_Status_Screen::draw_fan_speed(const uint8_t value) { write_byte('%'); } -void ST7920_Lite_Status_Screen::draw_print_time(const duration_t &elapsed) { +void ST7920_Lite_Status_Screen::draw_print_time(const duration_t &elapsed, char suffix) { #if HOTENDS == 1 set_ddram_address(DDRAM_LINE_3); #else set_ddram_address(DDRAM_LINE_3 + 5); #endif char str[7]; - str[elapsed.toDigital(str)] = ' '; + int str_length = elapsed.toDigital(str); + str[str_length++] = suffix; begin_data(); - write_str(str, 6); + write_str(str, str_length); } void ST7920_Lite_Status_Screen::draw_feedrate_percentage(const uint16_t percentage) { @@ -672,11 +667,7 @@ void ST7920_Lite_Status_Screen::draw_position(const xyze_pos_t &pos, const bool // If position is unknown, flash the labels. const unsigned char alt_label = position_known ? 0 : (ui.get_blink() ? ' ' : 0); - if (true - #if ENABLED(LCD_SHOW_E_TOTAL) - && !printingIsActive() - #endif - ) { + if (TERN1(LCD_SHOW_E_TOTAL, !printingIsActive())) { write_byte(alt_label ? alt_label : 'X'); write_str(dtostrf(pos.x, -4, 0, str), 4); @@ -704,7 +695,7 @@ bool ST7920_Lite_Status_Screen::indicators_changed() { const uint16_t feedrate_perc = feedrate_percentage; const uint16_t fs = thermalManager.scaledFanSpeed(0); const int16_t extruder_1_target = thermalManager.degTargetHotend(0); - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND const int16_t extruder_2_target = thermalManager.degTargetHotend(1); #endif #if HAS_HEATED_BED @@ -712,13 +703,8 @@ bool ST7920_Lite_Status_Screen::indicators_changed() { #endif static uint16_t last_checksum = 0; const uint16_t checksum = blink ^ feedrate_perc ^ fs ^ extruder_1_target - #if HOTENDS > 1 - ^ extruder_2_target - #endif - #if HAS_HEATED_BED - ^ bed_target - #endif - ; + ^ TERN0(HAS_MULTI_HOTEND, extruder_2_target) + ^ TERN0(HAS_HEATED_BED, bed_target); if (last_checksum == checksum) return false; last_checksum = checksum; return true; @@ -728,10 +714,11 @@ void ST7920_Lite_Status_Screen::update_indicators(const bool forceUpdate) { if (forceUpdate || indicators_changed()) { const bool blink = ui.get_blink(); const duration_t elapsed = print_job_timer.duration(); + duration_t remaining = TERN0(USE_M73_REMAINING_TIME, ui.get_remaining_time()); const uint16_t feedrate_perc = feedrate_percentage; const int16_t extruder_1_temp = thermalManager.degHotend(0), extruder_1_target = thermalManager.degTargetHotend(0); - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND const int16_t extruder_2_temp = thermalManager.degHotend(1), extruder_2_target = thermalManager.degTargetHotend(1); #endif @@ -741,12 +728,8 @@ void ST7920_Lite_Status_Screen::update_indicators(const bool forceUpdate) { #endif draw_extruder_1_temp(extruder_1_temp, extruder_1_target, forceUpdate); - #if HOTENDS > 1 - draw_extruder_2_temp(extruder_2_temp, extruder_2_target, forceUpdate); - #endif - #if HAS_HEATED_BED - draw_bed_temp(bed_temp, bed_target, forceUpdate); - #endif + TERN_(HAS_MULTI_HOTEND, draw_extruder_2_temp(extruder_2_temp, extruder_2_target, forceUpdate)); + TERN_(HAS_HEATED_BED, draw_bed_temp(bed_temp, bed_target, forceUpdate)); uint16_t spd = thermalManager.fan_speed[0]; @@ -756,14 +739,24 @@ void ST7920_Lite_Status_Screen::update_indicators(const bool forceUpdate) { #endif draw_fan_speed(thermalManager.fanPercent(spd)); - draw_print_time(elapsed); + + // Draw elapsed/remaining time + const bool show_remaining = ENABLED(SHOW_REMAINING_TIME) && (DISABLED(ROTATE_PROGRESS_DISPLAY) || blink); + if (show_remaining && !remaining.second()) { + const auto progress = ui.get_progress_percent(); + if (progress) + remaining = elapsed.second() * (100 - progress) / progress; + } + if (show_remaining && remaining.second()) + draw_print_time(remaining, 'R'); + else + draw_print_time(elapsed); + draw_feedrate_percentage(feedrate_perc); // Update the fan and bed animations if (spd) draw_fan_icon(blink); - #if HAS_HEATED_BED - draw_heat_icon(bed_target > 0 && blink, bed_target > 0); - #endif + TERN_(HAS_HEATED_BED, draw_heat_icon(bed_target > 0 && blink, bed_target > 0)); } } @@ -813,9 +806,7 @@ void ST7920_Lite_Status_Screen::update_status_or_position(bool forceUpdate) { * If STATUS_EXPIRE_SECONDS is zero, only the status is shown. */ if (forceUpdate || status_changed()) { - #if ENABLED(STATUS_MESSAGE_SCROLLING) - ui.status_scroll_offset = 0; - #endif + TERN_(STATUS_MESSAGE_SCROLLING, ui.status_scroll_offset = 0); #if STATUS_EXPIRE_SECONDS countdown = ui.status_message[0] ? STATUS_EXPIRE_SECONDS : 0; #endif @@ -823,40 +814,26 @@ void ST7920_Lite_Status_Screen::update_status_or_position(bool forceUpdate) { blink_changed(); // Clear changed flag } #if !STATUS_EXPIRE_SECONDS - #if ENABLED(STATUS_MESSAGE_SCROLLING) - else if (blink_changed()) - draw_status_message(); - #endif + else if (TERN0(STATUS_MESSAGE_SCROLLING, blink_changed())) + draw_status_message(); #else else if (blink_changed()) { if (countdown > 1) { countdown--; - #if ENABLED(STATUS_MESSAGE_SCROLLING) - draw_status_message(); - #endif + TERN_(STATUS_MESSAGE_SCROLLING, draw_status_message()); } else if (countdown > 0) { if (position_changed()) { countdown--; forceUpdate = true; } - #if ENABLED(STATUS_MESSAGE_SCROLLING) - draw_status_message(); - #endif + TERN_(STATUS_MESSAGE_SCROLLING, draw_status_message()); } } if (countdown == 0 && (forceUpdate || position_changed() - #if DISABLED(DISABLE_REDUCED_ACCURACY_WARNING) - || blink_changed() - #endif - )) { - draw_position(current_position, true - #if DISABLED(DISABLE_REDUCED_ACCURACY_WARNING) - && all_axes_known() - #endif - ); - } + || TERN(DISABLE_REDUCED_ACCURACY_WARNING, 0, blink_changed()) + )) draw_position(current_position, TERN(DISABLE_REDUCED_ACCURACY_WARNING, 1, all_axes_known())); #endif } diff --git a/Marlin/src/lcd/dogm/status_screen_lite_ST7920.h b/Marlin/src/lcd/dogm/status_screen_lite_ST7920.h index bc18c43f107f..b21724648484 100644 --- a/Marlin/src/lcd/dogm/status_screen_lite_ST7920.h +++ b/Marlin/src/lcd/dogm/status_screen_lite_ST7920.h @@ -11,7 +11,6 @@ * any later version. The code is distributed WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU GPL for more details. - * */ #pragma once @@ -80,14 +79,14 @@ class ST7920_Lite_Status_Screen { static void draw_fan_icon(const bool whichIcon); static void draw_heat_icon(const bool whichIcon, const bool heating); static void draw_temps(uint8_t line, const int16_t temp, const int16_t target, bool showTarget, bool targetStateChange); - static void draw_extruder_1_temp(const int16_t temp, const int16_t target, bool forceUpdate = false); - static void draw_extruder_2_temp(const int16_t temp, const int16_t target, bool forceUpdate = false); - static void draw_bed_temp(const int16_t temp, const int16_t target, bool forceUpdate = false); + static void draw_extruder_1_temp(const int16_t temp, const int16_t target, bool forceUpdate=false); + static void draw_extruder_2_temp(const int16_t temp, const int16_t target, bool forceUpdate=false); + static void draw_bed_temp(const int16_t temp, const int16_t target, bool forceUpdate=false); static void draw_fan_speed(const uint8_t value); - static void draw_print_time(const duration_t &elapsed); + static void draw_print_time(const duration_t &elapsed, char suffix=' '); static void draw_feedrate_percentage(const uint16_t percentage); static void draw_status_message(); - static void draw_position(const xyze_pos_t &pos, bool position_known = true); + static void draw_position(const xyze_pos_t &pos, bool position_known=true); static bool indicators_changed(); static bool position_changed(); diff --git a/Marlin/src/lcd/dogm/u8g_dev_ssd1306_sh1106_128x64_I2C.cpp b/Marlin/src/lcd/dogm/u8g_dev_ssd1306_sh1106_128x64_I2C.cpp index 1854ac1c674e..f97a323350ee 100644 --- a/Marlin/src/lcd/dogm/u8g_dev_ssd1306_sh1106_128x64_I2C.cpp +++ b/Marlin/src/lcd/dogm/u8g_dev_ssd1306_sh1106_128x64_I2C.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -67,7 +67,7 @@ #include "../../inc/MarlinConfigPre.h" -#if HAS_GRAPHICAL_LCD +#if HAS_MARLINUI_U8GLIB #include "HAL_LCD_com_defines.h" @@ -300,4 +300,4 @@ uint8_t u8g_WriteEscSeqP_2_wire(u8g_t *u8g, u8g_dev_t *dev, const uint8_t *esc_s return 1; } -#endif // HAS_GRAPHICAL_LCD +#endif // HAS_MARLINUI_U8GLIB diff --git a/Marlin/src/lcd/dogm/u8g_dev_st7565_64128n_HAL.cpp b/Marlin/src/lcd/dogm/u8g_dev_st7565_64128n_HAL.cpp index 1542d9db0dca..84c10dbb4d2e 100644 --- a/Marlin/src/lcd/dogm/u8g_dev_st7565_64128n_HAL.cpp +++ b/Marlin/src/lcd/dogm/u8g_dev_st7565_64128n_HAL.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -55,7 +55,7 @@ #include "../../inc/MarlinConfig.h" -#if HAS_GRAPHICAL_LCD +#if HAS_MARLINUI_U8GLIB #include #include "HAL_LCD_com_defines.h" @@ -233,4 +233,4 @@ u8g_dev_t u8g_dev_st7565_64128n_HAL_2x_sw_spi = { u8g_dev_st7565_64128n_HAL_2x_f U8G_PB_DEV(u8g_dev_st7565_64128n_HAL_hw_spi, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_st7565_64128n_HAL_fn, U8G_COM_HAL_HW_SPI_FN); u8g_dev_t u8g_dev_st7565_64128n_HAL_2x_hw_spi = { u8g_dev_st7565_64128n_HAL_2x_fn, &u8g_dev_st7565_64128n_HAL_2x_pb, U8G_COM_HAL_HW_SPI_FN }; -#endif // HAS_GRAPHICAL_LCD +#endif // HAS_MARLINUI_U8GLIB diff --git a/Marlin/src/lcd/dogm/u8g_dev_st7920_128x64_HAL.cpp b/Marlin/src/lcd/dogm/u8g_dev_st7920_128x64_HAL.cpp index b6449bd4ae90..740436d93c07 100644 --- a/Marlin/src/lcd/dogm/u8g_dev_st7920_128x64_HAL.cpp +++ b/Marlin/src/lcd/dogm/u8g_dev_st7920_128x64_HAL.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -55,7 +55,7 @@ #include "../../inc/MarlinConfigPre.h" -#if HAS_GRAPHICAL_LCD +#if HAS_MARLINUI_U8GLIB #include "HAL_LCD_com_defines.h" @@ -87,11 +87,11 @@ void clear_graphics_DRAM(u8g_t *u8g, u8g_dev_t *dev) { u8g_SetAddress(u8g, dev, 0); // cmd mode u8g_WriteByte(u8g, dev, 0x08); //display off, cursor+blink off u8g_WriteByte(u8g, dev, 0x3E); //extended mode + GDRAM active - for (uint8_t y = 0; y < (LCD_PIXEL_HEIGHT) / 2; y++) { //clear GDRAM + LOOP_L_N(y, (LCD_PIXEL_HEIGHT) / 2) { //clear GDRAM u8g_WriteByte(u8g, dev, 0x80 | y); //set y u8g_WriteByte(u8g, dev, 0x80); //set x = 0 u8g_SetAddress(u8g, dev, 1); /* data mode */ - for (uint8_t i = 0; i < 2 * (LCD_PIXEL_WIDTH) / 8; i++) //2x width clears both segments + LOOP_L_N(i, 2 * (LCD_PIXEL_WIDTH) / 8) //2x width clears both segments u8g_WriteByte(u8g, dev, 0); u8g_SetAddress(u8g, dev, 0); /* cmd mode */ } @@ -205,4 +205,4 @@ u8g_dev_t u8g_dev_st7920_128x64_HAL_4x_hw_spi = { u8g_dev_st7920_128x64_HAL_4x_f u8g_dev_t u8g_dev_st7920_128x64_rrd_sw_spi = { u8g_dev_st7920_128x64_HAL_4x_fn, &u8g_dev_st7920_128x64_HAL_4x_pb, U8G_COM_ST7920_HAL_SW_SPI }; #endif -#endif // HAS_GRAPHICAL_LCD +#endif // HAS_MARLINUI_U8GLIB diff --git a/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp b/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp deleted file mode 100644 index fcfebcbe1288..000000000000 --- a/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp +++ /dev/null @@ -1,718 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/* - - u8g_dev_tft_320x240_upscale_from_128x64.cpp - - Universal 8bit Graphics Library - - Copyright (c) 2011, olikraus@gmail.com - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or other - materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#include "../../inc/MarlinConfig.h" - -#if HAS_GRAPHICAL_LCD && PIN_EXISTS(FSMC_CS) - -#include "HAL_LCD_com_defines.h" -#include "ultralcd_DOGM.h" - -#include - -#if ENABLED(LCD_USE_DMA_FSMC) - extern void LCD_IO_WriteReg(uint16_t Reg); - extern void LCD_IO_WriteData(uint16_t RegValue); - extern void LCD_IO_WriteSequence(uint16_t *data, uint16_t length); - extern void LCD_IO_WriteSequence_Async(uint16_t *data, uint16_t length); - extern void LCD_IO_WaitSequence_Async(); - extern void LCD_IO_WriteMultiple(uint16_t color, uint32_t count); -#endif - -#define WIDTH LCD_PIXEL_WIDTH -#define HEIGHT LCD_PIXEL_HEIGHT -#define PAGE_HEIGHT 8 - -#define X_LO LCD_PIXEL_OFFSET_X -#define Y_LO LCD_PIXEL_OFFSET_Y -#define X_HI (X_LO + 2 * WIDTH - 1) -#define Y_HI (Y_LO + 2 * HEIGHT - 1) - -// see https://ee-programming-notepad.blogspot.com/2016/10/16-bit-color-generator-picker.html - -#define COLOR_BLACK 0x0000 // #000000 -#define COLOR_WHITE 0xFFFF // #FFFFFF -#define COLOR_SILVER 0xC618 // #C0C0C0 -#define COLOR_GREY 0x7BEF // #808080 -#define COLOR_DARKGREY 0x4208 // #404040 -#define COLOR_DARKGREY2 0x39E7 // #303030 -#define COLOR_DARK 0x0003 // Some dark color - -#define COLOR_RED 0xF800 // #FF0000 -#define COLOR_LIME 0x7E00 // #00FF00 -#define COLOR_BLUE 0x001F // #0000FF -#define COLOR_YELLOW 0xFFE0 // #FFFF00 -#define COLOR_MAGENTA 0xF81F // #FF00FF -#define COLOR_FUCHSIA 0xF81F // #FF00FF -#define COLOR_CYAN 0x07FF // #00FFFF -#define COLOR_AQUA 0x07FF // #00FFFF - -#define COLOR_MAROON 0x7800 // #800000 -#define COLOR_GREEN 0x03E0 // #008000 -#define COLOR_NAVY 0x000F // #000080 -#define COLOR_OLIVE 0x8400 // #808000 -#define COLOR_PURPLE 0x8010 // #800080 -#define COLOR_TEAL 0x0410 // #008080 - -#define COLOR_ORANGE 0xFC00 // #FF7F00 - -#ifndef TFT_MARLINUI_COLOR - #define TFT_MARLINUI_COLOR COLOR_WHITE -#endif -#ifndef TFT_MARLINBG_COLOR - #define TFT_MARLINBG_COLOR COLOR_BLACK -#endif -#ifndef TFT_DISABLED_COLOR - #define TFT_DISABLED_COLOR COLOR_DARK -#endif -#ifndef TFT_BTCANCEL_COLOR - #define TFT_BTCANCEL_COLOR COLOR_RED -#endif -#ifndef TFT_BTARROWS_COLOR - #define TFT_BTARROWS_COLOR COLOR_BLUE -#endif -#ifndef TFT_BTOKMENU_COLOR - #define TFT_BTOKMENU_COLOR COLOR_RED -#endif - -static uint32_t lcd_id = 0; - -#define ST7789V_CASET 0x2A /* Column address register */ -#define ST7789V_RASET 0x2B /* Row address register */ -#define ST7789V_WRITE_RAM 0x2C /* Write data to GRAM */ - - -/* Mind the mess: with landscape screen orientation 'Horizontal' is Y and 'Vertical' is X */ -#define ILI9328_HASET 0x20 /* Horizontal GRAM address register (0-255) */ -#define ILI9328_VASET 0x21 /* Vertical GRAM address register (0-511)*/ -#define ILI9328_WRITE_RAM 0x22 /* Write data to GRAM */ - -#define ILI9328_HASTART 0x50 /* Horizontal address start position (0-255) */ -#define ILI9328_HAEND 0x51 /* Horizontal address end position (0-255) */ -#define ILI9328_VASTART 0x52 /* Vertical address start position (0-511) */ -#define ILI9328_VAEND 0x53 /* Vertical address end position (0-511) */ - - -static void setWindow_ili9328(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) { - #ifdef LCD_USE_DMA_FSMC - LCD_IO_WriteReg(ILI9328_HASTART); - LCD_IO_WriteData(Ymin); - LCD_IO_WriteReg(ILI9328_HAEND); - LCD_IO_WriteData(Ymax); - LCD_IO_WriteReg(ILI9328_VASTART); - LCD_IO_WriteData(Xmin); - LCD_IO_WriteReg(ILI9328_VAEND); - LCD_IO_WriteData(Xmax); - - LCD_IO_WriteReg(ILI9328_HASET); - LCD_IO_WriteData(Ymin); - LCD_IO_WriteReg(ILI9328_VASET); - LCD_IO_WriteData(Xmin); - - LCD_IO_WriteReg(ILI9328_WRITE_RAM); - #else - u8g_SetAddress(u8g, dev, 0); - - u8g_WriteByte(u8g, dev, ILI9328_HASTART); - u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Ymin); - u8g_WriteByte(u8g, dev, ILI9328_HAEND); - u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Ymax); - u8g_WriteByte(u8g, dev, ILI9328_VASTART); - u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Xmin); - u8g_WriteByte(u8g, dev, ILI9328_VAEND); - u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Xmax); - - u8g_WriteByte(u8g, dev, ILI9328_HASET); - u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Ymin); - u8g_WriteByte(u8g, dev, ILI9328_VASET); - u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Xmin); - - u8g_WriteByte(u8g, dev, ILI9328_WRITE_RAM); - u8g_SetAddress(u8g, dev, 1); - #endif -} - -static void setWindow_st7789v(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) { - #ifdef LCD_USE_DMA_FSMC - LCD_IO_WriteReg(ST7789V_CASET); - LCD_IO_WriteData((Xmin >> 8) & 0xFF); - LCD_IO_WriteData(Xmin & 0xFF); - LCD_IO_WriteData((Xmax >> 8) & 0xFF); - LCD_IO_WriteData(Xmax & 0xFF); - - LCD_IO_WriteReg(ST7789V_RASET); - LCD_IO_WriteData((Ymin >> 8) & 0xFF); - LCD_IO_WriteData(Ymin & 0xFF); - LCD_IO_WriteData((Ymax >> 8) & 0xFF); - LCD_IO_WriteData(Ymax & 0xFF); - - LCD_IO_WriteReg(ST7789V_WRITE_RAM); - #else - u8g_SetAddress(u8g, dev, 0); u8g_WriteByte(u8g, dev, ST7789V_CASET); u8g_SetAddress(u8g, dev, 1); - u8g_WriteByte(u8g, dev, (Xmin >> 8) & 0xFF); - u8g_WriteByte(u8g, dev, Xmin & 0xFF); - u8g_WriteByte(u8g, dev, (Xmax >> 8) & 0xFF); - u8g_WriteByte(u8g, dev, Xmax & 0xFF); - - u8g_SetAddress(u8g, dev, 0); u8g_WriteByte(u8g, dev, ST7789V_RASET); u8g_SetAddress(u8g, dev, 1); - u8g_WriteByte(u8g, dev, (Ymin >> 8) & 0xFF); - u8g_WriteByte(u8g, dev, Ymin & 0xFF); - u8g_WriteByte(u8g, dev, (Ymax >> 8) & 0xFF); - u8g_WriteByte(u8g, dev, Ymax & 0xFF); - - u8g_SetAddress(u8g, dev, 0); u8g_WriteByte(u8g, dev, ST7789V_WRITE_RAM); u8g_SetAddress(u8g, dev, 1); - #endif -} - -static void setWindow_none(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) {} -void (*setWindow)(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) = setWindow_none; - - -#define ESC_REG(x) 0xFFFF, 0x00FF & (uint16_t)x -#define ESC_DELAY(x) 0xFFFF, 0x8000 | (x & 0x7FFF) -#define ESC_END 0xFFFF, 0x7FFF -#define ESC_FFFF 0xFFFF, 0xFFFF - -#ifdef LCD_USE_DMA_FSMC - void writeEscSequence(const uint16_t *sequence) { - uint16_t data; - for (;;) { - data = *sequence++; - if (data != 0xFFFF) { - LCD_IO_WriteData(data); - continue; - } - data = *sequence++; - if (data == 0x7FFF) return; - if (data == 0xFFFF) { - LCD_IO_WriteData(data); - } else if (data & 0x8000) { - delay(data & 0x7FFF); - } else if ((data & 0xFF00) == 0) { - LCD_IO_WriteReg(data); - } - } - } -#else - void writeEscSequence8(u8g_t *u8g, u8g_dev_t *dev, const uint16_t *sequence) { - uint16_t data; - u8g_SetAddress(u8g, dev, 1); - for (;;) { - data = *sequence++; - if (data != 0xFFFF) { - u8g_WriteByte(u8g, dev, data & 0xFF); - continue; - } - data = *sequence++; - if (data == 0x7FFF) return; - if (data == 0xFFFF) { - u8g_WriteByte(u8g, dev, data & 0xFF); - } else if (data & 0x8000) { - delay(data & 0x7FFF); - } else if ((data & 0xFF00) == 0) { - u8g_SetAddress(u8g, dev, 0); - u8g_WriteByte(u8g, dev, data & 0xFF); - u8g_SetAddress(u8g, dev, 1); - } - } - } - - void writeEscSequence16(u8g_t *u8g, u8g_dev_t *dev, const uint16_t *sequence) { - uint16_t data; - u8g_SetAddress(u8g, dev, 0); - for (;;) { - data = *sequence++; - if (data != 0xFFFF) { - u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&data); - continue; - } - data = *sequence++; - if (data == 0x7FFF) return; - if (data == 0xFFFF) { - u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&data); - } else if (data & 0x8000) { - delay(data & 0x7FFF); - } else if ((data & 0xFF00) == 0) { - u8g_WriteByte(u8g, dev, data & 0xFF); - } - } - u8g_SetAddress(u8g, dev, 1); - } -#endif - -static const uint16_t st7789v_init[] = { - ESC_REG(0x0010), ESC_DELAY(10), - ESC_REG(0x0001), ESC_DELAY(200), - ESC_REG(0x0011), ESC_DELAY(120), - ESC_REG(0x0036), 0x00A0, - ESC_REG(0x003A), 0x0055, - ESC_REG(0x002A), 0x0000, 0x0000, 0x0001, 0x003F, - ESC_REG(0x002B), 0x0000, 0x0000, 0x0000, 0x00EF, - ESC_REG(0x00B2), 0x000C, 0x000C, 0x0000, 0x0033, 0x0033, - ESC_REG(0x00B7), 0x0035, - ESC_REG(0x00BB), 0x001F, - ESC_REG(0x00C0), 0x002C, - ESC_REG(0x00C2), 0x0001, 0x00C3, - ESC_REG(0x00C4), 0x0020, - ESC_REG(0x00C6), 0x000F, - ESC_REG(0x00D0), 0x00A4, 0x00A1, - ESC_REG(0x0029), - ESC_REG(0x0011), - ESC_END -}; - -static const uint16_t ili9328_init[] = { - ESC_REG(0x0001), 0x0100, - ESC_REG(0x0002), 0x0400, - ESC_REG(0x0003), 0x1038, - ESC_REG(0x0004), 0x0000, - ESC_REG(0x0008), 0x0202, - ESC_REG(0x0009), 0x0000, - ESC_REG(0x000A), 0x0000, - ESC_REG(0x000C), 0x0000, - ESC_REG(0x000D), 0x0000, - ESC_REG(0x000F), 0x0000, - ESC_REG(0x0010), 0x0000, - ESC_REG(0x0011), 0x0007, - ESC_REG(0x0012), 0x0000, - ESC_REG(0x0013), 0x0000, - ESC_REG(0x0007), 0x0001, - ESC_DELAY(200), - ESC_REG(0x0010), 0x1690, - ESC_REG(0x0011), 0x0227, - ESC_DELAY(50), - ESC_REG(0x0012), 0x008C, - ESC_DELAY(50), - ESC_REG(0x0013), 0x1500, - ESC_REG(0x0029), 0x0004, - ESC_REG(0x002B), 0x000D, - ESC_DELAY(50), - ESC_REG(0x0050), 0x0000, - ESC_REG(0x0051), 0x00EF, - ESC_REG(0x0052), 0x0000, - ESC_REG(0x0053), 0x013F, - ESC_REG(0x0020), 0x0000, - ESC_REG(0x0021), 0x0000, - ESC_REG(0x0060), 0x2700, - ESC_REG(0x0061), 0x0001, - ESC_REG(0x006A), 0x0000, - ESC_REG(0x0080), 0x0000, - ESC_REG(0x0081), 0x0000, - ESC_REG(0x0082), 0x0000, - ESC_REG(0x0083), 0x0000, - ESC_REG(0x0084), 0x0000, - ESC_REG(0x0085), 0x0000, - ESC_REG(0x0090), 0x0010, - ESC_REG(0x0092), 0x0600, - ESC_REG(0x0007), 0x0133, - ESC_REG(0x0022), - ESC_END -}; - -static const uint16_t ili9341_init[] = { - ESC_REG(0x0010), ESC_DELAY(10), - ESC_REG(0x0001), ESC_DELAY(200), - ESC_REG(0x0036), 0x00E8, - ESC_REG(0x003A), 0x0055, - ESC_REG(0x002A), 0x0000, 0x0000, 0x0001, 0x003F, - ESC_REG(0x002B), 0x0000, 0x0000, 0x0000, 0x00EF, - ESC_REG(0x00C5), 0x003E, 0x0028, - ESC_REG(0x00C7), 0x0086, - ESC_REG(0x00B1), 0x0000, 0x0018, - ESC_REG(0x00C0), 0x0023, - ESC_REG(0x00C1), 0x0010, - ESC_REG(0x0029), - ESC_REG(0x0011), - ESC_DELAY(100), - ESC_END -}; - -#if ENABLED(TOUCH_BUTTONS) - - static const uint8_t buttonD[] = { - B01111111,B11111111,B11111111,B11111110, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00011000,B00110000,B00000001, - B10000000,B00001100,B01100000,B00000001, - B10000000,B00000110,B11000000,B00000001, - B10000000,B00000011,B10000000,B00000001, - B10000000,B00000011,B10000000,B00000001, - B10000000,B00000110,B11000000,B00000001, - B10000000,B00001100,B01100000,B00000001, - B10000000,B00011000,B00110000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B01111111,B11111111,B11111111,B11111110, - }; - - #if ENABLED(REVERSE_MENU_DIRECTION) - - static const uint8_t buttonA[] = { - B01111111,B11111111,B11111111,B11111110, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B11100000,B00000000,B00000001, - B10000000,B11100000,B00000000,B00000001, - B10000000,B11100000,B00000000,B00000001, - B10000000,B11100000,B00000000,B00000001, - B10000000,B11100000,B00111111,B11100001, - B10000111,B11111100,B00111111,B11100001, - B10000011,B11111000,B00000000,B00000001, - B10000001,B11110000,B00000000,B00000001, - B10000000,B11100000,B00000000,B00000001, - B10000000,B01000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B01111111,B11111111,B11111111,B11111110, - }; - static const uint8_t buttonB[] = { - B01111111,B11111111,B11111111,B11111110, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B01100000,B00000010,B00000001, - B10000000,B01100000,B00000111,B00000001, - B10000000,B01100000,B00001111,B10000001, - B10000000,B01100000,B00011111,B11000001, - B10000111,B11111110,B00111111,B11100001, - B10000111,B11111110,B00000111,B00000001, - B10000000,B01100000,B00000111,B00000001, - B10000000,B01100000,B00000111,B00000001, - B10000000,B01100000,B00000111,B00000001, - B10000000,B01100000,B00000111,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B01111111,B11111111,B11111111,B11111110, - }; - - #else - - static const uint8_t buttonA[] = { - B01111111,B11111111,B11111111,B11111110, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B01000000,B00000000,B00000001, - B10000000,B11100000,B00000000,B00000001, - B10000001,B11110000,B00000000,B00000001, - B10000011,B11111000,B00000000,B00000001, - B10000111,B11111100,B00111111,B11100001, - B10000000,B11100000,B00111111,B11100001, - B10000000,B11100000,B00000000,B00000001, - B10000000,B11100000,B00000000,B00000001, - B10000000,B11100000,B00000000,B00000001, - B10000000,B11100000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B01111111,B11111111,B11111111,B11111110, - }; - - static const uint8_t buttonB[] = { - B01111111,B11111111,B11111111,B11111110, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B01100000,B00000111,B00000001, - B10000000,B01100000,B00000111,B00000001, - B10000000,B01100000,B00000111,B00000001, - B10000000,B01100000,B00000111,B00000001, - B10000111,B11111110,B00000111,B00000001, - B10000111,B11111110,B00111111,B11100001, - B10000000,B01100000,B00011111,B11000001, - B10000000,B01100000,B00001111,B10000001, - B10000000,B01100000,B00000111,B00000001, - B10000000,B01100000,B00000010,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B01111111,B11111111,B11111111,B11111110, - }; - - #endif - - static const uint8_t buttonC[] = { - B01111111,B11111111,B11111111,B11111110, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00011100,B00000001, - B10000000,B00000100,B00011100,B00000001, - B10000000,B00001100,B00011100,B00000001, - B10000000,B00011111,B11111100,B00000001, - B10000000,B00111111,B11111100,B00000001, - B10000000,B00011111,B11111100,B00000001, - B10000000,B00001100,B00000000,B00000001, - B10000000,B00000100,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B10000000,B00000000,B00000000,B00000001, - B01111111,B11111111,B11111111,B11111110, - }; - - void drawImage(const uint8_t *data, u8g_t *u8g, u8g_dev_t *dev, uint16_t length, uint16_t height, uint16_t color) { - uint16_t buffer[128]; - - for (uint16_t i = 0; i < height; i++) { - uint16_t k = 0; - for (uint16_t j = 0; j < length; j++) { - uint16_t v = TFT_MARLINBG_COLOR; - if (*(data + (i * (length >> 3) + (j >> 3))) & (0x80 >> (j & 7))) - v = color; - else - v = TFT_MARLINBG_COLOR; - buffer[k++] = v; buffer[k++] = v; - } - #ifdef LCD_USE_DMA_FSMC - if (k <= 80) { // generally is... for our buttons - memcpy(&buffer[k], &buffer[0], k * sizeof(uint16_t)); - LCD_IO_WriteSequence(buffer, k * sizeof(uint16_t)); - } - else { - LCD_IO_WriteSequence(buffer, k); - LCD_IO_WriteSequence(buffer, k); - } - #else - u8g_WriteSequence(u8g, dev, k << 1, (uint8_t *)buffer); - u8g_WriteSequence(u8g, dev, k << 1, (uint8_t *)buffer); - #endif - } - } - -#endif // TOUCH_BUTTONS - -// Used to fill RGB565 (16bits) background -inline void memset2(const void *ptr, uint16_t fill, size_t cnt) { - uint16_t* wptr = (uint16_t*)ptr; - for (size_t i = 0; i < cnt; i += 2) { *wptr = fill; wptr++; } -} - -static bool preinit = true; -static uint8_t page; - -uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) { - u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); - #ifdef LCD_USE_DMA_FSMC - static uint16_t bufferA[512], bufferB[512]; - uint16_t* buffer = &bufferA[0]; - bool allow_async = true; - #else - uint16_t buffer[WIDTH*2]; // 16-bit RGB 565 pixel line buffer - #endif - switch (msg) { - case U8G_DEV_MSG_INIT: - dev->com_fn(u8g, U8G_COM_MSG_INIT, U8G_SPI_CLK_CYCLE_NONE, &lcd_id); - - switch(lcd_id & 0xFFFF) { - case 0x8552: // ST7789V - #ifdef LCD_USE_DMA_FSMC - writeEscSequence(st7789v_init); - #else - writeEscSequence8(u8g, dev, st7789v_init); - #endif - setWindow = setWindow_st7789v; - break; - case 0x9328: // ILI9328 - #ifdef LCD_USE_DMA_FSMC - writeEscSequence(ili9328_init); - #else - writeEscSequence16(u8g, dev, ili9328_init); - #endif - setWindow = setWindow_ili9328; - break; - case 0x9341: // ILI9341 - #ifdef LCD_USE_DMA_FSMC - writeEscSequence(ili9341_init); - #else - writeEscSequence8(u8g, dev, ili9341_init); - #endif - setWindow = setWindow_st7789v; - break; - case 0x0404: // No connected display on FSMC - lcd_id = 0; - return 0; - case 0xFFFF: // No connected display on SPI - lcd_id = 0; - return 0; - default: - if (lcd_id && 0xFF000000) - setWindow = setWindow_st7789v; - else - setWindow = setWindow_ili9328; - break; - } - - if (preinit) { - preinit = false; - return u8g_dev_pb8v1_base_fn(u8g, dev, msg, arg); - } - - // Clear Screen - setWindow(u8g, dev, 0, 0, LCD_FULL_PIXEL_WIDTH - 1, LCD_FULL_PIXEL_HEIGHT - 1); - #ifdef LCD_USE_DMA_FSMC - LCD_IO_WriteMultiple(TFT_MARLINBG_COLOR, LCD_FULL_PIXEL_WIDTH * LCD_FULL_PIXEL_HEIGHT); - #else - memset2(buffer, TFT_MARLINBG_COLOR, 160); - for (uint16_t i = 0; i < 960; i++) - u8g_WriteSequence(u8g, dev, 160, (uint8_t *)buffer); - #endif - - // bottom line and buttons - #if ENABLED(TOUCH_BUTTONS) - - setWindow(u8g, dev, 10, 170, 309, 171); - #ifdef LCD_USE_DMA_FSMC - LCD_IO_WriteMultiple(TFT_DISABLED_COLOR, 600); - #else - memset2(buffer, TFT_DISABLED_COLOR, 150); - for (uint8_t i = 8; i--;) - u8g_WriteSequence(u8g, dev, 150, (uint8_t *)buffer); - #endif - - setWindow(u8g, dev, 14, 185, 77, 224); - drawImage(buttonD, u8g, dev, 32, 20, TFT_BTCANCEL_COLOR); - - setWindow(u8g, dev, 90, 185, 153, 224); - drawImage(buttonA, u8g, dev, 32, 20, TFT_BTARROWS_COLOR); - - setWindow(u8g, dev, 166, 185, 229, 224); - drawImage(buttonB, u8g, dev, 32, 20, TFT_BTARROWS_COLOR); - - setWindow(u8g, dev, 242, 185, 305, 224); - drawImage(buttonC, u8g, dev, 32, 20, TFT_BTOKMENU_COLOR); - #endif // TOUCH_BUTTONS - - return 0; - - case U8G_DEV_MSG_STOP: preinit = true; break; - - case U8G_DEV_MSG_PAGE_FIRST: - page = 0; - setWindow(u8g, dev, X_LO, Y_LO, X_HI, Y_HI); - break; - - case U8G_DEV_MSG_PAGE_NEXT: - if (++page > (HEIGHT / PAGE_HEIGHT)) return 1; - - for (uint8_t y = 0; y < PAGE_HEIGHT; y++) { - uint32_t k = 0; - #ifdef LCD_USE_DMA_FSMC - buffer = (y & 1) ? bufferB : bufferA; - #endif - for (uint16_t i = 0; i < (uint32_t)pb->width; i++) { - const uint8_t b = *(((uint8_t *)pb->buf) + i); - const uint16_t c = TEST(b, y) ? TFT_MARLINUI_COLOR : TFT_MARLINBG_COLOR; - buffer[k++] = c; buffer[k++] = c; - } - #ifdef LCD_USE_DMA_FSMC - memcpy(&buffer[256], &buffer[0], 512); - if (allow_async) { - if (y > 0 || page > 1) LCD_IO_WaitSequence_Async(); - if (y == 7 && page == 8) - LCD_IO_WriteSequence(buffer, 512); // last line of last page - else - LCD_IO_WriteSequence_Async(buffer, 512); - } - else - LCD_IO_WriteSequence(buffer, 512); - #else - uint8_t* bufptr = (uint8_t*) buffer; - for (uint8_t i = 2; i--;) { - u8g_WriteSequence(u8g, dev, WIDTH, &bufptr[0]); - u8g_WriteSequence(u8g, dev, WIDTH, &bufptr[WIDTH]); - u8g_WriteSequence(u8g, dev, WIDTH, &bufptr[WIDTH*2]); - u8g_WriteSequence(u8g, dev, WIDTH, &bufptr[WIDTH*3]); - } - #endif - } - break; - - case U8G_DEV_MSG_SLEEP_ON: - // Enter Sleep Mode (10h) - return 1; - case U8G_DEV_MSG_SLEEP_OFF: - // Sleep Out (11h) - return 1; - } - return u8g_dev_pb8v1_base_fn(u8g, dev, msg, arg); -} - -U8G_PB_DEV(u8g_dev_tft_320x240_upscale_from_128x64, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_tft_320x240_upscale_from_128x64_fn, U8G_COM_HAL_FSMC_FN); - -#endif // HAS_GRAPHICAL_LCD && FSMC_CS diff --git a/Marlin/src/lcd/dogm/u8g_dev_tft_upscale_from_128x64.cpp b/Marlin/src/lcd/dogm/u8g_dev_tft_upscale_from_128x64.cpp new file mode 100644 index 000000000000..d18b617987cb --- /dev/null +++ b/Marlin/src/lcd/dogm/u8g_dev_tft_upscale_from_128x64.cpp @@ -0,0 +1,480 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * u8g_dev_tft_320x240_upscale_from_128x64.cpp + * + * Universal 8bit Graphics Library + * + * Copyright (c) 2011, olikraus@gmail.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "../../inc/MarlinConfig.h" + +#if HAS_MARLINUI_U8GLIB && (PIN_EXISTS(FSMC_CS) || ENABLED(SPI_GRAPHICAL_TFT)) + +#include "HAL_LCD_com_defines.h" +#include "ultralcd_DOGM.h" + +#include + +#if EITHER(LCD_USE_DMA_FSMC, LCD_USE_DMA_SPI) + #define HAS_LCD_IO 1 +#endif + +#include "../tft_io/tft_io.h" +TFT_IO tftio; + +#define WIDTH LCD_PIXEL_WIDTH +#define HEIGHT LCD_PIXEL_HEIGHT +#define PAGE_HEIGHT 8 + +#include "../scaled_tft.h" + +#define UPSCALE0(M) ((M) * (GRAPHICAL_TFT_UPSCALE)) +#define UPSCALE(A,M) (UPSCALE0(M) + (A)) +#define X_HI (UPSCALE(TFT_PIXEL_OFFSET_X, WIDTH) - 1) +#define Y_HI (UPSCALE(TFT_PIXEL_OFFSET_Y, HEIGHT) - 1) + +// see https://ee-programming-notepad.blogspot.com/2016/10/16-bit-color-generator-picker.html + +#define COLOR_BLACK 0x0000 // #000000 +#define COLOR_WHITE 0xFFFF // #FFFFFF +#define COLOR_SILVER 0xC618 // #C0C0C0 +#define COLOR_GREY 0x7BEF // #808080 +#define COLOR_DARKGREY 0x4208 // #404040 +#define COLOR_DARKGREY2 0x39E7 // #303030 +#define COLOR_DARK 0x0003 // Some dark color + +#define COLOR_RED 0xF800 // #FF0000 +#define COLOR_LIME 0x7E00 // #00FF00 +#define COLOR_BLUE 0x001F // #0000FF +#define COLOR_YELLOW 0xFFE0 // #FFFF00 +#define COLOR_MAGENTA 0xF81F // #FF00FF +#define COLOR_FUCHSIA 0xF81F // #FF00FF +#define COLOR_CYAN 0x07FF // #00FFFF +#define COLOR_AQUA 0x07FF // #00FFFF + +#define COLOR_MAROON 0x7800 // #800000 +#define COLOR_GREEN 0x03E0 // #008000 +#define COLOR_NAVY 0x000F // #000080 +#define COLOR_OLIVE 0x8400 // #808000 +#define COLOR_PURPLE 0x8010 // #800080 +#define COLOR_TEAL 0x0410 // #008080 + +#define COLOR_ORANGE 0xFC00 // #FF7F00 + +#ifndef TFT_MARLINUI_COLOR + #define TFT_MARLINUI_COLOR COLOR_WHITE +#endif +#ifndef TFT_MARLINBG_COLOR + #define TFT_MARLINBG_COLOR COLOR_BLACK +#endif +#ifndef TFT_DISABLED_COLOR + #define TFT_DISABLED_COLOR COLOR_DARK +#endif +#ifndef TFT_BTCANCEL_COLOR + #define TFT_BTCANCEL_COLOR COLOR_RED +#endif +#ifndef TFT_BTARROWS_COLOR + #define TFT_BTARROWS_COLOR COLOR_BLUE +#endif +#ifndef TFT_BTOKMENU_COLOR + #define TFT_BTOKMENU_COLOR COLOR_RED +#endif + +static void setWindow(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) { + tftio.set_window(Xmin, Ymin, Xmax, Ymax); +} + +#if HAS_TOUCH_XPT2046 + + static const uint8_t buttonD[] = { + B01111111,B11111111,B11111111,B11111110, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00011000,B00110000,B00000001, + B10000000,B00001100,B01100000,B00000001, + B10000000,B00000110,B11000000,B00000001, + B10000000,B00000011,B10000000,B00000001, + B10000000,B00000011,B10000000,B00000001, + B10000000,B00000110,B11000000,B00000001, + B10000000,B00001100,B01100000,B00000001, + B10000000,B00011000,B00110000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B01111111,B11111111,B11111111,B11111110, + }; + + #if ENABLED(REVERSE_MENU_DIRECTION) + + static const uint8_t buttonA[] = { + B01111111,B11111111,B11111111,B11111110, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B11100000,B00000000,B00000001, + B10000000,B11100000,B00000000,B00000001, + B10000000,B11100000,B00000000,B00000001, + B10000000,B11100000,B00000000,B00000001, + B10000000,B11100000,B00111111,B11100001, + B10000111,B11111100,B00111111,B11100001, + B10000011,B11111000,B00000000,B00000001, + B10000001,B11110000,B00000000,B00000001, + B10000000,B11100000,B00000000,B00000001, + B10000000,B01000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B01111111,B11111111,B11111111,B11111110, + }; + static const uint8_t buttonB[] = { + B01111111,B11111111,B11111111,B11111110, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B01100000,B00000010,B00000001, + B10000000,B01100000,B00000111,B00000001, + B10000000,B01100000,B00001111,B10000001, + B10000000,B01100000,B00011111,B11000001, + B10000111,B11111110,B00111111,B11100001, + B10000111,B11111110,B00000111,B00000001, + B10000000,B01100000,B00000111,B00000001, + B10000000,B01100000,B00000111,B00000001, + B10000000,B01100000,B00000111,B00000001, + B10000000,B01100000,B00000111,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B01111111,B11111111,B11111111,B11111110, + }; + + #else + + static const uint8_t buttonA[] = { + B01111111,B11111111,B11111111,B11111110, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B01000000,B00000000,B00000001, + B10000000,B11100000,B00000000,B00000001, + B10000001,B11110000,B00000000,B00000001, + B10000011,B11111000,B00000000,B00000001, + B10000111,B11111100,B00111111,B11100001, + B10000000,B11100000,B00111111,B11100001, + B10000000,B11100000,B00000000,B00000001, + B10000000,B11100000,B00000000,B00000001, + B10000000,B11100000,B00000000,B00000001, + B10000000,B11100000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B01111111,B11111111,B11111111,B11111110, + }; + + static const uint8_t buttonB[] = { + B01111111,B11111111,B11111111,B11111110, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B01100000,B00000111,B00000001, + B10000000,B01100000,B00000111,B00000001, + B10000000,B01100000,B00000111,B00000001, + B10000000,B01100000,B00000111,B00000001, + B10000111,B11111110,B00000111,B00000001, + B10000111,B11111110,B00111111,B11100001, + B10000000,B01100000,B00011111,B11000001, + B10000000,B01100000,B00001111,B10000001, + B10000000,B01100000,B00000111,B00000001, + B10000000,B01100000,B00000010,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B01111111,B11111111,B11111111,B11111110, + }; + + #endif + + static const uint8_t buttonC[] = { + B01111111,B11111111,B11111111,B11111110, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00011100,B00000001, + B10000000,B00000100,B00011100,B00000001, + B10000000,B00001100,B00011100,B00000001, + B10000000,B00011111,B11111100,B00000001, + B10000000,B00111111,B11111100,B00000001, + B10000000,B00011111,B11111100,B00000001, + B10000000,B00001100,B00000000,B00000001, + B10000000,B00000100,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B10000000,B00000000,B00000000,B00000001, + B01111111,B11111111,B11111111,B11111110, + }; + + #define BUTTON_SIZE_X 32 + #define BUTTON_SIZE_Y 20 + + // 14, 90, 166, 242, 185 are the original values upscaled 2x. + #define BUTTOND_X_LO UPSCALE0(14 / 2) + #define BUTTOND_X_HI (UPSCALE(BUTTOND_X_LO, BUTTON_SIZE_X) - 1) + + #define BUTTONA_X_LO UPSCALE0(90 / 2) + #define BUTTONA_X_HI (UPSCALE(BUTTONA_X_LO, BUTTON_SIZE_X) - 1) + + #define BUTTONB_X_LO UPSCALE0(166 / 2) + #define BUTTONB_X_HI (UPSCALE(BUTTONB_X_LO, BUTTON_SIZE_X) - 1) + + #define BUTTONC_X_LO UPSCALE0(242 / 2) + #define BUTTONC_X_HI (UPSCALE(BUTTONC_X_LO, BUTTON_SIZE_X) - 1) + + #define BUTTON_Y_LO UPSCALE0(140 / 2) + 44 // 184 2x, 254 3x + #define BUTTON_Y_HI (UPSCALE(BUTTON_Y_LO, BUTTON_SIZE_Y) - 1) + + void drawImage(const uint8_t *data, u8g_t *u8g, u8g_dev_t *dev, uint16_t length, uint16_t height, uint16_t color) { + uint16_t buffer[BUTTON_SIZE_X * sq(GRAPHICAL_TFT_UPSCALE)]; + + if (length > BUTTON_SIZE_X) return; + + for (uint16_t i = 0; i < height; i++) { + uint16_t k = 0; + for (uint16_t j = 0; j < length; j++) { + uint16_t v = TFT_MARLINBG_COLOR; + if (*(data + (i * (length >> 3) + (j >> 3))) & (0x80 >> (j & 7))) + v = color; + else + v = TFT_MARLINBG_COLOR; + LOOP_L_N(n, GRAPHICAL_TFT_UPSCALE) buffer[k++] = v; + } + #if HAS_LCD_IO + LOOP_S_L_N(n, 1, GRAPHICAL_TFT_UPSCALE) + for (uint16_t l = 0; l < UPSCALE0(length); l++) + buffer[l + n * UPSCALE0(length)] = buffer[l]; + + tftio.WriteSequence(buffer, length * sq(GRAPHICAL_TFT_UPSCALE)); + #else + for (uint8_t i = GRAPHICAL_TFT_UPSCALE; i--;) + u8g_WriteSequence(u8g, dev, k << 1, (uint8_t*)buffer); + #endif + } + } + +#endif // HAS_TOUCH_XPT2046 + +// Used to fill RGB565 (16bits) background +inline void memset2(const void *ptr, uint16_t fill, size_t cnt) { + uint16_t* wptr = (uint16_t*)ptr; + for (size_t i = 0; i < cnt; i += 2) { *wptr = fill; wptr++; } +} + +static bool preinit = true; +static uint8_t page; + +uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) { + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + + #if HAS_LCD_IO + static uint16_t bufferA[WIDTH * sq(GRAPHICAL_TFT_UPSCALE)], bufferB[WIDTH * sq(GRAPHICAL_TFT_UPSCALE)]; + uint16_t* buffer = &bufferA[0]; + #else + uint16_t buffer[WIDTH * GRAPHICAL_TFT_UPSCALE]; // 16-bit RGB 565 pixel line buffer + #endif + + switch (msg) { + case U8G_DEV_MSG_INIT: + dev->com_fn(u8g, U8G_COM_MSG_INIT, U8G_SPI_CLK_CYCLE_NONE, NULL); + tftio.Init(); + tftio.InitTFT(); + + if (preinit) { + preinit = false; + return u8g_dev_pb8v1_base_fn(u8g, dev, msg, arg); + } + + // Clear Screen + setWindow(u8g, dev, 0, 0, (TFT_WIDTH) - 1, (TFT_HEIGHT) - 1); + #if HAS_LCD_IO + tftio.WriteMultiple(TFT_MARLINBG_COLOR, uint32_t(TFT_WIDTH) * (TFT_HEIGHT)); + #else + memset2(buffer, TFT_MARLINBG_COLOR, (TFT_WIDTH) / 2); + for (uint16_t i = 0; i < (TFT_HEIGHT) * sq(GRAPHICAL_TFT_UPSCALE); i++) + u8g_WriteSequence(u8g, dev, (TFT_WIDTH) / 2, (uint8_t *)buffer); + #endif + + // Bottom buttons + #if HAS_TOUCH_XPT2046 + setWindow(u8g, dev, BUTTOND_X_LO, BUTTON_Y_LO, BUTTOND_X_HI, BUTTON_Y_HI); + drawImage(buttonD, u8g, dev, 32, 20, TFT_BTCANCEL_COLOR); + + setWindow(u8g, dev, BUTTONA_X_LO, BUTTON_Y_LO, BUTTONA_X_HI, BUTTON_Y_HI); + drawImage(buttonA, u8g, dev, 32, 20, TFT_BTARROWS_COLOR); + + setWindow(u8g, dev, BUTTONB_X_LO, BUTTON_Y_LO, BUTTONB_X_HI, BUTTON_Y_HI); + drawImage(buttonB, u8g, dev, 32, 20, TFT_BTARROWS_COLOR); + + setWindow(u8g, dev, BUTTONC_X_LO, BUTTON_Y_LO, BUTTONC_X_HI, BUTTON_Y_HI); + drawImage(buttonC, u8g, dev, 32, 20, TFT_BTOKMENU_COLOR); + #endif // HAS_TOUCH_XPT2046 + + return 0; + + case U8G_DEV_MSG_STOP: preinit = true; break; + + case U8G_DEV_MSG_PAGE_FIRST: + page = 0; + setWindow(u8g, dev, TFT_PIXEL_OFFSET_X, TFT_PIXEL_OFFSET_Y, X_HI, Y_HI); + break; + + case U8G_DEV_MSG_PAGE_NEXT: + if (++page > (HEIGHT / PAGE_HEIGHT)) return 1; + + LOOP_L_N(y, PAGE_HEIGHT) { + uint32_t k = 0; + #if HAS_LCD_IO + buffer = (y & 1) ? bufferB : bufferA; + #endif + for (uint16_t i = 0; i < (uint32_t)pb->width; i++) { + const uint8_t b = *(((uint8_t *)pb->buf) + i); + const uint16_t c = TEST(b, y) ? TFT_MARLINUI_COLOR : TFT_MARLINBG_COLOR; + LOOP_L_N(n, GRAPHICAL_TFT_UPSCALE) buffer[k++] = c; + } + #if HAS_LCD_IO + LOOP_S_L_N(n, 1, GRAPHICAL_TFT_UPSCALE) + for (uint16_t l = 0; l < UPSCALE0(WIDTH); l++) + buffer[l + n * UPSCALE0(WIDTH)] = buffer[l]; + + tftio.WriteSequence(buffer, COUNT(bufferA)); + #else + uint8_t* bufptr = (uint8_t*) buffer; + for (uint8_t i = GRAPHICAL_TFT_UPSCALE; i--;) { + LOOP_S_L_N(n, 0, GRAPHICAL_TFT_UPSCALE * 2) { + u8g_WriteSequence(u8g, dev, WIDTH, &bufptr[WIDTH * n]); + } + } + #endif + } + break; + + case U8G_DEV_MSG_SLEEP_ON: + // Enter Sleep Mode (10h) + return 1; + case U8G_DEV_MSG_SLEEP_OFF: + // Sleep Out (11h) + return 1; + } + return u8g_dev_pb8v1_base_fn(u8g, dev, msg, arg); +} + +static uint8_t msgInitCount = 2; // Ignore all messages until 2nd U8G_COM_MSG_INIT + +uint8_t u8g_com_hal_tft_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { + if (msgInitCount) { + if (msg == U8G_COM_MSG_INIT) msgInitCount--; + if (msgInitCount) return -1; + } + + static uint8_t isCommand; + + switch (msg) { + case U8G_COM_MSG_STOP: break; + case U8G_COM_MSG_INIT: + u8g_SetPIOutput(u8g, U8G_PI_RESET); + u8g_Delay(50); + isCommand = 0; + break; + + case U8G_COM_MSG_ADDRESS: // define cmd (arg_val = 0) or data mode (arg_val = 1) + isCommand = arg_val == 0 ? 1 : 0; + break; + + case U8G_COM_MSG_RESET: + u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val); + break; + + case U8G_COM_MSG_WRITE_BYTE: + tftio.DataTransferBegin(DATASIZE_8BIT); + if (isCommand) + tftio.WriteReg(arg_val); + else + tftio.WriteData((uint16_t)arg_val); + tftio.DataTransferEnd(); + break; + + case U8G_COM_MSG_WRITE_SEQ: + tftio.DataTransferBegin(DATASIZE_16BIT); + for (uint8_t i = 0; i < arg_val; i += 2) + tftio.WriteData(*(uint16_t *)(((uint32_t)arg_ptr) + i)); + tftio.DataTransferEnd(); + break; + + } + return 1; +} + +U8G_PB_DEV(u8g_dev_tft_320x240_upscale_from_128x64, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_tft_320x240_upscale_from_128x64_fn, U8G_COM_HAL_TFT_FN); + +#endif // HAS_MARLINUI_U8GLIB && FSMC_CS diff --git a/Marlin/src/lcd/dogm/u8g_dev_uc1701_mini12864_HAL.cpp b/Marlin/src/lcd/dogm/u8g_dev_uc1701_mini12864_HAL.cpp index e6fc310df161..172afbd76647 100644 --- a/Marlin/src/lcd/dogm/u8g_dev_uc1701_mini12864_HAL.cpp +++ b/Marlin/src/lcd/dogm/u8g_dev_uc1701_mini12864_HAL.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -55,7 +55,7 @@ #include "../../inc/MarlinConfigPre.h" -#if HAS_GRAPHICAL_LCD +#if HAS_MARLINUI_U8GLIB #include "HAL_LCD_com_defines.h" @@ -112,13 +112,14 @@ static const uint8_t u8g_dev_uc1701_mini12864_HAL_init_seq[] PROGMEM = { U8G_ESC_CS(1), // enable chip UC1701_ALL_PIX(0), // normal display U8G_ESC_CS(0), // disable chip + U8G_ESC_DLY(150), // delay 150 ms before sending any data U8G_ESC_END // end of sequence }; static const uint8_t u8g_dev_uc1701_mini12864_HAL_data_start[] PROGMEM = { U8G_ESC_ADR(0), // instruction mode U8G_ESC_CS(1), // enable chip - #if EITHER(MKS_MINI_12864, ENDER2_STOCKDISPLAY) + #if ANY(MKS_MINI_12864, ENDER2_STOCKDISPLAY, FYSETC_MINI_12864) UC1701_START_LINE(0), // set display start line to 0 UC1701_ADC_REVERSE(0), // ADC set to reverse UC1701_OUT_MODE(1), // common output mode @@ -209,4 +210,4 @@ u8g_pb_t u8g_dev_uc1701_mini12864_HAL_2x_pb = { {16, HEIGHT, 0, 0, 0}, WIDTH, u u8g_dev_t u8g_dev_uc1701_mini12864_HAL_2x_sw_spi = { u8g_dev_uc1701_mini12864_HAL_2x_fn, &u8g_dev_uc1701_mini12864_HAL_2x_pb, U8G_COM_HAL_SW_SPI_FN }; u8g_dev_t u8g_dev_uc1701_mini12864_HAL_2x_hw_spi = { u8g_dev_uc1701_mini12864_HAL_2x_fn, &u8g_dev_uc1701_mini12864_HAL_2x_pb, U8G_COM_HAL_HW_SPI_FN }; -#endif // HAS_GRAPHICAL_LCD +#endif // HAS_MARLINUI_U8GLIB diff --git a/Marlin/src/lcd/dogm/u8g_fontutf8.cpp b/Marlin/src/lcd/dogm/u8g_fontutf8.cpp index b976e2777cf4..89bdb09e1be2 100644 --- a/Marlin/src/lcd/dogm/u8g_fontutf8.cpp +++ b/Marlin/src/lcd/dogm/u8g_fontutf8.cpp @@ -9,7 +9,7 @@ #include "../../inc/MarlinConfigPre.h" -#if HAS_GRAPHICAL_LCD +#if HAS_MARLINUI_U8GLIB #include #include "../fontutils.h" @@ -140,7 +140,6 @@ static int fontgroup_cb_draw_u8g(void *userdata, const font_t *fnt_current, cons if (pdata->fnt_prev != fnt_current) { u8g_SetFont(pdata->pu8g, (const u8g_fntpgm_uint8_t*)fnt_current); - //u8g_SetFontPosBottom(pdata->pu8g); pdata->fnt_prev = fnt_current; } if ((pdata->max_width != PIXEL_LEN_NOLIMIT) && (pdata->adv + u8g_GetStrPixelWidth(pdata->pu8g, (char*)msg) > pdata->max_width)) @@ -256,7 +255,6 @@ static int fontgroup_cb_draw_u8gstrlen(void *userdata, const font_t *fnt_current if (pdata->fnt_prev != fnt_current) { u8g_SetFont(pdata->pu8g, (const u8g_fntpgm_uint8_t*)fnt_current); - u8g_SetFontPosBottom(pdata->pu8g); pdata->fnt_prev = fnt_current; } pdata->adv += u8g_GetStrPixelWidth(pdata->pu8g, (char*)msg); @@ -314,4 +312,4 @@ int uxg_GetUtf8StrPixelWidthP(u8g_t *pu8g, PGM_P utf8_msg) { return data.adv; } -#endif // HAS_GRAPHICAL_LCD +#endif // HAS_MARLINUI_U8GLIB diff --git a/Marlin/src/lcd/dogm/ultralcd_DOGM.cpp b/Marlin/src/lcd/dogm/ultralcd_DOGM.cpp index 8dd24e2737f1..c48abac81016 100644 --- a/Marlin/src/lcd/dogm/ultralcd_DOGM.cpp +++ b/Marlin/src/lcd/dogm/ultralcd_DOGM.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -26,18 +26,18 @@ * Implementation of the LCD display routines for a DOGM128 graphic display. * by STB for ErikZalm/Marlin. Common LCD 128x64 pixel graphic displays. * - * Demonstrator: http://www.reprap.org/wiki/STB_Electronics - * License: http://opensource.org/licenses/BSD-3-Clause + * Demonstrator: https://www.reprap.org/wiki/STB_Electronics + * License: https://opensource.org/licenses/BSD-3-Clause * * With the use of: * u8glib by Oliver Kraus * https://github.com/olikraus/U8glib_Arduino - * License: http://opensource.org/licenses/BSD-3-Clause + * License: https://opensource.org/licenses/BSD-3-Clause */ #include "../../inc/MarlinConfigPre.h" -#if HAS_GRAPHICAL_LCD +#if HAS_MARLINUI_U8GLIB #include "ultralcd_DOGM.h" #include "u8g_fontutf8.h" @@ -65,7 +65,7 @@ /** * Include all needed font files - * (See http://marlinfw.org/docs/development/fonts.html) + * (See https://marlinfw.org/docs/development/fonts.html) */ #include "fontdata/fontdata_ISO10646_1.h" #if ENABLED(USE_SMALL_INFOFONT) @@ -123,6 +123,7 @@ bool MarlinUI::detected() { return true; } custom_start_bmp #endif ; + TERN(CUSTOM_BOOTSCREEN_ANIMATED,,UNUSED(frame)); u8g.drawBitmapP(left, top, CUSTOM_BOOTSCREEN_BMP_BYTEWIDTH, CUSTOM_BOOTSCREEN_BMPHEIGHT, bmp); @@ -219,9 +220,6 @@ bool MarlinUI::detected() { return true; } // Show the Marlin bootscreen, with the u8g loop and delays void MarlinUI::show_marlin_bootscreen() { - #ifndef BOOTSCREEN_TIMEOUT - #define BOOTSCREEN_TIMEOUT 2500 - #endif constexpr uint8_t pages = two_part ? 2 : 1; for (uint8_t q = pages; q--;) { draw_marlin_bootscreen(q == 0); @@ -230,9 +228,7 @@ bool MarlinUI::detected() { return true; } } void MarlinUI::show_bootscreen() { - #if ENABLED(SHOW_CUSTOM_BOOTSCREEN) - show_custom_bootscreen(); - #endif + TERN_(SHOW_CUSTOM_BOOTSCREEN, show_custom_bootscreen()); show_marlin_bootscreen(); } @@ -244,60 +240,42 @@ bool MarlinUI::detected() { return true; } // Initialize or re-initialize the LCD void MarlinUI::init_lcd() { - #if DISABLED(MKS_LCD12864B) - - #if PIN_EXISTS(LCD_BACKLIGHT) - OUT_WRITE(LCD_BACKLIGHT_PIN, ( - #if ENABLED(DELAYED_BACKLIGHT_INIT) - LOW // Illuminate after reset - #else - HIGH // Illuminate right away - #endif - )); - #endif - - #if EITHER(MKS_12864OLED, MKS_12864OLED_SSD1306) - SET_OUTPUT(LCD_PINS_DC); - #ifndef LCD_RESET_PIN - #define LCD_RESET_PIN LCD_PINS_RS - #endif - #endif + #if PIN_EXISTS(LCD_BACKLIGHT) + OUT_WRITE(LCD_BACKLIGHT_PIN, DISABLED(DELAYED_BACKLIGHT_INIT)); // Illuminate after reset or right away + #endif - #if PIN_EXISTS(LCD_RESET) - // Perform a clean hardware reset with needed delays - OUT_WRITE(LCD_RESET_PIN, LOW); - _delay_ms(5); - WRITE(LCD_RESET_PIN, HIGH); - _delay_ms(5); - u8g.begin(); + #if ANY(MKS_12864OLED, MKS_12864OLED_SSD1306, FYSETC_242_OLED_12864, ZONESTAR_12864OLED) + SET_OUTPUT(LCD_PINS_DC); + #ifndef LCD_RESET_PIN + #define LCD_RESET_PIN LCD_PINS_RS #endif + #endif - #if PIN_EXISTS(LCD_BACKLIGHT) && ENABLED(DELAYED_BACKLIGHT_INIT) - WRITE(LCD_BACKLIGHT_PIN, HIGH); - #endif + #if PIN_EXISTS(LCD_RESET) + // Perform a clean hardware reset with needed delays + OUT_WRITE(LCD_RESET_PIN, LOW); + _delay_ms(5); + WRITE(LCD_RESET_PIN, HIGH); + _delay_ms(5); + u8g.begin(); + #endif - #if HAS_LCD_CONTRAST - refresh_contrast(); - #endif + #if PIN_EXISTS(LCD_BACKLIGHT) && ENABLED(DELAYED_BACKLIGHT_INIT) + WRITE(LCD_BACKLIGHT_PIN, HIGH); + #endif - #if ENABLED(LCD_SCREEN_ROT_90) - u8g.setRot90(); - #elif ENABLED(LCD_SCREEN_ROT_180) - u8g.setRot180(); - #elif ENABLED(LCD_SCREEN_ROT_270) - u8g.setRot270(); - #endif + TERN_(HAS_LCD_CONTRAST, refresh_contrast()); - #endif // !MKS_LCD12864B + TERN_(LCD_SCREEN_ROT_90, u8g.setRot90()); + TERN_(LCD_SCREEN_ROT_180, u8g.setRot180()); + TERN_(LCD_SCREEN_ROT_270, u8g.setRot270()); uxg_SetUtf8Fonts(g_fontinfo, COUNT(g_fontinfo)); } // The kill screen is displayed for unrecoverable conditions void MarlinUI::draw_kill_screen() { - #if ENABLED(LIGHTWEIGHT_UI) - ST7920_Lite_Status_Screen::clear_text_buffer(); - #endif + TERN_(LIGHTWEIGHT_UI, ST7920_Lite_Status_Screen::clear_text_buffer()); const u8g_uint_t h4 = u8g.getHeight() / 4; u8g.firstPage(); do { @@ -327,16 +305,17 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop lcd_put_wchar(LCD_PIXEL_WIDTH - 11 * (MENU_FONT_WIDTH), row_y2, 'E'); lcd_put_wchar((char)('1' + extruder)); lcd_put_wchar(' '); - lcd_put_u8str(i16tostr3(thermalManager.degHotend(extruder))); + lcd_put_u8str(i16tostr3rj(thermalManager.degHotend(extruder))); lcd_put_wchar('/'); - if (get_blink() || !thermalManager.hotend_idle[extruder].timed_out) - lcd_put_u8str(i16tostr3(thermalManager.degTargetHotend(extruder))); + if (get_blink() || !thermalManager.heater_idle[extruder].timed_out) + lcd_put_u8str(i16tostr3rj(thermalManager.degTargetHotend(extruder))); } #endif // ADVANCED_PAUSE_FEATURE - // Set the colors for a menu item based on whether it is selected + // Mark a menu item and set font color if selected. + // Return 'false' if the item is not on screen. static bool mark_as_selected(const uint8_t row, const bool sel) { row_y1 = row * (MENU_FONT_HEIGHT) + 1; row_y2 = row_y1 + MENU_FONT_HEIGHT - 1; @@ -348,15 +327,13 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop u8g.drawHLine(0, row_y1 + 1, LCD_PIXEL_WIDTH); u8g.drawHLine(0, row_y2 + 2, LCD_PIXEL_WIDTH); #else - u8g.setColorIndex(1); // black on white + u8g.setColorIndex(1); // solid outline u8g.drawBox(0, row_y1 + 2, LCD_PIXEL_WIDTH, MENU_FONT_HEIGHT - 1); - u8g.setColorIndex(0); // white on black + u8g.setColorIndex(0); // inverted text #endif } #if DISABLED(MENU_HOLLOW_FRAME) - else { - u8g.setColorIndex(1); // unmarked text is black on white - } + else u8g.setColorIndex(1); // solid text #endif if (!PAGE_CONTAINS(row_y1, row_y2)) return false; @@ -366,18 +343,21 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop } // Draw a static line of text in the same idiom as a menu item - void MenuItem_static::draw(const uint8_t row, PGM_P const pstr, const uint8_t style/*=SS_DEFAULT*/, const char * const valstr/*=nullptr*/) { + void MenuItem_static::draw(const uint8_t row, PGM_P const pstr, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) { if (mark_as_selected(row, style & SS_INVERT)) { - u8g_uint_t n = LCD_PIXEL_WIDTH; // pixel width of string allowed + pixel_len_t n = LCD_PIXEL_WIDTH; // pixel width of string allowed - if ((style & SS_CENTER) && !valstr) { - int8_t pad = (LCD_WIDTH - utf8_strlen_P(pstr)) / 2; - while (--pad >= 0) { lcd_put_wchar(' '); n--; } + const int8_t plen = pstr ? utf8_strlen_P(pstr) : 0, + vlen = vstr ? utf8_strlen(vstr) : 0; + if (style & SS_CENTER) { + int8_t pad = (LCD_WIDTH - plen - vlen) / 2; + while (--pad >= 0) n -= lcd_put_wchar(' '); } - n = lcd_put_u8str_ind_P(pstr, itemIndex, LCD_WIDTH) * (MENU_FONT_WIDTH); - if (valstr) n -= lcd_put_u8str_max(valstr, n); + + if (plen) n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, n / (MENU_FONT_WIDTH)) * (MENU_FONT_WIDTH); + if (vlen) n -= lcd_put_u8str_max(vstr, n); while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' '); } } @@ -385,7 +365,7 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop // Draw a generic menu item void MenuItemBase::_draw(const bool sel, const uint8_t row, PGM_P const pstr, const char, const char post_char) { if (mark_as_selected(row, sel)) { - u8g_uint_t n = lcd_put_u8str_ind_P(pstr, itemIndex, LCD_WIDTH - 2) * (MENU_FONT_WIDTH); + pixel_len_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 1) * (MENU_FONT_WIDTH); while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' '); lcd_put_wchar(LCD_PIXEL_WIDTH - (MENU_FONT_WIDTH), row_y2, post_char); lcd_put_wchar(' '); @@ -393,15 +373,17 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop } // Draw a menu item with an editable value - void MenuEditItemBase::draw(const bool sel, const uint8_t row, PGM_P const pstr, const char* const data, const bool pgm) { + void MenuEditItemBase::draw(const bool sel, const uint8_t row, PGM_P const pstr, const char* const inStr, const bool pgm) { if (mark_as_selected(row, sel)) { - const uint8_t vallen = (pgm ? utf8_strlen_P(data) : utf8_strlen((char*)data)); - u8g_uint_t n = lcd_put_u8str_ind_P(pstr, itemIndex, LCD_WIDTH - 2 - vallen) * (MENU_FONT_WIDTH); + const uint8_t vallen = (pgm ? utf8_strlen_P(inStr) : utf8_strlen((char*)inStr)), + pixelwidth = (pgm ? uxg_GetUtf8StrPixelWidthP(u8g.getU8g(), inStr) : uxg_GetUtf8StrPixelWidth(u8g.getU8g(), (char*)inStr)); + + pixel_len_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 2 - vallen) * (MENU_FONT_WIDTH); if (vallen) { lcd_put_wchar(':'); while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' '); - lcd_moveto(LCD_PIXEL_WIDTH - (MENU_FONT_WIDTH) * vallen, row_y2); - if (pgm) lcd_put_u8str_P(data); else lcd_put_u8str((char*)data); + lcd_moveto(LCD_PIXEL_WIDTH - _MAX((MENU_FONT_WIDTH) * vallen, pixelwidth + 2), row_y2); + if (pgm) lcd_put_u8str_P(inStr); else lcd_put_u8str((char*)inStr); } } } @@ -438,7 +420,7 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop // Assume the label is alpha-numeric (with a descender) bool onpage = PAGE_CONTAINS(baseline - (EDIT_FONT_ASCENT - 1), baseline + EDIT_FONT_DESCENT); - if (onpage) lcd_put_u8str_ind_P(0, baseline, pstr, itemIndex); + if (onpage) lcd_put_u8str_ind_P(0, baseline, pstr, itemIndex, itemString); // If a value is included, print a colon, then print the value right-justified if (value != nullptr) { @@ -453,11 +435,13 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop lcd_put_u8str(value); } } + TERN_(USE_BIG_EDIT_FONT, ui.set_font(FONT_MENU)); } inline void draw_boxed_string(const u8g_uint_t x, const u8g_uint_t y, PGM_P const pstr, const bool inv) { - const u8g_uint_t len = utf8_strlen_P(pstr), bw = len * (MENU_FONT_WIDTH), - bx = x * (MENU_FONT_WIDTH), by = (y + 1) * (MENU_FONT_HEIGHT); + const u8g_uint_t len = utf8_strlen_P(pstr), + by = (y + 1) * (MENU_FONT_HEIGHT); + const pixel_len_t bw = len * (MENU_FONT_WIDTH), bx = x * (MENU_FONT_WIDTH); if (inv) { u8g.setColorIndex(1); u8g.drawBox(bx - 1, by - (MENU_FONT_ASCENT) + 1, bw + 2, MENU_FONT_HEIGHT - 1); @@ -479,8 +463,8 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop if (mark_as_selected(row, sel)) { if (isDir) lcd_put_wchar(LCD_STR_FOLDER[0]); constexpr uint8_t maxlen = LCD_WIDTH - 1; - const u8g_uint_t pixw = maxlen * (MENU_FONT_WIDTH); - u8g_uint_t n = pixw - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, row, sel), pixw); + const pixel_len_t pixw = maxlen * (MENU_FONT_WIDTH); + pixel_len_t n = pixw - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, row, sel), pixw); while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' '); } } @@ -548,9 +532,9 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop if (PAGE_UNDER(7)) { const xy_pos_t pos = { ubl.mesh_index_to_xpos(x_plot), ubl.mesh_index_to_ypos(y_plot) }, lpos = pos.asLogical(); - lcd_put_u8str(5, 7, "X:"); + lcd_put_u8str_P(5, 7, X_LBL); lcd_put_u8str(ftostr52(lpos.x)); - lcd_put_u8str(74, 7, "Y:"); + lcd_put_u8str_P(74, 7, Y_LBL); lcd_put_u8str(ftostr52(lpos.y)); } @@ -563,7 +547,7 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop lcd_put_wchar(')'); // Show the location value - lcd_put_u8str(74, LCD_PIXEL_HEIGHT, "Z:"); + lcd_put_u8str_P(74, LCD_PIXEL_HEIGHT, Z_LBL); if (!isnan(ubl.z_values[x_plot][y_plot])) lcd_put_u8str(ftostr43sign(ubl.z_values[x_plot][y_plot])); else @@ -703,4 +687,4 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop #endif // HAS_LCD_MENU -#endif // HAS_GRAPHICAL_LCD +#endif // HAS_MARLINUI_U8GLIB diff --git a/Marlin/src/lcd/dogm/ultralcd_DOGM.h b/Marlin/src/lcd/dogm/ultralcd_DOGM.h index 536b8f0bf9f7..228cee6848b4 100644 --- a/Marlin/src/lcd/dogm/ultralcd_DOGM.h +++ b/Marlin/src/lcd/dogm/ultralcd_DOGM.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -33,6 +33,9 @@ //#define ALTERNATIVE_LCD #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) + + // RepRapWorld Graphical LCD + #define U8G_CLASS U8GLIB_ST7920_128X64_4X #if DISABLED(SDSUPPORT) && (LCD_PINS_D4 == SCK_PIN) && (LCD_PINS_ENABLE == MOSI_PIN) #define U8G_PARAM LCD_PINS_RS @@ -43,6 +46,7 @@ #elif ENABLED(U8GLIB_ST7920) // RepRap Discount Full Graphics Smart Controller + // and other variant LCDs using ST7920 #if DISABLED(SDSUPPORT) && (LCD_PINS_D4 == SCK_PIN) && (LCD_PINS_ENABLE == MOSI_PIN) #define U8G_CLASS U8GLIB_ST7920_128X64_4X_HAL // 2 stripes, HW SPI (Shared with SD card. Non-standard LCD adapter on AVR.) @@ -70,7 +74,7 @@ #elif ENABLED(U8GLIB_LM6059_AF) - // Based on the Adafruit ST7565 (http://www.adafruit.com/products/250) + // Based on the Adafruit ST7565 (https://www.adafruit.com/products/250) #if ENABLED(ALTERNATIVE_LCD) #define U8G_CLASS U8GLIB_LM6059 // 8 stripes (HW-SPI) @@ -88,9 +92,29 @@ #define FORCE_SOFT_SPI // SW-SPI #endif -#elif ENABLED(MKS_12864OLED_SSD1306) +#elif ANY(FYSETC_MINI_12864, MKS_MINI_12864, ENDER2_STOCKDISPLAY) + + // The FYSETC Mini 12864 display // "4 stripes" + + // The MKS_MINI_12864 V1/V2 aren't exact copies of the MiniPanel. + // Panel management is in u8g_dev_uc1701_mini12864_HAL.cpp with + // extra delays added to remove glitches seen with fast MCUs. + + #define U8G_CLASS U8GLIB_MINI12864_2X_HAL // 8 stripes (HW-SPI) + +#elif ENABLED(MINIPANEL) + + #if ENABLED(ALTERNATIVE_LCD) + #define U8G_CLASS U8GLIB_MINI12864 + #else + #define U8G_CLASS U8GLIB_MINI12864_2X // 8 stripes (HW-SPI) + #endif + +#elif EITHER(MKS_12864OLED_SSD1306, FYSETC_242_OLED_12864) // MKS 128x64 (SSD1306) OLED I2C LCD + // - or - + // FYSETC OLED 2.42" 128 × 64 FULL GRAPHICS CONTROLLER #define FORCE_SOFT_SPI // SW-SPI @@ -100,29 +124,37 @@ #define U8G_CLASS U8GLIB_SSD1306_128X64 // 8 stripes #endif -#elif ENABLED(U8GLIB_SSD1306) +#elif ENABLED(ZONESTAR_12864OLED_SSD1306) - // Generic SSD1306 OLED I2C LCD + // Zonestar SSD1306 OLED SPI LCD + #define FORCE_SOFT_SPI // SW-SPI #if ENABLED(ALTERNATIVE_LCD) - #define U8G_CLASS U8GLIB_SSD1306_128X64_2X_I2C_2_WIRE // 4 stripes + #define U8G_CLASS U8GLIB_SH1306_128X64_2X // 4 stripes #else - #define U8G_CLASS U8GLIB_SSD1306_128X64_2X // 4 stripes + #define U8G_CLASS U8GLIB_SH1306_128X64 // 8 stripes #endif - #define U8G_PARAM (U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST) -#elif ENABLED(MKS_12864OLED) +#elif EITHER(MKS_12864OLED, ZONESTAR_12864OLED) // MKS 128x64 (SH1106) OLED I2C LCD + // - or - + // Zonestar SH1106 OLED SPI LCD #define FORCE_SOFT_SPI // SW-SPI - #if ENABLED(ALTERNATIVE_LCD) #define U8G_CLASS U8GLIB_SH1106_128X64_2X // 4 stripes #else #define U8G_CLASS U8GLIB_SH1106_128X64 // 8 stripes #endif +#elif ENABLED(U8GLIB_SH1106_EINSTART) + + // Connected via motherboard header + + #define U8G_CLASS U8GLIB_SH1106_128X64 + #define U8G_PARAM DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, LCD_PINS_DC, LCD_PINS_RS + #elif ENABLED(U8GLIB_SH1106) // Generic SH1106 OLED I2C LCD @@ -141,41 +173,27 @@ #define U8G_CLASS U8GLIB_SSD1309_128X64 #define U8G_PARAM (U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST) // I2C -#elif ENABLED(FYSETC_MINI_12864) - - // The FYSETC Mini 12864 display - - #define U8G_CLASS U8GLIB_MINI12864_2X_HAL // 4 stripes - -#elif EITHER(MKS_MINI_12864, ENDER2_STOCKDISPLAY) - - // The MKS_MINI_12864 V1/V2 aren't exact copies of the MiniPanel. - // Panel management is in u8g_dev_uc1701_mini12864_HAL.cpp with - // extra delays added to remove glitches seen with fast MCUs. - - #define U8G_CLASS U8GLIB_MINI12864_2X_HAL // 8 stripes (HW-SPI) +#elif ENABLED(U8GLIB_SSD1306) -#elif ENABLED(MINIPANEL) + // Generic SSD1306 OLED I2C LCD #if ENABLED(ALTERNATIVE_LCD) - #define U8G_CLASS U8GLIB_MINI12864 + #define U8G_CLASS U8GLIB_SSD1306_128X64_2X_I2C_2_WIRE // 4 stripes #else - #define U8G_CLASS U8GLIB_MINI12864_2X // 8 stripes (HW-SPI) + #define U8G_CLASS U8GLIB_SSD1306_128X64_2X // 4 stripes #endif + #define U8G_PARAM (U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST) -#elif ENABLED(U8GLIB_SH1106_EINSTART) - - // Connected via motherboard header - - #define U8G_CLASS U8GLIB_SH1106_128X64 - #define U8G_PARAM DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, LCD_PINS_DC, LCD_PINS_RS - -#elif ENABLED(FSMC_GRAPHICAL_TFT) +#elif TFT_SCALED_DOGLCD // Unspecified 320x240 TFT pre-initialized by built-in bootloader #define U8G_CLASS U8GLIB_TFT_320X240_UPSCALE_FROM_128X64 - #define U8G_PARAM FSMC_CS_PIN, FSMC_RS_PIN + #if ENABLED(FSMC_GRAPHICAL_TFT) + #define U8G_PARAM FSMC_CS_PIN, FSMC_RS_PIN + #else + #define U8G_PARAM -1, -1 + #endif #else @@ -196,54 +214,9 @@ #endif #endif -// LCD_FULL_PIXEL_WIDTH = -// LCD_PIXEL_OFFSET_X + (LCD_PIXEL_WIDTH * 2) + LCD_PIXEL_OFFSET_X -#if ENABLED(FSMC_GRAPHICAL_TFT) - #define LCD_FULL_PIXEL_WIDTH 320 - #define LCD_PIXEL_OFFSET_X 32 - #define LCD_FULL_PIXEL_HEIGHT 240 - #define LCD_PIXEL_OFFSET_Y 32 -#endif - // For selective rendering within a Y range #define PAGE_OVER(ya) ((ya) <= u8g.getU8g()->current_page.y1) // Does the current page follow a region top? #define PAGE_UNDER(yb) ((yb) >= u8g.getU8g()->current_page.y0) // Does the current page precede a region bottom? #define PAGE_CONTAINS(ya, yb) ((yb) >= u8g.getU8g()->current_page.y0 && (ya) <= u8g.getU8g()->current_page.y1) // Do two vertical regions overlap? -// Only Western languages support big / small fonts -#if DISABLED(DISPLAY_CHARSET_ISO10646_1) - #undef USE_BIG_EDIT_FONT - #undef USE_SMALL_INFOFONT -#endif - -#define MENU_FONT_NAME ISO10646_1_5x7 -#define MENU_FONT_WIDTH 6 -#define MENU_FONT_ASCENT 10 -#define MENU_FONT_DESCENT 2 -#define MENU_FONT_HEIGHT (MENU_FONT_ASCENT + MENU_FONT_DESCENT) - -#if ENABLED(USE_BIG_EDIT_FONT) - #define EDIT_FONT_NAME u8g_font_9x18 - #define EDIT_FONT_WIDTH 9 - #define EDIT_FONT_ASCENT 10 - #define EDIT_FONT_DESCENT 3 -#else - #define EDIT_FONT_NAME MENU_FONT_NAME - #define EDIT_FONT_WIDTH MENU_FONT_WIDTH - #define EDIT_FONT_ASCENT MENU_FONT_ASCENT - #define EDIT_FONT_DESCENT MENU_FONT_DESCENT -#endif -#define EDIT_FONT_HEIGHT (EDIT_FONT_ASCENT + EDIT_FONT_DESCENT) - -// Get the Ascent, Descent, and total Height for the Info Screen font -#if ENABLED(USE_SMALL_INFOFONT) - extern const u8g_fntpgm_uint8_t u8g_font_6x9[]; - #define INFO_FONT_ASCENT 7 -#else - #define INFO_FONT_ASCENT 8 -#endif -#define INFO_FONT_DESCENT 2 -#define INFO_FONT_HEIGHT (INFO_FONT_ASCENT + INFO_FONT_DESCENT) -#define INFO_FONT_WIDTH 6 - extern U8G_CLASS u8g; diff --git a/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.cpp b/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.cpp index 4e38e554a2da..e6bd80c2c2fd 100644 --- a/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.cpp +++ b/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -34,19 +34,30 @@ #include "ultralcd_st7920_u8glib_rrd_AVR.h" #ifndef ST7920_DELAY_1 - #define ST7920_DELAY_1 CPU_ST7920_DELAY_1 + #ifdef BOARD_ST7920_DELAY_1 + #define ST7920_DELAY_1 BOARD_ST7920_DELAY_1 + #else + #define ST7920_DELAY_1 CPU_ST7920_DELAY_1 + #endif #endif #ifndef ST7920_DELAY_2 - #define ST7920_DELAY_2 CPU_ST7920_DELAY_2 + #ifdef BOARD_ST7920_DELAY_2 + #define ST7920_DELAY_2 BOARD_ST7920_DELAY_2 + #else + #define ST7920_DELAY_2 CPU_ST7920_DELAY_2 + #endif #endif #ifndef ST7920_DELAY_3 - #define ST7920_DELAY_3 CPU_ST7920_DELAY_3 + #ifdef BOARD_ST7920_DELAY_3 + #define ST7920_DELAY_3 BOARD_ST7920_DELAY_3 + #else + #define ST7920_DELAY_3 CPU_ST7920_DELAY_3 + #endif #endif // Optimize this code with -O3 #pragma GCC optimize (3) - #ifdef ARDUINO_ARCH_STM32F1 #define ST7920_DAT(V) !!((V) & 0x80) #else diff --git a/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.h b/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.h index c6e0b9944bb3..70be70eab79a 100644 --- a/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.h +++ b/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -46,11 +46,11 @@ #define CPU_ST7920_DELAY_1 DELAY_NS(0) #define CPU_ST7920_DELAY_2 DELAY_NS(0) #define CPU_ST7920_DELAY_3 DELAY_NS(50) -#elif MB(3DRAG, K8200, K8400, SILVER_GATE) +#elif MB(3DRAG, K8200, K8400) #define CPU_ST7920_DELAY_1 DELAY_NS(0) #define CPU_ST7920_DELAY_2 DELAY_NS(188) #define CPU_ST7920_DELAY_3 DELAY_NS(0) -#elif MB(MINIRAMBO, EINSY_RAMBO, EINSY_RETRO) +#elif MB(MINIRAMBO, EINSY_RAMBO, EINSY_RETRO, SILVER_GATE) #define CPU_ST7920_DELAY_1 DELAY_NS(0) #define CPU_ST7920_DELAY_2 DELAY_NS(250) #define CPU_ST7920_DELAY_3 DELAY_NS(0) @@ -86,5 +86,5 @@ void ST7920_SWSPI_SND_8BIT(uint8_t val); #define ST7920_NCS() { WRITE(ST7920_CS_PIN,0); } #define ST7920_SET_CMD() { ST7920_SWSPI_SND_8BIT(0xF8); U8G_DELAY(); } #define ST7920_SET_DAT() { ST7920_SWSPI_SND_8BIT(0xFA); U8G_DELAY(); } -#define ST7920_WRITE_BYTE(a) { ST7920_SWSPI_SND_8BIT((uint8_t)((a)&0xF0u)); ST7920_SWSPI_SND_8BIT((uint8_t)((a)<<4u)); U8G_DELAY(); } +#define ST7920_WRITE_BYTE(a) { ST7920_SWSPI_SND_8BIT((uint8_t)((a)&0xF0u)); ST7920_SWSPI_SND_8BIT((uint8_t)((a)<<4U)); U8G_DELAY(); } #define ST7920_WRITE_BYTES(p,l) { for (uint8_t i = l + 1; --i;) { ST7920_SWSPI_SND_8BIT(*p&0xF0); ST7920_SWSPI_SND_8BIT(*p<<4); p++; } U8G_DELAY(); } diff --git a/Marlin/src/lcd/dwin/dwin_lcd.cpp b/Marlin/src/lcd/dwin/dwin_lcd.cpp new file mode 100644 index 000000000000..7d1528bed19b --- /dev/null +++ b/Marlin/src/lcd/dwin/dwin_lcd.cpp @@ -0,0 +1,455 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/******************************************************************************** + * @file dwin_lcd.cpp + * @author LEO / Creality3D + * @date 2019/07/18 + * @version 2.0.1 + * @brief DWIN screen control functions + ********************************************************************************/ + +#include "../../inc/MarlinConfigPre.h" + +#if ENABLED(DWIN_CREALITY_LCD) + +#include "../../inc/MarlinConfig.h" + +#include "dwin_lcd.h" +#include // for memset + +//#define DEBUG_OUT 1 +#include "../../core/debug_out.h" + +// Make sure DWIN_SendBuf is large enough to hold the largest string plus draw command and tail. +// Assume the narrowest (6 pixel) font and 2-byte gb2312-encoded characters. +uint8_t DWIN_SendBuf[11 + DWIN_WIDTH / 6 * 2] = { 0xAA }; +uint8_t DWIN_BufTail[4] = { 0xCC, 0x33, 0xC3, 0x3C }; +uint8_t databuf[26] = { 0 }; +uint8_t receivedType; + +int recnum = 0; + +inline void DWIN_Byte(size_t &i, const uint16_t bval) { + DWIN_SendBuf[++i] = bval; +} + +inline void DWIN_Word(size_t &i, const uint16_t wval) { + DWIN_SendBuf[++i] = wval >> 8; + DWIN_SendBuf[++i] = wval & 0xFF; +} + +inline void DWIN_Long(size_t &i, const uint32_t lval) { + DWIN_SendBuf[++i] = (lval >> 24) & 0xFF; + DWIN_SendBuf[++i] = (lval >> 16) & 0xFF; + DWIN_SendBuf[++i] = (lval >> 8) & 0xFF; + DWIN_SendBuf[++i] = lval & 0xFF; +} + +inline void DWIN_String(size_t &i, char * const string) { + const size_t len = _MIN(sizeof(DWIN_SendBuf) - i, strlen(string)); + memcpy(&DWIN_SendBuf[i+1], string, len); + i += len; +} + +inline void DWIN_String(size_t &i, const __FlashStringHelper * string) { + if (!string) return; + const size_t len = strlen_P((PGM_P)string); // cast it to PGM_P, which is basically const char *, and measure it using the _P version of strlen. + if (len == 0) return; + memcpy(&DWIN_SendBuf[i+1], string, len); + i += len; +} + +// Send the data in the buffer and the packet end +inline void DWIN_Send(size_t &i) { + ++i; + LOOP_L_N(n, i) { MYSERIAL1.write(DWIN_SendBuf[n]); delayMicroseconds(1); } + LOOP_L_N(n, 4) { MYSERIAL1.write(DWIN_BufTail[n]); delayMicroseconds(1); } +} + +/*-------------------------------------- System variable function --------------------------------------*/ + +// Handshake (1: Success, 0: Fail) +bool DWIN_Handshake(void) { + size_t i = 0; + DWIN_Byte(i, 0x00); + DWIN_Send(i); + + while (MYSERIAL1.available() > 0 && recnum < (signed)sizeof(databuf)) { + databuf[recnum] = MYSERIAL1.read(); + // ignore the invalid data + if (databuf[0] != FHONE) { // prevent the program from running. + if (recnum > 0) { + recnum = 0; + ZERO(databuf); + } + continue; + } + delay(10); + recnum++; + } + + return ( recnum >= 3 + && databuf[0] == FHONE + && databuf[1] == '\0' + && databuf[2] == 'O' + && databuf[3] == 'K' ); +} + +// Set the backlight luminance +// luminance: (0x00-0xFF) +void DWIN_Backlight_SetLuminance(const uint8_t luminance) { + size_t i = 0; + DWIN_Byte(i, 0x30); + DWIN_Byte(i, _MAX(luminance, 0x1F)); + DWIN_Send(i); +} + +// Set screen display direction +// dir: 0=0°, 1=90°, 2=180°, 3=270° +void DWIN_Frame_SetDir(uint8_t dir) { + size_t i = 0; + DWIN_Byte(i, 0x34); + DWIN_Byte(i, 0x5A); + DWIN_Byte(i, 0xA5); + DWIN_Byte(i, dir); + DWIN_Send(i); +} + +// Update display +void DWIN_UpdateLCD(void) { + size_t i = 0; + DWIN_Byte(i, 0x3D); + DWIN_Send(i); +} + +/*---------------------------------------- Drawing functions ----------------------------------------*/ + +// Clear screen +// color: Clear screen color +void DWIN_Frame_Clear(const uint16_t color) { + size_t i = 0; + DWIN_Byte(i, 0x01); + DWIN_Word(i, color); + DWIN_Send(i); +} + +// Draw a point +// width: point width 0x01-0x0F +// height: point height 0x01-0x0F +// x,y: upper left point +void DWIN_Draw_Point(uint8_t width, uint8_t height, uint16_t x, uint16_t y) { + size_t i = 0; + DWIN_Byte(i, 0x02); + DWIN_Byte(i, width); + DWIN_Byte(i, height); + DWIN_Word(i, x); + DWIN_Word(i, y); + DWIN_Send(i); +} + +// Draw a line +// color: Line segment color +// xStart/yStart: Start point +// xEnd/yEnd: End point +void DWIN_Draw_Line(uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd) { + size_t i = 0; + DWIN_Byte(i, 0x03); + DWIN_Word(i, color); + DWIN_Word(i, xStart); + DWIN_Word(i, yStart); + DWIN_Word(i, xEnd); + DWIN_Word(i, yEnd); + DWIN_Send(i); +} + +// Draw a rectangle +// mode: 0=frame, 1=fill, 2=XOR fill +// color: Rectangle color +// xStart/yStart: upper left point +// xEnd/yEnd: lower right point +void DWIN_Draw_Rectangle(uint8_t mode, uint16_t color, + uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd) { + size_t i = 0; + DWIN_Byte(i, 0x05); + DWIN_Byte(i, mode); + DWIN_Word(i, color); + DWIN_Word(i, xStart); + DWIN_Word(i, yStart); + DWIN_Word(i, xEnd); + DWIN_Word(i, yEnd); + DWIN_Send(i); +} + +// Move a screen area +// mode: 0, circle shift; 1, translation +// dir: 0=left, 1=right, 2=up, 3=down +// dis: Distance +// color: Fill color +// xStart/yStart: upper left point +// xEnd/yEnd: bottom right point +void DWIN_Frame_AreaMove(uint8_t mode, uint8_t dir, uint16_t dis, + uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd) { + size_t i = 0; + DWIN_Byte(i, 0x09); + DWIN_Byte(i, (mode << 7) | dir); + DWIN_Word(i, dis); + DWIN_Word(i, color); + DWIN_Word(i, xStart); + DWIN_Word(i, yStart); + DWIN_Word(i, xEnd); + DWIN_Word(i, yEnd); + DWIN_Send(i); +} + +/*---------------------------------------- Text related functions ----------------------------------------*/ + +// Draw a string +// widthAdjust: true=self-adjust character width; false=no adjustment +// bShow: true=display background color; false=don't display background color +// size: Font size +// color: Character color +// bColor: Background color +// x/y: Upper-left coordinate of the string +// *string: The string +void DWIN_Draw_String(bool widthAdjust, bool bShow, uint8_t size, + uint16_t color, uint16_t bColor, uint16_t x, uint16_t y, char *string) { + size_t i = 0; + DWIN_Byte(i, 0x11); + // Bit 7: widthAdjust + // Bit 6: bShow + // Bit 5-4: Unused (0) + // Bit 3-0: size + DWIN_Byte(i, (widthAdjust * 0x80) | (bShow * 0x40) | size); + DWIN_Word(i, color); + DWIN_Word(i, bColor); + DWIN_Word(i, x); + DWIN_Word(i, y); + DWIN_String(i, string); + DWIN_Send(i); +} + +// Draw a positive integer +// bShow: true=display background color; false=don't display background color +// zeroFill: true=zero fill; false=no zero fill +// zeroMode: 1=leading 0 displayed as 0; 0=leading 0 displayed as a space +// size: Font size +// color: Character color +// bColor: Background color +// iNum: Number of digits +// x/y: Upper-left coordinate +// value: Integer value +void DWIN_Draw_IntValue(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color, + uint16_t bColor, uint8_t iNum, uint16_t x, uint16_t y, uint16_t value) { + size_t i = 0; + DWIN_Byte(i, 0x14); + // Bit 7: bshow + // Bit 6: 1 = signed; 0 = unsigned number; + // Bit 5: zeroFill + // Bit 4: zeroMode + // Bit 3-0: size + DWIN_Byte(i, (bShow * 0x80) | (zeroFill * 0x20) | (zeroMode * 0x10) | size); + DWIN_Word(i, color); + DWIN_Word(i, bColor); + DWIN_Byte(i, iNum); + DWIN_Byte(i, 0); // fNum + DWIN_Word(i, x); + DWIN_Word(i, y); + #if 0 + for (char count = 0; count < 8; count++) { + DWIN_Byte(i, value); + value >>= 8; + if (!(value & 0xFF)) break; + } + #else + // Write a big-endian 64 bit integer + const size_t p = i + 1; + for (char count = 8; count--;) { // 7..0 + ++i; + DWIN_SendBuf[p + count] = value; + value >>= 8; + } + #endif + + DWIN_Send(i); +} + +// Draw a floating point number +// bShow: true=display background color; false=don't display background color +// zeroFill: true=zero fill; false=no zero fill +// zeroMode: 1=leading 0 displayed as 0; 0=leading 0 displayed as a space +// size: Font size +// color: Character color +// bColor: Background color +// iNum: Number of whole digits +// fNum: Number of decimal digits +// x/y: Upper-left point +// value: Float value +void DWIN_Draw_FloatValue(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color, + uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, long value) { + //uint8_t *fvalue = (uint8_t*)&value; + size_t i = 0; + DWIN_Byte(i, 0x14); + DWIN_Byte(i, (bShow * 0x80) | (zeroFill * 0x20) | (zeroMode * 0x10) | size); + DWIN_Word(i, color); + DWIN_Word(i, bColor); + DWIN_Byte(i, iNum); + DWIN_Byte(i, fNum); + DWIN_Word(i, x); + DWIN_Word(i, y); + DWIN_Long(i, value); + /* + DWIN_Byte(i, fvalue[3]); + DWIN_Byte(i, fvalue[2]); + DWIN_Byte(i, fvalue[1]); + DWIN_Byte(i, fvalue[0]); + */ + DWIN_Send(i); +} + +/*---------------------------------------- Picture related functions ----------------------------------------*/ + +// Draw JPG and cached in #0 virtual display area +// id: Picture ID +void DWIN_JPG_ShowAndCache(const uint8_t id) { + size_t i = 0; + DWIN_Word(i, 0x2200); + DWIN_Byte(i, id); + DWIN_Send(i); // AA 23 00 00 00 00 08 00 01 02 03 CC 33 C3 3C +} + +// Draw an Icon +// libID: Icon library ID +// picID: Icon ID +// x/y: Upper-left point +void DWIN_ICON_Show(uint8_t libID, uint8_t picID, uint16_t x, uint16_t y) { + NOMORE(x, DWIN_WIDTH - 1); + NOMORE(y, DWIN_HEIGHT - 1); // -- ozy -- srl + size_t i = 0; + DWIN_Byte(i, 0x23); + DWIN_Word(i, x); + DWIN_Word(i, y); + DWIN_Byte(i, 0x80 | libID); + DWIN_Byte(i, picID); + DWIN_Send(i); +} + +// Unzip the JPG picture to a virtual display area +// n: Cache index +// id: Picture ID +void DWIN_JPG_CacheToN(uint8_t n, uint8_t id) { + size_t i = 0; + DWIN_Byte(i, 0x25); + DWIN_Byte(i, n); + DWIN_Byte(i, id); + DWIN_Send(i); +} + +// Copy area from virtual display area to current screen +// cacheID: virtual area number +// xStart/yStart: Upper-left of virtual area +// xEnd/yEnd: Lower-right of virtual area +// x/y: Screen paste point +void DWIN_Frame_AreaCopy(uint8_t cacheID, uint16_t xStart, uint16_t yStart, + uint16_t xEnd, uint16_t yEnd, uint16_t x, uint16_t y) { + size_t i = 0; + DWIN_Byte(i, 0x27); + DWIN_Byte(i, 0x80 | cacheID); + DWIN_Word(i, xStart); + DWIN_Word(i, yStart); + DWIN_Word(i, xEnd); + DWIN_Word(i, yEnd); + DWIN_Word(i, x); + DWIN_Word(i, y); + DWIN_Send(i); +} + +// Animate a series of icons +// animID: Animation ID; 0x00-0x0F +// animate: true on; false off; +// libID: Icon library ID +// picIDs: Icon starting ID +// picIDe: Icon ending ID +// x/y: Upper-left point +// interval: Display time interval, unit 10mS +void DWIN_ICON_Animation(uint8_t animID, bool animate, uint8_t libID, uint8_t picIDs, uint8_t picIDe, uint16_t x, uint16_t y, uint16_t interval) { + NOMORE(x, DWIN_WIDTH - 1); + NOMORE(y, DWIN_HEIGHT - 1); // -- ozy -- srl + size_t i = 0; + DWIN_Byte(i, 0x28); + DWIN_Word(i, x); + DWIN_Word(i, y); + // Bit 7: animation on or off + // Bit 6: start from begin or end + // Bit 5-4: unused (0) + // Bit 3-0: animID + DWIN_Byte(i, (animate * 0x80) | 0x40 | animID); + DWIN_Byte(i, libID); + DWIN_Byte(i, picIDs); + DWIN_Byte(i, picIDe); + DWIN_Byte(i, interval); + DWIN_Send(i); +} + +// Animation Control +// state: 16 bits, each bit is the state of an animation id +void DWIN_ICON_AnimationControl(uint16_t state) { + size_t i = 0; + DWIN_Byte(i, 0x28); + DWIN_Word(i, state); + DWIN_Send(i); +} + +/*---------------------------------------- Memory functions ----------------------------------------*/ +// The LCD has an additional 32KB SRAM and 16KB Flash + +// Data can be written to the sram and save to one of the jpeg page files + +// Write Data Memory +// command 0x31 +// Type: Write memory selection; 0x5A=SRAM; 0xA5=Flash +// Address: Write data memory address; 0x000-0x7FFF for SRAM; 0x000-0x3FFF for Flash +// Data: data +// +// Flash writing returns 0xA5 0x4F 0x4B + +// Read Data Memory +// command 0x32 +// Type: Read memory selection; 0x5A=SRAM; 0xA5=Flash +// Address: Read data memory address; 0x000-0x7FFF for SRAM; 0x000-0x3FFF for Flash +// Length: leangth of data to read; 0x01-0xF0 +// +// Response: +// Type, Address, Length, Data + +// Write Picture Memory +// Write the contents of the 32KB SRAM data memory into the designated image memory space +// Issued: 0x5A, 0xA5, PIC_ID +// Response: 0xA5 0x4F 0x4B +// +// command 0x33 +// 0x5A, 0xA5 +// PicId: Picture Memory location, 0x00-0x0F +// +// Flash writing returns 0xA5 0x4F 0x4B + +#endif // DWIN_CREALITY_LCD diff --git a/Marlin/src/lcd/dwin/dwin_lcd.h b/Marlin/src/lcd/dwin/dwin_lcd.h new file mode 100644 index 000000000000..9ae6d076d502 --- /dev/null +++ b/Marlin/src/lcd/dwin/dwin_lcd.h @@ -0,0 +1,213 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/******************************************************************************** + * @file dwin_lcd.h + * @author LEO / Creality3D + * @date 2019/07/18 + * @version 2.0.1 + * @brief 迪文屏控制操作函数 + ********************************************************************************/ + +#include + +#define RECEIVED_NO_DATA 0x00 +#define RECEIVED_SHAKE_HAND_ACK 0x01 + +#define FHONE 0xAA + +#define DWIN_SCROLL_UP 2 +#define DWIN_SCROLL_DOWN 3 + +#define DWIN_WIDTH 272 +#define DWIN_HEIGHT 480 + +/*-------------------------------------- System variable function --------------------------------------*/ + +// Handshake (1: Success, 0: Fail) +bool DWIN_Handshake(void); + +// Common DWIN startup +void DWIN_Startup(void); + +// Set the backlight luminance +// luminance: (0x00-0xFF) +void DWIN_Backlight_SetLuminance(const uint8_t luminance); + +// Set screen display direction +// dir: 0=0°, 1=90°, 2=180°, 3=270° +void DWIN_Frame_SetDir(uint8_t dir); + +// Update display +void DWIN_UpdateLCD(void); + +/*---------------------------------------- Drawing functions ----------------------------------------*/ + +// Clear screen +// color: Clear screen color +void DWIN_Frame_Clear(const uint16_t color); + +// Draw a point +// width: point width 0x01-0x0F +// height: point height 0x01-0x0F +// x,y: upper left point +void DWIN_Draw_Point(uint8_t width, uint8_t height, uint16_t x, uint16_t y); + +// Draw a line +// color: Line segment color +// xStart/yStart: Start point +// xEnd/yEnd: End point +void DWIN_Draw_Line(uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd); + +// Draw a Horizontal line +// color: Line segment color +// xStart/yStart: Start point +// xLength: Line Length +inline void DWIN_Draw_HLine(uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t xLength) { + DWIN_Draw_Line(color, xStart, yStart, xStart + xLength - 1, yStart); +} + +// Draw a Vertical line +// color: Line segment color +// xStart/yStart: Start point +// yLength: Line Length +inline void DWIN_Draw_VLine(uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t yLength) { + DWIN_Draw_Line(color, xStart, yStart, xStart, yStart + yLength - 1); +} + +// Draw a rectangle +// mode: 0=frame, 1=fill, 2=XOR fill +// color: Rectangle color +// xStart/yStart: upper left point +// xEnd/yEnd: lower right point +void DWIN_Draw_Rectangle(uint8_t mode, uint16_t color, + uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd); + +// Draw a box +// mode: 0=frame, 1=fill, 2=XOR fill +// color: Rectangle color +// xStart/yStart: upper left point +// xSize/ySize: box size +inline void DWIN_Draw_Box(uint8_t mode, uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t xSize, uint16_t ySize) { + DWIN_Draw_Rectangle(mode, color, xStart, yStart, xStart + xSize - 1, yStart + ySize - 1); +} + +// Move a screen area +// mode: 0, circle shift; 1, translation +// dir: 0=left, 1=right, 2=up, 3=down +// dis: Distance +// color: Fill color +// xStart/yStart: upper left point +// xEnd/yEnd: bottom right point +void DWIN_Frame_AreaMove(uint8_t mode, uint8_t dir, uint16_t dis, + uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd); + +/*---------------------------------------- Text related functions ----------------------------------------*/ + +// Draw a string +// widthAdjust: true=self-adjust character width; false=no adjustment +// bShow: true=display background color; false=don't display background color +// size: Font size +// color: Character color +// bColor: Background color +// x/y: Upper-left coordinate of the string +// *string: The string +void DWIN_Draw_String(bool widthAdjust, bool bShow, uint8_t size, + uint16_t color, uint16_t bColor, uint16_t x, uint16_t y, char *string); + +class __FlashStringHelper; + +inline void DWIN_Draw_String(bool widthAdjust, bool bShow, uint8_t size, uint16_t color, uint16_t bColor, uint16_t x, uint16_t y, const __FlashStringHelper *title) { + DWIN_Draw_String(widthAdjust, bShow, size, color, bColor, x, y, (char *)title); +} + +// Draw a positive integer +// bShow: true=display background color; false=don't display background color +// zeroFill: true=zero fill; false=no zero fill +// zeroMode: 1=leading 0 displayed as 0; 0=leading 0 displayed as a space +// size: Font size +// color: Character color +// bColor: Background color +// iNum: Number of digits +// x/y: Upper-left coordinate +// value: Integer value +void DWIN_Draw_IntValue(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color, + uint16_t bColor, uint8_t iNum, uint16_t x, uint16_t y, uint16_t value); + +// Draw a floating point number +// bShow: true=display background color; false=don't display background color +// zeroFill: true=zero fill; false=no zero fill +// zeroMode: 1=leading 0 displayed as 0; 0=leading 0 displayed as a space +// size: Font size +// color: Character color +// bColor: Background color +// iNum: Number of whole digits +// fNum: Number of decimal digits +// x/y: Upper-left point +// value: Float value +void DWIN_Draw_FloatValue(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color, + uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, long value); + +/*---------------------------------------- Picture related functions ----------------------------------------*/ + +// Draw JPG and cached in #0 virtual display area +// id: Picture ID +void DWIN_JPG_ShowAndCache(const uint8_t id); + +// Draw an Icon +// libID: Icon library ID +// picID: Icon ID +// x/y: Upper-left point +void DWIN_ICON_Show(uint8_t libID, uint8_t picID, uint16_t x, uint16_t y); + +// Unzip the JPG picture to a virtual display area +// n: Cache index +// id: Picture ID +void DWIN_JPG_CacheToN(uint8_t n, uint8_t id); + +// Unzip the JPG picture to virtual display area #1 +// id: Picture ID +inline void DWIN_JPG_CacheTo1(uint8_t id) { DWIN_JPG_CacheToN(1, id); } + +// Copy area from virtual display area to current screen +// cacheID: virtual area number +// xStart/yStart: Upper-left of virtual area +// xEnd/yEnd: Lower-right of virtual area +// x/y: Screen paste point +void DWIN_Frame_AreaCopy(uint8_t cacheID, uint16_t xStart, uint16_t yStart, + uint16_t xEnd, uint16_t yEnd, uint16_t x, uint16_t y); + +// Animate a series of icons +// animID: Animation ID up to 16 +// animate: animation on or off +// libID: Icon library ID +// picIDs: Icon starting ID +// picIDe: Icon ending ID +// x/y: Upper-left point +// interval: Display time interval, unit 10mS +void DWIN_ICON_Animation(uint8_t animID, bool animate, uint8_t libID, uint8_t picIDs, + uint8_t picIDe, uint16_t x, uint16_t y, uint16_t interval); + +// Animation Control +// state: 16 bits, each bit is the state of an animation id +void DWIN_ICON_AnimationControl(uint16_t state); diff --git a/Marlin/src/lcd/dwin/e3v2/README.md b/Marlin/src/lcd/dwin/e3v2/README.md new file mode 100644 index 000000000000..10b05455fdaf --- /dev/null +++ b/Marlin/src/lcd/dwin/e3v2/README.md @@ -0,0 +1,7 @@ +# DWIN for Creality Ender 3 v2 + +Marlin's Ender 3 v2 support requires the `DWIN_SET` included with the Ender 3 V2 [example configuration](https://github.com/MarlinFirmware/Configurations/tree/bugfix-2.0.x/config/examples/Creality/Ender-3%20V2). + +## Easy Install + +Copy the `DWIN_SET` folder onto a Micro-SD card and insert the card into the slot on the DWIN screen. Cycle the machine and wait for the screen to go from blue to orange. Turn the machine off and remove the SD card. When you turn on the machine the screen will display a "Creality" loading screen. diff --git a/Marlin/src/lcd/dwin/e3v2/dwin.cpp b/Marlin/src/lcd/dwin/e3v2/dwin.cpp new file mode 100644 index 000000000000..28087497371f --- /dev/null +++ b/Marlin/src/lcd/dwin/e3v2/dwin.cpp @@ -0,0 +1,3702 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * DWIN by Creality3D + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if ENABLED(DWIN_CREALITY_LCD) + +#include "dwin.h" + +#if ANY(AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_3POINT) && DISABLED(PROBE_MANUALLY) + #define HAS_ONESTEP_LEVELING 1 +#endif + +#if ANY(BABYSTEPPING, HAS_BED_PROBE, HAS_WORKSPACE_OFFSET) + #define HAS_ZOFFSET_ITEM 1 +#endif + +#if !HAS_BED_PROBE && ENABLED(BABYSTEPPING) + #define JUST_BABYSTEP 1 +#endif + +#include +#include +#include + +#include "../../fontutils.h" +#include "../../ultralcd.h" + +#include "../../../sd/cardreader.h" + +#include "../../../MarlinCore.h" +#include "../../../core/serial.h" +#include "../../../core/macros.h" +#include "../../../gcode/queue.h" + +#include "../../../module/temperature.h" +#include "../../../module/printcounter.h" +#include "../../../module/motion.h" +#include "../../../module/planner.h" + +#if ENABLED(EEPROM_SETTINGS) + #include "../../../module/settings.h" +#endif + +#if ENABLED(HOST_ACTION_COMMANDS) + #include "../../../feature/host_actions.h" +#endif + +#if HAS_ONESTEP_LEVELING + #include "../../../feature/bedlevel/bedlevel.h" +#endif + +#if HAS_BED_PROBE + #include "../../../module/probe.h" +#endif + +#if EITHER(BABYSTEP_ZPROBE_OFFSET, JUST_BABYSTEP) + #include "../../../feature/babystep.h" +#endif + +#if ENABLED(POWER_LOSS_RECOVERY) + #include "../../../feature/powerloss.h" +#endif + +#ifndef MACHINE_SIZE + #define MACHINE_SIZE "220x220x250" +#endif +#ifndef CORP_WEBSITE_C + #define CORP_WEBSITE_C "www.cxsw3d.com" +#endif +#ifndef CORP_WEBSITE_E + #define CORP_WEBSITE_E "www.creality.com" +#endif + +#define PAUSE_HEAT + +#define USE_STRING_HEADINGS + +#define DWIN_FONT_MENU font8x16 +#define DWIN_FONT_STAT font10x20 +#define DWIN_FONT_HEAD font10x20 + +#define MENU_CHAR_LIMIT 24 +#define STATUS_Y 360 + +// Fan speed limit +#define FANON 255 +#define FANOFF 0 + +// Print speed limit +#define MAX_PRINT_SPEED 999 +#define MIN_PRINT_SPEED 10 + +// Temp limits +#if HAS_HOTEND + #define MAX_E_TEMP (HEATER_0_MAXTEMP - (HOTEND_OVERSHOOT)) + #define MIN_E_TEMP HEATER_0_MINTEMP +#endif + +#if HAS_HEATED_BED + #define MIN_BED_TEMP BED_MINTEMP +#endif + +// Feedspeed limit (max feedspeed = DEFAULT_MAX_FEEDRATE * 2) +#define MIN_MAXFEEDSPEED 1 +#define MIN_MAXACCELERATION 1 +#define MIN_MAXJERK 0.1 +#define MIN_STEP 1 + +#define FEEDRATE_E (60) + +// Mininum unit (0.1) : multiple (10) +#define MINUNITMULT 10 + +#define ENCODER_WAIT 20 +#define DWIN_SCROLL_UPDATE_INTERVAL 2000 +#define DWIN_REMAIN_TIME_UPDATE_INTERVAL 20000 + +constexpr uint16_t TROWS = 6, MROWS = TROWS - 1, // Total rows, and other-than-Back + TITLE_HEIGHT = 30, // Title bar height + MLINE = 53, // Menu line height + LBLX = 60, // Menu item label X + MENU_CHR_W = 8, STAT_CHR_W = 10; + +#define MBASE(L) (49 + MLINE * (L)) + +#define BABY_Z_VAR TERN(HAS_BED_PROBE, probe.offset.z, dwin_zoffset) + +/* Value Init */ +HMI_value_t HMI_ValueStruct; +HMI_Flag_t HMI_flag{0}; + +millis_t dwin_heat_time = 0; + +uint8_t checkkey = 0; + +typedef struct { + uint8_t now, last; + void set(uint8_t v) { now = last = v; } + void reset() { set(0); } + bool changed() { bool c = (now != last); if (c) last = now; return c; } + bool dec() { if (now) now--; return changed(); } + bool inc(uint8_t v) { if (now < (v - 1)) now++; else now = (v - 1); return changed(); } +} select_t; + +select_t select_page{0}, select_file{0}, select_print{0}, select_prepare{0} + , select_control{0}, select_axis{0}, select_temp{0}, select_motion{0}, select_tune{0} + , select_PLA{0}, select_ABS{0} + , select_speed{0} + , select_acc{0} + , select_jerk{0} + , select_step{0} + ; + +uint8_t index_file = MROWS, + index_prepare = MROWS, + index_control = MROWS, + index_leveling = MROWS, + index_tune = MROWS; + +bool dwin_abort_flag = false; // Flag to reset feedrate, return to Home + +constexpr float default_max_feedrate[] = DEFAULT_MAX_FEEDRATE; +constexpr float default_max_acceleration[] = DEFAULT_MAX_ACCELERATION; +constexpr float default_max_jerk[] = { DEFAULT_XJERK, DEFAULT_YJERK, DEFAULT_ZJERK, DEFAULT_EJERK }; +constexpr float default_axis_steps_per_unit[] = DEFAULT_AXIS_STEPS_PER_UNIT; + +uint8_t Percentrecord = 0; +uint16_t remain_time = 0; + +#if ENABLED(PAUSE_HEAT) + #if HAS_HOTEND + uint16_t temphot = 0; + #endif + #if HAS_HEATED_BED + uint16_t tempbed = 0; + #endif +#endif + +#if HAS_ZOFFSET_ITEM + float dwin_zoffset = 0, last_zoffset = 0; +#endif + +#define DWIN_LANGUAGE_EEPROM_ADDRESS 0x01 // Between 0x01 and 0x63 (EEPROM_OFFSET-1) + // BL24CXX::check() uses 0x00 + +inline bool HMI_IsChinese() { return HMI_flag.language == DWIN_CHINESE; } + +void HMI_SetLanguageCache() { + DWIN_JPG_CacheTo1(HMI_IsChinese() ? Language_Chinese : Language_English); +} + +void HMI_SetLanguage() { + #if ENABLED(EEPROM_SETTINGS) + BL24CXX::read(DWIN_LANGUAGE_EEPROM_ADDRESS, (uint8_t*)&HMI_flag.language, sizeof(HMI_flag.language)); + #endif + HMI_SetLanguageCache(); +} + +void HMI_ToggleLanguage() { + HMI_flag.language = HMI_IsChinese() ? DWIN_ENGLISH : DWIN_CHINESE; + HMI_SetLanguageCache(); + #if ENABLED(EEPROM_SETTINGS) + BL24CXX::write(DWIN_LANGUAGE_EEPROM_ADDRESS, (uint8_t*)&HMI_flag.language, sizeof(HMI_flag.language)); + #endif +} + +void DWIN_Draw_Signed_Float(uint8_t size, uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, long value) { + if (value < 0) { + DWIN_Draw_String(false, true, size, Color_White, bColor, x - 6, y, F("-")); + DWIN_Draw_FloatValue(true, true, 0, size, Color_White, bColor, iNum, fNum, x, y, -value); + } + else { + DWIN_Draw_String(false, true, size, Color_White, bColor, x - 6, y, F(" ")); + DWIN_Draw_FloatValue(true, true, 0, size, Color_White, bColor, iNum, fNum, x, y, value); + } +} + +void ICON_Print() { + if (select_page.now == 0) { + DWIN_ICON_Show(ICON, ICON_Print_1, 17, 130); + DWIN_Draw_Rectangle(0, Color_White, 17, 130, 126, 229); + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 1, 447, 28, 460, 58, 201); + else + DWIN_Frame_AreaCopy(1, 1, 451, 31, 463, 57, 201); + } + else { + DWIN_ICON_Show(ICON, ICON_Print_0, 17, 130); + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 1, 405, 28, 420, 58, 201); + else + DWIN_Frame_AreaCopy(1, 1, 423, 31, 435, 57, 201); + } +} + +void ICON_Prepare() { + if (select_page.now == 1) { + DWIN_ICON_Show(ICON, ICON_Prepare_1, 145, 130); + DWIN_Draw_Rectangle(0, Color_White, 145, 130, 254, 229); + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 31, 447, 58, 460, 186, 201); + else + DWIN_Frame_AreaCopy(1, 33, 451, 82, 466, 175, 201); + } + else { + DWIN_ICON_Show(ICON, ICON_Prepare_0, 145, 130); + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 31, 405, 58, 420, 186, 201); + else + DWIN_Frame_AreaCopy(1, 33, 423, 82, 438, 175, 201); + } +} + +void ICON_Control() { + if (select_page.now == 2) { + DWIN_ICON_Show(ICON, ICON_Control_1, 17, 246); + DWIN_Draw_Rectangle(0, Color_White, 17, 246, 126, 345); + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 61, 447, 88, 460, 58, 318); + else + DWIN_Frame_AreaCopy(1, 85, 451, 132, 463, 48, 318); + } + else { + DWIN_ICON_Show(ICON, ICON_Control_0, 17, 246); + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 61, 405, 88, 420, 58, 318); + else + DWIN_Frame_AreaCopy(1, 85, 423, 132, 434, 48, 318); + } +} + +void ICON_StartInfo(bool show) { + if (show) { + DWIN_ICON_Show(ICON, ICON_Info_1, 145, 246); + DWIN_Draw_Rectangle(0, Color_White, 145, 246, 254, 345); + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 91, 447, 118, 460, 186, 318); + else + DWIN_Frame_AreaCopy(1, 132, 451, 159, 466, 186, 318); + } + else { + DWIN_ICON_Show(ICON, ICON_Info_0, 145, 246); + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 91, 405, 118, 420, 186, 318); + else + DWIN_Frame_AreaCopy(1, 132, 423, 159, 435, 186, 318); + } +} + +void ICON_Leveling(bool show) { + if (show) { + DWIN_ICON_Show(ICON, ICON_Leveling_1, 145, 246); + DWIN_Draw_Rectangle(0, Color_White, 145, 246, 254, 345); + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 211, 447, 238, 460, 186, 318); + else + DWIN_Frame_AreaCopy(1, 84, 437, 120, 449, 182, 318); + } + else { + DWIN_ICON_Show(ICON, ICON_Leveling_0, 145, 246); + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 211, 405, 238, 420, 186, 318); + else + DWIN_Frame_AreaCopy(1, 84, 465, 120, 478, 182, 318); + } +} + +void ICON_Tune() { + if (select_print.now == 0) { + DWIN_ICON_Show(ICON, ICON_Setup_1, 8, 252); + DWIN_Draw_Rectangle(0, Color_White, 8, 252, 87, 351); + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 121, 447, 148, 458, 34, 325); + else + DWIN_Frame_AreaCopy(1, 0, 466, 34, 476, 31, 325); + } + else { + DWIN_ICON_Show(ICON, ICON_Setup_0, 8, 252); + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 121, 405, 148, 420, 34, 325); + else + DWIN_Frame_AreaCopy(1, 0, 438, 32, 448, 31, 325); + } +} + +void ICON_Pause() { + if (select_print.now == 1) { + DWIN_ICON_Show(ICON, ICON_Pause_1, 96, 252); + DWIN_Draw_Rectangle(0, Color_White, 96, 252, 175, 351); + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 181, 447, 208, 459, 124, 325); + else + DWIN_Frame_AreaCopy(1, 177, 451, 216, 462, 116, 325); + } + else { + DWIN_ICON_Show(ICON, ICON_Pause_0, 96, 252); + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 181, 405, 208, 420, 124, 325); + else + DWIN_Frame_AreaCopy(1, 177, 423, 215, 433, 116, 325); + } +} + +void ICON_Continue() { + if (select_print.now == 1) { + DWIN_ICON_Show(ICON, ICON_Continue_1, 96, 252); + DWIN_Draw_Rectangle(0, Color_White, 96, 252, 175, 351); + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 1, 447, 28, 460, 124, 325); + else + DWIN_Frame_AreaCopy(1, 1, 452, 32, 464, 121, 325); + } + else { + DWIN_ICON_Show(ICON, ICON_Continue_0, 96, 252); + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 1, 405, 28, 420, 124, 325); + else + DWIN_Frame_AreaCopy(1, 1, 424, 31, 434, 121, 325); + } +} + +void ICON_Stop() { + if (select_print.now == 2) { + DWIN_ICON_Show(ICON, ICON_Stop_1, 184, 252); + DWIN_Draw_Rectangle(0, Color_White, 184, 252, 263, 351); + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 151, 447, 178, 459, 210, 325); + else + DWIN_Frame_AreaCopy(1, 218, 452, 249, 466, 209, 325); + } + else { + DWIN_ICON_Show(ICON, ICON_Stop_0, 184, 252); + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 151, 405, 178, 420, 210, 325); + else + DWIN_Frame_AreaCopy(1, 218, 423, 247, 436, 209, 325); + } +} + +inline void Clear_Title_Bar() { + DWIN_Draw_Rectangle(1, Color_Bg_Blue, 0, 0, DWIN_WIDTH, 30); +} + +inline void Draw_Title(const char * const title) { + DWIN_Draw_String(false, false, DWIN_FONT_HEAD, Color_White, Color_Bg_Blue, 14, 4, (char*)title); +} + +inline void Draw_Title(const __FlashStringHelper * title) { + DWIN_Draw_String(false, false, DWIN_FONT_HEAD, Color_White, Color_Bg_Blue, 14, 4, (char*)title); +} + +inline void Clear_Menu_Area() { + DWIN_Draw_Rectangle(1, Color_Bg_Black, 0, 31, DWIN_WIDTH, STATUS_Y); +} + +inline void Clear_Main_Window() { + Clear_Title_Bar(); + Clear_Menu_Area(); +} + +inline void Clear_Popup_Area() { + Clear_Title_Bar(); + DWIN_Draw_Rectangle(1, Color_Bg_Black, 0, 31, DWIN_WIDTH, DWIN_HEIGHT); +} + +void Draw_Popup_Bkgd_105() { + DWIN_Draw_Rectangle(1, Color_Bg_Window, 14, 105, 258, 374); +} + +inline void Draw_More_Icon(const uint8_t line) { + DWIN_ICON_Show(ICON, ICON_More, 226, MBASE(line) - 3); +} + +inline void Draw_Menu_Cursor(const uint8_t line) { + // DWIN_ICON_Show(ICON,ICON_Rectangle, 0, MBASE(line) - 18); + DWIN_Draw_Rectangle(1, Rectangle_Color, 0, MBASE(line) - 18, 14, MBASE(line + 1) - 20); +} + +inline void Erase_Menu_Cursor(const uint8_t line) { + DWIN_Draw_Rectangle(1, Color_Bg_Black, 0, MBASE(line) - 18, 14, MBASE(line + 1) - 20); +} + +inline void Move_Highlight(const int16_t from, const uint16_t newline) { + Erase_Menu_Cursor(newline - from); + Draw_Menu_Cursor(newline); +} + +inline void Add_Menu_Line() { + Move_Highlight(1, MROWS); + DWIN_Draw_Line(Line_Color, 16, MBASE(MROWS + 1) - 20, 256, MBASE(MROWS + 1) - 19); +} + +inline void Scroll_Menu(const uint8_t dir) { + DWIN_Frame_AreaMove(1, dir, MLINE, Color_Bg_Black, 0, 31, DWIN_WIDTH, 349); + switch (dir) { + case DWIN_SCROLL_DOWN: Move_Highlight(-1, 0); break; + case DWIN_SCROLL_UP: Add_Menu_Line(); break; + } +} + +inline uint16_t nr_sd_menu_items() { + return card.get_num_Files() + !card.flag.workDirIsRoot; +} + +inline void Draw_Menu_Icon(const uint8_t line, const uint8_t icon) { + DWIN_ICON_Show(ICON, icon, 26, MBASE(line) - 3); +} + +inline void Erase_Menu_Text(const uint8_t line) { + DWIN_Draw_Rectangle(1, Color_Bg_Black, LBLX, MBASE(line) - 14, 271, MBASE(line) + 28); +} + +inline void Draw_Menu_Line(const uint8_t line, const uint8_t icon=0, const char * const label=nullptr) { + if (label) DWIN_Draw_String(false, false, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(line) - 1, (char*)label); + if (icon) Draw_Menu_Icon(line, icon); + DWIN_Draw_Line(Line_Color, 16, MBASE(line) + 33, 256, MBASE(line) + 34); +} + +// The "Back" label is always on the first line +inline void Draw_Back_Label() { + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 129, 72, 156, 84, LBLX, MBASE(0)); + else + DWIN_Frame_AreaCopy(1, 226, 179, 256, 189, LBLX, MBASE(0)); +} + +// Draw "Back" line at the top +inline void Draw_Back_First(const bool is_sel=true) { + Draw_Menu_Line(0, ICON_Back); + Draw_Back_Label(); + if (is_sel) Draw_Menu_Cursor(0); +} + +inline bool Apply_Encoder(const ENCODER_DiffState &encoder_diffState, auto &valref) { + if (encoder_diffState == ENCODER_DIFF_CW) + valref += EncoderRate.encoderMoveValue; + else if (encoder_diffState == ENCODER_DIFF_CCW) + valref -= EncoderRate.encoderMoveValue; + else if (encoder_diffState == ENCODER_DIFF_ENTER) + return true; + return false; +} + +// +// Draw Menus +// + +#define MOTION_CASE_RATE 1 +#define MOTION_CASE_ACCEL 2 +#define MOTION_CASE_JERK (MOTION_CASE_ACCEL + ENABLED(HAS_CLASSIC_JERK)) +#define MOTION_CASE_STEPS (MOTION_CASE_JERK + 1) +#define MOTION_CASE_TOTAL MOTION_CASE_STEPS + +#define PREPARE_CASE_MOVE 1 +#define PREPARE_CASE_DISA 2 +#define PREPARE_CASE_HOME 3 +#define PREPARE_CASE_ZOFF (PREPARE_CASE_HOME + ENABLED(HAS_ZOFFSET_ITEM)) +#define PREPARE_CASE_PLA (PREPARE_CASE_ZOFF + ENABLED(HAS_HOTEND)) +#define PREPARE_CASE_ABS (PREPARE_CASE_PLA + ENABLED(HAS_HOTEND)) +#define PREPARE_CASE_COOL (PREPARE_CASE_ABS + EITHER(HAS_HOTEND, HAS_HEATED_BED)) +#define PREPARE_CASE_LANG (PREPARE_CASE_COOL + 1) +#define PREPARE_CASE_TOTAL PREPARE_CASE_LANG + +#define CONTROL_CASE_TEMP 1 +#define CONTROL_CASE_MOVE (CONTROL_CASE_TEMP + 1) +#define CONTROL_CASE_SAVE (CONTROL_CASE_MOVE + ENABLED(EEPROM_SETTINGS)) +#define CONTROL_CASE_LOAD (CONTROL_CASE_SAVE + ENABLED(EEPROM_SETTINGS)) +#define CONTROL_CASE_RESET (CONTROL_CASE_LOAD + ENABLED(EEPROM_SETTINGS)) +#define CONTROL_CASE_INFO (CONTROL_CASE_RESET + 1) +#define CONTROL_CASE_TOTAL CONTROL_CASE_INFO + +#define TUNE_CASE_SPEED 1 +#define TUNE_CASE_TEMP (TUNE_CASE_SPEED + ENABLED(HAS_HOTEND)) +#define TUNE_CASE_BED (TUNE_CASE_TEMP + ENABLED(HAS_HEATED_BED)) +#define TUNE_CASE_FAN (TUNE_CASE_BED + ENABLED(HAS_FAN)) +#define TUNE_CASE_ZOFF (TUNE_CASE_FAN + ENABLED(HAS_ZOFFSET_ITEM)) +#define TUNE_CASE_TOTAL TUNE_CASE_ZOFF + +#define TEMP_CASE_TEMP (0 + ENABLED(HAS_HOTEND)) +#define TEMP_CASE_BED (TEMP_CASE_TEMP + ENABLED(HAS_HEATED_BED)) +#define TEMP_CASE_FAN (TEMP_CASE_BED + ENABLED(HAS_FAN)) +#define TEMP_CASE_PLA (TEMP_CASE_FAN + ENABLED(HAS_HOTEND)) +#define TEMP_CASE_ABS (TEMP_CASE_PLA + ENABLED(HAS_HOTEND)) +#define TEMP_CASE_TOTAL TEMP_CASE_ABS + +#define PREHEAT_CASE_TEMP (0 + ENABLED(HAS_HOTEND)) +#define PREHEAT_CASE_BED (PREHEAT_CASE_TEMP + ENABLED(HAS_HEATED_BED)) +#define PREHEAT_CASE_FAN (PREHEAT_CASE_BED + ENABLED(HAS_FAN)) +#define PREHEAT_CASE_SAVE (PREHEAT_CASE_FAN + ENABLED(EEPROM_SETTINGS)) +#define PREHEAT_CASE_TOTAL PREHEAT_CASE_SAVE + +// +// Draw Menus +// + +inline void draw_move_en(const uint16_t line) { + DWIN_Frame_AreaCopy(1, 69, 61, 102, 71, LBLX, line); // "Move" +} + +inline void DWIN_Frame_TitleCopy(uint8_t id, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { DWIN_Frame_AreaCopy(id, x1, y1, x2, y2, 14, 8); } + +inline void Item_Prepare_Move(const uint8_t row) { + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 159, 70, 200, 84, LBLX, MBASE(row)); + else + draw_move_en(MBASE(row)); // "Move >" + Draw_Menu_Line(row, ICON_Axis); + Draw_More_Icon(row); +} + +inline void Item_Prepare_Disable(const uint8_t row) { + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 204, 70, 259, 82, LBLX, MBASE(row)); + else + DWIN_Frame_AreaCopy(1, 103, 59, 200, 74, LBLX, MBASE(row)); // "Disable Stepper" + Draw_Menu_Line(row, ICON_CloseMotor); +} + +inline void Item_Prepare_Home(const uint8_t row) { + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 0, 89, 41, 101, LBLX, MBASE(row)); + else + DWIN_Frame_AreaCopy(1, 202, 61, 271, 71, LBLX, MBASE(row)); // "Auto Home" + Draw_Menu_Line(row, ICON_Homing); +} + +#if HAS_ZOFFSET_ITEM + + inline void Item_Prepare_Offset(const uint8_t row) { + if (HMI_IsChinese()) { + #if HAS_BED_PROBE + DWIN_Frame_AreaCopy(1, 174, 164, 223, 177, LBLX, MBASE(row)); + DWIN_Draw_Signed_Float(font8x16, Color_Bg_Black, 2, 2, 202, MBASE(row), BABY_Z_VAR * 100); + #else + DWIN_Frame_AreaCopy(1, 43, 89, 98, 101, LBLX, MBASE(row)); + #endif + } + else { + #if HAS_BED_PROBE + DWIN_Frame_AreaCopy(1, 93, 179, 141, 189, LBLX, MBASE(row)); // "Z-Offset" + DWIN_Draw_Signed_Float(font8x16, Color_Bg_Black, 2, 2, 202, MBASE(row), BABY_Z_VAR * 100); + #else + DWIN_Frame_AreaCopy(1, 1, 76, 106, 86, LBLX, MBASE(row)); // "..." + #endif + } + Draw_Menu_Line(row, ICON_SetHome); + } + +#endif + +#if HAS_HOTEND + inline void Item_Prepare_PLA(const uint8_t row) { + if (HMI_IsChinese()) { + DWIN_Frame_AreaCopy(1, 100, 89, 151, 101, LBLX, MBASE(row)); + } + else { + DWIN_Frame_AreaCopy(1, 107, 76, 156, 86, LBLX, MBASE(row)); // "Preheat" + DWIN_Frame_AreaCopy(1, 157, 76, 181, 86, LBLX + 52, MBASE(row)); // "PLA" + } + Draw_Menu_Line(row, ICON_PLAPreheat); + } + + inline void Item_Prepare_ABS(const uint8_t row) { + if (HMI_IsChinese()) { + DWIN_Frame_AreaCopy(1, 180, 89, 233, 100, LBLX, MBASE(row)); + } + else { + DWIN_Frame_AreaCopy(1, 107, 76, 156, 86, LBLX, MBASE(row)); // "Preheat" + DWIN_Frame_AreaCopy(1, 172, 76, 198, 86, LBLX + 52, MBASE(row)); // "ABS" + } + Draw_Menu_Line(row, ICON_ABSPreheat); + } +#endif + +#if HAS_PREHEAT + inline void Item_Prepare_Cool(const uint8_t row) { + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 1, 104, 56, 117, LBLX, MBASE(row)); + else + DWIN_Frame_AreaCopy(1, 200, 76, 264, 86, LBLX, MBASE(row)); // "Cooldown" + Draw_Menu_Line(row, ICON_Cool); + } +#endif + +inline void Item_Prepare_Lang(const uint8_t row) { + if (HMI_IsChinese()) { + DWIN_Frame_AreaCopy(1, 239, 134, 266, 146, LBLX, MBASE(row)); + DWIN_Draw_String(false, false, font8x16, Color_White, Color_Bg_Black, 226, MBASE(row), F("CN")); + } + else { + DWIN_Frame_AreaCopy(1, 0, 194, 121, 207, LBLX, MBASE(row)); // "Language selection" + DWIN_Draw_String(false, false, font8x16, Color_White, Color_Bg_Black, 226, MBASE(row), F("EN")); + } + Draw_Menu_Icon(row, ICON_Language); +} + +inline void Draw_Prepare_Menu() { + Clear_Main_Window(); + + const int16_t scroll = MROWS - index_prepare; // Scrolled-up lines + #define PSCROL(L) (scroll + (L)) + #define PVISI(L) WITHIN(PSCROL(L), 0, MROWS) + + if (HMI_IsChinese()) { + DWIN_Frame_TitleCopy(1, 133, 1, 160, 13); // "Prepare" + } + else { + #ifdef USE_STRING_HEADINGS + Draw_Title(GET_TEXT_F(MSG_PREPARE)); + #else + DWIN_Frame_TitleCopy(1, 178, 2, 229, 14); // "Prepare" + #endif + } + + if (PVISI(0)) Draw_Back_First(select_prepare.now == 0); // < Back + if (PVISI(PREPARE_CASE_MOVE)) Item_Prepare_Move(PSCROL(PREPARE_CASE_MOVE)); // Move > + if (PVISI(PREPARE_CASE_DISA)) Item_Prepare_Disable(PSCROL(PREPARE_CASE_DISA)); // Disable Stepper + if (PVISI(PREPARE_CASE_HOME)) Item_Prepare_Home(PSCROL(PREPARE_CASE_HOME)); // Auto Home + #if HAS_ZOFFSET_ITEM + if (PVISI(PREPARE_CASE_ZOFF)) Item_Prepare_Offset(PSCROL(PREPARE_CASE_ZOFF)); // Edit Z-Offset / Babystep / Set Home Offset + #endif + #if HAS_HOTEND + if (PVISI(PREPARE_CASE_PLA)) Item_Prepare_PLA(PSCROL(PREPARE_CASE_PLA)); // Preheat PLA + if (PVISI(PREPARE_CASE_ABS)) Item_Prepare_ABS(PSCROL(PREPARE_CASE_ABS)); // Preheat ABS + #endif + #if HAS_PREHEAT + if (PVISI(PREPARE_CASE_COOL)) Item_Prepare_Cool(PSCROL(PREPARE_CASE_COOL)); // Cooldown + #endif + if (PVISI(PREPARE_CASE_LANG)) Item_Prepare_Lang(PSCROL(PREPARE_CASE_LANG)); // Language CN/EN + + if (select_prepare.now) Draw_Menu_Cursor(PSCROL(select_prepare.now)); +} + +inline void Draw_Control_Menu() { + Clear_Main_Window(); + + #if CONTROL_CASE_TOTAL >= 6 + const int16_t scroll = MROWS - index_control; // Scrolled-up lines + #define CSCROL(L) (scroll + (L)) + #else + #define CSCROL(L) (L) + #endif + #define CLINE(L) MBASE(CSCROL(L)) + #define CVISI(L) WITHIN(CSCROL(L), 0, MROWS) + + if (CVISI(0)) Draw_Back_First(select_control.now == 0); // < Back + + if (HMI_IsChinese()) { + DWIN_Frame_TitleCopy(1, 103, 1, 130, 14); // "Control" + + DWIN_Frame_AreaCopy(1, 57, 104, 84, 116, LBLX, CLINE(CONTROL_CASE_TEMP)); // Temperature > + DWIN_Frame_AreaCopy(1, 87, 104, 114, 116, LBLX, CLINE(CONTROL_CASE_MOVE)); // Motion > + + #if ENABLED(EEPROM_SETTINGS) + DWIN_Frame_AreaCopy(1, 117, 104, 172, 116, LBLX, CLINE(CONTROL_CASE_SAVE)); // Store Configuration + DWIN_Frame_AreaCopy(1, 174, 103, 229, 116, LBLX, CLINE(CONTROL_CASE_LOAD)); // Read Configuration + DWIN_Frame_AreaCopy(1, 1, 118, 56, 131, LBLX, CLINE(CONTROL_CASE_RESET)); // Reset Configuration + #endif + + if (CVISI(CONTROL_CASE_INFO)) + DWIN_Frame_AreaCopy(1, 231, 104, 258, 116, LBLX, CLINE(CONTROL_CASE_TEMP)); // Info > + } + else { + #ifdef USE_STRING_HEADINGS + Draw_Title(GET_TEXT_F(MSG_CONTROL)); + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(CONTROL_CASE_TEMP), GET_TEXT_F(MSG_TEMPERATURE)); + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(CONTROL_CASE_MOVE), GET_TEXT_F(MSG_MOTION)); + #if ENABLED(EEPROM_SETTINGS) + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(CONTROL_CASE_SAVE), GET_TEXT_F(MSG_STORE_EEPROM)); + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(CONTROL_CASE_LOAD), GET_TEXT_F(MSG_LOAD_EEPROM)); + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(CONTROL_CASE_RESET), GET_TEXT_F(MSG_RESTORE_DEFAULTS)); + #endif + if (CVISI(CONTROL_CASE_INFO)) DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(CONTROL_CASE_INFO), F("Info")); + #else + DWIN_Frame_TitleCopy(1, 128, 2, 176, 12); // "Control" + DWIN_Frame_AreaCopy(1, 1, 89, 83, 101, LBLX, CLINE(CONTROL_CASE_TEMP)); // Temperature > + DWIN_Frame_AreaCopy(1, 84, 89, 128, 99, LBLX, CLINE(CONTROL_CASE_MOVE)); // Motion > + #if ENABLED(EEPROM_SETTINGS) + DWIN_Frame_AreaCopy(1, 148, 89, 268, 101, LBLX , CLINE(CONTROL_CASE_SAVE // "Store Configuration" + DWIN_Frame_AreaCopy(1, 26, 104, 57, 114, LBLX , CLINE(CONTROL_CASE_LOAD)); // "Read" + DWIN_Frame_AreaCopy(1, 182, 89, 268, 101, LBLX + 34, CLINE(CONTROL_CASE_LOAD)); // "Configuration" + DWIN_Frame_AreaCopy(1, 59, 104, 93, 114, LBLX , CLINE(CONTROL_CASE_RESET)); // "Reset" + DWIN_Frame_AreaCopy(1, 182, 89, 268, 101, LBLX + 37, CLINE(CONTROL_CASE_RESET)); // "Configuration" + #endif + if (CVISI(CONTROL_CASE_INFO)) DWIN_Frame_AreaCopy(1, 0, 104, 25, 115, LBLX, CLINE(CONTROL_CASE_INFO)); // Info > + #endif + } + + if (select_control.now && CVISI(select_control.now)) + Draw_Menu_Cursor(CSCROL(select_control.now)); + + // Draw icons and lines + uint8_t i = 0; + #define _TEMP_ICON(N) do{ ++i; if (CVISI(i)) Draw_Menu_Line(CSCROL(i), ICON_Temperature + (N) - 1); }while(0) + + _TEMP_ICON(CONTROL_CASE_TEMP); + if (CVISI(i)) Draw_More_Icon(CSCROL(i)); + + _TEMP_ICON(CONTROL_CASE_MOVE); + Draw_More_Icon(CSCROL(i)); + + #if ENABLED(EEPROM_SETTINGS) + _TEMP_ICON(CONTROL_CASE_SAVE); + _TEMP_ICON(CONTROL_CASE_LOAD); + _TEMP_ICON(CONTROL_CASE_RESET); + #endif + + _TEMP_ICON(CONTROL_CASE_INFO); + if (CVISI(CONTROL_CASE_INFO)) Draw_More_Icon(CSCROL(i)); +} + +inline void Draw_Tune_Menu() { + Clear_Main_Window(); + + if (HMI_IsChinese()) { + DWIN_Frame_AreaCopy(1, 73, 2, 100, 13, 14, 9); + DWIN_Frame_AreaCopy(1, 116, 164, 171, 176, LBLX, MBASE(TUNE_CASE_SPEED)); + #if HAS_HOTEND + DWIN_Frame_AreaCopy(1, 1, 134, 56, 146, LBLX, MBASE(TUNE_CASE_TEMP)); + #endif + #if HAS_HEATED_BED + DWIN_Frame_AreaCopy(1, 58, 134, 113, 146, LBLX, MBASE(TUNE_CASE_BED)); + #endif + #if HAS_FAN + DWIN_Frame_AreaCopy(1, 115, 134, 170, 146, LBLX, MBASE(TUNE_CASE_FAN)); + #endif + #if HAS_ZOFFSET_ITEM + DWIN_Frame_AreaCopy(1, 174, 164, 223, 177, LBLX, MBASE(TUNE_CASE_ZOFF)); + #endif + } + else { + #ifdef USE_STRING_HEADINGS + Draw_Title(GET_TEXT_F(MSG_TUNE)); + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(TUNE_CASE_SPEED), GET_TEXT_F(MSG_SPEED)); + #if HAS_HOTEND + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(TUNE_CASE_TEMP), GET_TEXT_F(MSG_UBL_SET_TEMP_HOTEND)); + #endif + #if HAS_HEATED_BED + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(TUNE_CASE_BED), GET_TEXT_F(MSG_UBL_SET_TEMP_BED)); + #endif + #if HAS_FAN + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(TUNE_CASE_FAN), GET_TEXT_F(MSG_FAN_SPEED)); + #endif + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(TUNE_CASE_ZOFF), GET_TEXT_F(MSG_ZPROBE_ZOFFSET)); + #else + DWIN_Frame_AreaCopy(1, 94, 2, 126, 12, 14, 9); + DWIN_Frame_AreaCopy(1, 1, 179, 92, 190, LBLX, MBASE(TUNE_CASE_SPEED)); // Print speed + #if HAS_HOTEND + DWIN_Frame_AreaCopy(1, 197, 104, 238, 114, LBLX, MBASE(TUNE_CASE_TEMP)); // Hotend... + DWIN_Frame_AreaCopy(1, 1, 89, 83, 101, LBLX + 44, MBASE(TUNE_CASE_TEMP)); // ...Temperature + #endif + #if HAS_HEATED_BED + DWIN_Frame_AreaCopy(1, 240, 104, 264, 114, LBLX, MBASE(TUNE_CASE_BED)); // Bed... + DWIN_Frame_AreaCopy(1, 1, 89, 83, 101, LBLX + 27, MBASE(TUNE_CASE_BED)); // ...Temperature + #endif + #if HAS_FAN + DWIN_Frame_AreaCopy(1, 0, 119, 64, 132, LBLX, MBASE(TUNE_CASE_FAN)); // Fan speed + #endif + #if HAS_ZOFFSET_ITEM + DWIN_Frame_AreaCopy(1, 93, 179, 141, 189, LBLX, MBASE(TUNE_CASE_ZOFF)); // Z-offset + #endif + #endif + } + + Draw_Back_First(select_tune.now == 0); + if (select_tune.now) Draw_Menu_Cursor(select_tune.now); + + Draw_Menu_Line(TUNE_CASE_SPEED, ICON_Speed); + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(TUNE_CASE_SPEED), feedrate_percentage); + + #if HAS_HOTEND + Draw_Menu_Line(TUNE_CASE_TEMP, ICON_HotendTemp); + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(TUNE_CASE_TEMP), thermalManager.temp_hotend[0].target); + #endif + #if HAS_HEATED_BED + Draw_Menu_Line(TUNE_CASE_BED, ICON_BedTemp); + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(TUNE_CASE_BED), thermalManager.temp_bed.target); + #endif + #if HAS_FAN + Draw_Menu_Line(TUNE_CASE_FAN, ICON_FanSpeed); + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(TUNE_CASE_FAN), thermalManager.fan_speed[0]); + #endif + #if HAS_ZOFFSET_ITEM + Draw_Menu_Line(TUNE_CASE_ZOFF, ICON_Zoffset); + DWIN_Draw_Signed_Float(font8x16, Color_Bg_Black, 2, 2, 202, MBASE(TUNE_CASE_ZOFF), BABY_Z_VAR * 100); + #endif +} + +inline void draw_max_en(const uint16_t line) { + DWIN_Frame_AreaCopy(1, 245, 119, 269, 129, LBLX, line); // "Max" +} +inline void draw_max_accel_en(const uint16_t line) { + draw_max_en(line); + DWIN_Frame_AreaCopy(1, 1, 135, 79, 145, LBLX + 27, line); // "Acceleration" +} +inline void draw_speed_en(const uint16_t inset, const uint16_t line) { + DWIN_Frame_AreaCopy(1, 184, 119, 224, 132, LBLX + inset, line); // "Speed" +} +inline void draw_jerk_en(const uint16_t line) { + DWIN_Frame_AreaCopy(1, 64, 119, 106, 129, LBLX + 27, line); // "Jerk" +} +inline void draw_steps_per_mm(const uint16_t line) { + DWIN_Frame_AreaCopy(1, 1, 151, 101, 161, LBLX, line); // "Steps-per-mm" +} +inline void say_x(const uint16_t inset, const uint16_t line) { + DWIN_Frame_AreaCopy(1, 95, 104, 102, 114, LBLX + inset, line); // "X" +} +inline void say_y(const uint16_t inset, const uint16_t line) { + DWIN_Frame_AreaCopy(1, 104, 104, 110, 114, LBLX + inset, line); // "Y" +} +inline void say_z(const uint16_t inset, const uint16_t line) { + DWIN_Frame_AreaCopy(1, 112, 104, 120, 114, LBLX + inset, line); // "Z" +} +inline void say_e(const uint16_t inset, const uint16_t line) { + DWIN_Frame_AreaCopy(1, 237, 119, 244, 129, LBLX + inset, line); // "E" +} + +inline void Draw_Motion_Menu() { + Clear_Main_Window(); + + if (HMI_IsChinese()) { + DWIN_Frame_TitleCopy(1, 1, 16, 28, 28); // "Motion" + DWIN_Frame_AreaCopy(1, 173, 133, 228, 147, LBLX, MBASE(MOTION_CASE_RATE)); // Max speed + DWIN_Frame_AreaCopy(1, 173, 133, 200, 147, LBLX, MBASE(MOTION_CASE_ACCEL)); // Max... + DWIN_Frame_AreaCopy(1, 28, 149, 69, 161, LBLX + 27, MBASE(MOTION_CASE_ACCEL) + 1); // ...Acceleration + #if HAS_CLASSIC_JERK + DWIN_Frame_AreaCopy(1, 173, 133, 200, 147, LBLX, MBASE(MOTION_CASE_JERK)); // Max... + DWIN_Frame_AreaCopy(1, 1, 180, 28, 192, LBLX + 27, MBASE(MOTION_CASE_JERK) + 1); // ... + DWIN_Frame_AreaCopy(1, 202, 133, 228, 147, LBLX + 54, MBASE(MOTION_CASE_JERK)); // ...Jerk + #endif + DWIN_Frame_AreaCopy(1, 153, 148, 194, 161, LBLX, MBASE(MOTION_CASE_STEPS)); // Flow ratio + } + else { + #ifdef USE_STRING_HEADINGS + Draw_Title(GET_TEXT_F(MSG_MOTION)); + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(MOTION_CASE_RATE), F("Feedrate")); + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(MOTION_CASE_ACCEL), GET_TEXT_F(MSG_ACCELERATION)); + #if HAS_CLASSIC_JERK + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(MOTION_CASE_JERK), GET_TEXT_F(MSG_JERK)); + #endif + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(MOTION_CASE_STEPS), GET_TEXT_F(MSG_STEPS_PER_MM)); + #else + DWIN_Frame_TitleCopy(1, 144, 16, 189, 26); // "Motion" + draw_max_en(MBASE(MOTION_CASE_RATE)); draw_speed_en(27, MBASE(MOTION_CASE_RATE)); // "Max Speed" + draw_max_accel_en(MBASE(MOTION_CASE_ACCEL)); // "Max Acceleration" + #if HAS_CLASSIC_JERK + draw_max_en(MBASE(MOTION_CASE_JERK)); draw_jerk_en(MBASE(MOTION_CASE_JERK)); // "Max Jerk" + #endif + draw_steps_per_mm(MBASE(MOTION_CASE_STEPS)); // "Steps-per-mm" + #endif + } + + Draw_Back_First(select_motion.now == 0); + if (select_motion.now) Draw_Menu_Cursor(select_motion.now); + + uint8_t i = 0; + #define _MOTION_ICON(N) Draw_Menu_Line(++i, ICON_MaxSpeed + (N) - 1) + _MOTION_ICON(MOTION_CASE_RATE); Draw_More_Icon(i); + _MOTION_ICON(MOTION_CASE_ACCEL); Draw_More_Icon(i); + #if HAS_CLASSIC_JERK + _MOTION_ICON(MOTION_CASE_JERK); Draw_More_Icon(i); + #endif + _MOTION_ICON(MOTION_CASE_STEPS); Draw_More_Icon(i); +} + +// +// Draw Popup Windows +// +#if HAS_HOTEND || HAS_HEATED_BED + + void DWIN_Popup_Temperature(const bool toohigh) { + Clear_Popup_Area(); + Draw_Popup_Bkgd_105(); + if (toohigh) { + DWIN_ICON_Show(ICON, ICON_TempTooHigh, 102, 165); + if (HMI_IsChinese()) { + DWIN_Frame_AreaCopy(1, 103, 371, 237, 386, 52, 285); + DWIN_Frame_AreaCopy(1, 151, 389, 185, 402, 187, 285); + DWIN_Frame_AreaCopy(1, 189, 389, 271, 402, 95, 310); + } + else { + DWIN_Draw_String(false, true, font8x16, Popup_Text_Color, Color_Bg_Window, 36, 300, F("Nozzle or Bed temperature")); + DWIN_Draw_String(false, true, font8x16, Popup_Text_Color, Color_Bg_Window, 92, 300, F("is too high")); + } + } + else { + DWIN_ICON_Show(ICON, ICON_TempTooLow, 102, 165); + if (HMI_IsChinese()) { + DWIN_Frame_AreaCopy(1, 103, 371, 270, 386, 52, 285); + DWIN_Frame_AreaCopy(1, 189, 389, 271, 402, 95, 310); + } + else { + DWIN_Draw_String(false, true, font8x16, Popup_Text_Color, Color_Bg_Window, 36, 300, F("Nozzle or Bed temperature")); + DWIN_Draw_String(false, true, font8x16, Popup_Text_Color, Color_Bg_Window, 92, 300, F("is too low")); + } + } + } + +#endif + +inline void Draw_Popup_Bkgd_60() { + DWIN_Draw_Rectangle(1, Color_Bg_Window, 14, 60, 258, 330); +} + +#if HAS_HOTEND + + void Popup_Window_ETempTooLow() { + Clear_Main_Window(); + Draw_Popup_Bkgd_60(); + DWIN_ICON_Show(ICON, ICON_TempTooLow, 102, 105); + if (HMI_IsChinese()) { + DWIN_Frame_AreaCopy(1, 103, 371, 136, 386, 69, 240); + DWIN_Frame_AreaCopy(1, 170, 371, 270, 386, 102, 240); + DWIN_ICON_Show(ICON, ICON_Confirm_C, 86, 280); + } + else { + DWIN_Draw_String(false, true, font8x16, Popup_Text_Color, Color_Bg_Window, 20, 235, F("Nozzle is too cold")); + DWIN_ICON_Show(ICON, ICON_Confirm_E, 86, 280); + } + } + +#endif + +void Popup_Window_Resume() { + Clear_Popup_Area(); + Draw_Popup_Bkgd_105(); + if (HMI_IsChinese()) { + DWIN_Frame_AreaCopy(1, 160, 338, 235, 354, 98, 135); + DWIN_Frame_AreaCopy(1, 103, 321, 271, 335, 52, 192); + DWIN_ICON_Show(ICON, ICON_Cancel_C, 26, 307); + DWIN_ICON_Show(ICON, ICON_Continue_C, 146, 307); + } + else { + DWIN_Draw_String(false, true, font8x16, Popup_Text_Color, Color_Bg_Window, (272 - 8 * 14) / 2, 115, F("Continue Print")); + DWIN_Draw_String(false, true, font8x16, Popup_Text_Color, Color_Bg_Window, (272 - 8 * 22) / 2, 192, F("It looks like the last")); + DWIN_Draw_String(false, true, font8x16, Popup_Text_Color, Color_Bg_Window, (272 - 8 * 22) / 2, 212, F("file was interrupted.")); + DWIN_ICON_Show(ICON, ICON_Cancel_E, 26, 307); + DWIN_ICON_Show(ICON, ICON_Continue_E, 146, 307); + } +} + +void Popup_Window_Home(const bool parking/*=false*/) { + Clear_Main_Window(); + Draw_Popup_Bkgd_60(); + DWIN_ICON_Show(ICON, ICON_BLTouch, 101, 105); + if (HMI_IsChinese()) { + DWIN_Frame_AreaCopy(1, 0, 371, 33, 386, 85, 240); + DWIN_Frame_AreaCopy(1, 203, 286, 271, 302, 118, 240); + DWIN_Frame_AreaCopy(1, 0, 389, 150, 402, 61, 280); + } + else { + DWIN_Draw_String(false, true, font8x16, Popup_Text_Color, Color_Bg_Window, (272 - 8 * (parking ? 7 : 10)) / 2, 230, parking ? F("Parking") : F("Homing XYZ")); + DWIN_Draw_String(false, true, font8x16, Popup_Text_Color, Color_Bg_Window, (272 - 8 * 23) / 2, 260, F("Please wait until done.")); + } +} + +#if HAS_ONESTEP_LEVELING + + void Popup_Window_Leveling() { + Clear_Main_Window(); + Draw_Popup_Bkgd_60(); + DWIN_ICON_Show(ICON, ICON_AutoLeveling, 101, 105); + if (HMI_IsChinese()) { + DWIN_Frame_AreaCopy(1, 0, 371, 100, 386, 84, 240); + DWIN_Frame_AreaCopy(1, 0, 389, 150, 402, 61, 280); + } + else { + DWIN_Draw_String(false, true, font8x16, Popup_Text_Color, Color_Bg_Window, (272 - 8 * 13) / 2, 230, GET_TEXT_F(MSG_BED_LEVELING)); + DWIN_Draw_String(false, true, font8x16, Popup_Text_Color, Color_Bg_Window, (272 - 8 * 23) / 2, 260, F("Please wait until done.")); + } + } + +#endif + +void Draw_Select_Highlight(const bool sel) { + HMI_flag.select_flag = sel; + const uint16_t c1 = sel ? Select_Color : Color_Bg_Window, + c2 = sel ? Color_Bg_Window : Select_Color; + DWIN_Draw_Rectangle(0, c1, 25, 279, 126, 318); + DWIN_Draw_Rectangle(0, c1, 24, 278, 127, 319); + DWIN_Draw_Rectangle(0, c2, 145, 279, 246, 318); + DWIN_Draw_Rectangle(0, c2, 144, 278, 247, 319); +} + +void Popup_window_PauseOrStop() { + Clear_Main_Window(); + Draw_Popup_Bkgd_60(); + if (HMI_IsChinese()) { + if (select_print.now == 1) DWIN_Frame_AreaCopy(1, 237, 338, 269, 356, 98, 150); + else if (select_print.now == 2) DWIN_Frame_AreaCopy(1, 221, 320, 253, 336, 98, 150); + DWIN_Frame_AreaCopy(1, 220, 304, 264, 319, 130, 150); + DWIN_ICON_Show(ICON, ICON_Confirm_C, 26, 280); + DWIN_ICON_Show(ICON, ICON_Cancel_C, 146, 280); + } + else { + if (select_print.now == 1) DWIN_Draw_String(false, true, font8x16, Popup_Text_Color, Color_Bg_Window, (272 - 8 * 11) / 2, 150, GET_TEXT_F(MSG_PAUSE_PRINT)); + else if (select_print.now == 2) DWIN_Draw_String(false, true, font8x16, Popup_Text_Color, Color_Bg_Window, (272 - 8 * 10) / 2, 150, GET_TEXT_F(MSG_STOP_PRINT)); + DWIN_ICON_Show(ICON, ICON_Confirm_E, 26, 280); + DWIN_ICON_Show(ICON, ICON_Cancel_E, 146, 280); + } + Draw_Select_Highlight(true); +} + +void Draw_Printing_Screen() { + if (HMI_IsChinese()) { + DWIN_Frame_AreaCopy(1, 30, 1, 71, 14, 14, 9); // Tune + DWIN_Frame_AreaCopy(1, 0, 72, 63, 86, 41, 188); // Pause + DWIN_Frame_AreaCopy(1, 65, 72, 128, 86, 176, 188); // Stop + } + else { + DWIN_Frame_AreaCopy(1, 40, 2, 92, 14, 14, 9); // Tune + DWIN_Frame_AreaCopy(1, 0, 44, 96, 58, 41, 188); // Pause + DWIN_Frame_AreaCopy(1, 98, 44, 152, 58, 176, 188); // Stop + } +} + +void Draw_Print_ProgressBar() { + DWIN_ICON_Show(ICON, ICON_Bar, 15, 93); + DWIN_Draw_Rectangle(1, BarFill_Color, 16 + Percentrecord * 240 / 100, 93, 256, 113); + DWIN_Draw_IntValue(true, true, 0, font8x16, Percent_Color, Color_Bg_Black, 2, 117, 133, Percentrecord); + DWIN_Draw_String(false, false, font8x16, Percent_Color, Color_Bg_Black, 133, 133, F("%")); +} + +void Draw_Print_ProgressElapsed() { + duration_t elapsed = print_job_timer.duration(); // print timer + DWIN_Draw_IntValue(true, true, 1, font8x16, Color_White, Color_Bg_Black, 2, 42, 212, elapsed.value / 3600); + DWIN_Draw_String(false, false, font8x16, Color_White, Color_Bg_Black, 58, 212, F(":")); + DWIN_Draw_IntValue(true, true, 1, font8x16, Color_White, Color_Bg_Black, 2, 66, 212, (elapsed.value % 3600) / 60); +} + +void Draw_Print_ProgressRemain() { + DWIN_Draw_IntValue(true, true, 1, font8x16, Color_White, Color_Bg_Black, 2, 176, 212, remain_time / 3600); + DWIN_Draw_String(false, false, font8x16, Color_White, Color_Bg_Black, 192, 212, F(":")); + DWIN_Draw_IntValue(true, true, 1, font8x16, Color_White, Color_Bg_Black, 2, 200, 212, (remain_time % 3600) / 60); +} + +void Goto_PrintProcess() { + checkkey = PrintProcess; + + Clear_Main_Window(); + Draw_Printing_Screen(); + + ICON_Tune(); + if (printingIsPaused()) ICON_Continue(); else ICON_Pause(); + ICON_Stop(); + + // Copy into filebuf string before entry + char * const name = card.longest_filename(); + const int8_t npos = _MAX(0U, DWIN_WIDTH - strlen(name) * MENU_CHR_W) / 2; + DWIN_Draw_String(false, false, font8x16, Color_White, Color_Bg_Black, npos, 60, name); + + DWIN_ICON_Show(ICON, ICON_PrintTime, 17, 193); + DWIN_ICON_Show(ICON, ICON_RemainTime, 150, 191); + + Draw_Print_ProgressBar(); + Draw_Print_ProgressElapsed(); + Draw_Print_ProgressRemain(); +} + +void Goto_MainMenu() { + checkkey = MainMenu; + + Clear_Main_Window(); + + if (HMI_IsChinese()) { + DWIN_Frame_AreaCopy(1, 2, 2, 27, 14, 14, 9); // "Home" + } + else { + #ifdef USE_STRING_HEADINGS + Draw_Title(GET_TEXT_F(MSG_MAIN)); + #else + DWIN_Frame_AreaCopy(1, 0, 2, 39, 12, 14, 9); + #endif + } + + DWIN_ICON_Show(ICON, ICON_LOGO, 71, 52); + + ICON_Print(); + ICON_Prepare(); + ICON_Control(); + TERN(HAS_ONESTEP_LEVELING, ICON_Leveling, ICON_StartInfo)(select_page.now == 3); +} + +inline ENCODER_DiffState get_encoder_state() { + static millis_t Encoder_ms = 0; + const millis_t ms = millis(); + if (PENDING(ms, Encoder_ms)) return ENCODER_DIFF_NO; + const ENCODER_DiffState state = Encoder_ReceiveAnalyze(); + if (state != ENCODER_DIFF_NO) Encoder_ms = ms + ENCODER_WAIT; + return state; +} + +void HMI_Move_X() { + ENCODER_DiffState encoder_diffState = Encoder_ReceiveAnalyze(); + if (encoder_diffState != ENCODER_DIFF_NO) { + if (Apply_Encoder(encoder_diffState, HMI_ValueStruct.Move_X_scale)) { + checkkey = AxisMove; + EncoderRate.enabled = false; + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 1, 216, MBASE(1), HMI_ValueStruct.Move_X_scale); + if (!planner.is_full()) { + // Wait for planner moves to finish! + planner.synchronize(); + planner.buffer_line(current_position, MMM_TO_MMS(HOMING_FEEDRATE_XY), active_extruder); + } + DWIN_UpdateLCD(); + return; + } + NOLESS(HMI_ValueStruct.Move_X_scale, (X_MIN_POS) * MINUNITMULT); + NOMORE(HMI_ValueStruct.Move_X_scale, (X_MAX_POS) * MINUNITMULT); + current_position.x = HMI_ValueStruct.Move_X_scale / 10; + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 1, 216, MBASE(1), HMI_ValueStruct.Move_X_scale); + DWIN_UpdateLCD(); + } +} + +void HMI_Move_Y() { + ENCODER_DiffState encoder_diffState = Encoder_ReceiveAnalyze(); + if (encoder_diffState != ENCODER_DIFF_NO) { + if (Apply_Encoder(encoder_diffState, HMI_ValueStruct.Move_Y_scale)) { + checkkey = AxisMove; + EncoderRate.enabled = false; + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 1, 216, MBASE(2), HMI_ValueStruct.Move_Y_scale); + if (!planner.is_full()) { + // Wait for planner moves to finish! + planner.synchronize(); + planner.buffer_line(current_position, MMM_TO_MMS(HOMING_FEEDRATE_XY), active_extruder); + } + DWIN_UpdateLCD(); + return; + } + NOLESS(HMI_ValueStruct.Move_Y_scale, (Y_MIN_POS) * MINUNITMULT); + NOMORE(HMI_ValueStruct.Move_Y_scale, (Y_MAX_POS) * MINUNITMULT); + current_position.y = HMI_ValueStruct.Move_Y_scale / 10; + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 1, 216, MBASE(2), HMI_ValueStruct.Move_Y_scale); + DWIN_UpdateLCD(); + } +} + +void HMI_Move_Z() { + ENCODER_DiffState encoder_diffState = Encoder_ReceiveAnalyze(); + if (encoder_diffState != ENCODER_DIFF_NO) { + if (Apply_Encoder(encoder_diffState, HMI_ValueStruct.Move_Z_scale)) { + checkkey = AxisMove; + EncoderRate.enabled = false; + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 1, 216, MBASE(3), HMI_ValueStruct.Move_Z_scale); + if (!planner.is_full()) { + // Wait for planner moves to finish! + planner.synchronize(); + planner.buffer_line(current_position, MMM_TO_MMS(HOMING_FEEDRATE_Z), active_extruder); + } + DWIN_UpdateLCD(); + return; + } + NOLESS(HMI_ValueStruct.Move_Z_scale, Z_MIN_POS * MINUNITMULT); + NOMORE(HMI_ValueStruct.Move_Z_scale, Z_MAX_POS * MINUNITMULT); + current_position.z = HMI_ValueStruct.Move_Z_scale / 10; + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 1, 216, MBASE(3), HMI_ValueStruct.Move_Z_scale); + DWIN_UpdateLCD(); + } +} + +#if HAS_HOTEND + + void HMI_Move_E() { + static float last_E_scale = 0; + ENCODER_DiffState encoder_diffState = Encoder_ReceiveAnalyze(); + if (encoder_diffState != ENCODER_DIFF_NO) { + if (Apply_Encoder(encoder_diffState, HMI_ValueStruct.Move_E_scale)) { + checkkey = AxisMove; + EncoderRate.enabled = false; + last_E_scale = HMI_ValueStruct.Move_E_scale; + DWIN_Draw_Signed_Float(font8x16, Color_Bg_Black, 3, 1, 216, MBASE(4), HMI_ValueStruct.Move_E_scale); + if (!planner.is_full()) { + planner.synchronize(); // Wait for planner moves to finish! + planner.buffer_line(current_position, MMM_TO_MMS(FEEDRATE_E), active_extruder); + } + DWIN_UpdateLCD(); + return; + } + if ((HMI_ValueStruct.Move_E_scale - last_E_scale) > (EXTRUDE_MAXLENGTH) * MINUNITMULT) + HMI_ValueStruct.Move_E_scale = last_E_scale + (EXTRUDE_MAXLENGTH) * MINUNITMULT; + else if ((last_E_scale - HMI_ValueStruct.Move_E_scale) > (EXTRUDE_MAXLENGTH) * MINUNITMULT) + HMI_ValueStruct.Move_E_scale = last_E_scale - (EXTRUDE_MAXLENGTH) * MINUNITMULT; + current_position.e = HMI_ValueStruct.Move_E_scale / 10; + DWIN_Draw_Signed_Float(font8x16, Select_Color, 3, 1, 216, MBASE(4), HMI_ValueStruct.Move_E_scale); + DWIN_UpdateLCD(); + } + } + +#endif + +#if HAS_ZOFFSET_ITEM + + bool printer_busy() { return planner.movesplanned() || printingIsActive(); } + + void HMI_Zoffset() { + ENCODER_DiffState encoder_diffState = Encoder_ReceiveAnalyze(); + if (encoder_diffState != ENCODER_DIFF_NO) { + uint8_t zoff_line; + switch (HMI_ValueStruct.show_mode) { + case -4: zoff_line = PREPARE_CASE_ZOFF + MROWS - index_prepare; break; + default: zoff_line = TUNE_CASE_ZOFF + MROWS - index_tune; + } + if (Apply_Encoder(encoder_diffState, HMI_ValueStruct.offset_value)) { + EncoderRate.enabled = false; + #if HAS_BED_PROBE + probe.offset.z = dwin_zoffset; + TERN_(EEPROM_SETTINGS, settings.save()); + #endif + if (HMI_ValueStruct.show_mode == -4) { + checkkey = Prepare; + DWIN_Draw_Signed_Float(font8x16, Color_Bg_Black, 2, 2, 202, MBASE(zoff_line), TERN(HAS_BED_PROBE, BABY_Z_VAR * 100, HMI_ValueStruct.offset_value)); + } + else { + checkkey = Tune; + DWIN_Draw_Signed_Float(font8x16, Color_Bg_Black, 2, 2, 202, MBASE(zoff_line), TERN(HAS_BED_PROBE, BABY_Z_VAR * 100, HMI_ValueStruct.offset_value)); + } + DWIN_UpdateLCD(); + return; + } + NOLESS(HMI_ValueStruct.offset_value, (Z_PROBE_OFFSET_RANGE_MIN) * 100); + NOMORE(HMI_ValueStruct.offset_value, (Z_PROBE_OFFSET_RANGE_MAX) * 100); + last_zoffset = dwin_zoffset; + dwin_zoffset = HMI_ValueStruct.offset_value / 100.0f; + #if EITHER(BABYSTEP_ZPROBE_OFFSET, JUST_BABYSTEP) + if ( (ENABLED(BABYSTEP_WITHOUT_HOMING) || all_axes_known()) && (ENABLED(BABYSTEP_ALWAYS_AVAILABLE) || printer_busy()) ) + babystep.add_mm(Z_AXIS, dwin_zoffset - last_zoffset); + #endif + DWIN_Draw_Signed_Float(font8x16, Select_Color, 2, 2, 202, MBASE(zoff_line), HMI_ValueStruct.offset_value); + DWIN_UpdateLCD(); + } + } + +#endif // HAS_ZOFFSET_ITEM + +#if HAS_HOTEND + + void HMI_ETemp() { + ENCODER_DiffState encoder_diffState = Encoder_ReceiveAnalyze(); + if (encoder_diffState != ENCODER_DIFF_NO) { + uint8_t temp_line; + switch (HMI_ValueStruct.show_mode) { + case -1: temp_line = TEMP_CASE_TEMP; break; + case -2: temp_line = PREHEAT_CASE_TEMP; break; + case -3: temp_line = PREHEAT_CASE_TEMP; break; + default: temp_line = TUNE_CASE_TEMP + MROWS - index_tune; + } + if (Apply_Encoder(encoder_diffState, HMI_ValueStruct.E_Temp)) { + EncoderRate.enabled = false; + if (HMI_ValueStruct.show_mode == -1) { // temperature + checkkey = TemperatureID; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(temp_line), HMI_ValueStruct.E_Temp); + } + else if (HMI_ValueStruct.show_mode == -2) { + checkkey = PLAPreheat; + ui.material_preset[0].hotend_temp = HMI_ValueStruct.E_Temp; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(temp_line), ui.material_preset[0].hotend_temp); + return; + } + else if (HMI_ValueStruct.show_mode == -3) { + checkkey = ABSPreheat; + ui.material_preset[1].hotend_temp = HMI_ValueStruct.E_Temp; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(temp_line), ui.material_preset[1].hotend_temp); + return; + } + else { // tune + checkkey = Tune; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(temp_line), HMI_ValueStruct.E_Temp); + } + thermalManager.setTargetHotend(HMI_ValueStruct.E_Temp, 0); + return; + } + // E_Temp limit + NOMORE(HMI_ValueStruct.E_Temp, MAX_E_TEMP); + NOLESS(HMI_ValueStruct.E_Temp, MIN_E_TEMP); + // E_Temp value + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 216, MBASE(temp_line), HMI_ValueStruct.E_Temp); + } + } + +#endif // HAS_HOTEND + +#if HAS_HEATED_BED + + void HMI_BedTemp() { + ENCODER_DiffState encoder_diffState = Encoder_ReceiveAnalyze(); + if (encoder_diffState != ENCODER_DIFF_NO) { + uint8_t bed_line; + switch (HMI_ValueStruct.show_mode) { + case -1: bed_line = TEMP_CASE_BED; break; + case -2: bed_line = PREHEAT_CASE_BED; break; + case -3: bed_line = PREHEAT_CASE_BED; break; + default: bed_line = TUNE_CASE_BED + MROWS - index_tune; + } + if (Apply_Encoder(encoder_diffState, HMI_ValueStruct.Bed_Temp)) { + EncoderRate.enabled = false; + if (HMI_ValueStruct.show_mode == -1) { + checkkey = TemperatureID; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(bed_line), HMI_ValueStruct.Bed_Temp); + } + else if (HMI_ValueStruct.show_mode == -2) { + checkkey = PLAPreheat; + ui.material_preset[0].bed_temp = HMI_ValueStruct.Bed_Temp; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(bed_line), ui.material_preset[0].bed_temp); + return; + } + else if (HMI_ValueStruct.show_mode == -3) { + checkkey = ABSPreheat; + ui.material_preset[1].bed_temp = HMI_ValueStruct.Bed_Temp; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(bed_line), ui.material_preset[1].bed_temp); + return; + } + else { + checkkey = Tune; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(bed_line), HMI_ValueStruct.Bed_Temp); + } + thermalManager.setTargetBed(HMI_ValueStruct.Bed_Temp); + return; + } + // Bed_Temp limit + NOMORE(HMI_ValueStruct.Bed_Temp, BED_MAX_TARGET); + NOLESS(HMI_ValueStruct.Bed_Temp, MIN_BED_TEMP); + // Bed_Temp value + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 216, MBASE(bed_line), HMI_ValueStruct.Bed_Temp); + } + } + +#endif // HAS_HEATED_BED + +#if HAS_PREHEAT + + void HMI_FanSpeed() { + ENCODER_DiffState encoder_diffState = Encoder_ReceiveAnalyze(); + if (encoder_diffState != ENCODER_DIFF_NO) { + uint8_t fan_line; + switch (HMI_ValueStruct.show_mode) { + case -1: fan_line = TEMP_CASE_FAN; break; + case -2: fan_line = PREHEAT_CASE_FAN; break; + case -3: fan_line = PREHEAT_CASE_FAN; break; + default: fan_line = TUNE_CASE_FAN + MROWS - index_tune; + } + + if (Apply_Encoder(encoder_diffState, HMI_ValueStruct.Fan_speed)) { + EncoderRate.enabled = false; + if (HMI_ValueStruct.show_mode == -1) { + checkkey = TemperatureID; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(fan_line), HMI_ValueStruct.Fan_speed); + } + else if (HMI_ValueStruct.show_mode == -2) { + checkkey = PLAPreheat; + ui.material_preset[0].fan_speed = HMI_ValueStruct.Fan_speed; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(fan_line), ui.material_preset[0].fan_speed); + return; + } + else if (HMI_ValueStruct.show_mode == -3) { + checkkey = ABSPreheat; + ui.material_preset[1].fan_speed = HMI_ValueStruct.Fan_speed; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(fan_line), ui.material_preset[1].fan_speed); + return; + } + else { + checkkey = Tune; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(fan_line), HMI_ValueStruct.Fan_speed); + } + thermalManager.set_fan_speed(0, HMI_ValueStruct.Fan_speed); + return; + } + // Fan_speed limit + NOMORE(HMI_ValueStruct.Fan_speed, FANON); + NOLESS(HMI_ValueStruct.Fan_speed, FANOFF); + // Fan_speed value + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 216, MBASE(fan_line), HMI_ValueStruct.Fan_speed); + } + } + +#endif // HAS_PREHEAT + +void HMI_PrintSpeed() { + ENCODER_DiffState encoder_diffState = Encoder_ReceiveAnalyze(); + if (encoder_diffState != ENCODER_DIFF_NO) { + if (Apply_Encoder(encoder_diffState, HMI_ValueStruct.print_speed)) { + checkkey = Tune; + EncoderRate.enabled = false; + feedrate_percentage = HMI_ValueStruct.print_speed; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(select_tune.now + MROWS - index_tune), HMI_ValueStruct.print_speed); + return; + } + // print_speed limit + NOMORE(HMI_ValueStruct.print_speed, MAX_PRINT_SPEED); + NOLESS(HMI_ValueStruct.print_speed, MIN_PRINT_SPEED); + // print_speed value + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 216, MBASE(select_tune.now + MROWS - index_tune), HMI_ValueStruct.print_speed); + } +} + +void HMI_MaxFeedspeedXYZE() { + ENCODER_DiffState encoder_diffState = Encoder_ReceiveAnalyze(); + if (encoder_diffState != ENCODER_DIFF_NO) { + if (Apply_Encoder(encoder_diffState, HMI_ValueStruct.Max_Feedspeed)) { + checkkey = MaxSpeed; + EncoderRate.enabled = false; + if (WITHIN(HMI_flag.feedspeed_axis, X_AXIS, E_AXIS)) + planner.set_max_feedrate(HMI_flag.feedspeed_axis, HMI_ValueStruct.Max_Feedspeed); + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 4, 210, MBASE(select_speed.now), HMI_ValueStruct.Max_Feedspeed); + return; + } + // MaxFeedspeed limit + if (WITHIN(HMI_flag.feedspeed_axis, X_AXIS, E_AXIS)) + NOMORE(HMI_ValueStruct.Max_Feedspeed, default_max_feedrate[HMI_flag.feedspeed_axis] * 2); + if (HMI_ValueStruct.Max_Feedspeed < MIN_MAXFEEDSPEED) HMI_ValueStruct.Max_Feedspeed = MIN_MAXFEEDSPEED; + // MaxFeedspeed value + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Select_Color, 4, 210, MBASE(select_speed.now), HMI_ValueStruct.Max_Feedspeed); + } +} + +void HMI_MaxAccelerationXYZE() { + ENCODER_DiffState encoder_diffState = Encoder_ReceiveAnalyze(); + if (encoder_diffState != ENCODER_DIFF_NO) { + if (Apply_Encoder(encoder_diffState, HMI_ValueStruct.Max_Acceleration)) { + checkkey = MaxAcceleration; + EncoderRate.enabled = false; + if (HMI_flag.acc_axis == X_AXIS) planner.set_max_acceleration(X_AXIS, HMI_ValueStruct.Max_Acceleration); + else if (HMI_flag.acc_axis == Y_AXIS) planner.set_max_acceleration(Y_AXIS, HMI_ValueStruct.Max_Acceleration); + else if (HMI_flag.acc_axis == Z_AXIS) planner.set_max_acceleration(Z_AXIS, HMI_ValueStruct.Max_Acceleration); + #if HAS_HOTEND + else if (HMI_flag.acc_axis == E_AXIS) planner.set_max_acceleration(E_AXIS, HMI_ValueStruct.Max_Acceleration); + #endif + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 4, 210, MBASE(select_acc.now), HMI_ValueStruct.Max_Acceleration); + return; + } + // MaxAcceleration limit + if (WITHIN(HMI_flag.acc_axis, X_AXIS, E_AXIS)) + NOMORE(HMI_ValueStruct.Max_Acceleration, default_max_acceleration[HMI_flag.acc_axis] * 2); + if (HMI_ValueStruct.Max_Acceleration < MIN_MAXACCELERATION) HMI_ValueStruct.Max_Acceleration = MIN_MAXACCELERATION; + // MaxAcceleration value + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Select_Color, 4, 210, MBASE(select_acc.now), HMI_ValueStruct.Max_Acceleration); + } +} + +#if HAS_CLASSIC_JERK + + void HMI_MaxJerkXYZE() { + ENCODER_DiffState encoder_diffState = Encoder_ReceiveAnalyze(); + if (encoder_diffState != ENCODER_DIFF_NO) { + if (Apply_Encoder(encoder_diffState, HMI_ValueStruct.Max_Jerk)) { + checkkey = MaxJerk; + EncoderRate.enabled = false; + if (WITHIN(HMI_flag.step_axis, X_AXIS, E_AXIS)) + planner.set_max_jerk(HMI_flag.step_axis, HMI_ValueStruct.Max_Jerk / 10); + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 1, 210, MBASE(select_jerk.now), HMI_ValueStruct.Max_Jerk); + return; + } + // MaxJerk limit + if (WITHIN(HMI_flag.jerk_axis, X_AXIS, E_AXIS)) + NOMORE(HMI_ValueStruct.Max_Jerk, default_max_jerk[HMI_flag.jerk_axis] * 2 * MINUNITMULT); + NOLESS(HMI_ValueStruct.Max_Jerk, (MIN_MAXJERK) * MINUNITMULT); + // MaxJerk value + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 1, 210, MBASE(select_jerk.now), HMI_ValueStruct.Max_Jerk); + } + } + +#endif // HAS_CLASSIC_JERK + +void HMI_StepXYZE() { + ENCODER_DiffState encoder_diffState = Encoder_ReceiveAnalyze(); + if (encoder_diffState != ENCODER_DIFF_NO) { + if (Apply_Encoder(encoder_diffState, HMI_ValueStruct.Max_Step)) { + checkkey = Step; + EncoderRate.enabled = false; + if (WITHIN(HMI_flag.step_axis, X_AXIS, E_AXIS)) + planner.settings.axis_steps_per_mm[HMI_flag.step_axis] = HMI_ValueStruct.Max_Step / 10; + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 1, 210, MBASE(select_step.now), HMI_ValueStruct.Max_Step); + return; + } + // Step limit + if (WITHIN(HMI_flag.step_axis, X_AXIS, E_AXIS)) + NOMORE(HMI_ValueStruct.Max_Step, default_axis_steps_per_unit[HMI_flag.step_axis] * 2 * MINUNITMULT); + NOLESS(HMI_ValueStruct.Max_Step, MIN_STEP); + // Step value + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 1, 210, MBASE(select_step.now), HMI_ValueStruct.Max_Step); + } +} + +void update_variable() { + #if HAS_HOTEND + static float last_temp_hotend_target = 0, last_temp_hotend_current = 0; + #endif + #if HAS_HEATED_BED + static float last_temp_bed_target = 0, last_temp_bed_current = 0; + #endif + #if HAS_FAN + static uint8_t last_fan_speed = 0; + #endif + + /* Tune page temperature update */ + if (checkkey == Tune) { + #if HAS_HOTEND + if (last_temp_hotend_target != thermalManager.temp_hotend[0].target) + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(TUNE_CASE_TEMP + MROWS - index_tune), thermalManager.temp_hotend[0].target); + #endif + #if HAS_HEATED_BED + if (last_temp_bed_target != thermalManager.temp_bed.target) + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(TUNE_CASE_BED + MROWS - index_tune), thermalManager.temp_bed.target); + #endif + #if HAS_FAN + if (last_fan_speed != thermalManager.fan_speed[0]) { + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(TUNE_CASE_FAN + MROWS - index_tune), thermalManager.fan_speed[0]); + last_fan_speed = thermalManager.fan_speed[0]; + } + #endif + } + + /* Temperature page temperature update */ + if (checkkey == TemperatureID) { + #if HAS_HOTEND + if (last_temp_hotend_target != thermalManager.temp_hotend[0].target) + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(TEMP_CASE_TEMP), thermalManager.temp_hotend[0].target); + #endif + #if HAS_HEATED_BED + if (last_temp_bed_target != thermalManager.temp_bed.target) + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(TEMP_CASE_BED), thermalManager.temp_bed.target); + #endif + #if HAS_FAN + if (last_fan_speed != thermalManager.fan_speed[0]) { + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(TEMP_CASE_FAN), thermalManager.fan_speed[0]); + last_fan_speed = thermalManager.fan_speed[0]; + } + #endif + } + + /* Bottom temperature update */ + #if HAS_HOTEND + if (last_temp_hotend_current != thermalManager.temp_hotend[0].celsius) { + DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_STAT, Color_White, Color_Bg_Black, 3, 33, 382, thermalManager.temp_hotend[0].celsius); + last_temp_hotend_current = thermalManager.temp_hotend[0].celsius; + } + if (last_temp_hotend_target != thermalManager.temp_hotend[0].target) { + DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_STAT, Color_White, Color_Bg_Black, 3, 33 + 4 * STAT_CHR_W + 6, 382, thermalManager.temp_hotend[0].target); + last_temp_hotend_target = thermalManager.temp_hotend[0].target; + } + #endif + #if HAS_HEATED_BED + if (last_temp_bed_current != thermalManager.temp_bed.celsius) { + DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_STAT, Color_White, Color_Bg_Black, 3, 178, 382, thermalManager.temp_bed.celsius); + last_temp_bed_current = thermalManager.temp_bed.celsius; + } + if (last_temp_bed_target != thermalManager.temp_bed.target) { + DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_STAT, Color_White, Color_Bg_Black, 3, 178 + 4 * STAT_CHR_W + 6, 382, thermalManager.temp_bed.target); + last_temp_bed_target = thermalManager.temp_bed.target; + } + #endif + static uint16_t last_speed = 0; + if (last_speed != feedrate_percentage) { + DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_STAT, Color_White, Color_Bg_Black, 3, 33 + 2 * STAT_CHR_W, 429, feedrate_percentage); + last_speed = feedrate_percentage; + } + #if HAS_ZOFFSET_ITEM + if (last_zoffset != BABY_Z_VAR) { + DWIN_Draw_Signed_Float(DWIN_FONT_STAT, Color_Bg_Black, 2, 2, 178 + STAT_CHR_W, 429, BABY_Z_VAR * 100); + last_zoffset = BABY_Z_VAR; + } + #endif +} + +/** + * Read and cache the working directory. + * + * TODO: New code can follow the pattern of menu_media.cpp + * and rely on Marlin caching for performance. No need to + * cache files here. + */ + +#ifndef strcasecmp_P + #define strcasecmp_P(a, b) strcasecmp((a), (b)) +#endif + +inline void make_name_without_ext(char *dst, char *src, size_t maxlen=MENU_CHAR_LIMIT) { + char * const name = card.longest_filename(); + size_t pos = strlen(name); // index of ending nul + + // For files, remove the extension + // which may be .gcode, .gco, or .g + if (!card.flag.filenameIsDir) + while (pos && src[pos] != '.') pos--; // find last '.' (stop at 0) + + size_t len = pos; // nul or '.' + if (len > maxlen) { // Keep the name short + pos = len = maxlen; // move nul down + dst[--pos] = '.'; // insert dots + dst[--pos] = '.'; + dst[--pos] = '.'; + } + + dst[len] = '\0'; // end it + + // Copy down to 0 + while (pos--) dst[pos] = src[pos]; +} + +inline void HMI_SDCardInit() { card.cdroot(); } + +void MarlinUI::refresh() { /* Nothing to see here */ } + +#define ICON_Folder ICON_More + +#if ENABLED(SCROLL_LONG_FILENAMES) + + char shift_name[LONG_FILENAME_LENGTH + 1]; + int8_t shift_amt; // = 0 + millis_t shift_ms; // = 0 + + // Init the shift name based on the highlighted item + inline void Init_Shift_Name() { + const bool is_subdir = !card.flag.workDirIsRoot; + const int8_t filenum = select_file.now - 1 - is_subdir; // Skip "Back" and ".." + const uint16_t fileCnt = card.get_num_Files(); + if (WITHIN(filenum, 0, fileCnt - 1)) { + card.getfilename_sorted(SD_ORDER(filenum, fileCnt)); + char * const name = card.longest_filename(); + make_name_without_ext(shift_name, name, 100); + } + } + + inline void Init_SDItem_Shift() { + shift_amt = 0; + shift_ms = select_file.now > 0 && strlen(shift_name) > MENU_CHAR_LIMIT + ? millis() + 750UL : 0; + } + +#endif + +/** + * Display an SD item, adding a CDUP for subfolders. + */ +inline void Draw_SDItem(const uint16_t item, int16_t row=-1) { + if (row < 0) row = item + 1 + MROWS - index_file; + const bool is_subdir = !card.flag.workDirIsRoot; + if (is_subdir && item == 0) { + Draw_Menu_Line(row, ICON_Folder, ".."); + return; + } + + card.getfilename_sorted(item - is_subdir); + char * const name = card.longest_filename(); + + #if ENABLED(SCROLL_LONG_FILENAMES) + // Init the current selected name + // This is used during scroll drawing + if (item == select_file.now - 1) { + make_name_without_ext(shift_name, name, 100); + Init_SDItem_Shift(); + } + #endif + + // Draw the file/folder with name aligned left + char str[strlen(name) + 1]; + make_name_without_ext(str, name); + Draw_Menu_Line(row, card.flag.filenameIsDir ? ICON_Folder : ICON_File, str); +} + +#if ENABLED(SCROLL_LONG_FILENAMES) + + inline void Draw_SDItem_Shifted(int8_t &shift) { + // Limit to the number of chars past the cutoff + const size_t len = strlen(shift_name); + NOMORE(shift, _MAX(len - MENU_CHAR_LIMIT, 0U)); + + // Shorten to the available space + const size_t lastchar = _MIN((signed)len, shift + MENU_CHAR_LIMIT); + + const char c = shift_name[lastchar]; + shift_name[lastchar] = '\0'; + + const uint8_t row = select_file.now + MROWS - index_file; // skip "Back" and scroll + Erase_Menu_Text(row); + Draw_Menu_Line(row, 0, &shift_name[shift]); + + shift_name[lastchar] = c; + } + +#endif + +// Redraw the first set of SD Files +inline void Redraw_SD_List() { + select_file.reset(); + index_file = MROWS; + + Clear_Menu_Area(); // Leave title bar unchanged + + Draw_Back_First(); + + if (card.isMounted()) { + // As many files as will fit + LOOP_L_N(i, _MIN(nr_sd_menu_items(), MROWS)) + Draw_SDItem(i, i + 1); + + TERN_(SCROLL_LONG_FILENAMES, Init_SDItem_Shift()); + } + else { + DWIN_Draw_Rectangle(1, Color_Bg_Red, 10, MBASE(3) - 10, DWIN_WIDTH - 10, MBASE(4)); + DWIN_Draw_String(false, false, font16x32, Color_Yellow, Color_Bg_Red, ((DWIN_WIDTH) - 8 * 16) / 2, MBASE(3), F("No Media")); + } +} + +bool DWIN_lcd_sd_status = false; + +inline void SDCard_Up() { + card.cdup(); + Redraw_SD_List(); + DWIN_lcd_sd_status = false; // On next DWIN_Update +} + +inline void SDCard_Folder(char * const dirname) { + card.cd(dirname); + Redraw_SD_List(); + DWIN_lcd_sd_status = false; // On next DWIN_Update +} + +// +// Watch for media mount / unmount +// +void HMI_SDCardUpdate() { + if (HMI_flag.home_flag) return; + if (DWIN_lcd_sd_status != card.isMounted()) { + DWIN_lcd_sd_status = card.isMounted(); + // SERIAL_ECHOLNPAIR("HMI_SDCardUpdate: ", int(DWIN_lcd_sd_status)); + if (DWIN_lcd_sd_status) { + if (checkkey == SelectFile) + Redraw_SD_List(); + } + else { + // clean file icon + if (checkkey == SelectFile) { + Redraw_SD_List(); + } + else if (checkkey == PrintProcess || checkkey == Tune || printingIsActive()) { + // TODO: Move card removed abort handling + // to CardReader::manage_media. + card.flag.abort_sd_printing = true; + wait_for_heatup = wait_for_user = false; + dwin_abort_flag = true; // Reset feedrate, return to Home + } + } + DWIN_UpdateLCD(); + } +} + +// +// The status area is always on-screen, except during +// full-screen modal dialogs. (TODO: Keep alive during dialogs) +// +void Draw_Status_Area(const bool with_update) { + + // Clear the bottom area of the screen + DWIN_Draw_Rectangle(1, Color_Bg_Black, 0, STATUS_Y, DWIN_WIDTH, DWIN_HEIGHT - 1); + + // + // Status Area + // + #if HAS_HOTEND + DWIN_ICON_Show(ICON, ICON_HotendTemp, 13, 381); + DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_STAT, Color_White, Color_Bg_Black, 3, 33, 382, thermalManager.temp_hotend[0].celsius); + DWIN_Draw_String(false, false, DWIN_FONT_STAT, Color_White, Color_Bg_Black, 33 + 3 * STAT_CHR_W + 5, 383, F("/")); + DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_STAT, Color_White, Color_Bg_Black, 3, 33 + 4 * STAT_CHR_W + 6, 382, thermalManager.temp_hotend[0].target); + #endif + #if HOTENDS > 1 + // DWIN_ICON_Show(ICON,ICON_HotendTemp, 13, 381); + #endif + + #if HAS_HEATED_BED + DWIN_ICON_Show(ICON, ICON_BedTemp, 158, 381); + DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_STAT, Color_White, Color_Bg_Black, 3, 178, 382, thermalManager.temp_bed.celsius); + DWIN_Draw_String(false, false, DWIN_FONT_STAT, Color_White, Color_Bg_Black, 178 + 3 * STAT_CHR_W + 5, 383, F("/")); + DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_STAT, Color_White, Color_Bg_Black, 3, 178 + 4 * STAT_CHR_W + 6, 382, thermalManager.temp_bed.target); + #endif + + DWIN_ICON_Show(ICON, ICON_Speed, 13, 429); + DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_STAT, Color_White, Color_Bg_Black, 3, 33 + 2 * STAT_CHR_W, 429, feedrate_percentage); + DWIN_Draw_String(false, false, DWIN_FONT_STAT, Color_White, Color_Bg_Black, 33 + 5 * STAT_CHR_W + 2, 429, F("%")); + + #if HAS_ZOFFSET_ITEM + DWIN_ICON_Show(ICON, ICON_Zoffset, 158, 428); + DWIN_Draw_Signed_Float(DWIN_FONT_STAT, Color_Bg_Black, 2, 2, 178, 429, BABY_Z_VAR * 100); + #endif + + if (with_update) { + DWIN_UpdateLCD(); + delay(5); + } +} + +void HMI_StartFrame(const bool with_update) { + Goto_MainMenu(); + Draw_Status_Area(with_update); +} + +inline void Draw_Info_Menu() { + Clear_Main_Window(); + + DWIN_Draw_String(false, false, font8x16, Color_White, Color_Bg_Black, (DWIN_WIDTH - strlen(MACHINE_SIZE) * MENU_CHR_W) / 2, 122, (char*)MACHINE_SIZE); + DWIN_Draw_String(false, false, font8x16, Color_White, Color_Bg_Black, (DWIN_WIDTH - strlen(SHORT_BUILD_VERSION) * MENU_CHR_W) / 2, 195, (char*)SHORT_BUILD_VERSION); + + if (HMI_IsChinese()) { + DWIN_Frame_TitleCopy(1, 30, 17, 57, 29); // "Info" + + DWIN_Frame_AreaCopy(1, 197, 149, 252, 161, 108, 102); + DWIN_Frame_AreaCopy(1, 1, 164, 56, 176, 108, 175); + DWIN_Frame_AreaCopy(1, 58, 164, 113, 176, 105, 248); + DWIN_Draw_String(false, false, font8x16, Color_White, Color_Bg_Black, (DWIN_WIDTH - strlen(CORP_WEBSITE_C) * MENU_CHR_W) / 2, 268, (char*)CORP_WEBSITE_C); + } + else { + #ifdef USE_STRING_HEADINGS + Draw_Title(GET_TEXT_F(MSG_INFO_SCREEN)); + #else + DWIN_Frame_TitleCopy(1, 190, 16, 215, 26); // "Info" + #endif + + DWIN_Frame_AreaCopy(1, 120, 150, 146, 161, 124, 102); + DWIN_Frame_AreaCopy(1, 146, 151, 254, 161, 82, 175); + DWIN_Frame_AreaCopy(1, 0, 165, 94, 175, 89, 248); + DWIN_Draw_String(false, false, font8x16, Color_White, Color_Bg_Black, (DWIN_WIDTH - strlen(CORP_WEBSITE_E) * MENU_CHR_W) / 2, 268, (char*)CORP_WEBSITE_E); + } + + Draw_Back_First(); + LOOP_L_N(i, 3) { + DWIN_ICON_Show(ICON, ICON_PrintSize + i, 26, 99 + i * 73); + DWIN_Draw_Line(Line_Color, 16, MBASE(2) + i * 73, 256, 156 + i * 73); + } +} + +inline void Draw_Print_File_Menu() { + Clear_Title_Bar(); + + if (HMI_IsChinese()) { + DWIN_Frame_TitleCopy(1, 0, 31, 55, 44); // "Print file" + } + else { + #ifdef USE_STRING_HEADINGS + Draw_Title("Print file"); // TODO: GET_TEXT_F + #else + DWIN_Frame_TitleCopy(1, 52, 31, 137, 41); // "Print file" + #endif + } + + Redraw_SD_List(); +} + +/* Main Process */ +void HMI_MainMenu() { + ENCODER_DiffState encoder_diffState = get_encoder_state(); + if (encoder_diffState == ENCODER_DIFF_NO) return; + + if (encoder_diffState == ENCODER_DIFF_CW) { + if (select_page.inc(4)) { + switch (select_page.now) { + case 0: ICON_Print(); break; + case 1: ICON_Print(); ICON_Prepare(); break; + case 2: ICON_Prepare(); ICON_Control(); break; + case 3: ICON_Control(); TERN(HAS_ONESTEP_LEVELING, ICON_Leveling, ICON_StartInfo)(1); break; + } + } + } + else if (encoder_diffState == ENCODER_DIFF_CCW) { + if (select_page.dec()) { + switch (select_page.now) { + case 0: ICON_Print(); ICON_Prepare(); break; + case 1: ICON_Prepare(); ICON_Control(); break; + case 2: ICON_Control(); TERN(HAS_ONESTEP_LEVELING, ICON_Leveling, ICON_StartInfo)(0); break; + case 3: TERN(HAS_ONESTEP_LEVELING, ICON_Leveling, ICON_StartInfo)(1); break; + } + } + } + else if (encoder_diffState == ENCODER_DIFF_ENTER) { + switch (select_page.now) { + case 0: // Print File + checkkey = SelectFile; + Draw_Print_File_Menu(); + break; + + case 1: // Prepare + checkkey = Prepare; + select_prepare.reset(); + index_prepare = MROWS; + Draw_Prepare_Menu(); + break; + + case 2: // Control + checkkey = Control; + select_control.reset(); + index_control = MROWS; + Draw_Control_Menu(); + break; + + case 3: // Leveling or Info + #if HAS_ONESTEP_LEVELING + checkkey = Leveling; + HMI_Leveling(); + #else + checkkey = Info; + Draw_Info_Menu(); + #endif + break; + } + } + DWIN_UpdateLCD(); +} + +// Select (and Print) File +void HMI_SelectFile() { + ENCODER_DiffState encoder_diffState = get_encoder_state(); + + const uint16_t hasUpDir = !card.flag.workDirIsRoot; + + if (encoder_diffState == ENCODER_DIFF_NO) { + #if ENABLED(SCROLL_LONG_FILENAMES) + if (shift_ms && select_file.now >= 1 + hasUpDir) { + // Scroll selected filename every second + const millis_t ms = millis(); + if (ELAPSED(ms, shift_ms)) { + const bool was_reset = shift_amt < 0; + shift_ms = ms + 375UL + was_reset * 250UL; // ms per character + int8_t shift_new = shift_amt + 1; // Try to shift by... + Draw_SDItem_Shifted(shift_new); // Draw the item + if (!was_reset && shift_new == 0) // Was it limited to 0? + shift_ms = 0; // No scrolling needed + else if (shift_new == shift_amt) // Scroll reached the end + shift_new = -1; // Reset + shift_amt = shift_new; // Set new scroll + } + } + #endif + return; + } + + // First pause is long. Easy. + // On reset, long pause must be after 0. + + const uint16_t fullCnt = nr_sd_menu_items(); + + if (encoder_diffState == ENCODER_DIFF_CW && fullCnt) { + if (select_file.inc(1 + fullCnt)) { + const uint8_t itemnum = select_file.now - 1; // -1 for "Back" + if (TERN0(SCROLL_LONG_FILENAMES, shift_ms)) { // If line was shifted + Erase_Menu_Text(itemnum + MROWS - index_file); // Erase and + Draw_SDItem(itemnum - 1); // redraw + } + if (select_file.now > MROWS && select_file.now > index_file) { // Cursor past the bottom + index_file = select_file.now; // New bottom line + Scroll_Menu(DWIN_SCROLL_UP); + Draw_SDItem(itemnum, MROWS); // Draw and init the shift name + } + else { + Move_Highlight(1, select_file.now + MROWS - index_file); // Just move highlight + TERN_(SCROLL_LONG_FILENAMES, Init_Shift_Name()); // ...and init the shift name + } + TERN_(SCROLL_LONG_FILENAMES, Init_SDItem_Shift()); + } + } + else if (encoder_diffState == ENCODER_DIFF_CCW && fullCnt) { + if (select_file.dec()) { + const uint8_t itemnum = select_file.now - 1; // -1 for "Back" + if (TERN0(SCROLL_LONG_FILENAMES, shift_ms)) { // If line was shifted + Erase_Menu_Text(select_file.now + 1 + MROWS - index_file); // Erase and + Draw_SDItem(itemnum + 1); // redraw + } + if (select_file.now < index_file - MROWS) { // Cursor past the top + index_file--; // New bottom line + Scroll_Menu(DWIN_SCROLL_DOWN); + if (index_file == MROWS) { + Draw_Back_First(); + TERN_(SCROLL_LONG_FILENAMES, shift_ms = 0); + } + else { + Draw_SDItem(itemnum, 0); // Draw the item (and init shift name) + } + } + else { + Move_Highlight(-1, select_file.now + MROWS - index_file); // Just move highlight + TERN_(SCROLL_LONG_FILENAMES, Init_Shift_Name()); // ...and init the shift name + } + TERN_(SCROLL_LONG_FILENAMES, Init_SDItem_Shift()); // Reset left. Init timer. + } + } + else if (encoder_diffState == ENCODER_DIFF_ENTER) { + if (select_file.now == 0) { // Back + select_page.set(0); + Goto_MainMenu(); + } + else if (hasUpDir && select_file.now == 1) { // CD-Up + SDCard_Up(); + goto HMI_SelectFileExit; + } + else { + const uint16_t filenum = select_file.now - 1 - hasUpDir; + card.getfilename_sorted(SD_ORDER(filenum, card.get_num_Files())); + + // Enter that folder! + if (card.flag.filenameIsDir) { + SDCard_Folder(card.filename); + goto HMI_SelectFileExit; + } + + // Reset highlight for next entry + select_print.reset(); + select_file.reset(); + + // Start choice and print SD file + HMI_flag.heat_flag = true; + HMI_flag.print_finish = false; + HMI_ValueStruct.show_mode = 0; + + card.openAndPrintFile(card.filename); + + #if FAN_COUNT > 0 + // All fans on for Ender 3 v2 ? + // The slicer should manage this for us. + // for (uint8_t i = 0; i < FAN_COUNT; i++) + // thermalManager.fan_speed[i] = FANON; + #endif + + Goto_PrintProcess(); + } + } +HMI_SelectFileExit: + DWIN_UpdateLCD(); +} + +/* Printing */ +void HMI_Printing() { + ENCODER_DiffState encoder_diffState = get_encoder_state(); + if (encoder_diffState == ENCODER_DIFF_NO) return; + + if (HMI_flag.done_confirm_flag) { + if (encoder_diffState == ENCODER_DIFF_ENTER) { + HMI_flag.done_confirm_flag = false; + dwin_abort_flag = true; // Reset feedrate, return to Home + } + return; + } + + // Avoid flicker by updating only the previous menu + if (encoder_diffState == ENCODER_DIFF_CW) { + if (select_print.inc(3)) { + switch (select_print.now) { + case 0: ICON_Tune(); break; + case 1: + ICON_Tune(); + if (printingIsPaused()) ICON_Continue(); else ICON_Pause(); + break; + case 2: + if (printingIsPaused()) ICON_Continue(); else ICON_Pause(); + ICON_Stop(); + break; + } + } + } + else if (encoder_diffState == ENCODER_DIFF_CCW) { + if (select_print.dec()) { + switch (select_print.now) { + case 0: + ICON_Tune(); + if (printingIsPaused()) ICON_Continue(); else ICON_Pause(); + break; + case 1: + if (printingIsPaused()) ICON_Continue(); else ICON_Pause(); + ICON_Stop(); + break; + case 2: ICON_Stop(); break; + } + } + } + else if (encoder_diffState == ENCODER_DIFF_ENTER) { + switch (select_print.now) { + case 0: // Tune + checkkey = Tune; + HMI_ValueStruct.show_mode = 0; + select_tune.reset(); + index_tune = MROWS; + Draw_Tune_Menu(); + break; + case 1: // Pause + if (HMI_flag.pause_flag) { + ICON_Pause(); + + char cmd[40]; + cmd[0] = '\0'; + + #if ENABLED(PAUSE_HEAT) + #if HAS_HEATED_BED + if (tempbed) sprintf_P(cmd, PSTR("M190 S%i\n"), tempbed); + #endif + #if HAS_HOTEND + if (temphot) sprintf_P(&cmd[strlen(cmd)], PSTR("M109 S%i\n"), temphot); + #endif + #endif + + strcat_P(cmd, PSTR("M24")); + queue.inject(cmd); + } + else { + HMI_flag.select_flag = true; + checkkey = Print_window; + Popup_window_PauseOrStop(); + } + break; + + case 2: // Stop + HMI_flag.select_flag = true; + checkkey = Print_window; + Popup_window_PauseOrStop(); + break; + + default: break; + } + } + DWIN_UpdateLCD(); +} + +/* Pause and Stop window */ +void HMI_PauseOrStop() { + ENCODER_DiffState encoder_diffState = get_encoder_state(); + if (encoder_diffState == ENCODER_DIFF_NO) return; + + if (encoder_diffState == ENCODER_DIFF_CW) + Draw_Select_Highlight(false); + else if (encoder_diffState == ENCODER_DIFF_CCW) + Draw_Select_Highlight(true); + else if (encoder_diffState == ENCODER_DIFF_ENTER) { + if (select_print.now == 1) { // pause window + if (HMI_flag.select_flag) { + HMI_flag.pause_action = true; + ICON_Continue(); + #if ENABLED(POWER_LOSS_RECOVERY) + if (recovery.enabled) recovery.save(true); + #endif + queue.inject_P(PSTR("M25")); + } + else { + // cancel pause + } + Goto_PrintProcess(); + } + else if (select_print.now == 2) { // stop window + if (HMI_flag.select_flag) { + checkkey = Back_Main; + if (HMI_flag.home_flag) planner.synchronize(); // Wait for planner moves to finish! + wait_for_heatup = wait_for_user = false; // Stop waiting for heating/user + card.flag.abort_sd_printing = true; // Let the main loop handle SD abort + dwin_abort_flag = true; // Reset feedrate, return to Home + #ifdef ACTION_ON_CANCEL + host_action_cancel(); + #endif + Popup_Window_Home(true); + } + else + Goto_PrintProcess(); // cancel stop + } + } + DWIN_UpdateLCD(); +} + +inline void Draw_Move_Menu() { + Clear_Main_Window(); + + if (HMI_IsChinese()) { + DWIN_Frame_TitleCopy(1, 192, 1, 233, 14); // "Move" + DWIN_Frame_AreaCopy(1, 58, 118, 106, 132, LBLX, MBASE(1)); + DWIN_Frame_AreaCopy(1, 109, 118, 157, 132, LBLX, MBASE(2)); + DWIN_Frame_AreaCopy(1, 160, 118, 209, 132, LBLX, MBASE(3)); + #if HAS_HOTEND + DWIN_Frame_AreaCopy(1, 212, 118, 253, 131, LBLX, MBASE(4)); + #endif + } + else { + #ifdef USE_STRING_HEADINGS + Draw_Title(GET_TEXT_F(MSG_MOVE_AXIS)); + #else + DWIN_Frame_TitleCopy(1, 231, 2, 265, 12); // "Move" + #endif + draw_move_en(MBASE(1)); say_x(36, MBASE(1)); // "Move X" + draw_move_en(MBASE(2)); say_y(36, MBASE(2)); // "Move Y" + draw_move_en(MBASE(3)); say_z(36, MBASE(3)); // "Move Z" + #if HAS_HOTEND + DWIN_Frame_AreaCopy(1, 123, 192, 176, 202, LBLX, MBASE(4)); // "Extruder" + #endif + } + + Draw_Back_First(select_axis.now == 0); + if (select_axis.now) Draw_Menu_Cursor(select_axis.now); + + // Draw separators and icons + LOOP_L_N(i, 3 + ENABLED(HAS_HOTEND)) Draw_Menu_Line(i + 1, ICON_MoveX + i); +} + +#include "../../../libs/buzzer.h" + +void HMI_AudioFeedback(const bool success=true) { + if (success) { + buzzer.tone(100, 659); + buzzer.tone(10, 0); + buzzer.tone(100, 698); + } + else + buzzer.tone(40, 440); +} + +/* Prepare */ +void HMI_Prepare() { + ENCODER_DiffState encoder_diffState = get_encoder_state(); + if (encoder_diffState == ENCODER_DIFF_NO) return; + + // Avoid flicker by updating only the previous menu + if (encoder_diffState == ENCODER_DIFF_CW) { + if (select_prepare.inc(1 + PREPARE_CASE_TOTAL)) { + if (select_prepare.now > MROWS && select_prepare.now > index_prepare) { + index_prepare = select_prepare.now; + + // Scroll up and draw a blank bottom line + Scroll_Menu(DWIN_SCROLL_UP); + Draw_Menu_Icon(MROWS, ICON_Axis + select_prepare.now - 1); + + // Draw "More" icon for sub-menus + if (index_prepare < 7) Draw_More_Icon(MROWS - index_prepare + 1); + + #if HAS_HOTEND + if (index_prepare == PREPARE_CASE_ABS) Item_Prepare_ABS(MROWS); + #endif + #if HAS_PREHEAT + if (index_prepare == PREPARE_CASE_COOL) Item_Prepare_Cool(MROWS); + #endif + if (index_prepare == PREPARE_CASE_LANG) Item_Prepare_Lang(MROWS); + } + else { + Move_Highlight(1, select_prepare.now + MROWS - index_prepare); + } + } + } + else if (encoder_diffState == ENCODER_DIFF_CCW) { + if (select_prepare.dec()) { + if (select_prepare.now < index_prepare - MROWS) { + index_prepare--; + Scroll_Menu(DWIN_SCROLL_DOWN); + + if (index_prepare == MROWS) + Draw_Back_First(); + else + Draw_Menu_Line(0, ICON_Axis + select_prepare.now - 1); + + if (index_prepare < 7) Draw_More_Icon(MROWS - index_prepare + 1); + + if (index_prepare == 6) Item_Prepare_Move(0); + else if (index_prepare == 7) Item_Prepare_Disable(0); + else if (index_prepare == 8) Item_Prepare_Home(0); + } + else { + Move_Highlight(-1, select_prepare.now + MROWS - index_prepare); + } + } + } + else if (encoder_diffState == ENCODER_DIFF_ENTER) { + switch (select_prepare.now) { + case 0: // Back + select_page.set(1); + Goto_MainMenu(); + break; + case PREPARE_CASE_MOVE: // Axis move + checkkey = AxisMove; + select_axis.reset(); + Draw_Move_Menu(); + + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 1, 216, MBASE(1), current_position.x * MINUNITMULT); + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 1, 216, MBASE(2), current_position.y * MINUNITMULT); + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 1, 216, MBASE(3), current_position.z * MINUNITMULT); + #if HAS_HOTEND + queue.inject_P(PSTR("G92 E0")); + current_position.e = HMI_ValueStruct.Move_E_scale = 0; + DWIN_Draw_Signed_Float(font8x16, Color_Bg_Black, 3, 1, 216, MBASE(4), 0); + #endif + break; + case PREPARE_CASE_DISA: // Disable steppers + queue.inject_P(PSTR("M84")); + break; + case PREPARE_CASE_HOME: // Homing + checkkey = Last_Prepare; + index_prepare = MROWS; + queue.inject_P(PSTR("G28")); // G28 will set home_flag + Popup_Window_Home(); + break; + #if HAS_ZOFFSET_ITEM + case PREPARE_CASE_ZOFF: // Z-offset + #if EITHER(HAS_BED_PROBE, BABYSTEPPING) + checkkey = Homeoffset; + HMI_ValueStruct.show_mode = -4; + HMI_ValueStruct.offset_value = BABY_Z_VAR * 100; + DWIN_Draw_Signed_Float(font8x16, Select_Color, 2, 2, 202, MBASE(PREPARE_CASE_ZOFF + MROWS - index_prepare), HMI_ValueStruct.offset_value); + EncoderRate.enabled = true; + #else + // Apply workspace offset, making the current position 0,0,0 + queue.inject_P(PSTR("G92 X0 Y0 Z0")); + HMI_AudioFeedback(); + #endif + break; + #endif + #if HAS_HOTEND + case PREPARE_CASE_PLA: // PLA preheat + thermalManager.setTargetHotend(ui.material_preset[0].hotend_temp, 0); + thermalManager.setTargetBed(ui.material_preset[0].bed_temp); + thermalManager.set_fan_speed(0, ui.material_preset[0].fan_speed); + break; + case PREPARE_CASE_ABS: // ABS preheat + thermalManager.setTargetHotend(ui.material_preset[1].hotend_temp, 0); + thermalManager.setTargetBed(ui.material_preset[1].bed_temp); + thermalManager.set_fan_speed(0, ui.material_preset[1].fan_speed); + break; + #endif + #if HAS_PREHEAT + case PREPARE_CASE_COOL: // Cool + TERN_(HAS_FAN, thermalManager.zero_fan_speeds()); + #if HAS_HOTEND || HAS_HEATED_BED + thermalManager.disable_all_heaters(); + #endif + break; + #endif + case PREPARE_CASE_LANG: // Toggle Language + HMI_ToggleLanguage(); + Draw_Prepare_Menu(); + break; + default: break; + } + } + DWIN_UpdateLCD(); +} + +void Draw_Temperature_Menu() { + Clear_Main_Window(); + + if (HMI_IsChinese()) { + DWIN_Frame_TitleCopy(1, 236, 2, 263, 13); // "Temperature" + #if HAS_HOTEND + DWIN_Frame_AreaCopy(1, 1, 134, 56, 146, LBLX, MBASE(TEMP_CASE_TEMP)); + #endif + #if HAS_HEATED_BED + DWIN_Frame_AreaCopy(1, 58, 134, 113, 146, LBLX, MBASE(TEMP_CASE_BED)); + #endif + #if HAS_FAN + DWIN_Frame_AreaCopy(1, 115, 134, 170, 146, LBLX, MBASE(TEMP_CASE_FAN)); + #endif + #if HAS_HOTEND + DWIN_Frame_AreaCopy(1, 100, 89, 178, 101, LBLX, MBASE(TEMP_CASE_PLA)); + DWIN_Frame_AreaCopy(1, 180, 89, 260, 100, LBLX, MBASE(TEMP_CASE_ABS)); + #endif + } + else { + #ifdef USE_STRING_HEADINGS + Draw_Title(GET_TEXT_F(MSG_TEMPERATURE)); + #if HAS_HOTEND + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(TEMP_CASE_TEMP), GET_TEXT_F(MSG_UBL_SET_TEMP_HOTEND)); + #endif + #if HAS_HEATED_BED + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(TEMP_CASE_BED), GET_TEXT_F(MSG_UBL_SET_TEMP_BED)); + #endif + #if HAS_FAN + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(TEMP_CASE_FAN), GET_TEXT_F(MSG_FAN_SPEED)); + #endif + #if HAS_HOTEND + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(TEMP_CASE_PLA), F("PLA Preheat Settings")); + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(TEMP_CASE_ABS), F("ABS Preheat Settings")); + #endif + #else + DWIN_Frame_TitleCopy(1, 56, 16, 141, 28); // "Temperature" + #if HAS_HOTEND + DWIN_Frame_AreaCopy(1, 197, 104, 238, 114, LBLX, MBASE(TEMP_CASE_TEMP)); // Nozzle... + DWIN_Frame_AreaCopy(1, 1, 89, 83, 101, LBLX + 44, MBASE(TEMP_CASE_TEMP)); // ...Temperature + #endif + #if HAS_HEATED_BED + DWIN_Frame_AreaCopy(1, 240, 104, 264, 114, LBLX, MBASE(TEMP_CASE_BED)); // Bed... + DWIN_Frame_AreaCopy(1, 1, 89, 83, 101, LBLX + 27, MBASE(TEMP_CASE_BED)); // ...Temperature + #endif + #if HAS_FAN + DWIN_Frame_AreaCopy(1, 0, 119, 64, 132, LBLX, MBASE(TEMP_CASE_FAN)); // Fan speed + #endif + #if HAS_HOTEND + DWIN_Frame_AreaCopy(1, 107, 76, 156, 86, LBLX, MBASE(TEMP_CASE_PLA)); // Preheat... + DWIN_Frame_AreaCopy(1, 157, 76, 181, 86, LBLX + 52, MBASE(TEMP_CASE_PLA)); // ...PLA + DWIN_Frame_AreaCopy(1, 131, 119, 182, 132, LBLX + 79, MBASE(TEMP_CASE_PLA)); // PLA setting + DWIN_Frame_AreaCopy(1, 107, 76, 156, 86, LBLX, MBASE(TEMP_CASE_ABS)); // Preheat... + DWIN_Frame_AreaCopy(1, 172, 76, 198, 86, LBLX + 52, MBASE(TEMP_CASE_ABS)); // ...ABS + DWIN_Frame_AreaCopy(1, 131, 119, 182, 132, LBLX + 81, MBASE(TEMP_CASE_ABS)); // ABS setting + #endif + #endif + } + + Draw_Back_First(select_temp.now == 0); + if (select_temp.now) Draw_Menu_Cursor(select_temp.now); + + // Draw icons and lines + uint8_t i = 0; + #define _TMENU_ICON(N) Draw_Menu_Line(++i, ICON_SetEndTemp + (N) - 1) + #if HAS_HOTEND + _TMENU_ICON(TEMP_CASE_TEMP); + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(i), thermalManager.temp_hotend[0].target); + #endif + #if HAS_HEATED_BED + _TMENU_ICON(TEMP_CASE_BED); + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(i), thermalManager.temp_bed.target); + #endif + #if HAS_FAN + _TMENU_ICON(TEMP_CASE_FAN); + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(i), thermalManager.fan_speed[0]); + #endif + #if HAS_HOTEND + // PLA/ABS items have submenus + _TMENU_ICON(TEMP_CASE_PLA); + Draw_More_Icon(i); + _TMENU_ICON(TEMP_CASE_ABS); + Draw_More_Icon(i); + #endif +} + +/* Control */ +void HMI_Control() { + ENCODER_DiffState encoder_diffState = get_encoder_state(); + if (encoder_diffState == ENCODER_DIFF_NO) return; + + // Avoid flicker by updating only the previous menu + if (encoder_diffState == ENCODER_DIFF_CW) { + if (select_control.inc(1 + CONTROL_CASE_TOTAL)) { + if (select_control.now > MROWS && select_control.now > index_control) { + index_control = select_control.now; + Scroll_Menu(DWIN_SCROLL_UP); + Draw_Menu_Icon(MROWS, ICON_Temperature + index_control - 1); + Draw_More_Icon(CONTROL_CASE_TEMP + MROWS - index_control); // Temperature > + Draw_More_Icon(CONTROL_CASE_MOVE + MROWS - index_control); // Motion > + if (index_control > MROWS) { + Draw_More_Icon(CONTROL_CASE_INFO + MROWS - index_control); // Info > + if (HMI_IsChinese()) + DWIN_Frame_AreaCopy(1, 231, 104, 258, 116, LBLX, MBASE(CONTROL_CASE_INFO - 1)); + else + DWIN_Frame_AreaCopy(1, 0, 104, 24, 114, LBLX, MBASE(CONTROL_CASE_INFO - 1)); + } + } + else { + Move_Highlight(1, select_control.now + MROWS - index_control); + } + } + } + else if (encoder_diffState == ENCODER_DIFF_CCW) { + if (select_control.dec()) { + if (select_control.now < index_control - MROWS) { + index_control--; + Scroll_Menu(DWIN_SCROLL_DOWN); + if (index_control == MROWS) + Draw_Back_First(); + else + Draw_Menu_Line(0, ICON_Temperature + select_control.now - 1); + Draw_More_Icon(0 + MROWS - index_control + 1); // Temperature > + Draw_More_Icon(1 + MROWS - index_control + 1); // Motion > + } + else { + Move_Highlight(-1, select_control.now + MROWS - index_control); + } + } + } + else if (encoder_diffState == ENCODER_DIFF_ENTER) { + switch (select_control.now) { + case 0: // Back + select_page.set(2); + Goto_MainMenu(); + break; + case CONTROL_CASE_TEMP: // Temperature + checkkey = TemperatureID; + HMI_ValueStruct.show_mode = -1; + select_temp.reset(); + Draw_Temperature_Menu(); + break; + case CONTROL_CASE_MOVE: // Motion + checkkey = Motion; + select_motion.reset(); + Draw_Motion_Menu(); + break; + #if ENABLED(EEPROM_SETTINGS) + case CONTROL_CASE_SAVE: { // Write EEPROM + const bool success = settings.save(); + HMI_AudioFeedback(success); + } break; + case CONTROL_CASE_LOAD: { // Read EEPROM + const bool success = settings.load(); + HMI_AudioFeedback(success); + } break; + case CONTROL_CASE_RESET: // Reset EEPROM + settings.reset(); + HMI_AudioFeedback(); + break; + #endif + case CONTROL_CASE_INFO: // Info + checkkey = Info; + Draw_Info_Menu(); + break; + default: break; + } + } + DWIN_UpdateLCD(); +} + + +#if HAS_ONESTEP_LEVELING + + /* Leveling */ + void HMI_Leveling() { + Popup_Window_Leveling(); + DWIN_UpdateLCD(); + queue.inject_P(PSTR("G28O\nG29")); + } + +#endif + +/* Axis Move */ +void HMI_AxisMove() { + ENCODER_DiffState encoder_diffState = get_encoder_state(); + if (encoder_diffState == ENCODER_DIFF_NO) return; + + #if ENABLED(PREVENT_COLD_EXTRUSION) + // popup window resume + if (HMI_flag.ETempTooLow_flag) { + if (encoder_diffState == ENCODER_DIFF_ENTER) { + HMI_flag.ETempTooLow_flag = false; + current_position.e = HMI_ValueStruct.Move_E_scale = 0; + Draw_Move_Menu(); + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 1, 216, MBASE(1), HMI_ValueStruct.Move_X_scale); + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 1, 216, MBASE(2), HMI_ValueStruct.Move_Y_scale); + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 1, 216, MBASE(3), HMI_ValueStruct.Move_Z_scale); + DWIN_Draw_Signed_Float(font8x16, Color_Bg_Black, 3, 1, 216, MBASE(4), 0); + DWIN_UpdateLCD(); + } + return; + } + #endif + + // Avoid flicker by updating only the previous menu + if (encoder_diffState == ENCODER_DIFF_CW) { + if (select_axis.inc(1 + 3 + ENABLED(HAS_HOTEND))) Move_Highlight(1, select_axis.now); + } + else if (encoder_diffState == ENCODER_DIFF_CCW) { + if (select_axis.dec()) Move_Highlight(-1, select_axis.now); + } + else if (encoder_diffState == ENCODER_DIFF_ENTER) { + switch (select_axis.now) { + case 0: // Back + checkkey = Prepare; + select_prepare.set(1); + index_prepare = MROWS; + Draw_Prepare_Menu(); + break; + case 1: // X axis move + checkkey = Move_X; + HMI_ValueStruct.Move_X_scale = current_position.x * MINUNITMULT; + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 1, 216, MBASE(1), HMI_ValueStruct.Move_X_scale); + EncoderRate.enabled = true; + break; + case 2: // Y axis move + checkkey = Move_Y; + HMI_ValueStruct.Move_Y_scale = current_position.y * MINUNITMULT; + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 1, 216, MBASE(2), HMI_ValueStruct.Move_Y_scale); + EncoderRate.enabled = true; + break; + case 3: // Z axis move + checkkey = Move_Z; + HMI_ValueStruct.Move_Z_scale = current_position.z * MINUNITMULT; + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 1, 216, MBASE(3), HMI_ValueStruct.Move_Z_scale); + EncoderRate.enabled = true; + break; + #if HAS_HOTEND + case 4: // Extruder + // window tips + #ifdef PREVENT_COLD_EXTRUSION + if (thermalManager.temp_hotend[0].celsius < EXTRUDE_MINTEMP) { + HMI_flag.ETempTooLow_flag = true; + Popup_Window_ETempTooLow(); + DWIN_UpdateLCD(); + return; + } + #endif + checkkey = Extruder; + HMI_ValueStruct.Move_E_scale = current_position.e * MINUNITMULT; + DWIN_Draw_Signed_Float(font8x16, Select_Color, 3, 1, 216, MBASE(4), HMI_ValueStruct.Move_E_scale); + EncoderRate.enabled = true; + break; + #endif + } + } + DWIN_UpdateLCD(); +} + +/* TemperatureID */ +void HMI_Temperature() { + ENCODER_DiffState encoder_diffState = get_encoder_state(); + if (encoder_diffState == ENCODER_DIFF_NO) return; + + // Avoid flicker by updating only the previous menu + if (encoder_diffState == ENCODER_DIFF_CW) { + if (select_temp.inc(1 + TEMP_CASE_TOTAL)) Move_Highlight(1, select_temp.now); + } + else if (encoder_diffState == ENCODER_DIFF_CCW) { + if (select_temp.dec()) Move_Highlight(-1, select_temp.now); + } + else if (encoder_diffState == ENCODER_DIFF_ENTER) { + switch (select_temp.now) { + case 0: // Back + checkkey = Control; + select_control.set(1); + index_control = MROWS; + Draw_Control_Menu(); + break; + #if HAS_HOTEND + case TEMP_CASE_TEMP: // Nozzle temperature + checkkey = ETemp; + HMI_ValueStruct.E_Temp = thermalManager.temp_hotend[0].target; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 216, MBASE(1), thermalManager.temp_hotend[0].target); + EncoderRate.enabled = true; + break; + #endif + #if HAS_HEATED_BED + case TEMP_CASE_BED: // Bed temperature + checkkey = BedTemp; + HMI_ValueStruct.Bed_Temp = thermalManager.temp_bed.target; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 216, MBASE(2), thermalManager.temp_bed.target); + EncoderRate.enabled = true; + break; + #endif + #if HAS_FAN + case TEMP_CASE_FAN: // Fan speed + checkkey = FanSpeed; + HMI_ValueStruct.Fan_speed = thermalManager.fan_speed[0]; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 216, MBASE(3), thermalManager.fan_speed[0]); + EncoderRate.enabled = true; + break; + #endif + #if HAS_HOTEND + case TEMP_CASE_PLA: { // PLA preheat setting + checkkey = PLAPreheat; + select_PLA.reset(); + HMI_ValueStruct.show_mode = -2; + + Clear_Main_Window(); + + if (HMI_IsChinese()) { + DWIN_Frame_TitleCopy(1, 59, 16, 139, 29); // "PLA Settings" + DWIN_Frame_AreaCopy(1, 100, 89, 124, 101, LBLX, MBASE(PREHEAT_CASE_TEMP)); + DWIN_Frame_AreaCopy(1, 1, 134, 56, 146, LBLX + 24, MBASE(PREHEAT_CASE_TEMP)); // PLA nozzle temp + #if HAS_HEATED_BED + DWIN_Frame_AreaCopy(1, 100, 89, 124, 101, LBLX, MBASE(PREHEAT_CASE_BED)); + DWIN_Frame_AreaCopy(1, 58, 134, 113, 146, LBLX + 24, MBASE(PREHEAT_CASE_BED)); // PLA bed temp + #endif + #if HAS_FAN + DWIN_Frame_AreaCopy(1, 100, 89, 124, 101, LBLX, MBASE(PREHEAT_CASE_FAN)); + DWIN_Frame_AreaCopy(1, 115, 134, 170, 146, LBLX + 24, MBASE(PREHEAT_CASE_FAN)); // PLA fan speed + #endif + #if ENABLED(EEPROM_SETTINGS) + DWIN_Frame_AreaCopy(1, 72, 148, 151, 162, LBLX, MBASE(PREHEAT_CASE_SAVE)); // Save PLA configuration + #endif + } + else { + #ifdef USE_STRING_HEADINGS + Draw_Title("PLA Settings"); // TODO: GET_TEXT_F + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(PREHEAT_CASE_TEMP), F("Nozzle Temp")); + #if HAS_HEATED_BED + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(PREHEAT_CASE_BED), F("Bed Temp")); + #endif + #if HAS_FAN + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(PREHEAT_CASE_FAN), GET_TEXT_F(MSG_FAN_SPEED)); + #endif + #if ENABLED(EEPROM_SETTINGS) + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(PREHEAT_CASE_SAVE), GET_TEXT_F(MSG_STORE_EEPROM)); + #endif + #else + DWIN_Frame_TitleCopy(1, 56, 16, 141, 28); // "PLA Settings" + DWIN_Frame_AreaCopy(1, 157, 76, 181, 86, LBLX, MBASE(PREHEAT_CASE_TEMP)); + DWIN_Frame_AreaCopy(1, 197, 104, 238, 114, LBLX + 27, MBASE(PREHEAT_CASE_TEMP)); + DWIN_Frame_AreaCopy(1, 1, 89, 83, 101, LBLX + 71, MBASE(PREHEAT_CASE_TEMP)); // PLA nozzle temp + #if HAS_HEATED_BED + DWIN_Frame_AreaCopy(1, 157, 76, 181, 86, LBLX, MBASE(PREHEAT_CASE_BED) + 3); + DWIN_Frame_AreaCopy(1, 240, 104, 264, 114, LBLX + 27, MBASE(PREHEAT_CASE_BED) + 3); + DWIN_Frame_AreaCopy(1, 1, 89, 83, 101, LBLX + 54, MBASE(PREHEAT_CASE_BED) + 3); // PLA bed temp + #endif + #if HAS_FAN + DWIN_Frame_AreaCopy(1, 157, 76, 181, 86, LBLX, MBASE(PREHEAT_CASE_FAN)); + DWIN_Frame_AreaCopy(1, 0, 119, 64, 132, LBLX + 27, MBASE(PREHEAT_CASE_FAN)); // PLA fan speed + #endif + #if ENABLED(EEPROM_SETTINGS) + DWIN_Frame_AreaCopy(1, 97, 165, 229, 177, LBLX, MBASE(PREHEAT_CASE_SAVE)); // Save PLA configuration + #endif + #endif + } + + Draw_Back_First(); + + uint8_t i = 0; + Draw_Menu_Line(++i, ICON_SetEndTemp); + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(i), ui.material_preset[0].hotend_temp); + #if HAS_HEATED_BED + Draw_Menu_Line(++i, ICON_SetBedTemp); + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(i), ui.material_preset[0].bed_temp); + #endif + #if HAS_FAN + Draw_Menu_Line(++i, ICON_FanSpeed); + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(i), ui.material_preset[0].fan_speed); + #endif + #if ENABLED(EEPROM_SETTINGS) + Draw_Menu_Line(++i, ICON_WriteEEPROM); + #endif + } break; + + case TEMP_CASE_ABS: { // ABS preheat setting + checkkey = ABSPreheat; + select_ABS.reset(); + HMI_ValueStruct.show_mode = -3; + + Clear_Main_Window(); + + if (HMI_IsChinese()) { + DWIN_Frame_TitleCopy(1, 142, 16, 223, 29); // "ABS Settings" + + DWIN_Frame_AreaCopy(1, 180, 89, 204, 100, LBLX, MBASE(PREHEAT_CASE_TEMP)); + DWIN_Frame_AreaCopy(1, 1, 134, 56, 146, LBLX + 24, MBASE(PREHEAT_CASE_TEMP)); // ABS nozzle temp + #if HAS_HEATED_BED + DWIN_Frame_AreaCopy(1, 180, 89, 204, 100, LBLX, MBASE(PREHEAT_CASE_BED)); + DWIN_Frame_AreaCopy(1, 58, 134, 113, 146, LBLX + 24, MBASE(PREHEAT_CASE_BED)); // ABS bed temp + #endif + #if HAS_FAN + DWIN_Frame_AreaCopy(1, 180, 89, 204, 100, LBLX, MBASE(PREHEAT_CASE_FAN)); + DWIN_Frame_AreaCopy(1, 115, 134, 170, 146, LBLX + 24, MBASE(PREHEAT_CASE_FAN)); // ABS fan speed + #endif + #if ENABLED(EEPROM_SETTINGS) + DWIN_Frame_AreaCopy(1, 72, 148, 151, 162, LBLX, MBASE(PREHEAT_CASE_SAVE)); + DWIN_Frame_AreaCopy(1, 180, 89, 204, 100, LBLX + 28, MBASE(PREHEAT_CASE_SAVE) + 2); // Save ABS configuration + #endif + } + else { + #ifdef USE_STRING_HEADINGS + Draw_Title("ABS Settings"); // TODO: GET_TEXT_F + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(PREHEAT_CASE_TEMP), F("Nozzle Temp")); + #if HAS_HEATED_BED + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(PREHEAT_CASE_BED), F("Bed Temp")); + #endif + #if HAS_FAN + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(PREHEAT_CASE_FAN), GET_TEXT_F(MSG_FAN_SPEED)); + #endif + #if ENABLED(EEPROM_SETTINGS) + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(PREHEAT_CASE_SAVE), GET_TEXT_F(MSG_STORE_EEPROM)); + #endif + #else + DWIN_Frame_TitleCopy(1, 56, 16, 141, 28); // "ABS Settings" + DWIN_Frame_AreaCopy(1, 172, 76, 198, 86, LBLX, MBASE(PREHEAT_CASE_TEMP)); + DWIN_Frame_AreaCopy(1, 197, 104, 238, 114, LBLX + 27, MBASE(PREHEAT_CASE_TEMP)); + DWIN_Frame_AreaCopy(1, 1, 89, 83, 101, LBLX + 71, MBASE(PREHEAT_CASE_TEMP)); // ABS nozzle temp + #if HAS_HEATED_BED + DWIN_Frame_AreaCopy(1, 172, 76, 198, 86, LBLX, MBASE(PREHEAT_CASE_BED) + 3); + DWIN_Frame_AreaCopy(1, 240, 104, 264, 114, LBLX + 27, MBASE(PREHEAT_CASE_BED) + 3); + DWIN_Frame_AreaCopy(1, 1, 89, 83, 101, LBLX + 54, MBASE(PREHEAT_CASE_BED) + 3); // ABS bed temp + #endif + #if HAS_FAN + DWIN_Frame_AreaCopy(1, 172, 76, 198, 86, LBLX, MBASE(PREHEAT_CASE_FAN)); + DWIN_Frame_AreaCopy(1, 0, 119, 64, 132, LBLX + 27, MBASE(PREHEAT_CASE_FAN)); // ABS fan speed + #endif + #if ENABLED(EEPROM_SETTINGS) + DWIN_Frame_AreaCopy(1, 97, 165, 229, 177, LBLX, MBASE(PREHEAT_CASE_SAVE)); + DWIN_Frame_AreaCopy(1, 172, 76, 198, 86, LBLX + 33, MBASE(PREHEAT_CASE_SAVE)); // Save ABS configuration + #endif + #endif + } + + Draw_Back_First(); + + uint8_t i = 0; + Draw_Menu_Line(++i, ICON_SetEndTemp); + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(i), ui.material_preset[1].hotend_temp); + #if HAS_HEATED_BED + Draw_Menu_Line(++i, ICON_SetBedTemp); + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(i), ui.material_preset[1].bed_temp); + #endif + #if HAS_FAN + Draw_Menu_Line(++i, ICON_FanSpeed); + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 216, MBASE(i), ui.material_preset[1].fan_speed); + #endif + #if ENABLED(EEPROM_SETTINGS) + Draw_Menu_Line(++i, ICON_WriteEEPROM); + #endif + + } break; + + #endif // HAS_HOTEND + } + } + DWIN_UpdateLCD(); +} + +inline void Draw_Max_Speed_Menu() { + Clear_Main_Window(); + + if (HMI_IsChinese()) { + DWIN_Frame_TitleCopy(1, 1, 16, 28, 28); // "Max Speed (mm/s)" + + auto say_max_speed = [](const uint16_t row) { + DWIN_Frame_AreaCopy(1, 173, 133, 228, 147, LBLX, row); // "Max speed" + }; + + say_max_speed(MBASE(1)); // "Max speed" + DWIN_Frame_AreaCopy(1, 229, 133, 236, 147, LBLX + 58, MBASE(1)); // X + say_max_speed(MBASE(2)); // "Max speed" + DWIN_Frame_AreaCopy(1, 1, 150, 7, 160, LBLX + 58, MBASE(2) + 3); // Y + say_max_speed(MBASE(3)); // "Max speed" + DWIN_Frame_AreaCopy(1, 9, 150, 16, 160, LBLX + 58, MBASE(3) + 3); // Z + #if HAS_HOTEND + say_max_speed(MBASE(4)); // "Max speed" + DWIN_Frame_AreaCopy(1, 18, 150, 25, 160, LBLX + 58, MBASE(4) + 3); // E + #endif + } + else { + #ifdef USE_STRING_HEADINGS + Draw_Title("Max Speed (mm/s)"); // TODO: GET_TEXT_F + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(1), F("Max Feedrate X")); + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(2), F("Max Feedrate Y")); + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(3), F("Max Feedrate Z")); + #if HAS_HOTEND + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(4), F("Max Feedrate E")); + #endif + #else + DWIN_Frame_TitleCopy(1, 144, 16, 189, 26); // "Max Speed (mm/s)" + + draw_max_en(MBASE(1)); // "Max" + DWIN_Frame_AreaCopy(1, 184, 119, 234, 132, LBLX + 27, MBASE(1)); // "Speed X" + + draw_max_en(MBASE(2)); // "Max" + draw_speed_en(27, MBASE(2)); // "Speed" + say_y(70, MBASE(2)); // "Y" + + draw_max_en(MBASE(3)); // "Max" + draw_speed_en(27, MBASE(3)); // "Speed" + say_z(70, MBASE(3)); // "Z" + + #if HAS_HOTEND + draw_max_en(MBASE(4)); // "Max" + draw_speed_en(27, MBASE(4)); // "Speed" + say_e(70, MBASE(4)); // "E" + #endif + #endif + } + + Draw_Back_First(); + LOOP_L_N(i, 3 + ENABLED(HAS_HOTEND)) Draw_Menu_Line(i + 1, ICON_MaxSpeedX + i); + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 4, 210, MBASE(1), planner.settings.max_feedrate_mm_s[X_AXIS]); + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 4, 210, MBASE(2), planner.settings.max_feedrate_mm_s[Y_AXIS]); + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 4, 210, MBASE(3), planner.settings.max_feedrate_mm_s[Z_AXIS]); + #if HAS_HOTEND + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 4, 210, MBASE(4), planner.settings.max_feedrate_mm_s[E_AXIS]); + #endif +} + +inline void Draw_Max_Accel_Menu() { + Clear_Main_Window(); + + if (HMI_IsChinese()) { + DWIN_Frame_TitleCopy(1, 1, 16, 28, 28); // "Acceleration" + + DWIN_Frame_AreaCopy(1, 173, 133, 200, 147, LBLX, MBASE(1)); + DWIN_Frame_AreaCopy(1, 28, 149, 69, 161, LBLX + 27, MBASE(1) + 1); + DWIN_Frame_AreaCopy(1, 229, 133, 236, 147, LBLX + 71, MBASE(1)); // Max acceleration X + DWIN_Frame_AreaCopy(1, 173, 133, 200, 147, LBLX, MBASE(2)); + DWIN_Frame_AreaCopy(1, 28, 149, 69, 161, LBLX + 27, MBASE(2) + 1); + DWIN_Frame_AreaCopy(1, 1, 150, 7, 160, LBLX + 71, MBASE(2) + 2); // Max acceleration Y + DWIN_Frame_AreaCopy(1, 173, 133, 200, 147, LBLX, MBASE(3)); + DWIN_Frame_AreaCopy(1, 28, 149, 69, 161, LBLX + 27, MBASE(3) + 1); + DWIN_Frame_AreaCopy(1, 9, 150, 16, 160, LBLX + 71, MBASE(3) + 2); // Max acceleration Z + #if HAS_HOTEND + DWIN_Frame_AreaCopy(1, 173, 133, 200, 147, LBLX, MBASE(4)); + DWIN_Frame_AreaCopy(1, 28, 149, 69, 161, LBLX + 27, MBASE(4) + 1); + DWIN_Frame_AreaCopy(1, 18, 150, 25, 160, LBLX + 71, MBASE(4) + 2); // Max acceleration E + #endif + } + else { + #ifdef USE_STRING_HEADINGS + Draw_Title(GET_TEXT_F(MSG_ACCELERATION)); + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(1), F("Max Accel X")); + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(2), F("Max Accel Y")); + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(3), F("Max Accel Z")); + #if HAS_HOTEND + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(4), F("Max Accel E")); + #endif + #else + DWIN_Frame_TitleCopy(1, 144, 16, 189, 26); // "Acceleration" + draw_max_accel_en(MBASE(1)); say_x(108, MBASE(1)); // "Max Acceleration X" + draw_max_accel_en(MBASE(2)); say_y(108, MBASE(2)); // "Max Acceleration Y" + draw_max_accel_en(MBASE(3)); say_z(108, MBASE(3)); // "Max Acceleration Z" + #if HAS_HOTEND + draw_max_accel_en(MBASE(4)); say_e(108, MBASE(4)); // "Max Acceleration E" + #endif + #endif + } + + Draw_Back_First(); + LOOP_L_N(i, 3 + ENABLED(HAS_HOTEND)) Draw_Menu_Line(i + 1, ICON_MaxAccX + i); + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 4, 210, MBASE(1), planner.settings.max_acceleration_mm_per_s2[X_AXIS]); + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 4, 210, MBASE(2), planner.settings.max_acceleration_mm_per_s2[Y_AXIS]); + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 4, 210, MBASE(3), planner.settings.max_acceleration_mm_per_s2[Z_AXIS]); + #if HAS_HOTEND + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 4, 210, MBASE(4), planner.settings.max_acceleration_mm_per_s2[E_AXIS]); + #endif +} + +inline void Draw_Max_Jerk_Menu() { + Clear_Main_Window(); + + if (HMI_IsChinese()) { + DWIN_Frame_TitleCopy(1, 1, 16, 28, 28); // "Jerk" + + DWIN_Frame_AreaCopy(1, 173, 133, 200, 147, LBLX , MBASE(1)); + DWIN_Frame_AreaCopy(1, 1, 180, 28, 192, LBLX + 27, MBASE(1) + 1); + DWIN_Frame_AreaCopy(1, 202, 133, 228, 147, LBLX + 53, MBASE(1)); + DWIN_Frame_AreaCopy(1, 229, 133, 236, 147, LBLX + 83, MBASE(1)); // Max Jerk speed X + DWIN_Frame_AreaCopy(1, 173, 133, 200, 147, LBLX , MBASE(2)); + DWIN_Frame_AreaCopy(1, 1, 180, 28, 192, LBLX + 27, MBASE(2) + 1); + DWIN_Frame_AreaCopy(1, 202, 133, 228, 147, LBLX + 53, MBASE(2)); + DWIN_Frame_AreaCopy(1, 1, 150, 7, 160, LBLX + 83, MBASE(2) + 3); // Max Jerk speed Y + DWIN_Frame_AreaCopy(1, 173, 133, 200, 147, LBLX , MBASE(3)); + DWIN_Frame_AreaCopy(1, 1, 180, 28, 192, LBLX + 27, MBASE(3) + 1); + DWIN_Frame_AreaCopy(1, 202, 133, 228, 147, LBLX + 53, MBASE(3)); + DWIN_Frame_AreaCopy(1, 9, 150, 16, 160, LBLX + 83, MBASE(3) + 3); // Max Jerk speed Z + #if HAS_HOTEND + DWIN_Frame_AreaCopy(1, 173, 133, 200, 147, LBLX , MBASE(4)); + DWIN_Frame_AreaCopy(1, 1, 180, 28, 192, LBLX + 27, MBASE(4) + 1); + DWIN_Frame_AreaCopy(1, 202, 133, 228, 147, LBLX + 53, MBASE(4)); + DWIN_Frame_AreaCopy(1, 18, 150, 25, 160, LBLX + 83, MBASE(4) + 3); // Max Jerk speed E + #endif + } + else { + #ifdef USE_STRING_HEADINGS + Draw_Title(GET_TEXT_F(MSG_JERK)); + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(1), F("Max Jerk X")); + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(2), F("Max Jerk Y")); + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(3), F("Max Jerk Z")); + #if HAS_HOTEND + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(4), F("Max Jerk E")); + #endif + #else + DWIN_Frame_TitleCopy(1, 144, 16, 189, 26); // "Jerk" + draw_max_en(MBASE(1)); // "Max" + draw_jerk_en(MBASE(1)); // "Jerk" + draw_speed_en(72, MBASE(1)); // "Speed" + say_x(115, MBASE(1)); // "X" + + draw_max_en(MBASE(2)); // "Max" + draw_jerk_en(MBASE(2)); // "Jerk" + draw_speed_en(72, MBASE(2)); // "Speed" + say_y(115, MBASE(2)); // "Y" + + draw_max_en(MBASE(3)); // "Max" + draw_jerk_en(MBASE(3)); // "Jerk" + draw_speed_en(72, MBASE(3)); // "Speed" + say_z(115, MBASE(3)); // "Z" + + #if HAS_HOTEND + draw_max_en(MBASE(4)); // "Max" + draw_jerk_en(MBASE(4)); // "Jerk" + draw_speed_en(72, MBASE(4)); // "Speed" + say_e(115, MBASE(4)); // "E" + #endif + #endif + } + + Draw_Back_First(); + LOOP_L_N(i, 3 + ENABLED(HAS_HOTEND)) Draw_Menu_Line(i + 1, ICON_MaxSpeedJerkX + i); + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 1, 210, MBASE(1), planner.max_jerk[X_AXIS] * MINUNITMULT); + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 1, 210, MBASE(2), planner.max_jerk[Y_AXIS] * MINUNITMULT); + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 1, 210, MBASE(3), planner.max_jerk[Z_AXIS] * MINUNITMULT); + #if HAS_HOTEND + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 1, 210, MBASE(4), planner.max_jerk[E_AXIS] * MINUNITMULT); + #endif +} + +inline void Draw_Steps_Menu() { + Clear_Main_Window(); + + if (HMI_IsChinese()) { + DWIN_Frame_TitleCopy(1, 1, 16, 28, 28); // "Steps per mm" + + DWIN_Frame_AreaCopy(1, 153, 148, 194, 161, LBLX, MBASE(1)); + DWIN_Frame_AreaCopy(1, 229, 133, 236, 147, LBLX + 44, MBASE(1)); // Transmission Ratio X + DWIN_Frame_AreaCopy(1, 153, 148, 194, 161, LBLX, MBASE(2)); + DWIN_Frame_AreaCopy(1, 1, 150, 7, 160, LBLX + 44, MBASE(2) + 3); // Transmission Ratio Y + DWIN_Frame_AreaCopy(1, 153, 148, 194, 161, LBLX, MBASE(3)); + DWIN_Frame_AreaCopy(1, 9, 150, 16, 160, LBLX + 44, MBASE(3) + 3); // Transmission Ratio Z + #if HAS_HOTEND + DWIN_Frame_AreaCopy(1, 153, 148, 194, 161, LBLX, MBASE(4)); + DWIN_Frame_AreaCopy(1, 18, 150, 25, 160, LBLX + 44, MBASE(4) + 3); // Transmission Ratio E + #endif + } + else { + #ifdef USE_STRING_HEADINGS + Draw_Title(GET_TEXT_F(MSG_STEPS_PER_MM)); + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(1), F("Steps/mm X")); + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(2), F("Steps/mm Y")); + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(3), F("Steps/mm Z")); + #if HAS_HOTEND + DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(4), F("Steps/mm E")); + #endif + #else + DWIN_Frame_TitleCopy(1, 144, 16, 189, 26); // "Steps per mm" + draw_steps_per_mm(MBASE(1)); say_x(103, MBASE(1)); // "Steps-per-mm X" + draw_steps_per_mm(MBASE(2)); say_y(103, MBASE(2)); // "Y" + draw_steps_per_mm(MBASE(3)); say_z(103, MBASE(3)); // "Z" + #if HAS_HOTEND + draw_steps_per_mm(MBASE(4)); say_e(103, MBASE(4)); // "E" + #endif + #endif + } + + Draw_Back_First(); + LOOP_L_N(i, 3 + ENABLED(HAS_HOTEND)) Draw_Menu_Line(i + 1, ICON_StepX + i); + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 1, 210, MBASE(1), planner.settings.axis_steps_per_mm[X_AXIS] * MINUNITMULT); + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 1, 210, MBASE(2), planner.settings.axis_steps_per_mm[Y_AXIS] * MINUNITMULT); + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 1, 210, MBASE(3), planner.settings.axis_steps_per_mm[Z_AXIS] * MINUNITMULT); + #if HAS_HOTEND + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 1, 210, MBASE(4), planner.settings.axis_steps_per_mm[E_AXIS] * MINUNITMULT); + #endif +} + +/* Motion */ +void HMI_Motion() { + ENCODER_DiffState encoder_diffState = get_encoder_state(); + if (encoder_diffState == ENCODER_DIFF_NO) return; + + // Avoid flicker by updating only the previous menu + if (encoder_diffState == ENCODER_DIFF_CW) { + if (select_motion.inc(1 + MOTION_CASE_TOTAL)) Move_Highlight(1, select_motion.now); + } + else if (encoder_diffState == ENCODER_DIFF_CCW) { + if (select_motion.dec()) Move_Highlight(-1, select_motion.now); + } + else if (encoder_diffState == ENCODER_DIFF_ENTER) { + switch (select_motion.now) { + case 0: // Back + checkkey = Control; + select_control.set(CONTROL_CASE_MOVE); + index_control = MROWS; + Draw_Control_Menu(); + break; + case MOTION_CASE_RATE: // Max speed + checkkey = MaxSpeed; + select_speed.reset(); + Draw_Max_Speed_Menu(); + break; + case MOTION_CASE_ACCEL: // Max acceleration + checkkey = MaxAcceleration; + select_acc.reset(); + Draw_Max_Accel_Menu(); + break; + #if HAS_CLASSIC_JERK + case MOTION_CASE_JERK: // Max jerk + checkkey = MaxJerk; + select_jerk.reset(); + Draw_Max_Jerk_Menu(); + break; + #endif + case MOTION_CASE_STEPS: // Steps per mm + checkkey = Step; + select_step.reset(); + Draw_Steps_Menu(); + break; + default: break; + } + } + DWIN_UpdateLCD(); +} + +/* Info */ +void HMI_Info() { + ENCODER_DiffState encoder_diffState = get_encoder_state(); + if (encoder_diffState == ENCODER_DIFF_NO) return; + if (encoder_diffState == ENCODER_DIFF_ENTER) { + #if HAS_ONESTEP_LEVELING + checkkey = Control; + select_control.set(CONTROL_CASE_INFO); + Draw_Control_Menu(); + #else + select_page.set(3); + Goto_MainMenu(); + #endif + } + DWIN_UpdateLCD(); +} + +/* Tune */ +void HMI_Tune() { + ENCODER_DiffState encoder_diffState = get_encoder_state(); + if (encoder_diffState == ENCODER_DIFF_NO) return; + + // Avoid flicker by updating only the previous menu + if (encoder_diffState == ENCODER_DIFF_CW) { + if (select_tune.inc(1 + TUNE_CASE_TOTAL)) { + if (select_tune.now > MROWS && select_tune.now > index_tune) { + index_tune = select_tune.now; + Scroll_Menu(DWIN_SCROLL_UP); + } + else { + Move_Highlight(1, select_tune.now + MROWS - index_tune); + } + } + } + else if (encoder_diffState == ENCODER_DIFF_CCW) { + if (select_tune.dec()) { + if (select_tune.now < index_tune - MROWS) { + index_tune--; + Scroll_Menu(DWIN_SCROLL_DOWN); + if (index_tune == MROWS) Draw_Back_First(); + } + else { + Move_Highlight(-1, select_tune.now + MROWS - index_tune); + } + } + } + else if (encoder_diffState == ENCODER_DIFF_ENTER) { + switch (select_tune.now) { + case 0: { // Back + select_print.set(0); + Goto_PrintProcess(); + } + break; + case TUNE_CASE_SPEED: // Print speed + checkkey = PrintSpeed; + HMI_ValueStruct.print_speed = feedrate_percentage; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 216, MBASE(TUNE_CASE_SPEED + MROWS - index_tune), feedrate_percentage); + EncoderRate.enabled = true; + break; + #if HAS_HOTEND + case TUNE_CASE_TEMP: // Nozzle temp + checkkey = ETemp; + HMI_ValueStruct.E_Temp = thermalManager.temp_hotend[0].target; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 216, MBASE(TUNE_CASE_TEMP + MROWS - index_tune), thermalManager.temp_hotend[0].target); + EncoderRate.enabled = true; + break; + #endif + #if HAS_HEATED_BED + case TUNE_CASE_BED: // Bed temp + checkkey = BedTemp; + HMI_ValueStruct.Bed_Temp = thermalManager.temp_bed.target; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 216, MBASE(TUNE_CASE_BED + MROWS - index_tune), thermalManager.temp_bed.target); + EncoderRate.enabled = true; + break; + #endif + #if HAS_FAN + case TUNE_CASE_FAN: // Fan speed + checkkey = FanSpeed; + HMI_ValueStruct.Fan_speed = thermalManager.fan_speed[0]; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 216, MBASE(TUNE_CASE_FAN + MROWS - index_tune), thermalManager.fan_speed[0]); + EncoderRate.enabled = true; + break; + #endif + #if HAS_ZOFFSET_ITEM + case TUNE_CASE_ZOFF: // Z-offset + #if EITHER(HAS_BED_PROBE, BABYSTEPPING) + checkkey = Homeoffset; + HMI_ValueStruct.offset_value = BABY_Z_VAR * 100; + DWIN_Draw_Signed_Float(font8x16, Select_Color, 2, 2, 202, MBASE(TUNE_CASE_ZOFF + MROWS - index_tune), HMI_ValueStruct.offset_value); + EncoderRate.enabled = true; + #else + // Apply workspace offset, making the current position 0,0,0 + queue.inject_P(PSTR("G92 X0 Y0 Z0")); + HMI_AudioFeedback(); + #endif + break; + #endif + default: break; + } + } + DWIN_UpdateLCD(); +} + +#if HAS_PREHEAT + + /* PLA Preheat */ + void HMI_PLAPreheatSetting() { + ENCODER_DiffState encoder_diffState = get_encoder_state(); + if (encoder_diffState == ENCODER_DIFF_NO) return; + + // Avoid flicker by updating only the previous menu + if (encoder_diffState == ENCODER_DIFF_CW) { + if (select_PLA.inc(1 + PREHEAT_CASE_TOTAL)) Move_Highlight(1, select_PLA.now); + } + else if (encoder_diffState == ENCODER_DIFF_CCW) { + if (select_PLA.dec()) Move_Highlight(-1, select_PLA.now); + } + else if (encoder_diffState == ENCODER_DIFF_ENTER) { + switch (select_PLA.now) { + case 0: // Back + checkkey = TemperatureID; + select_temp.now = TEMP_CASE_PLA; + HMI_ValueStruct.show_mode = -1; + Draw_Temperature_Menu(); + break; + #if HAS_HOTEND + case PREHEAT_CASE_TEMP: // Nozzle temperature + checkkey = ETemp; + HMI_ValueStruct.E_Temp = ui.material_preset[0].hotend_temp; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 216, MBASE(PREHEAT_CASE_TEMP), ui.material_preset[0].hotend_temp); + EncoderRate.enabled = true; + break; + #endif + #if HAS_HEATED_BED + case PREHEAT_CASE_BED: // Bed temperature + checkkey = BedTemp; + HMI_ValueStruct.Bed_Temp = ui.material_preset[0].bed_temp; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 216, MBASE(PREHEAT_CASE_BED), ui.material_preset[0].bed_temp); + EncoderRate.enabled = true; + break; + #endif + #if HAS_FAN + case PREHEAT_CASE_FAN: // Fan speed + checkkey = FanSpeed; + HMI_ValueStruct.Fan_speed = ui.material_preset[0].fan_speed; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 216, MBASE(PREHEAT_CASE_FAN), ui.material_preset[0].fan_speed); + EncoderRate.enabled = true; + break; + #endif + #if ENABLED(EEPROM_SETTINGS) + case 4: { // Save PLA configuration + const bool success = settings.save(); + HMI_AudioFeedback(success); + } break; + #endif + default: break; + } + } + DWIN_UpdateLCD(); + } + + /* ABS Preheat */ + void HMI_ABSPreheatSetting() { + ENCODER_DiffState encoder_diffState = get_encoder_state(); + if (encoder_diffState == ENCODER_DIFF_NO) return; + + // Avoid flicker by updating only the previous menu + if (encoder_diffState == ENCODER_DIFF_CW) { + if (select_ABS.inc(1 + PREHEAT_CASE_TOTAL)) Move_Highlight(1, select_ABS.now); + } + else if (encoder_diffState == ENCODER_DIFF_CCW) { + if (select_ABS.dec()) Move_Highlight(-1, select_ABS.now); + } + else if (encoder_diffState == ENCODER_DIFF_ENTER) { + switch (select_ABS.now) { + case 0: // Back + checkkey = TemperatureID; + select_temp.now = TEMP_CASE_ABS; + HMI_ValueStruct.show_mode = -1; + Draw_Temperature_Menu(); + break; + #if HAS_HOTEND + case PREHEAT_CASE_TEMP: // Set nozzle temperature + checkkey = ETemp; + HMI_ValueStruct.E_Temp = ui.material_preset[1].hotend_temp; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 216, MBASE(PREHEAT_CASE_TEMP), ui.material_preset[1].hotend_temp); + EncoderRate.enabled = true; + break; + #endif + #if HAS_HEATED_BED + case PREHEAT_CASE_BED: // Set bed temperature + checkkey = BedTemp; + HMI_ValueStruct.Bed_Temp = ui.material_preset[1].bed_temp; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 216, MBASE(PREHEAT_CASE_BED), ui.material_preset[1].bed_temp); + EncoderRate.enabled = true; + break; + #endif + #if HAS_FAN + case PREHEAT_CASE_FAN: // Set fan speed + checkkey = FanSpeed; + HMI_ValueStruct.Fan_speed = ui.material_preset[1].fan_speed; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 216, MBASE(PREHEAT_CASE_FAN), ui.material_preset[1].fan_speed); + EncoderRate.enabled = true; + break; + #endif + #if ENABLED(EEPROM_SETTINGS) + case PREHEAT_CASE_SAVE: { // Save ABS configuration + const bool success = settings.save(); + HMI_AudioFeedback(success); + } break; + #endif + default: break; + } + } + DWIN_UpdateLCD(); + } + +#endif + +/* Max Speed */ +void HMI_MaxSpeed() { + ENCODER_DiffState encoder_diffState = get_encoder_state(); + if (encoder_diffState == ENCODER_DIFF_NO) return; + + // Avoid flicker by updating only the previous menu + if (encoder_diffState == ENCODER_DIFF_CW) { + if (select_speed.inc(1 + 3 + ENABLED(HAS_HOTEND))) Move_Highlight(1, select_speed.now); + } + else if (encoder_diffState == ENCODER_DIFF_CCW) { + if (select_speed.dec()) Move_Highlight(-1, select_speed.now); + } + else if (encoder_diffState == ENCODER_DIFF_ENTER) { + if (WITHIN(select_speed.now, 1, 4)) { + checkkey = MaxSpeed_value; + HMI_flag.feedspeed_axis = AxisEnum(select_speed.now - 1); + HMI_ValueStruct.Max_Feedspeed = planner.settings.max_feedrate_mm_s[HMI_flag.feedspeed_axis]; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Select_Color, 4, 210, MBASE(select_speed.now), HMI_ValueStruct.Max_Feedspeed); + EncoderRate.enabled = true; + } + else { // Back + checkkey = Motion; + select_motion.now = MOTION_CASE_RATE; + Draw_Motion_Menu(); + } + } + DWIN_UpdateLCD(); +} + +/* Max Acceleration */ +void HMI_MaxAcceleration() { + ENCODER_DiffState encoder_diffState = get_encoder_state(); + if (encoder_diffState == ENCODER_DIFF_NO) return; + + // Avoid flicker by updating only the previous menu + if (encoder_diffState == ENCODER_DIFF_CW) { + if (select_acc.inc(1 + 3 + ENABLED(HAS_HOTEND))) Move_Highlight(1, select_acc.now); + } + else if (encoder_diffState == ENCODER_DIFF_CCW) { + if (select_acc.dec()) Move_Highlight(-1, select_acc.now); + } + else if (encoder_diffState == ENCODER_DIFF_ENTER) { + if (WITHIN(select_acc.now, 1, 4)) { + checkkey = MaxAcceleration_value; + HMI_flag.acc_axis = AxisEnum(select_acc.now - 1); + HMI_ValueStruct.Max_Acceleration = planner.settings.max_acceleration_mm_per_s2[HMI_flag.acc_axis]; + DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Select_Color, 4, 210, MBASE(select_acc.now), HMI_ValueStruct.Max_Acceleration); + EncoderRate.enabled = true; + } + else { // Back + checkkey = Motion; + select_motion.now = MOTION_CASE_ACCEL; + Draw_Motion_Menu(); + } + } + DWIN_UpdateLCD(); +} + +#if HAS_CLASSIC_JERK + /* Max Jerk */ + void HMI_MaxJerk() { + ENCODER_DiffState encoder_diffState = get_encoder_state(); + if (encoder_diffState == ENCODER_DIFF_NO) return; + + // Avoid flicker by updating only the previous menu + if (encoder_diffState == ENCODER_DIFF_CW) { + if (select_jerk.inc(1 + 3 + ENABLED(HAS_HOTEND))) Move_Highlight(1, select_jerk.now); + } + else if (encoder_diffState == ENCODER_DIFF_CCW) { + if (select_jerk.dec()) Move_Highlight(-1, select_jerk.now); + } + else if (encoder_diffState == ENCODER_DIFF_ENTER) { + if (WITHIN(select_jerk.now, 1, 4)) { + checkkey = MaxJerk_value; + HMI_flag.jerk_axis = AxisEnum(select_jerk.now - 1); + HMI_ValueStruct.Max_Jerk = planner.max_jerk[HMI_flag.jerk_axis] * MINUNITMULT; + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 1, 210, MBASE(select_jerk.now), HMI_ValueStruct.Max_Jerk); + EncoderRate.enabled = true; + } + else { // Back + checkkey = Motion; + select_motion.now = MOTION_CASE_JERK; + Draw_Motion_Menu(); + } + } + DWIN_UpdateLCD(); + } +#endif // HAS_CLASSIC_JERK + +/* Step */ +void HMI_Step() { + ENCODER_DiffState encoder_diffState = get_encoder_state(); + if (encoder_diffState == ENCODER_DIFF_NO) return; + + // Avoid flicker by updating only the previous menu + if (encoder_diffState == ENCODER_DIFF_CW) { + if (select_step.inc(1 + 3 + ENABLED(HAS_HOTEND))) Move_Highlight(1, select_step.now); + } + else if (encoder_diffState == ENCODER_DIFF_CCW) { + if (select_step.dec()) Move_Highlight(-1, select_step.now); + } + else if (encoder_diffState == ENCODER_DIFF_ENTER) { + if (WITHIN(select_step.now, 1, 4)) { + checkkey = Step_value; + HMI_flag.step_axis = AxisEnum(select_step.now - 1); + HMI_ValueStruct.Max_Step = planner.settings.axis_steps_per_mm[HMI_flag.step_axis] * MINUNITMULT; + DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Select_Color, 3, 1, 210, MBASE(select_step.now), HMI_ValueStruct.Max_Step); + EncoderRate.enabled = true; + } + else { // Back + checkkey = Motion; + select_motion.now = MOTION_CASE_STEPS; + Draw_Motion_Menu(); + } + } + DWIN_UpdateLCD(); +} + +void HMI_Init() { + HMI_SDCardInit(); + + for (uint16_t t = 0; t <= 100; t += 2) { + DWIN_ICON_Show(ICON, ICON_Bar, 15, 260); + DWIN_Draw_Rectangle(1, Color_Bg_Black, 15 + t * 242 / 100, 260, 257, 280); + DWIN_UpdateLCD(); + delay(20); + } + + HMI_SetLanguage(); +} + +void DWIN_Update() { + EachMomentUpdate(); // Status update + HMI_SDCardUpdate(); // SD card update + DWIN_HandleScreen(); // Rotary encoder update +} + +void EachMomentUpdate() { + static millis_t next_rts_update_ms = 0; + const millis_t ms = millis(); + if (PENDING(ms, next_rts_update_ms)) return; + next_rts_update_ms = ms + DWIN_SCROLL_UPDATE_INTERVAL; + + // variable update + update_variable(); + + if (checkkey == PrintProcess) { + // if print done + if (HMI_flag.print_finish && !HMI_flag.done_confirm_flag) { + HMI_flag.print_finish = false; + HMI_flag.done_confirm_flag = true; + + TERN_(POWER_LOSS_RECOVERY, recovery.cancel()); + + planner.finish_and_disable(); + + // show percent bar and value + Percentrecord = 0; + Draw_Print_ProgressBar(); + + // show print done confirm + DWIN_Draw_Rectangle(1, Color_Bg_Black, 0, 250, DWIN_WIDTH - 1, STATUS_Y); + DWIN_ICON_Show(ICON, HMI_IsChinese() ? ICON_Confirm_C : ICON_Confirm_E, 86, 283); + } + else if (HMI_flag.pause_flag != printingIsPaused()) { + // print status update + HMI_flag.pause_flag = printingIsPaused(); + if (HMI_flag.pause_flag) ICON_Continue(); else ICON_Pause(); + } + } + + // pause after homing + if (HMI_flag.pause_action && printingIsPaused() && !planner.has_blocks_queued()) { + HMI_flag.pause_action = false; + #if ENABLED(PAUSE_HEAT) + #if HAS_HEATED_BED + tempbed = thermalManager.temp_bed.target; + #endif + #if HAS_HOTEND + temphot = thermalManager.temp_hotend[0].target; + #endif + thermalManager.disable_all_heaters(); + #endif + queue.inject_P(PSTR("G1 F1200 X0 Y0")); + } + + if (card.isPrinting() && checkkey == PrintProcess) { // print process + const uint8_t card_pct = card.percentDone(); + static uint8_t last_cardpercentValue = 101; + if (last_cardpercentValue != card_pct) { // print percent + last_cardpercentValue = card_pct; + if (card_pct) { + Percentrecord = card_pct; + Draw_Print_ProgressBar(); + } + } + + duration_t elapsed = print_job_timer.duration(); // print timer + + // Print time so far + static uint16_t last_Printtime = 0; + const uint16_t min = (elapsed.value % 3600) / 60; + if (last_Printtime != min) { // 1 minute update + last_Printtime = min; + Draw_Print_ProgressElapsed(); + } + + // Estimate remaining time every 20 seconds + static millis_t next_remain_time_update = 0; + if (Percentrecord > 1 && ELAPSED(ms, next_remain_time_update) && !HMI_flag.heat_flag) { + remain_time = (elapsed.value - dwin_heat_time) / (Percentrecord * 0.01f) - (elapsed.value - dwin_heat_time); + next_remain_time_update += 20 * 1000UL; + Draw_Print_ProgressRemain(); + } + } + else if (dwin_abort_flag && !HMI_flag.home_flag) { // Print Stop + dwin_abort_flag = false; + HMI_ValueStruct.print_speed = feedrate_percentage = 100; + dwin_zoffset = TERN0(HAS_BED_PROBE, probe.offset.z); + select_page.set(0); + Goto_MainMenu(); + } + #if ENABLED(POWER_LOSS_RECOVERY) + else if (DWIN_lcd_sd_status && recovery.dwin_flag) { // resume print before power off + static bool recovery_flag = false; + + recovery.dwin_flag = false; + recovery_flag = true; + + auto update_selection = [&](const bool sel) { + HMI_flag.select_flag = sel; + const uint16_t c1 = sel ? Color_Bg_Window : Select_Color; + DWIN_Draw_Rectangle(0, c1, 25, 306, 126, 345); + DWIN_Draw_Rectangle(0, c1, 24, 305, 127, 346); + const uint16_t c2 = sel ? Select_Color : Color_Bg_Window; + DWIN_Draw_Rectangle(0, c2, 145, 306, 246, 345); + DWIN_Draw_Rectangle(0, c2, 144, 305, 247, 346); + }; + + Popup_Window_Resume(); + update_selection(true); + + // TODO: Get the name of the current file from someplace + // + //(void)recovery.interrupted_file_exists(); + char * const name = card.longest_filename(); + const int8_t npos = _MAX(0U, DWIN_WIDTH - strlen(name) * (MENU_CHR_W)) / 2; + DWIN_Draw_String(false, true, font8x16, Popup_Text_Color, Color_Bg_Window, npos, 252, name); + DWIN_UpdateLCD(); + + while (recovery_flag) { + ENCODER_DiffState encoder_diffState = Encoder_ReceiveAnalyze(); + if (encoder_diffState != ENCODER_DIFF_NO) { + if (encoder_diffState == ENCODER_DIFF_ENTER) { + recovery_flag = false; + if (HMI_flag.select_flag) break; + TERN_(POWER_LOSS_RECOVERY, queue.inject_P(PSTR("M1000C"))); + HMI_StartFrame(true); + return; + } + else + update_selection(encoder_diffState == ENCODER_DIFF_CW); + + DWIN_UpdateLCD(); + } + } + + select_print.set(0); + HMI_ValueStruct.show_mode = 0; + queue.inject_P(PSTR("M1000")); + Goto_PrintProcess(); + Draw_Status_Area(true); + } + #endif + DWIN_UpdateLCD(); +} + +void DWIN_HandleScreen() { + switch (checkkey) { + case MainMenu: HMI_MainMenu(); break; + case SelectFile: HMI_SelectFile(); break; + case Prepare: HMI_Prepare(); break; + case Control: HMI_Control(); break; + case Leveling: break; + case PrintProcess: HMI_Printing(); break; + case Print_window: HMI_PauseOrStop(); break; + case AxisMove: HMI_AxisMove(); break; + case TemperatureID: HMI_Temperature(); break; + case Motion: HMI_Motion(); break; + case Info: HMI_Info(); break; + case Tune: HMI_Tune(); break; + #if HAS_PREHEAT + case PLAPreheat: HMI_PLAPreheatSetting(); break; + case ABSPreheat: HMI_ABSPreheatSetting(); break; + #endif + case MaxSpeed: HMI_MaxSpeed(); break; + case MaxAcceleration: HMI_MaxAcceleration(); break; + case MaxJerk: HMI_MaxJerk(); break; + case Step: HMI_Step(); break; + case Move_X: HMI_Move_X(); break; + case Move_Y: HMI_Move_Y(); break; + case Move_Z: HMI_Move_Z(); break; + #if HAS_HOTEND + case Extruder: HMI_Move_E(); break; + case ETemp: HMI_ETemp(); break; + #endif + #if EITHER(HAS_BED_PROBE, BABYSTEPPING) + case Homeoffset: HMI_Zoffset(); break; + #endif + #if HAS_HEATED_BED + case BedTemp: HMI_BedTemp(); break; + #endif + #if HAS_PREHEAT + case FanSpeed: HMI_FanSpeed(); break; + #endif + case PrintSpeed: HMI_PrintSpeed(); break; + case MaxSpeed_value: HMI_MaxFeedspeedXYZE(); break; + case MaxAcceleration_value: HMI_MaxAccelerationXYZE(); break; + case MaxJerk_value: HMI_MaxJerkXYZE(); break; + case Step_value: HMI_StepXYZE(); break; + default: break; + } +} + +void DWIN_CompletedHoming() { + HMI_flag.home_flag = false; + if (checkkey == Last_Prepare) { + checkkey = Prepare; + select_prepare.now = PREPARE_CASE_HOME; + index_prepare = MROWS; + Draw_Prepare_Menu(); + } + else if (checkkey == Back_Main) { + HMI_ValueStruct.print_speed = feedrate_percentage = 100; + dwin_zoffset = TERN0(HAS_BED_PROBE, probe.offset.z); + planner.finish_and_disable(); + Goto_MainMenu(); + } +} + +void DWIN_CompletedLeveling() { + if (checkkey == Leveling) Goto_MainMenu(); +} + +#endif // DWIN_CREALITY_LCD diff --git a/Marlin/src/lcd/dwin/e3v2/dwin.h b/Marlin/src/lcd/dwin/e3v2/dwin.h new file mode 100644 index 000000000000..5bff2e9f7890 --- /dev/null +++ b/Marlin/src/lcd/dwin/e3v2/dwin.h @@ -0,0 +1,373 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * DWIN by Creality3D + */ + +#include "../dwin_lcd.h" +#include "rotary_encoder.h" +#include "../../../libs/BL24CXX.h" + +#include "../../../inc/MarlinConfigPre.h" + +#if ANY(HAS_HOTEND, HAS_HEATED_BED, HAS_FAN) && PREHEAT_COUNT + #define HAS_PREHEAT 1 + #if PREHEAT_COUNT < 2 + #error "Creality DWIN requires two material preheat presets." + #endif +#endif + +enum processID : uint8_t { + // Process ID + MainMenu, + SelectFile, + Prepare, + Control, + Leveling, + PrintProcess, + AxisMove, + TemperatureID, + Motion, + Info, + Tune, + #if HAS_PREHEAT + PLAPreheat, + ABSPreheat, + #endif + MaxSpeed, + MaxSpeed_value, + MaxAcceleration, + MaxAcceleration_value, + MaxJerk, + MaxJerk_value, + Step, + Step_value, + + // Last Process ID + Last_Prepare, + + // Back Process ID + Back_Main, + Back_Print, + + // Date variable ID + Move_X, + Move_Y, + Move_Z, + #if HAS_HOTEND + Extruder, + ETemp, + #endif + Homeoffset, + #if HAS_HEATED_BED + BedTemp, + #endif + #if HAS_FAN + FanSpeed, + #endif + PrintSpeed, + + // Window ID + Print_window, + Popup_Window +}; + +// Picture ID +#define Start_Process 0 +#define Language_English 1 +#define Language_Chinese 2 + +// ICON ID +#define ICON 0x09 +#define ICON_LOGO 0 +#define ICON_Print_0 1 +#define ICON_Print_1 2 +#define ICON_Prepare_0 3 +#define ICON_Prepare_1 4 +#define ICON_Control_0 5 +#define ICON_Control_1 6 +#define ICON_Leveling_0 7 +#define ICON_Leveling_1 8 +#define ICON_HotendTemp 9 +#define ICON_BedTemp 10 +#define ICON_Speed 11 +#define ICON_Zoffset 12 +#define ICON_Back 13 +#define ICON_File 14 +#define ICON_PrintTime 15 +#define ICON_RemainTime 16 +#define ICON_Setup_0 17 +#define ICON_Setup_1 18 +#define ICON_Pause_0 19 +#define ICON_Pause_1 20 +#define ICON_Continue_0 21 +#define ICON_Continue_1 22 +#define ICON_Stop_0 23 +#define ICON_Stop_1 24 +#define ICON_Bar 25 +#define ICON_More 26 + +#define ICON_Axis 27 +#define ICON_CloseMotor 28 +#define ICON_Homing 29 +#define ICON_SetHome 30 +#define ICON_PLAPreheat 31 +#define ICON_ABSPreheat 32 +#define ICON_Cool 33 +#define ICON_Language 34 + +#define ICON_MoveX 35 +#define ICON_MoveY 36 +#define ICON_MoveZ 37 +#define ICON_Extruder 38 + +#define ICON_Temperature 40 +#define ICON_Motion 41 +#define ICON_WriteEEPROM 42 +#define ICON_ReadEEPROM 43 +#define ICON_ResumeEEPROM 44 +#define ICON_Info 45 + +#define ICON_SetEndTemp 46 +#define ICON_SetBedTemp 47 +#define ICON_FanSpeed 48 +#define ICON_SetPLAPreheat 49 +#define ICON_SetABSPreheat 50 + +#define ICON_MaxSpeed 51 +#define ICON_MaxAccelerated 52 +#define ICON_MaxJerk 53 +#define ICON_Step 54 +#define ICON_PrintSize 55 +#define ICON_Version 56 +#define ICON_Contact 57 +#define ICON_StockConfiguraton 58 +#define ICON_MaxSpeedX 59 +#define ICON_MaxSpeedY 60 +#define ICON_MaxSpeedZ 61 +#define ICON_MaxSpeedE 62 +#define ICON_MaxAccX 63 +#define ICON_MaxAccY 64 +#define ICON_MaxAccZ 65 +#define ICON_MaxAccE 66 +#define ICON_MaxSpeedJerkX 67 +#define ICON_MaxSpeedJerkY 68 +#define ICON_MaxSpeedJerkZ 69 +#define ICON_MaxSpeedJerkE 70 +#define ICON_StepX 71 +#define ICON_StepY 72 +#define ICON_StepZ 73 +#define ICON_StepE 74 +#define ICON_Setspeed 75 +#define ICON_SetZOffset 76 +#define ICON_Rectangle 77 +#define ICON_BLTouch 78 +#define ICON_TempTooLow 79 +#define ICON_AutoLeveling 80 +#define ICON_TempTooHigh 81 +#define ICON_NoTips_C 82 +#define ICON_NoTips_E 83 +#define ICON_Continue_C 84 +#define ICON_Continue_E 85 +#define ICON_Cancel_C 86 +#define ICON_Cancel_E 87 +#define ICON_Confirm_C 88 +#define ICON_Confirm_E 89 +#define ICON_Info_0 90 +#define ICON_Info_1 91 + +/** + * 3-.0:The font size, 0x00-0x09, corresponds to the font size below: + * 0x00=6*12 0x01=8*16 0x02=10*20 0x03=12*24 0x04=14*28 + * 0x05=16*32 0x06=20*40 0x07=24*48 0x08=28*56 0x09=32*64 + */ +#define font6x12 0x00 +#define font8x16 0x01 +#define font10x20 0x02 +#define font12x24 0x03 +#define font14x28 0x04 +#define font16x32 0x05 +#define font20x40 0x06 +#define font24x48 0x07 +#define font28x56 0x08 +#define font32x64 0x09 + +// Color +#define Color_White 0xFFFF +#define Color_Yellow 0xFF0F +#define Color_Bg_Window 0x31E8 // Popup background color +#define Color_Bg_Blue 0x1125 // Dark blue background color +#define Color_Bg_Black 0x0841 // Black background color +#define Color_Bg_Red 0xF00F // Red background color +#define Popup_Text_Color 0xD6BA // Popup font background color +#define Line_Color 0x3A6A // Split line color +#define Rectangle_Color 0xEE2F // Blue square cursor color +#define Percent_Color 0xFE29 // Percentage color +#define BarFill_Color 0x10E4 // Fill color of progress bar +#define Select_Color 0x33BB // Selected color + +extern uint8_t checkkey; +extern float zprobe_zoffset; +extern char print_filename[16]; + +extern millis_t dwin_heat_time; + +typedef struct { + TERN_(HAS_HOTEND, int16_t E_Temp = 0); + TERN_(HAS_HEATED_BED, int16_t Bed_Temp = 0); + TERN_(HAS_PREHEAT, int16_t Fan_speed = 0); + int16_t print_speed = 100; + float Max_Feedspeed = 0; + float Max_Acceleration = 0; + float Max_Jerk = 0; + float Max_Step = 0; + float Move_X_scale = 0; + float Move_Y_scale = 0; + float Move_Z_scale = 0; + #if HAS_HOTEND + float Move_E_scale = 0; + #endif + float offset_value = 0; + char show_mode = 0; // -1: Temperature control 0: Printing temperature +} HMI_value_t; + +#define DWIN_CHINESE 123 +#define DWIN_ENGLISH 0 + +typedef struct { + uint8_t language; + bool pause_flag:1; + bool pause_action:1; + bool print_finish:1; + bool done_confirm_flag:1; + bool select_flag:1; + bool home_flag:1; + bool heat_flag:1; // 0: heating done 1: during heating + #if ENABLED(PREVENT_COLD_EXTRUSION) + bool ETempTooLow_flag:1; + #endif + #if HAS_LEVELING + bool leveling_offset_flag:1; + #endif + #if HAS_FAN + AxisEnum feedspeed_axis; + #endif + AxisEnum acc_axis, jerk_axis, step_axis; +} HMI_Flag_t; + +extern HMI_value_t HMI_ValueStruct; +extern HMI_Flag_t HMI_flag; + +// Show ICO +void ICON_Print(bool show); +void ICON_Prepare(bool show); +void ICON_Control(bool show); +void ICON_Leveling(bool show); +void ICON_StartInfo(bool show); + +void ICON_Setting(bool show); +void ICON_Pause(bool show); +void ICON_Continue(bool show); +void ICON_Stop(bool show); + +#if HAS_HOTEND || HAS_HEATED_BED + // Popup message window + void DWIN_Popup_Temperature(const bool toohigh); +#endif + +#if HAS_HOTEND + void Popup_Window_ETempTooLow(); +#endif + +void Popup_Window_Resume(); +void Popup_Window_Home(const bool parking=false); +void Popup_Window_Leveling(); + +void Goto_PrintProcess(); +void Goto_MainMenu(); + +// Variable control +void HMI_Move_X(); +void HMI_Move_Y(); +void HMI_Move_Z(); +void HMI_Move_E(); + +void HMI_Zoffset(); + +TERN_(HAS_HOTEND, void HMI_ETemp()); +TERN_(HAS_HEATED_BED, void HMI_BedTemp()); +TERN_(HAS_FAN, void HMI_FanSpeed()); + +void HMI_PrintSpeed(); + +void HMI_MaxFeedspeedXYZE(); +void HMI_MaxAccelerationXYZE(); +void HMI_MaxJerkXYZE(); +void HMI_StepXYZE(); + +void update_variable(); +void DWIN_Draw_Signed_Float(uint8_t size, uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, long value); + +// SD Card +void HMI_SDCardInit(); +void HMI_SDCardUpdate(); + +// Main Process +void Icon_print(bool value); +void Icon_control(bool value); +void Icon_temperature(bool value); +void Icon_leveling(bool value); + +// Other +void Draw_Status_Area(const bool with_update); // Status Area +void HMI_StartFrame(const bool with_update); // Prepare the menu view +void HMI_MainMenu(); // Main process screen +void HMI_SelectFile(); // File page +void HMI_Printing(); // Print page +void HMI_Prepare(); // Prepare page +void HMI_Control(); // Control page +void HMI_Leveling(); // Level the page +void HMI_AxisMove(); // Axis movement menu +void HMI_Temperature(); // Temperature menu +void HMI_Motion(); // Sports menu +void HMI_Info(); // Information menu +void HMI_Tune(); // Adjust the menu + +#if HAS_PREHEAT + void HMI_PLAPreheatSetting(); // PLA warm-up setting + void HMI_ABSPreheatSetting(); // ABS warm-up setting +#endif + +void HMI_MaxSpeed(); // Maximum speed submenu +void HMI_MaxAcceleration(); // Maximum acceleration submenu +void HMI_MaxJerk(); // Maximum jerk speed submenu +void HMI_Step(); // Transmission ratio + +void HMI_Init(); +void DWIN_Update(); +void EachMomentUpdate(); +void DWIN_HandleScreen(); + +void DWIN_CompletedHoming(); +void DWIN_CompletedLeveling(); diff --git a/Marlin/src/lcd/dwin/e3v2/rotary_encoder.cpp b/Marlin/src/lcd/dwin/e3v2/rotary_encoder.cpp new file mode 100644 index 000000000000..d39c6cfbd5e8 --- /dev/null +++ b/Marlin/src/lcd/dwin/e3v2/rotary_encoder.cpp @@ -0,0 +1,254 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/***************************************************************************** + * @file rotary_encoder.cpp + * @author LEO / Creality3D + * @date 2019/07/06 + * @version 2.0.1 + * @brief Rotary encoder functions + *****************************************************************************/ + +#include "../../../inc/MarlinConfigPre.h" + +#if ENABLED(DWIN_CREALITY_LCD) + +#include "rotary_encoder.h" + +#include "../../../MarlinCore.h" +#include "../../../HAL/shared/Delay.h" + +#if HAS_BUZZER + #include "../../../libs/buzzer.h" +#endif + +#include + +ENCODER_Rate EncoderRate; + +// Buzzer +void Encoder_tick(void) { + WRITE(BEEPER_PIN, 1); + delay(10); + WRITE(BEEPER_PIN, 0); +} + +// Encoder initialization +void Encoder_Configuration(void) { + #if BUTTON_EXISTS(EN1) + SET_INPUT_PULLUP(BTN_EN1); + #endif + #if BUTTON_EXISTS(EN2) + SET_INPUT_PULLUP(BTN_EN2); + #endif + #if BUTTON_EXISTS(ENC) + SET_INPUT_PULLUP(BTN_ENC); + #endif + #ifdef BEEPER_PIN + SET_OUTPUT(BEEPER_PIN); + #endif +} + +// Analyze encoder value and return state +ENCODER_DiffState Encoder_ReceiveAnalyze(void) { + const millis_t now = millis(); + static unsigned char lastEncoderBits; + unsigned char newbutton = 0; + static signed char temp_diff = 0; + + ENCODER_DiffState temp_diffState = ENCODER_DIFF_NO; + if (BUTTON_PRESSED(EN1)) newbutton |= 0x01; + if (BUTTON_PRESSED(EN2)) newbutton |= 0x02; + if (BUTTON_PRESSED(ENC)) { + static millis_t next_click_update_ms; + if (ELAPSED(now, next_click_update_ms)) { + next_click_update_ms = millis() + 300; + Encoder_tick(); + #if PIN_EXISTS(LCD_LED) + //LED_Action(); + #endif + const bool was_waiting = wait_for_user; + wait_for_user = false; + return was_waiting ? ENCODER_DIFF_NO : ENCODER_DIFF_ENTER; + } + else return ENCODER_DIFF_NO; + } + if (newbutton != lastEncoderBits) { + switch (newbutton) { + case ENCODER_PHASE_0: { + if (lastEncoderBits == ENCODER_PHASE_3) temp_diff++; + else if (lastEncoderBits == ENCODER_PHASE_1) temp_diff--; + }break; + case ENCODER_PHASE_1: { + if (lastEncoderBits == ENCODER_PHASE_0) temp_diff++; + else if (lastEncoderBits == ENCODER_PHASE_2) temp_diff--; + }break; + case ENCODER_PHASE_2: { + if (lastEncoderBits == ENCODER_PHASE_1) temp_diff++; + else if (lastEncoderBits == ENCODER_PHASE_3) temp_diff--; + }break; + case ENCODER_PHASE_3: { + if (lastEncoderBits == ENCODER_PHASE_2) temp_diff++; + else if (lastEncoderBits == ENCODER_PHASE_0) temp_diff--; + }break; + } + lastEncoderBits = newbutton; + } + + if (abs(temp_diff) >= ENCODER_PULSES_PER_STEP) { + if (temp_diff > 0) temp_diffState = ENCODER_DIFF_CW; + else temp_diffState = ENCODER_DIFF_CCW; + + #if ENABLED(ENCODER_RATE_MULTIPLIER) + + millis_t ms = millis(); + int32_t encoderMultiplier = 1; + + // if must encoder rati multiplier + if (EncoderRate.enabled) { + const float abs_diff = ABS(temp_diff), + encoderMovementSteps = abs_diff / (ENCODER_PULSES_PER_STEP); + if (EncoderRate.lastEncoderTime) { + // Note that the rate is always calculated between two passes through the + // loop and that the abs of the temp_diff value is tracked. + const float encoderStepRate = encoderMovementSteps / float(ms - EncoderRate.lastEncoderTime) * 1000; + if (encoderStepRate >= ENCODER_100X_STEPS_PER_SEC) encoderMultiplier = 100; + else if (encoderStepRate >= ENCODER_10X_STEPS_PER_SEC) encoderMultiplier = 10; + else if (encoderStepRate >= ENCODER_5X_STEPS_PER_SEC) encoderMultiplier = 5; + } + EncoderRate.lastEncoderTime = ms; + } + #else + constexpr int32_t encoderMultiplier = 1; + #endif // ENCODER_RATE_MULTIPLIER + + // EncoderRate.encoderMoveValue += (temp_diff * encoderMultiplier) / (ENCODER_PULSES_PER_STEP); + EncoderRate.encoderMoveValue = (temp_diff * encoderMultiplier) / (ENCODER_PULSES_PER_STEP); + if (EncoderRate.encoderMoveValue < 0) EncoderRate.encoderMoveValue = -EncoderRate.encoderMoveValue; + + temp_diff = 0; + } + return temp_diffState; +} + +#if PIN_EXISTS(LCD_LED) + + // Take the low 24 valid bits 24Bit: G7 G6 G5 G4 G3 G2 G1 G0 R7 R6 R5 R4 R3 R2 R1 R0 B7 B6 B5 B4 B3 B2 B1 B0 + unsigned int LED_DataArray[LED_NUM]; + + // LED light operation + void LED_Action(void) { + LED_Control(RGB_SCALE_WARM_WHITE,0x0F); + delay(30); + LED_Control(RGB_SCALE_WARM_WHITE,0x00); + } + + // LED initialization + void LED_Configuration(void) { + SET_OUTPUT(LCD_LED_PIN); + } + + // LED write data + void LED_WriteData(void) { + unsigned char tempCounter_LED, tempCounter_Bit; + for (tempCounter_LED = 0; tempCounter_LED < LED_NUM; tempCounter_LED++) { + for (tempCounter_Bit = 0; tempCounter_Bit < 24; tempCounter_Bit++) { + if (LED_DataArray[tempCounter_LED] & (0x800000 >> tempCounter_Bit)) { + LED_DATA_HIGH; + DELAY_NS(300); + LED_DATA_LOW; + DELAY_NS(200); + } + else { + LED_DATA_HIGH; + LED_DATA_LOW; + DELAY_NS(200); + } + } + } + } + + // LED control + // RGB_Scale: RGB color ratio + // luminance: brightness (0~0xFF) + void LED_Control(unsigned char RGB_Scale, unsigned char luminance) { + unsigned char temp_Counter; + for (temp_Counter = 0; temp_Counter < LED_NUM; temp_Counter++) { + LED_DataArray[temp_Counter] = 0; + switch (RGB_Scale) { + case RGB_SCALE_R10_G7_B5: LED_DataArray[temp_Counter] = (luminance*10/10) << 8 | (luminance*7/10) << 16 | luminance*5/10; break; + case RGB_SCALE_R10_G7_B4: LED_DataArray[temp_Counter] = (luminance*10/10) << 8 | (luminance*7/10) << 16 | luminance*4/10; break; + case RGB_SCALE_R10_G8_B7: LED_DataArray[temp_Counter] = (luminance*10/10) << 8 | (luminance*8/10) << 16 | luminance*7/10; break; + } + } + LED_WriteData(); + } + + // LED gradient control + // RGB_Scale: RGB color ratio + // luminance: brightness (0~0xFF) + // change_Time: gradient time (ms) + void LED_GraduallyControl(unsigned char RGB_Scale, unsigned char luminance, unsigned int change_Interval) { + unsigned char temp_Counter; + unsigned char LED_R_Data[LED_NUM], LED_G_Data[LED_NUM], LED_B_Data[LED_NUM]; + bool LED_R_Flag = 0, LED_G_Flag = 0, LED_B_Flag = 0; + + for (temp_Counter = 0; temp_Counter < LED_NUM; temp_Counter++) { + switch (RGB_Scale) { + case RGB_SCALE_R10_G7_B5: { + LED_R_Data[temp_Counter] = luminance*10/10; + LED_G_Data[temp_Counter] = luminance*7/10; + LED_B_Data[temp_Counter] = luminance*5/10; + }break; + case RGB_SCALE_R10_G7_B4: { + LED_R_Data[temp_Counter] = luminance*10/10; + LED_G_Data[temp_Counter] = luminance*7/10; + LED_B_Data[temp_Counter] = luminance*4/10; + }break; + case RGB_SCALE_R10_G8_B7: { + LED_R_Data[temp_Counter] = luminance*10/10; + LED_G_Data[temp_Counter] = luminance*8/10; + LED_B_Data[temp_Counter] = luminance*7/10; + }break; + } + } + for (temp_Counter = 0; temp_Counter < LED_NUM; temp_Counter++) { + if ((unsigned char)(LED_DataArray[temp_Counter] >> 8) > LED_R_Data[temp_Counter]) LED_DataArray[temp_Counter] -= 0x000100; + else if ((unsigned char)(LED_DataArray[temp_Counter] >> 8) < LED_R_Data[temp_Counter]) LED_DataArray[temp_Counter] += 0x000100; + while (1) { + else LED_R_Flag = 1; + if ((unsigned char)(LED_DataArray[temp_Counter]>>16) > LED_G_Data[temp_Counter]) LED_DataArray[temp_Counter] -= 0x010000; + else if ((unsigned char)(LED_DataArray[temp_Counter]>>16) < LED_G_Data[temp_Counter]) LED_DataArray[temp_Counter] += 0x010000; + else LED_G_Flag = 1; + if ((unsigned char)LED_DataArray[temp_Counter] > LED_B_Data[temp_Counter]) LED_DataArray[temp_Counter] -= 0x000001; + else if ((unsigned char)LED_DataArray[temp_Counter] < LED_B_Data[temp_Counter]) LED_DataArray[temp_Counter] += 0x000001; + else LED_B_Flag = 1; + } + LED_WriteData(); + if (LED_R_Flag && LED_G_Flag && LED_B_Flag) break; + else delay(change_Interval); + } + } + +#endif // LCD_LED + +#endif // DWIN_CREALITY_LCD diff --git a/Marlin/src/lcd/dwin/e3v2/rotary_encoder.h b/Marlin/src/lcd/dwin/e3v2/rotary_encoder.h new file mode 100644 index 000000000000..93e54839d625 --- /dev/null +++ b/Marlin/src/lcd/dwin/e3v2/rotary_encoder.h @@ -0,0 +1,104 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/***************************************************************************** + * @file rotary_encoder.h + * @author LEO / Creality3D + * @date 2019/07/06 + * @version 2.0.1 + * @brief Rotary encoder functions + ****************************************************************************/ + +#include "../../../inc/MarlinConfig.h" +#include "../../../MarlinCore.h" + +/*********************** Encoder Set ***********************/ + +#define ENCODER_PHASE_0 0 +#define ENCODER_PHASE_1 2 +#define ENCODER_PHASE_2 3 +#define ENCODER_PHASE_3 1 + +#define ENCODER_PULSES_PER_STEP 4 + +#define BUTTON_PRESSED(BN) !READ(BTN_## BN) + +typedef struct { + bool enabled = false; + int encoderMoveValue = 0; + millis_t lastEncoderTime = 0; +} ENCODER_Rate; + +extern ENCODER_Rate EncoderRate; + +typedef enum { + ENCODER_DIFF_NO = 0, // no state + ENCODER_DIFF_CW = 1, // clockwise rotation + ENCODER_DIFF_CCW = 2, // counterclockwise rotation + ENCODER_DIFF_ENTER = 3 // click +} ENCODER_DiffState; + +// Encoder initialization +void Encoder_Configuration(void); + +// Analyze encoder value and return state +ENCODER_DiffState Encoder_ReceiveAnalyze(void); + +/*********************** Encoder LED ***********************/ + +#if PIN_EXISTS(LCD_LED) + + #define LED_NUM 4 + #define LED_DATA_HIGH WRITE(LCD_LED_PIN, 1) + #define LED_DATA_LOW WRITE(LCD_LED_PIN, 0) + + #define RGB_SCALE_R10_G7_B5 1 + #define RGB_SCALE_R10_G7_B4 2 + #define RGB_SCALE_R10_G8_B7 3 + #define RGB_SCALE_NEUTRAL_WHITE RGB_SCALE_R10_G7_B5 + #define RGB_SCALE_WARM_WHITE RGB_SCALE_R10_G7_B4 + #define RGB_SCALE_COOL_WHITE RGB_SCALE_R10_G8_B7 + + extern unsigned int LED_DataArray[LED_NUM]; + + // LED light operation + void LED_Action(void); + + // LED initialization + void LED_Configuration(void); + + // LED write data + void LED_WriteData(void); + + // LED control + // RGB_Scale: RGB color ratio + // luminance: brightness (0~0xFF) + void LED_Control(unsigned char RGB_Scale, unsigned char luminance); + + // LED gradient control + // RGB_Scale: RGB color ratio + // luminance: brightness (0~0xFF) + // change_Time: gradient time (ms) + void LED_GraduallyControl(unsigned char RGB_Scale, unsigned char luminance, unsigned int change_Interval); + +#endif // LCD_LED diff --git a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinitionOrigin.cpp b/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinitionOrigin.cpp deleted file mode 100644 index 51f292421a0d..000000000000 --- a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinitionOrigin.cpp +++ /dev/null @@ -1,308 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/* DGUS implementation written by coldtobi in 2019 for Marlin */ - -#include "../../../../inc/MarlinConfigPre.h" - -#if ENABLED(DGUS_LCD_UI_ORIGIN) - -#include "DGUSDisplayDefinition.h" -#include "DGUSDisplay.h" - -#include "../../../../module/temperature.h" -#include "../../../../module/motion.h" -#include "../../../../module/planner.h" - -#include "../../../ultralcd.h" - -#if ENABLED(DUGS_UI_MOVE_DIS_OPTION) - uint16_t distanceToMove = 0.1; -#endif - -const uint16_t VPList_Boot[] PROGMEM = { - VP_MARLIN_VERSION, - 0x0000 -}; - -const uint16_t VPList_Main[] PROGMEM = { - /* VP_M117, for completeness, but it cannot be auto-uploaded. */ - 0x0000 -}; - -const uint16_t VPList_Temp[] PROGMEM = { - #if HOTENDS >= 1 - VP_T_E0_Is, VP_T_E0_Set, - #endif - #if HOTENDS >= 2 - VP_T_E1_Is, VP_T_E1_Set, - #endif - #if HAS_HEATED_BED - VP_T_Bed_Is, VP_T_Bed_Set, - #endif - 0x0000 -}; - -const uint16_t VPList_Status[] PROGMEM = { - /* VP_M117, for completeness, but it cannot be auto-uploaded */ - #if HOTENDS >= 1 - VP_T_E0_Is, VP_T_E0_Set, - #endif - #if HOTENDS >= 2 - VP_T_E1_Is, VP_T_E1_Set, - #endif - #if HAS_HEATED_BED - VP_T_Bed_Is, VP_T_Bed_Set, - #endif - #if FAN_COUNT > 0 - VP_Fan0_Percentage, - #endif - VP_XPos, VP_YPos, VP_ZPos, - VP_Fan0_Percentage, - VP_Feedrate_Percentage, - VP_PrintProgress_Percentage, - 0x0000 -}; - -const uint16_t VPList_Status2[] PROGMEM = { - /* VP_M117, for completeness, but it cannot be auto-uploaded */ - #if HOTENDS >= 1 - VP_Flowrate_E0, - #endif - #if HOTENDS >= 2 - VP_Flowrate_E1, - #endif - VP_PrintProgress_Percentage, - VP_PrintTime, - 0x0000 -}; - -const uint16_t VPList_ManualMove[] PROGMEM = { - VP_XPos, VP_YPos, VP_ZPos, - 0x0000 -}; - -const uint16_t VPList_ManualExtrude[] PROGMEM = { - VP_EPos, - 0x0000 -}; - -const uint16_t VPList_FanAndFeedrate[] PROGMEM = { - VP_Feedrate_Percentage, VP_Fan0_Percentage, - 0x0000 -}; - -const uint16_t VPList_SD_FlowRates[] PROGMEM = { - VP_Flowrate_E0, VP_Flowrate_E1, - 0x0000 -}; - -const uint16_t VPList_SDFileList[] PROGMEM = { - VP_SD_FileName0, VP_SD_FileName1, VP_SD_FileName2, VP_SD_FileName3, VP_SD_FileName4, - 0x0000 -}; - -const uint16_t VPList_SD_PrintManipulation[] PROGMEM = { - VP_PrintProgress_Percentage, VP_PrintTime, - 0x0000 -}; - -const struct VPMapping VPMap[] PROGMEM = { - { DGUSLCD_SCREEN_BOOT, VPList_Boot }, - { DGUSLCD_SCREEN_MAIN, VPList_Main }, - { DGUSLCD_SCREEN_TEMPERATURE, VPList_Temp }, - { DGUSLCD_SCREEN_STATUS, VPList_Status }, - { DGUSLCD_SCREEN_STATUS2, VPList_Status2 }, - { DGUSLCD_SCREEN_MANUALMOVE, VPList_ManualMove }, - { DGUSLCD_SCREEN_MANUALEXTRUDE, VPList_ManualExtrude }, - { DGUSLCD_SCREEN_FANANDFEEDRATE, VPList_FanAndFeedrate }, - { DGUSLCD_SCREEN_FLOWRATES, VPList_SD_FlowRates }, - { DGUSLCD_SCREEN_SDPRINTMANIPULATION, VPList_SD_PrintManipulation }, - { DGUSLCD_SCREEN_SDFILELIST, VPList_SDFileList }, - { 0 , nullptr } // List is terminated with an nullptr as table entry. -}; - -const char MarlinVersion[] PROGMEM = SHORT_BUILD_VERSION; - -// Helper to define a DGUS_VP_Variable for common use cases. -#define VPHELPER(VPADR, VPADRVAR, RXFPTR, TXFPTR ) { .VP=VPADR, .memadr=VPADRVAR, .size=sizeof(VPADRVAR), \ - .set_by_display_handler = RXFPTR, .send_to_display_handler = TXFPTR } - -// Helper to define a DGUS_VP_Variable when the sizeo of the var cannot be determined automaticalyl (eg. a string) -#define VPHELPER_STR(VPADR, VPADRVAR, STRLEN, RXFPTR, TXFPTR ) { .VP=VPADR, .memadr=VPADRVAR, .size=STRLEN, \ - .set_by_display_handler = RXFPTR, .send_to_display_handler = TXFPTR } - -const struct DGUS_VP_Variable ListOfVP[] PROGMEM = { - // Helper to detect touch events - VPHELPER(VP_SCREENCHANGE, nullptr, DGUSScreenVariableHandler::ScreenChangeHook, nullptr), - VPHELPER(VP_SCREENCHANGE_ASK, nullptr, DGUSScreenVariableHandler::ScreenChangeHookIfIdle, nullptr), - #if ENABLED(SDSUPPORT) - VPHELPER(VP_SCREENCHANGE_WHENSD, nullptr, DGUSScreenVariableHandler::ScreenChangeHookIfSD, nullptr), - #endif - VPHELPER(VP_CONFIRMED, nullptr, DGUSScreenVariableHandler::ScreenConfirmedOK, nullptr), - - VPHELPER(VP_TEMP_ALL_OFF, nullptr, &DGUSScreenVariableHandler::HandleAllHeatersOff, nullptr), - - #if ENABLED(DUGS_UI_MOVE_DIS_OPTION) - VPHELPER(VP_MOVE_OPTION, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMoveOption, nullptr), - #endif - #if ENABLED(DUGS_UI_MOVE_DIS_OPTION) - VPHELPER(VP_MOVE_X, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr), - VPHELPER(VP_MOVE_Y, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr), - VPHELPER(VP_MOVE_Z, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr), - VPHELPER(VP_HOME_ALL, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr), - #else - VPHELPER(VP_MOVE_X, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr), - VPHELPER(VP_MOVE_Y, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr), - VPHELPER(VP_MOVE_Z, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr), - VPHELPER(VP_HOME_ALL, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr), - #endif - - VPHELPER(VP_MOTOR_LOCK_UNLOK, nullptr, &DGUSScreenVariableHandler::HandleMotorLockUnlock, nullptr), - #if ENABLED(POWER_LOSS_RECOVERY) - VPHELPER(VP_POWER_LOSS_RECOVERY, nullptr, &DGUSScreenVariableHandler::HandlePowerLossRecovery, nullptr), - #endif - VPHELPER(VP_SETTINGS, nullptr, &DGUSScreenVariableHandler::HandleSettings, nullptr), - - { .VP = VP_MARLIN_VERSION, .memadr = (void*)MarlinVersion, .size = VP_MARLIN_VERSION_LEN, .set_by_display_handler = nullptr, .send_to_display_handler =&DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM }, - // M117 LCD String (We don't need the string in memory but "just" push it to the display on demand, hence the nullptr - { .VP = VP_M117, .memadr = nullptr, .size = VP_M117_LEN, .set_by_display_handler = nullptr, .send_to_display_handler =&DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplay }, - - // Temperature Data - #if HOTENDS >= 1 - VPHELPER(VP_T_E0_Is, &thermalManager.temp_hotend[0].celsius, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<0>), - VPHELPER(VP_T_E0_Set, &thermalManager.temp_hotend[0].target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay), - VPHELPER(VP_Flowrate_E0, nullptr, DGUSScreenVariableHandler::HandleFlowRateChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay), - VPHELPER(VP_EPos, &destination.e, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>), - VPHELPER(VP_MOVE_E0, nullptr, &DGUSScreenVariableHandler::HandleManualExtrude, nullptr), - VPHELPER(VP_E0_CONTROL, &thermalManager.temp_hotend[0].target, &DGUSScreenVariableHandler::HandleHeaterControl, nullptr), - VPHELPER(VP_E0_STATUS, &thermalManager.temp_hotend[0].target, nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay), - #if ENABLED(DGUS_PREHEAT_UI) - VPHELPER(VP_E0_BED_PREHEAT, nullptr, &DGUSScreenVariableHandler::HandlePreheat, nullptr), - #endif - #if ENABLED(PIDTEMP) - VPHELPER(VP_E0_PID_P, &thermalManager.temp_hotend[0].pid.Kp, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID), - VPHELPER(VP_E0_PID_I, &thermalManager.temp_hotend[0].pid.Ki, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID), - VPHELPER(VP_E0_PID_D, &thermalManager.temp_hotend[0].pid.Kd, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID), - VPHELPER(VP_PID_AUTOTUNE_E0, nullptr, &DGUSScreenVariableHandler::HandlePIDAutotune, nullptr), - #endif - #if ENABLED(DGUS_FILAMENT_LOADUNLOAD) - VPHELPER(VP_E0_FILAMENT_LOAD_UNLOAD, nullptr, &DGUSScreenVariableHandler::HandleFilamentOption, &DGUSScreenVariableHandler::HandleFilamentLoadUnload), - #endif - #endif - #if HOTENDS >= 2 - VPHELPER(VP_T_E1_Is, &thermalManager.temp_hotend[1].celsius, nullptr, DGUSLCD_SendFloatAsLongValueToDisplay<0>), - VPHELPER(VP_T_E1_Set, &thermalManager.temp_hotend[1].target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay), - VPHELPER(VP_Flowrate_E1, nullptr, DGUSScreenVariableHandler::HandleFlowRateChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay), - VPHELPER(VP_MOVE_E1, nullptr, &DGUSScreenVariableHandler::HandleManualExtrude, nullptr), - VPHELPER(VP_E1_CONTROL, &thermalManager.temp_hotend[1].target, &DGUSScreenVariableHandler::HandleHeaterControl, nullptr), - VPHELPER(VP_E1_STATUS, &thermalManager.temp_hotend[1].target, nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay), - #if ENABLED(PIDTEMP) - VPHELPER(VP_PID_AUTOTUNE_E1, nullptr, &DGUSScreenVariableHandler::HandlePIDAutotune, nullptr), - #endif - #endif - #if HAS_HEATED_BED - VPHELPER(VP_T_Bed_Is, &thermalManager.temp_bed.celsius, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<0>), - VPHELPER(VP_T_Bed_Set, &thermalManager.temp_bed.target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay), - VPHELPER(VP_BED_CONTROL, &thermalManager.temp_bed.target, &DGUSScreenVariableHandler::HandleHeaterControl, nullptr), - VPHELPER(VP_BED_STATUS, &thermalManager.temp_bed.target, nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay), - #if ENABLED(PIDTEMPBED) - VPHELPER(VP_BED_PID_P, &thermalManager.temp_bed.pid.Kp, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID), - VPHELPER(VP_BED_PID_I, &thermalManager.temp_bed.pid.Ki, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID), - VPHELPER(VP_BED_PID_D, &thermalManager.temp_bed.pid.Kd, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID), - #endif - #endif - - // Fan Data - #if FAN_COUNT - #define FAN_VPHELPER(N) \ - VPHELPER(VP_Fan##N##_Percentage, &thermalManager.fan_speed[N], DGUSScreenVariableHandler::DGUSLCD_PercentageToUint8, &DGUSScreenVariableHandler::DGUSLCD_SendPercentageToDisplay), \ - VPHELPER(VP_FAN##N##_CONTROL, &thermalManager.fan_speed[N], &DGUSScreenVariableHandler::HandleFanControl, nullptr), \ - VPHELPER(VP_FAN##N##_STATUS, &thermalManager.fan_speed[N], nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendFanStatusToDisplay), - REPEAT(FAN_COUNT, FAN_VPHELPER) - #endif - - // Feedrate - VPHELPER(VP_Feedrate_Percentage, &feedrate_percentage, DGUSScreenVariableHandler::DGUSLCD_SetValueDirectly, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay ), - - // Position Data - VPHELPER(VP_XPos, ¤t_position.x, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>), - VPHELPER(VP_YPos, ¤t_position.y, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>), - VPHELPER(VP_ZPos, ¤t_position.z, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>), - - // Print Progress - #if ENABLED(LCD_SET_PROGRESS_MANUALLY) - VPHELPER(VP_PrintProgress_Percentage, &ui.progress_override, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay ), - #endif - - // Print Time - VPHELPER_STR(VP_PrintTime, nullptr, VP_PrintTime_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendPrintTimeToDisplay ), - #if ENABLED(PRINTCOUNTER) - VPHELPER_STR(VP_PrintAccTime, nullptr, VP_PrintAccTime_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendPrintAccTimeToDisplay ), - VPHELPER_STR(VP_PrintsTotal, nullptr, VP_PrintsTotal_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendPrintsTotalToDisplay ), - #endif - - VPHELPER(VP_X_STEP_PER_MM, &planner.settings.axis_steps_per_mm[X_AXIS], DGUSScreenVariableHandler::HandleStepPerMMChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>), - VPHELPER(VP_Y_STEP_PER_MM, &planner.settings.axis_steps_per_mm[Y_AXIS], DGUSScreenVariableHandler::HandleStepPerMMChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>), - VPHELPER(VP_Z_STEP_PER_MM, &planner.settings.axis_steps_per_mm[Z_AXIS], DGUSScreenVariableHandler::HandleStepPerMMChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>), - #if HOTENDS >= 1 - VPHELPER(VP_E0_STEP_PER_MM, &planner.settings.axis_steps_per_mm[E_AXIS_N(0)], DGUSScreenVariableHandler::HandleStepPerMMExtruderChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>), - #endif - #if HOTENDS >= 2 - VPHELPER(VP_E1_STEP_PER_MM, &planner.settings.axis_steps_per_mm[E_AXIS_N(1)], DGUSScreenVariableHandler::HandleStepPerMMExtruderChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>), - #endif - - // SDCard File listing. - #if ENABLED(SDSUPPORT) - VPHELPER(VP_SD_ScrollEvent, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_ScrollFilelist, nullptr), - VPHELPER(VP_SD_FileSelected, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_FileSelected, nullptr), - VPHELPER(VP_SD_FileSelectConfirm, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_StartPrint, nullptr), - VPHELPER_STR(VP_SD_FileName0, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ), - VPHELPER_STR(VP_SD_FileName1, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ), - VPHELPER_STR(VP_SD_FileName2, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ), - VPHELPER_STR(VP_SD_FileName3, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ), - VPHELPER_STR(VP_SD_FileName4, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ), - VPHELPER(VP_SD_ResumePauseAbort, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_ResumePauseAbort, nullptr), - VPHELPER(VP_SD_AbortPrintConfirmed, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_ReallyAbort, nullptr), - VPHELPER(VP_SD_Print_Setting, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_PrintTune, nullptr), - #if HAS_BED_PROBE - VPHELPER(VP_SD_Print_ProbeOffsetZ, &probe.offset.z, DGUSScreenVariableHandler::HandleProbeOffsetZChanged, &DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<2>), - #if ENABLED(BABYSTEPPING) - VPHELPER(VP_SD_Print_LiveAdjustZ, nullptr, DGUSScreenVariableHandler::HandleLiveAdjustZ, nullptr), - #endif - #endif - #endif - - #if ENABLED(DGUS_UI_WAITING) - VPHELPER(VP_WAITING_STATUS, nullptr, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendWaitingStatusToDisplay), - #endif - - // Messages for the User, shared by the popup and the kill screen. They cant be autouploaded as we do not buffer content. - { .VP = VP_MSGSTR1, .memadr = nullptr, .size = VP_MSGSTR1_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM }, - { .VP = VP_MSGSTR2, .memadr = nullptr, .size = VP_MSGSTR2_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM }, - { .VP = VP_MSGSTR3, .memadr = nullptr, .size = VP_MSGSTR3_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM }, - { .VP = VP_MSGSTR4, .memadr = nullptr, .size = VP_MSGSTR4_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM }, - - VPHELPER(0, 0, 0, 0) // must be last entry. -}; - -#endif // DGUS_LCD_UI_ORIGIN diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/config.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/config.h deleted file mode 100644 index 458c9012065c..000000000000 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/config.h +++ /dev/null @@ -1,124 +0,0 @@ -/************ - * 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: . * - ****************************************************************************/ - -#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 - -// Enable UTF8 processing and rendering. Unsupported characters -// will be shown as '?'. -//#define TOUCH_UI_USE_UTF8 -#ifdef TOUCH_UI_USE_UTF8 - // Western accents support. These accented characters use - // combined bitmaps and require relatively little storage. - #define TOUCH_UI_UTF8_WESTERN_CHARSET - #ifdef TOUCH_UI_UTF8_WESTERN_CHARSET - // Additional character groups. These characters require - // full bitmaps and take up considerable storage: - //#define TOUCH_UI_UTF8_SUPERSCRIPTS // ¹ ² ³ - //#define TOUCH_UI_UTF8_COPYRIGHT // © ® - //#define TOUCH_UI_UTF8_GERMANIC // ß - //#define TOUCH_UI_UTF8_SCANDINAVIAN // Æ Ð Ø Þ æ ð ø þ - //#define TOUCH_UI_UTF8_PUNCTUATION // « » ¿ ¡ - //#define TOUCH_UI_UTF8_CURRENCY // ¢ £ ¤ ¥ - //#define TOUCH_UI_UTF8_ORDINALS // º ª - //#define TOUCH_UI_UTF8_MATHEMATICS // ± × ÷ - //#define TOUCH_UI_UTF8_FRACTIONS // ¼ ½ ¾ - //#define TOUCH_UI_UTF8_SYMBOLS // µ ¶ ¦ § ¬ - #endif -#endif - -// When labels do not fit buttons, use smaller font -//#define TOUCH_UI_FIT_TEXT - -// Enable support for selection of languages at run-time -// (otherwise will use the value of LCD_LANGUAGE) -//#define TOUCH_UI_LANGUAGE_MENU - -// Use a numeric passcode for "Parental lock". -// This is a recommended for smaller displays. -//#define TOUCH_UI_PASSCODE - -// The timeout (in ms) to return to the status screen from sub-menus -//#define LCD_TIMEOUT_TO_STATUS 15000 - -// Enable this to debug the event framework -//#define TOUCH_UI_DEBUG - -// Enable the developer's menu and screens -//#define DEVELOPER_SCREENS - -// Sets the SPI speed in Hz - -#define SPI_FREQUENCY 8000000 >> SPI_SPEED diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/boards.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/boards.h deleted file mode 100644 index 854b8897b375..000000000000 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/boards.h +++ /dev/null @@ -1,183 +0,0 @@ -/************ - * 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: . * - ****************************************************************************/ - -#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 TOUCH_UI_FTDI_EVE board specified. To add a new board, modify 'ftdi_eve_boards.h'." -#endif diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set.cpp b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set.cpp deleted file mode 100644 index 688b68ae0c51..000000000000 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set.cpp +++ /dev/null @@ -1,449 +0,0 @@ -/************************ - * western_char_set.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: . * - ****************************************************************************/ - -#include "../ftdi_extended.h" - -#if defined(FTDI_EXTENDED) && BOTH(TOUCH_UI_USE_UTF8, TOUCH_UI_UTF8_WESTERN_CHARSET) - - #include "western_char_set_bitmap_31.h" - - #define NUM_ELEMENTS(a) (sizeof(a)/sizeof(a[0])) - - using namespace FTDI; - - constexpr static uint8_t std_font = 31; - constexpr static uint8_t alt_font = 1; - - static uint32_t bitmap_addr; - - /* Glyphs in the WesternCharSet bitmap */ - - enum { - GRAVE, - ACUTE, - CIRCUMFLEX, - TILDE, - DIAERESIS, - DOT_ABOVE, - CEDILLA, - NO_DOT_I, -#if ENABLED(TOUCH_UI_UTF8_GERMANIC) - SHARP_S, -#endif -#if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN) - LRG_O_STROKE, - SML_O_STROKE, - LRG_AE, - SML_AE, - LRG_ETH, - SML_ETH, - LRG_THORN, - SML_THORN, -#endif -#if ENABLED(TOUCH_UI_UTF8_PUNCTUATION) - LEFT_DBL_QUOTE, - RIGHT_DBL_QUOTE, - INV_EXCLAMATION, - INV_QUESTION, -#endif -#if ENABLED(TOUCH_UI_UTF8_CURRENCY) - CENT_SIGN, - POUND_SIGN, - CURRENCY_SIGN, - YEN_SIGN, -#endif -#if ENABLED(TOUCH_UI_UTF8_SUPERSCRIPTS) - SUPERSCRIPT_ONE, - SUPERSCRIPT_TWO, - SUPERSCRIPT_THREE, -#endif -#if ENABLED(TOUCH_UI_UTF8_ORDINALS) - MASCULINE_ORDINAL, - FEMININE_ORDINAL, -#endif -#if ENABLED(TOUCH_UI_UTF8_COPYRIGHT) - COPYRIGHT_SIGN, - REGISTERED_SIGN, -#endif -#if ENABLED(TOUCH_UI_UTF8_MATHEMATICS) - PLUS_MINUS_SIGN, - MULTIPLICATION_SIGN, - DIVISION_SIGN, -#endif -#if ENABLED(TOUCH_UI_UTF8_FRACTIONS) - FRACTION_QUARTER, - FRACTION_HALF, - FRACTION_THREE_FOURTHS, -#endif -#if ENABLED(TOUCH_UI_UTF8_SYMBOLS) - MICRON_SIGN, - PILCROW_SIGN, - BROKEN_BAR, - SECTION_SIGN, - NOT_SIGN -#endif - }; - - /* Centerline of characters that can take accents */ - - constexpr int8_t mid_a = 12; - constexpr int8_t mid_e = 12; - constexpr int8_t mid_i = 5; - constexpr int8_t mid_o = 12; - constexpr int8_t mid_u = 12; - constexpr int8_t mid_y = 11; - constexpr int8_t mid_n = 12; - constexpr int8_t mid_c = 12; - constexpr int8_t mid_A = 13; - constexpr int8_t mid_E = 13; - constexpr int8_t mid_I = 6; - constexpr int8_t mid_O = 14; - constexpr int8_t mid_U = 14; - constexpr int8_t mid_Y = 13; - constexpr int8_t mid_N = 15; - constexpr int8_t mid_C = 13; - - /* Centerline of accent glyphs */ - - constexpr int8_t mid_accent = 16; - - /* When reusing the DOT_ABOVE accent glyph for the degree sign, we need to trim the leading space */ - constexpr uint8_t deg_sign_leading = 9; - - /* Look-up table for constructing characters (must be ordered by unicode) - * - * Characters are either complete symbols from the Western Char Set bitmap, - * or they are constructed using a standard letter from the romfont and - * drawing an accent from the Western Char Set bitmap over it. - */ - - #define UTF8(A) uint16_t(utf8(U##A)) - - PROGMEM constexpr struct { - uint16_t unicode; - uint8_t std_char; // Glyph from standard ROMFONT (zero if none) - uint8_t alt_char; // Glyph from Western Char Set bitmap - uint8_t alt_data; // For accented characters, the centerline; else char width - } char_recipe[] = { - {0, 0, NO_DOT_I, 10 }, -#if ENABLED(TOUCH_UI_UTF8_PUNCTUATION) - {UTF8('¡'), 0 , INV_EXCLAMATION, 13 }, -#endif -#if ENABLED(TOUCH_UI_UTF8_CURRENCY) - {UTF8('¢'), 0 , CENT_SIGN, 23 }, - {UTF8('£'), 0 , POUND_SIGN, 24 }, - {UTF8('¤'), 0 , CURRENCY_SIGN, 26 }, - {UTF8('¥'), 0 , YEN_SIGN, 26 }, -#endif -#if ENABLED(TOUCH_UI_UTF8_SYMBOLS) - {UTF8('¦'), 0 , BROKEN_BAR, 11 }, - {UTF8('§'), 0 , SECTION_SIGN, 21 }, -#endif -#if ENABLED(TOUCH_UI_UTF8_COPYRIGHT) - {UTF8('©'), 0 , COPYRIGHT_SIGN, 38 }, -#endif -#if ENABLED(TOUCH_UI_UTF8_ORDINALS) - {UTF8('ª'), 0 , FEMININE_ORDINAL, 19 }, -#endif -#if ENABLED(TOUCH_UI_UTF8_PUNCTUATION) - {UTF8('«'), 0 , LEFT_DBL_QUOTE, 23 }, -#endif -#if ENABLED(TOUCH_UI_UTF8_SYMBOLS) - {UTF8('¬'), 0 , NOT_SIGN, 32 }, -#endif -#if ENABLED(TOUCH_UI_UTF8_COPYRIGHT) - {UTF8('®'), 0 , REGISTERED_SIGN, 38 }, -#endif - {UTF8('°'), 0 , DOT_ABOVE, 24 }, -#if ENABLED(TOUCH_UI_UTF8_MATHEMATICS) - {UTF8('±'), 0 , NOT_SIGN, 32 }, -#endif -#if ENABLED(TOUCH_UI_UTF8_SUPERSCRIPTS) - {UTF8('²'), 0 , SUPERSCRIPT_TWO, 16 }, - {UTF8('³'), 0 , SUPERSCRIPT_THREE, 16 }, -#endif -#if ENABLED(TOUCH_UI_UTF8_SYMBOLS) - {UTF8('µ'), 0 , MICRON_SIGN, 28 }, - {UTF8('¶'), 0 , PILCROW_SIGN, 24 }, -#endif -#if ENABLED(TOUCH_UI_UTF8_SUPERSCRIPTS) - {UTF8('¹'), 0 , SUPERSCRIPT_ONE, 16 }, -#endif -#if ENABLED(TOUCH_UI_UTF8_ORDINALS) - {UTF8('º'), 0 , MASCULINE_ORDINAL, 19 }, -#endif -#if ENABLED(TOUCH_UI_UTF8_PUNCTUATION) - {UTF8('»'), 0 , RIGHT_DBL_QUOTE, 24 }, -#endif -#if ENABLED(TOUCH_UI_UTF8_FRACTIONS) - {UTF8('¼'), 0 , FRACTION_QUARTER, 40 }, - {UTF8('½'), 0 , FRACTION_HALF, 40 }, - {UTF8('¾'), 0 , FRACTION_THREE_FOURTHS, 40 }, -#endif -#if ENABLED(TOUCH_UI_UTF8_PUNCTUATION) - {UTF8('¿'), 0 , INV_QUESTION, 21 }, -#endif - {UTF8('À'), 'A', GRAVE, mid_A}, - {UTF8('Á'), 'A', ACUTE, mid_A}, - {UTF8('Â'), 'A', CIRCUMFLEX, mid_A}, - {UTF8('Ã'), 'A', TILDE, mid_A}, - {UTF8('Ä'), 'A', DIAERESIS, mid_A}, - {UTF8('Å'), 'A', DOT_ABOVE, mid_A}, -#if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN) - {UTF8('Æ'), 0 , LRG_AE, 40}, -#endif - {UTF8('Ç'), 'C', CEDILLA, mid_C}, - {UTF8('È'), 'E', GRAVE, mid_E}, - {UTF8('É'), 'E', ACUTE, mid_E}, - {UTF8('Ê'), 'E', CIRCUMFLEX, mid_E}, - {UTF8('Ë'), 'E', DIAERESIS, mid_E}, - {UTF8('Ì'), 'I', GRAVE, mid_I}, - {UTF8('Í'), 'I', ACUTE, mid_I}, - {UTF8('Î'), 'I', CIRCUMFLEX, mid_I}, - {UTF8('Ï'), 'I', DIAERESIS, mid_I}, -#if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN) - {UTF8('Ð'), 0, LRG_ETH, 31 }, -#endif - {UTF8('Ñ'), 'N', TILDE, mid_N}, - {UTF8('Ò'), 'O', GRAVE, mid_O}, - {UTF8('Ó'), 'O', ACUTE, mid_O}, - {UTF8('Ô'), 'O', CIRCUMFLEX, mid_O}, - {UTF8('Õ'), 'O', TILDE, mid_O}, - {UTF8('Ö'), 'O', DIAERESIS, mid_O}, -#if ENABLED(TOUCH_UI_UTF8_MATHEMATICS) - {UTF8('×'), 0 , MULTIPLICATION_SIGN, 32 }, -#endif -#if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN) - {UTF8('Ø'), 0 , LRG_O_STROKE, 32 }, -#endif - {UTF8('Ù'), 'U', GRAVE, mid_U}, - {UTF8('Ú'), 'U', ACUTE, mid_U}, - {UTF8('Û'), 'U', CIRCUMFLEX, mid_U}, - {UTF8('Ü'), 'U', DIAERESIS, mid_U}, - {UTF8('Ý'), 'Y', ACUTE, mid_Y}, -#if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN) - {UTF8('Þ'), 0 , LRG_THORN, 25 }, -#endif -#if ENABLED(TOUCH_UI_UTF8_GERMANIC) - {UTF8('ß'), 0 , SHARP_S, 26 }, -#endif - {UTF8('à'), 'a', GRAVE, mid_a}, - {UTF8('á'), 'a', ACUTE, mid_a}, - {UTF8('â'), 'a', CIRCUMFLEX, mid_a}, - {UTF8('ã'), 'a', TILDE, mid_a}, - {UTF8('ä'), 'a', DIAERESIS, mid_a}, - {UTF8('å'), 'a', DOT_ABOVE, mid_a}, -#if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN) - {UTF8('æ'), 0 , SML_AE, 40 }, -#endif - {UTF8('ç'), 'c', CEDILLA, mid_c}, - {UTF8('è'), 'e', GRAVE, mid_e}, - {UTF8('é'), 'e', ACUTE, mid_e}, - {UTF8('ê'), 'e', CIRCUMFLEX, mid_e}, - {UTF8('ë'), 'e', DIAERESIS, mid_e}, - {UTF8('ì'), 'i', GRAVE, mid_i}, - {UTF8('í'), 'i', ACUTE, mid_i}, - {UTF8('î'), 'i', CIRCUMFLEX, mid_i}, - {UTF8('ï'), 'i', DIAERESIS, mid_i}, -#if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN) - {UTF8('ð'), 0, SML_ETH, 24 }, -#endif - {UTF8('ñ'), 'n', TILDE, mid_n}, - {UTF8('ò'), 'o', GRAVE, mid_o}, - {UTF8('ó'), 'o', ACUTE, mid_o}, - {UTF8('ô'), 'o', CIRCUMFLEX, mid_o}, - {UTF8('õ'), 'o', TILDE, mid_o}, - {UTF8('ö'), 'o', DIAERESIS, mid_o}, -#if ENABLED(TOUCH_UI_UTF8_MATHEMATICS) - {UTF8('÷'), 0 , DIVISION_SIGN, 32 }, -#endif -#if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN) - {UTF8('ø'), 0 , SML_O_STROKE, 25 }, -#endif - {UTF8('ù'), 'u', GRAVE, mid_u}, - {UTF8('ú'), 'u', ACUTE, mid_u}, - {UTF8('û'), 'u', CIRCUMFLEX, mid_u}, - {UTF8('ü'), 'u', DIAERESIS, mid_u}, - {UTF8('ý'), 'y', ACUTE, mid_y}, -#if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN) - {UTF8('þ'), 0 , SML_THORN, 25 }, -#endif - {UTF8('ÿ'), 'y', DIAERESIS, mid_y} - }; - - static_assert(UTF8('¡') == 0xC2A1, "Incorrect encoding for character"); - - /* Compile-time check that the table is in sorted order */ - - constexpr bool is_sorted(size_t n) { - return n < 2 ? true : char_recipe[n-2].unicode < char_recipe[n-1].unicode && is_sorted(n-1); - } - - static_assert(is_sorted(NUM_ELEMENTS(char_recipe)), "The table must be sorted by unicode value"); - - /* Performs a binary search to find a unicode character in the table */ - - static int8_t find_char_data(FTDI::utf8_char_t c) { - int8_t min = 0, max = NUM_ELEMENTS(char_recipe), index; - for (;;) { - index = (min + max)/2; - const uint16_t char_at = pgm_read_word(&char_recipe[index].unicode); - if (char_at == c) break; - if (min == max) return -1; - if (c > char_at) - min = index + 1; - else - max = index; - } - return index; - } - - static void get_char_data(uint8_t index, uint8_t &std_char, uint8_t &alt_char, uint8_t &alt_data) { - std_char = pgm_read_byte(&char_recipe[index].std_char); - alt_char = pgm_read_byte(&char_recipe[index].alt_char); - alt_data = pgm_read_byte(&char_recipe[index].alt_data); - } - - /** - * Load bitmap data into RAMG. This function is called once at the start - * of the program. - * - * Parameters: - * - * addr - Address in RAMG where the font data is written - */ - - void FTDI::WesternCharSet::load_data(uint32_t addr) { - // Load the alternative font metrics - CLCD::FontMetrics alt_fm; - alt_fm.ptr = addr + 148; - alt_fm.format = L4; - alt_fm.stride = 19; - alt_fm.width = 38; - alt_fm.height = 49; - for (uint8_t i = 0; i < 127; i++) - alt_fm.char_widths[i] = 0; - - // For special characters, copy the character widths from the char tables - for (uint8_t i = 0; i < NUM_ELEMENTS(char_recipe); i++) { - uint8_t std_char, alt_char, alt_data; - get_char_data(i, std_char, alt_char, alt_data); - if (std_char == 0) - alt_fm.char_widths[alt_char] = alt_data; - } - CLCD::mem_write_bulk(addr, &alt_fm, 148); - - // Decode the RLE data and load it into RAMG as a bitmap - write_rle_data(addr + 148, font, sizeof(font)); - - bitmap_addr = addr; - } - - /** - * Populates the bitmap handles for the custom into the display list. - * This function is called once at the start of each display list. - * - * Parameters: - * - * cmd - Object used for writing to the FTDI chip command queue. - */ - - void FTDI::WesternCharSet::load_bitmaps(CommandProcessor& cmd) { - CLCD::FontMetrics alt_fm; - alt_fm.ptr = bitmap_addr + 148; - alt_fm.format = L4; - alt_fm.stride = 19; - alt_fm.width = 38; - alt_fm.height = 49; - set_font_bitmap(cmd, alt_fm, alt_font); - } - - /** - * Renders a character at location x and y. The x position is incremented - * by the width of the character. - * - * Parameters: - * - * cmd - If non-NULL the symbol is drawn to the screen. - * If NULL, only increment position for text measurement. - * - * x, y - The location at which to draw the character. On output, - * incremented to the location of the next character. - * - * fs - A scaling object used to scale the font. The display will - * already be configured to scale bitmaps, but positions - * must be scaled using fs.scale() - * - * c - The unicode code point to draw. If the renderer does not - * support the character, it should return false. - - * Returns: Whether the character was supported. - */ - - bool FTDI::WesternCharSet::render_glyph(CommandProcessor* cmd, int &x, int &y, font_size_t fs, utf8_char_t c) { - - // A supported character? - if (c < UTF8('¡') || c > UTF8('ÿ')) return false; - - int8_t index = find_char_data(c); - if (index == -1) return false; - - // Determine character characteristics - uint8_t std_char, alt_char, alt_data; - get_char_data(index, std_char, alt_char, alt_data); - - bool base_special; - uint8_t base_width; - uint8_t base_char; - uint8_t accent_char; - int8_t accent_dx, accent_dy; - - if (std_char == 0) { - // Special character, non-accented - base_width = alt_data; - base_special = true; - base_char = alt_char; - accent_char = 0; - if (c == UTF8('°')) - x -= fs.scale(deg_sign_leading); - } else { - // Regular character with accent: - accent_dx = alt_data - mid_accent; - accent_dy = isupper(std_char) ? -7 : 0; - accent_char = alt_char; - base_width = StandardCharSet::std_char_width(std_char); - base_special = std_char == 'i'; - base_char = base_special ? NO_DOT_I : std_char; - } - - // If cmd != NULL, draw the glyph to the screen - if (cmd) { - ext_vertex2ii(*cmd, x, y, base_special ? alt_font : std_font, base_char); - if (accent_char) - ext_vertex2ii(*cmd, x + fs.scale(accent_dx), y + fs.scale(accent_dy), alt_font, accent_char); - } - - // Increment X to the next character position - x += fs.scale(base_width); - return true; - } - -#endif // FTDI_EXTENDED && TOUCH_UI_USE_UTF8 && TOUCH_UI_UTF8_WESTERN_CHARSET diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set_bitmap_31.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set_bitmap_31.h deleted file mode 100644 index 64a14121d975..000000000000 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set_bitmap_31.h +++ /dev/null @@ -1,1315 +0,0 @@ -/******************************** - * western_european_bitmap_31.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: . * - ****************************************************************************/ - -#pragma once - -/* This is a dump of "font_bitmaps/western_european_bitmap_31.png" - * using the tool "bitmap2cpp.py". The tool converts the image into - * 16-level grayscale and packs two pixels per byte. The resulting - * bytes are then RLE compressed to yield (count, byte) pairs. - */ - -const unsigned char font[] PROGMEM = { - - /* 0 GRAVE */ - 0x76, 0x00, 0x01, 0x08, 0x01, 0xee, 0x01, 0xe5, 0x11, 0x00, 0x01, 0xaf, - 0x01, 0xff, 0x01, 0x20, 0x10, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xd0, - 0x10, 0x00, 0x01, 0x01, 0x01, 0xdf, 0x01, 0xf9, 0x11, 0x00, 0x01, 0x2e, - 0x01, 0xff, 0x01, 0x50, 0x10, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xf2, - 0x11, 0x00, 0x01, 0x5f, 0x01, 0xfd, 0x11, 0x00, 0x01, 0x06, 0x01, 0x99, - 0x01, 0x40, 0xff, 0x00, 0xff, 0x00, 0xa4, 0x00, - - /* 1 ACUTE */ - 0x7b, 0x00, 0x01, 0x9e, 0x01, 0xee, 0x01, 0x50, 0x0f, 0x00, 0x01, 0x05, - 0x01, 0xff, 0x01, 0xf8, 0x10, 0x00, 0x01, 0x2f, 0x01, 0xff, 0x01, 0xa0, - 0x10, 0x00, 0x01, 0xcf, 0x01, 0xfc, 0x10, 0x00, 0x01, 0x09, 0x01, 0xff, - 0x01, 0xd1, 0x10, 0x00, 0x01, 0x4f, 0x01, 0xfe, 0x01, 0x20, 0x0f, 0x00, - 0x01, 0x01, 0x01, 0xef, 0x01, 0xf3, 0x10, 0x00, 0x01, 0x07, 0x01, 0xaa, - 0x01, 0x40, 0xff, 0x00, 0xff, 0x00, 0xa5, 0x00, - - /* 2 CIRCUMFLEX */ - 0x79, 0x00, 0x01, 0xcf, 0x01, 0xfc, 0x10, 0x00, 0x01, 0x07, 0x02, 0xff, - 0x01, 0x60, 0x0f, 0x00, 0x01, 0x2f, 0x02, 0xff, 0x01, 0xf2, 0x0f, 0x00, - 0x01, 0xcf, 0x01, 0xf6, 0x01, 0x6f, 0x01, 0xfb, 0x0e, 0x00, 0x01, 0x06, - 0x01, 0xff, 0x01, 0xa0, 0x01, 0x0a, 0x01, 0xff, 0x01, 0x60, 0x0d, 0x00, - 0x01, 0x1f, 0x01, 0xfd, 0x01, 0x00, 0x01, 0x01, 0x01, 0xdf, 0x01, 0xf1, - 0x0d, 0x00, 0x01, 0xbf, 0x01, 0xf3, 0x02, 0x00, 0x01, 0x3f, 0x01, 0xfb, - 0x0c, 0x00, 0x01, 0x02, 0x01, 0x99, 0x01, 0x50, 0x02, 0x00, 0x01, 0x05, - 0x01, 0x99, 0x01, 0x20, 0xff, 0x00, 0xff, 0x00, 0xa2, 0x00, - - /* 3 TILDE */ - 0x7c, 0x00, 0x01, 0x11, 0x0d, 0x00, 0x01, 0x09, 0x01, 0xff, 0x01, 0xc3, - 0x02, 0x00, 0x01, 0xff, 0x01, 0x80, 0x0c, 0x00, 0x01, 0xaf, 0x02, 0xff, - 0x01, 0x50, 0x01, 0x01, 0x01, 0xff, 0x01, 0x60, 0x0b, 0x00, 0x01, 0x02, - 0x01, 0xff, 0x01, 0xd9, 0x01, 0xff, 0x01, 0xf7, 0x01, 0x07, 0x01, 0xff, - 0x01, 0x40, 0x0b, 0x00, 0x01, 0x07, 0x01, 0xff, 0x01, 0x20, 0x01, 0x3e, - 0x02, 0xff, 0x01, 0xfd, 0x0c, 0x00, 0x01, 0x09, 0x01, 0xfe, 0x01, 0x00, - 0x01, 0x02, 0x01, 0xdf, 0x01, 0xff, 0x01, 0xf4, 0x0c, 0x00, 0x01, 0x07, - 0x01, 0xa8, 0x02, 0x00, 0x01, 0x06, 0x01, 0x98, 0x01, 0x20, 0xff, 0x00, - 0xff, 0x00, 0xb6, 0x00, - - /* 4 DIAERESIS */ - 0x8a, 0x00, 0x02, 0x44, 0x02, 0x00, 0x02, 0x44, 0x0d, 0x00, 0x02, 0xff, - 0x01, 0x10, 0x01, 0x01, 0x02, 0xff, 0x0d, 0x00, 0x02, 0xff, 0x01, 0x10, - 0x01, 0x01, 0x02, 0xff, 0x0d, 0x00, 0x02, 0xff, 0x01, 0x10, 0x01, 0x01, - 0x02, 0xff, 0x0d, 0x00, 0x02, 0xcc, 0x01, 0x10, 0x01, 0x01, 0x02, 0xcc, - 0xff, 0x00, 0xff, 0x00, 0xc9, 0x00, - - /* 5 DOT_ABOVE / DEGREE_SIGN */ - 0x2d, 0x00, 0x01, 0x13, 0x01, 0x30, 0x10, 0x00, 0x01, 0x2b, 0x02, 0xff, - 0x01, 0xa1, 0x0e, 0x00, 0x01, 0x02, 0x01, 0xef, 0x02, 0xff, 0x01, 0xfd, - 0x01, 0x10, 0x0d, 0x00, 0x01, 0x0d, 0x01, 0xff, 0x01, 0x94, 0x01, 0x5a, - 0x01, 0xff, 0x01, 0xb0, 0x0d, 0x00, 0x01, 0x4f, 0x01, 0xf7, 0x02, 0x00, - 0x01, 0x9f, 0x01, 0xf2, 0x0d, 0x00, 0x01, 0x8f, 0x01, 0xf0, 0x02, 0x00, - 0x01, 0x2f, 0x01, 0xf6, 0x0d, 0x00, 0x01, 0x8f, 0x01, 0xe0, 0x02, 0x00, - 0x01, 0x0f, 0x01, 0xf7, 0x0d, 0x00, 0x01, 0x7f, 0x01, 0xf2, 0x02, 0x00, - 0x01, 0x4f, 0x01, 0xf5, 0x0d, 0x00, 0x01, 0x2f, 0x01, 0xfc, 0x01, 0x10, - 0x01, 0x02, 0x01, 0xdf, 0x01, 0xf0, 0x0d, 0x00, 0x01, 0x08, 0x01, 0xff, - 0x01, 0xfb, 0x01, 0xcf, 0x01, 0xff, 0x01, 0x60, 0x0e, 0x00, 0x01, 0x9f, - 0x02, 0xff, 0x01, 0xf8, 0x0f, 0x00, 0x01, 0x03, 0x01, 0x9c, 0x01, 0xc9, - 0x01, 0x30, 0xff, 0x00, 0xff, 0x00, 0xa4, 0x00, - - /* 6 CEDILLA */ - 0xff, 0x00, 0xff, 0x00, 0xee, 0x00, 0x01, 0x06, 0x01, 0xff, 0x01, 0x20, - 0x11, 0x00, 0x01, 0xcf, 0x01, 0xc0, 0x11, 0x00, 0x01, 0x3f, 0x01, 0xf6, - 0x11, 0x00, 0x01, 0x0f, 0x01, 0xfb, 0x11, 0x00, 0x01, 0x3f, 0x01, 0xfd, - 0x0e, 0x00, 0x01, 0x07, 0x01, 0xd9, 0x01, 0x89, 0x01, 0xff, 0x01, 0xfb, - 0x0e, 0x00, 0x01, 0x07, 0x03, 0xff, 0x01, 0xf3, 0x0e, 0x00, 0x01, 0x04, - 0x01, 0xbd, 0x01, 0xee, 0x01, 0xd9, 0x01, 0x20, 0x2f, 0x00, - - /* 7 NO_DOT_I */ - 0xff, 0x00, 0x32, 0x00, 0x01, 0x01, 0x01, 0x99, 0x01, 0x96, 0x10, 0x00, - 0x01, 0x01, 0x01, 0xff, 0x01, 0xf9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xff, - 0x01, 0xf9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xff, 0x01, 0xf9, 0x10, 0x00, - 0x01, 0x01, 0x01, 0xff, 0x01, 0xf9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xff, - 0x01, 0xf9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xff, 0x01, 0xf9, 0x10, 0x00, - 0x01, 0x01, 0x01, 0xff, 0x01, 0xf9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xff, - 0x01, 0xf9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xff, 0x01, 0xf9, 0x10, 0x00, - 0x01, 0x01, 0x01, 0xff, 0x01, 0xf9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xff, - 0x01, 0xf9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xff, 0x01, 0xf9, 0x10, 0x00, - 0x01, 0x01, 0x01, 0xff, 0x01, 0xf9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xff, - 0x01, 0xf9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xff, 0x01, 0xf9, 0x10, 0x00, - 0x01, 0x01, 0x01, 0xff, 0x01, 0xf9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xff, - 0x01, 0xf9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xff, 0x01, 0xf9, 0x10, 0x00, - 0x01, 0x01, 0x01, 0xff, 0x01, 0xf9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xff, - 0x01, 0xf9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xff, 0x01, 0xf9, 0x10, 0x00, - 0x01, 0x01, 0x01, 0xff, 0x01, 0xf9, 0xcd, 0x00, - -#if ENABLED(TOUCH_UI_UTF8_GERMANIC) - /* 8 SHARP_S */ - 0x8a, 0x00, 0x01, 0x35, 0x01, 0x66, 0x01, 0x52, 0x0e, 0x00, 0x01, 0x03, - 0x01, 0xaf, 0x03, 0xff, 0x01, 0xe7, 0x0d, 0x00, 0x01, 0x7f, 0x05, 0xff, - 0x01, 0xc1, 0x0b, 0x00, 0x01, 0x07, 0x02, 0xff, 0x01, 0xfc, 0x01, 0xaa, - 0x01, 0xdf, 0x01, 0xff, 0x01, 0xfc, 0x0b, 0x00, 0x01, 0x2f, 0x01, 0xff, - 0x01, 0xf9, 0x01, 0x10, 0x01, 0x00, 0x01, 0x02, 0x01, 0xcf, 0x01, 0xff, - 0x01, 0x70, 0x0a, 0x00, 0x01, 0xaf, 0x01, 0xff, 0x01, 0x80, 0x03, 0x00, - 0x01, 0x0d, 0x01, 0xff, 0x01, 0xe0, 0x0a, 0x00, 0x01, 0xef, 0x01, 0xff, - 0x04, 0x00, 0x01, 0x05, 0x01, 0xff, 0x01, 0xf3, 0x09, 0x00, 0x01, 0x02, - 0x01, 0xff, 0x01, 0xfb, 0x04, 0x00, 0x01, 0x01, 0x01, 0xff, 0x01, 0xf7, - 0x09, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xf9, 0x03, 0x00, 0x01, 0x03, - 0x01, 0x9e, 0x01, 0xff, 0x01, 0xf8, 0x09, 0x00, 0x01, 0x03, 0x01, 0xff, - 0x01, 0xf8, 0x02, 0x00, 0x01, 0x01, 0x01, 0xaf, 0x02, 0xff, 0x01, 0xd7, - 0x09, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xf8, 0x02, 0x00, 0x01, 0x1d, - 0x01, 0xff, 0x01, 0xfc, 0x01, 0x50, 0x0a, 0x00, 0x01, 0x03, 0x01, 0xff, - 0x01, 0xf8, 0x02, 0x00, 0x01, 0xaf, 0x01, 0xff, 0x01, 0x70, 0x0b, 0x00, - 0x01, 0x03, 0x01, 0xff, 0x01, 0xf8, 0x01, 0x00, 0x01, 0x01, 0x01, 0xff, - 0x01, 0xfa, 0x0c, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xf8, 0x01, 0x00, - 0x01, 0x05, 0x01, 0xff, 0x01, 0xf4, 0x0c, 0x00, 0x01, 0x03, 0x01, 0xff, - 0x01, 0xf8, 0x01, 0x00, 0x01, 0x06, 0x01, 0xff, 0x01, 0xf4, 0x0c, 0x00, - 0x01, 0x03, 0x01, 0xff, 0x01, 0xf8, 0x01, 0x00, 0x01, 0x05, 0x01, 0xff, - 0x01, 0xf9, 0x0c, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xf8, 0x01, 0x00, - 0x01, 0x02, 0x02, 0xff, 0x01, 0x50, 0x0b, 0x00, 0x01, 0x03, 0x01, 0xff, - 0x01, 0xf8, 0x02, 0x00, 0x01, 0xbf, 0x01, 0xff, 0x01, 0xf8, 0x0b, 0x00, - 0x01, 0x03, 0x01, 0xff, 0x01, 0xf8, 0x02, 0x00, 0x01, 0x1d, 0x02, 0xff, - 0x01, 0xd3, 0x0a, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xf8, 0x02, 0x00, - 0x01, 0x01, 0x01, 0xcf, 0x02, 0xff, 0x01, 0x70, 0x09, 0x00, 0x01, 0x03, - 0x01, 0xff, 0x01, 0xf8, 0x03, 0x00, 0x01, 0x07, 0x02, 0xff, 0x01, 0xfb, - 0x09, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xf8, 0x04, 0x00, 0x01, 0x2b, - 0x02, 0xff, 0x01, 0xb0, 0x08, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xf8, - 0x05, 0x00, 0x01, 0x6f, 0x01, 0xff, 0x01, 0xf6, 0x08, 0x00, 0x01, 0x03, - 0x01, 0xff, 0x01, 0xf8, 0x05, 0x00, 0x01, 0x06, 0x01, 0xff, 0x01, 0xfd, - 0x08, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xf8, 0x06, 0x00, 0x01, 0xdf, - 0x01, 0xff, 0x08, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xf8, 0x06, 0x00, - 0x01, 0xbf, 0x01, 0xff, 0x01, 0x10, 0x07, 0x00, 0x01, 0x03, 0x01, 0xff, - 0x01, 0xf8, 0x06, 0x00, 0x01, 0xcf, 0x01, 0xff, 0x08, 0x00, 0x01, 0x03, - 0x01, 0xff, 0x01, 0xf8, 0x05, 0x00, 0x01, 0x01, 0x01, 0xff, 0x01, 0xfd, - 0x08, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xf8, 0x01, 0x02, 0x01, 0x84, - 0x03, 0x00, 0x01, 0x2d, 0x01, 0xff, 0x01, 0xf8, 0x08, 0x00, 0x01, 0x03, - 0x01, 0xff, 0x01, 0xf8, 0x01, 0x02, 0x01, 0xff, 0x01, 0xec, 0x01, 0xa9, - 0x01, 0xac, 0x02, 0xff, 0x01, 0xe0, 0x08, 0x00, 0x01, 0x03, 0x01, 0xff, - 0x01, 0xf8, 0x01, 0x02, 0x05, 0xff, 0x01, 0xfe, 0x01, 0x20, 0x08, 0x00, - 0x01, 0x03, 0x01, 0xee, 0x01, 0xe7, 0x01, 0x01, 0x01, 0xbf, 0x03, 0xff, - 0x01, 0xfe, 0x01, 0x80, 0x0e, 0x00, 0x01, 0x35, 0x01, 0x78, 0x01, 0x76, - 0x01, 0x30, 0xb4, 0x00, -#endif - -#if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN) - /* 9 LRG_O_STROKE */ - 0x93, 0x00, 0x01, 0x40, 0x0a, 0x00, 0x01, 0x47, 0x01, 0x9a, 0x01, 0xba, - 0x01, 0x95, 0x01, 0x10, 0x02, 0x00, 0x01, 0x07, 0x01, 0xf8, 0x08, 0x00, - 0x01, 0x02, 0x01, 0xaf, 0x04, 0xff, 0x01, 0xfc, 0x01, 0x50, 0x01, 0x00, - 0x01, 0x5f, 0x01, 0xff, 0x01, 0x30, 0x07, 0x00, 0x01, 0x8f, 0x06, 0xff, - 0x01, 0xfc, 0x01, 0x23, 0x01, 0xff, 0x01, 0xf6, 0x07, 0x00, 0x01, 0x1c, - 0x03, 0xff, 0x01, 0xca, 0x01, 0x9b, 0x01, 0xdf, 0x02, 0xff, 0x01, 0xfe, - 0x01, 0xff, 0x01, 0x80, 0x07, 0x00, 0x01, 0xcf, 0x01, 0xff, 0x01, 0xfd, - 0x01, 0x50, 0x02, 0x00, 0x01, 0x02, 0x01, 0x9f, 0x02, 0xff, 0x01, 0xfa, - 0x07, 0x00, 0x01, 0x09, 0x02, 0xff, 0x01, 0x90, 0x04, 0x00, 0x01, 0x03, - 0x01, 0xef, 0x01, 0xff, 0x01, 0xf3, 0x07, 0x00, 0x01, 0x5f, 0x01, 0xff, - 0x01, 0xf9, 0x06, 0x00, 0x01, 0x9f, 0x01, 0xff, 0x01, 0xfc, 0x07, 0x00, - 0x01, 0xdf, 0x01, 0xff, 0x01, 0xc0, 0x05, 0x00, 0x01, 0x06, 0x03, 0xff, - 0x01, 0x60, 0x05, 0x00, 0x01, 0x04, 0x02, 0xff, 0x01, 0x30, 0x05, 0x00, - 0x01, 0x4f, 0x01, 0xff, 0x01, 0xdf, 0x01, 0xff, 0x01, 0xc0, 0x05, 0x00, - 0x01, 0x0b, 0x01, 0xff, 0x01, 0xfc, 0x05, 0x00, 0x01, 0x02, 0x01, 0xef, - 0x01, 0xf7, 0x01, 0x3f, 0x01, 0xff, 0x01, 0xf3, 0x05, 0x00, 0x01, 0x0f, - 0x01, 0xff, 0x01, 0xf6, 0x05, 0x00, 0x01, 0x1d, 0x01, 0xff, 0x01, 0xa0, - 0x01, 0x0d, 0x01, 0xff, 0x01, 0xf8, 0x05, 0x00, 0x01, 0x3f, 0x01, 0xff, - 0x01, 0xf2, 0x05, 0x00, 0x01, 0xcf, 0x01, 0xfc, 0x01, 0x00, 0x01, 0x09, - 0x01, 0xff, 0x01, 0xfb, 0x05, 0x00, 0x01, 0x6f, 0x01, 0xff, 0x01, 0xe0, - 0x04, 0x00, 0x01, 0x0a, 0x01, 0xff, 0x01, 0xd1, 0x01, 0x00, 0x01, 0x06, - 0x01, 0xff, 0x01, 0xfe, 0x05, 0x00, 0x01, 0x8f, 0x01, 0xff, 0x01, 0xc0, - 0x04, 0x00, 0x01, 0x7f, 0x01, 0xff, 0x01, 0x20, 0x01, 0x00, 0x01, 0x03, - 0x02, 0xff, 0x05, 0x00, 0x01, 0x9f, 0x01, 0xff, 0x01, 0xb0, 0x03, 0x00, - 0x01, 0x05, 0x01, 0xff, 0x01, 0xf4, 0x02, 0x00, 0x01, 0x02, 0x02, 0xff, - 0x01, 0x10, 0x04, 0x00, 0x01, 0xaf, 0x01, 0xff, 0x01, 0xa0, 0x03, 0x00, - 0x01, 0x3f, 0x01, 0xff, 0x01, 0x60, 0x02, 0x00, 0x01, 0x01, 0x02, 0xff, - 0x01, 0x30, 0x04, 0x00, 0x01, 0xaf, 0x01, 0xff, 0x01, 0xa0, 0x02, 0x00, - 0x01, 0x01, 0x01, 0xef, 0x01, 0xf8, 0x03, 0x00, 0x01, 0x02, 0x02, 0xff, - 0x01, 0x20, 0x04, 0x00, 0x01, 0x9f, 0x01, 0xff, 0x01, 0xb0, 0x02, 0x00, - 0x01, 0x0d, 0x01, 0xff, 0x01, 0xb0, 0x03, 0x00, 0x01, 0x03, 0x02, 0xff, - 0x01, 0x10, 0x04, 0x00, 0x01, 0x8f, 0x01, 0xff, 0x01, 0xc0, 0x02, 0x00, - 0x01, 0xbf, 0x01, 0xfd, 0x04, 0x00, 0x01, 0x04, 0x02, 0xff, 0x05, 0x00, - 0x01, 0x6f, 0x01, 0xff, 0x01, 0xe0, 0x01, 0x00, 0x01, 0x08, 0x01, 0xff, - 0x01, 0xe1, 0x04, 0x00, 0x01, 0x06, 0x01, 0xff, 0x01, 0xfe, 0x05, 0x00, - 0x01, 0x2f, 0x01, 0xff, 0x01, 0xf2, 0x01, 0x00, 0x01, 0x6f, 0x01, 0xff, - 0x01, 0x30, 0x04, 0x00, 0x01, 0x0a, 0x01, 0xff, 0x01, 0xfa, 0x05, 0x00, - 0x01, 0x0f, 0x01, 0xff, 0x01, 0xf6, 0x01, 0x04, 0x01, 0xff, 0x01, 0xf5, - 0x05, 0x00, 0x01, 0x0e, 0x01, 0xff, 0x01, 0xf7, 0x05, 0x00, 0x01, 0x09, - 0x01, 0xff, 0x01, 0xfc, 0x01, 0x2e, 0x01, 0xff, 0x01, 0x70, 0x05, 0x00, - 0x01, 0x5f, 0x01, 0xff, 0x01, 0xf2, 0x05, 0x00, 0x01, 0x03, 0x02, 0xff, - 0x01, 0xef, 0x01, 0xfa, 0x06, 0x00, 0x01, 0xcf, 0x01, 0xff, 0x01, 0xb0, - 0x06, 0x00, 0x01, 0xcf, 0x02, 0xff, 0x01, 0xc0, 0x05, 0x00, 0x01, 0x06, - 0x02, 0xff, 0x01, 0x40, 0x06, 0x00, 0x01, 0x2f, 0x02, 0xff, 0x01, 0x20, - 0x05, 0x00, 0x01, 0x4f, 0x01, 0xff, 0x01, 0xfb, 0x07, 0x00, 0x01, 0x0b, - 0x02, 0xff, 0x01, 0xd2, 0x04, 0x00, 0x01, 0x06, 0x02, 0xff, 0x01, 0xe1, - 0x07, 0x00, 0x01, 0x5f, 0x03, 0xff, 0x01, 0x93, 0x02, 0x00, 0x01, 0x05, - 0x01, 0xcf, 0x02, 0xff, 0x01, 0x30, 0x06, 0x00, 0x01, 0x03, 0x01, 0xff, - 0x01, 0xfb, 0x03, 0xff, 0x01, 0xfd, 0x01, 0xde, 0x03, 0xff, 0x01, 0xe3, - 0x07, 0x00, 0x01, 0x1e, 0x01, 0xff, 0x01, 0x80, 0x01, 0x4d, 0x06, 0xff, - 0x01, 0xfa, 0x01, 0x10, 0x07, 0x00, 0x01, 0xbf, 0x01, 0xfb, 0x02, 0x00, - 0x01, 0x5c, 0x04, 0xff, 0x01, 0xe9, 0x01, 0x30, 0x08, 0x00, 0x01, 0x1c, - 0x01, 0xd0, 0x03, 0x00, 0x01, 0x04, 0x01, 0x67, 0x01, 0x86, 0x01, 0x53, - 0x0b, 0x00, 0x01, 0x10, 0xa8, 0x00, - - /* 10 SML_O_STROKE */ - 0xff, 0x00, 0x15, 0x00, 0x01, 0x02, 0x01, 0x20, 0x0c, 0x00, 0x01, 0x02, - 0x01, 0x32, 0x01, 0x10, 0x02, 0x00, 0x01, 0x1d, 0x01, 0xe3, 0x0a, 0x00, - 0x01, 0x01, 0x01, 0x7c, 0x02, 0xff, 0x01, 0xfd, 0x01, 0x82, 0x01, 0x00, - 0x01, 0xcf, 0x01, 0xf7, 0x0a, 0x00, 0x01, 0x6e, 0x05, 0xff, 0x01, 0x89, - 0x01, 0xff, 0x01, 0xa0, 0x09, 0x00, 0x01, 0x08, 0x07, 0xff, 0x01, 0xfc, - 0x0a, 0x00, 0x01, 0x6f, 0x01, 0xff, 0x01, 0xfc, 0x01, 0x50, 0x01, 0x00, - 0x01, 0x3a, 0x02, 0xff, 0x01, 0xf1, 0x09, 0x00, 0x01, 0x01, 0x02, 0xff, - 0x01, 0x90, 0x03, 0x00, 0x01, 0x7f, 0x01, 0xff, 0x01, 0xf5, 0x09, 0x00, - 0x01, 0x08, 0x01, 0xff, 0x01, 0xfc, 0x03, 0x00, 0x01, 0x01, 0x01, 0xdf, - 0x01, 0xff, 0x01, 0xfd, 0x09, 0x00, 0x01, 0x0e, 0x01, 0xff, 0x01, 0xf3, - 0x03, 0x00, 0x01, 0x0b, 0x03, 0xff, 0x01, 0x30, 0x08, 0x00, 0x01, 0x3f, - 0x01, 0xff, 0x01, 0xd0, 0x03, 0x00, 0x01, 0x9f, 0x01, 0xfa, 0x01, 0x8f, - 0x01, 0xff, 0x01, 0x80, 0x08, 0x00, 0x01, 0x7f, 0x01, 0xff, 0x01, 0x80, - 0x02, 0x00, 0x01, 0x06, 0x01, 0xff, 0x01, 0xc0, 0x01, 0x3f, 0x01, 0xff, - 0x01, 0xb0, 0x08, 0x00, 0x01, 0x9f, 0x01, 0xff, 0x01, 0x50, 0x02, 0x00, - 0x01, 0x3f, 0x01, 0xfe, 0x01, 0x10, 0x01, 0x1f, 0x01, 0xff, 0x01, 0xe0, - 0x08, 0x00, 0x01, 0xaf, 0x01, 0xff, 0x01, 0x40, 0x01, 0x00, 0x01, 0x02, - 0x01, 0xef, 0x01, 0xf3, 0x01, 0x00, 0x01, 0x0f, 0x01, 0xff, 0x01, 0xf0, - 0x08, 0x00, 0x01, 0xbf, 0x01, 0xff, 0x01, 0x30, 0x01, 0x00, 0x01, 0x0d, - 0x01, 0xff, 0x01, 0x50, 0x01, 0x00, 0x01, 0x0e, 0x01, 0xff, 0x01, 0xf0, - 0x08, 0x00, 0x01, 0xaf, 0x01, 0xff, 0x01, 0x30, 0x01, 0x00, 0x01, 0xbf, - 0x01, 0xf8, 0x02, 0x00, 0x01, 0x0f, 0x01, 0xff, 0x01, 0xf0, 0x08, 0x00, - 0x01, 0x9f, 0x01, 0xff, 0x01, 0x40, 0x01, 0x08, 0x01, 0xff, 0x01, 0xb0, - 0x02, 0x00, 0x01, 0x0f, 0x01, 0xff, 0x01, 0xe0, 0x08, 0x00, 0x01, 0x7f, - 0x01, 0xff, 0x01, 0x60, 0x01, 0x5f, 0x01, 0xfd, 0x03, 0x00, 0x01, 0x3f, - 0x01, 0xff, 0x01, 0xc0, 0x08, 0x00, 0x01, 0x4f, 0x01, 0xff, 0x01, 0xa3, - 0x01, 0xff, 0x01, 0xe2, 0x03, 0x00, 0x01, 0x7f, 0x01, 0xff, 0x01, 0x90, - 0x08, 0x00, 0x01, 0x0f, 0x01, 0xff, 0x01, 0xfe, 0x01, 0xff, 0x01, 0x40, - 0x03, 0x00, 0x01, 0xcf, 0x01, 0xff, 0x01, 0x50, 0x08, 0x00, 0x01, 0x0a, - 0x02, 0xff, 0x01, 0xf6, 0x03, 0x00, 0x01, 0x05, 0x01, 0xff, 0x01, 0xfe, - 0x09, 0x00, 0x01, 0x02, 0x02, 0xff, 0x01, 0xb0, 0x03, 0x00, 0x01, 0x2e, - 0x01, 0xff, 0x01, 0xf8, 0x0a, 0x00, 0x01, 0xbf, 0x01, 0xff, 0x01, 0xf7, - 0x02, 0x00, 0x01, 0x05, 0x01, 0xef, 0x01, 0xff, 0x01, 0xd0, 0x09, 0x00, - 0x01, 0x04, 0x03, 0xff, 0x01, 0xfc, 0x01, 0xab, 0x01, 0xef, 0x01, 0xff, - 0x01, 0xfe, 0x01, 0x20, 0x09, 0x00, 0x01, 0x2f, 0x01, 0xff, 0x01, 0xaf, - 0x05, 0xff, 0x01, 0xd2, 0x09, 0x00, 0x01, 0x01, 0x01, 0xdf, 0x01, 0xf5, - 0x01, 0x04, 0x01, 0xbf, 0x03, 0xff, 0x01, 0xd6, 0x0a, 0x00, 0x01, 0x03, - 0x01, 0xff, 0x01, 0x70, 0x01, 0x00, 0x01, 0x01, 0x01, 0x46, 0x01, 0x76, - 0x01, 0x52, 0x0c, 0x00, 0x01, 0x28, 0xa9, 0x00, - - /* 11 LRG_AE */ - 0x9e, 0x00, 0x01, 0x14, 0x0b, 0x44, 0x01, 0x41, 0x06, 0x00, 0x01, 0x8f, - 0x0b, 0xff, 0x01, 0xf3, 0x06, 0x00, 0x01, 0xef, 0x0b, 0xff, 0x01, 0xf3, - 0x05, 0x00, 0x01, 0x05, 0x02, 0xff, 0x01, 0xee, 0x09, 0xff, 0x01, 0xf3, - 0x05, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xf5, 0x01, 0x00, 0x01, 0xdf, - 0x01, 0xff, 0x01, 0x63, 0x06, 0x33, 0x01, 0x30, 0x05, 0x00, 0x01, 0x3f, - 0x01, 0xff, 0x01, 0xe0, 0x01, 0x00, 0x01, 0xdf, 0x01, 0xff, 0x01, 0x40, - 0x0c, 0x00, 0x01, 0xaf, 0x01, 0xff, 0x01, 0x80, 0x01, 0x00, 0x01, 0xdf, - 0x01, 0xff, 0x01, 0x40, 0x0b, 0x00, 0x01, 0x01, 0x02, 0xff, 0x01, 0x10, - 0x01, 0x00, 0x01, 0xdf, 0x01, 0xff, 0x01, 0x40, 0x0b, 0x00, 0x01, 0x07, - 0x01, 0xff, 0x01, 0xfa, 0x02, 0x00, 0x01, 0xdf, 0x01, 0xff, 0x01, 0x40, - 0x0b, 0x00, 0x01, 0x0d, 0x01, 0xff, 0x01, 0xf3, 0x02, 0x00, 0x01, 0xdf, - 0x01, 0xff, 0x01, 0x40, 0x0b, 0x00, 0x01, 0x4f, 0x01, 0xff, 0x01, 0xd0, - 0x02, 0x00, 0x01, 0xdf, 0x01, 0xff, 0x01, 0x40, 0x0b, 0x00, 0x01, 0xbf, - 0x01, 0xff, 0x01, 0x60, 0x02, 0x00, 0x01, 0xdf, 0x01, 0xff, 0x01, 0x40, - 0x0a, 0x00, 0x01, 0x02, 0x01, 0xff, 0x01, 0xfe, 0x03, 0x00, 0x01, 0xdf, - 0x01, 0xff, 0x01, 0x40, 0x0a, 0x00, 0x01, 0x08, 0x01, 0xff, 0x01, 0xf9, - 0x03, 0x00, 0x01, 0xdf, 0x01, 0xff, 0x01, 0xed, 0x06, 0xdd, 0x01, 0x80, - 0x03, 0x00, 0x01, 0x0e, 0x01, 0xff, 0x01, 0xf2, 0x03, 0x00, 0x01, 0xdf, - 0x08, 0xff, 0x01, 0xa0, 0x03, 0x00, 0x01, 0x6f, 0x01, 0xff, 0x01, 0xb0, - 0x03, 0x00, 0x01, 0xdf, 0x08, 0xff, 0x01, 0xa0, 0x03, 0x00, 0x01, 0xcf, - 0x01, 0xff, 0x01, 0x40, 0x03, 0x00, 0x01, 0xdf, 0x01, 0xff, 0x01, 0xa8, - 0x06, 0x88, 0x01, 0x50, 0x02, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xfe, - 0x04, 0x00, 0x01, 0xdf, 0x01, 0xff, 0x01, 0x40, 0x09, 0x00, 0x01, 0x0a, - 0x01, 0xff, 0x01, 0xf7, 0x04, 0x00, 0x01, 0xdf, 0x01, 0xff, 0x01, 0x40, - 0x09, 0x00, 0x01, 0x1f, 0x01, 0xff, 0x01, 0xf4, 0x04, 0x33, 0x01, 0xdf, - 0x01, 0xff, 0x01, 0x40, 0x09, 0x00, 0x01, 0x7f, 0x08, 0xff, 0x01, 0x40, - 0x09, 0x00, 0x01, 0xef, 0x08, 0xff, 0x01, 0x40, 0x08, 0x00, 0x01, 0x05, - 0x09, 0xff, 0x01, 0x40, 0x08, 0x00, 0x01, 0x0b, 0x01, 0xff, 0x01, 0xf7, - 0x05, 0x33, 0x01, 0xdf, 0x01, 0xff, 0x01, 0x40, 0x08, 0x00, 0x01, 0x2f, - 0x01, 0xff, 0x01, 0xe0, 0x05, 0x00, 0x01, 0xdf, 0x01, 0xff, 0x01, 0x40, - 0x08, 0x00, 0x01, 0x9f, 0x01, 0xff, 0x01, 0x80, 0x05, 0x00, 0x01, 0xdf, - 0x01, 0xff, 0x01, 0x40, 0x08, 0x00, 0x02, 0xff, 0x01, 0x20, 0x05, 0x00, - 0x01, 0xdf, 0x01, 0xff, 0x01, 0x40, 0x07, 0x00, 0x01, 0x06, 0x01, 0xff, - 0x01, 0xfb, 0x06, 0x00, 0x01, 0xdf, 0x01, 0xff, 0x01, 0xa8, 0x06, 0x88, - 0x01, 0x85, 0x01, 0x0d, 0x01, 0xff, 0x01, 0xf4, 0x06, 0x00, 0x01, 0xdf, - 0x08, 0xff, 0x01, 0xf9, 0x01, 0x4f, 0x01, 0xff, 0x01, 0xe0, 0x06, 0x00, - 0x01, 0xdf, 0x08, 0xff, 0x01, 0xf9, 0x01, 0x8d, 0x01, 0xdd, 0x01, 0x60, - 0x06, 0x00, 0x01, 0xbd, 0x08, 0xdd, 0x01, 0xd8, 0xbe, 0x00, - - /* 12 SML_AE */ - 0xff, 0x00, 0x22, 0x00, 0x01, 0x01, 0x01, 0x34, 0x01, 0x31, 0x06, 0x00, - 0x01, 0x12, 0x01, 0x42, 0x01, 0x10, 0x05, 0x00, 0x01, 0x02, 0x01, 0x7b, - 0x01, 0xef, 0x02, 0xff, 0x01, 0xfb, 0x01, 0x60, 0x02, 0x00, 0x01, 0x03, - 0x01, 0x9e, 0x02, 0xff, 0x01, 0xfd, 0x01, 0x81, 0x04, 0x00, 0x01, 0xbf, - 0x05, 0xff, 0x01, 0xfe, 0x01, 0x40, 0x01, 0x01, 0x01, 0x9f, 0x05, 0xff, - 0x01, 0x60, 0x03, 0x00, 0x01, 0xdf, 0x02, 0xff, 0x01, 0xee, 0x03, 0xff, - 0x01, 0xf5, 0x01, 0x1d, 0x03, 0xff, 0x01, 0xef, 0x02, 0xff, 0x01, 0xf8, - 0x03, 0x00, 0x01, 0xdf, 0x01, 0xb6, 0x01, 0x30, 0x01, 0x00, 0x01, 0x01, - 0x01, 0x5d, 0x02, 0xff, 0x01, 0xdf, 0x01, 0xff, 0x01, 0xe7, 0x01, 0x20, - 0x01, 0x00, 0x01, 0x29, 0x02, 0xff, 0x01, 0x50, 0x02, 0x00, 0x01, 0x71, - 0x05, 0x00, 0x01, 0xaf, 0x02, 0xff, 0x01, 0xfb, 0x01, 0x10, 0x03, 0x00, - 0x01, 0x4f, 0x01, 0xff, 0x01, 0xe0, 0x08, 0x00, 0x01, 0x0d, 0x02, 0xff, - 0x01, 0xd0, 0x04, 0x00, 0x01, 0x07, 0x01, 0xff, 0x01, 0xf7, 0x08, 0x00, - 0x01, 0x06, 0x02, 0xff, 0x01, 0x40, 0x05, 0x00, 0x01, 0xef, 0x01, 0xfd, - 0x08, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xfd, 0x06, 0x00, 0x01, 0x9f, - 0x01, 0xff, 0x04, 0x00, 0x01, 0x02, 0x01, 0x45, 0x02, 0x66, 0x01, 0x67, - 0x01, 0xff, 0x01, 0xf9, 0x06, 0x00, 0x01, 0x6f, 0x01, 0xff, 0x03, 0x00, - 0x01, 0x4a, 0x06, 0xff, 0x01, 0xfb, 0x03, 0x66, 0x01, 0x67, 0x02, 0x77, - 0x01, 0xaf, 0x01, 0xff, 0x02, 0x00, 0x01, 0x1b, 0x10, 0xff, 0x01, 0x00, - 0x01, 0x01, 0x01, 0xdf, 0x02, 0xff, 0x01, 0xca, 0x01, 0x98, 0x01, 0x88, - 0x01, 0x89, 0x0a, 0xff, 0x01, 0x00, 0x01, 0x09, 0x01, 0xff, 0x01, 0xfd, - 0x01, 0x40, 0x03, 0x00, 0x01, 0x02, 0x01, 0xff, 0x01, 0xfa, 0x08, 0x77, - 0x01, 0x00, 0x01, 0x1f, 0x01, 0xff, 0x01, 0xd0, 0x04, 0x00, 0x01, 0x03, - 0x01, 0xff, 0x01, 0xf7, 0x09, 0x00, 0x01, 0x5f, 0x01, 0xff, 0x01, 0x70, - 0x04, 0x00, 0x01, 0x05, 0x01, 0xff, 0x01, 0xfa, 0x09, 0x00, 0x01, 0x7f, - 0x01, 0xff, 0x01, 0x30, 0x04, 0x00, 0x01, 0x09, 0x01, 0xff, 0x01, 0xfe, - 0x09, 0x00, 0x01, 0x7f, 0x01, 0xff, 0x01, 0x30, 0x04, 0x00, 0x01, 0x0f, - 0x02, 0xff, 0x01, 0x50, 0x08, 0x00, 0x01, 0x6f, 0x01, 0xff, 0x01, 0x60, - 0x04, 0x00, 0x01, 0x8f, 0x02, 0xff, 0x01, 0xe1, 0x08, 0x00, 0x01, 0x3f, - 0x01, 0xff, 0x01, 0xd0, 0x03, 0x00, 0x01, 0x06, 0x01, 0xff, 0x01, 0xfe, - 0x01, 0xff, 0x01, 0xfc, 0x01, 0x10, 0x05, 0x00, 0x01, 0x45, 0x01, 0x00, - 0x01, 0x0d, 0x01, 0xff, 0x01, 0xfc, 0x01, 0x20, 0x01, 0x00, 0x01, 0x01, - 0x01, 0x9f, 0x01, 0xff, 0x01, 0xa2, 0x02, 0xff, 0x01, 0xe6, 0x01, 0x10, - 0x02, 0x00, 0x01, 0x02, 0x01, 0x8d, 0x01, 0xf8, 0x01, 0x00, 0x01, 0x05, - 0x02, 0xff, 0x01, 0xfd, 0x01, 0xab, 0x01, 0xcf, 0x01, 0xff, 0x01, 0xfc, - 0x01, 0x00, 0x01, 0x3f, 0x02, 0xff, 0x01, 0xfd, 0x01, 0xba, 0x01, 0xbc, - 0x02, 0xff, 0x01, 0xf8, 0x02, 0x00, 0x01, 0x7f, 0x05, 0xff, 0x01, 0xa0, - 0x01, 0x00, 0x01, 0x02, 0x01, 0xcf, 0x06, 0xff, 0x01, 0xf7, 0x02, 0x00, - 0x01, 0x03, 0x01, 0xbf, 0x03, 0xff, 0x01, 0xb4, 0x03, 0x00, 0x01, 0x05, - 0x01, 0xbf, 0x04, 0xff, 0x01, 0xb7, 0x01, 0x10, 0x03, 0x00, 0x01, 0x01, - 0x01, 0x46, 0x01, 0x76, 0x01, 0x41, 0x06, 0x00, 0x01, 0x35, 0x01, 0x67, - 0x01, 0x64, 0x01, 0x20, 0xad, 0x00, - - /* 13 LRG_ETH */ - 0x9a, 0x00, 0x01, 0x34, 0x03, 0x44, 0x01, 0x43, 0x01, 0x21, 0x0d, 0x00, - 0x01, 0xbf, 0x05, 0xff, 0x01, 0xfe, 0x01, 0xb8, 0x01, 0x40, 0x0a, 0x00, - 0x01, 0xbf, 0x07, 0xff, 0x01, 0xfe, 0x01, 0x81, 0x09, 0x00, 0x01, 0xbf, - 0x08, 0xff, 0x01, 0xfe, 0x01, 0x60, 0x08, 0x00, 0x01, 0xbf, 0x01, 0xff, - 0x01, 0x61, 0x02, 0x11, 0x01, 0x23, 0x01, 0x58, 0x01, 0xcf, 0x02, 0xff, - 0x01, 0xf9, 0x08, 0x00, 0x01, 0xbf, 0x01, 0xff, 0x01, 0x50, 0x04, 0x00, - 0x01, 0x02, 0x01, 0x9f, 0x02, 0xff, 0x01, 0x80, 0x07, 0x00, 0x01, 0xbf, - 0x01, 0xff, 0x01, 0x50, 0x05, 0x00, 0x01, 0x04, 0x01, 0xef, 0x01, 0xff, - 0x01, 0xf4, 0x07, 0x00, 0x01, 0xbf, 0x01, 0xff, 0x01, 0x50, 0x06, 0x00, - 0x01, 0x2f, 0x01, 0xff, 0x01, 0xfd, 0x07, 0x00, 0x01, 0xbf, 0x01, 0xff, - 0x01, 0x50, 0x06, 0x00, 0x01, 0x06, 0x02, 0xff, 0x01, 0x50, 0x06, 0x00, - 0x01, 0xbf, 0x01, 0xff, 0x01, 0x50, 0x07, 0x00, 0x01, 0xef, 0x01, 0xff, - 0x01, 0xb0, 0x06, 0x00, 0x01, 0xbf, 0x01, 0xff, 0x01, 0x50, 0x07, 0x00, - 0x01, 0x7f, 0x01, 0xff, 0x01, 0xf0, 0x06, 0x00, 0x01, 0xbf, 0x01, 0xff, - 0x01, 0x50, 0x07, 0x00, 0x01, 0x3f, 0x01, 0xff, 0x01, 0xf3, 0x06, 0x00, - 0x01, 0xbf, 0x01, 0xff, 0x01, 0x50, 0x07, 0x00, 0x01, 0x0f, 0x01, 0xff, - 0x01, 0xf5, 0x04, 0x00, 0x01, 0x23, 0x01, 0x33, 0x01, 0xcf, 0x01, 0xff, - 0x01, 0x73, 0x02, 0x33, 0x01, 0x30, 0x04, 0x00, 0x01, 0x0d, 0x01, 0xff, - 0x01, 0xf6, 0x04, 0x00, 0x01, 0xcf, 0x06, 0xff, 0x01, 0xf2, 0x04, 0x00, - 0x01, 0x0c, 0x01, 0xff, 0x01, 0xf7, 0x04, 0x00, 0x01, 0xcf, 0x06, 0xff, - 0x01, 0xf2, 0x04, 0x00, 0x01, 0x0b, 0x01, 0xff, 0x01, 0xf9, 0x04, 0x00, - 0x01, 0x9b, 0x01, 0xbb, 0x01, 0xef, 0x01, 0xff, 0x01, 0xdb, 0x02, 0xbb, - 0x01, 0xb1, 0x04, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xf8, 0x06, 0x00, - 0x01, 0xbf, 0x01, 0xff, 0x01, 0x50, 0x07, 0x00, 0x01, 0x0d, 0x01, 0xff, - 0x01, 0xf7, 0x06, 0x00, 0x01, 0xbf, 0x01, 0xff, 0x01, 0x50, 0x07, 0x00, - 0x01, 0x0e, 0x01, 0xff, 0x01, 0xf6, 0x06, 0x00, 0x01, 0xbf, 0x01, 0xff, - 0x01, 0x50, 0x07, 0x00, 0x01, 0x1f, 0x01, 0xff, 0x01, 0xf4, 0x06, 0x00, - 0x01, 0xbf, 0x01, 0xff, 0x01, 0x50, 0x07, 0x00, 0x01, 0x5f, 0x01, 0xff, - 0x01, 0xf1, 0x06, 0x00, 0x01, 0xbf, 0x01, 0xff, 0x01, 0x50, 0x07, 0x00, - 0x01, 0xaf, 0x01, 0xff, 0x01, 0xd0, 0x06, 0x00, 0x01, 0xbf, 0x01, 0xff, - 0x01, 0x50, 0x06, 0x00, 0x01, 0x01, 0x02, 0xff, 0x01, 0x80, 0x06, 0x00, - 0x01, 0xbf, 0x01, 0xff, 0x01, 0x50, 0x06, 0x00, 0x01, 0x0b, 0x02, 0xff, - 0x01, 0x20, 0x06, 0x00, 0x01, 0xbf, 0x01, 0xff, 0x01, 0x50, 0x06, 0x00, - 0x01, 0x8f, 0x01, 0xff, 0x01, 0xf9, 0x07, 0x00, 0x01, 0xbf, 0x01, 0xff, - 0x01, 0x50, 0x05, 0x00, 0x01, 0x0a, 0x02, 0xff, 0x01, 0xe1, 0x07, 0x00, - 0x01, 0xbf, 0x01, 0xff, 0x01, 0x50, 0x04, 0x00, 0x01, 0x29, 0x03, 0xff, - 0x01, 0x30, 0x07, 0x00, 0x01, 0xbf, 0x01, 0xff, 0x01, 0xa7, 0x01, 0x77, - 0x01, 0x78, 0x01, 0x9a, 0x01, 0xbf, 0x03, 0xff, 0x01, 0xe3, 0x08, 0x00, - 0x01, 0xbf, 0x08, 0xff, 0x01, 0xf9, 0x01, 0x10, 0x08, 0x00, 0x01, 0xbf, - 0x07, 0xff, 0x01, 0xd8, 0x01, 0x10, 0x09, 0x00, 0x01, 0xad, 0x03, 0xdd, - 0x01, 0xdc, 0x01, 0xcb, 0x01, 0xa7, 0x01, 0x41, 0xc7, 0x00, - - /* 14 SML_ETH */ - 0x88, 0x00, 0x01, 0x38, 0x01, 0x88, 0x01, 0x81, 0x10, 0x00, 0x01, 0x0b, - 0x01, 0xff, 0x01, 0xfc, 0x03, 0x00, 0x01, 0x5a, 0x01, 0x40, 0x0c, 0x00, - 0x01, 0xdf, 0x01, 0xff, 0x01, 0xb0, 0x01, 0x04, 0x01, 0xaf, 0x01, 0xff, - 0x01, 0xa0, 0x0c, 0x00, 0x01, 0x1e, 0x01, 0xff, 0x01, 0xfc, 0x02, 0xff, - 0x01, 0xd8, 0x01, 0x20, 0x0c, 0x00, 0x01, 0x07, 0x02, 0xff, 0x01, 0xfd, - 0x01, 0x82, 0x0d, 0x00, 0x01, 0x5a, 0x03, 0xff, 0x01, 0xf4, 0x0d, 0x00, - 0x01, 0x7f, 0x01, 0xff, 0x01, 0xfd, 0x01, 0x87, 0x02, 0xff, 0x01, 0x30, - 0x0c, 0x00, 0x01, 0x6f, 0x01, 0xe9, 0x01, 0x30, 0x01, 0x00, 0x01, 0x8f, - 0x01, 0xff, 0x01, 0xe2, 0x0c, 0x00, 0x01, 0x03, 0x03, 0x00, 0x01, 0x0a, - 0x01, 0xff, 0x01, 0xfd, 0x01, 0x10, 0x0e, 0x00, 0x01, 0x23, 0x01, 0x44, - 0x01, 0xdf, 0x01, 0xff, 0x01, 0xb0, 0x0c, 0x00, 0x01, 0x02, 0x01, 0x9e, - 0x04, 0xff, 0x01, 0xf7, 0x0c, 0x00, 0x01, 0x7f, 0x06, 0xff, 0x01, 0x30, - 0x0a, 0x00, 0x01, 0x09, 0x02, 0xff, 0x01, 0xfe, 0x01, 0xcb, 0x01, 0xdf, - 0x02, 0xff, 0x01, 0xd0, 0x0a, 0x00, 0x01, 0x6f, 0x01, 0xff, 0x01, 0xfb, - 0x01, 0x30, 0x02, 0x00, 0x01, 0x4e, 0x01, 0xff, 0x01, 0xf5, 0x09, 0x00, - 0x01, 0x02, 0x02, 0xff, 0x01, 0x70, 0x03, 0x00, 0x01, 0x05, 0x01, 0xff, - 0x01, 0xfd, 0x09, 0x00, 0x01, 0x09, 0x01, 0xff, 0x01, 0xfa, 0x05, 0x00, - 0x01, 0xef, 0x01, 0xff, 0x01, 0x20, 0x08, 0x00, 0x01, 0x0f, 0x01, 0xff, - 0x01, 0xf1, 0x05, 0x00, 0x01, 0x8f, 0x01, 0xff, 0x01, 0x70, 0x08, 0x00, - 0x01, 0x4f, 0x01, 0xff, 0x01, 0xa0, 0x05, 0x00, 0x01, 0x4f, 0x01, 0xff, - 0x01, 0xb0, 0x08, 0x00, 0x01, 0x8f, 0x01, 0xff, 0x01, 0x70, 0x05, 0x00, - 0x01, 0x1f, 0x01, 0xff, 0x01, 0xd0, 0x08, 0x00, 0x01, 0x9f, 0x01, 0xff, - 0x01, 0x40, 0x05, 0x00, 0x01, 0x0f, 0x01, 0xff, 0x01, 0xf0, 0x08, 0x00, - 0x01, 0xaf, 0x01, 0xff, 0x01, 0x30, 0x05, 0x00, 0x01, 0x0e, 0x01, 0xff, - 0x01, 0xf0, 0x08, 0x00, 0x01, 0xaf, 0x01, 0xff, 0x01, 0x30, 0x05, 0x00, - 0x01, 0x0f, 0x01, 0xff, 0x01, 0xf0, 0x08, 0x00, 0x01, 0x9f, 0x01, 0xff, - 0x01, 0x40, 0x05, 0x00, 0x01, 0x0f, 0x01, 0xff, 0x01, 0xe0, 0x08, 0x00, - 0x01, 0x8f, 0x01, 0xff, 0x01, 0x70, 0x05, 0x00, 0x01, 0x2f, 0x01, 0xff, - 0x01, 0xd0, 0x08, 0x00, 0x01, 0x4f, 0x01, 0xff, 0x01, 0xa0, 0x05, 0x00, - 0x01, 0x6f, 0x01, 0xff, 0x01, 0x90, 0x08, 0x00, 0x01, 0x0f, 0x01, 0xff, - 0x01, 0xf1, 0x05, 0x00, 0x01, 0xcf, 0x01, 0xff, 0x01, 0x50, 0x08, 0x00, - 0x01, 0x09, 0x01, 0xff, 0x01, 0xf9, 0x04, 0x00, 0x01, 0x05, 0x01, 0xff, - 0x01, 0xfe, 0x09, 0x00, 0x01, 0x02, 0x02, 0xff, 0x01, 0x60, 0x03, 0x00, - 0x01, 0x3e, 0x01, 0xff, 0x01, 0xf6, 0x0a, 0x00, 0x01, 0x7f, 0x01, 0xff, - 0x01, 0xf9, 0x01, 0x20, 0x01, 0x00, 0x01, 0x07, 0x02, 0xff, 0x01, 0xb0, - 0x0a, 0x00, 0x01, 0x09, 0x02, 0xff, 0x01, 0xfd, 0x01, 0xbd, 0x02, 0xff, - 0x01, 0xfd, 0x01, 0x10, 0x0b, 0x00, 0x01, 0x7f, 0x05, 0xff, 0x01, 0xb0, - 0x0c, 0x00, 0x01, 0x02, 0x01, 0xae, 0x03, 0xff, 0x01, 0xb4, 0x0f, 0x00, - 0x01, 0x35, 0x01, 0x65, 0x01, 0x40, 0xb6, 0x00, - - /* 15 LRG_THORN */ - 0x9a, 0x00, 0x02, 0x55, 0x11, 0x00, 0x02, 0xff, 0x01, 0x20, 0x10, 0x00, - 0x02, 0xff, 0x01, 0x20, 0x10, 0x00, 0x02, 0xff, 0x01, 0x20, 0x10, 0x00, - 0x02, 0xff, 0x01, 0x20, 0x10, 0x00, 0x02, 0xff, 0x01, 0x20, 0x10, 0x00, - 0x05, 0xff, 0x01, 0xed, 0x01, 0xa7, 0x01, 0x10, 0x0b, 0x00, 0x07, 0xff, - 0x01, 0xfa, 0x01, 0x10, 0x0a, 0x00, 0x08, 0xff, 0x01, 0xe2, 0x0a, 0x00, - 0x02, 0xff, 0x01, 0x65, 0x01, 0x55, 0x01, 0x56, 0x01, 0x7a, 0x02, 0xff, - 0x01, 0xfe, 0x01, 0x10, 0x09, 0x00, 0x02, 0xff, 0x01, 0x20, 0x03, 0x00, - 0x01, 0x1b, 0x02, 0xff, 0x01, 0x80, 0x09, 0x00, 0x02, 0xff, 0x01, 0x20, - 0x04, 0x00, 0x01, 0xcf, 0x01, 0xff, 0x01, 0xf0, 0x09, 0x00, 0x02, 0xff, - 0x01, 0x20, 0x04, 0x00, 0x01, 0x4f, 0x01, 0xff, 0x01, 0xf3, 0x09, 0x00, - 0x02, 0xff, 0x01, 0x20, 0x04, 0x00, 0x01, 0x0f, 0x01, 0xff, 0x01, 0xf6, - 0x09, 0x00, 0x02, 0xff, 0x01, 0x20, 0x04, 0x00, 0x01, 0x0d, 0x01, 0xff, - 0x01, 0xf7, 0x09, 0x00, 0x02, 0xff, 0x01, 0x20, 0x04, 0x00, 0x01, 0x0d, - 0x01, 0xff, 0x01, 0xf7, 0x09, 0x00, 0x02, 0xff, 0x01, 0x20, 0x04, 0x00, - 0x01, 0x0f, 0x01, 0xff, 0x01, 0xf6, 0x09, 0x00, 0x02, 0xff, 0x01, 0x20, - 0x04, 0x00, 0x01, 0x4f, 0x01, 0xff, 0x01, 0xf3, 0x09, 0x00, 0x02, 0xff, - 0x01, 0x20, 0x04, 0x00, 0x01, 0xcf, 0x01, 0xff, 0x01, 0xf0, 0x09, 0x00, - 0x02, 0xff, 0x01, 0x20, 0x03, 0x00, 0x01, 0x1b, 0x02, 0xff, 0x01, 0x80, - 0x09, 0x00, 0x02, 0xff, 0x01, 0x65, 0x02, 0x55, 0x01, 0x7a, 0x02, 0xff, - 0x01, 0xfe, 0x01, 0x10, 0x09, 0x00, 0x08, 0xff, 0x01, 0xe2, 0x0a, 0x00, - 0x07, 0xff, 0x01, 0xfa, 0x01, 0x10, 0x0a, 0x00, 0x05, 0xff, 0x01, 0xed, - 0x01, 0xa7, 0x01, 0x10, 0x0b, 0x00, 0x02, 0xff, 0x01, 0x20, 0x10, 0x00, - 0x02, 0xff, 0x01, 0x20, 0x10, 0x00, 0x02, 0xff, 0x01, 0x20, 0x10, 0x00, - 0x02, 0xff, 0x01, 0x20, 0x10, 0x00, 0x02, 0xff, 0x01, 0x20, 0x10, 0x00, - 0x02, 0xff, 0x01, 0x20, 0x10, 0x00, 0x02, 0xcc, 0x01, 0x10, 0xcc, 0x00, - - /* 16 SML_THORN */ - 0x86, 0x00, 0x01, 0x02, 0x01, 0x99, 0x01, 0x94, 0x10, 0x00, 0x01, 0x03, - 0x01, 0xff, 0x01, 0xf7, 0x10, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xf7, - 0x10, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xf7, 0x10, 0x00, 0x01, 0x03, - 0x01, 0xff, 0x01, 0xf7, 0x10, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xf7, - 0x10, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xf7, 0x10, 0x00, 0x01, 0x03, - 0x01, 0xff, 0x01, 0xf7, 0x10, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xf7, - 0x02, 0x00, 0x01, 0x13, 0x01, 0x54, 0x01, 0x20, 0x0b, 0x00, 0x01, 0x03, - 0x01, 0xff, 0x01, 0xf7, 0x01, 0x00, 0x01, 0x5c, 0x02, 0xff, 0x01, 0xfd, - 0x01, 0x70, 0x0a, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xf7, 0x01, 0x0b, - 0x04, 0xff, 0x01, 0xfd, 0x01, 0x20, 0x09, 0x00, 0x01, 0x03, 0x01, 0xff, - 0x01, 0xf7, 0x01, 0xaf, 0x01, 0xff, 0x01, 0xec, 0x01, 0xdf, 0x02, 0xff, - 0x01, 0xe1, 0x09, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xfd, 0x01, 0xff, - 0x01, 0xc3, 0x02, 0x00, 0x01, 0x6f, 0x01, 0xff, 0x01, 0xfc, 0x09, 0x00, - 0x01, 0x03, 0x02, 0xff, 0x01, 0xfa, 0x03, 0x00, 0x01, 0x02, 0x01, 0xef, - 0x01, 0xff, 0x01, 0x60, 0x08, 0x00, 0x01, 0x03, 0x02, 0xff, 0x01, 0xe0, - 0x04, 0x00, 0x01, 0x5f, 0x01, 0xff, 0x01, 0xd0, 0x08, 0x00, 0x01, 0x03, - 0x02, 0xff, 0x01, 0x60, 0x04, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xf3, - 0x08, 0x00, 0x01, 0x03, 0x02, 0xff, 0x05, 0x00, 0x01, 0x06, 0x01, 0xff, - 0x01, 0xf7, 0x08, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xfc, 0x05, 0x00, - 0x01, 0x02, 0x01, 0xff, 0x01, 0xfb, 0x08, 0x00, 0x01, 0x03, 0x01, 0xff, - 0x01, 0xf9, 0x06, 0x00, 0x01, 0xff, 0x01, 0xfd, 0x08, 0x00, 0x01, 0x03, - 0x01, 0xff, 0x01, 0xf8, 0x06, 0x00, 0x01, 0xef, 0x01, 0xfe, 0x08, 0x00, - 0x01, 0x03, 0x01, 0xff, 0x01, 0xf8, 0x06, 0x00, 0x01, 0xef, 0x01, 0xff, - 0x08, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xf8, 0x06, 0x00, 0x01, 0xef, - 0x01, 0xfe, 0x08, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xf9, 0x06, 0x00, - 0x01, 0xff, 0x01, 0xfd, 0x08, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xfc, - 0x05, 0x00, 0x01, 0x02, 0x01, 0xff, 0x01, 0xfb, 0x08, 0x00, 0x01, 0x03, - 0x02, 0xff, 0x05, 0x00, 0x01, 0x06, 0x01, 0xff, 0x01, 0xf8, 0x08, 0x00, - 0x01, 0x03, 0x02, 0xff, 0x01, 0x60, 0x04, 0x00, 0x01, 0x0c, 0x01, 0xff, - 0x01, 0xf3, 0x08, 0x00, 0x01, 0x03, 0x02, 0xff, 0x01, 0xd0, 0x04, 0x00, - 0x01, 0x5f, 0x01, 0xff, 0x01, 0xd0, 0x08, 0x00, 0x01, 0x03, 0x02, 0xff, - 0x01, 0xfa, 0x03, 0x00, 0x01, 0x02, 0x01, 0xef, 0x01, 0xff, 0x01, 0x60, - 0x08, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xfd, 0x01, 0xff, 0x01, 0xb3, - 0x02, 0x00, 0x01, 0x6e, 0x01, 0xff, 0x01, 0xfc, 0x09, 0x00, 0x01, 0x03, - 0x01, 0xff, 0x01, 0xf7, 0x01, 0xbf, 0x01, 0xff, 0x01, 0xec, 0x01, 0xcf, - 0x02, 0xff, 0x01, 0xe2, 0x09, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xf7, - 0x01, 0x0b, 0x04, 0xff, 0x01, 0xfd, 0x01, 0x20, 0x09, 0x00, 0x01, 0x03, - 0x01, 0xff, 0x01, 0xf7, 0x01, 0x00, 0x01, 0x6c, 0x02, 0xff, 0x01, 0xfe, - 0x01, 0x70, 0x0a, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xf7, 0x02, 0x00, - 0x01, 0x23, 0x01, 0x54, 0x01, 0x20, 0x0b, 0x00, 0x01, 0x03, 0x01, 0xff, - 0x01, 0xf7, 0x10, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xf7, 0x10, 0x00, - 0x01, 0x03, 0x01, 0xff, 0x01, 0xf7, 0x10, 0x00, 0x01, 0x03, 0x01, 0xff, - 0x01, 0xf7, 0x10, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xf7, 0x10, 0x00, - 0x01, 0x03, 0x01, 0xff, 0x01, 0xf7, 0x10, 0x00, 0x01, 0x03, 0x01, 0xff, - 0x01, 0xf7, 0x10, 0x00, 0x01, 0x01, 0x01, 0x66, 0x01, 0x63, 0x22, 0x00, -#endif // TOUCH_UI_UTF8_SCANDINAVIAN - -#if ENABLED(TOUCH_UI_UTF8_PUNCTUATION) - /* 17 LEFT_DBL_QUOTE */ - 0xff, 0x00, 0x4a, 0x00, 0x01, 0x30, 0x03, 0x00, 0x01, 0x02, 0x0d, 0x00, - 0x01, 0x08, 0x01, 0xa0, 0x02, 0x00, 0x01, 0x01, 0x01, 0xc6, 0x0d, 0x00, - 0x01, 0xaf, 0x01, 0xa0, 0x02, 0x00, 0x01, 0x1d, 0x01, 0xf6, 0x0c, 0x00, - 0x01, 0x1c, 0x01, 0xff, 0x01, 0xa0, 0x01, 0x00, 0x01, 0x02, 0x01, 0xef, - 0x01, 0xf6, 0x0b, 0x00, 0x01, 0x01, 0x01, 0xdf, 0x01, 0xff, 0x01, 0x50, - 0x01, 0x00, 0x01, 0x3e, 0x01, 0xff, 0x01, 0xe2, 0x0b, 0x00, 0x01, 0x2e, - 0x01, 0xff, 0x01, 0xf4, 0x01, 0x00, 0x01, 0x05, 0x01, 0xff, 0x01, 0xfd, - 0x01, 0x20, 0x0a, 0x00, 0x01, 0x04, 0x01, 0xef, 0x01, 0xfe, 0x01, 0x30, - 0x01, 0x00, 0x01, 0x6f, 0x01, 0xff, 0x01, 0xd1, 0x0b, 0x00, 0x01, 0x5f, - 0x01, 0xff, 0x01, 0xd2, 0x01, 0x00, 0x01, 0x08, 0x01, 0xff, 0x01, 0xfb, - 0x0b, 0x00, 0x01, 0x06, 0x01, 0xff, 0x01, 0xfc, 0x01, 0x10, 0x01, 0x00, - 0x01, 0xaf, 0x01, 0xff, 0x01, 0xa0, 0x0b, 0x00, 0x01, 0x0c, 0x01, 0xff, - 0x01, 0xd0, 0x02, 0x00, 0x01, 0xff, 0x01, 0xfa, 0x0c, 0x00, 0x01, 0x0a, - 0x01, 0xff, 0x01, 0xf8, 0x02, 0x00, 0x01, 0xef, 0x01, 0xff, 0x01, 0x50, - 0x0c, 0x00, 0x01, 0xaf, 0x01, 0xff, 0x01, 0xa0, 0x01, 0x00, 0x01, 0x1c, - 0x01, 0xff, 0x01, 0xf6, 0x0c, 0x00, 0x01, 0x08, 0x01, 0xff, 0x01, 0xfb, - 0x02, 0x00, 0x01, 0xbf, 0x01, 0xff, 0x01, 0x90, 0x0c, 0x00, 0x01, 0x6f, - 0x01, 0xff, 0x01, 0xd1, 0x01, 0x00, 0x01, 0x0a, 0x01, 0xff, 0x01, 0xfa, - 0x0c, 0x00, 0x01, 0x05, 0x01, 0xff, 0x01, 0xfd, 0x01, 0x20, 0x01, 0x00, - 0x01, 0x8f, 0x01, 0xff, 0x01, 0xb0, 0x0c, 0x00, 0x01, 0x4f, 0x01, 0xff, - 0x01, 0xa0, 0x01, 0x00, 0x01, 0x07, 0x01, 0xff, 0x01, 0xf6, 0x0c, 0x00, - 0x01, 0x02, 0x01, 0xef, 0x01, 0xa0, 0x02, 0x00, 0x01, 0x5f, 0x01, 0xf6, - 0x0d, 0x00, 0x01, 0x1d, 0x01, 0xa0, 0x02, 0x00, 0x01, 0x04, 0x01, 0xe6, - 0x0d, 0x00, 0x01, 0x01, 0x01, 0x60, 0x03, 0x00, 0x01, 0x24, 0xff, 0x00, - - /* 18 RIGHT_DBL_QUOTE */ - 0xff, 0x00, 0x46, 0x00, 0x01, 0x20, 0x03, 0x00, 0x01, 0x20, 0x0d, 0x00, - 0x01, 0x01, 0x01, 0xe3, 0x03, 0x00, 0x01, 0x5d, 0x01, 0x10, 0x0c, 0x00, - 0x01, 0x01, 0x01, 0xff, 0x01, 0x50, 0x02, 0x00, 0x01, 0x5f, 0x01, 0xe2, - 0x0c, 0x00, 0x01, 0x01, 0x01, 0xff, 0x01, 0xf6, 0x02, 0x00, 0x01, 0x5f, - 0x01, 0xfe, 0x01, 0x30, 0x0c, 0x00, 0x01, 0xbf, 0x01, 0xff, 0x01, 0x80, - 0x01, 0x00, 0x01, 0x2e, 0x01, 0xff, 0x01, 0xf5, 0x0c, 0x00, 0x01, 0x0a, - 0x01, 0xff, 0x01, 0xfa, 0x01, 0x00, 0x01, 0x01, 0x01, 0xcf, 0x01, 0xff, - 0x01, 0x60, 0x0c, 0x00, 0x01, 0x8f, 0x01, 0xff, 0x01, 0xb0, 0x01, 0x00, - 0x01, 0x0b, 0x01, 0xff, 0x01, 0xf9, 0x0c, 0x00, 0x01, 0x06, 0x01, 0xff, - 0x01, 0xfc, 0x01, 0x10, 0x01, 0x00, 0x01, 0xaf, 0x01, 0xff, 0x01, 0xa0, - 0x0c, 0x00, 0x01, 0x5f, 0x01, 0xff, 0x01, 0xd1, 0x01, 0x00, 0x01, 0x08, - 0x01, 0xff, 0x01, 0xfb, 0x0c, 0x00, 0x01, 0x05, 0x01, 0xff, 0x01, 0xf5, - 0x02, 0x00, 0x01, 0x9f, 0x01, 0xff, 0x01, 0x10, 0x0b, 0x00, 0x01, 0x2d, - 0x01, 0xff, 0x01, 0xf3, 0x01, 0x00, 0x01, 0x04, 0x01, 0xff, 0x01, 0xfe, - 0x01, 0x10, 0x0a, 0x00, 0x01, 0x03, 0x01, 0xef, 0x01, 0xff, 0x01, 0x40, - 0x01, 0x00, 0x01, 0x5f, 0x01, 0xff, 0x01, 0xd2, 0x0b, 0x00, 0x01, 0x4f, - 0x01, 0xff, 0x01, 0xe3, 0x01, 0x00, 0x01, 0x06, 0x01, 0xff, 0x01, 0xfc, - 0x01, 0x10, 0x0a, 0x00, 0x01, 0x05, 0x01, 0xff, 0x01, 0xfd, 0x01, 0x10, - 0x01, 0x00, 0x01, 0x9f, 0x01, 0xff, 0x01, 0xb0, 0x0b, 0x00, 0x01, 0x6f, - 0x01, 0xff, 0x01, 0xc1, 0x01, 0x00, 0x01, 0x0a, 0x01, 0xff, 0x01, 0xf9, - 0x0b, 0x00, 0x01, 0x01, 0x01, 0xff, 0x01, 0xfa, 0x02, 0x00, 0x01, 0x5f, - 0x01, 0xff, 0x01, 0x70, 0x0b, 0x00, 0x01, 0x01, 0x01, 0xff, 0x01, 0x90, - 0x02, 0x00, 0x01, 0x5f, 0x01, 0xf6, 0x0c, 0x00, 0x01, 0x01, 0x01, 0xf8, - 0x03, 0x00, 0x01, 0x5f, 0x01, 0x40, 0x0c, 0x00, 0x01, 0x01, 0x01, 0x50, - 0x03, 0x00, 0x01, 0x43, 0xff, 0x00, 0x04, 0x00, - - /* 19 INV_EXCLAMATION */ - 0xff, 0x00, 0x34, 0x00, 0x01, 0xad, 0x01, 0xdd, 0x01, 0x40, 0x10, 0x00, - 0x01, 0xcf, 0x01, 0xff, 0x01, 0x50, 0x10, 0x00, 0x01, 0xcf, 0x01, 0xff, - 0x01, 0x50, 0x10, 0x00, 0x01, 0xcf, 0x01, 0xff, 0x01, 0x50, 0x10, 0x00, - 0x01, 0xcf, 0x01, 0xff, 0x01, 0x50, 0x10, 0x00, 0x01, 0x34, 0x01, 0x44, - 0x01, 0x10, 0x49, 0x00, 0x01, 0x02, 0x01, 0x22, 0x11, 0x00, 0x01, 0x6f, - 0x01, 0xff, 0x11, 0x00, 0x01, 0x7f, 0x01, 0xff, 0x11, 0x00, 0x01, 0x7f, - 0x01, 0xff, 0x01, 0x10, 0x10, 0x00, 0x01, 0x8f, 0x01, 0xff, 0x01, 0x20, - 0x10, 0x00, 0x01, 0x9f, 0x01, 0xff, 0x01, 0x30, 0x10, 0x00, 0x01, 0xaf, - 0x01, 0xff, 0x01, 0x30, 0x10, 0x00, 0x01, 0xbf, 0x01, 0xff, 0x01, 0x40, - 0x10, 0x00, 0x01, 0xcf, 0x01, 0xff, 0x01, 0x50, 0x10, 0x00, 0x01, 0xcf, - 0x01, 0xff, 0x01, 0x50, 0x10, 0x00, 0x01, 0xcf, 0x01, 0xff, 0x01, 0x50, - 0x10, 0x00, 0x01, 0xcf, 0x01, 0xff, 0x01, 0x50, 0x10, 0x00, 0x01, 0xcf, - 0x01, 0xff, 0x01, 0x50, 0x10, 0x00, 0x01, 0xcf, 0x01, 0xff, 0x01, 0x50, - 0x10, 0x00, 0x01, 0xcf, 0x01, 0xff, 0x01, 0x50, 0x10, 0x00, 0x01, 0xcf, - 0x01, 0xff, 0x01, 0x50, 0x10, 0x00, 0x01, 0xcf, 0x01, 0xff, 0x01, 0x50, - 0x10, 0x00, 0x01, 0xcf, 0x01, 0xff, 0x01, 0x50, 0x10, 0x00, 0x01, 0xcf, - 0x01, 0xff, 0x01, 0x50, 0x10, 0x00, 0x01, 0xcf, 0x01, 0xff, 0x01, 0x50, - 0x10, 0x00, 0x01, 0xcf, 0x01, 0xff, 0x01, 0x50, 0x10, 0x00, 0x01, 0x34, - 0x01, 0x44, 0x01, 0x10, 0x33, 0x00, - - /* 20 INV_QUESTION */ - 0xff, 0x00, 0x36, 0x00, 0x02, 0xdd, 0x11, 0x00, 0x02, 0xff, 0x11, 0x00, - 0x02, 0xff, 0x11, 0x00, 0x02, 0xff, 0x11, 0x00, 0x02, 0xff, 0x11, 0x00, - 0x02, 0x44, 0x37, 0x00, 0x01, 0xbc, 0x01, 0xcb, 0x11, 0x00, 0x01, 0xef, - 0x01, 0xfe, 0x11, 0x00, 0x01, 0xef, 0x01, 0xfe, 0x11, 0x00, 0x01, 0xef, - 0x01, 0xfe, 0x11, 0x00, 0x01, 0xff, 0x01, 0xfd, 0x10, 0x00, 0x01, 0x03, - 0x01, 0xff, 0x01, 0xfb, 0x10, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xf6, - 0x10, 0x00, 0x01, 0xaf, 0x01, 0xff, 0x01, 0xd0, 0x0f, 0x00, 0x01, 0x0a, - 0x02, 0xff, 0x01, 0x30, 0x0f, 0x00, 0x01, 0xaf, 0x01, 0xff, 0x01, 0xf4, - 0x0f, 0x00, 0x01, 0x09, 0x02, 0xff, 0x01, 0x40, 0x0f, 0x00, 0x01, 0x7f, - 0x01, 0xff, 0x01, 0xf4, 0x0f, 0x00, 0x01, 0x03, 0x02, 0xff, 0x01, 0x40, - 0x0f, 0x00, 0x01, 0x0a, 0x01, 0xff, 0x01, 0xf8, 0x10, 0x00, 0x01, 0x0f, - 0x01, 0xff, 0x01, 0xf2, 0x10, 0x00, 0x01, 0x1f, 0x01, 0xff, 0x01, 0xf0, - 0x10, 0x00, 0x01, 0x0f, 0x01, 0xff, 0x01, 0xf2, 0x10, 0x00, 0x01, 0x0e, - 0x01, 0xff, 0x01, 0xf8, 0x04, 0x00, 0x01, 0x05, 0x01, 0xd0, 0x0a, 0x00, - 0x01, 0x08, 0x02, 0xff, 0x01, 0x70, 0x02, 0x00, 0x01, 0x05, 0x01, 0xcf, - 0x01, 0xf0, 0x0a, 0x00, 0x01, 0x01, 0x01, 0xef, 0x01, 0xff, 0x01, 0xfe, - 0x01, 0x98, 0x01, 0x8b, 0x02, 0xff, 0x01, 0xf0, 0x0b, 0x00, 0x01, 0x3f, - 0x06, 0xff, 0x01, 0xc0, 0x0b, 0x00, 0x01, 0x02, 0x01, 0xcf, 0x04, 0xff, - 0x01, 0xc5, 0x0d, 0x00, 0x01, 0x03, 0x01, 0x8b, 0x01, 0xcc, 0x01, 0xb9, - 0x01, 0x62, 0x31, 0x00, -#endif // TOUCH_UI_UTF8_PUNCTUATION - -#if ENABLED(TOUCH_UI_UTF8_CURRENCY) - /* 21 CENT_SIGN */ - 0xb1, 0x00, 0x01, 0x01, 0x01, 0x32, 0x11, 0x00, 0x01, 0x05, 0x01, 0xfb, - 0x11, 0x00, 0x01, 0x05, 0x01, 0xfb, 0x11, 0x00, 0x01, 0x05, 0x01, 0xfb, - 0x11, 0x00, 0x01, 0x05, 0x01, 0xfc, 0x11, 0x00, 0x01, 0x05, 0x01, 0xfc, - 0x11, 0x00, 0x01, 0x39, 0x01, 0xfd, 0x01, 0x42, 0x0e, 0x00, 0x01, 0x05, - 0x01, 0xbf, 0x03, 0xff, 0x01, 0xfb, 0x01, 0x50, 0x0b, 0x00, 0x01, 0x03, - 0x01, 0xcf, 0x05, 0xff, 0x01, 0xf6, 0x0b, 0x00, 0x01, 0x4f, 0x02, 0xff, - 0x02, 0xfe, 0x01, 0xce, 0x01, 0xff, 0x01, 0xf6, 0x0a, 0x00, 0x01, 0x02, - 0x02, 0xff, 0x01, 0xe6, 0x01, 0x05, 0x01, 0xfc, 0x01, 0x00, 0x01, 0x38, - 0x01, 0xe6, 0x0a, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xfd, 0x01, 0x10, - 0x01, 0x05, 0x01, 0xfc, 0x02, 0x00, 0x01, 0x02, 0x0a, 0x00, 0x01, 0x5f, - 0x01, 0xff, 0x01, 0xe1, 0x01, 0x00, 0x01, 0x05, 0x01, 0xfc, 0x0d, 0x00, - 0x01, 0xcf, 0x01, 0xff, 0x01, 0x60, 0x01, 0x00, 0x01, 0x05, 0x01, 0xfc, - 0x0d, 0x00, 0x02, 0xff, 0x02, 0x00, 0x01, 0x05, 0x01, 0xfc, 0x0c, 0x00, - 0x01, 0x04, 0x01, 0xff, 0x01, 0xfb, 0x02, 0x00, 0x01, 0x05, 0x01, 0xfc, - 0x0c, 0x00, 0x01, 0x06, 0x01, 0xff, 0x01, 0xf8, 0x02, 0x00, 0x01, 0x05, - 0x01, 0xfc, 0x0c, 0x00, 0x01, 0x07, 0x01, 0xff, 0x01, 0xf7, 0x02, 0x00, - 0x01, 0x05, 0x01, 0xfb, 0x0c, 0x00, 0x01, 0x08, 0x01, 0xff, 0x01, 0xf6, - 0x02, 0x00, 0x01, 0x05, 0x01, 0xfc, 0x0c, 0x00, 0x01, 0x07, 0x01, 0xff, - 0x01, 0xf7, 0x02, 0x00, 0x01, 0x05, 0x01, 0xfb, 0x0c, 0x00, 0x01, 0x06, - 0x01, 0xff, 0x01, 0xf9, 0x02, 0x00, 0x01, 0x05, 0x01, 0xfb, 0x0c, 0x00, - 0x01, 0x03, 0x01, 0xff, 0x01, 0xfc, 0x02, 0x00, 0x01, 0x05, 0x01, 0xfb, - 0x0d, 0x00, 0x02, 0xff, 0x01, 0x10, 0x01, 0x00, 0x01, 0x05, 0x01, 0xfb, - 0x0d, 0x00, 0x01, 0xaf, 0x01, 0xff, 0x01, 0x80, 0x01, 0x00, 0x01, 0x05, - 0x01, 0xfb, 0x0d, 0x00, 0x01, 0x4f, 0x01, 0xff, 0x01, 0xf3, 0x01, 0x00, - 0x01, 0x05, 0x01, 0xfb, 0x0d, 0x00, 0x01, 0x0b, 0x01, 0xff, 0x01, 0xfe, - 0x01, 0x30, 0x01, 0x05, 0x01, 0xfb, 0x02, 0x00, 0x01, 0x33, 0x0a, 0x00, - 0x01, 0x01, 0x01, 0xef, 0x01, 0xff, 0x01, 0xf9, 0x01, 0x35, 0x01, 0xfb, - 0x01, 0x02, 0x01, 0x6c, 0x01, 0xf6, 0x0b, 0x00, 0x01, 0x2d, 0x06, 0xff, - 0x01, 0xf6, 0x0b, 0x00, 0x01, 0x01, 0x01, 0x9f, 0x05, 0xff, 0x01, 0xf5, - 0x0c, 0x00, 0x01, 0x02, 0x01, 0x8d, 0x03, 0xff, 0x01, 0xc7, 0x01, 0x20, - 0x0e, 0x00, 0x01, 0x06, 0x01, 0xfc, 0x01, 0x20, 0x10, 0x00, 0x01, 0x05, - 0x01, 0xfb, 0x11, 0x00, 0x01, 0x05, 0x01, 0xfb, 0x11, 0x00, 0x01, 0x05, - 0x01, 0xfb, 0x11, 0x00, 0x01, 0x05, 0x01, 0xfb, 0x11, 0x00, 0x01, 0x05, - 0x01, 0xfb, 0x57, 0x00, - - /* 22 POUND_SIGN */ - 0x9e, 0x00, 0x01, 0x6b, 0x01, 0xdf, 0x01, 0xfd, 0x01, 0xc9, 0x01, 0x40, - 0x0d, 0x00, 0x01, 0x6e, 0x05, 0xff, 0x01, 0x30, 0x0b, 0x00, 0x01, 0x07, - 0x06, 0xff, 0x01, 0x30, 0x0b, 0x00, 0x01, 0x3f, 0x01, 0xff, 0x01, 0xfe, - 0x01, 0x85, 0x01, 0x34, 0x01, 0x7b, 0x01, 0xff, 0x01, 0x30, 0x0b, 0x00, - 0x01, 0xaf, 0x01, 0xff, 0x01, 0xc1, 0x03, 0x00, 0x01, 0x18, 0x01, 0x30, - 0x0a, 0x00, 0x01, 0x01, 0x02, 0xff, 0x01, 0x30, 0x0f, 0x00, 0x01, 0x04, - 0x01, 0xff, 0x01, 0xfd, 0x10, 0x00, 0x01, 0x07, 0x01, 0xff, 0x01, 0xfa, - 0x10, 0x00, 0x01, 0x08, 0x01, 0xff, 0x01, 0xf8, 0x10, 0x00, 0x01, 0x09, - 0x01, 0xff, 0x01, 0xf7, 0x10, 0x00, 0x01, 0x0a, 0x01, 0xff, 0x01, 0xf6, - 0x10, 0x00, 0x01, 0x0a, 0x01, 0xff, 0x01, 0xf6, 0x10, 0x00, 0x01, 0x0a, - 0x01, 0xff, 0x01, 0xf6, 0x10, 0x00, 0x01, 0x0a, 0x01, 0xff, 0x01, 0xf6, - 0x10, 0x00, 0x01, 0x0a, 0x01, 0xff, 0x01, 0xf6, 0x0e, 0x00, 0x01, 0x0a, - 0x07, 0xff, 0x01, 0xf4, 0x0a, 0x00, 0x01, 0x0a, 0x07, 0xff, 0x01, 0xf4, - 0x0a, 0x00, 0x01, 0x08, 0x01, 0xdd, 0x01, 0xdf, 0x01, 0xff, 0x01, 0xfe, - 0x03, 0xdd, 0x01, 0xd4, 0x0c, 0x00, 0x01, 0x0a, 0x01, 0xff, 0x01, 0xf6, - 0x10, 0x00, 0x01, 0x0a, 0x01, 0xff, 0x01, 0xf6, 0x10, 0x00, 0x01, 0x0a, - 0x01, 0xff, 0x01, 0xf6, 0x10, 0x00, 0x01, 0x0a, 0x01, 0xff, 0x01, 0xf6, - 0x10, 0x00, 0x01, 0x0a, 0x01, 0xff, 0x01, 0xf6, 0x10, 0x00, 0x01, 0x0a, - 0x01, 0xff, 0x01, 0xf6, 0x10, 0x00, 0x01, 0x0a, 0x01, 0xff, 0x01, 0xf6, - 0x10, 0x00, 0x01, 0x0a, 0x01, 0xff, 0x01, 0xf6, 0x10, 0x00, 0x01, 0x0a, - 0x01, 0xff, 0x01, 0xf6, 0x0e, 0x00, 0x01, 0x4b, 0x01, 0xbb, 0x01, 0xbe, - 0x01, 0xff, 0x01, 0xfd, 0x05, 0xbb, 0x01, 0x70, 0x08, 0x00, 0x01, 0x6f, - 0x09, 0xff, 0x01, 0xa0, 0x08, 0x00, 0x01, 0x6f, 0x09, 0xff, 0x01, 0xa0, - 0x08, 0x00, 0x01, 0x4a, 0x09, 0xaa, 0x01, 0x60, 0xc5, 0x00, - - /* 23 CURRENCY_SIGN */ - 0xff, 0x00, 0x0d, 0x00, 0x01, 0x30, 0x07, 0x00, 0x01, 0x01, 0x01, 0x40, - 0x08, 0x00, 0x01, 0x0b, 0x01, 0xf5, 0x07, 0x00, 0x01, 0x1d, 0x01, 0xf4, - 0x08, 0x00, 0x01, 0xbf, 0x01, 0xff, 0x01, 0x40, 0x05, 0x00, 0x01, 0x01, - 0x01, 0xdf, 0x01, 0xff, 0x01, 0x30, 0x07, 0x00, 0x01, 0x5f, 0x01, 0xff, - 0x01, 0xf4, 0x01, 0x00, 0x01, 0x6b, 0x01, 0xdd, 0x01, 0xc8, 0x01, 0x20, - 0x01, 0x1d, 0x01, 0xff, 0x01, 0xfa, 0x08, 0x00, 0x01, 0x05, 0x02, 0xff, - 0x01, 0x8e, 0x03, 0xff, 0x01, 0xfa, 0x01, 0xdf, 0x01, 0xff, 0x01, 0xa0, - 0x09, 0x00, 0x01, 0x5f, 0x07, 0xff, 0x01, 0xfa, 0x0a, 0x00, 0x01, 0x05, - 0x02, 0xff, 0x01, 0xe9, 0x01, 0x55, 0x01, 0x7c, 0x02, 0xff, 0x01, 0xa0, - 0x0a, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0xfb, 0x01, 0x10, 0x02, 0x00, - 0x01, 0x6f, 0x01, 0xff, 0x01, 0xa0, 0x0a, 0x00, 0x01, 0x0b, 0x01, 0xff, - 0x01, 0xc0, 0x03, 0x00, 0x01, 0x07, 0x01, 0xff, 0x01, 0xf2, 0x0a, 0x00, - 0x01, 0x1f, 0x01, 0xff, 0x01, 0x30, 0x04, 0x00, 0x01, 0xdf, 0x01, 0xf7, - 0x0a, 0x00, 0x01, 0x4f, 0x01, 0xfd, 0x05, 0x00, 0x01, 0x8f, 0x01, 0xfa, - 0x0a, 0x00, 0x01, 0x6f, 0x01, 0xfc, 0x05, 0x00, 0x01, 0x6f, 0x01, 0xfc, - 0x0a, 0x00, 0x01, 0x5f, 0x01, 0xfc, 0x05, 0x00, 0x01, 0x7f, 0x01, 0xfb, - 0x0a, 0x00, 0x01, 0x3f, 0x01, 0xff, 0x01, 0x10, 0x04, 0x00, 0x01, 0xbf, - 0x01, 0xf8, 0x0a, 0x00, 0x01, 0x0e, 0x01, 0xff, 0x01, 0x80, 0x03, 0x00, - 0x01, 0x03, 0x01, 0xff, 0x01, 0xf3, 0x0a, 0x00, 0x01, 0x07, 0x01, 0xff, - 0x01, 0xf5, 0x03, 0x00, 0x01, 0x1d, 0x01, 0xff, 0x01, 0xc0, 0x0a, 0x00, - 0x01, 0x01, 0x02, 0xff, 0x01, 0x92, 0x01, 0x00, 0x01, 0x16, 0x01, 0xef, - 0x01, 0xff, 0x01, 0x60, 0x0a, 0x00, 0x01, 0x1d, 0x03, 0xff, 0x01, 0xfe, - 0x03, 0xff, 0x01, 0xf4, 0x09, 0x00, 0x01, 0x01, 0x01, 0xdf, 0x05, 0xff, - 0x01, 0xfe, 0x02, 0xff, 0x01, 0x40, 0x08, 0x00, 0x01, 0x1d, 0x01, 0xff, - 0x01, 0xfa, 0x01, 0x06, 0x01, 0xdf, 0x01, 0xff, 0x01, 0xfe, 0x01, 0x81, - 0x01, 0x5f, 0x01, 0xff, 0x01, 0xf4, 0x08, 0x00, 0x01, 0xcf, 0x01, 0xff, - 0x01, 0xa0, 0x01, 0x00, 0x01, 0x01, 0x01, 0x44, 0x01, 0x20, 0x01, 0x00, - 0x01, 0x05, 0x02, 0xff, 0x01, 0x20, 0x07, 0x00, 0x01, 0x4f, 0x01, 0xfa, - 0x07, 0x00, 0x01, 0x4f, 0x01, 0xf8, 0x08, 0x00, 0x01, 0x05, 0x01, 0xa0, - 0x07, 0x00, 0x01, 0x05, 0x01, 0x80, 0xeb, 0x00, - - /* 24 YEN_SIGN */ - 0x98, 0x00, 0x01, 0x01, 0x01, 0x88, 0x01, 0x85, 0x07, 0x00, 0x01, 0x38, - 0x01, 0x88, 0x01, 0x40, 0x07, 0x00, 0x01, 0xcf, 0x01, 0xff, 0x01, 0x10, - 0x06, 0x00, 0x01, 0xcf, 0x01, 0xff, 0x01, 0x10, 0x07, 0x00, 0x01, 0x3f, - 0x01, 0xff, 0x01, 0x90, 0x05, 0x00, 0x01, 0x05, 0x01, 0xff, 0x01, 0xf8, - 0x08, 0x00, 0x01, 0x0b, 0x01, 0xff, 0x01, 0xf2, 0x05, 0x00, 0x01, 0x0d, - 0x01, 0xff, 0x01, 0xe0, 0x08, 0x00, 0x01, 0x02, 0x01, 0xff, 0x01, 0xfa, - 0x05, 0x00, 0x01, 0x6f, 0x01, 0xff, 0x01, 0x60, 0x09, 0x00, 0x01, 0xaf, - 0x01, 0xff, 0x01, 0x30, 0x04, 0x00, 0x01, 0xef, 0x01, 0xfd, 0x0a, 0x00, - 0x01, 0x1f, 0x01, 0xff, 0x01, 0xc0, 0x03, 0x00, 0x01, 0x07, 0x01, 0xff, - 0x01, 0xf5, 0x0a, 0x00, 0x01, 0x08, 0x01, 0xff, 0x01, 0xf4, 0x03, 0x00, - 0x01, 0x1f, 0x01, 0xff, 0x01, 0xc0, 0x0a, 0x00, 0x01, 0x01, 0x01, 0xef, - 0x01, 0xfd, 0x03, 0x00, 0x01, 0x9f, 0x01, 0xff, 0x01, 0x40, 0x0b, 0x00, - 0x01, 0x7f, 0x01, 0xff, 0x01, 0x50, 0x01, 0x00, 0x01, 0x02, 0x01, 0xff, - 0x01, 0xfb, 0x0c, 0x00, 0x01, 0x0e, 0x01, 0xff, 0x01, 0xe0, 0x01, 0x00, - 0x01, 0x0a, 0x01, 0xff, 0x01, 0xf3, 0x0c, 0x00, 0x01, 0x06, 0x01, 0xff, - 0x01, 0xf7, 0x01, 0x00, 0x01, 0x2f, 0x01, 0xff, 0x01, 0xa0, 0x0a, 0x00, - 0x01, 0x2a, 0x02, 0xaa, 0x01, 0xff, 0x01, 0xfe, 0x01, 0x10, 0x01, 0xbf, - 0x01, 0xff, 0x01, 0xca, 0x01, 0xaa, 0x01, 0xa5, 0x08, 0x00, 0x01, 0x4f, - 0x04, 0xff, 0x01, 0x83, 0x04, 0xff, 0x01, 0xf8, 0x08, 0x00, 0x01, 0x3c, - 0x02, 0xcc, 0x01, 0xce, 0x01, 0xff, 0x01, 0xfd, 0x01, 0xff, 0x01, 0xfc, - 0x02, 0xcc, 0x01, 0xc6, 0x0b, 0x00, 0x01, 0x03, 0x03, 0xff, 0x01, 0x70, - 0x0f, 0x00, 0x01, 0xaf, 0x01, 0xff, 0x01, 0xfe, 0x10, 0x00, 0x01, 0x2f, - 0x01, 0xff, 0x01, 0xf5, 0x0c, 0x00, 0x01, 0x01, 0x03, 0x11, 0x01, 0x1e, - 0x01, 0xff, 0x01, 0xf3, 0x03, 0x11, 0x01, 0x10, 0x08, 0x00, 0x01, 0x4f, - 0x09, 0xff, 0x01, 0xf8, 0x08, 0x00, 0x01, 0x4f, 0x09, 0xff, 0x01, 0xf8, - 0x08, 0x00, 0x01, 0x27, 0x03, 0x77, 0x01, 0x7e, 0x01, 0xff, 0x01, 0xf8, - 0x03, 0x77, 0x01, 0x73, 0x0c, 0x00, 0x01, 0x0e, 0x01, 0xff, 0x01, 0xf2, - 0x10, 0x00, 0x01, 0x0e, 0x01, 0xff, 0x01, 0xf2, 0x10, 0x00, 0x01, 0x0e, - 0x01, 0xff, 0x01, 0xf2, 0x10, 0x00, 0x01, 0x0e, 0x01, 0xff, 0x01, 0xf2, - 0x10, 0x00, 0x01, 0x0e, 0x01, 0xff, 0x01, 0xf2, 0x10, 0x00, 0x01, 0x0e, - 0x01, 0xff, 0x01, 0xf2, 0x10, 0x00, 0x01, 0x0e, 0x01, 0xff, 0x01, 0xf2, - 0x10, 0x00, 0x01, 0x0e, 0x01, 0xff, 0x01, 0xf2, 0x10, 0x00, 0x01, 0x08, - 0x01, 0x99, 0x01, 0x91, 0xc9, 0x00, -#endif // TOUCH_UI_UTF8_CURRENCY - -#if ENABLED(TOUCH_UI_UTF8_SUPERSCRIPTS) - /* 25 SUPERSCRIPT_ONE */ - 0x99, 0x00, 0x01, 0x01, 0x01, 0x36, 0x01, 0x9b, 0x01, 0xbb, 0x01, 0x20, - 0x0e, 0x00, 0x01, 0x3f, 0x03, 0xff, 0x01, 0x20, 0x0e, 0x00, 0x01, 0x3f, - 0x01, 0xfe, 0x01, 0xbe, 0x01, 0xff, 0x01, 0x20, 0x0e, 0x00, 0x01, 0x14, - 0x01, 0x10, 0x01, 0x0b, 0x01, 0xff, 0x01, 0x20, 0x10, 0x00, 0x01, 0x0b, - 0x01, 0xff, 0x01, 0x20, 0x10, 0x00, 0x01, 0x0b, 0x01, 0xff, 0x01, 0x20, - 0x10, 0x00, 0x01, 0x0b, 0x01, 0xff, 0x01, 0x20, 0x10, 0x00, 0x01, 0x0b, - 0x01, 0xff, 0x01, 0x20, 0x10, 0x00, 0x01, 0x0b, 0x01, 0xff, 0x01, 0x20, - 0x10, 0x00, 0x01, 0x0b, 0x01, 0xff, 0x01, 0x20, 0x10, 0x00, 0x01, 0x0b, - 0x01, 0xff, 0x01, 0x20, 0x10, 0x00, 0x01, 0x0b, 0x01, 0xff, 0x01, 0x20, - 0x10, 0x00, 0x01, 0x0b, 0x01, 0xff, 0x01, 0x20, 0x10, 0x00, 0x01, 0x0b, - 0x01, 0xff, 0x01, 0x20, 0x0f, 0x00, 0x01, 0x11, 0x01, 0x1c, 0x01, 0xff, - 0x01, 0x31, 0x01, 0x11, 0x0d, 0x00, 0x01, 0x0d, 0x05, 0xff, 0x01, 0x40, - 0x0c, 0x00, 0x01, 0x0d, 0x05, 0xff, 0x01, 0x40, 0x0c, 0x00, 0x01, 0x01, - 0x05, 0x22, 0xff, 0x00, 0xc2, 0x00, - - /* 26 SUPERSCRIPT_TWO */ - 0x88, 0x00, 0x01, 0x01, 0x10, 0x00, 0x01, 0x16, 0x01, 0xae, 0x01, 0xff, - 0x01, 0xfd, 0x01, 0x92, 0x0e, 0x00, 0x05, 0xff, 0x01, 0x60, 0x0d, 0x00, - 0x01, 0xfe, 0x01, 0x84, 0x01, 0x22, 0x01, 0x5c, 0x01, 0xff, 0x01, 0xf3, - 0x0d, 0x00, 0x01, 0x50, 0x03, 0x00, 0x01, 0xcf, 0x01, 0xfa, 0x11, 0x00, - 0x01, 0x5f, 0x01, 0xfc, 0x11, 0x00, 0x01, 0x5f, 0x01, 0xfb, 0x11, 0x00, - 0x01, 0xcf, 0x01, 0xf4, 0x10, 0x00, 0x01, 0x08, 0x01, 0xff, 0x01, 0xa0, - 0x10, 0x00, 0x01, 0x6f, 0x01, 0xfe, 0x01, 0x10, 0x0f, 0x00, 0x01, 0x05, - 0x01, 0xff, 0x01, 0xe2, 0x10, 0x00, 0x01, 0x5f, 0x01, 0xff, 0x01, 0x30, - 0x0f, 0x00, 0x01, 0x05, 0x01, 0xff, 0x01, 0xe3, 0x10, 0x00, 0x01, 0x6f, - 0x01, 0xfe, 0x01, 0x20, 0x0f, 0x00, 0x01, 0x08, 0x01, 0xff, 0x01, 0xd1, - 0x10, 0x00, 0x01, 0xaf, 0x01, 0xfd, 0x01, 0x43, 0x03, 0x33, 0x0c, 0x00, - 0x01, 0x01, 0x06, 0xff, 0x0c, 0x00, 0x01, 0x01, 0x06, 0xff, 0x0d, 0x00, - 0x06, 0x22, 0xff, 0x00, 0xc2, 0x00, - - /* 27 SUPERSCRIPT_THREE */ - 0x88, 0x00, 0x01, 0x01, 0x01, 0x10, 0x0f, 0x00, 0x01, 0x39, 0x01, 0xce, - 0x02, 0xff, 0x01, 0xb5, 0x0e, 0x00, 0x01, 0x7f, 0x04, 0xff, 0x01, 0xb0, - 0x0d, 0x00, 0x01, 0x6b, 0x01, 0x73, 0x01, 0x22, 0x01, 0x38, 0x01, 0xff, - 0x01, 0xf9, 0x11, 0x00, 0x01, 0x5f, 0x01, 0xff, 0x11, 0x00, 0x01, 0x0f, - 0x01, 0xff, 0x11, 0x00, 0x01, 0x4f, 0x01, 0xfc, 0x10, 0x00, 0x01, 0x27, - 0x01, 0xff, 0x01, 0xf3, 0x0e, 0x00, 0x01, 0x0c, 0x02, 0xff, 0x01, 0xfa, - 0x01, 0x20, 0x0e, 0x00, 0x01, 0x0c, 0x02, 0xff, 0x01, 0xfb, 0x01, 0x40, - 0x0e, 0x00, 0x01, 0x01, 0x01, 0x23, 0x01, 0x49, 0x01, 0xff, 0x01, 0xf6, - 0x11, 0x00, 0x01, 0x3f, 0x01, 0xff, 0x01, 0x10, 0x10, 0x00, 0x01, 0x0b, - 0x01, 0xff, 0x01, 0x50, 0x10, 0x00, 0x01, 0x0a, 0x01, 0xff, 0x01, 0x60, - 0x10, 0x00, 0x01, 0x1e, 0x01, 0xff, 0x01, 0x40, 0x0c, 0x00, 0x01, 0xa4, - 0x02, 0x00, 0x01, 0x05, 0x01, 0xdf, 0x01, 0xfd, 0x0d, 0x00, 0x02, 0xff, - 0x01, 0xde, 0x02, 0xff, 0x01, 0xe3, 0x0d, 0x00, 0x01, 0xae, 0x03, 0xff, - 0x01, 0xe9, 0x01, 0x10, 0x0e, 0x00, 0x01, 0x24, 0x01, 0x55, 0x01, 0x52, - 0xff, 0x00, 0xc4, 0x00, -#endif // TOUCH_UI_UTF8_SUPERSCRIPTS - -#if ENABLED(TOUCH_UI_UTF8_ORDINALS) - /* 28 MASCULINE_ORDINAL */ - 0x89, 0x00, 0x01, 0x01, 0x01, 0x10, 0x0f, 0x00, 0x01, 0x01, 0x01, 0x8d, - 0x02, 0xff, 0x01, 0xb4, 0x0e, 0x00, 0x01, 0x4f, 0x04, 0xff, 0x01, 0xa0, - 0x0c, 0x00, 0x01, 0x04, 0x01, 0xff, 0x01, 0xfc, 0x01, 0x63, 0x01, 0x48, - 0x01, 0xff, 0x01, 0xfb, 0x0c, 0x00, 0x01, 0x0e, 0x01, 0xff, 0x01, 0xa0, - 0x02, 0x00, 0x01, 0x3f, 0x01, 0xff, 0x01, 0x60, 0x0b, 0x00, 0x01, 0x6f, - 0x01, 0xfe, 0x03, 0x00, 0x01, 0x07, 0x01, 0xff, 0x01, 0xd0, 0x0b, 0x00, - 0x01, 0xbf, 0x01, 0xf7, 0x04, 0x00, 0x01, 0xff, 0x01, 0xf2, 0x0b, 0x00, - 0x01, 0xef, 0x01, 0xf3, 0x04, 0x00, 0x01, 0xcf, 0x01, 0xf6, 0x0b, 0x00, - 0x01, 0xff, 0x01, 0xf1, 0x04, 0x00, 0x01, 0xaf, 0x01, 0xf7, 0x0b, 0x00, - 0x01, 0xff, 0x01, 0xf1, 0x04, 0x00, 0x01, 0xaf, 0x01, 0xf7, 0x0b, 0x00, - 0x01, 0xff, 0x01, 0xf2, 0x04, 0x00, 0x01, 0xbf, 0x01, 0xf6, 0x0b, 0x00, - 0x01, 0xcf, 0x01, 0xf6, 0x04, 0x00, 0x01, 0xef, 0x01, 0xf4, 0x0b, 0x00, - 0x01, 0x8f, 0x01, 0xfc, 0x03, 0x00, 0x01, 0x04, 0x01, 0xff, 0x01, 0xf0, - 0x0b, 0x00, 0x01, 0x2f, 0x01, 0xff, 0x01, 0x60, 0x02, 0x00, 0x01, 0x1d, - 0x01, 0xff, 0x01, 0x90, 0x0b, 0x00, 0x01, 0x08, 0x01, 0xff, 0x01, 0xf8, - 0x01, 0x10, 0x01, 0x04, 0x01, 0xdf, 0x01, 0xfe, 0x01, 0x10, 0x0c, 0x00, - 0x01, 0xaf, 0x04, 0xff, 0x01, 0xe3, 0x0d, 0x00, 0x01, 0x05, 0x01, 0xdf, - 0x02, 0xff, 0x01, 0xfa, 0x01, 0x10, 0x0e, 0x00, 0x01, 0x02, 0x01, 0x56, - 0x01, 0x64, 0x21, 0x00, 0x01, 0x16, 0x06, 0x66, 0x01, 0x40, 0x0b, 0x00, - 0x01, 0x3f, 0x06, 0xff, 0x01, 0xb0, 0x0b, 0x00, 0x01, 0x3f, 0x06, 0xff, - 0x01, 0xb0, 0x0b, 0x00, 0x01, 0x01, 0x06, 0x11, 0xff, 0x00, 0x75, 0x00, - - /* 29 FEMININE_ORDINAL */ - 0x89, 0x00, 0x01, 0x12, 0x01, 0x10, 0x0f, 0x00, 0x01, 0x49, 0x01, 0xdf, - 0x02, 0xff, 0x01, 0xb4, 0x0d, 0x00, 0x01, 0x07, 0x05, 0xff, 0x01, 0xa0, - 0x0c, 0x00, 0x01, 0x07, 0x01, 0xfc, 0x01, 0x74, 0x01, 0x33, 0x01, 0x59, - 0x01, 0xff, 0x01, 0xf8, 0x0c, 0x00, 0x01, 0x03, 0x01, 0x20, 0x03, 0x00, - 0x01, 0x3f, 0x01, 0xff, 0x01, 0x10, 0x10, 0x00, 0x01, 0x09, 0x01, 0xff, - 0x01, 0x50, 0x0e, 0x00, 0x01, 0x01, 0x01, 0x11, 0x01, 0x16, 0x01, 0xff, - 0x01, 0x80, 0x0c, 0x00, 0x01, 0x05, 0x01, 0xae, 0x04, 0xff, 0x01, 0x90, - 0x0b, 0x00, 0x01, 0x01, 0x01, 0xcf, 0x05, 0xff, 0x01, 0xa0, 0x0b, 0x00, - 0x01, 0x0d, 0x01, 0xff, 0x01, 0xe9, 0x01, 0x65, 0x01, 0x44, 0x01, 0x48, - 0x01, 0xff, 0x01, 0xa0, 0x0b, 0x00, 0x01, 0x5f, 0x01, 0xfd, 0x01, 0x10, - 0x02, 0x00, 0x01, 0x06, 0x01, 0xff, 0x01, 0xa0, 0x0b, 0x00, 0x01, 0x9f, - 0x01, 0xf6, 0x03, 0x00, 0x01, 0x09, 0x01, 0xff, 0x01, 0xa0, 0x0b, 0x00, - 0x01, 0xaf, 0x01, 0xf5, 0x03, 0x00, 0x01, 0x0e, 0x01, 0xff, 0x01, 0xa0, - 0x0b, 0x00, 0x01, 0x9f, 0x01, 0xfa, 0x03, 0x00, 0x01, 0xaf, 0x01, 0xff, - 0x01, 0xa0, 0x0b, 0x00, 0x01, 0x4f, 0x01, 0xff, 0x01, 0xa2, 0x01, 0x00, - 0x01, 0x3b, 0x02, 0xff, 0x01, 0xa0, 0x0b, 0x00, 0x01, 0x0a, 0x04, 0xff, - 0x01, 0xe7, 0x01, 0xff, 0x01, 0xa0, 0x0c, 0x00, 0x01, 0x8f, 0x02, 0xff, - 0x01, 0xf9, 0x01, 0x15, 0x01, 0xff, 0x01, 0xa0, 0x0d, 0x00, 0x01, 0x46, - 0x01, 0x64, 0x02, 0x00, 0x01, 0x11, 0x1f, 0x00, 0x01, 0x16, 0x06, 0x66, - 0x01, 0x40, 0x0b, 0x00, 0x01, 0x3f, 0x06, 0xff, 0x01, 0xb0, 0x0b, 0x00, - 0x01, 0x3f, 0x06, 0xff, 0x01, 0xb0, 0x0b, 0x00, 0x01, 0x01, 0x06, 0x11, - 0xff, 0x00, 0x75, 0x00, -#endif // TOUCH_UI_UTF8_ORDINALS - -#if ENABLED(TOUCH_UI_UTF8_COPYRIGHT) - /* 30 COPYRIGHT_SIGN */ - 0xa0, 0x00, 0x01, 0x01, 0x01, 0x45, 0x01, 0x76, 0x01, 0x43, 0x0e, 0x00, - 0x01, 0x28, 0x01, 0xdf, 0x03, 0xff, 0x01, 0xe9, 0x01, 0x40, 0x0b, 0x00, - 0x01, 0x19, 0x02, 0xff, 0x01, 0xdb, 0x01, 0xab, 0x01, 0xce, 0x01, 0xff, - 0x01, 0xfb, 0x01, 0x30, 0x09, 0x00, 0x01, 0x03, 0x01, 0xef, 0x01, 0xfb, - 0x01, 0x50, 0x03, 0x00, 0x01, 0x38, 0x01, 0xff, 0x01, 0xf7, 0x09, 0x00, - 0x01, 0x6f, 0x01, 0xfc, 0x01, 0x30, 0x05, 0x00, 0x01, 0x19, 0x01, 0xff, - 0x01, 0xa0, 0x07, 0x00, 0x01, 0x05, 0x01, 0xff, 0x01, 0xa0, 0x07, 0x00, - 0x01, 0x5f, 0x01, 0xfb, 0x07, 0x00, 0x01, 0x3f, 0x01, 0xf8, 0x03, 0x00, - 0x01, 0x46, 0x01, 0x88, 0x01, 0x65, 0x01, 0x10, 0x01, 0x00, 0x01, 0x03, - 0x01, 0xff, 0x01, 0x80, 0x06, 0x00, 0x01, 0xef, 0x01, 0xa0, 0x01, 0x00, - 0x01, 0x01, 0x01, 0x9f, 0x03, 0xff, 0x01, 0xfc, 0x01, 0x60, 0x01, 0x00, - 0x01, 0x4f, 0x01, 0xf4, 0x05, 0x00, 0x01, 0x08, 0x01, 0xfd, 0x02, 0x00, - 0x01, 0x4e, 0x02, 0xff, 0x01, 0xed, 0x01, 0xef, 0x01, 0xff, 0x01, 0xb0, - 0x01, 0x00, 0x01, 0x08, 0x01, 0xfd, 0x05, 0x00, 0x01, 0x1f, 0x01, 0xf4, - 0x01, 0x00, 0x01, 0x04, 0x01, 0xff, 0x01, 0xfe, 0x01, 0x61, 0x01, 0x00, - 0x01, 0x01, 0x01, 0x4a, 0x01, 0xa0, 0x02, 0x00, 0x01, 0xef, 0x01, 0x60, - 0x04, 0x00, 0x01, 0x6f, 0x01, 0xc0, 0x01, 0x00, 0x01, 0x0e, 0x01, 0xff, - 0x01, 0xc1, 0x07, 0x00, 0x01, 0x7f, 0x01, 0xb0, 0x04, 0x00, 0x01, 0xbf, - 0x01, 0x60, 0x01, 0x00, 0x01, 0x7f, 0x01, 0xff, 0x01, 0x10, 0x07, 0x00, - 0x01, 0x1f, 0x01, 0xf0, 0x04, 0x00, 0x01, 0xff, 0x01, 0x20, 0x01, 0x00, - 0x01, 0xdf, 0x01, 0xf9, 0x08, 0x00, 0x01, 0x0d, 0x01, 0xf4, 0x03, 0x00, - 0x01, 0x01, 0x01, 0xfe, 0x01, 0x00, 0x01, 0x01, 0x01, 0xff, 0x01, 0xf4, - 0x08, 0x00, 0x01, 0x0a, 0x01, 0xf6, 0x03, 0x00, 0x01, 0x03, 0x01, 0xfd, - 0x01, 0x00, 0x01, 0x02, 0x01, 0xff, 0x01, 0xf1, 0x08, 0x00, 0x01, 0x08, - 0x01, 0xf8, 0x03, 0x00, 0x01, 0x04, 0x01, 0xfc, 0x01, 0x00, 0x01, 0x03, - 0x01, 0xff, 0x01, 0xf0, 0x08, 0x00, 0x01, 0x07, 0x01, 0xf9, 0x03, 0x00, - 0x01, 0x03, 0x01, 0xfd, 0x01, 0x00, 0x01, 0x02, 0x01, 0xff, 0x01, 0xf1, - 0x08, 0x00, 0x01, 0x08, 0x01, 0xf8, 0x03, 0x00, 0x01, 0x01, 0x01, 0xfe, - 0x01, 0x00, 0x01, 0x01, 0x01, 0xff, 0x01, 0xf3, 0x08, 0x00, 0x01, 0x09, - 0x01, 0xf7, 0x04, 0x00, 0x01, 0xff, 0x01, 0x10, 0x01, 0x00, 0x01, 0xdf, - 0x01, 0xf8, 0x08, 0x00, 0x01, 0x0c, 0x01, 0xf5, 0x04, 0x00, 0x01, 0xbf, - 0x01, 0x60, 0x01, 0x00, 0x01, 0x8f, 0x01, 0xfe, 0x01, 0x10, 0x07, 0x00, - 0x01, 0x1f, 0x01, 0xf1, 0x04, 0x00, 0x01, 0x6f, 0x01, 0xb0, 0x01, 0x00, - 0x01, 0x1f, 0x01, 0xff, 0x01, 0xb0, 0x07, 0x00, 0x01, 0x6f, 0x01, 0xc0, - 0x04, 0x00, 0x01, 0x1f, 0x01, 0xf4, 0x01, 0x00, 0x01, 0x05, 0x01, 0xff, - 0x01, 0xfd, 0x01, 0x50, 0x02, 0x00, 0x01, 0x29, 0x01, 0xa0, 0x02, 0x00, - 0x01, 0xef, 0x01, 0x60, 0x04, 0x00, 0x01, 0x08, 0x01, 0xfd, 0x02, 0x00, - 0x01, 0x6f, 0x02, 0xff, 0x01, 0xdb, 0x01, 0xce, 0x01, 0xff, 0x01, 0xb0, - 0x01, 0x00, 0x01, 0x07, 0x01, 0xfd, 0x05, 0x00, 0x01, 0x01, 0x01, 0xef, - 0x01, 0x90, 0x01, 0x00, 0x01, 0x02, 0x01, 0xbf, 0x03, 0xff, 0x01, 0xfe, - 0x01, 0x70, 0x01, 0x00, 0x01, 0x4f, 0x01, 0xf4, 0x06, 0x00, 0x01, 0x4f, - 0x01, 0xf7, 0x02, 0x00, 0x01, 0x01, 0x01, 0x58, 0x01, 0x9a, 0x01, 0x86, - 0x01, 0x30, 0x01, 0x00, 0x01, 0x02, 0x01, 0xef, 0x01, 0x80, 0x06, 0x00, - 0x01, 0x06, 0x01, 0xff, 0x01, 0x90, 0x07, 0x00, 0x01, 0x4f, 0x01, 0xfb, - 0x08, 0x00, 0x01, 0x6f, 0x01, 0xfc, 0x01, 0x30, 0x05, 0x00, 0x01, 0x18, - 0x01, 0xff, 0x01, 0xb0, 0x08, 0x00, 0x01, 0x04, 0x01, 0xef, 0x01, 0xfa, - 0x01, 0x40, 0x03, 0x00, 0x01, 0x27, 0x01, 0xef, 0x01, 0xf8, 0x0a, 0x00, - 0x01, 0x19, 0x02, 0xff, 0x01, 0xca, 0x01, 0x9a, 0x01, 0xbe, 0x01, 0xff, - 0x01, 0xfc, 0x01, 0x30, 0x0b, 0x00, 0x01, 0x29, 0x01, 0xdf, 0x03, 0xff, - 0x01, 0xfa, 0x01, 0x40, 0x0d, 0x00, 0x01, 0x02, 0x01, 0x46, 0x01, 0x76, - 0x01, 0x53, 0xc5, 0x00, - - /* 31 REGISTERED_SIGN */ - 0xa0, 0x00, 0x01, 0x02, 0x01, 0x46, 0x01, 0x76, 0x01, 0x53, 0x0e, 0x00, - 0x01, 0x28, 0x01, 0xdf, 0x03, 0xff, 0x01, 0xea, 0x01, 0x40, 0x0b, 0x00, - 0x01, 0x19, 0x02, 0xff, 0x01, 0xcb, 0x01, 0x9a, 0x01, 0xce, 0x01, 0xff, - 0x01, 0xfc, 0x01, 0x30, 0x09, 0x00, 0x01, 0x04, 0x01, 0xef, 0x01, 0xfa, - 0x01, 0x40, 0x03, 0x00, 0x01, 0x38, 0x01, 0xff, 0x01, 0xf8, 0x09, 0x00, - 0x01, 0x6f, 0x01, 0xfc, 0x01, 0x30, 0x05, 0x00, 0x01, 0x18, 0x01, 0xff, - 0x01, 0xa0, 0x07, 0x00, 0x01, 0x06, 0x01, 0xff, 0x01, 0x90, 0x07, 0x00, - 0x01, 0x4f, 0x01, 0xfb, 0x07, 0x00, 0x01, 0x3f, 0x01, 0xf7, 0x01, 0x00, - 0x01, 0x13, 0x02, 0x33, 0x01, 0x32, 0x03, 0x00, 0x01, 0x02, 0x01, 0xff, - 0x01, 0x80, 0x06, 0x00, 0x01, 0xef, 0x01, 0xa0, 0x01, 0x00, 0x01, 0x7f, - 0x03, 0xff, 0x01, 0xfd, 0x01, 0x81, 0x02, 0x00, 0x01, 0x4f, 0x01, 0xf5, - 0x05, 0x00, 0x01, 0x08, 0x01, 0xfd, 0x02, 0x00, 0x01, 0x7f, 0x01, 0xff, - 0x01, 0xdd, 0x01, 0xef, 0x01, 0xff, 0x01, 0xfe, 0x01, 0x30, 0x01, 0x00, - 0x01, 0x08, 0x01, 0xfe, 0x05, 0x00, 0x01, 0x1f, 0x01, 0xf4, 0x02, 0x00, - 0x01, 0x7f, 0x01, 0xfa, 0x02, 0x00, 0x01, 0x3c, 0x01, 0xff, 0x01, 0xd0, - 0x02, 0x00, 0x01, 0xef, 0x01, 0x60, 0x04, 0x00, 0x01, 0x6f, 0x01, 0xc0, - 0x02, 0x00, 0x01, 0x7f, 0x01, 0xfa, 0x02, 0x00, 0x01, 0x02, 0x01, 0xff, - 0x01, 0xf3, 0x02, 0x00, 0x01, 0x7f, 0x01, 0xb0, 0x04, 0x00, 0x01, 0xbf, - 0x01, 0x60, 0x02, 0x00, 0x01, 0x7f, 0x01, 0xfa, 0x03, 0x00, 0x01, 0xff, - 0x01, 0xf4, 0x02, 0x00, 0x01, 0x1f, 0x01, 0xf0, 0x04, 0x00, 0x01, 0xff, - 0x01, 0x10, 0x02, 0x00, 0x01, 0x7f, 0x01, 0xfa, 0x03, 0x00, 0x01, 0xff, - 0x01, 0xf2, 0x02, 0x00, 0x01, 0x0c, 0x01, 0xf5, 0x03, 0x00, 0x01, 0x01, - 0x01, 0xfe, 0x03, 0x00, 0x01, 0x7f, 0x01, 0xfa, 0x02, 0x00, 0x01, 0x08, - 0x01, 0xff, 0x01, 0xe0, 0x02, 0x00, 0x01, 0x0a, 0x01, 0xf6, 0x03, 0x00, - 0x01, 0x03, 0x01, 0xfd, 0x03, 0x00, 0x01, 0x7f, 0x01, 0xfd, 0x01, 0x88, - 0x01, 0x9a, 0x01, 0xef, 0x01, 0xfe, 0x01, 0x30, 0x02, 0x00, 0x01, 0x08, - 0x01, 0xf8, 0x03, 0x00, 0x01, 0x04, 0x01, 0xfc, 0x03, 0x00, 0x01, 0x7f, - 0x03, 0xff, 0x01, 0xfe, 0x01, 0x91, 0x03, 0x00, 0x01, 0x07, 0x01, 0xf9, - 0x03, 0x00, 0x01, 0x03, 0x01, 0xfd, 0x03, 0x00, 0x01, 0x7f, 0x01, 0xfc, - 0x01, 0x78, 0x01, 0xdf, 0x01, 0xfd, 0x01, 0x20, 0x03, 0x00, 0x01, 0x08, - 0x01, 0xf8, 0x03, 0x00, 0x01, 0x01, 0x01, 0xfe, 0x03, 0x00, 0x01, 0x7f, - 0x01, 0xfa, 0x01, 0x00, 0x01, 0x0b, 0x01, 0xff, 0x01, 0xc0, 0x03, 0x00, - 0x01, 0x09, 0x01, 0xf6, 0x04, 0x00, 0x01, 0xff, 0x01, 0x10, 0x02, 0x00, - 0x01, 0x7f, 0x01, 0xfa, 0x02, 0x00, 0x01, 0xdf, 0x01, 0xf8, 0x03, 0x00, - 0x01, 0x0c, 0x01, 0xf5, 0x04, 0x00, 0x01, 0xbf, 0x01, 0x60, 0x02, 0x00, - 0x01, 0x7f, 0x01, 0xfa, 0x02, 0x00, 0x01, 0x4f, 0x01, 0xff, 0x01, 0x30, - 0x02, 0x00, 0x01, 0x1f, 0x01, 0xf1, 0x04, 0x00, 0x01, 0x6f, 0x01, 0xc0, - 0x02, 0x00, 0x01, 0x7f, 0x01, 0xfa, 0x02, 0x00, 0x01, 0x09, 0x01, 0xff, - 0x01, 0xd0, 0x02, 0x00, 0x01, 0x6f, 0x01, 0xb0, 0x04, 0x00, 0x01, 0x1f, - 0x01, 0xf4, 0x02, 0x00, 0x01, 0x7f, 0x01, 0xfa, 0x02, 0x00, 0x01, 0x01, - 0x01, 0xef, 0x01, 0xf7, 0x02, 0x00, 0x01, 0xef, 0x01, 0x60, 0x04, 0x00, - 0x01, 0x08, 0x01, 0xfd, 0x02, 0x00, 0x01, 0x7f, 0x01, 0xfa, 0x03, 0x00, - 0x01, 0x6f, 0x01, 0xff, 0x01, 0x20, 0x01, 0x08, 0x01, 0xfe, 0x06, 0x00, - 0x01, 0xef, 0x01, 0xa0, 0x01, 0x00, 0x01, 0x5a, 0x01, 0xa6, 0x03, 0x00, - 0x01, 0x09, 0x01, 0xaa, 0x01, 0x60, 0x01, 0x4f, 0x01, 0xf4, 0x06, 0x00, - 0x01, 0x3f, 0x01, 0xf8, 0x08, 0x00, 0x01, 0x03, 0x01, 0xff, 0x01, 0x80, - 0x06, 0x00, 0x01, 0x05, 0x01, 0xff, 0x01, 0x90, 0x07, 0x00, 0x01, 0x4f, - 0x01, 0xfb, 0x08, 0x00, 0x01, 0x6f, 0x01, 0xfc, 0x01, 0x30, 0x05, 0x00, - 0x01, 0x19, 0x01, 0xff, 0x01, 0xa0, 0x08, 0x00, 0x01, 0x04, 0x01, 0xef, - 0x01, 0xfa, 0x01, 0x40, 0x03, 0x00, 0x01, 0x38, 0x01, 0xef, 0x01, 0xf8, - 0x0a, 0x00, 0x01, 0x19, 0x02, 0xff, 0x01, 0xcb, 0x01, 0x9a, 0x01, 0xce, - 0x01, 0xff, 0x01, 0xfc, 0x01, 0x30, 0x0b, 0x00, 0x01, 0x28, 0x01, 0xdf, - 0x03, 0xff, 0x01, 0xea, 0x01, 0x40, 0x0d, 0x00, 0x01, 0x02, 0x01, 0x45, - 0x01, 0x76, 0x01, 0x43, 0xc5, 0x00, -#endif // TOUCH_UI_UTF8_COPYRIGHT - -#if ENABLED(TOUCH_UI_UTF8_MATHEMATICS) - /* 32 PLUS_MINUS_SIGN */ - 0xeb, 0x00, 0x01, 0x02, 0x01, 0x77, 0x01, 0x70, 0x10, 0x00, 0x01, 0x06, - 0x01, 0xff, 0x01, 0xf0, 0x10, 0x00, 0x01, 0x06, 0x01, 0xff, 0x01, 0xf0, - 0x10, 0x00, 0x01, 0x06, 0x01, 0xff, 0x01, 0xf0, 0x10, 0x00, 0x01, 0x06, - 0x01, 0xff, 0x01, 0xf0, 0x10, 0x00, 0x01, 0x06, 0x01, 0xff, 0x01, 0xf0, - 0x10, 0x00, 0x01, 0x06, 0x01, 0xff, 0x01, 0xf0, 0x10, 0x00, 0x01, 0x06, - 0x01, 0xff, 0x01, 0xf0, 0x0b, 0x00, 0x01, 0x6a, 0x04, 0xaa, 0x01, 0xac, - 0x01, 0xff, 0x01, 0xfa, 0x05, 0xaa, 0x01, 0x20, 0x05, 0x00, 0x01, 0x9f, - 0x0c, 0xff, 0x01, 0x40, 0x05, 0x00, 0x01, 0x9f, 0x0c, 0xff, 0x01, 0x40, - 0x05, 0x00, 0x01, 0x7c, 0x04, 0xcc, 0x01, 0xcd, 0x01, 0xff, 0x01, 0xfc, - 0x05, 0xcc, 0x01, 0x30, 0x0a, 0x00, 0x01, 0x06, 0x01, 0xff, 0x01, 0xf0, - 0x10, 0x00, 0x01, 0x06, 0x01, 0xff, 0x01, 0xf0, 0x10, 0x00, 0x01, 0x06, - 0x01, 0xff, 0x01, 0xf0, 0x10, 0x00, 0x01, 0x06, 0x01, 0xff, 0x01, 0xf0, - 0x10, 0x00, 0x01, 0x06, 0x01, 0xff, 0x01, 0xf0, 0x10, 0x00, 0x01, 0x06, - 0x01, 0xff, 0x01, 0xf0, 0x10, 0x00, 0x01, 0x06, 0x01, 0xff, 0x01, 0xf0, - 0x10, 0x00, 0x01, 0x03, 0x01, 0x99, 0x01, 0x90, 0x44, 0x00, 0x01, 0x9f, - 0x0c, 0xff, 0x01, 0x30, 0x05, 0x00, 0x01, 0x9f, 0x0c, 0xff, 0x01, 0x40, - 0x05, 0x00, 0x01, 0x9f, 0x0c, 0xff, 0x01, 0x40, 0x05, 0x00, 0x01, 0x47, - 0x0c, 0x77, 0x01, 0x10, 0xc1, 0x00, - - /* 33 MULTIPLICATION_SIGN */ - 0xff, 0x00, 0x0e, 0x00, 0x01, 0x09, 0x01, 0xb0, 0x07, 0x00, 0x01, 0x03, - 0x01, 0xe4, 0x08, 0x00, 0x01, 0x9f, 0x01, 0xfb, 0x07, 0x00, 0x01, 0x3e, - 0x01, 0xff, 0x01, 0x40, 0x06, 0x00, 0x01, 0x01, 0x01, 0xef, 0x01, 0xff, - 0x01, 0xb0, 0x05, 0x00, 0x01, 0x03, 0x01, 0xef, 0x01, 0xff, 0x01, 0xa0, - 0x07, 0x00, 0x01, 0x2e, 0x01, 0xff, 0x01, 0xfb, 0x05, 0x00, 0x01, 0x3e, - 0x01, 0xff, 0x01, 0xfb, 0x08, 0x00, 0x01, 0x02, 0x01, 0xef, 0x01, 0xff, - 0x01, 0xb0, 0x03, 0x00, 0x01, 0x03, 0x01, 0xef, 0x01, 0xff, 0x01, 0xb0, - 0x09, 0x00, 0x01, 0x2e, 0x01, 0xff, 0x01, 0xfb, 0x03, 0x00, 0x01, 0x3e, - 0x01, 0xff, 0x01, 0xfb, 0x0a, 0x00, 0x01, 0x02, 0x01, 0xef, 0x01, 0xff, - 0x01, 0xb0, 0x01, 0x00, 0x01, 0x03, 0x01, 0xef, 0x01, 0xff, 0x01, 0xb0, - 0x0b, 0x00, 0x01, 0x2e, 0x01, 0xff, 0x01, 0xfb, 0x01, 0x00, 0x01, 0x3e, - 0x01, 0xff, 0x01, 0xfb, 0x0c, 0x00, 0x01, 0x02, 0x01, 0xef, 0x01, 0xff, - 0x01, 0xb3, 0x01, 0xef, 0x01, 0xff, 0x01, 0xb0, 0x0d, 0x00, 0x01, 0x3e, - 0x03, 0xff, 0x01, 0xfb, 0x0e, 0x00, 0x01, 0x03, 0x01, 0xef, 0x02, 0xff, - 0x01, 0xb0, 0x0f, 0x00, 0x01, 0x5f, 0x02, 0xff, 0x01, 0x10, 0x0e, 0x00, - 0x01, 0x03, 0x01, 0xef, 0x02, 0xff, 0x01, 0xb0, 0x0e, 0x00, 0x01, 0x3e, - 0x03, 0xff, 0x01, 0xfb, 0x0d, 0x00, 0x01, 0x02, 0x01, 0xef, 0x01, 0xff, - 0x01, 0xb3, 0x01, 0xef, 0x01, 0xff, 0x01, 0xb0, 0x0c, 0x00, 0x01, 0x2e, - 0x01, 0xff, 0x01, 0xfb, 0x01, 0x00, 0x01, 0x2e, 0x01, 0xff, 0x01, 0xfb, - 0x0b, 0x00, 0x01, 0x02, 0x01, 0xef, 0x01, 0xff, 0x01, 0xb0, 0x01, 0x00, - 0x01, 0x02, 0x01, 0xef, 0x01, 0xff, 0x01, 0xb0, 0x0a, 0x00, 0x01, 0x2e, - 0x01, 0xff, 0x01, 0xfb, 0x03, 0x00, 0x01, 0x2e, 0x01, 0xff, 0x01, 0xfb, - 0x09, 0x00, 0x01, 0x02, 0x01, 0xef, 0x01, 0xff, 0x01, 0xb0, 0x03, 0x00, - 0x01, 0x02, 0x01, 0xef, 0x01, 0xff, 0x01, 0xb0, 0x08, 0x00, 0x01, 0x2e, - 0x01, 0xff, 0x01, 0xfb, 0x05, 0x00, 0x01, 0x2e, 0x01, 0xff, 0x01, 0xfb, - 0x07, 0x00, 0x01, 0x01, 0x01, 0xef, 0x01, 0xff, 0x01, 0xb0, 0x05, 0x00, - 0x01, 0x02, 0x01, 0xef, 0x01, 0xff, 0x01, 0xa0, 0x07, 0x00, 0x01, 0x8f, - 0x01, 0xfb, 0x07, 0x00, 0x01, 0x2e, 0x01, 0xff, 0x01, 0x40, 0x07, 0x00, - 0x01, 0x09, 0x01, 0xb0, 0x07, 0x00, 0x01, 0x02, 0x01, 0xe4, 0xe9, 0x00, - - /* 34 DIVISION_SIGN */ - 0xff, 0x00, 0x25, 0x00, 0x01, 0x17, 0x01, 0x77, 0x01, 0x76, 0x10, 0x00, - 0x01, 0x2f, 0x01, 0xff, 0x01, 0xfc, 0x10, 0x00, 0x01, 0x2f, 0x01, 0xff, - 0x01, 0xfc, 0x10, 0x00, 0x01, 0x2f, 0x01, 0xff, 0x01, 0xfc, 0x10, 0x00, - 0x01, 0x2f, 0x01, 0xff, 0x01, 0xfc, 0x10, 0x00, 0x01, 0x17, 0x01, 0x77, - 0x01, 0x76, 0x31, 0x00, 0x01, 0x24, 0x0c, 0x44, 0x01, 0x10, 0x05, 0x00, - 0x01, 0x9f, 0x0c, 0xff, 0x01, 0x40, 0x05, 0x00, 0x01, 0x9f, 0x0c, 0xff, - 0x01, 0x40, 0x05, 0x00, 0x01, 0x9f, 0x0c, 0xff, 0x01, 0x40, 0x05, 0x00, - 0x01, 0x12, 0x0c, 0x22, 0x31, 0x00, 0x01, 0x18, 0x01, 0x88, 0x01, 0x87, - 0x10, 0x00, 0x01, 0x2f, 0x01, 0xff, 0x01, 0xfc, 0x10, 0x00, 0x01, 0x2f, - 0x01, 0xff, 0x01, 0xfc, 0x10, 0x00, 0x01, 0x2f, 0x01, 0xff, 0x01, 0xfc, - 0x10, 0x00, 0x01, 0x2f, 0x01, 0xff, 0x01, 0xfc, 0x10, 0x00, 0x01, 0x16, - 0x01, 0x66, 0x01, 0x65, 0xff, 0x00, 0x01, 0x00, -#endif // TOUCH_UI_UTF8_MATHEMATICS - -#if ENABLED(TOUCH_UI_UTF8_FRACTIONS) - /* 35 FRACTION_QUARTER */ - 0x92, 0x00, 0x01, 0x01, 0x01, 0x44, 0x01, 0x40, 0x04, 0x00, 0x01, 0x04, - 0x01, 0x79, 0x01, 0xce, 0x01, 0xee, 0x01, 0x20, 0x07, 0x00, 0x01, 0x0a, - 0x01, 0xff, 0x01, 0x90, 0x04, 0x00, 0x01, 0x3f, 0x03, 0xff, 0x01, 0x20, - 0x07, 0x00, 0x01, 0x3f, 0x01, 0xfe, 0x01, 0x10, 0x04, 0x00, 0x01, 0x3f, - 0x01, 0xdb, 0x01, 0x8d, 0x01, 0xff, 0x01, 0x20, 0x07, 0x00, 0x01, 0xdf, - 0x01, 0xf5, 0x05, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x0b, 0x01, 0xff, - 0x01, 0x20, 0x06, 0x00, 0x01, 0x07, 0x01, 0xff, 0x01, 0xc0, 0x07, 0x00, - 0x01, 0x0b, 0x01, 0xff, 0x01, 0x20, 0x06, 0x00, 0x01, 0x1f, 0x01, 0xff, - 0x01, 0x20, 0x07, 0x00, 0x01, 0x0b, 0x01, 0xff, 0x01, 0x20, 0x06, 0x00, - 0x01, 0xaf, 0x01, 0xf8, 0x08, 0x00, 0x01, 0x0b, 0x01, 0xff, 0x01, 0x20, - 0x05, 0x00, 0x01, 0x04, 0x01, 0xff, 0x01, 0xe1, 0x08, 0x00, 0x01, 0x0b, - 0x01, 0xff, 0x01, 0x20, 0x05, 0x00, 0x01, 0x0d, 0x01, 0xff, 0x01, 0x50, - 0x08, 0x00, 0x01, 0x0b, 0x01, 0xff, 0x01, 0x20, 0x05, 0x00, 0x01, 0x7f, - 0x01, 0xfc, 0x09, 0x00, 0x01, 0x0b, 0x01, 0xff, 0x01, 0x20, 0x04, 0x00, - 0x01, 0x01, 0x01, 0xff, 0x01, 0xf2, 0x09, 0x00, 0x01, 0x0b, 0x01, 0xff, - 0x01, 0x20, 0x04, 0x00, 0x01, 0x0a, 0x01, 0xff, 0x01, 0x80, 0x09, 0x00, - 0x01, 0x0b, 0x01, 0xff, 0x01, 0x20, 0x04, 0x00, 0x01, 0x4f, 0x01, 0xfe, - 0x0a, 0x00, 0x01, 0x0b, 0x01, 0xff, 0x01, 0x20, 0x04, 0x00, 0x01, 0xdf, - 0x01, 0xf5, 0x0a, 0x00, 0x01, 0x0b, 0x01, 0xff, 0x01, 0x20, 0x03, 0x00, - 0x01, 0x07, 0x01, 0xff, 0x01, 0xb0, 0x04, 0x00, 0x01, 0x37, 0x01, 0x77, - 0x02, 0x00, 0x01, 0x04, 0x01, 0x55, 0x01, 0x5d, 0x01, 0xff, 0x01, 0x75, - 0x01, 0x55, 0x01, 0x10, 0x01, 0x00, 0x01, 0x1f, 0x01, 0xff, 0x01, 0x20, - 0x03, 0x00, 0x01, 0x01, 0x01, 0xef, 0x01, 0xff, 0x02, 0x00, 0x01, 0x0d, - 0x05, 0xff, 0x01, 0x40, 0x01, 0x00, 0x01, 0xaf, 0x01, 0xf8, 0x04, 0x00, - 0x01, 0x0c, 0x02, 0xff, 0x02, 0x00, 0x01, 0x0c, 0x05, 0xee, 0x01, 0x40, - 0x01, 0x04, 0x01, 0xff, 0x01, 0xe0, 0x04, 0x00, 0x01, 0x8f, 0x01, 0xbe, - 0x01, 0xff, 0x09, 0x00, 0x01, 0x0d, 0x01, 0xff, 0x01, 0x50, 0x03, 0x00, - 0x01, 0x04, 0x01, 0xfe, 0x01, 0x1e, 0x01, 0xff, 0x09, 0x00, 0x01, 0x7f, - 0x01, 0xfc, 0x04, 0x00, 0x01, 0x1e, 0x01, 0xf4, 0x01, 0x0e, 0x01, 0xff, - 0x08, 0x00, 0x01, 0x01, 0x01, 0xff, 0x01, 0xf2, 0x04, 0x00, 0x01, 0xbf, - 0x01, 0x80, 0x01, 0x0e, 0x01, 0xff, 0x08, 0x00, 0x01, 0x0b, 0x01, 0xff, - 0x01, 0x80, 0x03, 0x00, 0x01, 0x08, 0x01, 0xfc, 0x01, 0x00, 0x01, 0x0e, - 0x01, 0xff, 0x08, 0x00, 0x01, 0x4f, 0x01, 0xfe, 0x04, 0x00, 0x01, 0x4f, - 0x01, 0xe1, 0x01, 0x00, 0x01, 0x0e, 0x01, 0xff, 0x08, 0x00, 0x01, 0xdf, - 0x01, 0xf5, 0x03, 0x00, 0x01, 0x01, 0x01, 0xef, 0x01, 0x40, 0x01, 0x00, - 0x01, 0x0e, 0x01, 0xff, 0x07, 0x00, 0x01, 0x07, 0x01, 0xff, 0x01, 0xb0, - 0x03, 0x00, 0x01, 0x0b, 0x01, 0xf8, 0x02, 0x00, 0x01, 0x0e, 0x01, 0xff, - 0x07, 0x00, 0x01, 0x2f, 0x01, 0xff, 0x01, 0x20, 0x03, 0x00, 0x01, 0x3f, - 0x01, 0xf8, 0x02, 0x88, 0x01, 0x8f, 0x01, 0xff, 0x01, 0x88, 0x06, 0x00, - 0x01, 0xbf, 0x01, 0xf8, 0x04, 0x00, 0x01, 0x4f, 0x06, 0xff, 0x05, 0x00, - 0x01, 0x04, 0x01, 0xff, 0x01, 0xe0, 0x04, 0x00, 0x01, 0x2a, 0x03, 0xaa, - 0x01, 0xaf, 0x01, 0xff, 0x01, 0xaa, 0x05, 0x00, 0x01, 0x0d, 0x01, 0xff, - 0x01, 0x50, 0x08, 0x00, 0x01, 0x0e, 0x01, 0xff, 0x06, 0x00, 0x01, 0x8f, - 0x01, 0xfb, 0x09, 0x00, 0x01, 0x0e, 0x01, 0xff, 0x05, 0x00, 0x01, 0x02, - 0x01, 0xff, 0x01, 0xf2, 0x09, 0x00, 0x01, 0x0e, 0x01, 0xff, 0x05, 0x00, - 0x01, 0x0b, 0x01, 0xff, 0x01, 0x80, 0x09, 0x00, 0x01, 0x05, 0x01, 0x66, - 0xbf, 0x00, - - /* 36 FRACTION_HALF */ - 0x92, 0x00, 0x01, 0x01, 0x01, 0x44, 0x01, 0x40, 0x04, 0x00, 0x01, 0x04, - 0x01, 0x7a, 0x01, 0xce, 0x01, 0xee, 0x01, 0x20, 0x07, 0x00, 0x01, 0x0a, - 0x01, 0xff, 0x01, 0x80, 0x04, 0x00, 0x01, 0x3f, 0x03, 0xff, 0x01, 0x20, - 0x07, 0x00, 0x01, 0x4f, 0x01, 0xfe, 0x05, 0x00, 0x01, 0x3f, 0x01, 0xda, - 0x01, 0x7d, 0x01, 0xff, 0x01, 0x20, 0x07, 0x00, 0x01, 0xdf, 0x01, 0xf5, - 0x07, 0x00, 0x01, 0x0b, 0x01, 0xff, 0x01, 0x20, 0x06, 0x00, 0x01, 0x07, - 0x01, 0xff, 0x01, 0xc0, 0x07, 0x00, 0x01, 0x0b, 0x01, 0xff, 0x01, 0x20, - 0x06, 0x00, 0x01, 0x1f, 0x01, 0xff, 0x01, 0x20, 0x07, 0x00, 0x01, 0x0b, - 0x01, 0xff, 0x01, 0x20, 0x06, 0x00, 0x01, 0xaf, 0x01, 0xf8, 0x08, 0x00, - 0x01, 0x0b, 0x01, 0xff, 0x01, 0x20, 0x05, 0x00, 0x01, 0x04, 0x01, 0xff, - 0x01, 0xe0, 0x08, 0x00, 0x01, 0x0b, 0x01, 0xff, 0x01, 0x20, 0x05, 0x00, - 0x01, 0x0d, 0x01, 0xff, 0x01, 0x50, 0x08, 0x00, 0x01, 0x0b, 0x01, 0xff, - 0x01, 0x20, 0x05, 0x00, 0x01, 0x7f, 0x01, 0xfc, 0x09, 0x00, 0x01, 0x0b, - 0x01, 0xff, 0x01, 0x20, 0x04, 0x00, 0x01, 0x01, 0x01, 0xff, 0x01, 0xf2, - 0x09, 0x00, 0x01, 0x0b, 0x01, 0xff, 0x01, 0x20, 0x04, 0x00, 0x01, 0x0a, - 0x01, 0xff, 0x01, 0x80, 0x09, 0x00, 0x01, 0x0b, 0x01, 0xff, 0x01, 0x20, - 0x04, 0x00, 0x01, 0x4f, 0x01, 0xfe, 0x0a, 0x00, 0x01, 0x0b, 0x01, 0xff, - 0x01, 0x20, 0x04, 0x00, 0x01, 0xdf, 0x01, 0xf5, 0x0a, 0x00, 0x01, 0x0b, - 0x01, 0xff, 0x01, 0x20, 0x03, 0x00, 0x01, 0x07, 0x01, 0xff, 0x01, 0xb0, - 0x01, 0x00, 0x01, 0x04, 0x01, 0x8a, 0x01, 0xcc, 0x01, 0xa7, 0x01, 0x10, - 0x02, 0x00, 0x01, 0x04, 0x01, 0x55, 0x01, 0x5d, 0x01, 0xff, 0x01, 0x75, - 0x01, 0x55, 0x01, 0x10, 0x01, 0x00, 0x01, 0x2f, 0x01, 0xff, 0x01, 0x20, - 0x01, 0x06, 0x04, 0xff, 0x01, 0xf7, 0x02, 0x00, 0x01, 0x0d, 0x05, 0xff, - 0x01, 0x40, 0x01, 0x00, 0x01, 0xbf, 0x01, 0xf8, 0x01, 0x00, 0x01, 0x08, - 0x01, 0xff, 0x01, 0xa7, 0x01, 0x68, 0x01, 0xdf, 0x01, 0xff, 0x01, 0x70, - 0x01, 0x00, 0x01, 0x0b, 0x05, 0xdd, 0x01, 0x40, 0x01, 0x04, 0x01, 0xff, - 0x01, 0xe0, 0x01, 0x00, 0x01, 0x05, 0x01, 0x60, 0x02, 0x00, 0x01, 0x08, - 0x01, 0xff, 0x01, 0xf1, 0x08, 0x00, 0x01, 0x0d, 0x01, 0xff, 0x01, 0x50, - 0x06, 0x00, 0x01, 0xef, 0x01, 0xf4, 0x08, 0x00, 0x01, 0x7f, 0x01, 0xfb, - 0x07, 0x00, 0x01, 0xcf, 0x01, 0xf3, 0x07, 0x00, 0x01, 0x02, 0x01, 0xff, - 0x01, 0xf2, 0x06, 0x00, 0x01, 0x02, 0x01, 0xff, 0x01, 0xe0, 0x07, 0x00, - 0x01, 0x0b, 0x01, 0xff, 0x01, 0x80, 0x06, 0x00, 0x01, 0x0d, 0x01, 0xff, - 0x01, 0x50, 0x07, 0x00, 0x01, 0x4f, 0x01, 0xfe, 0x07, 0x00, 0x01, 0xaf, - 0x01, 0xfa, 0x08, 0x00, 0x01, 0xdf, 0x01, 0xf5, 0x06, 0x00, 0x01, 0x09, - 0x01, 0xff, 0x01, 0xc0, 0x07, 0x00, 0x01, 0x08, 0x01, 0xff, 0x01, 0xb0, - 0x06, 0x00, 0x01, 0x8f, 0x01, 0xfd, 0x01, 0x10, 0x07, 0x00, 0x01, 0x2f, - 0x01, 0xff, 0x01, 0x20, 0x05, 0x00, 0x01, 0x09, 0x01, 0xff, 0x01, 0xc1, - 0x08, 0x00, 0x01, 0xbf, 0x01, 0xf8, 0x06, 0x00, 0x01, 0xaf, 0x01, 0xfb, - 0x08, 0x00, 0x01, 0x05, 0x01, 0xff, 0x01, 0xe0, 0x05, 0x00, 0x01, 0x0b, - 0x01, 0xff, 0x01, 0xa0, 0x08, 0x00, 0x01, 0x0d, 0x01, 0xff, 0x01, 0x50, - 0x04, 0x00, 0x01, 0x01, 0x01, 0xcf, 0x01, 0xf9, 0x09, 0x00, 0x01, 0x8f, - 0x01, 0xfb, 0x05, 0x00, 0x01, 0x09, 0x01, 0xff, 0x01, 0xfe, 0x03, 0xee, - 0x01, 0xe6, 0x04, 0x00, 0x01, 0x02, 0x01, 0xff, 0x01, 0xf2, 0x05, 0x00, - 0x01, 0x0a, 0x05, 0xff, 0x01, 0xf7, 0x04, 0x00, 0x01, 0x0a, 0x01, 0xee, - 0x01, 0x70, 0x05, 0x00, 0x01, 0x04, 0x05, 0x66, 0x01, 0x62, 0xbe, 0x00, - - /* 37 FRACTION_THREE_FOURTHS */ - 0x87, 0x00, 0x01, 0x02, 0x01, 0x34, 0x01, 0x42, 0x08, 0x00, 0x01, 0x01, - 0x01, 0x55, 0x01, 0x50, 0x04, 0x00, 0x01, 0x4c, 0x03, 0xff, 0x01, 0xe9, - 0x01, 0x10, 0x06, 0x00, 0x01, 0x0a, 0x01, 0xff, 0x01, 0x80, 0x04, 0x00, - 0x01, 0x7f, 0x01, 0xff, 0x01, 0xfe, 0x02, 0xff, 0x01, 0xe2, 0x06, 0x00, - 0x01, 0x4f, 0x01, 0xfe, 0x05, 0x00, 0x01, 0x47, 0x01, 0x30, 0x01, 0x00, - 0x01, 0x05, 0x01, 0xef, 0x01, 0xfb, 0x06, 0x00, 0x01, 0xdf, 0x01, 0xf5, - 0x09, 0x00, 0x01, 0x3f, 0x01, 0xff, 0x05, 0x00, 0x01, 0x07, 0x01, 0xff, - 0x01, 0xb0, 0x09, 0x00, 0x01, 0x1f, 0x01, 0xff, 0x05, 0x00, 0x01, 0x2f, - 0x01, 0xff, 0x01, 0x20, 0x09, 0x00, 0x01, 0x6f, 0x01, 0xfb, 0x05, 0x00, - 0x01, 0xbf, 0x01, 0xf8, 0x07, 0x00, 0x01, 0x03, 0x01, 0x44, 0x01, 0x5a, - 0x01, 0xff, 0x01, 0xd1, 0x04, 0x00, 0x01, 0x04, 0x01, 0xff, 0x01, 0xe0, - 0x07, 0x00, 0x01, 0x0c, 0x02, 0xff, 0x01, 0xe7, 0x05, 0x00, 0x01, 0x0d, - 0x01, 0xff, 0x01, 0x50, 0x07, 0x00, 0x01, 0x0b, 0x01, 0xef, 0x01, 0xff, - 0x01, 0xfe, 0x01, 0x70, 0x04, 0x00, 0x01, 0x7f, 0x01, 0xfb, 0x0a, 0x00, - 0x01, 0x16, 0x01, 0xdf, 0x01, 0xf9, 0x03, 0x00, 0x01, 0x02, 0x01, 0xff, - 0x01, 0xf2, 0x0b, 0x00, 0x01, 0x1e, 0x01, 0xff, 0x01, 0x20, 0x02, 0x00, - 0x01, 0x0b, 0x01, 0xff, 0x01, 0x80, 0x0b, 0x00, 0x01, 0x0a, 0x01, 0xff, - 0x01, 0x60, 0x02, 0x00, 0x01, 0x4f, 0x01, 0xfe, 0x0c, 0x00, 0x01, 0x0a, - 0x01, 0xff, 0x01, 0x60, 0x02, 0x00, 0x01, 0xdf, 0x01, 0xf5, 0x0c, 0x00, - 0x01, 0x2f, 0x01, 0xff, 0x01, 0x30, 0x01, 0x00, 0x01, 0x08, 0x01, 0xff, - 0x01, 0xb0, 0x04, 0x00, 0x01, 0x47, 0x01, 0x77, 0x02, 0x00, 0x01, 0xd7, - 0x01, 0x42, 0x01, 0x01, 0x01, 0x38, 0x01, 0xef, 0x01, 0xfc, 0x02, 0x00, - 0x01, 0x2f, 0x01, 0xff, 0x01, 0x20, 0x03, 0x00, 0x01, 0x02, 0x02, 0xff, - 0x02, 0x00, 0x05, 0xff, 0x01, 0xc1, 0x02, 0x00, 0x01, 0xbf, 0x01, 0xf8, - 0x04, 0x00, 0x01, 0x0c, 0x02, 0xff, 0x02, 0x00, 0x01, 0x7b, 0x01, 0xef, - 0x02, 0xff, 0x01, 0xb6, 0x02, 0x00, 0x01, 0x04, 0x01, 0xff, 0x01, 0xe0, - 0x04, 0x00, 0x01, 0x9f, 0x01, 0xbe, 0x01, 0xff, 0x04, 0x00, 0x01, 0x22, - 0x01, 0x10, 0x03, 0x00, 0x01, 0x0d, 0x01, 0xff, 0x01, 0x50, 0x03, 0x00, - 0x01, 0x04, 0x01, 0xfe, 0x01, 0x1e, 0x01, 0xff, 0x09, 0x00, 0x01, 0x8f, - 0x01, 0xfb, 0x04, 0x00, 0x01, 0x1e, 0x01, 0xf3, 0x01, 0x0e, 0x01, 0xff, - 0x08, 0x00, 0x01, 0x02, 0x01, 0xff, 0x01, 0xf2, 0x04, 0x00, 0x01, 0xcf, - 0x01, 0x70, 0x01, 0x0e, 0x01, 0xff, 0x08, 0x00, 0x01, 0x0b, 0x01, 0xff, - 0x01, 0x80, 0x03, 0x00, 0x01, 0x08, 0x01, 0xfb, 0x01, 0x00, 0x01, 0x0e, - 0x01, 0xff, 0x08, 0x00, 0x01, 0x5f, 0x01, 0xfe, 0x04, 0x00, 0x01, 0x4f, - 0x01, 0xe1, 0x01, 0x00, 0x01, 0x0e, 0x01, 0xff, 0x08, 0x00, 0x01, 0xdf, - 0x01, 0xf4, 0x03, 0x00, 0x01, 0x01, 0x01, 0xef, 0x01, 0x40, 0x01, 0x00, - 0x01, 0x0e, 0x01, 0xff, 0x07, 0x00, 0x01, 0x08, 0x01, 0xff, 0x01, 0xb0, - 0x03, 0x00, 0x01, 0x0b, 0x01, 0xf8, 0x02, 0x00, 0x01, 0x0e, 0x01, 0xff, - 0x07, 0x00, 0x01, 0x2f, 0x01, 0xff, 0x01, 0x20, 0x03, 0x00, 0x01, 0x3f, - 0x01, 0xf9, 0x02, 0x99, 0x01, 0x9f, 0x01, 0xff, 0x01, 0x99, 0x06, 0x00, - 0x01, 0xbf, 0x01, 0xf8, 0x04, 0x00, 0x01, 0x4f, 0x06, 0xff, 0x05, 0x00, - 0x01, 0x05, 0x01, 0xff, 0x01, 0xd0, 0x04, 0x00, 0x01, 0x29, 0x03, 0x99, - 0x01, 0x9f, 0x01, 0xff, 0x01, 0x99, 0x05, 0x00, 0x01, 0x0d, 0x01, 0xff, - 0x01, 0x40, 0x08, 0x00, 0x01, 0x0e, 0x01, 0xff, 0x06, 0x00, 0x01, 0x8f, - 0x01, 0xfb, 0x09, 0x00, 0x01, 0x0e, 0x01, 0xff, 0x05, 0x00, 0x01, 0x02, - 0x01, 0xff, 0x01, 0xf2, 0x09, 0x00, 0x01, 0x0e, 0x01, 0xff, 0x05, 0x00, - 0x01, 0x0a, 0x01, 0xee, 0x01, 0x70, 0x09, 0x00, 0x01, 0x04, 0x01, 0x55, - 0xbf, 0x00, -#endif // TOUCH_UI_UTF8_FRACTIONS - -#if ENABLED(TOUCH_UI_UTF8_SYMBOLS) - /* 38 MICRON_SIGN */ - 0xff, 0x00, 0x1f, 0x00, 0x01, 0x02, 0x01, 0x44, 0x01, 0x40, 0x05, 0x00, - 0x01, 0x14, 0x01, 0x44, 0x01, 0x10, 0x08, 0x00, 0x01, 0x07, 0x01, 0xff, - 0x01, 0xf3, 0x05, 0x00, 0x01, 0x4f, 0x01, 0xff, 0x01, 0x70, 0x08, 0x00, - 0x01, 0x07, 0x01, 0xff, 0x01, 0xf3, 0x05, 0x00, 0x01, 0x4f, 0x01, 0xff, - 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x01, 0xff, 0x01, 0xf3, 0x05, 0x00, - 0x01, 0x4f, 0x01, 0xff, 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x01, 0xff, - 0x01, 0xf3, 0x05, 0x00, 0x01, 0x4f, 0x01, 0xff, 0x01, 0x70, 0x08, 0x00, - 0x01, 0x07, 0x01, 0xff, 0x01, 0xf3, 0x05, 0x00, 0x01, 0x4f, 0x01, 0xff, - 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x01, 0xff, 0x01, 0xf3, 0x05, 0x00, - 0x01, 0x4f, 0x01, 0xff, 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x01, 0xff, - 0x01, 0xf3, 0x05, 0x00, 0x01, 0x4f, 0x01, 0xff, 0x01, 0x70, 0x08, 0x00, - 0x01, 0x07, 0x01, 0xff, 0x01, 0xf3, 0x05, 0x00, 0x01, 0x4f, 0x01, 0xff, - 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x01, 0xff, 0x01, 0xf3, 0x05, 0x00, - 0x01, 0x4f, 0x01, 0xff, 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x01, 0xff, - 0x01, 0xf3, 0x05, 0x00, 0x01, 0x4f, 0x01, 0xff, 0x01, 0x70, 0x08, 0x00, - 0x01, 0x07, 0x01, 0xff, 0x01, 0xf3, 0x05, 0x00, 0x01, 0x4f, 0x01, 0xff, - 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x01, 0xff, 0x01, 0xf3, 0x05, 0x00, - 0x01, 0x4f, 0x01, 0xff, 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x01, 0xff, - 0x01, 0xf3, 0x05, 0x00, 0x01, 0x4f, 0x01, 0xff, 0x01, 0x70, 0x08, 0x00, - 0x01, 0x07, 0x01, 0xff, 0x01, 0xf3, 0x05, 0x00, 0x01, 0x4f, 0x01, 0xff, - 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x01, 0xff, 0x01, 0xf4, 0x05, 0x00, - 0x01, 0x6f, 0x01, 0xff, 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x01, 0xff, - 0x01, 0xf6, 0x05, 0x00, 0x01, 0x9f, 0x01, 0xff, 0x01, 0x70, 0x08, 0x00, - 0x01, 0x07, 0x01, 0xff, 0x01, 0xfa, 0x05, 0x00, 0x01, 0xef, 0x01, 0xff, - 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x02, 0xff, 0x01, 0x20, 0x03, 0x00, - 0x01, 0x07, 0x02, 0xff, 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x02, 0xff, - 0x01, 0xd2, 0x03, 0x00, 0x01, 0x6f, 0x02, 0xff, 0x01, 0xa0, 0x08, 0x00, - 0x01, 0x07, 0x03, 0xff, 0x01, 0xa6, 0x01, 0x55, 0x01, 0x8d, 0x03, 0xff, - 0x01, 0xf9, 0x01, 0xa4, 0x07, 0x00, 0x01, 0x07, 0x01, 0xff, 0x01, 0xf7, - 0x05, 0xff, 0x01, 0x5d, 0x02, 0xff, 0x01, 0xf4, 0x07, 0x00, 0x01, 0x07, - 0x01, 0xff, 0x01, 0xf3, 0x01, 0x5f, 0x03, 0xff, 0x01, 0xf5, 0x01, 0x06, - 0x02, 0xff, 0x01, 0xf4, 0x07, 0x00, 0x01, 0x07, 0x01, 0xff, 0x01, 0xf3, - 0x01, 0x01, 0x01, 0x7c, 0x01, 0xdd, 0x01, 0xc7, 0x01, 0x10, 0x01, 0x00, - 0x01, 0x6c, 0x01, 0xdb, 0x01, 0x50, 0x07, 0x00, 0x01, 0x07, 0x01, 0xff, - 0x01, 0xf3, 0x10, 0x00, 0x01, 0x07, 0x01, 0xff, 0x01, 0xf3, 0x10, 0x00, - 0x01, 0x07, 0x01, 0xff, 0x01, 0xf3, 0x10, 0x00, 0x01, 0x07, 0x01, 0xff, - 0x01, 0xf3, 0x10, 0x00, 0x01, 0x07, 0x01, 0xff, 0x01, 0xf3, 0x10, 0x00, - 0x01, 0x07, 0x01, 0xff, 0x01, 0xf3, 0x10, 0x00, 0x01, 0x07, 0x01, 0xff, - 0x01, 0xf3, 0x10, 0x00, 0x01, 0x07, 0x01, 0xee, 0x01, 0xe3, 0x35, 0x00, - - /* 39 PILCROW_SIGN */ - 0x9c, 0x00, 0x01, 0x16, 0x01, 0x9b, 0x04, 0xcc, 0x01, 0xca, 0x0b, 0x00, - 0x01, 0x19, 0x06, 0xff, 0x01, 0xfd, 0x0a, 0x00, 0x01, 0x03, 0x01, 0xef, - 0x03, 0xff, 0x01, 0xfb, 0x01, 0xaa, 0x01, 0xaf, 0x01, 0xfd, 0x0a, 0x00, - 0x01, 0x2e, 0x04, 0xff, 0x01, 0xf2, 0x01, 0x00, 0x01, 0x0f, 0x01, 0xfd, - 0x0a, 0x00, 0x01, 0xbf, 0x04, 0xff, 0x01, 0xf2, 0x01, 0x00, 0x01, 0x0f, - 0x01, 0xfd, 0x09, 0x00, 0x01, 0x03, 0x05, 0xff, 0x01, 0xf2, 0x01, 0x00, - 0x01, 0x0f, 0x01, 0xfd, 0x09, 0x00, 0x01, 0x08, 0x05, 0xff, 0x01, 0xf2, - 0x01, 0x00, 0x01, 0x0f, 0x01, 0xfd, 0x09, 0x00, 0x01, 0x0b, 0x05, 0xff, - 0x01, 0xf2, 0x01, 0x00, 0x01, 0x0f, 0x01, 0xfd, 0x09, 0x00, 0x01, 0x0c, - 0x05, 0xff, 0x01, 0xf2, 0x01, 0x00, 0x01, 0x0f, 0x01, 0xfd, 0x09, 0x00, - 0x01, 0x0b, 0x05, 0xff, 0x01, 0xf2, 0x01, 0x00, 0x01, 0x0f, 0x01, 0xfd, - 0x09, 0x00, 0x01, 0x0a, 0x05, 0xff, 0x01, 0xf2, 0x01, 0x00, 0x01, 0x0f, - 0x01, 0xfd, 0x09, 0x00, 0x01, 0x06, 0x05, 0xff, 0x01, 0xf2, 0x01, 0x00, - 0x01, 0x0f, 0x01, 0xfd, 0x0a, 0x00, 0x01, 0xef, 0x04, 0xff, 0x01, 0xf2, - 0x01, 0x00, 0x01, 0x0f, 0x01, 0xfd, 0x0a, 0x00, 0x01, 0x6f, 0x04, 0xff, - 0x01, 0xf2, 0x01, 0x00, 0x01, 0x0f, 0x01, 0xfd, 0x0a, 0x00, 0x01, 0x08, - 0x04, 0xff, 0x01, 0xf2, 0x01, 0x00, 0x01, 0x0f, 0x01, 0xfd, 0x0b, 0x00, - 0x01, 0x5e, 0x03, 0xff, 0x01, 0xf2, 0x01, 0x00, 0x01, 0x0f, 0x01, 0xfd, - 0x0c, 0x00, 0x01, 0x6b, 0x02, 0xff, 0x01, 0xf2, 0x01, 0x00, 0x01, 0x0f, - 0x01, 0xfd, 0x0d, 0x00, 0x01, 0x01, 0x01, 0xcf, 0x01, 0xf2, 0x01, 0x00, - 0x01, 0x0f, 0x01, 0xfd, 0x0e, 0x00, 0x01, 0xbf, 0x01, 0xf2, 0x01, 0x00, - 0x01, 0x0f, 0x01, 0xfd, 0x0e, 0x00, 0x01, 0xbf, 0x01, 0xf2, 0x01, 0x00, - 0x01, 0x0f, 0x01, 0xfd, 0x0e, 0x00, 0x01, 0xbf, 0x01, 0xf2, 0x01, 0x00, - 0x01, 0x0f, 0x01, 0xfd, 0x0e, 0x00, 0x01, 0xbf, 0x01, 0xf2, 0x01, 0x00, - 0x01, 0x0f, 0x01, 0xfd, 0x0e, 0x00, 0x01, 0xbf, 0x01, 0xf2, 0x01, 0x00, - 0x01, 0x0f, 0x01, 0xfd, 0x0e, 0x00, 0x01, 0xbf, 0x01, 0xf2, 0x01, 0x00, - 0x01, 0x0f, 0x01, 0xfd, 0x0e, 0x00, 0x01, 0xbf, 0x01, 0xf2, 0x01, 0x00, - 0x01, 0x0f, 0x01, 0xfd, 0x0e, 0x00, 0x01, 0xbf, 0x01, 0xf2, 0x01, 0x00, - 0x01, 0x0f, 0x01, 0xfd, 0x0e, 0x00, 0x01, 0xbf, 0x01, 0xf2, 0x01, 0x00, - 0x01, 0x0f, 0x01, 0xfd, 0x0e, 0x00, 0x01, 0xbf, 0x01, 0xf2, 0x01, 0x00, - 0x01, 0x0f, 0x01, 0xfd, 0x0e, 0x00, 0x01, 0xbf, 0x01, 0xf2, 0x01, 0x00, - 0x01, 0x0f, 0x01, 0xfd, 0x0e, 0x00, 0x01, 0xbf, 0x01, 0xf2, 0x01, 0x00, - 0x01, 0x0f, 0x01, 0xfd, 0x0e, 0x00, 0x01, 0xbf, 0x01, 0xf2, 0x01, 0x00, - 0x01, 0x0f, 0x01, 0xfd, 0x0e, 0x00, 0x01, 0xbf, 0x01, 0xf2, 0x01, 0x00, - 0x01, 0x0f, 0x01, 0xfd, 0x0e, 0x00, 0x01, 0xbf, 0x01, 0xf2, 0x01, 0x00, - 0x01, 0x0f, 0x01, 0xfd, 0x0e, 0x00, 0x01, 0xbf, 0x01, 0xf2, 0x01, 0x00, - 0x01, 0x0f, 0x01, 0xfd, 0x0e, 0x00, 0x01, 0x34, 0x01, 0x40, 0x01, 0x00, - 0x01, 0x04, 0x01, 0x43, 0x7a, 0x00, - - /* 40 BROKEN_BAR */ - 0xad, 0x00, 0x01, 0x07, 0x01, 0x99, 0x01, 0x60, 0x10, 0x00, 0x01, 0x0c, - 0x01, 0xff, 0x01, 0xa0, 0x10, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xa0, - 0x10, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xa0, 0x10, 0x00, 0x01, 0x0c, - 0x01, 0xff, 0x01, 0xa0, 0x10, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xa0, - 0x10, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xa0, 0x10, 0x00, 0x01, 0x0c, - 0x01, 0xff, 0x01, 0xa0, 0x10, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xa0, - 0x10, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xa0, 0x10, 0x00, 0x01, 0x0c, - 0x01, 0xff, 0x01, 0xa0, 0x10, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xa0, - 0x10, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xa0, 0x10, 0x00, 0x01, 0x0c, - 0x01, 0xff, 0x01, 0xa0, 0x10, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xa0, - 0x10, 0x00, 0x01, 0x08, 0x01, 0xbb, 0x01, 0x70, 0x6f, 0x00, 0x01, 0x0b, - 0x01, 0xff, 0x01, 0xa0, 0x10, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xa0, - 0x10, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xa0, 0x10, 0x00, 0x01, 0x0c, - 0x01, 0xff, 0x01, 0xa0, 0x10, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xa0, - 0x10, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xa0, 0x10, 0x00, 0x01, 0x0c, - 0x01, 0xff, 0x01, 0xa0, 0x10, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xa0, - 0x10, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xa0, 0x10, 0x00, 0x01, 0x0c, - 0x01, 0xff, 0x01, 0xa0, 0x10, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xa0, - 0x10, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xa0, 0x10, 0x00, 0x01, 0x0c, - 0x01, 0xff, 0x01, 0xa0, 0x10, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xa0, - 0x10, 0x00, 0x01, 0x0c, 0x01, 0xff, 0x01, 0xa0, 0x10, 0x00, 0x01, 0x04, - 0x01, 0x55, 0x01, 0x30, 0x47, 0x00, - - /* 41 SECTION_SIGN */ - 0x89, 0x00, 0x01, 0x35, 0x01, 0x64, 0x01, 0x31, 0x0e, 0x00, 0x01, 0x01, - 0x01, 0x9e, 0x03, 0xff, 0x01, 0xd9, 0x01, 0x30, 0x0c, 0x00, 0x01, 0x2e, - 0x05, 0xff, 0x01, 0xb0, 0x0c, 0x00, 0x01, 0xef, 0x01, 0xff, 0x01, 0xfb, - 0x01, 0x98, 0x01, 0xae, 0x01, 0xff, 0x01, 0xb0, 0x0b, 0x00, 0x01, 0x07, - 0x01, 0xff, 0x01, 0xfc, 0x01, 0x10, 0x02, 0x00, 0x01, 0x39, 0x01, 0xa0, - 0x0b, 0x00, 0x01, 0x0b, 0x01, 0xff, 0x01, 0xf2, 0x10, 0x00, 0x01, 0x0c, - 0x01, 0xff, 0x01, 0xf0, 0x10, 0x00, 0x01, 0x0a, 0x01, 0xff, 0x01, 0xf3, - 0x10, 0x00, 0x01, 0x06, 0x01, 0xff, 0x01, 0xfd, 0x01, 0x20, 0x10, 0x00, - 0x01, 0xdf, 0x01, 0xff, 0x01, 0xe4, 0x10, 0x00, 0x01, 0x1d, 0x02, 0xff, - 0x01, 0xa1, 0x0f, 0x00, 0x01, 0x4e, 0x03, 0xff, 0x01, 0x70, 0x0d, 0x00, - 0x01, 0x06, 0x01, 0xff, 0x01, 0xf9, 0x01, 0xdf, 0x01, 0xff, 0x01, 0xfd, - 0x01, 0x30, 0x0c, 0x00, 0x01, 0x3f, 0x01, 0xff, 0x01, 0x60, 0x01, 0x07, - 0x02, 0xff, 0x01, 0xf8, 0x0c, 0x00, 0x01, 0xbf, 0x01, 0xf9, 0x02, 0x00, - 0x01, 0x19, 0x02, 0xff, 0x01, 0xc0, 0x0b, 0x00, 0x01, 0xff, 0x01, 0xf3, - 0x03, 0x00, 0x01, 0x4e, 0x01, 0xff, 0x01, 0xfb, 0x0a, 0x00, 0x01, 0x01, - 0x01, 0xff, 0x01, 0xf2, 0x03, 0x00, 0x01, 0x01, 0x01, 0xdf, 0x01, 0xff, - 0x01, 0x40, 0x09, 0x00, 0x01, 0x01, 0x01, 0xff, 0x01, 0xf7, 0x04, 0x00, - 0x01, 0x2f, 0x01, 0xff, 0x01, 0x90, 0x0a, 0x00, 0x01, 0xdf, 0x01, 0xff, - 0x01, 0x20, 0x03, 0x00, 0x01, 0x0a, 0x01, 0xff, 0x01, 0xb0, 0x0a, 0x00, - 0x01, 0x6f, 0x01, 0xff, 0x01, 0xf5, 0x03, 0x00, 0x01, 0x08, 0x01, 0xff, - 0x01, 0xa0, 0x0a, 0x00, 0x01, 0x0a, 0x02, 0xff, 0x01, 0x91, 0x02, 0x00, - 0x01, 0x0c, 0x01, 0xff, 0x01, 0x70, 0x0b, 0x00, 0x01, 0x8f, 0x01, 0xff, - 0x01, 0xfe, 0x01, 0x60, 0x01, 0x00, 0x01, 0x6f, 0x01, 0xff, 0x01, 0x10, - 0x0b, 0x00, 0x01, 0x03, 0x01, 0xdf, 0x01, 0xff, 0x01, 0xfd, 0x01, 0x46, - 0x01, 0xff, 0x01, 0xf5, 0x0d, 0x00, 0x01, 0x07, 0x04, 0xff, 0x01, 0x50, - 0x0e, 0x00, 0x01, 0x2a, 0x02, 0xff, 0x01, 0xf5, 0x10, 0x00, 0x01, 0x4e, - 0x01, 0xff, 0x01, 0xfe, 0x01, 0x20, 0x0f, 0x00, 0x01, 0x01, 0x01, 0xcf, - 0x01, 0xff, 0x01, 0xc0, 0x10, 0x00, 0x01, 0x1e, 0x01, 0xff, 0x01, 0xf3, - 0x10, 0x00, 0x01, 0x06, 0x01, 0xff, 0x01, 0xf6, 0x10, 0x00, 0x01, 0x05, - 0x01, 0xff, 0x01, 0xf6, 0x0b, 0x00, 0x01, 0x01, 0x04, 0x00, 0x01, 0x0a, - 0x01, 0xff, 0x01, 0xf3, 0x0b, 0x00, 0x01, 0x08, 0x01, 0xe8, 0x01, 0x20, - 0x01, 0x00, 0x01, 0x01, 0x01, 0x8f, 0x01, 0xff, 0x01, 0xe0, 0x0b, 0x00, - 0x01, 0x08, 0x01, 0xff, 0x01, 0xfe, 0x01, 0xcb, 0x01, 0xdf, 0x02, 0xff, - 0x01, 0x40, 0x0b, 0x00, 0x01, 0x08, 0x05, 0xff, 0x01, 0xf5, 0x0d, 0x00, - 0x01, 0x49, 0x01, 0xdf, 0x02, 0xff, 0x01, 0xe8, 0x01, 0x20, 0x0f, 0x00, - 0x01, 0x12, 0x01, 0x21, 0x7f, 0x00, - - /* 42 NOT_SIGN */ - 0xff, 0x00, 0x7f, 0x00, 0x01, 0x12, 0x0c, 0x22, 0x06, 0x00, 0x01, 0x9f, - 0x0c, 0xff, 0x01, 0x40, 0x05, 0x00, 0x01, 0x9f, 0x0c, 0xff, 0x01, 0x40, - 0x05, 0x00, 0x01, 0x9f, 0x0c, 0xff, 0x01, 0x40, 0x05, 0x00, 0x01, 0x24, - 0x0a, 0x44, 0x01, 0x6f, 0x01, 0xff, 0x01, 0x40, 0x10, 0x00, 0x01, 0x2f, - 0x01, 0xff, 0x01, 0x40, 0x10, 0x00, 0x01, 0x2f, 0x01, 0xff, 0x01, 0x40, - 0x10, 0x00, 0x01, 0x2f, 0x01, 0xff, 0x01, 0x40, 0x10, 0x00, 0x01, 0x2f, - 0x01, 0xff, 0x01, 0x40, 0x10, 0x00, 0x01, 0x2f, 0x01, 0xff, 0x01, 0x40, - 0x10, 0x00, 0x01, 0x2f, 0x01, 0xff, 0x01, 0x40, 0x10, 0x00, 0x01, 0x2f, - 0x01, 0xff, 0x01, 0x40, 0x10, 0x00, 0x01, 0x17, 0x01, 0x77, 0x01, 0x10, - 0xff, 0x00, 0x34, 0x00 -#endif // TOUCH_UI_UTF8_SYMBOLS -}; diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/pin_mappings.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/pin_mappings.h deleted file mode 100644 index 548c6c7439d4..000000000000 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/pin_mappings.h +++ /dev/null @@ -1,151 +0,0 @@ -/****************** - * 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: . * - ****************************************************************************/ - -#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 S6_TFT_PINMAP - #ifndef __MARLIN_FIRMWARE__ - #error "This pin mapping requires Marlin." - #endif - - #define CLCD_SPI_CS PC7 - #define CLCD_MOD_RESET PC6 -#endif - -#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 diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/advanced_settings_menu.cpp b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/advanced_settings_menu.cpp deleted file mode 100644 index 103dcc036481..000000000000 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/advanced_settings_menu.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/***************************** - * 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: . * - ****************************************************************************/ - -#include "../config.h" - -#if ENABLED(TOUCH_UI_FTDI_EVE) && !defined(TOUCH_UI_LULZBOT_BIO) - -#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 10 - #define GRID_COLS 2 - .enabled( - #if HAS_BED_PROBE - 1 - #endif - ) - .tag(2) .button( BTN_POS(1,1), BTN_SIZE(1,1), GET_TEXT_F(MSG_ZPROBE_ZOFFSET)) - .enabled( - #if HAS_CASE_LIGHT - 1 - #endif - ) - .tag(16).button( BTN_POS(1,6), BTN_SIZE(1,1), GET_TEXT_F(MSG_CASE_LIGHT)) - .tag(3) .button( BTN_POS(2,1), BTN_SIZE(1,1), GET_TEXT_F(MSG_STEPS_PER_MM)) - .enabled( - #if HAS_TRINAMIC - 1 - #endif - ) - .tag(13).button( BTN_POS(1,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_TMC_CURRENT)) - .enabled( - #if HAS_TRINAMIC - 1 - #endif - ) - .tag(14).button( BTN_POS(1,7), BTN_SIZE(2,1), GET_TEXT_F(MSG_TMC_HOMING_THRS)) - .enabled( - #if HOTENDS > 1 - 1 - #endif - ) - .tag(4) .button( BTN_POS(1,2), BTN_SIZE(1,1), GET_TEXT_F(MSG_OFFSETS_MENU)) - .enabled( - #if EITHER(LIN_ADVANCE, FILAMENT_RUNOUT_SENSOR) - 1 - #endif - ) - .tag(11).button( BTN_POS(1,3), BTN_SIZE(1,1), GET_TEXT_F(MSG_FILAMENT)) - .tag(12).button( BTN_POS(1,5), BTN_SIZE(1,1), GET_TEXT_F(MSG_LCD_ENDSTOPS)) - .tag(15).button( BTN_POS(2,6), BTN_SIZE(1,1), GET_TEXT_F(MSG_DISPLAY_MENU)) - .tag(9) .button( BTN_POS(1,8), BTN_SIZE(2,1), GET_TEXT_F(MSG_INTERFACE_SETTINGS)) - .tag(10).button( BTN_POS(1,9), BTN_SIZE(2,1), GET_TEXT_F(MSG_RESTORE_DEFAULTS)) - .tag(5) .button( BTN_POS(2,2), BTN_SIZE(1,1), GET_TEXT_F(MSG_VELOCITY)) - .tag(6) .button( BTN_POS(2,3), BTN_SIZE(1,1), GET_TEXT_F(MSG_ACCELERATION)) - #if DISABLED(CLASSIC_JERK) - .tag(7) .button( BTN_POS(2,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_JUNCTION_DEVIATION)) - #else - .tag(7) .button( BTN_POS(2,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_JERK)) - #endif - .enabled( - #if ENABLED(BACKLASH_GCODE) - 1 - #endif - ) - .tag(8).button( BTN_POS(2,5), BTN_SIZE(1,1), GET_TEXT_F(MSG_BACKLASH)) - .colors(action_btn) - .tag(1) .button( BTN_POS(1,10), BTN_SIZE(2,1), GET_TEXT_F(MSG_BACK)); - #undef GRID_COLS - #undef GRID_ROWS - #else - #define GRID_ROWS 6 - #define GRID_COLS 3 - .enabled( - #if HAS_BED_PROBE - 1 - #endif - ) - .tag(2) .button( BTN_POS(1,1), BTN_SIZE(1,1), GET_TEXT_F(MSG_ZPROBE_ZOFFSET)) - .enabled( - #if HAS_CASE_LIGHT - 1 - #endif - ) - .tag(16).button( BTN_POS(1,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_CASE_LIGHT)) - .enabled(1) - .tag(3) .button( BTN_POS(2,1), BTN_SIZE(1,1), GET_TEXT_F(MSG_STEPS_PER_MM)) - .enabled( - #if HAS_TRINAMIC - 1 - #endif - ) - .tag(13).button( BTN_POS(3,1), BTN_SIZE(1,1), GET_TEXT_F(MSG_TMC_CURRENT)) - .enabled( - #if HAS_TRINAMIC - 1 - #endif - ) - .tag(14).button( BTN_POS(3,2), BTN_SIZE(1,1), GET_TEXT_F(MSG_TMC_HOMING_THRS)) - .enabled( - #if ENABLED(BACKLASH_GCODE) - 1 - #endif - ) - .tag(8).button( BTN_POS(3,3), BTN_SIZE(1,1), GET_TEXT_F(MSG_BACKLASH)) - .enabled( - #if HOTENDS > 1 - 1 - #endif - ) - .tag(4) .button( BTN_POS(1,2), BTN_SIZE(1,1), GET_TEXT_F(MSG_OFFSETS_MENU)) - .tag(12).button( BTN_POS(3,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_LCD_ENDSTOPS)) - .tag(5) .button( BTN_POS(2,2), BTN_SIZE(1,1), GET_TEXT_F(MSG_VELOCITY)) - .tag(6) .button( BTN_POS(2,3), BTN_SIZE(1,1), GET_TEXT_F(MSG_ACCELERATION)) - #if DISABLED(CLASSIC_JERK) - .tag(7) .button( BTN_POS(2,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_JUNCTION_DEVIATION)) - #else - .tag(7) .button( BTN_POS(2,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_JERK)) - #endif - .tag(11).button( BTN_POS(1,3), BTN_SIZE(1,1), GET_TEXT_F(MSG_FILAMENT)) - .tag(15).button( BTN_POS(3,5), BTN_SIZE(1,1), GET_TEXT_F(MSG_DISPLAY_MENU)) - .tag(9) .button( BTN_POS(1,5), BTN_SIZE(2,1), GET_TEXT_F(MSG_INTERFACE_SETTINGS)) - .tag(10).button( BTN_POS(1,6), BTN_SIZE(2,1), GET_TEXT_F(MSG_RESTORE_DEFAULTS)) - .colors(action_btn) - .tag(1) .button( BTN_POS(3,6), BTN_SIZE(1,1), GET_TEXT_F(MSG_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 DISABLED(CLASSIC_JERK) - 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 EITHER(LIN_ADVANCE, 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; - #if HAS_CASE_LIGHT - case 16: GOTO_SCREEN(CaseLightScreen); break; - #endif - default: return false; - } - return true; -} - -#endif // TOUCH_UI_FTDI_EVE diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/main_menu.cpp b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/main_menu.cpp deleted file mode 100644 index 016996e26579..000000000000 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/main_menu.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/***************** - * main_menu.cpp * - *****************/ - -/**************************************************************************** - * Written By Mark Pelletier 2017 - Aleph Objects, Inc. * - * Written By Marcio Teixeira 2018 - Aleph Objects, Inc. * - * Written By Marcio Teixeira 2019 - Cocoa Press * - * * - * 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: . * - ****************************************************************************/ - -#include "../config.h" - -#if ENABLED(TOUCH_UI_FTDI_EVE) && !defined(TOUCH_UI_LULZBOT_BIO) - -#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), GET_TEXT_F(MSG_AUTO_HOME)) - .enabled( - #if ENABLED(NOZZLE_CLEAN_FEATURE) - 1 - #endif - ) - .tag(3).button( BTN_POS(2,1), BTN_SIZE(1,1), GET_TEXT_F(MSG_CLEAN_NOZZLE)) - .tag(4).button( BTN_POS(1,2), BTN_SIZE(1,1), GET_TEXT_F(MSG_MOVE_AXIS)) - .tag(5).button( BTN_POS(2,2), BTN_SIZE(1,1), GET_TEXT_F(MSG_DISABLE_STEPPERS)) - .tag(6).button( BTN_POS(1,3), BTN_SIZE(2,1), GET_TEXT_F(MSG_TEMPERATURE)) - .enabled( - #if NONE(TOUCH_UI_LULZBOT_BIO, TOUCH_UI_COCOA_PRESS) - 1 - #endif - ) - .tag(7).button( BTN_POS(1,4), BTN_SIZE(2,1), GET_TEXT_F(MSG_FILAMENTCHANGE)) - .tag(8).button( BTN_POS(1,5), BTN_SIZE(2,1), GET_TEXT_F(MSG_ADVANCED_SETTINGS)) - .enabled( - #ifdef PRINTCOUNTER - 1 - #endif - ) - .tag(9).button( BTN_POS(1,7), BTN_SIZE(2,1), GET_TEXT_F(MSG_INFO_STATS_MENU)) - .tag(10).button( BTN_POS(1,6), BTN_SIZE(2,1), GET_TEXT_F(MSG_INFO_MENU)) - .colors(action_btn) - .tag(1).button( BTN_POS(1,8), BTN_SIZE(2,1), GET_TEXT_F(MSG_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), GET_TEXT_F(MSG_AUTO_HOME)) - #if ENABLED(TOUCH_UI_COCOA_PRESS) - .tag(3).button( BTN_POS(2,1), BTN_SIZE(1,1), GET_TEXT_F(MSG_PREHEAT_1)) - #else - .enabled( - #if ENABLED(NOZZLE_CLEAN_FEATURE) - 1 - #endif - ) - .tag(3).button( BTN_POS(2,1), BTN_SIZE(1,1), GET_TEXT_F(MSG_CLEAN_NOZZLE)) - #endif - .tag(4).button( BTN_POS(1,2), BTN_SIZE(1,1), GET_TEXT_F(MSG_MOVE_AXIS)) - .tag(5).button( BTN_POS(2,2), BTN_SIZE(1,1), GET_TEXT_F(MSG_DISABLE_STEPPERS)) - .tag(6).button( BTN_POS(1,3), BTN_SIZE(1,1), GET_TEXT_F(MSG_TEMPERATURE)) - #if ENABLED(TOUCH_UI_COCOA_PRESS) - .tag(7).button( BTN_POS(2,3), BTN_SIZE(1,1), GET_TEXT_F(MSG_CASE_LIGHT)) - #else - .enabled( - #if DISABLED(TOUCH_UI_LULZBOT_BIO) - 1 - #endif - ) - .tag(7).button( BTN_POS(2,3), BTN_SIZE(1,1), GET_TEXT_F(MSG_FILAMENTCHANGE)) - #endif - .tag(8).button( BTN_POS(1,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_ADVANCED_SETTINGS)) - .enabled( - #ifdef PRINTCOUNTER - 1 - #endif - ) - .tag(9).button( BTN_POS(2,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_INFO_STATS_MENU)) - .tag(10).button( BTN_POS(1,5), BTN_SIZE(1,1), GET_TEXT_F(MSG_INFO_MENU)) - .colors(action_btn) - .tag(1).button( BTN_POS(2,5), BTN_SIZE(1,1), GET_TEXT_F(MSG_BACK)); - #undef GRID_COLS - #undef GRID_ROWS - #endif - } -} - -bool MainMenu::onTouchEnd(uint8_t tag) { - using namespace ExtUI; - - switch (tag) { - case 1: SaveSettingsDialogBox::promptToSaveSettings(); break; - case 2: SpinnerDialogBox::enqueueAndWait_P(F("G28")); break; - #if ENABLED(TOUCH_UI_COCOA_PRESS) - case 3: GOTO_SCREEN(PreheatTimerScreen); break; - #elif 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; - #if ENABLED(TOUCH_UI_COCOA_PRESS) - case 7: GOTO_SCREEN(CaseLightScreen); break; - #else - case 7: GOTO_SCREEN(ChangeFilamentScreen); break; - #endif - 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 // TOUCH_UI_FTDI_EVE diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/stepper_current_screen.cpp b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/stepper_current_screen.cpp deleted file mode 100644 index acc94684e096..000000000000 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/stepper_current_screen.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/****************************** - * stepper_current_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: . * - ****************************************************************************/ - -#include "../config.h" - -#if ENABLED(TOUCH_UI_FTDI_EVE) && HAS_TRINAMIC - -#include "screens.h" - -using namespace FTDI; -using namespace ExtUI; -using namespace Theme; - -void StepperCurrentScreen::onRedraw(draw_mode_t what) { - widgets_t w(what); - w.precision(0); - w.units(GET_TEXT_F(MSG_UNITS_MILLIAMP)); - w.heading( GET_TEXT_F(MSG_TMC_CURRENT)); - w.color(x_axis) .adjuster( 2, GET_TEXT_F(MSG_AXIS_X), getAxisCurrent_mA(X) ); - w.color(y_axis) .adjuster( 4, GET_TEXT_F(MSG_AXIS_Y), getAxisCurrent_mA(Y) ); - w.color(z_axis) .adjuster( 6, GET_TEXT_F(MSG_AXIS_Z), getAxisCurrent_mA(Z) ); - #if EXTRUDERS == 1 - w.color(e_axis).adjuster( 8, GET_TEXT_F(MSG_AXIS_E), getAxisCurrent_mA(E0) ); - #elif EXTRUDERS > 1 - w.color(e_axis).adjuster( 8, GET_TEXT_F(MSG_AXIS_E1), getAxisCurrent_mA(E0) ); - w.color(e_axis).adjuster(10, GET_TEXT_F(MSG_AXIS_E2), getAxisCurrent_mA(E1) ); - #if EXTRUDERS > 2 - w.color(e_axis).adjuster(12, GET_TEXT_F(MSG_AXIS_E3), getAxisCurrent_mA(E2) ); - #endif - #if EXTRUDERS > 3 - w.color(e_axis).adjuster(14, GET_TEXT_F(MSG_AXIS_E4), getAxisCurrent_mA(E3) ); - #endif - #endif - w.increments(); -} - -bool StepperCurrentScreen::onTouchHeld(uint8_t tag) { - const float increment = getIncrement(); - switch (tag) { - case 2: UI_DECREMENT(AxisCurrent_mA, X ); break; - case 3: UI_INCREMENT(AxisCurrent_mA, X ); break; - case 4: UI_DECREMENT(AxisCurrent_mA, Y ); break; - case 5: UI_INCREMENT(AxisCurrent_mA, Y ); break; - case 6: UI_DECREMENT(AxisCurrent_mA, Z ); break; - case 7: UI_INCREMENT(AxisCurrent_mA, Z ); break; - case 8: UI_DECREMENT(AxisCurrent_mA, E0); break; - case 9: UI_INCREMENT(AxisCurrent_mA, E0); break; - #if EXTRUDERS > 1 - case 10: UI_DECREMENT(AxisCurrent_mA, E1); break; - case 11: UI_INCREMENT(AxisCurrent_mA, E1); break; - #endif - #if EXTRUDERS > 2 - case 12: UI_DECREMENT(AxisCurrent_mA, E2); break; - case 13: UI_INCREMENT(AxisCurrent_mA, E2); break; - #endif - #if EXTRUDERS > 3 - case 14: UI_DECREMENT(AxisCurrent_mA, E3); break; - case 15: UI_INCREMENT(AxisCurrent_mA, E3); break; - #endif - default: - return false; - } - SaveSettingsDialogBox::settingsChanged(); - return true; -} - -#endif // TOUCH_UI_FTDI_EVE diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/tune_menu.cpp b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/tune_menu.cpp deleted file mode 100644 index 8b4f0942fb4a..000000000000 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/tune_menu.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/******************* - * 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: . * - ****************************************************************************/ - -#include "../config.h" - -#if ENABLED(TOUCH_UI_FTDI_EVE) && !defined(TOUCH_UI_LULZBOT_BIO) - -#include "screens.h" - -using namespace FTDI; -using namespace Theme; - -void TuneMenu::onRedraw(draw_mode_t what) { - if (what & BACKGROUND) { - CommandProcessor cmd; - cmd.cmd(CLEAR_COLOR_RGB(bg_color)) - .cmd(CLEAR(true,true,true)); - } - - #ifdef TOUCH_UI_PORTRAIT - #define GRID_ROWS 8 - #define GRID_COLS 2 - #else - #define GRID_ROWS 4 - #define GRID_COLS 2 - #endif - - if (what & FOREGROUND) { - using namespace ExtUI; - - CommandProcessor cmd; - cmd.colors(normal_btn) - .font(font_medium) - #ifdef TOUCH_UI_PORTRAIT - .tag(2).enabled(1) .button( BTN_POS(1,1), BTN_SIZE(2,1), GET_TEXT_F(MSG_TEMPERATURE)) - .tag(3).enabled(!isPrinting()).button( BTN_POS(1,2), BTN_SIZE(2,1), GET_TEXT_F(MSG_FILAMENTCHANGE)) - .enabled( - #if EITHER(LIN_ADVANCE, FILAMENT_RUNOUT_SENSOR) - 1 - #endif - ) - .tag(9).button( BTN_POS(1,3), BTN_SIZE(2,1), GET_TEXT_F(MSG_FILAMENT)) - #if ENABLED(BABYSTEPPING) - .tag(4).enabled(1) .button( BTN_POS(1,4), BTN_SIZE(2,1), GET_TEXT_F(MSG_NUDGE_NOZZLE)) - #else - .enabled( - #if HAS_BED_PROBE - 1 - #endif - ) - .tag(4) .button( BTN_POS(1,4), BTN_SIZE(2,1), GET_TEXT_F(MSG_ZPROBE_ZOFFSET)) - #endif - .tag(5).enabled(1) .button( BTN_POS(1,5), BTN_SIZE(2,1), GET_TEXT_F(MSG_PRINT_SPEED)) - .tag(isPrintingFromMediaPaused() ? 7 : 6) - .enabled( - #if ENABLED(SDSUPPORT) - isPrintingFromMedia() - #endif - ) - .button( BTN_POS(1,6), BTN_SIZE(2,1), isPrintingFromMediaPaused() ? GET_TEXT_F(MSG_RESUME_PRINT) : GET_TEXT_F(MSG_PAUSE_PRINT)) - .enabled( - #if ENABLED(SDSUPPORT) - isPrintingFromMedia() - #endif - ) - .tag(8) .button( BTN_POS(1,7), BTN_SIZE(2,1), GET_TEXT_F(MSG_STOP_PRINT)) - .tag(1).colors(action_btn) - .button( BTN_POS(1,8), BTN_SIZE(2,1), GET_TEXT_F(MSG_BACK)); - #else // TOUCH_UI_PORTRAIT - .tag(2).enabled(1) .button( BTN_POS(1,1), BTN_SIZE(1,1), GET_TEXT_F(MSG_TEMPERATURE)) - .tag(3).enabled(!isPrinting()).button( BTN_POS(1,2), BTN_SIZE(1,1), GET_TEXT_F(MSG_FILAMENTCHANGE)) - .enabled( - #if ENABLED(BABYSTEPPING) - isPrintingFromMedia() - #endif - ) - #if ENABLED(BABYSTEPPING) - .tag(4) .button( BTN_POS(2,1), BTN_SIZE(1,1), GET_TEXT_F(MSG_NUDGE_NOZZLE)) - #else - .enabled( - #if HAS_BED_PROBE - isPrintingFromMedia() - #endif - ) - .tag(4) .button( BTN_POS(1,4), BTN_SIZE(2,1), GET_TEXT_F(MSG_ZPROBE_ZOFFSET)) - #endif - .tag(5).enabled(1) .button( BTN_POS(2,2), BTN_SIZE(1,1), GET_TEXT_F(MSG_PRINT_SPEED)) - .tag(isPrintingFromMediaPaused() ? 7 : 6) - .enabled( - #if ENABLED(SDSUPPORT) - isPrintingFromMedia() - #endif - ) - .button( BTN_POS(1,3), BTN_SIZE(1,1), isPrintingFromMediaPaused() ? GET_TEXT_F(MSG_RESUME_PRINT) : GET_TEXT_F(MSG_PAUSE_PRINT)) - .enabled( - #if ENABLED(SDSUPPORT) - isPrintingFromMedia() - #endif - ) - .tag(8). button( BTN_POS(2,3), BTN_SIZE(1,1), GET_TEXT_F(MSG_STOP_PRINT)) - .enabled( - #if ANY(LIN_ADVANCE, FILAMENT_RUNOUT_SENSOR) - 1 - #endif - ) - .tag(9).button( BTN_POS(1,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_FILAMENT)) - .tag(1).colors(action_btn) .button( BTN_POS(2,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_BACK)); - #endif - } - #undef GRID_COLS - #undef GRID_ROWS -} - -bool TuneMenu::onTouchEnd(uint8_t tag) { - using namespace Theme; - using namespace ExtUI; - switch (tag) { - case 1: GOTO_PREVIOUS(); break; - case 2: GOTO_SCREEN(TemperatureScreen); break; - case 3: GOTO_SCREEN(ChangeFilamentScreen); break; - case 4: - #if ENABLED(BABYSTEPPING) - GOTO_SCREEN(NudgeNozzleScreen); - #elif HAS_BED_PROBE - GOTO_SCREEN(ZOffsetScreen); - #endif - break; - case 5: GOTO_SCREEN(FeedratePercentScreen); break; - case 6: sound.play(twinkle, PLAY_ASYNCHRONOUS); ExtUI::pausePrint(); GOTO_SCREEN(StatusScreen); break; - case 7: sound.play(twinkle, PLAY_ASYNCHRONOUS); ExtUI::resumePrint(); GOTO_SCREEN(StatusScreen); break; - case 8: - GOTO_SCREEN(ConfirmAbortPrintDialogBox); - current_screen.forget(); - PUSH_SCREEN(StatusScreen); - break; - #if EITHER(LIN_ADVANCE, FILAMENT_RUNOUT_SENSOR) - case 9: GOTO_SCREEN(FilamentMenu); break; - #endif - default: - return false; - } - return true; -} - -#endif // TOUCH_UI_FTDI_EVE diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/colors.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/colors.h deleted file mode 100644 index 933e91db80fd..000000000000 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/colors.h +++ /dev/null @@ -1,149 +0,0 @@ -/************ - * colors.h * - ************/ - -/**************************************************************************** - * Written By Mark Pelletier 2017 - Aleph Objects, Inc. * - * Written By Marcio Teixeira 2018 - Aleph Objects, Inc. * - * Written By Marcio Teixeira 2019 - Cocoa Press * - * * - * 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: . * - ****************************************************************************/ - -#pragma once - -namespace Theme { - #ifdef TOUCH_UI_LULZBOT_BIO - // The Lulzbot Bio uses the color PANTONE 2175C on the case silkscreen. - // This translates to HSL(208°, 100%, 39%) as an accent color on the GUI. - - constexpr int accent_hue = 208; - constexpr float accent_sat = 0.5; - - constexpr uint32_t logo_bg_rgb = 0xffffff; - constexpr uint32_t logo_fill_rgb = 0xffffff; - constexpr uint32_t logo_stroke_rgb = hsl_to_rgb(accent_hue, 1.0, 0.39); - #else - // The Lulzbot logo uses the color PANTONE 382c. - // This translates to HSL(68°, 68%, 52%) as an accent color on the GUI. - - constexpr int accent_hue = 68; - constexpr float accent_sat = 0.68; - - constexpr uint32_t logo_bg_rgb = hsl_to_rgb(accent_hue, 0.77, 0.64); - constexpr uint32_t logo_fill_rgb = hsl_to_rgb(accent_hue, 0.68, 0.52); // Lulzbot Green - constexpr uint32_t logo_stroke_rgb = 0x000000; - #endif - - // Shades of accent color - - #ifdef TOUCH_UI_COCOA_PRESS - constexpr uint32_t accent_color_1 = hsl_to_rgb(12.8,0.597,0.263); // Darkest - constexpr uint32_t accent_color_2 = hsl_to_rgb(12.8,0.597,0.263); - constexpr uint32_t accent_color_3 = hsl_to_rgb( 9.6,0.664,0.443); - constexpr uint32_t accent_color_4 = hsl_to_rgb(16.3,0.873,0.537); - constexpr uint32_t accent_color_5 = hsl_to_rgb(23.0,0.889,0.539); - constexpr uint32_t accent_color_6 = hsl_to_rgb(23.0,0.889,0.539); // Lightest - #else - constexpr uint32_t accent_color_1 = hsl_to_rgb(accent_hue, accent_sat, 0.26); // Darkest - constexpr uint32_t accent_color_2 = hsl_to_rgb(accent_hue, accent_sat, 0.39); - constexpr uint32_t accent_color_3 = hsl_to_rgb(accent_hue, accent_sat, 0.52); - constexpr uint32_t accent_color_4 = hsl_to_rgb(accent_hue, accent_sat, 0.65); - constexpr uint32_t accent_color_5 = hsl_to_rgb(accent_hue, accent_sat, 0.78); - constexpr uint32_t accent_color_6 = hsl_to_rgb(accent_hue, accent_sat, 0.91); // Lightest - #endif - - // Shades of gray - - constexpr float gray_sat = 0.14; - - constexpr uint32_t gray_color_1 = hsl_to_rgb(accent_hue, gray_sat, 0.26); // Darkest - constexpr uint32_t gray_color_2 = hsl_to_rgb(accent_hue, gray_sat, 0.39); - constexpr uint32_t gray_color_3 = hsl_to_rgb(accent_hue, gray_sat, 0.52); - constexpr uint32_t gray_color_4 = hsl_to_rgb(accent_hue, gray_sat, 0.65); - constexpr uint32_t gray_color_5 = hsl_to_rgb(accent_hue, gray_sat, 0.78); - constexpr uint32_t gray_color_6 = hsl_to_rgb(accent_hue, gray_sat, 0.91); // Lightest - - #if NONE(TOUCH_UI_LULZBOT_BIO, TOUCH_UI_COCOA_PRESS) - // Lulzbot TAZ Pro - constexpr uint32_t theme_darkest = gray_color_1; - constexpr uint32_t theme_dark = gray_color_2; - - constexpr uint32_t bg_color = theme_darkest; - constexpr uint32_t bg_text_disabled = theme_dark; - constexpr uint32_t bg_text_enabled = 0xFFFFFF; - constexpr uint32_t bg_normal = theme_darkest; - - constexpr uint32_t fg_normal = theme_dark; - constexpr uint32_t fg_action = accent_color_2; - constexpr uint32_t fg_disabled = theme_darkest; - #else - // Lulzbot Bio - constexpr uint32_t theme_darkest = accent_color_1; - constexpr uint32_t theme_dark = accent_color_4; - - constexpr uint32_t bg_color = 0xFFFFFF; - constexpr uint32_t bg_text_disabled = gray_color_1; - constexpr uint32_t bg_text_enabled = accent_color_1; - constexpr uint32_t bg_normal = accent_color_4; - - constexpr uint32_t fg_normal = accent_color_1; - constexpr uint32_t fg_action = accent_color_4; - constexpr uint32_t fg_disabled = gray_color_6; - - constexpr uint32_t shadow_rgb = gray_color_6; - constexpr uint32_t stroke_rgb = accent_color_1; - constexpr uint32_t fill_rgb = accent_color_3; - constexpr uint32_t syringe_rgb = accent_color_5; - #endif - - constexpr uint32_t x_axis = 0xFF0000; - constexpr uint32_t y_axis = 0x00BB00; - constexpr uint32_t z_axis = 0x0000BF; - constexpr uint32_t e_axis = gray_color_2; - constexpr uint32_t feedrate = gray_color_2; - constexpr uint32_t other = gray_color_2; - - // Status screen - constexpr uint32_t progress = gray_color_2; - constexpr uint32_t status_msg = gray_color_2; - constexpr uint32_t fan_speed = 0x377198; - constexpr uint32_t temp = 0x892c78; - constexpr uint32_t axis_label = gray_color_2; - - constexpr uint32_t disabled_icon = gray_color_1; - - // Calibration Registers Screen - constexpr uint32_t transformA = 0x3010D0; - constexpr uint32_t transformB = 0x4010D0; - constexpr uint32_t transformC = 0x5010D0; - constexpr uint32_t transformD = 0x6010D0; - constexpr uint32_t transformE = 0x7010D0; - constexpr uint32_t transformF = 0x8010D0; - constexpr uint32_t transformVal = 0x104010; - - constexpr btn_colors disabled_btn = {.bg = bg_color, .grad = fg_disabled, .fg = fg_disabled, .rgb = fg_disabled }; - constexpr btn_colors normal_btn = {.bg = fg_action, .grad = 0xFFFFFF, .fg = fg_normal, .rgb = 0xFFFFFF }; - constexpr btn_colors action_btn = {.bg = bg_color, .grad = 0xFFFFFF, .fg = fg_action, .rgb = 0xFFFFFF }; - constexpr btn_colors red_btn = {.bg = 0xFF5555, .grad = 0xFFFFFF, .fg = 0xFF0000, .rgb = 0xFFFFFF }; - constexpr btn_colors ui_slider = {.bg = theme_darkest, .grad = 0xFFFFFF, .fg = theme_dark, .rgb = accent_color_3 }; - constexpr btn_colors ui_toggle = {.bg = theme_darkest, .grad = 0xFFFFFF, .fg = theme_dark, .rgb = 0xFFFFFF }; - - // Temperature color scale - - const rgb_t cool_rgb ( 0, 0, 0); - const rgb_t low_rgb (128, 0, 0); - const rgb_t med_rgb (255, 128, 0); - const rgb_t high_rgb (255, 255, 128); -}; diff --git a/Marlin/src/lcd/extui/anycubic_chiron_lcd.cpp b/Marlin/src/lcd/extui/anycubic_chiron_lcd.cpp new file mode 100644 index 000000000000..a7f9a7a0c3e3 --- /dev/null +++ b/Marlin/src/lcd/extui/anycubic_chiron_lcd.cpp @@ -0,0 +1,121 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * lcd/extui/anycubic_chiron_lcd.cpp + * + * Anycubic Chiron TFT support for Marlin + */ + +#include "../../inc/MarlinConfigPre.h" + +#if ENABLED(ANYCUBIC_LCD_CHIRON) + +#include "ui_api.h" +#include "lib/anycubic_chiron/chiron_tft.h" + +using namespace Anycubic; + +namespace ExtUI { + + void onStartup() { Chiron.Startup(); } + + void onIdle() { Chiron.IdleLoop(); } + + void onPrinterKilled(PGM_P const error, PGM_P const component) { + Chiron.PrinterKilled(error,component); + } + + void onMediaInserted() { Chiron.MediaEvent(AC_media_inserted); } + void onMediaError() { Chiron.MediaEvent(AC_media_error); } + void onMediaRemoved() { Chiron.MediaEvent(AC_media_removed); } + + void onPlayTone(const uint16_t frequency, const uint16_t duration) { + #if ENABLED(SPEAKER) + ::tone(BEEPER_PIN, frequency, duration); + #endif + } + + void onPrintTimerStarted() { Chiron.TimerEvent(AC_timer_started); } + void onPrintTimerPaused() { Chiron.TimerEvent(AC_timer_paused); } + void onPrintTimerStopped() { Chiron.TimerEvent(AC_timer_stopped); } + void onFilamentRunout(const extruder_t) { Chiron.FilamentRunout(); } + void onUserConfirmRequired(const char * const msg) { Chiron.ConfirmationRequest(msg); } + void onStatusChanged(const char * const msg) { Chiron.StatusChange(msg); } + + void onFactoryReset() {} + + void onStoreSettings(char *buff) { + // Called when saving to EEPROM (i.e. M500). If the ExtUI needs + // permanent data to be stored, it can write up to eeprom_data_size bytes + // into buff. + + // Example: + // static_assert(sizeof(myDataStruct) <= ExtUI::eeprom_data_size); + // memcpy(buff, &myDataStruct, sizeof(myDataStruct)); + } + + void onLoadSettings(const char *buff) { + // Called while loading settings from EEPROM. If the ExtUI + // needs to retrieve data, it should copy up to eeprom_data_size bytes + // from buff + + // Example: + // static_assert(sizeof(myDataStruct) <= ExtUI::eeprom_data_size); + // memcpy(&myDataStruct, buff, sizeof(myDataStruct)); + } + + void onConfigurationStoreWritten(bool success) { + // Called after the entire EEPROM has been written, + // whether successful or not. + } + + void onConfigurationStoreRead(bool success) { + // Called after the entire EEPROM has been read, + // whether successful or not. + } + + #if HAS_MESH + void onMeshUpdate(const int8_t xpos, const int8_t ypos, const float zval) { + // Called when any mesh points are updated + //SERIAL_ECHOLNPAIR("onMeshUpdate() x:", xpos, " y:", ypos, " z:", zval); + } + + void onMeshUpdate(const int8_t xpos, const int8_t ypos, const ExtUI::probe_state_t state) { + // Called to indicate a special condition + //SERIAL_ECHOLNPAIR("onMeshUpdate() x:", xpos, " y:", ypos, " state:", state); + } + #endif + + #if ENABLED(POWER_LOSS_RECOVERY) + // Called on resume from power-loss + void onPowerLossResume() { Chiron.PowerLossRecovery(); } + #endif + + #if HAS_PID_HEATING + void onPidTuning(const result_t rst) { + // Called for temperature PID tuning result + } + #endif +} + +#endif // ANYCUBIC_LCD_CHIRON diff --git a/Marlin/src/lcd/extui/anycubic_i3mega_lcd.cpp b/Marlin/src/lcd/extui/anycubic_i3mega_lcd.cpp new file mode 100644 index 000000000000..15526d16fc21 --- /dev/null +++ b/Marlin/src/lcd/extui/anycubic_i3mega_lcd.cpp @@ -0,0 +1,104 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * anycubic_i3mega_lcd.cpp + */ + +#include "../../inc/MarlinConfigPre.h" + +#if ENABLED(ANYCUBIC_LCD_I3MEGA) + +#include "lib/anycubic_i3mega/anycubic_i3mega_lcd.h" +#include "ui_api.h" + +#include // for the ::tone() call + +namespace ExtUI { + + void onStartup() { AnycubicTFT.OnSetup(); } + void onIdle() { AnycubicTFT.OnCommandScan(); } + void onPrinterKilled(PGM_P const error, PGM_P const component) { AnycubicTFT.OnKillTFT(); } + void onMediaInserted() { AnycubicTFT.OnSDCardStateChange(true); } + void onMediaError() { AnycubicTFT.OnSDCardError(); } + void onMediaRemoved() { AnycubicTFT.OnSDCardStateChange(false); } + void onPlayTone(const uint16_t frequency, const uint16_t duration) { + #if ENABLED(SPEAKER) + ::tone(BEEPER_PIN, frequency, duration); + #endif + } + void onPrintTimerStarted() { AnycubicTFT.OnPrintTimerStarted(); } + void onPrintTimerPaused() { AnycubicTFT.OnPrintTimerPaused(); } + void onPrintTimerStopped() { AnycubicTFT.OnPrintTimerStopped(); } + void onFilamentRunout(const extruder_t extruder) { AnycubicTFT.OnFilamentRunout(); } + void onUserConfirmRequired(const char * const msg) { AnycubicTFT.OnUserConfirmRequired(msg); } + void onStatusChanged(const char * const msg) {} + void onFactoryReset() {} + + void onStoreSettings(char *buff) { + // Called when saving to EEPROM (i.e. M500). If the ExtUI needs + // permanent data to be stored, it can write up to eeprom_data_size bytes + // into buff. + + // Example: + // static_assert(sizeof(myDataStruct) <= ExtUI::eeprom_data_size); + // memcpy(buff, &myDataStruct, sizeof(myDataStruct)); + } + + void onLoadSettings(const char *buff) { + // Called while loading settings from EEPROM. If the ExtUI + // needs to retrieve data, it should copy up to eeprom_data_size bytes + // from buff + + // Example: + // static_assert(sizeof(myDataStruct) <= ExtUI::eeprom_data_size); + // memcpy(&myDataStruct, buff, sizeof(myDataStruct)); + } + + void onConfigurationStoreWritten(bool success) { + // Called after the entire EEPROM has been written, + // whether successful or not. + } + + void onConfigurationStoreRead(bool success) { + // Called after the entire EEPROM has been read, + // whether successful or not. + } + + void onMeshUpdate(const int8_t xpos, const int8_t ypos, const float zval) { + // Called when any mesh points are updated + } + + #if ENABLED(POWER_LOSS_RECOVERY) + void onPowerLossResume() { + // Called on resume from power-loss + } + #endif + + #if HAS_PID_HEATING + void onPidTuning(const result_t rst) { + // Called for temperature PID tuning result + } + #endif +} + +#endif // ANYCUBIC_LCD_I3MEGA diff --git a/Marlin/src/lcd/extui_dgus_lcd.cpp b/Marlin/src/lcd/extui/dgus_lcd.cpp similarity index 74% rename from Marlin/src/lcd/extui_dgus_lcd.cpp rename to Marlin/src/lcd/extui/dgus_lcd.cpp index 5c6f11d7cb48..d175b5acac9a 100644 --- a/Marlin/src/lcd/extui_dgus_lcd.cpp +++ b/Marlin/src/lcd/extui/dgus_lcd.cpp @@ -16,23 +16,24 @@ * 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 . + * along with this program. If not, see . * */ /** - * extui_dgus_lcd.cpp + * dgus_lcd.cpp * * DGUS implementation for Marlin by coldtobi, Feb-May 2019 */ -#include "../inc/MarlinConfigPre.h" +#include "../../inc/MarlinConfigPre.h" #if HAS_DGUS_LCD -#include "extensible_ui/ui_api.h" -#include "extensible_ui/lib/dgus/DGUSDisplay.h" -#include "extensible_ui/lib/dgus/DGUSDisplayDefinition.h" +#include "ui_api.h" +#include "lib/dgus/DGUSDisplay.h" +#include "lib/dgus/DGUSDisplayDef.h" +#include "lib/dgus/DGUSScreenHandler.h" extern const char NUL_STR[]; @@ -45,27 +46,15 @@ namespace ExtUI { void onIdle() { ScreenHandler.loop(); } - void onPrinterKilled(PGM_P error, PGM_P component) { + void onPrinterKilled(PGM_P const error, PGM_P const component) { ScreenHandler.sendinfoscreen(GET_TEXT(MSG_HALTED), error, NUL_STR, GET_TEXT(MSG_PLEASE_RESET), true, true, true, true); ScreenHandler.GotoScreen(DGUSLCD_SCREEN_KILL); while (!ScreenHandler.loop()); // Wait while anything is left to be sent } - void onMediaInserted() { - #if ENABLED(SDSUPPORT) - ScreenHandler.SDCardInserted(); - #endif - } - void onMediaError() { - #if ENABLED(SDSUPPORT) - ScreenHandler.SDCardError(); - #endif - } - void onMediaRemoved() { - #if ENABLED(SDSUPPORT) - ScreenHandler.SDCardRemoved(); - #endif - } + void onMediaInserted() { TERN_(SDSUPPORT, ScreenHandler.SDCardInserted()); } + void onMediaError() { TERN_(SDSUPPORT, ScreenHandler.SDCardError()); } + void onMediaRemoved() { TERN_(SDSUPPORT, ScreenHandler.SDCardRemoved()); } void onPlayTone(const uint16_t frequency, const uint16_t duration) {} void onPrintTimerStarted() {} @@ -118,12 +107,18 @@ namespace ExtUI { // whether successful or not. } - void onMeshUpdate(const int8_t xpos, const int8_t ypos, const float zval) { - // Called when any mesh points are updated - } + #if HAS_MESH + void onMeshUpdate(const int8_t xpos, const int8_t ypos, const float zval) { + // Called when any mesh points are updated + } + + void onMeshUpdate(const int8_t xpos, const int8_t ypos, const ExtUI::probe_state_t state) { + // Called to indicate a special condition + } + #endif #if ENABLED(POWER_LOSS_RECOVERY) - void OnPowerLossResume() { + void onPowerLossResume() { // Called on resume from power-loss ScreenHandler.GotoScreen(DGUSLCD_SCREEN_POWER_LOSS); } @@ -131,21 +126,20 @@ namespace ExtUI { #if HAS_PID_HEATING - void OnPidTuning(const result_t rst) { + void onPidTuning(const result_t rst) { // Called for temperature PID tuning result - SERIAL_ECHOLNPAIR("OnPidTuning:",rst); - switch(rst) { + switch (rst) { case PID_BAD_EXTRUDER_NUM: - ScreenHandler.setstatusmessagePGM(PSTR(STR_PID_BAD_EXTRUDER_NUM)); + ScreenHandler.setstatusmessagePGM(GET_TEXT(MSG_PID_BAD_EXTRUDER_NUM)); break; case PID_TEMP_TOO_HIGH: - ScreenHandler.setstatusmessagePGM(PSTR(STR_PID_TEMP_TOO_HIGH)); + ScreenHandler.setstatusmessagePGM(GET_TEXT(MSG_PID_TEMP_TOO_HIGH)); break; case PID_TUNING_TIMEOUT: - ScreenHandler.setstatusmessagePGM(PSTR(STR_PID_TIMEOUT)); + ScreenHandler.setstatusmessagePGM(GET_TEXT(MSG_PID_TIMEOUT)); break; case PID_DONE: - ScreenHandler.setstatusmessagePGM(PSTR(STR_PID_AUTOTUNE_FINISHED)); + ScreenHandler.setstatusmessagePGM(GET_TEXT(MSG_PID_AUTOTUNE_DONE)); break; } ScreenHandler.GotoScreen(DGUSLCD_SCREEN_MAIN); diff --git a/Marlin/src/lcd/extui_example.cpp b/Marlin/src/lcd/extui/example.cpp similarity index 86% rename from Marlin/src/lcd/extui_example.cpp rename to Marlin/src/lcd/extui/example.cpp index 5e65af73815e..a5ef5652bc0f 100644 --- a/Marlin/src/lcd/extui_example.cpp +++ b/Marlin/src/lcd/extui/example.cpp @@ -1,5 +1,5 @@ /********************* - * extui_example.cpp * + * example.cpp * *********************/ /**************************************************************************** @@ -16,14 +16,14 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ -#include "../inc/MarlinConfigPre.h" +#include "../../inc/MarlinConfigPre.h" #if BOTH(EXTUI_EXAMPLE, EXTENSIBLE_UI) -#include "extensible_ui/ui_api.h" +#include "ui_api.h" // To implement a new UI, complete the functions below and // read or update Marlin's state using the methods in the @@ -89,18 +89,24 @@ namespace ExtUI { // whether successful or not. } - void onMeshUpdate(const int8_t xpos, const int8_t ypos, const float zval) { - // Called when any mesh points are updated - } + #if HAS_MESH + void onMeshUpdate(const int8_t xpos, const int8_t ypos, const float zval) { + // Called when any mesh points are updated + } + + void onMeshUpdate(const int8_t xpos, const int8_t ypos, const ExtUI::probe_state_t state) { + // Called to indicate a special condition + } + #endif #if ENABLED(POWER_LOSS_RECOVERY) - void OnPowerLossResume() { + void onPowerLossResume() { // Called on resume from power-loss } #endif #if HAS_PID_HEATING - void OnPidTuning(const result_t rst) { + void onPidTuning(const result_t rst) { // Called for temperature PID tuning result } #endif diff --git a/Marlin/src/lcd/extui/lib/anycubic_chiron/FileNavigator.cpp b/Marlin/src/lcd/extui/lib/anycubic_chiron/FileNavigator.cpp new file mode 100644 index 000000000000..fb4c84abb485 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/anycubic_chiron/FileNavigator.cpp @@ -0,0 +1,162 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * lcd/extui/lib/FileNavigator.cpp + * + * Extensible_UI implementation for Anycubic Chiron + * Written By Nick Wells, 2020 [https://github.com/SwiftNick] + * (not affiliated with Anycubic, Ltd.) + */ + +/*************************************************************************** + * The AC panel wants files in block of 4 and can only display a flat list * + * This library allows full folder traversal. * + ***************************************************************************/ + +#include "../../../../inc/MarlinConfigPre.h" + +#if ENABLED(ANYCUBIC_LCD_CHIRON) + +#include "FileNavigator.h" +#include "chiron_tft.h" + +using namespace ExtUI; + +namespace Anycubic { + + FileList FileNavigator::filelist; // Instance of the Marlin file API + char FileNavigator::currentfoldername[MAX_PATH_LEN]; // Current folder path + uint16_t FileNavigator::lastindex; + uint8_t FileNavigator::folderdepth; + uint16_t FileNavigator::currentindex; // override the panel request + + FileNavigator::FileNavigator() { reset(); } + + void FileNavigator::reset() { + currentfoldername[0] = '\0'; + folderdepth = 0; + currentindex = 0; + lastindex = 0; + // Start at root folder + while (!filelist.isAtRootDir()) filelist.upDir(); + refresh(); + } + + void FileNavigator::refresh() { filelist.refresh(); } + + void FileNavigator::getFiles(uint16_t index) { + uint8_t files = 4; + if (index == 0) currentindex = 0; + + // Each time we change folder we reset the file index to 0 and keep track + // of the current position as the TFT panel isnt aware of folders trees. + if (index > 0) { + --currentindex; // go back a file to take account off the .. we added to the root. + if (index > lastindex) + currentindex += files; + else + currentindex = currentindex < 4 ? 0 : currentindex - files; + } + lastindex = index; + + #if ACDEBUG(AC_FILE) + SERIAL_ECHOLNPAIR("index=", index, " currentindex=", currentindex); + #endif + + if (currentindex == 0 && folderdepth > 0) { // Add a link to go up a folder + TFTSer.println("<<"); + TFTSer.println(".."); + files--; + } + + for (uint16_t seek = currentindex; seek < currentindex + files; seek++) { + if (filelist.seek(seek)) { + sendFile(); + #if ACDEBUG(AC_FILE) + SERIAL_ECHOLNPAIR("-", seek, " '", filelist.longFilename(), "' '", currentfoldername, "", filelist.shortFilename(), "'\n"); + #endif + } + } + } + + void FileNavigator::sendFile() { + // send the file and folder info to the panel + // this info will be returned when the file is selected + // Permitted special characters in file name -_*#~ + // Panel can display 22 characters per line + if (filelist.isDir()) { + //TFTSer.print(currentfoldername); + TFTSer.println(filelist.shortFilename()); + TFTSer.print(filelist.shortFilename()); + TFTSer.println("/"); + } + else { + // Logical Name + TFTSer.print("/"); + if (folderdepth > 0) TFTSer.print(currentfoldername); + + TFTSer.println(filelist.shortFilename()); + + // Display Name + TFTSer.println(filelist.longFilename()); + } + } + void FileNavigator::changeDIR(char *folder) { + #if ACDEBUG(AC_FILE) + SERIAL_ECHOLNPAIR("currentfolder: ", currentfoldername, " New: ", folder); + #endif + if (folderdepth >= MAX_FOLDER_DEPTH) return; // limit the folder depth + strcat(currentfoldername, folder); + strcat(currentfoldername, "/"); + filelist.changeDir(folder); + refresh(); + folderdepth++; + currentindex = 0; + } + + void FileNavigator::upDIR() { + filelist.upDir(); + refresh(); + folderdepth--; + currentindex = 0; + // Remove the last child folder from the stored path + if (folderdepth == 0) { + currentfoldername[0] = '\0'; + reset(); + } + else { + char *pos = nullptr; + for (uint8_t f = 0; f < folderdepth; f++) + pos = strchr(currentfoldername, '/'); + + *(pos + 1) = '\0'; + } + #if ACDEBUG(AC_FILE) + SERIAL_ECHOLNPAIR("depth: ", folderdepth, " currentfoldername: ", currentfoldername); + #endif + } + + char* FileNavigator::getCurrentFolderName() { return currentfoldername; } +} + +#endif // ANYCUBIC_LCD_CHIRON diff --git a/Marlin/src/lcd/extui/lib/anycubic_chiron/FileNavigator.h b/Marlin/src/lcd/extui/lib/anycubic_chiron/FileNavigator.h new file mode 100644 index 000000000000..8e03614a4649 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/anycubic_chiron/FileNavigator.h @@ -0,0 +1,56 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * lcd/extui/lib/FileNavigator.h + * + * Extensible_UI implementation for Anycubic Chiron + * Written By Nick Wells, 2020 [https://github.com/SwiftNick] + * (not affiliated with Anycubic, Ltd.) + */ + +#include "chiron_tft_defs.h" +#include "../../ui_api.h" + +using namespace ExtUI; + +namespace Anycubic { + class FileNavigator { + public: + FileNavigator(); + void reset(); + void getFiles(uint16_t); + void upDIR(); + void changeDIR(char *); + void sendFile(); + void refresh(); + char * getCurrentFolderName(); + private: + static FileList filelist; + static char currentfoldername[MAX_PATH_LEN]; + static uint16_t lastindex; + static uint8_t folderdepth; + static uint16_t currentindex; + }; + extern FileNavigator filenavigator; +} diff --git a/Marlin/src/lcd/extui/lib/anycubic_chiron/Tunes.cpp b/Marlin/src/lcd/extui/lib/anycubic_chiron/Tunes.cpp new file mode 100644 index 000000000000..f09c4db3f283 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/anycubic_chiron/Tunes.cpp @@ -0,0 +1,62 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * lcd/extui/lib/Tunes.cpp + * + * Extensible_UI implementation for Anycubic Chiron + * Written By Nick Wells, 2020 [https://github.com/SwiftNick] + * (not affiliated with Anycubic, Ltd.) + */ + +/*********************************************************************** + * A Utility to play tunes using the buzzer in the printer controller. * + * See Tunes.h for note and tune definitions. * + ***********************************************************************/ + +#include "../../../../inc/MarlinConfigPre.h" + +#if ENABLED(ANYCUBIC_LCD_CHIRON) + +#include "Tunes.h" +#include "../../ui_api.h" + +namespace Anycubic { + + void PlayTune(uint8_t beeperPin, const uint16_t *tune, uint8_t speed=1) { + uint8_t pos = 1; + uint16_t wholenotelen = tune[0] / speed; + do { + uint16_t freq = tune[pos]; + uint16_t notelen = wholenotelen / tune[pos + 1]; + + ::tone(beeperPin, freq, notelen); + ExtUI::delay_ms(notelen); + pos += 2; + + if (pos >= MAX_TUNE_LENGTH) break; + } while (tune[pos] != n_END); + } + +} + +#endif // ANYCUBIC_LCD_CHIRON diff --git a/Marlin/src/lcd/extui/lib/anycubic_chiron/Tunes.h b/Marlin/src/lcd/extui/lib/anycubic_chiron/Tunes.h new file mode 100644 index 000000000000..1bafec43adf3 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/anycubic_chiron/Tunes.h @@ -0,0 +1,224 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * lcd/extui/lib/Tunes.h + * + * Extensible_UI implementation for Anycubic Chiron + * Written By Nick Wells, 2020 [https://github.com/SwiftNick] + * (not affiliated with Anycubic, Ltd.) + */ + +/************************************************************************** + * Notes definition from https://pages.mtu.edu/~suits/NoteFreqCalcs.html * + * * + * The format of a tune is: * + * {,,, ,, ... } * + * * + * 1) The first value is the length of a whole note in milliseconds * + * 2) Then a sequence of pitch and duration pairs * + * 3) Finally the END marker so your tunes can be any length up to * + * MAX_TUNE_LEN * + *************************************************************************/ + +#include + +#define MAX_TUNE_LENGTH 128 + +// Special notes! +#define n_P 0 // silence or pause +#define n_END 10000 // end of tune marker + +// Note duration divisors +#define l_T1 1 +#define l_T2 2 +#define l_T3 3 +#define l_T4 4 +#define l_T8 8 +#define l_T16 16 + +// Note Frequency +#define n_C0 16 +#define n_CS0 17 +#define n_D0 18 +#define n_DS0 19 +#define n_E0 21 +#define n_F0 22 +#define n_FS0 23 +#define n_G0 25 +#define n_GS0 26 +#define n_A0 28 +#define n_AS0 29 +#define n_B0 31 +#define n_C1 33 +#define n_CS1 35 +#define n_D1 37 +#define n_DS1 39 +#define n_E1 41 +#define n_F1 44 +#define n_FS1 46 +#define n_G1 49 +#define n_GS1 52 +#define n_A1 55 +#define n_AS1 58 +#define n_B1 62 +#define n_C2 65 +#define n_CS2 69 +#define n_D2 73 +#define n_DS2 78 +#define n_E2 82 +#define n_F2 87 +#define n_FS2 93 +#define n_G2 98 +#define n_GS2 104 +#define n_A2 110 +#define n_AS2 117 +#define n_B2 123 +#define n_C3 131 +#define n_CS3 139 +#define n_D3 147 +#define n_DS3 156 +#define n_E3 165 +#define n_F3 175 +#define n_FS3 185 +#define n_G3 196 +#define n_GS3 208 +#define n_A3 220 +#define n_AS3 233 +#define n_B3 247 +#define n_C4 262 +#define n_CS4 277 +#define n_D4 294 +#define n_DS4 311 +#define n_E4 330 +#define n_F4 349 +#define n_FS4 370 +#define n_G4 392 +#define n_GS4 415 +#define n_A4 440 +#define n_AS4 466 +#define n_B4 494 +#define n_C5 523 +#define n_CS5 554 +#define n_D5 587 +#define n_DS5 622 +#define n_E5 659 +#define n_F5 698 +#define n_FS5 740 +#define n_G5 784 +#define n_GS5 831 +#define n_A5 880 +#define n_AS5 932 +#define n_B5 988 +#define n_C6 1047 +#define n_CS6 1109 +#define n_D6 1175 +#define n_DS6 1245 +#define n_E6 1319 +#define n_F6 1397 +#define n_FS6 1480 +#define n_G6 1568 +#define n_GS6 1661 +#define n_A6 1760 +#define n_AS6 1865 +#define n_B6 1976 +#define n_C7 2093 +#define n_CS7 2217 +#define n_D7 2349 +#define n_DS7 2489 +#define n_E7 2637 +#define n_F7 2794 +#define n_FS7 2960 +#define n_G7 3136 +#define n_GS7 3322 +#define n_A7 3520 +#define n_AS7 3729 +#define n_B7 3951 +#define n_C8 4186 +#define n_CS8 4435 +#define n_D8 4699 +#define n_DS8 4978 +#define n_E8 5274 +#define n_F8 5587 +#define n_FS8 5920 +#define n_G8 6272 +#define n_GS8 6645 +#define n_A8 7040 +#define n_AS8 7459 +#define n_B8 7902 + +namespace Anycubic { + + void PlayTune(uint8_t beeperPin, const uint16_t *tune, uint8_t speed); + + // Only uncomment the tunes you are using to save memory + // This will help you write tunes! + // https://www.apronus.com/music/flashpiano.htm + + const uint16_t SOS[] = { + 250, + n_G6,l_T3, n_P,l_T3, n_G6,l_T3, n_P,l_T3, n_G6,l_T3, n_P,l_T1, + n_G6,l_T1, n_P,l_T3, n_G6,l_T1, n_P,l_T3, n_G6,l_T1, n_P,l_T1, + n_G6,l_T3, n_P,l_T3, n_G6,l_T3, n_P,l_T3, n_G6,l_T3, n_P,l_T1, + n_END + }; + + const uint16_t BeepBeep[] = { + 500, + n_C7,l_T8, n_P,l_T16, n_C7,l_T8, n_P,l_T8, + n_END + }; + + const uint16_t BeepBeepBeeep[] = { + 1000, + n_G7,l_T4, n_P,l_T16, n_G7,l_T4, n_P,l_T8, n_G7,l_T2, + n_END + }; + + const uint16_t Anycubic_PowerOn[] = { + 1000, + n_F7,l_T8, n_P,l_T8, n_C7,l_T8, n_P,l_T8, n_D7,l_T8, n_P,l_T8, + n_E7,l_T8, n_P,l_T8, n_D7,l_T4, n_P,l_T4, n_G7,l_T4, n_P,l_T4, + n_A7,l_T2, n_P,l_T1, + n_END + }; + + const uint16_t GB_PowerOn[] = { + 500, + n_C6,l_T4, n_P,l_T16, n_C7,l_T2, n_P,l_T8, + n_END + }; + + const uint16_t Heater_Timedout[] = { + 1000, + n_C6,l_T1, + n_END + }; + + const uint16_t FilamentOut[] = { + 1000, + n_AS7,l_T4, n_P,l_T16, n_FS7,l_T2, + n_END + }; + +} diff --git a/Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft.cpp b/Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft.cpp new file mode 100644 index 000000000000..5e492573e70a --- /dev/null +++ b/Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft.cpp @@ -0,0 +1,896 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * lcd/extui/lib/chiron_tft.cpp + * + * Extensible_UI implementation for Anycubic Chiron + * Written By Nick Wells, 2020 [https://github.com/SwiftNick] + * (not affiliated with Anycubic, Ltd.) + */ + +#include "../../../../inc/MarlinConfigPre.h" + +#if ENABLED(ANYCUBIC_LCD_CHIRON) + +#include "chiron_tft.h" +#include "Tunes.h" +#include "FileNavigator.h" + +#include "../../../../gcode/queue.h" +#include "../../../../sd/cardreader.h" +#include "../../../../libs/numtostr.h" +#include "../../../../MarlinCore.h" +namespace Anycubic { + + printer_state_t ChironTFT::printer_state; + paused_state_t ChironTFT::pause_state; + heater_state_t ChironTFT::hotend_state; + heater_state_t ChironTFT::hotbed_state; + xy_uint8_t ChironTFT::selectedmeshpoint; + char ChironTFT::selectedfile[MAX_PATH_LEN]; + char ChironTFT::panel_command[MAX_CMND_LEN]; + uint8_t ChironTFT::command_len; + float ChironTFT::live_Zoffset; + file_menu_t ChironTFT::file_menu; + + ChironTFT::ChironTFT(){} + + void ChironTFT::Startup() { + selectedfile[0] = '\0'; + panel_command[0] = '\0'; + command_len = 0; + printer_state = AC_printer_idle; + pause_state = AC_paused_idle; + hotend_state = AC_heater_off; + hotbed_state = AC_heater_off; + live_Zoffset = 0.0; + file_menu = AC_menu_file; + + // Setup pins for powerloss detection + // Two IO pins are connected on the Trigorilla Board + // On a power interruption the OUTAGECON_PIN goes low. + + #if ENABLED(POWER_LOSS_RECOVERY) + OUT_WRITE(OUTAGECON_PIN, HIGH); + #endif + + // Filament runout is handled by Marlin settings in Configuration.h + // set FIL_RUNOUT_STATE HIGH // Pin state indicating that filament is NOT present. + // enable FIL_RUNOUT_PULLUP + + TFTSer.begin(115200); + + // Signal Board has reset + SendtoTFTLN(AC_msg_main_board_has_reset); + + safe_delay(200); + + // Enable levelling and Disable end stops during print + // as Z home places nozzle above the bed so we need to allow it past the end stops + injectCommands_P(AC_cmnd_enable_levelling); //M211 S0\n")); + + // Startup tunes are defined in Tunes.h + //PlayTune(BEEPER_PIN, Anycubic_PowerOn, 1); + PlayTune(BEEPER_PIN, GB_PowerOn, 1); + #if ACDEBUGLEVEL + SERIAL_ECHOLNPAIR("AC Debug Level ", ACDEBUGLEVEL); + #endif + SendtoTFTLN(AC_msg_ready); + } + + void ChironTFT::IdleLoop() { + if (ReadTFTCommand()) { + ProcessPanelRequest(); + command_len = 0; + } + CheckHeaters(); + } + + void ChironTFT::PrinterKilled(PGM_P error,PGM_P component) { + SendtoTFTLN(AC_msg_kill_lcd); + #if ACDEBUG(AC_MARLIN) + SERIAL_ECHOLNPAIR("PrinterKilled()\nerror: ", error , "\ncomponent: ", component); + #endif + } + + void ChironTFT::MediaEvent(media_event_t event) { + #if ACDEBUG(AC_MARLIN) + SERIAL_ECHOLNPAIR("ProcessMediaStatus() ", event); + #endif + switch (event) { + case AC_media_inserted: + SendtoTFTLN(AC_msg_sd_card_inserted); + break; + + case AC_media_removed: + SendtoTFTLN(AC_msg_sd_card_removed); + break; + + case AC_media_error: + SendtoTFTLN(AC_msg_no_sd_card); + break; + } + } + + void ChironTFT::TimerEvent(timer_event_t event) { + #if ACDEBUG(AC_MARLIN) + SERIAL_ECHOLNPAIR("TimerEvent() ", event); + SERIAL_ECHOLNPAIR("Printer State: ", printer_state); + #endif + + switch (event) { + case AC_timer_started: { + live_Zoffset = 0.0; // reset print offset + setSoftEndstopState(false); // disable endstops to print + printer_state = AC_printer_printing; + SendtoTFTLN(AC_msg_print_from_sd_card); + } break; + + case AC_timer_paused: { + printer_state = AC_printer_paused; + pause_state = AC_paused_idle; + SendtoTFTLN(AC_msg_paused); + } break; + + case AC_timer_stopped: { + if (printer_state != AC_printer_idle) { + printer_state = AC_printer_stopping; + SendtoTFTLN(AC_msg_print_complete); + } + setSoftEndstopState(true); // enable endstops + } break; + } + } + + void ChironTFT::FilamentRunout() { + #if ACDEBUG(AC_MARLIN) + SERIAL_ECHOLNPAIR("FilamentRunout() printer_state ", printer_state); + #endif + // 1 Signal filament out + SendtoTFTLN(isPrintingFromMedia() ? AC_msg_filament_out_alert : AC_msg_filament_out_block); + //printer_state = AC_printer_filament_out; + PlayTune(BEEPER_PIN, FilamentOut, 1); + } + + void ChironTFT::ConfirmationRequest(const char * const msg) { + // M108 continue + #if ACDEBUG(AC_MARLIN) + SERIAL_ECHOLNPAIR("ConfirmationRequest() ", msg, " printer_state:", printer_state); + #endif + switch (printer_state) { + case AC_printer_pausing: { + if ( (strcmp_P(msg, MARLIN_msg_print_paused) == 0 ) || (strcmp_P(msg, MARLIN_msg_nozzle_parked) == 0 ) ) { + SendtoTFTLN(AC_msg_paused); // enable continue button + printer_state = AC_printer_paused; + } + } break; + + case AC_printer_resuming_from_power_outage: + case AC_printer_printing: + case AC_printer_paused: { + // Heater timout, send acknowledgement + if (strcmp_P(msg, MARLIN_msg_heater_timeout) == 0 ) { + pause_state = AC_paused_heater_timed_out; + SendtoTFTLN(AC_msg_paused); // enable continue button + PlayTune(BEEPER_PIN,Heater_Timedout,1); + } + // Reheat finished, send acknowledgement + else if (strcmp_P(msg, MARLIN_msg_reheat_done) == 0 ) { + pause_state = AC_paused_idle; + SendtoTFTLN(AC_msg_paused); // enable continue button + } + // Filament Purging, send acknowledgement enter run mode + else if (strcmp_P(msg, MARLIN_msg_filament_purging) == 0 ) { + pause_state = AC_paused_purging_filament; + SendtoTFTLN(AC_msg_paused); // enable continue button + } + } break; + default: + break; + } + } + + void ChironTFT::StatusChange(const char * const msg) { + #if ACDEBUG(AC_MARLIN) + SERIAL_ECHOLNPAIR("StatusChange() ", msg); + SERIAL_ECHOLNPAIR("printer_state:", printer_state); + #endif + bool msg_matched = false; + // The only way to get printer status is to parse messages + // Use the state to minimise the work we do here. + switch (printer_state) { + case AC_printer_probing: { + // If probing completes ok save the mesh and park + if (strcmp_P(msg, MARLIN_msg_ready) == 0 ) { + injectCommands_P(PSTR("M500\nG27")); + SendtoTFTLN(AC_msg_probing_complete); + printer_state = AC_printer_idle; + msg_matched = true; + } + // If probing fails dont save the mesh raise the probe above the bad point + if (strcmp_P(msg, MARLIN_msg_probing_failed) == 0 ) { + PlayTune(BEEPER_PIN, BeepBeepBeeep, 1); + injectCommands_P(PSTR("G1 Z50 F500")); + SendtoTFTLN(AC_msg_probing_complete); + printer_state = AC_printer_idle; + msg_matched = true; + } + } break; + + case AC_printer_printing: { + if (strcmp_P(msg, MARLIN_msg_reheating) == 0 ) { + SendtoTFTLN(AC_msg_paused); // enable continue button + msg_matched = true; + } + } break; + + case AC_printer_pausing: { + if (strcmp_P(msg, MARLIN_msg_print_paused) == 0 ) { + SendtoTFTLN(AC_msg_paused); + printer_state = AC_printer_paused; + pause_state = AC_paused_idle; + msg_matched = true; + } + } break; + + case AC_printer_stopping: { + if (strcmp_P(msg, MARLIN_msg_print_aborted) == 0 ) { + SendtoTFTLN(AC_msg_stop); + printer_state = AC_printer_idle; + msg_matched = true; + } + } break; + default: + break; + } + + // If not matched earlier see if this was a heater message + if (!msg_matched) { + if (strcmp_P(msg, MARLIN_msg_extruder_heating) == 0) { + SendtoTFTLN(AC_msg_nozzle_heating); + hotend_state = AC_heater_temp_set; + } + else if (strcmp_P(msg, MARLIN_msg_bed_heating) == 0) { + SendtoTFTLN(AC_msg_bed_heating); + hotbed_state = AC_heater_temp_set; + } + } + } + + void ChironTFT::PowerLossRecovery() { + printer_state = AC_printer_resuming_from_power_outage; // Play tune to notify user we can recover. + PlayTune(BEEPER_PIN, SOS, 1); + SERIAL_ECHOLNPGM("Resuming from power outage..."); + SERIAL_ECHOLNPGM("Select SD file then press resume"); + } + + void ChironTFT::SendtoTFT(PGM_P str) { // A helper to print PROGMEN string to the panel + #if ACDEBUG(AC_SOME) + serialprintPGM(str); + #endif + while (const char c = pgm_read_byte(str++)) TFTSer.print(c); + } + + void ChironTFT::SendtoTFTLN(PGM_P str = nullptr) { + if (str != nullptr) { + #if ACDEBUG(AC_SOME) + SERIAL_ECHO("> "); + #endif + SendtoTFT(str); + #if ACDEBUG(AC_SOME) + SERIAL_EOL(); + #endif + } + TFTSer.println(""); + } + + bool ChironTFT::ReadTFTCommand() { + bool command_ready = false; + while( (TFTSer.available() > 0) && (command_len < MAX_CMND_LEN) ) { + panel_command[command_len] = TFTSer.read(); + if(panel_command[command_len] == '\n') { + command_ready = true; + break; + } + command_len++; + } + + if(command_ready) { + panel_command[command_len] = 0x00; + #if ACDEBUG(AC_ALL) + SERIAL_ECHOLNPAIR("< ", panel_command); + #endif + #if ACDEBUG(AC_SOME) + // Ignore status request commands + uint8_t req = atoi(&panel_command[1]); + if (req > 7 && req != 20) { + SERIAL_ECHOLNPAIR("> ", panel_command); + SERIAL_ECHOLNPAIR("printer_state:", printer_state); + } + #endif + } + return command_ready; + } + + int8_t ChironTFT::Findcmndpos(const char * buff, char q) { + bool found = false; + int8_t pos = 0; + do { + if (buff[pos] == q) { + found = true; + break; + } + pos ++; + } while(pos < MAX_CMND_LEN); + if (found) return pos; + return -1; + } + + void ChironTFT::CheckHeaters() { + uint8_t faultDuration = 0; float temp = 0; + + // if the hotend temp is abnormal, confirm state before signalling panel + temp = getActualTemp_celsius(E0); + if ( (temp <= HEATER_0_MINTEMP) || (temp >= HEATER_0_MAXTEMP) ) { + do { + faultDuration ++; + if (faultDuration >= AC_HEATER_FAULT_VALIDATION_TIME) { + SendtoTFTLN(AC_msg_nozzle_temp_abnormal); + SERIAL_ECHOLNPAIR("Extruder temp abnormal! : ", temp); + break; + } + delay_ms(500); + temp = getActualTemp_celsius(E0); + } while ((temp <= HEATER_0_MINTEMP) || (temp >= HEATER_0_MAXTEMP) ); + } + + // if the hotbed temp is abnormal, confirm state before signalling panel + faultDuration = 0; + temp = getActualTemp_celsius(BED); + if ( (temp <= BED_MINTEMP) || (temp >= BED_MAXTEMP) ) { + do { + faultDuration ++; + if (faultDuration >= AC_HEATER_FAULT_VALIDATION_TIME) { + SendtoTFTLN(AC_msg_nozzle_temp_abnormal); + SERIAL_ECHOLNPAIR_P("Bed temp abnormal! : ", temp); + break; + } + delay_ms(500); + temp = getActualTemp_celsius(E0); + } while ((temp <= BED_MINTEMP) || (temp >= BED_MAXTEMP) ); + } + + // Update panel with hotend heater status + if (hotend_state != AC_heater_temp_reached) { + if ( WITHIN( getActualTemp_celsius(E0) - getTargetTemp_celsius(E0), -1, 1 ) ) { + SendtoTFTLN(AC_msg_nozzle_heating_done); + hotend_state = AC_heater_temp_reached; + } + } + + // Update panel with bed heater status + if (hotbed_state != AC_heater_temp_reached) { + if ( WITHIN( getActualTemp_celsius(BED) - getTargetTemp_celsius(BED), -0.5, 0.5 ) ) { + SendtoTFTLN(AC_msg_bed_heating_done); + hotbed_state = AC_heater_temp_reached; + } + } + } + + void ChironTFT::SendFileList(int8_t startindex) { + // respond to panel request for 4 files starting at index + #if ACDEBUG(AC_INFO) + SERIAL_ECHOLNPAIR("## SendFileList ## ", startindex); + #endif + SendtoTFTLN(PSTR("FN ")); + filenavigator.getFiles(startindex); + SendtoTFTLN(PSTR("END")); + } + + void ChironTFT::SelectFile() { + strncpy(selectedfile,panel_command+4,command_len-4); + selectedfile[command_len-5] = '\0'; + #if ACDEBUG(AC_FILE) + SERIAL_ECHOLNPAIR_F(" Selected File: ",selectedfile); + #endif + switch (selectedfile[0]) { + case '/': // Valid file selected + SendtoTFTLN(AC_msg_sd_file_open_success); + break; + + case '<': // .. (go up folder level) + filenavigator.upDIR(); + SendtoTFTLN(AC_msg_sd_file_open_failed); + SendFileList( 0 ); + break; + default: // enter sub folder + filenavigator.changeDIR(selectedfile); + SendtoTFTLN(AC_msg_sd_file_open_failed); + SendFileList( 0 ); + break; + } + } + + void ChironTFT::InjectCommandandWait(PGM_P cmd) { + //injectCommands_P(cmnd); queue.enqueue_now_P(cmd); + //SERIAL_ECHOLN(PSTR("Inject>")); + } + + void ChironTFT::ProcessPanelRequest() { + // Break these up into logical blocks // as its easier to navigate than one huge switch case! + int8_t req = atoi(&panel_command[1]); + + // Information requests A0 - A8 and A33 + if (req <= 8 || req == 33) PanelInfo(req); + + // Simple Actions A9 - A28 + else if ( req <= 28) PanelAction(req); + + // Process Initiation + else if (req <= 34) PanelProcess(req); + + else SendtoTFTLN(); + } + + void ChironTFT::PanelInfo(uint8_t req) { + // information requests A0-A8 and A33 + switch (req) { + case 0: // A0 Get HOTEND Temp + SendtoTFT(PSTR("A0V ")); + TFTSer.println(getActualTemp_celsius(E0)); + break; + + case 1: // A1 Get HOTEND Target Temp + SendtoTFT(PSTR("A1V ")); + TFTSer.println(getTargetTemp_celsius(E0)); + break; + + case 2: // A2 Get BED Temp + SendtoTFT(PSTR("A2V ")); + TFTSer.println(getActualTemp_celsius(BED)); + break; + + case 3: // A3 Get BED Target Temp + SendtoTFT(PSTR("A3V ")); + TFTSer.println(getTargetTemp_celsius(BED)); + break; + + case 4: // A4 Get FAN Speed + SendtoTFT(PSTR("A4V ")); + TFTSer.println(getActualFan_percent(FAN0)); + break; + + case 5: // A5 Get Current Coordinates + SendtoTFT(PSTR("A5V X: ")); + TFTSer.print(getAxisPosition_mm(X)); + SendtoTFT(PSTR(" Y: ")); + TFTSer.print(getAxisPosition_mm(Y)); + SendtoTFT(PSTR(" Z: ")); + TFTSer.println(getAxisPosition_mm(Z)); + break; + + case 6: // A6 Get printing progress + if (isPrintingFromMedia()) { + SendtoTFT(PSTR("A6V ")); + TFTSer.println(ui8tostr2(getProgress_percent())); + + } + else + SendtoTFTLN(PSTR("A6V ---")); + break; + + case 7: { // A7 Get Printing Time + uint32_t time = getProgress_seconds_elapsed() / 60; + SendtoTFT(PSTR("A7V ")); + TFTSer.print(ui8tostr2(time / 60)); + SendtoTFT(PSTR(" H ")); + TFTSer.print(ui8tostr2(time % 60)); + SendtoTFT(PSTR(" M")); + #if ACDEBUG(AC_ALL) + SERIAL_ECHOLNPAIR("Print time ", ui8tostr2(time / 60), ":", ui8tostr2(time % 60)); + #endif + } break; + + case 8: // A8 Get SD Card list A8 S0 + if (!isMediaInserted()) safe_delay(500); + if (!isMediaInserted()) // Make sure the card is removed + SendtoTFTLN(AC_msg_no_sd_card); + else if (panel_command[3] == 'S') + SendFileList( atoi( &panel_command[4] ) ); + break; + + case 33: // A33 Get firmware info + SendtoTFT(PSTR("J33 ")); + SendtoTFTLN(PSTR(SHORT_BUILD_VERSION)); + break; + } + } + + void ChironTFT::PanelAction(uint8_t req) { + switch (req) { + case 9: // A9 Pause SD print + if (isPrintingFromMedia()) { + SendtoTFTLN(AC_msg_pause); + pausePrint(); + printer_state = AC_printer_pausing; + } + else + SendtoTFTLN(AC_msg_stop); + break; + + case 10: // A10 Resume SD Print + if (pause_state == AC_paused_idle || printer_state == AC_printer_resuming_from_power_outage) + resumePrint(); + else + setUserConfirmed(); + break; + + case 11: // A11 Stop SD print + if (isPrintingFromMedia()) { + printer_state = AC_printer_stopping; + stopPrint(); + } + else { + if (printer_state == AC_printer_resuming_from_power_outage) + injectCommands_P(PSTR("M1000 C\n")); // Cancel recovery + SendtoTFTLN(AC_msg_stop); + printer_state = AC_printer_idle; + } + break; + + case 12: // A12 Kill printer + kill(); // from marlincore.h + break; + + case 13: // A13 Select file + SelectFile(); + break; + + case 14: { // A14 Start Printing + // Allows printer to restart the job if we dont want to recover + if (printer_state == AC_printer_resuming_from_power_outage) { + injectCommands_P(PSTR("M1000 C\n")); // Cancel recovery + printer_state = AC_printer_idle; + } + #if ACDebugLevel >= 1 + SERIAL_ECHOLNPAIR_F("Print: ", selectedfile); + #endif + // the card library needs a path starting // but the File api doesn't... + char file[MAX_PATH_LEN]; + file[0] = '/'; + strcpy(file + 1, selectedfile); + printFile(file); + SendtoTFTLN(AC_msg_print_from_sd_card); + } break; + + case 15: // A15 Resuming from outage + if (printer_state == AC_printer_resuming_from_power_outage) + // Need to home here to restore the Z position + injectCommands_P(AC_cmnd_power_loss_recovery); + + injectCommands_P(PSTR("M1000\n")); // home and start recovery + break; + + case 16: { // A16 Set HotEnd temp A17 S170 + const float set_Htemp = atof(&panel_command[5]); + hotend_state = set_Htemp ? AC_heater_temp_set : AC_heater_off; + switch ((char)panel_command[4]) { + // Set Temp + case 'S': case 'C': setTargetTemp_celsius(set_Htemp, E0); + } + } break; + + case 17: { // A17 Set bed temp + const float set_Btemp = atof(&panel_command[5]); + hotbed_state = set_Btemp ? AC_heater_temp_set : AC_heater_off; + if (panel_command[4] == 'S') + setTargetTemp_celsius(set_Btemp, BED); + } break; + + case 18: // A18 Set Fan Speed + if (panel_command[4] == 'S') + setTargetFan_percent(atof(&panel_command[5]), FAN0); + break; + + case 19: // A19 Motors off + if (!isPrinting()) { + disable_all_steppers(); // from marlincore.h + SendtoTFTLN(AC_msg_ready); + } + break; + + case 20: // A20 Read/write print speed + if (panel_command[4] == 'S') + setFeedrate_percent(atoi(&panel_command[5])); + else { + SendtoTFT(PSTR("A20V ")); + TFTSer.println(getFeedrate_percent()); + } + break; + + case 21: // A21 Home Axis A21 X + if (!isPrinting()) { + switch ((char)panel_command[4]) { + case 'X': injectCommands_P(PSTR("G28 X\n")); break; + case 'Y': injectCommands_P(PSTR("G28 Y\n")); break; + case 'Z': injectCommands_P(PSTR("G28 Z\n")); break; + case 'C': injectCommands_P(PSTR("G28\n")); break; + } + } + break; + + case 22: // A22 Move Axis A22 Y +10F3000 + // Ignore request if printing + if (!isPrinting()) { + // setAxisPosition_mm() uses pre defined manual feedrates so ignore the feedrate from the panel + setSoftEndstopState(true); // enable endstops + float newposition = atof(&panel_command[6]); + + #if ACDEBUG(AC_ACTION) + SERIAL_ECHOLNPAIR("Nudge ", panel_command[4], " axis ", newposition); + #endif + + switch (panel_command[4]) { + case 'X': setAxisPosition_mm(getAxisPosition_mm(X) + newposition, X); break; + case 'Y': setAxisPosition_mm(getAxisPosition_mm(Y) + newposition, Y); break; + case 'Z': setAxisPosition_mm(getAxisPosition_mm(Z) + newposition, Z); break; + case 'E': // The only time we get this command is from the filament load/unload menu + // the standard movement is too slow so we will use the load unlod GCode to speed it up a bit + if (canMove(E0) && !commandsInQueue()) + injectCommands_P(newposition > 0 ? AC_cmnd_manual_load_filament : AC_cmnd_manual_unload_filament); + break; + } + } + break; + + case 23: // A23 Preheat PLA + // Ignore request if printing + if (!isPrinting()) { + // Temps defined in configuration.h + setTargetTemp_celsius(PREHEAT_1_TEMP_BED, BED); + setTargetTemp_celsius(PREHEAT_1_TEMP_HOTEND, E0); + SendtoTFTLN(); + hotbed_state = AC_heater_temp_set; + hotend_state = AC_heater_temp_set; + } + break; + + case 24: // A24 Preheat ABS + // Ignore request if printing + if (!isPrinting()) { + setTargetTemp_celsius(PREHEAT_2_TEMP_BED, BED); + setTargetTemp_celsius(PREHEAT_2_TEMP_HOTEND, E0); + SendtoTFTLN(); + hotbed_state = AC_heater_temp_set; + hotend_state = AC_heater_temp_set; + } + break; + + case 25: // A25 Cool Down + // Ignore request if printing + if (!isPrinting()) { + setTargetTemp_celsius(0, E0); + setTargetTemp_celsius(0, BED); + SendtoTFTLN(AC_msg_ready); + hotbed_state = AC_heater_off; + hotend_state = AC_heater_off; + } + break; + + case 26: // A26 Refresh SD + // M22 M21 maybe needed here to reset sd card + filenavigator.reset(); + break; + + case 27: // A27 Servo Angles adjust + break; + + case 28: // A28 Filament set A28 O/C + // Ignore request if printing + if (isPrinting()) break; + SendtoTFTLN(); + break; + } + } + + void ChironTFT::PanelProcess(uint8_t req) { + switch (req) { + case 29: { // A29 Read Mesh Point A29 X1 Y1 + xy_uint8_t pos; + float pos_z; + pos.x = atoi(&panel_command[5]); + pos.y = atoi(&panel_command[8]); + pos_z = getMeshPoint(pos); + + SendtoTFT(PSTR("A29V ")); + TFTSer.println(pos_z * 100); + if (!isPrinting()) { + setSoftEndstopState(true); // disable endstops + // If the same meshpoint is selected twice in a row, move the head to that ready for adjustment + if ((selectedmeshpoint.x == pos.x) && (selectedmeshpoint.y == pos.y)) { + if (!isPositionKnown()) + injectCommands_P(PSTR("G28\n")); // home + + if (isPositionKnown()) { + #if ACDEBUG(AC_INFO) + SERIAL_ECHOLNPAIR("Moving to mesh point at x: ", pos.x, " y: ", pos.y, " z: ", pos_z); + #endif + // Go up before moving + setAxisPosition_mm(3.0,Z); + + setAxisPosition_mm(17 + (93 * pos.x), X); + setAxisPosition_mm(20 + (93 * pos.y), Y); + setAxisPosition_mm(0.0, Z); + #if ACDEBUG(AC_INFO) + SERIAL_ECHOLNPAIR("Current Z: ", getAxisPosition_mm(Z)); + #endif + } + } + selectedmeshpoint.x = pos.x; + selectedmeshpoint.y = pos.y; + } + } break; + + case 30: { // A30 Auto leveling + if (panel_command[3] == 'S') { // Start probing + // Ignore request if printing + if (isPrinting()) + SendtoTFTLN(AC_msg_probing_not_allowed); // forbid auto leveling + else { + injectCommands_P(isMachineHomed() ? PSTR("G29") : PSTR("G28\nG29")); + printer_state = AC_printer_probing; + SendtoTFTLN(AC_msg_start_probing); + } + } + else SendtoTFTLN(AC_msg_start_probing); + } break; + + case 31: { // A31 Adjust all Probe Points + switch (panel_command[3]) { + case 'C': // Restore and apply original offsets + if (!isPrinting()) { + injectCommands_P(PSTR("M501\nM420 S1\n")); + selectedmeshpoint.x = 99; + selectedmeshpoint.y = 99; + } + break; + case 'D': // Save Z Offset tables and restore levelling state + if (!isPrinting()) { + setAxisPosition_mm(1.0,Z); + injectCommands_P(PSTR("M500\n")); + selectedmeshpoint.x = 99; + selectedmeshpoint.y = 99; + } + break; + case 'G': // Get current offset + SendtoTFT(PSTR("A31V ")); + // When printing use the live z Offset position + // we will use babystepping to move the print head + if (isPrinting()) + TFTSer.println(live_Zoffset); + else { + TFTSer.println(getZOffset_mm()); + selectedmeshpoint.x = 99; + selectedmeshpoint.y = 99; + } + break; + case 'S': { // Set offset (adjusts all points by value) + float Zshift = atof(&panel_command[4]); + setSoftEndstopState(false); // disable endstops + // Allow temporary Z position nudging during print + // From the levelling panel use the all points UI to adjust the print pos. + if (isPrinting()) { + #if ACDEBUG(AC_INFO) + SERIAL_ECHOLNPAIR("Change Zoffset from:", live_Zoffset, " to ", live_Zoffset + Zshift); + #endif + if (isAxisPositionKnown(Z)) { + #if ACDEBUG(AC_INFO) + const float currZpos = getAxisPosition_mm(Z); + SERIAL_ECHOLNPAIR("Nudge Z pos from ", currZpos, " to ", currZpos + constrain(Zshift, -0.05, 0.05)); + #endif + // Use babystepping to adjust the head position + int16_t steps = mmToWholeSteps(constrain(Zshift,-0.05,0.05), Z); + #if ACDEBUG(AC_INFO) + SERIAL_ECHOLNPAIR("Steps to move Z: ", steps); + #endif + babystepAxis_steps(steps, Z); + live_Zoffset += Zshift; + } + SendtoTFT(PSTR("A31V ")); + TFTSer.println(live_Zoffset); + } + else { + GRID_LOOP(x, y) { + const xy_uint8_t pos { x, y }; + const float currval = getMeshPoint(pos); + setMeshPoint(pos, constrain(currval + Zshift, AC_LOWEST_MESHPOINT_VAL, 2)); + } + const float currZOffset = getZOffset_mm(); + #if ACDEBUG(AC_INFO) + SERIAL_ECHOLNPAIR("Change probe offset from ", currZOffset, " to ", currZOffset + Zshift); + #endif + + setZOffset_mm(currZOffset + Zshift); + SendtoTFT(PSTR("A31V ")); + TFTSer.println(getZOffset_mm()); + + if (isAxisPositionKnown(Z)) { + // Move Z axis + const float currZpos = getAxisPosition_mm(Z); + #if ACDEBUG(AC_INFO) + SERIAL_ECHOLNPAIR("Move Z pos from ", currZpos, " to ", currZpos + constrain(Zshift, -0.05, 0.05)); + #endif + setAxisPosition_mm(currZpos+constrain(Zshift,-0.05,0.05),Z); + } + } + } break; + } // end switch + } break; + + case 32: { // A32 clean leveling beep flag + // Ignore request if printing + //if (isPrinting()) break; + //injectCommands_P(PSTR("M500\nM420 S1\nG1 Z10 F240\nG1 X0 Y0 F6000")); + //TFTSer.println(""); + } break; + + // A33 firmware info request seet PanelInfo() + + case 34: { // A34 Adjust single mesh point A34 C/S X1 Y1 V123 + if (panel_command[3] == 'C') { // Restore original offsets + injectCommands_P(PSTR("M501\nM420 S1")); + selectedmeshpoint.x = 99; + selectedmeshpoint.y = 99; + //printer_state = AC_printer_idle; + } + else { + xy_uint8_t pos; + pos.x = atoi(&panel_command[5]); + pos.y = atoi(&panel_command[8]); + + float currmesh = getMeshPoint(pos); + float newval = atof(&panel_command[11])/100; + #if ACDEBUG(AC_INFO) + SERIAL_ECHOLNPAIR("Change mesh point x:", pos.x, " y:", pos.y); + SERIAL_ECHOLNPAIR("from ", currmesh, " to ", newval); + #endif + // Update Meshpoint + setMeshPoint(pos,newval); + if ( (printer_state == AC_printer_idle) || (printer_state == AC_printer_probing) ) {//!isPrinting()) { + // if we are at the current mesh point indicated on the panel Move Z pos +/- 0.05mm ( The panel changes the mesh value by +/- 0.05mm on each button press) + if ((selectedmeshpoint.x == pos.x) && (selectedmeshpoint.y == pos.y)) { + setSoftEndstopState(false); + float currZpos = getAxisPosition_mm(Z); + #if ACDEBUG(AC_INFO) + SERIAL_ECHOLNPAIR("Move Z pos from ", currZpos, " to ", currZpos + constrain(newval - currmesh, -0.05, 0.05)); + #endif + setAxisPosition_mm(currZpos + constrain(newval - currmesh, -0.05, 0.05), Z); + } + } + } + } break; + } + } +} // namespace + +#endif // ANYCUBIC_LCD_CHIRON diff --git a/Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft.h b/Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft.h new file mode 100644 index 000000000000..267f2fe9783f --- /dev/null +++ b/Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft.h @@ -0,0 +1,77 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * lcd/extui/lib/chiron_tft.h + * + * Extensible_UI implementation for Anycubic Chiron + * Written By Nick Wells, 2020 [https://github.com/SwiftNick] + * (not affiliated with Anycubic, Ltd.) + */ + +#include "chiron_tft_defs.h" +#include "../../../../inc/MarlinConfigPre.h" +#include "../../ui_api.h" +namespace Anycubic { + + class ChironTFT { + static printer_state_t printer_state; + static paused_state_t pause_state; + static heater_state_t hotend_state; + static heater_state_t hotbed_state; + static xy_uint8_t selectedmeshpoint; + static char panel_command[MAX_CMND_LEN]; + static uint8_t command_len; + static char selectedfile[MAX_PATH_LEN]; + static float live_Zoffset; + static file_menu_t file_menu; + public: + ChironTFT(); + void Startup(); + void IdleLoop(); + void PrinterKilled(PGM_P,PGM_P); + void MediaEvent(media_event_t); + void TimerEvent(timer_event_t); + void FilamentRunout(); + void ConfirmationRequest(const char * const ); + void StatusChange(const char * const ); + void PowerLossRecovery(); + + private: + void SendtoTFT(PGM_P); + void SendtoTFTLN(PGM_P); + bool ReadTFTCommand(); + int8_t Findcmndpos(const char *, char); + void CheckHeaters(); + void SendFileList(int8_t); + void SelectFile(); + void InjectCommandandWait(PGM_P); + void ProcessPanelRequest(); + void PanelInfo(uint8_t); + void PanelAction(uint8_t); + void PanelProcess(uint8_t); + }; + + extern ChironTFT Chiron; + +} diff --git a/Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft_defs.h b/Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft_defs.h new file mode 100644 index 000000000000..937bdfde33b3 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft_defs.h @@ -0,0 +1,151 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * lcd/extui/lib/chiron_defs.h + * + * Extensible_UI implementation for Anycubic Chiron + * Written By Nick Wells, 2020 [https://github.com/SwiftNick] + * (not affiliated with Anycubic, Ltd.) + */ + +#pragma once +#include "../../../../inc/MarlinConfigPre.h" +//#define ACDEBUGLEVEL 255 + +#if ACDEBUGLEVEL + // Bit-masks for selective debug: + enum ACDebugMask : uint8_t { + AC_INFO = 1, + AC_ACTION = 2, + AC_FILE = 4, + AC_PANEL = 8, + AC_MARLIN = 16, + AC_SOME = 32, + AC_ALL = 64 + }; + #define ACDEBUG(mask) ( ((mask) & ACDEBUGLEVEL) == mask ) // Debug flag macro +#else + #define ACDEBUG(mask) false +#endif + +#define TFTSer LCD_SERIAL // Serial interface for TFT panel now uses marlinserial +#define MAX_FOLDER_DEPTH 4 // Limit folder depth TFT has a limit for the file path +#define MAX_CMND_LEN 16 * MAX_FOLDER_DEPTH // Maximum Length for a Panel command +#define MAX_PATH_LEN 16 * MAX_FOLDER_DEPTH // Maximum number of characters in a SD file path + +#define AC_HEATER_FAULT_VALIDATION_TIME 5 // number of 1/2 second loops before signalling a heater fault +#define AC_LOWEST_MESHPOINT_VAL -7.00 // The lowest value you can set for a single mesh point offset + + // TFT panel commands +#define AC_msg_sd_card_inserted PSTR("J00") +#define AC_msg_sd_card_removed PSTR("J01") +#define AC_msg_no_sd_card PSTR("J02") +#define AC_msg_usb_connected PSTR("J03") +#define AC_msg_print_from_sd_card PSTR("J04") +#define AC_msg_pause PSTR("J05") +#define AC_msg_nozzle_heating PSTR("J06") +#define AC_msg_nozzle_heating_done PSTR("J07") +#define AC_msg_bed_heating PSTR("J08") +#define AC_msg_bed_heating_done PSTR("J09") +#define AC_msg_nozzle_temp_abnormal PSTR("J10") +#define AC_msg_kill_lcd PSTR("J11") +#define AC_msg_ready PSTR("J12") +#define AC_msg_low_nozzle_temp PSTR("J13") +#define AC_msg_print_complete PSTR("J14") +#define AC_msg_filament_out_alert PSTR("J15") +#define AC_msg_stop PSTR("J16") +#define AC_msg_main_board_has_reset PSTR("J17") +#define AC_msg_paused PSTR("J18") +#define AC_msg_j19_unknown PSTR("J19") +#define AC_msg_sd_file_open_success PSTR("J20") +#define AC_msg_sd_file_open_failed PSTR("J21") +#define AC_msg_level_monitor_finished PSTR("J22") +#define AC_msg_filament_out_block PSTR("J23") +#define AC_msg_probing_not_allowed PSTR("J24") +#define AC_msg_probing_complete PSTR("J25") +#define AC_msg_start_probing PSTR("J26") +#define AC_msg_version PSTR("J27") + +#define MARLIN_msg_start_probing PSTR("Probing Point 1/25") +#define MARLIN_msg_probing_failed PSTR("Probing Failed") +#define MARLIN_msg_ready PSTR("3D Printer Ready.") +#define MARLIN_msg_print_paused PSTR("Print Paused") +#define MARLIN_msg_print_aborted PSTR("Print Aborted") +#define MARLIN_msg_extruder_heating PSTR("E Heating...") +#define MARLIN_msg_bed_heating PSTR("Bed Heating...") + +#define MARLIN_msg_nozzle_parked PSTR("Nozzle Parked") +#define MARLIN_msg_heater_timeout PSTR("Heater Timeout") +#define MARLIN_msg_reheating PSTR("Reheating...") +#define MARLIN_msg_reheat_done PSTR("Reheat finished.") +#define MARLIN_msg_filament_purging PSTR("Filament Purging...") +#define MARLIN_msg_special_pause PSTR("PB") +#define AC_cmnd_auto_unload_filament PSTR("M701") // Use Marlin unload routine +#define AC_cmnd_auto_load_filament PSTR("M702 M0 PB") // Use Marlin load routing then pause for user to clean nozzle + +#define AC_cmnd_manual_load_filament PSTR("M83\nG1 E50 F700\nM82") // replace the manual panel commands with something a little faster +#define AC_cmnd_manual_unload_filament PSTR("M83\nG1 E-50 F1200\nM82") +#define AC_cmnd_enable_levelling PSTR("M420 S1 V1") +#define AC_cmnd_power_loss_recovery PSTR("G28 X Y R5\nG28 Z") // Lift, home X and Y then home Z when in 'safe' position + +namespace Anycubic { + enum heater_state_t : uint8_t { + AC_heater_off, + AC_heater_temp_set, + AC_heater_temp_reached + }; + + enum paused_state_t : uint8_t { + AC_paused_heater_timed_out, + AC_paused_purging_filament, + AC_paused_idle + }; + + enum printer_state_t : uint8_t { + AC_printer_idle, + AC_printer_probing, + AC_printer_printing, + AC_printer_pausing, + AC_printer_paused, + AC_printer_stopping, + AC_printer_resuming_from_power_outage + }; + + enum timer_event_t : uint8_t { + AC_timer_started, + AC_timer_paused, + AC_timer_stopped + }; + + enum media_event_t : uint8_t { + AC_media_inserted, + AC_media_removed, + AC_media_error + }; + enum file_menu_t : uint8_t { + AC_menu_file, + AC_menu_command, + AC_menu_change_to_file, + AC_menu_change_to_command + }; +} diff --git a/Marlin/src/lcd/extui/lib/anycubic_i3mega/anycubic_i3mega_lcd.cpp b/Marlin/src/lcd/extui/lib/anycubic_i3mega/anycubic_i3mega_lcd.cpp new file mode 100644 index 000000000000..efbc57e68a80 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/anycubic_i3mega/anycubic_i3mega_lcd.cpp @@ -0,0 +1,1032 @@ +/** + * anycubic_i3mega_lcd.cpp --- Support for Anycubic i3 Mega TFT + * Created by Christian Hopp on 09.12.17. + * Improved by David Ramiro + * Converted to ext_iu by John BouAntoun 21 June 2020 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "../../../../inc/MarlinConfigPre.h" + +#if ENABLED(ANYCUBIC_LCD_I3MEGA) + +#include "anycubic_i3mega_lcd.h" +#include "../../ui_api.h" + +#include "../../../../libs/numtostr.h" +#include "../../../../module/motion.h" // for A20 read printing speed feedrate_percentage +#include "../../../../MarlinCore.h" // for quickstop_stepper and disable_steppers +#include "../../../../inc/MarlinConfig.h" + +// command sending macro's with debugging capability +#define SEND_PGM(x) send_P(PSTR(x)) +#define SENDLINE_PGM(x) sendLine_P(PSTR(x)) +#define SEND_PGM_VAL(x,y) (send_P(PSTR(x)), sendLine(i16tostr3rj(y))) +#define SEND(x) send(x) +#define SENDLINE(x) sendLine(x) +#if ENABLED(ANYCUBIC_LCD_DEBUG) + #define SENDLINE_DBG_PGM(x,y) (sendLine_P(PSTR(x)), SERIAL_ECHOLNPGM(y)) + #define SENDLINE_DBG_PGM_VAL(x,y,z) (sendLine_P(PSTR(x)), SERIAL_ECHOPGM(y), SERIAL_ECHOLN(z)) +#else + #define SENDLINE_DBG_PGM(x,y) sendLine_P(PSTR(x)) + #define SENDLINE_DBG_PGM_VAL(x,y,z) sendLine_P(PSTR(x)) +#endif + +AnycubicTFTClass AnycubicTFT; + +static void sendNewLine(void) { + LCD_SERIAL.write('\r'); + LCD_SERIAL.write('\n'); +} + +static void send(const char *str) { + LCD_SERIAL.print(str); +} + +static void sendLine(const char *str) { + send(str); + sendNewLine(); +} + +static void send_P(PGM_P str) { + while (const char c = pgm_read_byte(str++)) + LCD_SERIAL.write(c); +} + +static void sendLine_P(PGM_P str) { + send_P(str); + sendNewLine(); +} + +AnycubicTFTClass::AnycubicTFTClass() {} + +void AnycubicTFTClass::OnSetup() { + #ifndef LCD_BAUDRATE + #define LCD_BAUDRATE 115200 + #endif + LCD_SERIAL.begin(LCD_BAUDRATE); + + SENDLINE_DBG_PGM("J17", "TFT Serial Debug: Main board reset... J17"); // J17 Main board reset + ExtUI::delay_ms(10); + + // initialise the state of the key pins running on the tft + #if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_DETECT) + SET_INPUT_PULLUP(SD_DETECT_PIN); + #endif + #if ENABLED(FILAMENT_RUNOUT_SENSOR) + SET_INPUT_PULLUP(FIL_RUNOUT_PIN); + #endif + + mediaPrintingState = AMPRINTSTATE_NOT_PRINTING; + mediaPauseState = AMPAUSESTATE_NOT_PAUSED; + + // DoSDCardStateCheck(); + SENDLINE_DBG_PGM("J12", "TFT Serial Debug: Ready... J12"); // J12 Ready + ExtUI::delay_ms(10); + + DoFilamentRunoutCheck(); + SelectedFile[0] = 0; + + #if ENABLED(STARTUP_CHIME) + ExtUI::injectCommands_P(PSTR("M300 P250 S554\nM300 P250 S554\nM300 P250 S740\nM300 P250 S554\nM300 P250 S740\nM300 P250 S554\nM300 P500 S831")); + #endif + #if ENABLED(ANYCUBIC_LCD_DEBUG) + SERIAL_ECHOLNPGM("TFT Serial Debug: Finished startup"); + #endif +} + +void AnycubicTFTClass::OnCommandScan() { + static millis_t nextStopCheck = 0; // used to slow the stopped print check down to reasonable times + const millis_t ms = millis(); + if (ELAPSED(ms, nextStopCheck)) { + nextStopCheck = ms + 1000UL; + if (mediaPrintingState == AMPRINTSTATE_STOP_REQUESTED && IsNozzleHomed()) { + #if ENABLED(ANYCUBIC_LCD_DEBUG) + SERIAL_ECHOLNPGM("TFT Serial Debug: Finished stopping print, releasing motors ..."); + #endif + mediaPrintingState = AMPRINTSTATE_NOT_PRINTING; + mediaPauseState = AMPAUSESTATE_NOT_PAUSED; + ExtUI::injectCommands_P(PSTR("M84\nM27")); // disable stepper motors and force report of SD status + ExtUI::delay_ms(200); + // tell printer to release resources of print to indicate it is done + SENDLINE_DBG_PGM("J14", "TFT Serial Debug: SD Print Stopped... J14"); + } + } + + if (TFTbuflen < (TFTBUFSIZE - 1)) + GetCommandFromTFT(); + + if (TFTbuflen) { + TFTbuflen = (TFTbuflen - 1); + TFTbufindr = (TFTbufindr + 1) % TFTBUFSIZE; + } +} + +void AnycubicTFTClass::OnKillTFT() { + SENDLINE_DBG_PGM("J11", "TFT Serial Debug: Kill command... J11"); +} + +void AnycubicTFTClass::OnSDCardStateChange(bool isInserted) { + #if ENABLED(ANYCUBIC_LCD_DEBUG) + SERIAL_ECHOPGM("TFT Serial Debug: OnSDCardStateChange event triggered..."); + SERIAL_ECHO(ui8tostr2(isInserted)); + SERIAL_EOL(); + #endif + DoSDCardStateCheck(); +} + +void AnycubicTFTClass::OnSDCardError() { + #if ENABLED(ANYCUBIC_LCD_DEBUG) + SERIAL_ECHOLNPGM("TFT Serial Debug: OnSDCardError event triggered..."); + #endif + SENDLINE_DBG_PGM("J21", "TFT Serial Debug: On SD Card Error ... J21"); +} + +void AnycubicTFTClass::OnFilamentRunout() { + #if ENABLED(ANYCUBIC_LCD_DEBUG) + SERIAL_ECHOLNPGM("TFT Serial Debug: FilamentRunout triggered..."); + #endif + DoFilamentRunoutCheck(); +} + +void AnycubicTFTClass::OnUserConfirmRequired(const char * const msg) { + #if ENABLED(ANYCUBIC_LCD_DEBUG) + SERIAL_ECHOPGM("TFT Serial Debug: OnUserConfirmRequired triggered... "); + SERIAL_ECHOLN(msg); + #endif + + #if ENABLED(SDSUPPORT) + /** + * Need to handle the process of following states + * "Nozzle Parked" + * "Load Filament" + * "Filament Purging..." + * "HeaterTimeout" + * "Reheat finished." + * + * NOTE: The only way to handle these states is strcmp_P with the msg unfortunately (very expensive) + */ + if (strcmp_P(msg, PSTR("Nozzle Parked")) == 0) { + mediaPrintingState = AMPRINTSTATE_PAUSED; + mediaPauseState = AMPAUSESTATE_PARKED; + // enable continue button + SENDLINE_DBG_PGM("J18", "TFT Serial Debug: UserConfirm SD print paused done... J18"); + } + else if (strcmp_P(msg, PSTR("Load Filament")) == 0) { + mediaPrintingState = AMPRINTSTATE_PAUSED; + mediaPauseState = AMPAUSESTATE_FILAMENT_OUT; + // enable continue button + SENDLINE_DBG_PGM("J18", "TFT Serial Debug: UserConfirm Filament is out... J18"); + SENDLINE_DBG_PGM("J23", "TFT Serial Debug: UserConfirm Blocking filament prompt... J23"); + } + else if (strcmp_P(msg, PSTR("Filament Purging...")) == 0) { + mediaPrintingState = AMPRINTSTATE_PAUSED; + mediaPauseState = AMPAUSESTATE_PARKING; + // TODO: JBA I don't think J05 just disables the continue button, i think it injects a rogue M25. So taking this out + // disable continue button + // SENDLINE_DBG_PGM("J05", "TFT Serial Debug: UserConfirm SD Filament Purging... J05"); // J05 printing pause + + // enable continue button + SENDLINE_DBG_PGM("J18", "TFT Serial Debug: UserConfirm Filament is purging... J18"); + } + else if (strcmp_P(msg, PSTR("HeaterTimeout")) == 0) { + mediaPrintingState = AMPRINTSTATE_PAUSED; + mediaPauseState = AMPAUSESTATE_HEATER_TIMEOUT; + // enable continue button + SENDLINE_DBG_PGM("J18", "TFT Serial Debug: UserConfirm SD Heater timeout... J18"); + } + else if (strcmp_P(msg, PSTR("Reheat finished.")) == 0) { + mediaPrintingState = AMPRINTSTATE_PAUSED; + mediaPauseState = AMPAUSESTATE_REHEAT_FINISHED; + // enable continue button + SENDLINE_DBG_PGM("J18", "TFT Serial Debug: UserConfirm SD Reheat done... J18"); + } + #endif +} + +float AnycubicTFTClass::CodeValue() { + return (strtod(&TFTcmdbuffer[TFTbufindr][TFTstrchr_pointer - TFTcmdbuffer[TFTbufindr] + 1], NULL)); +} + +bool AnycubicTFTClass::CodeSeen(char code) { + TFTstrchr_pointer = strchr(TFTcmdbuffer[TFTbufindr], code); + return (TFTstrchr_pointer != NULL); // Return True if a character was found +} + +bool AnycubicTFTClass::IsNozzleHomed() { + const float xPosition = ExtUI::getAxisPosition_mm((ExtUI::axis_t) ExtUI::X); + const float yPosition = ExtUI::getAxisPosition_mm((ExtUI::axis_t) ExtUI::Y); + return WITHIN(xPosition, X_MIN_POS - 0.1, X_MIN_POS + 0.1) && + WITHIN(yPosition, Y_MIN_POS - 0.1, Y_MIN_POS + 0.1); +} + +void AnycubicTFTClass::HandleSpecialMenu() { + /** + * NOTE: that the file selection command actual lowercases the entire selected file/foldername, so charracter comparisons need to be lowercase. + */ + if (SelectedDirectory[0] == '<') { + switch (SelectedDirectory[1]) { + case 'e': // "" + SpecialMenu = false; + return; + break; + + #if ENABLED(PROBE_MANUALLY) + case '0': + switch (SelectedDirectory[2]) { + case '1': // "<01ZUp0.1>" + SERIAL_ECHOLNPGM("Special Menu: Z Up 0.1"); + ExtUI::injectCommands_P(PSTR("G91\nG1 Z+0.1\nG90")); + break; + + case '2': // "<02ZUp0.02>" + SERIAL_ECHOLNPGM("Special Menu: Z Up 0.02"); + ExtUI::injectCommands_P(PSTR("G91\nG1 Z+0.02\nG90")); + break; + + case '3': // "<03ZDn0.02>" + SERIAL_ECHOLNPGM("Special Menu: Z Down 0.02"); + ExtUI::injectCommands_P(PSTR("G91\nG1 Z-0.02\nG90")); + break; + + case '4': // "<04ZDn0.1>" + SERIAL_ECHOLNPGM("Special Menu: Z Down 0.1"); + ExtUI::injectCommands_P(PSTR("G91\nG1 Z-0.1\nG90")); + break; + + case '5': // "<05PrehtBed>" + SERIAL_ECHOLNPGM("Special Menu: Preheat Bed"); + ExtUI::injectCommands_P(PSTR("M140 S65")); + break; + + case '6': // "<06SMeshLvl>" + SERIAL_ECHOLNPGM("Special Menu: Start Mesh Leveling"); + ExtUI::injectCommands_P(PSTR("G29 S1")); + break; + + case '7': // "<07MeshNPnt>" + SERIAL_ECHOLNPGM("Special Menu: Next Mesh Point"); + ExtUI::injectCommands_P(PSTR("G29 S2")); + break; + + case '8': // "<08HtEndPID>" + SERIAL_ECHOLNPGM("Special Menu: Auto Tune Hotend PID"); + // need to dwell for half a second to give the fan a chance to start before the pid tuning starts + ExtUI::injectCommands_P(PSTR("M106 S204\nG4 P500\nM303 E0 S215 C15 U1")); + break; + + case '9': // "<09HtBedPID>" + SERIAL_ECHOLNPGM("Special Menu: Auto Tune Hotbed Pid"); + ExtUI::injectCommands_P(PSTR("M303 E-1 S65 C6 U1")); + break; + + default: + break; + } + break; + + case '1': + switch (SelectedDirectory[2]) { + case '0': // "<10FWDeflts>" + SERIAL_ECHOLNPGM("Special Menu: Load FW Defaults"); + ExtUI::injectCommands_P(PSTR("M502\nM300 P105 S1661\nM300 P210 S1108")); + break; + + case '1': // "<11SvEEPROM>" + SERIAL_ECHOLNPGM("Special Menu: Save EEPROM"); + ExtUI::injectCommands_P(PSTR("M500\nM300 P105 S1108\nM300 P210 S1661")); + break; + + default: + break; + } + break; + #else // if ENABLED(PROBE_MANUALLY) + case '0': + switch (SelectedDirectory[2]) { + case '1': // "<01PrehtBed>" + SERIAL_ECHOLNPGM("Special Menu: Preheat Bed"); + ExtUI::injectCommands_P(PSTR("M140 S65")); + break; + + case '2': // "<02ABL>" + SERIAL_ECHOLNPGM("Special Menu: Auto Bed Leveling"); + ExtUI::injectCommands_P(PSTR("G28\nG29")); + break; + + case '3': // "<03HtendPID>" + SERIAL_ECHOLNPGM("Special Menu: Auto Tune Hotend PID"); + // need to dwell for half a second to give the fan a chance to start before the pid tuning starts + ExtUI::injectCommands_P(PSTR("M106 S204\nG4 P500\nM303 E0 S215 C15 U1")); + break; + + case '4': // "<04HtbedPID>" + SERIAL_ECHOLNPGM("Special Menu: Auto Tune Hotbed Pid"); + ExtUI::injectCommands_P(PSTR("M303 E-1 S65 C6 U1")); + break; + + case '5': // "<05FWDeflts>" + SERIAL_ECHOLNPGM("Special Menu: Load FW Defaults"); + ExtUI::injectCommands_P(PSTR("M502\nM300 P105 S1661\nM300 P210 S1108")); + break; + + case '6': // "<06SvEEPROM>" + SERIAL_ECHOLNPGM("Special Menu: Save EEPROM"); + ExtUI::injectCommands_P(PSTR("M500\nM300 P105 S1108\nM300 P210 S1661")); + break; + + case '7': // <07SendM108> + SERIAL_ECHOLNPGM("Special Menu: Send User Confirmation"); + ExtUI::injectCommands_P(PSTR("M108")); + break; + + default: + break; + } + break; + #endif // PROBE_MANUALLY + + default: + break; + } + #if ENABLED(ANYCUBIC_LCD_DEBUG) + } + else { + SERIAL_ECHOPGM("TFT Serial Debug: Attempted to HandleSpecialMenu on non-special menu... "); + SERIAL_ECHOLN(SelectedDirectory); + #endif + } +} + +void AnycubicTFTClass::RenderCurrentFileList() { + #if ENABLED(SDSUPPORT) + uint16_t selectedNumber = 0; + SelectedDirectory[0] = 0; + SelectedFile[0] = 0; + ExtUI::FileList currentFileList; + + SENDLINE_PGM("FN "); // Filelist start + + if (!ExtUI::isMediaInserted() && !SpecialMenu) { + SENDLINE_DBG_PGM("J02", "TFT Serial Debug: No SD Card mounted to render Current File List... J02"); + + SENDLINE_PGM(""); + SENDLINE_PGM(""); + } + else { + if (CodeSeen('S')) + selectedNumber = CodeValue(); + + if (SpecialMenu) + RenderSpecialMenu(selectedNumber); + else if (selectedNumber <= currentFileList.count()) + RenderCurrentFolder(selectedNumber); + } + SENDLINE_PGM("END"); // Filelist stop + #endif // SDSUPPORT +} + +void AnycubicTFTClass::RenderSpecialMenu(uint16_t selectedNumber) { + switch (selectedNumber) { + #if ENABLED(PROBE_MANUALLY) + case 0: // First Page + SENDLINE_PGM("<01ZUp0.1>"); + SENDLINE_PGM(""); + SENDLINE_PGM("<02ZUp0.02>"); + SENDLINE_PGM(""); + SENDLINE_PGM("<03ZDn0.02>"); + SENDLINE_PGM(""); + SENDLINE_PGM("<04ZDn0.1>"); + SENDLINE_PGM(""); + break; + + case 4: // Second Page + SENDLINE_PGM("<05PrehtBed>"); + SENDLINE_PGM(""); + SENDLINE_PGM("<06SMeshLvl>"); + SENDLINE_PGM(""); + SENDLINE_PGM("<07MeshNPnt>"); + SENDLINE_PGM(""); + SENDLINE_PGM("<08HtEndPID>"); + SENDLINE_PGM(""); + break; + + case 8: // Third Page + SENDLINE_PGM("<09HtBedPID>"); + SENDLINE_PGM(""); + SENDLINE_PGM("<10FWDeflts>"); + SENDLINE_PGM(""); + SENDLINE_PGM("<11SvEEPROM>"); + SENDLINE_PGM(""); + SENDLINE_PGM(""); + SENDLINE_PGM(""); + break; + #else + case 0: // First Page + SENDLINE_PGM("<01PrehtBed>"); + SENDLINE_PGM(""); + SENDLINE_PGM("<02ABL>"); + SENDLINE_PGM(""); + SENDLINE_PGM("<03HtEndPID>"); + SENDLINE_PGM(""); + SENDLINE_PGM("<04HtBedPID>"); + SENDLINE_PGM(""); + break; + + case 4: // Second Page + SENDLINE_PGM("<05FWDeflts>"); + SENDLINE_PGM(""); + SENDLINE_PGM("<06SvEEPROM>"); + SENDLINE_PGM(""); + SENDLINE_PGM("<07SendM108>"); + SENDLINE_PGM(""); + SENDLINE_PGM(""); + SENDLINE_PGM(""); + break; + + #endif // PROBE_MANUALLY + + default: + break; + } +} + +void AnycubicTFTClass::RenderCurrentFolder(uint16_t selectedNumber) { + ExtUI::FileList currentFileList; + uint16_t cnt = selectedNumber; + uint16_t max_files; + uint16_t dir_files = currentFileList.count(); + + if ((dir_files - selectedNumber) < 4) + max_files = dir_files; + else + max_files = selectedNumber + 3; + + for (cnt = selectedNumber; cnt <= max_files; cnt++) { + if (cnt == 0) { // Special Entry + if (currentFileList.isAtRootDir()) { + SENDLINE_PGM(""); + SENDLINE_PGM(""); + } + else { + SENDLINE_PGM("/.."); + SENDLINE_PGM("/.."); + } + } + else { + currentFileList.seek(cnt - 1, false); + + #if ENABLED(ANYCUBIC_LCD_DEBUG) + SERIAL_ECHOLN(currentFileList.filename()); + #endif + if (currentFileList.isDir()) { + SEND_PGM("/"); + SENDLINE(currentFileList.shortFilename()); + SEND_PGM("/"); + SENDLINE(currentFileList.filename()); + + } + else { + SENDLINE(currentFileList.shortFilename()); + SENDLINE(currentFileList.filename()); + } + } + } +} + +void AnycubicTFTClass::OnPrintTimerStarted() { + #if ENABLED(SDSUPPORT) + if (mediaPrintingState == AMPRINTSTATE_PRINTING) + SENDLINE_DBG_PGM("J04", "TFT Serial Debug: Starting SD Print... J04"); // J04 Starting Print + + #endif +} + +void AnycubicTFTClass::OnPrintTimerPaused() { + #if ENABLED(SDSUPPORT) + if (ExtUI::isPrintingFromMedia()) { + mediaPrintingState = AMPRINTSTATE_PAUSED; + mediaPauseState = AMPAUSESTATE_PARKING; + } + #endif +} + +void AnycubicTFTClass::OnPrintTimerStopped() { + #if ENABLED(SDSUPPORT) + if (mediaPrintingState == AMPRINTSTATE_PRINTING) { + mediaPrintingState = AMPRINTSTATE_NOT_PRINTING; + mediaPauseState = AMPAUSESTATE_NOT_PAUSED; + SENDLINE_DBG_PGM("J14", "TFT Serial Debug: SD Print Completed... J14"); + } + // otherwise it was stopped by the printer so don't send print completed signal to TFT + #endif +} + +void AnycubicTFTClass::GetCommandFromTFT() { + char *starpos = NULL; + while (LCD_SERIAL.available() > 0 && TFTbuflen < TFTBUFSIZE) { + serial3_char = LCD_SERIAL.read(); + if (serial3_char == '\n' || + serial3_char == '\r' || + serial3_char == ':' || + serial3_count >= (TFT_MAX_CMD_SIZE - 1) + ) { + + if (!serial3_count) return; // if empty line + + TFTcmdbuffer[TFTbufindw][serial3_count] = 0; // terminate string + + if ((strchr(TFTcmdbuffer[TFTbufindw], 'A') != NULL)) { + int16_t a_command; + TFTstrchr_pointer = strchr(TFTcmdbuffer[TFTbufindw], 'A'); + a_command = ((int)((strtod(&TFTcmdbuffer[TFTbufindw][TFTstrchr_pointer - TFTcmdbuffer[TFTbufindw] + 1], NULL)))); + + #if ENABLED(ANYCUBIC_LCD_DEBUG) + if ((a_command > 7) && (a_command != 20)) { // No debugging of status polls, please! + SERIAL_ECHOPGM("TFT Serial Command: "); + SERIAL_ECHOLN(TFTcmdbuffer[TFTbufindw]); + } + #endif + + switch (a_command) { + case 0: { // A0 GET HOTEND TEMP + float hotendActualTemp = ExtUI::getActualTemp_celsius((ExtUI::extruder_t) (ExtUI::extruder_t) ExtUI::E0); + SEND_PGM_VAL("A0V ", int(hotendActualTemp + 0.5)); + } + break; + + case 1: { // A1 GET HOTEND TARGET TEMP + float hotendTargetTemp = ExtUI::getTargetTemp_celsius((ExtUI::extruder_t) (ExtUI::extruder_t) ExtUI::E0); + SEND_PGM_VAL("A1V ", int(hotendTargetTemp + 0.5)); + } + break; + + case 2: { // A2 GET HOTBED TEMP + float heatedBedActualTemp = ExtUI::getActualTemp_celsius((ExtUI::heater_t) ExtUI::BED); + SEND_PGM_VAL("A2V ", int(heatedBedActualTemp + 0.5)); + } + break; + + case 3: { // A3 GET HOTBED TARGET TEMP + float heatedBedTargetTemp = ExtUI::getTargetTemp_celsius((ExtUI::heater_t) ExtUI::BED); + SEND_PGM_VAL("A3V ", int(heatedBedTargetTemp + 0.5)); + } break; + + case 4: { // A4 GET FAN SPEED + float fanPercent = ExtUI::getActualFan_percent(ExtUI::FAN0); + fanPercent = constrain(fanPercent, 0, 100); + SEND_PGM_VAL("A4V ", int(fanPercent)); + } break; + + case 5: { // A5 GET CURRENT COORDINATE + float xPostition = ExtUI::getAxisPosition_mm(ExtUI::X); + float yPostition = ExtUI::getAxisPosition_mm(ExtUI::Y); + float zPostition = ExtUI::getAxisPosition_mm(ExtUI::Z); + SEND_PGM("A5V X: "); + LCD_SERIAL.print(xPostition); + SEND_PGM(" Y: "); + LCD_SERIAL.print(yPostition); + SEND_PGM(" Z: "); + LCD_SERIAL.print(zPostition); + SENDLINE_PGM(""); + } break; + + case 6: // A6 GET SD CARD PRINTING STATUS + #if ENABLED(SDSUPPORT) + if (ExtUI::isPrintingFromMedia()) { + SEND_PGM("A6V "); + if (ExtUI::isMediaInserted()) + SENDLINE(ui8tostr3rj(ExtUI::getProgress_percent())); + else + SENDLINE_DBG_PGM("J02", "TFT Serial Debug: No SD Card mounted to return printing status... J02"); + } + else + SENDLINE_PGM("A6V ---"); + #endif + break; + + case 7: { // A7 GET PRINTING TIME + const uint32_t elapsedSeconds = ExtUI::getProgress_seconds_elapsed(); + SEND_PGM("A7V "); + if (elapsedSeconds != 0) { // print time + const uint32_t elapsedMinutes = elapsedSeconds / 60; + SEND(ui8tostr2(elapsedMinutes / 60)); + SEND_PGM(" H "); + SEND(ui8tostr2(elapsedMinutes % 60)); + SENDLINE_PGM(" M"); + } + else + SENDLINE_PGM(" 999:999"); + } + break; + + case 8: // A8 GET SD LIST + #if ENABLED(SDSUPPORT) + SelectedFile[0] = 0; + RenderCurrentFileList(); + #endif + break; + + case 9: // A9 pause sd print + #if ENABLED(SDSUPPORT) + if (ExtUI::isPrintingFromMedia()) + PausePrint(); + #endif + break; + + case 10: // A10 resume sd print + #if ENABLED(SDSUPPORT) + if (ExtUI::isPrintingFromMediaPaused()) + ResumePrint(); + #endif + break; + + case 11: // A11 STOP SD PRINT + TERN_(SDSUPPORT, StopPrint()); + break; + + case 12: // A12 kill + kill(PSTR(STR_ERR_KILLED)); + break; + + case 13: // A13 SELECTION FILE + #if ENABLED(SDSUPPORT) + if (ExtUI::isMediaInserted()) { + starpos = (strchr(TFTstrchr_pointer + 4, '*')); + if (TFTstrchr_pointer[4] == '/') { + strcpy(SelectedDirectory, TFTstrchr_pointer + 5); + SelectedFile[0] = 0; + SENDLINE_DBG_PGM("J21", "TFT Serial Debug: Clear file selection... J21 "); // J21 Not File Selected + SENDLINE_PGM(""); + } + else if (TFTstrchr_pointer[4] == '<') { + strcpy(SelectedDirectory, TFTstrchr_pointer + 4); + SpecialMenu = true; + SelectedFile[0] = 0; + SENDLINE_DBG_PGM("J21", "TFT Serial Debug: Clear file selection... J21 "); // J21 Not File Selected + SENDLINE_PGM(""); + } + else { + SelectedDirectory[0] = 0; + + if (starpos != NULL) + *(starpos - 1) = '\0'; + + strcpy(SelectedFile, TFTstrchr_pointer + 4); + SENDLINE_DBG_PGM_VAL("J20", "TFT Serial Debug: File Selected... J20 ", SelectedFile); // J20 File Selected + } + } + #endif + break; + + case 14: // A14 START PRINTING + #if ENABLED(SDSUPPORT) + if (!ExtUI::isPrinting() && strlen(SelectedFile) > 0) + StartPrint(); + #endif + break; + + case 15: // A15 RESUMING FROM OUTAGE + // TODO: JBA implement resume form outage + break; + + case 16: { // A16 set hotend temp + unsigned int tempvalue; + if (CodeSeen('S')) { + tempvalue = constrain(CodeValue(), 0, 275); + ExtUI::setTargetTemp_celsius(tempvalue, (ExtUI::extruder_t) ExtUI::E0); + } + else if (CodeSeen('C') && !ExtUI::isPrinting()) { + if (ExtUI::getAxisPosition_mm(ExtUI::Z) < 10) + ExtUI::injectCommands_P(PSTR("G1 Z10")); // RASE Z AXIS + tempvalue = constrain(CodeValue(), 0, 275); + ExtUI::setTargetTemp_celsius(tempvalue, (ExtUI::extruder_t) ExtUI::E0); + } + } + break; + + case 17: { // A17 set heated bed temp + unsigned int tempbed; + if (CodeSeen('S')) { + tempbed = constrain(CodeValue(), 0, 100); + ExtUI::setTargetTemp_celsius(tempbed, (ExtUI::heater_t)ExtUI::BED); + } + } + break; + + case 18: { // A18 set fan speed + float fanPercent; + if (CodeSeen('S')) { + fanPercent = CodeValue(); + fanPercent = constrain(fanPercent, 0, 100); + ExtUI::setTargetFan_percent(fanPercent, ExtUI::FAN0); + } + else + fanPercent = 100; + + ExtUI::setTargetFan_percent(fanPercent, ExtUI::FAN0); + SENDLINE_PGM(""); + } + break; + + case 19: // A19 stop stepper drivers - sent on stop extrude command and on turn motors off command + if (!ExtUI::isPrinting()) { + quickstop_stepper(); + disable_all_steppers(); + } + + SENDLINE_PGM(""); + break; + + case 20: // A20 read printing speed + if (CodeSeen('S')) + feedrate_percentage = constrain(CodeValue(), 40, 999); + else + SEND_PGM_VAL("A20V ", feedrate_percentage); + break; + + case 21: // A21 all home + if (!ExtUI::isPrinting() && !ExtUI::isPrintingFromMediaPaused()) { + if (CodeSeen('X') || CodeSeen('Y') || CodeSeen('Z')) { + if (CodeSeen('X')) + ExtUI::injectCommands_P(PSTR("G28 X")); + if (CodeSeen('Y')) + ExtUI::injectCommands_P(PSTR("G28 Y")); + if (CodeSeen('Z')) + ExtUI::injectCommands_P(PSTR("G28 Z")); + } + else if (CodeSeen('C')) { + ExtUI::injectCommands_P(PSTR("G28")); + } + } + break; + + case 22: // A22 move X/Y/Z or extrude + if (!ExtUI::isPrinting()) { + float coorvalue; + unsigned int movespeed = 0; + char commandStr[30]; + char fullCommandStr[38]; + + commandStr[0] = 0; // empty string + if (CodeSeen('F')) // Set feedrate + movespeed = CodeValue(); + + if (CodeSeen('X')) { // Move in X direction + coorvalue = CodeValue(); + if ((coorvalue <= 0.2) && coorvalue > 0) + sprintf_P(commandStr, PSTR("G1 X0.1F%i"), movespeed); + else if ((coorvalue <= -0.1) && coorvalue > -1) + sprintf_P(commandStr, PSTR("G1 X-0.1F%i"), movespeed); + else + sprintf_P(commandStr, PSTR("G1 X%iF%i"), int(coorvalue), movespeed); + } + else if (CodeSeen('Y')) { // Move in Y direction + coorvalue = CodeValue(); + if ((coorvalue <= 0.2) && coorvalue > 0) + sprintf_P(commandStr, PSTR("G1 Y0.1F%i"), movespeed); + else if ((coorvalue <= -0.1) && coorvalue > -1) + sprintf_P(commandStr, PSTR("G1 Y-0.1F%i"), movespeed); + else + sprintf_P(commandStr, PSTR("G1 Y%iF%i"), int(coorvalue), movespeed); + } + else if (CodeSeen('Z')) { // Move in Z direction + coorvalue = CodeValue(); + if ((coorvalue <= 0.2) && coorvalue > 0) + sprintf_P(commandStr, PSTR("G1 Z0.1F%i"), movespeed); + else if ((coorvalue <= -0.1) && coorvalue > -1) + sprintf_P(commandStr, PSTR("G1 Z-0.1F%i"), movespeed); + else + sprintf_P(commandStr, PSTR("G1 Z%iF%i"), int(coorvalue), movespeed); + } + else if (CodeSeen('E')) { // Extrude + coorvalue = CodeValue(); + if ((coorvalue <= 0.2) && coorvalue > 0) + sprintf_P(commandStr, PSTR("G1 E0.1F%i"), movespeed); + else if ((coorvalue <= -0.1) && coorvalue > -1) + sprintf_P(commandStr, PSTR("G1 E-0.1F%i"), movespeed); + else + sprintf_P(commandStr, PSTR("G1 E%iF500"), int(coorvalue)); + } + + if (strlen(commandStr) > 0) { + sprintf_P(fullCommandStr, PSTR("G91\n%s\nG90"), commandStr); + #if ENABLED(ANYCUBIC_LCD_DEBUG) + SERIAL_ECHOPGM("TFT Serial Debug: A22 Move final request with gcode... "); + SERIAL_ECHOLN(fullCommandStr); + #endif + ExtUI::injectCommands(fullCommandStr); + } + } + SENDLINE_PGM(""); + break; + + case 23: // A23 preheat pla + if (!ExtUI::isPrinting()) { + if (ExtUI::getAxisPosition_mm(ExtUI::Z) < 10) + ExtUI::injectCommands_P(PSTR("G1 Z10")); // RASE Z AXIS + + ExtUI::setTargetTemp_celsius(PREHEAT_1_TEMP_BED, (ExtUI::heater_t) ExtUI::BED); + ExtUI::setTargetTemp_celsius(PREHEAT_1_TEMP_HOTEND, (ExtUI::extruder_t) ExtUI::E0); + SENDLINE_PGM("OK"); + } + break; + + case 24:// A24 preheat abs + if (!ExtUI::isPrinting()) { + if (ExtUI::getAxisPosition_mm(ExtUI::Z) < 10) + ExtUI::injectCommands_P(PSTR("G1 Z10")); // RASE Z AXIS + + ExtUI::setTargetTemp_celsius(PREHEAT_2_TEMP_BED, (ExtUI::heater_t) ExtUI::BED); + ExtUI::setTargetTemp_celsius(PREHEAT_2_TEMP_HOTEND, (ExtUI::extruder_t) ExtUI::E0); + SENDLINE_PGM("OK"); + } + break; + + case 25: // A25 cool down + if (!ExtUI::isPrinting()) { + ExtUI::setTargetTemp_celsius(0, (ExtUI::heater_t) ExtUI::BED); + ExtUI::setTargetTemp_celsius(0, (ExtUI::extruder_t) ExtUI::E0); + + SENDLINE_DBG_PGM("J12", "TFT Serial Debug: Cooling down... J12"); // J12 cool down + } + break; + + case 26: // A26 refresh SD + #if ENABLED(SDSUPPORT) + if (ExtUI::isMediaInserted()) { + if (strlen(SelectedDirectory) > 0) { + ExtUI::FileList currentFileList; + if ((SelectedDirectory[0] == '.') && (SelectedDirectory[1] == '.')) { + currentFileList.upDir(); + } + else { + if (SelectedDirectory[0] == '<') + HandleSpecialMenu(); + else + currentFileList.changeDir(SelectedDirectory); + } + } + } + else { + SENDLINE_DBG_PGM("J02", "TFT Serial Debug: No SD Card mounted to refresh SD A26... J02"); + } + + SelectedDirectory[0] = 0; + #endif + break; + + #if ENABLED(SERVO_ENDSTOPS) + case 27: break; // A27 servos angles adjust + #endif + + case 28: // A28 filament test + if (CodeSeen('O')) + NOOP; + else if (CodeSeen('C')) + NOOP; + SENDLINE_PGM(""); + break; + + case 33: // A33 get version info + SEND_PGM("J33 "); + SENDLINE_PGM(DETAILED_BUILD_VERSION); + break; + + default: + break; + } + } + + TFTbufindw = (TFTbufindw + 1) % TFTBUFSIZE; + TFTbuflen += 1; + serial3_count = 0; // clear buffer + } + else { + TFTcmdbuffer[TFTbufindw][serial3_count++] = serial3_char; + } + } +} + +void AnycubicTFTClass::DoSDCardStateCheck() { + #if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_DETECT) + bool isInserted = ExtUI::isMediaInserted(); + if (isInserted) + SENDLINE_DBG_PGM("J00", "TFT Serial Debug: SD card state changed... isInserted"); + else + SENDLINE_DBG_PGM("J01", "TFT Serial Debug: SD card state changed... !isInserted"); + + #endif +} + +void AnycubicTFTClass::DoFilamentRunoutCheck() { + #if ENABLED(FILAMENT_RUNOUT_SENSOR) + // NOTE: ExtUI::getFilamentRunoutState() only returns the runout state if the job is printing + // we want to actually check the status of the pin here, regardless of printstate + if (READ(FIL_RUNOUT_PIN)) { + if (mediaPrintingState == AMPRINTSTATE_PRINTING || mediaPrintingState == AMPRINTSTATE_PAUSED || mediaPrintingState == AMPRINTSTATE_PAUSE_REQUESTED) { + // play tone to indicate filament is out + ExtUI::injectCommands_P(PSTR("\nM300 P200 S1567\nM300 P200 S1174\nM300 P200 S1567\nM300 P200 S1174\nM300 P2000 S1567")); + + // tell the user that the filament has run out and wait + SENDLINE_DBG_PGM("J23", "TFT Serial Debug: Blocking filament prompt... J23"); + } + else { + SENDLINE_DBG_PGM("J15", "TFT Serial Debug: Non blocking filament runout... J15"); + } + } + #endif // FILAMENT_RUNOUT_SENSOR +} + +void AnycubicTFTClass::StartPrint() { + #if ENABLED(SDSUPPORT) + if (!ExtUI::isPrinting() && strlen(SelectedFile) > 0) { + #if ENABLED(ANYCUBIC_LCD_DEBUG) + SERIAL_ECHOPGM("TFT Serial Debug: About to print file ... "); + SERIAL_ECHO(ExtUI::isPrinting()); + SERIAL_ECHOPGM(" "); + SERIAL_ECHOLN(SelectedFile); + #endif + mediaPrintingState = AMPRINTSTATE_PRINTING; + mediaPauseState = AMPAUSESTATE_NOT_PAUSED; + ExtUI::printFile(SelectedFile); + } + #endif // SDUPPORT +} + +void AnycubicTFTClass::PausePrint() { + #if ENABLED(SDSUPPORT) + if (ExtUI::isPrintingFromMedia() && mediaPrintingState != AMPRINTSTATE_STOP_REQUESTED && mediaPauseState == AMPAUSESTATE_NOT_PAUSED) { + mediaPrintingState = AMPRINTSTATE_PAUSE_REQUESTED; + mediaPauseState = AMPAUSESTATE_NOT_PAUSED; // need the userconfirm method to update pause state + SENDLINE_DBG_PGM("J05", "TFT Serial Debug: SD print pause started... J05"); // J05 printing pause + + // for some reason pausing the print doesn't retract the extruder so force a manual one here + ExtUI::injectCommands_P(PSTR("G91\nG1 E-2 F1800\nG90")); + ExtUI::pausePrint(); + } + #endif +} + +void AnycubicTFTClass::ResumePrint() { + #if ENABLED(SDSUPPORT) + #if ENABLED(FILAMENT_RUNOUT_SENSOR) + if (READ(FIL_RUNOUT_PIN)) { + #if ENABLED(ANYCUBIC_LCD_DEBUG) + SERIAL_ECHOLNPGM("TFT Serial Debug: Resume Print with filament sensor still tripped... "); + #endif + + // trigger the user message box + DoFilamentRunoutCheck(); + + // re-enable the continue button + SENDLINE_DBG_PGM("J18", "TFT Serial Debug: Resume Print with filament sensor still tripped... J18"); + return; + } + #endif + + if (mediaPauseState == AMPAUSESTATE_HEATER_TIMEOUT) { + mediaPauseState = AMPAUSESTATE_REHEATING; + // TODO: JBA I don't think J05 just disables the continue button, i think it injects a rogue M25. So taking this out + // // disable the continue button + // SENDLINE_DBG_PGM("J05", "TFT Serial Debug: Resume called with heater timeout... J05"); // J05 printing pause + + // reheat the nozzle + ExtUI::setUserConfirmed(); + } + else { + mediaPrintingState = AMPRINTSTATE_PRINTING; + mediaPauseState = AMPAUSESTATE_NOT_PAUSED; + + SENDLINE_DBG_PGM("J04", "TFT Serial Debug: SD print resumed... J04"); // J04 printing form sd card now + ExtUI::resumePrint(); + } + #endif +} + +void AnycubicTFTClass::StopPrint() { + #if ENABLED(SDSUPPORT) + mediaPrintingState = AMPRINTSTATE_STOP_REQUESTED; + mediaPauseState = AMPAUSESTATE_NOT_PAUSED; + SENDLINE_DBG_PGM("J16", "TFT Serial Debug: SD print stop called... J16"); + + // for some reason stopping the print doesn't retract the extruder so force a manual one here + ExtUI::injectCommands_P(PSTR("G91\nG1 E-2 F1800\nG90")); + ExtUI::stopPrint(); + #endif +} + +#endif // ANYCUBIC_LCD_I3MEGA diff --git a/Marlin/src/lcd/extui/lib/anycubic_i3mega/anycubic_i3mega_lcd.h b/Marlin/src/lcd/extui/lib/anycubic_i3mega/anycubic_i3mega_lcd.h new file mode 100644 index 000000000000..a4ecf5604f9e --- /dev/null +++ b/Marlin/src/lcd/extui/lib/anycubic_i3mega/anycubic_i3mega_lcd.h @@ -0,0 +1,96 @@ +/** + * anycubic_i3mega_lcd.h --- Support for Anycubic i3 Mega TFT + * Created by Christian Hopp on 09.12.17. + * Improved by David Ramiro + * Converted to ext_iu by John BouAntoun 21 June 2020 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#pragma once + +#include "../../../../inc/MarlinConfigPre.h" +#include "../../../../sd/SdFatConfig.h" // for the FILENAME_LENGTH macro + +#define TFTBUFSIZE 4 +#define TFT_MAX_CMD_SIZE 96 + +enum AnycubicMediaPrintState { + AMPRINTSTATE_NOT_PRINTING, + AMPRINTSTATE_PRINTING, + AMPRINTSTATE_PAUSE_REQUESTED, + AMPRINTSTATE_PAUSED, + AMPRINTSTATE_STOP_REQUESTED +}; + +enum AnycubicMediaPauseState { + AMPAUSESTATE_NOT_PAUSED, + AMPAUSESTATE_PARKING, + AMPAUSESTATE_PARKED, + AMPAUSESTATE_FILAMENT_OUT, + AMPAUSESTATE_FIAMENT_PRUGING, + AMPAUSESTATE_HEATER_TIMEOUT, + AMPAUSESTATE_REHEATING, + AMPAUSESTATE_REHEAT_FINISHED +}; + +class AnycubicTFTClass { +public: + AnycubicTFTClass(); + void OnSetup(); + void OnCommandScan(); + void OnKillTFT(); + void OnSDCardStateChange(bool); + void OnSDCardError(); + void OnFilamentRunout(); + void OnUserConfirmRequired(const char *); + void OnPrintTimerStarted(); + void OnPrintTimerPaused(); + void OnPrintTimerStopped(); + +private: + char TFTcmdbuffer[TFTBUFSIZE][TFT_MAX_CMD_SIZE]; + int TFTbuflen=0; + int TFTbufindr = 0; + int TFTbufindw = 0; + char serial3_char; + int serial3_count = 0; + char *TFTstrchr_pointer; + uint8_t SpecialMenu = false; + AnycubicMediaPrintState mediaPrintingState = AMPRINTSTATE_NOT_PRINTING; + AnycubicMediaPauseState mediaPauseState = AMPAUSESTATE_NOT_PAUSED; + + float CodeValue(); + bool CodeSeen(char); + bool IsNozzleHomed(); + void RenderCurrentFileList(); + void RenderSpecialMenu(uint16_t); + void RenderCurrentFolder(uint16_t); + void GetCommandFromTFT(); + void CheckSDCardChange(); + void CheckPauseState(); + void CheckPrintCompletion(); + void HandleSpecialMenu(); + void DoSDCardStateCheck(); + void DoFilamentRunoutCheck(); + void StartPrint(); + void PausePrint(); + void ResumePrint(); + void StopPrint(); + + char SelectedDirectory[30]; + char SelectedFile[FILENAME_LENGTH]; +}; + +extern AnycubicTFTClass AnycubicTFT; diff --git a/Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.cpp b/Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.cpp new file mode 100644 index 000000000000..8577b76ce61f --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.cpp @@ -0,0 +1,263 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* DGUS implementation written by coldtobi in 2019 for Marlin */ + +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_DGUS_LCD + +#if HOTENDS > 2 + #error "More than 2 hotends not implemented on the Display UI design." +#endif + +#include "../../ui_api.h" + +#include "../../../../MarlinCore.h" +#include "../../../../module/temperature.h" +#include "../../../../module/motion.h" +#include "../../../../gcode/queue.h" +#include "../../../../module/planner.h" +#include "../../../../sd/cardreader.h" +#include "../../../../libs/duration_t.h" +#include "../../../../module/printcounter.h" +#if ENABLED(POWER_LOSS_RECOVERY) + #include "../../../../feature/powerloss.h" +#endif + +#include "DGUSDisplay.h" +#include "DGUSVPVariable.h" +#include "DGUSDisplayDef.h" + +// Preamble... 2 Bytes, usually 0x5A 0xA5, but configurable +constexpr uint8_t DGUS_HEADER1 = 0x5A; +constexpr uint8_t DGUS_HEADER2 = 0xA5; + +constexpr uint8_t DGUS_CMD_WRITEVAR = 0x82; +constexpr uint8_t DGUS_CMD_READVAR = 0x83; + +#if ENABLED(DEBUG_DGUSLCD) + bool dguslcd_local_debug; // = false; +#endif + +void DGUSDisplay::InitDisplay() { + #ifndef LCD_BAUDRATE + #define LCD_BAUDRATE 115200 + #endif + LCD_SERIAL.begin(LCD_BAUDRATE); + if (TERN1(POWER_LOSS_RECOVERY, !recovery.valid())) + RequestScreen(TERN(SHOW_BOOTSCREEN, DGUSLCD_SCREEN_BOOT, DGUSLCD_SCREEN_MAIN)); +} + +void DGUSDisplay::WriteVariable(uint16_t adr, const void* values, uint8_t valueslen, bool isstr) { + const char* myvalues = static_cast(values); + bool strend = !myvalues; + WriteHeader(adr, DGUS_CMD_WRITEVAR, valueslen); + while (valueslen--) { + char x; + if (!strend) x = *myvalues++; + if ((isstr && !x) || strend) { + strend = true; + x = ' '; + } + LCD_SERIAL.write(x); + } +} + +void DGUSDisplay::WriteVariable(uint16_t adr, uint16_t value) { + value = (value & 0xffU) << 8U | (value >> 8U); + WriteVariable(adr, static_cast(&value), sizeof(uint16_t)); +} + +void DGUSDisplay::WriteVariable(uint16_t adr, int16_t value) { + value = (value & 0xffU) << 8U | (value >> 8U); + WriteVariable(adr, static_cast(&value), sizeof(uint16_t)); +} + +void DGUSDisplay::WriteVariable(uint16_t adr, uint8_t value) { + WriteVariable(adr, static_cast(&value), sizeof(uint8_t)); +} + +void DGUSDisplay::WriteVariable(uint16_t adr, int8_t value) { + WriteVariable(adr, static_cast(&value), sizeof(int8_t)); +} + +void DGUSDisplay::WriteVariable(uint16_t adr, long value) { + union { long l; char lb[4]; } endian; + char tmp[4]; + endian.l = value; + tmp[0] = endian.lb[3]; + tmp[1] = endian.lb[2]; + tmp[2] = endian.lb[1]; + tmp[3] = endian.lb[0]; + WriteVariable(adr, static_cast(&tmp), sizeof(long)); +} + +void DGUSDisplay::WriteVariablePGM(uint16_t adr, const void* values, uint8_t valueslen, bool isstr) { + const char* myvalues = static_cast(values); + bool strend = !myvalues; + WriteHeader(adr, DGUS_CMD_WRITEVAR, valueslen); + while (valueslen--) { + char x; + if (!strend) x = pgm_read_byte(myvalues++); + if ((isstr && !x) || strend) { + strend = true; + x = ' '; + } + LCD_SERIAL.write(x); + } +} + +void DGUSDisplay::ProcessRx() { + + #if ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS) + if (!LCD_SERIAL.available() && LCD_SERIAL.buffer_overruns()) { + // Overrun, but reset the flag only when the buffer is empty + // We want to extract as many as valid datagrams possible... + DEBUG_ECHOPGM("OVFL"); + rx_datagram_state = DGUS_IDLE; + //LCD_SERIAL.reset_rx_overun(); + LCD_SERIAL.flush(); + } + #endif + + uint8_t receivedbyte; + while (LCD_SERIAL.available()) { + switch (rx_datagram_state) { + + case DGUS_IDLE: // Waiting for the first header byte + receivedbyte = LCD_SERIAL.read(); + //DEBUG_ECHOPAIR("< ",x); + if (DGUS_HEADER1 == receivedbyte) rx_datagram_state = DGUS_HEADER1_SEEN; + break; + + case DGUS_HEADER1_SEEN: // Waiting for the second header byte + receivedbyte = LCD_SERIAL.read(); + //DEBUG_ECHOPAIR(" ",x); + rx_datagram_state = (DGUS_HEADER2 == receivedbyte) ? DGUS_HEADER2_SEEN : DGUS_IDLE; + break; + + case DGUS_HEADER2_SEEN: // Waiting for the length byte + rx_datagram_len = LCD_SERIAL.read(); + DEBUG_ECHOPAIR(" (", rx_datagram_len, ") "); + + // Telegram min len is 3 (command and one word of payload) + rx_datagram_state = WITHIN(rx_datagram_len, 3, DGUS_RX_BUFFER_SIZE) ? DGUS_WAIT_TELEGRAM : DGUS_IDLE; + break; + + case DGUS_WAIT_TELEGRAM: // wait for complete datagram to arrive. + if (LCD_SERIAL.available() < rx_datagram_len) return; + + Initialized = true; // We've talked to it, so we defined it as initialized. + uint8_t command = LCD_SERIAL.read(); + + DEBUG_ECHOPAIR("# ", command); + + uint8_t readlen = rx_datagram_len - 1; // command is part of len. + unsigned char tmp[rx_datagram_len - 1]; + unsigned char *ptmp = tmp; + while (readlen--) { + receivedbyte = LCD_SERIAL.read(); + DEBUG_ECHOPAIR(" ", receivedbyte); + *ptmp++ = receivedbyte; + } + DEBUG_ECHOPGM(" # "); + // mostly we'll get this: 5A A5 03 82 4F 4B -- ACK on 0x82, so discard it. + if (command == DGUS_CMD_WRITEVAR && 'O' == tmp[0] && 'K' == tmp[1]) { + DEBUG_ECHOLNPGM(">"); + rx_datagram_state = DGUS_IDLE; + break; + } + + /* AutoUpload, (and answer to) Command 0x83 : + | tmp[0 1 2 3 4 ... ] + | Example 5A A5 06 83 20 01 01 78 01 …… + | / / | | \ / | \ \ + | Header | | | | \_____\_ DATA (Words!) + | DatagramLen / VPAdr | + | Command DataLen (in Words) */ + if (command == DGUS_CMD_READVAR) { + const uint16_t vp = tmp[0] << 8 | tmp[1]; + //const uint8_t dlen = tmp[2] << 1; // Convert to Bytes. (Display works with words) + //DEBUG_ECHOPAIR(" vp=", vp, " dlen=", dlen); + DGUS_VP_Variable ramcopy; + if (populate_VPVar(vp, &ramcopy)) { + if (ramcopy.set_by_display_handler) + ramcopy.set_by_display_handler(ramcopy, &tmp[3]); + else + DEBUG_ECHOLNPGM(" VPVar found, no handler."); + } + else + DEBUG_ECHOLNPAIR(" VPVar not found:", vp); + + rx_datagram_state = DGUS_IDLE; + break; + } + + // discard anything else + rx_datagram_state = DGUS_IDLE; + } + } +} + +size_t DGUSDisplay::GetFreeTxBuffer() { return SERIAL_GET_TX_BUFFER_FREE(); } + +void DGUSDisplay::WriteHeader(uint16_t adr, uint8_t cmd, uint8_t payloadlen) { + LCD_SERIAL.write(DGUS_HEADER1); + LCD_SERIAL.write(DGUS_HEADER2); + LCD_SERIAL.write(payloadlen + 3); + LCD_SERIAL.write(cmd); + LCD_SERIAL.write(adr >> 8); + LCD_SERIAL.write(adr & 0xFF); +} + +void DGUSDisplay::WritePGM(const char str[], uint8_t len) { + while (len--) LCD_SERIAL.write(pgm_read_byte(str++)); +} + +void DGUSDisplay::loop() { + // protect against recursion… ProcessRx() may indirectly call idle() when injecting gcode commands. + if (!no_reentrance) { + no_reentrance = true; + ProcessRx(); + no_reentrance = false; + } +} + +rx_datagram_state_t DGUSDisplay::rx_datagram_state = DGUS_IDLE; +uint8_t DGUSDisplay::rx_datagram_len = 0; +bool DGUSDisplay::Initialized = false; +bool DGUSDisplay::no_reentrance = false; + +// A SW memory barrier, to ensure GCC does not overoptimize loops +#define sw_barrier() asm volatile("": : :"memory"); + +bool populate_VPVar(const uint16_t VP, DGUS_VP_Variable * const ramcopy) { + // DEBUG_ECHOPAIR("populate_VPVar ", VP); + const DGUS_VP_Variable *pvp = DGUSLCD_FindVPVar(VP); + // DEBUG_ECHOLNPAIR(" pvp ", (uint16_t )pvp); + if (!pvp) return false; + memcpy_P(ramcopy, pvp, sizeof(DGUS_VP_Variable)); + return true; +} + +#endif // HAS_DGUS_LCD diff --git a/Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.h b/Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.h new file mode 100644 index 000000000000..ee536ea21905 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.h @@ -0,0 +1,117 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/* DGUS implementation written by coldtobi in 2019 for Marlin */ + +#include "../../../../inc/MarlinConfigPre.h" + +#include "../../../../MarlinCore.h" +#if HAS_BED_PROBE + #include "../../../../module/probe.h" +#endif +#include "DGUSVPVariable.h" + +enum DGUSLCD_Screens : uint8_t; + +#define DEBUG_OUT ENABLED(DEBUG_DGUSLCD) +#include "../../../../core/debug_out.h" + +typedef enum : uint8_t { + DGUS_IDLE, //< waiting for DGUS_HEADER1. + DGUS_HEADER1_SEEN, //< DGUS_HEADER1 received + DGUS_HEADER2_SEEN, //< DGUS_HEADER2 received + DGUS_WAIT_TELEGRAM, //< LEN received, Waiting for to receive all bytes. +} rx_datagram_state_t; + +// Low-Level access to the display. +class DGUSDisplay { +public: + + DGUSDisplay() = default; + + static void InitDisplay(); + + // Variable access. + static void WriteVariable(uint16_t adr, const void* values, uint8_t valueslen, bool isstr=false); + static void WriteVariablePGM(uint16_t adr, const void* values, uint8_t valueslen, bool isstr=false); + static void WriteVariable(uint16_t adr, int16_t value); + static void WriteVariable(uint16_t adr, uint16_t value); + static void WriteVariable(uint16_t adr, uint8_t value); + static void WriteVariable(uint16_t adr, int8_t value); + static void WriteVariable(uint16_t adr, long value); + + // Utility functions for bridging ui_api and dbus + template + static void SetVariable(DGUS_VP_Variable &var) { + WriteVariable(var.VP, (WireType)Getter(selector)); + } + + template + static void GetVariable(DGUS_VP_Variable &var, void *val_ptr) { + uint16_t newvalue = swap16(*(uint16_t*)val_ptr); + Setter(newvalue, selector); + } + + // Until now I did not need to actively read from the display. That's why there is no ReadVariable + // (I extensively use the auto upload of the display) + + // Force display into another screen. + // (And trigger update of containing VPs) + // (to implement a pop up message, which may not be nested) + static void RequestScreen(DGUSLCD_Screens screen); + + // Periodic tasks, eg. Rx-Queue handling. + static void loop(); + +public: + // Helper for users of this class to estimate if an interaction would be blocking. + static size_t GetFreeTxBuffer(); + + // Checks two things: Can we confirm the presence of the display and has we initiliazed it. + // (both boils down that the display answered to our chatting) + static inline bool isInitialized() { return Initialized; } + +private: + static void WriteHeader(uint16_t adr, uint8_t cmd, uint8_t payloadlen); + static void WritePGM(const char str[], uint8_t len); + static void ProcessRx(); + + static inline uint16_t swap16(const uint16_t value) { return (value & 0xffU) << 8U | (value >> 8U); } + static rx_datagram_state_t rx_datagram_state; + static uint8_t rx_datagram_len; + static bool Initialized, no_reentrance; +}; + +#define GET_VARIABLE(f, t, V...) (&DGUSDisplay::GetVariable) +#define SET_VARIABLE(f, t, V...) (&DGUSDisplay::SetVariable) + +extern DGUSDisplay dgusdisplay; + +// compile-time x^y +constexpr float cpow(const float x, const int y) { return y == 0 ? 1.0 : x * cpow(x, y - 1); } + +/// Find the flash address of a DGUS_VP_Variable for the VP. +extern const DGUS_VP_Variable* DGUSLCD_FindVPVar(const uint16_t vp); + +/// Helper to populate a DGUS_VP_Variable for a given VP. Return false if not found. +extern bool populate_VPVar(const uint16_t VP, DGUS_VP_Variable * const ramcopy); diff --git a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinition.h b/Marlin/src/lcd/extui/lib/dgus/DGUSDisplayDef.h similarity index 86% rename from Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinition.h rename to Marlin/src/lcd/extui/lib/dgus/DGUSDisplayDef.h index eebf18e37742..b34a04875d1a 100644 --- a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinition.h +++ b/Marlin/src/lcd/extui/lib/dgus/DGUSDisplayDef.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,6 +25,8 @@ #include "DGUSVPVariable.h" +#include + // This file defines the interaction between Marlin and the display firmware. // information on which screen which VP is displayed @@ -41,10 +43,12 @@ extern const struct VPMapping VPMap[]; // List of VPs handled by Marlin / The Display. extern const struct DGUS_VP_Variable ListOfVP[]; +#include "../../../../inc/MarlinConfig.h" + #if ENABLED(DGUS_LCD_UI_ORIGIN) - #include "DGUSDisplayDefinitionOrigin.h" + #include "origin/DGUSDisplayDef.h" #elif ENABLED(DGUS_LCD_UI_FYSETC) - #include "DGUSDisplayDefinitionFYSETC.h" + #include "fysetc/DGUSDisplayDef.h" #elif ENABLED(DGUS_LCD_UI_HIPRECY) - #include "DGUSDisplayDefinitionHIPRECY.h" + #include "hiprecy/DGUSDisplayDef.h" #endif diff --git a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.cpp b/Marlin/src/lcd/extui/lib/dgus/DGUSScreenHandler.cpp similarity index 67% rename from Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.cpp rename to Marlin/src/lcd/extui/lib/dgus/DGUSScreenHandler.cpp index e62a77ebeea3..7988985c2e4b 100644 --- a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.cpp +++ b/Marlin/src/lcd/extui/lib/dgus/DGUSScreenHandler.cpp @@ -16,26 +16,20 @@ * 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 . + * along with this program. If not, see . * */ -/* DGUS implementation written by coldtobi in 2019 for Marlin */ - #include "../../../../inc/MarlinConfigPre.h" #if HAS_DGUS_LCD -#if HOTENDS > 2 - #error "More than 2 hotends not implemented on the Display UI design." -#endif - +#include "DGUSScreenHandler.h" #include "DGUSDisplay.h" #include "DGUSVPVariable.h" -#include "DGUSDisplayDefinition.h" +#include "DGUSDisplayDef.h" #include "../../ui_api.h" - #include "../../../../MarlinCore.h" #include "../../../../module/temperature.h" #include "../../../../module/motion.h" @@ -44,91 +38,55 @@ #include "../../../../sd/cardreader.h" #include "../../../../libs/duration_t.h" #include "../../../../module/printcounter.h" -#if ENABLED(POWER_LOSS_RECOVERY) - #include "../../../../feature/power_loss_recovery.h" -#endif - -// Preamble... 2 Bytes, usually 0x5A 0xA5, but configurable -constexpr uint8_t DGUS_HEADER1 = 0x5A; -constexpr uint8_t DGUS_HEADER2 = 0xA5; - -constexpr uint8_t DGUS_CMD_WRITEVAR = 0x82; -constexpr uint8_t DGUS_CMD_READVAR = 0x83; -#if ENABLED(DEBUG_DGUSLCD) - bool dguslcd_local_debug; // = false; -#endif - -#if ENABLED(DGUS_FILAMENT_LOADUNLOAD) - typedef struct { - ExtUI::extruder_t extruder; // which extruder to operate - uint8_t action; // load or unload - bool heated; // heating done ? - float purge_length; // the length to extrude before unload, prevent filament jam - } filament_data_t; - static filament_data_t filament_data; +#if ENABLED(POWER_LOSS_RECOVERY) + #include "../../../../feature/powerloss.h" #endif -uint16_t DGUSScreenVariableHandler::ConfirmVP; +uint16_t DGUSScreenHandler::ConfirmVP; #if ENABLED(SDSUPPORT) - int16_t DGUSScreenVariableHandler::top_file = 0; - int16_t DGUSScreenVariableHandler::file_to_print = 0; + int16_t DGUSScreenHandler::top_file = 0; + int16_t DGUSScreenHandler::file_to_print = 0; static ExtUI::FileList filelist; #endif -void (*DGUSScreenVariableHandler::confirm_action_cb)() = nullptr; +void (*DGUSScreenHandler::confirm_action_cb)() = nullptr; -//DGUSScreenVariableHandler ScreenHandler; +//DGUSScreenHandler ScreenHandler; -DGUSLCD_Screens DGUSScreenVariableHandler::current_screen; -DGUSLCD_Screens DGUSScreenVariableHandler::past_screens[NUM_PAST_SCREENS]; -uint8_t DGUSScreenVariableHandler::update_ptr; -uint16_t DGUSScreenVariableHandler::skipVP; -bool DGUSScreenVariableHandler::ScreenComplete; +DGUSLCD_Screens DGUSScreenHandler::current_screen; +DGUSLCD_Screens DGUSScreenHandler::past_screens[NUM_PAST_SCREENS]; +uint8_t DGUSScreenHandler::update_ptr; +uint16_t DGUSScreenHandler::skipVP; +bool DGUSScreenHandler::ScreenComplete; //DGUSDisplay dgusdisplay; -rx_datagram_state_t DGUSDisplay::rx_datagram_state = DGUS_IDLE; -uint8_t DGUSDisplay::rx_datagram_len = 0; -bool DGUSDisplay::Initialized = false; -bool DGUSDisplay::no_reentrance = false; - -#define dgusserial DGUS_SERIAL - // endianness swap uint16_t swap16(const uint16_t value) { return (value & 0xffU) << 8U | (value >> 8U); } -bool populate_VPVar(const uint16_t VP, DGUS_VP_Variable * const ramcopy) { - // DEBUG_ECHOPAIR("populate_VPVar ", VP); - const DGUS_VP_Variable *pvp = DGUSLCD_FindVPVar(VP); - // DEBUG_ECHOLNPAIR(" pvp ", (uint16_t )pvp); - if (!pvp) return false; - memcpy_P(ramcopy, pvp, sizeof(DGUS_VP_Variable)); - return true; -} - -void DGUSScreenVariableHandler::sendinfoscreen(const char* line1, const char* line2, const char* line3, const char* line4, bool l1inflash, bool l2inflash, bool l3inflash, bool l4inflash) { +void DGUSScreenHandler::sendinfoscreen(const char* line1, const char* line2, const char* line3, const char* line4, bool l1inflash, bool l2inflash, bool l3inflash, bool l4inflash) { DGUS_VP_Variable ramcopy; if (populate_VPVar(VP_MSGSTR1, &ramcopy)) { ramcopy.memadr = (void*) line1; - l1inflash ? DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM(ramcopy) : DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplay(ramcopy); + l1inflash ? DGUSScreenHandler::DGUSLCD_SendStringToDisplayPGM(ramcopy) : DGUSScreenHandler::DGUSLCD_SendStringToDisplay(ramcopy); } if (populate_VPVar(VP_MSGSTR2, &ramcopy)) { ramcopy.memadr = (void*) line2; - l2inflash ? DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM(ramcopy) : DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplay(ramcopy); + l2inflash ? DGUSScreenHandler::DGUSLCD_SendStringToDisplayPGM(ramcopy) : DGUSScreenHandler::DGUSLCD_SendStringToDisplay(ramcopy); } if (populate_VPVar(VP_MSGSTR3, &ramcopy)) { ramcopy.memadr = (void*) line3; - l3inflash ? DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM(ramcopy) : DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplay(ramcopy); + l3inflash ? DGUSScreenHandler::DGUSLCD_SendStringToDisplayPGM(ramcopy) : DGUSScreenHandler::DGUSLCD_SendStringToDisplay(ramcopy); } if (populate_VPVar(VP_MSGSTR4, &ramcopy)) { ramcopy.memadr = (void*) line4; - l4inflash ? DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM(ramcopy) : DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplay(ramcopy); + l4inflash ? DGUSScreenHandler::DGUSLCD_SendStringToDisplayPGM(ramcopy) : DGUSScreenHandler::DGUSLCD_SendStringToDisplay(ramcopy); } } -void DGUSScreenVariableHandler::HandleUserConfirmationPopUp(uint16_t VP, const char* line1, const char* line2, const char* line3, const char* line4, bool l1, bool l2, bool l3, bool l4) { +void DGUSScreenHandler::HandleUserConfirmationPopUp(uint16_t VP, const char* line1, const char* line2, const char* line3, const char* line4, bool l1, bool l2, bool l3, bool l4) { if (current_screen == DGUSLCD_SCREEN_CONFIRM) { // Already showing a pop up, so we need to cancel that first. PopToOldScreen(); @@ -139,7 +97,7 @@ void DGUSScreenVariableHandler::HandleUserConfirmationPopUp(uint16_t VP, const c ScreenHandler.GotoScreen(DGUSLCD_SCREEN_CONFIRM); } -void DGUSScreenVariableHandler::setstatusmessage(const char *msg) { +void DGUSScreenHandler::setstatusmessage(const char *msg) { DGUS_VP_Variable ramcopy; if (populate_VPVar(VP_M117, &ramcopy)) { ramcopy.memadr = (void*) msg; @@ -147,7 +105,7 @@ void DGUSScreenVariableHandler::setstatusmessage(const char *msg) { } } -void DGUSScreenVariableHandler::setstatusmessagePGM(PGM_P const msg) { +void DGUSScreenHandler::setstatusmessagePGM(PGM_P const msg) { DGUS_VP_Variable ramcopy; if (populate_VPVar(VP_M117, &ramcopy)) { ramcopy.memadr = (void*) msg; @@ -156,32 +114,39 @@ void DGUSScreenVariableHandler::setstatusmessagePGM(PGM_P const msg) { } // Send an 8 bit or 16 bit value to the display. -void DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay(DGUS_VP_Variable &var) { +void DGUSScreenHandler::DGUSLCD_SendWordValueToDisplay(DGUS_VP_Variable &var) { if (var.memadr) { //DEBUG_ECHOPAIR(" DGUS_LCD_SendWordValueToDisplay ", var.VP); //DEBUG_ECHOLNPAIR(" data ", *(uint16_t *)var.memadr); - uint8_t *tmp = (uint8_t *) var.memadr; - uint16_t data_to_send = (tmp[0] << 8); - if (var.size >= 1) data_to_send |= tmp[1]; - dgusdisplay.WriteVariable(var.VP, data_to_send); + if (var.size > 1) + dgusdisplay.WriteVariable(var.VP, *(int16_t*)var.memadr); + else + dgusdisplay.WriteVariable(var.VP, *(int8_t*)var.memadr); } } // Send an uint8_t between 0 and 255 to the display, but scale to a percentage (0..100) -void DGUSScreenVariableHandler::DGUSLCD_SendPercentageToDisplay(DGUS_VP_Variable &var) { +void DGUSScreenHandler::DGUSLCD_SendPercentageToDisplay(DGUS_VP_Variable &var) { if (var.memadr) { //DEBUG_ECHOPAIR(" DGUS_LCD_SendWordValueToDisplay ", var.VP); //DEBUG_ECHOLNPAIR(" data ", *(uint16_t *)var.memadr); uint16_t tmp = *(uint8_t *) var.memadr +1 ; // +1 -> avoid rounding issues for the display. tmp = map(tmp, 0, 255, 0, 100); - uint16_t data_to_send = swap16(tmp); - dgusdisplay.WriteVariable(var.VP, data_to_send); + dgusdisplay.WriteVariable(var.VP, tmp); } } +// Send the current print progress to the display. +void DGUSScreenHandler::DGUSLCD_SendPrintProgressToDisplay(DGUS_VP_Variable &var) { + //DEBUG_ECHOPAIR(" DGUSLCD_SendPrintProgressToDisplay ", var.VP); + uint16_t tmp = ExtUI::getProgress_percent(); + //DEBUG_ECHOLNPAIR(" data ", tmp); + dgusdisplay.WriteVariable(var.VP, tmp); +} + // Send the current print time to the display. // It is using a hex display for that: It expects BSD coded data in the format xxyyzz -void DGUSScreenVariableHandler::DGUSLCD_SendPrintTimeToDisplay(DGUS_VP_Variable &var) { +void DGUSScreenHandler::DGUSLCD_SendPrintTimeToDisplay(DGUS_VP_Variable &var) { duration_t elapsed = print_job_timer.duration(); char buf[32]; elapsed.toString(buf); @@ -189,7 +154,7 @@ void DGUSScreenVariableHandler::DGUSLCD_SendPrintTimeToDisplay(DGUS_VP_Variable } // Send an uint8_t between 0 and 100 to a variable scale to 0..255 -void DGUSScreenVariableHandler::DGUSLCD_PercentageToUint8(DGUS_VP_Variable &var, void *val_ptr) { +void DGUSScreenHandler::DGUSLCD_PercentageToUint8(DGUS_VP_Variable &var, void *val_ptr) { if (var.memadr) { uint16_t value = swap16(*(uint16_t*)val_ptr); *(uint8_t*)var.memadr = map(constrain(value, 0, 100), 0, 100, 0, 255); @@ -199,7 +164,7 @@ void DGUSScreenVariableHandler::DGUSLCD_PercentageToUint8(DGUS_VP_Variable &var, // Sends a (RAM located) string to the DGUS Display // (Note: The DGUS Display does not clear after the \0, you have to // overwrite the remainings with spaces.// var.size has the display buffer size! -void DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplay(DGUS_VP_Variable &var) { +void DGUSScreenHandler::DGUSLCD_SendStringToDisplay(DGUS_VP_Variable &var) { char *tmp = (char*) var.memadr; dgusdisplay.WriteVariable(var.VP, tmp, var.size, true); } @@ -207,13 +172,13 @@ void DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplay(DGUS_VP_Variable &va // Sends a (flash located) string to the DGUS Display // (Note: The DGUS Display does not clear after the \0, you have to // overwrite the remainings with spaces.// var.size has the display buffer size! -void DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM(DGUS_VP_Variable &var) { +void DGUSScreenHandler::DGUSLCD_SendStringToDisplayPGM(DGUS_VP_Variable &var) { char *tmp = (char*) var.memadr; dgusdisplay.WriteVariablePGM(var.VP, tmp, var.size, true); } #if HAS_PID_HEATING - void DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID(DGUS_VP_Variable &var) { + void DGUSScreenHandler::DGUSLCD_SendTemperaturePID(DGUS_VP_Variable &var) { float value = *(float *)var.memadr; float valuesend = 0; switch (var.VP) { @@ -250,7 +215,7 @@ void DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM(DGUS_VP_Variable // Send the accumulate print time to the display. // It is using a hex display for that: It expects BSD coded data in the format xxyyzz - void DGUSScreenVariableHandler::DGUSLCD_SendPrintAccTimeToDisplay(DGUS_VP_Variable &var) { + void DGUSScreenHandler::DGUSLCD_SendPrintAccTimeToDisplay(DGUS_VP_Variable &var) { printStatistics state = print_job_timer.getStats(); char buf[21]; duration_t elapsed = state.printTime; @@ -258,7 +223,7 @@ void DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM(DGUS_VP_Variable dgusdisplay.WriteVariable(VP_PrintAccTime, buf, var.size, true); } - void DGUSScreenVariableHandler::DGUSLCD_SendPrintsTotalToDisplay(DGUS_VP_Variable &var) { + void DGUSScreenHandler::DGUSLCD_SendPrintsTotalToDisplay(DGUS_VP_Variable &var) { printStatistics state = print_job_timer.getStats(); char buf[21]; sprintf_P(buf, PSTR("%u"), state.totalPrints); @@ -268,40 +233,38 @@ void DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM(DGUS_VP_Variable #endif // Send fan status value to the display. -#if FAN_COUNT > 0 - void DGUSScreenVariableHandler::DGUSLCD_SendFanStatusToDisplay(DGUS_VP_Variable &var) { +#if HAS_FAN + void DGUSScreenHandler::DGUSLCD_SendFanStatusToDisplay(DGUS_VP_Variable &var) { if (var.memadr) { DEBUG_ECHOPAIR(" DGUSLCD_SendFanStatusToDisplay ", var.VP); DEBUG_ECHOLNPAIR(" data ", *(uint8_t *)var.memadr); uint16_t data_to_send = 0; if (*(uint8_t *) var.memadr) data_to_send = 1; - data_to_send = swap16(data_to_send); dgusdisplay.WriteVariable(var.VP, data_to_send); } } #endif // Send heater status value to the display. -void DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay(DGUS_VP_Variable &var) { +void DGUSScreenHandler::DGUSLCD_SendHeaterStatusToDisplay(DGUS_VP_Variable &var) { if (var.memadr) { DEBUG_ECHOPAIR(" DGUSLCD_SendHeaterStatusToDisplay ", var.VP); DEBUG_ECHOLNPAIR(" data ", *(int16_t *)var.memadr); uint16_t data_to_send = 0; if (*(int16_t *) var.memadr) data_to_send = 1; - data_to_send = swap16(data_to_send); dgusdisplay.WriteVariable(var.VP, data_to_send); } } #if ENABLED(DGUS_UI_WAITING) - void DGUSScreenVariableHandler::DGUSLCD_SendWaitingStatusToDisplay(DGUS_VP_Variable &var) { + void DGUSScreenHandler::DGUSLCD_SendWaitingStatusToDisplay(DGUS_VP_Variable &var) { // In FYSETC UI design there are 10 statuses to loop static uint16_t period = 0; static uint16_t index = 0; //DEBUG_ECHOPAIR(" DGUSLCD_SendWaitingStatusToDisplay ", var.VP); //DEBUG_ECHOLNPAIR(" data ", swap16(index)); if (period++ > DGUS_UI_WAITING_STATUS_PERIOD) { - dgusdisplay.WriteVariable(var.VP, swap16(index)); + dgusdisplay.WriteVariable(var.VP, index); //DEBUG_ECHOLNPAIR(" data ", swap16(index)); if (++index >= DGUS_UI_WAITING_STATUS) index = 0; period = 0; @@ -311,7 +274,7 @@ void DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay(DGUS_VP_Variab #if ENABLED(SDSUPPORT) - void DGUSScreenVariableHandler::ScreenChangeHookIfSD(DGUS_VP_Variable &var, void *val_ptr) { + void DGUSScreenHandler::ScreenChangeHookIfSD(DGUS_VP_Variable &var, void *val_ptr) { // default action executed when there is a SD card, but not printing if (ExtUI::isMediaInserted() && !ExtUI::isPrintingFromMedia()) { ScreenChangeHook(var, val_ptr); @@ -338,7 +301,7 @@ void DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay(DGUS_VP_Variab } } - void DGUSScreenVariableHandler::DGUSLCD_SD_ScrollFilelist(DGUS_VP_Variable& var, void *val_ptr) { + void DGUSScreenHandler::DGUSLCD_SD_ScrollFilelist(DGUS_VP_Variable& var, void *val_ptr) { auto old_top = top_file; const int16_t scroll = (int16_t)swap16(*(uint16_t*)val_ptr); if (scroll) { @@ -364,7 +327,7 @@ void DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay(DGUS_VP_Variab if (old_top != top_file) ForceCompleteUpdate(); } - void DGUSScreenVariableHandler::DGUSLCD_SD_FileSelected(DGUS_VP_Variable &var, void *val_ptr) { + void DGUSScreenHandler::DGUSLCD_SD_FileSelected(DGUS_VP_Variable &var, void *val_ptr) { uint16_t touched_nr = (int16_t)swap16(*(uint16_t*)val_ptr) + top_file; if (touched_nr > filelist.count()) return; if (!filelist.seek(touched_nr)) return; @@ -385,7 +348,7 @@ void DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay(DGUS_VP_Variab HandleUserConfirmationPopUp(VP_SD_FileSelectConfirm, nullptr, PSTR("Print file"), filelist.filename(), PSTR("from SD Card?"), true, true, false, true); } - void DGUSScreenVariableHandler::DGUSLCD_SD_StartPrint(DGUS_VP_Variable &var, void *val_ptr) { + void DGUSScreenHandler::DGUSLCD_SD_StartPrint(DGUS_VP_Variable &var, void *val_ptr) { if (!filelist.seek(file_to_print)) return; ExtUI::printFile(filelist.shortFilename()); ScreenHandler.GotoScreen( @@ -397,7 +360,7 @@ void DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay(DGUS_VP_Variab ); } - void DGUSScreenVariableHandler::DGUSLCD_SD_ResumePauseAbort(DGUS_VP_Variable &var, void *val_ptr) { + void DGUSScreenHandler::DGUSLCD_SD_ResumePauseAbort(DGUS_VP_Variable &var, void *val_ptr) { if (!ExtUI::isPrintingFromMedia()) return; // avoid race condition when user stays in this menu and printer finishes. switch (swap16(*(uint16_t*)val_ptr)) { case 0: // Resume @@ -412,17 +375,17 @@ void DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay(DGUS_VP_Variab } } - void DGUSScreenVariableHandler::DGUSLCD_SD_ReallyAbort(DGUS_VP_Variable &var, void *val_ptr) { + void DGUSScreenHandler::DGUSLCD_SD_ReallyAbort(DGUS_VP_Variable &var, void *val_ptr) { ExtUI::stopPrint(); GotoScreen(DGUSLCD_SCREEN_MAIN); } - void DGUSScreenVariableHandler::DGUSLCD_SD_PrintTune(DGUS_VP_Variable &var, void *val_ptr) { + void DGUSScreenHandler::DGUSLCD_SD_PrintTune(DGUS_VP_Variable &var, void *val_ptr) { if (!ExtUI::isPrintingFromMedia()) return; // avoid race condition when user stays in this menu and printer finishes. GotoScreen(DGUSLCD_SCREEN_SDPRINTTUNE); } - void DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename(DGUS_VP_Variable& var) { + void DGUSScreenHandler::DGUSLCD_SD_SendFilename(DGUS_VP_Variable& var) { uint16_t target_line = (var.VP - VP_SD_FileName0) / VP_SD_FileName_LEN; if (target_line > DGUS_SD_FILESPERSCREEN) return; char tmpfilename[VP_SD_FileName_LEN + 1] = ""; @@ -432,23 +395,23 @@ void DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay(DGUS_VP_Variab DGUSLCD_SendStringToDisplay(var); } - - void DGUSScreenVariableHandler::SDCardInserted() { + void DGUSScreenHandler::SDCardInserted() { top_file = 0; + filelist.refresh(); auto cs = ScreenHandler.getCurrentScreen(); if (cs == DGUSLCD_SCREEN_MAIN || cs == DGUSLCD_SCREEN_STATUS) ScreenHandler.GotoScreen(DGUSLCD_SCREEN_SDFILELIST); } - void DGUSScreenVariableHandler::SDCardRemoved() { + void DGUSScreenHandler::SDCardRemoved() { if (current_screen == DGUSLCD_SCREEN_SDFILELIST || (current_screen == DGUSLCD_SCREEN_CONFIRM && (ConfirmVP == VP_SD_AbortPrintConfirmed || ConfirmVP == VP_SD_FileSelectConfirm)) || current_screen == DGUSLCD_SCREEN_SDPRINTMANIPULATION ) ScreenHandler.GotoScreen(DGUSLCD_SCREEN_MAIN); } - void DGUSScreenVariableHandler::SDCardError() { - DGUSScreenVariableHandler::SDCardRemoved(); + void DGUSScreenHandler::SDCardError() { + DGUSScreenHandler::SDCardRemoved(); ScreenHandler.sendinfoscreen(PSTR("NOTICE"), nullptr, PSTR("SD card error"), nullptr, true, true, true, true); ScreenHandler.SetupConfirmAction(nullptr); ScreenHandler.GotoScreen(DGUSLCD_SCREEN_POPUP); @@ -456,7 +419,7 @@ void DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay(DGUS_VP_Variab #endif // SDSUPPORT -void DGUSScreenVariableHandler::ScreenConfirmedOK(DGUS_VP_Variable &var, void *val_ptr) { +void DGUSScreenHandler::ScreenConfirmedOK(DGUS_VP_Variable &var, void *val_ptr) { DGUS_VP_Variable ramcopy; if (!populate_VPVar(ConfirmVP, &ramcopy)) return; if (ramcopy.set_by_display_handler) ramcopy.set_by_display_handler(ramcopy, val_ptr); @@ -465,7 +428,7 @@ void DGUSScreenVariableHandler::ScreenConfirmedOK(DGUS_VP_Variable &var, void *v const uint16_t* DGUSLCD_FindScreenVPMapList(uint8_t screen) { const uint16_t *ret; const struct VPMapping *map = VPMap; - while (ret = (uint16_t*) pgm_read_word(&(map->VPList))) { + while (ret = (uint16_t*) pgm_read_ptr(&(map->VPList))) { if (pgm_read_byte(&(map->screen)) == screen) return ret; map++; } @@ -485,14 +448,14 @@ const DGUS_VP_Variable* DGUSLCD_FindVPVar(const uint16_t vp) { return nullptr; } -void DGUSScreenVariableHandler::ScreenChangeHookIfIdle(DGUS_VP_Variable &var, void *val_ptr) { +void DGUSScreenHandler::ScreenChangeHookIfIdle(DGUS_VP_Variable &var, void *val_ptr) { if (!ExtUI::isPrinting()) { ScreenChangeHook(var, val_ptr); dgusdisplay.RequestScreen(current_screen); } } -void DGUSScreenVariableHandler::ScreenChangeHook(DGUS_VP_Variable &var, void *val_ptr) { +void DGUSScreenHandler::ScreenChangeHook(DGUS_VP_Variable &var, void *val_ptr) { uint8_t *tmp = (uint8_t*)val_ptr; // The keycode in target is coded as , so 0x0100A means @@ -514,12 +477,12 @@ void DGUSScreenVariableHandler::ScreenChangeHook(DGUS_VP_Variable &var, void *va #endif } -void DGUSScreenVariableHandler::HandleAllHeatersOff(DGUS_VP_Variable &var, void *val_ptr) { +void DGUSScreenHandler::HandleAllHeatersOff(DGUS_VP_Variable &var, void *val_ptr) { thermalManager.disable_all_heaters(); ScreenHandler.ForceCompleteUpdate(); // hint to send all data. } -void DGUSScreenVariableHandler::HandleTemperatureChanged(DGUS_VP_Variable &var, void *val_ptr) { +void DGUSScreenHandler::HandleTemperatureChanged(DGUS_VP_Variable &var, void *val_ptr) { uint16_t newvalue = swap16(*(uint16_t*)val_ptr); uint16_t acceptedvalue; @@ -550,7 +513,7 @@ void DGUSScreenVariableHandler::HandleTemperatureChanged(DGUS_VP_Variable &var, ScreenHandler.skipVP = var.VP; // don't overwrite value the next update time as the display might autoincrement in parallel } -void DGUSScreenVariableHandler::HandleFlowRateChanged(DGUS_VP_Variable &var, void *val_ptr) { +void DGUSScreenHandler::HandleFlowRateChanged(DGUS_VP_Variable &var, void *val_ptr) { #if EXTRUDERS uint16_t newvalue = swap16(*(uint16_t*)val_ptr); uint8_t target_extruder; @@ -564,15 +527,14 @@ void DGUSScreenVariableHandler::HandleFlowRateChanged(DGUS_VP_Variable &var, voi #endif } - planner.flow_percentage[target_extruder] = newvalue; - planner.refresh_e_factor(target_extruder); + planner.set_flow(target_extruder, newvalue); ScreenHandler.skipVP = var.VP; // don't overwrite value the next update time as the display might autoincrement in parallel #else UNUSED(var); UNUSED(val_ptr); #endif } -void DGUSScreenVariableHandler::HandleManualExtrude(DGUS_VP_Variable &var, void *val_ptr) { +void DGUSScreenHandler::HandleManualExtrude(DGUS_VP_Variable &var, void *val_ptr) { DEBUG_ECHOLNPGM("HandleManualExtrude"); int16_t movevalue = swap16(*(uint16_t*)val_ptr); @@ -584,7 +546,7 @@ void DGUSScreenVariableHandler::HandleManualExtrude(DGUS_VP_Variable &var, void case VP_MOVE_E0: target_extruder = ExtUI::extruder_t::E0; break; #endif #if HOTENDS >= 2 - case VP_MOVE_E1: target_extruder = ExtUI::extruder_t::E1; break + case VP_MOVE_E1: target_extruder = ExtUI::extruder_t::E1; break; #endif default: return; } @@ -594,20 +556,22 @@ void DGUSScreenVariableHandler::HandleManualExtrude(DGUS_VP_Variable &var, void skipVP = var.VP; } -#if ENABLED(DUGS_UI_MOVE_DIS_OPTION) - void DGUSScreenVariableHandler::HandleManualMoveOption(DGUS_VP_Variable &var, void *val_ptr) { +#if ENABLED(DGUS_UI_MOVE_DIS_OPTION) + void DGUSScreenHandler::HandleManualMoveOption(DGUS_VP_Variable &var, void *val_ptr) { DEBUG_ECHOLNPGM("HandleManualMoveOption"); *(uint16_t*)var.memadr = swap16(*(uint16_t*)val_ptr); } #endif -void DGUSScreenVariableHandler::HandleManualMove(DGUS_VP_Variable &var, void *val_ptr) { +void DGUSScreenHandler::HandleManualMove(DGUS_VP_Variable &var, void *val_ptr) { DEBUG_ECHOLNPGM("HandleManualMove"); int16_t movevalue = swap16(*(uint16_t*)val_ptr); - #if ENABLED(DUGS_UI_MOVE_DIS_OPTION) - const uint16_t choice = *(uint16_t*)var.memadr; - movevalue = movevalue > 0 ? choice : -choice; + #if ENABLED(DGUS_UI_MOVE_DIS_OPTION) + if (movevalue) { + const uint16_t choice = *(uint16_t*)var.memadr; + movevalue = movevalue < 0 ? -choice : choice; + } #endif char axiscode; unsigned int speed = 1500; //FIXME: get default feedrate for manual moves, dont hardcode. @@ -690,7 +654,7 @@ void DGUSScreenVariableHandler::HandleManualMove(DGUS_VP_Variable &var, void *va return; } -void DGUSScreenVariableHandler::HandleMotorLockUnlock(DGUS_VP_Variable &var, void *val_ptr) { +void DGUSScreenHandler::HandleMotorLockUnlock(DGUS_VP_Variable &var, void *val_ptr) { DEBUG_ECHOLNPGM("HandleMotorLockUnlock"); char buf[4]; @@ -703,7 +667,7 @@ void DGUSScreenVariableHandler::HandleMotorLockUnlock(DGUS_VP_Variable &var, voi #if ENABLED(POWER_LOSS_RECOVERY) - void DGUSScreenVariableHandler::HandlePowerLossRecovery(DGUS_VP_Variable &var, void *val_ptr) { + void DGUSScreenHandler::HandlePowerLossRecovery(DGUS_VP_Variable &var, void *val_ptr) { uint16_t value = swap16(*(uint16_t*)val_ptr); if (value) { queue.inject_P(PSTR("M1000")); @@ -717,23 +681,21 @@ void DGUSScreenVariableHandler::HandleMotorLockUnlock(DGUS_VP_Variable &var, voi #endif -void DGUSScreenVariableHandler::HandleSettings(DGUS_VP_Variable &var, void *val_ptr) { +void DGUSScreenHandler::HandleSettings(DGUS_VP_Variable &var, void *val_ptr) { DEBUG_ECHOLNPGM("HandleSettings"); uint16_t value = swap16(*(uint16_t*)val_ptr); switch (value) { default: break; case 1: - #if ENABLED(PRINTCOUNTER) - print_job_timer.initStats(); - #endif - queue.enqueue_now_P(PSTR("M502\nM500")); + TERN_(PRINTCOUNTER, print_job_timer.initStats()); + queue.inject_P(PSTR("M502\nM500")); break; - case 2: queue.enqueue_now_P(PSTR("M501")); break; - case 3: queue.enqueue_now_P(PSTR("M500")); break; + case 2: queue.inject_P(PSTR("M501")); break; + case 3: queue.inject_P(PSTR("M500")); break; } } -void DGUSScreenVariableHandler::HandleStepPerMMChanged(DGUS_VP_Variable &var, void *val_ptr) { +void DGUSScreenHandler::HandleStepPerMMChanged(DGUS_VP_Variable &var, void *val_ptr) { DEBUG_ECHOLNPGM("HandleStepPerMMChanged"); uint16_t value_raw = swap16(*(uint16_t*)val_ptr); @@ -753,7 +715,7 @@ void DGUSScreenVariableHandler::HandleStepPerMMChanged(DGUS_VP_Variable &var, vo return; } -void DGUSScreenVariableHandler::HandleStepPerMMExtruderChanged(DGUS_VP_Variable &var, void *val_ptr) { +void DGUSScreenHandler::HandleStepPerMMExtruderChanged(DGUS_VP_Variable &var, void *val_ptr) { DEBUG_ECHOLNPGM("HandleStepPerMMExtruderChanged"); uint16_t value_raw = swap16(*(uint16_t*)val_ptr); @@ -777,7 +739,7 @@ void DGUSScreenVariableHandler::HandleStepPerMMExtruderChanged(DGUS_VP_Variable } #if HAS_PID_HEATING - void DGUSScreenVariableHandler::HandleTemperaturePIDChanged(DGUS_VP_Variable &var, void *val_ptr) { + void DGUSScreenHandler::HandleTemperaturePIDChanged(DGUS_VP_Variable &var, void *val_ptr) { uint16_t rawvalue = swap16(*(uint16_t*)val_ptr); DEBUG_ECHOLNPAIR("V1:", rawvalue); float value = (float)rawvalue / 10; @@ -808,7 +770,7 @@ void DGUSScreenVariableHandler::HandleStepPerMMExtruderChanged(DGUS_VP_Variable ScreenHandler.skipVP = var.VP; // don't overwrite value the next update time as the display might autoincrement in parallel } - void DGUSScreenVariableHandler::HandlePIDAutotune(DGUS_VP_Variable &var, void *val_ptr) { + void DGUSScreenHandler::HandlePIDAutotune(DGUS_VP_Variable &var, void *val_ptr) { DEBUG_ECHOLNPGM("HandlePIDAutotune"); char buf[32] = {0}; @@ -843,35 +805,37 @@ void DGUSScreenVariableHandler::HandleStepPerMMExtruderChanged(DGUS_VP_Variable } #endif -void DGUSScreenVariableHandler::HandleProbeOffsetZChanged(DGUS_VP_Variable &var, void *val_ptr) { - DEBUG_ECHOLNPGM("HandleProbeOffsetZChanged"); +#if HAS_BED_PROBE + void DGUSScreenHandler::HandleProbeOffsetZChanged(DGUS_VP_Variable &var, void *val_ptr) { + DEBUG_ECHOLNPGM("HandleProbeOffsetZChanged"); - uint16_t value = swap16(*(uint16_t*)val_ptr)/100; - ExtUI::setZOffset_mm(value); - ScreenHandler.skipVP = var.VP; // don't overwrite value the next update time as the display might autoincrement in parallel - return; -} + const float offset = float(int16_t(swap16(*(uint16_t*)val_ptr))) / 100.0f; + ExtUI::setZOffset_mm(offset); + ScreenHandler.skipVP = var.VP; // don't overwrite value the next update time as the display might autoincrement in parallel + return; + } +#endif #if ENABLED(BABYSTEPPING) - void DGUSScreenVariableHandler::HandleLiveAdjustZ(DGUS_VP_Variable &var, void *val_ptr) { + void DGUSScreenHandler::HandleLiveAdjustZ(DGUS_VP_Variable &var, void *val_ptr) { DEBUG_ECHOLNPGM("HandleLiveAdjustZ"); int16_t flag = swap16(*(uint16_t*)val_ptr); int16_t steps = flag ? -20 : 20; - ExtUI::smartAdjustAxis_steps(steps,ExtUI::axis_t::Z,true); + ExtUI::smartAdjustAxis_steps(steps, ExtUI::axis_t::Z, true); ScreenHandler.ForceCompleteUpdate(); return; } #endif -#if FAN_COUNT - void DGUSScreenVariableHandler::HandleFanControl(DGUS_VP_Variable &var, void *val_ptr) { +#if HAS_FAN + void DGUSScreenHandler::HandleFanControl(DGUS_VP_Variable &var, void *val_ptr) { DEBUG_ECHOLNPGM("HandleFanControl"); *(uint8_t*)var.memadr = *(uint8_t*)var.memadr > 0 ? 0 : 255; } #endif -void DGUSScreenVariableHandler::HandleHeaterControl(DGUS_VP_Variable &var, void *val_ptr) { +void DGUSScreenHandler::HandleHeaterControl(DGUS_VP_Variable &var, void *val_ptr) { DEBUG_ECHOLNPGM("HandleHeaterControl"); uint8_t preheat_temp = 0; @@ -897,49 +861,41 @@ void DGUSScreenVariableHandler::HandleHeaterControl(DGUS_VP_Variable &var, void } #if ENABLED(DGUS_PREHEAT_UI) - void DGUSScreenVariableHandler::HandlePreheat(DGUS_VP_Variable &var, void *val_ptr) { + + void DGUSScreenHandler::HandlePreheat(DGUS_VP_Variable &var, void *val_ptr) { DEBUG_ECHOLNPGM("HandlePreheat"); uint8_t e_temp = 0; - uint8_t bed_temp = 0; + TERN_(HAS_HEATED_BED, uint8_t bed_temp = 0); const uint16_t preheat_option = swap16(*(uint16_t*)val_ptr); switch (preheat_option) { + default: case 0: // Preheat PLA #if defined(PREHEAT_1_TEMP_HOTEND) && defined(PREHEAT_1_TEMP_BED) e_temp = PREHEAT_1_TEMP_HOTEND; - bed_temp = PREHEAT_1_TEMP_BED; + TERN_(HAS_HEATED_BED, bed_temp = PREHEAT_1_TEMP_BED); #endif break; case 1: // Preheat ABS #if defined(PREHEAT_2_TEMP_HOTEND) && defined(PREHEAT_2_TEMP_BED) e_temp = PREHEAT_2_TEMP_HOTEND; - bed_temp = PREHEAT_2_TEMP_BED; + TERN_(HAS_HEATED_BED, bed_temp = PREHEAT_2_TEMP_BED); #endif break; case 2: // Preheat PET #if defined(PREHEAT_3_TEMP_HOTEND) && defined(PREHEAT_3_TEMP_BED) e_temp = PREHEAT_3_TEMP_HOTEND; - bed_temp = PREHEAT_3_TEMP_BED; + TERN_(HAS_HEATED_BED, bed_temp = PREHEAT_3_TEMP_BED); #endif break; case 3: // Preheat FLEX #if defined(PREHEAT_4_TEMP_HOTEND) && defined(PREHEAT_4_TEMP_BED) e_temp = PREHEAT_4_TEMP_HOTEND; - bed_temp = PREHEAT_4_TEMP_BED; - #endif - break; - case 7: // Custom preheat - break; - case 9: // Cool down - e_temp = 0; - bed_temp = 0; - break; - default: - #if defined(PREHEAT_1_TEMP_HOTEND) && defined(PREHEAT_1_TEMP_BED) - e_temp = PREHEAT_1_TEMP_HOTEND; - bed_temp = PREHEAT_1_TEMP_BED; + TERN_(HAS_HEATED_BED, bed_temp = PREHEAT_4_TEMP_BED); #endif break; + case 7: break; // Custom preheat + case 9: break; // Cool down } switch (var.VP) { @@ -947,17 +903,13 @@ void DGUSScreenVariableHandler::HandleHeaterControl(DGUS_VP_Variable &var, void #if HOTENDS >= 1 case VP_E0_BED_PREHEAT: thermalManager.setTargetHotend(e_temp, 0); - #if HAS_HEATED_BED - thermalManager.setTargetBed(bed_temp); - #endif + TERN_(HAS_HEATED_BED, thermalManager.setTargetBed(bed_temp)); break; #endif #if HOTENDS >= 2 case VP_E1_BED_PREHEAT: thermalManager.setTargetHotend(e_temp, 1); - #if HAS_HEATED_BED - thermalManager.setTargetBed(bed_temp); - #endif + TERN_(HAS_HEATED_BED, thermalManager.setTargetBed(bed_temp)); break; #endif } @@ -965,10 +917,21 @@ void DGUSScreenVariableHandler::HandleHeaterControl(DGUS_VP_Variable &var, void // Go to the preheat screen to show the heating progress GotoScreen(DGUSLCD_SCREEN_PREHEAT); } + #endif #if ENABLED(DGUS_FILAMENT_LOADUNLOAD) - void DGUSScreenVariableHandler::HandleFilamentOption(DGUS_VP_Variable &var, void *val_ptr) { + + typedef struct { + ExtUI::extruder_t extruder; // which extruder to operate + uint8_t action; // load or unload + bool heated; // heating done ? + float purge_length; // the length to extrude before unload, prevent filament jam + } filament_data_t; + + static filament_data_t filament_data; + + void DGUSScreenHandler::HandleFilamentOption(DGUS_VP_Variable &var, void *val_ptr) { DEBUG_ECHOLNPGM("HandleFilamentOption"); uint8_t e_temp = 0; @@ -991,9 +954,7 @@ void DGUSScreenVariableHandler::HandleHeaterControl(DGUS_VP_Variable &var, void #endif break; case 1: // Load ABS - #if ENABLED(PREHEAT_2_TEMP_HOTEND) - e_temp = PREHEAT_2_TEMP_HOTEND; - #endif + TERN_(PREHEAT_2_TEMP_HOTEND, e_temp = PREHEAT_2_TEMP_HOTEND); break; case 2: // Load PET #ifdef PREHEAT_3_TEMP_HOTEND @@ -1040,7 +1001,7 @@ void DGUSScreenVariableHandler::HandleHeaterControl(DGUS_VP_Variable &var, void } } - void DGUSScreenVariableHandler::HandleFilamentLoadUnload(DGUS_VP_Variable &var) { + void DGUSScreenHandler::HandleFilamentLoadUnload(DGUS_VP_Variable &var) { DEBUG_ECHOLNPGM("HandleFilamentLoadUnload"); if (filament_data.action <= 0) return; @@ -1074,7 +1035,7 @@ void DGUSScreenVariableHandler::HandleHeaterControl(DGUS_VP_Variable &var, void } #endif -void DGUSScreenVariableHandler::UpdateNewScreen(DGUSLCD_Screens newscreen, bool popup) { +void DGUSScreenHandler::UpdateNewScreen(DGUSLCD_Screens newscreen, bool popup) { DEBUG_ECHOLNPAIR("SetNewScreen: ", newscreen); if (!popup) { @@ -1087,14 +1048,14 @@ void DGUSScreenVariableHandler::UpdateNewScreen(DGUSLCD_Screens newscreen, bool ForceCompleteUpdate(); } -void DGUSScreenVariableHandler::PopToOldScreen() { +void DGUSScreenHandler::PopToOldScreen() { DEBUG_ECHOLNPAIR("PopToOldScreen s=", past_screens[0]); GotoScreen(past_screens[0], true); memmove(&past_screens[0], &past_screens[1], sizeof(past_screens) - 1); past_screens[sizeof(past_screens) - 1] = DGUSLCD_SCREEN_MAIN; } -void DGUSScreenVariableHandler::UpdateScreenVPData() { +void DGUSScreenHandler::UpdateScreenVPData() { DEBUG_ECHOPAIR(" UpdateScreenVPData Screen: ", current_screen); const uint16_t *VPList = DGUSLCD_FindScreenVPMapList(current_screen); @@ -1142,68 +1103,12 @@ void DGUSScreenVariableHandler::UpdateScreenVPData() { } while (++update_ptr, ++VPList, true); } -void DGUSDisplay::loop() { - // protect against recursion… ProcessRx() may indirectly call idle() when injecting gcode commands. - if (!no_reentrance) { - no_reentrance = true; - ProcessRx(); - no_reentrance = false; - } -} - -void DGUSDisplay::InitDisplay() { - dgusserial.begin(DGUS_BAUDRATE); - - if (true - #if ENABLED(POWER_LOSS_RECOVERY) - && !recovery.valid() - #endif - ) - RequestScreen( - #if ENABLED(SHOW_BOOTSCREEN) - DGUSLCD_SCREEN_BOOT - #else - DGUSLCD_SCREEN_MAIN - #endif - ); -} - -void DGUSDisplay::WriteVariable(uint16_t adr, const void* values, uint8_t valueslen, bool isstr) { - const char* myvalues = static_cast(values); - bool strend = !myvalues; - WriteHeader(adr, DGUS_CMD_WRITEVAR, valueslen); - while (valueslen--) { - char x; - if (!strend) x = *myvalues++; - if ((isstr && !x) || strend) { - strend = true; - x = ' '; - } - dgusserial.write(x); - } -} - -void DGUSDisplay::WriteVariablePGM(uint16_t adr, const void* values, uint8_t valueslen, bool isstr) { - const char* myvalues = static_cast(values); - bool strend = !myvalues; - WriteHeader(adr, DGUS_CMD_WRITEVAR, valueslen); - while (valueslen--) { - char x; - if (!strend) x = pgm_read_byte(myvalues++); - if ((isstr && !x) || strend) { - strend = true; - x = ' '; - } - dgusserial.write(x); - } -} - -void DGUSScreenVariableHandler::GotoScreen(DGUSLCD_Screens screen, bool ispopup) { +void DGUSScreenHandler::GotoScreen(DGUSLCD_Screens screen, bool ispopup) { dgusdisplay.RequestScreen(screen); UpdateNewScreen(screen, ispopup); } -bool DGUSScreenVariableHandler::loop() { +bool DGUSScreenHandler::loop() { dgusdisplay.loop(); const millis_t ms = millis(); @@ -1216,9 +1121,8 @@ bool DGUSScreenVariableHandler::loop() { #if ENABLED(SHOW_BOOTSCREEN) static bool booted = false; - #if ENABLED(POWER_LOSS_RECOVERY) - if (!booted && recovery.valid()) booted = true; - #endif + if (!booted && TERN0(POWER_LOSS_RECOVERY, recovery.valid())) + booted = true; if (!booted && ELAPSED(ms, BOOTSCREEN_TIMEOUT)) { booted = true; GotoScreen(DGUSLCD_SCREEN_MAIN); @@ -1233,117 +1137,4 @@ void DGUSDisplay::RequestScreen(DGUSLCD_Screens screen) { WriteVariable(0x84, gotoscreen, sizeof(gotoscreen)); } -void DGUSDisplay::ProcessRx() { - - #if ENABLED(DGUS_SERIAL_STATS_RX_BUFFER_OVERRUNS) - if (!dgusserial.available() && dgusserial.buffer_overruns()) { - // Overrun, but reset the flag only when the buffer is empty - // We want to extract as many as valid datagrams possible... - DEBUG_ECHOPGM("OVFL"); - rx_datagram_state = DGUS_IDLE; - //dgusserial.reset_rx_overun(); - dgusserial.flush(); - } - #endif - - uint8_t receivedbyte; - while (dgusserial.available()) { - switch (rx_datagram_state) { - - case DGUS_IDLE: // Waiting for the first header byte - receivedbyte = dgusserial.read(); - //DEBUG_ECHOPAIR("< ",x); - if (DGUS_HEADER1 == receivedbyte) rx_datagram_state = DGUS_HEADER1_SEEN; - break; - - case DGUS_HEADER1_SEEN: // Waiting for the second header byte - receivedbyte = dgusserial.read(); - //DEBUG_ECHOPAIR(" ",x); - rx_datagram_state = (DGUS_HEADER2 == receivedbyte) ? DGUS_HEADER2_SEEN : DGUS_IDLE; - break; - - case DGUS_HEADER2_SEEN: // Waiting for the length byte - rx_datagram_len = dgusserial.read(); - DEBUG_ECHOPAIR(" (", rx_datagram_len, ") "); - - // Telegram min len is 3 (command and one word of payload) - rx_datagram_state = WITHIN(rx_datagram_len, 3, DGUS_RX_BUFFER_SIZE) ? DGUS_WAIT_TELEGRAM : DGUS_IDLE; - break; - - case DGUS_WAIT_TELEGRAM: // wait for complete datagram to arrive. - if (dgusserial.available() < rx_datagram_len) return; - - Initialized = true; // We've talked to it, so we defined it as initialized. - uint8_t command = dgusserial.read(); - - DEBUG_ECHOPAIR("# ", command); - - uint8_t readlen = rx_datagram_len - 1; // command is part of len. - unsigned char tmp[rx_datagram_len - 1]; - unsigned char *ptmp = tmp; - while (readlen--) { - receivedbyte = dgusserial.read(); - DEBUG_ECHOPAIR(" ", receivedbyte); - *ptmp++ = receivedbyte; - } - DEBUG_ECHOPGM(" # "); - // mostly we'll get this: 5A A5 03 82 4F 4B -- ACK on 0x82, so discard it. - if (command == DGUS_CMD_WRITEVAR && 'O' == tmp[0] && 'K' == tmp[1]) { - DEBUG_ECHOLNPGM(">"); - rx_datagram_state = DGUS_IDLE; - break; - } - - /* AutoUpload, (and answer to) Command 0x83 : - | tmp[0 1 2 3 4 ... ] - | Example 5A A5 06 83 20 01 01 78 01 …… - | / / | | \ / | \ \ - | Header | | | | \_____\_ DATA (Words!) - | DatagramLen / VPAdr | - | Command DataLen (in Words) */ - if (command == DGUS_CMD_READVAR) { - const uint16_t vp = tmp[0] << 8 | tmp[1]; - const uint8_t dlen = tmp[2] << 1; // Convert to Bytes. (Display works with words) - //DEBUG_ECHOPAIR(" vp=", vp, " dlen=", dlen); - DGUS_VP_Variable ramcopy; - if (populate_VPVar(vp, &ramcopy)) { - if (!(dlen == ramcopy.size || (dlen == 2 && ramcopy.size == 1))) - DEBUG_ECHOLNPGM("SIZE MISMATCH"); - else if (ramcopy.set_by_display_handler) { - ramcopy.set_by_display_handler(ramcopy, &tmp[3]); - } - else - DEBUG_ECHOLNPGM(" VPVar found, no handler."); - } - else - DEBUG_ECHOLNPAIR(" VPVar not found:", vp); - - rx_datagram_state = DGUS_IDLE; - break; - } - - // discard anything else - rx_datagram_state = DGUS_IDLE; - } - } -} - -size_t DGUSDisplay::GetFreeTxBuffer() { return DGUS_SERIAL_GET_TX_BUFFER_FREE(); } - -void DGUSDisplay::WriteHeader(uint16_t adr, uint8_t cmd, uint8_t payloadlen) { - dgusserial.write(DGUS_HEADER1); - dgusserial.write(DGUS_HEADER2); - dgusserial.write(payloadlen + 3); - dgusserial.write(cmd); - dgusserial.write(adr >> 8); - dgusserial.write(adr & 0xFF); -} - -void DGUSDisplay::WritePGM(const char str[], uint8_t len) { - while (len--) dgusserial.write(pgm_read_byte(str++)); -} - -// A SW memory barrier, to ensure GCC does not overoptimize loops -#define sw_barrier() asm volatile("": : :"memory"); - #endif // HAS_DGUS_LCD diff --git a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.h b/Marlin/src/lcd/extui/lib/dgus/DGUSScreenHandler.h similarity index 73% rename from Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.h rename to Marlin/src/lcd/extui/lib/dgus/DGUSScreenHandler.h index 165aab7ed674..df738dbfd144 100644 --- a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.h +++ b/Marlin/src/lcd/extui/lib/dgus/DGUSScreenHandler.h @@ -16,83 +16,21 @@ * 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 . + * along with this program. If not, see . * */ #pragma once -/* DGUS implementation written by coldtobi in 2019 for Marlin */ - -#include "../../../../inc/MarlinConfigPre.h" - -#include "../../../../MarlinCore.h" +#include "DGUSDisplay.h" #include "DGUSVPVariable.h" -enum DGUSLCD_Screens : uint8_t; - -#define DEBUG_OUT ENABLED(DEBUG_DGUSLCD) -#include "../../../../core/debug_out.h" - -typedef enum : uint8_t { - DGUS_IDLE, //< waiting for DGUS_HEADER1. - DGUS_HEADER1_SEEN, //< DGUS_HEADER1 received - DGUS_HEADER2_SEEN, //< DGUS_HEADER2 received - DGUS_WAIT_TELEGRAM, //< LEN received, Waiting for to receive all bytes. -} rx_datagram_state_t; - -// Low-Level access to the display. -class DGUSDisplay { -public: - - DGUSDisplay() = default; - - static void InitDisplay(); - - // Variable access. - static void WriteVariable(uint16_t adr, const void* values, uint8_t valueslen, bool isstr=false); - static void WriteVariablePGM(uint16_t adr, const void* values, uint8_t valueslen, bool isstr=false); - template - static void WriteVariable(uint16_t adr, T value) { - WriteVariable(adr, static_cast(&value), sizeof(T)); - } - - // Until now I did not need to actively read from the display. That's why there is no ReadVariable - // (I extensively use the auto upload of the display) - - // Force display into another screen. - // (And trigger update of containing VPs) - // (to implement a pop up message, which may not be nested) - static void RequestScreen(DGUSLCD_Screens screen); - - // Periodic tasks, eg. Rx-Queue handling. - static void loop(); +#include "../../../../inc/MarlinConfig.h" -public: - // Helper for users of this class to estimate if an interaction would be blocking. - static size_t GetFreeTxBuffer(); - - // Checks two things: Can we confirm the presence of the display and has we initiliazed it. - // (both boils down that the display answered to our chatting) - static inline bool isInitialized() { return Initialized; } - -private: - static void WriteHeader(uint16_t adr, uint8_t cmd, uint8_t payloadlen); - static void WritePGM(const char str[], uint8_t len); - static void ProcessRx(); - - static rx_datagram_state_t rx_datagram_state; - static uint8_t rx_datagram_len; - static bool Initialized, no_reentrance; -}; - -extern DGUSDisplay dgusdisplay; - -// compile-time x^y -constexpr float cpow(const float x, const int y) { return y == 0 ? 1.0 : x * cpow(x, y - 1); } +enum DGUSLCD_Screens : uint8_t; -class DGUSScreenVariableHandler { +class DGUSScreenHandler { public: - DGUSScreenVariableHandler() = default; + DGUSScreenHandler() = default; static bool loop(); @@ -116,7 +54,7 @@ class DGUSScreenVariableHandler { static void HandleTemperatureChanged(DGUS_VP_Variable &var, void *val_ptr); // Hook for "Change Flowrate" static void HandleFlowRateChanged(DGUS_VP_Variable &var, void *val_ptr); - #if ENABLED(DUGS_UI_MOVE_DIS_OPTION) + #if ENABLED(DGUS_UI_MOVE_DIS_OPTION) // Hook for manual move option static void HandleManualMoveOption(DGUS_VP_Variable &var, void *val_ptr); #endif @@ -140,13 +78,15 @@ class DGUSScreenVariableHandler { // Hook for PID autotune static void HandlePIDAutotune(DGUS_VP_Variable &var, void *val_ptr); #endif - // Hook for "Change probe offset z" - static void HandleProbeOffsetZChanged(DGUS_VP_Variable &var, void *val_ptr); + #if HAS_BED_PROBE + // Hook for "Change probe offset z" + static void HandleProbeOffsetZChanged(DGUS_VP_Variable &var, void *val_ptr); + #endif #if ENABLED(BABYSTEPPING) // Hook for live z adjust action static void HandleLiveAdjustZ(DGUS_VP_Variable &var, void *val_ptr); #endif - #if FAN_COUNT > 0 + #if HAS_FAN // Hook for fan control static void HandleFanControl(DGUS_VP_Variable &var, void *val_ptr); #endif @@ -210,12 +150,13 @@ class DGUSScreenVariableHandler { static void DGUSLCD_SendStringToDisplayPGM(DGUS_VP_Variable &var); static void DGUSLCD_SendTemperaturePID(DGUS_VP_Variable &var); static void DGUSLCD_SendPercentageToDisplay(DGUS_VP_Variable &var); + static void DGUSLCD_SendPrintProgressToDisplay(DGUS_VP_Variable &var); static void DGUSLCD_SendPrintTimeToDisplay(DGUS_VP_Variable &var); #if ENABLED(PRINTCOUNTER) static void DGUSLCD_SendPrintAccTimeToDisplay(DGUS_VP_Variable &var); static void DGUSLCD_SendPrintsTotalToDisplay(DGUS_VP_Variable &var); #endif - #if FAN_COUNT > 0 + #if HAS_FAN static void DGUSLCD_SendFanStatusToDisplay(DGUS_VP_Variable &var); #endif static void DGUSLCD_SendHeaterStatusToDisplay(DGUS_VP_Variable &var); @@ -231,7 +172,7 @@ class DGUSScreenVariableHandler { if (!var.memadr) return; union { unsigned char tmp[sizeof(T)]; T t; } x; unsigned char *ptr = (unsigned char*)val_ptr; - for (uint8_t i = 0; i < sizeof(T); i++) x.tmp[i] = ptr[sizeof(T) - i - 1]; + LOOP_L_N(i, sizeof(T)) x.tmp[i] = ptr[sizeof(T) - i - 1]; *(T*)var.memadr = x.t; } @@ -243,15 +184,7 @@ class DGUSScreenVariableHandler { if (var.memadr) { float f = *(float *)var.memadr; f *= cpow(10, decimals); - union { long l; char lb[4]; } endian; - - char tmp[4]; - endian.l = f; - tmp[0] = endian.lb[3]; - tmp[1] = endian.lb[2]; - tmp[2] = endian.lb[1]; - tmp[3] = endian.lb[0]; - dgusdisplay.WriteVariable(var.VP, tmp, 4); + dgusdisplay.WriteVariable(var.VP, (long)f); } } @@ -264,13 +197,7 @@ class DGUSScreenVariableHandler { float f = *(float *)var.memadr; DEBUG_ECHOLNPAIR_F(" >> ", f, 6); f *= cpow(10, decimals); - union { int16_t i; char lb[2]; } endian; - - char tmp[2]; - endian.i = f; - tmp[0] = endian.lb[1]; - tmp[1] = endian.lb[0]; - dgusdisplay.WriteVariable(var.VP, tmp, 2); + dgusdisplay.WriteVariable(var.VP, (int16_t)f); } } @@ -302,10 +229,4 @@ class DGUSScreenVariableHandler { static void (*confirm_action_cb)(); }; -extern DGUSScreenVariableHandler ScreenHandler; - -/// Find the flash address of a DGUS_VP_Variable for the VP. -extern const DGUS_VP_Variable* DGUSLCD_FindVPVar(const uint16_t vp); - -/// Helper to populate a DGUS_VP_Variable for a given VP. Return false if not found. -extern bool populate_VPVar(const uint16_t VP, DGUS_VP_Variable * const ramcopy); +extern DGUSScreenHandler ScreenHandler; diff --git a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSVPVariable.h b/Marlin/src/lcd/extui/lib/dgus/DGUSVPVariable.h similarity index 93% rename from Marlin/src/lcd/extensible_ui/lib/dgus/DGUSVPVariable.h rename to Marlin/src/lcd/extui/lib/dgus/DGUSVPVariable.h index 30555bbb9f3a..8c193c7c1edd 100644 --- a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSVPVariable.h +++ b/Marlin/src/lcd/extui/lib/dgus/DGUSVPVariable.h @@ -16,11 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once +#include + /** * DGUSVPVariable.h * diff --git a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinitionFYSETC.cpp b/Marlin/src/lcd/extui/lib/dgus/fysetc/DGUSDisplayDef.cpp similarity index 54% rename from Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinitionFYSETC.cpp rename to Marlin/src/lcd/extui/lib/dgus/fysetc/DGUSDisplayDef.cpp index 6e26e6343479..3beed892e35b 100644 --- a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinitionFYSETC.cpp +++ b/Marlin/src/lcd/extui/lib/dgus/fysetc/DGUSDisplayDef.cpp @@ -16,28 +16,29 @@ * 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 . + * along with this program. If not, see . * */ /* DGUS VPs changed by George Fu in 2019 for Marlin */ -#include "../../../../inc/MarlinConfigPre.h" +#include "../../../../../inc/MarlinConfigPre.h" #if ENABLED(DGUS_LCD_UI_FYSETC) -#include "DGUSDisplayDefinition.h" -#include "DGUSDisplay.h" +#include "../DGUSDisplayDef.h" +#include "../DGUSDisplay.h" +#include "../DGUSScreenHandler.h" -#include "../../../../module/temperature.h" -#include "../../../../module/motion.h" -#include "../../../../module/planner.h" +#include "../../../../../module/temperature.h" +#include "../../../../../module/motion.h" +#include "../../../../../module/planner.h" -#include "../../ui_api.h" -#include "../../../ultralcd.h" +#include "../../../ui_api.h" +#include "../../../../ultralcd.h" -#if ENABLED(DUGS_UI_MOVE_DIS_OPTION) - uint16_t distanceToMove = 0.1; +#if ENABLED(DGUS_UI_MOVE_DIS_OPTION) + uint16_t distanceToMove = 10; #endif const uint16_t VPList_Boot[] PROGMEM = { @@ -56,7 +57,7 @@ const uint16_t VPList_Main[] PROGMEM = { #if HAS_HEATED_BED VP_T_Bed_Is, VP_T_Bed_Set, VP_BED_STATUS, #endif - #if FAN_COUNT > 0 + #if HAS_FAN VP_Fan0_Percentage, VP_FAN0_STATUS, #endif VP_XPos, VP_YPos, VP_ZPos, @@ -92,7 +93,7 @@ const uint16_t VPList_Status[] PROGMEM = { #if HAS_HEATED_BED VP_T_Bed_Is, VP_T_Bed_Set, #endif - #if FAN_COUNT > 0 + #if HAS_FAN VP_Fan0_Percentage, #endif VP_XPos, VP_YPos, VP_ZPos, @@ -192,7 +193,7 @@ const uint16_t VPList_SD_PrintManipulation[] PROGMEM = { #if HAS_HEATED_BED VP_T_Bed_Is, VP_T_Bed_Set, #endif - #if FAN_COUNT > 0 + #if HAS_FAN VP_Fan0_Percentage, #if FAN_COUNT > 1 VP_Fan1_Percentage, @@ -213,6 +214,7 @@ const uint16_t VPList_SDPrintTune[] PROGMEM = { VP_T_Bed_Is, VP_T_Bed_Set, #endif VP_Feedrate_Percentage, + VP_SD_Print_ProbeOffsetZ, 0x0000 }; @@ -279,6 +281,13 @@ const uint16_t VPList_FLCPrinting[] PROGMEM = { 0x0000 }; +const uint16_t VPList_Z_Offset[] PROGMEM = { + #if HOTENDS >= 1 + VP_SD_Print_ProbeOffsetZ, + #endif + 0x0000 +}; + const struct VPMapping VPMap[] PROGMEM = { { DGUSLCD_SCREEN_BOOT, VPList_Boot }, { DGUSLCD_SCREEN_MAIN, VPList_Main }, @@ -297,6 +306,7 @@ const struct VPMapping VPMap[] PROGMEM = { { DGUSLCD_SCREEN_WAITING, VPList_PIDTuningWaiting }, { DGUSLCD_SCREEN_FLC_PREHEAT, VPList_FLCPreheat }, { DGUSLCD_SCREEN_FLC_PRINTING, VPList_FLCPrinting }, + { DGUSLCD_SCREEN_Z_OFFSET, VPList_Z_Offset }, { DGUSLCD_SCREEN_STEPPERMM, VPList_StepPerMM }, { DGUSLCD_SCREEN_PID_E, VPList_PIDE0 }, { DGUSLCD_SCREEN_PID_BED, VPList_PIDBED }, @@ -316,159 +326,159 @@ const char MarlinVersion[] PROGMEM = SHORT_BUILD_VERSION; const struct DGUS_VP_Variable ListOfVP[] PROGMEM = { // Helper to detect touch events - VPHELPER(VP_SCREENCHANGE, nullptr, DGUSScreenVariableHandler::ScreenChangeHook, nullptr), - VPHELPER(VP_SCREENCHANGE_ASK, nullptr, DGUSScreenVariableHandler::ScreenChangeHookIfIdle, nullptr), - VPHELPER(VP_SCREENCHANGE_WHENSD, nullptr, DGUSScreenVariableHandler::ScreenChangeHookIfSD, nullptr), - VPHELPER(VP_CONFIRMED, nullptr, DGUSScreenVariableHandler::ScreenConfirmedOK, nullptr), - - VPHELPER(VP_TEMP_ALL_OFF, nullptr, &DGUSScreenVariableHandler::HandleAllHeatersOff, nullptr), - #if ENABLED(DUGS_UI_MOVE_DIS_OPTION) - VPHELPER(VP_MOVE_OPTION, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMoveOption, nullptr), - #endif - #if ENABLED(DUGS_UI_MOVE_DIS_OPTION) - VPHELPER(VP_MOVE_X, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr), - VPHELPER(VP_MOVE_Y, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr), - VPHELPER(VP_MOVE_Z, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr), - VPHELPER(VP_HOME_ALL, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr), + VPHELPER(VP_SCREENCHANGE, nullptr, ScreenHandler.ScreenChangeHook, nullptr), + VPHELPER(VP_SCREENCHANGE_ASK, nullptr, ScreenHandler.ScreenChangeHookIfIdle, nullptr), + #if ENABLED(SDSUPPORT) + VPHELPER(VP_SCREENCHANGE_WHENSD, nullptr, ScreenHandler.ScreenChangeHookIfSD, nullptr), + #endif + VPHELPER(VP_CONFIRMED, nullptr, ScreenHandler.ScreenConfirmedOK, nullptr), + + VPHELPER(VP_TEMP_ALL_OFF, nullptr, &ScreenHandler.HandleAllHeatersOff, nullptr), + #if ENABLED(DGUS_UI_MOVE_DIS_OPTION) + VPHELPER(VP_MOVE_OPTION, &distanceToMove, &ScreenHandler.HandleManualMoveOption, nullptr), + #endif + #if ENABLED(DGUS_UI_MOVE_DIS_OPTION) + VPHELPER(VP_MOVE_X, &distanceToMove, &ScreenHandler.HandleManualMove, nullptr), + VPHELPER(VP_MOVE_Y, &distanceToMove, &ScreenHandler.HandleManualMove, nullptr), + VPHELPER(VP_MOVE_Z, &distanceToMove, &ScreenHandler.HandleManualMove, nullptr), + VPHELPER(VP_HOME_ALL, &distanceToMove, &ScreenHandler.HandleManualMove, nullptr), #else - VPHELPER(VP_MOVE_X, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr), - VPHELPER(VP_MOVE_Y, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr), - VPHELPER(VP_MOVE_Z, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr), - VPHELPER(VP_HOME_ALL, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr), + VPHELPER(VP_MOVE_X, nullptr, &ScreenHandler.HandleManualMove, nullptr), + VPHELPER(VP_MOVE_Y, nullptr, &ScreenHandler.HandleManualMove, nullptr), + VPHELPER(VP_MOVE_Z, nullptr, &ScreenHandler.HandleManualMove, nullptr), + VPHELPER(VP_HOME_ALL, nullptr, &ScreenHandler.HandleManualMove, nullptr), #endif - VPHELPER(VP_MOTOR_LOCK_UNLOK, nullptr, &DGUSScreenVariableHandler::HandleMotorLockUnlock, nullptr), + VPHELPER(VP_MOTOR_LOCK_UNLOK, nullptr, &ScreenHandler.HandleMotorLockUnlock, nullptr), #if ENABLED(POWER_LOSS_RECOVERY) - VPHELPER(VP_POWER_LOSS_RECOVERY, nullptr, &DGUSScreenVariableHandler::HandlePowerLossRecovery, nullptr), + VPHELPER(VP_POWER_LOSS_RECOVERY, nullptr, &ScreenHandler.HandlePowerLossRecovery, nullptr), #endif - VPHELPER(VP_SETTINGS, nullptr, &DGUSScreenVariableHandler::HandleSettings, nullptr), + VPHELPER(VP_SETTINGS, nullptr, &ScreenHandler.HandleSettings, nullptr), #if ENABLED(SINGLE_Z_CALIBRATION) - VPHELPER(VP_Z_CALIBRATE, nullptr, &DGUSScreenVariableHandler::HandleZCalibration, nullptr), + VPHELPER(VP_Z_CALIBRATE, nullptr, &ScreenHandler.HandleZCalibration, nullptr), #endif #if ENABLED(FIRST_LAYER_CAL) - VPHELPER(VP_Z_FIRST_LAYER_CAL, nullptr, &DGUSScreenVariableHandler::HandleFirstLayerCal, nullptr), + VPHELPER(VP_Z_FIRST_LAYER_CAL, nullptr, &ScreenHandler.HandleFirstLayerCal, nullptr), #endif - { .VP = VP_MARLIN_VERSION, .memadr = (void*)MarlinVersion, .size = VP_MARLIN_VERSION_LEN, .set_by_display_handler = nullptr, .send_to_display_handler =&DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM }, + { .VP = VP_MARLIN_VERSION, .memadr = (void*)MarlinVersion, .size = VP_MARLIN_VERSION_LEN, .set_by_display_handler = nullptr, .send_to_display_handler =&ScreenHandler.DGUSLCD_SendStringToDisplayPGM }, // M117 LCD String (We don't need the string in memory but "just" push it to the display on demand, hence the nullptr - { .VP = VP_M117, .memadr = nullptr, .size = VP_M117_LEN, .set_by_display_handler = nullptr, .send_to_display_handler =&DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplay }, + { .VP = VP_M117, .memadr = nullptr, .size = VP_M117_LEN, .set_by_display_handler = nullptr, .send_to_display_handler =&ScreenHandler.DGUSLCD_SendStringToDisplay }, // Temperature Data #if HOTENDS >= 1 - VPHELPER(VP_T_E0_Is, &thermalManager.temp_hotend[0].celsius, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<0>), - VPHELPER(VP_T_E0_Set, &thermalManager.temp_hotend[0].target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay), - VPHELPER(VP_Flowrate_E0, &planner.flow_percentage[ExtUI::extruder_t::E0], DGUSScreenVariableHandler::HandleFlowRateChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay), - VPHELPER(VP_EPos, &destination.e, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>), - VPHELPER(VP_MOVE_E0, nullptr, &DGUSScreenVariableHandler::HandleManualExtrude, nullptr), - VPHELPER(VP_E0_CONTROL, &thermalManager.temp_hotend[0].target, &DGUSScreenVariableHandler::HandleHeaterControl, nullptr), - VPHELPER(VP_E0_STATUS, &thermalManager.temp_hotend[0].target, nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay), + VPHELPER(VP_T_E0_Is, &thermalManager.temp_hotend[0].celsius, nullptr, ScreenHandler.DGUSLCD_SendFloatAsLongValueToDisplay<0>), + VPHELPER(VP_T_E0_Set, &thermalManager.temp_hotend[0].target, ScreenHandler.HandleTemperatureChanged, &ScreenHandler.DGUSLCD_SendWordValueToDisplay), + VPHELPER(VP_Flowrate_E0, &planner.flow_percentage[ExtUI::extruder_t::E0], ScreenHandler.HandleFlowRateChanged, &ScreenHandler.DGUSLCD_SendWordValueToDisplay), + VPHELPER(VP_EPos, &destination.e, nullptr, ScreenHandler.DGUSLCD_SendFloatAsLongValueToDisplay<2>), + VPHELPER(VP_MOVE_E0, nullptr, &ScreenHandler.HandleManualExtrude, nullptr), + VPHELPER(VP_E0_CONTROL, &thermalManager.temp_hotend[0].target, &ScreenHandler.HandleHeaterControl, nullptr), + VPHELPER(VP_E0_STATUS, &thermalManager.temp_hotend[0].target, nullptr, &ScreenHandler.DGUSLCD_SendHeaterStatusToDisplay), #if ENABLED(DGUS_PREHEAT_UI) - VPHELPER(VP_E0_BED_PREHEAT, nullptr, &DGUSScreenVariableHandler::HandlePreheat, nullptr), + VPHELPER(VP_E0_BED_PREHEAT, nullptr, &ScreenHandler.HandlePreheat, nullptr), #endif #if ENABLED(PIDTEMP) - VPHELPER(VP_E0_PID_P, &thermalManager.temp_hotend[0].pid.Kp, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID), - VPHELPER(VP_E0_PID_I, &thermalManager.temp_hotend[0].pid.Ki, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID), - VPHELPER(VP_E0_PID_D, &thermalManager.temp_hotend[0].pid.Kd, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID), - VPHELPER(VP_PID_AUTOTUNE_E0, nullptr, &DGUSScreenVariableHandler::HandlePIDAutotune, nullptr), + VPHELPER(VP_E0_PID_P, &thermalManager.temp_hotend[0].pid.Kp, ScreenHandler.HandleTemperaturePIDChanged, ScreenHandler.DGUSLCD_SendTemperaturePID), + VPHELPER(VP_E0_PID_I, &thermalManager.temp_hotend[0].pid.Ki, ScreenHandler.HandleTemperaturePIDChanged, ScreenHandler.DGUSLCD_SendTemperaturePID), + VPHELPER(VP_E0_PID_D, &thermalManager.temp_hotend[0].pid.Kd, ScreenHandler.HandleTemperaturePIDChanged, ScreenHandler.DGUSLCD_SendTemperaturePID), + VPHELPER(VP_PID_AUTOTUNE_E0, nullptr, &ScreenHandler.HandlePIDAutotune, nullptr), #endif #if ENABLED(DGUS_FILAMENT_LOADUNLOAD) - VPHELPER(VP_E0_FILAMENT_LOAD_UNLOAD, nullptr, &DGUSScreenVariableHandler::HandleFilamentOption, &DGUSScreenVariableHandler::HandleFilamentLoadUnload), + VPHELPER(VP_E0_FILAMENT_LOAD_UNLOAD, nullptr, &ScreenHandler.HandleFilamentOption, &ScreenHandler.HandleFilamentLoadUnload), #endif #endif #if HOTENDS >= 2 - VPHELPER(VP_T_E1_Is, &thermalManager.temp_hotend[1].celsius, nullptr, DGUSLCD_SendFloatAsLongValueToDisplay<0>), - VPHELPER(VP_T_E1_Set, &thermalManager.temp_hotend[1].target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay), - VPHELPER(VP_Flowrate_E1, &planner.flow_percentage[ExtUI::extruder_t::E1], DGUSScreenVariableHandler::HandleFlowRateChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay), - VPHELPER(VP_MOVE_E1, nullptr, &DGUSScreenVariableHandler::HandleManualExtrude, nullptr), - VPHELPER(VP_E1_CONTROL, &thermalManager.temp_hotend[1].target, &DGUSScreenVariableHandler::HandleHeaterControl, nullptr), - VPHELPER(VP_E1_STATUS, &thermalManager.temp_hotend[1].target, nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay), + VPHELPER(VP_T_E1_Is, &thermalManager.temp_hotend[1].celsius, nullptr, ScreenHandler.DGUSLCD_SendFloatAsLongValueToDisplay<0>), + VPHELPER(VP_T_E1_Set, &thermalManager.temp_hotend[1].target, ScreenHandler.HandleTemperatureChanged, &ScreenHandler.DGUSLCD_SendWordValueToDisplay), + VPHELPER(VP_Flowrate_E1, &planner.flow_percentage[ExtUI::extruder_t::E1], ScreenHandler.HandleFlowRateChanged, &ScreenHandler.DGUSLCD_SendWordValueToDisplay), + VPHELPER(VP_MOVE_E1, nullptr, &ScreenHandler.HandleManualExtrude, nullptr), + VPHELPER(VP_E1_CONTROL, &thermalManager.temp_hotend[1].target, &ScreenHandler.HandleHeaterControl, nullptr), + VPHELPER(VP_E1_STATUS, &thermalManager.temp_hotend[1].target, nullptr, &ScreenHandler.DGUSLCD_SendHeaterStatusToDisplay), #if ENABLED(PIDTEMP) - VPHELPER(VP_PID_AUTOTUNE_E1, nullptr, &DGUSScreenVariableHandler::HandlePIDAutotune, nullptr), + VPHELPER(VP_PID_AUTOTUNE_E1, nullptr, &ScreenHandler.HandlePIDAutotune, nullptr), #endif - VPHELPER(VP_E1_FILAMENT_LOAD_UNLOAD, nullptr, &DGUSScreenVariableHandler::HandleFilamentOption, &DGUSScreenVariableHandler::HandleFilamentLoadUnload), + VPHELPER(VP_E1_FILAMENT_LOAD_UNLOAD, nullptr, &ScreenHandler.HandleFilamentOption, &ScreenHandler.HandleFilamentLoadUnload), #endif #if HAS_HEATED_BED - VPHELPER(VP_T_Bed_Is, &thermalManager.temp_bed.celsius, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<0>), - VPHELPER(VP_T_Bed_Set, &thermalManager.temp_bed.target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay), - VPHELPER(VP_BED_CONTROL, &thermalManager.temp_bed.target, &DGUSScreenVariableHandler::HandleHeaterControl, nullptr), - VPHELPER(VP_BED_STATUS, &thermalManager.temp_bed.target, nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay), + VPHELPER(VP_T_Bed_Is, &thermalManager.temp_bed.celsius, nullptr, ScreenHandler.DGUSLCD_SendFloatAsLongValueToDisplay<0>), + VPHELPER(VP_T_Bed_Set, &thermalManager.temp_bed.target, ScreenHandler.HandleTemperatureChanged, &ScreenHandler.DGUSLCD_SendWordValueToDisplay), + VPHELPER(VP_BED_CONTROL, &thermalManager.temp_bed.target, &ScreenHandler.HandleHeaterControl, nullptr), + VPHELPER(VP_BED_STATUS, &thermalManager.temp_bed.target, nullptr, &ScreenHandler.DGUSLCD_SendHeaterStatusToDisplay), #if ENABLED(PIDTEMPBED) - VPHELPER(VP_BED_PID_P, &thermalManager.temp_bed.pid.Kp, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID), - VPHELPER(VP_BED_PID_I, &thermalManager.temp_bed.pid.Ki, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID), - VPHELPER(VP_BED_PID_D, &thermalManager.temp_bed.pid.Kd, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID), - VPHELPER(VP_PID_AUTOTUNE_BED, nullptr, &DGUSScreenVariableHandler::HandlePIDAutotune, nullptr), + VPHELPER(VP_BED_PID_P, &thermalManager.temp_bed.pid.Kp, ScreenHandler.HandleTemperaturePIDChanged, ScreenHandler.DGUSLCD_SendTemperaturePID), + VPHELPER(VP_BED_PID_I, &thermalManager.temp_bed.pid.Ki, ScreenHandler.HandleTemperaturePIDChanged, ScreenHandler.DGUSLCD_SendTemperaturePID), + VPHELPER(VP_BED_PID_D, &thermalManager.temp_bed.pid.Kd, ScreenHandler.HandleTemperaturePIDChanged, ScreenHandler.DGUSLCD_SendTemperaturePID), + VPHELPER(VP_PID_AUTOTUNE_BED, nullptr, &ScreenHandler.HandlePIDAutotune, nullptr), #endif #endif // Fan Data - #if FAN_COUNT + #if HAS_FAN #define FAN_VPHELPER(N) \ - VPHELPER(VP_Fan##N##_Percentage, &thermalManager.fan_speed[N], DGUSScreenVariableHandler::DGUSLCD_PercentageToUint8, &DGUSScreenVariableHandler::DGUSLCD_SendPercentageToDisplay), \ - VPHELPER(VP_FAN##N##_CONTROL, &thermalManager.fan_speed[N], &DGUSScreenVariableHandler::HandleFanControl, nullptr), \ - VPHELPER(VP_FAN##N##_STATUS, &thermalManager.fan_speed[N], nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendFanStatusToDisplay), + VPHELPER(VP_Fan##N##_Percentage, &thermalManager.fan_speed[N], ScreenHandler.DGUSLCD_PercentageToUint8, &ScreenHandler.DGUSLCD_SendPercentageToDisplay), \ + VPHELPER(VP_FAN##N##_CONTROL, &thermalManager.fan_speed[N], &ScreenHandler.HandleFanControl, nullptr), \ + VPHELPER(VP_FAN##N##_STATUS, &thermalManager.fan_speed[N], nullptr, &ScreenHandler.DGUSLCD_SendFanStatusToDisplay), REPEAT(FAN_COUNT, FAN_VPHELPER) #endif // Feedrate - VPHELPER(VP_Feedrate_Percentage, &feedrate_percentage, DGUSScreenVariableHandler::DGUSLCD_SetValueDirectly, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay ), + VPHELPER(VP_Feedrate_Percentage, &feedrate_percentage, ScreenHandler.DGUSLCD_SetValueDirectly, &ScreenHandler.DGUSLCD_SendWordValueToDisplay ), // Position Data - VPHELPER(VP_XPos, ¤t_position.x, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>), - VPHELPER(VP_YPos, ¤t_position.y, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>), - VPHELPER(VP_ZPos, ¤t_position.z, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>), + VPHELPER(VP_XPos, ¤t_position.x, nullptr, ScreenHandler.DGUSLCD_SendFloatAsLongValueToDisplay<2>), + VPHELPER(VP_YPos, ¤t_position.y, nullptr, ScreenHandler.DGUSLCD_SendFloatAsLongValueToDisplay<2>), + VPHELPER(VP_ZPos, ¤t_position.z, nullptr, ScreenHandler.DGUSLCD_SendFloatAsLongValueToDisplay<2>), // Print Progress - #if ENABLED(LCD_SET_PROGRESS_MANUALLY) - VPHELPER(VP_PrintProgress_Percentage, &ui.progress_override, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay), - #endif + VPHELPER(VP_PrintProgress_Percentage, nullptr, nullptr, ScreenHandler.DGUSLCD_SendPrintProgressToDisplay ), // Print Time - VPHELPER_STR(VP_PrintTime, nullptr, VP_PrintTime_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendPrintTimeToDisplay), + VPHELPER_STR(VP_PrintTime, nullptr, VP_PrintTime_LEN, nullptr, ScreenHandler.DGUSLCD_SendPrintTimeToDisplay), #if ENABLED(PRINTCOUNTER) - VPHELPER_STR(VP_PrintAccTime, nullptr, VP_PrintAccTime_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendPrintAccTimeToDisplay), - VPHELPER_STR(VP_PrintsTotal, nullptr, VP_PrintsTotal_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendPrintsTotalToDisplay), + VPHELPER_STR(VP_PrintAccTime, nullptr, VP_PrintAccTime_LEN, nullptr, ScreenHandler.DGUSLCD_SendPrintAccTimeToDisplay), + VPHELPER_STR(VP_PrintsTotal, nullptr, VP_PrintsTotal_LEN, nullptr, ScreenHandler.DGUSLCD_SendPrintsTotalToDisplay), #endif - VPHELPER(VP_X_STEP_PER_MM, &planner.settings.axis_steps_per_mm[X_AXIS], DGUSScreenVariableHandler::HandleStepPerMMChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>), - VPHELPER(VP_Y_STEP_PER_MM, &planner.settings.axis_steps_per_mm[Y_AXIS], DGUSScreenVariableHandler::HandleStepPerMMChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>), - VPHELPER(VP_Z_STEP_PER_MM, &planner.settings.axis_steps_per_mm[Z_AXIS], DGUSScreenVariableHandler::HandleStepPerMMChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>), + VPHELPER(VP_X_STEP_PER_MM, &planner.settings.axis_steps_per_mm[X_AXIS], ScreenHandler.HandleStepPerMMChanged, ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<1>), + VPHELPER(VP_Y_STEP_PER_MM, &planner.settings.axis_steps_per_mm[Y_AXIS], ScreenHandler.HandleStepPerMMChanged, ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<1>), + VPHELPER(VP_Z_STEP_PER_MM, &planner.settings.axis_steps_per_mm[Z_AXIS], ScreenHandler.HandleStepPerMMChanged, ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<1>), #if HOTENDS >= 1 - VPHELPER(VP_E0_STEP_PER_MM, &planner.settings.axis_steps_per_mm[E_AXIS_N(0)], DGUSScreenVariableHandler::HandleStepPerMMExtruderChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>), + VPHELPER(VP_E0_STEP_PER_MM, &planner.settings.axis_steps_per_mm[E_AXIS_N(0)], ScreenHandler.HandleStepPerMMExtruderChanged, ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<1>), #endif #if HOTENDS >= 2 - VPHELPER(VP_E1_STEP_PER_MM, &planner.settings.axis_steps_per_mm[E_AXIS_N(1)], DGUSScreenVariableHandler::HandleStepPerMMExtruderChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>), + VPHELPER(VP_E1_STEP_PER_MM, &planner.settings.axis_steps_per_mm[E_AXIS_N(1)], ScreenHandler.HandleStepPerMMExtruderChanged, ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<1>), #endif // SDCard File listing. #if ENABLED(SDSUPPORT) - VPHELPER(VP_SD_ScrollEvent, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_ScrollFilelist, nullptr), - VPHELPER(VP_SD_FileSelected, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_FileSelected, nullptr), - VPHELPER(VP_SD_FileSelectConfirm, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_StartPrint, nullptr), - VPHELPER_STR(VP_SD_FileName0, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename), - VPHELPER_STR(VP_SD_FileName1, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename), - VPHELPER_STR(VP_SD_FileName2, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename), - VPHELPER_STR(VP_SD_FileName3, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename), - VPHELPER_STR(VP_SD_FileName4, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename), - VPHELPER(VP_SD_ResumePauseAbort, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_ResumePauseAbort, nullptr), - VPHELPER(VP_SD_AbortPrintConfirmed, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_ReallyAbort, nullptr), - VPHELPER(VP_SD_Print_Setting, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_PrintTune, nullptr), + VPHELPER(VP_SD_ScrollEvent, nullptr, ScreenHandler.DGUSLCD_SD_ScrollFilelist, nullptr), + VPHELPER(VP_SD_FileSelected, nullptr, ScreenHandler.DGUSLCD_SD_FileSelected, nullptr), + VPHELPER(VP_SD_FileSelectConfirm, nullptr, ScreenHandler.DGUSLCD_SD_StartPrint, nullptr), + VPHELPER_STR(VP_SD_FileName0, nullptr, VP_SD_FileName_LEN, nullptr, ScreenHandler.DGUSLCD_SD_SendFilename), + VPHELPER_STR(VP_SD_FileName1, nullptr, VP_SD_FileName_LEN, nullptr, ScreenHandler.DGUSLCD_SD_SendFilename), + VPHELPER_STR(VP_SD_FileName2, nullptr, VP_SD_FileName_LEN, nullptr, ScreenHandler.DGUSLCD_SD_SendFilename), + VPHELPER_STR(VP_SD_FileName3, nullptr, VP_SD_FileName_LEN, nullptr, ScreenHandler.DGUSLCD_SD_SendFilename), + VPHELPER_STR(VP_SD_FileName4, nullptr, VP_SD_FileName_LEN, nullptr, ScreenHandler.DGUSLCD_SD_SendFilename), + VPHELPER(VP_SD_ResumePauseAbort, nullptr, ScreenHandler.DGUSLCD_SD_ResumePauseAbort, nullptr), + VPHELPER(VP_SD_AbortPrintConfirmed, nullptr, ScreenHandler.DGUSLCD_SD_ReallyAbort, nullptr), + VPHELPER(VP_SD_Print_Setting, nullptr, ScreenHandler.DGUSLCD_SD_PrintTune, nullptr), #if HAS_BED_PROBE - VPHELPER(VP_SD_Print_ProbeOffsetZ, &probe.offset.z, DGUSScreenVariableHandler::HandleProbeOffsetZChanged, &DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<2>), + VPHELPER(VP_SD_Print_ProbeOffsetZ, &probe.offset.z, ScreenHandler.HandleProbeOffsetZChanged, &ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<2>), #if ENABLED(BABYSTEPPING) - VPHELPER(VP_SD_Print_LiveAdjustZ, nullptr, DGUSScreenVariableHandler::HandleLiveAdjustZ, nullptr), + VPHELPER(VP_SD_Print_LiveAdjustZ, nullptr, ScreenHandler.HandleLiveAdjustZ, nullptr), #endif #endif #endif #if ENABLED(DGUS_UI_WAITING) - VPHELPER(VP_WAITING_STATUS, nullptr, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendWaitingStatusToDisplay), + VPHELPER(VP_WAITING_STATUS, nullptr, nullptr, ScreenHandler.DGUSLCD_SendWaitingStatusToDisplay), #endif // Messages for the User, shared by the popup and the kill screen. They cant be autouploaded as we do not buffer content. - { .VP = VP_MSGSTR1, .memadr = nullptr, .size = VP_MSGSTR1_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM }, - { .VP = VP_MSGSTR2, .memadr = nullptr, .size = VP_MSGSTR2_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM }, - { .VP = VP_MSGSTR3, .memadr = nullptr, .size = VP_MSGSTR3_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM }, - { .VP = VP_MSGSTR4, .memadr = nullptr, .size = VP_MSGSTR4_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM }, + { .VP = VP_MSGSTR1, .memadr = nullptr, .size = VP_MSGSTR1_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &ScreenHandler.DGUSLCD_SendStringToDisplayPGM }, + { .VP = VP_MSGSTR2, .memadr = nullptr, .size = VP_MSGSTR2_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &ScreenHandler.DGUSLCD_SendStringToDisplayPGM }, + { .VP = VP_MSGSTR3, .memadr = nullptr, .size = VP_MSGSTR3_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &ScreenHandler.DGUSLCD_SendStringToDisplayPGM }, + { .VP = VP_MSGSTR4, .memadr = nullptr, .size = VP_MSGSTR4_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &ScreenHandler.DGUSLCD_SendStringToDisplayPGM }, VPHELPER(0, 0, 0, 0) // must be last entry. }; diff --git a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinitionFYSETC.h b/Marlin/src/lcd/extui/lib/dgus/fysetc/DGUSDisplayDef.h similarity index 95% rename from Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinitionFYSETC.h rename to Marlin/src/lcd/extui/lib/dgus/fysetc/DGUSDisplayDef.h index 6eb2369fa1a4..f6a65fe8a061 100644 --- a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinitionFYSETC.h +++ b/Marlin/src/lcd/extui/lib/dgus/fysetc/DGUSDisplayDef.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -43,7 +43,8 @@ enum DGUSLCD_Screens : uint8_t { DGUSLCD_SCREEN_STEPPERMM = 212, DGUSLCD_SCREEN_PID_E = 214, DGUSLCD_SCREEN_PID_BED = 218, - DGUSLCD_SCREEN_INFOS = 30, + DGUSLCD_SCREEN_Z_OFFSET = 222, + DGUSLCD_SCREEN_INFOS = 36, DGUSLCD_SCREEN_CONFIRM = 240, DGUSLCD_SCREEN_KILL = 250, ///< Kill Screen. Must always be 250 (to be able to display "Error wrong LCD Version") DGUSLCD_SCREEN_WAITING = 251, @@ -121,8 +122,8 @@ constexpr uint16_t VP_POWER_LOSS_RECOVERY = 0x2180; // Fan Control Buttons , switch between "off" and "on" constexpr uint16_t VP_FAN0_CONTROL = 0x2200; constexpr uint16_t VP_FAN1_CONTROL = 0x2202; -//constexpr uint16_t VP_FAN2_CONTROL = 0x2204; -//constexpr uint16_t VP_FAN3_CONTROL = 0x2206; +constexpr uint16_t VP_FAN2_CONTROL = 0x2204; +constexpr uint16_t VP_FAN3_CONTROL = 0x2206; // Heater Control Buttons , triged between "cool down" and "heat PLA" state constexpr uint16_t VP_E0_CONTROL = 0x2210; @@ -150,7 +151,7 @@ constexpr uint16_t VP_SETTINGS = 0x2400; // PID autotune constexpr uint16_t VP_PID_AUTOTUNE_E0 = 0x2410; -//constexpr uint16_t VP_PID_AUTOTUNE_E1 = 0x2412; +constexpr uint16_t VP_PID_AUTOTUNE_E1 = 0x2412; //constexpr uint16_t VP_PID_AUTOTUNE_E2 = 0x2414; //constexpr uint16_t VP_PID_AUTOTUNE_E3 = 0x2416; //constexpr uint16_t VP_PID_AUTOTUNE_E4 = 0x2418; @@ -240,12 +241,12 @@ constexpr uint16_t VP_SD_Print_Filename = 0x32C0; // Fan status constexpr uint16_t VP_FAN0_STATUS = 0x3300; constexpr uint16_t VP_FAN1_STATUS = 0x3302; -//constexpr uint16_t VP_FAN2_STATUS = 0x3304; -//constexpr uint16_t VP_FAN3_STATUS = 0x3306; +constexpr uint16_t VP_FAN2_STATUS = 0x3304; +constexpr uint16_t VP_FAN3_STATUS = 0x3306; // Heater status constexpr uint16_t VP_E0_STATUS = 0x3310; -//constexpr uint16_t VP_E1_STATUS = 0x3312; +constexpr uint16_t VP_E1_STATUS = 0x3312; //constexpr uint16_t VP_E2_STATUS = 0x3314; //constexpr uint16_t VP_E3_STATUS = 0x3316; //constexpr uint16_t VP_E4_STATUS = 0x3318; @@ -272,6 +273,9 @@ constexpr uint16_t VP_E1_STEP_PER_MM = 0x3612; constexpr uint16_t VP_E0_PID_P = 0x3700; // at the moment , 2 byte unsigned int , 0~1638.4 constexpr uint16_t VP_E0_PID_I = 0x3702; constexpr uint16_t VP_E0_PID_D = 0x3704; +constexpr uint16_t VP_E1_PID_P = 0x3706; // at the moment , 2 byte unsigned int , 0~1638.4 +constexpr uint16_t VP_E1_PID_I = 0x3708; +constexpr uint16_t VP_E1_PID_D = 0x370A; constexpr uint16_t VP_BED_PID_P = 0x3710; constexpr uint16_t VP_BED_PID_I = 0x3712; constexpr uint16_t VP_BED_PID_D = 0x3714; diff --git a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinitionHIPRECY.cpp b/Marlin/src/lcd/extui/lib/dgus/hiprecy/DGUSDisplayDef.cpp similarity index 55% rename from Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinitionHIPRECY.cpp rename to Marlin/src/lcd/extui/lib/dgus/hiprecy/DGUSDisplayDef.cpp index 6ec6cddae469..82c06d7a4afb 100644 --- a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinitionHIPRECY.cpp +++ b/Marlin/src/lcd/extui/lib/dgus/hiprecy/DGUSDisplayDef.cpp @@ -16,28 +16,29 @@ * 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 . + * along with this program. If not, see . * */ /* DGUS VPs changed by George Fu in 2019 for Marlin */ -#include "../../../../inc/MarlinConfigPre.h" +#include "../../../../../inc/MarlinConfigPre.h" #if ENABLED(DGUS_LCD_UI_HIPRECY) -#include "DGUSDisplayDefinition.h" -#include "DGUSDisplay.h" +#include "../DGUSDisplayDef.h" +#include "../DGUSDisplay.h" +#include "../DGUSScreenHandler.h" -#include "../../../../module/temperature.h" -#include "../../../../module/motion.h" -#include "../../../../module/planner.h" +#include "../../../../../module/temperature.h" +#include "../../../../../module/motion.h" +#include "../../../../../module/planner.h" -#include "../../ui_api.h" -#include "../../../ultralcd.h" +#include "../../../ui_api.h" +#include "../../../../ultralcd.h" -#if ENABLED(DUGS_UI_MOVE_DIS_OPTION) - uint16_t distanceToMove = 0.1; +#if ENABLED(DGUS_UI_MOVE_DIS_OPTION) + uint16_t distanceToMove = 10; #endif const uint16_t VPList_Boot[] PROGMEM = { @@ -56,7 +57,7 @@ const uint16_t VPList_Main[] PROGMEM = { #if HAS_HEATED_BED VP_T_Bed_Is, VP_T_Bed_Set, VP_BED_STATUS, #endif - #if FAN_COUNT > 0 + #if HAS_FAN VP_Fan0_Percentage, VP_FAN0_STATUS, #endif VP_XPos, VP_YPos, VP_ZPos, @@ -92,7 +93,7 @@ const uint16_t VPList_Status[] PROGMEM = { #if HAS_HEATED_BED VP_T_Bed_Is, VP_T_Bed_Set, #endif - #if FAN_COUNT > 0 + #if HAS_FAN VP_Fan0_Percentage, #endif VP_XPos, VP_YPos, VP_ZPos, @@ -191,7 +192,7 @@ const uint16_t VPList_SD_PrintManipulation[] PROGMEM = { #if HAS_HEATED_BED VP_T_Bed_Is, VP_T_Bed_Set, #endif - #if FAN_COUNT > 0 + #if HAS_FAN VP_Fan0_Percentage, #if FAN_COUNT > 1 VP_Fan1_Percentage, @@ -212,7 +213,7 @@ const uint16_t VPList_SDPrintTune[] PROGMEM = { VP_T_Bed_Is, VP_T_Bed_Set, #endif VP_Feedrate_Percentage, - #if FAN_COUNT > 0 + #if HAS_FAN VP_Fan0_Percentage, #endif VP_Flowrate_E0, @@ -283,6 +284,13 @@ const uint16_t VPList_FLCPrinting[] PROGMEM = { 0x0000 }; +const uint16_t VPList_Z_Offset[] PROGMEM = { + #if HOTENDS >= 1 + VP_SD_Print_ProbeOffsetZ, + #endif + 0x0000 +}; + const struct VPMapping VPMap[] PROGMEM = { { DGUSLCD_SCREEN_BOOT, VPList_Boot }, { DGUSLCD_SCREEN_MAIN, VPList_Main }, @@ -291,6 +299,7 @@ const struct VPMapping VPMap[] PROGMEM = { { DGUSLCD_SCREEN_STATUS2, VPList_Status2 }, { DGUSLCD_SCREEN_PREHEAT, VPList_Preheat }, { DGUSLCD_SCREEN_MANUALMOVE, VPList_ManualMove }, + { DGUSLCD_SCREEN_Z_OFFSET, VPList_Z_Offset }, { DGUSLCD_SCREEN_MANUALEXTRUDE, VPList_ManualExtrude }, { DGUSLCD_SCREEN_FILAMENT_HEATING, VPList_Filament_heating }, { DGUSLCD_SCREEN_FILAMENT_LOADING, VPList_Filament_load_unload }, @@ -320,155 +329,155 @@ const char MarlinVersion[] PROGMEM = SHORT_BUILD_VERSION; const struct DGUS_VP_Variable ListOfVP[] PROGMEM = { // Helper to detect touch events - VPHELPER(VP_SCREENCHANGE, nullptr, DGUSScreenVariableHandler::ScreenChangeHook, nullptr), - VPHELPER(VP_SCREENCHANGE_ASK, nullptr, DGUSScreenVariableHandler::ScreenChangeHookIfIdle, nullptr), - VPHELPER(VP_SCREENCHANGE_WHENSD, nullptr, DGUSScreenVariableHandler::ScreenChangeHookIfSD, nullptr), - VPHELPER(VP_CONFIRMED, nullptr, DGUSScreenVariableHandler::ScreenConfirmedOK, nullptr), + VPHELPER(VP_SCREENCHANGE, nullptr, ScreenHandler.ScreenChangeHook, nullptr), + VPHELPER(VP_SCREENCHANGE_ASK, nullptr, ScreenHandler.ScreenChangeHookIfIdle, nullptr), + #if ENABLED(SDSUPPORT) + VPHELPER(VP_SCREENCHANGE_WHENSD, nullptr, ScreenHandler.ScreenChangeHookIfSD, nullptr), + #endif + VPHELPER(VP_CONFIRMED, nullptr, ScreenHandler.ScreenConfirmedOK, nullptr), - VPHELPER(VP_TEMP_ALL_OFF, nullptr, &DGUSScreenVariableHandler::HandleAllHeatersOff, nullptr), + VPHELPER(VP_TEMP_ALL_OFF, nullptr, &ScreenHandler.HandleAllHeatersOff, nullptr), - #if ENABLED(DUGS_UI_MOVE_DIS_OPTION) - VPHELPER(VP_MOVE_OPTION, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMoveOption, nullptr), + #if ENABLED(DGUS_UI_MOVE_DIS_OPTION) + VPHELPER(VP_MOVE_OPTION, &distanceToMove, &ScreenHandler.HandleManualMoveOption, nullptr), #endif - #if ENABLED(DUGS_UI_MOVE_DIS_OPTION) - VPHELPER(VP_MOVE_X, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr), - VPHELPER(VP_MOVE_Y, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr), - VPHELPER(VP_MOVE_Z, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr), - VPHELPER(VP_HOME_ALL, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr), + #if ENABLED(DGUS_UI_MOVE_DIS_OPTION) + VPHELPER(VP_MOVE_X, &distanceToMove, &ScreenHandler.HandleManualMove, nullptr), + VPHELPER(VP_MOVE_Y, &distanceToMove, &ScreenHandler.HandleManualMove, nullptr), + VPHELPER(VP_MOVE_Z, &distanceToMove, &ScreenHandler.HandleManualMove, nullptr), + VPHELPER(VP_HOME_ALL, &distanceToMove, &ScreenHandler.HandleManualMove, nullptr), #else - VPHELPER(VP_MOVE_X, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr), - VPHELPER(VP_MOVE_Y, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr), - VPHELPER(VP_MOVE_Z, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr), - VPHELPER(VP_HOME_ALL, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr), + VPHELPER(VP_MOVE_X, nullptr, &ScreenHandler.HandleManualMove, nullptr), + VPHELPER(VP_MOVE_Y, nullptr, &ScreenHandler.HandleManualMove, nullptr), + VPHELPER(VP_MOVE_Z, nullptr, &ScreenHandler.HandleManualMove, nullptr), + VPHELPER(VP_HOME_ALL, nullptr, &ScreenHandler.HandleManualMove, nullptr), #endif - VPHELPER(VP_MOTOR_LOCK_UNLOK, nullptr, &DGUSScreenVariableHandler::HandleMotorLockUnlock, nullptr), + VPHELPER(VP_MOTOR_LOCK_UNLOK, nullptr, &ScreenHandler.HandleMotorLockUnlock, nullptr), #if ENABLED(POWER_LOSS_RECOVERY) - VPHELPER(VP_POWER_LOSS_RECOVERY, nullptr, &DGUSScreenVariableHandler::HandlePowerLossRecovery, nullptr), + VPHELPER(VP_POWER_LOSS_RECOVERY, nullptr, &ScreenHandler.HandlePowerLossRecovery, nullptr), #endif - VPHELPER(VP_SETTINGS, nullptr, &DGUSScreenVariableHandler::HandleSettings, nullptr), + VPHELPER(VP_SETTINGS, nullptr, &ScreenHandler.HandleSettings, nullptr), #if ENABLED(SINGLE_Z_CALIBRATION) - VPHELPER(VP_Z_CALIBRATE, nullptr, &DGUSScreenVariableHandler::HandleZCalibration, nullptr), + VPHELPER(VP_Z_CALIBRATE, nullptr, &ScreenHandler.HandleZCalibration, nullptr), #endif #if ENABLED(FIRST_LAYER_CAL) - VPHELPER(VP_Z_FIRST_LAYER_CAL, nullptr, &DGUSScreenVariableHandler::HandleFirstLayerCal, nullptr), + VPHELPER(VP_Z_FIRST_LAYER_CAL, nullptr, &ScreenHandler.HandleFirstLayerCal, nullptr), #endif - { .VP = VP_MARLIN_VERSION, .memadr = (void*)MarlinVersion, .size = VP_MARLIN_VERSION_LEN, .set_by_display_handler = nullptr, .send_to_display_handler =&DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM }, + { .VP = VP_MARLIN_VERSION, .memadr = (void*)MarlinVersion, .size = VP_MARLIN_VERSION_LEN, .set_by_display_handler = nullptr, .send_to_display_handler =&ScreenHandler.DGUSLCD_SendStringToDisplayPGM }, // M117 LCD String (We don't need the string in memory but "just" push it to the display on demand, hence the nullptr - { .VP = VP_M117, .memadr = nullptr, .size = VP_M117_LEN, .set_by_display_handler = nullptr, .send_to_display_handler =&DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplay }, + { .VP = VP_M117, .memadr = nullptr, .size = VP_M117_LEN, .set_by_display_handler = nullptr, .send_to_display_handler =&ScreenHandler.DGUSLCD_SendStringToDisplay }, // Temperature Data #if HOTENDS >= 1 - VPHELPER(VP_T_E0_Is, &thermalManager.temp_hotend[0].celsius, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<0>), - VPHELPER(VP_T_E0_Set, &thermalManager.temp_hotend[0].target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay), - VPHELPER(VP_Flowrate_E0, nullptr, DGUSScreenVariableHandler::HandleFlowRateChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay), - VPHELPER(VP_EPos, &destination.e, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>), - VPHELPER(VP_MOVE_E0, nullptr, &DGUSScreenVariableHandler::HandleManualExtrude, nullptr), - VPHELPER(VP_E0_CONTROL, &thermalManager.temp_hotend[0].target, &DGUSScreenVariableHandler::HandleHeaterControl, nullptr), - VPHELPER(VP_E0_STATUS, &thermalManager.temp_hotend[0].target, nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay), + VPHELPER(VP_T_E0_Is, &thermalManager.temp_hotend[0].celsius, nullptr, ScreenHandler.DGUSLCD_SendFloatAsLongValueToDisplay<0>), + VPHELPER(VP_T_E0_Set, &thermalManager.temp_hotend[0].target, ScreenHandler.HandleTemperatureChanged, &ScreenHandler.DGUSLCD_SendWordValueToDisplay), + VPHELPER(VP_Flowrate_E0, &planner.flow_percentage[ExtUI::extruder_t::E0], ScreenHandler.HandleFlowRateChanged, &ScreenHandler.DGUSLCD_SendWordValueToDisplay), + VPHELPER(VP_EPos, &destination.e, nullptr, ScreenHandler.DGUSLCD_SendFloatAsLongValueToDisplay<2>), + VPHELPER(VP_MOVE_E0, nullptr, &ScreenHandler.HandleManualExtrude, nullptr), + VPHELPER(VP_E0_CONTROL, &thermalManager.temp_hotend[0].target, &ScreenHandler.HandleHeaterControl, nullptr), + VPHELPER(VP_E0_STATUS, &thermalManager.temp_hotend[0].target, nullptr, &ScreenHandler.DGUSLCD_SendHeaterStatusToDisplay), #if ENABLED(DGUS_PREHEAT_UI) - VPHELPER(VP_E0_BED_PREHEAT, nullptr, &DGUSScreenVariableHandler::HandlePreheat, nullptr), + VPHELPER(VP_E0_BED_PREHEAT, nullptr, &ScreenHandler.HandlePreheat, nullptr), #endif #if ENABLED(DGUS_FILAMENT_LOADUNLOAD) - VPHELPER(VP_E0_FILAMENT_LOAD_UNLOAD, nullptr, &DGUSScreenVariableHandler::HandleFilamentOption, &DGUSScreenVariableHandler::HandleFilamentLoadUnload), + VPHELPER(VP_E0_FILAMENT_LOAD_UNLOAD, nullptr, &ScreenHandler.HandleFilamentOption, &ScreenHandler.HandleFilamentLoadUnload), #endif #if ENABLED(PIDTEMP) - VPHELPER(VP_E0_PID_P, &thermalManager.temp_hotend[0].pid.Kp, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID), - VPHELPER(VP_E0_PID_I, &thermalManager.temp_hotend[0].pid.Ki, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID), - VPHELPER(VP_E0_PID_D, &thermalManager.temp_hotend[0].pid.Kd, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID), - VPHELPER(VP_PID_AUTOTUNE_E0, nullptr, &DGUSScreenVariableHandler::HandlePIDAutotune, nullptr), + VPHELPER(VP_E0_PID_P, &thermalManager.temp_hotend[0].pid.Kp, ScreenHandler.HandleTemperaturePIDChanged, ScreenHandler.DGUSLCD_SendTemperaturePID), + VPHELPER(VP_E0_PID_I, &thermalManager.temp_hotend[0].pid.Ki, ScreenHandler.HandleTemperaturePIDChanged, ScreenHandler.DGUSLCD_SendTemperaturePID), + VPHELPER(VP_E0_PID_D, &thermalManager.temp_hotend[0].pid.Kd, ScreenHandler.HandleTemperaturePIDChanged, ScreenHandler.DGUSLCD_SendTemperaturePID), + VPHELPER(VP_PID_AUTOTUNE_E0, nullptr, &ScreenHandler.HandlePIDAutotune, nullptr), #endif #endif #if HOTENDS >= 2 VPHELPER(VP_T_E1_Is, &thermalManager.temp_hotend[1].celsius, nullptr, DGUSLCD_SendFloatAsLongValueToDisplay<0>), - VPHELPER(VP_T_E1_Set, &thermalManager.temp_hotend[1].target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay), - VPHELPER(VP_Flowrate_E1, nullptr, DGUSScreenVariableHandler::HandleFlowRateChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay), - VPHELPER(VP_MOVE_E1, nullptr, &DGUSScreenVariableHandler::HandleManualExtrude, nullptr), - VPHELPER(VP_E1_CONTROL, &thermalManager.temp_hotend[1].target, &DGUSScreenVariableHandler::HandleHeaterControl, nullptr), - VPHELPER(VP_E1_STATUS, &thermalManager.temp_hotend[1].target, nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay), + VPHELPER(VP_T_E1_Set, &thermalManager.temp_hotend[1].target, ScreenHandler.HandleTemperatureChanged, &ScreenHandler.DGUSLCD_SendWordValueToDisplay), + VPHELPER(VP_Flowrate_E1, nullptr, ScreenHandler.HandleFlowRateChanged, &ScreenHandler.DGUSLCD_SendWordValueToDisplay), + VPHELPER(VP_MOVE_E1, nullptr, &ScreenHandler.HandleManualExtrude, nullptr), + VPHELPER(VP_E1_CONTROL, &thermalManager.temp_hotend[1].target, &ScreenHandler.HandleHeaterControl, nullptr), + VPHELPER(VP_E1_STATUS, &thermalManager.temp_hotend[1].target, nullptr, &ScreenHandler.DGUSLCD_SendHeaterStatusToDisplay), #endif #if HAS_HEATED_BED - VPHELPER(VP_T_Bed_Is, &thermalManager.temp_bed.celsius, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<0>), - VPHELPER(VP_T_Bed_Set, &thermalManager.temp_bed.target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay), - VPHELPER(VP_BED_CONTROL, &thermalManager.temp_bed.target, &DGUSScreenVariableHandler::HandleHeaterControl, nullptr), - VPHELPER(VP_BED_STATUS, &thermalManager.temp_bed.target, nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay), + VPHELPER(VP_T_Bed_Is, &thermalManager.temp_bed.celsius, nullptr, ScreenHandler.DGUSLCD_SendFloatAsLongValueToDisplay<0>), + VPHELPER(VP_T_Bed_Set, &thermalManager.temp_bed.target, ScreenHandler.HandleTemperatureChanged, &ScreenHandler.DGUSLCD_SendWordValueToDisplay), + VPHELPER(VP_BED_CONTROL, &thermalManager.temp_bed.target, &ScreenHandler.HandleHeaterControl, nullptr), + VPHELPER(VP_BED_STATUS, &thermalManager.temp_bed.target, nullptr, &ScreenHandler.DGUSLCD_SendHeaterStatusToDisplay), #if ENABLED(PIDTEMP) - VPHELPER(VP_BED_PID_P, &thermalManager.temp_bed.pid.Kp, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID), - VPHELPER(VP_BED_PID_I, &thermalManager.temp_bed.pid.Ki, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID), - VPHELPER(VP_BED_PID_D, &thermalManager.temp_bed.pid.Kd, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID), - VPHELPER(VP_PID_AUTOTUNE_BED, nullptr, &DGUSScreenVariableHandler::HandlePIDAutotune, nullptr), + VPHELPER(VP_BED_PID_P, &thermalManager.temp_bed.pid.Kp, ScreenHandler.HandleTemperaturePIDChanged, ScreenHandler.DGUSLCD_SendTemperaturePID), + VPHELPER(VP_BED_PID_I, &thermalManager.temp_bed.pid.Ki, ScreenHandler.HandleTemperaturePIDChanged, ScreenHandler.DGUSLCD_SendTemperaturePID), + VPHELPER(VP_BED_PID_D, &thermalManager.temp_bed.pid.Kd, ScreenHandler.HandleTemperaturePIDChanged, ScreenHandler.DGUSLCD_SendTemperaturePID), + VPHELPER(VP_PID_AUTOTUNE_BED, nullptr, &ScreenHandler.HandlePIDAutotune, nullptr), #endif #endif // Fan Data - #if FAN_COUNT + #if HAS_FAN #define FAN_VPHELPER(N) \ - VPHELPER(VP_Fan##N##_Percentage, &thermalManager.fan_speed[N], DGUSScreenVariableHandler::DGUSLCD_PercentageToUint8, &DGUSScreenVariableHandler::DGUSLCD_SendPercentageToDisplay), \ - VPHELPER(VP_FAN##N##_CONTROL, &thermalManager.fan_speed[N], &DGUSScreenVariableHandler::HandleFanControl, nullptr), \ - VPHELPER(VP_FAN##N##_STATUS, &thermalManager.fan_speed[N], nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendFanStatusToDisplay), + VPHELPER(VP_Fan##N##_Percentage, &thermalManager.fan_speed[N], ScreenHandler.DGUSLCD_PercentageToUint8, &ScreenHandler.DGUSLCD_SendPercentageToDisplay), \ + VPHELPER(VP_FAN##N##_CONTROL, &thermalManager.fan_speed[N], &ScreenHandler.HandleFanControl, nullptr), \ + VPHELPER(VP_FAN##N##_STATUS, &thermalManager.fan_speed[N], nullptr, &ScreenHandler.DGUSLCD_SendFanStatusToDisplay), REPEAT(FAN_COUNT, FAN_VPHELPER) #endif // Feedrate - VPHELPER(VP_Feedrate_Percentage, &feedrate_percentage, DGUSScreenVariableHandler::DGUSLCD_SetValueDirectly, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay ), + VPHELPER(VP_Feedrate_Percentage, &feedrate_percentage, ScreenHandler.DGUSLCD_SetValueDirectly, &ScreenHandler.DGUSLCD_SendWordValueToDisplay ), // Position Data - VPHELPER(VP_XPos, ¤t_position.x, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>), - VPHELPER(VP_YPos, ¤t_position.y, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>), - VPHELPER(VP_ZPos, ¤t_position.z, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>), + VPHELPER(VP_XPos, ¤t_position.x, nullptr, ScreenHandler.DGUSLCD_SendFloatAsLongValueToDisplay<2>), + VPHELPER(VP_YPos, ¤t_position.y, nullptr, ScreenHandler.DGUSLCD_SendFloatAsLongValueToDisplay<2>), + VPHELPER(VP_ZPos, ¤t_position.z, nullptr, ScreenHandler.DGUSLCD_SendFloatAsLongValueToDisplay<2>), // Print Progress - #if ENABLED(LCD_SET_PROGRESS_MANUALLY) - VPHELPER(VP_PrintProgress_Percentage, &ui.progress_override, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay ), - #endif + VPHELPER(VP_PrintProgress_Percentage, nullptr, nullptr, ScreenHandler.DGUSLCD_SendPrintProgressToDisplay ), // Print Time - VPHELPER_STR(VP_PrintTime, nullptr, VP_PrintTime_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendPrintTimeToDisplay ), + VPHELPER_STR(VP_PrintTime, nullptr, VP_PrintTime_LEN, nullptr, ScreenHandler.DGUSLCD_SendPrintTimeToDisplay ), #if ENABLED(PRINTCOUNTER) - VPHELPER_STR(VP_PrintAccTime, nullptr, VP_PrintAccTime_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendPrintAccTimeToDisplay ), - VPHELPER_STR(VP_PrintsTotal, nullptr, VP_PrintsTotal_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendPrintsTotalToDisplay ), + VPHELPER_STR(VP_PrintAccTime, nullptr, VP_PrintAccTime_LEN, nullptr, ScreenHandler.DGUSLCD_SendPrintAccTimeToDisplay ), + VPHELPER_STR(VP_PrintsTotal, nullptr, VP_PrintsTotal_LEN, nullptr, ScreenHandler.DGUSLCD_SendPrintsTotalToDisplay ), #endif - VPHELPER(VP_X_STEP_PER_MM, &planner.settings.axis_steps_per_mm[X_AXIS], DGUSScreenVariableHandler::HandleStepPerMMChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>), - VPHELPER(VP_Y_STEP_PER_MM, &planner.settings.axis_steps_per_mm[Y_AXIS], DGUSScreenVariableHandler::HandleStepPerMMChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>), - VPHELPER(VP_Z_STEP_PER_MM, &planner.settings.axis_steps_per_mm[Z_AXIS], DGUSScreenVariableHandler::HandleStepPerMMChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>), + VPHELPER(VP_X_STEP_PER_MM, &planner.settings.axis_steps_per_mm[X_AXIS], ScreenHandler.HandleStepPerMMChanged, ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<1>), + VPHELPER(VP_Y_STEP_PER_MM, &planner.settings.axis_steps_per_mm[Y_AXIS], ScreenHandler.HandleStepPerMMChanged, ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<1>), + VPHELPER(VP_Z_STEP_PER_MM, &planner.settings.axis_steps_per_mm[Z_AXIS], ScreenHandler.HandleStepPerMMChanged, ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<1>), #if HOTENDS >= 1 - VPHELPER(VP_E0_STEP_PER_MM, &planner.settings.axis_steps_per_mm[E_AXIS_N(0)], DGUSScreenVariableHandler::HandleStepPerMMExtruderChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>), + VPHELPER(VP_E0_STEP_PER_MM, &planner.settings.axis_steps_per_mm[E_AXIS_N(0)], ScreenHandler.HandleStepPerMMExtruderChanged, ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<1>), #endif #if HOTENDS >= 2 - VPHELPER(VP_E1_STEP_PER_MM, &planner.settings.axis_steps_per_mm[E_AXIS_N(1)], DGUSScreenVariableHandler::HandleStepPerMMExtruderChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>), + VPHELPER(VP_E1_STEP_PER_MM, &planner.settings.axis_steps_per_mm[E_AXIS_N(1)], ScreenHandler.HandleStepPerMMExtruderChanged, ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<1>), #endif // SDCard File listing. #if ENABLED(SDSUPPORT) - VPHELPER(VP_SD_ScrollEvent, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_ScrollFilelist, nullptr), - VPHELPER(VP_SD_FileSelected, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_FileSelected, nullptr), - VPHELPER(VP_SD_FileSelectConfirm, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_StartPrint, nullptr), - VPHELPER_STR(VP_SD_FileName0, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ), - VPHELPER_STR(VP_SD_FileName1, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ), - VPHELPER_STR(VP_SD_FileName2, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ), - VPHELPER_STR(VP_SD_FileName3, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ), - VPHELPER_STR(VP_SD_FileName4, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ), - VPHELPER(VP_SD_ResumePauseAbort, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_ResumePauseAbort, nullptr), - VPHELPER(VP_SD_AbortPrintConfirmed, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_ReallyAbort, nullptr), - VPHELPER(VP_SD_Print_Setting, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_PrintTune, nullptr), + VPHELPER(VP_SD_ScrollEvent, nullptr, ScreenHandler.DGUSLCD_SD_ScrollFilelist, nullptr), + VPHELPER(VP_SD_FileSelected, nullptr, ScreenHandler.DGUSLCD_SD_FileSelected, nullptr), + VPHELPER(VP_SD_FileSelectConfirm, nullptr, ScreenHandler.DGUSLCD_SD_StartPrint, nullptr), + VPHELPER_STR(VP_SD_FileName0, nullptr, VP_SD_FileName_LEN, nullptr, ScreenHandler.DGUSLCD_SD_SendFilename ), + VPHELPER_STR(VP_SD_FileName1, nullptr, VP_SD_FileName_LEN, nullptr, ScreenHandler.DGUSLCD_SD_SendFilename ), + VPHELPER_STR(VP_SD_FileName2, nullptr, VP_SD_FileName_LEN, nullptr, ScreenHandler.DGUSLCD_SD_SendFilename ), + VPHELPER_STR(VP_SD_FileName3, nullptr, VP_SD_FileName_LEN, nullptr, ScreenHandler.DGUSLCD_SD_SendFilename ), + VPHELPER_STR(VP_SD_FileName4, nullptr, VP_SD_FileName_LEN, nullptr, ScreenHandler.DGUSLCD_SD_SendFilename ), + VPHELPER(VP_SD_ResumePauseAbort, nullptr, ScreenHandler.DGUSLCD_SD_ResumePauseAbort, nullptr), + VPHELPER(VP_SD_AbortPrintConfirmed, nullptr, ScreenHandler.DGUSLCD_SD_ReallyAbort, nullptr), + VPHELPER(VP_SD_Print_Setting, nullptr, ScreenHandler.DGUSLCD_SD_PrintTune, nullptr), #if HAS_BED_PROBE - VPHELPER(VP_SD_Print_ProbeOffsetZ, &probe.offset.z, DGUSScreenVariableHandler::HandleProbeOffsetZChanged, &DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<2>), + VPHELPER(VP_SD_Print_ProbeOffsetZ, &probe.offset.z, ScreenHandler.HandleProbeOffsetZChanged, &ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<2>), #if ENABLED(BABYSTEPPING) - VPHELPER(VP_SD_Print_LiveAdjustZ, nullptr, DGUSScreenVariableHandler::HandleLiveAdjustZ, nullptr), + VPHELPER(VP_SD_Print_LiveAdjustZ, nullptr, ScreenHandler.HandleLiveAdjustZ, nullptr), #endif #endif #endif #if ENABLED(DGUS_UI_WAITING) - VPHELPER(VP_WAITING_STATUS, nullptr, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendWaitingStatusToDisplay), + VPHELPER(VP_WAITING_STATUS, nullptr, nullptr, ScreenHandler.DGUSLCD_SendWaitingStatusToDisplay), #endif // Messages for the User, shared by the popup and the kill screen. They cant be autouploaded as we do not buffer content. - { .VP = VP_MSGSTR1, .memadr = nullptr, .size = VP_MSGSTR1_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM }, - { .VP = VP_MSGSTR2, .memadr = nullptr, .size = VP_MSGSTR2_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM }, - { .VP = VP_MSGSTR3, .memadr = nullptr, .size = VP_MSGSTR3_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM }, - { .VP = VP_MSGSTR4, .memadr = nullptr, .size = VP_MSGSTR4_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM }, + { .VP = VP_MSGSTR1, .memadr = nullptr, .size = VP_MSGSTR1_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &ScreenHandler.DGUSLCD_SendStringToDisplayPGM }, + { .VP = VP_MSGSTR2, .memadr = nullptr, .size = VP_MSGSTR2_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &ScreenHandler.DGUSLCD_SendStringToDisplayPGM }, + { .VP = VP_MSGSTR3, .memadr = nullptr, .size = VP_MSGSTR3_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &ScreenHandler.DGUSLCD_SendStringToDisplayPGM }, + { .VP = VP_MSGSTR4, .memadr = nullptr, .size = VP_MSGSTR4_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &ScreenHandler.DGUSLCD_SendStringToDisplayPGM }, VPHELPER(0, 0, 0, 0) // must be last entry. }; diff --git a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinitionHIPRECY.h b/Marlin/src/lcd/extui/lib/dgus/hiprecy/DGUSDisplayDef.h similarity index 99% rename from Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinitionHIPRECY.h rename to Marlin/src/lcd/extui/lib/dgus/hiprecy/DGUSDisplayDef.h index dbf7b8f631cd..3ff5e06dc18c 100644 --- a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinitionHIPRECY.h +++ b/Marlin/src/lcd/extui/lib/dgus/hiprecy/DGUSDisplayDef.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -35,6 +35,7 @@ enum DGUSLCD_Screens : uint8_t { DGUSLCD_SCREEN_FILAMENT_LOADING = 76, DGUSLCD_SCREEN_FILAMENT_UNLOADING = 82, DGUSLCD_SCREEN_MANUALEXTRUDE = 84, + DGUSLCD_SCREEN_Z_OFFSET = 88, DGUSLCD_SCREEN_SDFILELIST = 3, DGUSLCD_SCREEN_SDPRINTMANIPULATION = 7, DGUSLCD_SCREEN_SDPRINTTUNE = 9, diff --git a/Marlin/src/lcd/extui/lib/dgus/origin/DGUSDisplayDef.cpp b/Marlin/src/lcd/extui/lib/dgus/origin/DGUSDisplayDef.cpp new file mode 100644 index 000000000000..f9d4351e02d9 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus/origin/DGUSDisplayDef.cpp @@ -0,0 +1,310 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* DGUS implementation written by coldtobi in 2019 for Marlin */ + +#include "../../../../../inc/MarlinConfigPre.h" + +#if ENABLED(DGUS_LCD_UI_ORIGIN) + +#include "../DGUSDisplayDef.h" +#include "../DGUSDisplay.h" +#include "../DGUSScreenHandler.h" + +#include "../../../../../module/temperature.h" +#include "../../../../../module/motion.h" +#include "../../../../../module/planner.h" + +#include "../../../../ultralcd.h" +#include "../../../ui_api.h" + +#if ENABLED(DGUS_UI_MOVE_DIS_OPTION) + uint16_t distanceToMove = 10; +#endif +using namespace ExtUI; + +const uint16_t VPList_Boot[] PROGMEM = { + VP_MARLIN_VERSION, + 0x0000 +}; + +const uint16_t VPList_Main[] PROGMEM = { + /* VP_M117, for completeness, but it cannot be auto-uploaded. */ + 0x0000 +}; + +const uint16_t VPList_Temp[] PROGMEM = { + #if HOTENDS >= 1 + VP_T_E0_Is, VP_T_E0_Set, + #endif + #if HOTENDS >= 2 + VP_T_E1_Is, VP_T_E1_Set, + #endif + #if HAS_HEATED_BED + VP_T_Bed_Is, VP_T_Bed_Set, + #endif + 0x0000 +}; + +const uint16_t VPList_Status[] PROGMEM = { + /* VP_M117, for completeness, but it cannot be auto-uploaded */ + #if HOTENDS >= 1 + VP_T_E0_Is, VP_T_E0_Set, + #endif + #if HOTENDS >= 2 + VP_T_E1_Is, VP_T_E1_Set, + #endif + #if HAS_HEATED_BED + VP_T_Bed_Is, VP_T_Bed_Set, + #endif + #if HAS_FAN + VP_Fan0_Percentage, + #endif + VP_XPos, VP_YPos, VP_ZPos, + VP_Fan0_Percentage, + VP_Feedrate_Percentage, + VP_PrintProgress_Percentage, + 0x0000 +}; + +const uint16_t VPList_Status2[] PROGMEM = { + /* VP_M117, for completeness, but it cannot be auto-uploaded */ + #if HOTENDS >= 1 + VP_Flowrate_E0, + #endif + #if HOTENDS >= 2 + VP_Flowrate_E1, + #endif + VP_PrintProgress_Percentage, + VP_PrintTime, + 0x0000 +}; + +const uint16_t VPList_ManualMove[] PROGMEM = { + VP_XPos, VP_YPos, VP_ZPos, + 0x0000 +}; + +const uint16_t VPList_ManualExtrude[] PROGMEM = { + VP_EPos, + 0x0000 +}; + +const uint16_t VPList_FanAndFeedrate[] PROGMEM = { + VP_Feedrate_Percentage, VP_Fan0_Percentage, + 0x0000 +}; + +const uint16_t VPList_SD_FlowRates[] PROGMEM = { + VP_Flowrate_E0, VP_Flowrate_E1, + 0x0000 +}; + +const uint16_t VPList_SDFileList[] PROGMEM = { + VP_SD_FileName0, VP_SD_FileName1, VP_SD_FileName2, VP_SD_FileName3, VP_SD_FileName4, + 0x0000 +}; + +const uint16_t VPList_SD_PrintManipulation[] PROGMEM = { + VP_PrintProgress_Percentage, VP_PrintTime, + 0x0000 +}; + +const struct VPMapping VPMap[] PROGMEM = { + { DGUSLCD_SCREEN_BOOT, VPList_Boot }, + { DGUSLCD_SCREEN_MAIN, VPList_Main }, + { DGUSLCD_SCREEN_TEMPERATURE, VPList_Temp }, + { DGUSLCD_SCREEN_STATUS, VPList_Status }, + { DGUSLCD_SCREEN_STATUS2, VPList_Status2 }, + { DGUSLCD_SCREEN_MANUALMOVE, VPList_ManualMove }, + { DGUSLCD_SCREEN_MANUALEXTRUDE, VPList_ManualExtrude }, + { DGUSLCD_SCREEN_FANANDFEEDRATE, VPList_FanAndFeedrate }, + { DGUSLCD_SCREEN_FLOWRATES, VPList_SD_FlowRates }, + { DGUSLCD_SCREEN_SDPRINTMANIPULATION, VPList_SD_PrintManipulation }, + { DGUSLCD_SCREEN_SDFILELIST, VPList_SDFileList }, + { 0 , nullptr } // List is terminated with an nullptr as table entry. +}; + +const char MarlinVersion[] PROGMEM = SHORT_BUILD_VERSION; + +// Helper to define a DGUS_VP_Variable for common use cases. +#define VPHELPER(VPADR, VPADRVAR, RXFPTR, TXFPTR ) { .VP=VPADR, .memadr=VPADRVAR, .size=sizeof(VPADRVAR), \ + .set_by_display_handler = RXFPTR, .send_to_display_handler = TXFPTR } + +// Helper to define a DGUS_VP_Variable when the sizeo of the var cannot be determined automaticalyl (eg. a string) +#define VPHELPER_STR(VPADR, VPADRVAR, STRLEN, RXFPTR, TXFPTR ) { .VP=VPADR, .memadr=VPADRVAR, .size=STRLEN, \ + .set_by_display_handler = RXFPTR, .send_to_display_handler = TXFPTR } + +const struct DGUS_VP_Variable ListOfVP[] PROGMEM = { + // Helper to detect touch events + VPHELPER(VP_SCREENCHANGE, nullptr, ScreenHandler.ScreenChangeHook, nullptr), + VPHELPER(VP_SCREENCHANGE_ASK, nullptr, ScreenHandler.ScreenChangeHookIfIdle, nullptr), + #if ENABLED(SDSUPPORT) + VPHELPER(VP_SCREENCHANGE_WHENSD, nullptr, ScreenHandler.ScreenChangeHookIfSD, nullptr), + #endif + VPHELPER(VP_CONFIRMED, nullptr, ScreenHandler.ScreenConfirmedOK, nullptr), + + VPHELPER(VP_TEMP_ALL_OFF, nullptr, &ScreenHandler.HandleAllHeatersOff, nullptr), + + #if ENABLED(DGUS_UI_MOVE_DIS_OPTION) + VPHELPER(VP_MOVE_OPTION, &distanceToMove, &ScreenHandler.HandleManualMoveOption, nullptr), + #endif + #if ENABLED(DGUS_UI_MOVE_DIS_OPTION) + VPHELPER(VP_MOVE_X, &distanceToMove, &ScreenHandler.HandleManualMove, nullptr), + VPHELPER(VP_MOVE_Y, &distanceToMove, &ScreenHandler.HandleManualMove, nullptr), + VPHELPER(VP_MOVE_Z, &distanceToMove, &ScreenHandler.HandleManualMove, nullptr), + VPHELPER(VP_HOME_ALL, &distanceToMove, &ScreenHandler.HandleManualMove, nullptr), + #else + VPHELPER(VP_MOVE_X, nullptr, &ScreenHandler.HandleManualMove, nullptr), + VPHELPER(VP_MOVE_Y, nullptr, &ScreenHandler.HandleManualMove, nullptr), + VPHELPER(VP_MOVE_Z, nullptr, &ScreenHandler.HandleManualMove, nullptr), + VPHELPER(VP_HOME_ALL, nullptr, &ScreenHandler.HandleManualMove, nullptr), + #endif + + VPHELPER(VP_MOTOR_LOCK_UNLOK, nullptr, &ScreenHandler.HandleMotorLockUnlock, nullptr), + #if ENABLED(POWER_LOSS_RECOVERY) + VPHELPER(VP_POWER_LOSS_RECOVERY, nullptr, &ScreenHandler.HandlePowerLossRecovery, nullptr), + #endif + VPHELPER(VP_SETTINGS, nullptr, &ScreenHandler.HandleSettings, nullptr), + + { .VP = VP_MARLIN_VERSION, .memadr = (void*)MarlinVersion, .size = VP_MARLIN_VERSION_LEN, .set_by_display_handler = nullptr, .send_to_display_handler =&ScreenHandler.DGUSLCD_SendStringToDisplayPGM }, + // M117 LCD String (We don't need the string in memory but "just" push it to the display on demand, hence the nullptr + { .VP = VP_M117, .memadr = nullptr, .size = VP_M117_LEN, .set_by_display_handler = nullptr, .send_to_display_handler =&ScreenHandler.DGUSLCD_SendStringToDisplay }, + + // Temperature Data + #if HOTENDS >= 1 + VPHELPER(VP_T_E0_Is, nullptr, nullptr, SET_VARIABLE(getActualTemp_celsius, E0, long)), + VPHELPER(VP_T_E0_Set, nullptr, GET_VARIABLE(setTargetTemp_celsius, E0), + SET_VARIABLE(getTargetTemp_celsius, E0)), + VPHELPER(VP_Flowrate_E0, nullptr, ScreenHandler.HandleFlowRateChanged, &ScreenHandler.DGUSLCD_SendWordValueToDisplay), + VPHELPER(VP_EPos, &destination.e, nullptr, ScreenHandler.DGUSLCD_SendFloatAsLongValueToDisplay<2>), + VPHELPER(VP_MOVE_E0, nullptr, &ScreenHandler.HandleManualExtrude, nullptr), + VPHELPER(VP_E0_CONTROL, &thermalManager.temp_hotend[0].target, &ScreenHandler.HandleHeaterControl, nullptr), + VPHELPER(VP_E0_STATUS, &thermalManager.temp_hotend[0].target, nullptr, &ScreenHandler.DGUSLCD_SendHeaterStatusToDisplay), + #if ENABLED(DGUS_PREHEAT_UI) + VPHELPER(VP_E0_BED_PREHEAT, nullptr, &ScreenHandler.HandlePreheat, nullptr), + #endif + #if ENABLED(PIDTEMP) + VPHELPER(VP_E0_PID_P, &thermalManager.temp_hotend[0].pid.Kp, ScreenHandler.HandleTemperaturePIDChanged, ScreenHandler.DGUSLCD_SendTemperaturePID), + VPHELPER(VP_E0_PID_I, &thermalManager.temp_hotend[0].pid.Ki, ScreenHandler.HandleTemperaturePIDChanged, ScreenHandler.DGUSLCD_SendTemperaturePID), + VPHELPER(VP_E0_PID_D, &thermalManager.temp_hotend[0].pid.Kd, ScreenHandler.HandleTemperaturePIDChanged, ScreenHandler.DGUSLCD_SendTemperaturePID), + VPHELPER(VP_PID_AUTOTUNE_E0, nullptr, &ScreenHandler.HandlePIDAutotune, nullptr), + #endif + #if ENABLED(DGUS_FILAMENT_LOADUNLOAD) + VPHELPER(VP_E0_FILAMENT_LOAD_UNLOAD, nullptr, &ScreenHandler.HandleFilamentOption, &ScreenHandler.HandleFilamentLoadUnload), + #endif + #endif + #if HOTENDS >= 2 + VPHELPER(VP_T_E1_Is, &thermalManager.temp_hotend[1].celsius, nullptr, DGUSLCD_SendFloatAsLongValueToDisplay<0>), + VPHELPER(VP_T_E1_Set, &thermalManager.temp_hotend[1].target, ScreenHandler.HandleTemperatureChanged, &ScreenHandler.DGUSLCD_SendWordValueToDisplay), + VPHELPER(VP_Flowrate_E1, nullptr, ScreenHandler.HandleFlowRateChanged, &ScreenHandler.DGUSLCD_SendWordValueToDisplay), + VPHELPER(VP_MOVE_E1, nullptr, &ScreenHandler.HandleManualExtrude, nullptr), + VPHELPER(VP_E1_CONTROL, &thermalManager.temp_hotend[1].target, &ScreenHandler.HandleHeaterControl, nullptr), + VPHELPER(VP_E1_STATUS, &thermalManager.temp_hotend[1].target, nullptr, &ScreenHandler.DGUSLCD_SendHeaterStatusToDisplay), + #if ENABLED(PIDTEMP) + VPHELPER(VP_PID_AUTOTUNE_E1, nullptr, &ScreenHandler.HandlePIDAutotune, nullptr), + #endif + #endif + #if HAS_HEATED_BED + VPHELPER(VP_T_Bed_Is, &thermalManager.temp_bed.celsius, nullptr, ScreenHandler.DGUSLCD_SendFloatAsLongValueToDisplay<0>), + VPHELPER(VP_T_Bed_Set, &thermalManager.temp_bed.target, ScreenHandler.HandleTemperatureChanged, &ScreenHandler.DGUSLCD_SendWordValueToDisplay), + VPHELPER(VP_BED_CONTROL, &thermalManager.temp_bed.target, &ScreenHandler.HandleHeaterControl, nullptr), + VPHELPER(VP_BED_STATUS, &thermalManager.temp_bed.target, nullptr, &ScreenHandler.DGUSLCD_SendHeaterStatusToDisplay), + #if ENABLED(PIDTEMPBED) + VPHELPER(VP_BED_PID_P, &thermalManager.temp_bed.pid.Kp, ScreenHandler.HandleTemperaturePIDChanged, ScreenHandler.DGUSLCD_SendTemperaturePID), + VPHELPER(VP_BED_PID_I, &thermalManager.temp_bed.pid.Ki, ScreenHandler.HandleTemperaturePIDChanged, ScreenHandler.DGUSLCD_SendTemperaturePID), + VPHELPER(VP_BED_PID_D, &thermalManager.temp_bed.pid.Kd, ScreenHandler.HandleTemperaturePIDChanged, ScreenHandler.DGUSLCD_SendTemperaturePID), + #endif + #endif + + // Fan Data + #if HAS_FAN + #define FAN_VPHELPER(N) \ + VPHELPER(VP_Fan##N##_Percentage, &thermalManager.fan_speed[N], ScreenHandler.DGUSLCD_PercentageToUint8, &ScreenHandler.DGUSLCD_SendPercentageToDisplay), \ + VPHELPER(VP_FAN##N##_CONTROL, &thermalManager.fan_speed[N], &ScreenHandler.HandleFanControl, nullptr), \ + VPHELPER(VP_FAN##N##_STATUS, &thermalManager.fan_speed[N], nullptr, &ScreenHandler.DGUSLCD_SendFanStatusToDisplay), + REPEAT(FAN_COUNT, FAN_VPHELPER) + #endif + + // Feedrate + VPHELPER(VP_Feedrate_Percentage, &feedrate_percentage, ScreenHandler.DGUSLCD_SetValueDirectly, &ScreenHandler.DGUSLCD_SendWordValueToDisplay ), + + // Position Data + VPHELPER(VP_XPos, ¤t_position.x, nullptr, ScreenHandler.DGUSLCD_SendFloatAsLongValueToDisplay<2>), + VPHELPER(VP_YPos, ¤t_position.y, nullptr, ScreenHandler.DGUSLCD_SendFloatAsLongValueToDisplay<2>), + VPHELPER(VP_ZPos, ¤t_position.z, nullptr, ScreenHandler.DGUSLCD_SendFloatAsLongValueToDisplay<2>), + + // Print Progress + VPHELPER(VP_PrintProgress_Percentage, nullptr, nullptr, ScreenHandler.DGUSLCD_SendPrintProgressToDisplay ), + + // Print Time + VPHELPER_STR(VP_PrintTime, nullptr, VP_PrintTime_LEN, nullptr, ScreenHandler.DGUSLCD_SendPrintTimeToDisplay ), + #if ENABLED(PRINTCOUNTER) + VPHELPER_STR(VP_PrintAccTime, nullptr, VP_PrintAccTime_LEN, nullptr, ScreenHandler.DGUSLCD_SendPrintAccTimeToDisplay ), + VPHELPER_STR(VP_PrintsTotal, nullptr, VP_PrintsTotal_LEN, nullptr, ScreenHandler.DGUSLCD_SendPrintsTotalToDisplay ), + #endif + + VPHELPER(VP_X_STEP_PER_MM, &planner.settings.axis_steps_per_mm[X_AXIS], ScreenHandler.HandleStepPerMMChanged, ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<1>), + VPHELPER(VP_Y_STEP_PER_MM, &planner.settings.axis_steps_per_mm[Y_AXIS], ScreenHandler.HandleStepPerMMChanged, ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<1>), + VPHELPER(VP_Z_STEP_PER_MM, &planner.settings.axis_steps_per_mm[Z_AXIS], ScreenHandler.HandleStepPerMMChanged, ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<1>), + #if HOTENDS >= 1 + VPHELPER(VP_E0_STEP_PER_MM, &planner.settings.axis_steps_per_mm[E_AXIS_N(0)], ScreenHandler.HandleStepPerMMExtruderChanged, ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<1>), + #endif + #if HOTENDS >= 2 + VPHELPER(VP_E1_STEP_PER_MM, &planner.settings.axis_steps_per_mm[E_AXIS_N(1)], ScreenHandler.HandleStepPerMMExtruderChanged, ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<1>), + #endif + + // SDCard File listing. + #if ENABLED(SDSUPPORT) + VPHELPER(VP_SD_ScrollEvent, nullptr, ScreenHandler.DGUSLCD_SD_ScrollFilelist, nullptr), + VPHELPER(VP_SD_FileSelected, nullptr, ScreenHandler.DGUSLCD_SD_FileSelected, nullptr), + VPHELPER(VP_SD_FileSelectConfirm, nullptr, ScreenHandler.DGUSLCD_SD_StartPrint, nullptr), + VPHELPER_STR(VP_SD_FileName0, nullptr, VP_SD_FileName_LEN, nullptr, ScreenHandler.DGUSLCD_SD_SendFilename ), + VPHELPER_STR(VP_SD_FileName1, nullptr, VP_SD_FileName_LEN, nullptr, ScreenHandler.DGUSLCD_SD_SendFilename ), + VPHELPER_STR(VP_SD_FileName2, nullptr, VP_SD_FileName_LEN, nullptr, ScreenHandler.DGUSLCD_SD_SendFilename ), + VPHELPER_STR(VP_SD_FileName3, nullptr, VP_SD_FileName_LEN, nullptr, ScreenHandler.DGUSLCD_SD_SendFilename ), + VPHELPER_STR(VP_SD_FileName4, nullptr, VP_SD_FileName_LEN, nullptr, ScreenHandler.DGUSLCD_SD_SendFilename ), + VPHELPER(VP_SD_ResumePauseAbort, nullptr, ScreenHandler.DGUSLCD_SD_ResumePauseAbort, nullptr), + VPHELPER(VP_SD_AbortPrintConfirmed, nullptr, ScreenHandler.DGUSLCD_SD_ReallyAbort, nullptr), + VPHELPER(VP_SD_Print_Setting, nullptr, ScreenHandler.DGUSLCD_SD_PrintTune, nullptr), + #if HAS_BED_PROBE + VPHELPER(VP_SD_Print_ProbeOffsetZ, &probe.offset.z, ScreenHandler.HandleProbeOffsetZChanged, &ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<2>), + #if ENABLED(BABYSTEPPING) + VPHELPER(VP_SD_Print_LiveAdjustZ, nullptr, ScreenHandler.HandleLiveAdjustZ, nullptr), + #endif + #endif + #endif + + #if ENABLED(DGUS_UI_WAITING) + VPHELPER(VP_WAITING_STATUS, nullptr, nullptr, ScreenHandler.DGUSLCD_SendWaitingStatusToDisplay), + #endif + + // Messages for the User, shared by the popup and the kill screen. They cant be autouploaded as we do not buffer content. + { .VP = VP_MSGSTR1, .memadr = nullptr, .size = VP_MSGSTR1_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &ScreenHandler.DGUSLCD_SendStringToDisplayPGM }, + { .VP = VP_MSGSTR2, .memadr = nullptr, .size = VP_MSGSTR2_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &ScreenHandler.DGUSLCD_SendStringToDisplayPGM }, + { .VP = VP_MSGSTR3, .memadr = nullptr, .size = VP_MSGSTR3_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &ScreenHandler.DGUSLCD_SendStringToDisplayPGM }, + { .VP = VP_MSGSTR4, .memadr = nullptr, .size = VP_MSGSTR4_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &ScreenHandler.DGUSLCD_SendStringToDisplayPGM }, + + VPHELPER(0, 0, 0, 0) // must be last entry. +}; + +#endif // DGUS_LCD_UI_ORIGIN diff --git a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinitionOrigin.h b/Marlin/src/lcd/extui/lib/dgus/origin/DGUSDisplayDef.h similarity index 98% rename from Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinitionOrigin.h rename to Marlin/src/lcd/extui/lib/dgus/origin/DGUSDisplayDef.h index 756b91ddbdf6..451c11adba16 100644 --- a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinitionOrigin.h +++ b/Marlin/src/lcd/extui/lib/dgus/origin/DGUSDisplayDef.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -192,7 +192,7 @@ constexpr uint16_t VP_Flowrate_E1 = 0x3092; // 2 Byte Integer //constexpr uint16_t VP_Flowrate_E5 = 0x309A; constexpr uint16_t VP_Fan0_Percentage = 0x3100; // 2 Byte Integer (0..100) -//constexpr uint16_t VP_Fan1_Percentage = 0x33A2; // 2 Byte Integer (0..100) +constexpr uint16_t VP_Fan1_Percentage = 0x33A2; // 2 Byte Integer (0..100) //constexpr uint16_t VP_Fan2_Percentage = 0x33A4; // 2 Byte Integer (0..100) //constexpr uint16_t VP_Fan3_Percentage = 0x33A6; // 2 Byte Integer (0..100) diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/archim2-flash/flash_storage.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/archim2-flash/flash_storage.cpp similarity index 97% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/archim2-flash/flash_storage.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/archim2-flash/flash_storage.cpp index c8cc6e8e9d67..2c466ffd0449 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/archim2-flash/flash_storage.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/archim2-flash/flash_storage.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../compat.h" @@ -42,7 +42,6 @@ constexpr uint32_t flash_eeprom_version = 1; * 0 16 DATA STORAGE AREA * 16 1 VERSIONING DATA * 17 inf MEDIA STORAGE AREA - * */ #define DATA_STORAGE_SIZE_64K @@ -188,7 +187,7 @@ bool UIFlashStorage::is_present = false; } void UIFlashStorage::initialize() { - for(uint8_t i = 0; i < 10; i++) { + for (uint8_t i = 0; i < 10; i++) { if (check_known_device()) { is_present = true; break; @@ -239,7 +238,7 @@ bool UIFlashStorage::is_present = false; uint16_t stride = 4 + block_size; int32_t read_offset = -1; - for(uint32_t offset = 0; offset < (data_storage_area_size - stride); offset += stride) { + 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)); @@ -395,9 +394,8 @@ bool UIFlashStorage::is_present = false; 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++) { + for (uint8_t i = 0; i < slot; i++) addr += spi_read_32(); - } spi_read_end(); return addr; } @@ -442,7 +440,7 @@ bool UIFlashStorage::is_present = false; addr = get_media_file_start(slot); // Write out the file itself - for(;;) { + for (;;) { const int16_t nBytes = reader.read(buff, write_page_size); if (nBytes == -1) { SERIAL_ECHOLNPGM("Failed to read from file"); @@ -450,12 +448,9 @@ bool UIFlashStorage::is_present = false; } addr = write(addr, buff, nBytes); - if (nBytes != write_page_size) - break; + if (nBytes != write_page_size) break; - #if ENABLED(EXTENSIBLE_UI) - ExtUI::yield(); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::yield()); } SERIAL_ECHOLNPGM("DONE"); @@ -493,21 +488,20 @@ bool UIFlashStorage::is_present = false; addr += nBytes; if (nBytes != write_page_size) break; - #if ENABLED(EXTENSIBLE_UI) - ExtUI::yield(); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::yield()); }; if (verifyOk) { SERIAL_ECHOLNPGM("DONE"); return SUCCESS; - } else { + } + else { SERIAL_ECHOLNPGM("FAIL"); return VERIFY_ERROR; } #else return VERIFY_ERROR; - #endif // ENABLED(SDSUPPORT) + #endif // SDSUPPORT } bool UIFlashStorage::BootMediaReader::isAvailable(uint32_t slot) { diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/archim2-flash/flash_storage.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/archim2-flash/flash_storage.h similarity index 97% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/archim2-flash/flash_storage.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/archim2-flash/flash_storage.h index 2917cb0b1e7b..3edc2a9de1c8 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/archim2-flash/flash_storage.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/archim2-flash/flash_storage.h @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ class SPIFlash { diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/archim2-flash/media_file_reader.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/archim2-flash/media_file_reader.cpp similarity index 97% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/archim2-flash/media_file_reader.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/archim2-flash/media_file_reader.cpp index 68886166c2d3..46683401dca7 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/archim2-flash/media_file_reader.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/archim2-flash/media_file_reader.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../compat.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/archim2-flash/media_file_reader.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/archim2-flash/media_file_reader.h similarity index 95% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/archim2-flash/media_file_reader.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/archim2-flash/media_file_reader.h index d64182fd5b0b..fcaa610e8bdb 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/archim2-flash/media_file_reader.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/archim2-flash/media_file_reader.h @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/compat.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/compat.h similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/compat.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/compat.h index c3e8052a0e51..11ad0798b56f 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/compat.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/compat.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once diff --git a/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/config.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/config.h new file mode 100644 index 000000000000..7476c9e67e4c --- /dev/null +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/config.h @@ -0,0 +1,26 @@ +/************ + * 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: . * + ****************************************************************************/ + +#pragma once + +#include "compat.h" + +// Configure this display with options in Configuration_adv.h diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/LICENSE.txt b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/LICENSE.txt similarity index 99% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/LICENSE.txt rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/LICENSE.txt index 94a9ed024d38..e60008693e01 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/LICENSE.txt +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/LICENSE.txt @@ -1,7 +1,7 @@ GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -645,7 +645,7 @@ the "copyright" line and a pointer to where the full notice is found. 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 . + along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. @@ -664,11 +664,11 @@ 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 -. +. 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 -. +. diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/README.md b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/README.md similarity index 100% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/README.md rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/README.md diff --git a/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/boards.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/boards.h new file mode 100644 index 000000000000..c09d10f1488c --- /dev/null +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/boards.h @@ -0,0 +1,184 @@ +/************ + * 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: . * + ****************************************************************************/ + +#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) + * and 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: + * https://www.hantronix.com/files/data/1278363262430-3.pdf + * https://www.haoyuelectronics.com/Attachment/HY43-LCD/LCD%20DataSheet.pdf + * https://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: + * https://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) + * https://4dsystems.com.au/4dlcd-ft843 + * Datasheet: + * https://4dsystems.com.au/mwdownloads/download/link/id/52/ + */ +#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 + * Datasheet https://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 */ + } + +/** + * FYSETC Color LCD + * https://www.aliexpress.com/item/4000627651757.html + * Product information: + * https://github.com/FYSETC/TFT81050 + */ +#elif defined(LCD_FYSETC_TFT81050) + #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 TOUCH_UI_FTDI_EVE board specified. To add a new board, modify this file." + +#endif diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.cpp similarity index 86% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.cpp index f57d2d896a14..bb95411e06fd 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "ftdi_basic.h" @@ -58,7 +58,7 @@ void CLCD::FontMetrics::load(const uint8_t font) { uint16_t CLCD::FontMetrics::get_text_width(const char *str, size_t n) const { uint16_t width = 0; const uint8_t *p = (const uint8_t *) str; - for(;;) { + for (;;) { const uint8_t val = *p++; n--; if (!val || n == 0) break; width += val < 128 ? char_widths[val] : 0; @@ -69,7 +69,7 @@ uint16_t CLCD::FontMetrics::get_text_width(const char *str, size_t n) const { uint16_t CLCD::FontMetrics::get_text_width(progmem_str str, size_t n) const { uint16_t width = 0; const uint8_t *p = (const uint8_t *) str; - for(;;) { + for (;;) { const uint8_t val = pgm_read_byte(p++); n--; if (!val || n == 0) break; width += val < 128 ? char_widths[val] : 0; @@ -79,7 +79,7 @@ uint16_t CLCD::FontMetrics::get_text_width(progmem_str str, size_t n) const { /************************** HOST COMMAND FUNCTION *********************************/ -void CLCD::host_cmd (unsigned char host_command, unsigned char byte2) { // Sends 24-Bit Host Command to LCD +void CLCD::host_cmd(unsigned char host_command, unsigned char byte2) { // Sends 24-Bit Host Command to LCD if (host_command != FTDI::ACTIVE) { host_command |= 0x40; } @@ -92,7 +92,7 @@ void CLCD::host_cmd (unsigned char host_command, unsigned char byte2) { // Send /************************** MEMORY READ FUNCTIONS *********************************/ -void CLCD::spi_read_addr (uint32_t reg_address) { +void CLCD::spi_read_addr(uint32_t reg_address) { spi_send((reg_address >> 16) & 0x3F); // Address [21:16] spi_send((reg_address >> 8 ) & 0xFF); // Address [15:8] spi_send((reg_address >> 0) & 0xFF); // Address [7:0] @@ -100,7 +100,7 @@ void CLCD::spi_read_addr (uint32_t reg_address) { } // Write 4-Byte Address, Read Multiple Bytes -void CLCD::mem_read_bulk (uint32_t reg_address, uint8_t *data, uint16_t len) { +void CLCD::mem_read_bulk(uint32_t reg_address, uint8_t *data, uint16_t len) { spi_ftdi_select(); spi_read_addr(reg_address); spi_read_bulk (data, len); @@ -108,7 +108,7 @@ void CLCD::mem_read_bulk (uint32_t reg_address, uint8_t *data, uint16_t len) { } // Write 4-Byte Address, Read 1-Byte Data -uint8_t CLCD::mem_read_8 (uint32_t reg_address) { +uint8_t CLCD::mem_read_8(uint32_t reg_address) { spi_ftdi_select(); spi_read_addr(reg_address); uint8_t r_data = spi_read_8(); @@ -117,7 +117,7 @@ uint8_t CLCD::mem_read_8 (uint32_t reg_address) { } // Write 4-Byte Address, Read 2-Bytes Data -uint16_t CLCD::mem_read_16 (uint32_t reg_address) { +uint16_t CLCD::mem_read_16(uint32_t reg_address) { using namespace SPI::least_significant_byte_first; spi_ftdi_select(); spi_read_addr(reg_address); @@ -127,7 +127,7 @@ uint16_t CLCD::mem_read_16 (uint32_t reg_address) { } // Write 4-Byte Address, Read 4-Bytes Data -uint32_t CLCD::mem_read_32 (uint32_t reg_address) { +uint32_t CLCD::mem_read_32(uint32_t reg_address) { using namespace SPI::least_significant_byte_first; spi_ftdi_select(); spi_read_addr(reg_address); @@ -147,14 +147,14 @@ static inline uint8_t reverse_byte(uint8_t a) { } static inline uint8_t xbm_write(const uint8_t *p) {return reverse_byte(pgm_read_byte(p));} -void CLCD::spi_write_addr (uint32_t reg_address) { +void CLCD::spi_write_addr(uint32_t reg_address) { spi_send((reg_address >> 16) | 0x80); // Address [21:16] spi_send((reg_address >> 8 ) & 0xFF); // Address [15:8] spi_send((reg_address >> 0) & 0xFF); // Address [7:0] } // Write 3-Byte Address, Multiple Bytes, plus padding bytes, from RAM -void CLCD::mem_write_bulk (uint32_t reg_address, const void *data, uint16_t len, uint8_t padding) { +void CLCD::mem_write_bulk(uint32_t reg_address, const void *data, uint16_t len, uint8_t padding) { spi_ftdi_select(); spi_write_addr(reg_address); spi_write_bulk(data, len, padding); @@ -162,7 +162,7 @@ void CLCD::mem_write_bulk (uint32_t reg_address, const void *data, uint16_t len, } // Write 3-Byte Address, Multiple Bytes, plus padding bytes, from PROGMEM -void CLCD::mem_write_bulk (uint32_t reg_address, progmem_str str, uint16_t len, uint8_t padding) { +void CLCD::mem_write_bulk(uint32_t reg_address, progmem_str str, uint16_t len, uint8_t padding) { spi_ftdi_select(); spi_write_addr(reg_address); spi_write_bulk(str, len, padding); @@ -170,7 +170,7 @@ void CLCD::mem_write_bulk (uint32_t reg_address, progmem_str str, uint16_t len, } // Write 3-Byte Address, Multiple Bytes, plus padding bytes, from PROGMEM -void CLCD::mem_write_pgm (uint32_t reg_address, const void *data, uint16_t len, uint8_t padding) { +void CLCD::mem_write_pgm(uint32_t reg_address, const void *data, uint16_t len, uint8_t padding) { spi_ftdi_select(); spi_write_addr(reg_address); spi_write_bulk(data, len, padding); @@ -178,7 +178,7 @@ void CLCD::mem_write_pgm (uint32_t reg_address, const void *data, uint16_t len, } // Write 3-Byte Address, Multiple Bytes, plus padding bytes, from PROGMEM, reversing bytes (suitable for loading XBM images) -void CLCD::mem_write_xbm (uint32_t reg_address, progmem_str data, uint16_t len, uint8_t padding) { +void CLCD::mem_write_xbm(uint32_t reg_address, progmem_str data, uint16_t len, uint8_t padding) { spi_ftdi_select(); spi_write_addr(reg_address); spi_write_bulk(data, len, padding); @@ -186,7 +186,7 @@ void CLCD::mem_write_xbm (uint32_t reg_address, progmem_str data, uint16_t len, } // Write 3-Byte Address, Write 1-Byte Data -void CLCD::mem_write_8 (uint32_t reg_address, uint8_t data) { +void CLCD::mem_write_8(uint32_t reg_address, uint8_t data) { spi_ftdi_select(); spi_write_addr(reg_address); spi_write_8(data); @@ -194,16 +194,16 @@ void CLCD::mem_write_8 (uint32_t reg_address, uint8_t data) { } // Write 3-Byte Address, Write 2-Bytes Data -void CLCD::mem_write_16 (uint32_t reg_address, uint16_t data) { +void CLCD::mem_write_16(uint32_t reg_address, uint16_t data) { using namespace SPI::least_significant_byte_first; spi_ftdi_select(); spi_write_addr(reg_address); - spi_write_32(data); + spi_write_16(data); spi_ftdi_deselect(); } // Write 3-Byte Address, Write 4-Bytes Data -void CLCD::mem_write_32 (uint32_t reg_address, uint32_t data) { +void CLCD::mem_write_32(uint32_t reg_address, uint32_t data) { using namespace SPI::least_significant_byte_first; spi_ftdi_select(); spi_write_addr(reg_address); @@ -281,7 +281,7 @@ void CLCD::CommandFifo::text(int16_t x, int16_t y, int16_t font, uint16_t optio } // This sends the a toggle command to the command preprocessor, must be followed by str() -void CLCD::CommandFifo::toggle (int16_t x, int16_t y, int16_t w, int16_t font, uint16_t options, bool state) { +void CLCD::CommandFifo::toggle(int16_t x, int16_t y, int16_t w, int16_t font, uint16_t options, bool state) { struct { int32_t type = CMD_TOGGLE; int16_t x; @@ -303,7 +303,7 @@ void CLCD::CommandFifo::toggle (int16_t x, int16_t y, int16_t w, int16_t font, u } // This sends the a keys command to the command preprocessor, must be followed by str() -void CLCD::CommandFifo::keys (int16_t x, int16_t y, int16_t w, int16_t h, int16_t font, uint16_t options) { +void CLCD::CommandFifo::keys(int16_t x, int16_t y, int16_t w, int16_t h, int16_t font, uint16_t options) { struct { int32_t type = CMD_KEYS; int16_t x; @@ -324,7 +324,7 @@ void CLCD::CommandFifo::keys (int16_t x, int16_t y, int16_t w, int16_t h, int16_ cmd( &cmd_data, sizeof(cmd_data) ); } -void CLCD::CommandFifo::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 CLCD::CommandFifo::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) { struct { int32_t type = CMD_CLOCK; @@ -350,7 +350,7 @@ void CLCD::CommandFifo::clock (int16_t x, int16_t y, int16_t r, uint16_t options cmd( &cmd_data, sizeof(cmd_data) ); } -void CLCD::CommandFifo::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 CLCD::CommandFifo::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) { struct { int32_t type = CMD_GAUGE; @@ -376,7 +376,7 @@ void CLCD::CommandFifo::gauge (int16_t x, int16_t y, int16_t r, uint16_t options cmd( &cmd_data, sizeof(cmd_data) ); } -void CLCD::CommandFifo::dial (int16_t x, int16_t y, int16_t r, uint16_t options, uint16_t val) +void CLCD::CommandFifo::dial(int16_t x, int16_t y, int16_t r, uint16_t options, uint16_t val) { struct { int32_t type = CMD_DIAL; @@ -396,7 +396,7 @@ void CLCD::CommandFifo::dial (int16_t x, int16_t y, int16_t r, uint16_t options, cmd( &cmd_data, sizeof(cmd_data) ); } -void CLCD::CommandFifo::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 CLCD::CommandFifo::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) { struct { int32_t type = CMD_SCROLLBAR; int16_t x; @@ -421,7 +421,7 @@ void CLCD::CommandFifo::scrollbar (int16_t x, int16_t y, int16_t w, int16_t h, u cmd( &cmd_data, sizeof(cmd_data) ); } -void CLCD::CommandFifo::progress (int16_t x, int16_t y, int16_t w, int16_t h, uint16_t options, uint16_t val, uint16_t range) { +void CLCD::CommandFifo::progress(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t options, uint16_t val, uint16_t range) { struct { int32_t type = CMD_PROGRESS; int16_t x; @@ -444,7 +444,7 @@ void CLCD::CommandFifo::progress (int16_t x, int16_t y, int16_t w, int16_t h, ui cmd( &cmd_data, sizeof(cmd_data) ); } -void CLCD::CommandFifo::slider (int16_t x, int16_t y, int16_t w, int16_t h, uint16_t options, uint16_t val, uint16_t range) { +void CLCD::CommandFifo::slider(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t options, uint16_t val, uint16_t range) { struct { int32_t type = CMD_SLIDER; int16_t x; @@ -467,7 +467,7 @@ void CLCD::CommandFifo::slider (int16_t x, int16_t y, int16_t w, int16_t h, uint cmd( &cmd_data, sizeof(cmd_data) ); } -void CLCD::CommandFifo::gradient (int16_t x0, int16_t y0, uint32_t rgb0, int16_t x1, int16_t y1, uint32_t rgb1) { +void CLCD::CommandFifo::gradient(int16_t x0, int16_t y0, uint32_t rgb0, int16_t x1, int16_t y1, uint32_t rgb1) { struct { int32_t type = CMD_GRADIENT; int16_t x0; @@ -488,7 +488,7 @@ void CLCD::CommandFifo::gradient (int16_t x0, int16_t y0, uint32_t rgb0, int16_t cmd( &cmd_data, sizeof(cmd_data) ); } -void CLCD::CommandFifo::number (int16_t x, int16_t y, int16_t font, uint16_t options, int32_t n) { +void CLCD::CommandFifo::number(int16_t x, int16_t y, int16_t font, uint16_t options, int32_t n) { struct { int32_t type = CMD_NUMBER; int16_t x; @@ -507,7 +507,7 @@ void CLCD::CommandFifo::number (int16_t x, int16_t y, int16_t font, uint16_t opt cmd( &cmd_data, sizeof(cmd_data) ); } -void CLCD::CommandFifo::memzero (uint32_t ptr, uint32_t size) { +void CLCD::CommandFifo::memzero(uint32_t ptr, uint32_t size) { struct { uint32_t type = CMD_MEMZERO; uint32_t ptr; @@ -520,7 +520,7 @@ void CLCD::CommandFifo::memzero (uint32_t ptr, uint32_t size) { cmd( &cmd_data, sizeof(cmd_data) ); } -void CLCD::CommandFifo::memset (uint32_t ptr, uint32_t val, uint32_t size) { +void CLCD::CommandFifo::memset(uint32_t ptr, uint32_t val, uint32_t size) { struct { uint32_t type = CMD_MEMSET; uint32_t ptr; @@ -535,7 +535,7 @@ void CLCD::CommandFifo::memset (uint32_t ptr, uint32_t val, uint32_t size) { cmd( &cmd_data, sizeof(cmd_data) ); } -void CLCD::CommandFifo::memcpy (uint32_t dst, uint32_t src, uint32_t size) { +void CLCD::CommandFifo::memcpy(uint32_t dst, uint32_t src, uint32_t size) { struct { uint32_t type = CMD_MEMCPY; uint32_t dst; @@ -550,7 +550,7 @@ void CLCD::CommandFifo::memcpy (uint32_t dst, uint32_t src, uint32_t size) { cmd( &cmd_data, sizeof(cmd_data) ); } -void CLCD::CommandFifo::memcrc (uint32_t ptr, uint32_t num, uint32_t result) { +void CLCD::CommandFifo::memcrc(uint32_t ptr, uint32_t num, uint32_t result) { struct { uint32_t type = CMD_MEMCRC; uint32_t ptr; @@ -565,7 +565,7 @@ void CLCD::CommandFifo::memcrc (uint32_t ptr, uint32_t num, uint32_t result) { cmd( &cmd_data, sizeof(cmd_data) ); } -void CLCD::CommandFifo::memwrite (uint32_t ptr, uint32_t value) { +void CLCD::CommandFifo::memwrite(uint32_t ptr, uint32_t value) { struct { uint32_t type = CMD_MEMWRITE; uint32_t ptr; @@ -580,7 +580,7 @@ void CLCD::CommandFifo::memwrite (uint32_t ptr, uint32_t value) { cmd( &cmd_data, sizeof(cmd_data) ); } -void CLCD::CommandFifo::append (uint32_t ptr, uint32_t size) { +void CLCD::CommandFifo::append(uint32_t ptr, uint32_t size) { struct { uint32_t type = CMD_APPEND; uint32_t ptr; @@ -593,7 +593,7 @@ void CLCD::CommandFifo::append (uint32_t ptr, uint32_t size) { cmd( &cmd_data, sizeof(cmd_data) ); } -void CLCD::CommandFifo::inflate (uint32_t ptr) { +void CLCD::CommandFifo::inflate(uint32_t ptr) { struct { uint32_t type = CMD_INFLATE; uint32_t ptr; @@ -604,7 +604,7 @@ void CLCD::CommandFifo::inflate (uint32_t ptr) { cmd( &cmd_data, sizeof(cmd_data) ); } -void CLCD::CommandFifo::getptr (uint32_t result) { +void CLCD::CommandFifo::getptr(uint32_t result) { struct { uint32_t type = CMD_GETPTR; uint32_t result; @@ -696,7 +696,7 @@ void CLCD::CommandFifo::loadimage(uint32_t ptr, uint32_t options) { cmd( &cmd_data, sizeof(cmd_data) ); } -void CLCD::CommandFifo::getprops (uint32_t ptr, uint32_t width, uint32_t height) { +void CLCD::CommandFifo::getprops(uint32_t ptr, uint32_t width, uint32_t height) { struct { uint32_t type = CMD_GETPROPS; uint32_t ptr; @@ -735,7 +735,7 @@ void CLCD::CommandFifo::rotate(int32_t a) { cmd( &cmd_data, sizeof(cmd_data) ); } -void CLCD::CommandFifo::translate (int32_t tx, int32_t ty) { +void CLCD::CommandFifo::translate(int32_t tx, int32_t ty) { struct { uint32_t type = CMD_TRANSLATE; int32_t tx; @@ -749,7 +749,7 @@ void CLCD::CommandFifo::translate (int32_t tx, int32_t ty) { } #if FTDI_API_LEVEL >= 810 -void CLCD::CommandFifo::setbase (uint8_t base) { +void CLCD::CommandFifo::setbase(uint8_t base) { struct { int32_t type = CMD_SETBASE; uint32_t base; @@ -855,7 +855,7 @@ void CLCD::CommandFifo::playvideo(uint32_t options) { #endif #if FTDI_API_LEVEL >= 810 -void CLCD::CommandFifo::setrotate (uint8_t rotation) { +void CLCD::CommandFifo::setrotate(uint8_t rotation) { struct { uint32_t type = CMD_SETROTATE; uint32_t rotation; @@ -868,7 +868,7 @@ void CLCD::CommandFifo::setrotate (uint8_t rotation) { #endif #if FTDI_API_LEVEL >= 810 -void CLCD::CommandFifo::romfont (uint8_t font, uint8_t romslot) { +void CLCD::CommandFifo::romfont(uint8_t font, uint8_t romslot) { struct { uint32_t type = CMD_ROMFONT; uint32_t font; @@ -922,9 +922,8 @@ template bool CLCD::CommandFifo::_write_unaligned(T data, uint16_t len uint32_t command_read_ptr; #if ENABLED(TOUCH_UI_DEBUG) - if (command_write_ptr == 0xFFFFFFFFul) { - SERIAL_ECHO_MSG("Attempt to write to FIFO before CommandFifo::Cmd_Start()."); - } + if (command_write_ptr == 0xFFFFFFFFul) + SERIAL_ECHO_MSG("Attempt to write to FIFO before CommandFifo::Cmd_Start()."); #endif /* Wait until there is enough space in the circular buffer for the transfer */ @@ -933,7 +932,8 @@ template bool CLCD::CommandFifo::_write_unaligned(T data, uint16_t len if (command_read_ptr <= command_write_ptr) { bytes_tail = 4096U - command_write_ptr; bytes_head = command_read_ptr; - } else { + } + else { bytes_tail = command_read_ptr - command_write_ptr; bytes_head = 0; } @@ -1055,28 +1055,24 @@ void CLCD::init() { spi_init(); // Set Up I/O Lines for SPI and FT800/810 Control ftdi_reset(); // Power down/up the FT8xx with the apropriate delays - if (Use_Crystal == 1) { - host_cmd(CLKEXT, 0); - } - else { - host_cmd(CLKINT, 0); - } - + host_cmd(Use_Crystal ? CLKEXT : CLKINT, 0); host_cmd(FTDI::ACTIVE, 0); // Activate the System Clock - /* read the device-id until it returns 0x7c or times out, should take less than 150ms */ + delay(40); // FTDI/BRT recommendation: no SPI traffic during startup. EVE needs at the very least 45ms to start, so leave her alone for a little while. + + /* read the device-id until it returns 0x7C or times out, should take less than 150ms */ uint8_t counter; - for(counter = 0; counter < 250; counter++) { + for (counter = 0; counter < 250; counter++) { uint8_t device_id = mem_read_8(REG::ID); // Read Device ID, Should Be 0x7C; - if (device_id == 0x7c) { + if (device_id == 0x7C) { #if ENABLED(TOUCH_UI_DEBUG) SERIAL_ECHO_MSG("FTDI chip initialized "); #endif break; } - else { + else delay(1); - } + if (counter == 249) { #if ENABLED(TOUCH_UI_DEBUG) SERIAL_ECHO_START(); @@ -1085,6 +1081,24 @@ void CLCD::init() { } } + /* make sure that all units are in working conditions, usually the touch-controller needs a little more time */ + for (counter = 0; counter < 100; counter++) { + uint8_t reset_status = mem_read_8(REG::CPURESET) & 0x03; + if (reset_status == 0x00) { + #if ENABLED(TOUCH_UI_DEBUG) + SERIAL_ECHO_MSG("FTDI chip all units running "); + #endif + break; + } + else + delay(1); + + if (ENABLED(TOUCH_UI_DEBUG) && counter == 99) { + SERIAL_ECHO_START(); + SERIAL_ECHOLNPAIR("Timeout waiting for reset status. Should be 0x00, got ", reset_status); + } + } + mem_write_8(REG::PWM_DUTY, 0); // turn off Backlight, Frequency already is set to 250Hz default /* Configure the FT8xx Registers */ @@ -1131,14 +1145,11 @@ void CLCD::init() { mem_write_8(REG::PCLK, Pclk); // Turns on Clock by setting PCLK Register to the value necessary for the module - mem_write_16(REG::PWM_HZ, 0x00FA); + mem_write_16(REG::PWM_HZ, 0x00FA); // Turning off dithering seems to help prevent horizontal line artifacts on certain colors mem_write_8(REG::DITHER, 0); - // Initialize the command FIFO - CommandFifo::reset(); - default_touch_transform(); default_display_orientation(); } @@ -1158,26 +1169,13 @@ void CLCD::default_display_orientation() { #if FTDI_API_LEVEL >= 810 // Set the initial display orientation. On the FT810, we use the command // processor to do this since it will also update the transform matrices. - if (FTDI::ftdi_chip >= 810) { - CommandFifo cmd; - cmd.setrotate(0 - #if ENABLED(TOUCH_UI_MIRRORED) - + 4 - #endif - #if ENABLED(TOUCH_UI_PORTRAIT) - + 2 - #endif - #if ENABLED(TOUCH_UI_INVERTED) - + 1 - #endif - ); - cmd.execute(); - } - else { - #if ENABLED(TOUCH_UI_INVERTED) - mem_write_32(REG::ROTATE, 1); - #endif - } + CommandFifo cmd; + cmd.setrotate( + ENABLED(TOUCH_UI_MIRRORED) * 4 + + ENABLED(TOUCH_UI_PORTRAIT) * 2 + + ENABLED(TOUCH_UI_INVERTED) * 1 + ); + cmd.execute(); #elif ANY(TOUCH_UI_PORTRAIT, TOUCH_UI_MIRRORED) #error "PORTRAIT or MIRRORED orientation not supported on the FT800." #elif ENABLED(TOUCH_UI_INVERTED) diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.h similarity index 98% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.h index 0426911edb27..a9fdb5c5c73c 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.h @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ /**************************************************************************** @@ -133,6 +133,7 @@ class CLCD { static void set_brightness (uint8_t brightness); static uint8_t get_brightness(); static void host_cmd (unsigned char host_command, unsigned char byte2); + static uint32_t dl_size() {return CLCD::mem_read_32(REG::CMD_DL) & 0x1FFF;} static void get_font_metrics (uint8_t font, struct FontMetrics &fm); static uint16_t get_text_width(const uint8_t font, const char *str); diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/constants.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/constants.h similarity index 99% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/constants.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/constants.h index 5f60881bdd0e..1e6642fedc19 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/constants.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/constants.h @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ /**************************************************************************** diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/display_list.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/display_list.h similarity index 100% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/display_list.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/display_list.h diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/ftdi_basic.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/ftdi_basic.h similarity index 95% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/ftdi_basic.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/ftdi_basic.h index e8f9f424d0a0..75a2d54fca52 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/ftdi_basic.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/ftdi_basic.h @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/registers_ft800.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/registers_ft800.h similarity index 98% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/registers_ft800.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/registers_ft800.h index ff17d019d788..4063bf2d5dc7 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/registers_ft800.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/registers_ft800.h @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ /**************************************************************************** @@ -63,7 +63,7 @@ namespace FTDI { 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 + static constexpr uint32_t RAM_G_SIZE = 256*1024L; // 256k }; struct ft800_registers { diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/registers_ft810.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/registers_ft810.h similarity index 99% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/registers_ft810.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/registers_ft810.h index 3e4044e1947d..448717b47834 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/registers_ft810.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/registers_ft810.h @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ /**************************************************************************** @@ -61,7 +61,7 @@ namespace FTDI { 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 + static constexpr uint32_t RAM_G_SIZE = 1024*1024L; // 1024k }; struct ft810_registers { diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/resolutions.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/resolutions.h similarity index 93% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/resolutions.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/resolutions.h index 471530cadf83..8d455907e91a 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/resolutions.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/resolutions.h @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once @@ -32,7 +32,6 @@ * Selecting an LCD Display * Version 2.1 * Issue Date: 2017-11-14 - * */ #define COMPUTE_REGS_FROM_DATASHEET \ constexpr uint16_t Hoffset = thfp + thb - 1; \ @@ -61,12 +60,12 @@ 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_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; + constexpr uint32_t default_transform_e = 0xFFFFBE3B; + constexpr uint32_t default_transform_f = 0x00F68E75; } #elif defined(TOUCH_UI_480x272) diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/spi.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/spi.cpp similarity index 77% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/spi.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/spi.cpp index 7f666be45b56..d91d08fbfa05 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/spi.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/spi.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "ftdi_basic.h" @@ -27,8 +27,15 @@ /********************************* SPI Functions *********************************/ namespace FTDI { + #ifndef CLCD_USE_SOFT_SPI - SPISettings SPI::spi_settings(SPI_FREQUENCY, MSBFIRST, SPI_MODE0); + #ifdef CLCD_SPI_BUS + SPIClass EVE_SPI(CLCD_SPI_BUS); + #endif + #ifndef CLCD_HW_SPI_SPEED + #define CLCD_HW_SPI_SPEED 8000000 >> SPI_SPEED + #endif + SPISettings SPI::spi_settings(CLCD_HW_SPI_SPEED, MSBFIRST, SPI_MODE0); #endif void SPI::spi_init() { @@ -38,6 +45,11 @@ namespace FTDI { SET_OUTPUT(CLCD_SPI_CS); WRITE(CLCD_SPI_CS, 1); + #ifdef CLCD_SPI_EXTRA_CS + SET_OUTPUT(CLCD_SPI_EXTRA_CS); + WRITE(CLCD_SPI_EXTRA_CS, 1); + #endif + #ifdef SPI_FLASH_SS SET_OUTPUT(SPI_FLASH_SS); WRITE(SPI_FLASH_SS, 1); @@ -52,12 +64,12 @@ namespace FTDI { SET_INPUT_PULLUP(CLCD_SOFT_SPI_MISO); #else - ::SPI.begin(); + SPI_OBJ.begin(); #endif } #ifdef CLCD_USE_SOFT_SPI - uint8_t SPI::_soft_spi_xfer (uint8_t spiOutByte) { + uint8_t SPI::_soft_spi_xfer(uint8_t spiOutByte) { uint8_t spiIndex = 0x80; uint8_t spiInByte = 0; uint8_t k; @@ -66,8 +78,8 @@ namespace FTDI { for (k = 0; k < 8; k++) { // Output and Read each bit of spiOutByte and spiInByte WRITE(CLCD_SOFT_SPI_MOSI, (spiOutByte & spiIndex) ? 1 : 0); // Output MOSI Bit WRITE(CLCD_SOFT_SPI_SCLK, 1); // Pulse Clock + if (READ(CLCD_SOFT_SPI_MISO)) spiInByte |= spiIndex; // MISO changes on the falling edge of clock, so sample it before WRITE(CLCD_SOFT_SPI_SCLK, 0); - if (READ(CLCD_SOFT_SPI_MISO)) spiInByte |= spiIndex; spiIndex >>= 1; } interrupts(); @@ -76,7 +88,7 @@ namespace FTDI { #endif #ifdef CLCD_USE_SOFT_SPI - void SPI::_soft_spi_send (uint8_t spiOutByte) { + void SPI::_soft_spi_send(uint8_t spiOutByte) { uint8_t k, spiIndex = 0x80; noInterrupts(); @@ -90,16 +102,12 @@ namespace FTDI { } #endif - void SPI::spi_read_bulk (void *data, uint16_t len) { + void SPI::spi_read_bulk(void *data, uint16_t len) { uint8_t* p = (uint8_t *)data; - #ifndef CLCD_USE_SOFT_SPI - ::SPI.transfer(p, len); - #else - while (len--) *p++ = spi_recv(); - #endif + while (len--) *p++ = spi_recv(); } - bool SPI::spi_verify_bulk (const void *data, uint16_t len) { + 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; @@ -108,35 +116,41 @@ namespace FTDI { // CLCD SPI - Chip Select void SPI::spi_ftdi_select() { #ifndef CLCD_USE_SOFT_SPI - ::SPI.beginTransaction(spi_settings); + SPI_OBJ.beginTransaction(spi_settings); #endif WRITE(CLCD_SPI_CS, 0); + #ifdef CLCD_SPI_EXTRA_CS + WRITE(CLCD_SPI_EXTRA_CS, 0); + #endif delayMicroseconds(1); } // CLCD SPI - Chip Deselect void SPI::spi_ftdi_deselect() { WRITE(CLCD_SPI_CS, 1); + #ifdef CLCD_SPI_EXTRA_CS + WRITE(CLCD_SPI_EXTRA_CS, 1); + #endif #ifndef CLCD_USE_SOFT_SPI - ::SPI.endTransaction(); + SPI_OBJ.endTransaction(); #endif } #ifdef SPI_FLASH_SS // Serial SPI Flash SPI - Chip Select - void SPI::spi_flash_select () { + void SPI::spi_flash_select() { #ifndef CLCD_USE_SOFT_SPI - ::SPI.beginTransaction(spi_settings); + SPI_OBJ.beginTransaction(spi_settings); #endif WRITE(SPI_FLASH_SS, 0); delayMicroseconds(1); } // Serial SPI Flash SPI - Chip Deselect - void SPI::spi_flash_deselect () { + void SPI::spi_flash_deselect() { WRITE(SPI_FLASH_SS, 1); #ifndef CLCD_USE_SOFT_SPI - ::SPI.endTransaction(); + SPI_OBJ.endTransaction(); #endif } #endif diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/spi.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/spi.h similarity index 94% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/spi.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/spi.h index 38f0e35d5a3e..30ec786c60ae 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/spi.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/spi.h @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once @@ -27,6 +27,14 @@ #endif namespace FTDI { + + #if !defined(CLCD_SPI_BUS) || defined(CLCD_USE_SOFT_SPI) + #define SPI_OBJ ::SPI + #else + extern SPIClass EVE_SPI; + #define SPI_OBJ EVE_SPI + #endif + namespace SPI { #ifndef CLCD_USE_SOFT_SPI extern SPISettings spi_settings; @@ -47,7 +55,7 @@ namespace FTDI { #ifdef CLCD_USE_SOFT_SPI return _soft_spi_xfer(0x00); #else - return ::SPI.transfer(0x00); + return SPI_OBJ.transfer(0x00); #endif }; @@ -55,7 +63,7 @@ namespace FTDI { #ifdef CLCD_USE_SOFT_SPI _soft_spi_send(val); #else - ::SPI.transfer(val); + SPI_OBJ.transfer(val); #endif }; diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/compat.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/compat.h similarity index 65% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/compat.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/compat.h index ef2b23a3a2b0..436c67edf2eb 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/compat.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/compat.h @@ -12,7 +12,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once @@ -176,11 +176,12 @@ #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) + #define SET_INPUT(pin) fast_io::pin::set_input() + #define SET_INPUT_PULLUP(pin) do{ fast_io::pin::set_input(); fast_io::pin::set_high(); }while(0) + #define SET_INPUT_PULLDOWN SET_INPUT + #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 @@ -195,24 +196,68 @@ #endif #define SERIAL_ECHO_START() - #define SERIAL_ECHOLNPGM(str) Serial.println(F(str)) - #define SERIAL_ECHOPGM(str) Serial.print(F(str)) - #define SERIAL_ECHO_MSG(str) Serial.println(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 SERIAL_ECHOLNPGM(str) Serial.println(F(str)) + #define SERIAL_ECHOPGM(str) Serial.print(F(str)) + #define SERIAL_ECHO_MSG(str) Serial.println(str) + #define SERIAL_ECHOLNPAIR(str, val) do{ Serial.print(F(str)); Serial.println(val); }while(0) + #define SERIAL_ECHOPAIR(str, val) do{ Serial.print(F(str)); Serial.print(val); }while(0) #define safe_delay delay // Define macros for compatibility - #define _CAT(a, ...) a ## __VA_ARGS__ - #define SWITCH_ENABLED_ 1 - #define ENABLED(b) _CAT(SWITCH_ENABLED_, b) - #define DISABLED(b) !ENABLED(b) - #define ANY(A,B) (ENABLED(A) || ENABLED(B)) - #define EITHER(A,B) (ENABLED(A) || ENABLED(B)) - #define BOTH(A,B) (ENABLED(A) && ENABLED(B)) - #define NONE(A,B) (DISABLED(A) && DISABLED(B)) + #define _CAT(a,V...) a##V + #define CAT(a,V...) _CAT(a,V) + + #define FIRST(a,...) a + #define SECOND(a,b,...) b + #define THIRD(a,b,c,...) c + + #define IS_PROBE(V...) SECOND(V, 0) // Get the second item passed, or 0 + #define PROBE() ~, 1 // Second item will be 1 if this is passed + #define _NOT_0 PROBE() + #define NOT(x) IS_PROBE(_CAT(_NOT_, x)) // NOT('0') gets '1'. Anything else gets '0'. + #define _BOOL(x) NOT(NOT(x)) // NOT('0') gets '0'. Anything else gets '1'. + + #define _DO_1(W,C,A) (_##W##_1(A)) + #define _DO_2(W,C,A,B) (_##W##_1(A) C _##W##_1(B)) + #define _DO_3(W,C,A,V...) (_##W##_1(A) C _DO_2(W,C,V)) + #define _DO_4(W,C,A,V...) (_##W##_1(A) C _DO_3(W,C,V)) + #define _DO_5(W,C,A,V...) (_##W##_1(A) C _DO_4(W,C,V)) + #define _DO_6(W,C,A,V...) (_##W##_1(A) C _DO_5(W,C,V)) + #define _DO_7(W,C,A,V...) (_##W##_1(A) C _DO_6(W,C,V)) + #define _DO_8(W,C,A,V...) (_##W##_1(A) C _DO_7(W,C,V)) + #define _DO_9(W,C,A,V...) (_##W##_1(A) C _DO_8(W,C,V)) + #define _DO_10(W,C,A,V...) (_##W##_1(A) C _DO_9(W,C,V)) + #define _DO_11(W,C,A,V...) (_##W##_1(A) C _DO_10(W,C,V)) + #define _DO_12(W,C,A,V...) (_##W##_1(A) C _DO_11(W,C,V)) + #define __DO_N(W,C,N,V...) _DO_##N(W,C,V) + #define _DO_N(W,C,N,V...) __DO_N(W,C,N,V) + #define DO(W,C,V...) _DO_N(W,C,NUM_ARGS(V),V) + + #define _ISENA_ ~,1 + #define _ISENA_1 ~,1 + #define _ISENA_0x1 ~,1 + #define _ISENA_true ~,1 + #define _ISENA(V...) IS_PROBE(V) + #define _ENA_1(O) _ISENA(CAT(_IS,CAT(ENA_, O))) + #define _DIS_1(O) NOT(_ENA_1(O)) + #define ENABLED(V...) DO(ENA,&&,V) + #define DISABLED(V...) DO(DIS,&&,V) + + #define TERN(O,A,B) _TERN(_ENA_1(O),B,A) // OPTION converted to '0' or '1' + #define TERN0(O,A) _TERN(_ENA_1(O),0,A) // OPTION converted to A or '0' + #define TERN1(O,A) _TERN(_ENA_1(O),1,A) // OPTION converted to A or '1' + #define TERN_(O,A) _TERN(_ENA_1(O),,A) // OPTION converted to A or '' + #define _TERN(E,V...) __TERN(_CAT(T_,E),V) // Prepend 'T_' to get 'T_0' or 'T_1' + #define __TERN(T,V...) ___TERN(_CAT(_NO,T),V) // Prepend '_NO' to get '_NOT_0' or '_NOT_1' + #define ___TERN(P,V...) THIRD(P,V) // If first argument has a comma, A. Else B. + + #define ANY(V...) !DISABLED(V) + #define NONE(V...) DISABLED(V) + #define ALL(V...) ENABLED(V) + #define BOTH(V1,V2) ALL(V1,V2) + #define EITHER(V1,V2) ANY(V1,V2) // Remove compiler warning on an unused variable #ifndef UNUSED diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/bitmap_info.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/bitmap_info.h similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/bitmap_info.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/bitmap_info.h index 2a095c344553..b763c890c20b 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/bitmap_info.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/bitmap_info.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.cpp similarity index 94% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.cpp index 08d208202048..7224b681bba5 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.cpp @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "ftdi_extended.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.h similarity index 99% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.h index b045ca203abc..94ccbb7a605b 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once @@ -78,7 +78,8 @@ class CommandProcessor : public CLCD::CommandFifo { y += (h - th) / 2; w -= tracker ? th * 5.0 : th * 2; h = th; - } else { + } + else { x += (w - th) / 2; y += tracker ? th * 2.5 : th; w = th; @@ -254,7 +255,8 @@ class CommandProcessor : public CLCD::CommandFifo { if (is_tracking) { if (FTDI::EventLoop::is_touch_held()) { return CLCD::get_tracker(value); - } else { + } + else { CLCD::CommandFifo::track(0, 0, 0, 0, 0); CLCD::CommandFifo::execute(); is_tracking = false; @@ -313,13 +315,14 @@ class CommandProcessor : public CLCD::CommandFifo { #ifdef TOUCH_UI_USE_UTF8 const bool is_utf8 = has_utf8_chars(text); #endif - for (;font >= 26;) { + for (;font > 26;) { int16_t width, height; #ifdef TOUCH_UI_USE_UTF8 if (is_utf8) { width = get_utf8_text_width(text, font_size_t::from_romfont(font)); height = font_size_t::from_romfont(font).get_height(); - } else + } + else #endif { CLCD::FontMetrics fm(font); diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/dl_cache.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/dl_cache.cpp similarity index 69% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/dl_cache.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/dl_cache.cpp index 9a55c55ae62a..baed9f8502fe 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/dl_cache.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/dl_cache.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "ftdi_extended.h" @@ -32,7 +32,8 @@ * * The cache memory begins with a table at * DL_CACHE_START: each table entry contains - * an address and size for a cached DL slot. + * an address, size and used bytes for a cached + * DL slot. * * Immediately following the table is the * DL_FREE_ADDR, which points to free cache @@ -44,11 +45,14 @@ * * DL_CACHE_START slot0_addr 4 * slot0_size 4 + * slot0_used 4 * slot1_addr 4 * slot1_size 4 + * slot1_used 4 * ... * slotN_addr 4 * slotN_size 4 + * slotN_used 4 * DL_FREE_ADDR dl_free_ptr 4 * cached data * ... @@ -57,7 +61,7 @@ */ #define DL_CACHE_START MAP::RAM_G_SIZE - 0xFFFF -#define DL_FREE_ADDR DL_CACHE_START + DL_CACHE_SLOTS * 8 +#define DL_FREE_ADDR DL_CACHE_START + DL_CACHE_SLOTS * 12 using namespace FTDI; @@ -65,13 +69,12 @@ using namespace FTDI; 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); - } + for (uint8_t slot = 0; slot < DL_CACHE_SLOTS; slot++) + save_slot(slot, 0, 0, 0); } bool DLCache::has_data() { - return dl_size != 0; + return dl_slot_size != 0; } bool DLCache::wait_until_idle() { @@ -93,12 +96,12 @@ bool DLCache::wait_until_idle() { * that it can be appended later. The memory is * dynamically allocated following DL_FREE_ADDR. * - * If num_bytes is provided, then that many bytes + * If min_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*/) { +bool DLCache::store(uint32_t min_bytes /* = 0*/) { CLCD::CommandFifo cmd; // Execute any commands already in the FIFO @@ -107,67 +110,69 @@ bool DLCache::store(uint32_t num_bytes /* = 0*/) { 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; + const uint32_t dl_size = CLCD::dl_size(); - if (dl_addr == 0) { + if (dl_slot_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 ?: 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 ?: dl_size; - dl_alloc = 0; - dl_size = new_dl_size; + dl_slot_addr = CLCD::mem_read_32(DL_FREE_ADDR); + dl_slot_size = max(dl_size, min_bytes); + + const uint32_t free_space = MAP::RAM_G_SIZE - dl_slot_addr; + if (dl_slot_size <= free_space) { + CLCD::mem_write_32(DL_FREE_ADDR, dl_slot_addr + dl_slot_size); + } + else { + dl_slot_addr = 0; + dl_slot_size = 0; + dl_slot_used = 0; + } } - if (dl_size > free_space) { + if (dl_size > dl_slot_size) { // Not enough memory to cache the display list. #if ENABLED(TOUCH_UI_DEBUG) SERIAL_ECHO_START(); - SERIAL_ECHOPAIR ("Not enough space in GRAM to cache display list, free space: ", free_space); + SERIAL_ECHOPAIR ("Not enough space in GRAM to cache display list, free space: ", dl_slot_size); SERIAL_ECHOLNPAIR(" Required: ", dl_size); #endif + dl_slot_used = 0; + save_slot(); return false; - } else { + } + else { #if ENABLED(TOUCH_UI_DEBUG) SERIAL_ECHO_START(); - SERIAL_ECHOPAIR ("Saving DL to RAMG cache, bytes: ", dl_size); - SERIAL_ECHOLNPAIR(" Free space: ", free_space); + SERIAL_ECHOPAIR ("Saving DL to RAMG cache, bytes: ", dl_slot_used); + SERIAL_ECHOLNPAIR(" Free space: ", dl_slot_size); #endif - cmd.memcpy(dl_addr, MAP::RAM_DL, dl_size); + dl_slot_used = dl_size; + save_slot(); + cmd.memcpy(dl_slot_addr, MAP::RAM_DL, dl_slot_used); 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::save_slot(uint8_t indx, uint32_t addr, uint16_t size, uint16_t used) { + CLCD::mem_write_32(DL_CACHE_START + indx * 12 + 0, addr); + CLCD::mem_write_32(DL_CACHE_START + indx * 12 + 4, size); + CLCD::mem_write_32(DL_CACHE_START + indx * 12 + 8, used); } -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::load_slot(uint8_t indx, uint32_t &addr, uint16_t &size, uint16_t &used) { + addr = CLCD::mem_read_32(DL_CACHE_START + indx * 12 + 0); + size = CLCD::mem_read_32(DL_CACHE_START + indx * 12 + 4); + used = CLCD::mem_read_32(DL_CACHE_START + indx * 12 + 8); } void DLCache::append() { CLCD::CommandFifo cmd; - cmd.append(dl_addr, dl_size); + cmd.append(dl_slot_addr, dl_slot_used); #if ENABLED(TOUCH_UI_DEBUG) cmd.execute(); wait_until_idle(); SERIAL_ECHO_START(); - SERIAL_ECHOPAIR ("Appending to DL from RAMG cache, bytes: ", dl_size); + SERIAL_ECHOPAIR ("Appending to DL from RAMG cache, bytes: ", dl_slot_used); SERIAL_ECHOLNPAIR(" REG_CMD_DL: ", CLCD::mem_read_32(REG::CMD_DL)); #endif } diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/dl_cache.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/dl_cache.h similarity index 74% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/dl_cache.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/dl_cache.h index f025b6a18d27..da927aeae23a 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/dl_cache.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/dl_cache.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once @@ -33,10 +33,10 @@ * DLCache dlcache(UNIQUE_ID); * * if (dlcache.hasData()) { - * dlcache.append(); + * dlcache.append(); * } else { - * // Add stuff to the DL - * dlcache.store(); + * // Add stuff to the DL + * dlcache.store(); * } */ class DLCache { @@ -44,12 +44,16 @@ class DLCache { typedef FTDI::ftdi_registers REG; typedef FTDI::ftdi_memory_map MAP; - uint8_t dl_slot; - uint32_t dl_addr; - uint16_t dl_size; + uint8_t dl_slot_indx; + uint32_t dl_slot_addr; + uint16_t dl_slot_size; + uint16_t dl_slot_used; - void load_slot(); - static void save_slot(uint8_t dl_slot, uint32_t dl_addr, uint32_t dl_size); + void load_slot() {load_slot(dl_slot_indx, dl_slot_addr, dl_slot_size, dl_slot_used);} + void save_slot() {save_slot(dl_slot_indx, dl_slot_addr, dl_slot_size, dl_slot_used);} + + static void load_slot(uint8_t indx, uint32_t &addr, uint16_t &size, uint16_t &used); + static void save_slot(uint8_t indx, uint32_t addr, uint16_t size, uint16_t used); bool wait_until_idle(); @@ -57,12 +61,12 @@ class DLCache { static void init(); DLCache(uint8_t slot) { - dl_slot = slot; + dl_slot_indx = slot; load_slot(); } bool has_data(); - bool store(uint32_t num_bytes = 0); + bool store(uint32_t min_bytes = 0); void append(); }; diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/event_loop.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/event_loop.cpp similarity index 92% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/event_loop.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/event_loop.cpp index f0f693bfd887..3dd2b88b19f7 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/event_loop.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/event_loop.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "ftdi_extended.h" @@ -109,7 +109,6 @@ namespace FTDI { * - 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 @@ -140,15 +139,12 @@ namespace FTDI { 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 { + // 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 = (lastScreen != current_screen.getScreen()); + } + else { touch_timer.start(); } break; @@ -191,7 +187,7 @@ namespace FTDI { #if ENABLED(TOUCH_UI_DEBUG) SERIAL_ECHO_START(); - SERIAL_ECHOLNPAIR("Touch end: ", tag); + SERIAL_ECHOLNPAIR("Touch end: ", pressed_tag); #endif const uint8_t saved_pressed_tag = pressed_tag; diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/event_loop.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/event_loop.h similarity index 97% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/event_loop.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/event_loop.h index 7eeea9c8154a..d9bede92dfbc 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/event_loop.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/event_loop.h @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/ftdi_extended.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/ftdi_extended.h similarity index 94% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/ftdi_extended.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/ftdi_extended.h index 329bea46f19a..6e4d0668fe3e 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/ftdi_extended.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/ftdi_extended.h @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once @@ -47,4 +47,5 @@ #include "sound_list.h" #include "polygon.h" #include "text_box.h" + #include "text_ellipsis.h" #endif diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/grid_layout.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/grid_layout.h similarity index 95% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/grid_layout.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/grid_layout.h index ec8154b22f69..e3c3ebb39d5a 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/grid_layout.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/grid_layout.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once @@ -74,12 +74,12 @@ #define DRAW_LAYOUT_GRID \ { \ cmd.cmd(LINE_WIDTH(4)); \ - for(int i = 1; i <= GRID_COLS; i++) { \ + 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++) { \ + 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)); \ diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/polygon.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/polygon.h similarity index 97% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/polygon.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/polygon.h index 4560996da76d..7da621321141 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/polygon.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/polygon.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/rgb_t.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/rgb_t.h similarity index 97% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/rgb_t.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/rgb_t.h index fde505287340..2b18244e22fb 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/rgb_t.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/rgb_t.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/screen_types.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/screen_types.cpp similarity index 93% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/screen_types.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/screen_types.cpp index ec1c0d1cbb4d..57a9e3e89b0a 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/screen_types.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/screen_types.cpp @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "ftdi_extended.h" @@ -26,7 +26,7 @@ /********************** VIRTUAL DISPATCH DATA TYPE ******************************/ uint8_t ScreenRef::lookupScreen(onRedraw_func_t onRedraw_ptr) { - for(uint8_t type = 0; type < functionTableSize; type++) { + for (uint8_t type = 0; type < functionTableSize; type++) { if (GET_METHOD(type, onRedraw) == onRedraw_ptr) { return type; } @@ -50,9 +50,8 @@ void ScreenRef::setScreen(onRedraw_func_t onRedraw_ptr) { } void ScreenRef::initializeAll() { - for(uint8_t type = 0; type < functionTableSize; type++) { + for (uint8_t type = 0; type < functionTableSize; type++) GET_METHOD(type, onStartup)(); - } } /********************** SCREEN STACK ******************************/ diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/screen_types.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/screen_types.h similarity index 94% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/screen_types.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/screen_types.h index f1ec4fc47664..d1f84c8a6e86 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/screen_types.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/screen_types.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once @@ -144,8 +144,8 @@ class UIScreen { 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 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)) @@ -173,10 +173,21 @@ class UncachedScreen { template class CachedScreen { protected: + static void gfxError() { + using namespace FTDI; + CommandProcessor cmd; + cmd.cmd(CMD_DLSTART) + .cmd(CLEAR(true,true,true)) + .font(30) + .text(0, 0, display_width, display_height, F("GFX MEM FULL")); + } + static bool storeBackground() { DLCache dlcache(DL_SLOT); if (!dlcache.store(DL_SIZE)) { SERIAL_ECHO_MSG("CachedScreen::storeBackground() failed: not enough DL cache space"); + gfxError(); // Try to cache a shorter error message instead. + dlcache.store(DL_SIZE); return false; } return true; @@ -209,7 +220,8 @@ class CachedScreen { if (dlcache.has_data()) { dlcache.append(); - } else { + } + else { #ifdef TOUCH_UI_USE_UTF8 load_utf8_bitmaps(cmd); #endif diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_list.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_list.h similarity index 87% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_list.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_list.h index a53ed95159fa..fbdfe2fe998a 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_list.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_list.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once @@ -30,9 +30,9 @@ class SoundList { public: static const uint8_t n; static inline const char* name(uint8_t val) { - return (const char* ) pgm_read_ptr_near(&list[val].name); + return (const char* ) pgm_read_ptr_far(&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); + return (FTDI::SoundPlayer::sound_t*) pgm_read_ptr_far(&list[val].data); } }; diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_player.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_player.cpp similarity index 97% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_player.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_player.cpp index a6d84dde5fab..6a5b6e3cf879 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_player.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_player.cpp @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "ftdi_extended.h" @@ -98,7 +98,8 @@ namespace FTDI { if (ms == 0 && fx == SILENCE && nt == END_SONG) { sequence = 0; play(SILENCE, REST); - } else { + } + else { wait = ms; timer.start(); play(fx, nt); diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_player.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_player.h similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_player.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_player.h index e177ec57dfb9..e2650b10aeff 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_player.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_player.h @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.cpp similarity index 97% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.cpp index 75a445a926b0..3616f15ab620 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.cpp @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "ftdi_extended.h" @@ -34,7 +34,7 @@ namespace FTDI { const char *p = str; end = str; uint16_t lw = 0, result = 0; - for(;;) { + for (;;) { utf8_char_t c = get_utf8_char_and_inc(p); if (c == ' ' || c == '\n' || c == '\0') { if (lw < w || end == str) { @@ -60,7 +60,7 @@ namespace FTDI { const char *line_end; const uint16_t wrap_width = width; width = height = 0; - for(;;) { + 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); @@ -78,7 +78,7 @@ namespace FTDI { FontMetrics fm(font); // Shrink the font until we find a font that fits - for(;;) { + 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; @@ -91,7 +91,7 @@ namespace FTDI { const char *line_start = str; const char *line_end; - for(;;) { + for (;;) { find_line_break(fm, w, line_start, line_end); if (line_end == line_start) break; diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.h similarity index 95% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.h index a0f99c6b08f3..261995147cd4 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once diff --git a/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_ellipsis.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_ellipsis.cpp new file mode 100644 index 000000000000..b2f62f060ccc --- /dev/null +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_ellipsis.cpp @@ -0,0 +1,80 @@ +/********************* + * text_ellipsis.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: . * + ****************************************************************************/ + +#include "ftdi_extended.h" + +#ifdef FTDI_EXTENDED + +namespace FTDI { + + /** + * Helper function for drawing text with ellipses. The str buffer may be modified and should have space for up to two extra characters. + */ + static void _draw_text_with_ellipsis(CommandProcessor& cmd, int16_t x, int16_t y, int16_t w, int16_t h, char *str, uint16_t options, uint8_t font) { + FontMetrics fm(font); + const int16_t ellipsisWidth = fm.get_char_width('.') * 3; + + // Compute the total line length, as well as + // the location in the string where it can + // split and still allow the ellipsis to fit. + int16_t lineWidth = 0; + char *breakPoint = str; + for (char* c = str; *c; c++) { + lineWidth += fm.get_char_width(*c); + if (lineWidth + ellipsisWidth < w) + breakPoint = c; + } + + if (lineWidth > w) { + *breakPoint = '\0'; + strcpy_P(breakPoint,PSTR("...")); + } + + cmd.apply_text_alignment(x, y, w, h, options); + #ifdef TOUCH_UI_USE_UTF8 + if (has_utf8_chars(str)) { + draw_utf8_text(cmd, x, y, str, font_size_t::from_romfont(font), options); + } else + #endif + { + cmd.CLCD::CommandFifo::text(x, y, font, options); + cmd.CLCD::CommandFifo::str(str); + } + } + + /** + * These functions draws text inside a bounding box, truncating the text and + * adding ellipsis if the text does not fit. + */ + void draw_text_with_ellipsis(CommandProcessor& cmd, int x, int y, int w, int h, const char *str, uint16_t options, uint8_t font) { + char tmp[strlen(str) + 3]; + strcpy(tmp, str); + _draw_text_with_ellipsis(cmd, x, y, w, h, tmp, options, font); + } + + void draw_text_with_ellipsis(CommandProcessor& cmd, int x, int y, int w, int h, progmem_str pstr, uint16_t options, uint8_t font) { + char tmp[strlen_P((const char*)pstr) + 3]; + strcpy_P(tmp, (const char*)pstr); + _draw_text_with_ellipsis(cmd, x, y, w, h, tmp, options, font); + } +} // namespace FTDI + +#endif // FTDI_EXTENDED diff --git a/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_ellipsis.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_ellipsis.h new file mode 100644 index 000000000000..7852b7ec3e38 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_ellipsis.h @@ -0,0 +1,31 @@ +/******************* + * text_ellipsis.h * + *******************/ + +/**************************************************************************** + * Written By Marcio Teixeira 2020 - SynDaver Labs, 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: . * + ****************************************************************************/ + +#pragma once + +/** + * This function draws text inside a bounding box, truncating the text and + * showing ellipsis if it does not fit. + */ +namespace FTDI { + void draw_text_with_ellipsis(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_with_ellipsis(class CommandProcessor& cmd, int x, int y, int w, int h, const char *str, uint16_t options = 0, uint8_t font = 31); +} diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/tiny_timer.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/tiny_timer.cpp similarity index 95% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/tiny_timer.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/tiny_timer.cpp index c7b35e92dfef..58ec96ac15fb 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/tiny_timer.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/tiny_timer.cpp @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "ftdi_extended.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/tiny_timer.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/tiny_timer.h similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/tiny_timer.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/tiny_timer.h index 9db912752966..700da7bcf2f9 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/tiny_timer.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/tiny_timer.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/README.txt b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/README.txt similarity index 100% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/README.txt rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/README.txt diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps.cpp similarity index 95% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps.cpp index 87baeb6d2023..c5126721abb2 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps.cpp @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../ftdi_extended.h" @@ -45,7 +45,8 @@ namespace FTDI { cmd.cmd(BITMAP_HANDLE(handle)); cmd.cmd(CELL(cell)); cmd.cmd(VERTEX2F(x * 16, y * 16)); - } else { + } + else { cmd.cmd(VERTEX2II(x, y, handle, cell)); } } diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps.h similarity index 95% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps.h index 85ece6b774ab..f1e22e17ddf5 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/romfont_31.pbm b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/romfont_31.pbm similarity index 100% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/romfont_31.pbm rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/romfont_31.pbm diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/western_char_set_bitmap_31.png b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/western_char_set_bitmap_31.png similarity index 100% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/western_char_set_bitmap_31.png rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/western_char_set_bitmap_31.png diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/western_char_set_bitmap_31.svg b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/western_char_set_bitmap_31.svg similarity index 100% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/western_char_set_bitmap_31.svg rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/western_char_set_bitmap_31.svg diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_size_t.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_size_t.cpp similarity index 93% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_size_t.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_size_t.cpp index c449f11537c4..733cf8f6603a 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_size_t.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_size_t.cpp @@ -16,12 +16,12 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../ftdi_extended.h" -#if defined(FTDI_EXTENDED) && ENABLED(TOUCH_UI_USE_UTF8) +#if BOTH(FTDI_EXTENDED, TOUCH_UI_USE_UTF8) namespace FTDI { // Returns the height of a standard FTDI romfont diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_size_t.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_size_t.h similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_size_t.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_size_t.h index 9cf6c181f5af..f5bf644ef9e7 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_size_t.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_size_t.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/standard_char_set.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/standard_char_set.cpp similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/standard_char_set.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/standard_char_set.cpp index fb049aee3b45..b50c12fc6df1 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/standard_char_set.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/standard_char_set.cpp @@ -16,12 +16,12 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../ftdi_extended.h" -#if defined(FTDI_EXTENDED) && ENABLED(TOUCH_UI_USE_UTF8) +#if BOTH(FTDI_EXTENDED, TOUCH_UI_USE_UTF8) constexpr static uint8_t std_font = 31; diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/standard_char_set.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/standard_char_set.h similarity index 95% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/standard_char_set.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/standard_char_set.h index 17ccfe6e3018..7decdfd38f66 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/standard_char_set.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/standard_char_set.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ namespace FTDI { diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.cpp similarity index 97% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.cpp index d717f7f154e1..09473c1c263d 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.cpp @@ -16,12 +16,12 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../ftdi_extended.h" -#if defined(FTDI_EXTENDED) && ENABLED(TOUCH_UI_USE_UTF8) +#if BOTH(FTDI_EXTENDED, TOUCH_UI_USE_UTF8) using namespace FTDI; diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.h similarity index 98% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.h index fedb89d172e9..16f7e197b589 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once diff --git a/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set.cpp new file mode 100644 index 000000000000..4aa2580c633a --- /dev/null +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set.cpp @@ -0,0 +1,450 @@ +/************************ + * western_char_set.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: . * + ****************************************************************************/ + +#include "../ftdi_extended.h" + +#if ALL(FTDI_EXTENDED, TOUCH_UI_USE_UTF8, TOUCH_UI_UTF8_WESTERN_CHARSET) + + #include "western_char_set_bitmap_31.h" + + #define NUM_ELEMENTS(a) (sizeof(a)/sizeof(a[0])) + + using namespace FTDI; + + constexpr static uint8_t std_font = 31; + constexpr static uint8_t alt_font = 1; + + static uint32_t bitmap_addr; + + /* Glyphs in the WesternCharSet bitmap */ + + enum { + GRAVE, + ACUTE, + CIRCUMFLEX, + TILDE, + DIAERESIS, + DOT_ABOVE, + CEDILLA, + NO_DOT_I, + #if ENABLED(TOUCH_UI_UTF8_GERMANIC) + SHARP_S, + #endif + #if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN) + LRG_O_STROKE, + SML_O_STROKE, + LRG_AE, + SML_AE, + LRG_ETH, + SML_ETH, + LRG_THORN, + SML_THORN, + #endif + #if ENABLED(TOUCH_UI_UTF8_PUNCTUATION) + LEFT_DBL_QUOTE, + RIGHT_DBL_QUOTE, + INV_EXCLAMATION, + INV_QUESTION, + #endif + #if ENABLED(TOUCH_UI_UTF8_CURRENCY) + CENT_SIGN, + POUND_SIGN, + CURRENCY_SIGN, + YEN_SIGN, + #endif + #if ENABLED(TOUCH_UI_UTF8_SUPERSCRIPTS) + SUPERSCRIPT_ONE, + SUPERSCRIPT_TWO, + SUPERSCRIPT_THREE, + #endif + #if ENABLED(TOUCH_UI_UTF8_ORDINALS) + MASCULINE_ORDINAL, + FEMININE_ORDINAL, + #endif + #if ENABLED(TOUCH_UI_UTF8_COPYRIGHT) + COPYRIGHT_SIGN, + REGISTERED_SIGN, + #endif + #if ENABLED(TOUCH_UI_UTF8_MATHEMATICS) + PLUS_MINUS_SIGN, + MULTIPLICATION_SIGN, + DIVISION_SIGN, + #endif + #if ENABLED(TOUCH_UI_UTF8_FRACTIONS) + FRACTION_QUARTER, + FRACTION_HALF, + FRACTION_THREE_FOURTHS, + #endif + #if ENABLED(TOUCH_UI_UTF8_SYMBOLS) + MICRON_SIGN, + PILCROW_SIGN, + BROKEN_BAR, + SECTION_SIGN, + NOT_SIGN + #endif + }; + + /* Centerline of characters that can take accents */ + + constexpr int8_t mid_a = 12, + mid_e = 12, + mid_i = 5, + mid_o = 12, + mid_u = 12, + mid_y = 11, + mid_n = 12, + mid_c = 12, + mid_A = 13, + mid_E = 13, + mid_I = 6, + mid_O = 14, + mid_U = 14, + mid_Y = 13, + mid_N = 15, + mid_C = 13; + + /* Centerline of accent glyphs */ + + constexpr int8_t mid_accent = 16; + + /* When reusing the DOT_ABOVE accent glyph for the degree sign, we need to trim the leading space */ + constexpr uint8_t deg_sign_leading = 9; + + /* Look-up table for constructing characters (must be ordered by unicode) + * + * Characters are either complete symbols from the Western Char Set bitmap, + * or they are constructed using a standard letter from the romfont and + * drawing an accent from the Western Char Set bitmap over it. + */ + + #define UTF8(A) uint16_t(utf8(U##A)) + + PROGMEM constexpr struct { + uint16_t unicode; + uint8_t std_char; // Glyph from standard ROMFONT (zero if none) + uint8_t alt_char; // Glyph from Western Char Set bitmap + uint8_t alt_data; // For accented characters, the centerline; else char width + } char_recipe[] = { + {0, 0, NO_DOT_I, 10 }, + #if ENABLED(TOUCH_UI_UTF8_PUNCTUATION) + {UTF8('¡'), 0 , INV_EXCLAMATION, 13 }, + #endif + #if ENABLED(TOUCH_UI_UTF8_CURRENCY) + {UTF8('¢'), 0 , CENT_SIGN, 23 }, + {UTF8('£'), 0 , POUND_SIGN, 24 }, + {UTF8('¤'), 0 , CURRENCY_SIGN, 26 }, + {UTF8('¥'), 0 , YEN_SIGN, 26 }, + #endif + #if ENABLED(TOUCH_UI_UTF8_SYMBOLS) + {UTF8('¦'), 0 , BROKEN_BAR, 11 }, + {UTF8('§'), 0 , SECTION_SIGN, 21 }, + #endif + #if ENABLED(TOUCH_UI_UTF8_COPYRIGHT) + {UTF8('©'), 0 , COPYRIGHT_SIGN, 38 }, + #endif + #if ENABLED(TOUCH_UI_UTF8_ORDINALS) + {UTF8('ª'), 0 , FEMININE_ORDINAL, 19 }, + #endif + #if ENABLED(TOUCH_UI_UTF8_PUNCTUATION) + {UTF8('«'), 0 , LEFT_DBL_QUOTE, 23 }, + #endif + #if ENABLED(TOUCH_UI_UTF8_SYMBOLS) + {UTF8('¬'), 0 , NOT_SIGN, 32 }, + #endif + #if ENABLED(TOUCH_UI_UTF8_COPYRIGHT) + {UTF8('®'), 0 , REGISTERED_SIGN, 38 }, + #endif + {UTF8('°'), 0 , DOT_ABOVE, 24 }, + #if ENABLED(TOUCH_UI_UTF8_MATHEMATICS) + {UTF8('±'), 0 , NOT_SIGN, 32 }, + #endif + #if ENABLED(TOUCH_UI_UTF8_SUPERSCRIPTS) + {UTF8('²'), 0 , SUPERSCRIPT_TWO, 16 }, + {UTF8('³'), 0 , SUPERSCRIPT_THREE, 16 }, + #endif + #if ENABLED(TOUCH_UI_UTF8_SYMBOLS) + {UTF8('µ'), 0 , MICRON_SIGN, 28 }, + {UTF8('¶'), 0 , PILCROW_SIGN, 24 }, + #endif + #if ENABLED(TOUCH_UI_UTF8_SUPERSCRIPTS) + {UTF8('¹'), 0 , SUPERSCRIPT_ONE, 16 }, + #endif + #if ENABLED(TOUCH_UI_UTF8_ORDINALS) + {UTF8('º'), 0 , MASCULINE_ORDINAL, 19 }, + #endif + #if ENABLED(TOUCH_UI_UTF8_PUNCTUATION) + {UTF8('»'), 0 , RIGHT_DBL_QUOTE, 24 }, + #endif + #if ENABLED(TOUCH_UI_UTF8_FRACTIONS) + {UTF8('¼'), 0 , FRACTION_QUARTER, 40 }, + {UTF8('½'), 0 , FRACTION_HALF, 40 }, + {UTF8('¾'), 0 , FRACTION_THREE_FOURTHS, 40 }, + #endif + #if ENABLED(TOUCH_UI_UTF8_PUNCTUATION) + {UTF8('¿'), 0 , INV_QUESTION, 21 }, + #endif + {UTF8('À'), 'A', GRAVE, mid_A}, + {UTF8('Á'), 'A', ACUTE, mid_A}, + {UTF8('Â'), 'A', CIRCUMFLEX, mid_A}, + {UTF8('Ã'), 'A', TILDE, mid_A}, + {UTF8('Ä'), 'A', DIAERESIS, mid_A}, + {UTF8('Å'), 'A', DOT_ABOVE, mid_A}, + #if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN) + {UTF8('Æ'), 0 , LRG_AE, 40}, + #endif + {UTF8('Ç'), 'C', CEDILLA, mid_C}, + {UTF8('È'), 'E', GRAVE, mid_E}, + {UTF8('É'), 'E', ACUTE, mid_E}, + {UTF8('Ê'), 'E', CIRCUMFLEX, mid_E}, + {UTF8('Ë'), 'E', DIAERESIS, mid_E}, + {UTF8('Ì'), 'I', GRAVE, mid_I}, + {UTF8('Í'), 'I', ACUTE, mid_I}, + {UTF8('Î'), 'I', CIRCUMFLEX, mid_I}, + {UTF8('Ï'), 'I', DIAERESIS, mid_I}, + #if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN) + {UTF8('Ð'), 0, LRG_ETH, 31 }, + #endif + {UTF8('Ñ'), 'N', TILDE, mid_N}, + {UTF8('Ò'), 'O', GRAVE, mid_O}, + {UTF8('Ó'), 'O', ACUTE, mid_O}, + {UTF8('Ô'), 'O', CIRCUMFLEX, mid_O}, + {UTF8('Õ'), 'O', TILDE, mid_O}, + {UTF8('Ö'), 'O', DIAERESIS, mid_O}, + #if ENABLED(TOUCH_UI_UTF8_MATHEMATICS) + {UTF8('×'), 0 , MULTIPLICATION_SIGN, 32 }, + #endif + #if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN) + {UTF8('Ø'), 0 , LRG_O_STROKE, 32 }, + #endif + {UTF8('Ù'), 'U', GRAVE, mid_U}, + {UTF8('Ú'), 'U', ACUTE, mid_U}, + {UTF8('Û'), 'U', CIRCUMFLEX, mid_U}, + {UTF8('Ü'), 'U', DIAERESIS, mid_U}, + {UTF8('Ý'), 'Y', ACUTE, mid_Y}, + #if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN) + {UTF8('Þ'), 0 , LRG_THORN, 25 }, + #endif + #if ENABLED(TOUCH_UI_UTF8_GERMANIC) + {UTF8('ß'), 0 , SHARP_S, 26 }, + #endif + {UTF8('à'), 'a', GRAVE, mid_a}, + {UTF8('á'), 'a', ACUTE, mid_a}, + {UTF8('â'), 'a', CIRCUMFLEX, mid_a}, + {UTF8('ã'), 'a', TILDE, mid_a}, + {UTF8('ä'), 'a', DIAERESIS, mid_a}, + {UTF8('å'), 'a', DOT_ABOVE, mid_a}, + #if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN) + {UTF8('æ'), 0 , SML_AE, 40 }, + #endif + {UTF8('ç'), 'c', CEDILLA, mid_c}, + {UTF8('è'), 'e', GRAVE, mid_e}, + {UTF8('é'), 'e', ACUTE, mid_e}, + {UTF8('ê'), 'e', CIRCUMFLEX, mid_e}, + {UTF8('ë'), 'e', DIAERESIS, mid_e}, + {UTF8('ì'), 'i', GRAVE, mid_i}, + {UTF8('í'), 'i', ACUTE, mid_i}, + {UTF8('î'), 'i', CIRCUMFLEX, mid_i}, + {UTF8('ï'), 'i', DIAERESIS, mid_i}, + #if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN) + {UTF8('ð'), 0, SML_ETH, 24 }, + #endif + {UTF8('ñ'), 'n', TILDE, mid_n}, + {UTF8('ò'), 'o', GRAVE, mid_o}, + {UTF8('ó'), 'o', ACUTE, mid_o}, + {UTF8('ô'), 'o', CIRCUMFLEX, mid_o}, + {UTF8('õ'), 'o', TILDE, mid_o}, + {UTF8('ö'), 'o', DIAERESIS, mid_o}, + #if ENABLED(TOUCH_UI_UTF8_MATHEMATICS) + {UTF8('÷'), 0 , DIVISION_SIGN, 32 }, + #endif + #if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN) + {UTF8('ø'), 0 , SML_O_STROKE, 25 }, + #endif + {UTF8('ù'), 'u', GRAVE, mid_u}, + {UTF8('ú'), 'u', ACUTE, mid_u}, + {UTF8('û'), 'u', CIRCUMFLEX, mid_u}, + {UTF8('ü'), 'u', DIAERESIS, mid_u}, + {UTF8('ý'), 'y', ACUTE, mid_y}, + #if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN) + {UTF8('þ'), 0 , SML_THORN, 25 }, + #endif + {UTF8('ÿ'), 'y', DIAERESIS, mid_y} + }; + + static_assert(UTF8('¡') == 0xC2A1, "Incorrect encoding for character"); + + /* Compile-time check that the table is in sorted order */ + + constexpr bool is_sorted(size_t n) { + return n < 2 ? true : char_recipe[n-2].unicode < char_recipe[n-1].unicode && is_sorted(n-1); + } + + static_assert(is_sorted(NUM_ELEMENTS(char_recipe)), "The table must be sorted by unicode value"); + + /* Performs a binary search to find a unicode character in the table */ + + static int8_t find_char_data(FTDI::utf8_char_t c) { + int8_t min = 0, max = NUM_ELEMENTS(char_recipe), index; + for (;;) { + index = (min + max)/2; + const uint16_t char_at = pgm_read_word(&char_recipe[index].unicode); + if (char_at == c) break; + if (min == max) return -1; + if (c > char_at) + min = index + 1; + else + max = index; + } + return index; + } + + static void get_char_data(uint8_t index, uint8_t &std_char, uint8_t &alt_char, uint8_t &alt_data) { + std_char = pgm_read_byte(&char_recipe[index].std_char); + alt_char = pgm_read_byte(&char_recipe[index].alt_char); + alt_data = pgm_read_byte(&char_recipe[index].alt_data); + } + + /** + * Load bitmap data into RAMG. This function is called once at the start + * of the program. + * + * Parameters: + * + * addr - Address in RAMG where the font data is written + */ + + void FTDI::WesternCharSet::load_data(uint32_t addr) { + // Load the alternative font metrics + CLCD::FontMetrics alt_fm; + alt_fm.ptr = addr + 148; + alt_fm.format = L4; + alt_fm.stride = 19; + alt_fm.width = 38; + alt_fm.height = 49; + LOOP_L_N(i, 127) + alt_fm.char_widths[i] = 0; + + // For special characters, copy the character widths from the char tables + LOOP_L_N(i, NUM_ELEMENTS(char_recipe)) { + uint8_t std_char, alt_char, alt_data; + get_char_data(i, std_char, alt_char, alt_data); + if (std_char == 0) + alt_fm.char_widths[alt_char] = alt_data; + } + CLCD::mem_write_bulk(addr, &alt_fm, 148); + + // Decode the RLE data and load it into RAMG as a bitmap + write_rle_data(addr + 148, font, sizeof(font)); + + bitmap_addr = addr; + } + + /** + * Populates the bitmap handles for the custom into the display list. + * This function is called once at the start of each display list. + * + * Parameters: + * + * cmd - Object used for writing to the FTDI chip command queue. + */ + + void FTDI::WesternCharSet::load_bitmaps(CommandProcessor& cmd) { + CLCD::FontMetrics alt_fm; + alt_fm.ptr = bitmap_addr + 148; + alt_fm.format = L4; + alt_fm.stride = 19; + alt_fm.width = 38; + alt_fm.height = 49; + set_font_bitmap(cmd, alt_fm, alt_font); + } + + /** + * Renders a character at location x and y. The x position is incremented + * by the width of the character. + * + * Parameters: + * + * cmd - If non-NULL the symbol is drawn to the screen. + * If NULL, only increment position for text measurement. + * + * x, y - The location at which to draw the character. On output, + * incremented to the location of the next character. + * + * fs - A scaling object used to scale the font. The display will + * already be configured to scale bitmaps, but positions + * must be scaled using fs.scale() + * + * c - The unicode code point to draw. If the renderer does not + * support the character, it should return false. + + * Returns: Whether the character was supported. + */ + + bool FTDI::WesternCharSet::render_glyph(CommandProcessor* cmd, int &x, int &y, font_size_t fs, utf8_char_t c) { + + // A supported character? + if (c < UTF8('¡') || c > UTF8('ÿ')) return false; + + int8_t index = find_char_data(c); + if (index == -1) return false; + + // Determine character characteristics + uint8_t std_char, alt_char, alt_data; + get_char_data(index, std_char, alt_char, alt_data); + + bool base_special; + uint8_t base_width; + uint8_t base_char; + uint8_t accent_char; + int8_t accent_dx, accent_dy; + + if (std_char == 0) { + // Special character, non-accented + base_width = alt_data; + base_special = true; + base_char = alt_char; + accent_char = 0; + if (c == UTF8('°')) + x -= fs.scale(deg_sign_leading); + } + else { + // Regular character with accent: + accent_dx = alt_data - mid_accent; + accent_dy = isupper(std_char) ? -7 : 0; + accent_char = alt_char; + base_width = StandardCharSet::std_char_width(std_char); + base_special = std_char == 'i'; + base_char = base_special ? NO_DOT_I : std_char; + } + + // If cmd != NULL, draw the glyph to the screen + if (cmd) { + ext_vertex2ii(*cmd, x, y, base_special ? alt_font : std_font, base_char); + if (accent_char) + ext_vertex2ii(*cmd, x + fs.scale(accent_dx), y + fs.scale(accent_dy), alt_font, accent_char); + } + + // Increment X to the next character position + x += fs.scale(base_width); + return true; + } + +#endif // FTDI_EXTENDED && TOUCH_UI_USE_UTF8 && TOUCH_UI_UTF8_WESTERN_CHARSET diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set.h similarity index 94% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set.h index 704de9508878..2adad2327afa 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ namespace FTDI { diff --git a/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set_bitmap_31.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set_bitmap_31.h new file mode 100644 index 000000000000..3426e1377dbf --- /dev/null +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set_bitmap_31.h @@ -0,0 +1,1315 @@ +/******************************** + * western_european_bitmap_31.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: . * + ****************************************************************************/ + +#pragma once + +/* This is a dump of "font_bitmaps/western_european_bitmap_31.png" + * using the tool "bitmap2cpp.py". The tool converts the image into + * 16-level grayscale and packs two pixels per byte. The resulting + * bytes are then RLE compressed to yield (count, byte) pairs. + */ + +const unsigned char font[] PROGMEM = { + + /* 0 GRAVE */ + 0x76, 0x00, 0x01, 0x08, 0x01, 0xEE, 0x01, 0xE5, 0x11, 0x00, 0x01, 0xAF, + 0x01, 0xFF, 0x01, 0x20, 0x10, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xD0, + 0x10, 0x00, 0x01, 0x01, 0x01, 0xDF, 0x01, 0xF9, 0x11, 0x00, 0x01, 0x2E, + 0x01, 0xFF, 0x01, 0x50, 0x10, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF2, + 0x11, 0x00, 0x01, 0x5F, 0x01, 0xFD, 0x11, 0x00, 0x01, 0x06, 0x01, 0x99, + 0x01, 0x40, 0xFF, 0x00, 0xFF, 0x00, 0xA4, 0x00, + + /* 1 ACUTE */ + 0x7B, 0x00, 0x01, 0x9E, 0x01, 0xEE, 0x01, 0x50, 0x0F, 0x00, 0x01, 0x05, + 0x01, 0xFF, 0x01, 0xF8, 0x10, 0x00, 0x01, 0x2F, 0x01, 0xFF, 0x01, 0xA0, + 0x10, 0x00, 0x01, 0xCF, 0x01, 0xFC, 0x10, 0x00, 0x01, 0x09, 0x01, 0xFF, + 0x01, 0xD1, 0x10, 0x00, 0x01, 0x4F, 0x01, 0xFE, 0x01, 0x20, 0x0F, 0x00, + 0x01, 0x01, 0x01, 0xEF, 0x01, 0xF3, 0x10, 0x00, 0x01, 0x07, 0x01, 0xAA, + 0x01, 0x40, 0xFF, 0x00, 0xFF, 0x00, 0xA5, 0x00, + + /* 2 CIRCUMFLEX */ + 0x79, 0x00, 0x01, 0xCF, 0x01, 0xFC, 0x10, 0x00, 0x01, 0x07, 0x02, 0xFF, + 0x01, 0x60, 0x0F, 0x00, 0x01, 0x2F, 0x02, 0xFF, 0x01, 0xF2, 0x0F, 0x00, + 0x01, 0xCF, 0x01, 0xF6, 0x01, 0x6F, 0x01, 0xFB, 0x0E, 0x00, 0x01, 0x06, + 0x01, 0xFF, 0x01, 0xA0, 0x01, 0x0A, 0x01, 0xFF, 0x01, 0x60, 0x0D, 0x00, + 0x01, 0x1F, 0x01, 0xFD, 0x01, 0x00, 0x01, 0x01, 0x01, 0xDF, 0x01, 0xF1, + 0x0D, 0x00, 0x01, 0xBF, 0x01, 0xF3, 0x02, 0x00, 0x01, 0x3F, 0x01, 0xFB, + 0x0C, 0x00, 0x01, 0x02, 0x01, 0x99, 0x01, 0x50, 0x02, 0x00, 0x01, 0x05, + 0x01, 0x99, 0x01, 0x20, 0xFF, 0x00, 0xFF, 0x00, 0xA2, 0x00, + + /* 3 TILDE */ + 0x7C, 0x00, 0x01, 0x11, 0x0D, 0x00, 0x01, 0x09, 0x01, 0xFF, 0x01, 0xC3, + 0x02, 0x00, 0x01, 0xFF, 0x01, 0x80, 0x0C, 0x00, 0x01, 0xAF, 0x02, 0xFF, + 0x01, 0x50, 0x01, 0x01, 0x01, 0xFF, 0x01, 0x60, 0x0B, 0x00, 0x01, 0x02, + 0x01, 0xFF, 0x01, 0xD9, 0x01, 0xFF, 0x01, 0xF7, 0x01, 0x07, 0x01, 0xFF, + 0x01, 0x40, 0x0B, 0x00, 0x01, 0x07, 0x01, 0xFF, 0x01, 0x20, 0x01, 0x3E, + 0x02, 0xFF, 0x01, 0xFD, 0x0C, 0x00, 0x01, 0x09, 0x01, 0xFE, 0x01, 0x00, + 0x01, 0x02, 0x01, 0xDF, 0x01, 0xFF, 0x01, 0xF4, 0x0C, 0x00, 0x01, 0x07, + 0x01, 0xA8, 0x02, 0x00, 0x01, 0x06, 0x01, 0x98, 0x01, 0x20, 0xFF, 0x00, + 0xFF, 0x00, 0xB6, 0x00, + + /* 4 DIAERESIS */ + 0x8A, 0x00, 0x02, 0x44, 0x02, 0x00, 0x02, 0x44, 0x0D, 0x00, 0x02, 0xFF, + 0x01, 0x10, 0x01, 0x01, 0x02, 0xFF, 0x0D, 0x00, 0x02, 0xFF, 0x01, 0x10, + 0x01, 0x01, 0x02, 0xFF, 0x0D, 0x00, 0x02, 0xFF, 0x01, 0x10, 0x01, 0x01, + 0x02, 0xFF, 0x0D, 0x00, 0x02, 0xCC, 0x01, 0x10, 0x01, 0x01, 0x02, 0xCC, + 0xFF, 0x00, 0xFF, 0x00, 0xC9, 0x00, + + /* 5 DOT_ABOVE / DEGREE_SIGN */ + 0x2D, 0x00, 0x01, 0x13, 0x01, 0x30, 0x10, 0x00, 0x01, 0x2B, 0x02, 0xFF, + 0x01, 0xA1, 0x0E, 0x00, 0x01, 0x02, 0x01, 0xEF, 0x02, 0xFF, 0x01, 0xFD, + 0x01, 0x10, 0x0D, 0x00, 0x01, 0x0D, 0x01, 0xFF, 0x01, 0x94, 0x01, 0x5A, + 0x01, 0xFF, 0x01, 0xB0, 0x0D, 0x00, 0x01, 0x4F, 0x01, 0xF7, 0x02, 0x00, + 0x01, 0x9F, 0x01, 0xF2, 0x0D, 0x00, 0x01, 0x8F, 0x01, 0xF0, 0x02, 0x00, + 0x01, 0x2F, 0x01, 0xF6, 0x0D, 0x00, 0x01, 0x8F, 0x01, 0xE0, 0x02, 0x00, + 0x01, 0x0F, 0x01, 0xF7, 0x0D, 0x00, 0x01, 0x7F, 0x01, 0xF2, 0x02, 0x00, + 0x01, 0x4F, 0x01, 0xF5, 0x0D, 0x00, 0x01, 0x2F, 0x01, 0xFC, 0x01, 0x10, + 0x01, 0x02, 0x01, 0xDF, 0x01, 0xF0, 0x0D, 0x00, 0x01, 0x08, 0x01, 0xFF, + 0x01, 0xFB, 0x01, 0xCF, 0x01, 0xFF, 0x01, 0x60, 0x0E, 0x00, 0x01, 0x9F, + 0x02, 0xFF, 0x01, 0xF8, 0x0F, 0x00, 0x01, 0x03, 0x01, 0x9C, 0x01, 0xC9, + 0x01, 0x30, 0xFF, 0x00, 0xFF, 0x00, 0xA4, 0x00, + + /* 6 CEDILLA */ + 0xFF, 0x00, 0xFF, 0x00, 0xEE, 0x00, 0x01, 0x06, 0x01, 0xFF, 0x01, 0x20, + 0x11, 0x00, 0x01, 0xCF, 0x01, 0xC0, 0x11, 0x00, 0x01, 0x3F, 0x01, 0xF6, + 0x11, 0x00, 0x01, 0x0F, 0x01, 0xFB, 0x11, 0x00, 0x01, 0x3F, 0x01, 0xFD, + 0x0E, 0x00, 0x01, 0x07, 0x01, 0xD9, 0x01, 0x89, 0x01, 0xFF, 0x01, 0xFB, + 0x0E, 0x00, 0x01, 0x07, 0x03, 0xFF, 0x01, 0xF3, 0x0E, 0x00, 0x01, 0x04, + 0x01, 0xBD, 0x01, 0xEE, 0x01, 0xD9, 0x01, 0x20, 0x2F, 0x00, + + /* 7 NO_DOT_I */ + 0xFF, 0x00, 0x32, 0x00, 0x01, 0x01, 0x01, 0x99, 0x01, 0x96, 0x10, 0x00, + 0x01, 0x01, 0x01, 0xFF, 0x01, 0xF9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xFF, + 0x01, 0xF9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xFF, 0x01, 0xF9, 0x10, 0x00, + 0x01, 0x01, 0x01, 0xFF, 0x01, 0xF9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xFF, + 0x01, 0xF9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xFF, 0x01, 0xF9, 0x10, 0x00, + 0x01, 0x01, 0x01, 0xFF, 0x01, 0xF9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xFF, + 0x01, 0xF9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xFF, 0x01, 0xF9, 0x10, 0x00, + 0x01, 0x01, 0x01, 0xFF, 0x01, 0xF9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xFF, + 0x01, 0xF9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xFF, 0x01, 0xF9, 0x10, 0x00, + 0x01, 0x01, 0x01, 0xFF, 0x01, 0xF9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xFF, + 0x01, 0xF9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xFF, 0x01, 0xF9, 0x10, 0x00, + 0x01, 0x01, 0x01, 0xFF, 0x01, 0xF9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xFF, + 0x01, 0xF9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xFF, 0x01, 0xF9, 0x10, 0x00, + 0x01, 0x01, 0x01, 0xFF, 0x01, 0xF9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xFF, + 0x01, 0xF9, 0x10, 0x00, 0x01, 0x01, 0x01, 0xFF, 0x01, 0xF9, 0x10, 0x00, + 0x01, 0x01, 0x01, 0xFF, 0x01, 0xF9, 0xCD, 0x00, + +#if ENABLED(TOUCH_UI_UTF8_GERMANIC) + /* 8 SHARP_S */ + 0x8A, 0x00, 0x01, 0x35, 0x01, 0x66, 0x01, 0x52, 0x0E, 0x00, 0x01, 0x03, + 0x01, 0xAF, 0x03, 0xFF, 0x01, 0xE7, 0x0D, 0x00, 0x01, 0x7F, 0x05, 0xFF, + 0x01, 0xC1, 0x0B, 0x00, 0x01, 0x07, 0x02, 0xFF, 0x01, 0xFC, 0x01, 0xAA, + 0x01, 0xDF, 0x01, 0xFF, 0x01, 0xFC, 0x0B, 0x00, 0x01, 0x2F, 0x01, 0xFF, + 0x01, 0xF9, 0x01, 0x10, 0x01, 0x00, 0x01, 0x02, 0x01, 0xCF, 0x01, 0xFF, + 0x01, 0x70, 0x0A, 0x00, 0x01, 0xAF, 0x01, 0xFF, 0x01, 0x80, 0x03, 0x00, + 0x01, 0x0D, 0x01, 0xFF, 0x01, 0xE0, 0x0A, 0x00, 0x01, 0xEF, 0x01, 0xFF, + 0x04, 0x00, 0x01, 0x05, 0x01, 0xFF, 0x01, 0xF3, 0x09, 0x00, 0x01, 0x02, + 0x01, 0xFF, 0x01, 0xFB, 0x04, 0x00, 0x01, 0x01, 0x01, 0xFF, 0x01, 0xF7, + 0x09, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF9, 0x03, 0x00, 0x01, 0x03, + 0x01, 0x9E, 0x01, 0xFF, 0x01, 0xF8, 0x09, 0x00, 0x01, 0x03, 0x01, 0xFF, + 0x01, 0xF8, 0x02, 0x00, 0x01, 0x01, 0x01, 0xAF, 0x02, 0xFF, 0x01, 0xD7, + 0x09, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF8, 0x02, 0x00, 0x01, 0x1D, + 0x01, 0xFF, 0x01, 0xFC, 0x01, 0x50, 0x0A, 0x00, 0x01, 0x03, 0x01, 0xFF, + 0x01, 0xF8, 0x02, 0x00, 0x01, 0xAF, 0x01, 0xFF, 0x01, 0x70, 0x0B, 0x00, + 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF8, 0x01, 0x00, 0x01, 0x01, 0x01, 0xFF, + 0x01, 0xFA, 0x0C, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF8, 0x01, 0x00, + 0x01, 0x05, 0x01, 0xFF, 0x01, 0xF4, 0x0C, 0x00, 0x01, 0x03, 0x01, 0xFF, + 0x01, 0xF8, 0x01, 0x00, 0x01, 0x06, 0x01, 0xFF, 0x01, 0xF4, 0x0C, 0x00, + 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF8, 0x01, 0x00, 0x01, 0x05, 0x01, 0xFF, + 0x01, 0xF9, 0x0C, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF8, 0x01, 0x00, + 0x01, 0x02, 0x02, 0xFF, 0x01, 0x50, 0x0B, 0x00, 0x01, 0x03, 0x01, 0xFF, + 0x01, 0xF8, 0x02, 0x00, 0x01, 0xBF, 0x01, 0xFF, 0x01, 0xF8, 0x0B, 0x00, + 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF8, 0x02, 0x00, 0x01, 0x1D, 0x02, 0xFF, + 0x01, 0xD3, 0x0A, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF8, 0x02, 0x00, + 0x01, 0x01, 0x01, 0xCF, 0x02, 0xFF, 0x01, 0x70, 0x09, 0x00, 0x01, 0x03, + 0x01, 0xFF, 0x01, 0xF8, 0x03, 0x00, 0x01, 0x07, 0x02, 0xFF, 0x01, 0xFB, + 0x09, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF8, 0x04, 0x00, 0x01, 0x2B, + 0x02, 0xFF, 0x01, 0xB0, 0x08, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF8, + 0x05, 0x00, 0x01, 0x6F, 0x01, 0xFF, 0x01, 0xF6, 0x08, 0x00, 0x01, 0x03, + 0x01, 0xFF, 0x01, 0xF8, 0x05, 0x00, 0x01, 0x06, 0x01, 0xFF, 0x01, 0xFD, + 0x08, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF8, 0x06, 0x00, 0x01, 0xDF, + 0x01, 0xFF, 0x08, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF8, 0x06, 0x00, + 0x01, 0xBF, 0x01, 0xFF, 0x01, 0x10, 0x07, 0x00, 0x01, 0x03, 0x01, 0xFF, + 0x01, 0xF8, 0x06, 0x00, 0x01, 0xCF, 0x01, 0xFF, 0x08, 0x00, 0x01, 0x03, + 0x01, 0xFF, 0x01, 0xF8, 0x05, 0x00, 0x01, 0x01, 0x01, 0xFF, 0x01, 0xFD, + 0x08, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF8, 0x01, 0x02, 0x01, 0x84, + 0x03, 0x00, 0x01, 0x2D, 0x01, 0xFF, 0x01, 0xF8, 0x08, 0x00, 0x01, 0x03, + 0x01, 0xFF, 0x01, 0xF8, 0x01, 0x02, 0x01, 0xFF, 0x01, 0xEC, 0x01, 0xA9, + 0x01, 0xAC, 0x02, 0xFF, 0x01, 0xE0, 0x08, 0x00, 0x01, 0x03, 0x01, 0xFF, + 0x01, 0xF8, 0x01, 0x02, 0x05, 0xFF, 0x01, 0xFE, 0x01, 0x20, 0x08, 0x00, + 0x01, 0x03, 0x01, 0xEE, 0x01, 0xE7, 0x01, 0x01, 0x01, 0xBF, 0x03, 0xFF, + 0x01, 0xFE, 0x01, 0x80, 0x0E, 0x00, 0x01, 0x35, 0x01, 0x78, 0x01, 0x76, + 0x01, 0x30, 0xB4, 0x00, +#endif + +#if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN) + /* 9 LRG_O_STROKE */ + 0x93, 0x00, 0x01, 0x40, 0x0A, 0x00, 0x01, 0x47, 0x01, 0x9A, 0x01, 0xBA, + 0x01, 0x95, 0x01, 0x10, 0x02, 0x00, 0x01, 0x07, 0x01, 0xF8, 0x08, 0x00, + 0x01, 0x02, 0x01, 0xAF, 0x04, 0xFF, 0x01, 0xFC, 0x01, 0x50, 0x01, 0x00, + 0x01, 0x5F, 0x01, 0xFF, 0x01, 0x30, 0x07, 0x00, 0x01, 0x8F, 0x06, 0xFF, + 0x01, 0xFC, 0x01, 0x23, 0x01, 0xFF, 0x01, 0xF6, 0x07, 0x00, 0x01, 0x1C, + 0x03, 0xFF, 0x01, 0xCA, 0x01, 0x9B, 0x01, 0xDF, 0x02, 0xFF, 0x01, 0xFE, + 0x01, 0xFF, 0x01, 0x80, 0x07, 0x00, 0x01, 0xCF, 0x01, 0xFF, 0x01, 0xFD, + 0x01, 0x50, 0x02, 0x00, 0x01, 0x02, 0x01, 0x9F, 0x02, 0xFF, 0x01, 0xFA, + 0x07, 0x00, 0x01, 0x09, 0x02, 0xFF, 0x01, 0x90, 0x04, 0x00, 0x01, 0x03, + 0x01, 0xEF, 0x01, 0xFF, 0x01, 0xF3, 0x07, 0x00, 0x01, 0x5F, 0x01, 0xFF, + 0x01, 0xF9, 0x06, 0x00, 0x01, 0x9F, 0x01, 0xFF, 0x01, 0xFC, 0x07, 0x00, + 0x01, 0xDF, 0x01, 0xFF, 0x01, 0xC0, 0x05, 0x00, 0x01, 0x06, 0x03, 0xFF, + 0x01, 0x60, 0x05, 0x00, 0x01, 0x04, 0x02, 0xFF, 0x01, 0x30, 0x05, 0x00, + 0x01, 0x4F, 0x01, 0xFF, 0x01, 0xDF, 0x01, 0xFF, 0x01, 0xC0, 0x05, 0x00, + 0x01, 0x0B, 0x01, 0xFF, 0x01, 0xFC, 0x05, 0x00, 0x01, 0x02, 0x01, 0xEF, + 0x01, 0xF7, 0x01, 0x3F, 0x01, 0xFF, 0x01, 0xF3, 0x05, 0x00, 0x01, 0x0F, + 0x01, 0xFF, 0x01, 0xF6, 0x05, 0x00, 0x01, 0x1D, 0x01, 0xFF, 0x01, 0xA0, + 0x01, 0x0D, 0x01, 0xFF, 0x01, 0xF8, 0x05, 0x00, 0x01, 0x3F, 0x01, 0xFF, + 0x01, 0xF2, 0x05, 0x00, 0x01, 0xCF, 0x01, 0xFC, 0x01, 0x00, 0x01, 0x09, + 0x01, 0xFF, 0x01, 0xFB, 0x05, 0x00, 0x01, 0x6F, 0x01, 0xFF, 0x01, 0xE0, + 0x04, 0x00, 0x01, 0x0A, 0x01, 0xFF, 0x01, 0xD1, 0x01, 0x00, 0x01, 0x06, + 0x01, 0xFF, 0x01, 0xFE, 0x05, 0x00, 0x01, 0x8F, 0x01, 0xFF, 0x01, 0xC0, + 0x04, 0x00, 0x01, 0x7F, 0x01, 0xFF, 0x01, 0x20, 0x01, 0x00, 0x01, 0x03, + 0x02, 0xFF, 0x05, 0x00, 0x01, 0x9F, 0x01, 0xFF, 0x01, 0xB0, 0x03, 0x00, + 0x01, 0x05, 0x01, 0xFF, 0x01, 0xF4, 0x02, 0x00, 0x01, 0x02, 0x02, 0xFF, + 0x01, 0x10, 0x04, 0x00, 0x01, 0xAF, 0x01, 0xFF, 0x01, 0xA0, 0x03, 0x00, + 0x01, 0x3F, 0x01, 0xFF, 0x01, 0x60, 0x02, 0x00, 0x01, 0x01, 0x02, 0xFF, + 0x01, 0x30, 0x04, 0x00, 0x01, 0xAF, 0x01, 0xFF, 0x01, 0xA0, 0x02, 0x00, + 0x01, 0x01, 0x01, 0xEF, 0x01, 0xF8, 0x03, 0x00, 0x01, 0x02, 0x02, 0xFF, + 0x01, 0x20, 0x04, 0x00, 0x01, 0x9F, 0x01, 0xFF, 0x01, 0xB0, 0x02, 0x00, + 0x01, 0x0D, 0x01, 0xFF, 0x01, 0xB0, 0x03, 0x00, 0x01, 0x03, 0x02, 0xFF, + 0x01, 0x10, 0x04, 0x00, 0x01, 0x8F, 0x01, 0xFF, 0x01, 0xC0, 0x02, 0x00, + 0x01, 0xBF, 0x01, 0xFD, 0x04, 0x00, 0x01, 0x04, 0x02, 0xFF, 0x05, 0x00, + 0x01, 0x6F, 0x01, 0xFF, 0x01, 0xE0, 0x01, 0x00, 0x01, 0x08, 0x01, 0xFF, + 0x01, 0xE1, 0x04, 0x00, 0x01, 0x06, 0x01, 0xFF, 0x01, 0xFE, 0x05, 0x00, + 0x01, 0x2F, 0x01, 0xFF, 0x01, 0xF2, 0x01, 0x00, 0x01, 0x6F, 0x01, 0xFF, + 0x01, 0x30, 0x04, 0x00, 0x01, 0x0A, 0x01, 0xFF, 0x01, 0xFA, 0x05, 0x00, + 0x01, 0x0F, 0x01, 0xFF, 0x01, 0xF6, 0x01, 0x04, 0x01, 0xFF, 0x01, 0xF5, + 0x05, 0x00, 0x01, 0x0E, 0x01, 0xFF, 0x01, 0xF7, 0x05, 0x00, 0x01, 0x09, + 0x01, 0xFF, 0x01, 0xFC, 0x01, 0x2E, 0x01, 0xFF, 0x01, 0x70, 0x05, 0x00, + 0x01, 0x5F, 0x01, 0xFF, 0x01, 0xF2, 0x05, 0x00, 0x01, 0x03, 0x02, 0xFF, + 0x01, 0xEF, 0x01, 0xFA, 0x06, 0x00, 0x01, 0xCF, 0x01, 0xFF, 0x01, 0xB0, + 0x06, 0x00, 0x01, 0xCF, 0x02, 0xFF, 0x01, 0xC0, 0x05, 0x00, 0x01, 0x06, + 0x02, 0xFF, 0x01, 0x40, 0x06, 0x00, 0x01, 0x2F, 0x02, 0xFF, 0x01, 0x20, + 0x05, 0x00, 0x01, 0x4F, 0x01, 0xFF, 0x01, 0xFB, 0x07, 0x00, 0x01, 0x0B, + 0x02, 0xFF, 0x01, 0xD2, 0x04, 0x00, 0x01, 0x06, 0x02, 0xFF, 0x01, 0xE1, + 0x07, 0x00, 0x01, 0x5F, 0x03, 0xFF, 0x01, 0x93, 0x02, 0x00, 0x01, 0x05, + 0x01, 0xCF, 0x02, 0xFF, 0x01, 0x30, 0x06, 0x00, 0x01, 0x03, 0x01, 0xFF, + 0x01, 0xFB, 0x03, 0xFF, 0x01, 0xFD, 0x01, 0xDE, 0x03, 0xFF, 0x01, 0xE3, + 0x07, 0x00, 0x01, 0x1E, 0x01, 0xFF, 0x01, 0x80, 0x01, 0x4D, 0x06, 0xFF, + 0x01, 0xFA, 0x01, 0x10, 0x07, 0x00, 0x01, 0xBF, 0x01, 0xFB, 0x02, 0x00, + 0x01, 0x5C, 0x04, 0xFF, 0x01, 0xE9, 0x01, 0x30, 0x08, 0x00, 0x01, 0x1C, + 0x01, 0xD0, 0x03, 0x00, 0x01, 0x04, 0x01, 0x67, 0x01, 0x86, 0x01, 0x53, + 0x0B, 0x00, 0x01, 0x10, 0xA8, 0x00, + + /* 10 SML_O_STROKE */ + 0xFF, 0x00, 0x15, 0x00, 0x01, 0x02, 0x01, 0x20, 0x0C, 0x00, 0x01, 0x02, + 0x01, 0x32, 0x01, 0x10, 0x02, 0x00, 0x01, 0x1D, 0x01, 0xE3, 0x0A, 0x00, + 0x01, 0x01, 0x01, 0x7C, 0x02, 0xFF, 0x01, 0xFD, 0x01, 0x82, 0x01, 0x00, + 0x01, 0xCF, 0x01, 0xF7, 0x0A, 0x00, 0x01, 0x6E, 0x05, 0xFF, 0x01, 0x89, + 0x01, 0xFF, 0x01, 0xA0, 0x09, 0x00, 0x01, 0x08, 0x07, 0xFF, 0x01, 0xFC, + 0x0A, 0x00, 0x01, 0x6F, 0x01, 0xFF, 0x01, 0xFC, 0x01, 0x50, 0x01, 0x00, + 0x01, 0x3A, 0x02, 0xFF, 0x01, 0xF1, 0x09, 0x00, 0x01, 0x01, 0x02, 0xFF, + 0x01, 0x90, 0x03, 0x00, 0x01, 0x7F, 0x01, 0xFF, 0x01, 0xF5, 0x09, 0x00, + 0x01, 0x08, 0x01, 0xFF, 0x01, 0xFC, 0x03, 0x00, 0x01, 0x01, 0x01, 0xDF, + 0x01, 0xFF, 0x01, 0xFD, 0x09, 0x00, 0x01, 0x0E, 0x01, 0xFF, 0x01, 0xF3, + 0x03, 0x00, 0x01, 0x0B, 0x03, 0xFF, 0x01, 0x30, 0x08, 0x00, 0x01, 0x3F, + 0x01, 0xFF, 0x01, 0xD0, 0x03, 0x00, 0x01, 0x9F, 0x01, 0xFA, 0x01, 0x8F, + 0x01, 0xFF, 0x01, 0x80, 0x08, 0x00, 0x01, 0x7F, 0x01, 0xFF, 0x01, 0x80, + 0x02, 0x00, 0x01, 0x06, 0x01, 0xFF, 0x01, 0xC0, 0x01, 0x3F, 0x01, 0xFF, + 0x01, 0xB0, 0x08, 0x00, 0x01, 0x9F, 0x01, 0xFF, 0x01, 0x50, 0x02, 0x00, + 0x01, 0x3F, 0x01, 0xFE, 0x01, 0x10, 0x01, 0x1F, 0x01, 0xFF, 0x01, 0xE0, + 0x08, 0x00, 0x01, 0xAF, 0x01, 0xFF, 0x01, 0x40, 0x01, 0x00, 0x01, 0x02, + 0x01, 0xEF, 0x01, 0xF3, 0x01, 0x00, 0x01, 0x0F, 0x01, 0xFF, 0x01, 0xF0, + 0x08, 0x00, 0x01, 0xBF, 0x01, 0xFF, 0x01, 0x30, 0x01, 0x00, 0x01, 0x0D, + 0x01, 0xFF, 0x01, 0x50, 0x01, 0x00, 0x01, 0x0E, 0x01, 0xFF, 0x01, 0xF0, + 0x08, 0x00, 0x01, 0xAF, 0x01, 0xFF, 0x01, 0x30, 0x01, 0x00, 0x01, 0xBF, + 0x01, 0xF8, 0x02, 0x00, 0x01, 0x0F, 0x01, 0xFF, 0x01, 0xF0, 0x08, 0x00, + 0x01, 0x9F, 0x01, 0xFF, 0x01, 0x40, 0x01, 0x08, 0x01, 0xFF, 0x01, 0xB0, + 0x02, 0x00, 0x01, 0x0F, 0x01, 0xFF, 0x01, 0xE0, 0x08, 0x00, 0x01, 0x7F, + 0x01, 0xFF, 0x01, 0x60, 0x01, 0x5F, 0x01, 0xFD, 0x03, 0x00, 0x01, 0x3F, + 0x01, 0xFF, 0x01, 0xC0, 0x08, 0x00, 0x01, 0x4F, 0x01, 0xFF, 0x01, 0xA3, + 0x01, 0xFF, 0x01, 0xE2, 0x03, 0x00, 0x01, 0x7F, 0x01, 0xFF, 0x01, 0x90, + 0x08, 0x00, 0x01, 0x0F, 0x01, 0xFF, 0x01, 0xFE, 0x01, 0xFF, 0x01, 0x40, + 0x03, 0x00, 0x01, 0xCF, 0x01, 0xFF, 0x01, 0x50, 0x08, 0x00, 0x01, 0x0A, + 0x02, 0xFF, 0x01, 0xF6, 0x03, 0x00, 0x01, 0x05, 0x01, 0xFF, 0x01, 0xFE, + 0x09, 0x00, 0x01, 0x02, 0x02, 0xFF, 0x01, 0xB0, 0x03, 0x00, 0x01, 0x2E, + 0x01, 0xFF, 0x01, 0xF8, 0x0A, 0x00, 0x01, 0xBF, 0x01, 0xFF, 0x01, 0xF7, + 0x02, 0x00, 0x01, 0x05, 0x01, 0xEF, 0x01, 0xFF, 0x01, 0xD0, 0x09, 0x00, + 0x01, 0x04, 0x03, 0xFF, 0x01, 0xFC, 0x01, 0xAB, 0x01, 0xEF, 0x01, 0xFF, + 0x01, 0xFE, 0x01, 0x20, 0x09, 0x00, 0x01, 0x2F, 0x01, 0xFF, 0x01, 0xAF, + 0x05, 0xFF, 0x01, 0xD2, 0x09, 0x00, 0x01, 0x01, 0x01, 0xDF, 0x01, 0xF5, + 0x01, 0x04, 0x01, 0xBF, 0x03, 0xFF, 0x01, 0xD6, 0x0A, 0x00, 0x01, 0x03, + 0x01, 0xFF, 0x01, 0x70, 0x01, 0x00, 0x01, 0x01, 0x01, 0x46, 0x01, 0x76, + 0x01, 0x52, 0x0C, 0x00, 0x01, 0x28, 0xA9, 0x00, + + /* 11 LRG_AE */ + 0x9E, 0x00, 0x01, 0x14, 0x0B, 0x44, 0x01, 0x41, 0x06, 0x00, 0x01, 0x8F, + 0x0B, 0xFF, 0x01, 0xF3, 0x06, 0x00, 0x01, 0xEF, 0x0B, 0xFF, 0x01, 0xF3, + 0x05, 0x00, 0x01, 0x05, 0x02, 0xFF, 0x01, 0xEE, 0x09, 0xFF, 0x01, 0xF3, + 0x05, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xF5, 0x01, 0x00, 0x01, 0xDF, + 0x01, 0xFF, 0x01, 0x63, 0x06, 0x33, 0x01, 0x30, 0x05, 0x00, 0x01, 0x3F, + 0x01, 0xFF, 0x01, 0xE0, 0x01, 0x00, 0x01, 0xDF, 0x01, 0xFF, 0x01, 0x40, + 0x0C, 0x00, 0x01, 0xAF, 0x01, 0xFF, 0x01, 0x80, 0x01, 0x00, 0x01, 0xDF, + 0x01, 0xFF, 0x01, 0x40, 0x0B, 0x00, 0x01, 0x01, 0x02, 0xFF, 0x01, 0x10, + 0x01, 0x00, 0x01, 0xDF, 0x01, 0xFF, 0x01, 0x40, 0x0B, 0x00, 0x01, 0x07, + 0x01, 0xFF, 0x01, 0xFA, 0x02, 0x00, 0x01, 0xDF, 0x01, 0xFF, 0x01, 0x40, + 0x0B, 0x00, 0x01, 0x0D, 0x01, 0xFF, 0x01, 0xF3, 0x02, 0x00, 0x01, 0xDF, + 0x01, 0xFF, 0x01, 0x40, 0x0B, 0x00, 0x01, 0x4F, 0x01, 0xFF, 0x01, 0xD0, + 0x02, 0x00, 0x01, 0xDF, 0x01, 0xFF, 0x01, 0x40, 0x0B, 0x00, 0x01, 0xBF, + 0x01, 0xFF, 0x01, 0x60, 0x02, 0x00, 0x01, 0xDF, 0x01, 0xFF, 0x01, 0x40, + 0x0A, 0x00, 0x01, 0x02, 0x01, 0xFF, 0x01, 0xFE, 0x03, 0x00, 0x01, 0xDF, + 0x01, 0xFF, 0x01, 0x40, 0x0A, 0x00, 0x01, 0x08, 0x01, 0xFF, 0x01, 0xF9, + 0x03, 0x00, 0x01, 0xDF, 0x01, 0xFF, 0x01, 0xED, 0x06, 0xDD, 0x01, 0x80, + 0x03, 0x00, 0x01, 0x0E, 0x01, 0xFF, 0x01, 0xF2, 0x03, 0x00, 0x01, 0xDF, + 0x08, 0xFF, 0x01, 0xA0, 0x03, 0x00, 0x01, 0x6F, 0x01, 0xFF, 0x01, 0xB0, + 0x03, 0x00, 0x01, 0xDF, 0x08, 0xFF, 0x01, 0xA0, 0x03, 0x00, 0x01, 0xCF, + 0x01, 0xFF, 0x01, 0x40, 0x03, 0x00, 0x01, 0xDF, 0x01, 0xFF, 0x01, 0xA8, + 0x06, 0x88, 0x01, 0x50, 0x02, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xFE, + 0x04, 0x00, 0x01, 0xDF, 0x01, 0xFF, 0x01, 0x40, 0x09, 0x00, 0x01, 0x0A, + 0x01, 0xFF, 0x01, 0xF7, 0x04, 0x00, 0x01, 0xDF, 0x01, 0xFF, 0x01, 0x40, + 0x09, 0x00, 0x01, 0x1F, 0x01, 0xFF, 0x01, 0xF4, 0x04, 0x33, 0x01, 0xDF, + 0x01, 0xFF, 0x01, 0x40, 0x09, 0x00, 0x01, 0x7F, 0x08, 0xFF, 0x01, 0x40, + 0x09, 0x00, 0x01, 0xEF, 0x08, 0xFF, 0x01, 0x40, 0x08, 0x00, 0x01, 0x05, + 0x09, 0xFF, 0x01, 0x40, 0x08, 0x00, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0xF7, + 0x05, 0x33, 0x01, 0xDF, 0x01, 0xFF, 0x01, 0x40, 0x08, 0x00, 0x01, 0x2F, + 0x01, 0xFF, 0x01, 0xE0, 0x05, 0x00, 0x01, 0xDF, 0x01, 0xFF, 0x01, 0x40, + 0x08, 0x00, 0x01, 0x9F, 0x01, 0xFF, 0x01, 0x80, 0x05, 0x00, 0x01, 0xDF, + 0x01, 0xFF, 0x01, 0x40, 0x08, 0x00, 0x02, 0xFF, 0x01, 0x20, 0x05, 0x00, + 0x01, 0xDF, 0x01, 0xFF, 0x01, 0x40, 0x07, 0x00, 0x01, 0x06, 0x01, 0xFF, + 0x01, 0xFB, 0x06, 0x00, 0x01, 0xDF, 0x01, 0xFF, 0x01, 0xA8, 0x06, 0x88, + 0x01, 0x85, 0x01, 0x0D, 0x01, 0xFF, 0x01, 0xF4, 0x06, 0x00, 0x01, 0xDF, + 0x08, 0xFF, 0x01, 0xF9, 0x01, 0x4F, 0x01, 0xFF, 0x01, 0xE0, 0x06, 0x00, + 0x01, 0xDF, 0x08, 0xFF, 0x01, 0xF9, 0x01, 0x8D, 0x01, 0xDD, 0x01, 0x60, + 0x06, 0x00, 0x01, 0xBD, 0x08, 0xDD, 0x01, 0xD8, 0xBE, 0x00, + + /* 12 SML_AE */ + 0xFF, 0x00, 0x22, 0x00, 0x01, 0x01, 0x01, 0x34, 0x01, 0x31, 0x06, 0x00, + 0x01, 0x12, 0x01, 0x42, 0x01, 0x10, 0x05, 0x00, 0x01, 0x02, 0x01, 0x7B, + 0x01, 0xEF, 0x02, 0xFF, 0x01, 0xFB, 0x01, 0x60, 0x02, 0x00, 0x01, 0x03, + 0x01, 0x9E, 0x02, 0xFF, 0x01, 0xFD, 0x01, 0x81, 0x04, 0x00, 0x01, 0xBF, + 0x05, 0xFF, 0x01, 0xFE, 0x01, 0x40, 0x01, 0x01, 0x01, 0x9F, 0x05, 0xFF, + 0x01, 0x60, 0x03, 0x00, 0x01, 0xDF, 0x02, 0xFF, 0x01, 0xEE, 0x03, 0xFF, + 0x01, 0xF5, 0x01, 0x1D, 0x03, 0xFF, 0x01, 0xEF, 0x02, 0xFF, 0x01, 0xF8, + 0x03, 0x00, 0x01, 0xDF, 0x01, 0xB6, 0x01, 0x30, 0x01, 0x00, 0x01, 0x01, + 0x01, 0x5D, 0x02, 0xFF, 0x01, 0xDF, 0x01, 0xFF, 0x01, 0xE7, 0x01, 0x20, + 0x01, 0x00, 0x01, 0x29, 0x02, 0xFF, 0x01, 0x50, 0x02, 0x00, 0x01, 0x71, + 0x05, 0x00, 0x01, 0xAF, 0x02, 0xFF, 0x01, 0xFB, 0x01, 0x10, 0x03, 0x00, + 0x01, 0x4F, 0x01, 0xFF, 0x01, 0xE0, 0x08, 0x00, 0x01, 0x0D, 0x02, 0xFF, + 0x01, 0xD0, 0x04, 0x00, 0x01, 0x07, 0x01, 0xFF, 0x01, 0xF7, 0x08, 0x00, + 0x01, 0x06, 0x02, 0xFF, 0x01, 0x40, 0x05, 0x00, 0x01, 0xEF, 0x01, 0xFD, + 0x08, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xFD, 0x06, 0x00, 0x01, 0x9F, + 0x01, 0xFF, 0x04, 0x00, 0x01, 0x02, 0x01, 0x45, 0x02, 0x66, 0x01, 0x67, + 0x01, 0xFF, 0x01, 0xF9, 0x06, 0x00, 0x01, 0x6F, 0x01, 0xFF, 0x03, 0x00, + 0x01, 0x4A, 0x06, 0xFF, 0x01, 0xFB, 0x03, 0x66, 0x01, 0x67, 0x02, 0x77, + 0x01, 0xAF, 0x01, 0xFF, 0x02, 0x00, 0x01, 0x1B, 0x10, 0xFF, 0x01, 0x00, + 0x01, 0x01, 0x01, 0xDF, 0x02, 0xFF, 0x01, 0xCA, 0x01, 0x98, 0x01, 0x88, + 0x01, 0x89, 0x0A, 0xFF, 0x01, 0x00, 0x01, 0x09, 0x01, 0xFF, 0x01, 0xFD, + 0x01, 0x40, 0x03, 0x00, 0x01, 0x02, 0x01, 0xFF, 0x01, 0xFA, 0x08, 0x77, + 0x01, 0x00, 0x01, 0x1F, 0x01, 0xFF, 0x01, 0xD0, 0x04, 0x00, 0x01, 0x03, + 0x01, 0xFF, 0x01, 0xF7, 0x09, 0x00, 0x01, 0x5F, 0x01, 0xFF, 0x01, 0x70, + 0x04, 0x00, 0x01, 0x05, 0x01, 0xFF, 0x01, 0xFA, 0x09, 0x00, 0x01, 0x7F, + 0x01, 0xFF, 0x01, 0x30, 0x04, 0x00, 0x01, 0x09, 0x01, 0xFF, 0x01, 0xFE, + 0x09, 0x00, 0x01, 0x7F, 0x01, 0xFF, 0x01, 0x30, 0x04, 0x00, 0x01, 0x0F, + 0x02, 0xFF, 0x01, 0x50, 0x08, 0x00, 0x01, 0x6F, 0x01, 0xFF, 0x01, 0x60, + 0x04, 0x00, 0x01, 0x8F, 0x02, 0xFF, 0x01, 0xE1, 0x08, 0x00, 0x01, 0x3F, + 0x01, 0xFF, 0x01, 0xD0, 0x03, 0x00, 0x01, 0x06, 0x01, 0xFF, 0x01, 0xFE, + 0x01, 0xFF, 0x01, 0xFC, 0x01, 0x10, 0x05, 0x00, 0x01, 0x45, 0x01, 0x00, + 0x01, 0x0D, 0x01, 0xFF, 0x01, 0xFC, 0x01, 0x20, 0x01, 0x00, 0x01, 0x01, + 0x01, 0x9F, 0x01, 0xFF, 0x01, 0xA2, 0x02, 0xFF, 0x01, 0xE6, 0x01, 0x10, + 0x02, 0x00, 0x01, 0x02, 0x01, 0x8D, 0x01, 0xF8, 0x01, 0x00, 0x01, 0x05, + 0x02, 0xFF, 0x01, 0xFD, 0x01, 0xAB, 0x01, 0xCF, 0x01, 0xFF, 0x01, 0xFC, + 0x01, 0x00, 0x01, 0x3F, 0x02, 0xFF, 0x01, 0xFD, 0x01, 0xBA, 0x01, 0xBC, + 0x02, 0xFF, 0x01, 0xF8, 0x02, 0x00, 0x01, 0x7F, 0x05, 0xFF, 0x01, 0xA0, + 0x01, 0x00, 0x01, 0x02, 0x01, 0xCF, 0x06, 0xFF, 0x01, 0xF7, 0x02, 0x00, + 0x01, 0x03, 0x01, 0xBF, 0x03, 0xFF, 0x01, 0xB4, 0x03, 0x00, 0x01, 0x05, + 0x01, 0xBF, 0x04, 0xFF, 0x01, 0xB7, 0x01, 0x10, 0x03, 0x00, 0x01, 0x01, + 0x01, 0x46, 0x01, 0x76, 0x01, 0x41, 0x06, 0x00, 0x01, 0x35, 0x01, 0x67, + 0x01, 0x64, 0x01, 0x20, 0xAD, 0x00, + + /* 13 LRG_ETH */ + 0x9A, 0x00, 0x01, 0x34, 0x03, 0x44, 0x01, 0x43, 0x01, 0x21, 0x0D, 0x00, + 0x01, 0xBF, 0x05, 0xFF, 0x01, 0xFE, 0x01, 0xB8, 0x01, 0x40, 0x0A, 0x00, + 0x01, 0xBF, 0x07, 0xFF, 0x01, 0xFE, 0x01, 0x81, 0x09, 0x00, 0x01, 0xBF, + 0x08, 0xFF, 0x01, 0xFE, 0x01, 0x60, 0x08, 0x00, 0x01, 0xBF, 0x01, 0xFF, + 0x01, 0x61, 0x02, 0x11, 0x01, 0x23, 0x01, 0x58, 0x01, 0xCF, 0x02, 0xFF, + 0x01, 0xF9, 0x08, 0x00, 0x01, 0xBF, 0x01, 0xFF, 0x01, 0x50, 0x04, 0x00, + 0x01, 0x02, 0x01, 0x9F, 0x02, 0xFF, 0x01, 0x80, 0x07, 0x00, 0x01, 0xBF, + 0x01, 0xFF, 0x01, 0x50, 0x05, 0x00, 0x01, 0x04, 0x01, 0xEF, 0x01, 0xFF, + 0x01, 0xF4, 0x07, 0x00, 0x01, 0xBF, 0x01, 0xFF, 0x01, 0x50, 0x06, 0x00, + 0x01, 0x2F, 0x01, 0xFF, 0x01, 0xFD, 0x07, 0x00, 0x01, 0xBF, 0x01, 0xFF, + 0x01, 0x50, 0x06, 0x00, 0x01, 0x06, 0x02, 0xFF, 0x01, 0x50, 0x06, 0x00, + 0x01, 0xBF, 0x01, 0xFF, 0x01, 0x50, 0x07, 0x00, 0x01, 0xEF, 0x01, 0xFF, + 0x01, 0xB0, 0x06, 0x00, 0x01, 0xBF, 0x01, 0xFF, 0x01, 0x50, 0x07, 0x00, + 0x01, 0x7F, 0x01, 0xFF, 0x01, 0xF0, 0x06, 0x00, 0x01, 0xBF, 0x01, 0xFF, + 0x01, 0x50, 0x07, 0x00, 0x01, 0x3F, 0x01, 0xFF, 0x01, 0xF3, 0x06, 0x00, + 0x01, 0xBF, 0x01, 0xFF, 0x01, 0x50, 0x07, 0x00, 0x01, 0x0F, 0x01, 0xFF, + 0x01, 0xF5, 0x04, 0x00, 0x01, 0x23, 0x01, 0x33, 0x01, 0xCF, 0x01, 0xFF, + 0x01, 0x73, 0x02, 0x33, 0x01, 0x30, 0x04, 0x00, 0x01, 0x0D, 0x01, 0xFF, + 0x01, 0xF6, 0x04, 0x00, 0x01, 0xCF, 0x06, 0xFF, 0x01, 0xF2, 0x04, 0x00, + 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xF7, 0x04, 0x00, 0x01, 0xCF, 0x06, 0xFF, + 0x01, 0xF2, 0x04, 0x00, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0xF9, 0x04, 0x00, + 0x01, 0x9B, 0x01, 0xBB, 0x01, 0xEF, 0x01, 0xFF, 0x01, 0xDB, 0x02, 0xBB, + 0x01, 0xB1, 0x04, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xF8, 0x06, 0x00, + 0x01, 0xBF, 0x01, 0xFF, 0x01, 0x50, 0x07, 0x00, 0x01, 0x0D, 0x01, 0xFF, + 0x01, 0xF7, 0x06, 0x00, 0x01, 0xBF, 0x01, 0xFF, 0x01, 0x50, 0x07, 0x00, + 0x01, 0x0E, 0x01, 0xFF, 0x01, 0xF6, 0x06, 0x00, 0x01, 0xBF, 0x01, 0xFF, + 0x01, 0x50, 0x07, 0x00, 0x01, 0x1F, 0x01, 0xFF, 0x01, 0xF4, 0x06, 0x00, + 0x01, 0xBF, 0x01, 0xFF, 0x01, 0x50, 0x07, 0x00, 0x01, 0x5F, 0x01, 0xFF, + 0x01, 0xF1, 0x06, 0x00, 0x01, 0xBF, 0x01, 0xFF, 0x01, 0x50, 0x07, 0x00, + 0x01, 0xAF, 0x01, 0xFF, 0x01, 0xD0, 0x06, 0x00, 0x01, 0xBF, 0x01, 0xFF, + 0x01, 0x50, 0x06, 0x00, 0x01, 0x01, 0x02, 0xFF, 0x01, 0x80, 0x06, 0x00, + 0x01, 0xBF, 0x01, 0xFF, 0x01, 0x50, 0x06, 0x00, 0x01, 0x0B, 0x02, 0xFF, + 0x01, 0x20, 0x06, 0x00, 0x01, 0xBF, 0x01, 0xFF, 0x01, 0x50, 0x06, 0x00, + 0x01, 0x8F, 0x01, 0xFF, 0x01, 0xF9, 0x07, 0x00, 0x01, 0xBF, 0x01, 0xFF, + 0x01, 0x50, 0x05, 0x00, 0x01, 0x0A, 0x02, 0xFF, 0x01, 0xE1, 0x07, 0x00, + 0x01, 0xBF, 0x01, 0xFF, 0x01, 0x50, 0x04, 0x00, 0x01, 0x29, 0x03, 0xFF, + 0x01, 0x30, 0x07, 0x00, 0x01, 0xBF, 0x01, 0xFF, 0x01, 0xA7, 0x01, 0x77, + 0x01, 0x78, 0x01, 0x9A, 0x01, 0xBF, 0x03, 0xFF, 0x01, 0xE3, 0x08, 0x00, + 0x01, 0xBF, 0x08, 0xFF, 0x01, 0xF9, 0x01, 0x10, 0x08, 0x00, 0x01, 0xBF, + 0x07, 0xFF, 0x01, 0xD8, 0x01, 0x10, 0x09, 0x00, 0x01, 0xAD, 0x03, 0xDD, + 0x01, 0xDC, 0x01, 0xCB, 0x01, 0xA7, 0x01, 0x41, 0xC7, 0x00, + + /* 14 SML_ETH */ + 0x88, 0x00, 0x01, 0x38, 0x01, 0x88, 0x01, 0x81, 0x10, 0x00, 0x01, 0x0B, + 0x01, 0xFF, 0x01, 0xFC, 0x03, 0x00, 0x01, 0x5A, 0x01, 0x40, 0x0C, 0x00, + 0x01, 0xDF, 0x01, 0xFF, 0x01, 0xB0, 0x01, 0x04, 0x01, 0xAF, 0x01, 0xFF, + 0x01, 0xA0, 0x0C, 0x00, 0x01, 0x1E, 0x01, 0xFF, 0x01, 0xFC, 0x02, 0xFF, + 0x01, 0xD8, 0x01, 0x20, 0x0C, 0x00, 0x01, 0x07, 0x02, 0xFF, 0x01, 0xFD, + 0x01, 0x82, 0x0D, 0x00, 0x01, 0x5A, 0x03, 0xFF, 0x01, 0xF4, 0x0D, 0x00, + 0x01, 0x7F, 0x01, 0xFF, 0x01, 0xFD, 0x01, 0x87, 0x02, 0xFF, 0x01, 0x30, + 0x0C, 0x00, 0x01, 0x6F, 0x01, 0xE9, 0x01, 0x30, 0x01, 0x00, 0x01, 0x8F, + 0x01, 0xFF, 0x01, 0xE2, 0x0C, 0x00, 0x01, 0x03, 0x03, 0x00, 0x01, 0x0A, + 0x01, 0xFF, 0x01, 0xFD, 0x01, 0x10, 0x0E, 0x00, 0x01, 0x23, 0x01, 0x44, + 0x01, 0xDF, 0x01, 0xFF, 0x01, 0xB0, 0x0C, 0x00, 0x01, 0x02, 0x01, 0x9E, + 0x04, 0xFF, 0x01, 0xF7, 0x0C, 0x00, 0x01, 0x7F, 0x06, 0xFF, 0x01, 0x30, + 0x0A, 0x00, 0x01, 0x09, 0x02, 0xFF, 0x01, 0xFE, 0x01, 0xCB, 0x01, 0xDF, + 0x02, 0xFF, 0x01, 0xD0, 0x0A, 0x00, 0x01, 0x6F, 0x01, 0xFF, 0x01, 0xFB, + 0x01, 0x30, 0x02, 0x00, 0x01, 0x4E, 0x01, 0xFF, 0x01, 0xF5, 0x09, 0x00, + 0x01, 0x02, 0x02, 0xFF, 0x01, 0x70, 0x03, 0x00, 0x01, 0x05, 0x01, 0xFF, + 0x01, 0xFD, 0x09, 0x00, 0x01, 0x09, 0x01, 0xFF, 0x01, 0xFA, 0x05, 0x00, + 0x01, 0xEF, 0x01, 0xFF, 0x01, 0x20, 0x08, 0x00, 0x01, 0x0F, 0x01, 0xFF, + 0x01, 0xF1, 0x05, 0x00, 0x01, 0x8F, 0x01, 0xFF, 0x01, 0x70, 0x08, 0x00, + 0x01, 0x4F, 0x01, 0xFF, 0x01, 0xA0, 0x05, 0x00, 0x01, 0x4F, 0x01, 0xFF, + 0x01, 0xB0, 0x08, 0x00, 0x01, 0x8F, 0x01, 0xFF, 0x01, 0x70, 0x05, 0x00, + 0x01, 0x1F, 0x01, 0xFF, 0x01, 0xD0, 0x08, 0x00, 0x01, 0x9F, 0x01, 0xFF, + 0x01, 0x40, 0x05, 0x00, 0x01, 0x0F, 0x01, 0xFF, 0x01, 0xF0, 0x08, 0x00, + 0x01, 0xAF, 0x01, 0xFF, 0x01, 0x30, 0x05, 0x00, 0x01, 0x0E, 0x01, 0xFF, + 0x01, 0xF0, 0x08, 0x00, 0x01, 0xAF, 0x01, 0xFF, 0x01, 0x30, 0x05, 0x00, + 0x01, 0x0F, 0x01, 0xFF, 0x01, 0xF0, 0x08, 0x00, 0x01, 0x9F, 0x01, 0xFF, + 0x01, 0x40, 0x05, 0x00, 0x01, 0x0F, 0x01, 0xFF, 0x01, 0xE0, 0x08, 0x00, + 0x01, 0x8F, 0x01, 0xFF, 0x01, 0x70, 0x05, 0x00, 0x01, 0x2F, 0x01, 0xFF, + 0x01, 0xD0, 0x08, 0x00, 0x01, 0x4F, 0x01, 0xFF, 0x01, 0xA0, 0x05, 0x00, + 0x01, 0x6F, 0x01, 0xFF, 0x01, 0x90, 0x08, 0x00, 0x01, 0x0F, 0x01, 0xFF, + 0x01, 0xF1, 0x05, 0x00, 0x01, 0xCF, 0x01, 0xFF, 0x01, 0x50, 0x08, 0x00, + 0x01, 0x09, 0x01, 0xFF, 0x01, 0xF9, 0x04, 0x00, 0x01, 0x05, 0x01, 0xFF, + 0x01, 0xFE, 0x09, 0x00, 0x01, 0x02, 0x02, 0xFF, 0x01, 0x60, 0x03, 0x00, + 0x01, 0x3E, 0x01, 0xFF, 0x01, 0xF6, 0x0A, 0x00, 0x01, 0x7F, 0x01, 0xFF, + 0x01, 0xF9, 0x01, 0x20, 0x01, 0x00, 0x01, 0x07, 0x02, 0xFF, 0x01, 0xB0, + 0x0A, 0x00, 0x01, 0x09, 0x02, 0xFF, 0x01, 0xFD, 0x01, 0xBD, 0x02, 0xFF, + 0x01, 0xFD, 0x01, 0x10, 0x0B, 0x00, 0x01, 0x7F, 0x05, 0xFF, 0x01, 0xB0, + 0x0C, 0x00, 0x01, 0x02, 0x01, 0xAE, 0x03, 0xFF, 0x01, 0xB4, 0x0F, 0x00, + 0x01, 0x35, 0x01, 0x65, 0x01, 0x40, 0xB6, 0x00, + + /* 15 LRG_THORN */ + 0x9A, 0x00, 0x02, 0x55, 0x11, 0x00, 0x02, 0xFF, 0x01, 0x20, 0x10, 0x00, + 0x02, 0xFF, 0x01, 0x20, 0x10, 0x00, 0x02, 0xFF, 0x01, 0x20, 0x10, 0x00, + 0x02, 0xFF, 0x01, 0x20, 0x10, 0x00, 0x02, 0xFF, 0x01, 0x20, 0x10, 0x00, + 0x05, 0xFF, 0x01, 0xED, 0x01, 0xA7, 0x01, 0x10, 0x0B, 0x00, 0x07, 0xFF, + 0x01, 0xFA, 0x01, 0x10, 0x0A, 0x00, 0x08, 0xFF, 0x01, 0xE2, 0x0A, 0x00, + 0x02, 0xFF, 0x01, 0x65, 0x01, 0x55, 0x01, 0x56, 0x01, 0x7A, 0x02, 0xFF, + 0x01, 0xFE, 0x01, 0x10, 0x09, 0x00, 0x02, 0xFF, 0x01, 0x20, 0x03, 0x00, + 0x01, 0x1B, 0x02, 0xFF, 0x01, 0x80, 0x09, 0x00, 0x02, 0xFF, 0x01, 0x20, + 0x04, 0x00, 0x01, 0xCF, 0x01, 0xFF, 0x01, 0xF0, 0x09, 0x00, 0x02, 0xFF, + 0x01, 0x20, 0x04, 0x00, 0x01, 0x4F, 0x01, 0xFF, 0x01, 0xF3, 0x09, 0x00, + 0x02, 0xFF, 0x01, 0x20, 0x04, 0x00, 0x01, 0x0F, 0x01, 0xFF, 0x01, 0xF6, + 0x09, 0x00, 0x02, 0xFF, 0x01, 0x20, 0x04, 0x00, 0x01, 0x0D, 0x01, 0xFF, + 0x01, 0xF7, 0x09, 0x00, 0x02, 0xFF, 0x01, 0x20, 0x04, 0x00, 0x01, 0x0D, + 0x01, 0xFF, 0x01, 0xF7, 0x09, 0x00, 0x02, 0xFF, 0x01, 0x20, 0x04, 0x00, + 0x01, 0x0F, 0x01, 0xFF, 0x01, 0xF6, 0x09, 0x00, 0x02, 0xFF, 0x01, 0x20, + 0x04, 0x00, 0x01, 0x4F, 0x01, 0xFF, 0x01, 0xF3, 0x09, 0x00, 0x02, 0xFF, + 0x01, 0x20, 0x04, 0x00, 0x01, 0xCF, 0x01, 0xFF, 0x01, 0xF0, 0x09, 0x00, + 0x02, 0xFF, 0x01, 0x20, 0x03, 0x00, 0x01, 0x1B, 0x02, 0xFF, 0x01, 0x80, + 0x09, 0x00, 0x02, 0xFF, 0x01, 0x65, 0x02, 0x55, 0x01, 0x7A, 0x02, 0xFF, + 0x01, 0xFE, 0x01, 0x10, 0x09, 0x00, 0x08, 0xFF, 0x01, 0xE2, 0x0A, 0x00, + 0x07, 0xFF, 0x01, 0xFA, 0x01, 0x10, 0x0A, 0x00, 0x05, 0xFF, 0x01, 0xED, + 0x01, 0xA7, 0x01, 0x10, 0x0B, 0x00, 0x02, 0xFF, 0x01, 0x20, 0x10, 0x00, + 0x02, 0xFF, 0x01, 0x20, 0x10, 0x00, 0x02, 0xFF, 0x01, 0x20, 0x10, 0x00, + 0x02, 0xFF, 0x01, 0x20, 0x10, 0x00, 0x02, 0xFF, 0x01, 0x20, 0x10, 0x00, + 0x02, 0xFF, 0x01, 0x20, 0x10, 0x00, 0x02, 0xCC, 0x01, 0x10, 0xCC, 0x00, + + /* 16 SML_THORN */ + 0x86, 0x00, 0x01, 0x02, 0x01, 0x99, 0x01, 0x94, 0x10, 0x00, 0x01, 0x03, + 0x01, 0xFF, 0x01, 0xF7, 0x10, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF7, + 0x10, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF7, 0x10, 0x00, 0x01, 0x03, + 0x01, 0xFF, 0x01, 0xF7, 0x10, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF7, + 0x10, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF7, 0x10, 0x00, 0x01, 0x03, + 0x01, 0xFF, 0x01, 0xF7, 0x10, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF7, + 0x02, 0x00, 0x01, 0x13, 0x01, 0x54, 0x01, 0x20, 0x0B, 0x00, 0x01, 0x03, + 0x01, 0xFF, 0x01, 0xF7, 0x01, 0x00, 0x01, 0x5C, 0x02, 0xFF, 0x01, 0xFD, + 0x01, 0x70, 0x0A, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF7, 0x01, 0x0B, + 0x04, 0xFF, 0x01, 0xFD, 0x01, 0x20, 0x09, 0x00, 0x01, 0x03, 0x01, 0xFF, + 0x01, 0xF7, 0x01, 0xAF, 0x01, 0xFF, 0x01, 0xEC, 0x01, 0xDF, 0x02, 0xFF, + 0x01, 0xE1, 0x09, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xFD, 0x01, 0xFF, + 0x01, 0xC3, 0x02, 0x00, 0x01, 0x6F, 0x01, 0xFF, 0x01, 0xFC, 0x09, 0x00, + 0x01, 0x03, 0x02, 0xFF, 0x01, 0xFA, 0x03, 0x00, 0x01, 0x02, 0x01, 0xEF, + 0x01, 0xFF, 0x01, 0x60, 0x08, 0x00, 0x01, 0x03, 0x02, 0xFF, 0x01, 0xE0, + 0x04, 0x00, 0x01, 0x5F, 0x01, 0xFF, 0x01, 0xD0, 0x08, 0x00, 0x01, 0x03, + 0x02, 0xFF, 0x01, 0x60, 0x04, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xF3, + 0x08, 0x00, 0x01, 0x03, 0x02, 0xFF, 0x05, 0x00, 0x01, 0x06, 0x01, 0xFF, + 0x01, 0xF7, 0x08, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xFC, 0x05, 0x00, + 0x01, 0x02, 0x01, 0xFF, 0x01, 0xFB, 0x08, 0x00, 0x01, 0x03, 0x01, 0xFF, + 0x01, 0xF9, 0x06, 0x00, 0x01, 0xFF, 0x01, 0xFD, 0x08, 0x00, 0x01, 0x03, + 0x01, 0xFF, 0x01, 0xF8, 0x06, 0x00, 0x01, 0xEF, 0x01, 0xFE, 0x08, 0x00, + 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF8, 0x06, 0x00, 0x01, 0xEF, 0x01, 0xFF, + 0x08, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF8, 0x06, 0x00, 0x01, 0xEF, + 0x01, 0xFE, 0x08, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF9, 0x06, 0x00, + 0x01, 0xFF, 0x01, 0xFD, 0x08, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xFC, + 0x05, 0x00, 0x01, 0x02, 0x01, 0xFF, 0x01, 0xFB, 0x08, 0x00, 0x01, 0x03, + 0x02, 0xFF, 0x05, 0x00, 0x01, 0x06, 0x01, 0xFF, 0x01, 0xF8, 0x08, 0x00, + 0x01, 0x03, 0x02, 0xFF, 0x01, 0x60, 0x04, 0x00, 0x01, 0x0C, 0x01, 0xFF, + 0x01, 0xF3, 0x08, 0x00, 0x01, 0x03, 0x02, 0xFF, 0x01, 0xD0, 0x04, 0x00, + 0x01, 0x5F, 0x01, 0xFF, 0x01, 0xD0, 0x08, 0x00, 0x01, 0x03, 0x02, 0xFF, + 0x01, 0xFA, 0x03, 0x00, 0x01, 0x02, 0x01, 0xEF, 0x01, 0xFF, 0x01, 0x60, + 0x08, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xFD, 0x01, 0xFF, 0x01, 0xB3, + 0x02, 0x00, 0x01, 0x6E, 0x01, 0xFF, 0x01, 0xFC, 0x09, 0x00, 0x01, 0x03, + 0x01, 0xFF, 0x01, 0xF7, 0x01, 0xBF, 0x01, 0xFF, 0x01, 0xEC, 0x01, 0xCF, + 0x02, 0xFF, 0x01, 0xE2, 0x09, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF7, + 0x01, 0x0B, 0x04, 0xFF, 0x01, 0xFD, 0x01, 0x20, 0x09, 0x00, 0x01, 0x03, + 0x01, 0xFF, 0x01, 0xF7, 0x01, 0x00, 0x01, 0x6C, 0x02, 0xFF, 0x01, 0xFE, + 0x01, 0x70, 0x0A, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF7, 0x02, 0x00, + 0x01, 0x23, 0x01, 0x54, 0x01, 0x20, 0x0B, 0x00, 0x01, 0x03, 0x01, 0xFF, + 0x01, 0xF7, 0x10, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF7, 0x10, 0x00, + 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF7, 0x10, 0x00, 0x01, 0x03, 0x01, 0xFF, + 0x01, 0xF7, 0x10, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF7, 0x10, 0x00, + 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF7, 0x10, 0x00, 0x01, 0x03, 0x01, 0xFF, + 0x01, 0xF7, 0x10, 0x00, 0x01, 0x01, 0x01, 0x66, 0x01, 0x63, 0x22, 0x00, +#endif // TOUCH_UI_UTF8_SCANDINAVIAN + +#if ENABLED(TOUCH_UI_UTF8_PUNCTUATION) + /* 17 LEFT_DBL_QUOTE */ + 0xFF, 0x00, 0x4A, 0x00, 0x01, 0x30, 0x03, 0x00, 0x01, 0x02, 0x0D, 0x00, + 0x01, 0x08, 0x01, 0xA0, 0x02, 0x00, 0x01, 0x01, 0x01, 0xC6, 0x0D, 0x00, + 0x01, 0xAF, 0x01, 0xA0, 0x02, 0x00, 0x01, 0x1D, 0x01, 0xF6, 0x0C, 0x00, + 0x01, 0x1C, 0x01, 0xFF, 0x01, 0xA0, 0x01, 0x00, 0x01, 0x02, 0x01, 0xEF, + 0x01, 0xF6, 0x0B, 0x00, 0x01, 0x01, 0x01, 0xDF, 0x01, 0xFF, 0x01, 0x50, + 0x01, 0x00, 0x01, 0x3E, 0x01, 0xFF, 0x01, 0xE2, 0x0B, 0x00, 0x01, 0x2E, + 0x01, 0xFF, 0x01, 0xF4, 0x01, 0x00, 0x01, 0x05, 0x01, 0xFF, 0x01, 0xFD, + 0x01, 0x20, 0x0A, 0x00, 0x01, 0x04, 0x01, 0xEF, 0x01, 0xFE, 0x01, 0x30, + 0x01, 0x00, 0x01, 0x6F, 0x01, 0xFF, 0x01, 0xD1, 0x0B, 0x00, 0x01, 0x5F, + 0x01, 0xFF, 0x01, 0xD2, 0x01, 0x00, 0x01, 0x08, 0x01, 0xFF, 0x01, 0xFB, + 0x0B, 0x00, 0x01, 0x06, 0x01, 0xFF, 0x01, 0xFC, 0x01, 0x10, 0x01, 0x00, + 0x01, 0xAF, 0x01, 0xFF, 0x01, 0xA0, 0x0B, 0x00, 0x01, 0x0C, 0x01, 0xFF, + 0x01, 0xD0, 0x02, 0x00, 0x01, 0xFF, 0x01, 0xFA, 0x0C, 0x00, 0x01, 0x0A, + 0x01, 0xFF, 0x01, 0xF8, 0x02, 0x00, 0x01, 0xEF, 0x01, 0xFF, 0x01, 0x50, + 0x0C, 0x00, 0x01, 0xAF, 0x01, 0xFF, 0x01, 0xA0, 0x01, 0x00, 0x01, 0x1C, + 0x01, 0xFF, 0x01, 0xF6, 0x0C, 0x00, 0x01, 0x08, 0x01, 0xFF, 0x01, 0xFB, + 0x02, 0x00, 0x01, 0xBF, 0x01, 0xFF, 0x01, 0x90, 0x0C, 0x00, 0x01, 0x6F, + 0x01, 0xFF, 0x01, 0xD1, 0x01, 0x00, 0x01, 0x0A, 0x01, 0xFF, 0x01, 0xFA, + 0x0C, 0x00, 0x01, 0x05, 0x01, 0xFF, 0x01, 0xFD, 0x01, 0x20, 0x01, 0x00, + 0x01, 0x8F, 0x01, 0xFF, 0x01, 0xB0, 0x0C, 0x00, 0x01, 0x4F, 0x01, 0xFF, + 0x01, 0xA0, 0x01, 0x00, 0x01, 0x07, 0x01, 0xFF, 0x01, 0xF6, 0x0C, 0x00, + 0x01, 0x02, 0x01, 0xEF, 0x01, 0xA0, 0x02, 0x00, 0x01, 0x5F, 0x01, 0xF6, + 0x0D, 0x00, 0x01, 0x1D, 0x01, 0xA0, 0x02, 0x00, 0x01, 0x04, 0x01, 0xE6, + 0x0D, 0x00, 0x01, 0x01, 0x01, 0x60, 0x03, 0x00, 0x01, 0x24, 0xFF, 0x00, + + /* 18 RIGHT_DBL_QUOTE */ + 0xFF, 0x00, 0x46, 0x00, 0x01, 0x20, 0x03, 0x00, 0x01, 0x20, 0x0D, 0x00, + 0x01, 0x01, 0x01, 0xE3, 0x03, 0x00, 0x01, 0x5D, 0x01, 0x10, 0x0C, 0x00, + 0x01, 0x01, 0x01, 0xFF, 0x01, 0x50, 0x02, 0x00, 0x01, 0x5F, 0x01, 0xE2, + 0x0C, 0x00, 0x01, 0x01, 0x01, 0xFF, 0x01, 0xF6, 0x02, 0x00, 0x01, 0x5F, + 0x01, 0xFE, 0x01, 0x30, 0x0C, 0x00, 0x01, 0xBF, 0x01, 0xFF, 0x01, 0x80, + 0x01, 0x00, 0x01, 0x2E, 0x01, 0xFF, 0x01, 0xF5, 0x0C, 0x00, 0x01, 0x0A, + 0x01, 0xFF, 0x01, 0xFA, 0x01, 0x00, 0x01, 0x01, 0x01, 0xCF, 0x01, 0xFF, + 0x01, 0x60, 0x0C, 0x00, 0x01, 0x8F, 0x01, 0xFF, 0x01, 0xB0, 0x01, 0x00, + 0x01, 0x0B, 0x01, 0xFF, 0x01, 0xF9, 0x0C, 0x00, 0x01, 0x06, 0x01, 0xFF, + 0x01, 0xFC, 0x01, 0x10, 0x01, 0x00, 0x01, 0xAF, 0x01, 0xFF, 0x01, 0xA0, + 0x0C, 0x00, 0x01, 0x5F, 0x01, 0xFF, 0x01, 0xD1, 0x01, 0x00, 0x01, 0x08, + 0x01, 0xFF, 0x01, 0xFB, 0x0C, 0x00, 0x01, 0x05, 0x01, 0xFF, 0x01, 0xF5, + 0x02, 0x00, 0x01, 0x9F, 0x01, 0xFF, 0x01, 0x10, 0x0B, 0x00, 0x01, 0x2D, + 0x01, 0xFF, 0x01, 0xF3, 0x01, 0x00, 0x01, 0x04, 0x01, 0xFF, 0x01, 0xFE, + 0x01, 0x10, 0x0A, 0x00, 0x01, 0x03, 0x01, 0xEF, 0x01, 0xFF, 0x01, 0x40, + 0x01, 0x00, 0x01, 0x5F, 0x01, 0xFF, 0x01, 0xD2, 0x0B, 0x00, 0x01, 0x4F, + 0x01, 0xFF, 0x01, 0xE3, 0x01, 0x00, 0x01, 0x06, 0x01, 0xFF, 0x01, 0xFC, + 0x01, 0x10, 0x0A, 0x00, 0x01, 0x05, 0x01, 0xFF, 0x01, 0xFD, 0x01, 0x10, + 0x01, 0x00, 0x01, 0x9F, 0x01, 0xFF, 0x01, 0xB0, 0x0B, 0x00, 0x01, 0x6F, + 0x01, 0xFF, 0x01, 0xC1, 0x01, 0x00, 0x01, 0x0A, 0x01, 0xFF, 0x01, 0xF9, + 0x0B, 0x00, 0x01, 0x01, 0x01, 0xFF, 0x01, 0xFA, 0x02, 0x00, 0x01, 0x5F, + 0x01, 0xFF, 0x01, 0x70, 0x0B, 0x00, 0x01, 0x01, 0x01, 0xFF, 0x01, 0x90, + 0x02, 0x00, 0x01, 0x5F, 0x01, 0xF6, 0x0C, 0x00, 0x01, 0x01, 0x01, 0xF8, + 0x03, 0x00, 0x01, 0x5F, 0x01, 0x40, 0x0C, 0x00, 0x01, 0x01, 0x01, 0x50, + 0x03, 0x00, 0x01, 0x43, 0xFF, 0x00, 0x04, 0x00, + + /* 19 INV_EXCLAMATION */ + 0xFF, 0x00, 0x34, 0x00, 0x01, 0xAD, 0x01, 0xDD, 0x01, 0x40, 0x10, 0x00, + 0x01, 0xCF, 0x01, 0xFF, 0x01, 0x50, 0x10, 0x00, 0x01, 0xCF, 0x01, 0xFF, + 0x01, 0x50, 0x10, 0x00, 0x01, 0xCF, 0x01, 0xFF, 0x01, 0x50, 0x10, 0x00, + 0x01, 0xCF, 0x01, 0xFF, 0x01, 0x50, 0x10, 0x00, 0x01, 0x34, 0x01, 0x44, + 0x01, 0x10, 0x49, 0x00, 0x01, 0x02, 0x01, 0x22, 0x11, 0x00, 0x01, 0x6F, + 0x01, 0xFF, 0x11, 0x00, 0x01, 0x7F, 0x01, 0xFF, 0x11, 0x00, 0x01, 0x7F, + 0x01, 0xFF, 0x01, 0x10, 0x10, 0x00, 0x01, 0x8F, 0x01, 0xFF, 0x01, 0x20, + 0x10, 0x00, 0x01, 0x9F, 0x01, 0xFF, 0x01, 0x30, 0x10, 0x00, 0x01, 0xAF, + 0x01, 0xFF, 0x01, 0x30, 0x10, 0x00, 0x01, 0xBF, 0x01, 0xFF, 0x01, 0x40, + 0x10, 0x00, 0x01, 0xCF, 0x01, 0xFF, 0x01, 0x50, 0x10, 0x00, 0x01, 0xCF, + 0x01, 0xFF, 0x01, 0x50, 0x10, 0x00, 0x01, 0xCF, 0x01, 0xFF, 0x01, 0x50, + 0x10, 0x00, 0x01, 0xCF, 0x01, 0xFF, 0x01, 0x50, 0x10, 0x00, 0x01, 0xCF, + 0x01, 0xFF, 0x01, 0x50, 0x10, 0x00, 0x01, 0xCF, 0x01, 0xFF, 0x01, 0x50, + 0x10, 0x00, 0x01, 0xCF, 0x01, 0xFF, 0x01, 0x50, 0x10, 0x00, 0x01, 0xCF, + 0x01, 0xFF, 0x01, 0x50, 0x10, 0x00, 0x01, 0xCF, 0x01, 0xFF, 0x01, 0x50, + 0x10, 0x00, 0x01, 0xCF, 0x01, 0xFF, 0x01, 0x50, 0x10, 0x00, 0x01, 0xCF, + 0x01, 0xFF, 0x01, 0x50, 0x10, 0x00, 0x01, 0xCF, 0x01, 0xFF, 0x01, 0x50, + 0x10, 0x00, 0x01, 0xCF, 0x01, 0xFF, 0x01, 0x50, 0x10, 0x00, 0x01, 0x34, + 0x01, 0x44, 0x01, 0x10, 0x33, 0x00, + + /* 20 INV_QUESTION */ + 0xFF, 0x00, 0x36, 0x00, 0x02, 0xDD, 0x11, 0x00, 0x02, 0xFF, 0x11, 0x00, + 0x02, 0xFF, 0x11, 0x00, 0x02, 0xFF, 0x11, 0x00, 0x02, 0xFF, 0x11, 0x00, + 0x02, 0x44, 0x37, 0x00, 0x01, 0xBC, 0x01, 0xCB, 0x11, 0x00, 0x01, 0xEF, + 0x01, 0xFE, 0x11, 0x00, 0x01, 0xEF, 0x01, 0xFE, 0x11, 0x00, 0x01, 0xEF, + 0x01, 0xFE, 0x11, 0x00, 0x01, 0xFF, 0x01, 0xFD, 0x10, 0x00, 0x01, 0x03, + 0x01, 0xFF, 0x01, 0xFB, 0x10, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xF6, + 0x10, 0x00, 0x01, 0xAF, 0x01, 0xFF, 0x01, 0xD0, 0x0F, 0x00, 0x01, 0x0A, + 0x02, 0xFF, 0x01, 0x30, 0x0F, 0x00, 0x01, 0xAF, 0x01, 0xFF, 0x01, 0xF4, + 0x0F, 0x00, 0x01, 0x09, 0x02, 0xFF, 0x01, 0x40, 0x0F, 0x00, 0x01, 0x7F, + 0x01, 0xFF, 0x01, 0xF4, 0x0F, 0x00, 0x01, 0x03, 0x02, 0xFF, 0x01, 0x40, + 0x0F, 0x00, 0x01, 0x0A, 0x01, 0xFF, 0x01, 0xF8, 0x10, 0x00, 0x01, 0x0F, + 0x01, 0xFF, 0x01, 0xF2, 0x10, 0x00, 0x01, 0x1F, 0x01, 0xFF, 0x01, 0xF0, + 0x10, 0x00, 0x01, 0x0F, 0x01, 0xFF, 0x01, 0xF2, 0x10, 0x00, 0x01, 0x0E, + 0x01, 0xFF, 0x01, 0xF8, 0x04, 0x00, 0x01, 0x05, 0x01, 0xD0, 0x0A, 0x00, + 0x01, 0x08, 0x02, 0xFF, 0x01, 0x70, 0x02, 0x00, 0x01, 0x05, 0x01, 0xCF, + 0x01, 0xF0, 0x0A, 0x00, 0x01, 0x01, 0x01, 0xEF, 0x01, 0xFF, 0x01, 0xFE, + 0x01, 0x98, 0x01, 0x8B, 0x02, 0xFF, 0x01, 0xF0, 0x0B, 0x00, 0x01, 0x3F, + 0x06, 0xFF, 0x01, 0xC0, 0x0B, 0x00, 0x01, 0x02, 0x01, 0xCF, 0x04, 0xFF, + 0x01, 0xC5, 0x0D, 0x00, 0x01, 0x03, 0x01, 0x8B, 0x01, 0xCC, 0x01, 0xB9, + 0x01, 0x62, 0x31, 0x00, +#endif // TOUCH_UI_UTF8_PUNCTUATION + +#if ENABLED(TOUCH_UI_UTF8_CURRENCY) + /* 21 CENT_SIGN */ + 0xB1, 0x00, 0x01, 0x01, 0x01, 0x32, 0x11, 0x00, 0x01, 0x05, 0x01, 0xFB, + 0x11, 0x00, 0x01, 0x05, 0x01, 0xFB, 0x11, 0x00, 0x01, 0x05, 0x01, 0xFB, + 0x11, 0x00, 0x01, 0x05, 0x01, 0xFC, 0x11, 0x00, 0x01, 0x05, 0x01, 0xFC, + 0x11, 0x00, 0x01, 0x39, 0x01, 0xFD, 0x01, 0x42, 0x0E, 0x00, 0x01, 0x05, + 0x01, 0xBF, 0x03, 0xFF, 0x01, 0xFB, 0x01, 0x50, 0x0B, 0x00, 0x01, 0x03, + 0x01, 0xCF, 0x05, 0xFF, 0x01, 0xF6, 0x0B, 0x00, 0x01, 0x4F, 0x02, 0xFF, + 0x02, 0xFE, 0x01, 0xCE, 0x01, 0xFF, 0x01, 0xF6, 0x0A, 0x00, 0x01, 0x02, + 0x02, 0xFF, 0x01, 0xE6, 0x01, 0x05, 0x01, 0xFC, 0x01, 0x00, 0x01, 0x38, + 0x01, 0xE6, 0x0A, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xFD, 0x01, 0x10, + 0x01, 0x05, 0x01, 0xFC, 0x02, 0x00, 0x01, 0x02, 0x0A, 0x00, 0x01, 0x5F, + 0x01, 0xFF, 0x01, 0xE1, 0x01, 0x00, 0x01, 0x05, 0x01, 0xFC, 0x0D, 0x00, + 0x01, 0xCF, 0x01, 0xFF, 0x01, 0x60, 0x01, 0x00, 0x01, 0x05, 0x01, 0xFC, + 0x0D, 0x00, 0x02, 0xFF, 0x02, 0x00, 0x01, 0x05, 0x01, 0xFC, 0x0C, 0x00, + 0x01, 0x04, 0x01, 0xFF, 0x01, 0xFB, 0x02, 0x00, 0x01, 0x05, 0x01, 0xFC, + 0x0C, 0x00, 0x01, 0x06, 0x01, 0xFF, 0x01, 0xF8, 0x02, 0x00, 0x01, 0x05, + 0x01, 0xFC, 0x0C, 0x00, 0x01, 0x07, 0x01, 0xFF, 0x01, 0xF7, 0x02, 0x00, + 0x01, 0x05, 0x01, 0xFB, 0x0C, 0x00, 0x01, 0x08, 0x01, 0xFF, 0x01, 0xF6, + 0x02, 0x00, 0x01, 0x05, 0x01, 0xFC, 0x0C, 0x00, 0x01, 0x07, 0x01, 0xFF, + 0x01, 0xF7, 0x02, 0x00, 0x01, 0x05, 0x01, 0xFB, 0x0C, 0x00, 0x01, 0x06, + 0x01, 0xFF, 0x01, 0xF9, 0x02, 0x00, 0x01, 0x05, 0x01, 0xFB, 0x0C, 0x00, + 0x01, 0x03, 0x01, 0xFF, 0x01, 0xFC, 0x02, 0x00, 0x01, 0x05, 0x01, 0xFB, + 0x0D, 0x00, 0x02, 0xFF, 0x01, 0x10, 0x01, 0x00, 0x01, 0x05, 0x01, 0xFB, + 0x0D, 0x00, 0x01, 0xAF, 0x01, 0xFF, 0x01, 0x80, 0x01, 0x00, 0x01, 0x05, + 0x01, 0xFB, 0x0D, 0x00, 0x01, 0x4F, 0x01, 0xFF, 0x01, 0xF3, 0x01, 0x00, + 0x01, 0x05, 0x01, 0xFB, 0x0D, 0x00, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0xFE, + 0x01, 0x30, 0x01, 0x05, 0x01, 0xFB, 0x02, 0x00, 0x01, 0x33, 0x0A, 0x00, + 0x01, 0x01, 0x01, 0xEF, 0x01, 0xFF, 0x01, 0xF9, 0x01, 0x35, 0x01, 0xFB, + 0x01, 0x02, 0x01, 0x6C, 0x01, 0xF6, 0x0B, 0x00, 0x01, 0x2D, 0x06, 0xFF, + 0x01, 0xF6, 0x0B, 0x00, 0x01, 0x01, 0x01, 0x9F, 0x05, 0xFF, 0x01, 0xF5, + 0x0C, 0x00, 0x01, 0x02, 0x01, 0x8D, 0x03, 0xFF, 0x01, 0xC7, 0x01, 0x20, + 0x0E, 0x00, 0x01, 0x06, 0x01, 0xFC, 0x01, 0x20, 0x10, 0x00, 0x01, 0x05, + 0x01, 0xFB, 0x11, 0x00, 0x01, 0x05, 0x01, 0xFB, 0x11, 0x00, 0x01, 0x05, + 0x01, 0xFB, 0x11, 0x00, 0x01, 0x05, 0x01, 0xFB, 0x11, 0x00, 0x01, 0x05, + 0x01, 0xFB, 0x57, 0x00, + + /* 22 POUND_SIGN */ + 0x9E, 0x00, 0x01, 0x6B, 0x01, 0xDF, 0x01, 0xFD, 0x01, 0xC9, 0x01, 0x40, + 0x0D, 0x00, 0x01, 0x6E, 0x05, 0xFF, 0x01, 0x30, 0x0B, 0x00, 0x01, 0x07, + 0x06, 0xFF, 0x01, 0x30, 0x0B, 0x00, 0x01, 0x3F, 0x01, 0xFF, 0x01, 0xFE, + 0x01, 0x85, 0x01, 0x34, 0x01, 0x7B, 0x01, 0xFF, 0x01, 0x30, 0x0B, 0x00, + 0x01, 0xAF, 0x01, 0xFF, 0x01, 0xC1, 0x03, 0x00, 0x01, 0x18, 0x01, 0x30, + 0x0A, 0x00, 0x01, 0x01, 0x02, 0xFF, 0x01, 0x30, 0x0F, 0x00, 0x01, 0x04, + 0x01, 0xFF, 0x01, 0xFD, 0x10, 0x00, 0x01, 0x07, 0x01, 0xFF, 0x01, 0xFA, + 0x10, 0x00, 0x01, 0x08, 0x01, 0xFF, 0x01, 0xF8, 0x10, 0x00, 0x01, 0x09, + 0x01, 0xFF, 0x01, 0xF7, 0x10, 0x00, 0x01, 0x0A, 0x01, 0xFF, 0x01, 0xF6, + 0x10, 0x00, 0x01, 0x0A, 0x01, 0xFF, 0x01, 0xF6, 0x10, 0x00, 0x01, 0x0A, + 0x01, 0xFF, 0x01, 0xF6, 0x10, 0x00, 0x01, 0x0A, 0x01, 0xFF, 0x01, 0xF6, + 0x10, 0x00, 0x01, 0x0A, 0x01, 0xFF, 0x01, 0xF6, 0x0E, 0x00, 0x01, 0x0A, + 0x07, 0xFF, 0x01, 0xF4, 0x0A, 0x00, 0x01, 0x0A, 0x07, 0xFF, 0x01, 0xF4, + 0x0A, 0x00, 0x01, 0x08, 0x01, 0xDD, 0x01, 0xDF, 0x01, 0xFF, 0x01, 0xFE, + 0x03, 0xDD, 0x01, 0xD4, 0x0C, 0x00, 0x01, 0x0A, 0x01, 0xFF, 0x01, 0xF6, + 0x10, 0x00, 0x01, 0x0A, 0x01, 0xFF, 0x01, 0xF6, 0x10, 0x00, 0x01, 0x0A, + 0x01, 0xFF, 0x01, 0xF6, 0x10, 0x00, 0x01, 0x0A, 0x01, 0xFF, 0x01, 0xF6, + 0x10, 0x00, 0x01, 0x0A, 0x01, 0xFF, 0x01, 0xF6, 0x10, 0x00, 0x01, 0x0A, + 0x01, 0xFF, 0x01, 0xF6, 0x10, 0x00, 0x01, 0x0A, 0x01, 0xFF, 0x01, 0xF6, + 0x10, 0x00, 0x01, 0x0A, 0x01, 0xFF, 0x01, 0xF6, 0x10, 0x00, 0x01, 0x0A, + 0x01, 0xFF, 0x01, 0xF6, 0x0E, 0x00, 0x01, 0x4B, 0x01, 0xBB, 0x01, 0xBE, + 0x01, 0xFF, 0x01, 0xFD, 0x05, 0xBB, 0x01, 0x70, 0x08, 0x00, 0x01, 0x6F, + 0x09, 0xFF, 0x01, 0xA0, 0x08, 0x00, 0x01, 0x6F, 0x09, 0xFF, 0x01, 0xA0, + 0x08, 0x00, 0x01, 0x4A, 0x09, 0xAA, 0x01, 0x60, 0xC5, 0x00, + + /* 23 CURRENCY_SIGN */ + 0xFF, 0x00, 0x0D, 0x00, 0x01, 0x30, 0x07, 0x00, 0x01, 0x01, 0x01, 0x40, + 0x08, 0x00, 0x01, 0x0B, 0x01, 0xF5, 0x07, 0x00, 0x01, 0x1D, 0x01, 0xF4, + 0x08, 0x00, 0x01, 0xBF, 0x01, 0xFF, 0x01, 0x40, 0x05, 0x00, 0x01, 0x01, + 0x01, 0xDF, 0x01, 0xFF, 0x01, 0x30, 0x07, 0x00, 0x01, 0x5F, 0x01, 0xFF, + 0x01, 0xF4, 0x01, 0x00, 0x01, 0x6B, 0x01, 0xDD, 0x01, 0xC8, 0x01, 0x20, + 0x01, 0x1D, 0x01, 0xFF, 0x01, 0xFA, 0x08, 0x00, 0x01, 0x05, 0x02, 0xFF, + 0x01, 0x8E, 0x03, 0xFF, 0x01, 0xFA, 0x01, 0xDF, 0x01, 0xFF, 0x01, 0xA0, + 0x09, 0x00, 0x01, 0x5F, 0x07, 0xFF, 0x01, 0xFA, 0x0A, 0x00, 0x01, 0x05, + 0x02, 0xFF, 0x01, 0xE9, 0x01, 0x55, 0x01, 0x7C, 0x02, 0xFF, 0x01, 0xA0, + 0x0A, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0xFB, 0x01, 0x10, 0x02, 0x00, + 0x01, 0x6F, 0x01, 0xFF, 0x01, 0xA0, 0x0A, 0x00, 0x01, 0x0B, 0x01, 0xFF, + 0x01, 0xC0, 0x03, 0x00, 0x01, 0x07, 0x01, 0xFF, 0x01, 0xF2, 0x0A, 0x00, + 0x01, 0x1F, 0x01, 0xFF, 0x01, 0x30, 0x04, 0x00, 0x01, 0xDF, 0x01, 0xF7, + 0x0A, 0x00, 0x01, 0x4F, 0x01, 0xFD, 0x05, 0x00, 0x01, 0x8F, 0x01, 0xFA, + 0x0A, 0x00, 0x01, 0x6F, 0x01, 0xFC, 0x05, 0x00, 0x01, 0x6F, 0x01, 0xFC, + 0x0A, 0x00, 0x01, 0x5F, 0x01, 0xFC, 0x05, 0x00, 0x01, 0x7F, 0x01, 0xFB, + 0x0A, 0x00, 0x01, 0x3F, 0x01, 0xFF, 0x01, 0x10, 0x04, 0x00, 0x01, 0xBF, + 0x01, 0xF8, 0x0A, 0x00, 0x01, 0x0E, 0x01, 0xFF, 0x01, 0x80, 0x03, 0x00, + 0x01, 0x03, 0x01, 0xFF, 0x01, 0xF3, 0x0A, 0x00, 0x01, 0x07, 0x01, 0xFF, + 0x01, 0xF5, 0x03, 0x00, 0x01, 0x1D, 0x01, 0xFF, 0x01, 0xC0, 0x0A, 0x00, + 0x01, 0x01, 0x02, 0xFF, 0x01, 0x92, 0x01, 0x00, 0x01, 0x16, 0x01, 0xEF, + 0x01, 0xFF, 0x01, 0x60, 0x0A, 0x00, 0x01, 0x1D, 0x03, 0xFF, 0x01, 0xFE, + 0x03, 0xFF, 0x01, 0xF4, 0x09, 0x00, 0x01, 0x01, 0x01, 0xDF, 0x05, 0xFF, + 0x01, 0xFE, 0x02, 0xFF, 0x01, 0x40, 0x08, 0x00, 0x01, 0x1D, 0x01, 0xFF, + 0x01, 0xFA, 0x01, 0x06, 0x01, 0xDF, 0x01, 0xFF, 0x01, 0xFE, 0x01, 0x81, + 0x01, 0x5F, 0x01, 0xFF, 0x01, 0xF4, 0x08, 0x00, 0x01, 0xCF, 0x01, 0xFF, + 0x01, 0xA0, 0x01, 0x00, 0x01, 0x01, 0x01, 0x44, 0x01, 0x20, 0x01, 0x00, + 0x01, 0x05, 0x02, 0xFF, 0x01, 0x20, 0x07, 0x00, 0x01, 0x4F, 0x01, 0xFA, + 0x07, 0x00, 0x01, 0x4F, 0x01, 0xF8, 0x08, 0x00, 0x01, 0x05, 0x01, 0xA0, + 0x07, 0x00, 0x01, 0x05, 0x01, 0x80, 0xEB, 0x00, + + /* 24 YEN_SIGN */ + 0x98, 0x00, 0x01, 0x01, 0x01, 0x88, 0x01, 0x85, 0x07, 0x00, 0x01, 0x38, + 0x01, 0x88, 0x01, 0x40, 0x07, 0x00, 0x01, 0xCF, 0x01, 0xFF, 0x01, 0x10, + 0x06, 0x00, 0x01, 0xCF, 0x01, 0xFF, 0x01, 0x10, 0x07, 0x00, 0x01, 0x3F, + 0x01, 0xFF, 0x01, 0x90, 0x05, 0x00, 0x01, 0x05, 0x01, 0xFF, 0x01, 0xF8, + 0x08, 0x00, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0xF2, 0x05, 0x00, 0x01, 0x0D, + 0x01, 0xFF, 0x01, 0xE0, 0x08, 0x00, 0x01, 0x02, 0x01, 0xFF, 0x01, 0xFA, + 0x05, 0x00, 0x01, 0x6F, 0x01, 0xFF, 0x01, 0x60, 0x09, 0x00, 0x01, 0xAF, + 0x01, 0xFF, 0x01, 0x30, 0x04, 0x00, 0x01, 0xEF, 0x01, 0xFD, 0x0A, 0x00, + 0x01, 0x1F, 0x01, 0xFF, 0x01, 0xC0, 0x03, 0x00, 0x01, 0x07, 0x01, 0xFF, + 0x01, 0xF5, 0x0A, 0x00, 0x01, 0x08, 0x01, 0xFF, 0x01, 0xF4, 0x03, 0x00, + 0x01, 0x1F, 0x01, 0xFF, 0x01, 0xC0, 0x0A, 0x00, 0x01, 0x01, 0x01, 0xEF, + 0x01, 0xFD, 0x03, 0x00, 0x01, 0x9F, 0x01, 0xFF, 0x01, 0x40, 0x0B, 0x00, + 0x01, 0x7F, 0x01, 0xFF, 0x01, 0x50, 0x01, 0x00, 0x01, 0x02, 0x01, 0xFF, + 0x01, 0xFB, 0x0C, 0x00, 0x01, 0x0E, 0x01, 0xFF, 0x01, 0xE0, 0x01, 0x00, + 0x01, 0x0A, 0x01, 0xFF, 0x01, 0xF3, 0x0C, 0x00, 0x01, 0x06, 0x01, 0xFF, + 0x01, 0xF7, 0x01, 0x00, 0x01, 0x2F, 0x01, 0xFF, 0x01, 0xA0, 0x0A, 0x00, + 0x01, 0x2A, 0x02, 0xAA, 0x01, 0xFF, 0x01, 0xFE, 0x01, 0x10, 0x01, 0xBF, + 0x01, 0xFF, 0x01, 0xCA, 0x01, 0xAA, 0x01, 0xA5, 0x08, 0x00, 0x01, 0x4F, + 0x04, 0xFF, 0x01, 0x83, 0x04, 0xFF, 0x01, 0xF8, 0x08, 0x00, 0x01, 0x3C, + 0x02, 0xCC, 0x01, 0xCE, 0x01, 0xFF, 0x01, 0xFD, 0x01, 0xFF, 0x01, 0xFC, + 0x02, 0xCC, 0x01, 0xC6, 0x0B, 0x00, 0x01, 0x03, 0x03, 0xFF, 0x01, 0x70, + 0x0F, 0x00, 0x01, 0xAF, 0x01, 0xFF, 0x01, 0xFE, 0x10, 0x00, 0x01, 0x2F, + 0x01, 0xFF, 0x01, 0xF5, 0x0C, 0x00, 0x01, 0x01, 0x03, 0x11, 0x01, 0x1E, + 0x01, 0xFF, 0x01, 0xF3, 0x03, 0x11, 0x01, 0x10, 0x08, 0x00, 0x01, 0x4F, + 0x09, 0xFF, 0x01, 0xF8, 0x08, 0x00, 0x01, 0x4F, 0x09, 0xFF, 0x01, 0xF8, + 0x08, 0x00, 0x01, 0x27, 0x03, 0x77, 0x01, 0x7E, 0x01, 0xFF, 0x01, 0xF8, + 0x03, 0x77, 0x01, 0x73, 0x0C, 0x00, 0x01, 0x0E, 0x01, 0xFF, 0x01, 0xF2, + 0x10, 0x00, 0x01, 0x0E, 0x01, 0xFF, 0x01, 0xF2, 0x10, 0x00, 0x01, 0x0E, + 0x01, 0xFF, 0x01, 0xF2, 0x10, 0x00, 0x01, 0x0E, 0x01, 0xFF, 0x01, 0xF2, + 0x10, 0x00, 0x01, 0x0E, 0x01, 0xFF, 0x01, 0xF2, 0x10, 0x00, 0x01, 0x0E, + 0x01, 0xFF, 0x01, 0xF2, 0x10, 0x00, 0x01, 0x0E, 0x01, 0xFF, 0x01, 0xF2, + 0x10, 0x00, 0x01, 0x0E, 0x01, 0xFF, 0x01, 0xF2, 0x10, 0x00, 0x01, 0x08, + 0x01, 0x99, 0x01, 0x91, 0xC9, 0x00, +#endif // TOUCH_UI_UTF8_CURRENCY + +#if ENABLED(TOUCH_UI_UTF8_SUPERSCRIPTS) + /* 25 SUPERSCRIPT_ONE */ + 0x99, 0x00, 0x01, 0x01, 0x01, 0x36, 0x01, 0x9B, 0x01, 0xBB, 0x01, 0x20, + 0x0E, 0x00, 0x01, 0x3F, 0x03, 0xFF, 0x01, 0x20, 0x0E, 0x00, 0x01, 0x3F, + 0x01, 0xFE, 0x01, 0xBE, 0x01, 0xFF, 0x01, 0x20, 0x0E, 0x00, 0x01, 0x14, + 0x01, 0x10, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x20, 0x10, 0x00, 0x01, 0x0B, + 0x01, 0xFF, 0x01, 0x20, 0x10, 0x00, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x20, + 0x10, 0x00, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x20, 0x10, 0x00, 0x01, 0x0B, + 0x01, 0xFF, 0x01, 0x20, 0x10, 0x00, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x20, + 0x10, 0x00, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x20, 0x10, 0x00, 0x01, 0x0B, + 0x01, 0xFF, 0x01, 0x20, 0x10, 0x00, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x20, + 0x10, 0x00, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x20, 0x10, 0x00, 0x01, 0x0B, + 0x01, 0xFF, 0x01, 0x20, 0x0F, 0x00, 0x01, 0x11, 0x01, 0x1C, 0x01, 0xFF, + 0x01, 0x31, 0x01, 0x11, 0x0D, 0x00, 0x01, 0x0D, 0x05, 0xFF, 0x01, 0x40, + 0x0C, 0x00, 0x01, 0x0D, 0x05, 0xFF, 0x01, 0x40, 0x0C, 0x00, 0x01, 0x01, + 0x05, 0x22, 0xFF, 0x00, 0xC2, 0x00, + + /* 26 SUPERSCRIPT_TWO */ + 0x88, 0x00, 0x01, 0x01, 0x10, 0x00, 0x01, 0x16, 0x01, 0xAE, 0x01, 0xFF, + 0x01, 0xFD, 0x01, 0x92, 0x0E, 0x00, 0x05, 0xFF, 0x01, 0x60, 0x0D, 0x00, + 0x01, 0xFE, 0x01, 0x84, 0x01, 0x22, 0x01, 0x5C, 0x01, 0xFF, 0x01, 0xF3, + 0x0D, 0x00, 0x01, 0x50, 0x03, 0x00, 0x01, 0xCF, 0x01, 0xFA, 0x11, 0x00, + 0x01, 0x5F, 0x01, 0xFC, 0x11, 0x00, 0x01, 0x5F, 0x01, 0xFB, 0x11, 0x00, + 0x01, 0xCF, 0x01, 0xF4, 0x10, 0x00, 0x01, 0x08, 0x01, 0xFF, 0x01, 0xA0, + 0x10, 0x00, 0x01, 0x6F, 0x01, 0xFE, 0x01, 0x10, 0x0F, 0x00, 0x01, 0x05, + 0x01, 0xFF, 0x01, 0xE2, 0x10, 0x00, 0x01, 0x5F, 0x01, 0xFF, 0x01, 0x30, + 0x0F, 0x00, 0x01, 0x05, 0x01, 0xFF, 0x01, 0xE3, 0x10, 0x00, 0x01, 0x6F, + 0x01, 0xFE, 0x01, 0x20, 0x0F, 0x00, 0x01, 0x08, 0x01, 0xFF, 0x01, 0xD1, + 0x10, 0x00, 0x01, 0xAF, 0x01, 0xFD, 0x01, 0x43, 0x03, 0x33, 0x0C, 0x00, + 0x01, 0x01, 0x06, 0xFF, 0x0C, 0x00, 0x01, 0x01, 0x06, 0xFF, 0x0D, 0x00, + 0x06, 0x22, 0xFF, 0x00, 0xC2, 0x00, + + /* 27 SUPERSCRIPT_THREE */ + 0x88, 0x00, 0x01, 0x01, 0x01, 0x10, 0x0F, 0x00, 0x01, 0x39, 0x01, 0xCE, + 0x02, 0xFF, 0x01, 0xB5, 0x0E, 0x00, 0x01, 0x7F, 0x04, 0xFF, 0x01, 0xB0, + 0x0D, 0x00, 0x01, 0x6B, 0x01, 0x73, 0x01, 0x22, 0x01, 0x38, 0x01, 0xFF, + 0x01, 0xF9, 0x11, 0x00, 0x01, 0x5F, 0x01, 0xFF, 0x11, 0x00, 0x01, 0x0F, + 0x01, 0xFF, 0x11, 0x00, 0x01, 0x4F, 0x01, 0xFC, 0x10, 0x00, 0x01, 0x27, + 0x01, 0xFF, 0x01, 0xF3, 0x0E, 0x00, 0x01, 0x0C, 0x02, 0xFF, 0x01, 0xFA, + 0x01, 0x20, 0x0E, 0x00, 0x01, 0x0C, 0x02, 0xFF, 0x01, 0xFB, 0x01, 0x40, + 0x0E, 0x00, 0x01, 0x01, 0x01, 0x23, 0x01, 0x49, 0x01, 0xFF, 0x01, 0xF6, + 0x11, 0x00, 0x01, 0x3F, 0x01, 0xFF, 0x01, 0x10, 0x10, 0x00, 0x01, 0x0B, + 0x01, 0xFF, 0x01, 0x50, 0x10, 0x00, 0x01, 0x0A, 0x01, 0xFF, 0x01, 0x60, + 0x10, 0x00, 0x01, 0x1E, 0x01, 0xFF, 0x01, 0x40, 0x0C, 0x00, 0x01, 0xA4, + 0x02, 0x00, 0x01, 0x05, 0x01, 0xDF, 0x01, 0xFD, 0x0D, 0x00, 0x02, 0xFF, + 0x01, 0xDE, 0x02, 0xFF, 0x01, 0xE3, 0x0D, 0x00, 0x01, 0xAE, 0x03, 0xFF, + 0x01, 0xE9, 0x01, 0x10, 0x0E, 0x00, 0x01, 0x24, 0x01, 0x55, 0x01, 0x52, + 0xFF, 0x00, 0xC4, 0x00, +#endif // TOUCH_UI_UTF8_SUPERSCRIPTS + +#if ENABLED(TOUCH_UI_UTF8_ORDINALS) + /* 28 MASCULINE_ORDINAL */ + 0x89, 0x00, 0x01, 0x01, 0x01, 0x10, 0x0F, 0x00, 0x01, 0x01, 0x01, 0x8D, + 0x02, 0xFF, 0x01, 0xB4, 0x0E, 0x00, 0x01, 0x4F, 0x04, 0xFF, 0x01, 0xA0, + 0x0C, 0x00, 0x01, 0x04, 0x01, 0xFF, 0x01, 0xFC, 0x01, 0x63, 0x01, 0x48, + 0x01, 0xFF, 0x01, 0xFB, 0x0C, 0x00, 0x01, 0x0E, 0x01, 0xFF, 0x01, 0xA0, + 0x02, 0x00, 0x01, 0x3F, 0x01, 0xFF, 0x01, 0x60, 0x0B, 0x00, 0x01, 0x6F, + 0x01, 0xFE, 0x03, 0x00, 0x01, 0x07, 0x01, 0xFF, 0x01, 0xD0, 0x0B, 0x00, + 0x01, 0xBF, 0x01, 0xF7, 0x04, 0x00, 0x01, 0xFF, 0x01, 0xF2, 0x0B, 0x00, + 0x01, 0xEF, 0x01, 0xF3, 0x04, 0x00, 0x01, 0xCF, 0x01, 0xF6, 0x0B, 0x00, + 0x01, 0xFF, 0x01, 0xF1, 0x04, 0x00, 0x01, 0xAF, 0x01, 0xF7, 0x0B, 0x00, + 0x01, 0xFF, 0x01, 0xF1, 0x04, 0x00, 0x01, 0xAF, 0x01, 0xF7, 0x0B, 0x00, + 0x01, 0xFF, 0x01, 0xF2, 0x04, 0x00, 0x01, 0xBF, 0x01, 0xF6, 0x0B, 0x00, + 0x01, 0xCF, 0x01, 0xF6, 0x04, 0x00, 0x01, 0xEF, 0x01, 0xF4, 0x0B, 0x00, + 0x01, 0x8F, 0x01, 0xFC, 0x03, 0x00, 0x01, 0x04, 0x01, 0xFF, 0x01, 0xF0, + 0x0B, 0x00, 0x01, 0x2F, 0x01, 0xFF, 0x01, 0x60, 0x02, 0x00, 0x01, 0x1D, + 0x01, 0xFF, 0x01, 0x90, 0x0B, 0x00, 0x01, 0x08, 0x01, 0xFF, 0x01, 0xF8, + 0x01, 0x10, 0x01, 0x04, 0x01, 0xDF, 0x01, 0xFE, 0x01, 0x10, 0x0C, 0x00, + 0x01, 0xAF, 0x04, 0xFF, 0x01, 0xE3, 0x0D, 0x00, 0x01, 0x05, 0x01, 0xDF, + 0x02, 0xFF, 0x01, 0xFA, 0x01, 0x10, 0x0E, 0x00, 0x01, 0x02, 0x01, 0x56, + 0x01, 0x64, 0x21, 0x00, 0x01, 0x16, 0x06, 0x66, 0x01, 0x40, 0x0B, 0x00, + 0x01, 0x3F, 0x06, 0xFF, 0x01, 0xB0, 0x0B, 0x00, 0x01, 0x3F, 0x06, 0xFF, + 0x01, 0xB0, 0x0B, 0x00, 0x01, 0x01, 0x06, 0x11, 0xFF, 0x00, 0x75, 0x00, + + /* 29 FEMININE_ORDINAL */ + 0x89, 0x00, 0x01, 0x12, 0x01, 0x10, 0x0F, 0x00, 0x01, 0x49, 0x01, 0xDF, + 0x02, 0xFF, 0x01, 0xB4, 0x0D, 0x00, 0x01, 0x07, 0x05, 0xFF, 0x01, 0xA0, + 0x0C, 0x00, 0x01, 0x07, 0x01, 0xFC, 0x01, 0x74, 0x01, 0x33, 0x01, 0x59, + 0x01, 0xFF, 0x01, 0xF8, 0x0C, 0x00, 0x01, 0x03, 0x01, 0x20, 0x03, 0x00, + 0x01, 0x3F, 0x01, 0xFF, 0x01, 0x10, 0x10, 0x00, 0x01, 0x09, 0x01, 0xFF, + 0x01, 0x50, 0x0E, 0x00, 0x01, 0x01, 0x01, 0x11, 0x01, 0x16, 0x01, 0xFF, + 0x01, 0x80, 0x0C, 0x00, 0x01, 0x05, 0x01, 0xAE, 0x04, 0xFF, 0x01, 0x90, + 0x0B, 0x00, 0x01, 0x01, 0x01, 0xCF, 0x05, 0xFF, 0x01, 0xA0, 0x0B, 0x00, + 0x01, 0x0D, 0x01, 0xFF, 0x01, 0xE9, 0x01, 0x65, 0x01, 0x44, 0x01, 0x48, + 0x01, 0xFF, 0x01, 0xA0, 0x0B, 0x00, 0x01, 0x5F, 0x01, 0xFD, 0x01, 0x10, + 0x02, 0x00, 0x01, 0x06, 0x01, 0xFF, 0x01, 0xA0, 0x0B, 0x00, 0x01, 0x9F, + 0x01, 0xF6, 0x03, 0x00, 0x01, 0x09, 0x01, 0xFF, 0x01, 0xA0, 0x0B, 0x00, + 0x01, 0xAF, 0x01, 0xF5, 0x03, 0x00, 0x01, 0x0E, 0x01, 0xFF, 0x01, 0xA0, + 0x0B, 0x00, 0x01, 0x9F, 0x01, 0xFA, 0x03, 0x00, 0x01, 0xAF, 0x01, 0xFF, + 0x01, 0xA0, 0x0B, 0x00, 0x01, 0x4F, 0x01, 0xFF, 0x01, 0xA2, 0x01, 0x00, + 0x01, 0x3B, 0x02, 0xFF, 0x01, 0xA0, 0x0B, 0x00, 0x01, 0x0A, 0x04, 0xFF, + 0x01, 0xE7, 0x01, 0xFF, 0x01, 0xA0, 0x0C, 0x00, 0x01, 0x8F, 0x02, 0xFF, + 0x01, 0xF9, 0x01, 0x15, 0x01, 0xFF, 0x01, 0xA0, 0x0D, 0x00, 0x01, 0x46, + 0x01, 0x64, 0x02, 0x00, 0x01, 0x11, 0x1F, 0x00, 0x01, 0x16, 0x06, 0x66, + 0x01, 0x40, 0x0B, 0x00, 0x01, 0x3F, 0x06, 0xFF, 0x01, 0xB0, 0x0B, 0x00, + 0x01, 0x3F, 0x06, 0xFF, 0x01, 0xB0, 0x0B, 0x00, 0x01, 0x01, 0x06, 0x11, + 0xFF, 0x00, 0x75, 0x00, +#endif // TOUCH_UI_UTF8_ORDINALS + +#if ENABLED(TOUCH_UI_UTF8_COPYRIGHT) + /* 30 COPYRIGHT_SIGN */ + 0xA0, 0x00, 0x01, 0x01, 0x01, 0x45, 0x01, 0x76, 0x01, 0x43, 0x0E, 0x00, + 0x01, 0x28, 0x01, 0xDF, 0x03, 0xFF, 0x01, 0xE9, 0x01, 0x40, 0x0B, 0x00, + 0x01, 0x19, 0x02, 0xFF, 0x01, 0xDB, 0x01, 0xAB, 0x01, 0xCE, 0x01, 0xFF, + 0x01, 0xFB, 0x01, 0x30, 0x09, 0x00, 0x01, 0x03, 0x01, 0xEF, 0x01, 0xFB, + 0x01, 0x50, 0x03, 0x00, 0x01, 0x38, 0x01, 0xFF, 0x01, 0xF7, 0x09, 0x00, + 0x01, 0x6F, 0x01, 0xFC, 0x01, 0x30, 0x05, 0x00, 0x01, 0x19, 0x01, 0xFF, + 0x01, 0xA0, 0x07, 0x00, 0x01, 0x05, 0x01, 0xFF, 0x01, 0xA0, 0x07, 0x00, + 0x01, 0x5F, 0x01, 0xFB, 0x07, 0x00, 0x01, 0x3F, 0x01, 0xF8, 0x03, 0x00, + 0x01, 0x46, 0x01, 0x88, 0x01, 0x65, 0x01, 0x10, 0x01, 0x00, 0x01, 0x03, + 0x01, 0xFF, 0x01, 0x80, 0x06, 0x00, 0x01, 0xEF, 0x01, 0xA0, 0x01, 0x00, + 0x01, 0x01, 0x01, 0x9F, 0x03, 0xFF, 0x01, 0xFC, 0x01, 0x60, 0x01, 0x00, + 0x01, 0x4F, 0x01, 0xF4, 0x05, 0x00, 0x01, 0x08, 0x01, 0xFD, 0x02, 0x00, + 0x01, 0x4E, 0x02, 0xFF, 0x01, 0xED, 0x01, 0xEF, 0x01, 0xFF, 0x01, 0xB0, + 0x01, 0x00, 0x01, 0x08, 0x01, 0xFD, 0x05, 0x00, 0x01, 0x1F, 0x01, 0xF4, + 0x01, 0x00, 0x01, 0x04, 0x01, 0xFF, 0x01, 0xFE, 0x01, 0x61, 0x01, 0x00, + 0x01, 0x01, 0x01, 0x4A, 0x01, 0xA0, 0x02, 0x00, 0x01, 0xEF, 0x01, 0x60, + 0x04, 0x00, 0x01, 0x6F, 0x01, 0xC0, 0x01, 0x00, 0x01, 0x0E, 0x01, 0xFF, + 0x01, 0xC1, 0x07, 0x00, 0x01, 0x7F, 0x01, 0xB0, 0x04, 0x00, 0x01, 0xBF, + 0x01, 0x60, 0x01, 0x00, 0x01, 0x7F, 0x01, 0xFF, 0x01, 0x10, 0x07, 0x00, + 0x01, 0x1F, 0x01, 0xF0, 0x04, 0x00, 0x01, 0xFF, 0x01, 0x20, 0x01, 0x00, + 0x01, 0xDF, 0x01, 0xF9, 0x08, 0x00, 0x01, 0x0D, 0x01, 0xF4, 0x03, 0x00, + 0x01, 0x01, 0x01, 0xFE, 0x01, 0x00, 0x01, 0x01, 0x01, 0xFF, 0x01, 0xF4, + 0x08, 0x00, 0x01, 0x0A, 0x01, 0xF6, 0x03, 0x00, 0x01, 0x03, 0x01, 0xFD, + 0x01, 0x00, 0x01, 0x02, 0x01, 0xFF, 0x01, 0xF1, 0x08, 0x00, 0x01, 0x08, + 0x01, 0xF8, 0x03, 0x00, 0x01, 0x04, 0x01, 0xFC, 0x01, 0x00, 0x01, 0x03, + 0x01, 0xFF, 0x01, 0xF0, 0x08, 0x00, 0x01, 0x07, 0x01, 0xF9, 0x03, 0x00, + 0x01, 0x03, 0x01, 0xFD, 0x01, 0x00, 0x01, 0x02, 0x01, 0xFF, 0x01, 0xF1, + 0x08, 0x00, 0x01, 0x08, 0x01, 0xF8, 0x03, 0x00, 0x01, 0x01, 0x01, 0xFE, + 0x01, 0x00, 0x01, 0x01, 0x01, 0xFF, 0x01, 0xF3, 0x08, 0x00, 0x01, 0x09, + 0x01, 0xF7, 0x04, 0x00, 0x01, 0xFF, 0x01, 0x10, 0x01, 0x00, 0x01, 0xDF, + 0x01, 0xF8, 0x08, 0x00, 0x01, 0x0C, 0x01, 0xF5, 0x04, 0x00, 0x01, 0xBF, + 0x01, 0x60, 0x01, 0x00, 0x01, 0x8F, 0x01, 0xFE, 0x01, 0x10, 0x07, 0x00, + 0x01, 0x1F, 0x01, 0xF1, 0x04, 0x00, 0x01, 0x6F, 0x01, 0xB0, 0x01, 0x00, + 0x01, 0x1F, 0x01, 0xFF, 0x01, 0xB0, 0x07, 0x00, 0x01, 0x6F, 0x01, 0xC0, + 0x04, 0x00, 0x01, 0x1F, 0x01, 0xF4, 0x01, 0x00, 0x01, 0x05, 0x01, 0xFF, + 0x01, 0xFD, 0x01, 0x50, 0x02, 0x00, 0x01, 0x29, 0x01, 0xA0, 0x02, 0x00, + 0x01, 0xEF, 0x01, 0x60, 0x04, 0x00, 0x01, 0x08, 0x01, 0xFD, 0x02, 0x00, + 0x01, 0x6F, 0x02, 0xFF, 0x01, 0xDB, 0x01, 0xCE, 0x01, 0xFF, 0x01, 0xB0, + 0x01, 0x00, 0x01, 0x07, 0x01, 0xFD, 0x05, 0x00, 0x01, 0x01, 0x01, 0xEF, + 0x01, 0x90, 0x01, 0x00, 0x01, 0x02, 0x01, 0xBF, 0x03, 0xFF, 0x01, 0xFE, + 0x01, 0x70, 0x01, 0x00, 0x01, 0x4F, 0x01, 0xF4, 0x06, 0x00, 0x01, 0x4F, + 0x01, 0xF7, 0x02, 0x00, 0x01, 0x01, 0x01, 0x58, 0x01, 0x9A, 0x01, 0x86, + 0x01, 0x30, 0x01, 0x00, 0x01, 0x02, 0x01, 0xEF, 0x01, 0x80, 0x06, 0x00, + 0x01, 0x06, 0x01, 0xFF, 0x01, 0x90, 0x07, 0x00, 0x01, 0x4F, 0x01, 0xFB, + 0x08, 0x00, 0x01, 0x6F, 0x01, 0xFC, 0x01, 0x30, 0x05, 0x00, 0x01, 0x18, + 0x01, 0xFF, 0x01, 0xB0, 0x08, 0x00, 0x01, 0x04, 0x01, 0xEF, 0x01, 0xFA, + 0x01, 0x40, 0x03, 0x00, 0x01, 0x27, 0x01, 0xEF, 0x01, 0xF8, 0x0A, 0x00, + 0x01, 0x19, 0x02, 0xFF, 0x01, 0xCA, 0x01, 0x9A, 0x01, 0xBE, 0x01, 0xFF, + 0x01, 0xFC, 0x01, 0x30, 0x0B, 0x00, 0x01, 0x29, 0x01, 0xDF, 0x03, 0xFF, + 0x01, 0xFA, 0x01, 0x40, 0x0D, 0x00, 0x01, 0x02, 0x01, 0x46, 0x01, 0x76, + 0x01, 0x53, 0xC5, 0x00, + + /* 31 REGISTERED_SIGN */ + 0xA0, 0x00, 0x01, 0x02, 0x01, 0x46, 0x01, 0x76, 0x01, 0x53, 0x0E, 0x00, + 0x01, 0x28, 0x01, 0xDF, 0x03, 0xFF, 0x01, 0xEA, 0x01, 0x40, 0x0B, 0x00, + 0x01, 0x19, 0x02, 0xFF, 0x01, 0xCB, 0x01, 0x9A, 0x01, 0xCE, 0x01, 0xFF, + 0x01, 0xFC, 0x01, 0x30, 0x09, 0x00, 0x01, 0x04, 0x01, 0xEF, 0x01, 0xFA, + 0x01, 0x40, 0x03, 0x00, 0x01, 0x38, 0x01, 0xFF, 0x01, 0xF8, 0x09, 0x00, + 0x01, 0x6F, 0x01, 0xFC, 0x01, 0x30, 0x05, 0x00, 0x01, 0x18, 0x01, 0xFF, + 0x01, 0xA0, 0x07, 0x00, 0x01, 0x06, 0x01, 0xFF, 0x01, 0x90, 0x07, 0x00, + 0x01, 0x4F, 0x01, 0xFB, 0x07, 0x00, 0x01, 0x3F, 0x01, 0xF7, 0x01, 0x00, + 0x01, 0x13, 0x02, 0x33, 0x01, 0x32, 0x03, 0x00, 0x01, 0x02, 0x01, 0xFF, + 0x01, 0x80, 0x06, 0x00, 0x01, 0xEF, 0x01, 0xA0, 0x01, 0x00, 0x01, 0x7F, + 0x03, 0xFF, 0x01, 0xFD, 0x01, 0x81, 0x02, 0x00, 0x01, 0x4F, 0x01, 0xF5, + 0x05, 0x00, 0x01, 0x08, 0x01, 0xFD, 0x02, 0x00, 0x01, 0x7F, 0x01, 0xFF, + 0x01, 0xDD, 0x01, 0xEF, 0x01, 0xFF, 0x01, 0xFE, 0x01, 0x30, 0x01, 0x00, + 0x01, 0x08, 0x01, 0xFE, 0x05, 0x00, 0x01, 0x1F, 0x01, 0xF4, 0x02, 0x00, + 0x01, 0x7F, 0x01, 0xFA, 0x02, 0x00, 0x01, 0x3C, 0x01, 0xFF, 0x01, 0xD0, + 0x02, 0x00, 0x01, 0xEF, 0x01, 0x60, 0x04, 0x00, 0x01, 0x6F, 0x01, 0xC0, + 0x02, 0x00, 0x01, 0x7F, 0x01, 0xFA, 0x02, 0x00, 0x01, 0x02, 0x01, 0xFF, + 0x01, 0xF3, 0x02, 0x00, 0x01, 0x7F, 0x01, 0xB0, 0x04, 0x00, 0x01, 0xBF, + 0x01, 0x60, 0x02, 0x00, 0x01, 0x7F, 0x01, 0xFA, 0x03, 0x00, 0x01, 0xFF, + 0x01, 0xF4, 0x02, 0x00, 0x01, 0x1F, 0x01, 0xF0, 0x04, 0x00, 0x01, 0xFF, + 0x01, 0x10, 0x02, 0x00, 0x01, 0x7F, 0x01, 0xFA, 0x03, 0x00, 0x01, 0xFF, + 0x01, 0xF2, 0x02, 0x00, 0x01, 0x0C, 0x01, 0xF5, 0x03, 0x00, 0x01, 0x01, + 0x01, 0xFE, 0x03, 0x00, 0x01, 0x7F, 0x01, 0xFA, 0x02, 0x00, 0x01, 0x08, + 0x01, 0xFF, 0x01, 0xE0, 0x02, 0x00, 0x01, 0x0A, 0x01, 0xF6, 0x03, 0x00, + 0x01, 0x03, 0x01, 0xFD, 0x03, 0x00, 0x01, 0x7F, 0x01, 0xFD, 0x01, 0x88, + 0x01, 0x9A, 0x01, 0xEF, 0x01, 0xFE, 0x01, 0x30, 0x02, 0x00, 0x01, 0x08, + 0x01, 0xF8, 0x03, 0x00, 0x01, 0x04, 0x01, 0xFC, 0x03, 0x00, 0x01, 0x7F, + 0x03, 0xFF, 0x01, 0xFE, 0x01, 0x91, 0x03, 0x00, 0x01, 0x07, 0x01, 0xF9, + 0x03, 0x00, 0x01, 0x03, 0x01, 0xFD, 0x03, 0x00, 0x01, 0x7F, 0x01, 0xFC, + 0x01, 0x78, 0x01, 0xDF, 0x01, 0xFD, 0x01, 0x20, 0x03, 0x00, 0x01, 0x08, + 0x01, 0xF8, 0x03, 0x00, 0x01, 0x01, 0x01, 0xFE, 0x03, 0x00, 0x01, 0x7F, + 0x01, 0xFA, 0x01, 0x00, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0xC0, 0x03, 0x00, + 0x01, 0x09, 0x01, 0xF6, 0x04, 0x00, 0x01, 0xFF, 0x01, 0x10, 0x02, 0x00, + 0x01, 0x7F, 0x01, 0xFA, 0x02, 0x00, 0x01, 0xDF, 0x01, 0xF8, 0x03, 0x00, + 0x01, 0x0C, 0x01, 0xF5, 0x04, 0x00, 0x01, 0xBF, 0x01, 0x60, 0x02, 0x00, + 0x01, 0x7F, 0x01, 0xFA, 0x02, 0x00, 0x01, 0x4F, 0x01, 0xFF, 0x01, 0x30, + 0x02, 0x00, 0x01, 0x1F, 0x01, 0xF1, 0x04, 0x00, 0x01, 0x6F, 0x01, 0xC0, + 0x02, 0x00, 0x01, 0x7F, 0x01, 0xFA, 0x02, 0x00, 0x01, 0x09, 0x01, 0xFF, + 0x01, 0xD0, 0x02, 0x00, 0x01, 0x6F, 0x01, 0xB0, 0x04, 0x00, 0x01, 0x1F, + 0x01, 0xF4, 0x02, 0x00, 0x01, 0x7F, 0x01, 0xFA, 0x02, 0x00, 0x01, 0x01, + 0x01, 0xEF, 0x01, 0xF7, 0x02, 0x00, 0x01, 0xEF, 0x01, 0x60, 0x04, 0x00, + 0x01, 0x08, 0x01, 0xFD, 0x02, 0x00, 0x01, 0x7F, 0x01, 0xFA, 0x03, 0x00, + 0x01, 0x6F, 0x01, 0xFF, 0x01, 0x20, 0x01, 0x08, 0x01, 0xFE, 0x06, 0x00, + 0x01, 0xEF, 0x01, 0xA0, 0x01, 0x00, 0x01, 0x5A, 0x01, 0xA6, 0x03, 0x00, + 0x01, 0x09, 0x01, 0xAA, 0x01, 0x60, 0x01, 0x4F, 0x01, 0xF4, 0x06, 0x00, + 0x01, 0x3F, 0x01, 0xF8, 0x08, 0x00, 0x01, 0x03, 0x01, 0xFF, 0x01, 0x80, + 0x06, 0x00, 0x01, 0x05, 0x01, 0xFF, 0x01, 0x90, 0x07, 0x00, 0x01, 0x4F, + 0x01, 0xFB, 0x08, 0x00, 0x01, 0x6F, 0x01, 0xFC, 0x01, 0x30, 0x05, 0x00, + 0x01, 0x19, 0x01, 0xFF, 0x01, 0xA0, 0x08, 0x00, 0x01, 0x04, 0x01, 0xEF, + 0x01, 0xFA, 0x01, 0x40, 0x03, 0x00, 0x01, 0x38, 0x01, 0xEF, 0x01, 0xF8, + 0x0A, 0x00, 0x01, 0x19, 0x02, 0xFF, 0x01, 0xCB, 0x01, 0x9A, 0x01, 0xCE, + 0x01, 0xFF, 0x01, 0xFC, 0x01, 0x30, 0x0B, 0x00, 0x01, 0x28, 0x01, 0xDF, + 0x03, 0xFF, 0x01, 0xEA, 0x01, 0x40, 0x0D, 0x00, 0x01, 0x02, 0x01, 0x45, + 0x01, 0x76, 0x01, 0x43, 0xC5, 0x00, +#endif // TOUCH_UI_UTF8_COPYRIGHT + +#if ENABLED(TOUCH_UI_UTF8_MATHEMATICS) + /* 32 PLUS_MINUS_SIGN */ + 0xEB, 0x00, 0x01, 0x02, 0x01, 0x77, 0x01, 0x70, 0x10, 0x00, 0x01, 0x06, + 0x01, 0xFF, 0x01, 0xF0, 0x10, 0x00, 0x01, 0x06, 0x01, 0xFF, 0x01, 0xF0, + 0x10, 0x00, 0x01, 0x06, 0x01, 0xFF, 0x01, 0xF0, 0x10, 0x00, 0x01, 0x06, + 0x01, 0xFF, 0x01, 0xF0, 0x10, 0x00, 0x01, 0x06, 0x01, 0xFF, 0x01, 0xF0, + 0x10, 0x00, 0x01, 0x06, 0x01, 0xFF, 0x01, 0xF0, 0x10, 0x00, 0x01, 0x06, + 0x01, 0xFF, 0x01, 0xF0, 0x0B, 0x00, 0x01, 0x6A, 0x04, 0xAA, 0x01, 0xAC, + 0x01, 0xFF, 0x01, 0xFA, 0x05, 0xAA, 0x01, 0x20, 0x05, 0x00, 0x01, 0x9F, + 0x0C, 0xFF, 0x01, 0x40, 0x05, 0x00, 0x01, 0x9F, 0x0C, 0xFF, 0x01, 0x40, + 0x05, 0x00, 0x01, 0x7C, 0x04, 0xCC, 0x01, 0xCD, 0x01, 0xFF, 0x01, 0xFC, + 0x05, 0xCC, 0x01, 0x30, 0x0A, 0x00, 0x01, 0x06, 0x01, 0xFF, 0x01, 0xF0, + 0x10, 0x00, 0x01, 0x06, 0x01, 0xFF, 0x01, 0xF0, 0x10, 0x00, 0x01, 0x06, + 0x01, 0xFF, 0x01, 0xF0, 0x10, 0x00, 0x01, 0x06, 0x01, 0xFF, 0x01, 0xF0, + 0x10, 0x00, 0x01, 0x06, 0x01, 0xFF, 0x01, 0xF0, 0x10, 0x00, 0x01, 0x06, + 0x01, 0xFF, 0x01, 0xF0, 0x10, 0x00, 0x01, 0x06, 0x01, 0xFF, 0x01, 0xF0, + 0x10, 0x00, 0x01, 0x03, 0x01, 0x99, 0x01, 0x90, 0x44, 0x00, 0x01, 0x9F, + 0x0C, 0xFF, 0x01, 0x30, 0x05, 0x00, 0x01, 0x9F, 0x0C, 0xFF, 0x01, 0x40, + 0x05, 0x00, 0x01, 0x9F, 0x0C, 0xFF, 0x01, 0x40, 0x05, 0x00, 0x01, 0x47, + 0x0C, 0x77, 0x01, 0x10, 0xC1, 0x00, + + /* 33 MULTIPLICATION_SIGN */ + 0xFF, 0x00, 0x0E, 0x00, 0x01, 0x09, 0x01, 0xB0, 0x07, 0x00, 0x01, 0x03, + 0x01, 0xE4, 0x08, 0x00, 0x01, 0x9F, 0x01, 0xFB, 0x07, 0x00, 0x01, 0x3E, + 0x01, 0xFF, 0x01, 0x40, 0x06, 0x00, 0x01, 0x01, 0x01, 0xEF, 0x01, 0xFF, + 0x01, 0xB0, 0x05, 0x00, 0x01, 0x03, 0x01, 0xEF, 0x01, 0xFF, 0x01, 0xA0, + 0x07, 0x00, 0x01, 0x2E, 0x01, 0xFF, 0x01, 0xFB, 0x05, 0x00, 0x01, 0x3E, + 0x01, 0xFF, 0x01, 0xFB, 0x08, 0x00, 0x01, 0x02, 0x01, 0xEF, 0x01, 0xFF, + 0x01, 0xB0, 0x03, 0x00, 0x01, 0x03, 0x01, 0xEF, 0x01, 0xFF, 0x01, 0xB0, + 0x09, 0x00, 0x01, 0x2E, 0x01, 0xFF, 0x01, 0xFB, 0x03, 0x00, 0x01, 0x3E, + 0x01, 0xFF, 0x01, 0xFB, 0x0A, 0x00, 0x01, 0x02, 0x01, 0xEF, 0x01, 0xFF, + 0x01, 0xB0, 0x01, 0x00, 0x01, 0x03, 0x01, 0xEF, 0x01, 0xFF, 0x01, 0xB0, + 0x0B, 0x00, 0x01, 0x2E, 0x01, 0xFF, 0x01, 0xFB, 0x01, 0x00, 0x01, 0x3E, + 0x01, 0xFF, 0x01, 0xFB, 0x0C, 0x00, 0x01, 0x02, 0x01, 0xEF, 0x01, 0xFF, + 0x01, 0xB3, 0x01, 0xEF, 0x01, 0xFF, 0x01, 0xB0, 0x0D, 0x00, 0x01, 0x3E, + 0x03, 0xFF, 0x01, 0xFB, 0x0E, 0x00, 0x01, 0x03, 0x01, 0xEF, 0x02, 0xFF, + 0x01, 0xB0, 0x0F, 0x00, 0x01, 0x5F, 0x02, 0xFF, 0x01, 0x10, 0x0E, 0x00, + 0x01, 0x03, 0x01, 0xEF, 0x02, 0xFF, 0x01, 0xB0, 0x0E, 0x00, 0x01, 0x3E, + 0x03, 0xFF, 0x01, 0xFB, 0x0D, 0x00, 0x01, 0x02, 0x01, 0xEF, 0x01, 0xFF, + 0x01, 0xB3, 0x01, 0xEF, 0x01, 0xFF, 0x01, 0xB0, 0x0C, 0x00, 0x01, 0x2E, + 0x01, 0xFF, 0x01, 0xFB, 0x01, 0x00, 0x01, 0x2E, 0x01, 0xFF, 0x01, 0xFB, + 0x0B, 0x00, 0x01, 0x02, 0x01, 0xEF, 0x01, 0xFF, 0x01, 0xB0, 0x01, 0x00, + 0x01, 0x02, 0x01, 0xEF, 0x01, 0xFF, 0x01, 0xB0, 0x0A, 0x00, 0x01, 0x2E, + 0x01, 0xFF, 0x01, 0xFB, 0x03, 0x00, 0x01, 0x2E, 0x01, 0xFF, 0x01, 0xFB, + 0x09, 0x00, 0x01, 0x02, 0x01, 0xEF, 0x01, 0xFF, 0x01, 0xB0, 0x03, 0x00, + 0x01, 0x02, 0x01, 0xEF, 0x01, 0xFF, 0x01, 0xB0, 0x08, 0x00, 0x01, 0x2E, + 0x01, 0xFF, 0x01, 0xFB, 0x05, 0x00, 0x01, 0x2E, 0x01, 0xFF, 0x01, 0xFB, + 0x07, 0x00, 0x01, 0x01, 0x01, 0xEF, 0x01, 0xFF, 0x01, 0xB0, 0x05, 0x00, + 0x01, 0x02, 0x01, 0xEF, 0x01, 0xFF, 0x01, 0xA0, 0x07, 0x00, 0x01, 0x8F, + 0x01, 0xFB, 0x07, 0x00, 0x01, 0x2E, 0x01, 0xFF, 0x01, 0x40, 0x07, 0x00, + 0x01, 0x09, 0x01, 0xB0, 0x07, 0x00, 0x01, 0x02, 0x01, 0xE4, 0xE9, 0x00, + + /* 34 DIVISION_SIGN */ + 0xFF, 0x00, 0x25, 0x00, 0x01, 0x17, 0x01, 0x77, 0x01, 0x76, 0x10, 0x00, + 0x01, 0x2F, 0x01, 0xFF, 0x01, 0xFC, 0x10, 0x00, 0x01, 0x2F, 0x01, 0xFF, + 0x01, 0xFC, 0x10, 0x00, 0x01, 0x2F, 0x01, 0xFF, 0x01, 0xFC, 0x10, 0x00, + 0x01, 0x2F, 0x01, 0xFF, 0x01, 0xFC, 0x10, 0x00, 0x01, 0x17, 0x01, 0x77, + 0x01, 0x76, 0x31, 0x00, 0x01, 0x24, 0x0C, 0x44, 0x01, 0x10, 0x05, 0x00, + 0x01, 0x9F, 0x0C, 0xFF, 0x01, 0x40, 0x05, 0x00, 0x01, 0x9F, 0x0C, 0xFF, + 0x01, 0x40, 0x05, 0x00, 0x01, 0x9F, 0x0C, 0xFF, 0x01, 0x40, 0x05, 0x00, + 0x01, 0x12, 0x0C, 0x22, 0x31, 0x00, 0x01, 0x18, 0x01, 0x88, 0x01, 0x87, + 0x10, 0x00, 0x01, 0x2F, 0x01, 0xFF, 0x01, 0xFC, 0x10, 0x00, 0x01, 0x2F, + 0x01, 0xFF, 0x01, 0xFC, 0x10, 0x00, 0x01, 0x2F, 0x01, 0xFF, 0x01, 0xFC, + 0x10, 0x00, 0x01, 0x2F, 0x01, 0xFF, 0x01, 0xFC, 0x10, 0x00, 0x01, 0x16, + 0x01, 0x66, 0x01, 0x65, 0xFF, 0x00, 0x01, 0x00, +#endif // TOUCH_UI_UTF8_MATHEMATICS + +#if ENABLED(TOUCH_UI_UTF8_FRACTIONS) + /* 35 FRACTION_QUARTER */ + 0x92, 0x00, 0x01, 0x01, 0x01, 0x44, 0x01, 0x40, 0x04, 0x00, 0x01, 0x04, + 0x01, 0x79, 0x01, 0xCE, 0x01, 0xEE, 0x01, 0x20, 0x07, 0x00, 0x01, 0x0A, + 0x01, 0xFF, 0x01, 0x90, 0x04, 0x00, 0x01, 0x3F, 0x03, 0xFF, 0x01, 0x20, + 0x07, 0x00, 0x01, 0x3F, 0x01, 0xFE, 0x01, 0x10, 0x04, 0x00, 0x01, 0x3F, + 0x01, 0xDB, 0x01, 0x8D, 0x01, 0xFF, 0x01, 0x20, 0x07, 0x00, 0x01, 0xDF, + 0x01, 0xF5, 0x05, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x0B, 0x01, 0xFF, + 0x01, 0x20, 0x06, 0x00, 0x01, 0x07, 0x01, 0xFF, 0x01, 0xC0, 0x07, 0x00, + 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x20, 0x06, 0x00, 0x01, 0x1F, 0x01, 0xFF, + 0x01, 0x20, 0x07, 0x00, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x20, 0x06, 0x00, + 0x01, 0xAF, 0x01, 0xF8, 0x08, 0x00, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x20, + 0x05, 0x00, 0x01, 0x04, 0x01, 0xFF, 0x01, 0xE1, 0x08, 0x00, 0x01, 0x0B, + 0x01, 0xFF, 0x01, 0x20, 0x05, 0x00, 0x01, 0x0D, 0x01, 0xFF, 0x01, 0x50, + 0x08, 0x00, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x20, 0x05, 0x00, 0x01, 0x7F, + 0x01, 0xFC, 0x09, 0x00, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x20, 0x04, 0x00, + 0x01, 0x01, 0x01, 0xFF, 0x01, 0xF2, 0x09, 0x00, 0x01, 0x0B, 0x01, 0xFF, + 0x01, 0x20, 0x04, 0x00, 0x01, 0x0A, 0x01, 0xFF, 0x01, 0x80, 0x09, 0x00, + 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x20, 0x04, 0x00, 0x01, 0x4F, 0x01, 0xFE, + 0x0A, 0x00, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x20, 0x04, 0x00, 0x01, 0xDF, + 0x01, 0xF5, 0x0A, 0x00, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x20, 0x03, 0x00, + 0x01, 0x07, 0x01, 0xFF, 0x01, 0xB0, 0x04, 0x00, 0x01, 0x37, 0x01, 0x77, + 0x02, 0x00, 0x01, 0x04, 0x01, 0x55, 0x01, 0x5D, 0x01, 0xFF, 0x01, 0x75, + 0x01, 0x55, 0x01, 0x10, 0x01, 0x00, 0x01, 0x1F, 0x01, 0xFF, 0x01, 0x20, + 0x03, 0x00, 0x01, 0x01, 0x01, 0xEF, 0x01, 0xFF, 0x02, 0x00, 0x01, 0x0D, + 0x05, 0xFF, 0x01, 0x40, 0x01, 0x00, 0x01, 0xAF, 0x01, 0xF8, 0x04, 0x00, + 0x01, 0x0C, 0x02, 0xFF, 0x02, 0x00, 0x01, 0x0C, 0x05, 0xEE, 0x01, 0x40, + 0x01, 0x04, 0x01, 0xFF, 0x01, 0xE0, 0x04, 0x00, 0x01, 0x8F, 0x01, 0xBE, + 0x01, 0xFF, 0x09, 0x00, 0x01, 0x0D, 0x01, 0xFF, 0x01, 0x50, 0x03, 0x00, + 0x01, 0x04, 0x01, 0xFE, 0x01, 0x1E, 0x01, 0xFF, 0x09, 0x00, 0x01, 0x7F, + 0x01, 0xFC, 0x04, 0x00, 0x01, 0x1E, 0x01, 0xF4, 0x01, 0x0E, 0x01, 0xFF, + 0x08, 0x00, 0x01, 0x01, 0x01, 0xFF, 0x01, 0xF2, 0x04, 0x00, 0x01, 0xBF, + 0x01, 0x80, 0x01, 0x0E, 0x01, 0xFF, 0x08, 0x00, 0x01, 0x0B, 0x01, 0xFF, + 0x01, 0x80, 0x03, 0x00, 0x01, 0x08, 0x01, 0xFC, 0x01, 0x00, 0x01, 0x0E, + 0x01, 0xFF, 0x08, 0x00, 0x01, 0x4F, 0x01, 0xFE, 0x04, 0x00, 0x01, 0x4F, + 0x01, 0xE1, 0x01, 0x00, 0x01, 0x0E, 0x01, 0xFF, 0x08, 0x00, 0x01, 0xDF, + 0x01, 0xF5, 0x03, 0x00, 0x01, 0x01, 0x01, 0xEF, 0x01, 0x40, 0x01, 0x00, + 0x01, 0x0E, 0x01, 0xFF, 0x07, 0x00, 0x01, 0x07, 0x01, 0xFF, 0x01, 0xB0, + 0x03, 0x00, 0x01, 0x0B, 0x01, 0xF8, 0x02, 0x00, 0x01, 0x0E, 0x01, 0xFF, + 0x07, 0x00, 0x01, 0x2F, 0x01, 0xFF, 0x01, 0x20, 0x03, 0x00, 0x01, 0x3F, + 0x01, 0xF8, 0x02, 0x88, 0x01, 0x8F, 0x01, 0xFF, 0x01, 0x88, 0x06, 0x00, + 0x01, 0xBF, 0x01, 0xF8, 0x04, 0x00, 0x01, 0x4F, 0x06, 0xFF, 0x05, 0x00, + 0x01, 0x04, 0x01, 0xFF, 0x01, 0xE0, 0x04, 0x00, 0x01, 0x2A, 0x03, 0xAA, + 0x01, 0xAF, 0x01, 0xFF, 0x01, 0xAA, 0x05, 0x00, 0x01, 0x0D, 0x01, 0xFF, + 0x01, 0x50, 0x08, 0x00, 0x01, 0x0E, 0x01, 0xFF, 0x06, 0x00, 0x01, 0x8F, + 0x01, 0xFB, 0x09, 0x00, 0x01, 0x0E, 0x01, 0xFF, 0x05, 0x00, 0x01, 0x02, + 0x01, 0xFF, 0x01, 0xF2, 0x09, 0x00, 0x01, 0x0E, 0x01, 0xFF, 0x05, 0x00, + 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x80, 0x09, 0x00, 0x01, 0x05, 0x01, 0x66, + 0xBF, 0x00, + + /* 36 FRACTION_HALF */ + 0x92, 0x00, 0x01, 0x01, 0x01, 0x44, 0x01, 0x40, 0x04, 0x00, 0x01, 0x04, + 0x01, 0x7A, 0x01, 0xCE, 0x01, 0xEE, 0x01, 0x20, 0x07, 0x00, 0x01, 0x0A, + 0x01, 0xFF, 0x01, 0x80, 0x04, 0x00, 0x01, 0x3F, 0x03, 0xFF, 0x01, 0x20, + 0x07, 0x00, 0x01, 0x4F, 0x01, 0xFE, 0x05, 0x00, 0x01, 0x3F, 0x01, 0xDA, + 0x01, 0x7D, 0x01, 0xFF, 0x01, 0x20, 0x07, 0x00, 0x01, 0xDF, 0x01, 0xF5, + 0x07, 0x00, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x20, 0x06, 0x00, 0x01, 0x07, + 0x01, 0xFF, 0x01, 0xC0, 0x07, 0x00, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x20, + 0x06, 0x00, 0x01, 0x1F, 0x01, 0xFF, 0x01, 0x20, 0x07, 0x00, 0x01, 0x0B, + 0x01, 0xFF, 0x01, 0x20, 0x06, 0x00, 0x01, 0xAF, 0x01, 0xF8, 0x08, 0x00, + 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x20, 0x05, 0x00, 0x01, 0x04, 0x01, 0xFF, + 0x01, 0xE0, 0x08, 0x00, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x20, 0x05, 0x00, + 0x01, 0x0D, 0x01, 0xFF, 0x01, 0x50, 0x08, 0x00, 0x01, 0x0B, 0x01, 0xFF, + 0x01, 0x20, 0x05, 0x00, 0x01, 0x7F, 0x01, 0xFC, 0x09, 0x00, 0x01, 0x0B, + 0x01, 0xFF, 0x01, 0x20, 0x04, 0x00, 0x01, 0x01, 0x01, 0xFF, 0x01, 0xF2, + 0x09, 0x00, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x20, 0x04, 0x00, 0x01, 0x0A, + 0x01, 0xFF, 0x01, 0x80, 0x09, 0x00, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x20, + 0x04, 0x00, 0x01, 0x4F, 0x01, 0xFE, 0x0A, 0x00, 0x01, 0x0B, 0x01, 0xFF, + 0x01, 0x20, 0x04, 0x00, 0x01, 0xDF, 0x01, 0xF5, 0x0A, 0x00, 0x01, 0x0B, + 0x01, 0xFF, 0x01, 0x20, 0x03, 0x00, 0x01, 0x07, 0x01, 0xFF, 0x01, 0xB0, + 0x01, 0x00, 0x01, 0x04, 0x01, 0x8A, 0x01, 0xCC, 0x01, 0xA7, 0x01, 0x10, + 0x02, 0x00, 0x01, 0x04, 0x01, 0x55, 0x01, 0x5D, 0x01, 0xFF, 0x01, 0x75, + 0x01, 0x55, 0x01, 0x10, 0x01, 0x00, 0x01, 0x2F, 0x01, 0xFF, 0x01, 0x20, + 0x01, 0x06, 0x04, 0xFF, 0x01, 0xF7, 0x02, 0x00, 0x01, 0x0D, 0x05, 0xFF, + 0x01, 0x40, 0x01, 0x00, 0x01, 0xBF, 0x01, 0xF8, 0x01, 0x00, 0x01, 0x08, + 0x01, 0xFF, 0x01, 0xA7, 0x01, 0x68, 0x01, 0xDF, 0x01, 0xFF, 0x01, 0x70, + 0x01, 0x00, 0x01, 0x0B, 0x05, 0xDD, 0x01, 0x40, 0x01, 0x04, 0x01, 0xFF, + 0x01, 0xE0, 0x01, 0x00, 0x01, 0x05, 0x01, 0x60, 0x02, 0x00, 0x01, 0x08, + 0x01, 0xFF, 0x01, 0xF1, 0x08, 0x00, 0x01, 0x0D, 0x01, 0xFF, 0x01, 0x50, + 0x06, 0x00, 0x01, 0xEF, 0x01, 0xF4, 0x08, 0x00, 0x01, 0x7F, 0x01, 0xFB, + 0x07, 0x00, 0x01, 0xCF, 0x01, 0xF3, 0x07, 0x00, 0x01, 0x02, 0x01, 0xFF, + 0x01, 0xF2, 0x06, 0x00, 0x01, 0x02, 0x01, 0xFF, 0x01, 0xE0, 0x07, 0x00, + 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x80, 0x06, 0x00, 0x01, 0x0D, 0x01, 0xFF, + 0x01, 0x50, 0x07, 0x00, 0x01, 0x4F, 0x01, 0xFE, 0x07, 0x00, 0x01, 0xAF, + 0x01, 0xFA, 0x08, 0x00, 0x01, 0xDF, 0x01, 0xF5, 0x06, 0x00, 0x01, 0x09, + 0x01, 0xFF, 0x01, 0xC0, 0x07, 0x00, 0x01, 0x08, 0x01, 0xFF, 0x01, 0xB0, + 0x06, 0x00, 0x01, 0x8F, 0x01, 0xFD, 0x01, 0x10, 0x07, 0x00, 0x01, 0x2F, + 0x01, 0xFF, 0x01, 0x20, 0x05, 0x00, 0x01, 0x09, 0x01, 0xFF, 0x01, 0xC1, + 0x08, 0x00, 0x01, 0xBF, 0x01, 0xF8, 0x06, 0x00, 0x01, 0xAF, 0x01, 0xFB, + 0x08, 0x00, 0x01, 0x05, 0x01, 0xFF, 0x01, 0xE0, 0x05, 0x00, 0x01, 0x0B, + 0x01, 0xFF, 0x01, 0xA0, 0x08, 0x00, 0x01, 0x0D, 0x01, 0xFF, 0x01, 0x50, + 0x04, 0x00, 0x01, 0x01, 0x01, 0xCF, 0x01, 0xF9, 0x09, 0x00, 0x01, 0x8F, + 0x01, 0xFB, 0x05, 0x00, 0x01, 0x09, 0x01, 0xFF, 0x01, 0xFE, 0x03, 0xEE, + 0x01, 0xE6, 0x04, 0x00, 0x01, 0x02, 0x01, 0xFF, 0x01, 0xF2, 0x05, 0x00, + 0x01, 0x0A, 0x05, 0xFF, 0x01, 0xF7, 0x04, 0x00, 0x01, 0x0A, 0x01, 0xEE, + 0x01, 0x70, 0x05, 0x00, 0x01, 0x04, 0x05, 0x66, 0x01, 0x62, 0xBE, 0x00, + + /* 37 FRACTION_THREE_FOURTHS */ + 0x87, 0x00, 0x01, 0x02, 0x01, 0x34, 0x01, 0x42, 0x08, 0x00, 0x01, 0x01, + 0x01, 0x55, 0x01, 0x50, 0x04, 0x00, 0x01, 0x4C, 0x03, 0xFF, 0x01, 0xE9, + 0x01, 0x10, 0x06, 0x00, 0x01, 0x0A, 0x01, 0xFF, 0x01, 0x80, 0x04, 0x00, + 0x01, 0x7F, 0x01, 0xFF, 0x01, 0xFE, 0x02, 0xFF, 0x01, 0xE2, 0x06, 0x00, + 0x01, 0x4F, 0x01, 0xFE, 0x05, 0x00, 0x01, 0x47, 0x01, 0x30, 0x01, 0x00, + 0x01, 0x05, 0x01, 0xEF, 0x01, 0xFB, 0x06, 0x00, 0x01, 0xDF, 0x01, 0xF5, + 0x09, 0x00, 0x01, 0x3F, 0x01, 0xFF, 0x05, 0x00, 0x01, 0x07, 0x01, 0xFF, + 0x01, 0xB0, 0x09, 0x00, 0x01, 0x1F, 0x01, 0xFF, 0x05, 0x00, 0x01, 0x2F, + 0x01, 0xFF, 0x01, 0x20, 0x09, 0x00, 0x01, 0x6F, 0x01, 0xFB, 0x05, 0x00, + 0x01, 0xBF, 0x01, 0xF8, 0x07, 0x00, 0x01, 0x03, 0x01, 0x44, 0x01, 0x5A, + 0x01, 0xFF, 0x01, 0xD1, 0x04, 0x00, 0x01, 0x04, 0x01, 0xFF, 0x01, 0xE0, + 0x07, 0x00, 0x01, 0x0C, 0x02, 0xFF, 0x01, 0xE7, 0x05, 0x00, 0x01, 0x0D, + 0x01, 0xFF, 0x01, 0x50, 0x07, 0x00, 0x01, 0x0B, 0x01, 0xEF, 0x01, 0xFF, + 0x01, 0xFE, 0x01, 0x70, 0x04, 0x00, 0x01, 0x7F, 0x01, 0xFB, 0x0A, 0x00, + 0x01, 0x16, 0x01, 0xDF, 0x01, 0xF9, 0x03, 0x00, 0x01, 0x02, 0x01, 0xFF, + 0x01, 0xF2, 0x0B, 0x00, 0x01, 0x1E, 0x01, 0xFF, 0x01, 0x20, 0x02, 0x00, + 0x01, 0x0B, 0x01, 0xFF, 0x01, 0x80, 0x0B, 0x00, 0x01, 0x0A, 0x01, 0xFF, + 0x01, 0x60, 0x02, 0x00, 0x01, 0x4F, 0x01, 0xFE, 0x0C, 0x00, 0x01, 0x0A, + 0x01, 0xFF, 0x01, 0x60, 0x02, 0x00, 0x01, 0xDF, 0x01, 0xF5, 0x0C, 0x00, + 0x01, 0x2F, 0x01, 0xFF, 0x01, 0x30, 0x01, 0x00, 0x01, 0x08, 0x01, 0xFF, + 0x01, 0xB0, 0x04, 0x00, 0x01, 0x47, 0x01, 0x77, 0x02, 0x00, 0x01, 0xD7, + 0x01, 0x42, 0x01, 0x01, 0x01, 0x38, 0x01, 0xEF, 0x01, 0xFC, 0x02, 0x00, + 0x01, 0x2F, 0x01, 0xFF, 0x01, 0x20, 0x03, 0x00, 0x01, 0x02, 0x02, 0xFF, + 0x02, 0x00, 0x05, 0xFF, 0x01, 0xC1, 0x02, 0x00, 0x01, 0xBF, 0x01, 0xF8, + 0x04, 0x00, 0x01, 0x0C, 0x02, 0xFF, 0x02, 0x00, 0x01, 0x7B, 0x01, 0xEF, + 0x02, 0xFF, 0x01, 0xB6, 0x02, 0x00, 0x01, 0x04, 0x01, 0xFF, 0x01, 0xE0, + 0x04, 0x00, 0x01, 0x9F, 0x01, 0xBE, 0x01, 0xFF, 0x04, 0x00, 0x01, 0x22, + 0x01, 0x10, 0x03, 0x00, 0x01, 0x0D, 0x01, 0xFF, 0x01, 0x50, 0x03, 0x00, + 0x01, 0x04, 0x01, 0xFE, 0x01, 0x1E, 0x01, 0xFF, 0x09, 0x00, 0x01, 0x8F, + 0x01, 0xFB, 0x04, 0x00, 0x01, 0x1E, 0x01, 0xF3, 0x01, 0x0E, 0x01, 0xFF, + 0x08, 0x00, 0x01, 0x02, 0x01, 0xFF, 0x01, 0xF2, 0x04, 0x00, 0x01, 0xCF, + 0x01, 0x70, 0x01, 0x0E, 0x01, 0xFF, 0x08, 0x00, 0x01, 0x0B, 0x01, 0xFF, + 0x01, 0x80, 0x03, 0x00, 0x01, 0x08, 0x01, 0xFB, 0x01, 0x00, 0x01, 0x0E, + 0x01, 0xFF, 0x08, 0x00, 0x01, 0x5F, 0x01, 0xFE, 0x04, 0x00, 0x01, 0x4F, + 0x01, 0xE1, 0x01, 0x00, 0x01, 0x0E, 0x01, 0xFF, 0x08, 0x00, 0x01, 0xDF, + 0x01, 0xF4, 0x03, 0x00, 0x01, 0x01, 0x01, 0xEF, 0x01, 0x40, 0x01, 0x00, + 0x01, 0x0E, 0x01, 0xFF, 0x07, 0x00, 0x01, 0x08, 0x01, 0xFF, 0x01, 0xB0, + 0x03, 0x00, 0x01, 0x0B, 0x01, 0xF8, 0x02, 0x00, 0x01, 0x0E, 0x01, 0xFF, + 0x07, 0x00, 0x01, 0x2F, 0x01, 0xFF, 0x01, 0x20, 0x03, 0x00, 0x01, 0x3F, + 0x01, 0xF9, 0x02, 0x99, 0x01, 0x9F, 0x01, 0xFF, 0x01, 0x99, 0x06, 0x00, + 0x01, 0xBF, 0x01, 0xF8, 0x04, 0x00, 0x01, 0x4F, 0x06, 0xFF, 0x05, 0x00, + 0x01, 0x05, 0x01, 0xFF, 0x01, 0xD0, 0x04, 0x00, 0x01, 0x29, 0x03, 0x99, + 0x01, 0x9F, 0x01, 0xFF, 0x01, 0x99, 0x05, 0x00, 0x01, 0x0D, 0x01, 0xFF, + 0x01, 0x40, 0x08, 0x00, 0x01, 0x0E, 0x01, 0xFF, 0x06, 0x00, 0x01, 0x8F, + 0x01, 0xFB, 0x09, 0x00, 0x01, 0x0E, 0x01, 0xFF, 0x05, 0x00, 0x01, 0x02, + 0x01, 0xFF, 0x01, 0xF2, 0x09, 0x00, 0x01, 0x0E, 0x01, 0xFF, 0x05, 0x00, + 0x01, 0x0A, 0x01, 0xEE, 0x01, 0x70, 0x09, 0x00, 0x01, 0x04, 0x01, 0x55, + 0xBF, 0x00, +#endif // TOUCH_UI_UTF8_FRACTIONS + +#if ENABLED(TOUCH_UI_UTF8_SYMBOLS) + /* 38 MICRON_SIGN */ + 0xFF, 0x00, 0x1F, 0x00, 0x01, 0x02, 0x01, 0x44, 0x01, 0x40, 0x05, 0x00, + 0x01, 0x14, 0x01, 0x44, 0x01, 0x10, 0x08, 0x00, 0x01, 0x07, 0x01, 0xFF, + 0x01, 0xF3, 0x05, 0x00, 0x01, 0x4F, 0x01, 0xFF, 0x01, 0x70, 0x08, 0x00, + 0x01, 0x07, 0x01, 0xFF, 0x01, 0xF3, 0x05, 0x00, 0x01, 0x4F, 0x01, 0xFF, + 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x01, 0xFF, 0x01, 0xF3, 0x05, 0x00, + 0x01, 0x4F, 0x01, 0xFF, 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x01, 0xFF, + 0x01, 0xF3, 0x05, 0x00, 0x01, 0x4F, 0x01, 0xFF, 0x01, 0x70, 0x08, 0x00, + 0x01, 0x07, 0x01, 0xFF, 0x01, 0xF3, 0x05, 0x00, 0x01, 0x4F, 0x01, 0xFF, + 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x01, 0xFF, 0x01, 0xF3, 0x05, 0x00, + 0x01, 0x4F, 0x01, 0xFF, 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x01, 0xFF, + 0x01, 0xF3, 0x05, 0x00, 0x01, 0x4F, 0x01, 0xFF, 0x01, 0x70, 0x08, 0x00, + 0x01, 0x07, 0x01, 0xFF, 0x01, 0xF3, 0x05, 0x00, 0x01, 0x4F, 0x01, 0xFF, + 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x01, 0xFF, 0x01, 0xF3, 0x05, 0x00, + 0x01, 0x4F, 0x01, 0xFF, 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x01, 0xFF, + 0x01, 0xF3, 0x05, 0x00, 0x01, 0x4F, 0x01, 0xFF, 0x01, 0x70, 0x08, 0x00, + 0x01, 0x07, 0x01, 0xFF, 0x01, 0xF3, 0x05, 0x00, 0x01, 0x4F, 0x01, 0xFF, + 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x01, 0xFF, 0x01, 0xF3, 0x05, 0x00, + 0x01, 0x4F, 0x01, 0xFF, 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x01, 0xFF, + 0x01, 0xF3, 0x05, 0x00, 0x01, 0x4F, 0x01, 0xFF, 0x01, 0x70, 0x08, 0x00, + 0x01, 0x07, 0x01, 0xFF, 0x01, 0xF3, 0x05, 0x00, 0x01, 0x4F, 0x01, 0xFF, + 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x01, 0xFF, 0x01, 0xF4, 0x05, 0x00, + 0x01, 0x6F, 0x01, 0xFF, 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x01, 0xFF, + 0x01, 0xF6, 0x05, 0x00, 0x01, 0x9F, 0x01, 0xFF, 0x01, 0x70, 0x08, 0x00, + 0x01, 0x07, 0x01, 0xFF, 0x01, 0xFA, 0x05, 0x00, 0x01, 0xEF, 0x01, 0xFF, + 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x02, 0xFF, 0x01, 0x20, 0x03, 0x00, + 0x01, 0x07, 0x02, 0xFF, 0x01, 0x70, 0x08, 0x00, 0x01, 0x07, 0x02, 0xFF, + 0x01, 0xD2, 0x03, 0x00, 0x01, 0x6F, 0x02, 0xFF, 0x01, 0xA0, 0x08, 0x00, + 0x01, 0x07, 0x03, 0xFF, 0x01, 0xA6, 0x01, 0x55, 0x01, 0x8D, 0x03, 0xFF, + 0x01, 0xF9, 0x01, 0xA4, 0x07, 0x00, 0x01, 0x07, 0x01, 0xFF, 0x01, 0xF7, + 0x05, 0xFF, 0x01, 0x5D, 0x02, 0xFF, 0x01, 0xF4, 0x07, 0x00, 0x01, 0x07, + 0x01, 0xFF, 0x01, 0xF3, 0x01, 0x5F, 0x03, 0xFF, 0x01, 0xF5, 0x01, 0x06, + 0x02, 0xFF, 0x01, 0xF4, 0x07, 0x00, 0x01, 0x07, 0x01, 0xFF, 0x01, 0xF3, + 0x01, 0x01, 0x01, 0x7C, 0x01, 0xDD, 0x01, 0xC7, 0x01, 0x10, 0x01, 0x00, + 0x01, 0x6C, 0x01, 0xDB, 0x01, 0x50, 0x07, 0x00, 0x01, 0x07, 0x01, 0xFF, + 0x01, 0xF3, 0x10, 0x00, 0x01, 0x07, 0x01, 0xFF, 0x01, 0xF3, 0x10, 0x00, + 0x01, 0x07, 0x01, 0xFF, 0x01, 0xF3, 0x10, 0x00, 0x01, 0x07, 0x01, 0xFF, + 0x01, 0xF3, 0x10, 0x00, 0x01, 0x07, 0x01, 0xFF, 0x01, 0xF3, 0x10, 0x00, + 0x01, 0x07, 0x01, 0xFF, 0x01, 0xF3, 0x10, 0x00, 0x01, 0x07, 0x01, 0xFF, + 0x01, 0xF3, 0x10, 0x00, 0x01, 0x07, 0x01, 0xEE, 0x01, 0xE3, 0x35, 0x00, + + /* 39 PILCROW_SIGN */ + 0x9C, 0x00, 0x01, 0x16, 0x01, 0x9B, 0x04, 0xCC, 0x01, 0xCA, 0x0B, 0x00, + 0x01, 0x19, 0x06, 0xFF, 0x01, 0xFD, 0x0A, 0x00, 0x01, 0x03, 0x01, 0xEF, + 0x03, 0xFF, 0x01, 0xFB, 0x01, 0xAA, 0x01, 0xAF, 0x01, 0xFD, 0x0A, 0x00, + 0x01, 0x2E, 0x04, 0xFF, 0x01, 0xF2, 0x01, 0x00, 0x01, 0x0F, 0x01, 0xFD, + 0x0A, 0x00, 0x01, 0xBF, 0x04, 0xFF, 0x01, 0xF2, 0x01, 0x00, 0x01, 0x0F, + 0x01, 0xFD, 0x09, 0x00, 0x01, 0x03, 0x05, 0xFF, 0x01, 0xF2, 0x01, 0x00, + 0x01, 0x0F, 0x01, 0xFD, 0x09, 0x00, 0x01, 0x08, 0x05, 0xFF, 0x01, 0xF2, + 0x01, 0x00, 0x01, 0x0F, 0x01, 0xFD, 0x09, 0x00, 0x01, 0x0B, 0x05, 0xFF, + 0x01, 0xF2, 0x01, 0x00, 0x01, 0x0F, 0x01, 0xFD, 0x09, 0x00, 0x01, 0x0C, + 0x05, 0xFF, 0x01, 0xF2, 0x01, 0x00, 0x01, 0x0F, 0x01, 0xFD, 0x09, 0x00, + 0x01, 0x0B, 0x05, 0xFF, 0x01, 0xF2, 0x01, 0x00, 0x01, 0x0F, 0x01, 0xFD, + 0x09, 0x00, 0x01, 0x0A, 0x05, 0xFF, 0x01, 0xF2, 0x01, 0x00, 0x01, 0x0F, + 0x01, 0xFD, 0x09, 0x00, 0x01, 0x06, 0x05, 0xFF, 0x01, 0xF2, 0x01, 0x00, + 0x01, 0x0F, 0x01, 0xFD, 0x0A, 0x00, 0x01, 0xEF, 0x04, 0xFF, 0x01, 0xF2, + 0x01, 0x00, 0x01, 0x0F, 0x01, 0xFD, 0x0A, 0x00, 0x01, 0x6F, 0x04, 0xFF, + 0x01, 0xF2, 0x01, 0x00, 0x01, 0x0F, 0x01, 0xFD, 0x0A, 0x00, 0x01, 0x08, + 0x04, 0xFF, 0x01, 0xF2, 0x01, 0x00, 0x01, 0x0F, 0x01, 0xFD, 0x0B, 0x00, + 0x01, 0x5E, 0x03, 0xFF, 0x01, 0xF2, 0x01, 0x00, 0x01, 0x0F, 0x01, 0xFD, + 0x0C, 0x00, 0x01, 0x6B, 0x02, 0xFF, 0x01, 0xF2, 0x01, 0x00, 0x01, 0x0F, + 0x01, 0xFD, 0x0D, 0x00, 0x01, 0x01, 0x01, 0xCF, 0x01, 0xF2, 0x01, 0x00, + 0x01, 0x0F, 0x01, 0xFD, 0x0E, 0x00, 0x01, 0xBF, 0x01, 0xF2, 0x01, 0x00, + 0x01, 0x0F, 0x01, 0xFD, 0x0E, 0x00, 0x01, 0xBF, 0x01, 0xF2, 0x01, 0x00, + 0x01, 0x0F, 0x01, 0xFD, 0x0E, 0x00, 0x01, 0xBF, 0x01, 0xF2, 0x01, 0x00, + 0x01, 0x0F, 0x01, 0xFD, 0x0E, 0x00, 0x01, 0xBF, 0x01, 0xF2, 0x01, 0x00, + 0x01, 0x0F, 0x01, 0xFD, 0x0E, 0x00, 0x01, 0xBF, 0x01, 0xF2, 0x01, 0x00, + 0x01, 0x0F, 0x01, 0xFD, 0x0E, 0x00, 0x01, 0xBF, 0x01, 0xF2, 0x01, 0x00, + 0x01, 0x0F, 0x01, 0xFD, 0x0E, 0x00, 0x01, 0xBF, 0x01, 0xF2, 0x01, 0x00, + 0x01, 0x0F, 0x01, 0xFD, 0x0E, 0x00, 0x01, 0xBF, 0x01, 0xF2, 0x01, 0x00, + 0x01, 0x0F, 0x01, 0xFD, 0x0E, 0x00, 0x01, 0xBF, 0x01, 0xF2, 0x01, 0x00, + 0x01, 0x0F, 0x01, 0xFD, 0x0E, 0x00, 0x01, 0xBF, 0x01, 0xF2, 0x01, 0x00, + 0x01, 0x0F, 0x01, 0xFD, 0x0E, 0x00, 0x01, 0xBF, 0x01, 0xF2, 0x01, 0x00, + 0x01, 0x0F, 0x01, 0xFD, 0x0E, 0x00, 0x01, 0xBF, 0x01, 0xF2, 0x01, 0x00, + 0x01, 0x0F, 0x01, 0xFD, 0x0E, 0x00, 0x01, 0xBF, 0x01, 0xF2, 0x01, 0x00, + 0x01, 0x0F, 0x01, 0xFD, 0x0E, 0x00, 0x01, 0xBF, 0x01, 0xF2, 0x01, 0x00, + 0x01, 0x0F, 0x01, 0xFD, 0x0E, 0x00, 0x01, 0xBF, 0x01, 0xF2, 0x01, 0x00, + 0x01, 0x0F, 0x01, 0xFD, 0x0E, 0x00, 0x01, 0xBF, 0x01, 0xF2, 0x01, 0x00, + 0x01, 0x0F, 0x01, 0xFD, 0x0E, 0x00, 0x01, 0x34, 0x01, 0x40, 0x01, 0x00, + 0x01, 0x04, 0x01, 0x43, 0x7A, 0x00, + + /* 40 BROKEN_BAR */ + 0xAD, 0x00, 0x01, 0x07, 0x01, 0x99, 0x01, 0x60, 0x10, 0x00, 0x01, 0x0C, + 0x01, 0xFF, 0x01, 0xA0, 0x10, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xA0, + 0x10, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xA0, 0x10, 0x00, 0x01, 0x0C, + 0x01, 0xFF, 0x01, 0xA0, 0x10, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xA0, + 0x10, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xA0, 0x10, 0x00, 0x01, 0x0C, + 0x01, 0xFF, 0x01, 0xA0, 0x10, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xA0, + 0x10, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xA0, 0x10, 0x00, 0x01, 0x0C, + 0x01, 0xFF, 0x01, 0xA0, 0x10, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xA0, + 0x10, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xA0, 0x10, 0x00, 0x01, 0x0C, + 0x01, 0xFF, 0x01, 0xA0, 0x10, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xA0, + 0x10, 0x00, 0x01, 0x08, 0x01, 0xBB, 0x01, 0x70, 0x6F, 0x00, 0x01, 0x0B, + 0x01, 0xFF, 0x01, 0xA0, 0x10, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xA0, + 0x10, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xA0, 0x10, 0x00, 0x01, 0x0C, + 0x01, 0xFF, 0x01, 0xA0, 0x10, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xA0, + 0x10, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xA0, 0x10, 0x00, 0x01, 0x0C, + 0x01, 0xFF, 0x01, 0xA0, 0x10, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xA0, + 0x10, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xA0, 0x10, 0x00, 0x01, 0x0C, + 0x01, 0xFF, 0x01, 0xA0, 0x10, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xA0, + 0x10, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xA0, 0x10, 0x00, 0x01, 0x0C, + 0x01, 0xFF, 0x01, 0xA0, 0x10, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xA0, + 0x10, 0x00, 0x01, 0x0C, 0x01, 0xFF, 0x01, 0xA0, 0x10, 0x00, 0x01, 0x04, + 0x01, 0x55, 0x01, 0x30, 0x47, 0x00, + + /* 41 SECTION_SIGN */ + 0x89, 0x00, 0x01, 0x35, 0x01, 0x64, 0x01, 0x31, 0x0E, 0x00, 0x01, 0x01, + 0x01, 0x9E, 0x03, 0xFF, 0x01, 0xD9, 0x01, 0x30, 0x0C, 0x00, 0x01, 0x2E, + 0x05, 0xFF, 0x01, 0xB0, 0x0C, 0x00, 0x01, 0xEF, 0x01, 0xFF, 0x01, 0xFB, + 0x01, 0x98, 0x01, 0xAE, 0x01, 0xFF, 0x01, 0xB0, 0x0B, 0x00, 0x01, 0x07, + 0x01, 0xFF, 0x01, 0xFC, 0x01, 0x10, 0x02, 0x00, 0x01, 0x39, 0x01, 0xA0, + 0x0B, 0x00, 0x01, 0x0B, 0x01, 0xFF, 0x01, 0xF2, 0x10, 0x00, 0x01, 0x0C, + 0x01, 0xFF, 0x01, 0xF0, 0x10, 0x00, 0x01, 0x0A, 0x01, 0xFF, 0x01, 0xF3, + 0x10, 0x00, 0x01, 0x06, 0x01, 0xFF, 0x01, 0xFD, 0x01, 0x20, 0x10, 0x00, + 0x01, 0xDF, 0x01, 0xFF, 0x01, 0xE4, 0x10, 0x00, 0x01, 0x1D, 0x02, 0xFF, + 0x01, 0xA1, 0x0F, 0x00, 0x01, 0x4E, 0x03, 0xFF, 0x01, 0x70, 0x0D, 0x00, + 0x01, 0x06, 0x01, 0xFF, 0x01, 0xF9, 0x01, 0xDF, 0x01, 0xFF, 0x01, 0xFD, + 0x01, 0x30, 0x0C, 0x00, 0x01, 0x3F, 0x01, 0xFF, 0x01, 0x60, 0x01, 0x07, + 0x02, 0xFF, 0x01, 0xF8, 0x0C, 0x00, 0x01, 0xBF, 0x01, 0xF9, 0x02, 0x00, + 0x01, 0x19, 0x02, 0xFF, 0x01, 0xC0, 0x0B, 0x00, 0x01, 0xFF, 0x01, 0xF3, + 0x03, 0x00, 0x01, 0x4E, 0x01, 0xFF, 0x01, 0xFB, 0x0A, 0x00, 0x01, 0x01, + 0x01, 0xFF, 0x01, 0xF2, 0x03, 0x00, 0x01, 0x01, 0x01, 0xDF, 0x01, 0xFF, + 0x01, 0x40, 0x09, 0x00, 0x01, 0x01, 0x01, 0xFF, 0x01, 0xF7, 0x04, 0x00, + 0x01, 0x2F, 0x01, 0xFF, 0x01, 0x90, 0x0A, 0x00, 0x01, 0xDF, 0x01, 0xFF, + 0x01, 0x20, 0x03, 0x00, 0x01, 0x0A, 0x01, 0xFF, 0x01, 0xB0, 0x0A, 0x00, + 0x01, 0x6F, 0x01, 0xFF, 0x01, 0xF5, 0x03, 0x00, 0x01, 0x08, 0x01, 0xFF, + 0x01, 0xA0, 0x0A, 0x00, 0x01, 0x0A, 0x02, 0xFF, 0x01, 0x91, 0x02, 0x00, + 0x01, 0x0C, 0x01, 0xFF, 0x01, 0x70, 0x0B, 0x00, 0x01, 0x8F, 0x01, 0xFF, + 0x01, 0xFE, 0x01, 0x60, 0x01, 0x00, 0x01, 0x6F, 0x01, 0xFF, 0x01, 0x10, + 0x0B, 0x00, 0x01, 0x03, 0x01, 0xDF, 0x01, 0xFF, 0x01, 0xFD, 0x01, 0x46, + 0x01, 0xFF, 0x01, 0xF5, 0x0D, 0x00, 0x01, 0x07, 0x04, 0xFF, 0x01, 0x50, + 0x0E, 0x00, 0x01, 0x2A, 0x02, 0xFF, 0x01, 0xF5, 0x10, 0x00, 0x01, 0x4E, + 0x01, 0xFF, 0x01, 0xFE, 0x01, 0x20, 0x0F, 0x00, 0x01, 0x01, 0x01, 0xCF, + 0x01, 0xFF, 0x01, 0xC0, 0x10, 0x00, 0x01, 0x1E, 0x01, 0xFF, 0x01, 0xF3, + 0x10, 0x00, 0x01, 0x06, 0x01, 0xFF, 0x01, 0xF6, 0x10, 0x00, 0x01, 0x05, + 0x01, 0xFF, 0x01, 0xF6, 0x0B, 0x00, 0x01, 0x01, 0x04, 0x00, 0x01, 0x0A, + 0x01, 0xFF, 0x01, 0xF3, 0x0B, 0x00, 0x01, 0x08, 0x01, 0xE8, 0x01, 0x20, + 0x01, 0x00, 0x01, 0x01, 0x01, 0x8F, 0x01, 0xFF, 0x01, 0xE0, 0x0B, 0x00, + 0x01, 0x08, 0x01, 0xFF, 0x01, 0xFE, 0x01, 0xCB, 0x01, 0xDF, 0x02, 0xFF, + 0x01, 0x40, 0x0B, 0x00, 0x01, 0x08, 0x05, 0xFF, 0x01, 0xF5, 0x0D, 0x00, + 0x01, 0x49, 0x01, 0xDF, 0x02, 0xFF, 0x01, 0xE8, 0x01, 0x20, 0x0F, 0x00, + 0x01, 0x12, 0x01, 0x21, 0x7F, 0x00, + + /* 42 NOT_SIGN */ + 0xFF, 0x00, 0x7F, 0x00, 0x01, 0x12, 0x0C, 0x22, 0x06, 0x00, 0x01, 0x9F, + 0x0C, 0xFF, 0x01, 0x40, 0x05, 0x00, 0x01, 0x9F, 0x0C, 0xFF, 0x01, 0x40, + 0x05, 0x00, 0x01, 0x9F, 0x0C, 0xFF, 0x01, 0x40, 0x05, 0x00, 0x01, 0x24, + 0x0A, 0x44, 0x01, 0x6F, 0x01, 0xFF, 0x01, 0x40, 0x10, 0x00, 0x01, 0x2F, + 0x01, 0xFF, 0x01, 0x40, 0x10, 0x00, 0x01, 0x2F, 0x01, 0xFF, 0x01, 0x40, + 0x10, 0x00, 0x01, 0x2F, 0x01, 0xFF, 0x01, 0x40, 0x10, 0x00, 0x01, 0x2F, + 0x01, 0xFF, 0x01, 0x40, 0x10, 0x00, 0x01, 0x2F, 0x01, 0xFF, 0x01, 0x40, + 0x10, 0x00, 0x01, 0x2F, 0x01, 0xFF, 0x01, 0x40, 0x10, 0x00, 0x01, 0x2F, + 0x01, 0xFF, 0x01, 0x40, 0x10, 0x00, 0x01, 0x17, 0x01, 0x77, 0x01, 0x10, + 0xFF, 0x00, 0x34, 0x00 +#endif // TOUCH_UI_UTF8_SYMBOLS +}; diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/bitmap2cpp.py b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/bitmap2cpp.py similarity index 98% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/bitmap2cpp.py rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/bitmap2cpp.py index c295dfc5b8d4..a7de06d68bb3 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/bitmap2cpp.py +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/bitmap2cpp.py @@ -13,7 +13,7 @@ # GNU General Public License for more details. # # To view a copy of the GNU General Public License, go to the following -# location: . +# location: . from __future__ import print_function from PIL import Image diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/circular_progress.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/circular_progress.h similarity index 97% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/circular_progress.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/circular_progress.h index da6a2bc32593..5357de3ef36c 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/circular_progress.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/circular_progress.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/poly_ui.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/poly_ui.h similarity index 91% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/poly_ui.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/poly_ui.h index 9f531146e130..a501de20ba87 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/poly_ui.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/poly_ui.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once @@ -36,7 +36,7 @@ * * PolyReader r(data, N_ELEMENTS(data)); * - * for(r.start();r.has_more(); r.next()) { + * for (r.start();r.has_more(); r.next()) { * uint16_t x = r.x; * uint16_t y = r.y; * @@ -49,7 +49,6 @@ * ... * } * } - * */ class PolyReader { @@ -92,7 +91,8 @@ class PolyReader { close_loop(); else p = NULL; - } else { + } + else { x = pgm_read_word_far(p++); if (x == eol) close_loop(); @@ -106,8 +106,8 @@ class PolyReader { } } - bool has_more() {return p != NULL;} - bool end_of_loop() {return start_x == eol;} + bool has_more() { return p != NULL; } + bool end_of_loop() { return start_x == eol; } }; /** @@ -128,7 +128,7 @@ class TransformedPolyReader : public PolyReader { */ static constexpr uint8_t fract_bits = 5; typedef int16_t fix_t; - fix_t makefix(float f) {return f * (1 << fract_bits);} + fix_t makefix(float f) { return f * (1 << fract_bits); } // First two rows of 3x3 transformation matrix fix_t a, b, c; @@ -225,7 +225,8 @@ class DeduplicatedPolyReader : public POLY_READER { } 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 { + } + else { last_x = POLY_READER::x; last_y = POLY_READER::y; } @@ -252,6 +253,13 @@ class GenericPolyUI { draw_mode_t mode; public: + enum ButtonStyle : uint8_t { + FILL = 1, + STROKE = 2, + SHADOW = 4, + REGULAR = 7 + }; + typedef POLY_READER poly_reader_t; GenericPolyUI(CommandProcessor &c, draw_mode_t what = BOTH) : cmd(c), mode(what) {} @@ -274,7 +282,7 @@ class GenericPolyUI { Polygon p(cmd); p.begin_fill(); p.begin_loop(); - for(r.start();r.has_more();r.next()) { + for (r.start();r.has_more();r.next()) { p(r.x * 16, r.y * 16); if (r.end_of_loop()) { p.end_loop(); @@ -304,7 +312,7 @@ class GenericPolyUI { Polygon p(cmd); p.begin_stroke(); p.begin_loop(); - for(r.start();r.has_more(); r.next()) { + for (r.start();r.has_more(); r.next()) { p(r.x * 16, r.y * 16); if (r.end_of_loop()) { p.end_loop(); @@ -321,7 +329,7 @@ class GenericPolyUI { 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()) { + for (r.start(); r.has_more(); r.next()) { x_min = min(x_min, int16_t(r.x)); x_max = max(x_max, int16_t(r.x)); y_min = min(y_min, int16_t(r.y)); @@ -353,11 +361,11 @@ class GenericPolyUI { btn_shadow_depth = depth; } - void button(const uint8_t tag, poly_reader_t r) { + void button(const uint8_t tag, poly_reader_t r, uint8_t style = REGULAR) { using namespace FTDI; // Draw the shadow #if FTDI_API_LEVEL >= 810 - if (mode & BACKGROUND) { + if (mode & BACKGROUND && style & SHADOW) { cmd.cmd(SAVE_CONTEXT()); cmd.cmd(TAG(tag)); cmd.cmd(VERTEX_TRANSLATE_X(btn_shadow_depth * 16)); @@ -379,11 +387,15 @@ class GenericPolyUI { #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); + if (style & FILL) { + cmd.cmd(COLOR_RGB(btn_fill_color)); + fill(r, false); + } + if (style & STROKE) { + cmd.cmd(COLOR_RGB(btn_stroke_color)); + cmd.cmd(LINE_WIDTH(btn_stroke_width)); + stroke(r); + } cmd.cmd(RESTORE_CONTEXT()); } } diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/svg2cpp.py b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/svg2cpp.py similarity index 98% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/svg2cpp.py rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/svg2cpp.py index 2778f94d9850..da08014e893e 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/svg2cpp.py +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/svg2cpp.py @@ -13,7 +13,7 @@ # GNU General Public License for more details. # # To view a copy of the GNU General Public License, go to the following -# location: . +# location: . from __future__ import print_function import argparse, re, sys @@ -56,7 +56,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ /** diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/ftdi_eve_lib.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/ftdi_eve_lib.h similarity index 94% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/ftdi_eve_lib.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/ftdi_eve_lib.h index 5a7d3c960bba..5c1a74f66e9d 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/ftdi_eve_lib.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/ftdi_eve_lib.h @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/language/language.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/language/language.cpp similarity index 94% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/language/language.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/language/language.cpp index 624c58576c30..912c95731d12 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/language/language.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/language/language.cpp @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/language/language.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/language/language.h similarity index 94% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/language/language.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/language/language.h index 54f843993312..873e84455ad0 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/language/language.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/language/language.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/language/language_en.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/language/language_en.h similarity index 86% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/language/language_en.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/language/language_en.h index e59e1d9468cc..cc96c8b9cda7 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/language/language_en.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/language/language_en.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once @@ -57,8 +57,11 @@ namespace Language_en { PROGMEM Language_Str MSG_AMAX_Y = u8"Amax Y"; PROGMEM Language_Str MSG_AMAX_Z = u8"Amax Z"; PROGMEM Language_Str MSG_AXIS_X = u8"X"; + PROGMEM Language_Str MSG_AXIS_X2 = u8"X2"; PROGMEM Language_Str MSG_AXIS_Y = u8"Y"; + PROGMEM Language_Str MSG_AXIS_Y2 = u8"Y2"; PROGMEM Language_Str MSG_AXIS_Z = u8"Z"; + PROGMEM Language_Str MSG_AXIS_Z2 = u8"Z2"; PROGMEM Language_Str MSG_AXIS_E = u8"E"; PROGMEM Language_Str MSG_AXIS_E1 = u8"E1"; PROGMEM Language_Str MSG_AXIS_E2 = u8"E2"; @@ -70,13 +73,15 @@ namespace Language_en { PROGMEM Language_Str MSG_PRINT_FINISHED = u8"Print finished"; PROGMEM Language_Str MSG_PRINT_ERROR = u8"Print error"; PROGMEM Language_Str MSG_ABOUT_TOUCH_PANEL_1 = u8"Color Touch Panel"; - PROGMEM Language_Str MSG_ABOUT_TOUCH_PANEL_2 = u8"Portions " COPYRIGHT_SIGN " 2019 Aleph Objects, Inc.\n" - "Portions " COPYRIGHT_SIGN " 2019 Cocoa Press"; - PROGMEM Language_Str MSG_FIRMWARE_FOR_TOOLHEAD = u8"Firmware for toolhead:\n%s\n\n"; + PROGMEM Language_Str MSG_ABOUT_TOUCH_PANEL_2 = WEBSITE_URL; + PROGMEM Language_Str MSG_LICENSE = u8"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.\n\nTo view a copy of the GNU General " + "Public License, go to the following location: https://www.gnu.org/licenses."; PROGMEM Language_Str MSG_RUNOUT_1 = u8"Runout 1"; PROGMEM Language_Str MSG_RUNOUT_2 = u8"Runout 2"; PROGMEM Language_Str MSG_DISPLAY_MENU = u8"Display"; - PROGMEM Language_Str MSG_INTERFACE_SETTINGS = u8"Interface Settings"; + PROGMEM Language_Str MSG_INTERFACE = u8"Interface"; PROGMEM Language_Str MSG_MEASURE_AUTOMATICALLY = u8"Measure automatically"; PROGMEM Language_Str MSG_H_OFFSET = u8"H Offset"; PROGMEM Language_Str MSG_V_OFFSET = u8"V Offset"; @@ -89,9 +94,6 @@ namespace Language_en { PROGMEM Language_Str MSG_UNITS_STEP_MM = u8"st/mm"; PROGMEM Language_Str MSG_UNITS_PERCENT = u8"%"; PROGMEM Language_Str MSG_UNITS_C = DEGREE_SIGN u8"C"; - PROGMEM Language_Str MSG_MATERIAL_PLA = u8"PLA"; - PROGMEM Language_Str MSG_MATERIAL_ABS = u8"ABS"; - PROGMEM Language_Str MSG_MATERIAL_HIGH_TEMP = u8"High"; PROGMEM Language_Str MSG_IDLE = u8"idle"; PROGMEM Language_Str MSG_SET_MAXIMUM = u8"Set Maximum"; PROGMEM Language_Str MSG_PRINT_SPEED = u8"Print Speed"; @@ -129,7 +131,7 @@ namespace Language_en { PROGMEM Language_Str MSG_SOUND_VOLUME = u8"Sound volume"; PROGMEM Language_Str MSG_SCREEN_LOCK = u8"Screen lock"; PROGMEM Language_Str MSG_BOOT_SCREEN = u8"Boot screen"; - PROGMEM Language_Str MSG_INTERFACE_SOUNDS = u8"Interface Sounds"; + PROGMEM Language_Str MSG_SOUNDS = u8"Sounds"; PROGMEM Language_Str MSG_CLICK_SOUNDS = u8"Click sounds"; PROGMEM Language_Str MSG_EEPROM_RESTORED = u8"Settings restored from backup"; PROGMEM Language_Str MSG_EEPROM_RESET = u8"Settings restored to default"; @@ -144,12 +146,16 @@ namespace Language_en { PROGMEM Language_Str MSG_TOUCH_CALIBRATION_START = u8"Release to begin screen calibration"; PROGMEM Language_Str MSG_TOUCH_CALIBRATION_PROMPT = u8"Touch the dots to calibrate"; + PROGMEM Language_Str MSG_AUTOLEVEL_X_AXIS = u8"Level X Axis"; + PROGMEM Language_Str MSG_BED_MAPPING_DONE = u8"Bed mapping finished"; + PROGMEM Language_Str MSG_BED_MAPPING_INCOMPLETE = u8"Not all points probed"; + PROGMEM Language_Str MSG_LEVELING = u8"Leveling"; + PROGMEM Language_Str MSG_SHOW_MESH = u8"Show Bed Mesh"; #ifdef TOUCH_UI_LULZBOT_BIO PROGMEM Language_Str MSG_MOVE_TO_HOME = u8"Move to Home"; PROGMEM Language_Str MSG_RAISE_PLUNGER = u8"Raise Plunger"; PROGMEM Language_Str MSG_RELEASE_XY_AXIS = u8"Release X and Y Axis"; - PROGMEM Language_Str MSG_AUTOLEVEL_X_AXIS = u8"Auto-level X Axis"; PROGMEM Language_Str MSG_BED_TEMPERATURE = u8"Bed Temperature"; PROGMEM Language_Str MSG_HOME_XYZ_WARNING = u8"About to move to home position. Ensure the top and the bed of the printer are clear.\n\nContinue?"; PROGMEM Language_Str MSG_HOME_E_WARNING = u8"About to re-home plunger and auto-level. Remove syringe prior to proceeding.\n\nContinue?"; diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/marlin_events.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/marlin_events.cpp similarity index 77% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/marlin_events.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/marlin_events.cpp index 96845d40658e..fe68faefee44 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/marlin_events.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/marlin_events.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "compat.h" @@ -51,12 +51,19 @@ namespace ExtUI { } void onMediaRemoved() { - if (AT_SCREEN(StatusScreen)) - StatusScreen::setStatusMessage(GET_TEXT_F(MSG_MEDIA_REMOVED)); - sound.play(media_removed, PLAY_ASYNCHRONOUS); - if (AT_SCREEN(FilesScreen)) { - GOTO_SCREEN(StatusScreen) + if (isPrintingFromMedia()) { + stopPrint(); + InterfaceSoundsScreen::playEventSound(InterfaceSoundsScreen::PRINTING_FAILED); } + else + sound.play(media_removed, PLAY_ASYNCHRONOUS); + + if (AT_SCREEN(StatusScreen) || isPrintingFromMedia()) + StatusScreen::setStatusMessage(GET_TEXT_F(MSG_MEDIA_REMOVED)); + + #if ENABLED(SDSUPPORT) + if (AT_SCREEN(FilesScreen)) GOTO_SCREEN(StatusScreen); + #endif } void onMediaError() { @@ -87,7 +94,7 @@ namespace ExtUI { char lcd_msg[30]; sprintf_P(lcd_msg, PSTR("Extruder %d Filament Error"), extruder + 1); StatusScreen::setStatusMessage(lcd_msg); - InterfaceSoundsScreen::playEventSound(InterfaceSoundsScreen::PRINTING_FAILED); + InterfaceSoundsScreen::playEventSound(InterfaceSoundsScreen::PRINTING_FAILED, FTDI::PLAY_SYNCHRONOUS); } void onFactoryReset() { @@ -127,26 +134,37 @@ namespace ExtUI { } #if HAS_LEVELING && HAS_MESH - void onMeshUpdate(const int8_t, const int8_t, const float) { + void onMeshUpdate(const int8_t x, const int8_t y, const float val) { + BedMeshScreen::onMeshUpdate(x, y, val); + } + + void onMeshUpdate(const int8_t x, const int8_t y, const ExtUI::probe_state_t state) { + BedMeshScreen::onMeshUpdate(x, y, state); + } + #endif + + #if ENABLED(POWER_LOSS_RECOVERY) + void onPowerLossResume() { + // Called on resume from power-loss } #endif #if HAS_PID_HEATING - void OnPidTuning(const result_t rst) { + void onPidTuning(const result_t rst) { // Called for temperature PID tuning result - SERIAL_ECHOLNPAIR("OnPidTuning:", rst); + //SERIAL_ECHOLNPAIR("OnPidTuning:", rst); switch (rst) { case PID_BAD_EXTRUDER_NUM: - StatusScreen::setStatusMessage(STR_PID_BAD_EXTRUDER_NUM); + StatusScreen::setStatusMessage(GET_TEXT_F(MSG_PID_BAD_EXTRUDER_NUM)); break; case PID_TEMP_TOO_HIGH: - StatusScreen::setStatusMessage(STR_PID_TEMP_TOO_HIGH); + StatusScreen::setStatusMessage(GET_TEXT_F(MSG_PID_TEMP_TOO_HIGH)); break; case PID_TUNING_TIMEOUT: - StatusScreen::setStatusMessage(STR_PID_TIMEOUT); + StatusScreen::setStatusMessage(GET_TEXT_F(MSG_PID_TIMEOUT)); break; case PID_DONE: - StatusScreen::setStatusMessage(STR_PID_AUTOTUNE_FINISHED); + StatusScreen::setStatusMessage(GET_TEXT_F(MSG_PID_AUTOTUNE_DONE)); break; } GOTO_SCREEN(StatusScreen); diff --git a/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/pin_mappings.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/pin_mappings.h new file mode 100644 index 000000000000..5ad84c60b0ff --- /dev/null +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/pin_mappings.h @@ -0,0 +1,144 @@ +/****************** + * 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: . * + ****************************************************************************/ + +#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. + */ + +#include "../../../../inc/MarlinConfig.h" + +#if ENABLED(F6_TFT_PINMAP) // FYSETC F6 - ATmega2560 + + #define CLCD_SPI_CS 33 + #define CLCD_MOD_RESET 31 + +#elif ENABLED(S6_TFT_PINMAP) // FYSETC S6 - STM32F4 + + #define CLCD_SPI_CS PC7 + #define CLCD_MOD_RESET PC6 + +#elif ENABLED(CR10_TFT_PINMAP) // FYSETC S6 - STM32F4 - with TOUCH_UI_ULTIPANEL + + #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 + +#elif ENABLED(AO_EXP1_DEPRECATED_PINMAP) + + /** + * This AlephObjects pinout re-purposes the UltraLCD + * connector EXP1 for Software SPI (rev B, obsolete) + */ + + #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 + +#elif ENABLED(AO_EXP1_PINMAP) + + /** + * AO_EXP1_PINMAP with TOUCH_UI_ULTIPANEL + * + * This AlephObjects mapping re-purposes 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. + */ + + #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 + +#elif ENABLED(AO_EXP2_PINMAP) + + /** + * AO_EXP2_PINMAP with TOUCH_UI_ULTIPANEL + * + * 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 allows daisy-chaining of the + * display and SD/USB on EXP2, except for [2] + * + * [2] The Ultimachine Einsy boards have a level shifter + * on MISO enabled by SD_CSEL chip select, hence it + * is not possible to run both the display and the + * 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. + */ + + #define CLCD_SPI_CS BTN_EN1 + #define CLCD_MOD_RESET BTN_EN2 + #if MB(EINSY_RAMBO, EINSY_RETRO) && DISABLED(SDSUPPORT) + #define CLCD_SPI_EXTRA_CS SDSS + #endif + +#endif diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/about_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/about_screen.cpp similarity index 53% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/about_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/about_screen.cpp index afd4402fc109..9cd17637bd52 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/about_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/about_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -27,7 +27,7 @@ #include "screens.h" #define GRID_COLS 4 -#define GRID_ROWS 9 +#define GRID_ROWS 7 using namespace FTDI; using namespace Theme; @@ -45,7 +45,34 @@ void AboutScreen::onRedraw(draw_mode_t) { .cmd(COLOR_RGB(bg_text_enabled)) .tag(0); - draw_text_box(cmd, BTN_POS(1,2), BTN_SIZE(4,1), + #define HEADING_POS BTN_POS(1,2), BTN_SIZE(4,1) + #define FW_VERS_POS BTN_POS(1,3), BTN_SIZE(4,1) + #define FW_INFO_POS BTN_POS(1,4), BTN_SIZE(4,1) + #define LICENSE_POS BTN_POS(1,5), BTN_SIZE(4,2) + #define STATS_POS BTN_POS(1,7), BTN_SIZE(2,1) + #define BACK_POS BTN_POS(3,7), BTN_SIZE(2,1) + + #define _INSET_POS(x,y,w,h) x + w/10, y, w - w/5, h + #define INSET_POS(pos) _INSET_POS(pos) + + char about_str[1 + + strlen_P(GET_TEXT(MSG_ABOUT_TOUCH_PANEL_2)) + #ifdef TOOLHEAD_NAME + + strlen_P(TOOLHEAD_NAME) + #endif + ]; + #ifdef TOOLHEAD_NAME + // If MSG_ABOUT_TOUCH_PANEL_2 has %s, substitute in the toolhead name. + // But this is optional, so squelch the compiler warning here. + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wformat-extra-args" + sprintf_P(about_str, GET_TEXT(MSG_ABOUT_TOUCH_PANEL_2), TOOLHEAD_NAME); + #pragma GCC diagnostic pop + #else + strcpy_P(about_str, GET_TEXT(MSG_ABOUT_TOUCH_PANEL_2)); + #endif + + draw_text_box(cmd, HEADING_POS, #ifdef CUSTOM_MACHINE_NAME F(CUSTOM_MACHINE_NAME) #else @@ -53,42 +80,37 @@ void AboutScreen::onRedraw(draw_mode_t) { #endif , OPT_CENTER, font_xlarge ); - - #ifdef TOOLHEAD_NAME - char about_str[ - strlen_P(GET_TEXT(FIRMWARE_FOR_TOOLHEAD)) + - strlen_P(TOOLHEAD_NAME) + - strlen_P(GET_TEXT(MSG_ABOUT_TOUCH_PANEL_2)) + 1 - ]; - - sprintf_P(about_str, GET_TEXT(MSG_FIRMWARE_FOR_TOOLHEAD), TOOLHEAD_NAME); - strcat_P (about_str, GET_TEXT(MSG_ABOUT_TOUCH_PANEL_2)); + cmd.tag(3); + draw_text_box(cmd, FW_VERS_POS, + #ifdef TOUCH_UI_VERSION + F(TOUCH_UI_VERSION) + #else + progmem_str(getFirmwareName_str()) #endif - - cmd.tag(2); - draw_text_box(cmd, BTN_POS(1,3), BTN_SIZE(4,3), - #ifdef TOOLHEAD_NAME - about_str - #else - GET_TEXT_F(MSG_ABOUT_TOUCH_PANEL_2) - #endif - , OPT_CENTER, font_medium - ); - + , 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), GET_TEXT_F(MSG_BUTTON_OKAY)); + draw_text_box(cmd, FW_INFO_POS, about_str, OPT_CENTER, font_medium); + draw_text_box(cmd, INSET_POS(LICENSE_POS), GET_TEXT_F(MSG_LICENSE), OPT_CENTER, font_tiny); + + cmd.font(font_medium) + .colors(normal_btn) + .tag(2).button(STATS_POS, GET_TEXT_F(MSG_INFO_STATS_MENU)) + .colors(action_btn) + .tag(1).button(BACK_POS, GET_TEXT_F(MSG_BACK)); } bool AboutScreen::onTouchEnd(uint8_t tag) { switch (tag) { - case 1: GOTO_PREVIOUS(); return true; -#if ENABLED(TOUCH_UI_DEVELOPER_MENU) - case 2: GOTO_SCREEN(DeveloperMenu); return true; -#endif - default: return false; + case 1: GOTO_PREVIOUS(); break; + #if ENABLED(PRINTCOUNTER) + case 2: GOTO_SCREEN(StatisticsScreen); break; + #endif + #if ENABLED(TOUCH_UI_DEVELOPER_MENU) + case 3: GOTO_SCREEN(DeveloperMenu); break; + #endif + default: return false; } + return true; } #endif // TOUCH_UI_FTDI_EVE diff --git a/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/advanced_settings_menu.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/advanced_settings_menu.cpp new file mode 100644 index 000000000000..cfb268f0b44f --- /dev/null +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/advanced_settings_menu.cpp @@ -0,0 +1,155 @@ +/***************************** + * 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: . * + ****************************************************************************/ + +#include "../config.h" + +#if ENABLED(TOUCH_UI_FTDI_EVE) && !defined(TOUCH_UI_LULZBOT_BIO) + +#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)); + } + + #ifdef TOUCH_UI_PORTRAIT + #if EITHER(HAS_MULTI_HOTEND, SENSORLESS_HOMING) + #define GRID_ROWS 9 + #else + #define GRID_ROWS 8 + #endif + #define GRID_COLS 2 + #define RESTORE_DEFAULTS_POS BTN_POS(1,1), BTN_SIZE(2,1) + #define DISPLAY_POS BTN_POS(1,2), BTN_SIZE(1,1) + #define INTERFACE_POS BTN_POS(2,2), BTN_SIZE(1,1) + #define ZPROBE_ZOFFSET_POS BTN_POS(1,3), BTN_SIZE(1,1) + #define STEPS_PER_MM_POS BTN_POS(2,3), BTN_SIZE(1,1) + #define FILAMENT_POS BTN_POS(1,4), BTN_SIZE(1,1) + #define VELOCITY_POS BTN_POS(2,4), BTN_SIZE(1,1) + #define TMC_CURRENT_POS BTN_POS(1,5), BTN_SIZE(1,1) + #define ACCELERATION_POS BTN_POS(2,5), BTN_SIZE(1,1) + #define ENDSTOPS_POS BTN_POS(1,6), BTN_SIZE(1,1) + #define JERK_POS BTN_POS(2,6), BTN_SIZE(1,1) + #define CASE_LIGHT_POS BTN_POS(1,7), BTN_SIZE(1,1) + #define BACKLASH_POS BTN_POS(2,7), BTN_SIZE(1,1) + #define OFFSETS_POS BTN_POS(1,8), BTN_SIZE(1,1) + #define TMC_HOMING_THRS_POS BTN_POS(2,8), BTN_SIZE(1,1) + #if EITHER(HAS_MULTI_HOTEND, SENSORLESS_HOMING) + #define BACK_POS BTN_POS(1,9), BTN_SIZE(2,1) + #else + #define BACK_POS BTN_POS(1,8), BTN_SIZE(2,1) + #endif + #else + #define GRID_ROWS 6 + #define GRID_COLS 3 + #define ZPROBE_ZOFFSET_POS BTN_POS(1,1), BTN_SIZE(1,1) + #define CASE_LIGHT_POS BTN_POS(1,4), BTN_SIZE(1,1) + #define STEPS_PER_MM_POS BTN_POS(2,1), BTN_SIZE(1,1) + #define TMC_CURRENT_POS BTN_POS(3,1), BTN_SIZE(1,1) + #define TMC_HOMING_THRS_POS BTN_POS(3,2), BTN_SIZE(1,1) + #define BACKLASH_POS BTN_POS(3,3), BTN_SIZE(1,1) + #define FILAMENT_POS BTN_POS(1,3), BTN_SIZE(1,1) + #define ENDSTOPS_POS BTN_POS(3,4), BTN_SIZE(1,1) + #define DISPLAY_POS BTN_POS(3,5), BTN_SIZE(1,1) + #define INTERFACE_POS BTN_POS(1,5), BTN_SIZE(2,1) + #define RESTORE_DEFAULTS_POS BTN_POS(1,6), BTN_SIZE(2,1) + #define VELOCITY_POS BTN_POS(2,2), BTN_SIZE(1,1) + #define ACCELERATION_POS BTN_POS(2,3), BTN_SIZE(1,1) + #define JERK_POS BTN_POS(2,4), BTN_SIZE(1,1) + #define OFFSETS_POS BTN_POS(1,2), BTN_SIZE(1,1) + #define BACK_POS BTN_POS(3,6), BTN_SIZE(1,1) + #endif + + if (what & FOREGROUND) { + CommandProcessor cmd; + cmd.colors(normal_btn) + .font(Theme::font_medium) + .enabled(ENABLED(HAS_BED_PROBE)) + .tag(2) .button( ZPROBE_ZOFFSET_POS, GET_TEXT_F(MSG_ZPROBE_ZOFFSET)) + .enabled(ENABLED(CASE_LIGHT_ENABLE)) + .tag(16).button( CASE_LIGHT_POS, GET_TEXT_F(MSG_CASE_LIGHT)) + .tag(3) .button( STEPS_PER_MM_POS, GET_TEXT_F(MSG_STEPS_PER_MM)) + .enabled(ENABLED(HAS_TRINAMIC_CONFIG)) + .tag(13).button( TMC_CURRENT_POS, GET_TEXT_F(MSG_TMC_CURRENT)) + .enabled(ENABLED(SENSORLESS_HOMING)) + .tag(14).button( TMC_HOMING_THRS_POS, GET_TEXT_F(MSG_TMC_HOMING_THRS)) + .enabled(ENABLED(HAS_MULTI_HOTEND)) + .tag(4) .button( OFFSETS_POS, GET_TEXT_F(MSG_OFFSETS_MENU)) + .enabled(EITHER(LIN_ADVANCE, FILAMENT_RUNOUT_SENSOR)) + .tag(11).button( FILAMENT_POS, GET_TEXT_F(MSG_FILAMENT)) + .tag(12).button( ENDSTOPS_POS, GET_TEXT_F(MSG_LCD_ENDSTOPS)) + .tag(15).button( DISPLAY_POS, GET_TEXT_F(MSG_DISPLAY_MENU)) + .tag(9) .button( INTERFACE_POS, GET_TEXT_F(MSG_INTERFACE)) + .tag(10).button( RESTORE_DEFAULTS_POS, GET_TEXT_F(MSG_RESTORE_DEFAULTS)) + .tag(5) .button( VELOCITY_POS, GET_TEXT_F(MSG_VELOCITY)) + .tag(6) .button( ACCELERATION_POS, GET_TEXT_F(MSG_ACCELERATION)) + .tag(7) .button( JERK_POS, GET_TEXT_F(TERN(HAS_JUNCTION_DEVIATION, MSG_JUNCTION_DEVIATION, MSG_JERK))) + .enabled(ENABLED(BACKLASH_GCODE)) + .tag(8).button( BACKLASH_POS, GET_TEXT_F(MSG_BACKLASH)) + .colors(action_btn) + .tag(1).button( BACK_POS, GET_TEXT_F(MSG_BACK)); + } +} + +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 ENABLED(HAS_MULTI_HOTEND) + case 4: GOTO_SCREEN(NozzleOffsetScreen); break; + #endif + case 5: GOTO_SCREEN(MaxVelocityScreen); break; + case 6: GOTO_SCREEN(DefaultAccelerationScreen); break; + case 7: GOTO_SCREEN(TERN(HAS_JUNCTION_DEVIATION, JunctionDeviationScreen, JerkScreen)); 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 EITHER(LIN_ADVANCE, FILAMENT_RUNOUT_SENSOR) + case 11: GOTO_SCREEN(FilamentMenu); break; + #endif + case 12: GOTO_SCREEN(EndstopStatesScreen); break; + #if HAS_TRINAMIC_CONFIG + case 13: GOTO_SCREEN(StepperCurrentScreen); break; + #endif + #if ENABLED(SENSORLESS_HOMING) + case 14: GOTO_SCREEN(StepperBumpSensitivityScreen); break; + #endif + case 15: GOTO_SCREEN(DisplayTuningScreen); break; + #if ENABLED(CASE_LIGHT_ENABLE) + case 16: GOTO_SCREEN(CaseLightScreen); break; + #endif + default: return false; + } + return true; +} +#endif // TOUCH_UI_FTDI_EVE diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/alert_dialog_box.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/alert_dialog_box.cpp similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/alert_dialog_box.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/alert_dialog_box.cpp index 17750c02ec02..bd09d2a5cd20 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/alert_dialog_box.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/alert_dialog_box.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/backlash_compensation_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/backlash_compensation_screen.cpp similarity index 97% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/backlash_compensation_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/backlash_compensation_screen.cpp index 0d6b97d46aba..8d65518455dd 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/backlash_compensation_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/backlash_compensation_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/base_numeric_adjustment_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/base_numeric_adjustment_screen.cpp similarity index 95% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/base_numeric_adjustment_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/base_numeric_adjustment_screen.cpp index 97e399a4030b..1c4ef594bb4e 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/base_numeric_adjustment_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/base_numeric_adjustment_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -73,13 +73,13 @@ void BaseNumericAdjustmentScreen::widgets_t::_button_style(CommandProcessor &cmd const btn_colors *old_colors = &normal_btn; const btn_colors *new_colors = &normal_btn; - switch(_style) { + switch (_style) { case BTN_ACTION: old_colors = &action_btn; break; case BTN_TOGGLE: old_colors = &ui_toggle; break; case BTN_DISABLED: old_colors = &disabled_btn; break; default: break; } - switch(style) { + switch (style) { case BTN_ACTION: new_colors = &action_btn; break; case BTN_TOGGLE: new_colors = &ui_toggle; break; case BTN_DISABLED: new_colors = &disabled_btn; break; @@ -345,10 +345,14 @@ void BaseNumericAdjustmentScreen::widgets_t::home_buttons(uint8_t tag) { } cmd.font(LAYOUT_FONT); - _button(cmd, tag+0, BTN_POS(5,_line), BTN_SIZE(2,1), GET_TEXT_F(MSG_AXIS_X)); - _button(cmd, tag+1, BTN_POS(7,_line), BTN_SIZE(2,1), GET_TEXT_F(MSG_AXIS_Y)); - _button(cmd, tag+2, BTN_POS(9,_line), BTN_SIZE(2,1), GET_TEXT_F(MSG_AXIS_Z)); - _button(cmd, tag+3, BTN_POS(11,_line), BTN_SIZE(3,1), GET_TEXT_F(MSG_AXIS_ALL)); + _button(cmd, tag+0, BTN_POS(5,_line), BTN_SIZE(2,1), GET_TEXT_F(MSG_AXIS_X)); + _button(cmd, tag+1, BTN_POS(7,_line), BTN_SIZE(2,1), GET_TEXT_F(MSG_AXIS_Y)); + #if DISABLED(Z_SAFE_HOMING) + _button(cmd, tag+2, BTN_POS(9,_line), BTN_SIZE(2,1), GET_TEXT_F(MSG_AXIS_Z)); + _button(cmd, tag+3, BTN_POS(11,_line), BTN_SIZE(3,1), GET_TEXT_F(MSG_AXIS_ALL)); + #else + _button(cmd, tag+3, BTN_POS(9,_line), BTN_SIZE(3,1), GET_TEXT_F(MSG_AXIS_ALL)); + #endif _line++; } diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/base_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/base_screen.cpp similarity index 92% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/base_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/base_screen.cpp index 77cadabcd778..c84dd45f004f 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/base_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/base_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -46,7 +46,7 @@ bool BaseScreen::buttonStyleCallback(CommandProcessor &cmd, uint8_t tag, uint8_t return false; } - #ifdef LCD_TIMEOUT_TO_STATUS + #if LCD_TIMEOUT_TO_STATUS > 0 if (EventLoop::get_pressed_tag() != 0) { reset_menu_timeout(); } @@ -66,7 +66,7 @@ bool BaseScreen::buttonStyleCallback(CommandProcessor &cmd, uint8_t tag, uint8_t } void BaseScreen::onIdle() { - #ifdef LCD_TIMEOUT_TO_STATUS + #if LCD_TIMEOUT_TO_STATUS > 0 if ((millis() - last_interaction) > LCD_TIMEOUT_TO_STATUS) { reset_menu_timeout(); #if ENABLED(TOUCH_UI_DEBUG) @@ -78,12 +78,12 @@ void BaseScreen::onIdle() { } void BaseScreen::reset_menu_timeout() { - #ifdef LCD_TIMEOUT_TO_STATUS + #if LCD_TIMEOUT_TO_STATUS > 0 last_interaction = millis(); #endif } -#ifdef LCD_TIMEOUT_TO_STATUS +#if LCD_TIMEOUT_TO_STATUS > 0 uint32_t BaseScreen::last_interaction; #endif diff --git a/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bed_mesh_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bed_mesh_screen.cpp new file mode 100644 index 000000000000..a11609dd97d2 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bed_mesh_screen.cpp @@ -0,0 +1,353 @@ +/*********************** + * bed_mesh_screen.cpp * + ***********************/ + +/**************************************************************************** + * Written By Marcio Teixeira 2020 * + * * + * 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: . * + ****************************************************************************/ + +#include "../config.h" + +#if BOTH(TOUCH_UI_FTDI_EVE, HAS_MESH) + +#include "screens.h" +#include "screen_data.h" + +using namespace FTDI; +using namespace Theme; +using namespace ExtUI; + +#ifdef TOUCH_UI_PORTRAIT + #define GRID_COLS 2 + #define GRID_ROWS 10 + + #define MESH_POS BTN_POS(1, 2), BTN_SIZE(2,5) + #define MESSAGE_POS BTN_POS(1, 7), BTN_SIZE(2,1) + #define Z_LABEL_POS BTN_POS(1, 8), BTN_SIZE(1,1) + #define Z_VALUE_POS BTN_POS(2, 8), BTN_SIZE(1,1) + #define OKAY_POS BTN_POS(1,10), BTN_SIZE(2,1) +#else + #define GRID_COLS 5 + #define GRID_ROWS 5 + + #define MESH_POS BTN_POS(1,1), BTN_SIZE(3,5) + #define MESSAGE_POS BTN_POS(4,1), BTN_SIZE(2,1) + #define Z_LABEL_POS BTN_POS(4,2), BTN_SIZE(2,1) + #define Z_VALUE_POS BTN_POS(4,3), BTN_SIZE(2,1) + #define OKAY_POS BTN_POS(4,5), BTN_SIZE(2,1) +#endif + +void BedMeshScreen::drawMesh(int16_t x, int16_t y, int16_t w, int16_t h, ExtUI::bed_mesh_t data, uint8_t opts, float autoscale_max) { + constexpr uint8_t rows = GRID_MAX_POINTS_Y; + constexpr uint8_t cols = GRID_MAX_POINTS_X; + + #define VALUE(X,Y) (data ? data[X][Y] : 0) + #define ISVAL(X,Y) (data ? !isnan(VALUE(X,Y)) : true) + #define HEIGHT(X,Y) (ISVAL(X,Y) ? (VALUE(X,Y) - val_min) * scale_z : 0) + + // Compute the mean, min and max for the points + + float val_mean = 0; + float val_max = -INFINITY; + float val_min = INFINITY; + uint8_t val_cnt = 0; + + if (data && (opts & USE_AUTOSCALE)) { + for (uint8_t y = 0; y < rows; y++) { + for (uint8_t x = 0; x < cols; x++) { + if (ISVAL(x,y)) { + const float val = VALUE(x,y); + val_mean += val; + val_max = max(val_max, val); + val_min = min(val_min, val); + val_cnt++; + } + } + } + } + if (val_cnt) { + val_mean /= val_cnt; + } else { + val_mean = 0; + val_min = 0; + val_max = 0; + } + + const float scale_z = ((val_max == val_min) ? 1 : 1/(val_max - val_min)) * autoscale_max; + + /** + * The 3D points go through a 3D graphics pipeline to determine the final 2D point on the screen. + * This is written out as a stack of macros that each apply an affine transformation to the point. + * At compile time, the compiler should be able to reduce these expressions. + * + * The last transformation in the chain (TRANSFORM_5) is initially set to a no-op so we can measure + * the dimensions of the grid, but is later replaced with a scaling transform that scales the grid + * to fit. + */ + + #define TRANSFORM_5(X,Y,Z) (X), (Y) // No transform + #define TRANSFORM_4(X,Y,Z) TRANSFORM_5((X)/(Z),(Y)/-(Z), 0) // Perspective + #define TRANSFORM_3(X,Y,Z) TRANSFORM_4((X), (Z), (Y)) // Swap Z and Y + #define TRANSFORM_2(X,Y,Z) TRANSFORM_3((X), (Y) + 2.5, (Z) - 1) // Translate + #define TRANSFORM(X,Y,Z) TRANSFORM_2(float(X)/(cols-1) - 0.5, float(Y)/(rows-1) - 0.5, (Z)) // Normalize + + // Compute the bounding box for the grid prior to scaling. Do this at compile-time by + // transforming the four corner points via the transformation equations and finding + // the min and max for each axis. + + constexpr float bounds[][3] = {{TRANSFORM(0 , 0 , 0)}, + {TRANSFORM(cols-1, 0 , 0)}, + {TRANSFORM(0 , rows-1, 0)}, + {TRANSFORM(cols-1, rows-1, 0)}}; + #define APPLY(FUNC, AXIS) FUNC(FUNC(bounds[0][AXIS], bounds[1][AXIS]), FUNC(bounds[2][AXIS], bounds[3][AXIS])) + constexpr float grid_x = APPLY(min,0); + constexpr float grid_y = APPLY(min,1); + constexpr float grid_w = APPLY(max,0) - grid_x; + constexpr float grid_h = APPLY(max,1) - grid_y; + constexpr float grid_cx = grid_x + grid_w/2; + constexpr float grid_cy = grid_y + grid_h/2; + + // Figure out scale and offset such that the grid fits within the rectangle given by (x,y,w,h) + + const float scale_x = float(w)/grid_w; + const float scale_y = float(h)/grid_h; + const float center_x = x + w/2; + const float center_y = y + h/2; + + // Now replace the last transformation in the chain with a scaling operation. + + #undef TRANSFORM_5 + #define TRANSFORM_6(X,Y,Z) (X)*16, (Y)*16 // Scale to 1/16 pixel units + #define TRANSFORM_5(X,Y,Z) TRANSFORM_6( center_x + ((X) - grid_cx) * scale_x, \ + center_y + ((Y) - grid_cy) * scale_y, 0) // Scale to bounds + + // Draw the grid + + const uint16_t basePointSize = min(w,h) / max(cols,rows); + + CommandProcessor cmd; + cmd.cmd(SAVE_CONTEXT()) + .cmd(TAG_MASK(false)) + .cmd(SAVE_CONTEXT()); + + for (uint8_t y = 0; y < rows; y++) { + for (uint8_t x = 0; x < cols; x++) { + if (ISVAL(x,y)) { + const bool hasLeftSegment = x < cols - 1 && ISVAL(x+1,y); + const bool hasRightSegment = y < rows - 1 && ISVAL(x,y+1); + if (hasLeftSegment || hasRightSegment) { + cmd.cmd(BEGIN(LINE_STRIP)); + if (hasLeftSegment) cmd.cmd(VERTEX2F(TRANSFORM(x + 1, y , HEIGHT(x + 1, y )))); + cmd.cmd( VERTEX2F(TRANSFORM(x , y , HEIGHT(x , y )))); + if (hasRightSegment) cmd.cmd(VERTEX2F(TRANSFORM(x , y + 1, HEIGHT(x , y + 1)))); + } + } + } + + if (opts & USE_POINTS) { + const float sq_min = sq(val_min - val_mean); + const float sq_max = sq(val_max - val_mean); + cmd.cmd(POINT_SIZE(basePointSize * 2)); + cmd.cmd(BEGIN(POINTS)); + for (uint8_t x = 0; x < cols; x++) { + if (ISVAL(x,y)) { + if (opts & USE_COLORS) { + const float val_dev = VALUE(x, y) - val_mean; + const uint8_t neg_byte = sq(val_dev) / (val_dev < 0 ? sq_min : sq_max) * 0xFF; + const uint8_t pos_byte = 255 - neg_byte; + cmd.cmd(COLOR_RGB(pos_byte, pos_byte, 0xFF)); + } + cmd.cmd(VERTEX2F(TRANSFORM(x, y, HEIGHT(x, y)))); + } + } + if (opts & USE_COLORS) { + cmd.cmd(RESTORE_CONTEXT()) + .cmd(SAVE_CONTEXT()); + } + } + } + cmd.cmd(RESTORE_CONTEXT()) + .cmd(TAG_MASK(true)); + + if (opts & USE_TAGS) { + cmd.cmd(COLOR_MASK(false, false, false, false)) + .cmd(POINT_SIZE(basePointSize * 10)) + .cmd(BEGIN(POINTS)); + for (uint8_t y = 0; y < rows; y++) { + for (uint8_t x = 0; x < cols; x++) { + const uint8_t tag = pointToTag(x, y); + cmd.tag(tag).cmd(VERTEX2F(TRANSFORM(x, y, HEIGHT(x, y)))); + } + } + cmd.cmd(COLOR_MASK(true, true, true, true)); + } + + if (opts & USE_HIGHLIGHT) { + const uint8_t tag = screen_data.BedMeshScreen.highlightedTag; + uint8_t x, y; + if (tagToPoint(tag, x, y)) { + cmd.cmd(COLOR_A(128)) + .cmd(POINT_SIZE(basePointSize * 6)) + .cmd(BEGIN(POINTS)) + .tag(tag).cmd(VERTEX2F(TRANSFORM(x, y, HEIGHT(x, y)))); + } + } + cmd.cmd(END()); + cmd.cmd(RESTORE_CONTEXT()); +} + +uint8_t BedMeshScreen::pointToTag(uint8_t x, uint8_t y) { + return y * (GRID_MAX_POINTS_X) + x + 10; +} + +bool BedMeshScreen::tagToPoint(uint8_t tag, uint8_t &x, uint8_t &y) { + if (tag < 10) return false; + x = (tag - 10) % (GRID_MAX_POINTS_X); + y = (tag - 10) / (GRID_MAX_POINTS_X); + return true; +} + +void BedMeshScreen::onEntry() { + screen_data.BedMeshScreen.highlightedTag = 0; + screen_data.BedMeshScreen.count = GRID_MAX_POINTS; + screen_data.BedMeshScreen.message = screen_data.BedMeshScreen.MSG_NONE; + BaseScreen::onEntry(); +} + +float BedMeshScreen::getHightlightedValue() { + if (screen_data.BedMeshScreen.highlightedTag) { + xy_uint8_t pt; + tagToPoint(screen_data.BedMeshScreen.highlightedTag, pt.x, pt.y); + return ExtUI::getMeshPoint(pt); + } + return NAN; +} + +void BedMeshScreen::drawHighlightedPointValue() { + char str[16]; + const float val = getHightlightedValue(); + const bool isGood = !isnan(val); + if (isGood) + dtostrf(val, 5, 3, str); + else + strcpy_P(str, PSTR("-")); + + CommandProcessor cmd; + cmd.font(Theme::font_medium) + .text(Z_LABEL_POS, GET_TEXT_F(MSG_MESH_EDIT_Z)) + .text(Z_VALUE_POS, str) + .colors(action_btn) + .tag(1).button( OKAY_POS, GET_TEXT_F(MSG_BUTTON_OKAY)) + .tag(0); + + switch (screen_data.BedMeshScreen.message) { + case screen_data.BedMeshScreen.MSG_MESH_COMPLETE: cmd.text(MESSAGE_POS, GET_TEXT_F(MSG_BED_MAPPING_DONE)); break; + case screen_data.BedMeshScreen.MSG_MESH_INCOMPLETE: cmd.text(MESSAGE_POS, GET_TEXT_F(MSG_BED_MAPPING_INCOMPLETE)); break; + default: break; + } +} + +void BedMeshScreen::onRedraw(draw_mode_t what) { + #define _INSET_POS(x,y,w,h) x + min(w,h)/10, y + min(w,h)/10, w - min(w,h)/5, h - min(w,h)/5 + #define INSET_POS(pos) _INSET_POS(pos) + + if (what & BACKGROUND) { + CommandProcessor cmd; + cmd.cmd(CLEAR_COLOR_RGB(bg_color)) + .cmd(CLEAR(true,true,true)); + + // Draw the shadow and tags + cmd.cmd(COLOR_RGB(0x444444)); + BedMeshScreen::drawMesh(INSET_POS(MESH_POS), nullptr, USE_POINTS | USE_TAGS); + cmd.cmd(COLOR_RGB(bg_text_enabled)); + } + + if (what & FOREGROUND) { + constexpr float autoscale_max_amplitude = 0.03; + const bool gotAllPoints = screen_data.BedMeshScreen.count >= GRID_MAX_POINTS; + if (gotAllPoints) { + drawHighlightedPointValue(); + } + const float levelingProgress = sq(float(screen_data.BedMeshScreen.count) / GRID_MAX_POINTS); + BedMeshScreen::drawMesh(INSET_POS(MESH_POS), ExtUI::getMeshArray(), + USE_POINTS | USE_HIGHLIGHT | USE_AUTOSCALE | (gotAllPoints ? USE_COLORS : 0), + autoscale_max_amplitude * levelingProgress + ); + } +} + +bool BedMeshScreen::onTouchStart(uint8_t tag) { + screen_data.BedMeshScreen.highlightedTag = tag; + return true; +} + +bool BedMeshScreen::onTouchEnd(uint8_t tag) { + switch (tag) { + case 1: + GOTO_PREVIOUS(); + return true; + default: + return false; + } +} + +void BedMeshScreen::onMeshUpdate(const int8_t, const int8_t, const float) { + if (AT_SCREEN(BedMeshScreen)) + onRefresh(); +} + +bool BedMeshScreen::isMeshComplete(ExtUI::bed_mesh_t data) { + for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) { + for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) { + if (isnan(data[x][y])) { + return false; + } + } + } + return true; +} + +void BedMeshScreen::onMeshUpdate(const int8_t x, const int8_t y, const ExtUI::probe_state_t state) { + switch (state) { + case ExtUI::MESH_START: + screen_data.BedMeshScreen.count = 0; + screen_data.BedMeshScreen.message = screen_data.BedMeshScreen.MSG_NONE; + break; + case ExtUI::MESH_FINISH: + if (screen_data.BedMeshScreen.count == GRID_MAX_POINTS && isMeshComplete(ExtUI::getMeshArray())) { + screen_data.BedMeshScreen.message = screen_data.BedMeshScreen.MSG_MESH_COMPLETE; + } else { + screen_data.BedMeshScreen.message = screen_data.BedMeshScreen.MSG_MESH_INCOMPLETE; + } + screen_data.BedMeshScreen.count = GRID_MAX_POINTS; + break; + case ExtUI::PROBE_START: + screen_data.BedMeshScreen.highlightedTag = pointToTag(x, y); + break; + case ExtUI::PROBE_FINISH: + screen_data.BedMeshScreen.count++; + break; + } + BedMeshScreen::onMeshUpdate(x, y, 0); +} + +void BedMeshScreen::startMeshProbe() { + GOTO_SCREEN(BedMeshScreen); + screen_data.BedMeshScreen.count = 0; + injectCommands_P(PSTR(BED_LEVELING_COMMANDS)); +} + +#endif // TOUCH_UI_FTDI_EVE && HAS_MESH diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_advanced_settings.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_advanced_settings.cpp similarity index 93% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_advanced_settings.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_advanced_settings.cpp index 0c53dca61b4e..76ebdca587e4 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_advanced_settings.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_advanced_settings.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -45,20 +45,20 @@ void AdvancedSettingsMenu::onRedraw(draw_mode_t what) { .tag(2) .button( BTN_POS(1,1), BTN_SIZE(1,1), GET_TEXT_F(MSG_DISPLAY_MENU)) .enabled( - #if HAS_TRINAMIC + #if HAS_TRINAMIC_CONFIG 1 #endif ) .tag(3) .button( BTN_POS(1,2), BTN_SIZE(1,1), GET_TEXT_F(MSG_TMC_CURRENT)) .enabled( - #if HAS_TRINAMIC + #if HAS_TRINAMIC_CONFIG 1 #endif ) .tag(4) .button( BTN_POS(1,3), BTN_SIZE(1,1), GET_TEXT_F(MSG_TMC_HOMING_THRS)) .tag(5) .button( BTN_POS(1,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_LCD_ENDSTOPS)) .enabled( - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND 1 #endif ) @@ -68,7 +68,7 @@ void AdvancedSettingsMenu::onRedraw(draw_mode_t what) { .tag(7) .button( BTN_POS(2,1), BTN_SIZE(1,1), GET_TEXT_F(MSG_STEPS_PER_MM)) .tag(8) .button( BTN_POS(2,2), BTN_SIZE(1,1), GET_TEXT_F(MSG_VELOCITY)) .tag(9) .button( BTN_POS(2,3), BTN_SIZE(1,1), GET_TEXT_F(MSG_ACCELERATION)) - #if DISABLED(CLASSIC_JERK) + #if HAS_JUNCTION_DEVIATION .tag(10) .button( BTN_POS(2,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_JUNCTION_DEVIATION)) #else .tag(10) .button( BTN_POS(2,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_JERK)) @@ -85,7 +85,7 @@ void AdvancedSettingsMenu::onRedraw(draw_mode_t what) { #endif ) .tag(12) .button( BTN_POS(1,6), BTN_SIZE(2,1), GET_TEXT_F(MSG_LINEAR_ADVANCE)) - .tag(13) .button( BTN_POS(1,7), BTN_SIZE(2,1), GET_TEXT_F(MSG_INTERFACE_SETTINGS)) + .tag(13) .button( BTN_POS(1,7), BTN_SIZE(2,1), GET_TEXT_F(MSG_INTERFACE)) .tag(14) .button( BTN_POS(1,8), BTN_SIZE(2,1), GET_TEXT_F(MSG_RESTORE_DEFAULTS)) .colors(action_btn) .tag(1). button( BTN_POS(1,9), BTN_SIZE(2,1), GET_TEXT_F(MSG_BACK)); @@ -100,12 +100,12 @@ bool AdvancedSettingsMenu::onTouchEnd(uint8_t tag) { switch (tag) { case 1: SaveSettingsDialogBox::promptToSaveSettings(); break; case 2: GOTO_SCREEN(DisplayTuningScreen); break; - #if HAS_TRINAMIC + #if HAS_TRINAMIC_CONFIG case 3: GOTO_SCREEN(StepperCurrentScreen); break; case 4: GOTO_SCREEN(StepperBumpSensitivityScreen); break; #endif case 5: GOTO_SCREEN(EndstopStatesScreen); break; - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND case 6: GOTO_SCREEN(NozzleOffsetScreen); break; #endif @@ -113,7 +113,7 @@ bool AdvancedSettingsMenu::onTouchEnd(uint8_t tag) { case 8: GOTO_SCREEN(MaxVelocityScreen); break; case 9: GOTO_SCREEN(DefaultAccelerationScreen); break; case 10: - #if DISABLED(CLASSIC_JERK) + #if HAS_JUNCTION_DEVIATION GOTO_SCREEN(JunctionDeviationScreen); #else GOTO_SCREEN(JerkScreen); diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_confirm_home_e.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_confirm_home_e.cpp similarity index 85% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_confirm_home_e.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_confirm_home_e.cpp index a3254bae9ae4..da772971ce01 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_confirm_home_e.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_confirm_home_e.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -36,11 +36,13 @@ void BioConfirmHomeE::onRedraw(draw_mode_t) { bool BioConfirmHomeE::onTouchEnd(uint8_t tag) { switch (tag) { case 1: - SpinnerDialogBox::enqueueAndWait_P(F( - "G28 E\n" - AXIS_LEVELING_COMMANDS "\n" - PARK_AND_RELEASE_COMMANDS - )); + #if defined(AXIS_LEVELING_COMMANDS) && defined(PARK_AND_RELEASE_COMMANDS) + SpinnerDialogBox::enqueueAndWait_P(F( + "G28 E\n" + AXIS_LEVELING_COMMANDS "\n" + PARK_AND_RELEASE_COMMANDS + )); + #endif current_screen.forget(); break; case 2: diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_confirm_home_xyz.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_confirm_home_xyz.cpp similarity index 88% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_confirm_home_xyz.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_confirm_home_xyz.cpp index 883a446b3ea9..48ce320482b2 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_confirm_home_xyz.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_confirm_home_xyz.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -36,10 +36,12 @@ void BioConfirmHomeXYZ::onRedraw(draw_mode_t) { bool BioConfirmHomeXYZ::onTouchEnd(uint8_t tag) { switch (tag) { case 1: - SpinnerDialogBox::enqueueAndWait_P(F( - "G28\n" - PARK_AND_RELEASE_COMMANDS - )); + #ifdef PARK_AND_RELEASE_COMMANDS + SpinnerDialogBox::enqueueAndWait_P(F( + "G28\n" + PARK_AND_RELEASE_COMMANDS + )); + #endif current_screen.forget(); break; case 2: diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_main_menu.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_main_menu.cpp similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_main_menu.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_main_menu.cpp index 40ed8479ee64..e2bb8a241402 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_main_menu.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_main_menu.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -51,7 +51,7 @@ void MainMenu::onRedraw(draw_mode_t what) { .tag(4).button( BTN_POS(1,4), BTN_SIZE(2,1), GET_TEXT_F(MSG_RELEASE_XY_AXIS)) .tag(5).button( BTN_POS(1,5), BTN_SIZE(2,1), GET_TEXT_F(MSG_AUTOLEVEL_X_AXIS)) .tag(6).button( BTN_POS(1,6), BTN_SIZE(2,1), GET_TEXT_F(MSG_BED_TEMPERATURE)) - .tag(7).button( BTN_POS(1,7), BTN_SIZE(2,1), GET_TEXT_F(MSG_INTERFACE_SETTINGS)) + .tag(7).button( BTN_POS(1,7), BTN_SIZE(2,1), GET_TEXT_F(MSG_INTERFACE)) .tag(8).button( BTN_POS(1,8), BTN_SIZE(2,1), GET_TEXT_F(MSG_ADVANCED_SETTINGS)) .tag(9).button( BTN_POS(1,9), BTN_SIZE(2,1), GET_TEXT_F(MSG_INFO_MENU)) .colors(action_btn) @@ -72,7 +72,9 @@ bool MainMenu::onTouchEnd(uint8_t tag) { case 2: GOTO_SCREEN(BioConfirmHomeXYZ); break; case 3: SpinnerDialogBox::enqueueAndWait_P(e_homed ? F("G0 E0 F120") : F("G112")); break; case 4: StatusScreen::unlockMotors(); break; + #ifdef AXIS_LEVELING_COMMANDS case 5: SpinnerDialogBox::enqueueAndWait_P(F(AXIS_LEVELING_COMMANDS)); break; + #endif case 6: GOTO_SCREEN(TemperatureScreen); break; case 7: GOTO_SCREEN(InterfaceSettingsScreen); break; case 8: GOTO_SCREEN(AdvancedSettingsMenu); break; diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_printer_ui_landscape.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_printer_ui_landscape.h similarity index 98% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_printer_ui_landscape.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_printer_ui_landscape.h index 1c7c02093d0f..9279fd7df0d6 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_printer_ui_landscape.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_printer_ui_landscape.h @@ -11,7 +11,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ /** diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_printer_ui_portrait.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_printer_ui_portrait.h similarity index 98% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_printer_ui_portrait.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_printer_ui_portrait.h index 32f52f8e4660..f03e3413f833 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_printer_ui_portrait.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_printer_ui_portrait.h @@ -11,7 +11,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ /** diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_printing_dialog_box.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_printing_dialog_box.cpp similarity index 94% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_printing_dialog_box.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_printing_dialog_box.cpp index 40130650867e..c5e26da98a32 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_printing_dialog_box.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_printing_dialog_box.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -102,12 +102,11 @@ bool BioPrintingDialogBox::onTouchEnd(uint8_t 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; + if (isPrinting()) + GOTO_SCREEN(ConfirmAbortPrintDialogBox); + else + GOTO_SCREEN(StatusScreen); + break; default: return false; } return true; @@ -136,9 +135,8 @@ void BioPrintingDialogBox::setStatusMessage(const char* message) { SERIAL_ECHOLNPAIR("New status message: ", message); #endif - if (AT_SCREEN(BioPrintingDialogBox)) { + if (AT_SCREEN(BioPrintingDialogBox)) current_screen.onRefresh(); - } } void BioPrintingDialogBox::onIdle() { diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_status_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_status_screen.cpp similarity index 89% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_status_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_status_screen.cpp index ec7f2bcffb47..e881995f2e69 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_status_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_status_screen.cpp @@ -18,7 +18,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -29,7 +29,9 @@ #include "../ftdi_eve_lib/extras/poly_ui.h" -#ifdef TOUCH_UI_PORTRAIT +#if ENABLED(TOUCH_UI_COCOA_PRESS) + #include "cocoa_press_ui.h" +#elif ENABLED(TOUCH_UI_PORTRAIT) #include "bio_printer_ui_portrait.h" #else #include "bio_printer_ui_landscape.h" @@ -100,7 +102,7 @@ void StatusScreen::draw_temperature(draw_mode_t what) { // heating zones, but has no bed temperature cmd.cmd(COLOR_RGB(bg_text_enabled)); - cmd.font(font_medium); + cmd.font(font_xsmall); ui.bounds(POLY(h0_label), x, y, h, v); cmd.text(x, y, h, v, GET_TEXT_F(MSG_ZONE_1)); @@ -198,16 +200,14 @@ void StatusScreen::draw_temperature(draw_mode_t what) { void StatusScreen::draw_syringe(draw_mode_t what) { int16_t x, y, h, v; - #ifdef E_MAX_POS - const float fill_level = 1.0 - min(1.0, max(0.0, getAxisPosition_mm(E0) / E_MAX_POS)); - #else - const float fill_level = 0.75; - #endif - const bool e_homed = (true - #if ENABLED(TOUCH_UI_LULZBOT_BIO) - && isAxisPositionKnown(E0) + const float fill_level = ( + #ifdef E_MAX_POS + 1.0 - min(1.0, max(0.0, getAxisPosition_mm(E0) / E_MAX_POS)) + #else + 0.75 #endif ); + const bool e_homed = TERN0(TOUCH_UI_LULZBOT_BIO, isAxisPositionKnown(E0)); CommandProcessor cmd; PolyUI ui(cmd, what); @@ -223,7 +223,7 @@ void StatusScreen::draw_syringe(draw_mode_t what) { ui.color(syringe_rgb); ui.fill(POLY(syringe_outline)); - ui.color(fill_rgb); + ui.color(fluid_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))); @@ -237,12 +237,8 @@ void StatusScreen::draw_syringe(draw_mode_t what) { } void StatusScreen::draw_arrows(draw_mode_t what) { - const bool e_homed = (true - #if ENABLED(TOUCH_UI_LULZBOT_BIO) - && isAxisPositionKnown(E0) - #endif - ); - const bool z_homed = isAxisPositionKnown(Z); + const bool e_homed = TERN1(TOUCH_UI_LULZBOT_BIO, isAxisPositionKnown(E0)), + z_homed = isAxisPositionKnown(Z); CommandProcessor cmd; PolyUI ui(cmd, what); @@ -251,23 +247,25 @@ void StatusScreen::draw_arrows(draw_mode_t what) { ui.button_stroke(stroke_rgb, 28); ui.button_shadow(shadow_rgb, shadow_depth); + constexpr uint8_t style = TERN(TOUCH_UI_COCOA_PRESS, PolyUI::FILL | PolyUI::SHADOW, PolyUI::REGULAR); + 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)); + ui.button(1, POLY(x_neg), style); + ui.button(2, POLY(x_pos), style); + ui.button(3, POLY(y_neg), style); + ui.button(4, POLY(y_pos), style); } if ((what & BACKGROUND) || z_homed) { - ui.button(5, POLY(z_neg)); - ui.button(6, POLY(z_pos)); + ui.button(5, POLY(z_neg), style); + ui.button(6, POLY(z_pos), style); } if ((what & BACKGROUND) || e_homed) { #if DISABLED(TOUCH_UI_COCOA_PRESS) - ui.button(7, POLY(e_neg)); + ui.button(7, POLY(e_neg), style); #endif - ui.button(8, POLY(e_pos)); + ui.button(8, POLY(e_pos), style); } } @@ -299,24 +297,21 @@ void StatusScreen::draw_fine_motion(draw_mode_t what) { } void StatusScreen::draw_overlay_icons(draw_mode_t what) { - const bool e_homed = (true - #if ENABLED(TOUCH_UI_LULZBOT_BIO) - && isAxisPositionKnown(E0) - #endif - ); - const bool z_homed = isAxisPositionKnown(Z); + const bool e_homed = TERN1(TOUCH_UI_LULZBOT_BIO, isAxisPositionKnown(E0)), + z_homed = isAxisPositionKnown(Z); CommandProcessor cmd; PolyUI ui(cmd, what); if (what & FOREGROUND) { - ui.button_fill (fill_rgb); + ui.button_fill (TERN(TOUCH_UI_COCOA_PRESS, stroke_rgb, 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)); + constexpr uint8_t style = TERN(TOUCH_UI_COCOA_PRESS, PolyUI::FILL | PolyUI::SHADOW, PolyUI::REGULAR); + if (!jog_xy) ui.button(12, POLY(padlock), style); + if (!e_homed) ui.button(13, POLY(home_e), style); + if (!z_homed) ui.button(14, POLY(home_z), style); } } diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_tune_menu.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_tune_menu.cpp similarity index 95% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_tune_menu.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_tune_menu.cpp index 27312c733fd7..0d8d71b45ce1 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/bio_tune_menu.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bio_tune_menu.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -50,11 +50,7 @@ void TuneMenu::onRedraw(draw_mode_t what) { .font(font_medium) .enabled( isPrinting()).tag(2).button( BTN_POS(1,2), BTN_SIZE(2,1), GET_TEXT_F(MSG_PRINT_SPEED)) .tag(3).button( BTN_POS(1,3), BTN_SIZE(2,1), GET_TEXT_F(MSG_BED_TEMPERATURE)) - .enabled( - #if ENABLED(BABYSTEPPING) - true - #endif - ) + .enabled(TERN_(BABYSTEPPING, true)) .tag(4).button( BTN_POS(1,4), BTN_SIZE(2,1), GET_TEXT_F(MSG_NUDGE_NOZZLE)) .enabled(!isPrinting()).tag(5).button( BTN_POS(1,5), BTN_SIZE(2,1), GET_TEXT_F(MSG_MOVE_TO_HOME)) .enabled(!isPrinting()).tag(6).button( BTN_POS(1,6), BTN_SIZE(2,1), GET_TEXT_F(MSG_RAISE_PLUNGER)) diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/boot_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/boot_screen.cpp similarity index 90% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/boot_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/boot_screen.cpp index 996c12cf23fd..4ce8f608f123 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/boot_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/boot_screen.cpp @@ -18,7 +18,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -32,7 +32,7 @@ #ifdef SHOW_CUSTOM_BOOTSCREEN #ifdef TOUCH_UI_PORTRAIT - #include "../theme/_bootscreen_portrait.h" + #include "../theme/bootscreen_logo_portrait.h" #else #include "../theme/_bootscreen_landscape.h" #endif @@ -68,10 +68,10 @@ void BootScreen::onIdle() { InterfaceSettingsScreen::failSafeSettings(); StatusScreen::loadBitmaps(); + StatusScreen::setStatusMessage(GET_TEXT_F(WELCOME_MSG)); GOTO_SCREEN(TouchCalibrationScreen); current_screen.forget(); PUSH_SCREEN(StatusScreen); - StatusScreen::setStatusMessage(GET_TEXT_F(WELCOME_MSG)); } else { if (!UIFlashStorage::is_valid()) { StatusScreen::loadBitmaps(); @@ -80,12 +80,14 @@ void BootScreen::onIdle() { 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(); - } + #if DISABLED(TOUCH_UI_NO_BOOTSCREEN) + 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(); + } + #endif StatusScreen::loadBitmaps(); diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/case_light_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/case_light_screen.cpp similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/case_light_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/case_light_screen.cpp index b82149c85959..776a9fe5f716 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/case_light_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/case_light_screen.cpp @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/change_filament_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/change_filament_screen.cpp similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/change_filament_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/change_filament_screen.cpp index 2d1e0d66272f..589da9b21055 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/change_filament_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/change_filament_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -111,6 +111,7 @@ void ChangeFilamentScreen::onRedraw(draw_mode_t what) { if (what & BACKGROUND) { cmd.cmd(CLEAR_COLOR_RGB(bg_color)) .cmd(CLEAR(true,true,true)) + .cmd(COLOR_RGB(bg_text_enabled)) .tag(0) #ifdef TOUCH_UI_PORTRAIT .font(font_large) @@ -119,7 +120,7 @@ void ChangeFilamentScreen::onRedraw(draw_mode_t what) { #endif .text(BTN_POS(1,1), BTN_SIZE(2,1), GET_TEXT_F(MSG_EXTRUDER_SELECTION)) #ifdef TOUCH_UI_PORTRAIT - .text(BTN_POS(1,7), BTN_SIZE(1,1), F("")) + .text(BTN_POS(1,7), BTN_SIZE(1,1), GET_TEXT_F(MSG_CURRENT_TEMPERATURE)) #else .text(BTN_POS(3,1), BTN_SIZE(2,1), GET_TEXT_F(MSG_CURRENT_TEMPERATURE)) .font(font_small) @@ -171,8 +172,8 @@ void ChangeFilamentScreen::onRedraw(draw_mode_t what) { 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; + #if HAS_MULTI_HOTEND + const bool tog11 = screen_data.ChangeFilamentScreen.e_tag == 11; #endif #ifdef TOUCH_UI_PORTRAIT @@ -206,13 +207,13 @@ void ChangeFilamentScreen::onRedraw(draw_mode_t what) { { char str[30]; - format_temp_and_material(str, LOW_TEMP, GET_TEXT(MSG_MATERIAL_PLA)); + format_temp(str, LOW_TEMP); cmd.tag(2) .TOG_STYLE(tog2) .button (BTN_POS(2,6), BTN_SIZE(1,1), str); - format_temp_and_material(str, MED_TEMP, GET_TEXT(MSG_MATERIAL_ABS)); + format_temp(str, MED_TEMP); cmd.tag(3) .TOG_STYLE(tog3) .button (BTN_POS(2,5), BTN_SIZE(1,1), str); - format_temp_and_material(str, HIGH_TEMP, GET_TEXT(MSG_MATERIAL_HIGH_TEMP)); + format_temp(str, HIGH_TEMP); cmd.tag(4) .TOG_STYLE(tog4) .button (BTN_POS(2,4), BTN_SIZE(1,1), str); } cmd.colors(normal_btn) diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/confirm_abort_print_dialog_box.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/confirm_abort_print_dialog_box.cpp similarity index 95% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/confirm_abort_print_dialog_box.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/confirm_abort_print_dialog_box.cpp index 933894259e73..e23592a46e9f 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/confirm_abort_print_dialog_box.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/confirm_abort_print_dialog_box.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/confirm_auto_calibration_dialog_box.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/confirm_auto_calibration_dialog_box.cpp similarity index 93% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/confirm_auto_calibration_dialog_box.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/confirm_auto_calibration_dialog_box.cpp index deae90fe9307..7e1a82025ddc 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/confirm_auto_calibration_dialog_box.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/confirm_auto_calibration_dialog_box.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -38,7 +38,7 @@ bool ConfirmAutoCalibrationDialogBox::onTouchEnd(uint8_t tag) { switch (tag) { case 1: GOTO_SCREEN(StatusScreen); - injectCommands_P(PSTR(CALIBRATION_COMMANDS)); + injectCommands_P(PSTR("G425")); return true; default: return DialogBoxBaseClass::onTouchEnd(tag); diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/confirm_erase_flash_dialog_box.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/confirm_erase_flash_dialog_box.cpp similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/confirm_erase_flash_dialog_box.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/confirm_erase_flash_dialog_box.cpp index 1e16546003bb..574de2108829 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/confirm_erase_flash_dialog_box.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/confirm_erase_flash_dialog_box.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/confirm_start_print_dialog_box.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/confirm_start_print_dialog_box.cpp similarity index 93% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/confirm_start_print_dialog_box.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/confirm_start_print_dialog_box.cpp index 5c691cb9a1d0..4e5b174d53f0 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/confirm_start_print_dialog_box.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/confirm_start_print_dialog_box.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -31,11 +31,6 @@ using namespace FTDI; using namespace Theme; using namespace ExtUI; -void ConfirmStartPrintDialogBox::onEntry() { - BaseScreen::onEntry(); - sound.play(twinkle, PLAY_ASYNCHRONOUS); -} - void ConfirmStartPrintDialogBox::onRedraw(draw_mode_t) { const char *filename = getLongFilename(); char buffer[strlen_P(GET_TEXT(MSG_START_PRINT_CONFIRMATION)) + strlen(filename) + 1]; diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/confirm_user_request_alert_box.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/confirm_user_request_alert_box.cpp similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/confirm_user_request_alert_box.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/confirm_user_request_alert_box.cpp index cc132064ecae..6b6affadd569 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/confirm_user_request_alert_box.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/confirm_user_request_alert_box.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/default_acceleration_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/default_acceleration_screen.cpp similarity index 97% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/default_acceleration_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/default_acceleration_screen.cpp index 21be095f963e..8496955f732c 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/default_acceleration_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/default_acceleration_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/developer_menu.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/developer_menu.cpp similarity index 98% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/developer_menu.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/developer_menu.cpp index b3b674ebd311..8e56c4197bbd 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/developer_menu.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/developer_menu.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/dialog_box_base_class.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/dialog_box_base_class.cpp similarity index 97% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/dialog_box_base_class.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/dialog_box_base_class.cpp index 7f3a27e9e8fd..782ae7bbc7f8 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/dialog_box_base_class.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/dialog_box_base_class.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/display_tuning_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/display_tuning_screen.cpp similarity index 97% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/display_tuning_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/display_tuning_screen.cpp index b449634b1a1a..8845dfb5c0aa 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/display_tuning_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/display_tuning_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/endstop_state_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/endstop_state_screen.cpp similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/endstop_state_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/endstop_state_screen.cpp index 4510c93416d4..7f3f507fd64f 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/endstop_state_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/endstop_state_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -92,12 +92,12 @@ void EndstopStatesScreen::onRedraw(draw_mode_t) { PIN_DISABLED(5, 3, PSTR(STR_Z_MIN), Z_MIN) #endif #if ENABLED(FILAMENT_RUNOUT_SENSOR) && PIN_EXISTS(FIL_RUNOUT) - PIN_ENABLED (1, 4, GET_TEXT_F(MSG_RUNOUT_1), FIL_RUNOUT, FIL_RUNOUT_INVERTING) + PIN_ENABLED (1, 4, GET_TEXT_F(MSG_RUNOUT_1), FIL_RUNOUT, FIL_RUNOUT_STATE) #else PIN_DISABLED(1, 4, GET_TEXT_F(MSG_RUNOUT_1), FIL_RUNOUT) #endif - #if ENABLED(FILAMENT_RUNOUT_SENSOR) && PIN_EXISTS(FIL_RUNOUT2) - PIN_ENABLED (3, 4, GET_TEXT_F(MSG_RUNOUT_2), FIL_RUNOUT2, FIL_RUNOUT_INVERTING) + #if BOTH(HAS_MULTI_EXTRUDER, FILAMENT_RUNOUT_SENSOR) && PIN_EXISTS(FIL_RUNOUT2) + PIN_ENABLED (3, 4, GET_TEXT_F(MSG_RUNOUT_2), FIL_RUNOUT2, FIL_RUNOUT_STATE) #else PIN_DISABLED(3, 4, GET_TEXT_F(MSG_RUNOUT_2), FIL_RUNOUT2) #endif diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/feedrate_percent_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/feedrate_percent_screen.cpp similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/feedrate_percent_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/feedrate_percent_screen.cpp index bd8e648e1125..2698708e51ba 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/feedrate_percent_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/feedrate_percent_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/filament_menu.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/filament_menu.cpp similarity index 60% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/filament_menu.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/filament_menu.cpp index 3972a14ef98a..82ee118e4c68 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/filament_menu.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/filament_menu.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -30,6 +30,22 @@ using namespace FTDI; using namespace ExtUI; using namespace Theme; +#ifdef TOUCH_UI_PORTRAIT + #define GRID_ROWS 9 + #define GRID_COLS 2 + #define TITLE_POS BTN_POS(1,1), BTN_SIZE(2,1) + #define RUNOUT_SENSOR_POS BTN_POS(1,2), BTN_SIZE(2,1) + #define LIN_ADVANCE_POS BTN_POS(1,3), BTN_SIZE(2,1) + #define BACK_POS BTN_POS(1,9), BTN_SIZE(2,1) +#else + #define GRID_ROWS 6 + #define GRID_COLS 2 + #define TITLE_POS BTN_POS(1,1), BTN_SIZE(2,1) + #define RUNOUT_SENSOR_POS BTN_POS(1,2), BTN_SIZE(2,1) + #define LIN_ADVANCE_POS BTN_POS(1,3), BTN_SIZE(2,1) + #define BACK_POS BTN_POS(1,6), BTN_SIZE(2,1) +#endif + void FilamentMenu::onRedraw(draw_mode_t what) { if (what & BACKGROUND) { CommandProcessor cmd; @@ -41,47 +57,14 @@ void FilamentMenu::onRedraw(draw_mode_t what) { 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), GET_TEXT_F(MSG_FILAMENT)) - .font(font_medium).colors(normal_btn) - .enabled( - #if ENABLED(FILAMENT_RUNOUT_SENSOR) - 1 - #endif - ) - .tag(2).button( BTN_POS(1,2), BTN_SIZE(2,1), GET_TEXT_F(MSG_RUNOUT_SENSOR)) - .enabled( - #if ENABLED(LIN_ADVANCE) - 1 - #endif - ) - .tag(3).button( BTN_POS(1,3), BTN_SIZE(2,1), GET_TEXT_F(MSG_LINEAR_ADVANCE)) - .colors(action_btn) - .tag(1) .button( BTN_POS(1,9), BTN_SIZE(2,1), GET_TEXT_F(MSG_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), GET_TEXT_F(MSG_FILAMENT)) - .font(font_medium).colors(normal_btn) - .enabled( - #if ENABLED(FILAMENT_RUNOUT_SENSOR) - 1 - #endif - ) - .tag(2).button( BTN_POS(1,2), BTN_SIZE(3,1), GET_TEXT_F(MSG_RUNOUT_SENSOR)) - .enabled( - #if ENABLED(LIN_ADVANCE) - 1 - #endif - ) - .tag(3).button( BTN_POS(1,3), BTN_SIZE(3,1), GET_TEXT_F(MSG_LINEAR_ADVANCE)) - .colors(action_btn) - .tag(1) .button( BTN_POS(1,6), BTN_SIZE(3,1), GET_TEXT_F(MSG_BACK)); - #endif + .text(TITLE_POS, GET_TEXT_F(MSG_FILAMENT)) + .font(font_medium).colors(normal_btn) + .enabled(ENABLED(FILAMENT_RUNOUT_SENSOR)) + .tag(2).button(RUNOUT_SENSOR_POS, GET_TEXT_F(MSG_RUNOUT_SENSOR)) + .enabled(ENABLED(LIN_ADVANCE)) + .tag(3).button(LIN_ADVANCE_POS, GET_TEXT_F(MSG_LINEAR_ADVANCE)) + .colors(action_btn) + .tag(1).button(BACK_POS, GET_TEXT_F(MSG_BACK)); } } diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/filament_runout_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/filament_runout_screen.cpp similarity index 94% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/filament_runout_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/filament_runout_screen.cpp index 9830123abbad..f1808bf20e69 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/filament_runout_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/filament_runout_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -35,7 +35,7 @@ void FilamentRunoutScreen::onRedraw(draw_mode_t what) { w.heading( GET_TEXT_F(MSG_FILAMENT)); w.toggle( 2, GET_TEXT_F(MSG_RUNOUT_SENSOR), getFilamentRunoutEnabled()); - #ifdef FILAMENT_RUNOUT_DISTANCE_MM + #if HAS_FILAMENT_RUNOUT_DISTANCE extern const char NUL_STR[]; w.heading(GET_TEXT_F(MSG_RUNOUT_DISTANCE_MM)); w.units(GET_TEXT_F(MSG_UNITS_MM)); @@ -51,7 +51,7 @@ bool FilamentRunoutScreen::onTouchHeld(uint8_t tag) { const float increment = getIncrement(); switch (tag) { case 2: setFilamentRunoutEnabled(!getFilamentRunoutEnabled()); break; - #ifdef FILAMENT_RUNOUT_DISTANCE_MM + #if HAS_FILAMENT_RUNOUT_DISTANCE case 10: UI_DECREMENT(FilamentRunoutDistance_mm); break; case 11: UI_INCREMENT(FilamentRunoutDistance_mm); break; #endif diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/files_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/files_screen.cpp similarity index 91% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/files_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/files_screen.cpp index d32ec4d07f3b..f4c224dbe8cf 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/files_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/files_screen.cpp @@ -17,12 +17,12 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" -#if ENABLED(TOUCH_UI_FTDI_EVE) +#if BOTH(TOUCH_UI_FTDI_EVE, SDSUPPORT) #include "screens.h" #include "screen_data.h" @@ -83,19 +83,19 @@ void FilesScreen::drawFileButton(const char* filename, uint8_t tag, bool is_dir, 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)); + constexpr uint16_t dim[2] = {BTN_SIZE(6,1)}; + #define POS_AND_SHORTEN(SHORTEN) BTN_POS(1,header_h+line), dim[0] - (SHORTEN), dim[1] + #define POS_AND_SIZE POS_AND_SHORTEN(0) #if ENABLED(SCROLL_LONG_FILENAMES) if (is_highlighted) { cmd.cmd(SAVE_CONTEXT()); cmd.cmd(MACRO(0)); - } + cmd.text(POS_AND_SIZE, filename, OPT_CENTERY | OPT_NOFIT); + } else #endif - cmd.text (BTN_POS(1,header_h+line), BTN_SIZE(6,1), filename, OPT_CENTERY - #if ENABLED(SCROLL_LONG_FILENAMES) - | OPT_NOFIT - #endif - ); - if (is_dir) { - cmd.text(BTN_POS(1,header_h+line), BTN_SIZE(6,1), F("> "), OPT_CENTERY | OPT_RIGHTX); + draw_text_with_ellipsis(cmd, POS_AND_SHORTEN(is_dir ? 20 : 0), filename, OPT_CENTERY, font_medium); + if (is_dir && !is_highlighted) { + cmd.text(POS_AND_SIZE, F("> "), OPT_CENTERY | OPT_RIGHTX); } #if ENABLED(SCROLL_LONG_FILENAMES) if (is_highlighted) { @@ -106,7 +106,7 @@ void FilesScreen::drawFileButton(const char* filename, uint8_t tag, bool is_dir, void FilesScreen::drawFileList() { FileList files; - screen_data.FilesScreen.num_page = max(1,(ceil)(float(files.count()) / files_per_page)); + 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(); @@ -115,10 +115,11 @@ void FilesScreen::drawFileList() { #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++) { + for (uint8_t i = 0; i < files_per_page; i++, fileIndex++) { if (files.seek(fileIndex)) { drawFileButton(files.filename(), getTagForLine(i), files.isDir(), false); - } else { + } + else { break; } } @@ -137,7 +138,6 @@ void FilesScreen::drawHeader() { 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) diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/interface_settings_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/interface_settings_screen.cpp similarity index 93% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/interface_settings_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/interface_settings_screen.cpp index 61875c52f1f3..c806ef499b65 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/interface_settings_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/interface_settings_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -29,7 +29,7 @@ #include "../archim2-flash/flash_storage.h" -#include "../../../../../module/configuration_store.h" +#include "../../../../../module/settings.h" #if ENABLED(LULZBOT_PRINTCOUNTER) #include "../../../../../module/printcounter.h" @@ -69,15 +69,19 @@ void InterfaceSettingsScreen::onRedraw(draw_mode_t what) { .cmd(COLOR_RGB(bg_text_enabled)) .tag(0) .font(font_medium) - .text(BTN_POS(1,1), BTN_SIZE(4,1), GET_TEXT_F(MSG_INTERFACE_SETTINGS)) + .text(BTN_POS(1,1), BTN_SIZE(4,1), GET_TEXT_F(MSG_INTERFACE)) #undef EDGE_R #define EDGE_R 30 .font(font_small) .tag(0) + #if DISABLED(LCD_FYSETC_TFT81050) .text(BTN_POS(1,2), BTN_SIZE(2,1), GET_TEXT_F(MSG_LCD_BRIGHTNESS), OPT_RIGHTX | OPT_CENTERY) + #endif .text(BTN_POS(1,3), BTN_SIZE(2,1), GET_TEXT_F(MSG_SOUND_VOLUME), OPT_RIGHTX | OPT_CENTERY) .text(BTN_POS(1,4), BTN_SIZE(2,1), GET_TEXT_F(MSG_SCREEN_LOCK), OPT_RIGHTX | OPT_CENTERY); + #if DISABLED(TOUCH_UI_NO_BOOTSCREEN) cmd.text(BTN_POS(1,5), BTN_SIZE(2,1), GET_TEXT_F(MSG_BOOT_SCREEN), OPT_RIGHTX | OPT_CENTERY); + #endif #undef EDGE_R } @@ -91,20 +95,24 @@ void InterfaceSettingsScreen::onRedraw(draw_mode_t what) { cmd.font(font_medium) #define EDGE_R 30 .colors(ui_slider) + #if DISABLED(LCD_FYSETC_TFT81050) .tag(2).slider(BTN_POS(3,2), BTN_SIZE(2,1), screen_data.InterfaceSettingsScreen.brightness, 128) + #endif .tag(3).slider(BTN_POS(3,3), BTN_SIZE(2,1), screen_data.InterfaceSettingsScreen.volume, 0xFF) .colors(ui_toggle) .tag(4).toggle2(BTN_POS(3,4), BTN_SIZE(w,1), GET_TEXT_F(MSG_NO), GET_TEXT_F(MSG_YES), LockScreen::is_enabled()) + #if DISABLED(TOUCH_UI_NO_BOOTSCREEN) .tag(5).toggle2(BTN_POS(3,5), BTN_SIZE(w,1), GET_TEXT_F(MSG_NO), GET_TEXT_F(MSG_YES), UIData::animations_enabled()) + #endif #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), GET_TEXT_F(MSG_INTERFACE_SOUNDS)) + .tag(6).button (BTN_POS(1,6), BTN_SIZE(4,1), GET_TEXT_F(MSG_SOUNDS)) .colors(action_btn) .tag(1).button (BTN_POS(1,7), BTN_SIZE(4,1), GET_TEXT_F(MSG_BACK)); #else - .tag(6).button (BTN_POS(1,6), BTN_SIZE(2,1), GET_TEXT_F(MSG_INTERFACE_SOUNDS)) + .tag(6).button (BTN_POS(1,6), BTN_SIZE(2,1), GET_TEXT_F(MSG_SOUNDS)) .colors(action_btn) .tag(1).button (BTN_POS(3,6), BTN_SIZE(2,1), GET_TEXT_F(MSG_BACK)); #endif @@ -153,7 +161,7 @@ void InterfaceSettingsScreen::onIdle() { CommandProcessor cmd; switch (cmd.track_tag(value)) { case 2: - screen_data.InterfaceSettingsScreen.brightness = float(value) * 128 / 0xFFFF; + screen_data.InterfaceSettingsScreen.brightness = max(11, (value * 128UL) / 0xFFFF); CLCD::set_brightness(screen_data.InterfaceSettingsScreen.brightness); SaveSettingsDialogBox::settingsChanged(); break; @@ -214,7 +222,7 @@ void InterfaceSettingsScreen::saveSettings(char *buff) { 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++) + for (uint8_t i = 0; i < InterfaceSoundsScreen::NUM_EVENTS; i++) eeprom.event_sounds[i] = InterfaceSoundsScreen::event_sounds[i]; memcpy(buff, &eeprom, sizeof(eeprom)); @@ -243,16 +251,14 @@ void InterfaceSettingsScreen::loadSettings(const char *buff) { 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++) + for (uint8_t i = 0; i < InterfaceSoundsScreen::NUM_EVENTS; i++) InterfaceSoundsScreen::event_sounds[i] = eeprom.event_sounds[i]; - #if ENABLED(TOUCH_UI_DEVELOPER_MENU) - StressTestScreen::startupCheck(); - #endif + TERN_(TOUCH_UI_DEVELOPER_MENU, StressTestScreen::startupCheck()); } #ifdef ARCHIM2_SPI_FLASH_EEPROM_BACKUP_SIZE - #include "../../../../../HAL/shared/persistent_store_api.h" + #include "../../../../../HAL/shared/eeprom_api.h" bool restoreEEPROM() { uint8_t data[ARCHIM2_SPI_FLASH_EEPROM_BACKUP_SIZE]; diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/interface_sounds_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/interface_sounds_screen.cpp similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/interface_sounds_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/interface_sounds_screen.cpp index 57f520e8abd1..25a44c1adbb5 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/interface_sounds_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/interface_sounds_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -43,7 +43,7 @@ void InterfaceSoundsScreen::toggleSoundSelection(event_t event) { } void InterfaceSoundsScreen::setSoundSelection(event_t event, const SoundPlayer::sound_t* sound) { - for(uint8_t i = 0; i < SoundList::n; i++) + for (uint8_t i = 0; i < SoundList::n; i++) if (SoundList::data(i) == sound) event_sounds[event] = i; } @@ -71,7 +71,7 @@ void InterfaceSoundsScreen::onRedraw(draw_mode_t what) { #define GRID_ROWS 9 .font(font_medium) - .text(BTN_POS(1,1), BTN_SIZE(4,1), GET_TEXT_F(MSG_INTERFACE_SOUNDS)) + .text(BTN_POS(1,1), BTN_SIZE(4,1), GET_TEXT_F(MSG_SOUNDS)) #undef EDGE_R #define EDGE_R 30 .font(font_small) diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/jerk_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/jerk_screen.cpp similarity index 97% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/jerk_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/jerk_screen.cpp index c208014cc75b..b96c2be7c80c 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/jerk_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/jerk_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/junction_deviation_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/junction_deviation_screen.cpp similarity index 93% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/junction_deviation_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/junction_deviation_screen.cpp index 034ac15c42e7..d365b12eb143 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/junction_deviation_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/junction_deviation_screen.cpp @@ -17,12 +17,12 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" -#if ENABLED(TOUCH_UI_FTDI_EVE) && DISABLED(CLASSIC_JERK) +#if BOTH(TOUCH_UI_FTDI_EVE, HAS_JUNCTION_DEVIATION) #include "screens.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/kill_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/kill_screen.cpp similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/kill_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/kill_screen.cpp index 9c27ae6af5f0..d98324623c28 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/kill_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/kill_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/language_menu.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/language_menu.cpp similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/language_menu.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/language_menu.cpp index 8906a14cf0f4..5b4c1c917536 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/language_menu.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/language_menu.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" diff --git a/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/leveling_menu.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/leveling_menu.cpp new file mode 100644 index 000000000000..763403d28722 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/leveling_menu.cpp @@ -0,0 +1,125 @@ +/********************* + * leveling_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: . * + ****************************************************************************/ + +#include "../config.h" + +#if BOTH(TOUCH_UI_FTDI_EVE,HAS_LEVELING) + +#include "screens.h" + +#if BOTH(HAS_BED_PROBE,BLTOUCH) + #include "../../../../../feature/bltouch.h" +#endif + +using namespace FTDI; +using namespace ExtUI; +using namespace Theme; + +#ifdef TOUCH_UI_PORTRAIT + #define GRID_ROWS 10 + #define GRID_COLS 2 + #define TITLE_POS BTN_POS(1,1), BTN_SIZE(2,1) + #define LEVEL_BED_POS BTN_POS(1,2), BTN_SIZE(2,1) + #define LEVEL_AXIS_POS BTN_POS(1,3), BTN_SIZE(2,1) + #define Z_AUTO_ALIGN_POS BTN_POS(1,4), BTN_SIZE(2,1) + #define SHOW_MESH_POS BTN_POS(1,5), BTN_SIZE(2,1) + #define BLTOUCH_TITLE_POS BTN_POS(1,7), BTN_SIZE(2,1) + #define BLTOUCH_RESET_POS BTN_POS(1,8), BTN_SIZE(1,1) + #define BLTOUCH_TEST_POS BTN_POS(2,8), BTN_SIZE(1,1) + #define BACK_POS BTN_POS(1,10), BTN_SIZE(2,1) +#else + #define GRID_ROWS 8 + #define GRID_COLS 2 + #define TITLE_POS BTN_POS(1,1), BTN_SIZE(2,1) + #define LEVEL_BED_POS BTN_POS(1,2), BTN_SIZE(2,1) + #define LEVEL_AXIS_POS BTN_POS(1,3), BTN_SIZE(2,1) + #define Z_AUTO_ALIGN_POS BTN_POS(1,4), BTN_SIZE(2,1) + #define SHOW_MESH_POS BTN_POS(1,5), BTN_SIZE(2,1) + #define BLTOUCH_TITLE_POS BTN_POS(1,6), BTN_SIZE(2,1) + #define BLTOUCH_RESET_POS BTN_POS(1,7), BTN_SIZE(1,1) + #define BLTOUCH_TEST_POS BTN_POS(2,7), BTN_SIZE(1,1) + #define BACK_POS BTN_POS(1,8), BTN_SIZE(2,1) +#endif + +void LevelingMenu::onRedraw(draw_mode_t what) { + if (what & BACKGROUND) { + CommandProcessor cmd; + cmd.cmd(CLEAR_COLOR_RGB(Theme::bg_color)) + .cmd(CLEAR(true,true,true)) + .tag(0); + } + + if (what & FOREGROUND) { + CommandProcessor cmd; + cmd.font(font_large) + .text(TITLE_POS, GET_TEXT_F(MSG_LEVELING)) + .font(font_medium).colors(normal_btn) + .tag(2).button(LEVEL_BED_POS, GET_TEXT_F(MSG_LEVEL_BED)) + .enabled( + #ifdef AXIS_LEVELING_COMMANDS + 1 + #endif + ) + .tag(3).button(LEVEL_AXIS_POS, GET_TEXT_F(MSG_AUTOLEVEL_X_AXIS)) + .enabled(ENABLED(Z_STEPPER_AUTO_ALIGN)) + .tag(4).button(Z_AUTO_ALIGN_POS, GET_TEXT_F(MSG_AUTO_Z_ALIGN)) + .enabled(ENABLED(HAS_MESH)) + .tag(5).button(SHOW_MESH_POS, GET_TEXT_F(MSG_SHOW_MESH)); + #if ENABLED(BLTOUCH) + cmd.text(BLTOUCH_TITLE_POS, GET_TEXT_F(MSG_BLTOUCH)) + .tag(6).button(BLTOUCH_RESET_POS, GET_TEXT_F(MSG_BLTOUCH_RESET)) + .tag(7).button(BLTOUCH_TEST_POS, GET_TEXT_F(MSG_BLTOUCH_SELFTEST)); + #endif + cmd.colors(action_btn) + .tag(1).button(BACK_POS, GET_TEXT_F(MSG_BACK)); + } +} + +bool LevelingMenu::onTouchEnd(uint8_t tag) { + switch (tag) { + case 1: GOTO_PREVIOUS(); break; + case 2: + #if HAS_MESH + BedMeshScreen::startMeshProbe(); + #else + SpinnerDialogBox::enqueueAndWait_P(F(BED_LEVELING_COMMANDS)); + #endif + break; + #ifdef AXIS_LEVELING_COMMANDS + case 3: SpinnerDialogBox::enqueueAndWait_P(F(AXIS_LEVELING_COMMANDS)); break; + #endif + #if ENABLED(Z_STEPPER_AUTO_ALIGN) + case 4: SpinnerDialogBox::enqueueAndWait_P(F("G34")); break; + #endif + #if HAS_MESH + case 5: GOTO_SCREEN(BedMeshScreen); break; + #endif + #if ENABLED(BLTOUCH) + case 6: injectCommands_P(PSTR("M280 P0 S60")); break; + case 7: SpinnerDialogBox::enqueueAndWait_P(F("M280 P0 S90\nG4 P100\nM280 P0 S120")); break; + #endif + default: return false; + } + return true; +} + +#endif // BOTH(TOUCH_UI_FTDI_EVE,HAS_LEVELING) diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/linear_advance_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/linear_advance_screen.cpp similarity index 95% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/linear_advance_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/linear_advance_screen.cpp index 0e35b4547581..8a5c675facc4 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/linear_advance_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/linear_advance_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -34,7 +34,7 @@ void LinearAdvanceScreen::onRedraw(draw_mode_t what) { widgets_t w(what); w.precision(2, DEFAULT_LOWEST).color(e_axis); w.heading( GET_TEXT_F(MSG_LINEAR_ADVANCE)); - #if EXTRUDERS == 1 + #if !HAS_MULTI_EXTRUDER w.adjuster( 2, GET_TEXT_F(MSG_LINEAR_ADVANCE_K), getLinearAdvance_mm_mm_s(E0) ); #else w.adjuster( 2, GET_TEXT_F(MSG_LINEAR_ADVANCE_K1), getLinearAdvance_mm_mm_s(E0) ); @@ -55,7 +55,7 @@ bool LinearAdvanceScreen::onTouchHeld(uint8_t tag) { 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 + #if HAS_MULTI_EXTRUDER case 4: UI_DECREMENT(LinearAdvance_mm_mm_s, E1); break; case 5: UI_INCREMENT(LinearAdvance_mm_mm_s, E1); break; #if EXTRUDERS > 2 diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/lock_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/lock_screen.cpp similarity index 94% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/lock_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/lock_screen.cpp index f012a2218b55..7854ce5e395c 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/lock_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/lock_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -72,19 +72,11 @@ void LockScreen::onRedraw(draw_mode_t what) { message = GET_TEXT_F(MSG_PASSCODE_ACCEPTED); break; default: - if (passcode == 0) { - message = GET_TEXT_F(MSG_PASSCODE_SELECT); - } else { - message = GET_TEXT_F(MSG_PASSCODE_REQUEST); - } + message = passcode ? GET_TEXT_F(MSG_PASSCODE_REQUEST) : GET_TEXT_F(MSG_PASSCODE_SELECT); } message_style() = '\0'; // Terminate the string. - #ifdef TOUCH_UI_PORTRAIT - constexpr uint8_t l = 6; - #else - constexpr uint8_t l = 3; - #endif + constexpr uint8_t l = TERN(TOUCH_UI_PORTRAIT, 6, 3); const uint8_t pressed = EventLoop::get_pressed_tag(); @@ -144,7 +136,8 @@ void LockScreen::onPasscodeEntered() { onRefresh(); sound.play(twinkle, PLAY_SYNCHRONOUS); GOTO_PREVIOUS(); - } else { + } + else { message_style() = 'w'; onRefresh(); sound.play(sad_trombone, PLAY_SYNCHRONOUS); @@ -162,7 +155,8 @@ bool LockScreen::onTouchEnd(uint8_t tag) { // Backspace deletes previous entered characters. *--c = '_'; } - } else { + } + else { // Append character to passcode *c++ = tag; if (*c == '\0') { diff --git a/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/main_menu.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/main_menu.cpp new file mode 100644 index 000000000000..53e3ab00c736 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/main_menu.cpp @@ -0,0 +1,143 @@ +/***************** + * main_menu.cpp * + *****************/ + +/**************************************************************************** + * Written By Mark Pelletier 2017 - Aleph Objects, Inc. * + * Written By Marcio Teixeira 2018 - Aleph Objects, Inc. * + * Written By Marcio Teixeira 2019 - Cocoa Press * + * * + * 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: . * + ****************************************************************************/ + +#include "../config.h" + +#if ENABLED(TOUCH_UI_FTDI_EVE) && !defined(TOUCH_UI_LULZBOT_BIO) + +#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)); + } + + #ifdef TOUCH_UI_PORTRAIT + #define GRID_ROWS 8 + #define GRID_COLS 2 + #define ABOUT_PRINTER_POS BTN_POS(1,1), BTN_SIZE(2,1) + #define ADVANCED_SETTINGS_POS BTN_POS(1,2), BTN_SIZE(2,1) + #define FILAMENTCHANGE_POS BTN_POS(1,3), BTN_SIZE(2,1) + #define TEMPERATURE_POS BTN_POS(1,4), BTN_SIZE(2,1) + #define DISABLE_STEPPERS_POS BTN_POS(1,5), BTN_SIZE(2,1) + #define MOVE_AXIS_POS BTN_POS(1,6), BTN_SIZE(1,1) + #define LEVELING_POS BTN_POS(2,6), BTN_SIZE(1,1) + #define AUTO_HOME_POS BTN_POS(1,7), BTN_SIZE(1,1) + #define CLEAN_NOZZLE_POS BTN_POS(2,7), BTN_SIZE(1,1) + #define BACK_POS BTN_POS(1,8), BTN_SIZE(2,1) + #else + #define GRID_ROWS 5 + #define GRID_COLS 2 + #define ADVANCED_SETTINGS_POS BTN_POS(1,1), BTN_SIZE(1,1) + #define ABOUT_PRINTER_POS BTN_POS(2,1), BTN_SIZE(1,1) + #define AUTO_HOME_POS BTN_POS(1,2), BTN_SIZE(1,1) + #define CLEAN_NOZZLE_POS BTN_POS(2,2), BTN_SIZE(1,1) + #define MOVE_AXIS_POS BTN_POS(1,3), BTN_SIZE(1,1) + #define DISABLE_STEPPERS_POS BTN_POS(2,3), BTN_SIZE(1,1) + #define TEMPERATURE_POS BTN_POS(1,4), BTN_SIZE(1,1) + #define FILAMENTCHANGE_POS BTN_POS(2,4), BTN_SIZE(1,1) + #define LEVELING_POS BTN_POS(1,5), BTN_SIZE(1,1) + #define BACK_POS BTN_POS(2,5), BTN_SIZE(1,1) + #endif + + if (what & FOREGROUND) { + CommandProcessor cmd; + cmd.colors(normal_btn) + .font(Theme::font_medium) + .tag(2).button( AUTO_HOME_POS, GET_TEXT_F(MSG_AUTO_HOME)) + .enabled( + #if ANY(NOZZLE_CLEAN_FEATURE, TOUCH_UI_COCOA_PRESS) + 1 + #endif + ) + .tag(3).button( CLEAN_NOZZLE_POS, GET_TEXT_F( + #if ENABLED(TOUCH_UI_COCOA_PRESS) + MSG_PREHEAT_1 + #else + MSG_CLEAN_NOZZLE + #endif + )) + .tag(4).button( MOVE_AXIS_POS, GET_TEXT_F(MSG_MOVE_AXIS)) + .tag(5).button( DISABLE_STEPPERS_POS, GET_TEXT_F(MSG_DISABLE_STEPPERS)) + .tag(6).button( TEMPERATURE_POS, GET_TEXT_F(MSG_TEMPERATURE)) + .enabled( + #if DISABLED(TOUCH_UI_LULZBOT_BIO) + 1 + #endif + ) + .tag(7).button( FILAMENTCHANGE_POS, GET_TEXT_F( + #if ENABLED(TOUCH_UI_COCOA_PRESS) + MSG_CASE_LIGHT + #else + MSG_FILAMENTCHANGE + #endif + )) + .tag(8).button( ADVANCED_SETTINGS_POS, GET_TEXT_F(MSG_ADVANCED_SETTINGS)) + .enabled( + #ifdef HAS_LEVELING + 1 + #endif + ) + .tag(9).button( LEVELING_POS, GET_TEXT_F(MSG_LEVELING)) + .tag(10).button( ABOUT_PRINTER_POS, GET_TEXT_F(MSG_INFO_MENU)) + .colors(action_btn) + .tag(1).button( BACK_POS, GET_TEXT_F(MSG_BACK)); + } +} + +bool MainMenu::onTouchEnd(uint8_t tag) { + using namespace ExtUI; + + switch (tag) { + case 1: SaveSettingsDialogBox::promptToSaveSettings(); break; + case 2: SpinnerDialogBox::enqueueAndWait_P(F("G28")); break; + #if ENABLED(TOUCH_UI_COCOA_PRESS) + case 3: GOTO_SCREEN(PreheatMenu); break; + #elif 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; + #if BOTH(TOUCH_UI_COCOA_PRESS, CASE_LIGHT_ENABLE) + case 7: GOTO_SCREEN(CaseLightScreen); break; + #else + case 7: GOTO_SCREEN(ChangeFilamentScreen); break; + #endif + case 8: GOTO_SCREEN(AdvancedSettingsMenu); break; + #ifdef HAS_LEVELING + case 9: GOTO_SCREEN(LevelingMenu); break; + #endif + case 10: GOTO_SCREEN(AboutScreen); break; + default: + return false; + } + return true; +} + +#endif // TOUCH_UI_FTDI_EVE diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/max_acceleration_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/max_acceleration_screen.cpp similarity index 91% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/max_acceleration_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/max_acceleration_screen.cpp index 8f7af4b81eda..29ac2f1b4038 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/max_acceleration_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/max_acceleration_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -38,16 +38,16 @@ void MaxAccelerationScreen::onRedraw(draw_mode_t what) { w.color(x_axis) .adjuster( 2, GET_TEXT_F(MSG_AMAX_X), getAxisMaxAcceleration_mm_s2(X) ); w.color(y_axis) .adjuster( 4, GET_TEXT_F(MSG_AMAX_Y), getAxisMaxAcceleration_mm_s2(Y) ); w.color(z_axis) .adjuster( 6, GET_TEXT_F(MSG_AMAX_Z), getAxisMaxAcceleration_mm_s2(Z) ); - #if EXTRUDERS == 1 || DISABLED(DISTINCT_E_FACTORS) + #if DISTINCT_E == 1 w.color(e_axis).adjuster( 8, GET_TEXT_F(MSG_AMAX_E), getAxisMaxAcceleration_mm_s2(E0) ); - #elif EXTRUDERS > 1 + #elif DISTINCT_E > 1 w.heading(GET_TEXT_F(MSG_AMAX_E)); w.color(e_axis).adjuster( 8, F(LCD_STR_E0), getAxisMaxAcceleration_mm_s2(E0) ); w.color(e_axis).adjuster(10, F(LCD_STR_E1), getAxisMaxAcceleration_mm_s2(E1) ); - #if EXTRUDERS > 2 + #if DISTINCT_E > 2 w.color(e_axis).adjuster(12, F(LCD_STR_E2), getAxisMaxAcceleration_mm_s2(E2) ); #endif - #if EXTRUDERS > 3 + #if DISTINCT_E > 3 w.color(e_axis).adjuster(14, F(LCD_STR_E3), getAxisMaxAcceleration_mm_s2(E3) ); #endif #endif @@ -65,15 +65,15 @@ bool MaxAccelerationScreen::onTouchHeld(uint8_t tag) { 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) + #if DISTINCT_E > 1 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) + #if DISTINCT_E > 2 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) + #if DISTINCT_E > 3 case 14: UI_DECREMENT(AxisMaxAcceleration_mm_s2, E3); break; case 15: UI_INCREMENT(AxisMaxAcceleration_mm_s2, E3); break; #endif diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/max_velocity_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/max_velocity_screen.cpp similarity index 93% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/max_velocity_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/max_velocity_screen.cpp index 864f6b735d1f..2316f93ee236 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/max_velocity_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/max_velocity_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -41,7 +41,7 @@ void MaxVelocityScreen::onRedraw(draw_mode_t what) { w.color(z_axis) .adjuster( 6, GET_TEXT_F(MSG_VMAX_Z), getAxisMaxFeedrate_mm_s(Z) ); #if EXTRUDERS == 1 || DISABLED(DISTINCT_E_FACTORS) w.color(e_axis) .adjuster( 8, GET_TEXT_F(MSG_VMAX_E), getAxisMaxFeedrate_mm_s(E0) ); - #elif EXTRUDERS > 1 + #elif HAS_MULTI_EXTRUDER w.heading(GET_TEXT_F(MSG_VMAX_E)); w.color(e_axis) .adjuster( 8, F(LCD_STR_E0), getAxisMaxFeedrate_mm_s(E0) ); w.color(e_axis) .adjuster( 10, F(LCD_STR_E1), getAxisMaxFeedrate_mm_s(E1) ); @@ -64,17 +64,19 @@ bool MaxVelocityScreen::onTouchHeld(uint8_t tag) { case 5: UI_INCREMENT(AxisMaxFeedrate_mm_s, Y); break; case 6: UI_DECREMENT(AxisMaxFeedrate_mm_s, Z); break; case 7: UI_INCREMENT(AxisMaxFeedrate_mm_s, Z); break; + #if DISTINCT_E > 0 case 8: UI_DECREMENT(AxisMaxFeedrate_mm_s, E0); break; case 9: UI_INCREMENT(AxisMaxFeedrate_mm_s, E0); break; - #if EXTRUDERS > 1 && ENABLED(DISTINCT_E_FACTORS) + #endif + #if DISTINCT_E > 1 case 10: UI_DECREMENT(AxisMaxFeedrate_mm_s, E1); break; case 11: UI_INCREMENT(AxisMaxFeedrate_mm_s, E1); break; #endif - #if EXTRUDERS > 2 && ENABLED(DISTINCT_E_FACTORS) + #if DISTINCT_E > 2 case 12: UI_DECREMENT(AxisMaxFeedrate_mm_s, E2); break; case 13: UI_INCREMENT(AxisMaxFeedrate_mm_s, E2); break; #endif - #if EXTRUDERS > 3 && ENABLED(DISTINCT_E_FACTORS) + #if DISTINCT_E > 3 case 14: UI_DECREMENT(AxisMaxFeedrate_mm_s, E3); break; case 15: UI_INCREMENT(AxisMaxFeedrate_mm_s, E3); break; #endif diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/media_player_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/media_player_screen.cpp similarity index 98% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/media_player_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/media_player_screen.cpp index 95a4e6b44ade..d7e476e04ef5 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/media_player_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/media_player_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/move_axis_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/move_axis_screen.cpp similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/move_axis_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/move_axis_screen.cpp index 8513c79f8457..5dd3174821e2 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/move_axis_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/move_axis_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -36,7 +36,7 @@ void MoveAxisScreen::onEntry() { // ourselves. The relative distances are reset to zero whenever this // screen is entered. - for (uint8_t i = 0; i < ExtUI::extruderCount; i++) { + LOOP_L_N(i, ExtUI::extruderCount) { screen_data.MoveAxisScreen.e_rel[i] = 0; } BaseNumericAdjustmentScreen::onEntry(); @@ -55,7 +55,7 @@ void MoveAxisScreen::onRedraw(draw_mode_t what) { w.color(Theme::e_axis); #if EXTRUDERS == 1 w.adjuster( 8, GET_TEXT_F(MSG_AXIS_E), screen_data.MoveAxisScreen.e_rel[0], canMove(E0)); - #elif EXTRUDERS > 1 + #elif HAS_MULTI_EXTRUDER w.adjuster( 8, GET_TEXT_F(MSG_AXIS_E1), screen_data.MoveAxisScreen.e_rel[0], canMove(E0)); w.adjuster( 10, GET_TEXT_F(MSG_AXIS_E2), screen_data.MoveAxisScreen.e_rel[1], canMove(E1)); #if EXTRUDERS > 2 @@ -82,7 +82,7 @@ bool MoveAxisScreen::onTouchHeld(uint8_t tag) { // For extruders, also update relative distances. case 8: UI_DECREMENT_AXIS(E0); screen_data.MoveAxisScreen.e_rel[0] -= increment; break; case 9: UI_INCREMENT_AXIS(E0); screen_data.MoveAxisScreen.e_rel[0] += increment; break; - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER case 10: UI_DECREMENT_AXIS(E1); screen_data.MoveAxisScreen.e_rel[1] -= increment; break; case 11: UI_INCREMENT_AXIS(E1); screen_data.MoveAxisScreen.e_rel[1] += increment; break; #endif diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/nozzle_offsets_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/nozzle_offsets_screen.cpp similarity index 95% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/nozzle_offsets_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/nozzle_offsets_screen.cpp index ae224e9c1135..07d6900c16f4 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/nozzle_offsets_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/nozzle_offsets_screen.cpp @@ -17,12 +17,12 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" -#if ENABLED(TOUCH_UI_FTDI_EVE) && HOTENDS > 1 +#if BOTH(TOUCH_UI_FTDI_EVE, HAS_MULTI_HOTEND) #include "screens.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/nudge_nozzle_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/nudge_nozzle_screen.cpp similarity index 94% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/nudge_nozzle_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/nudge_nozzle_screen.cpp index d9910ffa0420..ed3c8d999b4b 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/nudge_nozzle_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/nudge_nozzle_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -33,7 +33,7 @@ using namespace ExtUI; void NudgeNozzleScreen::onEntry() { screen_data.NudgeNozzleScreen.show_offsets = false; - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER screen_data.NudgeNozzleScreen.link_nozzles = true; #endif screen_data.NudgeNozzleScreen.rel.reset(); @@ -52,11 +52,11 @@ void NudgeNozzleScreen::onRedraw(draw_mode_t what) { #endif w.color(z_axis).adjuster(6, GET_TEXT_F(MSG_AXIS_Z), screen_data.NudgeNozzleScreen.rel.z / getAxisSteps_per_mm(Z)); w.increments(); - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER w.toggle(8, GET_TEXT_F(MSG_ADJUST_BOTH_NOZZLES), screen_data.NudgeNozzleScreen.link_nozzles); #endif - #if EXTRUDERS > 1 || HAS_BED_PROBE + #if HAS_MULTI_EXTRUDER || HAS_BED_PROBE w.toggle(9, GET_TEXT_F(MSG_SHOW_OFFSETS), screen_data.NudgeNozzleScreen.show_offsets); if (screen_data.NudgeNozzleScreen.show_offsets) { @@ -72,7 +72,7 @@ void NudgeNozzleScreen::onRedraw(draw_mode_t what) { w.text_field(0, GET_TEXT_F(MSG_ZPROBE_ZOFFSET), str); #endif - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND format_position(str, getNozzleOffset_mm(X, E1), getNozzleOffset_mm(Y, E1), getNozzleOffset_mm(Z, E1)); w.text_field(0, GET_TEXT_F(MSG_OFFSETS_MENU), str); #endif @@ -82,7 +82,7 @@ void NudgeNozzleScreen::onRedraw(draw_mode_t what) { bool NudgeNozzleScreen::onTouchHeld(uint8_t tag) { const float inc = getIncrement(); - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER const bool link = screen_data.NudgeNozzleScreen.link_nozzles; #else constexpr bool link = true; @@ -95,13 +95,13 @@ bool NudgeNozzleScreen::onTouchHeld(uint8_t tag) { case 5: steps = mmToWholeSteps(inc, Y); smartAdjustAxis_steps( steps, Y, link); screen_data.NudgeNozzleScreen.rel.y += steps; break; case 6: steps = mmToWholeSteps(inc, Z); smartAdjustAxis_steps(-steps, Z, link); screen_data.NudgeNozzleScreen.rel.z -= steps; break; case 7: steps = mmToWholeSteps(inc, Z); smartAdjustAxis_steps( steps, Z, link); screen_data.NudgeNozzleScreen.rel.z += steps; break; - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER case 8: screen_data.NudgeNozzleScreen.link_nozzles = !link; break; #endif case 9: screen_data.NudgeNozzleScreen.show_offsets = !screen_data.NudgeNozzleScreen.show_offsets; break; default: return false; } - #if EXTRUDERS > 1 || HAS_BED_PROBE + #if HAS_MULTI_EXTRUDER || HAS_BED_PROBE SaveSettingsDialogBox::settingsChanged(); #endif return true; diff --git a/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/preheat_menu.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/preheat_menu.cpp new file mode 100644 index 000000000000..a8891162ea0d --- /dev/null +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/preheat_menu.cpp @@ -0,0 +1,83 @@ +/******************** + * preheat_menu.cpp * + ********************/ + +/**************************************************************************** + * Written By Marcio Teixeira 2020 - Cocoa Press * + * * + * 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: . * + ****************************************************************************/ + +#include "../config.h" + +#if ENABLED(TOUCH_UI_FTDI_EVE) && defined(TOUCH_UI_COCOA_PRESS) + +#include "screens.h" + +using namespace FTDI; +using namespace ExtUI; +using namespace Theme; + +void PreheatMenu::onRedraw(draw_mode_t what) { + if (what & BACKGROUND) { + CommandProcessor cmd; + cmd.cmd(CLEAR_COLOR_RGB(Theme::bg_color)) + .cmd(CLEAR(true,true,true)) + .tag(0); + } + + #define GRID_ROWS 3 + #define GRID_COLS 2 + + if (what & FOREGROUND) { + CommandProcessor cmd; + cmd.cmd(COLOR_RGB(bg_text_enabled)) + .font(Theme::font_medium) + .text ( BTN_POS(1,1), BTN_SIZE(2,1), GET_TEXT_F(MSG_PREHEAT_1)) + .colors(normal_btn) + .tag(2).button( BTN_POS(1,2), BTN_SIZE(1,1), F("Dark Chocolate")) + .tag(3).button( BTN_POS(2,2), BTN_SIZE(1,1), F("Milk Chocolate")) + .tag(4).button( BTN_POS(1,3), BTN_SIZE(1,1), F("White Chocolate")) + .colors(action_btn) + .tag(1) .button( BTN_POS(2,3), BTN_SIZE(1,1), GET_TEXT_F(MSG_BACK)); + } +} + +bool PreheatMenu::onTouchEnd(uint8_t tag) { + switch (tag) { + case 1: GOTO_PREVIOUS(); break; + case 2: + #ifdef COCOA_PRESS_PREHEAT_DARK_CHOCOLATE_SCRIPT + injectCommands_P(PSTR(COCOA_PRESS_PREHEAT_DARK_CHOCOLATE_SCRIPT)); + #endif + GOTO_SCREEN(PreheatTimerScreen); + break; + case 3: + #ifdef COCOA_PRESS_PREHEAT_MILK_CHOCOLATE_SCRIPT + injectCommands_P(PSTR(COCOA_PRESS_PREHEAT_MILK_CHOCOLATE_SCRIPT)); + #endif + GOTO_SCREEN(PreheatTimerScreen); + break; + case 4: + #ifdef COCOA_PRESS_PREHEAT_WHITE_CHOCOLATE_SCRIPT + injectCommands_P(PSTR(COCOA_PRESS_PREHEAT_WHITE_CHOCOLATE_SCRIPT)); + #endif + GOTO_SCREEN(PreheatTimerScreen); + break; + default: return false; + } + return true; +} + +#endif // TOUCH_UI_FTDI_EVE diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/preheat_timer_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/preheat_timer_screen.cpp similarity index 95% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/preheat_timer_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/preheat_timer_screen.cpp index 0a24c3008204..69eecaf54b36 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/preheat_timer_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/preheat_timer_screen.cpp @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -77,9 +77,6 @@ void PreheatTimerScreen::draw_interaction_buttons(draw_mode_t what) { void PreheatTimerScreen::onEntry() { screen_data.PreheatTimerScreen.start_ms = millis(); - #ifdef COCOA_PRESS_PREHEAT_SCRIPT - injectCommands_P(PSTR(COCOA_PRESS_PREHEAT_SCRIPT)); - #endif } void PreheatTimerScreen::onRedraw(draw_mode_t what) { diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/restore_failsafe_dialog_box.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/restore_failsafe_dialog_box.cpp similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/restore_failsafe_dialog_box.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/restore_failsafe_dialog_box.cpp index a5fe95490f74..94b8ac0fb50f 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/restore_failsafe_dialog_box.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/restore_failsafe_dialog_box.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/save_settings_dialog_box.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/save_settings_dialog_box.cpp similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/save_settings_dialog_box.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/save_settings_dialog_box.cpp index 5ffe20cce1e9..f4a99accd63d 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/save_settings_dialog_box.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/save_settings_dialog_box.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/screen_data.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/screen_data.h similarity index 75% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/screen_data.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/screen_data.h index 6e2cb97a984a..dc38890a0efc 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/screen_data.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/screen_data.h @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once @@ -52,35 +52,46 @@ union screen_data_t { uint8_t num_page; uint8_t cur_page; #if ENABLED(SCROLL_LONG_FILENAMES) && (FTDI_API_LEVEL >= 810) - uint16_t scroll_pos; - uint16_t scroll_max; + uint16_t scroll_pos; + uint16_t scroll_max; #endif } FilesScreen; struct { struct base_numeric_adjustment_t placeholder; float e_rel[ExtUI::extruderCount]; } MoveAxisScreen; -#if ENABLED(TOUCH_UI_DEVELOPER_MENU) - struct { - uint32_t next_watchdog_trigger; - const char* message; - } StressTestScreen; -#endif -#if ENABLED(TOUCH_UI_COCOA_PRESS) - struct { - uint32_t start_ms; - } PreheatTimerScreen; -#endif -#if ENABLED(BABYSTEPPING) - struct { - struct base_numeric_adjustment_t placeholder; - xyz_int_t rel; - #if EXTRUDERS > 1 - bool link_nozzles; - #endif - bool show_offsets; - } NudgeNozzleScreen; -#endif + #if HAS_MESH + struct { + enum : uint8_t { + MSG_NONE, + MSG_MESH_COMPLETE, + MSG_MESH_INCOMPLETE + } message; + uint8_t count; + uint8_t highlightedTag; + } BedMeshScreen; + #endif + #if ENABLED(TOUCH_UI_DEVELOPER_MENU) + struct { + uint32_t next_watchdog_trigger; + const char* message; + } StressTestScreen; + #endif + #if ENABLED(TOUCH_UI_COCOA_PRESS) + struct { + uint32_t start_ms; + } PreheatTimerScreen; + #endif + #if ENABLED(BABYSTEPPING) + struct { + struct base_numeric_adjustment_t placeholder; + xyz_int_t rel; + #if HAS_MULTI_EXTRUDER + bool link_nozzles; + #endif + bool show_offsets; + } NudgeNozzleScreen; + #endif }; extern screen_data_t screen_data; diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/screens.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/screens.cpp similarity index 90% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/screens.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/screens.cpp index bc9280005400..16aa68216842 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/screens.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/screens.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -58,14 +58,20 @@ SCREEN_TABLE { #endif DECL_SCREEN(MoveAxisScreen), DECL_SCREEN(StepsScreen), -#if HAS_TRINAMIC +#if HAS_TRINAMIC_CONFIG DECL_SCREEN(StepperCurrentScreen), DECL_SCREEN(StepperBumpSensitivityScreen), #endif -#if HAS_BED_PROBE - DECL_SCREEN(ZOffsetScreen), +#if HAS_LEVELING + DECL_SCREEN(LevelingMenu), + #if HAS_BED_PROBE + DECL_SCREEN(ZOffsetScreen), + #endif + #if HAS_MESH + DECL_SCREEN(BedMeshScreen), + #endif #endif -#if HOTENDS > 1 +#if HAS_MULTI_HOTEND DECL_SCREEN(NozzleOffsetScreen), #endif #if ENABLED(BACKLASH_GCODE) @@ -75,12 +81,12 @@ SCREEN_TABLE { DECL_SCREEN(MaxVelocityScreen), DECL_SCREEN(MaxAccelerationScreen), DECL_SCREEN(DefaultAccelerationScreen), -#if DISABLED(CLASSIC_JERK) +#if HAS_JUNCTION_DEVIATION DECL_SCREEN(JunctionDeviationScreen), #else DECL_SCREEN(JerkScreen), #endif -#if HAS_CASE_LIGHT +#if ENABLED(CASE_LIGHT_ENABLE) DECL_SCREEN(CaseLightScreen), #endif #if EITHER(LIN_ADVANCE, FILAMENT_RUNOUT_SENSOR) @@ -97,7 +103,9 @@ SCREEN_TABLE { DECL_SCREEN(InterfaceSettingsScreen), DECL_SCREEN(InterfaceSoundsScreen), DECL_SCREEN(LockScreen), +#if ENABLED(SDSUPPORT) DECL_SCREEN(FilesScreen), +#endif DECL_SCREEN(EndstopStatesScreen), #if ENABLED(TOUCH_UI_LULZBOT_BIO) DECL_SCREEN(BioPrintingDialogBox), @@ -105,6 +113,7 @@ SCREEN_TABLE { DECL_SCREEN(BioConfirmHomeE), #endif #if ENABLED(TOUCH_UI_COCOA_PRESS) + DECL_SCREEN(PreheatMenu), DECL_SCREEN(PreheatTimerScreen), #endif #if ENABLED(TOUCH_UI_DEVELOPER_MENU) diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/screens.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/screens.h similarity index 85% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/screens.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/screens.h index 176c8145e34e..2108cff8df2a 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/screens.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/screens.h @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once @@ -27,6 +27,10 @@ #include "../theme/theme.h" #include "string_format.h" +#ifndef BED_LEVELING_COMMANDS + #define BED_LEVELING_COMMANDS "G29" +#endif + extern tiny_timer_t refresh_timer; /********************************* DL CACHE SLOTS ******************************/ @@ -39,28 +43,44 @@ enum { STATUS_SCREEN_CACHE, MENU_SCREEN_CACHE, TUNE_SCREEN_CACHE, - ADJUST_OFFSETS_SCREEN_CACHE, ALERT_BOX_CACHE, SPINNER_CACHE, ADVANCED_SETTINGS_SCREEN_CACHE, MOVE_AXIS_SCREEN_CACHE, TEMPERATURE_SCREEN_CACHE, STEPS_SCREEN_CACHE, - STEPPER_CURRENT_SCREEN_CACHE, - STEPPER_BUMP_SENSITIVITY_SCREEN_CACHE, - ZOFFSET_SCREEN_CACHE, - NOZZLE_OFFSET_SCREEN_CACHE, - BACKLASH_COMPENSATION_SCREEN_CACHE, MAX_FEEDRATE_SCREEN_CACHE, MAX_VELOCITY_SCREEN_CACHE, MAX_ACCELERATION_SCREEN_CACHE, DEFAULT_ACCELERATION_SCREEN_CACHE, -#if DISABLED(CLASSIC_JERK) +#if HAS_LEVELING + LEVELING_SCREEN_CACHE, + #if HAS_BED_PROBE + ZOFFSET_SCREEN_CACHE, + #endif + #if HAS_MESH + BED_MESH_SCREEN_CACHE, + #endif +#endif +#if ENABLED(BABYSTEPPING) + ADJUST_OFFSETS_SCREEN_CACHE, +#endif +#if HAS_TRINAMIC_CONFIG + STEPPER_CURRENT_SCREEN_CACHE, + STEPPER_BUMP_SENSITIVITY_SCREEN_CACHE, +#endif +#if HAS_MULTI_HOTEND + NOZZLE_OFFSET_SCREEN_CACHE, +#endif +#if ENABLED(BACKLASH_GCODE) + BACKLASH_COMPENSATION_SCREEN_CACHE, +#endif +#if HAS_JUNCTION_DEVIATION JUNC_DEV_SCREEN_CACHE, #else JERK_SCREEN_CACHE, #endif -#if HAS_CASE_LIGHT +#if ENABLED(CASE_LIGHT_ENABLE) CASE_LIGHT_SCREEN_CACHE, #endif #if EITHER(LIN_ADVANCE, FILAMENT_RUNOUT_SENSOR) @@ -76,13 +96,16 @@ enum { PRINTING_SCREEN_CACHE, #endif #if ENABLED(TOUCH_UI_COCOA_PRESS) + PREHEAT_MENU_CACHE, PREHEAT_TIMER_SCREEN_CACHE, +#endif +#if ENABLED(SDSUPPORT) + FILES_SCREEN_CACHE, #endif CHANGE_FILAMENT_SCREEN_CACHE, INTERFACE_SETTINGS_SCREEN_CACHE, INTERFACE_SOUNDS_SCREEN_CACHE, LOCK_SCREEN_CACHE, - FILES_SCREEN_CACHE, DISPLAY_TIMINGS_SCREEN_CACHE }; @@ -92,14 +115,14 @@ enum { #define STATUS_SCREEN_DL_SIZE 2048 #define ALERT_BOX_DL_SIZE 3072 #define SPINNER_DL_SIZE 3072 -#define FILE_SCREEN_DL_SIZE 3072 +#define FILE_SCREEN_DL_SIZE 4160 #define PRINTING_SCREEN_DL_SIZE 2048 /************************* MENU SCREEN DECLARATIONS *************************/ class BaseScreen : public UIScreen { protected: - #ifdef LCD_TIMEOUT_TO_STATUS + #if LCD_TIMEOUT_TO_STATUS > 0 static uint32_t last_interaction; #endif @@ -192,7 +215,6 @@ class ConfirmStartPrintDialogBox : public DialogBoxBaseClass, public UncachedScr static const char *getFilename(bool longName); public: - static void onEntry(); static void onRedraw(draw_mode_t); static bool onTouchEnd(uint8_t); @@ -314,6 +336,12 @@ class StatusScreen : public BaseScreen, public CachedScreen { + public: + static void onRedraw(draw_mode_t); + static bool onTouchEnd(uint8_t tag); + }; + class PreheatTimerScreen : public BaseScreen, public CachedScreen { private: static uint16_t secondsRemaining(); @@ -455,7 +483,7 @@ class StepsScreen : public BaseNumericAdjustmentScreen, public CachedScreen { public: static void onRedraw(draw_mode_t); @@ -469,21 +497,59 @@ class StepsScreen : public BaseNumericAdjustmentScreen, public CachedScreen { +#if HAS_MULTI_HOTEND + class NozzleOffsetScreen : public BaseNumericAdjustmentScreen, public CachedScreen { public: + static void onEntry(); static void onRedraw(draw_mode_t); static bool onTouchHeld(uint8_t tag); }; #endif -#if HOTENDS > 1 - class NozzleOffsetScreen : public BaseNumericAdjustmentScreen, public CachedScreen { +#if HAS_LEVELING + class LevelingMenu : public BaseScreen, public CachedScreen { public: + static void onRedraw(draw_mode_t); + static bool onTouchEnd(uint8_t tag); + }; + + #if HAS_BED_PROBE + class ZOffsetScreen : public BaseNumericAdjustmentScreen, public CachedScreen { + public: + static void onRedraw(draw_mode_t); + static bool onTouchHeld(uint8_t tag); + }; + #endif + + #if HAS_MESH + class BedMeshScreen : public BaseScreen, public CachedScreen { + private: + enum MeshOpts { + USE_POINTS = 0x01, + USE_COLORS = 0x02, + USE_TAGS = 0x04, + USE_HIGHLIGHT = 0x08, + USE_AUTOSCALE = 0x10 + }; + + static uint8_t pointToTag(uint8_t x, uint8_t y); + static bool tagToPoint(uint8_t tag, uint8_t &x, uint8_t &y); + static float getHightlightedValue(); + static void drawHighlightedPointValue(); + static void drawMesh(int16_t x, int16_t y, int16_t w, int16_t h, ExtUI::bed_mesh_t data, uint8_t opts, float autoscale_max = 0.1); + static bool isMeshComplete(ExtUI::bed_mesh_t data); + + public: + static void onMeshUpdate(const int8_t x, const int8_t y, const float val); + static void onMeshUpdate(const int8_t x, const int8_t y, const ExtUI::probe_state_t); static void onEntry(); static void onRedraw(draw_mode_t); - static bool onTouchHeld(uint8_t tag); + static bool onTouchStart(uint8_t tag); + static bool onTouchEnd(uint8_t tag); + + static void startMeshProbe(); }; + #endif #endif #if ENABLED(BABYSTEPPING) @@ -529,7 +595,7 @@ class DefaultAccelerationScreen : public BaseNumericAdjustmentScreen, public Cac static bool onTouchHeld(uint8_t tag); }; -#if DISABLED(CLASSIC_JERK) +#if HAS_JUNCTION_DEVIATION class JunctionDeviationScreen : public BaseNumericAdjustmentScreen, public CachedScreen { public: static void onRedraw(draw_mode_t); @@ -543,7 +609,7 @@ class DefaultAccelerationScreen : public BaseNumericAdjustmentScreen, public Cac }; #endif -#if HAS_CASE_LIGHT +#if ENABLED(CASE_LIGHT_ENABLE) class CaseLightScreen : public BaseNumericAdjustmentScreen, public CachedScreen { public: static void onRedraw(draw_mode_t); @@ -671,40 +737,42 @@ class LockScreen : public BaseScreen, public CachedScreen { static bool onTouchEnd(uint8_t tag); }; -class FilesScreen : public BaseScreen, public CachedScreen { - private: - #ifdef TOUCH_UI_PORTRAIT - static constexpr uint8_t header_h = 2; - static constexpr uint8_t footer_h = 2; - static constexpr uint8_t files_per_page = 11; - #else - static constexpr uint8_t header_h = 1; - static constexpr uint8_t footer_h = 1; - static constexpr uint8_t files_per_page = 6; - #endif - - static uint8_t getTagForLine(uint8_t line) {return line + 2;} - static uint8_t getLineForTag(uint8_t tag) {return tag - 2;} - static uint16_t getFileForTag(uint8_t tag); - static uint16_t getSelectedFileIndex(); - - inline static const char *getSelectedShortFilename() {return getSelectedFilename(false);} - inline static const char *getSelectedLongFilename() {return getSelectedFilename(true);} - static const char *getSelectedFilename(bool longName); - - static void drawFileButton(const char* filename, uint8_t tag, bool is_dir, bool is_highlighted); - static void drawFileList(); - static void drawHeader(); - static void drawFooter(); - static void drawSelectedFile(); - - static void gotoPage(uint8_t); - public: - static void onEntry(); - static void onRedraw(draw_mode_t); - static bool onTouchEnd(uint8_t tag); - static void onIdle(); -}; +#if ENABLED(SDSUPPORT) + class FilesScreen : public BaseScreen, public CachedScreen { + private: + #ifdef TOUCH_UI_PORTRAIT + static constexpr uint8_t header_h = 2; + static constexpr uint8_t footer_h = 2; + static constexpr uint8_t files_per_page = 11; + #else + static constexpr uint8_t header_h = 1; + static constexpr uint8_t footer_h = 1; + static constexpr uint8_t files_per_page = 6; + #endif + + static uint8_t getTagForLine(uint8_t line) {return line + 2;} + static uint8_t getLineForTag(uint8_t tag) {return tag - 2;} + static uint16_t getFileForTag(uint8_t tag); + static uint16_t getSelectedFileIndex(); + + inline static const char *getSelectedShortFilename() {return getSelectedFilename(false);} + inline static const char *getSelectedLongFilename() {return getSelectedFilename(true);} + static const char *getSelectedFilename(bool longName); + + static void drawFileButton(const char* filename, uint8_t tag, bool is_dir, bool is_highlighted); + static void drawFileList(); + static void drawHeader(); + static void drawFooter(); + static void drawSelectedFile(); + + static void gotoPage(uint8_t); + public: + static void onEntry(); + static void onRedraw(draw_mode_t); + static bool onTouchEnd(uint8_t tag); + static void onIdle(); + }; +#endif class EndstopStatesScreen : public BaseScreen, public UncachedScreen { public: diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/spinner_dialog_box.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/spinner_dialog_box.cpp similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/spinner_dialog_box.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/spinner_dialog_box.cpp index 05df0f3995bb..de7eb92a8897 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/spinner_dialog_box.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/spinner_dialog_box.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/statistics_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/statistics_screen.cpp similarity index 97% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/statistics_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/statistics_screen.cpp index e28e5d9b81f6..cb263248088e 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/statistics_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/statistics_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/status_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/status_screen.cpp similarity index 54% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/status_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/status_screen.cpp index e71f200a359c..fc7453fca70f 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/status_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/status_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -33,9 +33,9 @@ using namespace FTDI; using namespace Theme; #ifdef TOUCH_UI_PORTRAIT - #define GRID_ROWS 8 + #define GRID_ROWS 8 #else - #define GRID_ROWS 8 + #define GRID_ROWS 8 #endif void StatusScreen::draw_axis_position(draw_mode_t what) { @@ -43,41 +43,41 @@ void StatusScreen::draw_axis_position(draw_mode_t what) { #define GRID_COLS 3 + #ifdef TOUCH_UI_PORTRAIT + #define X_LBL_POS BTN_POS(1,5), BTN_SIZE(1,1) + #define Y_LBL_POS BTN_POS(1,6), BTN_SIZE(1,1) + #define Z_LBL_POS BTN_POS(1,7), BTN_SIZE(1,1) + #define X_VAL_POS BTN_POS(2,5), BTN_SIZE(2,1) + #define Y_VAL_POS BTN_POS(2,6), BTN_SIZE(2,1) + #define Z_VAL_POS BTN_POS(2,7), BTN_SIZE(2,1) + #else + #define X_LBL_POS BTN_POS(1,5), BTN_SIZE(1,1) + #define Y_LBL_POS BTN_POS(2,5), BTN_SIZE(1,1) + #define Z_LBL_POS BTN_POS(3,5), BTN_SIZE(1,1) + #define X_VAL_POS BTN_POS(1,6), BTN_SIZE(1,1) + #define Y_VAL_POS BTN_POS(2,6), BTN_SIZE(1,1) + #define Z_VAL_POS BTN_POS(3,6), BTN_SIZE(1,1) + #endif + + #define _UNION_POS(x1,y1,w1,h1,x2,y2,w2,h2) x1,y1,max(x1+w1,x2+w2)-x1,max(y1+h1,y2+h2)-y1 + #define UNION_POS(p1, p2) _UNION_POS(p1, p2) + if (what & BACKGROUND) { cmd.tag(6) - #ifdef TOUCH_UI_PORTRAIT - .fgcolor(Theme::axis_label) - .font(Theme::font_large) - .button( BTN_POS(1,5), BTN_SIZE(2,1), F(""), OPT_FLAT) - .button( BTN_POS(1,6), BTN_SIZE(2,1), F(""), OPT_FLAT) - .button( BTN_POS(1,7), BTN_SIZE(2,1), F(""), OPT_FLAT) - - .font(Theme::font_small) - .text ( BTN_POS(1,5), BTN_SIZE(1,1), GET_TEXT_F(MSG_AXIS_X)) - .text ( BTN_POS(1,6), BTN_SIZE(1,1), GET_TEXT_F(MSG_AXIS_Y)) - .text ( BTN_POS(1,7), BTN_SIZE(1,1), GET_TEXT_F(MSG_AXIS_Z)) - - .font(Theme::font_medium) - .fgcolor(Theme::x_axis) .button( BTN_POS(2,5), BTN_SIZE(2,1), F(""), OPT_FLAT) - .fgcolor(Theme::y_axis) .button( BTN_POS(2,6), BTN_SIZE(2,1), F(""), OPT_FLAT) - .fgcolor(Theme::z_axis) .button( BTN_POS(2,7), BTN_SIZE(2,1), F(""), OPT_FLAT); - #else - .fgcolor(Theme::axis_label) - .font(Theme::font_large) - .button( BTN_POS(1,5), BTN_SIZE(1,2), F(""), OPT_FLAT) - .button( BTN_POS(2,5), BTN_SIZE(1,2), F(""), OPT_FLAT) - .button( BTN_POS(3,5), BTN_SIZE(1,2), F(""), OPT_FLAT) - - .font(Theme::font_small) - .text ( BTN_POS(1,5), BTN_SIZE(1,1), GET_TEXT_F(MSG_AXIS_X)) - .text ( BTN_POS(2,5), BTN_SIZE(1,1), GET_TEXT_F(MSG_AXIS_Y)) - .text ( BTN_POS(3,5), BTN_SIZE(1,1), GET_TEXT_F(MSG_AXIS_Z)) - .font(Theme::font_medium) - - .fgcolor(Theme::x_axis) .button( BTN_POS(1,6), BTN_SIZE(1,1), F(""), OPT_FLAT) - .fgcolor(Theme::y_axis) .button( BTN_POS(2,6), BTN_SIZE(1,1), F(""), OPT_FLAT) - .fgcolor(Theme::z_axis) .button( BTN_POS(3,6), BTN_SIZE(1,1), F(""), OPT_FLAT); - #endif + .fgcolor(Theme::axis_label) + .font(Theme::font_large) + .button( UNION_POS(X_LBL_POS, X_VAL_POS), F(""), OPT_FLAT) + .button( UNION_POS(Y_LBL_POS, Y_VAL_POS), F(""), OPT_FLAT) + .button( UNION_POS(Z_LBL_POS, Z_VAL_POS), F(""), OPT_FLAT) + .font(Theme::font_medium) + .fgcolor(Theme::x_axis) .button( X_VAL_POS, F(""), OPT_FLAT) + .fgcolor(Theme::y_axis) .button( Y_VAL_POS, F(""), OPT_FLAT) + .fgcolor(Theme::z_axis) .button( Z_VAL_POS, F(""), OPT_FLAT) + .font(Theme::font_small) + .text ( X_LBL_POS, GET_TEXT_F(MSG_AXIS_X)) + .text ( Y_LBL_POS, GET_TEXT_F(MSG_AXIS_Y)) + .text ( Z_LBL_POS, GET_TEXT_F(MSG_AXIS_Z)) + .colors(normal_btn); } if (what & FOREGROUND) { @@ -97,20 +97,15 @@ void StatusScreen::draw_axis_position(draw_mode_t what) { strcpy_P(y_str, PSTR("?")); if (isAxisPositionKnown(Z)) - format_position(z_str, getAxisPosition_mm(Z)); + format_position(z_str, getAxisPosition_mm(Z), 2); else strcpy_P(z_str, PSTR("?")); - cmd.tag(6).font(Theme::font_medium) - #ifdef TOUCH_UI_PORTRAIT - .text ( BTN_POS(2,5), BTN_SIZE(2,1), x_str) - .text ( BTN_POS(2,6), BTN_SIZE(2,1), y_str) - .text ( BTN_POS(2,7), BTN_SIZE(2,1), z_str); - #else - .text ( BTN_POS(1,6), BTN_SIZE(1,1), x_str) - .text ( BTN_POS(2,6), BTN_SIZE(1,1), y_str) - .text ( BTN_POS(3,6), BTN_SIZE(1,1), z_str); - #endif + cmd.tag(6) + .font(Theme::font_medium) + .text ( X_VAL_POS, x_str) + .text ( Y_VAL_POS, y_str) + .text ( Z_VAL_POS, z_str); } #undef GRID_COLS @@ -125,49 +120,49 @@ void StatusScreen::draw_axis_position(draw_mode_t what) { void StatusScreen::draw_temperature(draw_mode_t what) { using namespace Theme; + #define TEMP_RECT_1 BTN_POS(1,1), BTN_SIZE(4,2) + #define TEMP_RECT_2 BTN_POS(1,1), BTN_SIZE(8,1) + #define NOZ_1_POS BTN_POS(1,1), BTN_SIZE(4,1) + #define NOZ_2_POS BTN_POS(5,1), BTN_SIZE(4,1) + #define BED_POS BTN_POS(1,2), BTN_SIZE(4,1) + #define FAN_POS BTN_POS(5,2), BTN_SIZE(4,1) + + #define _ICON_POS(x,y,w,h) x, y, w/4, h + #define _TEXT_POS(x,y,w,h) x + w/4, y, w - w/4, h + #define ICON_POS(pos) _ICON_POS(pos) + #define TEXT_POS(pos) _TEXT_POS(pos) + CommandProcessor cmd; if (what & BACKGROUND) { cmd.font(Theme::font_small) - #ifdef TOUCH_UI_PORTRAIT - .tag(5) - .fgcolor(temp) .button( BTN_POS(1,1), BTN_SIZE(4,2), F(""), OPT_FLAT) - .button( BTN_POS(1,1), BTN_SIZE(8,1), F(""), OPT_FLAT) - .fgcolor(fan_speed) .button( BTN_POS(5,2), BTN_SIZE(4,1), F(""), OPT_FLAT) - .tag(0) - .fgcolor(progress) .button( BTN_POS(1,3), BTN_SIZE(4,1), F(""), OPT_FLAT) - .button( BTN_POS(5,3), BTN_SIZE(4,1), F(""), OPT_FLAT); - #else .tag(5) - .fgcolor(temp) .button( BTN_POS(1,1), BTN_SIZE(4,2), F(""), OPT_FLAT) - .button( BTN_POS(1,1), BTN_SIZE(8,1), F(""), OPT_FLAT) - .fgcolor(fan_speed) .button( BTN_POS(5,2), BTN_SIZE(4,1), F(""), OPT_FLAT) - .tag(0) - .fgcolor(progress) .button( BTN_POS(9,1), BTN_SIZE(4,1), F(""), OPT_FLAT) - .button( BTN_POS(9,2), BTN_SIZE(4,1), F(""), OPT_FLAT); - #endif + .fgcolor(temp) .button( TEMP_RECT_1, F(""), OPT_FLAT) + .button( TEMP_RECT_2, F(""), OPT_FLAT) + .fgcolor(fan_speed).button( FAN_POS, F(""), OPT_FLAT) + .tag(0); // Draw Extruder Bitmap on Extruder Temperature Button cmd.tag(5) - .cmd(BITMAP_SOURCE(Extruder_Icon_Info)) - .cmd(BITMAP_LAYOUT(Extruder_Icon_Info)) - .cmd(BITMAP_SIZE (Extruder_Icon_Info)) - .icon (BTN_POS(1,1), BTN_SIZE(1,1), Extruder_Icon_Info, icon_scale) - .icon (BTN_POS(5,1), BTN_SIZE(1,1), Extruder_Icon_Info, icon_scale); + .cmd (BITMAP_SOURCE(Extruder_Icon_Info)) + .cmd (BITMAP_LAYOUT(Extruder_Icon_Info)) + .cmd (BITMAP_SIZE (Extruder_Icon_Info)) + .icon(ICON_POS(NOZ_1_POS), Extruder_Icon_Info, icon_scale) + .icon(ICON_POS(NOZ_2_POS), Extruder_Icon_Info, icon_scale); // Draw Bed Heat Bitmap on Bed Heat Button - cmd.cmd(BITMAP_SOURCE(Bed_Heat_Icon_Info)) - .cmd(BITMAP_LAYOUT(Bed_Heat_Icon_Info)) - .cmd(BITMAP_SIZE (Bed_Heat_Icon_Info)) - .icon (BTN_POS(1,2), BTN_SIZE(1,1), Bed_Heat_Icon_Info, icon_scale); + cmd.cmd (BITMAP_SOURCE(Bed_Heat_Icon_Info)) + .cmd (BITMAP_LAYOUT(Bed_Heat_Icon_Info)) + .cmd (BITMAP_SIZE (Bed_Heat_Icon_Info)) + .icon(ICON_POS(BED_POS), Bed_Heat_Icon_Info, icon_scale); // Draw Fan Percent Bitmap on Bed Heat Button - cmd.cmd(BITMAP_SOURCE(Fan_Icon_Info)) - .cmd(BITMAP_LAYOUT(Fan_Icon_Info)) - .cmd(BITMAP_SIZE (Fan_Icon_Info)) - .icon (BTN_POS(5,2), BTN_SIZE(1,1), Fan_Icon_Info, icon_scale); + cmd.cmd (BITMAP_SOURCE(Fan_Icon_Info)) + .cmd (BITMAP_LAYOUT(Fan_Icon_Info)) + .cmd (BITMAP_SIZE (Fan_Icon_Info)) + .icon(ICON_POS(FAN_POS), Fan_Icon_Info, icon_scale); #ifdef TOUCH_UI_USE_UTF8 load_utf8_bitmaps(cmd); // Restore font bitmap handles @@ -181,11 +176,7 @@ void StatusScreen::draw_temperature(draw_mode_t what) { char bed_str[20]; char fan_str[20]; - sprintf_P( - fan_str, - PSTR("%-3d %%"), - int8_t(getActualFan_percent(FAN0)) - ); + sprintf_P(fan_str, PSTR("%-3d %%"), int8_t(getActualFan_percent(FAN0))); if (isHeaterIdle(BED)) format_temp_and_idle(bed_str, getActualTemp_celsius(BED)); @@ -198,24 +189,21 @@ void StatusScreen::draw_temperature(draw_mode_t what) { format_temp_and_temp(e0_str, getActualTemp_celsius(H0), getTargetTemp_celsius(H0)); - #if EXTRUDERS == 2 + #if HAS_MULTI_EXTRUDER if (isHeaterIdle(H1)) format_temp_and_idle(e1_str, getActualTemp_celsius(H1)); else format_temp_and_temp(e1_str, getActualTemp_celsius(H1), getTargetTemp_celsius(H1)); #else - strcpy_P( - e1_str, - PSTR("-") - ); + strcpy_P(e1_str, PSTR("-")); #endif cmd.tag(5) .font(font_medium) - .text(BTN_POS(2,1), BTN_SIZE(3,1), e0_str) - .text(BTN_POS(6,1), BTN_SIZE(3,1), e1_str) - .text(BTN_POS(2,2), BTN_SIZE(3,1), bed_str) - .text(BTN_POS(6,2), BTN_SIZE(3,1), fan_str); + .text(TEXT_POS(NOZ_1_POS), e0_str) + .text(TEXT_POS(NOZ_2_POS), e1_str) + .text(TEXT_POS(BED_POS), bed_str) + .text(TEXT_POS(FAN_POS), fan_str); } } @@ -225,15 +213,18 @@ void StatusScreen::draw_progress(draw_mode_t what) { CommandProcessor cmd; + #if ENABLED(TOUCH_UI_PORTRAIT) + #define TIME_POS BTN_POS(1,3), BTN_SIZE(4,1) + #define PROGRESS_POS BTN_POS(5,3), BTN_SIZE(4,1) + #else + #define TIME_POS BTN_POS(9,1), BTN_SIZE(4,1) + #define PROGRESS_POS BTN_POS(9,2), BTN_SIZE(4,1) + #endif + if (what & BACKGROUND) { cmd.tag(0).font(font_medium) - #ifdef TOUCH_UI_PORTRAIT - .fgcolor(progress) .button(BTN_POS(1,3), BTN_SIZE(4,1), F(""), OPT_FLAT) - .button(BTN_POS(5,3), BTN_SIZE(4,1), F(""), OPT_FLAT); - #else - .fgcolor(progress) .button(BTN_POS(9,1), BTN_SIZE(4,1), F(""), OPT_FLAT) - .button(BTN_POS(9,2), BTN_SIZE(4,1), F(""), OPT_FLAT); - #endif + .fgcolor(progress).button(TIME_POS, F(""), OPT_FLAT) + .button(PROGRESS_POS, F(""), OPT_FLAT); } if (what & FOREGROUND) { @@ -248,13 +239,8 @@ void StatusScreen::draw_progress(draw_mode_t what) { sprintf_P(progress_str, PSTR("%-3d %%"), getProgress_percent() ); cmd.font(font_medium) - #ifdef TOUCH_UI_PORTRAIT - .tag(0).text(BTN_POS(1,3), BTN_SIZE(4,1), time_str) - .text(BTN_POS(5,3), BTN_SIZE(4,1), progress_str); - #else - .tag(0).text(BTN_POS(9,1), BTN_SIZE(4,1), time_str) - .text(BTN_POS(9,2), BTN_SIZE(4,1), progress_str); - #endif + .tag(7).text(TIME_POS, time_str) + .text(PROGRESS_POS, progress_str); } } @@ -266,49 +252,44 @@ void StatusScreen::draw_interaction_buttons(draw_mode_t what) { if (what & FOREGROUND) { using namespace ExtUI; + #if ENABLED(TOUCH_UI_PORTRAIT) + #define MEDIA_BTN_POS BTN_POS(1,8), BTN_SIZE(2,1) + #define MENU_BTN_POS BTN_POS(3,8), BTN_SIZE(2,1) + #else + #define MEDIA_BTN_POS BTN_POS(1,7), BTN_SIZE(2,2) + #define MENU_BTN_POS BTN_POS(3,7), BTN_SIZE(2,2) + #endif + const bool has_media = isMediaInserted() && !isPrintingFromMedia(); CommandProcessor cmd; cmd.colors(normal_btn) .font(Theme::font_medium) - .enabled(has_media) .colors(has_media ? action_btn : normal_btn) - .tag(3).button( - #ifdef TOUCH_UI_PORTRAIT - BTN_POS(1,8), BTN_SIZE(2,1), - #else - BTN_POS(1,7), BTN_SIZE(2,2), - #endif - isPrintingFromMedia() ? GET_TEXT_F(MSG_PRINTING) : GET_TEXT_F(MSG_BUTTON_MEDIA) - ).colors(!has_media ? action_btn : normal_btn) - #ifdef TOUCH_UI_PORTRAIT - .tag(4).button( BTN_POS(3,8), BTN_SIZE(2,1), GET_TEXT_F(MSG_BUTTON_MENU)); - #else - .tag(4).button( BTN_POS(3,7), BTN_SIZE(2,2), GET_TEXT_F(MSG_BUTTON_MENU)); - #endif + .enabled(has_media) + .tag(3).button(MEDIA_BTN_POS, isPrintingFromMedia() ? GET_TEXT_F(MSG_PRINTING) : GET_TEXT_F(MSG_BUTTON_MEDIA)) + .colors(!has_media ? action_btn : normal_btn) + .tag(4).button( MENU_BTN_POS, GET_TEXT_F(MSG_BUTTON_MENU)); } #undef GRID_COLS } void StatusScreen::draw_status_message(draw_mode_t what, const char* message) { #define GRID_COLS 1 + + #if ENABLED(TOUCH_UI_PORTRAIT) + #define STATUS_POS BTN_POS(1,4), BTN_SIZE(1,1) + #else + #define STATUS_POS BTN_POS(1,3), BTN_SIZE(1,2) + #endif + if (what & BACKGROUND) { CommandProcessor cmd; cmd.fgcolor(Theme::status_msg) .tag(0) - #ifdef TOUCH_UI_PORTRAIT - .button( BTN_POS(1,4), BTN_SIZE(1,1), F(""), OPT_FLAT); - #else - .button( BTN_POS(1,3), BTN_SIZE(1,2), F(""), OPT_FLAT); - #endif + .button( STATUS_POS, F(""), OPT_FLAT); - draw_text_box(cmd, - #ifdef TOUCH_UI_PORTRAIT - BTN_POS(1,4), BTN_SIZE(1,1), - #else - BTN_POS(1,3), BTN_SIZE(1,2), - #endif - message, OPT_CENTER, font_large); + draw_text_box(cmd, STATUS_POS, message, OPT_CENTER, font_large); } #undef GRID_COLS } @@ -326,10 +307,10 @@ void StatusScreen::setStatusMessage(const char* message) { .cmd(CLEAR(true,true,true)); draw_temperature(BACKGROUND); - draw_progress(BACKGROUND); - draw_axis_position(BACKGROUND); draw_status_message(BACKGROUND, message); draw_interaction_buttons(BACKGROUND); + draw_progress(BACKGROUND); + draw_axis_position(BACKGROUND); storeBackground(); @@ -372,6 +353,7 @@ void StatusScreen::onRedraw(draw_mode_t what) { } void StatusScreen::onEntry() { + BaseScreen::onEntry(); onRefresh(); } @@ -387,20 +369,33 @@ bool StatusScreen::onTouchEnd(uint8_t tag) { using namespace ExtUI; switch (tag) { - case 3: GOTO_SCREEN(FilesScreen); break; + #if ENABLED(SDSUPPORT) + case 3: GOTO_SCREEN(FilesScreen); break; + #endif case 4: if (isPrinting()) { GOTO_SCREEN(TuneMenu); - } else { + } + else { GOTO_SCREEN(MainMenu); } break; case 5: GOTO_SCREEN(TemperatureScreen); break; case 6: - if (!isPrinting()) { + if (isPrinting()) { + #if ENABLED(BABYSTEPPING) + GOTO_SCREEN(NudgeNozzleScreen); + #elif HAS_BED_PROBE + GOTO_SCREEN(ZOffsetScreen); + #else + return false; + #endif + } + else { GOTO_SCREEN(MoveAxisScreen); } break; + case 7: GOTO_SCREEN(FeedratePercentScreen); break; default: return true; } diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/stepper_bump_sensitivity_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/stepper_bump_sensitivity_screen.cpp similarity index 73% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/stepper_bump_sensitivity_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/stepper_bump_sensitivity_screen.cpp index 9aa28aff39d8..693d125fbf48 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/stepper_bump_sensitivity_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/stepper_bump_sensitivity_screen.cpp @@ -17,12 +17,12 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" -#if ENABLED(TOUCH_UI_FTDI_EVE) && HAS_TRINAMIC +#if BOTH(TOUCH_UI_FTDI_EVE, HAS_TRINAMIC_CONFIG) #include "screens.h" @@ -34,39 +34,21 @@ void StepperBumpSensitivityScreen::onRedraw(draw_mode_t what) { widgets_t w(what); w.precision(0, BaseNumericAdjustmentScreen::DEFAULT_LOWEST); w.heading( GET_TEXT_F(MSG_TMC_HOMING_THRS)); - w.color(x_axis) .adjuster( 2, GET_TEXT_F(MSG_AXIS_X), getTMCBumpSensitivity(X), - #if X_SENSORLESS - true - #else - false - #endif - ); - w.color(y_axis) .adjuster( 4, GET_TEXT_F(MSG_AXIS_Y), getTMCBumpSensitivity(Y), - #if Y_SENSORLESS - true - #else - false - #endif - ); - w.color(z_axis) .adjuster( 6, GET_TEXT_F(MSG_AXIS_Z), getTMCBumpSensitivity(Z), - #if Z_SENSORLESS - true - #else - false - #endif - ); + w.color(x_axis) .adjuster( 2, GET_TEXT_F(MSG_AXIS_X), getTMCBumpSensitivity(X), ENABLED(X_SENSORLESS)); + w.color(y_axis) .adjuster( 4, GET_TEXT_F(MSG_AXIS_Y), getTMCBumpSensitivity(Y), ENABLED(Y_SENSORLESS)); + w.color(z_axis) .adjuster( 6, GET_TEXT_F(MSG_AXIS_Z), getTMCBumpSensitivity(Z), ENABLED(Z_SENSORLESS)); w.increments(); } bool StepperBumpSensitivityScreen::onTouchHeld(uint8_t tag) { const float increment = getIncrement(); switch (tag) { - case 2: UI_DECREMENT(TMCBumpSensitivity, X ); break; - case 3: UI_INCREMENT(TMCBumpSensitivity, X ); break; - case 4: UI_DECREMENT(TMCBumpSensitivity, Y ); break; - case 5: UI_INCREMENT(TMCBumpSensitivity, Y ); break; - case 6: UI_DECREMENT(TMCBumpSensitivity, Z ); break; - case 7: UI_INCREMENT(TMCBumpSensitivity, Z ); break; + case 2: UI_DECREMENT(TMCBumpSensitivity, X); break; + case 3: UI_INCREMENT(TMCBumpSensitivity, X); break; + case 4: UI_DECREMENT(TMCBumpSensitivity, Y); break; + case 5: UI_INCREMENT(TMCBumpSensitivity, Y); break; + case 6: UI_DECREMENT(TMCBumpSensitivity, Z); break; + case 7: UI_INCREMENT(TMCBumpSensitivity, Z); break; default: return false; } @@ -74,4 +56,4 @@ bool StepperBumpSensitivityScreen::onTouchHeld(uint8_t tag) { return true; } -#endif // TOUCH_UI_FTDI_EVE && HAS_TRINAMIC +#endif // TOUCH_UI_FTDI_EVE && HAS_TRINAMIC_CONFIG diff --git a/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/stepper_current_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/stepper_current_screen.cpp new file mode 100644 index 000000000000..136582f09aa7 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/stepper_current_screen.cpp @@ -0,0 +1,127 @@ +/****************************** + * stepper_current_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: . * + ****************************************************************************/ + +#include "../config.h" + +#if BOTH(TOUCH_UI_FTDI_EVE, HAS_TRINAMIC_CONFIG) + +#include "screens.h" + +using namespace FTDI; +using namespace ExtUI; +using namespace Theme; + +void StepperCurrentScreen::onRedraw(draw_mode_t what) { + widgets_t w(what); + w.precision(0); + w.units(GET_TEXT_F(MSG_UNITS_MILLIAMP)); + w.heading( GET_TEXT_F(MSG_TMC_CURRENT)); + #if AXIS_IS_TMC(X) + w.color(x_axis) .adjuster( 2, GET_TEXT_F(MSG_AXIS_X), getAxisCurrent_mA(X) ); + #endif + #if AXIS_IS_TMC(X2) + w.color(x_axis) .adjuster( 4, GET_TEXT_F(MSG_AXIS_X2), getAxisCurrent_mA(X2) ); + #endif + #if AXIS_IS_TMC(Y) + w.color(y_axis) .adjuster( 6, GET_TEXT_F(MSG_AXIS_Y), getAxisCurrent_mA(Y) ); + #endif + #if AXIS_IS_TMC(Y2) + w.color(x_axis) .adjuster( 8, GET_TEXT_F(MSG_AXIS_Y2), getAxisCurrent_mA(Y2) ); + #endif + #if AXIS_IS_TMC(Z) + w.color(z_axis) .adjuster(10, GET_TEXT_F(MSG_AXIS_Z), getAxisCurrent_mA(Z) ); + #endif + #if AXIS_IS_TMC(Z2) + w.color(z_axis) .adjuster(12, GET_TEXT_F(MSG_AXIS_Z2), getAxisCurrent_mA(Z2) ); + #endif + #if AXIS_IS_TMC(E0) + w.color(e_axis) .adjuster(14, GET_TEXT_F( + #if EXTRUDERS == 1 + MSG_AXIS_E + #else + MSG_AXIS_E1 + #endif + ), getAxisCurrent_mA(E0) ); + #endif + #if AXIS_IS_TMC(E1) + w.color(e_axis).adjuster(16, GET_TEXT_F(MSG_AXIS_E2), getAxisCurrent_mA(E1) ); + #endif + #if AXIS_IS_TMC(E2) + w.color(e_axis).adjuster(18, GET_TEXT_F(MSG_AXIS_E3), getAxisCurrent_mA(E2) ); + #endif + #if AXIS_IS_TMC(E3) + w.color(e_axis).adjuster(20, GET_TEXT_F(MSG_AXIS_E4), getAxisCurrent_mA(E3) ); + #endif + w.increments(); +} + +bool StepperCurrentScreen::onTouchHeld(uint8_t tag) { + const float increment = getIncrement(); + switch (tag) { + #if AXIS_IS_TMC(X) + case 2: UI_DECREMENT(AxisCurrent_mA, X ); break; + case 3: UI_INCREMENT(AxisCurrent_mA, X ); break; + #endif + #if AXIS_IS_TMC(X2) + case 4: UI_DECREMENT(AxisCurrent_mA, X2 ); break; + case 5: UI_INCREMENT(AxisCurrent_mA, X2 ); break; + #endif + #if AXIS_IS_TMC(Y) + case 6: UI_DECREMENT(AxisCurrent_mA, Y ); break; + case 7: UI_INCREMENT(AxisCurrent_mA, Y ); break; + #endif + #if AXIS_IS_TMC(Y2) + case 8: UI_DECREMENT(AxisCurrent_mA, Y2 ); break; + case 9: UI_INCREMENT(AxisCurrent_mA, Y2 ); break; + #endif + #if AXIS_IS_TMC(Z) + case 10: UI_DECREMENT(AxisCurrent_mA, Z ); break; + case 11: UI_INCREMENT(AxisCurrent_mA, Z ); break; + #endif + #if AXIS_IS_TMC(Z2) + case 12: UI_DECREMENT(AxisCurrent_mA, Z2 ); break; + case 13: UI_INCREMENT(AxisCurrent_mA, Z2 ); break; + #endif + #if AXIS_IS_TMC(E0) + case 14: UI_DECREMENT(AxisCurrent_mA, E0); break; + case 15: UI_INCREMENT(AxisCurrent_mA, E0); break; + #endif + #if AXIS_IS_TMC(E1) + case 16: UI_DECREMENT(AxisCurrent_mA, E1); break; + case 17: UI_INCREMENT(AxisCurrent_mA, E1); break; + #endif + #if AXIS_IS_TMC(E2) + case 18: UI_DECREMENT(AxisCurrent_mA, E2); break; + case 19: UI_INCREMENT(AxisCurrent_mA, E2); break; + #endif + #if AXIS_IS_TMC(E3) + case 20: UI_DECREMENT(AxisCurrent_mA, E3); break; + case 21: UI_INCREMENT(AxisCurrent_mA, E3); break; + #endif + default: + return false; + } + SaveSettingsDialogBox::settingsChanged(); + return true; +} + +#endif // TOUCH_UI_FTDI_EVE diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/steps_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/steps_screen.cpp similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/steps_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/steps_screen.cpp index f47707f96547..92035d1b1c04 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/steps_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/steps_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -40,7 +40,7 @@ void StepsScreen::onRedraw(draw_mode_t what) { w.color(z_axis) .adjuster( 6, GET_TEXT_F(MSG_AXIS_Z), getAxisSteps_per_mm(Z) ); #if EXTRUDERS == 1 || DISABLED(DISTINCT_E_FACTORS) w.color(e_axis) .adjuster( 8, GET_TEXT_F(MSG_AXIS_E), getAxisSteps_per_mm(E0) ); - #elif EXTRUDERS > 1 + #elif HAS_MULTI_EXTRUDER w.color(e_axis) .adjuster( 8, GET_TEXT_F(MSG_AXIS_E1), getAxisSteps_per_mm(E0) ); w.color(e_axis) .adjuster(10, GET_TEXT_F(MSG_AXIS_E2), getAxisSteps_per_mm(E1) ); #if EXTRUDERS > 2 @@ -64,7 +64,7 @@ bool StepsScreen::onTouchHeld(uint8_t tag) { case 7: UI_INCREMENT(AxisSteps_per_mm, Z); break; case 8: UI_DECREMENT(AxisSteps_per_mm, E0); break; case 9: UI_INCREMENT(AxisSteps_per_mm, E0); break; - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER case 10: UI_DECREMENT(AxisSteps_per_mm, E1); break; case 11: UI_INCREMENT(AxisSteps_per_mm, E1); break; #endif diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/stress_test_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/stress_test_screen.cpp similarity index 86% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/stress_test_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/stress_test_screen.cpp index b5e9263efa53..44ee453f15e6 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/stress_test_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/stress_test_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -38,7 +38,7 @@ using namespace ExtUI; void StressTestScreen::drawDots(uint16_t x, uint16_t y, uint16_t w, uint16_t h) { CommandProcessor cmd; - for(uint8_t i = 0; i < 100; i++) { + for (uint8_t i = 0; i < 100; i++) { cmd.cmd(BEGIN(POINTS)) .cmd(POINT_SIZE(20*16)) .cmd(COLOR_RGB(random(0xFFFFFF))) @@ -87,9 +87,8 @@ void StressTestScreen::runTestOnBootup(bool enable) { } void StressTestScreen::startupCheck() { - if (LockScreen::get_hash() == 0xDEAD) { + if (LockScreen::get_hash() == 0xDEAD) GOTO_SCREEN(StressTestScreen); - } } void StressTestScreen::onEntry() { @@ -112,7 +111,7 @@ void StressTestScreen::recursiveLockup() { void StressTestScreen::iterativeLockup() { screen_data.StressTestScreen.message = PSTR("Test 3: Printer will restart."); - for(;;) current_screen.onRefresh(); + for (;;) current_screen.onRefresh(); } void StressTestScreen::onIdle() { @@ -120,19 +119,18 @@ void StressTestScreen::onIdle() { reset_menu_timeout(); if (!commandsInQueue()) { - if (!isPositionKnown()) { - extern const char G28_STR[]; - injectCommands_P(G28_STR); - } else { - injectCommands_P(PSTR( - "G0 X100 Y100 Z100 F6000\n" - "T0\nG4 S1" - #if EXTRUDERS > 1 - "\nT1\nG4 S1" - #endif - "\nG0 X150 Y150 Z150" - )); - } + if (!isPositionKnown()) { + extern const char G28_STR[]; + injectCommands_P(G28_STR); + } + else { + injectCommands_P(PSTR( + "G0 X100 Y100 Z100 F6000\n" + "T0\nG4 S1" + TERN_(HAS_MULTI_EXTRUDER, "\nT1\nG4 S1") + "\nG0 X150 Y150 Z150" + )); + } } if (refresh_timer.elapsed(STRESS_TEST_CHANGE_INTERVAL)) { @@ -140,10 +138,10 @@ void StressTestScreen::onIdle() { } if (watchDogTestNow()) { - if (random(2) % 2) - iterativeLockup(); - else - recursiveLockup(); + if (random(2) % 2) + iterativeLockup(); + else + recursiveLockup(); } BaseScreen::onIdle(); diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/string_format.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/string_format.cpp similarity index 93% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/string_format.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/string_format.cpp index ca4fdad3ce61..b7ce76ecd2b3 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/string_format.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/string_format.cpp @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -61,8 +61,8 @@ void format_temp_and_material(char *str, float t1, const char *material) { /** * Formats a position value (e.g. "10 mm") */ -void format_position(char *str, float p) { - dtostrf(p, 5, 1, str); +void format_position(char *str, float p, uint8_t decimals) { + dtostrf(p, 4 + decimals, decimals, str); strcat_P(str, PSTR(" ")); strcat_P(str, GET_TEXT(MSG_UNITS_MM)); } diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/string_format.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/string_format.h similarity index 91% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/string_format.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/string_format.h index d6e26fb5cbcd..e37a82d28a5f 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/string_format.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/string_format.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once @@ -25,5 +25,5 @@ void format_temp(char *str, float t1); void format_temp_and_idle(char *str, float t1); void format_temp_and_temp(char *str, float t1, float t2); void format_temp_and_material(char *str, float t1, const char *material); -void format_position(char *str, float p); +void format_position(char *str, float p, uint8_t decimals = 1); void format_position(char *str, float x, float y, float z); diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/temperature_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/temperature_screen.cpp similarity index 91% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/temperature_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/temperature_screen.cpp index 81cde5a34120..c254d2997f62 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/temperature_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/temperature_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -35,7 +35,7 @@ void TemperatureScreen::onRedraw(draw_mode_t what) { #if TOUCH_UI_LCD_TEMP_SCALING == 10 w.precision(1) #else - w.precision(0) + w.precision(0, getTargetTemp_celsius(E0) == 0 ? DEFAULT_HIGHEST : DEFAULT_MIDRANGE) #endif .color(temp).units(GET_TEXT_F(MSG_UNITS_C)); w.heading(GET_TEXT_F(MSG_TEMPERATURE)); @@ -60,7 +60,7 @@ void TemperatureScreen::onRedraw(draw_mode_t what) { #if HAS_HEATED_CHAMBER w.adjuster( 22, GET_TEXT_F(MSG_CHAMBER), getTargetTemp_celsius(CHAMBER)); #endif - #if FAN_COUNT > 0 + #if HAS_FAN w.color(fan_speed).units(GET_TEXT_F(MSG_UNITS_PERCENT)); w.adjuster( 10, GET_TEXT_F(MSG_FAN_SPEED), getTargetFan_percent(FAN0)); #endif @@ -78,7 +78,7 @@ bool TemperatureScreen::onTouchHeld(uint8_t tag) { case 2: UI_DECREMENT(TargetTemp_celsius, E0); break; case 3: UI_INCREMENT(TargetTemp_celsius, E0); break; #endif - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND case 4: UI_DECREMENT(TargetTemp_celsius, E1); break; case 5: UI_INCREMENT(TargetTemp_celsius, E1); break; #endif @@ -90,20 +90,16 @@ bool TemperatureScreen::onTouchHeld(uint8_t tag) { case 8: UI_DECREMENT(TargetTemp_celsius, E3); break; case 9: UI_INCREMENT(TargetTemp_celsius, E3); break; #endif - #if FAN_COUNT > 0 + #if HAS_FAN case 10: UI_DECREMENT(TargetFan_percent, FAN0); break; case 11: UI_INCREMENT(TargetFan_percent, FAN0); break; #endif case 30: #define _HOTEND_OFF(N) setTargetTemp_celsius(0,E##N); REPEAT(HOTENDS, _HOTEND_OFF); - #if HAS_HEATED_BED - setTargetTemp_celsius(0,BED); - #endif - #if HAS_HEATED_CHAMBER - setTargetTemp_celsius(0,CHAMBER); - #endif - #if FAN_COUNT > 0 + TERN_(HAS_HEATED_BED, setTargetTemp_celsius(0,BED)); + TERN_(HAS_HEATED_CHAMBER, setTargetTemp_celsius(0,CHAMBER)); + #if HAS_FAN setTargetFan_percent(0,FAN0); #endif break; diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/touch_calibration_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/touch_calibration_screen.cpp similarity index 89% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/touch_calibration_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/touch_calibration_screen.cpp index b6c5ecae3d85..436445024a2f 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/touch_calibration_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/touch_calibration_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" @@ -32,6 +32,8 @@ using namespace Theme; #define GRID_COLS 4 #define GRID_ROWS 16 +#define TEXT_POS BTN_POS(1,1), BTN_SIZE(4,12) + void TouchCalibrationScreen::onEntry() { CommandProcessor cmd; @@ -45,7 +47,7 @@ void TouchCalibrationScreen::onEntry() { .cmd(CLEAR_COLOR_RGB(bg_color)) .cmd(CLEAR(true,true,true)) .cmd(COLOR_RGB(bg_text_enabled)); - draw_text_box(cmd, BTN_POS(1,1), BTN_SIZE(4,16), GET_TEXT_F(MSG_TOUCH_CALIBRATION_START), OPT_CENTER, font_large); + draw_text_box(cmd, TEXT_POS, GET_TEXT_F(MSG_TOUCH_CALIBRATION_START), OPT_CENTER, font_large); cmd.cmd(DL::DL_DISPLAY) .cmd(CMD_SWAP) .execute(); @@ -76,7 +78,7 @@ void TouchCalibrationScreen::onRedraw(draw_mode_t) { .cmd(CLEAR(true,true,true)) .cmd(COLOR_RGB(bg_text_enabled)); - draw_text_box(cmd, BTN_POS(1,1), BTN_SIZE(4,16), GET_TEXT_F(MSG_TOUCH_CALIBRATION_PROMPT), OPT_CENTER, font_large); + draw_text_box(cmd, TEXT_POS, GET_TEXT_F(MSG_TOUCH_CALIBRATION_PROMPT), OPT_CENTER, font_large); cmd.cmd(CMD_CALIBRATE); } diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/touch_registers_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/touch_registers_screen.cpp similarity index 98% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/touch_registers_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/touch_registers_screen.cpp index 4d7477b300ad..8c3bc856b3c7 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/touch_registers_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/touch_registers_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" diff --git a/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/tune_menu.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/tune_menu.cpp new file mode 100644 index 000000000000..9fe2f1e9cbcb --- /dev/null +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/tune_menu.cpp @@ -0,0 +1,127 @@ +/******************* + * 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: . * + ****************************************************************************/ + +#include "../config.h" + +#if ENABLED(TOUCH_UI_FTDI_EVE) && !defined(TOUCH_UI_LULZBOT_BIO) + +#include "screens.h" + +using namespace FTDI; +using namespace Theme; + +void TuneMenu::onRedraw(draw_mode_t what) { + if (what & BACKGROUND) { + CommandProcessor cmd; + cmd.cmd(CLEAR_COLOR_RGB(bg_color)) + .cmd(CLEAR(true,true,true)); + } + + #ifdef TOUCH_UI_PORTRAIT + #define GRID_ROWS 9 + #define GRID_COLS 2 + #define TEMPERATURE_POS BTN_POS(1,1), BTN_SIZE(2,1) + #define FIL_CHANGE_POS BTN_POS(1,2), BTN_SIZE(2,1) + #define FILAMENT_POS BTN_POS(1,3), BTN_SIZE(2,1) + #define NUDGE_NOZ_POS BTN_POS(1,4), BTN_SIZE(2,1) + #define SPEED_POS BTN_POS(1,5), BTN_SIZE(2,1) + #define PAUSE_POS BTN_POS(1,6), BTN_SIZE(2,1) + #define STOP_POS BTN_POS(1,7), BTN_SIZE(2,1) + #define CASE_LIGHT_POS BTN_POS(1,8), BTN_SIZE(2,1) + #define BACK_POS BTN_POS(1,9), BTN_SIZE(2,1) + #else + #define GRID_ROWS 5 + #define GRID_COLS 2 + #define TEMPERATURE_POS BTN_POS(1,1), BTN_SIZE(1,1) + #define NUDGE_NOZ_POS BTN_POS(2,1), BTN_SIZE(1,1) + #define FIL_CHANGE_POS BTN_POS(1,2), BTN_SIZE(1,1) + #define SPEED_POS BTN_POS(2,2), BTN_SIZE(1,1) + #define PAUSE_POS BTN_POS(1,3), BTN_SIZE(1,1) + #define STOP_POS BTN_POS(2,3), BTN_SIZE(1,1) + #define FILAMENT_POS BTN_POS(1,4), BTN_SIZE(1,1) + #define CASE_LIGHT_POS BTN_POS(2,4), BTN_SIZE(1,1) + #define BACK_POS BTN_POS(1,5), BTN_SIZE(2,1) + #endif + + if (what & FOREGROUND) { + using namespace ExtUI; + + CommandProcessor cmd; + cmd.colors(normal_btn) + .font(font_medium) + .tag(2).button( TEMPERATURE_POS, GET_TEXT_F(MSG_TEMPERATURE)) + .enabled(!isPrinting() || isPrintingFromMediaPaused()) + .tag(3).button( FIL_CHANGE_POS, GET_TEXT_F(MSG_FILAMENTCHANGE)) + .enabled(EITHER(LIN_ADVANCE, FILAMENT_RUNOUT_SENSOR)) + .tag(9).button( FILAMENT_POS, GET_TEXT_F(MSG_FILAMENT)) + .enabled(EITHER(HAS_BED_PROBE, BABYSTEPPING)) + .tag(4).button( NUDGE_NOZ_POS, GET_TEXT_F(TERN(BABYSTEPPING, MSG_NUDGE_NOZZLE, MSG_ZPROBE_ZOFFSET))) + .tag(5).button( SPEED_POS, GET_TEXT_F(MSG_PRINT_SPEED)) + .tag(isPrintingFromMediaPaused() ? 7 : 6) + .enabled(TERN0(SDSUPPORT, isPrintingFromMedia())) + .button( PAUSE_POS, isPrintingFromMediaPaused() ? GET_TEXT_F(MSG_RESUME_PRINT) : GET_TEXT_F(MSG_PAUSE_PRINT)) + .enabled(TERN0(SDSUPPORT, isPrintingFromMedia())) + .tag(8).button( STOP_POS, GET_TEXT_F(MSG_STOP_PRINT)) + .enabled(ENABLED(CASE_LIGHT_ENABLE)) + .tag(10).button( CASE_LIGHT_POS, GET_TEXT_F(MSG_CASE_LIGHT)) + .tag(1).colors(action_btn) + .button( BACK_POS, GET_TEXT_F(MSG_BACK)); + } + #undef GRID_COLS + #undef GRID_ROWS +} + +bool TuneMenu::onTouchEnd(uint8_t tag) { + using namespace Theme; + using namespace ExtUI; + switch (tag) { + case 1: GOTO_PREVIOUS(); break; + case 2: GOTO_SCREEN(TemperatureScreen); break; + case 3: GOTO_SCREEN(ChangeFilamentScreen); break; + case 4: + #if ENABLED(BABYSTEPPING) + GOTO_SCREEN(NudgeNozzleScreen); + #elif HAS_BED_PROBE + GOTO_SCREEN(ZOffsetScreen); + #endif + break; + case 5: GOTO_SCREEN(FeedratePercentScreen); break; + case 6: sound.play(twinkle, PLAY_ASYNCHRONOUS); ExtUI::pausePrint(); GOTO_SCREEN(StatusScreen); break; + case 7: sound.play(twinkle, PLAY_ASYNCHRONOUS); ExtUI::resumePrint(); GOTO_SCREEN(StatusScreen); break; + case 8: + GOTO_SCREEN(ConfirmAbortPrintDialogBox); + current_screen.forget(); + PUSH_SCREEN(StatusScreen); + break; + #if EITHER(LIN_ADVANCE, FILAMENT_RUNOUT_SENSOR) + case 9: GOTO_SCREEN(FilamentMenu); break; + #endif + #if ENABLED(CASE_LIGHT_ENABLE) + case 10: GOTO_SCREEN(CaseLightScreen); break; + #endif + default: + return false; + } + return true; +} + +#endif // TOUCH_UI_FTDI_EVE diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/widget_demo_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/widget_demo_screen.cpp similarity index 98% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/widget_demo_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/widget_demo_screen.cpp index b77cb5143e46..d7c456204123 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/widget_demo_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/widget_demo_screen.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/z_offset_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/z_offset_screen.cpp similarity index 94% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/z_offset_screen.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/z_offset_screen.cpp index 65a2ad0e8ec1..f5cd03697c08 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/screens/z_offset_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/z_offset_screen.cpp @@ -17,12 +17,12 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../config.h" -#if ENABLED(TOUCH_UI_FTDI_EVE) && HAS_BED_PROBE +#if BOTH(TOUCH_UI_FTDI_EVE, HAS_BED_PROBE) #include "screens.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/bitmaps.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/bitmaps.h similarity index 98% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/bitmaps.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/bitmaps.h index 00952cfc5bd9..2cb039c84df9 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/bitmaps.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/bitmaps.h @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once diff --git a/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/bootscreen_logo_portrait.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/bootscreen_logo_portrait.h new file mode 100644 index 000000000000..6ea317dbc3cd --- /dev/null +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/bootscreen_logo_portrait.h @@ -0,0 +1,42 @@ +/**************************************************************************** + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * To view a copy of the GNU General Public License, go to the following * + * location: . * + ****************************************************************************/ + +/** + * This 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, x_max = 272.000000, + y_min = 0.000000, y_max = 480.000000; + +const PROGMEM uint16_t logo_green[] = {0x8048, 0x46D9, 0x27BC, 0x9DBA, 0xD8D3, 0x9DBA}; +const PROGMEM uint16_t logo_mark[] = {0xDB9F, 0xAC0C, 0xDA6F, 0xAC2D, 0xD970, 0xAC91, 0xD8C0, 0xAD23, 0xD885, 0xADCF, 0xD8C0, 0xAE7A, 0xD970, 0xAF0C, 0xDA6F, 0xAF6F, 0xDB9F, 0xAF8F, 0xDCCE, 0xAF6F, 0xDDD0, 0xAF0C, 0xDE7D, 0xAE7B, 0xDEB9, 0xADCF, 0xDE7D, 0xAD22, 0xDDD0, 0xAC91, 0xDCCE, 0xAC2D, 0xFFFF, 0xDB9F, 0xABC3, 0xDCFE, 0xABEA, 0xDE28, 0xAC5E, 0xDEF1, 0xAD06, 0xDF36, 0xADCF, 0xDEF1, 0xAE95, 0xDE28, 0xAF3E, 0xDCFE, 0xAFB1, 0xDB9F, 0xAFD8, 0xDA3F, 0xAFB1, 0xD916, 0xAF3E, 0xD849, 0xAE95, 0xD808, 0xADCF, 0xD849, 0xAD06, 0xD916, 0xAC5E, 0xDA3F, 0xABEA, 0xFFFF, 0xDB7D, 0xACE6, 0xDAE4, 0xACE6, 0xDAE4, 0xADA9, 0xDB7D, 0xADA9, 0xDC3B, 0xAD94, 0xDC71, 0xAD48, 0xDC3B, 0xACFD, 0xFFFF, 0xDB85, 0xAC9E, 0xDCCB, 0xACC8, 0xDD37, 0xAD47, 0xDCF6, 0xADAC, 0xDC3E, 0xADDE, 0xDC85, 0xADFF, 0xDCE8, 0xAE4E, 0xDD92, 0xAEEA, 0xDCBD, 0xAEEA, 0xDC1E, 0xAE58, 0xDBA7, 0xAE03, 0xDB36, 0xADEF, 0xDAE4, 0xADEF, 0xDAE4, 0xAEEA, 0xDA26, 0xAEEA, 0xDA26, 0xAC9E}; +const PROGMEM uint16_t logo_type[] = {0xD8D5, 0xA520, 0xD8A5, 0xA563, 0xD82E, 0xA57F, 0xD348, 0xA57F, 0xD2D1, 0xA598, 0xD2A0, 0xA5D9, 0xD2A0, 0xAF7A, 0xD274, 0xAFBE, 0xD202, 0xAFDA, 0xCD37, 0xAFDA, 0xCCBF, 0xAFBE, 0xCC8F, 0xAF7A, 0xCC8F, 0xA5D9, 0xCC63, 0xA598, 0xCBF1, 0xA57F, 0xC70B, 0xA57F, 0xC694, 0xA563, 0xC664, 0xA520, 0xC664, 0xA28C, 0xC70B, 0xA22C, 0xD82E, 0xA22C, 0xD8A5, 0xA248, 0xD8D5, 0xA28C, 0xFFFF, 0xB138, 0xAC8C, 0xB952, 0xAC8C, 0xB952, 0xA57F, 0xB138, 0xA57F, 0xFFFF, 0xBF27, 0xA421, 0xBF57, 0xA476, 0xBF6D, 0xA4D0, 0xBF6D, 0xAD36, 0xBF57, 0xAD90, 0xBF27, 0xADE6, 0xBBFA, 0xAFB2, 0xBB60, 0xAFCF, 0xBABD, 0xAFDA, 0xAFCE, 0xAFDA, 0xAF30, 0xAFCF, 0xAE9A, 0xAFB2, 0xAB6E, 0xADE6, 0xAB39, 0xAD90, 0xAB28, 0xAD36, 0xAB28, 0xA4D0, 0xAB39, 0xA476, 0xAB6E, 0xA421, 0xAE9A, 0xA255, 0xAF30, 0xA239, 0xAFCE, 0xA22C, 0xBABD, 0xA22C, 0xBB60, 0xA239, 0xBBFA, 0xA255, 0xFFFF, 0x93A4, 0xACDC, 0x9CEA, 0xACDC, 0x9CEA, 0xAA34, 0x93A4, 0xAA34, 0x93A4, 0xACDC, 0xFFFF, 0x93A4, 0xA796, 0x9CEA, 0xA796, 0x9CEA, 0xA525, 0x93A4, 0xA525, 0xFFFF, 0xA227, 0xA421, 0xA258, 0xA478, 0xA26E, 0xA4D5, 0xA26E, 0xA700, 0xA24F, 0xA757, 0xA204, 0xA7A5, 0xA089, 0xA8B8, 0xA061, 0xA903, 0xA092, 0xA949, 0xA1FC, 0xAA43, 0xA24B, 0xAA91, 0xA26E, 0xAAE8, 0xA26E, 0xAD36, 0xA258, 0xAD90, 0xA227, 0xADE6, 0x9EFC, 0xAFB2, 0x9E61, 0xAFCF, 0x9DBE, 0xAFDA, 0x8ED0, 0xAFDA, 0x8E28, 0xAF7A, 0x8E28, 0xA28C, 0x8E59, 0xA248, 0x8ED0, 0xA22C, 0x9DBE, 0xA22C, 0x9E61, 0xA239, 0x9EFC, 0xA255, 0xFFFF, 0x853C, 0xA502, 0x8517, 0xA557, 0x84C9, 0xA5A2, 0x7994, 0xACC8, 0x8494, 0xACC8, 0x850A, 0xACE4, 0x853C, 0xAD27, 0x853C, 0xAF7A, 0x850A, 0xAFBE, 0x8494, 0xAFDA, 0x7371, 0xAFDA, 0x72C9, 0xAF7A, 0x72C9, 0xAD09, 0x72E8, 0xACB2, 0x7333, 0xAC64, 0x7EA5, 0xA53E, 0x73A6, 0xA53E, 0x732F, 0xA522, 0x72FE, 0xA4DF, 0x72FE, 0xA28C, 0x732F, 0xA248, 0x73A6, 0xA22C, 0x8494, 0xA22C, 0x850A, 0xA248, 0x853C, 0xA28C, 0xFFFF, 0x6B68, 0xAC87, 0x6BDB, 0xACA3, 0x6C07, 0xACE6, 0x6C07, 0xAF7A, 0x6BDB, 0xAFBE, 0x6B68, 0xAFDA, 0x5C84, 0xAFDA, 0x5BDC, 0xAF7A, 0x5BDC, 0xA28C, 0x5C84, 0xA22C, 0x6146, 0xA22C, 0x61EE, 0xA28C, 0x61EE, 0xAC2D, 0x621E, 0xAC6E, 0x6295, 0xAC87, 0xFFFF, 0x52C6, 0xA248, 0x52F7, 0xA28C, 0x52F7, 0xAD45, 0x52EE, 0xAD45, 0x52DC, 0xAD9B, 0x52B1, 0xADE6, 0x4F85, 0xAFB2, 0x4EEA, 0xAFCF, 0x4E47, 0xAFDA, 0x4359, 0xAFDA, 0x42BA, 0xAFCF, 0x4224, 0xAFB2, 0x3EF8, 0xADE6, 0x3EC3, 0xAD90, 0x3EB2, 0xAD36, 0x3EB2, 0xA28C, 0x3EE2, 0xA248, 0x3F5A, 0xA22C, 0x441B, 0xA22C, 0x4493, 0xA248, 0x44C3, 0xA28C, 0x44C3, 0xAC2D, 0x44F4, 0xAC71, 0x456B, 0xAC8C, 0x4C3E, 0xAC8C, 0x4CB1, 0xAC71, 0x4CDD, 0xAC2D, 0x4CDD, 0xA28C, 0x4D0D, 0xA248, 0x4D85, 0xA22C, 0x524F, 0xA22C, 0xFFFF, 0x3748, 0xAC87, 0x37BB, 0xACA3, 0x37E7, 0xACE6, 0x37E7, 0xAF7A, 0x37BB, 0xAFBE, 0x3748, 0xAFDA, 0x2864, 0xAFDA, 0x27BC, 0xAF7A, 0x27BC, 0xA28C, 0x2864, 0xA22C, 0x2D26, 0xA22C, 0x2DCD, 0xA28C, 0x2DCD, 0xAC2D, 0x2DFE, 0xAC6E, 0x2E75, 0xAC87}; +const PROGMEM uint16_t logo_black[] = {0x8048, 0x527A, 0x8ADE, 0x5CDE, 0x75B2, 0x5CDE, 0xFFFF, 0x8048, 0x4FF6, 0x71D9, 0x5E20, 0x8EB8, 0x5E20, 0x8048, 0x4FF6, 0xFFFF, 0x4436, 0x8D8E, 0x4ECC, 0x97F2, 0x39A0, 0x97F2, 0xFFFF, 0x4436, 0x8B0A, 0x35C8, 0x9934, 0x52A5, 0x9934, 0xFFFF, 0xBC3D, 0x8D8E, 0xC6D4, 0x97F2, 0xB1A7, 0x97F2, 0xFFFF, 0xBC3D, 0x8B0A, 0xADCE, 0x9934, 0xCAAC, 0x9934, 0xFFFF, 0x8045, 0x6778, 0x7F6D, 0x67A7, 0x7E9D, 0x689F, 0x7D49, 0x69EA, 0x7B41, 0x6A81, 0x7908, 0x6A3A, 0x7726, 0x692C, 0x75EA, 0x685A, 0x7505, 0x684C, 0x744A, 0x6899, 0x73F5, 0x69A8, 0x7345, 0x6B1A, 0x7193, 0x6BF8, 0x6F4D, 0x6C08, 0x6CFA, 0x6B45, 0x6B61, 0x6AA3, 0x6A7D, 0x6AB7, 0x69EB, 0x6B1D, 0x6A1D, 0x6C34, 0x6A22, 0x6DB8, 0x68E5, 0x6ECD, 0x66B9, 0x6F33, 0x6417, 0x6EC5, 0x6239, 0x6E5C, 0x6165, 0x6E91, 0x6108, 0x6F09, 0x61C1, 0x7018, 0x6282, 0x7196, 0x61CF, 0x72D1, 0x5FE5, 0x7384, 0x5D38, 0x7380, 0x5B4B, 0x7365, 0x5A97, 0x73B7, 0x5A74, 0x7438, 0x5B90, 0x7520, 0x5CE8, 0x7671, 0x5CCB, 0x77BB, 0x5B43, 0x78B0, 0x58B6, 0x7914, 0x56D7, 0x7944, 0x564F, 0x79AD, 0x5667, 0x7A2F, 0x57DA, 0x7AE3, 0x59B7, 0x7BF3, 0x5A31, 0x7D37, 0x5927, 0x7E5D, 0x56E0, 0x7F1E, 0x5529, 0x7F93, 0x54D7, 0x800D, 0x5529, 0x8087, 0x56E0, 0x80FD, 0x5926, 0x81BE, 0x5A30, 0x82E5, 0x59B5, 0x8428, 0x57D8, 0x8538, 0x5664, 0x85EB, 0x564C, 0x866D, 0x56D4, 0x86D7, 0x58B2, 0x8708, 0x5B3F, 0x876B, 0x5CC6, 0x8860, 0x5CE3, 0x89AA, 0x5B8B, 0x8AFC, 0x5A6D, 0x8BE3, 0x5A91, 0x8C65, 0x5B44, 0x8CB7, 0x5D32, 0x8C9C, 0x5FDE, 0x8C98, 0x61C7, 0x8D4B, 0x627A, 0x8E87, 0x61B9, 0x9005, 0x60FF, 0x9114, 0x615C, 0x918B, 0x622F, 0x91C0, 0x640E, 0x9158, 0x66B0, 0x90EA, 0x68DC, 0x9150, 0x6A18, 0x9266, 0x6A12, 0x93E9, 0x69E0, 0x9501, 0x6A72, 0x9567, 0x6B56, 0x957B, 0x6CEE, 0x94D9, 0x6F43, 0x9417, 0x7188, 0x9428, 0x7339, 0x9506, 0x73E9, 0x9678, 0x743E, 0x9787, 0x74F8, 0x97D4, 0x75DD, 0x97C6, 0x771A, 0x96F4, 0x78FB, 0x95E6, 0x7B35, 0x95A1, 0x7D3D, 0x9637, 0x7E91, 0x9782, 0x7F60, 0x987A, 0x8038, 0x98AA, 0x810F, 0x987B, 0x81DF, 0x9782, 0x8333, 0x9638, 0x853B, 0x95A1, 0x8775, 0x95E7, 0x8956, 0x96F5, 0x8A92, 0x97C8, 0x8B78, 0x97D6, 0x8C32, 0x9789, 0x8C88, 0x967A, 0x8D37, 0x9508, 0x8EE9, 0x942A, 0x912F, 0x941A, 0x9383, 0x94DD, 0x951B, 0x957F, 0x95FF, 0x956B, 0x9690, 0x9505, 0x9660, 0x93ED, 0x9659, 0x926A, 0x9797, 0x9154, 0x99C3, 0x90EF, 0x9C65, 0x915D, 0x9E43, 0x91C6, 0x9F17, 0x9191, 0x9F74, 0x9119, 0x9EBB, 0x900A, 0x9DFA, 0x8E8C, 0x9EAE, 0x8D51, 0xA098, 0x8C9E, 0xA345, 0x8CA2, 0xA531, 0x8CBE, 0xA5E5, 0x8C6B, 0xA609, 0x8BEA, 0xA4EC, 0x8B02, 0xA394, 0x89B1, 0xA3B2, 0x8867, 0xA53A, 0x8772, 0xA7C6, 0x870E, 0xA9A5, 0x86DE, 0xAA2D, 0x8675, 0xAA14, 0x85F2, 0xA8A2, 0x853F, 0xA6C5, 0x842E, 0xA64B, 0x82EB, 0xA755, 0x81C5, 0xA99C, 0x8104, 0xAB52, 0x808F, 0xABA6, 0x8015, 0xAB52, 0x7F9B, 0xA99C, 0x7F25, 0xA755, 0x7E64, 0xA64C, 0x7D3E, 0xA6C7, 0x7BFA, 0xA8A5, 0x7AEA, 0xAA18, 0x7A37, 0xAA31, 0x79B5, 0xA9A9, 0x794B, 0xA7CA, 0x791B, 0xA53C, 0x78B7, 0xA3B6, 0x77C1, 0xA39A, 0x7677, 0xA4F1, 0x7526, 0xA60E, 0x743F, 0xA5EB, 0x73BD, 0xA538, 0x736B, 0xA34B, 0x7387, 0xA09E, 0x738A, 0x9EB4, 0x72D6, 0x9E02, 0x719B, 0x9EC4, 0x701D, 0x9F7E, 0x6F0E, 0x9F20, 0x6E96, 0x9E4E, 0x6E61, 0x9C6E, 0x6ECA, 0x99CB, 0x6F37, 0x97A0, 0x6ED2, 0x9664, 0x6DBC, 0x966B, 0x6C38, 0x969B, 0x6B21, 0x960B, 0x6ABB, 0x9526, 0x6AA6, 0x938E, 0x6B48, 0x913B, 0x6C0B, 0x8EF4, 0x6BFA, 0x8D43, 0x6B1D, 0x8C94, 0x69AA, 0x8C3F, 0x689B, 0x8B85, 0x684D, 0x8A9E, 0x685C, 0x8962, 0x692E, 0x8781, 0x6A3C, 0x8546, 0x6A82, 0x833F, 0x69EA, 0x81EC, 0x68A0, 0x811C, 0x67A8, 0x8045, 0x6778, 0x8045, 0x6778, 0xFFFF, 0x8047, 0x6AA0, 0x81C8, 0x6AFA, 0x8268, 0x6BD5, 0x81C8, 0x6CAF, 0x8047, 0x6D09, 0x7EC6, 0x6CAF, 0x7E27, 0x6BD5, 0x7EC6, 0x6AFA, 0x8047, 0x6AA0, 0x8047, 0x6AA0, 0xFFFF, 0x803E, 0x6E19, 0x867C, 0x6E71, 0x8C65, 0x6F75, 0x91D7, 0x711B, 0x96AD, 0x735B, 0x9ABC, 0x762C, 0x9DA2, 0x794C, 0x9F5F, 0x7CA2, 0x9FF3, 0x8011, 0x9F5E, 0x8380, 0x9DA1, 0x86D5, 0x9ABA, 0x89F6, 0x96AB, 0x8CC7, 0x91D6, 0x8F08, 0x8C65, 0x90AD, 0x867C, 0x91B1, 0x803D, 0x9209, 0x7A00, 0x91B1, 0x7416, 0x90AD, 0x6EA6, 0x8F08, 0x69D0, 0x8CC7, 0x65D6, 0x8A0A, 0x62EE, 0x86F4, 0x6125, 0x839B, 0x6089, 0x8011, 0x6124, 0x7C88, 0x62ED, 0x792E, 0x65D6, 0x7619, 0x69CF, 0x735B, 0x6EA5, 0x711B, 0x7416, 0x6F75, 0x7A00, 0x6E71, 0x803E, 0x6E19, 0x803E, 0x6E19, 0xFFFF, 0x803E, 0x6EB2, 0x7A5A, 0x6F04, 0x74B2, 0x6FF8, 0x6F4B, 0x7194, 0x6A8F, 0x73C7, 0x66A2, 0x7681, 0x63D5, 0x7986, 0x6226, 0x7CBF, 0x6197, 0x8011, 0x6226, 0x8363, 0x63D5, 0x869C, 0x66A2, 0x89A2, 0x6A8F, 0x8C5B, 0x6F4B, 0x8E8E, 0x74B2, 0x902B, 0x7A5A, 0x911E, 0x803D, 0x9170, 0x803E, 0x9170, 0x8621, 0x911E, 0x8BCA, 0x902B, 0x9130, 0x8E8E, 0x95ED, 0x8C5B, 0x99CF, 0x89AB, 0x9CA7, 0x869C, 0x9E55, 0x8367, 0x9EE5, 0x8011, 0x9E55, 0x7CBB, 0x9CA7, 0x7986, 0x99CF, 0x7677, 0x95ED, 0x73C7, 0x9130, 0x7194, 0x8BCA, 0x6FF8, 0x8621, 0x6F04, 0x803E, 0x6EB2, 0x803E, 0x6EB2, 0xFFFF, 0x80BC, 0x6FD7, 0x80AF, 0x71D8, 0x7FC8, 0x71D9, 0x7FB7, 0x6FD8, 0x80BC, 0x6FD7, 0x80BC, 0x6FD7, 0xFFFF, 0x83CB, 0x6FF6, 0x84CD, 0x700B, 0x843E, 0x7206, 0x835B, 0x71F4, 0xFFFF, 0x7CA9, 0x6FF8, 0x7D1A, 0x71F5, 0x7C37, 0x7207, 0x7BA7, 0x700D, 0x7CA9, 0x6FF8, 0x7CA9, 0x6FF8, 0xFFFF, 0x87CD, 0x7068, 0x88C7, 0x7092, 0x87BA, 0x727C, 0x86DF, 0x7258, 0xFFFF, 0x78A8, 0x706B, 0x7997, 0x725A, 0x78BA, 0x727E, 0x77AD, 0x7095, 0x78A8, 0x706B, 0x78A8, 0x706B, 0xFFFF, 0x6700, 0x708A, 0x6880, 0x70E5, 0x6920, 0x71BF, 0x6880, 0x7299, 0x66FF, 0x72F4, 0x657F, 0x7299, 0x64E0, 0x71BF, 0x657F, 0x70E4, 0x6700, 0x708A, 0x6700, 0x708A, 0xFFFF, 0x998D, 0x708C, 0x9B0E, 0x70E6, 0x9BAE, 0x71C0, 0x9B0E, 0x729B, 0x998D, 0x72F6, 0x980D, 0x729B, 0x976E, 0x71C1, 0x980D, 0x70E7, 0x998D, 0x708C, 0x998D, 0x708C, 0xFFFF, 0x8BA7, 0x712C, 0x8C95, 0x716A, 0x8B10, 0x7339, 0x8A3F, 0x7303, 0x8BA7, 0x712C, 0xFFFF, 0x74CE, 0x712F, 0x7635, 0x7307, 0x7564, 0x733C, 0x73DE, 0x716D, 0x74CE, 0x712F, 0x74CE, 0x712F, 0xFFFF, 0x8F47, 0x723F, 0x9023, 0x728E, 0x8E2D, 0x743A, 0x8D6B, 0x73F4, 0x8F47, 0x723F, 0xFFFF, 0x712D, 0x7242, 0x7308, 0x73F7, 0x7248, 0x743D, 0x7050, 0x7292, 0x712D, 0x7242, 0x712D, 0x7242, 0xFFFF, 0x803E, 0x72F6, 0x891B, 0x73F4, 0x909A, 0x76CC, 0x959F, 0x7B0B, 0x975E, 0x8011, 0x959F, 0x8517, 0x909A, 0x8957, 0x891B, 0x8C2E, 0x803E, 0x8D2B, 0x7761, 0x8C2E, 0x6FE2, 0x8957, 0x6ADD, 0x8517, 0x691E, 0x8011, 0x6ADD, 0x7B0B, 0x6FE2, 0x76CC, 0x7761, 0x73F4, 0x803E, 0x72F6, 0x803E, 0x72F6, 0xFFFF, 0x803E, 0x738F, 0x77C8, 0x7481, 0x70A0, 0x7738, 0x6BD7, 0x7B46, 0x6A2C, 0x8011, 0x6BD7, 0x84DC, 0x70A1, 0x88EA, 0x77C9, 0x8BA1, 0x803E, 0x8C93, 0x88B4, 0x8BA1, 0x8FDB, 0x88EA, 0x94A5, 0x84DD, 0x9650, 0x8011, 0x94A5, 0x7B46, 0x8FDB, 0x7738, 0x88B4, 0x7481, 0x803E, 0x738F, 0x803E, 0x738F, 0xFFFF, 0x929B, 0x739A, 0x935C, 0x73FA, 0x9100, 0x7578, 0x905A, 0x7527, 0x9175, 0x745E, 0xFFFF, 0x6DDC, 0x739D, 0x7022, 0x7527, 0x6F74, 0x757C, 0x6D16, 0x73FF, 0x6DDC, 0x739D, 0x6DDC, 0x739D, 0xFFFF, 0x9589, 0x7533, 0x9634, 0x75A4, 0x937E, 0x76ED, 0x92E8, 0x768B, 0xFFFF, 0x6AEB, 0x7539, 0x6D8D, 0x7690, 0x6CFB, 0x76F0, 0x6CEC, 0x76FA, 0x6BED, 0x7674, 0x6A40, 0x75A9, 0x6A45, 0x75A7, 0x6AEB, 0x7539, 0x6AEB, 0x7539, 0xFFFF, 0x980B, 0x7707, 0x989A, 0x7784, 0x9597, 0x7892, 0x951A, 0x7825, 0xFFFF, 0x686A, 0x770C, 0x6B5B, 0x782A, 0x6ADF, 0x7897, 0x67DD, 0x7788, 0x686A, 0x770C, 0x686A, 0x770C, 0xFFFF, 0x9A12, 0x790A, 0x9A7E, 0x7991, 0x9740, 0x7A5E, 0x96E1, 0x79E8, 0x9A12, 0x790A, 0xFFFF, 0x6664, 0x790F, 0x6996, 0x79ED, 0x6937, 0x7A63, 0x65F9, 0x7996, 0x6664, 0x790F, 0x6664, 0x790F, 0xFFFF, 0x9B91, 0x7B32, 0x9BDB, 0x7BC1, 0x9870, 0x7C48, 0x9831, 0x7BCB, 0xFFFF, 0x64E6, 0x7B37, 0x6847, 0x7BD0, 0x6807, 0x7C4C, 0x649D, 0x7BC5, 0x64E6, 0x7B37, 0x64E6, 0x7B37, 0xFFFF, 0x9C82, 0x7D72, 0x9CA7, 0x7E06, 0x9925, 0x7E46, 0x9903, 0x7DC5, 0xFFFF, 0x63F7, 0x7D78, 0x6776, 0x7DC9, 0x6756, 0x7E49, 0x63D3, 0x7E0A, 0x63F7, 0x7D78, 0x63F7, 0x7D78, 0xFFFF, 0x5C87, 0x7EDB, 0x5E08, 0x7F35, 0x5EA8, 0x800F, 0x5E08, 0x80E9, 0x5C87, 0x8144, 0x5C85, 0x8144, 0x5B06, 0x80E9, 0x5A67, 0x800F, 0x5B06, 0x7F35, 0x5C87, 0x7EDB, 0x5C87, 0x7EDB, 0xFFFF, 0xA402, 0x7EDE, 0xA583, 0x7F38, 0xA623, 0x8011, 0xA623, 0x8013, 0xA583, 0x80EC, 0xA402, 0x8147, 0xA281, 0x80ED, 0xA1E2, 0x8013, 0xA281, 0x7F38, 0xA402, 0x7EDE, 0xA402, 0x7EDE, 0xFFFF, 0x9CE0, 0x7FC0, 0x9CE0, 0x8055, 0x9957, 0x804D, 0x9957, 0x7FCB, 0xFFFF, 0x639D, 0x7FC5, 0x6726, 0x7FCE, 0x6726, 0x8051, 0x639D, 0x805A, 0x639D, 0x7FC5, 0x639D, 0x7FC5, 0xFFFF, 0x9927, 0x81D1, 0x9CAA, 0x8210, 0x9C87, 0x82A2, 0x9907, 0x8252, 0x9927, 0x81D1, 0x9927, 0x81D1, 0xFFFF, 0x6757, 0x81D5, 0x6777, 0x8255, 0x63F9, 0x82A7, 0x63D4, 0x8214, 0xFFFF, 0x9877, 0x83CF, 0x9BE2, 0x8455, 0x9B99, 0x84E3, 0x9838, 0x844C, 0x9877, 0x83CF, 0x9877, 0x83CF, 0xFFFF, 0x6808, 0x83D3, 0x6848, 0x8450, 0x64E7, 0x84E8, 0x649E, 0x845A, 0xFFFF, 0x9749, 0x85B9, 0x9A88, 0x8684, 0x9A1D, 0x870C, 0x96EB, 0x862E, 0x9749, 0x85B9, 0x9749, 0x85B9, 0xFFFF, 0x6938, 0x85BD, 0x6997, 0x8634, 0x6665, 0x8710, 0x65F9, 0x8689, 0xFFFF, 0x95A2, 0x8785, 0x98A5, 0x8892, 0x9818, 0x890F, 0x9527, 0x87F2, 0x95A2, 0x8785, 0x95A2, 0x8785, 0xFFFF, 0x6ADF, 0x878A, 0x6B5B, 0x87F8, 0x686A, 0x8914, 0x67DC, 0x8897, 0x6ADF, 0x878A, 0xFFFF, 0x6CF7, 0x892F, 0x6D8D, 0x8991, 0x6AEB, 0x8AE9, 0x6A40, 0x8A79, 0xFFFF, 0x9380, 0x8932, 0x9645, 0x8A72, 0x963E, 0x8A77, 0x9599, 0x8AE3, 0x92F5, 0x898D, 0x9380, 0x8932, 0x9380, 0x8932, 0xFFFF, 0x9110, 0x8AA1, 0x936F, 0x8C1F, 0x92AA, 0x8C80, 0x9064, 0x8AF7, 0x9110, 0x8AA1, 0x9110, 0x8AA1, 0xFFFF, 0x6F73, 0x8AA5, 0x7021, 0x8AFB, 0x7035, 0x8B04, 0x6DED, 0x8C8B, 0x6DE1, 0x8C87, 0x6D17, 0x8C23, 0xFFFF, 0x8E3E, 0x8BE1, 0x9037, 0x8D8B, 0x8F59, 0x8DDC, 0x8D7C, 0x8C27, 0x8E3E, 0x8BE1, 0x8E3E, 0x8BE1, 0xFFFF, 0x7259, 0x8BEB, 0x731B, 0x8C31, 0x7140, 0x8DE7, 0x7064, 0x8D97, 0xFFFF, 0x8B21, 0x8CE3, 0x8CA9, 0x8EB2, 0x8BBA, 0x8EEF, 0x8A51, 0x8D18, 0x8B21, 0x8CE3, 0x8B21, 0x8CE3, 0xFFFF, 0x7576, 0x8CEB, 0x7648, 0x8D20, 0x74E0, 0x8EF8, 0x73F2, 0x8EBB, 0xFFFF, 0x66F3, 0x8D2F, 0x6874, 0x8D8A, 0x687D, 0x8D8F, 0x6886, 0x8D94, 0x6926, 0x8E6E, 0x6887, 0x8F48, 0x6705, 0x8FA2, 0x6584, 0x8F49, 0x657F, 0x8F45, 0x6570, 0x8F3E, 0x6573, 0x8F3E, 0x64D3, 0x8E63, 0x6573, 0x8D89, 0x66F3, 0x8D2F, 0x66F3, 0x8D2F, 0xFFFF, 0x9993, 0x8D31, 0x9B13, 0x8D8C, 0x9BB4, 0x8E66, 0x9B16, 0x8F40, 0x9993, 0x8F9A, 0x9814, 0x8F40, 0x9774, 0x8E66, 0x9812, 0x8D8C, 0x9993, 0x8D31, 0x9993, 0x8D31, 0xFFFF, 0x87CD, 0x8DA1, 0x88DC, 0x8F8B, 0x87E0, 0x8FB5, 0x86F0, 0x8DC6, 0x87CD, 0x8DA1, 0x87CD, 0x8DA1, 0xFFFF, 0x78CD, 0x8DA8, 0x79A8, 0x8DCB, 0x78BC, 0x8FBB, 0x77C1, 0x8F92, 0xFFFF, 0x8450, 0x8E19, 0x84E2, 0x9014, 0x83E0, 0x9029, 0x836C, 0x8E2C, 0x8450, 0x8E19, 0x8450, 0x8E19, 0xFFFF, 0x7C48, 0x8E1C, 0x7D2B, 0x8E2E, 0x7CBD, 0x902C, 0x7BBB, 0x9017, 0x7C48, 0x8E1C, 0xFFFF, 0x80BF, 0x8E49, 0x80D2, 0x904A, 0x7FCC, 0x904A, 0x7FD9, 0x8E49, 0x80BF, 0x8E49, 0x80BF, 0x8E49, 0xFFFF, 0x804F, 0x9321, 0x81D0, 0x937A, 0x8271, 0x9455, 0x81D1, 0x952F, 0x8051, 0x958A, 0x7ECF, 0x9530, 0x7E2F, 0x9456, 0x7ECE, 0x937B, 0x804F, 0x9321, 0x804F, 0x9321, 0xFFFF, 0x8048, 0x46D9, 0x27BC, 0x9DBA, 0xD8D3, 0x9DBA, 0xFFFF, 0x8048, 0x4BC9, 0x952E, 0x604A, 0x6B62, 0x604A, 0xFFFF, 0x68D2, 0x62CE, 0x97BF, 0x62CE, 0xB9BA, 0x8427, 0xA239, 0x9B36, 0x5E16, 0x9B36, 0x46B6, 0x8446, 0x68D2, 0x62CE, 0xFFFF, 0xBC3E, 0x869F, 0xD13B, 0x9B36, 0xA742, 0x9B36, 0xFFFF, 0x4431, 0x86BE, 0x590E, 0x9B36, 0x2F54, 0x9B36, 0x4431, 0x86BE}; +const PROGMEM uint16_t logo_white[] = {0x80BC, 0x6FD7, 0x80AF, 0x71D8, 0x7FC8, 0x71D9, 0x7FB7, 0x6FD8, 0x80BC, 0x6FD7, 0xFFFF, 0x83CB, 0x6FF6, 0x84CD, 0x700B, 0x843E, 0x7206, 0x835B, 0x71F4, 0xFFFF, 0x7CA9, 0x6FF8, 0x7D1A, 0x71F5, 0x7C37, 0x7207, 0x7BA7, 0x700D, 0x7CA9, 0x6FF8, 0x7CA9, 0x6FF8, 0xFFFF, 0x87CD, 0x7068, 0x88C7, 0x7092, 0x87BA, 0x727C, 0x86DF, 0x7258, 0xFFFF, 0x78A8, 0x706B, 0x7997, 0x725A, 0x78BA, 0x727E, 0x77AD, 0x7095, 0x78A8, 0x706B, 0x78A8, 0x706B, 0xFFFF, 0x8BA7, 0x712C, 0x8C95, 0x716A, 0x8B10, 0x7339, 0x8A3F, 0x7303, 0xFFFF, 0x74CE, 0x712F, 0x7635, 0x7307, 0x7564, 0x733C, 0x73DE, 0x716D, 0x74CE, 0x712F, 0x74CE, 0x712F, 0xFFFF, 0x8F47, 0x723F, 0x9023, 0x728E, 0x8E2D, 0x743A, 0x8D6B, 0x73F4, 0xFFFF, 0x712D, 0x7242, 0x7309, 0x73F7, 0x7248, 0x743D, 0x7050, 0x7292, 0x712D, 0x7242, 0x712D, 0x7242, 0xFFFF, 0x929B, 0x739A, 0x935C, 0x73FA, 0x9100, 0x7578, 0x905A, 0x7527, 0xFFFF, 0x6DDC, 0x739D, 0x7022, 0x7527, 0x6F74, 0x757C, 0x6D16, 0x73FF, 0x6DDC, 0x739D, 0x6DDC, 0x739D, 0xFFFF, 0x9589, 0x7533, 0x9634, 0x75A4, 0x937E, 0x76ED, 0x92E8, 0x768B, 0xFFFF, 0x6AEB, 0x7539, 0x6D8D, 0x7690, 0x6CFB, 0x76F0, 0x6A40, 0x75A9, 0x6AEB, 0x7539, 0xFFFF, 0x980B, 0x7707, 0x989A, 0x7784, 0x9597, 0x7892, 0x951A, 0x7825, 0xFFFF, 0x686A, 0x770C, 0x6B5B, 0x782A, 0x6ADF, 0x7897, 0x67DD, 0x7788, 0x686A, 0x770C, 0x686A, 0x770C, 0xFFFF, 0x9A12, 0x790A, 0x9A7E, 0x7991, 0x9740, 0x7A5E, 0x96E1, 0x79E8, 0xFFFF, 0x6664, 0x790F, 0x6996, 0x79ED, 0x6937, 0x7A63, 0x65F9, 0x7996, 0x6664, 0x790F, 0x6664, 0x790F, 0xFFFF, 0x9B91, 0x7B32, 0x9BDB, 0x7BC1, 0x9870, 0x7C48, 0x9831, 0x7BCC, 0xFFFF, 0x64E6, 0x7B37, 0x6847, 0x7BD0, 0x6807, 0x7C4C, 0x649D, 0x7BC5, 0x64E6, 0x7B37, 0x64E6, 0x7B37, 0xFFFF, 0x9C82, 0x7D72, 0x9CA7, 0x7E06, 0x9925, 0x7E46, 0x9903, 0x7DC5, 0xFFFF, 0x63F7, 0x7D78, 0x6776, 0x7DC9, 0x6756, 0x7E49, 0x63D3, 0x7E0A, 0x63F7, 0x7D78, 0x63F7, 0x7D78, 0xFFFF, 0x9CE0, 0x7FC0, 0x9CE0, 0x8055, 0x9957, 0x804D, 0x9957, 0x7FCB, 0xFFFF, 0x639D, 0x7FC5, 0x6726, 0x7FCE, 0x6726, 0x8051, 0x639D, 0x805A, 0x639D, 0x7FC5, 0xFFFF, 0x9927, 0x81D1, 0x9CAA, 0x8210, 0x9C87, 0x82A2, 0x9907, 0x8252, 0x9927, 0x81D1, 0x9927, 0x81D1, 0xFFFF, 0x6757, 0x81D5, 0x6777, 0x8256, 0x63F9, 0x82A7, 0x63D4, 0x8214, 0xFFFF, 0x9877, 0x83CF, 0x9BE2, 0x8455, 0x9B99, 0x84E3, 0x9838, 0x844C, 0x9877, 0x83CF, 0xFFFF, 0x6808, 0x83D3, 0x6848, 0x8450, 0x64E7, 0x84E8, 0x649E, 0x845A, 0xFFFF, 0x9749, 0x85B9, 0x9A88, 0x8684, 0x9A1D, 0x870C, 0x96EB, 0x862E, 0x9749, 0x85B9, 0x9749, 0x85B9, 0xFFFF, 0x6938, 0x85BD, 0x6997, 0x8634, 0x6665, 0x8710, 0x65F9, 0x8689, 0xFFFF, 0x95A2, 0x8785, 0x98A5, 0x8892, 0x9818, 0x890F, 0x9527, 0x87F2, 0x95A2, 0x8785, 0x95A2, 0x8785, 0xFFFF, 0x6ADF, 0x878A, 0x6B5B, 0x87F8, 0x686A, 0x8915, 0x67DC, 0x8897, 0xFFFF, 0x6CF7, 0x8930, 0x6D8D, 0x8991, 0x6AEB, 0x8AE9, 0x6A40, 0x8A79, 0xFFFF, 0x9380, 0x8932, 0x9645, 0x8A72, 0x9599, 0x8AE3, 0x92F5, 0x898D, 0x9380, 0x8932, 0xFFFF, 0x9110, 0x8AA1, 0x936F, 0x8C1F, 0x92AA, 0x8C80, 0x9064, 0x8AF7, 0x9110, 0x8AA1, 0x9110, 0x8AA1, 0xFFFF, 0x6F73, 0x8AA5, 0x7021, 0x8AFB, 0x6DED, 0x8C8C, 0x6D17, 0x8C23, 0xFFFF, 0x8E3E, 0x8BE1, 0x9037, 0x8D8B, 0x8F59, 0x8DDC, 0x8D7C, 0x8C27, 0x8E3E, 0x8BE1, 0x8E3E, 0x8BE1, 0xFFFF, 0x7259, 0x8BEB, 0x731B, 0x8C31, 0x7140, 0x8DE7, 0x7064, 0x8D97, 0xFFFF, 0x8B21, 0x8CE3, 0x8CA9, 0x8EB2, 0x8BBA, 0x8EEF, 0x8A51, 0x8D18, 0x8B21, 0x8CE3, 0x8B21, 0x8CE3, 0xFFFF, 0x7576, 0x8CEB, 0x7648, 0x8D20, 0x74E0, 0x8EF8, 0x73F2, 0x8EBB, 0xFFFF, 0x87CD, 0x8DA1, 0x88DC, 0x8F8B, 0x87E0, 0x8FB5, 0x86F0, 0x8DC6, 0x87CD, 0x8DA1, 0x87CD, 0x8DA1, 0xFFFF, 0x78CC, 0x8DA8, 0x79A8, 0x8DCB, 0x78BC, 0x8FBB, 0x77C0, 0x8F92, 0xFFFF, 0x8450, 0x8E19, 0x84E2, 0x9014, 0x83E0, 0x9029, 0x836C, 0x8E2C, 0x8450, 0x8E19, 0x8450, 0x8E19, 0xFFFF, 0x7C48, 0x8E1C, 0x7D2B, 0x8E2E, 0x7CBD, 0x902C, 0x7BBB, 0x9017, 0xFFFF, 0x80BE, 0x8E49, 0x80D1, 0x904A, 0x7FCC, 0x904A, 0x7FD9, 0x8E49, 0x80BE, 0x8E49, 0xFFFF, 0x8276, 0x75D6, 0x83AF, 0x75FE, 0x8436, 0x7628, 0x84AE, 0x7661, 0x8542, 0x7706, 0x8512, 0x77BA, 0x8457, 0x7845, 0x8335, 0x788B, 0x8318, 0x7882, 0x82D8, 0x7860, 0x831E, 0x7830, 0x8353, 0x7823, 0x83E6, 0x77F9, 0x8464, 0x7790, 0x847A, 0x771A, 0x8415, 0x76B7, 0x83B6, 0x7691, 0x8351, 0x7676, 0x827F, 0x7662, 0x81BB, 0x7687, 0x8161, 0x76AF, 0x8123, 0x76DA, 0x80E5, 0x771A, 0x80C5, 0x774D, 0x80B8, 0x77C1, 0x80D1, 0x77EE, 0x8107, 0x7814, 0x81CC, 0x786B, 0x837F, 0x7918, 0x8464, 0x7983, 0x84C0, 0x79B2, 0x852D, 0x79FD, 0x859D, 0x7ABC, 0x858E, 0x7B79, 0x8545, 0x7C25, 0x84D9, 0x7CC5, 0x8469, 0x7D4D, 0x843B, 0x7DCD, 0x8555, 0x7DA8, 0x85D3, 0x7D67, 0x870D, 0x7CA0, 0x87E0, 0x7BC0, 0x880D, 0x7B5B, 0x886D, 0x7A46, 0x88B3, 0x799B, 0x88CC, 0x7970, 0x893A, 0x78EA, 0x8995, 0x78A8, 0x8A01, 0x786F, 0x8AF8, 0x781F, 0x8BA6, 0x77FD, 0x8C0C, 0x77EF, 0x8C96, 0x77FB, 0x8D1D, 0x7815, 0x8D59, 0x7826, 0x8E40, 0x7889, 0x8EDB, 0x7925, 0x8EFC, 0x797B, 0x8EFF, 0x79D4, 0x8E71, 0x7A7B, 0x8D58, 0x7AD2, 0x8C23, 0x7ADE, 0x8AFF, 0x7A97, 0x8AF5, 0x7A81, 0x8AEF, 0x7A4E, 0x8B68, 0x7A52, 0x8B96, 0x7A5F, 0x8C39, 0x7A87, 0x8D33, 0x7A7F, 0x8E07, 0x7A3F, 0x8E66, 0x79CB, 0x8E63, 0x7985, 0x8E43, 0x793F, 0x8DC6, 0x78C6, 0x8CFA, 0x7876, 0x8C7E, 0x785F, 0x8C18, 0x7857, 0x8B84, 0x7874, 0x8B22, 0x788F, 0x8A7D, 0x78CA, 0x8A2E, 0x78F9, 0x89F0, 0x7930, 0x89A3, 0x79A5, 0x8979, 0x7AC0, 0x897C, 0x7B9C, 0x8972, 0x7BF2, 0x88CC, 0x7D32, 0x87B7, 0x7E4C, 0x8665, 0x7F52, 0x8660, 0x7F5A, 0x878F, 0x7F01, 0x88AE, 0x7EC2, 0x89FD, 0x7E9E, 0x8B8D, 0x7EC6, 0x8C40, 0x7F0E, 0x8CB6, 0x7F68, 0x8D1D, 0x7FD7, 0x8DFA, 0x80BD, 0x8EA8, 0x816E, 0x8F34, 0x81D4, 0x8F8A, 0x81F9, 0x8FDA, 0x820A, 0x90AB, 0x820F, 0x9120, 0x81FF, 0x91A5, 0x81DC, 0x91F4, 0x81B8, 0x922C, 0x8198, 0x9288, 0x812B, 0x927D, 0x80AB, 0x9252, 0x8068, 0x921C, 0x8033, 0x9174, 0x7FEB, 0x9099, 0x7FEB, 0x8FCF, 0x8029, 0x8F5D, 0x808D, 0x8F47, 0x80A4, 0x8ED4, 0x80A4, 0x8EC5, 0x8070, 0x8F65, 0x7FE6, 0x906D, 0x7F92, 0x91A4, 0x7F90, 0x92A8, 0x7FF7, 0x92FC, 0x8043, 0x9331, 0x8090, 0x9349, 0x813D, 0x92D1, 0x81E3, 0x9264, 0x8227, 0x91E5, 0x825B, 0x915D, 0x8280, 0x90D3, 0x8296, 0x8FA0, 0x829A, 0x8F2C, 0x8286, 0x8EE7, 0x8273, 0x8E78, 0x824A, 0x8DA9, 0x81D4, 0x8CB9, 0x8127, 0x8B68, 0x802C, 0x8B22, 0x8001, 0x8AC3, 0x7FE7, 0x8A50, 0x7FF4, 0x88FD, 0x8068, 0x87A4, 0x811D, 0x879E, 0x812D, 0x8904, 0x81F1, 0x89D4, 0x8285, 0x8A7C, 0x8343, 0x8A94, 0x8431, 0x8A4E, 0x84A1, 0x89E8, 0x850E, 0x892F, 0x85E5, 0x88B0, 0x86E5, 0x88C0, 0x8757, 0x88F2, 0x878D, 0x8927, 0x87AD, 0x8ABF, 0x8821, 0x8B0E, 0x881E, 0x8B70, 0x8811, 0x8C1B, 0x87D6, 0x8C9B, 0x8776, 0x8CC4, 0x873D, 0x8CD3, 0x8705, 0x8CA2, 0x86A3, 0x8C06, 0x8662, 0x8B39, 0x864F, 0x8A77, 0x8662, 0x89F9, 0x864D, 0x8A10, 0x8606, 0x8A66, 0x85F7, 0x8B35, 0x85DC, 0x8C50, 0x85FD, 0x8D3C, 0x8663, 0x8D94, 0x870A, 0x8D7D, 0x875F, 0x8D3A, 0x87B8, 0x8CB1, 0x882D, 0x8BC1, 0x888C, 0x8B30, 0x88A7, 0x8A8D, 0x88AE, 0x89EE, 0x8898, 0x896E, 0x887E, 0x8869, 0x882D, 0x87EE, 0x87EA, 0x87A4, 0x87A8, 0x878E, 0x8785, 0x874D, 0x86E3, 0x875D, 0x8637, 0x87FD, 0x8466, 0x8705, 0x835A, 0x86B8, 0x8359, 0x84A4, 0x8358, 0x7F20, 0x851B, 0x7F13, 0x864D, 0x8016, 0x86F9, 0x818E, 0x87D8, 0x823B, 0x8869, 0x8272, 0x88C9, 0x8276, 0x8915, 0x8266, 0x893D, 0x81FB, 0x89D8, 0x8197, 0x8A21, 0x8119, 0x8A62, 0x80A7, 0x8A8A, 0x8016, 0x8AAA, 0x7EDC, 0x8AAE, 0x7DC5, 0x8A63, 0x7D55, 0x8A29, 0x7CFA, 0x89E5, 0x7CAD, 0x8939, 0x7D1B, 0x8895, 0x7E00, 0x8825, 0x7F27, 0x8800, 0x7F66, 0x880F, 0x7F69, 0x8850, 0x7E49, 0x8873, 0x7D9A, 0x88C9, 0x7D4F, 0x893E, 0x7D8B, 0x89B2, 0x7DD8, 0x89E6, 0x7E36, 0x8A10, 0x7F02, 0x8A40, 0x7FDB, 0x8A34, 0x8046, 0x8A16, 0x8091, 0x89F5, 0x80A5, 0x89EB, 0x80FE, 0x89AB, 0x8126, 0x8981, 0x8159, 0x8918, 0x814F, 0x88E6, 0x8128, 0x88B8, 0x8094, 0x8856, 0x7EFC, 0x8796, 0x7D74, 0x86E7, 0x7D3D, 0x86C5, 0x7CD8, 0x8674, 0x7C98, 0x8605, 0x7CA0, 0x8536, 0x7D7C, 0x83E6, 0x7E07, 0x8357, 0x7DED, 0x835B, 0x79CC, 0x843E, 0x7962, 0x8448, 0x77CB, 0x8450, 0x76F3, 0x8438, 0x763E, 0x841E, 0x7502, 0x83FE, 0x746C, 0x83FD, 0x73E4, 0x840A, 0x72CE, 0x8444, 0x729B, 0x8457, 0x71E6, 0x84B7, 0x71B5, 0x84EB, 0x719B, 0x853B, 0x719B, 0x8558, 0x71D4, 0x85E0, 0x72B0, 0x8642, 0x73D4, 0x8661, 0x74B3, 0x8616, 0x74AD, 0x84D7, 0x74B2, 0x84B3, 0x74B5, 0x849B, 0x751E, 0x8496, 0x753B, 0x84B8, 0x75C5, 0x856E, 0x756D, 0x865A, 0x74D0, 0x86B8, 0x73FA, 0x86EA, 0x7250, 0x86CF, 0x70E7, 0x863F, 0x707E, 0x85C8, 0x705F, 0x8549, 0x7075, 0x84CC, 0x70AC, 0x8475, 0x70CD, 0x8452, 0x71FF, 0x839C, 0x7287, 0x8376, 0x736A, 0x833A, 0x7443, 0x8319, 0x751E, 0x8311, 0x76AC, 0x8327, 0x77C4, 0x8341, 0x7810, 0x8340, 0x799F, 0x8313, 0x7A2A, 0x82EA, 0x7B24, 0x8281, 0x7BE4, 0x820C, 0x7BEC, 0x81B1, 0x7A5E, 0x81C8, 0x7809, 0x81ED, 0x7751, 0x81F8, 0x7664, 0x81EF, 0x7571, 0x81B4, 0x74BB, 0x8141, 0x7483, 0x80F9, 0x7408, 0x802F, 0x73D9, 0x7FEB, 0x7359, 0x7F50, 0x72A0, 0x7EC4, 0x719E, 0x7E89, 0x7074, 0x7EA8, 0x7015, 0x7ECC, 0x6FD0, 0x7EF8, 0x6FA3, 0x7F19, 0x6F6B, 0x7FBB, 0x6F93, 0x8017, 0x6FA7, 0x8032, 0x6FD7, 0x805A, 0x70DF, 0x8092, 0x7205, 0x805A, 0x729E, 0x7FCB, 0x72B3, 0x7FBC, 0x7309, 0x7FA6, 0x733B, 0x7FDE, 0x72F9, 0x804B, 0x726D, 0x80A7, 0x70E6, 0x80FB, 0x700D, 0x80EC, 0x6F48, 0x80A8, 0x6EFC, 0x8073, 0x6EC1, 0x8026, 0x6E93, 0x7FCC, 0x6ED4, 0x7ED8, 0x6F54, 0x7E72, 0x6FCB, 0x7E3A, 0x700B, 0x7E25, 0x71AB, 0x7DED, 0x7356, 0x7E3E, 0x7472, 0x7EF4, 0x7536, 0x7FBD, 0x75DA, 0x8075, 0x7628, 0x80B6, 0x767B, 0x80D8, 0x76D9, 0x80EF, 0x7755, 0x80FC, 0x7881, 0x80D5, 0x7931, 0x8093, 0x7A00, 0x801E, 0x799B, 0x7D9B, 0x789A, 0x7CD8, 0x77C0, 0x7BE5, 0x7783, 0x7B55, 0x7787, 0x7AB9, 0x77AE, 0x7A67, 0x77E6, 0x7A1D, 0x781E, 0x79CD, 0x785E, 0x7909, 0x7853, 0x78C0, 0x7823, 0x788B, 0x7808, 0x7875, 0x7649, 0x77E8, 0x74B6, 0x7869, 0x7488, 0x78B3, 0x7472, 0x7901, 0x74D2, 0x796F, 0x75D8, 0x799A, 0x76EE, 0x7971, 0x774A, 0x797A, 0x7751, 0x79B4, 0x76A0, 0x79F0, 0x75E4, 0x7A0A, 0x7454, 0x79E1, 0x73AF, 0x7986, 0x7369, 0x7909, 0x7374, 0x7891, 0x739D, 0x783C, 0x73B6, 0x781E, 0x74B7, 0x7768, 0x765D, 0x772C, 0x77ED, 0x7769, 0x7932, 0x77FC, 0x7979, 0x7836, 0x79B8, 0x787B, 0x79DF, 0x7912, 0x7998, 0x7A14, 0x7967, 0x7AB4, 0x796A, 0x7AD8, 0x79C5, 0x7B60, 0x7A9D, 0x7BE9, 0x7B72, 0x7C47, 0x7EBA, 0x7BD6, 0x8206, 0x7CA8, 0x82FA, 0x7C2E, 0x8391, 0x7BB4, 0x83F6, 0x7B40, 0x8413, 0x7AD0, 0x83DD, 0x7A71, 0x838A, 0x7A39, 0x8296, 0x79B7, 0x80F3, 0x78FA, 0x8016, 0x788A, 0x7FB4, 0x7833, 0x7F8D, 0x77DF, 0x7F92, 0x77A9, 0x7FB3, 0x7718, 0x7FF6, 0x76C2, 0x8036, 0x768A, 0x8097, 0x764A, 0x80DF, 0x762A, 0x813C, 0x7605, 0x8275, 0x75D5}; + +#define LOGO_BACKGROUND 0xDEEA5C + +#define LOGO_PAINT_PATHS \ + LOGO_PAINT_PATH(0xC1D82F, logo_green) \ + LOGO_PAINT_PATH(0x000000, logo_black) \ + LOGO_PAINT_PATH(0x000000, logo_type) \ + LOGO_PAINT_PATH(0x000000, logo_mark) \ + LOGO_PAINT_PATH(0xFFFFFF, logo_white) diff --git a/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/colors.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/colors.h new file mode 100644 index 000000000000..4e2fde6ab333 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/colors.h @@ -0,0 +1,183 @@ +/************ + * colors.h * + ************/ + +/**************************************************************************** + * Written By Mark Pelletier 2017 - Aleph Objects, Inc. * + * Written By Marcio Teixeira 2018 - Aleph Objects, Inc. * + * Written By Marcio Teixeira 2019 - Cocoa Press * + * * + * 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: . * + ****************************************************************************/ + +#pragma once + +namespace Theme { + #if ENABLED(TOUCH_UI_COCOA_THEME) + constexpr int accent_hue = 23; + + // Browns and Oranges + constexpr uint32_t accent_color_1 = hsl_to_rgb(12.8,0.597,0.263); // Darkest + constexpr uint32_t accent_color_2 = hsl_to_rgb(12.8,0.597,0.263); + constexpr uint32_t accent_color_3 = hsl_to_rgb( 9.6,0.664,0.443); + constexpr uint32_t accent_color_4 = hsl_to_rgb(16.3,0.873,0.537); + constexpr uint32_t accent_color_5 = hsl_to_rgb(23.0,0.889,0.539); + constexpr uint32_t accent_color_6 = hsl_to_rgb(23.0,0.889,0.539); // Lightest + #else + // Use linear accent colors + + #if ANY(TOUCH_UI_ROYAL_THEME, TOUCH_UI_FROZEN_THEME) + // Dark blue accent colors + constexpr int accent_hue = 216; + constexpr float accent_sat = 0.7; + #else + // Green accent colors + constexpr int accent_hue = 68; + constexpr float accent_sat = 0.68; + #endif + + // Shades of accent color + constexpr uint32_t accent_color_0 = hsl_to_rgb(accent_hue, accent_sat, 0.15); // Darkest + constexpr uint32_t accent_color_1 = hsl_to_rgb(accent_hue, accent_sat, 0.26); + constexpr uint32_t accent_color_2 = hsl_to_rgb(accent_hue, accent_sat, 0.39); + constexpr uint32_t accent_color_3 = hsl_to_rgb(accent_hue, accent_sat, 0.52); + constexpr uint32_t accent_color_4 = hsl_to_rgb(accent_hue, accent_sat, 0.65); + constexpr uint32_t accent_color_5 = hsl_to_rgb(accent_hue, accent_sat, 0.78); + constexpr uint32_t accent_color_6 = hsl_to_rgb(accent_hue, accent_sat, 0.91); // Lightest + #endif + + // Shades of gray + + constexpr float gray_sat = 0.14; + constexpr uint32_t gray_color_0 = hsl_to_rgb(accent_hue, gray_sat, 0.15); // Darkest + constexpr uint32_t gray_color_1 = hsl_to_rgb(accent_hue, gray_sat, 0.26); + constexpr uint32_t gray_color_2 = hsl_to_rgb(accent_hue, gray_sat, 0.39); + constexpr uint32_t gray_color_3 = hsl_to_rgb(accent_hue, gray_sat, 0.52); + constexpr uint32_t gray_color_4 = hsl_to_rgb(accent_hue, gray_sat, 0.65); + constexpr uint32_t gray_color_5 = hsl_to_rgb(accent_hue, gray_sat, 0.78); + constexpr uint32_t gray_color_6 = hsl_to_rgb(accent_hue, gray_sat, 0.91); // Lightest + + #if ENABLED(TOUCH_UI_ROYAL_THEME) + constexpr uint32_t theme_darkest = accent_color_1; + constexpr uint32_t theme_dark = accent_color_4; + + constexpr uint32_t bg_color = gray_color_0; + constexpr uint32_t axis_label = gray_color_1; + + constexpr uint32_t bg_text_enabled = accent_color_6; + constexpr uint32_t bg_text_disabled = gray_color_0; + constexpr uint32_t bg_normal = accent_color_4; + constexpr uint32_t fg_disabled = gray_color_0; + constexpr uint32_t fg_normal = accent_color_0; + constexpr uint32_t fg_action = accent_color_1; + + constexpr uint32_t logo_bg_rgb = accent_color_1; + constexpr uint32_t logo_fill_rgb = accent_color_0; + constexpr uint32_t logo_stroke_rgb = accent_color_4; + #elif ANY(TOUCH_UI_COCOA_THEME, TOUCH_UI_FROZEN_THEME) + constexpr uint32_t theme_darkest = accent_color_1; + constexpr uint32_t theme_dark = accent_color_4; + + constexpr uint32_t bg_color = 0xFFFFFF; + constexpr uint32_t axis_label = gray_color_5; + + constexpr uint32_t bg_text_enabled = accent_color_1; + constexpr uint32_t bg_text_disabled = gray_color_1; + constexpr uint32_t bg_normal = accent_color_4; + constexpr uint32_t fg_disabled = gray_color_6; + constexpr uint32_t fg_normal = accent_color_1; + constexpr uint32_t fg_action = accent_color_4; + + constexpr uint32_t logo_bg_rgb = accent_color_5; + constexpr uint32_t logo_fill_rgb = accent_color_6; + constexpr uint32_t logo_stroke_rgb = accent_color_2; + #else + constexpr uint32_t theme_darkest = gray_color_1; + constexpr uint32_t theme_dark = gray_color_2; + + constexpr uint32_t bg_color = gray_color_1; + constexpr uint32_t axis_label = gray_color_2; + + constexpr uint32_t bg_text_enabled = 0xFFFFFF; + constexpr uint32_t bg_text_disabled = gray_color_2; + constexpr uint32_t bg_normal = gray_color_1; + constexpr uint32_t fg_disabled = gray_color_1; + constexpr uint32_t fg_normal = gray_color_2; + constexpr uint32_t fg_action = accent_color_2; + + constexpr uint32_t logo_bg_rgb = accent_color_4; + constexpr uint32_t logo_fill_rgb = accent_color_3; + constexpr uint32_t logo_stroke_rgb = 0x000000; + #endif + + constexpr uint32_t shadow_rgb = gray_color_6; + constexpr uint32_t stroke_rgb = accent_color_1; + constexpr uint32_t fill_rgb = accent_color_3; + #if ENABLED(TOUCH_UI_COCOA_PRESS) + constexpr uint32_t syringe_rgb = 0xFFFFFF; + constexpr uint32_t fluid_rgb = accent_color_5; + #else + constexpr uint32_t syringe_rgb = accent_color_5; + constexpr uint32_t fluid_rgb = accent_color_3; + #endif + + #if ENABLED(TOUCH_UI_ROYAL_THEME) + constexpr uint32_t x_axis = hsl_to_rgb(0, 1.00, 0.26); + constexpr uint32_t y_axis = hsl_to_rgb(120, 1.00, 0.13); + constexpr uint32_t z_axis = hsl_to_rgb(240, 1.00, 0.10); + #else + constexpr uint32_t x_axis = hsl_to_rgb(0, 1.00, 0.5); + constexpr uint32_t y_axis = hsl_to_rgb(120, 1.00, 0.37); + constexpr uint32_t z_axis = hsl_to_rgb(240, 1.00, 0.37); + #endif + constexpr uint32_t e_axis = axis_label; + constexpr uint32_t feedrate = axis_label; + constexpr uint32_t other = axis_label; + + // Status screen + constexpr uint32_t progress = axis_label; + constexpr uint32_t status_msg = axis_label; + #if ENABLED(TOUCH_UI_ROYAL_THEME) + constexpr uint32_t fan_speed = hsl_to_rgb(240, 0.5, 0.13); + constexpr uint32_t temp = hsl_to_rgb(343, 1.0, 0.23); + #else + constexpr uint32_t fan_speed = hsl_to_rgb(204, 0.47, 0.41); + constexpr uint32_t temp = hsl_to_rgb(311, 0.51, 0.35); + #endif + + constexpr uint32_t disabled_icon = gray_color_1; + + // Calibration Registers Screen + constexpr uint32_t transformA = 0x3010D0; + constexpr uint32_t transformB = 0x4010D0; + constexpr uint32_t transformC = 0x5010D0; + constexpr uint32_t transformD = 0x6010D0; + constexpr uint32_t transformE = 0x7010D0; + constexpr uint32_t transformF = 0x8010D0; + constexpr uint32_t transformVal = 0x104010; + + constexpr btn_colors disabled_btn = {.bg = bg_color, .grad = fg_disabled, .fg = fg_disabled, .rgb = fg_disabled }; + constexpr btn_colors normal_btn = {.bg = fg_action, .grad = 0xFFFFFF, .fg = fg_normal, .rgb = 0xFFFFFF }; + constexpr btn_colors action_btn = {.bg = bg_color, .grad = 0xFFFFFF, .fg = fg_action, .rgb = 0xFFFFFF }; + constexpr btn_colors red_btn = {.bg = 0xFF5555, .grad = 0xFFFFFF, .fg = 0xFF0000, .rgb = 0xFFFFFF }; + constexpr btn_colors ui_slider = {.bg = theme_darkest, .grad = 0xFFFFFF, .fg = theme_dark, .rgb = accent_color_3 }; + constexpr btn_colors ui_toggle = {.bg = theme_darkest, .grad = 0xFFFFFF, .fg = theme_dark, .rgb = 0xFFFFFF }; + + // Temperature color scale + + const rgb_t cool_rgb ( 0, 0, 0); + const rgb_t low_rgb (128, 0, 0); + const rgb_t med_rgb (255, 128, 0); + const rgb_t high_rgb (255, 255, 128); +}; diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/fonts.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/fonts.h similarity index 97% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/fonts.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/fonts.h index 3e5a985cc3b2..63115b418730 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/fonts.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/fonts.h @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/marlin_bootscreen_landscape.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/marlin_bootscreen_landscape.h similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/marlin_bootscreen_landscape.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/marlin_bootscreen_landscape.h index 5e01f0471c6b..eb9cadeba1e4 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/marlin_bootscreen_landscape.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/marlin_bootscreen_landscape.h @@ -11,7 +11,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ /** @@ -35,5 +35,5 @@ const PROGMEM uint16_t logo_stroke[] = {0xADF3, 0x546C, 0x419D, 0x546F, 0x3D05, #define LOGO_BACKGROUND logo_bg_rgb #define LOGO_PAINT_PATHS \ - LOGO_PAINT_PATH(logo_stroke_rgb, logo_stroke) \ - LOGO_PAINT_PATH(logo_fill_rgb, logo_fill) + LOGO_PAINT_PATH(logo_fill_rgb, logo_fill) \ + LOGO_PAINT_PATH(logo_stroke_rgb, logo_stroke) diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/marlin_bootscreen_portrait.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/marlin_bootscreen_portrait.h similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/marlin_bootscreen_portrait.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/marlin_bootscreen_portrait.h index a5af7a14cd9c..dd5088e0ce2b 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/marlin_bootscreen_portrait.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/marlin_bootscreen_portrait.h @@ -11,7 +11,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ /** @@ -35,5 +35,5 @@ const PROGMEM uint16_t logo_stroke[] = {0x3C19, 0x70C5, 0x371A, 0x7159, 0x3302, #define LOGO_BACKGROUND logo_bg_rgb #define LOGO_PAINT_PATHS \ - LOGO_PAINT_PATH(logo_stroke_rgb, logo_stroke) \ - LOGO_PAINT_PATH(logo_fill_rgb, logo_fill) + LOGO_PAINT_PATH(logo_fill_rgb, logo_fill) \ + LOGO_PAINT_PATH(logo_stroke_rgb, logo_stroke) diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/sounds.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/sounds.cpp similarity index 99% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/sounds.cpp rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/sounds.cpp index e08373390f8d..f4a80bcc09fd 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/sounds.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/sounds.cpp @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../compat.h" diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/sounds.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/sounds.h similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/sounds.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/sounds.h index c728d0012f2d..b2b889038650 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/sounds.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/sounds.h @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/theme.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/theme.h similarity index 94% rename from Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/theme.h rename to Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/theme.h index 6a73a07163c7..df7782ce87dd 100644 --- a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/theme/theme.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/theme/theme.h @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once diff --git a/Marlin/src/lcd/extui/lib/mks_ui/SPIFlashStorage.cpp b/Marlin/src/lcd/extui/lib/mks_ui/SPIFlashStorage.cpp new file mode 100644 index 000000000000..3f5712445138 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/SPIFlashStorage.cpp @@ -0,0 +1,320 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "../../../../inc/MarlinConfig.h" +#include "SPIFlashStorage.h" + +extern W25QXXFlash W25QXX; + +uint8_t SPIFlashStorage::m_pageData[SPI_FLASH_PageSize]; +uint32_t SPIFlashStorage::m_currentPage; +uint16_t SPIFlashStorage::m_pageDataUsed; +uint32_t SPIFlashStorage::m_startAddress; + +#if HAS_SPI_FLASH_COMPRESSION + + uint8_t SPIFlashStorage::m_compressedData[SPI_FLASH_PageSize]; + uint16_t SPIFlashStorage::m_compressedDataUsed; + + template + static uint32_t rle_compress(T *output, uint32_t outputLength, T *input, uint32_t inputLength, uint32_t& inputProcessed) { + uint32_t count = 0, out = 0, index, i; + T pixel; + //32767 for uint16_t + //127 for uint16_t + //calculated at compile time + constexpr T max = (0xFFFFFFFF >> (8 * (4 - sizeof(T)))) / 2; + + inputProcessed = 0; + while (count < inputLength && out < outputLength) { + index = count; + pixel = input[index++]; + while (index < inputLength && index - count < max && input[index] == pixel) + index++; + if (index - count == 1) { + /* + * Failed to "replicate" the current pixel. See how many to copy. + * Avoid a replicate run of only 2-pixels after a literal run. There + * is no gain in this, and there is a risK of loss if the run after + * the two identical pixels is another literal run. So search for + * 3 identical pixels. + */ + while (index < inputLength && index - count < max && (input[index] != input[index - 1] || (index > 1 && input[index] != input[index - 2]))) + index++; + /* + * Check why this run stopped. If it found two identical pixels, reset + * the index so we can add a run. Do this twice: the previous run + * tried to detect a replicate run of at least 3 pixels. So we may be + * able to back up two pixels if such a replicate run was found. + */ + while (index < inputLength && input[index] == input[index - 1]) + index--; + // If the output buffer could overflow, stop at the remaining bytes + NOMORE(index, count + outputLength - out - 1); + output[out++] = (uint16_t)(count - index); + for (i = count; i < index; i++) + output[out++] = input[i]; + } + else { + // Need at least more 2 spaces + if (out > outputLength - 2) break; + output[out++] = (uint16_t)(index - count); + output[out++] = pixel; + } + count = index; + } + inputProcessed = count; + + // Padding + if (out == outputLength - 1) output[out++] = 0; + + return out; + } + + template + static uint32_t rle_uncompress(UT *output, uint32_t outputLength, UT *input, uint32_t inputLength, uint32_t &outputFilled) { + T count; + UT i; + uint32_t processedBytes = 0; + outputFilled = 0; + + while (outputLength > 0 && inputLength > 0) { + processedBytes++; + count = static_cast(*input++); + inputLength--; + if (count > 0) { // Replicate run + for (i = 0; i < count && outputLength > i; i++) + output[i] = *input; + outputFilled += i; + // If copy incomplete, change the input buffer to start with remaining data in the next call + if (i < count) { + // Change to process the difference in the next call + *(input - 1) = static_cast(count - i); + return processedBytes - 1; + } + input++; + inputLength--; + processedBytes++; + } + else if (count < 0) { // literal run + count = static_cast(-count); + // Copy, validating if the output have enough space + for (i = 0; i < count && outputLength > i; i++) + output[i] = input[i]; + outputFilled += i; + // If copy incomplete, change the input buffer to start with remaining data in the next call + if (i < count) { + input[i - 1] = static_cast((count - i) * -1); + // Back one + return processedBytes + i - 1; + } + input += count; + inputLength -= count; + processedBytes += count; + } + output += count; + outputLength -= count; + } + + return processedBytes; + } + +#endif // HAS_SPI_FLASH_COMPRESSION + +void SPIFlashStorage::beginWrite(uint32_t startAddress) { + m_pageDataUsed = 0; + m_currentPage = 0; + m_startAddress = startAddress; + #if HAS_SPI_FLASH_COMPRESSION + // Restart the compressed buffer, keep the pointers of the uncompressed buffer + m_compressedDataUsed = 0; + #endif +} + + +void SPIFlashStorage::endWrite() { + // Flush remaining data + #if HAS_SPI_FLASH_COMPRESSION + if (m_compressedDataUsed > 0) { + flushPage(); + savePage(m_compressedData); + } + #else + if (m_pageDataUsed > 0) flushPage(); + #endif +} + +void SPIFlashStorage::savePage(uint8_t* buffer) { + W25QXX.SPI_FLASH_BufferWrite(buffer, m_startAddress + (SPI_FLASH_PageSize * m_currentPage), SPI_FLASH_PageSize); + + // Test env + // char fname[256]; + // snprintf(fname, sizeof(fname), "./pages/page-%03d.data", m_currentPage); + // FILE *fp = fopen(fname, "wb"); + // fwrite(buffer, 1, m_compressedDataUsed, fp); + // fclose(fp); +} + +void SPIFlashStorage::loadPage(uint8_t* buffer) { + W25QXX.SPI_FLASH_BufferRead(buffer, m_startAddress + (SPI_FLASH_PageSize * m_currentPage), SPI_FLASH_PageSize); + + // Test env + // char fname[256]; + // memset(buffer, 0, SPI_FLASH_PageSize); + // snprintf(fname, sizeof(fname), "./pages/page-%03d.data", m_currentPage); + // FILE *fp = fopen(fname, "rb"); + // if (fp != NULL) { + // fread(buffer, 1, SPI_FLASH_PageSize, fp); + // fclose(fp); + // } +} + +void SPIFlashStorage::flushPage() { + #if HAS_SPI_FLASH_COMPRESSION + // Work com with compressed in memory + uint32_t inputProcessed; + uint32_t compressedSize = rle_compress((uint16_t *)(m_compressedData + m_compressedDataUsed), compressedDataFree() / 2, (uint16_t *)m_pageData, m_pageDataUsed / 2, inputProcessed) * 2; + inputProcessed *= 2; + m_compressedDataUsed += compressedSize; + + // Space remaining in the compressed buffer? + if (compressedDataFree() > 0) { + // Free the uncompressed buffer + m_pageDataUsed = 0; + return; + } + + // Part of the m_pageData was compressed, so ajust the pointers, freeing what was processed, shift the buffer + // TODO: To avoid this copy, use a circular buffer + memmove(m_pageData, m_pageData + inputProcessed, m_pageDataUsed - inputProcessed); + m_pageDataUsed -= inputProcessed; + + // No? So flush page with compressed data!! + uint8_t *buffer = m_compressedData; + #else + uint8_t *buffer = m_pageData; + #endif + + savePage(buffer); + + #if HAS_SPI_FLASH_COMPRESSION + // Restart the compressed buffer, keep the pointers of the uncompressed buffer + m_compressedDataUsed = 0; + #else + m_pageDataUsed = 0; + #endif + m_currentPage++; +} + +void SPIFlashStorage::readPage() { + #if HAS_SPI_FLASH_COMPRESSION + if (compressedDataFree() == 0) { + loadPage(m_compressedData); + m_currentPage++; + m_compressedDataUsed = 0; + } + + // Need to uncompress data + if (pageDataFree() == 0) { + m_pageDataUsed = 0; + uint32_t outpuProcessed = 0; + uint32_t inputProcessed = rle_uncompress((uint16_t *)(m_pageData + m_pageDataUsed), pageDataFree() / 2, (uint16_t *)(m_compressedData + m_compressedDataUsed), compressedDataFree() / 2, outpuProcessed); + inputProcessed *= 2; + outpuProcessed *= 2; + if (outpuProcessed < pageDataFree()) { + m_pageDataUsed = SPI_FLASH_PageSize - outpuProcessed; + // TODO: To avoid this copy, use a circular buffer + memmove(m_pageData + m_pageDataUsed, m_pageData, outpuProcessed); + } + + m_compressedDataUsed += inputProcessed; + } + #else + loadPage(m_pageData); + m_pageDataUsed = 0; + m_currentPage++; + #endif +} + +uint16_t SPIFlashStorage::inData(uint8_t* data, uint16_t size) { + // Don't write more than we can + NOMORE(size, pageDataFree()); + memcpy(m_pageData + m_pageDataUsed, data, size); + m_pageDataUsed += size; + return size; +} + +void SPIFlashStorage::writeData(uint8_t* data, uint16_t size) { + // Flush a page if needed + if (pageDataFree() == 0) flushPage(); + + while (size > 0) { + uint16_t written = inData(data, size); + size -= written; + // Need to write more? Flush page and continue! + if (size > 0) { + flushPage(); + data += written; + } + } +} + +void SPIFlashStorage::beginRead(uint32_t startAddress) { + m_startAddress = startAddress; + m_currentPage = 0; + // Nothing in memory now + m_pageDataUsed = SPI_FLASH_PageSize; + #if HAS_SPI_FLASH_COMPRESSION + m_compressedDataUsed = sizeof(m_compressedData); + #endif +} + +uint16_t SPIFlashStorage::outData(uint8_t* data, uint16_t size) { + // Don't read more than we have + NOMORE(size, pageDataFree()); + memcpy(data, m_pageData + m_pageDataUsed, size); + m_pageDataUsed += size; + return size; +} + +void SPIFlashStorage::readData(uint8_t* data, uint16_t size) { + // Read a page if needed + if (pageDataFree() == 0) readPage(); + + while (size > 0) { + uint16_t read = outData(data, size); + size -= read; + // Need to write more? Flush page and continue! + if (size > 0) { + readPage(); + data += read; + } + } +} + +SPIFlashStorage SPIFlash; + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/SPIFlashStorage.h b/Marlin/src/lcd/extui/lib/mks_ui/SPIFlashStorage.h new file mode 100644 index 000000000000..98c8067bd3c2 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/SPIFlashStorage.h @@ -0,0 +1,108 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../../../../libs/W25Qxx.h" + +#define HAS_SPI_FLASH_COMPRESSION 1 + +/** + * This class manages and optimizes SPI Flash data storage, + * keeping an internal buffer to write and save full SPI flash + * pages as needed. + * + * Since the data is always in the buffer, the class is also + * able to support fast on-the-fly RLE compression/decompression. + * + * In testing with the current LVGL_UI it compacts 2.9MB of icons + * (which have lots of runs) down to 370kB!!! As a result the UI + * refresh rate becomes faster and now all LVGL UI can fit into a + * tiny 2MB SPI Flash, such as the Chitu Board. + * + * == Usage == + * + * Writing: + * + * The class keeps an internal buffer that caches data until it + * fits into a full SPI Flash page. Each time the buffer fills up + * the page is saved to SPI Flash. Sequential writes are optimal. + * + * SPIFlashStorage.beginWrite(myStartAddress); + * while (there is data to write) + * SPIFlashStorage.addData(myBuffer, bufferSize); + * SPIFlashStorage.endWrite(); // Flush remaining buffer data + * + * Reading: + * + * When reading, it loads a full page from SPI Flash at once and + * keeps it in a private SRAM buffer. Data is loaded as needed to + * fullfill requests. Sequential reads are optimal. + * + * SPIFlashStorage.beginRead(myStartAddress); + * while (there is data to read) + * SPIFlashStorage.readData(myBuffer, bufferSize); + * + * Compression: + * + * The biggest advantage of this class is the RLE compression. + * With compression activated a second buffer holds the compressed + * data, so when writing data, as this buffer becomes full it is + * flushed to SPI Flash. + * + * The same goes for reading: A compressed page is read from SPI + * flash, and the data is uncompressed as needed to provide the + * requested amount of data. + */ +class SPIFlashStorage { +public: + // Write operation + static void beginWrite(uint32_t startAddress); + static void endWrite(); + static void writeData(uint8_t* data, uint16_t size); + + // Read operation + static void beginRead(uint32_t startAddress); + static void readData(uint8_t* data, uint16_t size); + + static uint32_t getCurrentPage() { return m_currentPage; } + +private: + static void flushPage(); + static void savePage(uint8_t* buffer); + static void loadPage(uint8_t* buffer); + static void readPage(); + static uint16_t inData(uint8_t* data, uint16_t size); + static uint16_t outData(uint8_t* data, uint16_t size); + + static uint8_t m_pageData[SPI_FLASH_PageSize]; + static uint32_t m_currentPage; + static uint16_t m_pageDataUsed; + static inline uint16_t pageDataFree() { return SPI_FLASH_PageSize - m_pageDataUsed; } + static uint32_t m_startAddress; + #if HAS_SPI_FLASH_COMPRESSION + static uint8_t m_compressedData[SPI_FLASH_PageSize]; + static uint16_t m_compressedDataUsed; + static inline uint16_t compressedDataFree() { return SPI_FLASH_PageSize - m_compressedDataUsed; } + #endif +}; + +extern SPIFlashStorage SPIFlash; diff --git a/Marlin/src/lcd/extui/lib/mks_ui/SPI_TFT.cpp b/Marlin/src/lcd/extui/lib/mks_ui/SPI_TFT.cpp new file mode 100644 index 000000000000..394ce4807572 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/SPI_TFT.cpp @@ -0,0 +1,88 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "SPI_TFT.h" +#include "pic_manager.h" +#include "tft_lvgl_configuration.h" + +#include "../../../../inc/MarlinConfig.h" + +#include + +#include "draw_ui.h" + +TFT SPI_TFT; + +// use SPI1 for the spi tft. +void TFT::spi_init(uint8_t spiRate) { + tftio.Init(); +} + +void TFT::SetPoint(uint16_t x, uint16_t y, uint16_t point) { + if ((x > 480) || (y > 320)) return; + + setWindow(x, y, 1, 1); + tftio.WriteMultiple(point, (uint16_t)1); +} + +void TFT::setWindow(uint16_t x, uint16_t y, uint16_t with, uint16_t height) { + tftio.set_window(x, y, (x + with - 1), (y + height - 1)); +} + +void TFT::LCD_init() { + tftio.InitTFT(); + #if PIN_EXISTS(TFT_BACKLIGHT) + OUT_WRITE(TFT_BACKLIGHT_PIN, LOW); + #endif + delay(100); + LCD_clear(0x0000); + LCD_Draw_Logo(); + #if PIN_EXISTS(TFT_BACKLIGHT) + OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH); + #endif + #if HAS_LOGO_IN_FLASH + delay(2000); + #endif +} + +void TFT::LCD_clear(uint16_t color) { + setWindow(0, 0, (TFT_WIDTH), (TFT_HEIGHT)); + tftio.WriteMultiple(color, (uint32_t)(TFT_WIDTH) * (TFT_HEIGHT)); +} + +extern unsigned char bmp_public_buf[17 * 1024]; + +void TFT::LCD_Draw_Logo() { + #if HAS_LOGO_IN_FLASH + setWindow(0, 0, TFT_WIDTH, TFT_HEIGHT); + for (uint16_t i = 0; i < (TFT_HEIGHT); i ++) { + Pic_Logo_Read((uint8_t *)"", (uint8_t *)bmp_public_buf, (TFT_WIDTH) * 2); + tftio.WriteSequence((uint16_t *)bmp_public_buf, TFT_WIDTH); + } + #endif +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/SPI_TFT.h b/Marlin/src/lcd/extui/lib/mks_ui/SPI_TFT.h new file mode 100644 index 000000000000..696bc16974be --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/SPI_TFT.h @@ -0,0 +1,43 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "../../../tft_io/tft_io.h" + +class TFT { +public: + TFT_IO tftio; + void spi_init(uint8_t spiRate); + void SetPoint(uint16_t x, uint16_t y, uint16_t point); + void setWindow(uint16_t x, uint16_t y, uint16_t with, uint16_t height); + void LCD_init(); + void LCD_clear(uint16_t color); + void LCD_Draw_Logo(); +}; + +extern TFT SPI_TFT; + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_about.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_about.cpp new file mode 100644 index 000000000000..34b7427860ed --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_about.cpp @@ -0,0 +1,125 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" +//#include "../lvgl/src/lv_objx/lv_imgbtn.h" +//#include "../lvgl/src/lv_objx/lv_img.h" +//#include "../lvgl/src/lv_core/lv_disp.h" +//#include "../lvgl/src/lv_core/lv_refr.h" + +#include "../../../../MarlinCore.h" +#include "../../../../module/temperature.h" + +extern lv_group_t * g; +static lv_obj_t * scr; +static lv_obj_t * fw_type, *board; //*fw_version; + +#define ID_A_RETURN 1 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_A_RETURN: + if (event == LV_EVENT_CLICKED) { + // do nothing + } + else if (event == LV_EVENT_RELEASED) { + clear_cur_ui(); + draw_return_ui(); + } + break; + } +} + +void lv_draw_about(void) { + lv_obj_t *buttonBack, *label_Back; + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != ABOUT_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = ABOUT_UI; + } + disp_state = ABOUT_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, creat_title_text()); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + // Create an Image button + buttonBack = lv_imgbtn_create(scr, NULL); + + #if 1 + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_A_RETURN, NULL, 0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_return.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_return.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonBack); + #endif + #endif + + lv_obj_set_pos(buttonBack, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + + // Create a label on the image button + label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + + //fw_version = lv_label_create(scr, NULL); + //lv_obj_set_style(fw_version, &tft_style_label_rel); + //lv_label_set_text(fw_version, SHORT_BUILD_VERSION); + //lv_obj_align(fw_version, NULL, LV_ALIGN_CENTER, 0, -60); + + fw_type = lv_label_create(scr, NULL); + lv_obj_set_style(fw_type, &tft_style_label_rel); + lv_label_set_text(fw_type, "Firmware: Marlin " SHORT_BUILD_VERSION); + lv_obj_align(fw_type, NULL, LV_ALIGN_CENTER, 0, -20); + + board = lv_label_create(scr, NULL); + lv_obj_set_style(board, &tft_style_label_rel); + lv_label_set_text(board, "Board: " BOARD_INFO_NAME); + lv_obj_align(board, NULL, LV_ALIGN_CENTER, 0, -60); +} + +void lv_clear_about() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_about.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_about.h new file mode 100644 index 000000000000..2ee7ec04c61a --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_about.h @@ -0,0 +1,34 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_about(void); +extern void lv_clear_about(); + +//extern void disp_temp_ready_print(); +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_acceleration_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_acceleration_settings.cpp new file mode 100644 index 000000000000..a30c99dba07d --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_acceleration_settings.cpp @@ -0,0 +1,449 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" + +#include "../../../../MarlinCore.h" +#include "../../../../module/planner.h" + +extern lv_group_t * g; +static lv_obj_t * scr; + +#define ID_ACCE_RETURN 1 +#define ID_ACCE_PRINT 2 +#define ID_ACCE_RETRA 3 +#define ID_ACCE_TRAVEL 4 +#define ID_ACCE_X 5 +#define ID_ACCE_Y 6 +#define ID_ACCE_Z 7 +#define ID_ACCE_E0 8 +#define ID_ACCE_E1 9 +#define ID_ACCE_UP 10 +#define ID_ACCE_DOWN 11 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_ACCE_RETURN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.para_ui_page = 0; + lv_clear_acceleration_settings(); + draw_return_ui(); + } + break; + case ID_ACCE_PRINT: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = PrintAcceleration; + lv_clear_acceleration_settings(); + lv_draw_number_key(); + } + break; + case ID_ACCE_RETRA: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = RetractAcceleration; + lv_clear_acceleration_settings(); + lv_draw_number_key(); + } + break; + case ID_ACCE_TRAVEL: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = TravelAcceleration; + lv_clear_acceleration_settings(); + lv_draw_number_key(); + } + break; + case ID_ACCE_X: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = XAcceleration; + lv_clear_acceleration_settings(); + lv_draw_number_key(); + } + break; + case ID_ACCE_Y: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = YAcceleration; + lv_clear_acceleration_settings(); + lv_draw_number_key(); + } + break; + case ID_ACCE_Z: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = ZAcceleration; + lv_clear_acceleration_settings(); + lv_draw_number_key(); + } + break; + case ID_ACCE_E0: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = E0Acceleration; + lv_clear_acceleration_settings(); + lv_draw_number_key(); + } + break; + case ID_ACCE_E1: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = E1Acceleration; + lv_clear_acceleration_settings(); + lv_draw_number_key(); + } + break; + case ID_ACCE_UP: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.para_ui_page = 0; + lv_clear_acceleration_settings(); + lv_draw_acceleration_settings(); + } + break; + case ID_ACCE_DOWN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.para_ui_page = 1; + lv_clear_acceleration_settings(); + lv_draw_acceleration_settings(); + } + break; + } +} + +void lv_draw_acceleration_settings(void) { + lv_obj_t *buttonBack = NULL, *label_Back = NULL, *buttonTurnPage = NULL, *labelTurnPage = NULL; + lv_obj_t *labelPrintText = NULL, *buttonPrintValue = NULL, *labelPrintValue = NULL; + lv_obj_t *labelRetraText = NULL, *buttonRetraValue = NULL, *labelRetraValue = NULL; + lv_obj_t *labelTravelText = NULL, *buttonTravelValue = NULL, *labelTravelValue = NULL; + lv_obj_t *labelXText = NULL, *buttonXValue = NULL, *labelXValue = NULL; + lv_obj_t *labelYText = NULL, *buttonYValue = NULL, *labelYValue = NULL; + lv_obj_t *labelZText = NULL, *buttonZValue = NULL, *labelZValue = NULL; + lv_obj_t *labelE0Text = NULL, *buttonE0Value = NULL, *labelE0Value = NULL; + lv_obj_t *labelE1Text = NULL, *buttonE1Value = NULL, *labelE1Value = NULL; + lv_obj_t * line1 = NULL, * line2 = NULL, * line3 = NULL, * line4 = NULL; + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != ACCELERATION_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = ACCELERATION_UI; + } + disp_state = ACCELERATION_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, machine_menu.AccelerationConfTitle); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + if (uiCfg.para_ui_page != 1) { + + labelPrintText = lv_label_create(scr, NULL); + lv_obj_set_style(labelPrintText, &tft_style_label_rel); + lv_obj_set_pos(labelPrintText, PARA_UI_POS_X, PARA_UI_POS_Y + 10); + lv_label_set_text(labelPrintText, machine_menu.PrintAcceleration); + + buttonPrintValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonPrintValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y + PARA_UI_VALUE_V); + lv_obj_set_size(buttonPrintValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonPrintValue, event_handler, ID_ACCE_PRINT, NULL, 0); + lv_btn_set_style(buttonPrintValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonPrintValue, LV_BTN_STYLE_PR, &style_para_value); + labelPrintValue = lv_label_create(buttonPrintValue, NULL); + + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1, line_points[0]); + + labelRetraText = lv_label_create(scr, NULL); + lv_obj_set_style(labelRetraText, &tft_style_label_rel); + lv_obj_set_pos(labelRetraText, PARA_UI_POS_X, PARA_UI_POS_Y * 2 + 10); + lv_label_set_text(labelRetraText, machine_menu.RetractAcceleration); + + buttonRetraValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonRetraValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 2 + PARA_UI_VALUE_V); + lv_obj_set_size(buttonRetraValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonRetraValue, event_handler, ID_ACCE_RETRA, NULL, 0); + lv_btn_set_style(buttonRetraValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonRetraValue, LV_BTN_STYLE_PR, &style_para_value); + labelRetraValue = lv_label_create(buttonRetraValue, NULL); + + line2 = lv_line_create(scr, NULL); + lv_ex_line(line2, line_points[1]); + + labelTravelText = lv_label_create(scr, NULL); + lv_obj_set_style(labelTravelText, &tft_style_label_rel); + lv_obj_set_pos(labelTravelText, PARA_UI_POS_X, PARA_UI_POS_Y * 3 + 10); + lv_label_set_text(labelTravelText, machine_menu.TravelAcceleration); + + buttonTravelValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonTravelValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 3 + PARA_UI_VALUE_V); + lv_obj_set_size(buttonTravelValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonTravelValue, event_handler, ID_ACCE_TRAVEL, NULL, 0); + lv_btn_set_style(buttonTravelValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonTravelValue, LV_BTN_STYLE_PR, &style_para_value); + labelTravelValue = lv_label_create(buttonTravelValue, NULL); + + line3 = lv_line_create(scr, NULL); + lv_ex_line(line3, line_points[2]); + + labelXText = lv_label_create(scr, NULL); + lv_obj_set_style(labelXText, &tft_style_label_rel); + lv_obj_set_pos(labelXText, PARA_UI_POS_X, PARA_UI_POS_Y * 4 + 10); + lv_label_set_text(labelXText, machine_menu.X_Acceleration); + + buttonXValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonXValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 4 + PARA_UI_VALUE_V); + lv_obj_set_size(buttonXValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonXValue, event_handler, ID_ACCE_X, NULL, 0); + lv_btn_set_style(buttonXValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonXValue, LV_BTN_STYLE_PR, &style_para_value); + labelXValue = lv_label_create(buttonXValue, NULL); + + line4 = lv_line_create(scr, NULL); + lv_ex_line(line4, line_points[3]); + + buttonTurnPage = lv_btn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonTurnPage, event_handler, ID_ACCE_DOWN, NULL, 0); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_REL, &style_para_back); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_PR, &style_para_back); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonPrintValue); + lv_group_add_obj(g, buttonRetraValue); + lv_group_add_obj(g, buttonTravelValue); + lv_group_add_obj(g, buttonXValue); + lv_group_add_obj(g, buttonTurnPage); + } + #endif + } + else { + labelYText = lv_label_create(scr, NULL); + lv_obj_set_style(labelYText, &tft_style_label_rel); + lv_obj_set_pos(labelYText, PARA_UI_POS_X, PARA_UI_POS_Y + 10); + lv_label_set_text(labelYText, machine_menu.Y_Acceleration); + + buttonYValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonYValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y + PARA_UI_VALUE_V); + lv_obj_set_size(buttonYValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonYValue, event_handler, ID_ACCE_Y, NULL, 0); + lv_btn_set_style(buttonYValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonYValue, LV_BTN_STYLE_PR, &style_para_value); + labelYValue = lv_label_create(buttonYValue, NULL); + + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1, line_points[0]); + + labelZText = lv_label_create(scr, NULL); + lv_obj_set_style(labelZText, &tft_style_label_rel); + lv_obj_set_pos(labelZText, PARA_UI_POS_X, PARA_UI_POS_Y * 2 + 10); + lv_label_set_text(labelZText, machine_menu.Z_Acceleration); + + buttonZValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonZValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 2 + PARA_UI_VALUE_V); + lv_obj_set_size(buttonZValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); lv_obj_set_event_cb_mks(buttonYValue, event_handler, ID_ACCE_Y, NULL, 0); + lv_obj_set_event_cb_mks(buttonZValue, event_handler, ID_ACCE_Z, NULL, 0); + lv_btn_set_style(buttonZValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonZValue, LV_BTN_STYLE_PR, &style_para_value); + labelZValue = lv_label_create(buttonZValue, NULL); + + + line2 = lv_line_create(scr, NULL); + lv_ex_line(line2, line_points[1]); + + labelE0Text = lv_label_create(scr, NULL); + lv_obj_set_style(labelE0Text, &tft_style_label_rel); + lv_obj_set_pos(labelE0Text, PARA_UI_POS_X, PARA_UI_POS_Y * 3 + 10); + lv_label_set_text(labelE0Text, machine_menu.E0_Acceleration); + + buttonE0Value = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonE0Value, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 3 + PARA_UI_VALUE_V); + lv_obj_set_size(buttonE0Value, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); lv_obj_set_event_cb_mks(buttonYValue, event_handler, ID_ACCE_Y, NULL, 0); + lv_obj_set_event_cb_mks(buttonE0Value, event_handler, ID_ACCE_E0, NULL, 0); + lv_btn_set_style(buttonE0Value, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonE0Value, LV_BTN_STYLE_PR, &style_para_value); + labelE0Value = lv_label_create(buttonE0Value, NULL); + + + line3 = lv_line_create(scr, NULL); + lv_ex_line(line3, line_points[2]); + + labelE1Text = lv_label_create(scr, NULL); + lv_obj_set_style(labelE1Text, &tft_style_label_rel); + lv_obj_set_pos(labelE1Text, PARA_UI_POS_X, PARA_UI_POS_Y * 4 + 10); + lv_label_set_text(labelE1Text, machine_menu.E1_Acceleration); + + buttonE1Value = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonE1Value, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 4 + PARA_UI_VALUE_V); + lv_obj_set_size(buttonE1Value, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); lv_obj_set_event_cb_mks(buttonYValue, event_handler, ID_ACCE_Y, NULL, 0); + lv_obj_set_event_cb_mks(buttonE1Value, event_handler, ID_ACCE_E1, NULL, 0); + lv_btn_set_style(buttonE1Value, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonE1Value, LV_BTN_STYLE_PR, &style_para_value); + labelE1Value = lv_label_create(buttonE1Value, NULL); + + + line4 = lv_line_create(scr, NULL); + lv_ex_line(line4, line_points[3]); + + buttonTurnPage = lv_btn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonTurnPage, event_handler, ID_ACCE_UP, NULL, 0); + //lv_imgbtn_set_src(buttonTurnPage, LV_BTN_STATE_REL, "F:/bmp_back70x40.bin"); + //lv_imgbtn_set_src(buttonTurnPage, LV_BTN_STATE_PR, "F:/bmp_back70x40.bin"); + //lv_imgbtn_set_style(buttonTurnPage, LV_BTN_STATE_PR, &tft_style_label_pre); + //lv_imgbtn_set_style(buttonTurnPage, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_REL, &style_para_back); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_PR, &style_para_back); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonYValue); + lv_group_add_obj(g, buttonZValue); + lv_group_add_obj(g, buttonE0Value); + lv_group_add_obj(g, buttonE1Value); + lv_group_add_obj(g, buttonTurnPage); + } + #endif + } + + //lv_obj_set_pos(buttonTurnPage, PARA_UI_TURN_PAGE_POS_X, PARA_UI_TURN_PAGE_POS_Y); + //lv_btn_set_layout(buttonTurnPage, LV_LAYOUT_OFF); + //labelTurnPage = lv_label_create(buttonTurnPage, NULL); + lv_obj_set_pos(buttonTurnPage, PARA_UI_TURN_PAGE_POS_X, PARA_UI_TURN_PAGE_POS_Y); + lv_obj_set_size(buttonTurnPage, PARA_UI_BACK_BTN_X_SIZE, PARA_UI_BACK_BTN_Y_SIZE); + labelTurnPage = lv_label_create(buttonTurnPage, NULL); + + buttonBack = lv_btn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_ACCE_RETURN, NULL, 0); + //lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_back70x40.bin"); + //lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_back70x40.bin"); + //lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + //lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_style(buttonBack, LV_BTN_STYLE_REL, &style_para_back); + lv_btn_set_style(buttonBack, LV_BTN_STYLE_PR, &style_para_back); + lv_obj_set_pos(buttonBack, PARA_UI_BACL_POS_X, PARA_UI_BACL_POS_Y); + lv_obj_set_size(buttonBack, PARA_UI_BACK_BTN_X_SIZE, PARA_UI_BACK_BTN_Y_SIZE); + label_Back = lv_label_create(buttonBack, NULL); + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonBack); + #endif + + //lv_obj_set_pos(buttonBack, PARA_UI_BACL_POS_X, PARA_UI_BACL_POS_Y); + //lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + + if (gCfgItems.multiple_language != 0) { + if (uiCfg.para_ui_page != 1) { + + lv_label_set_text(labelTurnPage, machine_menu.next); + lv_obj_align(labelTurnPage, buttonTurnPage, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), planner.settings.acceleration); + lv_label_set_text(labelPrintValue, public_buf_l); + lv_obj_align(labelPrintValue, buttonPrintValue, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), planner.settings.retract_acceleration); + lv_label_set_text(labelRetraValue, public_buf_l); + lv_obj_align(labelRetraValue, buttonRetraValue, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), planner.settings.travel_acceleration); + lv_label_set_text(labelTravelValue, public_buf_l); + lv_obj_align(labelTravelValue, buttonTravelValue, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[X_AXIS]); + lv_label_set_text(labelXValue, public_buf_l); + lv_obj_align(labelXValue, buttonXValue, LV_ALIGN_CENTER, 0, 0); + } + else { + + lv_label_set_text(labelTurnPage, machine_menu.previous); + lv_obj_align(labelTurnPage, buttonTurnPage, LV_ALIGN_CENTER, 0, 0); + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[Y_AXIS]); + lv_label_set_text(labelYValue, public_buf_l); + lv_obj_align(labelYValue, buttonYValue, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[Z_AXIS]); + lv_label_set_text(labelZValue, public_buf_l); + lv_obj_align(labelZValue, buttonZValue, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[E_AXIS]); + lv_label_set_text(labelE0Value, public_buf_l); + lv_obj_align(labelE0Value, buttonE0Value, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(1)]); + lv_label_set_text(labelE1Value, public_buf_l); + lv_obj_align(labelE1Value, buttonE1Value, LV_ALIGN_CENTER, 0, 0); + } + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_CENTER, 0, 0); + } +} + +void lv_clear_acceleration_settings() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_acceleration_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_acceleration_settings.h new file mode 100644 index 000000000000..6ab49713c9dd --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_acceleration_settings.h @@ -0,0 +1,33 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_acceleration_settings(void); +extern void lv_clear_acceleration_settings(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_advance_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_advance_settings.cpp new file mode 100644 index 000000000000..5b1b24171697 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_advance_settings.cpp @@ -0,0 +1,334 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" + +#include "../../../../MarlinCore.h" + +extern lv_group_t * g; +static lv_obj_t * scr; + +#define ID_ADVANCE_RETURN 1 +#define ID_PAUSE_POS 2 +#define ID_PAUSE_POS_ARROW 3 +#define ID_WIFI_PARA 4 +#define ID_WIFI_PARA_ARROW 5 +#define ID_FILAMENT_SETTINGS 6 +#define ID_FILAMENT_SETTINGS_ARROW 7 +#define ID_ENCODER_SETTINGS 8 +#define ID_ENCODER_SETTINGS_ARROW 9 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_ADVANCE_RETURN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_advance_settings(); + draw_return_ui(); + } + break; + case ID_PAUSE_POS: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_advance_settings(); + lv_draw_pause_position(); + } + break; + case ID_PAUSE_POS_ARROW: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_advance_settings(); + lv_draw_pause_position(); + } + break; + case ID_FILAMENT_SETTINGS: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_advance_settings(); + lv_draw_filament_settings(); + } + break; + case ID_FILAMENT_SETTINGS_ARROW: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_advance_settings(); + lv_draw_filament_settings(); + } + break; + #if ENABLED(USE_WIFI_FUNCTION) + case ID_WIFI_PARA: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_advance_settings(); + lv_draw_wifi_settings(); + } + break; + case ID_WIFI_PARA_ARROW: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_advance_settings(); + lv_draw_wifi_settings(); + } + break; + #endif + #if HAS_ROTARY_ENCODER + case ID_ENCODER_SETTINGS: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_advance_settings(); + lv_draw_encoder_settings(); + } + break; + case ID_ENCODER_SETTINGS_ARROW: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_advance_settings(); + lv_draw_encoder_settings(); + } + break; + #endif + } +} + +void lv_draw_advance_settings(void) { + lv_obj_t *buttonBack, *label_Back; + lv_obj_t *buttonPausePos, *labelPausePos, *buttonPausePosNarrow; + lv_obj_t *buttonFilamentSettings, *labelFilamentSettings, *buttonFilamentSettingsNarrow; + lv_obj_t * line1,* line2; + #if ENABLED(USE_WIFI_FUNCTION) + lv_obj_t *buttonWifiSet,*labelWifiSet,*buttonWifiSetNarrow; + #endif + #if HAS_ROTARY_ENCODER + lv_obj_t *buttonEcoder,*labelEcoder,*buttonEcoderNarrow; + #endif + + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != ADVANCED_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = ADVANCED_UI; + } + disp_state = ADVANCED_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, machine_menu.AdvancedConfTitle); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + buttonPausePos = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonPausePos, PARA_UI_POS_X, PARA_UI_POS_Y); + lv_obj_set_size(buttonPausePos, PARA_UI_SIZE_X, PARA_UI_SIZE_Y); + //lv_obj_set_event_cb(buttonMachine, event_handler); + lv_obj_set_event_cb_mks(buttonPausePos, event_handler, ID_PAUSE_POS, NULL, 0); + lv_btn_set_style(buttonPausePos, LV_BTN_STYLE_REL, &tft_style_label_rel); + lv_btn_set_style(buttonPausePos, LV_BTN_STYLE_PR, &tft_style_label_pre); + lv_btn_set_layout(buttonPausePos, LV_LAYOUT_OFF); + labelPausePos = lv_label_create(buttonPausePos, NULL); + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonPausePos); + #endif + + buttonPausePosNarrow = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonPausePosNarrow, PARA_UI_POS_X + PARA_UI_SIZE_X, PARA_UI_POS_Y + PARA_UI_ARROW_V); + lv_obj_set_event_cb_mks(buttonPausePosNarrow, event_handler, ID_PAUSE_POS_ARROW, NULL, 0); + lv_imgbtn_set_src(buttonPausePosNarrow, LV_BTN_STATE_REL, "F:/bmp_arrow.bin"); + lv_imgbtn_set_src(buttonPausePosNarrow, LV_BTN_STATE_PR, "F:/bmp_arrow.bin"); + lv_imgbtn_set_style(buttonPausePosNarrow, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonPausePosNarrow, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonPausePosNarrow, LV_LAYOUT_OFF); + + line1 = lv_line_create(lv_scr_act(), NULL); + lv_ex_line(line1, line_points[0]); + + buttonFilamentSettings = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonFilamentSettings, PARA_UI_POS_X, PARA_UI_POS_Y*2); + lv_obj_set_size(buttonFilamentSettings, PARA_UI_SIZE_X, PARA_UI_SIZE_Y); + lv_obj_set_event_cb_mks(buttonFilamentSettings, event_handler, ID_FILAMENT_SETTINGS, NULL, 0); + lv_btn_set_style(buttonFilamentSettings, LV_BTN_STYLE_REL, &tft_style_label_rel); + lv_btn_set_style(buttonFilamentSettings, LV_BTN_STYLE_PR, &tft_style_label_pre); + lv_btn_set_layout(buttonFilamentSettings, LV_LAYOUT_OFF); + labelFilamentSettings = lv_label_create(buttonFilamentSettings, NULL); + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonFilamentSettings); + #endif + + buttonFilamentSettingsNarrow = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonFilamentSettingsNarrow, PARA_UI_POS_X + PARA_UI_SIZE_X, PARA_UI_POS_Y*2 + PARA_UI_ARROW_V); + lv_obj_set_event_cb_mks(buttonFilamentSettingsNarrow, event_handler, ID_FILAMENT_SETTINGS_ARROW, NULL, 0); + lv_imgbtn_set_src(buttonFilamentSettingsNarrow, LV_BTN_STATE_REL, "F:/bmp_arrow.bin"); + lv_imgbtn_set_src(buttonFilamentSettingsNarrow, LV_BTN_STATE_PR, "F:/bmp_arrow.bin"); + lv_imgbtn_set_style(buttonFilamentSettingsNarrow, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonFilamentSettingsNarrow, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonFilamentSettingsNarrow, LV_LAYOUT_OFF); + + line2 = lv_line_create(lv_scr_act(), NULL); + lv_ex_line(line2, line_points[1]); + + #if ENABLED(USE_WIFI_FUNCTION) + + buttonWifiSet = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(buttonWifiSet, PARA_UI_POS_X,PARA_UI_POS_Y*3); + lv_obj_set_size(buttonWifiSet, PARA_UI_SIZE_X,PARA_UI_SIZE_Y); + lv_obj_set_event_cb_mks(buttonWifiSet, event_handler,ID_WIFI_PARA,NULL,0); + lv_btn_set_style(buttonWifiSet, LV_BTN_STYLE_REL, &tft_style_label_rel); + lv_btn_set_style(buttonWifiSet, LV_BTN_STYLE_PR, &tft_style_label_pre); + lv_btn_set_layout(buttonWifiSet, LV_LAYOUT_OFF); + labelWifiSet = lv_label_create(buttonWifiSet, NULL); + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonWifiSet); + #endif + + buttonWifiSetNarrow = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonWifiSetNarrow,PARA_UI_POS_X+PARA_UI_SIZE_X,PARA_UI_POS_Y*3+PARA_UI_ARROW_V); + lv_obj_set_event_cb_mks(buttonWifiSetNarrow, event_handler,ID_WIFI_PARA_ARROW, NULL,0); + lv_imgbtn_set_src(buttonWifiSetNarrow, LV_BTN_STATE_REL, "F:/bmp_arrow.bin"); + lv_imgbtn_set_src(buttonWifiSetNarrow, LV_BTN_STATE_PR, "F:/bmp_arrow.bin"); + lv_imgbtn_set_style(buttonWifiSetNarrow, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonWifiSetNarrow, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonWifiSetNarrow, LV_LAYOUT_OFF); + + lv_obj_t * line3 = lv_line_create(scr, NULL); + lv_ex_line(line3,line_points[2]); + + #if HAS_ROTARY_ENCODER + buttonEcoder = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(buttonEcoder, PARA_UI_POS_X,PARA_UI_POS_Y*4); + lv_obj_set_size(buttonEcoder, PARA_UI_SIZE_X,PARA_UI_SIZE_Y); + lv_obj_set_event_cb_mks(buttonEcoder, event_handler,ID_ENCODER_SETTINGS,NULL,0); + lv_btn_set_style(buttonEcoder, LV_BTN_STYLE_REL, &tft_style_label_rel); + lv_btn_set_style(buttonEcoder, LV_BTN_STYLE_PR, &tft_style_label_pre); + lv_btn_set_layout(buttonEcoder, LV_LAYOUT_OFF); + labelEcoder = lv_label_create(buttonEcoder, NULL); + + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonEcoder); + + buttonEcoderNarrow = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonEcoderNarrow,PARA_UI_POS_X+PARA_UI_SIZE_X,PARA_UI_POS_Y*4+PARA_UI_ARROW_V); + lv_obj_set_event_cb_mks(buttonEcoderNarrow, event_handler,ID_ENCODER_SETTINGS_ARROW, NULL,0); + lv_imgbtn_set_src(buttonEcoderNarrow, LV_BTN_STATE_REL, "F:/bmp_arrow.bin"); + lv_imgbtn_set_src(buttonEcoderNarrow, LV_BTN_STATE_PR, "F:/bmp_arrow.bin"); + lv_imgbtn_set_style(buttonEcoderNarrow, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonEcoderNarrow, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonEcoderNarrow, LV_LAYOUT_OFF); + + lv_obj_t * line4 = lv_line_create(scr, NULL); + lv_ex_line(line4,line_points[3]); + #endif + + #elif HAS_ROTARY_ENCODER + buttonEcoder = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(buttonEcoder, PARA_UI_POS_X,PARA_UI_POS_Y*3); + lv_obj_set_size(buttonEcoder, PARA_UI_SIZE_X,PARA_UI_SIZE_Y); + lv_obj_set_event_cb_mks(buttonEcoder, event_handler,ID_ENCODER_SETTINGS,NULL,0); + lv_btn_set_style(buttonEcoder, LV_BTN_STYLE_REL, &tft_style_label_rel); + lv_btn_set_style(buttonEcoder, LV_BTN_STYLE_PR, &tft_style_label_pre); + lv_btn_set_layout(buttonEcoder, LV_LAYOUT_OFF); + labelEcoder = lv_label_create(buttonEcoder, NULL); + + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonEcoder); + + buttonEcoderNarrow = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonEcoderNarrow,PARA_UI_POS_X+PARA_UI_SIZE_X,PARA_UI_POS_Y*3+PARA_UI_ARROW_V); + lv_obj_set_event_cb_mks(buttonEcoderNarrow, event_handler,ID_ENCODER_SETTINGS_ARROW, NULL,0); + lv_imgbtn_set_src(buttonEcoderNarrow, LV_BTN_STATE_REL, "F:/bmp_arrow.bin"); + lv_imgbtn_set_src(buttonEcoderNarrow, LV_BTN_STATE_PR, "F:/bmp_arrow.bin"); + lv_imgbtn_set_style(buttonEcoderNarrow, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonEcoderNarrow, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonEcoderNarrow, LV_LAYOUT_OFF); + + lv_obj_t * line3 = lv_line_create(scr, NULL); + lv_ex_line(line3,line_points[2]); + #endif + + buttonBack = lv_imgbtn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_ADVANCE_RETURN, NULL, 0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonBack); + #endif + + lv_obj_set_pos(buttonBack, PARA_UI_BACL_POS_X, PARA_UI_BACL_POS_Y); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_CENTER, 0, 0); + + lv_label_set_text(labelPausePos, machine_menu.PausePosition); + lv_obj_align(labelPausePos, buttonPausePos, LV_ALIGN_IN_LEFT_MID, 0, 0); + + lv_label_set_text(labelFilamentSettings, machine_menu.FilamentConf); + lv_obj_align(labelFilamentSettings, buttonFilamentSettings, LV_ALIGN_IN_LEFT_MID, 0, 0); + + #if ENABLED(USE_WIFI_FUNCTION) + lv_label_set_text(labelWifiSet, machine_menu.WifiSettings); + lv_obj_align(labelWifiSet, buttonWifiSet, LV_ALIGN_IN_LEFT_MID,0, 0); + #endif + #if HAS_ROTARY_ENCODER + lv_label_set_text(labelEcoder, machine_menu.EncoderSettings); + lv_obj_align(labelEcoder, buttonEcoder, LV_ALIGN_IN_LEFT_MID,0, 0); + #endif + } + +} + +void lv_clear_advance_settings() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_advance_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_advance_settings.h new file mode 100644 index 000000000000..84e4a4d4cf60 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_advance_settings.h @@ -0,0 +1,33 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_advance_settings(void); +extern void lv_clear_advance_settings(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_auto_level_offset_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_auto_level_offset_settings.cpp new file mode 100644 index 000000000000..bb6b45aebe48 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_auto_level_offset_settings.cpp @@ -0,0 +1,203 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if BOTH(HAS_TFT_LVGL_UI, HAS_BED_PROBE) + +#include "lv_conf.h" +#include "draw_ui.h" + +#include "../../../../MarlinCore.h" +#include "../../../../module/planner.h" +#include "../../../../module/probe.h" + +extern lv_group_t * g; +static lv_obj_t * scr; + +#define ID_OFFSET_RETURN 1 +#define ID_OFFSET_X 2 +#define ID_OFFSET_Y 3 +#define ID_OFFSET_Z 4 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_OFFSET_RETURN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_auto_level_offset_settings(); + draw_return_ui(); + } + break; + case ID_OFFSET_X: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = x_offset; + lv_clear_auto_level_offset_settings(); + lv_draw_number_key(); + } + break; + case ID_OFFSET_Y: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = y_offset; + lv_clear_auto_level_offset_settings(); + lv_draw_number_key(); + } + break; + case ID_OFFSET_Z: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = z_offset; + lv_clear_auto_level_offset_settings(); + lv_draw_number_key(); + } + break; + } +} + +void lv_draw_auto_level_offset_settings(void) { + lv_obj_t *buttonBack = NULL, *label_Back = NULL; + lv_obj_t *labelXText = NULL, *buttonXValue = NULL, *labelXValue = NULL; + lv_obj_t *labelYText = NULL, *buttonYValue = NULL, *labelYValue = NULL; + lv_obj_t *labelZText = NULL, *buttonZValue = NULL, *labelZValue = NULL; + lv_obj_t * line1 = NULL, * line2 = NULL, * line3 = NULL; + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != NOZZLE_PROBE_OFFSET_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = NOZZLE_PROBE_OFFSET_UI; + } + disp_state = NOZZLE_PROBE_OFFSET_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, machine_menu.OffsetConfTitle); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + labelXText = lv_label_create(scr, NULL); + lv_obj_set_style(labelXText, &tft_style_label_rel); + lv_obj_set_pos(labelXText, PARA_UI_POS_X, PARA_UI_POS_Y + 10); + lv_label_set_text(labelXText, machine_menu.Xoffset); + + buttonXValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonXValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y + PARA_UI_VALUE_V_2); + lv_obj_set_size(buttonXValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonXValue, event_handler, ID_OFFSET_X, NULL, 0); + lv_btn_set_style(buttonXValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonXValue, LV_BTN_STYLE_PR, &style_para_value); + labelXValue = lv_label_create(buttonXValue, NULL); + + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1, line_points[0]); + + labelYText = lv_label_create(scr, NULL); + lv_obj_set_style(labelYText, &tft_style_label_rel); + lv_obj_set_pos(labelYText, PARA_UI_POS_X, PARA_UI_POS_Y * 2 + 10); + lv_label_set_text(labelYText, machine_menu.Yoffset); + + buttonYValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonYValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 2 + PARA_UI_VALUE_V_2); + lv_obj_set_size(buttonYValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonYValue, event_handler, ID_OFFSET_Y, NULL, 0); + lv_btn_set_style(buttonYValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonYValue, LV_BTN_STYLE_PR, &style_para_value); + labelYValue = lv_label_create(buttonYValue, NULL); + + line2 = lv_line_create(scr, NULL); + lv_ex_line(line2, line_points[1]); + + labelZText = lv_label_create(scr, NULL); + lv_obj_set_style(labelZText, &tft_style_label_rel); + lv_obj_set_pos(labelZText, PARA_UI_POS_X, PARA_UI_POS_Y * 3 + 10); + lv_label_set_text(labelZText, machine_menu.Zoffset); + + buttonZValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonZValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 3 + PARA_UI_VALUE_V_2); + lv_obj_set_size(buttonZValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonZValue, event_handler, ID_OFFSET_Z, NULL, 0); + lv_btn_set_style(buttonZValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonZValue, LV_BTN_STYLE_PR, &style_para_value); + labelZValue = lv_label_create(buttonZValue, NULL); + + line3 = lv_line_create(scr, NULL); + lv_ex_line(line3, line_points[2]); + + buttonBack = lv_btn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_OFFSET_RETURN, NULL, 0); + lv_btn_set_style(buttonBack, LV_BTN_STYLE_REL, &style_para_back); + lv_btn_set_style(buttonBack, LV_BTN_STYLE_PR, &style_para_back); + lv_obj_set_pos(buttonBack, PARA_UI_BACL_POS_X, PARA_UI_BACL_POS_Y); + lv_obj_set_size(buttonBack, PARA_UI_BACK_BTN_X_SIZE, PARA_UI_BACK_BTN_Y_SIZE); + label_Back = lv_label_create(buttonBack, NULL); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonXValue); + lv_group_add_obj(g, buttonYValue); + lv_group_add_obj(g, buttonZValue); + lv_group_add_obj(g, buttonBack); + } + #endif + + if (gCfgItems.multiple_language != 0) { + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), TERN(HAS_PROBE_XY_OFFSET, probe.offset.x, 0)); + lv_label_set_text(labelXValue, public_buf_l); + lv_obj_align(labelXValue, buttonXValue, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), TERN(HAS_PROBE_XY_OFFSET, probe.offset.y, 0)); + lv_label_set_text(labelYValue, public_buf_l); + lv_obj_align(labelYValue, buttonYValue, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), probe.offset.z); + lv_label_set_text(labelZValue, public_buf_l); + lv_obj_align(labelZValue, buttonZValue, LV_ALIGN_CENTER, 0, 0); + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_CENTER, 0, 0); + } +} + +void lv_clear_auto_level_offset_settings() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI && HAS_BED_PROBE diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_auto_level_offset_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_auto_level_offset_settings.h new file mode 100644 index 000000000000..688cd205d04f --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_auto_level_offset_settings.h @@ -0,0 +1,33 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_auto_level_offset_settings(void); +extern void lv_clear_auto_level_offset_settings(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_baby_stepping.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_baby_stepping.cpp new file mode 100644 index 000000000000..70564c036c64 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_baby_stepping.cpp @@ -0,0 +1,352 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" + +#include "../../../../MarlinCore.h" +#include "../../../../gcode/queue.h" +#include "../../../../gcode/gcode.h" + +#if HAS_BED_PROBE + #include "../../../../module/probe.h" +#endif + +extern lv_group_t * g; +static lv_obj_t * scr; + +static lv_obj_t *labelV, *buttonV, * zOffsetText; + +#define ID_BABY_STEP_X_P 1 +#define ID_BABY_STEP_X_N 2 +#define ID_BABY_STEP_Y_P 3 +#define ID_BABY_STEP_Y_N 4 +#define ID_BABY_STEP_Z_P 5 +#define ID_BABY_STEP_Z_N 6 +#define ID_BABY_STEP_DIST 7 +#define ID_BABY_STEP_RETURN 8 + +static float babystep_dist=0.01; +static uint8_t has_adjust_z = 0; + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + char baby_buf[30]={0}; + switch (obj->mks_obj_id) { + case ID_BABY_STEP_X_P: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + ZERO(baby_buf); + sprintf_P(baby_buf, PSTR("M290 X%.3f"),babystep_dist); + gcode.process_subcommands_now_P(PSTR(baby_buf)); + has_adjust_z = 1; + } + break; + case ID_BABY_STEP_X_N: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + ZERO(baby_buf); + sprintf_P(baby_buf, PSTR("M290 X%.3f"),((float)0 - babystep_dist)); + gcode.process_subcommands_now_P(PSTR(baby_buf)); + has_adjust_z = 1; + } + break; + case ID_BABY_STEP_Y_P: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + ZERO(baby_buf); + sprintf_P(baby_buf, PSTR("M290 Y%.3f"), babystep_dist); + gcode.process_subcommands_now_P(PSTR(baby_buf)); + has_adjust_z = 1; + } + break; + case ID_BABY_STEP_Y_N: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + ZERO(baby_buf); + sprintf_P(baby_buf, PSTR("M290 Y%.3f"),((float)0 - babystep_dist)); + gcode.process_subcommands_now_P(PSTR(baby_buf)); + has_adjust_z = 1; + } + break; + case ID_BABY_STEP_Z_P: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + ZERO(baby_buf); + sprintf_P(baby_buf, PSTR("M290 Z%.3f"), babystep_dist); + gcode.process_subcommands_now_P(PSTR(baby_buf)); + has_adjust_z = 1; + } + break; + case ID_BABY_STEP_Z_N: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + ZERO(baby_buf); + sprintf_P(baby_buf, PSTR("M290 Z%.3f"),((float)0 - babystep_dist)); + gcode.process_subcommands_now_P(PSTR(baby_buf)); + has_adjust_z = 1; + } + break; + case ID_BABY_STEP_DIST: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (abs((int)(100 * babystep_dist)) == 1) + babystep_dist = 0.05; + else if (abs((int)(100 * babystep_dist)) == 5) + babystep_dist = 0.1; + else + babystep_dist = 0.01; + disp_baby_step_dist(); + } + + break; + case ID_BABY_STEP_RETURN: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (has_adjust_z == 1) { + gcode.process_subcommands_now_P(PSTR("M500")); + has_adjust_z = 0; + } + clear_cur_ui(); + draw_return_ui(); + } + break; + } +} + +void lv_draw_baby_stepping(void) { + lv_obj_t *buttonXI, *buttonXD, *buttonYI, *buttonYD, *buttonZI, *buttonZD, *buttonBack; + + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != BABY_STEP_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = BABY_STEP_UI; + } + disp_state = BABY_STEP_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, creat_title_text()); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + // Create an Image button + buttonXI = lv_imgbtn_create(scr, NULL); + buttonXD = lv_imgbtn_create(scr, NULL); + buttonYI = lv_imgbtn_create(scr, NULL); + buttonYD = lv_imgbtn_create(scr, NULL); + buttonZI = lv_imgbtn_create(scr, NULL); + buttonZD = lv_imgbtn_create(scr, NULL); + buttonV = lv_imgbtn_create(scr, NULL); + buttonBack = lv_imgbtn_create(scr, NULL); + + lv_obj_set_event_cb_mks(buttonXI, event_handler, ID_BABY_STEP_X_P, NULL, 0); + lv_imgbtn_set_src(buttonXI, LV_BTN_STATE_REL, "F:/bmp_xAdd.bin"); + lv_imgbtn_set_src(buttonXI, LV_BTN_STATE_PR, "F:/bmp_xAdd.bin"); + lv_imgbtn_set_style(buttonXI, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonXI, LV_BTN_STATE_REL, &tft_style_label_rel); + + #if 1 + lv_obj_set_event_cb_mks(buttonXD, event_handler, ID_BABY_STEP_X_N, NULL, 0); + lv_imgbtn_set_src(buttonXD, LV_BTN_STATE_REL, "F:/bmp_xDec.bin"); + lv_imgbtn_set_src(buttonXD, LV_BTN_STATE_PR, "F:/bmp_xDec.bin"); + lv_imgbtn_set_style(buttonXD, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonXD, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonYI, event_handler, ID_BABY_STEP_Y_P, NULL, 0); + lv_imgbtn_set_src(buttonYI, LV_BTN_STATE_REL, "F:/bmp_yAdd.bin"); + lv_imgbtn_set_src(buttonYI, LV_BTN_STATE_PR, "F:/bmp_yAdd.bin"); + lv_imgbtn_set_style(buttonYI, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonYI, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonYD, event_handler, ID_BABY_STEP_Y_N, NULL, 0); + lv_imgbtn_set_src(buttonYD, LV_BTN_STATE_REL, "F:/bmp_yDec.bin"); + lv_imgbtn_set_src(buttonYD, LV_BTN_STATE_PR, "F:/bmp_yDec.bin"); + lv_imgbtn_set_style(buttonYD, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonYD, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonZI, event_handler, ID_BABY_STEP_Z_P, NULL, 0); + lv_imgbtn_set_src(buttonZI, LV_BTN_STATE_REL, "F:/bmp_zAdd.bin"); + lv_imgbtn_set_src(buttonZI, LV_BTN_STATE_PR, "F:/bmp_zAdd.bin"); + lv_imgbtn_set_style(buttonZI, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonZI, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonZD, event_handler, ID_BABY_STEP_Z_N, NULL, 0); + lv_imgbtn_set_src(buttonZD, LV_BTN_STATE_REL, "F:/bmp_zDec.bin"); + lv_imgbtn_set_src(buttonZD, LV_BTN_STATE_PR, "F:/bmp_zDec.bin"); + lv_imgbtn_set_style(buttonZD, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonZD, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonV, event_handler, ID_BABY_STEP_DIST, NULL, 0); + lv_imgbtn_set_style(buttonV, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonV, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_BABY_STEP_RETURN, NULL, 0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_return.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_return.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + + #endif // if 1 + lv_obj_set_pos(buttonXI, INTERVAL_V, titleHeight); + lv_obj_set_pos(buttonYI, BTN_X_PIXEL + INTERVAL_V * 2, titleHeight); + lv_obj_set_pos(buttonZI, BTN_X_PIXEL * 2 + INTERVAL_V * 3, titleHeight); + lv_obj_set_pos(buttonV, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight); + lv_obj_set_pos(buttonXD, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonYD, BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonZD, BTN_X_PIXEL * 2 + INTERVAL_V * 3, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonBack, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + + // Create labels on the image buttons + lv_btn_set_layout(buttonXI, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonXD, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonYI, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonYD, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonZI, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonZD, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonV, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + + lv_obj_t *labelXI = lv_label_create(buttonXI, NULL); + lv_obj_t *labelXD = lv_label_create(buttonXD, NULL); + lv_obj_t *labelYI = lv_label_create(buttonYI, NULL); + lv_obj_t *labelYD = lv_label_create(buttonYD, NULL); + lv_obj_t *labelZI = lv_label_create(buttonZI, NULL); + lv_obj_t *labelZD = lv_label_create(buttonZD, NULL); + labelV = lv_label_create(buttonV, NULL); + lv_obj_t *label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(labelXI, move_menu.x_add); + lv_obj_align(labelXI, buttonXI, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelXD, move_menu.x_dec); + lv_obj_align(labelXD, buttonXD, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelYI, move_menu.y_add); + lv_obj_align(labelYI, buttonYI, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelYD, move_menu.y_dec); + lv_obj_align(labelYD, buttonYD, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelZI, move_menu.z_add); + lv_obj_align(labelZI, buttonZI, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelZD, move_menu.z_dec); + lv_obj_align(labelZD, buttonZD, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonXI); + lv_group_add_obj(g, buttonXD); + lv_group_add_obj(g, buttonYI); + lv_group_add_obj(g, buttonYD); + lv_group_add_obj(g, buttonZI); + lv_group_add_obj(g, buttonZD); + lv_group_add_obj(g, buttonV); + lv_group_add_obj(g, buttonBack); + } + #endif + + disp_baby_step_dist(); + + zOffsetText = lv_label_create(scr, NULL); + lv_obj_set_style(zOffsetText, &tft_style_label_rel); + lv_obj_set_pos(zOffsetText, 290, TITLE_YPOS); + disp_z_offset_value(); +} + +void disp_baby_step_dist() { + // char buf[30] = {0}; + + if ((int)(100 * babystep_dist) == 1) { + lv_imgbtn_set_src(buttonV, LV_BTN_STATE_REL, "F:/bmp_baby_move0_01.bin"); + lv_imgbtn_set_src(buttonV, LV_BTN_STATE_PR, "F:/bmp_baby_move0_01.bin"); + } + else if ((int)(100 * babystep_dist) == 5) { + lv_imgbtn_set_src(buttonV, LV_BTN_STATE_REL, "F:/bmp_baby_move0_05.bin"); + lv_imgbtn_set_src(buttonV, LV_BTN_STATE_PR, "F:/bmp_baby_move0_05.bin"); + } + else if ((int)(100 * babystep_dist) == 10) { + lv_imgbtn_set_src(buttonV, LV_BTN_STATE_REL, "F:/bmp_baby_move0_1.bin"); + lv_imgbtn_set_src(buttonV, LV_BTN_STATE_PR, "F:/bmp_baby_move0_1.bin"); + } + if (gCfgItems.multiple_language != 0) { + if ((int)(100 * babystep_dist) == 1) { + lv_label_set_text(labelV, move_menu.step_001mm); + lv_obj_align(labelV, buttonV, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + else if ((int)(100 * babystep_dist) == 5) { + lv_label_set_text(labelV, move_menu.step_005mm); + lv_obj_align(labelV, buttonV, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + else if ((int)(100 * babystep_dist) == 10) { + lv_label_set_text(labelV, move_menu.step_01mm); + lv_obj_align(labelV, buttonV, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + } +} + +void disp_z_offset_value() { + char buf[20]; + + ZERO(buf); + sprintf_P(buf, PSTR("offset Z: %.3f"), (double)TERN(HAS_BED_PROBE, probe.offset.z, 0)); + lv_label_set_text(zOffsetText, buf); +} + +void lv_clear_baby_stepping() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_baby_stepping.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_baby_stepping.h new file mode 100644 index 000000000000..333ba2d59717 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_baby_stepping.h @@ -0,0 +1,36 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_baby_stepping(void); +extern void lv_clear_baby_stepping(); +extern void disp_baby_step_dist(); +extern void disp_z_offset_value(); + +//extern void disp_temp_ready_print(); +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_change_speed.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_change_speed.cpp new file mode 100644 index 000000000000..c60000afaee3 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_change_speed.cpp @@ -0,0 +1,356 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" +//#include "../lvgl/src/lv_objx/lv_imgbtn.h" +//#include "../lvgl/src/lv_objx/lv_img.h" +//#include "../lvgl/src/lv_core/lv_disp.h" +//#include "../lvgl/src/lv_core/lv_refr.h" + +#include "../../../../MarlinCore.h" +#include "../../../../module/temperature.h" +#include "../../../../module/planner.h" + +extern lv_group_t * g; +static lv_obj_t * scr; +static lv_obj_t *labelStep, *buttonStep, *buttonMov, *buttonExt; +static lv_obj_t *labelMov, *labelExt; +static lv_obj_t * printSpeedText; + +#define ID_C_ADD 1 +#define ID_C_DEC 2 +#define ID_C_MOVE 3 +#define ID_C_EXT 4 +#define ID_C_STEP 5 +#define ID_C_RETURN 6 + +static uint8_t speedType; + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_C_ADD: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (speedType == 0) { + if (feedrate_percentage < MAX_EXT_SPEED_PERCENT - uiCfg.stepPrintSpeed) + feedrate_percentage += uiCfg.stepPrintSpeed; + else + feedrate_percentage = MAX_EXT_SPEED_PERCENT; + } + else if (speedType == 1) { + if (planner.flow_percentage[0] < MAX_EXT_SPEED_PERCENT - uiCfg.stepPrintSpeed) + planner.flow_percentage[0] += uiCfg.stepPrintSpeed; + else + planner.flow_percentage[0] = MAX_EXT_SPEED_PERCENT; + //planner.e_factor[0]= planner.flow_percentage[0]*0.01; + //planner.flow_percentage[1] = planner.flow_percentage[0]; + //planner.e_factor[1]= planner.flow_percentage[1]*0.01; + planner.refresh_e_factor(0); + #if HAS_MULTI_EXTRUDER + planner.flow_percentage[1] = planner.flow_percentage[0]; + planner.refresh_e_factor(1); + #endif + } + disp_print_speed(); + } + break; + case ID_C_DEC: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (speedType == 0) { + if (feedrate_percentage > MIN_EXT_SPEED_PERCENT + uiCfg.stepPrintSpeed) + feedrate_percentage -= uiCfg.stepPrintSpeed; + else + feedrate_percentage = MIN_EXT_SPEED_PERCENT; + } + else if (speedType == 1) { + if (planner.flow_percentage[0] > MIN_EXT_SPEED_PERCENT + uiCfg.stepPrintSpeed) + planner.flow_percentage[0] -= uiCfg.stepPrintSpeed; + else + planner.flow_percentage[0] = MIN_EXT_SPEED_PERCENT; + //planner.e_factor[0]= planner.flow_percentage[0] * 0.01; + //planner.flow_percentage[1] = planner.flow_percentage[0]; + //planner.e_factor[1]= planner.flow_percentage[1] * 0.01; + planner.refresh_e_factor(0); + #if HAS_MULTI_EXTRUDER + planner.flow_percentage[1] = planner.flow_percentage[0]; + planner.refresh_e_factor(1); + #endif + } + disp_print_speed(); + } + break; + case ID_C_MOVE: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + speedType = 0; + disp_speed_type(); + disp_print_speed(); + } + break; + case ID_C_EXT: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + speedType = 1; + disp_speed_type(); + disp_print_speed(); + } + break; + case ID_C_STEP: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (uiCfg.stepPrintSpeed == 1) + uiCfg.stepPrintSpeed = 5; + else if (uiCfg.stepPrintSpeed == 5) + uiCfg.stepPrintSpeed = 10; + else + uiCfg.stepPrintSpeed = 1; + disp_speed_step(); + } + break; + case ID_C_RETURN: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + clear_cur_ui(); + draw_return_ui(); + } + break; + } +} + +void lv_draw_change_speed(void) { + lv_obj_t *buttonAdd, *buttonDec; + lv_obj_t *buttonBack; + + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != CHANGE_SPEED_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = CHANGE_SPEED_UI; + } + disp_state = CHANGE_SPEED_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, creat_title_text()); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + + // Create an Image button + buttonAdd = lv_imgbtn_create(scr, NULL); + buttonDec = lv_imgbtn_create(scr, NULL); + buttonMov = lv_imgbtn_create(scr, NULL); + buttonExt = lv_imgbtn_create(scr, NULL); + buttonStep = lv_imgbtn_create(scr, NULL); + buttonBack = lv_imgbtn_create(scr, NULL); + + lv_obj_set_event_cb_mks(buttonAdd, event_handler, ID_C_ADD, NULL, 0); + lv_imgbtn_set_src(buttonAdd, LV_BTN_STATE_REL, "F:/bmp_Add.bin"); + lv_imgbtn_set_src(buttonAdd, LV_BTN_STATE_PR, "F:/bmp_Add.bin"); + lv_imgbtn_set_style(buttonAdd, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonAdd, LV_BTN_STATE_REL, &tft_style_label_rel); + + #if 1 + lv_obj_set_event_cb_mks(buttonDec, event_handler, ID_C_DEC, NULL, 0); + lv_imgbtn_set_src(buttonDec, LV_BTN_STATE_REL, "F:/bmp_Dec.bin"); + lv_imgbtn_set_src(buttonDec, LV_BTN_STATE_PR, "F:/bmp_Dec.bin"); + lv_imgbtn_set_style(buttonDec, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonDec, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonMov, event_handler, ID_C_MOVE, NULL, 0); + lv_imgbtn_set_style(buttonMov, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonMov, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonExt, event_handler, ID_C_EXT, NULL, 0); + lv_imgbtn_set_style(buttonExt, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonExt, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonStep, event_handler, ID_C_STEP, NULL, 0); + lv_imgbtn_set_style(buttonStep, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonStep, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_C_RETURN, NULL, 0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_return.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_return.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + #endif + + lv_obj_set_pos(buttonAdd, INTERVAL_V, titleHeight); + lv_obj_set_pos(buttonDec, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight); + lv_obj_set_pos(buttonMov, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonExt, BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonStep, BTN_X_PIXEL * 2 + INTERVAL_V * 3, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonBack, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + + // Create labels on the image buttons + lv_btn_set_layout(buttonAdd, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonDec, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonMov, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonExt, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonStep, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + + lv_obj_t *labelAdd = lv_label_create(buttonAdd, NULL); + lv_obj_t *labelDec = lv_label_create(buttonDec, NULL); + labelMov = lv_label_create(buttonMov, NULL); + labelExt = lv_label_create(buttonExt, NULL); + labelStep = lv_label_create(buttonStep, NULL); + lv_obj_t *label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(labelAdd, speed_menu.add); + lv_obj_align(labelAdd, buttonAdd, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelDec, speed_menu.dec); + lv_obj_align(labelDec, buttonDec, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonAdd); + lv_group_add_obj(g, buttonDec); + lv_group_add_obj(g, buttonMov); + lv_group_add_obj(g, buttonExt); + lv_group_add_obj(g, buttonStep); + lv_group_add_obj(g, buttonBack); + } + #endif + + disp_speed_type(); + disp_speed_step(); + + printSpeedText = lv_label_create(scr, NULL); + lv_obj_set_style(printSpeedText, &tft_style_label_rel); + disp_print_speed(); +} + +void disp_speed_step() { + if (uiCfg.stepPrintSpeed == 1) { + lv_imgbtn_set_src(buttonStep, LV_BTN_STATE_REL, "F:/bmp_step1_percent.bin"); + lv_imgbtn_set_src(buttonStep, LV_BTN_STATE_PR, "F:/bmp_step1_percent.bin"); + } + else if (uiCfg.stepPrintSpeed == 5) { + lv_imgbtn_set_src(buttonStep, LV_BTN_STATE_REL, "F:/bmp_step5_percent.bin"); + lv_imgbtn_set_src(buttonStep, LV_BTN_STATE_PR, "F:/bmp_step5_percent.bin"); + } + else if (uiCfg.stepPrintSpeed == 10) { + lv_imgbtn_set_src(buttonStep, LV_BTN_STATE_REL, "F:/bmp_step10_percent.bin"); + lv_imgbtn_set_src(buttonStep, LV_BTN_STATE_PR, "F:/bmp_step10_percent.bin"); + } + if (gCfgItems.multiple_language != 0) { + if (uiCfg.stepPrintSpeed == 1) { + lv_label_set_text(labelStep, speed_menu.step_1percent); + lv_obj_align(labelStep, buttonStep, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + else if (uiCfg.stepPrintSpeed == 5) { + lv_label_set_text(labelStep, speed_menu.step_5percent); + lv_obj_align(labelStep, buttonStep, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + else if (uiCfg.stepPrintSpeed == 10) { + lv_label_set_text(labelStep, speed_menu.step_10percent); + lv_obj_align(labelStep, buttonStep, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + } +} + +void disp_print_speed() { + char buf[30] = { 0 }; + + public_buf_l[0] = '\0'; + + if (speedType == 0) { // move + strcat(public_buf_l, speed_menu.move_speed); + strcat_P(public_buf_l, PSTR(": ")); + sprintf_P(buf, PSTR("%d%%"), feedrate_percentage); + strcat(public_buf_l, buf); + } + else if (speedType == 1) { // e1 + strcat(public_buf_l, speed_menu.extrude_speed); + strcat_P(public_buf_l, PSTR(": ")); + sprintf_P(buf, PSTR("%d%%"), planner.flow_percentage[0]); + strcat(public_buf_l, buf); + } + lv_label_set_text(printSpeedText, public_buf_l); + lv_obj_align(printSpeedText, NULL, LV_ALIGN_CENTER, 0, -65); +} + +void disp_speed_type() { + switch (speedType) { + case 1: + lv_imgbtn_set_src(buttonMov, LV_BTN_STATE_REL, "F:/bmp_mov_changeSpeed.bin"); + lv_imgbtn_set_src(buttonMov, LV_BTN_STATE_PR, "F:/bmp_mov_changeSpeed.bin"); + lv_imgbtn_set_src(buttonExt, LV_BTN_STATE_REL, "F:/bmp_extruct_sel.bin"); + lv_imgbtn_set_src(buttonExt, LV_BTN_STATE_PR, "F:/bmp_extruct_sel.bin"); + break; + + default: + lv_imgbtn_set_src(buttonMov, LV_BTN_STATE_REL, "F:/bmp_mov_sel.bin"); + lv_imgbtn_set_src(buttonMov, LV_BTN_STATE_PR, "F:/bmp_mov_sel.bin"); + lv_imgbtn_set_src(buttonExt, LV_BTN_STATE_REL, "F:/bmp_speed_extruct.bin"); + lv_imgbtn_set_src(buttonExt, LV_BTN_STATE_PR, "F:/bmp_speed_extruct.bin"); + break; + } + lv_obj_refresh_ext_draw_pad(buttonExt); + lv_obj_refresh_ext_draw_pad(buttonMov); + + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(labelMov, speed_menu.move); + lv_obj_align(labelMov, buttonMov, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelExt, speed_menu.extrude); + lv_obj_align(labelExt, buttonExt, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } +} + +void lv_clear_change_speed() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_change_speed.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_change_speed.h new file mode 100644 index 000000000000..c4996a3ef732 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_change_speed.h @@ -0,0 +1,40 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +#define MIN_EXT_SPEED_PERCENT 10 +#define MAX_EXT_SPEED_PERCENT 999 + +extern void lv_draw_change_speed(void); +extern void lv_clear_change_speed(); +extern void disp_speed_step(); +extern void disp_print_speed(); +extern void disp_speed_type(); + +//extern void disp_temp_ready_print(); +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_dialog.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_dialog.cpp new file mode 100644 index 000000000000..c8483230103c --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_dialog.cpp @@ -0,0 +1,703 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * draw_dialog.cpp + */ + +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" + +//#include "../lvgl/src/lv_objx/lv_imgbtn.h" +//#include "../lvgl/src/lv_objx/lv_img.h" +//#include "../lvgl/src/lv_core/lv_disp.h" +//#include "../lvgl/src/lv_core/lv_refr.h" + +#include "../../../../MarlinCore.h" +#include "../../../../sd/cardreader.h" +#include "../../../../gcode/queue.h" +#include "../../../../module/temperature.h" +#include "../../../../module/planner.h" +#include "../../../../gcode/gcode.h" + +#if ENABLED(POWER_LOSS_RECOVERY) + #include "../../../../feature/powerloss.h" +#endif + +#if ENABLED(PARK_HEAD_ON_PAUSE) + #include "../../../../feature/pause.h" +#endif +#include "../../../../gcode/gcode.h" + +extern lv_group_t * g; +static lv_obj_t * scr; +static lv_obj_t * tempText1; +static lv_obj_t * filament_bar; + +extern uint8_t sel_id; +extern uint8_t once_flag; +extern uint8_t gcode_preview_over; +extern int upload_result ; +extern uint32_t upload_time; +extern uint32_t upload_size; +extern uint8_t temperature_change_frequency; + +static void btn_ok_event_cb(lv_obj_t * btn, lv_event_t event) { + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (uiCfg.dialogType == DIALOG_TYPE_PRINT_FILE) { + #if HAS_GCODE_PREVIEW + preview_gcode_prehandle(list_file.file_name[sel_id]); + #endif + reset_print_time(); + start_print_time(); + + uiCfg.print_state = WORKING; + lv_clear_dialog(); + lv_draw_printing(); + + #if ENABLED(SDSUPPORT) + if (gcode_preview_over != 1) { + char *cur_name; + cur_name = strrchr(list_file.file_name[sel_id], '/'); + + SdFile file, *curDir; + card.endFilePrint(); + const char * const fname = card.diveToFile(true, curDir, cur_name); + if (!fname) return; + if (file.open(curDir, fname, O_READ)) { + gCfgItems.curFilesize = file.fileSize(); + file.close(); + update_spi_flash(); + } + card.openFileRead(cur_name); + if (card.isFileOpen()) { + feedrate_percentage = 100; + //saved_feedrate_percentage = feedrate_percentage; + planner.flow_percentage[0] = 100; + planner.e_factor[0] = planner.flow_percentage[0] * 0.01f; + #if HAS_MULTI_EXTRUDER + planner.flow_percentage[1] = 100; + planner.e_factor[1] = planner.flow_percentage[1] * 0.01f; + #endif + card.startFileprint(); + #if ENABLED(POWER_LOSS_RECOVERY) + recovery.prepare(); + #endif + once_flag = 0; + } + } + #endif + } + else if (uiCfg.dialogType == DIALOG_TYPE_STOP) { + wait_for_heatup = false; + stop_print_time(); + lv_clear_dialog(); + lv_draw_ready_print(); + + #if ENABLED(SDSUPPORT) + //card.endFilePrint(); + //wait_for_heatup = false; + uiCfg.print_state = IDLE; + card.flag.abort_sd_printing = true; + //queue.clear(); + //quickstop_stepper(); + //print_job_timer.stop(); + //thermalManager.disable_all_heaters(); + + //#if ENABLED(POWER_LOSS_RECOVERY) + // recovery.purge(); + //#endif + //queue.enqueue_now_P(PSTR("G91\nG1 Z10\nG90\nG28 X0 Y0")); + //queue.inject_P(PSTR("G91\nG1 Z10\nG90\nG28 X0 Y0\nM84\nM107")); + #endif + } + else if (uiCfg.dialogType == DIALOG_TYPE_FINISH_PRINT) { + clear_cur_ui(); + lv_draw_ready_print(); + } + #if ENABLED(ADVANCED_PAUSE_FEATURE) + else if (uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_WAITING + || uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_INSERT + || uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_HEAT + ) { + wait_for_user = false; + } + else if (uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_OPTION) { + pause_menu_response = PAUSE_RESPONSE_EXTRUDE_MORE; + } + else if (uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_RESUME) { + clear_cur_ui(); + draw_return_ui(); + } + #endif + else if (uiCfg.dialogType == DIALOG_STORE_EEPROM_TIPS) { + gcode.process_subcommands_now_P(PSTR("M500")); + clear_cur_ui(); + draw_return_ui(); + } + else if (uiCfg.dialogType == DIALOG_READ_EEPROM_TIPS) { + gcode.process_subcommands_now_P(PSTR("M501")); + clear_cur_ui(); + draw_return_ui(); + } + else if (uiCfg.dialogType == DIALOG_REVERT_EEPROM_TIPS) { + gcode.process_subcommands_now_P(PSTR("M502")); + clear_cur_ui(); + draw_return_ui(); + } + else if (uiCfg.dialogType == DIALOG_WIFI_CONFIG_TIPS) { + uiCfg.configWifi = 1; + clear_cur_ui(); + draw_return_ui(); + } + else if (uiCfg.dialogType == DIALOG_TYPE_FILAMENT_HEAT_LOAD_COMPLETED) { + uiCfg.filament_heat_completed_load = 1; + } + else if (uiCfg.dialogType == DIALOG_TYPE_FILAMENT_HEAT_UNLOAD_COMPLETED) { + uiCfg.filament_heat_completed_unload = 1; + } + else if (uiCfg.dialogType == DIALOG_TYPE_FILAMENT_LOAD_COMPLETED + || uiCfg.dialogType == DIALOG_TYPE_FILAMENT_UNLOAD_COMPLETED + ) { + clear_cur_ui(); + draw_return_ui(); + } + } +} + +static void btn_cancel_event_cb(lv_obj_t * btn, lv_event_t event) { + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_OPTION) { + #if ENABLED(ADVANCED_PAUSE_FEATURE) + pause_menu_response = PAUSE_RESPONSE_RESUME_PRINT; + #endif + } + else if ((uiCfg.dialogType == DIALOG_TYPE_FILAMENT_LOAD_HEAT) + || (uiCfg.dialogType == DIALOG_TYPE_FILAMENT_UNLOAD_HEAT) + || (uiCfg.dialogType == DIALOG_TYPE_FILAMENT_HEAT_LOAD_COMPLETED) + || (uiCfg.dialogType == DIALOG_TYPE_FILAMENT_HEAT_UNLOAD_COMPLETED) + ) { + thermalManager.temp_hotend[uiCfg.curSprayerChoose].target= uiCfg.desireSprayerTempBak; + clear_cur_ui(); + draw_return_ui(); + } + else if ((uiCfg.dialogType == DIALOG_TYPE_FILAMENT_LOADING) + || (uiCfg.dialogType == DIALOG_TYPE_FILAMENT_UNLOADING) + ) { + queue.enqueue_one_P(PSTR("M410")); + uiCfg.filament_rate = 0; + uiCfg.filament_loading_completed = 0; + uiCfg.filament_unloading_completed = 0; + uiCfg.filament_loading_time_flg = 0; + uiCfg.filament_loading_time_cnt = 0; + uiCfg.filament_unloading_time_flg = 0; + uiCfg.filament_unloading_time_cnt = 0; + thermalManager.temp_hotend[uiCfg.curSprayerChoose].target = uiCfg.desireSprayerTempBak; + clear_cur_ui(); + draw_return_ui(); + } + else { + clear_cur_ui(); + draw_return_ui(); + } + } +} + +void lv_draw_dialog(uint8_t type) { + + lv_obj_t * btnOk = NULL; + lv_obj_t * btnCancel = NULL; + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != DIALOG_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = DIALOG_UI; + } + disp_state = DIALOG_UI; + + uiCfg.dialogType = type; + + scr = lv_obj_create(NULL, NULL); + + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, creat_title_text()); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + + static lv_style_t style_btn_rel; // A variable to store the released style + lv_style_copy(&style_btn_rel, &lv_style_plain); // Initialize from a built-in style + style_btn_rel.body.border.color = lv_color_hex3(0x269); + style_btn_rel.body.border.width = 1; + style_btn_rel.body.main_color = lv_color_hex3(0xADF); + style_btn_rel.body.grad_color = lv_color_hex3(0x46B); + style_btn_rel.body.shadow.width = 4; + style_btn_rel.body.shadow.type = LV_SHADOW_BOTTOM; + style_btn_rel.body.radius = LV_RADIUS_CIRCLE; + style_btn_rel.text.color = lv_color_hex3(0xDEF); + style_btn_rel.text.font = &TERN(HAS_SPI_FLASH_FONT, gb2312_puhui32, lv_font_roboto_22); + + static lv_style_t style_btn_pr; // A variable to store the pressed style + lv_style_copy(&style_btn_pr, &style_btn_rel); // Initialize from the released style + style_btn_pr.body.border.color = lv_color_hex3(0x46B); + style_btn_pr.body.main_color = lv_color_hex3(0x8BD); + style_btn_pr.body.grad_color = lv_color_hex3(0x24A); + style_btn_pr.body.shadow.width = 2; + style_btn_pr.text.color = lv_color_hex3(0xBCD); + style_btn_pr.text.font = &TERN(HAS_SPI_FLASH_FONT, gb2312_puhui32, lv_font_roboto_22); + + lv_obj_t *labelDialog = lv_label_create(scr, NULL); + lv_obj_set_style(labelDialog, &tft_style_label_rel); + + if (uiCfg.dialogType == DIALOG_TYPE_FINISH_PRINT || uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_RESUME) { + btnOk = lv_btn_create(scr, NULL); // Add a button the current screen + lv_obj_set_pos(btnOk, BTN_OK_X + 90, BTN_OK_Y); // Set its position + lv_obj_set_size(btnOk, 100, 50); // Set its size + lv_obj_set_event_cb(btnOk, btn_ok_event_cb); + lv_btn_set_style(btnOk, LV_BTN_STYLE_REL, &style_btn_rel); // Set the button's released style + lv_btn_set_style(btnOk, LV_BTN_STYLE_PR, &style_btn_pr); // Set the button's pressed style + lv_obj_t *labelOk = lv_label_create(btnOk, NULL); // Add a label to the button + lv_label_set_text(labelOk, print_file_dialog_menu.confirm); // Set the labels text + } + else if (uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_WAITING + || uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_INSERT + || uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_HEAT + ) { + btnOk = lv_btn_create(scr, NULL); // Add a button the current screen + lv_obj_set_pos(btnOk, BTN_OK_X + 90, BTN_OK_Y); // Set its position + lv_obj_set_size(btnOk, 100, 50); // Set its size + lv_obj_set_event_cb(btnOk, btn_ok_event_cb); + lv_btn_set_style(btnOk, LV_BTN_STYLE_REL, &style_btn_rel); // Set the button's released style + lv_btn_set_style(btnOk, LV_BTN_STYLE_PR, &style_btn_pr); // Set the button's pressed style + lv_obj_t *labelOk = lv_label_create(btnOk, NULL); // Add a label to the button + lv_label_set_text(labelOk, print_file_dialog_menu.confirm); // Set the labels text + } + else if (uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_PAUSING + || uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_CHANGING + || uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_UNLOAD + || uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_LOAD + || uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_PURGE + || uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_RESUME + || uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_HEATING + ) { + // nothing to do + } + else if (uiCfg.dialogType == WIFI_ENABLE_TIPS) { + btnCancel = lv_btn_create(scr, NULL); + lv_obj_set_pos(btnCancel, BTN_OK_X+90, BTN_OK_Y); + lv_obj_set_size(btnCancel, 100, 50); + lv_obj_set_event_cb(btnCancel, btn_cancel_event_cb); + lv_btn_set_style(btnCancel, LV_BTN_STYLE_REL, &style_btn_rel); + lv_btn_set_style(btnCancel, LV_BTN_STYLE_PR, &style_btn_pr); + lv_obj_t *labelCancel = lv_label_create(btnCancel, NULL); + lv_label_set_text(labelCancel, print_file_dialog_menu.cancle); + } + else if (uiCfg.dialogType == DIALOG_TRANSFER_NO_DEVICE) { + btnCancel = lv_btn_create(scr, NULL); + lv_obj_set_pos(btnCancel, BTN_OK_X+90, BTN_OK_Y); + lv_obj_set_size(btnCancel, 100, 50); + lv_obj_set_event_cb(btnCancel, btn_cancel_event_cb); + lv_btn_set_style(btnCancel, LV_BTN_STYLE_REL, &style_btn_rel); + lv_btn_set_style(btnCancel, LV_BTN_STYLE_PR, &style_btn_pr); + lv_obj_t *labelCancel = lv_label_create(btnCancel, NULL); + lv_label_set_text(labelCancel, print_file_dialog_menu.cancle); + } + #if ENABLED(USE_WIFI_FUNCTION) + else if (uiCfg.dialogType == DIALOG_TYPE_UPLOAD_FILE) { + if (upload_result == 2) { + btnCancel = lv_btn_create(scr, NULL); + lv_obj_set_pos(btnCancel, BTN_OK_X+90, BTN_OK_Y); + lv_obj_set_size(btnCancel, 100, 50); + lv_obj_set_event_cb(btnCancel, btn_cancel_event_cb); + lv_btn_set_style(btnCancel, LV_BTN_STYLE_REL, &style_btn_rel); + lv_btn_set_style(btnCancel, LV_BTN_STYLE_PR, &style_btn_pr); + lv_obj_t *labelCancel = lv_label_create(btnCancel, NULL); + lv_label_set_text(labelCancel, print_file_dialog_menu.cancle); + } + else if (upload_result == 3) { + btnOk = lv_btn_create(scr, NULL); + lv_obj_set_pos(btnOk, BTN_OK_X+90, BTN_OK_Y); + lv_obj_set_size(btnOk, 100, 50); + lv_obj_set_event_cb(btnOk, btn_ok_event_cb); + lv_btn_set_style(btnOk, LV_BTN_STYLE_REL, &style_btn_rel); + lv_btn_set_style(btnOk, LV_BTN_STYLE_PR, &style_btn_pr); + lv_obj_t *labelOk = lv_label_create(btnOk, NULL); + lv_label_set_text(labelOk, print_file_dialog_menu.confirm); + } + } + #endif //USE_WIFI_FUNCTION + else if (uiCfg.dialogType == DIALOG_TYPE_FILAMENT_LOAD_HEAT + || uiCfg.dialogType == DIALOG_TYPE_FILAMENT_UNLOAD_HEAT + ) { + btnCancel = lv_btn_create(scr, NULL); + lv_obj_set_pos(btnCancel, BTN_OK_X+90, BTN_OK_Y); + lv_obj_set_size(btnCancel, 100, 50); + lv_obj_set_event_cb(btnCancel, btn_cancel_event_cb); + lv_btn_set_style(btnCancel, LV_BTN_STYLE_REL, &style_btn_rel); + lv_btn_set_style(btnCancel, LV_BTN_STYLE_PR, &style_btn_pr); + lv_obj_t *labelCancel = lv_label_create(btnCancel, NULL); + lv_label_set_text(labelCancel, print_file_dialog_menu.cancle); + + tempText1 = lv_label_create(scr, NULL); + lv_obj_set_style(tempText1, &tft_style_label_rel); + filament_sprayer_temp(); + } + else if (uiCfg.dialogType == DIALOG_TYPE_FILAMENT_LOAD_COMPLETED + || uiCfg.dialogType == DIALOG_TYPE_FILAMENT_UNLOAD_COMPLETED + ) { + btnOk = lv_btn_create(scr, NULL); + lv_obj_set_pos(btnOk, BTN_OK_X+90, BTN_OK_Y); + lv_obj_set_size(btnOk, 100, 50); + lv_obj_set_event_cb(btnOk, btn_ok_event_cb); + lv_btn_set_style(btnOk, LV_BTN_STYLE_REL, &style_btn_rel); + lv_btn_set_style(btnOk, LV_BTN_STYLE_PR, &style_btn_pr); + lv_obj_t *labelOk = lv_label_create(btnOk, NULL); + lv_label_set_text(labelOk, print_file_dialog_menu.confirm); + } + else if (uiCfg.dialogType == DIALOG_TYPE_FILAMENT_LOADING + || uiCfg.dialogType == DIALOG_TYPE_FILAMENT_UNLOADING + ) { + btnCancel = lv_btn_create(scr, NULL); + lv_obj_set_pos(btnCancel, BTN_OK_X+90, BTN_OK_Y); + lv_obj_set_size(btnCancel, 100, 50); + lv_obj_set_event_cb(btnCancel, btn_cancel_event_cb); + lv_btn_set_style(btnCancel, LV_BTN_STYLE_REL, &style_btn_rel); + lv_btn_set_style(btnCancel, LV_BTN_STYLE_PR, &style_btn_pr); + lv_obj_t *labelCancel = lv_label_create(btnCancel, NULL); + lv_label_set_text(labelCancel, print_file_dialog_menu.cancle); + + filament_bar = lv_bar_create(scr, NULL); + lv_obj_set_pos(filament_bar, (TFT_WIDTH-400)/2, ((TFT_HEIGHT - titleHeight)-40)/2); + lv_obj_set_size(filament_bar, 400, 25); + lv_bar_set_style(filament_bar, LV_BAR_STYLE_INDIC, &lv_bar_style_indic); + lv_bar_set_anim_time(filament_bar, 1000); + lv_bar_set_value(filament_bar, 0, LV_ANIM_ON); + } + else { + btnOk = lv_btn_create(scr, NULL); // Add a button the current screen + lv_obj_set_pos(btnOk, BTN_OK_X, BTN_OK_Y); // Set its position + lv_obj_set_size(btnOk, 100, 50); // Set its size + lv_obj_set_event_cb(btnOk, btn_ok_event_cb); + lv_btn_set_style(btnOk, LV_BTN_STYLE_REL, &style_btn_rel); // Set the button's released style + lv_btn_set_style(btnOk, LV_BTN_STYLE_PR, &style_btn_pr); // Set the button's pressed style + lv_obj_t *labelOk = lv_label_create(btnOk, NULL); // Add a label to the button + + btnCancel = lv_btn_create(scr, NULL); // Add a button the current screen + lv_obj_set_pos(btnCancel, BTN_CANCEL_X, BTN_CANCEL_Y); // Set its position + lv_obj_set_size(btnCancel, 100, 50); // Set its size + lv_obj_set_event_cb(btnCancel, btn_cancel_event_cb); + lv_btn_set_style(btnCancel, LV_BTN_STYLE_REL, &style_btn_rel); // Set the button's released style + lv_btn_set_style(btnCancel, LV_BTN_STYLE_PR, &style_btn_pr); // Set the button's pressed style + lv_obj_t *labelCancel = lv_label_create(btnCancel, NULL); // Add a label to the button + + if (uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_OPTION) { + lv_label_set_text(labelOk, pause_msg_menu.purgeMore); // Set the labels text + lv_label_set_text(labelCancel, pause_msg_menu.continuePrint); + } + else { + lv_label_set_text(labelOk, print_file_dialog_menu.confirm); // Set the labels text + lv_label_set_text(labelCancel, print_file_dialog_menu.cancle); + } + } + if (uiCfg.dialogType == DIALOG_TYPE_PRINT_FILE) { + lv_label_set_text(labelDialog, print_file_dialog_menu.print_file); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + + lv_obj_t *labelFile = lv_label_create(scr, NULL); + lv_obj_set_style(labelFile, &tft_style_label_rel); + + lv_label_set_text(labelFile, list_file.long_name[sel_id]); + lv_obj_align(labelFile, NULL, LV_ALIGN_CENTER, 0, -60); + } + else if (uiCfg.dialogType == DIALOG_TYPE_STOP) { + lv_label_set_text(labelDialog, print_file_dialog_menu.cancle_print); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == DIALOG_TYPE_FINISH_PRINT) { + lv_label_set_text(labelDialog, print_file_dialog_menu.print_finish); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_PAUSING) { + lv_label_set_text(labelDialog, pause_msg_menu.pausing); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_CHANGING) { + lv_label_set_text(labelDialog, pause_msg_menu.changing); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_UNLOAD) { + lv_label_set_text(labelDialog, pause_msg_menu.unload); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_WAITING) { + lv_label_set_text(labelDialog, pause_msg_menu.waiting); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_INSERT) { + lv_label_set_text(labelDialog, pause_msg_menu.insert); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_LOAD) { + lv_label_set_text(labelDialog, pause_msg_menu.load); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_PURGE) { + lv_label_set_text(labelDialog, pause_msg_menu.purge); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_RESUME) { + lv_label_set_text(labelDialog, pause_msg_menu.resume); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_HEAT) { + lv_label_set_text(labelDialog, pause_msg_menu.heat); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_HEATING) { + lv_label_set_text(labelDialog, pause_msg_menu.heating); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == DIALOG_PAUSE_MESSAGE_OPTION) { + lv_label_set_text(labelDialog, pause_msg_menu.option); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == DIALOG_STORE_EEPROM_TIPS) { + lv_label_set_text(labelDialog, eeprom_menu.storeTips); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == DIALOG_READ_EEPROM_TIPS) { + lv_label_set_text(labelDialog, eeprom_menu.readTips); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == DIALOG_REVERT_EEPROM_TIPS) { + lv_label_set_text(labelDialog, eeprom_menu.revertTips); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == DIALOG_WIFI_CONFIG_TIPS) { + lv_label_set_text(labelDialog, machine_menu.wifiConfigTips); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == WIFI_ENABLE_TIPS) { + lv_label_set_text(labelDialog, print_file_dialog_menu.wifi_enable_tips); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == DIALOG_TRANSFER_NO_DEVICE) { + lv_label_set_text(labelDialog, DIALOG_UPDATE_NO_DEVICE_EN); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + #if ENABLED(USE_WIFI_FUNCTION) + else if (uiCfg.dialogType == DIALOG_TYPE_UPLOAD_FILE) { + if (upload_result == 1) { + lv_label_set_text(labelDialog, DIALOG_UPLOAD_ING_EN); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (upload_result == 2) { + lv_label_set_text(labelDialog, DIALOG_UPLOAD_ERROR_EN); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (upload_result == 3) { + char buf[200]; + int _index = 0; + + ZERO(buf); + + strcpy(buf, DIALOG_UPLOAD_FINISH_EN); + _index = strlen(buf); + buf[_index] = '\n'; + _index++; + strcat(buf, DIALOG_UPLOAD_SIZE_EN); + + _index = strlen(buf); + buf[_index] = ':'; + _index++; + sprintf(&buf[_index], " %d KBytes\n", (int)(upload_size / 1024)); + + strcat(buf, DIALOG_UPLOAD_TIME_EN); + _index = strlen(buf); + buf[_index] = ':'; + _index++; + sprintf(&buf[_index], " %d s\n", (int)upload_time); + + strcat(buf, DIALOG_UPLOAD_SPEED_EN); + _index = strlen(buf); + buf[_index] = ':'; + _index++; + sprintf(&buf[_index], " %d KBytes/s\n", (int)(upload_size / upload_time / 1024)); + + lv_label_set_text(labelDialog, buf); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + + } + } + #endif //USE_WIFI_FUNCTION + else if (uiCfg.dialogType == DIALOG_TYPE_FILAMENT_LOAD_HEAT) { + lv_label_set_text(labelDialog, filament_menu.filament_dialog_load_heat); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == DIALOG_TYPE_FILAMENT_HEAT_LOAD_COMPLETED) { + lv_label_set_text(labelDialog, filament_menu.filament_dialog_load_heat_confirm); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == DIALOG_TYPE_FILAMENT_UNLOAD_HEAT) { + lv_label_set_text(labelDialog, filament_menu.filament_dialog_unload_heat); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == DIALOG_TYPE_FILAMENT_HEAT_UNLOAD_COMPLETED) { + lv_label_set_text(labelDialog, filament_menu.filament_dialog_unload_heat_confirm); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == DIALOG_TYPE_FILAMENT_LOAD_COMPLETED) { + lv_label_set_text(labelDialog, filament_menu.filament_dialog_load_completed); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == DIALOG_TYPE_FILAMENT_UNLOAD_COMPLETED) { + lv_label_set_text(labelDialog, filament_menu.filament_dialog_unload_completed); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20); + } + else if (uiCfg.dialogType == DIALOG_TYPE_FILAMENT_LOADING) { + lv_label_set_text(labelDialog, filament_menu.filament_dialog_loading); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -70); + } + else if (uiCfg.dialogType == DIALOG_TYPE_FILAMENT_UNLOADING) { + lv_label_set_text(labelDialog, filament_menu.filament_dialog_unloading); + lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -70); + } + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + if (btnOk) lv_group_add_obj(g, btnOk); + if (btnCancel) lv_group_add_obj(g, btnCancel); + } + #endif +} + +void filament_sprayer_temp() { + char buf[20] = {0}; + + public_buf_l[0] = '\0'; + + if (uiCfg.curSprayerChoose < 1) + strcat(public_buf_l, preheat_menu.ext1); + else + strcat(public_buf_l, preheat_menu.ext2); + sprintf(buf, preheat_menu.value_state, (int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius, (int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].target); + + strcat_P(public_buf_l, PSTR(": ")); + strcat(public_buf_l, buf); + lv_label_set_text(tempText1, public_buf_l); + lv_obj_align(tempText1, NULL, LV_ALIGN_CENTER, 0, -50); +} + +void filament_dialog_handle() { + if ((temperature_change_frequency == 1) + && ((uiCfg.dialogType == DIALOG_TYPE_FILAMENT_LOAD_HEAT) + || (uiCfg.dialogType == DIALOG_TYPE_FILAMENT_UNLOAD_HEAT)) + ) { + filament_sprayer_temp(); + temperature_change_frequency = 0; + } + if (uiCfg.filament_heat_completed_load == 1) { + uiCfg.filament_heat_completed_load = 0; + lv_clear_dialog(); + lv_draw_dialog(DIALOG_TYPE_FILAMENT_LOADING); + planner.synchronize(); + uiCfg.filament_loading_time_flg = 1; + uiCfg.filament_loading_time_cnt = 0; + ZERO(public_buf_m); + sprintf_P(public_buf_m,PSTR("T%d\nG91\nG1 E%d F%d\nG90"),uiCfg.curSprayerChoose,gCfgItems.filamentchange_load_length,gCfgItems.filamentchange_load_speed); + queue.inject_P(PSTR(public_buf_m)); + //gcode.process_subcommands_now_P(PSTR(public_buf_m)); + } + if (uiCfg.filament_heat_completed_unload == 1) { + uiCfg.filament_heat_completed_unload = 0; + lv_clear_dialog(); + lv_draw_dialog(DIALOG_TYPE_FILAMENT_UNLOADING); + planner.synchronize(); + uiCfg.filament_unloading_time_flg = 1; + uiCfg.filament_unloading_time_cnt = 0; + ZERO(public_buf_m); + sprintf_P(public_buf_m,PSTR("T%d\nG91\nG1 E-%d F%d\nG90"),uiCfg.curSprayerChoose,gCfgItems.filamentchange_unload_length,gCfgItems.filamentchange_unload_speed); + queue.inject_P(PSTR(public_buf_m)); + } + + if (((abs((int)((int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius - gCfgItems.filament_limit_temper)) <= 1) + || ((int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius > gCfgItems.filament_limit_temper)) + && (uiCfg.filament_load_heat_flg == 1) + ) { + uiCfg.filament_load_heat_flg = 0; + lv_clear_dialog(); + lv_draw_dialog(DIALOG_TYPE_FILAMENT_HEAT_LOAD_COMPLETED); + } + + if (uiCfg.filament_loading_completed == 1) { + uiCfg.filament_rate = 0; + uiCfg.filament_loading_completed = 0; + lv_clear_dialog(); + lv_draw_dialog(DIALOG_TYPE_FILAMENT_LOAD_COMPLETED); + } + if (((abs((int)((int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius - gCfgItems.filament_limit_temper)) <= 1) + || ((int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius > gCfgItems.filament_limit_temper)) + && (uiCfg.filament_unload_heat_flg == 1) + ) { + uiCfg.filament_unload_heat_flg = 0; + lv_clear_dialog(); + lv_draw_dialog(DIALOG_TYPE_FILAMENT_HEAT_UNLOAD_COMPLETED); + } + + if (uiCfg.filament_unloading_completed == 1) { + uiCfg.filament_rate = 0; + uiCfg.filament_unloading_completed = 0; + lv_clear_dialog(); + lv_draw_dialog(DIALOG_TYPE_FILAMENT_UNLOAD_COMPLETED); + } + + if ( uiCfg.dialogType == DIALOG_TYPE_FILAMENT_LOADING + || uiCfg.dialogType == DIALOG_TYPE_FILAMENT_UNLOADING + ) lv_filament_setbar(); +} + +void lv_filament_setbar() { + lv_bar_set_value(filament_bar, uiCfg.filament_rate, LV_ANIM_ON); +} + +void lv_clear_dialog() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_dialog.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_dialog.h new file mode 100644 index 000000000000..dc5adc5ad64c --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_dialog.h @@ -0,0 +1,88 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +#define DIALOG_TYPE_STOP 0 +#define DIALOG_TYPE_PRINT_FILE 1 +#define DIALOG_TYPE_REPRINT_NO_FILE 2 + +#define DIALOG_TYPE_M80_FAIL 3 //** +#define DIALOG_TYPE_MESSAGE_ERR1 4 //** + +#define DIALOG_TYPE_UPDATE_ESP_FIRMARE 5 +#define DIALOG_TYPE_UPDATE_ESP_DATA 6 +#define DIALOG_TYPE_UPLOAD_FILE 7 +#define DIALOG_TYPE_UNBIND 8 + +#define DIALOG_TYPE_FILAMENT_LOAD_HEAT 9 +#define DIALOG_TYPE_FILAMENT_HEAT_LOAD_COMPLETED 10 +#define DIALOG_TYPE_FILAMENT_LOADING 11 +#define DIALOG_TYPE_FILAMENT_LOAD_COMPLETED 12 +#define DIALOG_TYPE_FILAMENT_UNLOAD_HEAT 13 +#define DIALOG_TYPE_FILAMENT_HEAT_UNLOAD_COMPLETED 14 +#define DIALOG_TYPE_FILAMENT_UNLOADING 15 +#define DIALOG_TYPE_FILAMENT_UNLOAD_COMPLETED 16 + +#define DIALOG_TYPE_FILE_LOADING 17 //** + +#define DIALOG_TYPE_FILAMENT_NO_PRESS 18 +#define DIALOG_TYPE_FINISH_PRINT 19 + +#define WIFI_ENABLE_TIPS 20 + +#define DIALOG_PAUSE_MESSAGE_PAUSING 21 +#define DIALOG_PAUSE_MESSAGE_CHANGING 22 +#define DIALOG_PAUSE_MESSAGE_UNLOAD 23 +#define DIALOG_PAUSE_MESSAGE_WAITING 24 +#define DIALOG_PAUSE_MESSAGE_INSERT 25 +#define DIALOG_PAUSE_MESSAGE_LOAD 26 +#define DIALOG_PAUSE_MESSAGE_PURGE 27 +#define DIALOG_PAUSE_MESSAGE_RESUME 28 +#define DIALOG_PAUSE_MESSAGE_HEAT 29 +#define DIALOG_PAUSE_MESSAGE_HEATING 30 +#define DIALOG_PAUSE_MESSAGE_OPTION 31 + +#define DIALOG_STORE_EEPROM_TIPS 32 +#define DIALOG_READ_EEPROM_TIPS 33 +#define DIALOG_REVERT_EEPROM_TIPS 34 + +#define DIALOG_WIFI_CONFIG_TIPS 35 +#define DIALOG_TRANSFER_NO_DEVICE 36 +#define BTN_OK_X 100 +#define BTN_OK_Y 180 +#define BTN_CANCEL_X 280 +#define BTN_CANCEL_Y 180 + +extern void lv_draw_dialog(uint8_t type); +extern void lv_clear_dialog(); +extern void filament_sprayer_temp(); +extern void filament_dialog_handle(); +extern void lv_filament_setbar(); + +//extern void disp_temp_ready_print(); +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_eeprom_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_eeprom_settings.cpp new file mode 100644 index 000000000000..ca7d2d1e31b8 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_eeprom_settings.cpp @@ -0,0 +1,224 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" + +#include "../../../../MarlinCore.h" + +extern lv_group_t * g; +static lv_obj_t * scr; + +#define ID_EEPROM_RETURN 1 +#define ID_EEPROM_STORE 2 +#define ID_EEPROM_STORE_ARROW 3 +#define ID_EEPROM_READ 4 +#define ID_EEPROM_READ_ARROW 5 +#define ID_EEPROM_REVERT 6 +#define ID_EEPROM_REVERT_ARROW 7 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_EEPROM_RETURN: + if (event == LV_EVENT_CLICKED) { + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_eeprom_settings(); + draw_return_ui(); + } + break; + case ID_EEPROM_STORE: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_eeprom_settings(); + lv_draw_dialog(DIALOG_STORE_EEPROM_TIPS); + } + break; + case ID_EEPROM_STORE_ARROW: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_eeprom_settings(); + lv_draw_dialog(DIALOG_STORE_EEPROM_TIPS); + } + break; + #if 0 + case ID_EEPROM_READ: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_eeprom_settings(); + lv_draw_dialog(DIALOG_READ_EEPROM_TIPS); + } + break; + case ID_EEPROM_READ_ARROW: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_eeprom_settings(); + lv_draw_dialog(DIALOG_READ_EEPROM_TIPS); + } + break; + #endif + + case ID_EEPROM_REVERT: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_eeprom_settings(); + lv_draw_dialog(DIALOG_REVERT_EEPROM_TIPS); + } + break; + case ID_EEPROM_REVERT_ARROW: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_eeprom_settings(); + lv_draw_dialog(DIALOG_REVERT_EEPROM_TIPS); + } + break; + } +} + +void lv_draw_eeprom_settings(void) { + lv_obj_t *buttonBack, *label_Back; + lv_obj_t *buttonStore,*labelStore,*buttonStoreNarrow; + //lv_obj_t *buttonRead,*labelRead,*buttonReadNarrow; + lv_obj_t *buttonRevert, *labelRevert, *buttonRevertNarrow; + lv_obj_t * line1, * line2; //* line3; + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != EEPROM_SETTINGS_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = EEPROM_SETTINGS_UI; + } + disp_state = EEPROM_SETTINGS_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, creat_title_text()); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + buttonRevert = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(buttonRevert, PARA_UI_POS_X, PARA_UI_POS_Y); /*Set its position*/ + lv_obj_set_size(buttonRevert, PARA_UI_SIZE_X, PARA_UI_SIZE_Y); /*Set its size*/ + //lv_obj_set_event_cb(buttonMotor, event_handler); + lv_obj_set_event_cb_mks(buttonRevert, event_handler, ID_EEPROM_REVERT, NULL, 0); + lv_btn_set_style(buttonRevert, LV_BTN_STYLE_REL, &tft_style_label_rel); /*Set the button's released style*/ + lv_btn_set_style(buttonRevert, LV_BTN_STYLE_PR, &tft_style_label_pre); /*Set the button's pressed style*/ + lv_btn_set_layout(buttonRevert, LV_LAYOUT_OFF); + labelRevert = lv_label_create(buttonRevert, NULL); /*Add a label to the button*/ + + buttonRevertNarrow = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonRevertNarrow, PARA_UI_POS_X + PARA_UI_SIZE_X, PARA_UI_POS_Y + PARA_UI_ARROW_V); + lv_obj_set_event_cb_mks(buttonRevertNarrow, event_handler, ID_EEPROM_REVERT_ARROW, NULL, 0); + lv_imgbtn_set_src(buttonRevertNarrow, LV_BTN_STATE_REL, "F:/bmp_arrow.bin"); + lv_imgbtn_set_src(buttonRevertNarrow, LV_BTN_STATE_PR, "F:/bmp_arrow.bin"); + lv_imgbtn_set_style(buttonRevertNarrow, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonRevertNarrow, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonRevertNarrow, LV_LAYOUT_OFF); + + //line3 = lv_line_create(scr, NULL); + //lv_ex_line(line3,line_points[2]); + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1, line_points[0]); + + buttonStore = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(buttonStore, PARA_UI_POS_X, PARA_UI_POS_Y * 2); /*Set its position*/ + lv_obj_set_size(buttonStore, PARA_UI_SIZE_X, PARA_UI_SIZE_Y); /*Set its size*/ + //lv_obj_set_event_cb(buttonMotor, event_handler); + lv_obj_set_event_cb_mks(buttonStore, event_handler, ID_EEPROM_STORE, NULL, 0); + lv_btn_set_style(buttonStore, LV_BTN_STYLE_REL, &tft_style_label_rel); /*Set the button's released style*/ + lv_btn_set_style(buttonStore, LV_BTN_STYLE_PR, &tft_style_label_pre); /*Set the button's pressed style*/ + lv_btn_set_layout(buttonStore, LV_LAYOUT_OFF); + labelStore = lv_label_create(buttonStore, NULL); /*Add a label to the button*/ + + buttonStoreNarrow = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonStoreNarrow, PARA_UI_POS_X + PARA_UI_SIZE_X, PARA_UI_POS_Y * 2 + PARA_UI_ARROW_V); + lv_obj_set_event_cb_mks(buttonStoreNarrow, event_handler, ID_EEPROM_STORE_ARROW, NULL, 0); + lv_imgbtn_set_src(buttonStoreNarrow, LV_BTN_STATE_REL, "F:/bmp_arrow.bin"); + lv_imgbtn_set_src(buttonStoreNarrow, LV_BTN_STATE_PR, "F:/bmp_arrow.bin"); + lv_imgbtn_set_style(buttonStoreNarrow, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonStoreNarrow, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonStoreNarrow, LV_LAYOUT_OFF); + + line2 = lv_line_create(scr, NULL); + lv_ex_line(line2, line_points[1]); + + buttonBack = lv_imgbtn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_EEPROM_RETURN, NULL, 0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_pos(buttonBack, PARA_UI_BACL_POS_X, PARA_UI_BACL_POS_Y); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_CENTER, 0, 0); + + lv_label_set_text(labelStore, eeprom_menu.store); + lv_obj_align(labelStore, buttonStore, LV_ALIGN_IN_LEFT_MID,0, 0); + + //lv_label_set_text(labelRead, eeprom_menu.read); + //lv_obj_align(labelRead, buttonRead, LV_ALIGN_IN_LEFT_MID,0, 0); + + lv_label_set_text(labelRevert, eeprom_menu.revert); + lv_obj_align(labelRevert, buttonRevert, LV_ALIGN_IN_LEFT_MID, 0, 0); + } + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonRevert); + lv_group_add_obj(g, buttonStore); + lv_group_add_obj(g, buttonBack); + } + #endif + +} + +void lv_clear_eeprom_settings() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_eeprom_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_eeprom_settings.h new file mode 100644 index 000000000000..6d5ecf0870eb --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_eeprom_settings.h @@ -0,0 +1,33 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_eeprom_settings(void); +extern void lv_clear_eeprom_settings(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_encoder_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_encoder_settings.cpp new file mode 100644 index 000000000000..0ad2bb5f1ddb --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_encoder_settings.cpp @@ -0,0 +1,172 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" + +#include "../../../../MarlinCore.h" +#include "../../../../module/planner.h" +#include "../../../../module/stepper/indirection.h" +#include "../../../../feature/tmc_util.h" +#include "../../../../gcode/gcode.h" +#include "../../../../module/planner.h" + +#if BUTTONS_EXIST(EN1, EN2) + +extern lv_group_t * g; +static lv_obj_t * scr; +static lv_obj_t * buttonEncoderState = NULL; +static lv_obj_t *labelEncoderState = NULL; + +#define ID_ENCODER_RETURN 1 +#define ID_ENCODER_STATE 2 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_ENCODER_RETURN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_encoder_settings(); + draw_return_ui(); + } + break; + case ID_ENCODER_STATE: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (gCfgItems.encoder_enable) { + gCfgItems.encoder_enable = false; + lv_imgbtn_set_src(buttonEncoderState, LV_BTN_STATE_REL, "F:/bmp_disable.bin"); + lv_imgbtn_set_src(buttonEncoderState, LV_BTN_STATE_PR, "F:/bmp_disable.bin"); + lv_label_set_text(labelEncoderState, machine_menu.disable); + update_spi_flash(); + } + else { + gCfgItems.encoder_enable = true; + lv_imgbtn_set_src(buttonEncoderState, LV_BTN_STATE_REL, "F:/bmp_enable.bin"); + lv_imgbtn_set_src(buttonEncoderState, LV_BTN_STATE_PR, "F:/bmp_enable.bin"); + lv_label_set_text(labelEncoderState, machine_menu.enable); + update_spi_flash(); + } + } + break; + } +} + +void lv_draw_encoder_settings(void) { + lv_obj_t *buttonBack = NULL, *label_Back = NULL; + lv_obj_t *labelEncoderTips = NULL; + + lv_obj_t * line1 = NULL; + + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != ENCODER_SETTINGS_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = ENCODER_SETTINGS_UI; + } + disp_state = ENCODER_SETTINGS_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, machine_menu.EncoderConfTitle); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + labelEncoderTips = lv_label_create(scr, NULL); + lv_obj_set_style(labelEncoderTips, &tft_style_label_rel); + lv_obj_set_pos(labelEncoderTips, PARA_UI_POS_X, PARA_UI_POS_Y + 10); + lv_label_set_text(labelEncoderTips, machine_menu.EncoderConfText); + + buttonEncoderState = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonEncoderState, PARA_UI_STATE_POS_X, PARA_UI_POS_Y + PARA_UI_STATE_V); + if (gCfgItems.encoder_enable) { + lv_imgbtn_set_src(buttonEncoderState, LV_BTN_STATE_REL, "F:/bmp_enable.bin"); + lv_imgbtn_set_src(buttonEncoderState, LV_BTN_STATE_PR, "F:/bmp_enable.bin"); + } + else { + lv_imgbtn_set_src(buttonEncoderState, LV_BTN_STATE_REL, "F:/bmp_disable.bin"); + lv_imgbtn_set_src(buttonEncoderState, LV_BTN_STATE_PR, "F:/bmp_disable.bin"); + } + + lv_obj_set_event_cb_mks(buttonEncoderState, event_handler, ID_ENCODER_STATE, NULL, 0); + + lv_imgbtn_set_style(buttonEncoderState, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonEncoderState, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonEncoderState, LV_LAYOUT_OFF); + labelEncoderState = lv_label_create(buttonEncoderState, NULL); + + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1, line_points[0]); + + buttonBack = lv_imgbtn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_ENCODER_RETURN, NULL, 0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_pos(buttonBack, PARA_UI_BACL_POS_X, PARA_UI_BACL_POS_Y); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.encoder_enable) { + lv_label_set_text(labelEncoderState, machine_menu.enable); + lv_obj_align(labelEncoderState, buttonEncoderState, LV_ALIGN_CENTER, 0, 0); + } + else { + lv_label_set_text(labelEncoderState, machine_menu.disable); + lv_obj_align(labelEncoderState, buttonEncoderState, LV_ALIGN_CENTER, 0, 0); + } + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_CENTER, 0, 0); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonEncoderState); + lv_group_add_obj(g, buttonBack); + } + #endif +} + +void lv_clear_encoder_settings() { + #if HAS_ROTARY_ENCODER + lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // BUTTONS_EXIST(EN1, EN2) + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_encoder_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_encoder_settings.h new file mode 100644 index 000000000000..62892a6ec142 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_encoder_settings.h @@ -0,0 +1,33 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_encoder_settings(void); +extern void lv_clear_encoder_settings(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_error_message.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_error_message.cpp new file mode 100644 index 000000000000..c21ee3612c3a --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_error_message.cpp @@ -0,0 +1,86 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "SPI_TFT.h" + +#include "lv_conf.h" +#include "draw_ui.h" +#include "tft_lvgl_configuration.h" +#include "mks_hardware_test.h" +//#include "../lvgl/src/lv_objx/lv_imgbtn.h" +//#include "../lvgl/src/lv_objx/lv_img.h" +//#include "../lvgl/src/lv_core/lv_disp.h" +//#include "../lvgl/src/lv_core/lv_refr.h" + +#include "../../../../MarlinCore.h" + +static lv_obj_t * scr; + +void lv_draw_error_message(PGM_P const msg) { + #if 0 + static lv_obj_t * message = NULL, *kill_message = NULL, *reset_tips = NULL; + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != ERROR_MESSAGE_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = ERROR_MESSAGE_UI; + } + disp_state = ERROR_MESSAGE_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + if (msg) { + message = lv_label_create(scr, NULL); + lv_obj_set_style(message, &tft_style_label_rel); + lv_label_set_text(message, msg); + lv_obj_align(message, NULL, LV_ALIGN_CENTER, 0, -50); + } + + kill_message = lv_label_create(scr, NULL); + lv_obj_set_style(kill_message, &tft_style_label_rel); + lv_label_set_text(kill_message, "PRINTER HALTED"); + lv_obj_align(kill_message, NULL, LV_ALIGN_CENTER, 0, -10); + + reset_tips = lv_label_create(scr, NULL); + lv_obj_set_style(reset_tips, &tft_style_label_rel); + lv_label_set_text(reset_tips, "Please Reset"); + lv_obj_align(reset_tips, NULL, LV_ALIGN_CENTER, 0, 30); + + lv_task_handler(); + #endif + + SPI_TFT.LCD_clear(0x0000); + if (msg) disp_string((TFT_WIDTH - strlen(msg) * 16) / 2, 100, msg, 0xFFFF, 0x0000); + disp_string((TFT_WIDTH - strlen("PRINTER HALTED") * 16) / 2, 140, "PRINTER HALTED", 0xFFFF, 0x0000); + disp_string((TFT_WIDTH - strlen("Please Reset") * 16) / 2, 180, "Please Reset", 0xFFFF, 0x0000); +} + +void lv_clear_error_message() { lv_obj_del(scr); } + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_error_message.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_error_message.h new file mode 100644 index 000000000000..8f64d67f93da --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_error_message.h @@ -0,0 +1,38 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +#ifndef PGM_P + #define PGM_P const char * +#endif + +extern void lv_draw_error_message(PGM_P const msg); +extern void lv_clear_error_message(); + +//extern void disp_temp_ready_print(); +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_extrusion.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_extrusion.cpp new file mode 100644 index 000000000000..543202067f59 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_extrusion.cpp @@ -0,0 +1,403 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" +//#include "../lvgl/src/lv_objx/lv_imgbtn.h" +//#include "../lvgl/src/lv_objx/lv_img.h" +//#include "../lvgl/src/lv_core/lv_disp.h" +//#include "../lvgl/src/lv_core/lv_refr.h" + +#include "../../../../MarlinCore.h" +#include "../../../../module/temperature.h" +#include "../../../../gcode/queue.h" + +static lv_obj_t * scr; +extern lv_group_t* g; +static lv_obj_t * buttoType, *buttonStep, *buttonSpeed; +static lv_obj_t *labelType; +static lv_obj_t *labelStep; +static lv_obj_t *labelSpeed; +static lv_obj_t * tempText; +static lv_obj_t * ExtruText; + +#define ID_E_ADD 1 +#define ID_E_DEC 2 +#define ID_E_TYPE 3 +#define ID_E_STEP 4 +#define ID_E_SPEED 5 +#define ID_E_RETURN 6 + +static int32_t extructAmount; + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_E_ADD: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius >= EXTRUDE_MINTEMP) { + queue.enqueue_now_P(PSTR("G91")); + ZERO(public_buf_l); + sprintf_P((char *)public_buf_l, PSTR("G1 E%d F%d"), uiCfg.extruStep, 60 * uiCfg.extruSpeed); + queue.enqueue_one_now(public_buf_l); + queue.enqueue_now_P(PSTR("G90")); + extructAmount += uiCfg.extruStep; + disp_extru_amount(); + } + } + break; + case ID_E_DEC: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius >= EXTRUDE_MINTEMP) { + queue.enqueue_now_P(PSTR("G91")); + ZERO(public_buf_l); + sprintf_P((char *)public_buf_l, PSTR("G1 E%d F%d"), 0 - uiCfg.extruStep, 60 * uiCfg.extruSpeed); + queue.enqueue_one_now(public_buf_l); + queue.enqueue_now_P(PSTR("G90")); + extructAmount -= uiCfg.extruStep; + disp_extru_amount(); + } + } + break; + case ID_E_TYPE: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (ENABLED(HAS_MULTI_EXTRUDER)) { + if (uiCfg.curSprayerChoose == 0) { + uiCfg.curSprayerChoose = 1; + queue.inject_P(PSTR("T1")); + } + else { + uiCfg.curSprayerChoose = 0; + queue.inject_P(PSTR("T0")); + } + } + else + uiCfg.curSprayerChoose = 0; + + extructAmount = 0; + disp_hotend_temp(); + disp_ext_type(); + disp_extru_amount(); + } + break; + case ID_E_STEP: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + switch (abs(uiCfg.extruStep)) { + case 1: uiCfg.extruStep = 5; break; + case 5: uiCfg.extruStep = 10; break; + case 10: uiCfg.extruStep = 1; break; + default: break; + } + disp_ext_step(); + } + break; + case ID_E_SPEED: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + switch (uiCfg.extruSpeed) { + case 1: uiCfg.extruSpeed = 10; break; + case 10: uiCfg.extruSpeed = 20; break; + case 20: uiCfg.extruSpeed = 1; break; + default: break; + } + disp_ext_speed(); + } + break; + case ID_E_RETURN: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + clear_cur_ui(); + draw_return_ui(); + } + break; + } +} + +void lv_draw_extrusion(void) { + lv_obj_t *buttonAdd, *buttonDec, *buttonBack; + + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != EXTRUSION_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = EXTRUSION_UI; + } + disp_state = EXTRUSION_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, creat_title_text()); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + // Create image buttons + buttonAdd = lv_imgbtn_create(scr, NULL); + buttonDec = lv_imgbtn_create(scr, NULL); + buttoType = lv_imgbtn_create(scr, NULL); + buttonStep = lv_imgbtn_create(scr, NULL); + buttonSpeed = lv_imgbtn_create(scr, NULL); + buttonBack = lv_imgbtn_create(scr, NULL); + + lv_obj_set_event_cb_mks(buttonAdd, event_handler, ID_E_ADD, NULL, 0); + lv_imgbtn_set_src(buttonAdd, LV_BTN_STATE_REL, "F:/bmp_in.bin"); + lv_imgbtn_set_src(buttonAdd, LV_BTN_STATE_PR, "F:/bmp_in.bin"); + lv_imgbtn_set_style(buttonAdd, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonAdd, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_obj_clear_protect(buttonAdd, LV_PROTECT_FOLLOW); + + #if 1 + lv_obj_set_event_cb_mks(buttonDec, event_handler, ID_E_DEC, NULL, 0); + lv_imgbtn_set_src(buttonDec, LV_BTN_STATE_REL, "F:/bmp_out.bin"); + lv_imgbtn_set_src(buttonDec, LV_BTN_STATE_PR, "F:/bmp_out.bin"); + lv_imgbtn_set_style(buttonDec, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonDec, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttoType, event_handler, ID_E_TYPE, NULL, 0); + lv_imgbtn_set_style(buttoType, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttoType, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonStep, event_handler, ID_E_STEP, NULL, 0); + lv_imgbtn_set_style(buttonStep, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonStep, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonSpeed, event_handler, ID_E_SPEED, NULL, 0); + lv_imgbtn_set_style(buttonSpeed, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonSpeed, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_E_RETURN, NULL, 0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_return.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_return.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + #endif + + lv_obj_set_pos(buttonAdd, INTERVAL_V, titleHeight); + lv_obj_set_pos(buttonDec, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight); + lv_obj_set_pos(buttoType, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonStep, BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonSpeed, BTN_X_PIXEL * 2 + INTERVAL_V * 3, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonBack, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + + // Create labels on the image buttons + lv_btn_set_layout(buttonAdd, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonDec, LV_LAYOUT_OFF); + lv_btn_set_layout(buttoType, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonStep, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonSpeed, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + + lv_obj_t *labelAdd = lv_label_create(buttonAdd, NULL); + lv_obj_t *labelDec = lv_label_create(buttonDec, NULL); + labelType = lv_label_create(buttoType, NULL); + labelStep = lv_label_create(buttonStep, NULL); + labelSpeed = lv_label_create(buttonSpeed, NULL); + lv_obj_t *label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(labelAdd, extrude_menu.in); + lv_obj_align(labelAdd, buttonAdd, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelDec, extrude_menu.out); + lv_obj_align(labelDec, buttonDec, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonAdd); + lv_group_add_obj(g, buttonDec); + lv_group_add_obj(g, buttoType); + lv_group_add_obj(g, buttonStep); + lv_group_add_obj(g, buttonSpeed); + lv_group_add_obj(g, buttonBack); + } + #endif + + disp_ext_type(); + disp_ext_step(); + disp_ext_speed(); + + tempText = lv_label_create(scr, NULL); + lv_obj_set_style(tempText, &tft_style_label_rel); + disp_hotend_temp(); + + ExtruText = lv_label_create(scr, NULL); + lv_obj_set_style(ExtruText, &tft_style_label_rel); + disp_extru_amount(); +} + +void disp_ext_type() { + if (uiCfg.curSprayerChoose == 1) { + lv_imgbtn_set_src(buttoType, LV_BTN_STATE_REL, "F:/bmp_extru2.bin"); + lv_imgbtn_set_src(buttoType, LV_BTN_STATE_PR, "F:/bmp_extru2.bin"); + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(labelType, extrude_menu.ext2); + lv_obj_align(labelType, buttoType, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + } + else { + lv_imgbtn_set_src(buttoType, LV_BTN_STATE_REL, "F:/bmp_extru1.bin"); + lv_imgbtn_set_src(buttoType, LV_BTN_STATE_PR, "F:/bmp_extru1.bin"); + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(labelType, extrude_menu.ext1); + lv_obj_align(labelType, buttoType, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + } +} + +void disp_ext_speed() { + if (uiCfg.extruSpeed == 20) { + lv_imgbtn_set_src(buttonSpeed, LV_BTN_STATE_REL, "F:/bmp_speed_high.bin"); + lv_imgbtn_set_src(buttonSpeed, LV_BTN_STATE_PR, "F:/bmp_speed_high.bin"); + } + else if (uiCfg.extruSpeed == 1) { + lv_imgbtn_set_src(buttonSpeed, LV_BTN_STATE_REL, "F:/bmp_speed_slow.bin"); + lv_imgbtn_set_src(buttonSpeed, LV_BTN_STATE_PR, "F:/bmp_speed_slow.bin"); + } + else { + lv_imgbtn_set_src(buttonSpeed, LV_BTN_STATE_REL, "F:/bmp_speed_normal.bin"); + lv_imgbtn_set_src(buttonSpeed, LV_BTN_STATE_PR, "F:/bmp_speed_normal.bin"); + } + + if (gCfgItems.multiple_language != 0) { + if (uiCfg.extruSpeed == 20) { + lv_label_set_text(labelSpeed, extrude_menu.high); + lv_obj_align(labelSpeed, buttonSpeed, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + else if (uiCfg.extruSpeed == 1) { + lv_label_set_text(labelSpeed, extrude_menu.low); + lv_obj_align(labelSpeed, buttonSpeed, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + else { + lv_label_set_text(labelSpeed, extrude_menu.normal); + lv_obj_align(labelSpeed, buttonSpeed, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + } +} + +void disp_hotend_temp() { + char buf[20] = {0}; + public_buf_l[0] = '\0'; + strcat(public_buf_l, extrude_menu.temper_text); + sprintf(buf, extrude_menu.temp_value, (int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius, (int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].target); + strcat(public_buf_l, buf); + lv_label_set_text(tempText, public_buf_l); + lv_obj_align(tempText, NULL, LV_ALIGN_CENTER, 0, -50); +} + +void disp_extru_amount() { + char buf1[10] = {0}; + + public_buf_l[0] = '\0'; + + if (extructAmount < 999 && extructAmount > -99) { + sprintf(buf1, extrude_menu.count_value_mm, extructAmount); + if (uiCfg.curSprayerChoose < 1) + strcat(public_buf_l, extrude_menu.ext1); + else + strcat(public_buf_l, extrude_menu.ext2); + strcat(public_buf_l, buf1); + } + else if (extructAmount < 9999 && extructAmount > -999) { + sprintf(buf1, extrude_menu.count_value_cm, extructAmount / 10); + if (uiCfg.curSprayerChoose < 1) + strcat(public_buf_l, extrude_menu.ext1); + else + strcat(public_buf_l, extrude_menu.ext2); + strcat(public_buf_l, buf1); + } + else { + sprintf(buf1, extrude_menu.count_value_m, extructAmount / 1000); + if (uiCfg.curSprayerChoose < 1) + strcat(public_buf_l, extrude_menu.ext1); + else + strcat(public_buf_l, extrude_menu.ext2); + strcat(public_buf_l, buf1); + } + + lv_label_set_text(ExtruText, public_buf_l); + lv_obj_align(ExtruText, NULL, LV_ALIGN_CENTER, 0, -75); +} + +void disp_ext_step() { + if (uiCfg.extruStep == 1) { + lv_imgbtn_set_src(buttonStep, LV_BTN_STATE_REL, "F:/bmp_step1_mm.bin"); + lv_imgbtn_set_src(buttonStep, LV_BTN_STATE_PR, "F:/bmp_step1_mm.bin"); + } + else if (uiCfg.extruStep == 5) { + lv_imgbtn_set_src(buttonStep, LV_BTN_STATE_REL, "F:/bmp_step5_mm.bin"); + lv_imgbtn_set_src(buttonStep, LV_BTN_STATE_PR, "F:/bmp_step5_mm.bin"); + } + else if (uiCfg.extruStep == 10) { + lv_imgbtn_set_src(buttonStep, LV_BTN_STATE_REL, "F:/bmp_step10_mm.bin"); + lv_imgbtn_set_src(buttonStep, LV_BTN_STATE_PR, "F:/bmp_step10_mm.bin"); + } + + if (gCfgItems.multiple_language != 0) { + if (uiCfg.extruStep == 1) { + lv_label_set_text(labelStep, extrude_menu.step_1mm); + lv_obj_align(labelStep, buttonStep, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + else if (uiCfg.extruStep == 5) { + lv_label_set_text(labelStep, extrude_menu.step_5mm); + lv_obj_align(labelStep, buttonStep, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + else if (uiCfg.extruStep == 10) { + lv_label_set_text(labelStep, extrude_menu.step_10mm); + lv_obj_align(labelStep, buttonStep, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + } +} + +void lv_clear_extrusion() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_extrusion.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_extrusion.h new file mode 100644 index 000000000000..576cc6c66c15 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_extrusion.h @@ -0,0 +1,39 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_extrusion(void); +extern void lv_clear_extrusion(); +extern void disp_ext_type(); +extern void disp_ext_step(); +extern void disp_ext_speed(); +extern void disp_hotend_temp(); +extern void disp_extru_amount(); + +//extern void disp_temp_ready_print(); +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_fan.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_fan.cpp new file mode 100644 index 000000000000..8cdc14964f4b --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_fan.cpp @@ -0,0 +1,265 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "../../../../MarlinCore.h" +#include "lv_conf.h" +//#include "../lvgl/src/lv_objx/lv_imgbtn.h" +//#include "../lvgl/src/lv_objx/lv_img.h" +//#include "../lvgl/src/lv_core/lv_disp.h" +//#include "../lvgl/src/lv_core/lv_refr.h" +#include "../../../../../Configuration.h" +#include "draw_ui.h" +#include "../../../../module/temperature.h" +#include "../../../../gcode/queue.h" +#include "../../../../gcode/gcode.h" + +extern lv_group_t * g; +static lv_obj_t * scr; +static lv_obj_t * fanText; + +#define ID_F_ADD 1 +#define ID_F_DEC 2 +#define ID_F_HIGH 3 +#define ID_F_MID 4 +#define ID_F_OFF 5 +#define ID_F_RETURN 6 + +static uint8_t fanSpeed; + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_F_ADD: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (fanSpeed + 1 <= 255) { + fanSpeed++; + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("M106 S%d"), fanSpeed); + gcode.process_subcommands_now(public_buf_l); + } + } + break; + case ID_F_DEC: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (fanSpeed > 0) { + fanSpeed--; + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("M106 S%d"), fanSpeed); + gcode.process_subcommands_now(public_buf_l); + } + } + + break; + case ID_F_HIGH: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + gcode.process_subcommands_now_P(PSTR("M106 S255")); + } + break; + case ID_F_MID: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + gcode.process_subcommands_now_P(PSTR("M106 S127")); + } + break; + case ID_F_OFF: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + gcode.process_subcommands_now_P(PSTR("M107")); + } + break; + case ID_F_RETURN: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + clear_cur_ui(); + draw_return_ui(); + } + break; + } +} + +void lv_draw_fan(void) { + lv_obj_t *buttonAdd, *buttonDec, *buttonHigh, *buttonMid; + lv_obj_t *buttonOff, *buttonBack; + + #if HAS_FAN + fanSpeed = thermalManager.fan_speed[0]; + #endif + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != FAN_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = FAN_UI; + } + disp_state = FAN_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, creat_title_text()); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + // Create an Image button + buttonAdd = lv_imgbtn_create(scr, NULL); + buttonDec = lv_imgbtn_create(scr, NULL); + buttonHigh = lv_imgbtn_create(scr, NULL); + buttonMid = lv_imgbtn_create(scr, NULL); + buttonOff = lv_imgbtn_create(scr, NULL); + buttonBack = lv_imgbtn_create(scr, NULL); + + lv_obj_set_event_cb_mks(buttonAdd, event_handler, ID_F_ADD, NULL, 0); + lv_imgbtn_set_src(buttonAdd, LV_BTN_STATE_REL, "F:/bmp_Add.bin"); + lv_imgbtn_set_src(buttonAdd, LV_BTN_STATE_PR, "F:/bmp_Add.bin"); + lv_imgbtn_set_style(buttonAdd, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonAdd, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_obj_clear_protect(buttonAdd, LV_PROTECT_FOLLOW); + + #if 1 + lv_obj_set_event_cb_mks(buttonDec, event_handler, ID_F_DEC, NULL, 0); + lv_imgbtn_set_src(buttonDec, LV_BTN_STATE_REL, "F:/bmp_Dec.bin"); + lv_imgbtn_set_src(buttonDec, LV_BTN_STATE_PR, "F:/bmp_Dec.bin"); + lv_imgbtn_set_style(buttonDec, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonDec, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonHigh, event_handler,ID_F_HIGH, NULL,0); + lv_imgbtn_set_src(buttonHigh, LV_BTN_STATE_REL, "F:/bmp_speed255.bin"); + lv_imgbtn_set_src(buttonHigh, LV_BTN_STATE_PR, "F:/bmp_speed255.bin"); + lv_imgbtn_set_style(buttonHigh, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonHigh, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonMid, event_handler,ID_F_MID, NULL,0); + lv_imgbtn_set_src(buttonMid, LV_BTN_STATE_REL, "F:/bmp_speed127.bin"); + lv_imgbtn_set_src(buttonMid, LV_BTN_STATE_PR, "F:/bmp_speed127.bin"); + lv_imgbtn_set_style(buttonMid, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonMid, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonOff, event_handler,ID_F_OFF, NULL,0); + lv_imgbtn_set_src(buttonOff, LV_BTN_STATE_REL, "F:/bmp_speed0.bin"); + lv_imgbtn_set_src(buttonOff, LV_BTN_STATE_PR, "F:/bmp_speed0.bin"); + lv_imgbtn_set_style(buttonOff, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonOff, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonBack, event_handler,ID_F_RETURN, NULL,0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_return.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_return.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + + #endif + + lv_obj_set_pos(buttonAdd, INTERVAL_V, titleHeight); + lv_obj_set_pos(buttonDec, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight); + lv_obj_set_pos(buttonHigh, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonMid, BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonOff, BTN_X_PIXEL * 2 + INTERVAL_V * 3, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonBack, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + + // Create labels on the image buttons + lv_btn_set_layout(buttonAdd, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonDec, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonHigh, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonMid, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonOff, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + + lv_obj_t *labelAdd = lv_label_create(buttonAdd, NULL); + lv_obj_t *labelDec = lv_label_create(buttonDec, NULL); + lv_obj_t *labelHigh = lv_label_create(buttonHigh, NULL); + lv_obj_t *labelMid = lv_label_create(buttonMid, NULL); + lv_obj_t *labelOff = lv_label_create(buttonOff, NULL); + lv_obj_t *label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(labelAdd, fan_menu.add); + lv_obj_align(labelAdd, buttonAdd, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelDec, fan_menu.dec); + lv_obj_align(labelDec, buttonDec, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelHigh, fan_menu.full); + lv_obj_align(labelHigh, buttonHigh, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelMid, fan_menu.half); + lv_obj_align(labelMid, buttonMid, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelOff, fan_menu.off); + lv_obj_align(labelOff, buttonOff, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonAdd); + lv_group_add_obj(g, buttonDec); + lv_group_add_obj(g, buttonHigh); + lv_group_add_obj(g, buttonMid); + lv_group_add_obj(g, buttonOff); + lv_group_add_obj(g, buttonBack); + } + #endif + + fanText = lv_label_create(scr, NULL); + lv_obj_set_style(fanText, &tft_style_label_rel); + disp_fan_value(); +} + +void disp_fan_value() { + char buf1[10] = {0}; + public_buf_l[0] = '\0'; + strcat(public_buf_l, fan_menu.state); + strcat_P(public_buf_l, PSTR(": ")); + sprintf_P(buf1, PSTR("%3d"), thermalManager.fan_speed[0]); + strcat(public_buf_l, buf1); + lv_label_set_text(fanText, public_buf_l); + lv_obj_align(fanText, NULL, LV_ALIGN_CENTER, 0, -65); +} + +void lv_clear_fan() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_fan.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_fan.h new file mode 100644 index 000000000000..602d02c6c044 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_fan.h @@ -0,0 +1,35 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_fan(void); +extern void lv_clear_fan(); +extern void disp_fan_value(); + +//extern void disp_temp_ready_print(); +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_change.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_change.cpp new file mode 100644 index 000000000000..83f9e536774d --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_change.cpp @@ -0,0 +1,270 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" + +#include "../../../../MarlinCore.h" +#include "../../../../module/temperature.h" +#include "../../../../gcode/queue.h" +#include "../../../../gcode/gcode.h" +#include "../../../../module/motion.h" +#include "../../../../module/planner.h" + +extern lv_group_t * g; +static lv_obj_t * scr; +static lv_obj_t *buttoType; +static lv_obj_t *labelType; +static lv_obj_t * tempText1; + +#define ID_FILAMNT_IN 1 +#define ID_FILAMNT_OUT 2 +#define ID_FILAMNT_TYPE 3 +#define ID_FILAMNT_RETURN 4 + +extern feedRate_t feedrate_mm_s; + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_FILAMNT_IN: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.filament_load_heat_flg = 1; + if ((abs(thermalManager.temp_hotend[uiCfg.curSprayerChoose].target - thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius) <= 1) + || (gCfgItems.filament_limit_temper <= thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius)) { + lv_clear_filament_change(); + lv_draw_dialog(DIALOG_TYPE_FILAMENT_HEAT_LOAD_COMPLETED); + } + else { + lv_clear_filament_change(); + lv_draw_dialog(DIALOG_TYPE_FILAMENT_LOAD_HEAT); + if (thermalManager.temp_hotend[uiCfg.curSprayerChoose].target < gCfgItems.filament_limit_temper) { + thermalManager.temp_hotend[uiCfg.curSprayerChoose].target = gCfgItems.filament_limit_temper; + thermalManager.start_watching_hotend(uiCfg.curSprayerChoose); + } + } + } + break; + case ID_FILAMNT_OUT: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.filament_unload_heat_flg=1; + if ((thermalManager.temp_hotend[uiCfg.curSprayerChoose].target > 0) + && ((abs((int)((int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].target - thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius)) <= 1) + || ((int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius >= gCfgItems.filament_limit_temper)) + ) { + lv_clear_filament_change(); + lv_draw_dialog(DIALOG_TYPE_FILAMENT_HEAT_UNLOAD_COMPLETED); + } + else { + lv_clear_filament_change(); + lv_draw_dialog(DIALOG_TYPE_FILAMENT_UNLOAD_HEAT); + if (thermalManager.temp_hotend[uiCfg.curSprayerChoose].target < gCfgItems.filament_limit_temper) { + thermalManager.temp_hotend[uiCfg.curSprayerChoose].target = gCfgItems.filament_limit_temper; + thermalManager.start_watching_hotend(uiCfg.curSprayerChoose); + } + filament_sprayer_temp(); + } + } + break; + case ID_FILAMNT_TYPE: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + #if HAS_MULTI_EXTRUDER + if (uiCfg.curSprayerChoose == 0) + uiCfg.curSprayerChoose = 1; + else if (uiCfg.curSprayerChoose == 1) + uiCfg.curSprayerChoose = 0; + #endif + disp_filament_type(); + } + break; + case ID_FILAMNT_RETURN: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + #if HAS_MULTI_EXTRUDER + if (uiCfg.print_state != IDLE && uiCfg.print_state != REPRINTED) + gcode.process_subcommands_now_P(uiCfg.curSprayerChoose_bak == 1 ? PSTR("T1") : PSTR("T0")); + #endif + feedrate_mm_s = (float)uiCfg.moveSpeed_bak; + if (uiCfg.print_state == PAUSED) + planner.set_e_position_mm((destination.e = current_position.e = uiCfg.current_e_position_bak)); + //current_position.e = destination.e = uiCfg.current_e_position_bak; + thermalManager.temp_hotend[uiCfg.curSprayerChoose].target = uiCfg.desireSprayerTempBak; + + clear_cur_ui(); + draw_return_ui(); + } + break; + } +} + +void lv_draw_filament_change(void) { + lv_obj_t *buttonIn, *buttonOut; + lv_obj_t *buttonBack; + + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != FILAMENTCHANGE_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = FILAMENTCHANGE_UI; + } + disp_state = FILAMENTCHANGE_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, creat_title_text()); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + // Create an Image button + buttonIn = lv_imgbtn_create(scr, NULL); + buttonOut = lv_imgbtn_create(scr, NULL); + buttoType = lv_imgbtn_create(scr, NULL); + buttonBack = lv_imgbtn_create(scr, NULL); + + lv_obj_set_event_cb_mks(buttonIn, event_handler, ID_FILAMNT_IN, NULL, 0); + lv_imgbtn_set_src(buttonIn, LV_BTN_STATE_REL, "F:/bmp_in.bin"); + lv_imgbtn_set_src(buttonIn, LV_BTN_STATE_PR, "F:/bmp_in.bin"); + lv_imgbtn_set_style(buttonIn, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonIn, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_obj_clear_protect(buttonIn, LV_PROTECT_FOLLOW); + + lv_obj_set_event_cb_mks(buttonOut, event_handler, ID_FILAMNT_OUT, NULL, 0); + lv_imgbtn_set_src(buttonOut, LV_BTN_STATE_REL, "F:/bmp_out.bin"); + lv_imgbtn_set_src(buttonOut, LV_BTN_STATE_PR, "F:/bmp_out.bin"); + lv_imgbtn_set_style(buttonOut, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonOut, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttoType, event_handler, ID_FILAMNT_TYPE, NULL, 0); + lv_imgbtn_set_style(buttoType, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttoType, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_FILAMNT_RETURN, NULL, 0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_return.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_return.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_pos(buttonIn, INTERVAL_V, titleHeight); + lv_obj_set_pos(buttonOut, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight); + lv_obj_set_pos(buttoType, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonBack, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + + // Create labels on the image buttons + lv_btn_set_layout(buttonIn, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonOut, LV_LAYOUT_OFF); + lv_btn_set_layout(buttoType, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + + lv_obj_t *labelIn = lv_label_create(buttonIn, NULL); + lv_obj_t *labelOut = lv_label_create(buttonOut, NULL); + labelType = lv_label_create(buttoType, NULL); + lv_obj_t *label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(labelIn, filament_menu.in); + lv_obj_align(labelIn, buttonIn, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelOut, filament_menu.out); + lv_obj_align(labelOut, buttonOut, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonIn); + lv_group_add_obj(g, buttonOut); + lv_group_add_obj(g, buttoType); + lv_group_add_obj(g, buttonBack); + } + #endif + + disp_filament_type(); + + tempText1 = lv_label_create(scr, NULL); + lv_obj_set_style(tempText1, &tft_style_label_rel); + disp_filament_temp(); +} + +void disp_filament_type() { + if (uiCfg.curSprayerChoose == 1) { + lv_imgbtn_set_src(buttoType, LV_BTN_STATE_REL, "F:/bmp_extru2.bin"); + lv_imgbtn_set_src(buttoType, LV_BTN_STATE_PR, "F:/bmp_extru2.bin"); + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(labelType, preheat_menu.ext2); + lv_obj_align(labelType, buttoType, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + } + else { + lv_imgbtn_set_src(buttoType, LV_BTN_STATE_REL, "F:/bmp_extru1.bin"); + lv_imgbtn_set_src(buttoType, LV_BTN_STATE_PR, "F:/bmp_extru1.bin"); + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(labelType, preheat_menu.ext1); + lv_obj_align(labelType, buttoType, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + } +} + +void disp_filament_temp() { + char buf[20] = {0}; + + public_buf_l[0] = '\0'; + + if (uiCfg.curSprayerChoose < 1) + strcat(public_buf_l, preheat_menu.ext1); + else + strcat(public_buf_l, preheat_menu.ext2); + sprintf(buf, preheat_menu.value_state, (int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius, (int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].target); + + strcat_P(public_buf_l, PSTR(": ")); + strcat(public_buf_l, buf); + lv_label_set_text(tempText1, public_buf_l); + lv_obj_align(tempText1, NULL, LV_ALIGN_CENTER, 0, -50); +} + +void lv_clear_filament_change() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_change.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_change.h new file mode 100644 index 000000000000..b0068f7f0f32 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_change.h @@ -0,0 +1,36 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_filament_change(void); +extern void lv_clear_filament_change(); +extern void disp_filament_type(); +extern void disp_filament_temp(); + +//extern void disp_temp_ready_print(); +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_settings.cpp new file mode 100644 index 000000000000..06ab35f3f0e5 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_settings.cpp @@ -0,0 +1,329 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" + +#include "../../../../MarlinCore.h" +#include "../../../../module/planner.h" + +extern lv_group_t * g; +static lv_obj_t * scr; + +#define ID_FILAMENT_SET_RETURN 1 +#define ID_FILAMENT_SET_IN_LENGTH 2 +#define ID_FILAMENT_SET_IN_SPEED 3 +#define ID_FILAMENT_SET_OUT_LENGTH 4 +#define ID_FILAMENT_SET_OUT_SPEED 5 +#define ID_FILAMENT_SET_TEMP 6 +#define ID_FILAMENT_SET_DOWN 12 +#define ID_FILAMENT_SET_UP 13 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_FILAMENT_SET_RETURN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.para_ui_page = 0; + lv_clear_filament_settings(); + draw_return_ui(); + } + break; + case ID_FILAMENT_SET_IN_LENGTH: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = load_length; + lv_clear_filament_settings(); + lv_draw_number_key(); + } + break; + case ID_FILAMENT_SET_IN_SPEED: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = load_speed; + lv_clear_filament_settings(); + lv_draw_number_key(); + } + break; + case ID_FILAMENT_SET_OUT_LENGTH: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = unload_length; + lv_clear_filament_settings(); + lv_draw_number_key(); + } + break; + case ID_FILAMENT_SET_OUT_SPEED: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = unload_speed; + lv_clear_filament_settings(); + lv_draw_number_key(); + } + break; + case ID_FILAMENT_SET_TEMP: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = filament_temp; + lv_clear_filament_settings(); + lv_draw_number_key(); + } + break; + case ID_FILAMENT_SET_UP: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.para_ui_page = 0; + lv_clear_filament_settings(); + lv_draw_filament_settings(); + } + break; + case ID_FILAMENT_SET_DOWN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.para_ui_page = 1; + lv_clear_filament_settings(); + lv_draw_filament_settings(); + } + break; + } +} + +void lv_draw_filament_settings(void) { + lv_obj_t *buttonBack = NULL, *label_Back = NULL, *buttonTurnPage = NULL, *labelTurnPage = NULL; + lv_obj_t *labelInLengthText = NULL, *buttonInLengthValue = NULL, *labelInLengthValue = NULL; + lv_obj_t *labelInSpeedText = NULL, *buttonInSpeedValue = NULL, *labelInSpeedValue = NULL; + lv_obj_t *labelOutLengthText = NULL, *buttonOutLengthValue = NULL, *labelOutLengthValue = NULL; + lv_obj_t *labelOutSpeedText = NULL, *buttonOutSpeedValue = NULL, *labelOutSpeedValue = NULL; + lv_obj_t *labelTemperText = NULL, *buttonTemperValue = NULL, *labelTemperValue = NULL; + lv_obj_t * line1 = NULL, * line2 = NULL, * line3 = NULL, * line4 = NULL; + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != FILAMENT_SETTINGS_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = FILAMENT_SETTINGS_UI; + } + disp_state = FILAMENT_SETTINGS_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, machine_menu.FilamentConfTitle); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + if (uiCfg.para_ui_page != 1) { + labelInLengthText = lv_label_create(scr, NULL); + lv_obj_set_style(labelInLengthText, &tft_style_label_rel); + lv_obj_set_pos(labelInLengthText, PARA_UI_POS_X, PARA_UI_POS_Y + 10); + lv_label_set_text(labelInLengthText, machine_menu.InLength); + + buttonInLengthValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonInLengthValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y + PARA_UI_VALUE_V_2); + lv_obj_set_size(buttonInLengthValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonInLengthValue, event_handler, ID_FILAMENT_SET_IN_LENGTH, NULL, 0); + lv_btn_set_style(buttonInLengthValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonInLengthValue, LV_BTN_STYLE_PR, &style_para_value); + labelInLengthValue = lv_label_create(buttonInLengthValue, NULL); + + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1, line_points[0]); + + labelInSpeedText = lv_label_create(scr, NULL); + lv_obj_set_style(labelInSpeedText, &tft_style_label_rel); + lv_obj_set_pos(labelInSpeedText, PARA_UI_POS_X, PARA_UI_POS_Y * 2 + 10); + lv_label_set_text(labelInSpeedText, machine_menu.InSpeed); + + buttonInSpeedValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonInSpeedValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 2 + PARA_UI_VALUE_V_2); + lv_obj_set_size(buttonInSpeedValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonInSpeedValue, event_handler, ID_FILAMENT_SET_IN_SPEED, NULL, 0); + lv_btn_set_style(buttonInSpeedValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonInSpeedValue, LV_BTN_STYLE_PR, &style_para_value); + labelInSpeedValue = lv_label_create(buttonInSpeedValue, NULL); + + line2 = lv_line_create(scr, NULL); + lv_ex_line(line2, line_points[1]); + + labelOutLengthText = lv_label_create(scr, NULL); + lv_obj_set_style(labelOutLengthText, &tft_style_label_rel); + lv_obj_set_pos(labelOutLengthText, PARA_UI_POS_X, PARA_UI_POS_Y * 3 + 6); + lv_label_set_text(labelOutLengthText, machine_menu.OutLength); + + buttonOutLengthValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonOutLengthValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 3 + PARA_UI_VALUE_V_2); + lv_obj_set_size(buttonOutLengthValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonOutLengthValue, event_handler, ID_FILAMENT_SET_OUT_LENGTH, NULL, 0); + lv_btn_set_style(buttonOutLengthValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonOutLengthValue, LV_BTN_STYLE_PR, &style_para_value); + labelOutLengthValue = lv_label_create(buttonOutLengthValue, NULL); + + line3 = lv_line_create(scr, NULL); + lv_ex_line(line3, line_points[2]); + + labelOutSpeedText = lv_label_create(scr, NULL); + lv_obj_set_style(labelOutSpeedText, &tft_style_label_rel); + lv_obj_set_pos(labelOutSpeedText, PARA_UI_POS_X, PARA_UI_POS_Y * 4 + 10); + lv_label_set_text(labelOutSpeedText, machine_menu.OutSpeed); + + buttonOutSpeedValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonOutSpeedValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 4 + PARA_UI_VALUE_V_2); + lv_obj_set_size(buttonOutSpeedValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonOutSpeedValue, event_handler, ID_FILAMENT_SET_OUT_SPEED, NULL, 0); + lv_btn_set_style(buttonOutSpeedValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonOutSpeedValue, LV_BTN_STYLE_PR, &style_para_value); + labelOutSpeedValue = lv_label_create(buttonOutSpeedValue, NULL); + + line4 = lv_line_create(scr, NULL); + lv_ex_line(line4, line_points[3]); + + buttonTurnPage = lv_btn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonTurnPage, event_handler, ID_FILAMENT_SET_DOWN, NULL, 0); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_REL, &style_para_back); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_PR, &style_para_back); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonInLengthValue); + lv_group_add_obj(g, buttonInSpeedValue); + lv_group_add_obj(g, buttonOutLengthValue); + lv_group_add_obj(g, buttonOutSpeedValue); + lv_group_add_obj(g, buttonTurnPage); + } + #endif + } + else { + labelTemperText = lv_label_create(scr, NULL); + lv_obj_set_style(labelTemperText, &tft_style_label_rel); + lv_obj_set_pos(labelTemperText, PARA_UI_POS_X, PARA_UI_POS_Y + 10); + lv_label_set_text(labelTemperText, machine_menu.FilamentTemperature); + + buttonTemperValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonTemperValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y + PARA_UI_VALUE_V_2); + lv_obj_set_size(buttonTemperValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonTemperValue, event_handler, ID_FILAMENT_SET_TEMP, NULL, 0); + lv_btn_set_style(buttonTemperValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonTemperValue, LV_BTN_STYLE_PR, &style_para_value); + labelTemperValue = lv_label_create(buttonTemperValue, NULL); + + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1, line_points[0]); + + buttonTurnPage = lv_btn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonTurnPage, event_handler, ID_FILAMENT_SET_UP, NULL, 0); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_REL, &style_para_back); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_PR, &style_para_back); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonTemperValue); + lv_group_add_obj(g, buttonTurnPage); + } + #endif + } + + lv_obj_set_pos(buttonTurnPage, PARA_UI_TURN_PAGE_POS_X, PARA_UI_TURN_PAGE_POS_Y); + lv_obj_set_size(buttonTurnPage, PARA_UI_BACK_BTN_X_SIZE, PARA_UI_BACK_BTN_Y_SIZE); + labelTurnPage = lv_label_create(buttonTurnPage, NULL); + + buttonBack = lv_btn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_FILAMENT_SET_RETURN, NULL, 0); + lv_btn_set_style(buttonBack, LV_BTN_STYLE_REL, &style_para_back); + lv_btn_set_style(buttonBack, LV_BTN_STYLE_PR, &style_para_back); + lv_obj_set_pos(buttonBack, PARA_UI_BACL_POS_X, PARA_UI_BACL_POS_Y); + lv_obj_set_size(buttonBack, PARA_UI_BACK_BTN_X_SIZE, PARA_UI_BACK_BTN_Y_SIZE); + label_Back = lv_label_create(buttonBack, NULL); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonBack); + #endif + + if (gCfgItems.multiple_language != 0) { + if (uiCfg.para_ui_page != 1) { + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.filamentchange_load_length); + lv_label_set_text(labelInLengthValue, public_buf_l); + lv_obj_align(labelInLengthValue, buttonInLengthValue, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.filamentchange_load_speed); + lv_label_set_text(labelInSpeedValue, public_buf_l); + lv_obj_align(labelInSpeedValue, buttonInSpeedValue, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.filamentchange_unload_length); + lv_label_set_text(labelOutLengthValue, public_buf_l); + lv_obj_align(labelOutLengthValue, buttonOutLengthValue, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.filamentchange_unload_speed); + lv_label_set_text(labelOutSpeedValue, public_buf_l); + lv_obj_align(labelOutSpeedValue, buttonOutSpeedValue, LV_ALIGN_CENTER, 0, 0); + + lv_label_set_text(labelTurnPage, machine_menu.next); + lv_obj_align(labelTurnPage, buttonTurnPage, LV_ALIGN_CENTER, 0, 0); + } + else { + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.filament_limit_temper); + lv_label_set_text(labelTemperValue, public_buf_l); + lv_obj_align(labelTemperValue, buttonTemperValue, LV_ALIGN_CENTER, 0, 0); + + lv_label_set_text(labelTurnPage, machine_menu.previous); + lv_obj_align(labelTurnPage, buttonTurnPage, LV_ALIGN_CENTER, 0, 0); + } + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_CENTER, 0, 0); + } +} + +void lv_clear_filament_settings() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_settings.h new file mode 100644 index 000000000000..a5ae54289534 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_settings.h @@ -0,0 +1,33 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_filament_settings(void); +extern void lv_clear_filament_settings(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_home.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_home.cpp new file mode 100644 index 000000000000..22e05f0e00e5 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_home.cpp @@ -0,0 +1,252 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "../../../../MarlinCore.h" +#include "draw_ready_print.h" +#include "draw_set.h" +#include "lv_conf.h" +//#include "../lvgl/src/lv_objx/lv_imgbtn.h" +//#include "../lvgl/src/lv_objx/lv_img.h" +//#include "../lvgl/src/lv_core/lv_disp.h" +//#include "../lvgl/src/lv_core/lv_refr.h" +#include "draw_ui.h" +#include "../../../../gcode/queue.h" + +extern lv_group_t * g; +static lv_obj_t * scr; + +#define ID_H_ALL 1 +#define ID_H_X 2 +#define ID_H_Y 3 +#define ID_H_Z 4 +#define ID_H_RETURN 5 +#define ID_H_OFF_ALL 6 +#define ID_H_OFF_XY 7 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_H_ALL: + if (event == LV_EVENT_CLICKED) { + } + else if (event == LV_EVENT_RELEASED) { + queue.inject_P(PSTR("G28")); + } + break; + case ID_H_X: + if (event == LV_EVENT_CLICKED) { + } + else if (event == LV_EVENT_RELEASED) { + queue.inject_P(PSTR("G28 X0")); + } + break; + case ID_H_Y: + if (event == LV_EVENT_CLICKED) { + } + else if (event == LV_EVENT_RELEASED) { + queue.inject_P(PSTR("G28 Y0")); + } + break; + case ID_H_Z: + if (event == LV_EVENT_CLICKED) { + } + else if (event == LV_EVENT_RELEASED) { + queue.inject_P(PSTR("G28 Z0")); + } + break; + case ID_H_OFF_ALL: + if (event == LV_EVENT_CLICKED) { + } + else if (event == LV_EVENT_RELEASED) { + queue.inject_P(PSTR("M84")); + } + break; + case ID_H_OFF_XY: + if (event == LV_EVENT_CLICKED) { + } + else if (event == LV_EVENT_RELEASED) { + queue.inject_P(PSTR("M84 X Y")); + } + break; + case ID_H_RETURN: + if (event == LV_EVENT_CLICKED) { + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_home(); + lv_draw_tool(); + } + break; + } +} + +void lv_draw_home(void) { + lv_obj_t *buttonHomeAll, *buttonHomeX, *buttonHomeY, *buttonHomeZ; + lv_obj_t *buttonBack; + lv_obj_t *buttonOffAll, *buttonOffXY; + + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != ZERO_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = ZERO_UI; + } + disp_state = ZERO_UI; + + scr = lv_obj_create(NULL, NULL); + + //static lv_style_t tool_style; + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, creat_title_text()); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + // Create image buttons + //buttonWifi = lv_imgbtn_create(scr, NULL); + buttonHomeAll = lv_imgbtn_create(scr, NULL); + buttonHomeX = lv_imgbtn_create(scr, NULL); + //buttonContinue = lv_imgbtn_create(scr, NULL); + buttonHomeY = lv_imgbtn_create(scr, NULL); + buttonHomeZ = lv_imgbtn_create(scr, NULL); + buttonOffAll = lv_imgbtn_create(scr, NULL); + buttonOffXY = lv_imgbtn_create(scr, NULL); + buttonBack = lv_imgbtn_create(scr, NULL); + + #if 1 + lv_obj_set_event_cb_mks(buttonHomeAll, event_handler,ID_H_ALL, NULL,0); + lv_imgbtn_set_src(buttonHomeAll, LV_BTN_STATE_REL, "F:/bmp_zeroAll.bin"); + lv_imgbtn_set_src(buttonHomeAll, LV_BTN_STATE_PR, "F:/bmp_zeroAll.bin"); + lv_imgbtn_set_style(buttonHomeAll, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonHomeAll, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonHomeX, event_handler, ID_H_X, NULL, 0); + lv_imgbtn_set_src(buttonHomeX, LV_BTN_STATE_REL, "F:/bmp_zeroX.bin"); + lv_imgbtn_set_src(buttonHomeX, LV_BTN_STATE_PR, "F:/bmp_zeroX.bin"); + lv_imgbtn_set_style(buttonHomeX, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonHomeX, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonHomeY, event_handler, ID_H_Y, NULL, 0); + lv_imgbtn_set_src(buttonHomeY, LV_BTN_STATE_REL, "F:/bmp_zeroY.bin"); + lv_imgbtn_set_src(buttonHomeY, LV_BTN_STATE_PR, "F:/bmp_zeroY.bin"); + lv_imgbtn_set_style(buttonHomeY, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonHomeY, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonHomeZ, event_handler, ID_H_Z, NULL, 0); + lv_imgbtn_set_src(buttonHomeZ, LV_BTN_STATE_REL, "F:/bmp_zeroZ.bin"); + lv_imgbtn_set_src(buttonHomeZ, LV_BTN_STATE_PR, "F:/bmp_zeroZ.bin"); + lv_imgbtn_set_style(buttonHomeZ, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonHomeZ, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonOffAll, event_handler,ID_H_OFF_ALL, NULL,0); + lv_imgbtn_set_src(buttonOffAll, LV_BTN_STATE_REL, "F:/bmp_function1.bin"); + lv_imgbtn_set_src(buttonOffAll, LV_BTN_STATE_PR, "F:/bmp_function1.bin"); + lv_imgbtn_set_style(buttonOffAll, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonOffAll, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonOffXY, event_handler,ID_H_OFF_XY, NULL,0); + lv_imgbtn_set_src(buttonOffXY, LV_BTN_STATE_REL, "F:/bmp_function1.bin"); + lv_imgbtn_set_src(buttonOffXY, LV_BTN_STATE_PR, "F:/bmp_function1.bin"); + lv_imgbtn_set_style(buttonOffXY, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonOffXY, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonBack, event_handler,ID_H_RETURN, NULL,0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_return.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_return.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + #endif + + lv_obj_set_pos(buttonHomeAll, INTERVAL_V, titleHeight); + lv_obj_set_pos(buttonHomeX, BTN_X_PIXEL + INTERVAL_V * 2, titleHeight); + lv_obj_set_pos(buttonHomeY, BTN_X_PIXEL * 2 + INTERVAL_V * 3, titleHeight); + lv_obj_set_pos(buttonHomeZ, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight); + lv_obj_set_pos(buttonOffAll, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonOffXY, BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonBack, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + + // Create labels on the image buttons + lv_btn_set_layout(buttonHomeAll, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonHomeX, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonHomeY, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonHomeZ, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonOffAll, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonOffXY, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + + lv_obj_t *labelHomeAll = lv_label_create(buttonHomeAll, NULL); + lv_obj_t *labelHomeX = lv_label_create(buttonHomeX, NULL); + lv_obj_t *labelHomeY = lv_label_create(buttonHomeY, NULL); + lv_obj_t *labelHomeZ = lv_label_create(buttonHomeZ, NULL); + lv_obj_t *labelOffAll = lv_label_create(buttonOffAll, NULL); + lv_obj_t *labelOffXY = lv_label_create(buttonOffXY, NULL); + lv_obj_t *label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(labelHomeAll, home_menu.home_all); + lv_obj_align(labelHomeAll, buttonHomeAll, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelHomeX, home_menu.home_x); + lv_obj_align(labelHomeX, buttonHomeX, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelHomeY, home_menu.home_y); + lv_obj_align(labelHomeY, buttonHomeY, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelHomeZ, home_menu.home_z); + lv_obj_align(labelHomeZ, buttonHomeZ, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelOffAll, set_menu.motoroff); + lv_obj_align(labelOffAll, buttonOffAll, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelOffXY, set_menu.motoroffXY); + lv_obj_align(labelOffXY, buttonOffXY, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonHomeAll); + lv_group_add_obj(g, buttonHomeX); + lv_group_add_obj(g, buttonHomeY); + lv_group_add_obj(g, buttonHomeZ); + lv_group_add_obj(g, buttonOffAll); + lv_group_add_obj(g, buttonOffXY); + lv_group_add_obj(g, buttonBack); + } + #endif +} + +void lv_clear_home() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_home.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_home.h new file mode 100644 index 000000000000..c5060127a876 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_home.h @@ -0,0 +1,34 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_home(void); +extern void lv_clear_home(); + +//extern void disp_temp_ready_print(); +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_homing_sensitivity_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_homing_sensitivity_settings.cpp new file mode 100644 index 000000000000..d22eeb157e18 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_homing_sensitivity_settings.cpp @@ -0,0 +1,262 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" + +#include "../../../../MarlinCore.h" +#include "../../../../module/planner.h" +#include "../../../../module/probe.h" + +#if USE_SENSORLESS +#include "../../../../module/stepper/indirection.h" +#include "../../../../feature/tmc_util.h" + +extern lv_group_t * g; +static lv_obj_t * scr; + +#define ID_SENSITIVITY_RETURN 1 +#define ID_SENSITIVITY_X 2 +#define ID_SENSITIVITY_Y 3 +#define ID_SENSITIVITY_Z 4 +#define ID_SENSITIVITY_Z2 5 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_SENSITIVITY_RETURN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_homing_sensitivity_settings(); + draw_return_ui(); + } + break; + case ID_SENSITIVITY_X: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = x_sensitivity; + lv_clear_homing_sensitivity_settings(); + lv_draw_number_key(); + } + break; + case ID_SENSITIVITY_Y: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = y_sensitivity; + lv_clear_homing_sensitivity_settings(); + lv_draw_number_key(); + } + break; + case ID_SENSITIVITY_Z: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = z_sensitivity; + lv_clear_homing_sensitivity_settings(); + lv_draw_number_key(); + } + break; + #if Z2_SENSORLESS + case ID_SENSITIVITY_Z2: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = z2_sensitivity; + lv_clear_homing_sensitivity_settings(); + lv_draw_number_key(); + } + break; + #endif + } +} + +void lv_draw_homing_sensitivity_settings(void) { + lv_obj_t *buttonBack = NULL, *label_Back = NULL; + lv_obj_t *labelXText = NULL, *buttonXValue = NULL, *labelXValue = NULL; + lv_obj_t *labelYText = NULL, *buttonYValue = NULL, *labelYValue = NULL; + lv_obj_t *labelZText = NULL, *buttonZValue = NULL, *labelZValue = NULL; + lv_obj_t * line1 = NULL, * line2 = NULL, * line3 = NULL; + #if Z2_SENSORLESS + lv_obj_t *labelZ2Text = NULL, *buttonZ2Value = NULL, *labelZ2Value = NULL; + lv_obj_t * line4 = NULL; + #endif + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != HOMING_SENSITIVITY_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = HOMING_SENSITIVITY_UI; + } + disp_state = HOMING_SENSITIVITY_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, machine_menu.HomingSensitivityConfTitle); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + labelXText = lv_label_create(scr, NULL); + lv_obj_set_style(labelXText, &tft_style_label_rel); + lv_obj_set_pos(labelXText, PARA_UI_POS_X, PARA_UI_POS_Y + 10); + lv_label_set_text(labelXText, machine_menu.X_Sensitivity); + + buttonXValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonXValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y + PARA_UI_VALUE_V_2); + lv_obj_set_size(buttonXValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonXValue, event_handler, ID_SENSITIVITY_X, NULL, 0); + lv_btn_set_style(buttonXValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonXValue, LV_BTN_STYLE_PR, &style_para_value); + labelXValue = lv_label_create(buttonXValue, NULL); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonXValue); + #endif + + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1, line_points[0]); + + labelYText = lv_label_create(scr, NULL); + lv_obj_set_style(labelYText, &tft_style_label_rel); + lv_obj_set_pos(labelYText, PARA_UI_POS_X, PARA_UI_POS_Y * 2 + 10); + lv_label_set_text(labelYText, machine_menu.Y_Sensitivity); + + buttonYValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonYValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 2 + PARA_UI_VALUE_V_2); + lv_obj_set_size(buttonYValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonYValue, event_handler, ID_SENSITIVITY_Y, NULL, 0); + lv_btn_set_style(buttonYValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonYValue, LV_BTN_STYLE_PR, &style_para_value); + labelYValue = lv_label_create(buttonYValue, NULL); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonYValue); + #endif + + line2 = lv_line_create(scr, NULL); + lv_ex_line(line2, line_points[1]); + + labelZText = lv_label_create(scr, NULL); + lv_obj_set_style(labelZText, &tft_style_label_rel); + lv_obj_set_pos(labelZText, PARA_UI_POS_X, PARA_UI_POS_Y * 3 + 10); + lv_label_set_text(labelZText, machine_menu.Z_Sensitivity); + + buttonZValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonZValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 3 + PARA_UI_VALUE_V_2); + lv_obj_set_size(buttonZValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonZValue, event_handler, ID_SENSITIVITY_Z, NULL, 0); + lv_btn_set_style(buttonZValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonZValue, LV_BTN_STYLE_PR, &style_para_value); + labelZValue = lv_label_create(buttonZValue, NULL); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable == true) lv_group_add_obj(g, buttonZValue); + #endif + + line3 = lv_line_create(scr, NULL); + lv_ex_line(line3, line_points[2]); + + #if Z2_SENSORLESS + labelZ2Text = lv_label_create(scr, NULL); + lv_obj_set_style(labelZ2Text, &tft_style_label_rel); + lv_obj_set_pos(labelZ2Text, PARA_UI_POS_X, PARA_UI_POS_Y * 4 + 10); + lv_label_set_text(labelZ2Text, machine_menu.Z2_Sensitivity); + + buttonZ2Value = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonZ2Value, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 4 + PARA_UI_VALUE_V_2); + lv_obj_set_size(buttonZ2Value, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonZ2Value, event_handler, ID_SENSITIVITY_Z2, NULL, 0); + lv_btn_set_style(buttonZ2Value, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonZ2Value, LV_BTN_STYLE_PR, &style_para_value); + labelZ2Value = lv_label_create(buttonZ2Value, NULL); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonZ2Value); + #endif + + line4 = lv_line_create(scr, NULL); + lv_ex_line(line4, line_points[3]); + #endif + + buttonBack = lv_btn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_SENSITIVITY_RETURN, NULL, 0); + lv_btn_set_style(buttonBack, LV_BTN_STYLE_REL, &style_para_back); + lv_btn_set_style(buttonBack, LV_BTN_STYLE_PR, &style_para_back); + lv_obj_set_pos(buttonBack, PARA_UI_BACL_POS_X, PARA_UI_BACL_POS_Y); + lv_obj_set_size(buttonBack, PARA_UI_BACK_BTN_X_SIZE, PARA_UI_BACK_BTN_Y_SIZE); + label_Back = lv_label_create(buttonBack, NULL); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonBack); + #endif + + if (gCfgItems.multiple_language != 0) { + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), TERN(X_SENSORLESS, stepperX.homing_threshold(), 0)); + lv_label_set_text(labelXValue, public_buf_l); + lv_obj_align(labelXValue, buttonXValue, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), TERN(Y_SENSORLESS, stepperY.homing_threshold(), 0)); + lv_label_set_text(labelYValue, public_buf_l); + lv_obj_align(labelYValue, buttonYValue, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), TERN(Z_SENSORLESS, stepperZ.homing_threshold(), 0)); + lv_label_set_text(labelZValue, public_buf_l); + lv_obj_align(labelZValue, buttonZValue, LV_ALIGN_CENTER, 0, 0); + + #if Z2_SENSORLESS + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), TERN(Z2_SENSORLESS, stepperZ2.homing_threshold(), 0)); + lv_label_set_text(labelZ2Value, public_buf_l); + lv_obj_align(labelZ2Value, buttonZ2Value, LV_ALIGN_CENTER, 0, 0); + #endif + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_CENTER, 0, 0); + } +} + +void lv_clear_homing_sensitivity_settings() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // USE_SENSORLESS + +#endif // HAS_TFT_LVGL_UI && USE_SENSORLESS diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_homing_sensitivity_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_homing_sensitivity_settings.h new file mode 100644 index 000000000000..0c554702b1c6 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_homing_sensitivity_settings.h @@ -0,0 +1,33 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_homing_sensitivity_settings(void); +extern void lv_clear_homing_sensitivity_settings(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_jerk_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_jerk_settings.cpp new file mode 100644 index 000000000000..8c359233e6ea --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_jerk_settings.cpp @@ -0,0 +1,237 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if BOTH(HAS_TFT_LVGL_UI, HAS_CLASSIC_JERK) + +#include "lv_conf.h" +#include "draw_ui.h" + +#include "../../../../MarlinCore.h" +#include "../../../../module/planner.h" + +extern lv_group_t * g; +static lv_obj_t * scr; + +#define ID_JERK_RETURN 1 +#define ID_JERK_X 2 +#define ID_JERK_Y 3 +#define ID_JERK_Z 4 +#define ID_JERK_E 5 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_JERK_RETURN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_jerk_settings(); + draw_return_ui(); + } + break; + case ID_JERK_X: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = XJerk; + lv_clear_jerk_settings(); + lv_draw_number_key(); + } + break; + case ID_JERK_Y: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = YJerk; + lv_clear_jerk_settings(); + lv_draw_number_key(); + } + break; + case ID_JERK_Z: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = ZJerk; + lv_clear_jerk_settings(); + lv_draw_number_key(); + } + break; + case ID_JERK_E: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = EJerk; + lv_clear_jerk_settings(); + lv_draw_number_key(); + } + break; + } +} + +void lv_draw_jerk_settings(void) { + lv_obj_t *buttonBack = NULL, *label_Back = NULL; + lv_obj_t *labelXText = NULL, *buttonXValue = NULL, *labelXValue = NULL; + lv_obj_t *labelYText = NULL, *buttonYValue = NULL, *labelYValue = NULL; + lv_obj_t *labelZText = NULL, *buttonZValue = NULL, *labelZValue = NULL; + lv_obj_t *labelEText = NULL, *buttonEValue = NULL, *labelEValue = NULL; + lv_obj_t * line1 = NULL, * line2 = NULL, * line3 = NULL, * line4 = NULL; + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != JERK_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = JERK_UI; + } + disp_state = JERK_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, machine_menu.JerkConfTitle); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + labelXText = lv_label_create(scr, NULL); + lv_obj_set_style(labelXText, &tft_style_label_rel); + lv_obj_set_pos(labelXText, PARA_UI_POS_X, PARA_UI_POS_Y + 10); + lv_label_set_text(labelXText, machine_menu.X_Jerk); + + buttonXValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonXValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y + PARA_UI_VALUE_V); + lv_obj_set_size(buttonXValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonXValue, event_handler, ID_JERK_X, NULL, 0); + lv_btn_set_style(buttonXValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonXValue, LV_BTN_STYLE_PR, &style_para_value); + labelXValue = lv_label_create(buttonXValue, NULL); + + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1, line_points[0]); + + labelYText = lv_label_create(scr, NULL); + lv_obj_set_style(labelYText, &tft_style_label_rel); + lv_obj_set_pos(labelYText, PARA_UI_POS_X, PARA_UI_POS_Y * 2 + 10); + lv_label_set_text(labelYText, machine_menu.Y_Jerk); + + buttonYValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonYValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 2 + PARA_UI_VALUE_V); + lv_obj_set_size(buttonYValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonYValue, event_handler, ID_JERK_Y, NULL, 0); + lv_btn_set_style(buttonYValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonYValue, LV_BTN_STYLE_PR, &style_para_value); + labelYValue = lv_label_create(buttonYValue, NULL); + + line2 = lv_line_create(scr, NULL); + lv_ex_line(line2, line_points[1]); + + labelZText = lv_label_create(scr, NULL); + lv_obj_set_style(labelZText, &tft_style_label_rel); + lv_obj_set_pos(labelZText, PARA_UI_POS_X, PARA_UI_POS_Y * 3 + 10); + lv_label_set_text(labelZText, machine_menu.Z_Jerk); + + buttonZValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonZValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 3 + PARA_UI_VALUE_V); + lv_obj_set_size(buttonZValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonZValue, event_handler, ID_JERK_Z, NULL, 0); + lv_btn_set_style(buttonZValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonZValue, LV_BTN_STYLE_PR, &style_para_value); + labelZValue = lv_label_create(buttonZValue, NULL); + + line3 = lv_line_create(scr, NULL); + lv_ex_line(line3, line_points[2]); + + labelEText = lv_label_create(scr, NULL); + lv_obj_set_style(labelEText, &tft_style_label_rel); + lv_obj_set_pos(labelEText, PARA_UI_POS_X, PARA_UI_POS_Y * 4 + 10); + lv_label_set_text(labelEText, machine_menu.E_Jerk); + + buttonEValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonEValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 4 + PARA_UI_VALUE_V); + lv_obj_set_size(buttonEValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonEValue, event_handler, ID_JERK_E, NULL, 0); + lv_btn_set_style(buttonEValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonEValue, LV_BTN_STYLE_PR, &style_para_value); + labelEValue = lv_label_create(buttonEValue, NULL); + + line4 = lv_line_create(scr, NULL); + lv_ex_line(line4, line_points[3]); + + buttonBack = lv_btn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_JERK_RETURN, NULL, 0); + lv_btn_set_style(buttonBack, LV_BTN_STYLE_REL, &style_para_back); + lv_btn_set_style(buttonBack, LV_BTN_STYLE_PR, &style_para_back); + + lv_obj_set_pos(buttonBack, PARA_UI_BACL_POS_X, PARA_UI_BACL_POS_Y); + lv_obj_set_size(buttonBack, PARA_UI_BACK_BTN_X_SIZE, PARA_UI_BACK_BTN_Y_SIZE); + label_Back = lv_label_create(buttonBack, NULL); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable == true) { + lv_group_add_obj(g, buttonXValue); + lv_group_add_obj(g, buttonYValue); + lv_group_add_obj(g, buttonZValue); + lv_group_add_obj(g, buttonEValue); + lv_group_add_obj(g, buttonBack); + } + #endif + + if (gCfgItems.multiple_language != 0) { + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), planner.max_jerk[X_AXIS]); + lv_label_set_text(labelXValue, public_buf_l); + lv_obj_align(labelXValue, buttonXValue, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), planner.max_jerk[Y_AXIS]); + lv_label_set_text(labelYValue, public_buf_l); + lv_obj_align(labelYValue, buttonYValue, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), planner.max_jerk[Z_AXIS]); + lv_label_set_text(labelZValue, public_buf_l); + lv_obj_align(labelZValue, buttonZValue, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), planner.max_jerk[E_AXIS]); + lv_label_set_text(labelEValue, public_buf_l); + lv_obj_align(labelEValue, buttonEValue, LV_ALIGN_CENTER, 0, 0); + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_CENTER, 0, 0); + } +} + +void lv_clear_jerk_settings() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI && HAS_CLASSIC_JERK diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_jerk_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_jerk_settings.h new file mode 100644 index 000000000000..0531dae9da96 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_jerk_settings.h @@ -0,0 +1,33 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_jerk_settings(void); +extern void lv_clear_jerk_settings(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_keyboard.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_keyboard.cpp new file mode 100644 index 000000000000..902472b8842a --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_keyboard.cpp @@ -0,0 +1,286 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" + +#include "../../../../../Configuration.h" +#include "../../../../MarlinCore.h" + +extern lv_group_t * g; +static lv_obj_t * scr; + +#define LV_KB_CTRL_BTN_FLAGS (LV_BTNM_CTRL_NO_REPEAT | LV_BTNM_CTRL_CLICK_TRIG) + +static const char * kb_map_lc[] = {"1#", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", LV_SYMBOL_BACKSPACE, "\n", + "ABC", "a", "s", "d", "f", "g", "h", "j", "k", "l", LV_SYMBOL_NEW_LINE, "\n", + "_", "-", "z", "x", "c", "v", "b", "n", "m", ".", ",", ":", "\n", + LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""}; + +static const lv_btnm_ctrl_t kb_ctrl_lc_map[] = { + LV_KB_CTRL_BTN_FLAGS | 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7, + LV_KB_CTRL_BTN_FLAGS | 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + LV_KB_CTRL_BTN_FLAGS | 2, 2, 6, 2, LV_KB_CTRL_BTN_FLAGS | 2}; + +static const char * kb_map_uc[] = {"1#", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", LV_SYMBOL_BACKSPACE, "\n", + "abc", "A", "S", "D", "F", "G", "H", "J", "K", "L", LV_SYMBOL_NEW_LINE, "\n", + "_", "-", "Z", "X", "C", "V", "B", "N", "M", ".", ",", ":", "\n", + LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""}; + +static const lv_btnm_ctrl_t kb_ctrl_uc_map[] = { + LV_KB_CTRL_BTN_FLAGS | 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7, + LV_KB_CTRL_BTN_FLAGS | 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + LV_KB_CTRL_BTN_FLAGS | 2, 2, 6, 2, LV_KB_CTRL_BTN_FLAGS | 2}; + +static const char * kb_map_spec[] = {"0", "1", "2", "3", "4" ,"5", "6", "7", "8", "9", LV_SYMBOL_BACKSPACE, "\n", + "abc", "+", "-", "/", "*", "=", "%", "!", "?", "#", "<", ">", "\n", + "\\", "@", "$", "(", ")", "{", "}", "[", "]", ";", "\"", "'", "\n", + LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""}; + +static const lv_btnm_ctrl_t kb_ctrl_spec_map[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, LV_KB_CTRL_BTN_FLAGS | 2, + LV_KB_CTRL_BTN_FLAGS | 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + LV_KB_CTRL_BTN_FLAGS | 2, 2, 6, 2, LV_KB_CTRL_BTN_FLAGS | 2}; + +static const lv_btnm_ctrl_t kb_ctrl_num_map[] = { + 1, 1, 1, LV_KB_CTRL_BTN_FLAGS | 2, + 1, 1, 1, LV_KB_CTRL_BTN_FLAGS | 2, + 1, 1, 1, 2, + 1, 1, 1, 1, 1}; + +static void lv_kb_event_cb(lv_obj_t * kb, lv_event_t event) { + //LV_ASSERT_OBJ(kb, LV_OBJX_NAME); + + if (event != LV_EVENT_VALUE_CHANGED) return; + + lv_kb_ext_t * ext = (lv_kb_ext_t * )lv_obj_get_ext_attr(kb); + const uint16_t btn_id = lv_btnm_get_active_btn(kb); + if (btn_id == LV_BTNM_BTN_NONE) return; + if (lv_btnm_get_btn_ctrl(kb, btn_id, LV_BTNM_CTRL_HIDDEN | LV_BTNM_CTRL_INACTIVE)) return; + if (lv_btnm_get_btn_ctrl(kb, btn_id, LV_BTNM_CTRL_NO_REPEAT) && event == LV_EVENT_LONG_PRESSED_REPEAT) return; + + const char * txt = lv_btnm_get_active_btn_text(kb); + if (txt == NULL) return; + + // Do the corresponding action according to the text of the button + if (strcmp(txt, "abc") == 0) { + lv_btnm_set_map(kb, kb_map_lc); + lv_btnm_set_ctrl_map(kb, kb_ctrl_lc_map); + return; + } + else if (strcmp(txt, "ABC") == 0) { + lv_btnm_set_map(kb, kb_map_uc); + lv_btnm_set_ctrl_map(kb, kb_ctrl_uc_map); + return; + } + else if (strcmp(txt, "1#") == 0) { + lv_btnm_set_map(kb, kb_map_spec); + lv_btnm_set_ctrl_map(kb, kb_ctrl_spec_map); + return; + } + else if (strcmp(txt, LV_SYMBOL_CLOSE) == 0) { + if (kb->event_cb != lv_kb_def_event_cb) { + //lv_res_t res = lv_event_send(kb, LV_EVENT_CANCEL, NULL); + //if (res != LV_RES_OK) return; + lv_clear_keyboard(); + draw_return_ui(); + } + else { + lv_kb_set_ta(kb, NULL); /*De-assign the text area to hide it cursor if needed*/ + lv_obj_del(kb); + return; + } + return; + } + else if (strcmp(txt, LV_SYMBOL_OK) == 0) { + if (kb->event_cb != lv_kb_def_event_cb) { + //lv_res_t res = lv_event_send(kb, LV_EVENT_APPLY, NULL); + //if (res != LV_RES_OK) return; + const char * ret_ta_txt = lv_ta_get_text(ext->ta); + switch (keyboard_value) { + #if ENABLED(USE_WIFI_FUNCTION) + case wifiName: + memcpy(uiCfg.wifi_name,ret_ta_txt,sizeof(uiCfg.wifi_name)); + lv_clear_keyboard(); + draw_return_ui(); + break; + case wifiPassWord: + memcpy(uiCfg.wifi_key,ret_ta_txt,sizeof(uiCfg.wifi_name)); + lv_clear_keyboard(); + draw_return_ui(); + break; + case wifiConfig: + memset((void *)uiCfg.wifi_name, 0, sizeof(uiCfg.wifi_name)); + memcpy((void *)uiCfg.wifi_name, wifi_list.wifiName[wifi_list.nameIndex], 32); + + memset((void *)uiCfg.wifi_key, 0, sizeof(uiCfg.wifi_key)); + memcpy((void *)uiCfg.wifi_key, ret_ta_txt, sizeof(uiCfg.wifi_key)); + + gCfgItems.wifi_mode_sel = STA_MODEL; + + package_to_wifi(WIFI_PARA_SET, (char *)0, 0); + + memset(public_buf_l,0,sizeof(public_buf_l)); + + public_buf_l[0] = 0xA5; + public_buf_l[1] = 0x09; + public_buf_l[2] = 0x01; + public_buf_l[3] = 0x00; + public_buf_l[4] = 0x01; + public_buf_l[5] = 0xFC; + public_buf_l[6] = 0x00; + raw_send_to_wifi(public_buf_l, 6); + + last_disp_state = KEY_BOARD_UI; + lv_clear_keyboard(); + wifi_tips_type = TIPS_TYPE_JOINING; + lv_draw_wifi_tips(); + break; + #endif // USE_WIFI_FUNCTION + case gcodeCommand: + uint8_t buf[100]; + strncpy((char *)buf,ret_ta_txt,sizeof(buf)); + update_gcode_command(AUTO_LEVELING_COMMAND_ADDR,buf); + lv_clear_keyboard(); + draw_return_ui(); + break; + default: break; + } + } + else { + lv_kb_set_ta(kb, NULL); /*De-assign the text area to hide it cursor if needed*/ + } + return; + } + + /*Add the characters to the text area if set*/ + if (ext->ta == NULL) return; + + if (strcmp(txt, "Enter") == 0 || strcmp(txt, LV_SYMBOL_NEW_LINE) == 0) + lv_ta_add_char(ext->ta, '\n'); + else if (strcmp(txt, LV_SYMBOL_LEFT) == 0) + lv_ta_cursor_left(ext->ta); + else if (strcmp(txt, LV_SYMBOL_RIGHT) == 0) + lv_ta_cursor_right(ext->ta); + else if (strcmp(txt, LV_SYMBOL_BACKSPACE) == 0) + lv_ta_del_char(ext->ta); + else if (strcmp(txt, "+/-") == 0) { + uint16_t cur = lv_ta_get_cursor_pos(ext->ta); + const char * ta_txt = lv_ta_get_text(ext->ta); + if (ta_txt[0] == '-') { + lv_ta_set_cursor_pos(ext->ta, 1); + lv_ta_del_char(ext->ta); + lv_ta_add_char(ext->ta, '+'); + lv_ta_set_cursor_pos(ext->ta, cur); + } + else if (ta_txt[0] == '+') { + lv_ta_set_cursor_pos(ext->ta, 1); + lv_ta_del_char(ext->ta); + lv_ta_add_char(ext->ta, '-'); + lv_ta_set_cursor_pos(ext->ta, cur); + } + else { + lv_ta_set_cursor_pos(ext->ta, 0); + lv_ta_add_char(ext->ta, '-'); + lv_ta_set_cursor_pos(ext->ta, cur + 1); + } + } + else { + lv_ta_add_text(ext->ta, txt); + } +} + +void lv_draw_keyboard() { + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != KEY_BOARD_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = KEY_BOARD_UI; + } + disp_state = KEY_BOARD_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + /*Create styles for the keyboard*/ + static lv_style_t rel_style, pr_style; + + lv_style_copy(&rel_style, &lv_style_btn_rel); + rel_style.body.radius = 0; + rel_style.body.border.width = 1; + rel_style.body.main_color = lv_color_make(0xA9, 0x62, 0x1D); + rel_style.body.grad_color = lv_color_make(0xA7, 0x59, 0x0E); + + lv_style_copy(&pr_style, &lv_style_btn_pr); + pr_style.body.radius = 0; + pr_style.body.border.width = 1; + pr_style.body.main_color = lv_color_make(0x72, 0x42, 0x15); + pr_style.body.grad_color = lv_color_make(0x6A, 0x3A, 0x0C); + + /*Create a keyboard and apply the styles*/ + lv_obj_t *kb = lv_kb_create(scr, NULL); + lv_obj_set_event_cb(kb, lv_kb_event_cb); + lv_kb_set_cursor_manage(kb, true); + lv_kb_set_style(kb, LV_KB_STYLE_BG, &lv_style_transp_tight); + lv_kb_set_style(kb, LV_KB_STYLE_BTN_REL, &rel_style); + lv_kb_set_style(kb, LV_KB_STYLE_BTN_PR, &pr_style); + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + //lv_group_add_obj(g, kb); + //lv_group_set_editing(g, true); + } + #endif + + /*Create a text area. The keyboard will write here*/ + lv_obj_t *ta = lv_ta_create(scr, NULL); + lv_obj_align(ta, NULL, LV_ALIGN_IN_TOP_MID, 0, 10); + if (keyboard_value == gcodeCommand) { + get_gcode_command(AUTO_LEVELING_COMMAND_ADDR,(uint8_t *)public_buf_m); + public_buf_m[sizeof(public_buf_m)-1] = 0; + lv_ta_set_text(ta, public_buf_m); + } + else { + lv_ta_set_text(ta, ""); + } + + /*Assign the text area to the keyboard*/ + lv_kb_set_ta(kb, ta); +} + +void lv_clear_keyboard() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { /* lv_group_remove_all_objs(g); */ } + #endif + lv_obj_del(scr); +} + + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_keyboard.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_keyboard.h new file mode 100644 index 000000000000..0013dc4030ea --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_keyboard.h @@ -0,0 +1,33 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_keyboard(); +extern void lv_clear_keyboard(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_language.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_language.cpp new file mode 100644 index 000000000000..3e4ad06477cd --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_language.cpp @@ -0,0 +1,401 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" +//#include "../lvgl/src/lv_objx/lv_imgbtn.h" +//#include "../lvgl/src/lv_objx/lv_img.h" +//#include "../lvgl/src/lv_core/lv_disp.h" +//#include "../lvgl/src/lv_core/lv_refr.h" + +#include "../../../../MarlinCore.h" +#include + +//static lv_obj_t *buttonMoveZ,*buttonTest,*buttonZ0,*buttonStop,*buttonReturn; + +#define ID_CN 1 +#define ID_T_CN 2 +#define ID_EN 3 +#define ID_RU 4 +#define ID_ES 5 +#define ID_FR 6 +#define ID_IT 7 +#define ID_L_RETURN 8 + +#define SELECTED 1 +#define UNSELECTED 0 + +static void disp_language(uint8_t language, uint8_t state); + +extern lv_group_t * g; +static lv_obj_t * scr; +static lv_obj_t *buttonCN, *buttonT_CN, *buttonEN, *buttonRU; +static lv_obj_t *buttonES, *buttonFR, *buttonIT, *buttonBack; + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_CN: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + disp_language(gCfgItems.language, UNSELECTED); + lv_imgbtn_set_src(buttonCN, LV_BTN_STATE_REL, "F:/bmp_simplified_cn_sel.bin"); + lv_imgbtn_set_src(buttonCN, LV_BTN_STATE_PR, "F:/bmp_simplified_cn_sel.bin"); + lv_obj_refresh_ext_draw_pad(buttonCN); + gCfgItems.language = LANG_SIMPLE_CHINESE; + update_spi_flash(); + disp_language_init(); + } + break; + case ID_T_CN: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + disp_language(gCfgItems.language, UNSELECTED); + lv_imgbtn_set_src(buttonT_CN, LV_BTN_STATE_REL, "F:/bmp_traditional_cn_sel.bin"); + lv_imgbtn_set_src(buttonT_CN, LV_BTN_STATE_PR, "F:/bmp_traditional_cn_sel.bin"); + lv_obj_refresh_ext_draw_pad(buttonT_CN); + gCfgItems.language = LANG_COMPLEX_CHINESE; + update_spi_flash(); + disp_language_init(); + } + break; + case ID_EN: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + disp_language(gCfgItems.language, UNSELECTED); + lv_imgbtn_set_src(buttonEN, LV_BTN_STATE_REL, "F:/bmp_english_sel.bin"); + lv_imgbtn_set_src(buttonEN, LV_BTN_STATE_PR, "F:/bmp_english_sel.bin"); + lv_obj_refresh_ext_draw_pad(buttonEN); + gCfgItems.language = LANG_ENGLISH; + update_spi_flash(); + disp_language_init(); + } + break; + case ID_RU: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + disp_language(gCfgItems.language, UNSELECTED); + lv_imgbtn_set_src(buttonRU, LV_BTN_STATE_REL, "F:/bmp_russian_sel.bin"); + lv_imgbtn_set_src(buttonRU, LV_BTN_STATE_PR, "F:/bmp_russian_sel.bin"); + lv_obj_refresh_ext_draw_pad(buttonRU); + gCfgItems.language = LANG_RUSSIAN; + update_spi_flash(); + disp_language_init(); + } + break; + case ID_ES: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + disp_language(gCfgItems.language, UNSELECTED); + lv_imgbtn_set_src(buttonES, LV_BTN_STATE_REL, "F:/bmp_spanish_sel.bin"); + lv_imgbtn_set_src(buttonES, LV_BTN_STATE_PR, "F:/bmp_spanish_sel.bin"); + lv_obj_refresh_ext_draw_pad(buttonES); + gCfgItems.language = LANG_SPANISH; + update_spi_flash(); + disp_language_init(); + } + break; + case ID_FR: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + disp_language(gCfgItems.language, UNSELECTED); + lv_imgbtn_set_src(buttonFR, LV_BTN_STATE_REL, "F:/bmp_french_sel.bin"); + lv_imgbtn_set_src(buttonFR, LV_BTN_STATE_PR, "F:/bmp_french_sel.bin"); + lv_obj_refresh_ext_draw_pad(buttonFR); + gCfgItems.language = LANG_FRENCH; + update_spi_flash(); + disp_language_init(); + } + break; + case ID_IT: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + disp_language(gCfgItems.language, UNSELECTED); + lv_imgbtn_set_src(buttonIT, LV_BTN_STATE_REL, "F:/bmp_italy_sel.bin"); + lv_imgbtn_set_src(buttonIT, LV_BTN_STATE_PR, "F:/bmp_italy_sel.bin"); + lv_obj_refresh_ext_draw_pad(buttonIT); + gCfgItems.language = LANG_ITALY; + update_spi_flash(); + disp_language_init(); + } + break; + case ID_L_RETURN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + + buttonCN = NULL; + buttonT_CN = NULL; + buttonEN = NULL; + buttonRU = NULL; + buttonES = NULL; + buttonFR = NULL; + buttonFR = NULL; + buttonIT = NULL; + buttonBack = NULL; + lv_clear_language(); + lv_draw_set(); + } + break; + + } +} + +static void disp_language(uint8_t language, uint8_t state) { + uint16_t id; + lv_obj_t *obj; + + public_buf_l[0] = '\0'; + + switch (language) { + case LANG_SIMPLE_CHINESE: + id = ID_CN; + strcpy_P(public_buf_l, PSTR("F:/bmp_simplified_cn")); + obj = buttonCN; + break; + case LANG_COMPLEX_CHINESE: + id = ID_T_CN; + strcpy_P(public_buf_l, PSTR("F:/bmp_traditional_cn")); + obj = buttonT_CN; + break; + case LANG_ENGLISH: + id = ID_EN; + strcpy_P(public_buf_l, PSTR("F:/bmp_english")); + obj = buttonEN; + break; + case LANG_RUSSIAN: + id = ID_RU; + strcpy_P(public_buf_l, PSTR("F:/bmp_russian")); + obj = buttonRU; + break; + case LANG_SPANISH: + id = ID_ES; + strcpy_P(public_buf_l, PSTR("F:/bmp_spanish")); + obj = buttonES; + break; + case LANG_FRENCH: + id = ID_FR; + strcpy_P(public_buf_l, PSTR("F:/bmp_french")); + obj = buttonFR; + break; + case LANG_ITALY: + id = ID_IT; + strcpy_P(public_buf_l, PSTR("F:/bmp_italy")); + obj = buttonIT; + break; + default: + id = ID_CN; + strcpy_P(public_buf_l, PSTR("F:/bmp_simplified_cn")); + obj = buttonCN; + break; + } + + if (state == SELECTED) strcat_P(public_buf_l, PSTR("_sel")); + + strcat_P(public_buf_l, PSTR(".bin")); + + lv_obj_set_event_cb_mks(obj, event_handler, id, NULL, 0); + lv_imgbtn_set_src(obj, LV_BTN_STATE_REL, public_buf_l); + lv_imgbtn_set_src(obj, LV_BTN_STATE_PR, public_buf_l); + + if (state == UNSELECTED) lv_obj_refresh_ext_draw_pad(obj); +} + +void lv_draw_language(void) { + + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != LANGUAGE_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = LANGUAGE_UI; + } + disp_state = LANGUAGE_UI; + + scr = lv_obj_create(NULL, NULL); + + // static lv_style_t tool_style; + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, creat_title_text()); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + // Create image buttons + buttonCN = lv_imgbtn_create(scr, NULL); + buttonT_CN = lv_imgbtn_create(scr, NULL); + buttonEN = lv_imgbtn_create(scr, NULL); + buttonRU = lv_imgbtn_create(scr, NULL); + buttonES = lv_imgbtn_create(scr, NULL); + buttonFR = lv_imgbtn_create(scr, NULL); + buttonIT = lv_imgbtn_create(scr, NULL); + buttonBack = lv_imgbtn_create(scr, NULL); + + lv_obj_set_event_cb_mks(buttonCN, event_handler, ID_CN, NULL, 0); + lv_imgbtn_set_src(buttonCN, LV_BTN_STATE_REL, "F:/bmp_simplified_cn.bin"); + lv_imgbtn_set_src(buttonCN, LV_BTN_STATE_PR, "F:/bmp_simplified_cn.bin"); + lv_imgbtn_set_style(buttonCN, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonCN, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_obj_clear_protect(buttonCN, LV_PROTECT_FOLLOW); + + #if 1 + lv_obj_set_event_cb_mks(buttonT_CN, event_handler, ID_T_CN, NULL, 0); + lv_imgbtn_set_src(buttonT_CN, LV_BTN_STATE_REL, "F:/bmp_traditional_cn.bin"); + lv_imgbtn_set_src(buttonT_CN, LV_BTN_STATE_PR, "F:/bmp_traditional_cn.bin"); + lv_imgbtn_set_style(buttonT_CN, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonT_CN, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonEN, event_handler, ID_EN, NULL, 0); + lv_imgbtn_set_src(buttonEN, LV_BTN_STATE_REL, "F:/bmp_english.bin"); + lv_imgbtn_set_src(buttonEN, LV_BTN_STATE_PR, "F:/bmp_english.bin"); + lv_imgbtn_set_style(buttonEN, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonEN, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonRU, event_handler, ID_RU, NULL, 0); + lv_imgbtn_set_src(buttonRU, LV_BTN_STATE_REL, "F:/bmp_russian.bin"); + lv_imgbtn_set_src(buttonRU, LV_BTN_STATE_PR, "F:/bmp_russian.bin"); + lv_imgbtn_set_style(buttonRU, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonRU, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonES, event_handler, ID_ES, NULL, 0); + lv_imgbtn_set_src(buttonES, LV_BTN_STATE_REL, "F:/bmp_spanish.bin"); + lv_imgbtn_set_src(buttonES, LV_BTN_STATE_PR, "F:/bmp_spanish.bin"); + lv_imgbtn_set_style(buttonES, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonES, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonFR, event_handler, ID_FR, NULL, 0); + lv_imgbtn_set_src(buttonFR, LV_BTN_STATE_REL, "F:/bmp_french.bin"); + lv_imgbtn_set_src(buttonFR, LV_BTN_STATE_PR, "F:/bmp_french.bin"); + lv_imgbtn_set_style(buttonFR, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonFR, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonIT, event_handler, ID_IT, NULL, 0); + lv_imgbtn_set_src(buttonIT, LV_BTN_STATE_REL, "F:/bmp_italy.bin"); + lv_imgbtn_set_src(buttonIT, LV_BTN_STATE_PR, "F:/bmp_italy.bin"); + lv_imgbtn_set_style(buttonIT, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonIT, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_L_RETURN, NULL, 0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_return.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_return.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + + #endif // if 1 + + lv_obj_set_pos(buttonCN, INTERVAL_V, titleHeight); + lv_obj_set_pos(buttonT_CN, BTN_X_PIXEL + INTERVAL_V * 2, titleHeight); + lv_obj_set_pos(buttonEN, BTN_X_PIXEL * 2 + INTERVAL_V * 3, titleHeight); + lv_obj_set_pos(buttonRU, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight); + lv_obj_set_pos(buttonES, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonFR, BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonIT, BTN_X_PIXEL * 2 + INTERVAL_V * 3, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonBack, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + + // Create labels on the image buttons + lv_btn_set_layout(buttonCN, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonT_CN, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonEN, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonRU, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonES, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonFR, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonIT, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + + lv_obj_t *label_CN = lv_label_create(buttonCN, NULL); + lv_obj_t *label_T_CN = lv_label_create(buttonT_CN, NULL); + lv_obj_t *label_EN = lv_label_create(buttonEN, NULL); + lv_obj_t *label_RU = lv_label_create(buttonRU, NULL); + lv_obj_t *label_ES = lv_label_create(buttonES, NULL); + lv_obj_t *label_FR = lv_label_create(buttonFR, NULL); + lv_obj_t *label_IT = lv_label_create(buttonIT, NULL); + lv_obj_t *label_Back = lv_label_create(buttonBack, NULL); + + disp_language(gCfgItems.language, SELECTED); + + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(label_CN, language_menu.chinese_s); + lv_obj_align(label_CN, buttonCN, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_T_CN, language_menu.chinese_t); + lv_obj_align(label_T_CN, buttonT_CN, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_EN, language_menu.english); + lv_obj_align(label_EN, buttonEN, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_RU, language_menu.russian); + lv_obj_align(label_RU, buttonRU, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_ES, language_menu.spanish); + lv_obj_align(label_ES, buttonES, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_FR, language_menu.french); + lv_obj_align(label_FR, buttonFR, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_IT, language_menu.italy); + lv_obj_align(label_IT, buttonIT, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonCN); + lv_group_add_obj(g, buttonT_CN); + lv_group_add_obj(g, buttonEN); + lv_group_add_obj(g, buttonRU); + lv_group_add_obj(g, buttonES); + lv_group_add_obj(g, buttonFR); + lv_group_add_obj(g, buttonIT); + lv_group_add_obj(g, buttonBack); + } + #endif +} + +void lv_clear_language() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_language.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_language.h new file mode 100644 index 000000000000..ca6d40bfc3ca --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_language.h @@ -0,0 +1,34 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_language(void); +extern void lv_clear_language(); + +//extern void disp_temp_ready_print(); +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_level_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_level_settings.cpp new file mode 100644 index 000000000000..0e0283d32a40 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_level_settings.cpp @@ -0,0 +1,261 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" + +#include "../../../../MarlinCore.h" + +extern lv_group_t * g; +static lv_obj_t * scr; + +#define ID_LEVEL_RETURN 1 +#define ID_LEVEL_POSITION 2 +#define ID_LEVEL_POSITION_ARROW 3 +#define ID_LEVEL_COMMAND 4 +#define ID_LEVEL_COMMAND_ARROW 5 +#define ID_LEVEL_ZOFFSET 6 +#define ID_LEVEL_ZOFFSET_ARROW 7 + + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_LEVEL_RETURN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_level_settings(); + draw_return_ui(); + } + break; + case ID_LEVEL_POSITION: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_level_settings(); + lv_draw_manual_level_pos_settings(); + } + break; + case ID_LEVEL_POSITION_ARROW: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_level_settings(); + lv_draw_manual_level_pos_settings(); + } + break; + case ID_LEVEL_COMMAND: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + keyboard_value = gcodeCommand; + lv_clear_level_settings(); + lv_draw_keyboard(); + } + break; + case ID_LEVEL_COMMAND_ARROW: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + keyboard_value = gcodeCommand; + lv_clear_level_settings(); + lv_draw_keyboard(); + } + break; + #if HAS_BED_PROBE + case ID_LEVEL_ZOFFSET: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_level_settings(); + lv_draw_auto_level_offset_settings(); + } + break; + case ID_LEVEL_ZOFFSET_ARROW: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_level_settings(); + lv_draw_auto_level_offset_settings(); + } + break; + #endif + } +} + +void lv_draw_level_settings(void) { + lv_obj_t *buttonBack, *label_Back; + lv_obj_t *buttonPosition, *labelPosition, *buttonPositionNarrow; + lv_obj_t *buttonCommand, *labelCommand, *buttonCommandNarrow; + #if HAS_BED_PROBE + lv_obj_t *buttonZoffset, *labelZoffset, *buttonZoffsetNarrow; + lv_obj_t * line3; + #endif + lv_obj_t * line1, * line2; + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != LEVELING_PARA_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = LEVELING_PARA_UI; + } + disp_state = LEVELING_PARA_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, machine_menu.LevelingParaConfTitle); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + + buttonPosition = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(buttonPosition, PARA_UI_POS_X, PARA_UI_POS_Y); /*Set its position*/ + lv_obj_set_size(buttonPosition, PARA_UI_SIZE_X, PARA_UI_SIZE_Y); /*Set its size*/ + lv_obj_set_event_cb_mks(buttonPosition, event_handler, ID_LEVEL_POSITION, NULL, 0); + lv_btn_set_style(buttonPosition, LV_BTN_STYLE_REL, &tft_style_label_rel); /*Set the button's released style*/ + lv_btn_set_style(buttonPosition, LV_BTN_STYLE_PR, &tft_style_label_pre); /*Set the button's pressed style*/ + lv_btn_set_layout(buttonPosition, LV_LAYOUT_OFF); + labelPosition = lv_label_create(buttonPosition, NULL); /*Add a label to the button*/ + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonPosition); + #endif + + buttonPositionNarrow = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonPositionNarrow, PARA_UI_POS_X + PARA_UI_SIZE_X, PARA_UI_POS_Y + PARA_UI_ARROW_V); + lv_obj_set_event_cb_mks(buttonPositionNarrow, event_handler, ID_LEVEL_POSITION_ARROW, NULL, 0); + lv_imgbtn_set_src(buttonPositionNarrow, LV_BTN_STATE_REL, "F:/bmp_arrow.bin"); + lv_imgbtn_set_src(buttonPositionNarrow, LV_BTN_STATE_PR, "F:/bmp_arrow.bin"); + lv_imgbtn_set_style(buttonPositionNarrow, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonPositionNarrow, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonPositionNarrow, LV_LAYOUT_OFF); + + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1, line_points[0]); + + buttonCommand = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonCommand, PARA_UI_POS_X, PARA_UI_POS_Y * 2); + lv_obj_set_size(buttonCommand, PARA_UI_SIZE_X, PARA_UI_SIZE_Y); + lv_obj_set_event_cb_mks(buttonCommand, event_handler, ID_LEVEL_COMMAND, NULL, 0); + lv_btn_set_style(buttonCommand, LV_BTN_STYLE_REL, &tft_style_label_rel); + lv_btn_set_style(buttonCommand, LV_BTN_STYLE_PR, &tft_style_label_pre); + lv_btn_set_layout(buttonCommand, LV_LAYOUT_OFF); + labelCommand = lv_label_create(buttonCommand, NULL); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonCommand); + #endif + + buttonCommandNarrow = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonCommandNarrow, PARA_UI_POS_X + PARA_UI_SIZE_X, PARA_UI_POS_Y * 2 + PARA_UI_ARROW_V); + lv_obj_set_event_cb_mks(buttonCommandNarrow, event_handler, ID_LEVEL_COMMAND_ARROW, NULL, 0); + lv_imgbtn_set_src(buttonCommandNarrow, LV_BTN_STATE_REL, "F:/bmp_arrow.bin"); + lv_imgbtn_set_src(buttonCommandNarrow, LV_BTN_STATE_PR, "F:/bmp_arrow.bin"); + lv_imgbtn_set_style(buttonCommandNarrow, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonCommandNarrow, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonCommandNarrow, LV_LAYOUT_OFF); + + line2 = lv_line_create(scr, NULL); + lv_ex_line(line2, line_points[1]); + + #if HAS_BED_PROBE + + buttonZoffset = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(buttonZoffset, PARA_UI_POS_X, PARA_UI_POS_Y * 3); /*Set its position*/ + lv_obj_set_size(buttonZoffset, PARA_UI_SIZE_X, PARA_UI_SIZE_Y); /*Set its size*/ + lv_obj_set_event_cb_mks(buttonZoffset, event_handler, ID_LEVEL_ZOFFSET, NULL, 0); + lv_btn_set_style(buttonZoffset, LV_BTN_STYLE_REL, &tft_style_label_rel); /*Set the button's released style*/ + lv_btn_set_style(buttonZoffset, LV_BTN_STYLE_PR, &tft_style_label_pre); /*Set the button's pressed style*/ + lv_btn_set_layout(buttonZoffset, LV_LAYOUT_OFF); + labelZoffset = lv_label_create(buttonZoffset, NULL); /*Add a label to the button*/ + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonZoffset); + #endif + + buttonZoffsetNarrow = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonZoffsetNarrow, PARA_UI_POS_X + PARA_UI_SIZE_X, PARA_UI_POS_Y * 3 + PARA_UI_ARROW_V); + lv_obj_set_event_cb_mks(buttonZoffsetNarrow, event_handler, ID_LEVEL_ZOFFSET_ARROW, NULL, 0); + lv_imgbtn_set_src(buttonZoffsetNarrow, LV_BTN_STATE_REL, "F:/bmp_arrow.bin"); + lv_imgbtn_set_src(buttonZoffsetNarrow, LV_BTN_STATE_PR, "F:/bmp_arrow.bin"); + lv_imgbtn_set_style(buttonZoffsetNarrow, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonZoffsetNarrow, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonZoffsetNarrow, LV_LAYOUT_OFF); + + line3 = lv_line_create(scr, NULL); + lv_ex_line(line3, line_points[2]); + + #endif // HAS_BED_PROBE + + buttonBack = lv_imgbtn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_LEVEL_RETURN, NULL, 0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonBack); + #endif + + lv_obj_set_pos(buttonBack, PARA_UI_BACL_POS_X, PARA_UI_BACL_POS_Y); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_CENTER, 0, 0); + + lv_label_set_text(labelPosition, machine_menu.LevelingManuPosConf); + lv_obj_align(labelPosition, buttonPosition, LV_ALIGN_IN_LEFT_MID, 0, 0); + + lv_label_set_text(labelCommand, machine_menu.LevelingAutoCommandConf); + lv_obj_align(labelCommand, buttonCommand, LV_ALIGN_IN_LEFT_MID, 0, 0); + #if HAS_BED_PROBE + lv_label_set_text(labelZoffset, machine_menu.LevelingAutoZoffsetConf); + lv_obj_align(labelZoffset, buttonZoffset, LV_ALIGN_IN_LEFT_MID, 0, 0); + #endif + } + +} + +void lv_clear_level_settings() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_level_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_level_settings.h new file mode 100644 index 000000000000..ce290172b6e5 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_level_settings.h @@ -0,0 +1,33 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_level_settings(void); +extern void lv_clear_level_settings(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_para.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_para.cpp new file mode 100644 index 000000000000..9f03793c24f7 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_para.cpp @@ -0,0 +1,290 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" + +#include "../../../../MarlinCore.h" + +extern lv_group_t * g; +static lv_obj_t * scr; + +#define ID_PARA_RETURN 1 +#define ID_PARA_MACHINE 2 +#define ID_PARA_MACHINE_ARROW 3 +#define ID_PARA_MOTOR 4 +#define ID_PARA_MOTOR_ARROW 5 +#define ID_PARA_LEVEL 6 +#define ID_PARA_LEVEL_ARROW 7 +#define ID_PARA_ADVANCE 8 +#define ID_PARA_ADVANCE_ARROW 9 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_PARA_RETURN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_machine_para(); + draw_return_ui(); + } + break; + case ID_PARA_MACHINE: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_machine_para(); + lv_draw_machine_settings(); + } + break; + case ID_PARA_MACHINE_ARROW: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_machine_para(); + lv_draw_machine_settings(); + } + break; + case ID_PARA_MOTOR: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_machine_para(); + lv_draw_motor_settings(); + } + break; + case ID_PARA_MOTOR_ARROW: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_machine_para(); + lv_draw_motor_settings(); + } + break; + case ID_PARA_LEVEL: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_machine_para(); + lv_draw_level_settings(); + } + break; + case ID_PARA_LEVEL_ARROW: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_machine_para(); + lv_draw_level_settings(); + } + break; + case ID_PARA_ADVANCE: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_machine_para(); + lv_draw_advance_settings(); + } + break; + case ID_PARA_ADVANCE_ARROW: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_machine_para(); + lv_draw_advance_settings(); + } + break; + } +} + +void lv_draw_machine_para(void) { + lv_obj_t *buttonBack, *label_Back; + lv_obj_t *buttonMachine, *labelMachine, *buttonMachineNarrow; + lv_obj_t *buttonMotor, *labelMotor, *buttonMotorNarrow; + lv_obj_t *buttonLevel, *labelLevel, *buttonLevelNarrow; + lv_obj_t *buttonAdvance, *labelAdvance, *buttonAdvanceNarrow; + lv_obj_t * line1, * line2, * line3, * line4; + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != MACHINE_PARA_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = MACHINE_PARA_UI; + } + disp_state = MACHINE_PARA_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, creat_title_text()); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + buttonMachine = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(buttonMachine, PARA_UI_POS_X, PARA_UI_POS_Y); /*Set its position*/ + lv_obj_set_size(buttonMachine, PARA_UI_SIZE_X, PARA_UI_SIZE_Y); /*Set its size*/ + //lv_obj_set_event_cb(buttonMachine, event_handler); + lv_obj_set_event_cb_mks(buttonMachine, event_handler, ID_PARA_MACHINE, NULL, 0); + lv_btn_set_style(buttonMachine, LV_BTN_STYLE_REL, &tft_style_label_rel); /*Set the button's released style*/ + lv_btn_set_style(buttonMachine, LV_BTN_STYLE_PR, &tft_style_label_pre); /*Set the button's pressed style*/ + lv_btn_set_layout(buttonMachine, LV_LAYOUT_OFF); + labelMachine = lv_label_create(buttonMachine, NULL); /*Add a label to the button*/ + + buttonMachineNarrow = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonMachineNarrow, PARA_UI_POS_X + PARA_UI_SIZE_X, PARA_UI_POS_Y + PARA_UI_ARROW_V); + lv_obj_set_event_cb_mks(buttonMachineNarrow, event_handler, ID_PARA_MACHINE_ARROW, NULL, 0); + lv_imgbtn_set_src(buttonMachineNarrow, LV_BTN_STATE_REL, "F:/bmp_arrow.bin"); + lv_imgbtn_set_src(buttonMachineNarrow, LV_BTN_STATE_PR, "F:/bmp_arrow.bin"); + lv_imgbtn_set_style(buttonMachineNarrow, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonMachineNarrow, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonMachineNarrow, LV_LAYOUT_OFF); + + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1, line_points[0]); + + buttonMotor = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(buttonMotor, PARA_UI_POS_X, PARA_UI_POS_Y * 2); /*Set its position*/ + lv_obj_set_size(buttonMotor, PARA_UI_SIZE_X, PARA_UI_SIZE_Y); /*Set its size*/ + //lv_obj_set_event_cb(buttonMotor, event_handler); + lv_obj_set_event_cb_mks(buttonMotor, event_handler, ID_PARA_MOTOR, NULL, 0); + lv_btn_set_style(buttonMotor, LV_BTN_STYLE_REL, &tft_style_label_rel); /*Set the button's released style*/ + lv_btn_set_style(buttonMotor, LV_BTN_STYLE_PR, &tft_style_label_pre); /*Set the button's pressed style*/ + lv_btn_set_layout(buttonMotor, LV_LAYOUT_OFF); + labelMotor = lv_label_create(buttonMotor, NULL); /*Add a label to the button*/ + + buttonMotorNarrow = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonMotorNarrow, PARA_UI_POS_X + PARA_UI_SIZE_X, PARA_UI_POS_Y * 2 + PARA_UI_ARROW_V); + lv_obj_set_event_cb_mks(buttonMotorNarrow, event_handler, ID_PARA_MOTOR_ARROW, NULL, 0); + lv_imgbtn_set_src(buttonMotorNarrow, LV_BTN_STATE_REL, "F:/bmp_arrow.bin"); + lv_imgbtn_set_src(buttonMotorNarrow, LV_BTN_STATE_PR, "F:/bmp_arrow.bin"); + lv_imgbtn_set_style(buttonMotorNarrow, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonMotorNarrow, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonMotorNarrow, LV_LAYOUT_OFF); + + line2 = lv_line_create(scr, NULL); + lv_ex_line(line2, line_points[1]); + + buttonLevel = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(buttonLevel, PARA_UI_POS_X, PARA_UI_POS_Y * 3); /*Set its position*/ + lv_obj_set_size(buttonLevel, PARA_UI_SIZE_X, PARA_UI_SIZE_Y); /*Set its size*/ + //lv_obj_set_event_cb(buttonMotor, event_handler); + lv_obj_set_event_cb_mks(buttonLevel, event_handler, ID_PARA_LEVEL, NULL, 0); + lv_btn_set_style(buttonLevel, LV_BTN_STYLE_REL, &tft_style_label_rel); /*Set the button's released style*/ + lv_btn_set_style(buttonLevel, LV_BTN_STYLE_PR, &tft_style_label_pre); /*Set the button's pressed style*/ + lv_btn_set_layout(buttonLevel, LV_LAYOUT_OFF); + labelLevel = lv_label_create(buttonLevel, NULL); /*Add a label to the button*/ + + buttonLevelNarrow = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonLevelNarrow, PARA_UI_POS_X + PARA_UI_SIZE_X, PARA_UI_POS_Y * 3 + PARA_UI_ARROW_V); + lv_obj_set_event_cb_mks(buttonLevelNarrow, event_handler, ID_PARA_LEVEL_ARROW, NULL, 0); + lv_imgbtn_set_src(buttonLevelNarrow, LV_BTN_STATE_REL, "F:/bmp_arrow.bin"); + lv_imgbtn_set_src(buttonLevelNarrow, LV_BTN_STATE_PR, "F:/bmp_arrow.bin"); + lv_imgbtn_set_style(buttonLevelNarrow, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonLevelNarrow, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonLevelNarrow, LV_LAYOUT_OFF); + + line3 = lv_line_create(scr, NULL); + lv_ex_line(line3, line_points[2]); + + buttonAdvance = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(buttonAdvance, PARA_UI_POS_X, PARA_UI_POS_Y * 4); /*Set its position*/ + lv_obj_set_size(buttonAdvance, PARA_UI_SIZE_X, PARA_UI_SIZE_Y); /*Set its size*/ + //lv_obj_set_event_cb(buttonMotor, event_handler); + lv_obj_set_event_cb_mks(buttonAdvance, event_handler, ID_PARA_ADVANCE, NULL, 0); + lv_btn_set_style(buttonAdvance, LV_BTN_STYLE_REL, &tft_style_label_rel); /*Set the button's released style*/ + lv_btn_set_style(buttonAdvance, LV_BTN_STYLE_PR, &tft_style_label_pre); /*Set the button's pressed style*/ + lv_btn_set_layout(buttonAdvance, LV_LAYOUT_OFF); + labelAdvance = lv_label_create(buttonAdvance, NULL); /*Add a label to the button*/ + + buttonAdvanceNarrow = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonAdvanceNarrow, PARA_UI_POS_X + PARA_UI_SIZE_X, PARA_UI_POS_Y * 4 + PARA_UI_ARROW_V); + lv_obj_set_event_cb_mks(buttonAdvanceNarrow, event_handler, ID_PARA_ADVANCE_ARROW, NULL, 0); + lv_imgbtn_set_src(buttonAdvanceNarrow, LV_BTN_STATE_REL, "F:/bmp_arrow.bin"); + lv_imgbtn_set_src(buttonAdvanceNarrow, LV_BTN_STATE_PR, "F:/bmp_arrow.bin"); + lv_imgbtn_set_style(buttonAdvanceNarrow, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonAdvanceNarrow, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonAdvanceNarrow, LV_LAYOUT_OFF); + + line4 = lv_line_create(scr, NULL); + lv_ex_line(line4, line_points[3]); + + buttonBack = lv_imgbtn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_PARA_RETURN, NULL, 0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_pos(buttonBack, PARA_UI_BACL_POS_X + 10, PARA_UI_BACL_POS_Y); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_CENTER, 0, -2); + + lv_label_set_text(labelMachine, MachinePara_menu.MachineSetting); + lv_obj_align(labelMachine, buttonMachine, LV_ALIGN_IN_LEFT_MID, 0, -3); + + lv_label_set_text(labelMotor, MachinePara_menu.MotorSetting); + lv_obj_align(labelMotor, buttonMotor, LV_ALIGN_IN_LEFT_MID, 0, -3); + + lv_label_set_text(labelLevel, MachinePara_menu.leveling); + lv_obj_align(labelLevel, buttonLevel, LV_ALIGN_IN_LEFT_MID, 0, -3); + + lv_label_set_text(labelAdvance, MachinePara_menu.AdvanceSetting); + lv_obj_align(labelAdvance, buttonAdvance, LV_ALIGN_IN_LEFT_MID, 0, -3); + } + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonMachine); + lv_group_add_obj(g, buttonMotor); + lv_group_add_obj(g, buttonLevel); + lv_group_add_obj(g, buttonAdvance); + lv_group_add_obj(g, buttonBack); + } + #endif + +} + +void lv_clear_machine_para() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_para.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_para.h new file mode 100644 index 000000000000..e830f75db7e5 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_para.h @@ -0,0 +1,33 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_machine_para(void); +extern void lv_clear_machine_para(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_settings.cpp new file mode 100644 index 000000000000..0cf5bbaf7fba --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_settings.cpp @@ -0,0 +1,254 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" + +#include "../../../../MarlinCore.h" + +extern lv_group_t * g; +static lv_obj_t * scr; + +#define ID_MACHINE_RETURN 1 +#define ID_MACHINE_ACCELERATION 2 +#define ID_MACHINE_ACCELERATION_ARROW 3 +#define ID_MACHINE_FEEDRATE 4 +#define ID_MACHINE_FEEDRATE_ARROW 5 +#define ID_MACHINE_JERK 6 +#define ID_MACHINE_JERK_ARROW 7 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_MACHINE_RETURN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_machine_settings(); + draw_return_ui(); + } + break; + case ID_MACHINE_ACCELERATION: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_machine_settings(); + lv_draw_acceleration_settings(); + } + break; + case ID_MACHINE_ACCELERATION_ARROW: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_machine_settings(); + lv_draw_acceleration_settings(); + } + break; + case ID_MACHINE_FEEDRATE: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_machine_settings(); + lv_draw_max_feedrate_settings(); + } + break; + case ID_MACHINE_FEEDRATE_ARROW: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_machine_settings(); + lv_draw_max_feedrate_settings(); + } + break; + #if HAS_CLASSIC_JERK + case ID_MACHINE_JERK: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_machine_settings(); + lv_draw_jerk_settings(); + } + break; + case ID_MACHINE_JERK_ARROW: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_machine_settings(); + lv_draw_jerk_settings(); + } + break; + #endif + } +} + +void lv_draw_machine_settings(void) { + lv_obj_t *buttonBack, *label_Back; + lv_obj_t *buttonAcceleration, *labelAcceleration, *buttonAccelerationNarrow; + lv_obj_t *buttonMaxFeedrate, *labelMaxFeedrate, *buttonMaxFeedrateNarrow; + #if HAS_CLASSIC_JERK + lv_obj_t *buttonJerk, *labelJerk, *buttonJerkNarrow; + #endif + lv_obj_t * line1, * line2; + #if HAS_CLASSIC_JERK + lv_obj_t * line3; + #endif + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != MACHINE_SETTINGS_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = MACHINE_SETTINGS_UI; + } + disp_state = MACHINE_SETTINGS_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, machine_menu.MachineConfigTitle); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + buttonAcceleration = lv_btn_create(scr, NULL); // Add a button the current screen + lv_obj_set_pos(buttonAcceleration, PARA_UI_POS_X, PARA_UI_POS_Y); // Set its position + lv_obj_set_size(buttonAcceleration, PARA_UI_SIZE_X, PARA_UI_SIZE_Y); // Set its size + //lv_obj_set_event_cb(buttonMachine, event_handler); + lv_obj_set_event_cb_mks(buttonAcceleration, event_handler, ID_MACHINE_ACCELERATION, NULL, 0); + lv_btn_set_style(buttonAcceleration, LV_BTN_STYLE_REL, &tft_style_label_rel); // Set the button's released style + lv_btn_set_style(buttonAcceleration, LV_BTN_STYLE_PR, &tft_style_label_pre); // Set the button's pressed style + lv_btn_set_layout(buttonAcceleration, LV_LAYOUT_OFF); + labelAcceleration = lv_label_create(buttonAcceleration, NULL); // Add a label to the button + + buttonAccelerationNarrow = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonAccelerationNarrow, PARA_UI_POS_X + PARA_UI_SIZE_X, PARA_UI_POS_Y + PARA_UI_ARROW_V); + lv_obj_set_event_cb_mks(buttonAccelerationNarrow, event_handler, ID_MACHINE_ACCELERATION_ARROW, NULL, 0); + lv_imgbtn_set_src(buttonAccelerationNarrow, LV_BTN_STATE_REL, "F:/bmp_arrow.bin"); + lv_imgbtn_set_src(buttonAccelerationNarrow, LV_BTN_STATE_PR, "F:/bmp_arrow.bin"); + lv_imgbtn_set_style(buttonAccelerationNarrow, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonAccelerationNarrow, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonAccelerationNarrow, LV_LAYOUT_OFF); + + line1 = lv_line_create(lv_scr_act(), NULL); + lv_ex_line(line1, line_points[0]); + + buttonMaxFeedrate = lv_btn_create(scr, NULL); // Add a button the current screen + lv_obj_set_pos(buttonMaxFeedrate, PARA_UI_POS_X, PARA_UI_POS_Y * 2); // Set its position + lv_obj_set_size(buttonMaxFeedrate, PARA_UI_SIZE_X, PARA_UI_SIZE_Y); // Set its size + //lv_obj_set_event_cb(buttonMachine, event_handler); + lv_obj_set_event_cb_mks(buttonMaxFeedrate, event_handler, ID_MACHINE_FEEDRATE, NULL, 0); + lv_btn_set_style(buttonMaxFeedrate, LV_BTN_STYLE_REL, &tft_style_label_rel); // Set the button's released style + lv_btn_set_style(buttonMaxFeedrate, LV_BTN_STYLE_PR, &tft_style_label_pre); // Set the button's pressed style + lv_btn_set_layout(buttonMaxFeedrate, LV_LAYOUT_OFF); + labelMaxFeedrate = lv_label_create(buttonMaxFeedrate, NULL); // Add a label to the button + + buttonMaxFeedrateNarrow = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonMaxFeedrateNarrow, PARA_UI_POS_X + PARA_UI_SIZE_X, PARA_UI_POS_Y * 2 + PARA_UI_ARROW_V); + lv_obj_set_event_cb_mks(buttonMaxFeedrateNarrow, event_handler, ID_MACHINE_FEEDRATE_ARROW, NULL, 0); + lv_imgbtn_set_src(buttonMaxFeedrateNarrow, LV_BTN_STATE_REL, "F:/bmp_arrow.bin"); + lv_imgbtn_set_src(buttonMaxFeedrateNarrow, LV_BTN_STATE_PR, "F:/bmp_arrow.bin"); + lv_imgbtn_set_style(buttonMaxFeedrateNarrow, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonMaxFeedrateNarrow, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonMaxFeedrateNarrow, LV_LAYOUT_OFF); + + line2 = lv_line_create(lv_scr_act(), NULL); + lv_ex_line(line2, line_points[1]); + + #if HAS_CLASSIC_JERK + buttonJerk = lv_btn_create(scr, NULL); // Add a button the current screen + lv_obj_set_pos(buttonJerk, PARA_UI_POS_X, PARA_UI_POS_Y * 3); // Set its position + lv_obj_set_size(buttonJerk, PARA_UI_SIZE_X, PARA_UI_SIZE_Y); // Set its size + //lv_obj_set_event_cb(buttonMotor, event_handler); + lv_obj_set_event_cb_mks(buttonJerk, event_handler, ID_MACHINE_JERK, NULL, 0); + lv_btn_set_style(buttonJerk, LV_BTN_STYLE_REL, &tft_style_label_rel); // Set the button's released style + lv_btn_set_style(buttonJerk, LV_BTN_STYLE_PR, &tft_style_label_pre); // Set the button's pressed style + lv_btn_set_layout(buttonJerk, LV_LAYOUT_OFF); + labelJerk = lv_label_create(buttonJerk, NULL); // Add a label to the button + + buttonJerkNarrow = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonJerkNarrow, PARA_UI_POS_X + PARA_UI_SIZE_X, PARA_UI_POS_Y * 3 + PARA_UI_ARROW_V); + lv_obj_set_event_cb_mks(buttonJerkNarrow, event_handler, ID_MACHINE_JERK_ARROW, NULL, 0); + lv_imgbtn_set_src(buttonJerkNarrow, LV_BTN_STATE_REL, "F:/bmp_arrow.bin"); + lv_imgbtn_set_src(buttonJerkNarrow, LV_BTN_STATE_PR, "F:/bmp_arrow.bin"); + lv_imgbtn_set_style(buttonJerkNarrow, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonJerkNarrow, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonJerkNarrow, LV_LAYOUT_OFF); + + line3 = lv_line_create(lv_scr_act(), NULL); + lv_ex_line(line3, line_points[2]); + #endif + + buttonBack = lv_imgbtn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_MACHINE_RETURN, NULL, 0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_pos(buttonBack, PARA_UI_BACL_POS_X, PARA_UI_BACL_POS_Y); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_CENTER, 0, 0); + + lv_label_set_text(labelAcceleration, machine_menu.AccelerationConf); + lv_obj_align(labelAcceleration, buttonAcceleration, LV_ALIGN_IN_LEFT_MID, 0, 0); + + lv_label_set_text(labelMaxFeedrate, machine_menu.MaxFeedRateConf); + lv_obj_align(labelMaxFeedrate, buttonMaxFeedrate, LV_ALIGN_IN_LEFT_MID, 0, 0); + #if HAS_CLASSIC_JERK + lv_label_set_text(labelJerk, machine_menu.JerkConf); + lv_obj_align(labelJerk, buttonJerk, LV_ALIGN_IN_LEFT_MID, 0, 0); + #endif + } + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonAcceleration); + lv_group_add_obj(g, buttonMaxFeedrate); + #if HAS_CLASSIC_JERK + lv_group_add_obj(g, buttonJerk); + #endif + lv_group_add_obj(g, buttonBack); + } + #endif +} + +void lv_clear_machine_settings() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_settings.h new file mode 100644 index 000000000000..38d02e718948 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_settings.h @@ -0,0 +1,33 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_machine_settings(void); +extern void lv_clear_machine_settings(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_manuaLevel.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_manuaLevel.cpp new file mode 100644 index 000000000000..3d68019b3527 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_manuaLevel.cpp @@ -0,0 +1,294 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "../../../../MarlinCore.h" +#include "lv_conf.h" +//#include "../lvgl/src/lv_objx/lv_imgbtn.h" +//#include "../lvgl/src/lv_objx/lv_img.h" +//#include "../lvgl/src/lv_core/lv_disp.h" +//#include "../lvgl/src/lv_core/lv_refr.h" +#include "draw_ui.h" +#include "../../../../gcode/queue.h" + +extern lv_group_t * g; +static lv_obj_t * scr; + +#define ID_M_POINT1 1 +#define ID_M_POINT2 2 +#define ID_M_POINT3 3 +#define ID_M_POINT4 4 +#define ID_M_POINT5 5 +#define ID_MANUAL_RETURN 6 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_M_POINT1: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + + if (queue.length == 0) { + if (uiCfg.leveling_first_time) { + queue.enqueue_now_P(PSTR("G28")); + uiCfg.leveling_first_time = 0; + } + + queue.enqueue_now_P(PSTR("G1 Z10")); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("G1 X%d Y%d"), (int)gCfgItems.levelingPos[0][0], (int)gCfgItems.levelingPos[0][1]); + queue.enqueue_one_now(public_buf_l); + queue.enqueue_now_P(PSTR("G1 Z0")); + } + } + break; + case ID_M_POINT2: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (queue.length == 0) { + if (uiCfg.leveling_first_time) { + queue.enqueue_now_P(PSTR("G28")); + uiCfg.leveling_first_time = 0; + } + + queue.enqueue_now_P(PSTR("G1 Z10")); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("G1 X%d Y%d"), (int)gCfgItems.levelingPos[1][0], (int)gCfgItems.levelingPos[1][1]); + queue.enqueue_one_now(public_buf_l); + queue.enqueue_now_P(PSTR("G1 Z0")); + } + } + break; + case ID_M_POINT3: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (queue.length == 0) { + if (uiCfg.leveling_first_time) { + queue.enqueue_now_P(PSTR("G28")); + uiCfg.leveling_first_time = 0; + } + + queue.enqueue_now_P(PSTR("G1 Z10")); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("G1 X%d Y%d"), (int)gCfgItems.levelingPos[2][0], (int)gCfgItems.levelingPos[2][1]); + queue.enqueue_one_now(public_buf_l); + queue.enqueue_now_P(PSTR("G1 Z0")); + } + } + + break; + case ID_M_POINT4: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (queue.length == 0) { + if (uiCfg.leveling_first_time) { + queue.enqueue_now_P(PSTR("G28")); + uiCfg.leveling_first_time = 0; + } + + queue.enqueue_now_P(PSTR("G1 Z10")); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("G1 X%d Y%d"), (int)gCfgItems.levelingPos[3][0], (int)gCfgItems.levelingPos[3][1]); + queue.enqueue_one_now(public_buf_l); + queue.enqueue_now_P(PSTR("G1 Z0")); + } + } + break; + case ID_M_POINT5: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (queue.length == 0) { + if (uiCfg.leveling_first_time) { + queue.enqueue_now_P(PSTR("G28")); + uiCfg.leveling_first_time = 0; + } + + queue.enqueue_now_P(PSTR("G1 Z10")); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("G1 X%d Y%d"), (int)gCfgItems.levelingPos[4][0], (int)gCfgItems.levelingPos[4][1]); + queue.enqueue_one_now(public_buf_l); + queue.enqueue_now_P(PSTR("G1 Z0")); + } + } + + break; + case ID_MANUAL_RETURN: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_manualLevel(); + lv_draw_tool(); + } + break; + } +} + +void lv_draw_manualLevel(void) { + lv_obj_t *buttonPoint1, *buttonPoint2, *buttonPoint3, *buttonPoint4, *buttonPoint5; + lv_obj_t *buttonBack; + + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != LEVELING_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = LEVELING_UI; + } + disp_state = LEVELING_UI; + + scr = lv_obj_create(NULL, NULL); + + // static lv_style_t tool_style; + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, creat_title_text()); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + // Create an Image button + buttonPoint1 = lv_imgbtn_create(scr, NULL); + buttonPoint2 = lv_imgbtn_create(scr, NULL); + buttonPoint3 = lv_imgbtn_create(scr, NULL); + buttonPoint4 = lv_imgbtn_create(scr, NULL); + buttonPoint5 = lv_imgbtn_create(scr, NULL); + buttonBack = lv_imgbtn_create(scr, NULL); + + lv_obj_set_event_cb_mks(buttonPoint1, event_handler, ID_M_POINT1, NULL, 0); + lv_imgbtn_set_src(buttonPoint1, LV_BTN_STATE_REL, "F:/bmp_leveling1.bin"); + lv_imgbtn_set_src(buttonPoint1, LV_BTN_STATE_PR, "F:/bmp_leveling1.bin"); + lv_imgbtn_set_style(buttonPoint1, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonPoint1, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_obj_clear_protect(buttonPoint1, LV_PROTECT_FOLLOW); + + #if 1 + lv_obj_set_event_cb_mks(buttonPoint2, event_handler, ID_M_POINT2, NULL, 0); + lv_imgbtn_set_src(buttonPoint2, LV_BTN_STATE_REL, "F:/bmp_leveling2.bin"); + lv_imgbtn_set_src(buttonPoint2, LV_BTN_STATE_PR, "F:/bmp_leveling2.bin"); + lv_imgbtn_set_style(buttonPoint2, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonPoint2, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonPoint3, event_handler, ID_M_POINT3, NULL, 0); + lv_imgbtn_set_src(buttonPoint3, LV_BTN_STATE_REL, "F:/bmp_leveling3.bin"); + lv_imgbtn_set_src(buttonPoint3, LV_BTN_STATE_PR, "F:/bmp_leveling3.bin"); + lv_imgbtn_set_style(buttonPoint3, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonPoint3, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonPoint4, event_handler, ID_M_POINT4, NULL, 0); + lv_imgbtn_set_src(buttonPoint4, LV_BTN_STATE_REL, "F:/bmp_leveling4.bin"); + lv_imgbtn_set_src(buttonPoint4, LV_BTN_STATE_PR, "F:/bmp_leveling4.bin"); + lv_imgbtn_set_style(buttonPoint4, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonPoint4, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonPoint5, event_handler, ID_M_POINT5, NULL, 0); + lv_imgbtn_set_src(buttonPoint5, LV_BTN_STATE_REL, "F:/bmp_leveling5.bin"); + lv_imgbtn_set_src(buttonPoint5, LV_BTN_STATE_PR, "F:/bmp_leveling5.bin"); + lv_imgbtn_set_style(buttonPoint5, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonPoint5, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_MANUAL_RETURN, NULL, 0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_return.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_return.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + #endif + + lv_obj_set_pos(buttonPoint1, INTERVAL_V, titleHeight); + lv_obj_set_pos(buttonPoint2, BTN_X_PIXEL + INTERVAL_V * 2, titleHeight); + lv_obj_set_pos(buttonPoint3, BTN_X_PIXEL * 2 + INTERVAL_V * 3, titleHeight); + lv_obj_set_pos(buttonPoint4, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight); + lv_obj_set_pos(buttonPoint5, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonBack, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + + // Create labels on the image buttons + lv_btn_set_layout(buttonPoint1, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonPoint2, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonPoint3, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonPoint4, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonPoint5, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + + lv_obj_t *label_Point1 = lv_label_create(buttonPoint1, NULL); + lv_obj_t *label_Point2 = lv_label_create(buttonPoint2, NULL); + lv_obj_t *label_Point3 = lv_label_create(buttonPoint3, NULL); + lv_obj_t *label_Point4 = lv_label_create(buttonPoint4, NULL); + lv_obj_t *label_Point5 = lv_label_create(buttonPoint5, NULL); + lv_obj_t *label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(label_Point1, leveling_menu.position1); + lv_obj_align(label_Point1, buttonPoint1, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Point2, leveling_menu.position2); + lv_obj_align(label_Point2, buttonPoint2, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Point3, leveling_menu.position3); + lv_obj_align(label_Point3, buttonPoint3, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Point4, leveling_menu.position4); + lv_obj_align(label_Point4, buttonPoint4, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Point5, leveling_menu.position5); + lv_obj_align(label_Point5, buttonPoint5, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonPoint1); + lv_group_add_obj(g, buttonPoint2); + lv_group_add_obj(g, buttonPoint3); + lv_group_add_obj(g, buttonPoint4); + lv_group_add_obj(g, buttonPoint5); + lv_group_add_obj(g, buttonBack); + } + #endif +} + +void lv_clear_manualLevel() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_manuaLevel.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_manuaLevel.h new file mode 100644 index 000000000000..cfa10370e128 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_manuaLevel.h @@ -0,0 +1,34 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_manualLevel(void); +extern void lv_clear_manualLevel(); + +//extern void disp_temp_ready_print(); +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_manual_level_pos_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_manual_level_pos_settings.cpp new file mode 100644 index 000000000000..9b7200b5a97d --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_manual_level_pos_settings.cpp @@ -0,0 +1,459 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" + +#include "../../../../MarlinCore.h" +#include "../../../../module/planner.h" + +extern lv_group_t * g; +static lv_obj_t * scr; + +#define ID_MANUAL_POS_RETURN 1 +#define ID_MANUAL_POS_X1 2 +#define ID_MANUAL_POS_Y1 3 +#define ID_MANUAL_POS_X2 4 +#define ID_MANUAL_POS_Y2 5 +#define ID_MANUAL_POS_X3 6 +#define ID_MANUAL_POS_Y3 7 +#define ID_MANUAL_POS_X4 8 +#define ID_MANUAL_POS_Y4 9 +#define ID_MANUAL_POS_X5 10 +#define ID_MANUAL_POS_Y5 11 +#define ID_MANUAL_POS_DOWN 12 +#define ID_MANUAL_POS_UP 13 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_MANUAL_POS_RETURN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.para_ui_page = 0; + lv_clear_manual_level_pos_settings(); + draw_return_ui(); + } + break; + case ID_MANUAL_POS_X1: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = level_pos_x1; + lv_clear_manual_level_pos_settings(); + lv_draw_number_key(); + } + break; + case ID_MANUAL_POS_Y1: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = level_pos_y1; + lv_clear_manual_level_pos_settings(); + lv_draw_number_key(); + } + break; + case ID_MANUAL_POS_X2: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = level_pos_x2; + lv_clear_manual_level_pos_settings(); + lv_draw_number_key(); + } + break; + case ID_MANUAL_POS_Y2: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = level_pos_y2; + lv_clear_manual_level_pos_settings(); + lv_draw_number_key(); + } + break; + case ID_MANUAL_POS_X3: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = level_pos_x3; + lv_clear_manual_level_pos_settings(); + lv_draw_number_key(); + } + break; + case ID_MANUAL_POS_Y3: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = level_pos_y3; + lv_clear_manual_level_pos_settings(); + lv_draw_number_key(); + } + break; + case ID_MANUAL_POS_X4: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = level_pos_x4; + lv_clear_manual_level_pos_settings(); + lv_draw_number_key(); + } + break; + case ID_MANUAL_POS_Y4: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = level_pos_y4; + lv_clear_manual_level_pos_settings(); + lv_draw_number_key(); + } + break; + case ID_MANUAL_POS_X5: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = level_pos_y5; + lv_clear_manual_level_pos_settings(); + lv_draw_number_key(); + } + break; + case ID_MANUAL_POS_Y5: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = level_pos_y5; + lv_clear_manual_level_pos_settings(); + lv_draw_number_key(); + } + break; + case ID_MANUAL_POS_UP: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.para_ui_page = 0; + lv_clear_manual_level_pos_settings(); + lv_draw_manual_level_pos_settings(); + } + break; + case ID_MANUAL_POS_DOWN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.para_ui_page = 1; + lv_clear_manual_level_pos_settings(); + lv_draw_manual_level_pos_settings(); + } + break; + } +} + +void lv_draw_manual_level_pos_settings(void) { + lv_obj_t *buttonBack = NULL, *label_Back = NULL, *buttonTurnPage = NULL, *labelTurnPage = NULL; + lv_obj_t *labelPoint1Text = NULL, *buttonX1Value = NULL, *labelX1Value = NULL; + lv_obj_t *buttonY1Value = NULL, *labelY1Value = NULL; + lv_obj_t *labelPoint2Text = NULL, *buttonX2Value = NULL, *labelX2Value = NULL; + lv_obj_t *buttonY2Value = NULL, *labelY2Value = NULL; + lv_obj_t *labelPoint3Text = NULL, *buttonX3Value = NULL, *labelX3Value = NULL; + lv_obj_t *buttonY3Value = NULL, *labelY3Value = NULL; + lv_obj_t *labelPoint4Text = NULL, *buttonX4Value = NULL, *labelX4Value = NULL; + lv_obj_t *buttonY4Value = NULL, *labelY4Value = NULL; + lv_obj_t *labelPoint5Text = NULL, *buttonX5Value = NULL, *labelX5Value = NULL; + lv_obj_t *buttonY5Value = NULL, *labelY5Value = NULL; + lv_obj_t * line1 = NULL, * line2 = NULL, * line3 = NULL, * line4 = NULL; + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != MANUAL_LEVELING_POSIGION_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = MANUAL_LEVELING_POSIGION_UI; + } + disp_state = MANUAL_LEVELING_POSIGION_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, machine_menu.LevelingParaConfTitle); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + if (uiCfg.para_ui_page != 1) { + labelPoint1Text = lv_label_create(scr, NULL); + lv_obj_set_style(labelPoint1Text, &tft_style_label_rel); + lv_obj_set_pos(labelPoint1Text, PARA_UI_POS_X, PARA_UI_POS_Y + 10); + lv_label_set_text(labelPoint1Text, leveling_menu.position1); + + buttonX1Value = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonX1Value, PARA_UI_VALUE_POS_X_2, PARA_UI_POS_Y + PARA_UI_VALUE_V_2); + lv_obj_set_size(buttonX1Value, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonX1Value, event_handler, ID_MANUAL_POS_X1, NULL, 0); + lv_btn_set_style(buttonX1Value, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonX1Value, LV_BTN_STYLE_PR, &style_para_value); + labelX1Value = lv_label_create(buttonX1Value, NULL); + + buttonY1Value = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonY1Value, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y + PARA_UI_VALUE_V_2); + lv_obj_set_size(buttonY1Value, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonY1Value, event_handler, ID_MANUAL_POS_Y1, NULL, 0); + lv_btn_set_style(buttonY1Value, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonY1Value, LV_BTN_STYLE_PR, &style_para_value); + labelY1Value = lv_label_create(buttonY1Value, NULL); + + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1, line_points[0]); + + labelPoint2Text = lv_label_create(scr, NULL); + lv_obj_set_style(labelPoint2Text, &tft_style_label_rel); + lv_obj_set_pos(labelPoint2Text, PARA_UI_POS_X, PARA_UI_POS_Y * 2 + 10); + lv_label_set_text(labelPoint2Text, leveling_menu.position2); + + buttonX2Value = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonX2Value, PARA_UI_VALUE_POS_X_2, PARA_UI_POS_Y * 2 + PARA_UI_VALUE_V_2); + lv_obj_set_size(buttonX2Value, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonX2Value, event_handler, ID_MANUAL_POS_X2, NULL, 0); + lv_btn_set_style(buttonX2Value, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonX2Value, LV_BTN_STYLE_PR, &style_para_value); + labelX2Value = lv_label_create(buttonX2Value, NULL); + + buttonY2Value = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonY2Value, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 2 + PARA_UI_VALUE_V_2); + lv_obj_set_size(buttonY2Value, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonY2Value, event_handler, ID_MANUAL_POS_Y2, NULL, 0); + lv_btn_set_style(buttonY2Value, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonY2Value, LV_BTN_STYLE_PR, &style_para_value); + labelY2Value = lv_label_create(buttonY2Value, NULL); + + line2 = lv_line_create(scr, NULL); + lv_ex_line(line2, line_points[1]); + + labelPoint3Text = lv_label_create(scr, NULL); + lv_obj_set_style(labelPoint3Text, &tft_style_label_rel); + lv_obj_set_pos(labelPoint3Text, PARA_UI_POS_X, PARA_UI_POS_Y * 3 + 10); + lv_label_set_text(labelPoint3Text, leveling_menu.position3); + + buttonX3Value = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonX3Value, PARA_UI_VALUE_POS_X_2, PARA_UI_POS_Y * 3 + PARA_UI_VALUE_V_2); + lv_obj_set_size(buttonX3Value, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonX3Value, event_handler, ID_MANUAL_POS_X3, NULL, 0); + lv_btn_set_style(buttonX3Value, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonX3Value, LV_BTN_STYLE_PR, &style_para_value); + labelX3Value = lv_label_create(buttonX3Value, NULL); + + buttonY3Value = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonY3Value, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 3 + PARA_UI_VALUE_V_2); + lv_obj_set_size(buttonY3Value, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonY3Value, event_handler, ID_MANUAL_POS_Y3, NULL, 0); + lv_btn_set_style(buttonY3Value, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonY3Value, LV_BTN_STYLE_PR, &style_para_value); + labelY3Value = lv_label_create(buttonY3Value, NULL); + + line3 = lv_line_create(scr, NULL); + lv_ex_line(line3, line_points[2]); + + labelPoint4Text = lv_label_create(scr, NULL); + lv_obj_set_style(labelPoint4Text, &tft_style_label_rel); + lv_obj_set_pos(labelPoint4Text, PARA_UI_POS_X, PARA_UI_POS_Y * 4 + 10); + lv_label_set_text(labelPoint4Text, leveling_menu.position4); + + buttonX4Value = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonX4Value, PARA_UI_VALUE_POS_X_2, PARA_UI_POS_Y * 4 + PARA_UI_VALUE_V_2); + lv_obj_set_size(buttonX4Value, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonX4Value, event_handler, ID_MANUAL_POS_X4, NULL, 0); + lv_btn_set_style(buttonX4Value, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonX4Value, LV_BTN_STYLE_PR, &style_para_value); + labelX4Value = lv_label_create(buttonX4Value, NULL); + + buttonY4Value = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonY4Value, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 4 + PARA_UI_VALUE_V_2); + lv_obj_set_size(buttonY4Value, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonY4Value, event_handler, ID_MANUAL_POS_Y4, NULL, 0); + lv_btn_set_style(buttonY4Value, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonY4Value, LV_BTN_STYLE_PR, &style_para_value); + labelY4Value = lv_label_create(buttonY4Value, NULL); + + line4 = lv_line_create(scr, NULL); + lv_ex_line(line4, line_points[3]); + + buttonTurnPage = lv_btn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonTurnPage, event_handler, ID_MANUAL_POS_DOWN, NULL, 0); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_REL, &style_para_back); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_PR, &style_para_back); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonX1Value); + lv_group_add_obj(g, buttonY1Value); + lv_group_add_obj(g, buttonX2Value); + lv_group_add_obj(g, buttonY2Value); + lv_group_add_obj(g, buttonX3Value); + lv_group_add_obj(g, buttonY3Value); + lv_group_add_obj(g, buttonX4Value); + lv_group_add_obj(g, buttonY4Value); + lv_group_add_obj(g, buttonTurnPage); + } + #endif + } + else { + labelPoint5Text = lv_label_create(scr, NULL); + lv_obj_set_style(labelPoint5Text, &tft_style_label_rel); + lv_obj_set_pos(labelPoint5Text, PARA_UI_POS_X, PARA_UI_POS_Y + 10); + lv_label_set_text(labelPoint5Text, leveling_menu.position5); + + buttonX5Value = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonX5Value, PARA_UI_VALUE_POS_X_2, PARA_UI_POS_Y + PARA_UI_VALUE_V_2); + lv_obj_set_size(buttonX5Value, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonX5Value, event_handler, ID_MANUAL_POS_X5, NULL, 0); + lv_btn_set_style(buttonX5Value, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonX5Value, LV_BTN_STYLE_PR, &style_para_value); + labelX5Value = lv_label_create(buttonX5Value, NULL); + + buttonY5Value = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonY5Value, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y + PARA_UI_VALUE_V_2); + lv_obj_set_size(buttonY5Value, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonY5Value, event_handler, ID_MANUAL_POS_Y5, NULL, 0); + lv_btn_set_style(buttonY5Value, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonY5Value, LV_BTN_STYLE_PR, &style_para_value); + labelY5Value = lv_label_create(buttonY5Value, NULL); + + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1, line_points[0]); + + buttonTurnPage = lv_btn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonTurnPage, event_handler, ID_MANUAL_POS_UP, NULL, 0); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_REL, &style_para_back); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_PR, &style_para_back); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonX5Value); + lv_group_add_obj(g, buttonY5Value); + lv_group_add_obj(g, buttonTurnPage); + } + #endif + } + + lv_obj_set_pos(buttonTurnPage, PARA_UI_TURN_PAGE_POS_X, PARA_UI_TURN_PAGE_POS_Y); + lv_obj_set_size(buttonTurnPage, PARA_UI_BACK_BTN_X_SIZE, PARA_UI_BACK_BTN_Y_SIZE); + labelTurnPage = lv_label_create(buttonTurnPage, NULL); + + buttonBack = lv_btn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_MANUAL_POS_RETURN, NULL, 0); + lv_btn_set_style(buttonBack, LV_BTN_STYLE_REL, &style_para_back); + lv_btn_set_style(buttonBack, LV_BTN_STYLE_PR, &style_para_back); + lv_obj_set_pos(buttonBack, PARA_UI_BACL_POS_X, PARA_UI_BACL_POS_Y); + lv_obj_set_size(buttonBack, PARA_UI_BACK_BTN_X_SIZE, PARA_UI_BACK_BTN_Y_SIZE); + label_Back = lv_label_create(buttonBack, NULL); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonBack); + #endif + + if (gCfgItems.multiple_language != 0) { + if (uiCfg.para_ui_page != 1) { + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.levelingPos[0][0]); + lv_label_set_text(labelX1Value, public_buf_l); + lv_obj_align(labelX1Value, buttonX1Value, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.levelingPos[0][1]); + lv_label_set_text(labelY1Value, public_buf_l); + lv_obj_align(labelY1Value, buttonY1Value, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.levelingPos[1][0]); + lv_label_set_text(labelX2Value, public_buf_l); + lv_obj_align(labelX2Value, buttonX2Value, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.levelingPos[1][1]); + lv_label_set_text(labelY2Value, public_buf_l); + lv_obj_align(labelY2Value, buttonY2Value, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.levelingPos[2][0]); + lv_label_set_text(labelX3Value, public_buf_l); + lv_obj_align(labelX3Value, buttonX3Value, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.levelingPos[2][1]); + lv_label_set_text(labelY3Value, public_buf_l); + lv_obj_align(labelY3Value, buttonY3Value, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.levelingPos[3][0]); + lv_label_set_text(labelX4Value, public_buf_l); + lv_obj_align(labelX4Value, buttonX4Value, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.levelingPos[3][1]); + lv_label_set_text(labelY4Value, public_buf_l); + lv_obj_align(labelY4Value, buttonY4Value, LV_ALIGN_CENTER, 0, 0); + + lv_label_set_text(labelTurnPage, machine_menu.next); + lv_obj_align(labelTurnPage, buttonTurnPage, LV_ALIGN_CENTER, 0, 0); + } + else { + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.levelingPos[4][0]); + lv_label_set_text(labelX5Value, public_buf_l); + lv_obj_align(labelX5Value, buttonX5Value, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.levelingPos[4][1]); + lv_label_set_text(labelY5Value, public_buf_l); + lv_obj_align(labelY5Value, buttonY5Value, LV_ALIGN_CENTER, 0, 0); + + lv_label_set_text(labelTurnPage, machine_menu.previous); + lv_obj_align(labelTurnPage, buttonTurnPage, LV_ALIGN_CENTER, 0, 0); + } + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_CENTER, 0, 0); + } +} + +void lv_clear_manual_level_pos_settings() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_manual_level_pos_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_manual_level_pos_settings.h new file mode 100644 index 000000000000..8e89ecf559fc --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_manual_level_pos_settings.h @@ -0,0 +1,33 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_manual_level_pos_settings(void); +extern void lv_clear_manual_level_pos_settings(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_max_feedrate_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_max_feedrate_settings.cpp new file mode 100644 index 000000000000..e82124f7056c --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_max_feedrate_settings.cpp @@ -0,0 +1,335 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" + +#include "../../../../MarlinCore.h" +#include "../../../../module/planner.h" + +extern lv_group_t * g; +static lv_obj_t * scr; + +#define ID_FEED_RETURN 1 +#define ID_FEED_X 2 +#define ID_FEED_Y 3 +#define ID_FEED_Z 4 +#define ID_FEED_E0 5 +#define ID_FEED_E1 6 +#define ID_FEED_DOWN 7 +#define ID_FEED_UP 8 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_FEED_RETURN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.para_ui_page = 0; + lv_clear_max_feedrate_settings(); + draw_return_ui(); + } + break; + case ID_FEED_X: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = XMaxFeedRate; + lv_clear_max_feedrate_settings(); + lv_draw_number_key(); + } + break; + case ID_FEED_Y: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = YMaxFeedRate; + lv_clear_max_feedrate_settings(); + lv_draw_number_key(); + } + break; + case ID_FEED_Z: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = ZMaxFeedRate; + lv_clear_max_feedrate_settings(); + lv_draw_number_key(); + } + break; + case ID_FEED_E0: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = E0MaxFeedRate; + lv_clear_max_feedrate_settings(); + lv_draw_number_key(); + } + break; + case ID_FEED_E1: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = E1MaxFeedRate; + lv_clear_max_feedrate_settings(); + lv_draw_number_key(); + } + break; + case ID_FEED_UP: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.para_ui_page = 0; + lv_clear_max_feedrate_settings(); + lv_draw_max_feedrate_settings(); + } + break; + case ID_FEED_DOWN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.para_ui_page = 1; + lv_clear_max_feedrate_settings(); + lv_draw_max_feedrate_settings(); + } + break; + } +} + +void lv_draw_max_feedrate_settings(void) { + lv_obj_t *buttonBack = NULL, *label_Back = NULL, *buttonTurnPage = NULL, *labelTurnPage = NULL; + lv_obj_t *labelXText = NULL, *buttonXValue = NULL, *labelXValue = NULL; + lv_obj_t *labelYText = NULL, *buttonYValue = NULL, *labelYValue = NULL; + lv_obj_t *labelZText = NULL, *buttonZValue = NULL, *labelZValue = NULL; + lv_obj_t *labelE0Text = NULL, *buttonE0Value = NULL, *labelE0Value = NULL; + lv_obj_t *labelE1Text = NULL, *buttonE1Value = NULL, *labelE1Value = NULL; + lv_obj_t * line1 = NULL, * line2 = NULL, * line3 = NULL, * line4 = NULL; + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != MAXFEEDRATE_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = MAXFEEDRATE_UI; + } + disp_state = MAXFEEDRATE_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, machine_menu.MaxFeedRateConfTitle); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + if (uiCfg.para_ui_page != 1) { + labelXText = lv_label_create(scr, NULL); + lv_obj_set_style(labelXText, &tft_style_label_rel); + lv_obj_set_pos(labelXText, PARA_UI_POS_X, PARA_UI_POS_Y + 10); + lv_label_set_text(labelXText, machine_menu.XMaxFeedRate); + + buttonXValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonXValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y + PARA_UI_VALUE_V); + lv_obj_set_size(buttonXValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonXValue, event_handler, ID_FEED_X, NULL, 0); + lv_btn_set_style(buttonXValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonXValue, LV_BTN_STYLE_PR, &style_para_value); + lv_btn_set_layout(buttonXValue, LV_LAYOUT_OFF); + labelXValue = lv_label_create(buttonXValue, NULL); + + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1, line_points[0]); + + labelYText = lv_label_create(scr, NULL); + lv_obj_set_style(labelYText, &tft_style_label_rel); + lv_obj_set_pos(labelYText, PARA_UI_POS_X, PARA_UI_POS_Y * 2 + 10); + lv_label_set_text(labelYText, machine_menu.YMaxFeedRate); + + buttonYValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonYValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 2 + PARA_UI_VALUE_V); + lv_obj_set_size(buttonYValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonYValue, event_handler, ID_FEED_Y, NULL, 0); + lv_btn_set_style(buttonYValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonYValue, LV_BTN_STYLE_PR, &style_para_value); + lv_btn_set_layout(buttonYValue, LV_LAYOUT_OFF); + labelYValue = lv_label_create(buttonYValue, NULL); + + line2 = lv_line_create(scr, NULL); + lv_ex_line(line2, line_points[1]); + + labelZText = lv_label_create(scr, NULL); + lv_obj_set_style(labelZText, &tft_style_label_rel); + lv_obj_set_pos(labelZText, PARA_UI_POS_X, PARA_UI_POS_Y * 3 + 10); + lv_label_set_text(labelZText, machine_menu.ZMaxFeedRate); + + buttonZValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonZValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 3 + PARA_UI_VALUE_V); + lv_obj_set_size(buttonZValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonZValue, event_handler, ID_FEED_Z, NULL, 0); + lv_btn_set_style(buttonZValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonZValue, LV_BTN_STYLE_PR, &style_para_value); + lv_btn_set_layout(buttonZValue, LV_LAYOUT_OFF); + labelZValue = lv_label_create(buttonZValue, NULL); + + line3 = lv_line_create(scr, NULL); + lv_ex_line(line3, line_points[2]); + + labelE0Text = lv_label_create(scr, NULL); + lv_obj_set_style(labelE0Text, &tft_style_label_rel); + lv_obj_set_pos(labelE0Text, PARA_UI_POS_X, PARA_UI_POS_Y * 4 + 10); + lv_label_set_text(labelE0Text, machine_menu.E0MaxFeedRate); + + buttonE0Value = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonE0Value, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 4 + PARA_UI_VALUE_V); + lv_obj_set_size(buttonE0Value, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonE0Value, event_handler, ID_FEED_E0, NULL, 0); + lv_btn_set_style(buttonE0Value, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonE0Value, LV_BTN_STYLE_PR, &style_para_value); + lv_btn_set_layout(buttonE0Value, LV_LAYOUT_OFF); + labelE0Value = lv_label_create(buttonE0Value, NULL); + + line4 = lv_line_create(scr, NULL); + lv_ex_line(line4, line_points[3]); + + buttonTurnPage = lv_btn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonTurnPage, event_handler, ID_FEED_DOWN, NULL, 0); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_REL, &style_para_back); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_PR, &style_para_back); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonXValue); + lv_group_add_obj(g, buttonYValue); + lv_group_add_obj(g, buttonZValue); + lv_group_add_obj(g, buttonE0Value); + lv_group_add_obj(g, buttonTurnPage); + } + #endif + } + else { + labelE1Text = lv_label_create(scr, NULL); + lv_obj_set_style(labelE1Text, &tft_style_label_rel); + lv_obj_set_pos(labelE1Text, PARA_UI_POS_X, PARA_UI_POS_Y + 10); + lv_label_set_text(labelE1Text, machine_menu.E1MaxFeedRate); + + buttonE1Value = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonE1Value, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y + PARA_UI_VALUE_V); + lv_obj_set_size(buttonE1Value, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonE1Value, event_handler, ID_FEED_E1, NULL, 0); + lv_btn_set_style(buttonE1Value, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonE1Value, LV_BTN_STYLE_PR, &style_para_value); + lv_btn_set_layout(buttonE1Value, LV_LAYOUT_OFF); + labelE1Value = lv_label_create(buttonE1Value, NULL); + + + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1, line_points[0]); + + buttonTurnPage = lv_btn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonTurnPage, event_handler, ID_FEED_UP, NULL, 0); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_REL, &style_para_back); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_PR, &style_para_back); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonE1Value); + lv_group_add_obj(g, buttonTurnPage); + } + #endif + } + + lv_obj_set_pos(buttonTurnPage, PARA_UI_TURN_PAGE_POS_X, PARA_UI_TURN_PAGE_POS_Y); + lv_obj_set_size(buttonTurnPage, PARA_UI_BACK_BTN_X_SIZE, PARA_UI_BACK_BTN_Y_SIZE); + labelTurnPage = lv_label_create(buttonTurnPage, NULL); + + buttonBack = lv_btn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_FEED_RETURN, NULL, 0); + lv_obj_set_pos(buttonBack, PARA_UI_BACL_POS_X, PARA_UI_BACL_POS_Y); + lv_obj_set_size(buttonBack, PARA_UI_BACK_BTN_X_SIZE, PARA_UI_BACK_BTN_Y_SIZE); + lv_btn_set_style(buttonBack, LV_BTN_STYLE_REL, &style_para_back); + lv_btn_set_style(buttonBack, LV_BTN_STYLE_PR, &style_para_back); + label_Back = lv_label_create(buttonBack, NULL); + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonBack); + #endif + + if (gCfgItems.multiple_language != 0) { + if (uiCfg.para_ui_page != 1) { + + lv_label_set_text(labelTurnPage, machine_menu.next); + lv_obj_align(labelTurnPage, buttonTurnPage, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), planner.settings.max_feedrate_mm_s[X_AXIS]); + lv_label_set_text(labelXValue, public_buf_l); + lv_obj_align(labelXValue, buttonXValue, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), planner.settings.max_feedrate_mm_s[Y_AXIS]); + lv_label_set_text(labelYValue, public_buf_l); + lv_obj_align(labelYValue, buttonYValue, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), planner.settings.max_feedrate_mm_s[Z_AXIS]); + lv_label_set_text(labelZValue, public_buf_l); + lv_obj_align(labelZValue, buttonZValue, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), planner.settings.max_feedrate_mm_s[E_AXIS]); + lv_label_set_text(labelE0Value, public_buf_l); + lv_obj_align(labelE0Value, buttonE0Value, LV_ALIGN_CENTER, 0, 0); + } + else { + lv_label_set_text(labelTurnPage, machine_menu.previous); + lv_obj_align(labelTurnPage, buttonTurnPage, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), planner.settings.max_feedrate_mm_s[E_AXIS_N(1)]); + lv_label_set_text(labelE1Value, public_buf_l); + lv_obj_align(labelE1Value, buttonE1Value, LV_ALIGN_CENTER, 0, 0); + } + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_CENTER, 0, 0); + } +} + +void lv_clear_max_feedrate_settings() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_max_feedrate_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_max_feedrate_settings.h new file mode 100644 index 000000000000..78caca5adea4 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_max_feedrate_settings.h @@ -0,0 +1,33 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_max_feedrate_settings(void); +extern void lv_clear_max_feedrate_settings(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_motor_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_motor_settings.cpp new file mode 100644 index 000000000000..f6568df14314 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_motor_settings.cpp @@ -0,0 +1,343 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" + +#include "../../../../MarlinCore.h" + +extern lv_group_t * g; +static lv_obj_t * scr; + +#define ID_MOTOR_RETURN 1 +#define ID_MOTOR_STEPS 2 +#define ID_MOTOR_STEPS_ARROW 3 +#define ID_MOTOR_TMC_CURRENT 4 +#define ID_MOTOR_TMC_CURRENT_ARROW 5 +#define ID_MOTOR_STEP_MODE 6 +#define ID_MOTOR_STEP_MODE_ARROW 7 +#define ID_HOME_SENSE 8 +#define ID_HOME_SENSE_ARROW 9 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_MOTOR_RETURN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_motor_settings(); + draw_return_ui(); + } + break; + case ID_MOTOR_STEPS: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_motor_settings(); + lv_draw_step_settings(); + } + break; + case ID_MOTOR_STEPS_ARROW: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_motor_settings(); + lv_draw_step_settings(); + } + break; + #if USE_SENSORLESS + case ID_HOME_SENSE: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_motor_settings(); + lv_draw_homing_sensitivity_settings(); + } + break; + case ID_HOME_SENSE_ARROW: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_motor_settings(); + lv_draw_homing_sensitivity_settings(); + } + break; + #endif + #if HAS_TRINAMIC_CONFIG + case ID_MOTOR_TMC_CURRENT: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_motor_settings(); + lv_draw_tmc_current_settings(); + } + break; + case ID_MOTOR_TMC_CURRENT_ARROW: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_motor_settings(); + lv_draw_tmc_current_settings(); + } + break; + #if HAS_STEALTHCHOP + case ID_MOTOR_STEP_MODE: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_motor_settings(); + lv_draw_tmc_step_mode_settings(); + } + break; + case ID_MOTOR_STEP_MODE_ARROW: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_motor_settings(); + lv_draw_tmc_step_mode_settings(); + } + break; + #endif + #endif + } +} + +void lv_draw_motor_settings(void) { + lv_obj_t *buttonBack, *label_Back; + lv_obj_t *buttonSteps, *labelSteps, *buttonStepsNarrow; + lv_obj_t * line1; + #if USE_SENSORLESS + lv_obj_t *buttonSensitivity, *labelSensitivity, *buttonSensitivityNarrow; + lv_obj_t * line2; + #endif + #if HAS_TRINAMIC_CONFIG + #if USE_SENSORLESS + lv_obj_t * line3; + #else + lv_obj_t * line2; + #endif + lv_obj_t *buttonTMCcurrent, *labelTMCcurrent, *buttonTMCcurrentNarrow; + #if HAS_STEALTHCHOP + #if USE_SENSORLESS + lv_obj_t * line4; + #else + lv_obj_t * line3; + #endif + lv_obj_t *buttonStepMode, *labelStepMode, *buttonStepModeNarrow; + #endif + #endif + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != MOTOR_SETTINGS_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = MOTOR_SETTINGS_UI; + } + disp_state = MOTOR_SETTINGS_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, machine_menu.MotorConfTitle); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + buttonSteps = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(buttonSteps, PARA_UI_POS_X, PARA_UI_POS_Y); /*Set its position*/ + lv_obj_set_size(buttonSteps, PARA_UI_SIZE_X, PARA_UI_SIZE_Y); /*Set its size*/ + //lv_obj_set_event_cb(buttonMachine, event_handler); + lv_obj_set_event_cb_mks(buttonSteps, event_handler, ID_MOTOR_STEPS, NULL, 0); + lv_btn_set_style(buttonSteps, LV_BTN_STYLE_REL, &tft_style_label_rel); /*Set the button's released style*/ + lv_btn_set_style(buttonSteps, LV_BTN_STYLE_PR, &tft_style_label_pre); /*Set the button's pressed style*/ + lv_btn_set_layout(buttonSteps, LV_LAYOUT_OFF); + labelSteps = lv_label_create(buttonSteps, NULL); /*Add a label to the button*/ + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonSteps); + #endif + + buttonStepsNarrow = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonStepsNarrow, PARA_UI_POS_X + PARA_UI_SIZE_X, PARA_UI_POS_Y + PARA_UI_ARROW_V); + lv_obj_set_event_cb_mks(buttonStepsNarrow, event_handler, ID_MOTOR_STEPS_ARROW, NULL, 0); + lv_imgbtn_set_src(buttonStepsNarrow, LV_BTN_STATE_REL, "F:/bmp_arrow.bin"); + lv_imgbtn_set_src(buttonStepsNarrow, LV_BTN_STATE_PR, "F:/bmp_arrow.bin"); + lv_imgbtn_set_style(buttonStepsNarrow, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonStepsNarrow, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonStepsNarrow, LV_LAYOUT_OFF); + + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1, line_points[0]); + + #if USE_SENSORLESS + buttonSensitivity = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(buttonSensitivity, PARA_UI_POS_X, PARA_UI_POS_Y * 2); /*Set its position*/ + lv_obj_set_size(buttonSensitivity, PARA_UI_SIZE_X, PARA_UI_SIZE_Y); /*Set its size*/ + //lv_obj_set_event_cb(buttonMachine, event_handler); + lv_obj_set_event_cb_mks(buttonSensitivity, event_handler, ID_HOME_SENSE, NULL, 0); + lv_btn_set_style(buttonSensitivity, LV_BTN_STYLE_REL, &tft_style_label_rel); /*Set the button's released style*/ + lv_btn_set_style(buttonSensitivity, LV_BTN_STYLE_PR, &tft_style_label_pre); /*Set the button's pressed style*/ + lv_btn_set_layout(buttonSensitivity, LV_LAYOUT_OFF); + labelSensitivity = lv_label_create(buttonSensitivity, NULL); /*Add a label to the button*/ + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonSensitivity); + #endif + + buttonSensitivityNarrow = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonSensitivityNarrow, PARA_UI_POS_X + PARA_UI_SIZE_X, PARA_UI_POS_Y * 2 + PARA_UI_ARROW_V); + lv_obj_set_event_cb_mks(buttonSensitivityNarrow, event_handler, ID_HOME_SENSE_ARROW, NULL, 0); + lv_imgbtn_set_src(buttonSensitivityNarrow, LV_BTN_STATE_REL, "F:/bmp_arrow.bin"); + lv_imgbtn_set_src(buttonSensitivityNarrow, LV_BTN_STATE_PR, "F:/bmp_arrow.bin"); + lv_imgbtn_set_style(buttonSensitivityNarrow, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonSensitivityNarrow, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonSensitivityNarrow, LV_LAYOUT_OFF); + + line2 = lv_line_create(scr, NULL); + lv_ex_line(line2, line_points[1]); + #endif + + + #if HAS_TRINAMIC_CONFIG + buttonTMCcurrent = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(buttonTMCcurrent, PARA_UI_POS_X, TERN(USE_SENSORLESS, PARA_UI_POS_Y * 3, PARA_UI_POS_Y * 2)); + lv_obj_set_size(buttonTMCcurrent, PARA_UI_SIZE_X, PARA_UI_SIZE_Y); /*Set its size*/ + //lv_obj_set_event_cb(buttonMachine, event_handler); + lv_obj_set_event_cb_mks(buttonTMCcurrent, event_handler, ID_MOTOR_TMC_CURRENT, NULL, 0); + lv_btn_set_style(buttonTMCcurrent, LV_BTN_STYLE_REL, &tft_style_label_rel); /*Set the button's released style*/ + lv_btn_set_style(buttonTMCcurrent, LV_BTN_STYLE_PR, &tft_style_label_pre); /*Set the button's pressed style*/ + lv_btn_set_layout(buttonTMCcurrent, LV_LAYOUT_OFF); + labelTMCcurrent = lv_label_create(buttonTMCcurrent, NULL); /*Add a label to the button*/ + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonTMCcurrent); + #endif + + buttonTMCcurrentNarrow = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonTMCcurrentNarrow, PARA_UI_POS_X + PARA_UI_SIZE_X, TERN(USE_SENSORLESS, PARA_UI_POS_Y * 3, PARA_UI_POS_Y * 2) + PARA_UI_ARROW_V); + lv_obj_set_event_cb_mks(buttonTMCcurrentNarrow, event_handler, ID_MOTOR_TMC_CURRENT_ARROW, NULL, 0); + lv_imgbtn_set_src(buttonTMCcurrentNarrow, LV_BTN_STATE_REL, "F:/bmp_arrow.bin"); + lv_imgbtn_set_src(buttonTMCcurrentNarrow, LV_BTN_STATE_PR, "F:/bmp_arrow.bin"); + lv_imgbtn_set_style(buttonTMCcurrentNarrow, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonTMCcurrentNarrow, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonTMCcurrentNarrow, LV_LAYOUT_OFF); + #if USE_SENSORLESS + line3 = lv_line_create(scr, NULL); + lv_ex_line(line3, line_points[2]); + #else + line2 = lv_line_create(scr, NULL); + lv_ex_line(line2, line_points[1]); + #endif + + #if HAS_STEALTHCHOP + buttonStepMode = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(buttonStepMode, PARA_UI_POS_X, TERN(USE_SENSORLESS, PARA_UI_POS_Y * 4, PARA_UI_POS_Y * 3)); + lv_obj_set_size(buttonStepMode, PARA_UI_SIZE_X, PARA_UI_SIZE_Y); /*Set its size*/ + lv_obj_set_event_cb_mks(buttonStepMode, event_handler, ID_MOTOR_STEP_MODE, NULL, 0); + lv_btn_set_style(buttonStepMode, LV_BTN_STYLE_REL, &tft_style_label_rel); /*Set the button's released style*/ + lv_btn_set_style(buttonStepMode, LV_BTN_STYLE_PR, &tft_style_label_pre); /*Set the button's pressed style*/ + lv_btn_set_layout(buttonStepMode, LV_LAYOUT_OFF); + labelStepMode = lv_label_create(buttonStepMode, NULL); /*Add a label to the button*/ + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonStepMode); + #endif + + buttonStepModeNarrow = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonStepModeNarrow, PARA_UI_POS_X + PARA_UI_SIZE_X, TERN(USE_SENSORLESS, PARA_UI_POS_Y * 4, PARA_UI_POS_Y * 3) + PARA_UI_ARROW_V); + lv_obj_set_event_cb_mks(buttonStepModeNarrow, event_handler, ID_MOTOR_STEP_MODE_ARROW, NULL, 0); + lv_imgbtn_set_src(buttonStepModeNarrow, LV_BTN_STATE_REL, "F:/bmp_arrow.bin"); + lv_imgbtn_set_src(buttonStepModeNarrow, LV_BTN_STATE_PR, "F:/bmp_arrow.bin"); + lv_imgbtn_set_style(buttonStepModeNarrow, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonStepModeNarrow, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonStepModeNarrow, LV_LAYOUT_OFF); + + #if USE_SENSORLESS + line4 = lv_line_create(scr, NULL); + lv_ex_line(line4, line_points[3]); + #else + line3 = lv_line_create(scr, NULL); + lv_ex_line(line3, line_points[2]); + #endif + + #endif // HAS_STEALTHCHOP + + #endif // HAS_TRINAMIC_CONFIG + + buttonBack = lv_imgbtn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_MOTOR_RETURN, NULL, 0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_obj_set_pos(buttonBack, PARA_UI_BACL_POS_X, PARA_UI_BACL_POS_Y); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + label_Back = lv_label_create(buttonBack, NULL); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonBack); + #endif + + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_CENTER, 0, 0); + + lv_label_set_text(labelSteps, machine_menu.StepsConf); + lv_obj_align(labelSteps, buttonSteps, LV_ALIGN_IN_LEFT_MID, 0, 0); + + #if USE_SENSORLESS + lv_label_set_text(labelSensitivity, machine_menu.HomingSensitivityConf); + lv_obj_align(labelSensitivity, buttonSensitivity, LV_ALIGN_IN_LEFT_MID, 0, 0); + #endif + #if HAS_TRINAMIC_CONFIG + lv_label_set_text(labelTMCcurrent, machine_menu.TMCcurrentConf); + lv_obj_align(labelTMCcurrent, buttonTMCcurrent, LV_ALIGN_IN_LEFT_MID, 0, 0); + #if HAS_STEALTHCHOP + lv_label_set_text(labelStepMode, machine_menu.TMCStepModeConf); + lv_obj_align(labelStepMode, buttonStepMode, LV_ALIGN_IN_LEFT_MID, 0, 0); + #endif + #endif + } + +} + +void lv_clear_motor_settings() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_motor_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_motor_settings.h new file mode 100644 index 000000000000..9a1c7a4db517 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_motor_settings.h @@ -0,0 +1,33 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_motor_settings(void); +extern void lv_clear_motor_settings(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_move_motor.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_move_motor.cpp new file mode 100644 index 000000000000..a6c0c0551aba --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_move_motor.cpp @@ -0,0 +1,347 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "../../../../MarlinCore.h" +#include "lv_conf.h" +//#include "../lvgl/src/lv_objx/lv_imgbtn.h" +//#include "../lvgl/src/lv_objx/lv_img.h" +//#include "../lvgl/src/lv_core/lv_disp.h" +//#include "../lvgl/src/lv_core/lv_refr.h" +#include "draw_ui.h" +#include "../../../../gcode/queue.h" + +extern lv_group_t * g; +static lv_obj_t * scr; + +static lv_obj_t *labelV, *buttonV; + +#define ID_M_X_P 1 +#define ID_M_X_N 2 +#define ID_M_Y_P 3 +#define ID_M_Y_N 4 +#define ID_M_Z_P 5 +#define ID_M_Z_N 6 +#define ID_M_STEP 7 +#define ID_M_RETURN 8 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_M_X_P: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (queue.length <= (BUFSIZE - 3)) { + ZERO(public_buf_l); + queue.enqueue_one_P(PSTR("G91")); + sprintf_P(public_buf_l, PSTR("G1 X%3.1f F%d"), uiCfg.move_dist, uiCfg.moveSpeed); + queue.enqueue_one_now(public_buf_l); + queue.enqueue_one_P(PSTR("G90")); + } + } + break; + case ID_M_X_N: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (queue.length <= (BUFSIZE - 3)) { + ZERO(public_buf_l); + queue.enqueue_now_P(PSTR("G91")); + sprintf_P(public_buf_l, PSTR("G1 X-%3.1f F%d"), uiCfg.move_dist, uiCfg.moveSpeed); + queue.enqueue_one_now(public_buf_l); + queue.enqueue_now_P(PSTR("G90")); + } + } + break; + case ID_M_Y_P: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (queue.length <= (BUFSIZE - 3)) { + ZERO(public_buf_l); + queue.enqueue_now_P(PSTR("G91")); + sprintf_P(public_buf_l, PSTR("G1 Y%3.1f F%d"), uiCfg.move_dist, uiCfg.moveSpeed); + queue.enqueue_one_now(public_buf_l); + queue.enqueue_now_P(PSTR("G90")); + } + } + break; + case ID_M_Y_N: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (queue.length <= (BUFSIZE - 3)) { + ZERO(public_buf_l); + queue.enqueue_now_P(PSTR("G91")); + sprintf_P(public_buf_l, PSTR("G1 Y-%3.1f F%d"), uiCfg.move_dist, uiCfg.moveSpeed); + queue.enqueue_one_now(public_buf_l); + queue.enqueue_now_P(PSTR("G90")); + } + } + break; + case ID_M_Z_P: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (queue.length <= (BUFSIZE - 3)) { + ZERO(public_buf_l); + queue.enqueue_now_P(PSTR("G91")); + sprintf_P(public_buf_l, PSTR("G1 Z%3.1f F%d"), uiCfg.move_dist, uiCfg.moveSpeed); + queue.enqueue_one_now(public_buf_l); + queue.enqueue_now_P(PSTR("G90")); + } + } + break; + case ID_M_Z_N: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (queue.length <= (BUFSIZE - 3)) { + ZERO(public_buf_l); + queue.enqueue_now_P(PSTR("G91")); + sprintf_P(public_buf_l, PSTR("G1 Z-%3.1f F%d"), uiCfg.move_dist, uiCfg.moveSpeed); + queue.enqueue_one_now(public_buf_l); + queue.enqueue_now_P(PSTR("G90")); + } + } + break; + case ID_M_STEP: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (abs(10 * (int)uiCfg.move_dist) == 100) + uiCfg.move_dist = 0.1; + else + uiCfg.move_dist *= (float)10; + + disp_move_dist(); + } + + break; + case ID_M_RETURN: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + clear_cur_ui(); + draw_return_ui(); + } + break; + } +} + +void lv_draw_move_motor(void) { + lv_obj_t *buttonXI, *buttonXD, *buttonYI, *buttonYD, *buttonZI, *buttonZD, *buttonBack; + + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != MOVE_MOTOR_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = MOVE_MOTOR_UI; + } + disp_state = MOVE_MOTOR_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, creat_title_text()); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + // Create an Image button + buttonXI = lv_imgbtn_create(scr, NULL); + buttonXD = lv_imgbtn_create(scr, NULL); + buttonYI = lv_imgbtn_create(scr, NULL); + buttonYD = lv_imgbtn_create(scr, NULL); + buttonZI = lv_imgbtn_create(scr, NULL); + buttonZD = lv_imgbtn_create(scr, NULL); + buttonV = lv_imgbtn_create(scr, NULL); + buttonBack = lv_imgbtn_create(scr, NULL); + + lv_obj_set_event_cb_mks(buttonXI, event_handler, ID_M_X_P, NULL, 0); + lv_imgbtn_set_src(buttonXI, LV_BTN_STATE_REL, "F:/bmp_xAdd.bin"); + lv_imgbtn_set_src(buttonXI, LV_BTN_STATE_PR, "F:/bmp_xAdd.bin"); + lv_imgbtn_set_style(buttonXI, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonXI, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_obj_clear_protect(buttonXI, LV_PROTECT_FOLLOW); + + #if 1 + lv_obj_set_event_cb_mks(buttonXD, event_handler, ID_M_X_N, NULL, 0); + lv_imgbtn_set_src(buttonXD, LV_BTN_STATE_REL, "F:/bmp_xDec.bin"); + lv_imgbtn_set_src(buttonXD, LV_BTN_STATE_PR, "F:/bmp_xDec.bin"); + lv_imgbtn_set_style(buttonXD, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonXD, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonYI, event_handler, ID_M_Y_P, NULL, 0); + lv_imgbtn_set_src(buttonYI, LV_BTN_STATE_REL, "F:/bmp_yAdd.bin"); + lv_imgbtn_set_src(buttonYI, LV_BTN_STATE_PR, "F:/bmp_yAdd.bin"); + lv_imgbtn_set_style(buttonYI, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonYI, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonYD, event_handler, ID_M_Y_N, NULL, 0); + lv_imgbtn_set_src(buttonYD, LV_BTN_STATE_REL, "F:/bmp_yDec.bin"); + lv_imgbtn_set_src(buttonYD, LV_BTN_STATE_PR, "F:/bmp_yDec.bin"); + lv_imgbtn_set_style(buttonYD, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonYD, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonZI, event_handler, ID_M_Z_P, NULL, 0); + lv_imgbtn_set_src(buttonZI, LV_BTN_STATE_REL, "F:/bmp_zAdd.bin"); + lv_imgbtn_set_src(buttonZI, LV_BTN_STATE_PR, "F:/bmp_zAdd.bin"); + lv_imgbtn_set_style(buttonZI, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonZI, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonZD, event_handler, ID_M_Z_N, NULL, 0); + lv_imgbtn_set_src(buttonZD, LV_BTN_STATE_REL, "F:/bmp_zDec.bin"); + lv_imgbtn_set_src(buttonZD, LV_BTN_STATE_PR, "F:/bmp_zDec.bin"); + lv_imgbtn_set_style(buttonZD, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonZD, LV_BTN_STATE_REL, &tft_style_label_rel); + + //lv_obj_set_event_cb_mks(buttonV, event_handler,ID_T_MORE,"bmp_More.bin",0); + lv_obj_set_event_cb_mks(buttonV, event_handler, ID_M_STEP, NULL, 0); + lv_imgbtn_set_style(buttonV, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonV, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_M_RETURN, NULL, 0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_return.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_return.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + #endif // if 1 + + lv_obj_set_pos(buttonXI, INTERVAL_V, titleHeight); + lv_obj_set_pos(buttonYI, BTN_X_PIXEL + INTERVAL_V * 2, titleHeight); + lv_obj_set_pos(buttonZI, BTN_X_PIXEL * 2 + INTERVAL_V * 3, titleHeight); + lv_obj_set_pos(buttonV, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight); + lv_obj_set_pos(buttonXD, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonYD, BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonZD, BTN_X_PIXEL * 2 + INTERVAL_V * 3, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonBack, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + + // Create labels on the image buttons + lv_btn_set_layout(buttonXI, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonXD, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonYI, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonYD, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonZI, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonZD, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonV, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + + lv_obj_t *labelXI = lv_label_create(buttonXI, NULL); + lv_obj_t *labelXD = lv_label_create(buttonXD, NULL); + lv_obj_t *labelYI = lv_label_create(buttonYI, NULL); + lv_obj_t *labelYD = lv_label_create(buttonYD, NULL); + lv_obj_t *labelZI = lv_label_create(buttonZI, NULL); + lv_obj_t *labelZD = lv_label_create(buttonZD, NULL); + labelV = lv_label_create(buttonV, NULL); + lv_obj_t *label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(labelXI, move_menu.x_add); + lv_obj_align(labelXI, buttonXI, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelXD, move_menu.x_dec); + lv_obj_align(labelXD, buttonXD, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelYI, move_menu.y_add); + lv_obj_align(labelYI, buttonYI, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelYD, move_menu.y_dec); + lv_obj_align(labelYD, buttonYD, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelZI, move_menu.z_add); + lv_obj_align(labelZI, buttonZI, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelZD, move_menu.z_dec); + lv_obj_align(labelZD, buttonZD, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonXI); + lv_group_add_obj(g, buttonXD); + lv_group_add_obj(g, buttonYI); + lv_group_add_obj(g, buttonYD); + lv_group_add_obj(g, buttonZI); + lv_group_add_obj(g, buttonZD); + lv_group_add_obj(g, buttonV); + lv_group_add_obj(g, buttonBack); + } + #endif + + disp_move_dist(); +} + +void disp_move_dist() { + // char buf[30] = {0}; + + if ((int)(10 * uiCfg.move_dist) == 1) { + lv_imgbtn_set_src(buttonV, LV_BTN_STATE_REL, "F:/bmp_step_move0_1.bin"); + lv_imgbtn_set_src(buttonV, LV_BTN_STATE_PR, "F:/bmp_step_move0_1.bin"); + } + else if ((int)(10 * uiCfg.move_dist) == 10) { + lv_imgbtn_set_src(buttonV, LV_BTN_STATE_REL, "F:/bmp_step_move1.bin"); + lv_imgbtn_set_src(buttonV, LV_BTN_STATE_PR, "F:/bmp_step_move1.bin"); + } + else if ((int)(10 * uiCfg.move_dist) == 100) { + lv_imgbtn_set_src(buttonV, LV_BTN_STATE_REL, "F:/bmp_step_move10.bin"); + lv_imgbtn_set_src(buttonV, LV_BTN_STATE_PR, "F:/bmp_step_move10.bin"); + } + if (gCfgItems.multiple_language != 0) { + if ((int)(10 * uiCfg.move_dist) == 1) { + lv_label_set_text(labelV, move_menu.step_01mm); + lv_obj_align(labelV, buttonV, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + else if ((int)(10 * uiCfg.move_dist) == 10) { + lv_label_set_text(labelV, move_menu.step_1mm); + lv_obj_align(labelV, buttonV, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + else if ((int)(10 * uiCfg.move_dist) == 100) { + lv_label_set_text(labelV, move_menu.step_10mm); + lv_obj_align(labelV, buttonV, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + } +} + +void lv_clear_move_motor() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_move_motor.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_move_motor.h new file mode 100644 index 000000000000..fdbb61f6f95f --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_move_motor.h @@ -0,0 +1,35 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_move_motor(void); +extern void lv_clear_move_motor(); +extern void disp_move_dist(); + +//extern void disp_temp_ready_print(); +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_number_key.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_number_key.cpp new file mode 100644 index 000000000000..4842776304d7 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_number_key.cpp @@ -0,0 +1,981 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +//#include "../../lvgl/src/lv_objx/lv_imgbtn.h" +//#include "../../lvgl/src/lv_objx/lv_img.h" +//#include "../../lvgl/src/lv_core/lv_disp.h" +//#include "../../lvgl/src/lv_core/lv_refr.h" +//#include "../../MarlinCore.h" +#include "draw_ui.h" + +#include "../../../../MarlinCore.h" +#include "../../../../module/temperature.h" +#include "../../../../gcode/queue.h" + +#if ENABLED(POWER_LOSS_RECOVERY) + #include "../../../../feature/powerloss.h" +#endif + +#include "../../../../gcode/gcode.h" +#include "../../../../module/planner.h" + +#if HAS_TRINAMIC_CONFIG + #include "../../../../module/stepper/indirection.h" + #include "../../../../feature/tmc_util.h" +#endif + +#if HAS_BED_PROBE + #include "../../../../module/probe.h" +#endif + +extern lv_group_t * g; +static lv_obj_t * scr; +static lv_obj_t *buttonValue = NULL; +static lv_obj_t *labelValue = NULL; + +static char key_value[11] = {0}; +static uint8_t cnt = 0; +static char point_flg = 1; + +#define ID_NUM_KEY1 1 +#define ID_NUM_KEY2 2 +#define ID_NUM_KEY3 3 +#define ID_NUM_KEY4 4 +#define ID_NUM_KEY5 5 +#define ID_NUM_KEY6 6 +#define ID_NUM_KEY7 7 +#define ID_NUM_KEY8 8 +#define ID_NUM_KEY9 9 +#define ID_NUM_KEY0 10 +#define ID_NUM_BACK 11 +#define ID_NUM_RESET 12 +#define ID_NUM_CONFIRM 13 +#define ID_NUM_POINT 14 +#define ID_NUM_NAGETIVE 15 + +static void disp_key_value() { + char *temp; + #if HAS_TRINAMIC_CONFIG + float milliamps; + #endif + + ZERO(public_buf_m); + + switch (value) { + case PrintAcceleration: + sprintf_P(public_buf_m, PSTR("%.1f"), planner.settings.acceleration); + break; + case RetractAcceleration: + sprintf_P(public_buf_m, PSTR("%.1f"), planner.settings.retract_acceleration); + break; + case TravelAcceleration: + sprintf_P(public_buf_m, PSTR("%.1f"), planner.settings.travel_acceleration); + break; + case XAcceleration: + sprintf_P(public_buf_m, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[X_AXIS]); + break; + case YAcceleration: + sprintf_P(public_buf_m, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[Y_AXIS]); + break; + case ZAcceleration: + sprintf_P(public_buf_m, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[Z_AXIS]); + break; + case E0Acceleration: + sprintf_P(public_buf_m, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[E_AXIS]); + break; + case E1Acceleration: + sprintf_P(public_buf_m, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(1)]); + break; + case XMaxFeedRate: + sprintf_P(public_buf_m, PSTR("%.1f"), planner.settings.max_feedrate_mm_s[X_AXIS]); + break; + case YMaxFeedRate: + sprintf_P(public_buf_m, PSTR("%.1f"), planner.settings.max_feedrate_mm_s[Y_AXIS]); + break; + case ZMaxFeedRate: + sprintf_P(public_buf_m, PSTR("%.1f"), planner.settings.max_feedrate_mm_s[Z_AXIS]); + break; + case E0MaxFeedRate: + sprintf_P(public_buf_m, PSTR("%.1f"), planner.settings.max_feedrate_mm_s[E_AXIS]); + break; + case E1MaxFeedRate: + sprintf_P(public_buf_m, PSTR("%.1f"), planner.settings.max_feedrate_mm_s[E_AXIS_N(1)]); + break; + + case XJerk: + #if HAS_CLASSIC_JERK + sprintf_P(public_buf_m, PSTR("%.1f"), planner.max_jerk[X_AXIS]); + #endif + break; + case YJerk: + #if HAS_CLASSIC_JERK + sprintf_P(public_buf_m, PSTR("%.1f"), planner.max_jerk[Y_AXIS]); + #endif + break; + case ZJerk: + #if HAS_CLASSIC_JERK + sprintf_P(public_buf_m, PSTR("%.1f"), planner.max_jerk[Z_AXIS]); + #endif + break; + case EJerk: + #if HAS_CLASSIC_JERK + sprintf_P(public_buf_m, PSTR("%.1f"), planner.max_jerk[E_AXIS]); + #endif + break; + + case Xstep: + sprintf_P(public_buf_m, PSTR("%.1f"), planner.settings.axis_steps_per_mm[X_AXIS]); + + break; + case Ystep: + sprintf_P(public_buf_m, PSTR("%.1f"), planner.settings.axis_steps_per_mm[Y_AXIS]); + + break; + case Zstep: + sprintf_P(public_buf_m, PSTR("%.1f"), planner.settings.axis_steps_per_mm[Z_AXIS]); + + break; + case E0step: + sprintf_P(public_buf_m, PSTR("%.1f"), planner.settings.axis_steps_per_mm[E_AXIS]); + + break; + case E1step: + sprintf_P(public_buf_m, PSTR("%.1f"), planner.settings.axis_steps_per_mm[E_AXIS_N(1)]); + break; + + case Xcurrent: + #if AXIS_IS_TMC(X) + milliamps = stepperX.getMilliamps(); + sprintf_P(public_buf_m, PSTR("%.1f"), milliamps); + #endif + break; + + case Ycurrent: + #if AXIS_IS_TMC(Y) + milliamps = stepperY.getMilliamps(); + sprintf_P(public_buf_m, PSTR("%.1f"), milliamps); + #endif + break; + + case Zcurrent: + #if AXIS_IS_TMC(Z) + milliamps = stepperZ.getMilliamps(); + sprintf_P(public_buf_m, PSTR("%.1f"), milliamps); + #endif + break; + + case E0current: + #if AXIS_IS_TMC(E0) + milliamps = stepperE0.getMilliamps(); + sprintf_P(public_buf_m, PSTR("%.1f"), milliamps); + #endif + break; + + case E1current: + #if AXIS_IS_TMC(E1) + milliamps = stepperE1.getMilliamps(); + sprintf_P(public_buf_m, PSTR("%.1f"), milliamps); + #endif + break; + + case pause_pos_x: + sprintf_P(public_buf_m, PSTR("%.1f"), gCfgItems.pausePosX); + break; + case pause_pos_y: + sprintf_P(public_buf_m, PSTR("%.1f"), gCfgItems.pausePosY); + break; + case pause_pos_z: + sprintf_P(public_buf_m, PSTR("%.1f"), gCfgItems.pausePosZ); + break; + case level_pos_x1: + sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.levelingPos[0][0]); + break; + case level_pos_y1: + sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.levelingPos[0][1]); + break; + case level_pos_x2: + sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.levelingPos[1][0]); + break; + case level_pos_y2: + sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.levelingPos[1][1]); + break; + case level_pos_x3: + sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.levelingPos[2][0]); + break; + case level_pos_y3: + sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.levelingPos[2][1]); + break; + case level_pos_x4: + sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.levelingPos[3][0]); + break; + case level_pos_y4: + sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.levelingPos[3][1]); + break; + case level_pos_x5: + sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.levelingPos[4][0]); + break; + case level_pos_y5: + sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.levelingPos[4][1]); + break; + #if HAS_BED_PROBE + case x_offset: + #if HAS_PROBE_XY_OFFSET + sprintf_P(public_buf_m, PSTR("%.1f"), probe.offset.x); + #endif + break; + case y_offset: + #if HAS_PROBE_XY_OFFSET + sprintf_P(public_buf_m, PSTR("%.1f"), probe.offset.y); + #endif + break; + case z_offset: + sprintf_P(public_buf_m, PSTR("%.1f"), probe.offset.z); + break; + #endif + case load_length: + sprintf_P(public_buf_m, PSTR("%d"), gCfgItems.filamentchange_load_length); + break; + case load_speed: + sprintf_P(public_buf_m, PSTR("%d"), gCfgItems.filamentchange_load_speed); + break; + case unload_length: + sprintf_P(public_buf_m, PSTR("%d"), gCfgItems.filamentchange_unload_length); + break; + case unload_speed: + sprintf_P(public_buf_m, PSTR("%d"), gCfgItems.filamentchange_unload_speed); + break; + case filament_temp: + sprintf_P(public_buf_m, PSTR("%d"), gCfgItems.filament_limit_temper); + break; + case x_sensitivity: + #if X_SENSORLESS + sprintf_P(public_buf_m, PSTR("%d"), TERN(X_SENSORLESS, stepperX.homing_threshold(), 0)); + #endif + break; + case y_sensitivity: + #if Y_SENSORLESS + sprintf_P(public_buf_m, PSTR("%d"), TERN(Y_SENSORLESS, stepperY.homing_threshold(), 0)); + #endif + break; + case z_sensitivity: + #if Z_SENSORLESS + sprintf_P(public_buf_m, PSTR("%d"), TERN(Z_SENSORLESS, stepperZ.homing_threshold(), 0)); + #endif + break; + case z2_sensitivity: + #if Z2_SENSORLESS + sprintf_P(public_buf_m, PSTR("%d"), TERN(Z2_SENSORLESS, stepperZ2.homing_threshold(), 0)); + #endif + break; + } + ZERO(key_value); + strcpy(key_value, public_buf_m); + cnt = strlen(key_value); + temp = strchr(key_value, '.'); + if (temp) + point_flg = 0; + else + point_flg = 1; + lv_label_set_text(labelValue, key_value); + lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0); + +} + +static void set_value_confirm() { + #if HAS_TRINAMIC_CONFIG + uint16_t current_mA; + #endif + switch (value) { + case PrintAcceleration: + planner.settings.acceleration = atof(key_value); + break; + case RetractAcceleration: + planner.settings.retract_acceleration = atof(key_value); + break; + case TravelAcceleration: + planner.settings.travel_acceleration = atof(key_value); + break; + case XAcceleration: + planner.settings.max_acceleration_mm_per_s2[X_AXIS] = atof(key_value); + break; + case YAcceleration: + planner.settings.max_acceleration_mm_per_s2[Y_AXIS] = atof(key_value); + break; + case ZAcceleration: + planner.settings.max_acceleration_mm_per_s2[Z_AXIS] = atof(key_value); + break; + case E0Acceleration: + planner.settings.max_acceleration_mm_per_s2[E_AXIS] = atof(key_value); + break; + case E1Acceleration: + planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(1)] = atof(key_value); + break; + case XMaxFeedRate: + planner.settings.max_feedrate_mm_s[X_AXIS] = atof(key_value); + break; + case YMaxFeedRate: + planner.settings.max_feedrate_mm_s[Y_AXIS] = atof(key_value); + break; + case ZMaxFeedRate: + planner.settings.max_feedrate_mm_s[Z_AXIS] = atof(key_value); + break; + case E0MaxFeedRate: + planner.settings.max_feedrate_mm_s[E_AXIS] = atof(key_value); + break; + case E1MaxFeedRate: + planner.settings.max_feedrate_mm_s[E_AXIS_N(1)] = atof(key_value); + break; + case XJerk: + #if HAS_CLASSIC_JERK + planner.max_jerk[X_AXIS] = atof(key_value); + #endif + break; + case YJerk: + #if HAS_CLASSIC_JERK + planner.max_jerk[Y_AXIS] = atof(key_value); + #endif + break; + case ZJerk: + #if HAS_CLASSIC_JERK + planner.max_jerk[Z_AXIS] = atof(key_value); + #endif + break; + case EJerk: + #if HAS_CLASSIC_JERK + planner.max_jerk[E_AXIS] = atof(key_value); + #endif + break; + case Xstep: + planner.settings.axis_steps_per_mm[X_AXIS] = atof(key_value); + planner.refresh_positioning(); + break; + case Ystep: + planner.settings.axis_steps_per_mm[Y_AXIS] = atof(key_value); + planner.refresh_positioning(); + break; + case Zstep: + planner.settings.axis_steps_per_mm[Z_AXIS] = atof(key_value); + planner.refresh_positioning(); + break; + case E0step: + planner.settings.axis_steps_per_mm[E_AXIS] = atof(key_value); + planner.refresh_positioning(); + break; + case E1step: + planner.settings.axis_steps_per_mm[E_AXIS_N(1)] = atof(key_value); + planner.refresh_positioning(); + break; + case Xcurrent: + #if AXIS_IS_TMC(X) + current_mA = atoi(key_value); + stepperX.rms_current(current_mA); + #endif + break; + case Ycurrent: + #if AXIS_IS_TMC(Y) + current_mA = atoi(key_value); + stepperY.rms_current(current_mA); + #endif + break; + case Zcurrent: + #if AXIS_IS_TMC(Z) + current_mA = atoi(key_value); + stepperZ.rms_current(current_mA); + #endif + break; + case E0current: + #if AXIS_IS_TMC(E0) + current_mA = atoi(key_value); + stepperE0.rms_current(current_mA); + #endif + break; + case E1current: + #if AXIS_IS_TMC(E1) + current_mA = atoi(key_value); + stepperE1.rms_current(current_mA); + #endif + break; + case pause_pos_x: + gCfgItems.pausePosX = atof(key_value); + update_spi_flash(); + break; + case pause_pos_y: + gCfgItems.pausePosY = atof(key_value); + update_spi_flash(); + break; + case pause_pos_z: + gCfgItems.pausePosZ = atof(key_value); + update_spi_flash(); + break; + case level_pos_x1: + gCfgItems.levelingPos[0][0] = atoi(key_value); + update_spi_flash(); + break; + case level_pos_y1: + gCfgItems.levelingPos[0][1] = atoi(key_value); + update_spi_flash(); + break; + case level_pos_x2: + gCfgItems.levelingPos[1][0] = atoi(key_value); + update_spi_flash(); + break; + case level_pos_y2: + gCfgItems.levelingPos[1][1] = atoi(key_value); + update_spi_flash(); + break; + case level_pos_x3: + gCfgItems.levelingPos[2][0] = atoi(key_value); + update_spi_flash(); + break; + case level_pos_y3: + gCfgItems.levelingPos[2][1] = atoi(key_value); + update_spi_flash(); + break; + case level_pos_x4: + gCfgItems.levelingPos[3][0] = atoi(key_value); + update_spi_flash(); + break; + case level_pos_y4: + gCfgItems.levelingPos[3][1] = atoi(key_value); + update_spi_flash(); + break; + case level_pos_x5: + gCfgItems.levelingPos[4][0] = atoi(key_value); + update_spi_flash(); + break; + case level_pos_y5: + gCfgItems.levelingPos[4][1] = atoi(key_value); + update_spi_flash(); + break; + #if HAS_BED_PROBE + case x_offset: + #if HAS_PROBE_XY_OFFSET + float x; + x = atof(key_value); + if (WITHIN(x, -(X_BED_SIZE), X_BED_SIZE)) + probe.offset.x = x; + #endif + break; + case y_offset: + #if HAS_PROBE_XY_OFFSET + float y; + y = atof(key_value); + if (WITHIN(y, -(Y_BED_SIZE), Y_BED_SIZE)) + probe.offset.y = y; + #endif + break; + case z_offset: + float z; + z = atof(key_value); + if (WITHIN(z, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX)) + probe.offset.z = z; + break; + #endif + case load_length: + gCfgItems.filamentchange_load_length = atoi(key_value); + uiCfg.filament_loading_time = (uint32_t)((gCfgItems.filamentchange_load_length*60.0/gCfgItems.filamentchange_load_speed)+0.5); + update_spi_flash(); + break; + case load_speed: + gCfgItems.filamentchange_load_speed = atoi(key_value); + uiCfg.filament_loading_time = (uint32_t)((gCfgItems.filamentchange_load_length*60.0/gCfgItems.filamentchange_load_speed)+0.5); + update_spi_flash(); + break; + case unload_length: + gCfgItems.filamentchange_unload_length = atoi(key_value); + uiCfg.filament_unloading_time = (uint32_t)((gCfgItems.filamentchange_unload_length*60.0/gCfgItems.filamentchange_unload_speed)+0.5); + update_spi_flash(); + break; + case unload_speed: + gCfgItems.filamentchange_unload_speed = atoi(key_value); + uiCfg.filament_unloading_time = (uint32_t)((gCfgItems.filamentchange_unload_length*60.0/gCfgItems.filamentchange_unload_speed)+0.5); + update_spi_flash(); + break; + case filament_temp: + gCfgItems.filament_limit_temper = atoi(key_value); + update_spi_flash(); + break; + case x_sensitivity: + #if X_SENSORLESS + stepperX.homing_threshold(atoi(key_value)); + #endif + break; + case y_sensitivity: + #if Y_SENSORLESS + stepperY.homing_threshold(atoi(key_value)); + #endif + break; + case z_sensitivity: + #if Z_SENSORLESS + stepperZ.homing_threshold(atoi(key_value)); + #endif + break; + case z2_sensitivity: + #if Z2_SENSORLESS + stepperZ2.homing_threshold(atoi(key_value)); + #endif + break; + } + gcode.process_subcommands_now_P(PSTR("M500")); +} + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_NUM_KEY1: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (cnt <= 10) { + key_value[cnt] = (char)'1'; + lv_label_set_text(labelValue, key_value); + lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0); + cnt++; + } + } + break; + case ID_NUM_KEY2: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (cnt <= 10) { + key_value[cnt] = (char)'2'; + lv_label_set_text(labelValue, key_value); + lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0); + cnt++; + } + } + break; + case ID_NUM_KEY3: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (cnt <= 10) { + key_value[cnt] = (char)'3'; + lv_label_set_text(labelValue, key_value); + lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0); + cnt++; + } + } + break; + case ID_NUM_KEY4: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (cnt <= 10) { + key_value[cnt] = (char)'4'; + lv_label_set_text(labelValue, key_value); + lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0); + cnt++; + } + } + break; + case ID_NUM_KEY5: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (cnt <= 10) { + key_value[cnt] = (char)'5'; + lv_label_set_text(labelValue, key_value); + lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0); + cnt++; + } + } + break; + case ID_NUM_KEY6: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (cnt <= 10) { + key_value[cnt] = (char)'6'; + lv_label_set_text(labelValue, key_value); + lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0); + cnt++; + } + } + break; + case ID_NUM_KEY7: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (cnt <= 10) { + key_value[cnt] = (char)'7'; + lv_label_set_text(labelValue, key_value); + lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0); + cnt++; + } + } + break; + case ID_NUM_KEY8: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (cnt <= 10) { + key_value[cnt] = (char)'8'; + lv_label_set_text(labelValue, key_value); + lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0); + cnt++; + } + } + break; + case ID_NUM_KEY9: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (cnt <= 10) { + key_value[cnt] = (char)'9'; + lv_label_set_text(labelValue, key_value); + lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0); + cnt++; + } + } + break; + case ID_NUM_KEY0: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (cnt <= 10) { + key_value[cnt] = (char)'0'; + lv_label_set_text(labelValue, key_value); + lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0); + cnt++; + } + } + break; + case ID_NUM_BACK: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (cnt > 0) + cnt--; + if (key_value[cnt] == (char)'.') point_flg = 1; + key_value[cnt] = (char)'\0'; + lv_label_set_text(labelValue, key_value); + lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0); + } + break; + case ID_NUM_RESET: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + ZERO(key_value); + cnt = 0; + key_value[cnt] = (char)'0'; + point_flg = 1; + lv_label_set_text(labelValue, key_value); + lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0); + } + break; + case ID_NUM_POINT: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if ((cnt != 0) && (point_flg == 1)) { + point_flg = 0; + key_value[cnt] = (char)'.'; + lv_label_set_text(labelValue, key_value); + lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0); + cnt++; + } + } + break; + case ID_NUM_NAGETIVE: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (cnt == 0) { + key_value[cnt] = (char)'-'; + lv_label_set_text(labelValue, key_value); + lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0); + cnt++; + } + } + break; + case ID_NUM_CONFIRM: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + last_disp_state = NUMBER_KEY_UI; + if (strlen(key_value) != 0) + set_value_confirm(); + lv_clear_number_key(); + draw_return_ui(); + } + break; + } +} + +void lv_draw_number_key(void) { + lv_obj_t *NumberKey_1 = NULL, *NumberKey_2 = NULL, *NumberKey_3 = NULL, *NumberKey_4 = NULL, *NumberKey_5 = NULL; + lv_obj_t *NumberKey_6 = NULL, *NumberKey_7 = NULL, *NumberKey_8 = NULL, *NumberKey_9 = NULL, *NumberKey_0 = NULL; + lv_obj_t *KeyPoint = NULL, *KeyConfirm = NULL, *KeyReset = NULL, *KeyBack = NULL; + lv_obj_t *Minus = NULL; + lv_obj_t *labelKey_1 = NULL, *labelKey_2 = NULL, *labelKey_3 = NULL, *labelKey_4 = NULL, *labelKey_5 = NULL; + lv_obj_t *labelKey_6 = NULL, *labelKey_7 = NULL, *labelKey_8 = NULL, *labelKey_9 = NULL, *labelKey_0 = NULL; + lv_obj_t *labelKeyPoint = NULL, *labelKeyConfirm = NULL, *labelKeyReset = NULL, *labelKeyBack = NULL; + lv_obj_t *labelMinus = NULL; + + buttonValue = NULL; + labelValue = NULL; + + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != NUMBER_KEY_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = NUMBER_KEY_UI; + } + disp_state = NUMBER_KEY_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + //lv_obj_t * title = lv_label_create(scr, NULL); + //lv_obj_set_style(title, &tft_style_label_rel); + //lv_obj_set_pos(title,TITLE_XPOS,TITLE_YPOS); + //lv_label_set_text(title, creat_title_text()); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + buttonValue = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(buttonValue, 92, 40); /*Set its position*/ + lv_obj_set_size(buttonValue, 296, 40); + lv_obj_set_event_cb_mks(buttonValue, event_handler, ID_NUM_KEY1, NULL, 0); + lv_btn_set_style(buttonValue, LV_BTN_STYLE_REL, &style_num_text); /*Set the button's released style*/ + lv_btn_set_style(buttonValue, LV_BTN_STYLE_PR, &style_num_text); /*Set the button's pressed style*/ + //lv_btn_set_layout(buttonValue, LV_LAYOUT_OFF); + labelValue = lv_label_create(buttonValue, NULL); /*Add a label to the button*/ + + NumberKey_1 = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(NumberKey_1, 92, 90); /*Set its position*/ + lv_obj_set_size(NumberKey_1, 68, 40); + lv_obj_set_event_cb_mks(NumberKey_1, event_handler, ID_NUM_KEY1, NULL, 0); + lv_btn_set_style(NumberKey_1, LV_BTN_STYLE_REL, &style_num_key_pre); /*Set the button's released style*/ + lv_btn_set_style(NumberKey_1, LV_BTN_STYLE_PR, &style_num_key_rel); /*Set the button's pressed style*/ + //lv_btn_set_layout(NumberKey_1, LV_LAYOUT_OFF); + labelKey_1 = lv_label_create(NumberKey_1, NULL); /*Add a label to the button*/ + lv_label_set_text(labelKey_1, machine_menu.key_1); + lv_obj_align(labelKey_1, NumberKey_1, LV_ALIGN_CENTER, 0, 0); + + NumberKey_2 = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(NumberKey_2, 168, 90); /*Set its position*/ + lv_obj_set_size(NumberKey_2, 68, 40); + lv_obj_set_event_cb_mks(NumberKey_2, event_handler, ID_NUM_KEY2, NULL, 0); + lv_btn_set_style(NumberKey_2, LV_BTN_STYLE_REL, &style_num_key_pre); /*Set the button's released style*/ + lv_btn_set_style(NumberKey_2, LV_BTN_STYLE_PR, &style_num_key_rel); /*Set the button's pressed style*/ + //lv_btn_set_layout(NumberKey_2, LV_LAYOUT_OFF); + labelKey_2 = lv_label_create(NumberKey_2, NULL); /*Add a label to the button*/ + lv_label_set_text(labelKey_2, machine_menu.key_2); + lv_obj_align(labelKey_2, NumberKey_2, LV_ALIGN_CENTER, 0, 0); + + NumberKey_3 = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(NumberKey_3, 244, 90); /*Set its position*/ + lv_obj_set_size(NumberKey_3, 68, 40); + lv_obj_set_event_cb_mks(NumberKey_3, event_handler, ID_NUM_KEY3, NULL, 0); + lv_btn_set_style(NumberKey_3, LV_BTN_STYLE_REL, &style_num_key_pre); /*Set the button's released style*/ + lv_btn_set_style(NumberKey_3, LV_BTN_STYLE_PR, &style_num_key_rel); /*Set the button's pressed style*/ + //lv_btn_set_layout(NumberKey_3, LV_LAYOUT_OFF); + labelKey_3 = lv_label_create(NumberKey_3, NULL); /*Add a label to the button*/ + lv_label_set_text(labelKey_3, machine_menu.key_3); + lv_obj_align(labelKey_3, NumberKey_3, LV_ALIGN_CENTER, 0, 0); + + NumberKey_4 = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(NumberKey_4, 92, 140); /*Set its position*/ + lv_obj_set_size(NumberKey_4, 68, 40); + lv_obj_set_event_cb_mks(NumberKey_4, event_handler, ID_NUM_KEY4, NULL, 0); + lv_btn_set_style(NumberKey_4, LV_BTN_STYLE_REL, &style_num_key_pre); /*Set the button's released style*/ + lv_btn_set_style(NumberKey_4, LV_BTN_STYLE_PR, &style_num_key_rel); /*Set the button's pressed style*/ + //lv_btn_set_layout(NumberKey_4, LV_LAYOUT_OFF); + labelKey_4 = lv_label_create(NumberKey_4, NULL); /*Add a label to the button*/ + lv_label_set_text(labelKey_4, machine_menu.key_4); + lv_obj_align(labelKey_4, NumberKey_4, LV_ALIGN_CENTER, 0, 0); + + NumberKey_5 = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(NumberKey_5, 168, 140); /*Set its position*/ + lv_obj_set_size(NumberKey_5, 68, 40); + lv_obj_set_event_cb_mks(NumberKey_5, event_handler, ID_NUM_KEY5, NULL, 0); + lv_btn_set_style(NumberKey_5, LV_BTN_STYLE_REL, &style_num_key_pre); /*Set the button's released style*/ + lv_btn_set_style(NumberKey_5, LV_BTN_STYLE_PR, &style_num_key_rel); /*Set the button's pressed style*/ + //lv_btn_set_layout(NumberKey_5, LV_LAYOUT_OFF); + labelKey_5 = lv_label_create(NumberKey_5, NULL); /*Add a label to the button*/ + lv_label_set_text(labelKey_5, machine_menu.key_5); + lv_obj_align(labelKey_5, NumberKey_5, LV_ALIGN_CENTER, 0, 0); + + NumberKey_6 = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(NumberKey_6, 244, 140); /*Set its position*/ + lv_obj_set_size(NumberKey_6, 68, 40); + lv_obj_set_event_cb_mks(NumberKey_6, event_handler, ID_NUM_KEY6, NULL, 0); + lv_btn_set_style(NumberKey_6, LV_BTN_STYLE_REL, &style_num_key_pre); /*Set the button's released style*/ + lv_btn_set_style(NumberKey_6, LV_BTN_STYLE_PR, &style_num_key_rel); /*Set the button's pressed style*/ + //lv_btn_set_layout(NumberKey_6, LV_LAYOUT_OFF); + labelKey_6 = lv_label_create(NumberKey_6, NULL); /*Add a label to the button*/ + lv_label_set_text(labelKey_6, machine_menu.key_6); + lv_obj_align(labelKey_6, NumberKey_6, LV_ALIGN_CENTER, 0, 0); + + NumberKey_7 = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(NumberKey_7, 92, 190); /*Set its position*/ + lv_obj_set_size(NumberKey_7, 68, 40); + lv_obj_set_event_cb_mks(NumberKey_7, event_handler, ID_NUM_KEY7, NULL, 0); + lv_btn_set_style(NumberKey_7, LV_BTN_STYLE_REL, &style_num_key_pre); /*Set the button's released style*/ + lv_btn_set_style(NumberKey_7, LV_BTN_STYLE_PR, &style_num_key_rel); /*Set the button's pressed style*/ + //lv_btn_set_layout(NumberKey_7, LV_LAYOUT_OFF); + labelKey_7 = lv_label_create(NumberKey_7, NULL); /*Add a label to the button*/ + lv_label_set_text(labelKey_7, machine_menu.key_7); + lv_obj_align(labelKey_7, NumberKey_7, LV_ALIGN_CENTER, 0, 0); + + NumberKey_8 = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(NumberKey_8, 168, 190); /*Set its position*/ + lv_obj_set_size(NumberKey_8, 68, 40); + lv_obj_set_event_cb_mks(NumberKey_8, event_handler, ID_NUM_KEY8, NULL, 0); + lv_btn_set_style(NumberKey_8, LV_BTN_STYLE_REL, &style_num_key_pre); /*Set the button's released style*/ + lv_btn_set_style(NumberKey_8, LV_BTN_STYLE_PR, &style_num_key_rel); /*Set the button's pressed style*/ + //lv_btn_set_layout(NumberKey_8, LV_LAYOUT_OFF); + labelKey_8 = lv_label_create(NumberKey_8, NULL); /*Add a label to the button*/ + lv_label_set_text(labelKey_8, machine_menu.key_8); + lv_obj_align(labelKey_8, NumberKey_8, LV_ALIGN_CENTER, 0, 0); + + NumberKey_9 = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(NumberKey_9, 244, 190); /*Set its position*/ + lv_obj_set_size(NumberKey_9, 68, 40); + lv_obj_set_event_cb_mks(NumberKey_9, event_handler, ID_NUM_KEY9, NULL, 0); + lv_btn_set_style(NumberKey_9, LV_BTN_STYLE_REL, &style_num_key_pre); /*Set the button's released style*/ + lv_btn_set_style(NumberKey_9, LV_BTN_STYLE_PR, &style_num_key_rel); /*Set the button's pressed style*/ + //lv_btn_set_layout(NumberKey_9, LV_LAYOUT_OFF); + labelKey_9 = lv_label_create(NumberKey_9, NULL); /*Add a label to the button*/ + lv_label_set_text(labelKey_9, machine_menu.key_9); + lv_obj_align(labelKey_9, NumberKey_9, LV_ALIGN_CENTER, 0, 0); + + NumberKey_0 = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(NumberKey_0, 92, 240); /*Set its position*/ + lv_obj_set_size(NumberKey_0, 68, 40); + lv_obj_set_event_cb_mks(NumberKey_0, event_handler, ID_NUM_KEY0, NULL, 0); + lv_btn_set_style(NumberKey_0, LV_BTN_STYLE_REL, &style_num_key_pre); /*Set the button's released style*/ + lv_btn_set_style(NumberKey_0, LV_BTN_STYLE_PR, &style_num_key_rel); /*Set the button's pressed style*/ + //lv_btn_set_layout(NumberKey_0, LV_LAYOUT_OFF); + labelKey_0 = lv_label_create(NumberKey_0, NULL); /*Add a label to the button*/ + lv_label_set_text(labelKey_0, machine_menu.key_0); + lv_obj_align(labelKey_0, NumberKey_0, LV_ALIGN_CENTER, 0, 0); + + KeyBack = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(KeyBack, 320, 90); /*Set its position*/ + lv_obj_set_size(KeyBack, 68, 40); + lv_obj_set_event_cb_mks(KeyBack, event_handler, ID_NUM_BACK, NULL, 0); + lv_btn_set_style(KeyBack, LV_BTN_STYLE_REL, &style_num_key_pre); /*Set the button's released style*/ + lv_btn_set_style(KeyBack, LV_BTN_STYLE_PR, &style_num_key_rel); /*Set the button's pressed style*/ + //lv_btn_set_layout(KeyBack, LV_LAYOUT_OFF); + labelKeyBack = lv_label_create(KeyBack, NULL); /*Add a label to the button*/ + lv_label_set_text(labelKeyBack, machine_menu.key_back); + lv_obj_align(labelKeyBack, KeyBack, LV_ALIGN_CENTER, 0, 0); + + KeyReset = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(KeyReset, 320, 140); /*Set its position*/ + lv_obj_set_size(KeyReset, 68, 40); + lv_obj_set_event_cb_mks(KeyReset, event_handler, ID_NUM_RESET, NULL, 0); + lv_btn_set_style(KeyReset, LV_BTN_STYLE_REL, &style_num_key_pre); /*Set the button's released style*/ + lv_btn_set_style(KeyReset, LV_BTN_STYLE_PR, &style_num_key_rel); /*Set the button's pressed style*/ + //lv_btn_set_layout(KeyReset, LV_LAYOUT_OFF); + labelKeyReset = lv_label_create(KeyReset, NULL); /*Add a label to the button*/ + lv_label_set_text(labelKeyReset, machine_menu.key_reset); + lv_obj_align(labelKeyReset, KeyReset, LV_ALIGN_CENTER, 0, 0); + + KeyConfirm = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(KeyConfirm, 320, 190); /*Set its position*/ + lv_obj_set_size(KeyConfirm, 68, 90); + lv_obj_set_event_cb_mks(KeyConfirm, event_handler, ID_NUM_CONFIRM, NULL, 0); + lv_btn_set_style(KeyConfirm, LV_BTN_STYLE_REL, &style_num_key_pre); /*Set the button's released style*/ + lv_btn_set_style(KeyConfirm, LV_BTN_STYLE_PR, &style_num_key_rel); /*Set the button's pressed style*/ + //lv_btn_set_layout(KeyConfirm, LV_LAYOUT_OFF); + labelKeyConfirm = lv_label_create(KeyConfirm, NULL); /*Add a label to the button*/ + lv_label_set_text(labelKeyConfirm, machine_menu.key_confirm); + lv_obj_align(labelKeyConfirm, KeyConfirm, LV_ALIGN_CENTER, 0, 0); + + KeyPoint = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(KeyPoint, 244, 240); /*Set its position*/ + lv_obj_set_size(KeyPoint, 68, 40); + lv_obj_set_event_cb_mks(KeyPoint, event_handler, ID_NUM_POINT, NULL, 0); + lv_btn_set_style(KeyPoint, LV_BTN_STYLE_REL, &style_num_key_pre); /*Set the button's released style*/ + lv_btn_set_style(KeyPoint, LV_BTN_STYLE_PR, &style_num_key_rel); /*Set the button's pressed style*/ + //lv_btn_set_layout(KeyPoint, LV_LAYOUT_OFF); + labelKeyPoint = lv_label_create(KeyPoint, NULL); /*Add a label to the button*/ + lv_label_set_text(labelKeyPoint, machine_menu.key_point); + lv_obj_align(labelKeyPoint, KeyPoint, LV_ALIGN_CENTER, 0, 0); + + Minus = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(Minus, 168, 240); /*Set its position*/ + lv_obj_set_size(Minus, 68, 40); + lv_obj_set_event_cb_mks(Minus, event_handler, ID_NUM_NAGETIVE, NULL, 0); + lv_btn_set_style(Minus, LV_BTN_STYLE_REL, &style_num_key_pre); /*Set the button's released style*/ + lv_btn_set_style(Minus, LV_BTN_STYLE_PR, &style_num_key_rel); /*Set the button's pressed style*/ + //lv_btn_set_layout(Minus, LV_LAYOUT_OFF); + labelMinus = lv_label_create(Minus, NULL); /*Add a label to the button*/ + lv_label_set_text(labelMinus, machine_menu.negative); + lv_obj_align(labelMinus, Minus, LV_ALIGN_CENTER, 0, 0); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, NumberKey_1); + lv_group_add_obj(g, NumberKey_2); + lv_group_add_obj(g, NumberKey_3); + lv_group_add_obj(g, KeyBack); + lv_group_add_obj(g, NumberKey_4); + lv_group_add_obj(g, NumberKey_5); + lv_group_add_obj(g, NumberKey_6); + lv_group_add_obj(g, KeyReset); + lv_group_add_obj(g, NumberKey_7); + lv_group_add_obj(g, NumberKey_8); + lv_group_add_obj(g, NumberKey_9); + lv_group_add_obj(g, NumberKey_0); + lv_group_add_obj(g, Minus); + lv_group_add_obj(g, KeyPoint); + lv_group_add_obj(g, KeyConfirm); + } + #endif + + disp_key_value(); +} + +void lv_clear_number_key() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_number_key.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_number_key.h new file mode 100644 index 000000000000..7902da36493a --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_number_key.h @@ -0,0 +1,33 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_number_key(void); +extern void lv_clear_number_key(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_operation.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_operation.cpp new file mode 100644 index 000000000000..4a4a0ee1305b --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_operation.cpp @@ -0,0 +1,413 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" +//#include "../lvgl/src/lv_objx/lv_imgbtn.h" +//#include "../lvgl/src/lv_objx/lv_img.h" +//#include "../lvgl/src/lv_core/lv_disp.h" +//#include "../lvgl/src/lv_core/lv_refr.h" + +#include "../../../../MarlinCore.h" +#include "../../../../module/temperature.h" +#include "../../../../module/motion.h" +#include "../../../../sd/cardreader.h" + +extern lv_group_t * g; +static lv_obj_t * scr; + +#define ID_O_PRE_HEAT 1 +#define ID_O_EXTRUCT 2 +#define ID_O_MOV 3 +#define ID_O_FILAMENT 4 +#define ID_O_SPEED 5 +#define ID_O_RETURN 6 +#define ID_O_FAN 7 +#define ID_O_POWER_OFF 8 +#define ID_O_BABY_STEP 9 + +static lv_obj_t *label_PowerOff; +static lv_obj_t *buttonPowerOff; + +extern feedRate_t feedrate_mm_s; + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_O_PRE_HEAT: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_operation(); + lv_draw_preHeat(); + } + break; + case ID_O_EXTRUCT: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_operation(); + lv_draw_extrusion(); + } + break; + case ID_O_MOV: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_operation(); + lv_draw_move_motor(); + } + break; + case ID_O_FILAMENT: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + #if HAS_MULTI_EXTRUDER + uiCfg.curSprayerChoose_bak = active_extruder; + #endif + if (uiCfg.print_state == WORKING) { + #if ENABLED(SDSUPPORT) + card.pauseSDPrint(); + stop_print_time(); + uiCfg.print_state = PAUSING; + #endif + } + uiCfg.moveSpeed_bak = (uint16_t)feedrate_mm_s; + uiCfg.desireSprayerTempBak = thermalManager.temp_hotend[active_extruder].target; + lv_clear_operation(); + lv_draw_filament_change(); + } + break; + case ID_O_FAN: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_operation(); + lv_draw_fan(); + } + break; + case ID_O_SPEED: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_operation(); + lv_draw_change_speed(); + } + break; + case ID_O_RETURN: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + clear_cur_ui(); + draw_return_ui(); + } + break; + case ID_O_POWER_OFF: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (gCfgItems.finish_power_off == 1) { + gCfgItems.finish_power_off = 0; + lv_imgbtn_set_src(buttonPowerOff, LV_BTN_STATE_REL, "F:/bmp_manual_off.bin"); + lv_imgbtn_set_src(buttonPowerOff, LV_BTN_STATE_PR, "F:/bmp_manual_off.bin"); + lv_label_set_text(label_PowerOff, printing_more_menu.manual); + lv_obj_align(label_PowerOff, buttonPowerOff, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + lv_obj_refresh_ext_draw_pad(label_PowerOff); + update_spi_flash(); + } + else { + gCfgItems.finish_power_off = 1; + lv_imgbtn_set_src(buttonPowerOff, LV_BTN_STATE_REL, "F:/bmp_auto_off.bin"); + lv_imgbtn_set_src(buttonPowerOff, LV_BTN_STATE_PR, "F:/bmp_auto_off.bin"); + lv_label_set_text(label_PowerOff, printing_more_menu.auto_close); + lv_obj_align(label_PowerOff, buttonPowerOff, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + lv_obj_refresh_ext_draw_pad(label_PowerOff); + update_spi_flash(); + } + } + break; + case ID_O_BABY_STEP: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_operation(); + lv_draw_baby_stepping(); + } + break; + } +} + +void lv_draw_operation(void) { + lv_obj_t *buttonPreHeat = NULL, *buttonExtrusion = NULL, *buttonSpeed = NULL; + lv_obj_t *buttonBack = NULL, *buttonFan = NULL; + lv_obj_t *labelPreHeat = NULL, *labelExtrusion = NULL; + lv_obj_t *label_Back = NULL, *label_Speed = NULL, *label_Fan = NULL; + lv_obj_t *buttonMove = NULL, *label_Move = NULL; + lv_obj_t *buttonBabyStep = NULL, *label_BabyStep = NULL; + lv_obj_t *buttonFilament = NULL, *label_Filament = NULL; + + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != OPERATE_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = OPERATE_UI; + } + disp_state = OPERATE_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, creat_title_text()); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + // Create image buttons + buttonPreHeat = lv_imgbtn_create(scr, NULL); + buttonFilament = lv_imgbtn_create(scr, NULL); + buttonFan = lv_imgbtn_create(scr, NULL); + buttonPowerOff = lv_imgbtn_create(scr, NULL); + if (uiCfg.print_state != WORKING) { + buttonExtrusion = lv_imgbtn_create(scr, NULL); + buttonMove = lv_imgbtn_create(scr, NULL); + } + else { + buttonSpeed = lv_imgbtn_create(scr, NULL); + buttonBabyStep = lv_imgbtn_create(scr, NULL); + } + buttonBack = lv_imgbtn_create(scr, NULL); + + lv_obj_set_event_cb_mks(buttonPreHeat, event_handler, ID_O_PRE_HEAT, NULL, 0); + lv_imgbtn_set_src(buttonPreHeat, LV_BTN_STATE_REL, "F:/bmp_temp.bin"); + lv_imgbtn_set_src(buttonPreHeat, LV_BTN_STATE_PR, "F:/bmp_temp.bin"); + lv_imgbtn_set_style(buttonPreHeat, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonPreHeat, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonFilament, event_handler, ID_O_FILAMENT, NULL, 0); + lv_imgbtn_set_src(buttonFilament, LV_BTN_STATE_REL, "F:/bmp_filamentchange.bin"); + lv_imgbtn_set_src(buttonFilament, LV_BTN_STATE_PR, "F:/bmp_filamentchange.bin"); + lv_imgbtn_set_style(buttonFilament, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonFilament, LV_BTN_STATE_REL, &tft_style_label_rel); + + #if 1 + lv_obj_set_event_cb_mks(buttonFan, event_handler, ID_O_FAN, NULL, 0); + lv_imgbtn_set_src(buttonFan, LV_BTN_STATE_REL, "F:/bmp_fan.bin"); + lv_imgbtn_set_src(buttonFan, LV_BTN_STATE_PR, "F:/bmp_fan.bin"); + lv_imgbtn_set_style(buttonFan, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonFan, LV_BTN_STATE_REL, &tft_style_label_rel); + + if (gCfgItems.finish_power_off == 1) { + lv_imgbtn_set_src(buttonPowerOff, LV_BTN_STATE_REL, "F:/bmp_auto_off.bin"); + lv_imgbtn_set_src(buttonPowerOff, LV_BTN_STATE_PR, "F:/bmp_auto_off.bin"); + } + else { + lv_imgbtn_set_src(buttonPowerOff, LV_BTN_STATE_REL, "F:/bmp_manual_off.bin"); + lv_imgbtn_set_src(buttonPowerOff, LV_BTN_STATE_PR, "F:/bmp_manual_off.bin"); + } + lv_obj_set_event_cb_mks(buttonPowerOff, event_handler, ID_O_POWER_OFF, NULL, 0); + lv_imgbtn_set_style(buttonPowerOff, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonPowerOff, LV_BTN_STATE_REL, &tft_style_label_rel); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonPreHeat); + lv_group_add_obj(g, buttonFilament); + lv_group_add_obj(g, buttonFan); + lv_group_add_obj(g, buttonPowerOff); + } + #endif + + if (uiCfg.print_state != WORKING) { + lv_obj_set_event_cb_mks(buttonExtrusion, event_handler, ID_O_EXTRUCT, NULL, 0); + lv_imgbtn_set_src(buttonExtrusion, LV_BTN_STATE_REL, "F:/bmp_extrude_opr.bin"); + lv_imgbtn_set_src(buttonExtrusion, LV_BTN_STATE_PR, "F:/bmp_extrude_opr.bin"); + lv_imgbtn_set_style(buttonExtrusion, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonExtrusion, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonMove, event_handler, ID_O_MOV, NULL, 0); + lv_imgbtn_set_src(buttonMove, LV_BTN_STATE_REL, "F:/bmp_move_opr.bin"); + lv_imgbtn_set_src(buttonMove, LV_BTN_STATE_PR, "F:/bmp_move_opr.bin"); + lv_imgbtn_set_style(buttonMove, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonMove, LV_BTN_STATE_REL, &tft_style_label_rel); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonExtrusion); + lv_group_add_obj(g, buttonMove); + } + #endif + } + else { + lv_obj_set_event_cb_mks(buttonSpeed, event_handler, ID_O_SPEED, NULL, 0); + lv_imgbtn_set_src(buttonSpeed, LV_BTN_STATE_REL, "F:/bmp_speed.bin"); + lv_imgbtn_set_src(buttonSpeed, LV_BTN_STATE_PR, "F:/bmp_speed.bin"); + lv_imgbtn_set_style(buttonSpeed, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonSpeed, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonBabyStep, event_handler, ID_O_BABY_STEP, NULL, 0); + lv_imgbtn_set_src(buttonBabyStep, LV_BTN_STATE_REL, "F:/bmp_mov.bin"); + lv_imgbtn_set_src(buttonBabyStep, LV_BTN_STATE_PR, "F:/bmp_mov.bin"); + lv_imgbtn_set_style(buttonBabyStep, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBabyStep, LV_BTN_STATE_REL, &tft_style_label_rel); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonSpeed); + lv_group_add_obj(g, buttonBabyStep); + } + #endif + } + + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_O_RETURN, NULL, 0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_return.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_return.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + #endif // if 1 + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonBack); + #endif + + lv_obj_set_pos(buttonPreHeat, INTERVAL_V, titleHeight); + lv_obj_set_pos(buttonFilament, BTN_X_PIXEL + INTERVAL_V * 2, titleHeight); + lv_obj_set_pos(buttonFan, BTN_X_PIXEL * 2 + INTERVAL_V * 3, titleHeight); + lv_obj_set_pos(buttonPowerOff, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight); + + if (uiCfg.print_state != WORKING) { + /* + lv_obj_set_pos(buttonFilament,INTERVAL_V,BTN_Y_PIXEL+INTERVAL_H+titleHeight); + } else { + */ + lv_obj_set_pos(buttonExtrusion, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonMove, BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + } + else { + lv_obj_set_pos(buttonSpeed, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonBabyStep, BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + } + + lv_obj_set_pos(buttonBack, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + + // Create labels on the image buttons + lv_btn_set_layout(buttonPreHeat, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonFilament, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonFan, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonPowerOff, LV_LAYOUT_OFF); + + if (uiCfg.print_state != WORKING) { + /* + lv_btn_set_layout(buttonFilament, LV_LAYOUT_OFF); + } else { + */ + lv_btn_set_layout(buttonExtrusion, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonMove, LV_LAYOUT_OFF); + } + else { + lv_btn_set_layout(buttonSpeed, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonBabyStep, LV_LAYOUT_OFF); + } + + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + + labelPreHeat = lv_label_create(buttonPreHeat, NULL); + label_Filament = lv_label_create(buttonFilament, NULL); + label_Fan = lv_label_create(buttonFan, NULL); + label_PowerOff = lv_label_create(buttonPowerOff, NULL); + + if (uiCfg.print_state != WORKING) { + /* + label_Filament = lv_label_create(buttonFilament, NULL); + } else { + */ + labelExtrusion = lv_label_create(buttonExtrusion, NULL); + label_Move = lv_label_create(buttonMove, NULL); + } + else { + label_Speed = lv_label_create(buttonSpeed, NULL); + label_BabyStep = lv_label_create(buttonBabyStep, NULL); + } + label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(labelPreHeat, operation_menu.temp); + lv_obj_align(labelPreHeat, buttonPreHeat, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Filament, operation_menu.filament); + lv_obj_align(label_Filament, buttonFilament, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Fan, operation_menu.fan); + lv_obj_align(label_Fan, buttonFan, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + if (gCfgItems.finish_power_off == 1) + lv_label_set_text(label_PowerOff, printing_more_menu.auto_close); + else + lv_label_set_text(label_PowerOff, printing_more_menu.manual); + lv_obj_align(label_PowerOff, buttonPowerOff, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + if (uiCfg.print_state != WORKING) { + /* + lv_label_set_text(label_Filament, operation_menu.filament); + lv_obj_align(label_Filament, buttonFilament, LV_ALIGN_IN_BOTTOM_MID,0, BUTTON_TEXT_Y_OFFSET); + } else { + */ + lv_label_set_text(labelExtrusion, operation_menu.extr); + lv_obj_align(labelExtrusion, buttonExtrusion, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Move, operation_menu.move); + lv_obj_align(label_Move, buttonMove, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + else { + lv_label_set_text(label_Speed, operation_menu.speed); + lv_obj_align(label_Speed, buttonSpeed, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_BabyStep, operation_menu.babystep); + lv_obj_align(label_BabyStep, buttonBabyStep, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } +} + +void lv_clear_operation() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_operation.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_operation.h new file mode 100644 index 000000000000..cca1f6a2a5aa --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_operation.h @@ -0,0 +1,34 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_operation(void); +extern void lv_clear_operation(); + +//extern void disp_temp_ready_print(); +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_message.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_message.cpp new file mode 100644 index 000000000000..f7dd2060b8f6 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_message.cpp @@ -0,0 +1,55 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if BOTH(HAS_TFT_LVGL_UI, ADVANCED_PAUSE_FEATURE) + +#include "draw_ui.h" +#include "lv_conf.h" +//#include "../lvgl/src/lv_objx/lv_imgbtn.h" +//#include "../lvgl/src/lv_objx/lv_img.h" +//#include "../lvgl/src/lv_core/lv_disp.h" +//#include "../lvgl/src/lv_core/lv_refr.h" + +#include "../../../../MarlinCore.h" +#include "../../../../feature/pause.h" + +void lv_draw_pause_message(const PauseMessage msg) { + switch (msg) { + case PAUSE_MESSAGE_PAUSING: clear_cur_ui(); lv_draw_dialog(DIALOG_PAUSE_MESSAGE_PAUSING); break; + case PAUSE_MESSAGE_CHANGING: clear_cur_ui(); lv_draw_dialog(DIALOG_PAUSE_MESSAGE_CHANGING); break; + case PAUSE_MESSAGE_UNLOAD: clear_cur_ui(); lv_draw_dialog(DIALOG_PAUSE_MESSAGE_UNLOAD); break; + case PAUSE_MESSAGE_WAITING: clear_cur_ui(); lv_draw_dialog(DIALOG_PAUSE_MESSAGE_WAITING); break; + case PAUSE_MESSAGE_INSERT: clear_cur_ui(); lv_draw_dialog(DIALOG_PAUSE_MESSAGE_INSERT); break; + case PAUSE_MESSAGE_LOAD: clear_cur_ui(); lv_draw_dialog(DIALOG_PAUSE_MESSAGE_LOAD); break; + case PAUSE_MESSAGE_PURGE: clear_cur_ui(); lv_draw_dialog(DIALOG_PAUSE_MESSAGE_PURGE); break; + case PAUSE_MESSAGE_RESUME: clear_cur_ui(); lv_draw_dialog(DIALOG_PAUSE_MESSAGE_RESUME); break; + case PAUSE_MESSAGE_HEAT: clear_cur_ui(); lv_draw_dialog(DIALOG_PAUSE_MESSAGE_HEAT); break; + case PAUSE_MESSAGE_HEATING: clear_cur_ui(); lv_draw_dialog(DIALOG_PAUSE_MESSAGE_HEATING); break; + case PAUSE_MESSAGE_OPTION: pause_menu_response = PAUSE_RESPONSE_WAIT_FOR; + clear_cur_ui(); lv_draw_dialog(DIALOG_PAUSE_MESSAGE_OPTION); break; + case PAUSE_MESSAGE_STATUS: + default: break; + } +} + +#endif // HAS_TFT_LVGL_UI && ADVANCED_PAUSE_FEATURE diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_message.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_message.h new file mode 100644 index 000000000000..7d55d8375601 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_message.h @@ -0,0 +1,33 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_pause_message(const PauseMessage msg); + +//extern void disp_temp_ready_print(); +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_position.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_position.cpp new file mode 100644 index 000000000000..9b99971f4f96 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_position.cpp @@ -0,0 +1,202 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" + +#include "../../../../MarlinCore.h" +#include "../../../../module/planner.h" + +extern lv_group_t * g; +static lv_obj_t * scr; + +#define ID_PAUSE_RETURN 1 +#define ID_PAUSE_X 2 +#define ID_PAUSE_Y 3 +#define ID_PAUSE_Z 4 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_PAUSE_RETURN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_pause_position(); + draw_return_ui(); + } + break; + case ID_PAUSE_X: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = pause_pos_x; + lv_clear_pause_position(); + lv_draw_number_key(); + } + break; + case ID_PAUSE_Y: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = pause_pos_y; + lv_clear_pause_position(); + lv_draw_number_key(); + } + break; + case ID_PAUSE_Z: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = pause_pos_z; + lv_clear_pause_position(); + lv_draw_number_key(); + } + break; + } +} + +void lv_draw_pause_position(void) { + lv_obj_t *buttonBack = NULL, *label_Back = NULL; + lv_obj_t *labelXText = NULL, *buttonXValue = NULL, *labelXValue = NULL; + lv_obj_t *labelYText = NULL, *buttonYValue = NULL, *labelYValue = NULL; + lv_obj_t *labelZText = NULL, *buttonZValue = NULL, *labelZValue = NULL; + + lv_obj_t * line1 = NULL, * line2 = NULL, * line3 = NULL; + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != PAUSE_POS_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = PAUSE_POS_UI; + } + disp_state = PAUSE_POS_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, machine_menu.PausePosText); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + labelXText = lv_label_create(scr, NULL); + lv_obj_set_style(labelXText, &tft_style_label_rel); + lv_obj_set_pos(labelXText, PARA_UI_POS_X, PARA_UI_POS_Y + 10); + lv_label_set_text(labelXText, machine_menu.xPos); + + buttonXValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonXValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y + PARA_UI_VALUE_V); + lv_obj_set_size(buttonXValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_btn_set_style(buttonXValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonXValue, LV_BTN_STYLE_PR, &style_para_value); + lv_obj_set_event_cb_mks(buttonXValue, event_handler, ID_PAUSE_X, NULL, 0); + labelXValue = lv_label_create(buttonXValue, NULL); + + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1, line_points[0]); + + labelYText = lv_label_create(scr, NULL); + lv_obj_set_style(labelYText, &tft_style_label_rel); + lv_obj_set_pos(labelYText, PARA_UI_POS_X, PARA_UI_POS_Y * 2 + 10); + lv_label_set_text(labelYText, machine_menu.yPos); + + buttonYValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonYValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 2 + PARA_UI_VALUE_V); + lv_obj_set_size(buttonYValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonYValue, event_handler, ID_PAUSE_Y, NULL, 0); + lv_btn_set_style(buttonYValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonYValue, LV_BTN_STYLE_PR, &style_para_value); + labelYValue = lv_label_create(buttonYValue, NULL); + + line2 = lv_line_create(scr, NULL); + lv_ex_line(line2, line_points[1]); + + labelZText = lv_label_create(scr, NULL); + lv_obj_set_style(labelZText, &tft_style_label_rel); + lv_obj_set_pos(labelZText, PARA_UI_POS_X, PARA_UI_POS_Y * 3 + 10); + lv_label_set_text(labelZText, machine_menu.zPos); + + buttonZValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonZValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 3 + PARA_UI_VALUE_V); + lv_obj_set_size(buttonZValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonZValue, event_handler, ID_PAUSE_Z, NULL, 0); + lv_btn_set_style(buttonZValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonZValue, LV_BTN_STYLE_PR, &style_para_value); + labelZValue = lv_label_create(buttonZValue, NULL); + + line3 = lv_line_create(scr, NULL); + lv_ex_line(line3, line_points[2]); + + buttonBack = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonBack, PARA_UI_BACL_POS_X, PARA_UI_BACL_POS_Y); + lv_obj_set_size(buttonBack, PARA_UI_BACK_BTN_X_SIZE, PARA_UI_BACK_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_PAUSE_RETURN, NULL, 0); + lv_btn_set_style(buttonBack, LV_BTN_STYLE_REL, &style_para_back); + lv_btn_set_style(buttonBack, LV_BTN_STYLE_PR, &style_para_back); + label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.multiple_language != 0) { + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), gCfgItems.pausePosX); + lv_label_set_text(labelXValue, public_buf_l); + lv_obj_align(labelXValue, buttonXValue, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), gCfgItems.pausePosY); + lv_label_set_text(labelYValue, public_buf_l); + lv_obj_align(labelYValue, buttonYValue, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), gCfgItems.pausePosZ); + lv_label_set_text(labelZValue, public_buf_l); + lv_obj_align(labelZValue, buttonZValue, LV_ALIGN_CENTER, 0, 0); + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_CENTER, 0, 0); + } + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonXValue); + lv_group_add_obj(g, buttonYValue); + lv_group_add_obj(g, buttonZValue); + lv_group_add_obj(g, buttonBack); + } + #endif +} + +void lv_clear_pause_position() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_position.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_position.h new file mode 100644 index 000000000000..3e9e0798271b --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_position.h @@ -0,0 +1,33 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_pause_position(void); +extern void lv_clear_pause_position(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_preHeat.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_preHeat.cpp new file mode 100644 index 000000000000..f58a47b341b6 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_preHeat.cpp @@ -0,0 +1,401 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" +//#include "../lvgl/src/lv_objx/lv_imgbtn.h" +//#include "../lvgl/src/lv_objx/lv_img.h" +//#include "../lvgl/src/lv_core/lv_disp.h" +//#include "../lvgl/src/lv_core/lv_refr.h" + +#include "../../../../MarlinCore.h" +#include "../../../../module/temperature.h" + +static lv_obj_t * scr; +extern lv_group_t* g; +static lv_obj_t *buttoType, *buttonStep; +static lv_obj_t *labelType; +static lv_obj_t *labelStep; +static lv_obj_t * tempText1; + +#define ID_P_ADD 1 +#define ID_P_DEC 2 +#define ID_P_TYPE 3 +#define ID_P_STEP 4 +#define ID_P_OFF 5 +#define ID_P_RETURN 6 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_P_ADD: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (uiCfg.curTempType == 0) { + thermalManager.temp_hotend[uiCfg.curSprayerChoose].target += uiCfg.stepHeat; + if (uiCfg.curSprayerChoose == 0) { + if ((int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].target > (HEATER_0_MAXTEMP - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1))) { + thermalManager.temp_hotend[uiCfg.curSprayerChoose].target = (float)HEATER_0_MAXTEMP - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1); + } + } + #if !defined(SINGLENOZZLE) && HAS_MULTI_EXTRUDER + else if ((int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].target > (HEATER_1_MAXTEMP - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1))) { + thermalManager.temp_hotend[uiCfg.curSprayerChoose].target = (float)HEATER_1_MAXTEMP - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1); + } + #endif + thermalManager.start_watching_hotend(uiCfg.curSprayerChoose); + } + #if HAS_HEATED_BED + else { + thermalManager.temp_bed.target += uiCfg.stepHeat; + if ((int)thermalManager.temp_bed.target > BED_MAXTEMP - (WATCH_BED_TEMP_INCREASE + TEMP_BED_HYSTERESIS + 1)) { + thermalManager.temp_bed.target = (float)BED_MAXTEMP - (WATCH_BED_TEMP_INCREASE + TEMP_BED_HYSTERESIS + 1); + } + thermalManager.start_watching_bed(); + } + #endif + disp_desire_temp(); + } + break; + case ID_P_DEC: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (uiCfg.curTempType == 0) { + if ((int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].target > uiCfg.stepHeat) { + thermalManager.temp_hotend[uiCfg.curSprayerChoose].target -= uiCfg.stepHeat; + } + else { + thermalManager.temp_hotend[uiCfg.curSprayerChoose].target = (float)0; + } + thermalManager.start_watching_hotend(uiCfg.curSprayerChoose); + } + #if HAS_HEATED_BED + else { + if ((int)thermalManager.temp_bed.target > uiCfg.stepHeat) { + thermalManager.temp_bed.target -= uiCfg.stepHeat; + } + else { + thermalManager.temp_bed.target = (float)0; + } + thermalManager.start_watching_bed(); + } + #endif + disp_desire_temp(); + } + + break; + case ID_P_TYPE: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (uiCfg.curTempType == 0) { + if (ENABLED(HAS_MULTI_EXTRUDER)) { + if (uiCfg.curSprayerChoose == 0) { + uiCfg.curSprayerChoose = 1; + } + else if (uiCfg.curSprayerChoose == 1) { + if (TEMP_SENSOR_BED != 0) { + uiCfg.curTempType = 1; + } + else { + uiCfg.curTempType = 0; + uiCfg.curSprayerChoose = 0; + } + } + } + else if (uiCfg.curSprayerChoose == 0) { + if (TEMP_SENSOR_BED != 0) + uiCfg.curTempType = 1; + else + uiCfg.curTempType = 0; + } + } + else if (uiCfg.curTempType == 1) { + uiCfg.curSprayerChoose = 0; + uiCfg.curTempType = 0; + } + disp_temp_type(); + } + break; + case ID_P_STEP: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + switch (uiCfg.stepHeat) { + case 1: uiCfg.stepHeat = 5; break; + case 5: uiCfg.stepHeat = 10; break; + case 10: uiCfg.stepHeat = 1; break; + default: break; + } + disp_step_heat(); + } + break; + case ID_P_OFF: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (uiCfg.curTempType == 0) { + thermalManager.temp_hotend[uiCfg.curSprayerChoose].target = (float)0; + thermalManager.start_watching_hotend(uiCfg.curSprayerChoose); + } + #if HAS_HEATED_BED + else { + thermalManager.temp_bed.target = (float)0; + thermalManager.start_watching_bed(); + } + #endif + disp_desire_temp(); + } + break; + case ID_P_RETURN: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + clear_cur_ui(); + draw_return_ui(); + } + break; + } +} + +void lv_draw_preHeat(void) { + lv_obj_t *buttonAdd, *buttonDec; + lv_obj_t *buttonOff, *buttonBack; + + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != PRE_HEAT_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = PRE_HEAT_UI; + } + disp_state = PRE_HEAT_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, creat_title_text()); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + // Create image buttons + buttonAdd = lv_imgbtn_create(scr, NULL); + buttonDec = lv_imgbtn_create(scr, NULL); + buttoType = lv_imgbtn_create(scr, NULL); + buttonStep = lv_imgbtn_create(scr, NULL); + buttonOff = lv_imgbtn_create(scr, NULL); + buttonBack = lv_imgbtn_create(scr, NULL); + + lv_obj_set_event_cb_mks(buttonAdd, event_handler, ID_P_ADD, NULL, 0); + lv_imgbtn_set_src(buttonAdd, LV_BTN_STATE_REL, "F:/bmp_Add.bin"); + lv_imgbtn_set_src(buttonAdd, LV_BTN_STATE_PR, "F:/bmp_Add.bin"); + lv_imgbtn_set_style(buttonAdd, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonAdd, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_obj_clear_protect(buttonAdd, LV_PROTECT_FOLLOW); + + #if 1 + lv_obj_set_event_cb_mks(buttonDec, event_handler, ID_P_DEC, NULL, 0); + lv_imgbtn_set_src(buttonDec, LV_BTN_STATE_REL, "F:/bmp_Dec.bin"); + lv_imgbtn_set_src(buttonDec, LV_BTN_STATE_PR, "F:/bmp_Dec.bin"); + lv_imgbtn_set_style(buttonDec, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonDec, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttoType, event_handler, ID_P_TYPE, NULL, 0); + lv_imgbtn_set_style(buttoType, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttoType, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonStep, event_handler, ID_P_STEP, NULL, 0); + lv_imgbtn_set_style(buttonStep, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonStep, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonOff, event_handler, ID_P_OFF, NULL, 0); + lv_imgbtn_set_src(buttonOff, LV_BTN_STATE_REL, "F:/bmp_speed0.bin"); + lv_imgbtn_set_src(buttonOff, LV_BTN_STATE_PR, "F:/bmp_speed0.bin"); + lv_imgbtn_set_style(buttonOff, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonOff, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_P_RETURN, NULL, 0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_return.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_return.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + #endif + + lv_obj_set_pos(buttonAdd, INTERVAL_V, titleHeight); + lv_obj_set_pos(buttonDec, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight); + lv_obj_set_pos(buttoType, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonStep, BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonOff, BTN_X_PIXEL * 2 + INTERVAL_V * 3, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonBack, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + + // Create labels on the image buttons + lv_btn_set_layout(buttonAdd, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonDec, LV_LAYOUT_OFF); + lv_btn_set_layout(buttoType, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonStep, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonOff, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + + lv_obj_t *labelAdd = lv_label_create(buttonAdd, NULL); + lv_obj_t *labelDec = lv_label_create(buttonDec, NULL); + labelType = lv_label_create(buttoType, NULL); + labelStep = lv_label_create(buttonStep, NULL); + lv_obj_t *labelOff = lv_label_create(buttonOff, NULL); + lv_obj_t *label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(labelAdd, preheat_menu.add); + lv_obj_align(labelAdd, buttonAdd, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelDec, preheat_menu.dec); + lv_obj_align(labelDec, buttonDec, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelOff, preheat_menu.off); + lv_obj_align(labelOff, buttonOff, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonAdd); + lv_group_add_obj(g, buttonDec); + lv_group_add_obj(g, buttoType); + lv_group_add_obj(g, buttonStep); + lv_group_add_obj(g, buttonOff); + lv_group_add_obj(g, buttonBack); + } + #endif + + disp_temp_type(); + disp_step_heat(); + + tempText1 = lv_label_create(scr, NULL); + lv_obj_set_style(tempText1, &tft_style_label_rel); + disp_desire_temp(); +} + +void disp_temp_type() { + if (uiCfg.curTempType == 0) { + if (uiCfg.curSprayerChoose == 1) { + lv_imgbtn_set_src(buttoType, LV_BTN_STATE_REL, "F:/bmp_extru2.bin"); + lv_imgbtn_set_src(buttoType, LV_BTN_STATE_PR, "F:/bmp_extru2.bin"); + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(labelType, preheat_menu.ext2); + lv_obj_align(labelType, buttoType, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + } + else { + lv_imgbtn_set_src(buttoType, LV_BTN_STATE_REL, "F:/bmp_extru1.bin"); + lv_imgbtn_set_src(buttoType, LV_BTN_STATE_PR, "F:/bmp_extru1.bin"); + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(labelType, preheat_menu.ext1); + lv_obj_align(labelType, buttoType, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + } + + } + else { + lv_imgbtn_set_src(buttoType, LV_BTN_STATE_REL, "F:/bmp_bed.bin"); + lv_imgbtn_set_src(buttoType, LV_BTN_STATE_PR, "F:/bmp_bed.bin"); + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(labelType, preheat_menu.hotbed); + lv_obj_align(labelType, buttoType, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + } +} + +void disp_desire_temp() { + char buf[20] = {0}; + + public_buf_l[0] = '\0'; + + if (uiCfg.curTempType == 0) { + if (uiCfg.curSprayerChoose < 1) + strcat(public_buf_l, preheat_menu.ext1); + else + strcat(public_buf_l, preheat_menu.ext2); + sprintf(buf, preheat_menu.value_state, (int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius, (int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].target); + } + #if HAS_HEATED_BED + else { + strcat(public_buf_l, preheat_menu.hotbed); + sprintf(buf, preheat_menu.value_state, (int)thermalManager.temp_bed.celsius, (int)thermalManager.temp_bed.target); + } + #endif + strcat_P(public_buf_l, PSTR(": ")); + strcat(public_buf_l, buf); + lv_label_set_text(tempText1, public_buf_l); + lv_obj_align(tempText1, NULL, LV_ALIGN_CENTER, 0, -50); +} + +void disp_step_heat() { + if (uiCfg.stepHeat == 1) { + lv_imgbtn_set_src(buttonStep, LV_BTN_STATE_REL, "F:/bmp_step1_degree.bin"); + lv_imgbtn_set_src(buttonStep, LV_BTN_STATE_PR, "F:/bmp_step1_degree.bin"); + } + else if (uiCfg.stepHeat == 5) { + lv_imgbtn_set_src(buttonStep, LV_BTN_STATE_REL, "F:/bmp_step5_degree.bin"); + lv_imgbtn_set_src(buttonStep, LV_BTN_STATE_PR, "F:/bmp_step5_degree.bin"); + } + else if (uiCfg.stepHeat == 10) { + lv_imgbtn_set_src(buttonStep, LV_BTN_STATE_REL, "F:/bmp_step10_degree.bin"); + lv_imgbtn_set_src(buttonStep, LV_BTN_STATE_PR, "F:/bmp_step10_degree.bin"); + } + + if (gCfgItems.multiple_language != 0) { + if (uiCfg.stepHeat == 1) { + lv_label_set_text(labelStep, preheat_menu.step_1c); + lv_obj_align(labelStep, buttonStep, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + else if (uiCfg.stepHeat == 5) { + lv_label_set_text(labelStep, preheat_menu.step_5c); + lv_obj_align(labelStep, buttonStep, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + else if (uiCfg.stepHeat == 10) { + lv_label_set_text(labelStep, preheat_menu.step_10c); + lv_obj_align(labelStep, buttonStep, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + } +} + +void lv_clear_preHeat() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_preHeat.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_preHeat.h new file mode 100644 index 000000000000..c8de942f3f60 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_preHeat.h @@ -0,0 +1,37 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_preHeat(void); +extern void lv_clear_preHeat(); +extern void disp_temp_type(); +extern void disp_step_heat(); +extern void disp_desire_temp(); + +//extern void disp_temp_ready_print(); +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_print_file.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_print_file.cpp new file mode 100644 index 000000000000..6d7b68af42a7 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_print_file.cpp @@ -0,0 +1,640 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "../../../../MarlinCore.h" +#include "lv_conf.h" +//#include "../lvgl/src/lv_objx/lv_imgbtn.h" +//#include "../lvgl/src/lv_objx/lv_img.h" +//#include "../lvgl/src/lv_core/lv_disp.h" +//#include "../lvgl/src/lv_core/lv_refr.h" +#include "draw_ui.h" +#include "../../../../sd/cardreader.h" + +static lv_obj_t * scr; +extern lv_group_t* g; + +static lv_obj_t *buttonPageUp, *buttonPageDown, *buttonBack, + *buttonGcode[FILE_BTN_CNT], *labelPageUp[FILE_BTN_CNT], *buttonText[FILE_BTN_CNT]; + +#define ID_P_UP 7 +#define ID_P_DOWN 8 +#define ID_P_RETURN 9 + +int8_t curDirLever = 0; +LIST_FILE list_file; +DIR_OFFSET dir_offset[10]; + +extern uint8_t public_buf[512]; +extern char public_buf_m[100]; + +uint8_t sel_id = 0; + +#if ENABLED(SDSUPPORT) + + static uint8_t search_file() { + int valid_name_cnt = 0; + //char tmp[SHORT_NEME_LEN*MAX_DIR_LEVEL+1]; + + list_file.Sd_file_cnt = 0; + //list_file.Sd_file_offset = dir_offset[curDirLever].cur_page_first_offset; + + //root2.rewind(); + //SERIAL_ECHOLN(list_file.curDirPath); + + if (curDirLever != 0) card.cd(list_file.curDirPath); + else card.cdroot(); // while(card.cdup()); + + const uint16_t fileCnt = card.get_num_Files(); + + for (uint16_t i = 0; i < fileCnt; i++) { + if (list_file.Sd_file_cnt == list_file.Sd_file_offset) { + const uint16_t nr = SD_ORDER(i, fileCnt); + card.getfilename_sorted(nr); + + if (card.flag.filenameIsDir) { + //SERIAL_ECHOLN(card.longest_filename); + list_file.IsFolder[valid_name_cnt] = 1; + } + else { + //SERIAL_ECHOLN(card.longFilename); + list_file.IsFolder[valid_name_cnt] = 0; + } + + #if 1 + // + memset(list_file.file_name[valid_name_cnt], 0, strlen(list_file.file_name[valid_name_cnt])); + strcpy(list_file.file_name[valid_name_cnt], list_file.curDirPath); + strcat_P(list_file.file_name[valid_name_cnt], PSTR("/")); + strcat(list_file.file_name[valid_name_cnt], card.filename); + // + memset(list_file.long_name[valid_name_cnt], 0, strlen(list_file.long_name[valid_name_cnt])); + if (card.longFilename[0] == 0) + strncpy(list_file.long_name[valid_name_cnt], card.filename, strlen(card.filename)); + else + strncpy(list_file.long_name[valid_name_cnt], card.longFilename, strlen(card.longFilename)); + + valid_name_cnt++; + if (valid_name_cnt == 1) + dir_offset[curDirLever].cur_page_first_offset = list_file.Sd_file_offset; + if (valid_name_cnt >= FILE_NUM) { + dir_offset[curDirLever].cur_page_last_offset = list_file.Sd_file_offset; + list_file.Sd_file_offset++; + break; + } + list_file.Sd_file_offset++; + #endif + } + list_file.Sd_file_cnt++; + } + //card.closefile(false); + return valid_name_cnt; + } + +#endif // SDSUPPORT + +uint8_t have_pre_pic(char *path) { + #if ENABLED(SDSUPPORT) + char *ps1, *ps2, *cur_name = strrchr(path, '/'); + + card.openFileRead(cur_name); + card.read(public_buf, 512); + ps1 = strstr((char *)public_buf, ";simage:"); + card.read(public_buf, 512); + ps2 = strstr((char *)public_buf, ";simage:"); + if (ps1 || ps2) { + card.closefile(); + return 1; + } + card.closefile(); + #endif + + return 0; +} + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + uint8_t i, file_count = 0; + //switch (obj->mks_obj_id) + //{ + if (obj->mks_obj_id == ID_P_UP) { + if (event == LV_EVENT_CLICKED) { + } + else if (event == LV_EVENT_RELEASED) { + if (dir_offset[curDirLever].curPage > 0) { + // 2015.05.19 + list_file.Sd_file_cnt = 0; + + if (dir_offset[curDirLever].cur_page_first_offset >= FILE_NUM) + list_file.Sd_file_offset = dir_offset[curDirLever].cur_page_first_offset - FILE_NUM; + + #if ENABLED(SDSUPPORT) + file_count = search_file(); + #endif + if (file_count != 0) { + dir_offset[curDirLever].curPage--; + lv_clear_print_file(); + disp_gcode_icon(file_count); + } + } + } + } + else if (obj->mks_obj_id == ID_P_DOWN) { + if (event == LV_EVENT_CLICKED) { + } + else if (event == LV_EVENT_RELEASED) { + if (dir_offset[curDirLever].cur_page_last_offset > 0) { + list_file.Sd_file_cnt = 0; + list_file.Sd_file_offset = dir_offset[curDirLever].cur_page_last_offset + 1; + #if ENABLED(SDSUPPORT) + file_count = search_file(); + #endif + if (file_count != 0) { + dir_offset[curDirLever].curPage++; + lv_clear_print_file(); + disp_gcode_icon(file_count); + } + if (file_count < FILE_NUM) + dir_offset[curDirLever].cur_page_last_offset = 0; + } + } + } + else if (obj->mks_obj_id == ID_P_RETURN) { + if (event == LV_EVENT_CLICKED) { + } + else if (event == LV_EVENT_RELEASED) { + if (curDirLever > 0) { + int8_t *ch = (int8_t *)strrchr(list_file.curDirPath, '/'); + if (ch) { + *ch = 0; + #if ENABLED(SDSUPPORT) + card.cdup(); + #endif + dir_offset[curDirLever].curPage = 0; + dir_offset[curDirLever].cur_page_first_offset = 0; + dir_offset[curDirLever].cur_page_last_offset = 0; + curDirLever--; + list_file.Sd_file_offset = dir_offset[curDirLever].cur_page_first_offset; + #if ENABLED(SDSUPPORT) + file_count = search_file(); + #endif + lv_clear_print_file(); + disp_gcode_icon(file_count); + } + } + else { + lv_clear_print_file(); + lv_draw_ready_print(); + } + } + } + else { + for (i = 0; i < FILE_BTN_CNT; i++) { + if (obj->mks_obj_id == (i + 1)) { + if (event == LV_EVENT_CLICKED) { + } + else if (event == LV_EVENT_RELEASED) { + if (list_file.file_name[i][0] != 0) { + if (list_file.IsFolder[i] == 1) { + ZERO(list_file.curDirPath); + strcpy(list_file.curDirPath, list_file.file_name[i]); + curDirLever++; + list_file.Sd_file_offset = dir_offset[curDirLever].cur_page_first_offset; + #if ENABLED(SDSUPPORT) + file_count = search_file(); + #endif + lv_clear_print_file(); + disp_gcode_icon(file_count); + } + else { + sel_id = i; + lv_clear_print_file(); + lv_draw_dialog(DIALOG_TYPE_PRINT_FILE); + } + break; + } + } + } + } + } +} + +void lv_draw_print_file(void) { + //uint8_t i; + uint8_t file_count; + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != PRINT_FILE_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = PRINT_FILE_UI; + } + disp_state = PRINT_FILE_UI; + + curDirLever = 0; + dir_offset[curDirLever].curPage = 0; + + list_file.Sd_file_offset = 0; + list_file.Sd_file_cnt = 0; + + ZERO(dir_offset); + ZERO(list_file.IsFolder); + ZERO(list_file.curDirPath); + + list_file.Sd_file_offset = dir_offset[curDirLever].cur_page_first_offset; + #if ENABLED(SDSUPPORT) + card.mount(); + file_count = search_file(); + #endif + disp_gcode_icon(file_count); + + //lv_obj_t *labelPageUp = lv_label_create(buttonPageUp, NULL); + //lv_obj_t *labelPageDown = lv_label_create(buttonPageDown, NULL); + //lv_obj_t *label_Back = lv_label_create(buttonBack, NULL); + + /* + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(labelPageUp, tool_menu.preheat); + lv_obj_align(labelPageUp, buttonPageUp, LV_ALIGN_IN_BOTTOM_MID,0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelPageDown, tool_menu.extrude); + lv_obj_align(labelPageDown, buttonPageDown, LV_ALIGN_IN_BOTTOM_MID,0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_IN_BOTTOM_MID,0, BUTTON_TEXT_Y_OFFSET); + } + */ +} +static char test_public_buf_l[40]; +void disp_gcode_icon(uint8_t file_num) { + uint8_t i; + + scr = lv_obj_create(NULL, NULL); + + //static lv_style_t tool_style; + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, creat_title_text()); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + // Create image buttons + buttonPageUp = lv_imgbtn_create(scr, NULL); + buttonPageDown = lv_imgbtn_create(scr, NULL); + buttonBack = lv_imgbtn_create(scr, NULL); + + lv_obj_set_event_cb_mks(buttonPageUp, event_handler, ID_P_UP, NULL, 0); + lv_imgbtn_set_src(buttonPageUp, LV_BTN_STATE_REL, "F:/bmp_pageUp.bin"); + lv_imgbtn_set_src(buttonPageUp, LV_BTN_STATE_PR, "F:/bmp_pageUp.bin"); + lv_imgbtn_set_style(buttonPageUp, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonPageUp, LV_BTN_STATE_REL, &tft_style_label_rel); + + #if 1 + lv_obj_set_event_cb_mks(buttonPageDown, event_handler, ID_P_DOWN, NULL, 0); + lv_imgbtn_set_src(buttonPageDown, LV_BTN_STATE_REL, "F:/bmp_pageDown.bin"); + lv_imgbtn_set_src(buttonPageDown, LV_BTN_STATE_PR, "F:/bmp_pageDown.bin"); + lv_imgbtn_set_style(buttonPageDown, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonPageDown, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_P_RETURN, NULL, 0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_back.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_back.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + #endif + + lv_obj_set_pos(buttonPageUp, OTHER_BTN_XPIEL * 3 + INTERVAL_V * 4, titleHeight); + lv_obj_set_pos(buttonPageDown, OTHER_BTN_XPIEL * 3 + INTERVAL_V * 4, titleHeight + OTHER_BTN_YPIEL + INTERVAL_H); + lv_obj_set_pos(buttonBack, OTHER_BTN_XPIEL * 3 + INTERVAL_V * 4, titleHeight + OTHER_BTN_YPIEL * 2 + INTERVAL_H * 2); + + // Create labels on the image buttons + lv_btn_set_layout(buttonPageUp, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonPageDown, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + + for (i = 0; i < FILE_BTN_CNT; i++) { + /* + if (seq) { + j = (FILE_BTN_CNT-1) - i; + back_flg = 1; + } + else { + j = i; + back_flg = 0; + } + */ + if (i >= file_num) break; + + #ifdef TFT35 + buttonGcode[i] = lv_imgbtn_create(scr, NULL); + + lv_imgbtn_set_style(buttonGcode[i], LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonGcode[i], LV_BTN_STATE_REL, &tft_style_label_rel); + lv_obj_clear_protect(buttonGcode[i], LV_PROTECT_FOLLOW); + lv_btn_set_layout(buttonGcode[i], LV_LAYOUT_OFF); + + ZERO(public_buf_m); + cutFileName((char *)list_file.long_name[i], 16, 8, (char *)public_buf_m); + + if (list_file.IsFolder[i] == 1) { + lv_obj_set_event_cb_mks(buttonGcode[i], event_handler, (i + 1), NULL, 0); + lv_imgbtn_set_src(buttonGcode[i], LV_BTN_STATE_REL, "F:/bmp_dir.bin"); + lv_imgbtn_set_src(buttonGcode[i], LV_BTN_STATE_PR, "F:/bmp_dir.bin"); + if (i < 3) + lv_obj_set_pos(buttonGcode[i], BTN_X_PIXEL * i + INTERVAL_V * (i + 1), titleHeight); + else + lv_obj_set_pos(buttonGcode[i], BTN_X_PIXEL * (i - 3) + INTERVAL_V * ((i - 3) + 1), BTN_Y_PIXEL + INTERVAL_H + titleHeight); + + labelPageUp[i] = lv_label_create(buttonGcode[i], NULL); + lv_obj_set_style(labelPageUp[i], &tft_style_label_rel); + lv_label_set_text(labelPageUp[i], public_buf_m); + lv_obj_align(labelPageUp[i], buttonGcode[i], LV_ALIGN_IN_BOTTOM_MID, 0, -5); + } + else { + if (have_pre_pic((char *)list_file.file_name[i])) { + + //lv_obj_set_event_cb_mks(buttonGcode[i], event_handler, (i + 1), list_file.file_name[i], 1); + + ZERO(test_public_buf_l); + strcat(test_public_buf_l,"S:"); + strcat(test_public_buf_l,list_file.file_name[i]); + char *temp = strstr(test_public_buf_l,".GCO"); + if (temp) { strcpy(temp,".bin"); } + lv_obj_set_event_cb_mks(buttonGcode[i], event_handler, (i + 1), NULL, 0); + lv_imgbtn_set_src(buttonGcode[i], LV_BTN_STATE_REL, test_public_buf_l); + lv_imgbtn_set_src(buttonGcode[i], LV_BTN_STATE_PR, test_public_buf_l); + if (i < 3) { + lv_obj_set_pos(buttonGcode[i], BTN_X_PIXEL * i + INTERVAL_V * (i + 1) + FILE_PRE_PIC_X_OFFSET, titleHeight + FILE_PRE_PIC_Y_OFFSET); + buttonText[i] = lv_btn_create(scr, NULL); + //lv_obj_set_event_cb(buttonText[i], event_handler); + + lv_btn_set_style(buttonText[i], LV_BTN_STATE_PR, &tft_style_label_pre); + lv_btn_set_style(buttonText[i], LV_BTN_STATE_REL, &tft_style_label_rel); + //lv_obj_set_style(buttonText[i], &tft_style_label_pre); + //lv_obj_set_style(buttonText[i], &tft_style_label_rel); + lv_obj_clear_protect(buttonText[i], LV_PROTECT_FOLLOW); + lv_btn_set_layout(buttonText[i], LV_LAYOUT_OFF); + //lv_obj_set_event_cb_mks(buttonText[i], event_handler,(i+10),NULL,0); + lv_obj_set_pos(buttonText[i], BTN_X_PIXEL * i + INTERVAL_V * (i + 1) + FILE_PRE_PIC_X_OFFSET, titleHeight + FILE_PRE_PIC_Y_OFFSET + 100); + lv_obj_set_size(buttonText[i], 100, 40); + } + else { + lv_obj_set_pos(buttonGcode[i], BTN_X_PIXEL * (i - 3) + INTERVAL_V * ((i - 3) + 1) + FILE_PRE_PIC_X_OFFSET, BTN_Y_PIXEL + INTERVAL_H + titleHeight + FILE_PRE_PIC_Y_OFFSET); + buttonText[i] = lv_btn_create(scr, NULL); + //lv_obj_set_event_cb(buttonText[i], event_handler); + + lv_btn_set_style(buttonText[i], LV_BTN_STATE_PR, &tft_style_label_pre); + lv_btn_set_style(buttonText[i], LV_BTN_STATE_REL, &tft_style_label_rel); + + //lv_imgbtn_set_style(buttonText[i], LV_BTN_STATE_REL, &tft_style_label_rel); + lv_obj_clear_protect(buttonText[i], LV_PROTECT_FOLLOW); + lv_btn_set_layout(buttonText[i], LV_LAYOUT_OFF); + //lv_obj_set_event_cb_mks(buttonText[i], event_handler,(i+10),NULL,0); + lv_obj_set_pos(buttonText[i], BTN_X_PIXEL * (i - 3) + INTERVAL_V * ((i - 3) + 1) + FILE_PRE_PIC_X_OFFSET, BTN_Y_PIXEL + INTERVAL_H + titleHeight + FILE_PRE_PIC_Y_OFFSET + 100); + lv_obj_set_size(buttonText[i], 100, 40); + } + labelPageUp[i] = lv_label_create(buttonText[i], NULL); + lv_obj_set_style(labelPageUp[i], &tft_style_label_rel); + lv_label_set_text(labelPageUp[i], public_buf_m); + lv_obj_align(labelPageUp[i], buttonText[i], LV_ALIGN_IN_BOTTOM_MID, 0, 0); + } + else { + lv_obj_set_event_cb_mks(buttonGcode[i], event_handler, (i + 1), NULL, 0); + lv_imgbtn_set_src(buttonGcode[i], LV_BTN_STATE_REL, "F:/bmp_file.bin"); + lv_imgbtn_set_src(buttonGcode[i], LV_BTN_STATE_PR, "F:/bmp_file.bin"); + if (i < 3) + lv_obj_set_pos(buttonGcode[i], BTN_X_PIXEL * i + INTERVAL_V * (i + 1), titleHeight); + else + lv_obj_set_pos(buttonGcode[i], BTN_X_PIXEL * (i - 3) + INTERVAL_V * ((i - 3) + 1), BTN_Y_PIXEL + INTERVAL_H + titleHeight); + + labelPageUp[i] = lv_label_create(buttonGcode[i], NULL); + lv_obj_set_style(labelPageUp[i], &tft_style_label_rel); + lv_label_set_text(labelPageUp[i], public_buf_m); + lv_obj_align(labelPageUp[i], buttonGcode[i], LV_ALIGN_IN_BOTTOM_MID, 0, -5); + } + } + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonGcode[i]); + #endif + + #else // !TFT35 + #endif // !TFT35 + } + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonPageUp); + lv_group_add_obj(g, buttonPageDown); + lv_group_add_obj(g, buttonBack); + } + #endif +} + +uint32_t lv_open_gcode_file(char *path) { + #if ENABLED(SDSUPPORT) + uint32_t *ps4; + uint32_t pre_sread_cnt = 0; + char *cur_name; + + cur_name = strrchr(path, '/'); + + card.openFileRead(cur_name); + card.read(public_buf, 512); + ps4 = (uint32_t *)strstr((char *)public_buf, ";simage:"); + // Ignore the beginning message of gcode file + if (ps4) { + pre_sread_cnt = (uint32_t)ps4 - (uint32_t)((uint32_t *)(&public_buf[0])); + card.setIndex(pre_sread_cnt); + } + return pre_sread_cnt; + #endif // SDSUPPORT +} + +int ascii2dec_test(char *ascii) { + int result = 0; + if (ascii == 0) return 0; + + if (*(ascii) >= '0' && *(ascii) <= '9') + result = *(ascii) - '0'; + else if (*(ascii) >= 'a' && *(ascii) <= 'f') + result = *(ascii) - 'a' + 0x0A; + else if (*(ascii) >= 'A' && *(ascii) <= 'F') + result = *(ascii) - 'A' + 0x0A; + else + return 0; + + return result; +} + +void lv_gcode_file_read(uint8_t *data_buf) { + #if ENABLED(SDSUPPORT) + uint16_t i = 0, j = 0, k = 0; + uint16_t row_1 = 0; + bool ignore_start = true; + char temp_test[200]; + volatile uint16_t *p_index; + + memset(public_buf, 0, 200); + + while (card.isFileOpen()) { + if (ignore_start) card.read(temp_test, 8); // line start -> ignore + card.read(temp_test, 200); // data + // \r;;gimage: we got the bit img, so stop here + if (temp_test[1] == ';') { + card.closefile(); + break; + } + for (i = 0; i < 200;) { + public_buf[row_1 * 200 + 100 * k + j] = (char)(ascii2dec_test(&temp_test[i]) << 4 | ascii2dec_test(&temp_test[i + 1])); + j++; + i += 2; + } + + uint16_t c = card.get(); + // check if we have more data or finished the line (CR) + if (c == '\r') break; + card.setIndex(card.getIndex()); + k++; + j = 0; + ignore_start = false; + } + #if ENABLED(TFT_LVGL_UI_SPI) + for (i = 0; i < 200;) { + p_index = (uint16_t *)(&public_buf[i]); + + //Color = (*p_index >> 8); + //*p_index = Color | ((*p_index & 0xFF) << 8); + i += 2; + if (*p_index == 0x0000) *p_index = LV_COLOR_BACKGROUND.full; + } + #else + for (i = 0; i < 200;) { + p_index = (uint16_t *)(&public_buf[i]); + //Color = (*p_index >> 8); + //*p_index = Color | ((*p_index & 0xFF) << 8); + i += 2; + if (*p_index == 0x0000) *p_index = LV_COLOR_BACKGROUND.full; // 0x18C3; + } + #endif // TFT_LVGL_UI_SPI + memcpy(data_buf, public_buf, 200); + #endif // SDSUPPORT +} + +void lv_close_gcode_file() {TERN_(SDSUPPORT, card.closefile());} + +void lv_gcode_file_seek(uint32_t pos) { + card.setIndex(pos); +} + +void cutFileName(char *path, int len, int bytePerLine, char *outStr) { + #if _LFN_UNICODE + TCHAR *tmpFile; + TCHAR *strIndex1 = 0, *strIndex2 = 0, *beginIndex; + TCHAR secSeg[10] = {0}; + TCHAR gFileTail[4] = {'~', '.', 'g', '\0'}; + #else + char *tmpFile; + char *strIndex1 = 0, *strIndex2 = 0, *beginIndex; + char secSeg[10] = {0}; + #endif + + if (path == 0 || len <= 3 || outStr == 0) return; + + tmpFile = path; + #if _LFN_UNICODE + strIndex1 = (WCHAR *)wcsstr((const WCHAR *)tmpFile, (const WCHAR *)'/'); + strIndex2 = (WCHAR *)wcsstr((const WCHAR *)tmpFile, (const WCHAR *)'.'); + #else + strIndex1 = (char *)strrchr(tmpFile, '/'); + strIndex2 = (char *)strrchr(tmpFile, '.'); + #endif + + beginIndex = (strIndex1 != 0 + //&& (strIndex2 != 0) && (strIndex1 < strIndex2) + ) ? strIndex1 + 1 : tmpFile; + + if (strIndex2 == 0 || (strIndex1 > strIndex2)) { // not gcode file + #if _LFN_UNICODE + if (wcslen(beginIndex) > len) + wcsncpy(outStr, beginIndex, len); + else + wcscpy(outStr, beginIndex); + #else + if ((int)strlen(beginIndex) > len) + strncpy(outStr, beginIndex, len); + else + strcpy(outStr, beginIndex); + #endif + } + else { // gcode file + if (strIndex2 - beginIndex > (len - 2)) { + #if _LFN_UNICODE + wcsncpy(outStr, (const WCHAR *)beginIndex, len - 3); + wcscat(outStr, (const WCHAR *)gFileTail); + #else + //strncpy(outStr, beginIndex, len - 3); + strncpy(outStr, beginIndex, len - 4); + strcat_P(outStr, PSTR("~.g")); + #endif + } + else { + #if _LFN_UNICODE + wcsncpy(outStr, (const WCHAR *)beginIndex, strIndex2 - beginIndex + 1); + wcscat(outStr, (const WCHAR *)&gFileTail[3]); + #else + strncpy(outStr, beginIndex, strIndex2 - beginIndex + 1); + strcat_P(outStr, PSTR("g")); + #endif + } + } + + #if _LFN_UNICODE + if (wcslen(outStr) > bytePerLine) { + wcscpy(secSeg, (const WCHAR *)&outStr[bytePerLine]); + outStr[bytePerLine] = '\n'; + outStr[bytePerLine + 1] = '\0'; + wcscat(outStr, (const WCHAR *)secSeg); + } + #else + if ((int)strlen(outStr) > bytePerLine) { + strcpy(secSeg, &outStr[bytePerLine]); + outStr[bytePerLine] = '\n'; + outStr[bytePerLine + 1] = '\0'; + strcat(outStr, secSeg); + } + else { + strcat_P(outStr, PSTR("\n")); + } + #endif +} + +void lv_clear_print_file() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_print_file.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_print_file.h new file mode 100644 index 000000000000..083b3d9acf07 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_print_file.h @@ -0,0 +1,66 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +typedef struct { + int cur_page_first_offset; + int cur_page_last_offset; + int curPage; +} DIR_OFFSET; +extern DIR_OFFSET dir_offset[10]; + +#define FILE_NUM 6 +#define SHORT_NEME_LEN 13 +#define NAME_CUT_LEN 23 + +#define MAX_DIR_LEVEL 10 + +typedef struct { + //char longName[FILE_NUM][LONG_FILENAME_LENGTH]; + char file_name[FILE_NUM][SHORT_NEME_LEN * MAX_DIR_LEVEL + 1]; + char curDirPath[SHORT_NEME_LEN * MAX_DIR_LEVEL + 1]; + char long_name[FILE_NUM][SHORT_NEME_LEN * 2 + 1]; + char IsFolder[FILE_NUM]; + char Sd_file_cnt; + char sd_file_index; + char Sd_file_offset; +} LIST_FILE; +extern LIST_FILE list_file; + +extern void disp_gcode_icon(uint8_t file_num); +extern void lv_draw_print_file(void); +extern uint32_t lv_open_gcode_file(char *path); +extern void lv_gcode_file_read(uint8_t *data_buf); +extern void lv_close_gcode_file(); +extern void cutFileName(char *path, int len, int bytePerLine, char *outStr); +extern int ascii2dec_test(char *ascii); +extern void lv_clear_print_file(); +extern void lv_gcode_file_seek(uint32_t pos); + +//extern void disp_temp_ready_print(); +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_printing.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_printing.cpp new file mode 100644 index 000000000000..c6369db41383 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_printing.cpp @@ -0,0 +1,434 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" +//#include "../lvgl/src/lv_objx/lv_imgbtn.h" +//#include "../lvgl/src/lv_objx/lv_img.h" +//#include "../lvgl/src/lv_core/lv_disp.h" +//#include "../lvgl/src/lv_core/lv_refr.h" + +#include "../../../../MarlinCore.h" +#include "../../../../module/temperature.h" +#include "../../../../module/motion.h" +#include "../../../../sd/cardreader.h" +#include "../../../../gcode/queue.h" +#include "../../../../gcode/gcode.h" + +#if ENABLED(POWER_LOSS_RECOVERY) + #include "../../../../feature/powerloss.h" +#endif +#if BOTH(LCD_SET_PROGRESS_MANUALLY, USE_M73_REMAINING_TIME) + #include "../../../ultralcd.h" +#endif + +extern lv_group_t * g; +static lv_obj_t * scr; +static lv_obj_t *labelExt1, * labelFan, * labelZpos, * labelTime; +TERN_(HAS_MULTI_EXTRUDER, static lv_obj_t *labelExt2;) +static lv_obj_t *labelPause, * labelStop, * labelOperat; +static lv_obj_t * bar1, *bar1ValueText; +static lv_obj_t * buttonPause, *buttonOperat, *buttonStop; + +#if HAS_HEATED_BED + static lv_obj_t* labelBed; +#endif + +#define ID_PAUSE 1 +#define ID_STOP 2 +#define ID_OPTION 3 + +uint8_t once_flag = 0; +extern uint32_t To_pre_view; +extern uint8_t flash_preview_begin; +extern uint8_t default_preview_flg; +extern uint8_t gcode_preview_over; + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_PAUSE: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (gcode_preview_over != 1) { + if (uiCfg.print_state == WORKING) { + // #if ENABLED(PARK_HEAD_ON_PAUSE) + // queue.inject_P(PSTR("M25 P\nM24")); + #if ENABLED(SDSUPPORT) + // queue.inject_P(PSTR("M25\nG91\nG1 Z10\nG90")); + card.pauseSDPrint(); + stop_print_time(); + uiCfg.print_state = PAUSING; + #endif + lv_imgbtn_set_src(buttonPause, LV_BTN_STATE_REL, "F:/bmp_resume.bin"); + lv_imgbtn_set_src(buttonPause, LV_BTN_STATE_PR, "F:/bmp_resume.bin"); + lv_label_set_text(labelPause, printing_menu.resume); + lv_obj_align(labelPause, buttonPause, LV_ALIGN_CENTER, 30, 0); + } + else if (uiCfg.print_state == PAUSED) { + uiCfg.print_state = RESUMING; + lv_imgbtn_set_src(obj, LV_BTN_STATE_REL, "F:/bmp_pause.bin"); + lv_imgbtn_set_src(obj, LV_BTN_STATE_PR, "F:/bmp_pause.bin"); + lv_label_set_text(labelPause, printing_menu.pause); + lv_obj_align(labelPause, buttonPause, LV_ALIGN_CENTER, 30, 0); + } + #if ENABLED(POWER_LOSS_RECOVERY) + else if (uiCfg.print_state == REPRINTING) { + uiCfg.print_state = REPRINTED; + lv_imgbtn_set_src(obj, LV_BTN_STATE_REL, "F:/bmp_pause.bin"); + lv_imgbtn_set_src(obj, LV_BTN_STATE_PR, "F:/bmp_pause.bin"); + lv_label_set_text(labelPause, printing_menu.pause); + lv_obj_align(labelPause, buttonPause, LV_ALIGN_CENTER, 30, 0); + // recovery.resume(); + print_time.minutes = recovery.info.print_job_elapsed / 60; + print_time.seconds = recovery.info.print_job_elapsed % 60; + print_time.hours = print_time.minutes / 60; + } + #endif + } + } + break; + + case ID_STOP: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (gcode_preview_over != 1) { + lv_clear_printing(); + lv_draw_dialog(DIALOG_TYPE_STOP); + } + } + break; + case ID_OPTION: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + if (gcode_preview_over != 1) { + lv_clear_printing(); + lv_draw_operation(); + } + } + break; + } +} + +void lv_draw_printing(void) { + disp_state_stack._disp_index = 0; + ZERO(disp_state_stack._disp_state); + disp_state_stack._disp_state[disp_state_stack._disp_index] = PRINTING_UI; + + disp_state = PRINTING_UI; + + scr = lv_obj_create(NULL, NULL); + + // static lv_style_t tool_style; + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, creat_title_text()); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + // Create image buttons + lv_obj_t *buttonExt1 = lv_img_create(scr, NULL); + #if HAS_MULTI_EXTRUDER + lv_obj_t *buttonExt2 = lv_img_create(scr, NULL); + #endif + #if HAS_HEATED_BED + lv_obj_t *buttonBedstate = lv_img_create(scr, NULL); + #endif + lv_obj_t *buttonFanstate = lv_img_create(scr, NULL); + lv_obj_t *buttonTime = lv_img_create(scr, NULL); + lv_obj_t *buttonZpos = lv_img_create(scr, NULL); + buttonPause = lv_imgbtn_create(scr, NULL); + buttonStop = lv_imgbtn_create(scr, NULL); + buttonOperat = lv_imgbtn_create(scr, NULL); + + lv_img_set_src(buttonExt1, "F:/bmp_ext1_state.bin"); + #if 1 + #if HAS_MULTI_EXTRUDER + lv_img_set_src(buttonExt2, "F:/bmp_ext2_state.bin"); + #endif + #if HAS_HEATED_BED + lv_img_set_src(buttonBedstate, "F:/bmp_bed_state.bin"); + #endif + + lv_img_set_src(buttonFanstate, "F:/bmp_fan_state.bin"); + + lv_img_set_src(buttonTime, "F:/bmp_time_state.bin"); + + lv_img_set_src(buttonZpos, "F:/bmp_zpos_state.bin"); + + if (uiCfg.print_state == WORKING) { + lv_imgbtn_set_src(buttonPause, LV_BTN_STATE_REL, "F:/bmp_pause.bin"); + lv_imgbtn_set_src(buttonPause, LV_BTN_STATE_PR, "F:/bmp_pause.bin"); + } + else { + lv_imgbtn_set_src(buttonPause, LV_BTN_STATE_REL, "F:/bmp_resume.bin"); + lv_imgbtn_set_src(buttonPause, LV_BTN_STATE_PR, "F:/bmp_resume.bin"); + } + + lv_obj_set_event_cb_mks(buttonPause, event_handler, ID_PAUSE, NULL, 0); + lv_imgbtn_set_style(buttonPause, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonPause, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonStop, event_handler, ID_STOP, NULL, 0); + lv_imgbtn_set_src(buttonStop, LV_BTN_STATE_REL, "F:/bmp_stop.bin"); + lv_imgbtn_set_src(buttonStop, LV_BTN_STATE_PR, "F:/bmp_stop.bin"); + lv_imgbtn_set_style(buttonStop, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonStop, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonOperat, event_handler, ID_OPTION, NULL, 0); + lv_imgbtn_set_src(buttonOperat, LV_BTN_STATE_REL, "F:/bmp_operate.bin"); + lv_imgbtn_set_src(buttonOperat, LV_BTN_STATE_PR, "F:/bmp_operate.bin"); + lv_imgbtn_set_style(buttonOperat, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonOperat, LV_BTN_STATE_REL, &tft_style_label_rel); + + #endif // if 1 + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonPause); + lv_group_add_obj(g, buttonStop); + lv_group_add_obj(g, buttonOperat); + } + #endif + + lv_obj_set_pos(buttonExt1, 205, 136); + + #if HAS_MULTI_EXTRUDER + lv_obj_set_pos(buttonExt2, 350, 136); + #endif + + #if HAS_HEATED_BED + lv_obj_set_pos(buttonBedstate, 205, 186); + #endif + + lv_obj_set_pos(buttonFanstate, 350, 186); + lv_obj_set_pos(buttonTime, 205, 86); + lv_obj_set_pos(buttonZpos, 350, 86); + lv_obj_set_pos(buttonPause, 5, 240); + lv_obj_set_pos(buttonStop, 165, 240); + lv_obj_set_pos(buttonOperat, 325, 240); + + // Create labels on the image buttons + //lv_btn_set_layout(buttonExt1, LV_LAYOUT_OFF); + //#if HAS_MULTI_EXTRUDER + //lv_btn_set_layout(buttonExt2, LV_LAYOUT_OFF); + //#endif + + //#if HAS_HEATED_BED + //lv_btn_set_layout(buttonBedstate, LV_LAYOUT_OFF); + //#endif + + //lv_btn_set_layout(buttonFanstate, LV_LAYOUT_OFF); + //lv_btn_set_layout(buttonTime, LV_LAYOUT_OFF); + //lv_btn_set_layout(buttonZpos, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonPause, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonStop, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonOperat, LV_LAYOUT_OFF); + + labelExt1 = lv_label_create(scr, NULL); + lv_obj_set_style(labelExt1, &tft_style_label_rel); + lv_obj_set_pos(labelExt1, 250, 146); + + #if HAS_MULTI_EXTRUDER + labelExt2 = lv_label_create(scr, NULL); + lv_obj_set_style(labelExt2, &tft_style_label_rel); + lv_obj_set_pos(labelExt2, 395, 146); + #endif + + #if HAS_HEATED_BED + labelBed = lv_label_create(scr, NULL); + lv_obj_set_style(labelBed, &tft_style_label_rel); + lv_obj_set_pos(labelBed, 250, 196); + #endif + + labelFan = lv_label_create(scr, NULL); + lv_obj_set_style(labelFan, &tft_style_label_rel); + lv_obj_set_pos(labelFan, 395, 196); + + labelTime = lv_label_create(scr, NULL); + lv_obj_set_style(labelTime, &tft_style_label_rel); + lv_obj_set_pos(labelTime, 250, 96); + + labelZpos = lv_label_create(scr, NULL); + lv_obj_set_style(labelZpos, &tft_style_label_rel); + lv_obj_set_pos(labelZpos, 395, 96); + + labelPause = lv_label_create(buttonPause, NULL); + labelStop = lv_label_create(buttonStop, NULL); + labelOperat = lv_label_create(buttonOperat, NULL); + + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(labelPause, uiCfg.print_state == WORKING ? printing_menu.pause : printing_menu.resume); + lv_obj_align(labelPause, buttonPause, LV_ALIGN_CENTER, 20, 0); + + lv_label_set_text(labelStop, printing_menu.stop); + lv_obj_align(labelStop, buttonStop, LV_ALIGN_CENTER, 20, 0); + + lv_label_set_text(labelOperat, printing_menu.option); + lv_obj_align(labelOperat, buttonOperat, LV_ALIGN_CENTER, 20, 0); + } + + bar1 = lv_bar_create(scr, NULL); + lv_obj_set_pos(bar1, 205, 36); + lv_obj_set_size(bar1, 270, 40); + lv_bar_set_style(bar1, LV_BAR_STYLE_INDIC, &lv_bar_style_indic); + lv_bar_set_anim_time(bar1, 1000); + lv_bar_set_value(bar1, 0, LV_ANIM_ON); + bar1ValueText = lv_label_create(bar1, NULL); + lv_label_set_text(bar1ValueText,"0%"); + lv_obj_align(bar1ValueText, bar1, LV_ALIGN_CENTER, 0, 0); + + disp_ext_temp(); + disp_bed_temp(); + disp_fan_speed(); + disp_print_time(); + disp_fan_Zpos(); +} + +void disp_ext_temp() { + ZERO(public_buf_l); + sprintf(public_buf_l, printing_menu.temp1, (int)thermalManager.temp_hotend[0].celsius, (int)thermalManager.temp_hotend[0].target); + lv_label_set_text(labelExt1, public_buf_l); + + #if HAS_MULTI_EXTRUDER + ZERO(public_buf_l); + sprintf(public_buf_l, printing_menu.temp1, (int)thermalManager.temp_hotend[1].celsius, (int)thermalManager.temp_hotend[1].target); + lv_label_set_text(labelExt2, public_buf_l); + #endif +} + +void disp_bed_temp() { + #if HAS_HEATED_BED + ZERO(public_buf_l); + sprintf(public_buf_l, printing_menu.bed_temp, (int)thermalManager.temp_bed.celsius, (int)thermalManager.temp_bed.target); + lv_label_set_text(labelBed, public_buf_l); + #endif +} + +void disp_fan_speed() { + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%3d"), thermalManager.fan_speed[0]); + lv_label_set_text(labelFan, public_buf_l); +} + +void disp_print_time() { + ZERO(public_buf_l); + #if BOTH(LCD_SET_PROGRESS_MANUALLY, USE_M73_REMAINING_TIME) + const uint32_t r = ui.get_remaining_time(); + sprintf_P(public_buf_l, PSTR("%02d:%02d R"), r / 3600, (r % 3600) / 60); + #else + sprintf_P(public_buf_l, PSTR("%d%d:%d%d:%d%d"), print_time.hours / 10, print_time.hours % 10, print_time.minutes / 10, print_time.minutes % 10, print_time.seconds / 10, print_time.seconds % 10); + #endif + lv_label_set_text(labelTime, public_buf_l); +} + +void disp_fan_Zpos() { + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.3f"), current_position[Z_AXIS]); + lv_label_set_text(labelZpos, public_buf_l); +} + +void reset_print_time() { + // print_time.days = 0; + print_time.hours = 0; + print_time.minutes = 0; + print_time.seconds = 0; + print_time.ms_10 = 0; + // print_time.start = 1; +} + +void start_print_time() { print_time.start = 1; } + +void stop_print_time() { print_time.start = 0; } + +void setProBarRate() { + int rate; + volatile long long rate_tmp_r; + + if (gCfgItems.from_flash_pic != 1) { + #if ENABLED(SDSUPPORT) + rate_tmp_r = (long long)card.getIndex() * 100; + #endif + rate = rate_tmp_r / gCfgItems.curFilesize; + } + else { + #if ENABLED(SDSUPPORT) + rate_tmp_r = (long long)card.getIndex(); + #endif + rate = (rate_tmp_r - (PREVIEW_SIZE + To_pre_view)) * 100 / (gCfgItems.curFilesize - (PREVIEW_SIZE + To_pre_view)); + } + // gCurFileState.totalSend = rate; + + if (rate <= 0) return; + + if (disp_state == PRINTING_UI) { + lv_bar_set_value(bar1, rate, LV_ANIM_ON); + ZERO(public_buf_l); + sprintf_P(public_buf_l, "%d%%", rate); + lv_label_set_text(bar1ValueText,public_buf_l); + lv_obj_align(bar1ValueText, bar1, LV_ALIGN_CENTER, 0, 0); + + if (marlin_state == MF_SD_COMPLETE) { + if (once_flag == 0) { + stop_print_time(); + + flash_preview_begin = 0; + default_preview_flg = 0; + lv_clear_printing(); + lv_draw_dialog(DIALOG_TYPE_FINISH_PRINT); + + once_flag = 1; + + #if HAS_SUICIDE + if (gCfgItems.finish_power_off == 1) { + gcode.process_subcommands_now_P(PSTR("M1001")); + queue.inject_P(PSTR("M81")); + marlin_state = MF_RUNNING; + } + #endif + } + } + } +} + +void lv_clear_printing() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_printing.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_printing.h new file mode 100644 index 000000000000..b7d464e4f093 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_printing.h @@ -0,0 +1,52 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +#define IDLE 0 +#define WORKING 1 +#define PAUSING 2 +#define PAUSED 3 +#define REPRINTING 4 +#define REPRINTED 5 +#define RESUMING 6 +#define STOP 7 + +extern void lv_draw_printing(void); +extern void lv_clear_printing(); +extern void disp_ext_temp(); +extern void disp_bed_temp(); +extern void disp_fan_speed(); +extern void disp_print_time(); +extern void disp_fan_Zpos(); +extern void reset_print_time(); +extern void start_print_time(); +extern void stop_print_time(); +extern void setProBarRate(); + +//extern void disp_temp_ready_print(); +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_ready_print.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_ready_print.cpp new file mode 100644 index 000000000000..54ffdca64a44 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_ready_print.cpp @@ -0,0 +1,310 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "draw_ready_print.h" +#include "draw_tool.h" +#include "lv_conf.h" +//#include "../lvgl/src/lv_objx/lv_imgbtn.h" +//#include "../lvgl/src/lv_objx/lv_img.h" +//#include "../lvgl/src/lv_core/lv_disp.h" +//#include "../lvgl/src/lv_core/lv_refr.h" +#include "tft_lvgl_configuration.h" +#include "mks_hardware_test.h" +#include "draw_ui.h" + +#include + +#include "../../../../MarlinCore.h" +#include "../../../../module/temperature.h" + +#include + +//static lv_obj_t *buttonPrint,*buttonTool,*buttonSet; +extern lv_group_t* g; +static lv_obj_t * scr; +#if ENABLED(MKS_TEST) + uint8_t curent_disp_ui = 0; +#endif + +#define ID_TOOL 1 +#define ID_SET 2 +#define ID_PRINT 3 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_TOOL: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + + lv_clear_ready_print(); + lv_draw_tool(); + } + break; + case ID_SET: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_ready_print(); + lv_draw_set(); + } + break; + case ID_PRINT: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_ready_print(); + lv_draw_print_file(); + } + break; + } +} + +lv_obj_t *limit_info, *det_info; +lv_style_t limit_style, det_style; +void disp_Limit_ok() { + limit_style.text.color.full = 0xFFFF; + lv_obj_set_style(limit_info, &limit_style); + lv_label_set_text(limit_info, "Limit:ok"); +} +void disp_Limit_error() { + limit_style.text.color.full = 0xF800; + lv_obj_set_style(limit_info, &limit_style); + lv_label_set_text(limit_info, "Limit:error"); +} + +void disp_det_ok() { + det_style.text.color.full = 0xFFFF; + lv_obj_set_style(det_info, &det_style); + lv_label_set_text(det_info, "det:ok"); +} +void disp_det_error() { + det_style.text.color.full = 0xF800; + lv_obj_set_style(det_info, &det_style); + lv_label_set_text(det_info, "det:error"); +} + +lv_obj_t *e1, *e2, *e3, *bed; +void mks_disp_test() { + char buf[30] = {0}; + //lv_obj_t *label_tool2 = lv_label_create(scr, NULL); + //lv_obj_set_pos(label_tool,20,50); + ZERO(buf); + sprintf_P(buf, PSTR("e1:%d"), (int)thermalManager.temp_hotend[0].celsius); + lv_label_set_text(e1, buf); + #if HAS_MULTI_HOTEND + ZERO(buf); + sprintf_P(buf, PSTR("e2:%d"), (int)thermalManager.temp_hotend[1].celsius); + lv_label_set_text(e2, buf); + #endif + + //ZERO(buf); + //sprintf_P(buf, PSTR("e3:%d"), (int)thermalManager.temp_hotend[2].celsius); + //lv_label_set_text(e3, buf); + #if HAS_HEATED_BED + ZERO(buf); + sprintf_P(buf, PSTR("bed:%d"), (int)thermalManager.temp_bed.celsius); + lv_label_set_text(bed, buf); + #endif +} + +void lv_draw_ready_print(void) { + char buf[30] = {0}; + lv_obj_t *buttonPrint, *buttonTool, *buttonSet; + + disp_state_stack._disp_index = 0; + ZERO(disp_state_stack._disp_state); + disp_state_stack._disp_state[disp_state_stack._disp_index] = PRINT_READY_UI; + + disp_state = PRINT_READY_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + //lv_obj_set_hidden(scr,true); + lv_refr_now(lv_refr_get_disp_refreshing()); + + if (mks_test_flag == 0x1E) { + //lv_obj_t * title = lv_label_create(scr, NULL); + //lv_obj_set_style(title, &tft_style_label_rel); + //lv_obj_set_pos(title,TITLE_XPOS,TITLE_YPOS); + //lv_label_set_text(title, creat_title_text()); + + // Create image buttons + //buttonPrint = lv_imgbtn_create(scr, NULL); + buttonTool = lv_imgbtn_create(scr, NULL); + //buttonSet = lv_imgbtn_create(scr, NULL); + + #if 1 + lv_obj_set_event_cb_mks(buttonTool, event_handler, ID_TOOL, NULL, 0); + lv_imgbtn_set_src(buttonTool, LV_BTN_STATE_REL, "F:/bmp_tool.bin"); + lv_imgbtn_set_src(buttonTool, LV_BTN_STATE_PR, "F:/bmp_tool.bin"); + lv_imgbtn_set_style(buttonTool, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonTool, LV_BTN_STATE_REL, &tft_style_label_rel); + #endif + + lv_obj_set_pos(buttonTool, 360, 180); + //lv_obj_set_pos(buttonSet,180,90); + //lv_obj_set_pos(buttonPrint,340,90); + + //lv_obj_set_pos(buttonTool,SIMPLE_FIRST_PAGE_GRAP+1,(TFT_HEIGHT-BTN_Y_PIXEL)/2+2); + //lv_obj_set_pos(buttonSet,BTN_X_PIXEL+SIMPLE_FIRST_PAGE_GRAP*2+1,(TFT_HEIGHT-BTN_Y_PIXEL)/2+2); + //lv_obj_set_pos(buttonPrint,BTN_X_PIXEL*2+SIMPLE_FIRST_PAGE_GRAP*3+1,(TFT_HEIGHT-BTN_Y_PIXEL)/2+2); + + // Create labels on the image buttons + //lv_btn_set_layout(buttonPrint, LV_LAYOUT_OFF); + //lv_btn_set_layout(buttonSet, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonTool, LV_LAYOUT_OFF); + + //lv_obj_t *label_print = lv_label_create(buttonPrint, NULL); + //lv_obj_t *label_set = lv_label_create(buttonSet, NULL); + lv_obj_t *label_tool = lv_label_create(buttonTool, NULL); + if (gCfgItems.multiple_language != 0) { + //lv_label_set_text(label_print, main_menu.print); + //lv_obj_align(label_print, buttonPrint, LV_ALIGN_IN_BOTTOM_MID,0, BUTTON_TEXT_Y_OFFSET); + + //lv_label_set_text(label_set, main_menu.set); + //lv_obj_align(label_set, buttonSet, LV_ALIGN_IN_BOTTOM_MID,0, BUTTON_TEXT_Y_OFFSET); + + //lv_label_set_style(label_tool,LV_BTN_STATE_PR,&tft_style_label_pre); + //lv_label_set_style(label_tool,LV_BTN_STATE_REL,&tft_style_label_rel); + lv_label_set_text(label_tool, main_menu.tool); + lv_obj_align(label_tool, buttonTool, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + + #if 1 + e1 = lv_label_create(scr, NULL); + lv_obj_set_pos(e1, 20, 20); + sprintf_P(buf, PSTR("e1: %d"), (int)thermalManager.temp_hotend[0].celsius); + lv_label_set_text(e1, buf); + #if HAS_MULTI_HOTEND + e2 = lv_label_create(scr, NULL); + lv_obj_set_pos(e2, 20, 45); + sprintf_P(buf, PSTR("e1: %d"), (int)thermalManager.temp_hotend[1].celsius); + lv_label_set_text(e2, buf); + #endif + + //e3 = lv_label_create(scr, NULL); + //lv_obj_set_pos(e3,20,70); + //sprintf_P(buf, PSTR("e1: %d"), (int)thermalManager.temp_hotend[2].celsius); + //lv_label_set_text(e3, buf); + + #if HAS_HEATED_BED + bed = lv_label_create(scr, NULL); + lv_obj_set_pos(bed, 20, 95); + sprintf_P(buf, PSTR("bed: %d"), (int)thermalManager.temp_bed.celsius); + lv_label_set_text(bed, buf); + #endif + + limit_info = lv_label_create(scr, NULL); + + lv_style_copy(&limit_style, &lv_style_scr); + limit_style.body.main_color.full = 0X0000; + limit_style.body.grad_color.full = 0X0000; + limit_style.text.color.full = 0Xffff; + lv_obj_set_style(limit_info, &limit_style); + + lv_obj_set_pos(limit_info, 20, 120); + lv_label_set_text(limit_info, " "); + + det_info = lv_label_create(scr, NULL); + + lv_style_copy(&det_style, &lv_style_scr); + det_style.body.main_color.full = 0X0000; + det_style.body.grad_color.full = 0X0000; + det_style.text.color.full = 0Xffff; + lv_obj_set_style(det_info, &det_style); + + lv_obj_set_pos(det_info, 20, 145); + lv_label_set_text(det_info, " "); + #endif // if 1 + + } + else { + // Create an Image button + buttonTool = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonTool, 20, 90); + lv_obj_set_event_cb_mks(buttonTool, event_handler, ID_TOOL, NULL, 0); + lv_imgbtn_set_src(buttonTool, LV_BTN_STATE_REL, "F:/bmp_tool.bin"); + lv_imgbtn_set_src(buttonTool, LV_BTN_STATE_PR, "F:/bmp_tool.bin"); + lv_imgbtn_set_style(buttonTool, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonTool, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_obj_t *label_tool = lv_label_create(buttonTool, NULL); + lv_btn_set_layout(buttonTool, LV_LAYOUT_OFF); + + buttonSet = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonSet, 180, 90); + lv_obj_set_event_cb_mks(buttonSet, event_handler, ID_SET, NULL, 0); + lv_imgbtn_set_src(buttonSet, LV_BTN_STATE_REL, "F:/bmp_set.bin"); + lv_imgbtn_set_src(buttonSet, LV_BTN_STATE_PR, "F:/bmp_set.bin"); + lv_imgbtn_set_style(buttonSet, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonSet, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_obj_t *label_set = lv_label_create(buttonSet, NULL); + lv_btn_set_layout(buttonSet, LV_LAYOUT_OFF); + + buttonPrint = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonPrint, 340, 90); + lv_obj_set_event_cb_mks(buttonPrint, event_handler, ID_PRINT, NULL, 0); + lv_imgbtn_set_src(buttonPrint, LV_BTN_STATE_REL, "F:/bmp_printing.bin"); + lv_imgbtn_set_src(buttonPrint, LV_BTN_STATE_PR, "F:/bmp_printing.bin"); + lv_imgbtn_set_style(buttonPrint, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonPrint, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_obj_t *label_print = lv_label_create(buttonPrint, NULL); + lv_btn_set_layout(buttonPrint, LV_LAYOUT_OFF); + + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(label_print, main_menu.print); + lv_obj_align(label_print, buttonPrint, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_set, main_menu.set); + lv_obj_align(label_set, buttonSet, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_tool, main_menu.tool); + lv_obj_align(label_tool, buttonTool, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable == true) { + lv_group_add_obj(g, buttonTool); + lv_group_add_obj(g, buttonSet); + lv_group_add_obj(g, buttonPrint); + } + #endif + } +} + +void lv_clear_ready_print() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable == true) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_ready_print.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_ready_print.h new file mode 100644 index 000000000000..5cefe8b59b36 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_ready_print.h @@ -0,0 +1,39 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_ready_print(void); +extern void mks_disp_test(); +extern void disp_Limit_ok(); +extern void disp_Limit_error(); +extern void disp_det_error(); +extern void disp_det_ok(); +extern void lv_clear_ready_print(); + +//extern void disp_temp_ready_print(); +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_set.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_set.cpp new file mode 100644 index 000000000000..6c10713d8a9c --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_set.cpp @@ -0,0 +1,389 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "../../../../MarlinCore.h" +#include "draw_ready_print.h" +#include "draw_set.h" +#include "lv_conf.h" +//#include "../lvgl/src/lv_objx/lv_imgbtn.h" +//#include "../lvgl/src/lv_objx/lv_img.h" +//#include "../lvgl/src/lv_core/lv_disp.h" +//#include "../lvgl/src/lv_core/lv_refr.h" +#include "draw_ui.h" +#include "../../../../gcode/queue.h" +#include "pic_manager.h" + +static lv_obj_t * scr; +extern lv_group_t* g; + +#define ID_S_WIFI 1 +#define ID_S_FAN 2 +#define ID_S_ABOUT 3 +#define ID_S_CONTINUE 4 +#define ID_S_MOTOR_OFF 5 +#define ID_S_LANGUAGE 6 +#define ID_S_MACHINE_PARA 7 +#define ID_S_EEPROM_SET 8 +#define ID_S_RETURN 9 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + #if ENABLED(USE_WIFI_FUNCTION) + char buf[6] = { 0 }; + #endif + switch (obj->mks_obj_id) { + + case ID_S_FAN: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_set(); + lv_draw_fan(); + } + break; + case ID_S_ABOUT: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_set(); + lv_draw_about(); + } + break; + case ID_S_CONTINUE: + + break; + case ID_S_MOTOR_OFF: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + #if HAS_SUICIDE + suicide(); + #else + queue.enqueue_now_P(PSTR("M84")); + #endif + } + break; + case ID_S_LANGUAGE: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_set(); + lv_draw_language(); + } + break; + case ID_S_MACHINE_PARA: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_set(); + lv_draw_machine_para(); + } + break; + case ID_S_EEPROM_SET: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_set(); + lv_draw_eeprom_settings(); + } + break; + case ID_S_RETURN: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_set(); + lv_draw_ready_print(); + } + break; + #if ENABLED(USE_WIFI_FUNCTION) + case ID_S_WIFI: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (gCfgItems.wifi_mode_sel == STA_MODEL) { + if (wifi_link_state == WIFI_CONNECTED) { + last_disp_state = SET_UI; + lv_clear_set(); + lv_draw_wifi(); + } + else { + if (uiCfg.command_send == 1) { + buf[0] = 0xA5; + buf[1] = 0x07; + buf[2] = 0x00; + buf[3] = 0x00; + buf[4] = 0xFC; + raw_send_to_wifi(buf, 5); + + last_disp_state = SET_UI; + lv_clear_set(); + lv_draw_wifi_list(); + } + else { + last_disp_state = SET_UI; + lv_clear_set(); + lv_draw_dialog(WIFI_ENABLE_TIPS); + } + } + } + else { + last_disp_state = SET_UI; + lv_clear_set(); + lv_draw_wifi(); + } + } + break; + #endif + } +} + +void lv_draw_set(void) { + lv_obj_t *buttonFan, *buttonAbout; + lv_obj_t *buMotorOff, *buttonBack; + #if HAS_LANG_SELECT_SCREEN + lv_obj_t *buttonLanguage; + #endif + lv_obj_t *buttonMachinePara; + lv_obj_t *buttonEepromSet; + #if ENABLED(USE_WIFI_FUNCTION) + lv_obj_t *buttonWifi; + #endif + + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != SET_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = SET_UI; + } + disp_state = SET_UI; + + scr = lv_obj_create(NULL, NULL); + + //static lv_style_t tool_style; + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, creat_title_text()); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + // Create image buttons + buttonEepromSet = lv_imgbtn_create(scr, NULL); + //buttonWifi = lv_imgbtn_create(scr, NULL); + buttonFan = lv_imgbtn_create(scr, NULL); + buttonAbout = lv_imgbtn_create(scr, NULL); + //buttonContinue = lv_imgbtn_create(scr, NULL); + buMotorOff = lv_imgbtn_create(scr, NULL); + buttonMachinePara = lv_imgbtn_create(scr, NULL); + #if HAS_LANG_SELECT_SCREEN + buttonLanguage = lv_imgbtn_create(scr, NULL); + #endif + #if ENABLED(USE_WIFI_FUNCTION) + buttonWifi = lv_imgbtn_create(scr, NULL); + #endif + buttonBack = lv_imgbtn_create(scr, NULL); + + lv_obj_set_event_cb_mks(buttonEepromSet, event_handler, ID_S_EEPROM_SET, NULL, 0); + lv_imgbtn_set_src(buttonEepromSet, LV_BTN_STATE_REL, "F:/bmp_eeprom_settings.bin"); + lv_imgbtn_set_src(buttonEepromSet, LV_BTN_STATE_PR, "F:/bmp_eeprom_settings.bin"); + lv_imgbtn_set_style(buttonEepromSet, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonEepromSet, LV_BTN_STATE_REL, &tft_style_label_rel); + + #if 1 + lv_obj_set_event_cb_mks(buttonFan, event_handler, ID_S_FAN, NULL, 0); + lv_imgbtn_set_src(buttonFan, LV_BTN_STATE_REL, "F:/bmp_fan.bin"); + lv_imgbtn_set_src(buttonFan, LV_BTN_STATE_PR, "F:/bmp_fan.bin"); + lv_imgbtn_set_style(buttonFan, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonFan, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonAbout, event_handler, ID_S_ABOUT, NULL, 0); + lv_imgbtn_set_src(buttonAbout, LV_BTN_STATE_REL, "F:/bmp_about.bin"); + lv_imgbtn_set_src(buttonAbout, LV_BTN_STATE_PR, "F:/bmp_about.bin"); + lv_imgbtn_set_style(buttonAbout, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonAbout, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buMotorOff, event_handler, ID_S_MOTOR_OFF, NULL, 0); + + #if HAS_SUICIDE + lv_imgbtn_set_src(buMotorOff, LV_BTN_STATE_REL, "F:/bmp_manual_off.bin"); + lv_imgbtn_set_src(buMotorOff, LV_BTN_STATE_PR, "F:/bmp_manual_off.bin"); + #else + lv_imgbtn_set_src(buMotorOff, LV_BTN_STATE_REL, "F:/bmp_function1.bin"); + lv_imgbtn_set_src(buMotorOff, LV_BTN_STATE_PR, "F:/bmp_function1.bin"); + #endif + lv_imgbtn_set_style(buMotorOff, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buMotorOff, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonMachinePara, event_handler, ID_S_MACHINE_PARA, NULL, 0); + lv_imgbtn_set_src(buttonMachinePara, LV_BTN_STATE_REL, "F:/bmp_machine_para.bin"); + lv_imgbtn_set_src(buttonMachinePara, LV_BTN_STATE_PR, "F:/bmp_machine_para.bin"); + lv_imgbtn_set_style(buttonMachinePara, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonMachinePara, LV_BTN_STATE_REL, &tft_style_label_rel); + + #if HAS_LANG_SELECT_SCREEN + lv_obj_set_event_cb_mks(buttonLanguage, event_handler, ID_S_LANGUAGE, NULL, 0); + lv_imgbtn_set_src(buttonLanguage, LV_BTN_STATE_REL, "F:/bmp_language.bin"); + lv_imgbtn_set_src(buttonLanguage, LV_BTN_STATE_PR, "F:/bmp_language.bin"); + lv_imgbtn_set_style(buttonLanguage, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonLanguage, LV_BTN_STATE_REL, &tft_style_label_rel); + #endif + + #if ENABLED(USE_WIFI_FUNCTION) + lv_obj_set_event_cb_mks(buttonWifi, event_handler,ID_S_WIFI,NULL,0); + lv_imgbtn_set_src(buttonWifi, LV_BTN_STATE_REL, "F:/bmp_wifi.bin"); + lv_imgbtn_set_src(buttonWifi, LV_BTN_STATE_PR, "F:/bmp_wifi.bin"); + lv_imgbtn_set_style(buttonWifi, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonWifi, LV_BTN_STATE_REL, &tft_style_label_rel); + #endif + + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_S_RETURN,NULL , 0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_return.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_return.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + + #endif // if 1 + + /*lv_obj_set_pos(buttonWifi,INTERVAL_V,titleHeight); + lv_obj_set_pos(buttonFan,BTN_X_PIXEL+INTERVAL_V*2,titleHeight); + lv_obj_set_pos(buttonAbout,BTN_X_PIXEL*2+INTERVAL_V*3,titleHeight); + lv_obj_set_pos(buttonContinue,BTN_X_PIXEL*3+INTERVAL_V*4,titleHeight); + lv_obj_set_pos(buMotorOff,INTERVAL_V, BTN_Y_PIXEL+INTERVAL_H+titleHeight); + lv_obj_set_pos(buttonLanguage,BTN_X_PIXEL+INTERVAL_V*2,BTN_Y_PIXEL+INTERVAL_H+titleHeight); + lv_obj_set_pos(buttonBack,BTN_X_PIXEL*3+INTERVAL_V*4, BTN_Y_PIXEL+INTERVAL_H+titleHeight);*/ + + //lv_obj_set_pos(buttonWifi,INTERVAL_V,titleHeight); + lv_obj_set_pos(buttonEepromSet, INTERVAL_V, titleHeight); + lv_obj_set_pos(buttonFan, BTN_X_PIXEL + INTERVAL_V * 2, titleHeight); + lv_obj_set_pos(buttonAbout, BTN_X_PIXEL * 2 + INTERVAL_V * 3, titleHeight); + //lv_obj_set_pos(buttonContinue,BTN_X_PIXEL*3+INTERVAL_V*4,titleHeight); + lv_obj_set_pos(buMotorOff, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight); + + lv_obj_set_pos(buttonMachinePara, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + #if HAS_LANG_SELECT_SCREEN + lv_obj_set_pos(buttonLanguage, BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + #endif + #if ENABLED(USE_WIFI_FUNCTION) + lv_obj_set_pos(buttonWifi,BTN_X_PIXEL*2+INTERVAL_V*3,BTN_Y_PIXEL+INTERVAL_H+titleHeight); + #endif + lv_obj_set_pos(buttonBack, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + + /// Create labels on the buttons + //lv_btn_set_layout(buttonWifi, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonEepromSet, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonFan, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonAbout, LV_LAYOUT_OFF); + //lv_btn_set_layout(buttonContinue, LV_LAYOUT_OFF); + lv_btn_set_layout(buMotorOff, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonMachinePara, LV_LAYOUT_OFF); + #if HAS_LANG_SELECT_SCREEN + lv_btn_set_layout(buttonLanguage, LV_LAYOUT_OFF); + #endif + #if ENABLED(USE_WIFI_FUNCTION) + lv_btn_set_layout(buttonWifi, LV_LAYOUT_OFF); + #endif + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + + //lv_obj_t *labelWifi= lv_label_create(buttonWifi, NULL); + lv_obj_t *label_EepromSet = lv_label_create(buttonEepromSet, NULL); + lv_obj_t *labelFan = lv_label_create(buttonFan, NULL); + lv_obj_t *label_About = lv_label_create(buttonAbout, NULL); + //lv_obj_t *label_Continue = lv_label_create(buttonContinue, NULL); + lv_obj_t *label_MotorOff = lv_label_create(buMotorOff, NULL); + lv_obj_t *label_MachinePara = lv_label_create(buttonMachinePara, NULL); + #if HAS_LANG_SELECT_SCREEN + lv_obj_t *label_Language = lv_label_create(buttonLanguage, NULL); + #endif + #if ENABLED(USE_WIFI_FUNCTION) + lv_obj_t *label_Wifi = lv_label_create(buttonWifi, NULL); + #endif + lv_obj_t *label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.multiple_language != 0) { + + lv_label_set_text(label_EepromSet, set_menu.eepromSet); + lv_obj_align(label_EepromSet, buttonEepromSet, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelFan, set_menu.fan); + lv_obj_align(labelFan, buttonFan, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_About, set_menu.about); + lv_obj_align(label_About, buttonAbout, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + //lv_label_set_text(label_Continue, set_menu.breakpoint); + //lv_obj_align(label_Continue, buttonContinue, LV_ALIGN_IN_BOTTOM_MID,0, BUTTON_TEXT_Y_OFFSET); + lv_label_set_text(label_MotorOff, set_menu.TERN(HAS_SUICIDE, shutdown, motoroff)); + lv_obj_align(label_MotorOff, buMotorOff, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_MachinePara, set_menu.machine_para); + lv_obj_align(label_MachinePara, buttonMachinePara, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + #if HAS_LANG_SELECT_SCREEN + lv_label_set_text(label_Language, set_menu.language); + lv_obj_align(label_Language, buttonLanguage, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + #endif + + #if ENABLED(USE_WIFI_FUNCTION) + lv_label_set_text(label_Wifi, set_menu.wifi); + lv_obj_align(label_Wifi, buttonWifi, LV_ALIGN_IN_BOTTOM_MID,0, BUTTON_TEXT_Y_OFFSET); + #endif + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonEepromSet); + lv_group_add_obj(g, buttonFan); + lv_group_add_obj(g, buttonAbout); + lv_group_add_obj(g, buMotorOff); + lv_group_add_obj(g, buttonMachinePara); + lv_group_add_obj(g, buttonLanguage); + #if ENABLED(USE_WIFI_FUNCTION) + lv_group_add_obj(g, buttonWifi); + #endif + lv_group_add_obj(g, buttonBack); + } + #endif +} + +void lv_clear_set() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_set.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_set.h new file mode 100644 index 000000000000..b243bca296ad --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_set.h @@ -0,0 +1,34 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_set(void); +extern void lv_clear_set(); + +//extern void disp_temp_ready_print(); +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_step_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_step_settings.cpp new file mode 100644 index 000000000000..baad23f9aed7 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_step_settings.cpp @@ -0,0 +1,328 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" + +#include "../../../../MarlinCore.h" +#include "../../../../module/planner.h" + +extern lv_group_t * g; +static lv_obj_t * scr; + +#define ID_STEP_RETURN 1 +#define ID_STEP_X 2 +#define ID_STEP_Y 3 +#define ID_STEP_Z 4 +#define ID_STEP_E0 5 +#define ID_STEP_E1 6 +#define ID_STEP_DOWN 7 +#define ID_STEP_UP 8 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_STEP_RETURN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.para_ui_page = 0; + lv_clear_step_settings(); + draw_return_ui(); + } + break; + case ID_STEP_X: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = Xstep; + lv_clear_step_settings(); + lv_draw_number_key(); + } + break; + case ID_STEP_Y: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = Ystep; + lv_clear_step_settings(); + lv_draw_number_key(); + } + break; + case ID_STEP_Z: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = Zstep; + lv_clear_step_settings(); + lv_draw_number_key(); + } + break; + case ID_STEP_E0: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = E0step; + lv_clear_step_settings(); + lv_draw_number_key(); + } + break; + case ID_STEP_E1: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = E1step; + lv_clear_step_settings(); + lv_draw_number_key(); + } + break; + case ID_STEP_UP: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.para_ui_page = 0; + lv_clear_step_settings(); + lv_draw_step_settings(); + } + break; + case ID_STEP_DOWN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.para_ui_page = 1; + lv_clear_step_settings(); + lv_draw_step_settings(); + } + break; + } +} + +void lv_draw_step_settings(void) { + lv_obj_t *buttonBack = NULL, *label_Back = NULL, *buttonTurnPage = NULL, *labelTurnPage = NULL; + lv_obj_t *labelXText = NULL, *buttonXValue = NULL, *labelXValue = NULL; + lv_obj_t *labelYText = NULL, *buttonYValue = NULL, *labelYValue = NULL; + lv_obj_t *labelZText = NULL, *buttonZValue = NULL, *labelZValue = NULL; + lv_obj_t *labelE0Text = NULL, *buttonE0Value = NULL, *labelE0Value = NULL; + lv_obj_t *labelE1Text = NULL, *buttonE1Value = NULL, *labelE1Value = NULL; + lv_obj_t * line1 = NULL, * line2 = NULL, * line3 = NULL, * line4 = NULL; + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != STEPS_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = STEPS_UI; + } + disp_state = STEPS_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, machine_menu.StepsConfTitle); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + if (uiCfg.para_ui_page != 1) { + labelXText = lv_label_create(scr, NULL); + lv_obj_set_style(labelXText, &tft_style_label_rel); + lv_obj_set_pos(labelXText, PARA_UI_POS_X, PARA_UI_POS_Y + 10); + lv_label_set_text(labelXText, machine_menu.X_Steps); + + buttonXValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonXValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y + PARA_UI_VALUE_V); + lv_obj_set_size(buttonXValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonXValue, event_handler, ID_STEP_X, NULL, 0); + lv_btn_set_style(buttonXValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonXValue, LV_BTN_STYLE_PR, &style_para_value); + labelXValue = lv_label_create(buttonXValue, NULL); + + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1, line_points[0]); + + labelYText = lv_label_create(scr, NULL); + lv_obj_set_style(labelYText, &tft_style_label_rel); + lv_obj_set_pos(labelYText, PARA_UI_POS_X, PARA_UI_POS_Y * 2 + 10); + lv_label_set_text(labelYText, machine_menu.Y_Steps); + + buttonYValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonYValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 2 + PARA_UI_VALUE_V); + lv_obj_set_size(buttonYValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonYValue, event_handler, ID_STEP_Y, NULL, 0); + lv_btn_set_style(buttonYValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonYValue, LV_BTN_STYLE_PR, &style_para_value); + labelYValue = lv_label_create(buttonYValue, NULL); + + line2 = lv_line_create(scr, NULL); + lv_ex_line(line2, line_points[1]); + + labelZText = lv_label_create(scr, NULL); + lv_obj_set_style(labelZText, &tft_style_label_rel); + lv_obj_set_pos(labelZText, PARA_UI_POS_X, PARA_UI_POS_Y * 3 + 10); + lv_label_set_text(labelZText, machine_menu.Z_Steps); + + buttonZValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonZValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 3 + PARA_UI_VALUE_V); + lv_obj_set_size(buttonZValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonZValue, event_handler, ID_STEP_Z, NULL, 0); + lv_btn_set_style(buttonZValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonZValue, LV_BTN_STYLE_PR, &style_para_value); + labelZValue = lv_label_create(buttonZValue, NULL); + + line3 = lv_line_create(scr, NULL); + lv_ex_line(line3, line_points[2]); + + labelE0Text = lv_label_create(scr, NULL); + lv_obj_set_style(labelE0Text, &tft_style_label_rel); + lv_obj_set_pos(labelE0Text, PARA_UI_POS_X, PARA_UI_POS_Y * 4 + 10); + lv_label_set_text(labelE0Text, machine_menu.E0_Steps); + + buttonE0Value = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonE0Value, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 4 + PARA_UI_VALUE_V); + lv_obj_set_size(buttonE0Value, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonE0Value, event_handler, ID_STEP_E0, NULL, 0); + lv_btn_set_style(buttonE0Value, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonE0Value, LV_BTN_STYLE_PR, &style_para_value); + labelE0Value = lv_label_create(buttonE0Value, NULL); + + line4 = lv_line_create(scr, NULL); + lv_ex_line(line4, line_points[3]); + + buttonTurnPage = lv_btn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonTurnPage, event_handler, ID_STEP_DOWN, NULL, 0); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_REL, &style_para_back); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_PR, &style_para_back); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonXValue); + lv_group_add_obj(g, buttonYValue); + lv_group_add_obj(g, buttonZValue); + lv_group_add_obj(g, buttonE0Value); + lv_group_add_obj(g, buttonTurnPage); + } + #endif + } + else { + labelE1Text = lv_label_create(scr, NULL); + lv_obj_set_style(labelE1Text, &tft_style_label_rel); + lv_obj_set_pos(labelE1Text, PARA_UI_POS_X, PARA_UI_POS_Y + 10); + lv_label_set_text(labelE1Text, machine_menu.E1_Steps); + + buttonE1Value = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonE1Value, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y + PARA_UI_VALUE_V); + lv_obj_set_size(buttonE1Value, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonE1Value, event_handler, ID_STEP_E1, NULL, 0); + lv_btn_set_style(buttonE1Value, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonE1Value, LV_BTN_STYLE_PR, &style_para_value); + labelE1Value = lv_label_create(buttonE1Value, NULL); + + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1, line_points[0]); + + buttonTurnPage = lv_btn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonTurnPage, event_handler, ID_STEP_UP, NULL, 0); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_REL, &style_para_back); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_PR, &style_para_back); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonE1Value); + lv_group_add_obj(g, buttonTurnPage); + } + #endif + } + + lv_obj_set_pos(buttonTurnPage, PARA_UI_TURN_PAGE_POS_X, PARA_UI_TURN_PAGE_POS_Y); + lv_obj_set_size(buttonTurnPage, PARA_UI_BACK_BTN_X_SIZE, PARA_UI_BACK_BTN_Y_SIZE); + labelTurnPage = lv_label_create(buttonTurnPage, NULL); + + buttonBack = lv_btn_create(scr, NULL); + lv_btn_set_style(buttonBack, LV_BTN_STYLE_REL, &style_para_back); + lv_btn_set_style(buttonBack, LV_BTN_STYLE_PR, &style_para_back); + lv_obj_set_pos(buttonBack, PARA_UI_BACL_POS_X, PARA_UI_BACL_POS_Y); + lv_obj_set_size(buttonBack, PARA_UI_BACK_BTN_X_SIZE, PARA_UI_BACK_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_STEP_RETURN, NULL, 0); + label_Back = lv_label_create(buttonBack, NULL); + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonBack); + #endif + + if (gCfgItems.multiple_language != 0) { + if (uiCfg.para_ui_page != 1) { + lv_label_set_text(labelTurnPage, machine_menu.next); + lv_obj_align(labelTurnPage, buttonTurnPage, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), planner.settings.axis_steps_per_mm[X_AXIS]); + lv_label_set_text(labelXValue, public_buf_l); + lv_obj_align(labelXValue, buttonXValue, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), planner.settings.axis_steps_per_mm[Y_AXIS]); + lv_label_set_text(labelYValue, public_buf_l); + lv_obj_align(labelYValue, buttonYValue, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), planner.settings.axis_steps_per_mm[Z_AXIS]); + lv_label_set_text(labelZValue, public_buf_l); + lv_obj_align(labelZValue, buttonZValue, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), planner.settings.axis_steps_per_mm[E_AXIS]); + lv_label_set_text(labelE0Value, public_buf_l); + lv_obj_align(labelE0Value, buttonE0Value, LV_ALIGN_CENTER, 0, 0); + } + else { + lv_label_set_text(labelTurnPage, machine_menu.previous); + lv_obj_align(labelTurnPage, buttonTurnPage, LV_ALIGN_CENTER, 0, 0); + + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), planner.settings.axis_steps_per_mm[E_AXIS_N(1)]); + lv_label_set_text(labelE1Value, public_buf_l); + lv_obj_align(labelE1Value, buttonE1Value, LV_ALIGN_CENTER, 0, 0); + } + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_CENTER, 0, 0); + } +} + +void lv_clear_step_settings() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_step_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_step_settings.h new file mode 100644 index 000000000000..b7eaeb4c61e3 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_step_settings.h @@ -0,0 +1,33 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_step_settings(void); +extern void lv_clear_step_settings(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_current_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_current_settings.cpp new file mode 100644 index 000000000000..10aa7badff7e --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_current_settings.cpp @@ -0,0 +1,387 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if BOTH(HAS_TFT_LVGL_UI, HAS_TRINAMIC_CONFIG) + +#include "lv_conf.h" +#include "draw_ui.h" + +#include "../../../../MarlinCore.h" +#include "../../../../module/planner.h" +#include "../../../../module/stepper/indirection.h" +#include "../../../../feature/tmc_util.h" + +extern lv_group_t * g; +static lv_obj_t * scr; + +#define ID_TMC_CURRENT_RETURN 1 +#define ID_TMC_CURRENT_X 2 +#define ID_TMC_CURRENT_Y 3 +#define ID_TMC_CURRENT_Z 4 +#define ID_TMC_CURRENT_E0 5 +#define ID_TMC_CURRENT_E1 6 +#define ID_TMC_CURRENT_DOWN 7 +#define ID_TMC_CURRENT_UP 8 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_TMC_CURRENT_RETURN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.para_ui_page = 0; + lv_clear_tmc_current_settings(); + draw_return_ui(); + } + break; + #if AXIS_IS_TMC(X) + case ID_TMC_CURRENT_X: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = Xcurrent; + lv_clear_tmc_current_settings(); + lv_draw_number_key(); + } + break; + #endif + + #if AXIS_IS_TMC(Y) + case ID_TMC_CURRENT_Y: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = Ycurrent; + lv_clear_tmc_current_settings(); + lv_draw_number_key(); + } + break; + #endif + + #if AXIS_IS_TMC(Z) + case ID_TMC_CURRENT_Z: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = Zcurrent; + lv_clear_tmc_current_settings(); + lv_draw_number_key(); + } + break; + #endif + + #if AXIS_IS_TMC(E0) + case ID_TMC_CURRENT_E0: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = E0current; + lv_clear_tmc_current_settings(); + lv_draw_number_key(); + } + break; + #endif + + #if AXIS_IS_TMC(E1) + case ID_TMC_CURRENT_E1: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + value = E1current; + lv_clear_tmc_current_settings(); + lv_draw_number_key(); + } + break; + #endif + case ID_TMC_CURRENT_UP: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.para_ui_page = 0; + lv_clear_tmc_current_settings(); + lv_draw_tmc_current_settings(); + } + break; + case ID_TMC_CURRENT_DOWN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.para_ui_page = 1; + lv_clear_tmc_current_settings(); + lv_draw_tmc_current_settings(); + } + break; + } +} + +void lv_draw_tmc_current_settings(void) { + lv_obj_t *buttonBack = NULL, *label_Back = NULL; + lv_obj_t *labelXText = NULL, *buttonXValue = NULL, *labelXValue = NULL; + lv_obj_t *labelYText = NULL, *buttonYValue = NULL, *labelYValue = NULL; + lv_obj_t *labelZText = NULL, *buttonZValue = NULL, *labelZValue = NULL; + lv_obj_t *labelE0Text = NULL, *buttonE0Value = NULL, *labelE0Value = NULL; + + lv_obj_t * line1 = NULL, * line2 = NULL, * line3 = NULL, * line4 = NULL; + //#if AXIS_IS_TMC(E1) + lv_obj_t *buttonTurnPage = NULL, *labelTurnPage = NULL; + lv_obj_t *labelE1Text = NULL, *buttonE1Value = NULL, *labelE1Value = NULL; + //#endif + float milliamps; + + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != TMC_CURRENT_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = TMC_CURRENT_UI; + } + disp_state = TMC_CURRENT_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, machine_menu.TmcCurrentConfTitle); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + if (uiCfg.para_ui_page != 1) { + labelXText = lv_label_create(scr, NULL); + lv_obj_set_style(labelXText, &tft_style_label_rel); + lv_obj_set_pos(labelXText, PARA_UI_POS_X, PARA_UI_POS_Y + 10); + lv_label_set_text(labelXText, machine_menu.X_Current); + + buttonXValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonXValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y + PARA_UI_VALUE_V); + lv_obj_set_size(buttonXValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonXValue, event_handler, ID_TMC_CURRENT_X, NULL, 0); + lv_btn_set_style(buttonXValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonXValue, LV_BTN_STYLE_PR, &style_para_value); + labelXValue = lv_label_create(buttonXValue, NULL); + + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1, line_points[0]); + + labelYText = lv_label_create(scr, NULL); + lv_obj_set_style(labelYText, &tft_style_label_rel); + lv_obj_set_pos(labelYText, PARA_UI_POS_X, PARA_UI_POS_Y * 2 + 10); + lv_label_set_text(labelYText, machine_menu.Y_Current); + + buttonYValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonYValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 2 + PARA_UI_VALUE_V); + lv_obj_set_size(buttonYValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonYValue, event_handler, ID_TMC_CURRENT_Y, NULL, 0); + lv_btn_set_style(buttonYValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonYValue, LV_BTN_STYLE_PR, &style_para_value); + labelYValue = lv_label_create(buttonYValue, NULL); + + line2 = lv_line_create(scr, NULL); + lv_ex_line(line2, line_points[1]); + + labelZText = lv_label_create(scr, NULL); + lv_obj_set_style(labelZText, &tft_style_label_rel); + lv_obj_set_pos(labelZText, PARA_UI_POS_X, PARA_UI_POS_Y * 3 + 10); + lv_label_set_text(labelZText, machine_menu.Z_Current); + + buttonZValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonZValue, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 3 + PARA_UI_VALUE_V); + lv_obj_set_size(buttonZValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonZValue, event_handler, ID_TMC_CURRENT_Z, NULL, 0); + lv_btn_set_style(buttonZValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonZValue, LV_BTN_STYLE_PR, &style_para_value); + labelZValue = lv_label_create(buttonZValue, NULL); + + line3 = lv_line_create(scr, NULL); + lv_ex_line(line3, line_points[2]); + + labelE0Text = lv_label_create(scr, NULL); + lv_obj_set_style(labelE0Text, &tft_style_label_rel); + lv_obj_set_pos(labelE0Text, PARA_UI_POS_X, PARA_UI_POS_Y * 4 + 10); + lv_label_set_text(labelE0Text, machine_menu.E0_Current); + + buttonE0Value = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonE0Value, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y * 4 + PARA_UI_VALUE_V); + lv_obj_set_size(buttonE0Value, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonE0Value, event_handler, ID_TMC_CURRENT_E0, NULL, 0); + lv_btn_set_style(buttonE0Value, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonE0Value, LV_BTN_STYLE_PR, &style_para_value); + labelE0Value = lv_label_create(buttonE0Value, NULL); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonXValue); + lv_group_add_obj(g, buttonYValue); + lv_group_add_obj(g, buttonZValue); + lv_group_add_obj(g, buttonE0Value); + } + #endif + + line4 = lv_line_create(scr, NULL); + lv_ex_line(line4, line_points[3]); + + //#if AXIS_IS_TMC(E1) + buttonTurnPage = lv_btn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonTurnPage, event_handler, ID_TMC_CURRENT_DOWN, NULL, 0); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_REL, &style_para_back); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_PR, &style_para_back); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonTurnPage); + #endif + //#endif + } + else { + //#if AXIS_IS_TMC(E1) + labelE1Text = lv_label_create(scr, NULL); + lv_obj_set_style(labelE1Text, &tft_style_label_rel); + lv_obj_set_pos(labelE1Text, PARA_UI_POS_X, PARA_UI_POS_Y + 10); + lv_label_set_text(labelE1Text, machine_menu.E1_Current); + + buttonE1Value = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonE1Value, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y + PARA_UI_VALUE_V); + lv_obj_set_size(buttonE1Value, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonE1Value, event_handler, ID_TMC_CURRENT_E1, NULL, 0); + lv_btn_set_style(buttonE1Value, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonE1Value, LV_BTN_STYLE_PR, &style_para_value); + labelE1Value = lv_label_create(buttonE1Value, NULL); + + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1, line_points[0]); + + buttonTurnPage = lv_btn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonTurnPage, event_handler, ID_TMC_CURRENT_UP, NULL, 0); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_REL, &style_para_back); + lv_btn_set_style(buttonTurnPage, LV_BTN_STYLE_PR, &style_para_back); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonE1Value); + lv_group_add_obj(g, buttonTurnPage); + } + #endif + //#endif + } + //#if AXIS_IS_TMC(E1) + lv_obj_set_pos(buttonTurnPage, PARA_UI_TURN_PAGE_POS_X, PARA_UI_TURN_PAGE_POS_Y); + lv_obj_set_size(buttonTurnPage, PARA_UI_BACK_BTN_X_SIZE, PARA_UI_BACK_BTN_Y_SIZE); + labelTurnPage = lv_label_create(buttonTurnPage, NULL); + //#endif + + buttonBack = lv_btn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_TMC_CURRENT_RETURN, NULL, 0); + lv_btn_set_style(buttonBack, LV_BTN_STYLE_REL, &style_para_back); + lv_btn_set_style(buttonBack, LV_BTN_STYLE_PR, &style_para_back); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonBack); + #endif + + lv_obj_set_pos(buttonBack, PARA_UI_BACL_POS_X, PARA_UI_BACL_POS_Y); + lv_obj_set_size(buttonBack, PARA_UI_BACK_BTN_X_SIZE, PARA_UI_BACK_BTN_Y_SIZE); + label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.multiple_language != 0) { + if (uiCfg.para_ui_page != 1) { + //#if AXIS_IS_TMC(E1) + lv_label_set_text(labelTurnPage, machine_menu.next); + lv_obj_align(labelTurnPage, buttonTurnPage, LV_ALIGN_CENTER, 0, 0); + //#endif + #if AXIS_IS_TMC(X) + milliamps = stepperX.getMilliamps(); + #else + milliamps = -1; + #endif + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), milliamps); + lv_label_set_text(labelXValue, public_buf_l); + lv_obj_align(labelXValue, buttonXValue, LV_ALIGN_CENTER, 0, 0); + + #if AXIS_IS_TMC(Y) + milliamps = stepperY.getMilliamps(); + #else + milliamps = -1; + #endif + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), milliamps); + lv_label_set_text(labelYValue, public_buf_l); + lv_obj_align(labelYValue, buttonYValue, LV_ALIGN_CENTER, 0, 0); + + #if AXIS_IS_TMC(Z) + milliamps = stepperZ.getMilliamps(); + #else + milliamps = -1; + #endif + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), milliamps); + lv_label_set_text(labelZValue, public_buf_l); + lv_obj_align(labelZValue, buttonZValue, LV_ALIGN_CENTER, 0, 0); + + #if AXIS_IS_TMC(E0) + milliamps = stepperE0.getMilliamps(); + #else + milliamps = -1; + #endif + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), milliamps); + lv_label_set_text(labelE0Value, public_buf_l); + lv_obj_align(labelE0Value, buttonE0Value, LV_ALIGN_CENTER, 0, 0); + } + else { + //#if AXIS_IS_TMC(E1) + lv_label_set_text(labelTurnPage, machine_menu.previous); + lv_obj_align(labelTurnPage, buttonTurnPage, LV_ALIGN_CENTER, 0, 0); + #if AXIS_IS_TMC(E1) + milliamps = stepperE1.getMilliamps(); + #else + milliamps = -1; + #endif + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("%.1f"), milliamps); + lv_label_set_text(labelE1Value, public_buf_l); + lv_obj_align(labelE1Value, buttonE1Value, LV_ALIGN_CENTER, 0, 0); + //#endif + } + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_CENTER, 0, 0); + } +} + +void lv_clear_tmc_current_settings() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI && HAS_TRINAMIC_CONFIG diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_current_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_current_settings.h new file mode 100644 index 000000000000..927db37138e6 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_current_settings.h @@ -0,0 +1,34 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_tmc_current_settings(void); +extern void lv_clear_tmc_current_settings(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif + diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_step_mode_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_step_mode_settings.cpp new file mode 100644 index 000000000000..3e014a781cf0 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_step_mode_settings.cpp @@ -0,0 +1,586 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if BOTH(HAS_TFT_LVGL_UI, HAS_STEALTHCHOP) + +#include "lv_conf.h" +#include "draw_ui.h" + +#include "../../../../MarlinCore.h" +#include "../../../../module/planner.h" +#include "../../../../module/stepper/indirection.h" +#include "../../../../feature/tmc_util.h" +#include "../../../../gcode/gcode.h" +#include "../../../../module/planner.h" + +extern lv_group_t * g; +static lv_obj_t * scr; + +#define ID_TMC_MODE_RETURN 1 +#define ID_TMC_MODE_X 2 +#define ID_TMC_MODE_Y 3 +#define ID_TMC_MODE_Z 4 +#define ID_TMC_MODE_E0 5 +#define ID_TMC_MODE_E1 6 +#define ID_TMC_MODE_DOWN 7 +#define ID_TMC_MODE_UP 8 + +static lv_obj_t *labelXState = NULL, *labelYState = NULL, *labelZState = NULL, *labelE0State = NULL; +static lv_obj_t *buttonXState = NULL, *buttonYState = NULL, *buttonZState = NULL, *buttonE0State = NULL; + +//#if AXIS_HAS_STEALTHCHOP(E1) + static lv_obj_t *labelE1State = NULL, *buttonE1State = NULL; +//#endif + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_TMC_MODE_RETURN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.para_ui_page = 0; + lv_clear_tmc_step_mode_settings(); + draw_return_ui(); + } + break; + + #if AXIS_HAS_STEALTHCHOP(X) + case ID_TMC_MODE_X: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (stepperX.stored.stealthChop_enabled) { + stepperX.stored.stealthChop_enabled = false; + stepperX.refresh_stepping_mode(); + lv_imgbtn_set_src(buttonXState, LV_BTN_STATE_REL, "F:/bmp_disable.bin"); + lv_imgbtn_set_src(buttonXState, LV_BTN_STATE_PR, "F:/bmp_disable.bin"); + lv_label_set_text(labelXState, machine_menu.disable); + //lv_obj_align(labelXState, buttonE1State, LV_ALIGN_IN_LEFT_MID,0, 0); + // gcode.process_subcommands_now_P(PSTR("M500")); + } + else { + stepperX.stored.stealthChop_enabled = true; + stepperX.refresh_stepping_mode(); + lv_imgbtn_set_src(buttonXState, LV_BTN_STATE_REL, "F:/bmp_enable.bin"); + lv_imgbtn_set_src(buttonXState, LV_BTN_STATE_PR, "F:/bmp_enable.bin"); + lv_label_set_text(labelXState, machine_menu.enable); + // gcode.process_subcommands_now_P(PSTR("M500")); + } + gcode.process_subcommands_now_P(PSTR("M500")); + } + break; + #endif // if AXIS_HAS_STEALTHCHOP(X) + + #if AXIS_HAS_STEALTHCHOP(Y) + case ID_TMC_MODE_Y: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (stepperY.stored.stealthChop_enabled) { + stepperY.stored.stealthChop_enabled = false; + stepperY.refresh_stepping_mode(); + lv_imgbtn_set_src(buttonYState, LV_BTN_STATE_REL, "F:/bmp_disable.bin"); + lv_imgbtn_set_src(buttonYState, LV_BTN_STATE_PR, "F:/bmp_disable.bin"); + lv_label_set_text(labelYState, machine_menu.disable); + //lv_obj_align(labelXState, buttonE1State, LV_ALIGN_IN_LEFT_MID,0, 0); + } + else { + stepperY.stored.stealthChop_enabled = true; + stepperY.refresh_stepping_mode(); + lv_imgbtn_set_src(buttonYState, LV_BTN_STATE_REL, "F:/bmp_enable.bin"); + lv_imgbtn_set_src(buttonYState, LV_BTN_STATE_PR, "F:/bmp_enable.bin"); + lv_label_set_text(labelYState, machine_menu.enable); + } + gcode.process_subcommands_now_P(PSTR("M500")); + } + break; + #endif // if AXIS_HAS_STEALTHCHOP(Y) + + #if AXIS_HAS_STEALTHCHOP(Z) + case ID_TMC_MODE_Z: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (stepperZ.stored.stealthChop_enabled) { + stepperZ.stored.stealthChop_enabled = false; + stepperZ.refresh_stepping_mode(); + lv_imgbtn_set_src(buttonZState, LV_BTN_STATE_REL, "F:/bmp_disable.bin"); + lv_imgbtn_set_src(buttonZState, LV_BTN_STATE_PR, "F:/bmp_disable.bin"); + lv_label_set_text(labelZState, machine_menu.disable); + //lv_obj_align(labelXState, buttonE1State, LV_ALIGN_IN_LEFT_MID,0, 0); + } + else { + stepperZ.stored.stealthChop_enabled = true; + stepperZ.refresh_stepping_mode(); + lv_imgbtn_set_src(buttonZState, LV_BTN_STATE_REL, "F:/bmp_enable.bin"); + lv_imgbtn_set_src(buttonZState, LV_BTN_STATE_PR, "F:/bmp_enable.bin"); + lv_label_set_text(labelZState, machine_menu.enable); + } + gcode.process_subcommands_now_P(PSTR("M500")); + } + break; + #endif // if AXIS_HAS_STEALTHCHOP(Z) + + #if AXIS_HAS_STEALTHCHOP(E0) + case ID_TMC_MODE_E0: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (stepperE0.stored.stealthChop_enabled) { + stepperE0.stored.stealthChop_enabled = false; + stepperE0.refresh_stepping_mode(); + lv_imgbtn_set_src(buttonE0State, LV_BTN_STATE_REL, "F:/bmp_disable.bin"); + lv_imgbtn_set_src(buttonE0State, LV_BTN_STATE_PR, "F:/bmp_disable.bin"); + lv_label_set_text(labelE0State, machine_menu.disable); + //lv_obj_align(labelXState, buttonE1State, LV_ALIGN_IN_LEFT_MID,0, 0); + } + else { + stepperE0.stored.stealthChop_enabled = true; + stepperE0.refresh_stepping_mode(); + lv_imgbtn_set_src(buttonE0State, LV_BTN_STATE_REL, "F:/bmp_enable.bin"); + lv_imgbtn_set_src(buttonE0State, LV_BTN_STATE_PR, "F:/bmp_enable.bin"); + lv_label_set_text(labelE0State, machine_menu.enable); + } + gcode.process_subcommands_now_P(PSTR("M500")); + } + break; + #endif // if AXIS_HAS_STEALTHCHOP(E0) + + #if AXIS_HAS_STEALTHCHOP(E1) + case ID_TMC_MODE_E1: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (stepperE1.stored.stealthChop_enabled) { + stepperE1.stored.stealthChop_enabled = false; + stepperE1.refresh_stepping_mode(); + lv_imgbtn_set_src(buttonE1State, LV_BTN_STATE_REL, "F:/bmp_disable.bin"); + lv_imgbtn_set_src(buttonE1State, LV_BTN_STATE_PR, "F:/bmp_disable.bin"); + lv_label_set_text(labelE1State, machine_menu.disable); + //lv_obj_align(labelXState, buttonE1State, LV_ALIGN_IN_LEFT_MID,0, 0); + } + else { + stepperE1.stored.stealthChop_enabled = true; + stepperE1.refresh_stepping_mode(); + lv_imgbtn_set_src(buttonE1State, LV_BTN_STATE_REL, "F:/bmp_enable.bin"); + lv_imgbtn_set_src(buttonE1State, LV_BTN_STATE_PR, "F:/bmp_enable.bin"); + lv_label_set_text(labelE1State, machine_menu.enable); + } + gcode.process_subcommands_now_P(PSTR("M500")); + } + break; + #endif // if AXIS_HAS_STEALTHCHOP(E1) + case ID_TMC_MODE_UP: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.para_ui_page = 0; + lv_clear_tmc_step_mode_settings(); + lv_draw_tmc_step_mode_settings(); + } + break; + case ID_TMC_MODE_DOWN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.para_ui_page = 1; + lv_clear_tmc_step_mode_settings(); + lv_draw_tmc_step_mode_settings(); + } + break; + } +} + +void lv_draw_tmc_step_mode_settings(void) { + lv_obj_t *buttonBack = NULL, *label_Back = NULL; + lv_obj_t *buttonXText = NULL, *labelXText = NULL; + lv_obj_t *buttonYText = NULL, *labelYText = NULL; + lv_obj_t *buttonZText = NULL, *labelZText = NULL; + lv_obj_t *buttonE0Text = NULL, *labelE0Text = NULL; + + lv_obj_t * line1 = NULL, * line2 = NULL, * line3 = NULL, * line4 = NULL; + //#if AXIS_HAS_STEALTHCHOP(E1) + lv_obj_t *buttonTurnPage = NULL, *labelTurnPage = NULL; + lv_obj_t *buttonE1Text = NULL, *labelE1Text = NULL; + //#endif + + + labelXState = NULL; + buttonXState = NULL; + labelYState = NULL; + buttonYState = NULL; + labelZState = NULL; + buttonZState = NULL; + labelE0State = NULL; + buttonE0State = NULL; + //#if AXIS_HAS_STEALTHCHOP(E1) + labelE1State = NULL; + buttonE1State = NULL; + //#endif + + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != TMC_MODE_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = TMC_MODE_UI; + } + disp_state = TMC_MODE_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, machine_menu.TmcStepModeConfTitle); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + if (uiCfg.para_ui_page != 1) { + buttonXText = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(buttonXText, PARA_UI_POS_X, PARA_UI_POS_Y); /*Set its position*/ + lv_obj_set_size(buttonXText, PARA_UI_VALUE_SIZE_X, PARA_UI_SIZE_Y); /*Set its size*/ + lv_obj_set_event_cb(buttonXText, event_handler); + lv_btn_set_style(buttonXText, LV_BTN_STYLE_REL, &tft_style_label_rel); /*Set the button's released style*/ + lv_btn_set_style(buttonXText, LV_BTN_STYLE_PR, &tft_style_label_pre); /*Set the button's pressed style*/ + lv_btn_set_layout(buttonXText, LV_LAYOUT_OFF); + labelXText = lv_label_create(buttonXText, NULL); /*Add a label to the button*/ + + buttonXState = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonXState, PARA_UI_STATE_POS_X, PARA_UI_POS_Y + PARA_UI_STATE_V); + #if AXIS_HAS_STEALTHCHOP(X) + if (stepperX.get_stealthChop_status()) { + lv_imgbtn_set_src(buttonXState, LV_BTN_STATE_REL, "F:/bmp_enable.bin"); + lv_imgbtn_set_src(buttonXState, LV_BTN_STATE_PR, "F:/bmp_enable.bin"); + } + else { + lv_imgbtn_set_src(buttonXState, LV_BTN_STATE_REL, "F:/bmp_disable.bin"); + lv_imgbtn_set_src(buttonXState, LV_BTN_STATE_PR, "F:/bmp_disable.bin"); + } + #else + lv_imgbtn_set_src(buttonXState, LV_BTN_STATE_REL, "F:/bmp_disable.bin"); + lv_imgbtn_set_src(buttonXState, LV_BTN_STATE_PR, "F:/bmp_disable.bin"); + #endif + lv_obj_set_event_cb_mks(buttonXState, event_handler, ID_TMC_MODE_X, NULL, 0); + + lv_imgbtn_set_style(buttonXState, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonXState, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonXState, LV_LAYOUT_OFF); + labelXState = lv_label_create(buttonXState, NULL); + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonXState); + #endif + + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1, line_points[0]); + + buttonYText = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(buttonYText, PARA_UI_POS_X, PARA_UI_POS_Y * 2); /*Set its position*/ + lv_obj_set_size(buttonYText, PARA_UI_VALUE_SIZE_X, PARA_UI_SIZE_Y); /*Set its size*/ + lv_obj_set_event_cb(buttonYText, event_handler); + lv_btn_set_style(buttonYText, LV_BTN_STYLE_REL, &tft_style_label_rel); /*Set the button's released style*/ + lv_btn_set_style(buttonYText, LV_BTN_STYLE_PR, &tft_style_label_pre); /*Set the button's pressed style*/ + lv_btn_set_layout(buttonYText, LV_LAYOUT_OFF); + labelYText = lv_label_create(buttonYText, NULL); /*Add a label to the button*/ + + buttonYState = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonYState, PARA_UI_STATE_POS_X, PARA_UI_POS_Y * 2 + PARA_UI_STATE_V); + #if AXIS_HAS_STEALTHCHOP(Y) + if (stepperY.get_stealthChop_status()) { + lv_imgbtn_set_src(buttonYState, LV_BTN_STATE_REL, "F:/bmp_enable.bin"); + lv_imgbtn_set_src(buttonYState, LV_BTN_STATE_PR, "F:/bmp_enable.bin"); + } + else { + lv_imgbtn_set_src(buttonYState, LV_BTN_STATE_REL, "F:/bmp_disable.bin"); + lv_imgbtn_set_src(buttonYState, LV_BTN_STATE_PR, "F:/bmp_disable.bin"); + } + #else + lv_imgbtn_set_src(buttonYState, LV_BTN_STATE_REL, "F:/bmp_disable.bin"); + lv_imgbtn_set_src(buttonYState, LV_BTN_STATE_PR, "F:/bmp_disable.bin"); + #endif + lv_obj_set_event_cb_mks(buttonYState, event_handler, ID_TMC_MODE_Y, NULL, 0); + + lv_imgbtn_set_style(buttonYState, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonYState, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonYState, LV_LAYOUT_OFF); + labelYState = lv_label_create(buttonYState, NULL); + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonYState); + #endif + + line2 = lv_line_create(scr, NULL); + lv_ex_line(line2, line_points[1]); + + buttonZText = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(buttonZText, PARA_UI_POS_X, PARA_UI_POS_Y * 3); /*Set its position*/ + lv_obj_set_size(buttonZText, PARA_UI_VALUE_SIZE_X, PARA_UI_SIZE_Y); /*Set its size*/ + lv_obj_set_event_cb(buttonZText, event_handler); + lv_btn_set_style(buttonZText, LV_BTN_STYLE_REL, &tft_style_label_rel); /*Set the button's released style*/ + lv_btn_set_style(buttonZText, LV_BTN_STYLE_PR, &tft_style_label_pre); /*Set the button's pressed style*/ + lv_btn_set_layout(buttonZText, LV_LAYOUT_OFF); + labelZText = lv_label_create(buttonZText, NULL); /*Add a label to the button*/ + + buttonZState = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonZState, PARA_UI_STATE_POS_X, PARA_UI_POS_Y * 3 + PARA_UI_STATE_V); + #if AXIS_HAS_STEALTHCHOP(Z) + if (stepperZ.get_stealthChop_status()) { + lv_imgbtn_set_src(buttonZState, LV_BTN_STATE_REL, "F:/bmp_enable.bin"); + lv_imgbtn_set_src(buttonZState, LV_BTN_STATE_PR, "F:/bmp_enable.bin"); + } + else { + lv_imgbtn_set_src(buttonZState, LV_BTN_STATE_REL, "F:/bmp_disable.bin"); + lv_imgbtn_set_src(buttonZState, LV_BTN_STATE_PR, "F:/bmp_disable.bin"); + } + #else + lv_imgbtn_set_src(buttonZState, LV_BTN_STATE_REL, "F:/bmp_disable.bin"); + lv_imgbtn_set_src(buttonZState, LV_BTN_STATE_PR, "F:/bmp_disable.bin"); + #endif + lv_obj_set_event_cb_mks(buttonZState, event_handler, ID_TMC_MODE_Z, NULL, 0); + lv_imgbtn_set_style(buttonZState, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonZState, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonZState, LV_LAYOUT_OFF); + labelZState = lv_label_create(buttonZState, NULL); + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonZState); + #endif + + line3 = lv_line_create(scr, NULL); + lv_ex_line(line3, line_points[2]); + + buttonE0Text = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(buttonE0Text, PARA_UI_POS_X, PARA_UI_POS_Y * 4); /*Set its position*/ + lv_obj_set_size(buttonE0Text, PARA_UI_VALUE_SIZE_X, PARA_UI_SIZE_Y); /*Set its size*/ + lv_obj_set_event_cb(buttonE0Text, event_handler); + lv_btn_set_style(buttonE0Text, LV_BTN_STYLE_REL, &tft_style_label_rel); /*Set the button's released style*/ + lv_btn_set_style(buttonE0Text, LV_BTN_STYLE_PR, &tft_style_label_pre); /*Set the button's pressed style*/ + lv_btn_set_layout(buttonE0Text, LV_LAYOUT_OFF); + labelE0Text = lv_label_create(buttonE0Text, NULL); /*Add a label to the button*/ + + buttonE0State = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonE0State, PARA_UI_STATE_POS_X, PARA_UI_POS_Y * 4 + PARA_UI_STATE_V); + #if AXIS_HAS_STEALTHCHOP(E0) + if (stepperE0.get_stealthChop_status()) { + lv_imgbtn_set_src(buttonE0State, LV_BTN_STATE_REL, "F:/bmp_enable.bin"); + lv_imgbtn_set_src(buttonE0State, LV_BTN_STATE_PR, "F:/bmp_enable.bin"); + } + else { + lv_imgbtn_set_src(buttonE0State, LV_BTN_STATE_REL, "F:/bmp_disable.bin"); + lv_imgbtn_set_src(buttonE0State, LV_BTN_STATE_PR, "F:/bmp_disable.bin"); + } + #else + lv_imgbtn_set_src(buttonE0State, LV_BTN_STATE_REL, "F:/bmp_disable.bin"); + lv_imgbtn_set_src(buttonE0State, LV_BTN_STATE_PR, "F:/bmp_disable.bin"); + #endif + + lv_obj_set_event_cb_mks(buttonE0State, event_handler, ID_TMC_MODE_E0, NULL, 0); + + lv_imgbtn_set_style(buttonE0State, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonE0State, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonE0State, LV_LAYOUT_OFF); + labelE0State = lv_label_create(buttonE0State, NULL); + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonE0State); + #endif + + + line4 = lv_line_create(scr, NULL); + lv_ex_line(line4, line_points[3]); + + //#if AXIS_HAS_STEALTHCHOP(E1) + buttonTurnPage = lv_imgbtn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonTurnPage, event_handler, ID_TMC_MODE_DOWN, NULL, 0); + lv_imgbtn_set_src(buttonTurnPage, LV_BTN_STATE_REL, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_src(buttonTurnPage, LV_BTN_STATE_PR, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_style(buttonTurnPage, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonTurnPage, LV_BTN_STATE_REL, &tft_style_label_rel); + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonTurnPage); + #endif + //#endif + } + else { + //#if AXIS_HAS_STEALTHCHOP(E1) + buttonE1Text = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(buttonE1Text, PARA_UI_POS_X, PARA_UI_POS_Y); /*Set its position*/ + lv_obj_set_size(buttonE1Text, PARA_UI_VALUE_SIZE_X, PARA_UI_SIZE_Y); /*Set its size*/ + lv_obj_set_event_cb(buttonE1Text, event_handler); + lv_btn_set_style(buttonE1Text, LV_BTN_STYLE_REL, &tft_style_label_rel); /*Set the button's released style*/ + lv_btn_set_style(buttonE1Text, LV_BTN_STYLE_PR, &tft_style_label_pre); /*Set the button's pressed style*/ + lv_btn_set_layout(buttonE1Text, LV_LAYOUT_OFF); + labelE1Text = lv_label_create(buttonE1Text, NULL); /*Add a label to the button*/ + + buttonE1State = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonE1State, PARA_UI_STATE_POS_X, PARA_UI_POS_Y + PARA_UI_STATE_V); + #if AXIS_HAS_STEALTHCHOP(E1) + if (stepperE1.get_stealthChop_status()) { + lv_imgbtn_set_src(buttonE1State, LV_BTN_STATE_REL, "F:/bmp_enable.bin"); + lv_imgbtn_set_src(buttonE1State, LV_BTN_STATE_PR, "F:/bmp_enable.bin"); + } + else { + lv_imgbtn_set_src(buttonE1State, LV_BTN_STATE_REL, "F:/bmp_disable.bin"); + lv_imgbtn_set_src(buttonE1State, LV_BTN_STATE_PR, "F:/bmp_disable.bin"); + } + #else + lv_imgbtn_set_src(buttonE1State, LV_BTN_STATE_REL, "F:/bmp_disable.bin"); + lv_imgbtn_set_src(buttonE1State, LV_BTN_STATE_PR, "F:/bmp_disable.bin"); + #endif + lv_obj_set_event_cb_mks(buttonE1State, event_handler, ID_TMC_MODE_E1, NULL, 0); + lv_imgbtn_set_style(buttonE1State, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonE1State, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonE1State, LV_LAYOUT_OFF); + labelE1State = lv_label_create(buttonE1State, NULL); + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonE1State); + #endif + + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1, line_points[0]); + + buttonTurnPage = lv_imgbtn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonTurnPage, event_handler, ID_TMC_MODE_UP, NULL, 0); + lv_imgbtn_set_src(buttonTurnPage, LV_BTN_STATE_REL, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_src(buttonTurnPage, LV_BTN_STATE_PR, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_style(buttonTurnPage, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonTurnPage, LV_BTN_STATE_REL, &tft_style_label_rel); + //#endif + } + //#if AXIS_HAS_STEALTHCHOP(E1) + lv_obj_set_pos(buttonTurnPage, PARA_UI_TURN_PAGE_POS_X, PARA_UI_TURN_PAGE_POS_Y); + lv_btn_set_layout(buttonTurnPage, LV_LAYOUT_OFF); + labelTurnPage = lv_label_create(buttonTurnPage, NULL); + //#endif + + buttonBack = lv_imgbtn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_TMC_MODE_RETURN, NULL, 0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonBack); + #endif + + lv_obj_set_pos(buttonBack, PARA_UI_BACL_POS_X, PARA_UI_BACL_POS_Y); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.multiple_language != 0) { + if (uiCfg.para_ui_page != 1) { + lv_label_set_text(labelXText, machine_menu.X_StepMode); + lv_obj_align(labelXText, buttonXText, LV_ALIGN_IN_LEFT_MID, 0, 0); + + lv_label_set_text(labelYText, machine_menu.Y_StepMode); + lv_obj_align(labelYText, buttonYText, LV_ALIGN_IN_LEFT_MID, 0, 0); + + lv_label_set_text(labelZText, machine_menu.Z_StepMode); + lv_obj_align(labelZText, buttonZText, LV_ALIGN_IN_LEFT_MID, 0, 0); + + lv_label_set_text(labelE0Text, machine_menu.E0_StepMode); + lv_obj_align(labelE0Text, buttonE0Text, LV_ALIGN_IN_LEFT_MID, 0, 0); + + #if AXIS_HAS_STEALTHCHOP(X) + if (stepperX.get_stealthChop_status()) + lv_label_set_text(labelXState, machine_menu.enable); + else + lv_label_set_text(labelXState, machine_menu.disable); + #else + lv_label_set_text(labelXState, machine_menu.disable); + #endif + lv_obj_align(labelXState, buttonXState, LV_ALIGN_CENTER, 0, 0); + + #if AXIS_HAS_STEALTHCHOP(Y) + if (stepperY.get_stealthChop_status()) + lv_label_set_text(labelYState, machine_menu.enable); + else + lv_label_set_text(labelYState, machine_menu.disable); + #else + lv_label_set_text(labelYState, machine_menu.disable); + #endif + lv_obj_align(labelYState, buttonYState, LV_ALIGN_CENTER, 0, 0); + + #if AXIS_HAS_STEALTHCHOP(Z) + if (stepperZ.get_stealthChop_status()) + lv_label_set_text(labelZState, machine_menu.enable); + else + lv_label_set_text(labelZState, machine_menu.disable); + #else + lv_label_set_text(labelZState, machine_menu.disable); + #endif + lv_obj_align(labelZState, buttonZState, LV_ALIGN_CENTER, 0, 0); + + #if AXIS_HAS_STEALTHCHOP(E0) + if (stepperE0.get_stealthChop_status()) + lv_label_set_text(labelE0State, machine_menu.enable); + else + lv_label_set_text(labelE0State, machine_menu.disable); + #else + lv_label_set_text(labelE0State, machine_menu.disable); + #endif + lv_obj_align(labelE0State, buttonE0State, LV_ALIGN_CENTER, 0, 0); + + //#if AXIS_HAS_STEALTHCHOP(E1) + lv_label_set_text(labelTurnPage, machine_menu.next); + lv_obj_align(labelTurnPage, buttonTurnPage, LV_ALIGN_CENTER, 0, 0); + //#endif + } + else { + //#if AXIS_HAS_STEALTHCHOP(E1) + lv_label_set_text(labelE1Text, machine_menu.E1_StepMode); + lv_obj_align(labelE1Text, buttonE1Text, LV_ALIGN_IN_LEFT_MID, 0, 0); + #if AXIS_HAS_STEALTHCHOP(E1) + if (stepperE1.get_stealthChop_status()) + lv_label_set_text(labelE1State, machine_menu.enable); + else + lv_label_set_text(labelE1State, machine_menu.disable); + #else + lv_label_set_text(labelE1State, machine_menu.disable); + #endif + lv_obj_align(labelE1State, buttonE1State, LV_ALIGN_CENTER, 0, 0); + + lv_label_set_text(labelTurnPage, machine_menu.previous); + lv_obj_align(labelTurnPage, buttonTurnPage, LV_ALIGN_CENTER, 0, 0); + //#endif + } + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_CENTER, 0, 0); + } +} + +void lv_clear_tmc_step_mode_settings() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI && HAS_STEALTHCHOP diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_step_mode_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_step_mode_settings.h new file mode 100644 index 000000000000..35c57ab0cc01 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_step_mode_settings.h @@ -0,0 +1,33 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_tmc_step_mode_settings(void); +extern void lv_clear_tmc_step_mode_settings(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_tool.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_tool.cpp new file mode 100644 index 000000000000..3681b1b2d601 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_tool.cpp @@ -0,0 +1,284 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" +//#include "../lvgl/src/lv_objx/lv_imgbtn.h" +//#include "../lvgl/src/lv_objx/lv_img.h" +//#include "../lvgl/src/lv_core/lv_disp.h" +//#include "../lvgl/src/lv_core/lv_refr.h" + +#include "../../../../MarlinCore.h" +#include "../../../../gcode/queue.h" +#include "../../../../module/temperature.h" + +extern lv_group_t * g; +static lv_obj_t * scr; + +#define ID_T_PRE_HEAT 1 +#define ID_T_EXTRUCT 2 +#define ID_T_MOV 3 +#define ID_T_HOME 4 +#define ID_T_LEVELING 5 +#define ID_T_FILAMENT 6 +#define ID_T_MORE 7 +#define ID_T_RETURN 8 + +#if ENABLED(MKS_TEST) + extern uint8_t curent_disp_ui; +#endif + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_T_PRE_HEAT: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_tool(); + lv_draw_preHeat(); + } + break; + case ID_T_EXTRUCT: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_tool(); + lv_draw_extrusion(); + } + break; + case ID_T_MOV: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_tool(); + lv_draw_move_motor(); + } + break; + case ID_T_HOME: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_tool(); + lv_draw_home(); + } + break; + case ID_T_LEVELING: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + //queue.enqueue_one_P(PSTR("G28")); + //queue.enqueue_one_P(PSTR("G29")); + get_gcode_command(AUTO_LEVELING_COMMAND_ADDR,(uint8_t *)public_buf_m); + public_buf_m[sizeof(public_buf_m)-1] = 0; + queue.inject_P(PSTR(public_buf_m)); + #else + uiCfg.leveling_first_time = 1; + lv_clear_tool(); + lv_draw_manualLevel(); + #endif + } + break; + case ID_T_FILAMENT: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + uiCfg.desireSprayerTempBak = thermalManager.temp_hotend[uiCfg.curSprayerChoose].target; + lv_clear_tool(); + lv_draw_filament_change(); + } + break; + case ID_T_MORE: break; + case ID_T_RETURN: + if (event == LV_EVENT_CLICKED) { + // nothing to do + } + else if (event == LV_EVENT_RELEASED) { + TERN_(MKS_TEST, curent_disp_ui = 1); + lv_clear_tool(); + lv_draw_ready_print(); + } + break; + } +} + +void lv_draw_tool(void) { + lv_obj_t *buttonPreHeat, *buttonExtrusion, *buttonMove, *buttonHome, *buttonLevel; + lv_obj_t *buttonFilament; + lv_obj_t *buttonBack; + + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != TOOL_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = TOOL_UI; + } + disp_state = TOOL_UI; + + scr = lv_obj_create(NULL, NULL); + + //static lv_style_t tool_style; + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title, TITLE_XPOS, TITLE_YPOS); + lv_label_set_text(title, creat_title_text()); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + // Create image buttons + buttonPreHeat = lv_imgbtn_create(scr, NULL); + buttonExtrusion = lv_imgbtn_create(scr, NULL); + buttonMove = lv_imgbtn_create(scr, NULL); + buttonHome = lv_imgbtn_create(scr, NULL); + buttonLevel = lv_imgbtn_create(scr, NULL); + buttonFilament = lv_imgbtn_create(scr, NULL); + //buttonMore = lv_imgbtn_create(scr, NULL); + buttonBack = lv_imgbtn_create(scr, NULL); + + lv_obj_set_event_cb_mks(buttonPreHeat, event_handler, ID_T_PRE_HEAT, NULL, 0); + lv_imgbtn_set_src(buttonPreHeat, LV_BTN_STATE_REL, "F:/bmp_preHeat.bin"); + lv_imgbtn_set_src(buttonPreHeat, LV_BTN_STATE_PR, "F:/bmp_preHeat.bin"); + lv_imgbtn_set_style(buttonPreHeat, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonPreHeat, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonExtrusion, event_handler, ID_T_EXTRUCT, NULL, 0); + lv_imgbtn_set_src(buttonExtrusion, LV_BTN_STATE_REL, "F:/bmp_extruct.bin"); + lv_imgbtn_set_src(buttonExtrusion, LV_BTN_STATE_PR, "F:/bmp_extruct.bin"); + lv_imgbtn_set_style(buttonExtrusion, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonExtrusion, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonMove, event_handler, ID_T_MOV, NULL, 0); + lv_imgbtn_set_src(buttonMove, LV_BTN_STATE_REL, "F:/bmp_mov.bin"); + lv_imgbtn_set_src(buttonMove, LV_BTN_STATE_PR, "F:/bmp_mov.bin"); + lv_imgbtn_set_style(buttonMove, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonMove, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonHome, event_handler, ID_T_HOME, NULL, 0); + lv_imgbtn_set_src(buttonHome, LV_BTN_STATE_REL, "F:/bmp_zero.bin"); + lv_imgbtn_set_src(buttonHome, LV_BTN_STATE_PR, "F:/bmp_zero.bin"); + lv_imgbtn_set_style(buttonHome, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonHome, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonLevel, event_handler, ID_T_LEVELING, NULL, 0); + lv_imgbtn_set_src(buttonLevel, LV_BTN_STATE_REL, "F:/bmp_leveling.bin"); + lv_imgbtn_set_src(buttonLevel, LV_BTN_STATE_PR, "F:/bmp_leveling.bin"); + lv_imgbtn_set_style(buttonLevel, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonLevel, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonFilament, event_handler,ID_T_FILAMENT,NULL,0); + lv_imgbtn_set_src(buttonFilament, LV_BTN_STATE_REL, "F:/bmp_filamentchange.bin"); + lv_imgbtn_set_src(buttonFilament, LV_BTN_STATE_PR, "F:/bmp_filamentchange.bin"); + lv_imgbtn_set_style(buttonFilament, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonFilament, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_T_RETURN, NULL, 0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_return.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_return.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_pos(buttonPreHeat, INTERVAL_V, titleHeight); + lv_obj_set_pos(buttonExtrusion, BTN_X_PIXEL + INTERVAL_V * 2, titleHeight); + lv_obj_set_pos(buttonMove, BTN_X_PIXEL * 2 + INTERVAL_V * 3, titleHeight); + lv_obj_set_pos(buttonHome, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight); + lv_obj_set_pos(buttonLevel, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + lv_obj_set_pos(buttonFilament,BTN_X_PIXEL+INTERVAL_V*2,BTN_Y_PIXEL+INTERVAL_H+titleHeight); + //lv_obj_set_pos(buttonMore,BTN_X_PIXEL*2+INTERVAL_V*3, BTN_Y_PIXEL+INTERVAL_H+titleHeight); + lv_obj_set_pos(buttonBack, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight); + + // Create labels on the image buttons + lv_btn_set_layout(buttonPreHeat, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonExtrusion, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonMove, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonHome, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonLevel, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonFilament, LV_LAYOUT_OFF); + //lv_btn_set_layout(buttonMore, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + + lv_obj_t *labelPreHeat = lv_label_create(buttonPreHeat, NULL); + lv_obj_t *labelExtrusion = lv_label_create(buttonExtrusion, NULL); + lv_obj_t *label_Move = lv_label_create(buttonMove, NULL); + lv_obj_t *label_Home = lv_label_create(buttonHome, NULL); + lv_obj_t *label_Level = lv_label_create(buttonLevel, NULL); + lv_obj_t *label_Filament = lv_label_create(buttonFilament, NULL); + //lv_obj_t *label_More = lv_label_create(buttonMore, NULL); + lv_obj_t *label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.multiple_language != 0) { + lv_label_set_text(labelPreHeat, tool_menu.preheat); + lv_obj_align(labelPreHeat, buttonPreHeat, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(labelExtrusion, tool_menu.extrude); + lv_obj_align(labelExtrusion, buttonExtrusion, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Move, tool_menu.move); + lv_obj_align(label_Move, buttonMove, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Home, tool_menu.home); + lv_obj_align(label_Home, buttonHome, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Level, tool_menu.TERN(AUTO_BED_LEVELING_BILINEAR, autoleveling, leveling)); + lv_obj_align(label_Level, buttonLevel, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Filament, tool_menu.filament); + lv_obj_align(label_Filament, buttonFilament, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + //lv_label_set_text(label_More, tool_menu.more); + //lv_obj_align(label_More, buttonMore, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET); + } + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonPreHeat); + lv_group_add_obj(g, buttonExtrusion); + lv_group_add_obj(g, buttonMove); + lv_group_add_obj(g, buttonHome); + lv_group_add_obj(g, buttonLevel); + lv_group_add_obj(g, buttonFilament); + lv_group_add_obj(g, buttonBack); + } + #endif +} + +void lv_clear_tool() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_tool.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_tool.h new file mode 100644 index 000000000000..8a033e2c40b9 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_tool.h @@ -0,0 +1,34 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_tool(void); +extern void lv_clear_tool(); + +//extern void disp_temp_ready_print(); +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_ui.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_ui.cpp new file mode 100644 index 000000000000..d600b09a5f16 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_ui.cpp @@ -0,0 +1,1631 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "SPI_TFT.h" + +#include "tft_lvgl_configuration.h" + +#include "pic_manager.h" + +#include "draw_ui.h" +#include "mks_hardware_test.h" + +#include + +#include "../../../../MarlinCore.h" +#include "../../../../sd/cardreader.h" +#include "../../../../module/motion.h" +#include "../../../../module/planner.h" + +#if ENABLED(POWER_LOSS_RECOVERY) + #include "../../../../feature/powerloss.h" +#endif + +#if ENABLED(PARK_HEAD_ON_PAUSE) + #include "../../../../feature/pause.h" +#endif + +CFG_ITMES gCfgItems; +UI_CFG uiCfg; +DISP_STATE_STACK disp_state_stack; +DISP_STATE disp_state = MAIN_UI; +DISP_STATE last_disp_state; +PRINT_TIME print_time; +num_key_value_state value; +keyboard_value_state keyboard_value; + +uint32_t To_pre_view; +uint8_t gcode_preview_over; +uint8_t flash_preview_begin; +uint8_t default_preview_flg; +uint32_t size = 809; +uint16_t row; +uint8_t temperature_change_frequency; +uint8_t printing_rate_update_flag; + +extern uint8_t once_flag; +extern uint8_t sel_id; +extern uint8_t public_buf[512]; +extern uint8_t bmp_public_buf[17 * 1024]; + +extern void LCD_IO_WriteData(uint16_t RegValue); + +static const char custom_gcode_command[][100] = { + "G28\nG29\nM500", + "G28", + "G28", + "G28", + "G28" +}; + +lv_point_t line_points[4][2] = { + {{PARA_UI_POS_X, PARA_UI_POS_Y + PARA_UI_SIZE_Y}, {TFT_WIDTH, PARA_UI_POS_Y + PARA_UI_SIZE_Y}}, + {{PARA_UI_POS_X, PARA_UI_POS_Y*2 + PARA_UI_SIZE_Y}, {TFT_WIDTH, PARA_UI_POS_Y*2 + PARA_UI_SIZE_Y}}, + {{PARA_UI_POS_X, PARA_UI_POS_Y*3 + PARA_UI_SIZE_Y}, {TFT_WIDTH, PARA_UI_POS_Y*3 + PARA_UI_SIZE_Y}}, + {{PARA_UI_POS_X, PARA_UI_POS_Y*4 + PARA_UI_SIZE_Y}, {TFT_WIDTH, PARA_UI_POS_Y*4 + PARA_UI_SIZE_Y}} +}; +void gCfgItems_init() { + gCfgItems.multiple_language = MULTI_LANGUAGE_ENABLE; + #if 1 // LCD_LANGUAGE == en + gCfgItems.language = LANG_ENGLISH; + #elif LCD_LANGUAGE == zh_CN + gCfgItems.language = LANG_SIMPLE_CHINESE; + #elif LCD_LANGUAGE == zh_TW + gCfgItems.language = LANG_COMPLEX_CHINESE; + #elif LCD_LANGUAGE == jp_kana + gCfgItems.language = LANG_JAPAN; + #elif LCD_LANGUAGE == de + gCfgItems.language = LANG_GERMAN; + #elif LCD_LANGUAGE == fr + gCfgItems.language = LANG_FRENCH; + #elif LCD_LANGUAGE == ru + gCfgItems.language = LANG_RUSSIAN; + #elif LCD_LANGUAGE == ko_KR + gCfgItems.language = LANG_KOREAN; + #elif LCD_LANGUAGE == tr + gCfgItems.language = LANG_TURKISH; + #elif LCD_LANGUAGE == es + gCfgItems.language = LANG_SPANISH; + #elif LCD_LANGUAGE == el + gCfgItems.language = LANG_GREEK; + #elif LCD_LANGUAGE == it + gCfgItems.language = LANG_ITALY; + #elif LCD_LANGUAGE == pt + gCfgItems.language = LANG_PORTUGUESE; + #endif + gCfgItems.leveling_mode = 0; + gCfgItems.from_flash_pic = 0; + gCfgItems.curFilesize = 0; + gCfgItems.finish_power_off = 0; + gCfgItems.pause_reprint = 0; + gCfgItems.pausePosX = -1; + gCfgItems.pausePosY = -1; + gCfgItems.pausePosZ = 5; + gCfgItems.levelingPos[0][0] = X_MIN_POS + 30; + gCfgItems.levelingPos[0][1] = Y_MIN_POS + 30; + gCfgItems.levelingPos[1][0] = X_MAX_POS - 30; + gCfgItems.levelingPos[1][1] = Y_MIN_POS + 30; + gCfgItems.levelingPos[2][0] = X_MAX_POS - 30; + gCfgItems.levelingPos[2][1] = Y_MAX_POS - 30; + gCfgItems.levelingPos[3][0] = X_MIN_POS + 30; + gCfgItems.levelingPos[3][1] = Y_MAX_POS - 30; + gCfgItems.levelingPos[4][0] = X_BED_SIZE / 2; + gCfgItems.levelingPos[4][1] = Y_BED_SIZE / 2; + gCfgItems.cloud_enable = true; + #if ENABLED(USE_WIFI_FUNCTION) + gCfgItems.wifi_mode_sel = STA_MODEL; + gCfgItems.fileSysType = FILE_SYS_SD; + gCfgItems.wifi_type = ESP_WIFI; + #endif + gCfgItems.filamentchange_load_length = 200; + gCfgItems.filamentchange_load_speed = 1000; + gCfgItems.filamentchange_unload_length = 200; + gCfgItems.filamentchange_unload_speed = 1000; + gCfgItems.filament_limit_temper = 200; + + gCfgItems.encoder_enable = true; + + W25QXX.SPI_FLASH_BufferRead((uint8_t *)&gCfgItems.spi_flash_flag, VAR_INF_ADDR, sizeof(gCfgItems.spi_flash_flag)); + if (gCfgItems.spi_flash_flag == FLASH_INF_VALID_FLAG) { + W25QXX.SPI_FLASH_BufferRead((uint8_t *)&gCfgItems, VAR_INF_ADDR, sizeof(gCfgItems)); + } + else { + gCfgItems.spi_flash_flag = FLASH_INF_VALID_FLAG; + W25QXX.SPI_FLASH_SectorErase(VAR_INF_ADDR); + W25QXX.SPI_FLASH_BufferWrite((uint8_t *)&gCfgItems, VAR_INF_ADDR, sizeof(gCfgItems)); + //init gcode command + W25QXX.SPI_FLASH_BufferWrite((uint8_t *)&custom_gcode_command[0], AUTO_LEVELING_COMMAND_ADDR, 100); + W25QXX.SPI_FLASH_BufferWrite((uint8_t *)&custom_gcode_command[1], OTHERS_COMMAND_ADDR_1, 100); + W25QXX.SPI_FLASH_BufferWrite((uint8_t *)&custom_gcode_command[2], OTHERS_COMMAND_ADDR_2, 100); + W25QXX.SPI_FLASH_BufferWrite((uint8_t *)&custom_gcode_command[3], OTHERS_COMMAND_ADDR_3, 100); + W25QXX.SPI_FLASH_BufferWrite((uint8_t *)&custom_gcode_command[4], OTHERS_COMMAND_ADDR_4, 100); + } + + const byte rot = (TFT_ROTATION & TFT_ROTATE_180) ? 0xEE : 0x00; + if (gCfgItems.disp_rotation_180 != rot) { + gCfgItems.disp_rotation_180 = rot; + update_spi_flash(); + } + + uiCfg.F[0] = 'N'; + uiCfg.F[1] = 'A'; + uiCfg.F[2] = 'N'; + uiCfg.F[3] = 'O'; + W25QXX.SPI_FLASH_BlockErase(REFLSHE_FLGA_ADD + 32 - 64*1024); + W25QXX.SPI_FLASH_BufferWrite(uiCfg.F,REFLSHE_FLGA_ADD,4); +} + +void ui_cfg_init() { + uiCfg.curTempType = 0; + uiCfg.curSprayerChoose = 0; + uiCfg.stepHeat = 10; + uiCfg.leveling_first_time = 0; + uiCfg.para_ui_page = 0; + uiCfg.extruStep = 5; + uiCfg.extruSpeed = 10; + uiCfg.move_dist = 1; + uiCfg.moveSpeed = 3000; + uiCfg.stepPrintSpeed = 10; + uiCfg.command_send = 0; + uiCfg.dialogType = 0; + uiCfg.filament_heat_completed_load = 0; + uiCfg.filament_rate = 0; + uiCfg.filament_loading_completed = 0; + uiCfg.filament_unloading_completed = 0; + uiCfg.filament_loading_time_flg = 0; + uiCfg.filament_loading_time_cnt = 0; + uiCfg.filament_unloading_time_flg = 0; + uiCfg.filament_unloading_time_cnt = 0; + + #if ENABLED(USE_WIFI_FUNCTION) + memset(&wifiPara, 0, sizeof(wifiPara)); + memset(&ipPara, 0, sizeof(ipPara)); + strcpy(wifiPara.ap_name, WIFI_AP_NAME); + strcpy(wifiPara.keyCode, WIFI_KEY_CODE); + //client + strcpy(ipPara.ip_addr, IP_ADDR); + strcpy(ipPara.mask, IP_MASK); + strcpy(ipPara.gate, IP_GATE); + strcpy(ipPara.dns, IP_DNS); + + ipPara.dhcp_flag = IP_DHCP_FLAG; + + //AP + strcpy(ipPara.dhcpd_ip, AP_IP_ADDR); + strcpy(ipPara.dhcpd_mask, AP_IP_MASK); + strcpy(ipPara.dhcpd_gate, AP_IP_GATE); + strcpy(ipPara.dhcpd_dns, AP_IP_DNS); + strcpy(ipPara.start_ip_addr, IP_START_IP); + strcpy(ipPara.end_ip_addr, IP_END_IP); + + ipPara.dhcpd_flag = AP_IP_DHCP_FLAG; + + strcpy((char*)uiCfg.cloud_hostUrl, "baizhongyun.cn"); + uiCfg.cloud_port = 10086; + #endif + + uiCfg.filament_loading_time = (uint32_t)((gCfgItems.filamentchange_load_length * 60.0 / gCfgItems.filamentchange_load_speed) + 0.5); + uiCfg.filament_unloading_time = (uint32_t)((gCfgItems.filamentchange_unload_length * 60.0 / gCfgItems.filamentchange_unload_speed) + 0.5); +} + +void update_spi_flash() { + uint8_t command_buf[512]; + + W25QXX.init(SPI_QUARTER_SPEED); + //read back the gcode command befor erase spi flash + W25QXX.SPI_FLASH_BufferRead((uint8_t *)&command_buf, GCODE_COMMAND_ADDR, sizeof(command_buf)); + W25QXX.SPI_FLASH_SectorErase(VAR_INF_ADDR); + W25QXX.SPI_FLASH_BufferWrite((uint8_t *)&gCfgItems, VAR_INF_ADDR, sizeof(gCfgItems)); + W25QXX.SPI_FLASH_BufferWrite((uint8_t *)&command_buf, GCODE_COMMAND_ADDR, sizeof(command_buf)); +} + +void update_gcode_command(int addr,uint8_t *s) { + uint8_t command_buf[512]; + + W25QXX.init(SPI_QUARTER_SPEED); + //read back the gcode command befor erase spi flash + W25QXX.SPI_FLASH_BufferRead((uint8_t *)&command_buf, GCODE_COMMAND_ADDR, sizeof(command_buf)); + W25QXX.SPI_FLASH_SectorErase(VAR_INF_ADDR); + W25QXX.SPI_FLASH_BufferWrite((uint8_t *)&gCfgItems, VAR_INF_ADDR, sizeof(gCfgItems)); + switch (addr) { + case AUTO_LEVELING_COMMAND_ADDR: memcpy(&command_buf[0*100], s, 100); break; + case OTHERS_COMMAND_ADDR_1: memcpy(&command_buf[1*100], s, 100); break; + case OTHERS_COMMAND_ADDR_2: memcpy(&command_buf[2*100], s, 100); break; + case OTHERS_COMMAND_ADDR_3: memcpy(&command_buf[3*100], s, 100); break; + case OTHERS_COMMAND_ADDR_4: memcpy(&command_buf[4*100], s, 100); break; + default: break; + } + W25QXX.SPI_FLASH_BufferWrite((uint8_t *)&command_buf, GCODE_COMMAND_ADDR, sizeof(command_buf)); +} + +void get_gcode_command(int addr,uint8_t *d) { + W25QXX.init(SPI_QUARTER_SPEED); + W25QXX.SPI_FLASH_BufferRead((uint8_t *)d, addr, 100); +} + +lv_style_t tft_style_scr; +lv_style_t tft_style_label_pre; +lv_style_t tft_style_label_rel; +lv_style_t style_line; +lv_style_t style_para_value_pre; +lv_style_t style_para_value_rel; + +lv_style_t style_num_key_pre; +lv_style_t style_num_key_rel; + +lv_style_t style_num_text; +lv_style_t style_sel_text; + +lv_style_t style_para_value; +lv_style_t style_para_back; + +lv_style_t lv_bar_style_indic; + +void tft_style_init() { + lv_style_copy(&tft_style_scr, &lv_style_scr); + tft_style_scr.body.main_color = LV_COLOR_BACKGROUND; + tft_style_scr.body.grad_color = LV_COLOR_BACKGROUND; + tft_style_scr.text.color = LV_COLOR_TEXT; + tft_style_scr.text.sel_color = LV_COLOR_TEXT; + tft_style_scr.line.width = 0; + tft_style_scr.text.letter_space = 0; + tft_style_scr.text.line_space = 0; + + lv_style_copy(&tft_style_label_pre, &lv_style_scr); + lv_style_copy(&tft_style_label_rel, &lv_style_scr); + tft_style_label_pre.body.main_color = LV_COLOR_BACKGROUND; + tft_style_label_pre.body.grad_color = LV_COLOR_BACKGROUND; + tft_style_label_pre.text.color = LV_COLOR_TEXT; + tft_style_label_pre.text.sel_color = LV_COLOR_TEXT; + tft_style_label_rel.body.main_color = LV_COLOR_BACKGROUND; + tft_style_label_rel.body.grad_color = LV_COLOR_BACKGROUND; + tft_style_label_rel.text.color = LV_COLOR_TEXT; + tft_style_label_rel.text.sel_color = LV_COLOR_TEXT; + tft_style_label_pre.text.font = TERN(HAS_SPI_FLASH_FONT, &gb2312_puhui32, LV_FONT_DEFAULT); + tft_style_label_rel.text.font = TERN(HAS_SPI_FLASH_FONT, &gb2312_puhui32, LV_FONT_DEFAULT); + tft_style_label_pre.line.width = 0; + tft_style_label_rel.line.width = 0; + tft_style_label_pre.text.letter_space = 0; + tft_style_label_rel.text.letter_space = 0; + tft_style_label_pre.text.line_space = -5; + tft_style_label_rel.text.line_space = -5; + + lv_style_copy(&style_para_value_pre, &lv_style_scr); + lv_style_copy(&style_para_value_rel, &lv_style_scr); + style_para_value_pre.body.main_color = LV_COLOR_BACKGROUND; + style_para_value_pre.body.grad_color = LV_COLOR_BACKGROUND; + style_para_value_pre.text.color = LV_COLOR_TEXT; + style_para_value_pre.text.sel_color = LV_COLOR_TEXT; + style_para_value_rel.body.main_color = LV_COLOR_BACKGROUND; + style_para_value_rel.body.grad_color = LV_COLOR_BACKGROUND; + style_para_value_rel.text.color = LV_COLOR_BLACK; + style_para_value_rel.text.sel_color = LV_COLOR_BLACK; + style_para_value_pre.text.font = TERN(HAS_SPI_FLASH_FONT, &gb2312_puhui32, LV_FONT_DEFAULT); + style_para_value_rel.text.font = TERN(HAS_SPI_FLASH_FONT, &gb2312_puhui32, LV_FONT_DEFAULT); + style_para_value_pre.line.width = 0; + style_para_value_rel.line.width = 0; + style_para_value_pre.text.letter_space = 0; + style_para_value_rel.text.letter_space = 0; + style_para_value_pre.text.line_space = -5; + style_para_value_rel.text.line_space = -5; + + lv_style_copy(&style_num_key_pre, &lv_style_scr); + lv_style_copy(&style_num_key_rel, &lv_style_scr); + style_num_key_pre.body.main_color = LV_COLOR_KEY_BACKGROUND; + style_num_key_pre.body.grad_color = LV_COLOR_KEY_BACKGROUND; + style_num_key_pre.text.color = LV_COLOR_TEXT; + style_num_key_pre.text.sel_color = LV_COLOR_TEXT; + style_num_key_rel.body.main_color = LV_COLOR_KEY_BACKGROUND; + style_num_key_rel.body.grad_color = LV_COLOR_KEY_BACKGROUND; + style_num_key_rel.text.color = LV_COLOR_TEXT; + style_num_key_rel.text.sel_color = LV_COLOR_TEXT; + #if HAS_SPI_FLASH_FONT + style_num_key_pre.text.font = &gb2312_puhui32; + style_num_key_rel.text.font = &gb2312_puhui32; + #else + style_num_key_pre.text.font = LV_FONT_DEFAULT; + style_num_key_rel.text.font = LV_FONT_DEFAULT; + #endif + + style_num_key_pre.line.width = 0; + style_num_key_rel.line.width = 0; + style_num_key_pre.text.letter_space = 0; + style_num_key_rel.text.letter_space = 0; + style_num_key_pre.text.line_space = -5; + style_num_key_rel.text.line_space = -5; + lv_style_copy(&style_num_text, &lv_style_scr); + + style_num_text.body.main_color = LV_COLOR_WHITE; + style_num_text.body.grad_color = LV_COLOR_WHITE; + style_num_text.text.color = LV_COLOR_BLACK; + style_num_text.text.sel_color = LV_COLOR_BLACK; + style_num_text.text.font = TERN(HAS_SPI_FLASH_FONT, &gb2312_puhui32, LV_FONT_DEFAULT); + style_num_text.line.width = 0; + style_num_text.text.letter_space = 0; + style_num_text.text.line_space = -5; + + lv_style_copy(&style_sel_text, &lv_style_scr); + style_sel_text.body.main_color = LV_COLOR_BACKGROUND; + style_sel_text.body.grad_color = LV_COLOR_BACKGROUND; + style_sel_text.text.color = LV_COLOR_YELLOW; + style_sel_text.text.sel_color = LV_COLOR_YELLOW; + style_sel_text.text.font = &gb2312_puhui32; + style_sel_text.line.width = 0; + style_sel_text.text.letter_space = 0; + style_sel_text.text.line_space = -5; + lv_style_copy(&style_line, &lv_style_plain); + style_line.line.color = LV_COLOR_MAKE(0x49, 0x54, 0xFF); + style_line.line.width = 1; + style_line.line.rounded = 1; + + lv_style_copy(&style_para_value, &lv_style_plain); + style_para_value.body.border.color = LV_COLOR_BACKGROUND; + style_para_value.body.border.width = 1; + style_para_value.body.main_color = LV_COLOR_WHITE; + style_para_value.body.grad_color = LV_COLOR_WHITE; + style_para_value.body.shadow.width = 0; + style_para_value.body.radius = 3; + style_para_value.text.color = LV_COLOR_BLACK; + style_para_value.text.font = &TERN(HAS_SPI_FLASH_FONT, gb2312_puhui32, lv_font_roboto_22); + + lv_style_copy(&style_para_back, &lv_style_plain); + style_para_back.body.border.color = LV_COLOR_BACKGROUND; + style_para_back.body.border.width = 1; + style_para_back.body.main_color = TFT_LV_PARA_BACK_BODY_COLOR; + style_para_back.body.grad_color = TFT_LV_PARA_BACK_BODY_COLOR; + style_para_back.body.shadow.width = 0; + style_para_back.body.radius = 3; + style_para_back.text.color = LV_COLOR_WHITE; + style_para_back.text.font = &TERN(HAS_SPI_FLASH_FONT, gb2312_puhui32, lv_font_roboto_22); + + lv_style_copy(&lv_bar_style_indic, &lv_style_pretty_color); + lv_bar_style_indic.text.color = lv_color_hex3(0xADF); + lv_bar_style_indic.image.color = lv_color_hex3(0xADF); + lv_bar_style_indic.line.color = lv_color_hex3(0xADF); + lv_bar_style_indic.body.main_color = lv_color_hex3(0xADF); + lv_bar_style_indic.body.grad_color = lv_color_hex3(0xADF); + lv_bar_style_indic.body.border.color = lv_color_hex3(0xADF); + +} + +#define MAX_TITLE_LEN 28 + +char public_buf_m[100] = {0}; +char public_buf_l[30]; + +void titleText_cat(char *str, int strSize, char *addPart) { + if (str == 0 || addPart == 0) return; + if ((int)(strlen(str) + strlen(addPart)) >= strSize) return; + strcat(str, addPart); +} + +char *getDispText(int index) { + + ZERO(public_buf_l); + + switch (disp_state_stack._disp_state[index]) { + case PRINT_READY_UI: + strcpy(public_buf_l, main_menu.title); + break; + case PRINT_FILE_UI: + strcpy(public_buf_l, file_menu.title); + break; + case PRINTING_UI: + if (disp_state_stack._disp_state[disp_state_stack._disp_index] == PRINTING_UI + #ifndef TFT35 + || disp_state_stack._disp_state[disp_state_stack._disp_index] == OPERATE_UI + || disp_state_stack._disp_state[disp_state_stack._disp_index] == PAUSE_UI + #endif + ) strcpy(public_buf_l, common_menu.print_special_title); + else strcpy(public_buf_l, printing_menu.title); + break; + case MOVE_MOTOR_UI: + strcpy(public_buf_l, move_menu.title); + break; + case OPERATE_UI: + if (disp_state_stack._disp_state[disp_state_stack._disp_index] == PRINTING_UI + #ifndef TFT35 + || disp_state_stack._disp_state[disp_state_stack._disp_index] == OPERATE_UI + || disp_state_stack._disp_state[disp_state_stack._disp_index] == PAUSE_UI + #endif + ) strcpy(public_buf_l, common_menu.operate_special_title); + else strcpy(public_buf_l, operation_menu.title); + break; + + case PAUSE_UI: + if (disp_state_stack._disp_state[disp_state_stack._disp_index] == PRINTING_UI + || disp_state_stack._disp_state[disp_state_stack._disp_index] == OPERATE_UI + || disp_state_stack._disp_state[disp_state_stack._disp_index] == PAUSE_UI + ) strcpy(public_buf_l, common_menu.pause_special_title); + else strcpy(public_buf_l, pause_menu.title); + break; + + case EXTRUSION_UI: + strcpy(public_buf_l, extrude_menu.title); + break; + case CHANGE_SPEED_UI: + strcpy(public_buf_l, speed_menu.title); + break; + case FAN_UI: + strcpy(public_buf_l, fan_menu.title); + break; + case PRE_HEAT_UI: + if ((disp_state_stack._disp_state[disp_state_stack._disp_index - 1] == OPERATE_UI)) + strcpy(public_buf_l, preheat_menu.adjust_title); + else strcpy(public_buf_l, preheat_menu.title); + break; + case SET_UI: + strcpy(public_buf_l, set_menu.title); + break; + case ZERO_UI: + strcpy(public_buf_l, home_menu.title); + break; + case SPRAYER_UI: break; + case MACHINE_UI: break; + case LANGUAGE_UI: + strcpy(public_buf_l, language_menu.title); + break; + case ABOUT_UI: + strcpy(public_buf_l, about_menu.title); + break; + case LOG_UI: break; + case DISK_UI: + strcpy(public_buf_l, filesys_menu.title); + break; + case DIALOG_UI: + strcpy(public_buf_l, common_menu.dialog_confirm_title); + break; + case WIFI_UI: + strcpy(public_buf_l, wifi_menu.title); + break; + case MORE_UI: + case PRINT_MORE_UI: + strcpy(public_buf_l, more_menu.title); + break; + case FILAMENTCHANGE_UI: + strcpy(public_buf_l, filament_menu.title); + break; + case LEVELING_UI: + case MESHLEVELING_UI: + strcpy(public_buf_l, leveling_menu.title); + break; + case BIND_UI: + strcpy(public_buf_l, cloud_menu.title); + break; + case TOOL_UI: + strcpy(public_buf_l, tool_menu.title); + break; + case WIFI_LIST_UI: + #if ENABLED(USE_WIFI_FUNCTION) + strcpy(public_buf_l, list_menu.title); + break; + #endif + case MACHINE_PARA_UI: + strcpy(public_buf_l, MachinePara_menu.title); + break; + case BABY_STEP_UI: + strcpy(public_buf_l, operation_menu.babystep); + break; + case EEPROM_SETTINGS_UI: + strcpy(public_buf_l, eeprom_menu.title); + break; + default: break; + } + + return public_buf_l; +} + +char *creat_title_text() { + int index = 0; + char *tmpText = 0; + char tmpCurFileStr[20]; + + ZERO(tmpCurFileStr); + + #if _LFN_UNICODE + //cutFileName((TCHAR *)curFileName, 16, 16, (TCHAR *)tmpCurFileStr); + #else + cutFileName(list_file.long_name[sel_id], 16, 16, tmpCurFileStr); + #endif + + ZERO(public_buf_m); + + while (index <= disp_state_stack._disp_index) { + tmpText = getDispText(index); + if ((*tmpText == 0) || (tmpText == 0)) { + index++; + continue; + } + + titleText_cat(public_buf_m, sizeof(public_buf_m), tmpText); + if (index < disp_state_stack._disp_index) titleText_cat(public_buf_m, sizeof(public_buf_m), (char *)">"); + + index++; + } + + if (disp_state_stack._disp_state[disp_state_stack._disp_index] == PRINTING_UI + /*|| disp_state_stack._disp_state[disp_state_stack._disp_index] == OPERATE_UI + || disp_state_stack._disp_state[disp_state_stack._disp_index] == PAUSE_UI*/ + ) { + titleText_cat(public_buf_m, sizeof(public_buf_m), (char *)":"); + titleText_cat(public_buf_m, sizeof(public_buf_m), tmpCurFileStr); + } + + if (strlen(public_buf_m) > MAX_TITLE_LEN) { + ZERO(public_buf_m); + tmpText = getDispText(0); + if (*tmpText != 0) { + titleText_cat(public_buf_m, sizeof(public_buf_m), tmpText); + titleText_cat(public_buf_m, sizeof(public_buf_m), (char *)">...>"); + tmpText = getDispText(disp_state_stack._disp_index); + if (*tmpText != 0) titleText_cat(public_buf_m, sizeof(public_buf_m), tmpText); + } + } + + return public_buf_m; +} + +#if HAS_GCODE_PREVIEW + + uint32_t gPicturePreviewStart = 0; + + void preview_gcode_prehandle(char *path) { + #if ENABLED(SDSUPPORT) + //uint8_t re; + //uint32_t read; + uint32_t pre_read_cnt = 0; + uint32_t *p1; + char *cur_name; + + gPicturePreviewStart = 0; + cur_name = strrchr(path, '/'); + card.openFileRead(cur_name); + card.read(public_buf, 512); + p1 = (uint32_t *)strstr((char *)public_buf, ";simage:"); + + if (p1) { + pre_read_cnt = (uint32_t)p1 - (uint32_t)((uint32_t *)(&public_buf[0])); + + To_pre_view = pre_read_cnt; + gcode_preview_over = 1; + gCfgItems.from_flash_pic = 1; + update_spi_flash(); + } + else { + gcode_preview_over = 0; + default_preview_flg = 1; + gCfgItems.from_flash_pic = 0; + update_spi_flash(); + } + card.closefile(); + #endif + } + + #if 1 + + void gcode_preview(char *path, int xpos_pixel, int ypos_pixel) { + #if ENABLED(SDSUPPORT) + //uint8_t ress; + //uint32_t write; + volatile uint32_t i, j; + volatile uint16_t *p_index; + //int res; + char *cur_name; + + cur_name = strrchr(path, '/'); + card.openFileRead(cur_name); + + if (gPicturePreviewStart <= 0) { + while (1) { + uint32_t br = card.read(public_buf, 400); + uint32_t* p1 = (uint32_t *)strstr((char *)public_buf, ";gimage:"); + if (p1) { + gPicturePreviewStart += (uint32_t)p1 - (uint32_t)((uint32_t *)(&public_buf[0])); + break; + } + else { + gPicturePreviewStart += br; + } + if (br < 400) break; + } + } + + card.setIndex((gPicturePreviewStart + To_pre_view) + size * row + 8); + SPI_TFT.setWindow(xpos_pixel, ypos_pixel + row, 200, 1); + + j = i = 0; + + while (1) { + card.read(public_buf, 400); + for (i = 0; i < 400;) { + bmp_public_buf[j] = ascii2dec_test((char*)&public_buf[i]) << 4 | ascii2dec_test((char*)&public_buf[i + 1]); + i += 2; + j++; + } + if (j >= 400) break; + } + for (i = 0; i < 400; i += 2) { + p_index = (uint16_t *)(&bmp_public_buf[i]); + if (*p_index == 0x0000) *p_index = LV_COLOR_BACKGROUND.full; + } + SPI_TFT.tftio.WriteSequence((uint16_t*)bmp_public_buf, 200); + #if HAS_BAK_VIEW_IN_FLASH + W25QXX.init(SPI_QUARTER_SPEED); + if (row < 20) W25QXX.SPI_FLASH_SectorErase(BAK_VIEW_ADDR_TFT35 + row * 4096); + W25QXX.SPI_FLASH_BufferWrite(bmp_public_buf, BAK_VIEW_ADDR_TFT35 + row * 400, 400); + #endif + row++; + if (row >= 200) { + size = 809; + row = 0; + + gcode_preview_over = 0; + //flash_preview_begin = 1; + + card.closefile(); + + /* + if (gCurFileState.file_open_flag != 0xAA) { + reset_file_info(); + res = f_open(file, curFileName, FA_OPEN_EXISTING | FA_READ); + if (res == FR_OK) { + f_lseek(file,PREVIEW_SIZE+To_pre_view); + gCurFileState.file_open_flag = 0xAA; + //bakup_file_path((uint8_t *)curFileName, strlen(curFileName)); + srcfp = file; + mksReprint.mks_printer_state = MKS_WORKING; + once_flag = 0; + } + } + */ + char *cur_name; + + cur_name = strrchr(list_file.file_name[sel_id], '/'); + + SdFile file; + SdFile *curDir; + card.endFilePrint(); + const char * const fname = card.diveToFile(true, curDir, cur_name); + if (!fname) return; + if (file.open(curDir, fname, O_READ)) { + gCfgItems.curFilesize = file.fileSize(); + file.close(); + update_spi_flash(); + } + + card.openFileRead(cur_name); + if (card.isFileOpen()) { + feedrate_percentage = 100; + //saved_feedrate_percentage = feedrate_percentage; + planner.flow_percentage[0] = 100; + planner.e_factor[0] = planner.flow_percentage[0] * 0.01; + #if HAS_MULTI_EXTRUDER + planner.flow_percentage[1] = 100; + planner.e_factor[1] = planner.flow_percentage[1] * 0.01; + #endif + card.startFileprint(); + TERN_(POWER_LOSS_RECOVERY, recovery.prepare()); + once_flag = 0; + } + return; + } + card.closefile(); + #endif // SDSUPPORT + } + + #else // if 1 + + void gcode_preview(char *path, int xpos_pixel, int ypos_pixel) { + #if ENABLED(SDSUPPORT) + //uint8_t ress; + //uint32_t write; + volatile uint32_t i, j; + volatile uint16_t *p_index; + //int res; + char *cur_name; + uint16_t Color; + + cur_name = strrchr(path, '/'); + card.openFileRead(cur_name); + + card.setIndex((PREVIEW_LITTLE_PIC_SIZE + To_pre_view) + size * row + 8); + #if ENABLED(TFT_LVGL_UI_SPI) + SPI_TFT.setWindow(xpos_pixel, ypos_pixel + row, 200, 1); + #else + LCD_setWindowArea(xpos_pixel, ypos_pixel + row, 200, 1); + LCD_WriteRAM_Prepare(); + #endif + + j = 0; + i = 0; + + while (1) { + card.read(public_buf, 400); + for (i = 0; i < 400;) { + bmp_public_buf[j] = ascii2dec_test((char*)&public_buf[i]) << 4 | ascii2dec_test((char*)&public_buf[i + 1]); + i += 2; + j++; + } + + //if (i > 800) break; + //#ifdef TFT70 + // if (j > 400) { + // f_read(file, buff_pic, 1, &read); + // break; + // } + //#elif defined(TFT35) + if (j >= 400) + //f_read(file, buff_pic, 1, &read); + break; + //#endif + + } + #if ENABLED(TFT_LVGL_UI_SPI) + for (i = 0; i < 400;) { + p_index = (uint16_t *)(&bmp_public_buf[i]); + + Color = (*p_index >> 8); + *p_index = Color | ((*p_index & 0xFF) << 8); + i += 2; + if (*p_index == 0x0000) *p_index = 0xC318; + } + TFT_CS_L; + TFT_DC_H; + SPI.dmaSend(bmp_public_buf, 400, true); + TFT_CS_H; + + #else + for (i = 0; i < 400;) { + p_index = (uint16_t *)(&bmp_public_buf[i]); + if (*p_index == 0x0000) *p_index = 0x18C3; + LCD_IO_WriteData(*p_index); + i = i + 2; + } + #endif + W25QXX.init(SPI_QUARTER_SPEED); + if (row < 20) + W25QXX.SPI_FLASH_SectorErase(BAK_VIEW_ADDR_TFT35 + row * 4096); + W25QXX.SPI_FLASH_BufferWrite(bmp_public_buf, BAK_VIEW_ADDR_TFT35 + row * 400, 400); + row++; + if (row >= 200) { + size = 809; + row = 0; + + gcode_preview_over = 0; + //flash_preview_begin = 1; + + card.closefile(); + + /* + if (gCurFileState.file_open_flag != 0xAA) { + reset_file_info(); + res = f_open(file, curFileName, FA_OPEN_EXISTING | FA_READ); + if (res == FR_OK) { + f_lseek(file,PREVIEW_SIZE+To_pre_view); + gCurFileState.file_open_flag = 0xAA; + //bakup_file_path((uint8_t *)curFileName, strlen(curFileName)); + srcfp = file; + mksReprint.mks_printer_state = MKS_WORKING; + once_flag = 0; + } + } + */ + char *cur_name; + + cur_name = strrchr(list_file.file_name[sel_id], '/'); + + SdFile file; + SdFile *curDir; + card.endFilePrint(); + const char * const fname = card.diveToFile(true, curDir, cur_name); + if (!fname) return; + if (file.open(curDir, fname, O_READ)) { + gCfgItems.curFilesize = file.fileSize(); + file.close(); + update_spi_flash(); + } + + card.openFileRead(cur_name); + if (card.isFileOpen()) { + feedrate_percentage = 100; + //saved_feedrate_percentage = feedrate_percentage; + planner.flow_percentage[0] = 100; + planner.e_factor[0] = planner.flow_percentage[0] * 0.01; + #if HAS_MULTI_EXTRUDER + planner.flow_percentage[1] = 100; + planner.e_factor[1] = planner.flow_percentage[1] * 0.01; + #endif + card.startFileprint(); + TERN_(POWER_LOSS_RECOVERY, recovery.prepare()); + once_flag = 0; + } + return; + } + card.closefile(); + #endif // SDSUPPORT + } + + #endif // if 1 + + void Draw_default_preview(int xpos_pixel, int ypos_pixel, uint8_t sel) { + int index; + int y_off = 0; + W25QXX.init(SPI_QUARTER_SPEED); + for (index = 0; index < 10; index++) { // 200*200 + #if HAS_BAK_VIEW_IN_FLASH + if (sel == 1) { + flash_view_Read(bmp_public_buf, 8000); // 20k + } + else { + default_view_Read(bmp_public_buf, DEFAULT_VIEW_MAX_SIZE / 10); // 8k + } + #else + default_view_Read(bmp_public_buf, DEFAULT_VIEW_MAX_SIZE / 10); // 8k + #endif + + SPI_TFT.setWindow(xpos_pixel, y_off * 20 + ypos_pixel, 200, 20); // 200*200 + SPI_TFT.tftio.WriteSequence((uint16_t*)(bmp_public_buf), DEFAULT_VIEW_MAX_SIZE / 20); + + y_off++; + } + W25QXX.init(SPI_QUARTER_SPEED); + } + + void disp_pre_gcode(int xpos_pixel, int ypos_pixel) { + if (gcode_preview_over == 1) gcode_preview(list_file.file_name[sel_id], xpos_pixel, ypos_pixel); + #if HAS_BAK_VIEW_IN_FLASH + if (flash_preview_begin == 1) { + flash_preview_begin = 0; + Draw_default_preview(xpos_pixel, ypos_pixel, 1); + } + #endif + #if HAS_GCODE_DEFAULT_VIEW_IN_FLASH + if (default_preview_flg == 1) { + Draw_default_preview(xpos_pixel, ypos_pixel, 0); + default_preview_flg = 0; + } + #endif + } +#endif // HAS_GCODE_PREVIEW + +void print_time_run() { + static uint8_t lastSec = 0; + + if (print_time.seconds >= 60) { + print_time.seconds = 0; + print_time.minutes++; + if (print_time.minutes >= 60) { + print_time.minutes = 0; + print_time.hours++; + } + } + if (disp_state == PRINTING_UI) { + if (lastSec != print_time.seconds) disp_print_time(); + lastSec = print_time.seconds; + } +} + +void GUI_RefreshPage() { + if ((systick_uptime_millis % 1000) == 0) temperature_change_frequency = 1; + if ((systick_uptime_millis % 3000) == 0) printing_rate_update_flag = 1; + + switch (disp_state) { + case MAIN_UI: + //lv_draw_ready_print(); + break; + case EXTRUSION_UI: + if (temperature_change_frequency == 1) { + temperature_change_frequency = 0; + disp_hotend_temp(); + } + break; + case PRE_HEAT_UI: + if (temperature_change_frequency == 1) { + temperature_change_frequency = 0; + disp_desire_temp(); + } + break; + case PRINT_READY_UI: + /* + if (gCfgItems.display_style == 2) { + if (temperature_change_frequency) { + temperature_change_frequency = 0; + disp_restro_state(); + } + } + */ + break; + + case PRINT_FILE_UI: break; + + case PRINTING_UI: + if (temperature_change_frequency) { + temperature_change_frequency = 0; + disp_ext_temp(); + disp_bed_temp(); + disp_fan_speed(); + disp_print_time(); + disp_fan_Zpos(); + } + if (printing_rate_update_flag || marlin_state == MF_SD_COMPLETE) { + printing_rate_update_flag = 0; + if (gcode_preview_over == 0) setProBarRate(); + } + break; + + case OPERATE_UI: + /* + if (temperature_change_frequency == 1) { + temperature_change_frequency = 0; + disp_temp_operate(); + } + + setProBarRateOpera(); + */ + break; + + case PAUSE_UI: + /* + if (temperature_change_frequency == 1) { + temperature_change_frequency = 0; + disp_temp_pause(); + } + */ + break; + + case FAN_UI: + if (temperature_change_frequency == 1) { + temperature_change_frequency = 0; + disp_fan_value(); + } + break; + + case MOVE_MOTOR_UI: + /* + if (mksReprint.mks_printer_state == MKS_IDLE) { + if ((z_high_count==1)&&(temper_error_flg != 1)) { + z_high_count = 0; + { + memset((char *)gCfgItems.move_z_coordinate, ' ', sizeof(gCfgItems.move_z_coordinate)); + GUI_DispStringAt((const char *)gCfgItems.move_z_coordinate, 380, TITLE_YPOS); + sprintf_P((char *)gCfgItems.move_z_coordinate, PSTR("Z: %.3f"), current_position[Z_AXIS]); + GUI_DispStringAt((const char *)gCfgItems.move_z_coordinate, 380, TITLE_YPOS); + } + } + } + */ + break; + + #if ENABLED(USE_WIFI_FUNCTION) + case WIFI_UI: + if (temperature_change_frequency == 1) { + disp_wifi_state(); + temperature_change_frequency = 0; + } + break; + #endif + + case BIND_UI: + /*refresh_bind_ui();*/ + break; + + case FILAMENTCHANGE_UI: + if (temperature_change_frequency) { + temperature_change_frequency = 0; + disp_filament_temp(); + } + break; + case DIALOG_UI: + filament_dialog_handle(); + TERN_(USE_WIFI_FUNCTION, wifi_scan_handle()); + break; + case MESHLEVELING_UI: + /*disp_zpos();*/ + break; + case HARDWARE_TEST_UI: + break; + case WIFI_LIST_UI: + #if ENABLED(USE_WIFI_FUNCTION) + if (printing_rate_update_flag == 1) { + disp_wifi_list(); + printing_rate_update_flag = 0; + } + #endif + break; + case KEY_BOARD_UI: + /*update_password_disp(); + update_join_state_disp();*/ + break; + #if ENABLED(USE_WIFI_FUNCTION) + case WIFI_TIPS_UI: + switch (wifi_tips_type) { + case TIPS_TYPE_JOINING: + if (wifi_link_state == WIFI_CONNECTED && strcmp((const char *)wifi_list.wifiConnectedName,(const char *)wifi_list.wifiName[wifi_list.nameIndex]) == 0) { + tips_disp.timer = TIPS_TIMER_STOP; + tips_disp.timer_count = 0; + + lv_clear_wifi_tips(); + wifi_tips_type = TIPS_TYPE_WIFI_CONECTED; + lv_draw_wifi_tips(); + + } + if (tips_disp.timer_count >= 30 * 1000) { + tips_disp.timer = TIPS_TIMER_STOP; + tips_disp.timer_count = 0; + lv_clear_wifi_tips(); + wifi_tips_type = TIPS_TYPE_TAILED_JOIN; + lv_draw_wifi_tips(); + } + break; + case TIPS_TYPE_TAILED_JOIN: + if (tips_disp.timer_count >= 3 * 1000) { + tips_disp.timer = TIPS_TIMER_STOP; + tips_disp.timer_count = 0; + + last_disp_state = WIFI_TIPS_UI; + lv_clear_wifi_tips(); + lv_draw_wifi_list(); + } + break; + case TIPS_TYPE_WIFI_CONECTED: + if (tips_disp.timer_count >= 3 * 1000) { + tips_disp.timer = TIPS_TIMER_STOP; + tips_disp.timer_count = 0; + + last_disp_state = WIFI_TIPS_UI; + lv_clear_wifi_tips(); + lv_draw_wifi(); + } + break; + default: break; + } + break; + #endif + + case BABY_STEP_UI: + if (temperature_change_frequency == 1) { + temperature_change_frequency = 0; + disp_z_offset_value(); + } + break; + default: break; + } + + print_time_run(); +} + +void clear_cur_ui() { + last_disp_state = disp_state_stack._disp_state[disp_state_stack._disp_index]; + + switch (disp_state_stack._disp_state[disp_state_stack._disp_index]) { + case PRINT_READY_UI: + //Get_Temperature_Flg = 0; + lv_clear_ready_print(); + break; + case PRINT_FILE_UI: + lv_clear_print_file(); + break; + case PRINTING_UI: + lv_clear_printing(); + break; + case MOVE_MOTOR_UI: + lv_clear_move_motor(); + break; + case OPERATE_UI: + lv_clear_operation(); + break; + case PAUSE_UI: + //Clear_pause(); + break; + case EXTRUSION_UI: + lv_clear_extrusion(); + break; + case PRE_HEAT_UI: + lv_clear_preHeat(); + break; + case CHANGE_SPEED_UI: + lv_clear_change_speed(); + break; + case FAN_UI: + lv_clear_fan(); + break; + case SET_UI: + lv_clear_set(); + break; + case ZERO_UI: + lv_clear_home(); + break; + case SPRAYER_UI: + //Clear_Sprayer(); + break; + case MACHINE_UI: + //Clear_Machine(); + break; + case LANGUAGE_UI: + lv_clear_language(); + break; + case ABOUT_UI: + lv_clear_about(); + break; + case LOG_UI: + //Clear_Connect(); + break; + case DISK_UI: + //Clear_Disk(); + break; + #if ENABLED(USE_WIFI_FUNCTION) + case WIFI_UI: + lv_clear_wifi(); + break; + #endif + case MORE_UI: + //Clear_more(); + break; + case FILETRANSFER_UI: + //Clear_fileTransfer(); + break; + case DIALOG_UI: + lv_clear_dialog(); + break; + case FILETRANSFERSTATE_UI: + //Clear_WifiFileTransferdialog(); + break; + case PRINT_MORE_UI: + //Clear_Printmore(); + break; + case FILAMENTCHANGE_UI: + lv_clear_filament_change(); + break; + case LEVELING_UI: + lv_clear_manualLevel(); + break; + case BIND_UI: + //Clear_Bind(); + break; + #if HAS_BED_PROBE + case NOZZLE_PROBE_OFFSET_UI: + lv_clear_auto_level_offset_settings(); + break; + #endif + case TOOL_UI: + lv_clear_tool(); + break; + case MESHLEVELING_UI: + //Clear_MeshLeveling(); + break; + case HARDWARE_TEST_UI: + //Clear_Hardwaretest(); + break; + #if ENABLED(USE_WIFI_FUNCTION) + case WIFI_LIST_UI: + lv_clear_wifi_list(); + break; + #endif + case KEY_BOARD_UI: + lv_clear_keyboard(); + break; + #if ENABLED(USE_WIFI_FUNCTION) + case WIFI_TIPS_UI: + lv_clear_wifi_tips(); + break; + #endif + case MACHINE_PARA_UI: + lv_clear_machine_para(); + break; + case MACHINE_SETTINGS_UI: + lv_clear_machine_settings(); + break; + case TEMPERATURE_SETTINGS_UI: + //Clear_TemperatureSettings(); + break; + case MOTOR_SETTINGS_UI: + lv_clear_motor_settings(); + break; + case MACHINETYPE_UI: + //Clear_MachineType(); + break; + case STROKE_UI: + //Clear_Stroke(); + break; + case HOME_DIR_UI: + //Clear_HomeDir(); + break; + case ENDSTOP_TYPE_UI: + //Clear_EndstopType(); + break; + case FILAMENT_SETTINGS_UI: + lv_clear_filament_settings(); + break; + case LEVELING_SETTIGNS_UI: + //Clear_LevelingSettings(); + break; + case LEVELING_PARA_UI: + lv_clear_level_settings(); + break; + case DELTA_LEVELING_PARA_UI: + //Clear_DeltaLevelPara(); + break; + case MANUAL_LEVELING_POSIGION_UI: + lv_clear_manual_level_pos_settings(); + break; + case MAXFEEDRATE_UI: + lv_clear_max_feedrate_settings(); + break; + case STEPS_UI: + lv_clear_step_settings(); + break; + case ACCELERATION_UI: + lv_clear_acceleration_settings(); + break; + case JERK_UI: + #if HAS_CLASSIC_JERK + lv_clear_jerk_settings(); + #endif + break; + case MOTORDIR_UI: + //Clear_MotorDir(); + break; + case HOMESPEED_UI: + //Clear_HomeSpeed(); + break; + case NOZZLE_CONFIG_UI: + //Clear_NozzleConfig(); + break; + case HOTBED_CONFIG_UI: + //Clear_HotbedConfig(); + break; + case ADVANCED_UI: + lv_clear_advance_settings(); + break; + case DOUBLE_Z_UI: + //Clear_DoubleZ(); + break; + case ENABLE_INVERT_UI: + //Clear_EnableInvert(); + break; + case NUMBER_KEY_UI: + lv_clear_number_key(); + break; + case BABY_STEP_UI: + lv_clear_baby_stepping(); + break; + case PAUSE_POS_UI: + lv_clear_pause_position(); + break; + #if HAS_TRINAMIC_CONFIG + case TMC_CURRENT_UI: + lv_clear_tmc_current_settings(); + break; + #endif + case EEPROM_SETTINGS_UI: + lv_clear_eeprom_settings(); + break; + #if HAS_STEALTHCHOP + case TMC_MODE_UI: + lv_clear_tmc_step_mode_settings(); + break; + #endif + #if ENABLED(USE_WIFI_FUNCTION) + case WIFI_SETTINGS_UI: + lv_clear_wifi_settings(); + break; + #endif + #if USE_SENSORLESS + case HOMING_SENSITIVITY_UI: + lv_clear_homing_sensitivity_settings(); + break; + #endif + #if HAS_ROTARY_ENCODER + case ENCODER_SETTINGS_UI: + lv_clear_encoder_settings(); + break; + #endif + default: break; + } + //GUI_Clear(); +} + +void draw_return_ui() { + if (disp_state_stack._disp_index > 0) { + disp_state_stack._disp_index--; + + switch (disp_state_stack._disp_state[disp_state_stack._disp_index]) { + case PRINT_READY_UI: + lv_draw_ready_print(); + break; + case PRINT_FILE_UI: + lv_draw_print_file(); + break; + case PRINTING_UI: + if (gCfgItems.from_flash_pic == 1) flash_preview_begin = 1; + else default_preview_flg = 1; + lv_draw_printing(); + break; + case MOVE_MOTOR_UI: + lv_draw_move_motor(); + break; + case OPERATE_UI: + lv_draw_operation(); + break; + + #if 1 + case PAUSE_UI: + //draw_pause(); + break; + #endif + + case EXTRUSION_UI: + lv_draw_extrusion(); + break; + case PRE_HEAT_UI: + lv_draw_preHeat(); + break; + case CHANGE_SPEED_UI: + lv_draw_change_speed(); + break; + case FAN_UI: + lv_draw_fan(); + break; + case SET_UI: + lv_draw_set(); + break; + case ZERO_UI: + lv_draw_home(); + break; + case SPRAYER_UI: + //draw_Sprayer(); + break; + case MACHINE_UI: + //draw_Machine(); + break; + case LANGUAGE_UI: + lv_draw_language(); + break; + case ABOUT_UI: + lv_draw_about(); + break; + + case CALIBRATE_UI: + //draw_calibrate(); + break; + case DISK_UI: + //draw_Disk(); + break; + #if ENABLED(USE_WIFI_FUNCTION) + case WIFI_UI: + lv_draw_wifi(); + break; + #endif + case MORE_UI: + //draw_More(); + break; + case PRINT_MORE_UI: + //draw_printmore(); + break; + case FILAMENTCHANGE_UI: + lv_draw_filament_change(); + break; + case LEVELING_UI: + lv_draw_manualLevel(); + break; + case BIND_UI: + //draw_bind(); + break; + #if HAS_BED_PROBE + case NOZZLE_PROBE_OFFSET_UI: + lv_draw_auto_level_offset_settings(); + break; + #endif + case TOOL_UI: + lv_draw_tool(); + break; + case MESHLEVELING_UI: + //draw_meshleveling(); + break; + case HARDWARE_TEST_UI: + //draw_Hardwaretest(); + break; + case WIFI_LIST_UI: + #if ENABLED(USE_WIFI_FUNCTION) + lv_draw_wifi_list(); + #endif + break; + case KEY_BOARD_UI: + lv_draw_keyboard(); + break; + case WIFI_TIPS_UI: + #if ENABLED(USE_WIFI_FUNCTION) + lv_draw_wifi_tips(); + #endif + break; + case MACHINE_PARA_UI: + lv_draw_machine_para(); + break; + case MACHINE_SETTINGS_UI: + lv_draw_machine_settings(); + break; + case TEMPERATURE_SETTINGS_UI: + //draw_TemperatureSettings(); + break; + case MOTOR_SETTINGS_UI: + lv_draw_motor_settings(); + break; + case MACHINETYPE_UI: + //draw_MachineType(); + break; + case STROKE_UI: + //draw_Stroke(); + break; + case HOME_DIR_UI: + //draw_HomeDir(); + break; + case ENDSTOP_TYPE_UI: + //draw_EndstopType(); + break; + case FILAMENT_SETTINGS_UI: + lv_draw_filament_settings(); + break; + case LEVELING_SETTIGNS_UI: + //draw_LevelingSettings(); + break; + case LEVELING_PARA_UI: + lv_draw_level_settings(); + break; + case DELTA_LEVELING_PARA_UI: + //draw_DeltaLevelPara(); + break; + case MANUAL_LEVELING_POSIGION_UI: + lv_draw_manual_level_pos_settings(); + break; + case MAXFEEDRATE_UI: + lv_draw_max_feedrate_settings(); + break; + case STEPS_UI: + lv_draw_step_settings(); + break; + case ACCELERATION_UI: + lv_draw_acceleration_settings(); + break; + case JERK_UI: + #if HAS_CLASSIC_JERK + lv_draw_jerk_settings(); + #endif + break; + case MOTORDIR_UI: + //draw_MotorDir(); + break; + case HOMESPEED_UI: + //draw_HomeSpeed(); + break; + case NOZZLE_CONFIG_UI: + //draw_NozzleConfig(); + break; + case HOTBED_CONFIG_UI: + //draw_HotbedConfig(); + break; + case ADVANCED_UI: + lv_draw_advance_settings(); + break; + case DOUBLE_Z_UI: + //draw_DoubleZ(); + break; + case ENABLE_INVERT_UI: + //draw_EnableInvert(); + break; + case NUMBER_KEY_UI: + lv_draw_number_key(); + break; + case DIALOG_UI: + //draw_dialog(uiCfg.dialogType); + break; + case BABY_STEP_UI: + lv_draw_baby_stepping(); + break; + case PAUSE_POS_UI: + lv_draw_pause_position(); + break; + #if HAS_TRINAMIC_CONFIG + case TMC_CURRENT_UI: + lv_draw_tmc_current_settings(); + break; + #endif + case EEPROM_SETTINGS_UI: + lv_draw_eeprom_settings(); + break; + #if HAS_STEALTHCHOP + case TMC_MODE_UI: + lv_draw_tmc_step_mode_settings(); + break; + #endif + #if ENABLED(USE_WIFI_FUNCTION) + case WIFI_SETTINGS_UI: + lv_draw_wifi_settings(); + break; + #endif + #if USE_SENSORLESS + case HOMING_SENSITIVITY_UI: + lv_draw_homing_sensitivity_settings(); + break; + #endif + #if HAS_ROTARY_ENCODER + case ENCODER_SETTINGS_UI: + lv_draw_encoder_settings(); + break; + #endif + default: break; + } + } +} + +#if ENABLED(SDSUPPORT) + + void sd_detection() { + static bool last_sd_status; + const bool sd_status = IS_SD_INSERTED(); + if (sd_status != last_sd_status) { + last_sd_status = sd_status; + if (sd_status) card.mount(); else card.release(); + } + } + +#endif + +void lv_ex_line(lv_obj_t * line, lv_point_t *points) { + // Copy the previous line and apply the new style + lv_line_set_points(line, points, 2); // Set the points + lv_line_set_style(line, LV_LINE_STYLE_MAIN, &style_line); + lv_obj_align(line, NULL, LV_ALIGN_IN_TOP_MID, 0, 0); +} + +extern volatile uint32_t systick_uptime_millis; + +void print_time_count() { + if ((systick_uptime_millis % 1000) == 0) + if (print_time.start == 1) print_time.seconds++; +} + +void LV_TASK_HANDLER() { + //lv_tick_inc(1); + lv_task_handler(); + if (mks_test_flag == 0x1E) mks_hardware_test(); + + #if HAS_GCODE_PREVIEW + disp_pre_gcode(2, 36); + #endif + + GUI_RefreshPage(); + + #if ENABLED(USE_WIFI_FUNCTION) + get_wifi_commands(); + #endif + + //sd_detection(); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_update_encoder(); + #endif +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_ui.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_ui.h new file mode 100644 index 000000000000..51782688c0b1 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_ui.h @@ -0,0 +1,454 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include + +#include +#include + +// the colors of the last MKS Ui +#undef LV_COLOR_BACKGROUND +#define LV_COLOR_BACKGROUND LV_COLOR_MAKE(0x1A, 0x1A, 0x1A) // LV_COLOR_MAKE(0x00, 0x00, 0x00) + +#define TFT_LV_PARA_BACK_BODY_COLOR LV_COLOR_MAKE(0x4A, 0x52, 0xFF) + +#include "tft_lvgl_configuration.h" +#include "tft_multi_language.h" +#include "pic_manager.h" +#include "draw_ready_print.h" +#include "draw_language.h" +#include "draw_set.h" +#include "draw_tool.h" +#include "draw_print_file.h" +#include "draw_dialog.h" +#include "draw_printing.h" +#include "draw_operation.h" +#include "draw_preHeat.h" +#include "draw_extrusion.h" +#include "draw_home.h" +#include "draw_move_motor.h" +#include "draw_fan.h" +#include "draw_about.h" +#include "draw_change_speed.h" +#include "draw_manuaLevel.h" +#include "draw_error_message.h" +#include "printer_operation.h" +#include "draw_machine_para.h" +#include "draw_machine_settings.h" +#include "draw_motor_settings.h" +#include "draw_advance_settings.h" +#include "draw_acceleration_settings.h" +#include "draw_number_key.h" +#include "draw_jerk_settings.h" +#include "draw_pause_position.h" +#include "draw_step_settings.h" +#include "draw_tmc_current_settings.h" +#include "draw_eeprom_settings.h" +#include "draw_max_feedrate_settings.h" +#include "draw_tmc_step_mode_settings.h" +#include "draw_level_settings.h" +#include "draw_manual_level_pos_settings.h" +#include "draw_auto_level_offset_settings.h" +#include "draw_filament_change.h" +#include "draw_filament_settings.h" +#include "draw_homing_sensitivity_settings.h" +#include "draw_baby_stepping.h" +#include "draw_keyboard.h" +#include "draw_encoder_settings.h" + +#if ENABLED(USE_WIFI_FUNCTION) + #include "wifiSerial.h" + #include "wifi_module.h" + #include "wifi_upload.h" + #include "draw_wifi_settings.h" + #include "draw_wifi.h" + #include "draw_wifi_list.h" + #include "draw_wifi_tips.h" +#endif + +#include "../../inc/MarlinConfigPre.h" +#define FILE_SYS_USB 0 +#define FILE_SYS_SD 1 + +#define TICK_CYCLE 1 + +#define PARA_SEL_ICON_TEXT_COLOR LV_COLOR_MAKE(0x4A, 0x52, 0xFF); + +#define TFT35 + +#ifdef TFT35 + + #define TFT_WIDTH 480 + #define TFT_HEIGHT 320 + + #define titleHeight 36 // TFT_screen.title_high + #define INTERVAL_H 2 // TFT_screen.gap_h // 2 + #define INTERVAL_V 2 // TFT_screen.gap_v // 2 + #define BTN_X_PIXEL 117 // TFT_screen.btn_x_pixel + #define BTN_Y_PIXEL 140 // TFT_screen.btn_y_pixel + + #define SIMPLE_FIRST_PAGE_GRAP 30 + + #define BUTTON_TEXT_Y_OFFSET -20 + + #define TITLE_XPOS 3 // TFT_screen.title_xpos + #define TITLE_YPOS 5 // TFT_screen.title_ypos + + #define FILE_BTN_CNT 6 + + #define OTHER_BTN_XPIEL 117 + #define OTHER_BTN_YPIEL 92 + + #define FILE_PRE_PIC_X_OFFSET 8 + #define FILE_PRE_PIC_Y_OFFSET 0 + + #define PREVIEW_LITTLE_PIC_SIZE 40910 // 400*100+9*101+1 + #define PREVIEW_SIZE 202720 // (PREVIEW_LITTLE_PIC_SIZE+800*200+201*9+1) + + // machine parameter ui + #define PARA_UI_POS_X 10 + #define PARA_UI_POS_Y 50 + + #define PARA_UI_SIZE_X 450 + #define PARA_UI_SIZE_Y 40 + + #define PARA_UI_ARROW_V 12 + + #define PARA_UI_BACL_POS_X 400 + #define PARA_UI_BACL_POS_Y 270 + + #define PARA_UI_TURN_PAGE_POS_X 320 + #define PARA_UI_TURN_PAGE_POS_Y 270 + + #define PARA_UI_VALUE_SIZE_X 370 + #define PARA_UI_VALUE_POS_X 400 + #define PARA_UI_VALUE_V 5 + + #define PARA_UI_STATE_POS_X 380 + #define PARA_UI_STATE_V 2 + + #define PARA_UI_VALUE_SIZE_X_2 200 + #define PARA_UI_VALUE_POS_X_2 320 + #define PARA_UI_VALUE_V_2 5 + + #define PARA_UI_VALUE_BTN_X_SIZE 70 + #define PARA_UI_VALUE_BTN_Y_SIZE 28 + + #define PARA_UI_BACK_BTN_X_SIZE 70 + #define PARA_UI_BACK_BTN_Y_SIZE 40 + +#else // ifdef TFT35 + + #define TFT_WIDTH 320 + #define TFT_HEIGHT 240 + +#endif // ifdef TFT35 + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern char public_buf_m[100]; +extern char public_buf_l[30]; + +typedef struct { + uint32_t spi_flash_flag; + uint8_t disp_rotation_180; + uint8_t multiple_language; + uint8_t language; + uint8_t leveling_mode; + uint8_t from_flash_pic; + uint8_t finish_power_off; + uint8_t pause_reprint; + uint8_t wifi_mode_sel; + uint8_t fileSysType; + uint8_t wifi_type; + bool cloud_enable; + bool encoder_enable; + int levelingPos[5][2]; + int filamentchange_load_length; + int filamentchange_load_speed; + int filamentchange_unload_length; + int filamentchange_unload_speed; + int filament_limit_temper; + float pausePosX; + float pausePosY; + float pausePosZ; + uint32_t curFilesize; +} CFG_ITMES; + +typedef struct { + uint8_t curTempType : 1, + curSprayerChoose : 3, + stepHeat : 4; + uint8_t leveling_first_time : 1, + para_ui_page:1, + configWifi:1, + command_send:1, + filament_load_heat_flg:1, + filament_heat_completed_load:1, + filament_unload_heat_flg:1, + filament_heat_completed_unload:1; + uint8_t filament_loading_completed:1, + filament_unloading_completed:1, + filament_loading_time_flg:1, + filament_unloading_time_flg:1, + curSprayerChoose_bak:4; + uint8_t wifi_name[32]; + uint8_t wifi_key[64]; + uint8_t cloud_hostUrl[96]; + uint8_t extruStep; + uint8_t extruSpeed; + uint8_t print_state; + uint8_t stepPrintSpeed; + uint8_t waitEndMoves; + uint8_t dialogType; + uint8_t F[4]; + uint8_t filament_rate; + uint16_t moveSpeed; + uint16_t cloud_port; + uint16_t moveSpeed_bak; + uint32_t totalSend; + uint32_t filament_loading_time; + uint32_t filament_unloading_time; + uint32_t filament_loading_time_cnt; + uint32_t filament_unloading_time_cnt; + float move_dist; + float desireSprayerTempBak; + float current_x_position_bak; + float current_y_position_bak; + float current_e_position_bak; +} UI_CFG; + +typedef enum { + MAIN_UI, + PRINT_READY_UI, + PRINT_FILE_UI, + PRINTING_UI, + MOVE_MOTOR_UI, + OPERATE_UI, + PAUSE_UI, + EXTRUSION_UI, + FAN_UI, + PRE_HEAT_UI, + CHANGE_SPEED_UI, + TEMP_UI, + SET_UI, + ZERO_UI, + SPRAYER_UI, + MACHINE_UI, + LANGUAGE_UI, + ABOUT_UI, + LOG_UI, + DISK_UI, + CALIBRATE_UI, + DIALOG_UI, + WIFI_UI, + MORE_UI, + FILETRANSFER_UI, + FILETRANSFERSTATE_UI, + PRINT_MORE_UI, + FILAMENTCHANGE_UI, + LEVELING_UI, + MESHLEVELING_UI, + BIND_UI, + #if HAS_BED_PROBE + NOZZLE_PROBE_OFFSET_UI, + #endif + TOOL_UI, + HARDWARE_TEST_UI, + WIFI_LIST_UI, + KEY_BOARD_UI, + WIFI_TIPS_UI, + MACHINE_PARA_UI, + MACHINE_SETTINGS_UI, + TEMPERATURE_SETTINGS_UI, + MOTOR_SETTINGS_UI, + MACHINETYPE_UI, + STROKE_UI, + HOME_DIR_UI, + ENDSTOP_TYPE_UI, + FILAMENT_SETTINGS_UI, + LEVELING_SETTIGNS_UI, + LEVELING_PARA_UI, + DELTA_LEVELING_PARA_UI, + MANUAL_LEVELING_POSIGION_UI, + MAXFEEDRATE_UI, + STEPS_UI, + ACCELERATION_UI, + JERK_UI, + MOTORDIR_UI, + HOMESPEED_UI, + NOZZLE_CONFIG_UI, + HOTBED_CONFIG_UI, + ADVANCED_UI, + DOUBLE_Z_UI, + ENABLE_INVERT_UI, + NUMBER_KEY_UI, + BABY_STEP_UI, + ERROR_MESSAGE_UI, + PAUSE_POS_UI, + TMC_CURRENT_UI, + TMC_MODE_UI, + EEPROM_SETTINGS_UI, + WIFI_SETTINGS_UI, + HOMING_SENSITIVITY_UI, + ENCODER_SETTINGS_UI +} DISP_STATE; + +typedef struct { + DISP_STATE _disp_state[100]; + int _disp_index; +} DISP_STATE_STACK; + +typedef struct { + int16_t days; + uint16_t hours; + uint8_t minutes; + volatile int8_t seconds; + int8_t ms_10; + int8_t start; +} PRINT_TIME; +extern PRINT_TIME print_time; + +typedef enum { + PrintAcceleration, + RetractAcceleration, + TravelAcceleration, + XAcceleration, + YAcceleration, + ZAcceleration, + E0Acceleration, + E1Acceleration, + + XMaxFeedRate, + YMaxFeedRate, + ZMaxFeedRate, + E0MaxFeedRate, + E1MaxFeedRate, + + XJerk, + YJerk, + ZJerk, + EJerk, + + Xstep, + Ystep, + Zstep, + E0step, + E1step, + + Xcurrent, + Ycurrent, + Zcurrent, + E0current, + E1current, + + pause_pos_x, + pause_pos_y, + pause_pos_z, + + level_pos_x1, + level_pos_y1, + level_pos_x2, + level_pos_y2, + level_pos_x3, + level_pos_y3, + level_pos_x4, + level_pos_y4, + level_pos_x5, + level_pos_y5 + #if HAS_BED_PROBE + , + x_offset, + y_offset, + z_offset + #endif + , + load_length, + load_speed, + unload_length, + unload_speed, + filament_temp, + + x_sensitivity, + y_sensitivity, + z_sensitivity, + z2_sensitivity +} num_key_value_state; +extern num_key_value_state value; + +typedef enum { + wifiName, + wifiPassWord, + wifiConfig, + gcodeCommand +} keyboard_value_state; +extern keyboard_value_state keyboard_value; + +extern CFG_ITMES gCfgItems; +extern UI_CFG uiCfg; +extern DISP_STATE disp_state; +extern DISP_STATE last_disp_state; +extern DISP_STATE_STACK disp_state_stack; + +extern lv_style_t tft_style_scr; +extern lv_style_t tft_style_label_pre; +extern lv_style_t tft_style_label_rel; +extern lv_style_t style_line; +extern lv_style_t style_para_value_pre; +extern lv_style_t style_para_value_rel; +extern lv_style_t style_num_key_pre; +extern lv_style_t style_num_key_rel; +extern lv_style_t style_num_text; +extern lv_style_t style_sel_text; +extern lv_style_t style_para_value; +extern lv_style_t style_para_back; +extern lv_style_t lv_bar_style_indic; + +extern lv_point_t line_points[4][2]; + +extern void gCfgItems_init(); +extern void ui_cfg_init(); +extern void tft_style_init(); +extern char *creat_title_text(void); +extern void preview_gcode_prehandle(char *path); +extern void update_spi_flash(); +extern void update_gcode_command(int addr,uint8_t *s); +extern void get_gcode_command(int addr,uint8_t *d); +#if HAS_GCODE_PREVIEW + extern void disp_pre_gcode(int xpos_pixel, int ypos_pixel); +#endif +extern void GUI_RefreshPage(); +extern void clear_cur_ui(); +extern void draw_return_ui(); +extern void sd_detection(); +extern void gCfg_to_spiFlah(); +extern void print_time_count(); + +extern void LV_TASK_HANDLER(); +extern void lv_ex_line(lv_obj_t * line, lv_point_t *points); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi.cpp new file mode 100644 index 000000000000..9cf4555b25fe --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi.cpp @@ -0,0 +1,222 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" + +#if ENABLED(USE_WIFI_FUNCTION) + +#include "../../../../../Configuration.h" +#include "../../../../module/temperature.h" + +extern lv_group_t * g; +static lv_obj_t *scr, *wifi_name_text, *wifi_key_text, *wifi_state_text, *wifi_ip_text; + +#define ID_W_RETURN 1 +#define ID_W_CLOUD 2 +#define ID_W_RECONNECT 3 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_W_RETURN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + clear_cur_ui(); + lv_draw_set(); + } + break; + case ID_W_CLOUD: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + //clear_cur_ui(); + //draw_return_ui(); + } + break; + case ID_W_RECONNECT: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + clear_cur_ui(); + lv_draw_wifi_list(); + } + break; + } +} + +void lv_draw_wifi(void) { + lv_obj_t *buttonBack=NULL,*label_Back=NULL; + lv_obj_t *buttonCloud=NULL,*label_Cloud=NULL; + lv_obj_t *buttonReconnect=NULL,*label_Reconnect=NULL; + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != WIFI_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = WIFI_UI; + } + disp_state = WIFI_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title,TITLE_XPOS,TITLE_YPOS); + lv_label_set_text(title, creat_title_text()); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + // Create an Image button + buttonBack = lv_imgbtn_create(scr, NULL); + if (gCfgItems.wifi_mode_sel == STA_MODEL) { + //buttonCloud = lv_imgbtn_create(scr, NULL); + buttonReconnect = lv_imgbtn_create(scr, NULL); + } + + lv_obj_set_event_cb_mks(buttonBack, event_handler,ID_W_RETURN, NULL,0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_return.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_return.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonBack); + #endif + + lv_obj_set_pos(buttonBack,BTN_X_PIXEL*3+INTERVAL_V*4, BTN_Y_PIXEL+INTERVAL_H+titleHeight); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + + if (gCfgItems.wifi_mode_sel == STA_MODEL) { + + lv_obj_set_event_cb_mks(buttonReconnect, event_handler,ID_W_RECONNECT, NULL,0); + lv_imgbtn_set_src(buttonReconnect, LV_BTN_STATE_REL, "F:/bmp_wifi.bin"); + lv_imgbtn_set_src(buttonReconnect, LV_BTN_STATE_PR, "F:/bmp_wifi.bin"); + lv_imgbtn_set_style(buttonReconnect, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonReconnect, LV_BTN_STATE_REL, &tft_style_label_rel); + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonReconnect); + #endif + + lv_obj_set_pos(buttonReconnect,BTN_X_PIXEL*2+INTERVAL_V*3, BTN_Y_PIXEL+INTERVAL_H+titleHeight); + lv_btn_set_layout(buttonReconnect, LV_LAYOUT_OFF); + } + + label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.wifi_mode_sel == STA_MODEL) { + //label_Cloud = lv_label_create(buttonCloud, NULL); + label_Reconnect = lv_label_create(buttonReconnect, NULL); + } + + if (gCfgItems.multiple_language !=0) { + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_IN_BOTTOM_MID,0, BUTTON_TEXT_Y_OFFSET); + + if (gCfgItems.wifi_mode_sel == STA_MODEL) { + //lv_label_set_text(label_Cloud, common_menu.text_back); + //lv_obj_align(label_Cloud, buttonCloud, LV_ALIGN_IN_BOTTOM_MID,0, BUTTON_TEXT_Y_OFFSET); + + lv_label_set_text(label_Reconnect, wifi_menu.reconnect); + lv_obj_align(label_Reconnect, buttonReconnect, LV_ALIGN_IN_BOTTOM_MID,0, BUTTON_TEXT_Y_OFFSET); + } + } + + wifi_ip_text = lv_label_create(scr, NULL); + lv_obj_set_style(wifi_ip_text, &tft_style_label_rel); + + wifi_name_text = lv_label_create(scr, NULL); + lv_obj_set_style(wifi_name_text, &tft_style_label_rel); + + wifi_key_text = lv_label_create(scr, NULL); + lv_obj_set_style(wifi_key_text, &tft_style_label_rel); + + wifi_state_text = lv_label_create(scr, NULL); + lv_obj_set_style(wifi_state_text, &tft_style_label_rel); + + disp_wifi_state(); +} + +void disp_wifi_state() { + memset(public_buf_m, 0, sizeof(public_buf_m)); + strcpy(public_buf_m,wifi_menu.ip); + strcat(public_buf_m,ipPara.ip_addr); + lv_label_set_text(wifi_ip_text, public_buf_m); + lv_obj_align(wifi_ip_text, NULL, LV_ALIGN_CENTER,0, -100); + + memset(public_buf_m, 0, sizeof(public_buf_m)); + strcpy(public_buf_m,wifi_menu.wifi); + strcat(public_buf_m,wifiPara.ap_name); + lv_label_set_text(wifi_name_text, public_buf_m); + lv_obj_align(wifi_name_text, NULL, LV_ALIGN_CENTER,0, -70); + + if (wifiPara.mode == AP_MODEL) { + memset(public_buf_m, 0, sizeof(public_buf_m)); + strcpy(public_buf_m,wifi_menu.key); + strcat(public_buf_m,wifiPara.keyCode); + lv_label_set_text(wifi_key_text, public_buf_m); + lv_obj_align(wifi_key_text, NULL, LV_ALIGN_CENTER,0, -40); + + memset(public_buf_m, 0, sizeof(public_buf_m)); + strcpy(public_buf_m,wifi_menu.state_ap); + if (wifi_link_state == WIFI_CONNECTED) + strcat(public_buf_m,wifi_menu.connected); + else if (wifi_link_state == WIFI_NOT_CONFIG) + strcat(public_buf_m,wifi_menu.disconnected); + else + strcat(public_buf_m,wifi_menu.exception); + lv_label_set_text(wifi_state_text, public_buf_m); + lv_obj_align(wifi_state_text, NULL, LV_ALIGN_CENTER,0, -10); + } + else { + ZERO(public_buf_m); + strcpy(public_buf_m, wifi_menu.state_sta); + if (wifi_link_state == WIFI_CONNECTED) + strcat(public_buf_m, wifi_menu.connected); + else if (wifi_link_state == WIFI_NOT_CONFIG) + strcat(public_buf_m, wifi_menu.disconnected); + else + strcat(public_buf_m, wifi_menu.exception); + lv_label_set_text(wifi_state_text, public_buf_m); + lv_obj_align(wifi_state_text, NULL, LV_ALIGN_CENTER,0, -40); + + lv_label_set_text(wifi_key_text, ""); + lv_obj_align(wifi_key_text, NULL, LV_ALIGN_CENTER,0, -10); + } +} + +void lv_clear_wifi() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // USE_WIFI_FUNCTION +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi.h new file mode 100644 index 000000000000..966a84d3b19b --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi.h @@ -0,0 +1,38 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + + +extern void lv_draw_wifi(void); +extern void lv_clear_wifi(); +extern void disp_wifi_state(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif + + + diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_list.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_list.cpp new file mode 100644 index 000000000000..14fd63f85282 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_list.cpp @@ -0,0 +1,235 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" + +#if ENABLED(USE_WIFI_FUNCTION) + +#include "../../../../../Configuration.h" +#include "../../../../module/temperature.h" + +#define NAME_BTN_X 330 +#define NAME_BTN_Y 48 + +#define MARK_BTN_X 0 +#define MARK_BTN_Y 68 + +WIFI_LIST wifi_list; +list_menu_def list_menu; + +extern lv_group_t * g; +static lv_obj_t * scr; +static lv_obj_t *buttonWifiN[NUMBER_OF_PAGE]; +static lv_obj_t *lableWifiText[NUMBER_OF_PAGE]; +static lv_obj_t *lablePageText; + +#define ID_WL_RETURN 11 +#define ID_WL_DOWN 12 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + if (obj->mks_obj_id == ID_WL_RETURN) { + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + clear_cur_ui(); + lv_draw_set(); + } + } + else if (obj->mks_obj_id == ID_WL_DOWN) { + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (wifi_list.getNameNum > 0) { + if ((wifi_list.nameIndex + NUMBER_OF_PAGE) >= wifi_list.getNameNum) { + wifi_list.nameIndex = 0; + wifi_list.currentWifipage = 1; + } + else { + wifi_list.nameIndex += NUMBER_OF_PAGE; + wifi_list.currentWifipage++; + } + disp_wifi_list(); + } + } + } + else { + for (uint8_t i = 0; i < NUMBER_OF_PAGE; i++) { + if (obj->mks_obj_id == i + 1) { + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (wifi_list.getNameNum != 0) { + const bool do_wifi = wifi_link_state == WIFI_CONNECTED && strcmp((const char *)wifi_list.wifiConnectedName, (const char *)wifi_list.wifiName[wifi_list.nameIndex + i]) == 0; + wifi_list.nameIndex += i; + last_disp_state = WIFI_LIST_UI; + lv_clear_wifi_list(); + if (do_wifi) + lv_draw_wifi(); + else { + keyboard_value = wifiConfig; + lv_draw_keyboard(); + } + } + } + } + } + } +} + +void lv_draw_wifi_list(void) { + lv_obj_t *buttonBack = NULL, *buttonDown = NULL; + + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != WIFI_LIST_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = WIFI_LIST_UI; + } + disp_state = WIFI_LIST_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title,TITLE_XPOS,TITLE_YPOS); + lv_label_set_text(title, creat_title_text()); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + buttonDown = lv_imgbtn_create(scr, NULL); + buttonBack = lv_imgbtn_create(scr, NULL); + + lv_obj_set_event_cb_mks(buttonDown, event_handler,ID_WL_DOWN,NULL,0); + lv_imgbtn_set_src(buttonDown, LV_BTN_STATE_REL, "F:/bmp_pageDown.bin"); + lv_imgbtn_set_src(buttonDown, LV_BTN_STATE_PR, "F:/bmp_pageDown.bin"); + lv_imgbtn_set_style(buttonDown, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonDown, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_event_cb_mks(buttonBack, event_handler,ID_WL_RETURN,NULL,0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_back.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_back.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + + lv_obj_set_pos(buttonDown,OTHER_BTN_XPIEL*3+INTERVAL_V*4,titleHeight+OTHER_BTN_YPIEL+INTERVAL_H); + lv_obj_set_pos(buttonBack,OTHER_BTN_XPIEL*3+INTERVAL_V*4,titleHeight+OTHER_BTN_YPIEL*2+INTERVAL_H*2); + + lv_btn_set_layout(buttonDown, LV_LAYOUT_OFF); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + + for (uint8_t i = 0; i < NUMBER_OF_PAGE; i++) { + buttonWifiN[i] = lv_btn_create(scr, NULL); /*Add a button the current screen*/ + lv_obj_set_pos(buttonWifiN[i], 0,NAME_BTN_Y*i+10+titleHeight); /*Set its position*/ + lv_obj_set_size(buttonWifiN[i], NAME_BTN_X,NAME_BTN_Y); /*Set its size*/ + lv_obj_set_event_cb_mks(buttonWifiN[i], event_handler,(i+1),NULL,0); + lv_btn_set_style(buttonWifiN[i], LV_BTN_STYLE_REL, &tft_style_label_rel); /*Set the button's released style*/ + lv_btn_set_style(buttonWifiN[i], LV_BTN_STYLE_PR, &tft_style_label_pre); /*Set the button's pressed style*/ + lv_btn_set_layout(buttonWifiN[i], LV_LAYOUT_OFF); + lableWifiText[i] = lv_label_create(buttonWifiN[i], NULL); + #if HAS_ROTARY_ENCODER + uint8_t j = 0; + if (gCfgItems.encoder_enable) { + j = wifi_list.nameIndex + i; + if (j < wifi_list.getNameNum) lv_group_add_obj(g, buttonWifiN[i]); + } + #endif + } + + lablePageText = lv_label_create(scr, NULL); + lv_obj_set_style(lablePageText, &tft_style_label_rel); + + wifi_list.nameIndex = 0; + wifi_list.currentWifipage = 1; + + if (wifi_link_state == WIFI_CONNECTED && wifiPara.mode == STA_MODEL) { + memset(wifi_list.wifiConnectedName, 0, sizeof(&wifi_list.wifiConnectedName)); + memcpy(wifi_list.wifiConnectedName, wifiPara.ap_name, sizeof(wifi_list.wifiConnectedName)); + } + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonDown); + lv_group_add_obj(g, buttonBack); + } + #endif + + disp_wifi_list(); +} + +void disp_wifi_list(void) { + int8_t tmpStr[WIFI_NAME_BUFFER_SIZE] = { 0 }; + uint8_t i, j; + + sprintf((char *)tmpStr, list_menu.file_pages, wifi_list.currentWifipage, wifi_list.getPage); + lv_label_set_text(lablePageText, (const char *)tmpStr); + lv_obj_align(lablePageText, NULL, LV_ALIGN_CENTER, 50, -100); + + for (i = 0; i < NUMBER_OF_PAGE; i++) { + memset(tmpStr, 0, sizeof(tmpStr)); + + j = wifi_list.nameIndex + i; + if (j >= wifi_list.getNameNum) { + lv_label_set_text(lableWifiText[i], (const char *)tmpStr); + lv_obj_align(lableWifiText[i], buttonWifiN[i], LV_ALIGN_IN_LEFT_MID, 20, 0); + } + else { + lv_label_set_text(lableWifiText[i], (char const *)wifi_list.wifiName[j]); + lv_obj_align(lableWifiText[i], buttonWifiN[i], LV_ALIGN_IN_LEFT_MID, 20, 0); + + if (wifi_link_state == WIFI_CONNECTED && strcmp((const char *)wifi_list.wifiConnectedName, (const char *)wifi_list.wifiName[j]) == 0) { + lv_btn_set_style(buttonWifiN[i], LV_BTN_STYLE_REL, &style_sel_text); + } + else { + lv_btn_set_style(buttonWifiN[i], LV_BTN_STYLE_REL, &tft_style_label_rel); + } + } + } +} + +void wifi_scan_handle() { + if (uiCfg.dialogType != WIFI_ENABLE_TIPS || uiCfg.command_send != 1) return; + last_disp_state = DIALOG_UI; + lv_clear_dialog(); + if (wifi_link_state == WIFI_CONNECTED && wifiPara.mode != AP_MODEL) + lv_draw_wifi(); + else + lv_draw_wifi_list(); +} + +void lv_clear_wifi_list() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // USE_WIFI_FUNCTION + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_list.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_list.h new file mode 100644 index 000000000000..e2d9275ef918 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_list.h @@ -0,0 +1,76 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_wifi_list(); +extern void lv_clear_wifi_list(); +extern void disp_wifi_list(void); +extern void cutWifiName(char *name, int len,char *outStr); +extern void wifi_scan_handle(); + +#define NUMBER_OF_PAGE 5 + +#define WIFI_TOTAL_NUMBER 20 +#define WIFI_NAME_BUFFER_SIZE 33 + +typedef struct { + int8_t getNameNum; + int8_t nameIndex; + int8_t currentWifipage; + int8_t getPage; + int8_t RSSI[WIFI_TOTAL_NUMBER]; + uint8_t wifiName[WIFI_TOTAL_NUMBER][WIFI_NAME_BUFFER_SIZE]; + uint8_t wifiConnectedName[WIFI_NAME_BUFFER_SIZE]; +} WIFI_LIST; +extern WIFI_LIST wifi_list; + +typedef struct list_menu_disp { + const char *title; + const char *file_pages; +} list_menu_def; +extern list_menu_def list_menu; + +typedef struct keyboard_menu_disp { + const char *title; + const char *apply; + const char *password; + const char *letter; + const char *digital; + const char *symbol; + const char *space; +} keyboard_menu_def; +extern keyboard_menu_def keyboard_menu; + +typedef struct tips_menu_disp { + const char *joining; + const char *failedJoin; + const char *wifiConected; +} tips_menu_def; +extern tips_menu_def tips_menu; + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_settings.cpp new file mode 100644 index 000000000000..86733470ddbb --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_settings.cpp @@ -0,0 +1,299 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" + +#if ENABLED(USE_WIFI_FUNCTION) + +#include "../../../../../Configuration.h" +#include "../../../../module/planner.h" + +extern lv_group_t * g; +static lv_obj_t *scr, *labelModelValue = NULL, *buttonModelValue = NULL, *labelCloudValue = NULL; + +#define ID_WIFI_RETURN 1 +#define ID_WIFI_MODEL 2 +#define ID_WIFI_NAME 3 +#define ID_WIFI_PASSWORD 4 +#define ID_WIFI_CLOUD 5 +#define ID_WIFI_CONFIG 6 + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + switch (obj->mks_obj_id) { + case ID_WIFI_RETURN: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_wifi_settings(); + draw_return_ui(); + } + break; + case ID_WIFI_MODEL: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (gCfgItems.wifi_mode_sel == AP_MODEL) { + gCfgItems.wifi_mode_sel = STA_MODEL; + lv_label_set_text(labelModelValue, WIFI_STA_TEXT); + lv_obj_align(labelModelValue, buttonModelValue, LV_ALIGN_CENTER,0, 0); + update_spi_flash(); + } + else{ + gCfgItems.wifi_mode_sel = AP_MODEL; + lv_label_set_text(labelModelValue, WIFI_AP_TEXT); + lv_obj_align(labelModelValue, buttonModelValue, LV_ALIGN_CENTER,0, 0); + update_spi_flash(); + } + } + break; + case ID_WIFI_NAME: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + keyboard_value=wifiName; + lv_clear_wifi_settings(); + lv_draw_keyboard(); + } + break; + case ID_WIFI_PASSWORD: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + keyboard_value=wifiPassWord; + lv_clear_wifi_settings(); + lv_draw_keyboard(); + } + break; + case ID_WIFI_CLOUD: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + if (gCfgItems.cloud_enable) { + gCfgItems.cloud_enable = false; + lv_obj_set_event_cb_mks(obj, event_handler,ID_WIFI_CLOUD,"bmp_disable.bin",0); + lv_label_set_text(labelCloudValue, machine_menu.disable); + update_spi_flash(); + } + else { + gCfgItems.cloud_enable = true; + lv_obj_set_event_cb_mks(obj, event_handler,ID_WIFI_CLOUD,"bmp_enable.bin",0); + lv_label_set_text(labelCloudValue, machine_menu.enable); + update_spi_flash(); + } + } + break; + case ID_WIFI_CONFIG: + if (event == LV_EVENT_CLICKED) { + + } + else if (event == LV_EVENT_RELEASED) { + lv_clear_wifi_settings(); + lv_draw_dialog(DIALOG_WIFI_CONFIG_TIPS); + } + break; + } +} + +void lv_draw_wifi_settings(void) { + lv_obj_t *buttonBack = NULL, *label_Back = NULL, *buttonConfig = NULL, *labelConfig = NULL; + lv_obj_t *labelModelText = NULL; + lv_obj_t *labelNameText = NULL, *buttonNameValue = NULL, *labelNameValue = NULL; + lv_obj_t *labelPassWordText = NULL, *buttonPassWordValue = NULL, *labelPassWordValue = NULL; + lv_obj_t *labelCloudText = NULL, *buttonCloudValue = NULL; + lv_obj_t * line1 = NULL, *line2 = NULL, *line3 = NULL, *line4 = NULL; + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != WIFI_SETTINGS_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = WIFI_SETTINGS_UI; + } + disp_state = WIFI_SETTINGS_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + + lv_obj_t * title = lv_label_create(scr, NULL); + lv_obj_set_style(title, &tft_style_label_rel); + lv_obj_set_pos(title,TITLE_XPOS,TITLE_YPOS); + lv_label_set_text(title, machine_menu.WifiConfTitle); + + lv_refr_now(lv_refr_get_disp_refreshing()); + + labelModelText = lv_label_create(scr, NULL); + lv_obj_set_style(labelModelText, &tft_style_label_rel); + lv_obj_set_pos(labelModelText, PARA_UI_POS_X, PARA_UI_POS_Y + 10); + lv_label_set_text(labelModelText, machine_menu.wifiMode); + + buttonModelValue = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonModelValue,PARA_UI_VALUE_POS_X,PARA_UI_POS_Y+PARA_UI_VALUE_V); + lv_obj_set_event_cb_mks(buttonModelValue, event_handler,ID_WIFI_MODEL, NULL,0); + lv_imgbtn_set_src(buttonModelValue, LV_BTN_STATE_REL, "F:/bmp_blank_sel.bin"); + lv_imgbtn_set_src(buttonModelValue, LV_BTN_STATE_PR, "F:/bmp_blank_sel.bin"); + lv_imgbtn_set_style(buttonModelValue, LV_BTN_STATE_PR, &style_para_value_pre); + lv_imgbtn_set_style(buttonModelValue, LV_BTN_STATE_REL, &style_para_value_pre); + lv_btn_set_layout(buttonModelValue, LV_LAYOUT_OFF); + labelModelValue = lv_label_create(buttonModelValue, NULL); + + line1 = lv_line_create(scr, NULL); + lv_ex_line(line1,line_points[0]); + + labelNameText = lv_label_create(scr, NULL); + lv_obj_set_style(labelNameText, &tft_style_label_rel); + lv_obj_set_pos(labelNameText, PARA_UI_POS_X, PARA_UI_POS_Y * 2 + 10); + + buttonNameValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonNameValue,PARA_UI_VALUE_POS_X,PARA_UI_POS_Y*2+PARA_UI_VALUE_V); + lv_obj_set_size(buttonNameValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonNameValue, event_handler,ID_WIFI_NAME, NULL,0); + lv_btn_set_style(buttonNameValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonNameValue, LV_BTN_STYLE_PR, &style_para_value); + labelNameValue = lv_label_create(buttonNameValue, NULL); + + line2 = lv_line_create(scr, NULL); + lv_ex_line(line2,line_points[1]); + + labelPassWordText = lv_label_create(scr, NULL); + lv_obj_set_style(labelPassWordText, &tft_style_label_rel); + lv_obj_set_pos(labelPassWordText, PARA_UI_POS_X, PARA_UI_POS_Y * 3 + 10); + + buttonPassWordValue = lv_btn_create(scr, NULL); + lv_obj_set_pos(buttonPassWordValue,PARA_UI_VALUE_POS_X,PARA_UI_POS_Y*3+PARA_UI_VALUE_V); + lv_obj_set_size(buttonPassWordValue, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE); + lv_obj_set_event_cb_mks(buttonPassWordValue, event_handler,ID_WIFI_PASSWORD, NULL,0); + lv_btn_set_style(buttonPassWordValue, LV_BTN_STYLE_REL, &style_para_value); + lv_btn_set_style(buttonPassWordValue, LV_BTN_STYLE_PR, &style_para_value); + labelPassWordValue = lv_label_create(buttonPassWordValue, NULL); + + line3 = lv_line_create(scr, NULL); + lv_ex_line(line3,line_points[2]); + + labelCloudText = lv_label_create(scr, NULL); + lv_obj_set_style(labelCloudText, &tft_style_label_rel); + lv_obj_set_pos(labelCloudText, PARA_UI_POS_X, PARA_UI_POS_Y * 4 + 10); + lv_label_set_text(labelCloudText, machine_menu.wifiCloud); + + buttonCloudValue = lv_imgbtn_create(scr, NULL); + lv_obj_set_pos(buttonCloudValue,PARA_UI_STATE_POS_X,PARA_UI_POS_Y*4+PARA_UI_STATE_V); + if (gCfgItems.cloud_enable) { + lv_imgbtn_set_src(buttonCloudValue, LV_BTN_STATE_REL, "F:/bmp_enable.bin"); + lv_imgbtn_set_src(buttonCloudValue, LV_BTN_STATE_PR, "F:/bmp_enable.bin"); + } + else { + lv_imgbtn_set_src(buttonCloudValue, LV_BTN_STATE_REL, "F:/bmp_disable.bin"); + lv_imgbtn_set_src(buttonCloudValue, LV_BTN_STATE_PR, "F:/bmp_disable.bin"); + } + lv_obj_set_event_cb_mks(buttonCloudValue, event_handler,ID_WIFI_CLOUD, NULL,0); + lv_imgbtn_set_style(buttonCloudValue, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonCloudValue, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_btn_set_layout(buttonCloudValue, LV_LAYOUT_OFF); + labelCloudValue = lv_label_create(buttonCloudValue, NULL); + + line4 = lv_line_create(scr, NULL); + lv_ex_line(line4,line_points[3]); + + buttonConfig = lv_imgbtn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonConfig, event_handler,ID_WIFI_CONFIG, NULL,0); + lv_imgbtn_set_src(buttonConfig, LV_BTN_STATE_REL, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_src(buttonConfig, LV_BTN_STATE_PR, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_style(buttonConfig, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonConfig, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_obj_set_pos(buttonConfig, PARA_UI_TURN_PAGE_POS_X, PARA_UI_TURN_PAGE_POS_Y); + lv_btn_set_layout(buttonConfig, LV_LAYOUT_OFF); + labelConfig = lv_label_create(buttonConfig, NULL); + + buttonBack = lv_imgbtn_create(scr, NULL); + lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_WIFI_RETURN, NULL, 0); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_REL, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_src(buttonBack, LV_BTN_STATE_PR, "F:/bmp_back70x40.bin"); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_PR, &tft_style_label_pre); + lv_imgbtn_set_style(buttonBack, LV_BTN_STATE_REL, &tft_style_label_rel); + lv_obj_set_pos(buttonBack, PARA_UI_BACL_POS_X, PARA_UI_BACL_POS_Y); + lv_btn_set_layout(buttonBack, LV_LAYOUT_OFF); + label_Back = lv_label_create(buttonBack, NULL); + + if (gCfgItems.multiple_language !=0) { + if (gCfgItems.wifi_mode_sel == AP_MODEL) { + lv_label_set_text(labelModelValue, WIFI_AP_TEXT); + lv_obj_align(labelModelValue, buttonModelValue, LV_ALIGN_CENTER,0, 0); + } + else { + lv_label_set_text(labelModelValue, WIFI_STA_TEXT); + lv_obj_align(labelModelValue, buttonModelValue, LV_ALIGN_CENTER,0, 0); + } + memset(public_buf_m,0,sizeof(public_buf_m)); + strcat(public_buf_m,machine_menu.wifiName); + strcat(public_buf_m,(const char *)uiCfg.wifi_name); + lv_label_set_text(labelNameText,public_buf_m); + + lv_label_set_text(labelNameValue,machine_menu.wifiEdit); + lv_obj_align(labelNameValue, buttonNameValue, LV_ALIGN_CENTER,0, 0); + + memset(public_buf_m,0,sizeof(public_buf_m)); + strcat(public_buf_m,machine_menu.wifiPassWord); + strcat(public_buf_m,(const char *)uiCfg.wifi_key); + lv_label_set_text(labelPassWordText,public_buf_m); + + lv_label_set_text(labelPassWordValue,machine_menu.wifiEdit); + lv_obj_align(labelPassWordValue, buttonPassWordValue, LV_ALIGN_CENTER,0, 0); + + lv_label_set_text(labelCloudValue, gCfgItems.cloud_enable ? machine_menu.enable : machine_menu.disable); + lv_obj_align(labelCloudValue, buttonCloudValue, LV_ALIGN_CENTER,0, 0); + + lv_label_set_text(labelConfig,machine_menu.wifiConfig); + lv_obj_align(labelConfig, buttonConfig, LV_ALIGN_CENTER,0, 0); + + lv_label_set_text(label_Back, common_menu.text_back); + lv_obj_align(label_Back, buttonBack, LV_ALIGN_CENTER,0, 0); + } + + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) { + lv_group_add_obj(g, buttonModelValue); + lv_group_add_obj(g, buttonNameValue); + lv_group_add_obj(g, buttonPassWordValue); + lv_group_add_obj(g, buttonCloudValue); + lv_group_add_obj(g, buttonConfig); + lv_group_add_obj(g, buttonBack); + } + #endif +} + +void lv_clear_wifi_settings() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // USE_WIFI_FUNCTION + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_settings.h new file mode 100644 index 000000000000..c0d6e0ccdd78 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_settings.h @@ -0,0 +1,36 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +#define WIFI_AP_TEXT "AP" +#define WIFI_STA_TEXT "STA" + +extern void lv_draw_wifi_settings(void); +extern void lv_clear_wifi_settings(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_tips.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_tips.cpp new file mode 100644 index 000000000000..50fa0aaf99c7 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_tips.cpp @@ -0,0 +1,85 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "lv_conf.h" +#include "draw_ui.h" + +#if ENABLED(USE_WIFI_FUNCTION) + +#include "../../../../../Configuration.h" +#include "../../../../module/temperature.h" + +static lv_obj_t * scr; + +TIPS_TYPE wifi_tips_type; +TIPS_DISP tips_disp; +tips_menu_def tips_menu; + +void lv_draw_wifi_tips(void) { + static lv_obj_t * text_tips,*wifi_name; + + if (disp_state_stack._disp_state[disp_state_stack._disp_index] != WIFI_TIPS_UI) { + disp_state_stack._disp_index++; + disp_state_stack._disp_state[disp_state_stack._disp_index] = WIFI_TIPS_UI; + } + disp_state = WIFI_TIPS_UI; + + scr = lv_obj_create(NULL, NULL); + + lv_obj_set_style(scr, &tft_style_scr); + lv_scr_load(scr); + lv_obj_clean(scr); + lv_refr_now(lv_refr_get_disp_refreshing()); + + text_tips = lv_label_create(scr, NULL); + lv_obj_set_style(text_tips, &tft_style_label_rel); + + wifi_name = lv_label_create(scr, NULL); + lv_obj_set_style(wifi_name, &tft_style_label_rel); + + if (wifi_tips_type == TIPS_TYPE_JOINING) { + lv_label_set_text(text_tips, tips_menu.joining); + lv_obj_align(text_tips, NULL, LV_ALIGN_CENTER,0, -60); + } + else if (wifi_tips_type == TIPS_TYPE_TAILED_JOIN) { + lv_label_set_text(text_tips, tips_menu.failedJoin); + lv_obj_align(text_tips, NULL, LV_ALIGN_CENTER,0, -60); + } + else if (wifi_tips_type == TIPS_TYPE_WIFI_CONECTED) { + lv_label_set_text(text_tips, tips_menu.wifiConected); + lv_obj_align(text_tips, NULL, LV_ALIGN_CENTER,0, -60); + } + + lv_label_set_text(wifi_name, (const char *)wifi_list.wifiName[wifi_list.nameIndex]); + lv_obj_align(wifi_name, NULL, LV_ALIGN_CENTER,0, -20); + + tips_disp.timer = TIPS_TIMER_START; + tips_disp.timer_count = 0; +} + +void lv_clear_wifi_tips() { lv_obj_del(scr); } + +#endif // USE_WIFI_FUNCTION +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_tips.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_tips.h new file mode 100644 index 000000000000..4f81f00a434d --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_tips.h @@ -0,0 +1,51 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + + +extern void lv_draw_wifi_tips(void); +extern void lv_clear_wifi_tips(); + +typedef enum { + TIPS_TYPE_JOINING, + TIPS_TYPE_TAILED_JOIN, + TIPS_TYPE_WIFI_CONECTED +} TIPS_TYPE; +extern TIPS_TYPE wifi_tips_type; + +typedef struct { + unsigned char timer; + unsigned int timer_count; +} TIPS_DISP; +extern TIPS_DISP tips_disp; + +#define TIPS_TIMER_START 1 +#define TIPS_TIMER_STOP 0 + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif + diff --git a/Marlin/src/lcd/extui/lib/mks_ui/gb2312_puhui16.cpp b/Marlin/src/lcd/extui/lib/mks_ui/gb2312_puhui16.cpp new file mode 100644 index 000000000000..856d645e9ed4 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/gb2312_puhui16.cpp @@ -0,0 +1,115 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "pic_manager.h" +#include + +#include "../../../../inc/MarlinConfig.h" + +#if HAS_SPI_FLASH_FONT + +typedef struct { + uint16_t min; + uint16_t max; + uint8_t bpp; + uint8_t reserved[3]; +} x_header_t; + +typedef struct { + uint32_t pos; +} x_table_t; + +typedef struct { + uint8_t adv_w; + uint8_t box_w; +} glyph_dsc_t; + +static x_header_t __g_xbf_hd = { .min = 0, .max = 0, .bpp = 0 }; +static uint8_t __g_font_buf[63]; + +static uint8_t *__user_font_getdata(int offset, int size) { + //ZERO(__g_font_buf); + get_spi_flash_data((char *)__g_font_buf, offset, size); + return __g_font_buf; + //return &buf_test[offset]; +} + +static const uint8_t * __user_font_get_bitmap(const lv_font_t * font, uint32_t unicode_letter) { + if (__g_xbf_hd.max == 0) { + uint8_t *p = __user_font_getdata(0, sizeof(x_header_t)); + memcpy(&__g_xbf_hd, p, sizeof(x_header_t)); + } + if (unicode_letter > __g_xbf_hd.max || unicode_letter < __g_xbf_hd.min) + return NULL; + uint32_t unicode_offset = sizeof(x_header_t) + (unicode_letter - __g_xbf_hd.min) * 4; + uint32_t *p_pos = (uint32_t *)__user_font_getdata(unicode_offset, 4); + if (p_pos[0] != 0) { + uint32_t pos = p_pos[0]; + //glyph_dsc_t * gdsc = (glyph_dsc_t*)__user_font_getdata(pos, 2); + __user_font_getdata(pos, 2); + //return __user_font_getdata(pos+2, gdsc->box_w*__g_xbf_hd.bpp/8); + return __user_font_getdata(pos + 2, sizeof(__g_font_buf)); + } + return NULL; +} + +static bool __user_font_get_glyph_dsc(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next) { + if (__g_xbf_hd.max == 0) { + uint8_t *p = __user_font_getdata(0, sizeof(x_header_t)); + memcpy(&__g_xbf_hd, p, sizeof(x_header_t)); + } + if (unicode_letter > __g_xbf_hd.max || unicode_letter < __g_xbf_hd.min) + return NULL; + uint32_t unicode_offset = sizeof(x_header_t) + (unicode_letter - __g_xbf_hd.min) * 4; + uint32_t *p_pos = (uint32_t *)__user_font_getdata(unicode_offset, 4); + if (p_pos[0] != 0) { + glyph_dsc_t * gdsc = (glyph_dsc_t*)__user_font_getdata(p_pos[0], 2); + dsc_out->adv_w = gdsc->adv_w; + dsc_out->box_h = font->line_height; + dsc_out->box_w = gdsc->box_w; + dsc_out->ofs_x = 0; + dsc_out->ofs_y = 0; + dsc_out->bpp = __g_xbf_hd.bpp; + return true; + } + return false; +} + +/*lv_font_t gb2312_puhui32 = { +.get_glyph_bitmap = __user_font_get_bitmap, +.get_glyph_dsc = __user_font_get_glyph_dsc, +.line_height = 25, +.base_line = 0, +};*/ +lv_font_t gb2312_puhui32; +void init_gb2312_font() { + gb2312_puhui32.get_glyph_bitmap = __user_font_get_bitmap; + gb2312_puhui32.get_glyph_dsc = __user_font_get_glyph_dsc; + gb2312_puhui32.line_height = 21; + gb2312_puhui32.base_line = 0; +} + +#endif // HAS_SPI_FLASH_FONT +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/irq_overrid.cpp b/Marlin/src/lcd/extui/lib/mks_ui/irq_overrid.cpp new file mode 100644 index 000000000000..cf64571292bf --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/irq_overrid.cpp @@ -0,0 +1,69 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "draw_ui.h" + +#if ENABLED(USE_WIFI_FUNCTION) + +#include "wifiSerial.h" + +#include +#include +#include +#include +#include + +#include "../../../../inc/MarlinConfig.h" + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +#define WIFI_IO1_SET() WRITE(WIFI_IO1_PIN, HIGH); +#define WIFI_IO1_RESET() WRITE(WIFI_IO1_PIN, LOW); + +void __irq_usart1(void) { + WIFISERIAL.wifi_usart_irq(USART1_BASE); + if (wifi_link_state == WIFI_TRANS_FILE) { + if (WIFISERIAL.available() == (400)) WIFI_IO1_SET(); + if (WIFISERIAL.wifi_rb_is_full()) { + if (esp_state == TRANSFER_IDLE) esp_state = TRANSFERING; + if (storeRcvData(UART_RX_BUFFER_SIZE)) { + if (wifiTransError.flag != 0x1) WIFI_IO1_RESET(); + } + else { + WIFI_IO1_SET(); + esp_state = TRANSFER_STORE; + } + } + } +} + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif + +#endif // USE_WIFI_FUNCTION +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/mks_hardware_test.cpp b/Marlin/src/lcd/extui/lib/mks_ui/mks_hardware_test.cpp new file mode 100644 index 000000000000..bc329aa82b89 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/mks_hardware_test.cpp @@ -0,0 +1,665 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "SPI_TFT.h" + +#include "tft_lvgl_configuration.h" +#include "draw_ready_print.h" +#include "mks_hardware_test.h" +#include "draw_ui.h" +#include "pic_manager.h" +#include + +#include "../../../../MarlinCore.h" +#include "../../../../module/temperature.h" +#include "../../../../sd/cardreader.h" + +uint8_t pw_det_sta, pw_off_sta, mt_det_sta, mt_det3_sta; +#if PIN_EXISTS(MT_DET_2) + uint8_t mt_det2_sta; +#endif +uint8_t endstopx1_sta, endstopx2_sta, endstopy1_sta, endstopy2_sta, endstopz1_sta, endstopz2_sta; +void test_gpio_readlevel_L() { + #if ENABLED(MKS_TEST) + volatile uint32_t itest; + WRITE(WIFI_IO0_PIN, HIGH); + itest = 10000; + while (itest--); + pw_det_sta = (READ(MKS_TEST_POWER_LOSS_PIN) == 0); + pw_off_sta = (READ(MKS_TEST_PS_ON_PIN) == 0); + mt_det_sta = (READ(MT_DET_1_PIN) == 0); + #if PIN_EXISTS(MT_DET_2) + mt_det2_sta = (READ(MT_DET_2_PIN) == 0); + #endif + //mt_det3_sta = (READ(FIL_RUNOUT_3_PIN) == 0); + endstopx1_sta = (READ(X_MIN_PIN) == 0); + //endstopx2_sta = (READ(X_MAX_PIN) == 0); + endstopy1_sta = (READ(Y_MIN_PIN) == 0); + //endstopy2_sta = (READ(Y_MAX_PIN) == 0); + endstopz1_sta = (READ(Z_MIN_PIN) == 0); + endstopz2_sta = (READ(Z_MAX_PIN) == 0); + #endif +} + +void test_gpio_readlevel_H() { + #if ENABLED(MKS_TEST) + volatile uint32_t itest; + WRITE(WIFI_IO0_PIN, LOW); + itest = 10000; + while (itest--); + pw_det_sta = (READ(MKS_TEST_POWER_LOSS_PIN) == 1); + pw_off_sta = (READ(MKS_TEST_PS_ON_PIN) == 1); + mt_det_sta = (READ(MT_DET_1_PIN) == 1); + #if PIN_EXISTS(MT_DET_2) + mt_det2_sta = (READ(MT_DET_2_PIN) == 1); + #endif + //mt_det3_sta = (READ(MT_DET_3_PIN) == 1); + endstopx1_sta = (READ(X_MIN_PIN) == 1); + //endstopx2_sta = (READ(X_MAX_PIN) == 1); + endstopy1_sta = (READ(Y_MIN_PIN) == 1); + //endstopy2_sta = (READ(Y_MAX_PIN) == 1); + endstopz1_sta = (READ(Z_MIN_PIN) == 1); + endstopz2_sta = (READ(Z_MAX_PIN) == 1); + #endif +} + +void init_test_gpio() { + #ifdef MKS_TEST + SET_INPUT_PULLUP(X_MIN_PIN); + //SET_INPUT_PULLUP(X_MAX_PIN); + SET_INPUT_PULLUP(Y_MIN_PIN); + //SET_INPUT_PULLUP(Y_MAX_PIN); + SET_INPUT_PULLUP(Z_MIN_PIN); + SET_INPUT_PULLUP(Z_MAX_PIN); + + SET_OUTPUT(WIFI_IO0_PIN); + + SET_INPUT_PULLUP(MT_DET_1_PIN); + #if PIN_EXISTS(MT_DET_2) + SET_INPUT_PULLUP(MT_DET_2_PIN); + #endif + //SET_INPUT_PULLUP(MT_DET_3_PIN); + + SET_INPUT_PULLUP(MKS_TEST_POWER_LOSS_PIN); + SET_INPUT_PULLUP(MKS_TEST_PS_ON_PIN); + + SET_INPUT_PULLUP(SERVO0_PIN); + + SET_OUTPUT(X_ENABLE_PIN); + SET_OUTPUT(Y_ENABLE_PIN); + SET_OUTPUT(Z_ENABLE_PIN); + SET_OUTPUT(E0_ENABLE_PIN); + #if !MB(MKS_ROBIN_E3P) + SET_OUTPUT(E1_ENABLE_PIN); + #endif + + WRITE(X_ENABLE_PIN, LOW); + WRITE(Y_ENABLE_PIN, LOW); + WRITE(Z_ENABLE_PIN, LOW); + WRITE(E0_ENABLE_PIN, LOW); + #if !MB(MKS_ROBIN_E3P) + WRITE(E1_ENABLE_PIN, LOW); + #endif + //WRITE(E2_ENABLE_PIN, LOW); + + #if MB(MKS_ROBIN_E3P) + SET_INPUT_PULLUP(PA1); + SET_INPUT_PULLUP(PA3); + SET_INPUT_PULLUP(PC2); + SET_INPUT_PULLUP(PD8); + SET_INPUT_PULLUP(PE5); + SET_INPUT_PULLUP(PE6); + SET_INPUT_PULLUP(PE7); + #endif + #endif +} + +void mks_test_beeper() { + #ifdef MKS_TEST + WRITE(BEEPER_PIN, HIGH); + delay(100); + WRITE(BEEPER_PIN, LOW); + delay(100); + #endif +} + +void mks_gpio_test() { + #if ENABLED(MKS_TEST) + init_test_gpio(); + + test_gpio_readlevel_L(); + test_gpio_readlevel_H(); + test_gpio_readlevel_L(); + if ((pw_det_sta == 1) + && (pw_off_sta == 1) + && (mt_det_sta == 1) + #if PIN_EXISTS(MT_DET_2) + && (mt_det2_sta == 1) + #endif + #if MB(MKS_ROBIN_E3P) + && (READ(PA1) == 0) + && (READ(PA3) == 0) + && (READ(PC2) == 0) + && (READ(PD8) == 0) + && (READ(PE5) == 0) + && (READ(PE6) == 0) + && (READ(PE7) == 0) + #endif + ) // &&(mt_det3_sta == 1)) + disp_det_ok(); + else + disp_det_error(); + + if ( (endstopx1_sta == 1) + //&& (endstopx2_sta == 1) + && (endstopy1_sta == 1) + //&& (endstopy2_sta == 1) + && (endstopz1_sta == 1) + && (endstopz2_sta == 1) + ) + disp_Limit_ok(); + else + disp_Limit_error(); + #endif +} + +void mks_hardware_test() { + #if ENABLED(MKS_TEST) + if (millis() % 2000 < 1000) { + WRITE(X_DIR_PIN, LOW); + WRITE(Y_DIR_PIN, LOW); + WRITE(Z_DIR_PIN, LOW); + WRITE(E0_DIR_PIN, LOW); + #if !MB(MKS_ROBIN_E3P) + WRITE(E1_DIR_PIN, LOW); + #endif + //WRITE(E2_DIR_PIN, LOW); + thermalManager.fan_speed[0] = 255; + //WRITE(HEATER_2_PIN, HIGH); // HE2 + #if !MB(MKS_ROBIN_E3P) + WRITE(HEATER_1_PIN, HIGH); // HE1 + #endif + WRITE(HEATER_0_PIN, HIGH); // HE0 + WRITE(HEATER_BED_PIN, HIGH); // HOT-BED + } + else { + WRITE(X_DIR_PIN, HIGH); + WRITE(Y_DIR_PIN, HIGH); + WRITE(Z_DIR_PIN, HIGH); + WRITE(E0_DIR_PIN, HIGH); + #if !MB(MKS_ROBIN_E3P) + WRITE(E1_DIR_PIN, HIGH); + #endif + //WRITE(E2_DIR_PIN, HIGH); + thermalManager.fan_speed[0] = 0; + //WRITE(HEATER_2_PIN, LOW); // HE2 + #if !MB(MKS_ROBIN_E3P) + WRITE(HEATER_1_PIN, LOW); // HE1 + #endif + WRITE(HEATER_0_PIN, LOW); // HE0 + WRITE(HEATER_BED_PIN, LOW); // HOT-BED + } + + if ( (endstopx1_sta == 1) && (endstopx2_sta == 1) + && (endstopy1_sta == 1) && (endstopy2_sta == 1) + && (endstopz1_sta == 1) && (endstopz2_sta == 1) + ) { + // nothing here + } + else { + //mks_test_beeper(); + } + + if (disp_state == PRINT_READY_UI) + mks_disp_test(); + + #endif +} + +static const uint16_t ASCII_Table_16x24[] PROGMEM = { + // Space ' ' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '!' + 0x0000, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, + 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0000, 0x0000, + 0x0180, 0x0180, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '"' + 0x0000, 0x0000, 0x00CC, 0x00CC, 0x00CC, 0x00CC, 0x00CC, 0x00CC, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '#' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C60, 0x0C60, + 0x0C60, 0x0630, 0x0630, 0x1FFE, 0x1FFE, 0x0630, 0x0738, 0x0318, + 0x1FFE, 0x1FFE, 0x0318, 0x0318, 0x018C, 0x018C, 0x018C, 0x0000, + // '$' + 0x0000, 0x0080, 0x03E0, 0x0FF8, 0x0E9C, 0x1C8C, 0x188C, 0x008C, + 0x0098, 0x01F8, 0x07E0, 0x0E80, 0x1C80, 0x188C, 0x188C, 0x189C, + 0x0CB8, 0x0FF0, 0x03E0, 0x0080, 0x0080, 0x0000, 0x0000, 0x0000, + // '%' + 0x0000, 0x0000, 0x0000, 0x180E, 0x0C1B, 0x0C11, 0x0611, 0x0611, + 0x0311, 0x0311, 0x019B, 0x018E, 0x38C0, 0x6CC0, 0x4460, 0x4460, + 0x4430, 0x4430, 0x4418, 0x6C18, 0x380C, 0x0000, 0x0000, 0x0000, + // '&' + 0x0000, 0x01E0, 0x03F0, 0x0738, 0x0618, 0x0618, 0x0330, 0x01F0, + 0x00F0, 0x00F8, 0x319C, 0x330E, 0x1E06, 0x1C06, 0x1C06, 0x3F06, + 0x73FC, 0x21F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // "'" + 0x0000, 0x0000, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '(' + 0x0000, 0x0200, 0x0300, 0x0180, 0x00C0, 0x00C0, 0x0060, 0x0060, + 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, + 0x0060, 0x0060, 0x00C0, 0x00C0, 0x0180, 0x0300, 0x0200, 0x0000, + // ')' + 0x0000, 0x0020, 0x0060, 0x00C0, 0x0180, 0x0180, 0x0300, 0x0300, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, + 0x0300, 0x0300, 0x0180, 0x0180, 0x00C0, 0x0060, 0x0020, 0x0000, + // '*' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00C0, 0x00C0, + 0x06D8, 0x07F8, 0x01E0, 0x0330, 0x0738, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '+' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0180, 0x0180, + 0x0180, 0x0180, 0x0180, 0x3FFC, 0x3FFC, 0x0180, 0x0180, 0x0180, + 0x0180, 0x0180, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // ',' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0180, 0x0180, 0x0100, 0x0100, 0x0080, 0x0000, 0x0000, + // '-' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x07E0, 0x07E0, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '.' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x00C0, 0x00C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '/' + 0x0000, 0x0C00, 0x0C00, 0x0600, 0x0600, 0x0600, 0x0300, 0x0300, + 0x0300, 0x0380, 0x0180, 0x0180, 0x0180, 0x00C0, 0x00C0, 0x00C0, + 0x0060, 0x0060, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '0' + 0x0000, 0x03E0, 0x07F0, 0x0E38, 0x0C18, 0x180C, 0x180C, 0x180C, + 0x180C, 0x180C, 0x180C, 0x180C, 0x180C, 0x180C, 0x0C18, 0x0E38, + 0x07F0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '1' + 0x0000, 0x0100, 0x0180, 0x01C0, 0x01F0, 0x0198, 0x0188, 0x0180, + 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, + 0x0180, 0x0180, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '2' + 0x0000, 0x03E0, 0x0FF8, 0x0C18, 0x180C, 0x180C, 0x1800, 0x1800, + 0x0C00, 0x0600, 0x0300, 0x0180, 0x00C0, 0x0060, 0x0030, 0x0018, + 0x1FFC, 0x1FFC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '3' + 0x0000, 0x01E0, 0x07F8, 0x0E18, 0x0C0C, 0x0C0C, 0x0C00, 0x0600, + 0x03C0, 0x07C0, 0x0C00, 0x1800, 0x1800, 0x180C, 0x180C, 0x0C18, + 0x07F8, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '4' + 0x0000, 0x0C00, 0x0E00, 0x0F00, 0x0F00, 0x0D80, 0x0CC0, 0x0C60, + 0x0C60, 0x0C30, 0x0C18, 0x0C0C, 0x3FFC, 0x3FFC, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '5' + 0x0000, 0x0FF8, 0x0FF8, 0x0018, 0x0018, 0x000C, 0x03EC, 0x07FC, + 0x0E1C, 0x1C00, 0x1800, 0x1800, 0x1800, 0x180C, 0x0C1C, 0x0E18, + 0x07F8, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '6' + 0x0000, 0x07C0, 0x0FF0, 0x1C38, 0x1818, 0x0018, 0x000C, 0x03CC, + 0x0FEC, 0x0E3C, 0x1C1C, 0x180C, 0x180C, 0x180C, 0x1C18, 0x0E38, + 0x07F0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '7' + 0x0000, 0x1FFC, 0x1FFC, 0x0C00, 0x0600, 0x0600, 0x0300, 0x0380, + 0x0180, 0x01C0, 0x00C0, 0x00E0, 0x0060, 0x0060, 0x0070, 0x0030, + 0x0030, 0x0030, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '8' + 0x0000, 0x03E0, 0x07F0, 0x0E38, 0x0C18, 0x0C18, 0x0C18, 0x0638, + 0x07F0, 0x07F0, 0x0C18, 0x180C, 0x180C, 0x180C, 0x180C, 0x0C38, + 0x0FF8, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '9' + 0x0000, 0x03E0, 0x07F0, 0x0E38, 0x0C1C, 0x180C, 0x180C, 0x180C, + 0x1C1C, 0x1E38, 0x1BF8, 0x19E0, 0x1800, 0x0C00, 0x0C00, 0x0E1C, + 0x07F8, 0x01F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // ':' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0180, 0x0180, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0180, 0x0180, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // ';' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0180, 0x0180, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0180, 0x0180, 0x0100, 0x0100, 0x0080, 0x0000, 0x0000, 0x0000, + // '<' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1000, 0x1C00, 0x0F80, 0x03E0, 0x00F8, 0x0018, 0x00F8, 0x03E0, + 0x0F80, 0x1C00, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '=' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1FF8, 0x0000, 0x0000, 0x0000, 0x1FF8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '>' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0008, 0x0038, 0x01F0, 0x07C0, 0x1F00, 0x1800, 0x1F00, 0x07C0, + 0x01F0, 0x0038, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '?' + 0x0000, 0x03E0, 0x0FF8, 0x0C18, 0x180C, 0x180C, 0x1800, 0x0C00, + 0x0600, 0x0300, 0x0180, 0x00C0, 0x00C0, 0x00C0, 0x0000, 0x0000, + 0x00C0, 0x00C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '@' + 0x0000, 0x0000, 0x07E0, 0x1818, 0x2004, 0x29C2, 0x4A22, 0x4411, + 0x4409, 0x4409, 0x4409, 0x2209, 0x1311, 0x0CE2, 0x4002, 0x2004, + 0x1818, 0x07E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'A' + 0x0000, 0x0380, 0x0380, 0x06C0, 0x06C0, 0x06C0, 0x0C60, 0x0C60, + 0x1830, 0x1830, 0x1830, 0x3FF8, 0x3FF8, 0x701C, 0x600C, 0x600C, + 0xC006, 0xC006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'B' + 0x0000, 0x03FC, 0x0FFC, 0x0C0C, 0x180C, 0x180C, 0x180C, 0x0C0C, + 0x07FC, 0x0FFC, 0x180C, 0x300C, 0x300C, 0x300C, 0x300C, 0x180C, + 0x1FFC, 0x07FC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'C' + 0x0000, 0x07C0, 0x1FF0, 0x3838, 0x301C, 0x700C, 0x6006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x6006, 0x700C, 0x301C, + 0x1FF0, 0x07E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'D' + 0x0000, 0x03FE, 0x0FFE, 0x0E06, 0x1806, 0x1806, 0x3006, 0x3006, + 0x3006, 0x3006, 0x3006, 0x3006, 0x3006, 0x1806, 0x1806, 0x0E06, + 0x0FFE, 0x03FE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'E' + 0x0000, 0x3FFC, 0x3FFC, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, + 0x1FFC, 0x1FFC, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, + 0x3FFC, 0x3FFC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'F' + 0x0000, 0x3FF8, 0x3FF8, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, + 0x1FF8, 0x1FF8, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, + 0x0018, 0x0018, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'G' + 0x0000, 0x0FE0, 0x3FF8, 0x783C, 0x600E, 0xE006, 0xC007, 0x0003, + 0x0003, 0xFE03, 0xFE03, 0xC003, 0xC007, 0xC006, 0xC00E, 0xF03C, + 0x3FF8, 0x0FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'H' + 0x0000, 0x300C, 0x300C, 0x300C, 0x300C, 0x300C, 0x300C, 0x300C, + 0x3FFC, 0x3FFC, 0x300C, 0x300C, 0x300C, 0x300C, 0x300C, 0x300C, + 0x300C, 0x300C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'I' + 0x0000, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, + 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, + 0x0180, 0x0180, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'J' + 0x0000, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0618, 0x0618, 0x0738, + 0x03F0, 0x01E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'K' + 0x0000, 0x3006, 0x1806, 0x0C06, 0x0606, 0x0306, 0x0186, 0x00C6, + 0x0066, 0x0076, 0x00DE, 0x018E, 0x0306, 0x0606, 0x0C06, 0x1806, + 0x3006, 0x6006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'L' + 0x0000, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, + 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, + 0x1FF8, 0x1FF8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'M' + 0x0000, 0xE00E, 0xF01E, 0xF01E, 0xF01E, 0xD836, 0xD836, 0xD836, + 0xD836, 0xCC66, 0xCC66, 0xCC66, 0xC6C6, 0xC6C6, 0xC6C6, 0xC6C6, + 0xC386, 0xC386, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'N' + 0x0000, 0x300C, 0x301C, 0x303C, 0x303C, 0x306C, 0x306C, 0x30CC, + 0x30CC, 0x318C, 0x330C, 0x330C, 0x360C, 0x360C, 0x3C0C, 0x3C0C, + 0x380C, 0x300C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'O' + 0x0000, 0x07E0, 0x1FF8, 0x381C, 0x700E, 0x6006, 0xC003, 0xC003, + 0xC003, 0xC003, 0xC003, 0xC003, 0xC003, 0x6006, 0x700E, 0x381C, + 0x1FF8, 0x07E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'P' + 0x0000, 0x0FFC, 0x1FFC, 0x380C, 0x300C, 0x300C, 0x300C, 0x300C, + 0x180C, 0x1FFC, 0x07FC, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, + 0x000C, 0x000C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'Q' + 0x0000, 0x07E0, 0x1FF8, 0x381C, 0x700E, 0x6006, 0xE003, 0xC003, + 0xC003, 0xC003, 0xC003, 0xC003, 0xE007, 0x6306, 0x3F0E, 0x3C1C, + 0x3FF8, 0xF7E0, 0xC000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'R' + 0x0000, 0x0FFE, 0x1FFE, 0x3806, 0x3006, 0x3006, 0x3006, 0x3806, + 0x1FFE, 0x07FE, 0x0306, 0x0606, 0x0C06, 0x1806, 0x1806, 0x3006, + 0x3006, 0x6006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'S' + 0x0000, 0x03E0, 0x0FF8, 0x0C1C, 0x180C, 0x180C, 0x000C, 0x001C, + 0x03F8, 0x0FE0, 0x1E00, 0x3800, 0x3006, 0x3006, 0x300E, 0x1C1C, + 0x0FF8, 0x07E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'T' + 0x0000, 0x7FFE, 0x7FFE, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, + 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, + 0x0180, 0x0180, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'U' + 0x0000, 0x300C, 0x300C, 0x300C, 0x300C, 0x300C, 0x300C, 0x300C, + 0x300C, 0x300C, 0x300C, 0x300C, 0x300C, 0x300C, 0x300C, 0x1818, + 0x1FF8, 0x07E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'V' + 0x0000, 0x6003, 0x3006, 0x3006, 0x3006, 0x180C, 0x180C, 0x180C, + 0x0C18, 0x0C18, 0x0E38, 0x0630, 0x0630, 0x0770, 0x0360, 0x0360, + 0x01C0, 0x01C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'W' + 0x0000, 0x6003, 0x61C3, 0x61C3, 0x61C3, 0x3366, 0x3366, 0x3366, + 0x3366, 0x3366, 0x3366, 0x1B6C, 0x1B6C, 0x1B6C, 0x1A2C, 0x1E3C, + 0x0E38, 0x0E38, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'X' + 0x0000, 0xE00F, 0x700C, 0x3018, 0x1830, 0x0C70, 0x0E60, 0x07C0, + 0x0380, 0x0380, 0x03C0, 0x06E0, 0x0C70, 0x1C30, 0x1818, 0x300C, + 0x600E, 0xE007, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'Y' + 0x0000, 0xC003, 0x6006, 0x300C, 0x381C, 0x1838, 0x0C30, 0x0660, + 0x07E0, 0x03C0, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, + 0x0180, 0x0180, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'Z' + 0x0000, 0x7FFC, 0x7FFC, 0x6000, 0x3000, 0x1800, 0x0C00, 0x0600, + 0x0300, 0x0180, 0x00C0, 0x0060, 0x0030, 0x0018, 0x000C, 0x0006, + 0x7FFE, 0x7FFE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '[' + 0x0000, 0x03E0, 0x03E0, 0x0060, 0x0060, 0x0060, 0x0060, 0x0060, + 0x0060, 0x0060, 0x0060, 0x0060, 0x0060, 0x0060, 0x0060, 0x0060, + 0x0060, 0x0060, 0x0060, 0x0060, 0x0060, 0x03E0, 0x03E0, 0x0000, + // '\' + 0x0000, 0x0030, 0x0030, 0x0060, 0x0060, 0x0060, 0x00C0, 0x00C0, + 0x00C0, 0x01C0, 0x0180, 0x0180, 0x0180, 0x0300, 0x0300, 0x0300, + 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // ']' + 0x0000, 0x03E0, 0x03E0, 0x0300, 0x0300, 0x0300, 0x0300, 0x0300, + 0x0300, 0x0300, 0x0300, 0x0300, 0x0300, 0x0300, 0x0300, 0x0300, + 0x0300, 0x0300, 0x0300, 0x0300, 0x0300, 0x03E0, 0x03E0, 0x0000, + // '^' + 0x0000, 0x0000, 0x01C0, 0x01C0, 0x0360, 0x0360, 0x0360, 0x0630, + 0x0630, 0x0C18, 0x0C18, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '_' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // ''' + 0x0000, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'a' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03F0, 0x07F8, + 0x0C1C, 0x0C0C, 0x0F00, 0x0FF0, 0x0CF8, 0x0C0C, 0x0C0C, 0x0F1C, + 0x0FF8, 0x18F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'b' + 0x0000, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x03D8, 0x0FF8, + 0x0C38, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x0C38, + 0x0FF8, 0x03D8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'c' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03C0, 0x07F0, + 0x0E30, 0x0C18, 0x0018, 0x0018, 0x0018, 0x0018, 0x0C18, 0x0E30, + 0x07F0, 0x03C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'd' + 0x0000, 0x1800, 0x1800, 0x1800, 0x1800, 0x1800, 0x1BC0, 0x1FF0, + 0x1C30, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1C30, + 0x1FF0, 0x1BC0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'e' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03C0, 0x0FF0, + 0x0C30, 0x1818, 0x1FF8, 0x1FF8, 0x0018, 0x0018, 0x1838, 0x1C30, + 0x0FF0, 0x07C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'f' + 0x0000, 0x0F80, 0x0FC0, 0x00C0, 0x00C0, 0x00C0, 0x07F0, 0x07F0, + 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, + 0x00C0, 0x00C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'g' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0DE0, 0x0FF8, + 0x0E18, 0x0C0C, 0x0C0C, 0x0C0C, 0x0C0C, 0x0C0C, 0x0C0C, 0x0E18, + 0x0FF8, 0x0DE0, 0x0C00, 0x0C0C, 0x061C, 0x07F8, 0x01F0, 0x0000, + // 'h' + 0x0000, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x07D8, 0x0FF8, + 0x1C38, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, + 0x1818, 0x1818, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'i' + 0x0000, 0x00C0, 0x00C0, 0x0000, 0x0000, 0x0000, 0x00C0, 0x00C0, + 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, + 0x00C0, 0x00C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'j' + 0x0000, 0x00C0, 0x00C0, 0x0000, 0x0000, 0x0000, 0x00C0, 0x00C0, + 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, + 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00F8, 0x0078, 0x0000, + // 'k' + 0x0000, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x0C0C, 0x060C, + 0x030C, 0x018C, 0x00CC, 0x006C, 0x00FC, 0x019C, 0x038C, 0x030C, + 0x060C, 0x0C0C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'l' + 0x0000, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, + 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, + 0x00C0, 0x00C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'm' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3C7C, 0x7EFF, + 0xE3C7, 0xC183, 0xC183, 0xC183, 0xC183, 0xC183, 0xC183, 0xC183, + 0xC183, 0xC183, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'n' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0798, 0x0FF8, + 0x1C38, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, + 0x1818, 0x1818, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'o' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03C0, 0x0FF0, + 0x0C30, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x0C30, + 0x0FF0, 0x03C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'p' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03D8, 0x0FF8, + 0x0C38, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x0C38, + 0x0FF8, 0x03D8, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0000, + // 'q' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1BC0, 0x1FF0, + 0x1C30, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1C30, + 0x1FF0, 0x1BC0, 0x1800, 0x1800, 0x1800, 0x1800, 0x1800, 0x0000, + // 'r' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07B0, 0x03F0, + 0x0070, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, + 0x0030, 0x0030, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 's' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03F0, + 0x0E38, 0x0C18, 0x0038, 0x03F0, 0x07C0, 0x0C00, 0x0C18, 0x0E38, + 0x07F0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 't' + 0x0000, 0x0000, 0x0080, 0x00C0, 0x00C0, 0x00C0, 0x07F0, 0x07F0, + 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, + 0x07C0, 0x0780, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'u' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1818, 0x1818, + 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1C38, + 0x1FF0, 0x19E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'v' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x180C, 0x0C18, + 0x0C18, 0x0C18, 0x0630, 0x0630, 0x0630, 0x0360, 0x0360, 0x0360, + 0x01C0, 0x01C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'w' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x41C1, 0x41C1, + 0x61C3, 0x6363, 0x6363, 0x6363, 0x3636, 0x3636, 0x3636, 0x1C1C, + 0x1C1C, 0x1C1C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'x' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x381C, 0x1C38, + 0x0C30, 0x0660, 0x0360, 0x0360, 0x0360, 0x0360, 0x0660, 0x0C30, + 0x1C38, 0x381C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // 'y' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3018, 0x1830, + 0x1830, 0x1870, 0x0C60, 0x0C60, 0x0CE0, 0x06C0, 0x06C0, 0x0380, + 0x0380, 0x0380, 0x0180, 0x0180, 0x01C0, 0x00F0, 0x0070, 0x0000, + // 'z' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1FFC, 0x1FFC, + 0x0C00, 0x0600, 0x0300, 0x0180, 0x00C0, 0x0060, 0x0030, 0x0018, + 0x1FFC, 0x1FFC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // '{' + 0x0000, 0x0300, 0x0180, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, + 0x00C0, 0x0060, 0x0060, 0x0030, 0x0060, 0x0040, 0x00C0, 0x00C0, + 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x0180, 0x0300, 0x0000, 0x0000, + // '|' + 0x0000, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, + 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, + 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0000, + // '}' + 0x0000, 0x0060, 0x00C0, 0x01C0, 0x0180, 0x0180, 0x0180, 0x0180, + 0x0180, 0x0300, 0x0300, 0x0600, 0x0300, 0x0100, 0x0180, 0x0180, + 0x0180, 0x0180, 0x0180, 0x0180, 0x00C0, 0x0060, 0x0000, 0x0000, + // '~' + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x10F0, 0x1FF8, 0x0F08, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +}; + +void disp_char_1624(uint16_t x, uint16_t y, uint8_t c, uint16_t charColor, uint16_t bkColor) { + for (uint16_t i = 0; i < 24; i++) { + const uint16_t tmp_char = pgm_read_word(&ASCII_Table_16x24[((c - 0x20) * 24) + i]); + for (uint16_t j = 0; j < 16; j++) + SPI_TFT.SetPoint(x + j, y + i, ((tmp_char >> j) & 0x01) ? charColor : bkColor); + } +} + +void disp_string(uint16_t x, uint16_t y, const char * string, uint16_t charColor, uint16_t bkColor) { + while (*string != '\0') { + disp_char_1624(x, y, *string, charColor, bkColor); + string++; + x += 16; + } +} + +//static lv_obj_t * scr_test; +void disp_assets_update() { + SPI_TFT.LCD_clear(0x0000); + disp_string(100, 140, "Assets Updating...", 0xFFFF, 0x0000); +} + +void disp_assets_update_progress(const char *msg) { + char buf[30]; + memset(buf, ' ', COUNT(buf)); + strncpy(buf, msg, strlen(msg)); + buf[COUNT(buf)-1] = '\0'; + disp_string(100, 165, buf, 0xFFFF, 0x0000); +} + +uint8_t mks_test_flag = 0; +const char *MKSTestPath = "MKS_TEST"; + +#if ENABLED(SDSUPPORT) + void mks_test_get() { + SdFile dir, root = card.getroot(); + if (dir.open(&root, MKSTestPath, O_RDONLY)) + mks_test_flag = 0x1E; + } +#endif + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/mks_hardware_test.h b/Marlin/src/lcd/extui/lib/mks_ui/mks_hardware_test.h new file mode 100644 index 000000000000..0e2d8096bac9 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/mks_hardware_test.h @@ -0,0 +1,33 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include + +void mks_gpio_test(); +void disp_char_1624(uint16_t x, uint16_t y, uint8_t c, uint16_t charColor, uint16_t bkColor); +void disp_string(uint16_t x, uint16_t y, const char * string, uint16_t charColor, uint16_t bkColor); +void mks_hardware_test(); +void disp_assets_update(); +void disp_assets_update_progress(const char *msg); +void mks_test_get(); +extern uint8_t mks_test_flag; diff --git a/Marlin/src/lcd/extui/lib/mks_ui/pic_manager.cpp b/Marlin/src/lcd/extui/lib/mks_ui/pic_manager.cpp new file mode 100644 index 000000000000..07ac56380262 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/pic_manager.cpp @@ -0,0 +1,626 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "string.h" +#include "draw_ui.h" +#include "pic_manager.h" +#include "draw_ready_print.h" +#include "mks_hardware_test.h" + +#include "SPIFlashStorage.h" +#include "../../../../libs/W25Qxx.h" + +#include "../../../../sd/cardreader.h" +#include "../../../../MarlinCore.h" + +extern uint16_t DeviceCode; +extern unsigned char bmp_public_buf[17 * 1024]; + +#if ENABLED(SDSUPPORT) + extern char *createFilename(char * const buffer, const dir_t &p); +#endif + +static const char assets[][LONG_FILENAME_LENGTH] = { + //homing screen + "bmp_zeroAll.bin", + "bmp_zero.bin", + "bmp_zeroX.bin", + "bmp_zeroY.bin", + "bmp_zeroZ.bin", + "bmp_manual_off.bin", + + //tool screen + "bmp_preHeat.bin", + "bmp_extruct.bin", + "bmp_mov.bin", + // "bmp_Zero.bin", + "bmp_leveling.bin", + "bmp_filamentchange.bin", + + //fan screen + "bmp_Add.bin", + "bmp_Dec.bin", + "bmp_speed255.bin", + "bmp_speed127.bin", + "bmp_speed0.bin", + + //preheat screen + // "bmp_Add.bin", + // "bmp_Dec.bin", + "bmp_speed0.bin", + // "bmp_Extru2.bin", + // "bmp_Extru1.bin", + "bmp_bed.bin", + "bmp_step1_degree.bin", + "bmp_step5_degree.bin", + "bmp_step10_degree.bin", + + //extrusion screen + "bmp_in.bin", + "bmp_out.bin", + "bmp_extru1.bin", + #if HAS_MULTI_EXTRUDER + "bmp_extru2.bin", + #endif + "bmp_speed_high.bin", + "bmp_speed_slow.bin", + "bmp_speed_normal.bin", + "bmp_step1_mm.bin", + "bmp_step5_mm.bin", + "bmp_step10_mm.bin", + + //select file screen + "bmp_pageUp.bin", + "bmp_pageDown.bin", + "bmp_back.bin", //TODO: why two back buttons? Why not just one? (return / back) + "bmp_dir.bin", + "bmp_file.bin", + + //move motor screen + //TODO: 6 equal icons, just in diffenct rotation... it may be optimized too + "bmp_xAdd.bin", + "bmp_xDec.bin", + "bmp_yAdd.bin", + "bmp_yDec.bin", + "bmp_zAdd.bin", + "bmp_zDec.bin", + "bmp_step_move0_1.bin", + "bmp_step_move1.bin", + "bmp_step_move10.bin", + + //operation screen + "bmp_auto_off.bin", + "bmp_speed.bin", + //"bmp_Mamual.bin", //TODO: didn't find it.. changed to bmp_manual_off.bin + "bmp_fan.bin", + "bmp_temp.bin", + "bmp_extrude_opr.bin", + "bmp_move_opr.bin", + + //change speed screen + "bmp_step1_percent.bin", + "bmp_step5_percent.bin", + "bmp_step10_percent.bin", + "bmp_extruct_sel.bin", + "bmp_mov_changespeed.bin", + // "bmp_extrude_opr.bin", equal to "bmp_Extruct.bin" + "bmp_mov_sel.bin", + "bmp_speed_extruct.bin", + + //printing screen + "bmp_pause.bin", + "bmp_resume.bin", + "bmp_stop.bin", + "bmp_ext1_state.bin", + #if HAS_MULTI_EXTRUDER + "bmp_ext2_state.bin", + #endif + "bmp_bed_state.bin", + "bmp_fan_state.bin", + "bmp_time_state.bin", + "bmp_zpos_state.bin", + "bmp_operate.bin", + + //manual leval screen (only if disabled auto level) + #if DISABLED(AUTO_BED_LEVELING_BILINEAR) + "bmp_leveling1.bin", + "bmp_leveling2.bin", + "bmp_leveling3.bin", + "bmp_leveling4.bin", + "bmp_leveling5.bin", + #endif + + //lang select screen + #if HAS_LANG_SELECT_SCREEN + "bmp_language.bin", + "bmp_simplified_cn.bin", + "bmp_simplified_cn_sel.bin", + "bmp_traditional_cn.bin", + "bmp_traditional_cn_sel.bin", + "bmp_english.bin", + "bmp_english_sel.bin", + "bmp_russian.bin", + "bmp_russian_sel.bin", + "bmp_spanish.bin", + "bmp_spanish_sel.bin", + "bmp_french.bin", + "bmp_french_sel.bin", + "bmp_italy.bin", + "bmp_italy_sel.bin", + #endif // HAS_LANG_SELECT_SCREEN + + // gcode preview + #if HAS_GCODE_DEFAULT_VIEW_IN_FLASH + "bmp_preview.bin", + #endif + + #if HAS_LOGO_IN_FLASH + "bmp_logo.bin", + #endif + + // settings screen + "bmp_about.bin", + //"bmp_Language.bin", + //"bmp_Fan.bin", + //"bmp_manual_off.bin", + + //start screen + "bmp_printing.bin", + "bmp_set.bin", + "bmp_tool.bin", + + // settings screen + "bmp_eeprom_settings.bin", + "bmp_machine_para.bin", + "bmp_function1.bin", + + // base icons + "bmp_arrow.bin", + "bmp_back70x40.bin", + "bmp_value_blank.bin", + "bmp_blank_sel.bin", + "bmp_disable.bin", + "bmp_enable.bin", + "bmp_return.bin", + + #if ENABLED(USE_WIFI_FUNCTION) + //wifi screen + "bmp_wifi.bin", + #endif + + //babystep screen + "bmp_baby_move0_01.bin", + "bmp_baby_move0_05.bin", + "bmp_baby_move0_1.bin" +}; + +#if HAS_SPI_FLASH_FONT + static char fonts[][LONG_FILENAME_LENGTH] = { "FontUNIGBK.bin" }; +#endif + +uint8_t currentFlashPage = 0; + +uint32_t lv_get_pic_addr(uint8_t *Pname) { + uint8_t Pic_cnt; + uint8_t i, j; + PIC_MSG PIC; + uint32_t tmp_cnt = 0; + uint32_t addr = 0; + + currentFlashPage = 0; + + #if ENABLED(MARLIN_DEV_MODE) + SERIAL_ECHOLNPAIR("Getting picture SPI Flash Address: ", (const char*)Pname); + #endif + + W25QXX.init(SPI_QUARTER_SPEED); + + W25QXX.SPI_FLASH_BufferRead(&Pic_cnt, PIC_COUNTER_ADDR, 1); + if (Pic_cnt == 0xFF) Pic_cnt = 0; + for (i = 0; i < Pic_cnt; i++) { + j = 0; + do { + W25QXX.SPI_FLASH_BufferRead(&PIC.name[j], PIC_NAME_ADDR + tmp_cnt, 1); + tmp_cnt++; + } while (PIC.name[j++] != '\0'); + + if ((strcasecmp((char*)Pname, (char*)PIC.name)) == 0) { + if ((DeviceCode == 0x9488) || (DeviceCode == 0x5761)) + addr = PIC_DATA_ADDR_TFT35 + i * PER_PIC_MAX_SPACE_TFT35; + else + addr = PIC_DATA_ADDR_TFT32 + i * PER_PIC_MAX_SPACE_TFT32; + return addr; + } + } + + return addr; +} + +const char *assetsPath = "assets"; +const char *bakPath = "_assets"; + +void spiFlashErase_PIC() { + volatile uint32_t pic_sectorcnt = 0; + W25QXX.init(SPI_QUARTER_SPEED); + //erase 0x001000 -64K + for (pic_sectorcnt = 0; pic_sectorcnt < (64 - 4) / 4; pic_sectorcnt++) { + watchdog_refresh(); + W25QXX.SPI_FLASH_SectorErase(PICINFOADDR + pic_sectorcnt * 4 * 1024); + } + //erase 64K -- 6M + for (pic_sectorcnt = 0; pic_sectorcnt < (PIC_SIZE_xM * 1024 / 64 - 1); pic_sectorcnt++) { + watchdog_refresh(); + W25QXX.SPI_FLASH_BlockErase((pic_sectorcnt + 1) * 64 * 1024); + } +} + +#if HAS_SPI_FLASH_FONT + void spiFlashErase_FONT() { + volatile uint32_t Font_sectorcnt = 0; + W25QXX.init(SPI_QUARTER_SPEED); + for (Font_sectorcnt = 0; Font_sectorcnt < 32-1; Font_sectorcnt++) { + watchdog_refresh(); + W25QXX.SPI_FLASH_BlockErase(FONTINFOADDR + Font_sectorcnt * 64 * 1024); + } + } +#endif + +uint32_t LogoWrite_Addroffset = 0; + +uint8_t Pic_Logo_Write(uint8_t *LogoName, uint8_t *Logo_Wbuff, uint32_t LogoWriteSize) { + if (LogoWriteSize <= 0) return 0; + + W25QXX.SPI_FLASH_BufferWrite(Logo_Wbuff, PIC_LOGO_ADDR + LogoWrite_Addroffset, LogoWriteSize); + + for (uint32_t i = 0; i < LogoWriteSize; i++) { + uint8_t temp1; + W25QXX.SPI_FLASH_BufferRead(&temp1, PIC_LOGO_ADDR + LogoWrite_Addroffset + i, 1); + if (*(Logo_Wbuff + i) != temp1) return 0; + } + LogoWrite_Addroffset += LogoWriteSize; + const uint32_t logo_maxsize = DeviceCode == 0x9488 || DeviceCode == 0x5761 ? LOGO_MAX_SIZE_TFT35 : LOGO_MAX_SIZE_TFT32; + if (LogoWrite_Addroffset >= logo_maxsize) LogoWrite_Addroffset = 0; + return 1; +} + +uint32_t TitleLogoWrite_Addroffset = 0; +uint8_t Pic_TitleLogo_Write(uint8_t *TitleLogoName, uint8_t *TitleLogo_Wbuff, uint32_t TitleLogoWriteSize) { + if (TitleLogoWriteSize <= 0) + return 0; + if ((DeviceCode == 0x9488) || (DeviceCode == 0x5761)) + W25QXX.SPI_FLASH_BufferWrite(TitleLogo_Wbuff, PIC_ICON_LOGO_ADDR_TFT35 + TitleLogoWrite_Addroffset, TitleLogoWriteSize); + else + W25QXX.SPI_FLASH_BufferWrite(TitleLogo_Wbuff, PIC_ICON_LOGO_ADDR_TFT32 + TitleLogoWrite_Addroffset, TitleLogoWriteSize); + TitleLogoWrite_Addroffset += TitleLogoWriteSize; + if (TitleLogoWrite_Addroffset >= TITLELOGO_MAX_SIZE) + TitleLogoWrite_Addroffset = 0; + return 1; +} + +uint32_t default_view_addroffset_r = 0; +void default_view_Write(uint8_t *default_view__Rbuff, uint32_t default_view_Writesize) { + W25QXX.SPI_FLASH_BufferWrite(default_view__Rbuff, DEFAULT_VIEW_ADDR_TFT35 + default_view_addroffset_r, default_view_Writesize); + default_view_addroffset_r += default_view_Writesize; + if (default_view_addroffset_r >= DEFAULT_VIEW_MAX_SIZE) + default_view_addroffset_r = 0; +} + +uint32_t Pic_Info_Write(uint8_t *P_name, uint32_t P_size) { + uint8_t pic_counter = 0; + uint32_t Pic_SaveAddr; + uint32_t Pic_SizeSaveAddr; + uint32_t Pic_NameSaveAddr; + uint8_t Pname_temp; + uint32_t i, j; + uint32_t name_len = 0; + uint32_t SaveName_len = 0; + union union32 size_tmp; + + W25QXX.SPI_FLASH_BufferRead(&pic_counter, PIC_COUNTER_ADDR, 1); + + if (pic_counter == 0xFF) + pic_counter = 0; + + if ((DeviceCode == 0x9488) || (DeviceCode == 0x5761)) + Pic_SaveAddr = PIC_DATA_ADDR_TFT35 + pic_counter * PER_PIC_MAX_SPACE_TFT35; + else + Pic_SaveAddr = PIC_DATA_ADDR_TFT32 + pic_counter * PER_PIC_MAX_SPACE_TFT32; + + for (j = 0; j < pic_counter; j++) { + do { + W25QXX.SPI_FLASH_BufferRead(&Pname_temp, PIC_NAME_ADDR + SaveName_len, 1); + SaveName_len++; + } while (Pname_temp != '\0'); + } + i = 0; + while ((*(P_name + i) != '\0')) { + i++; + name_len++; + } + + Pic_NameSaveAddr = PIC_NAME_ADDR + SaveName_len; + W25QXX.SPI_FLASH_BufferWrite(P_name, Pic_NameSaveAddr, name_len + 1); + Pic_SizeSaveAddr = PIC_SIZE_ADDR + 4 * pic_counter; + size_tmp.dwords = P_size; + W25QXX.SPI_FLASH_BufferWrite(size_tmp.bytes, Pic_SizeSaveAddr, 4); + + pic_counter++; + W25QXX.SPI_FLASH_SectorErase(PIC_COUNTER_ADDR); + W25QXX.SPI_FLASH_BufferWrite(&pic_counter, PIC_COUNTER_ADDR, 1); + + return Pic_SaveAddr; +} + +uint8_t public_buf[512]; + +#if ENABLED(SDSUPPORT) + + static void dosName2LongName(const char dosName[11], char* longName) { + uint8_t j = 0; + LOOP_L_N(i, 11) { + if (i == 8) longName[j++] = '.'; + if (dosName[i] == '\0' || dosName[i] == ' ') continue; + longName[j++] = dosName[i]; + } + longName[j] = '\0'; + } + + static int8_t arrayFindStr(const char arr[][LONG_FILENAME_LENGTH], uint8_t arraySize, const char* str) { + for (uint8_t a = 0; a < arraySize; a++) { + if (strcasecmp(arr[a], str) == 0) + return a; + } + return -1; + } + + #if ENABLED(MARLIN_DEV_MODE) + static uint32_t totalSizes = 0, totalCompressed = 0; + #endif + + #define ASSET_TYPE_ICON 0 + #define ASSET_TYPE_LOGO 1 + #define ASSET_TYPE_TITLE_LOGO 2 + #define ASSET_TYPE_G_PREVIEW 3 + #define ASSET_TYPE_FONT 4 + static void loadAsset(SdFile &dir, dir_t& entry, const char *fn, int8_t assetType) { + SdFile file; + char dosFilename[FILENAME_LENGTH]; + createFilename(dosFilename, entry); + if (!file.open(&dir, dosFilename, O_READ)) { + #if ENABLED(MARLIN_DEV_MODE) + SERIAL_ECHOLNPAIR("Error opening Asset: ", fn); + #endif + return; + } + + watchdog_refresh(); + disp_assets_update_progress(fn); + + W25QXX.init(SPI_QUARTER_SPEED); + + uint16_t pbr; + uint32_t pfileSize; + uint32_t totalSizeLoaded = 0; + uint32_t Pic_Write_Addr; + pfileSize = file.fileSize(); + totalSizeLoaded += pfileSize; + if (assetType == ASSET_TYPE_LOGO) { + do { + watchdog_refresh(); + pbr = file.read(public_buf, BMP_WRITE_BUF_LEN); + Pic_Logo_Write((uint8_t *)fn, public_buf, pbr); + } while (pbr >= BMP_WRITE_BUF_LEN); + } + else if (assetType == ASSET_TYPE_TITLE_LOGO) { + do { + watchdog_refresh(); + pbr = file.read(public_buf, BMP_WRITE_BUF_LEN); + Pic_TitleLogo_Write((uint8_t *)fn, public_buf, pbr); + } while (pbr >= BMP_WRITE_BUF_LEN); + } + else if (assetType == ASSET_TYPE_G_PREVIEW) { + do { + watchdog_refresh(); + pbr = file.read(public_buf, BMP_WRITE_BUF_LEN); + default_view_Write(public_buf, pbr); + } while (pbr >= BMP_WRITE_BUF_LEN); + } + else if (assetType == ASSET_TYPE_ICON) { + Pic_Write_Addr = Pic_Info_Write((uint8_t *)fn, pfileSize); + SPIFlash.beginWrite(Pic_Write_Addr); + #if HAS_SPI_FLASH_COMPRESSION + do { + watchdog_refresh(); + pbr = file.read(public_buf, SPI_FLASH_PageSize); + TERN_(MARLIN_DEV_MODE, totalSizes += pbr); + SPIFlash.writeData(public_buf, SPI_FLASH_PageSize); + } while (pbr >= SPI_FLASH_PageSize); + #else + do { + pbr = file.read(public_buf, BMP_WRITE_BUF_LEN); + W25QXX.SPI_FLASH_BufferWrite(public_buf, Pic_Write_Addr, pbr); + Pic_Write_Addr += pbr; + } while (pbr >= BMP_WRITE_BUF_LEN); + #endif + #if ENABLED(MARLIN_DEV_MODE) + SERIAL_ECHOLNPAIR("Space used: ", fn, " - ", (SPIFlash.getCurrentPage() + 1) * SPI_FLASH_PageSize / 1024, "KB"); + totalCompressed += (SPIFlash.getCurrentPage() + 1) * SPI_FLASH_PageSize; + #endif + SPIFlash.endWrite(); + } + else if (assetType == ASSET_TYPE_FONT) { + Pic_Write_Addr = UNIGBK_FLASH_ADDR; + do { + watchdog_refresh(); + pbr = file.read(public_buf, BMP_WRITE_BUF_LEN); + W25QXX.SPI_FLASH_BufferWrite(public_buf, Pic_Write_Addr, pbr); + Pic_Write_Addr += pbr; + } while (pbr >= BMP_WRITE_BUF_LEN); + } + + file.close(); + + #if ENABLED(MARLIN_DEV_MODE) + SERIAL_ECHOLNPAIR("Asset added: ", fn); + #endif + } + + void UpdateAssets() { + SdFile dir, root = card.getroot(); + if (dir.open(&root, assetsPath, O_RDONLY)) { + + disp_assets_update(); + disp_assets_update_progress("Erasing pics..."); + watchdog_refresh(); + spiFlashErase_PIC(); + #if HAS_SPI_FLASH_FONT + disp_assets_update_progress("Erasing fonts..."); + watchdog_refresh(); + spiFlashErase_FONT(); + #endif + + disp_assets_update_progress("Reading files..."); + dir_t d; + while (dir.readDir(&d, card.longFilename) > 0) { + // If we dont get a long name, but gets a short one, try it + if (card.longFilename[0] == 0 && d.name[0] != 0) + dosName2LongName((const char*)d.name, card.longFilename); + if (card.longFilename[0] == 0) continue; + if (card.longFilename[0] == '.') continue; + + int8_t a = arrayFindStr(assets, COUNT(assets), card.longFilename); + if (a >= 0 && a < (int8_t)COUNT(assets)) { + uint8_t assetType = ASSET_TYPE_ICON; + if (strstr(assets[a], "_logo")) + assetType = ASSET_TYPE_LOGO; + else if (strstr(assets[a], "_titlelogo")) + assetType = ASSET_TYPE_TITLE_LOGO; + else if (strstr(assets[a], "_preview")) + assetType = ASSET_TYPE_G_PREVIEW; + + loadAsset(dir, d, assets[a], assetType); + + continue; + } + + #if HAS_SPI_FLASH_FONT + a = arrayFindStr(fonts, COUNT(fonts), card.longFilename); + if (a >= 0 && a < (int8_t)COUNT(fonts)) + loadAsset(dir, d, fonts[a], ASSET_TYPE_FONT); + #endif + } + dir.rename(&root, bakPath); + } + dir.close(); + + #if ENABLED(MARLIN_DEV_MODE) + uint8_t pic_counter = 0; + W25QXX.SPI_FLASH_BufferRead(&pic_counter, PIC_COUNTER_ADDR, 1); + SERIAL_ECHOLNPAIR("Total assets loaded: ", pic_counter); + SERIAL_ECHOLNPAIR("Total Uncompressed: ", totalSizes, ", Compressed: ", totalCompressed); + #endif + } + + #if HAS_SPI_FLASH_FONT + void spi_flash_read_test() { W25QXX.SPI_FLASH_BufferRead(public_buf, UNIGBK_FLASH_ADDR, BMP_WRITE_BUF_LEN); } + #endif + +#endif // SDSUPPORT + +void Pic_Read(uint8_t *Pname, uint8_t *P_Rbuff) { + uint8_t i, j; + uint8_t Pic_cnt; + uint32_t tmp_cnt = 0; + PIC_MSG PIC; + + W25QXX.SPI_FLASH_BufferRead(&Pic_cnt, PIC_COUNTER_ADDR, 1); + if (Pic_cnt == 0xFF) + Pic_cnt = 0; + + for (i = 0; i < Pic_cnt; i++) { + j = 0; + do { + W25QXX.SPI_FLASH_BufferRead(&PIC.name[j], PIC_NAME_ADDR + tmp_cnt, 1); + tmp_cnt++; + } while (PIC.name[j++] != '\0'); + //pic size + W25QXX.SPI_FLASH_BufferRead(PIC.size.bytes, PIC_SIZE_ADDR + i * 4, 4); + + if ((strcmp((char*)Pname, (char*)PIC.name)) == 0) { + W25QXX.SPI_FLASH_BufferRead((uint8_t *)P_Rbuff, PIC_DATA_ADDR_TFT35 + i * PER_PIC_MAX_SPACE_TFT35, PIC.size.dwords); + break; + } + } +} + +void lv_pic_test(uint8_t *P_Rbuff, uint32_t addr, uint32_t size) { + #if HAS_SPI_FLASH_COMPRESSION + if (currentFlashPage == 0) + SPIFlash.beginRead(addr); + SPIFlash.readData(P_Rbuff, size); + currentFlashPage++; + #else + W25QXX.init(SPI_QUARTER_SPEED); + W25QXX.SPI_FLASH_BufferRead((uint8_t *)P_Rbuff, addr, size); + #endif +} + +#if HAS_SPI_FLASH_FONT + void get_spi_flash_data(const char *rec_buf, int addr, int size) { + W25QXX.init(SPI_QUARTER_SPEED); + W25QXX.SPI_FLASH_BufferRead((uint8_t *)rec_buf, UNIGBK_FLASH_ADDR + addr, size); + } +#endif + +uint32_t logo_addroffset = 0; +void Pic_Logo_Read(uint8_t *LogoName, uint8_t *Logo_Rbuff, uint32_t LogoReadsize) { + W25QXX.init(SPI_QUARTER_SPEED); + W25QXX.SPI_FLASH_BufferRead(Logo_Rbuff, PIC_LOGO_ADDR + logo_addroffset, LogoReadsize); + logo_addroffset += LogoReadsize; + if (logo_addroffset >= LOGO_MAX_SIZE_TFT35) + logo_addroffset = 0; +} + +uint32_t default_view_addroffset = 0; +void default_view_Read(uint8_t *default_view_Rbuff, uint32_t default_view_Readsize) { + W25QXX.init(SPI_QUARTER_SPEED); + W25QXX.SPI_FLASH_BufferRead(default_view_Rbuff, DEFAULT_VIEW_ADDR_TFT35 + default_view_addroffset, default_view_Readsize); + default_view_addroffset += default_view_Readsize; + if (default_view_addroffset >= DEFAULT_VIEW_MAX_SIZE) + default_view_addroffset = 0; +} + +#if HAS_BAK_VIEW_IN_FLASH + uint32_t flash_view_addroffset = 0; + void flash_view_Read(uint8_t *flash_view_Rbuff, uint32_t flash_view_Readsize) { + W25QXX.init(SPI_QUARTER_SPEED); + W25QXX.SPI_FLASH_BufferRead(flash_view_Rbuff, BAK_VIEW_ADDR_TFT35 + flash_view_addroffset, flash_view_Readsize); + flash_view_addroffset += flash_view_Readsize; + if (flash_view_addroffset >= FLASH_VIEW_MAX_SIZE) + flash_view_addroffset = 0; + } +#endif + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/pic_manager.h b/Marlin/src/lcd/extui/lib/mks_ui/pic_manager.h new file mode 100644 index 000000000000..ea75915df363 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/pic_manager.h @@ -0,0 +1,170 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../../../../inc/MarlinConfig.h" + +#include "../../../../libs/W25Qxx.h" + +#include + +#include +#include + +#ifndef HAS_SPI_FLASH_FONT + #define HAS_SPI_FLASH_FONT 1 // Disabled until fix the font load code +#endif +#ifndef HAS_GCODE_PREVIEW + #define HAS_GCODE_PREVIEW 1 +#endif +#ifndef HAS_LANG_SELECT_SCREEN + #define HAS_LANG_SELECT_SCREEN 1 +#endif +#ifndef HAS_BAK_VIEW_IN_FLASH + #define HAS_BAK_VIEW_IN_FLASH 1 +#endif +#ifndef HAS_GCODE_DEFAULT_VIEW_IN_FLASH + #define HAS_GCODE_DEFAULT_VIEW_IN_FLASH 1 +#endif +#ifndef HAS_LOGO_IN_FLASH + #define HAS_LOGO_IN_FLASH 1 +#endif +#ifndef SPI_FLASH_SIZE + #define SPI_FLASH_SIZE 0x1000000 // 16MB +#endif + +#define PIC_MAX_CN 100 // Maximum number of pictures +#define PIC_NAME_MAX_LEN 50 // Picture name maximum length + +#define LOGO_MAX_SIZE_TFT35 (300*1024) +#define LOGO_MAX_SIZE_TFT32 (150*1024) +#define TITLELOGO_MAX_SIZE (150*1024) // Little logo maximum +#define DEFAULT_VIEW_MAX_SIZE (200*200*2) +#define FLASH_VIEW_MAX_SIZE (200*200*2) + +#define PER_PIC_MAX_SPACE_TFT35 (9*1024) +#define PER_PIC_MAX_SPACE_TFT32 (16*1024) +#define PER_FONT_MAX_SPACE (16*1024) + +#if SPI_FLASH_SIZE == 0x200000 + //pic + //Robin_pro pic addr + #define PIC_NAME_ADDR 0x001000 // Pic information addr + #define PIC_SIZE_ADDR 0x001800 // Pic size information addr + #define PIC_COUNTER_ADDR 0x002000 // Pic total number + #define PER_PIC_SAVE_ADDR 0x000000 // Storage address of each picture + #define PIC_LOGO_ADDR 0x000000 // Logo addr + #define PIC_DATA_ADDR 0x003000 // + + // TFT35 + #define DEFAULT_VIEW_ADDR_TFT35 0x1EA070 + #define BAK_VIEW_ADDR_TFT35 (DEFAULT_VIEW_ADDR_TFT35+90*1024) + #define PIC_ICON_LOGO_ADDR_TFT35 (BAK_VIEW_ADDR_TFT35+80*1024) + #define PIC_DATA_ADDR_TFT35 0x003000 // (PIC_ICON_LOGO_ADDR_TFT35+350*1024) //0xC5800 + + #define PIC_DATA_ADDR_TFT32 0x00F000 + #define PIC_ICON_LOGO_ADDR_TFT32 0x5D8000 + #define PIC_OTHER_SIZE_ADDR_TFT32 0x5EE000 + + // font + #define FONTINFOADDR 0x150000 // 6M -- font addr + #define UNIGBK_FLASH_ADDR (FONTINFOADDR+4096) // 4*1024 + +#else + //pic + //Robin_pro pic addr + #define PIC_NAME_ADDR 0x003000 // Pic information addr + #define PIC_SIZE_ADDR 0x007000 // Pic size information addr + #define PIC_COUNTER_ADDR 0x008000 // Pic total number + //#define PER_PIC_SAVE_ADDR 0x009000 // Storage address of each picture + #define PIC_LOGO_ADDR 0x009000 // Logo addr + //#define PIC_DATA_ADDR 0x02F000 // + + // TFT35 + #define DEFAULT_VIEW_ADDR_TFT35 0xC5800 + #define BAK_VIEW_ADDR_TFT35 (DEFAULT_VIEW_ADDR_TFT35+90*1024) + #define PIC_ICON_LOGO_ADDR_TFT35 (BAK_VIEW_ADDR_TFT35+80*1024) + #define PIC_DATA_ADDR_TFT35 (PIC_ICON_LOGO_ADDR_TFT35+350*1024) //0xC5800 + + // TFT32 + #define PIC_DATA_ADDR_TFT32 0x02F000 + #define PIC_ICON_LOGO_ADDR_TFT32 0x5D8000 + #define PIC_OTHER_SIZE_ADDR_TFT32 0x5EE000 + + // font + #define FONTINFOADDR 0x600000 // 6M -- font addr + #define UNIGBK_FLASH_ADDR (FONTINFOADDR+4096) // 4*1024 + #define GBK_FLASH_ADDR (UNIGBK_FLASH_ADDR+180224) // 176*1024 + +#endif + +// Flash flag +#define REFLSHE_FLGA_ADD (0X800000-32) + +// SD card information first addr +#define VAR_INF_ADDR 0x000000 +#define FLASH_INF_VALID_FLAG 0x20200831 + +//Store some gcode commands, such as auto leveling commands +#define GCODE_COMMAND_ADDR VAR_INF_ADDR + 3*1024 +#define AUTO_LEVELING_COMMAND_ADDR GCODE_COMMAND_ADDR +#define OTHERS_COMMAND_ADDR_1 AUTO_LEVELING_COMMAND_ADDR + 100 +#define OTHERS_COMMAND_ADDR_2 OTHERS_COMMAND_ADDR_1 + 100 +#define OTHERS_COMMAND_ADDR_3 OTHERS_COMMAND_ADDR_2 + 100 +#define OTHERS_COMMAND_ADDR_4 OTHERS_COMMAND_ADDR_3 + 100 + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +union union32 { + uint8_t bytes[4]; + uint32_t dwords; +}; + +// pic information +struct pic_msg { + uint8_t name[PIC_NAME_MAX_LEN]; + union union32 size; +}; + +typedef struct pic_msg PIC_MSG; + +#define BMP_WRITE_BUF_LEN 512 + +#define PICINFOADDR 0x1000 + +#define PIC_SIZE_xM 6 +#define FONT_SIZE_xM 2 + +extern void Pic_Read(uint8_t *Pname, uint8_t *P_Rbuff); +extern void Pic_Logo_Read(uint8_t *LogoName,uint8_t *Logo_Rbuff,uint32_t LogoReadsize); +extern void lv_pic_test(uint8_t *P_Rbuff, uint32_t addr, uint32_t size); +extern uint32_t lv_get_pic_addr(uint8_t *Pname); +extern void get_spi_flash_data(const char *rec_buf, int offset, int size); +extern void spi_flash_read_test(); +extern void default_view_Read(uint8_t *default_view_Rbuff, uint32_t default_view_Readsize); +extern void flash_view_Read(uint8_t *flash_view_Rbuff, uint32_t flash_view_Readsize); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/printer_operation.cpp b/Marlin/src/lcd/extui/lib/mks_ui/printer_operation.cpp new file mode 100644 index 000000000000..2b6f5f89f6ee --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/printer_operation.cpp @@ -0,0 +1,252 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "../../../../MarlinCore.h" + +#include "lv_conf.h" +#include "draw_ui.h" +#include "../../../../module/temperature.h" +#include "../../../../module/motion.h" +#include "../../../../sd/cardreader.h" +#include "../../../../gcode/queue.h" + +#if ENABLED(POWER_LOSS_RECOVERY) + #include "../../../../feature/powerloss.h" +#endif + +#include "../../../../gcode/gcode.h" +#include "../../../../module/planner.h" + +extern uint32_t To_pre_view; +extern uint8_t flash_preview_begin, default_preview_flg, gcode_preview_over; + +void printer_state_polling() { + if (uiCfg.print_state == PAUSING) { + #if ENABLED(SDSUPPORT) + if (!planner.has_blocks_queued() && card.getIndex() > MIN_FILE_PRINTED) + uiCfg.waitEndMoves++; + + if (uiCfg.waitEndMoves > 20) { + uiCfg.waitEndMoves = 0; + planner.synchronize(); + + gcode.process_subcommands_now_P(PSTR("M25")); + + //save the positon + uiCfg.current_x_position_bak = current_position.x; + uiCfg.current_y_position_bak = current_position.y; + + if (gCfgItems.pausePosZ != (float)-1) { + gcode.process_subcommands_now_P(PSTR("G91")); + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("G1 Z%.1f"), gCfgItems.pausePosZ); + gcode.process_subcommands_now(public_buf_l); + gcode.process_subcommands_now_P(PSTR("G90")); + } + if (gCfgItems.pausePosX != (float)-1 && gCfgItems.pausePosY != (float)-1) { + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("G1 X%.1f Y%.1f"), gCfgItems.pausePosX, gCfgItems.pausePosY); + gcode.process_subcommands_now(public_buf_l); + } + uiCfg.print_state = PAUSED; + uiCfg.current_e_position_bak = current_position.e; + + // #if ENABLED(POWER_LOSS_RECOVERY) + // if (recovery.enabled) recovery.save(true); + // #endif + gCfgItems.pause_reprint = 1; + update_spi_flash(); + } + #endif + } + else + uiCfg.waitEndMoves = 0; + + if (uiCfg.print_state == PAUSED) { + } + + if (uiCfg.print_state == RESUMING) { + if (IS_SD_PAUSED()) { + if (gCfgItems.pausePosX != (float)-1 && gCfgItems.pausePosY != (float)-1) { + ZERO(public_buf_m); + sprintf_P(public_buf_m, PSTR("G1 X%.1f Y%.1f"), uiCfg.current_x_position_bak, uiCfg.current_y_position_bak); + gcode.process_subcommands_now(public_buf_m); + } + if (gCfgItems.pausePosZ != (float)-1) { + gcode.process_subcommands_now_P(PSTR("G91")); + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("G1 Z-%.1f"), gCfgItems.pausePosZ); + gcode.process_subcommands_now(public_buf_l); + gcode.process_subcommands_now_P(PSTR("G90")); + } + gcode.process_subcommands_now_P(PSTR("M24")); + uiCfg.print_state = WORKING; + start_print_time(); + + gCfgItems.pause_reprint = 0; + update_spi_flash(); + } + } + #if ENABLED(POWER_LOSS_RECOVERY) + if (uiCfg.print_state == REPRINTED) { + ZERO(public_buf_m); + #if HAS_HOTEND + HOTEND_LOOP() { + const int16_t et = recovery.info.target_temperature[e]; + if (et) { + #if HAS_MULTI_HOTEND + sprintf_P(public_buf_m, PSTR("T%i"), e); + gcode.process_subcommands_now(public_buf_m); + #endif + sprintf_P(public_buf_m, PSTR("M109 S%i"), et); + gcode.process_subcommands_now(public_buf_m); + } + } + #endif + + recovery.resume(); + #if 0 + // Move back to the saved XY + char str_1[16], str_2[16]; + ZERO(public_buf_m); + sprintf_P(public_buf_m, PSTR("G1 X%s Y%s F2000"), + dtostrf(recovery.info.current_position.x, 1, 3, str_1), + dtostrf(recovery.info.current_position.y, 1, 3, str_2) + ); + gcode.process_subcommands_now(public_buf_m); + + if ((gCfgItems.pause_reprint) == 1 && (gCfgItems.pausePosZ != (float)-1)) { + gcode.process_subcommands_now_P(PSTR("G91")); + ZERO(public_buf_l); + sprintf_P(public_buf_l, PSTR("G1 Z-%.1f"), gCfgItems.pausePosZ); + gcode.process_subcommands_now(public_buf_l); + gcode.process_subcommands_now_P(PSTR("G90")); + } + #endif + uiCfg.print_state = WORKING; + start_print_time(); + + gCfgItems.pause_reprint = 0; + update_spi_flash(); + } + #endif + + if (uiCfg.print_state == WORKING) + filament_check(); + + TERN_(USE_WIFI_FUNCTION, wifi_looping()); +} + +void filament_pin_setup() { + #if PIN_EXISTS(MT_DET_1) + SET_INPUT_PULLUP(MT_DET_1_PIN); + #endif + #if PIN_EXISTS(MT_DET_2) + SET_INPUT_PULLUP(MT_DET_2_PIN); + #endif + #if PIN_EXISTS(MT_DET_3) + SET_INPUT_PULLUP(MT_DET_3_PIN); + #endif +} + +void filament_check() { + const int FIL_DELAY = 20; + #if PIN_EXISTS(MT_DET_1) + static int fil_det_count_1 = 0; + if (!READ(MT_DET_1_PIN) && !MT_DET_PIN_INVERTING) + fil_det_count_1++; + else if (READ(MT_DET_1_PIN) && MT_DET_PIN_INVERTING) + fil_det_count_1++; + else if (fil_det_count_1 > 0) + fil_det_count_1--; + + if (!READ(MT_DET_1_PIN) && !MT_DET_PIN_INVERTING) + fil_det_count_1++; + else if (READ(MT_DET_1_PIN) && MT_DET_PIN_INVERTING) + fil_det_count_1++; + else if (fil_det_count_1 > 0) + fil_det_count_1--; + #endif + + #if PIN_EXISTS(MT_DET_2) + static int fil_det_count_2 = 0; + if (!READ(MT_DET_2_PIN) && !MT_DET_PIN_INVERTING) + fil_det_count_2++; + else if (READ(MT_DET_2_PIN) && MT_DET_PIN_INVERTING) + fil_det_count_2++; + else if (fil_det_count_2 > 0) + fil_det_count_2--; + + if (!READ(MT_DET_2_PIN) && !MT_DET_PIN_INVERTING) + fil_det_count_2++; + else if (READ(MT_DET_2_PIN) && MT_DET_PIN_INVERTING) + fil_det_count_2++; + else if (fil_det_count_2 > 0) + fil_det_count_2--; + #endif + + #if PIN_EXISTS(MT_DET_3) + static int fil_det_count_3 = 0; + if (!READ(MT_DET_3_PIN) && !MT_DET_PIN_INVERTING) + fil_det_count_3++; + else if (READ(MT_DET_3_PIN) && MT_DET_PIN_INVERTING) + fil_det_count_3++; + else if (fil_det_count_3 > 0) + fil_det_count_3--; + + if (!READ(MT_DET_3_PIN) && !MT_DET_PIN_INVERTING) + fil_det_count_3++; + else if (READ(MT_DET_3_PIN) && MT_DET_PIN_INVERTING) + fil_det_count_3++; + else if (fil_det_count_3 > 0) + fil_det_count_3--; + #endif + + if (false + #if PIN_EXISTS(MT_DET_1) + || fil_det_count_1 >= FIL_DELAY + #endif + #if PIN_EXISTS(MT_DET_2) + || fil_det_count_2 >= FIL_DELAY + #endif + #if PIN_EXISTS(MT_DET_3) + || fil_det_count_3 >= FIL_DELAY + #endif + ) { + clear_cur_ui(); + card.pauseSDPrint(); + stop_print_time(); + uiCfg.print_state = PAUSING; + + if (gCfgItems.from_flash_pic == 1) + flash_preview_begin = 1; + else + default_preview_flg = 1; + + lv_draw_printing(); + } +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/printer_operation.h b/Marlin/src/lcd/extui/lib/mks_ui/printer_operation.h new file mode 100644 index 000000000000..f30415882451 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/printer_operation.h @@ -0,0 +1,36 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +#define MIN_FILE_PRINTED 100 //5000 + +extern void printer_state_polling(); +extern void filament_pin_setup(); +extern void filament_check(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_en.h b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_en.h new file mode 100644 index 000000000000..fa8d5a52a496 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_en.h @@ -0,0 +1,766 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +//****************英文***************************// +#define MACHINE_CONFIG_EN "Config" + +#define NEXT_EN "Next" +#define PREVIOUS_EN "Previous" +#define DEFAULT_EN "Default" +#define KEY_BACK_EN "Del" +#define KEY_REST_EN "Reset" +#define KEY_CONFIRM_EN "Confirm" + +#define KEYBOARD_KEY0_EN "0" +#define KEYBOARD_KEY1_EN "1" +#define KEYBOARD_KEY2_EN "2" +#define KEYBOARD_KEY3_EN "3" +#define KEYBOARD_KEY4_EN "4" +#define KEYBOARD_KEY5_EN "5" +#define KEYBOARD_KEY6_EN "6" +#define KEYBOARD_KEY7_EN "7" +#define KEYBOARD_KEY8_EN "8" +#define KEYBOARD_KEY9_EN "9" +#define KEYBOARD_KEY_POINT_EN "." +#define KEYBOARD_KEY_NEGATIVE_EN "-" + +#define MACHINE_PARA_TITLE_EN "Config" +#define MACHINE_TYPE_CNOFIG_EN "Machine settings" +#define MOTOR_CONFIG_EN "Motor settings" +#define MACHINE_LEVELING_CONFIG_EN "Leveling settings" +#define ADVANCE_CONFIG_EN "Adavance settings" + +#define MACHINE_CONFIG_TITLE_EN "Machine Settings" +#define MACHINE_TYPE_EN "Machine type" +#define MACHINE_STROKE_EN "Machine Size" +#define MACHINE_HOMEDIR_EN "Home direction" +#define MACHINE_ENDSTOP_TYPE_EN "Endstop type" +#define MACHINE_FILAMENT_CONFIG_EN "Filament settings" + +#define MACHINE_TYPE_CONFIG_TITLE_EN "Machine Settings>Machine type" +#define MACHINE_TYPE_XYZ_EN "XYZ Machine" +#define MACHINE_TYPE_DELTA_EN "Delta Machine" +#define MACHINE_TYPE_COREXY_EN "Corexy Machine" + +#define MACHINE_STROKE_CONF_TITLE_EN "Machine Settings>Machine Size" +#define X_MAX_LENGTH_EN "X-axis maximum stroke" +#define Y_MAX_LENGTH_EN "Y-axis maximum stroke" +#define Z_MAX_LENGTH_EN "Z-axis maximum stroke" + +#define X_MIN_LENGTH_EN "X-axis minimum stroke" +#define Y_MIN_LENGTH_EN "Y-axis minimum stroke" +#define Z_MIN_LENGTH_EN "Z-axis minimum stroke" + +#define HOME_DIR_CONF_TITLE_EN "Machine Settings>Home direction" +#define HOME_DIR_X_EN "X-axis home direction" +#define HOME_DIR_Y_EN "Y-axis home direction" +#define HOME_DIR_Z_EN "Z-axis home direction" +#define HOME_MIN_EN "MIN" +#define HOME_MAX_EN "MAX" + +#define ENDSTOP_CONF_TITLE_EN "Machine Settings>Endstop type" +#define MIN_ENDSTOP_X_EN "X-axis minimum Endstop" +#define MIN_ENDSTOP_Y_EN "Y-axis minimum Endstop" +#define MIN_ENDSTOP_Z_EN "Z-axis minimum Endstop" +#define MAX_ENDSTOP_X_EN "X axis maximum Endstop" +#define MAX_ENDSTOP_Y_EN "Y axis maximum Endstop" +#define MAX_ENDSTOP_Z_EN "Z axis maximum Endstop" +#define ENDSTOP_FIL_EN "Filament sensor" +#define ENDSTOP_LEVEL_EN "Leveling sensor" +#define ENDSTOP_OPENED_EN "Open" +#define ENDSTOP_CLOSED_EN "Close" + +#define FILAMENT_CONF_TITLE_EN "Machine Settings>Filament settings" +#define FILAMENT_IN_LENGTH_EN "Load length" +#define FILAMENT_IN_SPEED_EN "Load speed" +#define FILAMENT_TEMPERATURE_EN "Filament temperature" +#define FILAMENT_OUT_LENGTH_EN "Unload length" +#define FILAMENT_OUT_SPEED_EN "Unload speed" + +#define LEVELING_CONF_TITLE_EN "Machine Settings>Leveling settings" +#define LEVELING_PARA_CONF_EN "Leveling settings" +#define LEVELING_MANUAL_POS_EN "Manual leveling coordinate settings" +#define LEVELING_AUTO_COMMAND_EN "AutoLeveling command settings" +#define LEVELING_AUTO_ZOFFSET_EN "Nozzle-to-probe offsets settings" + +#define LEVELING_PARA_CONF_TITLE_EN "leveling setting" +#define AUTO_LEVELING_ENABLE_EN "Enable auto leveling" +#define BLTOUCH_LEVELING_ENABLE_EN "Enable BLtouch" +#define PROBE_PORT_EN "Probe connector" +#define PROBE_X_OFFSET_EN "Probe x axis offset" +#define PROBE_Y_OFFSET_EN "Probe y axis offset" +#define PROBE_Z_OFFSET_EN "Probe z axis offset" +#define PROBE_XY_SPEED_EN "Probe xy axis speed" +#define PROBE_Z_SPEED_EN "Probe z axis speed" +#define ENABLE_EN "YES" +#define DISABLE_EN "NO" +#define Z_MIN_EN "ZMin" +#define Z_MAX_EN "ZMax" + +#define DELTA_LEVEL_CONF_TITLE_EN "Delta Machine settings" +#define DELTA_LEVEL_CONF_EN "Delta Machine Leveling" +#define DELTA_MACHINE_RADIUS_EN "Machine Radius" +#define DELTA_DIAGONAL_ROD_EN "Machine rod length" +#define DELTA_PRINT_RADIUS_EN "Print radius" +#define DELTA_HEIGHT_EN "Print height" +#define SMOOTH_ROD_OFFSET_EN "Slider offset" +#define EFFECTOR_OFFSET_EN "Effector offset" +#define CALIBRATION_RADIUS_EN "Leveling radius" + +#define XYZ_LEVEL_CONF_TITLE_EN "Cartesian Machine Settings" +#define PROBE_REACH_MAX_LEFT_EN "Probe reaches leftmost position" +#define PROBE_REACH_MAX_RIGHT_EN "Probe reaches rightmost position" +#define PROBE_REACH_MAX_FRONT_EN "Probe reaches front position" +#define PROBE_REACH_MAX_BACK_EN "Probe reaches final position" + +#define TEMPERATURE_CONF_TITLE_EN "Machine Settings>Temperature settings" +#define NOZZLE_CONF_EN "Nozzle settings" +#define HOTBED_CONF_EN "Hotbed settings" +#define PREHEAT_TEMPER_EN "Preset temperature" + +#define NOZZLE_CONF_TITLE_EN "Machine Settings>Nozzle settings" +#define NOZZLECNT_EN "Number of nozzles" +#define NOZZLE_TYPE_EN "E0 Temperature type" +#define NOZZLE_ADJUST_TYPE_EN "PID thermostat" +#define NOZZLE_MIN_TEMPERATURE_EN "lowest temperature" +#define NOZZLE_MAX_TEMPERATURE_EN "Maximum temperature" +#define EXTRUD_MIN_TEMPER_EN "Minimum extrusion temperature" + +#define HOTBED_CONF_TITLE_EN "Machine Settings>Hotbed settings" +#define HOTBED_ADJUST_EN "PID thermostat" +#define HOTBED_MIN_TEMPERATURE_EN "lowest temperature" +#define HOTBED_MAX_TEMPERATURE_EN "Maximum temperature" + +#define MOTOR_CONF_TITLE_EN "Machine Settings>Motor settings" +#define MAXFEEDRATE_CONF_EN "Maximum speed settings" +#define ACCELERATION_CONF_EN "Acceleration settings" +#define JERKCONF_EN "Jerk settings" +#define STEPSCONF_EN "Steps settings" +#define TMC_CURRENT_EN "TMC Current settings" +#define TMC_STEP_MODE_EN "TMC Step mode settings" +#define MOTORDIRCONF_EN "Motor direction settings" +#define HOMEFEEDRATECONF_EN "Home speed setting" + +#define MAXFEEDRATE_CONF_TITLE_EN "Machine Settings>Maximum speed" +#define X_MAXFEEDRATE_EN "X axis maximum speed" +#define Y_MAXFEEDRATE_EN "Y axis maximum speed" +#define Z_MAXFEEDRATE_EN "Z axis maximum speed" +#define E0_MAXFEEDRATE_EN "E0 axis maximum speed" +#define E1_MAXFEEDRATE_EN "E1 axis maximum speed" + +#define ACCELERATION_CONF_TITLE_EN "Machine Settings>Acceleration" +#define PRINT_ACCELERATION_EN "Print acceleration" +#define RETRACT_ACCELERATION_EN "Retraction acceleration" +#define TRAVEL_ACCELERATION_EN "Travel acceleration" +#define X_ACCELERATION_EN "X-axis acceleration" +#define Y_ACCELERATION_EN "Y-axis acceleration" +#define Z_ACCELERATION_EN "Z-axis acceleration" +#define E0_ACCELERATION_EN "E0-axis acceleration" +#define E1_ACCELERATION_EN "E1-axis acceleration" + +#define JERK_CONF_TITLE_EN "Machine Settings>Jerk speed" +#define X_JERK_EN "X-axis jerk speed" +#define Y_JERK_EN "Y-axis jerk speed" +#define Z_JERK_EN "J-axis jerk speed" +#define E_JERK_EN "E-axis jerk speed" + +#define STEPS_CONF_TITLE_EN "Machine Settings>Steps settings" +#define X_STEPS_EN "X-axis steps" +#define Y_STEPS_EN "Y-axis stepS" +#define Z_STEPS_EN "Z-axis stepS" +#define E0_STEPS_EN "E0-axis steps" +#define E1_STEPS_EN "E1-axis steps" + +#define TMC_CURRENT_CONF_TITLE_EN "Machine Settings>TMC current settings" +#define X_TMC_CURRENT_EN "X axis current (mA)" +#define Y_TMC_CURRENT_EN "Y axis current (mA)" +#define Z_TMC_CURRENT_EN "Z axis current (mA)" +#define E0_TMC_CURRENT_EN "E0 axis current (mA)" +#define E1_TMC_CURRENT_EN "E1 axis current (mA)" + +#define TMC_MODE_CONF_TITLE_EN "Machine Settings>TMC step mode settings" +#define X_TMC_MODE_EN "Whether X axis enable stealthChop modes" +#define Y_TMC_MODE_EN "Whether Y axis enable stealthChop modes" +#define Z_TMC_MODE_EN "Whether Z axis enable stealthChop modes" +#define E0_TMC_MODE_EN "Whether E0 axis enable stealthChop modes" +#define E1_TMC_MODE_EN "Whether E1 axis enable stealthChop modes" + +#define MOTORDIR_CONF_TITLE_EN "Machine Settings>Motor direction" +#define X_MOTORDIR_EN "X-axis motor direction invert" +#define Y_MOTORDIR_EN "Y-axis motor direction invert" +#define Z_MOTORDIR_EN "Z-axis motor direction invert" +#define E0_MOTORDIR_EN "E0-axis motor direction invert" +#define E1_MOTORDIR_EN "E1-axis motor direction invert" +#define INVERT_P_EN "YES" +#define INVERT_N_EN "NO" + +#define HOMEFEEDRATE_CONF_TITLE_EN "Machine Settings>Home speed" +#define X_HOMESPEED_EN "XY-axis Home speed" +#define Y_HOMESPEED_EN "Y-axis Home speed" +#define Z_HOMESPEED_EN "Z-axis Home speed" + +#define ADVANCED_CONF_TITLE_EN "Machine Settings>Advance" +#define PWROFF_DECTION_EN "power off dection module" +#define PWROFF_AFTER_PRINT_EN "Auto Shutdown after print" +#define HAVE_UPS_EN "Has UPS power supply" +#define Z2_AND_Z2ENDSTOP_CONF_EN "Z2 Settings" +#define ENABLE_PINS_CONF_EN "Enable pins level settings" +#define WIFI_SETTINGS_EN "Wi-Fi parameter settings" +#define HOMING_SENSITIVITY_CONF_EN "Homing sensitivity settings" +#define ENCODER_SETTINGS_EN "Rotary encoder settings" + +#define Z2_AND_Z2ENDSTOP_CONF_TITLE_EN "Z2 Settings" +#define Z2_ENABLE_EN "Z2 Enable" +#define Z2_ENDSTOP_EN "Z2_EndStop Enable" +#define Z2_PORT_EN "Z2 Connector" + +#define ENABLE_PINS_CONF_TITLE_EN "ENABLE_PINS_LEVEL" +#define X_ENABLE_PINS_INVERT_EN "X_ENABLE_PIN_INVERT" +#define Y_ENABLE_PINS_INVERT_EN "Y_ENABLE_PIN_INVERT" +#define Z_ENABLE_PINS_INVERT_EN "Z_ENABLE_PIN_INVERT" +#define E_ENABLE_PINS_INVERT_EN "E_ENABLE_PIN_INVERT" + +#define PAUSE_POSITION_EN "Printing pause position settings" +#define PAUSE_POSITION_X_EN "X axis position (Absolute position,-1 invalid)" +#define PAUSE_POSITION_Y_EN "Y axis position (Absolute position,-1 invalid)" +#define PAUSE_POSITION_Z_EN "Z axis position (Relative position,-1 invalid)" + +#define WIFI_SETTINGS_TITLE_EN "Machine Settings>Wi-Fi Parameter" +#define WIFI_SETTINGS_MODE_EN "Wi-Fi Mode" +#define WIFI_SETTINGS_NAME_EN "Wi-Fi Name: " +#define WIFI_SETTINGS_PASSWORD_EN "Wi-Fi Password: " +#define WIFI_SETTINGS_CLOUD_EN "Do you use cloud services?" +#define WIFI_SETTINGS_CONFIG_EN "Config" +#define WIFI_SETTINGS_EDIT_EN "Edit" +#define WIFI_CONFIG_TIPS_EN "Wi-Fi configuration?" + +#define OFFSET_TITLE_EN "Machine Settings>Offset" +#define OFFSET_X_EN "X offset" +#define OFFSET_Y_EN "Y offset" +#define OFFSET_Z_EN "Z offset" + +#define HOMING_SENSITIVITY_CONF_TITLE_EN "Machine Settings>Sensitivity" +#define X_SENSITIVITY_EN "X Axis Sensitivity" +#define Y_SENSITIVITY_EN "Y Axis Sensitivity" +#define Z_SENSITIVITY_EN "Z Axis Sensitivity" +#define Z2_SENSITIVITY_EN "Z2 Axis Sensitivity" + +#define ENCODER_CONF_TITLE_EN "Machine Settings>Rotary encoder settings" +#define ENCODER_CONF_TEXT_EN "Is the encoder function used?" + +#define TOOL_TEXT_EN "Tool" +#define PREHEAT_TEXT_EN "Preheat" +#define MOVE_TEXT_EN "Move" +#define HOME_TEXT_EN "Home" +#define PRINT_TEXT_EN "Printing" +#define EXTRUDE_TEXT_EN "Extrusion" +#define LEVELING_TEXT_EN "Leveling" +#define AUTO_LEVELING_TEXT_EN "AutoLevel" +#define SET_TEXT_EN "Settings" +#define MORE_TEXT_EN "More" + +#define ADD_TEXT_EN "Add" +#define DEC_TEXT_EN "Dec" +#define EXTRUDER_1_TEXT_EN "Extrusion1" +#define EXTRUDER_2_TEXT_EN "Extrusion2" +#define HEATBED_TEXT_EN "HeatBed" +#define TEXT_1C_EN "1℃" +#define TEXT_5C_EN "5℃" +#define TEXT_10C_EN "10℃" +#define CLOSE_TEXT_EN "Close" + +#define BACK_TEXT_EN "Back" + +#define TOOL_PREHEAT_EN "Preheat" +#define TOOL_EXTRUDE_EN "Extrusion" +#define TOOL_MOVE_EN "Move" +#define TOOL_HOME_EN "Home" +#define TOOL_LEVELING_EN "Leveling" +#define TOOL_AUTO_LEVELING_EN "AutoLevel" +#define TOOL_FILAMENT_EN "Filament" +#define TOOL_MORE_EN "More" + +#define AXIS_X_ADD_TEXT_EN "X+" +#define AXIS_X_DEC_TEXT_EN "X-" +#define AXIS_Y_ADD_TEXT_EN "Y+" +#define AXIS_Y_DEC_TEXT_EN "Y-" +#define AXIS_Z_ADD_TEXT_EN "Z+" +#define AXIS_Z_DEC_TEXT_EN "Z-" +#define TEXT_01MM_EN "0.1mm" +#define TEXT_1MM_EN "1mm" +#define TEXT_10MM_EN "10mm" + +#define HOME_X_TEXT_EN "X" +#define HOME_Y_TEXT_EN "Y" +#define HOME_Z_TEXT_EN "Z" +#define HOME_ALL_TEXT_EN "Home" +#define HOME_STOPMOVE_EN "Quickstop" + +#define PAGE_UP_TEXT_EN "Page up" +#define PAGE_DOWN_TEXT_EN "Page down" + +#define EXTRUDER_IN_TEXT_EN "In" +#define EXTRUDER_OUT_TEXT_EN "Out" +#define EXTRUDE_1MM_TEXT_EN "1mm" +#define EXTRUDE_5MM_TEXT_EN "5mm" +#define EXTRUDE_10MM_TEXT_EN "10mm" +#define EXTRUDE_LOW_SPEED_TEXT_EN "Low" +#define EXTRUDE_MEDIUM_SPEED_TEXT_EN "Normal" +#define EXTRUDE_HIGH_SPEED_TEXT_EN "High" + +#define LEVELING_POINT1_TEXT_EN "Point1" +#define LEVELING_POINT2_TEXT_EN "Point2" +#define LEVELING_POINT3_TEXT_EN "Point3" +#define LEVELING_POINT4_TEXT_EN "Point4" +#define LEVELING_POINT5_TEXT_EN "Point5" + +#define FILESYS_TEXT_EN "FileSys" +#define WIFI_TEXT_EN "WiFi" +#define FAN_TEXT_EN "Fan" +#define ABOUT_TEXT_EN "About" +#define BREAK_POINT_TEXT_EN "Continue" +#define FILAMENT_TEXT_EN "Filament" +#define LANGUAGE_TEXT_EN "Language" +#define MOTOR_OFF_TEXT_EN "Motor-off" +#define MOTOR_OFF_XY_TEXT_EN "Off-XY" +#define SHUTDOWN_TEXT_EN "Shutdown" +#define MACHINE_PARA_EN "Config" +#define EEPROM_SETTINGS_EN "Eeprom Set" + +#define U_DISK_TEXT_EN "USB" +#define SD_CARD_TEXT_EN "SD" +#define WIFI_NAME_TEXT_EN "WiFi: " +#define WIFI_KEY_TEXT_EN "Key: " +#define WIFI_IP_TEXT_EN "IP: " +#define WIFI_AP_TEXT_EN "State: AP" +#define WIFI_STA_TEXT_EN "State: STA" +#define WIFI_CONNECTED_TEXT_EN "Connected" +#define WIFI_DISCONNECTED_TEXT_EN "Disconnected" +#define WIFI_EXCEPTION_TEXT_EN "Exception" +#define WIFI_RECONNECT_TEXT_EN "Reconnect" +#define CLOUD_TEXT_EN "Cloud" +#define CLOUD_BIND_EN "Bind" +#define CLOUD_UNBIND_EN "Unbind" +#define CLOUD_UNBINDING_EN "Unbinding" +#define CLOUD_DISCONNECTED_EN "Disconnected" +#define CLOUD_UNBINDED_EN "Unbinded" +#define CLOUD_BINDED_EN "Binded" +#define CLOUD_DISABLE_EN "Disable" + +#define FAN_ADD_TEXT_EN "Add" +#define FAN_DEC_TEXT_EN "Dec" +#define FAN_OPEN_TEXT_EN "100%" +#define FAN_HALF_TEXT_EN "50%" +#define FAN_CLOSE_TEXT_EN "Close" +#define FAN_TIPS1_TEXT_EN "FAN" +#define FAN_TIPS2_TEXT_EN "FAN\nClose" + +#define FILAMENT_IN_TEXT_EN "Load" +#define FILAMENT_OUT_TEXT_EN "Unload" +#define FILAMENT_EXT0_TEXT_EN "Extrusion1" +#define FILAMENT_EXT1_TEXT_EN "Extrusion2" +#define FILAMENT_HEAT_TEXT_EN "Preheat" +#define FILAMENT_STOP_TEXT_EN "Stop" +//#define FILAMENT_CHANGE_TEXT_EN "Filament replace" +#define FILAMENT_TIPS2_TEXT_EN "T:" +#define FILAMENT_TIPS3_TEXT_EN "Loading..." +#define FILAMENT_TIPS4_TEXT_EN "Unloading..." +#define FILAMENT_TIPS5_TEXT_EN "Temp is too low to go,please heat" +#define FILAMENT_TIPS6_TEXT_EN "Completed" + +#if 0 + #define FILAMENT_REPLAYS_IDLE_TEXT_EN "Please click or \nto replace filament!" + #define FILAMENT_CHANGE_TEXT_EN "Please click or ,\nAfter pinter pause." + #define FILAMENT_DIALOG_LOAD_HEAT_TIPS_EN "Heating up the nozzle,please wait..." + #define FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_EN "Heating up the nozzle,please wait..." + #define FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_EN "Heat completed,please load filament to extruder,and click for start loading." + #define FILAMENT_DIALOG_LOAD_CONFIRM2_TIPS_EN "Please load filament to extruder,and click for start loading." + #define FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_EN "Heat completed,please click for start unloading.!" + #define FILAMENT_DIALOG_LOADING_TIPS_EN "Is loading ,please wait!" + #define FILAMENT_DIALOG_UNLOADING_TIPS_EN "Is unloading,please wait!" + #define FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_EN "Load filament completed,click for return!" + #define FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_EN "Unload filament completed,click for return!" +#endif + + +#define FILAMENT_CHANGE_TEXT_EN "Please click \nor ,After \npinter pause." +#define FILAMENT_DIALOG_LOAD_HEAT_TIPS_EN "Heating up the nozzle,\nplease wait..." +#define FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_EN "Heating up the nozzle,\nplease wait..." +#define FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_EN "Heat completed,please load filament \nto extruder,and click \nfor start loading." +#define FILAMENT_DIALOG_LOAD_CONFIRM2_TIPS_EN "Please load filament to extruder,\nand click for start loading." +#define FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_EN "Heat completed,please \nclick for start unloading.!" +#define FILAMENT_DIALOG_LOADING_TIPS_EN "Is loading ,please wait!" +#define FILAMENT_DIALOG_UNLOADING_TIPS_EN "Is unloading,please wait!" +#define FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_EN "Load filament completed,\nclick for return!" +#define FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_EN "Unload filament completed,\nclick for return!" + + +#define PRE_HEAT_EXT_TEXT_EN "E" +#define PRE_HEAT_BED_TEXT_EN "Bed" + +#define FILE_LOADING_EN "Loading......" +#if 0 + #define NO_FILE_AND_CHECK_EN "No files found!Please insert SD card or U disk!" +#else + #define NO_FILE_AND_CHECK_EN " No files found!\n Check the file system configuration!" +#endif + +#define NO_FILE_EN "No files found!" + +#define EXTRUDER_TEMP_TEXT_EN "Temper" +#define EXTRUDER_E_LENGTH1_TEXT_EN "Extrusion1" +#define EXTRUDER_E_LENGTH2_TEXT_EN "Extrusion2" +#define EXTRUDER_E_LENGTH3_TEXT_EN "Extrusion3" + +#define ABOUT_TYPE_TEXT_EN "Type: " +#define ABOUT_VERSION_TEXT_EN "Firmware: " +#define ABOUT_WIFI_TEXT_EN "WiFi: " + +#define PRINTING_OPERATION_EN "Option" +#define PRINTING_PAUSE_EN "Pause" +#define PRINTING_TEMP_EN "Temp." +#define PRINTING_CHANGESPEED_EN "Speed" +#define PRINTING_RESUME_EN "Resume" +#define PRINTING_STOP_EN "Stop" +#define PRINTING_MORE_EN "More" +#define PRINTING_EXTRUDER_EN "Extrusion" +#define PRINTING_MOVE_EN "Move" + +#define EXTRUDER_SPEED_EN "Extrusion" +#define MOVE_SPEED_EN "Move" +#define EXTRUDER_SPEED_STATE_EN "Extrude Speed" +#define MOVE_SPEED_STATE_EN "Move Speed" +#define STEP_1PERCENT_EN "1%" +#define STEP_5PERCENT_EN "5%" +#define STEP_10PERCENT_EN "10%" + +#define TITLE_READYPRINT_EN "ReadyPrint" +#define TITLE_PREHEAT_EN "Preheat" +#define TITLE_MOVE_EN "Move" +#define TITLE_HOME_EN "Home" +#define TITLE_EXTRUDE_EN "Extrusion" +#define TITLE_LEVELING_EN "Leveling" +#define TITLE_SET_EN "Settings" +#define TITLE_MORE_EN "More" +#define TITLE_CHOOSEFILE_EN "ChooseFile" +#define TITLE_PRINTING_EN "Printing" +#define TITLE_OPERATION_EN "Operation" +#define TITLE_ADJUST_EN "Adjust" +#define TITLE_WIRELESS_EN "Wireless" +#define TITLE_FILAMENT_EN "Filament" +#define TITLE_ABOUT_EN "About" +#define TITLE_FAN_EN "Fan" +#define TITLE_LANGUAGE_EN "Language" +#define TITLE_PAUSE_EN "Pause" +#define TITLE_CHANGESPEED_EN "Speed" +#define TITLE_CLOUD_TEXT_EN "Cloud" +#define TITLE_DIALOG_CONFIRM_EN "Confirm" +#define TITLE_FILESYS_EN "FileSys" + +#define AUTO_SHUTDOWN_EN "Auto" +#define MANUAL_SHUTDOWN_EN "Manual" + +#define DIALOG_CONFIRM_EN "Confirm" +#define DIALOG_CANCLE_EN "Cancel" +#define DIALOG_OK_EN "OK" +#define DIALOG_RESET_EN "Reset" +#define DIALOG_RETRY_EN "Retry" +#define DIALOG_DISABLE_EN "Disable" +#define DIALOG_PRINT_MODEL_EN "Print this model?" +#define DIALOG_CANCEL_PRINT_EN "Stop print?" +#define DIALOG_RETRY_EN "Retry" +#define DIALOG_STOP_EN "Stop" +#define DIALOG_REPRINT_FROM_BREAKPOINT_EN "Reprint from breakpoint?" +//#define DIALOG_UNBIND_PRINTER_EN "Unbind the printer?" +#define DIALOG_ERROR_TIPS1_EN "Error:no file,please check it again." +#define DIALOG_ERROR_TIPS2_EN "Error:transaction failed.please check display baudrate \nwhether as the same as mainboard!" +#define DIALOG_ERROR_TIPS3_EN "Error:file name or path is too long!" +#define DIALOG_CLOSE_MACHINE_EN "Closing machine......" +#define DIALOG_UNBIND_PRINTER_EN "Unbind the printer?" +#define DIALOG_FILAMENT_NO_PRESS_EN "Filament detection switch is not pressed" +#define DIALOG_PRINT_FINISH_EN "Done print!" +#define DIALOG_PRINT_TIME_EN "Print time: " +#define DIALOG_REPRINT_EN "Print again" +#define DIALOG_WIFI_ENABLE_TIPS_EN "The wifi module is being configured\nplease wait a moment....." + +#define HOTBED_ENABLE_EN "Enable heatbed" +#define MOTOR_EN_HIGH_LEVEL_EN "High" +#define MOTOR_EN_LOW_LEVEL_EN "Low" + +#define TEXT_WIFI_MENU_TITLE_EN "WI-FI" +#define TEXT_WIFI_SAPCE_EN "space" +#define TEXT_WIFI_LETTER_EN "abc" +#define TEXT_WIFI_DIGITAL_EN "123" +#define TEXT_WIFI_SYMBOL_EN "#+=" +#define TEXT_WIFI_PASSWORD_EN "Password" + +#define TEXT_WIFI_JOINING_EN "Joining Network..." +#define TEXT_WIFI_FAILED_JOIN_EN "Failed to Join Wi-Fi" +#define TEXT_WIFI_WIFI_CONECTED_EN "Wi-Fi Connected" + +#define TEXT_BUTTON_DISCONECTED_EN "Disconnect" +#define TEXT_WIFI_FORGET_EN "Forget Network" +#define TEXT_DISCONECTED_EN "Wi-Fi Connected" + +//wifi-list +#define MAIN_BUILT_EN "Build" +#define MAIN_FILAMENT_EN "Filament" +#define MAIN_SETUP_EN "Setup" +#define MAIN_ABOUT_EN "About" +#define MAIN_MENU_EN "Menu" +#define FILE_MENU_BUILD_EN "Build" +#define FILE_MENU_MENU_EN " < Menu" + +//about +#define ABOUT_TITLE_EN "About" +#define ABOUT_BUILT_MACHINES_EN "Built Machines" +#define ABOUT_SPARK_EN "Spark" +#define ABOUT_VERSION_EN "Version 1.1.0" +#define ABOUT_SERIAL_NUMBER_EN "Serial Number:" +#define ABOUT_S_NUMBER_EN "DCPLX02KFC6P" + +//set +#define SETUP_TITLE_EN "Setup" +#define SETUP_WIFI_EN "Wi-Fi" +#define SETUP_MANUAL_IP_EN "Manual IP" +#define SETUP_WIFI_NOT_CONNECTED_EN "Not Connected" +#define SETUP_WIFI_NETWORK_EN "WiFi_Network" + +//build +#define BUILD_TITLE_EN "Build" +#define BUILD_SD_CARD_EN "SD Card" +#define BUILD_USB_DRIVE_EN "USB Drive" + +//SD card +#define SD_CARD_TITLE_EN "SD Card" +#define SD_CARD_BACK_EN "< Back" +//USB Drive +#define USB_DRIVE_TITLE_EN "USB Drive" +#define USB_DRIVE_BACK_EN "< Back" +#define FILE_PAGES_EN "%d/%d" +#define FILE_NEXT_PAGE_EN "Next Page" + +//BUILD PLATE +#define PLATE_TITLE_EN "Build Plate" +#define PLATE_BACK_EN "< Back" +#define PLATE_CONFIRM_EN "Confirm >" +#define PLATE_TIPS_EN "Confirm that there is a Clear\nBuild Plate installed in the\nmachine." + +//build model +#define MODEL_TITLE_EN "Build Model" +#define MODEL_START_BUILD_EN "Start Build" +#define MODEL_BACK_EN "< Back" + +//building +#define BUILDING_TITLE_EN "Building" +#define BUILDING_MENU_EN "Build Menu" +#define BUILDING_COMPLETED "Build\nComplete" + +//building menu +#define BUILDING_MENU_TITLE_EN "Build Menu" +#define BUILDING_MENU_SETTINGS_EN "Build Settings" +#define BUILDING_MENU_PAUSE_EN "Pause Build" +#define BUILDING_MENU_CANCEL_EN "Cancel Build" +#define BUILDING_MENU_BACK_EN "< Back" + +//build settings +#define SETTINGS_TITLE_EN "Build Settings" +#define SETTINGS_NOZZLE_TEMPER_EN "Nozzle Temp:" +#define SETTINGS_NOZZLE_VALUE_EN "%d" +#define SETTINGS_BED_TEMPER_EN "Bed Temp:" +#define SETTINGS_BED_VALUE_EN "%d" +#define SETTINGS_BUILD_SPEED_EN "Build Speed:" +#define SETTINGS_SPEED_VALUE_EN "Standard" +#define SETTINGS_BACK_EN "< Back" + +//build paused +#define PAUSED_TITLE_EN "Build Paused" +#define PAUSED_RESUME_EN "Resume Build" +#define PAUSED_CANCEL_EN "Cancel Build" +#define PAUSED_BACK_EN "< Back" + +//build cancel +#define CANCEL_TITLE_EN "Cancel Build" +#define CANCEL_BUILD_EN "Cancel Build" +#define CANCEL_TIPS_EN "Are you sure you want to\ncancel this build? The model\nwill be deleted from this\nmachine. It will need to be\nresent from your computer\nbefore it can be built in the\nfuture." +#define CANCEL_BACK_EN "< Back" +#define CANCEL_BUILD_DISPLAY_EN "Build\nCanceled" +#define CANCEL_OVER_PLATE_TIPS_EN "Confirm that the Build Plate\nhas been removed from the\nmachine." + +//filament model enter +#define FILAMENT_MODEL_ENTER_TITLE_EN "Model-PLA" +#define FILAMENT_MODEL_ENTER_BACK_EN "< Back" +#define FILAMENT_MODEL_ENTER_BEGIN_EN "Begin >" +#define FILAMENT_MODEL_ENTER_TIPS_EN "The Model Filament spool\ncompartment is located on\nthe right side of the machine." + +//filament model PLA +#define FILAMENT_MODEL_PLA_TITLE_EN "Model-PLA" +#define FILAMENT_PLA_LOAD_TITLE_EN "Load Filament" +#define FILAMENT_PLA_UNLOAD_TITLE_EN "Unload Filament" +#define FILAMENT_MODEL_PLA_LOAD_EN "Load Filament" +#define FILAMENT_MODEL_PLA_UNLOAD_EN "Unload Filament" +//filament support enter +#define FILAMENT_SUPPORT_ENTER_TITLE_EN "Support-PVA" +#define FILAMENT_SUPPORT_ENTER_BACK_EN "< Back" +#define FILAMENT_SUPPORT_ENTER_BEGIN_EN "Begin >" +#define FILAMENT_SUPPORT_ENTER_TIPS_EN "The Support Filament spool\ncompartment is located on\nthe left side of the machine." +//filament heating +#define FILAMENT_HEATING_LOAD_TITLE_EN "Load Filament" +#define FILAMENT_HEATING_UNLOAD_TITLE_EN "Unload Filament" +#define FILAMENT_HEATING_CANCEL_EN "< Cancel" +#define FILAMENT_HEATING_MATERIAL_EN "Material:" +#define FILAMENT_HEATING_PLA_EN "Model-PLA" +#define FILAMENT_HEATING_TIPS_EN "Print head is heating..." +//rotate left +#define ROTATE_LEFT_LOAD_TITLE_EN "Load Filament" +#define ROTATE_LEFT_UNLOAD_TITLE_EN "Unload Filament" +#define ROTATE_LEFT_CANCEL_EN "< Cancel" +#define ROTATE_LEFT_MATERIAL_EN "Material:" +#define ROTATE_LEFT_PLA_EN "Model-PLA" +#define ROTATE_LEFT_NEXT_EN "Next >" +#define ROTATE_LEFT_TIPS_EN "Rotate extruder selection\ndial to the left." + +//hang spool +#define HANG_SPOOL_TITLE_EN "Load Filament" +#define HANG_SPOOL_PREVIOUS_EN "< Previous" +#define HANG_SPOOL_MATERIAL_EN "Material:" +#define HANG_SPOOL_PLA_EN "Model-PLA" +#define HANG_SPOOL_NEXT_EN "Next >" +#define HANG_SPOOL_TIPS_EN "Hang the spool in the spool\ncompartment as shown." + +//feed filament +#define FEED_FILAMENT_TITLE_EN "Load Filament" +#define FEED_FILAMENT_PREVIOUS_EN "< Previous" +#define FEED_FILAMENT_MATERIAL_EN "Material:" +#define FEED_FILAMENT_PLA_EN "Model-PLA" +#define FEED_FILAMENT_NEXT_EN "Next >" +#define FEED_FILAMENT_TIPS_EN "Feed filament into extruder\nup beyond the gears." + +//feed filament +#define ROTATE_UP_TITLE_EN "Load Filament" +#define ROTATE_UP_PREVIOUS_EN "< Previous" +#define ROTATE_UP_MATERIAL_EN "Material:" +#define ROTATE_UP_PLA_EN "Model-PLA" +#define ROTATE_UP_NEXT_EN "Next >" +#define ROTATE_UP_TIPS_EN "Rotate extruder selection\ndial up." + +//filament begin +#define FEED_BEGIN_TITLE_EN "Load Filament" +#define FEED_BEGIN_MATERIAL_EN "Material:" +#define FEED_BEGIN_PLA_EN "Model-PLA" +#define FEED_BEGIN_NEXT_EN "Next >" +#define FEED_BEGIN_TIPS_EN "Press Next when filament\nbegins to extrude." + +//filament finish +#define FEED_FINISH_TITLE_EN "Load Filament" +#define FEED_FINISH_MATERIAL_EN "Material:" +#define FEED_FINISH_PLA_EN "Model-PLA" +#define FEED_FINISH_NEXT_EN "Finish >" +#define FEED_FINISH_TIPS_EN "Remove filament from the\nnozzle and discard." +//fiament remove +#define REMOVE_SPOOL_TITLE_EN "Unload Filament" +#define REMOVE_SPOOL_PREVIOUS_EN "< Previous" +#define REMOVE_SPOOL_FINISH_EN "Finish >" +#define REMOVE_SPOOL_MATERIAL_EN "Material:" +#define REMOVE_SPOOL_PLA_EN "Model-PLA" +#define REMOVE_SPOOL_TIPS_EN "Remove the spool and pull\nfilament out of the machine." + +#define FILAMENT_SUPPORT_PVA_EN "Support-PVA" +#define LOAD_FINISH_EN "Load\nFilament\nComplete" +#define UNLOAD_FINISH_EN "Unload\nFilament\nComplete" + +//manual ip +#define MANUAL_IP_TITLE_EN "Manual IP" +#define MANUAL_IP_CANCEL_EN "< Cancel" +#define MANUAL_IP_APPLY_EN "Join >" +#define MANUAL_IP_ADDRESS_EN "IP Address" +#define MANUAL_IP_MASK_EN "Subnet Mask" +#define MANUAL_IP_GATEWAY_EN "Default Gateway" +#define MANUAL_IP_SERVER_EN "Name Server" +#define MANUAL_IP_INIT_DATA_EN "0.0.0.0" +#define MANUAL_TEXT_POINT_EN "." +#define MANUAL_TEXT_ENTER_EN "enter" + +//Wifi name +//#define TEXT_WIFI_MENU_TITLE_EN "WI-FI" +//#define TEXT_WIFI_SAPCE_EN "space" +//#define TEXT_WIFI_LETTER_EN "abc" +//#define TEXT_WIFI_DIGITAL_EN "123" +//#define TEXT_WIFI_SYMBOL_EN "#+=" +//#define TEXT_WIFI_PASSWORD_EN "Password" + +//#define TEXT_WIFI_POINT_BOLD_EN "`" + +//#define TEXT_WIFI_JOINING_EN "Joining\nNetwork..." +//#define TEXT_WIFI_FAILED_JOIN_EN "Failed to\nJoin Wi-Fi" +//#define TEXT_WIFI_WIFI_CONECTED_EN "Wi-Fi\nConnected" + +//#define TEXT_BUTTON_DISCONECTED_EN "Disconnect" +//#define TEXT_WIFI_FORGET_EN "Forget Network" +//#define TEXT_DISCONECTED_EN "Wi-Fi Connected" + +#define TEXT_FORGET_TIPS_TITLE_EN "Forget Network" +#define TEXT_FORGET_NETWORK_TIPS1_EN "Are you sure you want to\nforget this network?" +#define TEXT_FORGET_NETWORK_TIPS2_EN "This machine will no longer\njoin this Wi-Fi Network." + +#define TEXT_IPADDRESS_EN "IP Address: " + +#define TEXT_BUILD_FROM_CURA_CANCEL_TIPS1_EN "Are you sure you want to\ncancel this build?" +#define TEXT_BUILD_FROM_CURA_CANCEL_TIPS2_EN "The model will be deleted\nfrom this machine.It will\nneed to be resent from your\ncomputer before it can be\nbuilt in the future." + +#define DIALOG_CONFIRM_EN2 "Confirm" + +#define HEATING_TITLE_EN "Heating" +#define LEVELING_TITLE_EN "Leveling" + +#define ABOUT_SPARK_ADD_EN "Spark+" + +#define TEXT_RECEIVING_DATA_EN "Receiving Data" + +#define TEXT_BABY_STEP_EN "Babystep" + +#define PRINTING_OTHER_LANGUGE "Printing" +#define PRINTING_OPERATION_OTHER_LANGUGE "Operation" +#define PRINTING_PAUSE_OTHER_LANGUGE "Pause" + +#define MESSAGE_PAUSING_EN "Parking..." +#define MESSAGE_CHANGING_EN "Wait for filament change to start" +#define MESSAGE_UNLOAD_EN "Wait for filament unload" +#define MESSAGE_WAITING_EN "Press Button to resume print" +#define MESSAGE_INSERT_EN "Insert filament and press button to continue" +#define MESSAGE_LOAD_EN "Wait for filament load" +#define MESSAGE_PURGE_EN "Wait for filament purge" +#define MESSAGE_RESUME_EN "Wait for print to resume..." +#define MESSAGE_HEAT_EN "Press button to heat nozzle" +#define MESSAGE_HEATING_EN "Nozzle heating Please wait..." +#define MESSAGE_OPTION_EN "Purge more or continue print?" +#define MESSAGE_PURGE_MORE_EN "Purge" +#define MESSAGE_CONTINUE_PRINT_EN "Print" +#define EEPROM_SETTINGS_TITLE_EN "EEPROM Settings" +#define EEPROM_SETTINGS_STORE_EN "Store settings to EEPROM" +#define EEPROM_SETTINGS_READ_EN "Read settings from EEPROM" +#define EEPROM_SETTINGS_REVERT_EN "Revert settings to factory defaults" + +#define EEPROM_STORE_TIPS_EN "Store settings to EEPROM?" +#define EEPROM_READ_TIPS_EN "Read settings from EEPROM?" +#define EEPROM_REVERT_TIPS_EN "Revert settings to factory defaults?" diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_fr.h b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_fr.h new file mode 100644 index 000000000000..6944d6b23518 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_fr.h @@ -0,0 +1,281 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +//*************法文****************************// +#define TOOL_TEXT_FR "prêt" +#define PREHEAT_TEXT_FR "Préchauffe" +#define MOVE_TEXT_FR "Déplace" +#define HOME_TEXT_FR "Acceuil" +#define PRINT_TEXT_FR "Impression" +#define EXTRUDE_TEXT_FR "Extruder" +#define LEVELING_TEXT_FR "Leveling" +#define AUTO_LEVELING_TEXT_FR "AutoLevel" +#define SET_TEXT_FR "Config" +#define MORE_TEXT_FR "Plus" + +#define ADD_TEXT_FR "Ajouter" +#define DEC_TEXT_FR "Réduire" +#define EXTRUDER_1_TEXT_FR "Extr1" +#define EXTRUDER_2_TEXT_FR "Extr2" +#define HEATBED_TEXT_FR "Hotlit" +#define TEXT_1C_FR "1℃" +#define TEXT_5C_FR "5℃" +#define TEXT_10C_FR "10℃" +#define CLOSE_TEXT_FR "Off" + +#define BACK_TEXT_FR "Arrière" + +#define TOOL_PREHEAT_FR "Préchauffe" +#define TOOL_EXTRUDE_FR "Extruder" +#define TOOL_MOVE_FR "Déplace" +#define TOOL_HOME_FR "Acceuil" +#define TOOL_LEVELING_FR "Leveling" +#define TOOL_AUTO_LEVELING_FR "AutoLevel" +#define TOOL_FILAMENT_FR "Filament" +#define TOOL_MORE_FR "Plus" + +#define AXIS_X_ADD_TEXT_FR "X+" +#define AXIS_X_DEC_TEXT_FR "X-" +#define AXIS_Y_ADD_TEXT_FR "Y+" +#define AXIS_Y_DEC_TEXT_FR "Y-" +#define AXIS_Z_ADD_TEXT_FR "Z+" +#define AXIS_Z_DEC_TEXT_FR "Z-" +#define TEXT_01MM_FR "0.1mm" +#define TEXT_1MM_FR "1mm" +#define TEXT_10MM_FR "10mm" + +#define HOME_X_TEXT_FR "X" +#define HOME_Y_TEXT_FR "Y" +#define HOME_Z_TEXT_FR "Z" +#define HOME_ALL_TEXT_FR "ALL" +#define HOME_STOPMOVE_FR "Quickstop" + +#define PAGE_UP_TEXT_FR "En haut" +#define PAGE_DOWN_TEXT_FR "En bas" + +#define EXTRUDER_IN_TEXT_FR "Insérer" +#define EXTRUDER_OUT_TEXT_FR "éjecter" +#define EXTRUDE_1MM_TEXT_FR "1mm" +#define EXTRUDE_5MM_TEXT_FR "5mm" +#define EXTRUDE_10MM_TEXT_FR "10mm" +#define EXTRUDE_LOW_SPEED_TEXT_FR "Lente" +#define EXTRUDE_MEDIUM_SPEED_TEXT_FR "Moyen" +#define EXTRUDE_HIGH_SPEED_TEXT_FR "Rapide" + +#define LEVELING_POINT1_TEXT_FR "Premier" +#define LEVELING_POINT2_TEXT_FR "Seconde" +#define LEVELING_POINT3_TEXT_FR "Troisième" +#define LEVELING_POINT4_TEXT_FR "Quatrième" +#define LEVELING_POINT5_TEXT_FR "Cinquième" + +#define FILESYS_TEXT_FR "Fichier" +#define WIFI_TEXT_FR "WiFi" +#define FAN_TEXT_FR "Fan" +#define ABOUT_TEXT_FR "A propos" +#define BREAK_POINT_TEXT_FR "Continuer" +#define FILAMENT_TEXT_FR "Remplacer" +#define LANGUAGE_TEXT_FR "Langue" +#define MOTOR_OFF_TEXT_FR "M-hors" +#define MOTOR_OFF_XY_TEXT_FR "M-hors-XY" +#define SHUTDOWN_TEXT_FR "Eteindre" +#define MACHINE_PARA_FR "Config" +#define EEPROM_SETTINGS_FR "Eeprom Set" + +#define U_DISK_TEXT_FR "Clé usb" +#define SD_CARD_TEXT_FR "Carte SD" +#define WIFI_NAME_TEXT_FR "WiFi: " +#define WIFI_KEY_TEXT_FR "Key: " +#define WIFI_IP_TEXT_FR "IP: " +#define WIFI_AP_TEXT_FR "Etat: AP" +#define WIFI_STA_TEXT_FR "Etat: STA" +#define WIFI_CONNECTED_TEXT_FR "Connecté" +#define WIFI_DISCONNECTED_TEXT_FR "Déconnecté" +#define WIFI_EXCEPTION_TEXT_FR "Exception" +#define WIFI_RECONNECT_TEXT_FR "Reconnect" +#define CLOUD_TEXT_FR "Cloud" +#define CLOUD_BIND_FR "Lié" +#define CLOUD_UNBIND_FR "Délier" +#define CLOUD_UNBINDING_FR "Délier" +#define CLOUD_DISCONNECTED_FR "Déconnecté" +#define CLOUD_UNBINDED_FR "Délier" +#define CLOUD_BINDED_FR "Lié" +#define CLOUD_DISABLE_FR "Désactiver" + +#define FAN_ADD_TEXT_FR "Ajouter" +#define FAN_DEC_TEXT_FR "Réduire" +#define FAN_OPEN_TEXT_FR "100%" +#define FAN_HALF_TEXT_FR "50%" +#define FAN_CLOSE_TEXT_FR "0%" +#define FAN_TIPS1_TEXT_FR "ventilateur" +#define FAN_TIPS2_TEXT_FR "ventilateur\n0" + +#define FILAMENT_IN_TEXT_FR "Insérer" +#define FILAMENT_OUT_TEXT_FR "éjecter" +#define FILAMENT_EXT0_TEXT_FR "Extr1" +#define FILAMENT_EXT1_TEXT_FR "Extr2" +#define FILAMENT_HEAT_TEXT_FR "Preheat" +#define FILAMENT_STOP_TEXT_FR "Arrêter" +//#define FILAMENT_CHANGE_TEXT_FR "Filament remplacer" +#define FILAMENT_TIPS2_TEXT_FR "T:" +#define FILAMENT_TIPS3_TEXT_FR "Insérer le filament..." +#define FILAMENT_TIPS4_TEXT_FR "éjecter le filament..." +#define FILAMENT_TIPS5_TEXT_FR "Température trop basse pour démarrer, chauffez svp" +#define FILAMENT_TIPS6_TEXT_FR "Terminé" + +#if 0 + #define FILAMENT_REPLAYS_IDLE_TEXT_FR "Please click or <éjecter> \nto replace filament!" + #define FILAMENT_CHANGE_TEXT_FR "Please click or <éjecter>,\nAfter pinter pause." + #define FILAMENT_DIALOG_LOAD_HEAT_TIPS_FR "Heating up the nozzle,please wait..." + #define FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_FR "Heating up the nozzle,please wait..." + #define FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_FR "Heat completed,please load filament to extruder,and click for start loading." + #define FILAMENT_DIALOG_LOAD_CONFIRM2_TIPS_FR "Please load filament to extruder,and click for start loading." + #define FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_FR "Heat completed,please click for start unloading.!" + #define FILAMENT_DIALOG_LOADING_TIPS_FR "Is loading ,please wait!" + #define FILAMENT_DIALOG_UNLOADING_TIPS_FR "Is unloading,please wait!" + #define FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_FR "Load filament completed,click for return!" + #define FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_FR "Unload filament completed,click for return!" +#endif +#define FILAMENT_CHANGE_TEXT_FR "Please click \nor ,After \npinter pause." +#define FILAMENT_DIALOG_LOAD_HEAT_TIPS_FR "Heating up the nozzle,\nplease wait..." +#define FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_FR "Heating up the nozzle,\nplease wait..." +#define FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_FR "Heat completed,please load filament \nto extruder,and click \nfor start loading." +#define FILAMENT_DIALOG_LOAD_CONFIRM2_TIPS_FR "Please load filament to extruder,\nand click for start loading." +#define FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_FR "Heat completed,please \nclick for start unloading.!" +#define FILAMENT_DIALOG_LOADING_TIPS_FR "Is loading ,please wait!" +#define FILAMENT_DIALOG_UNLOADING_TIPS_FR "Is unloading,please wait!" +#define FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_FR "Load filament completed,\nclick for return!" +#define FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_FR "Unload filament completed,\nclick for return!" + + +#define PRE_HEAT_EXT_TEXT_FR "E" +#define PRE_HEAT_BED_TEXT_FR "Bed" + +#define FILE_LOADING_FR "Chargement......" +#if 0 + #define NO_FILE_AND_CHECK_FR "Aucun fichier trouvé! Insérez une carte SD ou un disque U!" +#else + #define NO_FILE_AND_CHECK_FR "Aucun fichier,vérifiez à nouveau!" +#endif + +#define NO_FILE_FR "Pas de fichier!" + + + +#define EXTRUDER_TEMP_TEXT_FR "Temper" +#define EXTRUDER_E_LENGTH1_TEXT_FR "Extruder1" +#define EXTRUDER_E_LENGTH2_TEXT_FR "Extruder2" +#define EXTRUDER_E_LENGTH3_TEXT_FR "Extruder3" + +#define ABOUT_TYPE_TEXT_FR "Type: " +#define ABOUT_VERSION_TEXT_FR "Firmware: " +#define ABOUT_WIFI_TEXT_FR "Wifi: " + +#define PRINTING_OPERATION_FR "Option" +#define PRINTING_PAUSE_FR "Pause" +#define PRINTING_TEMP_FR "Temp." +#define PRINTING_CHANGESPEED_FR "Speed" +#define PRINTING_RESUME_FR "Reprendre" +#define PRINTING_STOP_FR "Stop" +#define PRINTING_MORE_FR "Plus" +#define PRINTING_EXTRUDER_FR "Extruder" +#define PRINTING_MOVE_FR "Déplace" + +#define EXTRUDER_SPEED_FR "Extruder" +#define MOVE_SPEED_FR "Déplace" +#define EXTRUDER_SPEED_STATE_FR "Vitesse d'extrusion" +#define MOVE_SPEED_STATE_FR "vitesse de déplacement" +#define STEP_1PERCENT_FR "1%" +#define STEP_5PERCENT_FR "5%" +#define STEP_10PERCENT_FR "10%" + +#define TITLE_READYPRINT_FR "Prête" +#define TITLE_PREHEAT_FR "Préchauffe" +#define TITLE_MOVE_FR "Déplace" +#define TITLE_HOME_FR "Acceuil" +#define TITLE_EXTRUDE_FR "Extruder" +#define TITLE_LEVELING_FR "Leveling" +#define TITLE_SET_FR "Paramètres" +#define TITLE_MORE_FR "Plus" +#define TITLE_CHOOSEFILE_FR "Fichier" +#define TITLE_PRINTING_FR "Pimpression" +#define TITLE_OPERATION_FR "Option" +#define TITLE_ADJUST_FR "Réglage" +#define TITLE_WIRELESS_FR "Sans fil" +#define TITLE_FILAMENT_FR "Remplacer" +#define TITLE_ABOUT_FR "A propos" +#define TITLE_FAN_FR "Ventilateur" +#define TITLE_LANGUAGE_FR "Langue" +#define TITLE_PAUSE_FR "Pause" +#define TITLE_CHANGESPEED_FR "Speed" +#define TITLE_CLOUD_TEXT_FR "Cloud" +#define TITLE_DIALOG_CONFIRM_FR "Confirm" +#define TITLE_FILESYS_FR "FileSys" + +#define DIALOG_CLOSE_MACHINE_FR "Closing machine......" + +#define AUTO_SHUTDOWN_FR "Auto" +#define MANUAL_SHUTDOWN_FR "Manuel" + +#define DIALOG_CONFIRM_FR "Confirmer" +#define DIALOG_CANCLE_FR "Annuler" +#define DIALOG_OK_FR "OK" +#define DIALOG_RESET_FR "Réinitialiser" +#define DIALOG_RETRY_FR "Recommencez" +#define DIALOG_DISABLE_FR "Disable" +#define DIALOG_PRINT_MODEL_FR "Imprimer le fichier?" +#define DIALOG_CANCEL_PRINT_FR "Arrêter?" + +#define DIALOG_STOP_FR "Arrêter" +#define DIALOG_REPRINT_FROM_BREAKPOINT_FR "Continuer?" +//#define DIALOG_UNBIND_PRINTER_FR "Non lié?" +#define DIALOG_ERROR_TIPS1_FR "Erreur:error:Aucun fichier, \nvérifiez à nouveau." +#define DIALOG_ERROR_TIPS2_FR "Erreur:La opération a échoué. \nVerifiez que le baudrate de l'écran et de \nla carte mère soient identique!" +#define DIALOG_ERROR_TIPS3_FR "Erreur: le nom du fichier ou le \nchemin d'accès est trop long." +#define DIALOG_UNBIND_PRINTER_FR "Unbind the printer?" +#define DIALOG_FILAMENT_NO_PRESS_FR "Filament detection switch is not pressed" +#define DIALOG_PRINT_FINISH_FR "L'impression est terminée!" +#define DIALOG_PRINT_TIME_FR "Temps d'impression: " +#define DIALOG_REPRINT_FR "Print again" +#define DIALOG_WIFI_ENABLE_TIPS_FR "The wifi module is being configured,\nplease wait a moment....." + +#define MESSAGE_PAUSING_FR "Parking..." +#define MESSAGE_CHANGING_FR "Attente filament pour démarrer" +#define MESSAGE_UNLOAD_FR "Attente retrait du filament" +#define MESSAGE_WAITING_FR "Presser bouton,pour reprendre" +#define MESSAGE_INSERT_FR "Insérer filament et app. bouton pour continuer..." +#define MESSAGE_LOAD_FR "Attente chargement filament" +#define MESSAGE_PURGE_FR "Attente Purge filament" +#define MESSAGE_RESUME_FR "Attente reprise impression" +#define MESSAGE_HEAT_FR "Presser le bouton pour chauffer..." +#define MESSAGE_HEATING_FR "Buse en chauffe Patienter SVP..." +#define MESSAGE_OPTION_FR "Purger davantage ou continuer l'impression?" +#define MESSAGE_PURGE_MORE_FR "Purge" +#define MESSAGE_CONTINUE_PRINT_FR "Impression" +#define EEPROM_SETTINGS_TITLE_FR "Paramètres EEPROM" +#define EEPROM_SETTINGS_STORE_FR "Stocker les paramètres dans l'EEPROM" +#define EEPROM_SETTINGS_READ_FR "Lire les paramètres de l'EEPROM" +#define EEPROM_SETTINGS_REVERT_FR "Rétablir les paramètres par défaut d'usine" + +#define EEPROM_STORE_TIPS_FR "Stocker les paramètres dans l'EEPROM?" +#define EEPROM_READ_TIPS_FR "Lire les paramètres de l'EEPROM?" +#define EEPROM_REVERT_TIPS_FR "Rétablir les paramètres par défaut d'usine?" diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_it.h b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_it.h new file mode 100644 index 000000000000..f64ca4df79df --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_it.h @@ -0,0 +1,276 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +//****************意大利语***************************// +#define TOOL_TEXT_IT "Strumento" +#define PREHEAT_TEXT_IT "Prerisc" +#define MOVE_TEXT_IT "Muovi" +#define HOME_TEXT_IT "Home" +#define PRINT_TEXT_IT "Stampa" +#define EXTRUDE_TEXT_IT "Estrude" +#define LEVELING_TEXT_IT "Leveling" +#define AUTO_LEVELING_TEXT_IT "AutoLevel" +#define SET_TEXT_IT "Imposta" +#define MORE_TEXT_IT "Di più" + +#define ADD_TEXT_IT "Aumentare" +#define DEC_TEXT_IT "Ridurre" +#define EXTRUDER_1_TEXT_IT "Estrude1" +#define EXTRUDER_2_TEXT_IT "Estrude2" +#define HEATBED_TEXT_IT "Piano" +#define TEXT_1C_IT "1℃" +#define TEXT_5C_IT "5℃" +#define TEXT_10C_IT "10℃" +#define CLOSE_TEXT_IT "Spento" + +#define BACK_TEXT_IT "Indietro" + +#define TOOL_PREHEAT_IT "Prerisc" +#define TOOL_EXTRUDE_IT "Estrude" +#define TOOL_MOVE_IT "Muovi" +#define TOOL_HOME_IT "Home" +#define TOOL_LEVELING_IT "Leveling" +#define TOOL_AUTO_LEVELING_IT "Autolevel" +#define TOOL_FILAMENT_IT "Filamento" +#define TOOL_MORE_IT "Di più" + +#define AXIS_X_ADD_TEXT_IT "X+" +#define AXIS_X_DEC_TEXT_IT "X-" +#define AXIS_Y_ADD_TEXT_IT "Y+" +#define AXIS_Y_DEC_TEXT_IT "Y-" +#define AXIS_Z_ADD_TEXT_IT "Z+" +#define AXIS_Z_DEC_TEXT_IT "Z-" +#define TEXT_01MM_IT "0.1mm" +#define TEXT_1MM_IT "1mm" +#define TEXT_10MM_IT "10mm" + +#define HOME_X_TEXT_IT "X" +#define HOME_Y_TEXT_IT "Y" +#define HOME_Z_TEXT_IT "Z" +#define HOME_ALL_TEXT_IT "All" +#define HOME_STOPMOVE_IT "Quickstop" + +#define PAGE_UP_TEXT_IT "Pagina su" +#define PAGE_DOWN_TEXT_IT "Pagina giù" + +#define EXTRUDER_IN_TEXT_IT "Estru" +#define EXTRUDER_OUT_TEXT_IT "Ritra" +#define EXTRUDE_1MM_TEXT_IT "1mm" +#define EXTRUDE_5MM_TEXT_IT "5mm" +#define EXTRUDE_10MM_TEXT_IT "10mm" +#define EXTRUDE_LOW_SPEED_TEXT_IT "Bassa" +#define EXTRUDE_MEDIUM_SPEED_TEXT_IT "Media" +#define EXTRUDE_HIGH_SPEED_TEXT_IT "Alta" + +#define LEVELING_POINT1_TEXT_IT "Primo" +#define LEVELING_POINT2_TEXT_IT "Secondo" +#define LEVELING_POINT3_TEXT_IT "Terzo" +#define LEVELING_POINT4_TEXT_IT "Quarto" +#define LEVELING_POINT5_TEXT_IT "Quinto" + +#define FILESYS_TEXT_IT "FileSys" +#define WIFI_TEXT_IT "WIFI" +#define FAN_TEXT_IT "Ventola" +#define ABOUT_TEXT_IT "Circa" +#define BREAK_POINT_TEXT_IT "Continua" +#define FILAMENT_TEXT_IT "Filamento" +#define LANGUAGE_TEXT_IT "Lingua" +#define MOTOR_OFF_TEXT_IT "Motor off" +#define MOTOR_OFF_XY_TEXT_IT "Off-XY" +#define SHUTDOWN_TEXT_IT "Spento" +#define MACHINE_PARA_IT "Config" +#define EEPROM_SETTINGS_IT "Eeprom Set" + +#define U_DISK_TEXT_IT "USB" +#define SD_CARD_TEXT_IT "SD" +#define WIFI_NAME_TEXT_IT "WIFI: " +#define WIFI_KEY_TEXT_IT "KEY: " +#define WIFI_IP_TEXT_IT "IP: " +#define WIFI_AP_TEXT_IT "Stato: AP" +#define WIFI_STA_TEXT_IT "Stato: STA" +#define WIFI_CONNECTED_TEXT_IT "Connesso" +#define WIFI_DISCONNECTED_TEXT_IT "Disconnesso" +#define WIFI_EXCEPTION_TEXT_IT "Eccezione" +#define WIFI_RECONNECT_TEXT_IT "Reconnect" +#define CLOUD_TEXT_IT "Cloud" +#define CLOUD_BIND_IT "Legato" +#define CLOUD_UNBIND_IT "Libero" +#define CLOUD_DISCONNECTED_IT "Disconnesso" +#define CLOUD_UNBINDING_IT "Libero" +#define CLOUD_UNBINDED_IT "Sciolto" +#define CLOUD_BINDED_IT "Legato" +#define CLOUD_DISABLE_IT "Disable" + +#define FAN_ADD_TEXT_IT "Aumentare" +#define FAN_DEC_TEXT_IT "Ridurre" +#define FAN_OPEN_TEXT_IT "100%" +#define FAN_HALF_TEXT_IT "50%" +#define FAN_CLOSE_TEXT_IT "Spento" +#define FAN_TIPS1_TEXT_IT "Ventola" +#define FAN_TIPS2_TEXT_IT "Ventola\n0" + +#define FILAMENT_IN_TEXT_IT "Inser" +#define FILAMENT_OUT_TEXT_IT "Estra" +#define FILAMENT_EXT0_TEXT_IT "Estrude1" +#define FILAMENT_EXT1_TEXT_IT "Estrude2" +#define FILAMENT_HEAT_TEXT_IT "Preriscaldamento" +#define FILAMENT_STOP_TEXT_IT "Stop" +//#define FILAMENT_CHANGE_TEXT_IT "Filamento" +#define FILAMENT_TIPS2_TEXT_IT "T:" +#define FILAMENT_TIPS3_TEXT_IT "Inserimento del filamento..." +#define FILAMENT_TIPS4_TEXT_IT "Estrazione del filamento..." +#define FILAMENT_TIPS5_TEXT_IT "Temp is too low to go,please heat" +#define FILAMENT_TIPS6_TEXT_IT "Completato" + +#if 0 + #define FILAMENT_REPLAYS_IDLE_TEXT_IT "Please click or \nto replace filament!" + #define FILAMENT_CHANGE_TEXT_IT "Please click or ,\nAfter pinter pause." + #define FILAMENT_DIALOG_LOAD_HEAT_TIPS_IT "Heating up the nozzle,please wait..." + #define FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_IT "Heating up the nozzle,please wait..." + #define FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_IT "Heat completed,please load filament to extruder,and click for start loading." + #define FILAMENT_DIALOG_LOAD_CONFIRM2_TIPS_IT "Please load filament to extruder,and click for start loading." + #define FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_IT "Heat completed,please click for start unloading.!" + #define FILAMENT_DIALOG_LOADING_TIPS_IT "Is loading ,please wait!" + #define FILAMENT_DIALOG_UNLOADING_TIPS_IT "Is unloading,please wait!" + #define FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_IT "Load filament completed,click for return!" + #define FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_IT "Unload filament completed,click for return!" +#endif +#define FILAMENT_CHANGE_TEXT_IT "Please click \nor ,After \npinter pause." +#define FILAMENT_DIALOG_LOAD_HEAT_TIPS_IT "Heating up the nozzle,please wait..." +#define FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_IT "Heating up the nozzle,please wait..." +#define FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_IT "Heat completed,please load filament \nto extruder,and click \nfor start loading." +#define FILAMENT_DIALOG_LOAD_CONFIRM2_TIPS_IT "Please load filament to extruder,\nand click for start loading." +#define FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_IT "Heat completed,please \nclick for start unloading.!" +#define FILAMENT_DIALOG_LOADING_TIPS_IT "Is loading ,please wait!" +#define FILAMENT_DIALOG_UNLOADING_TIPS_IT "Is unloading,please wait!" +#define FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_IT "Load filament completed,\nclick for return!" +#define FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_IT "Unload filament completed,\nclick for return!" + + +#define PRE_HEAT_EXT_TEXT_IT "E" +#define PRE_HEAT_BED_TEXT_IT "Piano" + +#define FILE_LOADING_IT "Caricamento......" +#if 0 + #define NO_FILE_AND_CHECK_IT "Nessun file trovato! Inserisci la scheda SD o il disco U!" +#endif +#define NO_FILE_AND_CHECK_IT "Nessun file,\n per favore controllare di nuovo!" + +#define NO_FILE_IT "Nessun file!" + +#define EXTRUDER_TEMP_TEXT_IT "Temper" +#define EXTRUDER_E_LENGTH1_TEXT_IT "Estrude1" +#define EXTRUDER_E_LENGTH2_TEXT_IT "Estrude2" +#define EXTRUDER_E_LENGTH3_TEXT_IT "Estrude3" + +#define ABOUT_TYPE_TEXT_IT "Type: " +#define ABOUT_VERSION_TEXT_IT "Firmware: " +#define ABOUT_WIFI_TEXT_IT "WiFi: " + +#define PRINTING_OPERATION_IT "Opzioni" +#define PRINTING_PAUSE_IT "Pause" +#define PRINTING_TEMP_IT "Temp." +#define PRINTING_CHANGESPEED_IT "Velocità" +#define PRINTING_RESUME_IT "Recupero" +#define PRINTING_STOP_IT "Stop" +#define PRINTING_MORE_IT "Di più" +#define PRINTING_EXTRUDER_IT "Estrude" +#define PRINTING_MOVE_IT "Muovi" + +#define EXTRUDER_SPEED_IT "Estrude" +#define MOVE_SPEED_IT "Muovi" +#define EXTRUDER_SPEED_STATE_IT "Estrusione" +#define MOVE_SPEED_STATE_IT "Movimento" +#define STEP_1PERCENT_IT "1%" +#define STEP_5PERCENT_IT "5%" +#define STEP_10PERCENT_IT "10%" + +#define TITLE_READYPRINT_IT "Pronto" +#define TITLE_PREHEAT_IT "Preris" +#define TITLE_MOVE_IT "Muovi" +#define TITLE_HOME_IT "Home" +#define TITLE_EXTRUDE_IT "Estrude" +#define TITLE_LEVELING_IT "Livella" +#define TITLE_SET_IT "Impostare" +#define TITLE_MORE_IT "Di più" +#define TITLE_CHOOSEFILE_IT "File" +#define TITLE_PRINTING_IT "Stampa" +#define TITLE_OPERATION_IT "Opzioni" +#define TITLE_ADJUST_IT "Regolare" +#define TITLE_WIRELESS_IT "Wireless" +#define TITLE_FILAMENT_IT "Filamento" +#define TITLE_ABOUT_IT "Circa" +#define TITLE_FAN_IT "Ventola" +#define TITLE_LANGUAGE_IT "Lingua" +#define TITLE_PAUSE_IT "Pausa" +#define TITLE_CHANGESPEED_IT "Velocità" +#define TITLE_CLOUD_TEXT_IT "Cloud" +#define TITLE_DIALOG_CONFIRM_IT "Confirm" +#define TITLE_FILESYS_IT "FileSys" + +#define AUTO_SHUTDOWN_IT "Auto" +#define MANUAL_SHUTDOWN_IT "Manuale" + +#define DIALOG_CONFIRM_IT "Conferma" +#define DIALOG_CANCLE_IT "Cancella" +#define DIALOG_OK_IT "OK" +#define DIALOG_RESET_IT "Resettare" +#define DIALOG_RETRY_IT "Riprovare" +#define DIALOG_DISABLE_IT "Disable" +#define DIALOG_PRINT_MODEL_IT "Gcode stampa?" +#define DIALOG_CANCEL_PRINT_IT "Stop stampa?" +#define DIALOG_STOP_IT "Stop" +#define DIALOG_REPRINT_FROM_BREAKPOINT_IT "Continua a stampare dal \npunto di interruzione?" +//#define DIALOG_UNBIND_PRINTER_IT "Libero?" +#define DIALOG_ERROR_TIPS1_IT "Errore: nessun file, \nper favore controllare di nuovo." +#define DIALOG_ERROR_TIPS2_IT "Errore: operazione non riuscita, \nsi prega di controllare se il baudrate del \ndisplay è lo stesso scheda madre" +#define DIALOG_ERROR_TIPS3_IT "Errore: il nome del file o il \npercorso è troppo lungo!" +#define DIALOG_CLOSE_MACHINE_IT "Closing machine......" +#define DIALOG_UNBIND_PRINTER_IT "Unbind the printer?" +#define DIALOG_FILAMENT_NO_PRESS_IT "Filament detection switch is not pressed" +#define DIALOG_PRINT_FINISH_IT "La stampa è completa!" +#define DIALOG_PRINT_TIME_IT "Tempo di stampa: " +#define DIALOG_REPRINT_IT "Print again" +#define DIALOG_WIFI_ENABLE_TIPS_IT "The wifi module is being configured,\nplease wait a moment....." + +#define MESSAGE_PAUSING_IT "Parcheggiando..." +#define MESSAGE_CHANGING_IT "Attendere avvio del cambio di filamento" +#define MESSAGE_UNLOAD_IT "Attendere l'espulsione del filamento" +#define MESSAGE_WAITING_IT "Premi per riprendere la stampa" +#define MESSAGE_INSERT_IT "Inserisci il filamento e premi per continuare" +#define MESSAGE_LOAD_IT "Attendere il caricamento del filamento" +#define MESSAGE_PURGE_IT "Attendere lo spurgo del filamento" +#define MESSAGE_RESUME_IT "Attendere la ripresa della stampa..." +#define MESSAGE_HEAT_IT "Premi per riscaldare ugello" +#define MESSAGE_HEATING_IT "Riscaldam. ugello Attendere prego..." +#define MESSAGE_OPTION_IT "Eliminare di più o continuare a stampare?" +#define MESSAGE_PURGE_MORE_IT "Epurazione" +#define MESSAGE_CONTINUE_PRINT_IT "Stampa" +#define EEPROM_SETTINGS_TITLE_IT "Impostazioni EEPROM" +#define EEPROM_SETTINGS_STORE_IT "Memorizzare le impostazioni su EEPROM" +#define EEPROM_SETTINGS_READ_IT "Leggi le impostazioni dalla EEPROM" +#define EEPROM_SETTINGS_REVERT_IT "Ripristina le impostazioni predefinite di fabbrica" + +#define EEPROM_STORE_TIPS_IT "Memorizzare le impostazioni su EEPROM?" +#define EEPROM_READ_TIPS_IT "Leggi le impostazioni dalla EEPROM?" +#define EEPROM_REVERT_TIPS_IT "Ripristinare le impostazioni predefinite?" diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_ru.h b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_ru.h new file mode 100644 index 000000000000..9f695b376b59 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_ru.h @@ -0,0 +1,277 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +//****************俄语***************************// +#define TOOL_TEXT_RU "инструмент" +#define PREHEAT_TEXT_RU " нагрев" +#define MOVE_TEXT_RU "движение" +#define HOME_TEXT_RU "домой" +#define PRINT_TEXT_RU " печать" +#define EXTRUDE_TEXT_RU "экструзия" +#define LEVELING_TEXT_RU "уровень" +#define AUTO_LEVELING_TEXT_RU "aвто" +#define SET_TEXT_RU "настройки" +#define MORE_TEXT_RU "больше" + +#define ADD_TEXT_RU "добавить" +#define DEC_TEXT_RU "уменьшить" +#define EXTRUDER_1_TEXT_RU "экструдер1" +#define EXTRUDER_2_TEXT_RU "экструдер2" +#define HEATBED_TEXT_RU "стол" +#define TEXT_1C_RU "1℃" +#define TEXT_5C_RU "5℃" +#define TEXT_10C_RU "10℃" +#define CLOSE_TEXT_RU "выкл" + +#define BACK_TEXT_RU "назад" + +#define TOOL_PREHEAT_RU "нагрев" +#define TOOL_EXTRUDE_RU "экструзия" +#define TOOL_MOVE_RU "движение" +#define TOOL_HOME_RU "домой" +#define TOOL_LEVELING_RU "уровень" +#define TOOL_AUTO_LEVELING_RU "aвто" +#define TOOL_FILAMENT_RU "замена" +#define TOOL_MORE_RU "больше" + +#define AXIS_X_ADD_TEXT_RU "X+" +#define AXIS_X_DEC_TEXT_RU "X-" +#define AXIS_Y_ADD_TEXT_RU "Y+" +#define AXIS_Y_DEC_TEXT_RU "Y-" +#define AXIS_Z_ADD_TEXT_RU "Z+" +#define AXIS_Z_DEC_TEXT_RU "Z-" +#define TEXT_01MM_RU "0.1mm" +#define TEXT_1MM_RU "1mm" +#define TEXT_10MM_RU "10mm" + +#define HOME_X_TEXT_RU "X" +#define HOME_Y_TEXT_RU "Y" +#define HOME_Z_TEXT_RU "Z" +#define HOME_ALL_TEXT_RU "Home" +#define HOME_STOPMOVE_RU "Quickstop" + +#define PAGE_UP_TEXT_RU "вверх" +#define PAGE_DOWN_TEXT_RU "вниз" + +#define EXTRUDER_IN_TEXT_RU "втянуть" +#define EXTRUDER_OUT_TEXT_RU "выдавить" +#define EXTRUDE_1MM_TEXT_RU "1mm" +#define EXTRUDE_5MM_TEXT_RU "5mm" +#define EXTRUDE_10MM_TEXT_RU "10mm" +#define EXTRUDE_LOW_SPEED_TEXT_RU "мин" +#define EXTRUDE_MEDIUM_SPEED_TEXT_RU "сред" +#define EXTRUDE_HIGH_SPEED_TEXT_RU "выс" + +#define LEVELING_POINT1_TEXT_RU "1точка" +#define LEVELING_POINT2_TEXT_RU "2точка" +#define LEVELING_POINT3_TEXT_RU "3точка" +#define LEVELING_POINT4_TEXT_RU "4точка" +#define LEVELING_POINT5_TEXT_RU "5точка" + +#define FILESYS_TEXT_RU "система" +#define WIFI_TEXT_RU "WiFi" +#define FAN_TEXT_RU "вентилятор" +#define ABOUT_TEXT_RU "инфо" +#define BREAK_POINT_TEXT_RU "продолжить" +#define FILAMENT_TEXT_RU "замена" +#define LANGUAGE_TEXT_RU "язык" +#define MOTOR_OFF_TEXT_RU "отклмотор" +#define MOTOR_OFF_XY_TEXT_RU "Off-XY" +#define SHUTDOWN_TEXT_RU "выключение" +#define MACHINE_PARA_RU "конфиг" +#define EEPROM_SETTINGS_RU "Eeprom Set" + +#define U_DISK_TEXT_RU "U диск" +#define SD_CARD_TEXT_RU "SD диск" +#define WIFI_NAME_TEXT_RU "WiFi: " +#define WIFI_KEY_TEXT_RU "пароль: " +#define WIFI_IP_TEXT_RU "IP: " +#define WIFI_AP_TEXT_RU "режим: AP" +#define WIFI_STA_TEXT_RU "режим: STA" +#define WIFI_CONNECTED_TEXT_RU "подключен" +#define WIFI_DISCONNECTED_TEXT_RU "не подключен" +#define WIFI_EXCEPTION_TEXT_RU "исключение" +#define WIFI_RECONNECT_TEXT_RU "Reconnect" +#define CLOUD_TEXT_RU "облако" +#define CLOUD_BIND_RU "соединён" +#define CLOUD_UNBIND_RU "не соединён" +#define CLOUD_UNBINDING_RU "Unbinding" +#define CLOUD_DISCONNECTED_RU "Disconnected" +#define CLOUD_UNBINDED_RU "Unbinded" +#define CLOUD_BINDED_RU "Binded" +#define CLOUD_DISABLE_RU "Disable" + +#define FAN_ADD_TEXT_RU "добавить" +#define FAN_DEC_TEXT_RU "уменьшить" +#define FAN_OPEN_TEXT_RU "100%" +#define FAN_HALF_TEXT_RU "50%" +#define FAN_CLOSE_TEXT_RU "откл" +#define FAN_TIPS1_TEXT_RU "вентилятор" +#define FAN_TIPS2_TEXT_RU "вентилятор\nоткл" + +#define FILAMENT_IN_TEXT_RU "втянуть" +#define FILAMENT_OUT_TEXT_RU "выдавить" +#define FILAMENT_EXT0_TEXT_RU "экструдер1" +#define FILAMENT_EXT1_TEXT_RU "экструдер2" +#define FILAMENT_HEAT_TEXT_RU "нагрев" +#define FILAMENT_STOP_TEXT_RU "стоп" +//#define FILAMENT_CHANGE_TEXT_RU "замена" +#define FILAMENT_TIPS2_TEXT_RU "T:" +#define FILAMENT_TIPS3_TEXT_RU "втянуть..." +#define FILAMENT_TIPS4_TEXT_RU "вядавить..." +#define FILAMENT_TIPS5_TEXT_RU "Низкая температура, \nнеобходим нагрев" +#define FILAMENT_TIPS6_TEXT_RU "завершено" + +#if 0 + #define FILAMENT_REPLAYS_IDLE_TEXT_RU "Please click <втянуть> or <выдавить> \nto replace filament!" + #define FILAMENT_CHANGE_TEXT_RU "Please click <втянуть> or <выдавить>,\nAfter pinter pause." + #define FILAMENT_DIALOG_LOAD_HEAT_TIPS_RU "Heating up the nozzle,please wait..." + #define FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_RU "Heating up the nozzle,please wait..." + #define FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_RU "Heat completed,please load filament to extruder,and click <да> for start loading." + #define FILAMENT_DIALOG_LOAD_CONFIRM2_TIPS_RU "Please load filament to extruder,and click <да> for start loading." + #define FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_RU "Heat completed,please click <да> for start unloading.!" + #define FILAMENT_DIALOG_LOADING_TIPS_RU "Is loading ,please wait!" + #define FILAMENT_DIALOG_UNLOADING_TIPS_RU "Is unloading,please wait!" + #define FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_RU "Load filament completed,click <да> for return!" + #define FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_RU "Unload filament completed,click <да> for return!" +#endif +#define FILAMENT_CHANGE_TEXT_RU "Please click \nor ,After \npinter pause." +#define FILAMENT_DIALOG_LOAD_HEAT_TIPS_RU "Heating up the nozzle,\nplease wait..." +#define FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_RU "Heating up the nozzle,\nplease wait..." +#define FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_RU "Heat completed,please load filament \nto extruder,and click \nfor start loading." +#define FILAMENT_DIALOG_LOAD_CONFIRM2_TIPS_RU "Please load filament to extruder,\nand click for start loading." +#define FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_RU "Heat completed,please \nclick for start unloading.!" +#define FILAMENT_DIALOG_LOADING_TIPS_RU "Is loading ,please wait!" +#define FILAMENT_DIALOG_UNLOADING_TIPS_RU "Is unloading,please wait!" +#define FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_RU "Load filament completed,\nclick for return!" +#define FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_RU "Unload filament completed,\nclick for return!" + + +#define PRE_HEAT_EXT_TEXT_RU "E" +#define PRE_HEAT_BED_TEXT_RU "стол" + +#define FILE_LOADING_RU "загрузка......" +#if 0 + #define NO_FILE_AND_CHECK_RU "Файлы не найдены! Вставьте SD-карту или диск U!" +#endif +#define NO_FILE_AND_CHECK_RU "нет файла,попробуйте ещё раз!" + +#define NO_FILE_RU "нет файла!" + +#define EXTRUDER_TEMP_TEXT_RU "температура" +#define EXTRUDER_E_LENGTH1_TEXT_RU "экструзия1" +#define EXTRUDER_E_LENGTH2_TEXT_RU "экструзия2" +#define EXTRUDER_E_LENGTH3_TEXT_RU "экструзия3" + +#define ABOUT_TYPE_TEXT_RU "Type: " +#define ABOUT_VERSION_TEXT_RU "Firmware: " +#define ABOUT_WIFI_TEXT_RU "WiFi: " + +#define PRINTING_OPERATION_RU "управление" +#define PRINTING_PAUSE_RU "пауза" +#define PRINTING_TEMP_RU "темп" +#define PRINTING_CHANGESPEED_RU "скорости" +#define PRINTING_RESUME_RU "возобновить" +#define PRINTING_STOP_RU "стоп" +#define PRINTING_MORE_RU "больше" +#define PRINTING_EXTRUDER_RU "экстр" +#define PRINTING_MOVE_RU "движение" + +#define EXTRUDER_SPEED_RU "экстр" +#define MOVE_SPEED_RU "движ" +#define EXTRUDER_SPEED_STATE_RU "скорость экстр" +#define MOVE_SPEED_STATE_RU "скорость движ" +#define STEP_1PERCENT_RU "1%" +#define STEP_5PERCENT_RU "5%" +#define STEP_10PERCENT_RU "10%" + +#define TITLE_READYPRINT_RU "готов к" +#define TITLE_PREHEAT_RU "движение" +#define TITLE_MOVE_RU "движение" +#define TITLE_HOME_RU "Home" +#define TITLE_EXTRUDE_RU "экструзия" +#define TITLE_LEVELING_RU "уровень" +#define TITLE_SET_RU "настройки" +#define TITLE_MORE_RU "больше" +#define TITLE_CHOOSEFILE_RU "файла" +#define TITLE_PRINTING_RU "печать" +#define TITLE_OPERATION_RU "управление" +#define TITLE_ADJUST_RU "регулировать" +#define TITLE_WIRELESS_RU "Wireless" +#define TITLE_FILAMENT_RU "замена" +#define TITLE_ABOUT_RU "инфо" +#define TITLE_FAN_RU "вентилятор" +#define TITLE_LANGUAGE_RU "язык" +#define TITLE_PAUSE_RU "пауза" +#define TITLE_CHANGESPEED_RU "скорости" +#define TILE_TOOL_RU "инструмент" +#define TITLE_CLOUD_TEXT_RU "Cloud" +#define TITLE_DIALOG_CONFIRM_RU "Confirm" +#define TITLE_FILESYS_RU "FileSys" + +#define AUTO_SHUTDOWN_RU "авто-откл" +#define MANUAL_SHUTDOWN_RU "ручн-откл" + +#define DIALOG_CONFIRM_RU "да"//"подтвердить" +#define DIALOG_CANCLE_RU "отмена" +#define DIALOG_OK_RU "да" +#define DIALOG_RESET_RU "сброс" +#define DIALOG_RETRY_RU "повтор" +#define DIALOG_DISABLE_RU "запретить" +#define DIALOG_PRINT_MODEL_RU "печать модели?" +#define DIALOG_CANCEL_PRINT_RU "стоп?" +#define DIALOG_STOP_RU "стоп" +#define DIALOG_REPRINT_FROM_BREAKPOINT_RU "продолжить?" +//#define DIALOG_UNBIND_PRINTER_RU "разрыв?" +#define DIALOG_ERROR_TIPS1_RU "ошибка:нет файла, попробуйте ещё раз." +#define DIALOG_ERROR_TIPS2_RU "ошибка:сбой передачи. установите скорость \nпередачи данных как на плате управления!" +#define DIALOG_ERROR_TIPS3_RU "ошибка: имя файла слишком длинное!" +#define DIALOG_CLOSE_MACHINE_RU "Closing machine......" +#define DIALOG_UNBIND_PRINTER_RU "Unbind the printer?" +#define DIALOG_FILAMENT_NO_PRESS_RU "Filament detection switch is not pressed" +#define DIALOG_PRINT_FINISH_RU "Печать завершена!" +#define DIALOG_PRINT_TIME_RU "Время печати: " +#define DIALOG_REPRINT_RU "Print again" +#define DIALOG_WIFI_ENABLE_TIPS_RU "The wifi module is being configured,\nplease wait a moment....." + +#define MESSAGE_PAUSING_RU "Стоянка..." +#define MESSAGE_CHANGING_RU "Подождите, пока начнется смена филамента" +#define MESSAGE_UNLOAD_RU "Дождитесь выгрузки нити" +#define MESSAGE_WAITING_RU "Нажмите кнопку,чтобы возобновить печать" +#define MESSAGE_INSERT_RU "Вставьте нить и нажмите кнопку,чтобы продолжить" +#define MESSAGE_LOAD_RU "Дождитесь загрузки нити" +#define MESSAGE_PURGE_RU "Дождитесь чистки нити" +#define MESSAGE_RESUME_RU "Подождите,пока печать возобновится ..." +#define MESSAGE_HEAT_RU "Нажмите кнопку, чтобы нагреть форсунку" +#define MESSAGE_HEATING_RU "Подогрев форсунки Пожалуйста, подождите ..." +#define MESSAGE_OPTION_RU "Очистить больше или продолжить печать?" +#define MESSAGE_PURGE_MORE_RU "чистка" +#define MESSAGE_CONTINUE_PRINT_RU "Распечатать" +#define EEPROM_SETTINGS_TITLE_RU "Настройки EEPROM" +#define EEPROM_SETTINGS_STORE_RU "Сохранение настроек в EEPROM" +#define EEPROM_SETTINGS_READ_RU "Чтение настроек из EEPROM" +#define EEPROM_SETTINGS_REVERT_RU "Восстановить заводские настройки по умолчанию" + +#define EEPROM_STORE_TIPS_RU "Сохранить настройки в EEPROM?" +#define EEPROM_READ_TIPS_RU "Читать настройки из EEPROM?" +#define EEPROM_REVERT_TIPS_RU "Revert settings to factory defaults?" diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_s_cn.h b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_s_cn.h new file mode 100644 index 000000000000..118992777048 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_s_cn.h @@ -0,0 +1,499 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +//*************简体中文***********************// +#define NEXT_CN "下一页" +#define PREVIOUS_CN "上一页" +#define DEFAULT_CN "默认值" +#define KEY_BACK_CN "退格" +#define KEY_REST_CN "重置" +#define KEY_CONFIRM_CN "确定" + +#define MACHINE_PARA_TITLE_CN "机器参数" +#define MACHINE_TYPE_CNOFIG_CN "机器设置" +#define MOTOR_CONFIG_CN "电机设置" +#define MACHINE_LEVELING_CONFIG_CN "调平设置" +#define ADVANCE_CONFIG_CN "高级设置" + +#define MACHINE_CONFIG_TITLE_CN "机器参数>机器配置" +#define MACHINE_TYPE_CN "机型选择" +#define MACHINE_STROKE_CN "行程设置" +#define MACHINE_HOMEDIR_CN "归零方向" +#define MACHINE_ENDSTOP_TYPE_CN "限位开关类型" +#define MACHINE_FILAMENT_CONFIG_CN "换料设置" + +#define MACHINE_TYPE_CONFIG_TITLE_CN "机器参数>机型选择" +#define MACHINE_TYPE_XYZ_CN "XYZ机型" +#define MACHINE_TYPE_DELTA_CN "Delta机型" +#define MACHINE_TYPE_COREXY_CN "Corexy机型" + +#define MACHINE_STROKE_CONF_TITLE_CN "机器参数>机器行程" +#define X_MAX_LENGTH_CN "X轴最大行程" +#define Y_MAX_LENGTH_CN "Y轴最大行程" +#define Z_MAX_LENGTH_CN "Z轴最大行程" + +#define X_MIN_LENGTH_CN "X轴最小行程" +#define Y_MIN_LENGTH_CN "Y轴最小行程" +#define Z_MIN_LENGTH_CN "Z轴最小行程" + +#define HOME_DIR_CONF_TITLE_CN "机器参数>归零方向" +#define HOME_DIR_X_CN "X轴归零方向" +#define HOME_DIR_Y_CN "Y轴归零方向" +#define HOME_DIR_Z_CN "Z轴归零方向" +#define HOME_MIN_CN "MIN" +#define HOME_MAX_CN "MAX" + +#define ENDSTOP_CONF_TITLE_CN "机器参数>限位开关" +#define MIN_ENDSTOP_X_CN "X轴最小限位" +#define MIN_ENDSTOP_Y_CN "Y轴最小限位" +#define MIN_ENDSTOP_Z_CN "Z轴最小限位" +#define MAX_ENDSTOP_X_CN "X轴最大限位" +#define MAX_ENDSTOP_Y_CN "Y轴最大限位" +#define MAX_ENDSTOP_Z_CN "Z轴最大限位" +#define ENDSTOP_FIL_CN "断料开关类型" +#define ENDSTOP_LEVEL_CN "调平开关类型" +#define ENDSTOP_OPENED_CN "常开" +#define ENDSTOP_CLOSED_CN "常闭" + +#define FILAMENT_CONF_TITLE_CN "换料设置" +#define FILAMENT_IN_LENGTH_CN "进料长度" +#define FILAMENT_IN_SPEED_CN "进料速度" +#define FILAMENT_TEMPERATURE_CN "换料温度" +#define FILAMENT_OUT_LENGTH_CN "退料长度" +#define FILAMENT_OUT_SPEED_CN "退料速度" + +#define LEVELING_CONF_TITLE_CN "机器参数>调平设置" +#define LEVELING_PARA_CONF_CN "调平设置" +#define LEVELING_MANUAL_POS_CN "手动调平坐标设置" +#define LEVELING_AUTO_COMMAND_CN "自动调平指令设置" +#define LEVELING_AUTO_ZOFFSET_CN "挤出头与调平开关偏移设置" + +#define LEVELING_PARA_CONF_TITLE_CN "调平参数" +#define AUTO_LEVELING_ENABLE_CN "自动调平" +#define BLTOUCH_LEVELING_ENABLE_CN "启动BLtouch" +#define PROBE_PORT_CN "调平探针接口" +#define PROBE_X_OFFSET_CN "探针X方向偏移" +#define PROBE_Y_OFFSET_CN "探针Y方向偏移" +#define PROBE_Z_OFFSET_CN "探针Z方向偏移" +#define PROBE_XY_SPEED_CN "探针XY方向移动速度" +#define PROBE_Z_SPEED_CN "探针Z方向移动速度" +#define ENABLE_CN "是" +#define DISABLE_CN "否" +#define Z_MIN_CN "ZMin" +#define Z_MAX_CN "ZMax" + +#define DELTA_LEVEL_CONF_TITLE_CN "Delta机器参数" +#define DELTA_LEVEL_CONF_CN "Delta机器调平" +#define DELTA_MACHINE_RADIUS_CN "机器半径" +#define DELTA_DIAGONAL_ROD_CN "机器杆长" +#define DELTA_PRINT_RADIUS_CN "打印半径" +#define DELTA_HEIGHT_CN "打印高度" +#define SMOOTH_ROD_OFFSET_CN "滑块偏移" +#define EFFECTOR_OFFSET_CN "效应器偏移" +#define CALIBRATION_RADIUS_CN "调平半径" + +#define XYZ_LEVEL_CONF_TITLE_CN "XYZ机器参数" +#define PROBE_REACH_MAX_LEFT_CN "探针达到最左位置" +#define PROBE_REACH_MAX_RIGHT_CN "探针达到最右位置" +#define PROBE_REACH_MAX_FRONT_CN "探针达到最前位置" +#define PROBE_REACH_MAX_BACK_CN "探针达到最后位置" + +#define TEMPERATURE_CONF_TITLE_CN "机器参数>温度设置" +#define NOZZLE_CONF_CN "喷头设置" +#define HOTBED_CONF_CN "热床设置" +#define PREHEAT_TEMPER_CN "预设温度" + +#define NOZZLE_CONF_TITLE_CN "机器参数>喷头设置" +#define NOZZLECNT_CN "喷头数量" +#define NOZZLE_TYPE_CN "E0温感类型" +#define NOZZLE_ADJUST_TYPE_CN "PID调温" +#define NOZZLE_MIN_TEMPERATURE_CN "最低温度" +#define NOZZLE_MAX_TEMPERATURE_CN "最高温度" +#define EXTRUD_MIN_TEMPER_CN "最低挤出温度" + +#define HOTBED_CONF_TITLE_CN "机器参数>热床设置" +#define HOTBED_ADJUST_CN "PID调温" +#define HOTBED_MIN_TEMPERATURE_CN "最低温度" +#define HOTBED_MAX_TEMPERATURE_CN "最高温度" + +#define MOTOR_CONF_TITLE_CN "机器参数>电机设置" +#define MAXFEEDRATE_CONF_CN "最大速度设置" +#define ACCELERATION_CONF_CN "加速度设置" +#define JERKCONF_CN "突变速度设置" +#define STEPSCONF_CN "脉冲设置" +#define TMC_CURRENT_CN "TMC 驱动电流设置" +#define TMC_STEP_MODE_CN "TMC 驱动模式设置" +#define MOTORDIRCONF_CN "电机方向设置" +#define HOMEFEEDRATECONF_CN "归零速度设置" +#define HOMING_SENSITIVITY_CONF_CN "无限位回零灵敏度调节" + +#define MAXFEEDRATE_CONF_TITLE_CN "机器参数>最大速度" +#define X_MAXFEEDRATE_CN "X轴最大速度" +#define Y_MAXFEEDRATE_CN "Y轴最大速度" +#define Z_MAXFEEDRATE_CN "Z轴最大速度" +#define E0_MAXFEEDRATE_CN "E0轴最大速度" +#define E1_MAXFEEDRATE_CN "E1轴最大速度" + +#define ACCELERATION_CONF_TITLE_CN "机器参数>加速度" +#define PRINT_ACCELERATION_CN "打印加速度" +#define RETRACT_ACCELERATION_CN "回抽加速度" +#define TRAVEL_ACCELERATION_CN "空载加速度" +#define X_ACCELERATION_CN "X轴加速度" +#define Y_ACCELERATION_CN "Y轴加速度" +#define Z_ACCELERATION_CN "Z轴加速度" +#define E0_ACCELERATION_CN "E0轴加速度" +#define E1_ACCELERATION_CN "E1轴加速度" + +#define JERK_CONF_TITLE_CN "机器参数>突变速度" +#define X_JERK_CN "X轴突变速度" +#define Y_JERK_CN "Y轴突变速度" +#define Z_JERK_CN "Z轴突变速度" +#define E_JERK_CN "E轴突变速度" + +#define STEPS_CONF_TITLE_CN "机器参数>脉冲设置" +#define X_STEPS_CN "X轴脉冲" +#define Y_STEPS_CN "Y轴脉冲" +#define Z_STEPS_CN "Z轴脉冲" +#define E0_STEPS_CN "E0轴脉冲" +#define E1_STEPS_CN "E1轴脉冲" + +#define TMC_CURRENT_CONF_TITLE_CN "机器参数>TMC电流设置" +#define X_TMC_CURRENT_CN "X轴电流(毫安)" +#define Y_TMC_CURRENT_CN "Y轴电流(毫安)" +#define Z_TMC_CURRENT_CN "Z轴电流(毫安)" +#define E0_TMC_CURRENT_CN "E0轴电流(毫安)" +#define E1_TMC_CURRENT_CN "E1轴电流(毫安)" + +#define TMC_MODE_CONF_TITLE_CN "机器参数>TMC模式设置" +#define X_TMC_MODE_CN "X轴是否使能静音模式" +#define Y_TMC_MODE_CN "Y轴是否使能静音模式" +#define Z_TMC_MODE_CN "Z轴是否使能静音模式" +#define E0_TMC_MODE_CN "E0轴是否使能静音模式" +#define E1_TMC_MODE_CN "E1轴是否使能静音模式" + +#define MOTORDIR_CONF_TITLE_CN "机器参数>电机方向" +#define X_MOTORDIR_CN "X轴电机方向" +#define Y_MOTORDIR_CN "Y轴电机方向" +#define Z_MOTORDIR_CN "Z轴电机方向" +#define E0_MOTORDIR_CN "E0轴电机方向" +#define E1_MOTORDIR_CN "E1轴电机方向" +#define INVERT_P_CN "正向" +#define INVERT_N_CN "反向" + +#define HOMEFEEDRATE_CONF_TITLE_CN "机器参数>归零速度" +#define X_HOMESPEED_CN "XY轴归零速度" +#define Y_HOMESPEED_CN "Y轴归零速度" +#define Z_HOMESPEED_CN "Z轴归零速度" + +#define ADVANCED_CONF_TITLE_CN "机器参数>高级设置" +#define PWROFF_DECTION_CN "断电检测模块" +#define PWROFF_AFTER_PRINT_CN "启动打完关机功能" +#define HAVE_UPS_CN "机器配备UPS电源" +#define Z2_AND_Z2ENDSTOP_CONF_CN "双Z轴双限位功能设置" +#define ENABLE_PINS_CONF_CN "电机使能脚电平设置" +#define WIFI_SETTINGS_CN "Wi-Fi参数设置" +#define ENCODER_SETTINGS_CN "旋钮设置" + +#define Z2_AND_Z2ENDSTOP_CONF_TITLE_CN "双z双限位设置" +#define Z2_ENABLE_CN "启用Z2轴" +#define Z2_ENDSTOP_CN "启用Z2限位" +#define Z2_PORT_CN "Z2限位接口" + +#define ENABLE_PINS_CONF_TITLE_CN "电机使能脚电平" +#define X_ENABLE_PINS_INVERT_CN "X轴电机使能电平" +#define Y_ENABLE_PINS_INVERT_CN "Y轴电机使能电平" +#define Z_ENABLE_PINS_INVERT_CN "Z轴电机使能电平" +#define E_ENABLE_PINS_INVERT_CN "E轴电机使能电平" + +#define PAUSE_POSITION_CN "打印暂停位置设置" +#define PAUSE_POSITION_X_CN "X轴暂停位置(绝对位置,-1无效)" +#define PAUSE_POSITION_Y_CN "Y轴暂停位置(绝对位置,-1无效)" +#define PAUSE_POSITION_Z_CN "Z轴暂停位置(相对位置,-1无效)" +#define WIFI_SETTINGS_TITLE_CN "机器参数>Wi-Fi设置" +#define WIFI_SETTINGS_MODE_CN "Wi-Fi 模式" +#define WIFI_SETTINGS_NAME_CN "Wi-Fi 名称: " +#define WIFI_SETTINGS_PASSWORD_CN "Wi-Fi 密码: " +#define WIFI_SETTINGS_CLOUD_CN "是否使用云服务?" +#define WIFI_SETTINGS_CONFIG_CN "配置" +#define WIFI_SETTINGS_EDIT_CN "编辑" +#define WIFI_CONFIG_TIPS_CN "进行Wi-Fi配置?" + +#define OFFSET_TITLE_CN "机器参数>偏移设置" +#define OFFSET_X_CN "X轴与调平开关偏移" +#define OFFSET_Y_CN "Y轴与调平开关偏移" +#define OFFSET_Z_CN "Z轴与调平开关偏移" + +#define HOMING_SENSITIVITY_CONF_TITLE_CN "机器参数>灵敏度调节" +#define X_SENSITIVITY_CN "X轴灵敏度" +#define Y_SENSITIVITY_CN "Y轴灵敏度" +#define Z_SENSITIVITY_CN "Z轴灵敏度" +#define Z2_SENSITIVITY_CN "Z2轴灵敏度" + +#define ENCODER_CONF_TITLE_CN "机器参数>旋钮设置" +#define ENCODER_CONF_TEXT_CN "是否使用旋钮功能?" + +#define TOOL_TEXT_CN "工具" +#define PREHEAT_TEXT_CN "预热" +#define MOVE_TEXT_CN "移动" +#define HOME_TEXT_CN "回零" +#define PRINT_TEXT_CN "打印" +#define EXTRUDE_TEXT_CN "挤出" +#define LEVELING_TEXT_CN "调平" +#define AUTO_LEVELING_TEXT_CN "自动调平" +#define SET_TEXT_CN "设置" +#define MORE_TEXT_CN "更多" + +#define ADD_TEXT_CN "增加" +#define DEC_TEXT_CN "减少" +#define EXTRUDER_1_TEXT_CN "喷头1" +#define EXTRUDER_2_TEXT_CN "喷头2" +#define HEATBED_TEXT_CN "热床" +#define TEXT_1C_CN "1℃" +#define TEXT_5C_CN "5℃" +#define TEXT_10C_CN "10℃" +#define CLOSE_TEXT_CN "关闭" + +#define BACK_TEXT_CN "返回" + +#define TOOL_PREHEAT_CN "预热" +#define TOOL_EXTRUDE_CN "挤出" +#define TOOL_MOVE_CN "移动" +#define TOOL_HOME_CN "回零" +#define TOOL_LEVELING_CN "调平" +#define TOOL_AUTO_LEVELING_CN "自动调平" +#define TOOL_FILAMENT_CN "换料" +#define TOOL_MORE_CN "更多" + +#define AXIS_X_ADD_TEXT_CN "X+" +#define AXIS_X_DEC_TEXT_CN "X-" +#define AXIS_Y_ADD_TEXT_CN "Y+" +#define AXIS_Y_DEC_TEXT_CN "Y-" +#define AXIS_Z_ADD_TEXT_CN "Z+" +#define AXIS_Z_DEC_TEXT_CN "Z-" +#define TEXT_01MM_CN "0.1mm" +#define TEXT_1MM_CN "1mm" +#define TEXT_10MM_CN "10mm" + +#define HOME_X_TEXT_CN "X" +#define HOME_Y_TEXT_CN "Y" +#define HOME_Z_TEXT_CN "Z" +#define HOME_ALL_TEXT_CN "回零" +#define HOME_STOPMOVE_CN "急停" + +#define PAGE_UP_TEXT_CN "上一页" +#define PAGE_DOWN_TEXT_CN "下一页" + +#define EXTRUDER_IN_TEXT_CN "进料" +#define EXTRUDER_OUT_TEXT_CN "退料" +#define EXTRUDE_1MM_TEXT_CN "1mm" +#define EXTRUDE_5MM_TEXT_CN "5mm" +#define EXTRUDE_10MM_TEXT_CN "10mm" +#define EXTRUDE_LOW_SPEED_TEXT_CN "低速" +#define EXTRUDE_MEDIUM_SPEED_TEXT_CN "常速" +#define EXTRUDE_HIGH_SPEED_TEXT_CN "高速" + +#define LEVELING_POINT1_TEXT_CN "第一点" +#define LEVELING_POINT2_TEXT_CN "第二点" +#define LEVELING_POINT3_TEXT_CN "第三点" +#define LEVELING_POINT4_TEXT_CN "第四点" +#define LEVELING_POINT5_TEXT_CN "第五点" + +#define FILESYS_TEXT_CN "文件系统" +#define WIFI_TEXT_CN "WIFI" +#define FAN_TEXT_CN "风扇" +#define ABOUT_TEXT_CN "关于" +#define BREAK_POINT_TEXT_CN "断点续打" +#define FILAMENT_TEXT_CN "换料" +#define LANGUAGE_TEXT_CN "语言" +#define MOTOR_OFF_TEXT_CN "关闭电机" +#define MOTOR_OFF_XY_TEXT_CN "关闭XY" +#define SHUTDOWN_TEXT_CN "关机" +#define MACHINE_PARA_CN "机器参数" +#define EEPROM_SETTINGS_CN "Eeprom设置" + +#define U_DISK_TEXT_CN "U盘" +#define SD_CARD_TEXT_CN "SD卡" +#define WIFI_NAME_TEXT_CN "无线网络:" +#define WIFI_KEY_TEXT_CN "密码: " +#define WIFI_IP_TEXT_CN "IP: " +#define WIFI_AP_TEXT_CN "状态: AP" +#define WIFI_STA_TEXT_CN "状态: STA" +#define WIFI_CONNECTED_TEXT_CN "已连接" +#define WIFI_DISCONNECTED_TEXT_CN "未连接" +#define WIFI_EXCEPTION_TEXT_CN "模块异常" +#define CLOUD_TEXT_CN "云服务" +#define CLOUD_BIND_CN "已绑定" +#define CLOUD_UNBIND_CN "解绑" +#define CLOUD_UNBINDING_CN "解绑中" +#define CLOUD_DISCONNECTED_CN "未连接" +#define CLOUD_UNBINDED_CN "未绑定" +#define CLOUD_BINDED_CN "已绑定" +#define CLOUD_DISABLE_CN "已禁用" + +#define FAN_ADD_TEXT_CN "增加" +#define FAN_DEC_TEXT_CN "减少" +#define FAN_OPEN_TEXT_CN "100%" +#define FAN_HALF_TEXT_CN "50%" +#define FAN_CLOSE_TEXT_CN "关闭" +#define FAN_TIPS1_TEXT_CN "风扇" +#define FAN_TIPS2_TEXT_CN "FAN\nClose" + +#define FILAMENT_IN_TEXT_CN "进料" +#define FILAMENT_OUT_TEXT_CN "退料" +#define FILAMENT_EXT0_TEXT_CN "喷头1" +#define FILAMENT_EXT1_TEXT_CN "喷头2" +#define FILAMENT_HEAT_TEXT_CN "预热" +#define FILAMENT_STOP_TEXT_CN "停止" +#if 0 + #define FILAMENT_REPLAYS_IDLE_TEXT_CN "请按<进料>或<退料>进行换料!" + #define FILAMENT_CHANGE_TEXT_CN "待打印机暂停后,请按<进料>或<退料>进行换料!" +#else + #define FILAMENT_CHANGE_TEXT_CN "待打印机暂停后,\n请按<进料>或<退料>" +#endif + +#define FILAMENT_DIALOG_LOAD_HEAT_TIPS_CN "准备进料,正在加热,请稍等!" +#define FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_CN "准备退料,正在加热,请稍等!" +#define FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_CN "加热完成,请装载耗材后,按<确定>开始进料!" +#define FILAMENT_DIALOG_LOAD_CONFIRM2_TIPS_CN "请装载耗材,按<确定>开始进料!" +#define FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_CN "加热完成,请按<确定>开始退料!" +#define FILAMENT_DIALOG_LOADING_TIPS_CN "正在进料,请等待耗材加载完成!" +#define FILAMENT_DIALOG_UNLOADING_TIPS_CN "正在退料,请等待耗材卸载完成!" +#define FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_CN "进料完成,请按<确定>返回" +#define FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_CN "退料完成,请按<确定>返回" + +#define FILAMENT_TIPS3_TEXT_CN "正在进料" +#define FILAMENT_TIPS4_TEXT_CN "正在退料" +#define FILAMENT_TIPS5_TEXT_CN "温度太低,请先预热" +#define FILAMENT_TIPS6_TEXT_CN "换料完成" + +#define PRE_HEAT_EXT_TEXT_CN "喷头" +#define PRE_HEAT_BED_TEXT_CN "热床" + +#define FILE_LOADING_CN "正在载入......" +#define NO_FILE_AND_CHECK_CN "无文件!请插入sd卡或u盘!" +#define NO_FILE_CN "无文件!" + +#define EXTRUDER_TEMP_TEXT_CN "温度" +#define EXTRUDER_E_LENGTH1_TEXT_CN "喷头" +#define EXTRUDER_E_LENGTH2_TEXT_CN "喷头" +#define EXTRUDER_E_LENGTH3_TEXT_CN "喷头" + +#define ABOUT_TYPE_TEXT_CN "Type: " +#define ABOUT_VERSION_TEXT_CN "Firmware: " +#define ABOUT_WIFI_TEXT_CN "Wifi: " + +#define PRINTING_OPERATION_CN "操作" +#define PRINTING_PAUSE_CN "暂停" +#define PRINTING_TEMP_CN "温度" +#define PRINTING_CHANGESPEED_CN "变速" +#define PRINTING_RESUME_CN "恢复" +#define PRINTING_STOP_CN "停止" +#define PRINTING_MORE_CN "更多" +#define PRINTING_EXTRUDER_CN "挤出" +#define PRINTING_MOVE_CN "移动" + +#define EXTRUDER_SPEED_CN "挤出" +#define MOVE_SPEED_CN "移动" +#define EXTRUDER_SPEED_STATE_CN "挤出速度" +#define MOVE_SPEED_STATE_CN "移动速度" +#define STEP_1PERCENT_CN "1%" +#define STEP_5PERCENT_CN "5%" +#define STEP_10PERCENT_CN "10%" + +#define TITLE_READYPRINT_CN "准备打印" +#define TITLE_PREHEAT_CN "预热" +#define TITLE_MOVE_CN "移动" +#define TITLE_HOME_CN "回零" +#define TITLE_EXTRUDE_CN "挤出" +#define TITLE_LEVELING_CN "调平" +#define TITLE_SET_CN "设置" +#define TITLE_MORE_CN "更多" +#define TITLE_CHOOSEFILE_CN "选择文件" +#define TITLE_PRINTING_CN "正在打印" +#define TITLE_OPERATION_CN "操作" +#define TITLE_ADJUST_CN "调整" +#define TITLE_WIRELESS_CN "无线网络" +#define TITLE_FILAMENT_CN "换料" +#define TITLE_ABOUT_CN "关于" +#define TITLE_FAN_CN "风扇" +#define TITLE_LANGUAGE_CN "语言" +#define TITLE_PAUSE_CN "暂停" +#define TITLE_CHANGESPEED_CN "变速" +#define TITLE_CLOUD_TEXT_CN "云服务" +#define TITLE_DIALOG_CONFIRM_CN "确认" +#define TITLE_FILESYS_CN "文件系统" + +#define AUTO_SHUTDOWN_CN "自动关机" +#define MANUAL_SHUTDOWN_CN "手动关机" + +#define DIALOG_CONFIRM_CN "确定" +#define DIALOG_CANCLE_CN "取消" +#define DIALOG_OK_CN "确认" +#define DIALOG_RESET_CN "重置" +#define DIALOG_DISABLE_CN "禁用" +#define DIALOG_PRINT_MODEL_CN "打印模型?" +#define DIALOG_CANCEL_PRINT_CN "停止打印?" +#define DIALOG_RETRY_CN "重试" +#define DIALOG_STOP_CN "停止" +#define DIALOG_REPRINT_FROM_BREAKPOINT_CN "从断点续打?" +//#define DIALOG_UNBIND_PRINTER_CN "解除绑定 ?" +#define DIALOG_ERROR_TIPS1_CN "错误:找不到文件,请插入sd卡/u盘!" +#define DIALOG_ERROR_TIPS2_CN "错误:通信失败,请检查波特率或主板硬件!" +#define DIALOG_ERROR_TIPS3_CN "错误:文件名或文件路径太长 !" +#define DIALOG_CLOSE_MACHINE_CN "正在关机......" +#define DIALOG_UNBIND_PRINTER_CN "解除绑定?" +#define DIALOG_FILAMENT_NO_PRESS_CN "请先装载耗材!" +#define DIALOG_PRINT_FINISH_CN "打印完成!" +#define DIALOG_PRINT_TIME_CN "打印时间: " +#define DIALOG_REPRINT_CN "再打印一次" +#define DIALOG_WIFI_ENABLE_TIPS_CN "wifi模块正在配置中,请稍等......" + +#define TEXT_VALUE_CN "%d℃/%d℃" +#define EXTRUDE_TEXT_VALUE_T_CN ": %d℃" +#define WIFI_RECONNECT_TEXT_CN "重新连接" + +#define PRINTING_GBK "正在打印" +#define PRINTING_OPERATION_GBK "操作" +#define PRINTING_PAUSE_GBK "暂停" + +#define MESSAGE_PAUSING_CN "暂停中..." +#define MESSAGE_CHANGING_CN "等待换料开始..." +#define MESSAGE_UNLOAD_CN "退料中,请稍等..." +#define MESSAGE_WAITING_CN "点击按钮恢复打印" +#define MESSAGE_INSERT_CN "装载耗材后,点击按钮开始打印" +#define MESSAGE_LOAD_CN "进料中,请稍等..." +#define MESSAGE_PURGE_CN "等待挤出..." +#define MESSAGE_RESUME_CN "等待恢复打印..." +#define MESSAGE_HEAT_CN "按下按钮,加热喷头" +#define MESSAGE_HEATING_CN "喷头加热中,请等待..." +#define MESSAGE_OPTION_CN "挤出更多还是继续打印?" +#define MESSAGE_PURGE_MORE_CN "挤出" +#define MESSAGE_CONTINUE_PRINT_CN "打印" +#define EEPROM_SETTINGS_TITLE_CN "EEPROM 设置" +#define EEPROM_SETTINGS_STORE_CN "保存参数至EEPROM" +#define EEPROM_SETTINGS_READ_CN "读取EEPROM参数" +#define EEPROM_SETTINGS_REVERT_CN "恢复默认参数" + +#define EEPROM_STORE_TIPS_CN "是否保存参数到EEPROM?" +#define EEPROM_READ_TIPS_CN "是否使用EEPROM参数?" +#define EEPROM_REVERT_TIPS_CN "是否恢复默认参数?" diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_sp.h b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_sp.h new file mode 100644 index 000000000000..2babbaba93c4 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_sp.h @@ -0,0 +1,284 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +//****************西班牙语*************************** +#define TOOL_TEXT_SP "Ajustes" +#define PREHEAT_TEXT_SP "Precalentar"//"precalent\nar" +#define MOVE_TEXT_SP "Mover" +#define HOME_TEXT_SP "Origen" +#define PRINT_TEXT_SP "Imprimir" +#define EXTRUDE_TEXT_SP "Extrusor" +#define LEVELING_TEXT_SP "Leveling"//"nivelac\nión" +#define AUTO_LEVELING_TEXT_SP "Autolevel"//"auto\nnivelación" +#define SET_TEXT_SP "Config" +#define MORE_TEXT_SP "Más" + +#define ADD_TEXT_SP "Más" +#define DEC_TEXT_SP "Menos" +#define EXTRUDER_1_TEXT_SP "Extrusor1: " +#define EXTRUDER_2_TEXT_SP "Extrusor2: " +#define HEATBED_TEXT_SP "Cama: " +#define TEXT_1C_SP "1℃" +#define TEXT_5C_SP "5℃" +#define TEXT_10C_SP "10℃" +#define CLOSE_TEXT_SP "Apagar" + +#define BACK_TEXT_SP "Atrás" + +#define TOOL_PREHEAT_SP "Precalentar" +#define TOOL_EXTRUDE_SP "Extrusor" +#define TOOL_MOVE_SP "Mover" +#define TOOL_HOME_SP "Origen" +#define TOOL_LEVELING_SP "Leveling" +#define TOOL_AUTO_LEVELING_SP "Autolevel" +#define TOOL_FILAMENT_SP "Filamento" +#define TOOL_MORE_SP "Más" + +#define AXIS_X_ADD_TEXT_SP "X+" +#define AXIS_X_DEC_TEXT_SP "X-" +#define AXIS_Y_ADD_TEXT_SP "Y+" +#define AXIS_Y_DEC_TEXT_SP "Y-" +#define AXIS_Z_ADD_TEXT_SP "Z+" +#define AXIS_Z_DEC_TEXT_SP "Z-" +#define TEXT_01MM_SP "0.1mm" +#define TEXT_1MM_SP "1mm" +#define TEXT_10MM_SP "10mm" + +#define HOME_X_TEXT_SP "EJE X" +#define HOME_Y_TEXT_SP "EJE Y" +#define HOME_Z_TEXT_SP "EJE Z" +#define HOME_ALL_TEXT_SP "TODOS" +#define HOME_STOPMOVE_SP "Quickstop" + +#define PAGE_UP_TEXT_SP "Arriba" +#define PAGE_DOWN_TEXT_SP "Abajo" + +#define EXTRUDER_IN_TEXT_SP "Dentro" +#define EXTRUDER_OUT_TEXT_SP "Fuera" +#define EXTRUDE_1MM_TEXT_SP "1mm" +#define EXTRUDE_5MM_TEXT_SP "5mm" +#define EXTRUDE_10MM_TEXT_SP "10mm" +#define EXTRUDE_LOW_SPEED_TEXT_SP "Baja" +#define EXTRUDE_MEDIUM_SPEED_TEXT_SP "Media" +#define EXTRUDE_HIGH_SPEED_TEXT_SP "Alta" + +#define LEVELING_POINT1_TEXT_SP "Primero" +#define LEVELING_POINT2_TEXT_SP "Segundo" +#define LEVELING_POINT3_TEXT_SP "Tercero" +#define LEVELING_POINT4_TEXT_SP "Cuarto" +#define LEVELING_POINT5_TEXT_SP "Quinto" + +#define FILESYS_TEXT_SP "Puerto" +#define WIFI_TEXT_SP "WiFi" +#define FAN_TEXT_SP "Ventilador" +#define ABOUT_TEXT_SP "Acerca" +#define BREAK_POINT_TEXT_SP "Continuar" +#define FILAMENT_TEXT_SP "Filamento" +#define LANGUAGE_TEXT_SP "Language" +#define MOTOR_OFF_TEXT_SP "Apagar motor" +#define MOTOR_OFF_XY_TEXT_SP "Off-XY" +#define SHUTDOWN_TEXT_SP "Apagar" +#define MACHINE_PARA_SP "Config" +#define EEPROM_SETTINGS_SP "Eeprom Set" + +#define U_DISK_TEXT_SP "PENDRIVE" +#define SD_CARD_TEXT_SP "SD" +#define WIFI_NAME_TEXT_SP "WIFI: " +#define WIFI_KEY_TEXT_SP "Contraseña: " +#define WIFI_IP_TEXT_SP "IP: " +#define WIFI_AP_TEXT_SP "Estado: AP" +#define WIFI_STA_TEXT_SP "Estado: STA" +#define WIFI_CONNECTED_TEXT_SP "Conectado" +#define WIFI_DISCONNECTED_TEXT_SP "Desconectado" +#define WIFI_EXCEPTION_TEXT_SP "Excepción" +#define WIFI_RECONNECT_TEXT_SP "Reconnect" +#define CLOUD_TEXT_SP "Nube" +#define CLOUD_BIND_SP "Atado" +#define CLOUD_UNBIND_SP "Sin atar" +#define CLOUD_UNBINDING_SP "Unbinding" +#define CLOUD_DISCONNECTED_SP "Disconnected" +#define CLOUD_UNBINDED_SP "Unbinded" +#define CLOUD_BINDED_SP "Binded" +#define CLOUD_DISABLE_SP "Disable" + +#define FAN_ADD_TEXT_SP "Más" +#define FAN_DEC_TEXT_SP "Menos" +#define FAN_OPEN_TEXT_SP "100%" +#define FAN_HALF_TEXT_SP "50%" +#define FAN_CLOSE_TEXT_SP "0%" +#define FAN_TIPS1_TEXT_SP "ventilador" +#define FAN_TIPS2_TEXT_SP "ventilador\n0" + +#define FILAMENT_IN_TEXT_SP "Dentro" +#define FILAMENT_OUT_TEXT_SP "Fuera" +#define FILAMENT_EXT0_TEXT_SP "Extrusor1" +#define FILAMENT_EXT1_TEXT_SP "Extrusor2" +#define FILAMENT_HEAT_TEXT_SP "Precalentar" +#define FILAMENT_STOP_TEXT_SP "Parar" +//#define FILAMENT_CHANGE_TEXT_SP "Filamento" +#define FILAMENT_TIPS2_TEXT_SP "T:" +#define FILAMENT_TIPS3_TEXT_SP "Dentro..." +#define FILAMENT_TIPS4_TEXT_SP "Fuera..." +#define FILAMENT_TIPS5_TEXT_SP "Temperatura demasiado baja, por favor calentar" +#define FILAMENT_TIPS6_TEXT_SP "Completado" +#if 0 + #define FILAMENT_REPLAYS_IDLE_TEXT_SP "Please click or \nto replace filament!" + #define FILAMENT_CHANGE_TEXT_SP "Please click or ,\nAfter pinter pause." + #define FILAMENT_DIALOG_LOAD_HEAT_TIPS_SP "Calentando el extrusor, por favor espere..." + #define FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_SP "Calentando el extrusor, por favor espere..." + #define FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_SP "Temperatura alcanzada.Inserte el filamento y luego presione\"Confirmar\"para comenzar la carga." + #define FILAMENT_DIALOG_LOAD_CONFIRM2_TIPS_SP "Inserte el filamento y luego presione\"Confirmar\"para comenzar la carga." + #define FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_SP "Temperatura alcanzada.Presione\"Confirmar\"para retirar el filamento." + #define FILAMENT_DIALOG_LOADING_TIPS_SP "Cargando filamento,por favor espere." + #define FILAMENT_DIALOG_UNLOADING_TIPS_SP "Retirando filamento,por favor espere." + #define FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_SP "Filamento cargado,presione\"Confirmar\"." + #define FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_SP "Filamento retirado,presione\"Confirmar\"." +#else + #define FILAMENT_CHANGE_TEXT_SP "Please click \nor ,After \npinter pause." + #define FILAMENT_DIALOG_LOAD_HEAT_TIPS_SP "Calentando el extrusor,\npor favor espere..." + #define FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_SP "Calentando el extrusor,\npor favor espere..." + #define FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_SP "Temperatura alcanzada.Inserte el \nfilamento y luego presione\"Confirmar\"\npara comenzar la carga." + #define FILAMENT_DIALOG_LOAD_CONFIRM2_TIPS_SP "Inserte el filamento y \nluego presione\"Confirmar\"para \ncomenzar la carga." + #define FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_SP "Temperatura alcanzada.\nPresione\"Confirmar\"para retirar \nel filamento." + #define FILAMENT_DIALOG_LOADING_TIPS_SP "Cargando filamento,\npor favor espere." + #define FILAMENT_DIALOG_UNLOADING_TIPS_SP "Retirando filamento,\npor favor espere." + #define FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_SP "Filamento cargado,\npresione\"Confirmar\"." + #define FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_SP "Filamento retirado,\npresione\"Confirmar\"." +#endif + +#define PRE_HEAT_EXT_TEXT_SP "Extrusor" +#define PRE_HEAT_BED_TEXT_SP "cama" + +#define FILE_LOADING_SP "Cargando......" +#if 0 + #define NO_FILE_AND_CHECK_SP "No se encontraron archivos! Por favor, inserte la tarjeta SD o el disco U!" +#endif +#define NO_FILE_AND_CHECK_SP "Archivo no encontrado,\n por favor insertar SD o disco USB!" + +#define NO_FILE_SP "Sin archivo!" + + + +#define EXTRUDER_TEMP_TEXT_SP "Temper" +#define EXTRUDER_E_LENGTH1_TEXT_SP "Extrusor1" +#define EXTRUDER_E_LENGTH2_TEXT_SP "Extrusor2" +#define EXTRUDER_E_LENGTH3_TEXT_SP "Extrusor3" + +#define ABOUT_TYPE_TEXT_SP "Pantalla: " +#define ABOUT_VERSION_TEXT_SP "Firmware: " +#define ABOUT_WIFI_TEXT_SP "WiFi: " + +#define PRINTING_OPERATION_SP "Ajustes" +#define PRINTING_PAUSE_SP "Pausar" +#define PRINTING_TEMP_SP "Temp." +#define PRINTING_CHANGESPEED_SP "Velocidad" +#define PRINTING_RESUME_SP "Resumir" +#define PRINTING_STOP_SP "Detener" +#define PRINTING_MORE_SP "Más" +#define PRINTING_EXTRUDER_SP "Extrusor" +#define PRINTING_MOVE_SP "Mover" + +#define EXTRUDER_SPEED_SP "Extrusor" +#define MOVE_SPEED_SP "Mover" +#define EXTRUDER_SPEED_STATE_SP "Extrusión" +#define MOVE_SPEED_STATE_SP "Movimiento" +#define STEP_1PERCENT_SP "1%" +#define STEP_5PERCENT_SP "5%" +#define STEP_10PERCENT_SP "10%" + +#define TITLE_READYPRINT_SP "Inicio" +#define TITLE_PREHEAT_SP "Precalentar" +#define TITLE_MOVE_SP "Mover" +#define TITLE_HOME_SP "Origen" +#define TITLE_EXTRUDE_SP "Extrusor" +#define TITLE_LEVELING_SP "Leveling" +#define TITLE_SET_SP "Config" +#define TITLE_MORE_SP "Más" +#define TITLE_CHOOSEFILE_SP "Imprimir" +#define TITLE_PRINTING_SP "Imprimir" +#define TITLE_OPERATION_SP "Ajustes" +#define TITLE_ADJUST_SP "Temp." +#define TITLE_WIRELESS_SP "Wireless" +#define TITLE_FILAMENT_SP "Filamento" +#define TITLE_ABOUT_SP "Acerca" +#define TITLE_FAN_SP "Ventilador" +#define TITLE_LANGUAGE_SP "Language" +#define TITLE_PAUSE_SP "Pausar" +#define TITLE_CHANGESPEED_SP "Velocidad" +#define TILE_TOOL_SP "Ajustes" +#define TITLE_CLOUD_TEXT_SP "Cloud" +#define TITLE_DIALOG_CONFIRM_SP "Confirmar" +#define TITLE_FILESYS_SP "Puerto" + +#define AUTO_SHUTDOWN_SP "Auto" +#define MANUAL_SHUTDOWN_SP "manual" + +#define DIALOG_CONFIRM_SP "Confirmar" +#define DIALOG_CANCLE_SP "Cancelar" +#define DIALOG_OK_SP "OK" +#define DIALOG_RESET_SP "Resetear" +#define DIALOG_RETRY_SP "Reintentar" +#define DIALOG_DISABLE_SP "Desactivar" +#define DIALOG_PRINT_MODEL_SP "¿Está seguro?" +#define DIALOG_CANCEL_PRINT_SP "¿Está seguro que desea detener la impresión?" + +#define DIALOG_RETRY_SP "Reintentar" +#define DIALOG_STOP_SP "Stop" +#define DIALOG_REPRINT_FROM_BREAKPOINT_SP "Reprint from breakpoint?" +//#define DIALOG_UNBIND_PRINTER_SP "Unbind the printer?" +#define DIALOG_ERROR_TIPS1_SP "Error:archivo no encontrado, \npor favor insertar SD o disco USB." +#define DIALOG_ERROR_TIPS2_SP "error:transacción fallida, \nconfigurar baudrate del \ndisplay para la placa base!" +#define DIALOG_ERROR_TIPS3_SP "Error : nombre de archivo o \nruta demasiado largo!" +#define DIALOG_CLOSE_MACHINE_SP "Closing machine......" +#define DIALOG_UNBIND_PRINTER_SP "Unbind the printer?" +#define DIALOG_FILAMENT_NO_PRESS_SP "Filament detection switch is not pressed" +#define DIALOG_PRINT_FINISH_SP "¡La impresión está completa!" +#define DIALOG_PRINT_TIME_SP "Tiempo de impresión: " +#define DIALOG_REPRINT_SP "Print again" +#define DIALOG_WIFI_ENABLE_TIPS_SP "The wifi module is being configured,\nplease wait a moment....." + +#define PRINTING_SP "Imprimiendo" +#define PRINTING_AJUSTES_SP "Ajustes" +#define PRINTING_PAUSAR_SP "Pausar" + +#define MESSAGE_PAUSING_SP "Aparcando..." +#define MESSAGE_CHANGING_SP "Esperando para iniciar el cambio de filamento" +#define MESSAGE_UNLOAD_SP "Espere para liberar el filamento" +#define MESSAGE_WAITING_SP "Pulsar el botón para reanudar impresión" +#define MESSAGE_INSERT_SP "Inserte el filamento y pulse el botón para continuar..." +#define MESSAGE_LOAD_SP "Espere para purgar el filamento" +#define MESSAGE_PURGE_SP "Espere para purgar el filamento" +#define MESSAGE_RESUME_SP "Esperando impresora para reanudar..." +#define MESSAGE_HEAT_SP "Pulse el botón para calentar la boquilla" +#define MESSAGE_HEATING_SP "Calentando boquilla Espere por favor..." +#define MESSAGE_OPTION_SP "¿Purgar más o continuar con la impresión?" +#define MESSAGE_PURGE_MORE_SP "Purga" +#define MESSAGE_CONTINUE_PRINT_SP "Impresión" +#define EEPROM_SETTINGS_TITLE_SP "Configuraciones EEPROM" +#define EEPROM_SETTINGS_STORE_SP "Guardar configuración en EEPROM" +#define EEPROM_SETTINGS_READ_SP "Leer la configuración de EEPROM" +#define EEPROM_SETTINGS_REVERT_SP "Revert settings to factory defaults" + +#define EEPROM_STORE_TIPS_SP "¿Guardar ajustes en EEPROM?" +#define EEPROM_READ_TIPS_SP "Leer la configuración de EEPROM?" +#define EEPROM_REVERT_TIPS_SP "Revert settings to factory defaults?" diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_t_cn.h b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_t_cn.h new file mode 100644 index 000000000000..d956e14aadf1 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_t_cn.h @@ -0,0 +1,499 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +//***************繁体中文**********************// +#define NEXT_T_CN "下一頁" +#define PREVIOUS_T_CN "上一頁" +#define DEFAULT_T_CN "默認值" +#define KEY_BACK_T_CN "退格" +#define KEY_REST_T_CN "重置" +#define KEY_CONFIRM_T_CN "確定" + +#define MACHINE_PARA_TITLE_T_CN "機器參數" +#define MACHINE_TYPE_CNOFIG_T_CN "機器設置" +#define MOTOR_CONFIG_T_CN "電機設置" +#define MACHINE_LEVELING_CONFIG_T_CN "調平設置" +#define ADVANCE_CONFIG_T_CN "高級設置" + +#define MACHINE_CONFIG_TITLE_T_CN "機器參數>機器配置" +#define MACHINE_TYPE_T_CN "機型選擇" +#define MACHINE_STROKE_T_CN "行程設置" +#define MACHINE_HOMEDIR_T_CN "歸零方向" +#define MACHINE_ENDSTOP_TYPE_T_CN "限位開關類型" +#define MACHINE_FILAMENT_CONFIG_T_CN "換料設置" + +#define MACHINE_TYPE_CONFIG_TITLE_T_CN "機器參數>機型選擇" +#define MACHINE_TYPE_XYZ_T_CN "XYZ機型" +#define MACHINE_TYPE_DELTA_T_CN "Delta機型" +#define MACHINE_TYPE_COREXY_T_CN "Corexy機型" + +#define MACHINE_STROKE_CONF_TITLE_T_CN "機器參數>機器行程" +#define X_MAX_LENGTH_T_CN "X軸最大行程" +#define Y_MAX_LENGTH_T_CN "Y軸最大行程" +#define Z_MAX_LENGTH_T_CN "Z軸最大行程" + +#define X_MIN_LENGTH_T_CN "X軸最小行程" +#define Y_MIN_LENGTH_T_CN "Y軸最小行程" +#define Z_MIN_LENGTH_T_CN "Z軸最小行程" + +#define HOME_DIR_CONF_TITLE_T_CN "機器參數>歸零方向" +#define HOME_DIR_X_T_CN "X軸歸零方向" +#define HOME_DIR_Y_T_CN "Y軸歸零方向" +#define HOME_DIR_Z_T_CN "Z軸歸零方向" +#define HOME_MIN_T_CN "MIN" +#define HOME_MAX_T_CN "MAX" + +#define ENDSTOP_CONF_TITLE_T_CN "機器參數>限位開關" +#define MIN_ENDSTOP_X_T_CN "X軸最小限位" +#define MIN_ENDSTOP_Y_T_CN "Y軸最小限位" +#define MIN_ENDSTOP_Z_T_CN "Z軸最小限位" +#define MAX_ENDSTOP_X_T_CN "X軸最大限位" +#define MAX_ENDSTOP_Y_T_CN "Y軸最大限位" +#define MAX_ENDSTOP_Z_T_CN "Z軸最大限位" +#define ENDSTOP_FIL_T_CN "斷料開關類型" +#define ENDSTOP_LEVEL_T_CN "調平開關類型" +#define ENDSTOP_OPENED_T_CN "常開" +#define ENDSTOP_CLOSED_T_CN "常閉" + +#define FILAMENT_CONF_TITLE_T_CN "換料設置" +#define FILAMENT_IN_LENGTH_T_CN "進料長度" +#define FILAMENT_IN_SPEED_T_CN "進料速度" +#define FILAMENT_TEMPERATURE_T_CN "換料溫度" +#define FILAMENT_OUT_LENGTH_T_CN "退料長度" +#define FILAMENT_OUT_SPEED_T_CN "退料速度" + +#define LEVELING_CONF_TITLE_T_CN "機器參數>調平設置" +#define LEVELING_PARA_CONF_T_CN "調平設置" +#define LEVELING_MANUAL_POS_T_CN "手動調平坐標設置" +#define LEVELING_AUTO_COMMAND_T_CN "自動調平指令設置" +#define LEVELING_AUTO_ZOFFSET_T_CN "擠出頭與調平開關偏移設置" + +#define LEVELING_PARA_CONF_TITLE_T_CN "調平參數" +#define AUTO_LEVELING_ENABLE_T_CN "自動調平" +#define BLTOUCH_LEVELING_ENABLE_T_CN "啟動BLtouch" +#define PROBE_PORT_T_CN "調平探針接口" +#define PROBE_X_OFFSET_T_CN "探針X方向偏移" +#define PROBE_Y_OFFSET_T_CN "探针Y方向偏移" +#define PROBE_Z_OFFSET_T_CN "探针Z方向偏移" +#define PROBE_XY_SPEED_T_CN "探针XY方向移動速度" +#define PROBE_Z_SPEED_T_CN "探针Z方向移動速度" +#define ENABLE_T_CN "是" +#define DISABLE_T_CN "否" +#define Z_MIN_T_CN "ZMin" +#define Z_MAX_T_CN "ZMax" + +#define DELTA_LEVEL_CONF_TITLE_T_CN "Delta機器參數" +#define DELTA_LEVEL_CONF_T_CN "Delta機器調平" +#define DELTA_MACHINE_RADIUS_T_CN "機器半徑" +#define DELTA_DIAGONAL_ROD_T_CN "機器桿長" +#define DELTA_PRINT_RADIUS_T_CN "打印半徑" +#define DELTA_HEIGHT_T_CN "打印高度" +#define SMOOTH_ROD_OFFSET_T_CN "滑塊偏移" +#define EFFECTOR_OFFSET_T_CN "效應器偏移" +#define CALIBRATION_RADIUS_T_CN "調平半徑" + +#define XYZ_LEVEL_CONF_TITLE_T_CN "XYZ機器參數" +#define PROBE_REACH_MAX_LEFT_T_CN "探针達到最左位置" +#define PROBE_REACH_MAX_RIGHT_T_CN "探针達到最右位置" +#define PROBE_REACH_MAX_FRONT_T_CN "探针達到最前位置" +#define PROBE_REACH_MAX_BACK_T_CN "探针達到最後位置" + +#define TEMPERATURE_CONF_TITLE_T_CN "機器參數>溫度設置" +#define NOZZLE_CONF_T_CN "噴頭設置" +#define HOTBED_CONF_T_CN "熱床設置" +#define PREHEAT_TEMPER_T_CN "預設溫度" + +#define NOZZLE_CONF_TITLE_T_CN "機器參數>噴頭設置" +#define NOZZLECNT_T_CN "噴頭數量" +#define NOZZLE_TYPE_T_CN "E0溫感類型" +#define NOZZLE_ADJUST_TYPE_T_CN "PID調溫" +#define NOZZLE_MIN_TEMPERATURE_T_CN "最低溫度" +#define NOZZLE_MAX_TEMPERATURE_T_CN "最高溫度" +#define EXTRUD_MIN_TEMPER_T_CN "最低擠出溫度" + +#define HOTBED_CONF_TITLE_T_CN "機器參數>熱床設置" +#define HOTBED_ADJUST_T_CN "PID調溫" +#define HOTBED_MIN_TEMPERATURE_T_CN "最低溫度" +#define HOTBED_MAX_TEMPERATURE_T_CN "最高溫度" + +#define MOTOR_CONF_TITLE_T_CN "機器參數>電機設置" +#define MAXFEEDRATE_CONF_T_CN "最大速度設置" +#define ACCELERATION_CONF_T_CN "加速度設置" +#define JERKCONF_T_CN "突變速度設置" +#define STEPSCONF_T_CN "脈沖設置" +#define TMC_CURRENT_T_CN "TMC 驅動電流設置" +#define TMC_STEP_MODE_T_CN "TMC 驅動模式設置" +#define MOTORDIRCONF_T_CN "電機方向設置" +#define HOMEFEEDRATECONF_T_CN "歸零速度設置" +#define HOMING_SENSITIVITY_CONF_T_CN "無限位回零靈敏度調節" + +#define MAXFEEDRATE_CONF_TITLE_T_CN "機器參數>最大速度" +#define X_MAXFEEDRATE_T_CN "X軸最大速度" +#define Y_MAXFEEDRATE_T_CN "Y軸最大速度" +#define Z_MAXFEEDRATE_T_CN "Z軸最大速度" +#define E0_MAXFEEDRATE_T_CN "E0軸最大速度" +#define E1_MAXFEEDRATE_T_CN "E1軸最大速度" + +#define ACCELERATION_CONF_TITLE_T_CN "機器參數>加速度" +#define PRINT_ACCELERATION_T_CN "打印加速度" +#define RETRACT_ACCELERATION_T_CN "回抽加速度" +#define TRAVEL_ACCELERATION_T_CN "空載加速度" +#define X_ACCELERATION_T_CN "X軸加速度" +#define Y_ACCELERATION_T_CN "Y軸加速度" +#define Z_ACCELERATION_T_CN "Z軸加速度" +#define E0_ACCELERATION_T_CN "E0軸加速度" +#define E1_ACCELERATION_T_CN "E1軸加速度" + +#define JERK_CONF_TITLE_T_CN "機器參數>突變速度" +#define X_JERK_T_CN "X軸突變速度" +#define Y_JERK_T_CN "Y軸突變速度" +#define Z_JERK_T_CN "Z軸突變速度" +#define E_JERK_T_CN "E軸突變速度" + +#define STEPS_CONF_TITLE_T_CN "機器參數>脈衝設置" +#define X_STEPS_T_CN "X軸脈沖" +#define Y_STEPS_T_CN "Y軸脈沖" +#define Z_STEPS_T_CN "Z軸脈沖" +#define E0_STEPS_T_CN "E0軸脈沖" +#define E1_STEPS_T_CN "E1軸脈沖" + +#define TMC_CURRENT_CONF_TITLE_T_CN "機器參數>TMC電流設置" +#define X_TMC_CURRENT_T_CN "X軸電流(毫安)" +#define Y_TMC_CURRENT_T_CN "Y軸電流(毫安)" +#define Z_TMC_CURRENT_T_CN "Z軸電流(毫安)" +#define E0_TMC_CURRENT_T_CN "E0軸電流(毫安)" +#define E1_TMC_CURRENT_T_CN "E1軸電流(毫安)" + +#define TMC_MODE_CONF_TITLE_T_CN "機器參數>TMC模式設置" +#define X_TMC_MODE_T_CN "X軸是否使能靜音模式" +#define Y_TMC_MODE_T_CN "Y軸是否使能靜音模式" +#define Z_TMC_MODE_T_CN "Z軸是否使能靜音模式" +#define E0_TMC_MODE_T_CN "E0軸是否使能靜音模式" +#define E1_TMC_MODE_T_CN "E1軸是否使能靜音模式" + +#define MOTORDIR_CONF_TITLE_T_CN "機器參數>電機方向" +#define X_MOTORDIR_T_CN "X軸電機方向" +#define Y_MOTORDIR_T_CN "Y軸電機方向" +#define Z_MOTORDIR_T_CN "Z軸電機方向" +#define E0_MOTORDIR_T_CN "E0軸電機方向" +#define E1_MOTORDIR_T_CN "E1軸電機方向" +#define INVERT_P_T_CN "正向" +#define INVERT_N_T_CN "反向" + +#define HOMEFEEDRATE_CONF_TITLE_T_CN "機器參數>歸零速度" +#define X_HOMESPEED_T_CN "XY軸歸零速度" +#define Y_HOMESPEED_T_CN "Y軸歸零速度" +#define Z_HOMESPEED_T_CN "Z軸歸零速度" + +#define ADVANCED_CONF_TITLE_T_CN "機器參數>高級設置" +#define PWROFF_DECTION_T_CN "斷電檢測模塊" +#define PWROFF_AFTER_PRINT_T_CN "啟動打完關機功能" +#define HAVE_UPS_T_CN "機器配備UPS電壓" +#define Z2_AND_Z2ENDSTOP_CONF_T_CN "雙z軸雙限位功能設置" +#define ENABLE_PINS_CONF_T_CN "電機使能腳電平設置" +#define WIFI_SETTINGS_T_CN "Wi-Fi參數設置" +#define ENCODER_SETTINGS_T_CN "旋鈕設置" + +#define Z2_AND_Z2ENDSTOP_CONF_TITLE_T_CN "雙z軸雙限位設置" +#define Z2_ENABLE_T_CN "啟用Z2軸" +#define Z2_ENDSTOP_T_CN "啟用Z2限位" +#define Z2_PORT_T_CN "Z2限位接口" + +#define ENABLE_PINS_CONF_TITLE_T_CN "電機使能腳電平" +#define X_ENABLE_PINS_INVERT_T_CN "X軸電機使能電平" +#define Y_ENABLE_PINS_INVERT_T_CN "Y軸電機使能電平" +#define Z_ENABLE_PINS_INVERT_T_CN "Z軸電機使能電平" +#define E_ENABLE_PINS_INVERT_T_CN "E軸電機使能電平" + +#define PAUSE_POSITION_T_CN "打印暫停位置設置" +#define PAUSE_POSITION_X_T_CN "X軸暫停位置(絕對位置,-1無效)" +#define PAUSE_POSITION_Y_T_CN "Y軸暫停位置(絕對位置,-1無效)" +#define PAUSE_POSITION_Z_T_CN "Z軸暫停位置(相對位置,-1無效)" +#define WIFI_SETTINGS_TITLE_T_CN "機器參數>Wi-Fi設置" +#define WIFI_SETTINGS_MODE_T_CN "Wi-Fi 模式" +#define WIFI_SETTINGS_NAME_T_CN "Wi-Fi 名稱: " +#define WIFI_SETTINGS_PASSWORD_T_CN "Wi-Fi 密碼: " +#define WIFI_SETTINGS_CLOUD_T_CN "是否使用雲服務?" +#define WIFI_SETTINGS_CONFIG_T_CN "配置" +#define WIFI_SETTINGS_EDIT_T_CN "編輯" +#define WIFI_CONFIG_TIPS_T_CN "進行Wi-Fi配置?" + +#define OFFSET_TITLE_T_CN "機器參數>偏移設置" +#define OFFSET_X_T_CN "X軸與調平開關偏移" +#define OFFSET_Y_T_CN "Y軸與調平開關偏移" +#define OFFSET_Z_T_CN "Z軸與調平開關偏移" + +#define HOMING_SENSITIVITY_CONF_TITLE_T_CN "機器參數>靈敏度調節" +#define X_SENSITIVITY_T_CN "X軸靈敏度" +#define Y_SENSITIVITY_T_CN "Y軸靈敏度" +#define Z_SENSITIVITY_T_CN "Z軸靈敏度" +#define Z2_SENSITIVITY_T_CN "Z2軸靈敏度" + +#define ENCODER_CONF_TITLE_T_CN "機器參數>旋鈕設置" +#define ENCODER_CONF_TEXT_T_CN "是否使用旋鈕功能?" + +#define TOOL_TEXT_T_CN "工具" +#define PREHEAT_TEXT_T_CN "預熱" +#define MOVE_TEXT_T_CN "移動" +#define HOME_TEXT_T_CN "回零" +#define PRINT_TEXT_T_CN "打印" +#define EXTRUDE_TEXT_T_CN "擠出" +#define LEVELING_TEXT_T_CN "調平" +#define AUTO_LEVELING_TEXT_T_CN "自動調平" +#define SET_TEXT_T_CN "設置" +#define MORE_TEXT_T_CN "更多" + +#define ADD_TEXT_T_CN "增加" +#define DEC_TEXT_T_CN "減少" +#define EXTRUDER_1_TEXT_T_CN "噴頭1" +#define EXTRUDER_2_TEXT_T_CN "噴頭2" +#define HEATBED_TEXT_T_CN "熱床" +#define TEXT_1C_T_CN "1℃" +#define TEXT_5C_T_CN "5℃" +#define TEXT_10C_T_CN "10℃" +#define CLOSE_TEXT_T_CN "關閉" + +#define BACK_TEXT_T_CN "返回" + +#define TOOL_PREHEAT_T_CN "預熱" +#define TOOL_EXTRUDE_T_CN "擠出" +#define TOOL_MOVE_T_CN "移動" +#define TOOL_HOME_T_CN "回零" +#define TOOL_LEVELING_T_CN "調平" +#define TOOL_AUTO_LEVELING_T_CN "自動調平" +#define TOOL_FILAMENT_T_CN "換料" +#define TOOL_MORE_T_CN "更多" + +#define AXIS_X_ADD_TEXT_T_CN "X+" +#define AXIS_X_DEC_TEXT_T_CN "X-" +#define AXIS_Y_ADD_TEXT_T_CN "Y+" +#define AXIS_Y_DEC_TEXT_T_CN "Y-" +#define AXIS_Z_ADD_TEXT_T_CN "Z+" +#define AXIS_Z_DEC_TEXT_T_CN "Z-" +#define TEXT_01MM_T_CN "0.1mm" +#define TEXT_1MM_T_CN "1mm" +#define TEXT_10MM_T_CN "10mm" + +#define HOME_X_TEXT_T_CN "X" +#define HOME_Y_TEXT_T_CN "Y" +#define HOME_Z_TEXT_T_CN "Z" +#define HOME_ALL_TEXT_T_CN "回零" +#define HOME_STOPMOVE_T_CN "急停" + +#define PAGE_UP_TEXT_T_CN "上一頁" +#define PAGE_DOWN_TEXT_T_CN "下一頁" + +#define EXTRUDER_IN_TEXT_T_CN "進料" +#define EXTRUDER_OUT_TEXT_T_CN "退料" +#define EXTRUDE_1MM_TEXT_T_CN "1mm" +#define EXTRUDE_5MM_TEXT_T_CN "5mm" +#define EXTRUDE_10MM_TEXT_T_CN "10mm" +#define EXTRUDE_LOW_SPEED_TEXT_T_CN "低速" +#define EXTRUDE_MEDIUM_SPEED_TEXT_T_CN "常速" +#define EXTRUDE_HIGH_SPEED_TEXT_T_CN "高速" + +#define LEVELING_POINT1_TEXT_T_CN "第一點" +#define LEVELING_POINT2_TEXT_T_CN "第二點" +#define LEVELING_POINT3_TEXT_T_CN "第三點" +#define LEVELING_POINT4_TEXT_T_CN "第四點" +#define LEVELING_POINT5_TEXT_T_CN "第五點" + +#define FILESYS_TEXT_T_CN "文件系統" +#define WIFI_TEXT_T_CN "WIFI" +#define FAN_TEXT_T_CN "風扇" +#define ABOUT_TEXT_T_CN "關於" +#define BREAK_POINT_TEXT_T_CN "斷點續打" +#define FILAMENT_TEXT_T_CN "換料" +#define LANGUAGE_TEXT_T_CN "語言" +#define MOTOR_OFF_TEXT_T_CN "關閉電機" +#define MOTOR_OFF_XY_TEXT_T_CN "關閉XY" +#define SHUTDOWN_TEXT_T_CN "關機" +#define MACHINE_PARA_T_CN "機器參數" +#define EEPROM_SETTINGS_T_CN "Eeprom設置" + +#define U_DISK_TEXT_T_CN "U盤" +#define SD_CARD_TEXT_T_CN "SD卡" +#define WIFI_NAME_TEXT_T_CN "無線網絡:" +#define WIFI_KEY_TEXT_T_CN "密碼: " +#define WIFI_IP_TEXT_T_CN "IP: " +#define WIFI_AP_TEXT_T_CN "狀態: AP" +#define WIFI_STA_TEXT_T_CN "狀態: STA" +#define WIFI_CONNECTED_TEXT_T_CN "已連接" +#define WIFI_DISCONNECTED_TEXT_T_CN "未連接" +#define WIFI_EXCEPTION_TEXT_T_CN "模塊異常" +#define CLOUD_TEXT_T_CN "雲服務" +#define CLOUD_BIND_T_CN "已綁定" +#define CLOUD_UNBIND_T_CN "解綁" +#define CLOUD_UNBINDING_T_CN "解绑中" +#define CLOUD_DISCONNECTED_T_CN "未連接" +#define CLOUD_UNBINDED_T_CN "未綁定" +#define CLOUD_BINDED_T_CN "已綁定" +#define CLOUD_DISABLE_T_CN "已禁用" + +#define FAN_ADD_TEXT_T_CN "增加" +#define FAN_DEC_TEXT_T_CN "減少" +#define FAN_OPEN_TEXT_T_CN "100%" +#define FAN_HALF_TEXT_T_CN "50%" +#define FAN_CLOSE_TEXT_T_CN "關閉" +#define FAN_TIPS1_TEXT_T_CN "風扇" +#define FAN_TIPS2_TEXT_T_CN "FAN\nClose" + +#define FILAMENT_IN_TEXT_T_CN "進料" +#define FILAMENT_OUT_TEXT_T_CN "退料" +#define FILAMENT_EXT0_TEXT_T_CN "噴頭1" +#define FILAMENT_EXT1_TEXT_T_CN "噴頭2" +#define FILAMENT_HEAT_TEXT_T_CN "預熱" +#define FILAMENT_STOP_TEXT_T_CN "停止" +//#define FILAMENT_CHANGE_TEXT_T_CN "準備換料" +#define FILAMENT_TIPS2_TEXT_T_CN "T:" +#define FILAMENT_TIPS3_TEXT_T_CN "正在進料" +#define FILAMENT_TIPS4_TEXT_T_CN "正在退料" +#define FILAMENT_TIPS5_TEXT_T_CN "溫度太低,請先預熱" +#define FILAMENT_TIPS6_TEXT_T_CN "換料完成" + +#if 0 + #define FILAMENT_REPLAYS_IDLE_TEXT_T_CN "請按<進料>或<退料>進行換料!" + #define FILAMENT_CHANGE_TEXT_T_CN "待打印機暫停后,請按<進料>或<退料>進行換料!" +#endif + + #define FILAMENT_CHANGE_TEXT_T_CN "待打印機暫停后,\n請按<進料>或<退料>" + +#define FILAMENT_DIALOG_LOAD_HEAT_TIPS_T_CN "準備進料,正在加熱,請稍等" +#define FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_T_CN "準備退料,正在加熱,請稍等" +#define FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_T_CN "加熱完成,請裝載耗材后,按<確定>開始進料" +#define FILAMENT_DIALOG_LOAD_CONFIRM2_TIPS_T_CN "請裝載耗,按<確定>開始進料!" +#define FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_T_CN "加熱完成,请按<確定>開始退料!" +#define FILAMENT_DIALOG_LOADING_TIPS_T_CN "正在進料,请等待耗材加載完成!" +#define FILAMENT_DIALOG_UNLOADING_TIPS_T_CN "正在退料,请等待耗材卸載完成!" +#define FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_T_CN "進料完成,请按<確定>返回" +#define FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_T_CN "退料完成,请按<確定>返回" + +#define PRE_HEAT_EXT_TEXT_T_CN "噴頭" +#define PRE_HEAT_BED_TEXT_T_CN "熱床" + +#define FILE_LOADING_T_CN "正在載入......" +#define NO_FILE_AND_CHECK_T_CN "無文件!請插入sd卡/u盤!" +#define NO_FILE_T_CN "無文件!" + +#define EXTRUDER_TEMP_TEXT_T_CN "溫度" +#define EXTRUDER_E_LENGTH1_TEXT_T_CN "噴頭" +#define EXTRUDER_E_LENGTH2_TEXT_T_CN "噴頭" +#define EXTRUDER_E_LENGTH3_TEXT_T_CN "噴頭" + +#define ABOUT_TYPE_TEXT_T_CN "Type: " +#define ABOUT_VERSION_TEXT_T_CN "Firmware: " +#define ABOUT_WIFI_TEXT_T_CN "Wifi: " + +#define PRINTING_OPERATION_T_CN "操作" +#define PRINTING_PAUSE_T_CN "暫停" +#define PRINTING_TEMP_T_CN "溫度" +#define PRINTING_CHANGESPEED_T_CN "變速" +#define PRINTING_RESUME_T_CN "恢復" +#define PRINTING_STOP_T_CN "停止" +#define PRINTING_MORE_T_CN "更多" +#define PRINTING_EXTRUDER_T_CN "擠出" +#define PRINTING_MOVE_T_CN "移動" + +#define EXTRUDER_SPEED_T_CN "擠出" +#define MOVE_SPEED_T_CN "移動" +#define EXTRUDER_SPEED_STATE_T_CN "擠出速度" +#define MOVE_SPEED_STATE_T_CN "移動速度" +#define STEP_1PERCENT_T_CN "1%%" +#define STEP_5PERCENT_T_CN "5%%" +#define STEP_10PERCENT_T_CN "10%%" + +#define TITLE_READYPRINT_T_CN "準備打印" +#define TITLE_PREHEAT_T_CN "預熱" +#define TITLE_MOVE_T_CN "移動" +#define TITLE_HOME_T_CN "回零" +#define TITLE_EXTRUDE_T_CN "擠出" +#define TITLE_LEVELING_T_CN "調平" +#define TITLE_SET_T_CN "設置" +#define TITLE_MORE_T_CN "更多" +#define TITLE_CHOOSEFILE_T_CN "選擇文件" +#define TITLE_PRINTING_T_CN "正在打印" +#define TITLE_OPERATION_T_CN "操作" +#define TITLE_ADJUST_T_CN "調整" +#define TITLE_WIRELESS_T_CN "無線網絡" +#define TITLE_FILAMENT_T_CN "換料" +#define TITLE_ABOUT_T_CN "關於" +#define TITLE_FAN_T_CN "風扇" +#define TITLE_LANGUAGE_T_CN "語言" +#define TITLE_PAUSE_T_CN "暫停" +#define TITLE_CHANGESPEED_T_CN "變速" +#define TITLE_CLOUD_TEXT_T_CN "雲服務" +#define TITLE_DIALOG_CONFIRM_T_CN "確認" +#define TITLE_FILESYS_T_CN "文件系統" + +#define AUTO_SHUTDOWN_T_CN "自動關機" +#define MANUAL_SHUTDOWN_T_CN "手動關機" + +#define DIALOG_CONFIRM_T_CN "確定" +#define DIALOG_CANCLE_T_CN "取消" +#define DIALOG_OK_T_CN "確認" +#define DIALOG_RESET_T_CN "重設" +#define DIALOG_RETRY_T_CN "重試" +#define DIALOG_DISABLE_T_CN "禁用" +#define DIALOG_PRINT_MODEL_T_CN "打印模型?" +#define DIALOG_CANCEL_PRINT_T_CN "停止打印?" +#define DIALOG_RETRY_T_CN "重試" +#define DIALOG_STOP_T_CN "停止" +#define DIALOG_REPRINT_FROM_BREAKPOINT_T_CN "從斷點續打?" +//#define DIALOG_UNBIND_PRINTER_T_CN "解除綁定?" +#define DIALOG_ERROR_TIPS1_T_CN "錯誤:找不到文件,請插入sd卡/u盤!" +#define DIALOG_ERROR_TIPS2_T_CN "錯誤:通信失敗,請檢查波特率或主板硬件!" +#define DIALOG_ERROR_TIPS3_T_CN "錯誤:文件名或文件路徑太長!" +#define DIALOG_CLOSE_MACHINE_T_CN "正在關機......" +#define DIALOG_UNBIND_PRINTER_T_CN "解除綁定?" +#define DIALOG_FILAMENT_NO_PRESS_T_CN "請先裝載耗材!" +#define DIALOG_PRINT_FINISH_T_CN "打印完成!" +#define DIALOG_PRINT_TIME_T_CN "打印時間: " +#define DIALOG_REPRINT_T_CN "再打印壹次" +#define DIALOG_WIFI_ENABLE_TIPS_T_CN "wifi模塊正在配置中,請稍等......" + +#define TEXT_VALUE_T_CN "%d℃/%d℃" +#define EXTRUDE_TEXT_VALUE_T_T_CN ": %d℃" +#define WIFI_RECONNECT_TEXT_T_CN "重新連接" + +#define MESSAGE_PAUSING_T_CN "暫停中..." +#define MESSAGE_CHANGING_T_CN "等待換料開始..." +#define MESSAGE_UNLOAD_T_CN "退料中,請稍等..." +#define MESSAGE_WAITING_T_CN "點擊按鈕恢復打印" +#define MESSAGE_INSERT_T_CN "裝載耗材後,點擊按鈕開始打印" +#define MESSAGE_LOAD_T_CN "進料中,請稍等..." +#define MESSAGE_PURGE_T_CN "等待擠出..." +#define MESSAGE_RESUME_T_CN "等待恢復打印..." +#define MESSAGE_HEAT_T_CN "按下按鈕,加熱噴頭" +#define MESSAGE_HEATING_T_CN "噴頭加熱中,請等待..." +#define MESSAGE_OPTION_T_CN "擠出更多還是繼續打印" +#define MESSAGE_PURGE_MORE_T_CN "擠出" +#define MESSAGE_CONTINUE_PRINT_T_CN "打印" + +#define EEPROM_SETTINGS_TITLE_T_CN "EEPROM 設置" +#define EEPROM_SETTINGS_STORE_T_CN "保存參數至EEPROM" +#define EEPROM_SETTINGS_READ_T_CN "讀取EEPROM參數" +#define EEPROM_SETTINGS_REVERT_T_CN "恢復默認參數" + +#define EEPROM_STORE_TIPS_T_CN "是否保存參數到EEPROM?" +#define EEPROM_READ_TIPS_T_CN "是否使用EEPROM參數?" +#define EEPROM_REVERT_TIPS_T_CN "是否恢復默認參數?" diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_lvgl_configuration.cpp b/Marlin/src/lcd/extui/lib/mks_ui/tft_lvgl_configuration.cpp new file mode 100644 index 000000000000..5a8c4986089e --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_lvgl_configuration.cpp @@ -0,0 +1,525 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * @file tft_lvgl_configuration.cpp + * @date 2020-02-21 + */ + +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "SPI_TFT.h" + +#include "tft_lvgl_configuration.h" +#include "draw_ready_print.h" + +#include "pic_manager.h" +#include "mks_hardware_test.h" +#include "draw_ui.h" +#include "SPIFlashStorage.h" +#include + +#include "../../../../MarlinCore.h" +#include "../../../../inc/MarlinConfig.h" + +#include HAL_PATH(../../HAL, tft/xpt2046.h) +#include "../../../ultralcd.h" +XPT2046 touch; + +#if ENABLED(POWER_LOSS_RECOVERY) + #include "../../../../feature/powerloss.h" +#endif + +#include + +#ifndef TFT_WIDTH + #define TFT_WIDTH 480 +#endif +#ifndef TFT_HEIGHT + #define TFT_HEIGHT 320 +#endif + +#if HAS_SPI_FLASH_FONT + extern void init_gb2312_font(); +#endif + +static lv_disp_buf_t disp_buf; +lv_group_t* g; +#if ENABLED(SDSUPPORT) + extern void UpdateAssets(); +#endif +uint16_t DeviceCode = 0x9488; +extern uint8_t sel_id; + +extern uint8_t gcode_preview_over, flash_preview_begin, default_preview_flg; + +uint8_t bmp_public_buf[17 * 1024]; + +void SysTick_Callback() { + lv_tick_inc(1); + print_time_count(); + #if ENABLED(USE_WIFI_FUNCTION) + if (tips_disp.timer == TIPS_TIMER_START) { + tips_disp.timer_count++; + } + #endif + if (uiCfg.filament_loading_time_flg == 1) { + uiCfg.filament_loading_time_cnt++; + uiCfg.filament_rate = (uint32_t)(((uiCfg.filament_loading_time_cnt / (uiCfg.filament_loading_time * 1000.0)) * 100.0) + 0.5); + if (uiCfg.filament_loading_time_cnt >= (uiCfg.filament_loading_time * 1000)) { + uiCfg.filament_loading_time_cnt = 0; + uiCfg.filament_loading_time_flg = 0; + uiCfg.filament_loading_completed = 1; + } + } + if (uiCfg.filament_unloading_time_flg == 1) { + uiCfg.filament_unloading_time_cnt++; + uiCfg.filament_rate = (uint32_t)(((uiCfg.filament_unloading_time_cnt / (uiCfg.filament_unloading_time * 1000.0)) * 100.0) + 0.5); + if (uiCfg.filament_unloading_time_cnt >= (uiCfg.filament_unloading_time * 1000)) { + uiCfg.filament_unloading_time_cnt = 0; + uiCfg.filament_unloading_time_flg = 0; + uiCfg.filament_unloading_completed = 1; + uiCfg.filament_rate = 100; + } + } +} + +extern uint8_t bmp_public_buf[17 * 1024]; + +void tft_lvgl_init() { + + //uint16_t test_id=0; + W25QXX.init(SPI_QUARTER_SPEED); + //test_id=W25QXX.W25QXX_ReadID(); + + gCfgItems_init(); + ui_cfg_init(); + disp_language_init(); + + //init tft first! + SPI_TFT.spi_init(SPI_FULL_SPEED); + SPI_TFT.LCD_init(); + + //spi_flash_read_test(); + #if ENABLED(SDSUPPORT) + watchdog_refresh(); + UpdateAssets(); + #endif + + watchdog_refresh(); + mks_test_get(); + + touch.Init(); + + lv_init(); + + lv_disp_buf_init(&disp_buf, bmp_public_buf, NULL, LV_HOR_RES_MAX * 18); /*Initialize the display buffer*/ + + lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/ + lv_disp_drv_init(&disp_drv); /*Basic initialization*/ + disp_drv.flush_cb = my_disp_flush; /*Set your driver function*/ + disp_drv.buffer = &disp_buf; /*Assign the buffer to the display*/ + lv_disp_drv_register(&disp_drv); /*Finally register the driver*/ + + lv_indev_drv_t indev_drv; + lv_indev_drv_init(&indev_drv); /*Descriptor of a input device driver*/ + indev_drv.type = LV_INDEV_TYPE_POINTER; /*Touch pad is a pointer-like device*/ + indev_drv.read_cb = my_touchpad_read; /*Set your driver function*/ + lv_indev_drv_register(&indev_drv); /*Finally register the driver*/ + + #if HAS_ROTARY_ENCODER + g = lv_group_create(); + lv_indev_drv_t enc_drv; + lv_indev_drv_init(&enc_drv); + enc_drv.type = LV_INDEV_TYPE_ENCODER; + enc_drv.read_cb = my_mousewheel_read; + lv_indev_t * enc_indev = lv_indev_drv_register(&enc_drv); + lv_indev_set_group(enc_indev, g); + #endif + + lv_fs_drv_t spi_flash_drv; + lv_fs_drv_init(&spi_flash_drv); + spi_flash_drv.letter = 'F'; + spi_flash_drv.open_cb = spi_flash_open_cb; + spi_flash_drv.close_cb = spi_flash_close_cb; + spi_flash_drv.read_cb = spi_flash_read_cb; + spi_flash_drv.seek_cb = spi_flash_seek_cb; + spi_flash_drv.tell_cb = spi_flash_tell_cb; + lv_fs_drv_register(&spi_flash_drv); + + lv_fs_drv_t sd_drv; + lv_fs_drv_init(&sd_drv); + sd_drv.letter = 'S'; + sd_drv.open_cb = sd_open_cb; + sd_drv.close_cb = sd_close_cb; + sd_drv.read_cb = sd_read_cb; + sd_drv.seek_cb = sd_seek_cb; + sd_drv.tell_cb = sd_tell_cb; + lv_fs_drv_register(&sd_drv); + + systick_attach_callback(SysTick_Callback); + + #if HAS_SPI_FLASH_FONT + init_gb2312_font(); + #endif + + tft_style_init(); + + filament_pin_setup(); + + lv_encoder_pin_init(); + + #if ENABLED(POWER_LOSS_RECOVERY) + recovery.load(); + if (recovery.valid()) { + if (gCfgItems.from_flash_pic == 1) + flash_preview_begin = 1; + else + default_preview_flg = 1; + + uiCfg.print_state = REPRINTING; + + ZERO(public_buf_m); + strncpy(public_buf_m, recovery.info.sd_filename, sizeof(public_buf_m)); + card.printLongPath(public_buf_m); + + strncpy(list_file.long_name[sel_id], card.longFilename, sizeof(list_file.long_name[sel_id])); + + lv_draw_printing(); + } + else + #endif + lv_draw_ready_print(); + + if (mks_test_flag == 0x1E) + mks_gpio_test(); +} + +void my_disp_flush(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * color_p) { + uint16_t i, width, height; + + width = area->x2 - area->x1 + 1; + height = area->y2 - area->y1 + 1; + + SPI_TFT.setWindow((uint16_t)area->x1, (uint16_t)area->y1, width, height); + for (i = 0; i < height; i++) { + SPI_TFT.tftio.WriteSequence((uint16_t*)(color_p + width * i), width); + } + lv_disp_flush_ready(disp); /* Indicate you are ready with the flushing*/ + + W25QXX.init(SPI_QUARTER_SPEED); +} + +#define TICK_CYCLE 1 + +unsigned int getTickDiff(unsigned int curTick, unsigned int lastTick) { + return TICK_CYCLE * (lastTick <= curTick ? (curTick - lastTick) : (0xFFFFFFFF - lastTick + curTick)); +} + +static bool get_point(int16_t *x, int16_t *y) { + bool is_touched = touch.getRawPoint(x, y); + + if (is_touched) { + *x = int16_t((int32_t(*x) * XPT2046_X_CALIBRATION) >> 16) + XPT2046_X_OFFSET; + *y = int16_t((int32_t(*y) * XPT2046_Y_CALIBRATION) >> 16) + XPT2046_Y_OFFSET; + } + + #if (TFT_ROTATION & TFT_ROTATE_180) + *x = int16_t((TFT_WIDTH) - (int)(*x)); + *y = int16_t((TFT_HEIGHT) - (int)(*y)); + #endif + + return is_touched; +} + +bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) { + static int16_t last_x = 0, last_y = 0; + static uint8_t last_touch_state = LV_INDEV_STATE_REL; + static int32_t touch_time1 = 0; + uint32_t tmpTime, diffTime = 0; + + tmpTime = millis(); + diffTime = getTickDiff(tmpTime, touch_time1); + /*Save the state and save the pressed coordinate*/ + //data->state = TOUCH_PressValid(last_x, last_y) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; + //if (data->state == LV_INDEV_STATE_PR) ADS7843_Rd_Addata((u16 *)&last_x, (u16 *)&last_y); + //touchpad_get_xy(&last_x, &last_y); + /*Save the pressed coordinates and the state*/ + if (diffTime > 20) { + if (get_point(&last_x, &last_y)) { + + if (last_touch_state == LV_INDEV_STATE_PR) return false; + data->state = LV_INDEV_STATE_PR; + + // Set the coordinates (if released use the last-pressed coordinates) + + data->point.x = last_x; + data->point.y = last_y; + + last_x = last_y = 0; + last_touch_state = LV_INDEV_STATE_PR; + } + else { + if (last_touch_state == LV_INDEV_STATE_PR) + data->state = LV_INDEV_STATE_REL; + last_touch_state = LV_INDEV_STATE_REL; + } + + touch_time1 = tmpTime; + } + + return false; // Return `false` since no data is buffering or left to read +} + +int16_t enc_diff = 0; +lv_indev_state_t state = LV_INDEV_STATE_REL; + +bool my_mousewheel_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) { + (void) indev_drv; /*Unused*/ + + data->state = state; + data->enc_diff = enc_diff; + enc_diff = 0; + + return false; /*No more data to read so return false*/ +} + +extern uint8_t currentFlashPage; + +//spi_flash +uint32_t pic_read_base_addr = 0, pic_read_addr_offset = 0; +lv_fs_res_t spi_flash_open_cb (lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode) { + static char last_path_name[30]; + if (strcasecmp(last_path_name,path) != 0) { + pic_read_base_addr = lv_get_pic_addr((uint8_t *)path); + ZERO(last_path_name); + strcpy(last_path_name,path); + } + else { + W25QXX.init(SPI_QUARTER_SPEED); + currentFlashPage = 0; + } + pic_read_addr_offset = pic_read_base_addr; + return LV_FS_RES_OK; +} + +lv_fs_res_t spi_flash_close_cb (lv_fs_drv_t * drv, void * file_p) { + lv_fs_res_t res = LV_FS_RES_OK; + /* Add your code here*/ + pic_read_addr_offset = pic_read_base_addr; + return res; +} + +lv_fs_res_t spi_flash_read_cb (lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br) { + lv_pic_test((uint8_t *)buf, pic_read_addr_offset, btr); + *br = btr; + return LV_FS_RES_OK; +} + +lv_fs_res_t spi_flash_seek_cb(lv_fs_drv_t * drv, void * file_p, uint32_t pos) { + #if HAS_SPI_FLASH_COMPRESSION + if (pos == 4) { + uint8_t bmp_header[4]; + SPIFlash.beginRead(pic_read_base_addr); + SPIFlash.readData(bmp_header, 4); + currentFlashPage = 1; + } + pic_read_addr_offset = pic_read_base_addr; + #else + pic_read_addr_offset = pic_read_base_addr + pos; + #endif + return LV_FS_RES_OK; +} + +lv_fs_res_t spi_flash_tell_cb(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p) { + *pos_p = pic_read_addr_offset - pic_read_base_addr; + return LV_FS_RES_OK; +} + +//sd +char *cur_namefff; +uint32_t sd_read_base_addr = 0,sd_read_addr_offset = 0; +lv_fs_res_t sd_open_cb (lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode) { + //cur_namefff = strrchr(path, '/'); + char name_buf[100]; + ZERO(name_buf); + strcat(name_buf,"/"); + strcat(name_buf,path); + char *temp = strstr(name_buf,".bin"); + if (temp) { strcpy(temp,".GCO"); } + sd_read_base_addr = lv_open_gcode_file((char *)name_buf); + sd_read_addr_offset = sd_read_base_addr; + if (sd_read_addr_offset == 0) return LV_FS_RES_NOT_EX; + return LV_FS_RES_OK; +} + +lv_fs_res_t sd_close_cb (lv_fs_drv_t * drv, void * file_p) { + /* Add your code here*/ + lv_close_gcode_file(); + return LV_FS_RES_OK; +} + +lv_fs_res_t sd_read_cb (lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br) { + if (btr == 200) { + lv_gcode_file_read((uint8_t *)buf); + //pic_read_addr_offset += 208; + *br = 200; + } + else if (btr == 4) { + uint8_t header_pic[4] = { 0x04, 0x90, 0x81, 0x0C }; + memcpy(buf, header_pic, 4); + //pic_read_addr_offset += 4; + *br = 4; + } + return LV_FS_RES_OK; +} + +lv_fs_res_t sd_seek_cb(lv_fs_drv_t * drv, void * file_p, uint32_t pos) { + sd_read_addr_offset = sd_read_base_addr + (pos - 4) / 200 * 409; + lv_gcode_file_seek(sd_read_addr_offset); + return LV_FS_RES_OK; +} + +lv_fs_res_t sd_tell_cb(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p) { + if (sd_read_addr_offset) *pos_p = 0; + else *pos_p = (sd_read_addr_offset - sd_read_base_addr) / 409 * 200 + 4; + return LV_FS_RES_OK; +} + +void lv_encoder_pin_init() { + #if 1 // HAS_DIGITAL_BUTTONS + + #if BUTTON_EXISTS(EN1) + SET_INPUT_PULLUP(BTN_EN1); + #endif + #if BUTTON_EXISTS(EN2) + SET_INPUT_PULLUP(BTN_EN2); + #endif + #if BUTTON_EXISTS(ENC) + SET_INPUT_PULLUP(BTN_ENC); + #endif + + #if BUTTON_EXISTS(BACK) + SET_INPUT_PULLUP(BTN_BACK); + #endif + + #if BUTTON_EXISTS(UP) + SET_INPUT(BTN_UP); + #endif + #if BUTTON_EXISTS(DWN) + SET_INPUT(BTN_DWN); + #endif + #if BUTTON_EXISTS(LFT) + SET_INPUT(BTN_LFT); + #endif + #if BUTTON_EXISTS(RT) + SET_INPUT(BTN_RT); + #endif + + #endif // HAS_DIGITAL_BUTTONS +} + +#if 1 // HAS_ENCODER_ACTION + + //static const int8_t encoderDirection = 1; + //static int16_t enc_Direction; + void lv_update_encoder() { + static uint32_t encoder_time1; + uint32_t tmpTime, diffTime = 0; + tmpTime = millis(); + diffTime = getTickDiff(tmpTime, encoder_time1); + if (diffTime > 50) { + + #if HAS_ENCODER_WHEEL + + #if ANY_BUTTON(EN1, EN2, ENC, BACK) + + uint8_t newbutton = 0; + + #if BUTTON_EXISTS(EN1) + if (BUTTON_PRESSED(EN1)) newbutton |= EN_A; + #endif + #if BUTTON_EXISTS(EN2) + if (BUTTON_PRESSED(EN2)) newbutton |= EN_B; + #endif + #if BUTTON_EXISTS(ENC) + if (BUTTON_PRESSED(ENC)) newbutton |= EN_C; + #endif + #if BUTTON_EXISTS(BACK) + if (BUTTON_PRESSED(BACK)) newbutton |= EN_D; + #endif + + #else + + constexpr uint8_t newbutton = 0; + + #endif + + static uint8_t buttons = 0; + buttons = newbutton; + static uint8_t lastEncoderBits; + + #define encrot0 0 + #define encrot1 1 + #define encrot2 2 + + // Manage encoder rotation + //#define ENCODER_SPIN(_E1, _E2) switch (lastEncoderBits) { case _E1: enc_Direction += encoderDirection; break; case _E2: enc_Direction -= encoderDirection; } + + uint8_t enc = 0; + if (buttons & EN_A) enc |= B01; + if (buttons & EN_B) enc |= B10; + if (enc != lastEncoderBits) { + switch (enc) { + case encrot1: + if (lastEncoderBits == encrot0) { + enc_diff--; + encoder_time1 = tmpTime; + } + break; + case encrot2: + if (lastEncoderBits == encrot0) { + enc_diff++; + encoder_time1 = tmpTime; + } + break; + } + lastEncoderBits = enc; + } + static uint8_t last_button_state = LV_INDEV_STATE_REL; + const uint8_t enc_c = (buttons & EN_C) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; + if (enc_c != last_button_state) { + state = enc_c ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; + + last_button_state = enc_c; + } + + #endif // HAS_ENCODER_WHEEL + + } // next_button_update_ms + } + +#endif // HAS_ENCODER_ACTION + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_lvgl_configuration.h b/Marlin/src/lcd/extui/lib/mks_ui/tft_lvgl_configuration.h new file mode 100644 index 000000000000..727ab33aea30 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_lvgl_configuration.h @@ -0,0 +1,65 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * @file lcd/extui/lib/mks_ui/tft_lvgl_configuration.h + * @date 2020-02-21 + */ + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +#include + +//#define TFT_ROTATION TFT_ROTATE_180 +#define USE_WIFI_FUNCTION 0 + +extern void tft_lvgl_init(); +extern void my_disp_flush(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * color_p); +extern bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data); +extern bool my_mousewheel_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); + +extern void LCD_Clear(uint16_t Color); +extern void tft_set_point(uint16_t x, uint16_t y, uint16_t point); +extern void LCD_setWindowArea(uint16_t StartX, uint16_t StartY, uint16_t width, uint16_t heigh); +extern void LCD_WriteRAM_Prepare(void); +extern void lcd_draw_logo(); +extern void lv_encoder_pin_init(); +extern void lv_update_encoder(); + +extern lv_fs_res_t spi_flash_open_cb (lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode); +extern lv_fs_res_t spi_flash_close_cb (lv_fs_drv_t * drv, void * file_p); +extern lv_fs_res_t spi_flash_read_cb (lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br); +extern lv_fs_res_t spi_flash_seek_cb(lv_fs_drv_t * drv, void * file_p, uint32_t pos); +extern lv_fs_res_t spi_flash_tell_cb(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p); + +extern lv_fs_res_t sd_open_cb (lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode); +extern lv_fs_res_t sd_close_cb (lv_fs_drv_t * drv, void * file_p); +extern lv_fs_res_t sd_read_cb (lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br); +extern lv_fs_res_t sd_seek_cb(lv_fs_drv_t * drv, void * file_p, uint32_t pos); +extern lv_fs_res_t sd_tell_cb(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.cpp b/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.cpp new file mode 100644 index 000000000000..e230195eabac --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.cpp @@ -0,0 +1,2631 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "../../../../MarlinCore.h" + +#include "draw_ui.h" +#include "tft_multi_language.h" + +// ********************************************* // + +common_menu_def common_menu; +main_menu_def main_menu; +preheat_menu_def preheat_menu; +move_menu_def move_menu; +home_menu_def home_menu; +file_menu_def file_menu; +extrude_menu_def extrude_menu; +leveling_menu_def leveling_menu; +set_menu_def set_menu; +more_menu_def more_menu; +wifi_menu_def wifi_menu; +cloud_menu_def cloud_menu; +about_menu_def about_menu; +fan_menu_def fan_menu; +filament_menu_def filament_menu; +printing_menu_def printing_menu; +operation_menu_def operation_menu; +pause_menu_def pause_menu; +speed_menu_def speed_menu; +printing_more_menu_def printing_more_menu; +dialog_menu_def dialog_menu; +language_menu_def language_menu; +print_file_dialog_menu_def print_file_dialog_menu; +filesys_menu_def filesys_menu; +tool_menu_def tool_menu; +MachinePara_menu_def MachinePara_menu; +pause_msg_def pause_msg_menu; +eeprom_def eeprom_menu; + +machine_common_def machine_menu; +void machine_setting_disp() { + if (gCfgItems.language == LANG_SIMPLE_CHINESE) { + MachinePara_menu.title = MACHINE_PARA_TITLE_CN; + MachinePara_menu.MachineSetting = MACHINE_TYPE_CNOFIG_CN; + MachinePara_menu.MotorSetting = MOTOR_CONFIG_CN; + MachinePara_menu.leveling = MACHINE_LEVELING_CONFIG_CN; + MachinePara_menu.AdvanceSetting = ADVANCE_CONFIG_CN; + + machine_menu.default_value = DEFAULT_CN; + machine_menu.next = NEXT_CN; + machine_menu.previous = PREVIOUS_CN; + + machine_menu.MachineConfigTitle = MACHINE_CONFIG_TITLE_CN; + machine_menu.MachineType = MACHINE_TYPE_CN; + machine_menu.Stroke = MACHINE_STROKE_CN; + machine_menu.HomeDir = MACHINE_HOMEDIR_CN; + machine_menu.EndStopType = MACHINE_ENDSTOP_TYPE_CN; + machine_menu.FilamentConf = MACHINE_FILAMENT_CONFIG_CN; + + machine_menu.MachineTypeConfTitle = MACHINE_TYPE_CONFIG_TITLE_CN; + machine_menu.xyz = MACHINE_TYPE_XYZ_CN; + machine_menu.delta = MACHINE_TYPE_DELTA_CN; + machine_menu.corexy = MACHINE_TYPE_COREXY_CN; + + machine_menu.StrokeConfTitle = MACHINE_STROKE_CONF_TITLE_CN; + machine_menu.xStroke = X_MAX_LENGTH_CN; + machine_menu.yStroke = Y_MAX_LENGTH_CN; + machine_menu.zStroke = Z_MAX_LENGTH_CN; + + machine_menu.xmin = X_MIN_LENGTH_CN; + machine_menu.ymin = Y_MIN_LENGTH_CN; + machine_menu.zmin = Z_MIN_LENGTH_CN; + + machine_menu.HomeDirConfTitle = HOME_DIR_CONF_TITLE_CN; + machine_menu.xHomeDir = HOME_DIR_X_CN; + machine_menu.yHomeDir = HOME_DIR_Y_CN; + machine_menu.zHomeDir = HOME_DIR_Z_CN; + machine_menu.min = HOME_MIN_CN; + machine_menu.max = HOME_MAX_CN; + + machine_menu.EndstopConfTitle = ENDSTOP_CONF_TITLE_CN; + machine_menu.xEndstop_min = MIN_ENDSTOP_X_CN; + machine_menu.yEndstop_min = MIN_ENDSTOP_Y_CN; + machine_menu.zEndstop_min = MIN_ENDSTOP_Z_CN; + machine_menu.xEndstop_max = MAX_ENDSTOP_X_CN; + machine_menu.yEndstop_max = MAX_ENDSTOP_Y_CN; + machine_menu.zEndstop_max = MAX_ENDSTOP_Z_CN; + machine_menu.FilamentEndstop = ENDSTOP_FIL_CN; + machine_menu.LevelingEndstop = ENDSTOP_LEVEL_CN; + machine_menu.opened = ENDSTOP_OPENED_CN; + machine_menu.closed = ENDSTOP_CLOSED_CN; + + machine_menu.FilamentConfTitle = FILAMENT_CONF_TITLE_CN; + machine_menu.InLength = FILAMENT_IN_LENGTH_CN; + machine_menu.InSpeed = FILAMENT_IN_SPEED_CN; + machine_menu.FilamentTemperature = FILAMENT_TEMPERATURE_CN; + machine_menu.OutLength = FILAMENT_OUT_LENGTH_CN; + machine_menu.OutSpeed = FILAMENT_OUT_SPEED_CN; + + machine_menu.LevelingParaConfTitle = LEVELING_CONF_TITLE_CN; + machine_menu.LevelingParaConf = LEVELING_PARA_CONF_CN; + machine_menu.LevelingManuPosConf = LEVELING_MANUAL_POS_CN; + machine_menu.LevelingAutoCommandConf = LEVELING_AUTO_COMMAND_CN; + machine_menu.LevelingAutoZoffsetConf = LEVELING_AUTO_ZOFFSET_CN; + + machine_menu.LevelingSubConfTitle = LEVELING_PARA_CONF_TITLE_CN; + machine_menu.AutoLevelEnable = AUTO_LEVELING_ENABLE_CN; + machine_menu.BLtouchEnable = BLTOUCH_LEVELING_ENABLE_CN; + machine_menu.ProbePort = PROBE_PORT_CN; + machine_menu.ProbeXoffset = PROBE_X_OFFSET_CN; + machine_menu.ProbeYoffset = PROBE_Y_OFFSET_CN; + machine_menu.ProbeZoffset = PROBE_Z_OFFSET_CN; + machine_menu.ProbeXYspeed = PROBE_XY_SPEED_CN; + machine_menu.ProbeZspeed = PROBE_Z_SPEED_CN; + machine_menu.enable = ENABLE_CN; + machine_menu.disable = DISABLE_CN; + machine_menu.z_min = Z_MIN_CN; + machine_menu.z_max = Z_MAX_CN; + + machine_menu.LevelingSubDeltaConfTitle = DELTA_LEVEL_CONF_TITLE_CN; + machine_menu.MachineRadius = DELTA_MACHINE_RADIUS_CN; + machine_menu.DiagonalRod = DELTA_DIAGONAL_ROD_CN; + machine_menu.PrintableRadius = DELTA_PRINT_RADIUS_CN; + machine_menu.DeltaHeight = DELTA_HEIGHT_CN; + machine_menu.SmoothRodOffset = SMOOTH_ROD_OFFSET_CN; + machine_menu.EffectorOffset = EFFECTOR_OFFSET_CN; + machine_menu.CalibrationRadius = CALIBRATION_RADIUS_CN; + + machine_menu.LevelingSubXYZConfTitle = XYZ_LEVEL_CONF_TITLE_CN; + // machine_menu.ProbeMaxLeft=PROBE_REACH_MAX_LEFT_CN; + // machine_menu.ProbeMaxRigh=PROBE_REACH_MAX_RIGHT_CN; + // machine_menu.ProbeMaxfront=PROBE_REACH_MAX_FRONT_CN; + // machine_menu.ProbeMaxback=PROBE_REACH_MAX_BACK_CN; + + machine_menu.TemperatureConfTitle = TEMPERATURE_CONF_TITLE_CN; + machine_menu.NozzleConf = NOZZLE_CONF_CN; + machine_menu.HotBedConf = HOTBED_CONF_CN; + machine_menu.PreheatTemperConf = PREHEAT_TEMPER_CN; + + machine_menu.NozzleConfTitle = NOZZLE_CONF_TITLE_CN; + machine_menu.NozzleCnt = NOZZLECNT_CN; + machine_menu.NozzleType = NOZZLE_TYPE_CN; + machine_menu.NozzleAdjustType = NOZZLE_ADJUST_TYPE_CN; + machine_menu.NozzleMinTemperature = NOZZLE_MIN_TEMPERATURE_CN; + machine_menu.NozzleMaxTemperature = NOZZLE_MAX_TEMPERATURE_CN; + machine_menu.Extrude_Min_Temper = EXTRUD_MIN_TEMPER_CN; + + // machine_menu.HotbedEnable=HOTBED_ENABLE_CN; + machine_menu.HotbedConfTitle = HOTBED_CONF_TITLE_CN; + machine_menu.HotbedAjustType = HOTBED_ADJUST_CN; + machine_menu.HotbedMinTemperature = HOTBED_MIN_TEMPERATURE_CN; + machine_menu.HotbedMaxTemperature = HOTBED_MAX_TEMPERATURE_CN; + + machine_menu.MotorConfTitle = MOTOR_CONF_TITLE_CN; + machine_menu.MaxFeedRateConf = MAXFEEDRATE_CONF_CN; + machine_menu.AccelerationConf = ACCELERATION_CONF_CN; + machine_menu.JerkConf = JERKCONF_CN; + machine_menu.StepsConf = STEPSCONF_CN; + machine_menu.TMCcurrentConf = TMC_CURRENT_CN; + machine_menu.TMCStepModeConf = TMC_STEP_MODE_CN; + machine_menu.MotorDirConf = MOTORDIRCONF_CN; + machine_menu.HomeFeedRateConf = HOMEFEEDRATECONF_CN; + machine_menu.PausePosition = PAUSE_POSITION_CN; + machine_menu.WifiSettings = WIFI_SETTINGS_CN; + machine_menu.HomingSensitivityConf = HOMING_SENSITIVITY_CONF_CN; + machine_menu.EncoderSettings = ENCODER_SETTINGS_CN; + + machine_menu.MaxFeedRateConfTitle = MAXFEEDRATE_CONF_TITLE_CN; + machine_menu.XMaxFeedRate = X_MAXFEEDRATE_CN; + machine_menu.YMaxFeedRate = Y_MAXFEEDRATE_CN; + machine_menu.ZMaxFeedRate = Z_MAXFEEDRATE_CN; + machine_menu.E0MaxFeedRate = E0_MAXFEEDRATE_CN; + machine_menu.E1MaxFeedRate = E1_MAXFEEDRATE_CN; + + machine_menu.AccelerationConfTitle = ACCELERATION_CONF_TITLE_CN; + machine_menu.PrintAcceleration = PRINT_ACCELERATION_CN; + machine_menu.RetractAcceleration = RETRACT_ACCELERATION_CN; + machine_menu.TravelAcceleration = TRAVEL_ACCELERATION_CN; + machine_menu.X_Acceleration = X_ACCELERATION_CN; + machine_menu.Y_Acceleration = Y_ACCELERATION_CN; + machine_menu.Z_Acceleration = Z_ACCELERATION_CN; + machine_menu.E0_Acceleration = E0_ACCELERATION_CN; + machine_menu.E1_Acceleration = E1_ACCELERATION_CN; + + machine_menu.JerkConfTitle = JERK_CONF_TITLE_CN; + machine_menu.X_Jerk = X_JERK_CN; + machine_menu.Y_Jerk = Y_JERK_CN; + machine_menu.Z_Jerk = Z_JERK_CN; + machine_menu.E_Jerk = E_JERK_CN; + + machine_menu.StepsConfTitle = STEPS_CONF_TITLE_CN; + machine_menu.X_Steps = X_STEPS_CN; + machine_menu.Y_Steps = Y_STEPS_CN; + machine_menu.Z_Steps = Z_STEPS_CN; + machine_menu.E0_Steps = E0_STEPS_CN; + machine_menu.E1_Steps = E1_STEPS_CN; + + machine_menu.TmcCurrentConfTitle = TMC_CURRENT_CONF_TITLE_CN; + machine_menu.X_Current = X_TMC_CURRENT_CN; + machine_menu.Y_Current = Y_TMC_CURRENT_CN; + machine_menu.Z_Current = Z_TMC_CURRENT_CN; + machine_menu.E0_Current = E0_TMC_CURRENT_CN; + machine_menu.E1_Current = E1_TMC_CURRENT_CN; + + machine_menu.TmcStepModeConfTitle = TMC_MODE_CONF_TITLE_CN; + machine_menu.X_StepMode = X_TMC_MODE_CN; + machine_menu.Y_StepMode = Y_TMC_MODE_CN; + machine_menu.Z_StepMode = Z_TMC_MODE_CN; + machine_menu.E0_StepMode = E0_TMC_MODE_CN; + machine_menu.E1_StepMode = E1_TMC_MODE_CN; + + machine_menu.MotorDirConfTitle = MOTORDIR_CONF_TITLE_CN; + machine_menu.X_MotorDir = X_MOTORDIR_CN; + machine_menu.Y_MotorDir = Y_MOTORDIR_CN; + machine_menu.Z_MotorDir = Z_MOTORDIR_CN; + machine_menu.E0_MotorDir = E0_MOTORDIR_CN; + machine_menu.E1_MotorDir = E1_MOTORDIR_CN; + machine_menu.Invert_0 = INVERT_P_CN; + machine_menu.Invert_1 = INVERT_N_CN; + + machine_menu.HomeFeedRateConfTitle = HOMEFEEDRATE_CONF_TITLE_CN; + machine_menu.XY_HomeFeedRate = X_HOMESPEED_CN; + // machine_menu.Y_HomeFeedRate=Y_HOMESPEED_CN; + machine_menu.Z_HomeFeedRate = Z_HOMESPEED_CN; + + machine_menu.AdvancedConfTitle = ADVANCED_CONF_TITLE_CN; + machine_menu.PwrOffDection = PWROFF_DECTION_CN; + machine_menu.PwrOffAfterPrint = PWROFF_AFTER_PRINT_CN; + machine_menu.HaveUps = HAVE_UPS_CN; + machine_menu.Z2andZ2Endstop = Z2_AND_Z2ENDSTOP_CONF_CN; + machine_menu.EnablePinsInvert = ENABLE_PINS_CONF_CN; + + machine_menu.Z2ConfTitle = Z2_AND_Z2ENDSTOP_CONF_TITLE_CN; + machine_menu.Z2Enable = Z2_ENABLE_CN; + machine_menu.Z2EndstopEnable = Z2_ENDSTOP_CN; + machine_menu.Z2Port = Z2_PORT_CN; + + machine_menu.EnablePinsInvertTitle = ENABLE_PINS_CONF_TITLE_CN; + machine_menu.XInvert = X_ENABLE_PINS_INVERT_CN; + machine_menu.YInvert = Y_ENABLE_PINS_INVERT_CN; + machine_menu.ZInvert = Z_ENABLE_PINS_INVERT_CN; + machine_menu.EInvert = E_ENABLE_PINS_INVERT_CN; + + machine_menu.key_back = KEY_BACK_CN; + machine_menu.key_reset = KEY_REST_CN; + machine_menu.key_confirm = KEY_CONFIRM_CN; + + machine_menu.PausePosText = PAUSE_POSITION_CN; + machine_menu.xPos = PAUSE_POSITION_X_CN; + machine_menu.yPos = PAUSE_POSITION_Y_CN; + machine_menu.zPos = PAUSE_POSITION_Z_CN; + machine_menu.WifiConfTitle = WIFI_SETTINGS_TITLE_CN; + machine_menu.wifiMode = WIFI_SETTINGS_MODE_CN; + machine_menu.wifiName = WIFI_SETTINGS_NAME_CN; + machine_menu.wifiPassWord = WIFI_SETTINGS_PASSWORD_CN; + machine_menu.wifiCloud = WIFI_SETTINGS_CLOUD_CN; + machine_menu.wifiConfig = WIFI_SETTINGS_CONFIG_CN; + machine_menu.wifiEdit = WIFI_SETTINGS_EDIT_CN; + machine_menu.wifiConfigTips = WIFI_CONFIG_TIPS_CN; + + machine_menu.OffsetConfTitle = OFFSET_TITLE_CN; + machine_menu.Xoffset = OFFSET_X_CN; + machine_menu.Yoffset = OFFSET_Y_CN; + machine_menu.Zoffset = OFFSET_Z_CN; + + machine_menu.HomingSensitivityConfTitle = HOMING_SENSITIVITY_CONF_TITLE_CN; + machine_menu.X_Sensitivity = X_SENSITIVITY_CN; + machine_menu.Y_Sensitivity = Y_SENSITIVITY_CN; + machine_menu.Z_Sensitivity = Z_SENSITIVITY_CN; + machine_menu.Z2_Sensitivity = Z2_SENSITIVITY_CN; + + machine_menu.EncoderConfTitle = ENCODER_CONF_TITLE_CN; + machine_menu.EncoderConfText = ENCODER_CONF_TEXT_CN; + } + else if (gCfgItems.language == LANG_COMPLEX_CHINESE) { + MachinePara_menu.title = MACHINE_PARA_TITLE_T_CN; + MachinePara_menu.MachineSetting = MACHINE_TYPE_CNOFIG_T_CN; + MachinePara_menu.MotorSetting = MOTOR_CONFIG_T_CN; + MachinePara_menu.leveling = MACHINE_LEVELING_CONFIG_T_CN; + MachinePara_menu.AdvanceSetting = ADVANCE_CONFIG_T_CN; + + machine_menu.default_value = DEFAULT_T_CN; + machine_menu.next = NEXT_T_CN; + machine_menu.previous = PREVIOUS_T_CN; + + machine_menu.MachineConfigTitle = MACHINE_CONFIG_TITLE_T_CN; + machine_menu.MachineType = MACHINE_TYPE_T_CN; + machine_menu.Stroke = MACHINE_STROKE_T_CN; + machine_menu.HomeDir = MACHINE_HOMEDIR_T_CN; + machine_menu.EndStopType = MACHINE_ENDSTOP_TYPE_T_CN; + machine_menu.FilamentConf = MACHINE_FILAMENT_CONFIG_T_CN; + + machine_menu.MachineTypeConfTitle = MACHINE_TYPE_CONFIG_TITLE_T_CN; + machine_menu.xyz = MACHINE_TYPE_XYZ_T_CN; + machine_menu.delta = MACHINE_TYPE_DELTA_T_CN; + machine_menu.corexy = MACHINE_TYPE_COREXY_T_CN; + + machine_menu.StrokeConfTitle = MACHINE_STROKE_CONF_TITLE_T_CN; + machine_menu.xStroke = X_MAX_LENGTH_T_CN; + machine_menu.yStroke = Y_MAX_LENGTH_T_CN; + machine_menu.zStroke = Z_MAX_LENGTH_T_CN; + + machine_menu.xmin = X_MIN_LENGTH_T_CN; + machine_menu.ymin = Y_MIN_LENGTH_T_CN; + machine_menu.zmin = Z_MIN_LENGTH_T_CN; + + machine_menu.HomeDirConfTitle = HOME_DIR_CONF_TITLE_T_CN; + machine_menu.xHomeDir = HOME_DIR_X_T_CN; + machine_menu.yHomeDir = HOME_DIR_Y_T_CN; + machine_menu.zHomeDir = HOME_DIR_Z_T_CN; + machine_menu.min = HOME_MIN_T_CN; + machine_menu.max = HOME_MAX_T_CN; + + machine_menu.EndstopConfTitle = ENDSTOP_CONF_TITLE_T_CN; + machine_menu.xEndstop_min = MIN_ENDSTOP_X_T_CN; + machine_menu.yEndstop_min = MIN_ENDSTOP_Y_T_CN; + machine_menu.zEndstop_min = MIN_ENDSTOP_Z_T_CN; + machine_menu.xEndstop_max = MAX_ENDSTOP_X_T_CN; + machine_menu.yEndstop_max = MAX_ENDSTOP_Y_T_CN; + machine_menu.zEndstop_max = MAX_ENDSTOP_Z_T_CN; + machine_menu.FilamentEndstop = ENDSTOP_FIL_T_CN; + machine_menu.LevelingEndstop = ENDSTOP_LEVEL_T_CN; + machine_menu.opened = ENDSTOP_OPENED_T_CN; + machine_menu.closed = ENDSTOP_CLOSED_T_CN; + + machine_menu.FilamentConfTitle = FILAMENT_CONF_TITLE_T_CN; + machine_menu.InLength = FILAMENT_IN_LENGTH_T_CN; + machine_menu.InSpeed = FILAMENT_IN_SPEED_T_CN; + machine_menu.FilamentTemperature = FILAMENT_TEMPERATURE_T_CN; + machine_menu.OutLength = FILAMENT_OUT_LENGTH_T_CN; + machine_menu.OutSpeed = FILAMENT_OUT_SPEED_T_CN; + + machine_menu.LevelingParaConfTitle = LEVELING_CONF_TITLE_T_CN; + machine_menu.LevelingParaConf = LEVELING_PARA_CONF_T_CN; + machine_menu.LevelingManuPosConf = LEVELING_MANUAL_POS_T_CN; + machine_menu.LevelingAutoCommandConf = LEVELING_AUTO_COMMAND_T_CN; + machine_menu.LevelingAutoZoffsetConf = LEVELING_AUTO_ZOFFSET_T_CN; + + machine_menu.LevelingSubConfTitle = LEVELING_PARA_CONF_TITLE_T_CN; + machine_menu.AutoLevelEnable = AUTO_LEVELING_ENABLE_T_CN; + machine_menu.BLtouchEnable = BLTOUCH_LEVELING_ENABLE_T_CN; + machine_menu.ProbePort = PROBE_PORT_T_CN; + machine_menu.ProbeXoffset = PROBE_X_OFFSET_T_CN; + machine_menu.ProbeYoffset = PROBE_Y_OFFSET_T_CN; + machine_menu.ProbeZoffset = PROBE_Z_OFFSET_T_CN; + machine_menu.ProbeXYspeed = PROBE_XY_SPEED_T_CN; + machine_menu.ProbeZspeed = PROBE_Z_SPEED_T_CN; + machine_menu.enable = ENABLE_T_CN; + machine_menu.disable = DISABLE_T_CN; + machine_menu.z_min = Z_MIN_T_CN; + machine_menu.z_max = Z_MAX_T_CN; + + machine_menu.LevelingSubDeltaConfTitle = DELTA_LEVEL_CONF_TITLE_T_CN; + machine_menu.MachineRadius = DELTA_MACHINE_RADIUS_T_CN; + machine_menu.DiagonalRod = DELTA_DIAGONAL_ROD_T_CN; + machine_menu.PrintableRadius = DELTA_PRINT_RADIUS_T_CN; + machine_menu.DeltaHeight = DELTA_HEIGHT_T_CN; + machine_menu.SmoothRodOffset = SMOOTH_ROD_OFFSET_T_CN; + machine_menu.EffectorOffset = EFFECTOR_OFFSET_T_CN; + machine_menu.CalibrationRadius = CALIBRATION_RADIUS_T_CN; + + machine_menu.LevelingSubXYZConfTitle = XYZ_LEVEL_CONF_TITLE_T_CN; + // machine_menu.ProbeMaxLeft=PROBE_REACH_MAX_LEFT_T_CN; + // machine_menu.ProbeMaxRigh=PROBE_REACH_MAX_RIGHT_T_CN; + // machine_menu.ProbeMaxfront=PROBE_REACH_MAX_FRONT_T_CN; + // machine_menu.ProbeMaxback=PROBE_REACH_MAX_BACK_T_CN; + + machine_menu.TemperatureConfTitle = TEMPERATURE_CONF_TITLE_T_CN; + machine_menu.NozzleConf = NOZZLE_CONF_T_CN; + machine_menu.HotBedConf = HOTBED_CONF_T_CN; + machine_menu.PreheatTemperConf = PREHEAT_TEMPER_T_CN; + + machine_menu.NozzleConfTitle = NOZZLE_CONF_TITLE_T_CN; + machine_menu.NozzleCnt = NOZZLECNT_T_CN; + machine_menu.NozzleType = NOZZLE_TYPE_T_CN; + machine_menu.NozzleAdjustType = NOZZLE_ADJUST_TYPE_T_CN; + machine_menu.NozzleMinTemperature = NOZZLE_MIN_TEMPERATURE_T_CN; + machine_menu.NozzleMaxTemperature = NOZZLE_MAX_TEMPERATURE_T_CN; + machine_menu.Extrude_Min_Temper = EXTRUD_MIN_TEMPER_T_CN; + + // machine_menu.HotbedEnable=HOTBED_ENABLE_T_CN; + machine_menu.HotbedConfTitle = HOTBED_CONF_TITLE_T_CN; + machine_menu.HotbedAjustType = HOTBED_ADJUST_T_CN; + machine_menu.HotbedMinTemperature = HOTBED_MIN_TEMPERATURE_T_CN; + machine_menu.HotbedMaxTemperature = HOTBED_MAX_TEMPERATURE_T_CN; + + machine_menu.MotorConfTitle = MOTOR_CONF_TITLE_T_CN; + machine_menu.MaxFeedRateConf = MAXFEEDRATE_CONF_T_CN; + machine_menu.AccelerationConf = ACCELERATION_CONF_T_CN; + machine_menu.JerkConf = JERKCONF_T_CN; + machine_menu.StepsConf = STEPSCONF_T_CN; + machine_menu.TMCcurrentConf = TMC_CURRENT_T_CN; + machine_menu.TMCStepModeConf = TMC_STEP_MODE_T_CN; + machine_menu.MotorDirConf = MOTORDIRCONF_T_CN; + machine_menu.HomeFeedRateConf = HOMEFEEDRATECONF_T_CN; + machine_menu.PausePosition = PAUSE_POSITION_T_CN; + machine_menu.WifiSettings = WIFI_SETTINGS_T_CN; + machine_menu.HomingSensitivityConf = HOMING_SENSITIVITY_CONF_T_CN; + machine_menu.EncoderSettings = ENCODER_SETTINGS_T_CN; + + machine_menu.MaxFeedRateConfTitle = MAXFEEDRATE_CONF_TITLE_T_CN; + machine_menu.XMaxFeedRate = X_MAXFEEDRATE_T_CN; + machine_menu.YMaxFeedRate = Y_MAXFEEDRATE_T_CN; + machine_menu.ZMaxFeedRate = Z_MAXFEEDRATE_T_CN; + machine_menu.E0MaxFeedRate = E0_MAXFEEDRATE_T_CN; + machine_menu.E1MaxFeedRate = E1_MAXFEEDRATE_T_CN; + + machine_menu.AccelerationConfTitle = ACCELERATION_CONF_TITLE_T_CN; + machine_menu.PrintAcceleration = PRINT_ACCELERATION_T_CN; + machine_menu.RetractAcceleration = RETRACT_ACCELERATION_T_CN; + machine_menu.TravelAcceleration = TRAVEL_ACCELERATION_T_CN; + machine_menu.X_Acceleration = X_ACCELERATION_T_CN; + machine_menu.Y_Acceleration = Y_ACCELERATION_T_CN; + machine_menu.Z_Acceleration = Z_ACCELERATION_T_CN; + machine_menu.E0_Acceleration = E0_ACCELERATION_T_CN; + machine_menu.E1_Acceleration = E1_ACCELERATION_T_CN; + + machine_menu.JerkConfTitle = JERK_CONF_TITLE_T_CN; + machine_menu.X_Jerk = X_JERK_T_CN; + machine_menu.Y_Jerk = Y_JERK_T_CN; + machine_menu.Z_Jerk = Z_JERK_T_CN; + machine_menu.E_Jerk = E_JERK_T_CN; + + machine_menu.StepsConfTitle = STEPS_CONF_TITLE_T_CN; + machine_menu.X_Steps = X_STEPS_T_CN; + machine_menu.Y_Steps = Y_STEPS_T_CN; + machine_menu.Z_Steps = Z_STEPS_T_CN; + machine_menu.E0_Steps = E0_STEPS_T_CN; + machine_menu.E1_Steps = E1_STEPS_T_CN; + + machine_menu.TmcCurrentConfTitle = TMC_CURRENT_CONF_TITLE_T_CN; + machine_menu.X_Current = X_TMC_CURRENT_T_CN; + machine_menu.Y_Current = Y_TMC_CURRENT_T_CN; + machine_menu.Z_Current = Z_TMC_CURRENT_T_CN; + machine_menu.E0_Current = E0_TMC_CURRENT_T_CN; + machine_menu.E1_Current = E1_TMC_CURRENT_T_CN; + + machine_menu.TmcStepModeConfTitle = TMC_MODE_CONF_TITLE_T_CN; + machine_menu.X_StepMode = X_TMC_MODE_T_CN; + machine_menu.Y_StepMode = Y_TMC_MODE_T_CN; + machine_menu.Z_StepMode = Z_TMC_MODE_T_CN; + machine_menu.E0_StepMode = E0_TMC_MODE_T_CN; + machine_menu.E1_StepMode = E1_TMC_MODE_T_CN; + + machine_menu.MotorDirConfTitle = MOTORDIR_CONF_TITLE_T_CN; + machine_menu.X_MotorDir = X_MOTORDIR_T_CN; + machine_menu.Y_MotorDir = Y_MOTORDIR_T_CN; + machine_menu.Z_MotorDir = Z_MOTORDIR_T_CN; + machine_menu.E0_MotorDir = E0_MOTORDIR_T_CN; + machine_menu.E1_MotorDir = E1_MOTORDIR_T_CN; + machine_menu.Invert_0 = INVERT_P_T_CN; + machine_menu.Invert_1 = INVERT_N_T_CN; + + machine_menu.HomeFeedRateConfTitle = HOMEFEEDRATE_CONF_TITLE_T_CN; + machine_menu.XY_HomeFeedRate = X_HOMESPEED_T_CN; + // machine_menu.Y_HomeFeedRate=Y_HOMESPEED_T_CN; + machine_menu.Z_HomeFeedRate = Z_HOMESPEED_T_CN; + + machine_menu.AdvancedConfTitle = ADVANCED_CONF_TITLE_T_CN; + machine_menu.PwrOffDection = PWROFF_DECTION_T_CN; + machine_menu.PwrOffAfterPrint = PWROFF_AFTER_PRINT_T_CN; + machine_menu.HaveUps = HAVE_UPS_T_CN; + machine_menu.Z2andZ2Endstop = Z2_AND_Z2ENDSTOP_CONF_T_CN; + machine_menu.EnablePinsInvert = ENABLE_PINS_CONF_T_CN; + + machine_menu.Z2ConfTitle = Z2_AND_Z2ENDSTOP_CONF_TITLE_T_CN; + machine_menu.Z2Enable = Z2_ENABLE_T_CN; + machine_menu.Z2EndstopEnable = Z2_ENDSTOP_T_CN; + machine_menu.Z2Port = Z2_PORT_T_CN; + + machine_menu.EnablePinsInvertTitle = ENABLE_PINS_CONF_TITLE_T_CN; + machine_menu.XInvert = X_ENABLE_PINS_INVERT_T_CN; + machine_menu.YInvert = Y_ENABLE_PINS_INVERT_T_CN; + machine_menu.ZInvert = Z_ENABLE_PINS_INVERT_T_CN; + machine_menu.EInvert = E_ENABLE_PINS_INVERT_T_CN; + + machine_menu.key_back = KEY_BACK_T_CN; + machine_menu.key_reset = KEY_REST_T_CN; + machine_menu.key_confirm = KEY_CONFIRM_T_CN; + // machine_menu.high_level = MOTOR_EN_HIGH_LEVEL_T_CN; + // machine_menu.low_level = MOTOR_EN_LOW_LEVEL_T_CN; + + machine_menu.PausePosText = PAUSE_POSITION_T_CN; + machine_menu.xPos = PAUSE_POSITION_X_T_CN; + machine_menu.yPos = PAUSE_POSITION_Y_T_CN; + machine_menu.zPos = PAUSE_POSITION_Z_T_CN; + + machine_menu.WifiConfTitle = WIFI_SETTINGS_TITLE_T_CN; + machine_menu.wifiMode = WIFI_SETTINGS_MODE_T_CN; + machine_menu.wifiName = WIFI_SETTINGS_NAME_T_CN; + machine_menu.wifiPassWord = WIFI_SETTINGS_PASSWORD_T_CN; + machine_menu.wifiCloud = WIFI_SETTINGS_CLOUD_T_CN; + machine_menu.wifiConfig = WIFI_SETTINGS_CONFIG_T_CN; + machine_menu.wifiEdit = WIFI_SETTINGS_EDIT_T_CN; + machine_menu.wifiConfigTips = WIFI_CONFIG_TIPS_T_CN; + + machine_menu.OffsetConfTitle = OFFSET_TITLE_T_CN; + machine_menu.Xoffset = OFFSET_X_T_CN; + machine_menu.Yoffset = OFFSET_Y_T_CN; + machine_menu.Zoffset = OFFSET_Z_T_CN; + + machine_menu.HomingSensitivityConfTitle = HOMING_SENSITIVITY_CONF_TITLE_T_CN; + machine_menu.X_Sensitivity = X_SENSITIVITY_T_CN; + machine_menu.Y_Sensitivity = Y_SENSITIVITY_T_CN; + machine_menu.Z_Sensitivity = Z_SENSITIVITY_T_CN; + machine_menu.Z2_Sensitivity = Z2_SENSITIVITY_T_CN; + + machine_menu.EncoderConfTitle = ENCODER_CONF_TITLE_T_CN; + machine_menu.EncoderConfText = ENCODER_CONF_TEXT_T_CN; + } + else { + MachinePara_menu.title = MACHINE_PARA_TITLE_EN; + MachinePara_menu.MachineSetting = MACHINE_TYPE_CNOFIG_EN; + MachinePara_menu.MotorSetting = MOTOR_CONFIG_EN; + MachinePara_menu.leveling = MACHINE_LEVELING_CONFIG_EN; + MachinePara_menu.AdvanceSetting = ADVANCE_CONFIG_EN; + + machine_menu.default_value = DEFAULT_EN; + machine_menu.next = NEXT_EN; + machine_menu.previous = PREVIOUS_EN; + + machine_menu.MachineConfigTitle = MACHINE_CONFIG_TITLE_EN; + machine_menu.MachineType = MACHINE_TYPE_EN; + machine_menu.Stroke = MACHINE_STROKE_EN; + machine_menu.HomeDir = MACHINE_HOMEDIR_EN; + machine_menu.EndStopType = MACHINE_ENDSTOP_TYPE_EN; + machine_menu.FilamentConf = MACHINE_FILAMENT_CONFIG_EN; + + machine_menu.MachineTypeConfTitle = MACHINE_TYPE_CONFIG_TITLE_EN; + machine_menu.xyz = MACHINE_TYPE_XYZ_EN; + machine_menu.delta = MACHINE_TYPE_DELTA_EN; + machine_menu.corexy = MACHINE_TYPE_COREXY_EN; + + machine_menu.StrokeConfTitle = MACHINE_STROKE_CONF_TITLE_EN; + machine_menu.xStroke = X_MAX_LENGTH_EN; + machine_menu.yStroke = Y_MAX_LENGTH_EN; + machine_menu.zStroke = Z_MAX_LENGTH_EN; + + machine_menu.xmin = X_MIN_LENGTH_EN; + machine_menu.ymin = Y_MIN_LENGTH_EN; + machine_menu.zmin = Z_MIN_LENGTH_EN; + + machine_menu.HomeDirConfTitle = HOME_DIR_CONF_TITLE_EN; + machine_menu.xHomeDir = HOME_DIR_X_EN; + machine_menu.yHomeDir = HOME_DIR_Y_EN; + machine_menu.zHomeDir = HOME_DIR_Z_EN; + machine_menu.min = HOME_MIN_EN; + machine_menu.max = HOME_MAX_EN; + + machine_menu.EndstopConfTitle = ENDSTOP_CONF_TITLE_EN; + machine_menu.xEndstop_min = MIN_ENDSTOP_X_EN; + machine_menu.yEndstop_min = MIN_ENDSTOP_Y_EN; + machine_menu.zEndstop_min = MIN_ENDSTOP_Z_EN; + machine_menu.xEndstop_max = MAX_ENDSTOP_X_EN; + machine_menu.yEndstop_max = MAX_ENDSTOP_Y_EN; + machine_menu.zEndstop_max = MAX_ENDSTOP_Z_EN; + machine_menu.FilamentEndstop = ENDSTOP_FIL_EN; + machine_menu.LevelingEndstop = ENDSTOP_LEVEL_EN; + machine_menu.opened = ENDSTOP_OPENED_EN; + machine_menu.closed = ENDSTOP_CLOSED_EN; + + machine_menu.FilamentConfTitle = FILAMENT_CONF_TITLE_EN; + machine_menu.InLength = FILAMENT_IN_LENGTH_EN; + machine_menu.InSpeed = FILAMENT_IN_SPEED_EN; + machine_menu.FilamentTemperature = FILAMENT_TEMPERATURE_EN; + machine_menu.OutLength = FILAMENT_OUT_LENGTH_EN; + machine_menu.OutSpeed = FILAMENT_OUT_SPEED_EN; + + machine_menu.LevelingParaConfTitle = LEVELING_CONF_TITLE_EN; + machine_menu.LevelingParaConf = LEVELING_PARA_CONF_EN; + machine_menu.LevelingManuPosConf = LEVELING_MANUAL_POS_EN; + machine_menu.LevelingAutoCommandConf = LEVELING_AUTO_COMMAND_EN; + machine_menu.LevelingAutoZoffsetConf = LEVELING_AUTO_ZOFFSET_EN; + + machine_menu.LevelingSubConfTitle = LEVELING_PARA_CONF_TITLE_EN; + machine_menu.AutoLevelEnable = AUTO_LEVELING_ENABLE_EN; + machine_menu.BLtouchEnable = BLTOUCH_LEVELING_ENABLE_EN; + machine_menu.ProbePort = PROBE_PORT_EN; + machine_menu.ProbeXoffset = PROBE_X_OFFSET_EN; + machine_menu.ProbeYoffset = PROBE_Y_OFFSET_EN; + machine_menu.ProbeZoffset = PROBE_Z_OFFSET_EN; + machine_menu.ProbeXYspeed = PROBE_XY_SPEED_EN; + machine_menu.ProbeZspeed = PROBE_Z_SPEED_EN; + machine_menu.enable = ENABLE_EN; + machine_menu.disable = DISABLE_EN; + machine_menu.z_min = Z_MIN_EN; + machine_menu.z_max = Z_MAX_EN; + + machine_menu.LevelingSubDeltaConfTitle = DELTA_LEVEL_CONF_TITLE_EN; + machine_menu.MachineRadius = DELTA_MACHINE_RADIUS_EN; + machine_menu.DiagonalRod = DELTA_DIAGONAL_ROD_EN; + machine_menu.PrintableRadius = DELTA_PRINT_RADIUS_EN; + machine_menu.DeltaHeight = DELTA_HEIGHT_EN; + machine_menu.SmoothRodOffset = SMOOTH_ROD_OFFSET_EN; + machine_menu.EffectorOffset = EFFECTOR_OFFSET_EN; + machine_menu.CalibrationRadius = CALIBRATION_RADIUS_EN; + + machine_menu.LevelingSubXYZConfTitle = XYZ_LEVEL_CONF_TITLE_EN; + // machine_menu.Level_positon=PROBE_REACH_MAX_LEFT_EN; + // machine_menu.ProbeMaxRigh=PROBE_REACH_MAX_RIGHT_EN; + // machine_menu.ProbeMaxfront=PROBE_REACH_MAX_FRONT_EN; + // machine_menu.ProbeMaxback=PROBE_REACH_MAX_BACK_EN; + + machine_menu.TemperatureConfTitle = TEMPERATURE_CONF_TITLE_EN; + machine_menu.NozzleConf = NOZZLE_CONF_EN; + machine_menu.HotBedConf = HOTBED_CONF_EN; + machine_menu.PreheatTemperConf = PREHEAT_TEMPER_EN; + + machine_menu.NozzleConfTitle = NOZZLE_CONF_TITLE_EN; + machine_menu.NozzleCnt = NOZZLECNT_EN; + machine_menu.NozzleType = NOZZLE_TYPE_EN; + machine_menu.NozzleAdjustType = NOZZLE_ADJUST_TYPE_EN; + machine_menu.NozzleMinTemperature = NOZZLE_MIN_TEMPERATURE_EN; + machine_menu.NozzleMaxTemperature = NOZZLE_MAX_TEMPERATURE_EN; + machine_menu.Extrude_Min_Temper = EXTRUD_MIN_TEMPER_EN; + + machine_menu.HotbedEnable = HOTBED_ENABLE_EN; + machine_menu.HotbedConfTitle = HOTBED_CONF_TITLE_EN; + machine_menu.HotbedAjustType = HOTBED_ADJUST_EN; + machine_menu.HotbedMinTemperature = HOTBED_MIN_TEMPERATURE_EN; + machine_menu.HotbedMaxTemperature = HOTBED_MAX_TEMPERATURE_EN; + + machine_menu.MotorConfTitle = MOTOR_CONF_TITLE_EN; + machine_menu.MaxFeedRateConf = MAXFEEDRATE_CONF_EN; + machine_menu.AccelerationConf = ACCELERATION_CONF_EN; + machine_menu.JerkConf = JERKCONF_EN; + machine_menu.StepsConf = STEPSCONF_EN; + machine_menu.TMCcurrentConf = TMC_CURRENT_EN; + machine_menu.TMCStepModeConf = TMC_STEP_MODE_EN; + machine_menu.MotorDirConf = MOTORDIRCONF_EN; + machine_menu.HomeFeedRateConf = HOMEFEEDRATECONF_EN; + machine_menu.PausePosition = PAUSE_POSITION_EN; + machine_menu.WifiSettings = WIFI_SETTINGS_EN; + machine_menu.HomingSensitivityConf = HOMING_SENSITIVITY_CONF_EN; + machine_menu.EncoderSettings = ENCODER_SETTINGS_EN; + + machine_menu.MaxFeedRateConfTitle = MAXFEEDRATE_CONF_TITLE_EN; + machine_menu.XMaxFeedRate = X_MAXFEEDRATE_EN; + machine_menu.YMaxFeedRate = Y_MAXFEEDRATE_EN; + machine_menu.ZMaxFeedRate = Z_MAXFEEDRATE_EN; + machine_menu.E0MaxFeedRate = E0_MAXFEEDRATE_EN; + machine_menu.E1MaxFeedRate = E1_MAXFEEDRATE_EN; + + machine_menu.AccelerationConfTitle = ACCELERATION_CONF_TITLE_EN; + machine_menu.PrintAcceleration = PRINT_ACCELERATION_EN; + machine_menu.RetractAcceleration = RETRACT_ACCELERATION_EN; + machine_menu.TravelAcceleration = TRAVEL_ACCELERATION_EN; + machine_menu.X_Acceleration = X_ACCELERATION_EN; + machine_menu.Y_Acceleration = Y_ACCELERATION_EN; + machine_menu.Z_Acceleration = Z_ACCELERATION_EN; + machine_menu.E0_Acceleration = E0_ACCELERATION_EN; + machine_menu.E1_Acceleration = E1_ACCELERATION_EN; + + machine_menu.JerkConfTitle = JERK_CONF_TITLE_EN; + machine_menu.X_Jerk = X_JERK_EN; + machine_menu.Y_Jerk = Y_JERK_EN; + machine_menu.Z_Jerk = Z_JERK_EN; + machine_menu.E_Jerk = E_JERK_EN; + + machine_menu.StepsConfTitle = STEPS_CONF_TITLE_EN; + machine_menu.X_Steps = X_STEPS_EN; + machine_menu.Y_Steps = Y_STEPS_EN; + machine_menu.Z_Steps = Z_STEPS_EN; + machine_menu.E0_Steps = E0_STEPS_EN; + machine_menu.E1_Steps = E1_STEPS_EN; + + machine_menu.TmcCurrentConfTitle = TMC_CURRENT_CONF_TITLE_EN; + machine_menu.X_Current = X_TMC_CURRENT_EN; + machine_menu.Y_Current = Y_TMC_CURRENT_EN; + machine_menu.Z_Current = Z_TMC_CURRENT_EN; + machine_menu.E0_Current = E0_TMC_CURRENT_EN; + machine_menu.E1_Current = E1_TMC_CURRENT_EN; + + machine_menu.TmcStepModeConfTitle = TMC_MODE_CONF_TITLE_EN; + machine_menu.X_StepMode = X_TMC_MODE_EN; + machine_menu.Y_StepMode = Y_TMC_MODE_EN; + machine_menu.Z_StepMode = Z_TMC_MODE_EN; + machine_menu.E0_StepMode = E0_TMC_MODE_EN; + machine_menu.E1_StepMode = E1_TMC_MODE_EN; + + machine_menu.MotorDirConfTitle = MOTORDIR_CONF_TITLE_EN; + machine_menu.X_MotorDir = X_MOTORDIR_EN; + machine_menu.Y_MotorDir = Y_MOTORDIR_EN; + machine_menu.Z_MotorDir = Z_MOTORDIR_EN; + machine_menu.E0_MotorDir = E0_MOTORDIR_EN; + machine_menu.E1_MotorDir = E1_MOTORDIR_EN; + machine_menu.Invert_0 = INVERT_P_EN; + machine_menu.Invert_1 = INVERT_N_EN; + + machine_menu.HomeFeedRateConfTitle = HOMEFEEDRATE_CONF_TITLE_EN; + machine_menu.XY_HomeFeedRate = X_HOMESPEED_EN; + // machine_menu.Y_HomeFeedRate=Y_HOMESPEED_EN; + machine_menu.Z_HomeFeedRate = Z_HOMESPEED_EN; + + machine_menu.AdvancedConfTitle = ADVANCED_CONF_TITLE_EN; + machine_menu.PwrOffDection = PWROFF_DECTION_EN; + machine_menu.PwrOffAfterPrint = PWROFF_AFTER_PRINT_EN; + machine_menu.HaveUps = HAVE_UPS_EN; + machine_menu.Z2andZ2Endstop = Z2_AND_Z2ENDSTOP_CONF_EN; + machine_menu.EnablePinsInvert = ENABLE_PINS_CONF_EN; + + machine_menu.Z2ConfTitle = Z2_AND_Z2ENDSTOP_CONF_TITLE_EN; + machine_menu.Z2Enable = Z2_ENABLE_EN; + machine_menu.Z2EndstopEnable = Z2_ENDSTOP_EN; + machine_menu.Z2Port = Z2_PORT_EN; + + machine_menu.EnablePinsInvertTitle = ENABLE_PINS_CONF_TITLE_EN; + machine_menu.XInvert = X_ENABLE_PINS_INVERT_EN; + machine_menu.YInvert = Y_ENABLE_PINS_INVERT_EN; + machine_menu.ZInvert = Z_ENABLE_PINS_INVERT_EN; + machine_menu.EInvert = E_ENABLE_PINS_INVERT_EN; + + machine_menu.key_back = KEY_BACK_EN; + machine_menu.key_reset = KEY_REST_EN; + machine_menu.key_confirm = KEY_CONFIRM_EN; + // + machine_menu.high_level = MOTOR_EN_HIGH_LEVEL_EN; + machine_menu.low_level = MOTOR_EN_LOW_LEVEL_EN; + + machine_menu.PausePosText = PAUSE_POSITION_EN; + machine_menu.xPos = PAUSE_POSITION_X_EN; + machine_menu.yPos = PAUSE_POSITION_Y_EN; + machine_menu.zPos = PAUSE_POSITION_Z_EN; + machine_menu.WifiConfTitle = WIFI_SETTINGS_TITLE_EN; + machine_menu.wifiMode = WIFI_SETTINGS_MODE_EN; + machine_menu.wifiName = WIFI_SETTINGS_NAME_EN; + machine_menu.wifiPassWord = WIFI_SETTINGS_PASSWORD_EN; + machine_menu.wifiCloud = WIFI_SETTINGS_CLOUD_EN; + machine_menu.wifiConfig = WIFI_SETTINGS_CONFIG_EN; + machine_menu.wifiEdit = WIFI_SETTINGS_EDIT_EN; + machine_menu.wifiConfigTips = WIFI_CONFIG_TIPS_EN; + + machine_menu.OffsetConfTitle = OFFSET_TITLE_EN; + machine_menu.Xoffset = OFFSET_X_EN; + machine_menu.Yoffset = OFFSET_Y_EN; + machine_menu.Zoffset = OFFSET_Z_EN; + + machine_menu.HomingSensitivityConfTitle = HOMING_SENSITIVITY_CONF_TITLE_EN; + machine_menu.X_Sensitivity = X_SENSITIVITY_EN; + machine_menu.Y_Sensitivity = Y_SENSITIVITY_EN; + machine_menu.Z_Sensitivity = Z_SENSITIVITY_EN; + machine_menu.Z2_Sensitivity = Z2_SENSITIVITY_EN; + + machine_menu.EncoderConfTitle = ENCODER_CONF_TITLE_EN; + machine_menu.EncoderConfText = ENCODER_CONF_TEXT_EN; + } +} + +void disp_language_init() { + preheat_menu.value_state = TEXT_VALUE; + preheat_menu.step_1c = TEXT_1C; + preheat_menu.step_5c = TEXT_5C; + preheat_menu.step_10c = TEXT_10C; + + move_menu.x_add = AXIS_X_ADD_TEXT; + move_menu.x_dec = AXIS_X_DEC_TEXT; + move_menu.y_add = AXIS_Y_ADD_TEXT; + move_menu.y_dec = AXIS_Y_DEC_TEXT; + move_menu.z_add = AXIS_Z_ADD_TEXT; + move_menu.z_dec = AXIS_Z_DEC_TEXT; + + move_menu.step_001mm = TEXT_001MM; + move_menu.step_005mm = TEXT_005MM; + move_menu.step_01mm = TEXT_01MM; + move_menu.step_1mm = TEXT_1MM; + move_menu.step_10mm = TEXT_10MM; + + home_menu.home_x = HOME_X_TEXT; + home_menu.home_y = HOME_Y_TEXT; + home_menu.home_z = HOME_Z_TEXT; + home_menu.home_all = HOME_ALL_TEXT; + + extrude_menu.temp_value = TEXT_VALUE_T; + extrude_menu.count_value_mm = TEXT_VALUE_mm; + extrude_menu.count_value_cm = TEXT_VALUE_cm; + extrude_menu.count_value_m = TEXT_VALUE_m; + extrude_menu.step_1mm = EXTRUDE_1MM_TEXT; + extrude_menu.step_5mm = EXTRUDE_5MM_TEXT; + extrude_menu.step_10mm = EXTRUDE_10MM_TEXT; + + fan_menu.full = FAN_OPEN_TEXT; + fan_menu.half = FAN_HALF_TEXT; + fan_menu.off = FAN_CLOSE_TEXT; + + speed_menu.step_1percent = STEP_1PERCENT; + speed_menu.step_5percent = STEP_5PERCENT; + speed_menu.step_10percent = STEP_10PERCENT; + + language_menu.chinese_s = LANGUAGE_S_CN; + language_menu.chinese_t = LANGUAGE_T_CN; + language_menu.english = LANGUAGE_EN; + language_menu.russian = LANGUAGE_RU; + language_menu.spanish = LANGUAGE_SP; + language_menu.german = LANGUAGE_GE; + language_menu.japan = LANGUAGE_JP; + language_menu.korean = LANGUAGE_KR; + language_menu.portuguese = LANGUAGE_PR; + language_menu.italy = LANGUAGE_IT; + language_menu.brazil = LANGUAGE_BR; + language_menu.french = LANGUAGE_FR; + + about_menu.type_name = ABOUT_TYPE_TEXT; + about_menu.firmware_v = ABOUT_VERSION_TEXT; + // about_menu.wifi = ABOUT_WIFI_TEXT; + + wifi_menu.ip = WIFI_IP_TEXT; + wifi_menu.wifi = WIFI_NAME_TEXT; + wifi_menu.key = WIFI_KEY_TEXT; + wifi_menu.state_ap = WIFI_STATE_AP_TEXT; + wifi_menu.state_sta = WIFI_STATE_STA_TEXT; + wifi_menu.connected = WIFI_CONNECTED_TEXT; + wifi_menu.disconnected = WIFI_DISCONNECTED_TEXT; + wifi_menu.exception = WIFI_EXCEPTION_TEXT; + + printing_menu.temp1 = TEXT_VALUE; + printing_menu.temp2 = TEXT_VALUE; + printing_menu.bed_temp = TEXT_VALUE; + + filament_menu.stat_temp = TEXT_VALUE; + + machine_menu.key_0 = KEYBOARD_KEY0_EN; + machine_menu.key_1 = KEYBOARD_KEY1_EN; + machine_menu.key_2 = KEYBOARD_KEY2_EN; + machine_menu.key_3 = KEYBOARD_KEY3_EN; + machine_menu.key_4 = KEYBOARD_KEY4_EN; + machine_menu.key_5 = KEYBOARD_KEY5_EN; + machine_menu.key_6 = KEYBOARD_KEY6_EN; + machine_menu.key_7 = KEYBOARD_KEY7_EN; + machine_menu.key_8 = KEYBOARD_KEY8_EN; + machine_menu.key_9 = KEYBOARD_KEY9_EN; + machine_menu.key_point = KEYBOARD_KEY_POINT_EN; + machine_menu.negative = KEYBOARD_KEY_NEGATIVE_EN; + // wifi-list + #if ENABLED(USE_WIFI_FUNCTION) + list_menu.title = TEXT_WIFI_MENU_TITLE_EN; + list_menu.file_pages = FILE_PAGES_EN; + + // tips + tips_menu.joining = TEXT_WIFI_JOINING_EN; + tips_menu.failedJoin = TEXT_WIFI_FAILED_JOIN_EN; + tips_menu.wifiConected = TEXT_WIFI_WIFI_CONECTED_EN; + #endif //USE_WIFI_FUNCTION + machine_setting_disp(); + + operation_menu.babystep = TEXT_BABY_STEP_EN; + + switch (gCfgItems.language) { + case LANG_SIMPLE_CHINESE: + common_menu.dialog_confirm_title = TITLE_DIALOG_CONFIRM_CN; + common_menu.text_back = BACK_TEXT_CN; + common_menu.close_machine_tips = DIALOG_CLOSE_MACHINE_CN; + common_menu.unbind_printer_tips = DIALOG_UNBIND_PRINTER_CN; + common_menu.print_special_title = PRINTING_GBK; + common_menu.pause_special_title = PRINTING_PAUSE_GBK; + common_menu.operate_special_title = PRINTING_OPERATION_GBK; + // + main_menu.title = TITLE_READYPRINT_CN; + main_menu.preheat = PREHEAT_TEXT_CN; + main_menu.move = MOVE_TEXT_CN; + main_menu.home = HOME_TEXT_CN; + main_menu.print = PRINT_TEXT_CN; + main_menu.extrude = EXTRUDE_TEXT_CN; + main_menu.leveling = LEVELING_TEXT_CN; + main_menu.autoleveling = AUTO_LEVELING_TEXT_CN; + main_menu.fan = FAN_TEXT_CN; + main_menu.set = SET_TEXT_CN; + main_menu.more = MORE_TEXT_CN; + main_menu.tool = TOOL_TEXT_CN; + // TOOL + tool_menu.title = TOOL_TEXT_CN; + tool_menu.preheat = TOOL_PREHEAT_CN; + tool_menu.extrude = TOOL_EXTRUDE_CN; + tool_menu.move = TOOL_MOVE_CN; + tool_menu.home = TOOL_HOME_CN; + tool_menu.leveling = TOOL_LEVELING_CN; + tool_menu.autoleveling = TOOL_AUTO_LEVELING_CN; + tool_menu.filament = TOOL_FILAMENT_CN; + tool_menu.more = TOOL_MORE_CN; + // + preheat_menu.adjust_title = TITLE_ADJUST_CN; + preheat_menu.title = TITLE_PREHEAT_CN; + preheat_menu.add = ADD_TEXT_CN; + preheat_menu.dec = DEC_TEXT_CN; + preheat_menu.ext1 = EXTRUDER_1_TEXT_CN; + preheat_menu.ext2 = EXTRUDER_2_TEXT_CN; + preheat_menu.hotbed = HEATBED_TEXT_CN; + preheat_menu.off = CLOSE_TEXT_CN; + + preheat_menu.value_state = TEXT_VALUE_CN; + preheat_menu.step_1c = TEXT_1C_CN; + preheat_menu.step_5c = TEXT_5C_CN; + preheat_menu.step_10c = TEXT_10C_CN; + // + move_menu.title = MOVE_TEXT_CN; + // + home_menu.title = TITLE_HOME_CN; + home_menu.stopmove = HOME_STOPMOVE_CN; + // + file_menu.title = TITLE_CHOOSEFILE_CN; + file_menu.page_up = PAGE_UP_TEXT_CN; + file_menu.page_down = PAGE_DOWN_TEXT_CN; + file_menu.file_loading = FILE_LOADING_CN; + file_menu.no_file = NO_FILE_CN; + file_menu.no_file_and_check = NO_FILE_CN;// NO_FILE_AND_CHECK_CN; + // + extrude_menu.title = TITLE_EXTRUDE_CN; + extrude_menu.in = EXTRUDER_IN_TEXT_CN; + extrude_menu.out = EXTRUDER_OUT_TEXT_CN; + extrude_menu.ext1 = EXTRUDER_1_TEXT_CN; + extrude_menu.ext2 = EXTRUDER_2_TEXT_CN; + extrude_menu.low = EXTRUDE_LOW_SPEED_TEXT_CN; + extrude_menu.normal = EXTRUDE_MEDIUM_SPEED_TEXT_CN; + extrude_menu.high = EXTRUDE_HIGH_SPEED_TEXT_CN; + extrude_menu.temper_text = EXTRUDER_TEMP_TEXT_CN; + extrude_menu.temp_value = EXTRUDE_TEXT_VALUE_T_CN; + // + leveling_menu.title = TITLE_LEVELING_CN; + leveling_menu.position1 = LEVELING_POINT1_TEXT_CN; + leveling_menu.position2 = LEVELING_POINT2_TEXT_CN; + leveling_menu.position3 = LEVELING_POINT3_TEXT_CN; + leveling_menu.position4 = LEVELING_POINT4_TEXT_CN; + leveling_menu.position5 = LEVELING_POINT5_TEXT_CN; + // + set_menu.title = TITLE_SET_CN; + set_menu.filesys = FILESYS_TEXT_CN; + set_menu.wifi = WIFI_TEXT_CN; + set_menu.about = ABOUT_TEXT_CN; + set_menu.fan = FAN_TEXT_CN; + set_menu.filament = FILAMENT_TEXT_CN; + set_menu.breakpoint = BREAK_POINT_TEXT_CN; + set_menu.motoroff = MOTOR_OFF_TEXT_CN; + set_menu.motoroffXY = MOTOR_OFF_XY_TEXT_CN; + set_menu.language = LANGUAGE_TEXT_CN; + set_menu.shutdown = SHUTDOWN_TEXT_CN; + set_menu.machine_para = MACHINE_PARA_CN; + set_menu.eepromSet = EEPROM_SETTINGS_CN; + // + filesys_menu.title = TITLE_FILESYS_CN; + filesys_menu.sd_sys = SD_CARD_TEXT_CN; + filesys_menu.usb_sys = U_DISK_TEXT_CN; + // + more_menu.title = TITLE_MORE_CN; + // WIFI + wifi_menu.title = WIFI_TEXT; + // wifi_menu.key = WIFI_KEY_TEXT_CN; + // wifi_menu.ip = WIFI_IP_TEXT_CN; + // wifi_menu.state = WIFI_STA_TEXT_CN; + wifi_menu.cloud = CLOUD_TEXT_CN; + wifi_menu.reconnect = WIFI_RECONNECT_TEXT_CN; + // CLOUD + cloud_menu.title = TITLE_CLOUD_TEXT_CN; + cloud_menu.bind = CLOUD_BINDED_CN; + cloud_menu.binded = CLOUD_BINDED_CN; + cloud_menu.unbind = CLOUD_UNBIND_CN; + cloud_menu.unbinding = CLOUD_UNBINDED_CN; + cloud_menu.disconnected = CLOUD_DISCONNECTED_CN; + cloud_menu.disable = CLOUD_DISABLE_CN; + // + about_menu.title = ABOUT_TEXT_CN; + about_menu.type = ABOUT_TYPE_TEXT_CN; + about_menu.version = ABOUT_VERSION_TEXT_CN; + about_menu.wifi = ABOUT_WIFI_TEXT_CN; + + // + fan_menu.title = FAN_TEXT_CN; + fan_menu.add = FAN_ADD_TEXT_CN; + fan_menu.dec = FAN_DEC_TEXT_CN; + fan_menu.state = FAN_TIPS1_TEXT_CN; + // + filament_menu.title = TITLE_FILAMENT_CN; + filament_menu.in = FILAMENT_IN_TEXT_CN; + filament_menu.out = FILAMENT_OUT_TEXT_CN; + filament_menu.ext1 = FILAMENT_EXT0_TEXT_CN; + filament_menu.ext2 = FILAMENT_EXT1_TEXT_CN; + filament_menu.ready_replace = FILAMENT_CHANGE_TEXT_CN; + filament_menu.filament_dialog_load_heat = FILAMENT_DIALOG_LOAD_HEAT_TIPS_CN; + filament_menu.filament_dialog_load_heat_confirm = FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_CN; + filament_menu.filament_dialog_loading = FILAMENT_DIALOG_LOADING_TIPS_CN; + filament_menu.filament_dialog_load_completed = FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_CN; + filament_menu.filament_dialog_unload_heat = FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_CN; + filament_menu.filament_dialog_unload_heat_confirm = FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_CN; + filament_menu.filament_dialog_unloading = FILAMENT_DIALOG_UNLOADING_TIPS_CN; + filament_menu.filament_dialog_unload_completed = FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_CN; + + + // + language_menu.title = TITLE_LANGUAGE_CN; + language_menu.next = PAGE_DOWN_TEXT_CN; + language_menu.up = PAGE_UP_TEXT_CN; + + // + printing_menu.title = TITLE_PRINTING_CN; + printing_menu.option = PRINTING_OPERATION_CN; + printing_menu.stop = PRINTING_STOP_CN; + printing_menu.pause = PRINTING_PAUSE_CN; + printing_menu.resume = PRINTING_RESUME_CN; + + // + operation_menu.title = TITLE_OPERATION_CN; + operation_menu.pause = PRINTING_PAUSE_CN; + operation_menu.stop = PRINTING_STOP_CN; + operation_menu.temp = PRINTING_TEMP_CN; + operation_menu.fan = FAN_TEXT_CN; + operation_menu.filament = FILAMENT_TEXT_CN; + operation_menu.extr = PRINTING_EXTRUDER_CN; + operation_menu.speed = PRINTING_CHANGESPEED_CN; + operation_menu.more = PRINTING_MORE_CN; + operation_menu.move = PRINTING_MOVE_CN; + operation_menu.auto_off = AUTO_SHUTDOWN_CN; + operation_menu.manual_off = MANUAL_SHUTDOWN_CN; + // + pause_menu.title = TITLE_PAUSE_CN; + pause_menu.resume = PRINTING_RESUME_CN; + pause_menu.stop = PRINTING_STOP_CN; + pause_menu.extrude = PRINTING_EXTRUDER_CN; + pause_menu.move = PRINTING_MOVE_CN; + pause_menu.filament = FILAMENT_TEXT_CN; + pause_menu.more = PRINTING_MORE_CN; + + // + speed_menu.title = PRINTING_CHANGESPEED_CN; + speed_menu.add = ADD_TEXT_CN; + speed_menu.dec = DEC_TEXT_CN; + speed_menu.move = MOVE_SPEED_CN; + speed_menu.extrude = EXTRUDER_SPEED_CN; + speed_menu.extrude_speed = EXTRUDER_SPEED_STATE_CN; + speed_menu.move_speed = MOVE_SPEED_STATE_CN; + // + printing_more_menu.title = TITLE_MORE_CN; + printing_more_menu.fan = FAN_TEXT_CN; + printing_more_menu.auto_close = AUTO_SHUTDOWN_CN; + printing_more_menu.manual = MANUAL_SHUTDOWN_CN; + printing_more_menu.speed = PRINTING_CHANGESPEED_CN; + printing_more_menu.temp = PRINTING_TEMP_CN; + + // print_file_dialog_menu.title = TITLE_DIALOG_CONFIRM_CN; + print_file_dialog_menu.confirm = DIALOG_CONFIRM_CN; + print_file_dialog_menu.cancle = DIALOG_CANCLE_CN; + print_file_dialog_menu.print_file = DIALOG_PRINT_MODEL_CN; + print_file_dialog_menu.cancle_print = DIALOG_CANCEL_PRINT_CN; + print_file_dialog_menu.retry = DIALOG_RETRY_CN; + print_file_dialog_menu.stop = DIALOG_STOP_CN; + print_file_dialog_menu.no_file_print_tips = DIALOG_ERROR_TIPS1_CN; + print_file_dialog_menu.print_from_breakpoint = DIALOG_REPRINT_FROM_BREAKPOINT_CN; + + print_file_dialog_menu.close_machine_error = DIALOG_ERROR_TIPS2_CN; + print_file_dialog_menu.filament_no_press = DIALOG_FILAMENT_NO_PRESS_CN; + + print_file_dialog_menu.print_finish = DIALOG_PRINT_FINISH_CN; + print_file_dialog_menu.print_time = DIALOG_PRINT_TIME_CN; + print_file_dialog_menu.reprint = DIALOG_REPRINT_CN; + print_file_dialog_menu.wifi_enable_tips = DIALOG_WIFI_ENABLE_TIPS_CN; + + pause_msg_menu.pausing = MESSAGE_PAUSING_CN; + pause_msg_menu.changing = MESSAGE_CHANGING_CN; + pause_msg_menu.unload = MESSAGE_UNLOAD_CN; + pause_msg_menu.waiting = MESSAGE_WAITING_CN; + pause_msg_menu.insert = MESSAGE_INSERT_CN; + pause_msg_menu.load = MESSAGE_LOAD_CN; + pause_msg_menu.purge = MESSAGE_PURGE_CN; + pause_msg_menu.resume = MESSAGE_RESUME_CN; + pause_msg_menu.heat = MESSAGE_HEAT_CN; + pause_msg_menu.heating = MESSAGE_HEATING_CN; + pause_msg_menu.option = MESSAGE_OPTION_CN; + pause_msg_menu.purgeMore = MESSAGE_PURGE_MORE_CN; + pause_msg_menu.continuePrint = MESSAGE_CONTINUE_PRINT_CN; + eeprom_menu.title = EEPROM_SETTINGS_TITLE_CN; + eeprom_menu.store = EEPROM_SETTINGS_STORE_CN; + eeprom_menu.read = EEPROM_SETTINGS_READ_CN; + eeprom_menu.revert = EEPROM_SETTINGS_REVERT_CN; + eeprom_menu.storeTips = EEPROM_STORE_TIPS_CN; + eeprom_menu.readTips = EEPROM_READ_TIPS_CN; + eeprom_menu.revertTips = EEPROM_REVERT_TIPS_CN; + break; + + #if 1 + #if 1 + + case LANG_COMPLEX_CHINESE: + common_menu.dialog_confirm_title = TITLE_DIALOG_CONFIRM_T_CN; + common_menu.text_back = BACK_TEXT_T_CN; + common_menu.close_machine_tips = DIALOG_CLOSE_MACHINE_T_CN; + common_menu.unbind_printer_tips = DIALOG_UNBIND_PRINTER_T_CN; + common_menu.print_special_title = PRINTING_GBK; + common_menu.pause_special_title = PRINTING_PAUSE_GBK; + common_menu.operate_special_title = PRINTING_OPERATION_GBK; + // + main_menu.title = TITLE_READYPRINT_T_CN; + main_menu.preheat = PREHEAT_TEXT_T_CN; + main_menu.move = MOVE_TEXT_T_CN; + main_menu.home = HOME_TEXT_T_CN; + main_menu.print = PRINT_TEXT_T_CN; + main_menu.extrude = EXTRUDE_TEXT_T_CN; + main_menu.leveling = LEVELING_TEXT_T_CN; + main_menu.autoleveling = AUTO_LEVELING_TEXT_T_CN; + main_menu.fan = FAN_TEXT_T_CN; + main_menu.set = SET_TEXT_T_CN; + main_menu.more = MORE_TEXT_T_CN; + main_menu.tool = TOOL_TEXT_T_CN; + // TOOL + tool_menu.title = TOOL_TEXT_T_CN; + tool_menu.preheat = TOOL_PREHEAT_T_CN; + tool_menu.extrude = TOOL_EXTRUDE_T_CN; + tool_menu.move = TOOL_MOVE_T_CN; + tool_menu.home = TOOL_HOME_T_CN; + tool_menu.leveling = TOOL_LEVELING_T_CN; + tool_menu.autoleveling = TOOL_AUTO_LEVELING_T_CN; + tool_menu.filament = TOOL_FILAMENT_T_CN; + tool_menu.more = TOOL_MORE_T_CN; + // + preheat_menu.adjust_title = TITLE_ADJUST_T_CN; + preheat_menu.title = TITLE_PREHEAT_T_CN; + preheat_menu.add = ADD_TEXT_T_CN; + preheat_menu.dec = DEC_TEXT_T_CN; + preheat_menu.ext1 = EXTRUDER_1_TEXT_T_CN; + preheat_menu.ext2 = EXTRUDER_2_TEXT_T_CN; + preheat_menu.hotbed = HEATBED_TEXT_T_CN; + preheat_menu.off = CLOSE_TEXT_T_CN; + preheat_menu.value_state = TEXT_VALUE_T_CN; + preheat_menu.step_1c = TEXT_1C_T_CN; + preheat_menu.step_5c = TEXT_5C_T_CN; + preheat_menu.step_10c = TEXT_10C_T_CN; + // + move_menu.title = MOVE_TEXT_T_CN; + // + home_menu.title = TITLE_HOME_T_CN; + home_menu.stopmove = HOME_STOPMOVE_T_CN; + // + file_menu.title = TITLE_CHOOSEFILE_T_CN; + file_menu.page_up = PAGE_UP_TEXT_T_CN; + file_menu.page_down = PAGE_DOWN_TEXT_T_CN; + file_menu.file_loading = FILE_LOADING_T_CN; + file_menu.no_file = NO_FILE_T_CN; + file_menu.no_file_and_check = NO_FILE_T_CN;// NO_FILE_AND_CHECK_T_CN; + // + extrude_menu.title = TITLE_EXTRUDE_T_CN; + extrude_menu.in = EXTRUDER_IN_TEXT_T_CN; + extrude_menu.out = EXTRUDER_OUT_TEXT_T_CN; + extrude_menu.ext1 = EXTRUDER_1_TEXT_T_CN; + extrude_menu.ext2 = EXTRUDER_2_TEXT_T_CN; + extrude_menu.low = EXTRUDE_LOW_SPEED_TEXT_T_CN; + extrude_menu.normal = EXTRUDE_MEDIUM_SPEED_TEXT_T_CN; + extrude_menu.high = EXTRUDE_HIGH_SPEED_TEXT_T_CN; + extrude_menu.temper_text = EXTRUDER_TEMP_TEXT_T_CN; + extrude_menu.temp_value = EXTRUDE_TEXT_VALUE_T_T_CN; + // + leveling_menu.title = TITLE_LEVELING_CN; + leveling_menu.position1 = LEVELING_POINT1_TEXT_T_CN; + leveling_menu.position2 = LEVELING_POINT2_TEXT_T_CN; + leveling_menu.position3 = LEVELING_POINT3_TEXT_T_CN; + leveling_menu.position4 = LEVELING_POINT4_TEXT_T_CN; + leveling_menu.position5 = LEVELING_POINT5_TEXT_T_CN; + // + set_menu.title = TITLE_SET_T_CN; + set_menu.filesys = FILESYS_TEXT_T_CN; + set_menu.wifi = WIFI_TEXT_T_CN; + set_menu.about = ABOUT_TEXT_T_CN; + set_menu.fan = FAN_TEXT_T_CN; + set_menu.filament = FILAMENT_TEXT_T_CN; + set_menu.breakpoint = BREAK_POINT_TEXT_T_CN; + set_menu.motoroff = MOTOR_OFF_TEXT_T_CN; + set_menu.motoroffXY = MOTOR_OFF_XY_TEXT_T_CN; + set_menu.language = LANGUAGE_TEXT_T_CN; + set_menu.shutdown = SHUTDOWN_TEXT_T_CN; + set_menu.machine_para = MACHINE_PARA_T_CN; + set_menu.eepromSet = EEPROM_SETTINGS_T_CN; + filesys_menu.title = TITLE_FILESYS_T_CN; + filesys_menu.sd_sys = SD_CARD_TEXT_T_CN; + filesys_menu.usb_sys = U_DISK_TEXT_T_CN; + // + more_menu.title = TITLE_MORE_T_CN; + // WIFI + wifi_menu.title = WIFI_TEXT; + // wifi_menu.key = WIFI_KEY_TEXT_CN; + // wifi_menu.ip = WIFI_IP_TEXT_CN; + // wifi_menu.state= WIFI_STA_TEXT_CN; + wifi_menu.cloud = CLOUD_TEXT_T_CN; + wifi_menu.reconnect = WIFI_RECONNECT_TEXT_T_CN; + // CLOUD + cloud_menu.title = TITLE_CLOUD_TEXT_T_CN; + cloud_menu.bind = CLOUD_BINDED_T_CN; + cloud_menu.binded = CLOUD_BINDED_T_CN; + cloud_menu.unbind = CLOUD_UNBIND_T_CN; + cloud_menu.unbinding = CLOUD_UNBINDED_T_CN; + cloud_menu.disconnected = CLOUD_DISCONNECTED_T_CN; + cloud_menu.disable = CLOUD_DISABLE_T_CN; + // + about_menu.title = ABOUT_TEXT_T_CN; + about_menu.type = ABOUT_TYPE_TEXT_T_CN; + about_menu.version = ABOUT_VERSION_TEXT_T_CN; + about_menu.wifi = ABOUT_WIFI_TEXT_T_CN; + + // + fan_menu.title = FAN_TEXT_T_CN; + fan_menu.add = FAN_ADD_TEXT_T_CN; + fan_menu.dec = FAN_DEC_TEXT_T_CN; + fan_menu.state = FAN_TIPS1_TEXT_T_CN; + // + filament_menu.title = TITLE_FILAMENT_T_CN; + filament_menu.in = FILAMENT_IN_TEXT_T_CN; + filament_menu.out = FILAMENT_OUT_TEXT_T_CN; + filament_menu.ext1 = FILAMENT_EXT0_TEXT_T_CN; + filament_menu.ext2 = FILAMENT_EXT1_TEXT_T_CN; + filament_menu.ready_replace = FILAMENT_CHANGE_TEXT_T_CN; + filament_menu.filament_dialog_load_heat = FILAMENT_DIALOG_LOAD_HEAT_TIPS_T_CN; + filament_menu.filament_dialog_load_heat_confirm = FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_T_CN; + filament_menu.filament_dialog_loading = FILAMENT_DIALOG_LOADING_TIPS_T_CN; + filament_menu.filament_dialog_load_completed = FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_T_CN; + filament_menu.filament_dialog_unload_heat = FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_T_CN; + filament_menu.filament_dialog_unload_heat_confirm = FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_T_CN; + filament_menu.filament_dialog_unloading = FILAMENT_DIALOG_UNLOADING_TIPS_T_CN; + filament_menu.filament_dialog_unload_completed = FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_T_CN; + + + // + language_menu.title = TITLE_LANGUAGE_T_CN; + language_menu.next = PAGE_DOWN_TEXT_T_CN; + language_menu.up = PAGE_UP_TEXT_T_CN; + + // + printing_menu.title = TITLE_PRINTING_T_CN; + printing_menu.option = PRINTING_OPERATION_T_CN; + printing_menu.stop = PRINTING_STOP_T_CN; + printing_menu.pause = PRINTING_PAUSE_T_CN; + printing_menu.resume = PRINTING_RESUME_T_CN; + + // + operation_menu.title = TITLE_OPERATION_T_CN; + operation_menu.pause = PRINTING_PAUSE_T_CN; + operation_menu.stop = PRINTING_STOP_T_CN; + operation_menu.temp = PRINTING_TEMP_T_CN; + operation_menu.fan = FAN_TEXT_T_CN; + operation_menu.extr = PRINTING_EXTRUDER_T_CN; + operation_menu.speed = PRINTING_CHANGESPEED_T_CN; + operation_menu.filament = FILAMENT_TEXT_T_CN; + operation_menu.more = PRINTING_MORE_T_CN; + operation_menu.move = PRINTING_MOVE_T_CN; + operation_menu.auto_off = AUTO_SHUTDOWN_T_CN; + operation_menu.manual_off = MANUAL_SHUTDOWN_T_CN; + // + pause_menu.title = TITLE_PAUSE_T_CN; + pause_menu.resume = PRINTING_RESUME_T_CN; + pause_menu.stop = PRINTING_STOP_T_CN; + pause_menu.extrude = PRINTING_EXTRUDER_T_CN; + pause_menu.move = PRINTING_MOVE_T_CN; + pause_menu.filament = FILAMENT_TEXT_T_CN; + pause_menu.more = PRINTING_MORE_T_CN; + + // + speed_menu.title = PRINTING_CHANGESPEED_T_CN; + speed_menu.add = ADD_TEXT_T_CN; + speed_menu.dec = DEC_TEXT_T_CN; + speed_menu.move = MOVE_SPEED_T_CN; + speed_menu.extrude = EXTRUDER_SPEED_T_CN; + speed_menu.extrude_speed = EXTRUDER_SPEED_STATE_T_CN; + speed_menu.move_speed = MOVE_SPEED_STATE_T_CN; + // + printing_more_menu.title = TITLE_MORE_T_CN; + printing_more_menu.fan = FAN_TEXT_T_CN; + printing_more_menu.auto_close = AUTO_SHUTDOWN_T_CN; + printing_more_menu.manual = MANUAL_SHUTDOWN_T_CN; + printing_more_menu.speed = PRINTING_CHANGESPEED_T_CN; + printing_more_menu.temp = PRINTING_TEMP_T_CN; + + // print_file_dialog_menu.title = TITLE_DIALOG_CONFIRM_CN; + print_file_dialog_menu.confirm = DIALOG_CONFIRM_T_CN; + print_file_dialog_menu.cancle = DIALOG_CANCLE_T_CN; + print_file_dialog_menu.print_file = DIALOG_PRINT_MODEL_T_CN; + print_file_dialog_menu.cancle_print = DIALOG_CANCEL_PRINT_T_CN; + print_file_dialog_menu.retry = DIALOG_RETRY_T_CN; + print_file_dialog_menu.stop = DIALOG_STOP_T_CN; + print_file_dialog_menu.no_file_print_tips = DIALOG_ERROR_TIPS1_T_CN; + print_file_dialog_menu.print_from_breakpoint = DIALOG_REPRINT_FROM_BREAKPOINT_T_CN; + + print_file_dialog_menu.close_machine_error = DIALOG_ERROR_TIPS2_T_CN; + print_file_dialog_menu.filament_no_press = DIALOG_FILAMENT_NO_PRESS_T_CN; + print_file_dialog_menu.print_finish = DIALOG_PRINT_FINISH_T_CN; + print_file_dialog_menu.print_time = DIALOG_PRINT_TIME_T_CN; + print_file_dialog_menu.reprint = DIALOG_REPRINT_T_CN; + print_file_dialog_menu.wifi_enable_tips = DIALOG_WIFI_ENABLE_TIPS_T_CN; + + pause_msg_menu.pausing = MESSAGE_PAUSING_T_CN; + pause_msg_menu.changing = MESSAGE_CHANGING_T_CN; + pause_msg_menu.unload = MESSAGE_UNLOAD_T_CN; + pause_msg_menu.waiting = MESSAGE_WAITING_T_CN; + pause_msg_menu.insert = MESSAGE_INSERT_T_CN; + pause_msg_menu.load = MESSAGE_LOAD_T_CN; + pause_msg_menu.purge = MESSAGE_PURGE_T_CN; + pause_msg_menu.resume = MESSAGE_RESUME_T_CN; + pause_msg_menu.heat = MESSAGE_HEAT_T_CN; + pause_msg_menu.heating = MESSAGE_HEATING_T_CN; + pause_msg_menu.option = MESSAGE_OPTION_T_CN; + pause_msg_menu.purgeMore = MESSAGE_PURGE_MORE_T_CN; + pause_msg_menu.continuePrint = MESSAGE_CONTINUE_PRINT_T_CN; + eeprom_menu.title = EEPROM_SETTINGS_TITLE_T_CN; + eeprom_menu.store = EEPROM_SETTINGS_STORE_T_CN; + eeprom_menu.read = EEPROM_SETTINGS_READ_T_CN; + eeprom_menu.revert = EEPROM_SETTINGS_REVERT_T_CN; + eeprom_menu.storeTips = EEPROM_STORE_TIPS_T_CN; + eeprom_menu.readTips = EEPROM_READ_TIPS_T_CN; + eeprom_menu.revertTips = EEPROM_REVERT_TIPS_T_CN; + break; + case LANG_ENGLISH: + common_menu.dialog_confirm_title = TITLE_DIALOG_CONFIRM_EN; + common_menu.text_back = BACK_TEXT_EN; + common_menu.close_machine_tips = DIALOG_CLOSE_MACHINE_EN; + common_menu.unbind_printer_tips = DIALOG_UNBIND_PRINTER_EN; + common_menu.print_special_title = PRINTING_OTHER_LANGUGE; + common_menu.pause_special_title = PRINTING_PAUSE_OTHER_LANGUGE; + common_menu.operate_special_title = PRINTING_OPERATION_OTHER_LANGUGE; + // + main_menu.title = TITLE_READYPRINT_EN; + main_menu.preheat = PREHEAT_TEXT_EN; + main_menu.move = MOVE_TEXT_EN; + main_menu.home = HOME_TEXT_EN; + main_menu.print = PRINT_TEXT_EN; + main_menu.extrude = EXTRUDE_TEXT_EN; + main_menu.leveling = LEVELING_TEXT_EN; + main_menu.autoleveling = AUTO_LEVELING_TEXT_EN; + main_menu.fan = FAN_TEXT_EN; + main_menu.set = SET_TEXT_EN; + main_menu.more = MORE_TEXT_EN; + main_menu.tool = TOOL_TEXT_EN; + // TOOL + tool_menu.title = TOOL_TEXT_EN; + tool_menu.preheat = TOOL_PREHEAT_EN; + tool_menu.extrude = TOOL_EXTRUDE_EN; + tool_menu.move = TOOL_MOVE_EN; + tool_menu.home = TOOL_HOME_EN; + tool_menu.leveling = TOOL_LEVELING_EN; + tool_menu.autoleveling = TOOL_AUTO_LEVELING_EN; + tool_menu.filament = TOOL_FILAMENT_EN; + tool_menu.more = TOOL_MORE_EN; + // + preheat_menu.adjust_title = TITLE_ADJUST_EN; + preheat_menu.title = TITLE_PREHEAT_EN; + preheat_menu.add = ADD_TEXT_EN; + preheat_menu.dec = DEC_TEXT_EN; + preheat_menu.ext1 = EXTRUDER_1_TEXT_EN; + preheat_menu.ext2 = EXTRUDER_2_TEXT_EN; + preheat_menu.hotbed = HEATBED_TEXT_EN; + preheat_menu.off = CLOSE_TEXT_EN; + // + move_menu.title = TITLE_MOVE_EN; + // + home_menu.title = TITLE_HOME_EN; + home_menu.stopmove = HOME_STOPMOVE_EN; + // + file_menu.title = TITLE_CHOOSEFILE_EN; + file_menu.page_up = PAGE_UP_TEXT_EN; + file_menu.page_down = PAGE_DOWN_TEXT_EN; + file_menu.file_loading = FILE_LOADING_EN; + file_menu.no_file = NO_FILE_EN; + file_menu.no_file_and_check = NO_FILE_EN;// NO_FILE_AND_CHECK_EN; + // + extrude_menu.title = TITLE_EXTRUDE_EN; + extrude_menu.in = EXTRUDER_IN_TEXT_EN; + extrude_menu.out = EXTRUDER_OUT_TEXT_EN; + extrude_menu.ext1 = EXTRUDER_1_TEXT_EN; + extrude_menu.ext2 = EXTRUDER_2_TEXT_EN; + extrude_menu.low = EXTRUDE_LOW_SPEED_TEXT_EN; + extrude_menu.normal = EXTRUDE_MEDIUM_SPEED_TEXT_EN; + extrude_menu.high = EXTRUDE_HIGH_SPEED_TEXT_EN; + extrude_menu.temper_text = EXTRUDER_TEMP_TEXT_EN; + // + leveling_menu.title = TITLE_LEVELING_EN; + leveling_menu.position1 = LEVELING_POINT1_TEXT_EN; + leveling_menu.position2 = LEVELING_POINT2_TEXT_EN; + leveling_menu.position3 = LEVELING_POINT3_TEXT_EN; + leveling_menu.position4 = LEVELING_POINT4_TEXT_EN; + leveling_menu.position5 = LEVELING_POINT5_TEXT_EN; + // + set_menu.title = TITLE_SET_EN; + set_menu.filesys = FILESYS_TEXT_EN; + set_menu.wifi = WIFI_TEXT_EN; + set_menu.about = ABOUT_TEXT_EN; + set_menu.fan = FAN_TEXT_EN; + set_menu.filament = FILAMENT_TEXT_EN; + set_menu.breakpoint = BREAK_POINT_TEXT_EN; + set_menu.motoroff = MOTOR_OFF_TEXT_EN; + set_menu.motoroffXY = MOTOR_OFF_XY_TEXT_EN; + set_menu.language = LANGUAGE_TEXT_EN; + set_menu.shutdown = SHUTDOWN_TEXT_EN; + set_menu.machine_para = MACHINE_PARA_EN; + set_menu.eepromSet = EEPROM_SETTINGS_EN; + more_menu.title = TITLE_MORE_EN; + // + filesys_menu.title = TITLE_FILESYS_EN; + filesys_menu.sd_sys = SD_CARD_TEXT_EN; + filesys_menu.usb_sys = U_DISK_TEXT_EN; + // WIFI + wifi_menu.title = WIFI_TEXT; + // wifi_menu.key = WIFI_KEY_TEXT_EN; + // wifi_menu.ip = WIFI_IP_TEXT_EN; + // wifi_menu.state = WIFI_STA_TEXT_EN; + wifi_menu.cloud = CLOUD_TEXT_EN; + wifi_menu.reconnect = WIFI_RECONNECT_TEXT_EN; + + cloud_menu.title = TITLE_CLOUD_TEXT_EN; + cloud_menu.bind = CLOUD_BINDED_EN; + cloud_menu.binded = CLOUD_BINDED_EN; + cloud_menu.unbind = CLOUD_UNBIND_EN; + cloud_menu.unbinding = CLOUD_UNBINDED_EN; + cloud_menu.disconnected = CLOUD_DISCONNECTED_EN; + cloud_menu.disable = CLOUD_DISABLE_EN; + // + about_menu.title = TITLE_ABOUT_EN; + about_menu.type = ABOUT_TYPE_TEXT_EN; + about_menu.version = ABOUT_VERSION_TEXT_EN; + about_menu.wifi = ABOUT_WIFI_TEXT_EN; + // + fan_menu.title = TITLE_FAN_EN; + fan_menu.add = FAN_ADD_TEXT_EN; + fan_menu.dec = FAN_DEC_TEXT_EN; + fan_menu.state = FAN_TIPS1_TEXT_EN; + // + filament_menu.title = TITLE_FILAMENT_EN; + filament_menu.in = FILAMENT_IN_TEXT_EN; + filament_menu.out = FILAMENT_OUT_TEXT_EN; + filament_menu.ext1 = FILAMENT_EXT0_TEXT_EN; + filament_menu.ext2 = FILAMENT_EXT1_TEXT_EN; + filament_menu.ready_replace = FILAMENT_CHANGE_TEXT_EN; + filament_menu.filament_dialog_load_heat = FILAMENT_DIALOG_LOAD_HEAT_TIPS_EN; + filament_menu.filament_dialog_load_heat_confirm = FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_EN; + filament_menu.filament_dialog_loading = FILAMENT_DIALOG_LOADING_TIPS_EN; + filament_menu.filament_dialog_load_completed = FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_EN; + filament_menu.filament_dialog_unload_heat = FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_EN; + filament_menu.filament_dialog_unload_heat_confirm = FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_EN; + filament_menu.filament_dialog_unloading = FILAMENT_DIALOG_UNLOADING_TIPS_EN; + filament_menu.filament_dialog_unload_completed = FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_EN; + + // + language_menu.title = TITLE_LANGUAGE_EN; + language_menu.next = PAGE_DOWN_TEXT_EN; + language_menu.up = PAGE_UP_TEXT_EN; + // + printing_menu.title = TITLE_PRINTING_EN; + printing_menu.option = PRINTING_OPERATION_EN; + printing_menu.stop = PRINTING_STOP_EN; + printing_menu.pause = PRINTING_PAUSE_EN; + printing_menu.resume = PRINTING_RESUME_EN; + + // + operation_menu.title = TITLE_OPERATION_EN; + operation_menu.pause = PRINTING_PAUSE_EN; + operation_menu.stop = PRINTING_STOP_EN; + operation_menu.temp = PRINTING_TEMP_EN; + operation_menu.fan = FAN_TEXT_EN; + operation_menu.extr = PRINTING_EXTRUDER_EN; + operation_menu.speed = PRINTING_CHANGESPEED_EN; + operation_menu.filament = FILAMENT_TEXT_EN; + operation_menu.more = PRINTING_MORE_EN; + operation_menu.move = PRINTING_MOVE_EN; + operation_menu.auto_off = AUTO_SHUTDOWN_EN; + operation_menu.manual_off = MANUAL_SHUTDOWN_EN; + // + pause_menu.title = TITLE_PAUSE_EN; + pause_menu.resume = PRINTING_RESUME_EN; + pause_menu.stop = PRINTING_STOP_EN; + pause_menu.extrude = PRINTING_EXTRUDER_EN; + pause_menu.move = PRINTING_MOVE_EN; + pause_menu.filament = FILAMENT_TEXT_EN; + pause_menu.more = PRINTING_MORE_EN; + + // + speed_menu.title = TITLE_CHANGESPEED_EN; + speed_menu.add = ADD_TEXT_EN; + speed_menu.dec = DEC_TEXT_EN; + speed_menu.move = MOVE_SPEED_EN; + speed_menu.extrude = EXTRUDER_SPEED_EN; + speed_menu.extrude_speed = EXTRUDER_SPEED_STATE_EN; + speed_menu.move_speed = MOVE_SPEED_STATE_EN; + // + printing_more_menu.title = TITLE_MORE_EN; + printing_more_menu.fan = FAN_TEXT_EN; + printing_more_menu.auto_close = AUTO_SHUTDOWN_EN; + printing_more_menu.manual = MANUAL_SHUTDOWN_EN; + printing_more_menu.speed = PRINTING_CHANGESPEED_EN; + printing_more_menu.temp = PRINTING_TEMP_EN; + + // print_file_dialog_menu.title = TITLE_DIALOG_CONFIRM_EN; + print_file_dialog_menu.confirm = DIALOG_CONFIRM_EN; + print_file_dialog_menu.cancle = DIALOG_CANCLE_EN; + print_file_dialog_menu.print_file = DIALOG_PRINT_MODEL_EN; + print_file_dialog_menu.cancle_print = DIALOG_CANCEL_PRINT_EN; + print_file_dialog_menu.retry = DIALOG_RETRY_EN; + print_file_dialog_menu.stop = DIALOG_STOP_EN; + print_file_dialog_menu.no_file_print_tips = DIALOG_ERROR_TIPS1_EN; + print_file_dialog_menu.print_from_breakpoint = DIALOG_REPRINT_FROM_BREAKPOINT_EN; + print_file_dialog_menu.close_machine_error = DIALOG_ERROR_TIPS2_EN; + print_file_dialog_menu.filament_no_press = DIALOG_FILAMENT_NO_PRESS_EN; + print_file_dialog_menu.print_finish = DIALOG_PRINT_FINISH_EN; + print_file_dialog_menu.print_time = DIALOG_PRINT_TIME_EN; + print_file_dialog_menu.reprint = DIALOG_REPRINT_EN; + print_file_dialog_menu.wifi_enable_tips = DIALOG_WIFI_ENABLE_TIPS_EN; + + pause_msg_menu.pausing = MESSAGE_PAUSING_EN; + pause_msg_menu.changing = MESSAGE_CHANGING_EN; + pause_msg_menu.unload = MESSAGE_UNLOAD_EN; + pause_msg_menu.waiting = MESSAGE_WAITING_EN; + pause_msg_menu.insert = MESSAGE_INSERT_EN; + pause_msg_menu.load = MESSAGE_LOAD_EN; + pause_msg_menu.purge = MESSAGE_PURGE_EN; + pause_msg_menu.resume = MESSAGE_RESUME_EN; + pause_msg_menu.heat = MESSAGE_HEAT_EN; + pause_msg_menu.heating = MESSAGE_HEATING_EN; + pause_msg_menu.option = MESSAGE_OPTION_EN; + pause_msg_menu.purgeMore = MESSAGE_PURGE_MORE_EN; + pause_msg_menu.continuePrint = MESSAGE_CONTINUE_PRINT_EN; + eeprom_menu.title = EEPROM_SETTINGS_TITLE_EN; + eeprom_menu.store = EEPROM_SETTINGS_STORE_EN; + eeprom_menu.read = EEPROM_SETTINGS_READ_EN; + eeprom_menu.revert = EEPROM_SETTINGS_REVERT_EN; + eeprom_menu.storeTips = EEPROM_STORE_TIPS_EN; + eeprom_menu.readTips = EEPROM_READ_TIPS_EN; + eeprom_menu.revertTips = EEPROM_REVERT_TIPS_EN; + break; + case LANG_RUSSIAN: + common_menu.dialog_confirm_title = TITLE_DIALOG_CONFIRM_RU; + common_menu.text_back = BACK_TEXT_RU; + common_menu.close_machine_tips = DIALOG_CLOSE_MACHINE_RU; + common_menu.unbind_printer_tips = DIALOG_UNBIND_PRINTER_RU; + common_menu.print_special_title = PRINTING_OTHER_LANGUGE; + common_menu.pause_special_title = PRINTING_PAUSE_OTHER_LANGUGE; + common_menu.operate_special_title = PRINTING_OPERATION_OTHER_LANGUGE; + // + main_menu.title = TITLE_READYPRINT_RU; + main_menu.preheat = PREHEAT_TEXT_RU; + main_menu.move = MOVE_TEXT_RU; + main_menu.home = HOME_TEXT_RU; + main_menu.print = PRINT_TEXT_RU; + main_menu.extrude = EXTRUDE_TEXT_RU; + main_menu.leveling = LEVELING_TEXT_RU; + main_menu.autoleveling = AUTO_LEVELING_TEXT_RU; + main_menu.fan = FAN_TEXT_RU; + main_menu.set = SET_TEXT_RU; + main_menu.more = MORE_TEXT_RU; + main_menu.tool = TOOL_TEXT_RU; + // TOOL + tool_menu.title = TOOL_TEXT_RU; + tool_menu.preheat = TOOL_PREHEAT_RU; + tool_menu.extrude = TOOL_EXTRUDE_RU; + tool_menu.move = TOOL_MOVE_RU; + tool_menu.home = TOOL_HOME_RU; + tool_menu.leveling = TOOL_LEVELING_RU; + tool_menu.autoleveling = TOOL_AUTO_LEVELING_RU; + tool_menu.filament = TOOL_FILAMENT_RU; + tool_menu.more = TOOL_MORE_RU; + // + preheat_menu.adjust_title = TITLE_ADJUST_RU; + preheat_menu.title = TITLE_PREHEAT_RU; + preheat_menu.add = ADD_TEXT_RU; + preheat_menu.dec = DEC_TEXT_RU; + preheat_menu.ext1 = EXTRUDER_1_TEXT_RU; + preheat_menu.ext2 = EXTRUDER_2_TEXT_RU; + preheat_menu.hotbed = HEATBED_TEXT_RU; + preheat_menu.off = CLOSE_TEXT_RU; + // + move_menu.title = MOVE_TEXT_RU; + // + home_menu.title = TITLE_HOME_RU; + home_menu.stopmove = HOME_STOPMOVE_RU; + // + file_menu.title = TITLE_CHOOSEFILE_RU; + file_menu.page_up = PAGE_UP_TEXT_RU; + file_menu.page_down = PAGE_DOWN_TEXT_RU; + file_menu.file_loading = FILE_LOADING_RU; + file_menu.no_file = NO_FILE_RU; + file_menu.no_file_and_check = NO_FILE_RU;// NO_FILE_AND_CHECK_RU; + // + extrude_menu.title = TITLE_EXTRUDE_RU; + extrude_menu.in = EXTRUDER_IN_TEXT_RU; + extrude_menu.out = EXTRUDER_OUT_TEXT_RU; + extrude_menu.ext1 = EXTRUDER_1_TEXT_RU; + extrude_menu.ext2 = EXTRUDER_2_TEXT_RU; + extrude_menu.low = EXTRUDE_LOW_SPEED_TEXT_RU; + extrude_menu.normal = EXTRUDE_MEDIUM_SPEED_TEXT_RU; + extrude_menu.high = EXTRUDE_HIGH_SPEED_TEXT_RU; + extrude_menu.temper_text = EXTRUDER_TEMP_TEXT_RU; + // + leveling_menu.title = TITLE_LEVELING_RU; + leveling_menu.position1 = LEVELING_POINT1_TEXT_RU; + leveling_menu.position2 = LEVELING_POINT2_TEXT_RU; + leveling_menu.position3 = LEVELING_POINT3_TEXT_RU; + leveling_menu.position4 = LEVELING_POINT4_TEXT_RU; + leveling_menu.position5 = LEVELING_POINT5_TEXT_RU; + // + set_menu.title = TITLE_SET_RU; + set_menu.filesys = FILESYS_TEXT_RU; + set_menu.wifi = WIFI_TEXT_RU; + set_menu.about = ABOUT_TEXT_RU; + set_menu.fan = FAN_TEXT_RU; + set_menu.filament = FILAMENT_TEXT_RU; + set_menu.breakpoint = BREAK_POINT_TEXT_RU; + set_menu.motoroff = MOTOR_OFF_TEXT_RU; + set_menu.motoroffXY = MOTOR_OFF_XY_TEXT_RU; + set_menu.language = LANGUAGE_TEXT_RU; + set_menu.shutdown = SHUTDOWN_TEXT_RU; + set_menu.machine_para = MACHINE_PARA_RU; + set_menu.eepromSet = EEPROM_SETTINGS_RU; + more_menu.title = TITLE_MORE_RU; + // + filesys_menu.title = TITLE_FILESYS_RU; + filesys_menu.sd_sys = SD_CARD_TEXT_RU; + filesys_menu.usb_sys = U_DISK_TEXT_RU; + // WIFI + wifi_menu.title = WIFI_TEXT; + // wifi_menu.key = WIFI_KEY_TEXT_RU; + // wifi_menu.ip = WIFI_IP_TEXT_RU; + // wifi_menu.state = WIFI_STA_TEXT_RU; + wifi_menu.cloud = CLOUD_TEXT_RU; + wifi_menu.reconnect = WIFI_RECONNECT_TEXT_RU; + + + cloud_menu.title = TITLE_CLOUD_TEXT_RU; + cloud_menu.bind = CLOUD_BINDED_RU; + cloud_menu.binded = CLOUD_BINDED_RU; + cloud_menu.unbind = CLOUD_UNBIND_RU; + cloud_menu.unbinding = CLOUD_UNBINDED_RU; + cloud_menu.disconnected = CLOUD_DISCONNECTED_RU; + cloud_menu.disable = CLOUD_DISABLE_RU; + // + about_menu.title = ABOUT_TEXT_RU; + about_menu.type = ABOUT_TYPE_TEXT_RU; + about_menu.version = ABOUT_VERSION_TEXT_RU; + about_menu.wifi = ABOUT_WIFI_TEXT_RU; + // + fan_menu.title = FAN_TEXT_RU; + fan_menu.add = FAN_ADD_TEXT_RU; + fan_menu.dec = FAN_DEC_TEXT_RU; + fan_menu.state = FAN_TIPS1_TEXT_RU; + // + filament_menu.title = TITLE_FILAMENT_RU; + filament_menu.in = FILAMENT_IN_TEXT_RU; + filament_menu.out = FILAMENT_OUT_TEXT_RU; + filament_menu.ext1 = FILAMENT_EXT0_TEXT_RU; + filament_menu.ext2 = FILAMENT_EXT1_TEXT_RU; + filament_menu.ready_replace = FILAMENT_CHANGE_TEXT_RU; + filament_menu.filament_dialog_load_heat = FILAMENT_DIALOG_LOAD_HEAT_TIPS_RU; + filament_menu.filament_dialog_load_heat_confirm = FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_RU; + filament_menu.filament_dialog_loading = FILAMENT_DIALOG_LOADING_TIPS_RU; + filament_menu.filament_dialog_load_completed = FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_RU; + filament_menu.filament_dialog_unload_heat = FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_RU; + filament_menu.filament_dialog_unload_heat_confirm = FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_RU; + filament_menu.filament_dialog_unloading = FILAMENT_DIALOG_UNLOADING_TIPS_RU; + filament_menu.filament_dialog_unload_completed = FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_RU; + + // + language_menu.title = LANGUAGE_TEXT_RU; + language_menu.next = PAGE_DOWN_TEXT_RU; + language_menu.up = PAGE_UP_TEXT_RU; + // + printing_menu.title = TITLE_PRINTING_RU; + printing_menu.option = PRINTING_OPERATION_RU; + printing_menu.stop = PRINTING_STOP_RU; + printing_menu.pause = PRINTING_PAUSE_RU; + printing_menu.resume = PRINTING_RESUME_RU; + + // + operation_menu.title = TITLE_OPERATION_RU; + operation_menu.pause = PRINTING_PAUSE_RU; + operation_menu.stop = PRINTING_STOP_RU; + operation_menu.temp = PRINTING_TEMP_RU; + operation_menu.fan = FAN_TEXT_RU; + operation_menu.extr = PRINTING_EXTRUDER_RU; + operation_menu.speed = PRINTING_CHANGESPEED_RU; + operation_menu.filament = FILAMENT_TEXT_RU; + operation_menu.more = PRINTING_MORE_RU; + operation_menu.move = PRINTING_MOVE_RU; + operation_menu.auto_off = AUTO_SHUTDOWN_RU; + operation_menu.manual_off = MANUAL_SHUTDOWN_RU; + // + pause_menu.title = TITLE_PAUSE_RU; + pause_menu.resume = PRINTING_RESUME_RU; + pause_menu.stop = PRINTING_STOP_RU; + pause_menu.extrude = PRINTING_EXTRUDER_RU; + pause_menu.move = PRINTING_MOVE_RU; + pause_menu.filament = FILAMENT_TEXT_RU; + pause_menu.more = PRINTING_MORE_RU; + + // + speed_menu.title = PRINTING_CHANGESPEED_RU; + speed_menu.add = ADD_TEXT_RU; + speed_menu.dec = DEC_TEXT_RU; + speed_menu.move = MOVE_SPEED_RU; + speed_menu.extrude = EXTRUDER_SPEED_RU; + speed_menu.extrude_speed = EXTRUDER_SPEED_STATE_RU; + speed_menu.move_speed = MOVE_SPEED_STATE_RU; + // + printing_more_menu.title = TITLE_MORE_RU; + printing_more_menu.fan = FAN_TEXT_RU; + printing_more_menu.auto_close = AUTO_SHUTDOWN_RU; + printing_more_menu.manual = MANUAL_SHUTDOWN_RU; + printing_more_menu.speed = PRINTING_CHANGESPEED_RU; + printing_more_menu.temp = PRINTING_TEMP_RU; + // print_file_dialog_menu.title = TITLE_DIALOG_CONFIRM_RU; + print_file_dialog_menu.confirm = DIALOG_CONFIRM_RU; + print_file_dialog_menu.cancle = DIALOG_CANCLE_RU; + print_file_dialog_menu.print_file = DIALOG_PRINT_MODEL_RU; + print_file_dialog_menu.cancle_print = DIALOG_CANCEL_PRINT_RU; + print_file_dialog_menu.retry = DIALOG_RETRY_RU; + print_file_dialog_menu.stop = DIALOG_STOP_RU; + print_file_dialog_menu.no_file_print_tips = DIALOG_ERROR_TIPS1_RU; + print_file_dialog_menu.print_from_breakpoint = DIALOG_REPRINT_FROM_BREAKPOINT_RU; + print_file_dialog_menu.close_machine_error = DIALOG_ERROR_TIPS2_RU; + print_file_dialog_menu.filament_no_press = DIALOG_FILAMENT_NO_PRESS_RU; + print_file_dialog_menu.print_finish = DIALOG_PRINT_FINISH_RU; + print_file_dialog_menu.print_time = DIALOG_PRINT_TIME_RU; + print_file_dialog_menu.reprint = DIALOG_REPRINT_RU; + print_file_dialog_menu.wifi_enable_tips = DIALOG_WIFI_ENABLE_TIPS_RU; + + pause_msg_menu.pausing = MESSAGE_PAUSING_RU; + pause_msg_menu.changing = MESSAGE_CHANGING_RU; + pause_msg_menu.unload = MESSAGE_UNLOAD_RU; + pause_msg_menu.waiting = MESSAGE_WAITING_RU; + pause_msg_menu.insert = MESSAGE_INSERT_RU; + pause_msg_menu.load = MESSAGE_LOAD_RU; + pause_msg_menu.purge = MESSAGE_PURGE_RU; + pause_msg_menu.resume = MESSAGE_RESUME_RU; + pause_msg_menu.heat = MESSAGE_HEAT_RU; + pause_msg_menu.heating = MESSAGE_HEATING_RU; + pause_msg_menu.option = MESSAGE_OPTION_RU; + pause_msg_menu.purgeMore = MESSAGE_PURGE_MORE_RU; + pause_msg_menu.continuePrint = MESSAGE_CONTINUE_PRINT_RU; + eeprom_menu.title = EEPROM_SETTINGS_TITLE_RU; + eeprom_menu.store = EEPROM_SETTINGS_STORE_RU; + eeprom_menu.read = EEPROM_SETTINGS_READ_RU; + eeprom_menu.revert = EEPROM_SETTINGS_REVERT_RU; + eeprom_menu.storeTips = EEPROM_STORE_TIPS_RU; + eeprom_menu.readTips = EEPROM_READ_TIPS_RU; + eeprom_menu.revertTips = EEPROM_REVERT_TIPS_RU; + break; + case LANG_SPANISH: + common_menu.dialog_confirm_title = TITLE_DIALOG_CONFIRM_SP; + common_menu.text_back = BACK_TEXT_SP; + common_menu.close_machine_tips = DIALOG_CLOSE_MACHINE_SP; + common_menu.unbind_printer_tips = DIALOG_UNBIND_PRINTER_SP; + common_menu.print_special_title = PRINTING_SP; + common_menu.pause_special_title = PRINTING_PAUSAR_SP; + common_menu.operate_special_title = PRINTING_AJUSTES_SP; + // + main_menu.title = TITLE_READYPRINT_SP; + main_menu.preheat = PREHEAT_TEXT_SP; + main_menu.move = MOVE_TEXT_SP; + main_menu.home = HOME_TEXT_SP; + main_menu.print = PRINT_TEXT_SP; + main_menu.extrude = EXTRUDE_TEXT_SP; + main_menu.leveling = LEVELING_TEXT_SP; + main_menu.autoleveling = AUTO_LEVELING_TEXT_SP; + main_menu.fan = FAN_TEXT_SP; + main_menu.set = SET_TEXT_SP; + main_menu.more = MORE_TEXT_SP; + main_menu.tool = TOOL_TEXT_SP; + // TOOL + tool_menu.title = TOOL_TEXT_SP; + tool_menu.preheat = TOOL_PREHEAT_SP; + tool_menu.extrude = TOOL_EXTRUDE_SP; + tool_menu.move = TOOL_MOVE_SP; + tool_menu.home = TOOL_HOME_SP; + tool_menu.leveling = TOOL_LEVELING_SP; + tool_menu.autoleveling = TOOL_AUTO_LEVELING_SP; + tool_menu.filament = TOOL_FILAMENT_SP; + tool_menu.more = TOOL_MORE_SP; + // + preheat_menu.adjust_title = TITLE_ADJUST_SP; + preheat_menu.title = TITLE_PREHEAT_SP; + preheat_menu.add = ADD_TEXT_SP; + preheat_menu.dec = DEC_TEXT_SP; + preheat_menu.ext1 = EXTRUDER_1_TEXT_SP; + preheat_menu.ext2 = EXTRUDER_2_TEXT_SP; + preheat_menu.hotbed = HEATBED_TEXT_SP; + preheat_menu.off = CLOSE_TEXT_SP; + // + move_menu.title = MOVE_TEXT_SP; + // + home_menu.title = TITLE_HOME_SP; + home_menu.home_x = HOME_X_TEXT_SP; + home_menu.home_y = HOME_Y_TEXT_SP; + home_menu.home_z = HOME_Z_TEXT_SP; + home_menu.home_all = HOME_ALL_TEXT_SP; + home_menu.stopmove = HOME_STOPMOVE_SP; + // + file_menu.title = TITLE_CHOOSEFILE_SP; + file_menu.page_up = PAGE_UP_TEXT_SP; + file_menu.page_down = PAGE_DOWN_TEXT_SP; + file_menu.file_loading = FILE_LOADING_SP; + file_menu.no_file = NO_FILE_SP; + file_menu.no_file_and_check = NO_FILE_SP;// NO_FILE_AND_CHECK_SP; + // + extrude_menu.title = TITLE_EXTRUDE_SP; + extrude_menu.in = EXTRUDER_IN_TEXT_SP; + extrude_menu.out = EXTRUDER_OUT_TEXT_SP; + extrude_menu.ext1 = EXTRUDER_1_TEXT_SP; + extrude_menu.ext2 = EXTRUDER_2_TEXT_SP; + extrude_menu.low = EXTRUDE_LOW_SPEED_TEXT_SP; + extrude_menu.normal = EXTRUDE_MEDIUM_SPEED_TEXT_SP; + extrude_menu.high = EXTRUDE_HIGH_SPEED_TEXT_SP; + extrude_menu.temper_text = EXTRUDER_TEMP_TEXT_SP; + // + leveling_menu.title = TITLE_LEVELING_SP; + leveling_menu.position1 = LEVELING_POINT1_TEXT_SP; + leveling_menu.position2 = LEVELING_POINT2_TEXT_SP; + leveling_menu.position3 = LEVELING_POINT3_TEXT_SP; + leveling_menu.position4 = LEVELING_POINT4_TEXT_SP; + leveling_menu.position5 = LEVELING_POINT5_TEXT_SP; + // + set_menu.title = TITLE_SET_SP; + set_menu.filesys = FILESYS_TEXT_SP; + set_menu.wifi = WIFI_TEXT_SP; + set_menu.about = ABOUT_TEXT_SP; + set_menu.fan = FAN_TEXT_SP; + set_menu.filament = FILAMENT_TEXT_SP; + set_menu.breakpoint = BREAK_POINT_TEXT_SP; + set_menu.motoroff = MOTOR_OFF_TEXT_SP; + set_menu.motoroffXY = MOTOR_OFF_XY_TEXT_SP; + set_menu.language = LANGUAGE_TEXT_SP; + set_menu.shutdown = SHUTDOWN_TEXT_SP; + set_menu.machine_para = MACHINE_PARA_SP; + set_menu.eepromSet = EEPROM_SETTINGS_SP; + more_menu.title = TITLE_MORE_SP; + // + filesys_menu.title = TITLE_FILESYS_SP; + filesys_menu.sd_sys = SD_CARD_TEXT_SP; + filesys_menu.usb_sys = U_DISK_TEXT_SP; + + // WIFI + wifi_menu.title = WIFI_TEXT; + // wifi_menu.key = WIFI_KEY_TEXT_SP; + // wifi_menu.ip = WIFI_IP_TEXT_SP; + // wifi_menu.state = WIFI_STA_TEXT_SP; + wifi_menu.cloud = CLOUD_TEXT_SP; + wifi_menu.reconnect = WIFI_RECONNECT_TEXT_SP; + + cloud_menu.title = TITLE_CLOUD_TEXT_SP; + cloud_menu.bind = CLOUD_BINDED_SP; + cloud_menu.binded = CLOUD_BINDED_SP; + cloud_menu.unbind = CLOUD_UNBIND_SP; + cloud_menu.unbinding = CLOUD_UNBINDED_SP; + cloud_menu.disconnected = CLOUD_DISCONNECTED_SP; + cloud_menu.disable = CLOUD_DISABLE_SP; + // + about_menu.title = ABOUT_TEXT_SP; + about_menu.type = ABOUT_TYPE_TEXT_SP; + about_menu.version = ABOUT_VERSION_TEXT_SP; + about_menu.wifi = ABOUT_WIFI_TEXT_SP; + // + fan_menu.title = FAN_TEXT_SP; + fan_menu.add = FAN_ADD_TEXT_SP; + fan_menu.dec = FAN_DEC_TEXT_SP; + fan_menu.state = FAN_TIPS1_TEXT_SP; + // + filament_menu.title = TITLE_FILAMENT_SP; + filament_menu.in = FILAMENT_IN_TEXT_SP; + filament_menu.out = FILAMENT_OUT_TEXT_SP; + filament_menu.ext1 = FILAMENT_EXT0_TEXT_SP; + filament_menu.ext2 = FILAMENT_EXT1_TEXT_SP; + filament_menu.ready_replace = FILAMENT_CHANGE_TEXT_SP; + filament_menu.filament_dialog_load_heat = FILAMENT_DIALOG_LOAD_HEAT_TIPS_SP; + filament_menu.filament_dialog_load_heat_confirm = FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_SP; + filament_menu.filament_dialog_loading = FILAMENT_DIALOG_LOADING_TIPS_SP; + filament_menu.filament_dialog_load_completed = FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_SP; + filament_menu.filament_dialog_unload_heat = FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_SP; + filament_menu.filament_dialog_unload_heat_confirm = FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_SP; + filament_menu.filament_dialog_unloading = FILAMENT_DIALOG_UNLOADING_TIPS_SP; + filament_menu.filament_dialog_unload_completed = FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_SP; + + // + language_menu.title = LANGUAGE_TEXT_SP; + language_menu.next = PAGE_DOWN_TEXT_SP; + language_menu.up = PAGE_UP_TEXT_SP; + // + printing_menu.title = TITLE_PRINTING_SP; + printing_menu.option = PRINTING_OPERATION_SP; + printing_menu.stop = PRINTING_STOP_SP; + printing_menu.pause = PRINTING_PAUSE_SP; + printing_menu.resume = PRINTING_RESUME_SP; + + // + operation_menu.title = TITLE_OPERATION_SP; + operation_menu.pause = PRINTING_PAUSE_SP; + operation_menu.stop = PRINTING_STOP_SP; + operation_menu.temp = PRINTING_TEMP_SP; + operation_menu.fan = FAN_TEXT_SP; + operation_menu.extr = PRINTING_EXTRUDER_SP; + operation_menu.speed = PRINTING_CHANGESPEED_SP; + operation_menu.filament = FILAMENT_TEXT_SP; + operation_menu.more = PRINTING_MORE_SP; + operation_menu.move = PRINTING_MOVE_SP; + operation_menu.auto_off = AUTO_SHUTDOWN_SP; + operation_menu.manual_off = MANUAL_SHUTDOWN_SP; + // + pause_menu.title = TITLE_PAUSE_RU; + pause_menu.resume = PRINTING_RESUME_SP; + pause_menu.stop = PRINTING_STOP_SP; + pause_menu.extrude = PRINTING_EXTRUDER_SP; + pause_menu.move = PRINTING_MOVE_SP; + pause_menu.filament = FILAMENT_TEXT_SP; + pause_menu.more = PRINTING_MORE_SP; + + // + speed_menu.title = PRINTING_CHANGESPEED_SP; + speed_menu.add = ADD_TEXT_SP; + speed_menu.dec = DEC_TEXT_SP; + speed_menu.move = MOVE_SPEED_SP; + speed_menu.extrude = EXTRUDER_SPEED_SP; + speed_menu.extrude_speed = EXTRUDER_SPEED_STATE_SP; + speed_menu.move_speed = MOVE_SPEED_STATE_SP; + // + printing_more_menu.title = TITLE_MORE_SP; + printing_more_menu.fan = FAN_TEXT_SP; + printing_more_menu.auto_close = AUTO_SHUTDOWN_SP; + printing_more_menu.manual = MANUAL_SHUTDOWN_SP; + printing_more_menu.speed = PRINTING_CHANGESPEED_SP; + printing_more_menu.temp = PRINTING_TEMP_SP; + + // print_file_dialog_menu.title = TITLE_DIALOG_CONFIRM_SP; + print_file_dialog_menu.confirm = DIALOG_CONFIRM_SP; + print_file_dialog_menu.cancle = DIALOG_CANCLE_SP; + print_file_dialog_menu.print_file = DIALOG_PRINT_MODEL_SP; + print_file_dialog_menu.cancle_print = DIALOG_CANCEL_PRINT_SP; + print_file_dialog_menu.retry = DIALOG_RETRY_SP; + print_file_dialog_menu.stop = DIALOG_STOP_SP; + print_file_dialog_menu.no_file_print_tips = DIALOG_ERROR_TIPS1_SP; + print_file_dialog_menu.print_from_breakpoint = DIALOG_REPRINT_FROM_BREAKPOINT_SP; + print_file_dialog_menu.close_machine_error = DIALOG_ERROR_TIPS2_SP; + print_file_dialog_menu.filament_no_press = DIALOG_FILAMENT_NO_PRESS_SP; + print_file_dialog_menu.print_finish = DIALOG_PRINT_FINISH_SP; + print_file_dialog_menu.print_time = DIALOG_PRINT_TIME_SP; + print_file_dialog_menu.reprint = DIALOG_REPRINT_SP; + print_file_dialog_menu.wifi_enable_tips = DIALOG_WIFI_ENABLE_TIPS_SP; + + pause_msg_menu.pausing = MESSAGE_PAUSING_SP; + pause_msg_menu.changing = MESSAGE_CHANGING_SP; + pause_msg_menu.unload = MESSAGE_UNLOAD_SP; + pause_msg_menu.waiting = MESSAGE_WAITING_SP; + pause_msg_menu.insert = MESSAGE_INSERT_SP; + pause_msg_menu.load = MESSAGE_LOAD_SP; + pause_msg_menu.purge = MESSAGE_PURGE_SP; + pause_msg_menu.resume = MESSAGE_RESUME_SP; + pause_msg_menu.heat = MESSAGE_HEAT_SP; + pause_msg_menu.heating = MESSAGE_HEATING_SP; + pause_msg_menu.option = MESSAGE_OPTION_SP; + pause_msg_menu.purgeMore = MESSAGE_PURGE_MORE_SP; + pause_msg_menu.continuePrint = MESSAGE_CONTINUE_PRINT_SP; + eeprom_menu.title = EEPROM_SETTINGS_TITLE_SP; + eeprom_menu.store = EEPROM_SETTINGS_STORE_SP; + eeprom_menu.read = EEPROM_SETTINGS_READ_SP; + eeprom_menu.revert = EEPROM_SETTINGS_REVERT_SP; + eeprom_menu.storeTips = EEPROM_STORE_TIPS_SP; + eeprom_menu.readTips = EEPROM_READ_TIPS_SP; + eeprom_menu.revertTips = EEPROM_REVERT_TIPS_SP; + break; + + #endif // if 1 + + case LANG_FRENCH: + common_menu.dialog_confirm_title = TITLE_DIALOG_CONFIRM_FR; + common_menu.text_back = BACK_TEXT_FR; + common_menu.close_machine_tips = DIALOG_CLOSE_MACHINE_FR; + common_menu.unbind_printer_tips = DIALOG_UNBIND_PRINTER_FR; + common_menu.print_special_title = PRINTING_OTHER_LANGUGE; + common_menu.pause_special_title = PRINTING_PAUSE_OTHER_LANGUGE; + common_menu.operate_special_title = PRINTING_OPERATION_OTHER_LANGUGE; + + // + main_menu.title = TITLE_READYPRINT_FR; + main_menu.preheat = PREHEAT_TEXT_FR; + main_menu.move = MOVE_TEXT_FR; + main_menu.home = HOME_TEXT_FR; + main_menu.print = PRINT_TEXT_FR; + main_menu.extrude = EXTRUDE_TEXT_FR; + main_menu.leveling = LEVELING_TEXT_FR; + main_menu.autoleveling = AUTO_LEVELING_TEXT_FR; + main_menu.fan = FAN_TEXT_FR; + main_menu.set = SET_TEXT_FR; + main_menu.more = MORE_TEXT_FR; + main_menu.tool = TOOL_TEXT_FR; + // TOOL + tool_menu.title = TOOL_TEXT_FR; + tool_menu.preheat = TOOL_PREHEAT_FR; + tool_menu.extrude = TOOL_EXTRUDE_FR; + tool_menu.move = TOOL_MOVE_FR; + tool_menu.home = TOOL_HOME_FR; + tool_menu.leveling = TOOL_LEVELING_FR; + tool_menu.autoleveling = TOOL_AUTO_LEVELING_FR; + tool_menu.filament = TOOL_FILAMENT_FR; + tool_menu.more = TOOL_MORE_FR; + // + preheat_menu.adjust_title = TITLE_ADJUST_FR; + preheat_menu.title = TITLE_PREHEAT_FR; + preheat_menu.add = ADD_TEXT_FR; + preheat_menu.dec = DEC_TEXT_FR; + preheat_menu.ext1 = EXTRUDER_1_TEXT_FR; + preheat_menu.ext2 = EXTRUDER_2_TEXT_FR; + preheat_menu.hotbed = HEATBED_TEXT_FR; + preheat_menu.off = CLOSE_TEXT_FR; + // + move_menu.title = MOVE_TEXT_FR; + // + home_menu.title = TITLE_HOME_FR; + home_menu.stopmove = HOME_STOPMOVE_FR; + // + file_menu.title = TITLE_CHOOSEFILE_FR; + file_menu.page_up = PAGE_UP_TEXT_FR; + file_menu.page_down = PAGE_DOWN_TEXT_FR; + // + extrude_menu.title = TITLE_EXTRUDE_FR; + extrude_menu.in = EXTRUDER_IN_TEXT_FR; + extrude_menu.out = EXTRUDER_OUT_TEXT_FR; + extrude_menu.ext1 = EXTRUDER_1_TEXT_FR; + extrude_menu.ext2 = EXTRUDER_2_TEXT_FR; + extrude_menu.low = EXTRUDE_LOW_SPEED_TEXT_FR; + extrude_menu.normal = EXTRUDE_MEDIUM_SPEED_TEXT_FR; + extrude_menu.high = EXTRUDE_HIGH_SPEED_TEXT_FR; + extrude_menu.temper_text = EXTRUDER_TEMP_TEXT_FR; + // + leveling_menu.title = TITLE_LEVELING_FR; + leveling_menu.position1 = LEVELING_POINT1_TEXT_FR; + leveling_menu.position2 = LEVELING_POINT2_TEXT_FR; + leveling_menu.position3 = LEVELING_POINT3_TEXT_FR; + leveling_menu.position4 = LEVELING_POINT4_TEXT_FR; + leveling_menu.position5 = LEVELING_POINT5_TEXT_FR; + // + set_menu.title = TITLE_SET_FR; + set_menu.filesys = FILESYS_TEXT_FR; + set_menu.wifi = WIFI_TEXT_FR; + set_menu.about = ABOUT_TEXT_FR; + set_menu.fan = FAN_TEXT_FR; + set_menu.filament = FILAMENT_TEXT_FR; + set_menu.breakpoint = BREAK_POINT_TEXT_FR; + set_menu.motoroff = MOTOR_OFF_TEXT_FR; + set_menu.motoroffXY = MOTOR_OFF_XY_TEXT_FR; + set_menu.language = LANGUAGE_TEXT_FR; + set_menu.shutdown = SHUTDOWN_TEXT_FR; + set_menu.machine_para = MACHINE_PARA_FR; + set_menu.eepromSet = EEPROM_SETTINGS_FR; + more_menu.title = TITLE_MORE_FR; + // + filesys_menu.title = TITLE_FILESYS_FR; + filesys_menu.sd_sys = SD_CARD_TEXT_FR; + filesys_menu.usb_sys = U_DISK_TEXT_FR; + file_menu.file_loading = FILE_LOADING_FR; + file_menu.no_file = NO_FILE_FR; + file_menu.no_file_and_check = NO_FILE_FR;// NO_FILE_AND_CHECK_FR; + // WIFI + wifi_menu.title = WIFI_NAME_TEXT_FR; + // wifi_menu.key = WIFI_KEY_TEXT_FR; + // wifi_menu.ip = WIFI_IP_TEXT_FR; + // wifi_menu.state = WIFI_STA_TEXT_FR; + // wifi_menu.cloud = CLOSE_TEXT_FR; + wifi_menu.cloud = CLOUD_TEXT_FR; + wifi_menu.reconnect = WIFI_RECONNECT_TEXT_FR; + + cloud_menu.title = TITLE_CLOUD_TEXT_FR; + cloud_menu.bind = CLOUD_BINDED_FR; + cloud_menu.binded = CLOUD_BINDED_FR; + cloud_menu.unbind = CLOUD_UNBIND_FR; + cloud_menu.unbinding = CLOUD_UNBINDED_FR; + cloud_menu.disconnected = CLOUD_DISCONNECTED_FR; + cloud_menu.disable = CLOUD_DISABLE_FR; + // + about_menu.title = ABOUT_TEXT_FR; + about_menu.type = ABOUT_TYPE_TEXT_FR; + about_menu.version = ABOUT_VERSION_TEXT_FR; + about_menu.wifi = ABOUT_WIFI_TEXT_FR; + // + fan_menu.title = FAN_TEXT_FR; + fan_menu.add = FAN_ADD_TEXT_FR; + fan_menu.dec = FAN_DEC_TEXT_FR; + fan_menu.state = FAN_TIPS1_TEXT_FR; + // + filament_menu.title = TITLE_FILAMENT_FR; + filament_menu.in = FILAMENT_IN_TEXT_FR; + filament_menu.out = FILAMENT_OUT_TEXT_FR; + filament_menu.ext1 = FILAMENT_EXT0_TEXT_FR; + filament_menu.ext2 = FILAMENT_EXT1_TEXT_FR; + filament_menu.ready_replace = FILAMENT_CHANGE_TEXT_FR; + filament_menu.filament_dialog_load_heat = FILAMENT_DIALOG_LOAD_HEAT_TIPS_FR; + filament_menu.filament_dialog_load_heat_confirm = FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_FR; + filament_menu.filament_dialog_loading = FILAMENT_DIALOG_LOADING_TIPS_FR; + filament_menu.filament_dialog_load_completed = FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_FR; + filament_menu.filament_dialog_unload_heat = FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_FR; + filament_menu.filament_dialog_unload_heat_confirm = FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_FR; + filament_menu.filament_dialog_unloading = FILAMENT_DIALOG_UNLOADING_TIPS_FR; + filament_menu.filament_dialog_unload_completed = FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_FR; + + // + language_menu.title = LANGUAGE_TEXT_FR; + + // + printing_menu.title = TITLE_PRINTING_FR; + printing_menu.option = PRINTING_OPERATION_FR; + printing_menu.stop = PRINTING_STOP_FR; + printing_menu.pause = PRINTING_PAUSE_FR; + printing_menu.resume = PRINTING_RESUME_FR; + + // + operation_menu.title = TITLE_OPERATION_FR; + operation_menu.pause = PRINTING_PAUSE_FR; + operation_menu.stop = PRINTING_STOP_FR; + operation_menu.temp = PRINTING_TEMP_FR; + operation_menu.fan = FAN_TEXT_FR; + operation_menu.extr = PRINTING_EXTRUDER_FR; + operation_menu.speed = PRINTING_CHANGESPEED_FR; + operation_menu.filament = FILAMENT_TEXT_FR; + operation_menu.more = PRINTING_MORE_FR; + operation_menu.move = PRINTING_MOVE_FR; + operation_menu.auto_off = AUTO_SHUTDOWN_FR; + operation_menu.manual_off = MANUAL_SHUTDOWN_FR; + // + pause_menu.title = TITLE_PAUSE_FR; + pause_menu.resume = PRINTING_RESUME_FR; + pause_menu.stop = PRINTING_STOP_FR; + pause_menu.extrude = PRINTING_EXTRUDER_FR; + pause_menu.move = PRINTING_MOVE_FR; + pause_menu.filament = FILAMENT_TEXT_FR; + pause_menu.more = PRINTING_MORE_FR; + + // + speed_menu.title = PRINTING_CHANGESPEED_FR; + speed_menu.add = ADD_TEXT_FR; + speed_menu.dec = DEC_TEXT_FR; + speed_menu.move = MOVE_SPEED_FR; + speed_menu.extrude = EXTRUDER_SPEED_FR; + speed_menu.extrude_speed = EXTRUDER_SPEED_STATE_FR; + speed_menu.move_speed = MOVE_SPEED_STATE_FR; + // + printing_more_menu.fan = FAN_TEXT_FR; + printing_more_menu.auto_close = AUTO_SHUTDOWN_FR; + printing_more_menu.manual = MANUAL_SHUTDOWN_FR; + printing_more_menu.speed = PRINTING_CHANGESPEED_FR; + printing_more_menu.temp = PRINTING_TEMP_FR; + + // print_file_dialog_menu.title = TITLE_DIALOG_CONFIRM_SP; + print_file_dialog_menu.confirm = DIALOG_CONFIRM_FR; + print_file_dialog_menu.cancle = DIALOG_CANCLE_FR; + print_file_dialog_menu.print_file = DIALOG_PRINT_MODEL_FR; + print_file_dialog_menu.cancle_print = DIALOG_CANCEL_PRINT_FR; + print_file_dialog_menu.retry = DIALOG_RETRY_FR; + print_file_dialog_menu.stop = DIALOG_STOP_FR; + print_file_dialog_menu.no_file_print_tips = DIALOG_ERROR_TIPS1_FR; + print_file_dialog_menu.print_from_breakpoint = DIALOG_REPRINT_FROM_BREAKPOINT_FR; + print_file_dialog_menu.close_machine_error = DIALOG_ERROR_TIPS2_FR; + print_file_dialog_menu.filament_no_press = DIALOG_FILAMENT_NO_PRESS_FR; + print_file_dialog_menu.print_finish = DIALOG_PRINT_FINISH_FR; + print_file_dialog_menu.print_time = DIALOG_PRINT_TIME_FR; + print_file_dialog_menu.reprint = DIALOG_REPRINT_FR; + print_file_dialog_menu.wifi_enable_tips = DIALOG_WIFI_ENABLE_TIPS_FR; + + pause_msg_menu.pausing = MESSAGE_PAUSING_FR; + pause_msg_menu.changing = MESSAGE_CHANGING_FR; + pause_msg_menu.unload = MESSAGE_UNLOAD_FR; + pause_msg_menu.waiting = MESSAGE_WAITING_FR; + pause_msg_menu.insert = MESSAGE_INSERT_FR; + pause_msg_menu.load = MESSAGE_LOAD_FR; + pause_msg_menu.purge = MESSAGE_PURGE_FR; + pause_msg_menu.resume = MESSAGE_RESUME_FR; + pause_msg_menu.heat = MESSAGE_HEAT_FR; + pause_msg_menu.heating = MESSAGE_HEATING_FR; + pause_msg_menu.option = MESSAGE_OPTION_FR; + pause_msg_menu.purgeMore = MESSAGE_PURGE_MORE_FR; + pause_msg_menu.continuePrint = MESSAGE_CONTINUE_PRINT_FR; + eeprom_menu.title = EEPROM_SETTINGS_TITLE_FR; + eeprom_menu.store = EEPROM_SETTINGS_STORE_FR; + eeprom_menu.read = EEPROM_SETTINGS_READ_FR; + eeprom_menu.revert = EEPROM_SETTINGS_REVERT_FR; + eeprom_menu.storeTips = EEPROM_STORE_TIPS_FR; + eeprom_menu.readTips = EEPROM_READ_TIPS_FR; + eeprom_menu.revertTips = EEPROM_REVERT_TIPS_FR; + break; + + case LANG_ITALY: + common_menu.dialog_confirm_title = TITLE_DIALOG_CONFIRM_IT; + common_menu.text_back = BACK_TEXT_IT; + common_menu.close_machine_tips = DIALOG_CLOSE_MACHINE_IT; + common_menu.unbind_printer_tips = DIALOG_UNBIND_PRINTER_IT; + common_menu.print_special_title = PRINTING_OTHER_LANGUGE; + common_menu.pause_special_title = PRINTING_PAUSE_OTHER_LANGUGE; + common_menu.operate_special_title = PRINTING_OPERATION_OTHER_LANGUGE; + + // + main_menu.title = TITLE_READYPRINT_IT; + main_menu.preheat = PREHEAT_TEXT_IT; + main_menu.move = MOVE_TEXT_IT; + main_menu.home = HOME_TEXT_IT; + main_menu.print = PRINT_TEXT_IT; + main_menu.extrude = EXTRUDE_TEXT_IT; + main_menu.leveling = LEVELING_TEXT_IT; + main_menu.autoleveling = AUTO_LEVELING_TEXT_IT; + main_menu.fan = FAN_TEXT_IT; + main_menu.set = SET_TEXT_IT; + main_menu.more = MORE_TEXT_IT; + main_menu.tool = TOOL_TEXT_IT; + // TOOL + tool_menu.title = TOOL_TEXT_IT; + tool_menu.preheat = TOOL_PREHEAT_IT; + tool_menu.extrude = TOOL_EXTRUDE_IT; + tool_menu.move = TOOL_MOVE_IT; + tool_menu.home = TOOL_HOME_IT; + tool_menu.leveling = TOOL_LEVELING_IT; + tool_menu.autoleveling = TOOL_AUTO_LEVELING_IT; + tool_menu.filament = TOOL_FILAMENT_IT; + tool_menu.more = TOOL_MORE_IT; + // + preheat_menu.adjust_title = TITLE_ADJUST_IT; + preheat_menu.title = TITLE_PREHEAT_IT; + preheat_menu.add = ADD_TEXT_IT; + preheat_menu.dec = DEC_TEXT_IT; + preheat_menu.ext1 = EXTRUDER_1_TEXT_IT; + preheat_menu.ext2 = EXTRUDER_2_TEXT_IT; + preheat_menu.hotbed = HEATBED_TEXT_IT; + preheat_menu.off = CLOSE_TEXT_IT; + // + move_menu.title = MOVE_TEXT_IT; + // + home_menu.title = TITLE_HOME_IT; + home_menu.stopmove = HOME_STOPMOVE_IT; + // + file_menu.title = TITLE_CHOOSEFILE_IT; + file_menu.page_up = PAGE_UP_TEXT_IT; + file_menu.page_down = PAGE_DOWN_TEXT_IT; + file_menu.file_loading = FILE_LOADING_IT; + file_menu.no_file = NO_FILE_IT; + file_menu.no_file_and_check = NO_FILE_IT;// NO_FILE_AND_CHECK_IT; + // + extrude_menu.title = TITLE_EXTRUDE_IT; + extrude_menu.in = EXTRUDER_IN_TEXT_IT; + extrude_menu.out = EXTRUDER_OUT_TEXT_IT; + extrude_menu.ext1 = EXTRUDER_1_TEXT_IT; + extrude_menu.ext2 = EXTRUDER_2_TEXT_IT; + extrude_menu.low = EXTRUDE_LOW_SPEED_TEXT_IT; + extrude_menu.normal = EXTRUDE_MEDIUM_SPEED_TEXT_IT; + extrude_menu.high = EXTRUDE_HIGH_SPEED_TEXT_IT; + extrude_menu.temper_text = EXTRUDER_TEMP_TEXT_IT; + // + leveling_menu.title = TITLE_LEVELING_IT; + leveling_menu.position1 = LEVELING_POINT1_TEXT_IT; + leveling_menu.position2 = LEVELING_POINT2_TEXT_IT; + leveling_menu.position3 = LEVELING_POINT3_TEXT_IT; + leveling_menu.position4 = LEVELING_POINT4_TEXT_IT; + leveling_menu.position5 = LEVELING_POINT5_TEXT_IT; + // + set_menu.title = TITLE_SET_IT; + set_menu.filesys = FILESYS_TEXT_IT; + set_menu.wifi = WIFI_TEXT_IT; + set_menu.about = ABOUT_TEXT_IT; + set_menu.fan = FAN_TEXT_IT; + set_menu.filament = FILAMENT_TEXT_IT; + set_menu.breakpoint = BREAK_POINT_TEXT_IT; + set_menu.motoroff = MOTOR_OFF_TEXT_IT; + set_menu.motoroffXY = MOTOR_OFF_XY_TEXT_IT; + set_menu.language = LANGUAGE_TEXT_IT; + set_menu.shutdown = SHUTDOWN_TEXT_IT; + set_menu.machine_para = MACHINE_PARA_IT; + set_menu.eepromSet = EEPROM_SETTINGS_IT; + more_menu.title = TITLE_MORE_IT; + // + filesys_menu.title = TITLE_FILESYS_IT; + filesys_menu.sd_sys = SD_CARD_TEXT_IT; + filesys_menu.usb_sys = U_DISK_TEXT_IT; + + // WIFI + wifi_menu.title = WIFI_NAME_TEXT_IT; + // wifi_menu.key = WIFI_KEY_TEXT_IT; + // wifi_menu.ip = WIFI_IP_TEXT_IT; + // wifi_menu.state = WIFI_STA_TEXT_IT; + wifi_menu.cloud = CLOSE_TEXT_IT; + wifi_menu.reconnect = WIFI_RECONNECT_TEXT_IT; + + cloud_menu.title = TITLE_CLOUD_TEXT_IT; + cloud_menu.bind = CLOUD_BINDED_IT; + cloud_menu.binded = CLOUD_BINDED_IT; + cloud_menu.unbind = CLOUD_UNBIND_IT; + cloud_menu.unbinding = CLOUD_UNBINDED_IT; + cloud_menu.disconnected = CLOUD_DISCONNECTED_IT; + cloud_menu.disable = CLOUD_DISABLE_IT; + // + about_menu.title = ABOUT_TEXT_IT; + about_menu.type = ABOUT_TYPE_TEXT_IT; + about_menu.version = ABOUT_VERSION_TEXT_IT; + about_menu.wifi = ABOUT_WIFI_TEXT_IT; + // + fan_menu.title = FAN_TEXT_IT; + fan_menu.add = FAN_ADD_TEXT_IT; + fan_menu.dec = FAN_DEC_TEXT_IT; + fan_menu.state = FAN_TIPS1_TEXT_IT; + // + filament_menu.title = TITLE_FILAMENT_IT; + filament_menu.in = FILAMENT_IN_TEXT_IT; + filament_menu.out = FILAMENT_OUT_TEXT_IT; + filament_menu.ext1 = FILAMENT_EXT0_TEXT_IT; + filament_menu.ext2 = FILAMENT_EXT1_TEXT_IT; + filament_menu.ready_replace = FILAMENT_CHANGE_TEXT_IT; + filament_menu.filament_dialog_load_heat = FILAMENT_DIALOG_LOAD_HEAT_TIPS_IT; + filament_menu.filament_dialog_load_heat_confirm = FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_IT; + filament_menu.filament_dialog_loading = FILAMENT_DIALOG_LOADING_TIPS_IT; + filament_menu.filament_dialog_load_completed = FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_IT; + filament_menu.filament_dialog_unload_heat = FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_IT; + filament_menu.filament_dialog_unload_heat_confirm = FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_IT; + filament_menu.filament_dialog_unloading = FILAMENT_DIALOG_UNLOADING_TIPS_IT; + filament_menu.filament_dialog_unload_completed = FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_IT; + + // + language_menu.title = LANGUAGE_TEXT_IT; + + // + printing_menu.title = TITLE_PRINTING_IT; + printing_menu.option = PRINTING_OPERATION_IT; + printing_menu.stop = PRINTING_STOP_IT; + printing_menu.pause = PRINTING_PAUSE_IT; + printing_menu.resume = PRINTING_RESUME_IT; + + // + operation_menu.title = TITLE_OPERATION_IT; + operation_menu.pause = PRINTING_PAUSE_IT; + operation_menu.stop = PRINTING_STOP_IT; + operation_menu.temp = PRINTING_TEMP_IT; + operation_menu.fan = FAN_TEXT_IT; + operation_menu.extr = PRINTING_EXTRUDER_IT; + operation_menu.speed = PRINTING_CHANGESPEED_IT; + operation_menu.filament = FILAMENT_TEXT_IT; + operation_menu.more = PRINTING_MORE_IT; + operation_menu.move = PRINTING_MOVE_IT; + operation_menu.auto_off = AUTO_SHUTDOWN_IT; + operation_menu.manual_off = MANUAL_SHUTDOWN_IT; + // + pause_menu.title = TITLE_PAUSE_IT; + pause_menu.resume = PRINTING_RESUME_IT; + pause_menu.stop = PRINTING_STOP_IT; + pause_menu.extrude = PRINTING_EXTRUDER_IT; + pause_menu.move = PRINTING_MOVE_IT; + pause_menu.filament = FILAMENT_TEXT_IT; + pause_menu.more = PRINTING_MORE_IT; + + // + speed_menu.title = PRINTING_CHANGESPEED_IT; + speed_menu.add = ADD_TEXT_IT; + speed_menu.dec = DEC_TEXT_IT; + speed_menu.move = MOVE_SPEED_IT; + speed_menu.extrude = EXTRUDER_SPEED_IT; + speed_menu.extrude_speed = EXTRUDER_SPEED_STATE_IT; + speed_menu.move_speed = MOVE_SPEED_STATE_IT; + // + printing_more_menu.fan = FAN_TEXT_IT; + printing_more_menu.auto_close = AUTO_SHUTDOWN_IT; + printing_more_menu.manual = MANUAL_SHUTDOWN_IT; + printing_more_menu.temp = PRINTING_TEMP_IT; + printing_more_menu.speed = PRINTING_CHANGESPEED_IT; + + // print_file_dialog_menu.title = TITLE_DIALOG_CONFIRM_SP; + print_file_dialog_menu.confirm = DIALOG_CONFIRM_IT; + print_file_dialog_menu.cancle = DIALOG_CANCLE_IT; + print_file_dialog_menu.print_file = DIALOG_PRINT_MODEL_IT; + print_file_dialog_menu.cancle_print = DIALOG_CANCEL_PRINT_IT; + print_file_dialog_menu.retry = DIALOG_RETRY_IT; + print_file_dialog_menu.stop = DIALOG_STOP_IT; + print_file_dialog_menu.no_file_print_tips = DIALOG_ERROR_TIPS1_IT; + print_file_dialog_menu.print_from_breakpoint = DIALOG_REPRINT_FROM_BREAKPOINT_IT; + print_file_dialog_menu.close_machine_error = DIALOG_ERROR_TIPS2_IT; + print_file_dialog_menu.filament_no_press = DIALOG_FILAMENT_NO_PRESS_IT; + print_file_dialog_menu.print_finish = DIALOG_PRINT_FINISH_IT; + print_file_dialog_menu.print_time = DIALOG_PRINT_TIME_IT; + print_file_dialog_menu.reprint = DIALOG_REPRINT_IT; + print_file_dialog_menu.wifi_enable_tips = DIALOG_WIFI_ENABLE_TIPS_IT; + + pause_msg_menu.pausing = MESSAGE_PAUSING_IT; + pause_msg_menu.changing = MESSAGE_CHANGING_IT; + pause_msg_menu.unload = MESSAGE_UNLOAD_IT; + pause_msg_menu.waiting = MESSAGE_WAITING_IT; + pause_msg_menu.insert = MESSAGE_INSERT_IT; + pause_msg_menu.load = MESSAGE_LOAD_IT; + pause_msg_menu.purge = MESSAGE_PURGE_IT; + pause_msg_menu.resume = MESSAGE_RESUME_IT; + pause_msg_menu.heat = MESSAGE_HEAT_IT; + pause_msg_menu.heating = MESSAGE_HEATING_IT; + pause_msg_menu.option = MESSAGE_OPTION_IT; + pause_msg_menu.purgeMore = MESSAGE_PURGE_MORE_IT; + pause_msg_menu.continuePrint = MESSAGE_CONTINUE_PRINT_IT; + eeprom_menu.title = EEPROM_SETTINGS_TITLE_IT; + eeprom_menu.store = EEPROM_SETTINGS_STORE_IT; + eeprom_menu.read = EEPROM_SETTINGS_READ_IT; + eeprom_menu.revert = EEPROM_SETTINGS_REVERT_IT; + eeprom_menu.storeTips = EEPROM_STORE_TIPS_IT; + eeprom_menu.readTips = EEPROM_READ_TIPS_IT; + eeprom_menu.revertTips = EEPROM_REVERT_TIPS_IT; + break; + + #endif // if 1 + + default: + common_menu.dialog_confirm_title = TITLE_DIALOG_CONFIRM_EN; + common_menu.text_back = BACK_TEXT_EN; + common_menu.close_machine_tips = DIALOG_CLOSE_MACHINE_EN; + common_menu.unbind_printer_tips = DIALOG_UNBIND_PRINTER_EN; + common_menu.print_special_title = PRINTING_OTHER_LANGUGE; + common_menu.pause_special_title = PRINTING_PAUSE_OTHER_LANGUGE; + common_menu.operate_special_title = PRINTING_OPERATION_OTHER_LANGUGE; + // + main_menu.title = TITLE_READYPRINT_EN; + main_menu.preheat = PREHEAT_TEXT_EN; + main_menu.move = MOVE_TEXT_EN; + main_menu.home = HOME_TEXT_EN; + main_menu.print = PRINT_TEXT_EN; + main_menu.extrude = EXTRUDE_TEXT_EN; + main_menu.leveling = LEVELING_TEXT_EN; + main_menu.autoleveling = AUTO_LEVELING_TEXT_EN; + main_menu.fan = FAN_TEXT_EN; + main_menu.set = SET_TEXT_EN; + main_menu.more = MORE_TEXT_EN; + main_menu.tool = TOOL_TEXT_EN; + // TOOL + tool_menu.title = TOOL_TEXT_EN; + tool_menu.preheat = TOOL_PREHEAT_EN; + tool_menu.extrude = TOOL_EXTRUDE_EN; + tool_menu.move = TOOL_MOVE_EN; + tool_menu.home = TOOL_HOME_EN; + tool_menu.leveling = TOOL_LEVELING_EN; + tool_menu.autoleveling = TOOL_AUTO_LEVELING_EN; + tool_menu.filament = TOOL_FILAMENT_EN; + tool_menu.more = TOOL_MORE_EN; + // + preheat_menu.adjust_title = TITLE_ADJUST_EN; + preheat_menu.title = TITLE_PREHEAT_EN; + preheat_menu.add = ADD_TEXT_EN; + preheat_menu.dec = DEC_TEXT_EN; + preheat_menu.ext1 = EXTRUDER_1_TEXT_EN; + preheat_menu.ext2 = EXTRUDER_2_TEXT_EN; + preheat_menu.hotbed = HEATBED_TEXT_EN; + preheat_menu.off = CLOSE_TEXT_EN; + // + move_menu.title = TITLE_MOVE_EN; + // + home_menu.title = TITLE_HOME_EN; + home_menu.stopmove = HOME_STOPMOVE_EN; + // + file_menu.title = TITLE_CHOOSEFILE_EN; + file_menu.page_up = PAGE_UP_TEXT_EN; + file_menu.page_down = PAGE_DOWN_TEXT_EN; + file_menu.file_loading = FILE_LOADING_EN; + file_menu.no_file = NO_FILE_EN; + file_menu.no_file_and_check = NO_FILE_EN;// NO_FILE_AND_CHECK_EN; + // + extrude_menu.title = TITLE_EXTRUDE_EN; + extrude_menu.in = EXTRUDER_IN_TEXT_EN; + extrude_menu.out = EXTRUDER_OUT_TEXT_EN; + extrude_menu.ext1 = EXTRUDER_1_TEXT_EN; + extrude_menu.ext2 = EXTRUDER_2_TEXT_EN; + extrude_menu.low = EXTRUDE_LOW_SPEED_TEXT_EN; + extrude_menu.normal = EXTRUDE_MEDIUM_SPEED_TEXT_EN; + extrude_menu.high = EXTRUDE_HIGH_SPEED_TEXT_EN; + extrude_menu.temper_text = EXTRUDER_TEMP_TEXT_EN; + // + leveling_menu.title = TITLE_LEVELING_EN; + leveling_menu.position1 = LEVELING_POINT1_TEXT_EN; + leveling_menu.position2 = LEVELING_POINT2_TEXT_EN; + leveling_menu.position3 = LEVELING_POINT3_TEXT_EN; + leveling_menu.position4 = LEVELING_POINT4_TEXT_EN; + leveling_menu.position5 = LEVELING_POINT5_TEXT_EN; + // + set_menu.title = TITLE_SET_EN; + set_menu.filesys = FILESYS_TEXT_EN; + set_menu.wifi = WIFI_TEXT_EN; + set_menu.about = ABOUT_TEXT_EN; + set_menu.fan = FAN_TEXT_EN; + set_menu.filament = FILAMENT_TEXT_EN; + set_menu.breakpoint = BREAK_POINT_TEXT_EN; + set_menu.motoroff = MOTOR_OFF_TEXT_EN; + set_menu.motoroffXY = MOTOR_OFF_XY_TEXT_EN; + set_menu.language = LANGUAGE_TEXT_EN; + set_menu.shutdown = SHUTDOWN_TEXT_EN; + set_menu.machine_para = MACHINE_PARA_EN; + set_menu.eepromSet = EEPROM_SETTINGS_EN; + // + more_menu.title = TITLE_MORE_EN; + // + filesys_menu.title = TITLE_FILESYS_EN; + filesys_menu.sd_sys = SD_CARD_TEXT_EN; + filesys_menu.usb_sys = U_DISK_TEXT_EN; + // WIFI + wifi_menu.title = WIFI_TEXT; + // wifi_menu.key = WIFI_KEY_TEXT_EN; + // wifi_menu.ip = WIFI_IP_TEXT_EN; + // wifi_menu.state = WIFI_STA_TEXT_EN; + wifi_menu.cloud = CLOUD_TEXT_EN; + wifi_menu.reconnect = WIFI_RECONNECT_TEXT_EN; + + cloud_menu.title = TITLE_CLOUD_TEXT_EN; + cloud_menu.bind = CLOUD_BINDED_EN; + cloud_menu.binded = CLOUD_BINDED_EN; + cloud_menu.unbind = CLOUD_UNBIND_EN; + cloud_menu.unbinding = CLOUD_UNBINDED_EN; + cloud_menu.disconnected = CLOUD_DISCONNECTED_EN; + cloud_menu.disable = CLOUD_DISABLE_EN; + // + about_menu.title = TITLE_ABOUT_EN; + about_menu.type = ABOUT_TYPE_TEXT_EN; + about_menu.version = ABOUT_VERSION_TEXT_EN; + about_menu.wifi = ABOUT_WIFI_TEXT_EN; + // + fan_menu.title = TITLE_FAN_EN; + fan_menu.add = FAN_ADD_TEXT_EN; + fan_menu.dec = FAN_DEC_TEXT_EN; + fan_menu.state = FAN_TIPS1_TEXT_EN; + // + filament_menu.title = TITLE_FILAMENT_EN; + filament_menu.in = FILAMENT_IN_TEXT_EN; + filament_menu.out = FILAMENT_OUT_TEXT_EN; + filament_menu.ext1 = FILAMENT_EXT0_TEXT_EN; + filament_menu.ext2 = FILAMENT_EXT1_TEXT_EN; + filament_menu.ready_replace = FILAMENT_CHANGE_TEXT_EN; + filament_menu.filament_dialog_load_heat = FILAMENT_DIALOG_LOAD_HEAT_TIPS_EN; + filament_menu.filament_dialog_load_heat_confirm = FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_EN; + filament_menu.filament_dialog_loading = FILAMENT_DIALOG_LOADING_TIPS_EN; + filament_menu.filament_dialog_load_completed = FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_EN; + filament_menu.filament_dialog_unload_heat = FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_EN; + filament_menu.filament_dialog_unload_heat_confirm = FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_EN; + filament_menu.filament_dialog_unloading = FILAMENT_DIALOG_UNLOADING_TIPS_EN; + filament_menu.filament_dialog_unload_completed = FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_EN; + + // + language_menu.title = TITLE_LANGUAGE_EN; + language_menu.next = PAGE_DOWN_TEXT_EN; + language_menu.up = PAGE_UP_TEXT_EN; + // + printing_menu.title = TITLE_PRINTING_EN; + printing_menu.option = PRINTING_OPERATION_EN; + printing_menu.stop = PRINTING_STOP_EN; + printing_menu.pause = PRINTING_PAUSE_EN; + printing_menu.resume = PRINTING_RESUME_EN; + + // + operation_menu.title = TITLE_OPERATION_EN; + operation_menu.pause = PRINTING_PAUSE_EN; + operation_menu.stop = PRINTING_STOP_EN; + operation_menu.temp = PRINTING_TEMP_EN; + operation_menu.fan = FAN_TEXT_EN; + operation_menu.extr = PRINTING_EXTRUDER_EN; + operation_menu.speed = PRINTING_CHANGESPEED_EN; + operation_menu.filament = FILAMENT_TEXT_EN; + operation_menu.more = PRINTING_MORE_EN; + operation_menu.move = PRINTING_MOVE_EN; + operation_menu.auto_off = AUTO_SHUTDOWN_EN; + operation_menu.manual_off = MANUAL_SHUTDOWN_EN; + // + pause_menu.title = TITLE_PAUSE_EN; + pause_menu.resume = PRINTING_RESUME_EN; + pause_menu.stop = PRINTING_STOP_EN; + pause_menu.extrude = PRINTING_EXTRUDER_EN; + pause_menu.move = PRINTING_MOVE_EN; + pause_menu.filament = FILAMENT_TEXT_EN; + pause_menu.more = PRINTING_MORE_EN; + + // + speed_menu.title = TITLE_CHANGESPEED_EN; + speed_menu.add = ADD_TEXT_EN; + speed_menu.dec = DEC_TEXT_EN; + speed_menu.move = MOVE_SPEED_EN; + speed_menu.extrude = EXTRUDER_SPEED_EN; + speed_menu.extrude_speed = EXTRUDER_SPEED_STATE_EN; + speed_menu.move_speed = MOVE_SPEED_STATE_EN; + // + printing_more_menu.title = TITLE_MORE_EN; + printing_more_menu.fan = FAN_TEXT_EN; + printing_more_menu.auto_close = AUTO_SHUTDOWN_EN; + printing_more_menu.manual = MANUAL_SHUTDOWN_EN; + printing_more_menu.speed = PRINTING_CHANGESPEED_EN; + printing_more_menu.temp = PRINTING_TEMP_EN; + + // print_file_dialog_menu.title = TITLE_DIALOG_CONFIRM_EN; + print_file_dialog_menu.confirm = DIALOG_CONFIRM_EN; + print_file_dialog_menu.cancle = DIALOG_CANCLE_EN; + print_file_dialog_menu.print_file = DIALOG_PRINT_MODEL_EN; + print_file_dialog_menu.cancle_print = DIALOG_CANCEL_PRINT_EN; + print_file_dialog_menu.retry = DIALOG_RETRY_EN; + print_file_dialog_menu.stop = DIALOG_STOP_EN; + print_file_dialog_menu.no_file_print_tips = DIALOG_ERROR_TIPS1_EN; + print_file_dialog_menu.print_from_breakpoint = DIALOG_REPRINT_FROM_BREAKPOINT_EN; + print_file_dialog_menu.close_machine_error = DIALOG_ERROR_TIPS2_EN; + print_file_dialog_menu.filament_no_press = DIALOG_FILAMENT_NO_PRESS_EN; + print_file_dialog_menu.print_finish = DIALOG_PRINT_FINISH_EN; + print_file_dialog_menu.print_time = DIALOG_PRINT_TIME_EN; + print_file_dialog_menu.reprint = DIALOG_REPRINT_EN; + print_file_dialog_menu.wifi_enable_tips = DIALOG_WIFI_ENABLE_TIPS_EN; + + pause_msg_menu.pausing = MESSAGE_PAUSING_EN; + pause_msg_menu.changing = MESSAGE_CHANGING_EN; + pause_msg_menu.unload = MESSAGE_UNLOAD_EN; + pause_msg_menu.waiting = MESSAGE_WAITING_EN; + pause_msg_menu.insert = MESSAGE_INSERT_EN; + pause_msg_menu.load = MESSAGE_LOAD_EN; + pause_msg_menu.purge = MESSAGE_PURGE_EN; + pause_msg_menu.resume = MESSAGE_RESUME_EN; + pause_msg_menu.heat = MESSAGE_HEAT_EN; + pause_msg_menu.heating = MESSAGE_HEATING_EN; + pause_msg_menu.option = MESSAGE_OPTION_EN; + pause_msg_menu.purgeMore = MESSAGE_PURGE_MORE_EN; + pause_msg_menu.continuePrint = MESSAGE_CONTINUE_PRINT_EN; + eeprom_menu.title = EEPROM_SETTINGS_TITLE_EN; + eeprom_menu.store = EEPROM_SETTINGS_STORE_EN; + eeprom_menu.read = EEPROM_SETTINGS_READ_EN; + eeprom_menu.revert = EEPROM_SETTINGS_REVERT_EN; + eeprom_menu.storeTips = EEPROM_STORE_TIPS_EN; + eeprom_menu.readTips = EEPROM_READ_TIPS_EN; + eeprom_menu.revertTips = EEPROM_REVERT_TIPS_EN; + break; + } +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.h b/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.h new file mode 100644 index 000000000000..675fd41f168e --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.h @@ -0,0 +1,837 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "tft_Language_en.h" +#include "tft_Language_s_cn.h" +#include "tft_Language_t_cn.h" +#include "tft_Language_ru.h" +#include "tft_Language_fr.h" +#include "tft_Language_sp.h" +#include "tft_Language_it.h" + +extern void disp_language_init(); + +#define LANG_SIMPLE_CHINESE 1 +#define LANG_COMPLEX_CHINESE 2 +#define LANG_ENGLISH 3 +#define LANG_JAPAN 4 +#define LANG_GERMAN 5 +#define LANG_FRENCH 6 +#define LANG_RUSSIAN 7 +#define LANG_KOREAN 8 +#define LANG_TURKISH 9 +#define LANG_SPANISH 10 +#define LANG_GREEK 11 +#define LANG_ITALY 12 +#define LANG_PORTUGUESE 13 + +#define MULTI_LANGUAGE_ENABLE 1 +#define MULTI_LANGUAGE_DISABLE 0 + +typedef struct machine_common_disp{ + const char *default_value; + + const char *next; + const char *previous; + + const char *MachineConfigTitle; + const char *MachineType; + const char *Stroke; + const char *HomeDir; + const char *EndStopType; + const char *FilamentConf; + + const char *MachineTypeConfTitle; + const char *xyz; + const char *delta; + const char *corexy; + + const char *StrokeConfTitle; + const char *xStroke; + const char *yStroke; + const char *zStroke; + + const char *xmin; + const char *ymin; + const char *zmin; + + const char *HomeDirConfTitle; + const char *xHomeDir; + const char *yHomeDir; + const char *zHomeDir; + const char *min; + const char *max; + + const char *EndstopConfTitle; + const char *xEndstop_min; + const char *yEndstop_min; + const char *zEndstop_min; + const char *xEndstop_max; + const char *yEndstop_max; + const char *zEndstop_max; + const char *FilamentEndstop; + const char *LevelingEndstop; + const char *opened; + const char *closed; + + const char *FilamentConfTitle; + const char *InLength; + const char *InSpeed; + const char *FilamentTemperature; + const char *OutLength; + const char *OutSpeed; + + const char *LevelingParaConfTitle; + const char *LevelingParaConf; + const char *LevelingManuPosConf; + const char *LevelingAutoCommandConf; + const char *LevelingAutoZoffsetConf; + + const char *LevelingSubConfTitle; + const char *AutoLevelEnable; + const char *BLtouchEnable; + const char *ProbePort; + const char *ProbeXoffset; + const char *ProbeYoffset; + const char *ProbeZoffset; + const char *ProbeXYspeed; + const char *ProbeZspeed; + const char *enable; + const char *disable; + const char *z_min; + const char *z_max; + + const char *LevelingSubDeltaConfTitle; + const char *MachineRadius; + const char *DiagonalRod; + const char *PrintableRadius; + const char *DeltaHeight; + const char *SmoothRodOffset; + const char *EffectorOffset; + const char *CalibrationRadius; + + const char *LevelingSubXYZConfTitle; + //const char *Level_positon1; + //const char *Level_positon2; + //const char *Level_positon3; + //const char *Level_positon4; + + const char *TemperatureConfTitle; + const char *NozzleConf; + const char *HotBedConf; + const char *PreheatTemperConf; + + const char *NozzleCnt; + const char *NozzleConfTitle; + const char *NozzleType; + const char *NozzleAdjustType; + const char *NozzleMinTemperature; + const char *NozzleMaxTemperature; + const char *Extrude_Min_Temper; + + const char *HotbedEnable; + const char *HotbedConfTitle; + const char *HotbedAjustType; + const char *HotbedMinTemperature; + const char *HotbedMaxTemperature; + + const char *MotorConfTitle; + const char *MaxFeedRateConf; + const char *AccelerationConf; + const char *JerkConf; + const char *StepsConf; + const char *MotorDirConf; + const char *HomeFeedRateConf; + const char *TMCcurrentConf; + const char *TMCStepModeConf; + const char *HomingSensitivityConf; + + const char *MaxFeedRateConfTitle; + const char *XMaxFeedRate; + const char *YMaxFeedRate; + const char *ZMaxFeedRate; + const char *E0MaxFeedRate; + const char *E1MaxFeedRate; + + const char *AccelerationConfTitle; + const char *PrintAcceleration; + const char *RetractAcceleration; + const char *TravelAcceleration; + const char *X_Acceleration; + const char *Y_Acceleration; + const char *Z_Acceleration; + const char *E0_Acceleration; + const char *E1_Acceleration; + + const char *JerkConfTitle; + const char *X_Jerk; + const char *Y_Jerk; + const char *Z_Jerk; + const char *E_Jerk; + + const char *StepsConfTitle; + const char *X_Steps; + const char *Y_Steps; + const char *Z_Steps; + const char *E0_Steps; + const char *E1_Steps; + + const char *TmcCurrentConfTitle; + const char *X_Current; + const char *Y_Current; + const char *Z_Current; + const char *E0_Current; + const char *E1_Current; + + const char *TmcStepModeConfTitle; + const char *X_StepMode; + const char *Y_StepMode; + const char *Z_StepMode; + const char *E0_StepMode; + const char *E1_StepMode; + + const char *HomingSensitivityConfTitle; + const char *X_Sensitivity; + const char *Y_Sensitivity; + const char *Z_Sensitivity; + const char *Z2_Sensitivity; + + const char *MotorDirConfTitle; + const char *X_MotorDir; + const char *Y_MotorDir; + const char *Z_MotorDir; + const char *E0_MotorDir; + const char *E1_MotorDir; + const char *Invert_1; + const char *Invert_0; + + const char *HomeFeedRateConfTitle; + const char *XY_HomeFeedRate; + const char *Y_HomeFeedRate; + const char *Z_HomeFeedRate; + + const char *AdvancedConfTitle; + const char *PwrOffDection; + const char *PwrOffAfterPrint; + const char *HaveUps; + const char *Z2andZ2Endstop; + const char *EnablePinsInvert; + const char *PausePosition; + const char *WifiSettings; + const char *EncoderSettings; + + const char *Z2ConfTitle; + const char *Z2Enable; + const char *Z2EndstopEnable; + const char *Z2Port; + + const char *EnablePinsInvertTitle; + const char *XInvert; + const char *YInvert; + const char *ZInvert; + const char *EInvert; + + const char *key_1; + const char *key_2; + const char *key_3; + const char *key_4; + const char *key_5; + const char *key_6; + const char *key_7; + const char *key_8; + const char *key_9; + const char *key_0; + const char *key_point; + const char *key_back; + const char *key_reset; + const char *key_confirm; + const char *negative; + const char *low_level; + const char *high_level; + + const char *PausePosText; + const char *xPos; + const char *yPos; + const char *zPos; + + const char *WifiConfTitle; + const char *wifiMode; + const char *wifiName; + const char *wifiPassWord; + const char *wifiCloud; + const char *wifiConfig; + const char *wifiEdit; + const char *wifiConfigTips; + + const char *OffsetConfTitle; + const char *Xoffset; + const char *Yoffset; + const char *Zoffset; + + const char *EncoderConfTitle; + const char *EncoderConfText; + +} machine_common_def; + +extern machine_common_def machine_menu; + +typedef struct common_menu_disp { + const char *text_back; + const char *dialog_confirm_title; + const char *close_machine_tips; + const char *unbind_printer_tips; + const char *print_special_title; + const char *pause_special_title; + const char *operate_special_title; + const char *next; + const char *previous; +} common_menu_def; + +extern common_menu_def common_menu; + +typedef struct main_menu_disp { + const char *title; + const char *preheat; + const char *move; + const char *home; + const char *print; + const char *extrude; + const char *leveling; + const char *autoleveling; + const char *fan; + const char *set; + const char *tool; + const char *more; + const char *machine_para; +} main_menu_def; + +extern main_menu_def main_menu; + +typedef struct preheat_menu_disp { + const char *adjust_title; + const char *title; + const char *add; + const char *dec; + const char *ext1; + const char *ext2; + const char *hotbed; + const char *off; + const char *step_1c; + const char *step_5c; + const char *step_10c; + const char *back; + + const char *value_state; + + const char *dialog_tips; + +} preheat_menu_def; + +extern preheat_menu_def preheat_menu; + +typedef struct move_menu_disp { + const char *title; + const char *x_add; + const char *x_dec; + const char *y_add; + const char *y_dec; + const char *z_add; + const char *z_dec; + const char *step_001mm; + const char *step_005mm; + const char *step_01mm; + const char *step_1mm; + const char *step_10mm; + const char *back; +} move_menu_def; + +extern move_menu_def move_menu; + +typedef struct home_menu_disp { + const char *title; + const char *home_all; + const char *home_x; + const char *home_y; + const char *home_z; + const char *stopmove; + const char *back; +} home_menu_def; + +extern home_menu_def home_menu; + +typedef struct file_menu_disp { + const char *title; + const char *page_up; + const char *page_down; + const char *back; + + const char *file_loading; + const char *no_file; + const char *no_file_and_check; + +} file_menu_def; + +extern file_menu_def file_menu; + +typedef struct extrude_menu_disp { + const char *title; + const char *in; + const char *out; + const char *ext1; + const char *ext2; + const char *step_1mm; + const char *step_5mm; + const char *step_10mm; + const char *low; + const char *normal; + const char *high; + const char *back; + + const char *count_value_mm; + const char *count_value_cm; + const char *count_value_m; + const char *temp_value; + const char *temper_text; +} extrude_menu_def; + +extern extrude_menu_def extrude_menu; + +typedef struct leveling_menu_disp { + const char *title; + const char *position1; + const char *position2; + const char *position3; + const char *position4; + const char *position5; + + char *back; +} leveling_menu_def; + +extern leveling_menu_def leveling_menu; + +typedef struct set_menu_disp { + const char *title; + const char *filesys; + const char *wifi; + const char *about; + const char *fan; + const char *filament; + const char *breakpoint; + const char *motoroff; + const char *motoroffXY; + const char *shutdown; + const char *language; + const char *machine_para; + const char *eepromSet; + const char *back; +} set_menu_def; + +extern set_menu_def set_menu; + +typedef struct filesys_menu_disp { + const char *title; + const char *filesys; + const char *sd_sys; + const char *usb_sys; + const char *back; +} filesys_menu_def; + +extern filesys_menu_def filesys_menu; + +typedef struct more_menu_disp { + const char *title; + const char *back; +} more_menu_def; + +extern more_menu_def more_menu; + +typedef struct wifi_menu_disp { + const char *title; + const char *ip; + const char *wifi; + const char *key; + const char *state_ap; + const char *state_sta; + const char *cloud; + const char *connected; + const char *disconnected; + const char *exception; + const char *back; + const char *reconnect; +} wifi_menu_def; + +extern wifi_menu_def wifi_menu; + +typedef struct cloud_menu_disp { + const char *title; + const char *unbind; + const char *unbinding; + const char *unbinded; + const char *bind; + const char *binding; + const char *binded; + const char *disable; + const char *disconnected; + const char *back; + const char *unbind_printer_tips; +} cloud_menu_def; + +extern cloud_menu_def cloud_menu; + +typedef struct about_menu_disp { + const char *title; + const char *type_name; + const char *firmware_v; + const char *type; + const char *version; + const char *wifi; + const char *type_robin; + const char *type_robin_mini; + const char *back; +} about_menu_def; + +extern about_menu_def about_menu; + +typedef struct fan_menu_disp { + const char *title; + const char *add; + const char *dec; + const char *full; + const char *half; + const char *off; + const char *back; + + const char *state; + const char *state_value; +} fan_menu_def; + +extern fan_menu_def fan_menu; + +typedef struct filament_menu_disp { + const char *title; + const char *in; + const char *out; + const char *ext1; + const char *ext2; + const char *back; + const char *stat_temp; + const char *ready_replace; + const char *replacing; + const char *loading; + const char *unloading; + const char *heating; + const char *complete_and_back; + const char *filament_dialog_load_heat; + const char *filament_dialog_unload_heat; + const char *filament_dialog_load_heat_confirm; + const char *filament_dialog_unload_heat_confirm; + const char *filament_dialog_loading; + const char *filament_dialog_unloading; + const char *filament_dialog_load_completed; + const char *filament_dialog_unload_completed; + const char *filament_dialog_ok; + const char *filament_dialog_back; +} filament_menu_def; + +extern filament_menu_def filament_menu; + +typedef struct language_menu { + const char *title; + const char *chinese_s; + const char *chinese_t; + const char *english; + const char *russian; + const char *japan; + const char *italy; + const char *german; + const char *spanish; + const char *korean; + const char *french; + const char *brazil; + const char *portuguese; + const char *next; + const char *up; + const char *back; +} language_menu_def; + +extern language_menu_def language_menu; + +typedef struct printing_menu_disp { + const char *title; + const char *option; + const char *temp1; + const char *temp2; + const char *bed_temp; + const char *fan_speed; + const char *pause; + const char *resume; + const char *stop; +} printing_menu_def; + +extern printing_menu_def printing_menu; + +typedef struct operation_menu_disp { + const char *title; + const char *pause; + const char *stop; + const char *temp; + const char *fan; + const char *filament; + const char *extr; + const char *speed; + const char *move; + const char *more; + const char *auto_off; + const char *manual_off; + const char *back; + const char *babystep; +} operation_menu_def; + +extern operation_menu_def operation_menu; + +typedef struct pause_menu_disp { + const char *title; + const char *resume; + const char *stop; + const char *extrude; + const char *move; + const char *filament; + const char *more; +} pause_menu_def; + +extern pause_menu_def pause_menu; + +typedef struct speed_menu_disp { + const char *title; + const char *add; + const char *dec; + const char *extrude; + const char *move; + const char *step_1percent; + const char *step_5percent; + const char *step_10percent; + const char *back; + const char *move_speed; + const char *extrude_speed; +} speed_menu_def; + +extern speed_menu_def speed_menu; + +typedef struct printing_more_menu_disp { + const char *title; + const char *fan; + const char *auto_close; + const char *manual; + const char *temp; + const char *speed; + const char *back; +} printing_more_menu_def; + +extern printing_more_menu_def printing_more_menu; + +typedef struct dialog_menu_disp { + const char *confirm_title; + + const char *error1_repint_no_file; + const char *error2_communication_fail; + const char *error3_filename_too_long; + const char *error4_no_file; + const char *error5_check_filesys; + + const char *tip1_print_file; + const char *tip2_stop_file; +} dialog_menu_def; + +extern dialog_menu_def dialog_menu; + +typedef struct print_file_dialog_disp { + const char *title; + const char *confirm; + const char *cancle; + const char *print_file; + const char *cancle_print; + const char *retry; + const char *stop; + const char *no_file_print_tips; + const char *print_from_breakpoint; + const char *file_name_too_long_error; + const char *close_machine_error; + const char *filament_no_press; + const char *print_finish; + const char *print_time; + const char *reprint; + const char *wifi_enable_tips; +} print_file_dialog_menu_def; + +extern print_file_dialog_menu_def print_file_dialog_menu; + +typedef struct tool_menu_disp { + const char *title; + const char *preheat; + const char *extrude; + const char *move; + const char *home; + const char *leveling; + const char *autoleveling; + const char *filament; + const char *more; + const char *back; +} tool_menu_def; + +extern tool_menu_def tool_menu; + +typedef struct MachinePara_menu_disp { + const char *title; + const char *MachineSetting; + const char *MotorSetting; + const char *leveling; + const char *AdvanceSetting; +} MachinePara_menu_def; + +extern MachinePara_menu_def MachinePara_menu; + +typedef struct pause_msg_disp { + const char *pausing; + const char *changing; + const char *unload; + const char *waiting; + const char *insert; + const char *load; + const char *purge; + const char *resume; + const char *heat; + const char *heating; + const char *option; + const char *purgeMore; + const char *continuePrint; +} pause_msg_def; + +extern pause_msg_def pause_msg_menu; + +typedef struct eeprom_disp{ + const char *title; + const char *store; + const char *read; + const char *revert; + const char *storeTips; + const char *readTips; + const char *revertTips; +} eeprom_def; + +extern eeprom_def eeprom_menu; +/*****************************************/ +//********************************************// +//#if defined(TFT70) +// +//#elif defined(TFT35) +#define TEXT_VALUE "%d/%d" +//#endif + +#define TEXT_VALUE_T ": %d℃" +#define TEXT_VALUE_mm ": %dmm" +#define TEXT_VALUE_cm ": %dcm" +#define TEXT_VALUE_m ": %dm" + +#define TEMP_UNIT_SYBOL "%d℃" +#define FLOAT_TEMP_UNIT_SYBOL "%.1f℃" + +#define TEXT_1C "1℃" +#define TEXT_5C "5℃" +#define TEXT_10C "10℃" + +#define AXIS_X_ADD_TEXT "X+" +#define AXIS_X_DEC_TEXT "X-" +#define AXIS_Y_ADD_TEXT "Y+" +#define AXIS_Y_DEC_TEXT "Y-" +#define AXIS_Z_ADD_TEXT "Z+" +#define AXIS_Z_DEC_TEXT "Z-" +#define TEXT_001MM "0.01mm" +#define TEXT_005MM "0.05mm" +#define TEXT_01MM "0.1mm" +#define TEXT_1MM "1mm" +#define TEXT_10MM "10mm" + +#define EXTRUDE_1MM_TEXT "1mm" +#define EXTRUDE_5MM_TEXT "5mm" +#define EXTRUDE_10MM_TEXT "10mm" + +#define STEP_1PERCENT "1%" +#define STEP_5PERCENT "5%" +#define STEP_10PERCENT "10%" + +#define LANGUAGE_S_CN "简体" +#define LANGUAGE_T_CN "繁体" +#define LANGUAGE_EN "English" +#define LANGUAGE_JP "日本語" +#define LANGUAGE_GE "Deutsch" +#define LANGUAGE_FR "français" +#define LANGUAGE_IT "Italiano" +#define LANGUAGE_PR "português" +#define LANGUAGE_KR "Korean" +#define LANGUAGE_BR "Brazil" +#define LANGUAGE_RU "русский" +#define LANGUAGE_SP "español" + +#define HOME_X_TEXT "X" +#define HOME_Y_TEXT "Y" +#define HOME_Z_TEXT "Z" +#define HOME_ALL_TEXT "All" +//#if defined(MKS_ROBIN_NANO) +#define ABOUT_TYPE_TEXT "MKS Robin Pro" +//#elif defined(MKS_ROBIN_MINI) +//#define ABOUT_TYPE_TEXT "MKS Robin Mini" +//#endif +#define ABOUT_VERSION_TEXT "1.0.0" +//#define ABOUT_WIFI_TEXT "WiFi:" + +#define FAN_OPEN_TEXT "100%" +#define FAN_HALF_TEXT "50%" +#define FAN_CLOSE_TEXT "0%" +//#define FAN_TIPS1_TEXT "FAN" +//#define FAN_TIPS2_TEXT "FAN\nClose" + +#define WIFI_TEXT "WIFI" +#define WIFI_IP_TEXT "IP: " +#define WIFI_NAME_TEXT "WiFi: " +#define WIFI_KEY_TEXT "Key: " +#define WIFI_STATE_AP_TEXT "State: AP" +#define WIFI_STATE_STA_TEXT "State: STA" +#define WIFI_CONNECTED_TEXT "Connected" +#define WIFI_DISCONNECTED_TEXT "Disconnected" +#define WIFI_EXCEPTION_TEXT "Exception" + +#define FILAMENT_TIPS2_TEXT "T:" + +#define DIALOG_UPLOAD_ING_EN "Uploading......" +#define DIALOG_UPLOAD_ERROR_EN "Upload error" +#define DIALOG_UPLOAD_FINISH_EN "Upload finished" +#define DIALOG_UPLOAD_SIZE_EN "Size" +#define DIALOG_UPLOAD_TIME_EN "Time" +#define DIALOG_UPLOAD_SPEED_EN "Speed" +#define DIALOG_UPDATE_WIFI_FIRMWARE_EN "Updating wifi model firmware" +#define DIALOG_UPDATE_WIFI_WEB_EN "Updating wifi model web data" +#define DIALOG_UPDATE_NO_DEVICE_EN "please check \nwether memory device insert!" + +#define ZOFFSET_STEP001 "0.01mm" +#define ZOFFSET_STEP01 "0.1mm" +#define ZOFFSET_STEP1 "1mm" diff --git a/Marlin/src/lcd/extui/lib/mks_ui/wifiSerial.cpp b/Marlin/src/lcd/extui/lib/mks_ui/wifiSerial.cpp new file mode 100644 index 000000000000..01c86ad7cb47 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/wifiSerial.cpp @@ -0,0 +1,120 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "draw_ui.h" +#include "wifiSerial.h" + +#if ENABLED(USE_WIFI_FUNCTION) + +#include +#include +#include +#include +#include + +#include "../../../../MarlinCore.h" + +DEFINE_WFSERIAL(WifiSerial1, 1); + +WifiSerial::WifiSerial(usart_dev *usart_device, uint8 tx_pin, uint8 rx_pin) { + this->usart_device = usart_device; + this->tx_pin = tx_pin; + this->rx_pin = rx_pin; +} + +/** + * Set up / tear down + */ +#if STM32_MCU_SERIES == STM32_SERIES_F1 + /* F1 MCUs have no GPIO_AFR[HL], so turn off PWM if there's a conflict + * on this GPIO bit. */ + static void disable_timer_if_necessary(timer_dev *dev, uint8 ch) { + if (dev != nullptr) timer_set_mode(dev, ch, TIMER_DISABLED); + } +#elif STM32_MCU_SERIES == STM32_SERIES_F2 || STM32_MCU_SERIES == STM32_SERIES_F4 + #define disable_timer_if_necessary(dev, ch) ((void)0) +#else + #warning "Unsupported STM32 series; timer conflicts are possible" +#endif + +void WifiSerial::begin(uint32 baud) { begin(baud, SERIAL_8N1); } + +/** + * Roger Clark. + * Note. The config parameter is not currently used. This is a work in progress. + * Code needs to be written to set the config of the hardware serial control register in question. + */ + +void WifiSerial::begin(uint32 baud, uint8_t config) { + //ASSERT(baud <= this->usart_device->max_baud); // Roger Clark. Assert doesn't do anything useful, we may as well save the space in flash and ram etc + + if (baud > this->usart_device->max_baud) return; + + const stm32_pin_info *txi = &PIN_MAP[this->tx_pin], + *rxi = &PIN_MAP[this->rx_pin]; + + disable_timer_if_necessary(txi->timer_device, txi->timer_channel); + + usart_init(this->usart_device); + + // Reinitialize the receive buffer, mks_esp8266 fixed data frame length is 1k bytes + rb_init(this->usart_device->rb, WIFI_RX_BUF_SIZE, wifiRxBuf); + + usart_config_gpios_async(this->usart_device, + rxi->gpio_device, rxi->gpio_bit, + txi->gpio_device, txi->gpio_bit, + config); + usart_set_baud_rate(this->usart_device, USART_USE_PCLK, baud); + usart_enable(this->usart_device); +} + +void WifiSerial::end(void) { + usart_disable(this->usart_device); +} + +int WifiSerial::available(void) { + return usart_data_available(this->usart_device); +} + +// +// I/O +// + +int WifiSerial::read(void) { + if (usart_data_available(usart_device) <= 0) return -1; + return usart_getc(usart_device); +} + +int WifiSerial::write(unsigned char ch) { + usart_putc(this->usart_device, ch); + return 1; +} + +int WifiSerial::wifi_rb_is_full(void) { + return rb_is_full(this->usart_device->rb); +} + +#endif // USE_WIFI_FUNCTION +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/wifiSerial.h b/Marlin/src/lcd/extui/lib/mks_ui/wifiSerial.h new file mode 100644 index 000000000000..9d3946fee79b --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/wifiSerial.h @@ -0,0 +1,102 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "tft_lvgl_configuration.h" + +#if ENABLED(USE_WIFI_FUNCTION) + +#if SERIAL_PORT_2 != -1 + #error "SERIAL_PORT_2 must be set to -1 with HAS_TFT_LVGL_UI and USE_WIFI_FUNCTION." +#endif + +#define WIFI_BAUDRATE 115200 +#define WIFI_UPLOAD_BAUDRATE 1958400 +#define USART_SAFE_INSERT + +#define WIFI_RX_BUF_SIZE (1024+1) + +#include +#include +#include +#include +#include +#include + +#define DEFINE_WFSERIAL(name, n)\ + WifiSerial name(USART##n, \ + BOARD_USART##n##_TX_PIN, \ + BOARD_USART##n##_RX_PIN) + +class WifiSerial { + public: + uint8 wifiRxBuf[WIFI_RX_BUF_SIZE]; + + public: + WifiSerial(struct usart_dev *usart_device, uint8 tx_pin, uint8 rx_pin); + + /* Set up/tear down */ + void begin(uint32 baud); + void begin(uint32 baud,uint8_t config); + void end(); + int available(void); + int read(void); + int write(uint8_t); + inline void wifi_usart_irq(usart_reg_map *regs) { + /* Handling RXNEIE and TXEIE interrupts. + * RXNE signifies availability of a byte in DR. + * + * See table 198 (sec 27.4, p809) in STM document RM0008 rev 15. + * We enable RXNEIE. + */ + if ((regs->CR1 & USART_CR1_RXNEIE) && (regs->SR & USART_SR_RXNE)) { + #ifdef USART_SAFE_INSERT + /* If the buffer is full and the user defines USART_SAFE_INSERT, + * ignore new bytes. */ + rb_safe_insert(this->usart_device->rb, (uint8)regs->DR); + #else + /* By default, push bytes around in the ring buffer. */ + rb_push_insert(this->usart_device->rb, (uint8)regs->DR); + #endif + } + /* TXE signifies readiness to send a byte to DR. */ + if ((regs->CR1 & USART_CR1_TXEIE) && (regs->SR & USART_SR_TXE)) { + if (!rb_is_empty(this->usart_device->wb)) + regs->DR=rb_remove(this->usart_device->wb); + else + regs->CR1 &= ~((uint32)USART_CR1_TXEIE); // disable TXEIE + } + } + + int wifi_rb_is_full(void); + + private: + struct usart_dev *usart_device; + uint8 tx_pin; + uint8 rx_pin; +}; + +extern WifiSerial WifiSerial1; + +#define WIFISERIAL WifiSerial1 + +#endif // USE_WIFI_FUNCTION diff --git a/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.cpp b/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.cpp new file mode 100644 index 000000000000..f5d954792ead --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.cpp @@ -0,0 +1,1927 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "draw_ui.h" +#include "wifi_module.h" +#include "wifi_upload.h" + +#if ENABLED(USE_WIFI_FUNCTION) + +#include "../../../../MarlinCore.h" +#include "../../../../module/temperature.h" +#include "../../../../gcode/queue.h" +#include "../../../../gcode/gcode.h" +#include "../../../../lcd/ultralcd.h" +#include "../../../../sd/cardreader.h" +#include "../../../../module/planner.h" +#if ENABLED(POWER_LOSS_RECOVERY) + #include "../../../../feature/powerloss.h" +#endif +#if ENABLED(PARK_HEAD_ON_PAUSE) + #include "../../../../feature/pause.h" +#endif + +#define WIFI_SET() WRITE(WIFI_RESET_PIN, HIGH); +#define WIFI_RESET() WRITE(WIFI_RESET_PIN, LOW); +#define WIFI_IO1_SET() WRITE(WIFI_IO1_PIN, HIGH); +#define WIFI_IO1_RESET() WRITE(WIFI_IO1_PIN, LOW); + +extern uint8_t Explore_Disk (char* path , uint8_t recu_level); + +extern uint8_t commands_in_queue; +extern uint8_t sel_id; + +int usartFifoAvailable(SZ_USART_FIFO *fifo); +int readUsartFifo(SZ_USART_FIFO *fifo, int8_t *buf, int32_t len); +int writeUsartFifo(SZ_USART_FIFO * fifo, int8_t * buf, int32_t len); +extern unsigned int getTickDiff(unsigned int curTick, unsigned int lastTick); + +volatile SZ_USART_FIFO WifiRxFifo; + +#define WAIT_ESP_TRANS_TIMEOUT_TICK 10500 + +int cfg_cloud_flag = 0; + +extern PRINT_TIME print_time; + +char wifi_firm_ver[20] = {0}; +WIFI_GCODE_BUFFER espGcodeFifo; +extern uint8_t pause_resum; + +uint8_t wifi_connect_flg = 0; +extern volatile uint8_t get_temp_flag; + + +#define WIFI_MODE 2 +#define WIFI_AP_MODE 3 + +int upload_result = 0; + +uint32_t upload_time = 0; +uint32_t upload_size = 0; + +volatile WIFI_STATE wifi_link_state; +WIFI_PARA wifiPara; +IP_PARA ipPara; +CLOUD_PARA cloud_para; + +char wifi_check_time = 0; + +extern uint8_t gCurDir[100]; + +extern uint32_t wifi_loop_cycle; + +volatile TRANSFER_STATE esp_state; + +uint8_t left_to_send = 0; +uint8_t left_to_save[96] = {0}; + +volatile WIFI_DMA_RCV_FIFO wifiDmaRcvFifo; + +volatile WIFI_TRANS_ERROR wifiTransError; + +static bool need_ok_later = false; + +extern volatile WIFI_STATE wifi_link_state; +extern WIFI_PARA wifiPara; +extern IP_PARA ipPara; +extern CLOUD_PARA cloud_para; + +extern uint8_t once_flag; +extern uint8_t flash_preview_begin; +extern uint8_t default_preview_flg; +extern uint8_t gcode_preview_over; + +extern uint8_t bmp_public_buf[17 * 1024]; + +uint32_t getWifiTick() { + return millis(); +} + +uint32_t getWifiTickDiff(int32_t lastTick, int32_t curTick) { + if (lastTick <= curTick) { + return (curTick - lastTick) * TICK_CYCLE; + } + else { + return (0xFFFFFFFF - lastTick + curTick) * TICK_CYCLE; + } +} + +void wifi_delay(int n) { + uint32_t begin = getWifiTick(); + uint32_t end = begin; + + while (getWifiTickDiff(begin, end) < (uint32_t)n) { + end = getWifiTick(); + } +} + +void wifi_reset() { + uint32_t start, now; + start = getWifiTick(); + now = start; + WIFI_RESET(); + while (getWifiTickDiff(start, now) < 500) { + now = getWifiTick(); + } + WIFI_SET(); + +} + +void mount_file_sys(uint8_t disk_type) { + if (disk_type == FILE_SYS_SD) { + card.mount(); + } + else if (disk_type == FILE_SYS_USB) { + + } +} + +static void dma_init() { + #if 0 + __HAL_RCC_DMA1_CLK_ENABLE(); + + //HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0); + HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 4, 0); + HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn); + + hdma_usart1_rx.Instance = DMA1_Channel5; + //hdma_usart1_rx.Init.Channel = DMA_CHANNEL_4; + hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE; + hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + hdma_usart1_rx.Init.MemDataAlignment = DMA_PDATAALIGN_BYTE; + hdma_usart1_rx.Init.Mode = DMA_NORMAL; + hdma_usart1_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH; + if (HAL_DMA_Init((DMA_HandleTypeDef *)&hdma_usart1_rx) != HAL_OK) { + Error_Handler(); + } + + + HAL_DMA_Start_IT((DMA_HandleTypeDef *)&hdma_usart1_rx, + (uint32_t)&huart1.Instance->DR, + (uint32_t)(&WifiRxFifo.uartTxBuffer[0]), + UART_RX_BUFFER_SIZE); + + //HAL_UART_Receive_DMA(&huart1,(uint8_t*)&WifiRxFifo.uartTxBuffer[0], UART_RX_BUFFER_SIZE); + + /* Enable the DMA transfer for the receiver request by setting the DMAR bit + in the UART CR3 register */ + SET_BIT(huart1.Instance->CR3, USART_CR3_DMAR); + + #endif + for (uint8_t i = 0; i < TRANS_RCV_FIFO_BLOCK_NUM; i++) { + wifiDmaRcvFifo.bufferAddr[i] = &bmp_public_buf[1024 * i]; + wifiDmaRcvFifo.state[i] = udisk_buf_empty; + } + + memset(wifiDmaRcvFifo.bufferAddr[0], 0, 1024 * TRANS_RCV_FIFO_BLOCK_NUM); + wifiDmaRcvFifo.read_cur = 0; + wifiDmaRcvFifo.write_cur = 0; + +} + +static void wifi_deInit() { + #if 0 + HAL_DMA_Abort((DMA_HandleTypeDef *)&hdma_usart1_rx); + HAL_DMA_DeInit((DMA_HandleTypeDef *)&hdma_usart1_rx); + __HAL_DMA_DISABLE((DMA_HandleTypeDef *)&hdma_usart1_rx); + #endif +} + +extern uint8_t mksUsart1Rx; + +void esp_port_begin(uint8_t interrupt) { + WifiRxFifo.uart_read_point = 0; + WifiRxFifo.uart_write_point = 0; + #if 0 + NVIC_InitTypeDef NVIC_InitStructure; + + USART_InitTypeDef USART_InitStructure; + GPIO_InitTypeDef GPIO_InitStruct; + + WifiRxFifo.uart_read_point = 0; + WifiRxFifo.uart_write_point = 0; + memset((uint8_t*)WifiRxFifo.uartTxBuffer, 0, sizeof(WifiRxFifo.uartTxBuffer)); + + if (interrupt) { + #if TAN + wifi_deInit (); + + //SZ_STM32_COMInit(COM1, 115200); + __HAL_UART_ENABLE_IT(USART1, USART_IT_RXNE); + + USART_InitStructure.USART_BaudRate = 115200; //���ڵIJ����ʣ�����115200 ��ߴ�4.5Mbits/s + USART_InitStructure.USART_WordLength = USART_WordLength_8b; //�����ֳ���(8λ��9λ) + USART_InitStructure.USART_StopBits = USART_StopBits_1; //�����õ�ֹͣλ-֧��1��2��ֹͣλ + USART_InitStructure.USART_Parity = USART_Parity_No; //����żУ�� + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //��Ӳ�������� + USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //˫��ģʽ��ʹ�ܷ��ͺͽ��� + + __HAL_RCC_USART1_CLK_ENABLE(); + + GPIO_InitStruct.Pin = TFT_WIFI_TX_Pin|TFT_WIFI_RX_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF7_USART1; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pin = TFT_WIFI_RX_Pin; + HAL_GPIO_Init(GPIOA,&GPIO_InitStruct); + + USART_Init(USART1, &USART_InitStructure); + + NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; + // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; + // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + + NVIC_Init(&NVIC_InitStructure); + #else + HAL_UART_DeInit(&huart1); + MX_USART1_UART_Init(3); + //__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE); + HAL_UART_Receive_IT(&huart1,&mksUsart1Rx,1); + #endif + } + else{ + #if 0 + NVIC_DisableIRQ(SZ_STM32_COM1_IRQn); + + USART_Cmd(SZ_STM32_COM1, DISABLE); + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, DISABLE); + RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); + + SZ_STM32_COMInit(COM1, 1958400); + + USART_Cmd(SZ_STM32_COM1, ENABLE); + + wifi_delay(10); + + dma_init(); + #endif + HAL_UART_DeInit(&huart1); + MX_USART1_UART_Init(5); + //dma1_5_IRQ_sel = 1; + dma_init(); + } + #endif + if (interrupt) { + #if ENABLED(USE_WIFI_FUNCTION) + WIFISERIAL.end(); + for (uint16_t i = 0; i < 65535; i++); + WIFISERIAL.begin(WIFI_BAUDRATE); + uint32_t serial_connect_timeout = millis() + 1000UL; + while (/*!WIFISERIAL && */PENDING(millis(), serial_connect_timeout)) { /*nada*/ } + //for(uint8_t i=0;i<100;i++)WIFISERIAL.write(0x33); + #endif + } + else { + #if ENABLED(USE_WIFI_FUNCTION) + WIFISERIAL.end(); + for (uint16_t i = 0; i < 65535; i++); + WIFISERIAL.begin(WIFI_UPLOAD_BAUDRATE); + uint32_t serial_connect_timeout = millis() + 1000UL; + while (/*!WIFISERIAL && */PENDING(millis(), serial_connect_timeout)) { /*nada*/ } + //for(uint16_t i=0;i<65535;i++);//WIFISERIAL.write(0x33); + #endif + dma_init(); + } +} + +#if ENABLED(USE_WIFI_FUNCTION) + +int raw_send_to_wifi(char *buf, int len) { + if (buf == 0 || len <= 0) return 0; + + for (int i = 0; i < len; i++) + WIFISERIAL.write(*(buf + i)); + + return len; +} + +#endif // USE_WIFI_FUNCTION + +void wifi_ret_ack() {} + +char buf_to_wifi[256]; +int index_to_wifi = 0; +int package_to_wifi(WIFI_RET_TYPE type,char *buf, int len) { + char wifi_ret_head = 0xA5; + char wifi_ret_tail = 0xFC; + + if (type == WIFI_PARA_SET) { + int data_offset = 4; + int apLen = strlen((const char *)uiCfg.wifi_name); + int keyLen = strlen((const char *)uiCfg.wifi_key); + + memset(buf_to_wifi, 0, sizeof(buf_to_wifi)); + index_to_wifi = 0; + + buf_to_wifi[data_offset] = gCfgItems.wifi_mode_sel; + buf_to_wifi[data_offset + 1] = apLen; + strncpy(&buf_to_wifi[data_offset + 2], (const char *)uiCfg.wifi_name, apLen); + buf_to_wifi[data_offset + apLen + 2] = keyLen; + strncpy(&buf_to_wifi[data_offset + apLen + 3], (const char *)uiCfg.wifi_key, keyLen); + buf_to_wifi[data_offset + apLen + keyLen + 3] = wifi_ret_tail; + + index_to_wifi = apLen + keyLen + 3; + + buf_to_wifi[0] = wifi_ret_head; + buf_to_wifi[1] = type; + buf_to_wifi[2] = index_to_wifi & 0xFF; + buf_to_wifi[3] = (index_to_wifi >> 8) & 0xFF; + + raw_send_to_wifi(buf_to_wifi, 5 + index_to_wifi); + + memset(buf_to_wifi, 0, sizeof(buf_to_wifi)); + index_to_wifi = 0; + + } + else if (type == WIFI_TRANS_INF) { + if (len > (int)(sizeof(buf_to_wifi) - index_to_wifi - 5)) { + memset(buf_to_wifi, 0, sizeof(buf_to_wifi)); + index_to_wifi = 0; + return 0; + } + + if (len > 0) { + memcpy(&buf_to_wifi[4 + index_to_wifi], buf, len); + index_to_wifi += len; + + if (index_to_wifi < 1) + return 0; + + if (buf_to_wifi[index_to_wifi + 3] == '\n') { + //mask "wait" "busy" "X:" + if (((buf_to_wifi[4] == 'w') && (buf_to_wifi[5] == 'a') && (buf_to_wifi[6] == 'i') && (buf_to_wifi[7] == 't') ) + || ((buf_to_wifi[4] == 'b') && (buf_to_wifi[5] == 'u') && (buf_to_wifi[6] == 's') && (buf_to_wifi[7] == 'y') ) + || ((buf_to_wifi[4] == 'X') && (buf_to_wifi[5] == ':') ) + ) { + memset(buf_to_wifi, 0, sizeof(buf_to_wifi)); + index_to_wifi = 0; + return 0; + } + + buf_to_wifi[0] = wifi_ret_head; + buf_to_wifi[1] = type; + buf_to_wifi[2] = index_to_wifi & 0xFF; + buf_to_wifi[3] = (index_to_wifi >> 8) & 0xFF; + buf_to_wifi[4 + index_to_wifi] = wifi_ret_tail; + + raw_send_to_wifi(buf_to_wifi, 5 + index_to_wifi); + + memset(buf_to_wifi, 0, sizeof(buf_to_wifi)); + index_to_wifi = 0; + } + } + } + else if (type == WIFI_EXCEP_INF) { + memset(buf_to_wifi, 0, sizeof(buf_to_wifi)); + + buf_to_wifi[0] = wifi_ret_head; + buf_to_wifi[1] = type; + buf_to_wifi[2] = 1; + buf_to_wifi[3] = 0; + buf_to_wifi[4] = *buf; + buf_to_wifi[5] = wifi_ret_tail; + + raw_send_to_wifi(buf_to_wifi, 6); + + memset(buf_to_wifi, 0, sizeof(buf_to_wifi)); + index_to_wifi = 0; + } + else if (type == WIFI_CLOUD_CFG) { + int data_offset = 4; + int urlLen = strlen((const char *)uiCfg.cloud_hostUrl); + + memset(buf_to_wifi, 0, sizeof(buf_to_wifi)); + index_to_wifi = 0; + + if (gCfgItems.cloud_enable == true) + buf_to_wifi[data_offset] = 0x0A; + else + buf_to_wifi[data_offset] = 0x05; + + buf_to_wifi[data_offset + 1] = urlLen; + strncpy(&buf_to_wifi[data_offset + 2], (const char *)uiCfg.cloud_hostUrl, urlLen); + buf_to_wifi[data_offset + urlLen + 2] = uiCfg.cloud_port & 0xFF; + buf_to_wifi[data_offset + urlLen + 3] = (uiCfg.cloud_port >> 8) & 0xFF; + buf_to_wifi[data_offset + urlLen + 4] = wifi_ret_tail; + + index_to_wifi = urlLen + 4; + + buf_to_wifi[0] = wifi_ret_head; + buf_to_wifi[1] = type; + buf_to_wifi[2] = index_to_wifi & 0xFF; + buf_to_wifi[3] = (index_to_wifi >> 8) & 0xFF; + + raw_send_to_wifi(buf_to_wifi, 5 + index_to_wifi); + + memset(buf_to_wifi, 0, sizeof(buf_to_wifi)); + index_to_wifi = 0; + } + else if (type == WIFI_CLOUD_UNBIND) { + memset(buf_to_wifi, 0, sizeof(buf_to_wifi)); + + buf_to_wifi[0] = wifi_ret_head; + buf_to_wifi[1] = type; + buf_to_wifi[2] = 0; + buf_to_wifi[3] = 0; + buf_to_wifi[4] = wifi_ret_tail; + + raw_send_to_wifi(buf_to_wifi, 5); + + memset(buf_to_wifi, 0, sizeof(buf_to_wifi)); + index_to_wifi = 0; + } +} + + +int send_to_wifi(char *buf, int len) { return package_to_wifi(WIFI_TRANS_INF, buf, len); } + +void set_cur_file_sys(int fileType) { + gCfgItems.fileSysType = fileType; +} + +void get_file_list(char *path) { + if ( path == 0) { + return; + } + + if (gCfgItems.fileSysType == FILE_SYS_SD) { + #if ENABLED(SDSUPPORT) + card.mount(); + #endif + } + else if (gCfgItems.fileSysType == FILE_SYS_USB) { + //udisk + } + Explore_Disk(path, 0); +} + +char wait_ip_back_flag = 0; + +typedef struct { + char write_buf[513]; + int write_index; + uint8_t saveFileName[30]; + uint32_t fileLen; + uint32_t tick_begin; + uint32_t tick_end; +} FILE_WRITER; + +FILE_WRITER file_writer; + +int32_t lastFragment = 0; + +char lastBinaryCmd[50] = {0}; + +int total_write = 0; +char binary_head[2] = {0, 0}; +unsigned char binary_data_len = 0; + +int write_to_file(char *buf, int len) { + int i; + int res; + + for (i = 0; i < len; i++) { + file_writer.write_buf[file_writer.write_index++] = buf[i]; + if (file_writer.write_index >= 512) { + res = card.write(file_writer.write_buf, file_writer.write_index); + if (res == -1) { + return -1; + } + memset(file_writer.write_buf, 0, sizeof(file_writer.write_buf)); + file_writer.write_index = 0; + } + } + return 0; +} + +#define ESP_PROTOC_HEAD (uint8_t)0xA5 +#define ESP_PROTOC_TAIL (uint8_t)0xFC + +#define ESP_TYPE_NET (uint8_t)0x0 +#define ESP_TYPE_GCODE (uint8_t)0x1 +#define ESP_TYPE_FILE_FIRST (uint8_t)0x2 +#define ESP_TYPE_FILE_FRAGMENT (uint8_t)0x3 + +#define ESP_TYPE_WIFI_LIST (uint8_t)0x4 + +uint8_t esp_msg_buf[UART_RX_BUFFER_SIZE] = {0}; +uint16_t esp_msg_index = 0; + +typedef struct { + uint8_t head; + uint8_t type; + uint16_t dataLen; + uint8_t *data; + uint8_t tail; +} ESP_PROTOC_FRAME; + + +static int cut_msg_head(uint8_t *msg, uint16_t msgLen, uint16_t cutLen) { + if (msgLen < cutLen) return 0; + + else if (msgLen == cutLen) { + memset(msg, 0, msgLen); + return 0; + } + + for (int i = 0; i < (msgLen - cutLen); i++) + msg[i] = msg[cutLen + i]; + + memset(&msg[msgLen - cutLen], 0, cutLen); + + return msgLen - cutLen; +} + + +uint8_t Explore_Disk (char* path , uint8_t recu_level) { + char tmp[200]; + char Fstream[200]; + + if (path == 0)return 0; + + const uint8_t fileCnt = card.get_num_Files(); + + for (uint8_t i = 0; i < fileCnt; i++) { + const uint16_t nr = + #if ENABLED(SDCARD_RATHERRECENTFIRST) && DISABLED(SDCARD_SORT_ALPHA) + fileCnt - 1 - + #endif + i; + + #if ENABLED(SDCARD_SORT_ALPHA) + card.getfilename_sorted(nr); + #else + card.getfilename_sorted(nr); + #endif + memset(tmp, 0, sizeof(tmp)); + //if (card.longFilename[0] == 0) + strcpy(tmp, card.filename); + //else + //strcpy(tmp, card.longFilename); + + memset(Fstream, 0, sizeof(Fstream)); + strcpy(Fstream, tmp); + + if (card.flag.filenameIsDir && (recu_level <= 10)) { + strcat(Fstream, ".DIR\r\n"); + send_to_wifi(Fstream, strlen(Fstream)); + } + else { + strcat(Fstream, "\r\n"); + send_to_wifi(Fstream, strlen(Fstream)); + } + } + + return fileCnt; +} + +static void wifi_gcode_exec(uint8_t *cmd_line) { + int8_t tempBuf[100] = {0}; + uint8_t *tmpStr = 0; + int cmd_value; + volatile int print_rate; + if ((strstr((char *)&cmd_line[0], "\n") != 0) && ((strstr((char *)&cmd_line[0], "G") != 0) || (strstr((char *)&cmd_line[0], "M") != 0) || (strstr((char *)&cmd_line[0], "T") != 0) )) { + + tmpStr = (uint8_t *)strstr((char *)&cmd_line[0], "\n"); + if (tmpStr) { + *tmpStr = '\0'; + } + tmpStr = (uint8_t *)strstr((char *)&cmd_line[0], "\r"); + if (tmpStr) { + *tmpStr = '\0'; + } + tmpStr = (uint8_t *)strstr((char *)&cmd_line[0], "*"); + if (tmpStr) { + *tmpStr = '\0'; + } + tmpStr = (uint8_t *)strstr((char *)&cmd_line[0], "M"); + if ( tmpStr) { + cmd_value = atoi((char *)(tmpStr + 1)); + tmpStr = (uint8_t *)strstr((char *)tmpStr, " "); + + switch (cmd_value) { + + case 20: //print sd / udisk file + if (uiCfg.print_state == IDLE) { + int index = 0; + + if (tmpStr == 0) { + gCfgItems.fileSysType = FILE_SYS_SD; + send_to_wifi((char *)"Begin file list\r\n", strlen("Begin file list\r\n")); + + get_file_list((char *)"0:/"); + + send_to_wifi((char *)"End file list\r\n", strlen("End file list\r\n")); + + send_to_wifi((char *)"ok\r\n", strlen("ok\r\n")); + break; + } + + while (tmpStr[index] == ' ') + index++; + + if (gCfgItems.wifi_type == ESP_WIFI) { + char *path = (char *)tempBuf; + + if (strlen((char *)&tmpStr[index]) < 80) { + send_to_wifi((char *)"Begin file list\r\n", strlen("Begin file list\r\n")); + + if (strncmp((char *)&tmpStr[index], "1:", 2) == 0) { + gCfgItems.fileSysType = FILE_SYS_SD; + + } + else if (strncmp((char *)&tmpStr[index], "0:", 2) == 0) { + gCfgItems.fileSysType = FILE_SYS_USB; + } + strcpy((char *)path, (char *)&tmpStr[index]); + get_file_list(path); + send_to_wifi((char *)"End file list\r\n", strlen("End file list\r\n")); + } + send_to_wifi((char *)"ok\r\n", strlen("ok\r\n")); + } + } + break; + + case 21: + /*init sd card*/ + send_to_wifi((char *)"ok\r\n", strlen("ok\r\n")); + break; + + case 23: + /*select the file*/ + if (uiCfg.print_state == IDLE) { + int index = 0; + while (tmpStr[index] == ' ') + index++; + + if (strstr((char *)&tmpStr[index], ".g") || strstr((char *)&tmpStr[index], ".G")) { + if (strlen((char *)&tmpStr[index]) < 80) { + memset(list_file.file_name[sel_id], 0, sizeof(list_file.file_name[sel_id])); + + if (gCfgItems.wifi_type == ESP_WIFI) { + if (strncmp((char *)&tmpStr[index], "1:", 2) == 0) { + gCfgItems.fileSysType = FILE_SYS_SD; + + } + else if (strncmp((char *)&tmpStr[index], "0:", 2) == 0) { + gCfgItems.fileSysType = FILE_SYS_USB; + } + else { + if (tmpStr[index] != '/') + strcat((char *)list_file.file_name[0], "/"); + } + strcat((char *)list_file.file_name[sel_id], (char *)&tmpStr[index]); + + } + else { + strcpy(list_file.file_name[sel_id], (char *)&tmpStr[index]); + } + + char *cur_name=strrchr(list_file.file_name[sel_id],'/'); + + card.openFileRead(cur_name); + + if (card.isFileOpen()) { + send_to_wifi((char *)"File selected\r\n", strlen("File selected\r\n")); + + } + else { + send_to_wifi((char *)"file.open failed\r\n", strlen("file.open failed\r\n")); + strcpy(list_file.file_name[sel_id], "notValid"); + } + send_to_wifi((char *)"ok\r\n", strlen("ok\r\n")); + + } + + + } + } + break; + + case 24: + if (strcmp(list_file.file_name[sel_id], "notValid") != 0) { + if (uiCfg.print_state == IDLE) { + clear_cur_ui(); + reset_print_time(); + start_print_time(); + preview_gcode_prehandle(list_file.file_name[sel_id]); + uiCfg.print_state = WORKING; + lv_draw_printing(); + + if (gcode_preview_over != 1) { + #if ENABLED(SDSUPPORT) + char *cur_name; + cur_name=strrchr(list_file.file_name[sel_id],'/'); + + SdFile file; + SdFile *curDir; + card.endFilePrint(); + const char * const fname = card.diveToFile(true, curDir, cur_name); + if (!fname) return; + if (file.open(curDir, fname, O_READ)) { + gCfgItems.curFilesize = file.fileSize(); + file.close(); + update_spi_flash(); + } + card.openFileRead(cur_name); + if (card.isFileOpen()) { + feedrate_percentage = 100; + //saved_feedrate_percentage = feedrate_percentage; + planner.flow_percentage[0] = 100; + planner.e_factor[0]= planner.flow_percentage[0]*0.01; + if (EXTRUDERS==2) { + planner.flow_percentage[1] = 100; + planner.e_factor[1]= planner.flow_percentage[1]*0.01; + } + card.startFileprint(); + #if ENABLED(POWER_LOSS_RECOVERY) + recovery.prepare(); + #endif + once_flag = 0; + } + #endif + + } + } + else if (uiCfg.print_state == PAUSED) { + uiCfg.print_state = RESUMING; + clear_cur_ui(); + start_print_time(); + + if (gCfgItems.from_flash_pic==1) + flash_preview_begin = 1; + else + default_preview_flg = 1; + lv_draw_printing(); + } + else if (uiCfg.print_state == REPRINTING) { + uiCfg.print_state = REPRINTED; + clear_cur_ui(); + start_print_time(); + if (gCfgItems.from_flash_pic==1) + flash_preview_begin = 1; + else + default_preview_flg = 1; + lv_draw_printing(); + } + } + send_to_wifi((char *)"ok\r\n", strlen("ok\r\n")); + break; + + case 25: + /*pause print file*/ + if (uiCfg.print_state == WORKING) { + stop_print_time(); + + clear_cur_ui(); + + #if ENABLED(SDSUPPORT) + card.pauseSDPrint(); + uiCfg.print_state = PAUSING; + #endif + if (gCfgItems.from_flash_pic==1) + flash_preview_begin = 1; + else + default_preview_flg = 1; + lv_draw_printing(); + send_to_wifi((char *)"ok\r\n", strlen("ok\r\n")); + } + break; + + case 26: + /*stop print file*/ + if ((uiCfg.print_state == WORKING) || (uiCfg.print_state == PAUSED) || (uiCfg.print_state == REPRINTING)) { + stop_print_time(); + + clear_cur_ui(); + #if ENABLED(SDSUPPORT) + uiCfg.print_state = IDLE; + card.flag.abort_sd_printing = true; + #endif + + lv_draw_ready_print(); + + send_to_wifi((char *)"ok\r\n", strlen("ok\r\n")); + } + break; + + case 27: + /*report print rate*/ + if ((uiCfg.print_state == WORKING) || (uiCfg.print_state == PAUSED)|| (uiCfg.print_state == REPRINTING)) { + print_rate = uiCfg.totalSend; + + memset((char *)tempBuf, 0, sizeof(tempBuf)); + + sprintf((char *)tempBuf, "M27 %d\r\n", print_rate); + + send_to_wifi((char *)tempBuf, strlen((char *)tempBuf)); + + } + + break; + + case 28: + /*begin to transfer file to filesys*/ + if (uiCfg.print_state == IDLE) { + + int index = 0; + while (tmpStr[index] == ' ') + index++; + + if (strstr((char *)&tmpStr[index], ".g") || strstr((char *)&tmpStr[index], ".G")) { + strcpy((char *)file_writer.saveFileName, (char *)&tmpStr[index]); + + if (gCfgItems.fileSysType == FILE_SYS_SD) { + memset(tempBuf, 0, sizeof(tempBuf)); + sprintf((char *)tempBuf, "%s", file_writer.saveFileName); + } + else if (gCfgItems.fileSysType == FILE_SYS_USB) { + memset(tempBuf, 0, sizeof(tempBuf)); + sprintf((char *)tempBuf, "%s", (char *)file_writer.saveFileName); + } + mount_file_sys(gCfgItems.fileSysType); + + #if ENABLED(SDSUPPORT) + char *cur_name=strrchr(list_file.file_name[sel_id],'/'); + card.openFileWrite(cur_name); + if (card.isFileOpen()) { + memset(file_writer.saveFileName, 0, sizeof(file_writer.saveFileName)); + strcpy((char *)file_writer.saveFileName, (char *)&tmpStr[index]); + memset(tempBuf, 0, sizeof(tempBuf)); + sprintf((char *)tempBuf, "Writing to file: %s\r\n", (char *)file_writer.saveFileName); + wifi_ret_ack(); + send_to_wifi((char *)tempBuf, strlen((char *)tempBuf)); + + total_write = 0; + wifi_link_state = WIFI_WAIT_TRANS_START; + + } + else{ + wifi_link_state = WIFI_CONNECTED; + clear_cur_ui(); + lv_draw_dialog(DIALOG_TRANSFER_NO_DEVICE); + } + #endif + + } + + } + break; + case 105: + case 991: + memset(tempBuf, 0, sizeof(tempBuf)); + if (cmd_value == 105) { + send_to_wifi((char *)"ok\r\n", strlen("ok\r\n")); + sprintf((char *)tempBuf,"T:%.1f /%.1f B:%.1f /%.1f T0:%.1f /%.1f T1:%.1f /%.1f @:0 B@:0\r\n", + + (float)thermalManager.temp_hotend[0].celsius,(float)thermalManager.temp_hotend[0].target, + #if HAS_HEATED_BED + (float)thermalManager.temp_bed.celsius,(float)thermalManager.temp_bed.target, + #else + (float)0,(float)0, + #endif + (float)thermalManager.temp_hotend[0].celsius,(float)thermalManager.temp_hotend[0].target, + #if !defined(SINGLENOZZLE) && HAS_MULTI_EXTRUDER + (float)thermalManager.temp_hotend[1].celsius,(float)thermalManager.temp_hotend[1].target + #else + (float)0,(float)0 + #endif + ); + } + else { + sprintf((char *)tempBuf,"T:%d /%d B:%d /%d T0:%d /%d T1:%d /%d @:0 B@:0\r\n", + + (int)thermalManager.temp_hotend[0].celsius,(int)thermalManager.temp_hotend[0].target, + #if HAS_HEATED_BED + (int)thermalManager.temp_bed.celsius,(int)thermalManager.temp_bed.target, + #else + 0,0, + #endif + (int)thermalManager.temp_hotend[0].celsius,(int)thermalManager.temp_hotend[0].target, + #if !defined(SINGLENOZZLE) && HAS_MULTI_EXTRUDER + (int)thermalManager.temp_hotend[1].celsius,(int)thermalManager.temp_hotend[1].target + #else + 0,0 + #endif + ); + } + + send_to_wifi((char *)tempBuf, strlen((char *)tempBuf)); + + queue.enqueue_one_P(PSTR("M105")); + + break; + case 992: + if ((uiCfg.print_state == WORKING) || (uiCfg.print_state == PAUSED)) { + memset(tempBuf,0,sizeof(tempBuf)); + sprintf((char *)tempBuf, "M992 %d%d:%d%d:%d%d\r\n", print_time.hours/10, print_time.hours%10, print_time.minutes/10, print_time.minutes%10, print_time.seconds/10, print_time.seconds%10); + wifi_ret_ack(); + send_to_wifi((char *)tempBuf, strlen((char *)tempBuf)); + } + + break; + case 994: + if ((uiCfg.print_state == WORKING) || (uiCfg.print_state == PAUSED)) { + memset(tempBuf,0,sizeof(tempBuf)); + if (strlen((char *)list_file.file_name[sel_id]) > (100-1)) { + return; + } + sprintf((char *)tempBuf, "M994 %s;%d\n", list_file.file_name[sel_id],(int)gCfgItems.curFilesize); + wifi_ret_ack(); + send_to_wifi((char *)tempBuf, strlen((char *)tempBuf)); + } + break; + case 997: + if (uiCfg.print_state == IDLE) { + wifi_ret_ack(); + send_to_wifi((char *)"M997 IDLE\r\n", strlen("M997 IDLE\r\n")); + } + else if (uiCfg.print_state == WORKING) { + wifi_ret_ack(); + send_to_wifi((char *)"M997 PRINTING\r\n", strlen("M997 PRINTING\r\n")); + } + else if (uiCfg.print_state == PAUSED) { + wifi_ret_ack(); + send_to_wifi((char *)"M997 PAUSE\r\n", strlen("M997 PAUSE\r\n")); + } + else if (uiCfg.print_state == REPRINTING) { + wifi_ret_ack(); + send_to_wifi((char *)"M997 PAUSE\r\n", strlen("M997 PAUSE\r\n")); + } + if (uiCfg.command_send == 0) get_wifi_list_command_send(); + break; + + case 998: + if (uiCfg.print_state == IDLE) { + if (atoi((char *)tmpStr) == 0) { + set_cur_file_sys(0); + } + else if (atoi((char *)tmpStr) == 1) { + set_cur_file_sys(1); + } + wifi_ret_ack(); + } + break; + + case 115: + memset(tempBuf,0,sizeof(tempBuf)); + send_to_wifi((char *)"ok\r\n", strlen("ok\r\n")); + send_to_wifi((char *)"FIRMWARE_NAME:Robin_nano\r\n", strlen("FIRMWARE_NAME:Robin_nano\r\n")); + break; + + default: + strcat((char *)cmd_line, "\n"); + + uint32_t left; + + if (espGcodeFifo.wait_tick> 5) { + + if (espGcodeFifo.r > espGcodeFifo.w) + left = espGcodeFifo.r - espGcodeFifo.w - 1; + else + left = WIFI_GCODE_BUFFER_SIZE + espGcodeFifo.r - espGcodeFifo.w - 1; + if (left >= strlen((const char *)cmd_line)) { + uint32_t index = 0; + while (index < strlen((const char *)cmd_line)) { + espGcodeFifo.Buffer[espGcodeFifo.w] = cmd_line[index] ; + espGcodeFifo.w = (espGcodeFifo.w + 1) % WIFI_GCODE_BUFFER_SIZE; + index++; + } + if (left - WIFI_GCODE_BUFFER_LEAST_SIZE >= strlen((const char *)cmd_line)) + send_to_wifi((char *)"ok\r\n", strlen("ok\r\n")); + else + need_ok_later = true; + + } + + } + break; + + } + } + else{ + strcat((char *)cmd_line, "\n"); + uint32_t left_g; + + if (espGcodeFifo.wait_tick > 5) { + + if (espGcodeFifo.r > espGcodeFifo.w) + left_g = espGcodeFifo.r - espGcodeFifo.w - 1; + else + left_g = WIFI_GCODE_BUFFER_SIZE + espGcodeFifo.r - espGcodeFifo.w - 1; + if (left_g >= strlen((const char *)cmd_line)) { + uint32_t index = 0; + while (index < strlen((const char *)cmd_line)) { + espGcodeFifo.Buffer[espGcodeFifo.w] = cmd_line[index] ; + espGcodeFifo.w = (espGcodeFifo.w + 1) % WIFI_GCODE_BUFFER_SIZE; + index++; + } + if (left_g - WIFI_GCODE_BUFFER_LEAST_SIZE >= strlen((const char *)cmd_line)) + send_to_wifi((char *)"ok\r\n", strlen("ok\r\n")); + else + need_ok_later = true; + + } + } + } + } +} + +static int32_t charAtArray(const uint8_t *_array, uint32_t _arrayLen, uint8_t _char) { + for (uint32_t i = 0; i < _arrayLen; i++) + if (*(_array + i) == _char) return i; + return -1; +} + +void get_wifi_list_command_send() { + char buf[6] = {0}; + buf[0] = 0xA5; + buf[1] = 0x07; + buf[2] = 0x00; + buf[3] = 0x00; + buf[4] = 0xFC; + raw_send_to_wifi(buf, 5); +} + +static void net_msg_handle(uint8_t * msg, uint16_t msgLen) { + int wifiNameLen, wifiKeyLen, hostLen, id_len, ver_len; + + if (msgLen <= 0) return; + //ip + sprintf(ipPara.ip_addr, "%d.%d.%d.%d", msg[0], msg[1], msg[2], msg[3]); + + //port + //connect state + if (msg[6] == 0x0A) + wifi_link_state = WIFI_CONNECTED; + else if (msg[6] == 0x0E) + wifi_link_state = WIFI_EXCEPTION; + else + wifi_link_state = WIFI_NOT_CONFIG; + + //mode + wifiPara.mode = msg[7]; + + + //wifi name + wifiNameLen = msg[8]; + wifiKeyLen = msg[9 + wifiNameLen]; + if (wifiNameLen < 32) { + memset(wifiPara.ap_name, 0, sizeof(wifiPara.ap_name)); + memcpy(wifiPara.ap_name, &msg[9], wifiNameLen); + + memset(&wifi_list.wifiConnectedName,0,sizeof(wifi_list.wifiConnectedName)); + memcpy(&wifi_list.wifiConnectedName,&msg[9],wifiNameLen); + + //wifi key + if (wifiKeyLen < 64) { + memset(wifiPara.keyCode, 0, sizeof(wifiPara.keyCode)); + memcpy(wifiPara.keyCode, &msg[10 + wifiNameLen], wifiKeyLen); + } + } + + + cloud_para.state =msg[10 + wifiNameLen + wifiKeyLen]; + hostLen = msg[11 + wifiNameLen + wifiKeyLen]; + if (cloud_para.state) { + if (hostLen < 96) { + memset(cloud_para.hostUrl, 0, sizeof(cloud_para.hostUrl)); + memcpy(cloud_para.hostUrl, &msg[12 + wifiNameLen + wifiKeyLen], hostLen); + } + cloud_para.port = msg[12 + wifiNameLen + wifiKeyLen + hostLen] + (msg[13 + wifiNameLen + wifiKeyLen + hostLen] << 8); + + } + + // id + id_len = msg[14 + wifiNameLen + wifiKeyLen + hostLen]; + if (id_len == 20) { + memset(cloud_para.id, 0, sizeof(cloud_para.id)); + memcpy(cloud_para.id, (const char *)&msg[15 + wifiNameLen + wifiKeyLen + hostLen], id_len); + } + ver_len = msg[15 + wifiNameLen + wifiKeyLen + hostLen + id_len]; + if (ver_len < 20) { + memset(wifi_firm_ver, 0, sizeof(wifi_firm_ver)); + memcpy(wifi_firm_ver, (const char *)&msg[16 + wifiNameLen + wifiKeyLen + hostLen + id_len], ver_len); + } + + if (uiCfg.configWifi == 1) { + if ((wifiPara.mode != gCfgItems.wifi_mode_sel) + || (strncmp(wifiPara.ap_name, (const char *)uiCfg.wifi_name, 32) != 0) + || (strncmp(wifiPara.keyCode, (const char *)uiCfg.wifi_key, 64) != 0)) { + package_to_wifi(WIFI_PARA_SET, (char *)0, 0); + } + else uiCfg.configWifi = 0; + } + if (cfg_cloud_flag == 1) { + if (((cloud_para.state >> 4) != (char)gCfgItems.cloud_enable) + || (strncmp(cloud_para.hostUrl, (const char *)uiCfg.cloud_hostUrl, 96) != 0) + || (cloud_para.port != uiCfg.cloud_port)) { + package_to_wifi(WIFI_CLOUD_CFG, (char *)0, 0); + } + else cfg_cloud_flag = 0; + } +} + +static void wifi_list_msg_handle(uint8_t * msg, uint16_t msgLen) { + int wifiNameLen,wifiMsgIdex=1; + int8_t wifi_name_is_same=0; + int8_t i,j; + int8_t wifi_name_num=0; + uint8_t *str=0; + int8_t valid_name_num; + + if (msgLen <= 0) + return; + if (disp_state == KEY_BOARD_UI) + return; + + wifi_list.getNameNum = msg[0]; + + if (wifi_list.getNameNum < 20) { + uiCfg.command_send = 1; + + memset(wifi_list.wifiName,0,sizeof(wifi_list.wifiName)); + + wifi_name_num = wifi_list.getNameNum; + + valid_name_num=0; + str = wifi_list.wifiName[valid_name_num]; + + if (wifi_list.getNameNum > 0) wifi_list.currentWifipage = 1; + + for (i = 0; i 0x80) { + wifi_name_is_same = 1; + //break; + } + //} + } + if (wifi_name_is_same == 1) { + wifi_name_is_same = 0; + wifiMsgIdex += wifiNameLen; + //wifi_list.RSSI[i] = msg[wifiMsgIdex]; + wifiMsgIdex += 1; + wifi_name_num--; + //i--; + continue; + } + if (i < WIFI_TOTAL_NUMBER-1) { + str = wifi_list.wifiName[++valid_name_num]; + } + } + wifiMsgIdex += wifiNameLen; + wifi_list.RSSI[i] = msg[wifiMsgIdex]; + wifiMsgIdex += 1; + } + wifi_list.getNameNum = wifi_name_num; + if (wifi_list.getNameNum % NUMBER_OF_PAGE == 0) { + wifi_list.getPage = wifi_list.getNameNum/NUMBER_OF_PAGE; + } + else { + wifi_list.getPage = wifi_list.getNameNum/NUMBER_OF_PAGE + 1; + } + wifi_list.nameIndex = 0; + if (disp_state == WIFI_LIST_UI) + disp_wifi_list(); + } +} + +static void gcode_msg_handle(uint8_t * msg, uint16_t msgLen) { + uint8_t gcodeBuf[100] = {0}; + char *index_s; + char *index_e; + + if (msgLen <= 0) + return; + + index_s = (char *)msg; + index_e = (char *)strstr((char *)msg, "\n"); + if (*msg == 'N') { + index_s = (char *)strstr((char *)msg, " "); + while ((*index_s) == ' ') { + index_s++; + } + } + while ((index_e != 0) && ((int)index_s < (int)index_e)) { + if ((int)(index_e - index_s) < (int)sizeof(gcodeBuf)) { + memset(gcodeBuf, 0, sizeof(gcodeBuf)); + + memcpy(gcodeBuf, index_s, index_e - index_s + 1); + + wifi_gcode_exec(gcodeBuf); + } + while ((*index_e == '\r') || (*index_e == '\n')) + index_e++; + + index_s = index_e; + index_e = (char *)strstr(index_s, "\n"); + } +} + +void utf8_2_unicode(uint8_t *source,uint8_t Len) { + uint8_t i=0,char_i=0,char_byte_num=0; + uint16_t u16_h,u16_m,u16_l,u16_value; + uint8_t FileName_unicode[30]; + + memset(FileName_unicode, 0, sizeof(FileName_unicode)); + + while (1) { + char_byte_num = source[i] & 0xF0; + if (source[i] < 0X80) { + //ASCII --1byte + FileName_unicode[char_i] = source[i]; + i += 1; + char_i += 1; + } + else if (char_byte_num == 0XC0 || char_byte_num == 0XD0) { + //--2byte + + u16_h = (((uint16_t)source[i] <<8) & 0x1F00) >> 2; + u16_l = ((uint16_t)source[i+1] & 0x003F); + u16_value = (u16_h | u16_l); + FileName_unicode[char_i] = (uint8_t)((u16_value & 0xFF00) >> 8); + FileName_unicode[char_i + 1] = (uint8_t)(u16_value & 0x00FF); + i += 2; + char_i += 2; + } + else if (char_byte_num == 0XE0) { + //--3byte + u16_h = (((uint16_t)source[i] <<8 ) & 0x0F00) << 4; + u16_m = (((uint16_t)source[i+1] << 8) & 0x3F00) >> 2; + u16_l = ((uint16_t)source[i+2] & 0x003F); + u16_value = (u16_h | u16_m | u16_l); + FileName_unicode[char_i] = (uint8_t)((u16_value & 0xFF00) >> 8); + FileName_unicode[char_i + 1] = (uint8_t)(u16_value & 0x00FF); + i += 3; + char_i += 2; + } + else if (char_byte_num == 0XF0) { + //--4byte + i += 4; + //char_i += 3; + } + else { + break; + } + if (i >= Len || i >= 255)break; + } + memcpy(source, FileName_unicode, sizeof(FileName_unicode)); +} + +char saveFilePath[50]; + +static bool longName2DosName(const char* longName, uint8_t* dosName) { + uint8_t i = 11; + while (i--) dosName[i] = '\0'; + while (*longName) { + uint8_t c = *longName++; + if (c == '.') { // For a dot... + if (i == 0) return false; + else { strcat((char *)dosName,".GCO"); return dosName[0] != '\0'; } + } + else { + // Fail for illegal characters + PGM_P p = PSTR("|<>^+=?/[];,*\"\\"); + while (uint8_t b = pgm_read_byte(p++)) if (b == c) return false; + if (c < 0x21 || c == 0x7F) return false; // Check size, non-printable characters + dosName[i++] = (c < 'a' || c > 'z') ? (c) : (c + ('A' - 'a')); // Uppercase required for 8.3 name + } + if (i >= 5) strcat((char *)dosName,"~1.GCO"); + } + return dosName[0] != '\0'; // Return true if any name was set +} + +static void file_first_msg_handle(uint8_t * msg, uint16_t msgLen) { + uint8_t fileNameLen = *msg; + + if (msgLen != fileNameLen + 5) return; + + file_writer.fileLen = *((uint32_t *)(msg + 1)); + memset(file_writer.saveFileName, 0, sizeof(file_writer.saveFileName)); + + memcpy(file_writer.saveFileName, msg + 5, fileNameLen); + + utf8_2_unicode(file_writer.saveFileName,fileNameLen); + + memset(file_writer.write_buf, 0, sizeof(file_writer.write_buf)); + + if (strlen((const char *)file_writer.saveFileName) > sizeof(saveFilePath)) + return; + + memset(saveFilePath, 0, sizeof(saveFilePath)); + + if (gCfgItems.fileSysType == FILE_SYS_SD) { + //sprintf((char *)saveFilePath, "/%s", file_writer.saveFileName); + card.mount(); + + //ZERO(list_file.long_name[sel_id]); + //memcpy(list_file.long_name[sel_id],file_writer.saveFileName,sizeof(list_file.long_name[sel_id])); + } + else if (gCfgItems.fileSysType == FILE_SYS_USB) { + + } + file_writer.write_index = 0; + lastFragment = -1; + + wifiTransError.flag = 0; + wifiTransError.start_tick = 0; + wifiTransError.now_tick = 0; + + TERN_(SDSUPPORT, card.closefile()); + + wifi_delay(1000); + + #if ENABLED(SDSUPPORT) + + uint8_t dosName[FILENAME_LENGTH]; + + if (!longName2DosName((const char *)file_writer.saveFileName,dosName)) { + clear_cur_ui(); + upload_result = 2; + wifiTransError.flag = 1; + wifiTransError.start_tick = getWifiTick(); + lv_draw_dialog(DIALOG_TYPE_UPLOAD_FILE); + return; + } + sprintf((char *)saveFilePath, "/%s", dosName); + + ZERO(list_file.long_name[sel_id]); + memcpy(list_file.long_name[sel_id],dosName,sizeof(dosName)); + + char *cur_name=strrchr((const char *)saveFilePath,'/'); + + SdFile file; + SdFile *curDir; + card.endFilePrint(); + const char * const fname = card.diveToFile(true, curDir, cur_name); + if (!fname) return; + if (file.open(curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) { + gCfgItems.curFilesize = file.fileSize(); + } + else { + clear_cur_ui(); + upload_result = 2; + wifiTransError.flag = 1; + wifiTransError.start_tick = getWifiTick(); + lv_draw_dialog(DIALOG_TYPE_UPLOAD_FILE); + return; + } + #endif + + wifi_link_state = WIFI_TRANS_FILE; + + upload_result = 1; + + clear_cur_ui(); + lv_draw_dialog(DIALOG_TYPE_UPLOAD_FILE); + + lv_task_handler(); + + file_writer.tick_begin = getWifiTick(); +} + +#define FRAG_MASK _BV32(31) + +static void file_fragment_msg_handle(uint8_t * msg, uint16_t msgLen) { + uint32_t frag = *((uint32_t *)msg); + + if ((frag & FRAG_MASK) != (uint32_t)(lastFragment + 1)) { + memset(file_writer.write_buf, 0, sizeof(file_writer.write_buf)); + file_writer.write_index = 0; + wifi_link_state = WIFI_CONNECTED; + upload_result = 2; + } + else { + if (write_to_file((char *)msg + 4, msgLen - 4) < 0) { + memset(file_writer.write_buf, 0, sizeof(file_writer.write_buf)); + file_writer.write_index = 0; + wifi_link_state = WIFI_CONNECTED; + upload_result = 2; + return; + } + lastFragment = frag; + + if ((frag & (~FRAG_MASK))) { + int res = card.write(file_writer.write_buf, file_writer.write_index); + if (res == -1) { + memset(file_writer.write_buf, 0, sizeof(file_writer.write_buf)); + file_writer.write_index = 0; + wifi_link_state = WIFI_CONNECTED; + upload_result = 2; + return; + } + memset(file_writer.write_buf, 0, sizeof(file_writer.write_buf)); + file_writer.write_index = 0; + file_writer.tick_end = getWifiTick(); + upload_time = getWifiTickDiff(file_writer.tick_begin, file_writer.tick_end) / 1000; + upload_size = gCfgItems.curFilesize; + wifi_link_state = WIFI_CONNECTED; + upload_result = 3; + } + + } +} + +void esp_data_parser(char *cmdRxBuf, int len) { + int32_t head_pos; + int32_t tail_pos; + uint16_t cpyLen; + int16_t leftLen = len; + bool loop_again = false; + + ESP_PROTOC_FRAME esp_frame; + + while (leftLen > 0 || loop_again) { + loop_again = false; + + if (esp_msg_index != 0) { + head_pos = 0; + cpyLen = (leftLen < (int16_t)((sizeof(esp_msg_buf) - esp_msg_index)) ? leftLen : sizeof(esp_msg_buf) - esp_msg_index); + + memcpy(&esp_msg_buf[esp_msg_index], cmdRxBuf + len - leftLen, cpyLen); + + esp_msg_index += cpyLen; + + leftLen = leftLen - cpyLen; + tail_pos = charAtArray(esp_msg_buf, esp_msg_index, ESP_PROTOC_TAIL); + + if (tail_pos == -1) { + if (esp_msg_index >= sizeof(esp_msg_buf)) { + memset(esp_msg_buf, 0, sizeof(esp_msg_buf)); + esp_msg_index = 0; + } + return; + } + } + else { + head_pos = charAtArray((uint8_t const *)&cmdRxBuf[len - leftLen], leftLen, ESP_PROTOC_HEAD); + if (head_pos == -1) return; + + memset(esp_msg_buf, 0, sizeof(esp_msg_buf)); + memcpy(esp_msg_buf, &cmdRxBuf[len - leftLen + head_pos], leftLen - head_pos); + + esp_msg_index = leftLen - head_pos; + + leftLen = 0; + head_pos = 0; + tail_pos = charAtArray(esp_msg_buf, esp_msg_index, ESP_PROTOC_TAIL); + if (tail_pos == -1) { + if (esp_msg_index >= sizeof(esp_msg_buf)) { + memset(esp_msg_buf, 0, sizeof(esp_msg_buf)); + esp_msg_index = 0; + } + return; + } + } + + esp_frame.type = esp_msg_buf[1]; + if ((esp_frame.type != ESP_TYPE_NET) && (esp_frame.type != ESP_TYPE_GCODE) + && (esp_frame.type != ESP_TYPE_FILE_FIRST) && (esp_frame.type != ESP_TYPE_FILE_FRAGMENT) + &&(esp_frame.type != ESP_TYPE_WIFI_LIST)) { + memset(esp_msg_buf, 0, sizeof(esp_msg_buf)); + esp_msg_index = 0; + return; + } + + esp_frame.dataLen = esp_msg_buf[2] + (esp_msg_buf[3] << 8); + + if ((int)(4 + esp_frame.dataLen) > (int)(sizeof(esp_msg_buf))) { + memset(esp_msg_buf, 0, sizeof(esp_msg_buf)); + esp_msg_index = 0; + return; + } + + if (esp_msg_buf[4 + esp_frame.dataLen] != ESP_PROTOC_TAIL) { + if (esp_msg_index >= sizeof(esp_msg_buf)) { + memset(esp_msg_buf, 0, sizeof(esp_msg_buf)); + esp_msg_index = 0; + } + return; + } + + esp_frame.data = &esp_msg_buf[4]; + switch (esp_frame.type) { + case ESP_TYPE_NET: + net_msg_handle(esp_frame.data, esp_frame.dataLen); + break; + case ESP_TYPE_GCODE: + gcode_msg_handle(esp_frame.data, esp_frame.dataLen); + break; + case ESP_TYPE_FILE_FIRST: + file_first_msg_handle(esp_frame.data, esp_frame.dataLen); + break; + case ESP_TYPE_FILE_FRAGMENT: + file_fragment_msg_handle(esp_frame.data, esp_frame.dataLen); + break; + case ESP_TYPE_WIFI_LIST: + wifi_list_msg_handle(esp_frame.data, esp_frame.dataLen); + break; + default: break; + } + + esp_msg_index = cut_msg_head(esp_msg_buf, esp_msg_index, esp_frame.dataLen + 5); + if (esp_msg_index > 0) { + if (charAtArray(esp_msg_buf, esp_msg_index, ESP_PROTOC_HEAD) == -1) { + memset(esp_msg_buf, 0, sizeof(esp_msg_buf)); + esp_msg_index = 0; + return; + } + + if ((charAtArray(esp_msg_buf, esp_msg_index, ESP_PROTOC_HEAD) != -1) && (charAtArray(esp_msg_buf, esp_msg_index, ESP_PROTOC_TAIL) != -1)) + loop_again = true; + } + } +} + +int32_t tick_net_time1, tick_net_time2; + +int storeRcvData(int32_t len) { + unsigned char tmpW = wifiDmaRcvFifo.write_cur; + if (len <= UDISKBUFLEN && wifiDmaRcvFifo.state[tmpW] == udisk_buf_empty) { + for (uint16_t i = 0; i < len; i++) + wifiDmaRcvFifo.bufferAddr[tmpW][i] = WIFISERIAL.read(); + wifiDmaRcvFifo.state[tmpW] = udisk_buf_full; + wifiDmaRcvFifo.write_cur = (tmpW + 1) % TRANS_RCV_FIFO_BLOCK_NUM; + return 1; + } + return 0; +} + +int32_t readWifiFifo(uint8_t *retBuf, uint32_t bufLen) { + unsigned char tmpR = wifiDmaRcvFifo.read_cur; + if (bufLen >= UDISKBUFLEN && wifiDmaRcvFifo.state[tmpR] == udisk_buf_full) { + memcpy(retBuf, (unsigned char *)wifiDmaRcvFifo.bufferAddr[tmpR], UDISKBUFLEN); + wifiDmaRcvFifo.state[tmpR] = udisk_buf_empty; + wifiDmaRcvFifo.read_cur = (tmpR + 1) % TRANS_RCV_FIFO_BLOCK_NUM; + return UDISKBUFLEN; + } + return 0; +} + +void stopEspTransfer() { + if (wifi_link_state == WIFI_TRANS_FILE) + wifi_link_state = WIFI_CONNECTED; + + TERN_(SDSUPPORT, card.closefile()); + + if (upload_result != 3) { + wifiTransError.flag = 1; + wifiTransError.start_tick = getWifiTick(); + card.removeFile((const char *)saveFilePath); + } + else { + } + wifi_delay(200); + WIFI_IO1_SET(); + //exchangeFlashMode(1); //change spi flash to use dma mode + esp_port_begin(1); + if (wifiTransError.flag != 0x1) WIFI_IO1_RESET(); +} + +void wifi_rcv_handle() { + int32_t len = 0; + uint8_t ucStr[(UART_RX_BUFFER_SIZE) + 1] = {0}; + int8_t getDataF = 0; + + if (wifi_link_state == WIFI_TRANS_FILE) { + #if 0 + if (WIFISERIAL.available() == UART_RX_BUFFER_SIZE) { + for (uint16_t i=0;i 0) { + esp_data_parser((char *)ucStr, len); + if (wifi_link_state == WIFI_CONNECTED) { + clear_cur_ui(); + lv_draw_dialog(DIALOG_TYPE_UPLOAD_FILE); + stopEspTransfer(); + } + getDataF = 1; + } + if (esp_state == TRANSFER_STORE) { + if (storeRcvData(UART_RX_BUFFER_SIZE)) { + esp_state = TRANSFERING; + //esp_dma_pre(); + if (wifiTransError.flag != 0x1) WIFI_IO1_RESET(); + } + else + WIFI_IO1_SET(); + } + } + else { + //len = readUsartFifo((SZ_USART_FIFO *)&WifiRxFifo, (int8_t *)ucStr, UART_RX_BUFFER_SIZE); + len = readWifiBuf((int8_t *)ucStr, UART_RX_BUFFER_SIZE); + if (len > 0) { + esp_data_parser((char *)ucStr, len); + + if (wifi_link_state == WIFI_TRANS_FILE) { + //exchangeFlashMode(0); //change spi flash not use dma mode + wifi_delay(10); + esp_port_begin(0); + wifi_delay(10); + tick_net_time1 = 0; + } + if (wifiTransError.flag != 0x1) WIFI_IO1_RESET(); + getDataF = 1; + } + if (need_ok_later && (queue.length < BUFSIZE)) { + need_ok_later = false; + send_to_wifi((char *)"ok\r\n", strlen("ok\r\n")); + } + } + + if (getDataF == 1) { + tick_net_time1 = getWifiTick(); + } + else { + tick_net_time2 = getWifiTick(); + + if (wifi_link_state == WIFI_TRANS_FILE) { + if ((tick_net_time1 != 0) && (getWifiTickDiff(tick_net_time1, tick_net_time2) > 4500)) { + wifi_link_state = WIFI_CONNECTED; + upload_result = 2; + clear_cur_ui(); + stopEspTransfer(); + lv_draw_dialog(DIALOG_TYPE_UPLOAD_FILE); + } + } + + if ((tick_net_time1 != 0) && (getWifiTickDiff(tick_net_time1, tick_net_time2) > 10000)) + wifi_link_state = WIFI_NOT_CONFIG; + + if ((tick_net_time1 != 0) && (getWifiTickDiff(tick_net_time1, tick_net_time2) > 120000)) { + wifi_link_state = WIFI_NOT_CONFIG; + wifi_reset(); + tick_net_time1 = getWifiTick(); + } + } + + if (wifiTransError.flag == 0x1) { + wifiTransError.now_tick = getWifiTick(); + if (getWifiTickDiff(wifiTransError.start_tick, wifiTransError.now_tick) > WAIT_ESP_TRANS_TIMEOUT_TICK) { + wifiTransError.flag = 0; + WIFI_IO1_RESET(); + } + } +} + +void wifi_looping() { + do { wifi_rcv_handle(); } while (wifi_link_state == WIFI_TRANS_FILE); +} + +void mks_esp_wifi_init() { + wifi_link_state = WIFI_NOT_CONFIG; + + SET_OUTPUT(WIFI_RESET_PIN); + WIFI_SET(); + SET_OUTPUT(WIFI_IO1_PIN); + SET_INPUT_PULLUP(WIFI_IO0_PIN); + WIFI_IO1_SET(); + + esp_state = TRANSFER_IDLE; + esp_port_begin(1); + + wifi_reset(); + + #if 0 + res = f_open(&esp_upload.uploadFile, ESP_FIRMWARE_FILE, FA_OPEN_EXISTING | FA_READ); + + if (res == FR_OK) { + f_close(&esp_upload.uploadFile); + + wifi_delay(2000); + + if (usartFifoAvailable((SZ_USART_FIFO *)&WifiRxFifo) < 20) { + return; + } + + clear_cur_ui(); + + draw_dialog(DIALOG_TYPE_UPDATE_ESP_FIRMARE); + + if (wifi_upload(0) >= 0) { + + f_unlink("1:/MKS_WIFI_CUR"); + f_rename(ESP_FIRMWARE_FILE,"/MKS_WIFI_CUR"); + } + draw_return_ui(); + + update_flag = 1; + } + if (update_flag == 0) { + res = f_open(&esp_upload.uploadFile, ESP_WEB_FIRMWARE_FILE, FA_OPEN_EXISTING | FA_READ); + + if (res == FR_OK) { + f_close(&esp_upload.uploadFile); + + wifi_delay(2000); + + if (usartFifoAvailable((SZ_USART_FIFO *)&WifiRxFifo) < 20) { + return; + } + + clear_cur_ui(); + + draw_dialog(DIALOG_TYPE_UPDATE_ESP_FIRMARE); + if (wifi_upload(1) >= 0) { + + f_unlink("1:/MKS_WIFI_CUR"); + f_rename(ESP_WEB_FIRMWARE_FILE,"/MKS_WIFI_CUR"); + } + draw_return_ui(); + update_flag = 1; + } + + } + if (update_flag == 0) { + res = f_open(&esp_upload.uploadFile, ESP_WEB_FILE, FA_OPEN_EXISTING | FA_READ); + if (res == FR_OK) { + f_close(&esp_upload.uploadFile); + + wifi_delay(2000); + + if (usartFifoAvailable((SZ_USART_FIFO *)&WifiRxFifo) < 20) { + return; + } + + clear_cur_ui(); + + draw_dialog(DIALOG_TYPE_UPDATE_ESP_DATA); + + if (wifi_upload(2) >= 0) { + + f_unlink("1:/MKS_WEB_CONTROL_CUR"); + f_rename(ESP_WEB_FILE,"/MKS_WEB_CONTROL_CUR"); + } + draw_return_ui(); + } + } + #endif + wifiPara.decodeType = WIFI_DECODE_TYPE; + wifiPara.baud = 115200; + wifi_link_state = WIFI_NOT_CONFIG; +} + +#define BUF_INC_POINTER(p) ((p + 1 == UART_FIFO_BUFFER_SIZE) ? 0 : (p + 1)) + +int usartFifoAvailable(SZ_USART_FIFO *fifo) { + int diff = fifo->uart_write_point - fifo->uart_read_point; + if (diff < 0) diff += UART_FIFO_BUFFER_SIZE; + return diff; +} + +int readUsartFifo(SZ_USART_FIFO *fifo, int8_t *buf, int32_t len) { + int i = 0 ; + while (i < len && fifo->uart_read_point != fifo->uart_write_point) { + buf[i++] = fifo->uartTxBuffer[fifo->uart_read_point]; + fifo->uart_read_point = BUF_INC_POINTER(fifo->uart_read_point); + } + return i; +} + +int writeUsartFifo(SZ_USART_FIFO *fifo, int8_t *buf, int32_t len) { + if (buf == 0 || len <= 0) return -1; + + int i = 0 ; + while (i < len && fifo->uart_read_point != BUF_INC_POINTER(fifo->uart_write_point)) { + fifo->uartTxBuffer[fifo->uart_write_point] = buf[i++]; + fifo->uart_write_point = BUF_INC_POINTER(fifo->uart_write_point); + } + return i; +} + +void get_wifi_commands() { + static char wifi_line_buffer[MAX_CMD_SIZE]; + static bool wifi_comment_mode = false; + static int wifi_read_count = 0; + + if (espGcodeFifo.wait_tick > 5) { + while ((queue.length < BUFSIZE) && (espGcodeFifo.r != espGcodeFifo.w)) { + + espGcodeFifo.wait_tick = 0; + + char wifi_char = espGcodeFifo.Buffer[espGcodeFifo.r]; + + espGcodeFifo.r = (espGcodeFifo.r + 1) % WIFI_GCODE_BUFFER_SIZE; + + /** + * If the character ends the line + */ + if (wifi_char == '\n' || wifi_char == '\r') { + + wifi_comment_mode = false; // end of line == end of comment + + if (!wifi_read_count) continue; // skip empty lines + + wifi_line_buffer[wifi_read_count] = 0; // terminate string + wifi_read_count = 0; //reset buffer + + char* command = wifi_line_buffer; + while (*command == ' ') command++; // skip any leading spaces + + // Movement commands alert when stopped + if (IsStopped()) { + char* gpos = strchr(command, 'G'); + if (gpos) { + switch (strtol(gpos + 1, nullptr, 10)) { + case 0 ... 1: + #if ENABLED(ARC_SUPPORT) + case 2 ... 3: + #endif + #if ENABLED(BEZIER_CURVE_SUPPORT) + case 5: + #endif + SERIAL_ECHOLNPGM(STR_ERR_STOPPED); + LCD_MESSAGEPGM(MSG_STOPPED); + break; + } + } + } + + #if DISABLED(EMERGENCY_PARSER) + // Process critical commands early + if (strcmp(command, "M108") == 0) { + wait_for_heatup = false; + TERN_(HAS_LCD_MENU, wait_for_user = false); + } + if (strcmp(command, "M112") == 0) kill(M112_KILL_STR, nullptr, true); + if (strcmp(command, "M410") == 0) quickstop_stepper(); + #endif + + // Add the command to the queue + queue.enqueue_one_P(wifi_line_buffer); + } + else if (wifi_read_count >= MAX_CMD_SIZE - 1) { + + } + else { // it's not a newline, carriage return or escape char + if (wifi_char == ';') wifi_comment_mode = true; + if (!wifi_comment_mode) wifi_line_buffer[wifi_read_count++] = wifi_char; + } + } + }// queue has space, serial has data + else { + espGcodeFifo.wait_tick++; + } +} + +int readWifiBuf(int8_t *buf, int32_t len) { + int i = 0; + while (i < len && WIFISERIAL.available()) + buf[i++] = WIFISERIAL.read(); + return i; +} + +#endif // USE_WIFI_FUNCTION +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.h b/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.h new file mode 100644 index 000000000000..0b402a3adb10 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.h @@ -0,0 +1,202 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +#include "../../inc/MarlinConfigPre.h" + +#include +#include +#include + +#define UART_RX_BUFFER_SIZE 1024 +#define UART_FIFO_BUFFER_SIZE 1024 + +#define ESP_WIFI 0x02 + +#define AP_MODEL 0x01 +#define STA_MODEL 0x02 + +#define WIFI_DECODE_TYPE 1 + +#define IP_DHCP_FLAG 1 + +#define WIFI_AP_NAME "TP-LINK_MKS" +#define WIFI_KEY_CODE "makerbase" + +#define IP_ADDR "192.168.3.100" +#define IP_MASK "255.255.255.0" +#define IP_GATE "192.168.3.1" +#define IP_DNS "192.168.3.1" + +#define AP_IP_DHCP_FLAG 1 +#define AP_IP_ADDR "192.168.3.100" +#define AP_IP_MASK "255.255.255.0" +#define AP_IP_GATE "192.168.3.1" +#define AP_IP_DNS "192.168.3.1" +#define IP_START_IP "192.168.3.1" +#define IP_END_IP "192.168.3.255" + +#define UDISKBUFLEN 1024 + +typedef enum{ + udisk_buf_empty = 0, + udisk_buf_full, +} UDISK_DATA_BUFFER_STATE; + +#define TRANS_RCV_FIFO_BLOCK_NUM 8 + +typedef struct { + unsigned char *bufferAddr[TRANS_RCV_FIFO_BLOCK_NUM]; + unsigned char *p; + UDISK_DATA_BUFFER_STATE state[TRANS_RCV_FIFO_BLOCK_NUM]; + unsigned char read_cur; + unsigned char write_cur; +} WIFI_DMA_RCV_FIFO; + +typedef struct { + uint8_t flag; // 0x0: no error; 0x01: error + uint32_t start_tick; //error start time + uint32_t now_tick; +} WIFI_TRANS_ERROR; + +extern volatile WIFI_TRANS_ERROR wifiTransError; + +typedef struct { + char ap_name[32]; //wifi-name + char keyCode[64]; //wifi password + int decodeType; + int baud; + int mode; +} WIFI_PARA; + +typedef struct { + char state; + char hostUrl[96]; + int port; + char id[21]; +} CLOUD_PARA; + +typedef struct { + char dhcp_flag; + char ip_addr[16]; + char mask[16]; + char gate[16]; + char dns[16]; + + char dhcpd_flag; + char dhcpd_ip[16]; + char dhcpd_mask[16]; + char dhcpd_gate[16]; + char dhcpd_dns[16]; + char start_ip_addr[16]; + char end_ip_addr[16]; +} IP_PARA; + +typedef enum { + WIFI_NOT_CONFIG, + WIFI_CONFIG_MODE, + WIFI_CONFIG_DHCP, + WIFI_CONFIG_AP, + WIFI_CONFIG_IP_INF, + WIFI_CONFIG_DNS, + WIFI_CONFIG_TCP, + WIFI_CONFIG_SERVER, + WIFI_CONFIG_REMOTE_PORT, + WIFI_CONFIG_BAUD, + WIFI_CONFIG_COMMINT, + WIFI_CONFIG_OK, + WIFI_GET_IP_OK, + WIFI_RECONN, + WIFI_CONNECTED, + WIFI_WAIT_TRANS_START, + WIFI_TRANS_FILE, + WIFI_CONFIG_DHCPD, + WIFI_COFIG_DHCPD_IP, + WIFI_COFIG_DHCPD_DNS, + WIFI_EXCEPTION, +} WIFI_STATE; + +typedef enum { + TRANSFER_IDLE, + TRANSFERING, + TRANSFER_STORE, +} TRANSFER_STATE; +extern volatile TRANSFER_STATE esp_state; + +typedef struct { + char buf[20][80]; + int rd_index; + int wt_index; +} QUEUE; + +typedef enum { + WIFI_PARA_SET, // 0x0:net parameter + WIFI_PRINT_INF, // 0x1:print message + WIFI_TRANS_INF, // 0x2:Pass through information + WIFI_EXCEP_INF, // 0x3:Exception information + WIFI_CLOUD_CFG, // 0x4:cloud config + WIFI_CLOUD_UNBIND, // 0x5:Unbind ID +} WIFI_RET_TYPE; + +typedef struct { + uint32_t uart_read_point; + uint32_t uart_write_point; + uint8_t uartTxBuffer[UART_FIFO_BUFFER_SIZE]; +} SZ_USART_FIFO; + +#define WIFI_GCODE_BUFFER_LEAST_SIZE 96 +#define WIFI_GCODE_BUFFER_SIZE (WIFI_GCODE_BUFFER_LEAST_SIZE * 3) +typedef struct { + uint8_t wait_tick; + uint8_t Buffer[WIFI_GCODE_BUFFER_SIZE]; + uint32_t r; + uint32_t w; +} WIFI_GCODE_BUFFER; + +extern volatile WIFI_STATE wifi_link_state; +extern WIFI_PARA wifiPara; +extern IP_PARA ipPara; +extern CLOUD_PARA cloud_para; + +extern WIFI_GCODE_BUFFER espGcodeFifo; + +extern uint32_t getWifiTick(); +extern uint32_t getWifiTickDiff(int32_t lastTick, int32_t curTick); + +extern void mks_esp_wifi_init(); +extern int cfg_cloud_flag; +extern int send_to_wifi(char *buf, int len); +extern void wifi_looping(); +extern int raw_send_to_wifi(char *buf, int len); +extern int package_to_wifi(WIFI_RET_TYPE type,char *buf, int len); +extern void get_wifi_list_command_send(); +extern void get_wifi_commands(); +extern int readWifiBuf(int8_t *buf, int32_t len); +extern int storeRcvData(int32_t len); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/wifi_upload.cpp b/Marlin/src/lcd/extui/lib/mks_ui/wifi_upload.cpp new file mode 100644 index 000000000000..087a3b21105c --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/wifi_upload.cpp @@ -0,0 +1,829 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if HAS_TFT_LVGL_UI + +#include "draw_ui.h" +#include "wifi_module.h" +#include "wifi_upload.h" + +#include "../../../../MarlinCore.h" + +#define WIFI_SET() WRITE(WIFI_RESET_PIN, HIGH); +#define WIFI_RESET() WRITE(WIFI_RESET_PIN, LOW); +#define WIFI_IO1_SET() WRITE(WIFI_IO1_PIN, HIGH); +#define WIFI_IO1_RESET() WRITE(WIFI_IO1_PIN, LOW); + +extern SZ_USART_FIFO WifiRxFifo; + +extern int readUsartFifo(SZ_USART_FIFO *fifo, int8_t *buf, int32_t len); +extern int writeUsartFifo(SZ_USART_FIFO * fifo, int8_t * buf, int32_t len); +extern void esp_port_begin(uint8_t interrupt); +extern int usartFifoAvailable(SZ_USART_FIFO *fifo); +extern void wifi_delay(int n); + +#define ARRAY_SIZE(a) sizeof(a) / sizeof((a)[0]) + +//typedef signed char bool; + +// ESP8266 command codes +const uint8_t ESP_FLASH_BEGIN = 0x02; +const uint8_t ESP_FLASH_DATA = 0x03; +const uint8_t ESP_FLASH_END = 0x04; +const uint8_t ESP_MEM_BEGIN = 0x05; +const uint8_t ESP_MEM_END = 0x06; +const uint8_t ESP_MEM_DATA = 0x07; +const uint8_t ESP_SYNC = 0x08; +const uint8_t ESP_WRITE_REG = 0x09; +const uint8_t ESP_READ_REG = 0x0A; + +// MAC address storage locations +const uint32_t ESP_OTP_MAC0 = 0x3FF00050; +const uint32_t ESP_OTP_MAC1 = 0x3FF00054; +const uint32_t ESP_OTP_MAC2 = 0x3FF00058; +const uint32_t ESP_OTP_MAC3 = 0x3FF0005C; + +const size_t EspFlashBlockSize = 0x0400; // 1K byte blocks + +const uint8_t ESP_IMAGE_MAGIC = 0xE9; +const uint8_t ESP_CHECKSUM_MAGIC = 0xEF; + +const uint32_t ESP_ERASE_CHIP_ADDR = 0x40004984; // &SPIEraseChip +const uint32_t ESP_SEND_PACKET_ADDR = 0x40003C80; // &send_packet +const uint32_t ESP_SPI_READ_ADDR = 0x40004B1C; // &SPIRead +const uint32_t ESP_UNKNOWN_ADDR = 0x40001121; // not used +const uint32_t ESP_USER_DATA_RAM_ADDR = 0x3FFE8000; // &user data ram +const uint32_t ESP_IRAM_ADDR = 0x40100000; // instruction RAM +const uint32_t ESP_FLASH_ADDR = 0x40200000; // address of start of Flash +//const uint32_t ESP_FLASH_READ_STUB_BEGIN = IRAM_ADDR + 0x18; + +UPLOAD_STRUCT esp_upload; + +static const unsigned int retriesPerReset = 3; +static const uint32_t connectAttemptInterval = 50; +static const unsigned int percentToReportIncrement = 5; // how often we report % complete +static const uint32_t defaultTimeout = 500; +static const uint32_t eraseTimeout = 15000; +static const uint32_t blockWriteTimeout = 200; +static const uint32_t blockWriteInterval = 15; // 15ms is long enough, 10ms is mostly too short + +// Messages corresponding to result codes, should make sense when followed by " error" +const char *resultMessages[] = { + "no", + "timeout", + "comm write", + "connect", + "bad reply", + "file read", + "empty file", + "response header", + "slip frame", + "slip state", + "slip data" +}; + +// A note on baud rates. +// The ESP8266 supports 921600, 460800, 230400, 115200, 74880 and some lower baud rates. +// 921600b is not reliable because even though it sometimes succeeds in connecting, we get a bad response during uploading after a few blocks. +// Probably our UART ISR cannot receive bytes fast enough, perhaps because of the latency of the system tick ISR. +// 460800b doesn't always manage to connect, but if it does then uploading appears to be reliable. +// 230400b always manages to connect. +static const uint32_t uploadBaudRates[] = { 460800, 230400, 115200, 74880 }; + +signed char IsReady() { + return esp_upload.state == upload_idle; +} + +void uploadPort_write(const uint8_t *buf, size_t len) { + #if 0 + int i; + + for (i = 0; i < len; i++) { + while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) { /* nada */ } + USART_SendData(USART1, *(buf + i)); + } + #endif +} + +char uploadPort_read() { + uint8_t retChar; + if (readUsartFifo(&WifiRxFifo, (int8_t *)&retChar, 1) == 1) + return retChar; + else + return 0; +} + +int uploadPort_available() { + return usartFifoAvailable(&WifiRxFifo); +} + +void uploadPort_begin() { + esp_port_begin(1); +} + +void uploadPort_close() { + //WIFI_COM.end(); + //WIFI_COM.begin(115200, true); + esp_port_begin(0); +} + +void flushInput() { + while (uploadPort_available() != 0) { + (void)uploadPort_read(); + //IWDG_ReloadCounter(); + } +} + +// Extract 1-4 bytes of a value in little-endian order from a buffer beginning at a specified offset +uint32_t getData(unsigned byteCnt, const uint8_t *buf, int ofst) { + uint32_t val = 0; + + if (buf && byteCnt) { + unsigned int shiftCnt = 0; + if (byteCnt > 4) + byteCnt = 4; + do{ + val |= (uint32_t)buf[ofst++] << shiftCnt; + shiftCnt += 8; + } while (--byteCnt); + } + return(val); +} + +// Put 1-4 bytes of a value in little-endian order into a buffer beginning at a specified offset. +void putData(uint32_t val, unsigned byteCnt, uint8_t *buf, int ofst) { + if (buf && byteCnt) { + if (byteCnt > 4) { + byteCnt = 4; + } + do { + buf[ofst++] = (uint8_t)(val & 0xFF); + val >>= 8; + } while (--byteCnt); + } +} + +// Read a byte optionally performing SLIP decoding. The return values are: +// +// 2 - an escaped byte was read successfully +// 1 - a non-escaped byte was read successfully +// 0 - no data was available +// -1 - the value 0xC0 was encountered (shouldn't happen) +// -2 - a SLIP escape byte was found but the following byte wasn't available +// -3 - a SLIP escape byte was followed by an invalid byte +int ReadByte(uint8_t *data, signed char slipDecode) { + if (uploadPort_available() == 0) { + return(0); + } + + // at least one byte is available + *data = uploadPort_read(); + if (!slipDecode) { + return(1); + } + + if (*data == 0xC0) { + // this shouldn't happen + return(-1); + } + + // if not the SLIP escape, we're done + if (*data != 0xDB) { + return(1); + } + + // SLIP escape, check availability of subsequent byte + if (uploadPort_available() == 0) { + return(-2); + } + + // process the escaped byte + *data = uploadPort_read(); + if (*data == 0xDC) { + *data = 0xC0; + return(2); + } + + if (*data == 0xDD) { + *data = 0xDB; + return(2); + } + // invalid + return(-3); +} +// When we write a sync packet, there must be no gaps between most of the characters. +// So use this function, which does a block write to the UART buffer in the latest CoreNG. +void _writePacketRaw(const uint8_t *buf, size_t len) { + uploadPort_write(buf, len); +} + +// Write a byte to the serial port optionally SLIP encoding. Return the number of bytes actually written. +void WriteByteRaw(uint8_t b) { + uploadPort_write((const uint8_t *)&b, 1); +} + +// Write a byte to the serial port optionally SLIP encoding. Return the number of bytes actually written. +void WriteByteSlip(uint8_t b) { + if (b == 0xC0) { + WriteByteRaw(0xDB); + WriteByteRaw(0xDC); + } + else if (b == 0xDB) { + WriteByteRaw(0xDB); + WriteByteRaw(0xDD); + } + else { + uploadPort_write((const uint8_t *)&b, 1); + } +} + +// Wait for a data packet to be returned. If the body of the packet is +// non-zero length, return an allocated buffer indirectly containing the +// data and return the data length. Note that if the pointer for returning +// the data buffer is NULL, the response is expected to be two bytes of zero. +// +// If an error occurs, return a negative value. Otherwise, return the number +// of bytes in the response (or zero if the response was not the standard "two bytes of zero"). +EspUploadResult readPacket(uint8_t op, uint32_t *valp, size_t *bodyLen, uint32_t msTimeout) { + typedef enum { + begin = 0, + header, + body, + end, + done + } PacketState; + + uint8_t resp, opRet; + + const size_t headerLength = 8; + + uint32_t startTime = getWifiTick(); + uint8_t hdr[headerLength]; + uint16_t hdrIdx = 0; + + uint16_t bodyIdx = 0; + uint8_t respBuf[2]; + + // wait for the response + uint16_t needBytes = 1; + + PacketState state = begin; + + *bodyLen = 0; + + while (state != done) { + uint8_t c; + EspUploadResult stat; + + //IWDG_ReloadCounter(); + + if (getWifiTickDiff(startTime, getWifiTick()) > msTimeout) { + return(timeout); + } + + if (uploadPort_available() < needBytes) { + // insufficient data available + // preferably, return to Spin() here + continue; + } + + // sufficient bytes have been received for the current state, process them + switch (state) { + case begin: // expecting frame start + c = uploadPort_read(); + if (c != (uint8_t)0xC0) { + break; + } + state = header; + needBytes = 2; + + break; + case end: // expecting frame end + c = uploadPort_read(); + if (c != (uint8_t)0xC0) { + return slipFrame; + } + state = done; + + break; + + case header: // reading an 8-byte header + case body: // reading the response body + { + int rslt; + // retrieve a byte with SLIP decoding + rslt = ReadByte(&c, 1); + if (rslt != 1 && rslt != 2) { + // some error occurred + stat = (rslt == 0 || rslt == -2) ? slipData : slipFrame; + return stat; + } + else if (state == header) { + //store the header byte + hdr[hdrIdx++] = c; + if (hdrIdx >= headerLength) { + // get the body length, prepare a buffer for it + *bodyLen = (uint16_t)getData(2, hdr, 2); + + // extract the value, if requested + if (valp != 0) { + *valp = getData(4, hdr, 4); + } + + if (*bodyLen != 0) { + state = body; + } + else { + needBytes = 1; + state = end; + } + } + } + else { + // Store the response body byte, check for completion + if (bodyIdx < ARRAY_SIZE(respBuf)) { + respBuf[bodyIdx] = c; + } + ++bodyIdx; + if (bodyIdx >= *bodyLen) { + needBytes = 1; + state = end; + } + } + } + break; + + default: // this shouldn't happen + return slipState; + } + } + + // Extract elements from the header + resp = (uint8_t)getData(1, hdr, 0); + opRet = (uint8_t)getData(1, hdr, 1); + // Sync packets often provoke a response with a zero opcode instead of ESP_SYNC + if (resp != 0x01 || opRet != op) { + //printf("resp %02x %02x\n", resp, opRet); //debug + return respHeader; + } + + return success; +} + +// Send a block of data performing SLIP encoding of the content. +void _writePacket(const uint8_t *data, size_t len) { + unsigned char outBuf[2048] = {0}; + unsigned int outIndex = 0; + while (len != 0) { + if (*data == 0xC0) { + outBuf[outIndex++] = 0xDB; + outBuf[outIndex++] = 0xDC; + } + else if (*data == 0xDB) { + outBuf[outIndex++] = 0xDB; + outBuf[outIndex++] = 0xDD; + } + else { + outBuf[outIndex++] = *data; + + } + data++; + --len; + } + uploadPort_write((const uint8_t *)outBuf, outIndex); +} + +// Send a packet to the serial port while performing SLIP framing. The packet data comprises a header and an optional data block. +// A SLIP packet begins and ends with 0xC0. The data encapsulated has the bytes +// 0xC0 and 0xDB replaced by the two-byte sequences {0xDB, 0xDC} and {0xDB, 0xDD} respectively. + +void writePacket(const uint8_t *hdr, size_t hdrLen, const uint8_t *data, size_t dataLen) { + WriteByteRaw(0xC0); // send the packet start character + _writePacket(hdr, hdrLen); // send the header + _writePacket(data, dataLen); // send the data block + WriteByteRaw(0xC0); // send the packet end character +} + +// Send a packet to the serial port while performing SLIP framing. The packet data comprises a header and an optional data block. +// This is like writePacket except that it does a fast block write for both the header and the main data with no SLIP encoding. Used to send sync commands. +void writePacketRaw(const uint8_t *hdr, size_t hdrLen, const uint8_t *data, size_t dataLen) { + WriteByteRaw(0xC0); // send the packet start character + _writePacketRaw(hdr, hdrLen); // send the header + _writePacketRaw(data, dataLen); // send the data block in raw mode + WriteByteRaw(0xC0); // send the packet end character +} + +// Send a command to the attached device together with the supplied data, if any. +// The data is supplied via a list of one or more segments. +void sendCommand(uint8_t op, uint32_t checkVal, const uint8_t *data, size_t dataLen) { + // populate the header + uint8_t hdr[8]; + putData(0, 1, hdr, 0); + putData(op, 1, hdr, 1); + putData(dataLen, 2, hdr, 2); + putData(checkVal, 4, hdr, 4); + + // send the packet + //flushInput(); + if (op == ESP_SYNC) + writePacketRaw(hdr, sizeof(hdr), data, dataLen); + else + writePacket(hdr, sizeof(hdr), data, dataLen); +} + +// Send a command to the attached device together with the supplied data, if any, and get the response +EspUploadResult doCommand(uint8_t op, const uint8_t *data, size_t dataLen, uint32_t checkVal, uint32_t *valp, uint32_t msTimeout) { + size_t bodyLen; + EspUploadResult stat; + + sendCommand(op, checkVal, data, dataLen); + + stat = readPacket(op, valp, &bodyLen, msTimeout); + if (stat == success && bodyLen != 2) + stat = badReply; + + return stat; +} + +// Send a synchronising packet to the serial port in an attempt to induce +// the ESP8266 to auto-baud lock on the baud rate. +EspUploadResult Sync(uint16_t timeout) { + uint8_t buf[36]; + EspUploadResult stat; + int i ; + + // compose the data for the sync attempt + memset(buf, 0x55, sizeof(buf)); + buf[0] = 0x07; + buf[1] = 0x07; + buf[2] = 0x12; + buf[3] = 0x20; + + stat = doCommand(ESP_SYNC, buf, sizeof(buf), 0, 0, timeout); + + // If we got a response other than sync, discard it and wait for a sync response. This happens at higher baud rates. + for (i = 0; i < 10 && stat == respHeader; ++i) { + size_t bodyLen; + stat = readPacket(ESP_SYNC, 0, &bodyLen, timeout); + } + + if (stat == success) { + // Read and discard additional replies + for (;;) { + size_t bodyLen; + EspUploadResult rc = readPacket(ESP_SYNC, 0, &bodyLen, defaultTimeout); + if (rc != success || bodyLen != 2) { + break; + } + } + } + //DEBUG + //else debug//printf("stat=%d\n", (int)stat); + return stat; +} + +// Send a command to the device to begin the Flash process. +EspUploadResult flashBegin(uint32_t addr, uint32_t size) { + // determine the number of blocks represented by the size + uint32_t blkCnt; + uint8_t buf[16]; + uint32_t timeout; + + blkCnt = (size + EspFlashBlockSize - 1) / EspFlashBlockSize; + + // ensure that the address is on a block boundary + addr &= ~(EspFlashBlockSize - 1); + + // begin the Flash process + putData(size, 4, buf, 0); + putData(blkCnt, 4, buf, 4); + putData(EspFlashBlockSize, 4, buf, 8); + putData(addr, 4, buf, 12); + + timeout = (size != 0) ? eraseTimeout : defaultTimeout; + return doCommand(ESP_FLASH_BEGIN, buf, sizeof(buf), 0, 0, timeout); +} + +// Send a command to the device to terminate the Flash process +EspUploadResult flashFinish(signed char reboot) { + uint8_t buf[4]; + putData(reboot ? 0 : 1, 4, buf, 0); + return doCommand(ESP_FLASH_END, buf, sizeof(buf), 0, 0, defaultTimeout); +} + +// Compute the checksum of a block of data +uint16_t checksum(const uint8_t *data, uint16_t dataLen, uint16_t cksum) { + if (data != NULL) { + while (dataLen--) { + cksum ^= (uint16_t)*data++; + } + } + return(cksum); +} + +EspUploadResult flashWriteBlock(uint16_t flashParmVal, uint16_t flashParmMask) { + #if 0 + const uint32_t blkSize = EspFlashBlockSize; + int i; + + // Allocate a data buffer for the combined header and block data + const uint16_t hdrOfst = 0; + const uint16_t dataOfst = 16; + const uint16_t blkBufSize = dataOfst + blkSize; + uint32_t blkBuf32[blkBufSize/4]; + uint8_t * const blkBuf = (uint8_t*)(blkBuf32); + uint32_t cnt; + uint16_t cksum; + EspUploadResult stat; + + // Prepare the header for the block + putData(blkSize, 4, blkBuf, hdrOfst + 0); + putData(esp_upload.uploadBlockNumber, 4, blkBuf, hdrOfst + 4); + putData(0, 4, blkBuf, hdrOfst + 8); + putData(0, 4, blkBuf, hdrOfst + 12); + + // Get the data for the block + f_read(&esp_upload.uploadFile, blkBuf + dataOfst, blkSize, &cnt );//->Read(reinterpret_cast(blkBuf + dataOfst), blkSize); + if (cnt != blkSize) { + if (f_tell(&esp_upload.uploadFile) == esp_upload.fileSize) { + // partial last block, fill the remainder + memset(blkBuf + dataOfst + cnt, 0xFF, blkSize - cnt); + } + else { + return fileRead; + } + } + + // Patch the flash parameters into the first block if it is loaded at address 0 + if (esp_upload.uploadBlockNumber == 0 && esp_upload.uploadAddress == 0 && blkBuf[dataOfst] == ESP_IMAGE_MAGIC && flashParmMask != 0) { + // update the Flash parameters + uint32_t flashParm = getData(2, blkBuf + dataOfst + 2, 0) & ~(uint32_t)flashParmMask; + putData(flashParm | flashParmVal, 2, blkBuf + dataOfst + 2, 0); + } + + // Calculate the block checksum + cksum = checksum(blkBuf + dataOfst, blkSize, ESP_CHECKSUM_MAGIC); + + for (i = 0; i < 3; i++) { + if ((stat = doCommand(ESP_FLASH_DATA, blkBuf, blkBufSize, cksum, 0, blockWriteTimeout)) == success) { + break; + } + } + + //printf("Upload %d\%\n", ftell(&esp_upload.uploadFile) * 100 / esp_upload.fileSize); + + return stat; + #else + return success; + #endif +} + +void upload_spin() { + #if 0 + switch (esp_upload.state) { + case resetting: + + if (esp_upload.connectAttemptNumber == 9) { + // Time to give up + //Network::ResetWiFi(); + esp_upload.uploadResult = connected; + esp_upload.state = done; + } + else { + + // Reset the serial port at the new baud rate. Also reset the ESP8266. + // const uint32_t baud = uploadBaudRates[esp_upload.connectAttemptNumber/esp_upload.retriesPerBaudRate]; + if (esp_upload.connectAttemptNumber % esp_upload.retriesPerBaudRate == 0) { + } + //uploadPort.begin(baud); + //uploadPort_close(); + + uploadPort_begin(); + + wifi_delay(2000); + + flushInput(); + + esp_upload.lastAttemptTime = esp_upload.lastResetTime = getWifiTick(); + esp_upload.state = connecting; + } + + break; + + case connecting: + if ((getWifiTickDiff(esp_upload.lastAttemptTime, getWifiTick()) >= connectAttemptInterval) && (getWifiTickDiff(esp_upload.lastResetTime, getWifiTick()) >= 500)) { + // Attempt to establish a connection to the ESP8266. + EspUploadResult res = Sync(5000); + esp_upload.lastAttemptTime = getWifiTick(); + if (res == success) { + // Successful connection + //MessageF(" success on attempt %d\n", (connectAttemptNumber % retriesPerBaudRate) + 1); + //printf("connect success\n"); + esp_upload.state = erasing; + } + else { + // This attempt failed + esp_upload.connectAttemptNumber++; + if (esp_upload.connectAttemptNumber % retriesPerReset == 0) { + esp_upload.state = resetting; // try a reset and a lower baud rate + } + } + } + break; + + case erasing: + if (getWifiTickDiff(esp_upload.lastAttemptTime, getWifiTick()) >= blockWriteInterval) { + uint32_t eraseSize; + const uint32_t sectorsPerBlock = 16; + const uint32_t sectorSize = 4096; + const uint32_t numSectors = (esp_upload.fileSize + sectorSize - 1)/sectorSize; + const uint32_t startSector = esp_upload.uploadAddress/sectorSize; + + uint32_t headSectors = sectorsPerBlock - (startSector % sectorsPerBlock); + NOMORE(headSectors, numSectors); + + eraseSize = (numSectors < 2 * headSectors) + ? (numSectors + 1) / 2 * sectorSize + : (numSectors - headSectors) * sectorSize; + + //MessageF("Erasing %u bytes...\n", fileSize); + esp_upload.uploadResult = flashBegin(esp_upload.uploadAddress, eraseSize); + if (esp_upload.uploadResult == success) { + //MessageF("Uploading file...\n"); + esp_upload.uploadBlockNumber = 0; + esp_upload.uploadNextPercentToReport = percentToReportIncrement; + esp_upload.lastAttemptTime = getWifiTick(); + esp_upload.state = uploading; + } + else { + //MessageF("Erase failed\n"); + esp_upload.state = done; + } + } + break; + + case uploading: + // The ESP needs several milliseconds to recover from one packet before it will accept another + if (getWifiTickDiff(esp_upload.lastAttemptTime, getWifiTick()) >= 15) { + unsigned int percentComplete; + const uint32_t blkCnt = (esp_upload.fileSize + EspFlashBlockSize - 1) / EspFlashBlockSize; + if (esp_upload.uploadBlockNumber < blkCnt) { + esp_upload.uploadResult = flashWriteBlock(0, 0); + esp_upload.lastAttemptTime = getWifiTick(); + if (esp_upload.uploadResult != success) { + //MessageF("Flash block upload failed\n"); + esp_upload.state = done; + } + percentComplete = (100 * esp_upload.uploadBlockNumber)/blkCnt; + ++esp_upload.uploadBlockNumber; + if (percentComplete >= esp_upload.uploadNextPercentToReport) { + //MessageF("%u%% complete\n", percentComplete); + esp_upload.uploadNextPercentToReport += percentToReportIncrement; + } + } + else { + esp_upload.state = done; + } + } + break; + + case done: + f_close(&esp_upload.uploadFile); + //uploadPort.end(); + //uploadPort_close(); + + //WIFI_COM.begin(115200, true); + //wifi_init(); + + if (esp_upload.uploadResult == success) { + //printf("upload successfully\n"); + } + else { + //printf("upload failed\n"); + } + esp_upload.state = upload_idle;//idle; + break; + + default: + break; + } + #endif +} + +// Try to upload the given file at the given address +void SendUpdateFile(const char *file, uint32_t address) { + #if 0 + FRESULT res = f_open(&esp_upload.uploadFile, file, FA_OPEN_EXISTING | FA_READ); + + if (res != FR_OK) return; + + esp_upload.fileSize = f_size(&esp_upload.uploadFile); + if (esp_upload.fileSize == 0) { + f_close(&esp_upload.uploadFile); + return; + } + f_lseek(&esp_upload.uploadFile, 0); + + esp_upload.uploadAddress = address; + esp_upload.connectAttemptNumber = 0; + esp_upload.state = resetting; + #endif +} + +static const uint32_t FirmwareAddress = 0x00000000, WebFilesAddress = 0x00100000; + +void ResetWiFiForUpload(int begin_or_end) { + #if 0 + uint32_t start, now; + + GPIO_InitTypeDef GPIO_InitStructure; + + #if V1_0_V1_1 + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStructure.Pin = GPIO_Pin_8; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); + #else + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStructure.Pin = GPIO_Pin_13; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); + #endif + start = getWifiTick(); + now = start; + + if (begin_or_end == 0) { + #if V1_0_V1_1 + HAL_GPIO_WritePin(GPIOA,GPIO_Pin_8,GPIO_PIN_RESET); //update mode + #else + HAL_GPIO_WritePin(GPIOC,GPIO_Pin_13,GPIO_PIN_RESET); //update mode + #endif + } + else { + #if V1_0_V1_1 + #if V1_0_V1_1 + HAL_GPIO_WritePin(GPIOA,GPIO_Pin_8,GPIO_PIN_SET); //boot mode + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStructure.Pin = GPIO_Pin_8; + GPIO_InitStructure.Mode = GPIO_MODE_INPUT; + HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); + #endif + #else + HAL_GPIO_WritePin(GPIOC,GPIO_Pin_13,GPIO_PIN_SET); //boot mode + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStructure.Pin = GPIO_Pin_13; + GPIO_InitStructure.Mode = GPIO_MODE_INPUT; + HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); + #endif + } + WIFI_RESET(); + while (getWifiTickDiff(start, now) < 500) now = getWifiTick(); + WIFI_SET(); + #endif +} + +int32_t wifi_upload(int type) { + esp_upload.retriesPerBaudRate = 9; + + ResetWiFiForUpload(0); + + if (type == 0) + SendUpdateFile(ESP_FIRMWARE_FILE, FirmwareAddress); + else if (type == 1) + SendUpdateFile(ESP_WEB_FIRMWARE_FILE, FirmwareAddress); + else if (type == 2) + SendUpdateFile(ESP_WEB_FILE, WebFilesAddress); + else + return -1; + + while (esp_upload.state != upload_idle) { + upload_spin(); + //IWDG_ReloadCounter(); + } + + ResetWiFiForUpload(1); + + return esp_upload.uploadResult == success ? 0 : -1; +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/wifi_upload.h b/Marlin/src/lcd/extui/lib/mks_ui/wifi_upload.h new file mode 100644 index 000000000000..d942a2c84f80 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/wifi_upload.h @@ -0,0 +1,74 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +#define ESP_FIRMWARE_FILE "1:/MksWifi.bin" +#define ESP_WEB_FIRMWARE_FILE "1:/MksWifi_Web.bin" +#define ESP_WEB_FILE "1:/MksWifi_WebView.bin" + +typedef enum { + upload_idle, + resetting, + connecting, + erasing, + uploading, + done +} UploadState; + +typedef enum { + success = 0, + timeout, + connected, + badReply, + fileRead, + emptyFile, + respHeader, + slipFrame, + slipState, + slipData, +} EspUploadResult; + +typedef struct { + //FIL uploadFile; + uint32_t fileSize; + + uint32_t uploadAddress; + UploadState state; + uint32_t retriesPerBaudRate; + uint32_t connectAttemptNumber; + uint32_t lastAttemptTime; + uint32_t lastResetTime; + uint32_t uploadBlockNumber; + uint32_t uploadNextPercentToReport; + EspUploadResult uploadResult; +} UPLOAD_STRUCT; + +extern UPLOAD_STRUCT esp_upload; +int32_t wifi_upload(int type); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui_malyan_lcd.cpp b/Marlin/src/lcd/extui/malyan_lcd.cpp similarity index 79% rename from Marlin/src/lcd/extui_malyan_lcd.cpp rename to Marlin/src/lcd/extui/malyan_lcd.cpp index 0d2567a20489..79a5fb961aa1 100644 --- a/Marlin/src/lcd/extui_malyan_lcd.cpp +++ b/Marlin/src/lcd/extui/malyan_lcd.cpp @@ -16,12 +16,12 @@ * 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 . + * along with this program. If not, see . * */ /** - * extui_malyan_lcd.cpp + * malyan_lcd.cpp * * LCD implementation for Malyan's LCD, a separate ESP8266 MCU running * on Serial1 for the M200 board. This module outputs a pseudo-gcode @@ -41,29 +41,25 @@ * Copyright (c) 2017 Jason Nelson (xC0000005) */ -#include "../inc/MarlinConfigPre.h" +#include "../../inc/MarlinConfigPre.h" #if ENABLED(MALYAN_LCD) -#define DEBUG_MALYAN_LCD +//#define DEBUG_MALYAN_LCD -#include "extensible_ui/ui_api.h" +#include "ui_api.h" -#include "ultralcd.h" -#include "../sd/cardreader.h" -#include "../module/temperature.h" -#include "../module/stepper.h" -#include "../module/motion.h" -#include "../libs/duration_t.h" -#include "../module/printcounter.h" -#include "../gcode/queue.h" +#include "../ultralcd.h" +#include "../../sd/cardreader.h" +#include "../../module/temperature.h" +#include "../../module/stepper.h" +#include "../../module/motion.h" +#include "../../libs/duration_t.h" +#include "../../module/printcounter.h" +#include "../../gcode/queue.h" #define DEBUG_OUT ENABLED(DEBUG_MALYAN_LCD) -#include "../core/debug_out.h" - -// On the Malyan M200, this will be Serial1. On a RAMPS board, -// it might not be. -#define LCD_SERIAL Serial1 +#include "../../core/debug_out.h" // This is based on longest sys command + a filename, plus some buffer // in case we encounter some data we don't recognize @@ -71,7 +67,7 @@ #define MAX_CURLY_COMMAND (32 + LONG_FILENAME_LENGTH) * 2 // Track incoming command bytes from the LCD -int inbound_count; +uint16_t inbound_count; // For sending print completion messages bool last_printing_status = false; @@ -81,7 +77,7 @@ void write_to_lcd_P(PGM_P const message) { char encoded_message[MAX_CURLY_COMMAND]; uint8_t message_length = _MIN(strlen_P(message), sizeof(encoded_message)); - for (uint8_t i = 0; i < message_length; i++) + LOOP_L_N(i, message_length) encoded_message[i] = pgm_read_byte(&message[i]) | 0x80; LCD_SERIAL.Print::write(encoded_message, message_length); @@ -91,12 +87,24 @@ void write_to_lcd(const char * const message) { char encoded_message[MAX_CURLY_COMMAND]; const uint8_t message_length = _MIN(strlen(message), sizeof(encoded_message)); - for (uint8_t i = 0; i < message_length; i++) + LOOP_L_N(i, message_length) encoded_message[i] = message[i] | 0x80; LCD_SERIAL.Print::write(encoded_message, message_length); } +// {E:} is for error states. +void set_lcd_error_P(PGM_P const error, PGM_P const component=nullptr) { + write_to_lcd_P(PSTR("{E:")); + write_to_lcd_P(error); + if (component) { + write_to_lcd_P(PSTR(" ")); + write_to_lcd_P(component); + } + write_to_lcd_P(PSTR("}")); +} + + /** * Process an LCD 'C' command. * These are currently all temperature commands @@ -194,18 +202,19 @@ void process_lcd_eb_command(const char* command) { * {J:E}{J:X+200}{J:E} * X, Y, Z, A (extruder) */ -void process_lcd_j_command(const char* command) { - auto move_axis = [command](const auto axis) { - const float dist = atof(command + 1) / 10.0; - ExtUI::setAxisPosition_mm(ExtUI::getAxisPosition_mm(axis) + dist, axis); - }; +template +void j_move_axis(const char* command, const T axis) { + const float dist = atof(command + 1) / 10.0; + ExtUI::setAxisPosition_mm(ExtUI::getAxisPosition_mm(axis) + dist, axis); +}; +void process_lcd_j_command(const char* command) { switch (command[0]) { case 'E': break; - case 'A': move_axis(ExtUI::extruder_t::E0); break; - case 'Y': move_axis(ExtUI::axis_t::Y); break; - case 'Z': move_axis(ExtUI::axis_t::Z); break; - case 'X': move_axis(ExtUI::axis_t::X); break; + case 'A': j_move_axis(command, ExtUI::extruder_t::E0); break; + case 'Y': j_move_axis(command, ExtUI::axis_t::Y); break; + case 'Z': j_move_axis(command, ExtUI::axis_t::Z); break; + case 'X': j_move_axis(command, ExtUI::axis_t::X); break; default: DEBUG_ECHOLNPAIR("UNKNOWN J COMMAND ", command); } } @@ -361,29 +370,38 @@ void process_lcd_command(const char* command) { DEBUG_ECHOLNPAIR("UNKNOWN COMMAND FORMAT ", command); } +// // Parse LCD commands mixed with G-Code -void parse_lcd_byte(byte b) { - static bool parsing_lcd_cmd = false; +// +void parse_lcd_byte(const byte b) { static char inbound_buffer[MAX_CURLY_COMMAND]; - if (!parsing_lcd_cmd) { - if (b == '{' || b == '\n' || b == '\r') { // A line-ending or opening brace - parsing_lcd_cmd = b == '{'; // Brace opens an LCD command - if (inbound_count) { // Looks like a G-code is in the buffer - inbound_buffer[inbound_count] = '\0'; // Reset before processing - inbound_count = 0; + static uint8_t parsing = 0; // Parsing state + static bool prevcr = false; // Was the last c a CR? + + const char c = b & 0x7F; + + if (parsing) { + const bool is_lcd = parsing == 1; // 1 for LCD + if ( ( is_lcd && c == '}') // Closing brace on LCD command + || (!is_lcd && c == '\n') // LF on a G-code command + ) { + inbound_buffer[inbound_count] = '\0'; // Reset before processing + inbound_count = 0; // Reset buffer index + if (parsing == 1) + process_lcd_command(inbound_buffer); // Handle the LCD command + else queue.enqueue_one_now(inbound_buffer); // Handle the G-code command - } + parsing = 0; // Unflag and... } + else if (inbound_count < MAX_CURLY_COMMAND - 2) + inbound_buffer[inbound_count++] = is_lcd ? c : b; // Buffer while space remains } - else if (b == '}') { // Closing brace on an LCD command - parsing_lcd_cmd = false; // Unflag and... - inbound_buffer[inbound_count] = '\0'; // reset before processing - inbound_count = 0; - process_lcd_command(inbound_buffer); // Handle the LCD command + else { + if (c == '{') parsing = 1; // Brace opens an LCD command + else if (prevcr && c == '\n') parsing = 2; // CRLF indicates G-code + prevcr = (c == '\r'); // Remember if it was a CR } - else if (inbound_count < MAX_CURLY_COMMAND - 2) - inbound_buffer[inbound_count++] = b; // Buffer only if space remains } /** @@ -410,7 +428,11 @@ namespace ExtUI { * it and translate into ExtUI operations where possible. */ inbound_count = 0; - LCD_SERIAL.begin(500000); + + #ifndef LCD_BAUDRATE + #define LCD_BAUDRATE 500000 + #endif + LCD_SERIAL.begin(LCD_BAUDRATE); // Signal init write_to_lcd_P(PSTR("{SYS:STARTED}\r\n")); @@ -433,9 +455,8 @@ namespace ExtUI { update_usb_status(false); // now drain commands... - while (LCD_SERIAL.available()) { - parse_lcd_byte((byte)LCD_SERIAL.read() & 0x7F); - } + while (LCD_SERIAL.available()) + parse_lcd_byte((byte)LCD_SERIAL.read()); #if ENABLED(SDSUPPORT) // The way last printing status works is simple: @@ -457,15 +478,33 @@ namespace ExtUI { #endif } - // {E:} is for error states. - void onPrinterKilled(PGM_P error, PGM_P component) { - write_to_lcd_P(PSTR("{E:")); - write_to_lcd_P(error); - write_to_lcd_P(PSTR(" ")); - write_to_lcd_P(component); - write_to_lcd_P("}"); + void onPrinterKilled(PGM_P const error, PGM_P const component) { + set_lcd_error_P(error, component); } + #if HAS_PID_HEATING + + void onPidTuning(const result_t rst) { + // Called for temperature PID tuning result + //SERIAL_ECHOLNPAIR("OnPidTuning:", rst); + switch (rst) { + case PID_BAD_EXTRUDER_NUM: + set_lcd_error_P(GET_TEXT(MSG_PID_BAD_EXTRUDER_NUM)); + break; + case PID_TEMP_TOO_HIGH: + set_lcd_error_P(GET_TEXT(MSG_PID_TEMP_TOO_HIGH)); + break; + case PID_TUNING_TIMEOUT: + set_lcd_error_P(GET_TEXT(MSG_PID_TIMEOUT)); + break; + case PID_DONE: + set_lcd_error_P(GET_TEXT(MSG_PID_AUTOTUNE_DONE)); + break; + } + } + + #endif + void onPrintTimerStarted() { write_to_lcd_P(PSTR("{SYS:BUILD}")); } void onPrintTimerPaused() {} void onPrintTimerStopped() { write_to_lcd_P(PSTR("{TQ:100}")); } @@ -483,6 +522,15 @@ namespace ExtUI { void onLoadSettings(const char*) {} void onConfigurationStoreWritten(bool) {} void onConfigurationStoreRead(bool) {} + + #if HAS_MESH + void onMeshUpdate(const int8_t xpos, const int8_t ypos, const float zval) {} + void onMeshUpdate(const int8_t xpos, const int8_t ypos, const ExtUI::probe_state_t state) {} + #endif + + #if ENABLED(POWER_LOSS_RECOVERY) + void onPowerLossResume() {} + #endif } #endif // MALYAN_LCD diff --git a/Marlin/src/lcd/extensible_ui/ui_api.cpp b/Marlin/src/lcd/extui/ui_api.cpp similarity index 76% rename from Marlin/src/lcd/extensible_ui/ui_api.cpp rename to Marlin/src/lcd/extui/ui_api.cpp index 7ef7614b8df8..30cf696f3ed7 100644 --- a/Marlin/src/lcd/extensible_ui/ui_api.cpp +++ b/Marlin/src/lcd/extui/ui_api.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -38,7 +38,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../../inc/MarlinConfigPre.h" @@ -54,28 +54,22 @@ #include "../../module/printcounter.h" #include "../../libs/duration_t.h" #include "../../HAL/shared/Delay.h" +#include "../../sd/cardreader.h" #if ENABLED(PRINTCOUNTER) #include "../../core/utility.h" #include "../../libs/numtostr.h" #endif -#if EXTRUDERS > 1 +#if HAS_MULTI_EXTRUDER #include "../../module/tool_change.h" #endif #if ENABLED(EMERGENCY_PARSER) - #include "../../feature/emergency_parser.h" + #include "../../feature/e_parser.h" #endif -#if ENABLED(SDSUPPORT) - #include "../../sd/cardreader.h" - #define IFSD(A,B) (A) -#else - #define IFSD(A,B) (B) -#endif - -#if HAS_TRINAMIC +#if HAS_TRINAMIC_CONFIG #include "../../feature/tmc_util.h" #include "../../module/stepper/indirection.h" #endif @@ -109,9 +103,8 @@ namespace ExtUI { static struct { uint8_t printer_killed : 1; - #if ENABLED(JOYSTICK) - uint8_t jogging : 1; - #endif + TERN_(JOYSTICK, uint8_t jogging : 1); + TERN_(SDSUPPORT, uint8_t was_sd_printing : 1); } flags; #ifdef __SAM3X8E__ @@ -165,12 +158,11 @@ namespace ExtUI { } void yield() { - if (!flags.printer_killed) - thermalManager.manage_heater(); + if (!flags.printer_killed) thermalManager.manage_heater(); } void enableHeater(const extruder_t extruder) { - #if HOTENDS && HEATER_IDLE_HANDLER + #if HAS_HOTEND && HEATER_IDLE_HANDLER thermalManager.reset_hotend_idle_timer(extruder - E0); #else UNUSED(extruder); @@ -181,17 +173,11 @@ namespace ExtUI { #if HEATER_IDLE_HANDLER switch (heater) { #if HAS_HEATED_BED - case BED: - thermalManager.reset_bed_idle_timer(); - return; - #endif - #if HAS_HEATED_CHAMBER - case CHAMBER: return; // Chamber has no idle timer + case BED: thermalManager.reset_bed_idle_timer(); return; #endif + TERN_(HAS_HEATED_CHAMBER, case CHAMBER: return); // Chamber has no idle timer default: - #if HOTENDS - thermalManager.reset_hotend_idle_timer(heater - H0); - #endif + TERN_(HAS_HOTEND, thermalManager.reset_hotend_idle_timer(heater - H0)); break; } #else @@ -236,30 +222,21 @@ namespace ExtUI { #endif bool isHeaterIdle(const extruder_t extruder) { - return false - #if HOTENDS && HEATER_IDLE_HANDLER - || thermalManager.hotend_idle[extruder - E0].timed_out - #else - ; UNUSED(extruder) - #endif - ; + #if HAS_HOTEND && HEATER_IDLE_HANDLER + return thermalManager.heater_idle[extruder - E0].timed_out; + #else + UNUSED(extruder); + return false; + #endif } bool isHeaterIdle(const heater_t heater) { #if HEATER_IDLE_HANDLER switch (heater) { - #if HAS_HEATED_BED - case BED: return thermalManager.bed_idle.timed_out; - #endif - #if HAS_HEATED_CHAMBER - case CHAMBER: return false; // Chamber has no idle timer - #endif + TERN_(HAS_HEATED_BED, case BED: return thermalManager.heater_idle[thermalManager.IDLE_INDEX_BED].timed_out); + TERN_(HAS_HEATED_CHAMBER, case CHAMBER: return false); // Chamber has no idle timer default: - #if HOTENDS - return thermalManager.hotend_idle[heater - H0].timed_out; - #else - return false; - #endif + return TERN0(HAS_HOTEND, thermalManager.heater_idle[heater - H0].timed_out); } #else UNUSED(heater); @@ -275,12 +252,8 @@ namespace ExtUI { float getActualTemp_celsius(const heater_t heater) { switch (heater) { - #if HAS_HEATED_BED - case BED: return GET_TEMP_ADJUSTMENT(thermalManager.degBed()); - #endif - #if HAS_HEATED_CHAMBER - case CHAMBER: return GET_TEMP_ADJUSTMENT(thermalManager.degChamber()); - #endif + TERN_(HAS_HEATED_BED, case BED: return GET_TEMP_ADJUSTMENT(thermalManager.degBed())); + TERN_(HAS_HEATED_CHAMBER, case CHAMBER: return GET_TEMP_ADJUSTMENT(thermalManager.degChamber())); default: return GET_TEMP_ADJUSTMENT(thermalManager.degHotend(heater - H0)); } } @@ -291,12 +264,8 @@ namespace ExtUI { float getTargetTemp_celsius(const heater_t heater) { switch (heater) { - #if HAS_HEATED_BED - case BED: return GET_TEMP_ADJUSTMENT(thermalManager.degTargetBed()); - #endif - #if HAS_HEATED_CHAMBER - case CHAMBER: return GET_TEMP_ADJUSTMENT(thermalManager.degTargetChamber()); - #endif + TERN_(HAS_HEATED_BED, case BED: return GET_TEMP_ADJUSTMENT(thermalManager.degTargetBed())); + TERN_(HAS_HEATED_CHAMBER, case CHAMBER: return GET_TEMP_ADJUSTMENT(thermalManager.degTargetChamber())); default: return GET_TEMP_ADJUSTMENT(thermalManager.degTargetHotend(heater - H0)); } } @@ -306,7 +275,7 @@ namespace ExtUI { } float getTargetFan_percent(const fan_t fan) { - #if FAN_COUNT > 0 + #if HAS_FAN return thermalManager.fanPercent(thermalManager.fan_speed[fan - FAN0]); #else UNUSED(fan); @@ -315,7 +284,7 @@ namespace ExtUI { } float getActualFan_percent(const fan_t fan) { - #if FAN_COUNT > 0 + #if HAS_FAN return thermalManager.fanPercent(thermalManager.scaledFanSpeed(fan - FAN0)); #else UNUSED(fan); @@ -324,83 +293,44 @@ namespace ExtUI { } float getAxisPosition_mm(const axis_t axis) { - return - #if ENABLED(JOYSTICK) - flags.jogging ? destination[axis] : - #endif - current_position[axis]; + return TERN_(JOYSTICK, flags.jogging ? destination[axis] :) current_position[axis]; } float getAxisPosition_mm(const extruder_t extruder) { const extruder_t old_tool = getActiveTool(); setActiveTool(extruder, true); - const float epos = ( - #if ENABLED(JOYSTICK) - flags.jogging ? destination.e : - #endif - current_position.e - ); + const float epos = TERN_(JOYSTICK, flags.jogging ? destination.e :) current_position.e; setActiveTool(old_tool, true); return epos; } - void setAxisPosition_mm(const float position, const axis_t axis) { - // Start with no limits to movement - float min = current_position[axis] - 1000, - max = current_position[axis] + 1000; - - // Limit to software endstops, if enabled - #if HAS_SOFTWARE_ENDSTOPS - if (soft_endstops_enabled) switch (axis) { - case X_AXIS: - #if ENABLED(MIN_SOFTWARE_ENDSTOP_X) - min = soft_endstop.min.x; - #endif - #if ENABLED(MAX_SOFTWARE_ENDSTOP_X) - max = soft_endstop.max.x; - #endif - break; - case Y_AXIS: - #if ENABLED(MIN_SOFTWARE_ENDSTOP_Y) - min = soft_endstop.min.y; - #endif - #if ENABLED(MAX_SOFTWARE_ENDSTOP_Y) - max = soft_endstop.max.y; - #endif - break; - case Z_AXIS: - #if ENABLED(MIN_SOFTWARE_ENDSTOP_Z) - min = soft_endstop.min.z; - #endif - #if ENABLED(MAX_SOFTWARE_ENDSTOP_Z) - max = soft_endstop.max.z; - #endif - default: break; - } - #endif // HAS_SOFTWARE_ENDSTOPS + void setAxisPosition_mm(const float position, const axis_t axis, const feedRate_t feedrate/*=0*/) { + // Get motion limit from software endstops, if any + float min, max; + soft_endstop.get_manual_axis_limits((AxisEnum)axis, min, max); // Delta limits XY based on the current offset from center // This assumes the center is 0,0 #if ENABLED(DELTA) - if (axis != Z_AXIS) { - max = SQRT(sq((float)(DELTA_PRINTABLE_RADIUS)) - sq(current_position[Y_AXIS - axis])); // (Y_AXIS - axis) == the other axis + if (axis != Z) { + max = SQRT(sq(float(DELTA_PRINTABLE_RADIUS)) - sq(current_position[Y - axis])); // (Y - axis) == the other axis min = -max; } #endif current_position[axis] = constrain(position, min, max); - line_to_current_position(manual_feedrate_mm_s[axis]); + line_to_current_position(feedrate ?: manual_feedrate_mm_s[axis]); } - void setAxisPosition_mm(const float position, const extruder_t extruder) { + void setAxisPosition_mm(const float position, const extruder_t extruder, const feedRate_t feedrate/*=0*/) { setActiveTool(extruder, true); current_position.e = position; - line_to_current_position(manual_feedrate_mm_s.e); + line_to_current_position(feedrate ?: manual_feedrate_mm_s.e); } void setActiveTool(const extruder_t extruder, bool no_move) { - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER const uint8_t e = extruder - E0; if (e != active_extruder) tool_change(e, no_move); active_extruder = e; @@ -441,22 +371,31 @@ namespace ExtUI { } #if HAS_SOFTWARE_ENDSTOPS - bool getSoftEndstopState() { return soft_endstops_enabled; } - void setSoftEndstopState(const bool value) { soft_endstops_enabled = value; } + bool getSoftEndstopState() { return soft_endstop._enabled; } + void setSoftEndstopState(const bool value) { soft_endstop._enabled = value; } #endif - #if HAS_TRINAMIC + #if HAS_TRINAMIC_CONFIG float getAxisCurrent_mA(const axis_t axis) { switch (axis) { #if AXIS_IS_TMC(X) case X: return stepperX.getMilliamps(); #endif + #if AXIS_IS_TMC(X2) + case X2: return stepperX2.getMilliamps(); + #endif #if AXIS_IS_TMC(Y) case Y: return stepperY.getMilliamps(); #endif + #if AXIS_IS_TMC(Y2) + case Y2: return stepperY2.getMilliamps(); + #endif #if AXIS_IS_TMC(Z) case Z: return stepperZ.getMilliamps(); #endif + #if AXIS_IS_TMC(Z2) + case Z2: return stepperZ2.getMilliamps(); + #endif default: return NAN; }; } @@ -494,13 +433,22 @@ namespace ExtUI { void setAxisCurrent_mA(const float mA, const axis_t axis) { switch (axis) { #if AXIS_IS_TMC(X) - case X: stepperX.rms_current(constrain(mA, 500, 1500)); break; + case X: stepperX.rms_current(constrain(mA, 400, 1500)); break; + #endif + #if AXIS_IS_TMC(X2) + case X2: stepperX2.rms_current(constrain(mA, 400, 1500)); break; #endif #if AXIS_IS_TMC(Y) - case Y: stepperY.rms_current(constrain(mA, 500, 1500)); break; + case Y: stepperY.rms_current(constrain(mA, 400, 1500)); break; + #endif + #if AXIS_IS_TMC(Y2) + case Y2: stepperY2.rms_current(constrain(mA, 400, 1500)); break; #endif #if AXIS_IS_TMC(Z) - case Z: stepperZ.rms_current(constrain(mA, 500, 1500)); break; + case Z: stepperZ.rms_current(constrain(mA, 400, 1500)); break; + #endif + #if AXIS_IS_TMC(Z2) + case Z2: stepperZ2.rms_current(constrain(mA, 400, 1500)); break; #endif default: break; }; @@ -509,28 +457,28 @@ namespace ExtUI { void setAxisCurrent_mA(const float mA, const extruder_t extruder) { switch (extruder) { #if AXIS_IS_TMC(E0) - case E0: stepperE0.rms_current(constrain(mA, 500, 1500)); break; + case E0: stepperE0.rms_current(constrain(mA, 400, 1500)); break; #endif #if AXIS_IS_TMC(E1) - case E1: stepperE1.rms_current(constrain(mA, 500, 1500)); break; + case E1: stepperE1.rms_current(constrain(mA, 400, 1500)); break; #endif #if AXIS_IS_TMC(E2) - case E2: stepperE2.rms_current(constrain(mA, 500, 1500)); break; + case E2: stepperE2.rms_current(constrain(mA, 400, 1500)); break; #endif #if AXIS_IS_TMC(E3) - case E3: stepperE3.rms_current(constrain(mA, 500, 1500)); break; + case E3: stepperE3.rms_current(constrain(mA, 400, 1500)); break; #endif #if AXIS_IS_TMC(E4) - case E4: stepperE4.rms_current(constrain(mA, 500, 1500)); break; + case E4: stepperE4.rms_current(constrain(mA, 400, 1500)); break; #endif #if AXIS_IS_TMC(E5) - case E5: stepperE5.rms_current(constrain(mA, 500, 1500)); break; + case E5: stepperE5.rms_current(constrain(mA, 400, 1500)); break; #endif #if AXIS_IS_TMC(E6) - case E6: stepperE6.rms_current(constrain(mA, 500, 1500)); break; + case E6: stepperE6.rms_current(constrain(mA, 400, 1500)); break; #endif #if AXIS_IS_TMC(E7) - case E7: stepperE7.rms_current(constrain(mA, 500, 1500)); break; + case E7: stepperE7.rms_current(constrain(mA, 400, 1500)); break; #endif default: break; }; @@ -538,15 +486,14 @@ namespace ExtUI { int getTMCBumpSensitivity(const axis_t axis) { switch (axis) { - #if X_SENSORLESS - case X: return stepperX.homing_threshold(); - #endif - #if Y_SENSORLESS - case Y: return stepperY.homing_threshold(); - #endif - #if Z_SENSORLESS - case Z: return stepperZ.homing_threshold(); - #endif + TERN_(X_SENSORLESS, case X: return stepperX.homing_threshold()); + TERN_(X2_SENSORLESS, case X2: return stepperX2.homing_threshold()); + TERN_(Y_SENSORLESS, case Y: return stepperY.homing_threshold()); + TERN_(Y2_SENSORLESS, case Y2: return stepperY2.homing_threshold()); + TERN_(Z_SENSORLESS, case Z: return stepperZ.homing_threshold()); + TERN_(Z2_SENSORLESS, case Z2: return stepperZ2.homing_threshold()); + TERN_(Z3_SENSORLESS, case Z3: return stepperZ3.homing_threshold()); + TERN_(Z4_SENSORLESS, case Z4: return stepperZ4.homing_threshold()); default: return 0; } } @@ -555,14 +502,29 @@ namespace ExtUI { switch (axis) { #if X_SENSORLESS || Y_SENSORLESS || Z_SENSORLESS #if X_SENSORLESS - case X: stepperX.homing_threshold(value); break; + case X: stepperX.homing_threshold(value); break; + #endif + #if X2_SENSORLESS + case X2: stepperX2.homing_threshold(value); break; #endif #if Y_SENSORLESS case Y: stepperY.homing_threshold(value); break; #endif + #if Y2_SENSORLESS + case Y2: stepperY2.homing_threshold(value); break; + #endif #if Z_SENSORLESS case Z: stepperZ.homing_threshold(value); break; #endif + #if Z2_SENSORLESS + case Z2: stepperZ2.homing_threshold(value); break; + #endif + #if Z3_SENSORLESS + case Z3: stepperZ3.homing_threshold(value); break; + #endif + #if Z4_SENSORLESS + case Z4: stepperZ4.homing_threshold(value); break; + #endif #else UNUSED(value); #endif @@ -582,11 +544,13 @@ namespace ExtUI { void setAxisSteps_per_mm(const float value, const axis_t axis) { planner.settings.axis_steps_per_mm[axis] = value; + planner.refresh_positioning(); } void setAxisSteps_per_mm(const float value, const extruder_t extruder) { UNUSED_E(extruder); - planner.settings.axis_steps_per_mm[E_AXIS_N(axis - E0)] = value; + planner.settings.axis_steps_per_mm[E_AXIS_N(extruder - E0)] = value; + planner.refresh_positioning(); } feedRate_t getAxisMaxFeedrate_mm_s(const axis_t axis) { @@ -595,7 +559,7 @@ namespace ExtUI { feedRate_t getAxisMaxFeedrate_mm_s(const extruder_t extruder) { UNUSED_E(extruder); - return planner.settings.max_feedrate_mm_s[E_AXIS_N(axis - E0)]; + return planner.settings.max_feedrate_mm_s[E_AXIS_N(extruder - E0)]; } void setAxisMaxFeedrate_mm_s(const feedRate_t value, const axis_t axis) { @@ -618,35 +582,39 @@ namespace ExtUI { void setAxisMaxAcceleration_mm_s2(const float value, const axis_t axis) { planner.set_max_acceleration(axis, value); + planner.reset_acceleration_rates(); } void setAxisMaxAcceleration_mm_s2(const float value, const extruder_t extruder) { UNUSED_E(extruder); planner.set_max_acceleration(E_AXIS_N(extruder - E0), value); + planner.reset_acceleration_rates(); } #if HAS_FILAMENT_SENSOR bool getFilamentRunoutEnabled() { return runout.enabled; } void setFilamentRunoutEnabled(const bool value) { runout.enabled = value; } + bool getFilamentRunoutState() { return runout.filament_ran_out; } + void setFilamentRunoutState(const bool value) { runout.filament_ran_out = value; } - #ifdef FILAMENT_RUNOUT_DISTANCE_MM + #if HAS_FILAMENT_RUNOUT_DISTANCE float getFilamentRunoutDistance_mm() { return runout.runout_distance(); } void setFilamentRunoutDistance_mm(const float value) { runout.set_runout_distance(constrain(value, 0, 999)); } #endif #endif - #if HAS_CASE_LIGHT - bool getCaseLightState() { return case_light_on; } + #if ENABLED(CASE_LIGHT_ENABLE) + bool getCaseLightState() { return caselight.on; } void setCaseLightState(const bool value) { - case_light_on = value; - update_case_light(); + caselight.on = value; + caselight.update_enabled(); } #if DISABLED(CASE_LIGHT_NO_BRIGHTNESS) - float getCaseLightBrightness_percent() { return ui8_to_percent(case_light_brightness); } + float getCaseLightBrightness_percent() { return ui8_to_percent(caselight.brightness); } void setCaseLightBrightness_percent(const float value) { - case_light_brightness = map(constrain(value, 0, 100), 0, 100, 0, 255); - update_case_light(); + caselight.brightness = map(constrain(value, 0, 100), 0, 100, 0, 255); + caselight.update_brightness(); } #endif #endif @@ -662,17 +630,15 @@ namespace ExtUI { } #endif - #if DISABLED(CLASSIC_JERK) + #if HAS_JUNCTION_DEVIATION float getJunctionDeviation_mm() { return planner.junction_deviation_mm; } void setJunctionDeviation_mm(const float value) { - planner.junction_deviation_mm = constrain(value, 0.01, 0.3); - #if ENABLED(LIN_ADVANCE) - planner.recalculate_max_e_jerk(); - #endif + planner.junction_deviation_mm = constrain(value, 0.001, 0.3); + TERN_(LIN_ADVANCE, planner.recalculate_max_e_jerk()); } #else @@ -702,10 +668,7 @@ namespace ExtUI { float getRetractAcceleration_mm_s2() { return planner.settings.retract_acceleration; } float getTravelAcceleration_mm_s2() { return planner.settings.travel_acceleration; } void setFeedrate_mm_s(const feedRate_t fr) { feedrate_mm_s = fr; } - void setFlow_percent(const int16_t flow, const extruder_t extr) { - planner.flow_percentage[extr] = flow; - planner.refresh_e_factor(extr); - } + void setFlow_percent(const int16_t flow, const extruder_t extr) { planner.set_flow(extr, flow); } void setMinFeedrate_mm_s(const feedRate_t fr) { planner.settings.min_feedrate_mm_s = fr; } void setMinTravelFeedrate_mm_s(const feedRate_t fr) { planner.settings.min_travel_feedrate_mm_s = fr; } void setPrintingAcceleration_mm_s2(const float acc) { planner.settings.acceleration = acc; } @@ -736,21 +699,17 @@ namespace ExtUI { */ void smartAdjustAxis_steps(const int16_t steps, const axis_t axis, bool linked_nozzles) { const float mm = steps * planner.steps_to_mm[axis]; + UNUSED(mm); if (!babystepAxis_steps(steps, axis)) return; #if ENABLED(BABYSTEP_ZPROBE_OFFSET) // Make it so babystepping in Z adjusts the Z probe offset. - if (axis == Z - #if EXTRUDERS > 1 - && (linked_nozzles || active_extruder == 0) - #endif - ) probe.offset.z += mm; - #else - UNUSED(mm); + if (axis == Z && TERN1(HAS_MULTI_EXTRUDER, (linked_nozzles || active_extruder == 0))) + probe.offset.z += mm; #endif - #if EXTRUDERS > 1 && HAS_HOTEND_OFFSET + #if HAS_MULTI_EXTRUDER && HAS_HOTEND_OFFSET /** * When linked_nozzles is false, as an axis is babystepped * adjust the hotend offsets so that the other nozzles are @@ -767,7 +726,6 @@ namespace ExtUI { } #else UNUSED(linked_nozzles); - UNUSED(mm); #endif } @@ -777,18 +735,18 @@ namespace ExtUI { */ int16_t mmToWholeSteps(const float mm, const axis_t axis) { const float steps = mm / planner.steps_to_mm[axis]; - return steps > 0 ? ceil(steps) : floor(steps); + return steps > 0 ? CEIL(steps) : FLOOR(steps); } #endif float getZOffset_mm() { - #if HAS_BED_PROBE - return probe.offset.z; - #elif ENABLED(BABYSTEP_DISPLAY_TOTAL) - return (planner.steps_to_mm[Z_AXIS] * babystep.axis_total[BS_AXIS_IND(Z_AXIS)]); - #else - return 0.0; - #endif + return (0.0f + #if HAS_BED_PROBE + + probe.offset.z + #elif ENABLED(BABYSTEP_DISPLAY_TOTAL) + + planner.steps_to_mm[Z_AXIS] * babystep.axis_total[BS_AXIS_IND(Z_AXIS)] + #endif + ); } void setZOffset_mm(const float value) { @@ -796,7 +754,7 @@ namespace ExtUI { if (WITHIN(value, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX)) probe.offset.z = value; #elif ENABLED(BABYSTEP_DISPLAY_TOTAL) - babystep.add_mm(Z_AXIS, (value - getZOffset_mm())); + babystep.add_mm(Z_AXIS, value - getZOffset_mm()); #else UNUSED(value); #endif @@ -868,9 +826,7 @@ namespace ExtUI { void setMeshPoint(const xy_uint8_t &pos, const float zoff) { if (WITHIN(pos.x, 0, GRID_MAX_POINTS_X) && WITHIN(pos.y, 0, GRID_MAX_POINTS_Y)) { Z_VALUES(pos.x, pos.y) = zoff; - #if ENABLED(ABL_BILINEAR_SUBDIVISION) - bed_level_virt_interpolate(); - #endif + TERN_(ABL_BILINEAR_SUBDIVISION, bed_level_virt_interpolate()); } } #endif @@ -895,17 +851,9 @@ namespace ExtUI { float getFeedrate_percent() { return feedrate_percentage; } #if ENABLED(PIDTEMP) - float getPIDValues_Kp(const extruder_t tool) { - return PID_PARAM(Kp, tool); - } - - float getPIDValues_Ki(const extruder_t tool) { - return unscalePID_i(PID_PARAM(Ki, tool)); - } - - float getPIDValues_Kd(const extruder_t tool) { - return unscalePID_d(PID_PARAM(Kd, tool)); - } + float getPIDValues_Kp(const extruder_t tool) { return PID_PARAM(Kp, tool); } + float getPIDValues_Ki(const extruder_t tool) { return unscalePID_i(PID_PARAM(Ki, tool)); } + float getPIDValues_Kd(const extruder_t tool) { return unscalePID_d(PID_PARAM(Kd, tool)); } void setPIDValues(const float p, const float i, const float d, extruder_t tool) { thermalManager.temp_hotend[tool].pid.Kp = p; @@ -914,23 +862,15 @@ namespace ExtUI { thermalManager.updatePID(); } - void startPIDTune(const float temp, extruder_t tool){ - thermalManager.PID_autotune(temp, (heater_ind_t)tool, 8, true); + void startPIDTune(const float temp, extruder_t tool) { + thermalManager.PID_autotune(temp, (heater_id_t)tool, 8, true); } #endif #if ENABLED(PIDTEMPBED) - float getBedPIDValues_Kp() { - return thermalManager.temp_bed.pid.Kp; - } - - float getBedPIDValues_Ki() { - return unscalePID_i(thermalManager.temp_bed.pid.Ki); - } - - float getBedPIDValues_Kd() { - return unscalePID_d(thermalManager.temp_bed.pid.Kd); - } + float getBedPIDValues_Kp() { return thermalManager.temp_bed.pid.Kp; } + float getBedPIDValues_Ki() { return unscalePID_i(thermalManager.temp_bed.pid.Ki); } + float getBedPIDValues_Kd() { return unscalePID_d(thermalManager.temp_bed.pid.Kd); } void setBedPIDValues(const float p, const float i, const float d) { thermalManager.temp_bed.pid.Kp = p; @@ -944,25 +884,18 @@ namespace ExtUI { } #endif - void injectCommands_P(PGM_P const gcode) { - queue.inject_P(gcode); - } + void injectCommands_P(PGM_P const gcode) { queue.inject_P(gcode); } + void injectCommands(char * const gcode) { queue.inject(gcode); } bool commandsInQueue() { return (planner.movesplanned() || queue.has_commands_queued()); } - bool isAxisPositionKnown(const axis_t axis) { - return TEST(axis_known_position, axis); - } - - bool isAxisPositionKnown(const extruder_t) { - return TEST(axis_known_position, E_AXIS); - } - + bool isAxisPositionKnown(const axis_t axis) { return TEST(axis_known_position, axis); } + bool isAxisPositionKnown(const extruder_t) { return TEST(axis_known_position, E_AXIS); } bool isPositionKnown() { return all_axes_known(); } bool isMachineHomed() { return all_axes_homed(); } PGM_P getFirmwareName_str() { - static const char firmware_name[] PROGMEM = "Marlin " SHORT_BUILD_VERSION; + static PGMSTR(firmware_name, "Marlin " SHORT_BUILD_VERSION); return firmware_name; } @@ -978,14 +911,13 @@ namespace ExtUI { #endif #if HAS_HEATED_BED if (heater == BED) - thermalManager.setTargetBed(LROUND(constrain(value, 0, BED_MAXTEMP - 10))); + thermalManager.setTargetBed(LROUND(constrain(value, 0, BED_MAX_TARGET))); else #endif { - #if HOTENDS - static constexpr int16_t heater_maxtemp[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP, HEATER_2_MAXTEMP, HEATER_3_MAXTEMP, HEATER_4_MAXTEMP, HEATER_5_MAXTEMP, HEATER_6_MAXTEMP, HEATER_7_MAXTEMP); + #if HAS_HOTEND const int16_t e = heater - H0; - thermalManager.setTargetHotend(LROUND(constrain(value, 0, heater_maxtemp[e] - 15)), e); + thermalManager.setTargetHotend(LROUND(constrain(value, 0, thermalManager.heater_maxtemp[e] - HOTEND_OVERSHOOT)), e); #endif } } @@ -994,16 +926,15 @@ namespace ExtUI { #ifdef TOUCH_UI_LCD_TEMP_SCALING value *= TOUCH_UI_LCD_TEMP_SCALING; #endif - #if HOTENDS - constexpr int16_t heater_maxtemp[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP, HEATER_2_MAXTEMP, HEATER_3_MAXTEMP, HEATER_4_MAXTEMP, HEATER_5_MAXTEMP, HEATER_6_MAXTEMP, HEATER_7_MAXTEMP); + #if HAS_HOTEND const int16_t e = extruder - E0; enableHeater(extruder); - thermalManager.setTargetHotend(LROUND(constrain(value, 0, heater_maxtemp[e] - 15)), e); + thermalManager.setTargetHotend(LROUND(constrain(value, 0, thermalManager.heater_maxtemp[e] - HOTEND_OVERSHOOT)), e); #endif } void setTargetFan_percent(const float value, const fan_t fan) { - #if FAN_COUNT > 0 + #if HAS_FAN if (fan < FAN_COUNT) thermalManager.set_fan_speed(fan - FAN0, map(constrain(value, 0, 100), 0, 100, 0, 255)); #else @@ -1017,9 +948,7 @@ namespace ExtUI { } void setUserConfirmed() { - #if HAS_RESUME_CONTINUE - wait_for_user = false; - #endif + TERN_(HAS_RESUME_CONTINUE, wait_for_user = false); } void printFile(const char *filename) { @@ -1032,28 +961,27 @@ namespace ExtUI { } bool isPrintingFromMedia() { - return IFSD(card.isFileOpen(), false); + #if ENABLED(SDSUPPORT) + // Account for when IS_SD_PRINTING() reports the end of the + // print when there is still SD card data in the planner. + flags.was_sd_printing = card.isFileOpen() || (flags.was_sd_printing && commandsInQueue()); + return flags.was_sd_printing; + #else + return false; + #endif } bool isPrinting() { - return (planner.movesplanned() || isPrintingFromMedia() || IFSD(IS_SD_PRINTING(), false)); + return (commandsInQueue() || isPrintingFromMedia() || IFSD(IS_SD_PRINTING(), false)); } bool isMediaInserted() { return IFSD(IS_SD_INSERTED() && card.isMounted(), false); } - void pausePrint() { - ui.pause_print(); - } - - void resumePrint() { - ui.resume_print(); - } - - void stopPrint() { - ui.abort_print(); - } + void pausePrint() { ui.pause_print(); } + void resumePrint() { ui.resume_print(); } + void stopPrint() { ui.abort_print(); } void onUserConfirmRequired_P(PGM_P const pstr) { char msg[strlen_P(pstr) + 1]; @@ -1061,6 +989,12 @@ namespace ExtUI { onUserConfirmRequired(msg); } + void onStatusChanged_P(PGM_P const pstr) { + char msg[strlen_P(pstr) + 1]; + strcpy_P(msg, pstr); + onStatusChanged(msg); + } + FileList::FileList() { refresh(); } void FileList::refresh() { num_files = 0xFFFF; } @@ -1068,13 +1002,7 @@ namespace ExtUI { bool FileList::seek(const uint16_t pos, const bool skip_range_check) { #if ENABLED(SDSUPPORT) if (!skip_range_check && (pos + 1) > count()) return false; - const uint16_t nr = - #if ENABLED(SDCARD_RATHERRECENTFIRST) && DISABLED(SDCARD_SORT_ALPHA) - count() - 1 - - #endif - pos; - - card.getfilename_sorted(nr); + card.getfilename_sorted(SD_ORDER(pos, count())); return card.filename[0] != '\0'; #else UNUSED(pos); @@ -1104,11 +1032,7 @@ namespace ExtUI { } bool FileList::isAtRootDir() { - return (true - #if ENABLED(SDSUPPORT) - && card.flag.workDirIsRoot - #endif - ); + return IFSD(card.flag.workDirIsRoot, true); } void FileList::upDir() { @@ -1132,35 +1056,10 @@ namespace ExtUI { // At the moment, we piggy-back off the ultralcd calls, but this could be cleaned up in the future void MarlinUI::init() { - #if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_DETECT) - SET_INPUT_PULLUP(SD_DETECT_PIN); - #endif - ExtUI::onStartup(); } -void MarlinUI::update() { - #if ENABLED(SDSUPPORT) - static bool last_sd_status; - const bool sd_status = IS_SD_INSERTED(); - if (sd_status != last_sd_status) { - last_sd_status = sd_status; - if (sd_status) { - card.mount(); - if (card.isMounted()) - ExtUI::onMediaInserted(); - else - ExtUI::onMediaError(); - } - else { - const bool ok = card.isMounted(); - card.release(); - if (ok) ExtUI::onMediaRemoved(); - } - } - #endif // SDSUPPORT - ExtUI::onIdle(); -} +void MarlinUI::update() { ExtUI::onIdle(); } void MarlinUI::kill_screen(PGM_P const error, PGM_P const component) { using namespace ExtUI; diff --git a/Marlin/src/lcd/extensible_ui/ui_api.h b/Marlin/src/lcd/extui/ui_api.h similarity index 91% rename from Marlin/src/lcd/extensible_ui/ui_api.h rename to Marlin/src/lcd/extui/ui_api.h index 10df2bc72d99..15122ec69e15 100644 --- a/Marlin/src/lcd/extensible_ui/ui_api.h +++ b/Marlin/src/lcd/extui/ui_api.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -39,7 +39,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #include "../../inc/MarlinConfig.h" @@ -52,7 +52,7 @@ namespace ExtUI { static constexpr size_t eeprom_data_size = 48; - enum axis_t : uint8_t { X, Y, Z }; + enum axis_t : uint8_t { X, Y, Z, X2, Y2, Z2, Z3, Z4 }; enum extruder_t : uint8_t { E0, E1, E2, E3, E4, E5, E6, E7 }; enum heater_t : uint8_t { H0, H1, H2, H3, H4, H5, BED, CHAMBER }; enum fan_t : uint8_t { FAN0, FAN1, FAN2, FAN3, FAN4, FAN5, FAN6, FAN7 }; @@ -74,6 +74,7 @@ namespace ExtUI { bool canMove(const axis_t); bool canMove(const extruder_t); void injectCommands_P(PGM_P const); + void injectCommands(char * const); bool commandsInQueue(); bool isHeaterIdle(const heater_t); @@ -97,7 +98,7 @@ namespace ExtUI { void setSoftEndstopState(const bool); #endif - #if HAS_TRINAMIC + #if HAS_TRINAMIC_CONFIG float getAxisCurrent_mA(const axis_t); float getAxisCurrent_mA(const extruder_t); void setAxisCurrent_mA(const float, const axis_t); @@ -141,6 +142,15 @@ namespace ExtUI { void setMeshPoint(const xy_uint8_t &pos, const float zval); void onMeshUpdate(const int8_t xpos, const int8_t ypos, const float zval); inline void onMeshUpdate(const xy_int8_t &pos, const float zval) { onMeshUpdate(pos.x, pos.y, zval); } + + typedef enum : unsigned char { + MESH_START, // Prior to start of probe + MESH_FINISH, // Following probe of all points + PROBE_START, // Beginning probe of grid location + PROBE_FINISH // Finished probe of grid location + } probe_state_t; + void onMeshUpdate(const int8_t xpos, const int8_t ypos, probe_state_t state); + inline void onMeshUpdate(const xy_int8_t &pos, probe_state_t state) { onMeshUpdate(pos.x, pos.y, state); } #endif #endif @@ -159,8 +169,8 @@ namespace ExtUI { void setTargetTemp_celsius(const float, const heater_t); void setTargetTemp_celsius(const float, const extruder_t); void setTargetFan_percent(const float, const fan_t); - void setAxisPosition_mm(const float, const axis_t); - void setAxisPosition_mm(const float, const extruder_t); + void setAxisPosition_mm(const float, const axis_t, const feedRate_t=0); + void setAxisPosition_mm(const float, const extruder_t, const feedRate_t=0); void setAxisSteps_per_mm(const float, const axis_t); void setAxisSteps_per_mm(const float, const extruder_t); void setAxisMaxFeedrate_mm_s(const feedRate_t, const axis_t); @@ -182,7 +192,7 @@ namespace ExtUI { void setLinearAdvance_mm_mm_s(const float, const extruder_t); #endif - #if DISABLED(CLASSIC_JERK) + #if HAS_JUNCTION_DEVIATION float getJunctionDeviation_mm(); void setJunctionDeviation_mm(const float); #else @@ -232,8 +242,10 @@ namespace ExtUI { #if HAS_FILAMENT_SENSOR bool getFilamentRunoutEnabled(); void setFilamentRunoutEnabled(const bool); + bool getFilamentRunoutState(); + void setFilamentRunoutState(const bool); - #ifdef FILAMENT_RUNOUT_DISTANCE_MM + #if HAS_FILAMENT_RUNOUT_DISTANCE float getFilamentRunoutDistance_mm(); void setFilamentRunoutDistance_mm(const float); #endif @@ -335,16 +347,17 @@ namespace ExtUI { void onUserConfirmRequired(const char * const msg); void onUserConfirmRequired_P(PGM_P const pstr); void onStatusChanged(const char * const msg); + void onStatusChanged_P(PGM_P const pstr); void onFactoryReset(); void onStoreSettings(char *); void onLoadSettings(const char *); void onConfigurationStoreWritten(bool success); void onConfigurationStoreRead(bool success); #if ENABLED(POWER_LOSS_RECOVERY) - void OnPowerLossResume(); + void onPowerLossResume(); #endif #if HAS_PID_HEATING - void OnPidTuning(const result_t rst); + void onPidTuning(const result_t rst); #endif }; @@ -362,7 +375,6 @@ namespace ExtUI { * constexpr float increment = 10; * * UI_INCREMENT(TargetTemp_celsius, E0) - * */ #define UI_INCREMENT_BY(method, inc, ...) ExtUI::set ## method(ExtUI::get ## method (__VA_ARGS__) + inc, ##__VA_ARGS__) #define UI_DECREMENT_BY(method, inc, ...) ExtUI::set ## method(ExtUI::get ## method (__VA_ARGS__) - inc, ##__VA_ARGS__) diff --git a/Marlin/src/lcd/fontutils.cpp b/Marlin/src/lcd/fontutils.cpp index ffa6d0df70b8..5bf07e1bd458 100644 --- a/Marlin/src/lcd/fontutils.cpp +++ b/Marlin/src/lcd/fontutils.cpp @@ -9,7 +9,7 @@ #include "../inc/MarlinConfig.h" -#if HAS_SPI_LCD +#if HAS_WIRED_LCD #include "ultralcd.h" #include "../MarlinCore.h" #endif @@ -73,7 +73,7 @@ int pf_bsearch_r(void *userdata, size_t num_data, pf_bsearch_cb_comp_t cb_comp, return -1; } -/* This function gets the character at the pstart position, interpreting UTF8 multybyte sequences +/* This function gets the character at the pstart position, interpreting UTF8 multibyte sequences and returns the pointer to the next character */ uint8_t* get_utf8_value_cb(uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t *pval) { uint32_t val = 0; @@ -161,7 +161,6 @@ uint8_t* get_utf8_value_cb(uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t } static inline uint8_t utf8_strlen_cb(const char *pstart, read_byte_cb_t cb_read_byte) { - uint8_t cnt = 0; uint8_t *pnext = (uint8_t *)pstart; for (;;) { diff --git a/Marlin/src/lcd/fontutils.h b/Marlin/src/lcd/fontutils.h index 8839e36a2bd1..74c4a87fb9d3 100644 --- a/Marlin/src/lcd/fontutils.h +++ b/Marlin/src/lcd/fontutils.h @@ -38,6 +38,6 @@ int pf_bsearch_r(void *userdata, size_t num_data, pf_bsearch_cb_comp_t cb_comp, /* Get the character, decoding multibyte UTF8 characters and returning a pointer to the start of the next UTF8 character */ uint8_t* get_utf8_value_cb(uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t *pval); -/* Returns lenght of string in CHARACTERS, NOT BYTES */ +/* Returns length of string in CHARACTERS, NOT BYTES */ uint8_t utf8_strlen(const char *pstart); uint8_t utf8_strlen_P(PGM_P pstart); diff --git a/Marlin/src/lcd/language/language_an.h b/Marlin/src/lcd/language/language_an.h index 8e7798d72ddb..a5030fcd5636 100644 --- a/Marlin/src/lcd/language/language_an.h +++ b/Marlin/src/lcd/language/language_an.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,8 +25,7 @@ * Aragonese * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ #define DISPLAY_CHARSET_ISO10646_1 @@ -56,20 +55,23 @@ namespace Language_an { PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Achustar desfases"); PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Desfase aplicau"); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Establir orichen"); - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Precalentar ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Precalentar ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Precal. ") PREHEAT_1_LABEL _UxGT(" Boquilla"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Precal. ") PREHEAT_1_LABEL _UxGT(" Boquilla ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Precalentar ") PREHEAT_1_LABEL _UxGT(" Tot"); - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Precalentar ") PREHEAT_1_LABEL _UxGT(" Base"); - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Precalentar ") PREHEAT_1_LABEL _UxGT(" Conf"); - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("Precalentar ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("Precalentar ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("Precal. ") PREHEAT_2_LABEL _UxGT(" Boquilla"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("Precal. ") PREHEAT_2_LABEL _UxGT(" Boquilla ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("Precalentar ") PREHEAT_2_LABEL _UxGT(" Tot"); - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("Precalentar ") PREHEAT_2_LABEL _UxGT(" Base"); - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("Precalentar ") PREHEAT_2_LABEL _UxGT(" Conf"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Precalentar ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Precalentar ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Precal. ") PREHEAT_1_LABEL _UxGT(" Boquilla"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Precal. ") PREHEAT_1_LABEL _UxGT(" Boquilla ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Precalentar ") PREHEAT_1_LABEL _UxGT(" Tot"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Precalentar ") PREHEAT_1_LABEL _UxGT(" Base"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Precalentar ") PREHEAT_1_LABEL _UxGT(" Conf"); + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Precalentar $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Precalentar $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Precal. $ Boquilla"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Precal. $ Boquilla ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Precalentar $ Tot"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Precalentar $ Base"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Precalentar $ Conf"); + #endif PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Enfriar"); PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Enchegar Fuent"); PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("Amortar Fuent"); @@ -165,7 +167,6 @@ namespace Language_an { PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("Error de temperatura"); PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("Error: Temp Max"); PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("Error: Temp Min"); - PROGMEM Language_Str MSG_ERR_Z_HOMING = _UxGT("Home XY first"); PROGMEM Language_Str MSG_HALTED = _UxGT("IMPRESORA ATURADA"); PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("Per favor reinic."); PROGMEM Language_Str MSG_SHORT_DAY = _UxGT("d"); diff --git a/Marlin/src/lcd/language/language_bg.h b/Marlin/src/lcd/language/language_bg.h index 1987c207660d..dcb06e31e703 100644 --- a/Marlin/src/lcd/language/language_bg.h +++ b/Marlin/src/lcd/language/language_bg.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,8 +25,7 @@ * Bulgarian * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ #define DISPLAY_CHARSET_ISO10646_5 @@ -46,20 +45,23 @@ namespace Language_bg { PROGMEM Language_Str MSG_AUTO_HOME = _UxGT("Паркиране"); PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Задай Начало"); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Изходна точка"); - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Подгряване ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Подгряване ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Подгряване ") PREHEAT_1_LABEL _UxGT(" Дюза"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Подгряване ") PREHEAT_1_LABEL _UxGT(" Дюза ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Подгр. ") PREHEAT_1_LABEL _UxGT(" Всички"); - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Подгр. ") PREHEAT_1_LABEL _UxGT(" Легло"); - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Настройки ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("Подгряване ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("Подгряване ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("Подгряване ") PREHEAT_2_LABEL _UxGT(" Дюза"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("Подгряване ") PREHEAT_2_LABEL _UxGT(" Дюза ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("Подгр. ") PREHEAT_2_LABEL _UxGT(" Всички"); - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("Подгр. ") PREHEAT_2_LABEL _UxGT(" Легло"); - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("Настройки ") PREHEAT_2_LABEL; + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Подгряване ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Подгряване ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Подгряване ") PREHEAT_1_LABEL _UxGT(" Дюза"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Подгряване ") PREHEAT_1_LABEL _UxGT(" Дюза ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Подгр. ") PREHEAT_1_LABEL _UxGT(" Всички"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Подгр. ") PREHEAT_1_LABEL _UxGT(" Легло"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Настройки ") PREHEAT_1_LABEL; + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Подгряване $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Подгряване $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Подгряване $ Дюза"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Подгряване $ Дюза ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Подгр. $ Всички"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Подгр. $ Легло"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Настройки $"); + #endif PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Охлаждане"); PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Вкл. захранване"); PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("Изкл. захранване"); @@ -149,5 +151,5 @@ namespace Language_bg { PROGMEM Language_Str MSG_DELTA_CALIBRATE_Y = _UxGT("Калибровка Y"); PROGMEM Language_Str MSG_DELTA_CALIBRATE_Z = _UxGT("Калибровка Z"); PROGMEM Language_Str MSG_DELTA_CALIBRATE_CENTER = _UxGT("Калибровка Център"); - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("Неправилен принтер"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("Неправилен принтер"); } diff --git a/Marlin/src/lcd/language/language_ca.h b/Marlin/src/lcd/language/language_ca.h index ef5334f878e2..0657c4a75959 100644 --- a/Marlin/src/lcd/language/language_ca.h +++ b/Marlin/src/lcd/language/language_ca.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,8 +25,7 @@ * Catalan * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ namespace Language_ca { using namespace Language_en; // Inherit undefined strings from English @@ -54,23 +53,25 @@ namespace Language_ca { PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Ajusta decalatge"); PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Decalatge aplicat"); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Estableix origen"); - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Preescalfa ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Preescalfa ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Preheat ") PREHEAT_1_LABEL _UxGT(" End"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Preheat ") PREHEAT_1_LABEL _UxGT(" End ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Preheat ") PREHEAT_1_LABEL _UxGT(" Tot"); - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Preheat ") PREHEAT_1_LABEL _UxGT(" Llit"); - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Preheat ") PREHEAT_1_LABEL _UxGT(" Conf."); - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("Preescalfa ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("Preescalfa ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("Preheat ") PREHEAT_2_LABEL _UxGT(" End"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("Preheat ") PREHEAT_2_LABEL _UxGT(" End ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("Preheat ") PREHEAT_2_LABEL _UxGT(" Tot"); - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("Preheat ") PREHEAT_2_LABEL _UxGT(" Llit"); - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("Preheat ") PREHEAT_2_LABEL _UxGT(" Conf."); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Preescalfa ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Preescalfa ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Preescalfa ") PREHEAT_1_LABEL _UxGT(" End"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Preescalfa ") PREHEAT_1_LABEL _UxGT(" End ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Preescalfa ") PREHEAT_1_LABEL _UxGT(" Tot"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Preescalfa ") PREHEAT_1_LABEL _UxGT(" Llit"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Preescalfa ") PREHEAT_1_LABEL _UxGT(" Conf."); + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Preescalfa $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Preescalfa $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Preescalfa $ End"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Preescalfa $ End ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Preescalfa $ Tot"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Preescalfa $ Llit"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Preescalfa $ Conf."); + #endif PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Refreda"); - PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Switch power on"); - PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("Switch power off"); + PROGMEM Language_Str MSG_EXTRUDE = _UxGT("Extrudeix"); PROGMEM Language_Str MSG_RETRACT = _UxGT("Retreu"); PROGMEM Language_Str MSG_MOVE_AXIS = _UxGT("Mou eixos"); @@ -98,11 +99,7 @@ namespace Language_ca { PROGMEM Language_Str MSG_FLOW = _UxGT("Flux"); PROGMEM Language_Str MSG_FLOW_N = _UxGT("Flux ~"); PROGMEM Language_Str MSG_VTRAV_MIN = _UxGT("VViatge min"); - PROGMEM Language_Str MSG_AMAX_A = _UxGT("Accel. max ") LCD_STR_A; - PROGMEM Language_Str MSG_AMAX_B = _UxGT("Accel. max ") LCD_STR_B; - PROGMEM Language_Str MSG_AMAX_C = _UxGT("Accel. max ") LCD_STR_C; - PROGMEM Language_Str MSG_AMAX_E = _UxGT("Accel. max ") LCD_STR_E; - PROGMEM Language_Str MSG_AMAX_EN = _UxGT("Accel. max *"); + PROGMEM Language_Str MSG_A_RETRACT = _UxGT("Accel. retracc"); PROGMEM Language_Str MSG_A_TRAVEL = _UxGT("Accel. Viatge"); PROGMEM Language_Str MSG_STEPS_PER_MM = _UxGT("Passos/mm"); @@ -161,7 +158,6 @@ namespace Language_ca { PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("THERMAL RUNAWAY"); PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("Err: TEMP MAXIMA"); PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("Err: TEMP MINIMA"); - PROGMEM Language_Str MSG_ERR_Z_HOMING = _UxGT("Home XY primer"); PROGMEM Language_Str MSG_HALTED = _UxGT("IMPRESSORA PARADA"); PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("Reinicieu"); PROGMEM Language_Str MSG_SHORT_DAY = _UxGT("d"); // One character only @@ -204,14 +200,10 @@ namespace Language_ca { PROGMEM Language_Str MSG_INFO_PSU = _UxGT("Font alimentacio"); PROGMEM Language_Str MSG_DRIVE_STRENGTH = _UxGT("Força motor"); - PROGMEM Language_Str MSG_DAC_PERCENT_X = _UxGT("X Driver %"); - PROGMEM Language_Str MSG_DAC_PERCENT_Y = _UxGT("Y Driver %"); - PROGMEM Language_Str MSG_DAC_PERCENT_Z = _UxGT("Z Driver %"); - PROGMEM Language_Str MSG_DAC_PERCENT_E = _UxGT("E Driver %"); - PROGMEM Language_Str MSG_DAC_EEPROM_WRITE = _UxGT("DAC EEPROM Write"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_RESUME = _UxGT("Repren impressió"); - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("Impressora incorrecta"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("Impressora incorrecta"); // // Filament Change screens show up to 3 lines on a 4-line display diff --git a/Marlin/src/lcd/language/language_cz.h b/Marlin/src/lcd/language/language_cz.h index 77e25b73329b..9cbd7042d613 100644 --- a/Marlin/src/lcd/language/language_cz.h +++ b/Marlin/src/lcd/language/language_cz.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -26,12 +26,11 @@ * UTF-8 for Graphical Display * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html + * See also https://marlinfw.org/docs/development/lcd_language.html * * Translated by Petr Zahradnik, Computer Laboratory * Blog and video blog Zahradnik se bavi - * http://www.zahradniksebavi.cz - * + * https://www.zahradniksebavi.cz */ #define DISPLAY_CHARSET_ISO10646_CZ @@ -49,7 +48,6 @@ namespace Language_cz { PROGMEM Language_Str MSG_MEDIA_ABORTING = _UxGT("Rušení..."); PROGMEM Language_Str MSG_MEDIA_INSERTED = _UxGT("Médium vloženo"); PROGMEM Language_Str MSG_MEDIA_REMOVED = _UxGT("Médium vyjmuto"); - PROGMEM Language_Str MSG_MEDIA_RELEASED = _UxGT("Médium uvolněno"); PROGMEM Language_Str MSG_MEDIA_WAITING = _UxGT("Čekání na médium"); PROGMEM Language_Str MSG_MEDIA_READ_ERROR = _UxGT("Chyba čtení média"); PROGMEM Language_Str MSG_MEDIA_USB_REMOVED = _UxGT("USB odstraněno"); @@ -80,20 +78,23 @@ namespace Language_cz { PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Nastavit ofsety"); PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Ofsety nastaveny"); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Nastavit počátek"); - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Zahřát ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Zahřát ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Zahřát ") PREHEAT_1_LABEL _UxGT(" end"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Zahřát ") PREHEAT_1_LABEL _UxGT(" end ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Zahřát ") PREHEAT_1_LABEL _UxGT(" vše"); - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Zahřát ") PREHEAT_1_LABEL _UxGT(" podlož"); - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Zahřát ") PREHEAT_1_LABEL _UxGT(" nast"); - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("Zahřát ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("Zahřát ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("Zahřát ") PREHEAT_2_LABEL _UxGT(" end"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("Zahřát ") PREHEAT_2_LABEL _UxGT(" end ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("Zahřát ") PREHEAT_2_LABEL _UxGT(" vše"); - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("Zahřát ") PREHEAT_2_LABEL _UxGT(" podlož"); - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("Zahřát ") PREHEAT_2_LABEL _UxGT(" nast"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Zahřát ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Zahřát ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Zahřát ") PREHEAT_1_LABEL _UxGT(" end"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Zahřát ") PREHEAT_1_LABEL _UxGT(" end ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Zahřát ") PREHEAT_1_LABEL _UxGT(" vše"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Zahřát ") PREHEAT_1_LABEL _UxGT(" podlož"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Zahřát ") PREHEAT_1_LABEL _UxGT(" nast"); + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Zahřát $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Zahřát $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Zahřát $ end"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Zahřát $ end ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Zahřát $ vše"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Zahřát $ podlož"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Zahřát $ nast"); + #endif PROGMEM Language_Str MSG_PREHEAT_CUSTOM = _UxGT("Zahřát vlastní"); PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Zchladit"); PROGMEM Language_Str MSG_LASER_MENU = _UxGT("Ovládání laseru"); @@ -157,14 +158,14 @@ namespace Language_cz { PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("Konec úprav sítě"); PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("Vlastní síť"); PROGMEM Language_Str MSG_UBL_BUILD_MESH_MENU = _UxGT("Vytvořit síť"); - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M1 = _UxGT("Síť bodů ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M2 = _UxGT("Síť bodů ") PREHEAT_2_LABEL; + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_UBL_BUILD_MESH_M = _UxGT("Síť bodů $"); + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("Kontrola sítě $"); + #endif PROGMEM Language_Str MSG_UBL_BUILD_COLD_MESH = _UxGT("Studená síť bodů"); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_ADJUST = _UxGT("Upravit výšku sítě"); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_AMOUNT = _UxGT("Výška"); PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_MENU = _UxGT("Zkontrolovat síť"); - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M1 = _UxGT("Kontrola sítě ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M2 = _UxGT("Kontrola sítě ") PREHEAT_2_LABEL; PROGMEM Language_Str MSG_UBL_VALIDATE_CUSTOM_MESH = _UxGT("Kontrola vlast. sítě"); PROGMEM Language_Str MSG_G26_HEATING_BED = _UxGT("G26 zahřívání podl."); PROGMEM Language_Str MSG_G26_HEATING_NOZZLE = _UxGT("G26 zařívání trysky"); @@ -197,8 +198,8 @@ namespace Language_cz { PROGMEM Language_Str MSG_UBL_STORAGE_SLOT = _UxGT("Paměťový slot"); PROGMEM Language_Str MSG_UBL_LOAD_MESH = _UxGT("Načíst síť bodů"); PROGMEM Language_Str MSG_UBL_SAVE_MESH = _UxGT("Uložit síť bodů"); - PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("M117 Síť %i načtena"); - PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("M117 Síť %i uložena"); + PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("Síť %i načtena"); + PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("Síť %i uložena"); PROGMEM Language_Str MSG_UBL_NO_STORAGE = _UxGT("Nedostatek místa"); PROGMEM Language_Str MSG_UBL_SAVE_ERROR = _UxGT("Ch.: Uložit UBL"); PROGMEM Language_Str MSG_UBL_RESTORE_ERROR = _UxGT("Ch.: Obnovit UBL"); @@ -349,17 +350,17 @@ namespace Language_cz { PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("Výměna Re.mm"); PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("Retraktovat V"); PROGMEM Language_Str MSG_CONTROL_RETRACT_ZHOP = _UxGT("Zvednuti Z mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("UnRet mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("S UnRet mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("UnRet V"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("Unretr. mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("S Unretr. mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("Unretract V"); PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAPF = _UxGT("S UnRet V"); - PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("AutoRetr."); + PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("Auto-Retract"); PROGMEM Language_Str MSG_FILAMENT_SWAP_LENGTH = _UxGT("Délka retrakce"); PROGMEM Language_Str MSG_FILAMENT_PURGE_LENGTH = _UxGT("Délka zavedení"); PROGMEM Language_Str MSG_TOOL_CHANGE = _UxGT("Výměna nástroje"); PROGMEM Language_Str MSG_TOOL_CHANGE_ZLIFT = _UxGT("Zdvih Z"); - PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPD = _UxGT("Rychlost primár."); - PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPD = _UxGT("Rychlost retrak."); + PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPEED = _UxGT("Rychlost primár."); + PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPEED = _UxGT("Rychlost retrak."); PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("Tryska standby"); PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("Vyměnit filament"); PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Vyměnit filament *"); @@ -402,19 +403,12 @@ namespace Language_cz { PROGMEM Language_Str MSG_BABYSTEP_TOTAL = _UxGT("Celkem"); PROGMEM Language_Str MSG_ENDSTOP_ABORT = _UxGT("Endstop abort"); PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("Chyba zahřívání"); - PROGMEM Language_Str MSG_HEATING_FAILED_LCD_BED = _UxGT("Chyba zahř.podl."); - PROGMEM Language_Str MSG_HEATING_FAILED_LCD_CHAMBER = _UxGT("Chyba zahř.komory"); PROGMEM Language_Str MSG_ERR_REDUNDANT_TEMP = _UxGT("REDUND. TEPLOTA"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("TEPLOTNÍ ÚNIK"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY_BED = _UxGT("TEPL. ÚNIK PODL."); PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER = _UxGT("TEPL. ÚNIK KOMORA"); PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("VYSOKÁ TEPLOTA"); PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("NÍZKA TEPLOTA"); - PROGMEM Language_Str MSG_ERR_MAXTEMP_BED = _UxGT("VYS. TEPL. PODL."); - PROGMEM Language_Str MSG_ERR_MINTEMP_BED = _UxGT("NÍZ. TEPL. PODL."); - PROGMEM Language_Str MSG_ERR_MAXTEMP_CHAMBER = _UxGT("Err: MAXTEMP KOMORA"); - PROGMEM Language_Str MSG_ERR_MINTEMP_CHAMBER = _UxGT("Err: MINTEMP KOMORA"); - PROGMEM Language_Str MSG_ERR_Z_HOMING = _UxGT("Domů XY první"); PROGMEM Language_Str MSG_HALTED = _UxGT("TISK. ZASTAVENA"); PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("Proveďte reset"); PROGMEM Language_Str MSG_SHORT_DAY = _UxGT("d"); @@ -464,7 +458,7 @@ namespace Language_cz { PROGMEM Language_Str MSG_CASE_LIGHT = _UxGT("Osvětlení"); PROGMEM Language_Str MSG_CASE_LIGHT_BRIGHTNESS = _UxGT("Jas světla"); - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("NESPRÁVNÁ TISKÁRNA"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("NESPRÁVNÁ TISKÁRNA"); #if LCD_WIDTH >= 20 PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Počet tisků"); @@ -500,13 +494,12 @@ namespace Language_cz { PROGMEM Language_Str MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" Tryska: "); PROGMEM Language_Str MSG_RUNOUT_SENSOR = _UxGT("Senzor filamentu"); PROGMEM Language_Str MSG_RUNOUT_DISTANCE_MM = _UxGT("Délka mm senz.fil."); - PROGMEM Language_Str MSG_LCD_HOMING_FAILED = _UxGT("Parkování selhalo"); + PROGMEM Language_Str MSG_KILL_HOMING_FAILED = _UxGT("Parkování selhalo"); PROGMEM Language_Str MSG_LCD_PROBING_FAILED = _UxGT("Kalibrace selhala"); - PROGMEM Language_Str MSG_M600_TOO_COLD = _UxGT("M600: Moc studený"); PROGMEM Language_Str MSG_MMU2_CHOOSE_FILAMENT_HEADER = _UxGT("VYBERTE FILAMENT"); PROGMEM Language_Str MSG_MMU2_MENU = _UxGT("MMU"); - PROGMEM Language_Str MSG_MMU2_WRONG_FIRMWARE = _UxGT("Aktual. MMU firmware!"); + PROGMEM Language_Str MSG_KILL_MMU2_FIRMWARE = _UxGT("Aktual. MMU firmware!"); PROGMEM Language_Str MSG_MMU2_NOT_RESPONDING = _UxGT("MMU potř. pozornost."); PROGMEM Language_Str MSG_MMU2_RESUME = _UxGT("Obnovit tisk"); PROGMEM Language_Str MSG_MMU2_RESUMING = _UxGT("Obnovování..."); @@ -526,7 +519,7 @@ namespace Language_cz { PROGMEM Language_Str MSG_MMU2_EJECT_RECOVER = _UxGT("Vytáhněte, klikněte"); PROGMEM Language_Str MSG_MIX = _UxGT("Mix"); - PROGMEM Language_Str MSG_MIX_COMPONENT_N = _UxGT("Komponenta ~"); + PROGMEM Language_Str MSG_MIX_COMPONENT_N = _UxGT("Komponenta ="); PROGMEM Language_Str MSG_MIXER = _UxGT("Mixér"); PROGMEM Language_Str MSG_GRADIENT = _UxGT("Přechod"); PROGMEM Language_Str MSG_FULL_GRADIENT = _UxGT("Celý přechod"); @@ -563,7 +556,7 @@ namespace Language_cz { #if LCD_HEIGHT >= 4 // Up to 3 lines allowed PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_2_LINE("Stikněte tlačítko", "pro obnovení tisku")); - PROGMEM Language_Str MSG_PAUSE_PRINT_INIT = _UxGT(MSG_1_LINE("Parkování...")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Parkování...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_3_LINE("Čekejte prosím", "na zahájení", "výměny filamentu")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_3_LINE("Vložte filament", "a stiskněte", "tlačítko...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_2_LINE("Klikněte pro", "nahřátí trysky")); @@ -576,7 +569,7 @@ namespace Language_cz { #else // LCD_HEIGHT < 4 // Up to 2 lines allowed PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_2_LINE("Stikněte tlač.", "pro obnovení")); - PROGMEM Language_Str MSG_PAUSE_PRINT_INIT = _UxGT(MSG_1_LINE("Parkování...")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Parkování...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_1_LINE("Čekejte...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_1_LINE("Vložte, klikněte")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_2_LINE("Klikněte pro", "nahřátí")); diff --git a/Marlin/src/lcd/language/language_da.h b/Marlin/src/lcd/language/language_da.h index 23d931c17419..be9ad758ce92 100644 --- a/Marlin/src/lcd/language/language_da.h +++ b/Marlin/src/lcd/language/language_da.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,8 +25,7 @@ * Danish * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ #define DISPLAY_CHARSET_ISO10646_1 @@ -49,20 +48,23 @@ namespace Language_da { PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Sæt forsk. af home"); PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Forsk. er nu aktiv"); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Sæt origin"); - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Forvarm ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Forvarm ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Forvarm ") PREHEAT_1_LABEL _UxGT(" end") - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Forvarm ") PREHEAT_1_LABEL _UxGT(" end ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Forvarm ") PREHEAT_1_LABEL _UxGT(" Alle"); - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Forvarm ") PREHEAT_1_LABEL _UxGT(" Bed"); - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Forvarm ") PREHEAT_1_LABEL _UxGT(" conf"); - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("Forvarm ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("Forvarm ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("Forvarm ") PREHEAT_2_LABEL _UxGT(" end") - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("Forvarm ") PREHEAT_2_LABEL _UxGT(" end ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("Forvarm ") PREHEAT_2_LABEL _UxGT(" Alle"); - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("Forvarm ") PREHEAT_2_LABEL _UxGT(" Bed"); - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("Forvarm ") PREHEAT_2_LABEL _UxGT(" conf"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Forvarm ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Forvarm ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Forvarm ") PREHEAT_1_LABEL _UxGT(" end"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Forvarm ") PREHEAT_1_LABEL _UxGT(" end ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Forvarm ") PREHEAT_1_LABEL _UxGT(" Alle"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Forvarm ") PREHEAT_1_LABEL _UxGT(" Bed"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Forvarm ") PREHEAT_1_LABEL _UxGT(" conf"); + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Forvarm $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Forvarm $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Forvarm $ end"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Forvarm $ end ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Forvarm $ Alle"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Forvarm $ Bed"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Forvarm $ conf"); + #endif PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Afkøl"); PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Slå strøm til"); PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("Slå strøm fra"); @@ -124,10 +126,10 @@ namespace Language_da { PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("Skift Re.mm"); PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("Tilbagetræk V"); PROGMEM Language_Str MSG_CONTROL_RETRACT_ZHOP = _UxGT("Hop mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("UnRet mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("Skift UnRet mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("UnRet V"); - PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("AutoRetr."); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("Unretr. mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("Skift Unretr. mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("Unretract V"); + PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("Auto-Retract"); PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("Skift filament"); PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Skift filament *"); PROGMEM Language_Str MSG_CHANGE_MEDIA = _UxGT("Skift SD kort"); @@ -139,9 +141,6 @@ namespace Language_da { PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("Temp løber løbsk"); PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("Fejl: Maks temp"); PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("Fejl: Min temp"); - PROGMEM Language_Str MSG_ERR_MAXTEMP_BED = _UxGT("Fejl: Maks Plade temp"); - PROGMEM Language_Str MSG_ERR_MINTEMP_BED = _UxGT("Fejl: Min Plade temp"); - PROGMEM Language_Str MSG_ERR_Z_HOMING = _UxGT("Home XY først"); PROGMEM Language_Str MSG_HALTED = _UxGT("PRINTER STOPPET"); PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("Reset Venligst"); PROGMEM Language_Str MSG_SHORT_DAY = _UxGT("d"); // Kun et bogstav @@ -185,7 +184,7 @@ namespace Language_da { PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_RESUME = _UxGT("Forsæt print"); - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("Forkert printer"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("Forkert printer"); #if LCD_HEIGHT >= 4 PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_3_LINE("Vent på start", "af filament", "skift")); diff --git a/Marlin/src/lcd/language/language_de.h b/Marlin/src/lcd/language/language_de.h index ed2f779dd84a..74e185680cc7 100644 --- a/Marlin/src/lcd/language/language_de.h +++ b/Marlin/src/lcd/language/language_de.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,29 +25,29 @@ * German * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ namespace Language_de { using namespace Language_en; // Inherit undefined strings from English constexpr uint8_t CHARSIZE = 2; - PROGMEM Language_Str LANGUAGE = _UxGT("Deutsche"); + PROGMEM Language_Str LANGUAGE = _UxGT("Deutsch"); PROGMEM Language_Str WELCOME_MSG = MACHINE_NAME _UxGT(" bereit"); - + PROGMEM Language_Str MSG_MARLIN = _UxGT("Marlin"); PROGMEM Language_Str MSG_YES = _UxGT("JA"); PROGMEM Language_Str MSG_NO = _UxGT("NEIN"); PROGMEM Language_Str MSG_BACK = _UxGT("Zurück"); PROGMEM Language_Str MSG_MEDIA_ABORTING = _UxGT("Abbruch..."); PROGMEM Language_Str MSG_MEDIA_INSERTED = _UxGT("Medium erkannt"); PROGMEM Language_Str MSG_MEDIA_REMOVED = _UxGT("Medium entfernt"); - PROGMEM Language_Str MSG_MEDIA_RELEASED = _UxGT("Medium freigegeben"); PROGMEM Language_Str MSG_MEDIA_WAITING = _UxGT("Warten auf Medium"); + PROGMEM Language_Str MSG_SD_INIT_FAIL = _UxGT("SD Init fehlgesch."); PROGMEM Language_Str MSG_MEDIA_READ_ERROR = _UxGT("Medium Lesefehler"); PROGMEM Language_Str MSG_MEDIA_USB_REMOVED = _UxGT("USB Gerät entfernt"); PROGMEM Language_Str MSG_MEDIA_USB_FAILED = _UxGT("USB Start fehlge."); + PROGMEM Language_Str MSG_KILL_SUBCALL_OVERFLOW = _UxGT("Subcall überschritten"); PROGMEM Language_Str MSG_LCD_ENDSTOPS = _UxGT("Endstopp"); // Max length 8 characters PROGMEM Language_Str MSG_LCD_SOFT_ENDSTOPS = _UxGT("Software-Endstopp"); PROGMEM Language_Str MSG_MAIN = _UxGT("Hauptmenü"); @@ -57,7 +57,13 @@ namespace Language_de { PROGMEM Language_Str MSG_DISABLE_STEPPERS = _UxGT("Motoren deaktivieren"); // M84 :: Max length 19 characters PROGMEM Language_Str MSG_DEBUG_MENU = _UxGT("Debug-Menü"); PROGMEM Language_Str MSG_PROGRESS_BAR_TEST = _UxGT("Statusbalken-Test"); + PROGMEM Language_Str MSG_AUTO_HOME = _UxGT("Auto Home"); + PROGMEM Language_Str MSG_AUTO_HOME_X = _UxGT("Home X"); + PROGMEM Language_Str MSG_AUTO_HOME_Y = _UxGT("Home Y"); + PROGMEM Language_Str MSG_AUTO_HOME_Z = _UxGT("Home Z"); PROGMEM Language_Str MSG_AUTO_Z_ALIGN = _UxGT("Z-Achsen ausgleichen"); + PROGMEM Language_Str MSG_ASSISTED_TRAMMING = _UxGT("Bett ausrichten"); // Bettausrichtung + PROGMEM Language_Str MSG_LEVEL_BED_HOMING = _UxGT("XYZ homen"); PROGMEM Language_Str MSG_LEVEL_BED_WAITING = _UxGT("Klick zum Starten"); PROGMEM Language_Str MSG_LEVEL_BED_NEXT_POINT = _UxGT("Nächste Koordinate"); PROGMEM Language_Str MSG_LEVEL_BED_DONE = _UxGT("Nivellieren fertig!"); @@ -65,22 +71,26 @@ namespace Language_de { PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Setze Homeversatz"); PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Homeversatz aktiv"); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Setze Nullpunkte"); //"G92 X0 Y0 Z0" commented out in ultralcd.cpp - PROGMEM Language_Str MSG_PREHEAT_1 = PREHEAT_1_LABEL _UxGT(" Vorwärmen"); - PROGMEM Language_Str MSG_PREHEAT_1_H = PREHEAT_1_LABEL _UxGT(" Vorwärmen") " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = PREHEAT_1_LABEL _UxGT(" Extr. Vorwärmen"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = PREHEAT_1_LABEL _UxGT(" Extr. Vorwärm. ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = PREHEAT_1_LABEL _UxGT(" Alles Vorwärmen"); - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = PREHEAT_1_LABEL _UxGT(" Bett Vorwärmen"); - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = PREHEAT_1_LABEL _UxGT(" Einstellungen"); - PROGMEM Language_Str MSG_PREHEAT_2 = PREHEAT_2_LABEL _UxGT(" Vorwärmen"); - PROGMEM Language_Str MSG_PREHEAT_2_H = PREHEAT_2_LABEL _UxGT(" Vorwärmen") " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = PREHEAT_2_LABEL _UxGT(" Extr. Vorwärmen"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = PREHEAT_2_LABEL _UxGT(" Extr. Vorwärm. ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = PREHEAT_2_LABEL _UxGT(" Alles Vorwärmen"); - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = PREHEAT_2_LABEL _UxGT(" Bett Vorwärmen"); - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = PREHEAT_2_LABEL _UxGT(" Einstellungen"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = PREHEAT_1_LABEL _UxGT(" Vorwärmen"); + PROGMEM Language_Str MSG_PREHEAT_1_H = PREHEAT_1_LABEL _UxGT(" Vorwärmen ~"); + PROGMEM Language_Str MSG_PREHEAT_1_END = PREHEAT_1_LABEL _UxGT(" Extr. Vorwärmen"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = PREHEAT_1_LABEL _UxGT(" Extr. Vorwärm. ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = PREHEAT_1_LABEL _UxGT(" Alles Vorwärmen"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = PREHEAT_1_LABEL _UxGT(" Bett Vorwärmen"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = PREHEAT_1_LABEL _UxGT(" Einstellungen"); + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("$ Vorwärmen"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("$ Vorwärmen") " ~"; + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("$ Extr. Vorwärmen"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("$ Extr. Vorwärm. ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("$ Alles Vorwärmen"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("$ Bett Vorwärmen"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("$ Einstellungen"); + #endif PROGMEM Language_Str MSG_PREHEAT_CUSTOM = _UxGT("benutzerdef. Heizen"); PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Abkühlen"); + PROGMEM Language_Str MSG_CUTTER_FREQUENCY = _UxGT("Frequenz"); PROGMEM Language_Str MSG_LASER_MENU = _UxGT("Laser"); PROGMEM Language_Str MSG_LASER_OFF = _UxGT("Laser aus"); PROGMEM Language_Str MSG_LASER_ON = _UxGT("Laser an"); @@ -107,9 +117,9 @@ namespace Language_de { PROGMEM Language_Str MSG_MESH_Y = _UxGT("Index Y"); PROGMEM Language_Str MSG_MESH_EDIT_Z = _UxGT("Z-Wert"); PROGMEM Language_Str MSG_USER_MENU = _UxGT("Benutzer-Menü"); - PROGMEM Language_Str MSG_LCD_TILTING_MESH = _UxGT("Berührungspunkt"); PROGMEM Language_Str MSG_M48_TEST = _UxGT("M48 Sondentest"); PROGMEM Language_Str MSG_M48_POINT = _UxGT("M48 Punkt"); + PROGMEM Language_Str MSG_M48_OUT_OF_BOUNDS = _UxGT("Zu weit draußen"); PROGMEM Language_Str MSG_M48_DEVIATION = _UxGT("Abweichung"); PROGMEM Language_Str MSG_IDEX_MENU = _UxGT("IDEX-Modus"); PROGMEM Language_Str MSG_OFFSETS_MENU = _UxGT("Werkzeugversätze"); @@ -123,6 +133,7 @@ namespace Language_de { PROGMEM Language_Str MSG_UBL_DOING_G29 = _UxGT("G29 ausführen"); PROGMEM Language_Str MSG_UBL_TOOLS = _UxGT("UBL-Werkzeuge"); PROGMEM Language_Str MSG_UBL_LEVEL_BED = _UxGT("Unified Bed Leveling"); + PROGMEM Language_Str MSG_LCD_TILTING_MESH = _UxGT("Berührungspunkt"); PROGMEM Language_Str MSG_UBL_MANUAL_MESH = _UxGT("Netz manuell erst."); PROGMEM Language_Str MSG_UBL_BC_INSERT = _UxGT("Unterlegen & messen"); PROGMEM Language_Str MSG_UBL_BC_INSERT2 = _UxGT("Messen"); @@ -140,17 +151,18 @@ namespace Language_de { PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("Bearbeitung beendet"); PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("Eigenes Netz erst."); PROGMEM Language_Str MSG_UBL_BUILD_MESH_MENU = _UxGT("Netz erstellen"); - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M1 = PREHEAT_1_LABEL _UxGT(" Netz erstellen"); - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M2 = PREHEAT_2_LABEL _UxGT(" Netz erstellen"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_UBL_BUILD_MESH_M = _UxGT("$ Netz erstellen"); + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("$ Netz validieren"); + #endif PROGMEM Language_Str MSG_UBL_BUILD_COLD_MESH = _UxGT("Netz erstellen kalt"); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_ADJUST = _UxGT("Netzhöhe einst."); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_AMOUNT = _UxGT("Höhe"); PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_MENU = _UxGT("Netz validieren"); - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M1 = PREHEAT_1_LABEL _UxGT(" Netz validieren"); - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M2 = PREHEAT_2_LABEL _UxGT(" Netz validieren"); PROGMEM Language_Str MSG_UBL_VALIDATE_CUSTOM_MESH = _UxGT("Eig. Netz validieren"); - PROGMEM Language_Str MSG_G26_HEATING_NOZZLE = _UxGT("G26 Heating Nozzle"); PROGMEM Language_Str MSG_G26_HEATING_BED = _UxGT("G26 heizt Bett"); + PROGMEM Language_Str MSG_G26_HEATING_NOZZLE = _UxGT("G26 Düse aufheizen"); + PROGMEM Language_Str MSG_G26_MANUAL_PRIME = _UxGT("Manuell Prime..."); PROGMEM Language_Str MSG_G26_FIXED_LENGTH = _UxGT("Feste Länge Prime"); PROGMEM Language_Str MSG_G26_PRIME_DONE = _UxGT("Priming fertig"); PROGMEM Language_Str MSG_G26_CANCELED = _UxGT("G26 abgebrochen"); @@ -179,8 +191,8 @@ namespace Language_de { PROGMEM Language_Str MSG_UBL_STORAGE_SLOT = _UxGT("Speicherort"); PROGMEM Language_Str MSG_UBL_LOAD_MESH = _UxGT("Bettnetz laden"); PROGMEM Language_Str MSG_UBL_SAVE_MESH = _UxGT("Bettnetz speichern"); - PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("M117 Netz %i geladen"); - PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("M117 Netz %i gespeichert"); + PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("Netz %i geladen"); + PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("Netz %i gespeichert"); PROGMEM Language_Str MSG_UBL_NO_STORAGE = _UxGT("Kein Speicher"); PROGMEM Language_Str MSG_UBL_SAVE_ERROR = _UxGT("Err:UBL speichern"); PROGMEM Language_Str MSG_UBL_RESTORE_ERROR = _UxGT("Err:UBL wiederherst."); @@ -230,12 +242,20 @@ namespace Language_de { PROGMEM Language_Str MSG_BED_Z = _UxGT("Bett Z"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Düse"); PROGMEM Language_Str MSG_NOZZLE_N = _UxGT("Düse ~"); + PROGMEM Language_Str MSG_NOZZLE_PARKED = _UxGT("Düse geparkt"); + PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("Düse bereit"); PROGMEM Language_Str MSG_BED = _UxGT("Bett"); PROGMEM Language_Str MSG_CHAMBER = _UxGT("Gehäuse"); PROGMEM Language_Str MSG_FAN_SPEED = _UxGT("Lüfter"); PROGMEM Language_Str MSG_FAN_SPEED_N = _UxGT("Lüfter ~"); + PROGMEM Language_Str MSG_STORED_FAN_N = _UxGT("Gespeich. Lüfter ~"); PROGMEM Language_Str MSG_EXTRA_FAN_SPEED = _UxGT("Geschw. Extralüfter"); PROGMEM Language_Str MSG_EXTRA_FAN_SPEED_N = _UxGT("Geschw. Extralüfter ~"); + PROGMEM Language_Str MSG_CONTROLLER_FAN = _UxGT("Lüfter Kontroller"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_IDLE_SPEED = _UxGT("Lüfter Leerlauf"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_AUTO_ON = _UxGT("Motorlast Modus"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_SPEED = _UxGT("Lüfter Motorlast"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_DURATION = _UxGT("Ausschalt Delay"); PROGMEM Language_Str MSG_FLOW = _UxGT("Flussrate"); PROGMEM Language_Str MSG_FLOW_N = _UxGT("Flussrate ~"); PROGMEM Language_Str MSG_CONTROL = _UxGT("Einstellungen"); @@ -245,6 +265,22 @@ namespace Language_de { PROGMEM Language_Str MSG_AUTOTEMP = _UxGT("Auto Temperatur"); PROGMEM Language_Str MSG_LCD_ON = _UxGT("an"); PROGMEM Language_Str MSG_LCD_OFF = _UxGT("aus"); + PROGMEM Language_Str MSG_PID_AUTOTUNE = _UxGT("PID Autotune"); + PROGMEM Language_Str MSG_PID_AUTOTUNE_E = _UxGT("PID Autotune *"); + PROGMEM Language_Str MSG_PID_AUTOTUNE_DONE = _UxGT("PID Tuning fertig"); + PROGMEM Language_Str MSG_PID_BAD_EXTRUDER_NUM = _UxGT("Autotune fehlge. Falscher Extruder"); + PROGMEM Language_Str MSG_PID_TEMP_TOO_HIGH = _UxGT("Autotune fehlge. Temperatur zu hoch."); + PROGMEM Language_Str MSG_PID_TIMEOUT = _UxGT("Autotune fehlge.! Timeout."); + PROGMEM Language_Str MSG_PID_P = _UxGT("PID-P"); + PROGMEM Language_Str MSG_PID_P_E = _UxGT("PID-P *"); + PROGMEM Language_Str MSG_PID_I = _UxGT("PID-I"); + PROGMEM Language_Str MSG_PID_I_E = _UxGT("PID-I *"); + PROGMEM Language_Str MSG_PID_D = _UxGT("PID-D"); + PROGMEM Language_Str MSG_PID_D_E = _UxGT("PID-D *"); + PROGMEM Language_Str MSG_PID_C = _UxGT("PID-C"); + PROGMEM Language_Str MSG_PID_C_E = _UxGT("PID-C *"); + PROGMEM Language_Str MSG_PID_F = _UxGT("PID-F"); + PROGMEM Language_Str MSG_PID_F_E = _UxGT("PID-F *"); PROGMEM Language_Str MSG_SELECT = _UxGT("Auswählen"); PROGMEM Language_Str MSG_SELECT_E = _UxGT("Auswählen *"); PROGMEM Language_Str MSG_ACC = _UxGT("Beschleunigung"); @@ -271,6 +307,8 @@ namespace Language_de { PROGMEM Language_Str MSG_AMAX_EN = _UxGT("A max *"); PROGMEM Language_Str MSG_A_RETRACT = _UxGT("A Einzug"); PROGMEM Language_Str MSG_A_TRAVEL = _UxGT("A Leerfahrt"); + PROGMEM Language_Str MSG_XY_FREQUENCY_LIMIT = _UxGT("max. Frequenz"); + PROGMEM Language_Str MSG_XY_FREQUENCY_FEEDRATE = _UxGT("min. Vorschub"); PROGMEM Language_Str MSG_STEPS_PER_MM = _UxGT("Steps/mm"); PROGMEM Language_Str MSG_A_STEPS = LCD_STR_A _UxGT(" Steps/mm"); PROGMEM Language_Str MSG_B_STEPS = LCD_STR_B _UxGT(" Steps/mm"); @@ -281,6 +319,8 @@ namespace Language_de { PROGMEM Language_Str MSG_MOTION = _UxGT("Bewegung"); PROGMEM Language_Str MSG_FILAMENT = _UxGT("Filament"); PROGMEM Language_Str MSG_VOLUMETRIC_ENABLED = _UxGT("E in mm³"); + PROGMEM Language_Str MSG_VOLUMETRIC_LIMIT = _UxGT("E Limit in mm³"); + PROGMEM Language_Str MSG_VOLUMETRIC_LIMIT_E = _UxGT("E Limit *"); PROGMEM Language_Str MSG_FILAMENT_DIAM = _UxGT("Filamentdurchmesser"); PROGMEM Language_Str MSG_FILAMENT_DIAM_E = _UxGT("Filamentdurchmesser *"); PROGMEM Language_Str MSG_FILAMENT_UNLOAD = _UxGT("Entladen mm"); @@ -292,23 +332,38 @@ namespace Language_de { PROGMEM Language_Str MSG_LOAD_EEPROM = _UxGT("Konfig. laden"); PROGMEM Language_Str MSG_RESTORE_DEFAULTS = _UxGT("Standardwerte laden"); PROGMEM Language_Str MSG_INIT_EEPROM = _UxGT("Werkseinstellungen"); + PROGMEM Language_Str MSG_ERR_EEPROM_CRC = _UxGT("EEPROM CRC Fehler"); + PROGMEM Language_Str MSG_ERR_EEPROM_INDEX = _UxGT("EEPROM Index Fehler"); + PROGMEM Language_Str MSG_ERR_EEPROM_VERSION = _UxGT("EEPROM Version Fehler"); + PROGMEM Language_Str MSG_SETTINGS_STORED = _UxGT("Einstell. gespei."); PROGMEM Language_Str MSG_MEDIA_UPDATE = _UxGT("FW Update vom Medium"); PROGMEM Language_Str MSG_RESET_PRINTER = _UxGT("Drucker neustarten"); PROGMEM Language_Str MSG_REFRESH = LCD_STR_REFRESH _UxGT("Aktualisieren"); PROGMEM Language_Str MSG_INFO_SCREEN = _UxGT("Info"); PROGMEM Language_Str MSG_PREPARE = _UxGT("Vorbereitung"); PROGMEM Language_Str MSG_TUNE = _UxGT("Justierung"); + PROGMEM Language_Str MSG_POWER_MONITOR = _UxGT("Power Monitor"); + PROGMEM Language_Str MSG_CURRENT = _UxGT("Strom"); + PROGMEM Language_Str MSG_VOLTAGE = _UxGT("Spannung"); + PROGMEM Language_Str MSG_POWER = _UxGT("Power"); PROGMEM Language_Str MSG_START_PRINT = _UxGT("Starte Druck"); PROGMEM Language_Str MSG_BUTTON_NEXT = _UxGT("Weiter"); PROGMEM Language_Str MSG_BUTTON_INIT = _UxGT("Bestätigen"); PROGMEM Language_Str MSG_BUTTON_STOP = _UxGT("Stop"); PROGMEM Language_Str MSG_BUTTON_PRINT = _UxGT("Drucken"); PROGMEM Language_Str MSG_BUTTON_RESET = _UxGT("Reseten"); + PROGMEM Language_Str MSG_BUTTON_IGNORE = _UxGT("Ignorieren"); PROGMEM Language_Str MSG_BUTTON_CANCEL = _UxGT("Abbrechen"); PROGMEM Language_Str MSG_BUTTON_DONE = _UxGT("Fertig"); + PROGMEM Language_Str MSG_BUTTON_BACK = _UxGT("Zurück"); + PROGMEM Language_Str MSG_BUTTON_PROCEED = _UxGT("Weiter"); + PROGMEM Language_Str MSG_PAUSING = _UxGT("Pause..."); PROGMEM Language_Str MSG_PAUSE_PRINT = _UxGT("SD-Druck pausieren"); PROGMEM Language_Str MSG_RESUME_PRINT = _UxGT("SD-Druck fortsetzen"); PROGMEM Language_Str MSG_STOP_PRINT = _UxGT("SD-Druck abbrechen"); + PROGMEM Language_Str MSG_PRINTING_OBJECT = _UxGT("Objekt drucken"); + PROGMEM Language_Str MSG_CANCEL_OBJECT = _UxGT("Objekt abbrechen"); + PROGMEM Language_Str MSG_CANCEL_OBJECT_N = _UxGT("Objekt abbrechen ="); PROGMEM Language_Str MSG_OUTAGE_RECOVERY = _UxGT("Wiederh. n. Stroma."); PROGMEM Language_Str MSG_MEDIA_MENU = _UxGT("Druck vom Medium"); PROGMEM Language_Str MSG_NO_MEDIA = _UxGT("Kein Medium"); @@ -317,6 +372,7 @@ namespace Language_de { PROGMEM Language_Str MSG_PRINT_PAUSED = _UxGT("Druck pausiert..."); PROGMEM Language_Str MSG_PRINTING = _UxGT("Druckt..."); PROGMEM Language_Str MSG_PRINT_ABORTED = _UxGT("Druck abgebrochen"); + PROGMEM Language_Str MSG_PRINT_DONE = _UxGT("Druck fertig"); PROGMEM Language_Str MSG_NO_MOVE = _UxGT("Motoren angeschaltet"); PROGMEM Language_Str MSG_KILLED = _UxGT("ABGEBROCHEN"); PROGMEM Language_Str MSG_STOPPED = _UxGT("ANGEHALTEN"); @@ -324,18 +380,28 @@ namespace Language_de { PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("Wechs. Einzug mm"); PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("V Einzug"); PROGMEM Language_Str MSG_CONTROL_RETRACT_ZHOP = _UxGT("Z-Sprung mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("UnRet mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("Wechs. UnRet mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("UnRet V"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("Unretr. mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("Wechs. Unretr. mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("Unretract V"); PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAPF = _UxGT("S UnRet V"); PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("Autom. Einzug"); PROGMEM Language_Str MSG_FILAMENT_SWAP_LENGTH = _UxGT("Einzugslänge"); + PROGMEM Language_Str MSG_FILAMENT_SWAP_EXTRA = _UxGT("Extra Einzug"); PROGMEM Language_Str MSG_FILAMENT_PURGE_LENGTH = _UxGT("Entladelänge"); PROGMEM Language_Str MSG_TOOL_CHANGE = _UxGT("Werkzeugwechsel"); PROGMEM Language_Str MSG_TOOL_CHANGE_ZLIFT = _UxGT("Z anheben"); - PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPD = _UxGT("Prime-Geschwin."); - PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPD = _UxGT("Einzug-Geschwin."); - PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("Düsen-Standby"); + PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPEED = _UxGT("Prime-Geschwin."); + PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPEED = _UxGT("Einzug-Geschwin."); + PROGMEM Language_Str MSG_FILAMENT_PARK_ENABLED = _UxGT("Kopf parken"); + PROGMEM Language_Str MSG_SINGLENOZZLE_UNRETRACT_SPEED = _UxGT("Rückzugsgeschwindigkeit"); + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_SPEED = _UxGT("Lüfter Geschwindigkeit"); + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_TIME = _UxGT("Lüfter Zeit"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_ON = _UxGT("Auto AN"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_OFF = _UxGT("Auto AUS"); + PROGMEM Language_Str MSG_TOOL_MIGRATION = _UxGT("Werkzeugmigration"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_AUTO = _UxGT("Auto-Migration"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_END = _UxGT("Letzter Extruder"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_SWAP = _UxGT("Migrieren zu *"); PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("Filament wechseln"); PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Filament wechseln *"); PROGMEM Language_Str MSG_FILAMENTLOAD = _UxGT("Filament laden"); @@ -349,17 +415,17 @@ namespace Language_de { PROGMEM Language_Str MSG_ZPROBE_OUT = _UxGT("Z-Sonde außerhalb"); PROGMEM Language_Str MSG_SKEW_FACTOR = _UxGT("Korrekturfaktor"); PROGMEM Language_Str MSG_BLTOUCH = _UxGT("BLTouch"); - PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("BLTouch Selbsttest"); - PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("BLTouch zurücks."); - PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("BLTouch ausfahren"); - PROGMEM Language_Str MSG_BLTOUCH_SW_MODE = _UxGT("BLTouch SW-Modus"); - PROGMEM Language_Str MSG_BLTOUCH_5V_MODE = _UxGT("BLTouch 5V-Modus"); - PROGMEM Language_Str MSG_BLTOUCH_OD_MODE = _UxGT("BLTouch OD-Modus"); - PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE = _UxGT("BLTouch Mode Store"); - PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_5V = _UxGT("BLTouch auf 5V"); - PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_OD = _UxGT("BLTouch auf OD"); - PROGMEM Language_Str MSG_BLTOUCH_STOW = _UxGT("BLTouch einfahren"); - PROGMEM Language_Str MSG_BLTOUCH_MODE_ECHO = _UxGT("BLTouch Modus: "); + PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("Selbsttest"); + PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("Zurücksetzen"); + PROGMEM Language_Str MSG_BLTOUCH_STOW = _UxGT("Einfahren"); + PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("Ausfahren"); + PROGMEM Language_Str MSG_BLTOUCH_SW_MODE = _UxGT("SW-Modus"); + PROGMEM Language_Str MSG_BLTOUCH_5V_MODE = _UxGT("5V-Modus"); + PROGMEM Language_Str MSG_BLTOUCH_OD_MODE = _UxGT("OD-Modus"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE = _UxGT("Mode-Store"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_5V = _UxGT("Setze auf 5V"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_OD = _UxGT("Setze auf OD"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_ECHO = _UxGT("Modus: "); PROGMEM Language_Str MSG_BLTOUCH_MODE_CHANGE = _UxGT("ACHTUNG: Falsche Einstellung - kann zu Beschädigung führen! Fortfahren?"); PROGMEM Language_Str MSG_TOUCHMI_PROBE = _UxGT("TouchMI"); PROGMEM Language_Str MSG_TOUCHMI_INIT = _UxGT("TouchMI initial."); @@ -369,6 +435,9 @@ namespace Language_de { PROGMEM Language_Str MSG_MANUAL_DEPLOY = _UxGT("Z-Sonde ausfahren"); PROGMEM Language_Str MSG_MANUAL_STOW = _UxGT("Z-Sonde einfahren"); PROGMEM Language_Str MSG_HOME_FIRST = _UxGT("Vorher %s%s%s homen"); + PROGMEM Language_Str MSG_ZPROBE_OFFSETS = _UxGT("Sondenversatz"); + PROGMEM Language_Str MSG_ZPROBE_XOFFSET = _UxGT("Sondenversatz X"); + PROGMEM Language_Str MSG_ZPROBE_YOFFSET = _UxGT("Sondenversatz Y"); PROGMEM Language_Str MSG_ZPROBE_ZOFFSET = _UxGT("Sondenversatz Z"); PROGMEM Language_Str MSG_BABYSTEP_X = _UxGT("Babystep X"); PROGMEM Language_Str MSG_BABYSTEP_Y = _UxGT("Babystep Y"); @@ -376,19 +445,12 @@ namespace Language_de { PROGMEM Language_Str MSG_BABYSTEP_TOTAL = _UxGT("Total"); PROGMEM Language_Str MSG_ENDSTOP_ABORT = _UxGT("Abbr. mit Endstopp"); PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("HEIZEN ERFOLGLOS"); - PROGMEM Language_Str MSG_HEATING_FAILED_LCD_BED = _UxGT("Bett heizen fehlge."); - PROGMEM Language_Str MSG_HEATING_FAILED_LCD_CHAMBER = _UxGT("Geh. heizen fehlge."); PROGMEM Language_Str MSG_ERR_REDUNDANT_TEMP = _UxGT("REDUND. TEMP-ABWEI."); PROGMEM Language_Str MSG_THERMAL_RUNAWAY = " " LCD_STR_THERMOMETER _UxGT(" NICHT ERREICHT"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY_BED = _UxGT("BETT") " " LCD_STR_THERMOMETER _UxGT(" NICHT ERREICHT"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER = _UxGT("GEH.") " " LCD_STR_THERMOMETER _UxGT(" NICHT ERREICHT"); PROGMEM Language_Str MSG_ERR_MAXTEMP = " " LCD_STR_THERMOMETER _UxGT(" ÜBERSCHRITTEN"); PROGMEM Language_Str MSG_ERR_MINTEMP = " " LCD_STR_THERMOMETER _UxGT(" UNTERSCHRITTEN"); - PROGMEM Language_Str MSG_ERR_MAXTEMP_BED = _UxGT("BETT ") LCD_STR_THERMOMETER _UxGT(" ÜBERSCHRITTEN"); - PROGMEM Language_Str MSG_ERR_MINTEMP_BED = _UxGT("BETT ") LCD_STR_THERMOMETER _UxGT(" UNTERSCHRITTEN"); - PROGMEM Language_Str MSG_ERR_MAXTEMP_CHAMBER = _UxGT("Err:Gehäuse max Temp"); - PROGMEM Language_Str MSG_ERR_MINTEMP_CHAMBER = _UxGT("Err:Gehäuse min Temp"); - PROGMEM Language_Str MSG_ERR_Z_HOMING = _UxGT("Vorher XY homen"); PROGMEM Language_Str MSG_HALTED = _UxGT("DRUCKER GESTOPPT"); PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("Bitte neustarten"); PROGMEM Language_Str MSG_SHORT_DAY = _UxGT("t"); // One character only @@ -425,10 +487,13 @@ namespace Language_de { PROGMEM Language_Str MSG_INFO_EXTRUDERS = _UxGT("Extruder"); PROGMEM Language_Str MSG_INFO_BAUDRATE = _UxGT("Baudrate"); PROGMEM Language_Str MSG_INFO_PROTOCOL = _UxGT("Protokoll"); + PROGMEM Language_Str MSG_INFO_RUNAWAY_OFF = _UxGT("Runaway Watch: AUS"); + PROGMEM Language_Str MSG_INFO_RUNAWAY_ON = _UxGT("Runaway Watch: AN"); + PROGMEM Language_Str MSG_HOTEND_IDLE_TIMEOUT = _UxGT("Hotend Idle Timeout"); PROGMEM Language_Str MSG_CASE_LIGHT = _UxGT("Beleuchtung"); PROGMEM Language_Str MSG_CASE_LIGHT_BRIGHTNESS = _UxGT("Helligkeit"); - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("Falscher Drucker"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("Falscher Drucker"); #if LCD_WIDTH >= 20 PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Gesamte Drucke"); @@ -464,13 +529,12 @@ namespace Language_de { PROGMEM Language_Str MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" Düse: "); PROGMEM Language_Str MSG_RUNOUT_SENSOR = _UxGT("Runout-Sensor"); PROGMEM Language_Str MSG_RUNOUT_DISTANCE_MM = _UxGT("Runout-Weg mm"); - PROGMEM Language_Str MSG_LCD_HOMING_FAILED = _UxGT("Homing gescheitert"); + PROGMEM Language_Str MSG_KILL_HOMING_FAILED = _UxGT("Homing gescheitert"); PROGMEM Language_Str MSG_LCD_PROBING_FAILED = _UxGT("Probing gescheitert"); - PROGMEM Language_Str MSG_M600_TOO_COLD = _UxGT("M600: zu kalt"); PROGMEM Language_Str MSG_MMU2_CHOOSE_FILAMENT_HEADER = _UxGT("FILAMENT WÄHLEN"); PROGMEM Language_Str MSG_MMU2_MENU = _UxGT("MMU"); - PROGMEM Language_Str MSG_MMU2_WRONG_FIRMWARE = _UxGT("Update MMU Firmware!"); + PROGMEM Language_Str MSG_KILL_MMU2_FIRMWARE = _UxGT("Update MMU Firmware!"); PROGMEM Language_Str MSG_MMU2_NOT_RESPONDING = _UxGT("MMU handeln erfor."); PROGMEM Language_Str MSG_MMU2_RESUME = _UxGT("Druck fortsetzen"); PROGMEM Language_Str MSG_MMU2_RESUMING = _UxGT("Fortfahren..."); @@ -490,7 +554,7 @@ namespace Language_de { PROGMEM Language_Str MSG_MMU2_EJECT_RECOVER = _UxGT("Entfernen, klicken"); PROGMEM Language_Str MSG_MIX = _UxGT("Mix"); - PROGMEM Language_Str MSG_MIX_COMPONENT_N = _UxGT("Komponente ~"); + PROGMEM Language_Str MSG_MIX_COMPONENT_N = _UxGT("Komponente ="); PROGMEM Language_Str MSG_MIXER = _UxGT("Mixer"); PROGMEM Language_Str MSG_GRADIENT = _UxGT("Gradient"); // equal Farbverlauf PROGMEM Language_Str MSG_FULL_GRADIENT = _UxGT("Volle Gradient"); @@ -513,32 +577,46 @@ namespace Language_de { PROGMEM Language_Str MSG_SNAKE = _UxGT("Sn4k3"); PROGMEM Language_Str MSG_MAZE = _UxGT("Maze"); + PROGMEM Language_Str MSG_BAD_PAGE = _UxGT("ungült. Seitenzahl"); + PROGMEM Language_Str MSG_BAD_PAGE_SPEED = _UxGT("ungült. Seitengeschw."); + + PROGMEM Language_Str MSG_EDIT_PASSWORD = _UxGT("Passwort bearbeiten"); + PROGMEM Language_Str MSG_LOGIN_REQUIRED = _UxGT("Login erforderlich"); + PROGMEM Language_Str MSG_PASSWORD_SETTINGS = _UxGT("Passwort Einstellungen"); + PROGMEM Language_Str MSG_ENTER_DIGIT = _UxGT("PIN eingeben"); + PROGMEM Language_Str MSG_CHANGE_PASSWORD = _UxGT("Passwort ändern"); + PROGMEM Language_Str MSG_REMOVE_PASSWORD = _UxGT("Passwort löschen"); + PROGMEM Language_Str MSG_PASSWORD_SET = _UxGT("Passwort ist "); + PROGMEM Language_Str MSG_START_OVER = _UxGT("von vorn beginnen"); + PROGMEM Language_Str MSG_REMINDER_SAVE_SETTINGS = _UxGT("Bald speichern!"); + PROGMEM Language_Str MSG_PASSWORD_REMOVED = _UxGT("Passwort gelöscht"); + // // Die Filament-Change-Bildschirme können bis zu 3 Zeilen auf einem 4-Zeilen-Display anzeigen // ...oder 2 Zeilen auf einem 3-Zeilen-Display. #if LCD_HEIGHT >= 4 PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_2_LINE("Knopf drücken um", "Druck fortzusetzen")); - PROGMEM Language_Str MSG_PAUSE_PRINT_INIT = _UxGT(MSG_2_LINE("Druck ist", "pausiert...")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_2_LINE("Druck ist", "pausiert...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_3_LINE("Warte auf den", "Start des", "Filamentwechsels...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_3_LINE("Filament einlegen", "und Knopf drücken", "um fortzusetzen")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_2_LINE("Knopf drücken um", "Düse aufzuheizen")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEATING = _UxGT(MSG_2_LINE("Düse heizt auf", "bitte warten...")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_3_LINE("Warte auf", "Herausnahme", "des Filaments...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_3_LINE("Warte auf", "Entnahme", "des Filaments...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_3_LINE("Warte auf", "Laden des", "Filaments...")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_PURGE = _UxGT(MSG_3_LINE("Warte auf", "Entladen des", "Filaments...")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_CONT_PURGE = _UxGT(MSG_3_LINE("Klicke um", "die Fila-Entladung", "zu beenden")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_PURGE = _UxGT(MSG_3_LINE("Warte auf", "Spülung", "der Düse...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_CONT_PURGE = _UxGT(MSG_3_LINE("Klicke um", "die Düsenspülung", "zu beenden")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_3_LINE("Warte auf", "Fortsetzen des", "Drucks...")); #else // LCD_HEIGHT < 4 PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_1_LINE("Klick zum Fortsetzen")); - PROGMEM Language_Str MSG_PAUSE_PRINT_INIT = _UxGT(MSG_1_LINE("Pausiert...")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Pausiert...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_1_LINE("Bitte warten...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_1_LINE("Laden und Klick")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_1_LINE("Klick zum Heizen")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEATING = _UxGT(MSG_1_LINE("Heizen...")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_1_LINE("Entladen...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_1_LINE("Entnehmen...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_1_LINE("Laden...")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_PURGE = _UxGT(MSG_1_LINE("Entladen...")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_CONT_PURGE = _UxGT(MSG_2_LINE("Klick zum beenden", "der Fila-Entladung")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_PURGE = _UxGT(MSG_1_LINE("Spülen...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_CONT_PURGE = _UxGT(MSG_2_LINE("Klick zum beenden", "der Düsenspülung")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_1_LINE("Fortsetzen...")); #endif // LCD_HEIGHT < 4 @@ -556,4 +634,13 @@ namespace Language_de { PROGMEM Language_Str MSG_BACKLASH_C = LCD_STR_C; PROGMEM Language_Str MSG_BACKLASH_CORRECTION = _UxGT("Korrektur"); PROGMEM Language_Str MSG_BACKLASH_SMOOTHING = _UxGT("Glätten"); + PROGMEM Language_Str MSG_LEVEL_X_AXIS = _UxGT("X Achse leveln"); + PROGMEM Language_Str MSG_AUTO_CALIBRATE = _UxGT("Auto. Kalibiren"); + #if ENABLED(TOUCH_UI_FTDI_EVE) + PROGMEM Language_Str MSG_HEATER_TIMEOUT = _UxGT("Idle Timeout, Temperatur fällt. Drücke Okay, um erneut aufzuheizen und fortzufahren."); + #else + PROGMEM Language_Str MSG_HEATER_TIMEOUT = _UxGT("Heizungs Timeout"); + #endif + PROGMEM Language_Str MSG_REHEAT = _UxGT("Erneut aufheizen"); + PROGMEM Language_Str MSG_REHEATING = _UxGT("Erneut aufhei. ..."); } diff --git a/Marlin/src/lcd/language/language_el.h b/Marlin/src/lcd/language/language_el.h index 6cb177d10806..125119d5ccfa 100644 --- a/Marlin/src/lcd/language/language_el.h +++ b/Marlin/src/lcd/language/language_el.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,8 +25,7 @@ * Greek * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ #define DISPLAY_CHARSET_ISO10646_GREEK @@ -54,20 +53,23 @@ namespace Language_el { PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Ορισμός βασικών μετατοπίσεων"); //SHORTEN PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Εφαρμόστηκαν οι μετατοπίσεις"); //SHORTEN PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Ορισμός προέλευσης"); - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL _UxGT(" End"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL _UxGT(" End ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL _UxGT(" όλα"); - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL _UxGT(" bed"); //SHORTEN - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL _UxGT(" επιβεβαίωση"); //SHORTEN - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("Προθέρμανση ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_H0 = _UxGT("Προθέρμανση ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("Προθέρμανση ") PREHEAT_2_LABEL _UxGT(" End"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("Προθέρμανση ") PREHEAT_2_LABEL _UxGT(" End ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("Προθέρμανση ") PREHEAT_2_LABEL _UxGT(" όλα"); - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("Προθέρμανση ") PREHEAT_2_LABEL _UxGT(" bed"); //SHORTEN - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("Προθέρμανση ") PREHEAT_2_LABEL _UxGT(" επιβεβαίωση"); //SHORTEN + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL _UxGT(" End"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL _UxGT(" End ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL _UxGT(" όλα"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL _UxGT(" bed"); //SHORTEN + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL _UxGT(" επιβεβαίωση"); //SHORTEN + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Προθέρμανση $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Προθέρμανση $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Προθέρμανση $ End"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Προθέρμανση $ End ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Προθέρμανση $ όλα"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Προθέρμανση $ bed"); //SHORTEN + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Προθέρμανση $ επιβεβαίωση"); //SHORTEN + #endif PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Μειωση θερμοκρασιας"); PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Ενεργοποίηση"); PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("Απενεργοποίηση"); @@ -156,9 +158,9 @@ namespace Language_el { PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("Εναλλαγή ανάσυρσης μμ"); //SHORTEN PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("Ανάσυρση V"); PROGMEM Language_Str MSG_CONTROL_RETRACT_ZHOP = _UxGT("Μεταπήδηση μμ"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("UnRet mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("S UnRet mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("UnRet V"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("Unretr. mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("S Unretr. mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("Unretract V"); PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("Αυτόματη ανάσυρση"); PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("Αλλαγή νήματος"); PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Αλλαγή νήματος *"); @@ -177,8 +179,6 @@ namespace Language_el { PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("ΔΙΑΦΥΓΗ ΘΕΡΜΟΚΡΑΣΙΑΣ"); PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("ΠΕΡΙΤΗ ΘΕΡΜΟΚΡΑΣΙΑ"); PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("ΜΗ ΕΠΑΡΚΗΣ ΘΕΡΜΟΚΡΑΣΙΑΣ"); //SHORTEN - PROGMEM Language_Str MSG_ERR_MAXTEMP_BED = _UxGT("ΜΕΓΙΣΤΗ ΘΕΡΜΟΚΡΑΣΙΑΣ ΕΠ. ΕΚΤΥΠΩΣΗΣ"); //SHORTEN - PROGMEM Language_Str MSG_ERR_MINTEMP_BED = _UxGT("ΕΛΑΧΙΣΤΗ ΘΕΡΜΟΚΡΑΣΙΑΣ ΕΠ. ΕΚΤΥΠΩΣΗΣ"); //SHORTEN PROGMEM Language_Str MSG_HALTED = _UxGT("H εκτύπωση διακόπηκε"); PROGMEM Language_Str MSG_HEATING = _UxGT("Θερμαίνεται…"); PROGMEM Language_Str MSG_BED_HEATING = _UxGT("Θέρμανση ΕΠ. Εκτύπωσης"); //SHORTEN @@ -188,5 +188,5 @@ namespace Language_el { PROGMEM Language_Str MSG_DELTA_CALIBRATE_Z = _UxGT("Βαθμονόμηση Z"); PROGMEM Language_Str MSG_DELTA_CALIBRATE_CENTER = _UxGT("Βαθμονόμηση κέντρου"); - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("Εσφαλμένος εκτυπωτής"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("Εσφαλμένος εκτυπωτής"); } diff --git a/Marlin/src/lcd/language/language_el_gr.h b/Marlin/src/lcd/language/language_el_gr.h index 5213dc7db92e..3db6fccdf07f 100644 --- a/Marlin/src/lcd/language/language_el_gr.h +++ b/Marlin/src/lcd/language/language_el_gr.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,8 +25,7 @@ * Greek (Greece) * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ #define DISPLAY_CHARSET_ISO10646_GREEK @@ -55,20 +54,23 @@ namespace Language_el_gr { PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Ορισμός βασικών μετατοπίσεων"); PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Εφαρμόστηκαν οι μετατοπίσεις"); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Ορισμός προέλευσης"); - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL _UxGT(" End"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL _UxGT(" End ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL _UxGT(" όλα"); - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL _UxGT(" κλίνη"); - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL _UxGT(" επιβεβαίωση"); - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("Προθέρμανση ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("Προθέρμανση ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("Προθέρμανση ") PREHEAT_2_LABEL _UxGT(" End"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("Προθέρμανση ") PREHEAT_2_LABEL _UxGT(" End ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("Προθέρμανση ") PREHEAT_2_LABEL _UxGT(" όλα"); - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("Προθέρμανση ") PREHEAT_2_LABEL _UxGT(" κλίνη"); - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("Προθέρμανση ") PREHEAT_2_LABEL _UxGT(" επιβεβαίωση"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL _UxGT(" End"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL _UxGT(" End ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL _UxGT(" όλα"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL _UxGT(" κλίνη"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Προθέρμανση ") PREHEAT_1_LABEL _UxGT(" επιβεβαίωση"); + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Προθέρμανση $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Προθέρμανση $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Προθέρμανση $ End"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Προθέρμανση $ End ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Προθέρμανση $ όλα"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Προθέρμανση $ κλίνη"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Προθέρμανση $ επιβεβαίωση"); + #endif PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Μειωση θερμοκρασιας"); PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Ενεργοποίηση"); PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("Απενεργοποίηση"); @@ -158,9 +160,9 @@ namespace Language_el_gr { PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("Εναλλαγή ανάσυρσης μμ"); PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("Ανάσυρση V"); PROGMEM Language_Str MSG_CONTROL_RETRACT_ZHOP = _UxGT("Μεταπήδηση μμ"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("UnRet mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("S UnRet mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("UnRet V"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("Unretr. mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("S Unretr. mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("Unretract V"); PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("Αυτόματη ανάσυρση"); PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("Αλλαγή νήματος"); PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Αλλαγή νήματος *"); @@ -179,8 +181,6 @@ namespace Language_el_gr { PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("ΔΙΑΦΥΓΗ ΘΕΡΜΟΤΗΤΑΣ"); PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("Λάθος: ΜΕΓΙΣΤΗ ΘΕΡΜΟΤΗΤΑ"); PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("Λάθος: ΕΛΑΧΙΣΤΗ ΘΕΡΜΟΤΗΤΑ"); - PROGMEM Language_Str MSG_ERR_MAXTEMP_BED = _UxGT("Λάθος: ΜΕΓΙΣΤΗ ΘΕΡΜΟΤΗΤΑ ΚΛΙΝΗΣ"); - PROGMEM Language_Str MSG_ERR_MINTEMP_BED = _UxGT("Λάθος: ΕΛΑΧΙΣΤΗ ΘΕΡΜΟΤΗΤΑ ΚΛΙΝΗΣ"); PROGMEM Language_Str MSG_HEATING = _UxGT("Θερμαίνεται…"); PROGMEM Language_Str MSG_BED_HEATING = _UxGT("Θέρμανση κλίνης…"); PROGMEM Language_Str MSG_DELTA_CALIBRATE = _UxGT("Βαθμονόμηση Delta"); @@ -189,5 +189,5 @@ namespace Language_el_gr { PROGMEM Language_Str MSG_DELTA_CALIBRATE_Z = _UxGT("Βαθμονόμηση Z"); PROGMEM Language_Str MSG_DELTA_CALIBRATE_CENTER = _UxGT("Βαθμονόμηση κέντρου"); - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("Εσφαλμένος εκτυπωτής"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("Εσφαλμένος εκτυπωτής"); } diff --git a/Marlin/src/lcd/language/language_en.h b/Marlin/src/lcd/language/language_en.h index b5f508973df6..e8b4769cc216 100644 --- a/Marlin/src/lcd/language/language_en.h +++ b/Marlin/src/lcd/language/language_en.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,8 +25,7 @@ * English * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ #define en 1234 @@ -47,11 +46,12 @@ namespace Language_en { PROGMEM Language_Str MSG_MEDIA_ABORTING = _UxGT("Aborting..."); PROGMEM Language_Str MSG_MEDIA_INSERTED = _UxGT("Media Inserted"); PROGMEM Language_Str MSG_MEDIA_REMOVED = _UxGT("Media Removed"); - PROGMEM Language_Str MSG_MEDIA_RELEASED = _UxGT("Media Released"); PROGMEM Language_Str MSG_MEDIA_WAITING = _UxGT("Waiting for media"); + PROGMEM Language_Str MSG_SD_INIT_FAIL = _UxGT("SD Init Fail"); PROGMEM Language_Str MSG_MEDIA_READ_ERROR = _UxGT("Media read error"); PROGMEM Language_Str MSG_MEDIA_USB_REMOVED = _UxGT("USB device removed"); PROGMEM Language_Str MSG_MEDIA_USB_FAILED = _UxGT("USB start failed"); + PROGMEM Language_Str MSG_KILL_SUBCALL_OVERFLOW = _UxGT("Subcall Overflow"); PROGMEM Language_Str MSG_LCD_ENDSTOPS = _UxGT("Endstops"); // Max length 8 characters PROGMEM Language_Str MSG_LCD_SOFT_ENDSTOPS = _UxGT("Soft Endstops"); PROGMEM Language_Str MSG_MAIN = _UxGT("Main"); @@ -66,6 +66,10 @@ namespace Language_en { PROGMEM Language_Str MSG_AUTO_HOME_Y = _UxGT("Home Y"); PROGMEM Language_Str MSG_AUTO_HOME_Z = _UxGT("Home Z"); PROGMEM Language_Str MSG_AUTO_Z_ALIGN = _UxGT("Auto Z-Align"); + PROGMEM Language_Str MSG_ASSISTED_TRAMMING = _UxGT("Assisted Tramming"); + PROGMEM Language_Str MSG_ITERATION = _UxGT("G34 Iteration: %i"); + PROGMEM Language_Str MSG_DECREASING_ACCURACY = _UxGT("Accuracy Decreasing!"); + PROGMEM Language_Str MSG_ACCURACY_ACHIEVED = _UxGT("Accuracy Achieved"); PROGMEM Language_Str MSG_LEVEL_BED_HOMING = _UxGT("Homing XYZ"); PROGMEM Language_Str MSG_LEVEL_BED_WAITING = _UxGT("Click to Begin"); PROGMEM Language_Str MSG_LEVEL_BED_NEXT_POINT = _UxGT("Next Point"); @@ -74,22 +78,26 @@ namespace Language_en { PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Set Home Offsets"); PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Offsets Applied"); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Set Origin"); - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Preheat ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Preheat ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Preheat ") PREHEAT_1_LABEL _UxGT(" End"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Preheat ") PREHEAT_1_LABEL _UxGT(" End ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Preheat ") PREHEAT_1_LABEL _UxGT(" All"); - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Preheat ") PREHEAT_1_LABEL _UxGT(" Bed"); - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Preheat ") PREHEAT_1_LABEL _UxGT(" Conf"); - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("Preheat ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("Preheat ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("Preheat ") PREHEAT_2_LABEL _UxGT(" End"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("Preheat ") PREHEAT_2_LABEL _UxGT(" End ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("Preheat ") PREHEAT_2_LABEL _UxGT(" All"); - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("Preheat ") PREHEAT_2_LABEL _UxGT(" Bed"); - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("Preheat ") PREHEAT_2_LABEL _UxGT(" Conf"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Preheat ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Preheat ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Preheat ") PREHEAT_1_LABEL _UxGT(" End"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Preheat ") PREHEAT_1_LABEL _UxGT(" End ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Preheat ") PREHEAT_1_LABEL _UxGT(" All"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Preheat ") PREHEAT_1_LABEL _UxGT(" Bed"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Preheat ") PREHEAT_1_LABEL _UxGT(" Conf"); + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Preheat $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Preheat $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Preheat $ End"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Preheat $ End ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Preheat $ All"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Preheat $ Bed"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Preheat $ Conf"); + #endif PROGMEM Language_Str MSG_PREHEAT_CUSTOM = _UxGT("Preheat Custom"); PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Cooldown"); + PROGMEM Language_Str MSG_CUTTER_FREQUENCY = _UxGT("Frequency"); PROGMEM Language_Str MSG_LASER_MENU = _UxGT("Laser Control"); PROGMEM Language_Str MSG_LASER_OFF = _UxGT("Laser Off"); PROGMEM Language_Str MSG_LASER_ON = _UxGT("Laser On"); @@ -118,6 +126,7 @@ namespace Language_en { PROGMEM Language_Str MSG_USER_MENU = _UxGT("Custom Commands"); PROGMEM Language_Str MSG_M48_TEST = _UxGT("M48 Probe Test"); PROGMEM Language_Str MSG_M48_POINT = _UxGT("M48 Point"); + PROGMEM Language_Str MSG_M48_OUT_OF_BOUNDS = _UxGT("Probe out of bounds"); PROGMEM Language_Str MSG_M48_DEVIATION = _UxGT("Deviation"); PROGMEM Language_Str MSG_IDEX_MENU = _UxGT("IDEX Mode"); PROGMEM Language_Str MSG_OFFSETS_MENU = _UxGT("Tool Offsets"); @@ -149,14 +158,12 @@ namespace Language_en { PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("Done Editing Mesh"); PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("Build Custom Mesh"); PROGMEM Language_Str MSG_UBL_BUILD_MESH_MENU = _UxGT("Build Mesh"); - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M1 = _UxGT("Build Mesh (") PREHEAT_1_LABEL _UxGT(")"); - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M2 = _UxGT("Build Mesh (") PREHEAT_2_LABEL _UxGT(")"); + PROGMEM Language_Str MSG_UBL_BUILD_MESH_M = _UxGT("Build Mesh ($)"); PROGMEM Language_Str MSG_UBL_BUILD_COLD_MESH = _UxGT("Build Cold Mesh"); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_ADJUST = _UxGT("Adjust Mesh Height"); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_AMOUNT = _UxGT("Height Amount"); PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_MENU = _UxGT("Validate Mesh"); - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M1 = _UxGT("Validate Mesh (") PREHEAT_1_LABEL _UxGT(")"); - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M2 = _UxGT("Validate Mesh (") PREHEAT_2_LABEL _UxGT(")"); + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("Validate Mesh ($)"); PROGMEM Language_Str MSG_UBL_VALIDATE_CUSTOM_MESH = _UxGT("Validate Custom Mesh"); PROGMEM Language_Str MSG_G26_HEATING_BED = _UxGT("G26 Heating Bed"); PROGMEM Language_Str MSG_G26_HEATING_NOZZLE = _UxGT("G26 Heating Nozzle"); @@ -189,8 +196,8 @@ namespace Language_en { PROGMEM Language_Str MSG_UBL_STORAGE_SLOT = _UxGT("Memory Slot"); PROGMEM Language_Str MSG_UBL_LOAD_MESH = _UxGT("Load Bed Mesh"); PROGMEM Language_Str MSG_UBL_SAVE_MESH = _UxGT("Save Bed Mesh"); - PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("M117 Mesh %i Loaded"); - PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("M117 Mesh %i Saved"); + PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("Mesh %i Loaded"); + PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("Mesh %i Saved"); PROGMEM Language_Str MSG_UBL_NO_STORAGE = _UxGT("No Storage"); PROGMEM Language_Str MSG_UBL_SAVE_ERROR = _UxGT("Err: UBL Save"); PROGMEM Language_Str MSG_UBL_RESTORE_ERROR = _UxGT("Err: UBL Restore"); @@ -217,6 +224,10 @@ namespace Language_en { PROGMEM Language_Str MSG_SET_LEDS_VIOLET = _UxGT("Violet"); PROGMEM Language_Str MSG_SET_LEDS_WHITE = _UxGT("White"); PROGMEM Language_Str MSG_SET_LEDS_DEFAULT = _UxGT("Default"); + PROGMEM Language_Str MSG_LED_CHANNEL_N = _UxGT("Channel ="); + PROGMEM Language_Str MSG_LEDS2 = _UxGT("Lights #2"); + PROGMEM Language_Str MSG_NEO2_PRESETS = _UxGT("Light #2 Presets"); + PROGMEM Language_Str MSG_NEO2_BRIGHTNESS = _UxGT("Brightness"); PROGMEM Language_Str MSG_CUSTOM_LEDS = _UxGT("Custom Lights"); PROGMEM Language_Str MSG_INTENSITY_R = _UxGT("Red Intensity"); PROGMEM Language_Str MSG_INTENSITY_G = _UxGT("Green Intensity"); @@ -240,6 +251,8 @@ namespace Language_en { PROGMEM Language_Str MSG_BED_Z = _UxGT("Bed Z"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Nozzle"); PROGMEM Language_Str MSG_NOZZLE_N = _UxGT("Nozzle ~"); + PROGMEM Language_Str MSG_NOZZLE_PARKED = _UxGT("Nozzle Parked"); + PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("Nozzle Standby"); PROGMEM Language_Str MSG_BED = _UxGT("Bed"); PROGMEM Language_Str MSG_CHAMBER = _UxGT("Enclosure"); PROGMEM Language_Str MSG_FAN_SPEED = _UxGT("Fan Speed"); @@ -247,6 +260,11 @@ namespace Language_en { PROGMEM Language_Str MSG_STORED_FAN_N = _UxGT("Stored Fan ~"); PROGMEM Language_Str MSG_EXTRA_FAN_SPEED = _UxGT("Extra Fan Speed"); PROGMEM Language_Str MSG_EXTRA_FAN_SPEED_N = _UxGT("Extra Fan Speed ~"); + PROGMEM Language_Str MSG_CONTROLLER_FAN = _UxGT("Controller Fan"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_IDLE_SPEED = _UxGT("Idle Speed"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_AUTO_ON = _UxGT("Auto Mode"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_SPEED = _UxGT("Active Speed"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_DURATION = _UxGT("Idle Period"); PROGMEM Language_Str MSG_FLOW = _UxGT("Flow"); PROGMEM Language_Str MSG_FLOW_N = _UxGT("Flow ~"); PROGMEM Language_Str MSG_CONTROL = _UxGT("Control"); @@ -258,6 +276,10 @@ namespace Language_en { PROGMEM Language_Str MSG_LCD_OFF = _UxGT("Off"); PROGMEM Language_Str MSG_PID_AUTOTUNE = _UxGT("PID Autotune"); PROGMEM Language_Str MSG_PID_AUTOTUNE_E = _UxGT("PID Autotune *"); + PROGMEM Language_Str MSG_PID_AUTOTUNE_DONE = _UxGT("PID tuning done"); + PROGMEM Language_Str MSG_PID_BAD_EXTRUDER_NUM = _UxGT("Autotune failed. Bad extruder."); + PROGMEM Language_Str MSG_PID_TEMP_TOO_HIGH = _UxGT("Autotune failed. Temperature too high."); + PROGMEM Language_Str MSG_PID_TIMEOUT = _UxGT("Autotune failed! Timeout."); PROGMEM Language_Str MSG_PID_P = _UxGT("PID-P"); PROGMEM Language_Str MSG_PID_P_E = _UxGT("PID-P *"); PROGMEM Language_Str MSG_PID_I = _UxGT("PID-I"); @@ -293,16 +315,20 @@ namespace Language_en { PROGMEM Language_Str MSG_AMAX_EN = _UxGT("Amax *"); PROGMEM Language_Str MSG_A_RETRACT = _UxGT("A-Retract"); PROGMEM Language_Str MSG_A_TRAVEL = _UxGT("A-Travel"); + PROGMEM Language_Str MSG_XY_FREQUENCY_LIMIT = _UxGT("Frequency max"); + PROGMEM Language_Str MSG_XY_FREQUENCY_FEEDRATE = _UxGT("Feed min"); PROGMEM Language_Str MSG_STEPS_PER_MM = _UxGT("Steps/mm"); - PROGMEM Language_Str MSG_A_STEPS = LCD_STR_A _UxGT("steps/mm"); - PROGMEM Language_Str MSG_B_STEPS = LCD_STR_B _UxGT("steps/mm"); - PROGMEM Language_Str MSG_C_STEPS = LCD_STR_C _UxGT("steps/mm"); - PROGMEM Language_Str MSG_E_STEPS = _UxGT("Esteps/mm"); - PROGMEM Language_Str MSG_EN_STEPS = _UxGT("*steps/mm"); + PROGMEM Language_Str MSG_A_STEPS = LCD_STR_A _UxGT(" Steps/mm"); + PROGMEM Language_Str MSG_B_STEPS = LCD_STR_B _UxGT(" Steps/mm"); + PROGMEM Language_Str MSG_C_STEPS = LCD_STR_C _UxGT(" Steps/mm"); + PROGMEM Language_Str MSG_E_STEPS = _UxGT("E steps/mm"); + PROGMEM Language_Str MSG_EN_STEPS = _UxGT("* Steps/mm"); PROGMEM Language_Str MSG_TEMPERATURE = _UxGT("Temperature"); PROGMEM Language_Str MSG_MOTION = _UxGT("Motion"); PROGMEM Language_Str MSG_FILAMENT = _UxGT("Filament"); PROGMEM Language_Str MSG_VOLUMETRIC_ENABLED = _UxGT("E in mm³"); + PROGMEM Language_Str MSG_VOLUMETRIC_LIMIT = _UxGT("E Limit in mm³"); + PROGMEM Language_Str MSG_VOLUMETRIC_LIMIT_E = _UxGT("E Limit *"); PROGMEM Language_Str MSG_FILAMENT_DIAM = _UxGT("Fil. Dia."); PROGMEM Language_Str MSG_FILAMENT_DIAM_E = _UxGT("Fil. Dia. *"); PROGMEM Language_Str MSG_FILAMENT_UNLOAD = _UxGT("Unload mm"); @@ -314,32 +340,40 @@ namespace Language_en { PROGMEM Language_Str MSG_LOAD_EEPROM = _UxGT("Load Settings"); PROGMEM Language_Str MSG_RESTORE_DEFAULTS = _UxGT("Restore Defaults"); PROGMEM Language_Str MSG_INIT_EEPROM = _UxGT("Initialize EEPROM"); - PROGMEM Language_Str MSG_ERR_EEPROM_CRC = _UxGT("Err: EEPROM CRC"); - PROGMEM Language_Str MSG_ERR_EEPROM_INDEX = _UxGT("Err: EEPROM Index"); - PROGMEM Language_Str MSG_ERR_EEPROM_VERSION = _UxGT("Err: EEPROM Version"); + PROGMEM Language_Str MSG_ERR_EEPROM_CRC = _UxGT("EEPROM CRC Error"); + PROGMEM Language_Str MSG_ERR_EEPROM_INDEX = _UxGT("EEPROM Index Error"); + PROGMEM Language_Str MSG_ERR_EEPROM_VERSION = _UxGT("EEPROM Version Error"); + PROGMEM Language_Str MSG_SETTINGS_STORED = _UxGT("Settings Stored"); PROGMEM Language_Str MSG_MEDIA_UPDATE = _UxGT("Media Update"); PROGMEM Language_Str MSG_RESET_PRINTER = _UxGT("Reset Printer"); - PROGMEM Language_Str MSG_REFRESH = LCD_STR_REFRESH _UxGT("Refresh"); + PROGMEM Language_Str MSG_REFRESH = LCD_STR_REFRESH _UxGT("Refresh"); PROGMEM Language_Str MSG_INFO_SCREEN = _UxGT("Info Screen"); PROGMEM Language_Str MSG_PREPARE = _UxGT("Prepare"); PROGMEM Language_Str MSG_TUNE = _UxGT("Tune"); + PROGMEM Language_Str MSG_POWER_MONITOR = _UxGT("Power monitor"); + PROGMEM Language_Str MSG_CURRENT = _UxGT("Current"); + PROGMEM Language_Str MSG_VOLTAGE = _UxGT("Voltage"); + PROGMEM Language_Str MSG_POWER = _UxGT("Power"); PROGMEM Language_Str MSG_START_PRINT = _UxGT("Start Print"); PROGMEM Language_Str MSG_BUTTON_NEXT = _UxGT("Next"); PROGMEM Language_Str MSG_BUTTON_INIT = _UxGT("Init"); PROGMEM Language_Str MSG_BUTTON_STOP = _UxGT("Stop"); PROGMEM Language_Str MSG_BUTTON_PRINT = _UxGT("Print"); PROGMEM Language_Str MSG_BUTTON_RESET = _UxGT("Reset"); + PROGMEM Language_Str MSG_BUTTON_IGNORE = _UxGT("Ignore"); PROGMEM Language_Str MSG_BUTTON_CANCEL = _UxGT("Cancel"); PROGMEM Language_Str MSG_BUTTON_DONE = _UxGT("Done"); PROGMEM Language_Str MSG_BUTTON_BACK = _UxGT("Back"); PROGMEM Language_Str MSG_BUTTON_PROCEED = _UxGT("Proceed"); + PROGMEM Language_Str MSG_PAUSING = _UxGT("Pausing..."); PROGMEM Language_Str MSG_PAUSE_PRINT = _UxGT("Pause Print"); PROGMEM Language_Str MSG_RESUME_PRINT = _UxGT("Resume Print"); + PROGMEM Language_Str MSG_HOST_START_PRINT = _UxGT("Host Start"); PROGMEM Language_Str MSG_STOP_PRINT = _UxGT("Stop Print"); PROGMEM Language_Str MSG_PRINTING_OBJECT = _UxGT("Printing Object"); PROGMEM Language_Str MSG_CANCEL_OBJECT = _UxGT("Cancel Object"); PROGMEM Language_Str MSG_CANCEL_OBJECT_N = _UxGT("Cancel Object ="); - PROGMEM Language_Str MSG_OUTAGE_RECOVERY = _UxGT("Outage Recovery"); + PROGMEM Language_Str MSG_OUTAGE_RECOVERY = _UxGT("Power Outage"); PROGMEM Language_Str MSG_MEDIA_MENU = _UxGT("Print from Media"); PROGMEM Language_Str MSG_NO_MEDIA = _UxGT("No Media"); PROGMEM Language_Str MSG_DWELL = _UxGT("Sleep..."); @@ -347,25 +381,36 @@ namespace Language_en { PROGMEM Language_Str MSG_PRINT_PAUSED = _UxGT("Print Paused"); PROGMEM Language_Str MSG_PRINTING = _UxGT("Printing..."); PROGMEM Language_Str MSG_PRINT_ABORTED = _UxGT("Print Aborted"); + PROGMEM Language_Str MSG_PRINT_DONE = _UxGT("Print Done"); PROGMEM Language_Str MSG_NO_MOVE = _UxGT("No Move."); PROGMEM Language_Str MSG_KILLED = _UxGT("KILLED. "); PROGMEM Language_Str MSG_STOPPED = _UxGT("STOPPED. "); PROGMEM Language_Str MSG_CONTROL_RETRACT = _UxGT("Retract mm"); PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("Swap Re.mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("Retract V"); + PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("Retract V"); PROGMEM Language_Str MSG_CONTROL_RETRACT_ZHOP = _UxGT("Hop mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("UnRet mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("S UnRet mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("UnRet V"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("Unretr. mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("S Unretr. mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("Unretract V"); PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAPF = _UxGT("S UnRet V"); - PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("AutoRetr."); + PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("Auto-Retract"); PROGMEM Language_Str MSG_FILAMENT_SWAP_LENGTH = _UxGT("Swap Length"); + PROGMEM Language_Str MSG_FILAMENT_SWAP_EXTRA = _UxGT("Swap Extra"); PROGMEM Language_Str MSG_FILAMENT_PURGE_LENGTH = _UxGT("Purge Length"); PROGMEM Language_Str MSG_TOOL_CHANGE = _UxGT("Tool Change"); PROGMEM Language_Str MSG_TOOL_CHANGE_ZLIFT = _UxGT("Z Raise"); - PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPD = _UxGT("Prime Speed"); - PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPD = _UxGT("Retract Speed"); - PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("Nozzle Standby"); + PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPEED = _UxGT("Prime Speed"); + PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPEED = _UxGT("Retract Speed"); + PROGMEM Language_Str MSG_FILAMENT_PARK_ENABLED = _UxGT("Park Head"); + PROGMEM Language_Str MSG_SINGLENOZZLE_UNRETRACT_SPEED = _UxGT("Recover Speed"); + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_SPEED = _UxGT("Fan Speed"); + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_TIME = _UxGT("Fan Time"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_ON = _UxGT("Auto ON"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_OFF = _UxGT("Auto OFF"); + PROGMEM Language_Str MSG_TOOL_MIGRATION = _UxGT("Tool Migration"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_AUTO = _UxGT("Auto-migration"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_END = _UxGT("Last Extruder"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_SWAP = _UxGT("Migrate to *"); PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("Change Filament"); PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Change Filament *"); PROGMEM Language_Str MSG_FILAMENTLOAD = _UxGT("Load Filament"); @@ -379,14 +424,14 @@ namespace Language_en { PROGMEM Language_Str MSG_ZPROBE_OUT = _UxGT("Z Probe Past Bed"); PROGMEM Language_Str MSG_SKEW_FACTOR = _UxGT("Skew Factor"); PROGMEM Language_Str MSG_BLTOUCH = _UxGT("BLTouch"); - PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("Cmd: Self-Test"); - PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("Cmd: Reset"); - PROGMEM Language_Str MSG_BLTOUCH_STOW = _UxGT("Cmd: Stow"); - PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("Cmd: Deploy"); - PROGMEM Language_Str MSG_BLTOUCH_SW_MODE = _UxGT("Cmd: SW-Mode"); - PROGMEM Language_Str MSG_BLTOUCH_5V_MODE = _UxGT("Cmd: 5V-Mode"); - PROGMEM Language_Str MSG_BLTOUCH_OD_MODE = _UxGT("Cmd: OD-Mode"); - PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE = _UxGT("Cmd: Mode-Store"); + PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("Self-Test"); + PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("Reset"); + PROGMEM Language_Str MSG_BLTOUCH_STOW = _UxGT("Stow"); + PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("Deploy"); + PROGMEM Language_Str MSG_BLTOUCH_SW_MODE = _UxGT("SW-Mode"); + PROGMEM Language_Str MSG_BLTOUCH_5V_MODE = _UxGT("5V-Mode"); + PROGMEM Language_Str MSG_BLTOUCH_OD_MODE = _UxGT("OD-Mode"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE = _UxGT("Mode-Store"); PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_5V = _UxGT("Set BLTouch to 5V"); PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_OD = _UxGT("Set BLTouch to OD"); PROGMEM Language_Str MSG_BLTOUCH_MODE_ECHO = _UxGT("Report Drain"); @@ -403,25 +448,19 @@ namespace Language_en { PROGMEM Language_Str MSG_ZPROBE_XOFFSET = _UxGT("Probe X Offset"); PROGMEM Language_Str MSG_ZPROBE_YOFFSET = _UxGT("Probe Y Offset"); PROGMEM Language_Str MSG_ZPROBE_ZOFFSET = _UxGT("Probe Z Offset"); + PROGMEM Language_Str MSG_MOVE_NOZZLE_TO_BED = _UxGT("Move Nozzle to Bed"); PROGMEM Language_Str MSG_BABYSTEP_X = _UxGT("Babystep X"); PROGMEM Language_Str MSG_BABYSTEP_Y = _UxGT("Babystep Y"); PROGMEM Language_Str MSG_BABYSTEP_Z = _UxGT("Babystep Z"); PROGMEM Language_Str MSG_BABYSTEP_TOTAL = _UxGT("Total"); PROGMEM Language_Str MSG_ENDSTOP_ABORT = _UxGT("Endstop Abort"); PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("Heating Failed"); - PROGMEM Language_Str MSG_HEATING_FAILED_LCD_BED = _UxGT("Bed Heating Failed"); - PROGMEM Language_Str MSG_HEATING_FAILED_LCD_CHAMBER = _UxGT("Chamber Heating Fail"); PROGMEM Language_Str MSG_ERR_REDUNDANT_TEMP = _UxGT("Err: REDUNDANT TEMP"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("THERMAL RUNAWAY"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY_BED = _UxGT("BED THERMAL RUNAWAY"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER = _UxGT("CHAMBER T. RUNAWAY"); PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("Err: MAXTEMP"); PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("Err: MINTEMP"); - PROGMEM Language_Str MSG_ERR_MAXTEMP_BED = _UxGT("Err: MAXTEMP BED"); - PROGMEM Language_Str MSG_ERR_MINTEMP_BED = _UxGT("Err: MINTEMP BED"); - PROGMEM Language_Str MSG_ERR_MAXTEMP_CHAMBER = _UxGT("Err: MAXTEMP CHAMBER"); - PROGMEM Language_Str MSG_ERR_MINTEMP_CHAMBER = _UxGT("Err: MINTEMP CHAMBER"); - PROGMEM Language_Str MSG_ERR_Z_HOMING = _UxGT("Home XY First"); PROGMEM Language_Str MSG_HALTED = _UxGT("PRINTER HALTED"); PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("Please Reset"); PROGMEM Language_Str MSG_SHORT_DAY = _UxGT("d"); // One character only @@ -431,6 +470,8 @@ namespace Language_en { PROGMEM Language_Str MSG_COOLING = _UxGT("Cooling..."); PROGMEM Language_Str MSG_BED_HEATING = _UxGT("Bed Heating..."); PROGMEM Language_Str MSG_BED_COOLING = _UxGT("Bed Cooling..."); + PROGMEM Language_Str MSG_PROBE_HEATING = _UxGT("Probe Heating..."); + PROGMEM Language_Str MSG_PROBE_COOLING = _UxGT("Probe Cooling..."); PROGMEM Language_Str MSG_CHAMBER_HEATING = _UxGT("Chamber Heating..."); PROGMEM Language_Str MSG_CHAMBER_COOLING = _UxGT("Chamber Cooling..."); PROGMEM Language_Str MSG_DELTA_CALIBRATE = _UxGT("Delta Calibration"); @@ -460,15 +501,16 @@ namespace Language_en { PROGMEM Language_Str MSG_INFO_PROTOCOL = _UxGT("Protocol"); PROGMEM Language_Str MSG_INFO_RUNAWAY_OFF = _UxGT("Runaway Watch: OFF"); PROGMEM Language_Str MSG_INFO_RUNAWAY_ON = _UxGT("Runaway Watch: ON"); + PROGMEM Language_Str MSG_HOTEND_IDLE_TIMEOUT = _UxGT("Hotend Idle Timeout"); PROGMEM Language_Str MSG_CASE_LIGHT = _UxGT("Case Light"); PROGMEM Language_Str MSG_CASE_LIGHT_BRIGHTNESS = _UxGT("Light Brightness"); - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("INCORRECT PRINTER"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("INCORRECT PRINTER"); #if LCD_WIDTH >= 20 PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Print Count"); PROGMEM Language_Str MSG_INFO_COMPLETED_PRINTS = _UxGT("Completed"); - PROGMEM Language_Str MSG_INFO_PRINT_TIME = _UxGT("Total Print time"); + PROGMEM Language_Str MSG_INFO_PRINT_TIME = _UxGT("Total Print Time"); PROGMEM Language_Str MSG_INFO_PRINT_LONGEST = _UxGT("Longest Job Time"); PROGMEM Language_Str MSG_INFO_PRINT_FILAMENT = _UxGT("Extruded Total"); #else @@ -499,29 +541,28 @@ namespace Language_en { PROGMEM Language_Str MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" Nozzle: "); PROGMEM Language_Str MSG_RUNOUT_SENSOR = _UxGT("Runout Sensor"); PROGMEM Language_Str MSG_RUNOUT_DISTANCE_MM = _UxGT("Runout Dist mm"); - PROGMEM Language_Str MSG_LCD_HOMING_FAILED = _UxGT("Homing Failed"); + PROGMEM Language_Str MSG_KILL_HOMING_FAILED = _UxGT("Homing Failed"); PROGMEM Language_Str MSG_LCD_PROBING_FAILED = _UxGT("Probing Failed"); - PROGMEM Language_Str MSG_M600_TOO_COLD = _UxGT("M600: Too Cold"); PROGMEM Language_Str MSG_MMU2_CHOOSE_FILAMENT_HEADER = _UxGT("CHOOSE FILAMENT"); PROGMEM Language_Str MSG_MMU2_MENU = _UxGT("MMU"); - PROGMEM Language_Str MSG_MMU2_WRONG_FIRMWARE = _UxGT("Update MMU Firmware!"); + PROGMEM Language_Str MSG_KILL_MMU2_FIRMWARE = _UxGT("Update MMU Firmware!"); PROGMEM Language_Str MSG_MMU2_NOT_RESPONDING = _UxGT("MMU Needs Attention."); - PROGMEM Language_Str MSG_MMU2_RESUME = _UxGT("Resume Print"); - PROGMEM Language_Str MSG_MMU2_RESUMING = _UxGT("Resuming..."); - PROGMEM Language_Str MSG_MMU2_LOAD_FILAMENT = _UxGT("Load Filament"); - PROGMEM Language_Str MSG_MMU2_LOAD_ALL = _UxGT("Load All"); - PROGMEM Language_Str MSG_MMU2_LOAD_TO_NOZZLE = _UxGT("Load to Nozzle"); - PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT = _UxGT("Eject Filament"); - PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT_N = _UxGT("Eject Filament ~"); - PROGMEM Language_Str MSG_MMU2_UNLOAD_FILAMENT = _UxGT("Unload Filament"); + PROGMEM Language_Str MSG_MMU2_RESUME = _UxGT("MMU Resume"); + PROGMEM Language_Str MSG_MMU2_RESUMING = _UxGT("MMU Resuming..."); + PROGMEM Language_Str MSG_MMU2_LOAD_FILAMENT = _UxGT("MMU Load"); + PROGMEM Language_Str MSG_MMU2_LOAD_ALL = _UxGT("MMU Load All"); + PROGMEM Language_Str MSG_MMU2_LOAD_TO_NOZZLE = _UxGT("MMU Load to Nozzle"); + PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT = _UxGT("MMU Eject"); + PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT_N = _UxGT("MMU Eject ~"); + PROGMEM Language_Str MSG_MMU2_UNLOAD_FILAMENT = _UxGT("MMU Unload"); PROGMEM Language_Str MSG_MMU2_LOADING_FILAMENT = _UxGT("Loading Fil. %i..."); PROGMEM Language_Str MSG_MMU2_EJECTING_FILAMENT = _UxGT("Ejecting Fil. ..."); PROGMEM Language_Str MSG_MMU2_UNLOADING_FILAMENT = _UxGT("Unloading Fil...."); PROGMEM Language_Str MSG_MMU2_ALL = _UxGT("All"); PROGMEM Language_Str MSG_MMU2_FILAMENT_N = _UxGT("Filament ~"); PROGMEM Language_Str MSG_MMU2_RESET = _UxGT("Reset MMU"); - PROGMEM Language_Str MSG_MMU2_RESETTING = _UxGT("Resetting MMU..."); + PROGMEM Language_Str MSG_MMU2_RESETTING = _UxGT("MMU Resetting..."); PROGMEM Language_Str MSG_MMU2_EJECT_RECOVER = _UxGT("Remove, click"); PROGMEM Language_Str MSG_MIX = _UxGT("Mix"); @@ -549,9 +590,19 @@ namespace Language_en { PROGMEM Language_Str MSG_SNAKE = _UxGT("Sn4k3"); PROGMEM Language_Str MSG_MAZE = _UxGT("Maze"); - #define MSG_1_LINE(A) A "\0" "\0" - #define MSG_2_LINE(A,B) A "\0" B "\0" - #define MSG_3_LINE(A,B,C) A "\0" B "\0" C + PROGMEM Language_Str MSG_BAD_PAGE = _UxGT("Bad page index"); + PROGMEM Language_Str MSG_BAD_PAGE_SPEED = _UxGT("Bad page speed"); + + PROGMEM Language_Str MSG_EDIT_PASSWORD = _UxGT("Edit Password"); + PROGMEM Language_Str MSG_LOGIN_REQUIRED = _UxGT("Login Required"); + PROGMEM Language_Str MSG_PASSWORD_SETTINGS = _UxGT("Password Settings"); + PROGMEM Language_Str MSG_ENTER_DIGIT = _UxGT("Enter Digit"); + PROGMEM Language_Str MSG_CHANGE_PASSWORD = _UxGT("Set/Edit Password"); + PROGMEM Language_Str MSG_REMOVE_PASSWORD = _UxGT("Remove Password"); + PROGMEM Language_Str MSG_PASSWORD_SET = _UxGT("Password is "); + PROGMEM Language_Str MSG_START_OVER = _UxGT("Start Over"); + PROGMEM Language_Str MSG_REMINDER_SAVE_SETTINGS = _UxGT("Remember to Save!"); + PROGMEM Language_Str MSG_PASSWORD_REMOVED = _UxGT("Password Removed"); // // Filament Change screens show up to 3 lines on a 4-line display @@ -559,7 +610,7 @@ namespace Language_en { // #if LCD_HEIGHT >= 4 PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_2_LINE("Press Button", "to resume print")); - PROGMEM Language_Str MSG_PAUSE_PRINT_INIT = _UxGT(MSG_1_LINE("Parking...")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Parking...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_3_LINE("Wait for", "filament change", "to start")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_3_LINE("Insert filament", "and press button", "to continue")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_2_LINE("Press button", "to heat nozzle")); @@ -571,7 +622,7 @@ namespace Language_en { PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_2_LINE("Wait for print", "to resume...")); #else PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_1_LINE("Click to continue")); - PROGMEM Language_Str MSG_PAUSE_PRINT_INIT = _UxGT(MSG_1_LINE("Parking...")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Parking...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_1_LINE("Please wait...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_1_LINE("Insert and Click")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_1_LINE("Click to heat")); @@ -596,12 +647,24 @@ namespace Language_en { PROGMEM Language_Str MSG_BACKLASH_C = LCD_STR_C; PROGMEM Language_Str MSG_BACKLASH_CORRECTION = _UxGT("Correction"); PROGMEM Language_Str MSG_BACKLASH_SMOOTHING = _UxGT("Smoothing"); + + PROGMEM Language_Str MSG_LEVEL_X_AXIS = _UxGT("Level X Axis"); + PROGMEM Language_Str MSG_AUTO_CALIBRATE = _UxGT("Auto Calibrate"); + #if ENABLED(TOUCH_UI_FTDI_EVE) + PROGMEM Language_Str MSG_HEATER_TIMEOUT = _UxGT("Idle timeout, temperature decreased. Press Okay to reheat and again to resume."); + #else + PROGMEM Language_Str MSG_HEATER_TIMEOUT = _UxGT("Heater Timeout"); + #endif + PROGMEM Language_Str MSG_REHEAT = _UxGT("Reheat"); + PROGMEM Language_Str MSG_REHEATING = _UxGT("Reheating..."); + + PROGMEM Language_Str MSG_PROBE_WIZARD = _UxGT("Z Probe Wizard"); } #if FAN_COUNT == 1 #define MSG_FIRST_FAN_SPEED MSG_FAN_SPEED - #define MSG_FIRST_EXTRA_FAN_SPEED MSG_EXTRA_FAN_SPEED + #define MSG_EXTRA_FIRST_FAN_SPEED MSG_EXTRA_FAN_SPEED #else #define MSG_FIRST_FAN_SPEED MSG_FAN_SPEED_N - #define MSG_FIRST_EXTRA_FAN_SPEED MSG_EXTRA_FAN_SPEED_N + #define MSG_EXTRA_FIRST_FAN_SPEED MSG_EXTRA_FAN_SPEED_N #endif diff --git a/Marlin/src/lcd/language/language_es.h b/Marlin/src/lcd/language/language_es.h index 12d487b35b76..c77b12ee7749 100644 --- a/Marlin/src/lcd/language/language_es.h +++ b/Marlin/src/lcd/language/language_es.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,26 +25,23 @@ * Spanish * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ -#define DISPLAY_CHARSET_ISO10646_1 - namespace Language_es { using namespace Language_en; // Inherit undefined strings from English constexpr uint8_t CHARSIZE = 2; PROGMEM Language_Str LANGUAGE = _UxGT("Spanish"); - PROGMEM Language_Str WELCOME_MSG = MACHINE_NAME _UxGT(" lista"); + PROGMEM Language_Str WELCOME_MSG = MACHINE_NAME _UxGT(" Lista"); + PROGMEM Language_Str MSG_MARLIN = _UxGT("Marlin"); PROGMEM Language_Str MSG_YES = _UxGT("SI"); PROGMEM Language_Str MSG_NO = _UxGT("NO"); PROGMEM Language_Str MSG_BACK = _UxGT("Atrás"); PROGMEM Language_Str MSG_MEDIA_ABORTING = _UxGT("Cancelando..."); PROGMEM Language_Str MSG_MEDIA_INSERTED = _UxGT("SD/USB insertado"); PROGMEM Language_Str MSG_MEDIA_REMOVED = _UxGT("SD/USB retirado"); - PROGMEM Language_Str MSG_MEDIA_RELEASED = _UxGT("SD/USB lanzado"); PROGMEM Language_Str MSG_MEDIA_WAITING = _UxGT("Esperando al SD/USB"); PROGMEM Language_Str MSG_MEDIA_READ_ERROR = _UxGT("Error lectura SD/USB"); PROGMEM Language_Str MSG_MEDIA_USB_REMOVED = _UxGT("Disp. USB retirado"); @@ -67,33 +64,37 @@ namespace Language_es { PROGMEM Language_Str MSG_LEVEL_BED_WAITING = _UxGT("Pulsar para comenzar"); PROGMEM Language_Str MSG_LEVEL_BED_NEXT_POINT = _UxGT("Siguiente punto"); PROGMEM Language_Str MSG_LEVEL_BED_DONE = _UxGT("¡Nivelación lista!"); - PROGMEM Language_Str MSG_Z_FADE_HEIGHT = _UxGT("Compensación Altura"); + PROGMEM Language_Str MSG_Z_FADE_HEIGHT = _UxGT("Compen. Altura"); PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Ajustar desfases"); PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Desfase aplicada"); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Establecer origen"); - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Precalentar ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Precalentar ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Precalentar ") PREHEAT_1_LABEL _UxGT(" Fin"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Precalentar ") PREHEAT_1_LABEL _UxGT(" Fin ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Precalentar ") PREHEAT_1_LABEL _UxGT(" Todo"); - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Precalentar ") PREHEAT_1_LABEL _UxGT(" Cama"); - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Precalentar ") PREHEAT_1_LABEL _UxGT(" Ajuste"); - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("Precalentar ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("Precalentar ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("Precalentar ") PREHEAT_2_LABEL _UxGT(" Fin"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("Precalentar ") PREHEAT_2_LABEL _UxGT(" Fin ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("Precalentar ") PREHEAT_2_LABEL _UxGT(" Todo"); - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("Precalentar ") PREHEAT_2_LABEL _UxGT(" Cama"); - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("Precalentar ") PREHEAT_2_LABEL _UxGT(" Ajuste"); - PROGMEM Language_Str MSG_PREHEAT_CUSTOM = _UxGT("Precalen. Personali."); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Precal. ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Precal. ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Precal. ") PREHEAT_1_LABEL _UxGT(" Fusor"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Precal. ") PREHEAT_1_LABEL _UxGT(" Fusor ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Precal. ") PREHEAT_1_LABEL _UxGT(" Todo"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Precal. ") PREHEAT_1_LABEL _UxGT(" Cama"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Precal. ") PREHEAT_1_LABEL _UxGT(" Ajuste"); + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Precal. $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Precal. $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Precal. $ Fusor"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Precal. $ Fusor ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Precal. $ Todo"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Precal. $ Cama"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Precal. $ Ajuste"); + #endif + PROGMEM Language_Str MSG_PREHEAT_CUSTOM = _UxGT("Precal. manual"); PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Enfriar"); + PROGMEM Language_Str MSG_CUTTER_FREQUENCY = _UxGT("Frecuencia"); PROGMEM Language_Str MSG_LASER_MENU = _UxGT("Control Láser"); - PROGMEM Language_Str MSG_LASER_OFF = _UxGT("Láser Apagado"); - PROGMEM Language_Str MSG_LASER_ON = _UxGT("Láser Encendido"); + PROGMEM Language_Str MSG_LASER_OFF = _UxGT("Apagar Láser"); + PROGMEM Language_Str MSG_LASER_ON = _UxGT("Encender Láser"); PROGMEM Language_Str MSG_LASER_POWER = _UxGT("Potencia Láser"); PROGMEM Language_Str MSG_SPINDLE_MENU = _UxGT("Control Mandrino"); - PROGMEM Language_Str MSG_SPINDLE_OFF = _UxGT("Mandrino Apagado"); - PROGMEM Language_Str MSG_SPINDLE_ON = _UxGT("Mandrino Encendido"); + PROGMEM Language_Str MSG_SPINDLE_OFF = _UxGT("Apagar Mandrino"); + PROGMEM Language_Str MSG_SPINDLE_ON = _UxGT("Encender Mandrino"); PROGMEM Language_Str MSG_SPINDLE_POWER = _UxGT("Potencia Mandrino"); PROGMEM Language_Str MSG_SPINDLE_REVERSE = _UxGT("Invertir giro"); PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Encender Fuente"); @@ -112,22 +113,22 @@ namespace Language_es { PROGMEM Language_Str MSG_MESH_X = _UxGT("Índice X"); PROGMEM Language_Str MSG_MESH_Y = _UxGT("Índice Y"); PROGMEM Language_Str MSG_MESH_EDIT_Z = _UxGT("Valor Z"); - PROGMEM Language_Str MSG_USER_MENU = _UxGT("Comandos Personaliz."); + PROGMEM Language_Str MSG_USER_MENU = _UxGT("Com. Personalizados"); PROGMEM Language_Str MSG_M48_TEST = _UxGT("M48 Probar Sonda"); PROGMEM Language_Str MSG_M48_POINT = _UxGT("M48 Punto"); PROGMEM Language_Str MSG_M48_DEVIATION = _UxGT("Desviación"); PROGMEM Language_Str MSG_IDEX_MENU = _UxGT("Modo IDEX"); - PROGMEM Language_Str MSG_OFFSETS_MENU = _UxGT("Desfase Boquillas"); + PROGMEM Language_Str MSG_OFFSETS_MENU = _UxGT("Desfase Herramienta"); PROGMEM Language_Str MSG_IDEX_MODE_AUTOPARK = _UxGT("Auto-Aparcado"); PROGMEM Language_Str MSG_IDEX_MODE_DUPLICATE = _UxGT("Duplicar"); PROGMEM Language_Str MSG_IDEX_MODE_MIRRORED_COPY = _UxGT("Copia Reflejada"); PROGMEM Language_Str MSG_IDEX_MODE_FULL_CTRL = _UxGT("Control Total"); - PROGMEM Language_Str MSG_HOTEND_OFFSET_X = _UxGT("2ª Boquilla X"); - PROGMEM Language_Str MSG_HOTEND_OFFSET_Y = _UxGT("2ª Boquilla Y"); - PROGMEM Language_Str MSG_HOTEND_OFFSET_Z = _UxGT("2ª Boquilla Z"); + PROGMEM Language_Str MSG_HOTEND_OFFSET_X = _UxGT("2ª Fusor X"); + PROGMEM Language_Str MSG_HOTEND_OFFSET_Y = _UxGT("2ª Fusor Y"); + PROGMEM Language_Str MSG_HOTEND_OFFSET_Z = _UxGT("2ª Fusor Z"); PROGMEM Language_Str MSG_UBL_DOING_G29 = _UxGT("Hacer G29"); PROGMEM Language_Str MSG_UBL_TOOLS = _UxGT("Herramientas UBL"); - PROGMEM Language_Str MSG_UBL_LEVEL_BED = _UxGT("Nivel.Cama.Uni.(UBL)"); + PROGMEM Language_Str MSG_UBL_LEVEL_BED = _UxGT("Nivelado UBL"); PROGMEM Language_Str MSG_LCD_TILTING_MESH = _UxGT("Punto de inclinación"); PROGMEM Language_Str MSG_UBL_MANUAL_MESH = _UxGT("Crear Mallado man."); PROGMEM Language_Str MSG_UBL_BC_INSERT = _UxGT("Colocar cuña y Medir"); @@ -137,24 +138,24 @@ namespace Language_es { PROGMEM Language_Str MSG_UBL_ACTIVATE_MESH = _UxGT("Activar UBL"); PROGMEM Language_Str MSG_UBL_DEACTIVATE_MESH = _UxGT("Desactivar UBL"); PROGMEM Language_Str MSG_UBL_SET_TEMP_BED = _UxGT("Temp. Cama"); - PROGMEM Language_Str MSG_UBL_BED_TEMP_CUSTOM = _UxGT("Bed Temp"); - PROGMEM Language_Str MSG_UBL_SET_TEMP_HOTEND = _UxGT ("Hotend Temp"); - PROGMEM Language_Str MSG_UBL_HOTEND_TEMP_CUSTOM = _UxGT("Hotend Temp"); + PROGMEM Language_Str MSG_UBL_BED_TEMP_CUSTOM = _UxGT("Temp. Cama perso."); + PROGMEM Language_Str MSG_UBL_SET_TEMP_HOTEND = _UxGT("Temp. Fusor"); + PROGMEM Language_Str MSG_UBL_HOTEND_TEMP_CUSTOM = _UxGT("Temp. Fusor perso."); PROGMEM Language_Str MSG_UBL_MESH_EDIT = _UxGT("Editar Mallado"); PROGMEM Language_Str MSG_UBL_EDIT_CUSTOM_MESH = _UxGT("Edit. Mallado perso."); PROGMEM Language_Str MSG_UBL_FINE_TUNE_MESH = _UxGT("Ajuste fino Mallado"); PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("Term. edici. Mallado"); - PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("Crear Mallado Perso."); + PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("Crear Mallado Pers."); PROGMEM Language_Str MSG_UBL_BUILD_MESH_MENU = _UxGT("Crear Mallado"); - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M1 = _UxGT("Crear Mallado (") PREHEAT_1_LABEL _UxGT(")"); - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M2 = _UxGT("Crear Mallado (") PREHEAT_2_LABEL _UxGT(")"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_UBL_BUILD_MESH_M = _UxGT("Crear Mallado ($)"); + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("Valid. Mall. ($)"); + #endif PROGMEM Language_Str MSG_UBL_BUILD_COLD_MESH = _UxGT("Crear Mallado Frío"); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_ADJUST = _UxGT("Ajustar alt. Mallado"); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_AMOUNT = _UxGT("Cantidad de altura"); - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_MENU = _UxGT("Validar Mallado"); - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M1 = _UxGT("Validar Mallado (") PREHEAT_1_LABEL _UxGT(")"); - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M2 = _UxGT("Validar Mallado (") PREHEAT_2_LABEL _UxGT(")"); - PROGMEM Language_Str MSG_UBL_VALIDATE_CUSTOM_MESH = _UxGT("Vali. Mallado perso."); + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_MENU = _UxGT("Valid. Mallado"); + PROGMEM Language_Str MSG_UBL_VALIDATE_CUSTOM_MESH = _UxGT("Valid. Mall. perso."); PROGMEM Language_Str MSG_G26_HEATING_BED = _UxGT("G26 Calentando Cama"); PROGMEM Language_Str MSG_G26_HEATING_NOZZLE = _UxGT("G26 Calent. Boquilla"); PROGMEM Language_Str MSG_G26_MANUAL_PRIME = _UxGT("Imprimado manual..."); @@ -165,14 +166,14 @@ namespace Language_es { PROGMEM Language_Str MSG_UBL_CONTINUE_MESH = _UxGT("Contin. Mallado cama"); PROGMEM Language_Str MSG_UBL_MESH_LEVELING = _UxGT("Nivelando Mallado"); PROGMEM Language_Str MSG_UBL_3POINT_MESH_LEVELING = _UxGT("Nivelando 3Puntos"); - PROGMEM Language_Str MSG_UBL_GRID_MESH_LEVELING = _UxGT("Nivel. Mallado cuad."); + PROGMEM Language_Str MSG_UBL_GRID_MESH_LEVELING = _UxGT("Niv. Mall. cuadri"); PROGMEM Language_Str MSG_UBL_MESH_LEVEL = _UxGT("Nivel de Mallado"); PROGMEM Language_Str MSG_UBL_SIDE_POINTS = _UxGT("Puntos Laterales"); PROGMEM Language_Str MSG_UBL_MAP_TYPE = _UxGT("Tipo de mapa "); PROGMEM Language_Str MSG_UBL_OUTPUT_MAP = _UxGT("Salida Mapa mallado"); PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_HOST = _UxGT("Salida para el host"); PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_CSV = _UxGT("Salida para CSV"); - PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_BACKUP = _UxGT("Off Printer Backup"); + PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_BACKUP = _UxGT("Cópia de seg. ext"); PROGMEM Language_Str MSG_UBL_INFO_UBL = _UxGT("Salida Info. UBL"); PROGMEM Language_Str MSG_UBL_FILLIN_AMOUNT = _UxGT("Cantidad de relleno"); PROGMEM Language_Str MSG_UBL_MANUAL_FILLIN = _UxGT("Relleno manual"); @@ -183,28 +184,28 @@ namespace Language_es { PROGMEM Language_Str MSG_UBL_FINE_TUNE_ALL = _UxGT("Ajustar Fino Todo"); PROGMEM Language_Str MSG_UBL_FINE_TUNE_CLOSEST = _UxGT("Ajustar Fino proxi."); PROGMEM Language_Str MSG_UBL_STORAGE_MESH_MENU = _UxGT("Almacen de Mallado"); - PROGMEM Language_Str MSG_UBL_STORAGE_SLOT = _UxGT("Huecos de memoria"); - PROGMEM Language_Str MSG_UBL_LOAD_MESH = _UxGT("Cargar Mallado cama"); - PROGMEM Language_Str MSG_UBL_SAVE_MESH = _UxGT("Guardar Mallado cama"); - PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("M117 Mallado %i Cargado"); - PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("M117 Mallado %i Guardado"); + PROGMEM Language_Str MSG_UBL_STORAGE_SLOT = _UxGT("Huecos memoria"); + PROGMEM Language_Str MSG_UBL_LOAD_MESH = _UxGT("Cargar Mall. cama"); + PROGMEM Language_Str MSG_UBL_SAVE_MESH = _UxGT("Guardar Mall. cama"); + PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("Malla %i Cargada"); + PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("Malla %i Guardada"); PROGMEM Language_Str MSG_UBL_NO_STORAGE = _UxGT("Sin guardar"); PROGMEM Language_Str MSG_UBL_SAVE_ERROR = _UxGT("Error: Guardar UBL"); PROGMEM Language_Str MSG_UBL_RESTORE_ERROR = _UxGT("Error: Restaurar UBL"); PROGMEM Language_Str MSG_UBL_Z_OFFSET = _UxGT("Desfase de Z: "); PROGMEM Language_Str MSG_UBL_Z_OFFSET_STOPPED = _UxGT("Desfase de Z Parado"); PROGMEM Language_Str MSG_UBL_STEP_BY_STEP_MENU = _UxGT("UBL Paso a Paso"); - PROGMEM Language_Str MSG_UBL_1_BUILD_COLD_MESH = _UxGT("1.Crear Mallado Frío"); - PROGMEM Language_Str MSG_UBL_2_SMART_FILLIN = _UxGT("2.Relleno inteligente"); - PROGMEM Language_Str MSG_UBL_3_VALIDATE_MESH_MENU = _UxGT("3.Validar Mallado"); + PROGMEM Language_Str MSG_UBL_1_BUILD_COLD_MESH = _UxGT("1.Crear Mall. Frío"); + PROGMEM Language_Str MSG_UBL_2_SMART_FILLIN = _UxGT("2.Relleno intelig."); + PROGMEM Language_Str MSG_UBL_3_VALIDATE_MESH_MENU = _UxGT("3.Valid. Mallado"); PROGMEM Language_Str MSG_UBL_4_FINE_TUNE_ALL = _UxGT("4.Ajustar Fino Todo"); - PROGMEM Language_Str MSG_UBL_5_VALIDATE_MESH_MENU = _UxGT("5.Validar Mallado"); + PROGMEM Language_Str MSG_UBL_5_VALIDATE_MESH_MENU = _UxGT("5.Valid. Mallado"); PROGMEM Language_Str MSG_UBL_6_FINE_TUNE_ALL = _UxGT("6.Ajustar Fino Todo"); - PROGMEM Language_Str MSG_UBL_7_SAVE_MESH = _UxGT("7.Guardar Mallado cama"); + PROGMEM Language_Str MSG_UBL_7_SAVE_MESH = _UxGT("7.Guardar Mall. cama"); PROGMEM Language_Str MSG_LED_CONTROL = _UxGT("Control LED"); - PROGMEM Language_Str MSG_LEDS = _UxGT("Luzes"); - PROGMEM Language_Str MSG_LED_PRESETS = _UxGT("Luz predefinida"); + PROGMEM Language_Str MSG_LEDS = _UxGT("LEDS"); + PROGMEM Language_Str MSG_LED_PRESETS = _UxGT("Color predefinido"); PROGMEM Language_Str MSG_SET_LEDS_RED = _UxGT("Rojo"); PROGMEM Language_Str MSG_SET_LEDS_ORANGE = _UxGT("Naranja"); PROGMEM Language_Str MSG_SET_LEDS_YELLOW = _UxGT("Amarillo"); @@ -214,7 +215,7 @@ namespace Language_es { PROGMEM Language_Str MSG_SET_LEDS_VIOLET = _UxGT("Violeta"); PROGMEM Language_Str MSG_SET_LEDS_WHITE = _UxGT("Blanco"); PROGMEM Language_Str MSG_SET_LEDS_DEFAULT = _UxGT("Por defecto"); - PROGMEM Language_Str MSG_CUSTOM_LEDS = _UxGT("Luces personalizadas"); + PROGMEM Language_Str MSG_CUSTOM_LEDS = _UxGT("Color personalizado"); PROGMEM Language_Str MSG_INTENSITY_R = _UxGT("Intensidad Rojo"); PROGMEM Language_Str MSG_INTENSITY_G = _UxGT("Intensidad Verde"); PROGMEM Language_Str MSG_INTENSITY_B = _UxGT("Intensidad Azul"); @@ -237,27 +238,59 @@ namespace Language_es { PROGMEM Language_Str MSG_BED_Z = _UxGT("Cama Z"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Boquilla"); PROGMEM Language_Str MSG_NOZZLE_N = _UxGT("Boquilla ~"); + PROGMEM Language_Str MSG_NOZZLE_PARKED = _UxGT("Boquilla Aparcada"); + PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("Boquilla en Espera"); PROGMEM Language_Str MSG_BED = _UxGT("Cama"); PROGMEM Language_Str MSG_CHAMBER = _UxGT("Recinto"); PROGMEM Language_Str MSG_FAN_SPEED = _UxGT("Ventilador"); PROGMEM Language_Str MSG_FAN_SPEED_N = _UxGT("Ventilador ~"); - PROGMEM Language_Str MSG_EXTRA_FAN_SPEED = _UxGT("Vel. Ext. ventilador"); - PROGMEM Language_Str MSG_EXTRA_FAN_SPEED_N = _UxGT("Vel. Ext. ventilador ~"); + PROGMEM Language_Str MSG_STORED_FAN_N = _UxGT("Vent. almacenado ~"); + PROGMEM Language_Str MSG_EXTRA_FAN_SPEED = _UxGT("Vel. Ext. ventil."); + PROGMEM Language_Str MSG_EXTRA_FAN_SPEED_N = _UxGT("Vel. Ext. ventil. ~"); + PROGMEM Language_Str MSG_CONTROLLER_FAN = _UxGT("Controlador Vent."); + PROGMEM Language_Str MSG_CONTROLLER_FAN_IDLE_SPEED = _UxGT("Velocidad en reposo"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_AUTO_ON = _UxGT("Modo Auto"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_SPEED = _UxGT("Velocidad Activa"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_DURATION = _UxGT("Periodo de reposo"); PROGMEM Language_Str MSG_FLOW = _UxGT("Flujo"); PROGMEM Language_Str MSG_FLOW_N = _UxGT("Flujo ~"); PROGMEM Language_Str MSG_CONTROL = _UxGT("Control"); PROGMEM Language_Str MSG_MIN = " " LCD_STR_THERMOMETER _UxGT(" Min"); PROGMEM Language_Str MSG_MAX = " " LCD_STR_THERMOMETER _UxGT(" Max"); - PROGMEM Language_Str MSG_FACTOR = " " LCD_STR_THERMOMETER _UxGT(" Fact"); - PROGMEM Language_Str MSG_AUTOTEMP = _UxGT("Temperatura Auto."); - PROGMEM Language_Str MSG_LCD_ON = _UxGT("Encender"); - PROGMEM Language_Str MSG_LCD_OFF = _UxGT("Apagar"); + PROGMEM Language_Str MSG_FACTOR = " " LCD_STR_THERMOMETER _UxGT(" Factor"); + PROGMEM Language_Str MSG_AUTOTEMP = _UxGT("Temp. Autom."); + PROGMEM Language_Str MSG_LCD_ON = _UxGT("Enc"); + PROGMEM Language_Str MSG_LCD_OFF = _UxGT("Apg"); + PROGMEM Language_Str MSG_PID_AUTOTUNE = _UxGT("PID Auto-ajuste"); + PROGMEM Language_Str MSG_PID_AUTOTUNE_E = _UxGT("PID Auto-ajuste *"); + PROGMEM Language_Str MSG_PID_P = _UxGT("PID-P"); + PROGMEM Language_Str MSG_PID_P_E = _UxGT("PID-P *"); + PROGMEM Language_Str MSG_PID_I = _UxGT("PID-I"); + PROGMEM Language_Str MSG_PID_I_E = _UxGT("PID-I *"); + PROGMEM Language_Str MSG_PID_D = _UxGT("PID-D"); + PROGMEM Language_Str MSG_PID_D_E = _UxGT("PID-D *"); + PROGMEM Language_Str MSG_PID_C = _UxGT("PID-C"); + PROGMEM Language_Str MSG_PID_C_E = _UxGT("PID-C *"); + PROGMEM Language_Str MSG_PID_F = _UxGT("PID-F"); + PROGMEM Language_Str MSG_PID_F_E = _UxGT("PID-F *"); PROGMEM Language_Str MSG_SELECT = _UxGT("Seleccionar"); PROGMEM Language_Str MSG_SELECT_E = _UxGT("Seleccionar *"); PROGMEM Language_Str MSG_ACC = _UxGT("Aceleración"); + PROGMEM Language_Str MSG_JERK = _UxGT("Jerk"); + PROGMEM Language_Str MSG_VA_JERK = _UxGT("V") LCD_STR_A _UxGT("-Jerk"); + PROGMEM Language_Str MSG_VB_JERK = _UxGT("V") LCD_STR_B _UxGT("-Jerk"); + PROGMEM Language_Str MSG_VC_JERK = _UxGT("V") LCD_STR_C _UxGT("-Jerk"); + PROGMEM Language_Str MSG_VE_JERK = _UxGT("Ve-Jerk"); + PROGMEM Language_Str MSG_JUNCTION_DEVIATION = _UxGT("Desvi. Unión"); PROGMEM Language_Str MSG_VELOCITY = _UxGT("Velocidad"); + PROGMEM Language_Str MSG_VMAX_A = _UxGT("Vmax ") LCD_STR_A; + PROGMEM Language_Str MSG_VMAX_B = _UxGT("Vmax ") LCD_STR_B; + PROGMEM Language_Str MSG_VMAX_C = _UxGT("Vmax ") LCD_STR_C; + PROGMEM Language_Str MSG_VMAX_E = _UxGT("Vmax ") LCD_STR_E; + PROGMEM Language_Str MSG_VMAX_EN = _UxGT("Vmax *"); + PROGMEM Language_Str MSG_VMIN = _UxGT("Vmin"); PROGMEM Language_Str MSG_VTRAV_MIN = _UxGT("Vel. viaje min"); - PROGMEM Language_Str MSG_ACCELERATION = _UxGT("Accel"); + PROGMEM Language_Str MSG_ACCELERATION = _UxGT("Acceleración"); PROGMEM Language_Str MSG_AMAX_A = _UxGT("Acel. max") LCD_STR_A; PROGMEM Language_Str MSG_AMAX_B = _UxGT("Acel. max") LCD_STR_B; PROGMEM Language_Str MSG_AMAX_C = _UxGT("Acel. max") LCD_STR_C; @@ -275,8 +308,8 @@ namespace Language_es { PROGMEM Language_Str MSG_MOTION = _UxGT("Movimiento"); PROGMEM Language_Str MSG_FILAMENT = _UxGT("Filamento"); PROGMEM Language_Str MSG_VOLUMETRIC_ENABLED = _UxGT("E en mm³"); - PROGMEM Language_Str MSG_FILAMENT_DIAM = _UxGT("Fil. Dia."); - PROGMEM Language_Str MSG_FILAMENT_DIAM_E = _UxGT("Fil. Dia. *"); + PROGMEM Language_Str MSG_FILAMENT_DIAM = _UxGT("Diámetro Fil."); + PROGMEM Language_Str MSG_FILAMENT_DIAM_E = _UxGT("Diámetro Fil. *"); PROGMEM Language_Str MSG_FILAMENT_UNLOAD = _UxGT("Descarga mm"); PROGMEM Language_Str MSG_FILAMENT_LOAD = _UxGT("Carga mm"); PROGMEM Language_Str MSG_ADVANCE_K = _UxGT("Avance K"); @@ -286,6 +319,9 @@ namespace Language_es { PROGMEM Language_Str MSG_LOAD_EEPROM = _UxGT("Cargar EEPROM"); PROGMEM Language_Str MSG_RESTORE_DEFAULTS = _UxGT("Rest. fábrica"); PROGMEM Language_Str MSG_INIT_EEPROM = _UxGT("Inicializar EEPROM"); + PROGMEM Language_Str MSG_ERR_EEPROM_CRC = _UxGT("Err: EEPROM CRC"); + PROGMEM Language_Str MSG_ERR_EEPROM_INDEX = _UxGT("Err: Índice EEPROM"); + PROGMEM Language_Str MSG_ERR_EEPROM_VERSION = _UxGT("Err: Versión EEPROM"); PROGMEM Language_Str MSG_MEDIA_UPDATE = _UxGT("Actualizar SD/USB"); PROGMEM Language_Str MSG_RESET_PRINTER = _UxGT("Resetear Impresora"); PROGMEM Language_Str MSG_REFRESH = LCD_STR_REFRESH _UxGT("Recargar"); @@ -300,10 +336,15 @@ namespace Language_es { PROGMEM Language_Str MSG_BUTTON_RESET = _UxGT("Reiniciar"); PROGMEM Language_Str MSG_BUTTON_CANCEL = _UxGT("Cancelar"); PROGMEM Language_Str MSG_BUTTON_DONE = _UxGT("Listo"); + PROGMEM Language_Str MSG_BUTTON_BACK = _UxGT("Retroceder"); + PROGMEM Language_Str MSG_BUTTON_PROCEED = _UxGT("Proceder"); PROGMEM Language_Str MSG_PAUSE_PRINT = _UxGT("Pausar impresión"); PROGMEM Language_Str MSG_RESUME_PRINT = _UxGT("Reanudar impresión"); PROGMEM Language_Str MSG_STOP_PRINT = _UxGT("Detener impresión"); - PROGMEM Language_Str MSG_OUTAGE_RECOVERY = _UxGT("Recuper. por interr."); + PROGMEM Language_Str MSG_PRINTING_OBJECT = _UxGT("Imprimiendo Objeto"); + PROGMEM Language_Str MSG_CANCEL_OBJECT = _UxGT("Cancelar Objeto"); + PROGMEM Language_Str MSG_CANCEL_OBJECT_N = _UxGT("Cancelar Objeto ="); + PROGMEM Language_Str MSG_OUTAGE_RECOVERY = _UxGT("Rec. Fallo electrico"); PROGMEM Language_Str MSG_MEDIA_MENU = _UxGT("Imprim. desde SD/USB"); PROGMEM Language_Str MSG_NO_MEDIA = _UxGT("SD/USB no presente"); PROGMEM Language_Str MSG_DWELL = _UxGT("Reposo..."); @@ -311,6 +352,7 @@ namespace Language_es { PROGMEM Language_Str MSG_PRINT_PAUSED = _UxGT("Impresión Pausada"); PROGMEM Language_Str MSG_PRINTING = _UxGT("Imprimiendo..."); PROGMEM Language_Str MSG_PRINT_ABORTED = _UxGT("Impresión cancelada"); + PROGMEM Language_Str MSG_PRINT_DONE = _UxGT("Impresión Completada"); PROGMEM Language_Str MSG_NO_MOVE = _UxGT("Sin movimiento"); PROGMEM Language_Str MSG_KILLED = _UxGT("MUERTA"); PROGMEM Language_Str MSG_STOPPED = _UxGT("DETENIDA"); @@ -327,9 +369,8 @@ namespace Language_es { PROGMEM Language_Str MSG_FILAMENT_PURGE_LENGTH = _UxGT("Purgar longitud"); PROGMEM Language_Str MSG_TOOL_CHANGE = _UxGT("Cambiar Herramienta"); PROGMEM Language_Str MSG_TOOL_CHANGE_ZLIFT = _UxGT("Aumentar Z"); - PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPD = _UxGT("Prime Speed"); - PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPD = _UxGT("Vel. de retracción"); - PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("Colocar boquilla"); + PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPEED = _UxGT("Vel. de Cebado"); + PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPEED = _UxGT("Vel. de retracción"); PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("Cambiar filamento"); PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Cambiar filamento *"); PROGMEM Language_Str MSG_FILAMENTLOAD = _UxGT("Cargar filamento"); @@ -343,14 +384,14 @@ namespace Language_es { PROGMEM Language_Str MSG_ZPROBE_OUT = _UxGT("Sonda Z fuera cama"); PROGMEM Language_Str MSG_SKEW_FACTOR = _UxGT("Factor de desviación"); PROGMEM Language_Str MSG_BLTOUCH = _UxGT("BLTouch"); - PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("Cmd: Auto-Prueba"); - PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("Cmd: Reiniciar"); - PROGMEM Language_Str MSG_BLTOUCH_STOW = _UxGT("Cmd: Subir pistón"); - PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("Cmd: Bajar pistón"); - PROGMEM Language_Str MSG_BLTOUCH_SW_MODE = _UxGT("Cmd: Modo Software"); - PROGMEM Language_Str MSG_BLTOUCH_5V_MODE = _UxGT("Cmd: Modo 5V"); - PROGMEM Language_Str MSG_BLTOUCH_OD_MODE = _UxGT("Cmd: Modo OD"); - PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE = _UxGT("Cmd: Modo almacenar"); + PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("Auto-Prueba"); + PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("Reiniciar"); + PROGMEM Language_Str MSG_BLTOUCH_STOW = _UxGT("Subir pistón"); + PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("Bajar pistón"); + PROGMEM Language_Str MSG_BLTOUCH_SW_MODE = _UxGT("Modo Software"); + PROGMEM Language_Str MSG_BLTOUCH_5V_MODE = _UxGT("Modo 5V"); + PROGMEM Language_Str MSG_BLTOUCH_OD_MODE = _UxGT("Modo OD"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE = _UxGT("Modo almacenar"); PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_5V = _UxGT("Poner BLTouch a 5V"); PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_OD = _UxGT("Poner BLTouch a OD"); PROGMEM Language_Str MSG_BLTOUCH_MODE_ECHO = _UxGT("Informe de drenaje"); @@ -362,27 +403,23 @@ namespace Language_es { PROGMEM Language_Str MSG_MANUAL_DEPLOY_TOUCHMI = _UxGT("Subir TouchMI"); PROGMEM Language_Str MSG_MANUAL_DEPLOY = _UxGT("Subir Sonda Z"); PROGMEM Language_Str MSG_MANUAL_STOW = _UxGT("Bajar Sonda Z"); - PROGMEM Language_Str MSG_HOME_FIRST = _UxGT("Origen %s%s%s Primero"); - PROGMEM Language_Str MSG_ZPROBE_ZOFFSET = _UxGT("Desfase Z"); + PROGMEM Language_Str MSG_HOME_FIRST = _UxGT("Origen %s%s%s Prim."); + PROGMEM Language_Str MSG_ZPROBE_OFFSETS = _UxGT("Desf. Sonda"); + PROGMEM Language_Str MSG_ZPROBE_XOFFSET = _UxGT("Desf. Sonda X"); + PROGMEM Language_Str MSG_ZPROBE_YOFFSET = _UxGT("Desf. Sonda Y"); + PROGMEM Language_Str MSG_ZPROBE_ZOFFSET = _UxGT("Desf. Sonda Z"); PROGMEM Language_Str MSG_BABYSTEP_X = _UxGT("Micropaso X"); PROGMEM Language_Str MSG_BABYSTEP_Y = _UxGT("Micropaso Y"); PROGMEM Language_Str MSG_BABYSTEP_Z = _UxGT("Micropaso Z"); PROGMEM Language_Str MSG_BABYSTEP_TOTAL = _UxGT("Total"); PROGMEM Language_Str MSG_ENDSTOP_ABORT = _UxGT("Cancelado - Endstop"); PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("Calent. fallido"); - PROGMEM Language_Str MSG_HEATING_FAILED_LCD_BED = _UxGT("Calent. cama fallido"); - PROGMEM Language_Str MSG_HEATING_FAILED_LCD_CHAMBER = _UxGT("Calent. Cám. fallido"); PROGMEM Language_Str MSG_ERR_REDUNDANT_TEMP = _UxGT("Err: TEMP. REDUN."); PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("FUGA TÉRMICA"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY_BED = _UxGT("FUGA TÉRMICA CAMA"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER = _UxGT("FUGA TÉRMICA CAMARA"); PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("Err:TEMP. MÁX"); PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("Err:TEMP. MIN"); - PROGMEM Language_Str MSG_ERR_MAXTEMP_BED = _UxGT("Err:TEMP. MÁX CAMA"); - PROGMEM Language_Str MSG_ERR_MINTEMP_BED = _UxGT("Err:TEMP. MIN CAMA"); - PROGMEM Language_Str MSG_ERR_MAXTEMP_CHAMBER = _UxGT("Err:TEMP. MÁX CÁMARA"); - PROGMEM Language_Str MSG_ERR_MINTEMP_CHAMBER = _UxGT("Err:TEMP. MIN CÁMARA"); - PROGMEM Language_Str MSG_ERR_Z_HOMING = _UxGT("Origen XY Primero"); PROGMEM Language_Str MSG_HALTED = _UxGT("IMPRESORA DETENIDA"); PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("Por favor, reinicie"); PROGMEM Language_Str MSG_SHORT_DAY = _UxGT("d"); // One character only @@ -406,7 +443,7 @@ namespace Language_es { PROGMEM Language_Str MSG_DELTA_DIAG_ROD = _UxGT("Barra Diagonal"); PROGMEM Language_Str MSG_DELTA_HEIGHT = _UxGT("Altura"); PROGMEM Language_Str MSG_DELTA_RADIUS = _UxGT("Radio"); - PROGMEM Language_Str MSG_INFO_MENU = _UxGT("Acerca de Impresora"); + PROGMEM Language_Str MSG_INFO_MENU = _UxGT("Info. Impresora"); PROGMEM Language_Str MSG_INFO_PRINTER_MENU = _UxGT("Info. Impresora"); PROGMEM Language_Str MSG_3POINT_LEVELING = _UxGT("Nivelando 3puntos"); PROGMEM Language_Str MSG_LINEAR_LEVELING = _UxGT("Nivelando Lineal"); @@ -419,10 +456,12 @@ namespace Language_es { PROGMEM Language_Str MSG_INFO_EXTRUDERS = _UxGT("Extrusores"); PROGMEM Language_Str MSG_INFO_BAUDRATE = _UxGT("Baudios"); PROGMEM Language_Str MSG_INFO_PROTOCOL = _UxGT("Protocolo"); + PROGMEM Language_Str MSG_INFO_RUNAWAY_OFF = _UxGT("Vig. Fuga Térm.: OFF"); + PROGMEM Language_Str MSG_INFO_RUNAWAY_ON = _UxGT("Vig. Fuga Térm.: ON"); + PROGMEM Language_Str MSG_CASE_LIGHT = _UxGT("Luz cabina"); PROGMEM Language_Str MSG_CASE_LIGHT_BRIGHTNESS = _UxGT("Brillo cabina"); - - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("Impresora incorrecta"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("Impresora incorrecta"); #if LCD_WIDTH >= 20 PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Cont. de impresión"); @@ -437,9 +476,10 @@ namespace Language_es { PROGMEM Language_Str MSG_INFO_PRINT_LONGEST = _UxGT("Más larga"); PROGMEM Language_Str MSG_INFO_PRINT_FILAMENT = _UxGT("Extruido"); #endif + PROGMEM Language_Str MSG_INFO_MIN_TEMP = _UxGT("Temp. Mínima"); PROGMEM Language_Str MSG_INFO_MAX_TEMP = _UxGT("Temp. Máxima"); - PROGMEM Language_Str MSG_INFO_PSU = _UxGT("Fuente alimentación"); + PROGMEM Language_Str MSG_INFO_PSU = _UxGT("F. Aliment."); PROGMEM Language_Str MSG_DRIVE_STRENGTH = _UxGT("Fuerza de empuje"); PROGMEM Language_Str MSG_DAC_PERCENT_X = _UxGT("X Driver %"); PROGMEM Language_Str MSG_DAC_PERCENT_Y = _UxGT("Y Driver %"); @@ -455,15 +495,14 @@ namespace Language_es { PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_PURGE = _UxGT("Purgar más"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_RESUME = _UxGT("Continuar imp."); PROGMEM Language_Str MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" Boquilla: "); - PROGMEM Language_Str MSG_RUNOUT_SENSOR = _UxGT("Sensor de sección"); - PROGMEM Language_Str MSG_RUNOUT_DISTANCE_MM = _UxGT("Dist de secc. mm"); - PROGMEM Language_Str MSG_LCD_HOMING_FAILED = _UxGT("Ir a origen Fallado"); + PROGMEM Language_Str MSG_RUNOUT_SENSOR = _UxGT("Sens. filamento"); + PROGMEM Language_Str MSG_RUNOUT_DISTANCE_MM = _UxGT("Dist. filamento mm"); + PROGMEM Language_Str MSG_KILL_HOMING_FAILED = _UxGT("Ir a origen Fallado"); PROGMEM Language_Str MSG_LCD_PROBING_FAILED = _UxGT("Sondeo Fallado"); - PROGMEM Language_Str MSG_M600_TOO_COLD = _UxGT("M600: Muy Frio"); PROGMEM Language_Str MSG_MMU2_CHOOSE_FILAMENT_HEADER = _UxGT("ELIJE FILAMENTO"); PROGMEM Language_Str MSG_MMU2_MENU = _UxGT("MMU"); - PROGMEM Language_Str MSG_MMU2_WRONG_FIRMWARE = _UxGT("¡Actu. MMU Firmware!"); + PROGMEM Language_Str MSG_KILL_MMU2_FIRMWARE = _UxGT("¡Actu. MMU Firmware!"); PROGMEM Language_Str MSG_MMU2_NOT_RESPONDING = _UxGT("MMU Necesita Cuidado"); PROGMEM Language_Str MSG_MMU2_RESUME = _UxGT("Continuar imp."); PROGMEM Language_Str MSG_MMU2_RESUMING = _UxGT("Resumiendo..."); @@ -501,7 +540,7 @@ namespace Language_es { PROGMEM Language_Str MSG_START_Z = _UxGT("Inicio Z:"); PROGMEM Language_Str MSG_END_Z = _UxGT(" Fin Z:"); - PROGMEM Language_Str MSG_GAMES = _UxGT("Games"); + PROGMEM Language_Str MSG_GAMES = _UxGT("Juegos"); PROGMEM Language_Str MSG_BRICKOUT = _UxGT("Brickout"); PROGMEM Language_Str MSG_INVADERS = _UxGT("Invaders"); PROGMEM Language_Str MSG_SNAKE = _UxGT("Sn4k3"); @@ -509,18 +548,19 @@ namespace Language_es { #if LCD_HEIGHT >= 4 PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_2_LINE("Pulsar el botón para", "reanudar impresión")); - PROGMEM Language_Str MSG_PAUSE_PRINT_INIT = _UxGT(MSG_1_LINE("Aparcando...")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Aparcando...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_3_LINE("Esperando para", "iniciar el cambio", "de filamento")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_3_LINE("Inserte el filamento", "y pulse el botón", "para continuar...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_2_LINE("Pulse el botón para", "calentar la boquilla")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEATING = _UxGT(MSG_2_LINE("Calentando boquilla", "Espere por favor...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_2_LINE("Espere para", "liberar el filamento")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_2_LINE("Espere para", "cargar el filamento")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_PURGE = _UxGT(MSG_2_LINE("Espere para", "purgar el filamento")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_CONT_PURGE = _UxGT(MSG_2_LINE("Pulse para finalizar", "la purga de filamen.")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_2_LINE("Esperando impresora", "para reanudar...")); #else PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_1_LINE("Pulse para continuar")); - PROGMEM Language_Str MSG_PAUSE_PRINT_INIT = _UxGT(MSG_1_LINE("Aparcando...")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Aparcando...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_1_LINE("Por Favor espere...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_1_LINE("Inserte y Pulse")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_1_LINE("Pulse para Calentar")); @@ -531,17 +571,24 @@ namespace Language_es { PROGMEM Language_Str MSG_FILAMENT_CHANGE_CONT_PURGE = _UxGT(MSG_1_LINE("Pulse para finalizar")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_1_LINE("Reanudando...")); #endif - PROGMEM Language_Str MSG_TMC_DRIVERS = _UxGT("Controladores TMC"); PROGMEM Language_Str MSG_TMC_CURRENT = _UxGT("Amperaje Controlador"); PROGMEM Language_Str MSG_TMC_HYBRID_THRS = _UxGT("Límite Hibrido"); PROGMEM Language_Str MSG_TMC_HOMING_THRS = _UxGT("Origen sin sensores"); PROGMEM Language_Str MSG_TMC_STEPPING_MODE = _UxGT("Modo de pasos"); PROGMEM Language_Str MSG_TMC_STEALTH_ENABLED = _UxGT("StealthChop Habilit."); - PROGMEM Language_Str MSG_SERVICE_RESET = _UxGT("Reiniciar"); PROGMEM Language_Str MSG_SERVICE_IN = _UxGT(" dentro:"); - - PROGMEM Language_Str MSG_BACKLASH_CORRECTION = _UxGT("Correction"); + PROGMEM Language_Str MSG_BACKLASH = _UxGT("Backlash"); + PROGMEM Language_Str MSG_BACKLASH_A = LCD_STR_A; + PROGMEM Language_Str MSG_BACKLASH_B = LCD_STR_B; + PROGMEM Language_Str MSG_BACKLASH_C = LCD_STR_C; + PROGMEM Language_Str MSG_BACKLASH_CORRECTION = _UxGT("Corrección"); PROGMEM Language_Str MSG_BACKLASH_SMOOTHING = _UxGT("Suavizado"); + + PROGMEM Language_Str MSG_LEVEL_X_AXIS = _UxGT("Nivel Eje X"); + PROGMEM Language_Str MSG_AUTO_CALIBRATE = _UxGT("Auto Calibrar"); + PROGMEM Language_Str MSG_HEATER_TIMEOUT = _UxGT("T. de esp. Calent."); + PROGMEM Language_Str MSG_REHEAT = _UxGT("Recalentar"); + PROGMEM Language_Str MSG_REHEATING = _UxGT("Recalentando..."); } diff --git a/Marlin/src/lcd/language/language_eu.h b/Marlin/src/lcd/language/language_eu.h index a6a0a52518c9..7e35c6ee41ec 100644 --- a/Marlin/src/lcd/language/language_eu.h +++ b/Marlin/src/lcd/language/language_eu.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,8 +25,7 @@ * Basque-Euskera * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ #define DISPLAY_CHARSET_ISO10646_1 @@ -58,20 +57,23 @@ namespace Language_eu { PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Etxe. offset eza."); PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Offsetak ezarrita"); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Hasiera ipini"); - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Berotu ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Berotu ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Berotu ") PREHEAT_1_LABEL _UxGT(" Amaia"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Berotu ") PREHEAT_1_LABEL _UxGT(" Amaia ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Berotu ") PREHEAT_1_LABEL _UxGT(" Guztia"); - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Berotu ") PREHEAT_1_LABEL _UxGT(" Ohea"); - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Berotu ") PREHEAT_1_LABEL _UxGT(" Ezarp."); - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("Berotu ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("Berotu ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("Berotu ") PREHEAT_2_LABEL _UxGT(" Amaia"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("Berotu ") PREHEAT_2_LABEL _UxGT(" Amaia ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("Berotu ") PREHEAT_2_LABEL _UxGT(" Guztia"); - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("Berotu ") PREHEAT_2_LABEL _UxGT(" Ohea"); - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("Berotu ") PREHEAT_2_LABEL _UxGT(" Ezarp."); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Berotu ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Berotu ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Berotu ") PREHEAT_1_LABEL _UxGT(" Amaia"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Berotu ") PREHEAT_1_LABEL _UxGT(" Amaia ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Berotu ") PREHEAT_1_LABEL _UxGT(" Guztia"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Berotu ") PREHEAT_1_LABEL _UxGT(" Ohea"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Berotu ") PREHEAT_1_LABEL _UxGT(" Ezarp."); + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Berotu $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Berotu $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Berotu $ Amaia"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Berotu $ Amaia ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Berotu $ Guztia"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Berotu $ Ohea"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Berotu $ Ezarp."); + #endif PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Hoztu"); PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Energia piztu"); PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("Energia itzali"); @@ -98,13 +100,13 @@ namespace Language_eu { PROGMEM Language_Str MSG_UBL_MESH_EDIT = _UxGT("Sarea editatu"); PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("Sarea editatzea eginda"); PROGMEM Language_Str MSG_UBL_BUILD_MESH_MENU = _UxGT("Sarea sortu"); - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M1 = PREHEAT_1_LABEL _UxGT(" sarea sortu"); - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M2 = PREHEAT_2_LABEL _UxGT(" sarea sortu"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_UBL_BUILD_MESH_M = _UxGT("$ sarea sortu"); + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("$ sarea balioetsi"); + #endif PROGMEM Language_Str MSG_UBL_BUILD_COLD_MESH = _UxGT("Sare hotza sortu"); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_ADJUST = _UxGT("Sarearen altuera doitu"); PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_MENU = _UxGT("Sarea balioetsi"); - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M1 = PREHEAT_1_LABEL _UxGT(" sarea balioetsi"); - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M2 = PREHEAT_2_LABEL _UxGT(" sarea balioetsi"); PROGMEM Language_Str MSG_UBL_CONTINUE_MESH = _UxGT("Ohe sarea balioetsi"); PROGMEM Language_Str MSG_UBL_MESH_LEVELING = _UxGT("Sare berdinketa"); PROGMEM Language_Str MSG_UBL_3POINT_MESH_LEVELING = _UxGT("3 puntuko berdinketa"); @@ -241,9 +243,6 @@ namespace Language_eu { PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("TENP. KONTROL EZA"); PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("Err: Tenp Maximoa"); PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("Err: Tenp Minimoa"); - PROGMEM Language_Str MSG_ERR_MAXTEMP_BED = _UxGT("Err: Ohe Tenp Max"); - PROGMEM Language_Str MSG_ERR_MINTEMP_BED = _UxGT("Err: Ohe Tenp Min"); - PROGMEM Language_Str MSG_ERR_Z_HOMING = _UxGT("Etxera XY lehenengo"); PROGMEM Language_Str MSG_HALTED = _UxGT("INPRIMA. GELDIRIK"); PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("Berrabia. Mesedez"); PROGMEM Language_Str MSG_SHORT_DAY = _UxGT("d"); // One character only @@ -276,8 +275,7 @@ namespace Language_eu { PROGMEM Language_Str MSG_INFO_BAUDRATE = _UxGT("Baudioak"); PROGMEM Language_Str MSG_INFO_PROTOCOL = _UxGT("Protokoloa"); PROGMEM Language_Str MSG_CASE_LIGHT = _UxGT("Kabina Argia"); - PROGMEM Language_Str MSG_CASE_LIGHT_BRIGHTNESS - = ; + PROGMEM Language_Str MSG_CASE_LIGHT_BRIGHTNESS = _UxGT("Argiaren Distira"); #if LCD_WIDTH >= 20 PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Inprim. Zenbaketa"); PROGMEM Language_Str MSG_INFO_COMPLETED_PRINTS = _UxGT("Burututa"); @@ -306,11 +304,10 @@ namespace Language_eu { PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_HEADER = _UxGT("ALDAKETA AUKERAK:"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_RESUME = _UxGT("Inprima. jarraitu"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" Pita: "); - PROGMEM Language_Str MSG_LCD_HOMING_FAILED = _UxGT("Hasi. huts egin du"); + PROGMEM Language_Str MSG_KILL_HOMING_FAILED = _UxGT("Hasi. huts egin du"); PROGMEM Language_Str MSG_LCD_PROBING_FAILED = _UxGT("Neurketak huts egin du"); - PROGMEM Language_Str MSG_M600_TOO_COLD = _UxGT("M600: hotzegi"); - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("Inprimagailu okerra"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("Inprimagailu okerra"); // // Filament Change screens show up to 3 lines on a 4-line display diff --git a/Marlin/src/lcd/language/language_fi.h b/Marlin/src/lcd/language/language_fi.h index 79124c000770..e8621377d966 100644 --- a/Marlin/src/lcd/language/language_fi.h +++ b/Marlin/src/lcd/language/language_fi.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,8 +25,7 @@ * Finnish * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ #define DISPLAY_CHARSET_ISO10646_1 @@ -45,20 +44,23 @@ namespace Language_fi { PROGMEM Language_Str MSG_DISABLE_STEPPERS = _UxGT("Vapauta moottorit"); PROGMEM Language_Str MSG_AUTO_HOME = _UxGT("Aja referenssiin"); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Aseta origo"); - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Esilämmitä ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Esilämmitä ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Esilä. ") PREHEAT_1_LABEL _UxGT("Suutin"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Esilä. ") PREHEAT_1_LABEL _UxGT("Suutin ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Esilä. ") PREHEAT_1_LABEL _UxGT(" Kaikki"); - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Esilä. ") PREHEAT_1_LABEL _UxGT(" Alusta"); - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Esilämm. ") PREHEAT_1_LABEL _UxGT(" konf"); - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("Esilämmitä ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("Esilämmitä ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("Esilä. ") PREHEAT_2_LABEL _UxGT("Suutin"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("Esilä. ") PREHEAT_2_LABEL _UxGT("Suutin ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("Esilä. ") PREHEAT_2_LABEL _UxGT(" Kaikki"); - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("Esilä. ") PREHEAT_2_LABEL _UxGT(" Alusta"); - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("Esilämm. ") PREHEAT_2_LABEL _UxGT(" konf"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Esilämmitä ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Esilämmitä ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Esilä. ") PREHEAT_1_LABEL _UxGT("Suutin"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Esilä. ") PREHEAT_1_LABEL _UxGT("Suutin ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Esilä. ") PREHEAT_1_LABEL _UxGT(" Kaikki"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Esilä. ") PREHEAT_1_LABEL _UxGT(" Alusta"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Esilämm. ") PREHEAT_1_LABEL _UxGT(" konf"); + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Esilämmitä $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Esilämmitä $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Esilä. $Suutin"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Esilä. $Suutin ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Esilä. $ Kaikki"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Esilä. $ Alusta"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Esilämm. $ konf"); + #endif PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Jäähdytä"); PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Virta päälle"); PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("Virta pois"); @@ -114,9 +116,9 @@ namespace Language_fi { PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("Va. Vedä mm"); PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("Vedä V"); PROGMEM Language_Str MSG_CONTROL_RETRACT_ZHOP = _UxGT("Z mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("UnRet mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("Va. UnRet mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("UnRet V"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("Unretr. mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("Va. Unretr. mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("Unretract V"); PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("AutoVeto."); PROGMEM Language_Str MSG_DELTA_CALIBRATE = _UxGT("Delta Kalibrointi"); PROGMEM Language_Str MSG_DELTA_CALIBRATE_X = _UxGT("Kalibroi X"); @@ -124,5 +126,5 @@ namespace Language_fi { PROGMEM Language_Str MSG_DELTA_CALIBRATE_Z = _UxGT("Kalibroi Z"); PROGMEM Language_Str MSG_DELTA_CALIBRATE_CENTER = _UxGT("Kalibroi Center"); - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("Väärä tulostin"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("Väärä tulostin"); } diff --git a/Marlin/src/lcd/language/language_fr.h b/Marlin/src/lcd/language/language_fr.h index ffa12f39fe6d..714feeee9976 100644 --- a/Marlin/src/lcd/language/language_fr.h +++ b/Marlin/src/lcd/language/language_fr.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,8 +25,7 @@ * French * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ #define DISPLAY_CHARSET_ISO10646_1 @@ -44,7 +43,6 @@ namespace Language_fr { PROGMEM Language_Str MSG_MEDIA_ABORTING = _UxGT("Annulation..."); PROGMEM Language_Str MSG_MEDIA_INSERTED = _UxGT("Média inséré"); PROGMEM Language_Str MSG_MEDIA_REMOVED = _UxGT("Média retiré"); - PROGMEM Language_Str MSG_MEDIA_RELEASED = _UxGT("Média libéré"); PROGMEM Language_Str MSG_MEDIA_WAITING = _UxGT("Attente média"); PROGMEM Language_Str MSG_MEDIA_READ_ERROR = _UxGT("Err lecture média"); PROGMEM Language_Str MSG_MEDIA_USB_REMOVED = _UxGT("USB débranché"); @@ -54,7 +52,7 @@ namespace Language_fr { PROGMEM Language_Str MSG_MAIN = _UxGT("Menu principal"); PROGMEM Language_Str MSG_ADVANCED_SETTINGS = _UxGT("Config. avancée"); PROGMEM Language_Str MSG_CONFIGURATION = _UxGT("Configuration"); - PROGMEM Language_Str MSG_AUTOSTART = _UxGT("Exéc. auto#.gcode"); + PROGMEM Language_Str MSG_AUTOSTART = _UxGT("Exéc. auto.gcode"); PROGMEM Language_Str MSG_DISABLE_STEPPERS = _UxGT("Arrêter moteurs"); PROGMEM Language_Str MSG_DEBUG_MENU = _UxGT("Menu debug"); PROGMEM Language_Str MSG_PROGRESS_BAR_TEST = _UxGT("Test barre progress."); @@ -71,20 +69,23 @@ namespace Language_fr { PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Régl. décal origine"); PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Décalages appliqués"); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Régler origine"); - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Préchauffage ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Préchauffage ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Préch. ") PREHEAT_1_LABEL _UxGT(" buse"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Préch. ") PREHEAT_1_LABEL _UxGT(" buse ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Préch. ") PREHEAT_1_LABEL _UxGT(" Tout"); - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Préch. ") PREHEAT_1_LABEL _UxGT(" lit"); - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Régler préch. ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("Préchauffage ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("Préchauffage ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("Préch. ") PREHEAT_2_LABEL _UxGT(" buse"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("Préch. ") PREHEAT_2_LABEL _UxGT(" buse ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("Préch. ") PREHEAT_2_LABEL _UxGT(" Tout"); - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("Préch. ") PREHEAT_2_LABEL _UxGT(" lit"); - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("Régler préch. ") PREHEAT_2_LABEL; + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Préchauffage ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Préchauffage ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Préch. ") PREHEAT_1_LABEL _UxGT(" buse"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Préch. ") PREHEAT_1_LABEL _UxGT(" buse ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Préch. ") PREHEAT_1_LABEL _UxGT(" Tout"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Préch. ") PREHEAT_1_LABEL _UxGT(" lit"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Régler préch. ") PREHEAT_1_LABEL; + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Préchauffage $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Préchauffage $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Préch. $ buse"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Préch. $ buse ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Préch. $ Tout"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Préch. $ lit"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Régler préch. $"); + #endif PROGMEM Language_Str MSG_PREHEAT_CUSTOM = _UxGT("Préchauf. perso"); PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Refroidir"); PROGMEM Language_Str MSG_LASER_MENU = _UxGT("Contrôle Laser"); @@ -93,7 +94,7 @@ namespace Language_fr { PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Allumer alim."); PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("Eteindre alim."); PROGMEM Language_Str MSG_EXTRUDE = _UxGT("Extrusion"); - PROGMEM Language_Str MSG_RETRACT = _UxGT("Rétraction"); + PROGMEM Language_Str MSG_RETRACT = _UxGT("Rétractation"); PROGMEM Language_Str MSG_MOVE_AXIS = _UxGT("Déplacer un axe"); PROGMEM Language_Str MSG_BED_LEVELING = _UxGT("Régler Niv. lit"); PROGMEM Language_Str MSG_LEVEL_BED = _UxGT("Niveau du lit"); @@ -147,15 +148,15 @@ namespace Language_fr { PROGMEM Language_Str MSG_UBL_FINE_TUNE_MESH = _UxGT("Réglage fin"); PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("Terminer"); PROGMEM Language_Str MSG_UBL_BUILD_MESH_MENU = _UxGT("Créer la grille"); - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M1 = _UxGT("Créer grille ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M2 = _UxGT("Créer grille ") PREHEAT_2_LABEL; + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_UBL_BUILD_MESH_M = _UxGT("Créer grille $"); + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("Impr. grille $"); + #endif PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("Créer grille ..."); PROGMEM Language_Str MSG_UBL_BUILD_COLD_MESH = _UxGT("Mesure à froid"); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_ADJUST = _UxGT("Ajuster haut. couche"); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_AMOUNT = _UxGT("Hauteur (x0.1mm)"); PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_MENU = _UxGT("Vérifier grille"); - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M1 = _UxGT("Impr. grille ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M2 = _UxGT("Impr. grille ") PREHEAT_2_LABEL; PROGMEM Language_Str MSG_UBL_VALIDATE_CUSTOM_MESH = _UxGT("Impr. grille ..."); PROGMEM Language_Str MSG_UBL_CONTINUE_MESH = _UxGT("Continuer grille"); PROGMEM Language_Str MSG_UBL_MESH_LEVELING = _UxGT("Niveau par mailles"); @@ -249,6 +250,12 @@ namespace Language_fr { PROGMEM Language_Str MSG_AUTOTEMP = _UxGT("Temp. Auto."); PROGMEM Language_Str MSG_LCD_ON = _UxGT("Marche"); PROGMEM Language_Str MSG_LCD_OFF = _UxGT("Arrêt"); + PROGMEM Language_Str MSG_PID_AUTOTUNE = _UxGT("PID Autotune"); + PROGMEM Language_Str MSG_PID_AUTOTUNE_E = _UxGT("PID Autotune *"); + PROGMEM Language_Str MSG_PID_AUTOTUNE_DONE = _UxGT("Tuning PID terminé"); + PROGMEM Language_Str MSG_PID_BAD_EXTRUDER_NUM = _UxGT("Echec Autotune! E incorrect"); + PROGMEM Language_Str MSG_PID_TEMP_TOO_HIGH = _UxGT("Echec Autotune! Temp. trop haute"); + PROGMEM Language_Str MSG_PID_TIMEOUT = _UxGT("Echec Autotune! Opér. expirée"); PROGMEM Language_Str MSG_SELECT = _UxGT("Sélectionner"); PROGMEM Language_Str MSG_SELECT_E = _UxGT("Sélectionner *"); PROGMEM Language_Str MSG_ACC = _UxGT("Accélération"); @@ -263,6 +270,8 @@ namespace Language_fr { PROGMEM Language_Str MSG_ACCELERATION = _UxGT("Accélération"); PROGMEM Language_Str MSG_A_RETRACT = _UxGT("Acc.rétraction"); PROGMEM Language_Str MSG_A_TRAVEL = _UxGT("Acc.course"); + PROGMEM Language_Str MSG_XY_FREQUENCY_LIMIT = _UxGT("Fréquence max"); + PROGMEM Language_Str MSG_XY_FREQUENCY_FEEDRATE = _UxGT("Vitesse min"); PROGMEM Language_Str MSG_STEPS_PER_MM = _UxGT("Pas/mm"); PROGMEM Language_Str MSG_A_STEPS = LCD_STR_A _UxGT(" pas/mm"); PROGMEM Language_Str MSG_B_STEPS = LCD_STR_B _UxGT(" pas/mm"); @@ -273,6 +282,8 @@ namespace Language_fr { PROGMEM Language_Str MSG_MOTION = _UxGT("Mouvement"); PROGMEM Language_Str MSG_FILAMENT = _UxGT("Filament"); PROGMEM Language_Str MSG_VOLUMETRIC_ENABLED = _UxGT("E en mm³"); + PROGMEM Language_Str MSG_VOLUMETRIC_LIMIT = _UxGT("Limite en mm³"); + PROGMEM Language_Str MSG_VOLUMETRIC_LIMIT_E = _UxGT("Limite *"); PROGMEM Language_Str MSG_FILAMENT_DIAM = _UxGT("Diamètre fil."); PROGMEM Language_Str MSG_FILAMENT_DIAM_E = _UxGT("Diamètre fil. *"); PROGMEM Language_Str MSG_FILAMENT_UNLOAD = _UxGT("Retrait mm"); @@ -284,6 +295,7 @@ namespace Language_fr { PROGMEM Language_Str MSG_LOAD_EEPROM = _UxGT("Charger config."); PROGMEM Language_Str MSG_RESTORE_DEFAULTS = _UxGT("Restaurer défauts"); PROGMEM Language_Str MSG_INIT_EEPROM = _UxGT("Initialiser EEPROM"); + PROGMEM Language_Str MSG_SETTINGS_STORED = _UxGT("Config. enregistrée"); PROGMEM Language_Str MSG_MEDIA_UPDATE = _UxGT("MaJ Firmware SD"); PROGMEM Language_Str MSG_RESET_PRINTER = _UxGT("RaZ imprimante"); PROGMEM Language_Str MSG_REFRESH = LCD_STR_REFRESH _UxGT("Actualiser"); @@ -296,10 +308,12 @@ namespace Language_fr { PROGMEM Language_Str MSG_BUTTON_STOP = _UxGT("Stop"); PROGMEM Language_Str MSG_BUTTON_PRINT = _UxGT("Imprimer"); PROGMEM Language_Str MSG_BUTTON_RESET = _UxGT("Reset"); + PROGMEM Language_Str MSG_BUTTON_IGNORE = _UxGT("Ignorer"); PROGMEM Language_Str MSG_BUTTON_CANCEL = _UxGT("Annuler"); PROGMEM Language_Str MSG_BUTTON_DONE = _UxGT("Terminé"); PROGMEM Language_Str MSG_BUTTON_BACK = _UxGT("Retour"); PROGMEM Language_Str MSG_BUTTON_PROCEED = _UxGT("Procéder"); + PROGMEM Language_Str MSG_PAUSING = _UxGT("Mise en pause..."); PROGMEM Language_Str MSG_PAUSE_PRINT = _UxGT("Pause impression"); PROGMEM Language_Str MSG_RESUME_PRINT = _UxGT("Reprendre impr."); PROGMEM Language_Str MSG_STOP_PRINT = _UxGT("Arrêter impr."); @@ -317,7 +331,7 @@ namespace Language_fr { PROGMEM Language_Str MSG_NO_MOVE = _UxGT("Moteurs bloqués"); PROGMEM Language_Str MSG_KILLED = _UxGT("KILLED"); PROGMEM Language_Str MSG_STOPPED = _UxGT("STOPPÉ"); - PROGMEM Language_Str MSG_CONTROL_RETRACT = _UxGT("Rétraction mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT = _UxGT("Rétractation mm"); PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("Ech. rétr. mm"); PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("Vit. rétract°"); PROGMEM Language_Str MSG_CONTROL_RETRACT_ZHOP = _UxGT("Saut Z mm"); @@ -328,10 +342,21 @@ namespace Language_fr { PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("Rétraction auto"); PROGMEM Language_Str MSG_TOOL_CHANGE = _UxGT("Changement outil"); PROGMEM Language_Str MSG_TOOL_CHANGE_ZLIFT = _UxGT("Augmenter Z"); - PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPD = _UxGT("Vitesse primaire"); - PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPD = _UxGT("Vitesse rétract°"); + PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPEED = _UxGT("Vitesse primaire"); + PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPEED = _UxGT("Vitesse rétract°"); + PROGMEM Language_Str MSG_FILAMENT_PARK_ENABLED = _UxGT("Garer Extrudeur"); + PROGMEM Language_Str MSG_SINGLENOZZLE_UNRETRACT_SPEED = _UxGT("Vitesse reprise"); + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_SPEED = _UxGT("Vit. ventil."); + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_TIME = _UxGT("Temps ventil."); + PROGMEM Language_Str MSG_TOOL_MIGRATION_ON = _UxGT("Auto ON"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_OFF = _UxGT("Auto OFF"); + PROGMEM Language_Str MSG_TOOL_MIGRATION = _UxGT("Migration d'outil"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_AUTO = _UxGT("Migration auto"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_END = _UxGT("Extrudeur Final"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_SWAP = _UxGT("Migrer vers *"); PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("Attente buse"); PROGMEM Language_Str MSG_FILAMENT_SWAP_LENGTH = _UxGT("Longueur retrait"); + PROGMEM Language_Str MSG_FILAMENT_SWAP_EXTRA = _UxGT("Longueur Extra"); PROGMEM Language_Str MSG_FILAMENT_PURGE_LENGTH = _UxGT("Longueur de purge"); PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("Changer filament"); PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Changer filament *"); @@ -346,13 +371,13 @@ namespace Language_fr { PROGMEM Language_Str MSG_ZPROBE_OUT = _UxGT("Sonde Z hors lit"); PROGMEM Language_Str MSG_SKEW_FACTOR = _UxGT("Facteur écart"); PROGMEM Language_Str MSG_BLTOUCH = _UxGT("BLTouch"); - PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("Cmd: Self-Test"); - PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("Cmd: Reset"); - PROGMEM Language_Str MSG_BLTOUCH_STOW = _UxGT("Cmd: Ranger"); - PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("Cmd: Déployer"); - PROGMEM Language_Str MSG_BLTOUCH_SW_MODE = _UxGT("Cmd: Mode SW"); - PROGMEM Language_Str MSG_BLTOUCH_5V_MODE = _UxGT("Cmd: Mode 5V"); - PROGMEM Language_Str MSG_BLTOUCH_OD_MODE = _UxGT("Cmd: Mode OD"); + PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("Self-Test"); + PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("Reset"); + PROGMEM Language_Str MSG_BLTOUCH_STOW = _UxGT("Ranger"); + PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("Déployer"); + PROGMEM Language_Str MSG_BLTOUCH_SW_MODE = _UxGT("Mode SW"); + PROGMEM Language_Str MSG_BLTOUCH_5V_MODE = _UxGT("Mode 5V"); + PROGMEM Language_Str MSG_BLTOUCH_OD_MODE = _UxGT("Mode OD"); PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE = _UxGT("Appliquer Mode"); PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_5V = _UxGT("Mise en 5V"); PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_OD = _UxGT("Mise en OD"); @@ -376,7 +401,6 @@ namespace Language_fr { PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("Err THERMIQUE"); PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("Err TEMP. MAX"); PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("Err TEMP. MIN"); - PROGMEM Language_Str MSG_ERR_Z_HOMING = _UxGT("Origine XY Premier"); PROGMEM Language_Str MSG_HALTED = _UxGT("IMPR. STOPPÉE"); PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("Redémarrer SVP"); @@ -388,6 +412,8 @@ namespace Language_fr { PROGMEM Language_Str MSG_COOLING = _UxGT("Refroidissement"); PROGMEM Language_Str MSG_BED_HEATING = _UxGT("Lit en chauffe..."); PROGMEM Language_Str MSG_BED_COOLING = _UxGT("Refroid. du lit..."); + PROGMEM Language_Str MSG_PROBE_HEATING = _UxGT("Probe en chauffe..."); + PROGMEM Language_Str MSG_PROBE_COOLING = _UxGT("Refroid. Probe..."); PROGMEM Language_Str MSG_CHAMBER_HEATING = _UxGT("Chauffe caisson..."); PROGMEM Language_Str MSG_CHAMBER_COOLING = _UxGT("Refroid. caisson..."); PROGMEM Language_Str MSG_DELTA_CALIBRATE = _UxGT("Calibration Delta"); @@ -418,11 +444,11 @@ namespace Language_fr { PROGMEM Language_Str MSG_INFO_PROTOCOL = _UxGT("Protocole"); PROGMEM Language_Str MSG_INFO_RUNAWAY_OFF = _UxGT("Protection inactive"); PROGMEM Language_Str MSG_INFO_RUNAWAY_ON = _UxGT("Protection active"); + PROGMEM Language_Str MSG_HOTEND_IDLE_TIMEOUT = _UxGT("Hotend Idle Timeout"); PROGMEM Language_Str MSG_CASE_LIGHT = _UxGT("Lumière caisson"); PROGMEM Language_Str MSG_CASE_LIGHT_BRIGHTNESS = _UxGT("Luminosité"); - - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("Imprimante incorrecte"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("Imprimante incorrecte"); #if LCD_WIDTH >= 20 PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Nbre impressions"); @@ -458,19 +484,19 @@ namespace Language_fr { PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_RESUME = _UxGT("Reprendre impr."); PROGMEM Language_Str MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" Buse: "); PROGMEM Language_Str MSG_RUNOUT_SENSOR = _UxGT("Capteur fil."); - PROGMEM Language_Str MSG_LCD_HOMING_FAILED = _UxGT("Echec origine"); + PROGMEM Language_Str MSG_KILL_HOMING_FAILED = _UxGT("Echec origine"); PROGMEM Language_Str MSG_LCD_PROBING_FAILED = _UxGT("Echec sonde"); - PROGMEM Language_Str MSG_M600_TOO_COLD = _UxGT("M600: Trop froid"); + PROGMEM Language_Str MSG_KILL_MMU2_FIRMWARE = _UxGT("MAJ firmware MMU!!"); PROGMEM Language_Str MSG_MMU2_CHOOSE_FILAMENT_HEADER = _UxGT("CHOISIR FILAMENT"); PROGMEM Language_Str MSG_MMU2_MENU = _UxGT("MMU"); PROGMEM Language_Str MSG_MMU2_NOT_RESPONDING = _UxGT("MMU ne répond plus"); - PROGMEM Language_Str MSG_MMU2_RESUME = _UxGT("Continuer impr."); - PROGMEM Language_Str MSG_MMU2_RESUMING = _UxGT("Reprise..."); - PROGMEM Language_Str MSG_MMU2_LOAD_FILAMENT = _UxGT("Charger filament"); - PROGMEM Language_Str MSG_MMU2_LOAD_ALL = _UxGT("Charger tous"); + PROGMEM Language_Str MSG_MMU2_RESUME = _UxGT("Continuer Imp. MMU"); + PROGMEM Language_Str MSG_MMU2_RESUMING = _UxGT("Reprise MMU..."); + PROGMEM Language_Str MSG_MMU2_LOAD_FILAMENT = _UxGT("Charge dans MMU"); + PROGMEM Language_Str MSG_MMU2_LOAD_ALL = _UxGT("Charger tous dans MMU"); PROGMEM Language_Str MSG_MMU2_LOAD_TO_NOZZLE = _UxGT("Charger dans buse"); - PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT = _UxGT("Ejecter filament"); + PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT = _UxGT("Ejecter fil. du MMU"); PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT_N = _UxGT("Ejecter fil. ~"); PROGMEM Language_Str MSG_MMU2_UNLOAD_FILAMENT = _UxGT("Retrait filament"); PROGMEM Language_Str MSG_MMU2_LOADING_FILAMENT = _UxGT("Chargem. fil. %i..."); @@ -482,7 +508,7 @@ namespace Language_fr { PROGMEM Language_Str MSG_MMU2_RESETTING = _UxGT("Réinit. MMU..."); PROGMEM Language_Str MSG_MMU2_EJECT_RECOVER = _UxGT("Retrait, click"); - PROGMEM Language_Str MSG_MIX_COMPONENT_N = _UxGT("Composante ~"); + PROGMEM Language_Str MSG_MIX_COMPONENT_N = _UxGT("Composante ="); PROGMEM Language_Str MSG_MIXER = _UxGT("Mixeur"); PROGMEM Language_Str MSG_GRADIENT = _UxGT("Dégradé"); PROGMEM Language_Str MSG_FULL_GRADIENT = _UxGT("Dégradé complet"); @@ -505,10 +531,13 @@ namespace Language_fr { PROGMEM Language_Str MSG_SNAKE = _UxGT("Sn4k3"); PROGMEM Language_Str MSG_MAZE = _UxGT("Labyrinthe"); + PROGMEM Language_Str MSG_BAD_PAGE = _UxGT("Erreur index page"); + PROGMEM Language_Str MSG_BAD_PAGE_SPEED = _UxGT("Erreur vitesse page"); + #if LCD_HEIGHT >= 4 // Up to 3 lines allowed PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_2_LINE("Presser bouton", "pour reprendre")); - PROGMEM Language_Str MSG_PAUSE_PRINT_INIT = _UxGT(MSG_1_LINE("Parking...")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Parking...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_2_LINE("Attente filament", "pour démarrer")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_3_LINE("Insérer filament", "et app. bouton", "pour continuer...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_2_LINE("Presser le bouton", "pour chauffer...")); diff --git a/Marlin/src/lcd/language/language_gl.h b/Marlin/src/lcd/language/language_gl.h index 6a8f166ff19c..2fd4bf69758a 100644 --- a/Marlin/src/lcd/language/language_gl.h +++ b/Marlin/src/lcd/language/language_gl.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,12 +25,10 @@ * Galician language (ISO "gl") * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ #define DISPLAY_CHARSET_ISO10646_1 -#define NOT_EXTENDED_ISO10646_1_5X7 namespace Language_gl { using namespace Language_en; // Inherit undefined strings from English @@ -39,50 +37,202 @@ namespace Language_gl { PROGMEM Language_Str LANGUAGE = _UxGT("Galician"); PROGMEM Language_Str WELCOME_MSG = MACHINE_NAME _UxGT(" lista."); + PROGMEM Language_Str MSG_MARLIN = _UxGT("Marlin"); + PROGMEM Language_Str MSG_YES = _UxGT("SI"); + PROGMEM Language_Str MSG_NO = _UxGT("NON"); + PROGMEM Language_Str MSG_BACK = _UxGT("Atrás"); + PROGMEM Language_Str MSG_MEDIA_ABORTING = _UxGT("Cancelando..."); PROGMEM Language_Str MSG_MEDIA_INSERTED = _UxGT("Tarxeta inserida"); PROGMEM Language_Str MSG_MEDIA_REMOVED = _UxGT("Tarxeta retirada"); + PROGMEM Language_Str MSG_MEDIA_WAITING = _UxGT("Agardando ao SD/USB"); + PROGMEM Language_Str MSG_MEDIA_READ_ERROR = _UxGT("Erro lectura SD/USB"); + PROGMEM Language_Str MSG_MEDIA_USB_REMOVED = _UxGT("Disp. USB retirado"); + PROGMEM Language_Str MSG_MEDIA_USB_FAILED = _UxGT("Inicio USB fallido"); + PROGMEM Language_Str MSG_KILL_SUBCALL_OVERFLOW = _UxGT("Desbord. Subch."); PROGMEM Language_Str MSG_LCD_ENDSTOPS = _UxGT("FinCarro"); - PROGMEM Language_Str MSG_MAIN = _UxGT("Menu principal"); + PROGMEM Language_Str MSG_LCD_SOFT_ENDSTOPS = _UxGT("FinCarro SW"); + PROGMEM Language_Str MSG_MAIN = _UxGT("Menú principal"); + PROGMEM Language_Str MSG_ADVANCED_SETTINGS = _UxGT("Axustes avanzados"); + PROGMEM Language_Str MSG_CONFIGURATION = _UxGT("Configuración"); PROGMEM Language_Str MSG_AUTOSTART = _UxGT("Autoarranque"); PROGMEM Language_Str MSG_DISABLE_STEPPERS = _UxGT("Apagar motores"); + PROGMEM Language_Str MSG_DEBUG_MENU = _UxGT("Menú depuración"); + PROGMEM Language_Str MSG_PROGRESS_BAR_TEST = _UxGT("Test barra progreso"); PROGMEM Language_Str MSG_AUTO_HOME = _UxGT("Ir a orixe"); PROGMEM Language_Str MSG_AUTO_HOME_X = _UxGT("Ir orixe X"); PROGMEM Language_Str MSG_AUTO_HOME_Y = _UxGT("Ir orixe Y"); PROGMEM Language_Str MSG_AUTO_HOME_Z = _UxGT("Ir orixe Z"); + PROGMEM Language_Str MSG_AUTO_Z_ALIGN = _UxGT("Autoaliñar Z"); PROGMEM Language_Str MSG_LEVEL_BED_HOMING = _UxGT("Ir orixes XYZ"); PROGMEM Language_Str MSG_LEVEL_BED_WAITING = _UxGT("Prema pulsador"); PROGMEM Language_Str MSG_LEVEL_BED_NEXT_POINT = _UxGT("Seguinte punto"); - PROGMEM Language_Str MSG_LEVEL_BED_DONE = _UxGT("Nivelado feito"); - PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Offsets na orixe"); - PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Offsets fixados"); + PROGMEM Language_Str MSG_LEVEL_BED_DONE = _UxGT("Fin Nivelación!"); + PROGMEM Language_Str MSG_Z_FADE_HEIGHT = _UxGT("Compensación Altura"); + PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Axustar Desfases"); + PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Desfases aplicados"); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Fixar orixe"); - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Prequentar ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Prequentar ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Preque. ") PREHEAT_1_LABEL _UxGT(" Bico"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Preque. ") PREHEAT_1_LABEL _UxGT(" Bico ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Preque. ") PREHEAT_1_LABEL _UxGT(" Todo"); - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Preque. ") PREHEAT_1_LABEL _UxGT(" Cama"); - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Preque. ") PREHEAT_1_LABEL _UxGT(" conf"); - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("Prequentar ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("Prequentar ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("Preque. ") PREHEAT_2_LABEL _UxGT(" Bico"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("Preque. ") PREHEAT_2_LABEL _UxGT(" Bico ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("Preque. ") PREHEAT_2_LABEL _UxGT(" Todo"); - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("Preque. ") PREHEAT_2_LABEL _UxGT(" Cama"); - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("Preque. ") PREHEAT_2_LABEL _UxGT(" conf"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Prequentar ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Prequentar ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Preque. ") PREHEAT_1_LABEL _UxGT(" Bico"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Preque. ") PREHEAT_1_LABEL _UxGT(" Bico ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Preque. ") PREHEAT_1_LABEL _UxGT(" Todo"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Preque. ") PREHEAT_1_LABEL _UxGT(" Cama"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Preque. ") PREHEAT_1_LABEL _UxGT(" conf"); + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Prequentar $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Prequentar $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Preque. $ Bico"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Preque. $ Bico ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Preque. $ Todo"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Preque. $ Cama"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Preque. $ conf"); + #endif + PROGMEM Language_Str MSG_PREHEAT_CUSTOM = _UxGT("Preque. Personali."); PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Arrefriar"); + PROGMEM Language_Str MSG_CUTTER_FREQUENCY = _UxGT("Frecuencia"); + PROGMEM Language_Str MSG_LASER_MENU = _UxGT("Control Láser"); + PROGMEM Language_Str MSG_LASER_OFF = _UxGT("Láser Apagado"); + PROGMEM Language_Str MSG_LASER_ON = _UxGT("Láser Aceso"); + PROGMEM Language_Str MSG_LASER_POWER = _UxGT("Potencia Láser"); + PROGMEM Language_Str MSG_SPINDLE_MENU = _UxGT("Control Fuso"); + PROGMEM Language_Str MSG_SPINDLE_OFF = _UxGT("Fuso Apagado"); + PROGMEM Language_Str MSG_SPINDLE_ON = _UxGT("Fuso Aceso"); + PROGMEM Language_Str MSG_SPINDLE_POWER = _UxGT("Potencia Fuso"); + PROGMEM Language_Str MSG_SPINDLE_REVERSE = _UxGT("Inverter xiro"); PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Acender"); PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("Apagar"); - PROGMEM Language_Str MSG_EXTRUDE = _UxGT("Extrudir"); + PROGMEM Language_Str MSG_EXTRUDE = _UxGT("Extruír"); PROGMEM Language_Str MSG_RETRACT = _UxGT("Retraer"); PROGMEM Language_Str MSG_MOVE_AXIS = _UxGT("Mover eixe"); - PROGMEM Language_Str MSG_BED_LEVELING = _UxGT("Nivelar cama"); - PROGMEM Language_Str MSG_LEVEL_BED = _UxGT("Nivelar cama"); + PROGMEM Language_Str MSG_BED_LEVELING = _UxGT("Nivelando Cama"); + PROGMEM Language_Str MSG_LEVEL_BED = _UxGT("Nivelar Cama"); + PROGMEM Language_Str MSG_LEVEL_CORNERS = _UxGT("Nivelar Cantos"); + PROGMEM Language_Str MSG_NEXT_CORNER = _UxGT("Seguinte Canto"); + PROGMEM Language_Str MSG_MESH_EDITOR = _UxGT("Editor Mallado"); + PROGMEM Language_Str MSG_EDIT_MESH = _UxGT("Editar Mallado"); + PROGMEM Language_Str MSG_EDITING_STOPPED = _UxGT("Ed. Mallado Detida"); + PROGMEM Language_Str MSG_PROBING_MESH = _UxGT("Punto de Proba"); + PROGMEM Language_Str MSG_MESH_X = _UxGT("Índice X"); + PROGMEM Language_Str MSG_MESH_Y = _UxGT("Índice Y"); + PROGMEM Language_Str MSG_MESH_EDIT_Z = _UxGT("Valor Z"); + PROGMEM Language_Str MSG_USER_MENU = _UxGT("Comandos Personaliz."); + PROGMEM Language_Str MSG_M48_TEST = _UxGT("M48 Probar Sonda"); + PROGMEM Language_Str MSG_M48_POINT = _UxGT("M48 Punto"); + PROGMEM Language_Str MSG_M48_DEVIATION = _UxGT("Desviación"); + PROGMEM Language_Str MSG_IDEX_MENU = _UxGT("Modo IDEX"); + PROGMEM Language_Str MSG_OFFSETS_MENU = _UxGT("Ferramentas Compens"); + PROGMEM Language_Str MSG_IDEX_MODE_AUTOPARK = _UxGT("Auto-Estacionar"); + PROGMEM Language_Str MSG_IDEX_MODE_DUPLICATE = _UxGT("Duplicación"); + PROGMEM Language_Str MSG_IDEX_MODE_MIRRORED_COPY = _UxGT("Copia Espello"); + PROGMEM Language_Str MSG_IDEX_MODE_FULL_CTRL = _UxGT("Control Total"); + PROGMEM Language_Str MSG_HOTEND_OFFSET_X = _UxGT("2º Bico X"); + PROGMEM Language_Str MSG_HOTEND_OFFSET_Y = _UxGT("2º Bico Y"); + PROGMEM Language_Str MSG_HOTEND_OFFSET_Z = _UxGT("2º Bico Z"); + PROGMEM Language_Str MSG_UBL_DOING_G29 = _UxGT("Executando G29"); + PROGMEM Language_Str MSG_UBL_TOOLS = _UxGT("Ferramentas UBL"); + PROGMEM Language_Str MSG_UBL_LEVEL_BED = _UxGT("Unified Bed Leveling"); + PROGMEM Language_Str MSG_LCD_TILTING_MESH = _UxGT("Punto de inclinación"); + PROGMEM Language_Str MSG_UBL_MANUAL_MESH = _UxGT("Facer Malla Manual"); + PROGMEM Language_Str MSG_UBL_BC_INSERT = _UxGT("Colocar Calzo e Medir"); + PROGMEM Language_Str MSG_UBL_BC_INSERT2 = _UxGT("Medir"); + PROGMEM Language_Str MSG_UBL_BC_REMOVE = _UxGT("Quitar e Medir Cama"); + PROGMEM Language_Str MSG_UBL_MOVING_TO_NEXT = _UxGT("Mover ao Seguinte"); + PROGMEM Language_Str MSG_UBL_ACTIVATE_MESH = _UxGT("Activar UBL"); + PROGMEM Language_Str MSG_UBL_DEACTIVATE_MESH = _UxGT("Desactivar UBL"); + PROGMEM Language_Str MSG_UBL_SET_TEMP_BED = _UxGT("Temp Cama"); + PROGMEM Language_Str MSG_UBL_BED_TEMP_CUSTOM = _UxGT("Temp Cama"); + PROGMEM Language_Str MSG_UBL_SET_TEMP_HOTEND = _UxGT("Temp Bico"); + PROGMEM Language_Str MSG_UBL_HOTEND_TEMP_CUSTOM = _UxGT("Temp Bico"); + PROGMEM Language_Str MSG_UBL_MESH_EDIT = _UxGT("Editar Malla"); + PROGMEM Language_Str MSG_UBL_EDIT_CUSTOM_MESH = _UxGT("Edit. Malla Person."); + PROGMEM Language_Str MSG_UBL_FINE_TUNE_MESH = _UxGT("Axuste Fino da Malla"); + PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("Fin Edición da Malla"); + PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("Crear Malla Person."); + PROGMEM Language_Str MSG_UBL_BUILD_MESH_MENU = _UxGT("Crear Malla"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_UBL_BUILD_MESH_M = _UxGT("Crear Malla ($)"); + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("Validar Malla ($)"); + #endif + PROGMEM Language_Str MSG_UBL_BUILD_COLD_MESH = _UxGT("Crear Malla Fría"); + PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_ADJUST = _UxGT("Axustar Altura Malla"); + PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_AMOUNT = _UxGT("Altura"); + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_MENU = _UxGT("Validar Malla"); + PROGMEM Language_Str MSG_UBL_VALIDATE_CUSTOM_MESH = _UxGT("Validar Malla perso."); + PROGMEM Language_Str MSG_G26_HEATING_BED = _UxGT("G26 Quentando Cama"); + PROGMEM Language_Str MSG_G26_HEATING_NOZZLE = _UxGT("G26 Quentando Bico"); + PROGMEM Language_Str MSG_G26_MANUAL_PRIME = _UxGT("Traballo manual..."); + PROGMEM Language_Str MSG_G26_FIXED_LENGTH = _UxGT("Traballo Lonxit Fixa"); + PROGMEM Language_Str MSG_G26_PRIME_DONE = _UxGT("Fin Traballo"); + PROGMEM Language_Str MSG_G26_CANCELED = _UxGT("G26 Cancelado"); + PROGMEM Language_Str MSG_G26_LEAVING = _UxGT("Saíndo de G26"); + PROGMEM Language_Str MSG_UBL_CONTINUE_MESH = _UxGT("Continuar Malla"); + PROGMEM Language_Str MSG_UBL_MESH_LEVELING = _UxGT("Nivelación Malla"); + PROGMEM Language_Str MSG_UBL_3POINT_MESH_LEVELING = _UxGT("Nivelación 3Puntos"); + PROGMEM Language_Str MSG_UBL_GRID_MESH_LEVELING = _UxGT("Nivelación Grid"); + PROGMEM Language_Str MSG_UBL_MESH_LEVEL = _UxGT("Nivelar Malla"); + PROGMEM Language_Str MSG_UBL_SIDE_POINTS = _UxGT("Puntos Laterais"); + PROGMEM Language_Str MSG_UBL_MAP_TYPE = _UxGT("Tipo de Mapa "); + PROGMEM Language_Str MSG_UBL_OUTPUT_MAP = _UxGT("Gardar Mapa"); + PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_HOST = _UxGT("Enviar ao Host"); + PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_CSV = _UxGT("Gardar en CSV"); + PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_BACKUP = _UxGT("Backup Externo"); + PROGMEM Language_Str MSG_UBL_INFO_UBL = _UxGT("Info do UBL"); + PROGMEM Language_Str MSG_UBL_FILLIN_AMOUNT = _UxGT("Cantidade de Recheo"); + PROGMEM Language_Str MSG_UBL_MANUAL_FILLIN = _UxGT("Recheo Manual"); + PROGMEM Language_Str MSG_UBL_SMART_FILLIN = _UxGT("Recheo Intelixente"); + PROGMEM Language_Str MSG_UBL_FILLIN_MESH = _UxGT("Recheo da Malla"); + PROGMEM Language_Str MSG_UBL_INVALIDATE_ALL = _UxGT("Invalidar todo"); + PROGMEM Language_Str MSG_UBL_INVALIDATE_CLOSEST = _UxGT("Invalidar cercanos"); + PROGMEM Language_Str MSG_UBL_FINE_TUNE_ALL = _UxGT("Axustar Fino Todo"); + PROGMEM Language_Str MSG_UBL_FINE_TUNE_CLOSEST = _UxGT("Axustar Fino Cerc"); + PROGMEM Language_Str MSG_UBL_STORAGE_MESH_MENU = _UxGT("Almacenamento Malla"); + PROGMEM Language_Str MSG_UBL_STORAGE_SLOT = _UxGT("Rañura Memoria"); + PROGMEM Language_Str MSG_UBL_LOAD_MESH = _UxGT("Cargar Malla Cama"); + PROGMEM Language_Str MSG_UBL_SAVE_MESH = _UxGT("Gardar Malla Cama"); + PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("Malla %i Cargada"); + PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("Malla %i Gardada"); + PROGMEM Language_Str MSG_UBL_NO_STORAGE = _UxGT("Sen Gardar"); + PROGMEM Language_Str MSG_UBL_SAVE_ERROR = _UxGT("Erro: Gardadado UBL"); + PROGMEM Language_Str MSG_UBL_RESTORE_ERROR = _UxGT("Erro: Recuperación UBL"); + PROGMEM Language_Str MSG_UBL_Z_OFFSET = _UxGT("Desfase de Z: "); + PROGMEM Language_Str MSG_UBL_Z_OFFSET_STOPPED = _UxGT("Desfase de Z Detido"); + PROGMEM Language_Str MSG_UBL_STEP_BY_STEP_MENU = _UxGT("UBL Paso a Paso"); + PROGMEM Language_Str MSG_UBL_1_BUILD_COLD_MESH = _UxGT("1. Crear Malla Fría"); + PROGMEM Language_Str MSG_UBL_2_SMART_FILLIN = _UxGT("2. Recheo Intelixente"); + PROGMEM Language_Str MSG_UBL_3_VALIDATE_MESH_MENU = _UxGT("3. Validar Malla"); + PROGMEM Language_Str MSG_UBL_4_FINE_TUNE_ALL = _UxGT("4. Axustar Fino Todo"); + PROGMEM Language_Str MSG_UBL_5_VALIDATE_MESH_MENU = _UxGT("5. Validar Malla"); + PROGMEM Language_Str MSG_UBL_6_FINE_TUNE_ALL = _UxGT("6. Axustar Fino Todo"); + PROGMEM Language_Str MSG_UBL_7_SAVE_MESH = _UxGT("7. Gardar Malla Cama"); + + PROGMEM Language_Str MSG_LED_CONTROL = _UxGT("Control LED"); + PROGMEM Language_Str MSG_LEDS = _UxGT("Luces"); + PROGMEM Language_Str MSG_LED_PRESETS = _UxGT("Axustes Luz"); + PROGMEM Language_Str MSG_SET_LEDS_RED = _UxGT("Vermello"); + PROGMEM Language_Str MSG_SET_LEDS_ORANGE = _UxGT("Laranxa"); + PROGMEM Language_Str MSG_SET_LEDS_YELLOW = _UxGT("Amarelo"); + PROGMEM Language_Str MSG_SET_LEDS_GREEN = _UxGT("Verde"); + PROGMEM Language_Str MSG_SET_LEDS_BLUE = _UxGT("Azul"); + PROGMEM Language_Str MSG_SET_LEDS_INDIGO = _UxGT("Índigo"); + PROGMEM Language_Str MSG_SET_LEDS_VIOLET = _UxGT("Violeta"); + PROGMEM Language_Str MSG_SET_LEDS_WHITE = _UxGT("Branco"); + PROGMEM Language_Str MSG_SET_LEDS_DEFAULT = _UxGT("Por defecto"); + PROGMEM Language_Str MSG_CUSTOM_LEDS = _UxGT("Luces personalizadas"); + PROGMEM Language_Str MSG_INTENSITY_R = _UxGT("Intensidade Vermello"); + PROGMEM Language_Str MSG_INTENSITY_G = _UxGT("Intensidade Verde"); + PROGMEM Language_Str MSG_INTENSITY_B = _UxGT("Intensidade Azul"); + PROGMEM Language_Str MSG_INTENSITY_W = _UxGT("Intensidade Branco"); + PROGMEM Language_Str MSG_LED_BRIGHTNESS = _UxGT("Brillo"); + + PROGMEM Language_Str MSG_MOVING = _UxGT("Movendo..."); + PROGMEM Language_Str MSG_FREE_XY = _UxGT("Libre XY"); PROGMEM Language_Str MSG_MOVE_X = _UxGT("Mover X"); PROGMEM Language_Str MSG_MOVE_Y = _UxGT("Mover Y"); PROGMEM Language_Str MSG_MOVE_Z = _UxGT("Mover Z"); PROGMEM Language_Str MSG_MOVE_E = _UxGT("Extrusor"); PROGMEM Language_Str MSG_MOVE_EN = _UxGT("Extrusor *"); + PROGMEM Language_Str MSG_HOTEND_TOO_COLD = _UxGT("Bico moi frío"); PROGMEM Language_Str MSG_MOVE_Z_DIST = _UxGT("Mover %smm"); PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Mover 0.1mm"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Mover 1mm"); @@ -91,17 +241,72 @@ namespace Language_gl { PROGMEM Language_Str MSG_BED_Z = _UxGT("Cama Z"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Bico"); PROGMEM Language_Str MSG_NOZZLE_N = _UxGT("Bico ~"); + PROGMEM Language_Str MSG_NOZZLE_PARKED = _UxGT("Bico Estacionado"); + PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("Bico Standby"); PROGMEM Language_Str MSG_BED = _UxGT("Cama"); - PROGMEM Language_Str MSG_FAN_SPEED = _UxGT("Velocidade vent."); - PROGMEM Language_Str MSG_FAN_SPEED_N = _UxGT("Velocidade vent. ~"); + PROGMEM Language_Str MSG_CHAMBER = _UxGT("Cámara"); + PROGMEM Language_Str MSG_FAN_SPEED = _UxGT("Vel. Ventilador"); + PROGMEM Language_Str MSG_FAN_SPEED_N = _UxGT("Vel. Ventilador ~"); + PROGMEM Language_Str MSG_STORED_FAN_N = _UxGT("Ventilador Mem. ~"); + PROGMEM Language_Str MSG_EXTRA_FAN_SPEED = _UxGT("Vel. Vent. Extra"); + PROGMEM Language_Str MSG_EXTRA_FAN_SPEED_N = _UxGT("Vel. Vent. Extra ~"); + PROGMEM Language_Str MSG_CONTROLLER_FAN = _UxGT("Controlador Vent."); + PROGMEM Language_Str MSG_CONTROLLER_FAN_IDLE_SPEED = _UxGT("Velocidade Repouso"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_AUTO_ON = _UxGT("Modo Auto"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_SPEED = _UxGT("Velocidade Activa"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_DURATION = _UxGT("Tempo Repouso"); PROGMEM Language_Str MSG_FLOW = _UxGT("Fluxo"); PROGMEM Language_Str MSG_FLOW_N = _UxGT("Fluxo ~"); + PROGMEM Language_Str MSG_CONTROL = _UxGT("Control"); PROGMEM Language_Str MSG_MIN = " " LCD_STR_THERMOMETER _UxGT(" Min"); PROGMEM Language_Str MSG_MAX = " " LCD_STR_THERMOMETER _UxGT(" Max"); PROGMEM Language_Str MSG_FACTOR = " " LCD_STR_THERMOMETER _UxGT(" Fact"); + PROGMEM Language_Str MSG_AUTOTEMP = _UxGT("Temperatura Auto."); + PROGMEM Language_Str MSG_LCD_ON = _UxGT("Acender"); + PROGMEM Language_Str MSG_LCD_OFF = _UxGT("Apagar"); + PROGMEM Language_Str MSG_PID_AUTOTUNE = _UxGT("Auto-Sint. PID"); + PROGMEM Language_Str MSG_PID_AUTOTUNE_E = _UxGT("Auto-Sint. PID *"); + PROGMEM Language_Str MSG_PID_AUTOTUNE_DONE = _UxGT("Fin Auto-Sint PID"); + PROGMEM Language_Str MSG_PID_BAD_EXTRUDER_NUM = _UxGT("Auto-Sint. fallida. Extrusor danado."); + PROGMEM Language_Str MSG_PID_TEMP_TOO_HIGH = _UxGT("Auto-Sint. fallida. Temperatura moi alta."); + PROGMEM Language_Str MSG_PID_TIMEOUT = _UxGT("Auto-Sint. fallida. Tempo excedido."); + PROGMEM Language_Str MSG_PID_P = _UxGT("PID-P"); + PROGMEM Language_Str MSG_PID_P_E = _UxGT("PID-P *"); + PROGMEM Language_Str MSG_PID_I = _UxGT("PID-I"); + PROGMEM Language_Str MSG_PID_I_E = _UxGT("PID-I *"); + PROGMEM Language_Str MSG_PID_D = _UxGT("PID-D"); + PROGMEM Language_Str MSG_PID_D_E = _UxGT("PID-D *"); + PROGMEM Language_Str MSG_PID_C = _UxGT("PID-C"); + PROGMEM Language_Str MSG_PID_C_E = _UxGT("PID-C *"); + PROGMEM Language_Str MSG_PID_F = _UxGT("PID-F"); + PROGMEM Language_Str MSG_PID_F_E = _UxGT("PID-F *"); PROGMEM Language_Str MSG_SELECT = _UxGT("Escolla"); PROGMEM Language_Str MSG_SELECT_E = _UxGT("Escolla *"); PROGMEM Language_Str MSG_ACC = _UxGT("Acel"); + PROGMEM Language_Str MSG_JERK = _UxGT("Jerk"); + PROGMEM Language_Str MSG_VA_JERK = _UxGT("V") LCD_STR_A _UxGT("-Jerk"); + PROGMEM Language_Str MSG_VB_JERK = _UxGT("V") LCD_STR_B _UxGT("-Jerk"); + PROGMEM Language_Str MSG_VC_JERK = _UxGT("V") LCD_STR_C _UxGT("-Jerk"); + PROGMEM Language_Str MSG_VE_JERK = _UxGT("Ve-Jerk"); + PROGMEM Language_Str MSG_JUNCTION_DEVIATION = _UxGT("Desvío Unión"); + PROGMEM Language_Str MSG_VELOCITY = _UxGT("Velocidade"); + PROGMEM Language_Str MSG_VMAX_A = _UxGT("Vmax ") LCD_STR_A; + PROGMEM Language_Str MSG_VMAX_B = _UxGT("Vmax ") LCD_STR_B; + PROGMEM Language_Str MSG_VMAX_C = _UxGT("Vmax ") LCD_STR_C; + PROGMEM Language_Str MSG_VMAX_E = _UxGT("Vmax ") LCD_STR_E; + PROGMEM Language_Str MSG_VMAX_EN = _UxGT("Vmax *"); + PROGMEM Language_Str MSG_VMIN = _UxGT("Vmin"); + PROGMEM Language_Str MSG_VTRAV_MIN = _UxGT("V-viaxe min"); + PROGMEM Language_Str MSG_ACCELERATION = _UxGT("Aceleración"); + PROGMEM Language_Str MSG_AMAX_A = _UxGT("Amax") LCD_STR_A; + PROGMEM Language_Str MSG_AMAX_B = _UxGT("Amax") LCD_STR_B; + PROGMEM Language_Str MSG_AMAX_C = _UxGT("Amax") LCD_STR_C; + PROGMEM Language_Str MSG_AMAX_E = _UxGT("Amax") LCD_STR_E; + PROGMEM Language_Str MSG_AMAX_EN = _UxGT("Amax *"); + PROGMEM Language_Str MSG_A_RETRACT = _UxGT("A-retrac."); + PROGMEM Language_Str MSG_A_TRAVEL = _UxGT("A-viaxe"); + PROGMEM Language_Str MSG_XY_FREQUENCY_LIMIT = _UxGT("Frecuencia max"); + PROGMEM Language_Str MSG_XY_FREQUENCY_FEEDRATE = _UxGT("Avance min"); PROGMEM Language_Str MSG_STEPS_PER_MM = _UxGT("Pasos/mm"); PROGMEM Language_Str MSG_A_STEPS = LCD_STR_A _UxGT(" pasos/mm"); PROGMEM Language_Str MSG_B_STEPS = LCD_STR_B _UxGT(" pasos/mm"); @@ -114,102 +319,299 @@ namespace Language_gl { PROGMEM Language_Str MSG_VOLUMETRIC_ENABLED = _UxGT("E en mm³"); PROGMEM Language_Str MSG_FILAMENT_DIAM = _UxGT("Diam. fil."); PROGMEM Language_Str MSG_FILAMENT_DIAM_E = _UxGT("Diam. fil. *"); + PROGMEM Language_Str MSG_FILAMENT_UNLOAD = _UxGT("Descarga mm"); + PROGMEM Language_Str MSG_FILAMENT_LOAD = _UxGT("Carga mm"); + PROGMEM Language_Str MSG_ADVANCE_K = _UxGT("Avance K"); + PROGMEM Language_Str MSG_ADVANCE_K_E = _UxGT("Avance K *"); PROGMEM Language_Str MSG_CONTRAST = _UxGT("Constraste LCD"); - PROGMEM Language_Str MSG_STORE_EEPROM = _UxGT("Gardar en memo."); - PROGMEM Language_Str MSG_LOAD_EEPROM = _UxGT("Cargar de memo."); - PROGMEM Language_Str MSG_RESTORE_DEFAULTS = _UxGT("Cargar de firm."); - PROGMEM Language_Str MSG_REFRESH = LCD_STR_REFRESH _UxGT("Volver a cargar"); - PROGMEM Language_Str MSG_INFO_SCREEN = _UxGT("Monitorizacion"); + PROGMEM Language_Str MSG_STORE_EEPROM = _UxGT("Gardar Configuración"); + PROGMEM Language_Str MSG_LOAD_EEPROM = _UxGT("Cargar Configuración"); + PROGMEM Language_Str MSG_RESTORE_DEFAULTS = _UxGT("Rest. Defecto"); + PROGMEM Language_Str MSG_INIT_EEPROM = _UxGT("Inicializar EEPROM"); + PROGMEM Language_Str MSG_ERR_EEPROM_CRC = _UxGT("Erro: CRC EEPROM"); + PROGMEM Language_Str MSG_ERR_EEPROM_INDEX = _UxGT("Erro: Índice EEPROM"); + PROGMEM Language_Str MSG_ERR_EEPROM_VERSION = _UxGT("Erro: Versión EEPROM"); + PROGMEM Language_Str MSG_SETTINGS_STORED = _UxGT("Config Gardada"); + PROGMEM Language_Str MSG_MEDIA_UPDATE = _UxGT("Actualizar SD/USB"); + PROGMEM Language_Str MSG_RESET_PRINTER = _UxGT("Reiniciar Impresora"); + PROGMEM Language_Str MSG_REFRESH = LCD_STR_REFRESH _UxGT("Recargar"); + PROGMEM Language_Str MSG_INFO_SCREEN = _UxGT("Información"); PROGMEM Language_Str MSG_PREPARE = _UxGT("Preparar"); PROGMEM Language_Str MSG_TUNE = _UxGT("Axustar"); - PROGMEM Language_Str MSG_PAUSE_PRINT = _UxGT("Pausar impres."); - PROGMEM Language_Str MSG_RESUME_PRINT = _UxGT("Seguir impres."); - PROGMEM Language_Str MSG_STOP_PRINT = _UxGT("Deter impres."); + PROGMEM Language_Str MSG_START_PRINT = _UxGT("Comezar impresión"); + PROGMEM Language_Str MSG_BUTTON_NEXT = _UxGT("Seguinte"); + PROGMEM Language_Str MSG_BUTTON_INIT = _UxGT("Comezar"); + PROGMEM Language_Str MSG_BUTTON_STOP = _UxGT("Deter"); + PROGMEM Language_Str MSG_BUTTON_PRINT = _UxGT("Imprimir"); + PROGMEM Language_Str MSG_BUTTON_RESET = _UxGT("Reiniciar"); + PROGMEM Language_Str MSG_BUTTON_CANCEL = _UxGT("Cancelar"); + PROGMEM Language_Str MSG_BUTTON_DONE = _UxGT("Listo"); + PROGMEM Language_Str MSG_BUTTON_BACK = _UxGT("Atrás"); + PROGMEM Language_Str MSG_BUTTON_PROCEED = _UxGT("Proceder"); + PROGMEM Language_Str MSG_PAUSING = _UxGT("Pausando..."); + PROGMEM Language_Str MSG_PAUSE_PRINT = _UxGT("Pausar impresión"); + PROGMEM Language_Str MSG_RESUME_PRINT = _UxGT("Retomar impresión"); + PROGMEM Language_Str MSG_STOP_PRINT = _UxGT("Deter impresión"); + PROGMEM Language_Str MSG_PRINTING_OBJECT = _UxGT("Imprimindo Obxecto"); + PROGMEM Language_Str MSG_CANCEL_OBJECT = _UxGT("Cancelar Obxecto"); + PROGMEM Language_Str MSG_CANCEL_OBJECT_N = _UxGT("Cancelar Obxecto ="); + PROGMEM Language_Str MSG_OUTAGE_RECOVERY = _UxGT("Recuperar Impresión"); PROGMEM Language_Str MSG_MEDIA_MENU = _UxGT("Tarxeta SD"); PROGMEM Language_Str MSG_NO_MEDIA = _UxGT("Sen tarxeta SD"); PROGMEM Language_Str MSG_DWELL = _UxGT("En repouso..."); - PROGMEM Language_Str MSG_USERWAIT = _UxGT("A espera..."); - PROGMEM Language_Str MSG_PRINT_ABORTED = _UxGT("Impre. cancelada"); + PROGMEM Language_Str MSG_USERWAIT = _UxGT("Prema para Retomar.."); + PROGMEM Language_Str MSG_PRINT_PAUSED = _UxGT("Impresión Pausada"); + PROGMEM Language_Str MSG_PRINTING = _UxGT("Imprimindo..."); + PROGMEM Language_Str MSG_PRINT_ABORTED = _UxGT("Impresión Cancelada"); + PROGMEM Language_Str MSG_PRINT_DONE = _UxGT("Fin Impresión"); PROGMEM Language_Str MSG_NO_MOVE = _UxGT("Sen movemento."); - PROGMEM Language_Str MSG_KILLED = _UxGT("PROGRAMA MORTO"); - PROGMEM Language_Str MSG_STOPPED = _UxGT("PROGRAMA PARADO"); - PROGMEM Language_Str MSG_CONTROL_RETRACT = _UxGT("Retraccion mm"); + PROGMEM Language_Str MSG_KILLED = _UxGT("MORTO."); + PROGMEM Language_Str MSG_STOPPED = _UxGT("DETIDO."); + PROGMEM Language_Str MSG_CONTROL_RETRACT = _UxGT("Retraer mm"); PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("Cambio retra. mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("Retraccion V"); + PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("Retraer V"); PROGMEM Language_Str MSG_CONTROL_RETRACT_ZHOP = _UxGT("Alzar Z mm"); PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("Recup. retra. mm"); PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("Cambio recup. mm"); PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("Recuperacion V"); - PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("Retraccion auto."); - PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("Cambiar filamen."); - PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Cambiar filamen. *"); - PROGMEM Language_Str MSG_ATTACH_MEDIA = _UxGT("Iniciando SD"); - PROGMEM Language_Str MSG_CHANGE_MEDIA = _UxGT("Cambiar SD"); - PROGMEM Language_Str MSG_ZPROBE_OUT = _UxGT("Sonda-Z sen cama"); - PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("Comprobar BLTouch"); - PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("Iniciar BLTouch"); - PROGMEM Language_Str MSG_ZPROBE_ZOFFSET = _UxGT("Offset Z"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAPF = _UxGT("S UnRet V"); + PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("Auto-Retracción"); + PROGMEM Language_Str MSG_FILAMENT_SWAP_LENGTH = _UxGT("Lonxitude Retracción"); + PROGMEM Language_Str MSG_FILAMENT_SWAP_EXTRA = _UxGT("Cambio Extra"); + PROGMEM Language_Str MSG_FILAMENT_PURGE_LENGTH = _UxGT("Lonxitude de Purga"); + PROGMEM Language_Str MSG_TOOL_CHANGE = _UxGT("Cambiar Ferramenta"); + PROGMEM Language_Str MSG_TOOL_CHANGE_ZLIFT = _UxGT("Levantar Z"); + PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPEED = _UxGT("Velocidade prim."); + PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPEED = _UxGT("Vel. de Retracción"); + PROGMEM Language_Str MSG_FILAMENT_PARK_ENABLED = _UxGT("Extrusor Est."); + PROGMEM Language_Str MSG_SINGLENOZZLE_UNRETRACT_SPEED = _UxGT("Vel. Recuperación"); + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_SPEED = _UxGT("Vel. Ventilador"); + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_TIME = _UxGT("Tempo Ventilador"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_ON = _UxGT("Auto ON"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_OFF = _UxGT("Auto OFF"); + PROGMEM Language_Str MSG_TOOL_MIGRATION = _UxGT("Cambio Ferramenta"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_AUTO = _UxGT("Cambio Automático"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_END = _UxGT("Último Extrusor"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_SWAP = _UxGT("Cambio a *"); + PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("Cambiar Filamento"); + PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Cambiar Filamento *"); + PROGMEM Language_Str MSG_FILAMENTLOAD = _UxGT("Cargar Filamento"); + PROGMEM Language_Str MSG_FILAMENTLOAD_E = _UxGT("Cargar Filamento *"); + PROGMEM Language_Str MSG_FILAMENTUNLOAD = _UxGT("Descargar Filamento"); + PROGMEM Language_Str MSG_FILAMENTUNLOAD_E = _UxGT("Descargar Filamento *"); + PROGMEM Language_Str MSG_FILAMENTUNLOAD_ALL = _UxGT("Descargar Todo"); + PROGMEM Language_Str MSG_ATTACH_MEDIA = _UxGT("Iniciar SD/USB"); + PROGMEM Language_Str MSG_CHANGE_MEDIA = _UxGT("Cambiar SD/USB"); + PROGMEM Language_Str MSG_RELEASE_MEDIA = _UxGT("Lanzar SD/USB"); + PROGMEM Language_Str MSG_ZPROBE_OUT = _UxGT("Sonda-Z fóra Cama"); + PROGMEM Language_Str MSG_SKEW_FACTOR = _UxGT("Factor de Desviación"); + PROGMEM Language_Str MSG_BLTOUCH = _UxGT("BLTouch"); + PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("Auto-Test"); + PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("Reiniciar"); + PROGMEM Language_Str MSG_BLTOUCH_STOW = _UxGT("Recoller"); + PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("Estender"); + PROGMEM Language_Str MSG_BLTOUCH_SW_MODE = _UxGT("Modo Software"); + PROGMEM Language_Str MSG_BLTOUCH_5V_MODE = _UxGT("Modo 5V"); + PROGMEM Language_Str MSG_BLTOUCH_OD_MODE = _UxGT("Modo OD"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE = _UxGT("Modo Almacenar"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_5V = _UxGT("Axustar BLTouch a 5V"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_OD = _UxGT("Axustar BLTouch a OD"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_ECHO = _UxGT("Modo de Informe"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_CHANGE = _UxGT("PERIGO: Unha mala configuración pode producir daños! Proceder igualmente?"); + PROGMEM Language_Str MSG_TOUCHMI_PROBE = _UxGT("TouchMI"); + PROGMEM Language_Str MSG_TOUCHMI_INIT = _UxGT("Iniciar TouchMI"); + PROGMEM Language_Str MSG_TOUCHMI_ZTEST = _UxGT("Test de Desfase Z"); + PROGMEM Language_Str MSG_TOUCHMI_SAVE = _UxGT("Gardar"); + PROGMEM Language_Str MSG_MANUAL_DEPLOY_TOUCHMI = _UxGT("Estender TouchMI"); + PROGMEM Language_Str MSG_MANUAL_DEPLOY = _UxGT("Estender Sonda Z"); + PROGMEM Language_Str MSG_MANUAL_STOW = _UxGT("Recoller Sonda Z"); + PROGMEM Language_Str MSG_HOME_FIRST = _UxGT("Orixe %s%s%s Primeiro"); + PROGMEM Language_Str MSG_ZPROBE_OFFSETS = _UxGT("Desfases Sonda"); + PROGMEM Language_Str MSG_ZPROBE_XOFFSET = _UxGT("Desfase Sonda X"); + PROGMEM Language_Str MSG_ZPROBE_YOFFSET = _UxGT("Desfase Sonda Y"); + PROGMEM Language_Str MSG_ZPROBE_ZOFFSET = _UxGT("Desfase Z"); PROGMEM Language_Str MSG_BABYSTEP_X = _UxGT("Micropaso X"); PROGMEM Language_Str MSG_BABYSTEP_Y = _UxGT("Micropaso Y"); PROGMEM Language_Str MSG_BABYSTEP_Z = _UxGT("Micropaso Z"); - PROGMEM Language_Str MSG_ENDSTOP_ABORT = _UxGT("Erro fin carro"); - PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("Fallo quentando"); - PROGMEM Language_Str MSG_ERR_REDUNDANT_TEMP = _UxGT("Erro temperatura"); - PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("Temp. excesiva"); - PROGMEM Language_Str MSG_HALTED = _UxGT("SISTEMA MORTO"); + PROGMEM Language_Str MSG_BABYSTEP_TOTAL = _UxGT("Total"); + PROGMEM Language_Str MSG_ENDSTOP_ABORT = _UxGT("Erro FinCarro"); + PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("Fallo Quentando"); + PROGMEM Language_Str MSG_ERR_REDUNDANT_TEMP = _UxGT("Erro:Temp Redundante"); + PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("FUGA TÉRMICA"); + PROGMEM Language_Str MSG_THERMAL_RUNAWAY_BED = _UxGT("FUGA TÉRMICA CAMA"); + PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER = _UxGT("FUGA TÉRMICA CÁMARA"); + PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("Erro:TEMP MÁX"); + PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("Erro:TEMP MÍN"); + PROGMEM Language_Str MSG_HALTED = _UxGT("IMPRESORA DETIDA"); PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("Debe reiniciar!"); + PROGMEM Language_Str MSG_SHORT_DAY = _UxGT("d"); // One character only + PROGMEM Language_Str MSG_SHORT_HOUR = _UxGT("h"); // One character only + PROGMEM Language_Str MSG_SHORT_MINUTE = _UxGT("m"); // One character only PROGMEM Language_Str MSG_HEATING = _UxGT("Quentando..."); + PROGMEM Language_Str MSG_COOLING = _UxGT("Arrefriando..."); PROGMEM Language_Str MSG_BED_HEATING = _UxGT("Quentando cama..."); + PROGMEM Language_Str MSG_BED_COOLING = _UxGT("Enfriando Cama..."); + PROGMEM Language_Str MSG_CHAMBER_HEATING = _UxGT("Quentando Cámara..."); + PROGMEM Language_Str MSG_CHAMBER_COOLING = _UxGT("Arrefriando Cámara..."); PROGMEM Language_Str MSG_DELTA_CALIBRATE = _UxGT("Calibracion Delta"); PROGMEM Language_Str MSG_DELTA_CALIBRATE_X = _UxGT("Calibrar X"); PROGMEM Language_Str MSG_DELTA_CALIBRATE_Y = _UxGT("Calibrar Y"); PROGMEM Language_Str MSG_DELTA_CALIBRATE_Z = _UxGT("Calibrar Z"); PROGMEM Language_Str MSG_DELTA_CALIBRATE_CENTER = _UxGT("Calibrar Centro"); + PROGMEM Language_Str MSG_DELTA_SETTINGS = _UxGT("Configuración Delta"); + PROGMEM Language_Str MSG_DELTA_AUTO_CALIBRATE = _UxGT("Auto Calibración"); + PROGMEM Language_Str MSG_DELTA_HEIGHT_CALIBRATE = _UxGT("Ax. Altura Delta"); + PROGMEM Language_Str MSG_DELTA_Z_OFFSET_CALIBRATE = _UxGT("Axustar Sonda Z"); + PROGMEM Language_Str MSG_DELTA_DIAG_ROD = _UxGT("Barra Diagonal"); + PROGMEM Language_Str MSG_DELTA_HEIGHT = _UxGT("Altura"); + PROGMEM Language_Str MSG_DELTA_RADIUS = _UxGT("Radio"); PROGMEM Language_Str MSG_INFO_MENU = _UxGT("Acerca de..."); - PROGMEM Language_Str MSG_INFO_PRINTER_MENU = _UxGT("Informacion"); - PROGMEM Language_Str MSG_INFO_STATS_MENU = _UxGT("Estadisticas"); + PROGMEM Language_Str MSG_INFO_PRINTER_MENU = _UxGT("Información"); + PROGMEM Language_Str MSG_3POINT_LEVELING = _UxGT("Nivelación 3puntos"); + PROGMEM Language_Str MSG_LINEAR_LEVELING = _UxGT("Nivelación Lineal"); + PROGMEM Language_Str MSG_BILINEAR_LEVELING = _UxGT("Nivelación Bilineal"); + PROGMEM Language_Str MSG_UBL_LEVELING = _UxGT("Nivelación UBL"); + PROGMEM Language_Str MSG_MESH_LEVELING = _UxGT("Nivelación en Malla"); + PROGMEM Language_Str MSG_INFO_STATS_MENU = _UxGT("Estatísticas"); PROGMEM Language_Str MSG_INFO_BOARD_MENU = _UxGT("Placa nai"); PROGMEM Language_Str MSG_INFO_THERMISTOR_MENU = _UxGT("Termistores"); PROGMEM Language_Str MSG_INFO_EXTRUDERS = _UxGT("Extrusores"); PROGMEM Language_Str MSG_INFO_BAUDRATE = _UxGT("Baudios"); PROGMEM Language_Str MSG_INFO_PROTOCOL = _UxGT("Protocolo"); - PROGMEM Language_Str MSG_CASE_LIGHT = _UxGT("Luz"); + PROGMEM Language_Str MSG_INFO_RUNAWAY_OFF = _UxGT("Reloxo Traballo: OFF"); + PROGMEM Language_Str MSG_INFO_RUNAWAY_ON = _UxGT("Reloxo Traballo: ON"); + + PROGMEM Language_Str MSG_CASE_LIGHT = _UxGT("Luz da Caixa"); + PROGMEM Language_Str MSG_CASE_LIGHT_BRIGHTNESS = _UxGT("Brillo Luces"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("IMPRESORA INCORRECTA"); + #if LCD_WIDTH >= 20 - PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Total traballos"); - PROGMEM Language_Str MSG_INFO_COMPLETED_PRINTS = _UxGT("Total completos"); - PROGMEM Language_Str MSG_INFO_PRINT_TIME = _UxGT("Tempo impresion"); - PROGMEM Language_Str MSG_INFO_PRINT_LONGEST = _UxGT("Traballo +longo"); - PROGMEM Language_Str MSG_INFO_PRINT_FILAMENT = _UxGT("Total extruido"); + PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Total Impresións"); + PROGMEM Language_Str MSG_INFO_COMPLETED_PRINTS = _UxGT("Completadas"); + PROGMEM Language_Str MSG_INFO_PRINT_TIME = _UxGT("Tempo Total Imp."); + PROGMEM Language_Str MSG_INFO_PRINT_LONGEST = _UxGT("Impresión máis longa"); + PROGMEM Language_Str MSG_INFO_PRINT_FILAMENT = _UxGT("Total Extruído"); #else - PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Traballos"); - PROGMEM Language_Str MSG_INFO_COMPLETED_PRINTS = _UxGT("Completos"); - PROGMEM Language_Str MSG_INFO_PRINT_TIME = _UxGT("Tempo"); - PROGMEM Language_Str MSG_INFO_PRINT_LONGEST = _UxGT("O +longo"); + PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Impresións"); + PROGMEM Language_Str MSG_INFO_COMPLETED_PRINTS = _UxGT("Completadas"); + PROGMEM Language_Str MSG_INFO_PRINT_TIME = _UxGT("Total"); + PROGMEM Language_Str MSG_INFO_PRINT_LONGEST = _UxGT("Máis Longa"); PROGMEM Language_Str MSG_INFO_PRINT_FILAMENT = _UxGT("Extruido"); #endif - PROGMEM Language_Str MSG_INFO_MIN_TEMP = _UxGT("Min Temp"); - PROGMEM Language_Str MSG_INFO_MAX_TEMP = _UxGT("Max Temp"); - PROGMEM Language_Str MSG_INFO_PSU = _UxGT("Fonte alime."); - PROGMEM Language_Str MSG_DRIVE_STRENGTH = _UxGT("Potencia motor"); - PROGMEM Language_Str MSG_DAC_EEPROM_WRITE = _UxGT("Garda DAC EEPROM"); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_RESUME = _UxGT("Segue traballo"); + PROGMEM Language_Str MSG_INFO_MIN_TEMP = _UxGT("Temp Mín"); + PROGMEM Language_Str MSG_INFO_MAX_TEMP = _UxGT("Temp Máx"); + PROGMEM Language_Str MSG_INFO_PSU = _UxGT("Fonte Alimentación"); + PROGMEM Language_Str MSG_DRIVE_STRENGTH = _UxGT("Forza do Motor"); + PROGMEM Language_Str MSG_DAC_PERCENT_X = _UxGT("X Driver %"); + PROGMEM Language_Str MSG_DAC_PERCENT_Y = _UxGT("Y Driver %"); + PROGMEM Language_Str MSG_DAC_PERCENT_Z = _UxGT("Z Driver %"); + PROGMEM Language_Str MSG_DAC_PERCENT_E = _UxGT("E Driver %"); + PROGMEM Language_Str MSG_ERROR_TMC = _UxGT("ERRO CONEX. TMC"); + PROGMEM Language_Str MSG_DAC_EEPROM_WRITE = _UxGT("Escribe DAC EEPROM"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER = _UxGT("CAMBIAR FILAMENTO"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_PAUSE = _UxGT("IMPRESIÓN PAUSADA"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_LOAD = _UxGT("CARGAR FILAMENTO"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_UNLOAD = _UxGT("DESCARGAR FILAMENTO"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_HEADER = _UxGT("OPCIÓN DE RETOMAR:"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_PURGE = _UxGT("Purgar máis"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_RESUME = _UxGT("Retomar traballo"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" Bico: "); + PROGMEM Language_Str MSG_RUNOUT_SENSOR = _UxGT("Sensor Filamento"); + PROGMEM Language_Str MSG_RUNOUT_DISTANCE_MM = _UxGT("Dist mm Sensor Fil"); + PROGMEM Language_Str MSG_KILL_HOMING_FAILED = _UxGT("Fallo ao ir á Orixe"); + PROGMEM Language_Str MSG_LCD_PROBING_FAILED = _UxGT("Fallo ao Sondar"); + + PROGMEM Language_Str MSG_MMU2_CHOOSE_FILAMENT_HEADER = _UxGT("ESCOLLE FILAMENTO"); + PROGMEM Language_Str MSG_MMU2_MENU = _UxGT("MMU"); + PROGMEM Language_Str MSG_KILL_MMU2_FIRMWARE = _UxGT("Actualizar FW MMU!"); + PROGMEM Language_Str MSG_MMU2_NOT_RESPONDING = _UxGT("MMU Precisa Atención."); + PROGMEM Language_Str MSG_MMU2_RESUME = _UxGT("Retomar impr."); + PROGMEM Language_Str MSG_MMU2_RESUMING = _UxGT("Retomando..."); + PROGMEM Language_Str MSG_MMU2_LOAD_FILAMENT = _UxGT("Cargar Filamento"); + PROGMEM Language_Str MSG_MMU2_LOAD_ALL = _UxGT("Cargar Todo"); + PROGMEM Language_Str MSG_MMU2_LOAD_TO_NOZZLE = _UxGT("Cargar até bico"); + PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT = _UxGT("Expulsar Filamento"); + PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT_N = _UxGT("Expulsar Filamento ~"); + PROGMEM Language_Str MSG_MMU2_UNLOAD_FILAMENT = _UxGT("Descargar Filamento"); + PROGMEM Language_Str MSG_MMU2_LOADING_FILAMENT = _UxGT("Cargando Fil. %i..."); + PROGMEM Language_Str MSG_MMU2_EJECTING_FILAMENT = _UxGT("Expulsando Fil. ..."); + PROGMEM Language_Str MSG_MMU2_UNLOADING_FILAMENT = _UxGT("Descargando Fil..."); + PROGMEM Language_Str MSG_MMU2_ALL = _UxGT("Todo"); + PROGMEM Language_Str MSG_MMU2_FILAMENT_N = _UxGT("Filamento ~"); + PROGMEM Language_Str MSG_MMU2_RESET = _UxGT("Reiniciar MMU"); + PROGMEM Language_Str MSG_MMU2_RESETTING = _UxGT("Reiniciando MMU..."); + PROGMEM Language_Str MSG_MMU2_EJECT_RECOVER = _UxGT("Expulsar, premer"); - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("Impresora incorrecta"); + PROGMEM Language_Str MSG_MIX = _UxGT("Mestura"); + PROGMEM Language_Str MSG_MIX_COMPONENT_N = _UxGT("Compoñente ="); + PROGMEM Language_Str MSG_MIXER = _UxGT("Mesturadora"); + PROGMEM Language_Str MSG_GRADIENT = _UxGT("Degradado"); + PROGMEM Language_Str MSG_FULL_GRADIENT = _UxGT("Degradado Total"); + PROGMEM Language_Str MSG_TOGGLE_MIX = _UxGT("Mestura Conmutada"); + PROGMEM Language_Str MSG_CYCLE_MIX = _UxGT("Mestura Cíclica"); + PROGMEM Language_Str MSG_GRADIENT_MIX = _UxGT("Mestura de Degradado"); + PROGMEM Language_Str MSG_REVERSE_GRADIENT = _UxGT("Degradado Inverso"); + PROGMEM Language_Str MSG_ACTIVE_VTOOL = _UxGT("Activar Ferr-V"); + PROGMEM Language_Str MSG_START_VTOOL = _UxGT("Inicio Ferr-V"); + PROGMEM Language_Str MSG_END_VTOOL = _UxGT(" Fin Ferr-V"); + PROGMEM Language_Str MSG_GRADIENT_ALIAS = _UxGT("Alias Ferr-V"); + PROGMEM Language_Str MSG_RESET_VTOOLS = _UxGT("Reiniciar Ferr-V"); + PROGMEM Language_Str MSG_COMMIT_VTOOL = _UxGT("Commit mest. Ferr-V"); + PROGMEM Language_Str MSG_VTOOLS_RESET = _UxGT("Ferr-V reiniciadas"); + PROGMEM Language_Str MSG_START_Z = _UxGT("Inicio Z:"); + PROGMEM Language_Str MSG_END_Z = _UxGT(" Fin Z:"); + + PROGMEM Language_Str MSG_GAMES = _UxGT("Xogos"); + PROGMEM Language_Str MSG_BRICKOUT = _UxGT("Brickout"); + PROGMEM Language_Str MSG_INVADERS = _UxGT("Invaders"); + PROGMEM Language_Str MSG_SNAKE = _UxGT("Sn4k3"); + PROGMEM Language_Str MSG_MAZE = _UxGT("Labirinto"); #if LCD_HEIGHT >= 4 - // Up to 3 lines allowed - PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_3_LINE("Agarde para", "iniciar troco", "de filamento")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_3_LINE("Agarde pola", "descarga do", "filamento")); + PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_2_LINE("Preme o botón para", "continuar impresión")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Estacionando...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_3_LINE("Agarde para", "comezar cambio", "de filamento")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_3_LINE("Introduza o", "filamento e", "faga click")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_2_LINE("Prema o botón para", "quentar o bico")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEATING = _UxGT(MSG_2_LINE("Quentando bico", "Agarde, por favor...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_3_LINE("Agarde pola", "descarga do", "filamento")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_3_LINE("Agarde pola", "carga do", "filamento")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_3_LINE("Agarde para", "seguir co", "traballo")); - #else // LCD_HEIGHT < 4 - // Up to 2 lines allowed + PROGMEM Language_Str MSG_FILAMENT_CHANGE_PURGE = _UxGT(MSG_2_LINE("Agarde para", "purgar o filamento")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_CONT_PURGE = _UxGT(MSG_2_LINE("Prema para finalizar", "a purga do filamen.")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_3_LINE("Agarde a que", "se retome", "a impresión")); + #else + PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_1_LINE("Premer para continuar")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Estacionando...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_1_LINE("Agarde...")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_1_LINE("Descargando...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_1_LINE("Introduza e click")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_1_LINE("Prema para quentar")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEATING = _UxGT(MSG_1_LINE("Quentando...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_1_LINE("Descargando...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_1_LINE("Cargando...")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_1_LINE("Seguindo...")); - #endif // LCD_HEIGHT < 4 + PROGMEM Language_Str MSG_FILAMENT_CHANGE_PURGE = _UxGT(MSG_1_LINE("Purgando...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_CONT_PURGE = _UxGT(MSG_1_LINE("Prema para finalizar")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_1_LINE("Retomando...")); + #endif + + PROGMEM Language_Str MSG_TMC_DRIVERS = _UxGT("Controladores TMC"); + PROGMEM Language_Str MSG_TMC_CURRENT = _UxGT("Controlador Actual"); + PROGMEM Language_Str MSG_TMC_HYBRID_THRS = _UxGT("Limiar Hibrido"); + PROGMEM Language_Str MSG_TMC_HOMING_THRS = _UxGT("Orixe sen Sensores"); + PROGMEM Language_Str MSG_TMC_STEPPING_MODE = _UxGT("Modo de pasos"); + PROGMEM Language_Str MSG_TMC_STEALTH_ENABLED = _UxGT("StealthChop Habilit."); + PROGMEM Language_Str MSG_SERVICE_RESET = _UxGT("Reiniciar"); + PROGMEM Language_Str MSG_SERVICE_IN = _UxGT(" dentro:"); + PROGMEM Language_Str MSG_BACKLASH = _UxGT("Reacción"); + PROGMEM Language_Str MSG_BACKLASH_A = LCD_STR_A; + PROGMEM Language_Str MSG_BACKLASH_B = LCD_STR_B; + PROGMEM Language_Str MSG_BACKLASH_C = LCD_STR_C; + PROGMEM Language_Str MSG_BACKLASH_CORRECTION = _UxGT("Corrección"); + PROGMEM Language_Str MSG_BACKLASH_SMOOTHING = _UxGT("Suavizado"); + + PROGMEM Language_Str MSG_LEVEL_X_AXIS = _UxGT("Nivel Eixe X"); + PROGMEM Language_Str MSG_AUTO_CALIBRATE = _UxGT("Auto Calibrar"); + PROGMEM Language_Str MSG_HEATER_TIMEOUT = _UxGT("Tempo exc. Quent."); + PROGMEM Language_Str MSG_REHEAT = _UxGT("Requentar"); + PROGMEM Language_Str MSG_REHEATING = _UxGT("Requentando..."); } diff --git a/Marlin/src/lcd/language/language_hr.h b/Marlin/src/lcd/language/language_hr.h index 740d7e562599..1b2ae41fcedb 100644 --- a/Marlin/src/lcd/language/language_hr.h +++ b/Marlin/src/lcd/language/language_hr.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,8 +25,7 @@ * Croatian (Hrvatski) * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ #define DISPLAY_CHARSET_ISO10646_1 // use the better font on full graphic displays. @@ -55,20 +54,23 @@ namespace Language_hr { PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Postavi home offsete"); PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Offsets postavljeni"); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Postavi ishodište"); - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Predgrij ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Predgrij ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Predgrij ") PREHEAT_1_LABEL _UxGT(" Dizna"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Predgrij ") PREHEAT_1_LABEL _UxGT(" Dizna ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Predgrij ") PREHEAT_1_LABEL _UxGT(" Sve"); - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Predgrij ") PREHEAT_1_LABEL _UxGT(" Bed"); - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Predgrij ") PREHEAT_1_LABEL _UxGT(" conf"); - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("Predgrij ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("Predgrij ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("Predgrij ") PREHEAT_2_LABEL _UxGT(" Dizna"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("Predgrij ") PREHEAT_2_LABEL _UxGT(" Dizna ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("Predgrij ") PREHEAT_2_LABEL _UxGT(" Sve"); - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("Predgrij ") PREHEAT_2_LABEL _UxGT(" Bed"); - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("Predgrij ") PREHEAT_2_LABEL _UxGT(" conf"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Predgrij ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Predgrij ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Predgrij ") PREHEAT_1_LABEL _UxGT(" Dizna"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Predgrij ") PREHEAT_1_LABEL _UxGT(" Dizna ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Predgrij ") PREHEAT_1_LABEL _UxGT(" Sve"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Predgrij ") PREHEAT_1_LABEL _UxGT(" Bed"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Predgrij ") PREHEAT_1_LABEL _UxGT(" conf"); + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Predgrij $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Predgrij $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Predgrij $ Dizna"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Predgrij $ Dizna ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Predgrij $ Sve"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Predgrij $ Bed"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Predgrij $ conf"); + #endif PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Hlađenje"); PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Uključi napajanje"); PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("Isključi napajanje"); @@ -132,7 +134,7 @@ namespace Language_hr { PROGMEM Language_Str MSG_INFO_PROTOCOL = _UxGT("Protokol"); PROGMEM Language_Str MSG_CASE_LIGHT = _UxGT("Osvjetljenje"); - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("Neispravan pisač"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("Neispravan pisač"); #if LCD_WIDTH >= 20 PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Broj printova"); diff --git a/Marlin/src/lcd/language/language_hu.h b/Marlin/src/lcd/language/language_hu.h new file mode 100644 index 000000000000..6e1b30c18096 --- /dev/null +++ b/Marlin/src/lcd/language/language_hu.h @@ -0,0 +1,630 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * Magyar + * + * LCD Menü Üzenetek. Lásd még https://marlinfw.org/docs/development/lcd_language.html + * Marlin 2.0.x bugfix Magyar fordítása. A fordítást folyamatosan javítom és frissítem. + * A Magyar fordítást készítette: AntoszHUN + * + * + */ + +namespace Language_hu { + using namespace Language_en; // A fordítás az örökölt Amerikai Angol (English) karakterláncokat használja. + + + constexpr uint8_t CHARSIZE = 2; + PROGMEM Language_Str LANGUAGE = _UxGT("Magyar"); + + PROGMEM Language_Str WELCOME_MSG = MACHINE_NAME _UxGT(" Kész."); + PROGMEM Language_Str MSG_MARLIN = _UxGT("Marlin"); + PROGMEM Language_Str MSG_YES = _UxGT("IGEN"); + PROGMEM Language_Str MSG_NO = _UxGT("NEM"); + PROGMEM Language_Str MSG_BACK = _UxGT("Vissza"); + PROGMEM Language_Str MSG_MEDIA_ABORTING = _UxGT("Megszakítás..."); + PROGMEM Language_Str MSG_MEDIA_INSERTED = _UxGT("Tároló Behelyezve"); + PROGMEM Language_Str MSG_MEDIA_REMOVED = _UxGT("Tároló Eltávolítva"); + PROGMEM Language_Str MSG_MEDIA_WAITING = _UxGT("Várakozás a tárolóra"); + PROGMEM Language_Str MSG_MEDIA_READ_ERROR = _UxGT("Tároló olvasási hiba"); + PROGMEM Language_Str MSG_MEDIA_USB_REMOVED = _UxGT("USB eltávolítva"); + PROGMEM Language_Str MSG_MEDIA_USB_FAILED = _UxGT("USB eszköz hiba"); + PROGMEM Language_Str MSG_KILL_SUBCALL_OVERFLOW = _UxGT("Túlfolyás"); + PROGMEM Language_Str MSG_LCD_ENDSTOPS = _UxGT("Végállás"); // Maximum 8 karakter + PROGMEM Language_Str MSG_LCD_SOFT_ENDSTOPS = _UxGT("Szoft. Végállás"); + PROGMEM Language_Str MSG_MAIN = _UxGT(""); + PROGMEM Language_Str MSG_ADVANCED_SETTINGS = _UxGT("További Beállítások"); + PROGMEM Language_Str MSG_CONFIGURATION = _UxGT("Konfiguráció"); + PROGMEM Language_Str MSG_AUTOSTART = _UxGT("Autoinditás"); + PROGMEM Language_Str MSG_DISABLE_STEPPERS = _UxGT("Motorok kikapcsolása"); + PROGMEM Language_Str MSG_DEBUG_MENU = _UxGT("Hiba Menü"); + PROGMEM Language_Str MSG_PROGRESS_BAR_TEST = _UxGT("Haladás sáv teszt"); + PROGMEM Language_Str MSG_AUTO_HOME = _UxGT("XYZ Auto kezdöpont"); + PROGMEM Language_Str MSG_AUTO_HOME_X = _UxGT("X Kezdöpont"); + PROGMEM Language_Str MSG_AUTO_HOME_Y = _UxGT("Y Kezdöpont"); + PROGMEM Language_Str MSG_AUTO_HOME_Z = _UxGT("Z Kezdöpont"); + PROGMEM Language_Str MSG_AUTO_Z_ALIGN = _UxGT("Auto Z-Igazítás"); + PROGMEM Language_Str MSG_LEVEL_BED_HOMING = _UxGT("XYZ Kezdöpont"); + PROGMEM Language_Str MSG_LEVEL_BED_WAITING = _UxGT("Kattints a kezdéshez."); + PROGMEM Language_Str MSG_LEVEL_BED_NEXT_POINT = _UxGT("Következö Pont"); + PROGMEM Language_Str MSG_LEVEL_BED_DONE = _UxGT("Szintezés Kész!"); + PROGMEM Language_Str MSG_Z_FADE_HEIGHT = _UxGT("Szint Csökkentés"); + PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Kezdöpont eltolás"); + PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Eltolás beállítva."); + PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Eredeti Be"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Fütés ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Fütés ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Fütés ") PREHEAT_1_LABEL _UxGT(" Fej"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Fütés ") PREHEAT_1_LABEL _UxGT(" Fej ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Fütés ") PREHEAT_1_LABEL _UxGT(" Mind"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Fütés ") PREHEAT_1_LABEL _UxGT(" Ágy"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Fütés ") PREHEAT_1_LABEL _UxGT(" Beáll"); + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Fütés $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Fütés $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Fütés $ Fej"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Fütés $ Fej ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Fütés $ Mind"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Fütés $ Ágy"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Fütés $ Beáll"); + #endif + PROGMEM Language_Str MSG_PREHEAT_CUSTOM = _UxGT("Egyedi Elömelegítés"); + PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Visszahütés"); + PROGMEM Language_Str MSG_CUTTER_FREQUENCY = _UxGT("Frekvencia"); + PROGMEM Language_Str MSG_LASER_MENU = _UxGT("Lézer Vezérlés"); + PROGMEM Language_Str MSG_LASER_OFF = _UxGT("Lézer Ki"); + PROGMEM Language_Str MSG_LASER_ON = _UxGT("Lézer Be"); + PROGMEM Language_Str MSG_LASER_POWER = _UxGT("Lézer Teljesítmény"); + PROGMEM Language_Str MSG_SPINDLE_MENU = _UxGT("Orsó Vezérlés"); + PROGMEM Language_Str MSG_SPINDLE_OFF = _UxGT("Orsó Ki"); + PROGMEM Language_Str MSG_SPINDLE_ON = _UxGT("Orsó Be"); + PROGMEM Language_Str MSG_SPINDLE_POWER = _UxGT("Orsó Teljesítmény"); + PROGMEM Language_Str MSG_SPINDLE_REVERSE = _UxGT("Orsó Hátra"); + PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Bekapcsolás"); + PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("Kikapcsolás"); + PROGMEM Language_Str MSG_EXTRUDE = _UxGT("Extrudál"); + PROGMEM Language_Str MSG_RETRACT = _UxGT("Visszahúz"); + PROGMEM Language_Str MSG_MOVE_AXIS = _UxGT("Tengelyek Mozgatása"); + PROGMEM Language_Str MSG_BED_LEVELING = _UxGT("Ágy Szintezés"); + PROGMEM Language_Str MSG_LEVEL_BED = _UxGT("Ágy szintezése"); + PROGMEM Language_Str MSG_LEVEL_CORNERS = _UxGT("Sarok szint"); + PROGMEM Language_Str MSG_NEXT_CORNER = _UxGT("Következö sarok"); + PROGMEM Language_Str MSG_MESH_EDITOR = _UxGT("Háló Szerkesztö"); + PROGMEM Language_Str MSG_EDIT_MESH = _UxGT("Háló Szerkesztése"); + PROGMEM Language_Str MSG_EDITING_STOPPED = _UxGT("Háló Szerk. Állj"); + PROGMEM Language_Str MSG_PROBING_MESH = _UxGT("Próbapont"); + PROGMEM Language_Str MSG_MESH_X = _UxGT("Index X"); + PROGMEM Language_Str MSG_MESH_Y = _UxGT("Index Y"); + PROGMEM Language_Str MSG_MESH_EDIT_Z = _UxGT("Z Érték"); + PROGMEM Language_Str MSG_USER_MENU = _UxGT("Egyéni Parancs"); + PROGMEM Language_Str MSG_M48_TEST = _UxGT("M48 Probe Teszt"); + PROGMEM Language_Str MSG_M48_POINT = _UxGT("M48 Pont"); + PROGMEM Language_Str MSG_M48_DEVIATION = _UxGT("Eltérés"); + PROGMEM Language_Str MSG_IDEX_MENU = _UxGT("IDEX Mód"); + PROGMEM Language_Str MSG_OFFSETS_MENU = _UxGT("Eszköz Eltolás"); + PROGMEM Language_Str MSG_IDEX_MODE_AUTOPARK = _UxGT("Auto-Parkolás"); + PROGMEM Language_Str MSG_IDEX_MODE_DUPLICATE = _UxGT("Duplikálás"); + PROGMEM Language_Str MSG_IDEX_MODE_MIRRORED_COPY = _UxGT("Tükrözött másolás"); + PROGMEM Language_Str MSG_IDEX_MODE_FULL_CTRL = _UxGT("Teljes felügyelet"); + PROGMEM Language_Str MSG_HOTEND_OFFSET_X = _UxGT("2. fúvóka X"); + PROGMEM Language_Str MSG_HOTEND_OFFSET_Y = _UxGT("2. fúvóka Y"); + PROGMEM Language_Str MSG_HOTEND_OFFSET_Z = _UxGT("2. fúvóka Z"); + PROGMEM Language_Str MSG_UBL_DOING_G29 = _UxGT("Szintezz! G29"); + PROGMEM Language_Str MSG_UBL_TOOLS = _UxGT("UBL Eszköz"); + PROGMEM Language_Str MSG_UBL_LEVEL_BED = _UxGT("Egységes Ágy Szint"); + PROGMEM Language_Str MSG_LCD_TILTING_MESH = _UxGT("Döntési Pont"); + PROGMEM Language_Str MSG_UBL_MANUAL_MESH = _UxGT("Kézi Háló Építés"); + PROGMEM Language_Str MSG_UBL_BC_INSERT = _UxGT("Tégy alátétet és mérj"); + PROGMEM Language_Str MSG_UBL_BC_INSERT2 = _UxGT("Mérés"); + PROGMEM Language_Str MSG_UBL_BC_REMOVE = _UxGT("Üres ágyat mérj"); + PROGMEM Language_Str MSG_UBL_MOVING_TO_NEXT = _UxGT("Továbblépés"); + PROGMEM Language_Str MSG_UBL_ACTIVATE_MESH = _UxGT("UBL Aktivál"); + PROGMEM Language_Str MSG_UBL_DEACTIVATE_MESH = _UxGT("UBL Deaktivál"); + PROGMEM Language_Str MSG_UBL_SET_TEMP_BED = _UxGT("Ágy Höfok"); + PROGMEM Language_Str MSG_UBL_BED_TEMP_CUSTOM = _UxGT("Ágy Höfok"); + PROGMEM Language_Str MSG_UBL_SET_TEMP_HOTEND = _UxGT("Fúvóka Höfok"); + PROGMEM Language_Str MSG_UBL_HOTEND_TEMP_CUSTOM = _UxGT("Fúvóka Höfok"); + PROGMEM Language_Str MSG_UBL_MESH_EDIT = _UxGT("Háló Szerkesztés"); + PROGMEM Language_Str MSG_UBL_EDIT_CUSTOM_MESH = _UxGT("Egyéni Háló Szerkesztés"); + PROGMEM Language_Str MSG_UBL_FINE_TUNE_MESH = _UxGT("Finomított Háló"); + PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("Háló Kész"); + PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("Egyéni Háló Építés"); + PROGMEM Language_Str MSG_UBL_BUILD_MESH_MENU = _UxGT("Háló Építés"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_UBL_BUILD_MESH_M = _UxGT("Háló Építés ($)"); + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("Háló Elfogadás ($)"); + #endif + PROGMEM Language_Str MSG_UBL_BUILD_COLD_MESH = _UxGT("Hideg Háló Építés"); + PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_ADJUST = _UxGT("AHáló Magasság Állítása"); + PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_AMOUNT = _UxGT("Összmagasság"); + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_MENU = _UxGT("Háló Elfogadás"); + PROGMEM Language_Str MSG_UBL_VALIDATE_CUSTOM_MESH = _UxGT("Valódi Háló Elfogadása"); + PROGMEM Language_Str MSG_G26_HEATING_BED = _UxGT("G26 Ágy Fűtés"); + PROGMEM Language_Str MSG_G26_HEATING_NOZZLE = _UxGT("G26 Fúvóka Fűtés"); + PROGMEM Language_Str MSG_G26_MANUAL_PRIME = _UxGT("Kézi alapozás..."); + PROGMEM Language_Str MSG_G26_FIXED_LENGTH = _UxGT("Fix hosszúságú alap"); + PROGMEM Language_Str MSG_G26_PRIME_DONE = _UxGT("Alapozás Kész"); + PROGMEM Language_Str MSG_G26_CANCELED = _UxGT("G26 Törölve"); + PROGMEM Language_Str MSG_G26_LEAVING = _UxGT("Kilépö G26"); + PROGMEM Language_Str MSG_UBL_CONTINUE_MESH = _UxGT("Ágy Háló Folyt."); + PROGMEM Language_Str MSG_UBL_MESH_LEVELING = _UxGT("Háló Szintezés"); + PROGMEM Language_Str MSG_UBL_3POINT_MESH_LEVELING = _UxGT("3-Pontos Szintezés"); + PROGMEM Language_Str MSG_UBL_GRID_MESH_LEVELING = _UxGT("Rács Szintezés"); + PROGMEM Language_Str MSG_UBL_MESH_LEVEL = _UxGT("Háló Szint"); + PROGMEM Language_Str MSG_UBL_SIDE_POINTS = _UxGT("Oldal pontok"); + PROGMEM Language_Str MSG_UBL_MAP_TYPE = _UxGT("Térkép Típus"); + PROGMEM Language_Str MSG_UBL_OUTPUT_MAP = _UxGT("Háló Térkép Kimenet"); + PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_HOST = _UxGT("Host Kimenet"); + PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_CSV = _UxGT("CSV Kimenet"); + PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_BACKUP = _UxGT("Nyomtató Backup Ki"); + PROGMEM Language_Str MSG_UBL_INFO_UBL = _UxGT("UBL Infó Kimenet"); + PROGMEM Language_Str MSG_UBL_FILLIN_AMOUNT = _UxGT("Kitöltési Költség"); + PROGMEM Language_Str MSG_UBL_MANUAL_FILLIN = _UxGT("Kézi Kitöltés"); + PROGMEM Language_Str MSG_UBL_SMART_FILLIN = _UxGT("Okos Kitöltés"); + PROGMEM Language_Str MSG_UBL_FILLIN_MESH = _UxGT("Háló Kitöltés"); + PROGMEM Language_Str MSG_UBL_INVALIDATE_ALL = _UxGT("Minden Érvénytelen"); + PROGMEM Language_Str MSG_UBL_INVALIDATE_CLOSEST = _UxGT("Közelebbi Érvénytelen"); + PROGMEM Language_Str MSG_UBL_FINE_TUNE_ALL = _UxGT("Mindet Finomhangolja"); + PROGMEM Language_Str MSG_UBL_FINE_TUNE_CLOSEST = _UxGT("Közelebbi Finomhangolása"); + PROGMEM Language_Str MSG_UBL_STORAGE_MESH_MENU = _UxGT("Háló Tárolás"); + PROGMEM Language_Str MSG_UBL_STORAGE_SLOT = _UxGT("Memória Foglalat"); + PROGMEM Language_Str MSG_UBL_LOAD_MESH = _UxGT("Ágy háló Betöltés"); + PROGMEM Language_Str MSG_UBL_SAVE_MESH = _UxGT("Ágy háló Mentés"); + PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("M117 Háló %i Betöltve"); + PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("M117 Háló %i Mentve"); + PROGMEM Language_Str MSG_UBL_NO_STORAGE = _UxGT("Nincs tároló"); + PROGMEM Language_Str MSG_UBL_SAVE_ERROR = _UxGT("Hiba: UBL Mentés"); + PROGMEM Language_Str MSG_UBL_RESTORE_ERROR = _UxGT("Hiba: UBL Visszaáll"); + PROGMEM Language_Str MSG_UBL_Z_OFFSET = _UxGT("Z-Eltolás: "); + PROGMEM Language_Str MSG_UBL_Z_OFFSET_STOPPED = _UxGT("Z-Eltolás Leállítva"); + PROGMEM Language_Str MSG_UBL_STEP_BY_STEP_MENU = _UxGT("Lépésröl Lépésre UBL"); + PROGMEM Language_Str MSG_UBL_1_BUILD_COLD_MESH = _UxGT("1. Hideg Háló Készítés"); + PROGMEM Language_Str MSG_UBL_2_SMART_FILLIN = _UxGT("2. Inteligens Kitöltés"); + PROGMEM Language_Str MSG_UBL_3_VALIDATE_MESH_MENU = _UxGT("3. Háló Érvényesítés"); + PROGMEM Language_Str MSG_UBL_4_FINE_TUNE_ALL = _UxGT("4. Minden Finomítása"); + PROGMEM Language_Str MSG_UBL_5_VALIDATE_MESH_MENU = _UxGT("5. Háló Érvényesítés"); + PROGMEM Language_Str MSG_UBL_6_FINE_TUNE_ALL = _UxGT("6. Minden Finomítása"); + PROGMEM Language_Str MSG_UBL_7_SAVE_MESH = _UxGT("7. Ágy Háló Mentése"); + + PROGMEM Language_Str MSG_LED_CONTROL = _UxGT("LED Vezérlés"); + PROGMEM Language_Str MSG_LEDS = _UxGT("Világítás"); + PROGMEM Language_Str MSG_LED_PRESETS = _UxGT("Beállított Színek"); + PROGMEM Language_Str MSG_SET_LEDS_RED = _UxGT("Piros"); + PROGMEM Language_Str MSG_SET_LEDS_ORANGE = _UxGT("Narancs"); + PROGMEM Language_Str MSG_SET_LEDS_YELLOW = _UxGT("Sárga"); + PROGMEM Language_Str MSG_SET_LEDS_GREEN = _UxGT("Zöld"); + PROGMEM Language_Str MSG_SET_LEDS_BLUE = _UxGT("Kék"); + PROGMEM Language_Str MSG_SET_LEDS_INDIGO = _UxGT("Indigó"); + PROGMEM Language_Str MSG_SET_LEDS_VIOLET = _UxGT("Viola"); + PROGMEM Language_Str MSG_SET_LEDS_WHITE = _UxGT("Fehér"); + PROGMEM Language_Str MSG_SET_LEDS_DEFAULT = _UxGT("Alapérték"); + PROGMEM Language_Str MSG_CUSTOM_LEDS = _UxGT("Egyéni Szín"); + PROGMEM Language_Str MSG_INTENSITY_R = _UxGT("Piros Intenzitás"); + PROGMEM Language_Str MSG_INTENSITY_G = _UxGT("Zöld Intenzitás"); + PROGMEM Language_Str MSG_INTENSITY_B = _UxGT("Kék Intenzitás"); + PROGMEM Language_Str MSG_INTENSITY_W = _UxGT("Fehér Intenzitás"); + PROGMEM Language_Str MSG_LED_BRIGHTNESS = _UxGT("Fényerö"); + + PROGMEM Language_Str MSG_MOVING = _UxGT("Mozgás..."); + PROGMEM Language_Str MSG_FREE_XY = _UxGT("XY Szabad"); + PROGMEM Language_Str MSG_MOVE_X = _UxGT("X Mozgás"); + PROGMEM Language_Str MSG_MOVE_Y = _UxGT("Y Mozgás"); + PROGMEM Language_Str MSG_MOVE_Z = _UxGT("Z Mozgás"); + PROGMEM Language_Str MSG_MOVE_E = _UxGT("Adagoló"); + PROGMEM Language_Str MSG_MOVE_EN = _UxGT("Adagoló *"); + PROGMEM Language_Str MSG_HOTEND_TOO_COLD = _UxGT("A fúvóka túl hideg"); + PROGMEM Language_Str MSG_MOVE_Z_DIST = _UxGT("Mozgás %smm"); + PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Mozgás 0.1mm"); + PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Mozgás 1mm"); + PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Mozgás 10mm"); + PROGMEM Language_Str MSG_SPEED = _UxGT("Sebesség"); + PROGMEM Language_Str MSG_BED_Z = _UxGT("Z ágy"); + PROGMEM Language_Str MSG_NOZZLE = _UxGT("Fúvóka"); + PROGMEM Language_Str MSG_NOZZLE_N = _UxGT("Fúvóka ~"); + PROGMEM Language_Str MSG_NOZZLE_PARKED = _UxGT("Fej Parkolva"); + PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("Fej Készenlétbe"); + PROGMEM Language_Str MSG_BED = _UxGT("Ágy"); + PROGMEM Language_Str MSG_CHAMBER = _UxGT("Burkolat"); + PROGMEM Language_Str MSG_FAN_SPEED = _UxGT("Hütés sebesség"); + PROGMEM Language_Str MSG_FAN_SPEED_N = _UxGT("Hütés sebesség ="); + PROGMEM Language_Str MSG_STORED_FAN_N = _UxGT("Tárolt Hütés ="); + PROGMEM Language_Str MSG_EXTRA_FAN_SPEED = _UxGT("Extra hütés sebesség"); + PROGMEM Language_Str MSG_EXTRA_FAN_SPEED_N = _UxGT("Extra hütés sebesség ="); + PROGMEM Language_Str MSG_CONTROLLER_FAN = _UxGT("Hűtésvezérlés"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_IDLE_SPEED = _UxGT("Alapjárat"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_AUTO_ON = _UxGT("Automatikus Mód"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_SPEED = _UxGT("Aktív Sebesség"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_DURATION = _UxGT("Készenlét"); + PROGMEM Language_Str MSG_FLOW = _UxGT("Folyás"); + PROGMEM Language_Str MSG_FLOW_N = _UxGT("Folyás ~"); + PROGMEM Language_Str MSG_CONTROL = _UxGT("Konfiguráció"); + PROGMEM Language_Str MSG_MIN = " " LCD_STR_THERMOMETER _UxGT(" Minimum"); + PROGMEM Language_Str MSG_MAX = " " LCD_STR_THERMOMETER _UxGT(" Maximum"); + PROGMEM Language_Str MSG_FACTOR = " " LCD_STR_THERMOMETER _UxGT(" Tényezö"); + PROGMEM Language_Str MSG_AUTOTEMP = _UxGT("Automata Höfok"); + PROGMEM Language_Str MSG_LCD_ON = _UxGT("Be"); + PROGMEM Language_Str MSG_LCD_OFF = _UxGT("Ki"); + PROGMEM Language_Str MSG_PID_AUTOTUNE = _UxGT("PID Hangolás"); + PROGMEM Language_Str MSG_PID_AUTOTUNE_E = _UxGT("PID Hangolás *"); + PROGMEM Language_Str MSG_PID_AUTOTUNE_DONE = _UxGT("PID hangolás kész"); + PROGMEM Language_Str MSG_PID_BAD_EXTRUDER_NUM = _UxGT("Hangolási hiba. Rossz Adagoló."); + PROGMEM Language_Str MSG_PID_TEMP_TOO_HIGH = _UxGT("Hangolási hiba. Magas hömérséklet."); + PROGMEM Language_Str MSG_PID_TIMEOUT = _UxGT("Hangolási hiba! Idötúllépés."); + PROGMEM Language_Str MSG_PID_P = _UxGT("PID-P"); + PROGMEM Language_Str MSG_PID_P_E = _UxGT("PID-P *"); + PROGMEM Language_Str MSG_PID_I = _UxGT("PID-I"); + PROGMEM Language_Str MSG_PID_I_E = _UxGT("PID-I *"); + PROGMEM Language_Str MSG_PID_D = _UxGT("PID-D"); + PROGMEM Language_Str MSG_PID_D_E = _UxGT("PID-D *"); + PROGMEM Language_Str MSG_PID_C = _UxGT("PID-C"); + PROGMEM Language_Str MSG_PID_C_E = _UxGT("PID-C *"); + PROGMEM Language_Str MSG_PID_F = _UxGT("PID-F"); + PROGMEM Language_Str MSG_PID_F_E = _UxGT("PID-F *"); + PROGMEM Language_Str MSG_SELECT = _UxGT("Kiválaszt"); + PROGMEM Language_Str MSG_SELECT_E = _UxGT("Kiválaszt *"); + PROGMEM Language_Str MSG_ACC = _UxGT("Gyorsítás"); + PROGMEM Language_Str MSG_JERK = _UxGT("Rántás"); + PROGMEM Language_Str MSG_VA_JERK = LCD_STR_A _UxGT(" Ránt. Seb."); + PROGMEM Language_Str MSG_VB_JERK = LCD_STR_B _UxGT(" Ránt. Seb."); + PROGMEM Language_Str MSG_VC_JERK = LCD_STR_C _UxGT(" Ránt. Seb."); + PROGMEM Language_Str MSG_VE_JERK = _UxGT("E Ránt. Seb."); + PROGMEM Language_Str MSG_JUNCTION_DEVIATION = _UxGT("Csomopont Eltérés"); + PROGMEM Language_Str MSG_VELOCITY = _UxGT("Sebesség"); + PROGMEM Language_Str MSG_VMAX_A = _UxGT("Max Sebesség ") LCD_STR_A; + PROGMEM Language_Str MSG_VMAX_B = _UxGT("Max Sebesség ") LCD_STR_B; + PROGMEM Language_Str MSG_VMAX_C = _UxGT("Max Sebesség ") LCD_STR_C; + PROGMEM Language_Str MSG_VMAX_E = _UxGT("Max Sebesség ") LCD_STR_E; + PROGMEM Language_Str MSG_VMAX_EN = _UxGT("Max Sebesség *"); + PROGMEM Language_Str MSG_VMIN = _UxGT("Min Sebesség"); + PROGMEM Language_Str MSG_VTRAV_MIN = _UxGT("Min Utazó.seb."); + PROGMEM Language_Str MSG_ACCELERATION = _UxGT("Gyorsulás"); + PROGMEM Language_Str MSG_AMAX_A = _UxGT("Max Gyors. ") LCD_STR_A; + PROGMEM Language_Str MSG_AMAX_B = _UxGT("Max Gyors. ") LCD_STR_B; + PROGMEM Language_Str MSG_AMAX_C = _UxGT("Max Gyors. ") LCD_STR_C; + PROGMEM Language_Str MSG_AMAX_E = _UxGT("Max Gyors. ") LCD_STR_E; + PROGMEM Language_Str MSG_AMAX_EN = _UxGT("Max Gyorsulás *"); + PROGMEM Language_Str MSG_A_RETRACT = _UxGT("Visszahúzás"); + PROGMEM Language_Str MSG_A_TRAVEL = _UxGT("Utazás"); + PROGMEM Language_Str MSG_XY_FREQUENCY_LIMIT = _UxGT("Max Frekvencia"); + PROGMEM Language_Str MSG_XY_FREQUENCY_FEEDRATE = _UxGT("Min Elötolás"); + PROGMEM Language_Str MSG_STEPS_PER_MM = _UxGT("Lépés/mm"); + PROGMEM Language_Str MSG_A_STEPS = LCD_STR_A _UxGT(" lépés/mm"); + PROGMEM Language_Str MSG_B_STEPS = LCD_STR_B _UxGT(" lépés/mm"); + PROGMEM Language_Str MSG_C_STEPS = LCD_STR_C _UxGT(" lépés/mm"); + PROGMEM Language_Str MSG_E_STEPS = _UxGT("E lépés/mm"); + PROGMEM Language_Str MSG_EN_STEPS = _UxGT("*lépés/mm"); + PROGMEM Language_Str MSG_TEMPERATURE = _UxGT("Höfok"); + PROGMEM Language_Str MSG_MOTION = _UxGT("Mozgatások"); + PROGMEM Language_Str MSG_FILAMENT = _UxGT("Nyomtatószál"); + PROGMEM Language_Str MSG_VOLUMETRIC_ENABLED = _UxGT("E mm³-ben"); + PROGMEM Language_Str MSG_FILAMENT_DIAM = _UxGT("Szál. Átm."); + PROGMEM Language_Str MSG_FILAMENT_DIAM_E = _UxGT("Szál. Átm. *"); + PROGMEM Language_Str MSG_FILAMENT_UNLOAD = _UxGT("Kiadás mm"); + PROGMEM Language_Str MSG_FILAMENT_LOAD = _UxGT("Betöltés mm"); + PROGMEM Language_Str MSG_ADVANCE_K = _UxGT("Haladó K"); + PROGMEM Language_Str MSG_ADVANCE_K_E = _UxGT("Haladó K *"); + PROGMEM Language_Str MSG_CONTRAST = _UxGT("LCD kontraszt"); + PROGMEM Language_Str MSG_STORE_EEPROM = _UxGT("Mentés EEPROM"); + PROGMEM Language_Str MSG_LOAD_EEPROM = _UxGT("Betöltés EEPROM"); + PROGMEM Language_Str MSG_RESTORE_DEFAULTS = _UxGT("Alapértelmezett"); + PROGMEM Language_Str MSG_INIT_EEPROM = _UxGT("EEPROM Inicializálás"); + PROGMEM Language_Str MSG_ERR_EEPROM_CRC = _UxGT("Hiba: EEPROM CRC"); + PROGMEM Language_Str MSG_ERR_EEPROM_INDEX = _UxGT("Hiba: EEPROM Index"); + PROGMEM Language_Str MSG_ERR_EEPROM_VERSION = _UxGT("Hiba: EEPROM Verzió"); + PROGMEM Language_Str MSG_SETTINGS_STORED = _UxGT("Beállítások Mentve"); + PROGMEM Language_Str MSG_MEDIA_UPDATE = _UxGT("Tároló Frissítés"); + PROGMEM Language_Str MSG_RESET_PRINTER = _UxGT("Nyomtató Újraindítása"); + PROGMEM Language_Str MSG_REFRESH = LCD_STR_REFRESH _UxGT("Frissítés"); + PROGMEM Language_Str MSG_INFO_SCREEN = _UxGT(""); + PROGMEM Language_Str MSG_PREPARE = _UxGT("Vezérlés"); + PROGMEM Language_Str MSG_TUNE = _UxGT("Hangolás"); + PROGMEM Language_Str MSG_START_PRINT = _UxGT("Nyomtatás Indítása"); + PROGMEM Language_Str MSG_BUTTON_NEXT = _UxGT("Tovább"); + PROGMEM Language_Str MSG_BUTTON_INIT = _UxGT("Kezdet"); + PROGMEM Language_Str MSG_BUTTON_STOP = _UxGT("Állj"); + PROGMEM Language_Str MSG_BUTTON_PRINT = _UxGT("Nyomtatás"); + PROGMEM Language_Str MSG_BUTTON_RESET = _UxGT("Újraindítás"); + PROGMEM Language_Str MSG_BUTTON_CANCEL = _UxGT("Mégse"); + PROGMEM Language_Str MSG_BUTTON_DONE = _UxGT("Kész"); + PROGMEM Language_Str MSG_BUTTON_BACK = _UxGT("Vissza"); + PROGMEM Language_Str MSG_BUTTON_PROCEED = _UxGT("Folytatás"); + PROGMEM Language_Str MSG_PAUSING = _UxGT("Szüneteltetve..."); + PROGMEM Language_Str MSG_PAUSE_PRINT = _UxGT("Nyomtatás Szünetelés"); + PROGMEM Language_Str MSG_RESUME_PRINT = _UxGT("Nyomtatás folytatása"); + PROGMEM Language_Str MSG_STOP_PRINT = _UxGT("Nyomtatás leállítása"); + PROGMEM Language_Str MSG_PRINTING_OBJECT = _UxGT("Objektum Nyomtatása"); + PROGMEM Language_Str MSG_CANCEL_OBJECT = _UxGT("Objektum Törlése"); + PROGMEM Language_Str MSG_CANCEL_OBJECT_N = _UxGT("Objektum Törlése ="); + PROGMEM Language_Str MSG_OUTAGE_RECOVERY = _UxGT("Kiesés Helyreáll."); + PROGMEM Language_Str MSG_MEDIA_MENU = _UxGT("Nyomtatás Tárolóról"); + PROGMEM Language_Str MSG_NO_MEDIA = _UxGT("Nincs Tároló"); + PROGMEM Language_Str MSG_DWELL = _UxGT("Alvás..."); + PROGMEM Language_Str MSG_USERWAIT = _UxGT("Katt a folytatáshoz..."); + PROGMEM Language_Str MSG_PRINT_PAUSED = _UxGT("Nyomtatás szünetelve"); + PROGMEM Language_Str MSG_PRINTING = _UxGT("Nyomtatás..."); + PROGMEM Language_Str MSG_PRINT_ABORTED = _UxGT("Nyomtatás leállítva"); + PROGMEM Language_Str MSG_PRINT_DONE = _UxGT("Nyomtatás Kész"); + PROGMEM Language_Str MSG_NO_MOVE = _UxGT("Nincs mozgás."); + PROGMEM Language_Str MSG_KILLED = _UxGT("HALOTT! "); + PROGMEM Language_Str MSG_STOPPED = _UxGT("MEGÁLLT! "); + PROGMEM Language_Str MSG_CONTROL_RETRACT = _UxGT("Visszahúzás mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("Visszahúzás Cs. mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("Viszahúzás"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_ZHOP = _UxGT("Ugrás mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("Visszah.helyre mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("Csere.Visszah.helyre mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("Unretract V"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAPF = _UxGT("S UnRet V"); + PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("AutoVisszah."); + PROGMEM Language_Str MSG_FILAMENT_SWAP_LENGTH = _UxGT("Visszahúzás Távolság"); + PROGMEM Language_Str MSG_FILAMENT_SWAP_EXTRA = _UxGT("Extra Csere"); + PROGMEM Language_Str MSG_FILAMENT_PURGE_LENGTH = _UxGT("Tisztítási Távolság"); + PROGMEM Language_Str MSG_TOOL_CHANGE = _UxGT("Szerszámcsere"); + PROGMEM Language_Str MSG_TOOL_CHANGE_ZLIFT = _UxGT("Z Emelés"); + PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPEED = _UxGT("Fösebesség"); + PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPEED = _UxGT("Visszah. Sebesség"); + PROGMEM Language_Str MSG_FILAMENT_PARK_ENABLED = _UxGT("Fej Parkolás"); + PROGMEM Language_Str MSG_SINGLENOZZLE_UNRETRACT_SPEED = _UxGT("Visszahúzás Sebesség"); + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_SPEED = _UxGT("FAN Sebesség"); + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_TIME = _UxGT("FAN idö"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_ON = _UxGT("Auto BE"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_OFF = _UxGT("Auto KI"); + PROGMEM Language_Str MSG_TOOL_MIGRATION = _UxGT("Szerszámcsere"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_AUTO = _UxGT("Automata Csere"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_END = _UxGT("Utolsó Adagoló"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_SWAP = _UxGT("Csere *"); + PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("Szál csere"); + PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Szál csere *"); + PROGMEM Language_Str MSG_FILAMENTLOAD = _UxGT("Szál betöltés"); + PROGMEM Language_Str MSG_FILAMENTLOAD_E = _UxGT("Szál betöltés *"); + PROGMEM Language_Str MSG_FILAMENTUNLOAD = _UxGT("Szál eltávolítás"); + PROGMEM Language_Str MSG_FILAMENTUNLOAD_E = _UxGT("Szál eltávolítás *"); + PROGMEM Language_Str MSG_FILAMENTUNLOAD_ALL = _UxGT("Mindet Eltávolít"); + PROGMEM Language_Str MSG_ATTACH_MEDIA = _UxGT("Tároló"); + PROGMEM Language_Str MSG_CHANGE_MEDIA = _UxGT("Tároló csere"); + PROGMEM Language_Str MSG_RELEASE_MEDIA = _UxGT("Tároló Kiadása"); + PROGMEM Language_Str MSG_ZPROBE_OUT = _UxGT("Z szonda tálcán kivül"); + PROGMEM Language_Str MSG_SKEW_FACTOR = _UxGT("Ferdeség Faktor"); + PROGMEM Language_Str MSG_BLTOUCH = _UxGT("BLTouch"); + PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("Önteszt"); + PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("Visszaállítás"); + PROGMEM Language_Str MSG_BLTOUCH_STOW = _UxGT("Elhelyez"); + PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("Telepít"); + PROGMEM Language_Str MSG_BLTOUCH_SW_MODE = _UxGT("SW-Mód"); + PROGMEM Language_Str MSG_BLTOUCH_5V_MODE = _UxGT("5V-Mód"); + PROGMEM Language_Str MSG_BLTOUCH_OD_MODE = _UxGT("OD-Mód"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE = _UxGT("Módok"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_5V = _UxGT("BLTouch 5V Mód"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_OD = _UxGT("BLTouch OD Mód"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_ECHO = _UxGT("Jelentés"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_CHANGE = _UxGT("VESZÉLY: A rossz beállítások kárt okozhatnak! Biztos továbblép?"); + PROGMEM Language_Str MSG_TOUCHMI_PROBE = _UxGT("TouchMI"); + PROGMEM Language_Str MSG_TOUCHMI_INIT = _UxGT("Kezd TouchMI"); + PROGMEM Language_Str MSG_TOUCHMI_ZTEST = _UxGT("Z Offset Teszt"); + PROGMEM Language_Str MSG_TOUCHMI_SAVE = _UxGT("Mentés"); + PROGMEM Language_Str MSG_MANUAL_DEPLOY_TOUCHMI = _UxGT("TouchMI Használ"); + PROGMEM Language_Str MSG_MANUAL_DEPLOY = _UxGT("Z-Probe Használ"); + PROGMEM Language_Str MSG_MANUAL_STOW = _UxGT("Z-Probe Elhelyezés"); + PROGMEM Language_Str MSG_HOME_FIRST = _UxGT("Elsö %s%s%s Kell"); + PROGMEM Language_Str MSG_ZPROBE_OFFSETS = _UxGT("Szonda Eltolások"); + PROGMEM Language_Str MSG_ZPROBE_XOFFSET = _UxGT("Szonda X Eltolás"); + PROGMEM Language_Str MSG_ZPROBE_YOFFSET = _UxGT("Szonda Y Eltolás"); + PROGMEM Language_Str MSG_ZPROBE_ZOFFSET = _UxGT("Szonda Z Eltolás"); + PROGMEM Language_Str MSG_BABYSTEP_X = _UxGT("Mikrolépés X"); + PROGMEM Language_Str MSG_BABYSTEP_Y = _UxGT("Mikrolépés Y"); + PROGMEM Language_Str MSG_BABYSTEP_Z = _UxGT("Mikrolépés Z"); + PROGMEM Language_Str MSG_BABYSTEP_TOTAL = _UxGT("Teljes"); + PROGMEM Language_Str MSG_ENDSTOP_ABORT = _UxGT("Végállás megszakítva!"); + PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("Fütés hiba!"); + PROGMEM Language_Str MSG_ERR_REDUNDANT_TEMP = _UxGT("Hiba: SZÜKSÉGTELEN HÖFOK"); + PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("FÜTÉS KIMARADÁS"); + PROGMEM Language_Str MSG_THERMAL_RUNAWAY_BED = _UxGT("ÁGY FÜTÉS KIMARADÁS"); + PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER = _UxGT("KAMRA FÜTÉS KIMARADÁS"); + PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("Hiba: MAX Höfok"); + PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("Hiba: MIN Höfok"); + PROGMEM Language_Str MSG_HALTED = _UxGT("A NYOMTATÓ LEFAGYOTT"); + PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("Indítsd újra!"); + PROGMEM Language_Str MSG_SHORT_DAY = _UxGT("n"); // Csak egy karakter + PROGMEM Language_Str MSG_SHORT_HOUR = _UxGT("ó"); // Csak egy karakter + PROGMEM Language_Str MSG_SHORT_MINUTE = _UxGT("p"); // Csak egy karakter + PROGMEM Language_Str MSG_HEATING = _UxGT("Fütés..."); + PROGMEM Language_Str MSG_COOLING = _UxGT("Hütés..."); + PROGMEM Language_Str MSG_BED_HEATING = _UxGT("Ágy fütés..."); + PROGMEM Language_Str MSG_BED_COOLING = _UxGT("Ágy hütés..."); + PROGMEM Language_Str MSG_CHAMBER_HEATING = _UxGT("Kamra fütés..."); + PROGMEM Language_Str MSG_CHAMBER_COOLING = _UxGT("Kamra hütés..."); + PROGMEM Language_Str MSG_DELTA_CALIBRATE = _UxGT("Delta Kalibráció"); + PROGMEM Language_Str MSG_DELTA_CALIBRATE_X = _UxGT("X Kalibrálás"); + PROGMEM Language_Str MSG_DELTA_CALIBRATE_Y = _UxGT("Y Kalibrálás"); + PROGMEM Language_Str MSG_DELTA_CALIBRATE_Z = _UxGT("Z Kalibrálás"); + PROGMEM Language_Str MSG_DELTA_CALIBRATE_CENTER = _UxGT("Központ Kalibrálás"); + PROGMEM Language_Str MSG_DELTA_SETTINGS = _UxGT("Delta Beállítások"); + PROGMEM Language_Str MSG_DELTA_AUTO_CALIBRATE = _UxGT("Auto Kalibráció"); + PROGMEM Language_Str MSG_DELTA_HEIGHT_CALIBRATE = _UxGT("Delta Magasság Kalib."); + PROGMEM Language_Str MSG_DELTA_Z_OFFSET_CALIBRATE = _UxGT("Z Szonda Eltolás"); + PROGMEM Language_Str MSG_DELTA_DIAG_ROD = _UxGT("Diag Rúd"); + PROGMEM Language_Str MSG_DELTA_HEIGHT = _UxGT("Magasság"); + PROGMEM Language_Str MSG_DELTA_RADIUS = _UxGT("Sugár"); + PROGMEM Language_Str MSG_INFO_MENU = _UxGT("A Nyomtatóról"); + PROGMEM Language_Str MSG_INFO_PRINTER_MENU = _UxGT("Nyomtató Infó"); + PROGMEM Language_Str MSG_3POINT_LEVELING = _UxGT("3-Pontos Szintezés"); + PROGMEM Language_Str MSG_LINEAR_LEVELING = _UxGT("Lineáris Szintezés"); + PROGMEM Language_Str MSG_BILINEAR_LEVELING = _UxGT("Bilineáris Szintezés"); + PROGMEM Language_Str MSG_UBL_LEVELING = _UxGT("Egységes Ágy Szintezés"); + PROGMEM Language_Str MSG_MESH_LEVELING = _UxGT("Háló Szintezés"); + PROGMEM Language_Str MSG_INFO_STATS_MENU = _UxGT("Statisztikák"); + PROGMEM Language_Str MSG_INFO_BOARD_MENU = _UxGT("Alaplap Infó"); + PROGMEM Language_Str MSG_INFO_THERMISTOR_MENU = _UxGT("Termisztorok"); + PROGMEM Language_Str MSG_INFO_EXTRUDERS = _UxGT("Adagolók"); + PROGMEM Language_Str MSG_INFO_BAUDRATE = _UxGT("Átviteli sebesség"); + PROGMEM Language_Str MSG_INFO_PROTOCOL = _UxGT("Protokoll"); + PROGMEM Language_Str MSG_INFO_RUNAWAY_OFF = _UxGT("Futáselemzés: KI"); + PROGMEM Language_Str MSG_INFO_RUNAWAY_ON = _UxGT("Futáselemzés: BE"); + + PROGMEM Language_Str MSG_CASE_LIGHT = _UxGT("Munkalámpa"); + PROGMEM Language_Str MSG_CASE_LIGHT_BRIGHTNESS = _UxGT("Fényerösség"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("HELYTELEN NYOMTATÓ"); + + #if LCD_WIDTH >= 20 + PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Nyomtatás Számláló"); + PROGMEM Language_Str MSG_INFO_COMPLETED_PRINTS = _UxGT("Befejezett"); + PROGMEM Language_Str MSG_INFO_PRINT_TIME = _UxGT("Összes nyomtatási idö"); + PROGMEM Language_Str MSG_INFO_PRINT_LONGEST = _UxGT("Leghosszabb munkaidö"); + PROGMEM Language_Str MSG_INFO_PRINT_FILAMENT = _UxGT("Összes anyag"); + #else + PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Nyomtatások"); + PROGMEM Language_Str MSG_INFO_COMPLETED_PRINTS = _UxGT("Befejezett"); + PROGMEM Language_Str MSG_INFO_PRINT_TIME = _UxGT("Összes"); + PROGMEM Language_Str MSG_INFO_PRINT_LONGEST = _UxGT("Leghosszabb"); + PROGMEM Language_Str MSG_INFO_PRINT_FILAMENT = _UxGT("Kiadott"); + #endif + + PROGMEM Language_Str MSG_INFO_MIN_TEMP = _UxGT("Min Höfok"); + PROGMEM Language_Str MSG_INFO_MAX_TEMP = _UxGT("Max Höfok"); + PROGMEM Language_Str MSG_INFO_PSU = _UxGT("PSU"); + PROGMEM Language_Str MSG_DRIVE_STRENGTH = _UxGT("Meghajtási Erö"); + PROGMEM Language_Str MSG_DAC_PERCENT_X = _UxGT("X Meghajtó %"); + PROGMEM Language_Str MSG_DAC_PERCENT_Y = _UxGT("Y Meghajtó %"); + PROGMEM Language_Str MSG_DAC_PERCENT_Z = _UxGT("Z Meghajtó %"); + PROGMEM Language_Str MSG_DAC_PERCENT_E = _UxGT("E Meghajtó %"); + PROGMEM Language_Str MSG_ERROR_TMC = _UxGT("TMC CSATLAKOZÁSI HIBA"); + PROGMEM Language_Str MSG_DAC_EEPROM_WRITE = _UxGT("DAC EEPROM Írása"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER = _UxGT("NYOMTATÓSZÁL CSERE"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_PAUSE = _UxGT("NYOMTATÁS SZÜNETEL"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_LOAD = _UxGT("SZÁL BETÖLTÉS"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_UNLOAD = _UxGT("SZÁL ELTÁVOLÍTÁS"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_HEADER = _UxGT("FOLYTATÁSI OPCIÓ:"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_PURGE = _UxGT("Tisztítsd meg"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_RESUME = _UxGT("Folytatás"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" Fúvóka: "); + PROGMEM Language_Str MSG_RUNOUT_SENSOR = _UxGT("Túlfutás Szenzor"); + PROGMEM Language_Str MSG_RUNOUT_DISTANCE_MM = _UxGT("Túlfutás Táv. mm"); + PROGMEM Language_Str MSG_KILL_HOMING_FAILED = _UxGT("Tájolási hiba"); + PROGMEM Language_Str MSG_LCD_PROBING_FAILED = _UxGT("Szondázás hiba"); + + PROGMEM Language_Str MSG_MMU2_CHOOSE_FILAMENT_HEADER = _UxGT("SZÁLVÁLASZTÁS"); + PROGMEM Language_Str MSG_MMU2_MENU = _UxGT("MMU"); + PROGMEM Language_Str MSG_KILL_MMU2_FIRMWARE = _UxGT("MMU Szoftver Feltöltése!"); + PROGMEM Language_Str MSG_MMU2_NOT_RESPONDING = _UxGT("MMU Figyelmeztetés."); + PROGMEM Language_Str MSG_MMU2_RESUME = _UxGT("Nyomtatás Folytatása"); + PROGMEM Language_Str MSG_MMU2_RESUMING = _UxGT("Folytatás..."); + PROGMEM Language_Str MSG_MMU2_LOAD_FILAMENT = _UxGT("Szál Betöltése"); + PROGMEM Language_Str MSG_MMU2_LOAD_ALL = _UxGT("Összes Betöltése"); + PROGMEM Language_Str MSG_MMU2_LOAD_TO_NOZZLE = _UxGT("Fúvóka Betöltése"); + PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT = _UxGT("Szál Kiadása"); + PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT_N = _UxGT("Szál Kiadása ~"); + PROGMEM Language_Str MSG_MMU2_UNLOAD_FILAMENT = _UxGT("Kiadja a szálat"); + PROGMEM Language_Str MSG_MMU2_LOADING_FILAMENT = _UxGT("Szál betölt. %i..."); + PROGMEM Language_Str MSG_MMU2_EJECTING_FILAMENT = _UxGT("Szál kiadás...."); + PROGMEM Language_Str MSG_MMU2_UNLOADING_FILAMENT = _UxGT("Szál kiadása...."); + PROGMEM Language_Str MSG_MMU2_ALL = _UxGT("Mind"); + PROGMEM Language_Str MSG_MMU2_FILAMENT_N = _UxGT("Nyomtatószál ~"); + PROGMEM Language_Str MSG_MMU2_RESET = _UxGT("MMU Újraindítás"); + PROGMEM Language_Str MSG_MMU2_RESETTING = _UxGT("MMU Újraindul..."); + PROGMEM Language_Str MSG_MMU2_EJECT_RECOVER = _UxGT("Eltávolít, kattint"); + + PROGMEM Language_Str MSG_MIX = _UxGT("Kever"); + PROGMEM Language_Str MSG_MIX_COMPONENT_N = _UxGT("Összetevö ="); + PROGMEM Language_Str MSG_MIXER = _UxGT("Keverö"); + PROGMEM Language_Str MSG_GRADIENT = _UxGT("Színátm."); + PROGMEM Language_Str MSG_FULL_GRADIENT = _UxGT("Teljes Színátm."); + PROGMEM Language_Str MSG_TOGGLE_MIX = _UxGT("Váltás Keverésre"); + PROGMEM Language_Str MSG_CYCLE_MIX = _UxGT("Ciklikus Keverés"); + PROGMEM Language_Str MSG_GRADIENT_MIX = _UxGT("Színátm. Keverés"); + PROGMEM Language_Str MSG_REVERSE_GRADIENT = _UxGT("Fordított Színátm."); + PROGMEM Language_Str MSG_ACTIVE_VTOOL = _UxGT("Aktív V-szerszám"); + PROGMEM Language_Str MSG_START_VTOOL = _UxGT("Kezdés V-szerszám"); + PROGMEM Language_Str MSG_END_VTOOL = _UxGT(" Vége V-szerszám"); + PROGMEM Language_Str MSG_GRADIENT_ALIAS = _UxGT("Ál V-szerszám"); + PROGMEM Language_Str MSG_RESET_VTOOLS = _UxGT("Újra V-szerszám"); + PROGMEM Language_Str MSG_COMMIT_VTOOL = _UxGT("Gyors V-szerszám Kev."); + PROGMEM Language_Str MSG_VTOOLS_RESET = _UxGT("V-szersz. visszaáll."); + PROGMEM Language_Str MSG_START_Z = _UxGT("Kezdés Z:"); + PROGMEM Language_Str MSG_END_Z = _UxGT(" Vége Z:"); + + PROGMEM Language_Str MSG_GAMES = _UxGT("Játékok"); + PROGMEM Language_Str MSG_BRICKOUT = _UxGT("Brickout"); + PROGMEM Language_Str MSG_INVADERS = _UxGT("Invaders"); + PROGMEM Language_Str MSG_SNAKE = _UxGT("Sn4k3"); + PROGMEM Language_Str MSG_MAZE = _UxGT("Maze"); + + // + // Filament Change screens show up to 3 lines on a 4-line display + // ...or up to 2 lines on a 3-line display + // + #if LCD_HEIGHT >= 4 + PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_2_LINE("Nyomj gombot", "nyomtatás folytatáshoz")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Parkolás...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_3_LINE("Várj míg", "szál csere", "indítás")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_3_LINE("Szál behelyezés", "majd nyomj gombot", "a folytatáshoz")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_2_LINE("Nyomj gombot", "a fúvóka fűtéséhez")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEATING = _UxGT(MSG_2_LINE("Fúvóka fűtése", "Kérlek várj...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_2_LINE("Várj a", "szál kiadására")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_2_LINE("Várj a", "szál betöltésére")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_PURGE = _UxGT(MSG_2_LINE("Várj a", "szál tisztításra")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_CONT_PURGE = _UxGT(MSG_2_LINE("Kattints a készre", "szál tiszta")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_2_LINE("Várj a nyomtatóra", "majd foltyat...")); + #else + PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_1_LINE("Katt a folytatáshoz")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Parkolás...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_1_LINE("Kérlek Várj...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_1_LINE("Behelyez majd katt")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_1_LINE("Katt a fűtéshez")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEATING = _UxGT(MSG_1_LINE("Fűtés...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_1_LINE("Kiadás...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_1_LINE("Betöltés...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_PURGE = _UxGT(MSG_1_LINE("Tisztítás...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_CONT_PURGE = _UxGT(MSG_1_LINE("Katt ha kész")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_1_LINE("Folytatás...")); + #endif + PROGMEM Language_Str MSG_TMC_DRIVERS = _UxGT("TMC Meghajtók"); + PROGMEM Language_Str MSG_TMC_CURRENT = _UxGT("Meghajtó áram"); + PROGMEM Language_Str MSG_TMC_HYBRID_THRS = _UxGT("Hibrid Küszöbérték"); + PROGMEM Language_Str MSG_TMC_HOMING_THRS = _UxGT("Motoros Kezdöpont"); + PROGMEM Language_Str MSG_TMC_STEPPING_MODE = _UxGT("Léptetö Mód"); + PROGMEM Language_Str MSG_TMC_STEALTH_ENABLED = _UxGT("StealthChop Mód"); + PROGMEM Language_Str MSG_SERVICE_RESET = _UxGT("Újraindítás"); + PROGMEM Language_Str MSG_SERVICE_IN = _UxGT(" be:"); + PROGMEM Language_Str MSG_BACKLASH = _UxGT("Holtjáték"); + PROGMEM Language_Str MSG_BACKLASH_A = LCD_STR_A; + PROGMEM Language_Str MSG_BACKLASH_B = LCD_STR_B; + PROGMEM Language_Str MSG_BACKLASH_C = LCD_STR_C; + PROGMEM Language_Str MSG_BACKLASH_CORRECTION = _UxGT("Korrekció"); + PROGMEM Language_Str MSG_BACKLASH_SMOOTHING = _UxGT("Simítás"); + + PROGMEM Language_Str MSG_LEVEL_X_AXIS = _UxGT("X Tengely Szint"); + PROGMEM Language_Str MSG_AUTO_CALIBRATE = _UxGT("Önkalibrálás"); + PROGMEM Language_Str MSG_HEATER_TIMEOUT = _UxGT("Fűtéskimaradás"); + PROGMEM Language_Str MSG_REHEAT = _UxGT("Újrafűt"); + PROGMEM Language_Str MSG_REHEATING = _UxGT("Újrafűtés..."); +} + +#if FAN_COUNT == 1 + #define MSG_FIRST_FAN_SPEED MSG_FAN_SPEED + #define MSG_EXTRA_FIRST_FAN_SPEED MSG_EXTRA_FAN_SPEED +#else + #define MSG_FIRST_FAN_SPEED MSG_FAN_SPEED_N + #define MSG_EXTRA_FIRST_FAN_SPEED MSG_EXTRA_FAN_SPEED_N +#endif diff --git a/Marlin/src/lcd/language/language_it.h b/Marlin/src/lcd/language/language_it.h index ae4dd813ea5f..38fffcb73b8c 100644 --- a/Marlin/src/lcd/language/language_it.h +++ b/Marlin/src/lcd/language/language_it.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,8 +25,7 @@ * Italian * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ #define DISPLAY_CHARSET_ISO10646_1 @@ -45,11 +44,12 @@ namespace Language_it { PROGMEM Language_Str MSG_MEDIA_ABORTING = _UxGT("Annullando..."); PROGMEM Language_Str MSG_MEDIA_INSERTED = _UxGT("Media inserito"); PROGMEM Language_Str MSG_MEDIA_REMOVED = _UxGT("Media rimosso"); - PROGMEM Language_Str MSG_MEDIA_RELEASED = _UxGT("Media rilasciato"); PROGMEM Language_Str MSG_MEDIA_WAITING = _UxGT("Aspettando media"); + PROGMEM Language_Str MSG_SD_INIT_FAIL = _UxGT("Inizial.SD fallita"); PROGMEM Language_Str MSG_MEDIA_READ_ERROR = _UxGT("Err.leggendo media"); PROGMEM Language_Str MSG_MEDIA_USB_REMOVED = _UxGT("Dispos.USB rimosso"); PROGMEM Language_Str MSG_MEDIA_USB_FAILED = _UxGT("Avvio USB fallito"); + PROGMEM Language_Str MSG_KILL_SUBCALL_OVERFLOW = _UxGT("Overflow subchiamate"); PROGMEM Language_Str MSG_LCD_ENDSTOPS = _UxGT("Finecor."); // Max 8 characters PROGMEM Language_Str MSG_LCD_SOFT_ENDSTOPS = _UxGT("Finecorsa Soft"); PROGMEM Language_Str MSG_MAIN = _UxGT("Menu principale"); @@ -64,6 +64,7 @@ namespace Language_it { PROGMEM Language_Str MSG_AUTO_HOME_Y = _UxGT("Home asse Y"); PROGMEM Language_Str MSG_AUTO_HOME_Z = _UxGT("Home asse Z"); PROGMEM Language_Str MSG_AUTO_Z_ALIGN = _UxGT("Allineam.automat. Z"); + PROGMEM Language_Str MSG_ASSISTED_TRAMMING = _UxGT("Tramming assistito"); PROGMEM Language_Str MSG_LEVEL_BED_HOMING = _UxGT("Home assi XYZ"); PROGMEM Language_Str MSG_LEVEL_BED_WAITING = _UxGT("Premi per iniziare"); PROGMEM Language_Str MSG_LEVEL_BED_NEXT_POINT = _UxGT("Punto successivo"); @@ -72,22 +73,26 @@ namespace Language_it { PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Imp. offset home"); PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Offset applicato"); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Imposta Origine"); - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Preriscalda ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Preriscalda ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Preris.") PREHEAT_1_LABEL _UxGT(" Ugello"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Preris.") PREHEAT_1_LABEL _UxGT(" Ugello ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Preris.") PREHEAT_1_LABEL _UxGT(" Tutto"); - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Preris.") PREHEAT_1_LABEL _UxGT(" Piatto"); - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Preris.") PREHEAT_1_LABEL _UxGT(" conf"); - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("Preriscalda ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("Preriscalda ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("Preris.") PREHEAT_2_LABEL _UxGT(" Ugello"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("Preris.") PREHEAT_2_LABEL _UxGT(" Ugello ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("Preris.") PREHEAT_2_LABEL _UxGT(" Tutto"); - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("Preris.") PREHEAT_2_LABEL _UxGT(" Piatto"); - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("Preris.") PREHEAT_2_LABEL _UxGT(" conf"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Preriscalda ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Preriscalda ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Preris.") PREHEAT_1_LABEL _UxGT(" Ugello"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Preris.") PREHEAT_1_LABEL _UxGT(" Ugello ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Preris.") PREHEAT_1_LABEL _UxGT(" Tutto"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Preris.") PREHEAT_1_LABEL _UxGT(" Piatto"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Preris.") PREHEAT_1_LABEL _UxGT(" conf"); + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Preriscalda $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Preriscalda $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Preris.$ Ugello"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Preris.$ Ugello ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Preris.$ Tutto"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Preris.$ Piatto"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Preris.$ conf"); + #endif PROGMEM Language_Str MSG_PREHEAT_CUSTOM = _UxGT("Prerisc.personal."); PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Raffredda"); + PROGMEM Language_Str MSG_CUTTER_FREQUENCY = _UxGT("Frequenza"); PROGMEM Language_Str MSG_LASER_MENU = _UxGT("Controllo laser"); PROGMEM Language_Str MSG_LASER_OFF = _UxGT("Laser Off"); PROGMEM Language_Str MSG_LASER_ON = _UxGT("Laser On"); @@ -117,6 +122,7 @@ namespace Language_it { PROGMEM Language_Str MSG_LCD_TILTING_MESH = _UxGT("Punto inclinaz."); PROGMEM Language_Str MSG_M48_TEST = _UxGT("Test sonda M48"); PROGMEM Language_Str MSG_M48_POINT = _UxGT("Punto M48"); + PROGMEM Language_Str MSG_M48_OUT_OF_BOUNDS = _UxGT("Sonda oltre i limiti"); PROGMEM Language_Str MSG_M48_DEVIATION = _UxGT("Deviazione"); PROGMEM Language_Str MSG_IDEX_MENU = _UxGT("Modo IDEX"); PROGMEM Language_Str MSG_OFFSETS_MENU = _UxGT("Strumenti Offsets"); @@ -147,14 +153,14 @@ namespace Language_it { PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("Modif.Mesh fatta"); PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("Crea Mesh personal."); PROGMEM Language_Str MSG_UBL_BUILD_MESH_MENU = _UxGT("Crea Mesh"); - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M1 = _UxGT("Crea Mesh ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M2 = _UxGT("Crea Mesh ") PREHEAT_2_LABEL; + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_UBL_BUILD_MESH_M = _UxGT("Crea Mesh ($)"); + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("Valida Mesh ($)"); + #endif PROGMEM Language_Str MSG_UBL_BUILD_COLD_MESH = _UxGT("Crea Mesh a freddo"); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_ADJUST = _UxGT("Aggiusta Alt. Mesh"); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_AMOUNT = _UxGT("Altezza"); PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_MENU = _UxGT("Valida Mesh"); - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M1 = _UxGT("Valida Mesh ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M2 = _UxGT("Valida Mesh ") PREHEAT_2_LABEL; PROGMEM Language_Str MSG_G26_HEATING_BED = _UxGT("G26 riscald.letto"); PROGMEM Language_Str MSG_G26_HEATING_NOZZLE = _UxGT("G26 riscald.ugello"); PROGMEM Language_Str MSG_G26_MANUAL_PRIME = _UxGT("Priming manuale..."); @@ -187,8 +193,8 @@ namespace Language_it { PROGMEM Language_Str MSG_UBL_STORAGE_SLOT = _UxGT("Slot di memoria"); PROGMEM Language_Str MSG_UBL_LOAD_MESH = _UxGT("Carica Mesh Piatto"); PROGMEM Language_Str MSG_UBL_SAVE_MESH = _UxGT("Salva Mesh Piatto"); - PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("M117 Mesh %i caricata"); - PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("M117 Mesh %i salvata"); + PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("Mesh %i caricata"); + PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("Mesh %i salvata"); PROGMEM Language_Str MSG_UBL_NO_STORAGE = _UxGT("Nessuna memoria"); PROGMEM Language_Str MSG_UBL_SAVE_ERROR = _UxGT("Err: Salvataggio UBL"); PROGMEM Language_Str MSG_UBL_RESTORE_ERROR = _UxGT("Err: Ripristino UBL"); @@ -215,6 +221,10 @@ namespace Language_it { PROGMEM Language_Str MSG_SET_LEDS_VIOLET = _UxGT("Viola"); PROGMEM Language_Str MSG_SET_LEDS_WHITE = _UxGT("Bianco"); PROGMEM Language_Str MSG_SET_LEDS_DEFAULT = _UxGT("Predefinito"); + PROGMEM Language_Str MSG_LED_CHANNEL_N = _UxGT("Canale ="); + PROGMEM Language_Str MSG_LEDS2 = _UxGT("Luci #2"); + PROGMEM Language_Str MSG_NEO2_PRESETS = _UxGT("Luce #2 Presets"); + PROGMEM Language_Str MSG_NEO2_BRIGHTNESS = _UxGT("Luminosità"); PROGMEM Language_Str MSG_CUSTOM_LEDS = _UxGT("Luci personalizzate"); PROGMEM Language_Str MSG_INTENSITY_R = _UxGT("Intensità rosso"); PROGMEM Language_Str MSG_INTENSITY_G = _UxGT("Intensità verde"); @@ -238,6 +248,8 @@ namespace Language_it { PROGMEM Language_Str MSG_BED_Z = _UxGT("Piatto Z"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Ugello"); PROGMEM Language_Str MSG_NOZZLE_N = _UxGT("Ugello ~"); + PROGMEM Language_Str MSG_NOZZLE_PARKED = _UxGT("Ugello parcheggiato"); + PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("Ugello in pausa"); PROGMEM Language_Str MSG_BED = _UxGT("Piatto"); PROGMEM Language_Str MSG_CHAMBER = _UxGT("Camera"); PROGMEM Language_Str MSG_FAN_SPEED = _UxGT("Vel. ventola"); // Max 15 characters @@ -245,6 +257,11 @@ namespace Language_it { PROGMEM Language_Str MSG_STORED_FAN_N = _UxGT("Ventola mem. ~"); // Max 15 characters PROGMEM Language_Str MSG_EXTRA_FAN_SPEED = _UxGT("Extra vel.vent."); // Max 15 characters PROGMEM Language_Str MSG_EXTRA_FAN_SPEED_N = _UxGT("Extra v.vent. ~"); // Max 15 characters + PROGMEM Language_Str MSG_CONTROLLER_FAN = _UxGT("Controller vent."); + PROGMEM Language_Str MSG_CONTROLLER_FAN_IDLE_SPEED = _UxGT("Vel. inattivo"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_AUTO_ON = _UxGT("Modo autom."); + PROGMEM Language_Str MSG_CONTROLLER_FAN_SPEED = _UxGT("Vel. attivo"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_DURATION = _UxGT("Tempo inattivo"); PROGMEM Language_Str MSG_FLOW = _UxGT("Flusso"); PROGMEM Language_Str MSG_FLOW_N = _UxGT("Flusso ~"); PROGMEM Language_Str MSG_CONTROL = _UxGT("Controllo"); @@ -254,8 +271,12 @@ namespace Language_it { PROGMEM Language_Str MSG_AUTOTEMP = _UxGT("Autotemp"); PROGMEM Language_Str MSG_LCD_ON = _UxGT("On"); PROGMEM Language_Str MSG_LCD_OFF = _UxGT("Off"); - PROGMEM Language_Str MSG_PID_AUTOTUNE = _UxGT("PID Autotune"); - PROGMEM Language_Str MSG_PID_AUTOTUNE_E = _UxGT("PID Autotune *"); + PROGMEM Language_Str MSG_PID_AUTOTUNE = _UxGT("Calibrazione PID"); + PROGMEM Language_Str MSG_PID_AUTOTUNE_E = _UxGT("Calibraz. PID *"); + PROGMEM Language_Str MSG_PID_AUTOTUNE_DONE = _UxGT("Calibr.PID eseguita"); + PROGMEM Language_Str MSG_PID_BAD_EXTRUDER_NUM = _UxGT("Calibrazione fallita. Estrusore errato."); + PROGMEM Language_Str MSG_PID_TEMP_TOO_HIGH = _UxGT("Calibrazione fallita. Temperatura troppo alta."); + PROGMEM Language_Str MSG_PID_TIMEOUT = _UxGT("Calibrazione fallita! Tempo scaduto."); PROGMEM Language_Str MSG_PID_P = _UxGT("PID-P"); PROGMEM Language_Str MSG_PID_P_E = _UxGT("PID-P *"); PROGMEM Language_Str MSG_PID_I = _UxGT("PID-I"); @@ -291,6 +312,8 @@ namespace Language_it { PROGMEM Language_Str MSG_AMAX_EN = _UxGT("Amax *"); PROGMEM Language_Str MSG_A_RETRACT = _UxGT("A-Ritrazione"); PROGMEM Language_Str MSG_A_TRAVEL = _UxGT("A-Spostamento"); + PROGMEM Language_Str MSG_XY_FREQUENCY_LIMIT = _UxGT("Frequenza max"); + PROGMEM Language_Str MSG_XY_FREQUENCY_FEEDRATE = _UxGT("Feed min"); PROGMEM Language_Str MSG_STEPS_PER_MM = _UxGT("Passi/mm"); PROGMEM Language_Str MSG_A_STEPS = LCD_STR_A _UxGT("passi/mm"); PROGMEM Language_Str MSG_B_STEPS = LCD_STR_B _UxGT("passi/mm"); @@ -301,6 +324,8 @@ namespace Language_it { PROGMEM Language_Str MSG_MOTION = _UxGT("Movimento"); PROGMEM Language_Str MSG_FILAMENT = _UxGT("Filamento"); PROGMEM Language_Str MSG_VOLUMETRIC_ENABLED = _UxGT("E in mm³"); + PROGMEM Language_Str MSG_VOLUMETRIC_LIMIT = _UxGT("Limite E in mm³"); + PROGMEM Language_Str MSG_VOLUMETRIC_LIMIT_E = _UxGT("Limite E *"); PROGMEM Language_Str MSG_FILAMENT_DIAM = _UxGT("Diam. filo"); PROGMEM Language_Str MSG_FILAMENT_DIAM_E = _UxGT("Diam. filo *"); PROGMEM Language_Str MSG_FILAMENT_UNLOAD = _UxGT("Rimuovi mm"); @@ -312,24 +337,35 @@ namespace Language_it { PROGMEM Language_Str MSG_LOAD_EEPROM = _UxGT("Carica impostazioni"); PROGMEM Language_Str MSG_RESTORE_DEFAULTS = _UxGT("Ripristina imp."); PROGMEM Language_Str MSG_INIT_EEPROM = _UxGT("Inizializza EEPROM"); + PROGMEM Language_Str MSG_ERR_EEPROM_CRC = _UxGT("Err: CRC EEPROM"); + PROGMEM Language_Str MSG_ERR_EEPROM_INDEX = _UxGT("Err: Indice EEPROM"); + PROGMEM Language_Str MSG_ERR_EEPROM_VERSION = _UxGT("Err: Versione EEPROM"); + PROGMEM Language_Str MSG_SETTINGS_STORED = _UxGT("Impostazioni mem."); PROGMEM Language_Str MSG_MEDIA_UPDATE = _UxGT("Aggiorna media"); PROGMEM Language_Str MSG_RESET_PRINTER = _UxGT("Resetta stampante"); PROGMEM Language_Str MSG_REFRESH = LCD_STR_REFRESH _UxGT("Aggiorna"); PROGMEM Language_Str MSG_INFO_SCREEN = _UxGT("Schermata info"); PROGMEM Language_Str MSG_PREPARE = _UxGT("Prepara"); PROGMEM Language_Str MSG_TUNE = _UxGT("Regola"); + PROGMEM Language_Str MSG_POWER_MONITOR = _UxGT("Controllo aliment."); + PROGMEM Language_Str MSG_CURRENT = _UxGT("Corrente"); + PROGMEM Language_Str MSG_VOLTAGE = _UxGT("Tensione"); + PROGMEM Language_Str MSG_POWER = _UxGT("Potenza"); PROGMEM Language_Str MSG_START_PRINT = _UxGT("Avvia stampa"); PROGMEM Language_Str MSG_BUTTON_NEXT = _UxGT("Prossimo"); PROGMEM Language_Str MSG_BUTTON_INIT = _UxGT("Inizializza"); PROGMEM Language_Str MSG_BUTTON_STOP = _UxGT("Stop"); PROGMEM Language_Str MSG_BUTTON_PRINT = _UxGT("Stampa"); PROGMEM Language_Str MSG_BUTTON_RESET = _UxGT("Resetta"); + PROGMEM Language_Str MSG_BUTTON_IGNORE = _UxGT("Ignora"); PROGMEM Language_Str MSG_BUTTON_CANCEL = _UxGT("Annulla"); PROGMEM Language_Str MSG_BUTTON_DONE = _UxGT("Fatto"); PROGMEM Language_Str MSG_BUTTON_BACK = _UxGT("Indietro"); PROGMEM Language_Str MSG_BUTTON_PROCEED = _UxGT("Procedi"); + PROGMEM Language_Str MSG_PAUSING = _UxGT("Messa in pausa..."); PROGMEM Language_Str MSG_PAUSE_PRINT = _UxGT("Pausa stampa"); PROGMEM Language_Str MSG_RESUME_PRINT = _UxGT("Riprendi stampa"); + PROGMEM Language_Str MSG_HOST_START_PRINT = _UxGT("Host Avvio"); PROGMEM Language_Str MSG_STOP_PRINT = _UxGT("Arresta stampa"); PROGMEM Language_Str MSG_PRINTING_OBJECT = _UxGT("Stampa Oggetto"); PROGMEM Language_Str MSG_CANCEL_OBJECT = _UxGT("Cancella Oggetto"); @@ -341,7 +377,8 @@ namespace Language_it { PROGMEM Language_Str MSG_USERWAIT = _UxGT("Premi tasto.."); PROGMEM Language_Str MSG_PRINT_PAUSED = _UxGT("Stampa sospesa"); PROGMEM Language_Str MSG_PRINTING = _UxGT("Stampa..."); - PROGMEM Language_Str MSG_PRINT_ABORTED = _UxGT("Stampa annullata"); + PROGMEM Language_Str MSG_PRINT_ABORTED = _UxGT("Stampa Annullata"); + PROGMEM Language_Str MSG_PRINT_DONE = _UxGT("Stampa Eseguita"); PROGMEM Language_Str MSG_NO_MOVE = _UxGT("Nessun Movimento"); PROGMEM Language_Str MSG_KILLED = _UxGT("UCCISO. "); PROGMEM Language_Str MSG_STOPPED = _UxGT("ARRESTATO. "); @@ -349,24 +386,34 @@ namespace Language_it { PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("Scamb. Ritrai mm"); PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("Ritrai V"); PROGMEM Language_Str MSG_CONTROL_RETRACT_ZHOP = _UxGT("Salta mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("UnRet mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("Scamb. UnRet mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("UnRet V"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAPF = _UxGT("S UnRet V"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("Avanza mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("Scamb. Avanza mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("Avanza V"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAPF = _UxGT("Scamb. Avanza V"); PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("AutoRitrai"); - PROGMEM Language_Str MSG_FILAMENT_SWAP_LENGTH = _UxGT("Dist. ritrazione"); + PROGMEM Language_Str MSG_FILAMENT_SWAP_LENGTH = _UxGT("Lunghezza scambio"); + PROGMEM Language_Str MSG_FILAMENT_SWAP_EXTRA = _UxGT("Extra scambio"); PROGMEM Language_Str MSG_FILAMENT_PURGE_LENGTH = _UxGT("Lunghezza spurgo"); PROGMEM Language_Str MSG_TOOL_CHANGE = _UxGT("Cambio utensile"); PROGMEM Language_Str MSG_TOOL_CHANGE_ZLIFT = _UxGT("Risalita Z"); - PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPD = _UxGT("Velocità innesco"); - PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPD = _UxGT("Velocità retrazione"); - PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("Standby ugello"); + PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPEED = _UxGT("Velocità innesco"); + PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPEED = _UxGT("Velocità ritrazione"); + PROGMEM Language_Str MSG_FILAMENT_PARK_ENABLED = _UxGT("Parcheggia testa"); + PROGMEM Language_Str MSG_SINGLENOZZLE_UNRETRACT_SPEED = _UxGT("Recover Speed"); + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_SPEED = _UxGT("Velocità ventola"); + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_TIME = _UxGT("Tempo ventola"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_ON = _UxGT("Auto ON"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_OFF = _UxGT("Auto OFF"); + PROGMEM Language_Str MSG_TOOL_MIGRATION = _UxGT("Migrazione utensile"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_AUTO = _UxGT("Auto-migrazione"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_END = _UxGT("Ultimo estrusore"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_SWAP = _UxGT("Migra a *"); PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("Cambia filamento"); - PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Cambia filamento *"); + PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Cambia filam. *"); PROGMEM Language_Str MSG_FILAMENTLOAD = _UxGT("Carica filamento"); PROGMEM Language_Str MSG_FILAMENTLOAD_E = _UxGT("Carica filamento *"); PROGMEM Language_Str MSG_FILAMENTUNLOAD = _UxGT("Rimuovi filamento"); - PROGMEM Language_Str MSG_FILAMENTUNLOAD_E = _UxGT("Rimuovi filamento *"); + PROGMEM Language_Str MSG_FILAMENTUNLOAD_E = _UxGT("Rimuovi filam. *"); PROGMEM Language_Str MSG_FILAMENTUNLOAD_ALL = _UxGT("Rimuovi tutto"); PROGMEM Language_Str MSG_ATTACH_MEDIA = _UxGT("Collega media"); PROGMEM Language_Str MSG_CHANGE_MEDIA = _UxGT("Cambia media"); @@ -398,25 +445,19 @@ namespace Language_it { PROGMEM Language_Str MSG_ZPROBE_XOFFSET = _UxGT("Offset X sonda"); PROGMEM Language_Str MSG_ZPROBE_YOFFSET = _UxGT("Offset Y sonda"); PROGMEM Language_Str MSG_ZPROBE_ZOFFSET = _UxGT("Offset Z sonda"); + PROGMEM Language_Str MSG_MOVE_NOZZLE_TO_BED = _UxGT("Muovi ugel.su letto"); PROGMEM Language_Str MSG_BABYSTEP_X = _UxGT("Babystep X"); PROGMEM Language_Str MSG_BABYSTEP_Y = _UxGT("Babystep Y"); PROGMEM Language_Str MSG_BABYSTEP_Z = _UxGT("Babystep Z"); PROGMEM Language_Str MSG_BABYSTEP_TOTAL = _UxGT("Totali"); PROGMEM Language_Str MSG_ENDSTOP_ABORT = _UxGT("Finecorsa annullati"); - PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("Riscald. Fallito"); - PROGMEM Language_Str MSG_HEATING_FAILED_LCD_BED = _UxGT("Risc. piatto fallito"); - PROGMEM Language_Str MSG_HEATING_FAILED_LCD_CHAMBER = _UxGT("Risc. camera fallito"); + PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("Risc.Fallito"); // Max 12 caratteri PROGMEM Language_Str MSG_ERR_REDUNDANT_TEMP = _UxGT("Err: TEMP RIDONDANTE"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("TEMP FUORI CONTROLLO"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY_BED = _UxGT("TEMP PIAT.FUORI CTRL"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER = _UxGT("T.CAMERA FUORI CTRL"); PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("Err: TEMP MASSIMA"); PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("Err: TEMP MINIMA"); - PROGMEM Language_Str MSG_ERR_MAXTEMP_BED = _UxGT("Err: TEMP MAX PIATTO"); - PROGMEM Language_Str MSG_ERR_MINTEMP_BED = _UxGT("Err: TEMP MIN PIATTO"); - PROGMEM Language_Str MSG_ERR_MAXTEMP_CHAMBER = _UxGT("Err: TEMP MAX CAMERA"); - PROGMEM Language_Str MSG_ERR_MINTEMP_CHAMBER = _UxGT("Err: TEMP MIN CAMERA"); - PROGMEM Language_Str MSG_ERR_Z_HOMING = _UxGT("Home XY prima"); PROGMEM Language_Str MSG_HALTED = _UxGT("STAMPANTE FERMATA"); PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("Riavviare prego"); PROGMEM Language_Str MSG_SHORT_DAY = _UxGT("g"); // Un solo carattere @@ -426,6 +467,8 @@ namespace Language_it { PROGMEM Language_Str MSG_COOLING = _UxGT("Raffreddamento.."); PROGMEM Language_Str MSG_BED_HEATING = _UxGT("Risc. piatto..."); PROGMEM Language_Str MSG_BED_COOLING = _UxGT("Raffr. piatto..."); + PROGMEM Language_Str MSG_PROBE_HEATING = _UxGT("Risc. sonda..."); + PROGMEM Language_Str MSG_PROBE_COOLING = _UxGT("Raffr. sonda..."); PROGMEM Language_Str MSG_CHAMBER_HEATING = _UxGT("Risc. camera..."); PROGMEM Language_Str MSG_CHAMBER_COOLING = _UxGT("Raffr. camera..."); PROGMEM Language_Str MSG_DELTA_CALIBRATE = _UxGT("Calibraz. Delta"); @@ -455,8 +498,12 @@ namespace Language_it { PROGMEM Language_Str MSG_INFO_PROTOCOL = _UxGT("Protocollo"); PROGMEM Language_Str MSG_INFO_RUNAWAY_OFF = _UxGT("Controllo fuga: OFF"); PROGMEM Language_Str MSG_INFO_RUNAWAY_ON = _UxGT("Controllo fuga: ON"); + PROGMEM Language_Str MSG_HOTEND_IDLE_TIMEOUT = _UxGT("Timeout inatt.ugello"); + PROGMEM Language_Str MSG_CASE_LIGHT = _UxGT("Luci Case"); PROGMEM Language_Str MSG_CASE_LIGHT_BRIGHTNESS = _UxGT("Luminosità Luci"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("STAMPANTE ERRATA"); + #if LCD_WIDTH >= 20 PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Contat. stampa"); PROGMEM Language_Str MSG_INFO_COMPLETED_PRINTS = _UxGT("Completati"); @@ -490,13 +537,12 @@ namespace Language_it { PROGMEM Language_Str MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" Ugello: "); PROGMEM Language_Str MSG_RUNOUT_SENSOR = _UxGT("Sens.filo termin."); // Max 17 characters PROGMEM Language_Str MSG_RUNOUT_DISTANCE_MM = _UxGT("Dist mm filo term."); - PROGMEM Language_Str MSG_LCD_HOMING_FAILED = _UxGT("Home fallito"); + PROGMEM Language_Str MSG_KILL_HOMING_FAILED = _UxGT("Home fallito"); PROGMEM Language_Str MSG_LCD_PROBING_FAILED = _UxGT("Sondaggio fallito"); - PROGMEM Language_Str MSG_M600_TOO_COLD = _UxGT("M600:Troppo freddo"); PROGMEM Language_Str MSG_MMU2_CHOOSE_FILAMENT_HEADER = _UxGT("SCELTA FILAMENTO"); PROGMEM Language_Str MSG_MMU2_MENU = _UxGT("MMU"); - PROGMEM Language_Str MSG_MMU2_WRONG_FIRMWARE = _UxGT("Agg.firmware MMU!"); + PROGMEM Language_Str MSG_KILL_MMU2_FIRMWARE = _UxGT("Agg.firmware MMU!"); PROGMEM Language_Str MSG_MMU2_NOT_RESPONDING = _UxGT("MMU chiede attenz."); PROGMEM Language_Str MSG_MMU2_RESUME = _UxGT("Riprendi stampa"); PROGMEM Language_Str MSG_MMU2_RESUMING = _UxGT("Ripresa..."); @@ -516,7 +562,7 @@ namespace Language_it { PROGMEM Language_Str MSG_MMU2_EJECT_RECOVER = _UxGT("Rimuovi, click"); PROGMEM Language_Str MSG_MIX = _UxGT("Miscela"); - PROGMEM Language_Str MSG_MIX_COMPONENT_N = _UxGT("Componente ~"); + PROGMEM Language_Str MSG_MIX_COMPONENT_N = _UxGT("Componente ="); PROGMEM Language_Str MSG_MIXER = _UxGT("Miscelatore"); PROGMEM Language_Str MSG_GRADIENT = _UxGT("Gradiente"); PROGMEM Language_Str MSG_FULL_GRADIENT = _UxGT("Gradiente pieno"); @@ -540,14 +586,26 @@ namespace Language_it { PROGMEM Language_Str MSG_SNAKE = _UxGT("Sn4k3"); PROGMEM Language_Str MSG_MAZE = _UxGT("Maze"); - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("Stampante errata"); + PROGMEM Language_Str MSG_BAD_PAGE = _UxGT("Indice pag. errato"); + PROGMEM Language_Str MSG_BAD_PAGE_SPEED = _UxGT("Vel. pag. errata"); + + PROGMEM Language_Str MSG_EDIT_PASSWORD = _UxGT("Modif.password"); + PROGMEM Language_Str MSG_LOGIN_REQUIRED = _UxGT("Login richiesto"); + PROGMEM Language_Str MSG_PASSWORD_SETTINGS = _UxGT("Impostaz.password"); + PROGMEM Language_Str MSG_ENTER_DIGIT = _UxGT("Inserisci cifra"); + PROGMEM Language_Str MSG_CHANGE_PASSWORD = _UxGT("Imp./Modif.password"); + PROGMEM Language_Str MSG_REMOVE_PASSWORD = _UxGT("Elimina password"); + PROGMEM Language_Str MSG_PASSWORD_SET = _UxGT("La password è "); + PROGMEM Language_Str MSG_START_OVER = _UxGT("Ricominciare"); + PROGMEM Language_Str MSG_REMINDER_SAVE_SETTINGS = _UxGT("Ricordati di mem.!"); + PROGMEM Language_Str MSG_PASSWORD_REMOVED = _UxGT("Password eliminata"); // // Le schermate di Cambio Filamento possono visualizzare fino a 3 linee su un display a 4 righe // ...o fino a 2 linee su un display a 3 righe. #if LCD_HEIGHT >= 4 PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_3_LINE("Premi per", "riprendere", "la stampa")); - PROGMEM Language_Str MSG_PAUSE_PRINT_INIT = _UxGT(MSG_1_LINE("Parcheggiando...")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Parcheggiando...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_3_LINE("Attendere avvio", "del cambio", "di filamento")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_3_LINE("Inserisci il", "filamento e premi", "per continuare")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_2_LINE("Premi per", "riscaldare ugello")); @@ -573,7 +631,7 @@ namespace Language_it { PROGMEM Language_Str MSG_TMC_DRIVERS = _UxGT("Drivers TMC"); PROGMEM Language_Str MSG_TMC_CURRENT = _UxGT("Driver in uso"); PROGMEM Language_Str MSG_TMC_HYBRID_THRS = _UxGT("Soglia modo ibrido"); - PROGMEM Language_Str MSG_TMC_HOMING_THRS = _UxGT("Azzer. sensorless"); + PROGMEM Language_Str MSG_TMC_HOMING_THRS = _UxGT("Azzer. senza sens."); PROGMEM Language_Str MSG_TMC_STEPPING_MODE = _UxGT("Modo stepping"); PROGMEM Language_Str MSG_TMC_STEALTH_ENABLED = _UxGT("StealthChop abil."); @@ -585,5 +643,13 @@ namespace Language_it { PROGMEM Language_Str MSG_BACKLASH_B = LCD_STR_B; PROGMEM Language_Str MSG_BACKLASH_C = LCD_STR_C; PROGMEM Language_Str MSG_BACKLASH_CORRECTION = _UxGT("Correzione"); - PROGMEM Language_Str MSG_BACKLASH_SMOOTHING = _UxGT("Smoothing"); + PROGMEM Language_Str MSG_BACKLASH_SMOOTHING = _UxGT("Appianamento"); + + PROGMEM Language_Str MSG_LEVEL_X_AXIS = _UxGT("Livello asse X"); + PROGMEM Language_Str MSG_AUTO_CALIBRATE = _UxGT("Auto Calibra"); + PROGMEM Language_Str MSG_HEATER_TIMEOUT = _UxGT("Timeout riscaldatore"); + PROGMEM Language_Str MSG_REHEAT = _UxGT("Riscalda"); + PROGMEM Language_Str MSG_REHEATING = _UxGT("Riscaldando..."); + + PROGMEM Language_Str MSG_PROBE_WIZARD = _UxGT("Proc.guid.sonda Z"); } diff --git a/Marlin/src/lcd/language/language_jp_kana.h b/Marlin/src/lcd/language/language_jp_kana.h index 809ee83de8b3..32b12f50cb8b 100644 --- a/Marlin/src/lcd/language/language_jp_kana.h +++ b/Marlin/src/lcd/language/language_jp_kana.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -26,8 +26,7 @@ * UTF-8 for Graphical Display * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ //#define DISPLAY_CHARSET_ISO10646_KANA @@ -46,7 +45,6 @@ namespace Language_jp_kana { PROGMEM Language_Str MSG_MEDIA_INSERTED = _UxGT("メディアガソウニュウサレマシタ"); // "Card inserted" PROGMEM Language_Str MSG_MEDIA_REMOVED = _UxGT("メディアガアリマセン"); // "Card removed" PROGMEM Language_Str MSG_RELEASE_MEDIA = _UxGT("メディアノトリダシ"); - PROGMEM Language_Str MSG_MEDIA_RELEASED = _UxGT("メディアガアリマセン"); // "Card removed" PROGMEM Language_Str MSG_LCD_ENDSTOPS = _UxGT("エンドストップ"); // "Endstops" // Max length 8 characters PROGMEM Language_Str MSG_MAIN = _UxGT("メイン"); // "Main" PROGMEM Language_Str MSG_AUTOSTART = _UxGT("ジドウカイシ"); // "Autostart" @@ -64,20 +62,23 @@ namespace Language_jp_kana { PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("キジュンオフセットセッテイ"); // "Set home offsets" PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("オフセットガテキヨウサレマシタ"); // "Offsets applied" PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("キジュンセット"); // "Set origin" - PROGMEM Language_Str MSG_PREHEAT_1 = PREHEAT_1_LABEL _UxGT(" ヨネツ"); // "Preheat " PREHEAT_1_LABEL - PROGMEM Language_Str MSG_PREHEAT_1_H = PREHEAT_1_LABEL _UxGT(" ヨネツ ~"); // "Preheat " PREHEAT_1_LABEL - PROGMEM Language_Str MSG_PREHEAT_1_END = PREHEAT_1_LABEL _UxGT(" ヨネツノズル"); // " Nozzle" - PROGMEM Language_Str MSG_PREHEAT_1_END_E = PREHEAT_1_LABEL _UxGT(" ヨネツノズル ~"); // " Nozzle" - PROGMEM Language_Str MSG_PREHEAT_1_ALL = PREHEAT_1_LABEL _UxGT(" スベテヨネツ"); // " All" - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = PREHEAT_1_LABEL _UxGT(" ベッドヨネツ"); // " Bed" - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = PREHEAT_1_LABEL _UxGT(" ヨネツセッテイ"); // " conf" - PROGMEM Language_Str MSG_PREHEAT_2 = PREHEAT_2_LABEL _UxGT(" ヨネツ"); // "Preheat " PREHEAT_1_LABEL - PROGMEM Language_Str MSG_PREHEAT_2_H = PREHEAT_2_LABEL _UxGT(" ヨネツ ~"); // "Preheat " PREHEAT_1_LABEL - PROGMEM Language_Str MSG_PREHEAT_2_END = PREHEAT_2_LABEL _UxGT(" ヨネツノズル"); // " Nozzle" - PROGMEM Language_Str MSG_PREHEAT_2_END_E = PREHEAT_2_LABEL _UxGT(" ヨネツノズル ~"); // " Nozzle" - PROGMEM Language_Str MSG_PREHEAT_2_ALL = PREHEAT_2_LABEL _UxGT(" スベテヨネツ"); // " All" - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = PREHEAT_2_LABEL _UxGT(" ベッドヨネツ"); // " Bed" - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = PREHEAT_2_LABEL _UxGT(" ヨネツセッテイ"); // " conf" + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = PREHEAT_1_LABEL _UxGT(" ヨネツ"); // "Preheat " PREHEAT_1_LABEL + PROGMEM Language_Str MSG_PREHEAT_1_H = PREHEAT_1_LABEL _UxGT(" ヨネツ ~"); // "Preheat " PREHEAT_1_LABEL + PROGMEM Language_Str MSG_PREHEAT_1_END = PREHEAT_1_LABEL _UxGT(" ヨネツノズル"); // " Nozzle" + PROGMEM Language_Str MSG_PREHEAT_1_END_E = PREHEAT_1_LABEL _UxGT(" ヨネツノズル ~"); // " Nozzle" + PROGMEM Language_Str MSG_PREHEAT_1_ALL = PREHEAT_1_LABEL _UxGT(" スベテヨネツ"); // " All" + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = PREHEAT_1_LABEL _UxGT(" ベッドヨネツ"); // " Bed" + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = PREHEAT_1_LABEL _UxGT(" ヨネツセッテイ"); // " conf" + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("$ ヨネツ"); // "Preheat " PREHEAT_1_LABEL + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("$ ヨネツ ~"); // "Preheat " PREHEAT_1_LABEL + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("$ ヨネツノズル"); // " Nozzle" + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("$ ヨネツノズル ~"); // " Nozzle" + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("$ スベテヨネツ"); // " All" + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("$ ベッドヨネツ"); // " Bed" + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("$ ヨネツセッテイ"); // " conf" + #endif PROGMEM Language_Str MSG_COOLDOWN = _UxGT("カネツテイシ"); // "Cooldown" PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("デンゲン オン"); // "Switch power on" PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("デンゲン オフ"); // "Switch power off" @@ -159,12 +160,12 @@ namespace Language_jp_kana { PROGMEM Language_Str MSG_STOPPED = _UxGT("テイシシマシタ"); // "STOPPED. " PROGMEM Language_Str MSG_CONTROL_RETRACT = _UxGT("ヒキコミリョウ mm"); // "Retract mm" PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("ヒキコミリョウS mm"); // "Swap Re.mm" - PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("ヒキコミソクド mm/s"); // "Retract V" + PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("ヒキコミソクド mm/s"); // "Retract V" PROGMEM Language_Str MSG_CONTROL_RETRACT_ZHOP = _UxGT("ノズルタイヒ mm"); // "Hop mm" - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("ホショウリョウ mm"); // "UnRet mm" - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("ホショウリョウS mm"); // "S UnRet mm" - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("ホショウソクド mm/s"); // "UnRet V" - PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("ジドウヒキコミ"); // "AutoRetr." + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("ホショウリョウ mm"); // "Unretr. mm" + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("ホショウリョウS mm"); // "S Unretr. mm" + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("ホショウソクド mm/s"); // "Unretract V" + PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("ジドウヒキコミ"); // "Auto-Retract" PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("フィラメントコウカン"); // "Change filament" PROGMEM Language_Str MSG_ATTACH_MEDIA = _UxGT("メディアサイヨミコミ"); // "Init. SD card" PROGMEM Language_Str MSG_CHANGE_MEDIA = _UxGT("メディアコウカン"); // "Change SD card" @@ -182,9 +183,6 @@ namespace Language_jp_kana { PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("ネツボウソウ"); // "THERMAL RUNAWAY" PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("エラー:サイコウオンチョウカ"); // "Err: MAXTEMP" PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("エラー:サイテイオンミマン"); // "Err: MINTEMP" - PROGMEM Language_Str MSG_ERR_MAXTEMP_BED = _UxGT("エラー:ベッド サイコウオンチョウカ"); // "Err: MAXTEMP BED" - PROGMEM Language_Str MSG_ERR_MINTEMP_BED = _UxGT("エラー:ベッド サイテイオンミマン"); // "Err: MINTEMP BED" - PROGMEM Language_Str MSG_ERR_Z_HOMING = _UxGT("サキニ XY ヲフッキサセテクダサイ"); // "Home XY first" PROGMEM Language_Str MSG_HALTED = _UxGT("プリンターハテイシシマシタ"); // "PRINTER HALTED" PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("リセットシテクダサイ"); // "Please reset" PROGMEM Language_Str MSG_SHORT_DAY = _UxGT("d"); // One character only @@ -228,7 +226,7 @@ namespace Language_jp_kana { PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_2_LINE("フィラメントソウテンチュウ", "シバラクオマチクダサイ")); // "Wait for filament load" PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_2_LINE("プリントヲサイカイシマス", "シバラクオマチクダサイ")); // "Wait for print to resume" - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("マチガッタプリンター"); // "Wrong printer" + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("マチガッタプリンター"); // "Wrong printer" PROGMEM Language_Str MSG_CONFIGURATION = _UxGT("セッテイカンリ"); PROGMEM Language_Str MSG_ADVANCED_SETTINGS = _UxGT("ショウサイセッテイ"); diff --git a/Marlin/src/lcd/language/language_ko_KR.h b/Marlin/src/lcd/language/language_ko_KR.h index 4d8142e38bae..1ab03dcf57df 100644 --- a/Marlin/src/lcd/language/language_ko_KR.h +++ b/Marlin/src/lcd/language/language_ko_KR.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,8 +25,7 @@ * Korean * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ namespace Language_ko_KR { using namespace Language_en; // Inherit undefined strings from English @@ -55,14 +54,17 @@ namespace Language_ko_KR { PROGMEM Language_Str MSG_LEVEL_BED_WAITING = _UxGT("누르면 시작합니다"); PROGMEM Language_Str MSG_LEVEL_BED_NEXT_POINT = _UxGT("다음 Point"); PROGMEM Language_Str MSG_LEVEL_BED_DONE = _UxGT("레벨링 완료!"); - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("예열하기 - ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("예열하기 - ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("예열하기 - ") PREHEAT_1_LABEL _UxGT(" 노즐"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("예열하기 - ") PREHEAT_1_LABEL _UxGT(" 노즐 ~"); - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("예열하기 - ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("예열하기 - ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("예열하기 - ") PREHEAT_2_LABEL _UxGT(" 노즐"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("예열하기 - ") PREHEAT_2_LABEL _UxGT(" 노즐 ~"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("예열하기 - ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("예열하기 - ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("예열하기 - ") PREHEAT_1_LABEL _UxGT(" 노즐"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("예열하기 - ") PREHEAT_1_LABEL _UxGT(" 노즐 ~"); + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("예열하기 - $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("예열하기 - $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("예열하기 - $ 노즐"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("예열하기 - $ 노즐 ~"); + #endif PROGMEM Language_Str MSG_PREHEAT_CUSTOM = _UxGT("Custom 예열"); PROGMEM Language_Str MSG_COOLDOWN = _UxGT("식히기"); PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("스위치 전원 켜기"); @@ -100,5 +102,5 @@ namespace Language_ko_KR { PROGMEM Language_Str MSG_PRINT_ABORTED = _UxGT("취소됨"); PROGMEM Language_Str MSG_KILLED = _UxGT("죽음. "); PROGMEM Language_Str MSG_STOPPED = _UxGT("멈춤. "); - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("잘못된 프린터"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("잘못된 프린터"); } diff --git a/Marlin/src/lcd/language/language_nl.h b/Marlin/src/lcd/language/language_nl.h index d5d46ecfe6aa..c142c5c9bfd6 100644 --- a/Marlin/src/lcd/language/language_nl.h +++ b/Marlin/src/lcd/language/language_nl.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,8 +25,7 @@ * Dutch * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ #define DISPLAY_CHARSET_ISO10646_1 @@ -46,33 +45,32 @@ namespace Language_nl { PROGMEM Language_Str MSG_MAIN = _UxGT("Hoofdmenu"); PROGMEM Language_Str MSG_AUTOSTART = _UxGT("Autostart"); PROGMEM Language_Str MSG_DISABLE_STEPPERS = _UxGT("Motoren uit"); - PROGMEM Language_Str MSG_DEBUG_MENU = _UxGT("Debug Menu"); //accepted English terms + PROGMEM Language_Str MSG_DEBUG_MENU = _UxGT("Debug Menu"); // accepted English terms PROGMEM Language_Str MSG_PROGRESS_BAR_TEST = _UxGT("Vooruitgang Test"); - PROGMEM Language_Str MSG_AUTO_HOME = _UxGT("Auto home"); - PROGMEM Language_Str MSG_AUTO_HOME_X = _UxGT("Home X"); - PROGMEM Language_Str MSG_AUTO_HOME_Y = _UxGT("Home Y"); - PROGMEM Language_Str MSG_AUTO_HOME_Z = _UxGT("Home Z"); - PROGMEM Language_Str MSG_LEVEL_BED_HOMING = _UxGT("Homing XYZ"); + PROGMEM Language_Str MSG_LEVEL_BED_WAITING = _UxGT("Klik voor begin"); PROGMEM Language_Str MSG_LEVEL_BED_NEXT_POINT = _UxGT("Volgende Plaats"); PROGMEM Language_Str MSG_LEVEL_BED_DONE = _UxGT("Bed level kompl."); PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Zet home offsets"); PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("H offset toegep."); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Nulpunt instellen"); - PROGMEM Language_Str MSG_PREHEAT_1 = PREHEAT_1_LABEL _UxGT(" voorverwarmen"); - PROGMEM Language_Str MSG_PREHEAT_1_H = PREHEAT_1_LABEL _UxGT(" voorverw. ~"); - PROGMEM Language_Str MSG_PREHEAT_1_END = PREHEAT_1_LABEL _UxGT(" voorverw. Einde"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = PREHEAT_1_LABEL _UxGT(" voorverw. Einde ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = PREHEAT_1_LABEL _UxGT(" voorverw. aan"); - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = PREHEAT_1_LABEL _UxGT(" voorverw. Bed"); - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = PREHEAT_1_LABEL _UxGT(" verw. conf"); - PROGMEM Language_Str MSG_PREHEAT_2 = PREHEAT_2_LABEL _UxGT(" voorverwarmen"); - PROGMEM Language_Str MSG_PREHEAT_2_H = PREHEAT_2_LABEL _UxGT(" voorverw. ~"); - PROGMEM Language_Str MSG_PREHEAT_2_END = PREHEAT_2_LABEL _UxGT(" voorverw. Einde"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = PREHEAT_2_LABEL _UxGT(" voorverw. Einde ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = PREHEAT_2_LABEL _UxGT(" voorverw. aan"); - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = PREHEAT_2_LABEL _UxGT(" voorverw. Bed"); - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = PREHEAT_2_LABEL _UxGT(" verw. conf"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = PREHEAT_1_LABEL _UxGT(" voorverwarmen"); + PROGMEM Language_Str MSG_PREHEAT_1_H = PREHEAT_1_LABEL _UxGT(" voorverw. ~"); + PROGMEM Language_Str MSG_PREHEAT_1_END = PREHEAT_1_LABEL _UxGT(" voorverw. Einde"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = PREHEAT_1_LABEL _UxGT(" voorverw. Einde ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = PREHEAT_1_LABEL _UxGT(" voorverw. aan"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = PREHEAT_1_LABEL _UxGT(" voorverw. Bed"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = PREHEAT_1_LABEL _UxGT(" verw. conf"); + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("$ voorverwarmen"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("$ voorverw. ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("$ voorverw. Einde"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("$ voorverw. Einde ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("$ voorverw. aan"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("$ voorverw. Bed"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("$ verw. conf"); + #endif PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Afkoelen"); PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Stroom aan"); PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("Stroom uit"); @@ -115,8 +113,8 @@ namespace Language_nl { PROGMEM Language_Str MSG_TEMPERATURE = _UxGT("Temperatuur"); PROGMEM Language_Str MSG_MOTION = _UxGT("Beweging"); PROGMEM Language_Str MSG_FILAMENT = _UxGT("Filament"); - PROGMEM Language_Str MSG_ADVANCE_K = _UxGT("Advance K"); //accepted english dutch - PROGMEM Language_Str MSG_ADVANCE_K_E = _UxGT("Advance K *"); //accepted english dutch + PROGMEM Language_Str MSG_ADVANCE_K = _UxGT("Advance K"); // accepted english dutch + PROGMEM Language_Str MSG_ADVANCE_K_E = _UxGT("Advance K *"); // accepted english dutch PROGMEM Language_Str MSG_VOLUMETRIC_ENABLED = _UxGT("E in mm³"); PROGMEM Language_Str MSG_FILAMENT_DIAM = _UxGT("Fil. Dia."); PROGMEM Language_Str MSG_FILAMENT_DIAM_E = _UxGT("Fil. Dia. *"); @@ -139,14 +137,14 @@ namespace Language_nl { PROGMEM Language_Str MSG_NO_MOVE = _UxGT("Geen beweging."); PROGMEM Language_Str MSG_KILLED = _UxGT("Afgebroken. "); PROGMEM Language_Str MSG_STOPPED = _UxGT("Gestopt. "); - PROGMEM Language_Str MSG_CONTROL_RETRACT = _UxGT("Retract mm"); //accepted English term in Dutch + PROGMEM Language_Str MSG_CONTROL_RETRACT = _UxGT("Retract mm"); // accepted English term in Dutch PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("Ruil Retract mm"); PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("Retract F"); PROGMEM Language_Str MSG_CONTROL_RETRACT_ZHOP = _UxGT("Hop mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("UnRet mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("Ruil UnRet mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("UnRet F"); - PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("AutoRetr."); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("Unretr. mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("Ruil Unretr. mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("Unretr. FR"); + PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("Auto-Retract"); PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("Verv. Filament"); PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Verv. Filament *"); PROGMEM Language_Str MSG_ATTACH_MEDIA = _UxGT("Init. SD kaart"); @@ -155,7 +153,7 @@ namespace Language_nl { PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("BLTouch Zelf-Test"); PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("Reset BLTouch"); PROGMEM Language_Str MSG_HOME_FIRST = _UxGT("Home %s%s%s Eerst"); - PROGMEM Language_Str MSG_ZPROBE_ZOFFSET = _UxGT("Z Offset"); //accepted English term in Dutch + PROGMEM Language_Str MSG_ZPROBE_ZOFFSET = _UxGT("Z Offset"); // accepted English term in Dutch PROGMEM Language_Str MSG_BABYSTEP_X = _UxGT("Babystap X"); PROGMEM Language_Str MSG_BABYSTEP_Y = _UxGT("Babystap Y"); PROGMEM Language_Str MSG_BABYSTEP_Z = _UxGT("Babystap Z"); @@ -165,9 +163,6 @@ namespace Language_nl { PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("Therm. wegloop"); PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("Err: Max. temp"); PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("Err: Min. temp"); - PROGMEM Language_Str MSG_ERR_MAXTEMP_BED = _UxGT("Err: Max.tmp bed"); - PROGMEM Language_Str MSG_ERR_MINTEMP_BED = _UxGT("Err: Min.tmp bed"); - PROGMEM Language_Str MSG_ERR_Z_HOMING = _UxGT("Home XY Eerst"); PROGMEM Language_Str MSG_HALTED = _UxGT("PRINTER GESTOPT"); PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("Reset A.U.B."); PROGMEM Language_Str MSG_SHORT_DAY = _UxGT("d"); // One character only. Keep English standard @@ -183,17 +178,9 @@ namespace Language_nl { PROGMEM Language_Str MSG_DELTA_AUTO_CALIBRATE = _UxGT("Auto Calibratie"); PROGMEM Language_Str MSG_DELTA_HEIGHT_CALIBRATE = _UxGT("Zet Delta Hoogte"); - PROGMEM Language_Str MSG_INFO_STATS_MENU = _UxGT("Printer Stats"); - PROGMEM Language_Str MSG_INFO_BOARD_MENU = _UxGT("Board Info"); //accepted English term in Dutch - PROGMEM Language_Str MSG_INFO_THERMISTOR_MENU = _UxGT("Thermistors"); - PROGMEM Language_Str MSG_INFO_EXTRUDERS = _UxGT("Extruders"); - PROGMEM Language_Str MSG_INFO_BAUDRATE = _UxGT("Baud"); - PROGMEM Language_Str MSG_INFO_MENU = _UxGT("Over Printer"); - PROGMEM Language_Str MSG_INFO_PRINTER_MENU = _UxGT("Printer Info"); - PROGMEM Language_Str MSG_INFO_PROTOCOL = _UxGT("Protocol"); PROGMEM Language_Str MSG_CASE_LIGHT = _UxGT("Case licht"); - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("Onjuiste printer"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("Onjuiste printer"); #if LCD_WIDTH >= 20 PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Printed Aantal"); @@ -211,16 +198,13 @@ namespace Language_nl { PROGMEM Language_Str MSG_INFO_MIN_TEMP = _UxGT("Min Temp"); PROGMEM Language_Str MSG_INFO_MAX_TEMP = _UxGT("Max Temp"); - PROGMEM Language_Str MSG_INFO_PSU = _UxGT("PSU"); //accepted English term in Dutch + PROGMEM Language_Str MSG_INFO_PSU = _UxGT("PSU"); // accepted English term in Dutch PROGMEM Language_Str MSG_DRIVE_STRENGTH = _UxGT("Motorstroom"); - PROGMEM Language_Str MSG_DAC_PERCENT_X = _UxGT("X Driver %"); //accepted English term in Dutch - PROGMEM Language_Str MSG_DAC_PERCENT_Y = _UxGT("Y Driver %"); //accepted English term in Dutch - PROGMEM Language_Str MSG_DAC_PERCENT_Z = _UxGT("Z Driver %"); //accepted English term in Dutch - PROGMEM Language_Str MSG_DAC_PERCENT_E = _UxGT("E Driver %"); //accepted English term in Dutch + PROGMEM Language_Str MSG_DAC_EEPROM_WRITE = _UxGT("DAC Opslaan"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_RESUME = _UxGT("Hervat print"); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" Nozzle: "); //accepeted English term + PROGMEM Language_Str MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" Nozzle: "); // accepted English term // // Filament Change screens show up to 3 lines on a 4-line display // ...or up to 2 lines on a 3-line display diff --git a/Marlin/src/lcd/language/language_pl.h b/Marlin/src/lcd/language/language_pl.h index 113c58629f10..770c872a4099 100644 --- a/Marlin/src/lcd/language/language_pl.h +++ b/Marlin/src/lcd/language/language_pl.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,8 +25,7 @@ * Polish - includes accented characters * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ #define DISPLAY_CHARSET_ISO10646_PL @@ -44,7 +43,6 @@ namespace Language_pl { PROGMEM Language_Str MSG_MEDIA_ABORTING = _UxGT("Przerywanie..."); PROGMEM Language_Str MSG_MEDIA_INSERTED = _UxGT("Karta włożona"); PROGMEM Language_Str MSG_MEDIA_REMOVED = _UxGT("Karta usunięta"); - PROGMEM Language_Str MSG_MEDIA_RELEASED = _UxGT("Karta zwolniona"); PROGMEM Language_Str MSG_MEDIA_WAITING = _UxGT("Oczekiwanie na kartę"); PROGMEM Language_Str MSG_MEDIA_READ_ERROR = _UxGT("Bład odczytu karty"); PROGMEM Language_Str MSG_MEDIA_USB_REMOVED = _UxGT("Urządzenie USB usunięte"); @@ -71,20 +69,23 @@ namespace Language_pl { PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Ust. poz. zer."); PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Poz. zerowa ust."); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Ustaw punkt zero"); - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Rozgrzej ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Rozgrzej ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Rozgrzej ") PREHEAT_1_LABEL _UxGT(" Dysza"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Rozgrzej ") PREHEAT_1_LABEL _UxGT(" Dysza ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Rozgrzej ") PREHEAT_1_LABEL _UxGT(" wsz."); - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Rozgrzej ") PREHEAT_1_LABEL _UxGT(" stół"); - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Rozgrzej ") PREHEAT_1_LABEL _UxGT(" ustaw."); - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("Rozgrzej ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("Rozgrzej ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("Rozgrzej ") PREHEAT_2_LABEL _UxGT(" Dysza"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("Rozgrzej ") PREHEAT_2_LABEL _UxGT(" Dysza ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("Rozgrzej ") PREHEAT_2_LABEL _UxGT(" wsz."); - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("Rozgrzej ") PREHEAT_2_LABEL _UxGT(" stół"); - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("Rozgrzej ") PREHEAT_2_LABEL _UxGT(" ustaw."); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Rozgrzej ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Rozgrzej ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Rozgrzej ") PREHEAT_1_LABEL _UxGT(" Dysza"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Rozgrzej ") PREHEAT_1_LABEL _UxGT(" Dysza ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Rozgrzej ") PREHEAT_1_LABEL _UxGT(" wsz."); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Rozgrzej ") PREHEAT_1_LABEL _UxGT(" stół"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Rozgrzej ") PREHEAT_1_LABEL _UxGT(" ustaw."); + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Rozgrzej $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Rozgrzej $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Rozgrzej $ Dysza"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Rozgrzej $ Dysza ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Rozgrzej $ wsz."); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Rozgrzej $ stół"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Rozgrzej $ ustaw."); + #endif PROGMEM Language_Str MSG_PREHEAT_CUSTOM = _UxGT("Rozgrzej własne ust."); PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Chłodzenie"); PROGMEM Language_Str MSG_LASER_MENU = _UxGT("Sterowanie Lasera"); @@ -146,20 +147,20 @@ namespace Language_pl { PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("Koniec edycji siati"); PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("Buduj własna siatkę"); PROGMEM Language_Str MSG_UBL_BUILD_MESH_MENU = _UxGT("Buduj siatkę"); - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M1 = _UxGT("Buduj siatkę (") PREHEAT_1_LABEL _UxGT(")"); - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M2 = _UxGT("Buduj siatkę (") PREHEAT_2_LABEL _UxGT(")"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_UBL_BUILD_MESH_M = _UxGT("Buduj siatkę ($)"); + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("Sprawdzenie siatki ($)"); + #endif PROGMEM Language_Str MSG_UBL_BUILD_COLD_MESH = _UxGT("Buduj siatkę na zimno"); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_ADJUST = _UxGT("Dostrojenie wysokości siatki"); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_AMOUNT = _UxGT("Wartość wysokości"); PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_MENU = _UxGT("Sprawdzenie siatki"); - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M1 = _UxGT("Sprawdzenie siatki (") PREHEAT_1_LABEL _UxGT(")"); - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M2 = _UxGT("Sprawdzenie siatki (") PREHEAT_2_LABEL _UxGT(")"); PROGMEM Language_Str MSG_UBL_VALIDATE_CUSTOM_MESH = _UxGT("Sprawdzenie własnej siatki"); PROGMEM Language_Str MSG_G26_HEATING_BED = _UxGT("G26 Nagrzewanie stołu"); PROGMEM Language_Str MSG_G26_HEATING_NOZZLE = _UxGT("G26 Nagrzewanie dyszy"); PROGMEM Language_Str MSG_G26_MANUAL_PRIME = _UxGT("Napełnianie ręczne..."); PROGMEM Language_Str MSG_G26_FIXED_LENGTH = _UxGT("Napełnij kreśloną długością"); - PROGMEM Language_Str MSG_G26_PRIME_DONE = _UxGT("Napełianie zakończone"); + PROGMEM Language_Str MSG_G26_PRIME_DONE = _UxGT("Napełnianie zakończone"); PROGMEM Language_Str MSG_G26_CANCELED = _UxGT("G26 Przewane"); PROGMEM Language_Str MSG_G26_LEAVING = _UxGT("Opuszczanie G26"); PROGMEM Language_Str MSG_UBL_CONTINUE_MESH = _UxGT("Kontynuuj tworzenie siatki"); @@ -184,17 +185,17 @@ namespace Language_pl { PROGMEM Language_Str MSG_UBL_FINE_TUNE_CLOSEST = _UxGT("Dostrajaj najbliższy"); PROGMEM Language_Str MSG_UBL_STORAGE_MESH_MENU = _UxGT("Przechowywanie siatki"); PROGMEM Language_Str MSG_UBL_STORAGE_SLOT = _UxGT("Slot Pamięci"); - PROGMEM Language_Str MSG_UBL_LOAD_MESH = _UxGT("Załaduj siatke stołu"); - PROGMEM Language_Str MSG_UBL_SAVE_MESH = _UxGT("Zapisz siatke stołu"); - PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("M117 Siatka %i załadowana"); - PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("M117 Siatka %i Zapisana"); + PROGMEM Language_Str MSG_UBL_LOAD_MESH = _UxGT("Załaduj siatkę stołu"); + PROGMEM Language_Str MSG_UBL_SAVE_MESH = _UxGT("Zapisz siatkę stołu"); + PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("Siatka %i załadowana"); + PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("Siatka %i zapisana"); PROGMEM Language_Str MSG_UBL_NO_STORAGE = _UxGT("Brak magazynu"); PROGMEM Language_Str MSG_UBL_SAVE_ERROR = _UxGT("Błąd: Zapis UBL"); PROGMEM Language_Str MSG_UBL_RESTORE_ERROR = _UxGT("Bład: Odczyt UBL"); PROGMEM Language_Str MSG_UBL_Z_OFFSET = _UxGT("Przesunięcie Z: "); PROGMEM Language_Str MSG_UBL_Z_OFFSET_STOPPED = _UxGT("Przesunięcie Z zatrzymane"); PROGMEM Language_Str MSG_UBL_STEP_BY_STEP_MENU = _UxGT("UBL Krok po kroku"); - PROGMEM Language_Str MSG_UBL_1_BUILD_COLD_MESH = _UxGT("1. Tworzeni ezimnej siatki"); + PROGMEM Language_Str MSG_UBL_1_BUILD_COLD_MESH = _UxGT("1. Tworzenie zimnej siatki"); PROGMEM Language_Str MSG_UBL_2_SMART_FILLIN = _UxGT("2. Inteligentne wypełnienie"); PROGMEM Language_Str MSG_UBL_3_VALIDATE_MESH_MENU = _UxGT("3. Sprawdzenie siatki"); PROGMEM Language_Str MSG_UBL_4_FINE_TUNE_ALL = _UxGT("4. Dostrojenie wszystkiego"); @@ -291,8 +292,8 @@ namespace Language_pl { PROGMEM Language_Str MSG_VOLUMETRIC_ENABLED = _UxGT("E w mm³"); PROGMEM Language_Str MSG_FILAMENT_DIAM = _UxGT("Śr. fil."); PROGMEM Language_Str MSG_FILAMENT_DIAM_E = _UxGT("Śr. fil. *"); - PROGMEM Language_Str MSG_FILAMENT_UNLOAD = _UxGT("Wyładuj mm"); - PROGMEM Language_Str MSG_FILAMENT_LOAD = _UxGT("Załaduj mm"); + PROGMEM Language_Str MSG_FILAMENT_UNLOAD = _UxGT("Wysuń mm"); + PROGMEM Language_Str MSG_FILAMENT_LOAD = _UxGT("Wsuń mm"); PROGMEM Language_Str MSG_ADVANCE_K = _UxGT("Advance K"); PROGMEM Language_Str MSG_ADVANCE_K_E = _UxGT("Advance K *"); PROGMEM Language_Str MSG_CONTRAST = _UxGT("Kontrast LCD"); @@ -340,16 +341,16 @@ namespace Language_pl { PROGMEM Language_Str MSG_FILAMENT_PURGE_LENGTH = _UxGT("Długość oczyszczania"); PROGMEM Language_Str MSG_TOOL_CHANGE = _UxGT("Zmiana narzędzia"); PROGMEM Language_Str MSG_TOOL_CHANGE_ZLIFT = _UxGT("Podniesienie Z"); - PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPD = _UxGT("Prędkość napełniania"); - PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPD = _UxGT("Prędkość wycofania"); + PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPEED = _UxGT("Prędkość napełniania"); + PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPEED = _UxGT("Prędkość wycofania"); PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("Dysza w oczekiwaniu"); PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("Zmień filament"); PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Zmień filament *"); - PROGMEM Language_Str MSG_FILAMENTLOAD = _UxGT("Załaduj Filament"); - PROGMEM Language_Str MSG_FILAMENTLOAD_E = _UxGT("Załaduj Filament *"); - PROGMEM Language_Str MSG_FILAMENTUNLOAD = _UxGT("Wyładuj Filament"); - PROGMEM Language_Str MSG_FILAMENTUNLOAD_E = _UxGT("Wyładuj Filament *"); - PROGMEM Language_Str MSG_FILAMENTUNLOAD_ALL = _UxGT("Wyładuj wszystkie"); + PROGMEM Language_Str MSG_FILAMENTLOAD = _UxGT("Wsuń Filament"); + PROGMEM Language_Str MSG_FILAMENTLOAD_E = _UxGT("Wsuń Filament *"); + PROGMEM Language_Str MSG_FILAMENTUNLOAD = _UxGT("Wysuń Filament"); + PROGMEM Language_Str MSG_FILAMENTUNLOAD_E = _UxGT("Wysuń Filament *"); + PROGMEM Language_Str MSG_FILAMENTUNLOAD_ALL = _UxGT("Wysuń wszystkie"); PROGMEM Language_Str MSG_ATTACH_MEDIA = _UxGT("Inicjal. karty SD"); PROGMEM Language_Str MSG_CHANGE_MEDIA = _UxGT("Zmiana karty SD"); PROGMEM Language_Str MSG_RELEASE_MEDIA = _UxGT("Zwolnienie karty"); @@ -358,16 +359,16 @@ namespace Language_pl { PROGMEM Language_Str MSG_BLTOUCH = _UxGT("BLTouch"); PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("BLTouch Self-Test"); PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("Reset BLTouch"); - PROGMEM Language_Str MSG_BLTOUCH_STOW = _UxGT("Cmd: Stow"); - PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("Cmd: Deploy"); - PROGMEM Language_Str MSG_BLTOUCH_SW_MODE = _UxGT("Cmd: SW-Mode"); - PROGMEM Language_Str MSG_BLTOUCH_5V_MODE = _UxGT("Cmd: 5V-Mode"); - PROGMEM Language_Str MSG_BLTOUCH_OD_MODE = _UxGT("Cmd: OD-Mode"); - PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE = _UxGT("Cmd: Mode-Store"); + PROGMEM Language_Str MSG_BLTOUCH_STOW = _UxGT("Stow"); + PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("Deploy"); + PROGMEM Language_Str MSG_BLTOUCH_SW_MODE = _UxGT("SW-Mode"); + PROGMEM Language_Str MSG_BLTOUCH_5V_MODE = _UxGT("5V-Mode"); + PROGMEM Language_Str MSG_BLTOUCH_OD_MODE = _UxGT("OD-Mode"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE = _UxGT("Mode-Store"); PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_5V = _UxGT("Set BLTouch to 5V"); PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_OD = _UxGT("Set BLTouch to OD"); PROGMEM Language_Str MSG_BLTOUCH_MODE_ECHO = _UxGT("Report Drain"); - PROGMEM Language_Str MSG_BLTOUCH_MODE_CHANGE = _UxGT("NIEBEZPIECZNE: Złe ustawienia mogą uszkodzić drukarkę. Kontynuować?"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_CHANGE = _UxGT("UWAGA: Złe ustawienia mogą uszkodzić drukarkę. Kontynuować?"); PROGMEM Language_Str MSG_TOUCHMI_PROBE = _UxGT("TouchMI"); PROGMEM Language_Str MSG_TOUCHMI_INIT = _UxGT("Init TouchMI"); PROGMEM Language_Str MSG_TOUCHMI_ZTEST = _UxGT("Z Offset Test"); @@ -383,19 +384,12 @@ namespace Language_pl { PROGMEM Language_Str MSG_BABYSTEP_TOTAL = _UxGT("Łącznie"); PROGMEM Language_Str MSG_ENDSTOP_ABORT = _UxGT("Błąd krańcówki"); PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("Rozgrz. nieudane"); - PROGMEM Language_Str MSG_HEATING_FAILED_LCD_BED = _UxGT("Rozgrz. stołu nieudane"); - PROGMEM Language_Str MSG_HEATING_FAILED_LCD_CHAMBER = _UxGT("Rozgrz. komory nieudane"); PROGMEM Language_Str MSG_ERR_REDUNDANT_TEMP = _UxGT("Błąd temperatury"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("ZANIK TEMPERATURY"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY_BED = _UxGT("ZANIK TEMP. STOŁU"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER = _UxGT("ZANIK TEMP.KOMORY"); PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("Błąd: MAXTEMP"); PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("Błąd: MINTEMP"); - PROGMEM Language_Str MSG_ERR_MAXTEMP_BED = _UxGT("Błąd: MAXTEMP STÓŁ"); - PROGMEM Language_Str MSG_ERR_MINTEMP_BED = _UxGT("Błąd: MINTEMP STÓŁ"); - PROGMEM Language_Str MSG_ERR_MAXTEMP_CHAMBER = _UxGT("Błąd: MAXTEMP KOMORA"); - PROGMEM Language_Str MSG_ERR_MINTEMP_CHAMBER = _UxGT("Błąd: MINTEMP KOMORA"); - PROGMEM Language_Str MSG_ERR_Z_HOMING = _UxGT("Najpierw Home XY"); PROGMEM Language_Str MSG_HALTED = _UxGT("Drukarka zatrzym."); PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("Proszę zresetować"); PROGMEM Language_Str MSG_SHORT_DAY = _UxGT("d"); // One character only @@ -437,7 +431,7 @@ namespace Language_pl { PROGMEM Language_Str MSG_CASE_LIGHT = _UxGT("Oświetlenie obudowy"); PROGMEM Language_Str MSG_CASE_LIGHT_BRIGHTNESS = _UxGT("Jasność oświetlenia"); - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("Niepoprawna drukarka"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("Niepoprawna drukarka"); #if LCD_WIDTH >= 20 PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Wydrukowano"); @@ -465,33 +459,32 @@ namespace Language_pl { PROGMEM Language_Str MSG_DAC_EEPROM_WRITE = _UxGT("Zapisz DAC EEPROM"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER = _UxGT("ZMIEŃ FILAMENT"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_PAUSE = _UxGT("WYDRUK WSTRZYMANY"); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_LOAD = _UxGT("ZAŁADUJ FILAMENT"); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_UNLOAD = _UxGT("WYŁADUJ FILAMENT"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_LOAD = _UxGT("WSUŃ FILAMENT"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_UNLOAD = _UxGT("WYSUŃ FILAMENT"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_HEADER = _UxGT("OPCJE WZNOWIENIA:"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_PURGE = _UxGT("Oczyść więcej"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_RESUME = _UxGT("Kontynuuj"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" Dysza: "); PROGMEM Language_Str MSG_RUNOUT_SENSOR = _UxGT("Czujnik filamentu"); PROGMEM Language_Str MSG_RUNOUT_DISTANCE_MM = _UxGT("Dystans do czujnika mm"); - PROGMEM Language_Str MSG_LCD_HOMING_FAILED = _UxGT("Zerowanie nieudane"); + PROGMEM Language_Str MSG_KILL_HOMING_FAILED = _UxGT("Zerowanie nieudane"); PROGMEM Language_Str MSG_LCD_PROBING_FAILED = _UxGT("Sondowanie nieudane"); - PROGMEM Language_Str MSG_M600_TOO_COLD = _UxGT("M600: za zimne"); PROGMEM Language_Str MSG_MMU2_CHOOSE_FILAMENT_HEADER = _UxGT("WYBIERZ FILAMENT"); PROGMEM Language_Str MSG_MMU2_MENU = _UxGT("MMU"); - PROGMEM Language_Str MSG_MMU2_WRONG_FIRMWARE = _UxGT("Uaktualnij firmware MMU!"); + PROGMEM Language_Str MSG_KILL_MMU2_FIRMWARE = _UxGT("Uaktualnij firmware MMU!"); PROGMEM Language_Str MSG_MMU2_NOT_RESPONDING = _UxGT("MMU wymaga uwagi."); PROGMEM Language_Str MSG_MMU2_RESUME = _UxGT("Wznów wydruk"); PROGMEM Language_Str MSG_MMU2_RESUMING = _UxGT("Wznawianie..."); - PROGMEM Language_Str MSG_MMU2_LOAD_FILAMENT = _UxGT("Załaduj filament"); - PROGMEM Language_Str MSG_MMU2_LOAD_ALL = _UxGT("Załaduj wszystko"); - PROGMEM Language_Str MSG_MMU2_LOAD_TO_NOZZLE = _UxGT("Załaduj do dyszy"); + PROGMEM Language_Str MSG_MMU2_LOAD_FILAMENT = _UxGT("Wsuń filament"); + PROGMEM Language_Str MSG_MMU2_LOAD_ALL = _UxGT("Wsuń wszystko"); + PROGMEM Language_Str MSG_MMU2_LOAD_TO_NOZZLE = _UxGT("Wsuń do dyszy"); PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT = _UxGT("Wysuń filament"); PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT_N = _UxGT("Wysuń filament ~"); - PROGMEM Language_Str MSG_MMU2_UNLOAD_FILAMENT = _UxGT("Wyładuj filament"); - PROGMEM Language_Str MSG_MMU2_LOADING_FILAMENT = _UxGT("Ładowanie fil. %i..."); + PROGMEM Language_Str MSG_MMU2_UNLOAD_FILAMENT = _UxGT("Wysuń filament"); + PROGMEM Language_Str MSG_MMU2_LOADING_FILAMENT = _UxGT("Wsuwanie fil. %i..."); PROGMEM Language_Str MSG_MMU2_EJECTING_FILAMENT = _UxGT("Wysuwanie fil. ..."); - PROGMEM Language_Str MSG_MMU2_UNLOADING_FILAMENT = _UxGT("Wyładowywanie fil...."); + PROGMEM Language_Str MSG_MMU2_UNLOADING_FILAMENT = _UxGT("Wysuwanie fil...."); PROGMEM Language_Str MSG_MMU2_ALL = _UxGT("Wszystko"); PROGMEM Language_Str MSG_MMU2_FILAMENT_N = _UxGT("Filament ~"); PROGMEM Language_Str MSG_MMU2_RESET = _UxGT("Resetuj MMU"); @@ -499,7 +492,7 @@ namespace Language_pl { PROGMEM Language_Str MSG_MMU2_EJECT_RECOVER = _UxGT("Usuń, kliknij"); PROGMEM Language_Str MSG_MIX = _UxGT("Miks"); - PROGMEM Language_Str MSG_MIX_COMPONENT_N = _UxGT("Komponent ~"); + PROGMEM Language_Str MSG_MIX_COMPONENT_N = _UxGT("Komponent ="); PROGMEM Language_Str MSG_MIXER = _UxGT("Mikser"); PROGMEM Language_Str MSG_GRADIENT = _UxGT("Gradient"); PROGMEM Language_Str MSG_FULL_GRADIENT = _UxGT("Pełny gradient"); @@ -507,25 +500,6 @@ namespace Language_pl { PROGMEM Language_Str MSG_CYCLE_MIX = _UxGT("Cycle Mix"); PROGMEM Language_Str MSG_GRADIENT_MIX = _UxGT("Gradient Mix"); PROGMEM Language_Str MSG_REVERSE_GRADIENT = _UxGT("Odwrotny gradient"); - PROGMEM Language_Str MSG_ACTIVE_VTOOL = _UxGT("Active V-tool"); - PROGMEM Language_Str MSG_START_VTOOL = _UxGT("Start V-tool"); - PROGMEM Language_Str MSG_END_VTOOL = _UxGT(" End V-tool"); - PROGMEM Language_Str MSG_GRADIENT_ALIAS = _UxGT("Alias V-tool"); - PROGMEM Language_Str MSG_RESET_VTOOLS = _UxGT("Reset V-tools"); - PROGMEM Language_Str MSG_COMMIT_VTOOL = _UxGT("Commit V-tool Mix"); - PROGMEM Language_Str MSG_VTOOLS_RESET = _UxGT("V-tools Were Reset"); - PROGMEM Language_Str MSG_START_Z = _UxGT("Start Z:"); - PROGMEM Language_Str MSG_END_Z = _UxGT(" End Z:"); - - PROGMEM Language_Str MSG_GAMES = _UxGT("Games"); - PROGMEM Language_Str MSG_BRICKOUT = _UxGT("Brickout"); - PROGMEM Language_Str MSG_INVADERS = _UxGT("Invaders"); - PROGMEM Language_Str MSG_SNAKE = _UxGT("Sn4k3"); - PROGMEM Language_Str MSG_MAZE = _UxGT("Maze"); - - #define MSG_1_LINE(A) A "\0" "\0" - #define MSG_2_LINE(A,B) A "\0" B "\0" - #define MSG_3_LINE(A,B,C) A "\0" B "\0" C // // Filament Change screens show up to 3 lines on a 4-line display @@ -533,7 +507,7 @@ namespace Language_pl { // #if LCD_HEIGHT >= 4 PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_2_LINE("Nacisnik przycisk", "by wznowić drukowanie")); - PROGMEM Language_Str MSG_PAUSE_PRINT_INIT = _UxGT(MSG_1_LINE("Parkowanie...")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Parkowanie...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_3_LINE("Czekam na", "zmianę filamentu", "by wystartować")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_3_LINE("Włóż filament", "i naciśnij przycisk", "by kontynuować")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_2_LINE("Naciśnij przycisk", "by nagrzać dyszę")); @@ -545,29 +519,15 @@ namespace Language_pl { PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_2_LINE("Czekam na", "wznowienie wydruku...")); #else PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_1_LINE("Kliknij by kontynuować")); - PROGMEM Language_Str MSG_PAUSE_PRINT_INIT = _UxGT(MSG_1_LINE("Parkowanie...")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Parkowanie...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_1_LINE("Proszę czekać...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_1_LINE("Włóż i kliknij")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_1_LINE("Kliknij by nagrzać")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEATING = _UxGT(MSG_1_LINE("Nagrzewanie...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_1_LINE("Wysuwanie...")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_1_LINE("Ładowanie...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_1_LINE("Wsuwanie...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_PURGE = _UxGT(MSG_1_LINE("Oczyszczanie...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_CONT_PURGE = _UxGT(MSG_1_LINE("Kliknij by zakończyć")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_1_LINE("Wznawianie...")); #endif - PROGMEM Language_Str MSG_TMC_DRIVERS = _UxGT("TMC Drivers"); - PROGMEM Language_Str MSG_TMC_CURRENT = _UxGT("Driver Current"); - PROGMEM Language_Str MSG_TMC_HYBRID_THRS = _UxGT("Hybrid Threshold"); - PROGMEM Language_Str MSG_TMC_HOMING_THRS = _UxGT("Sensorless Homing"); - PROGMEM Language_Str MSG_TMC_STEPPING_MODE = _UxGT("Stepping Mode"); - PROGMEM Language_Str MSG_TMC_STEALTH_ENABLED = _UxGT("StealthChop Enabled"); - PROGMEM Language_Str MSG_SERVICE_RESET = _UxGT("Reset"); - PROGMEM Language_Str MSG_SERVICE_IN = _UxGT(" in:"); - PROGMEM Language_Str MSG_BACKLASH = _UxGT("Backlash"); - PROGMEM Language_Str MSG_BACKLASH_A = LCD_STR_A; - PROGMEM Language_Str MSG_BACKLASH_B = LCD_STR_B; - PROGMEM Language_Str MSG_BACKLASH_C = LCD_STR_C; - PROGMEM Language_Str MSG_BACKLASH_CORRECTION = _UxGT("Correction"); - PROGMEM Language_Str MSG_BACKLASH_SMOOTHING = _UxGT("Smoothing"); } diff --git a/Marlin/src/lcd/language/language_pt.h b/Marlin/src/lcd/language/language_pt.h index 69c8be603fdc..37da6216240c 100644 --- a/Marlin/src/lcd/language/language_pt.h +++ b/Marlin/src/lcd/language/language_pt.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -26,8 +26,7 @@ * UTF-8 for Graphical Display * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ #define DISPLAY_CHARSET_ISO10646_1 @@ -54,20 +53,23 @@ namespace Language_pt { PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Definir desvio"); PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Offsets aplicados"); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Definir origem"); - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Pre-aquecer ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Pre-aquecer ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Pre-aquecer ") PREHEAT_1_LABEL _UxGT(" Bico"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Pre-aquecer ") PREHEAT_1_LABEL _UxGT(" Bico ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Pre-aq. ") PREHEAT_1_LABEL _UxGT(" Tudo"); - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Pre-aq. ") PREHEAT_1_LABEL _UxGT(" ") LCD_STR_THERMOMETER _UxGT("Base"); - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Definições ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("Pre-aquecer ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("Pre-aquecer ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("Pre-aquecer ") PREHEAT_2_LABEL _UxGT(" Bico"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("Pre-aquecer ") PREHEAT_2_LABEL _UxGT(" Bico ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("Pre-aq. ") PREHEAT_2_LABEL _UxGT(" Tudo"); - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("Pre-aq. ") PREHEAT_2_LABEL _UxGT(" ") LCD_STR_THERMOMETER _UxGT("Base"); - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("Definições ") PREHEAT_2_LABEL; + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Pre-aquecer ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Pre-aquecer ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Pre-aquecer ") PREHEAT_1_LABEL _UxGT(" Bico"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Pre-aquecer ") PREHEAT_1_LABEL _UxGT(" Bico ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Pre-aq. ") PREHEAT_1_LABEL _UxGT(" Tudo"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Pre-aq. ") PREHEAT_1_LABEL _UxGT(" ") LCD_STR_THERMOMETER _UxGT("Base"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Definições ") PREHEAT_1_LABEL; + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Pre-aquecer $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Pre-aquecer $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Pre-aquecer $ Bico"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Pre-aquecer $ Bico ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Pre-aq. $ Tudo"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Pre-aq. $ ") LCD_STR_THERMOMETER _UxGT("Base"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Definições $"); + #endif PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Arrefecer"); PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Ligar"); PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("Desligar"); @@ -136,7 +138,7 @@ namespace Language_pt { PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT(" DesRet mm"); PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("Troca DesRet mm"); PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT(" DesRet V"); - PROGMEM Language_Str MSG_AUTORETRACT = _UxGT(" AutoRetr."); + PROGMEM Language_Str MSG_AUTORETRACT = _UxGT(" Auto-Retract"); PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("Trocar filamento"); PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Trocar filamento *"); PROGMEM Language_Str MSG_ATTACH_MEDIA = _UxGT("Inici. cartão SD"); @@ -147,8 +149,6 @@ namespace Language_pt { PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("Aquecimento falhou"); PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("Err: T Máxima"); PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("Err: T Mínima"); - PROGMEM Language_Str MSG_ERR_MAXTEMP_BED = _UxGT("Err: T Base Máxima"); - PROGMEM Language_Str MSG_ERR_MINTEMP_BED = _UxGT("Err: T Base Mínima"); PROGMEM Language_Str MSG_HEATING = _UxGT("Aquecendo..."); PROGMEM Language_Str MSG_BED_HEATING = _UxGT("Aquecendo base..."); PROGMEM Language_Str MSG_DELTA_CALIBRATE = _UxGT("Calibração Delta"); @@ -159,5 +159,5 @@ namespace Language_pt { PROGMEM Language_Str MSG_LCD_ENDSTOPS = _UxGT("Fim de curso"); - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("Impressora Incorreta"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("Impressora Incorreta"); } diff --git a/Marlin/src/lcd/language/language_pt_br.h b/Marlin/src/lcd/language/language_pt_br.h index 9ce6a7042b46..cf2f7a0ccef1 100644 --- a/Marlin/src/lcd/language/language_pt_br.h +++ b/Marlin/src/lcd/language/language_pt_br.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -26,8 +26,7 @@ * UTF-8 for Graphical Display * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ namespace Language_pt_br { using namespace Language_en; // Inherit undefined strings from English @@ -36,10 +35,17 @@ namespace Language_pt_br { PROGMEM Language_Str LANGUAGE = _UxGT("Portuguese (BR)"); PROGMEM Language_Str WELCOME_MSG = MACHINE_NAME _UxGT(" pronto."); - + PROGMEM Language_Str MSG_YES = _UxGT("SIM"); + PROGMEM Language_Str MSG_NO = _UxGT("NÃO"); PROGMEM Language_Str MSG_BACK = _UxGT("Voltar"); + PROGMEM Language_Str MSG_MEDIA_ABORTING = _UxGT("Abortando..."); PROGMEM Language_Str MSG_MEDIA_INSERTED = _UxGT("Cartão inserido"); PROGMEM Language_Str MSG_MEDIA_REMOVED = _UxGT("Cartão removido"); + PROGMEM Language_Str MSG_MEDIA_RELEASED = _UxGT("Cartão liberado"); + PROGMEM Language_Str MSG_MEDIA_WAITING = _UxGT("Aguardando cartão"); + PROGMEM Language_Str MSG_MEDIA_READ_ERROR = _UxGT("Erro de leitura"); + PROGMEM Language_Str MSG_MEDIA_USB_REMOVED = _UxGT("USB removido"); + PROGMEM Language_Str MSG_MEDIA_USB_FAILED = _UxGT("USB falhou"); PROGMEM Language_Str MSG_LCD_ENDSTOPS = _UxGT("Fins de curso"); PROGMEM Language_Str MSG_LCD_SOFT_ENDSTOPS = _UxGT("Soft Fins curso"); PROGMEM Language_Str MSG_MAIN = _UxGT("Menu principal"); @@ -62,20 +68,23 @@ namespace Language_pt_br { PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Compensar origem"); PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Alteração aplicada"); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Ajustar Origem"); - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Pre-aquecer ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Pre-aquecer ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Extrusora ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Extrusora ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Pre-aq.Todo ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Pre-aq.Mesa ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Ajustar ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("Pre-aquecer ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("Pre-aquecer ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("Extrusora ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("Extrusora ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("Pre-aq.Todo ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("Pre-aq.Mesa ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("Ajustar ") PREHEAT_2_LABEL; + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Pre-aquecer ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Pre-aquecer ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Extrusora ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Extrusora ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Pre-aq.Todo ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Pre-aq.Mesa ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Ajustar ") PREHEAT_1_LABEL; + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Pre-aquecer $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Pre-aquecer $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Extrusora $"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Extrusora $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Pre-aq.Todo $"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Pre-aq.Mesa $"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Ajustar $"); + #endif PROGMEM Language_Str MSG_PREHEAT_CUSTOM = _UxGT("Customizar Pre-aq."); PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Esfriar"); PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Ligar"); @@ -87,13 +96,16 @@ namespace Language_pt_br { PROGMEM Language_Str MSG_LEVEL_BED = _UxGT("Nivelar Mesa"); PROGMEM Language_Str MSG_LEVEL_CORNERS = _UxGT("Nivelar Cantos"); PROGMEM Language_Str MSG_NEXT_CORNER = _UxGT("Próximo Canto"); + PROGMEM Language_Str MSG_MESH_EDITOR = _UxGT("Editor de Malha"); PROGMEM Language_Str MSG_EDIT_MESH = _UxGT("Editar Malha"); PROGMEM Language_Str MSG_EDITING_STOPPED = _UxGT("Fim da Edição"); + PROGMEM Language_Str MSG_PROBING_MESH = _UxGT("Sondando ponto"); PROGMEM Language_Str MSG_MESH_X = _UxGT("Índice X"); PROGMEM Language_Str MSG_MESH_Y = _UxGT("Índice Y"); PROGMEM Language_Str MSG_MESH_EDIT_Z = _UxGT("Valor Z"); PROGMEM Language_Str MSG_USER_MENU = _UxGT("Comando customizado"); - + PROGMEM Language_Str MSG_M48_TEST = _UxGT("M48 Teste de sonda"); + PROGMEM Language_Str MSG_M48_POINT = _UxGT("M48 Ponto"); PROGMEM Language_Str MSG_IDEX_MENU = _UxGT("Modo IDEX"); PROGMEM Language_Str MSG_IDEX_MODE_AUTOPARK = _UxGT("Auto-Estacionar"); PROGMEM Language_Str MSG_IDEX_MODE_DUPLICATE = _UxGT("Duplicação"); @@ -102,7 +114,6 @@ namespace Language_pt_br { PROGMEM Language_Str MSG_HOTEND_OFFSET_X = _UxGT("2o bico X"); PROGMEM Language_Str MSG_HOTEND_OFFSET_Y = _UxGT("2o bico Y"); PROGMEM Language_Str MSG_HOTEND_OFFSET_Z = _UxGT("2o bico Z"); - PROGMEM Language_Str MSG_UBL_DOING_G29 = _UxGT("Executando G29"); PROGMEM Language_Str MSG_UBL_TOOLS = _UxGT("Ferramentas UBL"); PROGMEM Language_Str MSG_UBL_LEVEL_BED = _UxGT("Nivel. Mesa Unif."); @@ -114,24 +125,28 @@ namespace Language_pt_br { PROGMEM Language_Str MSG_UBL_ACTIVATE_MESH = _UxGT("Ativar UBL"); PROGMEM Language_Str MSG_UBL_DEACTIVATE_MESH = _UxGT("Desativar UBL"); PROGMEM Language_Str MSG_UBL_SET_TEMP_BED = _UxGT("Temp. Mesa"); - PROGMEM Language_Str MSG_UBL_BED_TEMP_CUSTOM = _UxGT("Bed Temp"); + PROGMEM Language_Str MSG_UBL_BED_TEMP_CUSTOM = _UxGT("Temp. Mesa"); PROGMEM Language_Str MSG_UBL_SET_TEMP_HOTEND = _UxGT("Temp. Extrusora"); - PROGMEM Language_Str MSG_UBL_HOTEND_TEMP_CUSTOM = _UxGT("Hotend Temp"); + PROGMEM Language_Str MSG_UBL_HOTEND_TEMP_CUSTOM = _UxGT("Temp. Extrusora"); PROGMEM Language_Str MSG_UBL_MESH_EDIT = _UxGT("Editar Malha"); PROGMEM Language_Str MSG_UBL_EDIT_CUSTOM_MESH = _UxGT("Editar Malha Custom"); PROGMEM Language_Str MSG_UBL_FINE_TUNE_MESH = _UxGT("Ajuste Fino da Malha"); PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("Fim da Edição"); PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("Montar Malha Custom"); PROGMEM Language_Str MSG_UBL_BUILD_MESH_MENU = _UxGT("Montar "); - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M1 = _UxGT("Montar ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M2 = _UxGT("Montar ") PREHEAT_2_LABEL; + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_UBL_BUILD_MESH_M = _UxGT("Montar $"); + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("Checar $"); + #endif PROGMEM Language_Str MSG_UBL_BUILD_COLD_MESH = _UxGT("Montar Malha fria"); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_ADJUST = _UxGT("Ajustar Altura"); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_AMOUNT = _UxGT("Quant. de Altura"); PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_MENU = _UxGT("Validar Malha"); - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M1 = _UxGT("Checar ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M2 = _UxGT("Checar ") PREHEAT_2_LABEL; PROGMEM Language_Str MSG_UBL_VALIDATE_CUSTOM_MESH = _UxGT("Validar Malha Custom"); + PROGMEM Language_Str MSG_G26_HEATING_BED = _UxGT("G26 Aquecendo Mesa"); + PROGMEM Language_Str MSG_G26_HEATING_NOZZLE = _UxGT("G26 Aquecendo Ext."); + PROGMEM Language_Str MSG_G26_CANCELED = _UxGT("G26 Cancelado"); + PROGMEM Language_Str MSG_G26_LEAVING = _UxGT("G26 Saindo"); PROGMEM Language_Str MSG_UBL_CONTINUE_MESH = _UxGT("Continuar Malha"); PROGMEM Language_Str MSG_UBL_MESH_LEVELING = _UxGT("Nivelação da Malha"); PROGMEM Language_Str MSG_UBL_3POINT_MESH_LEVELING = _UxGT("Nivelação 3 pontos"); @@ -156,11 +171,12 @@ namespace Language_pt_br { PROGMEM Language_Str MSG_UBL_STORAGE_SLOT = _UxGT("Slot de Memória"); PROGMEM Language_Str MSG_UBL_LOAD_MESH = _UxGT("Ler Malha"); PROGMEM Language_Str MSG_UBL_SAVE_MESH = _UxGT("Salvar Malha"); - PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("M117 Malha %i carregada"); - PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("M117 Malha %i salva"); + PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("Malha %i carregada"); + PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("Malha %i salva"); PROGMEM Language_Str MSG_UBL_NO_STORAGE = _UxGT("Sem armazenamento"); PROGMEM Language_Str MSG_UBL_SAVE_ERROR = _UxGT("Erro ao salvar UBL"); PROGMEM Language_Str MSG_UBL_RESTORE_ERROR = _UxGT("Erro no restauro UBL"); + PROGMEM Language_Str MSG_UBL_Z_OFFSET = _UxGT("Compensação Z: "); PROGMEM Language_Str MSG_UBL_Z_OFFSET_STOPPED = _UxGT("Compensação Z parou"); PROGMEM Language_Str MSG_UBL_STEP_BY_STEP_MENU = _UxGT("UBL passo a passo"); PROGMEM Language_Str MSG_UBL_1_BUILD_COLD_MESH = _UxGT("1.Montar Malha fria"); @@ -189,6 +205,7 @@ namespace Language_pt_br { PROGMEM Language_Str MSG_INTENSITY_B = _UxGT("Intensidade Azul"); PROGMEM Language_Str MSG_INTENSITY_W = _UxGT("Intensidade Branco"); PROGMEM Language_Str MSG_LED_BRIGHTNESS = _UxGT("Brilho"); + PROGMEM Language_Str MSG_MOVING = _UxGT("Movendo..."); PROGMEM Language_Str MSG_FREE_XY = _UxGT("Liberar XY"); PROGMEM Language_Str MSG_MOVE_X = _UxGT("Mover X"); @@ -260,9 +277,22 @@ namespace Language_pt_br { PROGMEM Language_Str MSG_INFO_SCREEN = _UxGT("Informações"); PROGMEM Language_Str MSG_PREPARE = _UxGT("Preparar"); PROGMEM Language_Str MSG_TUNE = _UxGT("Ajustar"); + PROGMEM Language_Str MSG_START_PRINT = _UxGT("Iniciar Impressão"); + PROGMEM Language_Str MSG_BUTTON_NEXT = _UxGT("Prox."); + PROGMEM Language_Str MSG_BUTTON_INIT = _UxGT("Iniciar"); + PROGMEM Language_Str MSG_BUTTON_STOP = _UxGT("Parar"); + PROGMEM Language_Str MSG_BUTTON_PRINT = _UxGT("Imprimir"); + PROGMEM Language_Str MSG_BUTTON_RESET = _UxGT("Resetar"); + PROGMEM Language_Str MSG_BUTTON_CANCEL = _UxGT("Cancelar"); + PROGMEM Language_Str MSG_BUTTON_DONE = _UxGT("Pronto"); + PROGMEM Language_Str MSG_BUTTON_BACK = _UxGT("Voltar"); + PROGMEM Language_Str MSG_BUTTON_PROCEED = _UxGT("Continuar"); PROGMEM Language_Str MSG_PAUSE_PRINT = _UxGT("Pausar impressão"); - PROGMEM Language_Str MSG_RESUME_PRINT = _UxGT("Resumir impressão"); + PROGMEM Language_Str MSG_RESUME_PRINT = _UxGT("Continuar impressão"); PROGMEM Language_Str MSG_STOP_PRINT = _UxGT("Parar impressão"); + PROGMEM Language_Str MSG_PRINTING_OBJECT = _UxGT("Imprimindo objeto"); + PROGMEM Language_Str MSG_CANCEL_OBJECT = _UxGT("Cancelar Objeto"); + PROGMEM Language_Str MSG_CANCEL_OBJECT_N = _UxGT("Cancelar Objeto ="); PROGMEM Language_Str MSG_OUTAGE_RECOVERY = _UxGT("Recuperar Impressão"); PROGMEM Language_Str MSG_MEDIA_MENU = _UxGT("Imprimir do SD"); PROGMEM Language_Str MSG_NO_MEDIA = _UxGT("Sem cartão SD"); @@ -284,43 +314,48 @@ namespace Language_pt_br { PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAPF = _UxGT("Des-RetTroca V"); PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("Retração Automática"); PROGMEM Language_Str MSG_FILAMENT_SWAP_LENGTH = _UxGT("Distancia Retração"); + PROGMEM Language_Str MSG_FILAMENT_PURGE_LENGTH = _UxGT("Distancia Purga"); PROGMEM Language_Str MSG_TOOL_CHANGE = _UxGT("Mudar Ferramenta"); PROGMEM Language_Str MSG_TOOL_CHANGE_ZLIFT = _UxGT("Levantar Z"); - PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPD = _UxGT("Preparar Veloc."); - PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPD = _UxGT("Veloc. Retração"); + PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPEED = _UxGT("Preparar Veloc."); + PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPEED = _UxGT("Veloc. Retração"); + PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("Standby bico"); PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("Trocar Filamento"); PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Trocar Filamento *"); + PROGMEM Language_Str MSG_FILAMENTLOAD = _UxGT("Carregar Filamento"); PROGMEM Language_Str MSG_FILAMENTLOAD_E = _UxGT("Carregar Filamento *"); + PROGMEM Language_Str MSG_FILAMENTUNLOAD = _UxGT("Descarreg. Filamento"); PROGMEM Language_Str MSG_FILAMENTUNLOAD_E = _UxGT("Descarreg. Filamento *"); PROGMEM Language_Str MSG_FILAMENTUNLOAD_ALL = _UxGT("Descarregar Todos"); PROGMEM Language_Str MSG_ATTACH_MEDIA = _UxGT("Iniciar SD"); PROGMEM Language_Str MSG_CHANGE_MEDIA = _UxGT("Trocar SD"); + PROGMEM Language_Str MSG_RELEASE_MEDIA = _UxGT("Liberar SD"); PROGMEM Language_Str MSG_ZPROBE_OUT = _UxGT("Sonda fora da mesa"); PROGMEM Language_Str MSG_SKEW_FACTOR = _UxGT("Fator de Cisalho"); PROGMEM Language_Str MSG_BLTOUCH = _UxGT("BLTouch"); PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("Testar BLTouch"); PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("Reiniciar BLTouch"); - PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("Estender BLTouch"); PROGMEM Language_Str MSG_BLTOUCH_STOW = _UxGT("Recolher BLTouch"); + PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("Estender BLTouch"); PROGMEM Language_Str MSG_MANUAL_DEPLOY = _UxGT("Estender Sonda-Z"); PROGMEM Language_Str MSG_MANUAL_STOW = _UxGT("Recolher Sonda-Z"); - PROGMEM Language_Str MSG_HOME_FIRST = _UxGT("Home %s%s%s Primeiro"); + PROGMEM Language_Str MSG_ZPROBE_OFFSETS = _UxGT("Compensar Sonda"); + PROGMEM Language_Str MSG_ZPROBE_XOFFSET = _UxGT("Compensar Sonda em X"); + PROGMEM Language_Str MSG_ZPROBE_YOFFSET = _UxGT("Compensar Sonda em Y"); PROGMEM Language_Str MSG_ZPROBE_ZOFFSET = _UxGT("Compensar Sonda em Z"); PROGMEM Language_Str MSG_BABYSTEP_X = _UxGT("Passinho X"); PROGMEM Language_Str MSG_BABYSTEP_Y = _UxGT("Passinho Y"); PROGMEM Language_Str MSG_BABYSTEP_Z = _UxGT("Passinho Z"); + PROGMEM Language_Str MSG_BABYSTEP_TOTAL = _UxGT("Total"); PROGMEM Language_Str MSG_ENDSTOP_ABORT = _UxGT("Abortar Fim de Curso"); PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("Aquecimento falhou"); - PROGMEM Language_Str MSG_HEATING_FAILED_LCD_BED = _UxGT("Aquecer mesa falhou"); PROGMEM Language_Str MSG_ERR_REDUNDANT_TEMP = _UxGT("Erro:Temp Redundante"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("ESCAPE TÉRMICO"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY_BED = _UxGT("ESCAPE TÉRMICO MESA"); + PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER = _UxGT("ESCAPE TÉRMICO CAMARA"); PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("Erro:Temp Máxima"); PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("Erro:Temp Mínima"); - PROGMEM Language_Str MSG_ERR_MAXTEMP_BED = _UxGT("Erro:Temp Mesa Máx"); - PROGMEM Language_Str MSG_ERR_MINTEMP_BED = _UxGT("Erro:Temp Mesa Mín"); - PROGMEM Language_Str MSG_ERR_Z_HOMING = _UxGT("Home XY Primeiro"); PROGMEM Language_Str MSG_HALTED = _UxGT("IMPRESSORA PAROU"); PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("Favor resetar"); PROGMEM Language_Str MSG_SHORT_DAY = _UxGT("d"); @@ -330,12 +365,13 @@ namespace Language_pt_br { PROGMEM Language_Str MSG_COOLING = _UxGT("Resfriando..."); PROGMEM Language_Str MSG_BED_HEATING = _UxGT("Aquecendo mesa..."); PROGMEM Language_Str MSG_BED_COOLING = _UxGT("Esfriando mesa..."); + PROGMEM Language_Str MSG_CHAMBER_HEATING = _UxGT("Aquecendo Câmara..."); + PROGMEM Language_Str MSG_CHAMBER_COOLING = _UxGT("Esfriando Câmara..."); PROGMEM Language_Str MSG_DELTA_CALIBRATE = _UxGT("Calibrar Delta"); PROGMEM Language_Str MSG_DELTA_CALIBRATE_X = _UxGT("Calibrar X"); PROGMEM Language_Str MSG_DELTA_CALIBRATE_Y = _UxGT("Calibrar Y"); PROGMEM Language_Str MSG_DELTA_CALIBRATE_Z = _UxGT("Calibrar Z"); PROGMEM Language_Str MSG_DELTA_CALIBRATE_CENTER = _UxGT("Calibrar Centro"); - PROGMEM Language_Str MSG_DELTA_SETTINGS = _UxGT("Configuração Delta"); PROGMEM Language_Str MSG_DELTA_AUTO_CALIBRATE = _UxGT("Auto-Calibração"); PROGMEM Language_Str MSG_DELTA_HEIGHT_CALIBRATE = _UxGT("Calibrar Altura"); @@ -356,10 +392,10 @@ namespace Language_pt_br { PROGMEM Language_Str MSG_INFO_EXTRUDERS = _UxGT("Extrusoras"); PROGMEM Language_Str MSG_INFO_BAUDRATE = _UxGT("Taxa de Transmissão"); PROGMEM Language_Str MSG_INFO_PROTOCOL = _UxGT("Protocolo"); + PROGMEM Language_Str MSG_CASE_LIGHT = _UxGT("Luz da Impressora"); PROGMEM Language_Str MSG_CASE_LIGHT_BRIGHTNESS = _UxGT("Intensidade Brilho"); - - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("Impressora Incorreta"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("Impressora Incorreta"); #if LCD_WIDTH >= 20 PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Total de Impressões"); @@ -380,7 +416,7 @@ namespace Language_pt_br { PROGMEM Language_Str MSG_INFO_PSU = _UxGT("PSU"); PROGMEM Language_Str MSG_DRIVE_STRENGTH = _UxGT("Força do Motor"); PROGMEM Language_Str MSG_DAC_EEPROM_WRITE = _UxGT("Escrever EEPROM DAC"); - + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER = _UxGT("TROCA DE FILAMENTO"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_PAUSE = _UxGT("IMPRESSÃO PAUSADA"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_LOAD = _UxGT("CARREGAR FILAMENTO"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_UNLOAD = _UxGT("DESCARREG. FILAMENTO"); @@ -389,12 +425,37 @@ namespace Language_pt_br { PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_RESUME = _UxGT("Continuar Impressão"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" Bocal: "); PROGMEM Language_Str MSG_RUNOUT_SENSOR = _UxGT("Sensor filamento"); - PROGMEM Language_Str MSG_LCD_HOMING_FAILED = _UxGT("Falha ao ir à origem"); + PROGMEM Language_Str MSG_KILL_HOMING_FAILED = _UxGT("Falha ao ir à origem"); PROGMEM Language_Str MSG_LCD_PROBING_FAILED = _UxGT("Falha ao sondar"); - PROGMEM Language_Str MSG_M600_TOO_COLD = _UxGT("M600: Muito frio"); + + PROGMEM Language_Str MSG_MMU2_CHOOSE_FILAMENT_HEADER = _UxGT("ESCOLHER FILAMENTO"); + PROGMEM Language_Str MSG_MMU2_MENU = _UxGT("MMU"); + + PROGMEM Language_Str MSG_MMU2_RESUME = _UxGT("Continuar Impressão"); + PROGMEM Language_Str MSG_MMU2_RESUMING = _UxGT("Continuando..."); + PROGMEM Language_Str MSG_MMU2_LOAD_FILAMENT = _UxGT("Carregar Filamento"); + PROGMEM Language_Str MSG_MMU2_LOAD_ALL = _UxGT("Carregar Todos"); + PROGMEM Language_Str MSG_MMU2_LOAD_TO_NOZZLE = _UxGT("Carregar para bocal"); + PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT = _UxGT("Ejetar Filamento"); + PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT_N = _UxGT("Ejetar Filamento ~"); + PROGMEM Language_Str MSG_MMU2_UNLOAD_FILAMENT = _UxGT("Liberar Filamento"); + PROGMEM Language_Str MSG_MMU2_LOADING_FILAMENT = _UxGT("Carregando Fil. %i..."); + PROGMEM Language_Str MSG_MMU2_EJECTING_FILAMENT = _UxGT("Ejetando Fil. ..."); + PROGMEM Language_Str MSG_MMU2_UNLOADING_FILAMENT = _UxGT("Carregando Fil...."); + PROGMEM Language_Str MSG_MMU2_ALL = _UxGT("Todos"); + PROGMEM Language_Str MSG_MMU2_FILAMENT_N = _UxGT("Filamento ~"); + PROGMEM Language_Str MSG_MMU2_RESET = _UxGT("Resetar MMU"); + PROGMEM Language_Str MSG_MMU2_RESETTING = _UxGT("Resetando MMU..."); + + PROGMEM Language_Str MSG_GAMES = _UxGT("Jogos"); + PROGMEM Language_Str MSG_BRICKOUT = _UxGT("Brickout"); + PROGMEM Language_Str MSG_INVADERS = _UxGT("Invaders"); + PROGMEM Language_Str MSG_SNAKE = _UxGT("Sn4k3"); + PROGMEM Language_Str MSG_MAZE = _UxGT("Labirinto"); #if LCD_HEIGHT >= 4 PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_2_LINE("Aperte o botão para", "continuar impressão")); + PROGMEM Language_Str MSG_PAUSE_PRINT_INIT = _UxGT(MSG_1_LINE("Estacionando...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_3_LINE("Esperando o", "inicio da", "troca de filamento")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_3_LINE("Coloque filamento", "pressione o botão", "para continuar...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_2_LINE("Pressione o botão", "p/ aquecer o bocal")); @@ -406,8 +467,10 @@ namespace Language_pt_br { PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_2_LINE("Esperando impressão", "continuar")); #else // LCD_HEIGHT < 4 PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_1_LINE("Clique p. continuar")); + PROGMEM Language_Str MSG_PAUSE_PRINT_INIT = _UxGT(MSG_1_LINE("Estacionando...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_1_LINE("Aguarde...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_1_LINE("Insira e Clique")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_1_LINE("Clique para Aquecer")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEATING = _UxGT(MSG_1_LINE("Aquecendo...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_1_LINE("Ejetando...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_1_LINE("Carregando...")); diff --git a/Marlin/src/lcd/language/language_ro.h b/Marlin/src/lcd/language/language_ro.h new file mode 100644 index 000000000000..7b54f24abf7d --- /dev/null +++ b/Marlin/src/lcd/language/language_ro.h @@ -0,0 +1,638 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + + /** + * Romanian + * + * LCD Menu Messages + * See also https://marlinfw.org/docs/development/lcd_language.html + * + * Translation by cristyanul + */ +namespace Language_ro { + using namespace Language_en; // Inherit undefined strings from English + + constexpr uint8_t CHARSIZE = 2; + PROGMEM Language_Str LANGUAGE = _UxGT("Romanian"); + + PROGMEM Language_Str WELCOME_MSG = MACHINE_NAME _UxGT(" Pregatit."); + PROGMEM Language_Str MSG_MARLIN = _UxGT("Marlin"); + PROGMEM Language_Str MSG_YES = _UxGT("DA"); + PROGMEM Language_Str MSG_NO = _UxGT("NU"); + PROGMEM Language_Str MSG_BACK = _UxGT("Inapoi"); + PROGMEM Language_Str MSG_MEDIA_ABORTING = _UxGT("Abandon..."); + PROGMEM Language_Str MSG_MEDIA_INSERTED = _UxGT("Media Introdus"); + PROGMEM Language_Str MSG_MEDIA_REMOVED = _UxGT("Media Inlaturat"); + PROGMEM Language_Str MSG_MEDIA_WAITING = _UxGT("Astept Media"); + PROGMEM Language_Str MSG_MEDIA_READ_ERROR = _UxGT("Eroare Citire Media"); + PROGMEM Language_Str MSG_MEDIA_USB_REMOVED = _UxGT("Dispozitiv USB Inlaturat"); + PROGMEM Language_Str MSG_MEDIA_USB_FAILED = _UxGT("Pornire USB Esuata"); + PROGMEM Language_Str MSG_KILL_SUBCALL_OVERFLOW = _UxGT("Eroare:Subcall Overflow"); + PROGMEM Language_Str MSG_LCD_ENDSTOPS = _UxGT("Endstops"); // Max length 8 characters + PROGMEM Language_Str MSG_LCD_SOFT_ENDSTOPS = _UxGT("Soft Endstops"); + PROGMEM Language_Str MSG_MAIN = _UxGT("Principal"); + PROGMEM Language_Str MSG_ADVANCED_SETTINGS = _UxGT("Setari Avansate"); + PROGMEM Language_Str MSG_CONFIGURATION = _UxGT("Configurare"); + PROGMEM Language_Str MSG_AUTOSTART = _UxGT("Autostart"); + PROGMEM Language_Str MSG_DISABLE_STEPPERS = _UxGT("Dezactivare Motoare"); + PROGMEM Language_Str MSG_DEBUG_MENU = _UxGT("Meniu Debug"); + PROGMEM Language_Str MSG_PROGRESS_BAR_TEST = _UxGT("Test Bara Progres"); + PROGMEM Language_Str MSG_AUTO_HOME = _UxGT("Auto Acasa"); + PROGMEM Language_Str MSG_AUTO_HOME_X = _UxGT("Acasa X"); + PROGMEM Language_Str MSG_AUTO_HOME_Y = _UxGT("Acasa Y"); + PROGMEM Language_Str MSG_AUTO_HOME_Z = _UxGT("Acasa Z"); + PROGMEM Language_Str MSG_AUTO_Z_ALIGN = _UxGT("Auto Aliniere-Z"); + PROGMEM Language_Str MSG_LEVEL_BED_HOMING = _UxGT("Acasa XYZ"); + PROGMEM Language_Str MSG_LEVEL_BED_WAITING = _UxGT("Click pentru a incepe"); + PROGMEM Language_Str MSG_LEVEL_BED_NEXT_POINT = _UxGT("Urmatorul Punct"); + PROGMEM Language_Str MSG_LEVEL_BED_DONE = _UxGT("Nivelare Terminata!"); + PROGMEM Language_Str MSG_Z_FADE_HEIGHT = _UxGT("Fade Inaltime"); + PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Seteaza Offseturile Acasa"); + PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Offseturi Aplicate"); + PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Seteaza Originea"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Preincalzeste ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Preincalzeste ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Preincalzeste ") PREHEAT_1_LABEL _UxGT(" Capatul"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Preincalzeste ") PREHEAT_1_LABEL _UxGT(" Capatul ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Preincalzeste ") PREHEAT_1_LABEL _UxGT(" Tot"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Preincalzeste ") PREHEAT_1_LABEL _UxGT(" Patul"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Preincalzeste ") PREHEAT_1_LABEL _UxGT(" Conf"); + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Preincalzeste $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Preincalzeste $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Preincalzeste $ Capatul"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Preincalzeste $ Capatul ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Preincalzeste $ Tot"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Preincalzeste $ Patul"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Preincalzeste $ Conf"); + #endif + PROGMEM Language_Str MSG_PREHEAT_CUSTOM = _UxGT("Preincalzeste Personalizat"); + PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Racire"); + PROGMEM Language_Str MSG_CUTTER_FREQUENCY = _UxGT("Frecventa"); + PROGMEM Language_Str MSG_LASER_MENU = _UxGT("Control Laser"); + PROGMEM Language_Str MSG_LASER_OFF = _UxGT("Laser Oprit"); + PROGMEM Language_Str MSG_LASER_ON = _UxGT("Laser Pornit"); + PROGMEM Language_Str MSG_LASER_POWER = _UxGT("Puterea Laserului"); + PROGMEM Language_Str MSG_SPINDLE_MENU = _UxGT("Controlul Spindle"); + PROGMEM Language_Str MSG_SPINDLE_OFF = _UxGT("Spindle Oprit"); + PROGMEM Language_Str MSG_SPINDLE_ON = _UxGT("Spindle Pornit"); + PROGMEM Language_Str MSG_SPINDLE_POWER = _UxGT("Puterea Spindle"); + PROGMEM Language_Str MSG_SPINDLE_REVERSE = _UxGT("Spindle Invers"); + PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Porneste"); + PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("Opreste"); + PROGMEM Language_Str MSG_EXTRUDE = _UxGT("Extrudeaza"); + PROGMEM Language_Str MSG_RETRACT = _UxGT("Retracteaza"); + PROGMEM Language_Str MSG_MOVE_AXIS = _UxGT("Muta Axa"); + PROGMEM Language_Str MSG_BED_LEVELING = _UxGT("Nivelarea Patului"); + PROGMEM Language_Str MSG_LEVEL_BED = _UxGT("Niveleaza Patul"); + PROGMEM Language_Str MSG_LEVEL_CORNERS = _UxGT("Niveleaza Colturile"); + PROGMEM Language_Str MSG_NEXT_CORNER = _UxGT("Urmatorul Colt"); + PROGMEM Language_Str MSG_MESH_EDITOR = _UxGT("Editor Mesh"); + PROGMEM Language_Str MSG_EDIT_MESH = _UxGT("Editeaza Mesh"); + PROGMEM Language_Str MSG_EDITING_STOPPED = _UxGT("Editarea Meshului Oprita"); + PROGMEM Language_Str MSG_PROBING_MESH = _UxGT("Punctul de Probare"); + PROGMEM Language_Str MSG_MESH_X = _UxGT("Index X"); + PROGMEM Language_Str MSG_MESH_Y = _UxGT("Index Y"); + PROGMEM Language_Str MSG_MESH_EDIT_Z = _UxGT("Valoare Z"); + PROGMEM Language_Str MSG_USER_MENU = _UxGT("Comenzi Personalizate"); + PROGMEM Language_Str MSG_M48_TEST = _UxGT("M48 Probe Test"); + PROGMEM Language_Str MSG_M48_POINT = _UxGT("M48 Point"); + PROGMEM Language_Str MSG_M48_DEVIATION = _UxGT("Deviation"); + PROGMEM Language_Str MSG_IDEX_MENU = _UxGT("IDEX Mode"); + PROGMEM Language_Str MSG_OFFSETS_MENU = _UxGT("Tool Offsets"); + PROGMEM Language_Str MSG_IDEX_MODE_AUTOPARK = _UxGT("Auto-Park"); + PROGMEM Language_Str MSG_IDEX_MODE_DUPLICATE = _UxGT("Duplication"); + PROGMEM Language_Str MSG_IDEX_MODE_MIRRORED_COPY = _UxGT("Mirrored Copy"); + PROGMEM Language_Str MSG_IDEX_MODE_FULL_CTRL = _UxGT("Full Control"); + PROGMEM Language_Str MSG_HOTEND_OFFSET_X = _UxGT("2nd Nozzle X"); + PROGMEM Language_Str MSG_HOTEND_OFFSET_Y = _UxGT("2nd Nozzle Y"); + PROGMEM Language_Str MSG_HOTEND_OFFSET_Z = _UxGT("2nd Nozzle Z"); + PROGMEM Language_Str MSG_UBL_DOING_G29 = _UxGT("Doing G29"); + PROGMEM Language_Str MSG_UBL_TOOLS = _UxGT("UBL Tools"); + PROGMEM Language_Str MSG_UBL_LEVEL_BED = _UxGT("Unified Bed Leveling"); + PROGMEM Language_Str MSG_LCD_TILTING_MESH = _UxGT("Tilting Point"); + PROGMEM Language_Str MSG_UBL_MANUAL_MESH = _UxGT("Manually Build Mesh"); + PROGMEM Language_Str MSG_UBL_BC_INSERT = _UxGT("Place Shim & Measure"); + PROGMEM Language_Str MSG_UBL_BC_INSERT2 = _UxGT("Measure"); + PROGMEM Language_Str MSG_UBL_BC_REMOVE = _UxGT("Remove & Measure Bed"); + PROGMEM Language_Str MSG_UBL_MOVING_TO_NEXT = _UxGT("Moving to next"); + PROGMEM Language_Str MSG_UBL_ACTIVATE_MESH = _UxGT("Activate UBL"); + PROGMEM Language_Str MSG_UBL_DEACTIVATE_MESH = _UxGT("Deactivate UBL"); + PROGMEM Language_Str MSG_UBL_SET_TEMP_BED = _UxGT("Bed Temp"); + PROGMEM Language_Str MSG_UBL_BED_TEMP_CUSTOM = _UxGT("Bed Temp"); + PROGMEM Language_Str MSG_UBL_SET_TEMP_HOTEND = _UxGT("Hotend Temp"); + PROGMEM Language_Str MSG_UBL_HOTEND_TEMP_CUSTOM = _UxGT("Hotend Temp"); + PROGMEM Language_Str MSG_UBL_MESH_EDIT = _UxGT("Mesh Edit"); + PROGMEM Language_Str MSG_UBL_EDIT_CUSTOM_MESH = _UxGT("Edit Custom Mesh"); + PROGMEM Language_Str MSG_UBL_FINE_TUNE_MESH = _UxGT("Fine Tuning Mesh"); + PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("Done Editing Mesh"); + PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("Build Custom Mesh"); + PROGMEM Language_Str MSG_UBL_BUILD_MESH_MENU = _UxGT("Build Mesh"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_UBL_BUILD_MESH_M = _UxGT("Build Mesh ($)"); + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("Validate Mesh ($)"); + #endif + PROGMEM Language_Str MSG_UBL_BUILD_COLD_MESH = _UxGT("Build Cold Mesh"); + PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_ADJUST = _UxGT("Adjust Mesh Height"); + PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_AMOUNT = _UxGT("Height Amount"); + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_MENU = _UxGT("Validate Mesh"); + PROGMEM Language_Str MSG_UBL_VALIDATE_CUSTOM_MESH = _UxGT("Validate Custom Mesh"); + PROGMEM Language_Str MSG_G26_HEATING_BED = _UxGT("G26 Heating Bed"); + PROGMEM Language_Str MSG_G26_HEATING_NOZZLE = _UxGT("G26 Heating Nozzle"); + PROGMEM Language_Str MSG_G26_MANUAL_PRIME = _UxGT("Manual priming..."); + PROGMEM Language_Str MSG_G26_FIXED_LENGTH = _UxGT("Fixed Length Prime"); + PROGMEM Language_Str MSG_G26_PRIME_DONE = _UxGT("Done Priming"); + PROGMEM Language_Str MSG_G26_CANCELED = _UxGT("G26 Canceled"); + PROGMEM Language_Str MSG_G26_LEAVING = _UxGT("Leaving G26"); + PROGMEM Language_Str MSG_UBL_CONTINUE_MESH = _UxGT("Continue Bed Mesh"); + PROGMEM Language_Str MSG_UBL_MESH_LEVELING = _UxGT("Mesh Leveling"); + PROGMEM Language_Str MSG_UBL_3POINT_MESH_LEVELING = _UxGT("3-Point Leveling"); + PROGMEM Language_Str MSG_UBL_GRID_MESH_LEVELING = _UxGT("Grid Mesh Leveling"); + PROGMEM Language_Str MSG_UBL_MESH_LEVEL = _UxGT("Level Mesh"); + PROGMEM Language_Str MSG_UBL_SIDE_POINTS = _UxGT("Side Points"); + PROGMEM Language_Str MSG_UBL_MAP_TYPE = _UxGT("Map Type"); + PROGMEM Language_Str MSG_UBL_OUTPUT_MAP = _UxGT("Output Mesh Map"); + PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_HOST = _UxGT("Output for Host"); + PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_CSV = _UxGT("Output for CSV"); + PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_BACKUP = _UxGT("Off Imprimanta Backup"); + PROGMEM Language_Str MSG_UBL_INFO_UBL = _UxGT("Output UBL Info"); + PROGMEM Language_Str MSG_UBL_FILLIN_AMOUNT = _UxGT("Fill-in Amount"); + PROGMEM Language_Str MSG_UBL_MANUAL_FILLIN = _UxGT("Manual Fill-in"); + PROGMEM Language_Str MSG_UBL_SMART_FILLIN = _UxGT("Smart Fill-in"); + PROGMEM Language_Str MSG_UBL_FILLIN_MESH = _UxGT("Fill-in Mesh"); + PROGMEM Language_Str MSG_UBL_INVALIDATE_ALL = _UxGT("Invalidate All"); + PROGMEM Language_Str MSG_UBL_INVALIDATE_CLOSEST = _UxGT("Invalidate Closest"); + PROGMEM Language_Str MSG_UBL_FINE_TUNE_ALL = _UxGT("Fine Tune All"); + PROGMEM Language_Str MSG_UBL_FINE_TUNE_CLOSEST = _UxGT("Fine Tune Closest"); + PROGMEM Language_Str MSG_UBL_STORAGE_MESH_MENU = _UxGT("Mesh Storage"); + PROGMEM Language_Str MSG_UBL_STORAGE_SLOT = _UxGT("Memory Slot"); + PROGMEM Language_Str MSG_UBL_LOAD_MESH = _UxGT("Load Bed Mesh"); + PROGMEM Language_Str MSG_UBL_SAVE_MESH = _UxGT("Save Bed Mesh"); + PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("Mesh %i Loaded"); + PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("Mesh %i Saved"); + PROGMEM Language_Str MSG_UBL_NO_STORAGE = _UxGT("No Storage"); + PROGMEM Language_Str MSG_UBL_SAVE_ERROR = _UxGT("Err: UBL Save"); + PROGMEM Language_Str MSG_UBL_RESTORE_ERROR = _UxGT("Err: UBL Restore"); + PROGMEM Language_Str MSG_UBL_Z_OFFSET = _UxGT("Z-Offset: "); + PROGMEM Language_Str MSG_UBL_Z_OFFSET_STOPPED = _UxGT("Z-Offset Stopped"); + PROGMEM Language_Str MSG_UBL_STEP_BY_STEP_MENU = _UxGT("Step-By-Step UBL"); + PROGMEM Language_Str MSG_UBL_1_BUILD_COLD_MESH = _UxGT("1. Build Cold Mesh"); + PROGMEM Language_Str MSG_UBL_2_SMART_FILLIN = _UxGT("2. Smart Fill-in"); + PROGMEM Language_Str MSG_UBL_3_VALIDATE_MESH_MENU = _UxGT("3. Validate Mesh"); + PROGMEM Language_Str MSG_UBL_4_FINE_TUNE_ALL = _UxGT("4. Fine Tune All"); + PROGMEM Language_Str MSG_UBL_5_VALIDATE_MESH_MENU = _UxGT("5. Validate Mesh"); + PROGMEM Language_Str MSG_UBL_6_FINE_TUNE_ALL = _UxGT("6. Fine Tune All"); + PROGMEM Language_Str MSG_UBL_7_SAVE_MESH = _UxGT("7. Save Bed Mesh"); + + PROGMEM Language_Str MSG_LED_CONTROL = _UxGT("LED Control"); + PROGMEM Language_Str MSG_LEDS = _UxGT("Lights"); + PROGMEM Language_Str MSG_LED_PRESETS = _UxGT("Light Presets"); + PROGMEM Language_Str MSG_SET_LEDS_RED = _UxGT("Red"); + PROGMEM Language_Str MSG_SET_LEDS_ORANGE = _UxGT("Orange"); + PROGMEM Language_Str MSG_SET_LEDS_YELLOW = _UxGT("Yellow"); + PROGMEM Language_Str MSG_SET_LEDS_GREEN = _UxGT("Green"); + PROGMEM Language_Str MSG_SET_LEDS_BLUE = _UxGT("Blue"); + PROGMEM Language_Str MSG_SET_LEDS_INDIGO = _UxGT("Indigo"); + PROGMEM Language_Str MSG_SET_LEDS_VIOLET = _UxGT("Violet"); + PROGMEM Language_Str MSG_SET_LEDS_WHITE = _UxGT("White"); + PROGMEM Language_Str MSG_SET_LEDS_DEFAULT = _UxGT("Default"); + PROGMEM Language_Str MSG_CUSTOM_LEDS = _UxGT("Custom Lights"); + PROGMEM Language_Str MSG_INTENSITY_R = _UxGT("Red Intensity"); + PROGMEM Language_Str MSG_INTENSITY_G = _UxGT("Green Intensity"); + PROGMEM Language_Str MSG_INTENSITY_B = _UxGT("Blue Intensity"); + PROGMEM Language_Str MSG_INTENSITY_W = _UxGT("White Intensity"); + PROGMEM Language_Str MSG_LED_BRIGHTNESS = _UxGT("Brightness"); + + PROGMEM Language_Str MSG_MOVING = _UxGT("Moving..."); + PROGMEM Language_Str MSG_FREE_XY = _UxGT("Free XY"); + PROGMEM Language_Str MSG_MOVE_X = _UxGT("Move X"); + PROGMEM Language_Str MSG_MOVE_Y = _UxGT("Move Y"); + PROGMEM Language_Str MSG_MOVE_Z = _UxGT("Move Z"); + PROGMEM Language_Str MSG_MOVE_E = _UxGT("Extruder"); + PROGMEM Language_Str MSG_MOVE_EN = _UxGT("Extruder *"); + PROGMEM Language_Str MSG_HOTEND_TOO_COLD = _UxGT("Capat Prea Rece"); + PROGMEM Language_Str MSG_MOVE_Z_DIST = _UxGT("Move %smm"); + PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Move 0.1mm"); + PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Move 1mm"); + PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Move 10mm"); + PROGMEM Language_Str MSG_SPEED = _UxGT("Speed"); + PROGMEM Language_Str MSG_BED_Z = _UxGT("Bed Z"); + PROGMEM Language_Str MSG_NOZZLE = _UxGT("Nozzle"); + PROGMEM Language_Str MSG_NOZZLE_N = _UxGT("Nozzle ~"); + PROGMEM Language_Str MSG_NOZZLE_PARKED = _UxGT("Nozzle Parked"); + PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("Nozzle Standby"); + PROGMEM Language_Str MSG_BED = _UxGT("Bed"); + PROGMEM Language_Str MSG_CHAMBER = _UxGT("Enclosure"); + PROGMEM Language_Str MSG_FAN_SPEED = _UxGT("Fan Speed"); + PROGMEM Language_Str MSG_FAN_SPEED_N = _UxGT("Fan Speed ~"); + PROGMEM Language_Str MSG_STORED_FAN_N = _UxGT("Stored Fan ~"); + PROGMEM Language_Str MSG_EXTRA_FAN_SPEED = _UxGT("Extra Fan Speed"); + PROGMEM Language_Str MSG_EXTRA_FAN_SPEED_N = _UxGT("Extra Fan Speed ~"); + PROGMEM Language_Str MSG_CONTROLLER_FAN = _UxGT("Controller Fan"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_IDLE_SPEED = _UxGT("Idle Speed"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_AUTO_ON = _UxGT("Auto Mode"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_SPEED = _UxGT("Active Speed"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_DURATION = _UxGT("Idle Period"); + PROGMEM Language_Str MSG_FLOW = _UxGT("Flow"); + PROGMEM Language_Str MSG_FLOW_N = _UxGT("Flow ~"); + PROGMEM Language_Str MSG_CONTROL = _UxGT("Control"); + PROGMEM Language_Str MSG_MIN = " " LCD_STR_THERMOMETER _UxGT(" Min"); + PROGMEM Language_Str MSG_MAX = " " LCD_STR_THERMOMETER _UxGT(" Max"); + PROGMEM Language_Str MSG_FACTOR = " " LCD_STR_THERMOMETER _UxGT(" Fact"); + PROGMEM Language_Str MSG_AUTOTEMP = _UxGT("Autotemp"); + PROGMEM Language_Str MSG_LCD_ON = _UxGT("On"); + PROGMEM Language_Str MSG_LCD_OFF = _UxGT("Off"); + PROGMEM Language_Str MSG_PID_AUTOTUNE = _UxGT("PID Autotune"); + PROGMEM Language_Str MSG_PID_AUTOTUNE_E = _UxGT("PID Autotune *"); + PROGMEM Language_Str MSG_PID_AUTOTUNE_DONE = _UxGT("PID tuning done"); + PROGMEM Language_Str MSG_PID_BAD_EXTRUDER_NUM = _UxGT("Autotune failed. Bad extruder."); + PROGMEM Language_Str MSG_PID_TEMP_TOO_HIGH = _UxGT("Autotune failed. Temperature too high."); + PROGMEM Language_Str MSG_PID_TIMEOUT = _UxGT("Autotune failed! Timeout."); + PROGMEM Language_Str MSG_PID_P = _UxGT("PID-P"); + PROGMEM Language_Str MSG_PID_P_E = _UxGT("PID-P *"); + PROGMEM Language_Str MSG_PID_I = _UxGT("PID-I"); + PROGMEM Language_Str MSG_PID_I_E = _UxGT("PID-I *"); + PROGMEM Language_Str MSG_PID_D = _UxGT("PID-D"); + PROGMEM Language_Str MSG_PID_D_E = _UxGT("PID-D *"); + PROGMEM Language_Str MSG_PID_C = _UxGT("PID-C"); + PROGMEM Language_Str MSG_PID_C_E = _UxGT("PID-C *"); + PROGMEM Language_Str MSG_PID_F = _UxGT("PID-F"); + PROGMEM Language_Str MSG_PID_F_E = _UxGT("PID-F *"); + PROGMEM Language_Str MSG_SELECT = _UxGT("Select"); + PROGMEM Language_Str MSG_SELECT_E = _UxGT("Select *"); + PROGMEM Language_Str MSG_ACC = _UxGT("Accel"); + PROGMEM Language_Str MSG_JERK = _UxGT("Jerk"); + PROGMEM Language_Str MSG_VA_JERK = _UxGT("V") LCD_STR_A _UxGT("-Jerk"); + PROGMEM Language_Str MSG_VB_JERK = _UxGT("V") LCD_STR_B _UxGT("-Jerk"); + PROGMEM Language_Str MSG_VC_JERK = _UxGT("V") LCD_STR_C _UxGT("-Jerk"); + PROGMEM Language_Str MSG_VE_JERK = _UxGT("Ve-Jerk"); + PROGMEM Language_Str MSG_JUNCTION_DEVIATION = _UxGT("Junction Dev"); + PROGMEM Language_Str MSG_VELOCITY = _UxGT("Velocity"); + PROGMEM Language_Str MSG_VMAX_A = _UxGT("Vmax ") LCD_STR_A; + PROGMEM Language_Str MSG_VMAX_B = _UxGT("Vmax ") LCD_STR_B; + PROGMEM Language_Str MSG_VMAX_C = _UxGT("Vmax ") LCD_STR_C; + PROGMEM Language_Str MSG_VMAX_E = _UxGT("Vmax ") LCD_STR_E; + PROGMEM Language_Str MSG_VMAX_EN = _UxGT("Vmax *"); + PROGMEM Language_Str MSG_VMIN = _UxGT("Vmin"); + PROGMEM Language_Str MSG_VTRAV_MIN = _UxGT("VTrav Min"); + PROGMEM Language_Str MSG_ACCELERATION = _UxGT("Acceleration"); + PROGMEM Language_Str MSG_AMAX_A = _UxGT("Amax ") LCD_STR_A; + PROGMEM Language_Str MSG_AMAX_B = _UxGT("Amax ") LCD_STR_B; + PROGMEM Language_Str MSG_AMAX_C = _UxGT("Amax ") LCD_STR_C; + PROGMEM Language_Str MSG_AMAX_E = _UxGT("Amax ") LCD_STR_E; + PROGMEM Language_Str MSG_AMAX_EN = _UxGT("Amax *"); + PROGMEM Language_Str MSG_A_RETRACT = _UxGT("A-Retract"); + PROGMEM Language_Str MSG_A_TRAVEL = _UxGT("A-Travel"); + PROGMEM Language_Str MSG_XY_FREQUENCY_LIMIT = _UxGT("Frequency max"); + PROGMEM Language_Str MSG_XY_FREQUENCY_FEEDRATE = _UxGT("Feed min"); + PROGMEM Language_Str MSG_STEPS_PER_MM = _UxGT("Steps/mm"); + PROGMEM Language_Str MSG_A_STEPS = LCD_STR_A _UxGT("steps/mm"); + PROGMEM Language_Str MSG_B_STEPS = LCD_STR_B _UxGT("steps/mm"); + PROGMEM Language_Str MSG_C_STEPS = LCD_STR_C _UxGT("steps/mm"); + PROGMEM Language_Str MSG_E_STEPS = _UxGT("Esteps/mm"); + PROGMEM Language_Str MSG_EN_STEPS = _UxGT("*steps/mm"); + PROGMEM Language_Str MSG_TEMPERATURE = _UxGT("Temperature"); + PROGMEM Language_Str MSG_MOTION = _UxGT("Motion"); + PROGMEM Language_Str MSG_FILAMENT = _UxGT("Filament"); + PROGMEM Language_Str MSG_VOLUMETRIC_ENABLED = _UxGT("E in mm³"); + PROGMEM Language_Str MSG_VOLUMETRIC_LIMIT = _UxGT("E Limit in mm³"); + PROGMEM Language_Str MSG_VOLUMETRIC_LIMIT_E = _UxGT("E Limit *"); + PROGMEM Language_Str MSG_FILAMENT_DIAM = _UxGT("Fil. Dia."); + PROGMEM Language_Str MSG_FILAMENT_DIAM_E = _UxGT("Fil. Dia. *"); + PROGMEM Language_Str MSG_FILAMENT_UNLOAD = _UxGT("Unload mm"); + PROGMEM Language_Str MSG_FILAMENT_LOAD = _UxGT("Load mm"); + PROGMEM Language_Str MSG_ADVANCE_K = _UxGT("Advance K"); + PROGMEM Language_Str MSG_ADVANCE_K_E = _UxGT("Advance K *"); + PROGMEM Language_Str MSG_CONTRAST = _UxGT("LCD Contrast"); + PROGMEM Language_Str MSG_STORE_EEPROM = _UxGT("Store Settings"); + PROGMEM Language_Str MSG_LOAD_EEPROM = _UxGT("Load Settings"); + PROGMEM Language_Str MSG_RESTORE_DEFAULTS = _UxGT("Restore Defaults"); + PROGMEM Language_Str MSG_INIT_EEPROM = _UxGT("Initialize EEPROM"); + PROGMEM Language_Str MSG_ERR_EEPROM_CRC = _UxGT("EEPROM CRC Error"); + PROGMEM Language_Str MSG_ERR_EEPROM_INDEX = _UxGT("EEPROM Index Error"); + PROGMEM Language_Str MSG_ERR_EEPROM_VERSION = _UxGT("EEPROM Version Error"); + PROGMEM Language_Str MSG_SETTINGS_STORED = _UxGT("Settings Stored"); + PROGMEM Language_Str MSG_MEDIA_UPDATE = _UxGT("Media Update"); + PROGMEM Language_Str MSG_RESET_PRINTER = _UxGT("Reset Imprimanta"); + PROGMEM Language_Str MSG_REFRESH = LCD_STR_REFRESH _UxGT("Refresh"); + PROGMEM Language_Str MSG_INFO_SCREEN = _UxGT("Info Screen"); + PROGMEM Language_Str MSG_PREPARE = _UxGT("Prepare"); + PROGMEM Language_Str MSG_TUNE = _UxGT("Tune"); + PROGMEM Language_Str MSG_POWER_MONITOR = _UxGT("Power monitor"); + PROGMEM Language_Str MSG_CURRENT = _UxGT("Intensitate"); + PROGMEM Language_Str MSG_VOLTAGE = _UxGT("Voltaj"); + PROGMEM Language_Str MSG_POWER = _UxGT("Putere"); + PROGMEM Language_Str MSG_START_PRINT = _UxGT("Start Imprimare"); + PROGMEM Language_Str MSG_BUTTON_NEXT = _UxGT("Urmatorul"); + PROGMEM Language_Str MSG_BUTTON_INIT = _UxGT("Initiere"); + PROGMEM Language_Str MSG_BUTTON_STOP = _UxGT("Stop"); + PROGMEM Language_Str MSG_BUTTON_PRINT = _UxGT("Imprimeaza"); + PROGMEM Language_Str MSG_BUTTON_RESET = _UxGT("Reseteaza"); + PROGMEM Language_Str MSG_BUTTON_IGNORE = _UxGT("Ignora"); + PROGMEM Language_Str MSG_BUTTON_CANCEL = _UxGT("Anuleaza"); + PROGMEM Language_Str MSG_BUTTON_DONE = _UxGT("OK"); + PROGMEM Language_Str MSG_BUTTON_BACK = _UxGT("Inapoi"); + PROGMEM Language_Str MSG_BUTTON_PROCEED = _UxGT("Proceed"); + PROGMEM Language_Str MSG_PAUSING = _UxGT("Pausing..."); + PROGMEM Language_Str MSG_PAUSE_PRINT = _UxGT("Pause Print"); + PROGMEM Language_Str MSG_RESUME_PRINT = _UxGT("Resume Print"); + PROGMEM Language_Str MSG_STOP_PRINT = _UxGT("Stop Print"); + PROGMEM Language_Str MSG_PRINTING_OBJECT = _UxGT("Printing Object"); + PROGMEM Language_Str MSG_CANCEL_OBJECT = _UxGT("Cancel Object"); + PROGMEM Language_Str MSG_CANCEL_OBJECT_N = _UxGT("Cancel Object ="); + PROGMEM Language_Str MSG_OUTAGE_RECOVERY = _UxGT("Outage Recovery"); + PROGMEM Language_Str MSG_MEDIA_MENU = _UxGT("Print from Media"); + PROGMEM Language_Str MSG_NO_MEDIA = _UxGT("No Media"); + PROGMEM Language_Str MSG_DWELL = _UxGT("Sleep..."); + PROGMEM Language_Str MSG_USERWAIT = _UxGT("Click to Resume..."); + PROGMEM Language_Str MSG_PRINT_PAUSED = _UxGT("Print Paused"); + PROGMEM Language_Str MSG_PRINTING = _UxGT("Printing..."); + PROGMEM Language_Str MSG_PRINT_ABORTED = _UxGT("Print Aborted"); + PROGMEM Language_Str MSG_PRINT_DONE = _UxGT("Print Done"); + PROGMEM Language_Str MSG_NO_MOVE = _UxGT("No Move."); + PROGMEM Language_Str MSG_KILLED = _UxGT("KILLED. "); + PROGMEM Language_Str MSG_STOPPED = _UxGT("STOPPED. "); + PROGMEM Language_Str MSG_CONTROL_RETRACT = _UxGT("Retract mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("Swap Re.mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("Retract V"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_ZHOP = _UxGT("Hop mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("Unretr. mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("S Unretr. mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("Unretract V"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAPF = _UxGT("S UnRet V"); + PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("Auto-Retract"); + PROGMEM Language_Str MSG_FILAMENT_SWAP_LENGTH = _UxGT("Swap Length"); + PROGMEM Language_Str MSG_FILAMENT_SWAP_EXTRA = _UxGT("Swap Extra"); + PROGMEM Language_Str MSG_FILAMENT_PURGE_LENGTH = _UxGT("Purge Length"); + PROGMEM Language_Str MSG_TOOL_CHANGE = _UxGT("Tool Inlocuire"); + PROGMEM Language_Str MSG_TOOL_CHANGE_ZLIFT = _UxGT("Z Raise"); + PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPEED = _UxGT("Prime Speed"); + PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPEED = _UxGT("Retract Speed"); + PROGMEM Language_Str MSG_FILAMENT_PARK_ENABLED = _UxGT("Park Head"); + PROGMEM Language_Str MSG_SINGLENOZZLE_UNRETRACT_SPEED = _UxGT("Recover Speed"); + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_SPEED = _UxGT("Fan Speed"); + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_TIME = _UxGT("Fan Time"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_ON = _UxGT("Auto Pornit"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_OFF = _UxGT("Auto Oprit"); + PROGMEM Language_Str MSG_TOOL_MIGRATION = _UxGT("Tool Migration"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_AUTO = _UxGT("Auto-migrare"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_END = _UxGT("Last Extruder"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_SWAP = _UxGT("Migrate to *"); + PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("Inlocuire Filament"); + PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Inlocuire Filament *"); + PROGMEM Language_Str MSG_FILAMENTLOAD = _UxGT("Incarcare Filament"); + PROGMEM Language_Str MSG_FILAMENTLOAD_E = _UxGT("Incarcare Filament *"); + PROGMEM Language_Str MSG_FILAMENTUNLOAD = _UxGT("Scoatere Filament"); + PROGMEM Language_Str MSG_FILAMENTUNLOAD_E = _UxGT("Scoatere Filament *"); + PROGMEM Language_Str MSG_FILAMENTUNLOAD_ALL = _UxGT("Scoate Tot"); + PROGMEM Language_Str MSG_ATTACH_MEDIA = _UxGT("Atasare Media"); + PROGMEM Language_Str MSG_CHANGE_MEDIA = _UxGT("Inlocuire Media"); + PROGMEM Language_Str MSG_RELEASE_MEDIA = _UxGT("Eliberare Media"); + PROGMEM Language_Str MSG_ZPROBE_OUT = _UxGT("Z Probe Past Bed"); + PROGMEM Language_Str MSG_SKEW_FACTOR = _UxGT("Skew Factor"); + PROGMEM Language_Str MSG_BLTOUCH = _UxGT("BLTouch"); + PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("Self-Test"); + PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("Reset"); + PROGMEM Language_Str MSG_BLTOUCH_STOW = _UxGT("Stow"); + PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("Deploy"); + PROGMEM Language_Str MSG_BLTOUCH_SW_MODE = _UxGT("SW-Mode"); + PROGMEM Language_Str MSG_BLTOUCH_5V_MODE = _UxGT("5V-Mode"); + PROGMEM Language_Str MSG_BLTOUCH_OD_MODE = _UxGT("OD-Mode"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE = _UxGT("Mode-Store"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_5V = _UxGT("Set BLTouch to 5V"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_OD = _UxGT("Set BLTouch to OD"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_ECHO = _UxGT("Report Drain"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_CHANGE = _UxGT("DANGER: Bad settings can cause damage! Proceed anyway?"); + PROGMEM Language_Str MSG_TOUCHMI_PROBE = _UxGT("TouchMI"); + PROGMEM Language_Str MSG_TOUCHMI_INIT = _UxGT("Init TouchMI"); + PROGMEM Language_Str MSG_TOUCHMI_ZTEST = _UxGT("Z Offset Test"); + PROGMEM Language_Str MSG_TOUCHMI_SAVE = _UxGT("Save"); + PROGMEM Language_Str MSG_MANUAL_DEPLOY_TOUCHMI = _UxGT("Deploy TouchMI"); + PROGMEM Language_Str MSG_MANUAL_DEPLOY = _UxGT("Deploy Z-Probe"); + PROGMEM Language_Str MSG_MANUAL_STOW = _UxGT("Stow Z-Probe"); + PROGMEM Language_Str MSG_HOME_FIRST = _UxGT("Home %s%s%s First"); + PROGMEM Language_Str MSG_ZPROBE_OFFSETS = _UxGT("Probe Offsets"); + PROGMEM Language_Str MSG_ZPROBE_XOFFSET = _UxGT("Probe X Offset"); + PROGMEM Language_Str MSG_ZPROBE_YOFFSET = _UxGT("Probe Y Offset"); + PROGMEM Language_Str MSG_ZPROBE_ZOFFSET = _UxGT("Probe Z Offset"); + PROGMEM Language_Str MSG_BABYSTEP_X = _UxGT("Babystep X"); + PROGMEM Language_Str MSG_BABYSTEP_Y = _UxGT("Babystep Y"); + PROGMEM Language_Str MSG_BABYSTEP_Z = _UxGT("Babystep Z"); + PROGMEM Language_Str MSG_BABYSTEP_TOTAL = _UxGT("Total"); + PROGMEM Language_Str MSG_ENDSTOP_ABORT = _UxGT("Endstop Abort"); + PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("Heating Failed"); + PROGMEM Language_Str MSG_ERR_REDUNDANT_TEMP = _UxGT("Err: REDUNDANT TEMP"); + PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("THERMAL RUNAWAY"); + PROGMEM Language_Str MSG_THERMAL_RUNAWAY_BED = _UxGT("BED THERMAL RUNAWAY"); + PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER = _UxGT("CHAMBER T. RUNAWAY"); + PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("Err: MAXTEMP"); + PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("Err: MINTEMP"); + PROGMEM Language_Str MSG_HALTED = _UxGT("PRINTER HALTED"); + PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("Please Reset"); + PROGMEM Language_Str MSG_SHORT_DAY = _UxGT("d"); // One character only + PROGMEM Language_Str MSG_SHORT_HOUR = _UxGT("h"); // One character only + PROGMEM Language_Str MSG_SHORT_MINUTE = _UxGT("m"); // One character only + PROGMEM Language_Str MSG_HEATING = _UxGT("Heating..."); + PROGMEM Language_Str MSG_COOLING = _UxGT("Cooling..."); + PROGMEM Language_Str MSG_BED_HEATING = _UxGT("Bed Heating..."); + PROGMEM Language_Str MSG_BED_COOLING = _UxGT("Bed Cooling..."); + PROGMEM Language_Str MSG_CHAMBER_HEATING = _UxGT("Chamber Heating..."); + PROGMEM Language_Str MSG_CHAMBER_COOLING = _UxGT("Chamber Cooling..."); + PROGMEM Language_Str MSG_DELTA_CALIBRATE = _UxGT("Delta Calibration"); + PROGMEM Language_Str MSG_DELTA_CALIBRATE_X = _UxGT("Calibrate X"); + PROGMEM Language_Str MSG_DELTA_CALIBRATE_Y = _UxGT("Calibrate Y"); + PROGMEM Language_Str MSG_DELTA_CALIBRATE_Z = _UxGT("Calibrate Z"); + PROGMEM Language_Str MSG_DELTA_CALIBRATE_CENTER = _UxGT("Calibrate Center"); + PROGMEM Language_Str MSG_DELTA_SETTINGS = _UxGT("Delta Settings"); + PROGMEM Language_Str MSG_DELTA_AUTO_CALIBRATE = _UxGT("Auto Calibration"); + PROGMEM Language_Str MSG_DELTA_HEIGHT_CALIBRATE = _UxGT("Set Delta Height"); + PROGMEM Language_Str MSG_DELTA_Z_OFFSET_CALIBRATE = _UxGT("Probe Z-offset"); + PROGMEM Language_Str MSG_DELTA_DIAG_ROD = _UxGT("Diag Rod"); + PROGMEM Language_Str MSG_DELTA_HEIGHT = _UxGT("Inaltime"); + PROGMEM Language_Str MSG_DELTA_RADIUS = _UxGT("Radius"); + PROGMEM Language_Str MSG_INFO_MENU = _UxGT("Despre Imprimanta"); + PROGMEM Language_Str MSG_INFO_PRINTER_MENU = _UxGT("Info Imprimanta"); + PROGMEM Language_Str MSG_3POINT_LEVELING = _UxGT("Nivelare in 3 puncte"); + PROGMEM Language_Str MSG_LINEAR_LEVELING = _UxGT("Nivelare Lineara"); + PROGMEM Language_Str MSG_BILINEAR_LEVELING = _UxGT("Nivelare Bilineara"); + PROGMEM Language_Str MSG_UBL_LEVELING = _UxGT("Nivelarea Patului Unificata"); + PROGMEM Language_Str MSG_MESH_LEVELING = _UxGT("Nivelare Mesh"); + PROGMEM Language_Str MSG_INFO_STATS_MENU = _UxGT("Status Imprimanta"); + PROGMEM Language_Str MSG_INFO_BOARD_MENU = _UxGT("Informatii Placa"); + PROGMEM Language_Str MSG_INFO_THERMISTOR_MENU = _UxGT("Termistoare"); + PROGMEM Language_Str MSG_INFO_EXTRUDERS = _UxGT("Extrudere"); + PROGMEM Language_Str MSG_INFO_BAUDRATE = _UxGT("Baud"); + PROGMEM Language_Str MSG_INFO_PROTOCOL = _UxGT("Protocol"); + PROGMEM Language_Str MSG_INFO_RUNAWAY_OFF = _UxGT("Runaway Watch: OFF"); + PROGMEM Language_Str MSG_INFO_RUNAWAY_ON = _UxGT("Runaway Watch: ON"); + PROGMEM Language_Str MSG_HOTEND_IDLE_TIMEOUT = _UxGT("Hotend Idle Timeout"); + + PROGMEM Language_Str MSG_CASE_LIGHT = _UxGT("Case Light"); + PROGMEM Language_Str MSG_CASE_LIGHT_BRIGHTNESS = _UxGT("Light Brightness"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("INCORRECT PRINTER"); + +#if LCD_WIDTH >= 20 + PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Total Printuri"); + PROGMEM Language_Str MSG_INFO_COMPLETED_PRINTS = _UxGT("Completat"); + PROGMEM Language_Str MSG_INFO_PRINT_TIME = _UxGT("Timp Imprimare Total"); + PROGMEM Language_Str MSG_INFO_PRINT_LONGEST = _UxGT("Longest Job Time"); + PROGMEM Language_Str MSG_INFO_PRINT_FILAMENT = _UxGT("Total Extrudat"); +#else + PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Prints"); + PROGMEM Language_Str MSG_INFO_COMPLETED_PRINTS = _UxGT("Completed"); + PROGMEM Language_Str MSG_INFO_PRINT_TIME = _UxGT("Total"); + PROGMEM Language_Str MSG_INFO_PRINT_LONGEST = _UxGT("Longest"); + PROGMEM Language_Str MSG_INFO_PRINT_FILAMENT = _UxGT("Extruded"); +#endif + + PROGMEM Language_Str MSG_INFO_MIN_TEMP = _UxGT("Temperatura Minima"); + PROGMEM Language_Str MSG_INFO_MAX_TEMP = _UxGT("Temperatura Maxima"); + PROGMEM Language_Str MSG_INFO_PSU = _UxGT("PSU"); + PROGMEM Language_Str MSG_DRIVE_STRENGTH = _UxGT("Drive Strength"); + PROGMEM Language_Str MSG_DAC_PERCENT_X = _UxGT("X Driver %"); + PROGMEM Language_Str MSG_DAC_PERCENT_Y = _UxGT("Y Driver %"); + PROGMEM Language_Str MSG_DAC_PERCENT_Z = _UxGT("Z Driver %"); + PROGMEM Language_Str MSG_DAC_PERCENT_E = _UxGT("E Driver %"); + PROGMEM Language_Str MSG_ERROR_TMC = _UxGT("TMC CONNECTION ERROR"); + PROGMEM Language_Str MSG_DAC_EEPROM_WRITE = _UxGT("DAC EEPROM Write"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER = _UxGT("FILAMENT CHANGE"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_PAUSE = _UxGT("PRINT PAUSED"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_LOAD = _UxGT("LOAD FILAMENT"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_UNLOAD = _UxGT("UNLOAD FILAMENT"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_HEADER = _UxGT("RESUME OPTIONS:"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_PURGE = _UxGT("Purge more"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_RESUME = _UxGT("Continue"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" Nozzle: "); + PROGMEM Language_Str MSG_RUNOUT_SENSOR = _UxGT("Runout Sensor"); + PROGMEM Language_Str MSG_RUNOUT_DISTANCE_MM = _UxGT("Runout Dist mm"); + PROGMEM Language_Str MSG_KILL_HOMING_FAILED = _UxGT("Homing Failed"); + PROGMEM Language_Str MSG_LCD_PROBING_FAILED = _UxGT("Probing Failed"); + + PROGMEM Language_Str MSG_MMU2_CHOOSE_FILAMENT_HEADER = _UxGT("CHOOSE FILAMENT"); + PROGMEM Language_Str MSG_MMU2_MENU = _UxGT("MMU"); + PROGMEM Language_Str MSG_KILL_MMU2_FIRMWARE = _UxGT("Update MMU Firmware!"); + PROGMEM Language_Str MSG_MMU2_NOT_RESPONDING = _UxGT("MMU Needs Attention."); + PROGMEM Language_Str MSG_MMU2_RESUME = _UxGT("MMU Resume"); + PROGMEM Language_Str MSG_MMU2_RESUMING = _UxGT("MMU Resuming..."); + PROGMEM Language_Str MSG_MMU2_LOAD_FILAMENT = _UxGT("MMU Load"); + PROGMEM Language_Str MSG_MMU2_LOAD_ALL = _UxGT("MMU Load All"); + PROGMEM Language_Str MSG_MMU2_LOAD_TO_NOZZLE = _UxGT("MMU Load to Nozzle"); + PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT = _UxGT("MMU Eject"); + PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT_N = _UxGT("MMU Eject ~"); + PROGMEM Language_Str MSG_MMU2_UNLOAD_FILAMENT = _UxGT("MMU Unload"); + PROGMEM Language_Str MSG_MMU2_LOADING_FILAMENT = _UxGT("Loading Fil. %i..."); + PROGMEM Language_Str MSG_MMU2_EJECTING_FILAMENT = _UxGT("Ejecting Fil. ..."); + PROGMEM Language_Str MSG_MMU2_UNLOADING_FILAMENT = _UxGT("Unloading Fil...."); + PROGMEM Language_Str MSG_MMU2_ALL = _UxGT("All"); + PROGMEM Language_Str MSG_MMU2_FILAMENT_N = _UxGT("Filament ~"); + PROGMEM Language_Str MSG_MMU2_RESET = _UxGT("Reset MMU"); + PROGMEM Language_Str MSG_MMU2_RESETTING = _UxGT("MMU Resetting..."); + PROGMEM Language_Str MSG_MMU2_EJECT_RECOVER = _UxGT("Remove, click"); + + PROGMEM Language_Str MSG_MIX = _UxGT("Mix"); + PROGMEM Language_Str MSG_MIX_COMPONENT_N = _UxGT("Component ="); + PROGMEM Language_Str MSG_MIXER = _UxGT("Mixer"); + PROGMEM Language_Str MSG_GRADIENT = _UxGT("Gradient"); + PROGMEM Language_Str MSG_FULL_GRADIENT = _UxGT("Full Gradient"); + PROGMEM Language_Str MSG_TOGGLE_MIX = _UxGT("Toggle Mix"); + PROGMEM Language_Str MSG_CYCLE_MIX = _UxGT("Cycle Mix"); + PROGMEM Language_Str MSG_GRADIENT_MIX = _UxGT("Gradient Mix"); + PROGMEM Language_Str MSG_REVERSE_GRADIENT = _UxGT("Reverse Gradient"); + PROGMEM Language_Str MSG_ACTIVE_VTOOL = _UxGT("Active V-tool"); + PROGMEM Language_Str MSG_START_VTOOL = _UxGT("Start V-tool"); + PROGMEM Language_Str MSG_END_VTOOL = _UxGT(" End V-tool"); + PROGMEM Language_Str MSG_GRADIENT_ALIAS = _UxGT("Alias V-tool"); + PROGMEM Language_Str MSG_RESET_VTOOLS = _UxGT("Reset V-tools"); + PROGMEM Language_Str MSG_COMMIT_VTOOL = _UxGT("Commit V-tool Mix"); + PROGMEM Language_Str MSG_VTOOLS_RESET = _UxGT("V-tools Were Reset"); + PROGMEM Language_Str MSG_START_Z = _UxGT("Start Z:"); + PROGMEM Language_Str MSG_END_Z = _UxGT(" End Z:"); + + PROGMEM Language_Str MSG_GAMES = _UxGT("Jocuri"); + PROGMEM Language_Str MSG_BRICKOUT = _UxGT("Brickout"); + PROGMEM Language_Str MSG_INVADERS = _UxGT("Invaders"); + PROGMEM Language_Str MSG_SNAKE = _UxGT("Sn4k3"); + PROGMEM Language_Str MSG_MAZE = _UxGT("Maze"); + + PROGMEM Language_Str MSG_BAD_PAGE = _UxGT("Bad page index"); + PROGMEM Language_Str MSG_BAD_PAGE_SPEED = _UxGT("Bad page speed"); + + // + // Filament Inlocuire screens show up to 3 lines on a 4-line display + // ...or up to 2 lines on a 3-line display + // +#if LCD_HEIGHT >= 4 + PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_2_LINE("Apasa Butonul", "pentru a reveni la print")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Parcare...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_3_LINE("Astept ca", "inlocuirea filamentului", "sa inceapa")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_3_LINE("Insert filament", "and press button", "to continue")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_2_LINE("Press button", "to heat nozzle")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEATING = _UxGT(MSG_2_LINE("Nozzle heating", "Please wait...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_2_LINE("Wait for", "filament unload")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_2_LINE("Wait for", "filament load")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_PURGE = _UxGT(MSG_2_LINE("Wait for", "filament purge")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_CONT_PURGE = _UxGT(MSG_2_LINE("Click to finish", "filament purge")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_2_LINE("Wait for print", "to resume...")); +#else + PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_1_LINE("Click to continue")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Parcare...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_1_LINE("Va rog asteptati...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_1_LINE("Insert and Click")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_1_LINE("Click pentru incalzire")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEATING = _UxGT(MSG_1_LINE("Incalzire...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_1_LINE("Ejectare...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_1_LINE("Incarcare...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_PURGE = _UxGT(MSG_1_LINE("Curatare...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_CONT_PURGE = _UxGT(MSG_1_LINE("Click pentru a termina")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_1_LINE("Se Reia...")); +#endif + PROGMEM Language_Str MSG_TMC_DRIVERS = _UxGT("TMC Drivers"); + PROGMEM Language_Str MSG_TMC_CURRENT = _UxGT("Driver Current"); + PROGMEM Language_Str MSG_TMC_HYBRID_THRS = _UxGT("Hybrid Threshold"); + PROGMEM Language_Str MSG_TMC_HOMING_THRS = _UxGT("Sensorless Homing"); + PROGMEM Language_Str MSG_TMC_STEPPING_MODE = _UxGT("Stepping Mode"); + PROGMEM Language_Str MSG_TMC_STEALTH_ENABLED = _UxGT("StealthChop Enabled"); + PROGMEM Language_Str MSG_SERVICE_RESET = _UxGT("Reset"); + PROGMEM Language_Str MSG_SERVICE_IN = _UxGT(" in:"); + PROGMEM Language_Str MSG_BACKLASH = _UxGT("Backlash"); + PROGMEM Language_Str MSG_BACKLASH_A = LCD_STR_A; + PROGMEM Language_Str MSG_BACKLASH_B = LCD_STR_B; + PROGMEM Language_Str MSG_BACKLASH_C = LCD_STR_C; + PROGMEM Language_Str MSG_BACKLASH_CORRECTION = _UxGT("Corectare"); + PROGMEM Language_Str MSG_BACKLASH_SMOOTHING = _UxGT("Smoothing"); + + PROGMEM Language_Str MSG_LEVEL_X_AXIS = _UxGT("Nivelare Axa X"); + PROGMEM Language_Str MSG_AUTO_CALIBRATE = _UxGT("Auto Calibrare"); + PROGMEM Language_Str MSG_HEATER_TIMEOUT = _UxGT("Timeout Incalzitor"); + PROGMEM Language_Str MSG_REHEAT = _UxGT("Reincalzire"); + PROGMEM Language_Str MSG_REHEATING = _UxGT("Reincalzire..."); +} + +#if FAN_COUNT == 1 + #define MSG_FIRST_FAN_SPEED MSG_FAN_SPEED + #define MSG_EXTRA_FIRST_FAN_SPEED MSG_EXTRA_FAN_SPEED +#else + #define MSG_FIRST_FAN_SPEED MSG_FAN_SPEED_N + #define MSG_EXTRA_FIRST_FAN_SPEED MSG_EXTRA_FAN_SPEED_N +#endif diff --git a/Marlin/src/lcd/language/language_ru.h b/Marlin/src/lcd/language/language_ru.h index 82c91c65029c..2a2f56857303 100644 --- a/Marlin/src/lcd/language/language_ru.h +++ b/Marlin/src/lcd/language/language_ru.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,8 +25,7 @@ * Russian * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ #define DISPLAY_CHARSET_ISO10646_5 @@ -36,16 +35,27 @@ namespace Language_ru { constexpr uint8_t CHARSIZE = 2; PROGMEM Language_Str LANGUAGE = _UxGT("Russian"); - PROGMEM Language_Str WELCOME_MSG = MACHINE_NAME _UxGT(" готов."); + PROGMEM Language_Str WELCOME_MSG = MACHINE_NAME _UxGT(" Готов."); + PROGMEM Language_Str MSG_YES = _UxGT("Да"); + PROGMEM Language_Str MSG_NO = _UxGT("Нет"); PROGMEM Language_Str MSG_BACK = _UxGT("Назад"); - PROGMEM Language_Str MSG_MEDIA_INSERTED = _UxGT("Карта вставлена"); - PROGMEM Language_Str MSG_MEDIA_REMOVED = _UxGT("Карта извлечена"); - PROGMEM Language_Str MSG_MEDIA_RELEASED = _UxGT("SD карта не активна"); - PROGMEM Language_Str MSG_LCD_ENDSTOPS = _UxGT("Эндстопы"); // Max length 8 characters + PROGMEM Language_Str MSG_MEDIA_ABORTING = _UxGT("Прерывание..."); + PROGMEM Language_Str MSG_MEDIA_INSERTED = _UxGT("SD-карта вставлена"); + PROGMEM Language_Str MSG_MEDIA_REMOVED = _UxGT("SD-карта извлечена"); + PROGMEM Language_Str MSG_MEDIA_WAITING = _UxGT("Вставьте SD-карту"); + PROGMEM Language_Str MSG_MEDIA_READ_ERROR = _UxGT("Ошибка считывания"); + PROGMEM Language_Str MSG_MEDIA_USB_REMOVED = _UxGT("USB диск удалён"); + PROGMEM Language_Str MSG_MEDIA_USB_FAILED = _UxGT("Ошибка USB диска"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_KILL_SUBCALL_OVERFLOW = _UxGT("Переполнение вызова"); + #else + PROGMEM Language_Str MSG_KILL_SUBCALL_OVERFLOW = _UxGT("Переполн. вызова"); + #endif PROGMEM Language_Str MSG_LCD_SOFT_ENDSTOPS = _UxGT("Прогр. эндстопы"); - PROGMEM Language_Str MSG_MAIN = _UxGT("Меню"); + PROGMEM Language_Str MSG_LCD_ENDSTOPS = _UxGT("Эндстопы"); // Max length 8 characters + PROGMEM Language_Str MSG_MAIN = _UxGT("Основное меню"); PROGMEM Language_Str MSG_ADVANCED_SETTINGS = _UxGT("Другие настройки"); - PROGMEM Language_Str MSG_CONFIGURATION = _UxGT("Настройки"); + PROGMEM Language_Str MSG_CONFIGURATION = _UxGT("Конфигурация"); PROGMEM Language_Str MSG_AUTOSTART = _UxGT("Автостарт"); PROGMEM Language_Str MSG_DISABLE_STEPPERS = _UxGT("Выключить двигатели"); PROGMEM Language_Str MSG_DEBUG_MENU = _UxGT("Меню отладки"); @@ -54,60 +64,85 @@ namespace Language_ru { PROGMEM Language_Str MSG_AUTO_HOME_X = _UxGT("Парковка X"); PROGMEM Language_Str MSG_AUTO_HOME_Y = _UxGT("Парковка Y"); PROGMEM Language_Str MSG_AUTO_HOME_Z = _UxGT("Парковка Z"); + PROGMEM Language_Str MSG_AUTO_Z_ALIGN = _UxGT("Авто Z-выравнивание"); PROGMEM Language_Str MSG_LEVEL_BED_HOMING = _UxGT("Нулевое положение"); PROGMEM Language_Str MSG_LEVEL_BED_WAITING = _UxGT("Нажмите чтобы начать"); PROGMEM Language_Str MSG_LEVEL_BED_NEXT_POINT = _UxGT("Следующая точка"); PROGMEM Language_Str MSG_LEVEL_BED_DONE = _UxGT("Выравнивание готово!"); PROGMEM Language_Str MSG_Z_FADE_HEIGHT = _UxGT("Высота спада"); - PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Запомнить парковку"); - PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Коррекции применены"); - PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Запомнить ноль"); - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Преднагрев ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Нагрев ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Нагрев ") PREHEAT_1_LABEL _UxGT(" сопло"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Нагрев ") PREHEAT_1_LABEL _UxGT(" сопло ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Нагрев ") PREHEAT_1_LABEL _UxGT(" всё"); - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Нагрев ") PREHEAT_1_LABEL _UxGT(" стол"); - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Нагрев ") PREHEAT_1_LABEL _UxGT(" правка"); - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("Преднагрев ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("Нагрев ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("Нагрев ") PREHEAT_2_LABEL _UxGT(" сопло"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("Нагрев ") PREHEAT_2_LABEL _UxGT(" сопло ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("Нагрев ") PREHEAT_2_LABEL _UxGT(" всё"); - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("Нагрев ") PREHEAT_2_LABEL _UxGT(" стол"); - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("Нагрев ") PREHEAT_2_LABEL _UxGT(" правка"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Установ. смещения дома"); + #else + PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Установ.смещ.дома"); + #endif + PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Смещения применены"); + PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Установить ноль"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Преднагрев ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Нагрев ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Нагрев ") PREHEAT_1_LABEL _UxGT(" сопло"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Нагрев ") PREHEAT_1_LABEL _UxGT(" сопло ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Нагрев ") PREHEAT_1_LABEL _UxGT(" всё"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Нагрев ") PREHEAT_1_LABEL _UxGT(" стол"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Нагрев ") PREHEAT_1_LABEL _UxGT(" правка"); + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Преднагрев $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Нагрев $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Нагрев $ сопло"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Нагрев $ сопло ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Нагрев $ всё"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Нагрев $ стол"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Нагрев $ правка"); + #endif + PROGMEM Language_Str MSG_PREHEAT_CUSTOM = _UxGT("Нагрев Свой"); PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Охлаждение"); + PROGMEM Language_Str MSG_CUTTER_FREQUENCY = _UxGT("Частота"); PROGMEM Language_Str MSG_LASER_MENU = _UxGT("Управление лазером"); PROGMEM Language_Str MSG_LASER_OFF = _UxGT("Выключить лазер"); PROGMEM Language_Str MSG_LASER_ON = _UxGT("Включить лазер"); PROGMEM Language_Str MSG_LASER_POWER = _UxGT("Мощность лазера"); - PROGMEM Language_Str MSG_SPINDLE_MENU = _UxGT("Шпиндель управление"); + PROGMEM Language_Str MSG_SPINDLE_MENU = _UxGT("Управление шпинделем"); PROGMEM Language_Str MSG_SPINDLE_OFF = _UxGT("Выключить шпиндель"); PROGMEM Language_Str MSG_SPINDLE_ON = _UxGT("Включить шпиндель"); - PROGMEM Language_Str MSG_SPINDLE_POWER = _UxGT("Мощность шпинделя"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_SPINDLE_POWER = _UxGT("Мощность шпинделя"); + #else + PROGMEM Language_Str MSG_SPINDLE_POWER = _UxGT("Мощн.шпинделя"); + #endif PROGMEM Language_Str MSG_SPINDLE_REVERSE = _UxGT("Инверсия шпинделя"); PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Включить питание"); PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("Выключить питание"); PROGMEM Language_Str MSG_EXTRUDE = _UxGT("Экструзия"); PROGMEM Language_Str MSG_RETRACT = _UxGT("Втягивание"); PROGMEM Language_Str MSG_MOVE_AXIS = _UxGT("Движение по осям"); - PROGMEM Language_Str MSG_BED_LEVELING = _UxGT("Калибровка стола"); - PROGMEM Language_Str MSG_LEVEL_BED = _UxGT("Калибровать стол"); + PROGMEM Language_Str MSG_BED_LEVELING = _UxGT("Выравнивание стола"); + PROGMEM Language_Str MSG_LEVEL_BED = _UxGT("Выровнять стол"); PROGMEM Language_Str MSG_LEVEL_CORNERS = _UxGT("Выровнять углы"); PROGMEM Language_Str MSG_NEXT_CORNER = _UxGT("Следующий угол"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_MESH_EDITOR = _UxGT("Смещение по Z"); + PROGMEM Language_Str MSG_EDITING_STOPPED = _UxGT("Правка сетки окончена"); + #else + PROGMEM Language_Str MSG_MESH_EDITOR = _UxGT("Смещение Z"); + PROGMEM Language_Str MSG_EDITING_STOPPED = _UxGT("Правка окончена"); + #endif PROGMEM Language_Str MSG_EDIT_MESH = _UxGT("Редактировать сетку"); - PROGMEM Language_Str MSG_EDITING_STOPPED = _UxGT("Правка сетки окончена"); - PROGMEM Language_Str MSG_PROBING_MESH = _UxGT("Точка сетки:"); + PROGMEM Language_Str MSG_PROBING_MESH = _UxGT("Точка сетки"); PROGMEM Language_Str MSG_MESH_X = _UxGT("Индекс X"); PROGMEM Language_Str MSG_MESH_Y = _UxGT("Индекс Y"); PROGMEM Language_Str MSG_MESH_EDIT_Z = _UxGT("Значение Z"); PROGMEM Language_Str MSG_USER_MENU = _UxGT("Свои команды"); - PROGMEM Language_Str MSG_M48_TEST = _UxGT("Проверка Z-датчика"); + PROGMEM Language_Str MSG_M48_TEST = _UxGT("M48 тест Z-зонда"); PROGMEM Language_Str MSG_M48_DEVIATION = _UxGT("Отклонение"); - PROGMEM Language_Str MSG_M48_POINT = _UxGT("Измерение"); + PROGMEM Language_Str MSG_M48_POINT = _UxGT("M48 точка"); + + PROGMEM Language_Str MSG_IDEX_MENU = _UxGT("Меню IDEX"); + PROGMEM Language_Str MSG_IDEX_MODE_AUTOPARK = _UxGT("Авто парковка"); + PROGMEM Language_Str MSG_IDEX_MODE_DUPLICATE = _UxGT("Размножение"); + PROGMEM Language_Str MSG_IDEX_MODE_MIRRORED_COPY = _UxGT("Зеркальная копия"); + PROGMEM Language_Str MSG_IDEX_MODE_FULL_CTRL = _UxGT("Полный контроль"); - // TODO: IDEX Menu PROGMEM Language_Str MSG_OFFSETS_MENU = _UxGT("Размещение сопел"); PROGMEM Language_Str MSG_HOTEND_OFFSET_X = _UxGT("2-е сопло X"); @@ -115,72 +150,118 @@ namespace Language_ru { PROGMEM Language_Str MSG_HOTEND_OFFSET_Z = _UxGT("2-е сопло Z"); PROGMEM Language_Str MSG_UBL_DOING_G29 = _UxGT("Выполняем G29"); - PROGMEM Language_Str MSG_UBL_TOOLS = _UxGT("Утилиты UBL"); - PROGMEM Language_Str MSG_UBL_LEVEL_BED = _UxGT("Калибровка UBL"); - PROGMEM Language_Str MSG_UBL_MANUAL_MESH = _UxGT("Правка сетки вручную"); - PROGMEM Language_Str MSG_UBL_BC_INSERT = _UxGT("Z-пробник и замеры"); + PROGMEM Language_Str MSG_UBL_TOOLS = _UxGT("Инструменты UBL"); + PROGMEM Language_Str MSG_UBL_LEVEL_BED = _UxGT("Настройка UBL"); + PROGMEM Language_Str MSG_LCD_TILTING_MESH = _UxGT("Точка разворота"); + PROGMEM Language_Str MSG_UBL_MANUAL_MESH = _UxGT("Ручной ввод сетки"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_UBL_BC_INSERT = _UxGT("Разместить шайбу и измерить"); + PROGMEM Language_Str MSG_UBL_BC_REMOVE = _UxGT("Убрать и замерить стол"); + #else + PROGMEM Language_Str MSG_UBL_BC_INSERT = _UxGT("Разм.шайбу,измерить"); + PROGMEM Language_Str MSG_UBL_BC_REMOVE = _UxGT("Убрать, измер. стол"); + #endif PROGMEM Language_Str MSG_UBL_BC_INSERT2 = _UxGT("Измерение"); - PROGMEM Language_Str MSG_UBL_BC_REMOVE = _UxGT("Убрать и замер стола"); PROGMEM Language_Str MSG_UBL_MOVING_TO_NEXT = _UxGT("Двигаемся дальше"); PROGMEM Language_Str MSG_UBL_ACTIVATE_MESH = _UxGT("Активировать UBL"); PROGMEM Language_Str MSG_UBL_DEACTIVATE_MESH = _UxGT("Деактивировать UBL"); - PROGMEM Language_Str MSG_UBL_SET_TEMP_BED = _UxGT("Температура стола"); - PROGMEM Language_Str MSG_UBL_BED_TEMP_CUSTOM = _UxGT("Температура стола"); - PROGMEM Language_Str MSG_UBL_SET_TEMP_HOTEND = _UxGT("Температура сопла"); - PROGMEM Language_Str MSG_UBL_HOTEND_TEMP_CUSTOM = _UxGT("Температура сопла"); + PROGMEM Language_Str MSG_UBL_MESH_EDIT = _UxGT("Редактор сеток"); PROGMEM Language_Str MSG_UBL_EDIT_CUSTOM_MESH = _UxGT("Править свою сетку"); + + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_UBL_SET_TEMP_BED = _UxGT("Температура стола"); + PROGMEM Language_Str MSG_UBL_BED_TEMP_CUSTOM = _UxGT("Температура стола"); + PROGMEM Language_Str MSG_UBL_SET_TEMP_HOTEND = _UxGT("Температура сопла"); + PROGMEM Language_Str MSG_UBL_HOTEND_TEMP_CUSTOM = _UxGT("Температура сопла"); + PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("Построить свою сетку"); + PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("Правка сетки завершена"); + #else + PROGMEM Language_Str MSG_UBL_SET_TEMP_BED = LCD_STR_THERMOMETER _UxGT(" стола, ") LCD_STR_DEGREE "C"; + PROGMEM Language_Str MSG_UBL_BED_TEMP_CUSTOM = LCD_STR_THERMOMETER _UxGT(" стола, ") LCD_STR_DEGREE "C"; + PROGMEM Language_Str MSG_UBL_SET_TEMP_HOTEND = LCD_STR_THERMOMETER _UxGT(" сопла, ") LCD_STR_DEGREE "C"; + PROGMEM Language_Str MSG_UBL_HOTEND_TEMP_CUSTOM = LCD_STR_THERMOMETER _UxGT(" сопла, ") LCD_STR_DEGREE "C"; + PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("Построить свою"); + PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("Правка завершена"); + #endif PROGMEM Language_Str MSG_UBL_FINE_TUNE_MESH = _UxGT("Точная правка сетки"); - PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("Правка сетки завершена"); - PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("Построить свою сетку"); PROGMEM Language_Str MSG_UBL_BUILD_MESH_MENU = _UxGT("Построить сетку"); - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M1 = _UxGT("Построить сетку ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M2 = _UxGT("Построить сетку ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_UBL_BUILD_COLD_MESH = _UxGT("Построить хол. сетку"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_UBL_BUILD_MESH_M = _UxGT("Построить сетку $"); + #endif + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_UBL_BUILD_COLD_MESH = _UxGT("Построить холодную сетку"); + #else + PROGMEM Language_Str MSG_UBL_BUILD_COLD_MESH = _UxGT("Строить холод.сетку"); + #endif PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_ADJUST = _UxGT("Правка высоты сетки"); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_AMOUNT = _UxGT("Высота"); PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_MENU = _UxGT("Проверить сетку"); - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M1 = _UxGT("Проверить сетку ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M2 = _UxGT("Проверить сетку ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_UBL_VALIDATE_CUSTOM_MESH = _UxGT("Проверить свою сетку"); + #if LCD_WIDTH > 21 + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("Проверить сетку $"); + #endif + PROGMEM Language_Str MSG_UBL_VALIDATE_CUSTOM_MESH = _UxGT("Проверить свою сетку"); + #else + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("Провер. сетку $"); + #endif + PROGMEM Language_Str MSG_UBL_VALIDATE_CUSTOM_MESH = _UxGT("Провер. свою сетку"); + #endif + PROGMEM Language_Str MSG_G26_HEATING_BED = _UxGT("G26 нагрев стола"); + PROGMEM Language_Str MSG_G26_HEATING_NOZZLE = _UxGT("G26 нагрев сопла"); + PROGMEM Language_Str MSG_G26_MANUAL_PRIME = _UxGT("Ручная грунтовка"); + PROGMEM Language_Str MSG_G26_FIXED_LENGTH = _UxGT("Грунт фикс. длины"); + PROGMEM Language_Str MSG_G26_PRIME_DONE = _UxGT("Грунтовка сделана"); + PROGMEM Language_Str MSG_G26_CANCELED = _UxGT("G26 завершена"); + PROGMEM Language_Str MSG_G26_LEAVING = _UxGT("Выйти из G26"); PROGMEM Language_Str MSG_UBL_CONTINUE_MESH = _UxGT("Продолжить сетку"); - PROGMEM Language_Str MSG_UBL_MESH_LEVELING = _UxGT("Калибровка сетки"); - PROGMEM Language_Str MSG_UBL_3POINT_MESH_LEVELING = _UxGT("Калибровка 3-х точек"); + PROGMEM Language_Str MSG_UBL_MESH_LEVELING = _UxGT("Выравнивание сетки"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_UBL_3POINT_MESH_LEVELING = _UxGT("3-х точечное выравнивание"); + #else + PROGMEM Language_Str MSG_UBL_3POINT_MESH_LEVELING = _UxGT("3-точечное выравн."); + #endif PROGMEM Language_Str MSG_UBL_GRID_MESH_LEVELING = _UxGT("Калибровка растера"); - PROGMEM Language_Str MSG_UBL_MESH_LEVEL = _UxGT("Выровнить сетку"); + PROGMEM Language_Str MSG_UBL_MESH_LEVEL = _UxGT("Выровнять сетку"); PROGMEM Language_Str MSG_UBL_SIDE_POINTS = _UxGT("Крайние точки"); PROGMEM Language_Str MSG_UBL_MAP_TYPE = _UxGT("Тип карты"); PROGMEM Language_Str MSG_UBL_OUTPUT_MAP = _UxGT("Вывести карту сетки"); PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_HOST = _UxGT("Вывести на хост"); PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_CSV = _UxGT("Вывести в CSV"); - PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_BACKUP = _UxGT("Резервировать сетку"); - PROGMEM Language_Str MSG_UBL_INFO_UBL = _UxGT("Вывод информации UBL"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_BACKUP = _UxGT("Сохранить сетку снаружи"); + PROGMEM Language_Str MSG_UBL_INFO_UBL = _UxGT("Вывод информации UBL"); + #else + PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_BACKUP = _UxGT("Сохранить снаружи"); + PROGMEM Language_Str MSG_UBL_INFO_UBL = _UxGT("Информация UBL"); + #endif PROGMEM Language_Str MSG_UBL_FILLIN_AMOUNT = _UxGT("Кол-во заполнителя"); PROGMEM Language_Str MSG_UBL_MANUAL_FILLIN = _UxGT("Ручное заполнение"); PROGMEM Language_Str MSG_UBL_SMART_FILLIN = _UxGT("Умное заполнение"); PROGMEM Language_Str MSG_UBL_FILLIN_MESH = _UxGT("Заполнить сетку"); PROGMEM Language_Str MSG_UBL_INVALIDATE_ALL = _UxGT("Аннулировать всё"); - PROGMEM Language_Str MSG_UBL_INVALIDATE_CLOSEST = _UxGT("Обнулить ближ. точку"); - PROGMEM Language_Str MSG_UBL_FINE_TUNE_ALL = _UxGT("Точная правка всего"); - PROGMEM Language_Str MSG_UBL_FINE_TUNE_CLOSEST = _UxGT("Настр. ближ. точки"); + PROGMEM Language_Str MSG_UBL_INVALIDATE_CLOSEST = _UxGT("Аннулир. ближайшую"); + PROGMEM Language_Str MSG_UBL_FINE_TUNE_ALL = _UxGT("Точно править всё"); + PROGMEM Language_Str MSG_UBL_FINE_TUNE_CLOSEST = _UxGT("Настр. ближ. точку"); PROGMEM Language_Str MSG_UBL_STORAGE_MESH_MENU = _UxGT("Хранилище сеток"); PROGMEM Language_Str MSG_UBL_STORAGE_SLOT = _UxGT("Слот памяти"); - PROGMEM Language_Str MSG_UBL_LOAD_MESH = _UxGT("Загрузить сетку стола"); - PROGMEM Language_Str MSG_UBL_SAVE_MESH = _UxGT("Сохранить сетку стола"); - PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("M117 Сетка %i загружена"); - PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("M117 Сетка %i сохранена"); + PROGMEM Language_Str MSG_UBL_LOAD_MESH = _UxGT("Загрузить сетку"); + PROGMEM Language_Str MSG_UBL_SAVE_MESH = _UxGT("Сохранить сетку"); + PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("Сетка %i загружена"); + PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("Сетка %i сохранена"); PROGMEM Language_Str MSG_UBL_NO_STORAGE = _UxGT("Нет хранилища"); PROGMEM Language_Str MSG_UBL_SAVE_ERROR = _UxGT("Ошибка: Сохран. UBL"); - PROGMEM Language_Str MSG_UBL_RESTORE_ERROR = _UxGT("Ошибка: Восстан. UBL"); + PROGMEM Language_Str MSG_UBL_RESTORE_ERROR = _UxGT("Ошибка: Восстан.UBL"); PROGMEM Language_Str MSG_UBL_Z_OFFSET_STOPPED = _UxGT("Смещение Z останов."); - PROGMEM Language_Str MSG_UBL_STEP_BY_STEP_MENU = _UxGT("Пошаговое UBL"); - PROGMEM Language_Str MSG_UBL_1_BUILD_COLD_MESH = _UxGT("1.Построить хол. сетку"); + PROGMEM Language_Str MSG_UBL_STEP_BY_STEP_MENU = _UxGT("UBL пошагово"); + PROGMEM Language_Str MSG_UBL_1_BUILD_COLD_MESH = _UxGT("1.Строить холодную"); PROGMEM Language_Str MSG_UBL_2_SMART_FILLIN = _UxGT("2.Умное заполнение"); PROGMEM Language_Str MSG_UBL_3_VALIDATE_MESH_MENU = _UxGT("3.Проверить сетку"); - PROGMEM Language_Str MSG_UBL_4_FINE_TUNE_ALL = _UxGT("4.Точная настр. всего"); + PROGMEM Language_Str MSG_UBL_4_FINE_TUNE_ALL = _UxGT("4.Точно настр. всё"); PROGMEM Language_Str MSG_UBL_5_VALIDATE_MESH_MENU = _UxGT("5.Проверить сетку"); - PROGMEM Language_Str MSG_UBL_6_FINE_TUNE_ALL = _UxGT("6.Точная настр. всего"); - PROGMEM Language_Str MSG_UBL_7_SAVE_MESH = _UxGT("7.Сохранить сетку стола"); + PROGMEM Language_Str MSG_UBL_6_FINE_TUNE_ALL = _UxGT("6.Точно настр. всё"); + PROGMEM Language_Str MSG_UBL_7_SAVE_MESH = _UxGT("7.Сохранить сетку"); PROGMEM Language_Str MSG_LED_CONTROL = _UxGT("Настройка подсветки"); PROGMEM Language_Str MSG_LEDS = _UxGT("Подсветка"); @@ -202,7 +283,7 @@ namespace Language_ru { PROGMEM Language_Str MSG_LED_BRIGHTNESS = _UxGT("Яркость"); PROGMEM Language_Str MSG_MOVING = _UxGT("Движемся..."); - PROGMEM Language_Str MSG_FREE_XY = _UxGT("Освобождаем XY"); + PROGMEM Language_Str MSG_FREE_XY = _UxGT("Освободить XY"); PROGMEM Language_Str MSG_MOVE_X = _UxGT("Движение по X"); PROGMEM Language_Str MSG_MOVE_Y = _UxGT("Движение по Y"); PROGMEM Language_Str MSG_MOVE_Z = _UxGT("Движение по Z"); @@ -215,24 +296,39 @@ namespace Language_ru { PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Движение 10мм"); PROGMEM Language_Str MSG_SPEED = _UxGT("Скорость"); PROGMEM Language_Str MSG_BED_Z = _UxGT("Z стола"); - PROGMEM Language_Str MSG_NOZZLE = _UxGT("Сопло"); + PROGMEM Language_Str MSG_NOZZLE = _UxGT("Сопло, ") LCD_STR_DEGREE "C"; PROGMEM Language_Str MSG_NOZZLE_N = _UxGT("Сопло ~"); - PROGMEM Language_Str MSG_BED = _UxGT("Стол"); + PROGMEM Language_Str MSG_NOZZLE_PARKED = _UxGT("Сопло запарковано"); + PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("Сопло ожидает"); + PROGMEM Language_Str MSG_BED = _UxGT("Стол, ") LCD_STR_DEGREE "C"; + PROGMEM Language_Str MSG_CHAMBER = _UxGT("Камера,") LCD_STR_DEGREE "C"; PROGMEM Language_Str MSG_FAN_SPEED = _UxGT("Кулер"); PROGMEM Language_Str MSG_FAN_SPEED_N = _UxGT("Кулер ~"); - PROGMEM Language_Str MSG_EXTRA_FAN_SPEED = _UxGT("Кулер доп."); - PROGMEM Language_Str MSG_EXTRA_FAN_SPEED_N = _UxGT("Кулер доп. ~"); + PROGMEM Language_Str MSG_STORED_FAN_N = _UxGT("Сохранённый кулер ~"); + PROGMEM Language_Str MSG_EXTRA_FAN_SPEED = _UxGT("Дополн. кулер"); + PROGMEM Language_Str MSG_EXTRA_FAN_SPEED_N = _UxGT("Дополн. кулер ~"); + PROGMEM Language_Str MSG_CONTROLLER_FAN = _UxGT("Контроллер кулера"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_IDLE_SPEED = _UxGT("Холостые обороты"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_AUTO_ON = _UxGT("Автовключение"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_SPEED = _UxGT("Рабочие обороты"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_DURATION = _UxGT("Период простоя"); PROGMEM Language_Str MSG_FLOW = _UxGT("Поток"); PROGMEM Language_Str MSG_FLOW_N = _UxGT("Поток ~"); PROGMEM Language_Str MSG_CONTROL = _UxGT("Настройки"); - PROGMEM Language_Str MSG_MIN = " " LCD_STR_THERMOMETER _UxGT(" Мин"); - PROGMEM Language_Str MSG_MAX = " " LCD_STR_THERMOMETER _UxGT(" Макс"); + PROGMEM Language_Str MSG_MIN = " " LCD_STR_THERMOMETER ", " LCD_STR_DEGREE _UxGT("С мин"); + PROGMEM Language_Str MSG_MAX = " " LCD_STR_THERMOMETER ", " LCD_STR_DEGREE _UxGT("С макс"); PROGMEM Language_Str MSG_FACTOR = " " LCD_STR_THERMOMETER _UxGT(" Фактор"); - PROGMEM Language_Str MSG_AUTOTEMP = _UxGT("Автотемпература"); + PROGMEM Language_Str MSG_AUTOTEMP = _UxGT("Автотемпер."); PROGMEM Language_Str MSG_LCD_ON = _UxGT("Вкл"); PROGMEM Language_Str MSG_LCD_OFF = _UxGT("Выкл"); - PROGMEM Language_Str MSG_PID_AUTOTUNE = _UxGT("Автонастройка"); - PROGMEM Language_Str MSG_PID_AUTOTUNE_E = _UxGT("Автонастройка *"); + + PROGMEM Language_Str MSG_PID_AUTOTUNE = _UxGT("Автоподбор PID"); + PROGMEM Language_Str MSG_PID_AUTOTUNE_E = _UxGT("Автоподбор PID *"); + PROGMEM Language_Str MSG_PID_AUTOTUNE_DONE = _UxGT("Подбор PID выполнен"); + PROGMEM Language_Str MSG_PID_BAD_EXTRUDER_NUM = _UxGT("Сбой автоподбора. Плохой экструдер."); + PROGMEM Language_Str MSG_PID_TEMP_TOO_HIGH = _UxGT("Сбой автоподбора. Температура повышена."); + PROGMEM Language_Str MSG_PID_TIMEOUT = _UxGT("Сбой автоподбора! Завершение времени."); + PROGMEM Language_Str MSG_SELECT = _UxGT("Выбор"); PROGMEM Language_Str MSG_SELECT_E = _UxGT("Выбор *"); PROGMEM Language_Str MSG_ACC = _UxGT("Ускорение"); @@ -241,127 +337,204 @@ namespace Language_ru { PROGMEM Language_Str MSG_VB_JERK = _UxGT("V") LCD_STR_B _UxGT("-рывок"); PROGMEM Language_Str MSG_VC_JERK = _UxGT("V") LCD_STR_C _UxGT("-рывок"); PROGMEM Language_Str MSG_VE_JERK = _UxGT("Ve-рывок"); - PROGMEM Language_Str MSG_VELOCITY = _UxGT("Быстрота"); - PROGMEM Language_Str MSG_VMAX_A = _UxGT("Vмакс ") LCD_STR_A; - PROGMEM Language_Str MSG_VMAX_B = _UxGT("Vмакс ") LCD_STR_B; - PROGMEM Language_Str MSG_VMAX_C = _UxGT("Vмакс ") LCD_STR_C; - PROGMEM Language_Str MSG_VMAX_E = _UxGT("Vмакс ") LCD_STR_E; - PROGMEM Language_Str MSG_VMAX_EN = _UxGT("Vмакс *"); - PROGMEM Language_Str MSG_VMIN = _UxGT("Vмин"); - PROGMEM Language_Str MSG_VTRAV_MIN = _UxGT("Vпутеш. мин"); - PROGMEM Language_Str MSG_ACCELERATION = _UxGT("Ускорение"); - PROGMEM Language_Str MSG_AMAX_A = _UxGT("Aмакс ") LCD_STR_A; - PROGMEM Language_Str MSG_AMAX_B = _UxGT("Aмакс ") LCD_STR_B; - PROGMEM Language_Str MSG_AMAX_C = _UxGT("Aмакс ") LCD_STR_C; - PROGMEM Language_Str MSG_AMAX_E = _UxGT("Aмакс ") LCD_STR_E; - PROGMEM Language_Str MSG_AMAX_EN = _UxGT("Aмакс *"); - PROGMEM Language_Str MSG_A_RETRACT = _UxGT("A-втягивание"); - PROGMEM Language_Str MSG_A_TRAVEL = _UxGT("A-путеш."); - PROGMEM Language_Str MSG_STEPS_PER_MM = _UxGT("Шаг/мм"); - PROGMEM Language_Str MSG_A_STEPS = LCD_STR_A _UxGT("шаг/мм"); - PROGMEM Language_Str MSG_B_STEPS = LCD_STR_B _UxGT("шаг/мм"); - PROGMEM Language_Str MSG_C_STEPS = LCD_STR_C _UxGT("шаг/мм"); - PROGMEM Language_Str MSG_E_STEPS = _UxGT("Eшаг/мм"); - PROGMEM Language_Str MSG_EN_STEPS = _UxGT("*шаг/мм"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_JUNCTION_DEVIATION = _UxGT("Отклонение узла"); + #else + PROGMEM Language_Str MSG_JUNCTION_DEVIATION = _UxGT("Отклон. узла"); + #endif + PROGMEM Language_Str MSG_VELOCITY = _UxGT("Скорость, мм/с"); + PROGMEM Language_Str MSG_VMAX_A = _UxGT("Скор.макс ") LCD_STR_A; + PROGMEM Language_Str MSG_VMAX_B = _UxGT("Скор.макс ") LCD_STR_B; + PROGMEM Language_Str MSG_VMAX_C = _UxGT("Скор.макс ") LCD_STR_C; + PROGMEM Language_Str MSG_VMAX_E = _UxGT("Скор.макс ") LCD_STR_E; + PROGMEM Language_Str MSG_VMAX_EN = _UxGT("Скор.макс *"); + PROGMEM Language_Str MSG_VMIN = _UxGT("Скор.мин"); + PROGMEM Language_Str MSG_VTRAV_MIN = _UxGT("Перемещение мин"); + PROGMEM Language_Str MSG_ACCELERATION = _UxGT("Ускорение, мм/с2"); + PROGMEM Language_Str MSG_AMAX_A = _UxGT("Ускор.макс ") LCD_STR_A; + PROGMEM Language_Str MSG_AMAX_B = _UxGT("Ускор.макс ") LCD_STR_B; + PROGMEM Language_Str MSG_AMAX_C = _UxGT("Ускор.макс ") LCD_STR_C; + PROGMEM Language_Str MSG_AMAX_E = _UxGT("Ускор.макс ") LCD_STR_E; + PROGMEM Language_Str MSG_AMAX_EN = _UxGT("Ускор.макс *"); + PROGMEM Language_Str MSG_A_RETRACT = _UxGT("Ускор.втягив."); + PROGMEM Language_Str MSG_A_TRAVEL = _UxGT("Ускор.путеш."); + PROGMEM Language_Str MSG_XY_FREQUENCY_LIMIT = _UxGT("Частота макс."); + PROGMEM Language_Str MSG_XY_FREQUENCY_FEEDRATE = _UxGT("Подача мин."); + PROGMEM Language_Str MSG_STEPS_PER_MM = _UxGT("Шагов/мм"); + PROGMEM Language_Str MSG_A_STEPS = LCD_STR_A _UxGT(" шаг/мм"); + PROGMEM Language_Str MSG_B_STEPS = LCD_STR_B _UxGT(" шаг/мм"); + PROGMEM Language_Str MSG_C_STEPS = LCD_STR_C _UxGT(" шаг/мм"); + PROGMEM Language_Str MSG_E_STEPS = _UxGT("E шаг/мм"); + PROGMEM Language_Str MSG_EN_STEPS = _UxGT("* шаг/мм"); PROGMEM Language_Str MSG_TEMPERATURE = _UxGT("Температура"); PROGMEM Language_Str MSG_MOTION = _UxGT("Движение"); PROGMEM Language_Str MSG_FILAMENT = _UxGT("Филамент"); PROGMEM Language_Str MSG_VOLUMETRIC_ENABLED = _UxGT("E в мм³"); - PROGMEM Language_Str MSG_FILAMENT_DIAM = _UxGT("Диаметр филамента"); - PROGMEM Language_Str MSG_FILAMENT_DIAM_E = _UxGT("Диаметр филамента *"); - PROGMEM Language_Str MSG_FILAMENT_UNLOAD = _UxGT("Загрузка мм"); - PROGMEM Language_Str MSG_FILAMENT_LOAD = _UxGT("Выгрузка мм"); - PROGMEM Language_Str MSG_ADVANCE_K = _UxGT("K продвижения"); - PROGMEM Language_Str MSG_ADVANCE_K_E = _UxGT("K продвижения *"); - PROGMEM Language_Str MSG_CONTRAST = _UxGT("Контраст LCD"); + PROGMEM Language_Str MSG_VOLUMETRIC_LIMIT = _UxGT("E огран.,мм³"); + PROGMEM Language_Str MSG_VOLUMETRIC_LIMIT_E = _UxGT("E огран. *"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_FILAMENT_DIAM = _UxGT("Диам. филамента"); + PROGMEM Language_Str MSG_FILAMENT_DIAM_E = _UxGT("Диам. филамента *"); + #else + PROGMEM Language_Str MSG_FILAMENT_DIAM = _UxGT("Диам. филам."); + PROGMEM Language_Str MSG_FILAMENT_DIAM_E = _UxGT("Диам. филам. *"); + #endif + PROGMEM Language_Str MSG_FILAMENT_UNLOAD = _UxGT("Загрузка, мм"); + PROGMEM Language_Str MSG_FILAMENT_LOAD = _UxGT("Выгрузка, мм"); + PROGMEM Language_Str MSG_ADVANCE_K = _UxGT("Kоэф. продвиж."); + PROGMEM Language_Str MSG_ADVANCE_K_E = _UxGT("Kоэф. продвиж. *"); + PROGMEM Language_Str MSG_CONTRAST = _UxGT("Контраст экрана"); PROGMEM Language_Str MSG_STORE_EEPROM = _UxGT("Сохранить настройки"); PROGMEM Language_Str MSG_LOAD_EEPROM = _UxGT("Загрузить настройки"); - PROGMEM Language_Str MSG_RESTORE_DEFAULTS = _UxGT("Вернуть настройки"); - PROGMEM Language_Str MSG_INIT_EEPROM = _UxGT("Изначальный EEPROM"); + PROGMEM Language_Str MSG_RESTORE_DEFAULTS = _UxGT("На базовые параметры"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_INIT_EEPROM = _UxGT("Инициализация EEPROM"); + #else + PROGMEM Language_Str MSG_INIT_EEPROM = _UxGT("Инициализ. EEPROM"); + #endif + PROGMEM Language_Str MSG_ERR_EEPROM_CRC = _UxGT("Сбой EEPROM: CRC"); + PROGMEM Language_Str MSG_ERR_EEPROM_INDEX = _UxGT("Сбой EEPROM: индекс"); + PROGMEM Language_Str MSG_ERR_EEPROM_VERSION = _UxGT("Сбой EEPROM: версия"); + PROGMEM Language_Str MSG_SETTINGS_STORED = _UxGT("Параметры сохранены"); PROGMEM Language_Str MSG_MEDIA_UPDATE = _UxGT("Обновление прошивки"); PROGMEM Language_Str MSG_RESET_PRINTER = _UxGT("Сброс принтера"); - PROGMEM Language_Str MSG_REFRESH = LCD_STR_REFRESH _UxGT("Обновить"); + PROGMEM Language_Str MSG_REFRESH = LCD_STR_REFRESH _UxGT(" Обновить"); PROGMEM Language_Str MSG_INFO_SCREEN = _UxGT("Главный экран"); PROGMEM Language_Str MSG_PREPARE = _UxGT("Подготовить"); PROGMEM Language_Str MSG_TUNE = _UxGT("Настроить"); + PROGMEM Language_Str MSG_POWER_MONITOR = _UxGT("Монитор питания"); + PROGMEM Language_Str MSG_CURRENT = _UxGT("Ток"); + PROGMEM Language_Str MSG_VOLTAGE = _UxGT("Напряжение"); + PROGMEM Language_Str MSG_POWER = _UxGT("Мощность"); PROGMEM Language_Str MSG_START_PRINT = _UxGT("Начало печати"); - PROGMEM Language_Str MSG_BUTTON_NEXT = _UxGT("Дальше"); - PROGMEM Language_Str MSG_BUTTON_INIT = _UxGT("Инициализация"); - PROGMEM Language_Str MSG_BUTTON_STOP = _UxGT("Остановить"); + + PROGMEM Language_Str MSG_BUTTON_NEXT = _UxGT("Дальше"); //short text for buttons + PROGMEM Language_Str MSG_BUTTON_INIT = _UxGT("Иниц-я"); + PROGMEM Language_Str MSG_BUTTON_STOP = _UxGT("Стоп"); PROGMEM Language_Str MSG_BUTTON_PRINT = _UxGT("Печать"); PROGMEM Language_Str MSG_BUTTON_RESET = _UxGT("Сброс"); + PROGMEM Language_Str MSG_BUTTON_IGNORE = _UxGT("Игнорир."); PROGMEM Language_Str MSG_BUTTON_CANCEL = _UxGT("Отмена"); PROGMEM Language_Str MSG_BUTTON_DONE = _UxGT("Готово"); + PROGMEM Language_Str MSG_BUTTON_BACK = _UxGT("Назад"); + PROGMEM Language_Str MSG_BUTTON_PROCEED = _UxGT("Продолжить"); + PROGMEM Language_Str MSG_PAUSE_PRINT = _UxGT("Пауза печати"); PROGMEM Language_Str MSG_RESUME_PRINT = _UxGT("Продолжить печать"); PROGMEM Language_Str MSG_STOP_PRINT = _UxGT("Остановить печать"); + PROGMEM Language_Str MSG_PRINTING_OBJECT = _UxGT("Печать объекта"); + PROGMEM Language_Str MSG_CANCEL_OBJECT = _UxGT("Завершить объект"); + PROGMEM Language_Str MSG_CANCEL_OBJECT_N = _UxGT("Завершить объект ="); PROGMEM Language_Str MSG_OUTAGE_RECOVERY = _UxGT("Восстановение сбоя"); PROGMEM Language_Str MSG_MEDIA_MENU = _UxGT("Печать с SD карты"); PROGMEM Language_Str MSG_NO_MEDIA = _UxGT("Нет SD карты"); PROGMEM Language_Str MSG_DWELL = _UxGT("Сон..."); PROGMEM Language_Str MSG_USERWAIT = _UxGT("Продолжить..."); PROGMEM Language_Str MSG_PRINT_PAUSED = _UxGT("Печать на паузе"); + PROGMEM Language_Str MSG_PRINTING = _UxGT("Печать..."); PROGMEM Language_Str MSG_PRINT_ABORTED = _UxGT("Печать отменена"); + PROGMEM Language_Str MSG_PRINT_DONE = _UxGT("Печать завершена"); PROGMEM Language_Str MSG_NO_MOVE = _UxGT("Нет движения."); PROGMEM Language_Str MSG_KILLED = _UxGT("УБИТО. "); PROGMEM Language_Str MSG_STOPPED = _UxGT("ОСТАНОВЛЕНО. "); - PROGMEM Language_Str MSG_CONTROL_RETRACT = _UxGT("Втягивание мм"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("Втягивание смены мм"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_CONTROL_RETRACT = _UxGT("Втягивание, мм"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("Смена втягив., мм"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("Возврат смены, мм"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAPF = _UxGT("Возврат смены, V"); + PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("Автовтягивание"); + #else + PROGMEM Language_Str MSG_CONTROL_RETRACT = _UxGT("Втягив., мм"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("Смена втяг.,мм"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("Возвр.смены,мм"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAPF = _UxGT("Возвр.смены V"); + PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("Автовтягив."); + #endif + PROGMEM Language_Str MSG_CONTROL_RETRACT_ZHOP = _UxGT("Подскок, мм"); PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("Втягивание V"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_ZHOP = _UxGT("Втяг. прыжка мм"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("Возврат мм"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("Возврат смены мм"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("Возврат, мм"); PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("Возврат V"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAPF = _UxGT("Возврат смены V"); - PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("Автовтягивание"); - // TODO: Filament Change Swap / Purge Length + PROGMEM Language_Str MSG_FILAMENT_SWAP_LENGTH = _UxGT("Поменять длины"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_FILAMENT_SWAP_EXTRA = _UxGT("Поменять дополнительно"); + #else + PROGMEM Language_Str MSG_FILAMENT_SWAP_EXTRA = _UxGT("Поменять дополнит."); + #endif + PROGMEM Language_Str MSG_FILAMENT_PURGE_LENGTH = _UxGT("Очистить длину"); PROGMEM Language_Str MSG_TOOL_CHANGE = _UxGT("Смена сопел"); PROGMEM Language_Str MSG_TOOL_CHANGE_ZLIFT = _UxGT("Поднятие по Z"); - - // TODO: Singlenozzle, nozzle standby - + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPEED = _UxGT("Начальная скор."); + PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPEED = _UxGT("Скорость втягив."); + #else + PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPEED = _UxGT("Началь.скор."); + PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPEED = _UxGT("Скор.втягив."); + #endif + PROGMEM Language_Str MSG_FILAMENT_PARK_ENABLED = _UxGT("Парковать голову"); + PROGMEM Language_Str MSG_SINGLENOZZLE_UNRETRACT_SPEED = _UxGT("Вернуть скорость"); + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_SPEED = _UxGT("Обороти кулера"); + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_TIME = _UxGT("Время кулера"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_ON = _UxGT("Авто Вкл."); + PROGMEM Language_Str MSG_TOOL_MIGRATION_OFF = _UxGT("Авто Выкл."); + PROGMEM Language_Str MSG_TOOL_MIGRATION = _UxGT("Замена инструмента"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_AUTO = _UxGT("Авто замена"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_END = _UxGT("Последний экструдер"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_SWAP = _UxGT("Замена на *"); PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("Смена филамента"); PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Смена филамента *"); - PROGMEM Language_Str MSG_FILAMENTLOAD = _UxGT("Загрузка филамента"); - PROGMEM Language_Str MSG_FILAMENTLOAD_E = _UxGT("Загрузка филамента *"); - PROGMEM Language_Str MSG_FILAMENTUNLOAD_E = _UxGT("Выгрузка филамента *"); + PROGMEM Language_Str MSG_FILAMENTLOAD = _UxGT("Загрузить филамент"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_FILAMENTLOAD_E = _UxGT("Загрузить филамент *"); + PROGMEM Language_Str MSG_FILAMENTUNLOAD_E = _UxGT("Выгрузить филамент *"); + #else + PROGMEM Language_Str MSG_FILAMENTLOAD_E = _UxGT("Подать филамент *"); + PROGMEM Language_Str MSG_FILAMENTUNLOAD_E = _UxGT("Убрать филамент *"); + #endif PROGMEM Language_Str MSG_FILAMENTUNLOAD_ALL = _UxGT("Выгрузить всё"); - PROGMEM Language_Str MSG_ATTACH_MEDIA = _UxGT("Активировать SD"); + PROGMEM Language_Str MSG_ATTACH_MEDIA = _UxGT("Установить SD карту"); PROGMEM Language_Str MSG_CHANGE_MEDIA = _UxGT("Сменить SD карту"); - PROGMEM Language_Str MSG_RELEASE_MEDIA = _UxGT("Деактивировать SD"); - PROGMEM Language_Str MSG_ZPROBE_OUT = _UxGT("Z-датчик вне стола"); + PROGMEM Language_Str MSG_RELEASE_MEDIA = _UxGT("Освободить SD карту"); + PROGMEM Language_Str MSG_ZPROBE_OUT = _UxGT("Z-зонд вне стола"); PROGMEM Language_Str MSG_SKEW_FACTOR = _UxGT("Фактор наклона"); - PROGMEM Language_Str MSG_BLTOUCH = _UxGT("BLTouch"); + PROGMEM Language_Str MSG_BLTOUCH = _UxGT("Z-зонд BLTouch"); PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("Тестирование BLTouch"); PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("Сброс BLTouch"); - PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("Опустить BLTouch"); PROGMEM Language_Str MSG_BLTOUCH_STOW = _UxGT("Поднять BLTouch"); - - // TODO: TouchMI Probe, Manual deploy/stow - - PROGMEM Language_Str MSG_HOME_FIRST = _UxGT("Паркуй %s%s%s сначала"); - PROGMEM Language_Str MSG_ZPROBE_OFFSETS = _UxGT("Отступы Z-датчика"); + PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("Опустить BLTouch"); + PROGMEM Language_Str MSG_BLTOUCH_SW_MODE = _UxGT("Режим SW"); + PROGMEM Language_Str MSG_BLTOUCH_5V_MODE = _UxGT("Режим 5V"); + PROGMEM Language_Str MSG_BLTOUCH_OD_MODE = _UxGT("Режим OD"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE = _UxGT("Режим сохранения"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_5V = _UxGT("Установить на 5V"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_OD = _UxGT("Установить на OD"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_ECHO = _UxGT("Слив отчёта"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_CHANGE = _UxGT("ОПАСНОСТЬ: Неправильные параметры приводят к повреждениям! Продолжить?"); + PROGMEM Language_Str MSG_TOUCHMI_PROBE = _UxGT("Z-Зонд TouchMI"); + PROGMEM Language_Str MSG_TOUCHMI_INIT = _UxGT("Инициализация"); + PROGMEM Language_Str MSG_TOUCHMI_ZTEST = _UxGT("Тест Z-смещения"); + PROGMEM Language_Str MSG_TOUCHMI_SAVE = _UxGT("Сохранить"); + PROGMEM Language_Str MSG_MANUAL_DEPLOY_TOUCHMI = _UxGT("Установить TouchMI"); + PROGMEM Language_Str MSG_MANUAL_DEPLOY = _UxGT("Установить зонд"); + PROGMEM Language_Str MSG_MANUAL_STOW = _UxGT("Загрузить зонд"); + PROGMEM Language_Str MSG_HOME_FIRST = _UxGT("Сначала паркуй %s%s%s"); + PROGMEM Language_Str MSG_ZPROBE_OFFSETS = _UxGT("Смещения Z-зонда"); PROGMEM Language_Str MSG_ZPROBE_XOFFSET = _UxGT("Смещение X"); PROGMEM Language_Str MSG_ZPROBE_YOFFSET = _UxGT("Смещение Y"); PROGMEM Language_Str MSG_ZPROBE_ZOFFSET = _UxGT("Смещение Z"); PROGMEM Language_Str MSG_BABYSTEP_X = _UxGT("Микрошаг X"); PROGMEM Language_Str MSG_BABYSTEP_Y = _UxGT("Микрошаг Y"); PROGMEM Language_Str MSG_BABYSTEP_Z = _UxGT("Микрошаг Z"); + PROGMEM Language_Str MSG_BABYSTEP_TOTAL = _UxGT("Сумарно"); PROGMEM Language_Str MSG_ENDSTOP_ABORT = _UxGT("Сработал концевик"); PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("Разогрев не удался"); - PROGMEM Language_Str MSG_HEATING_FAILED_LCD_BED = _UxGT("Неудача нагрева стола"); - PROGMEM Language_Str MSG_ERR_REDUNDANT_TEMP = _UxGT("Ошибка: Избыточная Т"); - PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("УБЕГАНИЕ ТЕПЛА"); - PROGMEM Language_Str MSG_THERMAL_RUNAWAY_BED = _UxGT("УБЕГАНИЕ ТЕПЛА СТОЛА"); - // TODO: Heated chamber + PROGMEM Language_Str MSG_ERR_REDUNDANT_TEMP = _UxGT("Ошибка:Избыточная Т"); + PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("УТЕЧКА ТЕПЛА"); + PROGMEM Language_Str MSG_THERMAL_RUNAWAY_BED = _UxGT("УТЕЧКА ТЕПЛА СТОЛА"); + PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER = _UxGT("УТЕЧКА ТЕПЛА КАМЕРЫ"); PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("Ошибка: Т макс."); PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("Ошибка: Т мин."); - PROGMEM Language_Str MSG_ERR_MAXTEMP_BED = _UxGT("Ошибка: Т стола макс"); - PROGMEM Language_Str MSG_ERR_MINTEMP_BED = _UxGT("Ошибка: Т стола мин."); - // TODO: Heated chamber - PROGMEM Language_Str MSG_ERR_Z_HOMING = _UxGT("Паркуй XY сначала"); PROGMEM Language_Str MSG_HALTED = _UxGT("ПРИНТЕР ОСТАНОВЛЕН"); PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("Сделайте сброс"); PROGMEM Language_Str MSG_SHORT_DAY = _UxGT("д"); // One character only @@ -370,8 +543,9 @@ namespace Language_ru { PROGMEM Language_Str MSG_HEATING = _UxGT("Нагрев..."); PROGMEM Language_Str MSG_COOLING = _UxGT("Охлаждение..."); PROGMEM Language_Str MSG_BED_HEATING = _UxGT("Нагрев стола..."); + PROGMEM Language_Str MSG_CHAMBER_HEATING = _UxGT("Нагрев камеры..."); PROGMEM Language_Str MSG_BED_COOLING = _UxGT("Охлаждение стола..."); - // TODO: Heated chamber + PROGMEM Language_Str MSG_CHAMBER_COOLING = _UxGT("Охладжение камеры..."); PROGMEM Language_Str MSG_DELTA_CALIBRATE = _UxGT("Калибровка Delta"); PROGMEM Language_Str MSG_DELTA_CALIBRATE_X = _UxGT("Калибровать X"); PROGMEM Language_Str MSG_DELTA_CALIBRATE_Y = _UxGT("Калибровать Y"); @@ -379,67 +553,150 @@ namespace Language_ru { PROGMEM Language_Str MSG_DELTA_CALIBRATE_CENTER = _UxGT("Калибровать центр"); PROGMEM Language_Str MSG_DELTA_SETTINGS = _UxGT("Настройки Delta"); PROGMEM Language_Str MSG_DELTA_AUTO_CALIBRATE = _UxGT("Авто калибровка"); - PROGMEM Language_Str MSG_DELTA_HEIGHT_CALIBRATE = _UxGT("Задать высоту Delta"); - PROGMEM Language_Str MSG_DELTA_Z_OFFSET_CALIBRATE = _UxGT("Задать Z-смещение"); - PROGMEM Language_Str MSG_DELTA_DIAG_ROD = _UxGT("Диаг. стержень"); + PROGMEM Language_Str MSG_DELTA_HEIGHT_CALIBRATE = _UxGT("Высота Delta"); + #if LCD_WIDTH >= 20 + PROGMEM Language_Str MSG_DELTA_Z_OFFSET_CALIBRATE = _UxGT("Зондировать Z-смещение"); + PROGMEM Language_Str MSG_DELTA_DIAG_ROD = _UxGT("Стержень диагонали"); + #else + PROGMEM Language_Str MSG_DELTA_Z_OFFSET_CALIBRATE = _UxGT("Зондир. Z-смещения"); + PROGMEM Language_Str MSG_DELTA_DIAG_ROD = _UxGT("Стержень диаг."); + #endif PROGMEM Language_Str MSG_DELTA_HEIGHT = _UxGT("Высота"); PROGMEM Language_Str MSG_DELTA_RADIUS = _UxGT("Радиус"); PROGMEM Language_Str MSG_INFO_MENU = _UxGT("О принтере"); PROGMEM Language_Str MSG_INFO_PRINTER_MENU = _UxGT("Данные принтера"); - PROGMEM Language_Str MSG_3POINT_LEVELING = _UxGT("Калибровка 3-х точек"); - PROGMEM Language_Str MSG_LINEAR_LEVELING = _UxGT("Калибровка линейная"); - PROGMEM Language_Str MSG_BILINEAR_LEVELING = _UxGT("Калибровка билинейная"); - PROGMEM Language_Str MSG_UBL_LEVELING = _UxGT("Калибровка UBL"); - PROGMEM Language_Str MSG_MESH_LEVELING = _UxGT("Калибровка сетки"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_3POINT_LEVELING = _UxGT("3-точечное выравнивание"); + PROGMEM Language_Str MSG_LINEAR_LEVELING = _UxGT("Линейное выравнивание"); + PROGMEM Language_Str MSG_BILINEAR_LEVELING = _UxGT("Билинейное выравнивание"); + #else + PROGMEM Language_Str MSG_3POINT_LEVELING = _UxGT("3-точ. выравнив."); + PROGMEM Language_Str MSG_LINEAR_LEVELING = _UxGT("Линейное выравн."); + PROGMEM Language_Str MSG_BILINEAR_LEVELING = _UxGT("Билин. выравнив."); + #endif + PROGMEM Language_Str MSG_UBL_LEVELING = _UxGT("Управление UBL"); + PROGMEM Language_Str MSG_MESH_LEVELING = _UxGT("Выравнивание сетки"); + PROGMEM Language_Str MSG_INFO_STATS_MENU = _UxGT("Статистика принтера"); PROGMEM Language_Str MSG_INFO_BOARD_MENU = _UxGT("Данные платы"); PROGMEM Language_Str MSG_INFO_THERMISTOR_MENU = _UxGT("Термисторы"); PROGMEM Language_Str MSG_INFO_EXTRUDERS = _UxGT("Экструдеры"); - PROGMEM Language_Str MSG_INFO_BAUDRATE = _UxGT("Скорость БОД"); + PROGMEM Language_Str MSG_INFO_BAUDRATE = _UxGT("Скорость,БОД"); PROGMEM Language_Str MSG_INFO_PROTOCOL = _UxGT("Протокол"); - PROGMEM Language_Str MSG_INFO_RUNAWAY_OFF = _UxGT("Контроль темп.: Выкл"); - PROGMEM Language_Str MSG_INFO_RUNAWAY_ON = _UxGT("Контроль темп.: Вкл"); - + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_INFO_RUNAWAY_OFF = _UxGT("Контроль утечки Т: Выкл"); + PROGMEM Language_Str MSG_INFO_RUNAWAY_ON = _UxGT("Контроль утечки Т: Вкл"); + PROGMEM Language_Str MSG_HOTEND_IDLE_TIMEOUT = _UxGT("Время простоя хотенда"); + #else + PROGMEM Language_Str MSG_INFO_RUNAWAY_OFF = _UxGT("Контр.утечки Т:Выкл"); + PROGMEM Language_Str MSG_INFO_RUNAWAY_ON = _UxGT("Контр.утечки Т:Вкл"); + PROGMEM Language_Str MSG_HOTEND_IDLE_TIMEOUT = _UxGT("Время прост.хот-а"); + #endif PROGMEM Language_Str MSG_CASE_LIGHT = _UxGT("Подсветка корпуса"); PROGMEM Language_Str MSG_CASE_LIGHT_BRIGHTNESS = _UxGT("Яркость подсветки"); - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("Неверный принтер"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("Неверный принтер"); #if LCD_WIDTH >= 20 PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Счётчик печати"); - PROGMEM Language_Str MSG_INFO_COMPLETED_PRINTS = _UxGT("Закончено"); PROGMEM Language_Str MSG_INFO_PRINT_TIME = _UxGT("Общее время печати"); PROGMEM Language_Str MSG_INFO_PRINT_LONGEST = _UxGT("Наидольшее задание"); PROGMEM Language_Str MSG_INFO_PRINT_FILAMENT = _UxGT("Длина филамента"); #else PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Отпечатков"); - PROGMEM Language_Str MSG_INFO_COMPLETED_PRINTS = _UxGT("Закончено"); PROGMEM Language_Str MSG_INFO_PRINT_TIME = _UxGT("Всего"); PROGMEM Language_Str MSG_INFO_PRINT_LONGEST = _UxGT("Наидольшее"); PROGMEM Language_Str MSG_INFO_PRINT_FILAMENT = _UxGT("Выдавлено"); #endif - PROGMEM Language_Str MSG_INFO_MIN_TEMP = _UxGT("Температура мин."); - PROGMEM Language_Str MSG_INFO_MAX_TEMP = _UxGT("Температура макс"); + PROGMEM Language_Str MSG_INFO_COMPLETED_PRINTS = _UxGT("Завершено"); + + PROGMEM Language_Str MSG_INFO_MIN_TEMP = _UxGT("Мин. ") LCD_STR_THERMOMETER; + PROGMEM Language_Str MSG_INFO_MAX_TEMP = _UxGT("Макс. ") LCD_STR_THERMOMETER; PROGMEM Language_Str MSG_INFO_PSU = _UxGT("БП"); PROGMEM Language_Str MSG_DRIVE_STRENGTH = _UxGT("Сила привода"); - PROGMEM Language_Str MSG_DAC_PERCENT_X = _UxGT("X Привод %"); - PROGMEM Language_Str MSG_DAC_PERCENT_Y = _UxGT("Y Привод %"); - PROGMEM Language_Str MSG_DAC_PERCENT_Z = _UxGT("Z Привод %"); - PROGMEM Language_Str MSG_DAC_PERCENT_E = _UxGT("E Привод %"); - PROGMEM Language_Str MSG_DAC_EEPROM_WRITE = _UxGT("Запись DAC EEPROM"); + PROGMEM Language_Str MSG_DAC_PERCENT_X = _UxGT("X Привод, %"); + PROGMEM Language_Str MSG_DAC_PERCENT_Y = _UxGT("Y Привод, %"); + PROGMEM Language_Str MSG_DAC_PERCENT_Z = _UxGT("Z Привод, %"); + PROGMEM Language_Str MSG_DAC_PERCENT_E = _UxGT("E Привод, %"); + PROGMEM Language_Str MSG_ERROR_TMC = _UxGT("СБОЙ СВЯЗИ С TMC"); + PROGMEM Language_Str MSG_DAC_EEPROM_WRITE = _UxGT("Запись DAC в EEPROM"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER = _UxGT("ЗАМЕНА ФИЛАМЕНТА"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_PAUSE = _UxGT("ПЕЧАТЬ НА ПАУЗЕ"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_LOAD = _UxGT("ЗАГРУЗКА ФИЛАМЕНТА"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_UNLOAD = _UxGT("ВЫГРУЗКА ФИЛАМЕНТА"); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_HEADER = _UxGT("ОПЦИИ ВОЗОБНОВЛЕНИЯ:"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_HEADER = _UxGT("ОПЦИИ ПРОДОЛЖЕНИЯ:"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_PURGE = _UxGT("Выдавить ещё"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_RESUME = _UxGT("Возобновить печать"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" Сопла: "); - PROGMEM Language_Str MSG_LCD_HOMING_FAILED = _UxGT("Возврат не удался"); - PROGMEM Language_Str MSG_LCD_PROBING_FAILED = _UxGT("Не удалось прощупать"); - PROGMEM Language_Str MSG_M600_TOO_COLD = _UxGT("M600: Низкая Т"); - - // TODO: MMU2 + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_RUNOUT_SENSOR = _UxGT("Датчик оконч. филамента"); + #else + PROGMEM Language_Str MSG_RUNOUT_SENSOR = _UxGT("Датчик оконч.филам."); + #endif + PROGMEM Language_Str MSG_RUNOUT_DISTANCE_MM = _UxGT("До конца, мм"); + PROGMEM Language_Str MSG_KILL_HOMING_FAILED = _UxGT("Ошибка парковки"); + PROGMEM Language_Str MSG_LCD_PROBING_FAILED = _UxGT("Ошибка зондирования"); - // TODO: Mixing + PROGMEM Language_Str MSG_MMU2_CHOOSE_FILAMENT_HEADER = _UxGT("ВЫБИРЕТЕ ФИЛАМЕНТ"); + PROGMEM Language_Str MSG_MMU2_MENU = _UxGT("Настройки MMU"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_KILL_MMU2_FIRMWARE = _UxGT("Обновить прошивку MMU!"); + #else + PROGMEM Language_Str MSG_KILL_MMU2_FIRMWARE = _UxGT("Обнови прошивку MMU"); + #endif + PROGMEM Language_Str MSG_MMU2_NOT_RESPONDING = _UxGT("MMU требует внимания"); + PROGMEM Language_Str MSG_MMU2_RESUME = _UxGT("Продолжить печать"); + PROGMEM Language_Str MSG_MMU2_RESUMING = _UxGT("Продолжение..."); + PROGMEM Language_Str MSG_MMU2_LOAD_FILAMENT = _UxGT("Загрузить филамент"); + PROGMEM Language_Str MSG_MMU2_LOAD_ALL = _UxGT("Загрузить всё"); + PROGMEM Language_Str MSG_MMU2_LOAD_TO_NOZZLE = _UxGT("Загрузить в сопло"); + PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT = _UxGT("Извлечь филамент"); + PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT_N = _UxGT("Извлечь филамент ~"); + PROGMEM Language_Str MSG_MMU2_UNLOAD_FILAMENT = _UxGT("Выгрузить филамент"); + PROGMEM Language_Str MSG_MMU2_LOADING_FILAMENT = _UxGT("Загрузка %i..."); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_MMU2_EJECTING_FILAMENT = _UxGT("Извлечение филамента..."); + #else + PROGMEM Language_Str MSG_MMU2_EJECTING_FILAMENT = _UxGT("Извлеч.филамента..."); + #endif + PROGMEM Language_Str MSG_MMU2_UNLOADING_FILAMENT = _UxGT("Выгрузка...."); + PROGMEM Language_Str MSG_MMU2_ALL = _UxGT("Всё"); + PROGMEM Language_Str MSG_MMU2_FILAMENT_N = _UxGT("Филамент ~"); + PROGMEM Language_Str MSG_MMU2_RESET = _UxGT("Перезапуск MMU"); + PROGMEM Language_Str MSG_MMU2_RESETTING = _UxGT("Перезапуск MMU..."); + PROGMEM Language_Str MSG_MMU2_EJECT_RECOVER = _UxGT("Удалите и нажмите"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_MIX = _UxGT("Смешивание"); + #else + PROGMEM Language_Str MSG_MIX = _UxGT("Смешив."); + #endif + PROGMEM Language_Str MSG_MIX_COMPONENT_N = _UxGT("Компонент ="); + PROGMEM Language_Str MSG_MIXER = _UxGT("Смеситель"); + PROGMEM Language_Str MSG_GRADIENT = _UxGT("Градиент"); + PROGMEM Language_Str MSG_FULL_GRADIENT = _UxGT("Полний градиент"); + PROGMEM Language_Str MSG_CYCLE_MIX = _UxGT("Цикличное смешивание"); + PROGMEM Language_Str MSG_GRADIENT_MIX = _UxGT("Градиент смешивания"); + PROGMEM Language_Str MSG_REVERSE_GRADIENT = _UxGT("Сменить градиент"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_TOGGLE_MIX = _UxGT("Переключить смешивание"); + PROGMEM Language_Str MSG_ACTIVE_VTOOL = _UxGT("Активация В-инструм."); + PROGMEM Language_Str MSG_START_VTOOL = _UxGT("Начало В-инструмента"); + PROGMEM Language_Str MSG_END_VTOOL = _UxGT("Конец В-инструмента"); + PROGMEM Language_Str MSG_GRADIENT_ALIAS = _UxGT("Псевдоним В-инструмента"); + PROGMEM Language_Str MSG_RESET_VTOOLS = _UxGT("Сброс В-инструментов"); + PROGMEM Language_Str MSG_VTOOLS_RESET = _UxGT("В-инструменти сброшены"); + PROGMEM Language_Str MSG_COMMIT_VTOOL = _UxGT("Смешать В-инструменти"); + #else + PROGMEM Language_Str MSG_TOGGLE_MIX = _UxGT("Перекл. смешивание"); + PROGMEM Language_Str MSG_ACTIVE_VTOOL = _UxGT("Актив.В-инструм."); + PROGMEM Language_Str MSG_START_VTOOL = _UxGT("В-инструм.нач."); + PROGMEM Language_Str MSG_END_VTOOL = _UxGT("В-инструм.кон."); + PROGMEM Language_Str MSG_GRADIENT_ALIAS = _UxGT("Псевдоним В-инстр."); + PROGMEM Language_Str MSG_RESET_VTOOLS = _UxGT("Сброс В-инструм."); + PROGMEM Language_Str MSG_VTOOLS_RESET = _UxGT("В-инструм. сброшены"); + PROGMEM Language_Str MSG_COMMIT_VTOOL = _UxGT("Смешать В-инструм."); + #endif + PROGMEM Language_Str MSG_START_Z = _UxGT("Начало Z"); + PROGMEM Language_Str MSG_END_Z = _UxGT(" Конец Z"); PROGMEM Language_Str MSG_GAMES = _UxGT("Игры"); PROGMEM Language_Str MSG_BRICKOUT = _UxGT("Кирпичи"); @@ -447,26 +704,40 @@ namespace Language_ru { PROGMEM Language_Str MSG_SNAKE = _UxGT("Змейка"); PROGMEM Language_Str MSG_MAZE = _UxGT("Лабиринт"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_BAD_PAGE = _UxGT("Плохой индекс страницы"); + PROGMEM Language_Str MSG_BAD_PAGE_SPEED = _UxGT("Полохая скорость страницы"); + #else + PROGMEM Language_Str MSG_BAD_PAGE = _UxGT("Полохая страница"); + PROGMEM Language_Str MSG_BAD_PAGE_SPEED = _UxGT("Полохая скор.стран."); + #endif + + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Парковка...")); // // Filament Change screens show up to 3 lines on a 4-line display // ...or up to 2 lines on a 3-line display // #if LCD_HEIGHT >= 4 - PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_3_LINE("Ожидайте", "начала смены", "филамента")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_3_LINE("Ожидайте", "выгрузки", "филамента")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_3_LINE("Вставьте пруток", "и нажмите кнопку", "для продолжения")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_2_LINE("Нажмите кнопку для", "нагрева сопла...")); + PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_3_LINE("Нажмите кнопку", "для продолжения", "печати")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_2_LINE("Ожидайте начала", "смены филамента")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_3_LINE("Вставьте филамент", "и нажмите кнопку", "для продолжения")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_3_LINE("Нажмите кнопку", "для нагрева", "сопла...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEATING = _UxGT(MSG_2_LINE("Нагрев сопла", "Ждите...")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_2_LINE("Ожидайте", "загрузки прутка")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_3_LINE("Ожидайте", "выгрузки", "филамента")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_3_LINE("Ожидайте", "загрузки", "филамента")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_PURGE = _UxGT(MSG_3_LINE("Ожидайте", "экструзии", "филамента")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_CONT_PURGE = _UxGT(MSG_3_LINE("Нажмите кнопку", "для завершения", "очистки филамента")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_3_LINE("Ожидайте", "возобновления", "печати")); #else + PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_1_LINE("Продолжить печать")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_1_LINE("Ожидайте...")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_1_LINE("Выгрузка...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_1_LINE("Вставь и нажми")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_1_LINE("Нагреть сопло")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEATING = _UxGT(MSG_1_LINE("Нагрев...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_1_LINE("Выгрузка...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_1_LINE("Загрузка...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_PURGE = _UxGT(MSG_1_LINE("Выдавливание...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_CONT_PURGE = _UxGT(MSG_1_LINE("Завершить очистку")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_1_LINE("Возобновление...")); #endif @@ -477,7 +748,27 @@ namespace Language_ru { PROGMEM Language_Str MSG_TMC_STEPPING_MODE = _UxGT("Режим шага"); PROGMEM Language_Str MSG_TMC_STEALTH_ENABLED = _UxGT("Тихий режим вкл"); - // TODO: Service + PROGMEM Language_Str MSG_SERVICE_RESET = _UxGT("Сброс"); + PROGMEM Language_Str MSG_SERVICE_IN = _UxGT(" в:"); + PROGMEM Language_Str MSG_BACKLASH = _UxGT("Люфт"); + PROGMEM Language_Str MSG_BACKLASH_CORRECTION = _UxGT("Исправление"); + PROGMEM Language_Str MSG_BACKLASH_SMOOTHING = _UxGT("Сглаживание"); - // TODO: Backlash + PROGMEM Language_Str MSG_LEVEL_X_AXIS = _UxGT("Уровень оси X"); + PROGMEM Language_Str MSG_AUTO_CALIBRATE = _UxGT("Авто калибровка"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_HEATER_TIMEOUT = _UxGT("Время нагревателя вышло"); + #else + PROGMEM Language_Str MSG_HEATER_TIMEOUT = _UxGT("Время нагрев. вышло"); + #endif + PROGMEM Language_Str MSG_REHEAT = _UxGT("Возобновить нагрев"); + PROGMEM Language_Str MSG_REHEATING = _UxGT("Нагрев..."); } + +#if FAN_COUNT == 1 + #define MSG_FIRST_FAN_SPEED MSG_FAN_SPEED + #define MSG_EXTRA_FIRST_FAN_SPEED MSG_EXTRA_FAN_SPEED +#else + #define MSG_FIRST_FAN_SPEED MSG_FAN_SPEED_N + #define MSG_EXTRA_FIRST_FAN_SPEED MSG_EXTRA_FAN_SPEED_N +#endif diff --git a/Marlin/src/lcd/language/language_sk.h b/Marlin/src/lcd/language/language_sk.h index 4205cd598822..d0fdf5749cf2 100644 --- a/Marlin/src/lcd/language/language_sk.h +++ b/Marlin/src/lcd/language/language_sk.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -26,11 +26,10 @@ * UTF-8 for Graphical Display * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html + * See also https://marlinfw.org/docs/development/lcd_language.html * * Translated by Michal Holeš, Farma MaM - * http://www.facebook.com/farmamam - * + * https://www.facebook.com/farmamam */ #define DISPLAY_CHARSET_ISO10646_SK @@ -47,11 +46,12 @@ namespace Language_sk { PROGMEM Language_Str MSG_MEDIA_ABORTING = _UxGT("Ruším..."); PROGMEM Language_Str MSG_MEDIA_INSERTED = _UxGT("Karta vložená"); PROGMEM Language_Str MSG_MEDIA_REMOVED = _UxGT("Karta vybraná"); - PROGMEM Language_Str MSG_MEDIA_RELEASED = _UxGT("Karta odpojená"); PROGMEM Language_Str MSG_MEDIA_WAITING = _UxGT("Čakám na kartu"); + PROGMEM Language_Str MSG_SD_INIT_FAIL = _UxGT("Inicial. SD zlyhala"); PROGMEM Language_Str MSG_MEDIA_READ_ERROR = _UxGT("Chyba čítania karty"); PROGMEM Language_Str MSG_MEDIA_USB_REMOVED = _UxGT("USB zaria. odstrán."); PROGMEM Language_Str MSG_MEDIA_USB_FAILED = _UxGT("Chyba spúšťania USB"); + PROGMEM Language_Str MSG_KILL_SUBCALL_OVERFLOW = _UxGT("Preteč. podprogramu"); PROGMEM Language_Str MSG_LCD_ENDSTOPS = _UxGT("Endstopy"); // max 8 znakov PROGMEM Language_Str MSG_LCD_SOFT_ENDSTOPS = _UxGT("Soft. endstopy"); PROGMEM Language_Str MSG_MAIN = _UxGT("Hlavná ponuka"); @@ -66,6 +66,7 @@ namespace Language_sk { PROGMEM Language_Str MSG_AUTO_HOME_Y = _UxGT("Domov os Y"); PROGMEM Language_Str MSG_AUTO_HOME_Z = _UxGT("Domov os Z"); PROGMEM Language_Str MSG_AUTO_Z_ALIGN = _UxGT("Auto-zarovn. Z"); + PROGMEM Language_Str MSG_ASSISTED_TRAMMING = _UxGT("Asist. vyrovnanie"); PROGMEM Language_Str MSG_LEVEL_BED_HOMING = _UxGT("Parkovanie XYZ"); PROGMEM Language_Str MSG_LEVEL_BED_WAITING = _UxGT("Kliknutím začnete"); PROGMEM Language_Str MSG_LEVEL_BED_NEXT_POINT = _UxGT("Ďalší bod"); @@ -74,22 +75,26 @@ namespace Language_sk { PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Nastaviť ofsety"); PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Ofsety nastavené"); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Nastaviť začiatok"); - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Zahriať ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Zahriať ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Zahriať ") PREHEAT_1_LABEL _UxGT(" hotend"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Zahriať ") PREHEAT_1_LABEL _UxGT(" hotend ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Zahriať ") PREHEAT_1_LABEL _UxGT(" všetko"); - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Zahriať ") PREHEAT_1_LABEL _UxGT(" podlož"); - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Zahriať ") PREHEAT_1_LABEL _UxGT(" nast."); - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("Zahriať ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("Zahriať ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("Zahriať ") PREHEAT_2_LABEL _UxGT(" hotend"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("Zahriať ") PREHEAT_2_LABEL _UxGT(" hotend ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("Zahriať ") PREHEAT_2_LABEL _UxGT(" všetko"); - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("Zahriať ") PREHEAT_2_LABEL _UxGT(" podlož"); - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("Zahriať ") PREHEAT_2_LABEL _UxGT(" nast."); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Zahriať ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Zahriať ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Zahriať ") PREHEAT_1_LABEL _UxGT(" hotend"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Zahriať ") PREHEAT_1_LABEL _UxGT(" hotend ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Zahriať ") PREHEAT_1_LABEL _UxGT(" všetko"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Zahriať ") PREHEAT_1_LABEL _UxGT(" podlož"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Zahriať ") PREHEAT_1_LABEL _UxGT(" nast."); + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Zahriať $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Zahriať $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Zahriať $ hotend"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Zahriať $ hotend ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Zahriať $ všetko"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Zahriať $ podlož"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Zahriať $ nast."); + #endif PROGMEM Language_Str MSG_PREHEAT_CUSTOM = _UxGT("Vlastná teplota"); PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Schladiť"); + PROGMEM Language_Str MSG_CUTTER_FREQUENCY = _UxGT("Frekvencia"); PROGMEM Language_Str MSG_LASER_MENU = _UxGT("Nastavenie lasera"); PROGMEM Language_Str MSG_LASER_OFF = _UxGT("Vypnúť laser"); PROGMEM Language_Str MSG_LASER_ON = _UxGT("Zapnúť laser"); @@ -118,6 +123,7 @@ namespace Language_sk { PROGMEM Language_Str MSG_USER_MENU = _UxGT("Vlastné príkazy"); PROGMEM Language_Str MSG_M48_TEST = _UxGT("M48 Test sondy"); PROGMEM Language_Str MSG_M48_POINT = _UxGT("M48 Bod"); + PROGMEM Language_Str MSG_M48_OUT_OF_BOUNDS = _UxGT("Sonda mimo hraníc"); PROGMEM Language_Str MSG_M48_DEVIATION = _UxGT("Odchýlka"); PROGMEM Language_Str MSG_IDEX_MENU = _UxGT("IDEX režim"); PROGMEM Language_Str MSG_OFFSETS_MENU = _UxGT("Ofset nástrojov"); @@ -149,14 +155,12 @@ namespace Language_sk { PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("Koniec úprav siete"); PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("Vlastná sieť"); PROGMEM Language_Str MSG_UBL_BUILD_MESH_MENU = _UxGT("Vytvoriť sieť"); - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M1 = _UxGT("Sieť bodov ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M2 = _UxGT("Sieť bodov ") PREHEAT_2_LABEL; + PROGMEM Language_Str MSG_UBL_BUILD_MESH_M = _UxGT("Sieť bodov ($)"); PROGMEM Language_Str MSG_UBL_BUILD_COLD_MESH = _UxGT("Studená sieť bodov"); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_ADJUST = _UxGT("Upraviť výšku siete"); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_AMOUNT = _UxGT("Výška"); PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_MENU = _UxGT("Skontrolovať sieť"); - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M1 = _UxGT("Kontrola siete ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M2 = _UxGT("Kontrola siete ") PREHEAT_2_LABEL; + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("Kontrola siete ($)"); PROGMEM Language_Str MSG_UBL_VALIDATE_CUSTOM_MESH = _UxGT("Kontrola vlast.siete"); PROGMEM Language_Str MSG_G26_HEATING_BED = _UxGT("G26 ohrev podlž."); PROGMEM Language_Str MSG_G26_HEATING_NOZZLE = _UxGT("G26 ohrev trysky"); @@ -189,8 +193,8 @@ namespace Language_sk { PROGMEM Language_Str MSG_UBL_STORAGE_SLOT = _UxGT("Pamäťový slot"); PROGMEM Language_Str MSG_UBL_LOAD_MESH = _UxGT("Načítať sieť bodov"); PROGMEM Language_Str MSG_UBL_SAVE_MESH = _UxGT("Uložiť sieť bodov"); - PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("M117 Sieť %i načítaná"); - PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("M117 Sieť %i uložená"); + PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("Sieť %i načítaná"); + PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("Sieť %i uložená"); PROGMEM Language_Str MSG_UBL_NO_STORAGE = _UxGT("Nedostatok miesta"); PROGMEM Language_Str MSG_UBL_SAVE_ERROR = _UxGT("Chyba: Ukladanie UBL"); PROGMEM Language_Str MSG_UBL_RESTORE_ERROR = _UxGT("Chyba: Obnovenie UBL"); @@ -207,7 +211,7 @@ namespace Language_sk { PROGMEM Language_Str MSG_LED_CONTROL = _UxGT("Nastavenie LED"); PROGMEM Language_Str MSG_LEDS = _UxGT("Svetlo"); - PROGMEM Language_Str MSG_LED_PRESETS = _UxGT("Prednastavené farby"); + PROGMEM Language_Str MSG_LED_PRESETS = _UxGT("Predvolby svetla"); PROGMEM Language_Str MSG_SET_LEDS_RED = _UxGT("Červená"); PROGMEM Language_Str MSG_SET_LEDS_ORANGE = _UxGT("Oranžová"); PROGMEM Language_Str MSG_SET_LEDS_YELLOW = _UxGT("Žltá"); @@ -217,6 +221,10 @@ namespace Language_sk { PROGMEM Language_Str MSG_SET_LEDS_VIOLET = _UxGT("Fialová"); PROGMEM Language_Str MSG_SET_LEDS_WHITE = _UxGT("Biela"); PROGMEM Language_Str MSG_SET_LEDS_DEFAULT = _UxGT("Obnoviť nastavenie"); + PROGMEM Language_Str MSG_LED_CHANNEL_N = _UxGT("Kanál ="); + PROGMEM Language_Str MSG_LEDS2 = _UxGT("Svetlo #2"); + PROGMEM Language_Str MSG_NEO2_PRESETS = _UxGT("Predvolby svetla #2"); + PROGMEM Language_Str MSG_NEO2_BRIGHTNESS = _UxGT("Jas"); PROGMEM Language_Str MSG_CUSTOM_LEDS = _UxGT("Vlastná farba"); PROGMEM Language_Str MSG_INTENSITY_R = _UxGT("Inten. červenej"); PROGMEM Language_Str MSG_INTENSITY_G = _UxGT("Inten. zelenej"); @@ -240,6 +248,8 @@ namespace Language_sk { PROGMEM Language_Str MSG_BED_Z = _UxGT("Výška podl."); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Tryska"); PROGMEM Language_Str MSG_NOZZLE_N = _UxGT("Tryska ~"); + PROGMEM Language_Str MSG_NOZZLE_PARKED = _UxGT("Tryska zaparkovná"); + PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("Záložná tryska"); PROGMEM Language_Str MSG_BED = _UxGT("Podložka"); PROGMEM Language_Str MSG_CHAMBER = _UxGT("Komora"); PROGMEM Language_Str MSG_FAN_SPEED = _UxGT("Rýchlosť vent."); @@ -247,6 +257,11 @@ namespace Language_sk { PROGMEM Language_Str MSG_STORED_FAN_N = _UxGT("Ulož. vent. ~"); PROGMEM Language_Str MSG_EXTRA_FAN_SPEED = _UxGT("Rýchlosť ex. vent."); PROGMEM Language_Str MSG_EXTRA_FAN_SPEED_N = _UxGT("Rýchlosť ex. vent. ~"); + PROGMEM Language_Str MSG_CONTROLLER_FAN = _UxGT("Vent. riad. jedn."); + PROGMEM Language_Str MSG_CONTROLLER_FAN_IDLE_SPEED = _UxGT("Voľno. rýchl."); + PROGMEM Language_Str MSG_CONTROLLER_FAN_AUTO_ON = _UxGT("Auto-režím"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_SPEED = _UxGT("Aktív. rýchl."); + PROGMEM Language_Str MSG_CONTROLLER_FAN_DURATION = _UxGT("Doba nečinnosti"); PROGMEM Language_Str MSG_FLOW = _UxGT("Prietok"); PROGMEM Language_Str MSG_FLOW_N = _UxGT("Prietok ~"); PROGMEM Language_Str MSG_CONTROL = _UxGT("Ovládanie"); @@ -258,6 +273,10 @@ namespace Language_sk { PROGMEM Language_Str MSG_LCD_OFF = _UxGT("Vyp"); PROGMEM Language_Str MSG_PID_AUTOTUNE = _UxGT("PID kalibrácia"); PROGMEM Language_Str MSG_PID_AUTOTUNE_E = _UxGT("PID kalibrácia *"); + PROGMEM Language_Str MSG_PID_AUTOTUNE_DONE = _UxGT("PID kal. dokončená"); + PROGMEM Language_Str MSG_PID_BAD_EXTRUDER_NUM = _UxGT("Auto-kal. zlyhala. Zlý extrúder."); + PROGMEM Language_Str MSG_PID_TEMP_TOO_HIGH = _UxGT("Auto-kal. zlyhala. Príliš vysoká tepl."); + PROGMEM Language_Str MSG_PID_TIMEOUT = _UxGT("Auto-kal. zlyhala! Čas vypršal."); PROGMEM Language_Str MSG_SELECT = _UxGT("Vybrať"); PROGMEM Language_Str MSG_SELECT_E = _UxGT("Vybrať *"); PROGMEM Language_Str MSG_ACC = _UxGT("Zrýchlenie"); @@ -283,6 +302,8 @@ namespace Language_sk { PROGMEM Language_Str MSG_AMAX_EN = _UxGT("Amax *"); PROGMEM Language_Str MSG_A_RETRACT = _UxGT("A-retrakt"); PROGMEM Language_Str MSG_A_TRAVEL = _UxGT("A-prejazd"); + PROGMEM Language_Str MSG_XY_FREQUENCY_LIMIT = _UxGT("Max. frekvencia"); + PROGMEM Language_Str MSG_XY_FREQUENCY_FEEDRATE = _UxGT("Min. posun"); PROGMEM Language_Str MSG_STEPS_PER_MM = _UxGT("Kroky/mm"); PROGMEM Language_Str MSG_A_STEPS = LCD_STR_A _UxGT("krokov/mm"); PROGMEM Language_Str MSG_B_STEPS = LCD_STR_B _UxGT("krokov/mm"); @@ -292,7 +313,9 @@ namespace Language_sk { PROGMEM Language_Str MSG_TEMPERATURE = _UxGT("Teplota"); PROGMEM Language_Str MSG_MOTION = _UxGT("Pohyb"); PROGMEM Language_Str MSG_FILAMENT = _UxGT("Filament"); - PROGMEM Language_Str MSG_VOLUMETRIC_ENABLED = _UxGT("E na mm³"); + PROGMEM Language_Str MSG_VOLUMETRIC_ENABLED = _UxGT("E v mm³"); + PROGMEM Language_Str MSG_VOLUMETRIC_LIMIT = _UxGT("E Limit v mm³"); + PROGMEM Language_Str MSG_VOLUMETRIC_LIMIT_E = _UxGT("E Limit *"); PROGMEM Language_Str MSG_FILAMENT_DIAM = _UxGT("Priem. fil."); PROGMEM Language_Str MSG_FILAMENT_DIAM_E = _UxGT("Priem. fil. *"); PROGMEM Language_Str MSG_FILAMENT_UNLOAD = _UxGT("Vysunúť mm"); @@ -307,24 +330,32 @@ namespace Language_sk { PROGMEM Language_Str MSG_ERR_EEPROM_CRC = _UxGT("Chyba: EEPROM CRC"); PROGMEM Language_Str MSG_ERR_EEPROM_INDEX = _UxGT("Chyba: EEPROM Index"); PROGMEM Language_Str MSG_ERR_EEPROM_VERSION = _UxGT("Chyba: Verzia EEPROM"); + PROGMEM Language_Str MSG_SETTINGS_STORED = _UxGT("Nastavenie uložené"); PROGMEM Language_Str MSG_MEDIA_UPDATE = _UxGT("Aktualizovať z SD"); PROGMEM Language_Str MSG_RESET_PRINTER = _UxGT("Reštart. tlačiar."); PROGMEM Language_Str MSG_REFRESH = LCD_STR_REFRESH _UxGT("Obnoviť"); PROGMEM Language_Str MSG_INFO_SCREEN = _UxGT("Info. obrazovka"); PROGMEM Language_Str MSG_PREPARE = _UxGT("Príprava tlače"); PROGMEM Language_Str MSG_TUNE = _UxGT("Doladenie tlače"); + PROGMEM Language_Str MSG_POWER_MONITOR = _UxGT("Monitor napájania"); + PROGMEM Language_Str MSG_CURRENT = _UxGT("Prúd"); + PROGMEM Language_Str MSG_VOLTAGE = _UxGT("Napätie"); + PROGMEM Language_Str MSG_POWER = _UxGT("Výkon"); PROGMEM Language_Str MSG_START_PRINT = _UxGT("Spustiť tlač"); PROGMEM Language_Str MSG_BUTTON_NEXT = _UxGT("Ďalší"); PROGMEM Language_Str MSG_BUTTON_INIT = _UxGT("Inicial."); PROGMEM Language_Str MSG_BUTTON_STOP = _UxGT("Zastaviť"); PROGMEM Language_Str MSG_BUTTON_PRINT = _UxGT("Tlačiť"); PROGMEM Language_Str MSG_BUTTON_RESET = _UxGT("Vynulovať"); + PROGMEM Language_Str MSG_BUTTON_IGNORE = _UxGT("Ignorovať"); PROGMEM Language_Str MSG_BUTTON_CANCEL = _UxGT("Zrušiť"); PROGMEM Language_Str MSG_BUTTON_DONE = _UxGT("Hotovo"); PROGMEM Language_Str MSG_BUTTON_BACK = _UxGT("Naspäť"); PROGMEM Language_Str MSG_BUTTON_PROCEED = _UxGT("Pokračovať"); + PROGMEM Language_Str MSG_PAUSING = _UxGT("Pozastavujem..."); PROGMEM Language_Str MSG_PAUSE_PRINT = _UxGT("Pozastaviť tlač"); PROGMEM Language_Str MSG_RESUME_PRINT = _UxGT("Obnoviť tlač"); + PROGMEM Language_Str MSG_HOST_START_PRINT = _UxGT("Spustiť z hosta"); PROGMEM Language_Str MSG_STOP_PRINT = _UxGT("Zastaviť tlač"); PROGMEM Language_Str MSG_PRINTING_OBJECT = _UxGT("Tlačím objekt"); PROGMEM Language_Str MSG_CANCEL_OBJECT = _UxGT("Zrušiť objekt"); @@ -337,6 +368,7 @@ namespace Language_sk { PROGMEM Language_Str MSG_PRINT_PAUSED = _UxGT("Tlač pozastavená"); PROGMEM Language_Str MSG_PRINTING = _UxGT("Tlačím..."); PROGMEM Language_Str MSG_PRINT_ABORTED = _UxGT("Tlač zrušená"); + PROGMEM Language_Str MSG_PRINT_DONE = _UxGT("Tlač dokončená"); PROGMEM Language_Str MSG_NO_MOVE = _UxGT("Žiadny pohyb."); PROGMEM Language_Str MSG_KILLED = _UxGT("PRERUŠENÉ. "); PROGMEM Language_Str MSG_STOPPED = _UxGT("ZASTAVENÉ. "); @@ -344,18 +376,28 @@ namespace Language_sk { PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("Výmena Re.mm"); PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("Retraktovať V"); PROGMEM Language_Str MSG_CONTROL_RETRACT_ZHOP = _UxGT("Zdvih Z mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("UnRet mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("S UnRet mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("UnRet V"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("Unretr. mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("S Unretr. mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("Unretract V"); PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAPF = _UxGT("S UnRet V"); - PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("AutoRetr."); + PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("Auto-Retract"); PROGMEM Language_Str MSG_FILAMENT_SWAP_LENGTH = _UxGT("Dĺžka výmeny"); + PROGMEM Language_Str MSG_FILAMENT_SWAP_EXTRA = _UxGT("Vymeniť naviac"); PROGMEM Language_Str MSG_FILAMENT_PURGE_LENGTH = _UxGT("Dĺžka vytlačenia"); PROGMEM Language_Str MSG_TOOL_CHANGE = _UxGT("Výmena nástroja"); PROGMEM Language_Str MSG_TOOL_CHANGE_ZLIFT = _UxGT("Zdvihnúť Z"); - PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPD = _UxGT("Primárna rýchl."); - PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPD = _UxGT("Rýchl. retrakcie"); - PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("Záložná tryska"); + PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPEED = _UxGT("Primárna rýchl."); + PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPEED = _UxGT("Rýchl. retrakcie"); + PROGMEM Language_Str MSG_FILAMENT_PARK_ENABLED = _UxGT("Parkovať hlavu"); + PROGMEM Language_Str MSG_SINGLENOZZLE_UNRETRACT_SPEED = _UxGT("Rýchl. obnovenia"); + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_SPEED = _UxGT("Rýchlosť vent."); + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_TIME = _UxGT("Doba fúkania"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_ON = _UxGT("Auto-Zap"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_OFF = _UxGT("Auto-Vyp"); + PROGMEM Language_Str MSG_TOOL_MIGRATION = _UxGT("Výmena nástroja"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_AUTO = _UxGT("Auto-výmena"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_END = _UxGT("Posl. extruder"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_SWAP = _UxGT("Vymeniť za *"); PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("Vymeniť filament"); PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Vymeniť filament *"); PROGMEM Language_Str MSG_FILAMENTLOAD = _UxGT("Zaviesť filament"); @@ -369,14 +411,14 @@ namespace Language_sk { PROGMEM Language_Str MSG_ZPROBE_OUT = _UxGT("Sonda Z mimo podl."); PROGMEM Language_Str MSG_SKEW_FACTOR = _UxGT("Faktor skosenia"); PROGMEM Language_Str MSG_BLTOUCH = _UxGT("BLTouch"); - PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("Cmd: Self-Test"); - PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("Cmd: Reset"); - PROGMEM Language_Str MSG_BLTOUCH_STOW = _UxGT("Cmd: Zasunúť"); - PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("Cmd: Vysunúť"); - PROGMEM Language_Str MSG_BLTOUCH_SW_MODE = _UxGT("Cmd: Režim SW"); - PROGMEM Language_Str MSG_BLTOUCH_5V_MODE = _UxGT("Cmd: Režim 5V"); - PROGMEM Language_Str MSG_BLTOUCH_OD_MODE = _UxGT("Cmd: Režim OD"); - PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE = _UxGT("Cmd: Ulož. režim"); + PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("Self-Test"); + PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("Reset"); + PROGMEM Language_Str MSG_BLTOUCH_STOW = _UxGT("Zasunúť"); + PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("Vysunúť"); + PROGMEM Language_Str MSG_BLTOUCH_SW_MODE = _UxGT("Režim SW"); + PROGMEM Language_Str MSG_BLTOUCH_5V_MODE = _UxGT("Režim 5V"); + PROGMEM Language_Str MSG_BLTOUCH_OD_MODE = _UxGT("Režim OD"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE = _UxGT("Ulož. režim"); PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_5V = _UxGT("Prepnúť do 5V"); PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_OD = _UxGT("Prepnúť do OD"); PROGMEM Language_Str MSG_BLTOUCH_MODE_ECHO = _UxGT("Zobraziť režim"); @@ -399,19 +441,12 @@ namespace Language_sk { PROGMEM Language_Str MSG_BABYSTEP_TOTAL = _UxGT("Celkom"); PROGMEM Language_Str MSG_ENDSTOP_ABORT = _UxGT("Zastavenie Endstop"); PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("Chyba ohrevu"); - PROGMEM Language_Str MSG_HEATING_FAILED_LCD_BED = _UxGT("Chyba ohrevu podl."); - PROGMEM Language_Str MSG_HEATING_FAILED_LCD_CHAMBER = _UxGT("Chyba ohrevu komory"); PROGMEM Language_Str MSG_ERR_REDUNDANT_TEMP = _UxGT("Chyba: REDUND. TEP."); PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("TEPLOTNÝ SKOK"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY_BED = _UxGT("TEPLOTNÝ SKOK PODL."); PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER = _UxGT("TEPLOTNÝ SKOK KOMO."); PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("Chyba: MAXTEMP"); PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("Chyba: MINTEMP"); - PROGMEM Language_Str MSG_ERR_MAXTEMP_BED = _UxGT("Chyba: MAXTEMP PODL."); - PROGMEM Language_Str MSG_ERR_MINTEMP_BED = _UxGT("Chyba: MINTEMP PODL."); - PROGMEM Language_Str MSG_ERR_MAXTEMP_CHAMBER = _UxGT("Chyba: MAXTEMP KOMO."); - PROGMEM Language_Str MSG_ERR_MINTEMP_CHAMBER = _UxGT("Chyba: MINTEMP KOMO."); - PROGMEM Language_Str MSG_ERR_Z_HOMING = _UxGT("Najskôr os XY domov"); PROGMEM Language_Str MSG_HALTED = _UxGT("TLAČIAREŇ ZASTAVENÁ"); PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("Reštartuje ju"); PROGMEM Language_Str MSG_SHORT_DAY = _UxGT("d"); @@ -421,6 +456,8 @@ namespace Language_sk { PROGMEM Language_Str MSG_COOLING = _UxGT("Ochladzovanie..."); PROGMEM Language_Str MSG_BED_HEATING = _UxGT("Ohrev podložky..."); PROGMEM Language_Str MSG_BED_COOLING = _UxGT("Ochladz. podložky..."); + PROGMEM Language_Str MSG_PROBE_HEATING = _UxGT("Ohrev sondy..."); + PROGMEM Language_Str MSG_PROBE_COOLING = _UxGT("Ochladz. sondy..."); PROGMEM Language_Str MSG_CHAMBER_HEATING = _UxGT("Ohrev komory..."); PROGMEM Language_Str MSG_CHAMBER_COOLING = _UxGT("Ochladz. komory..."); PROGMEM Language_Str MSG_DELTA_CALIBRATE = _UxGT("Delta kalibrácia"); @@ -450,10 +487,11 @@ namespace Language_sk { PROGMEM Language_Str MSG_INFO_PROTOCOL = _UxGT("Protokol"); PROGMEM Language_Str MSG_INFO_RUNAWAY_OFF = _UxGT("Tepl. ochrana: VYP"); PROGMEM Language_Str MSG_INFO_RUNAWAY_ON = _UxGT("Tepl. ochrana: ZAP"); + PROGMEM Language_Str MSG_HOTEND_IDLE_TIMEOUT = _UxGT("Vypr.čas nečinnosti"); PROGMEM Language_Str MSG_CASE_LIGHT = _UxGT("Osvetlenie"); PROGMEM Language_Str MSG_CASE_LIGHT_BRIGHTNESS = _UxGT("Jas svetla"); - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("Nesprávna tlačiareň"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("Nesprávna tlačiareň"); #if LCD_WIDTH >= 20 PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Počet tlačí"); @@ -489,13 +527,12 @@ namespace Language_sk { PROGMEM Language_Str MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" Tryska: "); PROGMEM Language_Str MSG_RUNOUT_SENSOR = _UxGT("Senzor filamentu"); PROGMEM Language_Str MSG_RUNOUT_DISTANCE_MM = _UxGT("Vzd. mm fil. senz."); - PROGMEM Language_Str MSG_LCD_HOMING_FAILED = _UxGT("Parkovanie zlyhalo"); + PROGMEM Language_Str MSG_KILL_HOMING_FAILED = _UxGT("Parkovanie zlyhalo"); PROGMEM Language_Str MSG_LCD_PROBING_FAILED = _UxGT("Kalibrácia zlyhala"); - PROGMEM Language_Str MSG_M600_TOO_COLD = _UxGT("M600: Príliš studený"); PROGMEM Language_Str MSG_MMU2_CHOOSE_FILAMENT_HEADER = _UxGT("VYBERTE FILAMENT"); PROGMEM Language_Str MSG_MMU2_MENU = _UxGT("MMU2"); - PROGMEM Language_Str MSG_MMU2_WRONG_FIRMWARE = _UxGT("Aktualizujte FW MMU!"); + PROGMEM Language_Str MSG_KILL_MMU2_FIRMWARE = _UxGT("Aktualizujte FW MMU!"); PROGMEM Language_Str MSG_MMU2_NOT_RESPONDING = _UxGT("MMU potrebuje zásah."); PROGMEM Language_Str MSG_MMU2_RESUME = _UxGT("Obnoviť tlač"); PROGMEM Language_Str MSG_MMU2_RESUMING = _UxGT("Obnovovanie..."); @@ -539,13 +576,27 @@ namespace Language_sk { PROGMEM Language_Str MSG_SNAKE = _UxGT("Had"); PROGMEM Language_Str MSG_MAZE = _UxGT("Bludisko"); + PROGMEM Language_Str MSG_BAD_PAGE = _UxGT("Chyb. index stránky"); + PROGMEM Language_Str MSG_BAD_PAGE_SPEED = _UxGT("Chyb. rých. stránky"); + + PROGMEM Language_Str MSG_EDIT_PASSWORD = _UxGT("Zmeniť heslo"); + PROGMEM Language_Str MSG_LOGIN_REQUIRED = _UxGT("Vyžad. sa prihl."); + PROGMEM Language_Str MSG_PASSWORD_SETTINGS = _UxGT("Nastavenie hesla"); + PROGMEM Language_Str MSG_ENTER_DIGIT = _UxGT("Zvoľte číslo"); + PROGMEM Language_Str MSG_CHANGE_PASSWORD = _UxGT("Zmeniť heslo"); + PROGMEM Language_Str MSG_REMOVE_PASSWORD = _UxGT("Odstrániť heslo"); + PROGMEM Language_Str MSG_PASSWORD_SET = _UxGT("Heslo je "); + PROGMEM Language_Str MSG_START_OVER = _UxGT("Začať odznova"); + PROGMEM Language_Str MSG_REMINDER_SAVE_SETTINGS = _UxGT("Nezabudnite uložiť!"); + PROGMEM Language_Str MSG_PASSWORD_REMOVED = _UxGT("Heslo odstránene"); + // // Filament Change screens show up to 3 lines on a 4-line display // ...or up to 2 lines on a 3-line display // #if LCD_HEIGHT >= 4 PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_2_LINE("Stlačte tlačidlo", "pre obnovu tlače")); - PROGMEM Language_Str MSG_PAUSE_PRINT_INIT = _UxGT(MSG_1_LINE("Parkovanie...")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Parkovanie...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_3_LINE("Čakajte prosím", "na spustenie", "výmeny filamentu")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_3_LINE("Vložte filament", "a stlačte tlačidlo", "pre pokračovanie")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_2_LINE("Stlačte tlačidlo", "pre ohrev trysky")); @@ -557,7 +608,7 @@ namespace Language_sk { PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_2_LINE("Čakajte prosím na", "obnovenie tlače...")); #else PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_1_LINE("Kliknite pre pokr.")); - PROGMEM Language_Str MSG_PAUSE_PRINT_INIT = _UxGT(MSG_1_LINE("Parkovanie...")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Parkovanie...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_1_LINE("Čakajte prosím...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_1_LINE("Vložte a kliknite")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_1_LINE("Kliknite pre ohrev")); @@ -582,4 +633,14 @@ namespace Language_sk { PROGMEM Language_Str MSG_BACKLASH_C = LCD_STR_C; PROGMEM Language_Str MSG_BACKLASH_CORRECTION = _UxGT("Korekcia"); PROGMEM Language_Str MSG_BACKLASH_SMOOTHING = _UxGT("Vyhladzovanie"); + + PROGMEM Language_Str MSG_LEVEL_X_AXIS = _UxGT("Vyrovnať os X"); + PROGMEM Language_Str MSG_AUTO_CALIBRATE = _UxGT("Auto-kalibrovať"); + #if ENABLED(TOUCH_UI_FTDI_EVE) + PROGMEM Language_Str MSG_HEATER_TIMEOUT = _UxGT("Vypršal čas ohrevu, znížená teplota. Stlačte OK pre ohrev a ešte raz pre obnovu."); + #else + PROGMEM Language_Str MSG_HEATER_TIMEOUT = _UxGT("Vypršal čas ohrevu"); + #endif + PROGMEM Language_Str MSG_REHEAT = _UxGT("Zohriať"); + PROGMEM Language_Str MSG_REHEATING = _UxGT("Zohrievanie..."); } diff --git a/Marlin/src/lcd/language/language_test.h b/Marlin/src/lcd/language/language_test.h index 465d3743f3aa..16cafbebbe2e 100644 --- a/Marlin/src/lcd/language/language_test.h +++ b/Marlin/src/lcd/language/language_test.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,8 +25,7 @@ * TEST * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ // Select ONE of the following Mappers. diff --git a/Marlin/src/lcd/language/language_tr.h b/Marlin/src/lcd/language/language_tr.h index 57d2911af93d..f81f153789ae 100644 --- a/Marlin/src/lcd/language/language_tr.h +++ b/Marlin/src/lcd/language/language_tr.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,12 +25,11 @@ * Turkish * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html + * See also https://marlinfw.org/docs/development/lcd_language.html * * Bu çeviri dosyasındaki sorunlar ve düzeltmeler için iletişim; * Contact for issues and corrections in this translation file; * Yücel Temel - (info@elektromanyetix.com) - https://elektromanyetix.com/ - * */ #define DISPLAY_CHARSET_ISO10646_TR @@ -42,9 +41,17 @@ namespace Language_tr { PROGMEM Language_Str LANGUAGE = _UxGT("Turkish"); PROGMEM Language_Str WELCOME_MSG = MACHINE_NAME _UxGT(" hazır."); + PROGMEM Language_Str MSG_MARLIN = _UxGT("Marlin"); + PROGMEM Language_Str MSG_YES = _UxGT("EVET"); + PROGMEM Language_Str MSG_NO = _UxGT("HAYIR"); PROGMEM Language_Str MSG_BACK = _UxGT("Geri"); + PROGMEM Language_Str MSG_MEDIA_ABORTING = _UxGT("Durduruluyor..."); PROGMEM Language_Str MSG_MEDIA_INSERTED = _UxGT("SD K. Yerleştirildi."); PROGMEM Language_Str MSG_MEDIA_REMOVED = _UxGT("SD Kart Çıkarıldı."); + PROGMEM Language_Str MSG_MEDIA_WAITING = _UxGT("SD Kart Bekleniyor"); + PROGMEM Language_Str MSG_MEDIA_READ_ERROR = _UxGT("Kart Okuma Hatası"); + PROGMEM Language_Str MSG_MEDIA_USB_REMOVED = _UxGT("USB Çıkarıldı"); + PROGMEM Language_Str MSG_MEDIA_USB_FAILED = _UxGT("USB Başlat. Hatası"); PROGMEM Language_Str MSG_LCD_ENDSTOPS = _UxGT("Enstops"); // Max length 8 characters PROGMEM Language_Str MSG_LCD_SOFT_ENDSTOPS = _UxGT("Yazılımsal Endstops"); PROGMEM Language_Str MSG_MAIN = _UxGT("Ana"); @@ -64,25 +71,37 @@ namespace Language_tr { PROGMEM Language_Str MSG_LEVEL_BED_NEXT_POINT = _UxGT("Sonraki Nokta"); PROGMEM Language_Str MSG_LEVEL_BED_DONE = _UxGT("Hizalama Tamam!"); PROGMEM Language_Str MSG_Z_FADE_HEIGHT = _UxGT("Kaçınma Yüksekliği"); - PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Offset Ayarla"); - PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Offset Tamam"); + PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Ofset Ayarla"); + PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Ofset Tamam"); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Sıfır Belirle"); - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Ön Isınma ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Ön Isınma ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Ön Isınma ") PREHEAT_1_LABEL _UxGT(" Nozul"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Ön Isınma ") PREHEAT_1_LABEL _UxGT(" Nozul ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Ön Isınma ") PREHEAT_1_LABEL _UxGT(" Tüm"); - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Ön Isınma ") PREHEAT_1_LABEL _UxGT(" Tabla"); - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Ön Isınma ") PREHEAT_1_LABEL _UxGT(" Ayarlar"); - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("Ön Isınma ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("Ön Isınma ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("Ön Isınma ") PREHEAT_2_LABEL _UxGT(" Nozul"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("Ön Isınma ") PREHEAT_2_LABEL _UxGT(" Nozul ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("Ön Isınma ") PREHEAT_2_LABEL _UxGT(" Tüm"); - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("Ön Isınma ") PREHEAT_2_LABEL _UxGT(" Tabla"); - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("Ön Isınma ") PREHEAT_2_LABEL _UxGT(" Ayarlar"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Ön Isınma ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Ön Isınma ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Ön Isınma ") PREHEAT_1_LABEL _UxGT(" Nozul"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Ön Isınma ") PREHEAT_1_LABEL _UxGT(" Nozul ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Ön Isınma ") PREHEAT_1_LABEL _UxGT(" Tüm"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Ön Isınma ") PREHEAT_1_LABEL _UxGT(" Tabla"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Ön Isınma ") PREHEAT_1_LABEL _UxGT(" Ayarlar"); + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Ön Isınma $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Ön Isınma $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Ön Isınma $ Nozul"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Ön Isınma $ Nozul ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Ön Isınma $ Tüm"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Ön Isınma $ Tabla"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Ön Isınma $ Ayarlar"); + #endif PROGMEM Language_Str MSG_PREHEAT_CUSTOM = _UxGT("Özel Ön Isınma"); - PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Soğut"); + PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Soğut/(Durdur)"); + PROGMEM Language_Str MSG_LASER_MENU = _UxGT("Lazer Kontrolü"); + PROGMEM Language_Str MSG_LASER_OFF = _UxGT("Lazeri Kapat"); + PROGMEM Language_Str MSG_LASER_ON = _UxGT("Lazeri Aç"); + PROGMEM Language_Str MSG_LASER_POWER = _UxGT("Lazer Gücü"); + PROGMEM Language_Str MSG_SPINDLE_MENU = _UxGT("Spindle Kontrolü"); + PROGMEM Language_Str MSG_SPINDLE_OFF = _UxGT("Spindle Kapat"); + PROGMEM Language_Str MSG_SPINDLE_ON = _UxGT("Spindle Aç"); + PROGMEM Language_Str MSG_SPINDLE_POWER = _UxGT("Spindle Gücü"); + PROGMEM Language_Str MSG_SPINDLE_REVERSE = _UxGT("Spindle Ters Yön"); PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Gücü Aç"); PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("Gücü Kapat"); PROGMEM Language_Str MSG_EXTRUDE = _UxGT("Ekstrüzyon"); @@ -92,13 +111,19 @@ namespace Language_tr { PROGMEM Language_Str MSG_LEVEL_BED = _UxGT("Tabla Hizası"); PROGMEM Language_Str MSG_LEVEL_CORNERS = _UxGT("Hizalama Köşeleri"); PROGMEM Language_Str MSG_NEXT_CORNER = _UxGT("Sonraki Köşe"); + PROGMEM Language_Str MSG_MESH_EDITOR = _UxGT("Mesh Editörü"); PROGMEM Language_Str MSG_EDIT_MESH = _UxGT("Mesh Düzenle"); PROGMEM Language_Str MSG_EDITING_STOPPED = _UxGT("Mesh Düzenleme Durdu"); + PROGMEM Language_Str MSG_PROBING_MESH = _UxGT("Prop Noktası"); PROGMEM Language_Str MSG_MESH_X = _UxGT("İndeks X"); PROGMEM Language_Str MSG_MESH_Y = _UxGT("İndeks Y"); PROGMEM Language_Str MSG_MESH_EDIT_Z = _UxGT("Z Değeri"); PROGMEM Language_Str MSG_USER_MENU = _UxGT("Özel Komutlar"); + PROGMEM Language_Str MSG_M48_TEST = _UxGT("M48 Prob Testi"); + PROGMEM Language_Str MSG_M48_POINT = _UxGT("M48 Nokta"); + PROGMEM Language_Str MSG_M48_DEVIATION = _UxGT("Sapma"); PROGMEM Language_Str MSG_IDEX_MENU = _UxGT("IDEX Modu"); + PROGMEM Language_Str MSG_OFFSETS_MENU = _UxGT("Takım Ofsetleri"); PROGMEM Language_Str MSG_IDEX_MODE_AUTOPARK = _UxGT("Oto-Park"); PROGMEM Language_Str MSG_IDEX_MODE_DUPLICATE = _UxGT("Kopyala"); PROGMEM Language_Str MSG_IDEX_MODE_MIRRORED_COPY = _UxGT("Yansıtılmış kopya"); @@ -109,6 +134,7 @@ namespace Language_tr { PROGMEM Language_Str MSG_UBL_DOING_G29 = _UxGT("G29 Çalışıyor"); PROGMEM Language_Str MSG_UBL_TOOLS = _UxGT("UBL Araçları"); PROGMEM Language_Str MSG_UBL_LEVEL_BED = _UxGT("UBL Yatak Hizalama"); + PROGMEM Language_Str MSG_LCD_TILTING_MESH = _UxGT("Eğim Noktası"); PROGMEM Language_Str MSG_UBL_MANUAL_MESH = _UxGT("Elle Mesh Oluştur"); PROGMEM Language_Str MSG_UBL_BC_INSERT = _UxGT("Altlık & Ölçü Ver"); PROGMEM Language_Str MSG_UBL_BC_INSERT2 = _UxGT("Ölçü"); @@ -126,15 +152,22 @@ namespace Language_tr { PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("Mesh Düzenleme Tamam"); PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("Özel Mesh Oluştur"); PROGMEM Language_Str MSG_UBL_BUILD_MESH_MENU = _UxGT("Mesh Oluştur"); - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M1 = _UxGT("Mesh Oluştur (") PREHEAT_1_LABEL _UxGT(")"); - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M2 = _UxGT("Mesh Oluştur (") PREHEAT_2_LABEL _UxGT(")"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_UBL_BUILD_MESH_M = _UxGT("Mesh Oluştur ($)"); + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("Doğrulama Mesh ($)"); + #endif PROGMEM Language_Str MSG_UBL_BUILD_COLD_MESH = _UxGT("Soğuk Mesh Oluştur"); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_ADJUST = _UxGT("Mesh Yükseklik Ayarı"); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_AMOUNT = _UxGT("Yükseklik miktarı"); PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_MENU = _UxGT("Doğrulama Mesh"); - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M1 = _UxGT("Doğrulama Mesh (") PREHEAT_1_LABEL _UxGT(")"); - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M2 = _UxGT("Doğrulama Mesh (") PREHEAT_2_LABEL _UxGT(")"); PROGMEM Language_Str MSG_UBL_VALIDATE_CUSTOM_MESH = _UxGT("Özel Mesh Doğrulama"); + PROGMEM Language_Str MSG_G26_HEATING_BED = _UxGT("G26 Isıtma Tablası"); + PROGMEM Language_Str MSG_G26_HEATING_NOZZLE = _UxGT("G26 Isıtma Memesi"); + PROGMEM Language_Str MSG_G26_MANUAL_PRIME = _UxGT("Manuel çalışma..."); + PROGMEM Language_Str MSG_G26_FIXED_LENGTH = _UxGT("Birincil Sabit Uzunluk"); + PROGMEM Language_Str MSG_G26_PRIME_DONE = _UxGT("Çalışma Tamamlandı"); + PROGMEM Language_Str MSG_G26_CANCELED = _UxGT("G26 İptal edildi"); + PROGMEM Language_Str MSG_G26_LEAVING = _UxGT("Çıkış G26"); PROGMEM Language_Str MSG_UBL_CONTINUE_MESH = _UxGT("Tabla Mesh Devam et"); PROGMEM Language_Str MSG_UBL_MESH_LEVELING = _UxGT("Mesh Hizalama"); PROGMEM Language_Str MSG_UBL_3POINT_MESH_LEVELING = _UxGT("3-Nokta Hizalama"); @@ -159,11 +192,12 @@ namespace Language_tr { PROGMEM Language_Str MSG_UBL_STORAGE_SLOT = _UxGT("Bellek Yuvası"); PROGMEM Language_Str MSG_UBL_LOAD_MESH = _UxGT("Yatak Mesh Yükle"); PROGMEM Language_Str MSG_UBL_SAVE_MESH = _UxGT("Yatak Mesh Kayıt Et"); - PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("M117 Mesh %i yüklendi"); - PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("M117 Mesh %i kayıtlandı"); + PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("Mesh %i yüklendi"); + PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("Mesh %i kayıtlandı"); PROGMEM Language_Str MSG_UBL_NO_STORAGE = _UxGT("Depolama Yok"); PROGMEM Language_Str MSG_UBL_SAVE_ERROR = _UxGT("Hata: UBL Kayıt"); PROGMEM Language_Str MSG_UBL_RESTORE_ERROR = _UxGT("Hata: UBL Yenileme"); + PROGMEM Language_Str MSG_UBL_Z_OFFSET = _UxGT("Z-Ofset: "); PROGMEM Language_Str MSG_UBL_Z_OFFSET_STOPPED = _UxGT("Z-Ofset Durduruldu"); PROGMEM Language_Str MSG_UBL_STEP_BY_STEP_MENU = _UxGT("Adım Adım UBL"); PROGMEM Language_Str MSG_UBL_1_BUILD_COLD_MESH = _UxGT("1.Soğuk Mesh Oluştur"); @@ -175,8 +209,8 @@ namespace Language_tr { PROGMEM Language_Str MSG_UBL_7_SAVE_MESH = _UxGT("7.Yatak Mesh Kayıt Et"); PROGMEM Language_Str MSG_LED_CONTROL = _UxGT("LED Kontrolü"); - PROGMEM Language_Str MSG_LEDS = _UxGT("Işıklar"); - PROGMEM Language_Str MSG_LED_PRESETS = _UxGT("Işık Hazır Ayarları"); + PROGMEM Language_Str MSG_LEDS = _UxGT("LEDler"); + PROGMEM Language_Str MSG_LED_PRESETS = _UxGT("LED Hazır Ayarları"); PROGMEM Language_Str MSG_SET_LEDS_RED = _UxGT("Kırmızı"); PROGMEM Language_Str MSG_SET_LEDS_ORANGE = _UxGT("Turuncu"); PROGMEM Language_Str MSG_SET_LEDS_YELLOW = _UxGT("Sarı"); @@ -192,6 +226,7 @@ namespace Language_tr { PROGMEM Language_Str MSG_INTENSITY_B = _UxGT("Mavi Şiddeti"); PROGMEM Language_Str MSG_INTENSITY_W = _UxGT("Beyaz Şiddeti"); PROGMEM Language_Str MSG_LED_BRIGHTNESS = _UxGT("Parlaklık"); + PROGMEM Language_Str MSG_MOVING = _UxGT("Hareket Ediyor.."); PROGMEM Language_Str MSG_FREE_XY = _UxGT("Durdur XY"); PROGMEM Language_Str MSG_MOVE_X = _UxGT("X Hareketi"); @@ -209,8 +244,10 @@ namespace Language_tr { PROGMEM Language_Str MSG_NOZZLE = _UxGT("Nozul"); PROGMEM Language_Str MSG_NOZZLE_N = _UxGT("Nozul ~"); PROGMEM Language_Str MSG_BED = _UxGT("Tabla"); + PROGMEM Language_Str MSG_CHAMBER = _UxGT("Çevirme"); PROGMEM Language_Str MSG_FAN_SPEED = _UxGT("Fan Hızı"); PROGMEM Language_Str MSG_FAN_SPEED_N = _UxGT("Fan Hızı ~"); + PROGMEM Language_Str MSG_STORED_FAN_N = _UxGT("Depolanan Fan ~"); PROGMEM Language_Str MSG_EXTRA_FAN_SPEED = _UxGT("Ekstra Fan Hızı"); PROGMEM Language_Str MSG_EXTRA_FAN_SPEED_N = _UxGT("Ekstra Fan Hızı ~"); PROGMEM Language_Str MSG_FLOW = _UxGT("Akış"); @@ -222,9 +259,22 @@ namespace Language_tr { PROGMEM Language_Str MSG_AUTOTEMP = _UxGT("Oto. Sıcaklık"); PROGMEM Language_Str MSG_LCD_ON = _UxGT("Açık"); PROGMEM Language_Str MSG_LCD_OFF = _UxGT("Kapalı"); + PROGMEM Language_Str MSG_PID_AUTOTUNE = _UxGT("PID Kalibrasyon"); + PROGMEM Language_Str MSG_PID_AUTOTUNE_E = _UxGT("PID Kalibrasyon *"); + PROGMEM Language_Str MSG_PID_P = _UxGT("PID-P"); + PROGMEM Language_Str MSG_PID_P_E = _UxGT("PID-P *"); + PROGMEM Language_Str MSG_PID_I = _UxGT("PID-I"); + PROGMEM Language_Str MSG_PID_I_E = _UxGT("PID-I *"); + PROGMEM Language_Str MSG_PID_D = _UxGT("PID-D"); + PROGMEM Language_Str MSG_PID_D_E = _UxGT("PID-D *"); + PROGMEM Language_Str MSG_PID_C = _UxGT("PID-C"); + PROGMEM Language_Str MSG_PID_C_E = _UxGT("PID-C *"); + PROGMEM Language_Str MSG_PID_F = _UxGT("PID-F"); + PROGMEM Language_Str MSG_PID_F_E = _UxGT("PID-F *"); PROGMEM Language_Str MSG_SELECT = _UxGT("Seç"); PROGMEM Language_Str MSG_SELECT_E = _UxGT("Seç *"); PROGMEM Language_Str MSG_ACC = _UxGT("İvme"); + PROGMEM Language_Str MSG_JERK = _UxGT("Sarsım"); PROGMEM Language_Str MSG_VA_JERK = _UxGT("V") LCD_STR_A _UxGT("-Sarsım"); PROGMEM Language_Str MSG_VB_JERK = _UxGT("V") LCD_STR_B _UxGT("-Sarsım"); @@ -268,15 +318,31 @@ namespace Language_tr { PROGMEM Language_Str MSG_LOAD_EEPROM = _UxGT("Hafızadan Yükle"); PROGMEM Language_Str MSG_RESTORE_DEFAULTS = _UxGT("Fabrika Ayarları"); PROGMEM Language_Str MSG_INIT_EEPROM = _UxGT("EEPROM'u başlat"); + PROGMEM Language_Str MSG_ERR_EEPROM_CRC = _UxGT("Hata: EEPROM CRC"); + PROGMEM Language_Str MSG_ERR_EEPROM_INDEX = _UxGT("Hata: EEPROM Indeks"); + PROGMEM Language_Str MSG_ERR_EEPROM_VERSION = _UxGT("Hata: EEPROM Versiyonu"); PROGMEM Language_Str MSG_MEDIA_UPDATE = _UxGT("SD Güncellemesi"); PROGMEM Language_Str MSG_RESET_PRINTER = _UxGT("Yazıcıyı Resetle"); PROGMEM Language_Str MSG_REFRESH = LCD_STR_REFRESH _UxGT("Yenile"); PROGMEM Language_Str MSG_INFO_SCREEN = _UxGT("Bilgi Ekranı"); PROGMEM Language_Str MSG_PREPARE = _UxGT("Hazırlık"); PROGMEM Language_Str MSG_TUNE = _UxGT("Ayar"); + PROGMEM Language_Str MSG_START_PRINT = _UxGT("Yaz. Başlat"); + PROGMEM Language_Str MSG_BUTTON_NEXT = _UxGT("İleri"); + PROGMEM Language_Str MSG_BUTTON_INIT = _UxGT("İçinde"); + PROGMEM Language_Str MSG_BUTTON_STOP = _UxGT("Durdur"); + PROGMEM Language_Str MSG_BUTTON_PRINT = _UxGT("Yazdır"); + PROGMEM Language_Str MSG_BUTTON_RESET = _UxGT("Resetle"); + PROGMEM Language_Str MSG_BUTTON_CANCEL = _UxGT("İptal"); + PROGMEM Language_Str MSG_BUTTON_DONE = _UxGT("Tamamlandı"); + PROGMEM Language_Str MSG_BUTTON_BACK = _UxGT("Geri"); + PROGMEM Language_Str MSG_BUTTON_PROCEED = _UxGT("Devam ediyor"); PROGMEM Language_Str MSG_PAUSE_PRINT = _UxGT("Duraklat"); PROGMEM Language_Str MSG_RESUME_PRINT = _UxGT("Sürdür"); PROGMEM Language_Str MSG_STOP_PRINT = _UxGT("Durdur"); + PROGMEM Language_Str MSG_PRINTING_OBJECT = _UxGT("Yazdırma Nesnesi"); + PROGMEM Language_Str MSG_CANCEL_OBJECT = _UxGT("Nesneyi İptal Et"); + PROGMEM Language_Str MSG_CANCEL_OBJECT_N = _UxGT("Nesneyi İptal Et ="); PROGMEM Language_Str MSG_OUTAGE_RECOVERY = _UxGT("Kesinti Kurtarma"); PROGMEM Language_Str MSG_MEDIA_MENU = _UxGT("SD Karttan Yazdır"); PROGMEM Language_Str MSG_NO_MEDIA = _UxGT("SD Kart Yok!"); @@ -292,16 +358,18 @@ namespace Language_tr { PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("Swap Re.mm"); PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("Geri Çekme V"); PROGMEM Language_Str MSG_CONTROL_RETRACT_ZHOP = _UxGT("Atlama mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("UnRet mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("S UnRet mm"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("UnRet V"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("Unretr. mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("S Unretr. mm"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("Unretract V"); PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAPF = _UxGT("S UnRet V"); PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("Oto. Geri Çekme"); PROGMEM Language_Str MSG_FILAMENT_SWAP_LENGTH = _UxGT("G.Çekme Boyu"); + PROGMEM Language_Str MSG_FILAMENT_PURGE_LENGTH = _UxGT("Tasfiye uzunluğu"); PROGMEM Language_Str MSG_TOOL_CHANGE = _UxGT("Takım Değişimi"); PROGMEM Language_Str MSG_TOOL_CHANGE_ZLIFT = _UxGT("Z Yükselt"); - PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPD = _UxGT("Birincil Hız"); - PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPD = _UxGT("Geri Çekme Hızı"); + PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPEED = _UxGT("Birincil Hız"); + PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPEED = _UxGT("Geri Çekme Hızı"); + PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("Nozul Beklemede"); PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("Filaman Değiştir"); PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Filaman Değiştir *"); PROGMEM Language_Str MSG_FILAMENTLOAD = _UxGT("Filaman Yükle"); @@ -311,30 +379,46 @@ namespace Language_tr { PROGMEM Language_Str MSG_FILAMENTUNLOAD_ALL = _UxGT("Tümünü Çıkart"); PROGMEM Language_Str MSG_ATTACH_MEDIA = _UxGT("SD Kart Başlatılıyor"); PROGMEM Language_Str MSG_CHANGE_MEDIA = _UxGT("SD Kart Değiştir"); + PROGMEM Language_Str MSG_RELEASE_MEDIA = _UxGT("SD Kart Çıkart"); PROGMEM Language_Str MSG_ZPROBE_OUT = _UxGT("Z Prob Açık. Tabla"); PROGMEM Language_Str MSG_SKEW_FACTOR = _UxGT("Çarpıklık Faktörü"); PROGMEM Language_Str MSG_BLTOUCH = _UxGT("BLTouch"); - PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("BLTouch Self-Test"); - PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("Sıfırla BLTouch"); - PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("BLTouch Aç"); - PROGMEM Language_Str MSG_BLTOUCH_STOW = _UxGT("BLTouch Kapat"); - PROGMEM Language_Str MSG_MANUAL_DEPLOY = _UxGT("Z-Prob Aç"); - PROGMEM Language_Str MSG_MANUAL_STOW = _UxGT("Z-Sensör Kapat"); - PROGMEM Language_Str MSG_HOME_FIRST = _UxGT("Sıfırla %s%s%s Önce"); + PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("BLTouch K. Test"); + PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("Reset"); + PROGMEM Language_Str MSG_BLTOUCH_STOW = _UxGT("Kapat"); + PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("Aç"); + PROGMEM Language_Str MSG_BLTOUCH_SW_MODE = _UxGT("SW-Modu"); + PROGMEM Language_Str MSG_BLTOUCH_5V_MODE = _UxGT("5V-Modu"); + PROGMEM Language_Str MSG_BLTOUCH_OD_MODE = _UxGT("OD-Modu"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE = _UxGT("Mode-Store"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_5V = _UxGT("BLTouch 5V Ayarla"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_OD = _UxGT("BLTouch OD Ayarla"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_ECHO = _UxGT("Drenaj Raporu"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_CHANGE = _UxGT("TEHLIKE: Kötü ayarlar hasara neden olabilir! Yine de devam edilsin mi?"); + PROGMEM Language_Str MSG_TOUCHMI_PROBE = _UxGT("TouchMI"); + PROGMEM Language_Str MSG_TOUCHMI_INIT = _UxGT("Init TouchMI"); + PROGMEM Language_Str MSG_TOUCHMI_ZTEST = _UxGT("Z Ofset Testi"); + PROGMEM Language_Str MSG_TOUCHMI_SAVE = _UxGT("Kaydet"); + PROGMEM Language_Str MSG_MANUAL_DEPLOY_TOUCHMI = _UxGT("TouchMI Aç"); + PROGMEM Language_Str MSG_MANUAL_DEPLOY = _UxGT("Z-Probe Aç"); + PROGMEM Language_Str MSG_MANUAL_STOW = _UxGT("Z-Probe Kapat"); + PROGMEM Language_Str MSG_HOME_FIRST = _UxGT("Önce %s%s%s Sıfırla"); + PROGMEM Language_Str MSG_ZPROBE_OFFSETS = _UxGT("Prob Ofsetleri"); + PROGMEM Language_Str MSG_ZPROBE_XOFFSET = _UxGT("X Prob Ofset"); + PROGMEM Language_Str MSG_ZPROBE_YOFFSET = _UxGT("Y Prob Ofset"); + PROGMEM Language_Str MSG_ZPROBE_ZOFFSET = _UxGT("Z Prob Ofset"); PROGMEM Language_Str MSG_BABYSTEP_X = _UxGT("Miniadım X"); PROGMEM Language_Str MSG_BABYSTEP_Y = _UxGT("Miniadım Y"); PROGMEM Language_Str MSG_BABYSTEP_Z = _UxGT("Miniadım Z"); + PROGMEM Language_Str MSG_BABYSTEP_TOTAL = _UxGT("Toplam"); PROGMEM Language_Str MSG_ENDSTOP_ABORT = _UxGT("Endstop iptal"); PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("Isınma başarısız"); - PROGMEM Language_Str MSG_HEATING_FAILED_LCD_BED = _UxGT("Yatak Isınma Başrsız"); PROGMEM Language_Str MSG_ERR_REDUNDANT_TEMP = _UxGT("Hata: Sıcaklık Aşımı"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("TERMAL PROBLEM"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY_BED = _UxGT("TABLA TERMAL PROBLEM"); + PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER = _UxGT("ODA TERMAL PROBLEM"); PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("Hata: MAX.SICAKLIK"); PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("Hata: MIN.SICAKLIK"); - PROGMEM Language_Str MSG_ERR_MAXTEMP_BED = _UxGT("Hata: MAX.SIC. TABLA"); - PROGMEM Language_Str MSG_ERR_MINTEMP_BED = _UxGT("Hata: MIN.SIC. TABLA"); - PROGMEM Language_Str MSG_ERR_Z_HOMING = _UxGT("Önce XY Sıfırla"); PROGMEM Language_Str MSG_HALTED = _UxGT("YAZICI DURDURULDU"); PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("Lütfen Resetleyin"); PROGMEM Language_Str MSG_SHORT_DAY = _UxGT("G"); // One character only @@ -344,6 +428,8 @@ namespace Language_tr { PROGMEM Language_Str MSG_COOLING = _UxGT("Soğuyor..."); PROGMEM Language_Str MSG_BED_HEATING = _UxGT("Tabla Isınıyor..."); PROGMEM Language_Str MSG_BED_COOLING = _UxGT("Tabla Soğuyor..."); + PROGMEM Language_Str MSG_CHAMBER_HEATING = _UxGT("Oda Isınıyor..."); + PROGMEM Language_Str MSG_CHAMBER_COOLING = _UxGT("Oda Soğuyor..."); PROGMEM Language_Str MSG_DELTA_CALIBRATE = _UxGT("Delta Kalibrasyonu"); PROGMEM Language_Str MSG_DELTA_CALIBRATE_X = _UxGT("Ayarla X"); PROGMEM Language_Str MSG_DELTA_CALIBRATE_Y = _UxGT("Ayarla Y"); @@ -371,8 +457,7 @@ namespace Language_tr { PROGMEM Language_Str MSG_INFO_PROTOCOL = _UxGT("Protokol"); PROGMEM Language_Str MSG_CASE_LIGHT = _UxGT("Aydınlatmayı Aç"); PROGMEM Language_Str MSG_CASE_LIGHT_BRIGHTNESS = _UxGT("Aydınlatma Parlaklğı"); - - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("Yanlış Yazıcı"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("Yanlış Yazıcı"); #if LCD_WIDTH >= 20 PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Baskı Sayısı"); @@ -387,6 +472,7 @@ namespace Language_tr { PROGMEM Language_Str MSG_INFO_PRINT_LONGEST = _UxGT("En Uzun"); PROGMEM Language_Str MSG_INFO_PRINT_FILAMENT = _UxGT("Filaman"); #endif + PROGMEM Language_Str MSG_INFO_MIN_TEMP = _UxGT("Min Sıc."); PROGMEM Language_Str MSG_INFO_MAX_TEMP = _UxGT("Max Sıc."); PROGMEM Language_Str MSG_INFO_PSU = _UxGT("Güç Kaynağı"); @@ -395,7 +481,9 @@ namespace Language_tr { PROGMEM Language_Str MSG_DAC_PERCENT_Y = _UxGT("Y Sürücü %"); PROGMEM Language_Str MSG_DAC_PERCENT_Z = _UxGT("Z Sürücü %"); PROGMEM Language_Str MSG_DAC_PERCENT_E = _UxGT("E Sürücü %"); + PROGMEM Language_Str MSG_ERROR_TMC = _UxGT("TMC BAĞLANTI HATASI"); PROGMEM Language_Str MSG_DAC_EEPROM_WRITE = _UxGT("DAC EEPROM Yaz"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER = _UxGT("FILAMAN DEGISTIR"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_PAUSE = _UxGT("BASKI DURAKLATILDI"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_LOAD = _UxGT("FILAMAN YüKLE"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_UNLOAD = _UxGT("FILAMAN ÇIKART"); @@ -404,15 +492,64 @@ namespace Language_tr { PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_RESUME = _UxGT("Baskıyı sürdür"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" Nozul: "); PROGMEM Language_Str MSG_RUNOUT_SENSOR = _UxGT("Runout Sensörü"); - PROGMEM Language_Str MSG_LCD_HOMING_FAILED = _UxGT("Sıfırlama Başarısız"); + PROGMEM Language_Str MSG_RUNOUT_DISTANCE_MM = _UxGT("Aşınma Farkı mm"); + PROGMEM Language_Str MSG_KILL_HOMING_FAILED = _UxGT("Sıfırlama Başarısız"); PROGMEM Language_Str MSG_LCD_PROBING_FAILED = _UxGT("Probing Başarısız"); - PROGMEM Language_Str MSG_M600_TOO_COLD = _UxGT("M600: Çok Soğuk"); + + PROGMEM Language_Str MSG_MMU2_CHOOSE_FILAMENT_HEADER = _UxGT("FILAMAN SEÇ"); + PROGMEM Language_Str MSG_MMU2_MENU = _UxGT("MMU"); + PROGMEM Language_Str MSG_KILL_MMU2_FIRMWARE = _UxGT("MMU Yaz. Güncelle!"); + PROGMEM Language_Str MSG_MMU2_NOT_RESPONDING = _UxGT("MMU Dikkat Gerektirir."); + PROGMEM Language_Str MSG_MMU2_RESUME = _UxGT("Yaz. Devam Et"); + PROGMEM Language_Str MSG_MMU2_RESUMING = _UxGT("Sürdürülüyor..."); + PROGMEM Language_Str MSG_MMU2_LOAD_FILAMENT = _UxGT("Filaman Yükle"); + PROGMEM Language_Str MSG_MMU2_LOAD_ALL = _UxGT("Tümünü Yükle"); + PROGMEM Language_Str MSG_MMU2_LOAD_TO_NOZZLE = _UxGT("Nozula Yükle"); + PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT = _UxGT("Filaman Çıkart"); + PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT_N = _UxGT("Filaman Çıkart ~"); + PROGMEM Language_Str MSG_MMU2_UNLOAD_FILAMENT = _UxGT("Filamenti Boşalt"); + PROGMEM Language_Str MSG_MMU2_LOADING_FILAMENT = _UxGT("Fil. Yükleniyor %i..."); + PROGMEM Language_Str MSG_MMU2_EJECTING_FILAMENT = _UxGT("Fil Çıkartılıyor. ..."); + PROGMEM Language_Str MSG_MMU2_UNLOADING_FILAMENT = _UxGT("Fil. Boşaltılıyor...."); + PROGMEM Language_Str MSG_MMU2_ALL = _UxGT("Tümü"); + PROGMEM Language_Str MSG_MMU2_FILAMENT_N = _UxGT("Filaman ~"); + PROGMEM Language_Str MSG_MMU2_RESET = _UxGT("MMU Resetle"); + PROGMEM Language_Str MSG_MMU2_RESETTING = _UxGT("MMU Resetleniyot..."); + PROGMEM Language_Str MSG_MMU2_EJECT_RECOVER = _UxGT("Kaldır, tıkla"); + + PROGMEM Language_Str MSG_MIX = _UxGT("Karışım"); + PROGMEM Language_Str MSG_MIX_COMPONENT_N = _UxGT("Bileşen ="); + PROGMEM Language_Str MSG_MIXER = _UxGT("Karıştırıcı"); + PROGMEM Language_Str MSG_GRADIENT = _UxGT("Gradyan"); + PROGMEM Language_Str MSG_FULL_GRADIENT = _UxGT("Tam Gradyan"); + PROGMEM Language_Str MSG_TOGGLE_MIX = _UxGT("Karışım Geçişi"); + PROGMEM Language_Str MSG_CYCLE_MIX = _UxGT("Döngü Karışımı"); + PROGMEM Language_Str MSG_GRADIENT_MIX = _UxGT("Gradyan Karışımı"); + PROGMEM Language_Str MSG_REVERSE_GRADIENT = _UxGT("Ters Gradyan"); + PROGMEM Language_Str MSG_ACTIVE_VTOOL = _UxGT("Aktif V-tool"); + PROGMEM Language_Str MSG_START_VTOOL = _UxGT("Başlat V-tool"); + PROGMEM Language_Str MSG_END_VTOOL = _UxGT(" Bitir V-tool"); + PROGMEM Language_Str MSG_GRADIENT_ALIAS = _UxGT("Alias V-tool"); + PROGMEM Language_Str MSG_RESET_VTOOLS = _UxGT("Reset V-tools"); + PROGMEM Language_Str MSG_COMMIT_VTOOL = _UxGT("V-tool Karışıö Yap"); + PROGMEM Language_Str MSG_VTOOLS_RESET = _UxGT("V-tools Resetlendi"); + PROGMEM Language_Str MSG_START_Z = _UxGT("Başlat Z:"); + PROGMEM Language_Str MSG_END_Z = _UxGT(" Bitir Z:"); + + PROGMEM Language_Str MSG_GAMES = _UxGT("Oyunlar"); + PROGMEM Language_Str MSG_BRICKOUT = _UxGT("Brickout"); + PROGMEM Language_Str MSG_INVADERS = _UxGT("Invaders"); + PROGMEM Language_Str MSG_SNAKE = _UxGT("Sn4k3"); + PROGMEM Language_Str MSG_MAZE = _UxGT("Maze"); + // - // Filament Değiştirme ekranları, 4 satırlı bir ekranda 3 satıra kadar gösterilir + // Filament Değişim ekranları 4 satırlı ekranda 3 satıra kadar gösterilir // ...veya 3 satırlı ekranda 2 satıra kadar + // #if LCD_HEIGHT >= 4 - // Up to 3 lines allowed + PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_2_LINE("Baskıya devam etmek", "için Butona bas")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Park Ediliyor...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_3_LINE("Filaman değişimi", "için başlama", "bekleniyor")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_3_LINE("Filamanı yükle", "ve devam için", "tuşa bas...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_2_LINE("Nozulü Isıtmak için", "Butona Bas.")); @@ -422,9 +559,9 @@ namespace Language_tr { PROGMEM Language_Str MSG_FILAMENT_CHANGE_PURGE = _UxGT(MSG_2_LINE("Filaman Temizlemesi", "için bekle")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_CONT_PURGE = _UxGT(MSG_2_LINE("Filaman Temizlemesi", "bitirmek için tıkla")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_2_LINE("Baskının devam ", "etmesi için bekle")); - #else // LCD_HEIGHT < 4 - // Up to 2 lines allowed + #else PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_1_LINE("Sürdürmek İçin Tıkla")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Park Ediliyor...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_1_LINE("Lütfen bekleyiniz...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_1_LINE("Yükle ve bas")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_1_LINE("Isıtmak için Tıkla")); @@ -434,5 +571,27 @@ namespace Language_tr { PROGMEM Language_Str MSG_FILAMENT_CHANGE_PURGE = _UxGT(MSG_1_LINE("Temizleniyor...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_CONT_PURGE = _UxGT(MSG_1_LINE("Bitirmek için Tıkla")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_1_LINE("Sürdürülüyor...")); - #endif // LCD_HEIGHT < 4 + #endif + PROGMEM Language_Str MSG_TMC_DRIVERS = _UxGT("TMC Sürücüleri"); + PROGMEM Language_Str MSG_TMC_CURRENT = _UxGT("Sürücü Akımı"); + PROGMEM Language_Str MSG_TMC_HYBRID_THRS = _UxGT("Hibrit Eşiği"); + PROGMEM Language_Str MSG_TMC_HOMING_THRS = _UxGT("Sensörsüz Sıfırlama"); + PROGMEM Language_Str MSG_TMC_STEPPING_MODE = _UxGT("Adım Modu"); + PROGMEM Language_Str MSG_TMC_STEALTH_ENABLED = _UxGT("StealthChop Aktif"); + PROGMEM Language_Str MSG_SERVICE_RESET = _UxGT("Resetle"); + PROGMEM Language_Str MSG_SERVICE_IN = _UxGT(" içinde:"); + PROGMEM Language_Str MSG_BACKLASH = _UxGT("Ters Tepki"); + PROGMEM Language_Str MSG_BACKLASH_A = LCD_STR_A; + PROGMEM Language_Str MSG_BACKLASH_B = LCD_STR_B; + PROGMEM Language_Str MSG_BACKLASH_C = LCD_STR_C; + PROGMEM Language_Str MSG_BACKLASH_CORRECTION = _UxGT("Düzeltme"); + PROGMEM Language_Str MSG_BACKLASH_SMOOTHING = _UxGT("Yumuşatma"); } + +#if FAN_COUNT == 1 + #define MSG_FIRST_FAN_SPEED MSG_FAN_SPEED + #define MSG_EXTRA_FIRST_FAN_SPEED MSG_EXTRA_FAN_SPEED +#else + #define MSG_FIRST_FAN_SPEED MSG_FAN_SPEED_N + #define MSG_EXTRA_FIRST_FAN_SPEED MSG_EXTRA_FAN_SPEED_N +#endif diff --git a/Marlin/src/lcd/language/language_uk.h b/Marlin/src/lcd/language/language_uk.h index 0d473bf0af64..9cc1002964f8 100644 --- a/Marlin/src/lcd/language/language_uk.h +++ b/Marlin/src/lcd/language/language_uk.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,8 +25,7 @@ * Ukrainian * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ #define DISPLAY_CHARSET_ISO10646_5 @@ -37,205 +36,734 @@ namespace Language_uk { constexpr uint8_t CHARSIZE = 2; PROGMEM Language_Str LANGUAGE = _UxGT("Ukranian"); - PROGMEM Language_Str WELCOME_MSG = MACHINE_NAME _UxGT(" готовий."); - PROGMEM Language_Str MSG_MEDIA_INSERTED = _UxGT("Картка вставлена"); - PROGMEM Language_Str MSG_MEDIA_REMOVED = _UxGT("Картка видалена"); + PROGMEM Language_Str WELCOME_MSG = MACHINE_NAME _UxGT(" Готовий."); + PROGMEM Language_Str MSG_YES = _UxGT("ТАК"); + PROGMEM Language_Str MSG_NO = _UxGT("НІ"); + PROGMEM Language_Str MSG_BACK = _UxGT("Назад"); + PROGMEM Language_Str MSG_MEDIA_ABORTING = _UxGT("Переривання..."); + PROGMEM Language_Str MSG_MEDIA_INSERTED = _UxGT("SD-картка вставлена"); + PROGMEM Language_Str MSG_MEDIA_REMOVED = _UxGT("SD-картка видалена"); + PROGMEM Language_Str MSG_MEDIA_WAITING = _UxGT("Вставте SD-картку"); + PROGMEM Language_Str MSG_MEDIA_READ_ERROR = _UxGT("Помилка зчитування"); + PROGMEM Language_Str MSG_MEDIA_USB_REMOVED = _UxGT("USB диск видалений"); + PROGMEM Language_Str MSG_MEDIA_USB_FAILED = _UxGT("Помилка USB диску"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_KILL_SUBCALL_OVERFLOW = _UxGT("Переповнення виклику"); + PROGMEM Language_Str MSG_LCD_SOFT_ENDSTOPS = _UxGT("Програмні кінцевики"); + #else + PROGMEM Language_Str MSG_KILL_SUBCALL_OVERFLOW = _UxGT("Переповн. виклику"); + PROGMEM Language_Str MSG_LCD_SOFT_ENDSTOPS = _UxGT("Прогр.кінцевики"); + #endif PROGMEM Language_Str MSG_LCD_ENDSTOPS = _UxGT("Кінцевик"); // Max length 8 characters - PROGMEM Language_Str MSG_MAIN = _UxGT("Меню"); + PROGMEM Language_Str MSG_MAIN = _UxGT("Основне меню"); + PROGMEM Language_Str MSG_ADVANCED_SETTINGS = _UxGT("Інші налаштування"); + PROGMEM Language_Str MSG_CONFIGURATION = _UxGT("Конфігурація"); PROGMEM Language_Str MSG_AUTOSTART = _UxGT("Автостарт"); - PROGMEM Language_Str MSG_DISABLE_STEPPERS = _UxGT("Вимк. двигуни"); + PROGMEM Language_Str MSG_DISABLE_STEPPERS = _UxGT("Вимкнути двигуни"); + PROGMEM Language_Str MSG_DEBUG_MENU = _UxGT("Меню Debug"); + PROGMEM Language_Str MSG_PROGRESS_BAR_TEST = _UxGT("Тест Progress Bar"); PROGMEM Language_Str MSG_AUTO_HOME = _UxGT("Авто паркування"); PROGMEM Language_Str MSG_AUTO_HOME_X = _UxGT("Паркування X"); PROGMEM Language_Str MSG_AUTO_HOME_Y = _UxGT("Паркування Y"); PROGMEM Language_Str MSG_AUTO_HOME_Z = _UxGT("Паркування Z"); + PROGMEM Language_Str MSG_AUTO_Z_ALIGN = _UxGT("Авто Z-вирівнювання"); PROGMEM Language_Str MSG_LEVEL_BED_HOMING = _UxGT("Паркування XYZ"); PROGMEM Language_Str MSG_LEVEL_BED_WAITING = _UxGT("Почати"); - PROGMEM Language_Str MSG_LEVEL_BED_NEXT_POINT = _UxGT("Слідуюча Точка"); + PROGMEM Language_Str MSG_LEVEL_BED_NEXT_POINT = _UxGT("Наступна точка"); PROGMEM Language_Str MSG_LEVEL_BED_DONE = _UxGT("Завершено!"); - PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Зберегти паркув."); - PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Зміщення застос."); - PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Встанов. початок"); - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Нагрів ") PREHEAT_1_LABEL; - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Нагрів ") PREHEAT_1_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Нагрів ") PREHEAT_1_LABEL _UxGT(" Сопло"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Нагрів ") PREHEAT_1_LABEL _UxGT(" Сопло ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Нагрів ") PREHEAT_1_LABEL _UxGT(" Все"); - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Нагрів ") PREHEAT_1_LABEL _UxGT(" Стіл"); - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Нагрів ") PREHEAT_1_LABEL _UxGT(" нал."); - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("Нагрів ") PREHEAT_2_LABEL; - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("Нагрів ") PREHEAT_2_LABEL " ~"; - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("Нагрів ") PREHEAT_2_LABEL _UxGT(" Сопло"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("Нагрів ") PREHEAT_2_LABEL _UxGT(" Сопло ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("Нагрів ") PREHEAT_2_LABEL _UxGT(" Все"); - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("Нагрів ") PREHEAT_2_LABEL _UxGT(" Стіл"); - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("Нагрів ") PREHEAT_2_LABEL _UxGT(" нал."); - PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Охолодження"); + PROGMEM Language_Str MSG_Z_FADE_HEIGHT = _UxGT("Висота спаду"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Встанов. зміщення дому"); + #else + PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Встанов.зміщ.дому"); + #endif + PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Зміщення прийняті"); + PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Встановити ноль"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Нагрів ") PREHEAT_1_LABEL; + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Нагрів ") PREHEAT_1_LABEL " ~"; + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Нагрів ") PREHEAT_1_LABEL _UxGT(" сопло"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Нагрів ") PREHEAT_1_LABEL _UxGT(" сопло ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Нагрів ") PREHEAT_1_LABEL _UxGT(" все"); + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Нагрів ") PREHEAT_1_LABEL _UxGT(" стіл"); + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Нагрів ") PREHEAT_1_LABEL _UxGT(" налашт"); + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Нагрів $"); + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Нагрів $ ~"); + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Нагрів $ сопло"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Нагрів $ сопло ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Нагрів $ все"); + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Нагрів $ стіл"); + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Нагрів $ налашт"); + #endif + PROGMEM Language_Str MSG_PREHEAT_CUSTOM = _UxGT("Нагрів Свій"); + PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Вимкнути нагрів"); + PROGMEM Language_Str MSG_CUTTER_FREQUENCY = _UxGT("Частота"); + PROGMEM Language_Str MSG_LASER_MENU = _UxGT("Керування лазером"); + PROGMEM Language_Str MSG_LASER_OFF = _UxGT("Вимкнути лазер"); + PROGMEM Language_Str MSG_LASER_ON = _UxGT("Увімкнути лазер"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_LASER_POWER = _UxGT("Потужність лазера"); + PROGMEM Language_Str MSG_SPINDLE_MENU = _UxGT("Керування шпінделем"); + #else + PROGMEM Language_Str MSG_LASER_POWER = _UxGT("Потуж.лазера"); + PROGMEM Language_Str MSG_SPINDLE_MENU = _UxGT("Керув. шпінделем"); + #endif + PROGMEM Language_Str MSG_SPINDLE_OFF = _UxGT("Вимкнути шпіндель"); + PROGMEM Language_Str MSG_SPINDLE_ON = _UxGT("Увімкнути шпіндель"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_SPINDLE_POWER = _UxGT("Потуж. шпінделя"); + #else + PROGMEM Language_Str MSG_SPINDLE_POWER = _UxGT("Потуж. шпінд."); + #endif + PROGMEM Language_Str MSG_SPINDLE_REVERSE = _UxGT("Напрямок шпінделя"); PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Увімкнути живлення"); PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("Вимкнути живлення"); PROGMEM Language_Str MSG_EXTRUDE = _UxGT("Екструзія"); PROGMEM Language_Str MSG_RETRACT = _UxGT("Втягування"); PROGMEM Language_Str MSG_MOVE_AXIS = _UxGT("Рух по осям"); - PROGMEM Language_Str MSG_BED_LEVELING = _UxGT("Нівелювання столу"); - PROGMEM Language_Str MSG_LEVEL_BED = _UxGT("Нівелювання столу"); + PROGMEM Language_Str MSG_BED_LEVELING = _UxGT("Вирівнювання столу"); + PROGMEM Language_Str MSG_LEVEL_BED = _UxGT("Вирівняти стіл"); + PROGMEM Language_Str MSG_LEVEL_CORNERS = _UxGT("Вирівняти кути"); + PROGMEM Language_Str MSG_NEXT_CORNER = _UxGT("Наступний кут"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_MESH_EDITOR = _UxGT("Зміщення по Z"); + #else + PROGMEM Language_Str MSG_MESH_EDITOR = _UxGT("Зміщення Z"); + #endif + PROGMEM Language_Str MSG_EDIT_MESH = _UxGT("Редагувати сітку"); + PROGMEM Language_Str MSG_EDITING_STOPPED = _UxGT("Редагув. зупинено"); + PROGMEM Language_Str MSG_PROBING_MESH = _UxGT("Точка сітки"); + PROGMEM Language_Str MSG_MESH_X = _UxGT("Індекс X"); + PROGMEM Language_Str MSG_MESH_Y = _UxGT("Індекс Y"); + PROGMEM Language_Str MSG_MESH_EDIT_Z = _UxGT("Значення Z"); + PROGMEM Language_Str MSG_USER_MENU = _UxGT("Власні команди"); + PROGMEM Language_Str MSG_M48_TEST = _UxGT("M48 тест зонду"); + PROGMEM Language_Str MSG_M48_POINT = _UxGT("M48 точка"); + PROGMEM Language_Str MSG_M48_DEVIATION = _UxGT("Відхилення"); + PROGMEM Language_Str MSG_IDEX_MENU = _UxGT("Меню IDEX"); + PROGMEM Language_Str MSG_OFFSETS_MENU = _UxGT("Зміщення сопел"); + PROGMEM Language_Str MSG_IDEX_MODE_AUTOPARK = _UxGT("Авто паркування"); + PROGMEM Language_Str MSG_IDEX_MODE_DUPLICATE = _UxGT("Розмноження"); + PROGMEM Language_Str MSG_IDEX_MODE_MIRRORED_COPY = _UxGT("Дзеркальна копія"); + PROGMEM Language_Str MSG_IDEX_MODE_FU1L_CTRL = _UxGT("Повний контроль"); + PROGMEM Language_Str MSG_HOTEND_OFFSET_X = _UxGT("Друге сопло X"); + PROGMEM Language_Str MSG_HOTEND_OFFSET_Y = _UxGT("Друге сопло Y"); + PROGMEM Language_Str MSG_HOTEND_OFFSET_Z = _UxGT("Друге сопло Z"); + + PROGMEM Language_Str MSG_UBL_DOING_G29 = _UxGT("Виконується G29"); + PROGMEM Language_Str MSG_UBL_TOOLS = _UxGT("Інструменти UBL"); + PROGMEM Language_Str MSG_UBL_LEVEL_BED = _UxGT("Налаштування UBL"); + PROGMEM Language_Str MSG_LCD_TILTING_MESH = _UxGT("Точка розвороту"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_UBL_MANUAL_MESH = _UxGT("Ручне введення сітки"); + PROGMEM Language_Str MSG_UBL_BC_INSERT = _UxGT("Розмістити шайбу і вимір."); + #else + PROGMEM Language_Str MSG_UBL_MANUAL_MESH = _UxGT("Ручне введ. сітки"); + PROGMEM Language_Str MSG_UBL_BC_INSERT = _UxGT("Розм. шайбу і вимір."); + #endif + PROGMEM Language_Str MSG_UBL_BC_INSERT2 = _UxGT("Вимірювання"); + PROGMEM Language_Str MSG_UBL_BC_REMOVE = _UxGT("Видалити і виміряти"); + PROGMEM Language_Str MSG_UBL_MOVING_TO_NEXT = _UxGT("До наступної точки"); + PROGMEM Language_Str MSG_UBL_ACTIVATE_MESH = _UxGT("Активувати UBL"); + PROGMEM Language_Str MSG_UBL_DEACTIVATE_MESH = _UxGT("Деактивувати UBL"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_UBL_SET_TEMP_BED = _UxGT("Температура столу"); + PROGMEM Language_Str MSG_UBL_BED_TEMP_CUSTOM = _UxGT("Температура столу"); + PROGMEM Language_Str MSG_UBL_SET_TEMP_HOTEND = _UxGT("Температура сопла"); + PROGMEM Language_Str MSG_UBL_HOTEND_TEMP_CUSTOM = _UxGT("Температура сопла"); + PROGMEM Language_Str MSG_UBL_EDIT_CUSTOM_MESH = _UxGT("Редагувати свою сітку"); + PROGMEM Language_Str MSG_UBL_FINE_TUNE_MESH = _UxGT("Точне редагування сітки"); + PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("Будувати свою сітку"); + #else + PROGMEM Language_Str MSG_UBL_SET_TEMP_BED = LCD_STR_THERMOMETER _UxGT(" столу, ") LCD_STR_DEGREE "C"; + PROGMEM Language_Str MSG_UBL_BED_TEMP_CUSTOM = LCD_STR_THERMOMETER _UxGT(" столу, ") LCD_STR_DEGREE "C"; + PROGMEM Language_Str MSG_UBL_SET_TEMP_HOTEND = LCD_STR_THERMOMETER _UxGT(" сопла, ") LCD_STR_DEGREE "C"; + PROGMEM Language_Str MSG_UBL_HOTEND_TEMP_CUSTOM = LCD_STR_THERMOMETER _UxGT(" сопла, ") LCD_STR_DEGREE "C"; + PROGMEM Language_Str MSG_UBL_EDIT_CUSTOM_MESH = _UxGT("Редагувати свою"); + PROGMEM Language_Str MSG_UBL_FINE_TUNE_MESH = _UxGT("Точне редаг. сітки"); + PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("Будувати свою"); + #endif + PROGMEM Language_Str MSG_UBL_MESH_EDIT = _UxGT("Редагування сітки"); + PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("Сітка побудована"); + PROGMEM Language_Str MSG_UBL_BUILD_MESH_MENU = _UxGT("Будувати сітку"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_UBL_BUILD_MESH_M = _UxGT("Будувати сітку $"); + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("Підтвердити $"); + #endif + PROGMEM Language_Str MSG_UBL_BUILD_COLD_MESH = _UxGT("Буд. холодну сітку"); + PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_ADJUST = _UxGT("Встан.висоту сітки"); + PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_AMOUNT = _UxGT("Висота"); + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_MENU = _UxGT("Підтвердити сітку"); + PROGMEM Language_Str MSG_UBL_VALIDATE_CUSTOM_MESH = _UxGT("Підтвердити свою"); + PROGMEM Language_Str MSG_G26_HEATING_BED = _UxGT("G26 нагрів столу"); + PROGMEM Language_Str MSG_G26_HEATING_NOZZLE = _UxGT("G26 нагрів сопла"); + PROGMEM Language_Str MSG_G26_MANUAL_PRIME = _UxGT("Ручне грунтування"); + PROGMEM Language_Str MSG_G26_FIXED_LENGTH = _UxGT("Грунт фікс. довж."); + PROGMEM Language_Str MSG_G26_PRIME_DONE = _UxGT("Грунтув. виконане"); + PROGMEM Language_Str MSG_G26_CANCELED = _UxGT("G26 завершена"); + PROGMEM Language_Str MSG_G26_LEAVING = _UxGT("Вийти з G26"); + PROGMEM Language_Str MSG_UBL_CONTINUE_MESH = _UxGT("Продовжити сітку"); + PROGMEM Language_Str MSG_UBL_MESH_LEVELING = _UxGT("Вирівнювання сітки"); + PROGMEM Language_Str MSG_UBL_3POINT_MESH_LEVELING = _UxGT("3-точкове вирівн."); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_UBL_GRID_MESH_LEVELING = _UxGT("Вирівнювання растру"); + #else + PROGMEM Language_Str MSG_UBL_GRID_MESH_LEVELING = _UxGT("Вирівнюв. растру"); + #endif + PROGMEM Language_Str MSG_UBL_MESH_LEVEL = _UxGT("Вирівняти сітку"); + PROGMEM Language_Str MSG_UBL_SIDE_POINTS = _UxGT("Крайні точки"); + PROGMEM Language_Str MSG_UBL_MAP_TYPE = _UxGT("Тип мапи сітки"); + PROGMEM Language_Str MSG_UBL_OUTPUT_MAP = _UxGT("Вивести мапу сітки"); + PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_HOST = _UxGT("Вивести на хост"); + PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_CSV = _UxGT("Вивести в CSV"); + PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_BACKUP = _UxGT("Зберегти зовні"); + PROGMEM Language_Str MSG_UBL_INFO_UBL = _UxGT("Інформація по UBL"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_UBL_FILLIN_AMOUNT = _UxGT("Обсяг заповнювача"); + #else + PROGMEM Language_Str MSG_UBL_FILLIN_AMOUNT = _UxGT("Обсяг заповн."); + #endif + PROGMEM Language_Str MSG_UBL_MANUAL_FILLIN = _UxGT("Ручне заповнення"); + PROGMEM Language_Str MSG_UBL_SMART_FILLIN = _UxGT("Розумне заповнення"); + PROGMEM Language_Str MSG_UBL_FILLIN_MESH = _UxGT("Заповнити сітку"); + PROGMEM Language_Str MSG_UBL_INVALIDATE_ALL = _UxGT("Анулювати все"); + PROGMEM Language_Str MSG_UBL_INVALIDATE_CLOSEST = _UxGT("Анулювати найближчу"); + PROGMEM Language_Str MSG_UBL_FINE_TUNE_ALL = _UxGT("Точно налашт. все"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_UBL_FINE_TUNE_CLOSEST = _UxGT("Точно налашт.найближчу"); + #else + PROGMEM Language_Str MSG_UBL_FINE_TUNE_CLOSEST = _UxGT("Точно найближчу"); + #endif + PROGMEM Language_Str MSG_UBL_STORAGE_MESH_MENU = _UxGT("Збереження сітки"); + PROGMEM Language_Str MSG_UBL_STORAGE_SLOT = _UxGT("Слот пам'яті"); + PROGMEM Language_Str MSG_UBL_LOAD_MESH = _UxGT("Завантажити сітку"); + PROGMEM Language_Str MSG_UBL_SAVE_MESH = _UxGT("Зберегти сітку"); + PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("Сітка %i завантажена"); + PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("Сітка %i збережена"); + PROGMEM Language_Str MSG_UBL_NO_STORAGE = _UxGT("Немає носія"); + PROGMEM Language_Str MSG_UBL_SAVE_ERROR = _UxGT("Збій: збереж. UBL"); + PROGMEM Language_Str MSG_UBL_RESTORE_ERROR = _UxGT("Збій: відновл. UBL"); + PROGMEM Language_Str MSG_UBL_Z_OFFSET = _UxGT("Зміщення Z: "); + PROGMEM Language_Str MSG_UBL_Z_OFFSET_STOPPED = _UxGT("Зміщення Z зупинено"); + PROGMEM Language_Str MSG_UBL_STEP_BY_STEP_MENU = _UxGT("UBL покроково"); + PROGMEM Language_Str MSG_UBL_1_BUILD_COLD_MESH = _UxGT("1.Будувати холодну"); + PROGMEM Language_Str MSG_UBL_2_SMART_FILLIN = _UxGT("2.Розумне заповн-я"); + PROGMEM Language_Str MSG_UBL_3_VALIDATE_MESH_MENU = _UxGT("3.Затвердити сітку"); + PROGMEM Language_Str MSG_UBL_4_FINE_TUNE_ALL = _UxGT("4.Точно налашт.все"); + PROGMEM Language_Str MSG_UBL_5_VALIDATE_MESH_MENU = _UxGT("5.Затвердити сітку"); + PROGMEM Language_Str MSG_UBL_6_FINE_TUNE_ALL = _UxGT("6.Точно налашт.все"); + PROGMEM Language_Str MSG_UBL_7_SAVE_MESH = _UxGT("7.Зберегти сітку"); + + PROGMEM Language_Str MSG_LED_CONTROL = _UxGT("Керування світлом"); + PROGMEM Language_Str MSG_LEDS = _UxGT("Підсвітка"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_LED_PRESETS = _UxGT("Передустановки світла"); + #else + PROGMEM Language_Str MSG_LED_PRESETS = _UxGT("Передустан. світла"); + #endif + PROGMEM Language_Str MSG_SET_LEDS_RED = _UxGT("Червоний"); + PROGMEM Language_Str MSG_SET_LEDS_ORANGE = _UxGT("Оранжевий"); + PROGMEM Language_Str MSG_SET_LEDS_YELLOW = _UxGT("Жовтий"); + PROGMEM Language_Str MSG_SET_LEDS_GREEN = _UxGT("Зелений"); + PROGMEM Language_Str MSG_SET_LEDS_BLUE = _UxGT("Синій"); + PROGMEM Language_Str MSG_SET_LEDS_INDIGO = _UxGT("Індіго"); + PROGMEM Language_Str MSG_SET_LEDS_VIOLET = _UxGT("Фіолетовий"); + PROGMEM Language_Str MSG_SET_LEDS_WHITE = _UxGT("Білий"); + PROGMEM Language_Str MSG_SET_LEDS_DEFAULT = _UxGT("За умовчанням"); + PROGMEM Language_Str MSG_CUSTOM_LEDS = _UxGT("Свої кольори"); + PROGMEM Language_Str MSG_INTENSITY_R = _UxGT("Рівень червоного"); + PROGMEM Language_Str MSG_INTENSITY_G = _UxGT("Рівень зеленого"); + PROGMEM Language_Str MSG_INTENSITY_B = _UxGT("Рівень синього"); + PROGMEM Language_Str MSG_INTENSITY_W = _UxGT("Рівень білого"); + PROGMEM Language_Str MSG_LED_BRIGHTNESS = _UxGT("Яскравість"); + + PROGMEM Language_Str MSG_MOVING = _UxGT("Переміщення..."); + PROGMEM Language_Str MSG_FREE_XY = _UxGT("Звільнити XY"); PROGMEM Language_Str MSG_MOVE_X = _UxGT("Рух по X"); PROGMEM Language_Str MSG_MOVE_Y = _UxGT("Рух по Y"); PROGMEM Language_Str MSG_MOVE_Z = _UxGT("Рух по Z"); PROGMEM Language_Str MSG_MOVE_E = _UxGT("Екструдер"); PROGMEM Language_Str MSG_MOVE_EN = _UxGT("Екструдер *"); - PROGMEM Language_Str MSG_MOVE_Z_DIST = _UxGT("Рух по %smm"); - PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Рух по 0.1mm"); - PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Рух по 1mm"); - PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Рух по 10mm"); + PROGMEM Language_Str MSG_HOTEND_TOO_COLD = _UxGT("Сопло дуже холодне"); + PROGMEM Language_Str MSG_MOVE_Z_DIST = _UxGT("Рух по %sмм"); + PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Рух по 0.1мм"); + PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Рух по 1мм"); + PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Рух по 10мм"); PROGMEM Language_Str MSG_SPEED = _UxGT("Швидкість"); PROGMEM Language_Str MSG_BED_Z = _UxGT("Z Столу"); - PROGMEM Language_Str MSG_NOZZLE = _UxGT("Сопло"); + PROGMEM Language_Str MSG_NOZZLE = _UxGT("Сопло, ") LCD_STR_DEGREE "C"; PROGMEM Language_Str MSG_NOZZLE_N = _UxGT("Сопло ~"); - PROGMEM Language_Str MSG_BED = _UxGT("Стіл"); - PROGMEM Language_Str MSG_FAN_SPEED = _UxGT("Охолодж."); - PROGMEM Language_Str MSG_FAN_SPEED_N = _UxGT("Охолодж. ~"); + PROGMEM Language_Str MSG_NOZZLE_PARKED = _UxGT("Сопло запарковане"); + PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("Сопло очикує"); + PROGMEM Language_Str MSG_BED = _UxGT("Стіл, ") LCD_STR_DEGREE "C"; + PROGMEM Language_Str MSG_CHAMBER = _UxGT("Камера,") LCD_STR_DEGREE "C"; + PROGMEM Language_Str MSG_FAN_SPEED = _UxGT("Охолодження"); + PROGMEM Language_Str MSG_FAN_SPEED_N = _UxGT("Охолодження ~"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_STORED_FAN_N = _UxGT("Збережене охолодж. ~"); + PROGMEM Language_Str MSG_EXTRA_FAN_SPEED = _UxGT("Додаткове охолодж."); + PROGMEM Language_Str MSG_EXTRA_FAN_SPEED_N = _UxGT("Додаткове охолодж. ~"); + PROGMEM Language_Str MSG_CONTROLLER_FAN = _UxGT("Контролер охолодження"); + #else + PROGMEM Language_Str MSG_STORED_FAN_N = _UxGT("Збереж.охолодж. ~"); + PROGMEM Language_Str MSG_EXTRA_FAN_SPEED = _UxGT("Додат. охолодж."); + PROGMEM Language_Str MSG_EXTRA_FAN_SPEED_N = _UxGT("Додат.охолодж ~"); + PROGMEM Language_Str MSG_CONTROLLER_FAN = _UxGT("Контролер охолодж."); + #endif + PROGMEM Language_Str MSG_CONTROLLER_FAN_IDLE_SPEED = _UxGT("Холості оберти"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_SPEED = _UxGT("Робочі оберти"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_AUTO_ON = _UxGT("Авто-режим"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_DURATION = _UxGT("Період простою"); PROGMEM Language_Str MSG_FLOW = _UxGT("Потік"); PROGMEM Language_Str MSG_FLOW_N = _UxGT("Потік ~"); PROGMEM Language_Str MSG_CONTROL = _UxGT("Налаштування"); - PROGMEM Language_Str MSG_MIN = " " LCD_STR_THERMOMETER _UxGT(" Мін"); - PROGMEM Language_Str MSG_MAX = " " LCD_STR_THERMOMETER _UxGT(" Макс"); - PROGMEM Language_Str MSG_FACTOR = " " LCD_STR_THERMOMETER _UxGT(" Факт"); + PROGMEM Language_Str MSG_MIN = " " LCD_STR_THERMOMETER ", " LCD_STR_DEGREE _UxGT("С мін"); + PROGMEM Language_Str MSG_MAX = " " LCD_STR_THERMOMETER ", " LCD_STR_DEGREE _UxGT("С макс"); + PROGMEM Language_Str MSG_FACTOR = " " LCD_STR_THERMOMETER _UxGT(" Фактор"); PROGMEM Language_Str MSG_AUTOTEMP = _UxGT("Автотемпер."); - PROGMEM Language_Str MSG_LCD_ON = _UxGT("Увімк."); + PROGMEM Language_Str MSG_LCD_ON = _UxGT("Увімк"); PROGMEM Language_Str MSG_LCD_OFF = _UxGT("Вимк."); + + PROGMEM Language_Str MSG_PID_AUTOTUNE = _UxGT("Автопідбір PID"); + PROGMEM Language_Str MSG_PID_AUTOTUNE_E = _UxGT("Автопідбір PID *"); + PROGMEM Language_Str MSG_PID_AUTOTUNE_DONE = _UxGT("Підбір PID виконано"); + PROGMEM Language_Str MSG_PID_BAD_EXTRUDER_NUM = _UxGT("Збій автопідбору. Поганий екструдер."); + PROGMEM Language_Str MSG_PID_TEMP_TOO_HIGH = _UxGT("Збій автопідбору. Температура завищена."); + PROGMEM Language_Str MSG_PID_TIMEOUT = _UxGT("Збій автопідбору! Завершення часу."); + PROGMEM Language_Str MSG_SELECT = _UxGT("Вибрати"); PROGMEM Language_Str MSG_SELECT_E = _UxGT("Вибрати *"); - PROGMEM Language_Str MSG_ACC = _UxGT("Приск."); + PROGMEM Language_Str MSG_ACC = _UxGT("Прискорорення"); PROGMEM Language_Str MSG_JERK = _UxGT("Ривок"); PROGMEM Language_Str MSG_VA_JERK = _UxGT("V") LCD_STR_A _UxGT("-ривок"); PROGMEM Language_Str MSG_VB_JERK = _UxGT("V") LCD_STR_B _UxGT("-ривок"); PROGMEM Language_Str MSG_VC_JERK = _UxGT("V") LCD_STR_C _UxGT("-ривок"); PROGMEM Language_Str MSG_VE_JERK = _UxGT("Ve-ривок"); - PROGMEM Language_Str MSG_VMAX_A = _UxGT("Vмакс") LCD_STR_A; - PROGMEM Language_Str MSG_VMAX_B = _UxGT("Vмакс") LCD_STR_B; - PROGMEM Language_Str MSG_VMAX_C = _UxGT("Vмакс") LCD_STR_C; - PROGMEM Language_Str MSG_VMAX_E = _UxGT("Vмакс") LCD_STR_E; - PROGMEM Language_Str MSG_VMAX_EN = _UxGT("Vмакс *"); - PROGMEM Language_Str MSG_VMIN = _UxGT("Vмін"); - PROGMEM Language_Str MSG_VTRAV_MIN = _UxGT("Vруху мін"); - PROGMEM Language_Str MSG_AMAX_A = _UxGT("Aмакс ") LCD_STR_A; - PROGMEM Language_Str MSG_AMAX_B = _UxGT("Aмакс ") LCD_STR_B; - PROGMEM Language_Str MSG_AMAX_C = _UxGT("Aмакс ") LCD_STR_C; - PROGMEM Language_Str MSG_AMAX_E = _UxGT("Aмакс ") LCD_STR_E; - PROGMEM Language_Str MSG_AMAX_EN = _UxGT("Aмакс *"); - PROGMEM Language_Str MSG_A_RETRACT = _UxGT("A-втягув."); - PROGMEM Language_Str MSG_A_TRAVEL = _UxGT("A-руху"); - PROGMEM Language_Str MSG_STEPS_PER_MM = _UxGT("Кроків/мм"); - PROGMEM Language_Str MSG_A_STEPS = LCD_STR_A _UxGT("кроків/мм"); - PROGMEM Language_Str MSG_B_STEPS = LCD_STR_B _UxGT("кроків/мм"); - PROGMEM Language_Str MSG_C_STEPS = LCD_STR_C _UxGT("кроків/мм"); - PROGMEM Language_Str MSG_E_STEPS = _UxGT("Eкроків/мм"); - PROGMEM Language_Str MSG_EN_STEPS = _UxGT("*кроків/мм"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_JUNCTION_DEVIATION = _UxGT("Відхилення вузла"); + #else + PROGMEM Language_Str MSG_JUNCTION_DEVIATION = _UxGT("Відхил.вузла"); + #endif + PROGMEM Language_Str MSG_VELOCITY = _UxGT("Швидкість, мм/с"); + PROGMEM Language_Str MSG_VMAX_A = _UxGT("Швидк.макс ") LCD_STR_A; + PROGMEM Language_Str MSG_VMAX_B = _UxGT("Швидк.макс ") LCD_STR_B; + PROGMEM Language_Str MSG_VMAX_C = _UxGT("Швидк.макс ") LCD_STR_C; + PROGMEM Language_Str MSG_VMAX_E = _UxGT("Швидк.макс ") LCD_STR_E; + PROGMEM Language_Str MSG_VMAX_EN = _UxGT("Швидк.макс *"); + PROGMEM Language_Str MSG_VMIN = _UxGT("Швидк.мін"); + PROGMEM Language_Str MSG_VTRAV_MIN = _UxGT("Переміщення мін"); + PROGMEM Language_Str MSG_ACCELERATION = _UxGT("Прискорення, мм/с2"); + PROGMEM Language_Str MSG_AMAX_A = _UxGT("Приск.макс ") LCD_STR_A; + PROGMEM Language_Str MSG_AMAX_B = _UxGT("Приск.макс ") LCD_STR_B; + PROGMEM Language_Str MSG_AMAX_C = _UxGT("Приск.макс ") LCD_STR_C; + PROGMEM Language_Str MSG_AMAX_E = _UxGT("Приск.макс ") LCD_STR_E; + PROGMEM Language_Str MSG_AMAX_EN = _UxGT("Приск.макс *"); + PROGMEM Language_Str MSG_A_RETRACT = _UxGT("Приск.втягув."); + PROGMEM Language_Str MSG_A_TRAVEL = _UxGT("Приск.переміщ."); + PROGMEM Language_Str MSG_XY_FREQUENCY_LIMIT = _UxGT("Частота макс."); + PROGMEM Language_Str MSG_XY_FREQUENCY_FEEDRATE = _UxGT("Подача мін."); + PROGMEM Language_Str MSG_STEPS_PER_MM = _UxGT("Кроків на мм"); + PROGMEM Language_Str MSG_A_STEPS = LCD_STR_A _UxGT(" кроків/мм"); + PROGMEM Language_Str MSG_B_STEPS = LCD_STR_B _UxGT(" кроків/мм"); + PROGMEM Language_Str MSG_C_STEPS = LCD_STR_C _UxGT(" кроків/мм"); + PROGMEM Language_Str MSG_E_STEPS = _UxGT("E кроків/мм"); + PROGMEM Language_Str MSG_EN_STEPS = _UxGT("* кроків/мм"); PROGMEM Language_Str MSG_TEMPERATURE = _UxGT("Температура"); PROGMEM Language_Str MSG_MOTION = _UxGT("Рух"); - PROGMEM Language_Str MSG_FILAMENT = _UxGT("Волокно"); + PROGMEM Language_Str MSG_FILAMENT = _UxGT("Пруток"); PROGMEM Language_Str MSG_VOLUMETRIC_ENABLED = _UxGT("E в мм³"); - PROGMEM Language_Str MSG_FILAMENT_DIAM = _UxGT("Діам. волок."); - PROGMEM Language_Str MSG_FILAMENT_DIAM_E = _UxGT("Діам. волок. *"); - PROGMEM Language_Str MSG_CONTRAST = _UxGT("контраст LCD"); - PROGMEM Language_Str MSG_STORE_EEPROM = _UxGT("Зберегти в ПЗП"); - PROGMEM Language_Str MSG_LOAD_EEPROM = _UxGT("Зчитати з ПЗП"); - PROGMEM Language_Str MSG_RESTORE_DEFAULTS = _UxGT("Відновити базові"); - PROGMEM Language_Str MSG_REFRESH = LCD_STR_REFRESH _UxGT("Поновити"); - PROGMEM Language_Str MSG_INFO_SCREEN = _UxGT("Інформація"); + PROGMEM Language_Str MSG_VOLUMETRIC_LIMIT = _UxGT("E обмеж.,мм³"); + PROGMEM Language_Str MSG_VOLUMETRIC_LIMIT_E = _UxGT("E обмеж. *"); + PROGMEM Language_Str MSG_FILAMENT_DIAM = _UxGT("Діам. прутка"); + PROGMEM Language_Str MSG_FILAMENT_DIAM_E = _UxGT("Діам. прутка *"); + PROGMEM Language_Str MSG_FILAMENT_UNLOAD = _UxGT("Вивантаж., мм"); + PROGMEM Language_Str MSG_FILAMENT_LOAD = _UxGT("Завантаж., мм"); + PROGMEM Language_Str MSG_ADVANCE_K = _UxGT("Kоеф. просув."); + PROGMEM Language_Str MSG_ADVANCE_K_E = _UxGT("Kоеф. просув. *"); + PROGMEM Language_Str MSG_CONTRAST = _UxGT("Контраст екрану"); + PROGMEM Language_Str MSG_STORE_EEPROM = _UxGT("Зберегти в EEPROM"); + PROGMEM Language_Str MSG_LOAD_EEPROM = _UxGT("Зчитати з EEPROM"); + PROGMEM Language_Str MSG_RESTORE_DEFAULTS = _UxGT("На базові параметри"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_INIT_EEPROM = _UxGT("Ініціалізація EEPROM"); + #else + PROGMEM Language_Str MSG_INIT_EEPROM = _UxGT("Ініціаліз. EEPROM"); + #endif + PROGMEM Language_Str MSG_ERR_EEPROM_CRC = _UxGT("Збій EEPROM: CRC"); + PROGMEM Language_Str MSG_ERR_EEPROM_INDEX = _UxGT("Збій EEPROM: індекс"); + PROGMEM Language_Str MSG_ERR_EEPROM_VERSION = _UxGT("Збій EEPROM: версія"); + PROGMEM Language_Str MSG_SETTINGS_STORED = _UxGT("Параметри збережені"); + PROGMEM Language_Str MSG_MEDIA_UPDATE = _UxGT("Оновити SD-картку"); + PROGMEM Language_Str MSG_RESET_PRINTER = _UxGT("Зкинути принтер"); + PROGMEM Language_Str MSG_REFRESH = LCD_STR_REFRESH _UxGT(" Поновити"); + PROGMEM Language_Str MSG_INFO_SCREEN = _UxGT("Головний екран"); PROGMEM Language_Str MSG_PREPARE = _UxGT("Підготувати"); PROGMEM Language_Str MSG_TUNE = _UxGT("Підлаштування"); + PROGMEM Language_Str MSG_POWER_MONITOR = _UxGT("Монітор живлення"); + PROGMEM Language_Str MSG_CURRENT = _UxGT("Струм"); + PROGMEM Language_Str MSG_VOLTAGE = _UxGT("Напруга"); + PROGMEM Language_Str MSG_POWER = _UxGT("Потужність"); + PROGMEM Language_Str MSG_START_PRINT = _UxGT("Почати друк"); + + PROGMEM Language_Str MSG_BUTTON_NEXT = _UxGT("Далі"); //short text for buttons + PROGMEM Language_Str MSG_BUTTON_INIT = _UxGT("Ініц-я"); + PROGMEM Language_Str MSG_BUTTON_STOP = _UxGT("Зупинка"); + PROGMEM Language_Str MSG_BUTTON_PRINT = _UxGT("Друк"); + PROGMEM Language_Str MSG_BUTTON_RESET = _UxGT("Зкинути"); + PROGMEM Language_Str MSG_BUTTON_IGNORE = _UxGT("Ігнорув."); + PROGMEM Language_Str MSG_BUTTON_CANCEL = _UxGT("Відміна"); + PROGMEM Language_Str MSG_BUTTON_DONE = _UxGT("Готово"); + PROGMEM Language_Str MSG_BUTTON_BACK = _UxGT("Назад"); + PROGMEM Language_Str MSG_BUTTON_PROCEED = _UxGT("Продовжити"); + + PROGMEM Language_Str MSG_PAUSING = _UxGT("Призупинення..."); PROGMEM Language_Str MSG_PAUSE_PRINT = _UxGT("Призупинити друк"); PROGMEM Language_Str MSG_RESUME_PRINT = _UxGT("Відновити друк"); PROGMEM Language_Str MSG_STOP_PRINT = _UxGT("Скасувати друк"); + PROGMEM Language_Str MSG_PRINTING_OBJECT = _UxGT("Друк об'єкта"); + PROGMEM Language_Str MSG_CANCEL_OBJECT = _UxGT("Завершити об'єкт"); + PROGMEM Language_Str MSG_CANCEL_OBJECT_N = _UxGT("Завершити об'єкт ="); + PROGMEM Language_Str MSG_OUTAGE_RECOVERY = _UxGT("Віднов. після збою"); PROGMEM Language_Str MSG_MEDIA_MENU = _UxGT("Друкувати з SD"); - PROGMEM Language_Str MSG_NO_MEDIA = _UxGT("Відсутня SD карт."); + PROGMEM Language_Str MSG_NO_MEDIA = _UxGT("SD-картки немає"); PROGMEM Language_Str MSG_DWELL = _UxGT("Сплячка..."); - PROGMEM Language_Str MSG_USERWAIT = _UxGT("Очікування дій..."); + PROGMEM Language_Str MSG_USERWAIT = _UxGT("Продовжити..."); + PROGMEM Language_Str MSG_PRINT_PAUSED = _UxGT("Друк призупинено"); + PROGMEM Language_Str MSG_PRINTING = _UxGT("Друк..."); PROGMEM Language_Str MSG_PRINT_ABORTED = _UxGT("Друк скасовано"); + PROGMEM Language_Str MSG_PRINT_DONE = _UxGT("Друк завершено"); PROGMEM Language_Str MSG_NO_MOVE = _UxGT("Немає руху."); PROGMEM Language_Str MSG_KILLED = _UxGT("ПЕРЕРВАНО. "); PROGMEM Language_Str MSG_STOPPED = _UxGT("ЗУПИНЕНО. "); - PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("Зміна волокна"); - PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Зміна волокна *"); - PROGMEM Language_Str MSG_ATTACH_MEDIA = _UxGT("Старт SD картки"); - PROGMEM Language_Str MSG_CHANGE_MEDIA = _UxGT("Заміна SD карти"); - PROGMEM Language_Str MSG_ZPROBE_OUT = _UxGT("Z дет. не в межах"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_CONTROL_RETRACT = _UxGT("Втягування, мм"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("Зміна втягув.,мм"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("Повернення, мм"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("Поверн.зміни, мм"); + PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("Автовтягування"); + #else + PROGMEM Language_Str MSG_CONTROL_RETRACT = _UxGT("Втягув., мм"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("Зміна втяг.мм"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("Поверн., мм"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("Повер.зміни,мм"); + PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("Автовтягув."); + #endif + PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("Втягування V"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_ZHOP = _UxGT("Підскок, мм"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("Повернення V"); + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAPF = _UxGT("Поверн.зміни V"); + PROGMEM Language_Str MSG_FILAMENT_SWAP_LENGTH = _UxGT("Поміняти довжини"); + PROGMEM Language_Str MSG_FILAMENT_SWAP_EXTRA = _UxGT("Поміняти додатково"); + PROGMEM Language_Str MSG_FILAMENT_PURGE_LENGTH = _UxGT("Очистити довжину"); + PROGMEM Language_Str MSG_TOOL_CHANGE = _UxGT("Зміна сопла"); + PROGMEM Language_Str MSG_TOOL_CHANGE_ZLIFT = _UxGT("Підняти по Z"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPEED = _UxGT("Початк.швидкість"); + PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPEED = _UxGT("Швидкість втягув."); + #else + PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPEED = _UxGT("Початк.швидк."); + PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPEED = _UxGT("Швидк.втягув."); + #endif + PROGMEM Language_Str MSG_FILAMENT_PARK_ENABLED = _UxGT("Паркувати голову"); + PROGMEM Language_Str MSG_SINGLENOZZLE_UNRETRACT_SPEED = _UxGT("Відновити швидкість"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_SPEED = _UxGT("Оберти охолодження"); + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_TIME = _UxGT("Час охолодження"); + #else + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_SPEED = _UxGT("Оберти охолодж."); + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_TIME = _UxGT("Час охолодж."); + #endif + PROGMEM Language_Str MSG_TOOL_MIGRATION_ON = _UxGT("Авто Увімк."); + PROGMEM Language_Str MSG_TOOL_MIGRATION_OFF = _UxGT("Авто Вимкн."); + PROGMEM Language_Str MSG_TOOL_MIGRATION = _UxGT("Заміна інструменту"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_AUTO = _UxGT("Авто заміна"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_END = _UxGT("Останній екструдер"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_SWAP = _UxGT("Заміна на *"); + PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("Заміна прутка"); + PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Заміна прутка *"); + PROGMEM Language_Str MSG_FILAMENTLOAD = _UxGT("Подати пруток"); + PROGMEM Language_Str MSG_FILAMENTLOAD_E = _UxGT("Подати пруток *"); + PROGMEM Language_Str MSG_FILAMENTUNLOAD = _UxGT("Видалити пруток"); + PROGMEM Language_Str MSG_FILAMENTUNLOAD_E = _UxGT("Видалити пруток *"); + PROGMEM Language_Str MSG_FILAMENTUNLOAD_ALL = _UxGT("Видалити все"); + PROGMEM Language_Str MSG_ATTACH_MEDIA = _UxGT("Вставити SD-картку"); + PROGMEM Language_Str MSG_CHANGE_MEDIA = _UxGT("Заміна SD-картки"); + PROGMEM Language_Str MSG_RELEASE_MEDIA = _UxGT("Звільніть SD-картку"); + PROGMEM Language_Str MSG_ZPROBE_OUT = _UxGT("Z-Зонд поза столом"); + PROGMEM Language_Str MSG_SKEW_FACTOR = _UxGT("Фактор нахилу"); + PROGMEM Language_Str MSG_BLTOUCH = _UxGT("Z-зонд BLTouch"); PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("BLTouch Само-Тест"); - PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("Скинути BLTouch"); + PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("Зкинути BLTouch"); + PROGMEM Language_Str MSG_BLTOUCH_STOW = _UxGT("Підняти зонд"); + PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("Опустити зонд"); + PROGMEM Language_Str MSG_BLTOUCH_SW_MODE = _UxGT("Режим SW"); + PROGMEM Language_Str MSG_BLTOUCH_5V_MODE = _UxGT("Режим 5V"); + PROGMEM Language_Str MSG_BLTOUCH_OD_MODE = _UxGT("Режим OD"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE = _UxGT("Режим збереження"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_5V = _UxGT("Встановити на 5V"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_OD = _UxGT("Встановити на OD"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_ECHO = _UxGT("Злив звіту"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_CHANGE = _UxGT("НЕБЕЗПЕКА: Неправильні параметри приводять до пошкоджень! Продовжувати?"); + PROGMEM Language_Str MSG_TOUCHMI_PROBE = _UxGT("Z-Зонд TouchMI"); + PROGMEM Language_Str MSG_TOUCHMI_INIT = _UxGT("Ініціалізація"); + PROGMEM Language_Str MSG_TOUCHMI_ZTEST = _UxGT("Тест Z-зміщення"); + PROGMEM Language_Str MSG_TOUCHMI_SAVE = _UxGT("Зберегти"); + PROGMEM Language_Str MSG_MANUAL_DEPLOY_TOUCHMI = _UxGT("Установити TouchMI"); + PROGMEM Language_Str MSG_MANUAL_DEPLOY = _UxGT("Установити зонд"); + PROGMEM Language_Str MSG_MANUAL_STOW = _UxGT("Завантажити зонд"); PROGMEM Language_Str MSG_HOME_FIRST = _UxGT("Дім %s%s%s перший"); - PROGMEM Language_Str MSG_ZPROBE_ZOFFSET = _UxGT("Зміщення Z"); + PROGMEM Language_Str MSG_ZPROBE_OFFSETS = _UxGT("Зміщення зонду"); + PROGMEM Language_Str MSG_ZPROBE_XOFFSET = _UxGT("Тест зміщення X"); + PROGMEM Language_Str MSG_ZPROBE_YOFFSET = _UxGT("Тест зміщення Y"); + PROGMEM Language_Str MSG_ZPROBE_ZOFFSET = _UxGT("Тест зміщення Z"); PROGMEM Language_Str MSG_BABYSTEP_X = _UxGT("Мікрокрок X"); PROGMEM Language_Str MSG_BABYSTEP_Y = _UxGT("Мікрокрок Y"); PROGMEM Language_Str MSG_BABYSTEP_Z = _UxGT("Мікрокрок Z"); - PROGMEM Language_Str MSG_ENDSTOP_ABORT = _UxGT("невдача кінцевика"); - PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("Невдалий нагрів"); - PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("ЗБІЙ ТЕМПЕРАТУРИ"); - PROGMEM Language_Str MSG_ERR_Z_HOMING = _UxGT("Дім XY перший"); + PROGMEM Language_Str MSG_BABYSTEP_TOTAL = _UxGT("Сумарно"); + PROGMEM Language_Str MSG_ENDSTOP_ABORT = _UxGT("Кінцевик спрацював"); + PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("Збій нагріву"); + PROGMEM Language_Str MSG_ERR_REDUNDANT_TEMP = _UxGT("ЗАВИЩЕНА Т") LCD_STR_DEGREE; + PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("ВИТІК ТЕПЛА"); + PROGMEM Language_Str MSG_THERMAL_RUNAWAY_BED = _UxGT("ВИТІК ТЕПЛА СТОЛУ"); + PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER = _UxGT("ВИТІК ТЕПЛА КАМЕРИ"); + PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("ПЕРЕГРІВ"); + PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("МІНІМАЛЬНА Т") LCD_STR_DEGREE; PROGMEM Language_Str MSG_HALTED = _UxGT("ПРИНТЕР ЗУПИНЕНО"); PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("Перезавантажте"); PROGMEM Language_Str MSG_SHORT_DAY = _UxGT("д"); // One character only PROGMEM Language_Str MSG_SHORT_HOUR = _UxGT("г"); // One character only PROGMEM Language_Str MSG_SHORT_MINUTE = _UxGT("х"); // One character only PROGMEM Language_Str MSG_HEATING = _UxGT("Нагрівання..."); - PROGMEM Language_Str MSG_BED_HEATING = _UxGT("Нагрівання столу..."); - PROGMEM Language_Str MSG_DELTA_CALIBRATE = _UxGT("Калібр. Delta"); - PROGMEM Language_Str MSG_DELTA_CALIBRATE_X = _UxGT("Калібрування X"); - PROGMEM Language_Str MSG_DELTA_CALIBRATE_Y = _UxGT("Калібрування Y"); - PROGMEM Language_Str MSG_DELTA_CALIBRATE_Z = _UxGT("Калібрування Z"); - PROGMEM Language_Str MSG_DELTA_CALIBRATE_CENTER = _UxGT("Калібр. Центру"); + PROGMEM Language_Str MSG_COOLING = _UxGT("Охолодження..."); + PROGMEM Language_Str MSG_BED_HEATING = _UxGT("Нагрів столу..."); + PROGMEM Language_Str MSG_CHAMBER_HEATING = _UxGT("Нагрів камери..."); + #if LCD_WIDTH >= 20 + PROGMEM Language_Str MSG_BED_COOLING = _UxGT("Охолодження столу..."); + PROGMEM Language_Str MSG_CHAMBER_COOLING = _UxGT("Охолодження камери..."); + PROGMEM Language_Str MSG_DELTA_CALIBRATE = _UxGT("Калібрування Delta"); + #else + PROGMEM Language_Str MSG_BED_COOLING = _UxGT("Охол. столу..."); + PROGMEM Language_Str MSG_CHAMBER_COOLING = _UxGT("Охол. камери..."); + PROGMEM Language_Str MSG_DELTA_CALIBRATE = _UxGT("Калібрув. Delta"); + #endif + PROGMEM Language_Str MSG_DELTA_CALIBRATE_X = _UxGT("Калібрувати X"); + PROGMEM Language_Str MSG_DELTA_CALIBRATE_Y = _UxGT("Калібрувати Y"); + PROGMEM Language_Str MSG_DELTA_CALIBRATE_Z = _UxGT("Калібрувати Z"); + PROGMEM Language_Str MSG_DELTA_CALIBRATE_CENTER = _UxGT("Калібр. центр"); + PROGMEM Language_Str MSG_DELTA_SETTINGS = _UxGT("Параметри Delta"); + PROGMEM Language_Str MSG_DELTA_AUTO_CALIBRATE = _UxGT("Автокалібрування"); + PROGMEM Language_Str MSG_DELTA_HEIGHT_CALIBRATE = _UxGT("Висота Delta"); + #if LCD_WIDTH >= 20 + PROGMEM Language_Str MSG_DELTA_Z_OFFSET_CALIBRATE = _UxGT("Зондування Z-зміщ."); + PROGMEM Language_Str MSG_DELTA_DIAG_ROD = _UxGT("Стрижень діагоналі"); + #else + PROGMEM Language_Str MSG_DELTA_Z_OFFSET_CALIBRATE = _UxGT("Зондув. Z-зміщ."); + PROGMEM Language_Str MSG_DELTA_DIAG_ROD = _UxGT("Стрижень діаг."); + #endif + PROGMEM Language_Str MSG_DELTA_HEIGHT = _UxGT("Висота"); + PROGMEM Language_Str MSG_DELTA_RADIUS = _UxGT("Радіус"); PROGMEM Language_Str MSG_INFO_MENU = _UxGT("Про принтер"); - PROGMEM Language_Str MSG_INFO_PRINTER_MENU = _UxGT("Інформація"); - PROGMEM Language_Str MSG_INFO_STATS_MENU = _UxGT("Статистика"); + PROGMEM Language_Str MSG_INFO_PRINTER_MENU = _UxGT("Данні принтера"); + + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_3POINT_LEVELING = _UxGT("3-точкове вирівнювання"); + PROGMEM Language_Str MSG_LINEAR_LEVELING = _UxGT("Лінійне вирівнювання"); + PROGMEM Language_Str MSG_BILINEAR_LEVELING = _UxGT("Білінійне вирівнювання"); + #elif LCD_WIDTH == 20 + PROGMEM Language_Str MSG_3POINT_LEVELING = _UxGT("3-точкове вирівнюв."); + PROGMEM Language_Str MSG_LINEAR_LEVELING = _UxGT("Лінійне вирівнюван."); + PROGMEM Language_Str MSG_BILINEAR_LEVELING = _UxGT("Білінійне вирівнюв."); + #else + PROGMEM Language_Str MSG_3POINT_LEVELING = _UxGT("3-точк. вирівн."); + PROGMEM Language_Str MSG_LINEAR_LEVELING = _UxGT("Лінійне вирівн."); + PROGMEM Language_Str MSG_BILINEAR_LEVELING = _UxGT("Білін. вирівнюв."); + #endif + PROGMEM Language_Str MSG_UBL_LEVELING = _UxGT("Керування UBL"); + PROGMEM Language_Str MSG_MESH_LEVELING = _UxGT("Вирівнювання сітки"); + + PROGMEM Language_Str MSG_INFO_STATS_MENU = _UxGT("Статистика принтера"); PROGMEM Language_Str MSG_INFO_BOARD_MENU = _UxGT("Про плату"); PROGMEM Language_Str MSG_INFO_THERMISTOR_MENU = _UxGT("Термістори"); PROGMEM Language_Str MSG_INFO_EXTRUDERS = _UxGT("Екструдери"); - PROGMEM Language_Str MSG_INFO_BAUDRATE = _UxGT("біт/с"); + PROGMEM Language_Str MSG_INFO_BAUDRATE = _UxGT("Біт/секунду"); PROGMEM Language_Str MSG_INFO_PROTOCOL = _UxGT("Протокол"); - PROGMEM Language_Str MSG_CASE_LIGHT = _UxGT("Підсвітка"); - - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("Неправильний принтер"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_INFO_RUNAWAY_OFF = _UxGT("Контроль витіку ") LCD_STR_THERMOMETER _UxGT(" Вимк"); + PROGMEM Language_Str MSG_INFO_RUNAWAY_ON = _UxGT("Контроль витіку ") LCD_STR_THERMOMETER _UxGT(" Увімк"); + PROGMEM Language_Str MSG_HOTEND_IDLE_TIMEOUT = _UxGT("Час простою хотенду"); + #else + PROGMEM Language_Str MSG_INFO_RUNAWAY_OFF = _UxGT("Контр.витіку ") LCD_STR_THERMOMETER _UxGT(" Вимк"); + PROGMEM Language_Str MSG_INFO_RUNAWAY_ON = _UxGT("Контр.витіку ") LCD_STR_THERMOMETER _UxGT(" Увімк"); + PROGMEM Language_Str MSG_HOTEND_IDLE_TIMEOUT = _UxGT("Час прост. хот-у"); + #endif + PROGMEM Language_Str MSG_CASE_LIGHT = _UxGT("Підсвітка"); + PROGMEM Language_Str MSG_CASE_LIGHT_BRIGHTNESS = _UxGT("Яскравість світла"); + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("НЕ ТОЙ ПРИНТЕР"); + PROGMEM Language_Str MSG_INFO_COMPLETED_PRINTS = _UxGT("Завершено"); + PROGMEM Language_Str MSG_INFO_PRINT_FILAMENT = _UxGT("Екструдовано"); #if LCD_WIDTH >= 20 - PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("К-сть друків"); - PROGMEM Language_Str MSG_INFO_COMPLETED_PRINTS = _UxGT("Завершено"); + PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Кількість друків"); PROGMEM Language_Str MSG_INFO_PRINT_TIME = _UxGT("Весь час друку"); PROGMEM Language_Str MSG_INFO_PRINT_LONGEST = _UxGT("Найдовший час"); - PROGMEM Language_Str MSG_INFO_PRINT_FILAMENT = _UxGT("Екструдовано"); #else PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Друків"); - PROGMEM Language_Str MSG_INFO_COMPLETED_PRINTS = _UxGT("Завершено"); PROGMEM Language_Str MSG_INFO_PRINT_TIME = _UxGT("Загалом"); - PROGMEM Language_Str MSG_INFO_PRINT_LONGEST = _UxGT("Найдовший"); - PROGMEM Language_Str MSG_INFO_PRINT_FILAMENT = _UxGT("Ексдруд."); + PROGMEM Language_Str MSG_INFO_PRINT_LONGEST = _UxGT("Найдовше"); #endif - PROGMEM Language_Str MSG_INFO_MIN_TEMP = _UxGT("Мін Темп."); - PROGMEM Language_Str MSG_INFO_MAX_TEMP = _UxGT("Макс Темп."); - PROGMEM Language_Str MSG_INFO_PSU = _UxGT("Джерело жив."); - + PROGMEM Language_Str MSG_INFO_MIN_TEMP = _UxGT("Мін. ") LCD_STR_THERMOMETER; + PROGMEM Language_Str MSG_INFO_MAX_TEMP = _UxGT("Макс. ") LCD_STR_THERMOMETER; + PROGMEM Language_Str MSG_INFO_PSU = _UxGT("Блок жив-ня"); PROGMEM Language_Str MSG_DRIVE_STRENGTH = _UxGT("Сила мотору"); - PROGMEM Language_Str MSG_DAC_PERCENT_X = _UxGT("X % мотору"); - PROGMEM Language_Str MSG_DAC_PERCENT_Y = _UxGT("Y % мотору"); - PROGMEM Language_Str MSG_DAC_PERCENT_Z = _UxGT("Z % мотору"); - PROGMEM Language_Str MSG_DAC_PERCENT_E = _UxGT("E % мотору"); - PROGMEM Language_Str MSG_DAC_EEPROM_WRITE = _UxGT("Запис ЦАП на ПЗП"); - + PROGMEM Language_Str MSG_DAC_PERCENT_X = _UxGT("Драйвер X, %"); + PROGMEM Language_Str MSG_DAC_PERCENT_Y = _UxGT("Драйвер Y, %"); + PROGMEM Language_Str MSG_DAC_PERCENT_Z = _UxGT("Драйвер Z, %"); + PROGMEM Language_Str MSG_DAC_PERCENT_E = _UxGT("Драйвер E, %"); + PROGMEM Language_Str MSG_ERROR_TMC = _UxGT("ЗБІЙ ЗВ'ЯЗКУ З TMC"); + PROGMEM Language_Str MSG_DAC_EEPROM_WRITE = _UxGT("Запис ЦАП у EEPROM"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER = _UxGT("ЗАМІНА ПРУТКА"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_PAUSE = _UxGT("ЗУПИНКА ДРУКУ"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_LOAD = _UxGT("ЗАВАНТАЖИТИ ПРУТОК"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_UNLOAD = _UxGT("ВИВАНТАЖИТИ ПРУТОК"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_HEADER = _UxGT("ПАРАМЕТРИ ПРОДОВЖЕННЯ:"); + #else + PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_HEADER = _UxGT("ПАРАМ.ПРОДОВЖЕННЯ:"); + #endif + PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_PURGE = _UxGT("Видавити ще"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_RESUME = _UxGT("Відновити друк"); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" Сопло: "); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_RUNOUT_SENSOR = _UxGT("Датчик закінчення прутка"); + PROGMEM Language_Str MSG_RUNOUT_DISTANCE_MM = _UxGT("Відстань закінч.,мм"); + #else + PROGMEM Language_Str MSG_RUNOUT_SENSOR = _UxGT("Датчик закінч.прутка"); + PROGMEM Language_Str MSG_RUNOUT_DISTANCE_MM = _UxGT("До закінч.,мм"); + #endif + PROGMEM Language_Str MSG_KILL_HOMING_FAILED = _UxGT("Помилка паркування"); + PROGMEM Language_Str MSG_LCD_PROBING_FAILED = _UxGT("Помилка зондування"); + PROGMEM Language_Str MSG_MMU2_CHOOSE_FILAMENT_HEADER = _UxGT("ОБЕРІТЬ ПРУТОК"); + PROGMEM Language_Str MSG_MMU2_MENU = _UxGT("Налаштування MMU"); + PROGMEM Language_Str MSG_KILL_MMU2_FIRMWARE = _UxGT("Понови прошивку MMU!"); + PROGMEM Language_Str MSG_MMU2_NOT_RESPONDING = _UxGT("MMU потребує уваги"); + PROGMEM Language_Str MSG_MMU2_RESUME = _UxGT("Продовжити друк"); + PROGMEM Language_Str MSG_MMU2_RESUMING = _UxGT("Продовження..."); + PROGMEM Language_Str MSG_MMU2_LOAD_FILAMENT = _UxGT("Завантажити пруток"); + PROGMEM Language_Str MSG_MMU2_LOAD_ALL = _UxGT("Завантажити все"); + PROGMEM Language_Str MSG_MMU2_LOAD_TO_NOZZLE = _UxGT("Завантажити в сопло"); + PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT = _UxGT("Звільнити пруток"); + PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT_N = _UxGT("Звільнити пруток ~"); + PROGMEM Language_Str MSG_MMU2_UNLOAD_FILAMENT = _UxGT("Вивантажити пруток"); + PROGMEM Language_Str MSG_MMU2_LOADING_FILAMENT = _UxGT("Завантаження %i..."); + PROGMEM Language_Str MSG_MMU2_EJECTING_FILAMENT = _UxGT("Звільнення прутка..."); + PROGMEM Language_Str MSG_MMU2_UNLOADING_FILAMENT = _UxGT("Вивантаження ...."); + PROGMEM Language_Str MSG_MMU2_ALL = _UxGT("Все"); + PROGMEM Language_Str MSG_MMU2_FILAMENT_N = _UxGT("Пруток ~"); + PROGMEM Language_Str MSG_MMU2_RESET = _UxGT("Перезапуск MMU"); + PROGMEM Language_Str MSG_MMU2_RESETTING = _UxGT("Перезапуск MMU..."); + PROGMEM Language_Str MSG_MMU2_EJECT_RECOVER = _UxGT("Видаліть, натисніть"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_MIX = _UxGT("Змішування"); + #else + PROGMEM Language_Str MSG_MIX = _UxGT("Змішув."); + #endif + PROGMEM Language_Str MSG_MIX_COMPONENT_N = _UxGT("Компонент ="); + PROGMEM Language_Str MSG_MIXER = _UxGT("Змішувач"); + PROGMEM Language_Str MSG_GRADIENT = _UxGT("Градієнт"); + PROGMEM Language_Str MSG_FULL_GRADIENT = _UxGT("Повний градієнт"); + PROGMEM Language_Str MSG_CYCLE_MIX = _UxGT("Циклічне змішування"); + PROGMEM Language_Str MSG_GRADIENT_MIX = _UxGT("Градієнт змішування"); + PROGMEM Language_Str MSG_REVERSE_GRADIENT = _UxGT("Змінити градієнт"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_TOGGLE_MIX = _UxGT("Перемкнути змішування"); + PROGMEM Language_Str MSG_ACTIVE_VTOOL = _UxGT("Активація В-інструменту"); + PROGMEM Language_Str MSG_START_VTOOL = _UxGT("Початок В-інструменту"); + PROGMEM Language_Str MSG_END_VTOOL = _UxGT("Кінець В-інструменту"); + PROGMEM Language_Str MSG_GRADIENT_ALIAS = _UxGT("Псевдонім В-інструменту"); + PROGMEM Language_Str MSG_RESET_VTOOLS = _UxGT("Зкидання В-інструментів"); + PROGMEM Language_Str MSG_VTOOLS_RESET = _UxGT("В-інструменти зкинуті"); + PROGMEM Language_Str MSG_COMMIT_VTOOL = _UxGT("Змішати В-інструменти"); + #else + PROGMEM Language_Str MSG_TOGGLE_MIX = _UxGT("Перемкнути змішув."); + PROGMEM Language_Str MSG_ACTIVE_VTOOL = _UxGT("Актив.В-інструм."); + PROGMEM Language_Str MSG_START_VTOOL = _UxGT("В-інструм. поч."); + PROGMEM Language_Str MSG_END_VTOOL = _UxGT("В-інструм. кін."); + PROGMEM Language_Str MSG_GRADIENT_ALIAS = _UxGT("Псевдонім В-інстр."); + PROGMEM Language_Str MSG_RESET_VTOOLS = _UxGT("Зкидання В-інструм"); + PROGMEM Language_Str MSG_VTOOLS_RESET = _UxGT("В-інструм. зкинуті"); + PROGMEM Language_Str MSG_COMMIT_VTOOL = _UxGT("Змішати В-інструм."); + #endif + PROGMEM Language_Str MSG_START_Z = _UxGT("Початок Z"); + PROGMEM Language_Str MSG_END_Z = _UxGT(" Кінець Z"); + + PROGMEM Language_Str MSG_GAMES = _UxGT("Ігри"); + PROGMEM Language_Str MSG_BRICKOUT = _UxGT("Цеглини"); + PROGMEM Language_Str MSG_INVADERS = _UxGT("Вторгнення"); + PROGMEM Language_Str MSG_SNAKE = _UxGT("Змійка"); + PROGMEM Language_Str MSG_MAZE = _UxGT("Лабіринт"); + + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_BAD_PAGE = _UxGT("Поганий індекс сторінки"); + PROGMEM Language_Str MSG_BAD_PAGE_SPEED = _UxGT("Погана швидкість сторінки"); + #else + PROGMEM Language_Str MSG_BAD_PAGE = _UxGT("Погана сторінка"); + PROGMEM Language_Str MSG_BAD_PAGE_SPEED = _UxGT("Погана швидк.стор"); + #endif + + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Паркування...")); #if LCD_HEIGHT >= 4 // Up to 3 lines allowed - PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_3_LINE("Зачекайте на", "початок заміни", "волокна")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_2_LINE("Зачекайте на", "вивід волокна")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_3_LINE("Вставте волокно", "та натисніть для", "продовження...")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_2_LINE("Зачекайте на", "ввід волокна")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_3_LINE("Зачекайте на", "відновлення", "друку")); + PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_3_LINE("Натисніть кнопку", "для продовження", "друку")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_3_LINE("Зачекайте", "на початок", "заміни прутка")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_3_LINE("Вставте пруток", "та натисніть", "для продовження...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_2_LINE("Натисніть кнопку", "для нагріву сопла")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEATING = _UxGT(MSG_2_LINE("Сопло нагрівається", "зачекайте...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_2_LINE("Зачекайте", "на вивід прутка")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_2_LINE("Зачекайте", "на ввід прутка")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_PURGE = _UxGT(MSG_2_LINE("Дочекайтесь", "очищення прутка")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_CONT_PURGE = _UxGT(MSG_3_LINE("Натисніть кнопку", "для завершення", "очищення прутка")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_3_LINE("Зачекайте", "на відновлення", "друку")); #else // Up to 2 lines allowed + PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_1_LINE("Продовжити друк")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_1_LINE("Зачекайте...")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_1_LINE("Вивід...")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_1_LINE("Вставте і нат.")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_1_LINE("Ввід...")); - PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_1_LINE("Відновлення...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_1_LINE("Вставте і натисніть")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_1_LINE("Нагріти сопло")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEATING = _UxGT(MSG_1_LINE("Нагрів сопла...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_1_LINE("Вивід прутка...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_1_LINE("Ввід прутка...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_PURGE = _UxGT(MSG_1_LINE("Очищення прутка...")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_CONT_PURGE = _UxGT(MSG_1_LINE("Завершити очищення")); + PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_1_LINE("Поновлення друку...")); #endif + + PROGMEM Language_Str MSG_TMC_DRIVERS = _UxGT("Драйвери TMC"); + PROGMEM Language_Str MSG_TMC_CURRENT = _UxGT("Струм драйвера"); + PROGMEM Language_Str MSG_TMC_HYBRID_THRS = _UxGT("Гібридний поріг"); + PROGMEM Language_Str MSG_TMC_HOMING_THRS = _UxGT("Дім без кінцевиків"); + PROGMEM Language_Str MSG_TMC_STEPPING_MODE = _UxGT("Режим мікрокроку"); + PROGMEM Language_Str MSG_TMC_STEALTH_ENABLED = _UxGT("Тихий режим увімк."); + PROGMEM Language_Str MSG_SERVICE_RESET = _UxGT("Зкидання"); + PROGMEM Language_Str MSG_SERVICE_IN = _UxGT(" в:"); + PROGMEM Language_Str MSG_BACKLASH = _UxGT("Люфт"); + PROGMEM Language_Str MSG_BACKLASH_CORRECTION = _UxGT("Виправлення"); + PROGMEM Language_Str MSG_BACKLASH_SMOOTHING = _UxGT("Зглажування"); + + PROGMEM Language_Str MSG_LEVEL_X_AXIS = _UxGT("Рівень вісі X"); + PROGMEM Language_Str MSG_AUTO_CALIBRATE = _UxGT("Авто калібрування"); + PROGMEM Language_Str MSG_HEATER_TIMEOUT = _UxGT("Час нагрівача збіг"); + PROGMEM Language_Str MSG_REHEAT = _UxGT("Поновити нагрів"); + PROGMEM Language_Str MSG_REHEATING = _UxGT("Нагрівання..."); } + +#if FAN_COUNT == 1 + #define MSG_FIRST_FAN_SPEED MSG_FAN_SPEED + #define MSG_EXTRA_FIRST_FAN_SPEED MSG_EXTRA_FAN_SPEED +#else + #define MSG_FIRST_FAN_SPEED MSG_FAN_SPEED_N + #define MSG_EXTRA_FIRST_FAN_SPEED MSG_EXTRA_FAN_SPEED_N +#endif diff --git a/Marlin/src/lcd/language/language_vi.h b/Marlin/src/lcd/language/language_vi.h index 330db4b6906c..f7cf60657535 100644 --- a/Marlin/src/lcd/language/language_vi.h +++ b/Marlin/src/lcd/language/language_vi.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,8 +25,7 @@ * Vietnamese * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ namespace Language_vi { using namespace Language_en; // Inherit undefined strings from English @@ -39,7 +38,6 @@ namespace Language_vi { PROGMEM Language_Str MSG_MEDIA_ABORTING = _UxGT("Đang hủy bỏ..."); PROGMEM Language_Str MSG_MEDIA_INSERTED = _UxGT("Phương tiện được cắm vào"); // Media inserted PROGMEM Language_Str MSG_MEDIA_REMOVED = _UxGT("Phương tiện được rút ra"); - PROGMEM Language_Str MSG_MEDIA_RELEASED = _UxGT("Phương tiện đã phát hành"); PROGMEM Language_Str MSG_MEDIA_WAITING = _UxGT("Chờ đợi phương tiện"); PROGMEM Language_Str MSG_MEDIA_READ_ERROR = _UxGT("Lỗi đọc phương tiện"); PROGMEM Language_Str MSG_MEDIA_USB_REMOVED = _UxGT("USB được rút ra"); @@ -66,20 +64,23 @@ namespace Language_vi { PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Đặt bù đắp nhà"); // Set home offsets PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Bù đắp được áp dụng"); // Offsets applied PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Đặt nguồn gốc"); // Set origin - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Làm nóng ") PREHEAT_1_LABEL _UxGT(" trước"); // Preheat - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Làm nóng ") PREHEAT_1_LABEL _UxGT(" trước ~"); // Preheat - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Làm nóng ") PREHEAT_1_LABEL _UxGT(" Đầu"); - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Làm nóng ") PREHEAT_1_LABEL _UxGT(" Đầu ~"); - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Làm nóng ") PREHEAT_1_LABEL _UxGT(" Tất cả"); // all - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Làm nóng ") PREHEAT_1_LABEL _UxGT(" Bàn"); // bed -- using vietnamese term for 'table' instead - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Làm nóng ") PREHEAT_1_LABEL _UxGT(" Cấu hình"); // conf - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("Làm nóng ") PREHEAT_2_LABEL _UxGT(" trước"); // Preheat - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("Làm nóng ") PREHEAT_2_LABEL _UxGT(" trước ~"); // Preheat - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("Làm nóng ") PREHEAT_2_LABEL _UxGT(" Đầu"); - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("Làm nóng ") PREHEAT_2_LABEL _UxGT(" Đầu ~"); - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("Làm nóng ") PREHEAT_2_LABEL _UxGT(" Tất cả"); // all - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("Làm nóng ") PREHEAT_2_LABEL _UxGT(" Bàn"); // bed -- using vietnamese term for 'table' instead - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("Làm nóng ") PREHEAT_2_LABEL _UxGT(" Cấu hình"); // conf + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Làm nóng ") PREHEAT_1_LABEL _UxGT(" trước"); // Preheat + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Làm nóng ") PREHEAT_1_LABEL _UxGT(" trước ~"); // Preheat + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("Làm nóng ") PREHEAT_1_LABEL _UxGT(" Đầu"); + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("Làm nóng ") PREHEAT_1_LABEL _UxGT(" Đầu ~"); + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("Làm nóng ") PREHEAT_1_LABEL _UxGT(" Tất cả"); // all + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("Làm nóng ") PREHEAT_1_LABEL _UxGT(" Bàn"); // bed -- using vietnamese term for 'table' instead + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("Làm nóng ") PREHEAT_1_LABEL _UxGT(" Cấu hình"); // conf + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("Làm nóng $ trước"); // Preheat + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("Làm nóng $ trước ~"); // Preheat + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("Làm nóng $ Đầu"); + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("Làm nóng $ Đầu ~"); + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("Làm nóng $ Tất cả"); // all + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("Làm nóng $ Bàn"); // bed -- using vietnamese term for 'table' instead + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("Làm nóng $ Cấu hình"); // conf + #endif PROGMEM Language_Str MSG_PREHEAT_CUSTOM = _UxGT("Sự nóng trước tự chọn"); // Preheat Custom PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Nguội xuống"); // Cooldown PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Bật nguồn"); // Switch power on @@ -125,14 +126,14 @@ namespace Language_vi { PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("Chỉnh sửa xong lưới"); // Done Editing Mesh PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("Xây dựng lưới tự chọn"); // Build Custom Mesh PROGMEM Language_Str MSG_UBL_BUILD_MESH_MENU = _UxGT("Xây dựng lưới"); // Build Mesh - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M1 = _UxGT("Xây dựng lưới (") PREHEAT_1_LABEL _UxGT(")"); - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M2 = _UxGT("Xây dựng lưới (") PREHEAT_2_LABEL _UxGT(")"); + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_UBL_BUILD_MESH_M = _UxGT("Xây dựng lưới ($)"); + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("Thẩm tra lưới ($)"); + #endif PROGMEM Language_Str MSG_UBL_BUILD_COLD_MESH = _UxGT("Xây dựng lưới lạnh"); // Build cold mesh PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_ADJUST = _UxGT("Điều chỉnh chiều cao lưới"); // Adjust Mesh Height PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_AMOUNT = _UxGT("Số lượng chiều cao"); // Height Amount PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_MENU = _UxGT("Thẩm tra lưới"); // Validate Mesh - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M1 = _UxGT("Thẩm tra lưới (") PREHEAT_1_LABEL _UxGT(")"); - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M2 = _UxGT("Thẩm tra lưới (") PREHEAT_2_LABEL _UxGT(")"); PROGMEM Language_Str MSG_UBL_VALIDATE_CUSTOM_MESH = _UxGT("Thẩm tra lưới tự chọn"); // validate custom mesh PROGMEM Language_Str MSG_UBL_CONTINUE_MESH = _UxGT("Tiếp tục xây lưới bàn"); // Continue Bed Mesh PROGMEM Language_Str MSG_UBL_MESH_LEVELING = _UxGT("Đang san lấp lưới"); // Mesh Leveling @@ -159,8 +160,8 @@ namespace Language_vi { PROGMEM Language_Str MSG_UBL_STORAGE_SLOT = _UxGT("Khe nhớ"); // Memory Slot PROGMEM Language_Str MSG_UBL_LOAD_MESH = _UxGT("Tải lưới bàn"); // Load Bed Mesh PROGMEM Language_Str MSG_UBL_SAVE_MESH = _UxGT("Lưu lưới bàn"); // Save Bed Mesh - PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("M117 %i lưới được nạp"); // Mesh %i loaded - PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("M117 %i lưới đã lưu"); + PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("%i lưới được nạp"); // Mesh %i loaded + PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("%i lưới đã lưu"); PROGMEM Language_Str MSG_NO_STORAGE = _UxGT("Không lưu trữ"); // No Storage PROGMEM Language_Str MSG_UBL_SAVE_ERROR = _UxGT("Điều sai: Lưu UBL"); // Err: UBL Save PROGMEM Language_Str MSG_UBL_RESTORE_ERROR = _UxGT("Điều Sai: Khôi Phục UBL"); // Err: UBL Restore @@ -292,16 +293,16 @@ namespace Language_vi { PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("Rút Trao.mm"); // Swap Re.mm PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("Rút V"); PROGMEM Language_Str MSG_CONTROL_RETRACT_ZHOP = _UxGT("Nhảy mm"); // hop - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("BỏRút mm"); // UnRet mm - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("BỏRút T mm"); // S UnRet mm + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("BỏRút mm"); // Unretr. mm + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("BỏRút T mm"); // S Unretr. mm PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("BỏRút V"); // UnRet V PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAPF = _UxGT("BỏRút T V"); // S UnRet V - PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("RútTựĐộng"); // AutoRetr. + PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("RútTựĐộng"); // Auto-Retract PROGMEM Language_Str MSG_FILAMENT_SWAP_LENGTH = _UxGT("Khoảng Cách Rút"); // Retract Distance PROGMEM Language_Str MSG_TOOL_CHANGE = _UxGT("Thay Đổi Công Cụ"); // Tool Change PROGMEM Language_Str MSG_TOOL_CHANGE_ZLIFT = _UxGT("Đưa Lên Z"); // Z Raise - PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPD = _UxGT("Tốc Độ Tuôn Ra"); // Prime Speed - PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPD = _UxGT("Tốc Độ Rút Lại"); // Retract Speed + PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPEED = _UxGT("Tốc Độ Tuôn Ra"); // Prime Speed + PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPEED = _UxGT("Tốc Độ Rút Lại"); // Retract Speed PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("Thay dây nhựa"); // change filament PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("Thay dây nhựa *"); // change filament PROGMEM Language_Str MSG_FILAMENTLOAD = _UxGT("Nạp dây nhựa"); // load filament @@ -328,15 +329,11 @@ namespace Language_vi { PROGMEM Language_Str MSG_BABYSTEP_Z = _UxGT("Nhít Z"); PROGMEM Language_Str MSG_ENDSTOP_ABORT = _UxGT("Hủy bỏ công tắc"); // Endstop abort PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("Sưởi đầu phun không thành công"); // Heating failed - PROGMEM Language_Str MSG_HEATING_FAILED_LCD_BED = _UxGT("Sưởi bàn không thành công"); // Bed heating failed PROGMEM Language_Str MSG_ERR_REDUNDANT_TEMP = _UxGT("Điều sai: nhiệt độ dư"); // Err: REDUNDANT TEMP PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("Vấn đề nhiệt"); // THERMAL RUNAWAY | problem PROGMEM Language_Str MSG_THERMAL_RUNAWAY_BED = _UxGT("Vấn đề nhiệt bàn"); // BED THERMAL RUNAWAY PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("Điều sai: nhiệt độ tối đa"); // Err: MAXTEMP PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("Điều sai: nhiệt độ tối thiểu"); // Err: MINTEMP - PROGMEM Language_Str MSG_ERR_MAXTEMP_BED = _UxGT("Điều sai: nhiệt độ bàn tối đa"); // Err: MAXTEMP BED - PROGMEM Language_Str MSG_ERR_MINTEMP_BED = _UxGT("Điều sai: nhiệt độ bàn tối thiểu"); // Err: MINTEMP BED - PROGMEM Language_Str MSG_ERR_Z_HOMING = _UxGT("Về nhà XY Trước"); // Home XY First PROGMEM Language_Str MSG_HALTED = _UxGT("MÁY IN Đà DỪNG LẠI"); // PRINTER HALTED PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("Xin bặt lại"); // Please reset PROGMEM Language_Str MSG_SHORT_DAY = _UxGT("n"); // d - ngày - One character only @@ -403,9 +400,8 @@ namespace Language_vi { PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_RESUME = _UxGT("Tiếp tục"); // continue PROGMEM Language_Str MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" Đầu Phun: "); // Nozzle PROGMEM Language_Str MSG_RUNOUT_SENSOR_ENABLE = _UxGT("Cảm Biến Hết"); // Runout Sensor - PROGMEM Language_Str MSG_LCD_HOMING_FAILED = _UxGT("Sự nhà không thành công"); // Homing failed + PROGMEM Language_Str MSG_KILL_HOMING_FAILED = _UxGT("Sự nhà không thành công"); // Homing failed PROGMEM Language_Str MSG_LCD_PROBING_FAILED = _UxGT(" không thành công"); // Probing failed - PROGMEM Language_Str MSG_M600_TOO_COLD = _UxGT("M600: Quá lạnh"); // // Filament Change screens show up to 3 lines on a 4-line display diff --git a/Marlin/src/lcd/language/language_zh_CN.h b/Marlin/src/lcd/language/language_zh_CN.h index 742375c7d177..3bebe12fda8d 100644 --- a/Marlin/src/lcd/language/language_zh_CN.h +++ b/Marlin/src/lcd/language/language_zh_CN.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,29 +25,41 @@ * Simplified Chinese * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ namespace Language_zh_CN { using namespace Language_en; // Inherit undefined strings from English constexpr uint8_t CHARSIZE = 3; - PROGMEM Language_Str LANGUAGE = _UxGT("Simplified Chinese"); + PROGMEM Language_Str LANGUAGE = _UxGT("简体中文"); PROGMEM Language_Str WELCOME_MSG = MACHINE_NAME _UxGT("已就绪."); //" ready." + PROGMEM Language_Str MSG_MARLIN = _UxGT("马林"); + PROGMEM Language_Str MSG_YES = _UxGT("是"); + PROGMEM Language_Str MSG_NO = _UxGT("否"); PROGMEM Language_Str MSG_BACK = _UxGT("返回"); // ”Back“ + PROGMEM Language_Str MSG_MEDIA_ABORTING = _UxGT("放弃中..."); PROGMEM Language_Str MSG_MEDIA_INSERTED = _UxGT("存储卡已插入"); //"Card inserted" PROGMEM Language_Str MSG_MEDIA_REMOVED = _UxGT("存储卡被拔出"); //"Card removed" + PROGMEM Language_Str MSG_MEDIA_WAITING = _UxGT("等待存储器"); + PROGMEM Language_Str MSG_MEDIA_READ_ERROR = _UxGT("存储器读取错误"); + PROGMEM Language_Str MSG_MEDIA_USB_REMOVED = _UxGT("USB设备已弹出"); + PROGMEM Language_Str MSG_MEDIA_USB_FAILED = _UxGT("USB启动错误"); + PROGMEM Language_Str MSG_KILL_SUBCALL_OVERFLOW = _UxGT("子响应溢出"); PROGMEM Language_Str MSG_LCD_ENDSTOPS = _UxGT("挡块"); //"Endstops" // Max length 8 characters + PROGMEM Language_Str MSG_LCD_SOFT_ENDSTOPS = _UxGT("软挡块"); PROGMEM Language_Str MSG_MAIN = _UxGT("主菜单"); //"Main" + PROGMEM Language_Str MSG_ADVANCED_SETTINGS = _UxGT("高级设置"); + PROGMEM Language_Str MSG_CONFIGURATION = _UxGT("配置"); PROGMEM Language_Str MSG_AUTOSTART = _UxGT("自动开始"); //"Autostart" PROGMEM Language_Str MSG_DISABLE_STEPPERS = _UxGT("关闭步进电机"); //"Disable steppers" PROGMEM Language_Str MSG_DEBUG_MENU = _UxGT("调试菜单"); // "Debug Menu" PROGMEM Language_Str MSG_PROGRESS_BAR_TEST = _UxGT("进度条测试"); // "Progress Bar Test" - PROGMEM Language_Str MSG_AUTO_HOME = _UxGT("回原点"); //"Auto home" + PROGMEM Language_Str MSG_AUTO_HOME = _UxGT("自动回原点"); //"Auto home" PROGMEM Language_Str MSG_AUTO_HOME_X = _UxGT("回X原位"); //"Home X" PROGMEM Language_Str MSG_AUTO_HOME_Y = _UxGT("回Y原位"); //"Home Y" PROGMEM Language_Str MSG_AUTO_HOME_Z = _UxGT("回Z原位"); //"Home Z" + PROGMEM Language_Str MSG_AUTO_Z_ALIGN = _UxGT("自动Z对齐"); PROGMEM Language_Str MSG_LEVEL_BED_HOMING = _UxGT("平台调平XYZ归原位"); //"Homing XYZ" PROGMEM Language_Str MSG_LEVEL_BED_WAITING = _UxGT("单击开始热床调平"); //"Click to Begin" PROGMEM Language_Str MSG_LEVEL_BED_NEXT_POINT = _UxGT("下个热床调平点"); //"Next Point" @@ -56,21 +68,35 @@ namespace Language_zh_CN { PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("设置原点偏移"); //"Set home offsets" PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("偏移已启用"); //"Offsets applied" PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("设置原点"); //"Set origin" - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("预热 ") PREHEAT_1_LABEL; //"Preheat PREHEAT_2_LABEL" - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("预热 ") PREHEAT_1_LABEL " ~"; //"Preheat PREHEAT_2_LABEL" - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("预热 ") PREHEAT_1_LABEL _UxGT(" 喷嘴"); //MSG_PREHEAT_1 " " - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("预热 ") PREHEAT_1_LABEL _UxGT(" 喷嘴 ~"); //MSG_PREHEAT_1 " " - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("预热 ") PREHEAT_1_LABEL _UxGT(" 全部"); //MSG_PREHEAT_1 " All" - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("预热 ") PREHEAT_1_LABEL _UxGT(" 热床"); //MSG_PREHEAT_1 " Bed" - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("预热 ") PREHEAT_1_LABEL _UxGT(" 设置"); //MSG_PREHEAT_1 " conf" - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("预热 ") PREHEAT_2_LABEL; //"Preheat PREHEAT_2_LABEL" - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("预热 ") PREHEAT_2_LABEL " ~"; //"Preheat PREHEAT_2_LABEL" - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("预热 ") PREHEAT_2_LABEL _UxGT(" 喷嘴"); //MSG_PREHEAT_2 " " - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("预热 ") PREHEAT_2_LABEL _UxGT(" 喷嘴 ~"); //MSG_PREHEAT_2 " " - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("预热 ") PREHEAT_2_LABEL _UxGT(" 全部"); //MSG_PREHEAT_2 " All" - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("预热 ") PREHEAT_2_LABEL _UxGT(" 热床"); //MSG_PREHEAT_2 " Bed" - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("预热 ") PREHEAT_2_LABEL _UxGT(" 设置"); //MSG_PREHEAT_2 " conf" + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("预热 ") PREHEAT_1_LABEL; //"Preheat PREHEAT_2_LABEL" + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("预热 ") PREHEAT_1_LABEL " ~"; //"Preheat PREHEAT_2_LABEL" + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("预热 ") PREHEAT_1_LABEL _UxGT(" 喷嘴"); //MSG_PREHEAT_1 " " + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("预热 ") PREHEAT_1_LABEL _UxGT(" 喷嘴 ~"); //MSG_PREHEAT_1 " " + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("预热 ") PREHEAT_1_LABEL _UxGT(" 全部"); //MSG_PREHEAT_1 " All" + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("预热 ") PREHEAT_1_LABEL _UxGT(" 热床"); //MSG_PREHEAT_1 " Bed" + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("预热 ") PREHEAT_1_LABEL _UxGT(" 设置"); //MSG_PREHEAT_1 " conf" + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("预热 $"); //"Preheat PREHEAT_2_LABEL" + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("预热 $ ~"); //"Preheat PREHEAT_2_LABEL" + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("预热 $ 喷嘴"); //MSG_PREHEAT_1 " " + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("预热 $ 喷嘴 ~"); //MSG_PREHEAT_1 " " + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("预热 $ 全部"); //MSG_PREHEAT_1 " All" + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("预热 $ 热床"); //MSG_PREHEAT_1 " Bed" + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("预热 $ 设置"); //MSG_PREHEAT_1 " conf" + #endif + PROGMEM Language_Str MSG_PREHEAT_CUSTOM = _UxGT("预热自定义"); PROGMEM Language_Str MSG_COOLDOWN = _UxGT("降温"); //"Cooldown" + PROGMEM Language_Str MSG_CUTTER_FREQUENCY = _UxGT("切割频率"); + PROGMEM Language_Str MSG_LASER_MENU = _UxGT("激光控制"); + PROGMEM Language_Str MSG_LASER_OFF = _UxGT("激光关"); + PROGMEM Language_Str MSG_LASER_ON = _UxGT("激光开"); + PROGMEM Language_Str MSG_LASER_POWER = _UxGT("激光电源"); + PROGMEM Language_Str MSG_SPINDLE_MENU = _UxGT("主轴控制"); + PROGMEM Language_Str MSG_SPINDLE_OFF = _UxGT("主轴关"); + PROGMEM Language_Str MSG_SPINDLE_ON = _UxGT("主轴开"); + PROGMEM Language_Str MSG_SPINDLE_POWER = _UxGT("主轴电源"); + PROGMEM Language_Str MSG_SPINDLE_REVERSE = _UxGT("主轴反转"); PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("电源打开"); //"Switch power on" PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("电源关闭"); //"Switch power off" PROGMEM Language_Str MSG_EXTRUDE = _UxGT("挤出"); //"Extrude" @@ -79,15 +105,31 @@ namespace Language_zh_CN { PROGMEM Language_Str MSG_BED_LEVELING = _UxGT("调平热床"); //"Bed leveling" PROGMEM Language_Str MSG_LEVEL_BED = _UxGT("调平热床"); //"Level bed" PROGMEM Language_Str MSG_LEVEL_CORNERS = _UxGT("调平边角"); // "Level corners" - PROGMEM Language_Str MSG_NEXT_CORNER = _UxGT("下个边角"); // "Next corner" + PROGMEM Language_Str MSG_MESH_EDITOR = _UxGT("网格编辑器"); PROGMEM Language_Str MSG_EDIT_MESH = _UxGT("编辑网格"); // "Edit Mesh" PROGMEM Language_Str MSG_EDITING_STOPPED = _UxGT("网格编辑已停止"); // "Mesh Editing Stopped" + PROGMEM Language_Str MSG_PROBING_MESH = _UxGT("探测点"); + PROGMEM Language_Str MSG_MESH_X = _UxGT("索引X"); + PROGMEM Language_Str MSG_MESH_Y = _UxGT("索引Y"); + PROGMEM Language_Str MSG_MESH_EDIT_Z = _UxGT("Z 值"); PROGMEM Language_Str MSG_USER_MENU = _UxGT("定制命令"); // "Custom Commands" - + PROGMEM Language_Str MSG_M48_TEST = _UxGT("M48探测"); + PROGMEM Language_Str MSG_M48_POINT = _UxGT("M48点"); + PROGMEM Language_Str MSG_M48_DEVIATION = _UxGT("M48偏差"); + PROGMEM Language_Str MSG_IDEX_MENU = _UxGT("IDEX模式"); + PROGMEM Language_Str MSG_OFFSETS_MENU = _UxGT("工具偏移量"); + PROGMEM Language_Str MSG_IDEX_MODE_AUTOPARK = _UxGT("自动停靠"); + PROGMEM Language_Str MSG_IDEX_MODE_DUPLICATE = _UxGT("复制"); + PROGMEM Language_Str MSG_IDEX_MODE_MIRRORED_COPY = _UxGT("镜像复制"); + PROGMEM Language_Str MSG_IDEX_MODE_FULL_CTRL = _UxGT("完全控制"); + PROGMEM Language_Str MSG_HOTEND_OFFSET_X = _UxGT("第二喷头是X"); + PROGMEM Language_Str MSG_HOTEND_OFFSET_Y = _UxGT("第二喷头是Y"); + PROGMEM Language_Str MSG_HOTEND_OFFSET_Z = _UxGT("第二喷头是Z"); PROGMEM Language_Str MSG_UBL_DOING_G29 = _UxGT("执行G29"); // "Doing G29" PROGMEM Language_Str MSG_UBL_TOOLS = _UxGT("UBL工具"); // "UBL Tools" PROGMEM Language_Str MSG_UBL_LEVEL_BED = _UxGT("统一热床调平(UBL)"); // "Unified Bed Leveling" + PROGMEM Language_Str MSG_LCD_TILTING_MESH = _UxGT("倾斜點"); PROGMEM Language_Str MSG_UBL_MANUAL_MESH = _UxGT("手工创设网格"); // "Manually Build Mesh" PROGMEM Language_Str MSG_UBL_BC_INSERT = _UxGT("放置垫片并测量"); // "Place shim & measure" PROGMEM Language_Str MSG_UBL_BC_INSERT2 = _UxGT("测量"); // "Measure" @@ -95,23 +137,32 @@ namespace Language_zh_CN { PROGMEM Language_Str MSG_UBL_MOVING_TO_NEXT = _UxGT("移动到下一个"); // "Moving to next" PROGMEM Language_Str MSG_UBL_ACTIVATE_MESH = _UxGT("激活UBL"); // "Activate UBL" PROGMEM Language_Str MSG_UBL_DEACTIVATE_MESH = _UxGT("关闭UBL"); // "Deactivate UBL" - PROGMEM Language_Str MSG_UBL_SET_TEMP_BED = _UxGT("设置热床温度"); // "Bed Temp" + PROGMEM Language_Str MSG_UBL_SET_TEMP_BED = _UxGT("热床温度"); // "Bed Temp" + PROGMEM Language_Str MSG_UBL_BED_TEMP_CUSTOM = _UxGT("热床温度"); PROGMEM Language_Str MSG_UBL_SET_TEMP_HOTEND = _UxGT("热端温度"); // "Hotend Temp" + PROGMEM Language_Str MSG_UBL_HOTEND_TEMP_CUSTOM = _UxGT("热端温度"); PROGMEM Language_Str MSG_UBL_MESH_EDIT = _UxGT("网格编辑"); // "Mesh Edit" PROGMEM Language_Str MSG_UBL_EDIT_CUSTOM_MESH = _UxGT("编辑客户网格"); // "Edit Custom Mesh" PROGMEM Language_Str MSG_UBL_FINE_TUNE_MESH = _UxGT("细调网格"); // "Fine Tuning Mesh" PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("完成编辑网格"); // "Done Editing Mesh" PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("创设客户网格"); // "Build Custom Mesh" PROGMEM Language_Str MSG_UBL_BUILD_MESH_MENU = _UxGT("创设网格"); // "Build Mesh" - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M1 = _UxGT("创设 ") PREHEAT_1_LABEL _UxGT(" 网格"); // "Build PREHEAT_1_LABEL Mesh" - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M2 = _UxGT("创设 ") PREHEAT_2_LABEL _UxGT(" 网格"); // "Build PREHEAT_2_LABEL Mesh" + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_UBL_BUILD_MESH_M = _UxGT("创设 $ 网格"); // "Build PREHEAT_1_LABEL Mesh" + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("批准 $ 网格"); // "Validate PREHEAT_1_LABEL Mesh" + #endif PROGMEM Language_Str MSG_UBL_BUILD_COLD_MESH = _UxGT("创设冷网格"); // "Build Cold Mesh" PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_ADJUST = _UxGT("调整网格高度"); // "Adjust Mesh Height" PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_AMOUNT = _UxGT("高度合计"); // "Height Amount" PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_MENU = _UxGT("批准网格"); // "Validate Mesh" - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M1 = _UxGT("批准 ") PREHEAT_1_LABEL _UxGT(" 网格"); // "Validate PREHEAT_1_LABEL Mesh" - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M2 = _UxGT("批准 ") PREHEAT_2_LABEL _UxGT(" 网格"); // "Validate PREHEAT_2_LABEL Mesh" PROGMEM Language_Str MSG_UBL_VALIDATE_CUSTOM_MESH = _UxGT("批准客户网格"); // "Validate Custom Mesh" + PROGMEM Language_Str MSG_G26_HEATING_BED = _UxGT("G26加热热床"); + PROGMEM Language_Str MSG_G26_HEATING_NOZZLE = _UxGT("G26加热喷嘴"); + PROGMEM Language_Str MSG_G26_MANUAL_PRIME = _UxGT("手动填装中..."); + PROGMEM Language_Str MSG_G26_FIXED_LENGTH = _UxGT("固定距离填装"); + PROGMEM Language_Str MSG_G26_PRIME_DONE = _UxGT("填装完成"); + PROGMEM Language_Str MSG_G26_CANCELED = _UxGT("G26已取消"); + PROGMEM Language_Str MSG_G26_LEAVING = _UxGT("离开G26"); PROGMEM Language_Str MSG_UBL_CONTINUE_MESH = _UxGT("继续热床网格"); // "Continue Bed Mesh" PROGMEM Language_Str MSG_UBL_MESH_LEVELING = _UxGT("网格调平"); // "Mesh Leveling" PROGMEM Language_Str MSG_UBL_3POINT_MESH_LEVELING = _UxGT("三点调平"); // "3-Point Leveling" @@ -136,11 +187,12 @@ namespace Language_zh_CN { PROGMEM Language_Str MSG_UBL_STORAGE_SLOT = _UxGT("存储槽"); // "Memory Slot" PROGMEM Language_Str MSG_UBL_LOAD_MESH = _UxGT("装载热床网格"); // "Load Bed Mesh" PROGMEM Language_Str MSG_UBL_SAVE_MESH = _UxGT("保存热床网格"); // "Save Bed Mesh" - PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("M117 网格 %i 已装载"); // "Mesh %i loaded" - PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("M117 网格 %i 已保存"); // "Mesh %i saved" + PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("网格 %i 已装载"); // "Mesh %i loaded" + PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("网格 %i 已保存"); // "Mesh %i saved" PROGMEM Language_Str MSG_UBL_NO_STORAGE = _UxGT("没有存储"); // "No storage" PROGMEM Language_Str MSG_UBL_SAVE_ERROR = _UxGT("错误: UBL保存"); // "Err: UBL Save" PROGMEM Language_Str MSG_UBL_RESTORE_ERROR = _UxGT("错误: UBL还原"); // "Err: UBL Restore" + PROGMEM Language_Str MSG_UBL_Z_OFFSET = _UxGT("Z偏移量: "); PROGMEM Language_Str MSG_UBL_Z_OFFSET_STOPPED = _UxGT("Z偏移已停止"); // "Z-Offset Stopped" PROGMEM Language_Str MSG_UBL_STEP_BY_STEP_MENU = _UxGT("一步步UBL"); // "Step-By-Step UBL" PROGMEM Language_Str MSG_UBL_1_BUILD_COLD_MESH = _UxGT("1. 创设冷网格"); @@ -151,7 +203,7 @@ namespace Language_zh_CN { PROGMEM Language_Str MSG_UBL_6_FINE_TUNE_ALL = _UxGT("6. 细调所有的"); PROGMEM Language_Str MSG_UBL_7_SAVE_MESH = _UxGT("7. 保存热床网格"); - PROGMEM Language_Str MSG_LED_CONTROL = _UxGT("灯管控制"); // "LED Control") + PROGMEM Language_Str MSG_LED_CONTROL = _UxGT("LED控制"); // "LED Control") PROGMEM Language_Str MSG_LEDS = _UxGT("灯"); // "Lights") PROGMEM Language_Str MSG_LED_PRESETS = _UxGT("灯预置"); // "Light Presets") PROGMEM Language_Str MSG_SET_LEDS_RED = _UxGT("红"); // "Red") @@ -170,26 +222,36 @@ namespace Language_zh_CN { PROGMEM Language_Str MSG_INTENSITY_W = _UxGT("白饱和度"); // "White Intensity") PROGMEM Language_Str MSG_LED_BRIGHTNESS = _UxGT("亮度"); // "Brightness") - PROGMEM Language_Str MSG_MOVING = _UxGT("移动 ..."); // "Moving...") + PROGMEM Language_Str MSG_MOVING = _UxGT("移动..."); // "Moving...") PROGMEM Language_Str MSG_FREE_XY = _UxGT("释放 XY"); // "Free XY") PROGMEM Language_Str MSG_MOVE_X = _UxGT("移动X"); //"Move X" PROGMEM Language_Str MSG_MOVE_Y = _UxGT("移动Y"); //"Move Y" PROGMEM Language_Str MSG_MOVE_Z = _UxGT("移动Z"); //"Move Z" PROGMEM Language_Str MSG_MOVE_E = _UxGT("挤出机"); //"Extruder" PROGMEM Language_Str MSG_MOVE_EN = _UxGT("挤出机 *"); //"Extruder" + PROGMEM Language_Str MSG_HOTEND_TOO_COLD = _UxGT("热端太冷"); PROGMEM Language_Str MSG_MOVE_Z_DIST = _UxGT("移动 %s mm"); //"Move 0.025mm" PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("移动 0.1 mm"); //"Move 0.1mm" PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("移动 1 mm"); //"Move 1mm" PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("移动 10 mm"); //"Move 10mm" PROGMEM Language_Str MSG_SPEED = _UxGT("速率"); //"Speed" PROGMEM Language_Str MSG_BED_Z = _UxGT("热床Z"); //"Bed Z" - PROGMEM Language_Str MSG_NOZZLE = " " LCD_STR_THERMOMETER _UxGT(" 喷嘴"); //"Nozzle" 噴嘴 - PROGMEM Language_Str MSG_NOZZLE_N = " " LCD_STR_THERMOMETER _UxGT(" 喷嘴 ~"); //"Nozzle" 噴嘴 - PROGMEM Language_Str MSG_BED = " " LCD_STR_THERMOMETER _UxGT(" 热床"); //"Bed" + PROGMEM Language_Str MSG_NOZZLE = _UxGT("喷嘴"); //"Nozzle" 噴嘴 + PROGMEM Language_Str MSG_NOZZLE_N = _UxGT("喷嘴 ~"); //"Nozzle" 噴嘴 + PROGMEM Language_Str MSG_NOZZLE_PARKED = _UxGT("喷嘴已停靠"); + PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("喷嘴待命中"); + PROGMEM Language_Str MSG_BED = _UxGT("热床"); //"Bed" + PROGMEM Language_Str MSG_CHAMBER = _UxGT("机箱壳"); PROGMEM Language_Str MSG_FAN_SPEED = _UxGT("风扇速率"); //"Fan speed" PROGMEM Language_Str MSG_FAN_SPEED_N = _UxGT("风扇速率 ~"); //"Fan speed" + PROGMEM Language_Str MSG_STORED_FAN_N = _UxGT("存储的风扇 ~"); PROGMEM Language_Str MSG_EXTRA_FAN_SPEED = _UxGT("额外风扇速率"); // "Extra fan speed" PROGMEM Language_Str MSG_EXTRA_FAN_SPEED_N = _UxGT("额外风扇速率 ~"); // "Extra fan speed" + PROGMEM Language_Str MSG_CONTROLLER_FAN = _UxGT("控制器风扇"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_IDLE_SPEED = _UxGT("空闲速度"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_AUTO_ON = _UxGT("自动模式"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_SPEED = _UxGT("工作速度"); + PROGMEM Language_Str MSG_CONTROLLER_FAN_DURATION = _UxGT("空闲周期"); PROGMEM Language_Str MSG_FLOW = _UxGT("挤出速率"); //"Flow" PROGMEM Language_Str MSG_FLOW_N = _UxGT("挤出速率 ~"); //"Flow" PROGMEM Language_Str MSG_CONTROL = _UxGT("控制"); //"Control" @@ -199,6 +261,22 @@ namespace Language_zh_CN { PROGMEM Language_Str MSG_AUTOTEMP = _UxGT("自动控温"); //"Autotemp" PROGMEM Language_Str MSG_LCD_ON = _UxGT("开"); //"On" PROGMEM Language_Str MSG_LCD_OFF = _UxGT("关"); //"Off" + PROGMEM Language_Str MSG_PID_AUTOTUNE = _UxGT("自动PID"); + PROGMEM Language_Str MSG_PID_AUTOTUNE_E = _UxGT("自动PID *"); + PROGMEM Language_Str MSG_PID_AUTOTUNE_DONE = _UxGT("PID调整完成"); + PROGMEM Language_Str MSG_PID_BAD_EXTRUDER_NUM = _UxGT("自动调失败. 坏的挤出机"); + PROGMEM Language_Str MSG_PID_TEMP_TOO_HIGH = _UxGT("自动调失败. 温度太高"); + PROGMEM Language_Str MSG_PID_TIMEOUT = _UxGT("自动调失败! 超时"); + PROGMEM Language_Str MSG_PID_P = _UxGT("PID-P"); + PROGMEM Language_Str MSG_PID_P_E = _UxGT("PID-P *"); + PROGMEM Language_Str MSG_PID_I = _UxGT("PID-I"); + PROGMEM Language_Str MSG_PID_I_E = _UxGT("PID-I *"); + PROGMEM Language_Str MSG_PID_D = _UxGT("PID-D"); + PROGMEM Language_Str MSG_PID_D_E = _UxGT("PID-D *"); + PROGMEM Language_Str MSG_PID_C = _UxGT("PID-C"); + PROGMEM Language_Str MSG_PID_C_E = _UxGT("PID-C *"); + PROGMEM Language_Str MSG_PID_F = _UxGT("PID-F"); + PROGMEM Language_Str MSG_PID_F_E = _UxGT("PID-F *"); PROGMEM Language_Str MSG_SELECT = _UxGT("选择"); //"Select" PROGMEM Language_Str MSG_SELECT_E = _UxGT("选择 *"); PROGMEM Language_Str MSG_ACC = _UxGT("加速度"); //"Accel" acceleration @@ -207,6 +285,7 @@ namespace Language_zh_CN { PROGMEM Language_Str MSG_VB_JERK = _UxGT("轴抖动速率") LCD_STR_B; //"Vb-jerk" PROGMEM Language_Str MSG_VC_JERK = _UxGT("轴抖动速率") LCD_STR_C; //"Vc-jerk" PROGMEM Language_Str MSG_VE_JERK = _UxGT("挤出机抖动速率"); //"Ve-jerk" + PROGMEM Language_Str MSG_JUNCTION_DEVIATION = _UxGT("接点差"); PROGMEM Language_Str MSG_VELOCITY = _UxGT("速度"); // "Velocity" PROGMEM Language_Str MSG_VMAX_A = _UxGT("最大进料速率") LCD_STR_A; //"Vmax " max_feedrate_mm_s PROGMEM Language_Str MSG_VMAX_B = _UxGT("最大进料速率") LCD_STR_B; //"Vmax " max_feedrate_mm_s @@ -223,50 +302,101 @@ namespace Language_zh_CN { PROGMEM Language_Str MSG_AMAX_EN = _UxGT("最大打印加速度 *"); //"Amax " max_acceleration_mm_per_s2, acceleration in units/s^2 for print moves PROGMEM Language_Str MSG_A_RETRACT = _UxGT("收进加速度"); //"A-retract" retract_acceleration, E acceleration in mm/s^2 for retracts PROGMEM Language_Str MSG_A_TRAVEL = _UxGT("非打印移动加速度"); //"A-travel" travel_acceleration, X, Y, Z acceleration in mm/s^2 for travel (non printing) moves + PROGMEM Language_Str MSG_XY_FREQUENCY_LIMIT = _UxGT("频率最大"); + PROGMEM Language_Str MSG_XY_FREQUENCY_FEEDRATE = _UxGT("进给速度"); PROGMEM Language_Str MSG_STEPS_PER_MM = _UxGT("轴步数/mm"); //"Steps/mm" axis_steps_per_mm, axis steps-per-unit G92 - PROGMEM Language_Str MSG_A_STEPS = LCD_STR_A _UxGT("轴步数/mm"); //"Asteps/mm" - PROGMEM Language_Str MSG_B_STEPS = LCD_STR_B _UxGT("轴步数/mm"); //"Bsteps/mm" - PROGMEM Language_Str MSG_C_STEPS = LCD_STR_C _UxGT("轴步数/mm"); //"Csteps/mm" - PROGMEM Language_Str MSG_E_STEPS = _UxGT("挤出机步数/mm"); //"Esteps/mm" - PROGMEM Language_Str MSG_EN_STEPS = _UxGT("挤出机~步数/mm"); + PROGMEM Language_Str MSG_A_STEPS = LCD_STR_A _UxGT("步数/mm"); //"Asteps/mm" + PROGMEM Language_Str MSG_B_STEPS = LCD_STR_B _UxGT("步数/mm"); //"Bsteps/mm" + PROGMEM Language_Str MSG_C_STEPS = LCD_STR_C _UxGT("步数/mm"); //"Csteps/mm" + PROGMEM Language_Str MSG_E_STEPS = _UxGT("E 步数/mm"); //"Esteps/mm" + PROGMEM Language_Str MSG_EN_STEPS = _UxGT("* 步数/mm"); PROGMEM Language_Str MSG_TEMPERATURE = _UxGT("温度"); //"Temperature" PROGMEM Language_Str MSG_MOTION = _UxGT("运动"); //"Motion" - PROGMEM Language_Str MSG_FILAMENT = _UxGT("丝料测容"); //"Filament" menu_advanced_filament - PROGMEM Language_Str MSG_VOLUMETRIC_ENABLED = _UxGT("测容积mm³"); //"E in mm3" volumetric_enabled + PROGMEM Language_Str MSG_FILAMENT = _UxGT("料丝"); //"Filament" menu_advanced_filament + PROGMEM Language_Str MSG_VOLUMETRIC_ENABLED = _UxGT("E 在 mm³"); //"E in mm3" volumetric_enabled + PROGMEM Language_Str MSG_VOLUMETRIC_LIMIT = _UxGT("E 限制 在 mm³"); + PROGMEM Language_Str MSG_VOLUMETRIC_LIMIT_E = _UxGT("E 限制 *"); PROGMEM Language_Str MSG_FILAMENT_DIAM = _UxGT("丝料直径"); //"Fil. Dia." PROGMEM Language_Str MSG_FILAMENT_DIAM_E = _UxGT("丝料直径 *"); PROGMEM Language_Str MSG_FILAMENT_UNLOAD = _UxGT("卸载 mm"); // "Unload mm" PROGMEM Language_Str MSG_FILAMENT_LOAD = _UxGT("装载 mm"); // "Load mm" + PROGMEM Language_Str MSG_ADVANCE_K = _UxGT("Advance K"); + PROGMEM Language_Str MSG_ADVANCE_K_E = _UxGT("Advance K *"); PROGMEM Language_Str MSG_CONTRAST = _UxGT("LCD对比度"); //"LCD contrast" PROGMEM Language_Str MSG_STORE_EEPROM = _UxGT("保存设置"); //"Store memory" PROGMEM Language_Str MSG_LOAD_EEPROM = _UxGT("装载设置"); //"Load memory" PROGMEM Language_Str MSG_RESTORE_DEFAULTS = _UxGT("恢复安全值"); //"Restore Defaults" PROGMEM Language_Str MSG_INIT_EEPROM = _UxGT("初始化设置"); // "Initialize EEPROM" - PROGMEM Language_Str MSG_REFRESH = LCD_STR_REFRESH _UxGT("刷新"); //"Refresh" + PROGMEM Language_Str MSG_ERR_EEPROM_CRC = _UxGT("EEPROM CRC 错误"); + PROGMEM Language_Str MSG_ERR_EEPROM_INDEX = _UxGT("EEPROM Index 错误"); + PROGMEM Language_Str MSG_ERR_EEPROM_VERSION = _UxGT("EEPROM Version 错误"); + PROGMEM Language_Str MSG_SETTINGS_STORED = _UxGT("设置已保存"); + PROGMEM Language_Str MSG_MEDIA_UPDATE = _UxGT("存储器更新"); + PROGMEM Language_Str MSG_RESET_PRINTER = _UxGT("复位打印机"); + PROGMEM Language_Str MSG_REFRESH = LCD_STR_REFRESH _UxGT("刷新"); PROGMEM Language_Str MSG_INFO_SCREEN = _UxGT("信息屏"); //"Info screen" PROGMEM Language_Str MSG_PREPARE = _UxGT("准备"); //"Prepare" PROGMEM Language_Str MSG_TUNE = _UxGT("调整"); //"Tune" + PROGMEM Language_Str MSG_POWER_MONITOR = _UxGT("电源监控"); + PROGMEM Language_Str MSG_CURRENT = _UxGT("电流"); + PROGMEM Language_Str MSG_VOLTAGE = _UxGT("电压"); + PROGMEM Language_Str MSG_POWER = _UxGT("功率"); + PROGMEM Language_Str MSG_START_PRINT = _UxGT("开始打印"); + PROGMEM Language_Str MSG_BUTTON_NEXT = _UxGT("下一个"); + PROGMEM Language_Str MSG_BUTTON_INIT = _UxGT("初始"); + PROGMEM Language_Str MSG_BUTTON_STOP = _UxGT("停止"); + PROGMEM Language_Str MSG_BUTTON_PRINT = _UxGT("打印"); + PROGMEM Language_Str MSG_BUTTON_RESET = _UxGT("复位"); + PROGMEM Language_Str MSG_BUTTON_IGNORE = _UxGT("忽略"); + PROGMEM Language_Str MSG_BUTTON_CANCEL = _UxGT("取消"); + PROGMEM Language_Str MSG_BUTTON_DONE = _UxGT("完成"); + PROGMEM Language_Str MSG_BUTTON_BACK = _UxGT("返回"); + PROGMEM Language_Str MSG_BUTTON_PROCEED = _UxGT("继续"); + PROGMEM Language_Str MSG_PAUSING = _UxGT("暂停中..."); PROGMEM Language_Str MSG_PAUSE_PRINT = _UxGT("暂停打印"); //"Pause print" PROGMEM Language_Str MSG_RESUME_PRINT = _UxGT("恢复打印"); //"Resume print" PROGMEM Language_Str MSG_STOP_PRINT = _UxGT("停止打印"); //"Stop print" + PROGMEM Language_Str MSG_PRINTING_OBJECT = _UxGT("打印物体"); + PROGMEM Language_Str MSG_CANCEL_OBJECT = _UxGT("取消物体"); + PROGMEM Language_Str MSG_CANCEL_OBJECT_N = _UxGT("取消物体 ="); + PROGMEM Language_Str MSG_OUTAGE_RECOVERY = _UxGT("中断恢复"); PROGMEM Language_Str MSG_MEDIA_MENU = _UxGT("从存储卡上打印"); //"Print from SD" PROGMEM Language_Str MSG_NO_MEDIA = _UxGT("无存储卡"); //"No SD card" PROGMEM Language_Str MSG_DWELL = _UxGT("休眠中 ..."); //"Sleep..." PROGMEM Language_Str MSG_USERWAIT = _UxGT("点击继续 ..."); //"Click to resume..." PROGMEM Language_Str MSG_PRINT_PAUSED = _UxGT("暫停打印"); // "Print paused" + PROGMEM Language_Str MSG_PRINTING = _UxGT("打印中..."); PROGMEM Language_Str MSG_PRINT_ABORTED = _UxGT("已取消打印"); //"Print aborted" + PROGMEM Language_Str MSG_PRINT_DONE = _UxGT("打印已完成"); PROGMEM Language_Str MSG_NO_MOVE = _UxGT("无移动"); //"No move." PROGMEM Language_Str MSG_KILLED = _UxGT("已杀掉"); //"KILLED. " PROGMEM Language_Str MSG_STOPPED = _UxGT("已停止"); //"STOPPED. " PROGMEM Language_Str MSG_CONTROL_RETRACT = _UxGT("回抽长度mm"); //"Retract mm" retract_length, retract length (positive mm) PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("换手回抽长度mm"); //"Swap Re.mm" swap_retract_length, swap retract length (positive mm), for extruder change - PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("回抽速率mm/s"); //"Retract V" retract_feedrate_mm_s, feedrate for retracting (mm/s) + PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("回抽速率mm/s"); //"Retract V" retract_feedrate_mm_s, feedrate for retracting (mm/s) PROGMEM Language_Str MSG_CONTROL_RETRACT_ZHOP = _UxGT("Hop mm"); //"Hop mm" retract_zraise, retract Z-lift PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("回抽恢复长度mm"); //"UnRet +mm" retract_recover_extra, additional recover length (mm, added to retract length when recovering) PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("换手回抽恢复长度mm"); //"S UnRet+mm" swap_retract_recover_extra, additional swap recover length (mm, added to retract length when recovering from extruder change) - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("回抽恢复后进料速率mm/s"); //"UnRet V" retract_recover_feedrate_mm_s, feedrate for recovering from retraction (mm/s) + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("回抽恢复后进料速率mm/s"); //"Unretract V" retract_recover_feedrate_mm_s, feedrate for recovering from retraction (mm/s) PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAPF = _UxGT("S UnRet V"); // "S UnRet V" - PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("自动抽回"); //"AutoRetr." autoretract_enabled, + PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("自动抽回"); //"Auto-Retract" autoretract_enabled, + PROGMEM Language_Str MSG_FILAMENT_SWAP_LENGTH = _UxGT("交换长度"); + PROGMEM Language_Str MSG_FILAMENT_SWAP_EXTRA = _UxGT("额外的交换"); + PROGMEM Language_Str MSG_FILAMENT_PURGE_LENGTH = _UxGT("清洗长度"); + PROGMEM Language_Str MSG_TOOL_CHANGE = _UxGT("换工具"); + PROGMEM Language_Str MSG_TOOL_CHANGE_ZLIFT = _UxGT("Z抬起"); + PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPEED = _UxGT("进给速度"); + PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPEED = _UxGT("回抽速度"); + PROGMEM Language_Str MSG_FILAMENT_PARK_ENABLED = _UxGT("停靠头"); + PROGMEM Language_Str MSG_SINGLENOZZLE_UNRETRACT_SPEED = _UxGT("恢复速度"); + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_SPEED = _UxGT("风扇速度"); + PROGMEM Language_Str MSG_SINGLENOZZLE_FAN_TIME = _UxGT("风扇时间"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_ON = _UxGT("自动开"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_OFF = _UxGT("自动关"); + PROGMEM Language_Str MSG_TOOL_MIGRATION = _UxGT("工具迁移"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_AUTO = _UxGT("自动迁移"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_END = _UxGT("上一个挤出机"); + PROGMEM Language_Str MSG_TOOL_MIGRATION_SWAP = _UxGT("迁移至 *"); PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("更换丝料"); //"Change filament" PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("更换丝料 *"); //"Change filament" PROGMEM Language_Str MSG_FILAMENTLOAD = _UxGT("装载丝料"); // "Load filament" @@ -276,34 +406,57 @@ namespace Language_zh_CN { PROGMEM Language_Str MSG_FILAMENTUNLOAD_ALL = _UxGT("卸载全部"); // "Unload All" PROGMEM Language_Str MSG_ATTACH_MEDIA = _UxGT("初始化存储卡"); //"Init. SD card" PROGMEM Language_Str MSG_CHANGE_MEDIA = _UxGT("更换存储卡"); //"Change SD card" + PROGMEM Language_Str MSG_RELEASE_MEDIA = _UxGT("释放存储卡"); PROGMEM Language_Str MSG_ZPROBE_OUT = _UxGT("Z探针在热床之外"); //"Z probe out. bed" Z probe is not within the physical limits PROGMEM Language_Str MSG_SKEW_FACTOR = _UxGT("偏斜因数"); // "Skew Factor" PROGMEM Language_Str MSG_BLTOUCH = _UxGT("BLTouch"); // "BLTouch" - PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("BLTouch 自检"); // "BLTouch Self-Test" - PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("重置BLTouch"); // "Reset BLTouch" - PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("部署BLTouch"); // "Deploy BLTouch" - PROGMEM Language_Str MSG_BLTOUCH_STOW = _UxGT("装载BLTouch"); // "Stow BLTouch" + PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("自检"); + PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("重置"); + PROGMEM Language_Str MSG_BLTOUCH_STOW = _UxGT("装载"); + PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("部署"); + PROGMEM Language_Str MSG_BLTOUCH_SW_MODE = _UxGT("SW模式"); + PROGMEM Language_Str MSG_BLTOUCH_5V_MODE = _UxGT("5V模式"); + PROGMEM Language_Str MSG_BLTOUCH_OD_MODE = _UxGT("OD模式"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE = _UxGT("模式保存"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_5V = _UxGT("设置BLTouch为5V"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_STORE_OD = _UxGT("设置BLTouch为OD"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_ECHO = _UxGT("报告开漏"); + PROGMEM Language_Str MSG_BLTOUCH_MODE_CHANGE = _UxGT("危险: 错误的设置将引起损坏! 是否继续?"); + PROGMEM Language_Str MSG_TOUCHMI_PROBE = _UxGT("TouchMI"); + PROGMEM Language_Str MSG_TOUCHMI_INIT = _UxGT("初始化TouchMI"); + PROGMEM Language_Str MSG_TOUCHMI_ZTEST = _UxGT("Z偏移量测试"); + PROGMEM Language_Str MSG_TOUCHMI_SAVE = _UxGT("保存"); + PROGMEM Language_Str MSG_MANUAL_DEPLOY_TOUCHMI = _UxGT("部署TouchMI"); + PROGMEM Language_Str MSG_MANUAL_DEPLOY = _UxGT("部署Z探针"); + PROGMEM Language_Str MSG_MANUAL_STOW = _UxGT("收好Z探针"); PROGMEM Language_Str MSG_HOME_FIRST = _UxGT("归位 %s%s%s 先"); //"Home ... first" - PROGMEM Language_Str MSG_ZPROBE_ZOFFSET = _UxGT("Z偏移"); //"Z Offset" + PROGMEM Language_Str MSG_ZPROBE_OFFSETS = _UxGT("探针偏移量"); + PROGMEM Language_Str MSG_ZPROBE_XOFFSET = _UxGT("探针X偏移"); + PROGMEM Language_Str MSG_ZPROBE_YOFFSET = _UxGT("探针Y偏移"); + PROGMEM Language_Str MSG_ZPROBE_ZOFFSET = _UxGT("探针Z偏移"); //"Z Offset" PROGMEM Language_Str MSG_BABYSTEP_X = _UxGT("微量调整X轴"); //"Babystep X" lcd_babystep_x, Babystepping enables the user to control the axis in tiny amounts PROGMEM Language_Str MSG_BABYSTEP_Y = _UxGT("微量调整Y轴"); //"Babystep Y" PROGMEM Language_Str MSG_BABYSTEP_Z = _UxGT("微量调整Z轴"); //"Babystep Z" + PROGMEM Language_Str MSG_BABYSTEP_TOTAL = _UxGT("总计"); PROGMEM Language_Str MSG_ENDSTOP_ABORT = _UxGT("挡块终止"); //"Endstop abort" PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("加热失败"); //"Heating failed" - PROGMEM Language_Str MSG_ERR_REDUNDANT_TEMP = _UxGT("错误:REDUNDANT TEMP"); //"Err: REDUNDANT TEMP" + PROGMEM Language_Str MSG_ERR_REDUNDANT_TEMP = _UxGT("错误:冗余温度"); //"Err: REDUNDANT TEMP" PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("温控失控"); //"THERMAL RUNAWAY" + PROGMEM Language_Str MSG_THERMAL_RUNAWAY_BED = _UxGT("热床热量失控"); + PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER = _UxGT("机箱热量失控"); PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("错误:最高温度"); //"Err: MAXTEMP" PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("错误:最低温度"); //"Err: MINTEMP" - PROGMEM Language_Str MSG_ERR_MAXTEMP_BED = _UxGT("错误:最高热床温度"); //"Err: MAXTEMP BED" - PROGMEM Language_Str MSG_ERR_MINTEMP_BED = _UxGT("错误:最低热床温度"); //"Err: MINTEMP BED" - PROGMEM Language_Str MSG_ERR_Z_HOMING = _UxGT("归位 XY 先"); // "Home XY First" PROGMEM Language_Str MSG_HALTED = _UxGT("打印停机"); //"PRINTER HALTED" PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("请重置"); //"Please reset" PROGMEM Language_Str MSG_SHORT_DAY = _UxGT("天"); //"d" // One character only PROGMEM Language_Str MSG_SHORT_HOUR = _UxGT("时"); //"h" // One character only PROGMEM Language_Str MSG_SHORT_MINUTE = _UxGT("分"); //"m" // One character only PROGMEM Language_Str MSG_HEATING = _UxGT("加热中 ..."); //"Heating..." + PROGMEM Language_Str MSG_COOLING = _UxGT("冷却中 ..."); PROGMEM Language_Str MSG_BED_HEATING = _UxGT("加热热床中 ..."); //"Bed Heating..." + PROGMEM Language_Str MSG_BED_COOLING = _UxGT("热床冷却中 ..."); + PROGMEM Language_Str MSG_CHAMBER_HEATING = _UxGT("机箱加热中 ..."); + PROGMEM Language_Str MSG_CHAMBER_COOLING = _UxGT("机箱冷却中 ..."); PROGMEM Language_Str MSG_DELTA_CALIBRATE = _UxGT("⊿校准"); //"Delta Calibration" PROGMEM Language_Str MSG_DELTA_CALIBRATE_X = _UxGT("⊿校准X"); //"Calibrate X" PROGMEM Language_Str MSG_DELTA_CALIBRATE_Y = _UxGT("⊿校准Y"); //"Calibrate Y" @@ -312,6 +465,7 @@ namespace Language_zh_CN { PROGMEM Language_Str MSG_DELTA_SETTINGS = _UxGT("⊿设置"); // "Delta Settings" PROGMEM Language_Str MSG_DELTA_AUTO_CALIBRATE = _UxGT("⊿自动校准"); // "Auto Calibration" PROGMEM Language_Str MSG_DELTA_HEIGHT_CALIBRATE = _UxGT("设置⊿高度"); // "Set Delta Height" + PROGMEM Language_Str MSG_DELTA_Z_OFFSET_CALIBRATE = _UxGT("探针Z偏移量"); PROGMEM Language_Str MSG_DELTA_DIAG_ROD = _UxGT("⊿斜柱"); // "Diag Rod" PROGMEM Language_Str MSG_DELTA_HEIGHT = _UxGT("⊿高度"); // "Height" PROGMEM Language_Str MSG_DELTA_RADIUS = _UxGT("⊿半径"); // "Radius" @@ -328,10 +482,14 @@ namespace Language_zh_CN { PROGMEM Language_Str MSG_INFO_EXTRUDERS = _UxGT("挤出机"); //"Extruders" PROGMEM Language_Str MSG_INFO_BAUDRATE = _UxGT("波特率"); //"Baud" PROGMEM Language_Str MSG_INFO_PROTOCOL = _UxGT("协议"); //"Protocol" + PROGMEM Language_Str MSG_INFO_RUNAWAY_OFF = _UxGT("监控温度失控:关"); + PROGMEM Language_Str MSG_INFO_RUNAWAY_ON = _UxGT("监控温度失控:开"); + PROGMEM Language_Str MSG_HOTEND_IDLE_TIMEOUT = _UxGT("热端空闲超时"); + PROGMEM Language_Str MSG_CASE_LIGHT = _UxGT("外壳灯"); // "Case light" PROGMEM Language_Str MSG_CASE_LIGHT_BRIGHTNESS = _UxGT("灯亮度"); // "Light BRIGHTNESS" - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("打印机不正确"); // "The printer is incorrect" + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("打印机不正确"); // "The printer is incorrect" #if LCD_WIDTH >= 20 PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("打印计数"); //"Print Count" @@ -355,7 +513,9 @@ namespace Language_zh_CN { PROGMEM Language_Str MSG_DAC_PERCENT_Y = _UxGT("Y 驱动 %"); // "Y Driver %" PROGMEM Language_Str MSG_DAC_PERCENT_Z = _UxGT("Z 驱动 %"); // "Z Driver %" PROGMEM Language_Str MSG_DAC_PERCENT_E = _UxGT("E 驱动 %"); // "E Driver %" + PROGMEM Language_Str MSG_ERROR_TMC = _UxGT("TMC 连接错误"); PROGMEM Language_Str MSG_DAC_EEPROM_WRITE = _UxGT("保存驱动设置"); // "DAC EEPROM Write" + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER = _UxGT("更换料"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_PAUSE = _UxGT("打印已暂停"); // "PRINT PAUSED" PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_LOAD = _UxGT("装载丝料"); // "LOAD FILAMENT" PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_UNLOAD = _UxGT("卸载丝料"); // "UNLOAD FILAMENT" @@ -363,26 +523,115 @@ namespace Language_zh_CN { PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_PURGE = _UxGT("清除更多"); // "Purge more" PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_RESUME = _UxGT("恢复打印"); //"Resume print" PROGMEM Language_Str MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" 喷嘴: "); // " Nozzle: " - PROGMEM Language_Str MSG_LCD_HOMING_FAILED = _UxGT("归原位失败"); // "Homing failed" + PROGMEM Language_Str MSG_RUNOUT_SENSOR = _UxGT("断料传感器"); + PROGMEM Language_Str MSG_RUNOUT_DISTANCE_MM = _UxGT("断料距离mm"); + PROGMEM Language_Str MSG_KILL_HOMING_FAILED = _UxGT("归原位失败"); // "Homing failed" PROGMEM Language_Str MSG_LCD_PROBING_FAILED = _UxGT("探针探测失败"); // "Probing failed" - PROGMEM Language_Str MSG_M600_TOO_COLD = _UxGT("M600: 太凉"); // "M600: Too cold" + PROGMEM Language_Str MSG_MMU2_CHOOSE_FILAMENT_HEADER = _UxGT("选择料"); + PROGMEM Language_Str MSG_MMU2_MENU = _UxGT("MMU"); + PROGMEM Language_Str MSG_KILL_MMU2_FIRMWARE = _UxGT("升级MMU固件!"); + PROGMEM Language_Str MSG_MMU2_NOT_RESPONDING = _UxGT("MMU需要专注."); + PROGMEM Language_Str MSG_MMU2_RESUME = _UxGT("MMU恢复"); + PROGMEM Language_Str MSG_MMU2_RESUMING = _UxGT("MMU恢复中..."); + PROGMEM Language_Str MSG_MMU2_LOAD_FILAMENT = _UxGT("MMU加载"); + PROGMEM Language_Str MSG_MMU2_LOAD_ALL = _UxGT("MMU加载全部"); + PROGMEM Language_Str MSG_MMU2_LOAD_TO_NOZZLE = _UxGT("MMU加载到喷嘴"); + PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT = _UxGT("MMU弹出"); + PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT_N = _UxGT("MMU弹出 ~"); + PROGMEM Language_Str MSG_MMU2_UNLOAD_FILAMENT = _UxGT("MMU卸载"); + PROGMEM Language_Str MSG_MMU2_LOADING_FILAMENT = _UxGT("加载填充. %i..."); + PROGMEM Language_Str MSG_MMU2_EJECTING_FILAMENT = _UxGT("弹出填充. ..."); + PROGMEM Language_Str MSG_MMU2_UNLOADING_FILAMENT = _UxGT("卸载填充...."); + PROGMEM Language_Str MSG_MMU2_ALL = _UxGT("全部"); + PROGMEM Language_Str MSG_MMU2_FILAMENT_N = _UxGT("料 ~"); + PROGMEM Language_Str MSG_MMU2_RESET = _UxGT("复位MMU"); + PROGMEM Language_Str MSG_MMU2_RESETTING = _UxGT("MMU复位中..."); + PROGMEM Language_Str MSG_MMU2_EJECT_RECOVER = _UxGT("移出, 按下"); + + PROGMEM Language_Str MSG_MIX = _UxGT("混合"); + PROGMEM Language_Str MSG_MIX_COMPONENT_N = _UxGT("器件 ="); + PROGMEM Language_Str MSG_MIXER = _UxGT("混合器"); + PROGMEM Language_Str MSG_GRADIENT = _UxGT("梯度"); + PROGMEM Language_Str MSG_FULL_GRADIENT = _UxGT("全梯度"); + PROGMEM Language_Str MSG_TOGGLE_MIX = _UxGT("开关混合"); + PROGMEM Language_Str MSG_CYCLE_MIX = _UxGT("循环混合"); + PROGMEM Language_Str MSG_GRADIENT_MIX = _UxGT("梯度混合"); + PROGMEM Language_Str MSG_REVERSE_GRADIENT = _UxGT("反向梯度"); + PROGMEM Language_Str MSG_ACTIVE_VTOOL = _UxGT("激活 V-tool"); + PROGMEM Language_Str MSG_START_VTOOL = _UxGT("开始 V-tool"); + PROGMEM Language_Str MSG_END_VTOOL = _UxGT(" 结束 V-tool"); + PROGMEM Language_Str MSG_GRADIENT_ALIAS = _UxGT("别名 V-tool"); + PROGMEM Language_Str MSG_RESET_VTOOLS = _UxGT("复位 V-tools"); + PROGMEM Language_Str MSG_COMMIT_VTOOL = _UxGT("提交 V-tool Mix"); + PROGMEM Language_Str MSG_VTOOLS_RESET = _UxGT("V-tools 已复位"); + PROGMEM Language_Str MSG_START_Z = _UxGT("开始 Z:"); + PROGMEM Language_Str MSG_END_Z = _UxGT(" 结束 Z:"); + + PROGMEM Language_Str MSG_GAMES = _UxGT("游戏"); + PROGMEM Language_Str MSG_BRICKOUT = _UxGT("敲方块"); + PROGMEM Language_Str MSG_INVADERS = _UxGT("入侵者"); + PROGMEM Language_Str MSG_SNAKE = _UxGT("贪吃蛇"); + PROGMEM Language_Str MSG_MAZE = _UxGT("迷宫"); + + PROGMEM Language_Str MSG_BAD_PAGE = _UxGT("错误页面索引"); + PROGMEM Language_Str MSG_BAD_PAGE_SPEED = _UxGT("错误页面速度"); + + // + // Filament Change screens show up to 3 lines on a 4-line display + // ...or up to 2 lines on a 3-line display + // #if LCD_HEIGHT >= 4 + PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_2_LINE("按下按钮", "恢复打印")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("停靠中...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_3_LINE("等待开始", "丝料", "变更")); // "Wait for start of the filament change" - PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_2_LINE("等待", "卸下丝料")); // "Wait for filament unload" - PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_3_LINE("插入丝料", "并按键", "来继续 ...")); // "Insert filament and press button to continue..." + PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_3_LINE("插入料", "并按下", "以继续")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_2_LINE("按下按钮来", "加热喷嘴.")); // "Press button to heat nozzle." PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEATING = _UxGT(MSG_2_LINE("加热喷嘴", "请等待 ...")); // "Heating nozzle Please wait..." + PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_2_LINE("等待", "卸下丝料")); // "Wait for filament unload" PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_2_LINE("等待", "进料")); // "Wait for filament load" PROGMEM Language_Str MSG_FILAMENT_CHANGE_PURGE = _UxGT(MSG_2_LINE("等待", "丝料清除")); // "Wait for filament purge" + PROGMEM Language_Str MSG_FILAMENT_CHANGE_CONT_PURGE = _UxGT(MSG_2_LINE("按下已完成", "料的清洗")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_2_LINE("等待打印", "恢复")); // "Wait for print to resume" #else + PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_1_LINE("按下继续")); + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("停靠中...")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_1_LINE("请等待 ...")); //"Please wait..." - PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_1_LINE("退出中 ...")); //"Ejecting..." PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_1_LINE("插入并单击")); //"Insert and Click" + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_1_LINE("按下加热")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEATING = _UxGT(MSG_1_LINE("加热中 ...")); // "Heating..." + PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_1_LINE("退出中 ...")); //"Ejecting..." PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_1_LINE("装载中 ...")); //"Loading..." PROGMEM Language_Str MSG_FILAMENT_CHANGE_PURGE = _UxGT(MSG_1_LINE("清除中 ...")); // "Purging..." + PROGMEM Language_Str MSG_FILAMENT_CHANGE_CONT_PURGE = _UxGT(MSG_1_LINE("按下完成")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_1_LINE("恢复中 ...")); //"Resuming..." #endif + PROGMEM Language_Str MSG_TMC_DRIVERS = _UxGT("TMC驱动器"); + PROGMEM Language_Str MSG_TMC_CURRENT = _UxGT("驱动电流"); + PROGMEM Language_Str MSG_TMC_HYBRID_THRS = _UxGT("混合阈值"); + PROGMEM Language_Str MSG_TMC_HOMING_THRS = _UxGT("无感回零"); + PROGMEM Language_Str MSG_TMC_STEPPING_MODE = _UxGT("步进模式"); + PROGMEM Language_Str MSG_TMC_STEALTH_ENABLED = _UxGT("StealthChop已使能"); + PROGMEM Language_Str MSG_SERVICE_RESET = _UxGT("复位"); + PROGMEM Language_Str MSG_SERVICE_IN = _UxGT(" 在:"); + PROGMEM Language_Str MSG_BACKLASH = _UxGT("回差"); + PROGMEM Language_Str MSG_BACKLASH_A = LCD_STR_A; + PROGMEM Language_Str MSG_BACKLASH_B = LCD_STR_B; + PROGMEM Language_Str MSG_BACKLASH_C = LCD_STR_C; + PROGMEM Language_Str MSG_BACKLASH_CORRECTION = _UxGT("校正"); + PROGMEM Language_Str MSG_BACKLASH_SMOOTHING = _UxGT("平滑的"); + + PROGMEM Language_Str MSG_LEVEL_X_AXIS = _UxGT("X轴调平"); + PROGMEM Language_Str MSG_AUTO_CALIBRATE = _UxGT("自动校准"); + PROGMEM Language_Str MSG_HEATER_TIMEOUT = _UxGT("加热器超时"); + PROGMEM Language_Str MSG_REHEAT = _UxGT("重新加热"); + PROGMEM Language_Str MSG_REHEATING = _UxGT("重新加热中..."); } + +#if FAN_COUNT == 1 + #define MSG_FIRST_FAN_SPEED MSG_FAN_SPEED + #define MSG_EXTRA_FIRST_FAN_SPEED MSG_EXTRA_FAN_SPEED +#else + #define MSG_FIRST_FAN_SPEED MSG_FAN_SPEED_N + #define MSG_EXTRA_FIRST_FAN_SPEED MSG_EXTRA_FAN_SPEED_N +#endif diff --git a/Marlin/src/lcd/language/language_zh_TW.h b/Marlin/src/lcd/language/language_zh_TW.h index d0871f0e4604..7abf895d5457 100644 --- a/Marlin/src/lcd/language/language_zh_TW.h +++ b/Marlin/src/lcd/language/language_zh_TW.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,8 +25,7 @@ * Traditional Chinese * * LCD Menu Messages - * See also http://marlinfw.org/docs/development/lcd_language.html - * + * See also https://marlinfw.org/docs/development/lcd_language.html */ namespace Language_zh_TW { using namespace Language_en; // Inherit undefined strings from English @@ -35,11 +34,22 @@ namespace Language_zh_TW { PROGMEM Language_Str LANGUAGE = _UxGT("Traditional Chinese"); PROGMEM Language_Str WELCOME_MSG = MACHINE_NAME _UxGT("已就緒."); //" ready." - PROGMEM Language_Str MSG_BACK = _UxGT("返回"); // ”Back“ + PROGMEM Language_Str MSG_MARLIN = _UxGT("Marlin"); + PROGMEM Language_Str MSG_YES = _UxGT("是"); //"YES" + PROGMEM Language_Str MSG_NO = _UxGT("否"); //"NO" + PROGMEM Language_Str MSG_BACK = _UxGT("返回"); // "Back" + PROGMEM Language_Str MSG_MEDIA_ABORTING = _UxGT("正在中止..."); //"Aborting..." PROGMEM Language_Str MSG_MEDIA_INSERTED = _UxGT("記憶卡已插入"); //"Card inserted" PROGMEM Language_Str MSG_MEDIA_REMOVED = _UxGT("記憶卡被拔出"); //"Card removed" + PROGMEM Language_Str MSG_MEDIA_WAITING = _UxGT("等待記憶卡"); //"Waiting for media" + PROGMEM Language_Str MSG_MEDIA_READ_ERROR = _UxGT("記憶卡讀取錯誤"); //"Media read error" + PROGMEM Language_Str MSG_MEDIA_USB_REMOVED = _UxGT("USB裝置已移除"); //"USB device removed" + PROGMEM Language_Str MSG_MEDIA_USB_FAILED = _UxGT("USB啟動失敗"); //"USB start failed" PROGMEM Language_Str MSG_LCD_ENDSTOPS = _UxGT("擋塊"); //"Endstops" // Max length 8 characters + PROGMEM Language_Str MSG_LCD_SOFT_ENDSTOPS = _UxGT("軟體擋塊"); //"Soft Endstops" PROGMEM Language_Str MSG_MAIN = _UxGT("主選單"); //"Main" + PROGMEM Language_Str MSG_ADVANCED_SETTINGS = _UxGT("進階設置"); //"Advanced Settings" + PROGMEM Language_Str MSG_CONFIGURATION = _UxGT("設置"); //Configuration PROGMEM Language_Str MSG_AUTOSTART = _UxGT("自動開始"); //"Autostart" PROGMEM Language_Str MSG_DISABLE_STEPPERS = _UxGT("關閉步進馬達"); //"Disable steppers" PROGMEM Language_Str MSG_DEBUG_MENU = _UxGT("除錯選單"); // "Debug Menu" @@ -48,6 +58,7 @@ namespace Language_zh_TW { PROGMEM Language_Str MSG_AUTO_HOME_X = _UxGT("回X原點"); //"Home X" PROGMEM Language_Str MSG_AUTO_HOME_Y = _UxGT("回Y原點"); //"Home Y" PROGMEM Language_Str MSG_AUTO_HOME_Z = _UxGT("回Z原點"); //"Home Z" + PROGMEM Language_Str MSG_AUTO_Z_ALIGN = _UxGT("自動Z對齊"); //"Auto Z-Align" PROGMEM Language_Str MSG_LEVEL_BED_HOMING = _UxGT("平台調平XYZ歸原點"); //"Homing XYZ" PROGMEM Language_Str MSG_LEVEL_BED_WAITING = _UxGT("單擊開始熱床調平"); //"Click to Begin" PROGMEM Language_Str MSG_LEVEL_BED_NEXT_POINT = _UxGT("下個熱床調平點"); //"Next Point" @@ -56,21 +67,34 @@ namespace Language_zh_TW { PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("設置原點偏移"); //"Set home offsets" PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("偏移已啟用"); //"Offsets applied" PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("設置原點"); //"Set origin" - PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("預熱 ") PREHEAT_1_LABEL; //"Preheat PREHEAT_1_LABEL" - PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("預熱 ") PREHEAT_1_LABEL " ~"; //"Preheat PREHEAT_1_LABEL" - PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("預熱 ") PREHEAT_1_LABEL _UxGT(" 噴嘴"); //MSG_PREHEAT_1 " " - PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("預熱 ") PREHEAT_1_LABEL _UxGT(" 噴嘴 ~"); //MSG_PREHEAT_1 " " - PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("預熱 ") PREHEAT_1_LABEL _UxGT(" 全部"); //MSG_PREHEAT_1 " All" - PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("預熱 ") PREHEAT_1_LABEL _UxGT(" 熱床"); //MSG_PREHEAT_1 " Bed" - PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("預熱 ") PREHEAT_1_LABEL _UxGT(" 設置"); //MSG_PREHEAT_1 " conf" - PROGMEM Language_Str MSG_PREHEAT_2 = _UxGT("預熱 ") PREHEAT_2_LABEL; //"Preheat PREHEAT_2_LABEL" - PROGMEM Language_Str MSG_PREHEAT_2_H = _UxGT("預熱 ") PREHEAT_2_LABEL " ~"; //"Preheat PREHEAT_2_LABEL" - PROGMEM Language_Str MSG_PREHEAT_2_END = _UxGT("預熱 ") PREHEAT_2_LABEL _UxGT(" 噴嘴"); //MSG_PREHEAT_2 " " - PROGMEM Language_Str MSG_PREHEAT_2_END_E = _UxGT("預熱 ") PREHEAT_2_LABEL _UxGT(" 噴嘴 ~"); //MSG_PREHEAT_2 " " - PROGMEM Language_Str MSG_PREHEAT_2_ALL = _UxGT("預熱 ") PREHEAT_2_LABEL _UxGT(" 全部"); //MSG_PREHEAT_2 " All" - PROGMEM Language_Str MSG_PREHEAT_2_BEDONLY = _UxGT("預熱 ") PREHEAT_2_LABEL _UxGT(" 熱床"); //MSG_PREHEAT_2 " Bed" - PROGMEM Language_Str MSG_PREHEAT_2_SETTINGS = _UxGT("預熱 ") PREHEAT_2_LABEL _UxGT(" 設置"); //MSG_PREHEAT_2 " conf" + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("預熱 ") PREHEAT_1_LABEL; //"Preheat PREHEAT_1_LABEL" + PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("預熱 ") PREHEAT_1_LABEL " ~"; //"Preheat PREHEAT_1_LABEL" + PROGMEM Language_Str MSG_PREHEAT_1_END = _UxGT("預熱 ") PREHEAT_1_LABEL _UxGT(" 噴嘴"); //MSG_PREHEAT_1 " " + PROGMEM Language_Str MSG_PREHEAT_1_END_E = _UxGT("預熱 ") PREHEAT_1_LABEL _UxGT(" 噴嘴 ~"); //MSG_PREHEAT_1 " " + PROGMEM Language_Str MSG_PREHEAT_1_ALL = _UxGT("預熱 ") PREHEAT_1_LABEL _UxGT(" 全部"); //MSG_PREHEAT_1 " All" + PROGMEM Language_Str MSG_PREHEAT_1_BEDONLY = _UxGT("預熱 ") PREHEAT_1_LABEL _UxGT(" 熱床"); //MSG_PREHEAT_1 " Bed" + PROGMEM Language_Str MSG_PREHEAT_1_SETTINGS = _UxGT("預熱 ") PREHEAT_1_LABEL _UxGT(" 設置"); //MSG_PREHEAT_1 " conf" + + PROGMEM Language_Str MSG_PREHEAT_M = _UxGT("預熱 $"); //"Preheat PREHEAT_1_LABEL" + PROGMEM Language_Str MSG_PREHEAT_M_H = _UxGT("預熱 $ ~"); //"Preheat PREHEAT_1_LABEL" + PROGMEM Language_Str MSG_PREHEAT_M_END = _UxGT("預熱 $ 噴嘴"); //MSG_PREHEAT_1 " " + PROGMEM Language_Str MSG_PREHEAT_M_END_E = _UxGT("預熱 $ 噴嘴 ~"); //MSG_PREHEAT_1 " " + PROGMEM Language_Str MSG_PREHEAT_M_ALL = _UxGT("預熱 $ 全部"); //MSG_PREHEAT_1 " All" + PROGMEM Language_Str MSG_PREHEAT_M_BEDONLY = _UxGT("預熱 $ 熱床"); //MSG_PREHEAT_1 " Bed" + PROGMEM Language_Str MSG_PREHEAT_M_SETTINGS = _UxGT("預熱 $ 設置"); //MSG_PREHEAT_1 " conf" + #endif + PROGMEM Language_Str MSG_PREHEAT_CUSTOM = _UxGT("自定預熱"); //"Preheat Custom" PROGMEM Language_Str MSG_COOLDOWN = _UxGT("降溫"); //"Cooldown" + PROGMEM Language_Str MSG_LASER_MENU = _UxGT("激光控制"); //"Laser Control" + PROGMEM Language_Str MSG_LASER_OFF = _UxGT("激光 關"); //"Laser Off" + PROGMEM Language_Str MSG_LASER_ON = _UxGT("激光 開"); //"Laser On" + PROGMEM Language_Str MSG_LASER_POWER = _UxGT("激光電源"); //"Laser Power" + PROGMEM Language_Str MSG_SPINDLE_MENU = _UxGT("主軸控告制"); //"Spindle Control" + PROGMEM Language_Str MSG_SPINDLE_OFF = _UxGT("主軸 關"); //"Spindle Off" + PROGMEM Language_Str MSG_SPINDLE_ON = _UxGT("主軸 開"); //"Spindle On" + PROGMEM Language_Str MSG_SPINDLE_POWER = _UxGT("主軸電源"); //"Spindle Power" + PROGMEM Language_Str MSG_SPINDLE_REVERSE = _UxGT("主軸反轉"); //"Spindle Reverse" PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("電源打開"); //"Switch power on" PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("電源關閉"); //"Switch power off" PROGMEM Language_Str MSG_EXTRUDE = _UxGT("擠出"); //"Extrude" @@ -79,15 +103,31 @@ namespace Language_zh_TW { PROGMEM Language_Str MSG_BED_LEVELING = _UxGT("調平熱床"); //"Bed leveling" PROGMEM Language_Str MSG_LEVEL_BED = _UxGT("調平熱床"); //"Level bed" PROGMEM Language_Str MSG_LEVEL_CORNERS = _UxGT("調平邊角"); // "Level corners" - PROGMEM Language_Str MSG_NEXT_CORNER = _UxGT("下個邊角"); // "Next corner" + PROGMEM Language_Str MSG_MESH_EDITOR = _UxGT("網格編輯器"); //"Mesh Editor" PROGMEM Language_Str MSG_EDIT_MESH = _UxGT("編輯網格"); // "Edit Mesh" PROGMEM Language_Str MSG_EDITING_STOPPED = _UxGT("網格編輯已停止"); // "Mesh Editing Stopped" - PROGMEM Language_Str MSG_USER_MENU = _UxGT("客制命令"); // "Custom Commands" - + PROGMEM Language_Str MSG_PROBING_MESH = _UxGT("探測點"); //"Probing Point" + PROGMEM Language_Str MSG_MESH_X = _UxGT("索引 X"); //"Index X" + PROGMEM Language_Str MSG_MESH_Y = _UxGT("索引 Y"); //"Index Y" + PROGMEM Language_Str MSG_MESH_EDIT_Z = _UxGT("Z 值"); //"Z Value" + PROGMEM Language_Str MSG_USER_MENU = _UxGT("自定命令"); // "Custom Commands" + PROGMEM Language_Str MSG_M48_TEST = _UxGT("M48 探測測試"); //"M48 Probe Test" + PROGMEM Language_Str MSG_M48_POINT = _UxGT("M48 探測點"); //"M48 Point" + PROGMEM Language_Str MSG_M48_DEVIATION = _UxGT("偏差"); //"Deviation" + PROGMEM Language_Str MSG_IDEX_MENU = _UxGT("IDEX Mode"); + PROGMEM Language_Str MSG_OFFSETS_MENU = _UxGT("Tool Offsets"); + PROGMEM Language_Str MSG_IDEX_MODE_AUTOPARK = _UxGT("Auto-Park"); + PROGMEM Language_Str MSG_IDEX_MODE_DUPLICATE = _UxGT("Duplication"); + PROGMEM Language_Str MSG_IDEX_MODE_MIRRORED_COPY = _UxGT("Mirrored Copy"); + PROGMEM Language_Str MSG_IDEX_MODE_FULL_CTRL = _UxGT("Full Control"); + PROGMEM Language_Str MSG_HOTEND_OFFSET_X = _UxGT("2nd Nozzle X"); + PROGMEM Language_Str MSG_HOTEND_OFFSET_Y = _UxGT("2nd Nozzle Y"); + PROGMEM Language_Str MSG_HOTEND_OFFSET_Z = _UxGT("2nd Nozzle Z"); PROGMEM Language_Str MSG_UBL_DOING_G29 = _UxGT("執行G29"); // "Doing G29" PROGMEM Language_Str MSG_UBL_TOOLS = _UxGT("UBL工具"); // "UBL Tools" PROGMEM Language_Str MSG_UBL_LEVEL_BED = _UxGT("統一熱床調平(UBL)"); // "Unified Bed Leveling" + PROGMEM Language_Str MSG_LCD_TILTING_MESH = _UxGT("傾斜點"); //"Tilting Point" PROGMEM Language_Str MSG_UBL_MANUAL_MESH = _UxGT("手工建網"); // "Manually Build Mesh" PROGMEM Language_Str MSG_UBL_BC_INSERT = _UxGT("放置墊片並測量"); // "Place shim & measure" PROGMEM Language_Str MSG_UBL_BC_INSERT2 = _UxGT("測量"); // "Measure" @@ -95,23 +135,32 @@ namespace Language_zh_TW { PROGMEM Language_Str MSG_UBL_MOVING_TO_NEXT = _UxGT("移動到下一個"); // "Moving to next" PROGMEM Language_Str MSG_UBL_ACTIVATE_MESH = _UxGT("啟動UBL"); // "Activate UBL" PROGMEM Language_Str MSG_UBL_DEACTIVATE_MESH = _UxGT("關閉UBL"); // "Deactivate UBL" - PROGMEM Language_Str MSG_UBL_SET_TEMP_BED = _UxGT("設置熱床溫度"); // "Bed Temp" - PROGMEM Language_Str MSG_UBL_SET_TEMP_HOTEND = _UxGT("熱端溫度"); // "Hotend Temp" + PROGMEM Language_Str MSG_UBL_SET_TEMP_BED = _UxGT("置設熱床溫度"); // "Bed Temp" + PROGMEM Language_Str MSG_UBL_BED_TEMP_CUSTOM = _UxGT("置設熱床溫度"); //"Bed Temp") + PROGMEM Language_Str MSG_UBL_SET_TEMP_HOTEND = _UxGT("置設噴嘴溫度"); // "Hotend Temp" + PROGMEM Language_Str MSG_UBL_HOTEND_TEMP_CUSTOM = _UxGT("熱端溫度"); //"Hotend Temp" PROGMEM Language_Str MSG_UBL_MESH_EDIT = _UxGT("網格編輯"); // "Mesh Edit" PROGMEM Language_Str MSG_UBL_EDIT_CUSTOM_MESH = _UxGT("編輯客戶網格"); // "Edit Custom Mesh" PROGMEM Language_Str MSG_UBL_FINE_TUNE_MESH = _UxGT("細調網格"); // "Fine Tuning Mesh" PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("完成編輯網格"); // "Done Editing Mesh" PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("創設客戶網格"); // "Build Custom Mesh" PROGMEM Language_Str MSG_UBL_BUILD_MESH_MENU = _UxGT("創設網格"); // "Build Mesh" - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M1 = _UxGT("創設 ") PREHEAT_1_LABEL _UxGT(" 網格"); // "Build PREHEAT_1_LABEL Mesh" - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M2 = _UxGT("創設 ") PREHEAT_2_LABEL _UxGT(" 網格"); // "Build PREHEAT_2_LABEL Mesh" + #if PREHEAT_COUNT + PROGMEM Language_Str MSG_UBL_BUILD_MESH_M = _UxGT("創設 $ 網格"); // "Build PREHEAT_1_LABEL Mesh" + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("批准 $ 網格"); // "Validate PREHEAT_1_LABEL Mesh" + #endif PROGMEM Language_Str MSG_UBL_BUILD_COLD_MESH = _UxGT("創設冷網格"); // "Build Cold Mesh" PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_ADJUST = _UxGT("調整網格高度"); // "Adjust Mesh Height" PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_AMOUNT = _UxGT("高度合計"); // "Height Amount" PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_MENU = _UxGT("批准網格"); // "Validate Mesh" - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M1 = _UxGT("批准 ") PREHEAT_1_LABEL _UxGT(" 網格"); // "Validate PREHEAT_1_LABEL Mesh" - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M2 = _UxGT("批准 ") PREHEAT_2_LABEL _UxGT(" 網格"); // "Validate PREHEAT_2_LABEL Mesh" PROGMEM Language_Str MSG_UBL_VALIDATE_CUSTOM_MESH = _UxGT("批准客戶網格"); // "Validate Custom Mesh" + PROGMEM Language_Str MSG_G26_HEATING_BED = _UxGT("G26 加熱熱床"); //"G26 Heating Bed" + PROGMEM Language_Str MSG_G26_HEATING_NOZZLE = _UxGT("G26 加熱噴嘴"); //"G26 Heating Nozzle" + PROGMEM Language_Str MSG_G26_MANUAL_PRIME = _UxGT("手動填裝"); //"Manual priming..." + PROGMEM Language_Str MSG_G26_FIXED_LENGTH = _UxGT("固定距離填裝"); //"Fixed Length Prime" + PROGMEM Language_Str MSG_G26_PRIME_DONE = _UxGT("完成填裝"); //"Done Priming" + PROGMEM Language_Str MSG_G26_CANCELED = _UxGT("G26已取消"); //"G26 Canceled" + PROGMEM Language_Str MSG_G26_LEAVING = _UxGT("離開 G26"); //"Leaving G26" PROGMEM Language_Str MSG_UBL_CONTINUE_MESH = _UxGT("繼續熱床網格"); // "Continue Bed Mesh" PROGMEM Language_Str MSG_UBL_MESH_LEVELING = _UxGT("網格調平"); // "Mesh Leveling" PROGMEM Language_Str MSG_UBL_3POINT_MESH_LEVELING = _UxGT("三點調平"); // "3-Point Leveling" @@ -136,11 +185,12 @@ namespace Language_zh_TW { PROGMEM Language_Str MSG_UBL_STORAGE_SLOT = _UxGT("存儲槽"); // "Memory Slot" PROGMEM Language_Str MSG_UBL_LOAD_MESH = _UxGT("裝載熱床網格"); // "Load Bed Mesh" PROGMEM Language_Str MSG_UBL_SAVE_MESH = _UxGT("保存熱床網格"); // "Save Bed Mesh" - PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("M117 網格 %i 已裝載"); // "Mesh %i loaded" - PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("M117 網格 %i 已保存"); // "Mesh %i saved" + PROGMEM Language_Str MSG_MESH_LOADED = _UxGT("網格 %i 已裝載"); // "Mesh %i loaded" + PROGMEM Language_Str MSG_MESH_SAVED = _UxGT("網格 %i 已保存"); // "Mesh %i saved" PROGMEM Language_Str MSG_UBL_NO_STORAGE = _UxGT("沒有存儲"); // "No storage" PROGMEM Language_Str MSG_UBL_SAVE_ERROR = _UxGT("錯誤: UBL保存"); // "Err: UBL Save" PROGMEM Language_Str MSG_UBL_RESTORE_ERROR = _UxGT("錯誤: UBL還原"); // "Err: UBL Restore" + PROGMEM Language_Str MSG_UBL_Z_OFFSET = _UxGT("Z-偏移:"); //"Z-Offset: " PROGMEM Language_Str MSG_UBL_Z_OFFSET_STOPPED = _UxGT("Z偏移已停止"); // "Z-Offset Stopped" PROGMEM Language_Str MSG_UBL_STEP_BY_STEP_MENU = _UxGT("一步步UBL"); // "Step-By-Step UBL" PROGMEM Language_Str MSG_UBL_1_BUILD_COLD_MESH = _UxGT("1. 創設冷網格"); @@ -162,7 +212,7 @@ namespace Language_zh_TW { PROGMEM Language_Str MSG_SET_LEDS_INDIGO = _UxGT("青"); // "Indigo") PROGMEM Language_Str MSG_SET_LEDS_VIOLET = _UxGT("紫"); // "Violet") PROGMEM Language_Str MSG_SET_LEDS_WHITE = _UxGT("白"); // "White") - PROGMEM Language_Str MSG_SET_LEDS_DEFAULT = _UxGT("缺省"); // "Default") + PROGMEM Language_Str MSG_SET_LEDS_DEFAULT = _UxGT("復歸"); // "Default") PROGMEM Language_Str MSG_CUSTOM_LEDS = _UxGT("定制燈"); // "Custom Lights") PROGMEM Language_Str MSG_INTENSITY_R = _UxGT("紅飽和度"); // "Red Intensity") PROGMEM Language_Str MSG_INTENSITY_G = _UxGT("綠飽和度"); // "Green Intensity") @@ -176,7 +226,8 @@ namespace Language_zh_TW { PROGMEM Language_Str MSG_MOVE_Y = _UxGT("移動Y"); //"Move Y" PROGMEM Language_Str MSG_MOVE_Z = _UxGT("移動Z"); //"Move Z" PROGMEM Language_Str MSG_MOVE_E = _UxGT("擠出機"); //"Extruder" - PROGMEM Language_Str MSG_MOVE_EN = _UxGT("擠出機 *"); + PROGMEM Language_Str MSG_MOVE_EN = _UxGT("擠出機 *"); //"Extruder *" + PROGMEM Language_Str MSG_HOTEND_TOO_COLD = _UxGT("噴嘴溫度不夠"); //"Hotend too cold" PROGMEM Language_Str MSG_MOVE_Z_DIST = _UxGT("移動 %s mm"); //"Move 0.025mm" PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("移動 0.1 mm"); //"Move 0.1mm" PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("移動 1 mm"); //"Move 1mm" @@ -186,10 +237,12 @@ namespace Language_zh_TW { PROGMEM Language_Str MSG_NOZZLE = " " LCD_STR_THERMOMETER _UxGT(" 噴嘴"); //"Nozzle" 噴嘴 PROGMEM Language_Str MSG_NOZZLE_N = " " LCD_STR_THERMOMETER _UxGT(" 噴嘴 ~"); PROGMEM Language_Str MSG_BED = " " LCD_STR_THERMOMETER _UxGT(" 熱床"); //"Bed" + PROGMEM Language_Str MSG_CHAMBER = _UxGT("Enclosure"); PROGMEM Language_Str MSG_FAN_SPEED = _UxGT("風扇速率"); //"Fan speed" - PROGMEM Language_Str MSG_FAN_SPEED_N = _UxGT("風扇速率 ~"); + PROGMEM Language_Str MSG_FAN_SPEED_N = _UxGT("風扇速率 ="); + PROGMEM Language_Str MSG_STORED_FAN_N = _UxGT("Stored Fan ="); PROGMEM Language_Str MSG_EXTRA_FAN_SPEED = _UxGT("額外風扇速率"); // "Extra fan speed" - PROGMEM Language_Str MSG_EXTRA_FAN_SPEED_N = _UxGT("額外風扇速率 ~"); + PROGMEM Language_Str MSG_EXTRA_FAN_SPEED_N = _UxGT("額外風扇速率 ="); PROGMEM Language_Str MSG_FLOW = _UxGT("擠出速率"); PROGMEM Language_Str MSG_FLOW_N = _UxGT("擠出速率 ~"); //"Flow" PROGMEM Language_Str MSG_CONTROL = _UxGT("控制"); //"Control" @@ -197,8 +250,9 @@ namespace Language_zh_TW { PROGMEM Language_Str MSG_MAX = " " LCD_STR_THERMOMETER _UxGT(" 最大"); //" " LCD_STR_THERMOMETER " Max" PROGMEM Language_Str MSG_FACTOR = " " LCD_STR_THERMOMETER _UxGT(" 系數"); //" " LCD_STR_THERMOMETER " Fact" PROGMEM Language_Str MSG_AUTOTEMP = _UxGT("自動控溫"); //"Autotemp" - PROGMEM Language_Str MSG_LCD_ON = _UxGT("開"); //"On" - PROGMEM Language_Str MSG_LCD_OFF = _UxGT("關"); //"Off" + PROGMEM Language_Str MSG_LCD_ON = _UxGT("開 "); //"On" + PROGMEM Language_Str MSG_LCD_OFF = _UxGT("關 "); //"Off" + PROGMEM Language_Str MSG_SELECT = _UxGT("選擇"); //"Select" PROGMEM Language_Str MSG_SELECT_E = _UxGT("選擇 *"); PROGMEM Language_Str MSG_ACC = _UxGT("加速度"); //"Accel" acceleration @@ -207,6 +261,7 @@ namespace Language_zh_TW { PROGMEM Language_Str MSG_VB_JERK = _UxGT("軸抖動速率") LCD_STR_B; //"Vb-jerk" PROGMEM Language_Str MSG_VC_JERK = _UxGT("軸抖動速率") LCD_STR_C; //"Vc-jerk" PROGMEM Language_Str MSG_VE_JERK = _UxGT("擠出機抖動速率"); //"Ve-jerk" + PROGMEM Language_Str MSG_VELOCITY = _UxGT("速度"); // "Velocity" PROGMEM Language_Str MSG_VMAX_A = _UxGT("最大進料速率") LCD_STR_A; //"Vmax " max_feedrate_mm_s PROGMEM Language_Str MSG_VMAX_B = _UxGT("最大進料速率") LCD_STR_B; @@ -237,36 +292,65 @@ namespace Language_zh_TW { PROGMEM Language_Str MSG_FILAMENT_DIAM_E = _UxGT("絲料直徑 *"); PROGMEM Language_Str MSG_FILAMENT_UNLOAD = _UxGT("卸載 mm"); // "Unload mm" PROGMEM Language_Str MSG_FILAMENT_LOAD = _UxGT("装載 mm"); // "Load mm" + PROGMEM Language_Str MSG_ADVANCE_K = _UxGT("Advance K"); + PROGMEM Language_Str MSG_ADVANCE_K_E = _UxGT("Advance K *"); PROGMEM Language_Str MSG_CONTRAST = _UxGT("LCD對比度"); //"LCD contrast" PROGMEM Language_Str MSG_STORE_EEPROM = _UxGT("保存設置"); //"Store memory" PROGMEM Language_Str MSG_LOAD_EEPROM = _UxGT("載入設置"); //"Load memory" - PROGMEM Language_Str MSG_RESTORE_DEFAULTS = _UxGT("恢復安全值"); //"Restore Defaults" + PROGMEM Language_Str MSG_RESTORE_DEFAULTS = _UxGT("恢復安全值"); //"Restore failsafe" PROGMEM Language_Str MSG_INIT_EEPROM = _UxGT("初始化設置"); // "Initialize EEPROM" - PROGMEM Language_Str MSG_REFRESH = LCD_STR_REFRESH _UxGT("刷新"); //"Refresh" + PROGMEM Language_Str MSG_ERR_EEPROM_CRC = _UxGT("錯誤: EEPROM CRC"); //"Err: EEPROM CRC" + PROGMEM Language_Str MSG_ERR_EEPROM_INDEX = _UxGT("錯誤: EEPROM Index"); //"Err: EEPROM Index" + PROGMEM Language_Str MSG_ERR_EEPROM_VERSION = _UxGT("錯誤: EEPROM Version"); //"EEPROM Version" + PROGMEM Language_Str MSG_MEDIA_UPDATE = _UxGT("媒體更新"); //"Media Update" + PROGMEM Language_Str MSG_RESET_PRINTER = _UxGT("重置打印機"); //"Reset Printer + PROGMEM Language_Str MSG_REFRESH = _UxGT("刷新"); //"Refresh" PROGMEM Language_Str MSG_INFO_SCREEN = _UxGT("資訊界面"); //"Info screen" PROGMEM Language_Str MSG_PREPARE = _UxGT("準備"); //"Prepare" PROGMEM Language_Str MSG_TUNE = _UxGT("調整"); //"Tune" + PROGMEM Language_Str MSG_START_PRINT = _UxGT("開始列印"); //"Start Print" + PROGMEM Language_Str MSG_BUTTON_NEXT = _UxGT("下一個"); //"Next" + PROGMEM Language_Str MSG_BUTTON_INIT = _UxGT("初始 "); //"Init" + PROGMEM Language_Str MSG_BUTTON_STOP = _UxGT("停止 "); //"Stop" + PROGMEM Language_Str MSG_BUTTON_PRINT = _UxGT("列印 "); //"Print" + PROGMEM Language_Str MSG_BUTTON_RESET = _UxGT("復歸 "); //"Reset" + PROGMEM Language_Str MSG_BUTTON_CANCEL = _UxGT("放棄 "); //"Cancel" + PROGMEM Language_Str MSG_BUTTON_DONE = _UxGT("確認 "); //"Done" + PROGMEM Language_Str MSG_BUTTON_BACK = _UxGT("返回 "); //"Back" + PROGMEM Language_Str MSG_BUTTON_PROCEED = _UxGT("繼續 "); //"Proceed" PROGMEM Language_Str MSG_PAUSE_PRINT = _UxGT("暫停列印"); //"Pause print" PROGMEM Language_Str MSG_RESUME_PRINT = _UxGT("恢復列印"); //"Resume print" PROGMEM Language_Str MSG_STOP_PRINT = _UxGT("停止列印"); //"Stop print" + PROGMEM Language_Str MSG_PRINTING_OBJECT = _UxGT("列印物件"); //"Printing Object" + PROGMEM Language_Str MSG_CANCEL_OBJECT = _UxGT("中止物件"); //"Cancel Object" + PROGMEM Language_Str MSG_CANCEL_OBJECT_N = _UxGT("中止物件 ="); //"Cancel Object =" + PROGMEM Language_Str MSG_OUTAGE_RECOVERY = _UxGT("中斷恢復"); //"Outage Recovery" PROGMEM Language_Str MSG_MEDIA_MENU = _UxGT("從記憶卡上列印"); //"Print from SD" PROGMEM Language_Str MSG_NO_MEDIA = _UxGT("無記憶卡"); //"No SD card" PROGMEM Language_Str MSG_DWELL = _UxGT("休眠 ..."); //"Sleep..." PROGMEM Language_Str MSG_USERWAIT = _UxGT("點擊繼續 ..."); //"Click to resume..." PROGMEM Language_Str MSG_PRINT_PAUSED = _UxGT("列印已暫停"); // "Print paused" + PROGMEM Language_Str MSG_PRINTING = _UxGT("列印中 ..."); //"Printing..." PROGMEM Language_Str MSG_PRINT_ABORTED = _UxGT("已取消列印"); //"Print aborted" PROGMEM Language_Str MSG_NO_MOVE = _UxGT("無移動"); //"No move." PROGMEM Language_Str MSG_KILLED = _UxGT("已砍掉"); //"KILLED. " PROGMEM Language_Str MSG_STOPPED = _UxGT("已停止"); //"STOPPED. " PROGMEM Language_Str MSG_CONTROL_RETRACT = _UxGT("回縮長度mm"); //"Retract mm" retract_length, retract length (positive mm) PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("換手回抽長度mm"); //"Swap Re.mm" swap_retract_length, swap retract length (positive mm), for extruder change - PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("回縮速率mm/s"); //"Retract V" retract_feedrate_mm_s, feedrate for retracting (mm/s) + PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("回縮速率mm/s"); //"Retract V" retract_feedrate_mm_s, feedrate for retracting (mm/s) PROGMEM Language_Str MSG_CONTROL_RETRACT_ZHOP = _UxGT("Hop mm"); //"Hop mm" retract_zraise, retract Z-lift PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("回縮恢復長度mm"); //"UnRet +mm" retract_recover_extra, additional recover length (mm, added to retract length when recovering) PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("換手回縮恢復長度mm"); //"S UnRet+mm" swap_retract_recover_extra, additional swap recover length (mm, added to retract length when recovering from extruder change) - PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("回縮恢復後進料速率mm/s"); //"UnRet V" retract_recover_feedrate_mm_s, feedrate for recovering from retraction (mm/s) + PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVERF = _UxGT("回縮恢復後進料速率mm/s"); //"Unretract V" retract_recover_feedrate_mm_s, feedrate for recovering from retraction (mm/s) PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAPF = _UxGT("S UnRet V"); // "S UnRet V" - PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("自動回縮"); //"AutoRetr." autoretract_enabled, + PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("自動回縮"); //"Auto-Retract" autoretract_enabled, + PROGMEM Language_Str MSG_FILAMENT_SWAP_LENGTH = _UxGT("交換長度"); //"Swap Length" + PROGMEM Language_Str MSG_FILAMENT_PURGE_LENGTH = _UxGT("清除長度"); //"Purge Length" + PROGMEM Language_Str MSG_TOOL_CHANGE = _UxGT("交換工具"); //"Tool Change" + PROGMEM Language_Str MSG_TOOL_CHANGE_ZLIFT = _UxGT("Z軸提昇"); //"Z Raise" + PROGMEM Language_Str MSG_SINGLENOZZLE_PRIME_SPEED = _UxGT("最高速度"); //"Prime Speed" + PROGMEM Language_Str MSG_SINGLENOZZLE_RETRACT_SPEED = _UxGT("收回速度"); //"Retract Speed" + PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("噴嘴待機"); //"Nozzle Standby" PROGMEM Language_Str MSG_FILAMENTCHANGE = _UxGT("更換絲料"); //"Change filament" PROGMEM Language_Str MSG_FILAMENTCHANGE_E = _UxGT("更換絲料 *"); PROGMEM Language_Str MSG_FILAMENTLOAD = _UxGT("裝載絲料"); // "Load filament" @@ -274,36 +358,46 @@ namespace Language_zh_TW { PROGMEM Language_Str MSG_FILAMENTUNLOAD = _UxGT("卸載絲料"); // "Unload filament" PROGMEM Language_Str MSG_FILAMENTUNLOAD_E = _UxGT("卸載絲料 *"); // "Unload filament" PROGMEM Language_Str MSG_FILAMENTUNLOAD_ALL = _UxGT("卸載全部"); // "Unload All" - PROGMEM Language_Str MSG_ATTACH_MEDIA = _UxGT("初始化記憶卡"); //"Init. SD card" + PROGMEM Language_Str MSG_INIT_MEDIA = _UxGT("初始化記憶卡"); //"Init. SD card" + PROGMEM Language_Str MSG_ATTACH_MEDIA = _UxGT("連接記憶卡"); //"Attach Media PROGMEM Language_Str MSG_CHANGE_MEDIA = _UxGT("更換記憶卡"); //"Change SD card" + PROGMEM Language_Str MSG_RELEASE_MEDIA = _UxGT("釋放媒體"); //"Release Media" PROGMEM Language_Str MSG_ZPROBE_OUT = _UxGT("Z探針在熱床之外"); //"Z probe out. bed" Z probe is not within the physical limits PROGMEM Language_Str MSG_SKEW_FACTOR = _UxGT("偏斜因數"); // "Skew Factor" - PROGMEM Language_Str MSG_BLTOUCH = _UxGT("BLTouch"); // "BLTouch" + PROGMEM Language_Str MSG_BLTOUCH_SELFTEST = _UxGT("BLTouch 自檢"); // "BLTouch Self-Test" PROGMEM Language_Str MSG_BLTOUCH_RESET = _UxGT("重置BLTouch"); // "Reset BLTouch" - PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("部署BLTouch"); // "Deploy BLTouch" PROGMEM Language_Str MSG_BLTOUCH_STOW = _UxGT("裝載BLTouch"); // "Stow BLTouch" + PROGMEM Language_Str MSG_BLTOUCH_DEPLOY = _UxGT("部署BLTouch"); // "Deploy BLTouch" + PROGMEM Language_Str MSG_HOME_FIRST = _UxGT("歸位 %s%s%s 先"); //"Home ... first" - PROGMEM Language_Str MSG_ZPROBE_ZOFFSET = _UxGT("Z偏移"); //"Z Offset" + PROGMEM Language_Str MSG_ZPROBE_OFFSETS = _UxGT("探針偏移"); //Probe Offsets + PROGMEM Language_Str MSG_ZPROBE_XOFFSET = _UxGT("探針X偏移量"); //Probe X Offset + PROGMEM Language_Str MSG_ZPROBE_YOFFSET = _UxGT("探針Y偏移量"); //Probe Y Offset + PROGMEM Language_Str MSG_ZPROBE_ZOFFSET = _UxGT("探針Z偏移量"); //Probe Z Offset PROGMEM Language_Str MSG_BABYSTEP_X = _UxGT("微量調整X軸"); //"Babystep X" lcd_babystep_x, Babystepping enables the user to control the axis in tiny amounts PROGMEM Language_Str MSG_BABYSTEP_Y = _UxGT("微量調整Y軸"); //"Babystep Y" PROGMEM Language_Str MSG_BABYSTEP_Z = _UxGT("微量調整Z軸"); //"Babystep Z" + PROGMEM Language_Str MSG_BABYSTEP_TOTAL = _UxGT("總計"); //"Total" PROGMEM Language_Str MSG_ENDSTOP_ABORT = _UxGT("擋塊終止"); //"Endstop abort" PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("加熱失敗"); //"Heating failed" - PROGMEM Language_Str MSG_ERR_REDUNDANT_TEMP = _UxGT("錯誤:REDUNDANT TEMP"); //"Err: REDUNDANT TEMP" - PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("溫控失控"); //"THERMAL RUNAWAY" + PROGMEM Language_Str MSG_ERR_REDUNDANT_TEMP = _UxGT("錯誤:冗餘溫度"); //"Err: REDUNDANT TEMP" + PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("溫度失控"); //"THERMAL RUNAWAY" + PROGMEM Language_Str MSG_THERMAL_RUNAWAY_BED = _UxGT("熱床溫度失控"); //"BED THERMAL RUNAWAY" + PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER = _UxGT("機箱溫度失控"); //"CHAMBER T. RUNAWAY" PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("錯誤:最高溫度"); //"Err: MAXTEMP" PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("錯誤:最低溫度"); //"Err: MINTEMP" - PROGMEM Language_Str MSG_ERR_MAXTEMP_BED = _UxGT("錯誤:最高熱床溫度"); //"Err: MAXTEMP BED" - PROGMEM Language_Str MSG_ERR_MINTEMP_BED = _UxGT("錯誤:最低熱床溫度"); //"Err: MINTEMP BED" - PROGMEM Language_Str MSG_ERR_Z_HOMING = _UxGT("歸位 XY 先"); //"Home XY First" PROGMEM Language_Str MSG_HALTED = _UxGT("印表機停機"); //"PRINTER HALTED" PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("請重置"); //"Please reset" PROGMEM Language_Str MSG_SHORT_DAY = _UxGT("天"); //"d" // One character only PROGMEM Language_Str MSG_SHORT_HOUR = _UxGT("時"); //"h" // One character only PROGMEM Language_Str MSG_SHORT_MINUTE = _UxGT("分"); //"m" // One character only PROGMEM Language_Str MSG_HEATING = _UxGT("加熱中 ..."); //"Heating..." + PROGMEM Language_Str MSG_COOLING = _UxGT("冷卻中 ..."); //"Cooling..." PROGMEM Language_Str MSG_BED_HEATING = _UxGT("加熱熱床中 ..."); //"Bed Heating..." + PROGMEM Language_Str MSG_BED_COOLING = _UxGT("熱床冷卻中 ..."); //"Bed Cooling..." + PROGMEM Language_Str MSG_CHAMBER_HEATING = _UxGT("機箱加熱中 .."); //"Chamber Heating..." + PROGMEM Language_Str MSG_CHAMBER_COOLING = _UxGT("機箱冷卻中 ..."); //Chamber Cooling... PROGMEM Language_Str MSG_DELTA_CALIBRATE = _UxGT("⊿校準"); //"Delta Calibration" PROGMEM Language_Str MSG_DELTA_CALIBRATE_X = _UxGT("⊿校準X"); //"Calibrate X" PROGMEM Language_Str MSG_DELTA_CALIBRATE_Y = _UxGT("⊿校準Y"); //"Calibrate Y" @@ -312,6 +406,7 @@ namespace Language_zh_TW { PROGMEM Language_Str MSG_DELTA_SETTINGS = _UxGT("⊿設置"); // "Delta Settings" PROGMEM Language_Str MSG_DELTA_AUTO_CALIBRATE = _UxGT("⊿自動校準"); // "Auto Calibration" PROGMEM Language_Str MSG_DELTA_HEIGHT_CALIBRATE = _UxGT("設置⊿高度"); // "Set Delta Height" + PROGMEM Language_Str MSG_DELTA_Z_OFFSET_CALIBRATE = _UxGT("Z偏移"); PROGMEM Language_Str MSG_DELTA_DIAG_ROD = _UxGT("⊿斜柱"); // "Diag Rod" PROGMEM Language_Str MSG_DELTA_HEIGHT = _UxGT("⊿高度"); // "Height" PROGMEM Language_Str MSG_DELTA_RADIUS = _UxGT("⊿半徑"); // "Radius" @@ -319,19 +414,21 @@ namespace Language_zh_TW { PROGMEM Language_Str MSG_INFO_PRINTER_MENU = _UxGT("印表機訊息"); //"Printer Info" PROGMEM Language_Str MSG_3POINT_LEVELING = _UxGT("三點調平"); // "3-Point Leveling" PROGMEM Language_Str MSG_LINEAR_LEVELING = _UxGT("線性調平"); // "Linear Leveling" - PROGMEM Language_Str MSG_BILINEAR_LEVELING = _UxGT("雙線性調平"); // "Bilinear Leveling" + PROGMEM Language_Str MSG_BILINEAR_LEVELING = _UxGT(" 雙線性調平"); // "Bilinear Leveling" PROGMEM Language_Str MSG_UBL_LEVELING = _UxGT("統一熱床調平(UBL)"); // "Unified Bed Leveling" PROGMEM Language_Str MSG_MESH_LEVELING = _UxGT("網格調平"); // "Mesh Leveling" PROGMEM Language_Str MSG_INFO_STATS_MENU = _UxGT("印表機統計"); //"Printer Stats" PROGMEM Language_Str MSG_INFO_BOARD_MENU = _UxGT("主板訊息"); //"Board Info" PROGMEM Language_Str MSG_INFO_THERMISTOR_MENU = _UxGT("溫度計"); //"Thermistors" - PROGMEM Language_Str MSG_INFO_EXTRUDERS = _UxGT("擠出機"); //"Extruders" + PROGMEM Language_Str MSG_INFO_EXTRUDERS = _UxGT(" 擠出機"); //"Extruders" PROGMEM Language_Str MSG_INFO_BAUDRATE = _UxGT("傳輸率"); //"Baud" PROGMEM Language_Str MSG_INFO_PROTOCOL = _UxGT("協議"); //"Protocol" + PROGMEM Language_Str MSG_INFO_RUNAWAY_OFF = _UxGT("監測溫度失控:關"); //"Runaway Watch: OFF" + PROGMEM Language_Str MSG_INFO_RUNAWAY_ON = _UxGT("監測溫度失控:開"); //"Runaway Watch: ON" + PROGMEM Language_Str MSG_CASE_LIGHT = _UxGT("外殼燈"); // "Case light" PROGMEM Language_Str MSG_CASE_LIGHT_BRIGHTNESS = _UxGT("燈亮度"); // "Light BRIGHTNESS" - - PROGMEM Language_Str MSG_EXPECTED_PRINTER = _UxGT("打印機不正確"); // "The printer is incorrect" + PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("打印機不正確"); // "The printer is incorrect" #if LCD_WIDTH >= 20 PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("列印計數"); //"Print Count" @@ -351,11 +448,14 @@ namespace Language_zh_TW { PROGMEM Language_Str MSG_INFO_MAX_TEMP = _UxGT("最高溫度"); //"Max Temp" PROGMEM Language_Str MSG_INFO_PSU = _UxGT("電源供應"); //"Power Supply" PROGMEM Language_Str MSG_DRIVE_STRENGTH = _UxGT("驅動力度"); // "Drive Strength" - PROGMEM Language_Str MSG_DAC_PERCENT_X = _UxGT("X 驅動 %"); // "X Driver %" - PROGMEM Language_Str MSG_DAC_PERCENT_Y = _UxGT("Y 驅動 %"); // "Y Driver %" - PROGMEM Language_Str MSG_DAC_PERCENT_Z = _UxGT("Z 驅動 %"); // "Z Driver %" - PROGMEM Language_Str MSG_DAC_PERCENT_E = _UxGT("E 驅動 %"); // "E Driver %" + PROGMEM Language_Str MSG_DAC_PERCENT = _UxGT("驅動 %"); // "Driver %" + PROGMEM Language_Str MSG_DAC_PERCENT_X = _UxGT("X 驅動 %"); //X Driver % + PROGMEM Language_Str MSG_DAC_PERCENT_Y = _UxGT("Y 驅動 %"); //Y Driver % + PROGMEM Language_Str MSG_DAC_PERCENT_Z = _UxGT("Z 驅動 %"); //Z Driver % + PROGMEM Language_Str MSG_DAC_PERCENT_E = _UxGT("E 驅動 %"); //E Driver % + PROGMEM Language_Str MSG_ERROR_TMC = _UxGT("TMC連接錯誤"); //"TMC CONNECTION ERROR" PROGMEM Language_Str MSG_DAC_EEPROM_WRITE = _UxGT("保存驅動設置"); // "DAC EEPROM Write" + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER = _UxGT("更換絲料"); //"FILAMENT CHANGE" PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_PAUSE = _UxGT("列印已暫停"); // "PRINT PAUSED" PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_LOAD = _UxGT("裝載絲料"); // "LOAD FILAMENT" PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER_UNLOAD = _UxGT("卸載絲料"); // "UNLOAD FILAMENT" @@ -363,26 +463,46 @@ namespace Language_zh_TW { PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_PURGE = _UxGT("清除更多"); // "Purge more" PROGMEM Language_Str MSG_FILAMENT_CHANGE_OPTION_RESUME = _UxGT("恢復列印"); //"Resume print" PROGMEM Language_Str MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" 噴嘴: "); // " Nozzle: " - PROGMEM Language_Str MSG_LCD_HOMING_FAILED = _UxGT("歸原位失敗"); // "Homing failed" + PROGMEM Language_Str MSG_RUNOUT_SENSOR = _UxGT("斷絲偵測"); //"Runout Sensor" + PROGMEM Language_Str MSG_RUNOUT_DISTANCE_MM = _UxGT("絲距離mm"); //"Runout Dist mm" + PROGMEM Language_Str MSG_KILL_HOMING_FAILED = _UxGT("歸原位失敗"); // "Homing failed" PROGMEM Language_Str MSG_LCD_PROBING_FAILED = _UxGT("探針探測失敗"); // "Probing failed" - PROGMEM Language_Str MSG_M600_TOO_COLD = _UxGT("M600: 太冷"); // "M600: Too cold" + // + // Filament Change screens show up to 3 lines on a 4-line display + // ...or up to 2 lines on a 3-line display + // #if LCD_HEIGHT >= 4 + PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_2_LINE("按下按鈕", "恢復列印")); //"Press Button to resume print" + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("停車中 ...")); //"Parking..." PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_3_LINE("等待開始", "絲料", "變更")); //"Wait for start of the filament change" PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_2_LINE("等待", "卸下絲料")); //"Wait for filament unload" PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_3_LINE("插入絲料", "並按鍵", "繼續 ...")); //"Insert filament and press button to continue..." - PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_2_LINE("按下按鈕來", "加熱噴嘴.")); // "Press button to heat nozzle." + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_2_LINE("按下按鈕", "加熱噴嘴.")); // "Press button to heat nozzle." PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEATING = _UxGT(MSG_2_LINE("加熱噴嘴", "請等待 ...")); // "Heating nozzle Please wait..." PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_2_LINE("等待", "進料")); //"Wait for filament load" PROGMEM Language_Str MSG_FILAMENT_CHANGE_PURGE = _UxGT(MSG_2_LINE("等待", "絲料清除")); // "Wait for filament purge" + PROGMEM Language_Str MSG_FILAMENT_CHANGE_CONT_PURGE = _UxGT(MSG_2_LINE("按下完成","絲料清除")); //"Press button to filament purge" PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_2_LINE("等待列印", "恢復")); //"Wait for print to resume" #else // LCD_HEIGHT < 4 + PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_1_LINE("按下繼續..")); //"Click to continue" + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("停車中 ...")); //"Parking..." PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_1_LINE("請等待 ...")); //"Please wait..." - PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_1_LINE("退出中 ...")); //"Ejecting..." PROGMEM Language_Str MSG_FILAMENT_CHANGE_INSERT = _UxGT(MSG_1_LINE("插入並點擊")); //"Insert and Click" - PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEATING = _UxGT(MSG_1_LINE("加熱中 ...")); // "Heating..." + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEAT = _UxGT(MSG_1_LINE("按下加熱..")); //"Click to heat" + PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEATING = _UxGT(MSG_1_LINE("加熱中 ...")); //"Heating..." + PROGMEM Language_Str MSG_FILAMENT_CHANGE_UNLOAD = _UxGT(MSG_1_LINE("退出中 ...")); //"Ejecting..." PROGMEM Language_Str MSG_FILAMENT_CHANGE_LOAD = _UxGT(MSG_1_LINE("載入中 ...")); //"Loading..." - PROGMEM Language_Str MSG_FILAMENT_CHANGE_PURGE = _UxGT(MSG_1_LINE("清除中 ...")); // "Purging..." + PROGMEM Language_Str MSG_FILAMENT_CHANGE_PURGE = _UxGT(MSG_1_LINE("清除中 ...")); //"Purging..." + PROGMEM Language_Str MSG_FILAMENT_CHANGE_CONT_PURGE = _UxGT(MSG_1_LINE("按下完成..")); //"Click to finish" PROGMEM Language_Str MSG_FILAMENT_CHANGE_RESUME = _UxGT(MSG_1_LINE("恢復中 ...")); //"Resuming..." #endif // LCD_HEIGHT < 4 } + +#if FAN_COUNT == 1 + #define MSG_FIRST_FAN_SPEED MSG_FAN_SPEED + #define MSG_EXTRA_FIRST_FAN_SPEED MSG_EXTRA_FAN_SPEED +#else + #define MSG_FIRST_FAN_SPEED MSG_FAN_SPEED_N + #define MSG_EXTRA_FIRST_FAN_SPEED MSG_EXTRA_FAN_SPEED_N +#endif diff --git a/Marlin/src/lcd/lcdprint.cpp b/Marlin/src/lcd/lcdprint.cpp index b19ab38edb24..e381c590f578 100644 --- a/Marlin/src/lcd/lcdprint.cpp +++ b/Marlin/src/lcd/lcdprint.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -26,38 +26,51 @@ #include "../inc/MarlinConfigPre.h" -#if HAS_SPI_LCD +#if HAS_WIRED_LCD #include "lcdprint.h" -#include "../core/language.h" /** * lcd_put_u8str_ind_P * Print a string with an index substituted within it */ -lcd_uint_t lcd_put_u8str_ind_P(PGM_P const pstr, const uint8_t ind, const lcd_uint_t maxlen/*=LCD_WIDTH*/) { +lcd_uint_t lcd_put_u8str_ind_P(PGM_P const pstr, const int8_t ind, PGM_P const inStr/*=nullptr*/, const lcd_uint_t maxlen/*=LCD_WIDTH*/) { uint8_t *p = (uint8_t*)pstr; - lcd_uint_t n = maxlen; - for (; n; n--) { + int8_t n = maxlen; + while (n > 0) { wchar_t ch; p = get_utf8_value_cb(p, read_byte_rom, &ch); if (!ch) break; if (ch == '=' || ch == '~' || ch == '*') { - if (ch == '*') { lcd_put_wchar('E'); n--; } - // lcd_put_int(ind); n--; if (ind >= 10) n--; - // if (ind >= 0) - { - lcd_put_wchar(ind + ((ch == '=') ? '0' : LCD_FIRST_TOOL)); - n--; + if (ind >= 0) { + if (ch == '*') { lcd_put_wchar('E'); n--; } + if (n) { + int8_t inum = ind + ((ch == '=') ? 0 : LCD_FIRST_TOOL); + if (inum >= 10) { + lcd_put_wchar('0' + (inum / 10)); n--; + inum %= 10; + } + if (n) { lcd_put_wchar('0' + inum); n--; } } - // else if (ind == -1) { PGM_P const b = GET_TEXT(MSG_BED); lcd_put_u8str_P(b); n -= utf8_strlen_P(b); } - // else if (ind == -2) { PGM_P const c = GET_TEXT(MSG_CHAMBER); lcd_put_u8str_P(c); n -= utf8_strlen_P(c); } - if (n) n -= lcd_put_u8str_max_P((PGM_P)p, n); - break; + } + else { + PGM_P const b = ind == -2 ? GET_TEXT(MSG_CHAMBER) : GET_TEXT(MSG_BED); + n -= lcd_put_u8str_max_P(b, n * (MENU_FONT_WIDTH)) / (MENU_FONT_WIDTH); + } + if (n) { + n -= lcd_put_u8str_max_P((PGM_P)p, n * (MENU_FONT_WIDTH)) / (MENU_FONT_WIDTH); + break; + } + } + else if (ch == '$' && inStr) { + n -= lcd_put_u8str_max_P(inStr, n * (MENU_FONT_WIDTH)) / (MENU_FONT_WIDTH); + } + else { + lcd_put_wchar(ch); + n--; } - lcd_put_wchar(ch); } return n; } -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD diff --git a/Marlin/src/lcd/lcdprint.h b/Marlin/src/lcd/lcdprint.h index 7128d79c5725..cf34a7ade92e 100644 --- a/Marlin/src/lcd/lcdprint.h +++ b/Marlin/src/lcd/lcdprint.h @@ -1,3 +1,25 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + /** * @file lcdprint.h * @brief LCD print api @@ -12,15 +34,74 @@ #include "../inc/MarlinConfig.h" -#if HAS_GRAPHICAL_LCD +#if HAS_MARLINUI_U8GLIB + #include "dogm/u8g_fontutf8.h" typedef u8g_uint_t lcd_uint_t; + typedef u8g_int_t lcd_int_t; + + // Only Western languages support big / small fonts + #if DISABLED(DISPLAY_CHARSET_ISO10646_1) + #undef USE_BIG_EDIT_FONT + #undef USE_SMALL_INFOFONT + #endif + + #define MENU_FONT_NAME ISO10646_1_5x7 + #define MENU_FONT_WIDTH 6 + #define MENU_FONT_ASCENT 10 + #define MENU_FONT_DESCENT 2 + #define MENU_FONT_HEIGHT (MENU_FONT_ASCENT + MENU_FONT_DESCENT) + + #if ENABLED(USE_BIG_EDIT_FONT) + #define EDIT_FONT_NAME u8g_font_9x18 + #define EDIT_FONT_WIDTH 9 + #define EDIT_FONT_ASCENT 10 + #define EDIT_FONT_DESCENT 3 + #else + #define EDIT_FONT_NAME MENU_FONT_NAME + #define EDIT_FONT_WIDTH MENU_FONT_WIDTH + #define EDIT_FONT_ASCENT MENU_FONT_ASCENT + #define EDIT_FONT_DESCENT MENU_FONT_DESCENT + #endif + #define EDIT_FONT_HEIGHT (EDIT_FONT_ASCENT + EDIT_FONT_DESCENT) + + // Get the Ascent, Descent, and total Height for the Info Screen font + #if ENABLED(USE_SMALL_INFOFONT) + extern const u8g_fntpgm_uint8_t u8g_font_6x9[]; + #define INFO_FONT_ASCENT 7 + #else + #define INFO_FONT_ASCENT 8 + #endif + #define INFO_FONT_DESCENT 2 + #define INFO_FONT_HEIGHT (INFO_FONT_ASCENT + INFO_FONT_DESCENT) + #define INFO_FONT_WIDTH 6 + + #define SETCURSOR(col, row) lcd_moveto((col) * (MENU_FONT_WIDTH), ((row) + 1) * (MENU_FONT_HEIGHT)) + #define SETCURSOR_RJ(len, row) lcd_moveto(LCD_PIXEL_WIDTH - (len) * (MENU_FONT_WIDTH), ((row) + 1) * (MENU_FONT_HEIGHT)) + #else + #define _UxGT(a) a typedef uint8_t lcd_uint_t; + typedef int8_t lcd_int_t; + + #define MENU_FONT_WIDTH 1 + #define MENU_FONT_HEIGHT 1 + #define EDIT_FONT_WIDTH 1 + #define EDIT_FONT_HEIGHT 1 + #define INFO_FONT_WIDTH 1 + #define INFO_FONT_HEIGHT 1 + #define LCD_PIXEL_WIDTH LCD_WIDTH + #define LCD_PIXEL_HEIGHT LCD_HEIGHT + + #define SETCURSOR(col, row) lcd_moveto(col, row) + #define SETCURSOR_RJ(len, row) SETCURSOR(LCD_WIDTH - (len), row) + #endif -#define START_OF_UTF8_CHAR(C) (((C) & 0xC0u) != 0x80u) +#define SETCURSOR_X(col) SETCURSOR(col, _lcdLineNr) +#define SETCURSOR_X_RJ(len) SETCURSOR_RJ(len, _lcdLineNr) +#define START_OF_UTF8_CHAR(C) (((C) & 0xC0u) != 0x80U) int lcd_glyph_height(); @@ -71,10 +152,10 @@ inline int lcd_put_u8str_P(const lcd_uint_t col, const lcd_uint_t row, PGM_P con return lcd_put_u8str_P(pstr); } -lcd_uint_t lcd_put_u8str_ind_P(PGM_P const pstr, const uint8_t ind, const lcd_uint_t maxlen=LCD_WIDTH); -inline lcd_uint_t lcd_put_u8str_ind_P(const lcd_uint_t col, const lcd_uint_t row, PGM_P const pstr, const uint8_t ind, const lcd_uint_t maxlen=LCD_WIDTH) { +lcd_uint_t lcd_put_u8str_ind_P(PGM_P const pstr, const int8_t ind, PGM_P const inStr=nullptr, const lcd_uint_t maxlen=LCD_WIDTH); +inline lcd_uint_t lcd_put_u8str_ind_P(const lcd_uint_t col, const lcd_uint_t row, PGM_P const pstr, const int8_t ind, PGM_P const inStr=nullptr, const lcd_uint_t maxlen=LCD_WIDTH) { lcd_moveto(col, row); - return lcd_put_u8str_ind_P(pstr, ind, maxlen); + return lcd_put_u8str_ind_P(pstr, ind, inStr, maxlen); } inline int lcd_put_u8str(const char* str) { return lcd_put_u8str_max(str, PIXEL_LEN_NOLIMIT); } diff --git a/Marlin/src/lcd/menu/game/brickout.cpp b/Marlin/src/lcd/menu/game/brickout.cpp index 50da0f9cc756..4bdc9243801e 100644 --- a/Marlin/src/lcd/menu/game/brickout.cpp +++ b/Marlin/src/lcd/menu/game/brickout.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -140,13 +140,13 @@ void BrickoutGame::game_screen() { // Draw bricks if (PAGE_CONTAINS(BRICK_TOP, BRICK_BOT)) { - for (uint8_t y = 0; y < BRICK_ROWS; ++y) { + LOOP_L_N(y, BRICK_ROWS) { const uint8_t yy = y * BRICK_H + BRICK_TOP; if (PAGE_CONTAINS(yy, yy + BRICK_H - 1)) { - for (uint8_t x = 0; x < BRICK_COLS; ++x) { + LOOP_L_N(x, BRICK_COLS) { if (TEST(bdat.bricks[y], x)) { const uint8_t xx = x * BRICK_W; - for (uint8_t v = 0; v < BRICK_H - 1; ++v) + LOOP_L_N(v, BRICK_H - 1) if (PAGE_CONTAINS(yy + v, yy + v)) u8g.drawHLine(xx, yy + v, BRICK_W - 1); } diff --git a/Marlin/src/lcd/menu/game/brickout.h b/Marlin/src/lcd/menu/game/brickout.h index 2d23bf4c6ebe..cf1fbc6d98bc 100644 --- a/Marlin/src/lcd/menu/game/brickout.h +++ b/Marlin/src/lcd/menu/game/brickout.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/lcd/menu/game/game.cpp b/Marlin/src/lcd/menu/game/game.cpp index 18fb3c63dc08..c14bd2a68df8 100644 --- a/Marlin/src/lcd/menu/game/game.cpp +++ b/Marlin/src/lcd/menu/game/game.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/lcd/menu/game/game.h b/Marlin/src/lcd/menu/game/game.h index 3ebee563dea6..e788f2980512 100644 --- a/Marlin/src/lcd/menu/game/game.h +++ b/Marlin/src/lcd/menu/game/game.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -53,18 +53,10 @@ // Pool game data to save SRAM union MarlinGameData { - #if ENABLED(MARLIN_BRICKOUT) - brickout_data_t brickout; - #endif - #if ENABLED(MARLIN_INVADERS) - invaders_data_t invaders; - #endif - #if ENABLED(MARLIN_SNAKE) - snake_data_t snake; - #endif - #if ENABLED(MARLIN_MAZE) - maze_data_t maze; - #endif + TERN_(MARLIN_BRICKOUT, brickout_data_t brickout); + TERN_(MARLIN_INVADERS, invaders_data_t invaders); + TERN_(MARLIN_SNAKE, snake_data_t snake); + TERN_(MARLIN_MAZE, maze_data_t maze); }; extern MarlinGameData marlin_game_data; diff --git a/Marlin/src/lcd/menu/game/invaders.cpp b/Marlin/src/lcd/menu/game/invaders.cpp index 487f5406716f..56e4c224dd14 100644 --- a/Marlin/src/lcd/menu/game/invaders.cpp +++ b/Marlin/src/lcd/menu/game/invaders.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -170,7 +170,7 @@ inline void update_invader_data() { uint8_t m = idat.bugs[y]; if (m) idat.botmost = y + 1; inv_mask |= m; - for (uint8_t x = 0; x < INVADER_COLS; ++x) + LOOP_L_N(x, INVADER_COLS) if (TEST(m, x)) idat.shooters[sc++] = (y << 4) | x; } idat.leftmost = 0; @@ -371,11 +371,11 @@ void InvadersGame::game_screen() { // Draw invaders if (PAGE_CONTAINS(idat.pos.y, idat.pos.y + idat.botmost * (INVADER_ROW_H) - 2 - 1)) { int8_t yy = idat.pos.y; - for (uint8_t y = 0; y < INVADER_ROWS; ++y) { + LOOP_L_N(y, INVADER_ROWS) { const uint8_t type = inv_type[y]; if (PAGE_CONTAINS(yy, yy + INVADER_H - 1)) { int8_t xx = idat.pos.x; - for (uint8_t x = 0; x < INVADER_COLS; ++x) { + LOOP_L_N(x, INVADER_COLS) { if (TEST(idat.bugs[y], x)) u8g.drawBitmapP(xx, yy, 2, INVADER_H, invader[type][idat.game_blink]); xx += INVADER_COL_W; diff --git a/Marlin/src/lcd/menu/game/invaders.h b/Marlin/src/lcd/menu/game/invaders.h index d2b8790ff080..c99e6c16ae76 100644 --- a/Marlin/src/lcd/menu/game/invaders.h +++ b/Marlin/src/lcd/menu/game/invaders.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/lcd/menu/game/maze.cpp b/Marlin/src/lcd/menu/game/maze.cpp index 9cfa5da4da6e..85f752ee7de5 100644 --- a/Marlin/src/lcd/menu/game/maze.cpp +++ b/Marlin/src/lcd/menu/game/maze.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -83,7 +83,7 @@ void MazeGame::game_screen() { if (PAGE_UNDER(HEADER_H)) lcd_put_int(0, HEADER_H - 1, score); // Draw the maze - // for (uint8_t n = 0; n < head_ind; ++n) { + // LOOP_L_N(n, head_ind) { // const pos_t &p = maze_walls[n], &q = maze_walls[n + 1]; // if (p.x == q.x) { // const int8_t y1 = GAMEY(_MIN(p.y, q.y)), y2 = GAMEY(_MAX(p.y, q.y)); diff --git a/Marlin/src/lcd/menu/game/maze.h b/Marlin/src/lcd/menu/game/maze.h index 7917bab0d89d..ff5dde09f5e1 100644 --- a/Marlin/src/lcd/menu/game/maze.h +++ b/Marlin/src/lcd/menu/game/maze.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/lcd/menu/game/snake.cpp b/Marlin/src/lcd/menu/game/snake.cpp index 8c5280b6898d..f8892a4e7a39 100644 --- a/Marlin/src/lcd/menu/game/snake.cpp +++ b/Marlin/src/lcd/menu/game/snake.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -84,14 +84,14 @@ void shorten_tail() { } if (shift) { sdat.head_ind--; - for (uint8_t i = 0; i <= sdat.head_ind; ++i) + LOOP_LE_N(i, sdat.head_ind) sdat.snake_tail[i] = sdat.snake_tail[i + 1]; } } // The food is on a line inline bool food_on_line() { - for (uint8_t n = 0; n < sdat.head_ind; ++n) { + LOOP_L_N(n, sdat.head_ind) { pos_t &p = sdat.snake_tail[n], &q = sdat.snake_tail[n + 1]; if (p.x == q.x) { if ((sdat.foodx == p.x - 1 || sdat.foodx == p.x) && WITHIN(sdat.foody, _MIN(p.y, q.y), _MAX(p.y, q.y))) @@ -151,7 +151,7 @@ bool snake_overlap() { // VERTICAL head segment? if (h1.x == h2.x) { // Loop from oldest to segment two away from head - for (uint8_t n = 0; n < sdat.head_ind - 2; ++n) { + LOOP_L_N(n, sdat.head_ind - 2) { // Segment p to q const pos_t &p = sdat.snake_tail[n], &q = sdat.snake_tail[n + 1]; if (p.x != q.x) { @@ -163,7 +163,7 @@ bool snake_overlap() { } else { // Loop from oldest to segment two away from head - for (uint8_t n = 0; n < sdat.head_ind - 2; ++n) { + LOOP_L_N(n, sdat.head_ind - 2) { // Segment p to q const pos_t &p = sdat.snake_tail[n], &q = sdat.snake_tail[n + 1]; if (p.y != q.y) { @@ -240,7 +240,7 @@ void SnakeGame::game_screen() { #if SNAKE_WH < 2 // At this scale just draw a line - for (uint8_t n = 0; n < sdat.head_ind; ++n) { + LOOP_L_N(n, sdat.head_ind) { const pos_t &p = sdat.snake_tail[n], &q = sdat.snake_tail[n + 1]; if (p.x == q.x) { const int8_t y1 = GAMEY(_MIN(p.y, q.y)), y2 = GAMEY(_MAX(p.y, q.y)); @@ -256,7 +256,7 @@ void SnakeGame::game_screen() { #elif SNAKE_WH == 2 // At this scale draw two lines - for (uint8_t n = 0; n < sdat.head_ind; ++n) { + LOOP_L_N(n, sdat.head_ind) { const pos_t &p = sdat.snake_tail[n], &q = sdat.snake_tail[n + 1]; if (p.x == q.x) { const int8_t y1 = GAMEY(_MIN(p.y, q.y)), y2 = GAMEY(_MAX(p.y, q.y)); @@ -275,7 +275,7 @@ void SnakeGame::game_screen() { #else // Draw a series of boxes - for (uint8_t n = 0; n < sdat.head_ind; ++n) { + LOOP_L_N(n, sdat.head_ind) { const pos_t &p = sdat.snake_tail[n], &q = sdat.snake_tail[n + 1]; if (p.x == q.x) { const int8_t y1 = _MIN(p.y, q.y), y2 = _MAX(p.y, q.y); diff --git a/Marlin/src/lcd/menu/game/snake.h b/Marlin/src/lcd/menu/game/snake.h index c846d5646647..09a3a722de1e 100644 --- a/Marlin/src/lcd/menu/game/snake.h +++ b/Marlin/src/lcd/menu/game/snake.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/lcd/menu/game/types.h b/Marlin/src/lcd/menu/game/types.h index 16ff8d82b675..f6e6c78aa063 100644 --- a/Marlin/src/lcd/menu/game/types.h +++ b/Marlin/src/lcd/menu/game/types.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/lcd/menu/menu.cpp b/Marlin/src/lcd/menu/menu.cpp index f1bcb970d413..5d67410351f6 100644 --- a/Marlin/src/lcd/menu/menu.cpp +++ b/Marlin/src/lcd/menu/menu.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -34,14 +34,6 @@ #include "../../libs/buzzer.h" #endif -#if ENABLED(EEPROM_SETTINGS) - #include "../../module/configuration_store.h" -#endif - -#if WATCH_HOTENDS || WATCH_BED - #include "../../module/temperature.h" -#endif - #if ENABLED(BABYSTEP_ZPROBE_OFFSET) #include "../../module/probe.h" #endif @@ -65,7 +57,8 @@ typedef struct { menuPosition screen_history[6]; uint8_t screen_history_depth = 0; -uint8_t MenuItemBase::itemIndex; // Index number for draw and action +int8_t MenuItemBase::itemIndex; // Index number for draw and action +PGM_P MenuItemBase::itemString; // A PSTR for substitution chimera_t editable; // Value Editing // Menu Edit Items @@ -76,9 +69,6 @@ int32_t MenuEditItemBase::minEditValue, screenFunc_t MenuEditItemBase::callbackFunc; bool MenuEditItemBase::liveEdit; -// Prevent recursion into screen handlers -bool no_reentry = false; - //////////////////////////////////////////// //////// Menu Navigation & History ///////// //////////////////////////////////////////// @@ -90,14 +80,9 @@ void MarlinUI::save_previous_screen() { screen_history[screen_history_depth++] = { currentScreen, encoderPosition, encoderTopLine, screen_items }; } -void MarlinUI::_goto_previous_screen( - #if ENABLED(TURBO_BACK_MENU_ITEM) - const bool is_back/*=false*/ - #endif -) { - #if DISABLED(TURBO_BACK_MENU_ITEM) - constexpr bool is_back = false; - #endif +void MarlinUI::_goto_previous_screen(TERN_(TURBO_BACK_MENU_ITEM, const bool is_back/*=false*/)) { + TERN(TURBO_BACK_MENU_ITEM,,constexpr bool is_back = false); + TERN_(HAS_TOUCH_XPT2046, on_edit_screen = false); if (screen_history_depth > 0) { menuPosition &sh = screen_history[--screen_history_depth]; goto_screen(sh.menu_function, @@ -110,12 +95,6 @@ void MarlinUI::_goto_previous_screen( return_to_status(); } -//////////////////////////////////////////// -/////////// Common Menu Actions //////////// -//////////////////////////////////////////// - -void MenuItem_gcode::action(PGM_P const, PGM_P const pgcode) { queue.inject_P(pgcode); } - //////////////////////////////////////////// /////////// Menu Editing Actions /////////// //////////////////////////////////////////// @@ -127,7 +106,7 @@ void MenuItem_gcode::action(PGM_P const, PGM_P const pgcode) { queue.inject_P(pg * * The prerequisite is that in the header the type was already declared: * - * DEFINE_MENU_EDIT_ITEM_TYPE(int16_t, int3, i16tostr3, 1) + * DEFINE_MENU_EDIT_ITEM_TYPE(int3, int16_t, i16tostr3rj, 1) * * For example, DEFINE_MENU_EDIT_ITEM(int3) expands into: * @@ -144,9 +123,7 @@ void MenuItem_gcode::action(PGM_P const, PGM_P const pgcode) { queue.inject_P(pg * MenuItem_int3::draw(encoderLine == _thisItemNr, _lcdLineNr, plabel, &feedrate_percentage, 10, 999) */ void MenuEditItemBase::edit_screen(strfunc_t strfunc, loadfunc_t loadfunc) { - #if ENABLED(TOUCH_BUTTONS) - ui.repeat_delay = BUTTON_DELAY_EDIT; - #endif + TERN_(HAS_TOUCH_XPT2046, ui.repeat_delay = BUTTON_DELAY_EDIT); if (int32_t(ui.encoderPosition) < 0) ui.encoderPosition = 0; if (int32_t(ui.encoderPosition) > maxEditValue) ui.encoderPosition = maxEditValue; if (ui.should_draw()) @@ -168,6 +145,7 @@ void MenuEditItemBase::goto_edit_screen( const screenFunc_t cb, // Callback after edit const bool le // Flag to call cb() during editing ) { + TERN_(HAS_TOUCH_XPT2046, ui.on_edit_screen = true); ui.screen_changed = true; ui.save_previous_screen(); ui.refresh(); @@ -181,34 +159,6 @@ void MenuEditItemBase::goto_edit_screen( liveEdit = le; } -// TODO: Remove these but test build size with and without -#define DEFINE_MENU_EDIT_ITEM(NAME) template class TMenuEditItem - -DEFINE_MENU_EDIT_ITEM(percent); // 100% right-justified -DEFINE_MENU_EDIT_ITEM(int3); // 123, -12 right-justified -DEFINE_MENU_EDIT_ITEM(int4); // 1234, -123 right-justified -DEFINE_MENU_EDIT_ITEM(int8); // 123, -12 right-justified -DEFINE_MENU_EDIT_ITEM(uint8); // 123 right-justified -DEFINE_MENU_EDIT_ITEM(uint16_3); // 123 right-justified -DEFINE_MENU_EDIT_ITEM(uint16_4); // 1234 right-justified -DEFINE_MENU_EDIT_ITEM(uint16_5); // 12345 right-justified -DEFINE_MENU_EDIT_ITEM(float3); // 123 right-justified -DEFINE_MENU_EDIT_ITEM(float52); // _2.34, 12.34, -2.34 or 123.45, -23.45 -DEFINE_MENU_EDIT_ITEM(float43); // 1.234 -DEFINE_MENU_EDIT_ITEM(float5); // 12345 right-justified -DEFINE_MENU_EDIT_ITEM(float5_25); // 12345 right-justified (25 increment) -DEFINE_MENU_EDIT_ITEM(float51); // 1234.5 right-justified -DEFINE_MENU_EDIT_ITEM(float41sign); // +123.4 -DEFINE_MENU_EDIT_ITEM(float51sign); // +1234.5 -DEFINE_MENU_EDIT_ITEM(float52sign); // +123.45 -DEFINE_MENU_EDIT_ITEM(long5); // 12345 right-justified -DEFINE_MENU_EDIT_ITEM(long5_25); // 12345 right-justified (25 increment) - -void MenuItem_bool::action(PGM_P const, bool * const ptr, screenFunc_t callback) { - *ptr ^= true; ui.refresh(); - if (callback) (*callback)(); -} - //////////////////////////////////////////// ///////////////// Menu Tree //////////////// //////////////////////////////////////////// @@ -225,13 +175,9 @@ bool printer_busy() { void MarlinUI::goto_screen(screenFunc_t screen, const uint16_t encoder/*=0*/, const uint8_t top/*=0*/, const uint8_t items/*=0*/) { if (currentScreen != screen) { - #if ENABLED(TOUCH_BUTTONS) - repeat_delay = BUTTON_DELAY_MENU; - #endif + TERN_(HAS_TOUCH_XPT2046, repeat_delay = BUTTON_DELAY_MENU); - #if ENABLED(LCD_SET_PROGRESS_MANUALLY) - progress_reset(); - #endif + TERN_(LCD_SET_PROGRESS_MANUALLY, progress_reset()); #if BOTH(DOUBLECLICK_FOR_Z_BABYSTEPPING, BABYSTEPPING) static millis_t doubleclick_expire_ms = 0; @@ -242,33 +188,15 @@ void MarlinUI::goto_screen(screenFunc_t screen, const uint16_t encoder/*=0*/, co doubleclick_expire_ms = millis() + DOUBLECLICK_MAX_INTERVAL; } else if (screen == status_screen && currentScreen == menu_main && PENDING(millis(), doubleclick_expire_ms)) { - - #if ENABLED(BABYSTEP_WITHOUT_HOMING) - constexpr bool can_babystep = true; - #else - const bool can_babystep = all_axes_known(); - #endif - #if ENABLED(BABYSTEP_ALWAYS_AVAILABLE) - constexpr bool should_babystep = true; - #else - const bool should_babystep = printer_busy(); - #endif - - if (should_babystep && can_babystep) { - screen = - #if ENABLED(BABYSTEP_ZPROBE_OFFSET) - lcd_babystep_zoffset - #else - lcd_babystep_z - #endif - ; - } - #if ENABLED(MOVE_Z_WHEN_IDLE) - else { - move_menu_scale = MOVE_Z_IDLE_MULTIPLICATOR; + if ( (ENABLED(BABYSTEP_WITHOUT_HOMING) || all_axes_known()) + && (ENABLED(BABYSTEP_ALWAYS_AVAILABLE) || printer_busy()) ) + screen = TERN(BABYSTEP_ZPROBE_OFFSET, lcd_babystep_zoffset, lcd_babystep_z); + else { + #if ENABLED(MOVE_Z_WHEN_IDLE) + ui.manual_move.menu_scale = MOVE_Z_IDLE_MULTIPLICATOR; screen = lcd_move_z; - } - #endif + #endif + } } #endif @@ -276,34 +204,25 @@ void MarlinUI::goto_screen(screenFunc_t screen, const uint16_t encoder/*=0*/, co encoderPosition = encoder; encoderTopLine = top; screen_items = items; - if (screen == status_screen) { + if (on_status_screen()) { defer_status_screen(false); - #if ENABLED(AUTO_BED_LEVELING_UBL) - ubl.lcd_map_control = false; - #endif + TERN_(AUTO_BED_LEVELING_UBL, ubl.lcd_map_control = false); screen_history_depth = 0; } clear_lcd(); // Re-initialize custom characters that may be re-used - #if HAS_CHARACTER_LCD - if (true - #if ENABLED(AUTO_BED_LEVELING_UBL) - && !ubl.lcd_map_control - #endif - ) set_custom_characters(screen == status_screen ? CHARSET_INFO : CHARSET_MENU); + #if HAS_MARLINUI_HD44780 + if (TERN1(AUTO_BED_LEVELING_UBL, !ubl.lcd_map_control)) + set_custom_characters(on_status_screen() ? CHARSET_INFO : CHARSET_MENU); #endif refresh(LCDVIEW_CALL_REDRAW_NEXT); screen_changed = true; - #if HAS_GRAPHICAL_LCD - drawing_screen = false; - #endif + TERN_(HAS_MARLINUI_U8GLIB, drawing_screen = false); - #if HAS_LCD_MENU - encoder_direction_normal(); - #endif + TERN_(HAS_LCD_MENU, encoder_direction_normal()); set_selection(false); } @@ -314,29 +233,18 @@ void MarlinUI::goto_screen(screenFunc_t screen, const uint16_t encoder/*=0*/, co //////////////////////////////////////////// // -// Display the synchronize screen until moves are -// finished, and don't return to the caller until -// done. ** This blocks the command queue! ** +// Display a "synchronize" screen with a custom message until +// all moves are finished. Go back to calling screen when done. // -static PGM_P sync_message; - -void MarlinUI::_synchronize() { - if (should_draw()) MenuItem_static::draw(LCD_HEIGHT >= 4, sync_message); - if (no_reentry) return; - // Make this the current handler till all moves are done - const screenFunc_t old_screen = currentScreen; - goto_screen(_synchronize); - no_reentry = true; - planner.synchronize(); // idle() is called until moves complete - no_reentry = false; - goto_screen(old_screen); -} - -// Display the synchronize screen with a custom message -// ** This blocks the command queue! ** void MarlinUI::synchronize(PGM_P const msg/*=nullptr*/) { - sync_message = msg ?: GET_TEXT(MSG_MOVING); - _synchronize(); + static PGM_P sync_message = msg ?: GET_TEXT(MSG_MOVING); + save_previous_screen(); + goto_screen([]{ + if (should_draw()) MenuItem_static::draw(LCD_HEIGHT >= 4, sync_message); + }); + defer_status_screen(); + planner.synchronize(); // idle() is called until moves complete + goto_previous_screen_no_defer(); } /** @@ -396,88 +304,49 @@ void scroll_screen(const uint8_t limit, const bool is_menu) { void lcd_babystep_zoffset() { if (ui.use_click()) return ui.goto_previous_screen_no_defer(); ui.defer_status_screen(); - #if ENABLED(BABYSTEP_HOTEND_Z_OFFSET) - const bool do_probe = (active_extruder == 0); - #else - constexpr bool do_probe = true; - #endif + const bool do_probe = DISABLED(BABYSTEP_HOTEND_Z_OFFSET) || active_extruder == 0; if (ui.encoderPosition) { - const int16_t babystep_increment = int16_t(ui.encoderPosition) * (BABYSTEP_MULTIPLICATOR_Z); + const int16_t babystep_increment = int16_t(ui.encoderPosition) * (BABYSTEP_SIZE_Z); ui.encoderPosition = 0; const float diff = planner.steps_to_mm[Z_AXIS] * babystep_increment, new_probe_offset = probe.offset.z + diff, - new_offs = - #if ENABLED(BABYSTEP_HOTEND_Z_OFFSET) - do_probe ? new_probe_offset : hotend_offset[active_extruder].z - diff - #else - new_probe_offset - #endif - ; + new_offs = TERN(BABYSTEP_HOTEND_Z_OFFSET + , do_probe ? new_probe_offset : hotend_offset[active_extruder].z - diff + , new_probe_offset + ); if (WITHIN(new_offs, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX)) { babystep.add_steps(Z_AXIS, babystep_increment); - if (do_probe) probe.offset.z = new_offs; - #if ENABLED(BABYSTEP_HOTEND_Z_OFFSET) - else hotend_offset[active_extruder].z = new_offs; - #endif + if (do_probe) + probe.offset.z = new_offs; + else + TERN(BABYSTEP_HOTEND_Z_OFFSET, hotend_offset[active_extruder].z = new_offs, NOOP); ui.refresh(LCDVIEW_CALL_REDRAW_NEXT); } } if (ui.should_draw()) { - #if ENABLED(BABYSTEP_HOTEND_Z_OFFSET) - if (!do_probe) - MenuEditItemBase::draw_edit_screen(GET_TEXT(MSG_HOTEND_OFFSET_Z), LCD_Z_OFFSET_FUNC(hotend_offset[active_extruder].z)); - else - #endif - MenuEditItemBase::draw_edit_screen(GET_TEXT(MSG_ZPROBE_ZOFFSET), LCD_Z_OFFSET_FUNC(probe.offset.z)); - - #if ENABLED(BABYSTEP_ZPROBE_GFX_OVERLAY) - if (do_probe) _lcd_zoffset_overlay_gfx(probe.offset.z); - #endif + if (do_probe) { + MenuEditItemBase::draw_edit_screen(GET_TEXT(MSG_ZPROBE_ZOFFSET), BABYSTEP_TO_STR(probe.offset.z)); + TERN_(BABYSTEP_ZPROBE_GFX_OVERLAY, _lcd_zoffset_overlay_gfx(probe.offset.z)); + } + else { + #if ENABLED(BABYSTEP_HOTEND_Z_OFFSET) + MenuEditItemBase::draw_edit_screen(GET_TEXT(MSG_HOTEND_OFFSET_Z), ftostr54sign(hotend_offset[active_extruder].z)); + #endif + } } } #endif // BABYSTEP_ZPROBE_OFFSET -#if ANY(AUTO_BED_LEVELING_UBL, PID_AUTOTUNE_MENU, ADVANCED_PAUSE_FEATURE) - - void lcd_enqueue_one_now(const char * const cmd) { - no_reentry = true; - queue.enqueue_one_now(cmd); - no_reentry = false; - } - - void lcd_enqueue_one_now_P(PGM_P const cmd) { - no_reentry = true; - queue.enqueue_now_P(cmd); - no_reentry = false; - } - -#endif - -#if ENABLED(EEPROM_SETTINGS) - void lcd_store_settings() { - const bool saved = settings.save(); - #if HAS_BUZZER - ui.completion_feedback(saved); - #endif - UNUSED(saved); - } - void lcd_load_settings() { - const bool loaded = settings.load(); - #if HAS_BUZZER - ui.completion_feedback(loaded); - #endif - UNUSED(loaded); - } -#endif - void _lcd_draw_homing() { - constexpr uint8_t line = (LCD_HEIGHT - 1) / 2; - if (ui.should_draw()) MenuItem_static::draw(line, GET_TEXT(MSG_LEVEL_BED_HOMING)); + if (ui.should_draw()) { + constexpr uint8_t line = (LCD_HEIGHT - 1) / 2; + MenuItem_static::draw(line, GET_TEXT(MSG_LEVEL_BED_HOMING)); + } } #if ENABLED(LCD_BED_LEVELING) || (HAS_LEVELING && DISABLED(SLIM_LCD_MENUS)) @@ -498,11 +367,19 @@ bool MarlinUI::update_selection() { return selection; } -void MenuItem_confirm::select_screen(PGM_P const yes, PGM_P const no, selectFunc_t yesFunc, selectFunc_t noFunc, PGM_P const pref, const char * const string/*=nullptr*/, PGM_P const suff/*=nullptr*/) { +void MenuItem_confirm::select_screen( + PGM_P const yes, PGM_P const no, + selectFunc_t yesFunc, selectFunc_t noFunc, + PGM_P const pref, const char * const string/*=nullptr*/, PGM_P const suff/*=nullptr*/ +) { const bool ui_selection = ui.update_selection(), got_click = ui.use_click(); if (got_click || ui.should_draw()) { draw_select_screen(yes, no, ui_selection, pref, string, suff); - if (got_click) { ui_selection ? yesFunc() : noFunc(); } + if (got_click) { + selectFunc_t callFunc = ui_selection ? yesFunc : noFunc; + if (callFunc) callFunc(); else ui.goto_previous_screen(); + } + ui.defer_status_screen(); } } diff --git a/Marlin/src/lcd/menu/menu.h b/Marlin/src/lcd/menu/menu.h index 5299fefde2b7..89970225adbe 100644 --- a/Marlin/src/lcd/menu/menu.h +++ b/Marlin/src/lcd/menu/menu.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -29,10 +29,6 @@ extern int8_t encoderLine, encoderTopLine, screen_items; -#if HOTENDS - constexpr int16_t heater_maxtemp[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP, HEATER_2_MAXTEMP, HEATER_3_MAXTEMP, HEATER_4_MAXTEMP, HEATER_5_MAXTEMP, HEATER_6_MAXTEMP, HEATER_7_MAXTEMP); -#endif - void scroll_screen(const uint8_t limit, const bool is_menu); bool printer_busy(); @@ -43,16 +39,14 @@ typedef void (*selectFunc_t)(); #define SS_INVERT 0x02 #define SS_DEFAULT SS_CENTER -#if HAS_GRAPHICAL_LCD && EITHER(BABYSTEP_ZPROBE_GFX_OVERLAY, MESH_EDIT_GFX_OVERLAY) +#if HAS_MARLINUI_U8GLIB && EITHER(BABYSTEP_ZPROBE_GFX_OVERLAY, MESH_EDIT_GFX_OVERLAY) void _lcd_zoffset_overlay_gfx(const float zvalue); #endif -#if Z_PROBE_OFFSET_RANGE_MIN >= -9 && Z_PROBE_OFFSET_RANGE_MAX <= 9 - #define LCD_Z_OFFSET_FUNC(N) ftostr54sign(N) - #define LCD_Z_OFFSET_TYPE float43 -#else - #define LCD_Z_OFFSET_FUNC(N) ftostr52sign(N) - #define LCD_Z_OFFSET_TYPE float52 +#if ENABLED(BABYSTEP_ZPROBE_OFFSET) && Z_PROBE_OFFSET_RANGE_MIN >= -9 && Z_PROBE_OFFSET_RANGE_MAX <= 9 + #define BABYSTEP_TO_STR(N) ftostr43sign(N) +#elif ENABLED(BABYSTEPPING) + #define BABYSTEP_TO_STR(N) ftostr53sign(N) #endif //////////////////////////////////////////// @@ -61,12 +55,14 @@ typedef void (*selectFunc_t)(); class MenuItemBase { public: - // An index to interject in the item label and for - // use by the action - static uint8_t itemIndex; + // Index to interject in the item label and/or for use by its action. + static int8_t itemIndex; + + // An optional pointer for use in display or by the action + static PGM_P itemString; // Store the index of the item ahead of use by indexed items - FORCE_INLINE static void init(const uint8_t ind) { itemIndex = ind; } + FORCE_INLINE static void init(const int8_t ind=0, PGM_P const pstr=nullptr) { itemIndex = ind; itemString = pstr; } // Draw an item either selected (pre_char) or not (space) with post_char static void _draw(const bool sel, const uint8_t row, PGM_P const pstr, const char pre_char, const char post_char); @@ -77,13 +73,24 @@ class MenuItemBase { } }; +// STATIC_ITEM(LABEL,...) class MenuItem_static : public MenuItemBase { public: - static void draw(const uint8_t row, PGM_P const pstr, const uint8_t style=SS_DEFAULT, const char * const valstr=nullptr); + static void draw(const uint8_t row, PGM_P const pstr, const uint8_t style=SS_DEFAULT, const char * const vstr=nullptr); +}; + +// BACK_ITEM(LABEL) +class MenuItem_back : public MenuItemBase { + public: + FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr) { + _draw(sel, row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0]); + } + // Back Item action goes back one step in history + FORCE_INLINE static void action(PGM_P const=nullptr) { ui.go_back(); } }; -// CONFIRM_ITEM(LABEL,Y,N,FY,FN,V...), -// YESNO_ITEM(LABEL,FY,FN,V...) +// CONFIRM_ITEM(LABEL,Y,N,FY,FN,...), +// YESNO_ITEM(LABEL,FY,FN,...) class MenuItem_confirm : public MenuItemBase { public: FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, ...) { @@ -119,60 +126,6 @@ class MenuItem_confirm : public MenuItemBase { } }; -// BACK_ITEM(LABEL) -class MenuItem_back : public MenuItemBase { - public: - FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr) { - _draw(sel, row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0]); - } - // Back Item action goes back one step in history - FORCE_INLINE static void action(PGM_P const=nullptr) { ui.go_back(); } -}; - -// SUBMENU(LABEL, screen_handler) -class MenuItem_submenu : public MenuItemBase { - public: - FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, ...) { - _draw(sel, row, pstr, '>', LCD_STR_ARROW_RIGHT[0]); - } - static inline void action(PGM_P const, const screenFunc_t func) { ui.save_previous_screen(); ui.goto_screen(func); } -}; - -// Any menu item that invokes an immediate action -class MenuItem_button : public MenuItemBase { - public: - // Button-y Items are selectable lines with no other indicator - static inline void draw(const bool sel, const uint8_t row, PGM_P const pstr, ...) { - _draw(sel, row, pstr, '>', ' '); - } -}; - -// GCODES_ITEM(LABEL, GCODES) -class MenuItem_gcode : public MenuItem_button { - public: - FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, ...) { - _draw(sel, row, pstr, '>', ' '); - } - static void action(PGM_P const, const char * const pgcode); - static inline void action(PGM_P const pstr, const uint8_t, const char * const pgcode) { action(pstr, pgcode); } -}; - -// ACTION_ITEM(LABEL, FUNC) -class MenuItem_function : public MenuItem_button { - public: - //static inline void action(PGM_P const, const uint8_t, const menuAction_t func) { (*func)(); }; - static inline void action(PGM_P const, const menuAction_t func) { (*func)(); }; -}; - -#if ENABLED(SDSUPPORT) - class CardReader; - class MenuItem_sdbase { - public: - // Implemented for HD44780 and DOGM - static void draw(const bool sel, const uint8_t row, PGM_P const pstr, CardReader &theCard, const bool isDir); - }; -#endif - //////////////////////////////////////////// ///////////// Edit Menu Items ////////////// //////////////////////////////////////////// @@ -219,7 +172,7 @@ class MenuEditItemBase : public MenuItemBase { public: // Implemented for HD44780 and DOGM // Draw the current item at specified row with edit data - static void draw(const bool sel, const uint8_t row, PGM_P const pstr, const char* const data, const bool pgm=false); + static void draw(const bool sel, const uint8_t row, PGM_P const pstr, const char* const inStr, const bool pgm=false); // Implemented for HD44780 and DOGM // This low-level method is good to draw from anywhere @@ -229,283 +182,15 @@ class MenuEditItemBase : public MenuItemBase { static inline void draw_edit_screen(const char* const value) { draw_edit_screen(editLabel, value); } }; -// Template for specific Menu Edit Item Types -template -class TMenuEditItem : MenuEditItemBase { - private: - typedef typename NAME::type_t type_t; - static inline float scale(const float value) { return NAME::scale(value); } - static inline float unscale(const float value) { return NAME::unscale(value); } - static const char* to_string(const int32_t value) { return NAME::strfunc(unscale(value)); } - static void load(void *ptr, const int32_t value) { *((type_t*)ptr) = unscale(value); } - public: - FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, type_t * const data, ...) { - MenuEditItemBase::draw(sel, row, pstr, NAME::strfunc(*(data))); - } - FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, type_t (*pget)(), ...) { - MenuEditItemBase::draw(sel, row, pstr, NAME::strfunc(pget())); - } - // Edit screen for this type of item - static void edit_screen() { MenuEditItemBase::edit_screen(to_string, load); } - static void action( - PGM_P const pstr, // Edit label - type_t * const ptr, // Value pointer - const type_t minValue, // Value range - const type_t maxValue, - const screenFunc_t callback=nullptr, // Value update callback - const bool live=false // Callback during editing - ) { - // Make sure minv and maxv fit within int32_t - const int32_t minv = _MAX(scale(minValue), INT32_MIN), - maxv = _MIN(scale(maxValue), INT32_MAX); - goto_edit_screen(pstr, ptr, minv, maxv - minv, scale(*ptr) - minv, - edit_screen, callback, live); - } -}; - -// Provide a set of Edit Item Types which encompass a primitive -// type, a string function, and a scale factor for edit and display. -// These items call the Edit Item draw method passing the prepared string. -#define DEFINE_MENU_EDIT_ITEM_TYPE(TYPE, NAME, FIX, STRFUNC, SCALE, V...) \ - struct MenuEditItemInfo_##NAME { \ - typedef TYPE type_t; \ - static inline float scale(const float value) { return value * (SCALE) + (V+0); } \ - static inline float unscale(const float value) { return value / (SCALE) + (V+0); } \ - static inline const char* strfunc(const float value) { return STRFUNC((TYPE)(FIX ? FIXFLOAT(value) : value)); } \ - }; \ - typedef TMenuEditItem MenuItem_##NAME - -// TYPE NAME STRFUNC SCALE -DEFINE_MENU_EDIT_ITEM_TYPE(uint8_t, percent, 0, ui8tostr4pct, 100.0/255, 0.5); // 100% right-justified -DEFINE_MENU_EDIT_ITEM_TYPE(int16_t, int3, 0, i16tostr3, 1 ); // 123, -12 right-justified -DEFINE_MENU_EDIT_ITEM_TYPE(int16_t, int4, 0, i16tostr4sign, 1 ); // 1234, -123 right-justified -DEFINE_MENU_EDIT_ITEM_TYPE(int8_t, int8, 0, i8tostr3, 1 ); // 123, -12 right-justified -DEFINE_MENU_EDIT_ITEM_TYPE(uint8_t, uint8, 0, ui8tostr3, 1 ); // 123 right-justified -DEFINE_MENU_EDIT_ITEM_TYPE(uint16_t, uint16_3, 0, ui16tostr3, 1 ); // 123 right-justified -DEFINE_MENU_EDIT_ITEM_TYPE(uint16_t, uint16_4, 0, ui16tostr4, 0.1 ); // 1234 right-justified -DEFINE_MENU_EDIT_ITEM_TYPE(uint16_t, uint16_5, 0, ui16tostr5, 0.01 ); // 12345 right-justified -DEFINE_MENU_EDIT_ITEM_TYPE(float, float3, 1, ftostr3, 1 ); // 123 right-justified -DEFINE_MENU_EDIT_ITEM_TYPE(float, float52, 1, ftostr42_52, 100 ); // _2.34, 12.34, -2.34 or 123.45, -23.45 -DEFINE_MENU_EDIT_ITEM_TYPE(float, float43, 1, ftostr43sign, 1000 ); // 1.234 -DEFINE_MENU_EDIT_ITEM_TYPE(float, float5, 1, ftostr5rj, 1 ); // 12345 right-justified -DEFINE_MENU_EDIT_ITEM_TYPE(float, float5_25, 1, ftostr5rj, 0.04f ); // 12345 right-justified (25 increment) -DEFINE_MENU_EDIT_ITEM_TYPE(float, float51, 1, ftostr51rj, 10 ); // 1234.5 right-justified -DEFINE_MENU_EDIT_ITEM_TYPE(float, float41sign, 1, ftostr41sign, 10 ); // +123.4 -DEFINE_MENU_EDIT_ITEM_TYPE(float, float51sign, 1, ftostr51sign, 10 ); // +1234.5 -DEFINE_MENU_EDIT_ITEM_TYPE(float, float52sign, 1, ftostr52sign, 100 ); // +123.45 -DEFINE_MENU_EDIT_ITEM_TYPE(uint32_t, long5, 0, ftostr5rj, 0.01f ); // 12345 right-justified -DEFINE_MENU_EDIT_ITEM_TYPE(uint32_t, long5_25, 0, ftostr5rj, 0.04f ); // 12345 right-justified (25 increment) - -class MenuItem_bool : public MenuEditItemBase { - public: - FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, const bool onoff) { - MenuEditItemBase::draw(sel, row, pstr, onoff ? GET_TEXT(MSG_LCD_ON) : GET_TEXT(MSG_LCD_OFF), true); - } - FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, bool * const data, ...) { - draw(sel, row, pstr, *data); - } - FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, PGM_P const, bool (*pget)(), ...) { - draw(sel, row, pstr, pget()); - } - static void action(PGM_P const pstr, bool * const ptr, const screenFunc_t callbackFunc=nullptr); -}; - -//////////////////////////////////////////// -//////////// Menu System Macros //////////// -//////////////////////////////////////////// - -/** - * SCREEN_OR_MENU_LOOP generates init code for a screen or menu - * - * encoderTopLine is the top menu line to display - * _lcdLineNr is the index of the LCD line (e.g., 0-3) - * _menuLineNr is the menu item to draw and process - * _thisItemNr is the index of each MENU_ITEM or STATIC_ITEM - */ -#define SCREEN_OR_MENU_LOOP(IS_MENU) \ - scroll_screen(IS_MENU ? 1 : LCD_HEIGHT, IS_MENU); \ - int8_t _menuLineNr = encoderTopLine, _thisItemNr; \ - bool _skipStatic = IS_MENU; UNUSED(_thisItemNr); \ - for (int8_t _lcdLineNr = 0; _lcdLineNr < LCD_HEIGHT; _lcdLineNr++, _menuLineNr++) { \ - _thisItemNr = 0 - -/** - * START_SCREEN Opening code for a screen having only static items. - * Do simplified scrolling of the entire screen. - * - * START_MENU Opening code for a screen with menu items. - * Scroll as-needed to keep the selected line in view. - */ -#define START_SCREEN() SCREEN_OR_MENU_LOOP(false) -#define START_MENU() SCREEN_OR_MENU_LOOP(true) -#define NEXT_ITEM() (++_thisItemNr) -#define SKIP_ITEM() NEXT_ITEM() -#define END_SCREEN() } screen_items = _thisItemNr -#define END_MENU() END_SCREEN(); UNUSED(_skipStatic) - -#if ENABLED(ENCODER_RATE_MULTIPLIER) - #define ENCODER_RATE_MULTIPLY(F) (ui.encoderRateMultiplierEnabled = F) - #define _MENU_ITEM_MULTIPLIER_CHECK(USE_MULTIPLIER) do{ if (USE_MULTIPLIER) ui.enable_encoder_multiplier(true); }while(0) - //#define ENCODER_RATE_MULTIPLIER_DEBUG // If defined, output the encoder steps per second value -#else - #define ENCODER_RATE_MULTIPLY(F) NOOP - #define _MENU_ITEM_MULTIPLIER_CHECK(USE_MULTIPLIER) +#if ENABLED(SDSUPPORT) + class CardReader; + class MenuItem_sdbase { + public: + // Implemented for HD44780 and DOGM + static void draw(const bool sel, const uint8_t row, PGM_P const pstr, CardReader &theCard, const bool isDir); + }; #endif -/** - * MENU_ITEM generates draw & handler code for a menu item, potentially calling: - * - * MenuItem_::draw(sel, row, label, arg3...) - * MenuItem_::action(arg3...) - * - * Examples: - * BACK_ITEM(MSG_INFO_SCREEN) - * MenuItem_back::action(plabel, ...) - * MenuItem_back::draw(sel, row, plabel, ...) - * - * ACTION_ITEM(MSG_PAUSE_PRINT, lcd_sdcard_pause) - * MenuItem_function::action(plabel, lcd_sdcard_pause) - * MenuItem_function::draw(sel, row, plabel, lcd_sdcard_pause) - * - * EDIT_ITEM(int3, MSG_SPEED, &feedrate_percentage, 10, 999) - * MenuItem_int3::action(plabel, &feedrate_percentage, 10, 999) - * MenuItem_int3::draw(sel, row, plabel, &feedrate_percentage, 10, 999) - */ - -#define _MENU_INNER_P(TYPE, USE_MULTIPLIER, PLABEL, V...) do { \ - PGM_P const plabel = PLABEL; \ - if (encoderLine == _thisItemNr && ui.use_click()) { \ - _MENU_ITEM_MULTIPLIER_CHECK(USE_MULTIPLIER); \ - MenuItem_##TYPE::action(plabel, ##V); \ - if (ui.screen_changed) return; \ - } \ - if (ui.should_draw()) \ - MenuItem_##TYPE::draw \ - (encoderLine == _thisItemNr, _lcdLineNr, plabel, ##V); \ -}while(0) - -#define _MENU_ITEM_P(TYPE, V...) do { \ - _skipStatic = false; \ - if (_menuLineNr == _thisItemNr) \ - _MENU_INNER_P(TYPE, ##V); \ - NEXT_ITEM(); \ -}while(0) - -// Indexed items set a global index value -#define _MENU_ITEM_N_P(TYPE, N, V...) do{ \ - _skipStatic = false; \ - if (_menuLineNr == _thisItemNr) { \ - MenuItemBase::init(N); \ - _MENU_INNER_P(TYPE, ##V); \ - } \ - NEXT_ITEM(); \ -}while(0) - -// STATIC_ITEM draws a styled string with no highlight. -// Parameters: label [, style [, char *value] ] - -#define STATIC_ITEM_INNER_P(PLABEL, V...) do{ \ - if (_skipStatic && encoderLine <= _thisItemNr) { \ - ui.encoderPosition += ENCODER_STEPS_PER_MENU_ITEM; \ - ++encoderLine; \ - } \ - if (ui.should_draw()) \ - MenuItem_static::draw(_lcdLineNr, PLABEL, ##V); \ -} while(0) - -#define STATIC_ITEM_P(PLABEL, V...) do{ \ - if (_menuLineNr == _thisItemNr) \ - STATIC_ITEM_INNER_P(PLABEL, ##V); \ - NEXT_ITEM(); \ -} while(0) - -#define STATIC_ITEM_N_P(PLABEL, N, V...) do{ \ - if (_menuLineNr == _thisItemNr) { \ - MenuItemBase::init(N); \ - STATIC_ITEM_INNER_P(PLABEL, ##V); \ - } \ - NEXT_ITEM(); \ -}while(0) - -#define STATIC_ITEM(LABEL, V...) STATIC_ITEM_P( GET_TEXT(LABEL), ##V) -#define STATIC_ITEM_N(LABEL, N, V...) STATIC_ITEM_N_P(GET_TEXT(LABEL), ##V) - -#define MENU_ITEM_P(TYPE, PLABEL, V...) _MENU_ITEM_P(TYPE, false, PLABEL, ##V) -#define MENU_ITEM(TYPE, LABEL, V...) MENU_ITEM_P(TYPE, GET_TEXT(LABEL), ##V) - -#define MENU_ITEM_N_P(TYPE, N, PLABEL, V...) _MENU_ITEM_N_P(TYPE, N, false, PLABEL, ##V) -#define MENU_ITEM_N(TYPE, N, LABEL, V...) MENU_ITEM_N_P(TYPE, N, GET_TEXT(LABEL), ##V) - -#define BACK_ITEM(LABEL) MENU_ITEM(back, LABEL) - -#define ACTION_ITEM_P(PLABEL, ACTION) MENU_ITEM_P(function, PLABEL, ACTION) -#define ACTION_ITEM(LABEL, ACTION) ACTION_ITEM_P(GET_TEXT(LABEL), ACTION) - -#define ACTION_ITEM_N_P(N, PLABEL, ACTION) MENU_ITEM_N_P(function, N, PLABEL, ACTION) -#define ACTION_ITEM_N(N, LABEL, ACTION) ACTION_ITEM_N_P(N, GET_TEXT(LABEL), ACTION) - -#define GCODES_ITEM_P(PLABEL, GCODES) MENU_ITEM_P(gcode, PLABEL, GCODES) -#define GCODES_ITEM(LABEL, GCODES) GCODES_ITEM_P(GET_TEXT(LABEL), GCODES) - -#define GCODES_ITEM_N_P(N, PLABEL, GCODES) MENU_ITEM_N_P(gcode, N, PLABEL, GCODES) -#define GCODES_ITEM_N(N, LABEL, GCODES) GCODES_ITEM_N_P(N, GET_TEXT(LABEL), GCODES) - -#define SUBMENU_P(PLABEL, DEST) MENU_ITEM_P(submenu, PLABEL, DEST) -#define SUBMENU(LABEL, DEST) SUBMENU_P(GET_TEXT(LABEL), DEST) - -#define SUBMENU_N_P(N, PLABEL, DEST) MENU_ITEM_N_P(submenu, N, PLABEL, DEST) -#define SUBMENU_N(N, LABEL, DEST) SUBMENU_N_P(N, GET_TEXT(LABEL), DEST) - -#define EDIT_ITEM_P(TYPE, PLABEL, V...) MENU_ITEM_P(TYPE, PLABEL, ##V) -#define EDIT_ITEM(TYPE, LABEL, V...) EDIT_ITEM_P(TYPE, GET_TEXT(LABEL), ##V) - -#define EDIT_ITEM_N_P(TYPE, N, PLABEL, V...) MENU_ITEM_N_P(TYPE, N, PLABEL, ##V) -#define EDIT_ITEM_N(TYPE, N, LABEL, V...) EDIT_ITEM_N_P(TYPE, N, GET_TEXT(LABEL), ##V) - -#define EDIT_ITEM_FAST_P(TYPE, PLABEL, V...) _MENU_ITEM_P(TYPE, true, PLABEL, ##V) -#define EDIT_ITEM_FAST(TYPE, LABEL, V...) EDIT_ITEM_FAST_P(TYPE, GET_TEXT(LABEL), ##V) - -#define EDIT_ITEM_FAST_N_P(TYPE, N, PLABEL, V...) _MENU_ITEM_N_P(TYPE, N, true, PLABEL, ##V) -#define EDIT_ITEM_FAST_N(TYPE, N, LABEL, V...) EDIT_ITEM_FAST_N_P(TYPE, N, GET_TEXT(LABEL), ##V) - -#define _CONFIRM_ITEM_INNER_P(PLABEL, V...) do { \ - if (encoderLine == _thisItemNr && ui.use_click()) { \ - ui.goto_screen([]{MenuItem_confirm::select_screen(V);}); \ - return; \ - } \ - if (ui.should_draw()) MenuItem_confirm::draw \ - (encoderLine == _thisItemNr, _lcdLineNr, PLABEL, ##V); \ -}while(0) - -#define _CONFIRM_ITEM_P(PLABEL, V...) do { \ - _skipStatic = false; \ - if (_menuLineNr == _thisItemNr) \ - _CONFIRM_ITEM_INNER_P(PLABEL, ##V); \ - NEXT_ITEM(); \ -}while(0) - -// Indexed items set a global index value -#define _CONFIRM_ITEM_N_P(N, V...) do{ \ - _skipStatic = false; \ - if (_menuLineNr == _thisItemNr) { \ - MenuItemBase::init(N); \ - _CONFIRM_ITEM_INNER_P(TYPE, ##V); \ - } \ - NEXT_ITEM(); \ -}while(0) - -#define CONFIRM_ITEM_P(PLABEL,A,B,V...) _CONFIRM_ITEM_P(PLABEL, GET_TEXT(A), GET_TEXT(B), ##V) -#define CONFIRM_ITEM(LABEL, V...) CONFIRM_ITEM_P(GET_TEXT(LABEL), ##V) - -#define YESNO_ITEM_P(PLABEL, V...) _CONFIRM_ITEM_P(PLABEL, ##V) -#define YESNO_ITEM(LABEL, V...) YESNO_ITEM_P(GET_TEXT(LABEL), ##V) - -#define CONFIRM_ITEM_N_P(N,PLABEL,A,B,V...) _CONFIRM_ITEM_N_P(N, PLABEL, GET_TEXT(A), GET_TEXT(B), ##V) -#define CONFIRM_ITEM_N(N,LABEL, V...) CONFIRM_ITEM_N_P(N, GET_TEXT(LABEL), ##V) - -#define YESNO_ITEM_N_P(N,PLABEL, V...) _CONFIRM_ITEM_N_P(N, PLABEL, ##V) -#define YESNO_ITEM_N(N,LABEL, V...) YESNO_ITEM_N_P(N, GET_TEXT(LABEL), ##V) - //////////////////////////////////////////// /////////////// Menu Screens /////////////// //////////////////////////////////////////// @@ -517,15 +202,6 @@ void menu_move(); void menu_media(); #endif -// First Fan Speed title in "Tune" and "Control>Temperature" menus -#if FAN_COUNT > 0 && HAS_FAN0 - #if FAN_COUNT > 1 - #define FAN_SPEED_1_SUFFIX " 1" - #else - #define FAN_SPEED_1_SUFFIX "" - #endif -#endif - //////////////////////////////////////////// //////// Menu Item Helper Functions //////// //////////////////////////////////////////// @@ -539,17 +215,12 @@ void _lcd_draw_homing(); void line_to_z(const float &z); #endif -#if ANY(AUTO_BED_LEVELING_UBL, PID_AUTOTUNE_MENU, ADVANCED_PAUSE_FEATURE) - void lcd_enqueue_one_now(const char * const cmd); - void lcd_enqueue_one_now_P(PGM_P const cmd); -#endif - -#if HAS_GRAPHICAL_LCD && EITHER(BABYSTEP_ZPROBE_GFX_OVERLAY, MESH_EDIT_GFX_OVERLAY) +#if HAS_MARLINUI_U8GLIB && EITHER(BABYSTEP_ZPROBE_GFX_OVERLAY, MESH_EDIT_GFX_OVERLAY) void _lcd_zoffset_overlay_gfx(const float zvalue); #endif -#if ENABLED(LEVEL_BED_CORNERS) - void _lcd_level_bed_corners(); +#if ENABLED(PROBE_OFFSET_WIZARD) + void goto_probe_offset_wizard(); #endif #if ENABLED(LCD_BED_LEVELING) || (HAS_LEVELING && DISABLED(SLIM_LCD_MENUS)) @@ -562,13 +233,19 @@ void _lcd_draw_homing(); #else void lcd_babystep_z(); #endif -#endif -#if ENABLED(EEPROM_SETTINGS) - void lcd_store_settings(); - void lcd_load_settings(); + #if ENABLED(BABYSTEP_MILLIMETER_UNITS) + #define BABYSTEP_SIZE_X int32_t((BABYSTEP_MULTIPLICATOR_XY) * planner.settings.axis_steps_per_mm[X_AXIS]) + #define BABYSTEP_SIZE_Y int32_t((BABYSTEP_MULTIPLICATOR_XY) * planner.settings.axis_steps_per_mm[Y_AXIS]) + #define BABYSTEP_SIZE_Z int32_t((BABYSTEP_MULTIPLICATOR_Z) * planner.settings.axis_steps_per_mm[Z_AXIS]) + #else + #define BABYSTEP_SIZE_X BABYSTEP_MULTIPLICATOR_XY + #define BABYSTEP_SIZE_Y BABYSTEP_MULTIPLICATOR_XY + #define BABYSTEP_SIZE_Z BABYSTEP_MULTIPLICATOR_Z + #endif + #endif -#if ENABLED(POWER_LOSS_RECOVERY) - void menu_job_recovery(); +#if ENABLED(TOUCH_SCREEN_CALIBRATION) + void touch_screen_calibration(); #endif diff --git a/Marlin/src/lcd/menu/menu_addon.h b/Marlin/src/lcd/menu/menu_addon.h index 5f338c571abf..73e7061bf32c 100644 --- a/Marlin/src/lcd/menu/menu_addon.h +++ b/Marlin/src/lcd/menu/menu_addon.h @@ -16,18 +16,18 @@ * 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 . + * along with this program. If not, see . * */ #pragma once #include "../lcdprint.h" -#if HAS_GRAPHICAL_LCD - #include "../dogm/ultralcd_DOGM.h" -#endif -#define MENU_ITEM_ADDON_START(X) do{ \ +#define _MENU_ITEM_ADDON_START(N,X) do{ \ if (ui.should_draw() && _menuLineNr == _thisItemNr - 1) { \ - SETCURSOR(X, _lcdLineNr) + N(X) + +#define MENU_ITEM_ADDON_START(X) _MENU_ITEM_ADDON_START(SETCURSOR_X, X) +#define MENU_ITEM_ADDON_START_RJ(X) _MENU_ITEM_ADDON_START(SETCURSOR_X_RJ, X) #define MENU_ITEM_ADDON_END() } }while(0) diff --git a/Marlin/src/lcd/menu/menu_advanced.cpp b/Marlin/src/lcd/menu/menu_advanced.cpp index 03bcedb7305a..642d9d84d94f 100644 --- a/Marlin/src/lcd/menu/menu_advanced.cpp +++ b/Marlin/src/lcd/menu/menu_advanced.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -28,7 +28,7 @@ #if HAS_LCD_MENU -#include "menu.h" +#include "menu_item.h" #include "../../module/planner.h" #if DISABLED(NO_VOLUMETRICS) @@ -43,29 +43,31 @@ #include "../../module/temperature.h" #endif -#if ENABLED(FILAMENT_RUNOUT_SENSOR) && FILAMENT_RUNOUT_DISTANCE_MM +#if HAS_FILAMENT_RUNOUT_DISTANCE #include "../../feature/runout.h" - float lcd_runout_distance_mm; #endif -#if ENABLED(EEPROM_SETTINGS) && DISABLED(SLIM_LCD_MENUS) - #include "../../module/configuration_store.h" +#if ENABLED(SD_FIRMWARE_UPDATE) + #include "../../module/settings.h" +#endif + +#if ENABLED(PASSWORD_FEATURE) + #include "../../feature/password/password.h" #endif void menu_tmc(); void menu_backlash(); -void menu_cancelobject(); -#if ENABLED(DAC_STEPPER_CURRENT) +#if ENABLED(HAS_MOTOR_CURRENT_DAC) #include "../../feature/dac/stepper_dac.h" void menu_dac() { static xyze_uint8_t driverPercent; - LOOP_XYZE(i) driverPercent[i] = dac_current_get_percent((AxisEnum)i); + LOOP_XYZE(i) driverPercent[i] = stepper_dac.get_current_percent((AxisEnum)i); START_MENU(); BACK_ITEM(MSG_ADVANCED_SETTINGS); - #define EDIT_DAC_PERCENT(A) EDIT_ITEM(uint8, MSG_DAC_PERCENT_##A, &driverPercent[_AXIS(A)], 0, 100, []{ dac_current_set_percents(driverPercent); }) + #define EDIT_DAC_PERCENT(A) EDIT_ITEM(uint8, MSG_DAC_PERCENT_##A, &driverPercent[_AXIS(A)], 0, 100, []{ stepper_dac.set_current_percents(driverPercent); }) EDIT_DAC_PERCENT(X); EDIT_DAC_PERCENT(Y); EDIT_DAC_PERCENT(Z); @@ -84,7 +86,7 @@ void menu_cancelobject(); START_MENU(); BACK_ITEM(MSG_ADVANCED_SETTINGS); #define EDIT_CURRENT_PWM(LABEL,I) EDIT_ITEM_P(long5, PSTR(LABEL), &stepper.motor_current_setting[I], 100, 2000, stepper.refresh_motor_power) - #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY) + #if ANY_PIN(MOTOR_CURRENT_PWM_XY, MOTOR_CURRENT_PWM_X, MOTOR_CURRENT_PWM_Y) EDIT_CURRENT_PWM(STR_X STR_Y, 0); #endif #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z) @@ -98,10 +100,6 @@ void menu_cancelobject(); #endif -#if ENABLED(SD_FIRMWARE_UPDATE) - #include "../../module/configuration_store.h" -#endif - #if DISABLED(NO_VOLUMETRICS) || ENABLED(ADVANCED_PAUSE_FEATURE) // // Advanced Settings > Filament @@ -112,51 +110,54 @@ void menu_cancelobject(); #if ENABLED(LIN_ADVANCE) #if EXTRUDERS == 1 - EDIT_ITEM(float52, MSG_ADVANCE_K, &planner.extruder_advance_K[0], 0, 999); - #elif EXTRUDERS > 1 - for (uint8_t n = 0; n < EXTRUDERS; n++) - EDIT_ITEM_N(float52, n, MSG_ADVANCE_K_E, &planner.extruder_advance_K[n], 0, 999); + EDIT_ITEM(float42_52, MSG_ADVANCE_K, &planner.extruder_advance_K[0], 0, 999); + #elif HAS_MULTI_EXTRUDER + LOOP_L_N(n, EXTRUDERS) + EDIT_ITEM_N(float42_52, n, MSG_ADVANCE_K_E, &planner.extruder_advance_K[n], 0, 999); #endif #endif #if DISABLED(NO_VOLUMETRICS) EDIT_ITEM(bool, MSG_VOLUMETRIC_ENABLED, &parser.volumetric_enabled, planner.calculate_volumetric_multipliers); + #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) + EDIT_ITEM_FAST(float42_52, MSG_VOLUMETRIC_LIMIT, &planner.volumetric_extruder_limit[active_extruder], 0.0f, 20.0f, planner.calculate_volumetric_extruder_limits); + #if HAS_MULTI_EXTRUDER + LOOP_L_N(n, EXTRUDERS) + EDIT_ITEM_FAST_N(float42_52, n, MSG_VOLUMETRIC_LIMIT_E, &planner.volumetric_extruder_limit[n], 0.0f, 20.00f, planner.calculate_volumetric_extruder_limits); + #endif + #endif + if (parser.volumetric_enabled) { EDIT_ITEM_FAST(float43, MSG_FILAMENT_DIAM, &planner.filament_size[active_extruder], 1.5f, 3.25f, planner.calculate_volumetric_multipliers); - #if EXTRUDERS > 1 - for (uint8_t n = 0; n < EXTRUDERS; n++) + #if HAS_MULTI_EXTRUDER + LOOP_L_N(n, EXTRUDERS) EDIT_ITEM_FAST_N(float43, n, MSG_FILAMENT_DIAM_E, &planner.filament_size[n], 1.5f, 3.25f, planner.calculate_volumetric_multipliers); #endif } #endif #if ENABLED(ADVANCED_PAUSE_FEATURE) - constexpr float extrude_maxlength = - #if ENABLED(PREVENT_LENGTHY_EXTRUDE) - EXTRUDE_MAXLENGTH - #else - 999 - #endif - ; + constexpr float extrude_maxlength = TERN(PREVENT_LENGTHY_EXTRUDE, EXTRUDE_MAXLENGTH, 999); EDIT_ITEM_FAST(float3, MSG_FILAMENT_UNLOAD, &fc_settings[active_extruder].unload_length, 0, extrude_maxlength); - #if EXTRUDERS > 1 - for (uint8_t n = 0; n < EXTRUDERS; n++) + #if HAS_MULTI_EXTRUDER + LOOP_L_N(n, EXTRUDERS) EDIT_ITEM_FAST_N(float3, n, MSG_FILAMENTUNLOAD_E, &fc_settings[n].unload_length, 0, extrude_maxlength); #endif EDIT_ITEM_FAST(float3, MSG_FILAMENT_LOAD, &fc_settings[active_extruder].load_length, 0, extrude_maxlength); - #if EXTRUDERS > 1 - for (uint8_t n = 0; n < EXTRUDERS; n++) + #if HAS_MULTI_EXTRUDER + LOOP_L_N(n, EXTRUDERS) EDIT_ITEM_FAST_N(float3, n, MSG_FILAMENTLOAD_E, &fc_settings[n].load_length, 0, extrude_maxlength); #endif #endif - #if ENABLED(FILAMENT_RUNOUT_SENSOR) && FILAMENT_RUNOUT_DISTANCE_MM - EDIT_ITEM(float3, MSG_RUNOUT_DISTANCE_MM, &lcd_runout_distance_mm, 1, 30, []{ - runout.set_runout_distance(lcd_runout_distance_mm); - }); + #if HAS_FILAMENT_RUNOUT_DISTANCE + editable.decimal = runout.runout_distance(); + EDIT_ITEM(float3, MSG_RUNOUT_DISTANCE_MM, &editable.decimal, 1, float(FILAMENT_RUNOUT_DISTANCE_MM) * 1.5f, + []{ runout.set_runout_distance(editable.decimal); }, true + ); #endif END_MENU(); @@ -171,25 +172,25 @@ void menu_cancelobject(); #if ENABLED(PID_AUTOTUNE_MENU) #if ENABLED(PIDTEMP) - int16_t autotune_temp[HOTENDS] = ARRAY_BY_HOTENDS1(150); + int16_t autotune_temp[HOTENDS] = ARRAY_BY_HOTENDS1(PREHEAT_1_TEMP_HOTEND); #endif - #if ENABLED(PIDTEMPBED) - int16_t autotune_temp_bed = 70; + int16_t autotune_temp_bed = PREHEAT_1_TEMP_BED; #endif + #include "../../gcode/queue.h" + void _lcd_autotune(const int16_t e) { char cmd[30]; sprintf_P(cmd, PSTR("M303 U1 E%i S%i"), e, #if HAS_PID_FOR_BOTH e < 0 ? autotune_temp_bed : autotune_temp[e] - #elif ENABLED(PIDTEMPBED) - autotune_temp_bed #else - autotune_temp[e] + TERN(PIDTEMPBED, autotune_temp_bed, autotune_temp[e]) #endif ); - lcd_enqueue_one_now(cmd); + queue.inject(cmd); + ui.return_to_status(); } #endif // PID_AUTOTUNE_MENU @@ -201,16 +202,12 @@ void menu_cancelobject(); // Helpers for editing PID Ki & Kd values // grab the PID value out of the temp variable; scale it; then update the PID driver void copy_and_scalePID_i(int16_t e) { - #if DISABLED(PID_PARAMS_PER_HOTEND) || HOTENDS == 1 - UNUSED(e); - #endif + TERN(PID_PARAMS_PER_HOTEND,,UNUSED(e)); PID_PARAM(Ki, e) = scalePID_i(raw_Ki); thermalManager.updatePID(); } void copy_and_scalePID_d(int16_t e) { - #if DISABLED(PID_PARAMS_PER_HOTEND) || HOTENDS == 1 - UNUSED(e); - #endif + TERN(PID_PARAMS_PER_HOTEND,,UNUSED(e)); PID_PARAM(Kd, e) = scalePID_d(raw_Kd); thermalManager.updatePID(); } @@ -233,14 +230,16 @@ void menu_cancelobject(); #define DEFINE_PIDTEMP_FUNCS(N) _DEFINE_PIDTEMP_BASE_FUNCS(N); #endif -#if HOTENDS +#if HAS_HOTEND DEFINE_PIDTEMP_FUNCS(0); - #if HOTENDS > 1 && ENABLED(PID_PARAMS_PER_HOTEND) + #if ENABLED(PID_PARAMS_PER_HOTEND) REPEAT_S(1, HOTENDS, DEFINE_PIDTEMP_FUNCS) #endif #endif -#define SHOW_MENU_ADVANCED_TEMPERATURE ((ENABLED(AUTOTEMP) && HAS_TEMP_HOTEND) || EITHER(PID_AUTOTUNE_MENU, PID_EDIT_MENU)) +#if BOTH(AUTOTEMP, HAS_TEMP_HOTEND) || EITHER(PID_AUTOTUNE_MENU, PID_EDIT_MENU) + #define SHOW_MENU_ADVANCED_TEMPERATURE 1 +#endif // // Advanced Settings > Temperature @@ -253,11 +252,11 @@ void menu_cancelobject(); // // Autotemp, Min, Max, Fact // - #if ENABLED(AUTOTEMP) && HAS_TEMP_HOTEND + #if BOTH(AUTOTEMP, HAS_TEMP_HOTEND) EDIT_ITEM(bool, MSG_AUTOTEMP, &planner.autotemp_enabled); - EDIT_ITEM(float3, MSG_MIN, &planner.autotemp_min, 0, float(HEATER_0_MAXTEMP) - 15); - EDIT_ITEM(float3, MSG_MAX, &planner.autotemp_max, 0, float(HEATER_0_MAXTEMP) - 15); - EDIT_ITEM(float52, MSG_FACTOR, &planner.autotemp_factor, 0, 10); + EDIT_ITEM(float3, MSG_MIN, &planner.autotemp_min, 0, float(HEATER_0_MAXTEMP) - HOTEND_OVERSHOOT); + EDIT_ITEM(float3, MSG_MAX, &planner.autotemp_max, 0, float(HEATER_0_MAXTEMP) - HOTEND_OVERSHOOT); + EDIT_ITEM(float42_52, MSG_FACTOR, &planner.autotemp_factor, 0, 10); #endif // @@ -271,11 +270,11 @@ void menu_cancelobject(); #if ENABLED(PID_EDIT_MENU) #define __PID_BASE_MENU_ITEMS(N) \ - raw_Ki = unscalePID_i(PID_PARAM(Ki, N)); \ - raw_Kd = unscalePID_d(PID_PARAM(Kd, N)); \ - EDIT_ITEM_N(float52sign, N, MSG_PID_P_E, &PID_PARAM(Kp, N), 1, 9990); \ - EDIT_ITEM_N(float52sign, N, MSG_PID_I_E, &raw_Ki, 0.01f, 9990, []{ copy_and_scalePID_i(N); }); \ - EDIT_ITEM_N(float52sign, N, MSG_PID_D_E, &raw_Kd, 1, 9990, []{ copy_and_scalePID_d(N); }) + raw_Ki = unscalePID_i(TERN(PID_BED_MENU_SECTION, thermalManager.temp_bed.pid.Ki, PID_PARAM(Ki, N))); \ + raw_Kd = unscalePID_d(TERN(PID_BED_MENU_SECTION, thermalManager.temp_bed.pid.Kd, PID_PARAM(Kd, N))); \ + EDIT_ITEM_FAST_N(float41sign, N, MSG_PID_P_E, &TERN(PID_BED_MENU_SECTION, thermalManager.temp_bed.pid.Kp, PID_PARAM(Kp, N)), 1, 9990); \ + EDIT_ITEM_FAST_N(float52sign, N, MSG_PID_I_E, &raw_Ki, 0.01f, 9990, []{ copy_and_scalePID_i(N); }); \ + EDIT_ITEM_FAST_N(float41sign, N, MSG_PID_D_E, &raw_Kd, 1, 9990, []{ copy_and_scalePID_d(N); }) #if ENABLED(PID_EXTRUSION_SCALING) #define _PID_BASE_MENU_ITEMS(N) \ @@ -302,16 +301,27 @@ void menu_cancelobject(); #if ENABLED(PID_AUTOTUNE_MENU) #define PID_EDIT_MENU_ITEMS(N) \ _PID_EDIT_MENU_ITEMS(N); \ - EDIT_ITEM_FAST_N(int3, N, MSG_PID_AUTOTUNE_E, &autotune_temp[N], 150, heater_maxtemp[N] - 15, []{ _lcd_autotune(MenuItemBase::itemIndex); }); + EDIT_ITEM_FAST_N(int3, N, MSG_PID_AUTOTUNE_E, &autotune_temp[N], 150, thermalManager.heater_maxtemp[N] - HOTEND_OVERSHOOT, []{ _lcd_autotune(MenuItemBase::itemIndex); }); #else #define PID_EDIT_MENU_ITEMS(N) _PID_EDIT_MENU_ITEMS(N); #endif PID_EDIT_MENU_ITEMS(0); - #if HOTENDS > 1 && ENABLED(PID_PARAMS_PER_HOTEND) + #if ENABLED(PID_PARAMS_PER_HOTEND) REPEAT_S(1, HOTENDS, PID_EDIT_MENU_ITEMS) #endif + #if ENABLED(PIDTEMPBED) + #if ENABLED(PID_EDIT_MENU) + #define PID_BED_MENU_SECTION + __PID_BASE_MENU_ITEMS(-1); + #undef PID_BED_MENU_SECTION + #endif + #if ENABLED(PID_AUTOTUNE_MENU) + EDIT_ITEM_FAST_N(int3, -1, MSG_PID_AUTOTUNE_E, &autotune_temp_bed, PREHEAT_1_TEMP_BED, BED_MAX_TARGET, []{ _lcd_autotune(-1); }); + #endif + #endif + END_MENU(); } @@ -331,9 +341,6 @@ void menu_cancelobject(); // M203 / M205 Velocity options void menu_advanced_velocity() { - START_MENU(); - BACK_ITEM(MSG_ADVANCED_SETTINGS); - // M203 Max Feedrate constexpr xyze_feedrate_t max_fr_edit = #ifdef MAX_FEEDRATE_EDIT_VALUES @@ -349,6 +356,10 @@ void menu_cancelobject(); #else const xyze_feedrate_t &max_fr_edit_scaled = max_fr_edit; #endif + + START_MENU(); + BACK_ITEM(MSG_ADVANCED_SETTINGS); + #define EDIT_VMAX(N) EDIT_ITEM_FAST(float3, MSG_VMAX_##N, &planner.settings.max_feedrate_mm_s[_AXIS(N)], 1, max_fr_edit_scaled[_AXIS(N)]) EDIT_VMAX(A); EDIT_VMAX(B); @@ -358,7 +369,7 @@ void menu_cancelobject(); EDIT_ITEM_FAST(float3, MSG_VMAX_E, &planner.settings.max_feedrate_mm_s[E_AXIS_N(active_extruder)], 1, max_fr_edit_scaled.e); #endif #if ENABLED(DISTINCT_E_FACTORS) - for (uint8_t n = 0; n < E_STEPPERS; n++) + LOOP_L_N(n, E_STEPPERS) EDIT_ITEM_FAST_N(float3, n, MSG_VMAX_EN, &planner.settings.max_feedrate_mm_s[E_AXIS_N(n)], 1, max_fr_edit_scaled.e); #endif @@ -373,18 +384,7 @@ void menu_cancelobject(); // M201 / M204 Accelerations void menu_advanced_acceleration() { - START_MENU(); - BACK_ITEM(MSG_ADVANCED_SETTINGS); - - static float max_accel = _MAX(planner.settings.max_acceleration_mm_per_s2[A_AXIS], planner.settings.max_acceleration_mm_per_s2[B_AXIS], planner.settings.max_acceleration_mm_per_s2[C_AXIS]); - // M204 P Acceleration - EDIT_ITEM_FAST(float5_25, MSG_ACC, &planner.settings.acceleration, 25, max_accel); - - // M204 R Retract Acceleration - EDIT_ITEM_FAST(float5, MSG_A_RETRACT, &planner.settings.retract_acceleration, 100, max_accel); - - // M204 T Travel Acceleration - EDIT_ITEM_FAST(float5_25, MSG_A_TRAVEL, &planner.settings.travel_acceleration, 25, max_accel); + const float max_accel = _MAX(planner.settings.max_acceleration_mm_per_s2[A_AXIS], planner.settings.max_acceleration_mm_per_s2[B_AXIS], planner.settings.max_acceleration_mm_per_s2[C_AXIS]); // M201 settings constexpr xyze_ulong_t max_accel_edit = @@ -402,37 +402,56 @@ void menu_cancelobject(); const xyze_ulong_t &max_accel_edit_scaled = max_accel_edit; #endif + START_MENU(); + BACK_ITEM(MSG_ADVANCED_SETTINGS); + + // M204 P Acceleration + EDIT_ITEM_FAST(float5_25, MSG_ACC, &planner.settings.acceleration, 25, max_accel); + + // M204 R Retract Acceleration + EDIT_ITEM_FAST(float5, MSG_A_RETRACT, &planner.settings.retract_acceleration, 100, planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(active_extruder)]); + + // M204 T Travel Acceleration + EDIT_ITEM_FAST(float5_25, MSG_A_TRAVEL, &planner.settings.travel_acceleration, 25, max_accel); + #define EDIT_AMAX(Q,L) EDIT_ITEM_FAST(long5_25, MSG_AMAX_##Q, &planner.settings.max_acceleration_mm_per_s2[_AXIS(Q)], L, max_accel_edit_scaled[_AXIS(Q)], []{ planner.reset_acceleration_rates(); }) - EDIT_AMAX(A,100); - EDIT_AMAX(B,100); - EDIT_AMAX(C, 10); + EDIT_AMAX(A, 100); + EDIT_AMAX(B, 100); + EDIT_AMAX(C, 10); #if ENABLED(DISTINCT_E_FACTORS) EDIT_ITEM_FAST(long5_25, MSG_AMAX_E, &planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(active_extruder)], 100, max_accel_edit_scaled.e, []{ planner.reset_acceleration_rates(); }); - for (uint8_t n = 0; n < E_STEPPERS; n++) + LOOP_L_N(n, E_STEPPERS) EDIT_ITEM_FAST_N(long5_25, n, MSG_AMAX_EN, &planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(n)], 100, max_accel_edit_scaled.e, []{ _reset_e_acceleration_rate(MenuItemBase::itemIndex); }); #elif E_STEPPERS EDIT_ITEM_FAST(long5_25, MSG_AMAX_E, &planner.settings.max_acceleration_mm_per_s2[E_AXIS], 100, max_accel_edit_scaled.e, []{ planner.reset_acceleration_rates(); }); #endif + #ifdef XY_FREQUENCY_LIMIT + EDIT_ITEM(int8, MSG_XY_FREQUENCY_LIMIT, &planner.xy_freq_limit_hz, 0, 100, planner.refresh_frequency_limit, true); + editable.uint8 = uint8_t(LROUND(planner.xy_freq_min_speed_factor * 255)); // percent to u8 + EDIT_ITEM(percent, MSG_XY_FREQUENCY_FEEDRATE, &editable.uint8, 3, 255, []{ planner.set_min_speed_factor_u8(editable.uint8); }, true); + #endif + END_MENU(); } - // M205 Jerk - void menu_advanced_jerk() { - START_MENU(); - BACK_ITEM(MSG_ADVANCED_SETTINGS); + #if HAS_CLASSIC_JERK - #if DISABLED(CLASSIC_JERK) - #if ENABLED(LIN_ADVANCE) - EDIT_ITEM(float43, MSG_JUNCTION_DEVIATION, &planner.junction_deviation_mm, 0.001f, 0.3f, planner.recalculate_max_e_jerk); - #else - EDIT_ITEM(float43, MSG_JUNCTION_DEVIATION, &planner.junction_deviation_mm, 0.001f, 0.5f); + void menu_advanced_jerk() { + START_MENU(); + BACK_ITEM(MSG_ADVANCED_SETTINGS); + + #if HAS_JUNCTION_DEVIATION + #if ENABLED(LIN_ADVANCE) + EDIT_ITEM(float43, MSG_JUNCTION_DEVIATION, &planner.junction_deviation_mm, 0.001f, 0.3f, planner.recalculate_max_e_jerk); + #else + EDIT_ITEM(float43, MSG_JUNCTION_DEVIATION, &planner.junction_deviation_mm, 0.001f, 0.5f); + #endif #endif - #endif - #if HAS_CLASSIC_JERK + constexpr xyze_float_t max_jerk_edit = - #ifdef MAX_ACCEL_EDIT_VALUES + #ifdef MAX_JERK_EDIT_VALUES MAX_JERK_EDIT_VALUES #elif ENABLED(LIMITED_JERK_EDITING) { (DEFAULT_XJERK) * 2, (DEFAULT_YJERK) * 2, (DEFAULT_ZJERK) * 2, (DEFAULT_EJERK) * 2 } @@ -451,10 +470,11 @@ void menu_cancelobject(); #if HAS_CLASSIC_E_JERK EDIT_ITEM_FAST(float52sign, MSG_VE_JERK, &planner.max_jerk.e, 0.1f, max_jerk_edit.e); #endif - #endif - END_MENU(); - } + END_MENU(); + } + + #endif // M851 - Z Probe Offsets #if HAS_BED_PROBE @@ -462,10 +482,15 @@ void menu_cancelobject(); START_MENU(); BACK_ITEM(MSG_ADVANCED_SETTINGS); #if HAS_PROBE_XY_OFFSET - EDIT_ITEM(float51sign, MSG_ZPROBE_XOFFSET, &probe.offset.x, -(X_BED_SIZE), X_BED_SIZE); - EDIT_ITEM(float51sign, MSG_ZPROBE_YOFFSET, &probe.offset.y, -(Y_BED_SIZE), Y_BED_SIZE); + EDIT_ITEM(float31sign, MSG_ZPROBE_XOFFSET, &probe.offset.x, -(X_BED_SIZE), X_BED_SIZE); + EDIT_ITEM(float31sign, MSG_ZPROBE_YOFFSET, &probe.offset.y, -(Y_BED_SIZE), Y_BED_SIZE); #endif EDIT_ITEM(LCD_Z_OFFSET_TYPE, MSG_ZPROBE_ZOFFSET, &probe.offset.z, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX); + + #if ENABLED(PROBE_OFFSET_WIZARD) + SUBMENU(MSG_PROBE_WIZARD, goto_probe_offset_wizard); + #endif + END_MENU(); } #endif @@ -483,8 +508,7 @@ void menu_advanced_steps_per_mm() { EDIT_QSTEPS(C); #if ENABLED(DISTINCT_E_FACTORS) - EDIT_ITEM_FAST(float51, MSG_E_STEPS, &planner.settings.axis_steps_per_mm[E_AXIS_N(active_extruder)], 5, 9999, []{ planner.refresh_positioning(); }); - for (uint8_t n = 0; n < E_STEPPERS; n++) + LOOP_L_N(n, E_STEPPERS) EDIT_ITEM_FAST_N(float51, n, MSG_EN_STEPS, &planner.settings.axis_steps_per_mm[E_AXIS_N(n)], 5, 9999, []{ _planner_refresh_e_positioning(MenuItemBase::itemIndex); }); #elif E_STEPPERS EDIT_ITEM_FAST(float51, MSG_E_STEPS, &planner.settings.axis_steps_per_mm[E_AXIS], 5, 9999, []{ planner.refresh_positioning(); }); @@ -494,9 +518,12 @@ void menu_advanced_steps_per_mm() { } void menu_advanced_settings() { - #if ENABLED(FILAMENT_RUNOUT_SENSOR) && FILAMENT_RUNOUT_DISTANCE_MM - lcd_runout_distance_mm = runout.runout_distance(); + const bool is_busy = printer_busy(); + + #if ENABLED(SD_FIRMWARE_UPDATE) + bool sd_update_state = settings.sd_update_status(); #endif + START_MENU(); BACK_ITEM(MSG_CONFIGURATION); @@ -515,36 +542,40 @@ void menu_advanced_settings() { // M201 - Acceleration items SUBMENU(MSG_ACCELERATION, menu_advanced_acceleration); - // M205 - Max Jerk - SUBMENU(MSG_JERK, menu_advanced_jerk); + #if HAS_CLASSIC_JERK + // M205 - Max Jerk + SUBMENU(MSG_JERK, menu_advanced_jerk); + #elif HAS_JUNCTION_DEVIATION + EDIT_ITEM(float43, MSG_JUNCTION_DEVIATION, &planner.junction_deviation_mm, 0.001f, 0.3f + #if ENABLED(LIN_ADVANCE) + , planner.recalculate_max_e_jerk + #endif + ); + #endif // M851 - Z Probe Offsets #if HAS_BED_PROBE - if (!printer_busy()) - SUBMENU(MSG_ZPROBE_OFFSETS, menu_probe_offsets); + if (!is_busy) SUBMENU(MSG_ZPROBE_OFFSETS, menu_probe_offsets); #endif + #endif // !SLIM_LCD_MENUS // M92 - Steps Per mm - if (!printer_busy()) + if (!is_busy) SUBMENU(MSG_STEPS_PER_MM, menu_advanced_steps_per_mm); #if ENABLED(BACKLASH_GCODE) SUBMENU(MSG_BACKLASH, menu_backlash); #endif - #if ENABLED(CANCEL_OBJECTS) - SUBMENU(MSG_CANCEL_OBJECT, []{ editable.int8 = -1; ui.goto_screen(menu_cancelobject); }); - #endif - - #if ENABLED(DAC_STEPPER_CURRENT) + #if ENABLED(HAS_MOTOR_CURRENT_DAC) SUBMENU(MSG_DRIVE_STRENGTH, menu_dac); #endif #if HAS_MOTOR_CURRENT_PWM SUBMENU(MSG_DRIVE_STRENGTH, menu_pwm); #endif - #if HAS_TRINAMIC + #if HAS_TRINAMIC_CONFIG SUBMENU(MSG_TMC_DRIVERS, menu_tmc); #endif @@ -556,10 +587,10 @@ void menu_advanced_settings() { SUBMENU(MSG_FILAMENT, menu_advanced_filament); #elif ENABLED(LIN_ADVANCE) #if EXTRUDERS == 1 - EDIT_ITEM(float52, MSG_ADVANCE_K, &planner.extruder_advance_K[0], 0, 999); - #elif EXTRUDERS > 1 - for (uint8_t n = 0; n < E_STEPPERS; n++) - EDIT_ITEM_N(float52, n, MSG_ADVANCE_K_E, &planner.extruder_advance_K[n], 0, 999); + EDIT_ITEM(float42_52, MSG_ADVANCE_K, &planner.extruder_advance_K[0], 0, 999); + #elif HAS_MULTI_EXTRUDER + LOOP_L_N(n, E_STEPPERS) + EDIT_ITEM_N(float42_52, n, MSG_ADVANCE_K_E, &planner.extruder_advance_K[n], 0, 999); #endif #endif @@ -569,33 +600,27 @@ void menu_advanced_settings() { #endif #if ENABLED(SD_FIRMWARE_UPDATE) - bool sd_update_state = settings.sd_update_status(); EDIT_ITEM(bool, MSG_MEDIA_UPDATE, &sd_update_state, []{ // // Toggle the SD Firmware Update state in EEPROM // const bool new_state = !settings.sd_update_status(), didset = settings.set_sd_update_status(new_state); - #if HAS_BUZZER - ui.completion_feedback(didset); - #endif + ui.completion_feedback(didset); ui.return_to_status(); if (new_state) LCD_MESSAGEPGM(MSG_RESET_PRINTER); else ui.reset_status(); }); #endif + #if ENABLED(PASSWORD_FEATURE) + SUBMENU(MSG_PASSWORD_SETTINGS, password.access_menu_password); + #endif + #if ENABLED(EEPROM_SETTINGS) && DISABLED(SLIM_LCD_MENUS) CONFIRM_ITEM(MSG_INIT_EEPROM, MSG_BUTTON_INIT, MSG_BUTTON_CANCEL, - []{ - const bool inited = settings.init_eeprom(); - #if HAS_BUZZER - ui.completion_feedback(inited); - #endif - UNUSED(inited); - }, - ui.goto_previous_screen, - GET_TEXT(MSG_INIT_EEPROM), (PGM_P)nullptr, PSTR("?") + ui.init_eeprom, nullptr, + GET_TEXT(MSG_INIT_EEPROM), (const char *)nullptr, PSTR("?") ); #endif diff --git a/Marlin/src/lcd/menu/menu_backlash.cpp b/Marlin/src/lcd/menu/menu_backlash.cpp index ad9c51d4cfda..9d0b970ae1d3 100644 --- a/Marlin/src/lcd/menu/menu_backlash.cpp +++ b/Marlin/src/lcd/menu/menu_backlash.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -26,9 +26,9 @@ #include "../../inc/MarlinConfigPre.h" -#if HAS_LCD_MENU && ENABLED(BACKLASH_GCODE) +#if BOTH(HAS_LCD_MENU, BACKLASH_GCODE) -#include "menu.h" +#include "menu_item.h" #include "../../feature/backlash.h" @@ -39,9 +39,9 @@ void menu_backlash() { EDIT_ITEM_FAST(percent, MSG_BACKLASH_CORRECTION, &backlash.correction, all_off, all_on); #define EDIT_BACKLASH_DISTANCE(N) EDIT_ITEM_FAST(float43, MSG_BACKLASH_##N, &backlash.distance_mm[_AXIS(N)], 0.0f, 9.9f); - EDIT_BACKLASH_DISTANCE(A); - EDIT_BACKLASH_DISTANCE(B); - EDIT_BACKLASH_DISTANCE(C); + if (AXIS_CAN_CALIBRATE(A)) EDIT_BACKLASH_DISTANCE(A); + if (AXIS_CAN_CALIBRATE(B)) EDIT_BACKLASH_DISTANCE(B); + if (AXIS_CAN_CALIBRATE(C)) EDIT_BACKLASH_DISTANCE(C); #ifdef BACKLASH_SMOOTHING_MM EDIT_ITEM_FAST(float43, MSG_BACKLASH_SMOOTHING, &backlash.smoothing_mm, 0.0f, 9.9f); @@ -50,4 +50,4 @@ void menu_backlash() { END_MENU(); } -#endif // HAS_LCD_MENU && BACKLASH_COMPENSATION +#endif // HAS_LCD_MENU && BACKLASH_GCODE diff --git a/Marlin/src/lcd/menu/menu_bed_corners.cpp b/Marlin/src/lcd/menu/menu_bed_corners.cpp index 3d0a5bf2aa33..16f9992c1852 100644 --- a/Marlin/src/lcd/menu/menu_bed_corners.cpp +++ b/Marlin/src/lcd/menu/menu_bed_corners.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -26,9 +26,9 @@ #include "../../inc/MarlinConfigPre.h" -#if HAS_LCD_MENU && ENABLED(LEVEL_BED_CORNERS) +#if BOTH(HAS_LCD_MENU, LEVEL_BED_CORNERS) -#include "menu.h" +#include "menu_item.h" #include "../../module/motion.h" #include "../../module/planner.h" @@ -70,11 +70,7 @@ static inline void _lcd_goto_next_corner() { } line_to_current_position(manual_feedrate_mm_s.x); line_to_z(LEVEL_CORNERS_HEIGHT); - if (++bed_corner > (3 - #if ENABLED(LEVEL_CENTER_TOO) - + 1 - #endif - )) bed_corner = 0; + if (++bed_corner > 3 + ENABLED(LEVEL_CENTER_TOO)) bed_corner = 0; } static inline void _lcd_level_bed_corners_homing() { @@ -83,21 +79,14 @@ static inline void _lcd_level_bed_corners_homing() { bed_corner = 0; ui.goto_screen([]{ MenuItem_confirm::select_screen( - GET_TEXT(MSG_BUTTON_NEXT), GET_TEXT(MSG_BUTTON_DONE), - _lcd_goto_next_corner, - []{ - #if HAS_LEVELING - set_bed_leveling_enabled(leveling_was_active); - #endif - ui.goto_previous_screen_no_defer(); - }, - GET_TEXT( - #if ENABLED(LEVEL_CENTER_TOO) - MSG_LEVEL_BED_NEXT_POINT - #else - MSG_NEXT_CORNER - #endif - ), (PGM_P)nullptr, PSTR("?") + GET_TEXT(MSG_BUTTON_NEXT), GET_TEXT(MSG_BUTTON_DONE) + , _lcd_goto_next_corner + , []{ + TERN_(HAS_LEVELING, set_bed_leveling_enabled(leveling_was_active)); + ui.goto_previous_screen_no_defer(); + } + , GET_TEXT(TERN(LEVEL_CENTER_TOO, MSG_LEVEL_BED_NEXT_POINT, MSG_NEXT_CORNER)) + , (const char*)nullptr, PSTR("?") ); }); ui.set_selection(true); diff --git a/Marlin/src/lcd/menu/menu_bed_leveling.cpp b/Marlin/src/lcd/menu/menu_bed_leveling.cpp index 5834b73ba449..e19b04ccb517 100644 --- a/Marlin/src/lcd/menu/menu_bed_leveling.cpp +++ b/Marlin/src/lcd/menu/menu_bed_leveling.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -28,7 +28,7 @@ #if ENABLED(LCD_BED_LEVELING) -#include "menu.h" +#include "menu_item.h" #include "../../module/planner.h" #include "../../feature/bedlevel/bedlevel.h" @@ -36,6 +36,11 @@ #include "../../module/probe.h" #endif +#if HAS_GRAPHICAL_TFT + #include "../tft/touch.h" + #include "../tft/tft.h" +#endif + #if EITHER(PROBE_MANUALLY, MESH_BED_LEVELING) #include "../../module/motion.h" @@ -48,13 +53,7 @@ static uint8_t manual_probe_index; // LCD probed points are from defaults - constexpr uint8_t total_probe_points = ( - #if ENABLED(AUTO_BED_LEVELING_3POINT) - 3 - #elif ABL_GRID || ENABLED(MESH_BED_LEVELING) - GRID_MAX_POINTS - #endif - ); + constexpr uint8_t total_probe_points = TERN(AUTO_BED_LEVELING_3POINT, 3, GRID_MAX_POINTS); // // Bed leveling is done. Wait for G29 to complete. @@ -75,9 +74,7 @@ ui.synchronize(GET_TEXT(MSG_LEVEL_BED_DONE)); #endif ui.goto_previous_screen_no_defer(); - #if HAS_BUZZER - ui.completion_feedback(); - #endif + ui.completion_feedback(); } if (ui.should_draw()) MenuItem_static::draw(LCD_HEIGHT >= 4, GET_TEXT(MSG_LEVEL_BED_DONE)); ui.refresh(LCDVIEW_CALL_REDRAW_NEXT); @@ -167,7 +164,11 @@ // Move to the first probe position // void _lcd_level_bed_homing_done() { - if (ui.should_draw()) MenuItem_static::draw(1, GET_TEXT(MSG_LEVEL_BED_WAITING)); + if (ui.should_draw()) { + MenuItem_static::draw(1, GET_TEXT(MSG_LEVEL_BED_WAITING)); + // Color UI needs a control to detect a touch + TERN_(HAS_GRAPHICAL_TFT, touch.add_control(CLICK, 0, 0, TFT_WIDTH, TFT_HEIGHT)); + } if (ui.use_click()) { manual_probe_index = 0; _lcd_level_goto_next_point(); @@ -232,11 +233,12 @@ * Save Settings (Req: EEPROM_SETTINGS) */ void menu_bed_leveling() { + const bool is_homed = all_axes_known(), + is_valid = leveling_is_valid(); + START_MENU(); BACK_ITEM(MSG_MOTION); - const bool is_homed = all_axes_known(); - // Auto Home if not using manual probing #if NONE(PROBE_MANUALLY, MESH_BED_LEVELING) if (!is_homed) GCODES_ITEM(MSG_AUTO_HOME, G28_STR); @@ -252,12 +254,11 @@ void menu_bed_leveling() { #endif #if ENABLED(MESH_EDIT_MENU) - if (leveling_is_valid()) - SUBMENU(MSG_EDIT_MESH, menu_edit_mesh); + if (is_valid) SUBMENU(MSG_EDIT_MESH, menu_edit_mesh); #endif // Homed and leveling is valid? Then leveling can be toggled. - if (is_homed && leveling_is_valid()) { + if (is_homed && is_valid) { bool show_state = planner.leveling_active; EDIT_ITEM(bool, MSG_BED_LEVELING, &show_state, _lcd_toggle_bed_leveling); } @@ -287,8 +288,8 @@ void menu_bed_leveling() { #endif #if ENABLED(EEPROM_SETTINGS) - ACTION_ITEM(MSG_LOAD_EEPROM, lcd_load_settings); - ACTION_ITEM(MSG_STORE_EEPROM, lcd_store_settings); + ACTION_ITEM(MSG_LOAD_EEPROM, ui.load_settings); + ACTION_ITEM(MSG_STORE_EEPROM, ui.store_settings); #endif END_MENU(); } diff --git a/Marlin/src/lcd/menu/menu_cancelobject.cpp b/Marlin/src/lcd/menu/menu_cancelobject.cpp index 4d445a184837..a8ced05759bd 100644 --- a/Marlin/src/lcd/menu/menu_cancelobject.cpp +++ b/Marlin/src/lcd/menu/menu_cancelobject.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -26,9 +26,9 @@ #include "../../inc/MarlinConfigPre.h" -#if HAS_LCD_MENU && ENABLED(CANCEL_OBJECTS) +#if BOTH(HAS_LCD_MENU, CANCEL_OBJECTS) -#include "menu.h" +#include "menu_item.h" #include "menu_addon.h" #include "../../feature/cancel_object.h" @@ -43,10 +43,8 @@ static void lcd_cancel_object_confirm() { }; MenuItem_confirm::confirm_screen( []{ - cancelable.cancel_object(MenuItemBase::itemIndex - 1); - #if HAS_BUZZER - ui.completion_feedback(); - #endif + cancelable.cancel_object(MenuItemBase::itemIndex); + ui.completion_feedback(); ui.goto_previous_screen(); }, ui.goto_previous_screen, @@ -55,17 +53,19 @@ static void lcd_cancel_object_confirm() { } void menu_cancelobject() { + const int8_t ao = cancelable.active_object; + START_MENU(); BACK_ITEM(MSG_MAIN); // Draw cancelable items in a loop - int8_t a = cancelable.active_object; for (int8_t i = -1; i < cancelable.object_count; i++) { - if (i == a) continue; - int8_t j = i < 0 ? a : i; - if (!cancelable.is_canceled(j)) - SUBMENU_N(j, MSG_CANCEL_OBJECT_N, lcd_cancel_object_confirm); - if (i < 0) SKIP_ITEM(); + if (i == ao) continue; // Active is drawn on -1 index + const int8_t j = i < 0 ? ao : i; // Active or index item + if (!cancelable.is_canceled(j)) { // Not canceled already? + SUBMENU_N(j, MSG_CANCEL_OBJECT_N, lcd_cancel_object_confirm); // Offer the option. + if (i < 0) SKIP_ITEM(); // Extra line after active + } } END_MENU(); diff --git a/Marlin/src/lcd/menu/menu_configuration.cpp b/Marlin/src/lcd/menu/menu_configuration.cpp index d2285e083560..22947ee5149a 100644 --- a/Marlin/src/lcd/menu/menu_configuration.cpp +++ b/Marlin/src/lcd/menu/menu_configuration.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -28,16 +28,14 @@ #if HAS_LCD_MENU -#include "menu.h" - -#include "../../module/configuration_store.h" +#include "menu_item.h" #if HAS_FILAMENT_SENSOR #include "../../feature/runout.h" #endif #if ENABLED(POWER_LOSS_RECOVERY) - #include "../../feature/power_loss_recovery.h" + #include "../../feature/powerloss.h" #endif #if HAS_BED_PROBE @@ -62,20 +60,24 @@ void menu_advanced_settings(); static int8_t bar_percent = 0; if (ui.use_click()) { ui.goto_previous_screen(); - ui.set_custom_characters(CHARSET_MENU); + #if HAS_MARLINUI_HD44780 + ui.set_custom_characters(CHARSET_MENU); + #endif return; } bar_percent += (int8_t)ui.encoderPosition; LIMIT(bar_percent, 0, 100); ui.encoderPosition = 0; - MenuItem_static::draw(0, GET_TEXT(MSG_PROGRESS_BAR_TEST), SS_CENTER|SS_INVERT); + MenuItem_static::draw(0, GET_TEXT(MSG_PROGRESS_BAR_TEST), SS_DEFAULT|SS_INVERT); lcd_put_int((LCD_WIDTH) / 2 - 2, LCD_HEIGHT - 2, bar_percent); lcd_put_wchar('%'); lcd_moveto(0, LCD_HEIGHT - 1); ui.draw_progress_bar(bar_percent); } void _progress_bar_test() { ui.goto_screen(progress_bar_test); - ui.set_custom_characters(CHARSET_INFO); + #if HAS_MARLINUI_HD44780 + ui.set_custom_characters(CHARSET_INFO); + #endif } #endif // LCD_PROGRESS_BAR_TEST @@ -96,7 +98,7 @@ void menu_advanced_settings(); #endif -#if EXTRUDERS > 1 +#if HAS_MULTI_EXTRUDER #include "../../module/tool_change.h" @@ -104,22 +106,51 @@ void menu_advanced_settings(); START_MENU(); BACK_ITEM(MSG_CONFIGURATION); #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) - static constexpr float max_extrude = - #if ENABLED(PREVENT_LENGTHY_EXTRUDE) - EXTRUDE_MAXLENGTH - #else - 500 - #endif - ; + static constexpr float max_extrude = TERN(PREVENT_LENGTHY_EXTRUDE, EXTRUDE_MAXLENGTH, 500); + #if ENABLED(TOOLCHANGE_PARK) + EDIT_ITEM(bool, MSG_FILAMENT_PARK_ENABLED, &toolchange_settings.enable_park); + #endif EDIT_ITEM(float3, MSG_FILAMENT_SWAP_LENGTH, &toolchange_settings.swap_length, 0, max_extrude); + EDIT_ITEM(float41sign, MSG_FILAMENT_SWAP_EXTRA, &toolchange_settings.extra_resume, -10, 10); + EDIT_ITEM_FAST(int4, MSG_SINGLENOZZLE_RETRACT_SPEED, &toolchange_settings.retract_speed, 10, 5400); + EDIT_ITEM_FAST(int4, MSG_SINGLENOZZLE_UNRETRACT_SPEED, &toolchange_settings.unretract_speed, 10, 5400); EDIT_ITEM(float3, MSG_FILAMENT_PURGE_LENGTH, &toolchange_settings.extra_prime, 0, max_extrude); - EDIT_ITEM_FAST(int4, MSG_SINGLENOZZLE_RETRACT_SPD, &toolchange_settings.retract_speed, 10, 5400); - EDIT_ITEM_FAST(int4, MSG_SINGLENOZZLE_PRIME_SPD, &toolchange_settings.prime_speed, 10, 5400); + EDIT_ITEM_FAST(int4, MSG_SINGLENOZZLE_PRIME_SPEED, &toolchange_settings.prime_speed, 10, 5400); + EDIT_ITEM_FAST(int4, MSG_SINGLENOZZLE_FAN_SPEED, &toolchange_settings.fan_speed, 0, 255); + EDIT_ITEM_FAST(int4, MSG_SINGLENOZZLE_FAN_TIME, &toolchange_settings.fan_time, 1, 30); #endif EDIT_ITEM(float3, MSG_TOOL_CHANGE_ZLIFT, &toolchange_settings.z_raise, 0, 10); END_MENU(); } + #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) + + #include "../../module/motion.h" // for active_extruder + + void menu_toolchange_migration() { + PGM_P const msg_migrate = GET_TEXT(MSG_TOOL_MIGRATION_SWAP); + + START_MENU(); + BACK_ITEM(MSG_CONFIGURATION); + + // Auto mode ON/OFF + EDIT_ITEM(bool, MSG_TOOL_MIGRATION_AUTO, &migration.automode); + EDIT_ITEM(uint8, MSG_TOOL_MIGRATION_END, &migration.last, 0, EXTRUDERS - 1); + + // Migrate to a chosen extruder + LOOP_L_N(s, EXTRUDERS) { + if (s != active_extruder) { + ACTION_ITEM_N_P(s, msg_migrate, []{ + char cmd[12]; + sprintf_P(cmd, PSTR("M217 T%i"), int(MenuItemBase::itemIndex)); + queue.inject(cmd); + }); + } + } + END_MENU(); + } + #endif + #endif #if HAS_HOTEND_OFFSET @@ -138,14 +169,14 @@ void menu_advanced_settings(); START_MENU(); BACK_ITEM(MSG_CONFIGURATION); #if ENABLED(DUAL_X_CARRIAGE) - EDIT_ITEM_FAST(float51, MSG_HOTEND_OFFSET_X, &hotend_offset[1].x, float(X2_HOME_POS - 25), float(X2_HOME_POS + 25), _recalc_offsets); + EDIT_ITEM_FAST(float42_52, MSG_HOTEND_OFFSET_X, &hotend_offset[1].x, float(X2_HOME_POS - 25), float(X2_HOME_POS + 25), _recalc_offsets); #else - EDIT_ITEM_FAST(float41sign, MSG_HOTEND_OFFSET_X, &hotend_offset[1].x, -99.0, 99.0, _recalc_offsets); + EDIT_ITEM_FAST(float42_52, MSG_HOTEND_OFFSET_X, &hotend_offset[1].x, -99.0, 99.0, _recalc_offsets); #endif - EDIT_ITEM_FAST(float41sign, MSG_HOTEND_OFFSET_Y, &hotend_offset[1].y, -99.0, 99.0, _recalc_offsets); - EDIT_ITEM_FAST(float41sign, MSG_HOTEND_OFFSET_Z, &hotend_offset[1].z, Z_PROBE_LOW_POINT, 10.0, _recalc_offsets); + EDIT_ITEM_FAST(float42_52, MSG_HOTEND_OFFSET_Y, &hotend_offset[1].y, -99.0, 99.0, _recalc_offsets); + EDIT_ITEM_FAST(float42_52, MSG_HOTEND_OFFSET_Z, &hotend_offset[1].z, Z_PROBE_LOW_POINT, 10.0, _recalc_offsets); #if ENABLED(EEPROM_SETTINGS) - ACTION_ITEM(MSG_STORE_EEPROM, lcd_store_settings); + ACTION_ITEM(MSG_STORE_EEPROM, ui.store_settings); #endif END_MENU(); } @@ -154,11 +185,12 @@ void menu_advanced_settings(); #if ENABLED(DUAL_X_CARRIAGE) void menu_idex() { + const bool need_g28 = axes_should_home(_BV(Y_AXIS)|_BV(Z_AXIS)); + START_MENU(); BACK_ITEM(MSG_CONFIGURATION); GCODES_ITEM(MSG_IDEX_MODE_AUTOPARK, PSTR("M605 S1\nG28 X\nG1 X100")); - const bool need_g28 = !(TEST(axis_known_position, Y_AXIS) && TEST(axis_known_position, Z_AXIS)); GCODES_ITEM(MSG_IDEX_MODE_DUPLICATE, need_g28 ? PSTR("M605 S1\nT0\nG28\nM605 S2 X200\nG28 X\nG1 X100") // If Y or Z is not homed, do a full G28 first : PSTR("M605 S1\nT0\nM605 S2 X200\nG28 X\nG1 X100") @@ -178,13 +210,7 @@ void menu_advanced_settings(); #if ENABLED(BLTOUCH_LCD_VOLTAGE_MENU) void bltouch_report() { SERIAL_ECHOLNPAIR("EEPROM Last BLTouch Mode - ", (int)bltouch.last_written_mode); - SERIAL_ECHOLNPGM("Configuration BLTouch Mode - " - #if ENABLED(BLTOUCH_SET_5V_MODE) - "5V" - #else - "OD" - #endif - ); + SERIAL_ECHOLNPGM("Configuration BLTouch Mode - " TERN(BLTOUCH_SET_5V_MODE, "5V", "OD")); char mess[21]; strcpy_P(mess, PSTR("BLTouch Mode - ")); strcpy_P(&mess[15], bltouch.last_written_mode ? PSTR("5V") : PSTR("OD")); @@ -202,11 +228,11 @@ void menu_advanced_settings(); ACTION_ITEM(MSG_BLTOUCH_STOW, bltouch._stow); ACTION_ITEM(MSG_BLTOUCH_SW_MODE, bltouch._set_SW_mode); #if ENABLED(BLTOUCH_LCD_VOLTAGE_MENU) - CONFIRM_ITEM(MSG_BLTOUCH_5V_MODE, MSG_BLTOUCH_5V_MODE, MSG_BUTTON_CANCEL, bltouch._set_5V_mode, ui.goto_previous_screen, GET_TEXT(MSG_BLTOUCH_MODE_CHANGE)); - CONFIRM_ITEM(MSG_BLTOUCH_OD_MODE, MSG_BLTOUCH_OD_MODE, MSG_BUTTON_CANCEL, bltouch._set_OD_mode, ui.goto_previous_screen, GET_TEXT(MSG_BLTOUCH_MODE_CHANGE)); + CONFIRM_ITEM(MSG_BLTOUCH_5V_MODE, MSG_BLTOUCH_5V_MODE, MSG_BUTTON_CANCEL, bltouch._set_5V_mode, nullptr, GET_TEXT(MSG_BLTOUCH_MODE_CHANGE)); + CONFIRM_ITEM(MSG_BLTOUCH_OD_MODE, MSG_BLTOUCH_OD_MODE, MSG_BUTTON_CANCEL, bltouch._set_OD_mode, nullptr, GET_TEXT(MSG_BLTOUCH_MODE_CHANGE)); ACTION_ITEM(MSG_BLTOUCH_MODE_STORE, bltouch._mode_store); - CONFIRM_ITEM(MSG_BLTOUCH_MODE_STORE_5V, MSG_BLTOUCH_MODE_STORE_5V, MSG_BUTTON_CANCEL, bltouch.mode_conv_5V, ui.goto_previous_screen, GET_TEXT(MSG_BLTOUCH_MODE_CHANGE)); - CONFIRM_ITEM(MSG_BLTOUCH_MODE_STORE_OD, MSG_BLTOUCH_MODE_STORE_OD, MSG_BUTTON_CANCEL, bltouch.mode_conv_OD, ui.goto_previous_screen, GET_TEXT(MSG_BLTOUCH_MODE_CHANGE)); + CONFIRM_ITEM(MSG_BLTOUCH_MODE_STORE_5V, MSG_BLTOUCH_MODE_STORE_5V, MSG_BUTTON_CANCEL, bltouch.mode_conv_5V, nullptr, GET_TEXT(MSG_BLTOUCH_MODE_CHANGE)); + CONFIRM_ITEM(MSG_BLTOUCH_MODE_STORE_OD, MSG_BLTOUCH_MODE_STORE_OD, MSG_BUTTON_CANCEL, bltouch.mode_conv_OD, nullptr, GET_TEXT(MSG_BLTOUCH_MODE_CHANGE)); ACTION_ITEM(MSG_BLTOUCH_MODE_ECHO, bltouch_report); #endif END_MENU(); @@ -215,9 +241,10 @@ void menu_advanced_settings(); #endif #if ENABLED(TOUCH_MI_PROBE) + void menu_touchmi() { - START_MENU(); ui.defer_status_screen(); + START_MENU(); BACK_ITEM(MSG_CONFIGURATION); GCODES_ITEM(MSG_TOUCHMI_INIT, PSTR("M851 Z0\nG28\nG1 F200 Z0")); SUBMENU(MSG_ZPROBE_ZOFFSET, lcd_babystep_zoffset); @@ -225,23 +252,24 @@ void menu_advanced_settings(); GCODES_ITEM(MSG_TOUCHMI_ZTEST, PSTR("G28\nG1 F200 Z0")); END_MENU(); } -#endif -#if ENABLED(CASE_LIGHT_MENU) +#endif - #include "../../feature/caselight.h" +#if ENABLED(CONTROLLER_FAN_MENU) - #if DISABLED(CASE_LIGHT_NO_BRIGHTNESS) + #include "../../feature/controllerfan.h" - void menu_case_light() { - START_MENU(); - BACK_ITEM(MSG_CONFIGURATION); - EDIT_ITEM(percent, MSG_CASE_LIGHT_BRIGHTNESS, &case_light_brightness, 0, 255, update_case_light, true); - EDIT_ITEM(bool, MSG_CASE_LIGHT, (bool*)&case_light_on, update_case_light); - END_MENU(); + void menu_controller_fan() { + START_MENU(); + BACK_ITEM(MSG_CONFIGURATION); + EDIT_ITEM_FAST(percent, MSG_CONTROLLER_FAN_IDLE_SPEED, &controllerFan.settings.idle_speed, _MAX(1, CONTROLLERFAN_SPEED_MIN) - 1, 255); + EDIT_ITEM(bool, MSG_CONTROLLER_FAN_AUTO_ON, &controllerFan.settings.auto_mode); + if (controllerFan.settings.auto_mode) { + EDIT_ITEM_FAST(percent, MSG_CONTROLLER_FAN_SPEED, &controllerFan.settings.active_speed, _MAX(1, CONTROLLERFAN_SPEED_MIN) - 1, 255); + EDIT_ITEM(uint16_4, MSG_CONTROLLER_FAN_DURATION, &controllerFan.settings.duration, 0, 4800); } - - #endif + END_MENU(); + } #endif @@ -256,17 +284,17 @@ void menu_advanced_settings(); EDIT_ITEM(bool, MSG_AUTORETRACT, &fwretract.autoretract_enabled, fwretract.refresh_autoretract); #endif EDIT_ITEM(float52sign, MSG_CONTROL_RETRACT, &fwretract.settings.retract_length, 0, 100); - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER EDIT_ITEM(float52sign, MSG_CONTROL_RETRACT_SWAP, &fwretract.settings.swap_retract_length, 0, 100); #endif EDIT_ITEM(float3, MSG_CONTROL_RETRACTF, &fwretract.settings.retract_feedrate_mm_s, 1, 999); EDIT_ITEM(float52sign, MSG_CONTROL_RETRACT_ZHOP, &fwretract.settings.retract_zraise, 0, 999); EDIT_ITEM(float52sign, MSG_CONTROL_RETRACT_RECOVER, &fwretract.settings.retract_recover_extra, -100, 100); - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER EDIT_ITEM(float52sign, MSG_CONTROL_RETRACT_RECOVER_SWAP, &fwretract.settings.swap_retract_recover_extra, -100, 100); #endif EDIT_ITEM(float3, MSG_CONTROL_RETRACT_RECOVERF, &fwretract.settings.retract_recover_feedrate_mm_s, 1, 999); - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER EDIT_ITEM(float3, MSG_CONTROL_RETRACT_RECOVER_SWAPF, &fwretract.settings.swap_retract_recover_feedrate_mm_s, 1, 999); #endif END_MENU(); @@ -274,34 +302,38 @@ void menu_advanced_settings(); #endif -#if DISABLED(SLIM_LCD_MENUS) +#if PREHEAT_COUNT && DISABLED(SLIM_LCD_MENUS) - void _menu_configuration_preheat_settings(const uint8_t material) { + void _menu_configuration_preheat_settings() { #define _MINTEMP_ITEM(N) HEATER_##N##_MINTEMP, #define _MAXTEMP_ITEM(N) HEATER_##N##_MAXTEMP, #define MINTEMP_ALL _MIN(REPEAT(HOTENDS, _MINTEMP_ITEM) 999) #define MAXTEMP_ALL _MAX(REPEAT(HOTENDS, _MAXTEMP_ITEM) 0) + const uint8_t m = MenuItemBase::itemIndex; START_MENU(); + STATIC_ITEM_P(ui.get_preheat_label(m), SS_DEFAULT|SS_INVERT); BACK_ITEM(MSG_CONFIGURATION); - EDIT_ITEM(percent, MSG_FAN_SPEED, &ui.preheat_fan_speed[material], 0, 255); + #if HAS_FAN + editable.uint8 = uint8_t(ui.material_preset[m].fan_speed); + EDIT_ITEM_N(percent, m, MSG_FAN_SPEED, &editable.uint8, 0, 255, []{ ui.material_preset[MenuItemBase::itemIndex].fan_speed = editable.uint8; }); + #endif #if HAS_TEMP_HOTEND - EDIT_ITEM(int3, MSG_NOZZLE, &ui.preheat_hotend_temp[material], MINTEMP_ALL, MAXTEMP_ALL - 15); + EDIT_ITEM(uint16_3, MSG_NOZZLE, &ui.material_preset[m].hotend_temp, MINTEMP_ALL, MAXTEMP_ALL - HOTEND_OVERSHOOT); #endif #if HAS_HEATED_BED - EDIT_ITEM(int3, MSG_BED, &ui.preheat_bed_temp[material], BED_MINTEMP, BED_MAXTEMP - 10); + EDIT_ITEM(uint16_3, MSG_BED, &ui.material_preset[m].bed_temp, BED_MINTEMP, BED_MAX_TARGET); #endif #if ENABLED(EEPROM_SETTINGS) - ACTION_ITEM(MSG_STORE_EEPROM, lcd_store_settings); + ACTION_ITEM(MSG_STORE_EEPROM, ui.store_settings); #endif END_MENU(); } - void menu_preheat_material1_settings() { _menu_configuration_preheat_settings(0); } - void menu_preheat_material2_settings() { _menu_configuration_preheat_settings(1); } - #endif void menu_configuration() { + const bool busy = printer_busy(); + START_MENU(); BACK_ITEM(MSG_MAIN); @@ -320,7 +352,13 @@ void menu_configuration() { EDIT_ITEM(LCD_Z_OFFSET_TYPE, MSG_ZPROBE_ZOFFSET, &probe.offset.z, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX); #endif - const bool busy = printer_busy(); + // + // Set Fan Controller speed + // + #if ENABLED(CONTROLLER_FAN_MENU) + SUBMENU(MSG_CONTROLLER_FAN, menu_controller_fan); + #endif + if (!busy) { #if EITHER(DELTA_CALIBRATION_MENU, DELTA_AUTO_CALIBRATION) SUBMENU(MSG_DELTA_CALIBRATE, menu_delta_calibrate); @@ -346,24 +384,11 @@ void menu_configuration() { // // Set single nozzle filament retract and prime length // - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER SUBMENU(MSG_TOOL_CHANGE, menu_tool_change); - #endif - - // - // Set Case light on/off/brightness - // - #if ENABLED(CASE_LIGHT_MENU) - #if DISABLED(CASE_LIGHT_NO_BRIGHTNESS) - if (true - #if DISABLED(CASE_LIGHT_USE_NEOPIXEL) - && PWM_PIN(CASE_LIGHT_PIN) - #endif - ) - SUBMENU(MSG_CASE_LIGHT, menu_case_light); - else + #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) + SUBMENU(MSG_TOOL_MIGRATION, menu_toolchange_migration); #endif - EDIT_ITEM(bool, MSG_CASE_LIGHT, (bool*)&case_light_on, update_case_light); #endif #if HAS_LCD_CONTRAST @@ -381,25 +406,18 @@ void menu_configuration() { EDIT_ITEM(bool, MSG_OUTAGE_RECOVERY, &recovery.enabled, recovery.changed); #endif - #if DISABLED(SLIM_LCD_MENUS) - // Preheat configurations - SUBMENU(MSG_PREHEAT_1_SETTINGS, menu_preheat_material1_settings); - SUBMENU(MSG_PREHEAT_2_SETTINGS, menu_preheat_material2_settings); + // Preheat configurations + #if PREHEAT_COUNT && DISABLED(SLIM_LCD_MENUS) + LOOP_L_N(m, PREHEAT_COUNT) + SUBMENU_N_S(m, ui.get_preheat_label(m), MSG_PREHEAT_M_SETTINGS, _menu_configuration_preheat_settings); #endif #if ENABLED(EEPROM_SETTINGS) - ACTION_ITEM(MSG_STORE_EEPROM, lcd_store_settings); - if (!busy) - ACTION_ITEM(MSG_LOAD_EEPROM, lcd_load_settings); + ACTION_ITEM(MSG_STORE_EEPROM, ui.store_settings); + if (!busy) ACTION_ITEM(MSG_LOAD_EEPROM, ui.load_settings); #endif - if (!busy) - ACTION_ITEM(MSG_RESTORE_DEFAULTS, []{ - settings.reset(); - #if HAS_BUZZER - ui.completion_feedback(); - #endif - }); + if (!busy) ACTION_ITEM(MSG_RESTORE_DEFAULTS, ui.reset_settings); END_MENU(); } diff --git a/Marlin/src/lcd/menu/menu_custom.cpp b/Marlin/src/lcd/menu/menu_custom.cpp index 55297a8b9217..7c54ec6e2616 100644 --- a/Marlin/src/lcd/menu/menu_custom.cpp +++ b/Marlin/src/lcd/menu/menu_custom.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -26,9 +26,9 @@ #include "../../inc/MarlinConfigPre.h" -#if HAS_LCD_MENU && ENABLED(CUSTOM_USER_MENUS) +#if BOTH(HAS_LCD_MENU, CUSTOM_USER_MENUS) -#include "menu.h" +#include "menu_item.h" #include "../../gcode/queue.h" #ifdef USER_SCRIPT_DONE @@ -39,12 +39,8 @@ void _lcd_user_gcode(PGM_P const cmd) { queue.inject_P(cmd); - #if ENABLED(USER_SCRIPT_AUDIBLE_FEEDBACK) && HAS_BUZZER - ui.completion_feedback(); - #endif - #if ENABLED(USER_SCRIPT_RETURN) - ui.return_to_status(); - #endif + TERN_(USER_SCRIPT_AUDIBLE_FEEDBACK, ui.completion_feedback()); + TERN_(USER_SCRIPT_RETURN, ui.return_to_status()); } void menu_user() { diff --git a/Marlin/src/lcd/menu/menu_delta_calibrate.cpp b/Marlin/src/lcd/menu/menu_delta_calibrate.cpp index 2b3cac5bd2b4..4efcb7c8eded 100644 --- a/Marlin/src/lcd/menu/menu_delta_calibrate.cpp +++ b/Marlin/src/lcd/menu/menu_delta_calibrate.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -28,7 +28,7 @@ #if HAS_LCD_MENU && EITHER(DELTA_CALIBRATION_MENU, DELTA_AUTO_CALIBRATION) -#include "menu.h" +#include "menu_item.h" #include "../../module/delta.h" #include "../../module/motion.h" @@ -37,7 +37,7 @@ #endif #if ENABLED(EXTENSIBLE_UI) - #include "../../lcd/extensible_ui/ui_api.h" + #include "../../lcd/extui/ui_api.h" #endif void _man_probe_pt(const xy_pos_t &xy) { @@ -46,7 +46,7 @@ void _man_probe_pt(const xy_pos_t &xy) { do_blocking_move_to_xy_z(xy, Z_CLEARANCE_BETWEEN_PROBES); ui.wait_for_move = false; ui.synchronize(); - move_menu_scale = _MAX(PROBE_MANUALLY_STEP, MIN_STEPS_PER_SEGMENT / float(DEFAULT_XYZ_STEPS_PER_UNIT)); + ui.manual_move.menu_scale = _MAX(PROBE_MANUALLY_STEP, MIN_STEPS_PER_SEGMENT / float(DEFAULT_XYZ_STEPS_PER_UNIT)); ui.goto_screen(lcd_move_z); } } @@ -61,16 +61,10 @@ void _man_probe_pt(const xy_pos_t &xy) { float lcd_probe_pt(const xy_pos_t &xy) { _man_probe_pt(xy); - KEEPALIVE_STATE(PAUSED_FOR_USER); ui.defer_status_screen(); - wait_for_user = true; - #if ENABLED(HOST_PROMPT_SUPPORT) - host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Delta Calibration in progress"), CONTINUE_STR); - #endif - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onUserConfirmRequired_P(PSTR("Delta Calibration in progress")); - #endif - while (wait_for_user) idle(); + TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Delta Calibration in progress"), CONTINUE_STR)); + TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(PSTR("Delta Calibration in progress"))); + wait_for_user_response(); ui.goto_previous_screen_no_defer(); return current_position.z; } @@ -103,10 +97,8 @@ void _man_probe_pt(const xy_pos_t &xy) { #endif void lcd_delta_settings() { - auto _recalc_delta_settings = []() { - #if HAS_LEVELING - reset_bed_level(); // After changing kinematics bed-level data is no longer valid - #endif + auto _recalc_delta_settings = []{ + TERN_(HAS_LEVELING, reset_bed_level()); // After changing kinematics bed-level data is no longer valid recalc_delta_settings(); }; START_MENU(); @@ -126,14 +118,16 @@ void lcd_delta_settings() { } void menu_delta_calibrate() { + TERN_(DELTA_CALIBRATION_MENU, const bool all_homed = all_axes_homed()); // Acquire ahead of loop + START_MENU(); BACK_ITEM(MSG_MAIN); #if ENABLED(DELTA_AUTO_CALIBRATION) GCODES_ITEM(MSG_DELTA_AUTO_CALIBRATE, PSTR("G33")); #if ENABLED(EEPROM_SETTINGS) - ACTION_ITEM(MSG_STORE_EEPROM, lcd_store_settings); - ACTION_ITEM(MSG_LOAD_EEPROM, lcd_load_settings); + ACTION_ITEM(MSG_STORE_EEPROM, ui.store_settings); + ACTION_ITEM(MSG_LOAD_EEPROM, ui.load_settings); #endif #endif @@ -141,7 +135,7 @@ void menu_delta_calibrate() { #if ENABLED(DELTA_CALIBRATION_MENU) SUBMENU(MSG_AUTO_HOME, _lcd_delta_calibrate_home); - if (all_axes_homed()) { + if (all_homed) { SUBMENU(MSG_DELTA_CALIBRATE_X, _goto_tower_x); SUBMENU(MSG_DELTA_CALIBRATE_Y, _goto_tower_y); SUBMENU(MSG_DELTA_CALIBRATE_Z, _goto_tower_z); diff --git a/Marlin/src/lcd/menu/menu_filament.cpp b/Marlin/src/lcd/menu/menu_filament.cpp index 5f2ecb9ccd33..d116a6a398c0 100644 --- a/Marlin/src/lcd/menu/menu_filament.cpp +++ b/Marlin/src/lcd/menu/menu_filament.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -26,11 +26,12 @@ #include "../../inc/MarlinConfigPre.h" -#if HAS_LCD_MENU && ENABLED(ADVANCED_PAUSE_FEATURE) +#if BOTH(HAS_LCD_MENU, ADVANCED_PAUSE_FEATURE) -#include "menu.h" +#include "menu_item.h" #include "../../module/temperature.h" #include "../../feature/pause.h" +#include "../../gcode/queue.h" #if HAS_FILAMENT_SENSOR #include "../../feature/runout.h" #endif @@ -38,29 +39,35 @@ // // Change Filament > Change/Unload/Load Filament // -static PauseMode _change_filament_temp_mode; // =PAUSE_MODE_PAUSE_PRINT -static int8_t _change_filament_temp_extruder; // =0 - -inline PGM_P _change_filament_temp_command() { - switch (_change_filament_temp_mode) { - case PAUSE_MODE_LOAD_FILAMENT: - return PSTR("M701 T%d"); - case PAUSE_MODE_UNLOAD_FILAMENT: - return _change_filament_temp_extruder >= 0 ? PSTR("M702 T%d") : PSTR("M702 ;%d"); +static PauseMode _change_filament_mode; // = PAUSE_MODE_PAUSE_PRINT +static int8_t _change_filament_extruder; // = 0 + +inline PGM_P _change_filament_command() { + switch (_change_filament_mode) { + case PAUSE_MODE_LOAD_FILAMENT: return PSTR("M701 T%d"); + case PAUSE_MODE_UNLOAD_FILAMENT: return _change_filament_extruder >= 0 + ? PSTR("M702 T%d") : PSTR("M702 ;%d"); case PAUSE_MODE_CHANGE_FILAMENT: case PAUSE_MODE_PAUSE_PRINT: - default: - return PSTR("M600 B0 T%d"); + default: break; } - return GET_TEXT(MSG_FILAMENTCHANGE); + return PSTR("M600 B0 T%d"); } // Initiate Filament Load/Unload/Change at the specified temperature -static void _change_filament_temp(const uint16_t temperature) { +static void _change_filament_with_temp(const uint16_t celsius) { char cmd[11]; - sprintf_P(cmd, _change_filament_temp_command(), _change_filament_temp_extruder); - thermalManager.setTargetHotend(temperature, _change_filament_temp_extruder); - lcd_enqueue_one_now(cmd); + sprintf_P(cmd, _change_filament_command(), _change_filament_extruder); + thermalManager.setTargetHotend(celsius, _change_filament_extruder); + queue.inject(cmd); +} + +static void _change_filament_with_preset() { + _change_filament_with_temp(ui.material_preset[MenuItemBase::itemIndex].hotend_temp); +} + +static void _change_filament_with_custom() { + _change_filament_with_temp(thermalManager.temp_hotend[MenuItemBase::itemIndex].target); } // @@ -69,42 +76,52 @@ static void _change_filament_temp(const uint16_t temperature) { inline PGM_P change_filament_header(const PauseMode mode) { switch (mode) { - case PAUSE_MODE_LOAD_FILAMENT: - return GET_TEXT(MSG_FILAMENTLOAD); - case PAUSE_MODE_UNLOAD_FILAMENT: - return GET_TEXT(MSG_FILAMENTUNLOAD); + case PAUSE_MODE_LOAD_FILAMENT: return GET_TEXT(MSG_FILAMENTLOAD); + case PAUSE_MODE_UNLOAD_FILAMENT: return GET_TEXT(MSG_FILAMENTUNLOAD); default: break; } return GET_TEXT(MSG_FILAMENTCHANGE); } void _menu_temp_filament_op(const PauseMode mode, const int8_t extruder) { - _change_filament_temp_mode = mode; - _change_filament_temp_extruder = extruder; + _change_filament_mode = mode; + _change_filament_extruder = extruder; START_MENU(); - if (LCD_HEIGHT >= 4) STATIC_ITEM_P(change_filament_header(mode), SS_CENTER|SS_INVERT); + if (LCD_HEIGHT >= 4) STATIC_ITEM_P(change_filament_header(mode), SS_DEFAULT|SS_INVERT); BACK_ITEM(MSG_BACK); - ACTION_ITEM(MSG_PREHEAT_1, []{ _change_filament_temp(ui.preheat_hotend_temp[0]); }); - ACTION_ITEM(MSG_PREHEAT_2, []{ _change_filament_temp(ui.preheat_hotend_temp[1]); }); - EDIT_ITEM_FAST(int3, MSG_PREHEAT_CUSTOM, &thermalManager.temp_hotend[_change_filament_temp_extruder].target, EXTRUDE_MINTEMP, heater_maxtemp[extruder] - 15, []{ - _change_filament_temp(thermalManager.temp_hotend[_change_filament_temp_extruder].target); - }); + #if PREHEAT_COUNT + LOOP_L_N(m, PREHEAT_COUNT) + ACTION_ITEM_N_S(m, ui.get_preheat_label(m), MSG_PREHEAT_M, _change_filament_with_preset); + #endif + EDIT_ITEM_FAST_N(int3, extruder, MSG_PREHEAT_CUSTOM, &thermalManager.temp_hotend[extruder].target, + EXTRUDE_MINTEMP, thermalManager.heater_maxtemp[extruder] - HOTEND_OVERSHOOT, + _change_filament_with_custom + ); END_MENU(); } /** - * * "Change Filament" submenu - * */ #if E_STEPPERS > 1 || ENABLED(FILAMENT_LOAD_UNLOAD_GCODES) - void menu_change_filament() { - START_MENU(); - BACK_ITEM(MSG_MAIN); + void menu_change_filament() { // Say "filament change" when no print is active editable.int8 = printingIsPaused() ? PAUSE_MODE_PAUSE_PRINT : PAUSE_MODE_CHANGE_FILAMENT; + #if E_STEPPERS > 1 && ENABLED(FILAMENT_UNLOAD_ALL_EXTRUDERS) + bool too_cold = false; + for (uint8_t s = 0; !too_cold && s < E_STEPPERS; s++) + too_cold = thermalManager.targetTooColdToExtrude(s); + #endif + + #if ENABLED(FILAMENT_LOAD_UNLOAD_GCODES) + const bool is_busy = printer_busy(); + #endif + + START_MENU(); + BACK_ITEM(MSG_MAIN); + // Change filament #if E_STEPPERS == 1 PGM_P const msg = GET_TEXT(MSG_FILAMENTCHANGE); @@ -114,21 +131,22 @@ void _menu_temp_filament_op(const PauseMode mode, const int8_t extruder) { GCODES_ITEM_P(msg, PSTR("M600 B0")); #else PGM_P const msg = GET_TEXT(MSG_FILAMENTCHANGE_E); - for (uint8_t s = 0; s < E_STEPPERS; s++) { + LOOP_L_N(s, E_STEPPERS) { if (thermalManager.targetTooColdToExtrude(s)) SUBMENU_N_P(s, msg, []{ _menu_temp_filament_op(PAUSE_MODE_CHANGE_FILAMENT, MenuItemBase::itemIndex); }); else { ACTION_ITEM_N_P(s, msg, []{ - char cmd[13]; - sprintf_P(cmd, PSTR("M600 B0 T%i"), int(MenuItemBase::itemIndex)); - lcd_enqueue_one_now(cmd); + PGM_P const cmdpstr = PSTR("M600 B0 T%i"); + char cmd[strlen_P(cmdpstr) + 3 + 1]; + sprintf_P(cmd, cmdpstr, int(MenuItemBase::itemIndex)); + queue.inject(cmd); }); } } #endif #if ENABLED(FILAMENT_LOAD_UNLOAD_GCODES) - if (!printer_busy()) { + if (!is_busy) { // Load filament #if E_STEPPERS == 1 PGM_P const msg_load = GET_TEXT(MSG_FILAMENTLOAD); @@ -138,14 +156,14 @@ void _menu_temp_filament_op(const PauseMode mode, const int8_t extruder) { GCODES_ITEM_P(msg_load, PSTR("M701")); #else PGM_P const msg_load = GET_TEXT(MSG_FILAMENTLOAD_E); - for (uint8_t s = 0; s < E_STEPPERS; s++) { + LOOP_L_N(s, E_STEPPERS) { if (thermalManager.targetTooColdToExtrude(s)) SUBMENU_N_P(s, msg_load, []{ _menu_temp_filament_op(PAUSE_MODE_LOAD_FILAMENT, MenuItemBase::itemIndex); }); else { ACTION_ITEM_N_P(s, msg_load, []{ char cmd[12]; sprintf_P(cmd, PSTR("M701 T%i"), int(MenuItemBase::itemIndex)); - lcd_enqueue_one_now(cmd); + queue.inject(cmd); }); } } @@ -160,28 +178,20 @@ void _menu_temp_filament_op(const PauseMode mode, const int8_t extruder) { GCODES_ITEM_P(msg_unload, PSTR("M702")); #else #if ENABLED(FILAMENT_UNLOAD_ALL_EXTRUDERS) - { - bool too_cold = false; - for (uint8_t s = 0; s < E_STEPPERS; s++) { - if (thermalManager.targetTooColdToExtrude(s)) { - too_cold = true; break; - } - } - if (!too_cold) - GCODES_ITEM(MSG_FILAMENTUNLOAD_ALL, PSTR("M702")); - else + if (too_cold) SUBMENU(MSG_FILAMENTUNLOAD_ALL, []{ _menu_temp_filament_op(PAUSE_MODE_UNLOAD_FILAMENT, -1); }); - } + else + GCODES_ITEM(MSG_FILAMENTUNLOAD_ALL, PSTR("M702")); #endif PGM_P const msg_unload = GET_TEXT(MSG_FILAMENTUNLOAD_E); - for (uint8_t s = 0; s < E_STEPPERS; s++) { + LOOP_L_N(s, E_STEPPERS) { if (thermalManager.targetTooColdToExtrude(s)) SUBMENU_N_P(s, msg_unload, []{ _menu_temp_filament_op(PAUSE_MODE_UNLOAD_FILAMENT, MenuItemBase::itemIndex); }); else { ACTION_ITEM_N_P(s, msg_unload, []{ char cmd[12]; sprintf_P(cmd, PSTR("M702 T%i"), int(MenuItemBase::itemIndex)); - lcd_enqueue_one_now(cmd); + queue.inject(cmd); }); } } @@ -197,12 +207,9 @@ static uint8_t hotend_status_extruder = 0; static PGM_P pause_header() { switch (pause_mode) { - case PAUSE_MODE_CHANGE_FILAMENT: - return GET_TEXT(MSG_FILAMENT_CHANGE_HEADER); - case PAUSE_MODE_LOAD_FILAMENT: - return GET_TEXT(MSG_FILAMENT_CHANGE_HEADER_LOAD); - case PAUSE_MODE_UNLOAD_FILAMENT: - return GET_TEXT(MSG_FILAMENT_CHANGE_HEADER_UNLOAD); + case PAUSE_MODE_CHANGE_FILAMENT: return GET_TEXT(MSG_FILAMENT_CHANGE_HEADER); + case PAUSE_MODE_LOAD_FILAMENT: return GET_TEXT(MSG_FILAMENT_CHANGE_HEADER_LOAD); + case PAUSE_MODE_UNLOAD_FILAMENT: return GET_TEXT(MSG_FILAMENT_CHANGE_HEADER_UNLOAD); default: break; } return GET_TEXT(MSG_FILAMENT_CHANGE_HEADER_PAUSE); @@ -212,7 +219,7 @@ static PGM_P pause_header() { #define HOTEND_STATUS_ITEM() do { \ if (_menuLineNr == _thisItemNr) { \ if (ui.should_draw()) { \ - MenuItem_static::draw(_lcdLineNr, GET_TEXT(MSG_FILAMENT_CHANGE_NOZZLE), SS_INVERT); \ + TERN(HAS_GRAPHICAL_TFT,, MenuItem_static::draw(_lcdLineNr, GET_TEXT(MSG_FILAMENT_CHANGE_NOZZLE), SS_INVERT)); \ ui.draw_hotend_status(_lcdLineNr, hotend_status_extruder); \ } \ if (_skipStatic && encoderLine <= _thisItemNr) { \ @@ -230,11 +237,18 @@ void menu_pause_option() { STATIC_ITEM(MSG_FILAMENT_CHANGE_OPTION_HEADER); #endif ACTION_ITEM(MSG_FILAMENT_CHANGE_OPTION_PURGE, []{ pause_menu_response = PAUSE_RESPONSE_EXTRUDE_MORE; }); + #if HAS_FILAMENT_SENSOR - if (runout.filament_ran_out) + const bool still_out = runout.filament_ran_out; + if (still_out) EDIT_ITEM(bool, MSG_RUNOUT_SENSOR, &runout.enabled, runout.reset); + #else + constexpr bool still_out = false; #endif - ACTION_ITEM(MSG_FILAMENT_CHANGE_OPTION_RESUME, []{ pause_menu_response = PAUSE_RESPONSE_RESUME_PRINT; }); + + if (!still_out) + ACTION_ITEM(MSG_FILAMENT_CHANGE_OPTION_RESUME, []{ pause_menu_response = PAUSE_RESPONSE_RESUME_PRINT; }); + END_MENU(); } @@ -251,7 +265,7 @@ void _lcd_pause_message(PGM_P const msg) { skip1 = !has2 && (LCD_HEIGHT) >= 5; START_SCREEN(); - STATIC_ITEM_P(pause_header(), SS_CENTER|SS_INVERT); // 1: Header + STATIC_ITEM_P(pause_header(), SS_DEFAULT|SS_INVERT); // 1: Header if (skip1) SKIP_ITEM(); // Move a single-line message down STATIC_ITEM_P(msg1); // 2: Message Line 1 if (has2) STATIC_ITEM_P(msg2); // 3: Message Line 2 @@ -261,7 +275,7 @@ void _lcd_pause_message(PGM_P const msg) { END_SCREEN(); } -void lcd_pause_pausing_message() { _lcd_pause_message(GET_TEXT(MSG_PAUSE_PRINT_INIT)); } +void lcd_pause_parking_message() { _lcd_pause_message(GET_TEXT(MSG_PAUSE_PRINT_PARKING)); } void lcd_pause_changing_message() { _lcd_pause_message(GET_TEXT(MSG_FILAMENT_CHANGE_INIT)); } void lcd_pause_unload_message() { _lcd_pause_message(GET_TEXT(MSG_FILAMENT_CHANGE_UNLOAD)); } void lcd_pause_heating_message() { _lcd_pause_message(GET_TEXT(MSG_FILAMENT_CHANGE_HEATING)); } @@ -281,7 +295,7 @@ void lcd_pause_purge_message() { FORCE_INLINE screenFunc_t ap_message_screen(const PauseMessage message) { switch (message) { - case PAUSE_MESSAGE_PAUSING: return lcd_pause_pausing_message; + case PAUSE_MESSAGE_PARKING: return lcd_pause_parking_message; case PAUSE_MESSAGE_CHANGING: return lcd_pause_changing_message; case PAUSE_MESSAGE_UNLOAD: return lcd_pause_unload_message; case PAUSE_MESSAGE_WAITING: return lcd_pause_waiting_message; diff --git a/Marlin/src/lcd/menu/menu_game.cpp b/Marlin/src/lcd/menu/menu_game.cpp index c2ac9f62a97a..fa56d7eee266 100644 --- a/Marlin/src/lcd/menu/menu_game.cpp +++ b/Marlin/src/lcd/menu/menu_game.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -24,18 +24,12 @@ #if HAS_GAME_MENU -#include "menu.h" +#include "menu_item.h" #include "game/game.h" void menu_game() { START_MENU(); - BACK_ITEM( - #if ENABLED(LCD_INFO_MENU) - MSG_INFO_MENU - #else - MSG_MAIN - #endif - ); + BACK_ITEM(TERN(LCD_INFO_MENU, MSG_INFO_MENU, MSG_MAIN)); #if ENABLED(MARLIN_BRICKOUT) SUBMENU(MSG_BRICKOUT, brickout.enter_game); #endif diff --git a/Marlin/src/lcd/menu/menu_info.cpp b/Marlin/src/lcd/menu/menu_info.cpp index 284c3eb1a5ea..a4cbc31d8b6b 100644 --- a/Marlin/src/lcd/menu/menu_info.cpp +++ b/Marlin/src/lcd/menu/menu_info.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -26,16 +26,16 @@ #include "../../inc/MarlinConfigPre.h" -#if HAS_LCD_MENU && ENABLED(LCD_INFO_MENU) +#if BOTH(HAS_LCD_MENU, LCD_INFO_MENU) -#include "menu.h" +#include "menu_item.h" #if HAS_GAMES #include "game/game.h" #endif -#define VALUE_ITEM(MSG, VALUE, STYL) do{ strcpy_P(buffer, PSTR(": ")); strcpy(buffer + 2, VALUE); STATIC_ITEM(MSG, STYL, buffer); }while(0) -#define VALUE_ITEM_P(MSG, PVALUE, STYL) do{ strcpy_P(buffer, PSTR(": ")); strcpy_P(buffer + 2, PSTR(PVALUE)); STATIC_ITEM(MSG, STYL, buffer); }while(0) +#define VALUE_ITEM(MSG, VALUE, STYL) do{ char msg[21]; strcpy_P(msg, PSTR(": ")); strcpy(msg + 2, VALUE); STATIC_ITEM(MSG, STYL, msg); }while(0) +#define VALUE_ITEM_P(MSG, PVALUE, STYL) do{ char msg[21]; strcpy_P(msg, PSTR(": ")); strcpy_P(msg + 2, PSTR(PVALUE)); STATIC_ITEM(MSG, STYL, msg); }while(0) #if ENABLED(PRINTCOUNTER) @@ -47,31 +47,34 @@ void menu_info_stats() { if (ui.use_click()) return ui.go_back(); - char buffer[21]; // For macro usage - printStatistics stats = print_job_timer.getStats(); - START_SCREEN(); // 12345678901234567890 - VALUE_ITEM(MSG_INFO_PRINT_COUNT, i16tostr3left(stats.totalPrints), SS_LEFT); // Print Count: 999 - VALUE_ITEM(MSG_INFO_COMPLETED_PRINTS, i16tostr3left(stats.finishedPrints), SS_LEFT); // Completed : 666 + char buffer[21]; + + START_SCREEN(); // 12345678901234567890 + VALUE_ITEM(MSG_INFO_PRINT_COUNT, i16tostr3left(stats.totalPrints), SS_LEFT); // Print Count: 999 + VALUE_ITEM(MSG_INFO_COMPLETED_PRINTS, i16tostr3left(stats.finishedPrints), SS_LEFT); // Completed : 666 - STATIC_ITEM(MSG_INFO_PRINT_TIME, SS_LEFT); // Total print Time: - STATIC_ITEM_P(PSTR("> "), SS_LEFT, duration_t(stats.printTime).toString(buffer)); // > 99y 364d 23h 59m 59s + STATIC_ITEM(MSG_INFO_PRINT_TIME, SS_LEFT); // Total print Time: + STATIC_ITEM_P(PSTR("> "), SS_LEFT, duration_t(stats.printTime).toString(buffer)); // > 99y 364d 23h 59m 59s - STATIC_ITEM(MSG_INFO_PRINT_LONGEST, SS_LEFT); // Longest job time: - STATIC_ITEM_P(PSTR("> "), SS_LEFT, duration_t(stats.longestPrint).toString(buffer)); // > 99y 364d 23h 59m 59s + STATIC_ITEM(MSG_INFO_PRINT_LONGEST, SS_LEFT); // Longest job time: + STATIC_ITEM_P(PSTR("> "), SS_LEFT, duration_t(stats.longestPrint).toString(buffer)); // > 99y 364d 23h 59m 59s - STATIC_ITEM(MSG_INFO_PRINT_FILAMENT, SS_LEFT); // Extruded total: - sprintf_P(buffer, PSTR("%ld.%im"), long(stats.filamentUsed / 1000), int16_t(stats.filamentUsed / 100) % 10); - STATIC_ITEM_P(PSTR("> "), SS_LEFT, buffer); // > 125m + STATIC_ITEM(MSG_INFO_PRINT_FILAMENT, SS_LEFT); // Extruded total: + sprintf_P(buffer, PSTR("%ld.%im") + , long(stats.filamentUsed / 1000) + , int16_t(stats.filamentUsed / 100) % 10 + ); + STATIC_ITEM_P(PSTR("> "), SS_LEFT, buffer); // > 125m #if SERVICE_INTERVAL_1 > 0 || SERVICE_INTERVAL_2 > 0 || SERVICE_INTERVAL_3 > 0 strcpy_P(buffer, GET_TEXT(MSG_SERVICE_IN)); #endif #if SERVICE_INTERVAL_1 > 0 - STATIC_ITEM_P(PSTR(SERVICE_NAME_1 " "), SS_LEFT, buffer); // Service X in: - STATIC_ITEM_P(PSTR("> "), SS_LEFT, duration_t(stats.nextService1).toString(buffer)); // > 7d 12h 11m 10s + STATIC_ITEM_P(PSTR(SERVICE_NAME_1 " "), SS_LEFT, buffer); // Service X in: + STATIC_ITEM_P(PSTR("> "), SS_LEFT, duration_t(stats.nextService1).toString(buffer)); // > 7d 12h 11m 10s #endif #if SERVICE_INTERVAL_2 > 0 @@ -95,16 +98,14 @@ void menu_info_thermistors() { if (ui.use_click()) return ui.go_back(); - char buffer[21]; // For macro usage - START_SCREEN(); #if EXTRUDERS #define THERMISTOR_ID TEMP_SENSOR_0 #include "../thermistornames.h" STATIC_ITEM_P(PSTR(LCD_STR_E0 ": " THERMISTOR_NAME), SS_INVERT); - VALUE_ITEM_P(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_0_MINTEMP), SS_LEFT); - VALUE_ITEM_P(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_0_MAXTEMP), SS_LEFT); + PSTRING_ITEM(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_0_MINTEMP), SS_LEFT); + PSTRING_ITEM(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_0_MAXTEMP), SS_LEFT); #endif #if TEMP_SENSOR_1 != 0 @@ -112,8 +113,8 @@ void menu_info_thermistors() { #define THERMISTOR_ID TEMP_SENSOR_1 #include "../thermistornames.h" STATIC_ITEM_P(PSTR(LCD_STR_E1 ": " THERMISTOR_NAME), SS_INVERT); - VALUE_ITEM_P(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_1_MINTEMP), SS_LEFT); - VALUE_ITEM_P(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_1_MAXTEMP), SS_LEFT); + PSTRING_ITEM(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_1_MINTEMP), SS_LEFT); + PSTRING_ITEM(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_1_MAXTEMP), SS_LEFT); #endif #if TEMP_SENSOR_2 != 0 @@ -121,8 +122,8 @@ void menu_info_thermistors() { #define THERMISTOR_ID TEMP_SENSOR_2 #include "../thermistornames.h" STATIC_ITEM_P(PSTR(LCD_STR_E2 ": " THERMISTOR_NAME), SS_INVERT); - VALUE_ITEM_P(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_2_MINTEMP), SS_LEFT); - VALUE_ITEM_P(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_2_MAXTEMP), SS_LEFT); + PSTRING_ITEM(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_2_MINTEMP), SS_LEFT); + PSTRING_ITEM(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_2_MAXTEMP), SS_LEFT); #endif #if TEMP_SENSOR_3 != 0 @@ -130,8 +131,8 @@ void menu_info_thermistors() { #define THERMISTOR_ID TEMP_SENSOR_3 #include "../thermistornames.h" STATIC_ITEM_P(PSTR(LCD_STR_E3 ": " THERMISTOR_NAME), SS_INVERT); - VALUE_ITEM_P(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_3_MINTEMP), SS_LEFT); - VALUE_ITEM_P(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_3_MAXTEMP), SS_LEFT); + PSTRING_ITEM(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_3_MINTEMP), SS_LEFT); + PSTRING_ITEM(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_3_MAXTEMP), SS_LEFT); #endif #if TEMP_SENSOR_4 != 0 @@ -139,8 +140,8 @@ void menu_info_thermistors() { #define THERMISTOR_ID TEMP_SENSOR_4 #include "../thermistornames.h" STATIC_ITEM_P(PSTR(LCD_STR_E4 ": " THERMISTOR_NAME), SS_INVERT); - VALUE_ITEM_P(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_4_MINTEMP), SS_LEFT); - VALUE_ITEM_P(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_4_MAXTEMP), SS_LEFT); + PSTRING_ITEM(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_4_MINTEMP), SS_LEFT); + PSTRING_ITEM(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_4_MAXTEMP), SS_LEFT); #endif #if TEMP_SENSOR_5 != 0 @@ -148,8 +149,8 @@ void menu_info_thermistors() { #define THERMISTOR_ID TEMP_SENSOR_5 #include "../thermistornames.h" STATIC_ITEM_P(PSTR(LCD_STR_E5 ": " THERMISTOR_NAME), SS_INVERT); - VALUE_ITEM_P(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_5_MINTEMP), SS_LEFT); - VALUE_ITEM_P(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_5_MAXTEMP), SS_LEFT); + PSTRING_ITEM(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_5_MINTEMP), SS_LEFT); + PSTRING_ITEM(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_5_MAXTEMP), SS_LEFT); #endif #if TEMP_SENSOR_6 != 0 @@ -157,8 +158,8 @@ void menu_info_thermistors() { #define THERMISTOR_ID TEMP_SENSOR_6 #include "../thermistornames.h" STATIC_ITEM_P(PSTR(LCD_STR_E6 ": " THERMISTOR_NAME), SS_INVERT); - VALUE_ITEM_P(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_6_MINTEMP), SS_LEFT); - VALUE_ITEM_P(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_6_MAXTEMP), SS_LEFT); + PSTRING_ITEM(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_6_MINTEMP), SS_LEFT); + PSTRING_ITEM(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_6_MAXTEMP), SS_LEFT); #endif #if TEMP_SENSOR_7 != 0 @@ -166,59 +167,32 @@ void menu_info_thermistors() { #define THERMISTOR_ID TEMP_SENSOR_7 #include "../thermistornames.h" STATIC_ITEM_P(PSTR(LCD_STR_E7 ": " THERMISTOR_NAME), SS_INVERT); - VALUE_ITEM_P(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_7_MINTEMP), SS_LEFT); - VALUE_ITEM_P(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_7_MAXTEMP), SS_LEFT); + PSTRING_ITEM(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_7_MINTEMP), SS_LEFT); + PSTRING_ITEM(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_7_MAXTEMP), SS_LEFT); #endif #if EXTRUDERS - { - STATIC_ITEM( - #if WATCH_HOTENDS - MSG_INFO_RUNAWAY_ON - #else - MSG_INFO_RUNAWAY_OFF - #endif - , SS_LEFT - ); - } + STATIC_ITEM(TERN(WATCH_HOTENDS, MSG_INFO_RUNAWAY_ON, MSG_INFO_RUNAWAY_OFF), SS_LEFT); #endif #if HAS_HEATED_BED - { #undef THERMISTOR_ID #define THERMISTOR_ID TEMP_SENSOR_BED #include "../thermistornames.h" - STATIC_ITEM_P(PSTR("BED:" THERMISTOR_NAME), SS_INVERT); - VALUE_ITEM_P(MSG_INFO_MIN_TEMP, STRINGIFY(BED_MINTEMP), SS_LEFT); - VALUE_ITEM_P(MSG_INFO_MAX_TEMP, STRINGIFY(BED_MAXTEMP), SS_LEFT); - STATIC_ITEM( - #if WATCH_BED - MSG_INFO_RUNAWAY_ON - #else - MSG_INFO_RUNAWAY_OFF - #endif - , SS_LEFT - ); - } + STATIC_ITEM_P(PSTR("BED: " THERMISTOR_NAME), SS_INVERT); + PSTRING_ITEM(MSG_INFO_MIN_TEMP, STRINGIFY(BED_MINTEMP), SS_LEFT); + PSTRING_ITEM(MSG_INFO_MAX_TEMP, STRINGIFY(BED_MAXTEMP), SS_LEFT); + STATIC_ITEM(TERN(WATCH_BED, MSG_INFO_RUNAWAY_ON, MSG_INFO_RUNAWAY_OFF), SS_LEFT); #endif #if HAS_HEATED_CHAMBER - { #undef THERMISTOR_ID #define THERMISTOR_ID TEMP_SENSOR_CHAMBER #include "../thermistornames.h" - STATIC_ITEM_P(PSTR("CHAM:" THERMISTOR_NAME), SS_INVERT); - VALUE_ITEM_P(MSG_INFO_MIN_TEMP, STRINGIFY(CHAMBER_MINTEMP), SS_LEFT); - VALUE_ITEM_P(MSG_INFO_MAX_TEMP, STRINGIFY(CHAMBER_MAXTEMP), SS_LEFT); - STATIC_ITEM( - #if WATCH_CHAMBER - MSG_INFO_RUNAWAY_ON - #else - MSG_INFO_RUNAWAY_OFF - #endif - , SS_LEFT - ); - } + STATIC_ITEM_P(PSTR("CHAM: " THERMISTOR_NAME), SS_INVERT); + PSTRING_ITEM(MSG_INFO_MIN_TEMP, STRINGIFY(CHAMBER_MINTEMP), SS_LEFT); + PSTRING_ITEM(MSG_INFO_MAX_TEMP, STRINGIFY(CHAMBER_MAXTEMP), SS_LEFT); + STATIC_ITEM(TERN(WATCH_CHAMBER, MSG_INFO_RUNAWAY_ON, MSG_INFO_RUNAWAY_OFF), SS_LEFT); #endif END_SCREEN(); @@ -230,16 +204,14 @@ void menu_info_thermistors() { void menu_info_board() { if (ui.use_click()) return ui.go_back(); - char buffer[21]; // For macro usage - START_SCREEN(); - STATIC_ITEM_P(PSTR(BOARD_INFO_NAME), SS_CENTER|SS_INVERT); // MyPrinterController + STATIC_ITEM_P(PSTR(BOARD_INFO_NAME), SS_DEFAULT|SS_INVERT); // MyPrinterController #ifdef BOARD_WEBSITE_URL STATIC_ITEM_P(PSTR(BOARD_WEBSITE_URL), SS_LEFT); // www.my3dprinter.com #endif - VALUE_ITEM_P(MSG_INFO_BAUDRATE, STRINGIFY(BAUDRATE), SS_CENTER); // Baud: 250000 - VALUE_ITEM_P(MSG_INFO_PROTOCOL, PROTOCOL_VERSION, SS_CENTER); // Protocol: 1.0 - VALUE_ITEM_P(MSG_INFO_PSU, PSU_NAME, SS_CENTER); + PSTRING_ITEM(MSG_INFO_BAUDRATE, STRINGIFY(BAUDRATE), SS_CENTER); // Baud: 250000 + PSTRING_ITEM(MSG_INFO_PROTOCOL, PROTOCOL_VERSION, SS_CENTER); // Protocol: 1.0 + PSTRING_ITEM(MSG_INFO_PSU, PSU_NAME, SS_CENTER); END_SCREEN(); } @@ -265,23 +237,20 @@ void menu_info_board() { void menu_info_printer() { if (ui.use_click()) return ui.go_back(); START_SCREEN(); - STATIC_ITEM(MSG_MARLIN, SS_CENTER|SS_INVERT); // Marlin + STATIC_ITEM(MSG_MARLIN, SS_DEFAULT|SS_INVERT); // Marlin STATIC_ITEM_P(PSTR(SHORT_BUILD_VERSION)); // x.x.x-Branch STATIC_ITEM_P(PSTR(STRING_DISTRIBUTION_DATE)); // YYYY-MM-DD HH:MM STATIC_ITEM_P(PSTR(MACHINE_NAME)); // My3DPrinter STATIC_ITEM_P(PSTR(WEBSITE_URL)); // www.my3dprinter.com - char buffer[21]; - VALUE_ITEM_P(MSG_INFO_EXTRUDERS, STRINGIFY(EXTRUDERS), SS_CENTER); // Extruders: 2 - #if ENABLED(AUTO_BED_LEVELING_3POINT) - STATIC_ITEM(MSG_3POINT_LEVELING); // 3-Point Leveling - #elif ENABLED(AUTO_BED_LEVELING_LINEAR) - STATIC_ITEM(MSG_LINEAR_LEVELING); // Linear Leveling - #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) - STATIC_ITEM(MSG_BILINEAR_LEVELING); // Bi-linear Leveling - #elif ENABLED(AUTO_BED_LEVELING_UBL) - STATIC_ITEM(MSG_UBL_LEVELING); // Unified Bed Leveling - #elif ENABLED(MESH_BED_LEVELING) - STATIC_ITEM(MSG_MESH_LEVELING); // Mesh Leveling + PSTRING_ITEM(MSG_INFO_EXTRUDERS, STRINGIFY(EXTRUDERS), SS_CENTER); // Extruders: 2 + #if HAS_LEVELING + STATIC_ITEM( + TERN_(AUTO_BED_LEVELING_3POINT, MSG_3POINT_LEVELING) // 3-Point Leveling + TERN_(AUTO_BED_LEVELING_LINEAR, MSG_LINEAR_LEVELING) // Linear Leveling + TERN_(AUTO_BED_LEVELING_BILINEAR, MSG_BILINEAR_LEVELING) // Bi-linear Leveling + TERN_(AUTO_BED_LEVELING_UBL, MSG_UBL_LEVELING) // Unified Bed Leveling + TERN_(MESH_BED_LEVELING, MSG_MESH_LEVELING) // Mesh Leveling + ); #endif END_SCREEN(); } @@ -295,13 +264,7 @@ void menu_info() { START_MENU(); BACK_ITEM(MSG_MAIN); #if ENABLED(LCD_PRINTER_INFO_IS_BOOTSCREEN) - SUBMENU(MSG_INFO_PRINTER_MENU, ( - #if ENABLED(SHOW_CUSTOM_BOOTSCREEN) - menu_show_custom_bootscreen - #else - menu_show_marlin_bootscreen - #endif - )); + SUBMENU(MSG_INFO_PRINTER_MENU, TERN(SHOW_CUSTOM_BOOTSCREEN, menu_show_custom_bootscreen, menu_show_marlin_bootscreen)); #else SUBMENU(MSG_INFO_PRINTER_MENU, menu_info_printer); // Printer Info > SUBMENU(MSG_INFO_BOARD_MENU, menu_info_board); // Board Info > @@ -315,27 +278,26 @@ void menu_info() { #endif #if HAS_GAMES + { #if ENABLED(GAMES_EASTER_EGG) - SKIP_ITEM(); - SKIP_ITEM(); - SKIP_ITEM(); + SKIP_ITEM(); SKIP_ITEM(); SKIP_ITEM(); #endif + // Game sub-menu or the individual game - { - SUBMENU( - #if HAS_GAME_MENU - MSG_GAMES, menu_game - #elif ENABLED(MARLIN_BRICKOUT) - MSG_BRICKOUT, brickout.enter_game - #elif ENABLED(MARLIN_INVADERS) - MSG_INVADERS, invaders.enter_game - #elif ENABLED(MARLIN_SNAKE) - MSG_SNAKE, snake.enter_game - #elif ENABLED(MARLIN_MAZE) - MSG_MAZE, maze.enter_game - #endif - ); - } + SUBMENU( + #if HAS_GAME_MENU + MSG_GAMES, menu_game + #elif ENABLED(MARLIN_BRICKOUT) + MSG_BRICKOUT, brickout.enter_game + #elif ENABLED(MARLIN_INVADERS) + MSG_INVADERS, invaders.enter_game + #elif ENABLED(MARLIN_SNAKE) + MSG_SNAKE, snake.enter_game + #elif ENABLED(MARLIN_MAZE) + MSG_MAZE, maze.enter_game + #endif + ); + } #endif END_MENU(); diff --git a/Marlin/src/lcd/menu/menu_item.h b/Marlin/src/lcd/menu/menu_item.h new file mode 100644 index 000000000000..bd3af0cec6b3 --- /dev/null +++ b/Marlin/src/lcd/menu/menu_item.h @@ -0,0 +1,492 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "menu.h" +#include "../ultralcd.h" +#include "../../gcode/queue.h" // for inject_P + +#include "../../inc/MarlinConfigPre.h" + +void lcd_move_z(); + +//////////////////////////////////////////// +///////////// Base Menu Items ////////////// +//////////////////////////////////////////// + +// SUBMENU(LABEL, screen_handler) +class MenuItem_submenu : public MenuItemBase { + public: + FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, ...) { + _draw(sel, row, pstr, '>', LCD_STR_ARROW_RIGHT[0]); + } + static inline void action(PGM_P const, const screenFunc_t func) { ui.save_previous_screen(); ui.goto_screen(func); } +}; + +// Any menu item that invokes an immediate action +class MenuItem_button : public MenuItemBase { + public: + // Button-y Items are selectable lines with no other indicator + static inline void draw(const bool sel, const uint8_t row, PGM_P const pstr, ...) { + _draw(sel, row, pstr, '>', ' '); + } +}; + +// ACTION_ITEM(LABEL, FUNC) +class MenuItem_function : public MenuItem_button { + public: + //static inline void action(PGM_P const, const uint8_t, const menuAction_t func) { (*func)(); }; + static inline void action(PGM_P const, const menuAction_t func) { (*func)(); }; +}; + +// GCODES_ITEM(LABEL, GCODES) +class MenuItem_gcode : public MenuItem_button { + public: + FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, ...) { + _draw(sel, row, pstr, '>', ' '); + } + static void action(PGM_P const, PGM_P const pgcode) { queue.inject_P(pgcode); } + static inline void action(PGM_P const pstr, const uint8_t, const char * const pgcode) { action(pstr, pgcode); } +}; + +//////////////////////////////////////////// +///////////// Edit Menu Items ////////////// +//////////////////////////////////////////// + +// Template for specific Menu Edit Item Types +template +class TMenuEditItem : MenuEditItemBase { + private: + typedef typename NAME::type_t type_t; + static inline float scale(const float value) { return NAME::scale(value); } + static inline float unscale(const float value) { return NAME::unscale(value); } + static const char* to_string(const int32_t value) { return NAME::strfunc(unscale(value)); } + static void load(void *ptr, const int32_t value) { *((type_t*)ptr) = unscale(value); } + public: + FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, type_t * const data, ...) { + MenuEditItemBase::draw(sel, row, pstr, NAME::strfunc(*(data))); + } + FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, type_t (*pget)(), ...) { + MenuEditItemBase::draw(sel, row, pstr, NAME::strfunc(pget())); + } + // Edit screen for this type of item + static void edit_screen() { MenuEditItemBase::edit_screen(to_string, load); } + static void action( + PGM_P const pstr, // Edit label + type_t * const ptr, // Value pointer + const type_t minValue, // Value range + const type_t maxValue, + const screenFunc_t callback=nullptr, // Value update callback + const bool live=false // Callback during editing + ) { + // Make sure minv and maxv fit within int32_t + const int32_t minv = _MAX(scale(minValue), INT32_MIN), + maxv = _MIN(scale(maxValue), INT32_MAX); + goto_edit_screen(pstr, ptr, minv, maxv - minv, scale(*ptr) - minv, + edit_screen, callback, live); + } +}; + +// Provide a set of Edit Item Types which encompass a primitive +// type, a string function, and a scale factor for edit and display. +// These items call the Edit Item draw method passing the prepared string. +#define __DOFIXfloat PROBE() +#define _DOFIX(TYPE,V) TYPE(TERN(IS_PROBE(__DOFIX##TYPE),FIXFLOAT(V),(V))) +#define DEFINE_MENU_EDIT_ITEM_TYPE(NAME, TYPE, STRFUNC, SCALE, V...) \ + struct MenuEditItemInfo_##NAME { \ + typedef TYPE type_t; \ + static inline float scale(const float value) { return value * (SCALE) + (V+0); } \ + static inline float unscale(const float value) { return value / (SCALE) + (V+0); } \ + static inline const char* strfunc(const float value) { return STRFUNC(_DOFIX(TYPE,value)); } \ + }; \ + typedef TMenuEditItem MenuItem_##NAME + +// NAME TYPE STRFUNC SCALE +ROUND +DEFINE_MENU_EDIT_ITEM_TYPE(percent ,uint8_t ,ui8tostr4pctrj , 100.f/255.f, 0.5f); // 100% right-justified +DEFINE_MENU_EDIT_ITEM_TYPE(int3 ,int16_t ,i16tostr3rj , 1 ); // 123, -12 right-justified +DEFINE_MENU_EDIT_ITEM_TYPE(int4 ,int16_t ,i16tostr4signrj , 1 ); // 1234, -123 right-justified +DEFINE_MENU_EDIT_ITEM_TYPE(int8 ,int8_t ,i8tostr3rj , 1 ); // 123, -12 right-justified +DEFINE_MENU_EDIT_ITEM_TYPE(uint8 ,uint8_t ,ui8tostr3rj , 1 ); // 123 right-justified +DEFINE_MENU_EDIT_ITEM_TYPE(uint16_3 ,uint16_t ,ui16tostr3rj , 1 ); // 123 right-justified +DEFINE_MENU_EDIT_ITEM_TYPE(uint16_4 ,uint16_t ,ui16tostr4rj , 0.1f ); // 1234 right-justified +DEFINE_MENU_EDIT_ITEM_TYPE(uint16_5 ,uint16_t ,ui16tostr5rj , 0.01f ); // 12345 right-justified +DEFINE_MENU_EDIT_ITEM_TYPE(float3 ,float ,ftostr3 , 1 ); // 123 right-justified +DEFINE_MENU_EDIT_ITEM_TYPE(float42_52 ,float ,ftostr42_52 , 100 ); // _2.34, 12.34, -2.34 or 123.45, -23.45 +DEFINE_MENU_EDIT_ITEM_TYPE(float43 ,float ,ftostr43sign ,1000 ); // -1.234, _1.234, +1.234 +DEFINE_MENU_EDIT_ITEM_TYPE(float5 ,float ,ftostr5rj , 1 ); // 12345 right-justified +DEFINE_MENU_EDIT_ITEM_TYPE(float5_25 ,float ,ftostr5rj , 0.04f ); // 12345 right-justified (25 increment) +DEFINE_MENU_EDIT_ITEM_TYPE(float51 ,float ,ftostr51rj , 10 ); // 1234.5 right-justified +DEFINE_MENU_EDIT_ITEM_TYPE(float31sign ,float ,ftostr31sign , 10 ); // +12.3 +DEFINE_MENU_EDIT_ITEM_TYPE(float41sign ,float ,ftostr41sign , 10 ); // +123.4 +DEFINE_MENU_EDIT_ITEM_TYPE(float51sign ,float ,ftostr51sign , 10 ); // +1234.5 +DEFINE_MENU_EDIT_ITEM_TYPE(float52sign ,float ,ftostr52sign , 100 ); // +123.45 +DEFINE_MENU_EDIT_ITEM_TYPE(long5 ,uint32_t ,ftostr5rj , 0.01f ); // 12345 right-justified +DEFINE_MENU_EDIT_ITEM_TYPE(long5_25 ,uint32_t ,ftostr5rj , 0.04f ); // 12345 right-justified (25 increment) + +#if HAS_BED_PROBE + #if Z_PROBE_OFFSET_RANGE_MIN >= -9 && Z_PROBE_OFFSET_RANGE_MAX <= 9 + #define LCD_Z_OFFSET_TYPE float43 // Values from -9.000 to +9.000 + #else + #define LCD_Z_OFFSET_TYPE float42_52 // Values from -99.99 to 99.99 + #endif +#endif + +class MenuItem_bool : public MenuEditItemBase { + public: + FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, const bool onoff) { + MenuEditItemBase::draw(sel, row, pstr, onoff ? GET_TEXT(MSG_LCD_ON) : GET_TEXT(MSG_LCD_OFF), true); + } + FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, bool * const data, ...) { + draw(sel, row, pstr, *data); + } + FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, PGM_P const, bool (*pget)(), ...) { + draw(sel, row, pstr, pget()); + } + static void action(PGM_P const pstr, bool * const ptr, const screenFunc_t callbackFunc=nullptr) { + *ptr ^= true; ui.refresh(); + if (callbackFunc) (*callbackFunc)(); + } +}; + +/** + * //////////////////////////////////////////// + * //////////// Menu System Macros //////////// + * //////////////////////////////////////////// + * + * Marlin's native menu screens work by running a loop from the top visible line index + * to the bottom visible line index (according to how much the screen has been scrolled). + * This complete loop is done on every menu screen call. + * + * The menu system is highly dynamic, so it doesn't know ahead of any menu loop which + * items will be visible or hidden, so menu items don't have a fixed index number. + * + * During the loop, each menu item checks to see if its line is the current one. If it is, + * then it checks to see if a click has arrived so it can run its action. If the action + * doesn't redirect to another screen then the menu item calls its draw method. + * + * Menu item add-ons can do whatever they like. + * + * This mixture of drawing and processing inside a loop has the advantage that a single + * line can be used to represent a menu item, and that is the rationale for this design. + * + * One of the pitfalls of this method is that DOGM displays call the screen handler 2x, + * 4x, or 8x per screen update to draw just one segment of the screen. As a result, any + * menu item that exists in two screen segments is drawn and processed twice per screen + * update. With each item processed 5, 10, 20, or 40 times the logic has to be simple. + * + * To avoid repetition and side-effects, function calls for testing menu item conditions + * should be done before the menu loop (START_MENU / START_SCREEN). + */ + +/** + * SCREEN_OR_MENU_LOOP generates header code for a screen or menu + * + * encoderTopLine is the top menu line to display + * _lcdLineNr is the index of the LCD line (e.g., 0-3) + * _menuLineNr is the menu item to draw and process + * _thisItemNr is the index of each MENU_ITEM or STATIC_ITEM + */ +#define SCREEN_OR_MENU_LOOP(IS_MENU) \ + scroll_screen(IS_MENU ? 1 : LCD_HEIGHT, IS_MENU); \ + int8_t _menuLineNr = encoderTopLine, _thisItemNr = 0; \ + bool _skipStatic = IS_MENU; UNUSED(_thisItemNr); \ + for (int8_t _lcdLineNr = 0; _lcdLineNr < LCD_HEIGHT; _lcdLineNr++, _menuLineNr++) { \ + _thisItemNr = 0 + +/** + * START_SCREEN Opening code for a screen having only static items. + * Do simplified scrolling of the entire screen. + * + * START_MENU Opening code for a screen with menu items. + * Scroll as-needed to keep the selected line in view. + */ +#define START_SCREEN() SCREEN_OR_MENU_LOOP(false) +#define START_MENU() SCREEN_OR_MENU_LOOP(true) +#define NEXT_ITEM() (++_thisItemNr) +#define SKIP_ITEM() NEXT_ITEM() +#define END_SCREEN() } screen_items = _thisItemNr +#define END_MENU() END_SCREEN(); UNUSED(_skipStatic) + +/** + * MENU_ITEM generates draw & handler code for a menu item, potentially calling: + * + * MenuItem_::draw(sel, row, label, arg3...) + * MenuItem_::action(arg3...) + * + * Examples: + * BACK_ITEM(MSG_INFO_SCREEN) + * MenuItem_back::action(plabel, ...) + * MenuItem_back::draw(sel, row, plabel, ...) + * + * ACTION_ITEM(MSG_PAUSE_PRINT, lcd_sdcard_pause) + * MenuItem_function::action(plabel, lcd_sdcard_pause) + * MenuItem_function::draw(sel, row, plabel, lcd_sdcard_pause) + * + * EDIT_ITEM(int3, MSG_SPEED, &feedrate_percentage, 10, 999) + * MenuItem_int3::action(plabel, &feedrate_percentage, 10, 999) + * MenuItem_int3::draw(sel, row, plabel, &feedrate_percentage, 10, 999) + */ + +#if ENABLED(ENCODER_RATE_MULTIPLIER) + #define _MENU_ITEM_MULTIPLIER_CHECK(USE_MULTIPLIER) do{ if (USE_MULTIPLIER) ui.enable_encoder_multiplier(true); }while(0) +#else + #define _MENU_ITEM_MULTIPLIER_CHECK(USE_MULTIPLIER) +#endif + +#define _MENU_INNER_P(TYPE, USE_MULTIPLIER, PLABEL, V...) do { \ + PGM_P const plabel = PLABEL; \ + if (encoderLine == _thisItemNr && ui.use_click()) { \ + _MENU_ITEM_MULTIPLIER_CHECK(USE_MULTIPLIER); \ + MenuItem_##TYPE::action(plabel, ##V); \ + if (ui.screen_changed) return; \ + } \ + if (ui.should_draw()) \ + MenuItem_##TYPE::draw \ + (encoderLine == _thisItemNr, _lcdLineNr, plabel, ##V); \ +}while(0) + +#define _MENU_ITEM_P(TYPE, V...) do { \ + if (_menuLineNr == _thisItemNr) { \ + _skipStatic = false; \ + _MENU_INNER_P(TYPE, ##V); \ + } \ + NEXT_ITEM(); \ +}while(0) + +// Indexed items set a global index value and optional data +#define _MENU_ITEM_N_S_P(TYPE, N, S, V...) do{ \ + if (_menuLineNr == _thisItemNr) { \ + _skipStatic = false; \ + MenuItemBase::init(N, S); \ + _MENU_INNER_P(TYPE, ##V); \ + } \ + NEXT_ITEM(); \ +}while(0) + +// Indexed items set a global index value +#define _MENU_ITEM_N_P(TYPE, N, V...) do{ \ + if (_menuLineNr == _thisItemNr) { \ + _skipStatic = false; \ + MenuItemBase::itemIndex = N; \ + _MENU_INNER_P(TYPE, ##V); \ + } \ + NEXT_ITEM(); \ +}while(0) + +// Items with a unique string +#define _MENU_ITEM_S_P(TYPE, S, V...) do{ \ + if (_menuLineNr == _thisItemNr) { \ + _skipStatic = false; \ + MenuItemBase::itemString = S; \ + _MENU_INNER_P(TYPE, ##V); \ + } \ + NEXT_ITEM(); \ +}while(0) + +// STATIC_ITEM draws a styled string with no highlight. +// Parameters: label [, style [, char *value] ] + +#define STATIC_ITEM_INNER_P(PLABEL, V...) do{ \ + if (_skipStatic && encoderLine <= _thisItemNr) { \ + ui.encoderPosition += ENCODER_STEPS_PER_MENU_ITEM; \ + ++encoderLine; \ + } \ + if (ui.should_draw()) \ + MenuItem_static::draw(_lcdLineNr, PLABEL, ##V); \ +} while(0) + +#define STATIC_ITEM_P(PLABEL, V...) do{ \ + if (_menuLineNr == _thisItemNr) \ + STATIC_ITEM_INNER_P(PLABEL, ##V); \ + NEXT_ITEM(); \ +} while(0) + +#define STATIC_ITEM_N_P(PLABEL, N, V...) do{ \ + if (_menuLineNr == _thisItemNr) { \ + MenuItemBase::init(N); \ + STATIC_ITEM_INNER_P(PLABEL, ##V); \ + } \ + NEXT_ITEM(); \ +}while(0) + +// PSTRING_ITEM is like STATIC_ITEM but it takes +// two PSTRs with the style as the last parameter. + +#define PSTRING_ITEM_P(PLABEL, PVAL, STYL) do{ \ + constexpr int m = 20; \ + char msg[m+1]; \ + msg[0] = ':'; msg[1] = ' '; \ + strncpy_P(msg+2, PSTR(PVAL), m-2); \ + if (msg[m-1] & 0x80) msg[m-1] = '\0'; \ + STATIC_ITEM_P(PLABEL, STYL, msg); \ +}while(0) + +#define PSTRING_ITEM(LABEL, V...) PSTRING_ITEM_P(GET_TEXT(LABEL), ##V) + +#define STATIC_ITEM(LABEL, V...) STATIC_ITEM_P(GET_TEXT(LABEL), ##V) +#define STATIC_ITEM_N(LABEL, N, V...) STATIC_ITEM_N_P(GET_TEXT(LABEL), N, ##V) + +#define MENU_ITEM_N_S_P(TYPE, N, S, PLABEL, V...) _MENU_ITEM_N_S_P(TYPE, N, S, false, PLABEL, ##V) +#define MENU_ITEM_N_S(TYPE, N, S, LABEL, V...) MENU_ITEM_N_S_P(TYPE, N, S, GET_TEXT(LABEL), ##V) +#define MENU_ITEM_S_P(TYPE, S, PLABEL, V...) _MENU_ITEM_S_P(TYPE, S, false, PLABEL, ##V) +#define MENU_ITEM_S(TYPE, S, LABEL, V...) MENU_ITEM_S_P(TYPE, S, GET_TEXT(LABEL), ##V) +#define MENU_ITEM_N_P(TYPE, N, PLABEL, V...) _MENU_ITEM_N_P(TYPE, N, false, PLABEL, ##V) +#define MENU_ITEM_N(TYPE, N, LABEL, V...) MENU_ITEM_N_P(TYPE, N, GET_TEXT(LABEL), ##V) +#define MENU_ITEM_P(TYPE, PLABEL, V...) _MENU_ITEM_P(TYPE, false, PLABEL, ##V) +#define MENU_ITEM(TYPE, LABEL, V...) MENU_ITEM_P(TYPE, GET_TEXT(LABEL), ##V) + +#define BACK_ITEM(LABEL) MENU_ITEM(back, LABEL) + +#define ACTION_ITEM_N_S_P(N, S, PLABEL, ACTION) MENU_ITEM_N_S_P(function, N, S, PLABEL, ACTION) +#define ACTION_ITEM_N_S(N, S, LABEL, ACTION) ACTION_ITEM_N_S_P(N, S, GET_TEXT(LABEL), ACTION) +#define ACTION_ITEM_S_P(S, PLABEL, ACTION) MENU_ITEM_S_P(function, S, PLABEL, ACTION) +#define ACTION_ITEM_S(S, LABEL, ACTION) ACTION_ITEM_S_P(S, GET_TEXT(LABEL), ACTION) +#define ACTION_ITEM_N_P(N, PLABEL, ACTION) MENU_ITEM_N_P(function, N, PLABEL, ACTION) +#define ACTION_ITEM_N(N, LABEL, ACTION) ACTION_ITEM_N_P(N, GET_TEXT(LABEL), ACTION) +#define ACTION_ITEM_P(PLABEL, ACTION) MENU_ITEM_P(function, PLABEL, ACTION) +#define ACTION_ITEM(LABEL, ACTION) ACTION_ITEM_P(GET_TEXT(LABEL), ACTION) + +#define GCODES_ITEM_N_S_P(N, S, PLABEL, GCODES) MENU_ITEM_N_S_P(gcode, N, S, PLABEL, GCODES) +#define GCODES_ITEM_N_S(N, S, LABEL, GCODES) GCODES_ITEM_N_S_P(N, S, GET_TEXT(LABEL), GCODES) +#define GCODES_ITEM_S_P(S, PLABEL, GCODES) MENU_ITEM_S_P(gcode, S, PLABEL, GCODES) +#define GCODES_ITEM_S(S, LABEL, GCODES) GCODES_ITEM_S_P(S, GET_TEXT(LABEL), GCODES) +#define GCODES_ITEM_N_P(N, PLABEL, GCODES) MENU_ITEM_N_P(gcode, N, PLABEL, GCODES) +#define GCODES_ITEM_N(N, LABEL, GCODES) GCODES_ITEM_N_P(N, GET_TEXT(LABEL), GCODES) +#define GCODES_ITEM_P(PLABEL, GCODES) MENU_ITEM_P(gcode, PLABEL, GCODES) +#define GCODES_ITEM(LABEL, GCODES) GCODES_ITEM_P(GET_TEXT(LABEL), GCODES) + +#define SUBMENU_N_S_P(N, S, PLABEL, DEST) MENU_ITEM_N_S_P(submenu, N, S, PLABEL, DEST) +#define SUBMENU_N_S(N, S, LABEL, DEST) SUBMENU_N_S_P(N, S, GET_TEXT(LABEL), DEST) +#define SUBMENU_S_P(S, PLABEL, DEST) MENU_ITEM_S_P(submenu, S, PLABEL, DEST) +#define SUBMENU_S(S, LABEL, DEST) SUBMENU_S_P(S, GET_TEXT(LABEL), DEST) +#define SUBMENU_N_P(N, PLABEL, DEST) MENU_ITEM_N_P(submenu, N, PLABEL, DEST) +#define SUBMENU_N(N, LABEL, DEST) SUBMENU_N_P(N, GET_TEXT(LABEL), DEST) +#define SUBMENU_P(PLABEL, DEST) MENU_ITEM_P(submenu, PLABEL, DEST) +#define SUBMENU(LABEL, DEST) SUBMENU_P(GET_TEXT(LABEL), DEST) + +#define EDIT_ITEM_N_S_P(TYPE, N, S, PLABEL, V...) MENU_ITEM_N_S_P(TYPE, N, S, PLABEL, ##V) +#define EDIT_ITEM_N_S(TYPE, N, S, LABEL, V...) EDIT_ITEM_N_S_P(TYPE, N, S, GET_TEXT(LABEL), ##V) +#define EDIT_ITEM_S_P(TYPE, S, PLABEL, V...) MENU_ITEM_S_P(TYPE, S, PLABEL, ##V) +#define EDIT_ITEM_S(TYPE, S, LABEL, V...) EDIT_ITEM_S_P(TYPE, S, GET_TEXT(LABEL), ##V) +#define EDIT_ITEM_N_P(TYPE, N, PLABEL, V...) MENU_ITEM_N_P(TYPE, N, PLABEL, ##V) +#define EDIT_ITEM_N(TYPE, N, LABEL, V...) EDIT_ITEM_N_P(TYPE, N, GET_TEXT(LABEL), ##V) +#define EDIT_ITEM_P(TYPE, PLABEL, V...) MENU_ITEM_P(TYPE, PLABEL, ##V) +#define EDIT_ITEM(TYPE, LABEL, V...) EDIT_ITEM_P(TYPE, GET_TEXT(LABEL), ##V) + +#define EDIT_ITEM_FAST_N_S_P(TYPE, N, S, PLABEL, V...) _MENU_ITEM_N_S_P(TYPE, N, S, true, PLABEL, ##V) +#define EDIT_ITEM_FAST_N_S(TYPE, N, S, LABEL, V...) EDIT_ITEM_FAST_N_S_P(TYPE, N, S, true, GET_TEXT(LABEL), ##V) +#define EDIT_ITEM_FAST_S_P(TYPE, S, PLABEL, V...) _MENU_ITEM_S_P(TYPE, S, true, PLABEL, ##V) +#define EDIT_ITEM_FAST_S(TYPE, S, LABEL, V...) EDIT_ITEM_FAST_S_P(TYPE, S, GET_TEXT(LABEL), ##V) +#define EDIT_ITEM_FAST_N_P(TYPE, N, PLABEL, V...) _MENU_ITEM_N_P(TYPE, N, true, PLABEL, ##V) +#define EDIT_ITEM_FAST_N(TYPE, N, LABEL, V...) EDIT_ITEM_FAST_N_P(TYPE, N, GET_TEXT(LABEL), ##V) +#define EDIT_ITEM_FAST_P(TYPE, PLABEL, V...) _MENU_ITEM_P(TYPE, true, PLABEL, ##V) +#define EDIT_ITEM_FAST(TYPE, LABEL, V...) EDIT_ITEM_FAST_P(TYPE, GET_TEXT(LABEL), ##V) + +#define _CONFIRM_ITEM_INNER_P(PLABEL, V...) do { \ + if (encoderLine == _thisItemNr && ui.use_click()) { \ + ui.save_previous_screen(); \ + ui.goto_screen([]{MenuItem_confirm::select_screen(V);}); \ + return; \ + } \ + if (ui.should_draw()) MenuItem_confirm::draw \ + (encoderLine == _thisItemNr, _lcdLineNr, PLABEL, ##V); \ +}while(0) + +// Indexed items set a global index value and optional data +#define _CONFIRM_ITEM_P(PLABEL, V...) do { \ + if (_menuLineNr == _thisItemNr) { \ + _skipStatic = false; \ + _CONFIRM_ITEM_INNER_P(PLABEL, ##V); \ + } \ + NEXT_ITEM(); \ +}while(0) + +// Indexed items set a global index value +#define _CONFIRM_ITEM_N_S_P(N, S, V...) do{ \ + if (_menuLineNr == _thisItemNr) { \ + _skipStatic = false; \ + MenuItemBase::init(N, S); \ + _CONFIRM_ITEM_INNER_P(TYPE, ##V); \ + } \ + NEXT_ITEM(); \ +}while(0) + +// Indexed items set a global index value +#define _CONFIRM_ITEM_N_P(N, V...) _CONFIRM_ITEM_N_S_P(N, nullptr, V) + +#define CONFIRM_ITEM_P(PLABEL,A,B,V...) _CONFIRM_ITEM_P(PLABEL, GET_TEXT(A), GET_TEXT(B), ##V) +#define CONFIRM_ITEM(LABEL, V...) CONFIRM_ITEM_P(GET_TEXT(LABEL), ##V) + +#define YESNO_ITEM_P(PLABEL, V...) _CONFIRM_ITEM_P(PLABEL, ##V) +#define YESNO_ITEM(LABEL, V...) YESNO_ITEM_P(GET_TEXT(LABEL), ##V) + +#define CONFIRM_ITEM_N_S_P(N,S,PLABEL,A,B,V...) _CONFIRM_ITEM_N_S_P(N, S, PLABEL, GET_TEXT(A), GET_TEXT(B), ##V) +#define CONFIRM_ITEM_N_S(N,S,LABEL,V...) CONFIRM_ITEM_N_S_P(N, S, GET_TEXT(LABEL), ##V) +#define CONFIRM_ITEM_N_P(N,PLABEL,A,B,V...) _CONFIRM_ITEM_N_P(N, PLABEL, GET_TEXT(A), GET_TEXT(B), ##V) +#define CONFIRM_ITEM_N(N,LABEL, V...) CONFIRM_ITEM_N_P(N, GET_TEXT(LABEL), ##V) + +#define YESNO_ITEM_N_S_P(N,S,PLABEL, V...) _CONFIRM_ITEM_N_S_P(N, S, PLABEL, ##V) +#define YESNO_ITEM_N_S(N,S,LABEL, V...) YESNO_ITEM_N_S_P(N, S, GET_TEXT(LABEL), ##V) +#define YESNO_ITEM_N_P(N,PLABEL, V...) _CONFIRM_ITEM_N_P(N, PLABEL, ##V) +#define YESNO_ITEM_N(N,LABEL, V...) YESNO_ITEM_N_P(N, GET_TEXT(LABEL), ##V) + +#if ENABLED(LEVEL_BED_CORNERS) + void _lcd_level_bed_corners(); +#endif + +#if HAS_FAN + + #include "../../module/temperature.h" + + inline void on_fan_update() { + thermalManager.set_fan_speed(MenuItemBase::itemIndex, editable.uint8); + } + + #if ENABLED(EXTRA_FAN_SPEED) + #define EDIT_EXTRA_FAN_SPEED(V...) EDIT_ITEM_FAST_N(V) + #else + #define EDIT_EXTRA_FAN_SPEED(...) + #endif + + #define _FAN_EDIT_ITEMS(F,L) do{ \ + editable.uint8 = thermalManager.fan_speed[F]; \ + EDIT_ITEM_FAST_N(percent, F, MSG_##L, &editable.uint8, 0, 255, on_fan_update); \ + EDIT_EXTRA_FAN_SPEED(percent, F, MSG_EXTRA_##L, &thermalManager.new_fan_speed[F], 3, 255); \ + }while(0) + + #if FAN_COUNT > 1 + #define FAN_EDIT_ITEMS(F) _FAN_EDIT_ITEMS(F,FAN_SPEED_N) + #endif + + #define SNFAN(N) (ENABLED(SINGLENOZZLE_STANDBY_FAN) && !HAS_FAN##N && EXTRUDERS > N) + + #if SNFAN(1) || SNFAN(2) || SNFAN(3) || SNFAN(4) || SNFAN(5) || SNFAN(6) || SNFAN(7) + #define DEFINE_SINGLENOZZLE_ITEM() \ + auto singlenozzle_item = [&](const uint8_t f) { \ + editable.uint8 = singlenozzle_fan_speed[f]; \ + EDIT_ITEM_FAST_N(percent, f, MSG_STORED_FAN_N, &editable.uint8, 0, 255, on_fan_update); \ + } + #else + #define DEFINE_SINGLENOZZLE_ITEM() NOOP + #endif + +#endif // HAS_FAN diff --git a/Marlin/src/lcd/menu/menu_job_recovery.cpp b/Marlin/src/lcd/menu/menu_job_recovery.cpp index 5b57992f457e..7cd2949d627c 100644 --- a/Marlin/src/lcd/menu/menu_job_recovery.cpp +++ b/Marlin/src/lcd/menu/menu_job_recovery.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -26,12 +26,12 @@ #include "../../inc/MarlinConfigPre.h" -#if HAS_LCD_MENU && ENABLED(POWER_LOSS_RECOVERY) +#if BOTH(HAS_LCD_MENU, POWER_LOSS_RECOVERY) -#include "menu.h" +#include "menu_item.h" #include "../../gcode/queue.h" #include "../../sd/cardreader.h" -#include "../../feature/power_loss_recovery.h" +#include "../../feature/powerloss.h" static void lcd_power_loss_recovery_resume() { ui.return_to_status(); diff --git a/Marlin/src/lcd/menu/menu_led.cpp b/Marlin/src/lcd/menu/menu_led.cpp index b9e75422bcf5..386a4d799aa2 100644 --- a/Marlin/src/lcd/menu/menu_led.cpp +++ b/Marlin/src/lcd/menu/menu_led.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -26,57 +26,129 @@ #include "../../inc/MarlinConfigPre.h" -#if HAS_LCD_MENU && ENABLED(LED_CONTROL_MENU) +#if HAS_LCD_MENU && EITHER(LED_CONTROL_MENU, CASE_LIGHT_MENU) -#include "menu.h" -#include "../../feature/leds/leds.h" +#include "menu_item.h" -#if ENABLED(LED_COLOR_PRESETS) +#if ENABLED(LED_CONTROL_MENU) + #include "../../feature/leds/leds.h" - void menu_led_presets() { + #if ENABLED(LED_COLOR_PRESETS) + + void menu_led_presets() { + START_MENU(); + #if LCD_HEIGHT > 2 + STATIC_ITEM(MSG_LED_PRESETS, SS_DEFAULT|SS_INVERT); + #endif + BACK_ITEM(MSG_LED_CONTROL); + ACTION_ITEM(MSG_SET_LEDS_WHITE, leds.set_white); + ACTION_ITEM(MSG_SET_LEDS_RED, leds.set_red); + ACTION_ITEM(MSG_SET_LEDS_ORANGE, leds.set_orange); + ACTION_ITEM(MSG_SET_LEDS_YELLOW, leds.set_yellow); + ACTION_ITEM(MSG_SET_LEDS_GREEN, leds.set_green); + ACTION_ITEM(MSG_SET_LEDS_BLUE, leds.set_blue); + ACTION_ITEM(MSG_SET_LEDS_INDIGO, leds.set_indigo); + ACTION_ITEM(MSG_SET_LEDS_VIOLET, leds.set_violet); + END_MENU(); + } + + #endif + + #if ENABLED(NEO2_COLOR_PRESETS) + + void menu_leds2_presets() { + START_MENU(); + #if LCD_HEIGHT > 2 + STATIC_ITEM(MSG_NEO2_PRESETS, SS_DEFAULT|SS_INVERT); + #endif + BACK_ITEM(MSG_LED_CONTROL); + ACTION_ITEM(MSG_SET_LEDS_WHITE, leds2.set_white); + ACTION_ITEM(MSG_SET_LEDS_RED, leds2.set_red); + ACTION_ITEM(MSG_SET_LEDS_ORANGE, leds2.set_orange); + ACTION_ITEM(MSG_SET_LEDS_YELLOW, leds2.set_yellow); + ACTION_ITEM(MSG_SET_LEDS_GREEN, leds2.set_green); + ACTION_ITEM(MSG_SET_LEDS_BLUE, leds2.set_blue); + ACTION_ITEM(MSG_SET_LEDS_INDIGO, leds2.set_indigo); + ACTION_ITEM(MSG_SET_LEDS_VIOLET, leds2.set_violet); + END_MENU(); + } + + #endif + + void menu_led_custom() { START_MENU(); - #if LCD_HEIGHT > 2 - STATIC_ITEM(MSG_LED_PRESETS, SS_CENTER|SS_INVERT); - #endif BACK_ITEM(MSG_LED_CONTROL); - ACTION_ITEM(MSG_SET_LEDS_WHITE, leds.set_white); - ACTION_ITEM(MSG_SET_LEDS_RED, leds.set_red); - ACTION_ITEM(MSG_SET_LEDS_ORANGE, leds.set_orange); - ACTION_ITEM(MSG_SET_LEDS_YELLOW,leds.set_yellow); - ACTION_ITEM(MSG_SET_LEDS_GREEN, leds.set_green); - ACTION_ITEM(MSG_SET_LEDS_BLUE, leds.set_blue); - ACTION_ITEM(MSG_SET_LEDS_INDIGO, leds.set_indigo); - ACTION_ITEM(MSG_SET_LEDS_VIOLET, leds.set_violet); + #if ENABLED(NEOPIXEL2_SEPARATE) + STATIC_ITEM_N(MSG_LED_CHANNEL_N, 1, SS_DEFAULT|SS_INVERT); + #endif + EDIT_ITEM(uint8, MSG_INTENSITY_R, &leds.color.r, 0, 255, leds.update, true); + EDIT_ITEM(uint8, MSG_INTENSITY_G, &leds.color.g, 0, 255, leds.update, true); + EDIT_ITEM(uint8, MSG_INTENSITY_B, &leds.color.b, 0, 255, leds.update, true); + #if EITHER(RGBW_LED, NEOPIXEL_LED) + EDIT_ITEM(uint8, MSG_INTENSITY_W, &leds.color.w, 0, 255, leds.update, true); + #if ENABLED(NEOPIXEL_LED) + EDIT_ITEM(uint8, MSG_LED_BRIGHTNESS, &leds.color.i, 0, 255, leds.update, true); + #endif + #endif + #if ENABLED(NEOPIXEL2_SEPARATE) + STATIC_ITEM_N(MSG_LED_CHANNEL_N, 2, SS_DEFAULT|SS_INVERT); + EDIT_ITEM(uint8, MSG_INTENSITY_R, &leds2.color.r, 0, 255, leds2.update, true); + EDIT_ITEM(uint8, MSG_INTENSITY_G, &leds2.color.g, 0, 255, leds2.update, true); + EDIT_ITEM(uint8, MSG_INTENSITY_B, &leds2.color.b, 0, 255, leds2.update, true); + EDIT_ITEM(uint8, MSG_INTENSITY_W, &leds2.color.w, 0, 255, leds2.update, true); + EDIT_ITEM(uint8, MSG_NEO2_BRIGHTNESS, &leds2.color.i, 0, 255, leds2.update, true); + #endif END_MENU(); } - #endif -void menu_led_custom() { - START_MENU(); - BACK_ITEM(MSG_LED_CONTROL); - EDIT_ITEM(uint8, MSG_INTENSITY_R, &leds.color.r, 0, 255, leds.update, true); - EDIT_ITEM(uint8, MSG_INTENSITY_G, &leds.color.g, 0, 255, leds.update, true); - EDIT_ITEM(uint8, MSG_INTENSITY_B, &leds.color.b, 0, 255, leds.update, true); - #if EITHER(RGBW_LED, NEOPIXEL_LED) - EDIT_ITEM(uint8, MSG_INTENSITY_W, &leds.color.w, 0, 255, leds.update, true); - #if ENABLED(NEOPIXEL_LED) - EDIT_ITEM(uint8, MSG_LED_BRIGHTNESS, &leds.color.i, 0, 255, leds.update, true); - #endif +#if ENABLED(CASE_LIGHT_MENU) + #include "../../feature/caselight.h" + + #if DISABLED(CASE_LIGHT_NO_BRIGHTNESS) + void menu_case_light() { + START_MENU(); + BACK_ITEM(MSG_CONFIGURATION); + EDIT_ITEM(percent, MSG_CASE_LIGHT_BRIGHTNESS, &caselight.brightness, 0, 255, caselight.update_brightness, true); + EDIT_ITEM(bool, MSG_CASE_LIGHT, (bool*)&caselight.on, caselight.update_enabled); + END_MENU(); + } #endif - END_MENU(); -} +#endif void menu_led() { START_MENU(); BACK_ITEM(MSG_MAIN); - bool led_on = leds.lights_on; - EDIT_ITEM(bool, MSG_LEDS, &led_on, leds.toggle); - ACTION_ITEM(MSG_SET_LEDS_DEFAULT, leds.set_default); - #if ENABLED(LED_COLOR_PRESETS) - SUBMENU(MSG_LED_PRESETS, menu_led_presets); + + #if ENABLED(LED_CONTROL_MENU) + editable.state = leds.lights_on; + EDIT_ITEM(bool, MSG_LEDS, &editable.state, leds.toggle); + ACTION_ITEM(MSG_SET_LEDS_DEFAULT, leds.set_default); + #if ENABLED(NEOPIXEL2_SEPARATE) + editable.state = leds2.lights_on; + EDIT_ITEM(bool, MSG_LEDS2, &editable.state, leds2.toggle); + ACTION_ITEM(MSG_SET_LEDS_DEFAULT, leds2.set_default); + #endif + #if ENABLED(LED_COLOR_PRESETS) + SUBMENU(MSG_LED_PRESETS, menu_led_presets); + #endif + #if ENABLED(NEO2_COLOR_PRESETS) + SUBMENU(MSG_NEO2_PRESETS, menu_leds2_presets); + #endif + SUBMENU(MSG_CUSTOM_LEDS, menu_led_custom); + #endif + + // + // Set Case light on/off/brightness + // + #if ENABLED(CASE_LIGHT_MENU) + #if DISABLED(CASE_LIGHT_NO_BRIGHTNESS) + if (TERN1(CASE_LIGHT_USE_NEOPIXEL, PWM_PIN(CASE_LIGHT_PIN))) + SUBMENU(MSG_CASE_LIGHT, menu_case_light); + else + #endif + EDIT_ITEM(bool, MSG_CASE_LIGHT, (bool*)&caselight.on, caselight.update_enabled); #endif - SUBMENU(MSG_CUSTOM_LEDS, menu_led_custom); END_MENU(); } diff --git a/Marlin/src/lcd/menu/menu_main.cpp b/Marlin/src/lcd/menu/menu_main.cpp index d98670922c9d..5b983825599e 100644 --- a/Marlin/src/lcd/menu/menu_main.cpp +++ b/Marlin/src/lcd/menu/menu_main.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -28,7 +28,7 @@ #if HAS_LCD_MENU -#include "menu.h" +#include "menu_item.h" #include "../../module/temperature.h" #include "../../gcode/queue.h" #include "../../module/printcounter.h" @@ -39,14 +39,27 @@ #include "game/game.h" #endif -#define MACHINE_CAN_STOP (EITHER(SDSUPPORT, HOST_PROMPT_SUPPORT) || defined(ACTION_ON_CANCEL)) -#define MACHINE_CAN_PAUSE (ANY(SDSUPPORT, HOST_PROMPT_SUPPORT, PARK_HEAD_ON_PAUSE) || defined(ACTION_ON_PAUSE)) +#if EITHER(SDSUPPORT, HOST_PROMPT_SUPPORT) || defined(ACTION_ON_CANCEL) + #define MACHINE_CAN_STOP 1 +#endif +#if ANY(SDSUPPORT, HOST_PROMPT_SUPPORT, PARK_HEAD_ON_PAUSE) || defined(ACTION_ON_PAUSE) + #define MACHINE_CAN_PAUSE 1 +#endif #if ENABLED(PRUSA_MMU2) #include "../../lcd/menu/menu_mmu2.h" #endif +#if ENABLED(PASSWORD_FEATURE) + #include "../../feature/password/password.h" +#endif + +#if ENABLED(HOST_START_MENU_ITEM) && defined(ACTION_ON_START) + #include "../../feature/host_actions.h" +#endif + void menu_tune(); +void menu_cancelobject(); void menu_motion(); void menu_temperature(); void menu_configuration(); @@ -55,6 +68,14 @@ void menu_configuration(); void menu_user(); #endif +#if HAS_POWER_MONITOR + void menu_power_monitor(); +#endif + +#if ENABLED(MIXING_EXTRUDER) + void menu_mixer(); +#endif + #if ENABLED(ADVANCED_PAUSE_FEATURE) void _menu_temp_filament_op(const PauseMode, const int8_t); void menu_change_filament(); @@ -64,25 +85,17 @@ void menu_configuration(); void menu_info(); #endif -#if ENABLED(LED_CONTROL_MENU) +#if EITHER(LED_CONTROL_MENU, CASE_LIGHT_MENU) void menu_led(); #endif #if HAS_CUTTER - #include "../../feature/spindle_laser.h" void menu_spindle_laser(); #endif -#if ENABLED(MIXING_EXTRUDER) - void menu_mixer(); -#endif - extern const char M21_STR[]; void menu_main() { - START_MENU(); - BACK_ITEM(MSG_INFO_SCREEN); - const bool busy = printingIsActive() #if ENABLED(SDSUPPORT) , card_detected = card.isMounted() @@ -90,6 +103,9 @@ void menu_main() { #endif ; + START_MENU(); + BACK_ITEM(MSG_INFO_SCREEN); + if (busy) { #if MACHINE_CAN_PAUSE ACTION_ITEM(MSG_PAUSE_PRINT, ui.pause_print); @@ -99,11 +115,16 @@ void menu_main() { MenuItem_confirm::select_screen( GET_TEXT(MSG_BUTTON_STOP), GET_TEXT(MSG_BACK), ui.abort_print, ui.goto_previous_screen, - GET_TEXT(MSG_STOP_PRINT), (PGM_P)nullptr, PSTR("?") + GET_TEXT(MSG_STOP_PRINT), (const char *)nullptr, PSTR("?") ); }); #endif + SUBMENU(MSG_TUNE, menu_tune); + + #if ENABLED(CANCEL_OBJECTS) && DISABLED(SLIM_LCD_MENUS) + SUBMENU(MSG_CANCEL_OBJECT, []{ editable.int8 = -1; ui.goto_screen(menu_cancelobject); }); + #endif } else { @@ -115,19 +136,17 @@ void menu_main() { // Autostart // #if ENABLED(MENU_ADDAUTOSTART) - if (!busy) ACTION_ITEM(MSG_AUTOSTART, card.beginautostart); + ACTION_ITEM(MSG_AUTOSTART, card.beginautostart); #endif if (card_detected) { if (!card_open) { - SUBMENU(MSG_MEDIA_MENU, menu_media); - MENU_ITEM(gcode, - #if PIN_EXISTS(SD_DETECT) - MSG_CHANGE_MEDIA, M21_STR - #else - MSG_RELEASE_MEDIA, PSTR("M22") - #endif - ); + SUBMENU(MSG_MEDIA_MENU, TERN(PASSWORD_ON_SD_PRINT_MENU, password.media_gatekeeper, menu_media)); + #if PIN_EXISTS(SD_DETECT) + GCODES_ITEM(MSG_CHANGE_MEDIA, M21_STR); + #else + GCODES_ITEM(MSG_RELEASE_MEDIA, PSTR("M22")); + #endif } } else { @@ -135,14 +154,16 @@ void menu_main() { ACTION_ITEM(MSG_NO_MEDIA, nullptr); #else GCODES_ITEM(MSG_ATTACH_MEDIA, M21_STR); - ACTION_ITEM(MSG_MEDIA_RELEASED, nullptr); #endif } #endif // !HAS_ENCODER_WHEEL && SDSUPPORT - #if MACHINE_CAN_PAUSE - if (printingIsPaused()) ACTION_ITEM(MSG_RESUME_PRINT, ui.resume_print); + if (TERN0(MACHINE_CAN_PAUSE, printingIsPaused())) + ACTION_ITEM(MSG_RESUME_PRINT, ui.resume_print); + + #if ENABLED(HOST_START_MENU_ITEM) && defined(ACTION_ON_START) + ACTION_ITEM(MSG_HOST_START_PRINT, host_action_start); #endif SUBMENU(MSG_MOTION, menu_motion); @@ -152,7 +173,13 @@ void menu_main() { SUBMENU(MSG_CUTTER(MENU), menu_spindle_laser); #endif - SUBMENU(MSG_TEMPERATURE, menu_temperature); + #if HAS_TEMPERATURE + SUBMENU(MSG_TEMPERATURE, menu_temperature); + #endif + + #if HAS_POWER_MONITOR + SUBMENU(MSG_POWER_MONITOR, menu_power_monitor); + #endif #if ENABLED(MIXING_EXTRUDER) SUBMENU(MSG_MIXER, menu_mixer); @@ -187,8 +214,8 @@ void menu_main() { SUBMENU(MSG_INFO_MENU, menu_info); #endif - #if ENABLED(LED_CONTROL_MENU) - SUBMENU(MSG_LED_CONTROL, menu_led); + #if EITHER(LED_CONTROL_MENU, CASE_LIGHT_MENU) + SUBMENU(MSG_LEDS, menu_led); #endif // @@ -201,36 +228,36 @@ void menu_main() { GCODES_ITEM(MSG_SWITCH_PS_ON, PSTR("M80")); #endif - #if HAS_ENCODER_WHEEL && ENABLED(SDSUPPORT) + #if BOTH(HAS_ENCODER_WHEEL, SDSUPPORT) - // *** IF THIS SECTION IS CHANGED, REPRODUCE ABOVE *** + if (!busy) { - // - // Autostart - // - #if ENABLED(MENU_ADDAUTOSTART) - if (!busy) ACTION_ITEM(MSG_AUTOSTART, card.beginautostart); - #endif + // *** IF THIS SECTION IS CHANGED, REPRODUCE ABOVE *** - if (card_detected) { - if (!card_open) { - MENU_ITEM(gcode, + // + // Autostart + // + #if ENABLED(MENU_ADDAUTOSTART) + ACTION_ITEM(MSG_AUTOSTART, card.beginautostart); + #endif + + if (card_detected) { + if (!card_open) { #if PIN_EXISTS(SD_DETECT) - MSG_CHANGE_MEDIA, M21_STR + GCODES_ITEM(MSG_CHANGE_MEDIA, M21_STR); #else - MSG_RELEASE_MEDIA, PSTR("M22") + GCODES_ITEM(MSG_RELEASE_MEDIA, PSTR("M22")); #endif - ); - SUBMENU(MSG_MEDIA_MENU, menu_media); + SUBMENU(MSG_MEDIA_MENU, TERN(PASSWORD_ON_SD_PRINT_MENU, password.media_gatekeeper, menu_media)); + } + } + else { + #if PIN_EXISTS(SD_DETECT) + ACTION_ITEM(MSG_NO_MEDIA, nullptr); + #else + GCODES_ITEM(MSG_ATTACH_MEDIA, M21_STR); + #endif } - } - else { - #if PIN_EXISTS(SD_DETECT) - ACTION_ITEM(MSG_NO_MEDIA, nullptr); - #else - GCODES_ITEM(MSG_ATTACH_MEDIA, M21_STR); - ACTION_ITEM(MSG_MEDIA_RELEASED, nullptr); - #endif } #endif // HAS_ENCODER_WHEEL && SDSUPPORT @@ -238,9 +265,7 @@ void menu_main() { #if HAS_SERVICE_INTERVALS static auto _service_reset = [](const int index) { print_job_timer.resetServiceInterval(index); - #if HAS_BUZZER - ui.completion_feedback(); - #endif + ui.completion_feedback(); ui.reset_status(); ui.return_to_status(); }; diff --git a/Marlin/src/lcd/menu/menu_media.cpp b/Marlin/src/lcd/menu/menu_media.cpp index 4e68894add26..93ecc49d9859 100644 --- a/Marlin/src/lcd/menu/menu_media.cpp +++ b/Marlin/src/lcd/menu/menu_media.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -26,9 +26,9 @@ #include "../../inc/MarlinConfigPre.h" -#if HAS_LCD_MENU && ENABLED(SDSUPPORT) +#if BOTH(HAS_LCD_MENU, SDSUPPORT) -#include "menu.h" +#include "menu_item.h" #include "../../sd/cardreader.h" void lcd_sd_updir() { @@ -45,25 +45,11 @@ void lcd_sd_updir() { void MarlinUI::reselect_last_file() { if (sd_encoder_position == 0xFFFF) return; - //#if HAS_GRAPHICAL_LCD - // // This is a hack to force a screen update. - // ui.refresh(LCDVIEW_CALL_REDRAW_NEXT); - // ui.synchronize(); - // safe_delay(50); - // ui.synchronize(); - // ui.refresh(LCDVIEW_CALL_REDRAW_NEXT); - // ui.drawing_screen = ui.screen_changed = true; - //#endif - goto_screen(menu_media, sd_encoder_position, sd_top_line, sd_items); sd_encoder_position = 0xFFFF; - defer_status_screen(); - - //#if HAS_GRAPHICAL_LCD - // update(); - //#endif } + #endif inline void sdcard_start_selected_file() { @@ -113,9 +99,7 @@ class MenuItem_sdfolder : public MenuItem_sdbase { encoderTopLine = 0; ui.encoderPosition = 2 * (ENCODER_STEPS_PER_MENU_ITEM); ui.screen_changed = true; - #if HAS_GRAPHICAL_LCD - ui.drawing_screen = false; - #endif + TERN_(HAS_MARLINUI_U8GLIB, ui.drawing_screen = false); ui.refresh(); } }; @@ -123,7 +107,7 @@ class MenuItem_sdfolder : public MenuItem_sdbase { void menu_media() { ui.encoder_direction_menus(); - #if HAS_GRAPHICAL_LCD + #if HAS_MARLINUI_U8GLIB static uint16_t fileCnt; if (ui.first_page) fileCnt = card.get_num_Files(); #else @@ -142,22 +126,14 @@ void menu_media() { if (ui.should_draw()) for (uint16_t i = 0; i < fileCnt; i++) { if (_menuLineNr == _thisItemNr) { - const uint16_t nr = - #if ENABLED(SDCARD_RATHERRECENTFIRST) && DISABLED(SDCARD_SORT_ALPHA) - fileCnt - 1 - - #endif - i; - - card.getfilename_sorted(nr); - + card.getfilename_sorted(SD_ORDER(i, fileCnt)); if (card.flag.filenameIsDir) MENU_ITEM(sdfolder, MSG_MEDIA_MENU, card); else MENU_ITEM(sdfile, MSG_MEDIA_MENU, card); } - else { + else SKIP_ITEM(); - } } END_MENU(); } diff --git a/Marlin/src/lcd/menu/menu_mixer.cpp b/Marlin/src/lcd/menu/menu_mixer.cpp index 65b8af20ca19..8010239336ab 100644 --- a/Marlin/src/lcd/menu/menu_mixer.cpp +++ b/Marlin/src/lcd/menu/menu_mixer.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -26,63 +26,44 @@ #include "../../inc/MarlinConfigPre.h" -#if HAS_LCD_MENU && ENABLED(MIXING_EXTRUDER) +#if BOTH(HAS_LCD_MENU, MIXING_EXTRUDER) -#include "menu.h" +#include "menu_item.h" #include "menu_addon.h" #include "../../feature/mixing.h" -#define CHANNEL_MIX_EDITING !DUAL_MIXING_EXTRUDER +#define CHANNEL_MIX_EDITING !HAS_DUAL_MIXING #if ENABLED(GRADIENT_MIX) - void lcd_mixer_gradient_z_start_edit() { + void _lcd_mixer_gradient_z_edit(const bool isend) { ui.defer_status_screen(); ENCODER_RATE_MULTIPLY(true); - if (ui.encoderPosition != 0) { - mixer.gradient.start_z += float(int32_t(ui.encoderPosition)) * 0.1; - ui.encoderPosition = 0; - NOLESS(mixer.gradient.start_z, 0); - NOMORE(mixer.gradient.start_z, Z_MAX_POS); - } - if (ui.should_draw()) { - char tmp[21]; - strcpy_P(tmp, GET_TEXT(MSG_START_Z)); - sprintf_P(tmp + strlen(tmp), PSTR(": %4d.%d mm"), int(mixer.gradient.start_z), int(mixer.gradient.start_z * 10) % 10); - SETCURSOR(2, (LCD_HEIGHT - 1) / 2); - lcd_put_u8str(tmp); - } - if (ui.lcd_clicked) { - if (mixer.gradient.start_z > mixer.gradient.end_z) - mixer.gradient.end_z = mixer.gradient.start_z; - mixer.refresh_gradient(); - ui.goto_previous_screen(); - } - } + float &zvar = isend ? mixer.gradient.end_z : mixer.gradient.start_z; - void lcd_mixer_gradient_z_end_edit() { - ui.defer_status_screen(); - ENCODER_RATE_MULTIPLY(true); - if (ui.encoderPosition != 0) { - mixer.gradient.end_z += float(int32_t(ui.encoderPosition)) * 0.1; + if (ui.encoderPosition) { + zvar += float(int32_t(ui.encoderPosition)) * 0.1; ui.encoderPosition = 0; - NOLESS(mixer.gradient.end_z, 0); - NOMORE(mixer.gradient.end_z, Z_MAX_POS); + NOLESS(zvar, 0); + NOMORE(zvar, Z_MAX_POS); } if (ui.should_draw()) { - char tmp[21]; - strcpy_P(tmp, GET_TEXT(MSG_END_Z)); - sprintf_P(tmp + strlen(tmp), PSTR(": %4d.%d mm"), int(mixer.gradient.end_z), int(mixer.gradient.end_z * 10) % 10); - SETCURSOR(2, (LCD_HEIGHT - 1) / 2); + char tmp[16]; + SETCURSOR(1, (LCD_HEIGHT - 1) / 2); + lcd_put_u8str_P(isend ? GET_TEXT(MSG_END_Z) : GET_TEXT(MSG_START_Z)); + sprintf_P(tmp, PSTR("%4d.%d mm"), int(zvar), int(zvar * 10) % 10); + SETCURSOR_RJ(9, (LCD_HEIGHT - 1) / 2); lcd_put_u8str(tmp); } if (ui.lcd_clicked) { - if (mixer.gradient.end_z < mixer.gradient.start_z) - mixer.gradient.start_z = mixer.gradient.end_z; + if (isend && zvar < mixer.gradient.start_z) + mixer.gradient.start_z = zvar; + else if (!isend && zvar > mixer.gradient.end_z) + mixer.gradient.end_z = zvar; mixer.refresh_gradient(); ui.goto_previous_screen(); } @@ -96,19 +77,21 @@ EDIT_ITEM(int8, MSG_END_VTOOL, &mixer.gradient.end_vtool, 0, MIXING_VIRTUAL_TOOLS - 1, mixer.refresh_gradient); #if ENABLED(GRADIENT_VTOOL) - EDIT_ITEM(int8, MSG_GRADIENT_ALIAS, &mixer.gradient.vtool_index, 0, MIXING_VIRTUAL_TOOLS - 1, mixer.refresh_gradient); + EDIT_ITEM(int8, MSG_GRADIENT_ALIAS, &mixer.gradient.vtool_index, -1, MIXING_VIRTUAL_TOOLS - 1, mixer.refresh_gradient); #endif char tmp[18]; - SUBMENU(MSG_START_Z, lcd_mixer_gradient_z_start_edit); - MENU_ITEM_ADDON_START(9); + PGM_P const slabel = GET_TEXT(MSG_START_Z); + SUBMENU_P(slabel, []{ _lcd_mixer_gradient_z_edit(false); }); + MENU_ITEM_ADDON_START_RJ(11); sprintf_P(tmp, PSTR("%4d.%d mm"), int(mixer.gradient.start_z), int(mixer.gradient.start_z * 10) % 10); lcd_put_u8str(tmp); MENU_ITEM_ADDON_END(); - SUBMENU(MSG_END_Z, lcd_mixer_gradient_z_end_edit); - MENU_ITEM_ADDON_START(9); + PGM_P const elabel = GET_TEXT(MSG_END_Z); + SUBMENU_P(elabel, []{ _lcd_mixer_gradient_z_edit(true); }); + MENU_ITEM_ADDON_START_RJ(11); sprintf_P(tmp, PSTR("%4d.%d mm"), int(mixer.gradient.end_z), int(mixer.gradient.end_z * 10) % 10); lcd_put_u8str(tmp); MENU_ITEM_ADDON_END(); @@ -120,20 +103,18 @@ static uint8_t v_index; -#if DUAL_MIXING_EXTRUDER +#if HAS_DUAL_MIXING void _lcd_draw_mix(const uint8_t y) { char tmp[20]; // "100%_100%" sprintf_P(tmp, PSTR("%3d%% %3d%%"), int(mixer.mix[0]), int(mixer.mix[1])); SETCURSOR(2, y); lcd_put_u8str_P(GET_TEXT(MSG_MIX)); - SETCURSOR_RJ(9, y); lcd_put_u8str(tmp); + SETCURSOR_RJ(10, y); lcd_put_u8str(tmp); } #endif void _lcd_mixer_select_vtool() { mixer.T(v_index); - #if DUAL_MIXING_EXTRUDER - _lcd_draw_mix(LCD_HEIGHT - 1); - #endif + TERN_(HAS_DUAL_MIXING, _lcd_draw_mix(LCD_HEIGHT - 1)); } #if CHANNEL_MIX_EDITING @@ -156,10 +137,10 @@ void _lcd_mixer_select_vtool() { void lcd_mixer_mix_edit() { - #if DUAL_MIXING_EXTRUDER && !CHANNEL_MIX_EDITING + #if HAS_DUAL_MIXING && !CHANNEL_MIX_EDITING // Adjust 2-channel mix from the encoder - if (ui.encoderPosition != 0) { + if (ui.encoderPosition) { mixer.mix[0] += int32_t(ui.encoderPosition); ui.encoderPosition = 0; if (mixer.mix[0] < 0) mixer.mix[0] += 101; @@ -181,8 +162,8 @@ void lcd_mixer_mix_edit() { #if CHANNEL_MIX_EDITING - for (uint8_t n = 1; n <= MIXING_STEPPERS; n++) - EDIT_ITEM_FAST_N(float52, n, MSG_MIX_COMPONENT_N, &mixer.collector[n-1], 0, 10); + LOOP_S_LE_N(n, 1, MIXING_STEPPERS) + EDIT_ITEM_FAST_N(float42_52, n, MSG_MIX_COMPONENT_N, &mixer.collector[n-1], 0, 10); ACTION_ITEM(MSG_CYCLE_MIX, _lcd_mixer_cycle_mix); ACTION_ITEM(MSG_COMMIT_VTOOL, _lcd_mixer_commit_vtool); @@ -194,7 +175,7 @@ void lcd_mixer_mix_edit() { #endif } -#if DUAL_MIXING_EXTRUDER +#if HAS_DUAL_MIXING // // Toggle Dual-Mix @@ -239,17 +220,13 @@ void menu_mixer() { BACK_ITEM(MSG_MAIN); v_index = mixer.get_current_vtool(); - EDIT_ITEM(uint8, MSG_ACTIVE_VTOOL, &v_index, 0, MIXING_VIRTUAL_TOOLS - 1, _lcd_mixer_select_vtool - #if DUAL_MIXING_EXTRUDER - , true - #endif - ); + EDIT_ITEM(uint8, MSG_ACTIVE_VTOOL, &v_index, 0, MIXING_VIRTUAL_TOOLS - 1, _lcd_mixer_select_vtool, ENABLED(HAS_DUAL_MIXING)); - #if DUAL_MIXING_EXTRUDER + #if HAS_DUAL_MIXING { - char tmp[10]; + char tmp[11]; SUBMENU(MSG_MIX, lcd_mixer_mix_edit); - MENU_ITEM_ADDON_START(10); + MENU_ITEM_ADDON_START_RJ(9); mixer.update_mix_from_vtool(); sprintf_P(tmp, PSTR("%3d;%3d%%"), int(mixer.mix[0]), int(mixer.mix[1])); lcd_put_u8str(tmp); @@ -270,15 +247,15 @@ void menu_mixer() { LCD_MESSAGEPGM(MSG_VTOOLS_RESET); ui.return_to_status(); }, - ui.goto_previous_screen, - GET_TEXT(MSG_RESET_VTOOLS), (PGM_P)nullptr, PSTR("?") + nullptr, + GET_TEXT(MSG_RESET_VTOOLS), (const char *)nullptr, PSTR("?") ); #if ENABLED(GRADIENT_MIX) { char tmp[13]; SUBMENU(MSG_GRADIENT, lcd_mixer_edit_gradient_menu); - MENU_ITEM_ADDON_START(10); + MENU_ITEM_ADDON_START_RJ(9); sprintf_P(tmp, PSTR("T%i->T%i"), mixer.gradient.start_vtool, mixer.gradient.end_vtool); lcd_put_u8str(tmp); MENU_ITEM_ADDON_END(); diff --git a/Marlin/src/lcd/menu/menu_mmu2.cpp b/Marlin/src/lcd/menu/menu_mmu2.cpp index c2b8d4ae0a3c..0a63d90c6370 100644 --- a/Marlin/src/lcd/menu/menu_mmu2.cpp +++ b/Marlin/src/lcd/menu/menu_mmu2.cpp @@ -16,17 +16,17 @@ * 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 . + * along with this program. If not, see . * */ #include "../../inc/MarlinConfig.h" -#if HAS_LCD_MENU && ENABLED(MMU2_MENUS) +#if BOTH(HAS_LCD_MENU, MMU2_MENUS) -#include "../../feature/prusa_MMU2/mmu2.h" +#include "../../feature/mmu2/mmu2.h" #include "menu_mmu2.h" -#include "menu.h" +#include "menu_item.h" uint8_t currentTool; bool mmuMenuWait; @@ -54,8 +54,7 @@ void _mmu2_load_filament(uint8_t index) { ui.reset_status(); } void action_mmu2_load_all() { - for (uint8_t i = 0; i < EXTRUDERS; i++) - _mmu2_load_filament(i); + LOOP_L_N(i, EXTRUDERS) _mmu2_load_filament(i); ui.return_to_status(); } @@ -132,7 +131,7 @@ inline void action_mmu2_choose(const uint8_t tool) { void menu_mmu2_choose_filament() { START_MENU(); #if LCD_HEIGHT > 2 - STATIC_ITEM(MSG_MMU2_CHOOSE_FILAMENT_HEADER, SS_CENTER|SS_INVERT); + STATIC_ITEM(MSG_MMU2_CHOOSE_FILAMENT_HEADER, SS_DEFAULT|SS_INVERT); #endif LOOP_L_N(i, 5) ACTION_ITEM_N(i, MSG_MMU2_FILAMENT_N, []{ action_mmu2_choose(MenuItemBase::itemIndex); }); END_MENU(); @@ -146,7 +145,7 @@ void menu_mmu2_pause() { currentTool = mmu2.get_current_tool(); START_MENU(); #if LCD_HEIGHT > 2 - STATIC_ITEM(MSG_FILAMENT_CHANGE_HEADER, SS_CENTER|SS_INVERT); + STATIC_ITEM(MSG_FILAMENT_CHANGE_HEADER, SS_DEFAULT|SS_INVERT); #endif ACTION_ITEM(MSG_MMU2_RESUME, []{ mmuMenuWait = false; }); ACTION_ITEM(MSG_MMU2_UNLOAD_FILAMENT, []{ mmu2.unload(); }); @@ -171,4 +170,4 @@ uint8_t mmu2_choose_filament() { return currentTool; } -#endif // HAS_LCD_MENU && ENABLED(PRUSA_MMU2_MENUS) +#endif // HAS_LCD_MENU && MMU2_MENUS diff --git a/Marlin/src/lcd/menu/menu_mmu2.h b/Marlin/src/lcd/menu/menu_mmu2.h index 0221b4c765f3..4230c0146466 100644 --- a/Marlin/src/lcd/menu/menu_mmu2.h +++ b/Marlin/src/lcd/menu/menu_mmu2.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/lcd/menu/menu_motion.cpp b/Marlin/src/lcd/menu/menu_motion.cpp index 12cc7a331e2b..939a0480b94c 100644 --- a/Marlin/src/lcd/menu/menu_motion.cpp +++ b/Marlin/src/lcd/menu/menu_motion.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -28,7 +28,7 @@ #if HAS_LCD_MENU -#include "menu.h" +#include "menu_item.h" #include "menu_addon.h" #include "../../module/motion.h" @@ -46,29 +46,9 @@ #include "../../feature/bedlevel/bedlevel.h" #endif -extern millis_t manual_move_start_time; -extern int8_t manual_move_axis; #if ENABLED(MANUAL_E_MOVES_RELATIVE) float manual_move_e_origin = 0; #endif -#if IS_KINEMATIC - extern float manual_move_offset; -#endif - -// -// Tell ui.update() to start a move to current_position" after a short delay. -// -inline void manual_move_to_current(AxisEnum axis - #if E_MANUAL > 1 - , const int8_t eindex=-1 - #endif -) { - #if E_MANUAL > 1 - if (axis == E_AXIS) ui.manual_move_e_index = eindex >= 0 ? eindex : active_extruder; - #endif - manual_move_start_time = millis() + (move_menu_scale < 0.99f ? 0UL : 250UL); // delay for bigger moves - manual_move_axis = (int8_t)axis; -} // // "Motion" > "Move Axis" submenu @@ -76,41 +56,10 @@ inline void manual_move_to_current(AxisEnum axis static void _lcd_move_xyz(PGM_P const name, const AxisEnum axis) { if (ui.use_click()) return ui.goto_previous_screen_no_defer(); - if (ui.encoderPosition && !ui.processing_manual_move) { - - // Start with no limits to movement - float min = current_position[axis] - 1000, - max = current_position[axis] + 1000; - - // Limit to software endstops, if enabled - #if HAS_SOFTWARE_ENDSTOPS - if (soft_endstops_enabled) switch (axis) { - case X_AXIS: - #if ENABLED(MIN_SOFTWARE_ENDSTOP_X) - min = soft_endstop.min.x; - #endif - #if ENABLED(MAX_SOFTWARE_ENDSTOP_X) - max = soft_endstop.max.x; - #endif - break; - case Y_AXIS: - #if ENABLED(MIN_SOFTWARE_ENDSTOP_Y) - min = soft_endstop.min.y; - #endif - #if ENABLED(MAX_SOFTWARE_ENDSTOP_Y) - max = soft_endstop.max.y; - #endif - break; - case Z_AXIS: - #if ENABLED(MIN_SOFTWARE_ENDSTOP_Z) - min = soft_endstop.min.z; - #endif - #if ENABLED(MAX_SOFTWARE_ENDSTOP_Z) - max = soft_endstop.max.z; - #endif - default: break; - } - #endif // HAS_SOFTWARE_ENDSTOPS + if (ui.encoderPosition && !ui.manual_move.processing) { + // Get motion limit from software endstops, if any + float min, max; + soft_endstop.get_manual_axis_limits(axis, min, max); // Delta limits XY based on the current offset from center // This assumes the center is 0,0 @@ -122,13 +71,13 @@ static void _lcd_move_xyz(PGM_P const name, const AxisEnum axis) { #endif // Get the new position - const float diff = float(int32_t(ui.encoderPosition)) * move_menu_scale; + const float diff = float(int32_t(ui.encoderPosition)) * ui.manual_move.menu_scale; #if IS_KINEMATIC - manual_move_offset += diff; + ui.manual_move.offset += diff; if (int32_t(ui.encoderPosition) < 0) - NOLESS(manual_move_offset, min - current_position[axis]); + NOLESS(ui.manual_move.offset, min - current_position[axis]); else - NOMORE(manual_move_offset, max - current_position[axis]); + NOMORE(ui.manual_move.offset, max - current_position[axis]); #else current_position[axis] += diff; if (int32_t(ui.encoderPosition) < 0) @@ -137,17 +86,16 @@ static void _lcd_move_xyz(PGM_P const name, const AxisEnum axis) { NOMORE(current_position[axis], max); #endif - manual_move_to_current(axis); + ui.manual_move.soon(axis); ui.refresh(LCDVIEW_REDRAW_NOW); } ui.encoderPosition = 0; if (ui.should_draw()) { - const float pos = NATIVE_TO_LOGICAL(ui.processing_manual_move ? destination[axis] : current_position[axis] - #if IS_KINEMATIC - + manual_move_offset - #endif - , axis); - MenuEditItemBase::draw_edit_screen(name, move_menu_scale >= 0.1f ? ftostr41sign(pos) : ftostr43sign(pos)); + const float pos = NATIVE_TO_LOGICAL( + ui.manual_move.processing ? destination[axis] : current_position[axis] + TERN0(IS_KINEMATIC, ui.manual_move.offset), + axis + ); + MenuEditItemBase::draw_edit_screen(name, ui.manual_move.menu_scale >= 0.1f ? ftostr41sign(pos) : ftostr63(pos)); } } void lcd_move_x() { _lcd_move_xyz(GET_TEXT(MSG_MOVE_X), X_AXIS); } @@ -156,22 +104,14 @@ void lcd_move_z() { _lcd_move_xyz(GET_TEXT(MSG_MOVE_Z), Z_AXIS); } #if E_MANUAL - static void lcd_move_e( - #if E_MANUAL > 1 - const int8_t eindex=-1 - #endif - ) { + static void lcd_move_e(TERN_(MULTI_MANUAL, const int8_t eindex=-1)) { if (ui.use_click()) return ui.goto_previous_screen_no_defer(); if (ui.encoderPosition) { - if (!ui.processing_manual_move) { - const float diff = float(int32_t(ui.encoderPosition)) * move_menu_scale; - #if IS_KINEMATIC - manual_move_offset += diff; - #else - current_position.e += diff; - #endif - manual_move_to_current(E_AXIS - #if E_MANUAL > 1 + if (!ui.manual_move.processing) { + const float diff = float(int32_t(ui.encoderPosition)) * ui.manual_move.menu_scale; + TERN(IS_KINEMATIC, ui.manual_move.offset, current_position.e) += diff; + ui.manual_move.soon(E_AXIS + #if MULTI_MANUAL , eindex #endif ); @@ -180,24 +120,12 @@ void lcd_move_z() { _lcd_move_xyz(GET_TEXT(MSG_MOVE_Z), Z_AXIS); } ui.encoderPosition = 0; } if (ui.should_draw()) { - #if E_MANUAL > 1 - MenuItemBase::init(eindex); - #endif + TERN_(MULTI_MANUAL, MenuItemBase::init(eindex)); MenuEditItemBase::draw_edit_screen( - GET_TEXT( - #if E_MANUAL > 1 - MSG_MOVE_EN - #else - MSG_MOVE_E - #endif - ), + GET_TEXT(TERN(MULTI_MANUAL, MSG_MOVE_EN, MSG_MOVE_E)), ftostr41sign(current_position.e - #if IS_KINEMATIC - + manual_move_offset - #endif - #if ENABLED(MANUAL_E_MOVES_RELATIVE) - - manual_move_e_origin - #endif + + TERN0(IS_KINEMATIC, ui.manual_move.offset) + - TERN0(MANUAL_E_MOVES_RELATIVE, manual_move_e_origin) ) ); } // should_draw @@ -217,7 +145,7 @@ screenFunc_t _manual_move_func_ptr; void _goto_manual_move(const float scale) { ui.defer_status_screen(); - move_menu_scale = scale; + ui.manual_move.menu_scale = scale; ui.goto_screen(_manual_move_func_ptr); } @@ -226,69 +154,76 @@ void _menu_move_distance(const AxisEnum axis, const screenFunc_t func, const int START_MENU(); if (LCD_HEIGHT >= 4) { switch (axis) { - case X_AXIS: STATIC_ITEM(MSG_MOVE_X, SS_CENTER|SS_INVERT); break; - case Y_AXIS: STATIC_ITEM(MSG_MOVE_Y, SS_CENTER|SS_INVERT); break; - case Z_AXIS: STATIC_ITEM(MSG_MOVE_Z, SS_CENTER|SS_INVERT); break; + case X_AXIS: STATIC_ITEM(MSG_MOVE_X, SS_DEFAULT|SS_INVERT); break; + case Y_AXIS: STATIC_ITEM(MSG_MOVE_Y, SS_DEFAULT|SS_INVERT); break; + case Z_AXIS: STATIC_ITEM(MSG_MOVE_Z, SS_DEFAULT|SS_INVERT); break; default: - #if ENABLED(MANUAL_E_MOVES_RELATIVE) - manual_move_e_origin = current_position.e; - #endif - STATIC_ITEM(MSG_MOVE_E, SS_CENTER|SS_INVERT); + TERN_(MANUAL_E_MOVES_RELATIVE, manual_move_e_origin = current_position.e); + STATIC_ITEM(MSG_MOVE_E, SS_DEFAULT|SS_INVERT); break; } } - #if ENABLED(PREVENT_COLD_EXTRUSION) - if (axis == E_AXIS && thermalManager.tooColdToExtrude(eindex >= 0 ? eindex : active_extruder)) - BACK_ITEM(MSG_HOTEND_TOO_COLD); - else - #endif - { - BACK_ITEM(MSG_MOVE_AXIS); - SUBMENU(MSG_MOVE_10MM, []{ _goto_manual_move(10); }); - SUBMENU(MSG_MOVE_1MM, []{ _goto_manual_move( 1); }); - SUBMENU(MSG_MOVE_01MM, []{ _goto_manual_move( 0.1f); }); - if (axis == Z_AXIS && (SHORT_MANUAL_Z_MOVE) > 0.0f && (SHORT_MANUAL_Z_MOVE) < 0.1f) { + + BACK_ITEM(MSG_MOVE_AXIS); + SUBMENU(MSG_MOVE_10MM, []{ _goto_manual_move(10); }); + SUBMENU(MSG_MOVE_1MM, []{ _goto_manual_move( 1); }); + SUBMENU(MSG_MOVE_01MM, []{ _goto_manual_move( 0.1f); }); + if (axis == Z_AXIS && (SHORT_MANUAL_Z_MOVE) > 0.0f && (SHORT_MANUAL_Z_MOVE) < 0.1f) { + // Determine digits needed right of decimal + constexpr uint8_t digs = !UNEAR_ZERO((SHORT_MANUAL_Z_MOVE) * 1000 - int((SHORT_MANUAL_Z_MOVE) * 1000)) ? 4 : + !UNEAR_ZERO((SHORT_MANUAL_Z_MOVE) * 100 - int((SHORT_MANUAL_Z_MOVE) * 100)) ? 3 : 2; + PGM_P const label = GET_TEXT(MSG_MOVE_Z_DIST); + char tmp[strlen_P(label) + 10 + 1], numstr[10]; + sprintf_P(tmp, label, dtostrf(SHORT_MANUAL_Z_MOVE, 1, digs, numstr)); + + #if DISABLED(HAS_GRAPHICAL_TFT) extern const char NUL_STR[]; SUBMENU_P(NUL_STR, []{ _goto_manual_move(float(SHORT_MANUAL_Z_MOVE)); }); - MENU_ITEM_ADDON_START(0 - #if HAS_CHARACTER_LCD - + 1 - #endif - ); - char tmp[20], numstr[10]; - // Determine digits needed right of decimal - const uint8_t digs = !UNEAR_ZERO((SHORT_MANUAL_Z_MOVE) * 1000 - int((SHORT_MANUAL_Z_MOVE) * 1000)) ? 4 : - !UNEAR_ZERO((SHORT_MANUAL_Z_MOVE) * 100 - int((SHORT_MANUAL_Z_MOVE) * 100)) ? 3 : 2; - sprintf_P(tmp, GET_TEXT(MSG_MOVE_Z_DIST), dtostrf(SHORT_MANUAL_Z_MOVE, 1, digs, numstr)); - lcd_put_u8str(tmp); + MENU_ITEM_ADDON_START(0 + ENABLED(HAS_MARLINUI_HD44780)); + lcd_put_u8str(tmp); MENU_ITEM_ADDON_END(); - } + #else + SUBMENU_P(tmp, []{ _goto_manual_move(float(SHORT_MANUAL_Z_MOVE)); }); + #endif } END_MENU(); } +#if E_MANUAL + + inline void _goto_menu_move_distance_e() { + ui.goto_screen([]{ _menu_move_distance(E_AXIS, []{ lcd_move_e(TERN_(MULTI_MANUAL, active_extruder)); }, -1); }); + } + + inline void _menu_move_distance_e_maybe() { + #if ENABLED(PREVENT_COLD_EXTRUSION) + const bool too_cold = thermalManager.tooColdToExtrude(active_extruder); + if (too_cold) { + ui.goto_screen([]{ + MenuItem_confirm::select_screen( + GET_TEXT(MSG_BUTTON_PROCEED), GET_TEXT(MSG_BACK), + _goto_menu_move_distance_e, ui.goto_previous_screen, + GET_TEXT(MSG_HOTEND_TOO_COLD), (const char *)nullptr, PSTR("!") + ); + }); + return; + } + #endif + _goto_menu_move_distance_e(); + } + +#endif // E_MANUAL + void menu_move() { START_MENU(); BACK_ITEM(MSG_MOTION); - #if HAS_SOFTWARE_ENDSTOPS && ENABLED(SOFT_ENDSTOPS_MENU_ITEM) - EDIT_ITEM(bool, MSG_LCD_SOFT_ENDSTOPS, &soft_endstops_enabled); + #if BOTH(HAS_SOFTWARE_ENDSTOPS, SOFT_ENDSTOPS_MENU_ITEM) + EDIT_ITEM(bool, MSG_LCD_SOFT_ENDSTOPS, &soft_endstop._enabled); #endif - if ( - #if IS_KINEMATIC || ENABLED(NO_MOTION_BEFORE_HOMING) - all_axes_homed() - #else - true - #endif - ) { - if ( - #if ENABLED(DELTA) - current_position.z <= delta_clip_start_height - #else - true - #endif - ) { + if (NONE(IS_KINEMATIC, NO_MOTION_BEFORE_HOMING) || all_axes_homed()) { + if (TERN1(DELTA, current_position.z <= delta_clip_start_height)) { SUBMENU(MSG_MOVE_X, []{ _menu_move_distance(X_AXIS, lcd_move_x); }); SUBMENU(MSG_MOVE_Y, []{ _menu_move_distance(Y_AXIS, lcd_move_y); }); } @@ -341,23 +276,21 @@ void menu_move() { #if E_MANUAL // The current extruder - SUBMENU(MSG_MOVE_E, []{ _menu_move_distance(E_AXIS, []{ lcd_move_e(); }, -1); }); + SUBMENU(MSG_MOVE_E, []{ _menu_move_distance_e_maybe(); }); #define SUBMENU_MOVE_E(N) SUBMENU_N(N, MSG_MOVE_EN, []{ _menu_move_distance(E_AXIS, []{ lcd_move_e(MenuItemBase::itemIndex); }, MenuItemBase::itemIndex); }); #if EITHER(SWITCHING_EXTRUDER, SWITCHING_NOZZLE) // ...and the non-switching - #if E_MANUAL == 5 - SUBMENU_MOVE_E(4); - #elif E_MANUAL == 3 - SUBMENU_MOVE_E(2); + #if E_MANUAL == 7 || E_MANUAL == 5 || E_MANUAL == 3 + SUBMENU_MOVE_E(E_MANUAL - 1); #endif - #elif E_MANUAL > 1 + #elif MULTI_MANUAL // Independent extruders with one E-stepper per hotend - for (uint8_t n = 0; n < E_MANUAL; n++) SUBMENU_MOVE_E(n); + LOOP_L_N(n, E_MANUAL) SUBMENU_MOVE_E(n); #endif @@ -383,28 +316,40 @@ void menu_motion() { // // Move Axis // - #if ENABLED(DELTA) - if (all_axes_homed()) - #endif - SUBMENU(MSG_MOVE_AXIS, menu_move); + if (TERN1(DELTA, all_axes_homed())) + SUBMENU(MSG_MOVE_AXIS, menu_move); // // Auto Home // GCODES_ITEM(MSG_AUTO_HOME, G28_STR); #if ENABLED(INDIVIDUAL_AXIS_HOMING_MENU) - GCODES_ITEM(MSG_AUTO_HOME_X, PSTR("G28 X")); - GCODES_ITEM(MSG_AUTO_HOME_Y, PSTR("G28 Y")); - GCODES_ITEM(MSG_AUTO_HOME_Z, PSTR("G28 Z")); + GCODES_ITEM(MSG_AUTO_HOME_X, PSTR("G28X")); + GCODES_ITEM(MSG_AUTO_HOME_Y, PSTR("G28Y")); + GCODES_ITEM(MSG_AUTO_HOME_Z, PSTR("G28Z")); + #endif + + // + // Auto-calibration + // + #if ENABLED(CALIBRATION_GCODE) + GCODES_ITEM(MSG_AUTO_CALIBRATE, PSTR("G425")); #endif // // Auto Z-Align // - #if ENABLED(Z_STEPPER_AUTO_ALIGN) + #if EITHER(Z_STEPPER_AUTO_ALIGN, MECHANICAL_GANTRY_CALIBRATION) GCODES_ITEM(MSG_AUTO_Z_ALIGN, PSTR("G34")); #endif + // + // Assisted Bed Tramming + // + #if ENABLED(ASSISTED_TRAMMING_MENU_ITEM) + GCODES_ITEM(MSG_ASSISTED_TRAMMING, PSTR("G35")); + #endif + // // Level Bed // @@ -414,17 +359,20 @@ void menu_motion() { #elif ENABLED(LCD_BED_LEVELING) - if (!g29_in_progress) SUBMENU(MSG_BED_LEVELING, menu_bed_leveling); + if (!g29_in_progress) + SUBMENU(MSG_BED_LEVELING, menu_bed_leveling); #elif HAS_LEVELING && DISABLED(SLIM_LCD_MENUS) #if DISABLED(PROBE_MANUALLY) GCODES_ITEM(MSG_LEVEL_BED, PSTR("G28\nG29")); #endif + if (all_axes_homed() && leveling_is_valid()) { bool show_state = planner.leveling_active; EDIT_ITEM(bool, MSG_BED_LEVELING, &show_state, _lcd_toggle_bed_leveling); } + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) editable.decimal = planner.z_fade_height; EDIT_ITEM_FAST(float3, MSG_Z_FADE_HEIGHT, &editable.decimal, 0, 100, []{ set_z_fade_height(editable.decimal); }); @@ -437,7 +385,7 @@ void menu_motion() { #endif #if ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST) - GCODES_ITEM(MSG_M48_TEST, PSTR("G28\nM48 P10")); + GCODES_ITEM(MSG_M48_TEST, PSTR("G28 O\nM48 P10")); #endif // diff --git a/Marlin/src/lcd/menu/menu_password.cpp b/Marlin/src/lcd/menu/menu_password.cpp new file mode 100644 index 000000000000..c3924b568699 --- /dev/null +++ b/Marlin/src/lcd/menu/menu_password.cpp @@ -0,0 +1,184 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +// +// Advanced Settings Menus +// + +#include "../../inc/MarlinConfigPre.h" + +#if BOTH(HAS_LCD_MENU, PASSWORD_FEATURE) + +#include "../../feature/password/password.h" + +#include "menu_item.h" +#include "menu_addon.h" + +void menu_advanced_settings(); + +screenFunc_t success_screen, fail_screen; +bool authenticating; // = false +char string[(PASSWORD_LENGTH) + 1]; +static uint8_t digit_no; + +// +// Screen for both editing and setting the password +// +void Password::menu_password_entry() { + START_MENU(); + + // "Login" or "New Code" + STATIC_ITEM_P(authenticating ? GET_TEXT(MSG_LOGIN_REQUIRED) : GET_TEXT(MSG_EDIT_PASSWORD), SS_CENTER|SS_INVERT); + + STATIC_ITEM_P(PSTR(""), SS_CENTER|SS_INVERT, string); + + // Make the digit edit item look like a sub-menu + PGM_P const label = GET_TEXT(MSG_ENTER_DIGIT); + EDIT_ITEM_P(uint8, label, &editable.uint8, 0, 9, digit_entered); + MENU_ITEM_ADDON_START(utf8_strlen_P(label) + 1); + lcd_put_wchar(' '); + lcd_put_wchar('1' + digit_no); + SETCURSOR_X(LCD_WIDTH - 1); + lcd_put_wchar('>'); + MENU_ITEM_ADDON_END(); + + ACTION_ITEM(MSG_START_OVER, start_over); + + if (!authenticating) BACK_ITEM(MSG_BUTTON_CANCEL); + + END_MENU(); +} + +// +// Authentication check +// +void Password::authentication_done() { + ui.goto_screen(is_locked ? fail_screen : success_screen); + ui.completion_feedback(!is_locked); +} + +// A single digit was completed +void Password::digit_entered() { + uint32_t multiplier = CAT(1e, PASSWORD_LENGTH); // 1e5 = 100000 + LOOP_LE_N(i, digit_no) multiplier /= 10; + value_entry += editable.uint8 * multiplier; + string[digit_no++] = '0' + editable.uint8; + + // Exit edit screen menu and go to another screen + ui.goto_previous_screen(); + ui.use_click(); + ui.goto_screen(menu_password_entry); + + // After password has been keyed in + if (digit_no == PASSWORD_LENGTH) { + if (authenticating) + authentication_check(); + else + set_password_done(); + } +} + +// +// Set/Change Password +// +void Password::screen_password_entry() { + value_entry = 0; + digit_no = 0; + editable.uint8 = 0; + memset(string, '-', PASSWORD_LENGTH); + string[PASSWORD_LENGTH] = '\0'; + menu_password_entry(); +} + +void Password::screen_set_password() { + authenticating = false; + screen_password_entry(); +} + +void Password::authenticate_user(const screenFunc_t in_succ_scr, const screenFunc_t in_fail_scr) { + success_screen = in_succ_scr; + fail_screen = in_fail_scr; + if (is_set) { + authenticating = true; + ui.goto_screen(screen_password_entry); + ui.defer_status_screen(); + ui.update(); + } + else { + ui.goto_screen(in_succ_scr); + is_locked = false; + } +} + +void Password::access_menu_password() { + authenticate_user(menu_password, menu_advanced_settings); +} + +#if ENABLED(PASSWORD_ON_SD_PRINT_MENU) + void Password::media_gatekeeper() { + authenticate_user(menu_media, menu_main); + } +#endif + +void Password::start_over() { + ui.goto_previous_screen(); // Goto previous screen, if any + ui.goto_screen(screen_password_entry); +} + +void Password::menu_password_report() { + START_SCREEN(); + BACK_ITEM(MSG_PASSWORD_SETTINGS); + STATIC_ITEM(MSG_PASSWORD_SET, SS_LEFT, string); + STATIC_ITEM(MSG_REMINDER_SAVE_SETTINGS, SS_LEFT); + END_SCREEN(); +} + +void Password::set_password_done() { + is_set = true; + value = value_entry; + ui.completion_feedback(true); + ui.goto_screen(menu_password_report); +} + +void Password::remove_password() { + is_set = false; + string[0] = '0'; + string[1] = '\0'; + ui.completion_feedback(true); + ui.goto_screen(menu_password_report); +} + +// +// Password Menu +// +void Password::menu_password() { + START_MENU(); + BACK_ITEM(MSG_ADVANCED_SETTINGS); + SUBMENU(MSG_CHANGE_PASSWORD, screen_set_password); + ACTION_ITEM(MSG_REMOVE_PASSWORD, []{ ui.save_previous_screen(); remove_password(); } ); + #if ENABLED(EEPROM_SETTINGS) + ACTION_ITEM(MSG_STORE_EEPROM, ui.store_settings); + #endif + END_MENU(); +} + +#endif // HAS_LCD_MENU && PASSWORD_FEATURE diff --git a/Marlin/src/lcd/menu/menu_power_monitor.cpp b/Marlin/src/lcd/menu/menu_power_monitor.cpp new file mode 100644 index 000000000000..e88bdb28d8c8 --- /dev/null +++ b/Marlin/src/lcd/menu/menu_power_monitor.cpp @@ -0,0 +1,62 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +// +// Power Monitor Menu +// + +#include "../../inc/MarlinConfigPre.h" + +#if HAS_LCD_MENU && HAS_POWER_MONITOR + +#include "menu_item.h" +#include "../../feature/power_monitor.h" + +void menu_power_monitor() { + START_MENU(); + BACK_ITEM(MSG_MAIN); + + #if ENABLED(POWER_MONITOR_CURRENT) + { + bool ena = power_monitor.current_display_enabled(); + EDIT_ITEM(bool, MSG_CURRENT, &ena, power_monitor.toggle_current_display); + } + #endif + + #if HAS_POWER_MONITOR_VREF + { + bool ena = power_monitor.voltage_display_enabled(); + EDIT_ITEM(bool, MSG_VOLTAGE, &ena, power_monitor.toggle_voltage_display); + } + #endif + + #if HAS_POWER_MONITOR_WATTS + { + bool ena = power_monitor.power_display_enabled(); + EDIT_ITEM(bool, MSG_POWER, &ena, power_monitor.toggle_power_display); + } + #endif + + END_MENU(); +} + +#endif // HAS_LCD_MENU && HAS_POWER_MONITOR diff --git a/Marlin/src/lcd/menu/menu_probe_offset.cpp b/Marlin/src/lcd/menu/menu_probe_offset.cpp new file mode 100644 index 000000000000..6b7830b853d8 --- /dev/null +++ b/Marlin/src/lcd/menu/menu_probe_offset.cpp @@ -0,0 +1,138 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +// +// Calibrate Probe offset menu. +// + +#include "../../inc/MarlinConfigPre.h" + +#if ENABLED(PROBE_OFFSET_WIZARD) + +#ifndef PROBE_OFFSET_START + #error "PROBE_OFFSET_WIZARD requires a PROBE_OFFSET_START with a negative value." +#else + static_assert(PROBE_OFFSET_START < 0, "PROBE_OFFSET_START must be < 0. Please update your configuration."); +#endif + +#include "menu_item.h" +#include "menu_addon.h" +#include "../../module/motion.h" +#include "../../module/planner.h" +#include "../../module/probe.h" + +#if HAS_LEVELING + #include "../../feature/bedlevel/bedlevel.h" +#endif + +// Global storage +float z_offset_backup, calculated_z_offset; + +TERN_(HAS_LEVELING, bool leveling_was_active); + +void prepare_for_calibration() { + z_offset_backup = probe.offset.z; + + // Disable soft endstops for free Z movement + SET_SOFT_ENDSTOP_LOOSE(true); + + // Disable leveling for raw planner motion + #if HAS_LEVELING + leveling_was_active = planner.leveling_active; + set_bed_leveling_enabled(false); + #endif +} + +void set_offset_and_go_back(const float &z) { + probe.offset.z = z; + SET_SOFT_ENDSTOP_LOOSE(false); + TERN_(HAS_LEVELING, set_bed_leveling_enabled(leveling_was_active)); + ui.goto_previous_screen_no_defer(); +} + +void _goto_manual_move_z(const float scale) { + ui.manual_move.menu_scale = scale; + ui.goto_screen(lcd_move_z); +} + +void probe_offset_wizard_menu() { + START_MENU(); + calculated_z_offset = probe.offset.z + current_position.z; + + if (LCD_HEIGHT >= 4) + STATIC_ITEM(MSG_MOVE_NOZZLE_TO_BED, SS_CENTER|SS_INVERT); + + STATIC_ITEM_P(PSTR("Z="), SS_CENTER, ftostr42_52(current_position.z)); + STATIC_ITEM(MSG_ZPROBE_ZOFFSET, SS_LEFT, ftostr42_52(calculated_z_offset)); + + SUBMENU(MSG_MOVE_1MM, []{ _goto_manual_move_z( 1); }); + SUBMENU(MSG_MOVE_01MM, []{ _goto_manual_move_z( 0.1f); }); + + if ((SHORT_MANUAL_Z_MOVE) > 0.0f && (SHORT_MANUAL_Z_MOVE) < 0.1f) { + extern const char NUL_STR[]; + SUBMENU_P(NUL_STR, []{ _goto_manual_move_z(float(SHORT_MANUAL_Z_MOVE)); }); + MENU_ITEM_ADDON_START(0 + ENABLED(HAS_MARLINUI_HD44780)); + char tmp[20], numstr[10]; + // Determine digits needed right of decimal + const uint8_t digs = !UNEAR_ZERO((SHORT_MANUAL_Z_MOVE) * 1000 - int((SHORT_MANUAL_Z_MOVE) * 1000)) ? 4 : + !UNEAR_ZERO((SHORT_MANUAL_Z_MOVE) * 100 - int((SHORT_MANUAL_Z_MOVE) * 100)) ? 3 : 2; + sprintf_P(tmp, GET_TEXT(MSG_MOVE_Z_DIST), dtostrf(SHORT_MANUAL_Z_MOVE, 1, digs, numstr)); + lcd_put_u8str(tmp); + MENU_ITEM_ADDON_END(); + } + + ACTION_ITEM(MSG_BUTTON_DONE, []{ + set_offset_and_go_back(calculated_z_offset); + do_z_clearance(20.0 + #ifdef Z_AFTER_HOMING + - 20.0 + Z_AFTER_HOMING + #endif + ); + }); + + ACTION_ITEM(MSG_BUTTON_CANCEL, []{ + set_offset_and_go_back(z_offset_backup); + }); + + END_MENU(); +} + +void goto_probe_offset_wizard() { + ui.defer_status_screen(); + + prepare_for_calibration(); + + probe.offset.z = PROBE_OFFSET_START; + + set_all_unhomed(); + queue.inject_P(G28_STR); + + ui.goto_screen([]{ + _lcd_draw_homing(); + if (all_axes_homed()) { + ui.goto_screen(probe_offset_wizard_menu); + ui.defer_status_screen(); + } + }); +} + +#endif // PROBE_OFFSET_WIZARD diff --git a/Marlin/src/lcd/menu/menu_spindle_laser.cpp b/Marlin/src/lcd/menu/menu_spindle_laser.cpp index fd42522839eb..04b999eaf620 100644 --- a/Marlin/src/lcd/menu/menu_spindle_laser.cpp +++ b/Marlin/src/lcd/menu/menu_spindle_laser.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -28,26 +28,38 @@ #if HAS_LCD_MENU && HAS_CUTTER - #include "menu.h" + #include "menu_item.h" #include "../../feature/spindle_laser.h" void menu_spindle_laser() { + const bool is_enabled = cutter.enabled() && cutter.isReady; + START_MENU(); BACK_ITEM(MSG_MAIN); - if (cutter.enabled()) { - #if ENABLED(SPINDLE_LASER_PWM) - EDIT_ITEM(CUTTER_MENU_TYPE, MSG_CUTTER(POWER), &cutter.power, SPEED_POWER_MIN, SPEED_POWER_MAX); - #endif + + #if ENABLED(SPINDLE_LASER_PWM) + // Change the cutter's "current power" value without turning the cutter on or off + // Power is displayed and set in units and range according to CUTTER_POWER_UNIT + EDIT_ITEM_FAST(CUTTER_MENU_POWER_TYPE, MSG_CUTTER(POWER), &cutter.menuPower, + cutter.mpower_min(), cutter.mpower_max(), cutter.update_from_mpower); + #endif + + if (is_enabled) ACTION_ITEM(MSG_CUTTER(OFF), cutter.disable); - } else { ACTION_ITEM(MSG_CUTTER(ON), cutter.enable_forward); #if ENABLED(SPINDLE_CHANGE_DIR) ACTION_ITEM(MSG_SPINDLE_REVERSE, cutter.enable_reverse); #endif } + + #if ENABLED(MARLIN_DEV_MODE) + #if ENABLED(HAL_CAN_SET_PWM_FREQ) && defined(SPINDLE_LASER_FREQUENCY) + EDIT_ITEM_FAST(CUTTER_MENU_FREQUENCY_TYPE, MSG_CUTTER_FREQUENCY, &cutter.frequency, 2000, 50000, cutter.refresh_frequency); + #endif + #endif END_MENU(); } diff --git a/Marlin/src/lcd/menu/menu_temperature.cpp b/Marlin/src/lcd/menu/menu_temperature.cpp index 40fb88fccaed..0c70cd7e18e8 100644 --- a/Marlin/src/lcd/menu/menu_temperature.cpp +++ b/Marlin/src/lcd/menu/menu_temperature.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -24,11 +24,11 @@ // Temperature Menu // -#include "../../inc/MarlinConfigPre.h" +#include "../../inc/MarlinConfig.h" -#if HAS_LCD_MENU +#if HAS_LCD_MENU && HAS_TEMPERATURE -#include "menu.h" +#include "menu_item.h" #include "../../module/temperature.h" #if FAN_COUNT > 1 || ENABLED(SINGLENOZZLE) @@ -39,119 +39,103 @@ #include "../../module/tool_change.h" #endif -// Initialized by settings.load() -int16_t MarlinUI::preheat_hotend_temp[2], MarlinUI::preheat_bed_temp[2]; -uint8_t MarlinUI::preheat_fan_speed[2]; - // // "Temperature" submenu items // -void _lcd_preheat(const int16_t endnum, const int16_t temph, const int16_t tempb, const uint8_t fan) { - #if HOTENDS - if (temph > 0) thermalManager.setTargetHotend(_MIN(heater_maxtemp[endnum] - 15, temph), endnum); +void Temperature::lcd_preheat(const int16_t e, const int8_t indh, const int8_t indb) { + #if HAS_HOTEND + if (indh >= 0 && ui.material_preset[indh].hotend_temp > 0) + setTargetHotend(_MIN(thermalManager.heater_maxtemp[e] - HOTEND_OVERSHOOT, ui.material_preset[indh].hotend_temp), e); + #else + UNUSED(e); UNUSED(indh); #endif #if HAS_HEATED_BED - if (tempb >= 0) thermalManager.setTargetBed(tempb); + if (indb >= 0 && ui.material_preset[indb].bed_temp > 0) setTargetBed(ui.material_preset[indb].bed_temp); #else - UNUSED(tempb); + UNUSED(indb); #endif - #if FAN_COUNT > 0 - #if FAN_COUNT > 1 - thermalManager.set_fan_speed(active_extruder < FAN_COUNT ? active_extruder : 0, fan); - #else - thermalManager.set_fan_speed(0, fan); - #endif - #else - UNUSED(fan); + #if HAS_FAN + set_fan_speed(( + #if FAN_COUNT > 1 + active_extruder < FAN_COUNT ? active_extruder : + #endif + 0), ui.material_preset[indh].fan_speed + ); #endif ui.return_to_status(); } -#if HAS_TEMP_HOTEND - inline void _preheat_end(const uint8_t m, const uint8_t e) { - _lcd_preheat(e, ui.preheat_hotend_temp[m], -1, ui.preheat_fan_speed[m]); - } +#if PREHEAT_COUNT + + #if HAS_TEMP_HOTEND + inline void _preheat_end(const uint8_t m, const uint8_t e) { thermalManager.lcd_preheat(e, m, -1); } + #if HAS_HEATED_BED + inline void _preheat_both(const uint8_t m, const uint8_t e) { thermalManager.lcd_preheat(e, m, m); } + #endif + #endif #if HAS_HEATED_BED - inline void _preheat_both(const uint8_t m, const uint8_t e) { - _lcd_preheat(e, ui.preheat_hotend_temp[m], ui.preheat_bed_temp[m], ui.preheat_fan_speed[m]); - } + inline void _preheat_bed(const uint8_t m) { thermalManager.lcd_preheat(-1, -1, m); } #endif -#endif -#if HAS_HEATED_BED - inline void _preheat_bed(const uint8_t m) { - _lcd_preheat(0, 0, ui.preheat_bed_temp[m], ui.preheat_fan_speed[m]); - } -#endif -#if HAS_TEMP_HOTEND || HAS_HEATED_BED + #if HAS_TEMP_HOTEND && HAS_HEATED_BED + + // Indexed "Preheat ABC" and "Heat Bed" items + #define PREHEAT_ITEMS(M,E) do{ \ + ACTION_ITEM_N_S(E, ui.get_preheat_label(M), MSG_PREHEAT_M_H, []{ _preheat_both(M, MenuItemBase::itemIndex); }); \ + ACTION_ITEM_N_S(E, ui.get_preheat_label(M), MSG_PREHEAT_M_END_E, []{ _preheat_end(M, MenuItemBase::itemIndex); }); \ + }while(0) + + #elif HAS_MULTI_HOTEND + + // No heated bed, so just indexed "Preheat ABC" items + #define PREHEAT_ITEMS(M,E) ACTION_ITEM_N_S(E, ui.get_preheat_label(M), MSG_PREHEAT_M_H, []{ _preheat_end(M, MenuItemBase::itemIndex); }) - #define _PREHEAT_ITEMS(M,N) do{ \ - ACTION_ITEM_N(N, MSG_PREHEAT_##M##_H, []{ _preheat_both(M-1, MenuItemBase::itemIndex); }); \ - ACTION_ITEM_N(N, MSG_PREHEAT_##M##_END_E, []{ _preheat_end(M-1, MenuItemBase::itemIndex); }); \ - }while(0) - #if HAS_HEATED_BED - #define PREHEAT_ITEMS(M,N) _PREHEAT_ITEMS(M,N) - #else - #define PREHEAT_ITEMS(M,N) \ - ACTION_ITEM_N(N, MSG_PREHEAT_##M##_H, []{ _preheat_end(M-1, MenuItemBase::itemIndex); }) #endif - void menu_preheat_m1() { - START_MENU(); - BACK_ITEM(MSG_TEMPERATURE); - #if HOTENDS == 1 - #if HAS_HEATED_BED - ACTION_ITEM(MSG_PREHEAT_1, []{ _preheat_both(0, 0); }); - ACTION_ITEM(MSG_PREHEAT_1_END, []{ _preheat_end(0, 0); }); - #else - ACTION_ITEM(MSG_PREHEAT_1, []{ _preheat_end(0, 0); }); - #endif - #elif HOTENDS > 1 - #if HAS_HEATED_BED - _PREHEAT_ITEMS(1,0); - #endif - for (uint8_t n = 1; n < HOTENDS; n++) PREHEAT_ITEMS(1,n); - ACTION_ITEM(MSG_PREHEAT_1_ALL, []() { + void do_preheat_end_m() { _preheat_end(editable.int8, 0); } + + #if HAS_MULTI_HOTEND || HAS_HEATED_BED + + // Set editable.int8 to the Material index before entering this menu + // because MenuItemBase::itemIndex will be re-used by PREHEAT_ITEMS + void menu_preheat_m() { + const uint8_t m = editable.int8; // Don't re-use 'editable' in this menu + + START_MENU(); + BACK_ITEM(MSG_TEMPERATURE); + + #if HOTENDS == 1 + #if HAS_HEATED_BED - _preheat_bed(0); + ACTION_ITEM_S(ui.get_preheat_label(m), MSG_PREHEAT_M, []{ _preheat_both(editable.int8, 0); }); + ACTION_ITEM_S(ui.get_preheat_label(m), MSG_PREHEAT_M_END, do_preheat_end_m); + #else + ACTION_ITEM_S(ui.get_preheat_label(m), MSG_PREHEAT_M, do_preheat_end_m); #endif - HOTEND_LOOP() thermalManager.setTargetHotend(ui.preheat_hotend_temp[0], e); - }); - #endif // HOTENDS > 1 - #if HAS_HEATED_BED - ACTION_ITEM(MSG_PREHEAT_1_BEDONLY, []{ _preheat_bed(0); }); - #endif - END_MENU(); - } - void menu_preheat_m2() { - START_MENU(); - BACK_ITEM(MSG_TEMPERATURE); - #if HOTENDS == 1 - #if HAS_HEATED_BED - ACTION_ITEM(MSG_PREHEAT_2, []{ _preheat_both(1, 0); }); - ACTION_ITEM(MSG_PREHEAT_2_END, []{ _preheat_end(1, 0); }); - #else - ACTION_ITEM(MSG_PREHEAT_2, []{ _preheat_end(1, 0); }); + #elif HAS_MULTI_HOTEND + + HOTEND_LOOP() PREHEAT_ITEMS(editable.int8, e); + ACTION_ITEM_S(ui.get_preheat_label(m), MSG_PREHEAT_M_ALL, []() { + TERN_(HAS_HEATED_BED, []{ _preheat_bed(editable.int8); }); + HOTEND_LOOP() thermalManager.setTargetHotend(ui.material_preset[editable.int8].hotend_temp, e); + }); + #endif - #elif HOTENDS > 1 + #if HAS_HEATED_BED - _PREHEAT_ITEMS(2,0); + ACTION_ITEM_S(ui.get_preheat_label(m), MSG_PREHEAT_M_BEDONLY, []{ _preheat_bed(editable.int8); }); #endif - for (uint8_t n = 1; n < HOTENDS; n++) PREHEAT_ITEMS(2,n); - ACTION_ITEM(MSG_PREHEAT_2_ALL, []() { - #if HAS_HEATED_BED - _preheat_bed(1); - #endif - HOTEND_LOOP() thermalManager.setTargetHotend(ui.preheat_hotend_temp[1], e); - }); - #endif // HOTENDS > 1 - #if HAS_HEATED_BED - ACTION_ITEM(MSG_PREHEAT_2_BEDONLY, []{ _preheat_bed(1); }); - #endif - END_MENU(); - } + + END_MENU(); + } + + #endif // HAS_MULTI_HOTEND || HAS_HEATED_BED + +#endif // PREHEAT_COUNT + +#if HAS_TEMP_HOTEND || HAS_HEATED_BED void lcd_cooldown() { thermalManager.zero_fan_speeds(); @@ -162,6 +146,13 @@ void _lcd_preheat(const int16_t endnum, const int16_t temph, const int16_t tempb #endif // HAS_TEMP_HOTEND || HAS_HEATED_BED void menu_temperature() { + #if HAS_TEMP_HOTEND || HAS_HEATED_BED + bool has_heat = false; + #if HAS_TEMP_HOTEND + HOTEND_LOOP() if (thermalManager.temp_hotend[HOTEND_INDEX].target) { has_heat = true; break; } + #endif + #endif + START_MENU(); BACK_ITEM(MSG_MAIN); @@ -170,21 +161,22 @@ void menu_temperature() { // Nozzle [1-5]: // #if HOTENDS == 1 - EDIT_ITEM_FAST(int3, MSG_NOZZLE, &thermalManager.temp_hotend[0].target, 0, HEATER_0_MAXTEMP - 15, []{ thermalManager.start_watching_hotend(0); }); - #elif HOTENDS > 1 + EDIT_ITEM_FAST(int3, MSG_NOZZLE, &thermalManager.temp_hotend[0].target, 0, HEATER_0_MAXTEMP - (HOTEND_OVERSHOOT), []{ thermalManager.start_watching_hotend(0); }); + #elif HAS_MULTI_HOTEND HOTEND_LOOP() - EDIT_ITEM_FAST_N(int3, e, MSG_NOZZLE_N, &thermalManager.temp_hotend[e].target, 0, heater_maxtemp[e] - 15, []{ thermalManager.start_watching_hotend(MenuItemBase::itemIndex); }); + EDIT_ITEM_FAST_N(int3, e, MSG_NOZZLE_N, &thermalManager.temp_hotend[e].target, 0, thermalManager.heater_maxtemp[e] - (HOTEND_OVERSHOOT), []{ thermalManager.start_watching_hotend(MenuItemBase::itemIndex); }); #endif - #if ENABLED(SINGLENOZZLE) - EDIT_ITEM_FAST(uint16_3, MSG_NOZZLE_STANDBY, &singlenozzle_temp[active_extruder ? 0 : 1], 0, HEATER_0_MAXTEMP - 15); + #if ENABLED(SINGLENOZZLE_STANDBY_TEMP) + LOOP_S_L_N(e, 1, EXTRUDERS) + EDIT_ITEM_FAST_N(uint16_3, e, MSG_NOZZLE_STANDBY, &singlenozzle_temp[e], 0, thermalManager.heater_maxtemp[0] - (HOTEND_OVERSHOOT)); #endif // // Bed: // #if HAS_HEATED_BED - EDIT_ITEM_FAST(int3, MSG_BED, &thermalManager.temp_bed.target, 0, BED_MAXTEMP - 10, thermalManager.start_watching_bed); + EDIT_ITEM_FAST(int3, MSG_BED, &thermalManager.temp_bed.target, 0, BED_MAX_TARGET, thermalManager.start_watching_bed); #endif // @@ -197,101 +189,74 @@ void menu_temperature() { // // Fan Speed: // - #if FAN_COUNT > 0 - - auto on_fan_update = []{ - thermalManager.set_fan_speed(MenuItemBase::itemIndex, editable.uint8); - }; - - #if HAS_FAN1 || HAS_FAN2 || HAS_FAN3 || HAS_FAN4 || HAS_FAN5 || HAS_FAN6 || HAS_FAN7 - auto fan_edit_items = [&](const uint8_t f) { - editable.uint8 = thermalManager.fan_speed[f]; - EDIT_ITEM_FAST_N(percent, f, MSG_FAN_SPEED_N, &editable.uint8, 0, 255, on_fan_update); - #if ENABLED(EXTRA_FAN_SPEED) - EDIT_ITEM_FAST_N(percent, f, MSG_EXTRA_FAN_SPEED_N, &thermalManager.new_fan_speed[f], 3, 255); - #endif - }; - #endif + #if HAS_FAN - #define SNFAN(N) (ENABLED(SINGLENOZZLE) && !HAS_FAN##N && EXTRUDERS > N) - #if SNFAN(1) || SNFAN(2) || SNFAN(3) || SNFAN(4) || SNFAN(5) || SNFAN(6) || SNFAN(7) - auto singlenozzle_item = [&](const uint8_t f) { - editable.uint8 = thermalManager.fan_speed[f]; - EDIT_ITEM_FAST_N(percent, f, MSG_STORED_FAN_N, &editable.uint8, 0, 255, on_fan_update); - }; - #endif + DEFINE_SINGLENOZZLE_ITEM(); #if HAS_FAN0 - editable.uint8 = thermalManager.fan_speed[0]; - EDIT_ITEM_FAST_N(percent, 0, MSG_FIRST_FAN_SPEED, &editable.uint8, 0, 255, on_fan_update); - #if ENABLED(EXTRA_FAN_SPEED) - EDIT_ITEM_FAST_N(percent, 0, MSG_FIRST_EXTRA_FAN_SPEED, &thermalManager.new_fan_speed[0], 3, 255); - #endif + _FAN_EDIT_ITEMS(0,FIRST_FAN_SPEED); #endif #if HAS_FAN1 - fan_edit_items(1); + FAN_EDIT_ITEMS(1); #elif SNFAN(1) singlenozzle_item(1); #endif #if HAS_FAN2 - fan_edit_items(2); + FAN_EDIT_ITEMS(2); #elif SNFAN(2) - singlenozzle_item(1); + singlenozzle_item(2); #endif #if HAS_FAN3 - fan_edit_items(3); + FAN_EDIT_ITEMS(3); #elif SNFAN(3) - singlenozzle_item(1); + singlenozzle_item(3); #endif #if HAS_FAN4 - fan_edit_items(4); + FAN_EDIT_ITEMS(4); #elif SNFAN(4) - singlenozzle_item(1); + singlenozzle_item(4); #endif #if HAS_FAN5 - fan_edit_items(5); + FAN_EDIT_ITEMS(5); #elif SNFAN(5) - singlenozzle_item(1); + singlenozzle_item(5); #endif #if HAS_FAN6 - fan_edit_items(6); + FAN_EDIT_ITEMS(6); #elif SNFAN(6) - singlenozzle_item(1); + singlenozzle_item(6); #endif #if HAS_FAN7 - fan_edit_items(7); + FAN_EDIT_ITEMS(7); #elif SNFAN(7) - singlenozzle_item(1); + singlenozzle_item(7); #endif - #endif // FAN_COUNT > 0 - - #if HAS_TEMP_HOTEND + #endif // HAS_FAN + #if PREHEAT_COUNT // - // Preheat for Material 1 and 2 + // Preheat for Materials 1 to 5 // - #if TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 || TEMP_SENSOR_3 != 0 || TEMP_SENSOR_4 != 0 || TEMP_SENSOR_5 != 0 || TEMP_SENSOR_6 != 0 || TEMP_SENSOR_7 != 0 || HAS_HEATED_BED - SUBMENU(MSG_PREHEAT_1, menu_preheat_m1); - SUBMENU(MSG_PREHEAT_2, menu_preheat_m2); - #else - ACTION_ITEM(MSG_PREHEAT_1, []{ _preheat_end(0, 0); }); - ACTION_ITEM(MSG_PREHEAT_2, []{ _preheat_end(1, 0); }); - #endif + LOOP_L_N(m, PREHEAT_COUNT) { + editable.int8 = m; + #if HOTENDS > 1 || HAS_HEATED_BED + SUBMENU_S(ui.get_preheat_label(m), MSG_PREHEAT_M, menu_preheat_m); + #else + ACTION_ITEM_S(ui.get_preheat_label(m), MSG_PREHEAT_M, do_preheat_end_m); + #endif + } + #endif + #if HAS_TEMP_HOTEND || HAS_HEATED_BED // // Cooldown // - bool has_heat = false; - HOTEND_LOOP() if (thermalManager.temp_hotend[HOTEND_INDEX].target) { has_heat = true; break; } - #if HAS_TEMP_BED - if (thermalManager.temp_bed.target) has_heat = true; - #endif + if (TERN0(HAS_HEATED_BED, thermalManager.temp_bed.target)) has_heat = true; if (has_heat) ACTION_ITEM(MSG_COOLDOWN, lcd_cooldown); - - #endif // HAS_TEMP_HOTEND + #endif END_MENU(); } -#endif // HAS_LCD_MENU +#endif // HAS_LCD_MENU && HAS_TEMPERATURE diff --git a/Marlin/src/lcd/menu/menu_tmc.cpp b/Marlin/src/lcd/menu/menu_tmc.cpp index 0350d788eb15..402ee41a1b45 100644 --- a/Marlin/src/lcd/menu/menu_tmc.cpp +++ b/Marlin/src/lcd/menu/menu_tmc.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -26,9 +26,9 @@ #include "../../inc/MarlinConfigPre.h" -#if HAS_TRINAMIC && HAS_LCD_MENU +#if HAS_LCD_MENU && HAS_TRINAMIC_CONFIG -#include "menu.h" +#include "menu_item.h" #include "../../module/stepper/indirection.h" #include "../../feature/tmc_util.h" @@ -157,15 +157,27 @@ void menu_tmc_current() { BACK_ITEM(MSG_TMC_DRIVERS); #if X_SENSORLESS TMC_EDIT_STORED_SGT(X); - #endif - #if X2_SENSORLESS - TMC_EDIT_STORED_SGT(X2); + #if X2_SENSORLESS + TMC_EDIT_STORED_SGT(X2); + #endif #endif #if Y_SENSORLESS TMC_EDIT_STORED_SGT(Y); + #if Y2_SENSORLESS + TMC_EDIT_STORED_SGT(Y2); + #endif #endif #if Z_SENSORLESS TMC_EDIT_STORED_SGT(Z); + #if Z2_SENSORLESS + TMC_EDIT_STORED_SGT(Z2); + #endif + #if Z3_SENSORLESS + TMC_EDIT_STORED_SGT(Z3); + #endif + #if Z4_SENSORLESS + TMC_EDIT_STORED_SGT(Z4); + #endif #endif END_MENU(); } @@ -249,4 +261,4 @@ void menu_tmc() { END_MENU(); } -#endif // HAS_TRINAMIC +#endif // HAS_TRINAMIC_CONFIG diff --git a/Marlin/src/lcd/menu/menu_touch_screen.cpp b/Marlin/src/lcd/menu/menu_touch_screen.cpp new file mode 100644 index 000000000000..96eae2298e6c --- /dev/null +++ b/Marlin/src/lcd/menu/menu_touch_screen.cpp @@ -0,0 +1,36 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfigPre.h" + +#if BOTH(HAS_LCD_MENU, TOUCH_SCREEN_CALIBRATION) + +#include "menu_item.h" +#include "../ultralcd.h" + +void touch_screen_calibration() { + + ui.touch_calibration(); + +} + +#endif // TOUCH_SCREEN_CALIBRATION diff --git a/Marlin/src/lcd/menu/menu_tune.cpp b/Marlin/src/lcd/menu/menu_tune.cpp index 9221d7700541..6bf5c3a15d96 100644 --- a/Marlin/src/lcd/menu/menu_tune.cpp +++ b/Marlin/src/lcd/menu/menu_tune.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -28,7 +28,7 @@ #if HAS_LCD_MENU -#include "menu.h" +#include "menu_item.h" #include "../../module/motion.h" #include "../../module/planner.h" #include "../../module/temperature.h" @@ -46,7 +46,7 @@ #include "../../feature/babystep.h" #include "../lcdprint.h" - #if HAS_GRAPHICAL_LCD + #if HAS_MARLINUI_U8GLIB #include "../dogm/ultralcd_DOGM.h" #endif @@ -55,9 +55,10 @@ if (ui.encoderPosition) { const int16_t steps = int16_t(ui.encoderPosition) * ( #if ENABLED(BABYSTEP_XY) - axis != Z_AXIS ? BABYSTEP_MULTIPLICATOR_XY : + axis == X_AXIS ? BABYSTEP_SIZE_X : + axis == Y_AXIS ? BABYSTEP_SIZE_Y : #endif - BABYSTEP_MULTIPLICATOR_Z + BABYSTEP_SIZE_Z ); ui.encoderPosition = 0; ui.refresh(LCDVIEW_REDRAW_NOW); @@ -65,23 +66,15 @@ } if (ui.should_draw()) { const float spm = planner.steps_to_mm[axis]; - MenuEditItemBase::draw_edit_screen(msg, LCD_Z_OFFSET_FUNC(spm * babystep.accum)); + MenuEditItemBase::draw_edit_screen(msg, BABYSTEP_TO_STR(spm * babystep.accum)); #if ENABLED(BABYSTEP_DISPLAY_TOTAL) - const bool in_view = (true - #if HAS_GRAPHICAL_LCD - && PAGE_CONTAINS(LCD_PIXEL_HEIGHT - MENU_FONT_HEIGHT, LCD_PIXEL_HEIGHT - 1) - #endif - ); + const bool in_view = TERN1(HAS_MARLINUI_U8GLIB, PAGE_CONTAINS(LCD_PIXEL_HEIGHT - MENU_FONT_HEIGHT, LCD_PIXEL_HEIGHT - 1)); if (in_view) { - #if HAS_GRAPHICAL_LCD - ui.set_font(FONT_MENU); - lcd_moveto(0, LCD_PIXEL_HEIGHT - MENU_FONT_DESCENT); - #else - lcd_moveto(0, LCD_HEIGHT - 1); - #endif + TERN_(HAS_MARLINUI_U8GLIB, ui.set_font(FONT_MENU)); + lcd_moveto(0, TERN(HAS_MARLINUI_U8GLIB, LCD_PIXEL_HEIGHT - MENU_FONT_DESCENT, LCD_HEIGHT - 1)); lcd_put_u8str_P(GET_TEXT(MSG_BABYSTEP_TOTAL)); lcd_put_wchar(':'); - lcd_put_u8str(LCD_Z_OFFSET_FUNC(spm * babystep.axis_total[BS_TOTAL_IND(axis)])); + lcd_put_u8str(BABYSTEP_TO_STR(spm * babystep.axis_total[BS_TOTAL_IND(axis)])); } #endif } @@ -126,94 +119,71 @@ void menu_tune() { // Nozzle [1-4]: // #if HOTENDS == 1 - EDIT_ITEM_FAST(int3, MSG_NOZZLE, &thermalManager.temp_hotend[0].target, 0, HEATER_0_MAXTEMP - 15, []{ thermalManager.start_watching_hotend(0); }); - #elif HOTENDS > 1 + EDIT_ITEM_FAST(int3, MSG_NOZZLE, &thermalManager.temp_hotend[0].target, 0, HEATER_0_MAXTEMP - HOTEND_OVERSHOOT, []{ thermalManager.start_watching_hotend(0); }); + #elif HAS_MULTI_HOTEND HOTEND_LOOP() - EDIT_ITEM_FAST_N(int3, e, MSG_NOZZLE_N, &thermalManager.temp_hotend[e].target, 0, heater_maxtemp[e] - 15, []{ thermalManager.start_watching_hotend(MenuItemBase::itemIndex); }); + EDIT_ITEM_FAST_N(int3, e, MSG_NOZZLE_N, &thermalManager.temp_hotend[e].target, 0, thermalManager.heater_maxtemp[e] - HOTEND_OVERSHOOT, []{ thermalManager.start_watching_hotend(MenuItemBase::itemIndex); }); #endif - #if ENABLED(SINGLENOZZLE) - EDIT_ITEM_FAST(uint16_3, MSG_NOZZLE_STANDBY, &singlenozzle_temp[active_extruder ? 0 : 1], 0, HEATER_0_MAXTEMP - 15); + #if ENABLED(SINGLENOZZLE_STANDBY_TEMP) + LOOP_S_L_N(e, 1, EXTRUDERS) + EDIT_ITEM_FAST_N(uint16_3, e, MSG_NOZZLE_STANDBY, &singlenozzle_temp[e], 0, thermalManager.heater_maxtemp[0] - HOTEND_OVERSHOOT); #endif // // Bed: // #if HAS_HEATED_BED - EDIT_ITEM_FAST(int3, MSG_BED, &thermalManager.temp_bed.target, 0, BED_MAXTEMP - 10, thermalManager.start_watching_bed); + EDIT_ITEM_FAST(int3, MSG_BED, &thermalManager.temp_bed.target, 0, BED_MAX_TARGET, thermalManager.start_watching_bed); #endif // // Fan Speed: // - #if FAN_COUNT > 0 + #if HAS_FAN - auto on_fan_update = []{ - thermalManager.set_fan_speed(MenuItemBase::itemIndex, editable.uint8); - }; - - #if HAS_FAN1 || HAS_FAN2 || HAS_FAN3 || HAS_FAN4 || HAS_FAN5 || HAS_FAN6 || HAS_FAN7 - auto fan_edit_items = [&](const uint8_t f) { - editable.uint8 = thermalManager.fan_speed[f]; - EDIT_ITEM_FAST_N(percent, f, MSG_FAN_SPEED_N, &editable.uint8, 0, 255, on_fan_update); - #if ENABLED(EXTRA_FAN_SPEED) - EDIT_ITEM_FAST_N(percent, f, MSG_EXTRA_FAN_SPEED_N, &thermalManager.new_fan_speed[f], 3, 255); - #endif - }; - #endif - - #define SNFAN(N) (ENABLED(SINGLENOZZLE) && !HAS_FAN##N && EXTRUDERS > N) - #if SNFAN(1) || SNFAN(2) || SNFAN(3) || SNFAN(4) || SNFAN(5) || SNFAN(6) || SNFAN(7) - auto singlenozzle_item = [&](const uint8_t f) { - editable.uint8 = thermalManager.fan_speed[f]; - EDIT_ITEM_FAST_N(percent, f, MSG_STORED_FAN_N, &editable.uint8, 0, 255, on_fan_update); - }; - #endif + DEFINE_SINGLENOZZLE_ITEM(); #if HAS_FAN0 - editable.uint8 = thermalManager.fan_speed[0]; - EDIT_ITEM_FAST_N(percent, 0, MSG_FIRST_FAN_SPEED, &editable.uint8, 0, 255, on_fan_update); - #if ENABLED(EXTRA_FAN_SPEED) - EDIT_ITEM_FAST_N(percent, 0, MSG_FIRST_EXTRA_FAN_SPEED, &thermalManager.new_fan_speed[0], 3, 255); - #endif + _FAN_EDIT_ITEMS(0,FIRST_FAN_SPEED); #endif #if HAS_FAN1 - fan_edit_items(1); + FAN_EDIT_ITEMS(1); #elif SNFAN(1) singlenozzle_item(1); #endif #if HAS_FAN2 - fan_edit_items(2); + FAN_EDIT_ITEMS(2); #elif SNFAN(2) - singlenozzle_item(1); + singlenozzle_item(2); #endif #if HAS_FAN3 - fan_edit_items(3); + FAN_EDIT_ITEMS(3); #elif SNFAN(3) - singlenozzle_item(1); + singlenozzle_item(3); #endif #if HAS_FAN4 - fan_edit_items(4); + FAN_EDIT_ITEMS(4); #elif SNFAN(4) - singlenozzle_item(1); + singlenozzle_item(4); #endif #if HAS_FAN5 - fan_edit_items(5); + FAN_EDIT_ITEMS(5); #elif SNFAN(5) - singlenozzle_item(1); + singlenozzle_item(5); #endif #if HAS_FAN6 - fan_edit_items(6); + FAN_EDIT_ITEMS(6); #elif SNFAN(6) - singlenozzle_item(1); + singlenozzle_item(6); #endif #if HAS_FAN7 - fan_edit_items(7); + FAN_EDIT_ITEMS(7); #elif SNFAN(7) - singlenozzle_item(1); + singlenozzle_item(7); #endif - #endif // FAN_COUNT > 0 + #endif // HAS_FAN // // Flow: @@ -221,8 +191,8 @@ void menu_tune() { #if EXTRUDERS EDIT_ITEM(int3, MSG_FLOW, &planner.flow_percentage[active_extruder], 10, 999, []{ planner.refresh_e_factor(active_extruder); }); // Flow En: - #if EXTRUDERS > 1 - for (uint8_t n = 0; n < EXTRUDERS; n++) + #if HAS_MULTI_EXTRUDER + LOOP_L_N(n, EXTRUDERS) EDIT_ITEM_N(int3, n, MSG_FLOW_N, &planner.flow_percentage[n], 10, 999, []{ planner.refresh_e_factor(MenuItemBase::itemIndex); }); #endif #endif @@ -232,10 +202,10 @@ void menu_tune() { // #if ENABLED(LIN_ADVANCE) && DISABLED(SLIM_LCD_MENUS) #if EXTRUDERS == 1 - EDIT_ITEM(float52, MSG_ADVANCE_K, &planner.extruder_advance_K[0], 0, 999); - #elif EXTRUDERS > 1 - for (uint8_t n = 0; n < EXTRUDERS; n++) - EDIT_ITEM_N(float52, n, MSG_ADVANCE_K_E, &planner.extruder_advance_K[n], 0, 999); + EDIT_ITEM(float42_52, MSG_ADVANCE_K, &planner.extruder_advance_K[0], 0, 999); + #elif HAS_MULTI_EXTRUDER + LOOP_L_N(n, EXTRUDERS) + EDIT_ITEM_N(float42_52, n, MSG_ADVANCE_K_E, &planner.extruder_advance_K[n], 0, 999); #endif #endif diff --git a/Marlin/src/lcd/menu/menu_ubl.cpp b/Marlin/src/lcd/menu/menu_ubl.cpp index 8488c11c7df6..f0f5c21beca2 100644 --- a/Marlin/src/lcd/menu/menu_ubl.cpp +++ b/Marlin/src/lcd/menu/menu_ubl.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -26,11 +26,14 @@ #include "../../inc/MarlinConfigPre.h" -#if HAS_LCD_MENU && ENABLED(AUTO_BED_LEVELING_UBL) +#if BOTH(HAS_LCD_MENU, AUTO_BED_LEVELING_UBL) -#include "menu.h" +#include "menu_item.h" +#include "../../gcode/gcode.h" +#include "../../gcode/queue.h" +#include "../../module/motion.h" #include "../../module/planner.h" -#include "../../module/configuration_store.h" +#include "../../module/settings.h" #include "../../feature/bedlevel/bedlevel.h" static int16_t ubl_storage_slot = 0, @@ -39,53 +42,49 @@ static int16_t ubl_storage_slot = 0, ubl_fillin_amount = 5, ubl_height_amount = 1; -static uint8_t n_edit_pts = 1, x_plot = 0, y_plot = 0; +static uint8_t n_edit_pts = 1; +static int8_t x_plot = 0, y_plot = 0; // May be negative during move #if HAS_HEATED_BED static int16_t custom_bed_temp = 50; #endif -float mesh_edit_value, mesh_edit_accumulator; // We round mesh_edit_value to 2.5 decimal places. So we keep a - // separate value that doesn't lose precision. -static int16_t ubl_encoderPosition = 0; +float mesh_edit_accumulator; // Rounded to 2.5 decimal places on use -static void _lcd_mesh_fine_tune(PGM_P msg) { +inline float rounded_mesh_value() { + const int32_t rounded = int32_t(mesh_edit_accumulator * 1000); + return float(rounded - (rounded % 5L)) / 1000; +} + +static void _lcd_mesh_fine_tune(PGM_P const msg) { ui.defer_status_screen(); if (ubl.encoder_diff) { - ubl_encoderPosition = (ubl.encoder_diff > 0) ? 1 : -1; + mesh_edit_accumulator += TERN(IS_TFTGLCD_PANEL, + ubl.encoder_diff * 0.005f / ENCODER_PULSES_PER_STEP, + ubl.encoder_diff > 0 ? 0.005f : -0.005f + ); ubl.encoder_diff = 0; - - mesh_edit_accumulator += float(ubl_encoderPosition) * 0.005f * 0.5f; - mesh_edit_value = mesh_edit_accumulator; - ui.encoderPosition = 0; - ui.refresh(LCDVIEW_CALL_REDRAW_NEXT); - - const int32_t rounded = (int32_t)(mesh_edit_value * 1000); - mesh_edit_value = float(rounded - (rounded % 5L)) / 1000; + TERN(IS_TFTGLCD_PANEL,,ui.refresh(LCDVIEW_CALL_REDRAW_NEXT)); } + TERN_(IS_TFTGLCD_PANEL, ui.refresh(LCDVIEW_CALL_REDRAW_NEXT)); if (ui.should_draw()) { - MenuEditItemBase::draw_edit_screen(msg, ftostr43sign(mesh_edit_value)); - #if ENABLED(MESH_EDIT_GFX_OVERLAY) - _lcd_zoffset_overlay_gfx(mesh_edit_value); - #endif + const float rounded_f = rounded_mesh_value(); + MenuEditItemBase::draw_edit_screen(msg, ftostr43sign(rounded_f)); + TERN_(MESH_EDIT_GFX_OVERLAY, _lcd_zoffset_overlay_gfx(rounded_f)); + TERN_(HAS_GRAPHICAL_TFT, ui.refresh(LCDVIEW_NONE)); } } -void _lcd_mesh_edit_NOP() { - ui.defer_status_screen(); -} - -float lcd_mesh_edit() { - ui.goto_screen(_lcd_mesh_edit_NOP); - ui.refresh(LCDVIEW_CALL_REDRAW_NEXT); - _lcd_mesh_fine_tune(GET_TEXT(MSG_MESH_EDITOR)); - return mesh_edit_value; -} +// +// Called external to the menu system to acquire the result of an edit. +// +float lcd_mesh_edit() { return rounded_mesh_value(); } void lcd_mesh_edit_setup(const float &initial) { - mesh_edit_value = mesh_edit_accumulator = initial; - ui.goto_screen(_lcd_mesh_edit_NOP); + TERN_(HAS_GRAPHICAL_TFT, ui.clear_lcd()); + mesh_edit_accumulator = initial; + ui.goto_screen([]{ _lcd_mesh_fine_tune(GET_TEXT(MSG_MESH_EDIT_Z)); }); } void _lcd_z_offset_edit() { @@ -94,11 +93,11 @@ void _lcd_z_offset_edit() { float lcd_z_offset_edit() { ui.goto_screen(_lcd_z_offset_edit); - return mesh_edit_value; + return rounded_mesh_value(); } void lcd_z_offset_edit_setup(const float &initial) { - mesh_edit_value = mesh_edit_accumulator = initial; + mesh_edit_accumulator = initial; ui.goto_screen(_lcd_z_offset_edit); } @@ -106,15 +105,13 @@ void lcd_z_offset_edit_setup(const float &initial) { * UBL Build Custom Mesh Command */ void _lcd_ubl_build_custom_mesh() { - char ubl_lcd_gcode[20]; - queue.inject_P(G28_STR); + char ubl_lcd_gcode[64]; #if HAS_HEATED_BED - sprintf_P(ubl_lcd_gcode, PSTR("M190 S%i"), custom_bed_temp); - lcd_enqueue_one_now(ubl_lcd_gcode); + sprintf_P(ubl_lcd_gcode, PSTR("G28\nM190 S%i\nM109 S%i\nG29 P1"), custom_bed_temp, custom_hotend_temp); + #else + sprintf_P(ubl_lcd_gcode, PSTR("G28\nM109 S%i\nG29 P1"), custom_hotend_temp); #endif - sprintf_P(ubl_lcd_gcode, PSTR("M109 S%i"), custom_hotend_temp); - lcd_enqueue_one_now(ubl_lcd_gcode); - queue.inject_P(PSTR("G29 P1")); + queue.inject(ubl_lcd_gcode); } /** @@ -128,9 +125,11 @@ void _lcd_ubl_build_custom_mesh() { void _lcd_ubl_custom_mesh() { START_MENU(); BACK_ITEM(MSG_UBL_BUILD_MESH_MENU); - EDIT_ITEM(int3, MSG_UBL_HOTEND_TEMP_CUSTOM, &custom_hotend_temp, EXTRUDE_MINTEMP, (HEATER_0_MAXTEMP - 10)); + #if HAS_HOTEND + EDIT_ITEM(int3, MSG_UBL_HOTEND_TEMP_CUSTOM, &custom_hotend_temp, EXTRUDE_MINTEMP, HEATER_0_MAXTEMP - HOTEND_OVERSHOOT); + #endif #if HAS_HEATED_BED - EDIT_ITEM(int3, MSG_UBL_BED_TEMP_CUSTOM, &custom_bed_temp, BED_MINTEMP, (BED_MAXTEMP - 10)); + EDIT_ITEM(int3, MSG_UBL_BED_TEMP_CUSTOM, &custom_bed_temp, BED_MINTEMP, BED_MAX_TARGET); #endif ACTION_ITEM(MSG_UBL_BUILD_CUSTOM_MESH, _lcd_ubl_build_custom_mesh); END_MENU(); @@ -144,7 +143,7 @@ void _lcd_ubl_adjust_height_cmd() { const int ind = ubl_height_amount > 0 ? 9 : 10; strcpy_P(ubl_lcd_gcode, PSTR("G29 P6 C -")); sprintf_P(&ubl_lcd_gcode[ind], PSTR(".%i"), ABS(ubl_height_amount)); - lcd_enqueue_one_now(ubl_lcd_gcode); + queue.inject(ubl_lcd_gcode); } /** @@ -182,46 +181,62 @@ void _lcd_ubl_edit_mesh() { END_MENU(); } -/** - * UBL Validate Custom Mesh Command - */ -void _lcd_ubl_validate_custom_mesh() { - char ubl_lcd_gcode[24]; - const int temp = - #if HAS_HEATED_BED - custom_bed_temp - #else - 0 - #endif - ; - sprintf_P(ubl_lcd_gcode, PSTR("G26 C B%i H%i P"), temp, custom_hotend_temp); - lcd_enqueue_one_now_P(G28_STR); - lcd_enqueue_one_now(ubl_lcd_gcode); -} +#if ENABLED(G26_MESH_VALIDATION) + + /** + * UBL Validate Custom Mesh Command + */ + void _lcd_ubl_validate_custom_mesh() { + char ubl_lcd_gcode[24]; + sprintf_P(ubl_lcd_gcode, PSTR("G28\nG26 C P H%" PRIi16 TERN_(HAS_HEATED_BED, " B%" PRIi16)) + , custom_hotend_temp + #if HAS_HEATED_BED + , custom_bed_temp + #endif + ); + queue.inject(ubl_lcd_gcode); + } -/** - * UBL Validate Mesh submenu - * - * << UBL Tools - * Mesh Validation with Material 1 - * Mesh Validation with Material 2 - * Validate Custom Mesh - * << Info Screen - */ -void _lcd_ubl_validate_mesh() { - START_MENU(); - BACK_ITEM(MSG_UBL_TOOLS); - #if HAS_HEATED_BED - GCODES_ITEM(MSG_UBL_VALIDATE_MESH_M1, PSTR("G28\nG26 C B" STRINGIFY(PREHEAT_1_TEMP_BED) " H" STRINGIFY(PREHEAT_1_TEMP_HOTEND) " P")); - GCODES_ITEM(MSG_UBL_VALIDATE_MESH_M2, PSTR("G28\nG26 C B" STRINGIFY(PREHEAT_2_TEMP_BED) " H" STRINGIFY(PREHEAT_2_TEMP_HOTEND) " P")); - #else - GCODES_ITEM(MSG_UBL_VALIDATE_MESH_M1, PSTR("G28\nG26 C B0 H" STRINGIFY(PREHEAT_1_TEMP_HOTEND) " P")); - GCODES_ITEM(MSG_UBL_VALIDATE_MESH_M2, PSTR("G28\nG26 C B0 H" STRINGIFY(PREHEAT_2_TEMP_HOTEND) " P")); - #endif - ACTION_ITEM(MSG_UBL_VALIDATE_CUSTOM_MESH, _lcd_ubl_validate_custom_mesh); - ACTION_ITEM(MSG_INFO_SCREEN, ui.return_to_status); - END_MENU(); -} + /** + * UBL Validate Mesh submenu + * + * << UBL Tools + * Mesh Validation with Material 1 up to 5 + * Validate Custom Mesh + * << Info Screen + */ + void _lcd_ubl_validate_mesh() { + START_MENU(); + BACK_ITEM(MSG_UBL_TOOLS); + #if PREHEAT_COUNT + #if HAS_HEATED_BED + #define VALIDATE_MESH_GCODE_ITEM(M) \ + GCODES_ITEM_N_S(M, ui.get_preheat_label(M), MSG_UBL_VALIDATE_MESH_M, PSTR("G28\nG26 C P I" STRINGIFY(M))) + #else + #define VALIDATE_MESH_GCODE_ITEM(M) \ + GCODES_ITEM_N_S(M, ui.get_preheat_label(M), MSG_UBL_VALIDATE_MESH_M, PSTR("G28\nG26 C P B0 I" STRINGIFY(M))) + #endif + + VALIDATE_MESH_GCODE_ITEM(0); + #if PREHEAT_COUNT > 1 + VALIDATE_MESH_GCODE_ITEM(1); + #if PREHEAT_COUNT > 2 + VALIDATE_MESH_GCODE_ITEM(2); + #if PREHEAT_COUNT > 3 + VALIDATE_MESH_GCODE_ITEM(3); + #if PREHEAT_COUNT > 4 + VALIDATE_MESH_GCODE_ITEM(4); + #endif + #endif + #endif + #endif + #endif // PREHEAT_COUNT + ACTION_ITEM(MSG_UBL_VALIDATE_CUSTOM_MESH, _lcd_ubl_validate_custom_mesh); + ACTION_ITEM(MSG_INFO_SCREEN, ui.return_to_status); + END_MENU(); + } + +#endif /** * UBL Grid Leveling submenu @@ -237,7 +252,7 @@ void _lcd_ubl_grid_level() { ACTION_ITEM(MSG_UBL_MESH_LEVEL, []{ char ubl_lcd_gcode[12]; sprintf_P(ubl_lcd_gcode, PSTR("G29 J%i"), side_points); - lcd_enqueue_one_now(ubl_lcd_gcode); + queue.inject(ubl_lcd_gcode); }); END_MENU(); } @@ -265,7 +280,7 @@ void _lcd_ubl_mesh_leveling() { void _lcd_ubl_fillin_amount_cmd() { char ubl_lcd_gcode[18]; sprintf_P(ubl_lcd_gcode, PSTR("G29 P3 R C.%i"), ubl_fillin_amount); - lcd_enqueue_one_now(ubl_lcd_gcode); + gcode.process_subcommands_now(ubl_lcd_gcode); } /** @@ -297,8 +312,7 @@ void _lcd_ubl_invalidate() { * UBL Build Mesh submenu * * << UBL Tools - * Build Mesh with Material 1 - * Build Mesh with Material 2 + * Build Mesh with Material 1 up to 5 * - Build Custom Mesh >> * Build Cold Mesh * - Fill-in Mesh >> @@ -310,37 +324,36 @@ void _lcd_ubl_invalidate() { void _lcd_ubl_build_mesh() { START_MENU(); BACK_ITEM(MSG_UBL_TOOLS); - #if HAS_HEATED_BED - GCODES_ITEM(MSG_UBL_BUILD_MESH_M1, PSTR( - "G28\n" - "M190 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\n" - "M109 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) "\n" - "G29 P1\n" - "M104 S0\n" - "M140 S0" - )); - GCODES_ITEM(MSG_UBL_BUILD_MESH_M2, PSTR( - "G28\n" - "M190 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\n" - "M109 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) "\n" - "G29 P1\n" - "M104 S0\n" - "M140 S0" - )); - #else - GCODES_ITEM(MSG_UBL_BUILD_MESH_M1, PSTR( - "G28\n" - "M109 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) "\n" - "G29 P1\n" - "M104 S0" - )); - GCODES_ITEM(MSG_UBL_BUILD_MESH_M2, PSTR( - "G28\n" - "M109 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) "\n" - "G29 P1\n" - "M104 S0" - )); - #endif + #if PREHEAT_COUNT + #if HAS_HEATED_BED + #define PREHEAT_BED_GCODE(M) "M190 I" STRINGIFY(M) "\n" + #else + #define PREHEAT_BED_GCODE(M) "" + #endif + #define BUILD_MESH_GCODE_ITEM(M) GCODES_ITEM_S(ui.get_preheat_label(M), MSG_UBL_BUILD_MESH_M, \ + PSTR( \ + "G28\n" \ + PREHEAT_BED_GCODE(M) \ + "M109 I" STRINGIFY(M) "\n" \ + "G29 P1\n" \ + "M104 S0\n" \ + "M140 S0" \ + ) ) + BUILD_MESH_GCODE_ITEM(0); + #if PREHEAT_COUNT > 1 + BUILD_MESH_GCODE_ITEM(1); + #if PREHEAT_COUNT > 2 + BUILD_MESH_GCODE_ITEM(2); + #if PREHEAT_COUNT > 3 + BUILD_MESH_GCODE_ITEM(3); + #if PREHEAT_COUNT > 4 + BUILD_MESH_GCODE_ITEM(4); + #endif + #endif + #endif + #endif + #endif // PREHEAT_COUNT + SUBMENU(MSG_UBL_BUILD_CUSTOM_MESH, _lcd_ubl_custom_mesh); GCODES_ITEM(MSG_UBL_BUILD_COLD_MESH, PSTR("G28\nG29 P1")); SUBMENU(MSG_UBL_FILLIN_MESH, _menu_ubl_fillin); @@ -352,26 +365,16 @@ void _lcd_ubl_build_mesh() { } /** - * UBL Load Mesh Command + * UBL Load / Save Mesh Commands */ -void _lcd_ubl_load_mesh_cmd() { - char ubl_lcd_gcode[25]; - sprintf_P(ubl_lcd_gcode, PSTR("G29 L%i"), ubl_storage_slot); - lcd_enqueue_one_now(ubl_lcd_gcode); - sprintf_P(ubl_lcd_gcode, GET_TEXT(MSG_MESH_LOADED), ubl_storage_slot); - lcd_enqueue_one_now(ubl_lcd_gcode); -} - -/** - * UBL Save Mesh Command - */ -void _lcd_ubl_save_mesh_cmd() { - char ubl_lcd_gcode[25]; - sprintf_P(ubl_lcd_gcode, PSTR("G29 S%i"), ubl_storage_slot); - lcd_enqueue_one_now(ubl_lcd_gcode); - sprintf_P(ubl_lcd_gcode, GET_TEXT(MSG_MESH_SAVED), ubl_storage_slot); - lcd_enqueue_one_now(ubl_lcd_gcode); +inline void _lcd_ubl_load_save_cmd(const char loadsave, PGM_P const msg) { + char ubl_lcd_gcode[40]; + sprintf_P(ubl_lcd_gcode, PSTR("G29 %c%i\nM117 "), loadsave, ubl_storage_slot); + sprintf_P(&ubl_lcd_gcode[strlen(ubl_lcd_gcode)], msg, ubl_storage_slot); + gcode.process_subcommands_now(ubl_lcd_gcode); } +void _lcd_ubl_load_mesh_cmd() { _lcd_ubl_load_save_cmd('L', GET_TEXT(MSG_MESH_LOADED)); } +void _lcd_ubl_save_mesh_cmd() { _lcd_ubl_load_save_cmd('S', GET_TEXT(MSG_MESH_SAVED)); } /** * UBL Mesh Storage submenu @@ -385,9 +388,8 @@ void _lcd_ubl_storage_mesh() { int16_t a = settings.calc_num_meshes(); START_MENU(); BACK_ITEM(MSG_UBL_LEVEL_BED); - if (!WITHIN(ubl_storage_slot, 0, a - 1)) { + if (!WITHIN(ubl_storage_slot, 0, a - 1)) STATIC_ITEM(MSG_UBL_NO_STORAGE); - } else { EDIT_ITEM(int3, MSG_UBL_STORAGE_SLOT, &ubl_storage_slot, 0, a - 1); ACTION_ITEM(MSG_UBL_LOAD_MESH, _lcd_ubl_load_mesh_cmd); @@ -396,132 +398,137 @@ void _lcd_ubl_storage_mesh() { END_MENU(); } -/** - * UBL LCD "radar" map homing - */ -void _lcd_ubl_output_map_lcd(); - -void _lcd_ubl_map_homing() { - ui.defer_status_screen(); - _lcd_draw_homing(); - if (all_axes_homed()) { - ubl.lcd_map_control = true; // Return to the map screen - ui.goto_screen(_lcd_ubl_output_map_lcd); - } -} - /** * UBL LCD "radar" map point editing */ -void _lcd_ubl_map_lcd_edit_cmd() { +void _lcd_ubl_map_edit_cmd() { char ubl_lcd_gcode[50], str[10], str2[10]; dtostrf(ubl.mesh_index_to_xpos(x_plot), 0, 2, str); dtostrf(ubl.mesh_index_to_ypos(y_plot), 0, 2, str2); snprintf_P(ubl_lcd_gcode, sizeof(ubl_lcd_gcode), PSTR("G29 P4 X%s Y%s R%i"), str, str2, int(n_edit_pts)); - lcd_enqueue_one_now(ubl_lcd_gcode); + queue.inject(ubl_lcd_gcode); } /** * UBL LCD Map Movement */ void ubl_map_move_to_xy() { - const feedRate_t fr_mm_s = MMM_TO_MMS(XY_PROBE_SPEED); - - destination = current_position; // sync destination at the start #if ENABLED(DELTA) - if (current_position.z > delta_clip_start_height) { + if (current_position.z > delta_clip_start_height) { // Make sure the delta has fully free motion + destination = current_position; destination.z = delta_clip_start_height; - prepare_internal_move_to_destination(fr_mm_s); + prepare_internal_fast_move_to_destination(homing_feedrate(Z_AXIS)); // Set current_position from destination } #endif - destination.set(ubl.mesh_index_to_xpos(x_plot), ubl.mesh_index_to_ypos(y_plot)); - prepare_internal_move_to_destination(fr_mm_s); + // Set the nozzle position to the mesh point + current_position.set(ubl.mesh_index_to_xpos(x_plot), ubl.mesh_index_to_ypos(y_plot)); + + // Use the built-in manual move handler + ui.manual_move.soon(ALL_AXES); +} + +inline int32_t grid_index(const uint8_t x, const uint8_t y) { + return (GRID_MAX_POINTS_X) * y + x; } /** * UBL LCD "radar" map */ -void set_current_from_steppers_for_axis(const AxisEnum axis); -void sync_plan_position(); - -void _lcd_do_nothing() {} -void _lcd_hard_stop() { - const screenFunc_t old_screen = ui.currentScreen; - ui.currentScreen = _lcd_do_nothing; - planner.quick_stop(); - ui.currentScreen = old_screen; - set_current_from_steppers_for_axis(ALL_AXES); - sync_plan_position(); -} +void ubl_map_screen() { + // static millis_t next_move = 0; + // const millis_t ms = millis(); -void _lcd_ubl_output_map_lcd() { - static int16_t step_scaler = 0; + uint8_t x, y; - if (ui.use_click()) return _lcd_ubl_map_lcd_edit_cmd(); + if (ui.first_page) { - if (ui.encoderPosition) { - step_scaler += int32_t(ui.encoderPosition); - x_plot += step_scaler / (ENCODER_STEPS_PER_MENU_ITEM); - ui.encoderPosition = 0; - ui.refresh(LCDVIEW_REDRAW_NOW); - } + // On click send "G29 P4 ..." to edit the Z value + if (ui.use_click()) { + _lcd_ubl_map_edit_cmd(); + return; + } - #if IS_KINEMATIC - #define KEEP_LOOPING true // Loop until a valid point is found - #else - #define KEEP_LOOPING false - #endif + ui.defer_status_screen(); + + #if IS_KINEMATIC + // Index of the mesh point upon entry + const int32_t old_pos_index = grid_index(x_plot, y_plot); + // Direction from new (unconstrained) encoder value + const int8_t step_dir = int32_t(ui.encoderPosition) < old_pos_index ? -1 : 1; + #endif + + do { + // Now, keep the encoder position within range + if (int32_t(ui.encoderPosition) < 0) ui.encoderPosition = GRID_MAX_POINTS + TERN(TOUCH_SCREEN, ui.encoderPosition, -1); + if (int32_t(ui.encoderPosition) > GRID_MAX_POINTS - 1) ui.encoderPosition = TERN(TOUCH_SCREEN, ui.encoderPosition - GRID_MAX_POINTS, 0); - do { - // Encoder to the right (++) - if (x_plot >= GRID_MAX_POINTS_X) { x_plot = 0; y_plot++; } - if (y_plot >= GRID_MAX_POINTS_Y) y_plot = 0; + // Draw the grid point based on the encoder + x = ui.encoderPosition % (GRID_MAX_POINTS_X); + y = ui.encoderPosition / (GRID_MAX_POINTS_X); - // Encoder to the left (--) - if (x_plot < 0) { x_plot = GRID_MAX_POINTS_X - 1; y_plot--; } - if (y_plot < 0) y_plot = GRID_MAX_POINTS_Y - 1; + // Validate if needed + #if IS_KINEMATIC + const xy_pos_t xy = { ubl.mesh_index_to_xpos(x), ubl.mesh_index_to_ypos(y) }; + if (position_is_reachable(xy)) break; // Found a valid point + ui.encoderPosition += step_dir; // Test the next point + #endif + } while(ENABLED(IS_KINEMATIC)); + // Determine number of points to edit #if IS_KINEMATIC - const xy_pos_t xy = { ubl.mesh_index_to_xpos(x_plot), ubl.mesh_index_to_ypos(y_plot) }; - if (position_is_reachable(xy)) break; // Found a valid point - x_plot += (step_scaler < 0) ? -1 : 1; + n_edit_pts = 9; // TODO: Delta accessible edit points + #else + const bool xc = WITHIN(x, 1, GRID_MAX_POINTS_X - 2), + yc = WITHIN(y, 1, GRID_MAX_POINTS_Y - 2); + n_edit_pts = yc ? (xc ? 9 : 6) : (xc ? 6 : 4); // Corners #endif - } while(KEEP_LOOPING); - - // Determine number of points to edit - #if IS_KINEMATIC - n_edit_pts = 9; //TODO: Delta accessible edit points - #else - const bool xc = WITHIN(x_plot, 1, GRID_MAX_POINTS_X - 2), - yc = WITHIN(y_plot, 1, GRID_MAX_POINTS_Y - 2); - n_edit_pts = yc ? (xc ? 9 : 6) : (xc ? 6 : 4); // Corners - #endif + // Refresh is also set by encoder movement + //if (int32_t(ui.encoderPosition) != grid_index(x, y)) + // ui.refresh(LCDVIEW_CALL_REDRAW_NEXT); + } - // Cleanup - if (ABS(step_scaler) >= ENCODER_STEPS_PER_MENU_ITEM) step_scaler = 0; + // Draw the grid point based on the encoder + x = ui.encoderPosition % (GRID_MAX_POINTS_X); + y = ui.encoderPosition / (GRID_MAX_POINTS_X); - if (ui.should_draw()) { - ui.ubl_plot(x_plot, y_plot); + if (ui.should_draw()) ui.ubl_plot(x, y); - if (planner.movesplanned()) // If the nozzle is already moving, cancel the move. - _lcd_hard_stop(); + // Add a move if needed to match the grid point + if (x != x_plot || y != y_plot) { + x_plot = x; y_plot = y; // The move is always posted, so update the grid point now + ubl_map_move_to_xy(); // Sets up a "manual move" + ui.refresh(LCDVIEW_CALL_REDRAW_NEXT); // Clean up a half drawn box + } +} - ubl_map_move_to_xy(); // Move to new location +/** + * UBL LCD "radar" map homing + */ +void _ubl_map_screen_homing() { + ui.defer_status_screen(); + _lcd_draw_homing(); + if (all_axes_homed()) { + ubl.lcd_map_control = true; // Return to the map screen after editing Z + ui.goto_screen(ubl_map_screen, grid_index(x_plot, y_plot)); // Pre-set the encoder value + ui.manual_move.menu_scale = 0; // Immediate move + ubl_map_move_to_xy(); // Move to current mesh point + ui.manual_move.menu_scale = 1; // Delayed moves } } /** * UBL Homing before LCD map */ -void _lcd_ubl_output_map_lcd_cmd() { +void _ubl_goto_map_screen() { + if (planner.movesplanned()) return; // The ACTION_ITEM will do nothing if (!all_axes_known()) { set_all_unhomed(); queue.inject_P(G28_STR); } - ui.goto_screen(_lcd_ubl_map_homing); + ui.goto_screen(_ubl_map_screen_homing); // Go to the "Homing" screen } /** @@ -555,36 +562,42 @@ void _menu_ubl_tools() { BACK_ITEM(MSG_UBL_LEVEL_BED); SUBMENU(MSG_UBL_BUILD_MESH_MENU, _lcd_ubl_build_mesh); GCODES_ITEM(MSG_UBL_MANUAL_MESH, PSTR("G29 I999\nG29 P2 B T0")); - SUBMENU(MSG_UBL_VALIDATE_MESH_MENU, _lcd_ubl_validate_mesh); + #if ENABLED(G26_MESH_VALIDATION) + SUBMENU(MSG_UBL_VALIDATE_MESH_MENU, _lcd_ubl_validate_mesh); + #endif SUBMENU(MSG_EDIT_MESH, _lcd_ubl_edit_mesh); SUBMENU(MSG_UBL_MESH_LEVELING, _lcd_ubl_mesh_leveling); END_MENU(); } -/** - * UBL Step-By-Step submenu - * - * << Unified Bed Leveling - * 1 Build Cold Mesh - * 2 Smart Fill-in - * - 3 Validate Mesh >> - * 4 Fine Tune All - * - 5 Validate Mesh >> - * 6 Fine Tune All - * 7 Save Bed Mesh - */ -void _lcd_ubl_step_by_step() { - START_MENU(); - BACK_ITEM(MSG_UBL_LEVEL_BED); - GCODES_ITEM(MSG_UBL_1_BUILD_COLD_MESH, PSTR("G28\nG29 P1")); - GCODES_ITEM(MSG_UBL_2_SMART_FILLIN, PSTR("G29 P3 T0")); - SUBMENU(MSG_UBL_3_VALIDATE_MESH_MENU, _lcd_ubl_validate_mesh); - GCODES_ITEM(MSG_UBL_4_FINE_TUNE_ALL, PSTR("G29 P4 R999 T")); - SUBMENU(MSG_UBL_5_VALIDATE_MESH_MENU, _lcd_ubl_validate_mesh); - GCODES_ITEM(MSG_UBL_6_FINE_TUNE_ALL, PSTR("G29 P4 R999 T")); - ACTION_ITEM(MSG_UBL_7_SAVE_MESH, _lcd_ubl_save_mesh_cmd); - END_MENU(); -} +#if ENABLED(G26_MESH_VALIDATION) + + /** + * UBL Step-By-Step submenu + * + * << Unified Bed Leveling + * 1 Build Cold Mesh + * 2 Smart Fill-in + * - 3 Validate Mesh >> + * 4 Fine Tune All + * - 5 Validate Mesh >> + * 6 Fine Tune All + * 7 Save Bed Mesh + */ + void _lcd_ubl_step_by_step() { + START_MENU(); + BACK_ITEM(MSG_UBL_LEVEL_BED); + GCODES_ITEM(MSG_UBL_1_BUILD_COLD_MESH, PSTR("G28\nG29 P1")); + GCODES_ITEM(MSG_UBL_2_SMART_FILLIN, PSTR("G29 P3 T0")); + SUBMENU(MSG_UBL_3_VALIDATE_MESH_MENU, _lcd_ubl_validate_mesh); + GCODES_ITEM(MSG_UBL_4_FINE_TUNE_ALL, PSTR("G29 P4 R999 T")); + SUBMENU(MSG_UBL_5_VALIDATE_MESH_MENU, _lcd_ubl_validate_mesh); + GCODES_ITEM(MSG_UBL_6_FINE_TUNE_ALL, PSTR("G29 P4 R999 T")); + ACTION_ITEM(MSG_UBL_7_SAVE_MESH, _lcd_ubl_save_mesh_cmd); + END_MENU(); + } + +#endif /** * UBL System submenu @@ -599,7 +612,6 @@ void _lcd_ubl_step_by_step() { * - UBL Tools >> * - Output UBL Info >> */ - void _lcd_ubl_level_bed() { START_MENU(); BACK_ITEM(MSG_MOTION); @@ -607,8 +619,10 @@ void _lcd_ubl_level_bed() { GCODES_ITEM(MSG_UBL_DEACTIVATE_MESH, PSTR("G29 D")); else GCODES_ITEM(MSG_UBL_ACTIVATE_MESH, PSTR("G29 A")); - SUBMENU(MSG_UBL_STEP_BY_STEP_MENU, _lcd_ubl_step_by_step); - ACTION_ITEM(MSG_UBL_MESH_EDIT, _lcd_ubl_output_map_lcd_cmd); + #if ENABLED(G26_MESH_VALIDATION) + SUBMENU(MSG_UBL_STEP_BY_STEP_MENU, _lcd_ubl_step_by_step); + #endif + ACTION_ITEM(MSG_UBL_MESH_EDIT, _ubl_goto_map_screen); SUBMENU(MSG_UBL_STORAGE_MESH_MENU, _lcd_ubl_storage_mesh); SUBMENU(MSG_UBL_OUTPUT_MAP, _lcd_ubl_output_map); SUBMENU(MSG_UBL_TOOLS, _menu_ubl_tools); diff --git a/Marlin/src/lcd/scaled_tft.h b/Marlin/src/lcd/scaled_tft.h new file mode 100644 index 000000000000..2c05e5f26d81 --- /dev/null +++ b/Marlin/src/lcd/scaled_tft.h @@ -0,0 +1,55 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../inc/MarlinConfig.h" + +#ifndef GRAPHICAL_TFT_UPSCALE + #define GRAPHICAL_TFT_UPSCALE 2 +#endif + +#ifndef TFT_WIDTH + #if GRAPHICAL_TFT_UPSCALE == 3 + #define TFT_WIDTH 480 + #else + #define TFT_WIDTH 320 + #endif +#endif +#ifndef TFT_HEIGHT + #if GRAPHICAL_TFT_UPSCALE == 3 + #define TFT_HEIGHT 320 + #else + #define TFT_HEIGHT 240 + #endif +#endif + +#ifndef TFT_PIXEL_OFFSET_X + #if GRAPHICAL_TFT_UPSCALE == 2 + #define TFT_PIXEL_OFFSET_X 32 + #else + #define TFT_PIXEL_OFFSET_X 48 + #endif +#endif +#ifndef TFT_PIXEL_OFFSET_Y + // 32 is better for both 320x240 and 480x320 + #define TFT_PIXEL_OFFSET_Y 32 +#endif diff --git a/Marlin/src/lcd/tft/bitmaps/back.bmp b/Marlin/src/lcd/tft/bitmaps/back.bmp new file mode 100644 index 0000000000000000000000000000000000000000..5ad1f82542fb70779ed91bce77de3ee29299cce5 GIT binary patch literal 3126 zcmeH|y-s356vx?qA7INZ_X+HG`+WlW5Ct`A0s#aBloe?#OlY96FciE5l<)!?2o{C} zY!HE{@uL7E`&-XuGF&bQ?3!$`H{oXPoio4lKmR#*`1XC_qviEl;Qoc*=ik2%mQReh znEz^(pS-YGe*C}89Eiu`dwY9kGbZl{HhDY#mBeQpPwHe zABRFAJ=v@Cn}D-Zte!W-6P_K0ZFavIlo}cZhd59H#N2ywmAOF!#&LOP!C&NR39L?4!@; zgM4*$rGgopoSaZE=1_%Z$*&=vaJAcQJ)ZqV&&I|EK)>I=v$Jz}c$mxOPESwuFd4I7 zh*?@%8r?6*2-B6z5(+PsN|j0lqnLeuejdfDH|ca5{_5(gK|FBuw^}U~Ime(}F5?WH zNh9gzi*mK0bC6l`@bG|#Z0qLcrY>HT8$6#Q1>WKe-xM99#Pc$lO!5WI0o0eU+9=8f_+oAA(y0J`OVFZ zGD^<3wY4>lENYbYo>H@c&!ehBrI7QP#uh8)CaYYM0>QVpw^T9t{8y`H8b}KM7W@5v zv)RP?asMwfVfA3O7wG5I`s;jhVK^Jgc}UN^2VYV^Mn8Ynf4;N2KWdCo9E0x!S6Tke F!B0sxQ3?P6 literal 0 HcmV?d00001 diff --git a/Marlin/src/lcd/tft/bitmaps/bed.bmp b/Marlin/src/lcd/tft/bitmaps/bed.bmp new file mode 100644 index 0000000000000000000000000000000000000000..842174f82081429e5f914f27cfad78a722f067fd GIT binary patch literal 12342 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 B);a(H literal 0 HcmV?d00001 diff --git a/Marlin/src/lcd/tft/bitmaps/confirm.bmp b/Marlin/src/lcd/tft/bitmaps/confirm.bmp new file mode 100644 index 0000000000000000000000000000000000000000..076fa57897deb90f8ec673b42d73fdd92c062cd0 GIT binary patch literal 12410 zcmeI0$xa(V5Qd#R1&@(ONVxa_W-%N9<-&zU^34apW=U9tkl+>Agajw{GYAke%MEek zMG#x^g-S}TZo>@YF_}T#l1)$BO#k)&e^uAGF<1JMc^)O+3%tJmeSOL_Fk|rfx9{?j zg-oU~n=k&GhyDB6`r;2iJOiEq&wyvZGvFEcC=5(ZO-)WtrZJkI&trIaxLhtXO;-p2 zhW0|Ckk99PdU}S2h7ckxAqe=v!NF`c+tk#Q%jLSeyAdK4ApjnnfbZ<=1an76M{{#? zOG`^CLJ;Qr`}v za5}$pkEFI~YikR%jT-_+T3J~^0<)-2Pfx#3gQ4I_SgrFe$k$iYNM;D{pn`zskc!5< z85BlZU0oFwq^Q=r%~R&XfQR9mn;R3bJFlujo!UGFPr~l*?z&*i6}ZJ(V`F2dr>Ew+ zJ0}E+Diy4*ZJr4}Fkwkg$|FGW?)g}8D7@Qjd$l-LI51-#V5(a}*ZFE1}G&aF%HbdIq{qNedMBK^Fz zqjd>*`X39tgn$Z60z=>qR3uy^MykEphI!cQ?d{#%+_ccTms?v~Y8!!VzKfC0&d%I_ zG*?JxJ=$tl0o`Y3XHQN}%q`qG(!a#K8A3E8)zYc*(?|GfV|w0%ZO%igAh{q$s^zI| ze0+R zsuR*VmRw*v&U7mTz`vDwGY}*|+)AZV6}c|5i#FS8qzIj=s{(lufq658km=0PCPpG1 z2tm?0LZ_-KP~r{`54nUu6HkOWDv&sVr!z*<2T$!(sqJswk?rQ@=GNEOu~Y5fWq0n$ zBru&-1?jgrQX@#fMr>E3ZCuhs%D{9+cTQ)1D8NE=hSBi5yT`HuEeINDB=UM;VWC(o zCJMYTKnUc*>lNwv_;_Y!CKkr(aTAP06fdc8aBx6V%@^vibzJup72I3^eC&A_7iQ}| zgka^u(a{m$B1$C87g1b*(2VbO1 z`qQL~WDs(1pl}Y{#2C3b`S=qT&*81`n~)w~Y26*ym2g8x6ng)Dby$ZJg0Oga@&1nI zK3`8Rd`BPv0SG_<0uX=z1Rwwb2tWV=5P$##*a;*_@^PuKYkk~_ihG`CS=New*6TG{ zvHc2ZnmUf7Y1$Ld=(>A!xztNHXB7z znD_U6zpm>&|Fmr@NfM9#Wm)pCzu)b4vMi(j@KrfIsa%l7_7^S|A0zxk){`!EdYUOD*zp8qn-vQPfW^Zfj(CwGYB_>F&}C_4G+ hI0*p=KmY;|fB*y_009U<00Izz00bZa0SH`P;0K*ldIJCe literal 0 HcmV?d00001 diff --git a/Marlin/src/lcd/tft/bitmaps/directory.bmp b/Marlin/src/lcd/tft/bitmaps/directory.bmp new file mode 100644 index 0000000000000000000000000000000000000000..994abc70db0e527afe43b672db0e19fe4a63d080 GIT binary patch literal 3194 zcmZ?rt>R$-gDN1I1H=kY%*Y@CWB~zC-Z2J(Ap#5xPVPa)FgCF?6Pm(?;RPBS8=EKt zKof8U2~euCvNE4CP*hX|bRbqMDk>^!Yim0@J3Gh)ZEbByNlAHmd6-rJP2RR`+kc9| zxpU`$Rx~#^qj{max|(9Mp#~%*Bn*i8|Ni}>iWhLXf7EbmtX=&0$aLtX?=Y?TIB-d5@~)*OAAmXFtOnRz literal 0 HcmV?d00001 diff --git a/Marlin/src/lcd/tft/bitmaps/down.bmp b/Marlin/src/lcd/tft/bitmaps/down.bmp new file mode 100644 index 0000000000000000000000000000000000000000..42ff4e5cafcd9ba7e72e12d05c91892e4daeb061 GIT binary patch literal 3126 zcmeH{xvFA85Qd$69$>-==K=I0ijKP&OrY^32BL|P;J$BQ;D!r|A|irI;2W5V8wkFP zqUhWo>mtSRDvl!)*>IXV-PPY;U0vOpUvFPUr}l>a2fptg-xtw0SZJ76|E7-yM55@c zy)wWukVqur@i-fJrWp!_tX8Yj>4eHNxzT7O5<%EDn@uW}s?}<**ZV{Xz};?lzu#Z2 zRvL{)sZ<&a2A|LOltcmU@p$U>`kzyqOeQ~1O{dcZ0)c;&Ab7P}B{=od=~O0@K?HjV zhr<*?iBHsC0gSS*Gh%jL2_0u_Zz2MMFmcuj)fh*JRXbUG*!%mR)#0R|*W zrPASW;GVPD3~maA0+C!wT!Z7zVhOMWr#FWr3WWma!$zV=0$0!BaPWJ9%RU;71pb4; zKrWZVjl;P_Hk%bJ!Eu|-W~{PUEXib&oYA{nuI+ZqodHK-d2=~! z1%ttKI=$I!$hp_+U5or25*bJ}m&jx?TCFyfN^v-O;(}mDyWMU)9wPuaT>1#$XNi11 zkHEU!uE}J&R-ZUENWc@uon+#}AIFE|#_#Qg@I<1}e;VhF!G{;#V7{ha8Tbzwcn25a BkSPEF literal 0 HcmV?d00001 diff --git a/Marlin/src/lcd/tft/bitmaps/fan0.bmp b/Marlin/src/lcd/tft/bitmaps/fan0.bmp new file mode 100644 index 0000000000000000000000000000000000000000..558dbe4f8fea2eab1ba5caebe31737c560b11154 GIT binary patch literal 12410 zcmeI&g^pay5e8r8|>#`mgHh9{*Oe;I9=5TY=B+{{Hs+-=8Y{#gpd!-&=&g z&{3hnZea4YyJ^#=0|ySwdlgIs zc))-G9XodXM`7#KsS|-Z^OhN77w~jJUa?}us#UAPU!z8i)~#EcLSxLtB40r`Y}hc! z$*ESYTJ`GHYu2n;t5&W0_3L-&(1DkNbw$q2qjU7=(f#`Mt5c^AKVeRej96 zYp(7x-Yl-DQl(0R1`V1uYX&weID|}AG;G+gZ{NOwT6v(2Od*Ff>c);8d+pk_@87?_ zfB$~MgbAERUAuPea>8#gvP0OaRjc{)=N~z8k|zs928y?Yy+ z$Ks~r2cGA7Y0;uZU;`i8#fujkH*U-XpYSBqVwk}eap=&YSFc|EL)h>C-nemN(xgd< zr11=oF#&*dJUKm^YoYmS@#4i1T^~MtfJ7kB64pA2Wd7{dt(%EYo;-;N3|~Kg{=9PK zO0*0n@SC8^X?;^L%ql1-Xw<0Dym|A!e*K!MZques{IAJKNxa1Qg9i`h`TO_pXG%-& z*}Qo(w_p(~TDEM--aJg8PGsRZpQH;piiw3Kg)eE_CUpFVb|M~@z5)AHrZ7kLSVXz9|WOT3F{m)r5stZV|)`#*j9G;!j@ z5Y9}H@sju_*hQD*?DOW$o9Qw$pZD(FE2(mn7>Q4$VY3#YnL@Jlh!OE?eaW|1Vo|~+ zFcKKpvPn+$zkU0*fB*heSb}(>BG~HHt5XvbKAb*%8aeF?&!*UnP90P>d-WT!_-ygv9jUzI|JMgI_KUlH-?P#E20#k*80e#>kAkx_kF-_wL<; z3Aoy%NfY4~B8a;<1o@90I~JLh{3|?xqEbq+QH(t6)~!n}JdCs*BM%b-k*tM?W)xp> z$oTQ&i_Q5l8j*oOo>5@L^M|htIDh_pjI?a8Zr!>yX3Q9hWK`~w`kFUyP9TTaQWK`l zB85MG{5VCSu&miAWT9uyocZk8vm)gb+xhY1$6dR2Q9+$>LsuC?ARIq_yx6%h1ML1* zkV6!8(j9@>@YA?_`SNTVZj6fbSJZ9Ww#{15r8RX)NDYHaim}KCDnl(Hh z{AM9kgO@H{N=KE`^SE*2;Fp8lSE}J{_{FSKRZ57|N@>VQcCl1{ zt`9S2%xKY~1ufZvSHGp7GiT15H*azkF1;(U_y_)zCr?JEtC?*F5{RHyGNr#&q)EIo zwo{~P=gO5UHe9=B`dQC-d-s9`3%Iw~{BOHCbm&mJiX_i8_UzeHwvp&wzkVH=0yDd8 zKuY50&z}c8BHczgefo4paUI8MxJ?3AFIlo=%a$z%4<0;w_UxH6XN-)Yefo;P@0`vX z;xPgv+gJHk2_fg$KH!PC&a8Lu-ibbe;3&tId-v`wTegf+>Dr3Z7{G^5Uv=8`Gy=g! zcs<^xxUV)_w3oTYSk*Rtt{32oVi;G+W=K+#V(-@o53*{ z!Yi1Ab;XX13^0)jE9;75?b@}rkN*_59Xoc|AXcnc;kskWlqt;opPLH7z|TwS2Sh^Y zl+`S?C(5f%?zo}xPek2M`pWhIugFg@($|zNdK91Hv~%aq4zOI!XlB~W^xHsv+Kv-4 zxde@ZGu4U|>#e9+x^yWg!!KLfvj7&eo+W?H(&(`Z;8N+EP$cYBXRt0@rgiPwHDr5+ zfDN#R`ie7csd^nEDr+(9$S*PckbL#H8~5E zCU_AIzfv;^!k95CJr{KFmoj+xWgbeU&2X6$12Wqy_nEGD^1EBemJ)O7XM)rEtXZ>M z_zQ&0JD+UGonlQ~Au|<%&k<;&b&=@AO-K>(r z@Pl%~LcqhHZf?QDYJ~wOA3l88iNK*)lJv8V+a&gCru?ANpD`UOjTI1zN*hGTElkr> S7TEGLtS*;X?tx$Bf&T*c{D|HF literal 0 HcmV?d00001 diff --git a/Marlin/src/lcd/tft/bitmaps/fan1.bmp b/Marlin/src/lcd/tft/bitmaps/fan1.bmp new file mode 100644 index 0000000000000000000000000000000000000000..6da6f3294e63d813e55ced63e2b51bbc38451c5c GIT binary patch literal 12410 zcmeI&^^P3N6$fA^Pm#ySBP3TcGcz+Y#t<{JC8Lb83^K}=nItpGB$-iWW{mCR%hpZb zQO``zEM(VzY)RX$uC6-gcd$;?__vzF{#v1+4fE{b?{B~V{i(uV^fcf9-Xi>kfeICV zt6Z=D|N8m<`{&rif0nm$4U}u3 zC8!|O#*ZIAXU?3}t5C=njKTDP@Y2LiK%!6Rj0Tps( z0sQ~suTrH7)jfIgB!g!27?L&{H*P#|;K0&UevlPM`1yaWTD24gd4P>ixqkh6`}Xa7 z_wLOV3#q>nn2ssdb?VfqR;?Ox-@bi|<4b)1`t|FiNt3#F?_MV00j7WHx#Q@Dqd=2}avl5P>5p zO8-^RoD;cvj~+b$Rw+Gw`jiw7#lIB(AcC`iN=7cy7=j4XrcKl5RE(mLORziqo;Y!W zyjo<$U!lW`L}jyP%>sU~HJBO2NR1jb^hv?fR;*aT$FkusknHzIDa#dhgeFaz0PM+a zRHys)?K^w+?50hdx^(FRzj3E^E*D{g)d=%tYo&Is0Yg<23L8m@!>0!Fy?gh1_3Fj7 zM1-h^DgY)6FP*=_egz z#u1odu!KuQ#x)Ye@ijEB0V*OZSFUt7_3`6J7eR8-kRe0VIWau4DA)+jm@xz9jDTZH z!mA^az!x<*W&|7?1lulo;lhQB7cU+?dersK^5x5C&z{XUd#aU+LC+pzAzI?oHlIO&~;quCw<;UuF91wD>)uNejNLn^Yz1r5A)~GXYo|P zu|D0lXwibIb5hGT!I3s(dj}l89Zi$=-Q2?O)QO8DO!O)LjzCD*`#3zN^y5M!f10tG z!qzSjlD|NhH*cN`I-%XFRjUC52Eec6K6&zFY*n7GJ9g|4SuveQuY9{>$ByuuQ{?+h zNcQjF53M~*qwR_nD|&YB+?na+)va5%7Wv8|Cw^RPl=POf5>D2b<2lV!HAB>^SI=H1 z=SZz0J$YgBR~tmK{xPz}*g$O`$)s|Ab+6)pCfjfuLG8ArnAg1WtvxZ}?7;u=a*`5& z5?wLb*{u*1vp9C>(4k$scKpYMf6*eBx?a6{RWbG+j}M#;h{4;xlN52!v8X-+Pm#yFbB=Rk8GeUv$?fn2qH|LJlXwov?{s784yf%9_#`y z;YRnbEC|yTMqImQFu)2Za^7tcffq4> zjLO_rr4mW)`*n#bq!f^{p-mqrsiu|)B2bhAY%1AoeKm8xe*Mx3#zuhQV4O45Do$7# z3EFVQxM~oX7=@g#k)r}nQEC|XHW|4@gL1wQQ=jC+jtI6$_%#(>L?r6i{T<~RHEKjs zU~&RZpJ0_Acf#EuDHLO_{<0nV#E7VIJ(4Fc_*sftxR8bEiIg9T5s^|T&xuK4t@y=- zBN0KfiHOihOQEA!rFpp>l6;hpi)khY7xGNqj-B<~#?zZ(yExzj7y2ZEqK+47!dZdg zy2EcS;WEt?hiad$;K@_@K}#m9PHBb<@$+y;dh6CL=X4rlonnFyTqp`1)F6Z(JNp7D zNF=go$xezLLl+7>;^te$Ez#6uJg;Gcrg?cO04V;G2zWVoI-LbWa3o421-_j+b&{M5 z3m&TAY5o%eg`gu4oYbg7(3ObhV}e77queg9(vk)_UO~FpcS%=Dlkn>@4pYqHBhdBUrGc2 E0l_+m-T(jq literal 0 HcmV?d00001 diff --git a/Marlin/src/lcd/tft/bitmaps/fan_fast0.bmp b/Marlin/src/lcd/tft/bitmaps/fan_fast0.bmp new file mode 100644 index 0000000000000000000000000000000000000000..bd0de9a1eb3cdb55b92cac26b2322453fef25a28 GIT binary patch literal 12410 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 ZAXzvXjWi?1s}=Qq{&x#}w?K{s{tbONfS&*W literal 0 HcmV?d00001 diff --git a/Marlin/src/lcd/tft/bitmaps/fan_fast1.bmp b/Marlin/src/lcd/tft/bitmaps/fan_fast1.bmp new file mode 100644 index 0000000000000000000000000000000000000000..6da67fa44eaa086144192ff4bf9860c455f8ebd8 GIT binary patch literal 12410 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 J1ip#{{skjZ8zle$ literal 0 HcmV?d00001 diff --git a/Marlin/src/lcd/tft/bitmaps/fan_slow1.bmp b/Marlin/src/lcd/tft/bitmaps/fan_slow1.bmp new file mode 100644 index 0000000000000000000000000000000000000000..79d284b722553bf2a00577b1e24f37fbd1a468b1 GIT binary patch literal 12410 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 DyH+S5 literal 0 HcmV?d00001 diff --git a/Marlin/src/lcd/tft/bitmaps/flowrate.bmp b/Marlin/src/lcd/tft/bitmaps/flowrate.bmp new file mode 100644 index 0000000000000000000000000000000000000000..739375bd72a7ca2592a603e07288049be3983509 GIT binary patch literal 3194 zcmds&$4lKo5XVif$tkBC^S5}(DVH4Vy({)7mS>AWA}V&ojs>xSD53`y1$#lTS46Rk zieRs3KD;r@@_dS-rwqJxe!H{ZnVtF0X#K(VfB7Uo*|4&* z{{GYOPk-s(k7kCy-XIAH2~kl|Mx*f!7*AeJN=k~3j&^f%^YrvY;qyt;*B^iuA0O}T z?(X2=;OOWW5D@Ub_+$pj&d&Dn@o{o;a&>hjQSayiw8Fx|o12@gtSozbdtCVY`zIzQ zzCIHcZV-7yM8x9a;{E;o?CdOAB1O*5&LJTouX+N;gajI^ei886+S=ROTkw&hq9UF^ zA-ui4bu$Z*nYOSI2@MVP@bK{R@`52?$|hwcCwqH)0?xXS@qBU{(kOKWwBTIfq{WI z;-##TVY~<{z{k79qr+O%$HvCM=i>DAGzQ>H#z;|SW@c4YRc>ysq>(b=Lh=J=c+SSg zhK@@6E^wz z`Jf-$TJd=my6WheZ1o&lTWsEog^)S#64-XmIxB!;gO-)Vh@9!&{=H_P72np#j zQYTPydT?++W~g{?Z!bHHP}*5t)RoT8PVz(F4Gj(H`=o`6P$}Xh2FM1ZAdhZCbHRUh z7(Sw)Z*FelOYvlVeVu1Mg-`r+E`yyna?1?Ap`oF#uMfUmv)svGGF=Hk9z#@1dhMt}tbwoQrp`4r?!9k$}atg7TNUB&PBO{bm_(Li4 z^72%Di53@hG}UBwsVmeM=1UXN*T5DO6oiF^(UmFyrSLR@7yf{gmX^k(Ri`LtXJ?E@ zeP>}|0p{~4=COCXm}@h0hg7d^z?M93{*=? zOJ!xH!h{BlK{jc+$;nA{5EMQGfpp1#UNH5rb$oOJfQOI)@0ig?@&xKgcx>X7|169| zNv!0vwY8P8iM<(`#ZO+Lp2nPniU{o^0n=-O13m(2IprVO3&G7ia!Uj#vm^O@{?y_X XeUl8E!hGPEek8gWus%NepLYHN7OGr} literal 0 HcmV?d00001 diff --git a/Marlin/src/lcd/tft/bitmaps/home.bmp b/Marlin/src/lcd/tft/bitmaps/home.bmp new file mode 100644 index 0000000000000000000000000000000000000000..03d3d82a87554c044997ef5b525f4e86801eccbc GIT binary patch literal 12344 zcmeI2OH33=7=UN@!eI}ZJ?#}Pa3V`g2!w>EK_zZPUI$()k3bX@R31T4SHSfVObmiN zM7RhNo>A~3M`FT(1aA;dcpwB8O-K|Fi0&5(n@;sicTZ2x4D3<~Jyq2;e|`Voe^>qW z5AlCQ{O;H-;ao%bi{1PC$?+RChvR4N|N4vg+wI`;=+UFU4{ZVduR~t2{o&O>IF1?q zJ0^;u91}9`7z$AjFvHKJ4Gj%D0)<@+BoDd@(vYn(>kZ(WL+6$&=^LpU=w5LKI)o z0!uym{K6%|!ouR?F(~neEG685&V?X zr%z8!O_>w({mq*<7cX9v-O#2#Gm)>-Gf;a$Z6Kr)&>Oyy?XV^6|mIrFMjr~;NW0FRsuf^ zP9f|hsy}}GcxY%SL9)c@s_8HOZ{NN>e*8EsEiF4cTRE$xq@>WCpPzR{tL?YOPs~pd zF%lIE>yMViT93rP%jM*7t;BB(P!8$5cc^f1_~F5l6bN0#pWG7X>!PBf8#iw7>Kzb% zz~E<1D=aM39__I|ivwfo>gpmRBYE`*c<^4%ZX6%D>u&sG&0DnJ!he{ZRSQd|rltl4 z26DR3$jBf;Ap#QdAQ&?%F4=|oSdenCivUi+qLq&-2?x_ zhYztT>lkYnXV|5srNza?7cX9r$-y_&{2VjUZfgy*(gx~|Do{0!vFd6X9)}y7)d@v>i0pjwY8Pp{@B=b$`$;~%nYbXYD@6*AW)&8pulOWVQXuP7vEFVDX!Jbn69AD&lIfmib%1Qmqa=vZEYm-zjwLQ6{vmLDA* zb>%i%crCxbR1j{{-{0>RyiFH@wANq$8 z#j55jHu5Vfz{!S1HkBMK8NB7?WzL3VENzEpMtk{%3gl;?C0EZc4s2fJkkN>%I&Wj% z!ulg^=NHp)WZ>5j{(Fa98Oc>~g3u?icGpY%)?h4r>p#G6LF)tcmBar3^A5+qc0^VJ literal 0 HcmV?d00001 diff --git a/Marlin/src/lcd/tft/bitmaps/hotend.bmp b/Marlin/src/lcd/tft/bitmaps/hotend.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ed24b6011e70cacc01b06f32b300402f8c3ca9b1 GIT binary patch literal 12410 zcmeI1NlRN%6vxwkihhiKgw{=0RgANy8pYX))i}nfRdFZcfQX2w3#W?1LO~Z!2#Sas zH}2GpSZ728MQne~tuef(&*Z*mjO8A9$;+M2|NQU&o_CUjeRjXMdCbl0SFR8Lt~a)K z++p;8bcjnd*lb~+?5?|ef8XC~27Xtj7*Gr-1{4E|0mXohfge7m>kRbVq)Us8 z>1jtt2O}{;z`VyH_#1&oG=q{;Qc{paPfyRq#f1*Cw&CXHW_)~{)Fh4rA#famuO*=w z{G#^M)YRG8SuIe*&+F^!VPs=3n4HKR*x5y>+9frlukyBFx}# zX=yQ&9!-WaIXS8DEB>Wb^xE|^F)|i8O&GCr(dKQ`D7|l*r-d zcboS1_Or7ylQ5*GFD)%m+{%Hc-k?sPzU8a;=;-LrI~yJzrdE-LWH51VZjNfUyStl5 zu&~a~PU<(g%16wi$iFK*|Gu*$6rT$V3kEQxyFhEV+j&}fJwl)v@cOwdh^?-!N`o|* z*x%nziI|<8?e#0I9PbL68-agiWyJu7beF=fVO#%E@o%6mr60XuG%ZR$#`@v6pv=rn zL7L^slVyX+zrwE(zvACO{B&vZ=WEo@t3JPdeSQ3L$e%bc{~Y8C{ZmnIY-|`SL9TaZ zW`^Qif9Nc10X)WkbNs_)xuJg+w-D`PONnnWaAmFWwdFC7s$DUl7*Gr-1|%4Grf0DP K5;f)jW8e>u78A|@ literal 0 HcmV?d00001 diff --git a/Marlin/src/lcd/tft/bitmaps/increase.bmp b/Marlin/src/lcd/tft/bitmaps/increase.bmp new file mode 100644 index 0000000000000000000000000000000000000000..53d71d0c5afd45c53ab5fe015d3056f24abe1ac6 GIT binary patch literal 12342 zcmeI0yJ`Ya5QfcLR&;iE&VRlg_ss73#mTW{trL76VLScY4lIZG24Vl%rM77S zi{*~R1egF5U;<2l2`~W@5V+qZ6L=&oz$g?H%wI2n1X%*Of?a zw;NM4zkm3=7724Qv;RaQQ7)Hfv)PMC^?Kdubeh?JJRWZ}8gGR9{l3HDFuDI)twz{? z>vTHof3No^)DQFDD`9zZ<}c@?e=nBK2U@uQ<0db^|M>m>WHL$T_}GI{ApLH)GoV7y z-cUksQ>j$s{?Qgiqfsh@7LUbZ+e7P&00{7Uy)B|tX7fdL5ZnNT*HEtktt{#&gU4iKLBJ&1{53K$E8q?7r^>7`QXNveE4-|coO z|Ksr(2S^h<6$%9um~#KOYb_QF%A3MC$fJE#%U|<9pU)Ng6sB6OR^f1%{clu0^A}dj zcJLq6Pbd_^?etIof3Zqpp;x$mY4yKcF1N3^@<=wDh53y?p#Gnj0v-ULr5X;0lgWgd z(R4a(x7)p5Z!{WFX^?`0%m6HCOC&w41=0Kn{%4*fUktbxxli;aU8v`Unxf|8PBhUVl`N7$Gq4cx4y+L!}Zt zFR8Ebckd6}gKxhz%H?vcRx6cCKOwMEsU#AKP$-m2r9h-C1pxE;yv1U%*=&BlA4^bh z6#&m>vrs;t&ovs2-EI#CgT-P|5ef$Ga=EtK?d^7JwOTrz&T6%Sj&2bH_jE%Dp5JArBEoC&1O#d>2zu| z8t|NGOFEs_>-C$>My~vPJ~x|9VnSgoA{vb@mrFS~l*i-oWHL$IN3aEJKO7EnaE!y@ zuvV)@H$$~kC?Fmbv2Xg3gp7)^Py-dMj;odsD8iCQ6LxWd<+BvFp3h4VlWtR6tme3M?)+Yqv&VC z7zH+(oZ@&qqT^wTB3^ozTLr-Xe}wb^eZVM2qtW$xWrwd);w5bWM3=^wA+#$FF0uTQ F!8>#{kj?-A literal 0 HcmV?d00001 diff --git a/Marlin/src/lcd/tft/bitmaps/leveling.bmp b/Marlin/src/lcd/tft/bitmaps/leveling.bmp new file mode 100644 index 0000000000000000000000000000000000000000..34866402701c02c0a73accb772d6d27aba595e2f GIT binary patch literal 3126 zcmeH|Jx`iZ6vye_574n=KY@F@5iBni2u8pV%AmXxh$twvU?ji*CM1RpLc#_EgJA`n zG|>;h;Nn&wG0fOsyyS++^AMZJR8I2f@!WHN_uT(E&*Qi68y__w%XmPWhma3k%n!~hBhGYjK{PZPjV6JcndO6LV`Y7%nd_Y0Y3T*xA|PPtH0%J{G6Qjf~3O-JRWTx7lnm zsOCUUr_-@mOt07X`~CU8hr?l=PPe_ijR=gir~v`<`8;XOW^;3M6B*gQ1n%?stX3;^ z(zbcH@GF&yR;#5QySuxb0w)j%OePbt$`z223o7!_jgp*BCkcyW8R2C?2eaAi_xow+ z&CQKmq9l%kqsRxF%jIP9awi&%?(gplF_B0Z$_UZa_}OfBIaaPxJbZx641NFcV(4bE zSQtw+{@d#>7K_x(mFx97yUxze&d<*ag#vw1yMmZoK6kZRP1d>S+}_?&tbm|@tJRV@ zynXwRMHE4HLQ$_e>WEw7j$sZN~ID_gfoxAr>gmg Zq$xTaF&k*5UvI2ak-QGB75G;L{sIvY2vz_9 literal 0 HcmV?d00001 diff --git a/Marlin/src/lcd/tft/bitmaps/marlin-logo/Marlin-1500x319.png b/Marlin/src/lcd/tft/bitmaps/marlin-logo/Marlin-1500x319.png new file mode 100644 index 0000000000000000000000000000000000000000..d94d3efd2c4ebbcb06c3b3ad5f09e30a0e873268 GIT binary patch literal 387923 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

-0&{SE1&dD0s(jCk)J=t{sisbySlwriS;95A>q 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⪼YIxYN+B8$BT>CrXDag0ye( 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 z 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


!ngOXchG4G?N>;nx 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

H)1@8SFKm0f?4T~aKu3ek} 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

*!-gnMJ0a~ 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

jRpd2Fvnca9TV5|=x$t{0?~V}Q)k^QqCbB; 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 literal 0 HcmV?d00001 diff --git a/Marlin/src/lcd/tft/bitmaps/marlin-logo/Marlin-228x255-greyscale.png b/Marlin/src/lcd/tft/bitmaps/marlin-logo/Marlin-228x255-greyscale.png new file mode 100644 index 0000000000000000000000000000000000000000..f68708a8a2ce949083700dba7a1ac5542712d007 GIT binary patch literal 7940 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 literal 0 HcmV?d00001 diff --git a/Marlin/src/lcd/tft/bitmaps/marlin-logo/Marlin-320x240.png b/Marlin/src/lcd/tft/bitmaps/marlin-logo/Marlin-320x240.png new file mode 100644 index 0000000000000000000000000000000000000000..744ba0e8b3b59e5a79f71146b5a17dbf3edfff57 GIT binary patch literal 97523 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 z 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 literal 0 HcmV?d00001 diff --git a/Marlin/src/lcd/tft/bitmaps/marlin-logo/Marlin-480x319.png b/Marlin/src/lcd/tft/bitmaps/marlin-logo/Marlin-480x319.png new file mode 100644 index 0000000000000000000000000000000000000000..4959ca672279a92827a1e2a6ca7aa50b7e877e2a GIT binary patch literal 168816 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 literal 0 HcmV?d00001 diff --git a/Marlin/src/lcd/tft/bitmaps/pause.bmp b/Marlin/src/lcd/tft/bitmaps/pause.bmp new file mode 100644 index 0000000000000000000000000000000000000000..9c42f006d37ac65fc06040e3ff239ee345338440 GIT binary patch literal 12410 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 Vx})Ugo5+&2$6FR zB8r^Z{g_&p+C4q*^~`%S>%){ZJ=N9KRo`Fw{(jZ(pa1&#r+VMo&#wRQ_sjqOzN`16 zp62-v--o|2P_N!^b*)YVbsDJCKshupdi3bAW5@pft?8Fz$=X;0R1NY`qek`X*ROBi zzOExij2JU!jPcq)P^~>+3kXM!964mjklwv}ckI})RjXG2{?u7u-mn3*SvZ2CQX|B`mMQb)259pE0hucAG)Z}^5{OiMB9*qG;rX+sO=Ul zS~P3c%$2qmEn2i?%a%EF=D3Al>(i%?SMqF8cn$#8apj@_#Ac*`mxibDMX=KT5dA3uKl6ZK#IPn4Jlampp-DIyk&~=lyY|M78*ksfegFRbmoHy*?%cTpk~t94 zQe+IbV28J+O`B$p7qcN28|6aq4zK zyroN*3Rs#?x*c<$V}B}Z2WI@}pG9d+@DVGS=p%V*^8#gY66D=TB>1orZO?mK397m2E zS+;DM1({D$lO}=^DBt>|POxz^jU%g9i^L$CG_?q<)Em z1)Zd%=EjX1H)zm6CRKqb2pHUg7?~qEjUX1`EeP%9%a({Ss@!`V_;fd&g80h{w6mTKp2(c#ELOC>5l2*QX$*!ixqBVJM#m<6e=6}=3R ze3ZX05a>!!m+1TfKWhS`rYZ`+2?d$+e5OxE$Gdm$oVko}c)6qKI?}yGEL9f#7GVO7 z^IX4vJ#%-`$z`I0-^xw9cI^t&o;`b}wwXSCx*!URunyvq&NA0Ac>DHkOpCPy9Y(dg zmU8K;-de#@;JM2F$B!T9C$udVupfBb6>_8`t8Ux2Enrh=&|#!UJ*uUBXC+u z5Ypiv_%%d|ML9s}A`sakmZC-&;ECGC*mA4XV@~{}pz7npCS%}=>LLjBg37g0_}8sl z7goccL~uoAr6+bwpXM8u+L3hHcmhr1j zRl-68wgUbiT+y7_vu9V9=>q<;`@c;K=pU~FFZ2W;wlD0r{D0oOc`3EWTlmG1BD}o( z1HV&A+$GgPKI$L-Pj4cf2r2H0w?ur~}Ijo{ZSQb?)4`O3h66^GU>kF`RH!GC_f20g}){ zUt*#Phn*y5eaCI-PadZw;^)+A{%J69NYtl!Yvsz76)OS9t561n?+lJS$_9dj3@&#| zthgoS>nH-`rtv*<%I-NS87T)I2VsY@2q1JEuapN$i(mzA90Um`^zfP5C+pN(ZuwsQ z`t^m6qh(S0O5v&MEkjTdDKfnX7(Nh6J9uKlt~~JK#fufe8zGbl+z;*N$skq5oSe^# zSUDD)nRpzgKw=9&L-1!`0~jk-N|~=v3t@9+kR+a}_C=p>3x$u9nFtFH5|9Z5etBuX zqIB?AEFcSG%kz|VtX$KxW`7y_t zz>BGxp#4nQg9xt5wupf^l7i|zd{~R)$&S;d*b)25+#%8(YHFHxQi1?4ktqfoihX_Z zQ>hWz3W4w5y*r6H_I;29QWju7q@;vEQ+_j2Ez~mjAPd04Eu1nyg2A|s+EOBmuw%!E z6!gwd!i#45sf*9on%ksI;1&|Q2jt-?ag1bs@L?Al=)5J5<$+W*DLOO&PV^*RmIX`oI6nHu;n3OrP< literal 0 HcmV?d00001 diff --git a/Marlin/src/lcd/tft/bitmaps/up.bmp b/Marlin/src/lcd/tft/bitmaps/up.bmp new file mode 100644 index 0000000000000000000000000000000000000000..94afd1255bea1635e23962c6e3d834156224b38f GIT binary patch literal 3126 zcmeHGyQ*426g7Q5AZ5z5A|9Xk!Z${LAgx-6g^Ggj_(H+bT2WMN6cI!OQ4sMn{0kcu z^e*lW!!YqiuenW#1Lv^MoVC|ld+!;`cj>e2bxC-C!}Imm^GWsv5f=WNf6zl4GTG1P zdUoKS>Oi4TfM0sQ%XqO^yqTEK=R={8$Ky$-(}cfM0*Qe@z~}QJxatl2nM|fut63}- zgTdf(xpKMOJrYQSnM$Q%GMSL*^?JcCBoYSv`~7}0nMjfZu*2cFSuX&|WU^YVUM`nL zqd|#ow>uV#@l}8s7?1;oH6D-Ua=F=Twpy*FQi(?j?MkIm*r6=EA)!zxj7B3Gg^Cy$ za_94z!4S-5GbRC;P%kBd9EI~)h^N!3UayZtB76#J91I2ml1ZRZzt7?-`Fg#E^K3SY zs+oBNu#re4dcEFN3CzOjbRvr^0SrIoa#;W`mrI+?hF`pMra}_^eqYGKEHE{+6jP%^ z3kDps)9J(`7mEcvyhTnbZ&fiGjWik!NkpU3dcA%)9NtULOLV(kJ{|FJIMiyjN~JO! z4j+$4{x6){?RJdgYFk);SU^>DIvt(_F-T(iq&eR)9F5h z93<2zHjDXuu2QLRogZ!sbIt;iz!BZ;cEMl}72SCh8NyiZC{N^+M H&pYq}#5Inx literal 0 HcmV?d00001 diff --git a/Marlin/src/lcd/tft/canvas.cpp b/Marlin/src/lcd/tft/canvas.cpp new file mode 100644 index 000000000000..f6a5046b8d04 --- /dev/null +++ b/Marlin/src/lcd/tft/canvas.cpp @@ -0,0 +1,179 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfig.h" + +#if HAS_GRAPHICAL_TFT + +#include "canvas.h" + +uint16_t CANVAS::width, CANVAS::height; +uint16_t CANVAS::startLine, CANVAS::endLine; +uint16_t *CANVAS::buffer = TFT::buffer; + +void CANVAS::New(uint16_t x, uint16_t y, uint16_t width, uint16_t height) { + CANVAS::width = width; + CANVAS::height = height; + startLine = 0; + endLine = 0; + + tft.set_window(x, y, x + width - 1, y + height - 1); +} + +void CANVAS::Continue() { + startLine = endLine; + endLine = TFT_BUFFER_SIZE < width * (height - startLine) ? startLine + TFT_BUFFER_SIZE / width : height; +} + +bool CANVAS::ToScreen() { + tft.write_sequence(buffer, width * (endLine - startLine)); + return endLine == height; +} + +void CANVAS::SetBackground(uint16_t color) { + /* TODO: test and optimize perfomance */ + /* + uint32_t count = (endLine - startLine) * width; + uint16_t *pixel = buffer; + while (count--) + *pixel++ = color; + */ + const uint32_t two_pixels = (((uint32_t )color) << 16) | color; + uint32_t count = ((endLine - startLine) * width + 1) >> 1; + uint32_t *pointer = (uint32_t *)buffer; + while (count--) *pointer++ = two_pixels; +} + +void CANVAS::AddText(uint16_t x, uint16_t y, uint16_t color, uint8_t *string, uint16_t maxWidth) { + if (endLine < y || startLine > y + GetFontHeight()) return; + + if (maxWidth == 0) maxWidth = width - x; + + uint16_t stringWidth = 0; + for (uint16_t i = 0 ; *(string + i) ; i++) { + glyph_t *glyph = Glyph(string + i); + if (stringWidth + glyph->BBXWidth > maxWidth) break; + AddImage(x + stringWidth + glyph->BBXOffsetX, y + Font()->FontAscent - glyph->BBXHeight - glyph->BBXOffsetY, glyph->BBXWidth, glyph->BBXHeight, GREYSCALE1, ((uint8_t *)glyph) + sizeof(glyph_t), &color); + stringWidth += glyph->DWidth; + } +} + +void CANVAS::AddImage(int16_t x, int16_t y, MarlinImage image, uint16_t *colors) { + uint16_t *data = (uint16_t *)Images[image].data; + if (data == NULL) return; + + uint16_t image_width = Images[image].width, + image_height = Images[image].height; + colorMode_t color_mode = Images[image].colorMode; + + if (color_mode != HIGHCOLOR) + return AddImage(x, y, image_width, image_height, color_mode, (uint8_t *)data, colors); + + // HIGHCOLOR - 16 bits per pixel + + for (int16_t i = 0; i < image_height; i++) { + int16_t line = y + i; + if (line >= startLine && line < endLine) { + uint16_t *pixel = buffer + x + (line - startLine) * width; + for (int16_t j = 0; j < image_width; j++) { + if ((x + j >= 0) && (x + j < width)) *pixel = *data; + pixel++; + data++; + } + } + else + data += image_width; + } +} + +void CANVAS::AddImage(int16_t x, int16_t y, uint8_t image_width, uint8_t image_height, colorMode_t color_mode, uint8_t *data, uint16_t *colors) { + uint8_t bitsPerPixel; + switch (color_mode) { + case GREYSCALE1: bitsPerPixel = 1; break; + case GREYSCALE2: bitsPerPixel = 2; break; + case GREYSCALE4: bitsPerPixel = 4; break; + default: return; + } + + uint8_t mask = 0xFF >> (8 - bitsPerPixel), + pixelsPerByte = 8 / bitsPerPixel; + + colors--; + + for (int16_t i = 0; i < image_height; i++) { + int16_t line = y + i; + if (line >= startLine && line < endLine) { + uint16_t *pixel = buffer + x + (line - startLine) * width; + uint8_t offset = 8 - bitsPerPixel; + for (int16_t j = 0; j < image_width; j++) { + if (offset > 8) { + data++; + offset = 8 - bitsPerPixel; + } + if ((x + j >= 0) && (x + j < width)) { + const uint8_t color = ((*data) >> offset) & mask; + if (color) *pixel = *(colors + color); + } + pixel++; + offset -= bitsPerPixel; + } + data++; + } + else + data += (image_width + pixelsPerByte - 1) / pixelsPerByte; + } +} + +void CANVAS::AddRectangle(uint16_t x, uint16_t y, uint16_t rectangleWidth, uint16_t rectangleHeight, uint16_t color) { + if (endLine < y || startLine > y + rectangleHeight) return; + + for (uint16_t i = 0; i < rectangleHeight; i++) { + uint16_t line = y + i; + if (line >= startLine && line < endLine) { + uint16_t *pixel = buffer + x + (line - startLine) * width; + if (i == 0 || i == rectangleHeight - 1) { + for (uint16_t j = 0; j < rectangleWidth; j++) *pixel++ = color; + } + else { + *pixel = color; + pixel += rectangleWidth - 1; + *pixel = color; + } + } + } +} + +void CANVAS::AddBar(uint16_t x, uint16_t y, uint16_t barWidth, uint16_t barHeight, uint16_t color) { + if (endLine < y || startLine > y + barHeight) return; + + for (uint16_t i = 0; i < barHeight; i++) { + uint16_t line = y + i; + if (line >= startLine && line < endLine) { + uint16_t *pixel = buffer + x + (line - startLine) * width; + for (uint16_t j = 0; j < barWidth; j++) *pixel++ = color; + } + } +} + +CANVAS Canvas; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/canvas.h b/Marlin/src/lcd/tft/canvas.h new file mode 100644 index 000000000000..295ea038e3e8 --- /dev/null +++ b/Marlin/src/lcd/tft/canvas.h @@ -0,0 +1,57 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "tft_color.h" +#include "tft_string.h" +#include "tft_image.h" +#include "tft.h" + +#include "../../inc/MarlinConfig.h" + +class CANVAS { + private: + static uint16_t width, height; + static uint16_t startLine, endLine; + static uint16_t *buffer; + + inline static font_t *Font() { return TFT_String::font(); } + inline static glyph_t *Glyph(uint8_t *character) { return TFT_String::glyph(character); } + inline static uint16_t GetFontHeight() { return TFT_String::font_height(); } + + static void AddImage(int16_t x, int16_t y, uint8_t image_width, uint8_t image_height, colorMode_t color_mode, uint8_t *data, uint16_t *colors); + static void AddImage(uint16_t x, uint16_t y, uint16_t imageWidth, uint16_t imageHeight, uint16_t color, uint16_t bgColor, uint8_t *image); + + public: + static void New(uint16_t x, uint16_t y, uint16_t width, uint16_t height); + static void Continue(); + static bool ToScreen(); + + static void SetBackground(uint16_t color); + static void AddText(uint16_t x, uint16_t y, uint16_t color, uint8_t *string, uint16_t maxWidth); + static void AddImage(int16_t x, int16_t y, MarlinImage image, uint16_t *colors); + + static void AddRectangle(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color); + static void AddBar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color); +}; + +extern CANVAS Canvas; diff --git a/Marlin/src/lcd/tft/fontdata/fontdata_10x20.cpp b/Marlin/src/lcd/tft/fontdata/fontdata_10x20.cpp new file mode 100644 index 000000000000..cc328e885d41 --- /dev/null +++ b/Marlin/src/lcd/tft/fontdata/fontdata_10x20.cpp @@ -0,0 +1,257 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* + Fontname: -Misc-Fixed-Medium-R-Normal--20-200-75-75-C-100-ISO10646-1 + Copyright: Public domain font. Share and enjoy. + Capital A Height: 13, '1' Height: 13 + Calculated Max Values w= 9 h=17 x= 4 y=16 dx=10 dy= 0 ascent=16 len=26 + Font Bounding box w=10 h=20 x= 0 y=-4 + Calculated Min Values x= 0 y=-4 dx= 0 dy= 0 + Pure Font ascent =13 descent=-4 + X Font ascent =13 descent=-4 + Max Font ascent =16 descent=-4 +*/ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +#include + +extern const uint8_t font10x20[3453] = { + 0,10,20,0,252,13,2,74,4,153,32,255,252,16,252,13, + 252,0,0,0,10,0,16,2,13,13,10,4,0,192,192,192, + 192,192,192,192,192,192,192,0,192,192,6,4,4,10,2,9, + 204,204,204,72,9,11,22,10,1,1,27,0,27,0,27,0, + 127,128,54,0,54,0,54,0,255,0,108,0,108,0,108,0, + 8,13,13,10,1,0,24,126,219,216,216,216,126,27,27,27, + 219,126,24,9,12,24,10,1,0,115,0,219,0,222,0,118, + 0,12,0,12,0,24,0,24,0,55,0,61,128,109,128,103, + 0,9,13,26,10,1,0,56,0,108,0,108,0,108,0,120, + 0,48,0,112,0,216,0,205,128,199,0,198,0,239,0,121, + 128,2,5,5,10,4,8,192,192,192,192,128,5,13,13,10, + 3,0,24,48,96,96,192,192,192,192,192,96,96,48,24,5, + 13,13,10,2,0,192,96,48,48,24,24,24,24,24,48,48, + 96,192,8,7,7,10,1,3,102,102,60,255,60,102,102,8, + 7,7,10,1,3,24,24,24,255,24,24,24,4,3,3,10, + 3,255,112,112,224,8,1,1,10,1,6,255,3,3,3,10, + 4,0,224,224,224,7,12,12,10,2,0,6,6,12,12,24, + 24,48,48,96,96,192,192,8,13,13,10,1,0,24,60,102, + 102,195,195,195,195,195,102,102,60,24,8,13,13,10,1,0, + 24,56,120,216,24,24,24,24,24,24,24,24,255,8,13,13, + 10,1,0,60,102,195,195,3,3,6,28,48,96,192,192,255, + 8,13,13,10,1,0,60,102,195,195,3,6,28,6,3,195, + 195,102,60,8,13,13,10,1,0,2,6,14,30,54,102,198, + 198,255,6,6,6,6,8,13,13,10,1,0,255,192,192,192, + 192,220,230,3,3,3,195,102,60,8,13,13,10,1,0,60, + 102,194,192,192,220,230,195,195,195,195,102,60,8,13,13,10, + 1,0,255,3,3,6,6,12,12,24,24,48,48,96,96,8, + 13,13,10,1,0,60,102,195,195,195,102,60,102,195,195,195, + 102,60,8,13,13,10,1,0,60,102,195,195,195,195,103,59, + 3,3,67,102,60,3,8,8,10,4,0,224,224,0,0,0, + 0,224,224,4,9,9,10,3,255,112,112,0,0,0,0,112, + 112,224,7,13,13,10,1,0,2,6,12,24,48,96,192,96, + 48,24,12,6,2,8,6,6,10,1,3,255,0,0,0,0, + 255,7,13,13,10,2,0,128,192,96,48,24,12,6,12,24, + 48,96,192,128,8,13,13,10,1,0,60,102,195,195,195,6, + 12,24,24,24,0,24,24,8,13,13,10,1,0,60,102,195, + 207,223,219,219,219,222,204,192,99,62,8,13,13,10,1,0, + 24,60,102,102,195,195,195,255,195,195,195,195,195,8,13,13, + 10,1,0,248,204,198,198,198,204,252,198,195,195,195,198,252, + 8,13,13,10,1,0,60,102,195,192,192,192,192,192,192,192, + 195,102,60,8,13,13,10,1,0,252,198,195,195,195,195,195, + 195,195,195,195,198,252,8,13,13,10,1,0,255,192,192,192, + 192,192,252,192,192,192,192,192,255,8,13,13,10,1,0,255, + 192,192,192,192,192,252,192,192,192,192,192,192,8,13,13,10, + 1,0,60,102,195,192,192,192,207,195,195,195,195,103,61,8, + 13,13,10,1,0,195,195,195,195,195,195,255,195,195,195,195, + 195,195,8,13,13,10,1,0,255,24,24,24,24,24,24,24, + 24,24,24,24,255,9,13,26,10,1,0,31,128,6,0,6, + 0,6,0,6,0,6,0,6,0,6,0,6,0,198,0,198, + 0,108,0,56,0,8,13,13,10,1,0,195,195,198,198,204, + 204,248,204,204,198,198,195,195,8,13,13,10,1,0,192,192, + 192,192,192,192,192,192,192,192,192,192,255,8,13,13,10,1, + 0,195,195,231,231,255,219,219,219,219,195,195,195,195,8,13, + 13,10,1,0,195,227,227,243,243,219,219,207,207,199,199,195, + 195,8,13,13,10,1,0,60,102,195,195,195,195,195,195,195, + 195,195,102,60,8,13,13,10,1,0,252,198,195,195,195,195, + 198,252,192,192,192,192,192,8,14,14,10,1,255,60,102,195, + 195,195,195,195,195,195,219,207,102,62,3,8,13,13,10,1, + 0,252,198,195,195,195,195,198,252,204,198,198,195,195,8,13, + 13,10,1,0,60,102,195,192,192,96,60,6,3,3,195,102, + 60,8,13,13,10,1,0,255,24,24,24,24,24,24,24,24, + 24,24,24,24,8,13,13,10,1,0,195,195,195,195,195,195, + 195,195,195,195,195,102,60,8,13,13,10,1,0,195,195,195, + 195,102,102,102,60,60,60,24,24,24,8,13,13,10,1,0, + 195,195,195,195,195,219,219,219,219,231,231,195,195,8,13,13, + 10,1,0,195,195,102,102,60,60,24,60,60,102,102,195,195, + 8,13,13,10,1,0,195,195,102,102,60,60,24,24,24,24, + 24,24,24,8,13,13,10,1,0,255,3,3,6,12,12,24, + 48,48,96,192,192,255,6,13,13,10,2,0,252,192,192,192, + 192,192,192,192,192,192,192,192,252,7,12,12,10,2,0,192, + 192,96,96,48,48,24,24,12,12,6,6,6,13,13,10,2, + 0,252,12,12,12,12,12,12,12,12,12,12,12,252,8,4, + 4,10,1,9,24,60,102,195,9,1,2,10,1,255,255,128, + 4,3,3,10,3,10,192,96,48,8,8,8,10,1,0,62, + 99,3,127,195,195,195,125,8,13,13,10,1,0,192,192,192, + 192,192,220,230,195,195,195,195,230,220,8,8,8,10,1,0, + 62,99,192,192,192,192,99,62,8,13,13,10,1,0,3,3, + 3,3,3,59,103,195,195,195,195,103,59,8,8,8,10,1, + 0,60,102,195,255,192,192,99,62,8,13,13,10,1,0,30, + 51,51,48,48,252,48,48,48,48,48,48,48,8,12,12,10, + 1,252,125,199,198,198,198,124,192,126,195,195,195,126,8,13, + 13,10,1,0,192,192,192,192,192,220,230,195,195,195,195,195, + 195,8,11,11,10,1,0,24,24,0,120,24,24,24,24,24, + 24,255,7,15,15,10,2,252,6,6,0,30,6,6,6,6, + 6,6,6,198,198,198,124,8,13,13,10,1,0,192,192,192, + 192,192,198,204,216,240,248,204,198,195,8,13,13,10,1,0, + 120,24,24,24,24,24,24,24,24,24,24,24,255,8,8,8, + 10,1,0,182,255,219,219,219,219,219,219,8,8,8,10,1, + 0,220,230,195,195,195,195,195,195,8,8,8,10,1,0,60, + 102,195,195,195,195,102,60,8,12,12,10,1,252,220,230,195, + 195,195,195,230,220,192,192,192,192,8,12,12,10,1,252,59, + 103,195,195,195,195,103,59,3,3,3,3,8,8,8,10,1, + 0,222,115,96,96,96,96,96,96,8,8,8,10,1,0,126, + 195,192,126,3,3,195,126,8,11,11,10,1,0,48,48,48, + 252,48,48,48,48,48,51,30,8,8,8,10,1,0,195,195, + 195,195,195,195,103,59,8,8,8,10,1,0,195,195,102,102, + 60,60,24,24,8,8,8,10,1,0,195,195,195,219,219,219, + 255,102,8,8,8,10,1,0,195,102,60,24,24,60,102,195, + 8,12,12,10,1,252,195,195,195,195,195,195,103,59,3,195, + 102,60,7,8,8,10,2,0,254,6,12,24,48,96,192,254, + 8,13,13,10,1,0,15,24,24,24,24,24,240,24,24,24, + 24,24,15,2,13,13,10,4,0,192,192,192,192,192,192,192, + 192,192,192,192,192,192,8,13,13,10,1,0,240,24,24,24, + 24,24,15,24,24,24,24,24,240,8,3,3,10,1,10,115, + 219,206,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,10,0,16,2,13,13,10,4,0,192, + 192,0,192,192,192,192,192,192,192,192,192,192,7,12,12,10, + 1,0,24,24,60,102,194,192,192,194,102,60,24,24,9,12, + 24,10,1,0,30,0,51,0,51,0,48,0,48,0,252,0, + 48,0,48,0,48,0,248,0,173,128,231,0,9,9,18,10, + 0,1,128,128,221,128,127,0,99,0,99,0,99,0,127,0, + 221,128,128,128,8,11,11,10,1,0,129,195,102,60,126,24, + 126,24,24,24,24,2,13,13,10,4,0,192,192,192,192,192, + 0,0,0,192,192,192,192,192,8,13,13,10,1,0,60,102, + 198,96,120,204,102,51,30,6,99,102,60,6,2,2,10,2, + 11,204,204,8,11,11,10,1,0,60,102,195,189,165,161,165, + 189,195,102,60,8,9,9,10,1,4,62,67,3,127,195,195, + 125,0,255,9,11,22,10,0,0,4,128,13,128,27,0,54, + 0,108,0,216,0,108,0,54,0,27,0,13,128,4,128,8, + 4,4,10,1,4,255,255,3,3,6,1,1,10,2,6,252, + 8,11,11,10,1,0,60,102,195,189,165,189,169,173,195,102, + 60,8,1,1,10,1,13,255,6,6,6,10,2,7,48,120, + 204,204,120,48,8,7,7,10,1,2,24,24,255,24,24,0, + 255,5,7,7,10,2,6,112,216,24,48,96,192,248,5,7, + 7,10,2,6,112,216,24,48,24,216,112,4,3,3,10,3, + 10,48,96,192,7,10,10,10,1,253,198,198,198,198,198,238, + 250,192,192,192,8,13,13,10,1,0,127,255,251,251,251,123, + 27,27,27,27,27,27,27,3,3,3,10,4,5,224,224,224, + 5,4,4,10,2,252,48,24,216,112,4,7,7,10,2,6, + 96,224,96,96,96,96,240,7,9,9,10,1,4,56,108,198, + 198,198,108,56,0,254,9,11,22,10,1,0,144,0,216,0, + 108,0,54,0,27,0,13,128,27,0,54,0,108,0,216,0, + 144,0,8,12,12,10,1,1,64,192,65,66,228,8,18,38, + 74,158,2,2,8,12,12,10,1,1,64,192,65,66,228,8, + 22,41,65,130,4,15,8,12,12,10,1,1,224,16,97,18, + 228,8,18,38,74,159,2,2,8,13,13,10,1,0,24,24, + 0,24,24,24,48,96,195,195,195,102,60,8,15,15,10,1, + 0,96,48,24,0,24,60,102,195,195,195,255,195,195,195,195, + 8,15,15,10,1,0,6,12,24,0,24,60,102,195,195,195, + 255,195,195,195,195,8,15,15,10,1,0,24,60,102,0,24, + 60,102,195,195,195,255,195,195,195,195,8,15,15,10,1,0, + 50,126,76,0,24,60,102,195,195,195,255,195,195,195,195,8, + 15,15,10,1,0,102,102,0,24,60,102,102,195,195,195,255, + 195,195,195,195,8,16,16,10,1,0,60,102,102,60,0,24, + 60,102,195,195,195,255,195,195,195,195,8,13,13,10,1,0, + 31,60,108,108,204,204,255,204,204,204,204,204,207,8,17,17, + 10,1,252,60,102,195,192,192,192,192,192,192,192,195,102,60, + 24,12,108,56,8,15,15,10,1,0,96,48,24,0,255,192, + 192,192,192,252,192,192,192,192,255,8,15,15,10,1,0,12, + 24,48,0,255,192,192,192,192,252,192,192,192,192,255,8,15, + 15,10,1,0,24,60,102,0,255,192,192,192,192,252,192,192, + 192,192,255,8,15,15,10,1,0,102,102,0,0,255,192,192, + 192,192,252,192,192,192,192,255,6,15,15,10,2,0,96,48, + 24,0,252,48,48,48,48,48,48,48,48,48,252,6,15,15, + 10,2,0,24,48,96,0,252,48,48,48,48,48,48,48,48, + 48,252,6,15,15,10,2,0,48,120,204,0,252,48,48,48, + 48,48,48,48,48,48,252,6,15,15,10,2,0,204,204,0, + 252,48,48,48,48,48,48,48,48,48,48,252,9,13,26,10, + 0,0,126,0,99,0,97,128,97,128,97,128,97,128,249,128, + 97,128,97,128,97,128,97,128,99,0,126,0,8,15,15,10, + 1,0,50,126,76,0,195,227,243,243,219,219,207,207,199,195, + 195,8,15,15,10,1,0,48,24,12,0,60,102,195,195,195, + 195,195,195,195,102,60,8,15,15,10,1,0,12,24,48,0, + 60,102,195,195,195,195,195,195,195,102,60,8,15,15,10,1, + 0,24,60,102,0,60,102,195,195,195,195,195,195,195,102,60, + 8,15,15,10,1,0,50,126,76,0,60,102,195,195,195,195, + 195,195,195,102,60,8,15,15,10,1,0,102,102,0,60,102, + 195,195,195,195,195,195,195,195,102,60,7,8,8,10,1,0, + 130,198,108,56,56,108,198,130,8,15,15,10,1,255,1,62, + 102,199,199,203,203,203,211,211,211,227,102,124,128,8,15,15, + 10,1,0,48,24,12,0,195,195,195,195,195,195,195,195,195, + 102,60,8,15,15,10,1,0,12,24,48,0,195,195,195,195, + 195,195,195,195,195,102,60,8,15,15,10,1,0,24,60,102, + 0,195,195,195,195,195,195,195,195,195,102,60,8,15,15,10, + 1,0,102,102,0,195,195,195,195,195,195,195,195,195,195,102, + 60,8,15,15,10,1,0,12,24,48,0,195,195,102,102,60, + 60,24,24,24,24,24,7,13,13,10,2,0,192,192,192,252, + 198,198,198,198,198,252,192,192,192,8,13,13,10,1,0,28, + 54,99,99,102,236,108,102,99,99,99,102,108,8,12,12,10, + 1,0,48,24,12,0,126,195,3,127,195,195,195,125,8,12, + 12,10,1,0,12,24,48,0,126,195,3,127,195,195,195,125, + 8,12,12,10,1,0,24,60,102,0,126,195,3,127,195,195, + 195,125,8,12,12,10,1,0,50,126,76,0,126,195,3,127, + 195,195,195,125,8,11,11,10,1,0,102,102,0,126,195,3, + 127,195,195,195,125,8,13,13,10,1,0,60,102,102,60,0, + 126,195,3,127,195,195,195,125,8,8,8,10,1,0,118,155, + 27,30,120,216,217,110,8,12,12,10,1,252,62,99,192,192, + 192,192,99,62,24,12,108,56,8,12,12,10,1,0,96,48, + 24,0,60,102,195,255,192,192,99,62,8,12,12,10,1,0, + 6,12,24,0,60,102,195,255,192,192,99,62,8,12,12,10, + 1,0,24,60,102,0,60,102,195,255,192,192,99,62,8,11, + 11,10,1,0,102,102,0,60,102,195,255,192,192,99,62,8, + 12,12,10,1,0,96,48,24,0,120,24,24,24,24,24,24, + 255,8,12,12,10,1,0,12,24,48,0,120,24,24,24,24, + 24,24,255,8,12,12,10,1,0,24,60,102,0,120,24,24, + 24,24,24,24,255,8,11,11,10,1,0,102,102,0,120,24, + 24,24,24,24,24,255,8,13,13,10,1,0,136,216,112,112, + 216,140,62,103,195,195,195,102,60,8,12,12,10,1,0,50, + 126,76,0,220,230,195,195,195,195,195,195,8,12,12,10,1, + 0,96,48,24,0,60,102,195,195,195,195,102,60,8,12,12, + 10,1,0,6,12,24,0,60,102,195,195,195,195,102,60,8, + 12,12,10,1,0,24,60,102,0,60,102,195,195,195,195,102, + 60,8,12,12,10,1,0,50,126,76,0,60,102,195,195,195, + 195,102,60,8,11,11,10,1,0,102,102,0,60,102,195,195, + 195,195,102,60,8,10,10,10,1,1,24,24,0,0,255,255, + 0,0,24,24,8,10,10,10,1,255,1,62,102,203,203,211, + 211,102,124,128,8,12,12,10,1,0,48,24,12,0,195,195, + 195,195,195,195,103,59,8,12,12,10,1,0,6,12,24,0, + 195,195,195,195,195,195,103,59,8,12,12,10,1,0,24,60, + 102,0,195,195,195,195,195,195,103,59,8,11,11,10,1,0, + 102,102,0,195,195,195,195,195,195,103,59,8,16,16,10,1, + 252,12,24,48,0,195,195,195,195,195,195,103,59,3,195,102, + 60,7,17,17,10,2,252,192,192,192,192,192,192,248,204,198, + 198,198,204,248,192,192,192,192,8,15,15,10,1,252,102,102, + 0,195,195,195,195,195,195,103,59,3,195,102,60 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/fontdata/fontdata_ISO10646_1.cpp b/Marlin/src/lcd/tft/fontdata/fontdata_ISO10646_1.cpp new file mode 100644 index 000000000000..ade8bf23b8e4 --- /dev/null +++ b/Marlin/src/lcd/tft/fontdata/fontdata_ISO10646_1.cpp @@ -0,0 +1,314 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +#include + +#define STM32_NOT_EXTENDED_ISO10646_1_5X7 + +#if ENABLED(STM32_NOT_EXTENDED_ISO10646_1_5X7) + // reduced font (only symbols 1 - 127) - saves about 1278 bytes of FLASH + +/* + Fontname: -Marlin6x12-Fixed-Medium-R-SemiCondensed--12-90-100-100-C-111-ISO10646-1 + Copyright: Public domain terminal emulator font. Share and enjoy. original font -Misc-Fixed-Medium-R-SemiCondensed--12-110-75-75-C-60-ISO10646-1 + Capital A Height: 7, '1' Height: 7 + Calculated Max Values w= 5 h=10 x= 5 y= 5 dx= 6 dy= 0 ascent= 8 len=10 + Font Bounding box w=12 h=13 x= 0 y=-2 + Calculated Min Values x= 0 y=-2 dx= 0 dy= 0 + Pure Font ascent = 7 descent=-2 + X Font ascent = 8 descent=-2 + Max Font ascent = 8 descent=-2 +*/ +extern const uint8_t ISO10646_1_5x7[1325] = { + 0x00,0x0C,0x0D,0x00,0xFE,0x07,0x02,0x26,0x03,0xBC,0x01,0x7F,0xFE,0x0A,0xFE,0x08, + 0xFE,0x05,0x08,0x08,0x06,0x00,0x00,0x40,0xF0,0xC8,0x88,0x88,0x98,0x78,0x10,0x05, + 0x08,0x08,0x06,0x00,0x00,0xC0,0xF8,0x88,0x88,0x88,0x88,0x88,0xF8,0x05,0x05,0x05, + 0x06,0x00,0x01,0x20,0x30,0xF8,0x30,0x20,0x05,0x08,0x08,0x06,0x00,0x00,0x20,0x70, + 0xF8,0x20,0x20,0x20,0x20,0xE0,0x05,0x09,0x09,0x06,0x00,0xFF,0x20,0x70,0xA8,0xA8, + 0xB8,0x88,0x88,0x70,0x20,0x07,0x06,0x06,0x08,0x00,0x01,0xE0,0x8C,0xEA,0x8C,0x8A, + 0x0A,0x05,0x09,0x09,0x06,0x00,0xFF,0xF8,0xA8,0x88,0x88,0x88,0x88,0x88,0xA8,0xF8, + 0x05,0x0A,0x0A,0x06,0x00,0xFE,0x20,0x50,0x50,0x50,0x50,0x88,0xA8,0xA8,0x88,0x70, + 0x03,0x03,0x03,0x06,0x00,0x06,0x40,0xA0,0x40,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, + 0x00,0x00,0x06,0x05,0xFF,0x01,0x07,0x07,0x06,0x02,0x00,0x80,0x80,0x80,0x80,0x80, + 0x00,0x80,0x03,0x03,0x03,0x06,0x01,0x05,0xA0,0xA0,0xA0,0x05,0x06,0x06,0x06,0x00, + 0x00,0x50,0xF8,0x50,0x50,0xF8,0x50,0x05,0x09,0x09,0x06,0x00,0xFF,0x20,0x70,0xA8, + 0xA0,0x70,0x28,0xA8,0x70,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0xC8,0xC8,0x10,0x20, + 0x40,0x98,0x98,0x05,0x07,0x07,0x06,0x00,0x00,0x40,0xA0,0xA0,0x40,0xA8,0x90,0x68, + 0x01,0x03,0x03,0x06,0x02,0x05,0x80,0x80,0x80,0x03,0x09,0x09,0x06,0x01,0xFF,0x20, + 0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x20,0x03,0x09,0x09,0x06,0x01,0xFF,0x80,0x40, + 0x40,0x20,0x20,0x20,0x40,0x40,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0xA8,0x70, + 0x20,0x70,0xA8,0x20,0x05,0x05,0x05,0x06,0x00,0x01,0x20,0x20,0xF8,0x20,0x20,0x02, + 0x03,0x03,0x06,0x01,0xFF,0xC0,0x40,0x80,0x05,0x01,0x01,0x06,0x00,0x03,0xF8,0x02, + 0x02,0x02,0x06,0x01,0x00,0xC0,0xC0,0x05,0x07,0x07,0x06,0x00,0x00,0x08,0x10,0x10, + 0x20,0x40,0x40,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x98,0xA8,0xC8,0x88, + 0x70,0x03,0x07,0x07,0x06,0x01,0x00,0x40,0xC0,0x40,0x40,0x40,0x40,0xE0,0x05,0x07, + 0x07,0x06,0x00,0x00,0x70,0x88,0x08,0x10,0x20,0x40,0xF8,0x05,0x07,0x07,0x06,0x00, + 0x00,0xF8,0x08,0x10,0x30,0x08,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x10,0x30, + 0x50,0x90,0xF8,0x10,0x10,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x80,0xF0,0x08,0x08, + 0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x30,0x40,0x80,0xF0,0x88,0x88,0x70,0x05, + 0x07,0x07,0x06,0x00,0x00,0xF8,0x08,0x10,0x10,0x20,0x20,0x20,0x05,0x07,0x07,0x06, + 0x00,0x00,0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x70, + 0x88,0x88,0x78,0x08,0x10,0x60,0x02,0x05,0x05,0x06,0x01,0x00,0xC0,0xC0,0x00,0xC0, + 0xC0,0x02,0x06,0x06,0x06,0x01,0xFF,0xC0,0xC0,0x00,0xC0,0x40,0x80,0x03,0x05,0x05, + 0x06,0x01,0x01,0x20,0x40,0x80,0x40,0x20,0x05,0x03,0x03,0x06,0x00,0x02,0xF8,0x00, + 0xF8,0x03,0x05,0x05,0x06,0x01,0x01,0x80,0x40,0x20,0x40,0x80,0x05,0x07,0x07,0x06, + 0x00,0x00,0x70,0x88,0x10,0x20,0x20,0x00,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x70, + 0x88,0xB8,0xA8,0xB8,0x80,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0xF8, + 0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0xF0,0x48,0x48,0x70,0x48,0x48,0xF0, + 0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x05,0x07,0x07, + 0x06,0x00,0x00,0xF0,0x48,0x48,0x48,0x48,0x48,0xF0,0x05,0x07,0x07,0x06,0x00,0x00, + 0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x80,0x80, + 0xF0,0x80,0x80,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x80,0x80,0x98,0x88, + 0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x03,0x07, + 0x07,0x06,0x01,0x00,0xE0,0x40,0x40,0x40,0x40,0x40,0xE0,0x05,0x07,0x07,0x06,0x00, + 0x00,0x38,0x10,0x10,0x10,0x10,0x90,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x90, + 0xA0,0xC0,0xA0,0x90,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x80,0x80,0x80,0x80, + 0x80,0xF8,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0xD8,0xA8,0x88,0x88,0x88,0x88,0x05, + 0x07,0x07,0x06,0x00,0x00,0x88,0x88,0xC8,0xA8,0x98,0x88,0x88,0x05,0x07,0x07,0x06, + 0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0xF0, + 0x88,0x88,0xF0,0x80,0x80,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0x88, + 0xA8,0x90,0x68,0x05,0x07,0x07,0x06,0x00,0x00,0xF0,0x88,0x88,0xF0,0xA0,0x90,0x88, + 0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x05,0x07,0x07, + 0x06,0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0x00, + 0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88, + 0x88,0x50,0x50,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0x88,0xA8,0xA8, + 0x50,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x05,0x07, + 0x07,0x06,0x00,0x00,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00, + 0x00,0xF8,0x08,0x10,0x20,0x40,0x80,0xF8,0x03,0x09,0x09,0x06,0x01,0xFF,0xE0,0x80, + 0x80,0x80,0x80,0x80,0x80,0x80,0xE0,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x40,0x40, + 0x20,0x10,0x10,0x08,0x03,0x09,0x09,0x06,0x01,0xFF,0xE0,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0xE0,0x05,0x03,0x03,0x06,0x00,0x05,0x20,0x50,0x88,0x05,0x01,0x01,0x06, + 0x00,0xFE,0xF8,0x03,0x03,0x03,0x06,0x01,0x05,0x80,0x40,0x20,0x05,0x05,0x05,0x06, + 0x00,0x00,0x70,0x08,0x78,0x88,0x78,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x80,0xF0, + 0x88,0x88,0x88,0xF0,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x80,0x80,0x88,0x70,0x05, + 0x07,0x07,0x06,0x00,0x00,0x08,0x08,0x78,0x88,0x88,0x88,0x78,0x05,0x05,0x05,0x06, + 0x00,0x00,0x70,0x88,0xF0,0x80,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x30,0x48,0x40, + 0xE0,0x40,0x40,0x40,0x05,0x07,0x07,0x06,0x00,0xFE,0x70,0x88,0x88,0x88,0x78,0x08, + 0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x88,0x03,0x07, + 0x07,0x06,0x01,0x00,0x40,0x00,0xC0,0x40,0x40,0x40,0xE0,0x04,0x09,0x09,0x06,0x01, + 0xFE,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x90,0x60,0x05,0x07,0x07,0x06,0x00,0x00, + 0x80,0x80,0x88,0x90,0xE0,0x90,0x88,0x03,0x07,0x07,0x06,0x01,0x00,0xC0,0x40,0x40, + 0x40,0x40,0x40,0xE0,0x05,0x05,0x05,0x06,0x00,0x00,0xD0,0xA8,0xA8,0xA8,0xA8,0x05, + 0x05,0x05,0x06,0x00,0x00,0xB0,0xC8,0x88,0x88,0x88,0x05,0x05,0x05,0x06,0x00,0x00, + 0x70,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0xFE,0xF0,0x88,0x88,0x88,0xF0, + 0x80,0x80,0x05,0x07,0x07,0x06,0x00,0xFE,0x78,0x88,0x88,0x88,0x78,0x08,0x08,0x05, + 0x05,0x05,0x06,0x00,0x00,0xB0,0xC8,0x80,0x80,0x80,0x05,0x05,0x05,0x06,0x00,0x00, + 0x78,0x80,0x70,0x08,0xF0,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x20,0xF8,0x20,0x20, + 0x20,0x18,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x88,0x88,0x98,0x68,0x05,0x05,0x05, + 0x06,0x00,0x00,0x88,0x88,0x88,0x50,0x20,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x88, + 0xA8,0xA8,0x50,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x05,0x07, + 0x07,0x06,0x00,0xFE,0x88,0x88,0x88,0x50,0x20,0x40,0x80,0x05,0x05,0x05,0x06,0x00, + 0x00,0xF8,0x10,0x20,0x40,0xF8,0x03,0x09,0x09,0x06,0x01,0xFF,0x20,0x40,0x40,0x40, + 0x80,0x40,0x40,0x40,0x20,0x01,0x09,0x09,0x06,0x02,0xFF,0x80,0x80,0x80,0x80,0x80, + 0x80,0x80,0x80,0x80,0x03,0x09,0x09,0x06,0x01,0xFF,0x80,0x40,0x40,0x40,0x20,0x40, + 0x40,0x40,0x80,0x05,0x03,0x03,0x06,0x00,0x02,0x48,0xA8,0x90,0xFF +}; + +#else // !STM32_NOT_EXTENDED_ISO10646_1_5X7 + + // extended (original) font (symbols 1 - 255) + +/* + Fontname: -Marlin6x12-Fixed-Medium-R-SemiCondensed--12-90-100-100-C-111-ISO10646-1 + Copyright: Public domain terminal emulator font. Share and enjoy. original font -Misc-Fixed-Medium-R-SemiCondensed--12-110-75-75-C-60-ISO10646-1 + Capital A Height: 7, '1' Height: 7 + Calculated Max Values w= 6 h=10 x= 5 y= 7 dx= 6 dy= 0 ascent=10 len=10 + Font Bounding box w=12 h=13 x= 0 y=-2 + Calculated Min Values x= 0 y=-2 dx= 0 dy= 0 + Pure Font ascent = 7 descent=-2 + X Font ascent = 8 descent=-2 + Max Font ascent =10 descent=-2 +*/ +extern const uint8_t ISO10646_1_5x7[2648] = { + 0x00,0x0C,0x0D,0x00,0xFE,0x07,0x02,0x26,0x03,0xBC,0x01,0xFF,0xFE,0x0A,0xFE,0x08, + 0xFE,0x05,0x08,0x08,0x06,0x00,0x00,0x40,0xF0,0xC8,0x88,0x88,0x98,0x78,0x10,0x05, + 0x08,0x08,0x06,0x00,0x00,0xC0,0xF8,0x88,0x88,0x88,0x88,0x88,0xF8,0x05,0x05,0x05, + 0x06,0x00,0x01,0x20,0x30,0xF8,0x30,0x20,0x05,0x08,0x08,0x06,0x00,0x00,0x20,0x70, + 0xF8,0x20,0x20,0x20,0x20,0xE0,0x05,0x09,0x09,0x06,0x00,0xFF,0x20,0x70,0xA8,0xA8, + 0xB8,0x88,0x88,0x70,0x20,0x07,0x06,0x06,0x08,0x00,0x01,0xE0,0x8C,0xEA,0x8C,0x8A, + 0x0A,0x05,0x09,0x09,0x06,0x00,0xFF,0xF8,0xA8,0x88,0x88,0x88,0x88,0x88,0xA8,0xF8, + 0x05,0x0A,0x0A,0x06,0x00,0xFE,0x20,0x50,0x50,0x50,0x50,0x88,0xA8,0xA8,0x88,0x70, + 0x03,0x03,0x03,0x06,0x00,0x06,0x40,0xA0,0x40,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, + 0x00,0x00,0x06,0x05,0xFF,0x01,0x07,0x07,0x06,0x02,0x00,0x80,0x80,0x80,0x80,0x80, + 0x00,0x80,0x03,0x03,0x03,0x06,0x01,0x05,0xA0,0xA0,0xA0,0x05,0x06,0x06,0x06,0x00, + 0x00,0x50,0xF8,0x50,0x50,0xF8,0x50,0x05,0x09,0x09,0x06,0x00,0xFF,0x20,0x70,0xA8, + 0xA0,0x70,0x28,0xA8,0x70,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0xC8,0xC8,0x10,0x20, + 0x40,0x98,0x98,0x05,0x07,0x07,0x06,0x00,0x00,0x40,0xA0,0xA0,0x40,0xA8,0x90,0x68, + 0x01,0x03,0x03,0x06,0x02,0x05,0x80,0x80,0x80,0x03,0x09,0x09,0x06,0x01,0xFF,0x20, + 0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x20,0x03,0x09,0x09,0x06,0x01,0xFF,0x80,0x40, + 0x40,0x20,0x20,0x20,0x40,0x40,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0xA8,0x70, + 0x20,0x70,0xA8,0x20,0x05,0x05,0x05,0x06,0x00,0x01,0x20,0x20,0xF8,0x20,0x20,0x02, + 0x03,0x03,0x06,0x01,0xFF,0xC0,0x40,0x80,0x05,0x01,0x01,0x06,0x00,0x03,0xF8,0x02, + 0x02,0x02,0x06,0x01,0x00,0xC0,0xC0,0x05,0x07,0x07,0x06,0x00,0x00,0x08,0x10,0x10, + 0x20,0x40,0x40,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x98,0xA8,0xC8,0x88, + 0x70,0x03,0x07,0x07,0x06,0x01,0x00,0x40,0xC0,0x40,0x40,0x40,0x40,0xE0,0x05,0x07, + 0x07,0x06,0x00,0x00,0x70,0x88,0x08,0x10,0x20,0x40,0xF8,0x05,0x07,0x07,0x06,0x00, + 0x00,0xF8,0x08,0x10,0x30,0x08,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x10,0x30, + 0x50,0x90,0xF8,0x10,0x10,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x80,0xF0,0x08,0x08, + 0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x30,0x40,0x80,0xF0,0x88,0x88,0x70,0x05, + 0x07,0x07,0x06,0x00,0x00,0xF8,0x08,0x10,0x10,0x20,0x20,0x20,0x05,0x07,0x07,0x06, + 0x00,0x00,0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x70, + 0x88,0x88,0x78,0x08,0x10,0x60,0x02,0x05,0x05,0x06,0x01,0x00,0xC0,0xC0,0x00,0xC0, + 0xC0,0x02,0x06,0x06,0x06,0x01,0xFF,0xC0,0xC0,0x00,0xC0,0x40,0x80,0x03,0x05,0x05, + 0x06,0x01,0x01,0x20,0x40,0x80,0x40,0x20,0x05,0x03,0x03,0x06,0x00,0x02,0xF8,0x00, + 0xF8,0x03,0x05,0x05,0x06,0x01,0x01,0x80,0x40,0x20,0x40,0x80,0x05,0x07,0x07,0x06, + 0x00,0x00,0x70,0x88,0x10,0x20,0x20,0x00,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x70, + 0x88,0xB8,0xA8,0xB8,0x80,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0xF8, + 0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0xF0,0x48,0x48,0x70,0x48,0x48,0xF0, + 0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x05,0x07,0x07, + 0x06,0x00,0x00,0xF0,0x48,0x48,0x48,0x48,0x48,0xF0,0x05,0x07,0x07,0x06,0x00,0x00, + 0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x05,0x07,0x07,0x06,0x00,0x00,0xF8,0x80,0x80, + 0xF0,0x80,0x80,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x80,0x80,0x98,0x88, + 0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x03,0x07, + 0x07,0x06,0x01,0x00,0xE0,0x40,0x40,0x40,0x40,0x40,0xE0,0x05,0x07,0x07,0x06,0x00, + 0x00,0x38,0x10,0x10,0x10,0x10,0x90,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x90, + 0xA0,0xC0,0xA0,0x90,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x80,0x80,0x80,0x80, + 0x80,0xF8,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0xD8,0xA8,0x88,0x88,0x88,0x88,0x05, + 0x07,0x07,0x06,0x00,0x00,0x88,0x88,0xC8,0xA8,0x98,0x88,0x88,0x05,0x07,0x07,0x06, + 0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0xF0, + 0x88,0x88,0xF0,0x80,0x80,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x88,0x88, + 0xA8,0x90,0x68,0x05,0x07,0x07,0x06,0x00,0x00,0xF0,0x88,0x88,0xF0,0xA0,0x90,0x88, + 0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x05,0x07,0x07, + 0x06,0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00,0x00, + 0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88, + 0x88,0x50,0x50,0x20,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x88,0x88,0xA8,0xA8, + 0x50,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x05,0x07, + 0x07,0x06,0x00,0x00,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x05,0x07,0x07,0x06,0x00, + 0x00,0xF8,0x08,0x10,0x20,0x40,0x80,0xF8,0x03,0x09,0x09,0x06,0x01,0xFF,0xE0,0x80, + 0x80,0x80,0x80,0x80,0x80,0x80,0xE0,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x40,0x40, + 0x20,0x10,0x10,0x08,0x03,0x09,0x09,0x06,0x01,0xFF,0xE0,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0xE0,0x05,0x03,0x03,0x06,0x00,0x05,0x20,0x50,0x88,0x05,0x01,0x01,0x06, + 0x00,0xFE,0xF8,0x03,0x03,0x03,0x06,0x01,0x05,0x80,0x40,0x20,0x05,0x05,0x05,0x06, + 0x00,0x00,0x70,0x08,0x78,0x88,0x78,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x80,0xF0, + 0x88,0x88,0x88,0xF0,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x80,0x80,0x88,0x70,0x05, + 0x07,0x07,0x06,0x00,0x00,0x08,0x08,0x78,0x88,0x88,0x88,0x78,0x05,0x05,0x05,0x06, + 0x00,0x00,0x70,0x88,0xF0,0x80,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x30,0x48,0x40, + 0xE0,0x40,0x40,0x40,0x05,0x07,0x07,0x06,0x00,0xFE,0x70,0x88,0x88,0x88,0x78,0x08, + 0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x88,0x03,0x07, + 0x07,0x06,0x01,0x00,0x40,0x00,0xC0,0x40,0x40,0x40,0xE0,0x04,0x09,0x09,0x06,0x01, + 0xFE,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x90,0x60,0x05,0x07,0x07,0x06,0x00,0x00, + 0x80,0x80,0x88,0x90,0xE0,0x90,0x88,0x03,0x07,0x07,0x06,0x01,0x00,0xC0,0x40,0x40, + 0x40,0x40,0x40,0xE0,0x05,0x05,0x05,0x06,0x00,0x00,0xD0,0xA8,0xA8,0xA8,0xA8,0x05, + 0x05,0x05,0x06,0x00,0x00,0xB0,0xC8,0x88,0x88,0x88,0x05,0x05,0x05,0x06,0x00,0x00, + 0x70,0x88,0x88,0x88,0x70,0x05,0x07,0x07,0x06,0x00,0xFE,0xF0,0x88,0x88,0x88,0xF0, + 0x80,0x80,0x05,0x07,0x07,0x06,0x00,0xFE,0x78,0x88,0x88,0x88,0x78,0x08,0x08,0x05, + 0x05,0x05,0x06,0x00,0x00,0xB0,0xC8,0x80,0x80,0x80,0x05,0x05,0x05,0x06,0x00,0x00, + 0x78,0x80,0x70,0x08,0xF0,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x20,0xF8,0x20,0x20, + 0x20,0x18,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x88,0x88,0x98,0x68,0x05,0x05,0x05, + 0x06,0x00,0x00,0x88,0x88,0x88,0x50,0x20,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x88, + 0xA8,0xA8,0x50,0x05,0x05,0x05,0x06,0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x05,0x07, + 0x07,0x06,0x00,0xFE,0x88,0x88,0x88,0x50,0x20,0x40,0x80,0x05,0x05,0x05,0x06,0x00, + 0x00,0xF8,0x10,0x20,0x40,0xF8,0x03,0x09,0x09,0x06,0x01,0xFF,0x20,0x40,0x40,0x40, + 0x80,0x40,0x40,0x40,0x20,0x01,0x09,0x09,0x06,0x02,0xFF,0x80,0x80,0x80,0x80,0x80, + 0x80,0x80,0x80,0x80,0x03,0x09,0x09,0x06,0x01,0xFF,0x80,0x40,0x40,0x40,0x20,0x40, + 0x40,0x40,0x80,0x05,0x03,0x03,0x06,0x00,0x02,0x48,0xA8,0x90,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00, + 0x06,0x05,0xFF,0x01,0x07,0x07,0x06,0x02,0x00,0x80,0x00,0x80,0x80,0x80,0x80,0x80, + 0x05,0x07,0x07,0x06,0x00,0xFF,0x20,0x70,0xA8,0xA0,0xA8,0x70,0x20,0x05,0x07,0x07, + 0x06,0x00,0x00,0x30,0x48,0x40,0xE0,0x40,0x48,0xB0,0x05,0x05,0x05,0x06,0x00,0x00, + 0xA8,0x50,0x88,0x50,0xA8,0x05,0x07,0x07,0x06,0x00,0x00,0x88,0x50,0xF8,0x20,0xF8, + 0x20,0x20,0x01,0x07,0x07,0x06,0x02,0x00,0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x04, + 0x08,0x08,0x06,0x01,0x00,0x70,0x80,0x60,0x90,0x90,0x60,0x10,0xE0,0x03,0x01,0x01, + 0x06,0x01,0x07,0xA0,0x06,0x07,0x07,0x06,0x00,0x00,0x78,0x84,0xB4,0xA4,0xB4,0x84, + 0x78,0x03,0x05,0x05,0x06,0x01,0x04,0x60,0xA0,0x60,0x00,0xE0,0x05,0x05,0x05,0x06, + 0x00,0x00,0x28,0x50,0xA0,0x50,0x28,0x05,0x03,0x03,0x06,0x00,0x01,0xF8,0x08,0x08, + 0x03,0x01,0x01,0x06,0x01,0x03,0xE0,0x06,0x07,0x07,0x06,0x00,0x00,0x78,0x84,0xB4, + 0xA4,0xA4,0x84,0x78,0x05,0x01,0x01,0x06,0x00,0x07,0xF8,0x04,0x04,0x04,0x06,0x01, + 0x05,0x60,0x90,0x90,0x60,0x05,0x07,0x07,0x06,0x00,0x00,0x20,0x20,0xF8,0x20,0x20, + 0x00,0xF8,0x03,0x05,0x05,0x06,0x01,0x04,0x40,0xA0,0x20,0x40,0xE0,0x03,0x05,0x05, + 0x06,0x01,0x04,0xC0,0x20,0x40,0x20,0xC0,0x03,0x03,0x03,0x06,0x01,0x05,0x20,0x40, + 0x80,0x05,0x07,0x07,0x06,0x00,0xFE,0x88,0x88,0x88,0x98,0xE8,0x80,0x80,0x05,0x08, + 0x08,0x06,0x00,0x00,0x78,0xE8,0xE8,0xE8,0x68,0x28,0x28,0x28,0x02,0x02,0x02,0x06, + 0x02,0x03,0xC0,0xC0,0x03,0x02,0x02,0x06,0x01,0xFE,0x20,0xC0,0x03,0x05,0x05,0x06, + 0x01,0x04,0x40,0xC0,0x40,0x40,0xE0,0x03,0x05,0x05,0x06,0x01,0x05,0x40,0xA0,0x40, + 0x00,0xE0,0x05,0x05,0x05,0x06,0x00,0x00,0xA0,0x50,0x28,0x50,0xA0,0x05,0x0A,0x0A, + 0x06,0x00,0x00,0x40,0xC0,0x48,0x50,0x60,0x50,0xB0,0x50,0x78,0x10,0x05,0x0A,0x0A, + 0x06,0x00,0x00,0x40,0xC0,0x48,0x50,0x60,0x50,0xA8,0x08,0x10,0x38,0x05,0x0A,0x0A, + 0x06,0x00,0x00,0xC0,0x20,0x48,0x30,0xE0,0x50,0xB0,0x50,0x78,0x10,0x05,0x07,0x07, + 0x06,0x00,0x00,0x20,0x00,0x20,0x20,0x40,0x88,0x70,0x05,0x0A,0x0A,0x06,0x00,0x00, + 0x40,0x20,0x00,0x70,0x88,0x88,0xF8,0x88,0x88,0x88,0x05,0x0A,0x0A,0x06,0x00,0x00, + 0x10,0x20,0x00,0x70,0x88,0x88,0xF8,0x88,0x88,0x88,0x05,0x0A,0x0A,0x06,0x00,0x00, + 0x20,0x50,0x00,0x70,0x88,0x88,0xF8,0x88,0x88,0x88,0x05,0x0A,0x0A,0x06,0x00,0x00, + 0x68,0xB0,0x00,0x70,0x88,0x88,0xF8,0x88,0x88,0x88,0x05,0x09,0x09,0x06,0x00,0x00, + 0x50,0x00,0x70,0x88,0x88,0xF8,0x88,0x88,0x88,0x05,0x0A,0x0A,0x06,0x00,0x00,0x20, + 0x50,0x20,0x70,0x88,0x88,0xF8,0x88,0x88,0x88,0x05,0x07,0x07,0x06,0x00,0x00,0x78, + 0xA0,0xA0,0xF0,0xA0,0xA0,0xB8,0x05,0x09,0x09,0x06,0x00,0xFE,0x70,0x88,0x80,0x80, + 0x80,0x88,0x70,0x10,0x60,0x05,0x0A,0x0A,0x06,0x00,0x00,0x40,0x20,0x00,0xF8,0x80, + 0x80,0xF0,0x80,0x80,0xF8,0x05,0x0A,0x0A,0x06,0x00,0x00,0x10,0x20,0x00,0xF8,0x80, + 0x80,0xF0,0x80,0x80,0xF8,0x05,0x0A,0x0A,0x06,0x00,0x00,0x20,0x50,0x00,0xF8,0x80, + 0x80,0xF0,0x80,0x80,0xF8,0x05,0x09,0x09,0x06,0x00,0x00,0x50,0x00,0xF8,0x80,0x80, + 0xF0,0x80,0x80,0xF8,0x03,0x0A,0x0A,0x06,0x01,0x00,0x80,0x40,0x00,0xE0,0x40,0x40, + 0x40,0x40,0x40,0xE0,0x03,0x0A,0x0A,0x06,0x01,0x00,0x20,0x40,0x00,0xE0,0x40,0x40, + 0x40,0x40,0x40,0xE0,0x03,0x0A,0x0A,0x06,0x01,0x00,0x40,0xA0,0x00,0xE0,0x40,0x40, + 0x40,0x40,0x40,0xE0,0x03,0x09,0x09,0x06,0x01,0x00,0xA0,0x00,0xE0,0x40,0x40,0x40, + 0x40,0x40,0xE0,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x48,0x48,0xE8,0x48,0x48,0x70, + 0x05,0x0A,0x0A,0x06,0x00,0x00,0x68,0xB0,0x00,0x88,0x88,0xC8,0xA8,0x98,0x88,0x88, + 0x05,0x0A,0x0A,0x06,0x00,0x00,0x40,0x20,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70, + 0x05,0x0A,0x0A,0x06,0x00,0x00,0x10,0x20,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70, + 0x05,0x0A,0x0A,0x06,0x00,0x00,0x20,0x50,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70, + 0x05,0x0A,0x0A,0x06,0x00,0x00,0x68,0xB0,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70, + 0x05,0x09,0x09,0x06,0x00,0x00,0x50,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x05, + 0x05,0x05,0x06,0x00,0x01,0x88,0x50,0x20,0x50,0x88,0x05,0x09,0x09,0x06,0x00,0xFF, + 0x08,0x70,0x98,0xA8,0xA8,0xA8,0xC8,0x70,0x80,0x05,0x0A,0x0A,0x06,0x00,0x00,0x40, + 0x20,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x0A,0x0A,0x06,0x00,0x00,0x10, + 0x20,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x0A,0x0A,0x06,0x00,0x00,0x20, + 0x50,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x09,0x09,0x06,0x00,0x00,0x50, + 0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x05,0x0A,0x0A,0x06,0x00,0x00,0x10,0x20, + 0x00,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x04,0x07,0x07,0x06,0x01,0x00,0x80,0xE0, + 0x90,0x90,0x90,0xE0,0x80,0x05,0x07,0x07,0x06,0x00,0x00,0x70,0x88,0x90,0xA0,0x90, + 0x88,0xB0,0x05,0x08,0x08,0x06,0x00,0x00,0x40,0x20,0x00,0x70,0x08,0x78,0x88,0x78, + 0x05,0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0x70,0x08,0x78,0x88,0x78,0x05,0x08, + 0x08,0x06,0x00,0x00,0x20,0x50,0x00,0x70,0x08,0x78,0x88,0x78,0x05,0x08,0x08,0x06, + 0x00,0x00,0x68,0xB0,0x00,0x70,0x08,0x78,0x88,0x78,0x05,0x07,0x07,0x06,0x00,0x00, + 0x50,0x00,0x70,0x08,0x78,0x88,0x78,0x05,0x08,0x08,0x06,0x00,0x00,0x20,0x50,0x20, + 0x70,0x08,0x78,0x88,0x78,0x05,0x05,0x05,0x06,0x00,0x00,0x70,0x28,0x70,0xA0,0x78, + 0x05,0x07,0x07,0x06,0x00,0xFE,0x70,0x88,0x80,0x88,0x70,0x10,0x60,0x05,0x08,0x08, + 0x06,0x00,0x00,0x40,0x20,0x00,0x70,0x88,0xF0,0x80,0x70,0x05,0x08,0x08,0x06,0x00, + 0x00,0x10,0x20,0x00,0x70,0x88,0xF0,0x80,0x70,0x05,0x08,0x08,0x06,0x00,0x00,0x20, + 0x50,0x00,0x70,0x88,0xF0,0x80,0x70,0x05,0x07,0x07,0x06,0x00,0x00,0x50,0x00,0x70, + 0x88,0xF0,0x80,0x70,0x03,0x08,0x08,0x06,0x01,0x00,0x80,0x40,0x00,0xC0,0x40,0x40, + 0x40,0xE0,0x03,0x08,0x08,0x06,0x01,0x00,0x20,0x40,0x00,0xC0,0x40,0x40,0x40,0xE0, + 0x03,0x08,0x08,0x06,0x01,0x00,0x40,0xA0,0x00,0xC0,0x40,0x40,0x40,0xE0,0x03,0x07, + 0x07,0x06,0x01,0x00,0xA0,0x00,0xC0,0x40,0x40,0x40,0xE0,0x05,0x09,0x09,0x06,0x00, + 0x00,0x50,0x20,0x50,0x08,0x78,0x88,0x88,0x88,0x70,0x05,0x08,0x08,0x06,0x00,0x00, + 0x68,0xB0,0x00,0xB0,0xC8,0x88,0x88,0x88,0x05,0x08,0x08,0x06,0x00,0x00,0x40,0x20, + 0x00,0x70,0x88,0x88,0x88,0x70,0x05,0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0x70, + 0x88,0x88,0x88,0x70,0x05,0x08,0x08,0x06,0x00,0x00,0x20,0x50,0x00,0x70,0x88,0x88, + 0x88,0x70,0x05,0x08,0x08,0x06,0x00,0x00,0x68,0xB0,0x00,0x70,0x88,0x88,0x88,0x70, + 0x05,0x07,0x07,0x06,0x00,0x00,0x50,0x00,0x70,0x88,0x88,0x88,0x70,0x05,0x05,0x05, + 0x06,0x00,0x01,0x20,0x00,0xF8,0x00,0x20,0x05,0x05,0x05,0x06,0x00,0x00,0x78,0x98, + 0xA8,0xC8,0xF0,0x05,0x08,0x08,0x06,0x00,0x00,0x40,0x20,0x00,0x88,0x88,0x88,0x88, + 0x70,0x05,0x08,0x08,0x06,0x00,0x00,0x10,0x20,0x00,0x88,0x88,0x88,0x88,0x70,0x05, + 0x08,0x08,0x06,0x00,0x00,0x20,0x50,0x00,0x88,0x88,0x88,0x88,0x70,0x05,0x07,0x07, + 0x06,0x00,0x00,0x50,0x00,0x88,0x88,0x88,0x88,0x70,0x05,0x0A,0x0A,0x06,0x00,0xFE, + 0x10,0x20,0x00,0x88,0x88,0x88,0x50,0x20,0x40,0x80,0x05,0x09,0x09,0x06,0x00,0xFE, + 0x80,0x80,0xF0,0x88,0x88,0x88,0xF0,0x80,0x80,0x05,0x09,0x09,0x06,0x00,0xFE,0x50, + 0x00,0x88,0x88,0x88,0x50,0x20,0x40,0x80 +}; + +#endif // !STM32_NOT_EXTENDED_ISO10646_1_5X7 + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/fontdata/helvetica_12_bold.cpp b/Marlin/src/lcd/tft/fontdata/helvetica_12_bold.cpp new file mode 100644 index 000000000000..12efb3ba4947 --- /dev/null +++ b/Marlin/src/lcd/tft/fontdata/helvetica_12_bold.cpp @@ -0,0 +1,302 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* + Fontname: Helvetica + Copyright: Copyright (c) 1984, 1987 Adobe Systems Incorporated. All Rights Reserved. Copyright (c) 1988, 1991 Digital Equipment Corporation. All Rights Reserved. + Capital A Height: 12, '1' Height: 12 + Calculated Max Values w=14 h=17 x= 2 y=10 dx=16 dy= 0 ascent=14 len=32 + Font Bounding box w=16 h=17 x= 0 y=-4 + Calculated Min Values x= 0 y=-4 dx= 0 dy= 0 + Pure Font ascent =12 descent=-4 + X Font ascent =12 descent=-4 + Max Font ascent =14 descent=-4 +*/ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +#include + +extern const uint8_t Helvetica12Bold[4172] = { + 0,16,17,0,252,12,2,74,5,106,32,255,252,14,252,12, + 252,0,0,0,5,0,0,2,12,12,6,2,0,192,192,192, + 192,192,192,192,192,192,0,192,192,5,4,4,8,1,8,216, + 216,216,72,9,12,24,9,0,0,27,0,27,0,27,0,127, + 128,127,128,54,0,54,0,255,0,255,0,108,0,108,0,108, + 0,7,14,14,9,1,255,16,124,254,214,208,240,120,60,30, + 22,214,254,124,16,13,12,24,14,0,0,48,64,120,128,204, + 128,205,0,121,0,50,0,2,96,4,240,5,152,9,152,8, + 240,16,96,10,12,24,12,1,0,60,0,126,0,102,0,102, + 0,60,0,56,192,125,192,207,128,199,0,199,0,127,128,57, + 192,2,4,4,4,1,8,192,192,192,64,4,15,15,6,1, + 253,48,112,96,192,192,192,192,192,192,192,192,192,96,112,48, + 4,15,15,6,0,253,192,224,96,48,48,48,48,48,48,48, + 48,48,96,224,192,5,5,5,6,0,7,32,168,112,112,136, + 8,8,8,10,1,0,24,24,24,255,255,24,24,24,2,5, + 5,4,1,253,192,192,64,64,128,4,2,2,5,0,3,240, + 240,2,2,2,4,1,0,192,192,4,12,12,5,0,0,16, + 16,48,32,32,96,64,64,192,128,128,128,8,12,12,9,0, + 0,60,126,231,195,195,195,195,195,195,231,126,60,5,12,12, + 9,1,0,8,24,248,248,24,24,24,24,24,24,24,24,8, + 12,12,9,0,0,60,126,231,195,195,7,14,28,56,112,255, + 255,8,12,12,9,0,0,60,126,231,195,7,30,30,7,195, + 231,126,60,8,12,12,9,0,0,14,30,54,54,102,102,198, + 255,255,6,6,6,8,12,12,9,0,0,63,63,48,48,124, + 126,71,3,3,231,126,60,8,12,12,9,0,0,60,126,231, + 192,220,254,231,195,195,231,126,60,8,12,12,9,0,0,255, + 255,6,6,12,12,24,24,24,48,48,48,8,12,12,9,0, + 0,60,126,231,195,102,60,126,231,195,231,126,60,8,12,12, + 9,0,0,60,126,231,195,195,231,127,59,3,231,126,60,2, + 8,8,5,2,0,192,192,0,0,0,0,192,192,2,11,11, + 5,2,253,192,192,0,0,0,0,192,192,64,64,128,8,8, + 8,10,1,0,3,15,60,224,224,60,15,3,8,6,6,10, + 1,1,255,255,0,0,255,255,8,8,8,10,1,0,192,240, + 60,7,7,60,240,192,7,12,12,10,1,0,124,254,198,198, + 6,14,12,24,24,0,24,24,13,14,28,16,1,254,15,192, + 56,96,96,16,71,216,204,72,136,200,152,200,152,136,153,152, + 201,144,70,96,96,0,56,192,15,128,11,12,24,12,0,0, + 14,0,14,0,31,0,27,0,59,128,49,128,113,192,96,192, + 127,192,255,224,192,96,192,96,9,12,24,11,1,0,254,0, + 255,0,195,128,193,128,195,128,255,0,255,0,195,128,193,128, + 195,128,255,0,254,0,10,12,24,12,1,0,31,0,63,128, + 113,192,96,192,224,0,192,0,192,0,224,0,96,192,113,192, + 63,128,31,0,10,12,24,12,1,0,252,0,255,0,195,128, + 193,128,193,192,192,192,192,192,193,192,193,128,195,128,255,0, + 252,0,8,12,12,10,1,0,255,255,192,192,192,254,254,192, + 192,192,255,255,8,12,12,10,1,0,255,255,192,192,192,254, + 254,192,192,192,192,192,10,12,24,12,1,0,31,0,63,128, + 113,192,96,192,224,0,192,0,195,192,227,192,96,192,113,192, + 63,192,30,192,10,12,24,12,1,0,192,192,192,192,192,192, + 192,192,255,192,255,192,192,192,192,192,192,192,192,192,192,192, + 192,192,2,12,12,4,1,0,192,192,192,192,192,192,192,192, + 192,192,192,192,7,12,12,9,1,0,6,6,6,6,6,6, + 6,6,198,198,254,124,10,12,24,12,1,0,193,192,195,128, + 199,0,206,0,220,0,248,0,252,0,206,0,199,0,195,128, + 193,192,192,192,8,12,12,10,1,0,192,192,192,192,192,192, + 192,192,192,192,255,255,11,12,24,13,1,0,224,224,224,224, + 224,224,241,224,241,224,209,96,219,96,219,96,202,96,206,96, + 206,96,196,96,10,12,24,12,1,0,224,192,240,192,240,192, + 216,192,216,192,204,192,204,192,198,192,198,192,195,192,195,192, + 193,192,11,12,24,13,1,0,31,0,63,128,113,192,96,192, + 224,224,192,96,192,96,224,224,96,192,113,192,63,128,31,0, + 9,12,24,11,1,0,254,0,255,0,195,128,193,128,193,128, + 195,128,255,0,254,0,192,0,192,0,192,0,192,0,11,13, + 26,13,1,255,31,0,63,128,113,192,96,192,224,224,192,96, + 192,96,226,96,103,192,115,192,63,128,31,192,0,128,10,12, + 24,12,1,0,255,0,255,128,193,128,193,128,195,128,255,0, + 255,0,195,128,193,128,193,128,193,192,193,192,9,12,24,11, + 1,0,62,0,127,0,227,128,193,128,240,0,126,0,31,0, + 3,128,193,128,227,128,127,0,62,0,10,12,24,10,0,0, + 255,192,255,192,12,0,12,0,12,0,12,0,12,0,12,0, + 12,0,12,0,12,0,12,0,10,12,24,12,1,0,192,192, + 192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, + 225,192,127,128,63,0,10,12,24,11,0,0,192,192,192,192, + 97,128,97,128,97,128,51,0,51,0,51,0,30,0,30,0, + 12,0,12,0,14,12,24,15,0,0,195,12,195,12,195,12, + 99,24,103,152,103,152,52,176,60,240,60,240,24,96,24,96, + 24,96,9,12,24,11,1,0,193,128,227,128,99,0,54,0, + 62,0,28,0,28,0,62,0,54,0,99,0,227,128,193,128, + 10,12,24,11,0,0,192,192,225,192,97,128,51,0,51,0, + 30,0,30,0,12,0,12,0,12,0,12,0,12,0,8,12, + 12,10,1,0,255,255,7,6,12,28,56,48,96,224,255,255, + 4,15,15,6,1,253,240,240,192,192,192,192,192,192,192,192, + 192,192,192,240,240,4,12,12,5,0,0,128,128,192,64,64, + 96,32,32,48,16,16,16,4,15,15,6,0,253,240,240,48, + 48,48,48,48,48,48,48,48,48,48,240,240,8,7,7,10, + 1,5,24,24,60,102,102,195,195,9,1,2,9,0,253,255, + 128,3,3,3,6,2,10,128,192,32,8,9,9,9,1,0, + 124,254,198,14,126,230,198,254,119,8,12,12,10,1,0,192, + 192,192,220,254,231,195,195,195,231,254,220,8,9,9,9,1, + 0,60,126,231,192,192,192,231,126,60,8,12,12,10,1,0, + 3,3,3,63,127,231,195,195,195,231,127,59,8,9,9,10, + 1,0,60,126,195,255,255,192,231,126,60,4,12,12,6,1, + 0,48,112,96,240,240,96,96,96,96,96,96,96,8,13,13, + 10,1,252,59,127,231,195,195,195,231,127,59,3,231,126,60, + 8,12,12,10,1,0,192,192,192,222,255,227,195,195,195,195, + 195,195,2,12,12,4,1,0,192,192,0,192,192,192,192,192, + 192,192,192,192,3,16,16,5,1,252,96,96,0,96,96,96, + 96,96,96,96,96,96,96,96,224,192,8,12,12,9,1,0, + 192,192,192,199,206,220,248,252,236,206,198,199,2,12,12,4, + 1,0,192,192,192,192,192,192,192,192,192,192,192,192,12,9, + 18,14,1,0,222,224,255,240,231,48,198,48,198,48,198,48, + 198,48,198,48,198,48,8,9,9,10,1,0,222,255,227,195, + 195,195,195,195,195,8,9,9,10,1,0,60,126,231,195,195, + 195,231,126,60,8,13,13,10,1,252,220,254,231,195,195,195, + 231,254,220,192,192,192,192,8,13,13,10,1,252,59,127,231, + 195,195,195,231,127,59,3,3,3,3,5,9,9,6,1,0, + 216,248,224,192,192,192,192,192,192,7,9,9,9,1,0,124, + 254,198,240,124,14,198,254,124,4,11,11,6,1,0,96,96, + 240,240,96,96,96,96,96,112,48,8,9,9,10,1,0,195, + 195,195,195,195,195,199,255,123,8,9,9,9,0,0,195,195, + 102,102,102,60,60,24,24,12,9,18,13,0,0,198,48,198, + 48,102,96,102,96,111,96,63,192,57,192,25,128,25,128,7, + 9,9,9,1,0,198,198,108,124,56,124,108,198,198,8,13, + 13,9,0,252,195,195,99,102,54,54,60,28,24,24,24,112, + 96,7,9,9,8,0,0,254,254,14,28,24,56,112,254,254, + 4,15,15,6,1,253,48,112,96,96,96,96,96,192,96,96, + 96,96,96,112,48,1,16,16,4,1,252,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,4,15,15,6,1, + 253,192,224,96,96,96,96,96,48,96,96,96,96,96,224,192, + 8,3,3,10,1,3,113,153,142,0,0,0,1,0,0,0, + 0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0, + 0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0, + 1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0, + 0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0, + 0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0, + 1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0, + 0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0, + 0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0, + 1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0, + 0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0, + 0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0, + 1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0, + 0,0,5,0,0,2,12,12,6,1,253,192,192,0,64,64, + 64,192,192,192,192,192,192,8,11,11,9,0,255,4,60,126, + 239,200,216,208,247,126,60,32,8,12,12,9,0,0,28,62, + 99,99,96,48,124,48,48,32,127,255,7,7,7,9,1,2, + 186,124,198,198,198,124,186,8,12,12,9,0,0,195,195,102, + 102,60,24,126,24,126,24,24,24,1,16,16,5,2,252,128, + 128,128,128,128,128,128,0,0,128,128,128,128,128,128,128,8, + 15,15,9,0,253,60,126,102,96,120,126,199,195,243,126,30, + 6,102,126,60,5,2,2,6,0,10,216,216,12,12,24,12, + 0,0,15,0,57,192,96,96,79,32,217,176,144,16,144,16, + 217,176,79,32,96,32,57,192,15,0,5,7,7,6,1,5, + 96,144,112,144,120,0,248,8,6,6,9,0,2,51,102,204, + 204,102,51,8,5,5,10,0,2,255,255,3,3,3,4,2, + 2,5,0,3,240,240,12,12,24,12,0,0,15,0,57,192, + 96,96,95,32,217,176,153,144,158,16,219,48,91,32,96,96, + 57,192,15,0,5,1,1,6,0,10,248,4,5,5,7,1, + 7,96,144,144,144,96,8,11,11,10,1,0,24,24,24,255, + 255,24,24,24,0,255,255,5,7,7,6,0,5,112,216,216, + 48,96,248,248,5,7,7,6,0,5,112,216,24,48,24,216, + 112,3,3,3,6,1,10,32,96,128,8,12,12,10,1,253, + 195,195,195,195,195,195,199,255,251,192,192,192,8,15,15,9, + 0,253,127,242,242,242,242,242,114,18,18,18,18,18,18,18, + 18,2,2,2,5,1,4,192,192,5,4,4,6,0,252,32, + 48,152,112,4,7,7,6,1,5,48,240,240,48,48,48,48, + 5,7,7,6,0,5,112,216,136,216,112,0,248,8,6,6, + 9,1,2,204,102,51,51,102,204,13,12,24,14,1,0,48, + 192,240,128,241,128,49,0,51,48,50,112,54,240,4,176,13, + 176,9,248,24,48,16,48,12,12,24,14,0,0,48,128,241, + 128,241,0,51,0,50,0,54,224,53,176,13,176,8,96,24, + 192,17,240,49,240,13,12,24,14,0,0,112,64,216,192,24, + 128,49,128,25,48,219,112,114,240,6,176,5,176,13,248,8, + 48,24,48,7,12,12,10,1,253,48,48,0,48,48,96,224, + 192,198,198,254,124,11,14,28,12,0,0,4,0,0,0,14, + 0,14,0,31,0,27,0,59,128,49,128,113,192,96,192,127, + 192,255,224,192,96,192,96,11,14,28,12,0,0,8,0,0, + 0,14,0,14,0,31,0,27,0,59,128,49,128,113,192,96, + 192,127,192,255,224,192,96,192,96,11,14,28,12,0,0,17, + 0,0,0,14,0,14,0,31,0,27,0,59,128,49,128,113, + 192,96,192,127,192,255,224,192,96,192,96,11,14,28,12,0, + 0,23,0,0,0,14,0,14,0,31,0,27,0,59,128,49, + 128,113,192,96,192,127,192,255,224,192,96,192,96,11,14,28, + 12,0,0,49,128,0,0,14,0,14,0,31,0,27,0,59, + 128,49,128,113,192,96,192,127,192,255,224,192,96,192,96,11, + 14,28,12,0,0,18,0,12,0,14,0,14,0,31,0,27, + 0,59,128,49,128,113,192,96,192,127,192,255,224,192,96,192, + 96,14,12,24,15,0,0,31,252,31,252,27,0,51,0,51, + 0,51,248,99,248,127,0,127,0,195,0,195,252,195,252,10, + 16,32,12,1,252,31,0,63,128,113,192,96,192,224,0,192, + 0,192,0,224,0,96,192,113,192,63,128,31,0,4,0,6, + 0,19,0,14,0,8,14,14,10,1,0,8,0,255,255,192, + 192,192,254,254,192,192,192,255,255,8,14,14,10,1,0,16, + 0,255,255,192,192,192,254,254,192,192,192,255,255,8,14,14, + 10,1,0,34,0,255,255,192,192,192,254,254,192,192,192,255, + 255,8,14,14,10,1,0,102,0,255,255,192,192,192,254,254, + 192,192,192,255,255,2,14,14,4,1,0,64,0,192,192,192, + 192,192,192,192,192,192,192,192,192,2,14,14,4,1,0,128, + 0,192,192,192,192,192,192,192,192,192,192,192,192,5,14,14, + 5,0,0,136,0,96,96,96,96,96,96,96,96,96,96,96, + 96,5,14,14,5,0,0,152,0,96,96,96,96,96,96,96, + 96,96,96,96,96,12,12,24,12,0,0,63,0,63,192,48, + 224,48,96,48,112,252,48,252,48,48,112,48,96,48,224,63, + 192,63,0,10,14,28,12,1,0,46,0,0,0,224,192,240, + 192,240,192,216,192,216,192,204,192,204,192,198,192,198,192,195, + 192,195,192,193,192,11,14,28,13,1,0,2,0,0,0,31, + 0,63,128,113,192,96,192,224,224,192,96,192,96,224,224,96, + 192,113,192,63,128,31,0,11,14,28,13,1,0,4,0,0, + 0,31,0,63,128,113,192,96,192,224,224,192,96,192,96,224, + 224,96,192,113,192,63,128,31,0,11,14,28,13,1,0,17, + 0,0,0,31,0,63,128,113,192,96,192,224,224,192,96,192, + 96,224,224,96,192,113,192,63,128,31,0,11,14,28,13,1, + 0,23,0,0,0,31,0,63,128,113,192,96,192,224,224,192, + 96,192,96,224,224,96,192,113,192,63,128,31,0,11,14,28, + 13,1,0,25,128,0,0,31,0,63,128,113,192,96,192,224, + 224,192,96,192,96,224,224,96,192,113,192,63,128,31,0,9, + 9,18,10,0,0,65,0,227,128,119,0,62,0,28,0,62, + 0,119,0,227,128,65,0,11,12,24,13,1,0,31,32,63, + 192,112,192,97,192,227,96,198,96,204,96,216,224,112,192,97, + 192,127,128,159,0,10,14,28,12,1,0,4,0,0,0,192, + 192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, + 192,225,192,127,128,63,0,10,14,28,12,1,0,8,0,0, + 0,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, + 192,192,192,225,192,127,128,63,0,10,14,28,12,1,0,17, + 0,0,0,192,192,192,192,192,192,192,192,192,192,192,192,192, + 192,192,192,192,192,225,192,127,128,63,0,10,14,28,12,1, + 0,51,0,0,0,192,192,192,192,192,192,192,192,192,192,192, + 192,192,192,192,192,192,192,225,192,127,128,63,0,10,14,28, + 11,0,0,8,0,0,0,192,192,225,192,97,128,51,0,51, + 0,30,0,30,0,12,0,12,0,12,0,12,0,12,0,9, + 12,24,11,1,0,192,0,254,0,255,0,195,128,193,128,193, + 128,195,128,255,0,254,0,192,0,192,0,192,0,8,12,12, + 10,1,0,124,254,198,198,220,222,195,195,195,195,222,220,8, + 13,13,9,1,0,32,48,8,0,124,254,198,14,126,230,198, + 254,119,8,13,13,9,1,0,4,12,16,0,124,254,198,14, + 126,230,198,254,119,8,13,13,9,1,0,16,56,68,0,124, + 254,198,14,126,230,198,254,119,8,12,12,9,1,0,58,92, + 0,124,254,198,14,126,230,198,254,119,8,12,12,9,1,0, + 108,108,0,124,254,198,14,126,230,198,254,119,8,13,13,9, + 1,0,24,36,36,24,124,254,198,14,126,230,198,254,119,13, + 9,18,15,1,0,125,224,255,240,198,24,15,248,127,248,230, + 0,207,56,255,240,121,224,8,13,13,9,1,252,60,126,231, + 192,192,192,231,126,60,16,24,76,56,8,13,13,10,1,0, + 32,48,8,0,60,126,195,255,255,192,231,126,60,8,13,13, + 10,1,0,4,12,16,0,60,126,195,255,255,192,231,126,60, + 8,13,13,10,1,0,8,28,34,0,60,126,195,255,255,192, + 231,126,60,8,12,12,10,1,0,54,54,0,60,126,195,255, + 255,192,231,126,60,3,13,13,4,0,0,128,192,32,0,96, + 96,96,96,96,96,96,96,96,3,13,13,4,1,0,32,96, + 128,0,192,192,192,192,192,192,192,192,192,5,13,13,5,0, + 0,32,112,136,0,96,96,96,96,96,96,96,96,96,5,12, + 12,5,0,0,216,216,0,96,96,96,96,96,96,96,96,96, + 8,12,12,10,1,0,96,124,248,28,126,231,195,195,195,231, + 126,60,8,12,12,10,1,0,58,92,0,222,255,227,195,195, + 195,195,195,195,8,13,13,10,1,0,32,48,8,0,60,126, + 231,195,195,195,231,126,60,8,13,13,10,1,0,8,24,32, + 0,60,126,231,195,195,195,231,126,60,8,13,13,10,1,0, + 16,56,68,0,60,126,231,195,195,195,231,126,60,8,12,12, + 10,1,0,58,92,0,60,126,231,195,195,195,231,126,60,8, + 12,12,10,1,0,108,108,0,60,126,231,195,195,195,231,126, + 60,8,8,8,10,1,0,24,24,0,255,255,0,24,24,8, + 9,9,10,1,0,61,127,231,207,219,243,231,254,188,8,13, + 13,10,1,0,32,48,8,0,195,195,195,195,195,195,199,255, + 123,8,13,13,10,1,0,8,24,32,0,195,195,195,195,195, + 195,199,255,123,8,13,13,10,1,0,16,56,68,0,195,195, + 195,195,195,195,199,255,123,8,12,12,10,1,0,108,108,0, + 195,195,195,195,195,195,199,255,123,8,17,17,9,0,252,4, + 12,16,0,195,195,99,102,54,54,60,28,24,24,24,112,96, + 8,16,16,10,1,252,192,192,192,220,254,231,195,195,195,231, + 254,220,192,192,192,192,8,16,16,9,0,252,54,54,0,195, + 195,99,102,54,54,60,28,24,24,24,112,96 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/fontdata/helvetica_14.cpp b/Marlin/src/lcd/tft/fontdata/helvetica_14.cpp new file mode 100644 index 000000000000..a27ea4369793 --- /dev/null +++ b/Marlin/src/lcd/tft/fontdata/helvetica_14.cpp @@ -0,0 +1,378 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* + Fontname: Helvetica + Copyright: Copyright (c) 1984, 1987 Adobe Systems Incorporated. All Rights Reserved. Copyright (c) 1988, 1991 Digital Equipment Corporation. All Rights Reserved. + Capital A Height: 14, '1' Height: 13 + Calculated Max Values w=16 h=18 x= 2 y=12 dx=18 dy= 0 ascent=16 len=36 + Font Bounding box w=18 h=19 x= 0 y=-4 + Calculated Min Values x= 0 y=-4 dx= 0 dy= 0 + Pure Font ascent =14 descent=-4 + X Font ascent =14 descent=-4 + Max Font ascent =16 descent=-4 +*/ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +#include + +/* +typedef struct __attribute__((__packed__)) { + uint8_t BBXWidth; + uint8_t BBXHeight; + uint8_t DataSize; + int8_t DWidth; + int8_t BBXOffsetX; + int8_t BBXOffsetY; +} tGlyph; +*/ + +extern const uint8_t Helvetica14_symbols[63] = { + 0,18,19,0,252,14,0,0,0,0,1,9,252,16,252,14,252, // tFont + 0,0,0,0,0,0, // 0x01 - LCD_STR_REFRESH + 0,0,0,0,0,0, // 0x02 - LCD_STR_FOLDER + 255, // 0x03 - LCD_STR_ARROW_RIGHT + 255, // 0x04 - LCD_STR_UPLEVEL + 255, // 0x05 - LCD_STR_CLOCK + 255, // 0x06 - LCD_STR_FEEDRATE + 255, // 0x07 - LCD_STR_BEDTEMP + 5,12,12,6,0,1,32,80,80,80,80,80,80,80,136,136,136,112, // 0x08 - LCD_STR_THERMOMETER + 5,5,5,5,0,11,112,216,136,216,112, // 0x09 - LCD_STR_DEGREE +}; + +extern const uint8_t Helvetica14[5005] = { + 0,18,19,0,252,14,2,150,6,83,32,255,252,16,252,14,252, // tFont + 0,0,0,5,0,0,2,14,14,6,2,0,192,192,192, + 192,192,192,192,192,192,192,0,0,192,192,5,5,5,5,0, + 9,216,216,216,216,216,10,13,26,10,0,0,9,0,9,0, + 9,0,127,192,127,192,18,0,18,0,18,0,255,128,255,128, + 36,0,36,0,36,0,9,16,32,10,1,254,8,0,62,0, + 127,0,203,0,200,0,232,0,120,0,62,0,15,0,9,128, + 201,128,235,128,127,0,62,0,8,0,8,0,14,13,26,16, + 1,0,120,96,204,192,204,192,205,128,205,128,123,0,3,0, + 6,120,6,204,12,204,12,204,24,204,24,120,12,13,26,13, + 1,0,60,0,126,0,102,0,102,0,60,0,124,0,238,192, + 198,192,195,192,195,128,231,192,126,224,60,112,2,5,5,4, + 1,9,192,192,192,192,192,4,18,18,6,0,252,16,48,96, + 96,192,192,192,192,192,192,192,192,192,192,96,96,48,16,4, + 18,18,6,1,252,128,192,96,96,48,48,48,48,48,48,48, + 48,48,48,96,96,192,128,5,7,7,7,1,7,32,168,248, + 32,248,168,32,8,10,10,10,1,0,24,24,24,24,255,255, + 24,24,24,24,2,5,5,5,1,253,192,192,64,64,128,5, + 2,2,6,0,4,248,248,2,2,2,5,1,0,192,192,5, + 14,14,5,0,0,24,24,24,24,48,48,48,96,96,96,192, + 192,192,192,8,13,13,10,1,0,60,126,102,195,195,195,195, + 195,195,195,102,126,60,5,13,13,10,2,0,24,248,248,24, + 24,24,24,24,24,24,24,24,24,8,13,13,10,1,0,60, + 254,195,3,7,14,28,56,112,224,192,255,255,8,13,13,10, + 1,0,62,127,195,195,6,28,30,7,3,195,199,126,60,9, + 13,26,10,0,0,3,0,7,0,15,0,27,0,51,0,51, + 0,99,0,195,0,255,128,255,128,3,0,3,0,3,0,8, + 13,13,10,1,0,254,254,192,192,252,254,199,3,3,195,199, + 254,124,8,13,13,10,1,0,60,127,99,192,192,220,254,195, + 195,195,227,126,60,8,13,13,10,1,0,255,255,3,6,12, + 12,24,24,48,48,96,96,96,8,13,13,10,1,0,60,126, + 231,195,195,102,126,231,195,195,231,126,60,8,13,13,10,1, + 0,60,126,199,195,195,195,127,59,3,3,198,254,124,2,10, + 10,5,1,0,192,192,0,0,0,0,0,0,192,192,2,13, + 13,5,1,253,192,192,0,0,0,0,0,0,192,192,64,64, + 128,8,9,9,10,1,0,3,15,60,112,192,112,60,15,3, + 7,5,5,11,2,2,254,254,0,254,254,8,9,9,10,1, + 0,192,240,60,14,3,14,60,240,192,7,14,14,10,1,0, + 124,254,198,198,14,28,56,48,48,48,0,0,48,48,16,17, + 34,18,1,253,3,240,15,252,28,14,48,6,99,211,103,115, + 198,51,204,99,204,102,204,102,204,204,207,248,103,112,112,0, + 56,0,31,240,7,224,12,14,28,13,0,0,6,0,6,0, + 15,0,15,0,25,128,25,128,48,192,48,192,63,192,127,224, + 96,96,96,96,192,48,192,48,11,14,28,13,1,0,255,0, + 255,128,193,192,192,192,192,192,193,128,255,128,255,192,192,224, + 192,96,192,96,192,224,255,192,255,128,12,14,28,14,1,0, + 15,128,63,224,112,112,96,48,224,0,192,0,192,0,192,0, + 192,0,224,0,96,48,112,112,63,224,15,128,12,14,28,14, + 1,0,255,128,255,192,192,224,192,96,192,48,192,48,192,48, + 192,48,192,48,192,48,192,96,192,224,255,192,255,128,10,14, + 28,13,2,0,255,192,255,192,192,0,192,0,192,0,192,0, + 255,128,255,128,192,0,192,0,192,0,192,0,255,192,255,192, + 9,14,28,12,2,0,255,128,255,128,192,0,192,0,192,0, + 192,0,255,0,255,0,192,0,192,0,192,0,192,0,192,0, + 192,0,13,14,28,15,1,0,15,192,63,240,112,56,96,24, + 224,24,192,0,192,0,192,248,192,248,224,24,96,24,112,56, + 63,248,15,216,11,14,28,14,1,0,192,96,192,96,192,96, + 192,96,192,96,192,96,255,224,255,224,192,96,192,96,192,96, + 192,96,192,96,192,96,2,14,14,6,2,0,192,192,192,192, + 192,192,192,192,192,192,192,192,192,192,8,14,14,10,0,0, + 3,3,3,3,3,3,3,3,3,195,195,231,126,60,11,14, + 28,14,2,0,192,224,193,192,195,128,199,0,206,0,220,0, + 248,0,252,0,206,0,199,0,195,128,193,192,192,224,192,96, + 9,14,28,11,1,0,192,0,192,0,192,0,192,0,192,0, + 192,0,192,0,192,0,192,0,192,0,192,0,192,0,255,128, + 255,128,14,14,28,16,1,0,192,12,192,12,224,28,224,28, + 240,60,240,60,216,108,216,108,204,204,204,204,196,140,199,140, + 195,12,195,12,11,14,28,14,1,0,192,96,224,96,240,96, + 240,96,216,96,204,96,204,96,198,96,198,96,195,96,193,224, + 193,224,192,224,192,96,13,14,28,15,1,0,15,128,63,224, + 112,112,96,48,224,56,192,24,192,24,192,24,192,24,224,56, + 96,48,112,112,63,224,15,128,10,14,28,13,2,0,255,0, + 255,128,193,192,192,192,192,192,193,192,255,128,255,0,192,0, + 192,0,192,0,192,0,192,0,192,0,13,15,30,15,1,255, + 15,128,63,224,112,112,96,48,224,56,192,24,192,24,192,24, + 192,24,225,184,97,176,112,240,63,224,15,176,0,48,11,14, + 28,14,1,0,255,128,255,192,192,224,192,96,192,96,192,224, + 255,192,255,128,192,192,192,192,192,96,192,96,192,96,192,96, + 10,14,28,13,1,0,30,0,127,128,225,192,192,192,224,0, + 124,0,31,0,3,128,1,192,0,192,192,192,225,192,127,128, + 63,0,10,14,28,12,1,0,255,192,255,192,12,0,12,0, + 12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,0, + 12,0,12,0,11,14,28,14,1,0,192,96,192,96,192,96, + 192,96,192,96,192,96,192,96,192,96,192,96,192,96,192,96, + 96,192,127,192,31,0,12,14,28,13,0,0,192,48,192,48, + 96,96,96,96,96,96,48,192,48,192,48,192,25,128,25,128, + 25,128,15,0,15,0,6,0,16,14,28,18,1,0,193,131, + 193,131,193,131,195,195,99,198,98,70,102,102,102,102,54,108, + 54,108,52,44,28,56,24,24,24,24,11,14,28,13,1,0, + 192,96,192,96,96,192,113,192,49,128,27,0,14,0,14,0, + 27,0,49,128,113,192,96,192,192,96,192,96,12,14,28,13, + 0,0,192,48,192,48,96,96,96,96,48,192,57,192,25,128, + 15,0,6,0,6,0,6,0,6,0,6,0,6,0,10,14, + 28,12,1,0,255,192,255,192,0,192,1,128,3,0,6,0, + 12,0,28,0,24,0,48,0,96,0,192,0,255,192,255,192, + 4,18,18,5,0,252,240,240,192,192,192,192,192,192,192,192, + 192,192,192,192,192,192,240,240,5,14,14,5,0,0,192,192, + 192,96,96,96,48,48,48,48,24,24,24,24,4,18,18,5, + 0,252,240,240,48,48,48,48,48,48,48,48,48,48,48,48, + 48,48,240,240,7,6,6,9,1,7,16,56,108,108,198,198, + 11,2,4,11,0,252,255,224,255,224,4,3,3,4,0,11, + 192,96,48,9,10,20,11,1,0,126,0,231,0,195,0,7, + 0,127,0,227,0,195,0,195,0,231,128,121,128,9,14,28, + 11,1,0,192,0,192,0,192,0,192,0,222,0,255,0,227, + 0,193,128,193,128,193,128,193,128,227,0,255,0,222,0,8, + 10,10,10,1,0,62,127,99,192,192,192,192,99,127,62,9, + 14,28,11,1,0,1,128,1,128,1,128,1,128,61,128,127, + 128,99,128,193,128,193,128,193,128,193,128,99,128,127,128,61, + 128,8,10,10,10,1,0,60,126,195,195,255,192,192,227,127, + 60,6,14,14,6,0,0,28,60,48,48,252,252,48,48,48, + 48,48,48,48,48,9,14,28,11,1,252,61,128,127,128,97, + 128,193,128,193,128,193,128,193,128,99,128,127,128,61,128,1, + 128,99,0,127,0,28,0,8,14,14,10,1,0,192,192,192, + 192,222,255,227,195,195,195,195,195,195,195,2,14,14,4,1, + 0,192,192,0,0,192,192,192,192,192,192,192,192,192,192,3, + 18,18,4,0,252,96,96,0,0,96,96,96,96,96,96,96, + 96,96,96,96,96,224,192,8,14,14,9,1,0,192,192,192, + 192,198,204,216,240,248,216,204,206,198,199,2,14,14,4,1, + 0,192,192,192,192,192,192,192,192,192,192,192,192,192,192,14, + 10,20,16,1,0,222,120,255,252,227,140,195,12,195,12,195, + 12,195,12,195,12,195,12,195,12,8,10,10,10,1,0,222, + 255,227,195,195,195,195,195,195,195,9,10,20,11,1,0,62, + 0,127,0,99,0,193,128,193,128,193,128,193,128,99,0,127, + 0,62,0,9,14,28,11,1,252,222,0,255,0,227,0,193, + 128,193,128,193,128,193,128,227,0,255,0,222,0,192,0,192, + 0,192,0,192,0,9,14,28,11,1,252,61,128,127,128,99, + 128,193,128,193,128,193,128,193,128,99,128,127,128,61,128,1, + 128,1,128,1,128,1,128,5,10,10,6,1,0,216,216,224, + 192,192,192,192,192,192,192,7,10,10,9,1,0,60,126,198, + 192,252,62,6,198,252,120,6,13,13,6,0,0,48,48,48, + 252,252,48,48,48,48,48,48,60,28,8,10,10,10,1,0, + 195,195,195,195,195,195,195,199,255,123,8,10,10,10,1,0, + 195,195,195,102,102,102,36,60,24,24,12,10,20,14,1,0, + 198,48,198,48,198,48,102,96,102,96,105,96,41,64,57,192, + 25,128,25,128,8,10,10,10,1,0,195,231,102,60,24,24, + 60,102,231,195,8,14,14,10,1,252,195,195,195,102,102,102, + 36,60,24,24,24,24,112,112,7,10,10,9,1,0,254,254, + 6,12,24,48,96,192,254,254,5,18,18,6,0,252,24,48, + 96,96,96,96,96,192,128,192,96,96,96,96,96,96,48,24, + 2,18,18,5,1,252,192,192,192,192,192,192,192,192,192,192, + 192,192,192,192,192,192,192,192,6,18,18,6,0,252,192,96, + 48,48,48,48,48,24,12,24,48,48,48,48,48,48,96,192, + 8,3,3,10,1,4,115,255,206,0,0,0,1,0,0,0, + 0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0, + 0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0, + 1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0, + 0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0, + 0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0, + 1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0, + 0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0, + 0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0, + 1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0, + 0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0, + 0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0, + 1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0, + 0,0,5,0,0,2,14,14,6,2,252,192,192,0,0,64, + 64,192,192,192,192,192,192,192,192,8,14,14,10,1,254,4, + 4,62,127,107,200,200,200,200,107,127,62,16,16,9,13,26, + 10,0,0,30,0,63,0,97,128,97,128,96,0,48,0,126, + 0,24,0,24,0,48,0,96,128,255,128,223,0,8,7,7, + 10,1,3,195,255,102,102,102,255,195,8,13,13,10,1,0, + 195,195,102,102,102,60,255,24,255,24,24,24,24,2,18,18, + 5,1,252,192,192,192,192,192,192,192,0,0,0,0,192,192, + 192,192,192,192,192,8,18,18,10,1,252,60,126,195,195,240, + 124,110,199,195,227,115,62,14,7,195,195,126,60,5,2,2, + 6,0,12,216,216,13,14,28,15,1,0,15,128,48,96,64, + 16,71,16,136,136,144,136,144,8,144,8,144,8,136,136,71, + 16,64,16,48,96,15,128,5,8,8,7,1,6,112,152,56, + 72,216,104,0,248,7,6,6,9,1,2,54,108,216,216,108, + 54,9,5,10,11,1,3,255,128,255,128,1,128,1,128,1, + 128,5,1,1,6,0,5,248,13,14,28,14,0,0,15,128, + 48,96,64,16,79,144,136,72,136,72,136,72,143,136,137,8, + 136,136,72,80,64,16,48,96,15,128,5,1,1,5,0,12, + 248,5,5,5,7,1,8,112,216,136,216,112,8,11,11,10, + 1,0,24,24,24,255,255,24,24,24,0,255,255,5,8,8, + 6,0,5,112,248,152,24,48,96,248,248,5,8,8,6,0, + 5,112,248,152,48,48,152,248,112,4,3,3,4,0,11,48, + 96,192,8,14,14,10,1,252,195,195,195,195,195,195,195,231, + 255,219,192,192,192,192,8,18,18,10,1,252,63,114,242,242, + 242,242,242,114,50,18,18,18,18,18,18,18,18,18,2,2, + 2,4,1,4,192,192,5,5,5,5,0,252,96,112,24,216, + 240,4,8,8,6,0,5,48,240,240,48,48,48,48,48,5, + 8,8,7,1,6,112,216,136,136,216,112,0,248,7,6,6, + 9,1,2,216,108,54,54,108,216,14,13,26,15,0,0,48, + 48,240,48,240,96,48,192,48,192,49,136,49,24,51,56,6, + 120,6,216,12,252,24,24,24,24,14,13,26,15,0,0,48, + 48,240,48,240,96,48,192,48,192,49,184,49,124,51,76,6, + 12,6,24,12,48,24,124,24,124,14,13,26,15,0,0,112, + 48,248,48,152,96,48,192,48,192,153,136,249,24,115,56,6, + 120,6,216,12,252,24,24,24,24,7,14,14,10,1,252,24, + 24,0,0,24,24,24,56,112,224,198,198,254,124,12,16,32, + 13,0,0,6,0,0,0,6,0,6,0,15,0,15,0,25, + 128,25,128,48,192,48,192,63,192,127,224,96,96,96,96,192, + 48,192,48,12,16,32,13,0,0,6,0,0,0,6,0,6, + 0,15,0,15,0,25,128,25,128,48,192,48,192,63,192,127, + 224,96,96,96,96,192,48,192,48,12,16,32,13,0,0,25, + 128,0,0,6,0,6,0,15,0,15,0,25,128,25,128,48, + 192,48,192,63,192,127,224,96,96,96,96,192,48,192,48,12, + 16,32,13,0,0,19,0,0,0,6,0,6,0,15,0,15, + 0,25,128,25,128,48,192,48,192,63,192,127,224,96,96,96, + 96,192,48,192,48,12,16,32,13,0,0,25,128,0,0,6, + 0,6,0,15,0,15,0,25,128,25,128,48,192,48,192,63, + 192,127,224,96,96,96,96,192,48,192,48,12,16,32,13,0, + 0,9,0,9,0,6,0,6,0,15,0,15,0,25,128,25, + 128,48,192,48,192,63,192,127,224,96,96,96,96,192,48,192, + 48,16,14,28,18,1,0,7,255,7,255,13,128,13,128,25, + 128,25,128,49,254,49,254,63,128,127,128,97,128,97,128,193, + 255,193,255,12,18,36,14,1,252,15,128,63,224,112,112,96, + 48,224,0,192,0,192,0,192,0,192,0,224,0,96,48,112, + 112,63,224,15,128,6,0,3,0,27,0,30,0,10,16,32, + 13,2,0,12,0,0,0,255,192,255,192,192,0,192,0,192, + 0,192,0,255,128,255,128,192,0,192,0,192,0,192,0,255, + 192,255,192,10,16,32,13,2,0,12,0,0,0,255,192,255, + 192,192,0,192,0,192,0,192,0,255,128,255,128,192,0,192, + 0,192,0,192,0,255,192,255,192,10,16,32,13,2,0,51, + 0,0,0,255,192,255,192,192,0,192,0,192,0,192,0,255, + 128,255,128,192,0,192,0,192,0,192,0,255,192,255,192,10, + 16,32,13,2,0,51,0,0,0,255,192,255,192,192,0,192, + 0,192,0,192,0,255,128,255,128,192,0,192,0,192,0,192, + 0,255,192,255,192,2,16,16,6,2,0,192,0,192,192,192, + 192,192,192,192,192,192,192,192,192,192,192,2,16,16,6,2, + 0,192,0,192,192,192,192,192,192,192,192,192,192,192,192,192, + 192,6,16,16,6,0,0,132,0,48,48,48,48,48,48,48, + 48,48,48,48,48,48,48,6,16,16,6,0,0,204,0,48, + 48,48,48,48,48,48,48,48,48,48,48,48,48,13,14,28, + 14,0,0,127,192,127,224,96,112,96,48,96,24,96,24,252, + 24,252,24,96,24,96,24,96,48,96,112,127,224,127,192,11, + 16,32,14,1,0,19,0,0,0,192,96,224,96,240,96,240, + 96,216,96,204,96,204,96,198,96,198,96,195,96,193,224,193, + 224,192,224,192,96,13,16,32,15,1,0,6,0,0,0,15, + 128,63,224,112,112,96,48,224,56,192,24,192,24,192,24,192, + 24,224,56,96,48,112,112,63,224,15,128,13,16,32,15,1, + 0,6,0,0,0,15,128,63,224,112,112,96,48,224,56,192, + 24,192,24,192,24,192,24,224,56,96,48,112,112,63,224,15, + 128,13,16,32,15,1,0,12,192,0,0,15,128,63,224,112, + 112,96,48,224,56,192,24,192,24,192,24,192,24,224,56,96, + 48,112,112,63,224,15,128,13,16,32,15,1,0,9,128,0, + 0,15,128,63,224,112,112,96,48,224,56,192,24,192,24,192, + 24,192,24,224,56,96,48,112,112,63,224,15,128,13,16,32, + 15,1,0,12,192,0,0,15,128,63,224,112,112,96,48,224, + 56,192,24,192,24,192,24,192,24,224,56,96,48,112,112,63, + 224,15,128,10,9,18,10,0,0,192,192,97,128,51,0,30, + 0,12,0,30,0,51,0,97,128,192,192,14,14,28,15,0, + 0,7,204,31,248,56,48,48,120,112,220,97,140,99,12,98, + 12,102,12,108,28,56,24,56,56,111,240,199,192,11,16,32, + 14,1,0,6,0,0,0,192,96,192,96,192,96,192,96,192, + 96,192,96,192,96,192,96,192,96,192,96,192,96,96,192,127, + 192,31,0,11,16,32,14,1,0,12,0,0,0,192,96,192, + 96,192,96,192,96,192,96,192,96,192,96,192,96,192,96,192, + 96,192,96,96,192,127,192,31,0,11,16,32,14,1,0,25, + 128,0,0,192,96,192,96,192,96,192,96,192,96,192,96,192, + 96,192,96,192,96,192,96,192,96,96,192,127,192,31,0,11, + 16,32,14,1,0,49,128,0,0,192,96,192,96,192,96,192, + 96,192,96,192,96,192,96,192,96,192,96,192,96,192,96,96, + 192,127,192,31,0,12,16,32,13,0,0,6,0,0,0,192, + 48,192,48,96,96,96,96,48,192,57,192,25,128,15,0,6, + 0,6,0,6,0,6,0,6,0,6,0,10,14,28,12,1, + 0,192,0,192,0,192,0,255,0,255,128,193,192,192,192,192, + 192,193,192,255,128,255,0,192,0,192,0,192,0,7,14,14, + 9,1,0,56,124,198,198,198,198,220,220,198,198,198,198,222, + 220,9,14,28,11,1,0,48,0,24,0,12,0,0,0,126, + 0,231,0,195,0,7,0,127,0,227,0,195,0,195,0,231, + 128,121,128,9,14,28,11,1,0,12,0,24,0,48,0,0, + 0,126,0,231,0,195,0,7,0,127,0,227,0,195,0,195, + 0,231,128,121,128,9,14,28,11,1,0,24,0,60,0,102, + 0,0,0,126,0,231,0,195,0,7,0,127,0,227,0,195, + 0,195,0,231,128,121,128,9,14,28,11,1,0,50,0,90, + 0,76,0,0,0,126,0,231,0,195,0,7,0,127,0,227, + 0,195,0,195,0,231,128,121,128,9,14,28,11,1,0,102, + 0,102,0,0,0,0,0,126,0,231,0,195,0,7,0,127, + 0,227,0,195,0,195,0,231,128,121,128,9,14,28,11,1, + 0,24,0,36,0,36,0,24,0,126,0,231,0,195,0,7, + 0,127,0,227,0,195,0,195,0,231,128,121,128,14,10,20, + 17,2,0,126,240,231,248,195,12,7,12,127,252,227,0,195, + 0,195,140,231,252,122,240,8,14,14,10,1,252,62,127,99, + 192,192,192,192,99,127,62,24,12,108,120,8,14,14,10,1, + 0,48,24,12,0,60,126,195,195,255,192,192,227,127,60,8, + 14,14,10,1,0,12,24,48,0,60,126,195,195,255,192,192, + 227,127,60,8,14,14,10,1,0,24,60,102,0,60,126,195, + 195,255,192,192,227,127,60,8,14,14,10,1,0,102,102,0, + 0,60,126,195,195,255,192,192,227,127,60,4,14,14,4,0, + 0,192,96,48,0,96,96,96,96,96,96,96,96,96,96,4, + 14,14,4,0,0,48,96,192,0,96,96,96,96,96,96,96, + 96,96,96,5,14,14,5,0,0,96,240,152,0,96,96,96, + 96,96,96,96,96,96,96,5,14,14,5,0,0,216,216,0, + 0,96,96,96,96,96,96,96,96,96,96,9,14,28,11,1, + 0,96,0,54,0,56,0,76,0,62,0,127,0,99,0,193, + 128,193,128,193,128,193,128,99,0,127,0,62,0,8,14,14, + 10,1,0,50,90,76,0,222,255,227,195,195,195,195,195,195, + 195,9,14,28,11,1,0,48,0,24,0,12,0,0,0,62, + 0,127,0,99,0,193,128,193,128,193,128,193,128,99,0,127, + 0,62,0,9,14,28,11,1,0,6,0,12,0,24,0,0, + 0,62,0,127,0,99,0,193,128,193,128,193,128,193,128,99, + 0,127,0,62,0,9,14,28,11,1,0,24,0,60,0,102, + 0,0,0,62,0,127,0,99,0,193,128,193,128,193,128,193, + 128,99,0,127,0,62,0,9,14,28,11,1,0,50,0,90, + 0,76,0,0,0,62,0,127,0,99,0,193,128,193,128,193, + 128,193,128,99,0,127,0,62,0,9,14,28,11,1,0,51, + 0,51,0,0,0,0,0,62,0,127,0,99,0,193,128,193, + 128,193,128,193,128,99,0,127,0,62,0,8,8,8,10,1, + 1,24,24,0,255,255,0,24,24,11,10,20,11,0,0,14, + 96,63,192,49,128,99,192,102,192,108,192,120,192,49,128,127, + 128,206,0,8,14,14,10,1,0,48,24,12,0,195,195,195, + 195,195,195,195,199,255,123,8,14,14,10,1,0,6,12,24, + 0,195,195,195,195,195,195,195,199,255,123,8,14,14,10,1, + 0,24,60,102,0,195,195,195,195,195,195,195,199,255,123,8, + 14,14,10,1,0,102,102,0,0,195,195,195,195,195,195,195, + 199,255,123,8,18,18,10,1,252,6,12,24,0,195,195,195, + 102,102,102,36,60,24,24,24,24,112,112,9,18,36,11,1, + 252,192,0,192,0,192,0,192,0,222,0,255,0,227,0,193, + 128,193,128,193,128,193,128,227,0,255,0,222,0,192,0,192, + 0,192,0,192,0,8,18,18,10,1,252,102,102,0,0,195, + 195,195,102,102,102,36,60,24,24,24,24,112,112 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/fontdata/helvetica_18.cpp b/Marlin/src/lcd/tft/fontdata/helvetica_18.cpp new file mode 100644 index 000000000000..bb5f6ccf40f8 --- /dev/null +++ b/Marlin/src/lcd/tft/fontdata/helvetica_18.cpp @@ -0,0 +1,492 @@ +/* + Fontname: -Adobe-Helvetica-Medium-R-Normal--25-180-100-100-P-130-ISO10646-1 + Copyright: Copyright (c) 1984, 1987 Adobe Systems Incorporated. All Rights Reserved. Copyright (c) 1988, 1991 Digital Equipment Corporation. All Rights Reserved. + Capital A Height: 19, '1' Height: 18 + Calculated Max Values w=22 h=24 x= 3 y=16 dx=25 dy= 0 ascent=24 len=69 + Font Bounding box w=28 h=37 x=-3 y=-8 + Calculated Min Values x=-1 y=-5 dx= 0 dy= 0 + Pure Font ascent =19 descent=-5 + X Font ascent =19 descent=-5 + Max Font ascent =24 descent=-5 +*/ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +#include + +extern const uint8_t Helvetica18_symbols[71] = { + 0,28,37,253,248,19,4,37,9,49,1,9,251,24,251,19,251, // tFont + 0,0,0,0,0,0, // 0x01 - LCD_STR_REFRESH + 0,0,0,0,0,0, // 0x02 - LCD_STR_FOLDER + 255, // 0x03 - LCD_STR_ARROW_RIGHT + 255, // 0x04 - LCD_STR_UPLEVEL + 255, // 0x05 - LCD_STR_CLOCK + 255, // 0x06 - LCD_STR_FEEDRATE + 255, // 0x07 - LCD_STR_BEDTEMP + 7,18,18,8,0,1, 0,56, 68,68,68,68,68,84,84,84,84,84, 214,186,186,186,198,124, // 0x08 - LCD_STR_THERMOMETER + 7,7,7,7,0,15,56,124,198,198,198,124,56, // 0x09 - LCD_STR_DEGREE +}; + +extern const uint8_t Helvetica18[7307] = { + 0,28,37,253,248,19,4,37,9,49,32,255,251,24,251,19,251, // tFont + 0,0,0,6,0,1,2,19,19,6,2,0,192,192,192, + 192,192,192,192,192,192,192,192,192,128,128,0,0,192,192,192, + 6,6,6,8,1,13,204,204,204,204,204,68,11,17,34,14, + 2,0,12,192,12,192,12,192,25,128,255,224,255,224,25,128, + 25,128,51,0,51,0,255,224,255,224,51,0,51,0,102,0, + 102,0,102,0,11,22,44,13,1,254,6,0,6,0,31,128, + 63,192,118,224,102,96,102,96,102,0,118,0,62,0,62,0, + 15,128,7,192,6,224,6,96,198,96,198,96,230,224,127,192, + 63,128,6,0,6,0,19,18,54,22,1,0,0,6,0,60, + 12,0,126,12,0,195,24,0,195,24,0,195,48,0,195,48, + 0,126,96,0,60,96,0,0,192,0,0,199,128,1,143,192, + 1,152,96,3,24,96,3,24,96,6,24,96,6,15,192,4, + 7,128,14,18,36,17,2,0,15,0,31,128,57,192,48,192, + 48,192,48,192,25,128,15,0,30,0,63,24,115,152,97,216, + 192,240,192,96,192,240,225,216,127,156,30,0,2,6,6,6, + 2,13,192,192,192,192,192,64,5,24,24,8,2,251,24,24, + 48,48,96,96,96,192,192,192,192,192,192,192,192,192,192,96, + 96,96,48,48,24,24,5,24,24,8,1,251,192,192,96,96, + 48,48,48,24,24,24,24,24,24,24,24,24,24,48,48,48, + 96,96,192,192,7,7,7,10,1,12,16,16,214,124,56,108, + 68,12,12,24,14,1,1,6,0,6,0,6,0,6,0,6, + 0,255,240,255,240,6,0,6,0,6,0,6,0,6,0,2, + 6,6,6,2,253,192,192,192,64,64,128,6,2,2,8,1, + 6,252,252,2,3,3,6,2,0,192,192,192,7,19,19,7, + 0,0,6,4,12,12,8,24,24,16,16,48,48,32,96,96, + 64,192,192,128,128,11,18,36,13,1,0,31,0,63,128,113, + 192,96,192,96,192,224,224,192,96,192,96,192,96,192,96,192, + 96,192,96,224,224,96,192,96,192,113,192,63,128,31,0,6, + 18,18,13,2,0,12,12,28,252,252,12,12,12,12,12,12, + 12,12,12,12,12,12,12,11,18,36,13,1,0,30,0,127, + 128,97,192,192,192,192,96,192,96,0,224,0,192,1,192,3, + 128,15,0,28,0,56,0,112,0,224,0,192,0,255,224,255, + 224,11,18,36,13,1,0,31,0,127,128,97,128,192,192,192, + 192,192,192,0,192,1,128,15,0,15,192,0,192,0,96,0, + 96,192,96,192,192,97,192,127,128,31,0,11,18,36,13,1, + 0,1,128,3,128,3,128,7,128,15,128,13,128,25,128,57, + 128,49,128,97,128,225,128,193,128,255,224,255,224,1,128,1, + 128,1,128,1,128,11,18,36,13,1,0,127,192,127,192,96, + 0,96,0,96,0,96,0,126,0,127,128,113,192,0,192,0, + 224,0,96,0,96,192,224,192,192,225,192,127,128,30,0,11, + 18,36,13,1,0,15,0,63,192,112,192,96,96,224,96,192, + 0,192,0,207,0,223,128,241,192,224,192,192,96,192,96,192, + 96,224,224,113,192,127,192,31,0,11,18,36,13,1,0,255, + 224,255,224,0,224,0,192,1,128,1,128,3,0,3,0,6, + 0,6,0,12,0,12,0,28,0,24,0,24,0,56,0,48, + 0,48,0,11,18,36,13,1,0,14,0,63,128,49,128,96, + 192,96,192,96,192,49,128,31,0,63,128,113,192,96,192,192, + 96,192,96,192,96,192,96,96,192,127,192,31,0,11,18,36, + 13,1,0,31,0,127,192,113,192,224,192,192,96,192,96,192, + 96,192,96,224,224,113,224,127,96,30,96,0,96,0,224,192, + 192,225,192,127,128,30,0,2,14,14,6,2,0,192,192,192, + 0,0,0,0,0,0,0,0,192,192,192,2,17,17,6,2, + 253,192,192,192,0,0,0,0,0,0,0,0,192,192,192,64, + 64,128,12,12,24,15,1,1,0,48,0,240,3,192,15,0, + 60,0,224,0,224,0,60,0,15,0,3,192,0,240,0,48, + 10,5,10,15,2,5,255,192,255,192,0,0,255,192,255,192, + 12,12,24,15,1,1,192,0,240,0,60,0,15,0,3,192, + 0,112,0,112,3,192,15,0,60,0,240,0,192,0,10,19, + 38,12,1,0,31,0,127,128,113,192,224,192,192,192,193,192, + 1,128,3,128,7,0,6,0,12,0,12,0,12,0,12,0, + 0,0,0,0,12,0,12,0,12,0,22,23,69,25,2,252, + 0,255,0,3,255,192,15,1,224,28,0,112,56,0,24,48, + 0,24,96,115,12,96,251,12,193,199,12,195,134,12,195,6, + 12,198,6,12,198,12,28,198,12,24,198,12,56,231,28,112, + 99,247,224,113,227,128,56,0,0,28,0,0,15,3,0,7, + 255,0,0,252,0,15,19,38,17,1,0,3,128,3,128,6, + 192,6,192,12,64,12,96,12,96,24,48,24,48,24,48,48, + 24,63,248,63,248,96,12,96,12,96,12,192,6,192,6,192, + 6,14,19,38,17,2,0,255,192,255,240,192,112,192,24,192, + 24,192,24,192,24,192,48,255,224,255,240,192,24,192,12,192, + 12,192,12,192,12,192,28,192,120,255,240,255,192,15,19,38, + 18,1,0,7,224,31,248,60,60,112,14,96,6,224,6,192, + 0,192,0,192,0,192,0,192,0,192,0,192,0,224,6,96, + 6,112,14,60,60,31,248,7,224,15,19,38,18,2,0,255, + 192,255,240,192,120,192,28,192,12,192,14,192,6,192,6,192, + 6,192,6,192,6,192,6,192,6,192,14,192,12,192,28,192, + 120,255,240,255,192,12,19,38,16,2,0,255,240,255,240,192, + 0,192,0,192,0,192,0,192,0,192,0,255,224,255,224,192, + 0,192,0,192,0,192,0,192,0,192,0,192,0,255,240,255, + 240,11,19,38,14,2,0,255,224,255,224,192,0,192,0,192, + 0,192,0,192,0,192,0,255,192,255,192,192,0,192,0,192, + 0,192,0,192,0,192,0,192,0,192,0,192,0,16,19,38, + 19,1,0,7,224,31,248,60,60,112,14,96,6,224,6,192, + 0,192,0,192,0,192,127,192,127,192,3,192,3,224,3,96, + 7,112,15,60,63,31,251,7,227,14,19,38,18,2,0,192, + 12,192,12,192,12,192,12,192,12,192,12,192,12,192,12,255, + 252,255,252,192,12,192,12,192,12,192,12,192,12,192,12,192, + 12,192,12,192,12,2,19,19,8,3,0,192,192,192,192,192, + 192,192,192,192,192,192,192,192,192,192,192,192,192,192,10,19, + 38,13,1,0,0,192,0,192,0,192,0,192,0,192,0,192, + 0,192,0,192,0,192,0,192,0,192,0,192,192,192,192,192, + 192,192,192,192,97,128,127,128,63,0,13,19,38,18,3,0, + 192,56,192,112,192,224,193,192,195,128,199,0,206,0,220,0, + 252,0,254,0,231,0,195,128,193,128,193,192,192,224,192,96, + 192,112,192,56,192,24,11,19,38,14,2,0,192,0,192,0, + 192,0,192,0,192,0,192,0,192,0,192,0,192,0,192,0, + 192,0,192,0,192,0,192,0,192,0,192,0,192,0,255,224, + 255,224,17,19,57,21,2,0,192,1,128,224,3,128,224,3, + 128,240,7,128,240,7,128,216,13,128,216,13,128,216,13,128, + 204,25,128,204,25,128,204,25,128,198,49,128,198,49,128,198, + 49,128,195,97,128,195,97,128,195,97,128,193,193,128,193,193, + 128,14,19,38,18,2,0,224,12,240,12,240,12,216,12,220, + 12,204,12,206,12,198,12,199,12,195,12,195,140,193,140,193, + 204,192,204,192,236,192,108,192,60,192,60,192,28,16,19,38, + 18,1,0,7,224,31,248,60,60,112,14,96,6,224,7,192, + 3,192,3,192,3,192,3,192,3,192,3,192,3,224,7,96, + 6,112,14,60,60,31,248,7,224,13,19,38,16,2,0,255, + 224,255,240,192,48,192,24,192,24,192,24,192,24,192,48,255, + 240,255,224,192,0,192,0,192,0,192,0,192,0,192,0,192, + 0,192,0,192,0,16,19,38,18,1,0,7,224,31,248,60, + 60,112,14,96,6,224,7,192,3,192,3,192,3,192,3,192, + 3,192,3,192,3,224,7,96,230,112,126,60,28,31,254,7, + 231,13,19,38,17,2,0,255,224,255,240,192,48,192,24,192, + 24,192,24,192,24,192,48,255,240,255,224,192,112,192,48,192, + 24,192,24,192,24,192,24,192,24,192,24,192,24,13,19,38, + 16,2,0,15,128,63,224,96,96,192,48,192,48,192,0,224, + 0,124,0,63,128,7,224,0,240,0,56,0,24,0,24,192, + 24,192,56,240,112,127,224,31,128,14,19,38,16,1,0,255, + 252,255,252,3,0,3,0,3,0,3,0,3,0,3,0,3, + 0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3, + 0,3,0,3,0,14,19,38,18,2,0,192,12,192,12,192, + 12,192,12,192,12,192,12,192,12,192,12,192,12,192,12,192, + 12,192,12,192,12,192,12,192,12,96,24,112,56,63,240,15, + 192,15,19,38,17,1,0,192,6,192,6,224,14,96,12,112, + 28,48,24,48,24,56,56,24,48,24,48,28,112,12,96,12, + 96,14,224,6,192,6,192,3,128,3,128,3,128,20,19,57, + 22,1,0,192,96,48,192,96,48,192,96,48,192,240,48,96, + 240,96,97,152,96,97,152,96,97,152,96,97,152,96,49,152, + 192,51,12,192,51,12,192,51,12,192,27,13,128,27,13,128, + 30,7,128,14,7,0,12,3,0,12,3,0,15,19,38,17, + 1,0,192,6,224,14,112,28,48,24,24,48,28,112,14,224, + 7,192,3,128,3,128,7,192,14,224,12,96,28,112,56,56, + 48,24,96,12,224,14,192,6,14,19,38,16,1,0,192,12, + 224,28,96,24,112,56,48,48,56,112,24,96,28,224,12,192, + 15,192,7,128,7,128,3,0,3,0,3,0,3,0,3,0, + 3,0,3,0,13,19,38,15,1,0,255,248,255,248,0,56, + 0,112,0,224,1,192,1,192,3,128,7,0,7,0,14,0, + 28,0,28,0,56,0,112,0,112,0,224,0,255,248,255,248, + 4,24,24,7,2,251,240,240,192,192,192,192,192,192,192,192, + 192,192,192,192,192,192,192,192,192,192,192,192,240,240,8,19, + 19,7,0,0,192,64,64,96,32,32,48,16,16,16,24,8, + 8,12,4,4,6,2,3,4,24,24,7,1,251,240,240,48, + 48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48, + 48,48,48,240,240,10,9,18,12,1,10,12,0,12,0,30, + 0,18,0,51,0,97,128,97,128,192,192,192,192,14,2,4, + 14,0,251,255,252,255,252,5,4,4,7,1,15,192,96,48, + 24,11,14,28,13,1,0,31,0,63,128,97,192,96,192,0, + 192,7,192,63,192,120,192,224,192,192,192,193,192,227,192,126, + 224,60,96,11,19,38,14,2,0,192,0,192,0,192,0,192, + 0,192,0,207,0,223,128,241,192,224,192,192,224,192,96,192, + 96,192,96,192,96,192,224,224,192,241,192,223,128,207,0,10, + 14,28,12,1,0,31,0,63,128,113,192,96,192,224,0,192, + 0,192,0,192,0,192,0,224,0,96,192,113,192,63,128,31, + 0,11,19,38,14,1,0,0,96,0,96,0,96,0,96,0, + 96,30,96,63,96,113,224,96,224,224,96,192,96,192,96,192, + 96,192,96,224,96,96,224,113,224,63,96,30,96,11,14,28, + 13,1,0,14,0,63,128,113,192,96,192,192,96,192,96,255, + 224,255,224,192,0,192,0,96,96,112,224,63,192,15,0,6, + 19,19,8,1,0,28,60,48,48,48,252,252,48,48,48,48, + 48,48,48,48,48,48,48,48,11,19,38,14,1,251,30,96, + 63,96,113,224,96,224,224,96,192,96,192,96,192,96,192,96, + 224,96,96,224,113,224,63,96,30,96,0,96,192,96,224,192, + 127,192,31,0,10,19,38,13,2,0,192,0,192,0,192,0, + 192,0,192,0,206,0,223,128,241,128,224,192,192,192,192,192, + 192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, + 2,19,19,6,2,0,192,192,192,0,0,192,192,192,192,192, + 192,192,192,192,192,192,192,192,192,4,24,24,6,0,251,48, + 48,48,0,0,48,48,48,48,48,48,48,48,48,48,48,48, + 48,48,48,48,48,240,224,10,19,38,12,2,0,192,0,192, + 0,192,0,192,0,192,0,193,128,195,128,199,0,206,0,220, + 0,248,0,252,0,206,0,198,0,199,0,195,128,193,128,193, + 192,192,192,2,19,19,6,2,0,192,192,192,192,192,192,192, + 192,192,192,192,192,192,192,192,192,192,192,192,16,14,28,20, + 2,0,206,60,255,126,227,199,193,131,193,131,193,131,193,131, + 193,131,193,131,193,131,193,131,193,131,193,131,193,131,10,14, + 28,14,2,0,206,0,223,128,241,128,224,192,192,192,192,192, + 192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, + 11,14,28,13,1,0,31,0,63,128,113,192,96,192,224,224, + 192,96,192,96,192,96,192,96,224,224,96,192,113,192,63,128, + 31,0,11,19,38,14,2,251,207,0,223,128,241,192,224,192, + 192,224,192,96,192,96,192,96,192,96,192,224,224,192,241,192, + 223,128,207,0,192,0,192,0,192,0,192,0,192,0,11,19, + 38,14,1,251,30,96,63,96,113,224,96,224,224,96,192,96, + 192,96,192,96,192,96,224,96,96,224,113,224,63,96,30,96, + 0,96,0,96,0,96,0,96,0,96,6,14,14,9,2,0, + 204,220,248,240,224,192,192,192,192,192,192,192,192,192,10,14, + 28,12,1,0,63,0,127,128,225,192,192,192,192,0,248,0, + 127,0,15,128,1,192,192,192,192,192,225,192,127,128,63,0, + 6,18,18,8,1,0,48,48,48,48,252,252,48,48,48,48, + 48,48,48,48,48,48,60,28,10,14,28,14,2,0,192,192, + 192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, + 192,192,193,192,99,192,126,192,28,192,11,14,28,13,1,0, + 192,96,192,96,192,96,96,192,96,192,113,192,49,128,49,128, + 27,0,27,0,27,0,14,0,14,0,14,0,18,14,42,18, + 0,0,192,192,192,192,192,192,97,225,128,97,225,128,97,225, + 128,49,35,0,51,51,0,51,51,0,27,54,0,26,22,0, + 30,30,0,14,28,0,12,12,0,12,12,0,10,14,28,12, + 1,0,192,192,225,192,97,128,51,0,30,0,30,0,12,0, + 30,0,30,0,51,0,115,128,97,128,192,192,192,192,12,19, + 38,13,0,251,192,48,192,48,96,48,112,96,48,96,56,224, + 24,192,24,192,13,128,13,128,7,128,7,0,3,0,3,0, + 6,0,6,0,12,0,60,0,56,0,10,14,28,12,1,0, + 255,192,255,192,1,128,3,0,7,0,14,0,12,0,28,0, + 56,0,48,0,96,0,224,0,255,192,255,192,6,24,24,8, + 1,251,12,24,48,48,48,48,48,48,48,48,96,192,192,96, + 48,48,48,48,48,48,48,48,24,12,1,24,24,6,2,251, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,6,24,24,8,1,251,192,96, + 48,48,48,48,48,48,48,48,24,12,12,24,48,48,48,48, + 48,48,48,48,96,192,10,4,8,14,2,5,112,192,252,192, + 207,192,195,128,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,0,0,0,6,0,1,2,19,19,6,2, + 251,192,192,192,0,0,64,64,192,192,192,192,192,192,192,192, + 192,192,192,192,10,18,36,13,1,254,1,128,1,128,31,0, + 63,128,115,192,102,192,198,0,204,0,204,0,204,0,216,0, + 216,0,216,192,113,192,127,128,63,0,96,0,96,0,12,18, + 36,14,1,0,31,128,63,224,112,112,96,48,96,0,112,0, + 48,0,24,0,255,128,255,128,24,0,24,0,24,0,48,0, + 48,0,103,48,255,240,240,224,11,12,24,13,1,3,192,96, + 238,224,127,192,49,128,96,192,96,192,96,192,96,192,49,128, + 127,192,238,224,192,96,14,18,36,14,0,0,224,28,96,24, + 112,56,48,48,56,112,24,96,28,224,12,192,63,240,63,240, + 3,0,63,240,63,240,3,0,3,0,3,0,3,0,3,0, + 2,24,24,6,2,251,192,192,192,192,192,192,192,192,192,192, + 0,0,0,0,192,192,192,192,192,192,192,192,192,192,11,24, + 48,13,1,251,31,0,63,128,113,192,96,192,112,192,56,0, + 28,0,126,0,231,0,195,128,193,192,192,192,96,96,112,96, + 56,96,28,192,15,128,7,0,3,128,97,192,96,192,113,192, + 63,128,31,0,6,2,2,8,1,16,204,204,19,19,57,19, + 1,0,3,248,0,14,14,0,48,1,128,96,0,192,65,240, + 64,195,24,96,134,12,32,132,0,32,132,0,32,132,0,32, + 132,0,32,134,12,32,195,24,96,65,240,64,96,0,192,48, + 1,128,24,3,0,14,14,0,3,248,0,7,12,12,9,1, + 7,120,204,204,28,108,204,204,220,118,0,254,254,9,8,16, + 14,2,3,25,128,51,0,102,0,204,0,204,0,102,0,51, + 0,25,128,13,8,16,15,1,2,255,248,255,248,0,24,0, + 24,0,24,0,24,0,24,0,24,6,2,2,8,1,6,252, + 252,18,19,57,19,1,0,7,248,0,28,14,0,48,3,0, + 96,1,128,67,240,128,194,24,192,130,8,64,130,8,64,130, + 8,64,130,16,64,131,240,64,130,32,64,130,16,64,194,16, + 192,66,8,128,96,1,128,48,3,0,28,14,0,7,248,0, + 6,2,2,8,1,16,252,252,8,7,7,9,0,11,60,102, + 195,195,195,102,60,12,13,26,14,1,0,6,0,6,0,6, + 0,6,0,255,240,255,240,6,0,6,0,6,0,6,0,0, + 0,255,240,255,240,7,10,10,7,0,8,60,126,198,6,12, + 24,48,96,254,254,7,10,10,7,0,8,124,254,198,6,60, + 60,6,198,254,124,5,4,4,7,1,15,24,48,96,192,10, + 19,38,14,2,251,192,192,192,192,192,192,192,192,192,192,192, + 192,192,192,192,192,192,192,192,192,193,192,227,192,254,192,220, + 192,192,0,192,0,192,0,192,0,192,0,10,24,48,12,1, + 251,31,192,127,192,125,128,253,128,253,128,253,128,253,128,253, + 128,253,128,125,128,125,128,61,128,13,128,13,128,13,128,13, + 128,13,128,13,128,13,128,13,128,13,128,13,128,13,128,13, + 128,2,3,3,6,2,6,192,192,192,5,6,6,7,1,251, + 96,112,24,24,248,112,4,10,10,7,0,8,48,48,240,240, + 48,48,48,48,48,48,7,12,12,9,1,7,56,108,198,198, + 198,198,198,108,56,0,254,254,9,8,16,14,3,3,204,0, + 102,0,51,0,25,128,25,128,51,0,102,0,204,0,18,18, + 54,19,1,0,48,24,0,48,24,0,240,48,0,240,48,0, + 48,96,0,48,96,0,48,192,0,48,192,0,49,131,0,49, + 135,0,3,15,0,3,15,0,6,27,0,6,51,0,12,127, + 192,12,127,192,24,3,0,24,3,0,18,18,54,19,1,0, + 48,24,0,48,24,0,240,48,0,240,48,0,48,96,0,48, + 96,0,48,192,0,48,192,0,49,135,128,49,143,192,3,24, + 192,3,0,192,6,1,128,6,3,0,12,6,0,12,12,0, + 24,31,192,24,31,192,19,18,54,19,0,0,124,12,0,254, + 12,0,198,24,0,6,24,0,60,48,0,60,48,0,6,96, + 0,198,96,0,254,193,128,124,195,128,1,135,128,1,135,128, + 3,13,128,3,25,128,6,63,224,6,63,224,12,1,128,12, + 1,128,10,19,38,12,1,251,12,0,12,0,12,0,0,0, + 0,0,12,0,12,0,12,0,12,0,24,0,56,0,112,0, + 96,0,224,192,192,192,193,192,227,128,127,128,62,0,15,24, + 48,17,1,0,12,0,6,0,3,0,1,128,0,0,3,128, + 3,128,6,192,6,192,12,64,12,96,12,96,24,48,24,48, + 24,48,48,24,63,248,63,248,96,12,96,12,96,12,192,6, + 192,6,192,6,15,24,48,17,1,0,0,96,0,192,1,128, + 3,0,0,0,3,128,3,128,6,192,6,192,12,64,12,96, + 12,96,24,48,24,48,24,48,48,24,63,248,63,248,96,12, + 96,12,96,12,192,6,192,6,192,6,15,24,48,17,1,0, + 1,128,3,192,6,96,12,48,0,0,3,128,3,128,6,192, + 6,192,12,64,12,96,12,96,24,48,24,48,24,48,48,24, + 63,248,63,248,96,12,96,12,96,12,192,6,192,6,192,6, + 15,23,46,17,1,0,7,16,13,176,8,224,0,0,3,128, + 3,128,6,192,6,192,12,64,12,96,12,96,24,48,24,48, + 24,48,48,24,63,248,63,248,96,12,96,12,96,12,192,6, + 192,6,192,6,15,23,46,17,1,0,12,96,12,96,0,0, + 0,0,3,128,3,128,6,192,6,192,12,64,12,96,12,96, + 24,48,24,48,24,48,48,24,63,248,63,248,96,12,96,12, + 96,12,192,6,192,6,192,6,15,24,48,17,1,0,3,128, + 4,64,4,64,3,128,0,0,3,128,3,128,6,192,6,192, + 12,64,12,96,12,96,24,48,24,48,24,48,48,24,63,248, + 63,248,96,12,96,12,96,12,192,6,192,6,192,6,21,19, + 57,23,1,0,3,255,248,3,255,248,6,96,0,6,96,0, + 12,96,0,12,96,0,12,96,0,24,96,0,24,127,248,24, + 127,248,48,96,0,63,224,0,63,224,0,96,96,0,96,96, + 0,96,96,0,192,96,0,192,127,248,192,127,248,15,24,48, + 18,1,251,7,224,31,248,60,60,112,14,96,6,224,6,192, + 0,192,0,192,0,192,0,192,0,192,0,192,0,224,6,96, + 6,112,14,60,60,31,248,7,224,1,128,0,192,0,192,7, + 192,3,128,12,24,48,16,2,0,48,0,24,0,12,0,6, + 0,0,0,255,240,255,240,192,0,192,0,192,0,192,0,192, + 0,192,0,255,224,255,224,192,0,192,0,192,0,192,0,192, + 0,192,0,192,0,255,240,255,240,12,24,48,16,2,0,1, + 128,3,0,6,0,12,0,0,0,255,240,255,240,192,0,192, + 0,192,0,192,0,192,0,192,0,255,224,255,224,192,0,192, + 0,192,0,192,0,192,0,192,0,192,0,255,240,255,240,12, + 24,48,16,2,0,6,0,15,0,25,128,48,192,0,0,255, + 240,255,240,192,0,192,0,192,0,192,0,192,0,192,0,255, + 224,255,224,192,0,192,0,192,0,192,0,192,0,192,0,192, + 0,255,240,255,240,12,23,46,16,2,0,24,192,24,192,0, + 0,0,0,255,240,255,240,192,0,192,0,192,0,192,0,192, + 0,192,0,255,224,255,224,192,0,192,0,192,0,192,0,192, + 0,192,0,192,0,255,240,255,240,5,24,24,8,1,0,192, + 96,48,24,0,48,48,48,48,48,48,48,48,48,48,48,48, + 48,48,48,48,48,48,48,5,24,24,8,2,0,24,48,96, + 192,0,96,96,96,96,96,96,96,96,96,96,96,96,96,96, + 96,96,96,96,96,8,24,24,8,0,0,24,60,102,195,0, + 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24, + 24,24,24,6,23,23,8,1,0,204,204,0,0,48,48,48, + 48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48, + 18,19,57,18,255,0,31,248,0,31,254,0,24,15,0,24, + 3,128,24,1,128,24,1,192,24,0,192,24,0,192,255,128, + 192,255,128,192,24,0,192,24,0,192,24,0,192,24,1,192, + 24,1,128,24,3,128,24,15,0,31,254,0,31,248,0,14, + 23,46,18,2,0,14,32,27,96,17,192,0,0,224,12,240, + 12,240,12,216,12,220,12,204,12,206,12,198,12,199,12,195, + 12,195,140,193,140,193,204,192,204,192,236,192,108,192,60,192, + 60,192,28,16,24,48,18,1,0,12,0,6,0,3,0,1, + 128,0,0,7,224,31,248,60,60,112,14,96,6,224,7,192, + 3,192,3,192,3,192,3,192,3,192,3,192,3,224,7,96, + 6,112,14,60,60,31,248,7,224,16,24,48,18,1,0,0, + 48,0,96,0,192,1,128,0,0,7,224,31,248,60,60,112, + 14,96,6,224,7,192,3,192,3,192,3,192,3,192,3,192, + 3,192,3,224,7,96,6,112,14,60,60,31,248,7,224,16, + 24,48,18,1,0,0,192,1,224,3,48,6,24,0,0,7, + 224,31,248,60,60,112,14,96,6,224,7,192,3,192,3,192, + 3,192,3,192,3,192,3,192,3,224,7,96,6,112,14,60, + 60,31,248,7,224,16,23,46,18,1,0,3,136,6,216,4, + 112,0,0,7,224,31,248,60,60,112,14,96,6,224,7,192, + 3,192,3,192,3,192,3,192,3,192,3,192,3,224,7,96, + 6,112,14,60,60,31,248,7,224,16,23,46,18,1,0,6, + 48,6,48,0,0,0,0,7,224,31,248,60,60,112,14,96, + 6,224,7,192,3,192,3,192,3,192,3,192,3,192,3,192, + 3,224,7,96,6,112,14,60,60,31,248,7,224,13,12,24, + 14,0,1,192,24,96,48,48,96,24,192,13,128,7,0,7, + 0,13,128,24,192,48,96,96,48,192,24,18,19,57,18,0, + 0,3,240,192,15,253,192,30,31,128,56,7,0,48,15,0, + 112,29,128,96,57,128,96,113,128,96,225,128,97,193,128,99, + 129,128,103,1,128,110,1,128,124,3,128,56,3,0,56,7, + 0,126,30,0,239,252,0,195,240,0,14,24,48,18,2,0, + 24,0,12,0,6,0,3,0,0,0,192,12,192,12,192,12, + 192,12,192,12,192,12,192,12,192,12,192,12,192,12,192,12, + 192,12,192,12,192,12,192,12,96,24,112,56,63,240,15,192, + 14,24,48,18,2,0,0,96,0,192,1,128,3,0,0,0, + 192,12,192,12,192,12,192,12,192,12,192,12,192,12,192,12, + 192,12,192,12,192,12,192,12,192,12,192,12,192,12,96,24, + 112,56,63,240,15,192,14,24,48,18,2,0,3,0,7,128, + 12,192,24,96,0,0,192,12,192,12,192,12,192,12,192,12, + 192,12,192,12,192,12,192,12,192,12,192,12,192,12,192,12, + 192,12,192,12,96,24,112,56,63,240,15,192,14,23,46,18, + 2,0,24,192,24,192,0,0,0,0,192,12,192,12,192,12, + 192,12,192,12,192,12,192,12,192,12,192,12,192,12,192,12, + 192,12,192,12,192,12,192,12,96,24,112,56,63,240,15,192, + 14,24,48,16,1,0,0,96,0,192,1,128,3,0,0,0, + 192,12,224,28,96,24,112,56,48,48,56,112,24,96,28,224, + 12,192,15,192,7,128,7,128,3,0,3,0,3,0,3,0, + 3,0,3,0,3,0,13,19,38,16,2,0,192,0,192,0, + 192,0,192,0,255,224,255,240,192,48,192,24,192,24,192,24, + 192,24,192,48,255,240,255,224,192,0,192,0,192,0,192,0, + 192,0,10,19,38,15,3,0,28,0,127,0,227,0,193,128, + 193,128,193,128,195,0,199,0,206,0,207,0,195,128,193,128, + 192,192,192,192,192,192,193,128,195,128,207,0,206,0,11,19, + 38,13,1,0,24,0,12,0,6,0,3,0,0,0,31,0, + 63,128,97,192,96,192,0,192,7,192,63,192,120,192,224,192, + 192,192,193,192,227,192,126,224,60,96,11,19,38,13,1,0, + 1,128,3,0,6,0,12,0,0,0,31,0,63,128,97,192, + 96,192,0,192,7,192,63,192,120,192,224,192,192,192,193,192, + 227,192,126,224,60,96,11,19,38,13,1,0,12,0,30,0, + 51,0,97,128,0,0,31,0,63,128,97,192,96,192,0,192, + 7,192,63,192,120,192,224,192,192,192,193,192,227,192,126,224, + 60,96,11,18,36,13,1,0,28,64,54,192,35,128,0,0, + 31,0,63,128,97,192,96,192,0,192,7,192,63,192,120,192, + 224,192,192,192,193,192,227,192,126,224,60,96,11,18,36,13, + 1,0,51,0,51,0,0,0,0,0,31,0,63,128,97,192, + 96,192,0,192,7,192,63,192,120,192,224,192,192,192,193,192, + 227,192,126,224,60,96,11,19,38,13,1,0,6,0,9,0, + 9,0,6,0,0,0,31,0,63,128,97,192,96,192,0,192, + 7,192,63,192,120,192,224,192,192,192,193,192,227,192,126,224, + 60,96,19,14,42,21,1,0,31,14,0,63,191,128,97,241, + 192,96,224,192,0,192,96,7,192,96,63,255,224,120,255,224, + 224,192,0,192,192,0,193,224,96,227,240,224,126,63,192,60, + 15,0,10,19,38,12,1,251,31,0,63,128,113,192,96,192, + 224,0,192,0,192,0,192,0,192,0,224,0,96,192,113,192, + 63,128,31,0,12,0,6,0,6,0,62,0,28,0,11,19, + 38,13,1,0,24,0,12,0,6,0,3,0,0,0,14,0, + 63,128,113,192,96,192,192,96,192,96,255,224,255,224,192,0, + 192,0,96,96,112,224,63,192,15,0,11,19,38,13,1,0, + 3,0,6,0,12,0,24,0,0,0,14,0,63,128,113,192, + 96,192,192,96,192,96,255,224,255,224,192,0,192,0,96,96, + 112,224,63,192,15,0,11,19,38,13,1,0,12,0,30,0, + 51,0,97,128,0,0,14,0,63,128,113,192,96,192,192,96, + 192,96,255,224,255,224,192,0,192,0,96,96,112,224,63,192, + 15,0,11,18,36,13,1,0,51,0,51,0,0,0,0,0, + 14,0,63,128,113,192,96,192,192,96,192,96,255,224,255,224, + 192,0,192,0,96,96,112,224,63,192,15,0,5,19,19,6, + 0,0,192,96,48,24,0,48,48,48,48,48,48,48,48,48, + 48,48,48,48,48,5,19,19,6,1,0,24,48,96,192,0, + 96,96,96,96,96,96,96,96,96,96,96,96,96,96,8,19, + 19,6,255,0,24,60,102,195,0,24,24,24,24,24,24,24, + 24,24,24,24,24,24,24,6,18,18,6,0,0,204,204,0, + 0,48,48,48,48,48,48,48,48,48,48,48,48,48,48,11, + 19,38,13,1,0,96,0,57,128,14,0,30,0,99,0,31, + 128,63,128,113,192,96,192,224,224,192,96,192,96,192,96,192, + 96,224,224,96,192,113,192,63,128,31,0,10,18,36,14,2, + 0,56,128,109,128,71,0,0,0,206,0,223,128,241,128,224, + 192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, + 192,192,192,192,192,11,19,38,13,1,0,24,0,12,0,6, + 0,3,0,0,0,31,0,63,128,113,192,96,192,224,224,192, + 96,192,96,192,96,192,96,224,224,96,192,113,192,63,128,31, + 0,11,19,38,13,1,0,3,0,6,0,12,0,24,0,0, + 0,31,0,63,128,113,192,96,192,224,224,192,96,192,96,192, + 96,192,96,224,224,96,192,113,192,63,128,31,0,11,19,38, + 13,1,0,12,0,30,0,51,0,97,128,0,0,31,0,63, + 128,113,192,96,192,224,224,192,96,192,96,192,96,192,96,224, + 224,96,192,113,192,63,128,31,0,11,18,36,13,1,0,28, + 64,54,192,35,128,0,0,31,0,63,128,113,192,96,192,224, + 224,192,96,192,96,192,96,192,96,224,224,96,192,113,192,63, + 128,31,0,11,18,36,13,1,0,51,0,51,0,0,0,0, + 0,31,0,63,128,113,192,96,192,224,224,192,96,192,96,192, + 96,192,96,224,224,96,192,113,192,63,128,31,0,12,12,24, + 14,1,1,6,0,6,0,6,0,0,0,0,0,255,240,255, + 240,0,0,0,0,6,0,6,0,6,0,13,14,28,13,0, + 0,15,152,31,248,56,112,48,224,113,240,99,176,99,48,102, + 48,108,48,124,112,56,96,112,224,255,192,207,128,10,19,38, + 14,2,0,48,0,24,0,12,0,6,0,0,0,192,192,192, + 192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, + 192,193,192,99,192,126,192,28,192,10,19,38,14,2,0,3, + 0,6,0,12,0,24,0,0,0,192,192,192,192,192,192,192, + 192,192,192,192,192,192,192,192,192,192,192,192,192,193,192,99, + 192,126,192,28,192,10,19,38,14,2,0,12,0,30,0,51, + 0,97,128,0,0,192,192,192,192,192,192,192,192,192,192,192, + 192,192,192,192,192,192,192,192,192,193,192,99,192,126,192,28, + 192,10,18,36,14,2,0,51,0,51,0,0,0,0,0,192, + 192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, + 192,192,192,193,192,99,192,126,192,28,192,12,24,48,13,0, + 251,0,192,1,128,3,0,6,0,0,0,192,48,192,48,96, + 48,112,96,48,96,56,224,24,192,24,192,13,128,13,128,7, + 128,7,0,3,0,3,0,6,0,6,0,12,0,60,0,56, + 0,11,24,48,14,2,251,192,0,192,0,192,0,192,0,192, + 0,207,0,223,128,241,192,224,192,192,224,192,96,192,96,192, + 96,192,96,192,224,224,192,241,192,223,128,207,0,192,0,192, + 0,192,0,192,0,192,0,12,23,46,13,0,251,25,128,25, + 128,0,0,0,0,192,48,192,48,96,48,112,96,48,96,56, + 224,24,192,24,192,13,128,13,128,7,128,7,0,3,0,3, + 0,6,0,6,0,12,0,60,0,56,0 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/fontdata/profont_22.cpp b/Marlin/src/lcd/tft/fontdata/profont_22.cpp new file mode 100644 index 000000000000..1d02ebb069b0 --- /dev/null +++ b/Marlin/src/lcd/tft/fontdata/profont_22.cpp @@ -0,0 +1,426 @@ +/* + Fontname: ProFont22 + Copyright: ProFont Distribution 2.2 Generated by Fontographer 4.1.5 + Capital A Height: 14, '1' Height: 14 + Calculated Max Values w=12 h=22 x= 6 y=12 dx=12 dy= 0 ascent=18 len=44 + Font Bounding box w=12 h=21 x= 0 y=-4 + Calculated Min Values x= 0 y=-4 dx= 0 dy= 0 + Pure Font ascent =14 descent=-4 + X Font ascent =16 descent=-4 + Max Font ascent =18 descent=-4 +*/ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +#include + +extern const uint8_t ProFont22[6454] = { + 0,12,21,0,252,14,3,117,7,113,32,255,252,18,252,16, + 252,0,0,0,12,0,0,2,14,14,12,4,0,192,192,192, + 192,192,192,192,192,192,192,0,0,192,192,6,6,6,12,2, + 10,204,204,204,204,204,204,10,10,20,12,0,4,51,0,51, + 0,255,192,255,192,51,0,51,0,255,192,255,192,51,0,51, + 0,10,18,36,12,0,254,12,0,12,0,63,0,127,128,237, + 192,204,192,204,0,236,0,127,0,63,128,13,192,12,192,204, + 192,237,192,127,128,63,0,12,0,12,0,10,14,28,12,0, + 0,63,192,127,192,204,192,205,192,207,128,207,0,127,0,63, + 128,60,192,124,192,236,192,204,192,199,128,195,0,10,14,28, + 12,0,0,62,0,127,0,227,0,199,0,206,0,252,0,120, + 0,120,0,252,192,207,192,199,128,231,128,127,192,60,192,2, + 6,6,12,4,10,192,192,192,192,192,192,6,18,18,12,2, + 254,12,28,56,112,224,192,192,192,192,192,192,192,192,224,112, + 56,28,12,6,18,18,12,2,254,192,224,112,56,28,12,12, + 12,12,12,12,12,12,28,56,112,224,192,10,10,20,12,0, + 4,12,0,12,0,204,192,255,192,63,0,63,0,255,192,204, + 192,12,0,12,0,10,10,20,12,0,2,12,0,12,0,12, + 0,12,0,255,192,255,192,12,0,12,0,12,0,12,0,5, + 9,9,12,2,252,48,120,120,56,24,56,112,224,64,6,2, + 2,12,2,6,252,252,4,4,4,12,3,1,96,240,240,96, + 11,20,40,12,0,252,0,96,0,96,0,192,0,192,1,128, + 1,128,3,0,3,0,6,0,6,0,12,0,12,0,24,0, + 24,0,48,0,48,0,96,0,96,0,192,0,192,0,10,14, + 28,12,0,0,63,0,127,128,225,192,193,192,195,192,199,192, + 206,192,220,192,248,192,240,192,224,192,225,192,127,128,63,0, + 10,14,28,12,0,0,12,0,12,0,124,0,124,0,12,0, + 12,0,12,0,12,0,12,0,12,0,12,0,12,0,255,192, + 255,192,10,14,28,12,0,0,63,0,127,128,225,192,192,192, + 0,192,1,192,3,128,7,0,14,0,28,0,56,0,112,0, + 255,192,255,192,10,14,28,12,0,0,63,0,127,128,225,192, + 192,192,0,192,1,128,15,0,15,128,1,192,0,192,192,192, + 225,192,127,128,63,0,10,14,28,12,0,0,3,0,7,0, + 15,0,31,0,59,0,115,0,227,0,195,0,255,192,255,192, + 3,0,3,0,15,192,15,192,10,14,28,12,0,0,255,192, + 255,192,192,0,192,0,255,0,255,128,1,192,0,192,0,192, + 0,192,192,192,225,192,127,128,63,0,10,14,28,12,0,0, + 63,0,127,0,224,0,192,0,255,0,255,128,193,192,192,192, + 192,192,192,192,192,192,225,192,127,128,63,0,10,14,28,12, + 0,0,255,192,255,192,0,192,0,192,0,192,1,192,3,128, + 7,0,14,0,12,0,12,0,12,0,12,0,12,0,10,14, + 28,12,0,0,63,0,127,128,225,192,192,192,192,192,97,128, + 63,0,127,128,225,192,192,192,192,192,225,192,127,128,63,0, + 10,14,28,12,0,0,63,0,127,128,225,192,192,192,192,192, + 192,192,192,192,224,192,127,192,63,192,0,192,1,192,63,128, + 63,0,4,10,10,12,3,1,96,240,240,96,0,0,96,240, + 240,96,5,15,15,12,2,252,48,120,120,48,0,0,48,120, + 120,56,24,56,112,224,64,8,14,14,12,2,0,3,7,14, + 28,56,112,224,224,112,56,28,14,7,3,10,6,12,12,0, + 4,255,192,255,192,0,0,0,0,255,192,255,192,8,14,14, + 12,2,0,192,224,112,56,28,14,7,7,14,28,56,112,224, + 192,10,14,28,12,0,0,63,0,127,128,225,192,192,192,0, + 192,1,192,3,128,7,0,14,0,12,0,0,0,0,0,12, + 0,12,0,10,14,28,12,0,0,63,0,127,128,225,192,192, + 192,199,192,207,192,204,192,204,192,207,192,199,128,192,0,224, + 0,127,192,63,192,10,14,28,12,0,0,12,0,30,0,30, + 0,51,0,51,0,97,128,97,128,192,192,255,192,255,192,192, + 192,192,192,192,192,192,192,10,14,28,12,0,0,255,0,255, + 128,193,192,192,192,192,192,193,128,255,0,255,128,193,192,192, + 192,192,192,193,192,255,128,255,0,10,14,28,12,0,0,63, + 0,127,128,225,192,192,192,192,0,192,0,192,0,192,0,192, + 0,192,0,192,192,225,192,127,128,63,0,10,14,28,12,0, + 0,255,0,255,128,193,192,192,192,192,192,192,192,192,192,192, + 192,192,192,192,192,192,192,193,192,255,128,255,0,10,14,28, + 12,0,0,255,192,255,192,192,0,192,0,192,0,192,0,255, + 0,255,0,192,0,192,0,192,0,192,0,255,192,255,192,10, + 14,28,12,0,0,255,192,255,192,192,0,192,0,192,0,192, + 0,255,0,255,0,192,0,192,0,192,0,192,0,192,0,192, + 0,10,14,28,12,0,0,63,0,127,128,225,192,192,192,192, + 0,192,0,195,192,195,192,192,192,192,192,192,192,225,192,127, + 128,63,0,10,14,28,12,0,0,192,192,192,192,192,192,192, + 192,192,192,192,192,255,192,255,192,192,192,192,192,192,192,192, + 192,192,192,192,192,10,14,28,12,0,0,255,192,255,192,12, + 0,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12, + 0,12,0,255,192,255,192,10,14,28,12,0,0,0,192,0, + 192,0,192,0,192,0,192,0,192,0,192,0,192,192,192,192, + 192,192,192,225,192,127,128,63,0,10,14,28,12,0,0,193, + 192,195,128,199,0,206,0,220,0,248,0,240,0,248,0,220, + 0,206,0,199,0,195,128,193,192,192,192,10,14,28,12,0, + 0,192,0,192,0,192,0,192,0,192,0,192,0,192,0,192, + 0,192,0,192,0,192,0,192,0,255,192,255,192,10,14,28, + 12,0,0,192,192,225,192,243,192,255,192,222,192,204,192,204, + 192,204,192,192,192,192,192,192,192,192,192,192,192,192,192,10, + 14,28,12,0,0,192,192,224,192,240,192,248,192,220,192,206, + 192,199,192,195,192,193,192,192,192,192,192,192,192,192,192,192, + 192,10,14,28,12,0,0,63,0,127,128,225,192,192,192,192, + 192,192,192,192,192,192,192,192,192,192,192,192,192,225,192,127, + 128,63,0,10,14,28,12,0,0,255,0,255,128,193,192,192, + 192,192,192,193,192,255,128,255,0,192,0,192,0,192,0,192, + 0,192,0,192,0,10,16,32,12,0,254,63,0,127,128,225, + 192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,204, + 192,239,192,127,128,63,128,1,192,0,192,10,14,28,12,0, + 0,255,0,255,128,193,192,192,192,192,192,193,128,255,0,255, + 128,193,192,192,192,192,192,192,192,192,192,192,192,10,14,28, + 12,0,0,63,0,127,128,225,192,192,192,192,0,224,0,127, + 0,63,128,1,192,0,192,192,192,225,192,127,128,63,0,10, + 14,28,12,0,0,255,192,255,192,12,0,12,0,12,0,12, + 0,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12, + 0,10,14,28,12,0,0,192,192,192,192,192,192,192,192,192, + 192,192,192,192,192,192,192,192,192,192,192,192,192,225,192,127, + 128,63,0,10,14,28,12,0,0,192,192,192,192,192,192,192, + 192,192,192,192,192,97,128,97,128,51,0,51,0,30,0,30, + 0,12,0,12,0,10,14,28,12,0,0,192,192,192,192,192, + 192,192,192,192,192,192,192,204,192,204,192,204,192,222,192,255, + 192,243,192,225,192,192,192,10,14,28,12,0,0,192,192,192, + 192,192,192,225,192,115,128,63,0,30,0,30,0,63,0,115, + 128,225,192,192,192,192,192,192,192,10,14,28,12,0,0,192, + 192,192,192,192,192,192,192,192,192,225,192,115,128,63,0,30, + 0,12,0,12,0,12,0,12,0,12,0,10,14,28,12,0, + 0,255,192,255,192,0,192,1,192,3,128,7,0,14,0,28, + 0,56,0,112,0,224,0,192,0,255,192,255,192,4,18,18, + 12,4,254,240,240,192,192,192,192,192,192,192,192,192,192,192, + 192,192,192,240,240,11,20,40,12,1,252,192,0,192,0,96, + 0,96,0,48,0,48,0,24,0,24,0,12,0,12,0,6, + 0,6,0,3,0,3,0,1,128,1,128,0,192,0,192,0, + 96,0,96,4,18,18,12,2,254,240,240,48,48,48,48,48, + 48,48,48,48,48,48,48,48,48,240,240,10,6,12,12,0, + 8,12,0,30,0,63,0,115,128,225,192,64,128,12,2,4, + 12,0,252,255,240,255,240,4,4,4,12,2,12,192,224,112, + 48,10,10,20,12,0,0,63,192,127,192,224,192,192,192,192, + 192,193,192,195,192,231,192,126,192,60,192,10,14,28,12,0, + 0,192,0,192,0,192,0,192,0,255,0,255,128,193,192,192, + 192,192,192,192,192,192,192,193,192,255,128,255,0,10,10,20, + 12,0,0,63,0,127,128,225,192,192,192,192,0,192,0,192, + 0,224,0,127,192,63,192,10,14,28,12,0,0,0,192,0, + 192,0,192,0,192,63,192,127,192,224,192,192,192,192,192,192, + 192,192,192,224,192,127,192,63,192,10,10,20,12,0,0,63, + 0,127,128,225,192,192,192,255,192,255,192,192,0,224,0,127, + 192,63,192,8,14,14,12,2,0,15,31,56,48,252,252,48, + 48,48,48,48,48,48,48,10,14,28,12,0,252,63,192,127, + 192,224,192,192,192,192,192,192,192,192,192,224,192,127,192,63, + 192,0,192,1,192,63,128,63,0,10,14,28,12,0,0,192, + 0,192,0,192,0,192,0,255,0,255,128,193,192,192,192,192, + 192,192,192,192,192,192,192,192,192,192,192,6,14,14,12,2, + 0,48,48,0,0,240,240,48,48,48,48,48,48,252,252,6, + 18,18,12,0,252,12,12,0,0,60,60,12,12,12,12,12, + 12,12,12,12,28,248,240,10,14,28,12,0,0,192,0,192, + 0,192,0,192,0,195,128,199,0,206,0,220,0,252,0,254, + 0,231,0,195,128,193,192,192,192,6,14,14,12,2,0,240, + 240,48,48,48,48,48,48,48,48,48,48,252,252,10,10,20, + 12,0,0,255,0,255,128,205,192,204,192,204,192,204,192,204, + 192,204,192,204,192,204,192,10,10,20,12,0,0,207,0,223, + 128,249,192,240,192,224,192,192,192,192,192,192,192,192,192,192, + 192,10,10,20,12,0,0,63,0,127,128,225,192,192,192,192, + 192,192,192,192,192,225,192,127,128,63,0,10,14,28,12,0, + 252,255,0,255,128,193,192,192,192,192,192,192,192,192,192,193, + 192,255,128,255,0,192,0,192,0,192,0,192,0,10,14,28, + 12,0,252,63,192,127,192,224,192,192,192,192,192,192,192,192, + 192,224,192,127,192,63,192,0,192,0,192,0,192,0,192,10, + 10,20,12,0,0,207,0,223,128,249,192,240,192,224,0,192, + 0,192,0,192,0,192,0,192,0,10,10,20,12,0,0,63, + 192,127,192,192,0,192,0,127,0,63,128,0,192,0,192,255, + 128,255,0,8,14,14,12,2,0,48,48,48,48,252,252,48, + 48,48,48,48,56,31,15,10,10,20,12,0,0,192,192,192, + 192,192,192,192,192,192,192,193,192,195,192,231,192,126,192,60, + 192,10,10,20,12,0,0,192,192,192,192,192,192,97,128,97, + 128,51,128,51,0,30,0,30,0,12,0,10,10,20,12,0, + 0,204,192,204,192,204,192,204,192,204,192,204,192,204,192,204, + 192,127,128,51,0,10,10,20,12,0,0,192,192,225,192,115, + 128,63,0,30,0,30,0,63,0,115,128,225,192,192,192,10, + 14,28,12,0,252,192,192,192,192,192,192,192,192,192,192,192, + 192,192,192,224,192,127,192,63,192,0,192,1,192,63,128,63, + 0,10,10,20,12,0,0,255,192,255,192,3,128,7,0,14, + 0,28,0,56,0,112,0,255,192,255,192,6,22,22,12,2, + 252,12,28,56,48,48,48,48,48,48,112,224,224,112,48,48, + 48,48,48,48,56,28,12,2,18,18,12,4,254,192,192,192, + 192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,6, + 22,22,12,2,252,192,224,112,48,48,48,48,48,48,56,28, + 28,56,48,48,48,48,48,48,112,224,192,10,4,8,12,0, + 6,48,192,124,192,207,128,195,0,0,0,0,12,0,0,0, + 0,0,12,0,0,0,0,0,12,0,0,4,7,7,12,0, + 253,48,48,48,48,112,224,64,10,22,44,12,0,252,3,192, + 7,192,14,0,12,0,12,0,12,0,12,0,12,0,63,0, + 63,0,12,0,12,0,12,0,12,0,12,0,12,0,12,0, + 12,0,12,0,28,0,248,0,240,0,8,7,7,12,0,253, + 51,51,51,51,119,238,68,10,2,4,12,0,0,204,192,204, + 192,6,10,10,12,2,4,48,48,252,252,48,48,48,48,48, + 48,6,10,10,12,2,4,48,48,252,252,48,48,252,252,48, + 48,6,4,4,12,2,12,48,120,252,204,12,16,32,12,0, + 0,63,240,127,240,204,224,205,192,207,128,207,0,126,0,60, + 0,60,192,127,224,243,48,243,48,179,48,51,48,31,224,12, + 192,10,18,36,12,0,0,51,0,63,0,30,0,12,0,63, + 0,127,128,225,192,192,192,192,0,224,0,127,0,63,128,1, + 192,0,192,192,192,225,192,127,128,63,0,4,10,10,12,0, + 255,48,112,96,224,192,192,224,96,112,48,10,14,28,12,0, + 0,63,192,127,192,236,0,204,0,204,0,204,0,207,0,207, + 0,204,0,204,0,204,0,236,0,127,192,63,192,0,0,0, + 12,0,0,0,0,0,12,0,0,0,0,0,12,0,0,0, + 0,0,12,0,0,4,7,7,12,4,8,32,112,224,192,192, + 192,192,4,7,7,12,4,7,48,48,48,48,112,224,64,8, + 7,7,12,2,8,34,119,238,204,204,204,204,8,7,7,12, + 2,7,51,51,51,51,119,238,68,10,10,20,12,0,2,30, + 0,127,128,127,128,255,192,255,192,255,192,255,192,127,128,127, + 128,30,0,6,2,2,12,2,6,252,252,12,2,4,12,0, + 6,255,240,255,240,10,4,8,12,0,12,48,192,124,192,207, + 128,195,0,12,6,12,12,0,8,255,48,255,240,51,240,51, + 240,51,48,51,48,10,16,32,12,0,0,51,0,63,0,30, + 0,12,0,0,0,0,0,63,192,127,192,192,0,192,0,127, + 0,63,128,0,192,0,192,255,128,255,0,4,10,10,12,0, + 255,192,224,96,112,48,48,112,96,224,192,10,10,20,12,0, + 0,51,0,127,128,204,192,204,192,207,192,207,192,204,0,204, + 0,127,192,51,192,0,0,0,12,0,0,0,0,0,12,0, + 0,10,18,36,12,0,0,51,0,51,0,0,0,0,0,192, + 192,192,192,192,192,192,192,192,192,225,192,115,128,63,0,30, + 0,12,0,12,0,12,0,12,0,12,0,0,0,0,12,0, + 0,2,14,14,12,6,0,192,192,0,0,192,192,192,192,192, + 192,192,192,192,192,10,14,28,12,0,254,12,0,12,0,63, + 0,127,128,237,192,204,192,204,0,204,0,204,0,236,0,127, + 192,63,192,12,0,12,0,10,16,32,12,0,0,60,0,126, + 0,231,0,195,0,192,0,192,0,252,0,252,0,192,0,192, + 0,192,0,192,0,192,192,193,192,255,128,255,0,10,10,20, + 12,0,0,64,128,225,192,127,128,63,0,51,0,51,0,63, + 0,127,128,225,192,64,128,10,14,28,12,0,0,192,192,225, + 192,115,128,63,0,255,192,255,192,12,0,12,0,255,192,255, + 192,12,0,12,0,12,0,12,0,2,18,18,12,4,254,192, + 192,192,192,192,192,192,192,0,0,192,192,192,192,192,192,192, + 192,10,20,40,12,0,254,31,0,127,128,97,192,224,192,112, + 192,56,192,220,0,206,0,199,0,227,128,113,192,56,192,28, + 192,14,192,199,0,195,128,193,192,225,128,127,128,62,0,6, + 2,2,12,2,12,204,204,10,14,28,12,0,0,120,0,254, + 0,135,0,1,128,61,128,124,192,192,192,192,192,124,192,61, + 128,1,128,135,0,254,0,120,0,8,12,12,12,2,6,63, + 127,227,195,195,227,127,63,0,0,255,255,10,10,20,12,0, + 255,48,192,113,192,97,128,227,128,195,0,195,0,227,128,97, + 128,113,192,48,192,10,6,12,12,0,2,255,192,255,192,0, + 192,0,192,0,192,0,192,10,2,4,12,0,6,255,192,255, + 192,10,12,24,12,0,2,120,0,254,0,135,0,1,128,241, + 128,248,192,204,192,204,192,248,192,249,192,223,128,207,0,6, + 2,2,12,2,12,252,252,8,8,8,12,2,8,60,126,231, + 195,195,231,126,60,10,12,24,12,0,0,12,0,12,0,12, + 0,12,0,255,192,255,192,12,0,12,0,12,0,12,0,255, + 192,255,192,5,7,7,12,3,11,112,136,8,16,32,64,248, + 5,7,7,12,3,11,112,136,8,48,8,136,112,4,4,4, + 12,4,12,48,112,224,192,10,14,28,12,0,252,195,0,195, + 0,195,0,195,0,195,0,195,0,195,0,199,128,255,192,252, + 192,192,0,192,0,192,0,192,0,10,16,32,12,0,0,31, + 192,127,192,124,192,236,192,204,192,204,192,236,192,124,192,127, + 192,31,192,12,192,12,192,12,192,12,192,12,192,12,192,4, + 4,4,12,4,4,96,240,240,96,4,6,6,12,2,252,240, + 240,48,112,224,64,5,7,7,12,3,11,32,224,32,32,32, + 32,248,8,12,12,12,2,6,60,126,231,195,195,231,126,60, + 0,0,255,255,10,10,20,12,0,255,195,0,227,128,97,128, + 113,192,48,192,48,192,113,192,97,128,227,128,195,0,12,18, + 36,12,0,0,16,0,112,0,16,0,16,0,16,16,16,32, + 124,64,0,128,1,0,2,0,4,0,8,64,16,192,33,64, + 66,64,131,224,0,64,0,224,12,18,36,12,0,0,16,0, + 112,0,16,0,16,0,16,16,16,32,124,64,0,128,1,0, + 2,0,4,0,9,192,18,32,32,32,64,64,128,128,1,0, + 3,224,12,18,36,12,0,0,56,0,68,0,4,0,24,0, + 4,16,68,32,56,64,0,128,1,0,2,0,4,0,8,64, + 16,192,33,64,66,64,131,224,0,64,0,224,10,14,28,12, + 0,0,12,0,12,0,0,0,0,0,12,0,28,0,56,0, + 112,0,224,0,192,0,192,192,225,192,127,128,63,0,10,18, + 36,12,0,0,48,0,56,0,28,0,12,0,12,0,30,0, + 30,0,51,0,51,0,97,128,97,128,192,192,255,192,255,192, + 192,192,192,192,192,192,192,192,10,18,36,12,0,0,3,0, + 7,0,14,0,12,0,12,0,30,0,30,0,51,0,51,0, + 97,128,97,128,192,192,255,192,255,192,192,192,192,192,192,192, + 192,192,10,18,36,12,0,0,12,0,30,0,63,0,51,0, + 12,0,30,0,30,0,51,0,51,0,97,128,97,128,192,192, + 255,192,255,192,192,192,192,192,192,192,192,192,10,18,36,12, + 0,0,48,192,124,192,207,128,195,0,12,0,30,0,30,0, + 51,0,51,0,97,128,97,128,192,192,255,192,255,192,192,192, + 192,192,192,192,192,192,10,18,36,12,0,0,51,0,51,0, + 0,0,0,0,12,0,30,0,30,0,51,0,51,0,97,128, + 97,128,192,192,255,192,255,192,192,192,192,192,192,192,192,192, + 10,18,36,12,0,0,12,0,30,0,51,0,51,0,30,0, + 30,0,30,0,51,0,51,0,97,128,97,128,192,192,255,192, + 255,192,192,192,192,192,192,192,192,192,10,14,28,12,0,0, + 63,192,127,192,236,0,204,0,204,0,204,0,255,0,255,0, + 204,0,204,0,204,0,204,0,207,192,207,192,10,18,36,12, + 0,252,63,0,127,128,225,192,192,192,192,0,192,0,192,0, + 192,0,192,0,192,0,192,192,225,192,127,128,63,0,12,0, + 28,0,56,0,16,0,10,18,36,12,0,0,48,0,56,0, + 28,0,12,0,255,192,255,192,192,0,192,0,192,0,192,0, + 255,0,255,0,192,0,192,0,192,0,192,0,255,192,255,192, + 10,18,36,12,0,0,3,0,7,0,14,0,12,0,255,192, + 255,192,192,0,192,0,192,0,192,0,255,0,255,0,192,0, + 192,0,192,0,192,0,255,192,255,192,10,18,36,12,0,0, + 12,0,30,0,63,0,51,0,255,192,255,192,192,0,192,0, + 192,0,192,0,255,0,255,0,192,0,192,0,192,0,192,0, + 255,192,255,192,10,18,36,12,0,0,51,0,51,0,0,0, + 0,0,255,192,255,192,192,0,192,0,192,0,192,0,255,0, + 255,0,192,0,192,0,192,0,192,0,255,192,255,192,10,18, + 36,12,0,0,48,0,56,0,28,0,12,0,255,192,255,192, + 12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,0, + 12,0,12,0,255,192,255,192,10,18,36,12,0,0,3,0, + 7,0,14,0,12,0,255,192,255,192,12,0,12,0,12,0, + 12,0,12,0,12,0,12,0,12,0,12,0,12,0,255,192, + 255,192,10,18,36,12,0,0,12,0,30,0,63,0,51,0, + 255,192,255,192,12,0,12,0,12,0,12,0,12,0,12,0, + 12,0,12,0,12,0,12,0,255,192,255,192,10,18,36,12, + 0,0,51,0,51,0,0,0,0,0,255,192,255,192,12,0, + 12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,0, + 12,0,255,192,255,192,10,14,28,12,0,0,63,0,63,128, + 49,192,48,192,48,192,48,192,252,192,252,192,48,192,48,192, + 48,192,49,192,63,128,63,0,10,18,36,12,0,0,48,192, + 124,192,207,128,199,0,192,192,224,192,240,192,248,192,220,192, + 206,192,199,192,195,192,193,192,192,192,192,192,192,192,192,192, + 192,192,10,18,36,12,0,0,48,0,56,0,28,0,12,0, + 63,0,127,128,225,192,192,192,192,192,192,192,192,192,192,192, + 192,192,192,192,192,192,225,192,127,128,63,0,10,18,36,12, + 0,0,3,0,7,0,14,0,12,0,63,0,127,128,225,192, + 192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, + 225,192,127,128,63,0,10,18,36,12,0,0,12,0,30,0, + 63,0,51,0,0,0,63,0,127,128,225,192,192,192,192,192, + 192,192,192,192,192,192,192,192,192,192,225,192,127,128,63,0, + 10,18,36,12,0,0,48,192,124,192,207,128,199,0,63,0, + 127,128,225,192,192,192,192,192,192,192,192,192,192,192,192,192, + 192,192,192,192,225,192,127,128,63,0,10,18,36,12,0,0, + 51,0,51,0,0,0,0,0,63,0,127,128,225,192,192,192, + 192,192,192,192,192,192,192,192,192,192,192,192,192,192,225,192, + 127,128,63,0,10,10,20,12,0,2,64,128,225,192,115,128, + 63,0,30,0,30,0,63,0,115,128,225,192,64,128,10,14, + 28,12,0,0,63,0,127,128,225,192,193,192,195,192,199,192, + 206,192,220,192,248,192,240,192,224,192,225,192,127,128,63,0, + 10,18,36,12,0,0,48,0,56,0,28,0,12,0,192,192, + 192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, + 192,192,192,192,225,192,127,128,63,0,10,18,36,12,0,0, + 3,0,7,0,14,0,12,0,192,192,192,192,192,192,192,192, + 192,192,192,192,192,192,192,192,192,192,192,192,192,192,225,192, + 127,128,63,0,10,18,36,12,0,0,12,0,30,0,63,0, + 51,0,0,0,192,192,192,192,192,192,192,192,192,192,192,192, + 192,192,192,192,192,192,192,192,225,192,127,128,63,0,10,18, + 36,12,0,0,51,0,51,0,0,0,0,0,192,192,192,192, + 192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, + 192,192,225,192,127,128,63,0,10,18,36,12,0,0,3,0, + 7,0,14,0,12,0,192,192,192,192,192,192,192,192,192,192, + 225,192,115,128,63,0,30,0,12,0,12,0,12,0,12,0, + 12,0,10,14,28,12,0,0,192,0,192,0,255,0,255,128, + 193,192,192,192,192,192,193,192,255,128,255,0,192,0,192,0, + 192,0,192,0,10,18,36,12,0,254,15,0,31,128,57,192, + 112,192,224,192,193,192,195,128,195,0,195,0,195,128,193,192, + 192,192,192,192,193,192,207,128,207,0,192,0,192,0,10,16, + 32,12,0,0,12,0,14,0,7,0,3,0,0,0,0,0, + 63,192,127,192,224,192,192,192,192,192,193,192,195,192,231,192, + 126,192,60,192,10,16,32,12,0,0,3,0,7,0,14,0, + 12,0,0,0,0,0,63,192,127,192,224,192,192,192,192,192, + 193,192,195,192,231,192,126,192,60,192,10,16,32,12,0,0, + 12,0,30,0,63,0,51,0,0,0,0,0,63,192,127,192, + 224,192,192,192,192,192,193,192,195,192,231,192,126,192,60,192, + 10,16,32,12,0,0,48,192,124,192,207,128,199,0,0,0, + 0,0,63,192,127,192,224,192,192,192,192,192,193,192,195,192, + 231,192,126,192,60,192,10,14,28,12,0,0,51,0,51,0, + 0,0,0,0,63,192,127,192,224,192,192,192,192,192,193,192, + 195,192,231,192,126,192,60,192,10,16,32,12,0,0,12,0, + 30,0,51,0,51,0,30,0,12,0,63,192,127,192,224,192, + 192,192,192,192,193,192,195,192,231,192,126,192,60,192,10,10, + 20,12,0,0,63,0,127,128,237,192,204,192,207,192,207,192, + 204,0,236,0,127,192,63,192,10,14,28,12,0,252,63,0, + 127,128,225,192,192,192,192,0,192,0,192,0,224,0,127,192, + 63,192,12,0,28,0,56,0,16,0,10,16,32,12,0,0, + 48,0,56,0,28,0,12,0,0,0,0,0,63,0,127,128, + 225,192,192,192,255,192,255,192,192,0,224,0,127,192,63,192, + 10,16,32,12,0,0,3,0,7,0,14,0,12,0,0,0, + 0,0,63,0,127,128,225,192,192,192,255,192,255,192,192,0, + 224,0,127,192,63,192,10,16,32,12,0,0,12,0,30,0, + 63,0,51,0,0,0,0,0,63,0,127,128,225,192,192,192, + 255,192,255,192,192,0,224,0,127,192,63,192,10,14,28,12, + 0,0,51,0,51,0,0,0,0,0,63,0,127,128,225,192, + 192,192,255,192,255,192,192,0,224,0,127,192,63,192,6,16, + 16,12,2,0,192,224,112,48,0,0,240,240,48,48,48,48, + 48,48,252,252,6,16,16,12,2,0,12,28,56,48,0,0, + 240,240,48,48,48,48,48,48,252,252,6,16,16,12,2,0, + 48,120,252,204,0,0,240,240,48,48,48,48,48,48,252,252, + 6,14,14,12,2,0,204,204,0,0,240,240,48,48,48,48, + 48,48,252,252,10,17,34,12,0,0,36,0,126,0,60,0, + 60,0,126,0,39,0,3,128,63,192,127,192,225,192,192,192, + 192,192,192,192,192,192,225,192,127,128,63,0,10,16,32,12, + 0,0,48,192,124,192,207,128,199,0,0,0,0,0,207,0, + 223,128,249,192,240,192,224,192,192,192,192,192,192,192,192,192, + 192,192,10,16,32,12,0,0,48,0,56,0,28,0,12,0, + 0,0,0,0,63,0,127,128,225,192,192,192,192,192,192,192, + 192,192,225,192,127,128,63,0,10,16,32,12,0,0,3,0, + 7,0,14,0,12,0,0,0,0,0,63,0,127,128,225,192, + 192,192,192,192,192,192,192,192,225,192,127,128,63,0,10,16, + 32,12,0,0,12,0,30,0,63,0,51,0,0,0,0,0, + 63,0,127,128,225,192,192,192,192,192,192,192,192,192,225,192, + 127,128,63,0,10,16,32,12,0,0,48,192,124,192,207,128, + 199,0,0,0,0,0,63,0,127,128,225,192,192,192,192,192, + 192,192,192,192,225,192,127,128,63,0,10,14,28,12,0,0, + 51,0,51,0,0,0,0,0,63,0,127,128,225,192,192,192, + 192,192,192,192,192,192,225,192,127,128,63,0,10,10,20,12, + 0,2,12,0,12,0,0,0,0,0,255,192,255,192,0,0, + 0,0,12,0,12,0,10,10,20,12,0,0,63,0,127,128, + 227,192,199,192,206,192,220,192,248,192,241,192,127,128,63,0, + 10,16,32,12,0,0,48,0,56,0,28,0,12,0,0,0, + 0,0,192,192,192,192,192,192,192,192,192,192,193,192,195,192, + 231,192,126,192,60,192,10,16,32,12,0,0,3,0,7,0, + 14,0,12,0,0,0,0,0,192,192,192,192,192,192,192,192, + 192,192,193,192,195,192,231,192,126,192,60,192,10,16,32,12, + 0,0,12,0,30,0,63,0,51,0,0,0,0,0,192,192, + 192,192,192,192,192,192,192,192,193,192,195,192,231,192,126,192, + 60,192,10,14,28,12,0,0,51,0,51,0,0,0,0,0, + 192,192,192,192,192,192,192,192,192,192,193,192,195,192,231,192, + 126,192,60,192,10,20,40,12,0,252,3,0,7,0,14,0, + 12,0,0,0,0,0,192,192,192,192,192,192,192,192,192,192, + 192,192,192,192,224,192,127,192,63,192,0,192,1,192,63,128, + 63,0,10,18,36,12,0,252,192,0,192,0,192,0,192,0, + 255,0,255,128,193,192,192,192,192,192,192,192,192,192,193,192, + 255,128,255,0,192,0,192,0,192,0,192,0,10,18,36,12, + 0,252,51,0,51,0,0,0,0,0,192,192,192,192,192,192, + 192,192,192,192,192,192,192,192,224,192,127,192,63,192,0,192, + 1,192,63,128,63,0 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/back_32x32x4.cpp b/Marlin/src/lcd/tft/images/back_32x32x4.cpp new file mode 100644 index 000000000000..84a6e3aba6f5 --- /dev/null +++ b/Marlin/src/lcd/tft/images/back_32x32x4.cpp @@ -0,0 +1,62 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t back_32x32x4[512] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x75, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0xE5, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x6F, 0xE5, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x76, 0xFF, 0xE5, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x6E, 0xFF, 0xE5, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x76, 0xEF, 0xFF, 0xE5, 0x66, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x6E, 0xFF, 0xFF, 0xD5, 0x55, 0x66, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x76, 0xFF, 0xFF, 0xFF, 0xFE, 0xB8, 0x55, 0x56, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x87, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x85, 0x56, 0x67, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x76, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x95, 0x66, 0x78, 0x88, 0x88, 0x88, + 0x87, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x65, 0x66, 0x88, 0x88, 0x88, + 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x56, 0x78, 0x88, 0x88, + 0x78, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x85, 0x67, 0x88, 0x88, + 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x56, 0x78, 0x88, + 0x88, 0x77, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x65, 0x68, 0x88, + 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x67, 0x88, + 0x88, 0x88, 0x77, 0xEF, 0xFF, 0xFF, 0xFC, 0xDE, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x56, 0x88, + 0x88, 0x88, 0x87, 0x7E, 0xFF, 0xFF, 0xD5, 0x67, 0x77, 0x8A, 0xDF, 0xFF, 0xFF, 0xFF, 0x56, 0x78, + 0x88, 0x88, 0x88, 0x77, 0xEF, 0xFF, 0xE5, 0x78, 0x87, 0x77, 0x77, 0xAE, 0xFF, 0xFF, 0x95, 0x68, + 0x88, 0x88, 0x88, 0x87, 0x7E, 0xFF, 0xE5, 0x78, 0x88, 0x88, 0x88, 0x77, 0xAF, 0xFF, 0xF5, 0x58, + 0x88, 0x88, 0x88, 0x88, 0x77, 0xEF, 0xE5, 0x78, 0x88, 0x88, 0x88, 0x88, 0x77, 0xDF, 0xF8, 0x57, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x7F, 0xE6, 0x78, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7B, 0xFC, 0x56, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xD7, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xBF, 0x66, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7D, 0x97, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0x97, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x78, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/background_320x30x16.cpp b/Marlin/src/lcd/tft/images/background_320x30x16.cpp new file mode 100644 index 000000000000..49c4a84a0c9d --- /dev/null +++ b/Marlin/src/lcd/tft/images/background_320x30x16.cpp @@ -0,0 +1,60 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint16_t background_320x30x16[9600] = { + 0x10F2, 0x18D2, 0x18D2, 0x10D2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18D2, 0x18F2, 0x18F2, 0x18D2, 0x18D2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F3, 0x18F3, 0x18F3, 0x18F3, 0x18F3, 0x18F2, 0x18F3, 0x18F3, 0x20F2, 0x18F3, 0x18F3, 0x18F3, 0x18F3, 0x18F3, 0x18F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x2112, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x2113, 0x20F2, 0x20F3, 0x20F2, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x2113, 0x28F3, 0x2113, 0x20F3, 0x2113, 0x28F3, 0x20F3, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x28F3, 0x28F3, 0x2113, 0x2113, 0x2113, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2113, 0x2913, 0x2913, 0x2913, 0x2914, 0x2913, 0x2913, 0x28F3, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x28F3, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x28F3, 0x2913, 0x2913, 0x2914, 0x2913, 0x2913, 0x2913, 0x2113, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2113, 0x2113, 0x2113, 0x28F3, 0x28F3, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x20F3, 0x28F3, 0x2113, 0x20F3, 0x2113, 0x28F3, 0x2113, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F2, 0x20F3, 0x20F2, 0x2113, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x2112, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x18F3, 0x18F3, 0x18F3, 0x18F3, 0x18F3, 0x18F3, 0x20F2, 0x18F3, 0x18F3, 0x18F2, 0x18F3, 0x18F3, 0x18F3, 0x18F3, 0x18F3, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, + 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D9C, 0x1D9C, 0x1D9C, 0x1D9C, 0x1D9C, 0x1D9C, 0x1D9C, 0x1D9C, 0x1D9D, 0x1D9D, 0x1D9D, 0x1D9D, 0x259C, 0x1DBC, 0x1D9D, 0x259D, 0x1D9C, 0x259C, 0x259C, 0x259C, 0x259C, 0x259C, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25DD, 0x25DD, 0x25BD, 0x25BD, 0x1DDD, 0x25DD, 0x25DD, 0x25DD, 0x25BD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x2DFD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x2DFD, 0x2DFD, 0x2DFD, 0x2DFD, 0x2DFD, 0x25FD, 0x2DFE, 0x2DFD, 0x2DFD, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E3E, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E3D, 0x2E3D, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3D, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x365E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E3E, 0x365E, 0x2E5E, 0x2E5E, 0x2E5E, 0x365E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3D, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3D, 0x2E3D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E3E, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2DFD, 0x2DFD, 0x2DFE, 0x25FD, 0x2DFD, 0x2DFD, 0x2DFD, 0x2DFD, 0x2DFD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x2DFD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25BD, 0x25DD, 0x25DD, 0x25DD, 0x1DDD, 0x25BD, 0x25BD, 0x25DD, 0x25DD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, + 0x1C7C, 0x1C7C, 0x1C7C, 0x1C7B, 0x1C7C, 0x1C7C, 0x1C7C, 0x1C7C, 0x1C7C, 0x1C7C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x249C, 0x1C9C, 0x1D9D, 0x1D7C, 0x1CFC, 0x1C9C, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x24BC, 0x1CBC, 0x1CBC, 0x24BC, 0x24BC, 0x24BC, 0x1CBC, 0x24DC, 0x24DC, 0x24DC, 0x253D, 0x25BD, 0x253D, 0x24DD, 0x24BC, 0x24BC, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24FD, 0x24DC, 0x24DC, 0x24FD, 0x24FD, 0x24FC, 0x24DD, 0x24FD, 0x251C, 0x25FD, 0x255D, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x24FC, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x251D, 0x24FD, 0x24FD, 0x251D, 0x2D1D, 0x24FD, 0x2CFD, 0x25BD, 0x25BD, 0x253C, 0x2CFC, 0x2D1D, 0x251D, 0x2CFD, 0x2CFD, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1C, 0x2D5D, 0x2DDE, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D1D, 0x2D3D, 0x2D1D, 0x2D1D, 0x2E1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D3D, 0x2D1D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2DDE, 0x2D5D, 0x2D1C, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2CFD, 0x2CFD, 0x251D, 0x2D1D, 0x2CFC, 0x253C, 0x25BD, 0x25BD, 0x2CFD, 0x24FD, 0x2D1D, 0x251D, 0x24FD, 0x24FD, 0x251D, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x24FC, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x255D, 0x25FD, 0x251C, 0x24FD, 0x24DD, 0x24FC, 0x24FD, 0x24FD, 0x24DC, 0x24DC, 0x24FD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24BC, 0x24BC, 0x24DD, 0x253D, 0x25BD, 0x253D, 0x24DC, 0x24DC, 0x24DC, 0x1CBC, 0x24BC, 0x24BC, 0x24BC, 0x1CBC, 0x1CBC, 0x24BC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, + 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1B3B, 0x1CFC, 0x157C, 0x1C1C, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x22DB, 0x22DB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x22DB, 0x22DB, 0x22FB, 0x231C, 0x1D1C, 0x1D5C, 0x235B, 0x22DC, 0x22DB, 0x22DC, 0x22FB, 0x22FC, 0x22DC, 0x22DC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FB, 0x22FB, 0x22FB, 0x22FB, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x231B, 0x22FC, 0x233C, 0x253C, 0x1CFD, 0x22FC, 0x22FC, 0x22FB, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x2AFC, 0x2AFC, 0x231C, 0x2B1C, 0x2B1C, 0x259C, 0x247C, 0x231C, 0x231C, 0x2B1C, 0x231C, 0x231C, 0x2B1C, 0x231C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x25BD, 0x2BBC, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x231C, 0x2B1C, 0x2B1C, 0x25DD, 0x2B1C, 0x2B1C, 0x2B1C, 0x231C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2BBC, 0x25BD, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x231C, 0x2B1C, 0x231C, 0x231C, 0x2B1C, 0x231C, 0x231C, 0x247C, 0x259C, 0x2B1C, 0x2B1C, 0x231C, 0x2AFC, 0x2AFC, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FB, 0x22FC, 0x22FC, 0x1CFD, 0x253C, 0x233C, 0x22FC, 0x231B, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FB, 0x22FB, 0x22FB, 0x22FB, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22DC, 0x22DC, 0x22FC, 0x22FB, 0x22DC, 0x22DB, 0x22DC, 0x235B, 0x1D5C, 0x1D1C, 0x231C, 0x22FB, 0x22DB, 0x22DB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x22DB, 0x22DB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, + 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x1B7B, 0x137B, 0x1B5B, 0x1B7B, 0x137B, 0x137B, 0x137B, 0x139B, 0x1BBB, 0x14FB, 0x153C, 0x13FB, 0x1B7B, 0x139B, 0x1B7B, 0x1B7C, 0x1B9B, 0x1B7B, 0x1B7B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9C, 0x1B9B, 0x1B9B, 0x1B9B, 0x139C, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9C, 0x1B9B, 0x1D3C, 0x1D5C, 0x1BFB, 0x1B9C, 0x1BBB, 0x1B9B, 0x1BBC, 0x1B9B, 0x1B9B, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBC, 0x1BBB, 0x1CDC, 0x1D7D, 0x23FC, 0x1BDC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x1BBC, 0x1BBC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23BC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x247C, 0x1D9C, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x241C, 0x259D, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x1DBD, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x259D, 0x241C, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x1D9C, 0x247C, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23BC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x1BBC, 0x1BBC, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BDC, 0x23FC, 0x1D7D, 0x1CDC, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1B9B, 0x1B9B, 0x1BBC, 0x1B9B, 0x1BBB, 0x1B9C, 0x1BFB, 0x1D5C, 0x1D3C, 0x1B9B, 0x1B9C, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x139C, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9C, 0x1B9B, 0x1B9B, 0x1B9B, + 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x137B, 0x135A, 0x135A, 0x137B, 0x135A, 0x135B, 0x139B, 0x14BB, 0x14FB, 0x13FB, 0x137B, 0x137B, 0x135B, 0x137B, 0x137A, 0x137A, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x1B7B, 0x1B7B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x1BBB, 0x153C, 0x151C, 0x1B7B, 0x139B, 0x137B, 0x139B, 0x139B, 0x1B9B, 0x139B, 0x1B9B, 0x1B9B, 0x139B, 0x139B, 0x139B, 0x139B, 0x139B, 0x139B, 0x139B, 0x139B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x13BB, 0x139B, 0x1B9B, 0x139B, 0x1B9B, 0x1B9B, 0x1B9C, 0x1C3B, 0x1D5C, 0x1C3C, 0x1B9B, 0x1BBB, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1B9B, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBB, 0x1C9C, 0x1D1C, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BDB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1CFC, 0x1C7C, 0x1BBB, 0x1BDB, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBB, 0x1BDC, 0x23BC, 0x1BBB, 0x1D7C, 0x1BBB, 0x1BBB, 0x23BC, 0x1BDC, 0x1BBB, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BDB, 0x1BBB, 0x1C7C, 0x1CFC, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BDB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1D1C, 0x1C9C, 0x1BBB, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1B9B, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1BBB, 0x1B9B, 0x1C3C, 0x1D5C, 0x1C3B, 0x1B9C, 0x1B9B, 0x1B9B, 0x139B, 0x1B9B, 0x139B, 0x13BB, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x139B, 0x139B, 0x139B, 0x139B, 0x139B, 0x139B, 0x139B, 0x139B, 0x1B9B, 0x1B9B, 0x139B, 0x1B9B, 0x139B, 0x139B, 0x137B, 0x139B, 0x1B7B, 0x151C, 0x153C, 0x1BBB, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x1B7B, 0x1B7B, 0x137B, 0x137B, 0x137B, 0x137B, + 0x0999, 0x0999, 0x0999, 0x0999, 0x1199, 0x11BA, 0x11BA, 0x11B9, 0x09B9, 0x11BA, 0x1199, 0x11BA, 0x11BA, 0x1199, 0x11DA, 0x0B3A, 0x0C9B, 0x0BFB, 0x127A, 0x11BA, 0x119A, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x119A, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x119A, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x12BA, 0x14BB, 0x13FB, 0x11DB, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11DA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BB, 0x11BA, 0x11DA, 0x11BA, 0x11DA, 0x11BA, 0x11BA, 0x11DA, 0x11BA, 0x127A, 0x14DB, 0x137B, 0x11DA, 0x19BA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x19DA, 0x19DA, 0x19DA, 0x11DA, 0x11DB, 0x11DB, 0x11DB, 0x11DB, 0x11DB, 0x11DB, 0x11DB, 0x19DB, 0x11DA, 0x19DA, 0x1A3B, 0x14FB, 0x1AFB, 0x19DA, 0x11DB, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DA, 0x19DB, 0x19DA, 0x1A1B, 0x153C, 0x1A3B, 0x19DA, 0x19DA, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DB, 0x19DB, 0x19DA, 0x19DB, 0x153B, 0x19DB, 0x19DB, 0x19DA, 0x19DB, 0x19DB, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DA, 0x19DA, 0x1A3B, 0x153C, 0x1A1B, 0x19DA, 0x19DB, 0x19DA, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x11DB, 0x19DA, 0x1AFB, 0x14FB, 0x1A3B, 0x19DA, 0x11DA, 0x19DB, 0x11DB, 0x11DB, 0x11DB, 0x11DB, 0x11DB, 0x11DB, 0x11DB, 0x11DA, 0x19DA, 0x19DA, 0x19DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x19BA, 0x11DA, 0x137B, 0x14DB, 0x127A, 0x11BA, 0x11DA, 0x11BA, 0x11BA, 0x11DA, 0x11BA, 0x11DA, 0x11BA, 0x11BB, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11DA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11DB, 0x13FB, 0x14BB, 0x12BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x119A, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, + 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0B1A, 0x0B1A, 0x0AFA, 0x0AFA, 0x0B1A, 0x0AFA, 0x0B1A, 0x0AFA, 0x0B1A, 0x0B1A, 0x0C3A, 0x0C9A, 0x0BDA, 0x0B1A, 0x0AFA, 0x0AFA, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0BDB, 0x14BB, 0x0BFA, 0x0B1A, 0x0B1A, 0x0B3A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0B3A, 0x131A, 0x0B3A, 0x0B1A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x133B, 0x133B, 0x133A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x133A, 0x0B3A, 0x137A, 0x0CDB, 0x0C5B, 0x133B, 0x133B, 0x0B3A, 0x133A, 0x133A, 0x133A, 0x133A, 0x133A, 0x133A, 0x133A, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x135B, 0x135B, 0x135B, 0x135B, 0x133B, 0x133B, 0x135A, 0x0B5B, 0x133B, 0x143A, 0x147B, 0x135B, 0x135A, 0x133B, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135A, 0x13BB, 0x14DB, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135A, 0x135B, 0x133B, 0x14FB, 0x135A, 0x133B, 0x135B, 0x135A, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x14DB, 0x13BB, 0x135A, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x133B, 0x135A, 0x135B, 0x147B, 0x143A, 0x133B, 0x0B5B, 0x135A, 0x133B, 0x133B, 0x135B, 0x135B, 0x135B, 0x135B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133A, 0x133A, 0x133A, 0x133A, 0x133A, 0x133A, 0x133A, 0x0B3A, 0x133B, 0x133B, 0x0C5B, 0x0CDB, 0x137A, 0x0B3A, 0x133A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x133A, 0x133B, 0x133B, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B1A, 0x0B3A, 0x131A, 0x0B3A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0BFA, 0x14BB, 0x0BDB, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, + 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02F9, 0x02D9, 0x02DA, 0x0ADA, 0x0AFA, 0x0BFA, 0x0C5B, 0x0BFA, 0x0AD9, 0x02FA, 0x02F9, 0x02F9, 0x0AF9, 0x02F9, 0x0AF9, 0x02D9, 0x02F9, 0x0AF9, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AF9, 0x0AFA, 0x0AFA, 0x0AFA, 0x0C1A, 0x0C7B, 0x0B5A, 0x0AFA, 0x0AF9, 0x0B1A, 0x0AFA, 0x0AFA, 0x0AFA, 0x0B1A, 0x0AFA, 0x0AFA, 0x0B1A, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0B1A, 0x0B1A, 0x0B1A, 0x031A, 0x0AFA, 0x0B1A, 0x0B1A, 0x0AFA, 0x0B1A, 0x0B1A, 0x0B1A, 0x0AFA, 0x0C3A, 0x0C5A, 0x0B1A, 0x0AFA, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0C5B, 0x0C1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0C7B, 0x0B7A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0CBB, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0B7A, 0x0C7B, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0C1A, 0x0C5B, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0AFA, 0x0B1A, 0x0C5A, 0x0C3A, 0x0AFA, 0x0B1A, 0x0B1A, 0x0B1A, 0x0AFA, 0x0B1A, 0x0B1A, 0x0AFA, 0x031A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0B1A, 0x0AFA, 0x0AFA, 0x0B1A, 0x0AFA, 0x0AFA, 0x0AFA, 0x0B1A, 0x0AF9, 0x0AFA, 0x0B5A, 0x0C7B, 0x0C1A, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AF9, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, + 0x0158, 0x0158, 0x0158, 0x0158, 0x0138, 0x0158, 0x0158, 0x0158, 0x0138, 0x0238, 0x03B9, 0x03DA, 0x0259, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0138, 0x0178, 0x0158, 0x0158, 0x0159, 0x01B9, 0x037A, 0x0BDA, 0x0218, 0x0958, 0x0159, 0x0159, 0x0958, 0x0158, 0x0158, 0x0158, 0x0158, 0x0958, 0x0959, 0x0158, 0x0159, 0x0179, 0x0158, 0x0159, 0x0159, 0x0159, 0x0159, 0x0158, 0x0158, 0x0158, 0x0158, 0x0979, 0x0179, 0x0958, 0x0979, 0x0159, 0x0178, 0x0159, 0x0958, 0x033A, 0x041A, 0x01F9, 0x0959, 0x0179, 0x0958, 0x0959, 0x0158, 0x0159, 0x0159, 0x0159, 0x0159, 0x0979, 0x0979, 0x0979, 0x0979, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0979, 0x0979, 0x0959, 0x0959, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0A79, 0x043A, 0x0199, 0x0959, 0x0179, 0x0179, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0979, 0x0179, 0x09B9, 0x0C3B, 0x0179, 0x0979, 0x0179, 0x0179, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0179, 0x0979, 0x0179, 0x0C7A, 0x0979, 0x0179, 0x0979, 0x0179, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0179, 0x0179, 0x0979, 0x0179, 0x0C3B, 0x09B9, 0x0179, 0x0979, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0179, 0x0179, 0x0959, 0x0199, 0x043A, 0x0A79, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0959, 0x0959, 0x0979, 0x0979, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0979, 0x0979, 0x0979, 0x0979, 0x0159, 0x0159, 0x0159, 0x0159, 0x0158, 0x0959, 0x0958, 0x0179, 0x0959, 0x01F9, 0x041A, 0x033A, 0x0958, 0x0159, 0x0178, 0x0159, 0x0979, 0x0958, 0x0179, 0x0979, 0x0158, 0x0158, 0x0158, 0x0158, 0x0159, 0x0159, 0x0159, 0x0159, 0x0158, 0x0179, 0x0159, 0x0158, 0x0959, 0x0958, 0x0158, 0x0158, 0x0158, 0x0158, 0x0958, 0x0159, 0x0159, 0x0958, 0x0218, 0x0BDA, 0x037A, 0x01B9, 0x0159, 0x0158, 0x0158, 0x0178, 0x0138, 0x0158, 0x0158, 0x0158, + 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0138, 0x0137, 0x01D8, 0x0339, 0x0399, 0x0238, 0x0137, 0x0137, 0x0138, 0x0138, 0x0137, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0137, 0x0138, 0x0138, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0157, 0x0138, 0x0278, 0x03D9, 0x02B9, 0x0178, 0x0158, 0x0138, 0x0138, 0x0158, 0x0138, 0x0137, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0158, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0158, 0x0158, 0x0158, 0x0138, 0x0138, 0x0938, 0x0158, 0x0158, 0x0158, 0x0178, 0x0339, 0x0399, 0x0178, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x01D9, 0x03F9, 0x01F9, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x02D9, 0x0319, 0x0158, 0x0158, 0x0158, 0x0159, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0959, 0x0158, 0x0158, 0x0159, 0x041A, 0x0959, 0x0159, 0x0158, 0x0158, 0x0959, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0159, 0x0158, 0x0158, 0x0158, 0x0319, 0x02D9, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x01F9, 0x03F9, 0x01D9, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0178, 0x0399, 0x0339, 0x0178, 0x0158, 0x0158, 0x0158, 0x0938, 0x0138, 0x0138, 0x0158, 0x0158, 0x0158, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0158, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0137, 0x0138, 0x0158, 0x0138, 0x0138, 0x0158, 0x0178, 0x02B9, 0x03D9, 0x0278, 0x0138, 0x0157, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, + 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x01D7, 0x0318, 0x0379, 0x0238, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0137, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0137, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0137, 0x0117, 0x0117, 0x0177, 0x0318, 0x0379, 0x01D7, 0x0137, 0x0117, 0x0137, 0x0117, 0x0137, 0x0136, 0x0117, 0x0117, 0x0137, 0x0137, 0x0117, 0x0117, 0x0137, 0x0137, 0x0137, 0x0117, 0x0137, 0x0137, 0x0137, 0x0117, 0x0117, 0x0117, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0138, 0x0137, 0x0117, 0x0157, 0x0359, 0x02F8, 0x0157, 0x0117, 0x0137, 0x0117, 0x0137, 0x0117, 0x0137, 0x0137, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0158, 0x0359, 0x0278, 0x0137, 0x0138, 0x0137, 0x0138, 0x0138, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0138, 0x03B9, 0x01B8, 0x0137, 0x0138, 0x0138, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0137, 0x0137, 0x0138, 0x03F9, 0x0137, 0x0138, 0x0137, 0x0137, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0138, 0x0138, 0x0137, 0x01B8, 0x03B9, 0x0138, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0138, 0x0138, 0x0137, 0x0138, 0x0137, 0x0278, 0x0359, 0x0158, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0137, 0x0137, 0x0117, 0x0137, 0x0117, 0x0137, 0x0117, 0x0157, 0x02F8, 0x0359, 0x0157, 0x0117, 0x0137, 0x0138, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0117, 0x0117, 0x0117, 0x0137, 0x0137, 0x0137, 0x0117, 0x0137, 0x0137, 0x0137, 0x0117, 0x0117, 0x0137, 0x0137, 0x0117, 0x0117, 0x0136, 0x0137, 0x0117, 0x0137, 0x0117, 0x0137, 0x01D7, 0x0379, 0x0318, 0x0177, 0x0117, 0x0117, 0x0137, 0x0117, 0x0117, + 0x02D8, 0x02D8, 0x02D7, 0x02D7, 0x02F7, 0x0358, 0x0378, 0x02F7, 0x02D8, 0x02D8, 0x02D8, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02D7, 0x02F8, 0x02F8, 0x0398, 0x0378, 0x02F8, 0x02D8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x0378, 0x0398, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x0318, 0x02F8, 0x0318, 0x02F7, 0x02F8, 0x02F8, 0x0318, 0x0358, 0x0399, 0x0318, 0x02F8, 0x02F8, 0x0318, 0x0318, 0x02F8, 0x0318, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0338, 0x03B8, 0x0318, 0x0318, 0x02F8, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x03B8, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x02F8, 0x0318, 0x0318, 0x03B8, 0x0338, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x0318, 0x02F8, 0x0318, 0x0318, 0x02F8, 0x02F8, 0x0318, 0x0399, 0x0358, 0x0318, 0x02F8, 0x02F8, 0x02F7, 0x0318, 0x02F8, 0x0318, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x0398, 0x0378, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02D8, 0x02F8, 0x0378, 0x0398, 0x02F8, 0x02F8, 0x02D7, 0x02F8, 0x02F8, + 0x0176, 0x01B6, 0x02F8, 0x0317, 0x0217, 0x0196, 0x0176, 0x0196, 0x0196, 0x0196, 0x0196, 0x0176, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0176, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x01F7, 0x0337, 0x02D7, 0x01B6, 0x0197, 0x0196, 0x0196, 0x0176, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0197, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0237, 0x0358, 0x0217, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0196, 0x0196, 0x0197, 0x0197, 0x0196, 0x0196, 0x0277, 0x0318, 0x01B6, 0x0196, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x01B7, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x01B6, 0x02F7, 0x0257, 0x0197, 0x01B6, 0x01B7, 0x01B6, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x01B7, 0x01B6, 0x01B7, 0x0378, 0x01B7, 0x01B7, 0x01B6, 0x01B7, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x01B6, 0x01B7, 0x01B6, 0x0197, 0x0257, 0x02F7, 0x01B6, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x01B7, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0196, 0x01B6, 0x0318, 0x0277, 0x0196, 0x0196, 0x0197, 0x0197, 0x0196, 0x0196, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0217, 0x0358, 0x0237, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0197, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0176, 0x0196, 0x0196, 0x0197, 0x01B6, 0x02D7, 0x0337, 0x01F7, 0x0196, 0x0196, + 0x0236, 0x0317, 0x0256, 0x00F4, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00F5, 0x00F5, 0x00D5, 0x00F5, 0x00D5, 0x00D5, 0x00F5, 0x01F6, 0x0317, 0x01F6, 0x00F5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00F5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00F5, 0x00F5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00F5, 0x00D5, 0x00F5, 0x01B6, 0x0337, 0x01B6, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x0155, 0x0337, 0x0156, 0x00D5, 0x00D5, 0x00F6, 0x00F6, 0x00F6, 0x00F5, 0x00D6, 0x00D6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F6, 0x00D5, 0x00F6, 0x00F6, 0x00F5, 0x00F5, 0x00F5, 0x00F6, 0x0115, 0x0338, 0x0115, 0x00F6, 0x00F5, 0x00F6, 0x00F5, 0x00D6, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00D5, 0x00F6, 0x00D5, 0x00F5, 0x0357, 0x00F5, 0x00F5, 0x00D5, 0x00F6, 0x00D5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00D6, 0x00F5, 0x00F6, 0x00F5, 0x00F6, 0x0115, 0x0338, 0x0115, 0x00F6, 0x00F5, 0x00F5, 0x00F5, 0x00F6, 0x00F6, 0x00D5, 0x00F6, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00D6, 0x00D6, 0x00F5, 0x00F6, 0x00F6, 0x00F6, 0x00D5, 0x00D5, 0x0156, 0x0337, 0x0155, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x01B6, 0x0337, 0x01B6, 0x00F5, 0x00D5, 0x00F5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00F5, 0x00F5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00F5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00F5, 0x01F6, 0x0317, 0x01F6, 0x00F5, + 0x01F4, 0x0113, 0x00B3, 0x00D3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00D3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00D3, 0x00B3, 0x00D3, 0x00D4, 0x00B3, 0x00B3, 0x00D4, 0x00B3, 0x00B3, 0x00D4, 0x00B3, 0x00D3, 0x0133, 0x0275, 0x0255, 0x0134, 0x00D3, 0x00B3, 0x00D3, 0x00D3, 0x00D4, 0x00D4, 0x00B4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00B4, 0x00D4, 0x00B4, 0x00D4, 0x00D4, 0x00B4, 0x00B4, 0x01D4, 0x02B5, 0x0134, 0x00D4, 0x00B4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00F4, 0x02B5, 0x01B5, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x01B5, 0x0255, 0x00D5, 0x00B4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x02F6, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00B4, 0x00D5, 0x0255, 0x01B5, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x01B5, 0x02B5, 0x00F4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00B4, 0x00D4, 0x0134, 0x02B5, 0x01D4, 0x00B4, 0x00B4, 0x00D4, 0x00D4, 0x00B4, 0x00D4, 0x00B4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00B4, 0x00D4, 0x00D4, 0x00D3, 0x00D3, 0x00B3, 0x00D3, 0x0134, 0x0255, 0x0275, + 0x00B1, 0x0091, 0x0091, 0x0091, 0x00B1, 0x0091, 0x00B1, 0x00B1, 0x0091, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x0091, 0x0091, 0x00D2, 0x01B2, 0x0273, 0x0172, 0x00B1, 0x00B2, 0x00B1, 0x00B1, 0x00B2, 0x00B1, 0x00B1, 0x00B2, 0x00B1, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B1, 0x00B1, 0x00B2, 0x00B2, 0x00B1, 0x00B2, 0x00B2, 0x00B2, 0x01D3, 0x0253, 0x0112, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x0213, 0x01D3, 0x0092, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x0253, 0x0153, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x0294, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x0153, 0x0253, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x0092, 0x01D3, 0x0213, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x0112, 0x0253, 0x01D3, 0x00B2, 0x00B2, 0x00B2, 0x00B1, 0x00B2, 0x00B2, 0x00B1, 0x00B1, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B1, 0x00B2, 0x00B1, 0x00B1, 0x00B2, 0x00B1, 0x00B1, 0x00B2, 0x00B1, 0x0172, + 0x0090, 0x0070, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0111, 0x0212, 0x01D1, 0x00D0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x01D2, 0x01F2, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x0171, 0x0212, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x00F1, 0x0252, 0x00B0, 0x0090, 0x00B0, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x0272, 0x00B0, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x00B0, 0x0090, 0x00B0, 0x0252, 0x00F1, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x0212, 0x0171, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x01F2, 0x01D2, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, + 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x0191, 0x0232, 0x0151, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x01F2, 0x01D1, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0110, 0x0252, 0x00D0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x01B1, 0x0191, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x0090, 0x0090, 0x0252, 0x0090, 0x0090, 0x0090, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0191, 0x01B1, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00D0, 0x0252, 0x0110, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x01D1, 0x01F2, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, + 0x008F, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x00D0, 0x0212, 0x01D2, 0x00D0, 0x0090, 0x008F, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0090, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x0090, 0x0090, 0x00F0, 0x0232, 0x01B1, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0232, 0x0130, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x0232, 0x00D0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0252, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00D0, 0x0232, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0130, 0x0232, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x01B1, 0x0232, 0x00F0, 0x0090, 0x0090, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, + 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0171, 0x0232, 0x0151, 0x008F, 0x006F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0070, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x006F, 0x00F0, 0x0212, 0x0151, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x0070, 0x0090, 0x01F1, 0x01B1, 0x0070, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x008F, 0x0090, 0x008F, 0x008F, 0x0130, 0x01F1, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0252, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x01F1, 0x0130, 0x008F, 0x008F, 0x0090, 0x008F, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x0070, 0x01B1, 0x01F1, 0x0090, 0x0070, 0x008F, 0x008F, 0x008F, 0x008F, 0x0090, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x0151, 0x0212, 0x00F0, 0x006F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0090, 0x0070, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, + 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x0070, 0x008F, 0x006F, 0x008F, 0x0110, 0x0232, 0x01B1, 0x00AF, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x0110, 0x0252, 0x0130, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x0170, 0x01F2, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x01D2, 0x0130, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x0252, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0130, 0x01D2, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x01F2, 0x0170, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x0130, 0x0252, 0x0110, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, + 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x01B1, 0x0232, 0x010F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x0150, 0x0232, 0x00CF, 0x006F, 0x006F, 0x008E, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x006F, 0x010F, 0x0212, 0x00AF, 0x006F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x008F, 0x00AF, 0x0212, 0x00AF, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x0252, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x00AF, 0x0212, 0x00AF, 0x008F, 0x006F, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x006F, 0x00AF, 0x0212, 0x010F, 0x006F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008E, 0x006F, 0x006F, 0x00CF, 0x0232, 0x0150, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, + 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x008E, 0x0110, 0x0212, 0x01B1, 0x008F, 0x006F, 0x006E, 0x006F, 0x006F, 0x006E, 0x008F, 0x006E, 0x006E, 0x006E, 0x006F, 0x006F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006F, 0x008F, 0x006E, 0x006E, 0x006F, 0x006F, 0x008E, 0x006E, 0x0191, 0x01F1, 0x00CF, 0x006F, 0x006F, 0x006E, 0x008F, 0x006E, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x006E, 0x006E, 0x006F, 0x00CF, 0x0212, 0x0110, 0x008F, 0x006F, 0x006E, 0x008F, 0x006F, 0x006E, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x0150, 0x0191, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x0232, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x0191, 0x0150, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006E, 0x006F, 0x008F, 0x006E, 0x006F, 0x008F, 0x0110, 0x0212, 0x00CF, 0x006F, 0x006E, 0x006E, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006E, 0x008F, 0x006E, 0x006F, 0x006F, 0x00CF, 0x01F1, 0x0191, 0x006E, 0x008E, 0x006F, 0x006F, 0x006E, 0x006E, 0x008F, 0x006F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006F, 0x006F, + 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x008E, 0x01B1, 0x0212, 0x00EF, 0x006E, 0x006E, 0x006E, 0x006F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006F, 0x006E, 0x006E, 0x008E, 0x01D1, 0x01F1, 0x008F, 0x006F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x00AE, 0x01F1, 0x0170, 0x006F, 0x006E, 0x006E, 0x006E, 0x006F, 0x006E, 0x006E, 0x006F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0211, 0x00CF, 0x008F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0232, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x008F, 0x00CF, 0x0211, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006F, 0x006E, 0x006E, 0x006F, 0x006E, 0x006E, 0x006E, 0x006F, 0x0170, 0x01F1, 0x00AE, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006F, 0x008F, 0x01F1, 0x01D1, 0x008E, 0x006E, 0x006E, 0x006F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, + 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0130, 0x0212, 0x0170, 0x008E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x00AF, 0x01D1, 0x0190, 0x008E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0190, 0x01F1, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x00EF, 0x0211, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0232, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0211, 0x00EF, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x01F1, 0x0190, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x008E, 0x0190, 0x01D1, 0x00AF, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, + 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x008E, 0x01B1, 0x01F2, 0x00CF, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x00AF, 0x0212, 0x0191, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x004E, 0x008E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x010F, 0x0212, 0x008E, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0190, 0x0150, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0232, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0150, 0x0190, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x008E, 0x0212, 0x010F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x008E, 0x004E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x0191, 0x0212, 0x00AF, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, + 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x004E, 0x004D, 0x0130, 0x01F2, 0x0150, 0x006D, 0x006D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x00EF, 0x0212, 0x010F, 0x004E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x004E, 0x00AF, 0x0212, 0x00CF, 0x004E, 0x006E, 0x004E, 0x004E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x008E, 0x0232, 0x008E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0232, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x008E, 0x0232, 0x008E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x004E, 0x004E, 0x006E, 0x004E, 0x00CF, 0x0212, 0x00AF, 0x004E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x004E, 0x010F, 0x0212, 0x00EF, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, + 0x004D, 0x004D, 0x004D, 0x004D, 0x006E, 0x006D, 0x004D, 0x004D, 0x004E, 0x004D, 0x004D, 0x006D, 0x006D, 0x008E, 0x01B1, 0x01D1, 0x00CE, 0x006D, 0x004D, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x004D, 0x006E, 0x004D, 0x006E, 0x006E, 0x004E, 0x006D, 0x010F, 0x0212, 0x00EF, 0x006D, 0x006E, 0x006E, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004D, 0x006D, 0x006E, 0x006E, 0x006E, 0x004D, 0x006E, 0x004D, 0x006E, 0x01D1, 0x0150, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x0130, 0x0191, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x0232, 0x004E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x0191, 0x0130, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0150, 0x01D1, 0x006E, 0x004D, 0x006E, 0x004D, 0x006E, 0x006E, 0x006E, 0x006D, 0x004D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006E, 0x006E, 0x006D, 0x00EF, 0x0212, 0x010F, 0x006D, 0x004E, 0x006E, 0x006E, 0x004D, 0x006E, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, + 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006D, 0x004D, 0x004D, 0x004D, 0x0150, 0x01F1, 0x0150, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006D, 0x004D, 0x004E, 0x004D, 0x004D, 0x004D, 0x0150, 0x01F1, 0x00AE, 0x006D, 0x004D, 0x004D, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x004D, 0x006D, 0x006D, 0x004D, 0x006D, 0x004D, 0x006D, 0x006D, 0x006D, 0x0170, 0x01B1, 0x006D, 0x006D, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006D, 0x004E, 0x006E, 0x01D1, 0x010F, 0x006D, 0x006D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004D, 0x006D, 0x006E, 0x004E, 0x0212, 0x004D, 0x004E, 0x006E, 0x006D, 0x004D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006D, 0x006D, 0x010F, 0x01D1, 0x006E, 0x004E, 0x006D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x004D, 0x006D, 0x006D, 0x01B1, 0x0170, 0x006D, 0x006D, 0x006D, 0x004D, 0x006D, 0x004D, 0x006D, 0x006D, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x004D, 0x004D, 0x004D, 0x006D, 0x00AE, 0x01F1, 0x0150, 0x004D, 0x004D, 0x004D, 0x004E, 0x004D, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/bootscreen_112x38x1.cpp b/Marlin/src/lcd/tft/images/bootscreen_112x38x1.cpp new file mode 100644 index 000000000000..2308917b1313 --- /dev/null +++ b/Marlin/src/lcd/tft/images/bootscreen_112x38x1.cpp @@ -0,0 +1,70 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +#include "../../../inc/MarlinConfig.h" + +extern const uint8_t marlin_logo_112x38x1[532] = { + B00000001,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111, + B00001111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111, + B00011110,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,B11111111,B11111111, + B00111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,B11111111,B11111111, + B01110000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000001,B11111111,B11111111, + B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B11111111,B11111111, + B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111111,B11111111, + B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111000,B00000000,B00000000,B00111111,B11111111, + B11000000,B00001111,B11000000,B11111100,B00000000,B00000000,B00000000,B00000000,B00000000,B01111000,B00011000,B00000000,B00011111,B11111111, + B11000000,B00111111,B11100001,B11111111,B00000000,B00000000,B00000000,B00000000,B00000000,B01111000,B00111100,B00000000,B00001111,B11111111, + B11000000,B01111111,B11110011,B11111111,B10000000,B00000000,B00000000,B00000000,B00000000,B01111000,B00111100,B00000000,B00000111,B11111111, + B11000000,B11111111,B11111111,B11111111,B11000000,B00000000,B00000000,B00000000,B00000000,B01111000,B00111100,B00000000,B00000011,B11111111, + B11000001,B11111000,B01111111,B10000111,B11100000,B00000000,B00000000,B00000000,B00000000,B01111000,B00000000,B00000000,B00000001,B11111111, + B11000001,B11110000,B00111111,B00000011,B11100000,B00000000,B00000000,B00000000,B00000000,B01111000,B00000000,B00000000,B00000000,B11111111, + B11000001,B11100000,B00011110,B00000001,B11100000,B00011111,B00000000,B00000011,B11100000,B01111000,B00111100,B00000011,B11110000,B01111111, + B11000001,B11100000,B00011110,B00000001,B11100000,B01111111,B11000000,B00001111,B11111000,B01111000,B00111100,B00000111,B11111100,B00111111, + B11000001,B11100000,B00011110,B00000001,B11100001,B11111111,B11100000,B00011111,B11111100,B01111000,B00111100,B00001111,B11111110,B00011111, + B11000001,B11100000,B00011110,B00000001,B11100011,B11111111,B11110000,B00111111,B11111110,B01111000,B00111100,B00011111,B11111110,B00001111, + B11000001,B11100000,B00011110,B00000001,B11100011,B11110011,B11111000,B00111111,B00111110,B01111000,B00111100,B00111111,B00111111,B00000111, + B11000001,B11100000,B00011110,B00000001,B11100111,B11100000,B11111100,B01111100,B00011111,B01111000,B00111100,B00111110,B00011111,B00000111, + B11000001,B11100000,B00011110,B00000001,B11100111,B11000000,B01111100,B01111100,B00001111,B01111000,B00111100,B00111100,B00001111,B00000011, + B11000001,B11100000,B00011110,B00000001,B11100111,B10000000,B01111100,B01111000,B00001111,B01111000,B00111100,B00111100,B00001111,B00000011, + B11000001,B11100000,B00011110,B00000001,B11100111,B10000000,B00111100,B01111000,B00000000,B01111000,B00111100,B00111100,B00001111,B00000011, + B11000001,B11100000,B00011110,B00000001,B11100111,B10000000,B00111100,B01111000,B00000000,B01111000,B00111100,B00111100,B00001111,B00000011, + B11000001,B11100000,B00011110,B00000001,B11100111,B10000000,B00111100,B01111000,B00000000,B01111000,B00111100,B00111100,B00001111,B00000011, + B11000001,B11100000,B00011110,B00000001,B11100111,B11000000,B00111100,B01111000,B00000000,B01111000,B00111100,B00111100,B00001111,B00000011, + B11000001,B11100000,B00011110,B00000001,B11100011,B11100000,B00111100,B01111000,B00000000,B01111100,B00111100,B00111100,B00001111,B00000011, + B11000001,B11100000,B00011110,B00000001,B11100011,B11111111,B00111111,B11111000,B00000000,B01111111,B10111100,B00111100,B00001111,B00000011, + B11000001,B11100000,B00011110,B00000001,B11100001,B11111111,B00111111,B11111000,B00000000,B00111111,B10111111,B11111100,B00001111,B00000011, + B11000001,B11100000,B00011110,B00000001,B11100000,B11111111,B00111111,B11111000,B00000000,B00011111,B10111111,B11111100,B00001111,B00000011, + B11000001,B11100000,B00011110,B00000001,B11100000,B01111111,B00111111,B11111000,B00000000,B00001111,B10111111,B11111100,B00001111,B00000011, + B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111, + B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000110, + B01110000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001110, + B00111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00011100, + B00011110,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111000, + B00001111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11110000, + B00000001,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B10000000 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/bootscreen_195x59x16.cpp b/Marlin/src/lcd/tft/images/bootscreen_195x59x16.cpp new file mode 100644 index 000000000000..2545f845a80f --- /dev/null +++ b/Marlin/src/lcd/tft/images/bootscreen_195x59x16.cpp @@ -0,0 +1,89 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint16_t marlin_logo_195x59x16[11505] = { + 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x310E, 0x7A32, 0xAAD3, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, + 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x20AD, 0x18AD, 0x496F, 0xAAD3, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, + 0x18AD, 0x20AB, 0x18AD, 0x18AD, 0x18AD, 0x20EE, 0x8252, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD3B5, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDB95, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, + 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x28EE, 0xB314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD4F8, 0xD65C, 0xD6DD, 0xD6FD, 0xD7FF, 0xD7FF, 0xDFFF, 0xD7FF, 0xD7FF, 0xDFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xDFFF, 0xD539, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDB95, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, + 0x18AD, 0x20AD, 0x18AE, 0x28EE, 0xCB55, 0xD375, 0xD395, 0xD395, 0xD3D6, 0xD5DB, 0xD7BF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xDFFF, 0xDFFF, 0xDFFF, 0xD7FF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xDFFF, 0xD539, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, + 0x18AD, 0x18AD, 0x28EE, 0xB314, 0xD395, 0xD395, 0xD395, 0xD477, 0xD77E, 0xD7FF, 0xD7FF, 0xDFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xDFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xD7FF, 0xDFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD539, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, + 0x18AD, 0x18CD, 0x8252, 0xD395, 0xD395, 0xD396, 0xD4B8, 0xD7BF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xDFFF, 0xDFFF, 0xD7FF, 0xD7FF, 0xDFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xDFFF, 0xD7FF, 0xDFFF, 0xD539, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, + 0x18AD, 0x496F, 0xD395, 0xD395, 0xD395, 0xD457, 0xD7BF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7DF, 0xD7FF, 0xCF3E, 0xC67C, 0xC53A, 0xACB8, 0xACB8, 0xACB8, 0xACB8, 0xACB8, 0xACB8, 0xC53A, 0xC67C, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD65B, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD396, 0xD395, + 0x20AE, 0xA2D3, 0xD395, 0xD395, 0xD3D6, 0xD75E, 0xCFFF, 0xCFFF, 0xD7FF, 0xD7FF, 0xCFFF, 0xCFFF, 0xD7FF, 0xD7FF, 0xD7DF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7DF, 0xD7FF, 0xD7FF, 0xCFDF, 0xCFFF, 0xD7FF, 0xD7DF, 0xD7FF, 0xCFFF, 0xD7FF, 0xD7DF, 0xD7FF, 0xCFFF, 0xD7DF, 0xCFFF, 0xCFFF, 0xD7FF, 0xD7FF, 0xCFFF, 0xD7FF, 0xCFFF, 0xD7FF, 0xD7DF, 0xD7DF, 0xCFFF, 0xD7DF, 0xCFFF, 0xD7FF, 0xD7FF, 0xCFFF, 0xD7FF, 0xCFFF, 0xD7FF, 0xD7DF, 0xD7FF, 0xD7FF, 0xCFFF, 0xCFFF, 0xD7FF, 0xCFFF, 0xD7DF, 0xCFFF, 0xD7FF, 0xD7DF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xCFFF, 0xD7FF, 0xCFDF, 0xD7DF, 0xCFDF, 0xCFFF, 0xD7DF, 0xACD8, 0x8191, 0x9151, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0xBE3B, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7DF, 0xD7DF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7DF, 0xCFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7DF, 0xD7DF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7DF, 0xD7FF, 0xD7DF, 0xD7FF, 0xD7DF, 0xD65C, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, + 0x310E, 0xD395, 0xD375, 0xD375, 0xD5BA, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xC77E, 0xBE5B, 0xBE3C, 0xB57A, 0xACB8, 0xBDBB, 0xC63C, 0xBE3B, 0xC71E, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xC77E, 0xBE5C, 0xB5DB, 0xACB8, 0xAC98, 0xBD5A, 0xBE3C, 0xC61C, 0xC69D, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xACB9, 0x8191, 0x9151, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0xA111, 0xBE3B, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xD7DF, 0xCFDF, 0xCF5E, 0xBE5C, 0xBE5C, 0xC63C, 0xC61C, 0xCEFD, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFFF, 0xCFDF, 0xD63B, 0xD375, 0xD395, 0xD375, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD395, 0xD375, 0xD375, 0xD375, 0xD395, + 0x79F1, 0xD355, 0xD355, 0xD355, 0xCF7E, 0xC7DF, 0xCFBF, 0xCFDF, 0xC7DF, 0xC7DF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFBF, 0xCFDF, 0xCFDF, 0xCFBF, 0xBEFD, 0xACB8, 0x8A52, 0x9151, 0x9131, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0xA192, 0xAB96, 0xBE7D, 0xCFDF, 0xC7DF, 0xCFBF, 0xC7DF, 0xCFDF, 0xCFBF, 0xC75E, 0xAD19, 0x92B4, 0x8971, 0x9151, 0x9931, 0x9931, 0x9911, 0x9911, 0xA111, 0x9931, 0xA111, 0x9911, 0xAB36, 0xBD5A, 0xC75E, 0xCFDF, 0xC7BF, 0xC7BF, 0xCFDF, 0xC7DF, 0xC7BF, 0xC7DF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xC7DF, 0xCFBF, 0xC7DF, 0xC7BF, 0xCFBF, 0xC7DF, 0xA4B8, 0x8191, 0x9151, 0x9931, 0x9911, 0x9931, 0x9931, 0x9911, 0x9931, 0x9912, 0xBE3B, 0xCFBF, 0xCFDF, 0xCFBF, 0xCFDF, 0xCFDF, 0xB5DA, 0x8A12, 0x8971, 0x9931, 0x9931, 0xA111, 0x9931, 0xAB35, 0xC75E, 0xCFBF, 0xCFDF, 0xC7DF, 0xC7DF, 0xCFDF, 0xCFDF, 0xCFBF, 0xC7DF, 0xC7DF, 0xCFDF, 0xCFDF, 0xCFDF, 0xC7DF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCE1B, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, + 0xA293, 0xD335, 0xD335, 0xCC98, 0xC7BF, 0xC7BE, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC75E, 0xA4B8, 0x8191, 0x9151, 0x9911, 0xA131, 0xA111, 0xA111, 0x9931, 0xA111, 0xA112, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xAB35, 0xBEFE, 0xC7BF, 0xC7BE, 0xC7BF, 0xB5DB, 0x89F1, 0x8971, 0x9931, 0x9911, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA132, 0x9911, 0xA111, 0xA111, 0xA111, 0xA111, 0xA172, 0xBD3A, 0xC7BE, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BE, 0xC79F, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC79F, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xAC98, 0x8191, 0x9151, 0x9931, 0xA111, 0xA131, 0xA111, 0xA131, 0xA111, 0x9931, 0xBE1B, 0xC79F, 0xC7BF, 0xC7BF, 0xC7BF, 0xBEFD, 0x89F2, 0x8991, 0x9931, 0xA112, 0xA131, 0xA111, 0xA111, 0xA111, 0xAB97, 0xC7BF, 0xC7BF, 0xC7BE, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC6DD, 0xD375, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD334, 0xD335, 0xD335, + 0xD315, 0xD315, 0xD314, 0xC5FB, 0xC79F, 0xC79E, 0xC7BF, 0xC7BF, 0xC79E, 0xC79E, 0xC7BF, 0xC79F, 0xBF9E, 0xBFBF, 0xBFBE, 0xB67C, 0x8A53, 0x8971, 0xA131, 0xA112, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA112, 0xA111, 0xA111, 0xA172, 0xB539, 0xBF9F, 0x9BF6, 0x8191, 0x9151, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA112, 0xA111, 0xA111, 0xAB15, 0xBF3D, 0xC79F, 0xC7BE, 0xC79F, 0xC79F, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79F, 0xC79E, 0xC79F, 0xC79E, 0xC79E, 0xC7BF, 0xC79F, 0xA4B8, 0x8191, 0x9151, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA112, 0xA111, 0xBDFB, 0xC79F, 0xC79E, 0xC7BE, 0xC79F, 0xACF9, 0x8191, 0x9171, 0xA111, 0xA111, 0xA111, 0xA112, 0xA111, 0xA131, 0xA111, 0xBF3E, 0xBFBF, 0xC79E, 0xC79E, 0xC79E, 0xC7BF, 0xC79E, 0xC79E, 0xC79E, 0xBFBF, 0xC79E, 0xC79E, 0xC79E, 0xBF9E, 0xC79F, 0xC79E, 0xBFBE, 0xC79E, 0xC6BD, 0xD355, 0xD2F5, 0xD315, 0xCB14, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD315, 0xD315, 0xD315, 0xD314, + 0xD2F4, 0xCAF4, 0xD2F4, 0xC65C, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF7F, 0xB67C, 0x8A12, 0x8971, 0xA111, 0xA111, 0xA911, 0xA111, 0xA911, 0xA111, 0xA111, 0xA111, 0xA911, 0xA911, 0xA111, 0xA111, 0xA111, 0xA911, 0xA111, 0xA111, 0xA111, 0xA912, 0xA911, 0xA1F3, 0x8191, 0x9931, 0xA111, 0xA111, 0xA912, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA911, 0xA911, 0xA911, 0xA911, 0xA911, 0xA111, 0xA111, 0xA111, 0xA112, 0xA911, 0xAA54, 0xBF1D, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xB79E, 0xBF9F, 0xA498, 0x8191, 0x9951, 0xA911, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA911, 0xB5FB, 0xBF9E, 0xBF9F, 0xBF9E, 0xBF9F, 0xA498, 0x8191, 0x9951, 0xA111, 0xA111, 0xA111, 0xA111, 0xA112, 0xA111, 0xA911, 0xB5FB, 0xBF7E, 0xBF9E, 0xBF9E, 0xBF9F, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBEBD, 0xD335, 0xCAF4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xCAF4, 0xD2F4, 0xD2F5, 0xCAF4, + 0xD2D4, 0xD2D4, 0xD2D4, 0xBE5C, 0xB77E, 0xB79E, 0xB77E, 0xBF7E, 0xB77E, 0xB77E, 0xB77E, 0xB79E, 0xBF7E, 0xAE7B, 0x89F2, 0x8971, 0xA111, 0xA8F1, 0xA911, 0xA8F1, 0xA911, 0xA911, 0xA911, 0xA911, 0xA911, 0xA8F1, 0xA911, 0xA911, 0xA911, 0xA8F1, 0xA911, 0xA8F1, 0xA911, 0xA911, 0xA912, 0xA911, 0xA911, 0xA111, 0xA911, 0xA8F1, 0xA911, 0xA8F1, 0xA111, 0xA911, 0xA8F1, 0xA8F1, 0xA911, 0xA911, 0xA8F1, 0xA911, 0xA8F1, 0xA8F1, 0xA912, 0xA911, 0xA911, 0xA911, 0xA8F1, 0xA111, 0xAA34, 0xB71E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xB77E, 0xB77E, 0xBF7E, 0xB77E, 0xB77E, 0xBF7F, 0xB77E, 0x9C97, 0x8191, 0x9951, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA911, 0xA8F1, 0xB5DB, 0xBF7E, 0xB77E, 0xBF7E, 0xBF7E, 0xA478, 0x8191, 0x9951, 0xA911, 0xA8F1, 0xA8F1, 0xA911, 0xA911, 0xA8F1, 0xA911, 0xB5DB, 0xB77F, 0xB77E, 0xBF7E, 0xBF7E, 0xB77E, 0xBF7E, 0xBF7E, 0xBF7E, 0xB77E, 0xB77E, 0xBF7E, 0xB77E, 0xBF7E, 0xB77E, 0xBF7E, 0xBF7E, 0xB77E, 0xB77E, 0xBF7E, 0xBE9D, 0xCB75, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D5, + 0xD2B4, 0xD2B4, 0xD2B4, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB71D, 0x8A53, 0x8191, 0xA111, 0xA8F1, 0xB0F1, 0xA911, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F2, 0xA8F1, 0xB0F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xB2F5, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB75E, 0xB77E, 0xB77E, 0xB77E, 0xB75E, 0xB75E, 0xB77E, 0xB75E, 0xB77E, 0xB77E, 0xB75E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB75E, 0xB75E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB75E, 0xB77E, 0xB77E, 0xB75E, 0xB77E, 0xB75E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0x9C78, 0x8191, 0x9951, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xB5DB, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0x9C77, 0x8191, 0x9151, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xB5DB, 0xB77E, 0xB77E, 0xB77E, 0xB75E, 0xB77E, 0xB75E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB75E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB75E, 0xB71D, 0xCB96, 0xD2B4, 0xD2B4, 0xCAB4, 0xD2B4, 0xCAB4, 0xD2B4, 0xCAB4, 0xD2B4, 0xCAB4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xCA94, 0xD2B4, 0xD2B4, 0xD2B4, 0xCAB4, + 0xD294, 0xD294, 0xCA94, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF5E, 0xB75E, 0x9416, 0x8991, 0x9951, 0xB0F1, 0xA8F1, 0xB0F1, 0xA8F1, 0xB0F1, 0xA8F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xA8F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xA8F1, 0xA8F1, 0xB0F1, 0xA8F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0F2, 0xA8F1, 0xB0F1, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0F2, 0xA8F1, 0xB0F2, 0xB0F1, 0xB0F1, 0xB0F1, 0xA8F1, 0xB0F1, 0xB0F1, 0xACF9, 0xAF5E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF7E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xB75E, 0xB75E, 0xAF5E, 0xB75E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xB75E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5D, 0xB75E, 0xAF5E, 0xAF5E, 0x9C77, 0x8191, 0x9951, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xADBB, 0xB75E, 0xB75E, 0xB75E, 0xB75E, 0x9C78, 0x8991, 0x9951, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB5BB, 0xB75E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF5E, 0xB75E, 0xB75E, 0xB75E, 0xAF5E, 0xB75E, 0xB75E, 0xB75E, 0xAF5E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF1D, 0xCB75, 0xCA93, 0xD294, 0xCA74, 0xCA94, 0xCA74, 0xD274, 0xCA74, 0xD294, 0xCA94, 0xCA94, 0xCA94, 0xCA94, 0xCA94, 0xCA94, 0xCA94, 0xCA94, 0xD294, 0xCA93, 0xCA94, 0xD293, 0xCA74, + 0xD274, 0xD274, 0xCA53, 0xAF5E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3D, 0xAF5D, 0xAF3D, 0xAF3E, 0xA69C, 0x8191, 0x8191, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0D1, 0xB0F2, 0xB0D1, 0xB0D1, 0xB0F2, 0xB0F1, 0xB0F1, 0xAA13, 0xB418, 0xA438, 0x9AB4, 0x9931, 0xA8F1, 0xB0F1, 0xB0F2, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xAA74, 0xAC78, 0xACF9, 0x9B35, 0x9931, 0xA8F1, 0xB0F1, 0xB0F2, 0xB0F1, 0xB0D1, 0xB0D1, 0xB0F1, 0xB0F2, 0xB0D1, 0xB0F1, 0xA9B3, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3D, 0xAF3D, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3D, 0xAF3D, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3D, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0x9C77, 0x8191, 0x9931, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xADBB, 0xAF3E, 0xAF3E, 0xAF5D, 0xAF3E, 0x9477, 0x8191, 0x9951, 0xB0D1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0D1, 0xADBA, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3D, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF3D, 0xAF3D, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAEFD, 0xCB56, 0xCA53, 0xCA74, 0xD253, 0xD274, 0xD274, 0xD273, 0xCA73, 0xD274, 0xD274, 0xD274, 0xD274, 0xD274, 0xD274, 0xD274, 0xD274, 0xD254, 0xCA74, 0xCA54, 0xCA54, 0xCA74, + 0xCA53, 0xCA53, 0xCA53, 0xA73E, 0xA73E, 0xA73E, 0xA73E, 0xA73D, 0xA73D, 0xA73D, 0xA73D, 0x9457, 0x8191, 0x9931, 0xB8D1, 0xB0D1, 0xB8D1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB1B3, 0xAD9A, 0xAF3D, 0xAF3D, 0xA73D, 0xA73D, 0x9DDA, 0x89D1, 0x9951, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0F1, 0xB213, 0xAD9B, 0xA73E, 0xA73D, 0xAF3E, 0xAF3E, 0x9DDA, 0x81F2, 0x9171, 0xB0F1, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0D1, 0xB8D1, 0xB8D2, 0xB0F1, 0xAD39, 0xA73D, 0xA73E, 0xA73D, 0xA73D, 0xA73D, 0xA73D, 0xA73D, 0xA73E, 0xA73D, 0xA73D, 0xA73D, 0xAF3D, 0xA73D, 0xA73D, 0xA73D, 0xA73E, 0xA73E, 0xA73D, 0xAF3D, 0xA73D, 0xA73D, 0xA73E, 0xAF3D, 0xA73E, 0xA73E, 0xA73D, 0xAF3D, 0xA73D, 0xA73D, 0xA73E, 0xAF3E, 0xAF1E, 0xA73E, 0xA73E, 0xA73E, 0xA73E, 0xA73E, 0xA73E, 0xA73E, 0xA73E, 0xAF3E, 0xA73E, 0xA73D, 0xAF3E, 0xA73E, 0xA73D, 0xA73D, 0xA73D, 0xAF3D, 0xA73E, 0xA73E, 0xA73E, 0xA73D, 0xAF3D, 0xA73D, 0xAF3D, 0xA73E, 0xA73E, 0xAF3D, 0xA73E, 0xA73D, 0xA73D, 0xA73E, 0x9478, 0x8191, 0x9931, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB8D1, 0xAD9A, 0xA73E, 0xA73D, 0xA73E, 0xA73D, 0xA73D, 0xA73D, 0xAF3D, 0xA73D, 0xA73D, 0xA73D, 0xA73D, 0xA73D, 0xAF3D, 0xA73D, 0xA73D, 0xA73D, 0xAF3E, 0xA73E, 0xA73D, 0xA73D, 0xA73D, 0xAF3D, 0xAF3E, 0xA73D, 0xAF3D, 0xAF3E, 0xA73D, 0xA73D, 0xAF3D, 0xA73E, 0xAF3D, 0xAF3D, 0xAF3D, 0xA73E, 0xA73D, 0xA73D, 0xAF3D, 0xA73D, 0xAEDD, 0xC376, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA33, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xD233, 0xCA53, 0xD253, 0xCA53, 0xCA53, + 0xCA13, 0xCA33, 0xCA13, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA73D, 0xA73D, 0xA73D, 0x8A53, 0x8191, 0xA8F1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB213, 0xA6BD, 0xA71D, 0xA73E, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0x9E1B, 0x81F1, 0x9171, 0xB0F1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB1F3, 0xA6BD, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA73D, 0xA71D, 0x9E1B, 0x89F2, 0x8991, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB8D1, 0xB336, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA73D, 0xA73D, 0xA73D, 0xA71D, 0xA71D, 0xA73D, 0xA71D, 0xA71E, 0xA71D, 0xA71D, 0xA73D, 0xA73E, 0xA71D, 0xA71D, 0xA71D, 0xA73E, 0xA71D, 0xA73E, 0xA73D, 0xA71D, 0xA71D, 0xA73D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA73D, 0xA73D, 0xA73D, 0xA73E, 0xA71D, 0xA73D, 0xA73D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA73D, 0xA71D, 0xA71D, 0xA73E, 0xA73D, 0xA73D, 0xA71D, 0xA71D, 0x9477, 0x8191, 0x9931, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xA59A, 0xA71D, 0xA73D, 0xA73E, 0xA71D, 0xA71D, 0xA71E, 0xA73D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA73D, 0xA73D, 0xA71E, 0xA71D, 0xA73D, 0xA71D, 0xA73D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA73D, 0xA73D, 0xA71D, 0xA73D, 0xA73D, 0xA71D, 0xA73E, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xBBF7, 0xCA13, 0xCA33, 0xCA13, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA13, 0xCA13, 0xCA14, 0xD233, 0xCA33, + 0xCA13, 0xCA13, 0xCA13, 0x9F1D, 0x9F1D, 0xA71D, 0x9F1D, 0x9F1D, 0xA71D, 0x9F1D, 0x9F1D, 0x8191, 0x8191, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xA5DB, 0x9F1D, 0x9F1D, 0x9EFD, 0x9F1D, 0x9F1D, 0x9F1D, 0xA6FD, 0x9F1D, 0x94F9, 0x8191, 0x9931, 0xB8D1, 0xB8D1, 0xB8B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8B1, 0xA5DB, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0xA6FD, 0x9F1D, 0x9F1D, 0x9F1D, 0x94F9, 0x8191, 0x9931, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB932, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1E, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9E1B, 0x9457, 0x92D4, 0xA1F3, 0xA911, 0xB0F1, 0xB0F1, 0xA911, 0xB274, 0xB254, 0xB254, 0xABF7, 0xA5DB, 0xA6FD, 0xA6FD, 0xA71D, 0xA71D, 0x9F1D, 0x9F1D, 0xA6FD, 0x9F1D, 0x9F1D, 0xA71D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9E7C, 0x9498, 0x8B14, 0x9A13, 0xA131, 0xA912, 0xB0F1, 0xA8F1, 0xB255, 0xB274, 0xB254, 0xAB97, 0xAD1A, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0xA71D, 0x9F1D, 0xA71D, 0x9457, 0x8191, 0xA131, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xA57A, 0x9F1D, 0xA71D, 0x9F1D, 0xA71D, 0x9E7C, 0x9DBA, 0xA59A, 0xA57A, 0xA57A, 0xA57A, 0xA57A, 0xA57A, 0xA57A, 0xA57A, 0xA69C, 0x9F1D, 0x9F1D, 0x9F1D, 0xA71D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9E5C, 0x94B8, 0x8AF4, 0x9A13, 0xA131, 0xA8F1, 0xB0F1, 0xB0F1, 0xB932, 0xB274, 0xB254, 0xB336, 0xACB9, 0xA63C, 0x9F1D, 0xBBF7, 0xC9F3, 0xCA13, 0xCA13, 0xCA13, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xCA13, 0xCA13, 0xCA13, 0xCA13, 0xCA13, + 0xC9D3, 0xC9D3, 0xC9D3, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x959A, 0x8191, 0x9151, 0xC0B1, 0xB8D1, 0xC0B1, 0xB8D1, 0xC0D1, 0xB8D1, 0xB8D1, 0xB2B5, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x8252, 0x8191, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xC0B1, 0xC0D1, 0xB8D1, 0xC0D1, 0xB1F3, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9F1D, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x8A93, 0x8191, 0xB8D1, 0xB8D1, 0xC0D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xC0B1, 0xA63C, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x94F8, 0x8A53, 0x9171, 0xB0F1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8B1, 0xB8B1, 0xC0B1, 0xC0D1, 0xC0D1, 0xB8D1, 0xC0D1, 0xB8B1, 0xB992, 0xACB9, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9E5C, 0x8B96, 0x8991, 0xA131, 0xB8D1, 0xB8D1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xC0B1, 0xB8D1, 0xB932, 0xABF7, 0x9E9C, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9437, 0x8191, 0xA131, 0xB8D1, 0xC0B1, 0xB8D1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB8D1, 0xA57A, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9437, 0x8191, 0xA131, 0xB8D1, 0xC0B1, 0xB8D1, 0xB8D1, 0xC0B1, 0xB8D1, 0xB8D1, 0xA57A, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9E9C, 0x8B96, 0x8971, 0xA131, 0xB8D1, 0xB8D1, 0xC0B1, 0xB8D1, 0xC0B1, 0xC0D1, 0xB8D1, 0xB8D1, 0xC0D1, 0xB8D1, 0xB8D1, 0xC0D1, 0xB335, 0xA63C, 0xBBD7, 0xC9D3, 0xC9F3, 0xC9D3, 0xC9D3, 0xC9D3, 0xC9D3, 0xC9D3, 0xC9D3, 0xC9D3, 0xC9D3, 0xC9D3, 0xC9F3, 0xC9D3, 0xC9D3, 0xC9F3, 0xC9D3, + 0xC9B3, 0xC9B3, 0xC9B3, 0x9EDD, 0x96FD, 0x9EDD, 0x96FD, 0x9EFC, 0x96FD, 0x96FD, 0x9599, 0x8991, 0x9171, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xABD7, 0x9EFC, 0x96FD, 0x96FD, 0x96DD, 0x96FD, 0x9EFD, 0x9EDD, 0x96FD, 0x9EDD, 0x9EFD, 0x8C37, 0x8191, 0xA111, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xAB76, 0x9EDD, 0x9EFD, 0x9EFD, 0x9EDD, 0x9EDD, 0x96DD, 0x9EFD, 0x9EDD, 0x96FD, 0x9EDD, 0x8C37, 0x8191, 0xA131, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0D1, 0xA55A, 0x96FD, 0x9EDD, 0x9EFD, 0x96FD, 0x963B, 0x8AF4, 0x8991, 0xA911, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xB992, 0xA55A, 0x9EDD, 0x9EFC, 0x96FD, 0x9EDD, 0x96FD, 0x9EFD, 0x96FD, 0x96FD, 0x96FD, 0x96FD, 0x96FD, 0x96FD, 0x96FD, 0x96FD, 0x94F9, 0x81F1, 0x9171, 0xB8D2, 0xC0B1, 0xC0D1, 0xC0D1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xB992, 0x9DBB, 0x96FD, 0x9EDD, 0x96FD, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xA55A, 0x9EDD, 0x96FD, 0x96FD, 0x9EFD, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xA55A, 0x96FD, 0x9EFD, 0x96FD, 0x9EFD, 0x9EFD, 0x96FD, 0x9EFD, 0x96FD, 0x9539, 0x81F1, 0x9171, 0xB0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB911, 0xACFA, 0xB458, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9D2, 0xC9D3, 0xC9D3, 0xC9B3, + 0xC993, 0xC993, 0xC992, 0x96DC, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x8D79, 0x8191, 0x9151, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xABD7, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xABD7, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x9D5A, 0x96DD, 0x96DD, 0x96DD, 0x95DA, 0x89F2, 0x8971, 0xB8D1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xA499, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DC, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x8C37, 0x8191, 0x9931, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xA499, 0x96DC, 0x96DD, 0x8C37, 0x8191, 0xA111, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x9D5A, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x9D5A, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x8CD8, 0x8191, 0x9951, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xAC79, 0xACF9, 0xC992, 0xC993, 0xC9B2, 0xC992, 0xC992, 0xC993, 0xC993, 0xC993, 0xC992, 0xC992, 0xC992, 0xC993, 0xC993, 0xC993, + 0xC972, 0xC972, 0xC972, 0x8EBC, 0x8EBD, 0x8EBD, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBD, 0x8D7A, 0x8191, 0x9151, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xABB7, 0x8EBD, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBD, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xABB7, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EDC, 0x8EBC, 0x8EDD, 0x8EBC, 0x8EBC, 0x8EBD, 0x8EBC, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x9D39, 0x8EBD, 0x8EDD, 0x8DBA, 0x81F2, 0x9171, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC8B1, 0xC8B2, 0xC0B1, 0xC8B2, 0xC8B1, 0xC8B1, 0xC0D1, 0xC0B1, 0xC0D1, 0xC0D1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xA437, 0x8EBC, 0x8EDD, 0x8EBC, 0x8EBD, 0x8EBC, 0x8EBC, 0x8EBD, 0x8EBC, 0x8EBD, 0x8EBD, 0x8CD8, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC8B2, 0xC8B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC8B1, 0xA4D9, 0x8EBC, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC8B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0x9D3A, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x9D5A, 0x8EBC, 0x8EBC, 0x8EDC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8CD8, 0x8191, 0x9951, 0xC8B1, 0xC0B1, 0xC8B1, 0xC8B2, 0xC8B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC8B1, 0xC8B1, 0xC8D1, 0xA478, 0xA4D9, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, + 0xC952, 0xC952, 0xC952, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8D59, 0x8191, 0x9171, 0xC8F2, 0xC8F1, 0xC8F2, 0xC8F2, 0xC8F2, 0xC8F1, 0xC8F2, 0xABD7, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8C36, 0x8191, 0xA931, 0xC8F2, 0xC8F1, 0xC8F2, 0xC8F2, 0xC8F2, 0xC8F2, 0xC0F2, 0xABB7, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8437, 0x8191, 0xA951, 0xC8F1, 0xC8F1, 0xC8F2, 0xC8F1, 0xC8F1, 0xC8F2, 0xC8F1, 0x9D3A, 0x8EBC, 0x8E1B, 0x81F2, 0x8971, 0xB912, 0xC8F1, 0xC8F1, 0xC8F2, 0xC8F1, 0xC8F1, 0xC8F1, 0xC8F2, 0xC8D1, 0xC112, 0xC8F2, 0xC8F2, 0xC8F2, 0xC8D1, 0xC8F2, 0xC8D1, 0xC8F2, 0xC0F1, 0xC8F1, 0xC8F2, 0xC8F1, 0xC8F2, 0xC0F1, 0xA498, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8DBA, 0x8991, 0x8991, 0xC0F1, 0xC8F2, 0xC0F2, 0xC8F1, 0xC8F2, 0xC8F1, 0xC0F1, 0xC8F2, 0xC8F1, 0xC8F2, 0xC0F2, 0xC8F1, 0xC0F1, 0xC8F2, 0xC8F1, 0xC8F2, 0xC8F2, 0xC8F2, 0xC8F1, 0xC8F1, 0xC0F2, 0xC132, 0x8E5C, 0x8C17, 0x8191, 0xA931, 0xC8F2, 0xC8F2, 0xC8F2, 0xC8F2, 0xC8F1, 0xC8F2, 0xC8F2, 0x9D59, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8C17, 0x8191, 0xA951, 0xC8F1, 0xC8F1, 0xC8F2, 0xC8F1, 0xC8F1, 0xC8F2, 0xC8F1, 0x9D5A, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBD, 0x8DBA, 0x81F2, 0x8991, 0xC111, 0xC8F1, 0xC8F1, 0xC8F1, 0xC0F2, 0xC8F1, 0xC8F1, 0xC0F2, 0xC8D2, 0xC8F1, 0xC8F2, 0xC0F1, 0xC0F1, 0xC8F2, 0xC0F1, 0xC8F1, 0xC8F2, 0xC8F2, 0xC8F1, 0xC8F1, 0xC8F2, 0xC152, 0x95FB, 0xA4B8, 0xC152, 0xC952, 0xC952, 0xC952, 0xC972, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, + 0xC932, 0xC932, 0xC932, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8D79, 0x8191, 0x9171, 0xC132, 0xC131, 0xC912, 0xC912, 0xC132, 0xC911, 0xC912, 0xABF7, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x96BC, 0x8C36, 0x8191, 0xA951, 0xC912, 0xC911, 0xC912, 0xC912, 0xC112, 0xC912, 0xC912, 0xABF7, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8C36, 0x8191, 0xA951, 0xC912, 0xC912, 0xC912, 0xC911, 0xC911, 0xC912, 0xC912, 0x9D59, 0x8EBC, 0x8AD4, 0x8191, 0xB152, 0xC912, 0xC131, 0xC912, 0xC912, 0xC912, 0xC912, 0xC912, 0xC912, 0xC932, 0xC912, 0xC912, 0xC912, 0xC912, 0xC911, 0xC112, 0xC932, 0xC912, 0xC912, 0xC932, 0xC911, 0xC912, 0xC912, 0xC932, 0xC131, 0x9DBA, 0x8EBC, 0x96BC, 0x8EBC, 0x8EDC, 0x96BB, 0x8EBC, 0x8EDC, 0x82D4, 0x8191, 0xB932, 0xC912, 0xC112, 0xC912, 0xC112, 0xC912, 0xC112, 0xC912, 0xC911, 0xC911, 0xC932, 0xC911, 0xC131, 0xC912, 0xC132, 0xC131, 0xC912, 0xC912, 0xC911, 0xC911, 0xC131, 0xC912, 0xC912, 0xB356, 0x8C36, 0x8191, 0xA151, 0xC912, 0xC912, 0xC912, 0xC912, 0xC912, 0xC912, 0xC112, 0x9D59, 0x8EBC, 0x96BC, 0x8EBC, 0x8EBC, 0x8C37, 0x8191, 0xA951, 0xC912, 0xC912, 0xC912, 0xC911, 0xC911, 0xC912, 0xC912, 0x9D59, 0x8EBC, 0x8EBC, 0x8EBC, 0x96BC, 0x8EBC, 0x82F4, 0x8991, 0xB151, 0xC912, 0xC912, 0xC932, 0xC912, 0xC912, 0xC131, 0xC932, 0xC912, 0xC911, 0xC911, 0xC932, 0xC911, 0xC912, 0xC911, 0xC932, 0xC932, 0xC112, 0xC911, 0xC132, 0xC912, 0xC912, 0xC932, 0xB336, 0x96BC, 0xA4F9, 0xC192, 0xC932, 0xC932, 0xC932, 0xC932, 0xC932, 0xC932, 0xC932, 0xC932, 0xC932, 0xC932, + 0xC912, 0xC912, 0xC912, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDC, 0x9EDB, 0x9EDB, 0x9EDB, 0x9578, 0x8191, 0x9991, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xB417, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9436, 0x8191, 0xA972, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xA518, 0x9EDB, 0x96DB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9436, 0x8191, 0xA171, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xA579, 0x94D8, 0x8191, 0x9991, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC152, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC253, 0xC2B4, 0xB952, 0xC152, 0xC952, 0xC152, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xBAB5, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9599, 0x8191, 0x91B1, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC1F3, 0xC2B5, 0xB952, 0xC152, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC972, 0xC952, 0xC952, 0xC972, 0xC1B2, 0x9436, 0x8191, 0xA972, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xA579, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x8C36, 0x8991, 0xA171, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xA579, 0x9EDB, 0x9EDC, 0x9EDB, 0x9EDB, 0x9598, 0x8191, 0x9191, 0xC952, 0xC952, 0xC952, 0xC952, 0xC152, 0xC952, 0xC172, 0xC952, 0xC952, 0xC952, 0xC1F3, 0xC2B4, 0xB952, 0xC152, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xA61A, 0x9EDC, 0xA5DA, 0xC172, 0xC912, 0xC911, 0xC911, 0xC912, 0xC912, 0xC111, 0xC912, 0xC912, 0xC912, + 0xC8F1, 0xC8F1, 0xC8F2, 0xA6FB, 0xA6FA, 0xA6FA, 0xA6FB, 0xA6FA, 0xA6DA, 0xA6FA, 0x9D98, 0x8191, 0x9191, 0xC972, 0xC992, 0xC992, 0xC972, 0xC992, 0xC992, 0xC992, 0xB436, 0xA6FB, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0x9436, 0x8191, 0xA992, 0xC992, 0xC992, 0xC972, 0xC972, 0xC972, 0xC992, 0xC992, 0xAD98, 0xA6DA, 0xA6DA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0x9436, 0x8191, 0xA992, 0xC993, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xAD99, 0x8A32, 0x8991, 0xC192, 0xC992, 0xC992, 0xC972, 0xC992, 0xC992, 0xC973, 0xC992, 0xC992, 0xC992, 0xBC36, 0xA69A, 0xA6FA, 0xA6FA, 0xA69A, 0x9395, 0x8991, 0xB992, 0xC993, 0xC972, 0xC972, 0xC992, 0xC992, 0xC972, 0xC992, 0xC972, 0xC972, 0xAD98, 0xA6DB, 0xA6DA, 0xA6FA, 0xA6FB, 0xA6FA, 0x9395, 0x8191, 0xB192, 0xC992, 0xC992, 0xC992, 0xC993, 0xC972, 0xC972, 0xC992, 0xC972, 0xC233, 0xAD98, 0xA6FA, 0xA6FB, 0xA639, 0x8A93, 0x9992, 0xC192, 0xC972, 0xC992, 0xC992, 0xC992, 0xC972, 0xC992, 0xC972, 0xC972, 0x9A93, 0x8191, 0xA992, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xAD98, 0xA6FA, 0xA6FB, 0xA6FA, 0xA6FA, 0x9436, 0x8191, 0xA992, 0xC993, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xAD98, 0xA6DA, 0xA6DA, 0xA6FA, 0xA6DA, 0x8B95, 0x8191, 0xB192, 0xC972, 0xC992, 0xC972, 0xC992, 0xC992, 0xC972, 0xC992, 0xC972, 0xC294, 0xADF9, 0xA6FA, 0xA6DA, 0xA69A, 0x9334, 0x9191, 0xB992, 0xC992, 0xC993, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xB497, 0xAEFB, 0xAEFB, 0xB5D9, 0xC952, 0xC8F1, 0xC8F2, 0xC0F1, 0xC8F1, 0xC8F1, 0xC8F1, 0xC8F1, 0xC8F1, + 0xC0D1, 0xC0D1, 0xC8D2, 0xB71A, 0xB71A, 0xB71A, 0xAEFA, 0xB71A, 0xAF1A, 0xAEFA, 0xA598, 0x8191, 0x9191, 0xC9B3, 0xC9B3, 0xC9D3, 0xC9D3, 0xC9B2, 0xC9B3, 0xC9D3, 0xBC76, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0x9C55, 0x8191, 0xA9B2, 0xC9D3, 0xC9D3, 0xC9B3, 0xC9B2, 0xC9B3, 0xC9D3, 0xC9D3, 0xB5B8, 0xB71A, 0xAF1A, 0xB71A, 0xB6FA, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0xB6FA, 0xAF1A, 0x9C56, 0x8191, 0xA992, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xA3B5, 0x8191, 0x9992, 0xC9B2, 0xC9B3, 0xC9D2, 0xC9B2, 0xC9B3, 0xC9B2, 0xC9B3, 0xC9D3, 0xCA13, 0xBDB8, 0xAEFA, 0xAF1A, 0xB71A, 0xB6FA, 0xAEFA, 0xAF19, 0xA4F7, 0x8991, 0xB1B2, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9D2, 0xC9B3, 0xC9B3, 0xC314, 0xAF1A, 0xAF1A, 0xAEF9, 0xAF1A, 0xAF1A, 0x89F1, 0x8191, 0xC1B2, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B2, 0xC9B2, 0xC9D3, 0xC9B3, 0xCAB4, 0xB6B9, 0xAF1A, 0xB71A, 0xAEFA, 0xB71A, 0xB6B9, 0x8A93, 0x8991, 0xC1D2, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B2, 0xC9D3, 0xC9B2, 0xA992, 0x8191, 0xA9B2, 0xC9D3, 0xC9B3, 0xC9D3, 0xC9B2, 0xC9B2, 0xC9B2, 0xC9B3, 0xB5B8, 0xAF1A, 0xAEFA, 0xAF1A, 0xB71A, 0x9C56, 0x8191, 0xA992, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xB5B8, 0xB6FA, 0xAF1A, 0xAF1A, 0xB6FA, 0x89F2, 0x8191, 0xC1B2, 0xC9B3, 0xC9B2, 0xC9D3, 0xC9B3, 0xC9B3, 0xC9B2, 0xC9D3, 0xCAB4, 0xB6B9, 0xAF1A, 0xB71A, 0xB71A, 0xB6FA, 0xB71A, 0x92F3, 0x89B1, 0xC1B2, 0xC9D3, 0xC9B3, 0xC9B3, 0xC9D3, 0xC9D3, 0xC9B3, 0xC9D3, 0xC315, 0xB71A, 0xB71A, 0xB71A, 0xBDD9, 0xC132, 0xC0D1, 0xC8D1, 0xC8D1, 0xC8D1, 0xC8D1, 0xC0D1, 0xC0D1, + 0xC0B1, 0xC8B1, 0xC0B1, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xA4B5, 0x8191, 0xA1B2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xD1F3, 0xC496, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xA455, 0x8191, 0xA9D2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xBDD8, 0xBF19, 0xBF19, 0xBF19, 0xBF39, 0xBF19, 0xBF19, 0xBF39, 0xBF19, 0xBF39, 0xBF39, 0xA455, 0x8191, 0xA9D2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0x99F2, 0x8991, 0xB1D2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F2, 0xC577, 0xBF19, 0xBF39, 0xBF39, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0x9BF5, 0x8191, 0xB1D2, 0xC9F3, 0xC9F3, 0xD1F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xBE78, 0xBF19, 0xBF19, 0xBF19, 0xB6B9, 0x8191, 0x8991, 0xC9F3, 0xC9F3, 0xC9F2, 0xC9F3, 0xC9F3, 0xC9D3, 0xC9F3, 0xC9F3, 0xBED8, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF39, 0xAD57, 0x8191, 0x99B2, 0xC9F3, 0xC9F2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xB9D3, 0x8191, 0xA9B2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xBDD8, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0x9C75, 0x8191, 0xA9D2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xBDD8, 0xBF19, 0xBF19, 0xBF19, 0xB6B8, 0x8191, 0x8191, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xBE78, 0xBF19, 0xBF39, 0xBF19, 0xBF39, 0xBF19, 0xBF19, 0xADB7, 0x8191, 0x91B1, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC71A, 0xBF1A, 0xC73A, 0xBF3A, 0xC659, 0xC9D3, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, + 0xC0B1, 0xC0B1, 0xC0B1, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xA475, 0x8991, 0xA9D2, 0xCA13, 0xCA33, 0xCA33, 0xCA34, 0xCA13, 0xCA33, 0xCA33, 0xCCB6, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xA455, 0x8191, 0xA9D2, 0xCA33, 0xCA33, 0xCA13, 0xCA33, 0xCA33, 0xCA33, 0xD213, 0xC5F7, 0xC738, 0xC738, 0xC738, 0xC738, 0xC739, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xA475, 0x8191, 0xA9D2, 0xCA13, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA13, 0xCA33, 0x91B1, 0x8191, 0xCA13, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA13, 0xCA33, 0xCA13, 0xC455, 0xC738, 0xC739, 0xC738, 0xC738, 0xC738, 0xC738, 0xC739, 0xC738, 0xC738, 0xC738, 0x8A52, 0x8991, 0xC213, 0xCA13, 0xCA13, 0xCA13, 0xCA13, 0xCA33, 0xCA13, 0xCA33, 0xCD56, 0xC738, 0xC738, 0xC739, 0xB5D7, 0x8191, 0x91B1, 0xCA13, 0xCA13, 0xCA13, 0xD233, 0xCA33, 0xCA33, 0xCA33, 0xCB55, 0xCF38, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC739, 0xC738, 0x8191, 0x8191, 0xCA13, 0xCA13, 0xCA13, 0xCA33, 0xCA13, 0xCA33, 0xD233, 0xCA13, 0x8191, 0xA9D2, 0xCA33, 0xCA33, 0xCA13, 0xCA13, 0xCA33, 0xCA13, 0xCA33, 0xCDF7, 0xC738, 0xC738, 0xC738, 0xC739, 0xA475, 0x8191, 0xA9D2, 0xCA13, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA13, 0xCA33, 0xC5F7, 0xC738, 0xC738, 0xC738, 0xB5D6, 0x8191, 0x99B2, 0xCA33, 0xCA33, 0xD213, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCB74, 0xC739, 0xC738, 0xC738, 0xC738, 0xC738, 0xC739, 0xC738, 0xC738, 0x8AB2, 0x8191, 0xBA13, 0xCA13, 0xCA13, 0xCA33, 0xCA13, 0xCA33, 0xCA33, 0xCA13, 0xCF39, 0xC739, 0xC759, 0xCF3A, 0xCF39, 0xCED9, 0xC9F3, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, + 0xC0B1, 0xC0B1, 0xC0B1, 0xCF57, 0xD758, 0xD758, 0xCF58, 0xD758, 0xCF58, 0xD758, 0xAC74, 0x8191, 0xA9F2, 0xCA53, 0xD253, 0xCA54, 0xCA53, 0xCA53, 0xCA53, 0xCA54, 0xCCD6, 0xCF58, 0xD758, 0xD758, 0xD758, 0xD758, 0xD758, 0xD758, 0xD758, 0xD758, 0xCF58, 0xAC75, 0x8191, 0xA9F2, 0xCA53, 0xCA53, 0xD253, 0xCA53, 0xCA53, 0xCA53, 0xD254, 0xCE17, 0xCF57, 0xD758, 0xCF58, 0xD758, 0xCF58, 0xD758, 0xD758, 0xCF58, 0xD758, 0xCF58, 0xAC74, 0x8191, 0xA9F2, 0xCA53, 0xCA54, 0xD253, 0xCA53, 0xCA53, 0xCA54, 0xCA53, 0x99D2, 0x89B1, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xD253, 0xCA53, 0xCA53, 0xCA54, 0xD6B7, 0xD758, 0xCF58, 0xCF57, 0xCF58, 0xD758, 0xD757, 0xD758, 0xD757, 0xD758, 0xCF58, 0xB535, 0x8191, 0xA1D2, 0xCA53, 0xCA53, 0xCA53, 0xD254, 0xCA73, 0xCA53, 0xCA53, 0xCC95, 0xD758, 0xD758, 0xCF58, 0xBDD6, 0x8191, 0x99D2, 0xCA53, 0xCA53, 0xCA54, 0xCA53, 0xCA53, 0xD254, 0xCA54, 0xD435, 0xD758, 0xD758, 0xCF58, 0xD758, 0xD758, 0xCF57, 0xD738, 0xCF58, 0x9AF3, 0x8991, 0xC213, 0xCA54, 0xCA53, 0xCA53, 0xD253, 0xCA53, 0xCA54, 0xCA73, 0x8191, 0xA9F2, 0xCA53, 0xD253, 0xD253, 0xCA54, 0xD253, 0xCA53, 0xCA54, 0xCE17, 0xCF58, 0xD758, 0xD758, 0xCF58, 0xAC74, 0x8191, 0xA9F2, 0xCA53, 0xCA54, 0xD253, 0xCA53, 0xCA53, 0xCA54, 0xCA53, 0xD617, 0xD758, 0xCF58, 0xCF58, 0xBDD6, 0x8191, 0x91B2, 0xCA53, 0xD254, 0xCA53, 0xCA53, 0xCA54, 0xD253, 0xD253, 0xCCD6, 0xD758, 0xD758, 0xD758, 0xD758, 0xCF57, 0xD757, 0xCF58, 0xD758, 0x9AF3, 0x8191, 0xBA33, 0xCA54, 0xCA53, 0xD253, 0xCA54, 0xCA53, 0xD253, 0xCA53, 0xD758, 0xD758, 0xDF59, 0xD779, 0xD759, 0xD759, 0xD6F9, 0xC1F2, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, + 0xC0B1, 0xC0B1, 0xC0B1, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xB494, 0x8191, 0xAA12, 0xCA94, 0xCA74, 0xCA94, 0xCA94, 0xCA94, 0xCA94, 0xD294, 0xD4F5, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xB474, 0x8191, 0xAA12, 0xCA94, 0xCA94, 0xD294, 0xCA94, 0xD294, 0xCA94, 0xD294, 0xDE36, 0xDF77, 0xDF77, 0xDF57, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xB494, 0x8191, 0xAA12, 0xCA94, 0xD294, 0xD294, 0xD294, 0xD294, 0xD294, 0xD294, 0x99D2, 0x91D2, 0xD294, 0xCA94, 0xD294, 0xCA94, 0xD294, 0xCA94, 0xCA94, 0xD3D4, 0xDF77, 0xDF77, 0xDF77, 0xDF76, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF57, 0xDF77, 0xDF77, 0x8191, 0x8992, 0xCA94, 0xCA94, 0xCA94, 0xD294, 0xCA94, 0xCA93, 0xCA94, 0xD3D5, 0xDF77, 0xDF77, 0xDF77, 0xC5F5, 0x8191, 0x99D2, 0xCA94, 0xCA94, 0xD273, 0xCA94, 0xD294, 0xCA94, 0xD294, 0xD515, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0x9B12, 0x8191, 0xBA53, 0xCA94, 0xCA94, 0xD294, 0xCA94, 0xCA93, 0xD294, 0xCA94, 0x8191, 0xAA12, 0xD294, 0xD294, 0xD294, 0xCA94, 0xCA94, 0xD294, 0xD294, 0xDE36, 0xDF77, 0xDF77, 0xDF57, 0xDF77, 0xB474, 0x8191, 0xAA12, 0xCA94, 0xD294, 0xD294, 0xD294, 0xD294, 0xD294, 0xD294, 0xDE36, 0xDF77, 0xDF77, 0xDF77, 0xC5F5, 0x8191, 0x99D2, 0xD294, 0xCA94, 0xCA94, 0xD294, 0xCA94, 0xCA94, 0xCA93, 0xD4F5, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0x9B12, 0x8191, 0xBA53, 0xD294, 0xCA94, 0xCA94, 0xD294, 0xCA94, 0xD294, 0xCA94, 0xDF78, 0xDF78, 0xDF78, 0xDF78, 0xDF78, 0xDF78, 0xE779, 0xDF19, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, + 0xB8D1, 0xB8D1, 0xC0D1, 0xE776, 0xE796, 0xE797, 0xE797, 0xE796, 0xE796, 0xE796, 0xB494, 0x8191, 0xAA33, 0xD2B4, 0xD2B4, 0xD2B4, 0xCAB4, 0xD2D4, 0xD2B4, 0xD2B4, 0xDD35, 0xE776, 0xE796, 0xE796, 0xE796, 0xE796, 0xE796, 0xE796, 0xE796, 0xE796, 0xE796, 0xB474, 0x8191, 0xAA33, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2B4, 0xD2B4, 0xCAD4, 0xD2D4, 0xE656, 0xEF96, 0xE776, 0xE797, 0xE796, 0xE796, 0xE776, 0xE777, 0xE796, 0xE796, 0xE796, 0xB494, 0x8191, 0xAA33, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0x99D2, 0x99F2, 0xCAB4, 0xD2B4, 0xD2D4, 0xD2B4, 0xD2B4, 0xCAD4, 0xD2B4, 0xD3F5, 0xE777, 0xE797, 0xEF97, 0xE796, 0xE796, 0xE776, 0xE777, 0xE796, 0xE796, 0xE796, 0xE777, 0xEF97, 0x8191, 0x8191, 0xD2B4, 0xD2B4, 0xD2D4, 0xD2D4, 0xD2B4, 0xD2B4, 0xCAD4, 0xD3D5, 0xE796, 0xE796, 0xE796, 0xCE15, 0x8191, 0x99F2, 0xCAD4, 0xD2B4, 0xD2D4, 0xD2B4, 0xD2B4, 0xCAB4, 0xD2B4, 0xDD35, 0xE777, 0xEF76, 0xE796, 0xE797, 0xE797, 0xE776, 0xE796, 0xE776, 0xC534, 0xB494, 0xCC15, 0xD3F5, 0xDBF4, 0xDBF4, 0xDBF5, 0xD3F5, 0xD3F4, 0xCB34, 0x8191, 0xAA32, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2D4, 0xD2B4, 0xCAB4, 0xE656, 0xE776, 0xE796, 0xE796, 0xE776, 0xB494, 0x8191, 0xAA33, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xDE56, 0xE796, 0xE796, 0xE796, 0xCE15, 0x8191, 0x99F2, 0xD2B4, 0xD2B4, 0xD2D4, 0xD2B4, 0xD2D4, 0xCAD4, 0xCAD4, 0xDD15, 0xE796, 0xE796, 0xE776, 0xE796, 0xEF96, 0xE796, 0xE796, 0xE796, 0x9B13, 0x8191, 0xBA73, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xE797, 0xEF97, 0xEF77, 0xEF97, 0xEF78, 0xEF98, 0xEF98, 0xEF98, 0xC992, 0xB8D1, 0xC0D1, 0xC0B1, + 0xB8D1, 0xB8D1, 0xB8D1, 0xF796, 0xF7B6, 0xF796, 0xF795, 0xF795, 0xF796, 0xEFB6, 0xBC93, 0x8191, 0xAA52, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2F5, 0xD2F5, 0xD2F4, 0xDD55, 0xF7B6, 0xF7B6, 0xF7B6, 0xF7B6, 0xF7B6, 0xF7B6, 0xF7B6, 0xF7B6, 0xF7B6, 0xEFB6, 0xBC93, 0x8191, 0xAA53, 0xD2F5, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xE675, 0xF796, 0xF795, 0xF796, 0xF796, 0xF796, 0xF7B6, 0xF7B5, 0xF7B5, 0xEF96, 0xF796, 0xBC93, 0x8191, 0xAA33, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0x99F2, 0x99F2, 0xD2F5, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2D4, 0xD2F4, 0xD2F4, 0xDC75, 0xF795, 0xF795, 0xF795, 0xF796, 0xF7B5, 0xF796, 0xF796, 0xF796, 0xF796, 0xEFB6, 0xF7B5, 0xF796, 0x8191, 0x8991, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xDC15, 0xF796, 0xF796, 0xF796, 0xD615, 0x8191, 0x99F2, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2F4, 0xD2F5, 0xE535, 0xF7B6, 0xF7B5, 0xF796, 0xEFB6, 0xF796, 0xF795, 0xF7B6, 0xF796, 0xF7B6, 0xF795, 0xF796, 0xF796, 0xF795, 0xF7B6, 0xF795, 0xF7B6, 0xF796, 0xBC93, 0x8191, 0xAA53, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xEE75, 0xF796, 0xF796, 0xF7B5, 0xF796, 0xBC93, 0x8191, 0xAA33, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xEE75, 0xF796, 0xF7B5, 0xF795, 0xD634, 0x8191, 0x99F2, 0xD2F4, 0xD2F5, 0xD2F4, 0xD2F5, 0xD2F5, 0xD2F5, 0xD2D4, 0xE555, 0xF796, 0xF7B5, 0xF7B6, 0xF7B6, 0xF795, 0xF7B6, 0xF796, 0xF7B6, 0xA311, 0x8191, 0xBA94, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xF796, 0xF796, 0xF797, 0xF797, 0xF797, 0xF7B7, 0xF798, 0xF798, 0xD273, 0xB8D1, 0xB8D1, 0xB8D1, + 0xB8D1, 0xB8D1, 0xB8D1, 0xFF94, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB4, 0xFFB5, 0xC493, 0x8191, 0xAA53, 0xD315, 0xD335, 0xD335, 0xD335, 0xD334, 0xD315, 0xD335, 0xE575, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xC493, 0x8191, 0xAA53, 0xD335, 0xD335, 0xD314, 0xD315, 0xD335, 0xD335, 0xD335, 0xF675, 0xFFB5, 0xFFB4, 0xFFB5, 0xFFB5, 0xFFB4, 0xFFB4, 0xFFB4, 0xFFB5, 0xFFB5, 0xFF95, 0xC493, 0x8191, 0xAA53, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xD315, 0xD335, 0x99F2, 0x99F2, 0xD335, 0xD314, 0xD315, 0xD335, 0xD335, 0xD315, 0xD335, 0xDC54, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB4, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB4, 0xFFB5, 0x8191, 0x8191, 0xD334, 0xD315, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xDC34, 0xFFB4, 0xFFB5, 0xFFB5, 0xDE34, 0x8191, 0x99F2, 0xD314, 0xD335, 0xD315, 0xD334, 0xD334, 0xD335, 0xD335, 0xE574, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB4, 0xFFB4, 0xFFB5, 0xFFB4, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB4, 0xFFB5, 0xFFB5, 0xC4B3, 0x8191, 0xAA53, 0xD335, 0xD335, 0xD314, 0xD315, 0xD335, 0xD335, 0xD335, 0xEDF5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xC493, 0x8191, 0xAA53, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xD315, 0xD335, 0xF694, 0xFFB5, 0xFFB5, 0xFFB5, 0xDE14, 0x8191, 0x99F2, 0xD335, 0xD335, 0xD314, 0xD334, 0xD314, 0xD334, 0xD315, 0xE555, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB4, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xA332, 0x8191, 0xBAB4, 0xD335, 0xD335, 0xD335, 0xD315, 0xD334, 0xD335, 0xD335, 0xFFB5, 0xFFB6, 0xFFB6, 0xFFB6, 0xFFB6, 0xFFB6, 0xFFB7, 0xFFB8, 0xDBD4, 0xB8D2, 0xB8D1, 0xB8D1, + 0xB8D1, 0xB8D1, 0xB8D1, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE4E, 0xFE4E, 0xC3F0, 0x8191, 0xAA73, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xECD1, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xC3EF, 0x8191, 0xAA73, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD354, 0xF590, 0xFE4E, 0xFE4E, 0xFE2E, 0xFE2E, 0xFE4E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xC3EF, 0x8191, 0xAA73, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0x9A12, 0x91F2, 0xD355, 0xD354, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xDBD4, 0xFE4E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE4E, 0xFE2E, 0xFE4E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE4E, 0x8191, 0x8191, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xDC13, 0xFE4E, 0xFE2E, 0xFE2E, 0xE50F, 0x8191, 0x99F2, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD354, 0xECD1, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE4E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE4E, 0xFE4E, 0xFE2E, 0xFE2E, 0xC3CF, 0x8191, 0xAA73, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xE4D1, 0xFE4E, 0xFE2E, 0xFE2E, 0xFE4E, 0xC3D0, 0x8191, 0xAA73, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xF590, 0xFE4E, 0xFE2E, 0xFE2E, 0xE50F, 0x8191, 0x9A12, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xECD2, 0xFE2E, 0xFE4E, 0xFE2E, 0xFE4E, 0xFE4E, 0xFE4E, 0xFE4D, 0xFE2F, 0xA2B0, 0x8191, 0xC2F4, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xFE2F, 0xFE50, 0xFE50, 0xFE50, 0xFE51, 0xFE51, 0xFE52, 0xFE52, 0xE3D2, 0xB8D2, 0xB8D1, 0xB8D1, + 0xB8D1, 0xB0D1, 0xB0D2, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC6D, 0xC30F, 0x81B1, 0xAA73, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD375, 0xEC11, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC8D, 0xC30F, 0x8191, 0xAA93, 0xD375, 0xD375, 0xD395, 0xD395, 0xD375, 0xD395, 0xD396, 0xF42F, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC8D, 0xC30F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD395, 0x9A12, 0x8191, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xF44F, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC8D, 0xFC6D, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD396, 0xDBD3, 0xFC8D, 0xFC6D, 0xFC6D, 0xE3CE, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD376, 0xD395, 0xD395, 0xD395, 0xEC11, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC6D, 0xFC8D, 0xC30F, 0x8191, 0xAA93, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEBF1, 0xFC8D, 0xFC6D, 0xFC8D, 0xFC6D, 0xC30F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD395, 0xF42F, 0xFC6D, 0xFC6D, 0xFC8D, 0xE3CE, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD375, 0xD395, 0xD376, 0xD395, 0xD395, 0xEBF1, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC8D, 0xA250, 0x8191, 0xC314, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xFC8E, 0xFC8F, 0xFC8F, 0xFC8F, 0xFCB0, 0xFCB0, 0xFCB1, 0xFCB1, 0xF3B2, 0xB8D1, 0xB0F1, 0xB8D1, + 0xB0F1, 0xB0F1, 0xB0D1, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xC30F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC11, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xC30F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF44F, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xC30F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0x9A12, 0x8191, 0xC334, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDBB4, 0xFC8E, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xDBD3, 0xFC8D, 0xFC8D, 0xFC8D, 0xE3CE, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC11, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xCB2F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xEC11, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xC30F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF44F, 0xFC8D, 0xFC8D, 0xFC8D, 0xCB6F, 0x8191, 0x9A32, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC11, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xA250, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFC8E, 0xFC8F, 0xFCAF, 0xFCAF, 0xFCB0, 0xFCB0, 0xFCB0, 0xFCB2, 0xF451, 0xB0D1, 0xB0D1, 0xB0D1, + 0xB0F1, 0xB0F1, 0xB0D1, 0xFCAD, 0xFCCD, 0xFCAD, 0xFCAD, 0xFCCD, 0xFCCD, 0xFCCD, 0xCB4E, 0x8191, 0xAA73, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC31, 0xFCAD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xC32F, 0x8991, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF46F, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCAD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCAD, 0xFCAD, 0xFCAD, 0xC32F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xBB11, 0x8191, 0xAA73, 0xD396, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xDBB4, 0xFCAE, 0xFCAD, 0xFCCD, 0xFCAD, 0xFCCD, 0xFCAD, 0xFCCD, 0xFCCD, 0xFCAD, 0xFCAD, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xDBD3, 0xFCAD, 0xFCCD, 0xFCCD, 0xDBEE, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC31, 0xFCCD, 0xFCAD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCAD, 0xFCCD, 0xFCAD, 0xFCCD, 0xDBEE, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDBD3, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xC32F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF46F, 0xFCAD, 0xFCCD, 0xFCCD, 0xC32F, 0x8991, 0xAA94, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC31, 0xFCCD, 0xFCCD, 0xFCAD, 0xFCCD, 0xFCAD, 0xFCAD, 0xFCAD, 0xFCAD, 0xA270, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFCCE, 0xFCCF, 0xFCCF, 0xFCEF, 0xFCD0, 0xFCF0, 0xFCF1, 0xFCF1, 0xFCF2, 0xB0F1, 0xB0F1, 0xB0F2, + 0xB0F1, 0xA8F1, 0xB0F1, 0xFD0D, 0xFCED, 0xFCED, 0xFCED, 0xFD0D, 0xFCED, 0xFD0D, 0xE42E, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC51, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xC34F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF48F, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xC32F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC6F, 0x91D1, 0x89D1, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xDBB4, 0xEC70, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFD0D, 0xFCED, 0xFCED, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDBF3, 0xFCED, 0xFCED, 0xFCED, 0xE42E, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC51, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFD0D, 0xFCED, 0xEC6E, 0x8191, 0x91F2, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD376, 0xD395, 0xD395, 0xF4AF, 0xFD0D, 0xFCED, 0xFD0D, 0xC34F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF48F, 0xFCED, 0xFCED, 0xFCED, 0xC34F, 0x8191, 0xAA93, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC51, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xA270, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFD0E, 0xFD0F, 0xFD0F, 0xFD0F, 0xFD10, 0xFD10, 0xFD31, 0xFD31, 0xFD32, 0xB0F1, 0xB0F1, 0xB0F1, + 0xB0F1, 0xA8F1, 0xB0F1, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xE44E, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC71, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xC34F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF4CF, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xC34F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF4CF, 0xC34F, 0x8191, 0xB2D4, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDBD4, 0xE431, 0xEC71, 0xEC71, 0xDBF0, 0xE450, 0xF4CF, 0xFD0E, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDBD4, 0xF4AF, 0xF4CF, 0xF4AF, 0xDC10, 0x9A12, 0xAA73, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC71, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2C, 0xFD2C, 0x9211, 0x8191, 0xD375, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC71, 0xFCEE, 0xFD2D, 0xC36F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDC10, 0xE44E, 0xDC2E, 0xE44E, 0xB2F0, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC71, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xA270, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFD2E, 0xFD2F, 0xFD2F, 0xFD4F, 0xFD50, 0xFD50, 0xFD51, 0xFD51, 0xFD71, 0xA8F1, 0xB0F1, 0xB0F2, + 0xA8F1, 0xA8F1, 0xA8F2, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD4D, 0xFD6D, 0xFD6D, 0xE46E, 0x8191, 0x9212, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC71, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xC36F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF4EF, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xC36F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF4EF, 0xFD2D, 0x9211, 0x89B2, 0xCB75, 0xD396, 0xD375, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC91, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xCB95, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC71, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD4D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xBB2F, 0x8191, 0xB2D4, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xC314, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC71, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xA290, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFD6E, 0xFD6F, 0xFD6F, 0xFD8F, 0xFD90, 0xFD90, 0xFD91, 0xFD91, 0xFD92, 0xA8F1, 0xA8F1, 0xA8F1, + 0xA8F1, 0xA8F1, 0xA8F1, 0xEC6F, 0xFD8D, 0xFDAD, 0xFD8D, 0xFDAD, 0xFDAD, 0xFDAD, 0xE48E, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC91, 0xFDAD, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xC38F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF52F, 0xFDAD, 0xFD8D, 0xFDAD, 0xFD8D, 0xFD8D, 0xFDAD, 0xFD8D, 0xFD8D, 0xFDAD, 0xFDAD, 0xC38F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF52F, 0xFD8D, 0xE4AE, 0x8991, 0x9A32, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xE491, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC91, 0xFDAD, 0xFDAD, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFDAD, 0xFDAD, 0xFD8D, 0xFD8D, 0xFDAD, 0xFDAD, 0xFD8D, 0xFDAD, 0xF52D, 0x8191, 0x91F2, 0xD395, 0xD395, 0xD395, 0xD395, 0xD376, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xC314, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC91, 0xFD8D, 0xFD8D, 0xFDAD, 0xFDAD, 0xFDAD, 0xFDAD, 0xFDAD, 0xFD8D, 0xA290, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFDAF, 0xFDAF, 0xFDAD, 0xFDAD, 0xFDAD, 0xFD8D, 0xFDAD, 0xFD8D, 0xEC6F, 0xA8F1, 0xA8F1, 0xA8F1, + 0xA911, 0xA911, 0xA911, 0xEC8E, 0xFDED, 0xFDED, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDED, 0xE4CE, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECB1, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xC3AF, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF54F, 0xFDCD, 0xFDCD, 0xFDED, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDED, 0xFDCD, 0xC3AF, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF54F, 0xFDED, 0xFDCD, 0xD44F, 0x8191, 0xB2B3, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xECB1, 0x8991, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECB1, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xBB6F, 0x8191, 0xBAF4, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xC314, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECB1, 0xFDED, 0xFDED, 0xFDCD, 0xFDCD, 0xFDED, 0xFDED, 0xFDED, 0xFDED, 0xA2B0, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xFDEE, 0xFDEF, 0xFDED, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDED, 0xFDED, 0xEC8E, 0xA911, 0xA911, 0xA911, + 0xA911, 0xA911, 0xA111, 0xE42E, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xE4EE, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECD1, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xC3CF, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF56F, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xC3CF, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF56F, 0xFE0D, 0xFE0D, 0xFE0D, 0xD44F, 0x8191, 0xBAD3, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD376, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xECD1, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECD1, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xF5AD, 0x9A70, 0x89B1, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xC314, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECD1, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0E, 0xFE0D, 0xFE0E, 0xFE0E, 0xFE0E, 0xA2B0, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFE0F, 0xFE0F, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xE42E, 0xA111, 0xA911, 0xA911, + 0x80F0, 0xA111, 0xA111, 0xC2B0, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xE50E, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECF1, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xC3EF, 0x8991, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xF58F, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xC3EF, 0x8191, 0xAA93, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF58F, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xE50E, 0x89D1, 0xA253, 0xCB75, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD376, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECF1, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECF1, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xF60E, 0x9A70, 0x91F2, 0xCB75, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xC314, 0x8191, 0xAA93, 0xD395, 0xD396, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECF2, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4E, 0xFE4D, 0xFE4E, 0xFE4D, 0xFE4E, 0xA2D0, 0x8191, 0xC314, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFE4E, 0xFE4F, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xC2B0, 0xA111, 0xA111, 0x80F0, + 0x60EF, 0xA111, 0xA111, 0xA112, 0xFE2D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xE54E, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xED11, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE8D, 0xC40F, 0x8191, 0xAA93, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xF5CF, 0xFE6D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE6D, 0xC40F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF5CE, 0xFE6D, 0xFE6D, 0xFE8D, 0xFE6C, 0xFE8D, 0xF62D, 0xC40F, 0x9A12, 0xB2D4, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECF1, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xED11, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE8D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6C, 0xFE8D, 0xFE6D, 0xFE2D, 0xBBCF, 0x89B1, 0xBAF4, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD396, 0xC314, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xED12, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xA2D0, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFE8F, 0xFE8F, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE2D, 0xA112, 0xA111, 0xA111, 0x60EF, + 0x28CD, 0xA111, 0xA111, 0xA111, 0xCBCF, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xF5ED, 0x89D1, 0x91D2, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xED11, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xC42F, 0x81B1, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF5EF, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFECC, 0xFEAD, 0xC42F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xF5EF, 0xFEAD, 0xFEAC, 0xFEAD, 0xFEAD, 0xFEAC, 0xFEAD, 0xFEAD, 0xF64D, 0xD4CE, 0xBBD0, 0xC3B2, 0xC314, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xED12, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xED31, 0xFEAC, 0xFEAC, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xEE0D, 0xCC6F, 0xBB51, 0xBAD4, 0xCB55, 0xD395, 0xD395, 0xD395, 0xD395, 0xC334, 0x8191, 0xB294, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xED11, 0xFEAE, 0xFECE, 0xFEAD, 0xFEAE, 0xFEAD, 0xFECE, 0xFEAE, 0xFEAE, 0xA2F0, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDC34, 0xFEAF, 0xFED0, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xCBCF, 0xA111, 0xA111, 0xA111, 0x28CD, + 0x18AD, 0x8110, 0x9911, 0xA111, 0xA171, 0xF5ED, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAC, 0xFE6D, 0xF5CF, 0xF5EF, 0xF5CF, 0xF5CF, 0xF5EF, 0xF5CF, 0xFE4D, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFE4E, 0xF5EF, 0xF5EF, 0xF5CF, 0xF5EE, 0xF5EF, 0xF5EF, 0xF5EF, 0xFE8D, 0xFEAC, 0xFEAC, 0xFEAC, 0xFEAC, 0xFEAD, 0xFE8D, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAC, 0xFEAC, 0xFEAD, 0xF64D, 0xF5EF, 0xF5CF, 0xF5EF, 0xF5CF, 0xF5EF, 0xF5EF, 0xF5EF, 0xFE6E, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAC, 0xFEAC, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAC, 0xFEAD, 0xFEAD, 0xF60E, 0xF5EF, 0xF5CF, 0xF5EF, 0xF5EF, 0xF5CF, 0xF64E, 0xFEAC, 0xFEAD, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5CF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5CF, 0xFE4D, 0xFEAC, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAC, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAC, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFE6D, 0xF5EF, 0xF5EF, 0xF5CF, 0xF5CF, 0xFEAD, 0xF62E, 0xF5EF, 0xF5D0, 0xF5EF, 0xF5CF, 0xF5F0, 0xF5F0, 0xF5EF, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5EF, 0xF5F0, 0xFE4F, 0xFECE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAF, 0xF610, 0xF5D0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF610, 0xFEAF, 0xFEAF, 0xFEAF, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xF5ED, 0xA171, 0xA111, 0x9911, 0x8110, 0x18AD, + 0x20AC, 0x38CE, 0x9931, 0x9931, 0x9931, 0xAA31, 0xFE2D, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFEAD, 0xFE8C, 0xFEAC, 0xFEAC, 0xFE8C, 0xFE8C, 0xFEAC, 0xFEAD, 0xFE8D, 0xFE8C, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFE8C, 0xFE8C, 0xFEAC, 0xFEAC, 0xFEAD, 0xFE8C, 0xFEAD, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8C, 0xFEAD, 0xFE8C, 0xFE8C, 0xFEAD, 0xFEAD, 0xFEAC, 0xFEAC, 0xFE8C, 0xFE8C, 0xFEAC, 0xFE8C, 0xFEAC, 0xFEAD, 0xFEAD, 0xFE8D, 0xFE8C, 0xFEAD, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8D, 0xFEAC, 0xFE8C, 0xFEAC, 0xFE8D, 0xFEAD, 0xFEAD, 0xFE8C, 0xFEAC, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8C, 0xFEAC, 0xFE8D, 0xFE8C, 0xFEAD, 0xFEAD, 0xFE8C, 0xFE8C, 0xFE8C, 0xFEAD, 0xFE8C, 0xFEAC, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFE8C, 0xFEAC, 0xFE8D, 0xFEAC, 0xFEAD, 0xFEAD, 0xFE8C, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAC, 0xFE8C, 0xFEAD, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFEAD, 0xFEAD, 0xFEAD, 0xFE8D, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFE8D, 0xFE8E, 0xFEAD, 0xFEAE, 0xFEAE, 0xFEAD, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFE8E, 0xFE8E, 0xFEAE, 0xFEAE, 0xFEAE, 0xFE8E, 0xFEAE, 0xFEAE, 0xFEAE, 0xFE8E, 0xFE8E, 0xFEAE, 0xFEAF, 0xFEAE, 0xFEAE, 0xFEAF, 0xFE8E, 0xFEAF, 0xFEAF, 0xFEAF, 0xFEAF, 0xFEAF, 0xFE8F, 0xFEB0, 0xFEAF, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE2D, 0xAA31, 0x9931, 0x9931, 0x9931, 0x38CE, 0x20AC, + 0x20AD, 0x20AC, 0x60EF, 0x9912, 0x9931, 0x9931, 0xB270, 0xF62D, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE6D, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8E, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8F, 0xFE8E, 0xFE8E, 0xFE8F, 0xFE8F, 0xFE8E, 0xFE8F, 0xFE8F, 0xFE8E, 0xFE8F, 0xFE8E, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE90, 0xFE90, 0xFEB0, 0xFE8C, 0xFE8C, 0xF62D, 0xB270, 0x9931, 0x9931, 0x9912, 0x60EF, 0x20AC, 0x20AD, + 0x18AC, 0x20AC, 0x28AD, 0x8110, 0x9931, 0x9931, 0x9911, 0xAA31, 0xF5CD, 0xFE8C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE8C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE8C, 0xFE6D, 0xFE6D, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6C, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE8E, 0xFE8D, 0xFE8D, 0xFE6E, 0xFE8D, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE8F, 0xFE8F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE8F, 0xFE6F, 0xFE6F, 0xFE8F, 0xFE8F, 0xFE6F, 0xFE6F, 0xFE8F, 0xFE6F, 0xFE6F, 0xFE8F, 0xFE8F, 0xFE6F, 0xFE8F, 0xFE8F, 0xFE6F, 0xFE90, 0xFE8F, 0xFE8F, 0xFE90, 0xFE90, 0xFE8C, 0xF5CD, 0xAA31, 0x9911, 0x9931, 0x9931, 0x8110, 0x28AD, 0x20AC, 0x18AC, + 0x20AC, 0x20AC, 0x18AC, 0x28AD, 0x9111, 0x9931, 0x9931, 0x9931, 0xA171, 0xCBCF, 0xF60D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6C, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6C, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6C, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6E, 0xFE6E, 0xFE4E, 0xFE6D, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6F, 0xFE6E, 0xFE6E, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE70, 0xFE70, 0xFE6F, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE90, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE71, 0xFE71, 0xFE71, 0xE471, 0xCBCF, 0xA171, 0x9931, 0x9931, 0x9931, 0x9111, 0x28AD, 0x18AC, 0x20AC, 0x20AC, + 0x18AC, 0x18AC, 0x18AC, 0x20AC, 0x28CD, 0x8111, 0x9931, 0x9912, 0x9931, 0x9931, 0x9911, 0xBAB0, 0xDC6F, 0xE50F, 0xE50E, 0xFE4E, 0xFE6E, 0xFE4E, 0xFE6D, 0xFE4E, 0xFE4E, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4E, 0xFE4E, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4E, 0xFE4E, 0xFE4E, 0xFE4E, 0xFE6E, 0xFE6E, 0xFE4E, 0xFE4E, 0xFE4E, 0xFE6E, 0xFE6E, 0xFE4E, 0xFE6F, 0xFE6E, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE4F, 0xFE6F, 0xFE70, 0xFE50, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xF612, 0xE531, 0xE512, 0xD472, 0xB271, 0x9931, 0x9931, 0x9931, 0x9912, 0x9931, 0x8111, 0x28CD, 0x20AC, 0x18AC, 0x18AC, 0x18AC, + 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x28CC, 0x610F, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9932, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9912, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9911, 0x9931, 0x9931, 0x9911, 0x9911, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9911, 0x9931, 0x9932, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9912, 0x9931, 0x9931, 0x9931, 0x9911, 0x610F, 0x28CC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, + 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x40CE, 0x7910, 0x9931, 0x9931, 0x9932, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x7910, 0x40CE, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x18AC, + 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AB, 0x30CC, 0x58CF, 0x7910, 0x9931, 0x9931, 0x9912, 0x9931, 0x9931, 0x9911, 0x9931, 0x9911, 0x9932, 0x9931, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9931, 0x9932, 0x9911, 0x9931, 0x9911, 0x9931, 0x9931, 0x9912, 0x9931, 0x9931, 0x7910, 0x58CF, 0x30CC, 0x18AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/bootscreen_228x255x2.cpp b/Marlin/src/lcd/tft/images/bootscreen_228x255x2.cpp new file mode 100644 index 000000000000..08994071538d --- /dev/null +++ b/Marlin/src/lcd/tft/images/bootscreen_228x255x2.cpp @@ -0,0 +1,285 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t marlin_logo_228x255x2[14535] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFE, 0x90, 0x00, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x2F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x01, 0xFF, 0xFF, 0xF9, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0B, 0xFF, 0xFF, 0x80, 0x02, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xAF, 0xFF, 0xF8, 0x00, 0x6F, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xAA, 0x50, 0x1B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x07, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0x1F, 0xFF, 0xFF, 0xF9, 0xBD, 0x00, 0xBF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0xBF, 0xFF, 0xFF, 0x00, 0x0B, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x46, 0xFF, 0xFF, 0xD0, 0x3F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x2F, 0xFF, 0xF8, 0x06, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD1, 0xFF, 0xFC, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x2F, 0xFF, 0x1F, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, 0xFF, 0xC2, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x7F, 0xF0, 0x2F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0xFC, 0x07, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xE5, 0x55, 0x55, 0x56, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2, 0xFF, 0x40, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xBF, 0xFF, 0xFF, 0xFD, 0xBF, 0xC0, 0x2F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x6F, 0xFF, 0xFF, 0xDF, 0xE0, 0x0B, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xBF, 0xFF, 0xF7, 0xF8, 0x02, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFD, 0xFD, 0x00, 0xBF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0x7F, 0x00, 0x1F, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xF9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xDF, 0x80, 0x07, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFE, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xF7, 0xD0, 0x01, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFD, 0xF0, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7C, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xED, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAF, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0xBF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5A, 0x87, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6F, 0xF9, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x0F, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFE, 0x40, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xBF, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x7F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xBF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x2F, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xBF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x6B, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x0B, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFE, 0xAA, 0xA9, 0x55, 0x55, 0x40, 0x55, 0x56, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xD0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x5A, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x90, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF4, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x6A, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x40, 0x00, 0x00, 0x7F, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0B, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x00, 0x00, 0xBF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x07, 0xFF, 0xFD, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x6A, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x7F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xBF, 0xFF, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xBF, 0xFF, 0xFF, 0xE0, 0x2F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x02, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xBF, 0xFF, 0xFE, 0x0B, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x03, 0xF0, 0x00, 0x00, 0xBF, 0xFF, 0xD0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xD0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, 0x00, 0x00, 0x03, 0xF4, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x2F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x02, 0xF8, 0x00, 0x00, 0x2F, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x80, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x01, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x40, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x0B, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xD0, 0x00, 0x00, 0x00, 0x2F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xD0, 0x00, 0x00, 0xBF, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x02, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF0, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFD, 0x00, 0x05, 0xAB, 0xFF, 0xE4, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x3F, 0x40, 0x00, 0x02, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFD, 0x6B, 0xFF, 0xFF, 0xE4, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x02, 0xFF, 0xFF, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x00, 0x2F, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x2F, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xE0, 0x00, 0x0F, 0xC0, 0x00, 0x00, 0xBF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFE, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xD0, 0x00, 0x00, 0xBF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x0B, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xD0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFD, 0x00, 0x06, 0xFF, 0xFF, 0xAA, 0xA5, 0x40, 0x00, 0x05, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFC, 0x00, 0x0B, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xD0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xD0, 0x00, 0x2B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFE, 0x00, 0x0B, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFD, 0x00, 0x00, 0x00, 0x1A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x6A, 0x81, 0x6A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x2F, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0xFF, 0xD1, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x15, 0x69, 0x55, 0x00, 0x00, 0x02, 0xFF, 0x80, 0x03, 0xF0, 0x00, 0x00, 0x2F, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x07, 0xFF, 0xD0, 0xBF, 0xF8, 0x00, 0x00, 0x16, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xA4, 0x01, 0xFF, 0xC0, 0x02, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5B, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x0B, 0xFF, 0xC0, 0x3F, 0xFC, 0x00, 0x1B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE5, 0xFF, 0xD0, 0x02, 0xF4, 0x00, 0x00, 0x0F, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0xFF, 0xFE, 0x40, 0x0F, 0xFF, 0x80, 0x3F, 0xFD, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x01, 0xF4, 0x00, 0x00, 0x0F, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5A, 0xBE, 0x90, 0x00, 0x2F, 0xFF, 0x80, 0x7F, 0xFD, 0x0A, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0xBF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x16, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0xF8, 0x00, 0x00, 0x0B, 0xFF, 0xF4, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x78, 0x00, 0x00, 0x0B, 0xFF, 0xF4, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x3C, 0x00, 0x00, 0x07, 0xFF, 0xF4, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFD, 0x02, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFC, 0x00, 0x3C, 0x00, 0x00, 0x07, 0xFF, 0xF4, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFC, 0x02, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFC, 0x00, 0x2C, 0x00, 0x00, 0x03, 0xFF, 0xF4, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x6F, 0xFF, 0xFC, 0x07, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFD, 0x00, 0x1C, 0x00, 0x00, 0x03, 0xFF, 0xF4, 0x00, + 0x00, 0x00, 0x05, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBF, 0xFF, 0xFF, 0xFE, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x0C, 0x00, 0x00, 0x03, 0xFF, 0xF4, 0x00, + 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x08, 0x00, 0x00, 0x03, 0xFF, 0xF4, 0x00, + 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x04, 0x00, 0x00, 0x02, 0xFF, 0xF4, 0x00, + 0x00, 0x7F, 0xFE, 0xAA, 0xAA, 0xAA, 0xAA, 0xA5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x6A, 0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFA, 0x55, 0x55, 0x55, 0x55, 0x5A, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xF4, 0x00, + 0x01, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xF4, 0x00, + 0x07, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xF0, 0x00, + 0x0F, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xF0, 0x00, + 0x2F, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xF0, 0x00, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xF0, 0x00, + 0xBF, 0x00, 0x00, 0x00, 0x00, 0x06, 0xAA, 0x90, 0x00, 0x00, 0x01, 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFC, 0x00, 0x00, 0x6A, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xF0, 0x00, + 0xFE, 0x00, 0x00, 0x00, 0x01, 0xBF, 0xFF, 0xFE, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFC, 0x00, 0x02, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xF0, 0x00, + 0xFC, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xE0, 0x01, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xF0, 0x00, + 0xFC, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFC, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x05, 0x00, 0x00, 0x01, 0xFF, 0xE0, 0x00, + 0xFC, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0xBF, 0xC0, 0x00, 0x01, 0xFF, 0xE4, 0x00, + 0xFC, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xED, 0x00, + 0xFC, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xBF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xDF, 0x00, + 0xFC, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xEA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0xBF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xDF, 0x80, + 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x2F, 0xFF, 0xFF, 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x01, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xEF, 0xC0, + 0xFC, 0x00, 0x00, 0x7F, 0xFF, 0xD0, 0x00, 0x07, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFC, 0x1F, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xEF, 0xD0, + 0xFC, 0x00, 0x00, 0xBF, 0xFF, 0x40, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xF8, 0x0B, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xEF, 0xF0, + 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x2F, 0xFF, 0xC0, 0x00, 0x00, 0x6F, 0xFF, 0xF9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x06, 0xAA, 0xA0, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0xF9, 0x02, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xBF, 0xF0, + 0xFC, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x80, 0x00, 0x00, 0x0F, 0xFF, 0xD0, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFE, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xD0, 0x7F, 0xFF, 0xFF, 0xF8, 0x02, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xBF, 0x54, + 0xFC, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x80, 0x00, 0x00, 0x0F, 0xFF, 0xD0, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x02, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xF4, 0x1F, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xD0, 0x00, 0x01, 0xFF, 0x7F, 0x00, + 0xFC, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x80, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x02, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFE, 0x07, 0xFF, 0xFF, 0xF8, 0x00, 0xFF, 0xD0, 0x00, 0x01, 0xFF, 0x3F, 0x00, + 0xFC, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x80, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x02, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0xFF, 0xFF, 0xF8, 0x00, 0xFF, 0xD0, 0x00, 0x01, 0xFF, 0x3E, 0x00, + 0xFC, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x02, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xF8, 0x00, 0x7F, 0xE0, 0x00, 0x01, 0xFE, 0x3E, 0x00, + 0xFC, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x0F, 0xFF, 0xF8, 0x00, 0x2F, 0xF0, 0x00, 0x01, 0xFE, 0x7D, 0x00, + 0xFC, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x3F, 0xFF, 0xFE, 0x40, 0x7F, 0xFF, 0xFD, 0x00, 0x00, 0xBF, 0xFF, 0xF4, 0x07, 0xFF, 0xFF, 0x82, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xFE, 0x01, 0xBF, 0xFF, 0xF0, 0x03, 0xFF, 0xF8, 0x00, 0x2F, 0xF0, 0x00, 0x01, 0xFD, 0x7D, 0x00, + 0xFC, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x7F, 0xFF, 0xF4, 0x00, 0x0B, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0xBF, 0xFF, 0xC2, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x2F, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xF4, 0x00, 0xBF, 0xF8, 0x00, 0x2F, 0xF4, 0x00, 0x01, 0xFC, 0x7C, 0x00, + 0xFC, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0xBF, 0xFF, 0xC0, 0x00, 0x02, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xC2, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x0B, 0xFF, 0xF8, 0x00, 0x3F, 0xF8, 0x00, 0x1F, 0xF8, 0x00, 0x01, 0xFC, 0x3C, 0x00, + 0xFC, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0xBF, 0xFF, 0x40, 0x01, 0xFF, 0xFD, 0x00, 0x00, 0x1F, 0xFF, 0xD2, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x0F, 0xF8, 0x00, 0x07, 0xFC, 0x00, 0x02, 0xFC, 0x3E, 0x00, + 0xFC, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x0F, 0xFF, 0xE1, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x02, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xD2, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0x40, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x07, 0xF8, 0x00, 0x02, 0xFC, 0x00, 0x02, 0xF8, 0x1F, 0x00, + 0xFC, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x0F, 0xFF, 0xE2, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xC0, 0x02, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xE2, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0x40, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x00, 0xFE, 0x00, 0x02, 0xF4, 0x0B, 0x80, + 0xFC, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x0F, 0xFF, 0xE2, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xC0, 0x02, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xE2, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x7F, 0x00, 0x03, 0xF4, 0x03, 0xC0, + 0xFC, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x0F, 0xFF, 0xE2, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xC0, 0x02, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x1F, 0x80, 0x03, 0xF0, 0x00, 0xE0, + 0xFC, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x0F, 0xFF, 0xE2, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xC0, 0x02, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x0B, 0xC0, 0x03, 0xF0, 0x00, 0x34, + 0xFC, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x0F, 0xFF, 0xE2, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xC0, 0x02, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x02, 0xE0, 0x03, 0xE0, 0x00, 0x0C, + 0xFC, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x0F, 0xFF, 0xE2, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xC0, 0x02, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x74, 0x07, 0xD0, 0x00, 0x00, + 0xFC, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x0F, 0xFF, 0xE1, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xC0, 0x02, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x08, 0x07, 0xC0, 0x00, 0x00, + 0xFC, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x1F, 0xFF, 0xC0, 0x02, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xC0, 0x00, 0x00, + 0xFC, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0xBF, 0xFF, 0xE0, 0x00, 0x00, 0x1F, 0xFF, 0xC0, 0x02, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFD, 0x00, 0x0B, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x80, 0x00, 0x00, + 0xFC, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x7F, 0xFF, 0xFD, 0x00, 0x00, 0x1F, 0xFF, 0xC0, 0x02, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x40, 0x0B, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x40, 0x00, 0x00, + 0xFC, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x3F, 0xFF, 0xFF, 0xFA, 0xA8, 0x1F, 0xFF, 0xEA, 0xAB, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xE9, 0x0B, 0xFF, 0xF5, 0x55, 0xBF, 0xFF, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, + 0xFC, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0x4B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, + 0xFC, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x4B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, + 0xFC, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x02, 0xFF, 0xFF, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x4B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, + 0xFC, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x7F, 0xFF, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0x4B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0xFC, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0x4B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x03, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0xFD, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x40, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x01, 0xBF, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0x4B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x02, 0xFF, 0xFC, 0x00, 0x07, 0xF0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFE, 0x00, 0x00, 0x6A, 0xA9, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0x40, 0x00, 0x00, 0x0A, 0xAA, 0x90, 0x00, 0x00, 0x06, 0xAA, 0xA8, 0x0A, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x6A, 0x46, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x02, 0xAA, 0xA0, 0x00, 0x0B, 0xF2, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xBF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xD3, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xC7, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x47, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0B, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFE, 0x07, 0xD0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x02, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xF8, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0xBF, 0xFA, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x56, 0xFF, 0xE0, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x07, 0x80, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x0B, 0x80, 0x00, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x40, 0x00, 0x1F, 0x40, 0x00, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x56, 0xAA, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAB, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEA, 0xA5, 0x55, 0xAA, 0xBF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFA, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5B, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xD0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xF4, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xEA, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFD, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xF9, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xE4, 0x00, 0x00, 0x02, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x02, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x01, 0xFF, 0xD0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xBF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF, 0xF8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xF0, 0x00, 0x7F, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xF8, 0x00, 0x3F, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFE, 0x00, 0x3F, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x40, 0x2F, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xE0, 0x0F, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF4, 0x0F, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x0F, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x0B, 0xFF, 0xD0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0x0B, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xCB, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xD7, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xF7, 0xFF, 0xF4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFD, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFD, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFD, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFD, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xD0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/bootscreen_228x255x4.cpp b/Marlin/src/lcd/tft/images/bootscreen_228x255x4.cpp new file mode 100644 index 000000000000..3ed61a1b20d2 --- /dev/null +++ b/Marlin/src/lcd/tft/images/bootscreen_228x255x4.cpp @@ -0,0 +1,285 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t marlin_logo_228x255x4[29070] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xDF, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0xFF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xEF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xAF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0xFF, 0xFF, 0xFF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xCF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x57, 0x77, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x8C, 0xEF, 0xFF, 0xFF, 0xFF, 0xD8, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE, 0xDF, 0xFE, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0x84, 0x32, 0x10, 0x00, 0x46, 0x89, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x28, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x83, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x10, 0x00, 0x00, 0x18, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x00, 0x04, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB7, 0x10, 0x00, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x01, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xB3, 0x00, 0x00, 0x38, 0xE8, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x22, 0x22, 0x11, 0x11, 0x12, 0x35, 0x57, 0x8B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8A, 0xFF, 0xFF, 0xFF, 0xFF, 0xB3, 0x00, 0x00, 0x4B, 0xEF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0xEF, 0xFF, 0xFF, 0xFF, 0xED, 0xBA, 0x98, 0x64, 0x00, 0x05, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xDF, 0xFF, 0xFF, 0xC5, 0x00, 0x01, 0x6C, 0xFF, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x97, 0x30, 0x37, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0x9F, 0xE7, 0x10, 0x01, 0x8D, 0xFF, 0xFD, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA8, 0x23, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x30, 0x10, 0x01, 0x8E, 0xFF, 0xFF, 0xC2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x60, 0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x0E, 0xFF, 0xFF, 0xF8, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA6, 0x39, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0x00, 0x7B, 0xFE, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC6, 0x07, 0xFF, 0xFF, 0xFF, 0xF3, 0x88, 0x50, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC6, 0x19, 0xFF, 0xFF, 0xFE, 0x37, 0xDF, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC6, 0x3C, 0xFF, 0xFF, 0xE3, 0x08, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0x7F, 0xFF, 0xFE, 0x30, 0x3A, 0xFF, 0xF8, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xDF, 0xFF, 0xE3, 0x00, 0x7F, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD8, 0x76, 0x54, 0x44, 0x44, 0x55, 0x66, 0x68, 0x89, 0xBB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x2A, 0xFF, 0xFF, 0x50, 0x03, 0xDF, 0xFF, 0xC2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x58, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x8F, 0xFF, 0xE0, 0x00, 0x1B, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC5, 0xFF, 0xF9, 0x00, 0x00, 0x8F, 0xFF, 0xFC, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x9F, 0xFF, 0xFF, 0xFF, 0xFE, 0x6E, 0xFF, 0x80, 0x00, 0x08, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7D, 0xFF, 0xFF, 0xFF, 0xF7, 0xCF, 0xF6, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0xFF, 0xFF, 0xFF, 0x5C, 0xFF, 0x20, 0x00, 0x04, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xB6, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0xFF, 0xFF, 0xF4, 0xDF, 0xB0, 0x00, 0x00, 0x4F, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC8, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0xFF, 0xFE, 0x4F, 0xF7, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xEB, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0xFF, 0xE6, 0xFF, 0x30, 0x00, 0x00, 0x5F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xC8, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0xFD, 0x6F, 0xD0, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xB3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xCA, 0xF5, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xFC, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xFF, 0xB3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x9A, 0xCE, 0x00, 0x00, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xEF, 0xC5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x2F, 0x80, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x57, 0x89, 0x91, 0x7F, 0xE7, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF2, 0x00, 0x00, 0x00, 0x1D, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x6B, 0xEF, 0xFE, 0xB7, 0x18, 0xFB, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCA, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x8E, 0xFF, 0xEA, 0x51, 0x01, 0x8B, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x40, 0x00, 0x00, 0x00, 0x5F, 0xFF, 0xFF, 0xFF, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x8E, 0xFF, 0xE8, 0x20, 0x00, 0x06, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xC0, 0x00, 0x00, 0x00, 0x0A, 0xFF, 0xFF, 0xFF, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xCF, 0xFF, 0xFA, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5, 0x00, 0x00, 0x00, 0x01, 0xDF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0xDF, 0xFF, 0xFD, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x4F, 0xFF, 0xFF, 0xFF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x8C, 0xFF, 0xFF, 0xFF, 0xB1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x50, 0x00, 0x00, 0x00, 0x0A, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x47, 0x9C, 0xEF, 0xFF, 0xFF, 0xFF, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFE, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x68, 0x9C, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFF, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x57, 0x8B, 0xCE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9F, 0xFE, 0xDB, 0xAA, 0x98, 0x88, 0x87, 0x66, 0x55, 0x54, 0x44, 0x43, 0x33, 0x44, 0x55, 0x67, 0x78, 0x89, 0xBC, 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0xFE, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB8, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xFF, 0xFF, 0xFF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0xD8, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x89, 0xBB, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x96, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x56, 0x88, 0x9B, 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x35, 0x68, 0x8B, 0xBD, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x23, 0x56, 0x78, 0x9B, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x84, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x50, 0x00, 0x00, 0x00, 0x00, 0x4F, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x68, 0x9B, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD8, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0xF1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x20, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xAE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x20, 0x08, 0xFF, 0xFF, 0xF9, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x01, 0xDF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x8F, 0xFE, 0xB1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0x00, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x88, 0x00, 0x38, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8E, 0xB1, 0x00, 0x00, 0x07, 0xEF, 0xFF, 0xFF, 0xFC, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xF9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8E, 0xF8, 0x10, 0x00, 0x00, 0x00, 0x07, 0xDF, 0xFF, 0xFF, 0xD3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFD, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xDF, 0xFF, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xDF, 0xFF, 0xFF, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFE, 0x30, 0x00, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8F, 0xFF, 0xF7, 0x00, 0x00, 0x13, 0x57, 0x8A, 0xBC, 0xDE, 0xFF, 0xEB, 0x50, 0x6D, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xFF, 0xFF, 0xC4, 0x58, 0xBC, 0xEF, 0xFF, 0xFF, 0xFF, 0xCA, 0x63, 0x00, 0x00, 0x00, 0x8F, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xFF, 0xFF, 0xFF, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC8, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xFF, 0xE1, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0xFF, 0xFF, 0xA0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x83, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xAF, 0xFF, 0xFF, 0xFF, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xF9, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x6E, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xDF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0xF2, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0x90, 0x00, 0x00, 0x00, 0xBF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x9F, 0xFF, 0xFF, 0xFF, 0xD7, 0x10, 0x00, 0x01, 0x7B, 0xCE, 0xEE, 0xEE, 0xDD, 0xBA, 0x98, 0x88, 0x65, 0x43, 0x32, 0x21, 0x12, 0x33, 0x57, 0xCE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x8F, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xFF, 0xFF, 0xFF, 0xE7, 0x10, 0x00, 0x00, 0x2A, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFA, 0x00, 0x00, 0x00, 0x8F, 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xF9, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xE7, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x8B, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x81, 0x78, 0x88, 0x82, 0x04, 0x78, 0x98, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x4F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFA, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFB, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x09, 0xFF, 0xFF, 0xF7, 0x07, 0xFF, 0xFF, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x35, 0x77, 0x78, 0x87, 0x65, 0x44, 0x20, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x0D, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0xFF, 0xFE, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x30, 0x4F, 0xFF, 0xFF, 0xF5, 0x00, 0x8F, 0xFF, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x35, 0x78, 0xCD, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDA, 0x98, 0x52, 0x00, 0x06, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x08, 0xFF, 0x30, 0x00, 0x00, 0x00, 0x00, 0x05, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xEF, 0xFF, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x71, 0x00, 0xAF, 0xFF, 0xFF, 0xE1, 0x00, 0x2F, 0xFF, 0xFF, 0xF2, 0x00, 0x00, 0x37, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x65, 0xFF, 0xFF, 0xF5, 0x00, 0x00, 0x08, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xFF, 0xF9, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x71, 0x00, 0x02, 0xEF, 0xFF, 0xFF, 0xB0, 0x00, 0x3F, 0xFF, 0xFF, 0xF5, 0x00, 0x5C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x00, 0x00, 0x05, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0xFE, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x89, 0xBC, 0xCA, 0x84, 0x10, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x7F, 0xFF, 0xFF, 0xF4, 0x01, 0x89, 0xAB, 0xBC, 0xDE, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x01, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xFF, 0xFF, 0xFF, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xE5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x9F, 0xFF, 0xFF, 0xE2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x35, 0x68, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, 0x00, 0x00, 0xDF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xFC, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x7A, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x6F, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xB1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFA, 0x00, 0x03, 0xFF, 0xFF, 0xFE, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x58, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB0, 0x00, 0x00, 0x1F, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0xFF, 0xFF, 0xFF, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAF, 0xFF, 0xFF, 0xF6, 0x00, 0x08, 0xFF, 0xFF, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x0D, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0xFF, 0xFF, 0xFF, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xF2, 0x00, 0x0B, 0xFF, 0xFF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x00, 0x00, 0x08, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x23, 0x55, 0x78, 0xCF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x5F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x05, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x88, 0x88, 0x88, 0x89, 0x99, 0x99, 0x99, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xCC, 0xCC, 0xCC, 0xCC, 0xCD, 0xDD, 0xDD, 0xEE, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xBC, 0xEF, 0xFF, 0xFF, 0xFF, 0xDD, 0xCC, 0xCB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0xCC, 0xCC, 0xCC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x00, 0x00, 0x00, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0xFF, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xFF, 0xFF, 0xFF, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x4C, 0xFF, 0xFF, 0xFB, 0xA9, 0x98, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xA8, 0x77, 0x76, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x77, 0x88, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, + 0x00, 0x06, 0xEF, 0xFF, 0xE8, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, + 0x00, 0x6E, 0xFF, 0xFB, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0x30, 0x00, 0x00, + 0x03, 0xEF, 0xFE, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, + 0x0B, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, + 0x5F, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, + 0xAF, 0xFE, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0x9B, 0xBA, 0x85, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x89, 0xBA, 0xA9, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x01, 0x48, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0xFF, 0xF9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xAE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x20, 0x00, 0x00, 0x00, 0x18, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x1A, 0xFF, 0xFF, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, + 0xFF, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x07, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x5F, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0x00, 0x00, 0x01, 0x47, 0x20, 0x00, 0x00, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xFB, 0x00, 0x00, 0x00, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x3A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0x00, 0x02, 0x8D, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xF9, 0x50, 0x00, 0x00, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0x04, 0xCE, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xF8, 0xD6, 0x00, 0x00, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA1, 0x8E, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xF7, 0xFE, 0x20, 0x00, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDA, 0xBB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xAA, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xF7, 0xFF, 0x80, 0x00, + 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xFF, 0xFF, 0xFF, 0xFF, 0xB3, 0x00, 0x00, 0x38, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x31, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x35, 0x55, 0x55, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xEF, 0xFF, 0xFF, 0xFF, 0xF1, 0x00, 0x00, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xF8, 0xFF, 0xE0, 0x00, + 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x4F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x70, 0x00, 0x00, 0x00, 0x03, 0xEF, 0xFF, 0xFF, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x05, 0xFF, 0xFF, 0xFF, 0xF1, 0x00, 0x00, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xFA, 0xFF, 0xF6, 0x00, + 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0xAF, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x34, 0x44, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x34, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x35, 0x44, 0x20, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB0, 0x00, 0x9F, 0xFF, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xDA, 0xFF, 0xFD, 0x00, + 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFD, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xFF, 0xFF, 0xFF, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xFF, 0xFF, 0xFF, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x01, 0x49, 0xEF, 0xFF, 0xFF, 0xFF, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xCF, 0xFF, 0xFF, 0xFF, 0xC8, 0x20, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x68, 0x88, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x4A, 0xEF, 0xFF, 0xFF, 0xFF, 0xA6, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB0, 0x00, 0x5F, 0xFF, 0xFF, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xAD, 0xFF, 0xFF, 0x20, + 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x5C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC5, 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0x00, 0x09, 0xFF, 0xFF, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0x8D, 0xFF, 0x47, 0x60, + 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0xFF, 0xFF, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x70, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0x00, 0x05, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x05, 0xFF, 0xFF, 0x5F, 0xFE, 0x00, 0x00, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x01, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x40, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x01, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x4F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0x00, 0x01, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x05, 0xFF, 0xFF, 0x3F, 0xFC, 0x00, 0x00, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x1B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE2, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0x03, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0x00, 0x00, 0xEF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x05, 0xFF, 0xFE, 0x3F, 0xF9, 0x00, 0x00, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE2, 0x00, 0x3E, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0x00, 0x00, 0x5F, 0xFF, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFB, 0x3F, 0xF8, 0x00, 0x00, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x5F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x30, 0x0B, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x00, 0x01, 0xCF, 0xFF, 0xFF, 0xFF, 0x90, 0x00, 0x00, 0x0A, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xF8, 0x4F, 0xF5, 0x00, 0x00, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x1E, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0x43, 0x23, 0x7D, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0x00, 0x00, 0x00, 0x00, 0xAF, 0xFF, 0xFF, 0xFF, 0xFE, 0x73, 0x32, 0x7D, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0x0B, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0x33, 0x35, 0x8F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x1C, 0xFF, 0xFF, 0xFF, 0x90, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xF5, 0x4F, 0xF4, 0x00, 0x00, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFC, 0x40, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0xFA, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xA2, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xE0, 0x0B, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFD, 0x20, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0x90, 0x00, 0x00, 0x09, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xF2, 0x4F, 0xF2, 0x00, 0x00, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x05, 0xFF, 0xFF, 0xFF, 0xFA, 0x10, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0xFF, 0xF2, 0x0B, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0xA0, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0x90, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x1F, 0xF3, 0x00, 0x00, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xFF, 0xFE, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0xF4, 0x0B, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xFF, 0xFF, 0xFF, 0xB0, 0x00, 0x00, 0x01, 0xDF, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xC0, 0x0D, 0xF8, 0x00, 0x00, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF7, 0x0B, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x4F, 0xFF, 0xFF, 0xFF, 0x50, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x0A, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x0A, 0xFF, 0x90, 0x04, 0xFE, 0x00, 0x00, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF8, 0x08, 0xFF, 0xFF, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF8, 0x0B, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x4F, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x01, 0xDF, 0xF9, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0x60, 0x00, 0x9F, 0x80, 0x00, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF8, 0x09, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xF1, 0x00, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0xFF, 0xF8, 0x0B, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x5F, 0xFF, 0xFF, 0xFF, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4F, 0xFE, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0x50, 0x00, 0x0C, 0xE2, 0x00, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF8, 0x0A, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xF3, 0x00, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x0B, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0x80, 0x00, 0x00, 0x0F, 0xFF, 0x10, 0x00, 0x01, 0xDA, 0x00, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF8, 0x0B, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xF3, 0x00, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9F, 0xF2, 0x00, 0x00, 0x2F, 0xFC, 0x00, 0x00, 0x00, 0x3E, 0x50, + 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF8, 0x0B, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xF3, 0x00, 0x00, 0x0A, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFB, 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x00, 0x00, 0x03, 0xD2, + 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF8, 0x08, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0xF3, 0x00, 0x00, 0x0A, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x50, 0x00, 0x5F, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x11, + 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF8, 0x06, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0xF3, 0x00, 0x00, 0x0A, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xF1, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x90, 0x00, 0x7F, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0xF3, 0x00, 0x00, 0x0A, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xF3, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0xF3, 0x00, 0x00, 0x0A, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x4F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0xF3, 0x00, 0x00, 0x0A, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFE, 0x50, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAF, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xBA, 0xA9, 0x80, 0x06, 0xFF, 0xFF, 0xFF, 0xF9, 0x88, 0x88, 0x8C, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xF9, 0x84, 0x10, 0x9F, 0xFF, 0xFF, 0xFE, 0x66, 0x66, 0x66, 0xAF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x5F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x70, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xF1, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0x70, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xF1, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x03, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0x70, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x05, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0xFF, 0xFF, 0xFF, 0x70, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x5F, 0xFF, 0x30, 0x28, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFB, 0x00, 0x00, 0x00, 0x00, 0x69, 0xAA, 0xAA, 0xA5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xAA, 0xAA, 0xAA, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x99, 0x99, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x89, 0x9A, 0xAA, 0x90, 0x03, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x78, 0xAA, 0x60, 0x6A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x20, 0x00, 0x00, 0x00, 0x00, 0x08, 0xAA, 0xAA, 0xA8, 0x30, 0x00, 0x00, 0x00, 0xBF, 0xFC, 0x08, 0xEF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8F, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xF6, 0x3F, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0xFF, 0xD1, 0x4F, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xFF, 0xFC, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xCF, 0xFF, 0x60, 0x6F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xBF, 0xFF, 0xC2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0xFF, 0xF8, 0x00, 0x6F, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0A, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xFF, 0xFF, 0x90, 0x00, 0x6F, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9F, 0xFF, 0xFD, 0x88, 0x64, 0x44, 0x33, 0x22, 0x22, 0x21, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x11, 0x11, 0x11, 0x12, 0x22, 0x22, 0x33, 0x45, 0x56, 0x79, 0xEF, 0xFF, 0xF8, 0x10, 0x00, 0x6F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x50, 0x00, 0x00, 0x7F, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x82, 0x00, 0x00, 0x00, 0x8F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9F, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x38, 0xBD, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x71, 0x00, 0x00, 0x00, 0x04, 0xEF, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x12, 0x22, 0x22, 0x22, 0x22, 0x22, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x45, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x66, 0x66, 0x66, 0x77, 0x78, 0x88, 0x89, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xBB, 0xBB, 0xBB, 0xBC, 0xDF, 0xFF, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xF1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xEC, 0xCA, 0x98, 0x88, 0x77, 0x77, 0x77, 0x88, 0x9A, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xB9, 0x86, 0x43, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x56, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xF9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCA, 0x73, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x7B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xFF, 0xFF, 0xFF, 0xFB, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x8C, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xD8, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xB4, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFE, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFE, 0xA2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xB3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xE9, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xFF, 0xFF, 0xA0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xEA, 0x98, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFA, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFA, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xDF, 0xFF, 0xFF, 0xFF, 0xFC, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xA7, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xB0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xF2, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x05, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x10, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC1, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0x90, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x10, 0x00, 0x00, 0x5F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xF2, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0x00, 0x08, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2D, 0xFF, 0xFF, 0xFF, 0xFF, 0xE2, 0x00, 0x05, 0xFF, 0xFF, 0xFF, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xCF, 0xFF, 0xFF, 0xFF, 0xFB, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, 0x01, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xE2, 0x00, 0xDF, 0xFF, 0xFF, 0xF2, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0xFF, 0xFF, 0xFF, 0xFA, 0x00, 0xBF, 0xFF, 0xFF, 0xF7, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0x30, 0x8F, 0xFF, 0xFF, 0xFA, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xFF, 0xFF, 0xFF, 0xC0, 0x8F, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0xFF, 0xFF, 0xFF, 0xF5, 0x5F, 0xFF, 0xFF, 0xFF, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xFF, 0xFF, 0xFF, 0xFE, 0x6F, 0xFF, 0xFF, 0xFF, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xFB, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xF6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xF5, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xF2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFE, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0xF9, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF4, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFE, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFA, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xF4, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0, 0x00, 0x00 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/bootscreen_320x240x16.cpp b/Marlin/src/lcd/tft/images/bootscreen_320x240x16.cpp new file mode 100644 index 000000000000..cad6f1fef1b6 --- /dev/null +++ b/Marlin/src/lcd/tft/images/bootscreen_320x240x16.cpp @@ -0,0 +1,270 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint16_t marlin_logo_320x240x16[76800] = { + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18CE, 0x00F8, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F7, 0x18CE, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08D5, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x28EE, 0x8252, 0xCB54, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x00F9, 0x0119, 0x00F7, 0x00F7, 0x0119, 0x0119, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AE, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x394F, 0xB313, 0xD395, 0x7211, 0x18AD, 0x18AD, 0x20CD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x00F9, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x011A, 0x18CD, 0x20AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x0119, 0x011A, 0x08F3, 0x18AD, 0x18AD, 0x08F4, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x00F9, 0x10D2, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x496F, 0xCB55, 0xD395, 0xBB54, 0x28CE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x10D2, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x208D, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00FA, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AF, 0x0119, 0x0119, 0x18D0, 0x18AD, 0x18AD, 0x10D0, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x61D0, 0xD395, 0xD395, 0xD395, 0x69F1, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x00F9, 0x011A, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x08F3, 0x18AD, 0x18AD, 0x10D3, 0x011A, 0x011A, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x08F5, 0x0119, 0x00F9, 0x10D2, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x61D0, 0xD395, 0xD395, 0xD396, 0xD375, 0x310E, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x011A, 0x00F9, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18CE, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08D4, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08D5, 0x0119, 0x0119, 0x00F7, 0x0117, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x20AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x392F, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0x28CE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x0119, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x10D2, 0x0119, 0x00F9, 0x10F2, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x011A, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x310E, 0xCB55, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0x8252, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x10D2, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18CD, 0x18AD, 0x20AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x0119, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x10F2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x08F5, 0x0119, 0x00F9, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x10D2, 0x10D3, 0x08F3, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x00F9, 0x10D2, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0xB314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0x5190, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x011A, 0x011A, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x011A, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x00F9, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AF, 0x0119, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18EE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x011A, 0x011A, 0x0119, 0x0119, 0x00F9, 0x0119, 0x011A, 0x00F9, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x10F2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x08D5, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x08F5, 0x011A, 0x0119, 0x10D2, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x8252, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0x412F, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x08D5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F4, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x20AE, 0x20AD, 0x18AE, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18CD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0355, 0x190F, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F4, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AE, 0x10D2, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x00F9, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x208E, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x08F5, 0x0119, 0x00F9, 0x10D2, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x496F, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0x496F, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x00F9, 0x0119, 0x011A, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AE, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x20AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x08F5, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x11D1, 0x03B7, 0x0A93, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x00F9, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AE, 0x10D2, 0x011A, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AE, 0x08F5, 0x0119, 0x00F9, 0x10D2, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x28EE, 0xBB34, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0x9AB3, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x00F9, 0x00F9, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x10AF, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x011A, 0x011A, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x208D, 0x18AD, 0x10D2, 0x08F3, 0x10D3, 0x10D2, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0356, 0x03B7, 0x03B7, 0x190F, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08F3, 0x08D4, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x00F9, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x10D2, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x0119, 0x0119, 0x00FA, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x7A31, 0xD395, 0xD395, 0xD375, 0xDB95, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD396, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x11D1, 0x03B8, 0x03B7, 0x03B8, 0x0A94, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x10D2, 0x00F9, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x00F9, 0x10D2, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x08F5, 0x00F9, 0x011A, 0x0119, 0x011A, 0x0119, 0x011A, 0x08F5, 0x20AE, 0x18AD, 0x18CD, 0x18AD, 0x18CD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08D5, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AE, 0x18AD, 0x18CD, 0x18AD, 0x20AD, 0x18AD, 0x310E, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD396, 0xD395, 0xD395, 0xB313, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x011A, 0x011A, 0x011A, 0x0119, 0x08F5, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x08F5, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x08F5, 0x0119, 0x00F9, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x0356, 0x03B7, 0x03B7, 0x03B8, 0x03B7, 0x190E, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x10D2, 0x011A, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x011A, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x08F5, 0x0119, 0x00F9, 0x10D2, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AE, 0xA2D3, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xA2D3, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x0119, 0x0119, 0x0119, 0x0117, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x00F9, 0x0119, 0x011A, 0x0119, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18CE, 0x00F7, 0x011A, 0x011A, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18CD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x11D1, 0x03B8, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x0A94, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AE, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08D4, 0x08F3, 0x10D2, 0x18CD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18B0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x496F, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xAAD3, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x10D1, 0x08F3, 0x08F3, 0x10D2, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18CD, 0x10D2, 0x08F3, 0x08D4, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F4, 0x0119, 0x0119, 0x10D1, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0356, 0x03B8, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x190F, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x00F9, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x08F5, 0x0119, 0x00F9, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0xB314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0x61D0, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18CD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x00F9, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x0397, 0x03B8, 0x03B7, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x00F9, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x59D0, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD396, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F4, 0x011A, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x03B7, 0x03B7, 0x03B7, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x03B7, 0x03B7, 0x0397, 0x03B7, 0x03B8, 0x03B7, 0x03B7, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x011A, 0x10D1, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0xBB34, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xAAD3, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x00F9, 0x10D2, 0x18CD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x011A, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x03B7, 0x03B7, 0x03B7, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x0397, 0x03B7, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x011A, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AE, 0x08F5, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x61B1, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0x8A92, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x08F5, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x08F4, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x188D, 0x18AD, 0x10D2, 0x08F3, 0x08F3, 0x10D2, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x03B7, 0x03B7, 0x03B7, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x03B8, 0x03B7, 0x03B8, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x10D2, 0x00F9, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18CD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0xAAD3, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0x310E, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x0119, 0x0119, 0x10D1, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x03D7, 0x0397, 0x03B7, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x03B7, 0x03B8, 0x0397, 0x03B7, 0x03B8, 0x03B7, 0x03B7, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x10D2, 0x00F9, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x10D0, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x496F, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0x7231, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x10D1, 0x10D3, 0x08D3, 0x10D2, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x03B7, 0x03B7, 0x03B8, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x10D2, 0x011A, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x08F5, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x011A, 0x0119, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20CD, 0x20AE, 0x8A92, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0x7A31, 0x20AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x03B7, 0x03B7, 0x03B7, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x03B7, 0x03B7, 0x03B8, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AE, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x28EE, 0xC374, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xA2D3, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18CE, 0x194F, 0x18AE, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x03B7, 0x0397, 0x03B8, 0x18AD, 0x20AE, 0x20AD, 0x18AD, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B8, 0x03B7, 0x03B7, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x00F9, 0x0119, 0x08F5, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x20AE, 0x20AE, 0x61D1, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0x69F1, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x10D2, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x1930, 0x02F5, 0x03B7, 0x03B8, 0x0356, 0x114F, 0x18AD, 0x18AD, 0x18AD, 0x03B8, 0x03B7, 0x03B7, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x03B7, 0x03B8, 0x03B7, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x00F9, 0x0119, 0x08F4, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AE, 0x20AE, 0x9AB3, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0x412F, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18CE, 0x00F8, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F7, 0x18CE, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x0397, 0x03B7, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x190F, 0x0377, 0x0397, 0x03B8, 0x0398, 0x0397, 0x0B77, 0x18CE, 0x18AD, 0x18AD, 0x03B7, 0x0397, 0x03B8, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x03B7, 0x0BB7, 0x0398, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0xC355, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0x4970, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x00F9, 0x0119, 0x00F7, 0x00F7, 0x0119, 0x0119, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B8, 0x03B7, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x1253, 0x0B78, 0x0B98, 0x0B78, 0x0B98, 0x0B98, 0x1378, 0x11F2, 0x18AD, 0x18AD, 0x0B98, 0x0B78, 0x0B78, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0B98, 0x1378, 0x0B78, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x20AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x4970, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0x8252, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x0119, 0x011A, 0x08F3, 0x18AD, 0x18AD, 0x08F4, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x18AD, 0x18AD, 0x03B8, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x1AB5, 0x1B78, 0x1B58, 0x1358, 0x1B78, 0x1378, 0x1358, 0x1A13, 0x18AE, 0x18AE, 0x1358, 0x1358, 0x1378, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x1358, 0x1358, 0x1358, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x20AE, 0x20AE, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x7A32, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD375, 0xD395, 0xC354, 0x5990, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AF, 0x0119, 0x0119, 0x18D0, 0x18AD, 0x18AD, 0x10D0, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x1A54, 0x1B38, 0x1B38, 0x2338, 0x1B38, 0x1B58, 0x2338, 0x21D2, 0x18AD, 0x18AD, 0x2338, 0x2338, 0x2358, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x1930, 0x2339, 0x2358, 0x2338, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0xA2B3, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0x4970, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x08F3, 0x18AD, 0x18AD, 0x10D3, 0x011A, 0x011A, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x18AE, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x2150, 0x2B18, 0x2B39, 0x2B18, 0x2B19, 0x2B19, 0x2AF8, 0x18CE, 0x18AD, 0x18AD, 0x2B19, 0x2B18, 0x2B19, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x2192, 0x2B19, 0x2B19, 0x2B18, 0x2338, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0xBB34, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0x4970, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08D5, 0x0119, 0x0119, 0x00F7, 0x0117, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B8, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08F3, 0x10D3, 0x10D2, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x2192, 0x2B19, 0x3319, 0x32F9, 0x2A15, 0x18EF, 0x20AD, 0x18AD, 0x18AD, 0x32F9, 0x3319, 0x32F9, 0x18AD, 0x18AD, 0x18AD, 0x2191, 0x3319, 0x2AF9, 0x3319, 0x2AF9, 0x2A97, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x0119, 0x0119, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x20CF, 0x20CF, 0x28CF, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0x71D1, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x20CD, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x011A, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B8, + 0x18AD, 0x18AE, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x3AD9, 0x3AD9, 0x3AD9, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x3AF9, 0x3AD9, 0x3AD9, 0x18AD, 0x20AD, 0x3215, 0x3AD9, 0x3AF9, 0x3ADA, 0x3AD9, 0x3277, 0x18CE, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x011A, 0x20CD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CF, 0x28CF, 0x4950, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD374, 0xD375, 0xD355, 0xD355, 0xAAB3, 0x20CE, 0x18CE, 0x20CE, 0x20AE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x10D2, 0x10D3, 0x08F3, 0x10D2, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x0398, 0x0398, 0x0398, 0x0398, 0x03B7, 0x0397, + 0x18AD, 0x18AD, 0x08F5, 0x0139, 0x011A, 0x0117, 0x00F7, 0x011A, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x42D9, 0x42B9, 0x42B9, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x42B9, 0x42B9, 0x42BA, 0x18AE, 0x31F5, 0x42DA, 0x42D9, 0x42B9, 0x42D9, 0x3A77, 0x18CE, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x20AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x0119, 0x0119, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x5991, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD374, 0xD375, 0xD355, 0xD355, 0xD355, 0x9252, 0x30EF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x2338, 0x2338, 0x2318, 0x2319, 0x2338, 0x2338, + 0x18AD, 0x18AD, 0x00F9, 0x0119, 0x10D3, 0x18AD, 0x18AD, 0x10F3, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18B0, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x4A99, 0x4AB9, 0x4A9A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x4ABA, 0x4ABA, 0x4A9A, 0x4257, 0x4A99, 0x4A9A, 0x4A9A, 0x4ABA, 0x4237, 0x20CE, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AE, 0x20AE, 0x0119, 0x0119, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x69F1, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD375, 0xD355, 0xD355, 0xD355, 0xD335, 0xD355, 0xCB14, 0x4130, 0x20AF, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x18AD, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x18AD, 0x208E, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x42B9, 0x4A99, 0x42B9, 0x42BA, 0x18AD, 0x18AD, + 0x18AD, 0x18AF, 0x011A, 0x00F9, 0x10D0, 0x18AD, 0x20AD, 0x10D0, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0118, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x527A, 0x527A, 0x527A, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x527A, 0x527A, 0x529A, 0x527A, 0x527A, 0x527A, 0x527A, 0x4A18, 0x20CE, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x00F9, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D1, 0x0117, 0x0119, 0x0119, 0x0917, 0x18D2, 0x20CE, 0x20CF, 0x28CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x8253, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD354, 0xD355, 0x7A11, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x6A3B, 0x6A3B, 0x6A3B, 0x621A, 0x6A3B, 0x6A3B, + 0x18AD, 0x18AD, 0x0119, 0x0119, 0x10D3, 0x18AD, 0x20AE, 0x08F3, 0x0119, 0x0119, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x00F9, 0x18D0, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x20AD, 0x5A5B, 0x5A5A, 0x5A7A, 0x2910, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x5A5A, 0x5A7B, 0x5A5A, 0x5A5A, 0x5A5A, 0x5A5A, 0x4A18, 0x20CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D1, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x091A, 0x18F2, 0x28CF, 0x28CE, 0x28CF, 0x28CF, 0x28EF, 0x28F0, 0x30F0, 0x8232, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xA293, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x20AE, 0x20AD, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x89BC, 0x89BC, 0x89BC, 0x91BC, 0x89BC, 0x899C, + 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x00F7, 0x0117, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x18D0, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x623A, 0x623B, 0x625A, 0x621A, 0x2910, 0x18CD, 0x18AD, 0x18AD, 0x623B, 0x623A, 0x625A, 0x623B, 0x623B, 0x51F8, 0x20CE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0118, 0x0119, 0x0917, 0x18D2, 0x18D2, 0x0918, 0x091A, 0x0918, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x30D0, 0x30F0, 0x30F0, 0x8252, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xD335, 0x9253, 0x30EF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xA93D, 0xA93D, 0xA93D, 0xB13D, 0xA93D, 0xA93D, + 0x18AD, 0x20AD, 0x18AE, 0x0117, 0x011A, 0x011A, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x00F7, 0x0119, 0x00F8, 0x18D0, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x59D8, 0x6A1B, 0x6A1B, 0x6A1B, 0x6A1B, 0x4133, 0x18AD, 0x18AD, 0x6A3B, 0x6A1B, 0x6A1B, 0x6A1B, 0x51B6, 0x20CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x00F9, 0x10D3, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18D1, 0x20CE, 0x20CE, 0x18D1, 0x093A, 0x093A, 0x28EF, 0x28CF, 0x28CF, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x9273, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD334, 0xD335, 0xD334, 0xD334, 0xD314, 0xD315, 0xAA93, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0xD0BE, 0xD0BE, 0xD0BE, 0xD0BE, 0xD0BE, 0xD0BE, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08D4, 0x08F3, 0x10D2, 0x18CD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x18D0, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20CE, 0x61B8, 0x721B, 0x71FB, 0x721B, 0x721B, 0x4133, 0x20AD, 0x71FB, 0x721B, 0x71FB, 0x4174, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x0119, 0x011A, 0x18D1, 0x20AE, 0x20CE, 0x20F1, 0x093A, 0x093A, 0x28CF, 0x28CF, 0x30EF, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0xAAF4, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD314, 0xD314, 0xD315, 0x28EF, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x28CE, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x18AE, 0x20AD, 0x20AD, 0x20AE, 0x30EE, 0x6150, 0x81B1, 0xA1F2, 0xC233, 0xCA53, 0xCA54, 0xCA53, 0xC233, 0xA1F2, 0x8191, 0x512F, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0xF03F, 0xF03F, 0xF03F, 0xF03F, 0xF03F, 0xF03F, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x0119, 0x18D0, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x20CE, 0x69B9, 0x81FB, 0x79DB, 0x79DC, 0x81FC, 0x5976, 0x79DB, 0x79DC, 0x81DC, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x0918, 0x0119, 0x0917, 0x18D0, 0x20D0, 0x0917, 0x093A, 0x1138, 0x28CF, 0x30CF, 0x30EF, 0x30F0, 0x30F0, 0x3911, 0x3911, 0xAAD4, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xD314, 0xD315, 0xD315, 0xD314, 0x69B2, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CE, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x410F, 0x6990, 0x99F2, 0xC253, 0xCA74, 0xD274, 0xCA74, 0xD253, 0xCA53, 0xCA53, 0xCA53, 0xD233, 0xD253, 0xCA53, 0xD233, 0xCA33, 0xC213, 0x8991, 0x410F, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x0917, 0x0119, 0x0119, 0x10CF, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x20AE, 0x7199, 0x89DB, 0x89BC, 0x81BC, 0x89BC, 0x89BC, 0x89BC, 0x89BC, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x011A, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18D2, 0x0119, 0x0119, 0x093A, 0x093A, 0x093A, 0x093A, 0x20F2, 0x28CF, 0x28F0, 0x30F0, 0x30F0, 0x3111, 0x3911, 0x3911, 0xB2F5, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xD315, 0xD314, 0xD314, 0xD2F4, 0xD2F5, 0xCAD4, 0x5971, 0x30F0, 0x30D0, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CE, 0x38EF, 0x79B1, 0xBA53, 0xCA94, 0xCA94, 0xCA74, 0xD273, 0xD273, 0xCA73, 0xCA54, 0xCA53, 0xCA54, 0xCA53, 0xCA33, 0xCA53, 0xCA53, 0xCA33, 0xCA33, 0xCA33, 0xD213, 0xCA13, 0xCA13, 0xA1B2, 0x490F, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20CD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x00F9, 0x18B0, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20CE, 0x7979, 0x919C, 0x919C, 0x91BC, 0x919C, 0x899C, 0x89BC, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x10F2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AE, 0x20AE, 0x20CE, 0x18F2, 0x0919, 0x091A, 0x091A, 0x0919, 0x20F3, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x3110, 0x3911, 0x3911, 0x4112, 0xB2F5, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xD314, 0xD314, 0xD314, 0xD2F4, 0xD314, 0xD2F5, 0xD2F4, 0xD2F4, 0x4930, 0x30F0, 0x30EF, 0x28F0, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28CE, 0x28CF, 0x28CF, 0x28CF, 0x4130, 0x89F1, 0xD294, 0xD294, 0xCA93, 0xCA74, 0xD274, 0xCA74, 0xCA74, 0xCA53, 0xCA73, 0xD253, 0xD254, 0xCA53, 0xCA53, 0xCA54, 0xC274, 0x9B36, 0x83B8, 0x6419, 0x6C39, 0x6439, 0x6C1A, 0x8B57, 0xB295, 0xCA13, 0x9191, 0x28CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x18AF, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x28AE, 0x8159, 0x917C, 0x997C, 0x997C, 0x999C, 0x999C, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08D5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x08F4, 0x0119, 0x00F9, 0x10D2, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20D0, 0x20D1, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x3110, 0x3910, 0x4111, 0x4112, 0x4112, 0x9294, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xD315, 0xD314, 0xD2F4, 0xD2F4, 0xD315, 0xD2F4, 0xD2F5, 0xD2F4, 0xD2D5, 0x79D2, 0x3110, 0x30F0, 0x30F0, 0x30F0, 0x28F0, 0x30D0, 0x28EF, 0x28F0, 0x28CF, 0x5150, 0xAA32, 0xD293, 0xD294, 0xD294, 0xCA93, 0xCA74, 0xCA74, 0xCA74, 0xCA74, 0xD274, 0xD254, 0xCA53, 0xCA54, 0xB2D5, 0x83B8, 0x44FC, 0x1DBE, 0x063F, 0x0CDB, 0x0B76, 0x1377, 0x1377, 0x0B76, 0x1356, 0x0B76, 0x0B77, 0x23F8, 0x6991, 0x510F, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x00F9, 0x18AF, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x20AD, 0x20AE, 0x8939, 0xA17C, 0xA17C, 0xA15D, 0xA15D, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x10D2, 0x0119, 0x011A, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28CE, 0x28CF, 0x28CF, 0x28EF, 0x28F0, 0x30F0, 0x3110, 0x3911, 0x3911, 0x3911, 0x4112, 0x4132, 0x8A54, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD315, 0xD315, 0xD315, 0xD314, 0xD314, 0xD314, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2F4, 0xD2F4, 0xD2D4, 0xCAD4, 0x5951, 0x38F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x4130, 0x91F2, 0xD294, 0xD294, 0xCA94, 0xCA74, 0xCA94, 0xCA94, 0xCA74, 0xD274, 0xD274, 0xD274, 0xD253, 0xB2D5, 0x7419, 0x257D, 0x063F, 0x061F, 0x057D, 0x12B5, 0x190F, 0x18CE, 0x20AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x0117, 0x0119, 0x0119, 0x18B0, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20CE, 0x913A, 0xA93D, 0xA95D, 0xA95C, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x20AE, 0x18AE, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CE, 0x28CF, 0x28EF, 0x28F0, 0x30F0, 0x30F0, 0x3911, 0x3911, 0x3911, 0x4132, 0x4132, 0x4932, 0x9255, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xD315, 0xD315, 0xD314, 0xD314, 0xD314, 0xD2F4, 0xD2F5, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2D4, 0xD2D4, 0xCAB4, 0x5172, 0x3911, 0x38F1, 0x38F0, 0x30F0, 0x81D2, 0xC294, 0xD294, 0xD293, 0xD294, 0xD294, 0xCA93, 0xCA93, 0xD274, 0xD274, 0xCA73, 0xD274, 0x83D8, 0x353D, 0x061F, 0x063F, 0x063F, 0x063F, 0x4C5A, 0x4970, 0x20AE, 0x20AE, 0x20AD, 0x18CD, 0x20AD, 0x20AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18CD, 0x10D2, 0x08F3, 0x08D4, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x00F9, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0xB11D, 0xB11D, 0xB11D, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08D5, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x20CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x4112, 0x4132, 0x4932, 0x4953, 0x6B36, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2D4, 0xD2D4, 0xD2D5, 0xD2D4, 0xCAD4, 0xCAB4, 0x5972, 0x3911, 0x5151, 0xB253, 0xCAB4, 0xD294, 0xCA94, 0xD294, 0xCA94, 0xD294, 0xCA94, 0xCA74, 0xD274, 0xC294, 0x645A, 0x1DBE, 0x063F, 0x063F, 0x063F, 0x1DBE, 0x6459, 0xC274, 0x99D2, 0x28CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18CE, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AF, 0x0117, 0x0119, 0x0119, 0x0119, 0x0119, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x18D0, 0x18CD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0xB8FE, 0xB8FD, 0xB8FE, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x00F9, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28F0, 0x30F0, 0x30F0, 0x3911, 0x3911, 0x4111, 0x4132, 0x4132, 0x4933, 0x4953, 0x253B, 0x465C, 0x6D7B, 0x6D9A, 0x6D9A, 0x6D7A, 0x84F9, 0x9C78, 0x9C77, 0x9C78, 0x9C78, 0x9C57, 0x9C78, 0x9C58, 0x9C58, 0xBBB6, 0xD334, 0xD315, 0xD334, 0xD315, 0xD314, 0xD315, 0xD2F4, 0xCAF4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2D4, 0xCAD4, 0xD2D4, 0xD2D4, 0xCAD4, 0xCAB4, 0xD2D4, 0x91F3, 0x5972, 0xCA74, 0xD2B4, 0xD2B4, 0xD294, 0xCA94, 0xD294, 0xD294, 0xCA94, 0xCA74, 0xC2B4, 0x6C5A, 0x0DFF, 0x063F, 0x063F, 0x063F, 0x353D, 0x83B8, 0xCA53, 0xCA33, 0x89B1, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x011A, 0x0119, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x08F5, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x0119, 0x18D0, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AE, 0xC0DE, 0xC0FE, 0xC0DD, 0x18AE, 0x18CD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00F9, 0x00FA, 0x08F4, 0x18AD, 0x18AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30EF, 0x30F0, 0x30F0, 0x3911, 0x38F1, 0x3911, 0x4112, 0x4132, 0x4932, 0x4953, 0x5153, 0x4D1A, 0x6D9A, 0x94B9, 0x9C98, 0x9C77, 0x9C78, 0x9C78, 0x9C78, 0x94B8, 0x6D7A, 0x6D7A, 0x6D7B, 0x367C, 0x367D, 0x1EFE, 0x077F, 0x075F, 0x1EDE, 0x363D, 0x6D3A, 0x9C17, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xCAD4, 0xD2B4, 0xCAD4, 0xD2B3, 0xCAB4, 0xC294, 0xCAB4, 0xCA94, 0xCA94, 0xD294, 0xCA94, 0xCA74, 0xCA74, 0xCA74, 0x7BD8, 0x0DFF, 0x063F, 0x061F, 0x063F, 0x4CBB, 0x9B57, 0xD233, 0xCA33, 0xCA53, 0x6150, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x0119, 0x0119, 0x011A, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x0917, 0x0119, 0x0119, 0x18CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xC8BE, 0xC8DE, 0xC8BE, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x3912, 0x4132, 0x4132, 0x4933, 0x5153, 0xA2B5, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD355, 0xD334, 0xD335, 0xD335, 0xD335, 0xD335, 0xBB96, 0xA437, 0x74F9, 0x4DBC, 0x2E7E, 0x0EDF, 0x559B, 0x8498, 0xC335, 0xD2F4, 0xD2D4, 0xD2F5, 0xD2D4, 0xD2D4, 0xD2B5, 0xCAB4, 0xD2B4, 0xD2B4, 0xCAB4, 0xD2B4, 0xD2B4, 0xBAB4, 0xBAF6, 0xCA94, 0xD294, 0xCA94, 0xD273, 0x9B76, 0x1DBE, 0x061F, 0x063F, 0x0DDF, 0x643A, 0xB2D5, 0xCA54, 0xD253, 0xCA53, 0xC294, 0x59B1, 0x28CE, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x00F9, 0x18AF, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18CD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x40B0, 0xA09A, 0xD0BE, 0xD09E, 0xD0BE, 0xB89C, 0x78B5, 0x28AE, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x011A, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30EF, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x4112, 0x4112, 0x4932, 0x4933, 0x5173, 0xBB15, 0xD395, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD355, 0xD335, 0xD335, 0xD314, 0xD314, 0xD335, 0xD315, 0xD314, 0xD315, 0xD2F5, 0xD2F5, 0xD2F4, 0x9BF7, 0x6D1A, 0x2E3D, 0x45BC, 0x9418, 0xD2D4, 0xCAD4, 0xD2D4, 0xD2B4, 0xD2B4, 0xD2B4, 0xCAB4, 0xD2B4, 0xD294, 0xD294, 0xD294, 0xC2D4, 0x4CDB, 0x7BD8, 0x9B57, 0x44FC, 0x063F, 0x063F, 0x1DBE, 0x83D8, 0xC294, 0xCA53, 0xCA54, 0xCA33, 0xCA53, 0xB2B5, 0x33B8, 0x28F0, 0x28CF, 0x28CF, 0x28CF, 0x20CF, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x188E, 0x20CD, 0x10D1, 0x0119, 0x011A, 0x10D1, 0x20AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x00F7, 0x0119, 0x0118, 0x10D0, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x40B0, 0xD07D, 0xD87E, 0xD89F, 0xD89F, 0xE07F, 0xD89E, 0xD89F, 0xB87B, 0x28AE, 0x20AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x28EF, 0x30F0, 0x30F0, 0x3110, 0x3911, 0x3911, 0x3911, 0x4132, 0x4132, 0x4933, 0x5174, 0xBB14, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD334, 0xD335, 0xD335, 0xD335, 0xD314, 0xD335, 0xD315, 0xD314, 0xD314, 0xD315, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2D4, 0xC335, 0x8478, 0x4D7B, 0x4D5B, 0xAB96, 0xD2B4, 0xCAB4, 0xD2B4, 0xD2B4, 0xCA94, 0xCAB4, 0xD294, 0xD294, 0xD273, 0xC2B4, 0x5C9A, 0x061F, 0x061F, 0x063F, 0x7419, 0xD273, 0xD273, 0xCA53, 0xCA53, 0xD233, 0xCA53, 0xAAF6, 0x153C, 0x2951, 0x30F0, 0x30F0, 0x28EF, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x0119, 0x0119, 0x0119, 0x0117, 0x18CE, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F6, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x10B0, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x208D, 0x18AD, 0x10D2, 0x08F3, 0x10D3, 0x10D2, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xB07A, 0xE85F, 0xE85F, 0xE07F, 0xE85F, 0xE87F, 0xE07F, 0xE85F, 0xE07F, 0x9898, 0x20AD, 0x18AD, 0x18CD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x3110, 0x3910, 0x3911, 0x3911, 0x4112, 0x4132, 0x4932, 0x5153, 0xBB15, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD354, 0xD355, 0xD335, 0xD355, 0xD335, 0xD335, 0xD315, 0xCB34, 0xD315, 0xD314, 0xD314, 0xD315, 0xD314, 0xD2F4, 0xD2F5, 0xD2F4, 0xCAF4, 0xD2F4, 0xD2D4, 0xD2D4, 0xD2D5, 0xD2D4, 0xD2D4, 0xBB55, 0x7499, 0x35DC, 0x8439, 0xC2F4, 0xD2B4, 0xD294, 0xD294, 0xD294, 0xCA93, 0xD294, 0xD274, 0xCA74, 0x9B76, 0x061F, 0x061F, 0x83D8, 0xC295, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0x7BB8, 0x063F, 0x2A34, 0x30F0, 0x30F0, 0x30EF, 0x30F0, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x00F9, 0x08D5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0118, 0x18D0, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x38B0, 0xF05F, 0xE83F, 0xF03F, 0xF05F, 0xF05F, 0xF03F, 0xF03F, 0xF03F, 0xF05F, 0xE83F, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30EF, 0x30F0, 0x30F0, 0x30F0, 0x3911, 0x3911, 0x3911, 0x4112, 0x4132, 0x4933, 0x5173, 0xBB35, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xCB35, 0xD315, 0xD314, 0xD314, 0xD314, 0xD314, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2F5, 0xCAD4, 0xD2F4, 0xCAD4, 0xD2D4, 0xD2D4, 0xCAB4, 0xD2B4, 0xCAB4, 0xCAB4, 0x8BF8, 0x3D5C, 0x6499, 0xC2D4, 0xD294, 0xD294, 0xCA74, 0xCA74, 0xD274, 0xCA74, 0xCA74, 0x54BB, 0x5C9A, 0x353D, 0x1DBE, 0x4CBB, 0x9377, 0x9B36, 0x44FC, 0x061F, 0x1BF9, 0x3911, 0x3910, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F4, 0x10F3, 0x10D2, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x00F7, 0x0119, 0x0118, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x5092, 0xF83F, 0xF83F, 0xF03F, 0xF83F, 0xF83F, 0xF83F, 0xF83F, 0xF81F, 0xF03F, 0xF83F, 0x5092, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x3911, 0x3911, 0x3911, 0x4112, 0x4132, 0x4932, 0x69B3, 0xC355, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xD335, 0xD335, 0xD314, 0xD314, 0xD314, 0xD2F5, 0xD2F5, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xCAD4, 0xCAB4, 0xD2B4, 0xD2B4, 0xCAB4, 0xD294, 0x9B97, 0x453C, 0x6C59, 0xC2B4, 0xCA74, 0xD274, 0xD273, 0xCA73, 0xD273, 0xC294, 0x6C39, 0xC294, 0xCA53, 0x8B98, 0x4CBB, 0x0DFF, 0x063F, 0x0D7E, 0x3972, 0x3911, 0x3911, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x011A, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x20AE, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x0119, 0x00F9, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x18CD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x5092, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0x5092, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x4111, 0x4112, 0x4132, 0x4933, 0x9254, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD375, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD314, 0xD314, 0xD314, 0xD314, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2F4, 0xD2D4, 0xD2D4, 0xCAD4, 0xD2D4, 0xCAD4, 0xD2D4, 0xD2B4, 0xCAB4, 0xD2B4, 0xD2B4, 0xCAB4, 0xD294, 0xD294, 0xD294, 0xCA94, 0x9B77, 0x44DC, 0x73F9, 0xCA73, 0xCA74, 0xD254, 0xCA73, 0xCA53, 0xC294, 0x351C, 0x6C3A, 0xC294, 0xD253, 0xCA34, 0x83B8, 0x5A55, 0x4132, 0x4132, 0x3912, 0x3911, 0x3911, 0x3910, 0x30F0, 0x30F0, 0x30F0, 0x28F0, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x18AD, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18B0, 0x0119, 0x011A, 0x0119, 0x00F8, 0x18D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18CE, 0x0117, 0x0119, 0x0119, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x4090, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0x28AF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x28F0, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x4112, 0x4132, 0x4132, 0x69D3, 0xC355, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xCB55, 0xD335, 0xD335, 0xD335, 0xD315, 0xD314, 0xD314, 0xD314, 0xD314, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xCAD4, 0xD2F4, 0xD2D4, 0xD2D4, 0xD2B4, 0xD2B4, 0xD2B4, 0xCAB4, 0xCAB4, 0xCAB4, 0xD2B4, 0xCAB4, 0xD294, 0xD294, 0xD294, 0xCA94, 0xD274, 0xCA74, 0x8B78, 0x447C, 0xA316, 0xD253, 0xD253, 0xCA54, 0xCA53, 0xC294, 0x257D, 0x0DDF, 0x83B8, 0xD233, 0xCA33, 0xCA33, 0xBA13, 0x7993, 0x4112, 0x4112, 0x4111, 0x3911, 0x3911, 0x38F0, 0x30F0, 0x28F0, 0x30D0, 0x30D0, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x08F5, 0x0119, 0x011A, 0x011A, 0x0119, 0x011A, 0x00F9, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x0119, 0x00F9, 0x0119, 0x00F8, 0x18CF, 0x18AD, 0x18AE, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00F9, 0x011A, 0x0119, 0x011A, 0x00F9, 0x0119, 0x0119, 0x00F9, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x20AD, 0xD03C, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xD03C, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00F9, 0x0119, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x3911, 0x3911, 0x3911, 0x4111, 0x4112, 0x5193, 0xAAD4, 0xD375, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD314, 0xD314, 0xD315, 0xD314, 0xD314, 0xD314, 0xD314, 0xD315, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2D4, 0xD2D4, 0xD2D4, 0xCAD4, 0xD2B4, 0xD2B4, 0xD2D4, 0xD2B4, 0xCAB4, 0xD2B4, 0xD2B4, 0xD294, 0xD2B4, 0xCA94, 0xCA94, 0xD294, 0xCA74, 0xCA73, 0xCA74, 0xD274, 0xC295, 0x6BB9, 0x6B99, 0xCA54, 0xCA53, 0xD254, 0xCA33, 0xC294, 0x24FD, 0x063F, 0x351D, 0xB295, 0xCA13, 0xCA13, 0xCA13, 0xB9F3, 0x7992, 0x4111, 0x4112, 0x38F1, 0x3911, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CF, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x0117, 0x18CE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CF, 0x0118, 0x00F9, 0x0119, 0x00F9, 0x18D0, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x00F9, 0x0119, 0x0119, 0x0119, 0x00FA, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x4090, 0xF03F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0x6073, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20CD, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30EF, 0x28F0, 0x30F0, 0x30F0, 0x30F0, 0x3910, 0x3911, 0x3912, 0x4112, 0x4112, 0x8233, 0xCB55, 0xD375, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD334, 0xD314, 0xD335, 0xD314, 0xD314, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2D4, 0xD2D4, 0xD2D4, 0xCAD4, 0xD2D4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xCAB4, 0xD2B4, 0xD2B4, 0xCAB4, 0xD294, 0xD294, 0xD294, 0xCA74, 0xCA74, 0xCA74, 0xCA73, 0xCA73, 0xCA53, 0xCA53, 0xCA74, 0xAAB6, 0x5B7A, 0xBA74, 0xCA53, 0xCA33, 0xCA33, 0xC254, 0x4BFB, 0x059F, 0x0D7F, 0x8B57, 0xC9F3, 0xCA13, 0xC9F3, 0xC9F3, 0xA9B3, 0x5952, 0x4112, 0x3931, 0x3911, 0x3111, 0x3110, 0x30F0, 0x30F0, 0x28F0, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x10D2, 0x08F3, 0x10D3, 0x10D2, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18D0, 0x00F9, 0x0119, 0x0119, 0x0118, 0x10CF, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x011A, 0x0119, 0x011A, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x4091, 0xE01D, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0x7074, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x08F3, 0x10D2, 0x20CD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AD, 0x10D1, 0x0119, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x20AE, 0x18CD, 0x20AE, 0x20CD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x3910, 0x3911, 0x3911, 0x3912, 0x4132, 0x4953, 0xB2F4, 0xD395, 0xDB95, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD334, 0x84F9, 0x467D, 0x1F5E, 0x07DF, 0x07DF, 0x07DF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x079F, 0x1F1E, 0x367D, 0x367C, 0x4DDB, 0x653A, 0x8498, 0x9BF7, 0xC2F5, 0xD294, 0xD294, 0xD294, 0xD294, 0xCA94, 0xCA94, 0xCA74, 0xCA73, 0xD253, 0xD254, 0xCA74, 0xCA53, 0xCA53, 0xCA53, 0xD253, 0x72D9, 0xAA76, 0xCA33, 0xD233, 0xCA13, 0xCA33, 0x1C7E, 0x059F, 0x05FF, 0x5C7A, 0xCA13, 0xC9F3, 0xC9F3, 0xC9F3, 0xD1F3, 0x9193, 0x4911, 0x3911, 0x3911, 0x3911, 0x3110, 0x30F0, 0x30F0, 0x30F0, 0x28EF, 0x28EF, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0118, 0x10B0, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x10D1, 0x08F3, 0x08F3, 0x10D2, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x7074, 0x9077, 0x8856, 0x8876, 0x388F, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18CD, 0x18AE, 0x18CE, 0x00F7, 0x0119, 0x011A, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x08F7, 0x0119, 0x011A, 0x0119, 0x0119, 0x08F7, 0x18CE, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30EF, 0x30F0, 0x30F0, 0x30F0, 0x3111, 0x3111, 0x38F1, 0x3911, 0x4111, 0x4132, 0x6193, 0xC355, 0xD396, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD375, 0xD355, 0xD355, 0xD335, 0xD335, 0xB3D6, 0x271D, 0x07FF, 0x07FF, 0x07BF, 0x079F, 0x079F, 0x077F, 0x079F, 0x077F, 0x077F, 0x077F, 0x077F, 0x077F, 0x077F, 0x077F, 0x075F, 0x077F, 0x077F, 0x077F, 0x077F, 0x077F, 0x077F, 0x077F, 0x079F, 0x079F, 0x1EFE, 0x461C, 0x6D1A, 0x9BD6, 0xCA74, 0xCA74, 0xCA74, 0xCA73, 0xD274, 0xCA74, 0xCA53, 0xD254, 0xCA54, 0xD253, 0xCA53, 0xCA33, 0xA275, 0x9A76, 0xCA33, 0xCA13, 0xCA33, 0x9AD6, 0x04FF, 0x05BF, 0x063F, 0x357C, 0xC254, 0xC9F3, 0xD1F3, 0xC9F3, 0xC9F3, 0xB9D3, 0x6152, 0x4111, 0x3911, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x00F8, 0x10D0, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x208E, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x00F9, 0x08F5, 0x18AE, 0x20AD, 0x18AD, 0x08F4, 0x0119, 0x011A, 0x00F7, 0x0117, 0x0119, 0x011A, 0x08F5, 0x20AE, 0x20AE, 0x20AD, 0x20CE, 0x20CE, 0x20CE, 0x20CD, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30EF, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x3910, 0x3911, 0x3911, 0x3911, 0x4112, 0x4132, 0x6193, 0xCB55, 0xD395, 0xD395, 0xD375, 0xD395, 0xD375, 0xD375, 0xD375, 0xD355, 0xD375, 0xD355, 0xD355, 0xD355, 0xCB55, 0xD334, 0xCB55, 0xAC17, 0x0FBF, 0x07FF, 0x07FF, 0x07BF, 0x07BF, 0x077F, 0x075F, 0x075F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x075F, 0x075F, 0x077F, 0x077F, 0x079F, 0x07BF, 0x365C, 0x74B9, 0xB315, 0xCA73, 0xCA54, 0xCA54, 0xCA53, 0xCA53, 0xCA53, 0xCA33, 0xD233, 0xCA33, 0xB235, 0xAA16, 0xCA33, 0xCA13, 0xCA13, 0x7B37, 0x055F, 0x05FF, 0x067F, 0x25DD, 0xA2F5, 0xD1D3, 0xC9F3, 0xC9D3, 0xC9D2, 0xC9D3, 0x9193, 0x4932, 0x4111, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18B0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x0119, 0x00F9, 0x011A, 0x011A, 0x0119, 0x011A, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x10D3, 0x18CE, 0x20AD, 0x10F4, 0x011A, 0x0119, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x3911, 0x4111, 0x4132, 0x4132, 0x61B3, 0xCB75, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD375, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0x8CB8, 0x0FBF, 0x07FF, 0x07DF, 0x07BF, 0x079F, 0x077F, 0x075F, 0x073F, 0x071F, 0x06FF, 0x06FF, 0x06FF, 0x06FF, 0x06FF, 0x06FF, 0x06FF, 0x06DF, 0x06FF, 0x06DF, 0x06DF, 0x06DF, 0x06FF, 0x06FF, 0x06FF, 0x06FF, 0x071F, 0x071F, 0x071F, 0x073F, 0x073F, 0x073F, 0x073F, 0x075F, 0x075F, 0x071F, 0x2DFD, 0x7419, 0xB2B5, 0xCA53, 0xCA53, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xD233, 0xCA14, 0xA215, 0xCA13, 0xCA13, 0xC9F3, 0x8338, 0x05BF, 0x063F, 0x06BF, 0x0E9F, 0xAAD5, 0xC9D3, 0xC9D2, 0xC9D3, 0xC9D3, 0xC9B2, 0xB1B2, 0x5931, 0x3911, 0x3911, 0x3911, 0x30F0, 0x30F0, 0x28F0, 0x28EF, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18CF, 0x011A, 0x0119, 0x10D0, 0x18AD, 0x20AE, 0x18D0, 0x0119, 0x0119, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x3111, 0x38F1, 0x3911, 0x3911, 0x4112, 0x4112, 0x4132, 0x6193, 0xCB75, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD354, 0xD355, 0xD355, 0xC395, 0x5DFA, 0x07FF, 0x07DF, 0x07BF, 0x079F, 0x077F, 0x075F, 0x073F, 0x071F, 0x06FF, 0x06DF, 0x06BF, 0x06BF, 0x069F, 0x069F, 0x069F, 0x069F, 0x06BF, 0x06BF, 0x069F, 0x069F, 0x069F, 0x069F, 0x069F, 0x069F, 0x069F, 0x06BF, 0x06BF, 0x06BF, 0x06DF, 0x06DF, 0x06FF, 0x06FF, 0x06FF, 0x071F, 0x071F, 0x06FF, 0x06BF, 0x065F, 0x05BF, 0x443C, 0x8AF7, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA13, 0xCA13, 0xCA13, 0x99B6, 0xC9F3, 0xCA13, 0xC9F3, 0x4C3B, 0x061F, 0x069F, 0x06FF, 0x0EBE, 0xA2D5, 0xC9B3, 0xC9D3, 0xC9B2, 0xC9B3, 0xC9B2, 0xC1B3, 0x7152, 0x3911, 0x3911, 0x3110, 0x30F0, 0x30F0, 0x28F0, 0x30D0, 0x28CF, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CE, 0x08F7, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x011A, 0x0119, 0x20AE, 0x20AD, 0x18CE, 0x0119, 0x0119, 0x10D3, 0x20CE, 0x20AE, 0x10F4, 0x0119, 0x011A, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28CF, 0x28EF, 0x30EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x3911, 0x3911, 0x3911, 0x4112, 0x3912, 0x4112, 0x4132, 0x4133, 0x5153, 0xBB35, 0xD395, 0xD396, 0xD395, 0xD375, 0xD375, 0xD375, 0xD355, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xBBD6, 0x5DFB, 0x0FBF, 0x07FF, 0x07DF, 0x07BF, 0x077F, 0x075F, 0x073F, 0x071F, 0x06FF, 0x06DF, 0x06BF, 0x069F, 0x069F, 0x067F, 0x067F, 0x067F, 0x065F, 0x065F, 0x065F, 0x065F, 0x065F, 0x065F, 0x065F, 0x065F, 0x065F, 0x065F, 0x067F, 0x065F, 0x065F, 0x067F, 0x067F, 0x069F, 0x069F, 0x069F, 0x06BF, 0x06BF, 0x06DF, 0x06BF, 0x069F, 0x065F, 0x05FF, 0x053F, 0x049F, 0x1BBE, 0x8298, 0xCA13, 0xCA13, 0xCA13, 0xCA13, 0xCA13, 0xD1F3, 0x99B6, 0xC9F3, 0xC9F3, 0xB254, 0x0D9F, 0x067F, 0x06DF, 0x06FF, 0x0EBF, 0xA2D5, 0xC9D2, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B2, 0xC9B3, 0x8152, 0x3911, 0x3911, 0x3911, 0x30F0, 0x30F0, 0x28F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x00F9, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x08F5, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x08F5, 0x18AE, 0x20AE, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x0918, 0x0917, 0x0139, 0x011A, 0x10F5, 0x20CE, 0x20CF, 0x28CF, 0x28CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30EF, 0x30F0, 0x30F0, 0x30F0, 0x3110, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x3911, 0x4112, 0x4112, 0x4132, 0x4932, 0x4133, 0x4933, 0xBB35, 0xD395, 0xD396, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xAC37, 0x6D9A, 0x2EFE, 0x07FF, 0x07FF, 0x07DF, 0x07BF, 0x079F, 0x075F, 0x073F, 0x071F, 0x06DF, 0x06BF, 0x069F, 0x067F, 0x065F, 0x065F, 0x063F, 0x063F, 0x061F, 0x061F, 0x061F, 0x061F, 0x061F, 0x061F, 0x061F, 0x061F, 0x061F, 0x05FF, 0x061F, 0x061F, 0x061F, 0x061F, 0x061F, 0x061F, 0x063F, 0x063F, 0x063F, 0x065F, 0x065F, 0x065F, 0x065F, 0x067F, 0x067F, 0x063F, 0x05DF, 0x055F, 0x04BF, 0x043F, 0x037F, 0x1ABE, 0x7A18, 0xCA13, 0xCA13, 0xCA13, 0xC9F3, 0xC1F4, 0x7178, 0xC9F2, 0xD1F3, 0x8338, 0x061F, 0x06BF, 0x06FF, 0x071F, 0x0EDF, 0xA2D5, 0xC9B3, 0xC9B3, 0xC9B2, 0xC992, 0xC992, 0xC993, 0x9172, 0x3911, 0x3910, 0x3110, 0x30F0, 0x30F0, 0x30F0, 0x28EF, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AE, 0x00F7, 0x011A, 0x0119, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x20AD, 0x20AE, 0x20AE, 0x18CE, 0x0918, 0x011A, 0x011A, 0x0919, 0x011A, 0x0917, 0x20CF, 0x28AE, 0x20CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x28EF, 0x30EF, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x38F0, 0x3911, 0x3911, 0x3911, 0x3911, 0x3912, 0x4112, 0x4132, 0x4932, 0x4933, 0x4933, 0x4953, 0xA2B4, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD355, 0xD375, 0xD355, 0xC3B6, 0x8519, 0x4E3C, 0x0F9F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x079F, 0x077F, 0x077F, 0x075F, 0x073F, 0x06FF, 0x06BF, 0x069F, 0x067F, 0x065F, 0x063F, 0x061F, 0x061F, 0x05FF, 0x05DF, 0x05DF, 0x05DF, 0x05DF, 0x05BF, 0x05BF, 0x05DF, 0x05DF, 0x05BF, 0x05BF, 0x05BF, 0x05BF, 0x05BF, 0x05BF, 0x05DF, 0x05DF, 0x05DF, 0x05DF, 0x05FF, 0x05FF, 0x061F, 0x061F, 0x061F, 0x061F, 0x061F, 0x061F, 0x05DF, 0x057F, 0x04FF, 0x047F, 0x03DF, 0x031F, 0x025F, 0x19DE, 0x79B8, 0xC9F3, 0xCA13, 0xC9F3, 0xB9D3, 0xA1B5, 0xC9D3, 0xC9F3, 0x4C5B, 0x065F, 0x06DF, 0x071F, 0x071F, 0x0EDF, 0xA2B5, 0xC9B3, 0xC9B3, 0xC992, 0xC992, 0xC993, 0xC992, 0xB172, 0x4911, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x30EF, 0x28EF, 0x28EF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x10D2, 0x10F3, 0x10F3, 0x10D2, 0x20AE, 0x18AE, 0x20AE, 0x18CE, 0x20CE, 0x20CE, 0x20CE, 0x18F2, 0x10F4, 0x1114, 0x18F3, 0x20CF, 0x28CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x30EF, 0x30F0, 0x30F0, 0x30F0, 0x3110, 0x38F0, 0x3911, 0x3911, 0x3911, 0x3912, 0x3911, 0x4112, 0x4132, 0x4132, 0x4933, 0x4933, 0x4933, 0x4953, 0xA2B5, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xC3B5, 0x7D59, 0x36BD, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07BF, 0x07BF, 0x079F, 0x079F, 0x077F, 0x077F, 0x071F, 0x06DE, 0x069E, 0x067E, 0x065E, 0x063F, 0x063F, 0x061E, 0x05FF, 0x05DF, 0x05BF, 0x05BF, 0x059F, 0x059F, 0x059F, 0x057F, 0x057F, 0x057F, 0x057F, 0x057F, 0x057F, 0x057F, 0x057F, 0x057F, 0x057F, 0x057F, 0x057F, 0x059F, 0x059F, 0x059F, 0x05BF, 0x05BF, 0x05BF, 0x05DF, 0x05DF, 0x05DF, 0x05BF, 0x057F, 0x04FF, 0x049F, 0x03FF, 0x037F, 0x02BF, 0x021F, 0x017F, 0x213D, 0x9996, 0xC9F3, 0xC9F3, 0xB9D4, 0x99B6, 0xC9D3, 0xC213, 0x0DBF, 0x069F, 0x06FF, 0x071F, 0x073F, 0x0EFF, 0xA2B5, 0xC992, 0xC992, 0xC992, 0xC992, 0xC972, 0xC972, 0xA972, 0x4911, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AE, 0x18CE, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AF, 0x20CE, 0x28CE, 0x28CF, 0x28EF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x3110, 0x3910, 0x3911, 0x3911, 0x3911, 0x3911, 0x4111, 0x4131, 0x4112, 0x4132, 0x4913, 0x4933, 0x4933, 0x4953, 0x5154, 0xAAB5, 0xD375, 0xD395, 0xD375, 0xD395, 0xD375, 0x94D8, 0x467C, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07DF, 0x07BF, 0x07BF, 0x079F, 0x079F, 0x077F, 0x077F, 0x06DE, 0x06BE, 0x067E, 0x067E, 0x065E, 0x063E, 0x061E, 0x05FE, 0x05DE, 0x05DE, 0x05BE, 0x059F, 0x057F, 0x057F, 0x055F, 0x055F, 0x053F, 0x053F, 0x053F, 0x053F, 0x053F, 0x053F, 0x053F, 0x053F, 0x053F, 0x053F, 0x053F, 0x053F, 0x053F, 0x055F, 0x055F, 0x055F, 0x057F, 0x057F, 0x057F, 0x057F, 0x057F, 0x055F, 0x04FF, 0x04BF, 0x041F, 0x039F, 0x031F, 0x025F, 0x01BF, 0x013F, 0x00BF, 0x40FB, 0xB1B5, 0xC9D2, 0xB1D5, 0xB1D4, 0xC9B3, 0x6399, 0x061F, 0x06DF, 0x071F, 0x073F, 0x073F, 0x0EFF, 0xA2B5, 0xC992, 0xC992, 0xC972, 0xC972, 0xC992, 0xC972, 0xB152, 0x4111, 0x3911, 0x30F0, 0x30F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x0117, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x18AD, 0x20AE, 0x20AE, 0x20CE, 0x20CD, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28CE, 0x20CF, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30EF, 0x30D0, 0x28F0, 0x3110, 0x30F0, 0x30F0, 0x30F1, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x4112, 0x4132, 0x4132, 0x4132, 0x4932, 0x4933, 0x4953, 0x4953, 0x5153, 0x4A16, 0xA2B5, 0xD395, 0xD395, 0xD395, 0xD375, 0x8539, 0x1F5E, 0x07FF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07DF, 0x07DF, 0x07BF, 0x07BF, 0x079F, 0x07BF, 0x075F, 0x06BE, 0x069D, 0x067D, 0x065D, 0x063D, 0x063D, 0x061D, 0x05FE, 0x05DE, 0x05DE, 0x05BE, 0x059E, 0x057E, 0x055F, 0x053F, 0x053F, 0x051F, 0x051F, 0x04FF, 0x04FF, 0x04FF, 0x04FF, 0x04FF, 0x04FF, 0x04FF, 0x04FF, 0x04FF, 0x04FF, 0x04FF, 0x051F, 0x051F, 0x051F, 0x051F, 0x051F, 0x051F, 0x053F, 0x053F, 0x051F, 0x04DF, 0x04BF, 0x043F, 0x03DF, 0x035F, 0x02BF, 0x021F, 0x017F, 0x00FF, 0x009F, 0x087F, 0x7119, 0xC9D3, 0xB1D4, 0xB9D3, 0xC9B3, 0x1CFE, 0x065F, 0x06FF, 0x071F, 0x073F, 0x073F, 0x1EBE, 0xB9F3, 0xC993, 0xC972, 0xC992, 0xC972, 0xC973, 0xC952, 0xB152, 0x4111, 0x3910, 0x38F0, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x011A, 0x0139, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AD, 0x20CD, 0x20CE, 0x20AE, 0x20AE, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x20CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28CF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x3910, 0x3911, 0x3911, 0x3911, 0x3911, 0x4132, 0x4132, 0x4132, 0x4932, 0x4933, 0x4933, 0x4933, 0x4953, 0x4A15, 0x3439, 0x16BD, 0x8519, 0xD395, 0xD395, 0xD395, 0x94D8, 0x1F5E, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x071E, 0x069D, 0x069D, 0x067D, 0x065D, 0x063D, 0x063D, 0x061D, 0x05FD, 0x05DD, 0x05BD, 0x059D, 0x059E, 0x057E, 0x055E, 0x053E, 0x051E, 0x04FF, 0x04FF, 0x04DF, 0x04BF, 0x04BF, 0x04BF, 0x049F, 0x049F, 0x049F, 0x049F, 0x049F, 0x04BF, 0x04BF, 0x04BF, 0x04BF, 0x04BF, 0x04BF, 0x04DF, 0x04BF, 0x04DF, 0x04DF, 0x04DF, 0x04BF, 0x049F, 0x043F, 0x03DF, 0x035F, 0x02FF, 0x025F, 0x01BF, 0x013F, 0x00DF, 0x007F, 0x005F, 0x185E, 0x8957, 0x61B9, 0xC9D3, 0x9A96, 0x059F, 0x067F, 0x06FF, 0x071F, 0x073F, 0x075F, 0x267D, 0xB9D3, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC952, 0xB152, 0x4111, 0x38F1, 0x30F0, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18CF, 0x00F7, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x011A, 0x00F6, 0x18CE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CF, 0x20CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x3110, 0x38F1, 0x38F1, 0x3911, 0x3911, 0x4111, 0x4112, 0x4132, 0x4112, 0x4932, 0x4932, 0x4933, 0x4933, 0x69B4, 0x6336, 0x6CD9, 0x4E5B, 0x07DF, 0x8539, 0xD395, 0xD395, 0xBC17, 0x3E9C, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07FF, 0x07DF, 0x07DF, 0x07DF, 0x07BF, 0x07DF, 0x06BD, 0x069C, 0x069C, 0x067C, 0x065C, 0x065C, 0x063C, 0x061C, 0x05FC, 0x05DC, 0x05BC, 0x05BD, 0x059D, 0x057D, 0x055D, 0x053E, 0x051E, 0x04FE, 0x04DE, 0x04BE, 0x04BF, 0x049F, 0x047F, 0x047F, 0x047F, 0x045F, 0x045F, 0x045F, 0x047F, 0x047F, 0x047F, 0x047F, 0x047F, 0x047F, 0x047F, 0x047F, 0x047F, 0x047F, 0x049F, 0x047F, 0x045F, 0x041F, 0x03DF, 0x037F, 0x031F, 0x029F, 0x021F, 0x017F, 0x011F, 0x00BF, 0x005F, 0x001F, 0x001F, 0x00FF, 0x89B7, 0xC9B3, 0x447B, 0x065F, 0x06BF, 0x071F, 0x073F, 0x073F, 0x075F, 0x3D9B, 0xC972, 0xC972, 0xC972, 0xC972, 0xC952, 0xC952, 0xC952, 0xA132, 0x3911, 0x3911, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x20AE, 0x20CD, 0x18AD, 0x18D0, 0x00F9, 0x0119, 0x0119, 0x0119, 0x00FA, 0x0119, 0x0119, 0x011A, 0x08F4, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x3110, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x3931, 0x40F1, 0x4111, 0x4132, 0x4132, 0x4132, 0x61B3, 0x9274, 0xB2F5, 0xC355, 0xD395, 0xD395, 0xD395, 0xBC16, 0x469D, 0x8539, 0xD376, 0xD375, 0x6DBA, 0x0F9F, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x077F, 0x06BC, 0x06BB, 0x069B, 0x067B, 0x065B, 0x063B, 0x063B, 0x061B, 0x05FB, 0x05DB, 0x05BB, 0x059C, 0x059C, 0x057C, 0x055C, 0x053D, 0x051D, 0x04FD, 0x04DD, 0x04BE, 0x049E, 0x047F, 0x047F, 0x045F, 0x043F, 0x043F, 0x041F, 0x041F, 0x041F, 0x041F, 0x041F, 0x043F, 0x043F, 0x043F, 0x043F, 0x043F, 0x043F, 0x043F, 0x043F, 0x043F, 0x041F, 0x03FF, 0x03BF, 0x037F, 0x033F, 0x02BF, 0x023F, 0x01DF, 0x015F, 0x00DF, 0x009F, 0x005F, 0x001F, 0x005F, 0x097F, 0xB9B3, 0xB214, 0x0DBF, 0x06FF, 0x075F, 0x073F, 0x073F, 0x075F, 0x077F, 0x6479, 0xC972, 0xC972, 0xC952, 0xC952, 0xC952, 0xC952, 0xC932, 0x9132, 0x3911, 0x3111, 0x30F0, 0x28F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x18AD, 0x18D0, 0x00F9, 0x0119, 0x00F9, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x08F4, 0x20CD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30EF, 0x30F0, 0x28F0, 0x30F0, 0x3110, 0x38F0, 0x38F1, 0x3911, 0x3911, 0x3912, 0x4111, 0x4132, 0x4132, 0x5152, 0x8234, 0xC335, 0xD395, 0xD395, 0xD395, 0xD395, 0xAC57, 0x7D7A, 0x469C, 0x0F9F, 0xA4B8, 0xD395, 0x8539, 0x1F5E, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07FF, 0x07DF, 0x075D, 0x06BB, 0x06BB, 0x069A, 0x067A, 0x065A, 0x065A, 0x063A, 0x061A, 0x05FA, 0x05DA, 0x05DB, 0x05BB, 0x059B, 0x057B, 0x055B, 0x053C, 0x053C, 0x051C, 0x04FC, 0x04DD, 0x04BD, 0x047E, 0x047E, 0x045E, 0x043F, 0x041F, 0x03FF, 0x03FF, 0x03DF, 0x03DF, 0x03DF, 0x03DF, 0x03DF, 0x03DF, 0x03DF, 0x03DF, 0x03DF, 0x03DF, 0x03DF, 0x03DF, 0x03DF, 0x03DF, 0x03BF, 0x035F, 0x031F, 0x02DF, 0x027F, 0x01FF, 0x019F, 0x011F, 0x00BF, 0x007F, 0x003F, 0x001F, 0x009F, 0x39DB, 0xC992, 0x6399, 0x069F, 0x079F, 0x07FF, 0x07DF, 0x07BF, 0x077F, 0x079F, 0x9AF6, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC932, 0x7112, 0x3110, 0x30F0, 0x30EF, 0x28F0, 0x28EF, 0x28CE, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CD, 0x20CE, 0x20AE, 0x18CF, 0x00F9, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x011A, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08F3, 0x08D3, 0x10D2, 0x20AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x3911, 0x4112, 0x4132, 0x4132, 0x5193, 0x9274, 0xCB75, 0xD395, 0xD395, 0xD395, 0xC3D6, 0x6DBA, 0x1F7E, 0x07FF, 0x07FF, 0x36DD, 0xBC17, 0x8539, 0x1F5E, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07DF, 0x071B, 0x06DA, 0x06BA, 0x06BA, 0x0699, 0x0679, 0x0659, 0x0639, 0x0619, 0x0619, 0x05F9, 0x05DA, 0x05BA, 0x059A, 0x057A, 0x055A, 0x055B, 0x053B, 0x051B, 0x04FC, 0x04DC, 0x04BC, 0x049D, 0x047D, 0x045D, 0x043E, 0x041E, 0x03FE, 0x03DF, 0x03DF, 0x03BF, 0x03BF, 0x039F, 0x039F, 0x039F, 0x039F, 0x039F, 0x039F, 0x039F, 0x039F, 0x039F, 0x039F, 0x039F, 0x037F, 0x035F, 0x031F, 0x02DF, 0x027F, 0x023F, 0x01BF, 0x015F, 0x00FF, 0x009F, 0x005F, 0x001F, 0x003F, 0x011F, 0x99B6, 0xB9D3, 0x0D9F, 0x06DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x0F7E, 0xB9B3, 0xC952, 0xC952, 0xC952, 0xC952, 0xC931, 0xC932, 0xC132, 0x6111, 0x38F0, 0x30F0, 0x28F0, 0x30EF, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x18CE, 0x08F5, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x3110, 0x3910, 0x3911, 0x3911, 0x3912, 0x4132, 0x4132, 0x6173, 0xA2B4, 0xD395, 0xD375, 0xD395, 0xD395, 0xC3D6, 0x6DBA, 0x0FBF, 0x07FF, 0x07DF, 0x07FF, 0x07DF, 0x1F7E, 0x07DF, 0x07FF, 0x07FF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x06F9, 0x06F9, 0x06D9, 0x06B8, 0x0698, 0x0698, 0x0678, 0x0658, 0x0638, 0x0638, 0x0618, 0x05F8, 0x05D8, 0x05B8, 0x0598, 0x0579, 0x0559, 0x0559, 0x051A, 0x04FA, 0x04DB, 0x04BB, 0x049C, 0x047C, 0x045D, 0x043D, 0x041E, 0x03FE, 0x03DE, 0x03BF, 0x039F, 0x039F, 0x037F, 0x037F, 0x037F, 0x035F, 0x035F, 0x035F, 0x035F, 0x035F, 0x035F, 0x035F, 0x033F, 0x033F, 0x031F, 0x02FF, 0x02BF, 0x027F, 0x023F, 0x01FF, 0x019F, 0x013F, 0x00BF, 0x007F, 0x003F, 0x001F, 0x005F, 0x197E, 0xB993, 0x6379, 0x063F, 0x073F, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x3DFB, 0xC952, 0xC952, 0xC932, 0xC932, 0xC932, 0xC932, 0xC912, 0xB912, 0x4111, 0x30F0, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x08F6, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F5, 0x20AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18CD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x0117, 0x00F7, 0x0119, 0x0119, 0x08F4, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28EF, 0x28CF, 0x28EF, 0x30EF, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x3911, 0x4111, 0x4952, 0x79F3, 0xB2F4, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0x94F9, 0x0FBF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x079D, 0x0719, 0x06F8, 0x06F8, 0x06D7, 0x06B7, 0x06B7, 0x0697, 0x0676, 0x0656, 0x0637, 0x0636, 0x0617, 0x05F7, 0x05D7, 0x05B7, 0x0597, 0x0578, 0x0578, 0x0538, 0x0519, 0x04F9, 0x04DA, 0x04BB, 0x049B, 0x047C, 0x043C, 0x041D, 0x041D, 0x03FE, 0x03DE, 0x03BE, 0x039E, 0x037F, 0x035F, 0x035F, 0x033F, 0x031F, 0x031F, 0x031F, 0x031F, 0x02FF, 0x02FF, 0x02FF, 0x02FF, 0x02DF, 0x02BF, 0x029F, 0x027F, 0x023F, 0x01FF, 0x019F, 0x015F, 0x00FF, 0x009F, 0x005F, 0x003F, 0x001F, 0x00BF, 0x59BA, 0xB9B3, 0x0D3F, 0x06BF, 0x079F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x7438, 0xC952, 0xC132, 0xC932, 0xC932, 0xC932, 0xC911, 0xC912, 0xA111, 0x3911, 0x30F0, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x08F5, 0x011A, 0x0119, 0x00FA, 0x0119, 0x0119, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x011A, 0x08F3, 0x18AD, 0x18AD, 0x10D3, 0x011A, 0x00F9, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x3911, 0x3911, 0x5151, 0x79F3, 0xA2B4, 0xCB75, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xC3D6, 0x469C, 0x07FF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0xC335, 0x45D7, 0x0738, 0x0717, 0x06F6, 0x06F6, 0x06D6, 0x06B5, 0x06B5, 0x0695, 0x0675, 0x0655, 0x0635, 0x0615, 0x05F5, 0x05F5, 0x05D6, 0x05B6, 0x0597, 0x0557, 0x0538, 0x0518, 0x04F9, 0x04D9, 0x049A, 0x047B, 0x045B, 0x043C, 0x041C, 0x03DD, 0x03DD, 0x03BE, 0x039E, 0x037E, 0x035F, 0x033F, 0x033F, 0x031F, 0x02FF, 0x02DF, 0x02DF, 0x02BF, 0x02BF, 0x02BF, 0x02BF, 0x029F, 0x029F, 0x027F, 0x025F, 0x021F, 0x01FF, 0x01BF, 0x017F, 0x011F, 0x00DF, 0x009F, 0x003F, 0x001F, 0x003F, 0x013F, 0xB174, 0x6339, 0x05FF, 0x071F, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x0F9F, 0xB992, 0xC932, 0xC932, 0xC931, 0xC912, 0xC912, 0xC912, 0xC911, 0x8111, 0x30F0, 0x30F0, 0x28EF, 0x30EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20D0, 0x0119, 0x0119, 0x0119, 0x0139, 0x08F5, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AF, 0x00F9, 0x0119, 0x18D0, 0x18CD, 0x18AD, 0x10D1, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CF, 0x28EF, 0x28EF, 0x28EF, 0x30F0, 0x30F0, 0x59B2, 0x7A13, 0x9A94, 0xBB55, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xAC77, 0x2F1E, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07BC, 0x0759, 0xABB5, 0xC314, 0x1E97, 0x0736, 0x0716, 0x0715, 0x06F4, 0x06F4, 0x06F3, 0x06D3, 0x06B3, 0x06B2, 0x0692, 0x0672, 0x0653, 0x0633, 0x0613, 0x05F4, 0x05D4, 0x0595, 0x0575, 0x0556, 0x0517, 0x04F8, 0x04B9, 0x0499, 0x045A, 0x043B, 0x041B, 0x03FC, 0x03DD, 0x03BD, 0x039D, 0x037E, 0x035E, 0x033E, 0x033F, 0x031F, 0x02FF, 0x02DF, 0x02BF, 0x02BF, 0x029F, 0x027F, 0x027F, 0x025F, 0x025F, 0x023F, 0x021F, 0x021F, 0x01DF, 0x019F, 0x017F, 0x013F, 0x00FF, 0x009F, 0x007F, 0x003F, 0x001F, 0x007F, 0x399B, 0xB993, 0x055F, 0x067F, 0x079F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x45DB, 0xC132, 0xC932, 0xC912, 0xC132, 0xC912, 0xC912, 0xC911, 0xC912, 0x5111, 0x38F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x18CE, 0x10D3, 0x10F4, 0x18D0, 0x18AD, 0x18AE, 0x20CD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x00F9, 0x10D0, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x08D4, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x20CD, 0x20AE, 0x20AD, 0x20AE, 0x18CE, 0x20AE, 0x20CE, 0x20CE, 0x28AE, 0x20CE, 0x28EE, 0x5171, 0x69D2, 0x8232, 0xAAF4, 0xC334, 0xD375, 0xD3B5, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0x757A, 0x0FBF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07BD, 0x079B, 0x077A, 0x0779, 0x74D6, 0xD2D4, 0x9BF5, 0x0756, 0x0735, 0x0734, 0x0734, 0x0733, 0x0712, 0x0711, 0x0711, 0x06F0, 0x06F0, 0x06D0, 0x06AF, 0x06AF, 0x066F, 0x0650, 0x0631, 0x0611, 0x05D2, 0x0594, 0x0554, 0x0515, 0x04F7, 0x04B8, 0x0478, 0x0459, 0x043A, 0x03FB, 0x03BC, 0x03BC, 0x039D, 0x037D, 0x035E, 0x033E, 0x031F, 0x031F, 0x02FF, 0x02DF, 0x02BF, 0x02BF, 0x027F, 0x027F, 0x025F, 0x023F, 0x023F, 0x021F, 0x01FF, 0x01DF, 0x01BF, 0x019F, 0x017F, 0x013F, 0x011F, 0x00BF, 0x007F, 0x005F, 0x001F, 0x001F, 0x00DF, 0xA175, 0x33BC, 0x05DF, 0x06FF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x92D5, 0xC911, 0xC132, 0xC912, 0xC912, 0xC8F2, 0xC112, 0xC912, 0xA8F1, 0x3110, 0x30F0, 0x30EF, 0x28EF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x0119, 0x0119, 0x10CF, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x08F5, 0x0119, 0x0119, 0x00F7, 0x00F7, 0x011A, 0x011A, 0x08F5, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AD, 0x390F, 0x4970, 0x59B0, 0x7A32, 0x9293, 0xAAD3, 0xCB55, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0x9CB8, 0x271D, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DE, 0x07DD, 0x07BC, 0x079B, 0x079A, 0x079A, 0x0779, 0x55B7, 0xD2B4, 0xD2B4, 0x4DB5, 0x0775, 0x0774, 0x0753, 0x0773, 0x0752, 0x0750, 0x0750, 0x074F, 0x074E, 0x074D, 0x074D, 0x074C, 0x072B, 0x072B, 0x072A, 0x070A, 0x06EA, 0x06AC, 0x064D, 0x05D0, 0x0573, 0x04F5, 0x04B6, 0x0478, 0x0438, 0x041A, 0x03FB, 0x03BC, 0x039C, 0x037C, 0x033D, 0x033D, 0x031E, 0x02FE, 0x02FF, 0x02DF, 0x02BF, 0x029F, 0x029F, 0x027F, 0x025F, 0x023F, 0x021F, 0x01FF, 0x01DF, 0x01BF, 0x019F, 0x017F, 0x015F, 0x013F, 0x011F, 0x00DF, 0x009F, 0x005F, 0x003F, 0x001F, 0x003F, 0x213D, 0x1B1E, 0x051F, 0x065F, 0x077F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x1F3D, 0xC912, 0xC912, 0xC112, 0xC112, 0xC8F1, 0xC8F2, 0xC8F1, 0xC8F2, 0x80F1, 0x30F0, 0x30F0, 0x30EF, 0x28EF, 0x28CF, 0x28CE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x00F7, 0x00F9, 0x0119, 0x10D0, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x10D0, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x392F, 0xD395, 0xC374, 0xA2D3, 0xAAD3, 0x7A31, 0x7A31, 0x7A11, 0x7231, 0x5190, 0x496F, 0x496F, 0x4970, 0x496F, 0x494F, 0x412F, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x4970, 0x494F, 0x496F, 0x496F, 0x69F1, 0x7A31, 0x7A31, 0x9272, 0xA2D3, 0xAAF3, 0xC355, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD375, 0xD395, 0xAC57, 0x565C, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07DE, 0x07BD, 0x07BC, 0x07BC, 0x07BB, 0x079A, 0x079A, 0x0799, 0x26B8, 0xCAD4, 0xD2B4, 0xC314, 0x0F35, 0x0794, 0x0794, 0x0792, 0x0792, 0x0791, 0x0790, 0x078F, 0x078E, 0x078E, 0x078D, 0x078C, 0x07AA, 0x07A9, 0x07A9, 0x07A8, 0x07C7, 0x07C5, 0x07C4, 0x07E4, 0x07A4, 0x0727, 0x068A, 0x05AF, 0x0496, 0x0438, 0x03F9, 0x03BA, 0x039B, 0x035C, 0x035D, 0x031D, 0x031D, 0x02FE, 0x02DF, 0x02BF, 0x02BF, 0x029F, 0x027F, 0x025F, 0x025F, 0x023F, 0x021F, 0x01FF, 0x01DF, 0x019F, 0x019F, 0x017F, 0x015F, 0x013F, 0x00FF, 0x00DF, 0x00BF, 0x007F, 0x005F, 0x001F, 0x001F, 0x007F, 0x023F, 0x041F, 0x05BF, 0x06FF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x6498, 0xC911, 0xC912, 0xC8F1, 0xC8F1, 0xC8F1, 0xC8F2, 0xC8F1, 0xC8D1, 0x50F1, 0x30F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x0119, 0x0119, 0x0117, 0x10D2, 0x08F3, 0x10D3, 0x10D2, 0x18CD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x496F, 0xAAD3, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xC3D6, 0x8539, 0x36DD, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07DE, 0x07BD, 0x07BD, 0x07BC, 0x07BC, 0x07BB, 0x07BA, 0x07BA, 0x07B9, 0xD2B4, 0xD2B4, 0xD2B4, 0x6535, 0x07B5, 0x07B5, 0x07B4, 0x07B3, 0x07B2, 0x07B1, 0x07B0, 0x07AF, 0x07CE, 0x07CD, 0x07CC, 0x07CB, 0x07CA, 0x07CA, 0x07C9, 0x07E8, 0x07E7, 0x07E6, 0x07E5, 0x07E5, 0x07E3, 0x07E3, 0x07E2, 0x07E1, 0x0726, 0x060C, 0x04B4, 0x03B9, 0x037B, 0x035C, 0x033D, 0x031D, 0x02DE, 0x02DF, 0x02BE, 0x029F, 0x029F, 0x027F, 0x025F, 0x023F, 0x023F, 0x021F, 0x01FF, 0x01DF, 0x019F, 0x019F, 0x015F, 0x015F, 0x013F, 0x00FF, 0x00DF, 0x00BF, 0x007F, 0x007F, 0x003F, 0x001F, 0x001F, 0x011F, 0x02FF, 0x04DF, 0x063F, 0x077F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x0F9F, 0xB972, 0xC8F2, 0xC8F2, 0xC0F1, 0xC8F2, 0xC0F2, 0xC0F1, 0xC8D1, 0xA0F1, 0x30F0, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CE, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AE, 0x0117, 0x0119, 0x00F9, 0x18B0, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D0, 0x00F9, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x412F, 0x8A72, 0xC334, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD375, 0xAC57, 0x469C, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x467C, 0x8519, 0x8519, 0x36DD, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DE, 0x07DE, 0x07DE, 0x07DD, 0x07DC, 0x07DC, 0x07DB, 0x07DB, 0x07DA, 0x07DA, 0x9BF5, 0xD2B4, 0xD2B4, 0xC2F4, 0x0F77, 0x07D6, 0x07D5, 0x07D4, 0x07D4, 0x07D3, 0x07D2, 0x07D1, 0x07D0, 0x07EF, 0x07EE, 0x07ED, 0x07EC, 0x07EC, 0x07EA, 0x07E9, 0x07E9, 0x07E7, 0x07E6, 0x07E6, 0x07E5, 0x07E5, 0x07E4, 0x07E4, 0x07E3, 0x07E3, 0x07E2, 0x0785, 0x060C, 0x04D3, 0x035B, 0x031C, 0x02DE, 0x02DE, 0x02BE, 0x029F, 0x027F, 0x025F, 0x025F, 0x023F, 0x021F, 0x01FF, 0x01DF, 0x01BF, 0x019F, 0x019F, 0x017F, 0x015F, 0x013F, 0x011F, 0x00DF, 0x00BF, 0x009F, 0x007F, 0x005F, 0x001F, 0x001F, 0x003F, 0x01DF, 0x03BF, 0x059F, 0x06DF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x4D7A, 0xC111, 0xC0F1, 0xC8F1, 0xC8F2, 0xC8D1, 0xC8F2, 0xC0D1, 0xC8D1, 0x68F1, 0x30F0, 0x30F0, 0x28F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08F3, 0x08F3, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18CD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x00F8, 0x18D0, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x414F, 0x61D1, 0x8251, 0xA2D3, 0xBB34, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xBC16, 0x8539, 0x469C, 0x17BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x8518, 0xD355, 0xD355, 0xD335, 0xD335, 0x84F8, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07DE, 0x07FE, 0x07DD, 0x07DD, 0x07BC, 0x07DC, 0x07DB, 0x07DB, 0x07DA, 0x8C56, 0xCAB4, 0xCAB4, 0xD294, 0x4DF7, 0x07D7, 0x07D7, 0x07D6, 0x07F5, 0x07D5, 0x07F3, 0x07F3, 0x07F2, 0x07F1, 0x07F0, 0x07EF, 0x07EE, 0x07ED, 0x07EC, 0x07EB, 0x07EB, 0x07EA, 0x07E9, 0x07E8, 0x07E8, 0x07E7, 0x07E7, 0x07E6, 0x07E6, 0x07E5, 0x07E5, 0x07E5, 0x07E5, 0x07E4, 0x07A6, 0x060E, 0x03F8, 0x02DE, 0x02BE, 0x029F, 0x027F, 0x025F, 0x023F, 0x023F, 0x021F, 0x01FF, 0x01DF, 0x01BF, 0x019F, 0x019F, 0x017F, 0x015F, 0x013F, 0x011F, 0x00DF, 0x00BF, 0x009F, 0x007F, 0x005F, 0x003F, 0x001F, 0x001F, 0x00BF, 0x029F, 0x049F, 0x063F, 0x075F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xB1D3, 0xC8F1, 0xC8F2, 0xC0F1, 0xC8D1, 0xC8D1, 0xC0F1, 0xC8D1, 0xB8D1, 0x40F0, 0x30F0, 0x28F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CF, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0139, 0x00F8, 0x18B0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D0, 0x00F9, 0x0119, 0x00F7, 0x18AF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x310E, 0x496F, 0x5990, 0x7A12, 0x7A32, 0x9272, 0xA2D3, 0xA2D3, 0xC375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xAC77, 0x757A, 0x36FD, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x4E3C, 0xD355, 0xD335, 0xD355, 0xD335, 0xD335, 0xD334, 0x7539, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07FE, 0x07DD, 0x07DD, 0x07DD, 0x07DC, 0x07FC, 0x07DC, 0x07DB, 0x6D38, 0xCAB4, 0xD294, 0xD294, 0xAB95, 0x07D8, 0x07D8, 0x07F7, 0x07F7, 0x07F6, 0x07F5, 0x07F5, 0x07F4, 0x07F3, 0x07F2, 0x07F1, 0x07F0, 0x07EF, 0x07EE, 0x07ED, 0x07ED, 0x07EC, 0x07EC, 0x07EB, 0x07EA, 0x07EA, 0x07EA, 0x07E9, 0x07E9, 0x07E8, 0x07E8, 0x07E8, 0x07E8, 0x07E7, 0x07E7, 0x07E8, 0x07C8, 0x06EB, 0x0514, 0x033C, 0x027F, 0x025F, 0x023F, 0x021F, 0x01FF, 0x01DF, 0x01BF, 0x019F, 0x019F, 0x017F, 0x015F, 0x013F, 0x011F, 0x00FF, 0x00DF, 0x00BF, 0x009F, 0x009F, 0x005F, 0x005F, 0x003F, 0x001F, 0x001F, 0x015F, 0x037F, 0x057F, 0x06DF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x4D5A, 0xC8F1, 0xC8D1, 0xC0F1, 0xC8D1, 0xC8D1, 0xC0D1, 0xC0D1, 0xC8B1, 0x78D1, 0x3110, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x0117, 0x0117, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AF, 0x0118, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x496F, 0x496F, 0x4970, 0x7A12, 0x7A31, 0x8252, 0xAAD3, 0xA2D3, 0xBB34, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xCBD6, 0x94F8, 0x565B, 0x0FBF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xB3F6, 0xD335, 0xD335, 0xD334, 0xD335, 0xD335, 0xD335, 0xD334, 0x1F7E, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07DE, 0x07DD, 0x07FD, 0x07FD, 0x07FD, 0x07DD, 0x07DC, 0x6D38, 0xCAB4, 0xD294, 0xCA94, 0xD294, 0x1F39, 0x07F9, 0x07F8, 0x07F8, 0x07F8, 0x07F7, 0x07F7, 0x07F6, 0x07F5, 0x07F4, 0x07F3, 0x07F2, 0x07F2, 0x07F1, 0x07F0, 0x07EF, 0x07EF, 0x07EE, 0x07EE, 0x07ED, 0x07ED, 0x07EC, 0x07ED, 0x07EC, 0x07EB, 0x07EC, 0x07EB, 0x07EB, 0x07EA, 0x07EA, 0x07EA, 0x07CA, 0x07AB, 0x076C, 0x070D, 0x05B2, 0x039B, 0x023F, 0x021F, 0x01FF, 0x01DF, 0x01BF, 0x019F, 0x017F, 0x017F, 0x015F, 0x013F, 0x011F, 0x00FF, 0x00DF, 0x00DF, 0x009F, 0x009F, 0x007F, 0x005F, 0x003F, 0x003F, 0x001F, 0x60D9, 0x0A3F, 0x047F, 0x063F, 0x075F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xA9D3, 0xC0D1, 0xC8D1, 0xC0F1, 0xC8B1, 0xC0D1, 0xC8B1, 0xC0B1, 0xB8B1, 0x48F1, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x10D0, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x00F9, 0x10D0, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18D0, 0x00F9, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x18CD, 0x20AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x4970, 0x4970, 0x5990, 0x7A31, 0x7231, 0x7A31, 0x7A31, 0x9AB3, 0xAAD4, 0xA2D4, 0xB314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0x94F8, 0x565C, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xD335, 0xD334, 0xD335, 0xD335, 0xD335, 0xD335, 0xD314, 0xD315, 0x5DDB, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FD, 0x07FD, 0x6D58, 0xD294, 0xD293, 0xCA94, 0xD274, 0x4DF8, 0x07FB, 0x07FA, 0x07FA, 0x07F9, 0x07F9, 0x07F8, 0x07F7, 0x07F6, 0x07F6, 0x07F5, 0x07F5, 0x07F4, 0x07F3, 0x07F3, 0x07F2, 0x07F1, 0x07F1, 0x07F0, 0x07F0, 0x07F0, 0x07EF, 0x07EF, 0x07EF, 0x07EF, 0x07EF, 0x07EE, 0x07EE, 0x07EE, 0x07EE, 0x07EE, 0x07ED, 0x07CD, 0x078E, 0x076E, 0x0710, 0x06B1, 0x0574, 0x037B, 0x01FF, 0x01DF, 0x01BF, 0x019F, 0x017F, 0x017F, 0x013F, 0x013F, 0x011F, 0x00FF, 0x00DF, 0x00BF, 0x009F, 0x009F, 0x007F, 0x005F, 0x003F, 0x003F, 0x001F, 0x88D6, 0x6159, 0x031F, 0x053F, 0x06DF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x4D5B, 0xC0D1, 0xC8D1, 0xC8D1, 0xC0B1, 0xC8B1, 0xC8B2, 0xC0B1, 0xC8B1, 0x90D1, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CF, 0x20CF, 0x20CF, 0x20CE, 0x20AE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x0119, 0x011A, 0x10D1, 0x18AD, 0x18AD, 0x10D1, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, + 0x00F8, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x0117, 0x0119, 0x0119, 0x10CF, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18B0, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x10D2, 0x08F3, 0x08F3, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AE, 0x18AD, 0x18CE, 0x18AD, 0x20AE, 0x20AD, 0x20CE, 0x20CE, 0x290F, 0x5170, 0x5170, 0x69F1, 0x7A32, 0x8232, 0xAAF3, 0xAAF4, 0xCB75, 0xD395, 0xD396, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xC3B6, 0x8539, 0x1F7F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xD335, 0xD335, 0xD335, 0xD315, 0xD314, 0xD315, 0xD314, 0xD314, 0x659A, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x6D39, 0xD294, 0xCA94, 0xD274, 0xCA74, 0x7C96, 0x07FC, 0x07FC, 0x07FB, 0x07FB, 0x07FA, 0x07FA, 0x07F9, 0x07F8, 0x07F8, 0x07F7, 0x07F7, 0x07F6, 0x07F6, 0x07F5, 0x07F4, 0x07F4, 0x07F3, 0x07F3, 0x07F3, 0x07F2, 0x07F2, 0x07F2, 0x07F2, 0x07F2, 0x07F2, 0x07F2, 0x07F1, 0x07F1, 0x07F1, 0x07F1, 0x07F0, 0x07F1, 0x07D0, 0x0791, 0x0751, 0x0712, 0x0693, 0x0634, 0x0517, 0x02DD, 0x01BF, 0x019F, 0x017F, 0x015F, 0x015F, 0x013F, 0x011F, 0x00FF, 0x00DF, 0x00BF, 0x00BF, 0x007F, 0x005F, 0x005F, 0x003F, 0x003F, 0x001F, 0x60B8, 0xB8F3, 0x09BF, 0x041F, 0x061F, 0x073F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xB1B3, 0xC0D1, 0xC0D1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0x48F1, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, + 0x011A, 0x0118, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x00F9, 0x0119, 0x10D0, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AF, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x20AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18CD, 0x18AE, 0x00F7, 0x011A, 0x011A, 0x011A, 0x0119, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28CE, 0x28CF, 0x28EF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x5172, 0x61B2, 0x8A54, 0x9A94, 0xB335, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0x9C97, 0x36DD, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xAC17, 0xD335, 0xD314, 0xD335, 0xD314, 0xD315, 0xD315, 0xD2F4, 0x467C, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x6D59, 0xD274, 0xCA94, 0xD274, 0xCA74, 0xB334, 0x07FE, 0x07FD, 0x07FD, 0x07FD, 0x07FC, 0x07FC, 0x07FB, 0x07FA, 0x07FA, 0x07FA, 0x07F9, 0x07F8, 0x07F8, 0x07F8, 0x07F7, 0x07F6, 0x07F6, 0x07F6, 0x07F5, 0x07F5, 0x07F5, 0x07F5, 0x07F5, 0x07F5, 0x07F5, 0x07F5, 0x07F5, 0x07F5, 0x07F5, 0x07F4, 0x07F4, 0x07F4, 0x07D3, 0x07B3, 0x0793, 0x0753, 0x0714, 0x06B5, 0x5516, 0x0538, 0x037C, 0x01FF, 0x017F, 0x015F, 0x013F, 0x011F, 0x011F, 0x00FF, 0x00DF, 0x00BF, 0x009F, 0x009F, 0x007F, 0x005F, 0x005F, 0x003F, 0x001F, 0x6099, 0xC911, 0x491A, 0x02DF, 0x051F, 0x06BF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x6459, 0xC8B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x90D1, 0x30F1, 0x30F0, 0x30EF, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x00F7, 0x00F7, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x00F7, 0x011A, 0x00F8, 0x10D0, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x08F5, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x20AD, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x3111, 0x3911, 0x3911, 0x4132, 0x4132, 0x5152, 0x69D3, 0x9274, 0xB2F5, 0xD395, 0xD395, 0xD375, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xA478, 0x36DD, 0x07FF, 0x07FF, 0x563C, 0xD335, 0xD334, 0xD315, 0xD315, 0xD2F4, 0xCB15, 0xBB96, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x8498, 0xCA94, 0xCA94, 0xD274, 0xCA74, 0xCA74, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FD, 0x07FD, 0x07FC, 0x07FC, 0x07FC, 0x07FB, 0x07FB, 0x07FA, 0x07FA, 0x07F9, 0x07F9, 0x07F8, 0x07F8, 0x07F8, 0x07F8, 0x07F7, 0x07F7, 0x07F7, 0x07F7, 0x07F7, 0x07F7, 0x07F7, 0x07F7, 0x07F7, 0x07F7, 0x07F7, 0x07F7, 0x07F6, 0x07F6, 0x07D6, 0x07B6, 0x0796, 0x0756, 0x0716, 0xA456, 0xBBD6, 0x3479, 0x02FD, 0x023F, 0x019F, 0x015F, 0x011F, 0x00FF, 0x00FF, 0x00BF, 0x00BF, 0x009F, 0x009F, 0x007F, 0x005F, 0x003F, 0x003F, 0x003F, 0x78B7, 0xC111, 0xA114, 0x01FF, 0x041F, 0x05FF, 0x075F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x0F9F, 0xC0B1, 0xC0D2, 0xC8B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x48F1, 0x30F0, 0x30EF, 0x28F0, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18CE, 0x08F7, 0x0119, 0x00F8, 0x10CF, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x00F9, 0x18B0, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AF, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AE, 0x20CD, 0x20CD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CE, 0x28CF, 0x28CF, 0x28CF, 0x28F0, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x4132, 0x4132, 0x4932, 0x4933, 0x4953, 0x5154, 0x5154, 0x71F4, 0x9A75, 0xB2F5, 0xD375, 0xD375, 0xD375, 0xD355, 0xD375, 0xD355, 0xD375, 0xD355, 0xD355, 0xD335, 0xD335, 0x9C78, 0x36DD, 0x07FF, 0x9C57, 0xD335, 0xD315, 0xD334, 0xD314, 0xC355, 0x271D, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x9BF7, 0xCA94, 0xD274, 0xCA73, 0xCA74, 0xD253, 0x2EFD, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07FE, 0x07FD, 0x07FD, 0x07FD, 0x07FC, 0x07FC, 0x07FB, 0x07FB, 0x07FB, 0x07FA, 0x07FA, 0x07FA, 0x07F9, 0x07F9, 0x07F9, 0x07F9, 0x07F9, 0x07F9, 0x07FA, 0x07FA, 0x07FA, 0x07FA, 0x07FA, 0x07FA, 0x07F9, 0x07F9, 0x07F9, 0x07F8, 0x07D8, 0x07B8, 0x0797, 0x0758, 0x0EF8, 0xBBF6, 0xD395, 0x6B99, 0x025F, 0x021F, 0x01BF, 0x013F, 0x011F, 0x00FF, 0x00DF, 0x00BF, 0x009F, 0x009F, 0x007F, 0x005F, 0x005F, 0x003F, 0x001F, 0x98D5, 0xC8F2, 0xC911, 0x195E, 0x033F, 0x053F, 0x06BF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x7B76, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0x88D1, 0x30F1, 0x30F0, 0x28F0, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08F3, 0x08F3, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AE, 0x18AE, 0x00F7, 0x011A, 0x00F9, 0x18CF, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x00F8, 0x18D0, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18B0, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x00F9, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x00FA, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x20AE, 0x20AE, 0x18AD, 0x20AE, 0x20AE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CF, 0x28CE, 0x28CF, 0x28CF, 0x28EF, 0x30EF, 0x30F0, 0x30F0, 0x3111, 0x3910, 0x3911, 0x4111, 0x4912, 0x4133, 0x4932, 0x4933, 0x5154, 0x5154, 0x5955, 0x5955, 0x5975, 0x6996, 0x8A16, 0xAAD5, 0xCB55, 0xD375, 0xD355, 0xD354, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xCB35, 0x84F9, 0x0FBF, 0x5DDB, 0xA457, 0x9C58, 0x84D8, 0x1F5E, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x9BD6, 0xCA74, 0xCA74, 0xCA74, 0xCA74, 0xCA74, 0x369C, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07FE, 0x07FE, 0x07FD, 0x07FD, 0x07FD, 0x07FC, 0x07FC, 0x07FC, 0x07FB, 0x07FB, 0x07FB, 0x07FB, 0x07FB, 0x07FB, 0x07FB, 0x07FB, 0x07FB, 0x07FC, 0x07FC, 0x07FC, 0x07FC, 0x07FB, 0x07FB, 0x07FB, 0x07FB, 0x07DA, 0x07DA, 0x07BA, 0x079A, 0x0779, 0x2E99, 0xC3D6, 0xD395, 0x8339, 0x0A3E, 0x01DF, 0x019F, 0x015F, 0x011F, 0x00FF, 0x00BF, 0x009F, 0x007F, 0x007F, 0x007F, 0x003F, 0x003F, 0x003F, 0x90D5, 0xC912, 0xC0F1, 0x7117, 0x027F, 0x049F, 0x065F, 0x077F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x269D, 0xC891, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xB8B1, 0x3110, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AE, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x10CF, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0139, 0x00F8, 0x18B0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18D0, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x00F9, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20CD, 0x18CE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28EF, 0x28CF, 0x28EF, 0x28D0, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x3931, 0x4132, 0x4132, 0x4933, 0x5133, 0x5153, 0x5154, 0x5154, 0x5975, 0x6175, 0x6195, 0x9255, 0x8B14, 0x4AD3, 0x7A94, 0xAB14, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD315, 0xD314, 0xD335, 0xC355, 0x467C, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xC2D4, 0xCA74, 0xCA74, 0xD274, 0xCA74, 0xD253, 0x369C, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FD, 0x07FD, 0x07FD, 0x07FD, 0x07FD, 0x07FC, 0x07FC, 0x07FC, 0x07FD, 0x07FD, 0x07FD, 0x07FD, 0x07FD, 0x07FD, 0x07FE, 0x07FE, 0x07FE, 0x07FD, 0x07FD, 0x07FD, 0x07FC, 0x07FC, 0x07DB, 0x07BB, 0x07BB, 0x077B, 0x2EBA, 0xC3D6, 0xD395, 0xB337, 0x09DF, 0x01BF, 0x017F, 0x013F, 0x011F, 0x00DF, 0x009F, 0x009F, 0x007F, 0x005F, 0x005F, 0x003F, 0x003F, 0x7896, 0xC0F1, 0xC8F1, 0xA8F3, 0x01DF, 0x03DF, 0x05BF, 0x071F, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xA214, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0x68F1, 0x30F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x00F9, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AF, 0x00F9, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20EF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30EF, 0x30F0, 0x30F0, 0x3911, 0x3911, 0x4111, 0x4132, 0x4932, 0x4933, 0x5133, 0x5153, 0x5154, 0x5954, 0x6195, 0x9A75, 0xCB55, 0xCB75, 0x5BB4, 0x3B34, 0x42B3, 0x4A33, 0x6253, 0x9AB4, 0xD335, 0xD335, 0xD315, 0xD334, 0xD314, 0xD315, 0xD314, 0xD314, 0x5DDB, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x1F5E, 0xD274, 0xD274, 0xD274, 0xD274, 0xD274, 0xCA53, 0x369D, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07FE, 0x07FE, 0x07FD, 0x07DD, 0x07DD, 0x07BD, 0x079C, 0x561A, 0xD395, 0xD395, 0xAB37, 0x099F, 0x015F, 0x013F, 0x011F, 0x00FF, 0x00BF, 0x009F, 0x007F, 0x007F, 0x005F, 0x003F, 0x003F, 0x305C, 0xC0F1, 0xC8F1, 0xC8D1, 0x215D, 0x033F, 0x051F, 0x06DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x5CD9, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x98D1, 0x38F0, 0x30F0, 0x30F0, 0x28CF, 0x28EF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x011A, 0x00F8, 0x10D0, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18CE, 0x00F7, 0x0119, 0x00F8, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F8, 0x011A, 0x00F7, 0x18AE, 0x20AE, 0x18AD, 0x18AD, 0x18CD, 0x18B0, 0x00F9, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x0117, 0x0119, 0x0119, 0x011A, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x3911, 0x3911, 0x4111, 0x4131, 0x4132, 0x4933, 0x4933, 0x5154, 0x5974, 0x9255, 0xCB55, 0xD375, 0xBB95, 0x5474, 0x3C34, 0x3BB4, 0x4333, 0x42B3, 0x4A13, 0x49F3, 0x5A32, 0x9AB4, 0xD334, 0xD335, 0xD314, 0xD314, 0xD315, 0xD314, 0xD2F4, 0x84D8, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x4DDB, 0xD274, 0xCA74, 0xCA73, 0xD274, 0xCA54, 0xCA54, 0x369C, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07FE, 0x07DD, 0x07DE, 0x079D, 0x6D99, 0xD395, 0xD395, 0xAB17, 0x097F, 0x011F, 0x011F, 0x00FF, 0x00BF, 0x00BF, 0x009F, 0x007F, 0x007F, 0x003F, 0x003F, 0x003F, 0xC8F1, 0xC8F1, 0xC8D1, 0x5119, 0x02DF, 0x04FF, 0x06BF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x1F1E, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x4910, 0x30F0, 0x30F0, 0x28EF, 0x28EF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x10D2, 0x08F3, 0x08F3, 0x10D2, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F8, 0x10D0, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F7, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x00F7, 0x18AE, 0x20AE, 0x18AD, 0x18AD, 0x18AE, 0x10CF, 0x00F9, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AE, 0x10D2, 0x08F3, 0x08F3, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x3910, 0x3911, 0x4112, 0x4132, 0x4132, 0x4933, 0x5133, 0x8214, 0xCB55, 0xD375, 0xD375, 0xB3D5, 0x3D55, 0x3515, 0x3495, 0x3C14, 0x3B94, 0x3B13, 0x4293, 0x4212, 0x49F3, 0x49F3, 0x5A13, 0x9AB4, 0xD314, 0xD315, 0xCB15, 0xD2F4, 0xD2F5, 0xD2F4, 0x7539, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x8C37, 0xCA74, 0xD273, 0xD253, 0xCA54, 0xCA53, 0xD253, 0x1F5E, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07DF, 0x07DF, 0x94D8, 0xD396, 0xD395, 0x8299, 0x00FF, 0x00FF, 0x00FF, 0x00BF, 0x00BF, 0x009F, 0x007F, 0x005F, 0x005F, 0x003F, 0x001F, 0xC8D1, 0xC0F1, 0xC0D1, 0xA0D4, 0x027F, 0x04BF, 0x069F, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x8315, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x70F1, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F7, 0x011A, 0x0118, 0x10D0, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AE, 0x00F7, 0x011A, 0x0119, 0x0119, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x011A, 0x0119, 0x0117, 0x18AE, 0x20CD, 0x18AD, 0x18AE, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CE, 0x28CF, 0x28CF, 0x28CF, 0x28F0, 0x30F0, 0x30F0, 0x30F0, 0x3911, 0x3911, 0x4132, 0x4132, 0x4132, 0x5973, 0xB2F4, 0xD375, 0xD375, 0xD375, 0x9435, 0x3D55, 0x2D55, 0x2D75, 0x3515, 0x3C94, 0x3414, 0x3B94, 0x4313, 0x4293, 0x4A13, 0x41F3, 0x49F2, 0x4A13, 0x5A33, 0xA2B4, 0xD314, 0xD2F4, 0xD2F4, 0xD2D4, 0xD2F4, 0x4E1B, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x179F, 0xD274, 0xCA53, 0xCA73, 0xCA53, 0xCA53, 0xCA53, 0xD253, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x0F9E, 0xBC16, 0xD395, 0xD395, 0x725A, 0x00BF, 0x00BF, 0x00BF, 0x009F, 0x007F, 0x007F, 0x005F, 0x005F, 0x003F, 0x001F, 0x90B5, 0xC8D1, 0xC8D1, 0xC0D1, 0x123E, 0x047F, 0x067F, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x54D9, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0x90D1, 0x38F1, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CE, 0x00F7, 0x011A, 0x00F8, 0x10D0, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x20AE, 0x18AD, 0x18AE, 0x18AD, 0x18D0, 0x00F9, 0x00F9, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28F0, 0x30F0, 0x38F0, 0x30F0, 0x3911, 0x3911, 0x4112, 0x4132, 0x8234, 0xCB55, 0xD375, 0xD375, 0xD355, 0x9435, 0x3575, 0x3575, 0x2D75, 0x3555, 0x3555, 0x3514, 0x3474, 0x3BF4, 0x3B73, 0x42F4, 0x4273, 0x4A13, 0x4213, 0x49F2, 0x49F3, 0x49F3, 0x6A33, 0xBAD4, 0xD2F5, 0xD2F4, 0xD2D4, 0xC335, 0x177E, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x5D9A, 0xCA54, 0xD273, 0xCA54, 0xCA53, 0xCA53, 0xCA53, 0x9BB6, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07BF, 0x07BF, 0x07BF, 0x079F, 0x077F, 0x077F, 0x077E, 0x07BF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07BF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x36DD, 0xD395, 0xD395, 0xD395, 0x51BC, 0x009F, 0x009F, 0x007F, 0x007F, 0x007F, 0x005F, 0x005F, 0x003F, 0x001F, 0x7077, 0xC0D2, 0xC8D1, 0xC0D1, 0x49FA, 0x049F, 0x069F, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x1F1E, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0x3910, 0x30F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18CE, 0x08F7, 0x0119, 0x00F8, 0x18B0, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x0119, 0x0119, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x4952, 0xAAB4, 0xD375, 0xD375, 0xD375, 0xD355, 0x9435, 0x3575, 0x3575, 0x2D75, 0x2D75, 0x2D75, 0x3555, 0x54D5, 0x6475, 0x83B5, 0x8B74, 0x9B34, 0xAB14, 0xAAD4, 0xB2D4, 0xAAD4, 0xAAB4, 0xAAB4, 0xB2B4, 0x6B15, 0x8A94, 0xC2D4, 0xD2F4, 0xD2D4, 0x84B8, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xB315, 0xD274, 0xCA53, 0xCA54, 0xCA53, 0xCA53, 0xD253, 0x653A, 0x07FF, 0x07FF, 0x07DF, 0x07DF, 0x07FF, 0x07DF, 0x07DF, 0x07BF, 0x07BF, 0x079F, 0x079F, 0x077F, 0x075F, 0x075F, 0x073F, 0x073F, 0x071F, 0x071E, 0x071E, 0x073E, 0x079F, 0x07DF, 0x07FF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x7D7A, 0xD395, 0xD395, 0xC375, 0x28FE, 0x007F, 0x007F, 0x005F, 0x005F, 0x003F, 0x005F, 0x003F, 0x003F, 0x183E, 0xC0D1, 0xC0D1, 0xC0D2, 0x7996, 0x04BF, 0x067F, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xA214, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0x58F1, 0x30F0, 0x30F0, 0x30F0, 0x28CF, 0x28EF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x18AD, 0x18AE, 0x18AE, 0x00F7, 0x011A, 0x00F8, 0x18D0, 0x18AD, 0x18AD, 0x20CD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x20AD, 0x18CD, 0x20AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18D0, 0x00F9, 0x0119, 0x0117, 0x18CE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x5972, 0xCB55, 0xD375, 0xD375, 0xD375, 0xD375, 0xABD5, 0x4515, 0x54F5, 0x7C75, 0x8C35, 0xABD5, 0xCB55, 0xD335, 0xD335, 0xD334, 0xD335, 0xD335, 0xD315, 0xD314, 0xD314, 0xC355, 0x9C37, 0x659A, 0x467C, 0x0FBF, 0x07FF, 0x07FF, 0x269D, 0x9C17, 0xD2D4, 0x9C17, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x5D9A, 0xD274, 0xCA53, 0xCA54, 0xCA53, 0xCA33, 0xCA33, 0xCA33, 0x26DD, 0x07FF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07BF, 0x079F, 0x079F, 0x077F, 0x077F, 0x075F, 0x073F, 0x071E, 0x071E, 0x06FE, 0x06FE, 0x06FF, 0x06DE, 0x06DE, 0x06BE, 0x06BE, 0x06DE, 0x073E, 0x079F, 0x07BF, 0x07BF, 0x079F, 0x079F, 0x079F, 0x077F, 0x079F, 0x079F, 0x077F, 0x079F, 0x079F, 0x079F, 0x079F, 0x07BF, 0x07BF, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x0FBF, 0xC3F6, 0xD395, 0xD395, 0xAAF7, 0x003F, 0x003F, 0x003F, 0x003F, 0x003F, 0x003F, 0x003F, 0x001F, 0x001F, 0xA094, 0xC0D1, 0xC8B1, 0xA8F3, 0x04BF, 0x069F, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x73D8, 0xB8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0x78F1, 0x3911, 0x30F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x011A, 0x011A, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18CD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0118, 0x18D0, 0x18AD, 0x18AD, 0x18AD, 0x188D, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18CD, 0x10CF, 0x0119, 0x00F9, 0x0117, 0x18CE, 0x188D, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x3111, 0x71F2, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD375, 0xD355, 0xD355, 0xD335, 0xD335, 0xD355, 0xD335, 0xD335, 0xCB14, 0xD334, 0xD334, 0xAC16, 0x753A, 0x467D, 0x1F5E, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x369C, 0x4E1B, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x26FD, 0xC2B4, 0xCA53, 0xCA53, 0xCA53, 0xD253, 0xCA33, 0xCA33, 0xA356, 0x07FF, 0x07FF, 0x07DF, 0x07BF, 0x07BF, 0x079F, 0x077F, 0x077F, 0x075F, 0x073F, 0x071F, 0x071F, 0x06FF, 0x06FE, 0x06FE, 0x06DE, 0x06BE, 0x06BE, 0x069E, 0x069E, 0x069E, 0x067E, 0x067E, 0x065E, 0x065E, 0x06BE, 0x073E, 0x075F, 0x075F, 0x075F, 0x075F, 0x075F, 0x075F, 0x075F, 0x075F, 0x077F, 0x077F, 0x077F, 0x077F, 0x079F, 0x07BF, 0x07BF, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0x07DF, 0x6DDA, 0xD395, 0xD376, 0xD375, 0x79FA, 0x003F, 0x003F, 0x001F, 0x003F, 0x001F, 0x001F, 0x001F, 0x001F, 0x8896, 0xC0B1, 0xC0B1, 0xC8B1, 0x0C9F, 0x069F, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x3DBB, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xB8D1, 0xC0B1, 0xC0B1, 0x98D1, 0x3911, 0x30F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20AD, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x011A, 0x0119, 0x18B0, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x00F9, 0x0119, 0x00F7, 0x18CE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x9A93, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD355, 0xD355, 0xD335, 0xD335, 0xC375, 0x84F9, 0x4E3C, 0x0FBF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x0F9F, 0xAB75, 0xCA54, 0xD253, 0xCA53, 0xCA33, 0xCA33, 0xD233, 0xCA33, 0x4DBB, 0x07DF, 0x07BF, 0x07BF, 0x079F, 0x077F, 0x075F, 0x075F, 0x073F, 0x071F, 0x071F, 0x06FF, 0x06DE, 0x06DE, 0x06DE, 0x06BE, 0x06BE, 0x069E, 0x067E, 0x067E, 0x067E, 0x065E, 0x063E, 0x063E, 0x061E, 0x061E, 0x05FE, 0x05FD, 0x067D, 0x06DE, 0x06FE, 0x06FE, 0x06FE, 0x06FE, 0x071E, 0x073F, 0x073F, 0x073F, 0x073E, 0x075F, 0x077F, 0x079F, 0x079F, 0x07BF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x0FBF, 0xC3D6, 0xD375, 0xD375, 0xD355, 0x30FD, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x001F, 0x001F, 0x6058, 0xC0B1, 0xC0B1, 0xC0B1, 0x33FC, 0x06BF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x0F9E, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xB8B1, 0xC0B1, 0xB8D1, 0xB8D1, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AD, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0118, 0x18D0, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18B0, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x30F0, 0x3910, 0xAAF4, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xB3D6, 0x7539, 0x271D, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x2EFD, 0xB315, 0xCA53, 0xCA54, 0xCA33, 0xCA53, 0xCA34, 0xCA34, 0xCA33, 0xA335, 0x07BF, 0x07BF, 0x079F, 0x077F, 0x075F, 0x073F, 0x073F, 0x071F, 0x06FF, 0x06FF, 0x06DF, 0x06DE, 0x06BF, 0x06BE, 0x069E, 0x069E, 0x069E, 0x067E, 0x065E, 0x065E, 0x063E, 0x061E, 0x061E, 0x05FE, 0x05DE, 0x05BD, 0x05BE, 0x059D, 0x055E, 0x055E, 0x05BE, 0x05FE, 0x061D, 0x067E, 0x06BE, 0x06FE, 0x06FE, 0x071F, 0x071E, 0x073F, 0x073F, 0x075F, 0x077F, 0x079F, 0x07BF, 0x07BF, 0x07DF, 0x07FF, 0x07FF, 0x8539, 0xD375, 0xD355, 0xD355, 0xBAF6, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x403B, 0xC8B1, 0xC0B1, 0xC0B1, 0x6318, 0x06BF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xA9B3, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xB8D1, 0x4910, 0x3910, 0x30F0, 0x30F0, 0x28CF, 0x28EF, 0x28CF, 0x20CF, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x20AE, 0x18AD, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x10D3, 0x10D3, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x0117, 0x011A, 0x0119, 0x18AF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AE, 0x18CF, 0x00F8, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x20CF, 0x28CF, 0x28CF, 0x28EF, 0x30CF, 0x3910, 0xB314, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD354, 0xD355, 0xD355, 0xCB96, 0x8518, 0x36DD, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x0FBE, 0x653A, 0xCA54, 0xCA53, 0xD253, 0xCA53, 0xCA53, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0x2E9D, 0x077F, 0x077F, 0x075F, 0x073F, 0x073F, 0x071F, 0x06FF, 0x06FE, 0x06DF, 0x06DE, 0x06BF, 0x06BE, 0x06BF, 0x069E, 0x067E, 0x067E, 0x065E, 0x065E, 0x063E, 0x061E, 0x061E, 0x05FE, 0x05DE, 0x05BE, 0x05BE, 0x059E, 0x057E, 0x053E, 0x051E, 0x04FE, 0x04BE, 0x049E, 0x041E, 0x03DD, 0x04DE, 0x065E, 0x06BE, 0x06DE, 0x06DE, 0x06FE, 0x071F, 0x073E, 0x077F, 0x079F, 0x079F, 0x07BF, 0x07DF, 0x07DF, 0x07FF, 0x36DD, 0xD355, 0xD355, 0xD355, 0xD335, 0x699A, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0xB8B2, 0xC091, 0xC0B1, 0x7A96, 0x06BF, 0x079F, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x82F5, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB8D1, 0x60F1, 0x3911, 0x30F0, 0x30F0, 0x28EF, 0x28EF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F7, 0x0119, 0x08F7, 0x18CE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x10D0, 0x0118, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x20AD, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CE, 0x20CF, 0x28CF, 0x28EF, 0x3910, 0xB314, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xBBD6, 0x5DFB, 0x0FBF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x0FBF, 0x5D9A, 0xB315, 0xD254, 0xCA53, 0xD254, 0xCA53, 0xCA53, 0xCA33, 0xD233, 0xCA33, 0xCA33, 0x64D9, 0x077F, 0x073F, 0x073F, 0x071F, 0x06FF, 0x06FF, 0x06DF, 0x06DF, 0x06DF, 0x06BF, 0x06BE, 0x069F, 0x069F, 0x067E, 0x065E, 0x065E, 0x063E, 0x063E, 0x061E, 0x05FE, 0x05FE, 0x05DE, 0x05BE, 0x059E, 0x059E, 0x055E, 0x055E, 0x051E, 0x04FE, 0x04DE, 0x049E, 0x043D, 0x03DE, 0x03BE, 0x039E, 0x037E, 0x03FE, 0x05FE, 0x069E, 0x069E, 0x06BE, 0x06FE, 0x071E, 0x073F, 0x075F, 0x079F, 0x079F, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0xBBF6, 0xD355, 0xD335, 0xD335, 0xC2F5, 0x083F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x9095, 0xC8B1, 0xC8B1, 0x91F5, 0x067F, 0x06FF, 0x073F, 0x075F, 0x077F, 0x07BF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x54D9, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xB8D1, 0xC0D1, 0xB8D1, 0xB8D1, 0x80F2, 0x3911, 0x30F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x20CD, 0x20AE, 0x18AD, 0x18AE, 0x20AE, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CE, 0x08F7, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F6, 0x18CE, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CE, 0x28CF, 0x28CF, 0x3110, 0xB314, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0x9C77, 0x563B, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x1F7E, 0x65DB, 0x7CF9, 0x9C57, 0x9C57, 0x9C57, 0x9C57, 0x9C37, 0x9C37, 0x9C37, 0x9C37, 0x7539, 0x6D7A, 0x6579, 0x5DBB, 0x36BD, 0x36BD, 0x36BC, 0x2EFD, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x0FBF, 0x36BD, 0x5D9A, 0x8C37, 0xD274, 0xD273, 0xD254, 0xCA53, 0xD254, 0xD253, 0xCA33, 0xD233, 0xCA34, 0xCA13, 0xCA33, 0x8418, 0x075F, 0x073F, 0x071F, 0x06FF, 0x06FF, 0x06DF, 0x06DF, 0x06DF, 0x06BF, 0x06BF, 0x069E, 0x069F, 0x067E, 0x067E, 0x065E, 0x065E, 0x063E, 0x061E, 0x061E, 0x05FE, 0x05DE, 0x05DE, 0x05BE, 0x05BE, 0x057E, 0x055E, 0x051E, 0x051E, 0x04FE, 0x04BE, 0x045E, 0x03FE, 0x03BE, 0x039E, 0x037E, 0x037E, 0x035E, 0x033E, 0x035E, 0x061D, 0x067E, 0x067E, 0x069E, 0x06BE, 0x06FE, 0x073F, 0x075F, 0x077F, 0x079F, 0x07DF, 0x07DF, 0x07FF, 0x7D59, 0xD335, 0xD335, 0xD335, 0xD314, 0x699A, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x007F, 0x60D8, 0xC0B1, 0xC0B1, 0xB8F2, 0x05DF, 0x061F, 0x065F, 0x06DF, 0x073F, 0x077F, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x363C, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xB8D1, 0xC0D1, 0xB8D1, 0xB8D1, 0x90D1, 0x3911, 0x30F0, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x18AE, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x00F9, 0x0119, 0x0119, 0x011A, 0x08D5, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x20AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CE, 0x28CE, 0x30EF, 0xB314, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD375, 0xD355, 0x9C77, 0x3EDD, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x659A, 0xD315, 0xD314, 0xD315, 0xD314, 0xD314, 0xD314, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2D4, 0xD2D4, 0xD2F4, 0xCAD4, 0xD2D4, 0xD2B4, 0xD2B4, 0xD2B4, 0xCAB4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD294, 0xD294, 0xCA94, 0xCA94, 0xCA94, 0xCA94, 0xCA74, 0xCA74, 0xCA73, 0xCA73, 0xD274, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA33, 0xCA33, 0xCA33, 0xAB15, 0x0EDF, 0x06FF, 0x06FF, 0x06DF, 0x06DF, 0x06BF, 0x06BF, 0x06DF, 0x06BF, 0x069F, 0x069F, 0x067E, 0x067F, 0x067E, 0x065E, 0x063F, 0x061E, 0x061E, 0x05FE, 0x05FE, 0x05DE, 0x05BE, 0x059E, 0x059E, 0x055E, 0x053E, 0x051E, 0x04FE, 0x04DE, 0x049E, 0x043E, 0x03BE, 0x039E, 0x039E, 0x035E, 0x035E, 0x033E, 0x033E, 0x031E, 0x02FE, 0x037E, 0x05FE, 0x065E, 0x067E, 0x069E, 0x06DE, 0x06FE, 0x075F, 0x077F, 0x079F, 0x07BF, 0x07DF, 0x07FF, 0x271D, 0xD335, 0xD314, 0xD315, 0xD315, 0xC2D5, 0x083F, 0x001F, 0x001F, 0x001F, 0x001F, 0x009F, 0x60D8, 0xC0B1, 0xC0B2, 0xC0B1, 0x04BF, 0x053F, 0x05BF, 0x067F, 0x06DF, 0x075F, 0x079F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xC0B1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xC0B1, 0xB8D1, 0x98D1, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18CE, 0x20AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AE, 0x18AD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CE, 0x20CE, 0x30EF, 0xB314, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD375, 0xAC37, 0x36DD, 0x07FF, 0x07FF, 0x07FF, 0x0EBD, 0x1D7B, 0x1C99, 0x32F5, 0x3A75, 0x6193, 0x69B3, 0x79F4, 0x8A14, 0xB294, 0xCAF4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2B4, 0xD2B4, 0xCAD4, 0xD2B4, 0xCAB4, 0xD2B4, 0xD2B4, 0xD294, 0xD294, 0xD294, 0xD294, 0xCA94, 0xCA94, 0xCA74, 0xCA74, 0xD274, 0xD274, 0xCA53, 0xCA54, 0xCA54, 0xCA53, 0xD253, 0xCA53, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0x8B97, 0x35FD, 0x5D7B, 0x6D3A, 0x6D3A, 0x5D5B, 0x35FD, 0x06BF, 0x0E7E, 0x457C, 0x6C99, 0x6479, 0x6459, 0x4CBA, 0x0E1E, 0x063E, 0x063E, 0x061E, 0x05FE, 0x05FE, 0x05FE, 0x05DE, 0x05BE, 0x059E, 0x057E, 0x055E, 0x051E, 0x051E, 0x04FE, 0x04DE, 0x047E, 0x03DE, 0x03BE, 0x037E, 0x037F, 0x035E, 0x033E, 0x033E, 0x031E, 0x02FE, 0x02FE, 0x02FE, 0x02DE, 0x03FE, 0x05BE, 0x063E, 0x065E, 0x069E, 0x06DE, 0x071F, 0x073E, 0x077F, 0x079F, 0x07BF, 0x07DF, 0x07FF, 0xBBB6, 0xD314, 0xD315, 0xD2F4, 0xD2F4, 0x697A, 0x001F, 0x001F, 0x001F, 0x003F, 0x007F, 0x48FA, 0xC0B1, 0xC0B1, 0xC0B1, 0x331C, 0x047F, 0x053F, 0x05FF, 0x069F, 0x073F, 0x079F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x9A14, 0xB8D1, 0xB8D1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CF, 0x20AE, 0x18CF, 0x08F6, 0x011A, 0x0119, 0x0119, 0x08F4, 0x18CE, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x20AD, 0x20AE, 0x18AD, 0x20AE, 0x20AE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x9273, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xC3B6, 0x5DFB, 0x07FF, 0x0E3B, 0x1C98, 0x2AD5, 0x3911, 0x3911, 0x3912, 0x4111, 0x4112, 0x4112, 0x4112, 0x4132, 0x4132, 0x4132, 0x4132, 0x4933, 0x5173, 0x79D3, 0x9A54, 0xC294, 0xD2F4, 0xD2D5, 0xCAD4, 0xD2D4, 0xD2B4, 0xCAD4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD294, 0xD294, 0xD294, 0xD294, 0xCA94, 0xCA94, 0xCA74, 0xCA74, 0xCA74, 0xCA73, 0xD253, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0x99D4, 0x6358, 0xD395, 0xD396, 0xD395, 0xD395, 0xD375, 0xD375, 0x06BF, 0x5CFA, 0xD2B4, 0xCA94, 0xCA33, 0xCA13, 0xC9D3, 0xB9D3, 0x4C5A, 0x061E, 0x061E, 0x05DE, 0x05DE, 0x05BE, 0x059E, 0x059E, 0x057E, 0x053E, 0x051E, 0x051D, 0x04DE, 0x04BE, 0x043E, 0x03BE, 0x03BE, 0x037F, 0x0B7E, 0x337C, 0x333C, 0x335C, 0x333C, 0x333C, 0x331C, 0x331C, 0x32FC, 0x32FC, 0x32DC, 0x2B7C, 0x05DE, 0x061E, 0x065E, 0x069E, 0x06DE, 0x071F, 0x073F, 0x077F, 0x07BF, 0x07DF, 0x07DF, 0x84F9, 0xD314, 0xCB14, 0xCAF4, 0xD2D5, 0xB275, 0x001F, 0x001F, 0x001F, 0x001F, 0x005F, 0x08DF, 0xB8D2, 0xC0B1, 0xC0B1, 0x3A7B, 0x03FF, 0x04DF, 0x05BF, 0x067F, 0x071F, 0x079F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x7B77, 0xB8D1, 0xB8B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x4111, 0x38F1, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CF, 0x20CF, 0x20AE, 0x20CF, 0x0918, 0x013A, 0x011A, 0x0119, 0x011A, 0x0119, 0x08F6, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x0139, 0x00F9, 0x10D2, 0x20AE, 0x18AD, 0x20AE, 0x20AE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x7A32, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0x9C78, 0x261B, 0x1B96, 0x3171, 0x30F0, 0x38F1, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x4111, 0x3912, 0x4112, 0x4112, 0x4112, 0x4132, 0x4112, 0x4132, 0x4132, 0x4912, 0x4132, 0x6172, 0x81F3, 0xAA73, 0xCAD4, 0xD2B4, 0xCAB4, 0xD2B4, 0xD2B4, 0xCAB4, 0xCAB4, 0xCA94, 0xCA94, 0xD294, 0xCA94, 0xCA94, 0xCA74, 0xCA74, 0xCA74, 0xD274, 0xCA54, 0xD274, 0xCA53, 0xCA53, 0xCA53, 0xD233, 0xCA33, 0xCA33, 0xD233, 0xC234, 0x7994, 0x5975, 0xB315, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xC375, 0x067F, 0x067F, 0x6C79, 0xCA33, 0xCA13, 0xC9D3, 0xC992, 0xC952, 0xC912, 0x34BB, 0x05FE, 0x05DE, 0x05BE, 0x059E, 0x055E, 0x055E, 0x053E, 0x051E, 0x04FE, 0x249D, 0x347B, 0x6BFA, 0x7B99, 0x9B98, 0xAB97, 0xDB95, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD396, 0xD395, 0xBBD6, 0x9C37, 0x8499, 0x6D1A, 0x363C, 0x1EDD, 0x079F, 0x07BF, 0x07DF, 0x4E1B, 0xD2F4, 0xD2F5, 0xD2D4, 0xD2D4, 0xD2D4, 0x40FC, 0x001F, 0x001F, 0x001F, 0x003F, 0x009F, 0x78D7, 0xC0B1, 0xC0B1, 0x61D8, 0x03BF, 0x049F, 0x057F, 0x065F, 0x071F, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x54D9, 0xB8D1, 0xB8B1, 0xB8D1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x4111, 0x3911, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CF, 0x20AE, 0x10F3, 0x013A, 0x0119, 0x0139, 0x0119, 0x0119, 0x0119, 0x011A, 0x18D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x18AD, 0x20AE, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x5170, 0xD395, 0xD375, 0xD375, 0xD375, 0xD355, 0x6519, 0x22B3, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x4112, 0x4112, 0x4112, 0x4112, 0x4132, 0x4112, 0x4132, 0x4112, 0x4952, 0x79B3, 0xA233, 0xD2B4, 0xCAB4, 0xD294, 0xCA94, 0xD294, 0xCA94, 0xCA74, 0xCA94, 0xCA74, 0xCA74, 0xD274, 0xCA54, 0xD274, 0xD253, 0xCA54, 0xCA54, 0xCA33, 0xD233, 0xCA34, 0xCA33, 0xCA33, 0xA1D3, 0x5954, 0x5954, 0x79F5, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD335, 0x8C18, 0x067F, 0x065F, 0x063F, 0xA2D5, 0xC9D3, 0xC972, 0xC952, 0xC111, 0xC8D1, 0x8A55, 0x05DE, 0x05BE, 0x059E, 0x057E, 0x055E, 0x34DC, 0x6C5A, 0xA3F7, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xBBB6, 0x84D9, 0x4E1B, 0x465C, 0xD2F5, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2B4, 0x81D8, 0x001F, 0x001F, 0x001F, 0x001F, 0x005F, 0x6098, 0xC0B1, 0xC0D1, 0x59B8, 0x035F, 0x045F, 0x055F, 0x063F, 0x06FF, 0x079F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x363C, 0xC0D1, 0xB8D1, 0xB8B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x58F1, 0x3911, 0x30F0, 0x3110, 0x30CF, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x08F6, 0x013A, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, + 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x011A, 0x011A, 0x0119, 0x0119, 0x011A, 0x00F8, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AE, 0x20CE, 0x20AE, 0x28EE, 0xCB55, 0xD375, 0xD375, 0xD375, 0xBB14, 0x34F9, 0x2930, 0x30EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x4112, 0x4111, 0x3931, 0x4112, 0x4111, 0x6993, 0x91F2, 0xC254, 0xCA93, 0xCA94, 0xCA94, 0xCA74, 0xCA74, 0xD274, 0xCA73, 0xD273, 0xCA73, 0xD254, 0xCA53, 0xCA53, 0xCA54, 0xCA33, 0xCA34, 0xA1F3, 0x6973, 0x4953, 0x5134, 0x5154, 0xAAF5, 0xD395, 0xD395, 0xD395, 0xD375, 0xD335, 0xD314, 0x5CDA, 0x065F, 0x063F, 0x063F, 0xB254, 0xC972, 0xC952, 0xC112, 0xC8D1, 0xC0B1, 0xC0B1, 0x05BE, 0x059E, 0x2D1C, 0x9438, 0xCBB6, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD375, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD314, 0xD314, 0xD315, 0xD2F4, 0xD2F5, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2B4, 0xD2B4, 0xCA94, 0x087F, 0x003F, 0x001F, 0x001F, 0x001F, 0x385B, 0xC0B1, 0xC0B1, 0x9135, 0x031F, 0x043F, 0x053F, 0x063F, 0x071F, 0x079F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8B1, 0xB8D1, 0xC0D1, 0xB8B1, 0xB8D1, 0x5911, 0x3911, 0x38F0, 0x30F0, 0x30CF, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x0917, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, + 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0118, 0x011A, 0x00F9, 0x0119, 0x00F9, 0x10D2, 0x20AD, 0x18CD, 0x20AE, 0x18AD, 0x20AE, 0x20CE, 0x20CE, 0x8252, 0xD375, 0xD375, 0xD375, 0x9A93, 0x30EF, 0x20CF, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x28F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x38F0, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x38F1, 0x3911, 0x3911, 0x3911, 0x3911, 0x4111, 0x6972, 0x81D2, 0xAA13, 0xBA33, 0xCA54, 0xCA74, 0xCA53, 0xCA54, 0xCA53, 0xCA53, 0xB213, 0xA1F3, 0x8193, 0x5152, 0x4932, 0x4933, 0x4933, 0x4933, 0x5174, 0xD395, 0xD395, 0xD396, 0xD375, 0xD334, 0xD2F5, 0xD2B4, 0x2D9D, 0x063F, 0x063F, 0x061F, 0xC993, 0xC952, 0xC911, 0xC8F1, 0xC0B1, 0xC0B1, 0xB8D1, 0x059E, 0x057E, 0xABF7, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD315, 0xD335, 0xCB15, 0xD2F4, 0xD2F5, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2B4, 0xD2B4, 0xD294, 0xD294, 0x411C, 0x003F, 0x003F, 0x001F, 0x001F, 0x203C, 0xC0B1, 0xC0B1, 0x9135, 0x02FF, 0x041F, 0x051F, 0x061F, 0x06FF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xA1B3, 0xB8B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x68F1, 0x3911, 0x38F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x10F3, 0x0119, 0x0119, 0x0119, 0x00FA, 0x0119, 0x0119, 0x0119, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x18AE, 0x18AE, 0x18AD, 0x20AE, 0x18AD, 0x20AE, 0x20CE, 0x412F, 0xD375, 0xD375, 0xD375, 0x71D1, 0x20CE, 0x28CF, 0x20CF, 0x28CE, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x3110, 0x3110, 0x38F0, 0x30F0, 0x3111, 0x3111, 0x38F1, 0x38F1, 0x38F0, 0x3910, 0x3910, 0x3910, 0x3911, 0x3911, 0x3911, 0x3910, 0x6152, 0x6152, 0x5131, 0x3911, 0x3911, 0x3911, 0x3912, 0x4112, 0x4132, 0x4112, 0x4932, 0x4932, 0x8A34, 0xD395, 0xD395, 0xD375, 0xD335, 0xD2F4, 0xCAD4, 0xB2F6, 0x065F, 0x061F, 0x061F, 0x34DC, 0xC952, 0xC912, 0xC8D2, 0xC0B1, 0xC0D1, 0xB8D1, 0x89B4, 0x2BBA, 0x4216, 0x5154, 0x5154, 0x4954, 0x5154, 0x6194, 0x71D4, 0x69F4, 0x71D3, 0x69D4, 0x71D3, 0x7A14, 0x8A75, 0x9274, 0x9254, 0x9254, 0x9A95, 0xB315, 0xBB14, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD314, 0xD315, 0xD2F4, 0xCB14, 0xD2F4, 0xD2F4, 0xD2D4, 0xCAD4, 0xCAB4, 0xD2B4, 0xCAB4, 0xCA94, 0xCA94, 0x81B8, 0x005F, 0x005F, 0x003F, 0x001F, 0x001F, 0xA8B3, 0xC0B1, 0xB0D2, 0x02DF, 0x03FF, 0x051F, 0x061F, 0x06FF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x8A95, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x78F2, 0x3911, 0x38F0, 0x30F0, 0x28F0, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CF, 0x0918, 0x0119, 0x0119, 0x011A, 0x00F9, 0x0119, 0x08F7, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x20AE, 0x20AE, 0x20CD, 0x20AE, 0x20CD, 0x9272, 0xD375, 0xC334, 0x61D1, 0x20CF, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x30EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x30F0, 0x3110, 0x3110, 0x30F0, 0x3110, 0x38F0, 0x30F0, 0x38F0, 0x3111, 0x38F0, 0x3911, 0x38F1, 0x3911, 0x3911, 0x3912, 0x4111, 0x4132, 0x4132, 0xB2F5, 0xD395, 0xD375, 0xD355, 0xD2F4, 0xD2B4, 0xD274, 0x83B8, 0x063F, 0x061F, 0x061E, 0x6398, 0xC912, 0xC8D1, 0xC0B1, 0xC0B1, 0xB8B1, 0xB8D1, 0x7933, 0x5153, 0x5134, 0x5154, 0x5133, 0x4953, 0x4933, 0x4933, 0x4933, 0x4133, 0x4933, 0x4932, 0x4932, 0x4932, 0x4933, 0x4933, 0x4933, 0x4932, 0x4932, 0x4933, 0x4933, 0x4933, 0x61B3, 0x7A34, 0x9A95, 0xB2F5, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD314, 0xD314, 0xD315, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2D4, 0xD2D4, 0xD2B4, 0xD2B4, 0xD294, 0xD294, 0xD274, 0xCA74, 0xC254, 0x007F, 0x005F, 0x005F, 0x003F, 0x001F, 0x5878, 0xB8D1, 0xC0B1, 0x02BF, 0x03BF, 0x04FF, 0x05FF, 0x06FF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x6478, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x78F1, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CF, 0x0917, 0x011A, 0x011A, 0x0119, 0x08F4, 0x18CE, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20CD, 0x18CE, 0x20AE, 0x390F, 0xD375, 0xCB35, 0x414F, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x28EF, 0x30EF, 0x30EF, 0x30EF, 0x30EF, 0x30EF, 0x30EF, 0x30EF, 0x30EF, 0x30F0, 0x28F0, 0x30F0, 0x30F0, 0x30F0, 0x28F0, 0x30F0, 0x30EF, 0x3110, 0x30F0, 0x30D0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F1, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3910, 0x3911, 0x38F1, 0x3911, 0x3912, 0x4952, 0xD395, 0xD375, 0xD335, 0xD2F4, 0xD2B4, 0xD274, 0xCA33, 0x4C9A, 0x05FF, 0x061F, 0x05FF, 0xA1F4, 0xC0D1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB8D1, 0xA0F1, 0x5134, 0x4933, 0x4933, 0x4933, 0x4933, 0x4933, 0x4932, 0x4932, 0x4932, 0x4132, 0x4132, 0x4132, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4132, 0x4132, 0x4132, 0x4132, 0x4132, 0x4133, 0x4933, 0x4932, 0x4953, 0x6193, 0x8214, 0xA274, 0xC315, 0xD335, 0xD314, 0xD315, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2B4, 0xCAB4, 0xCAB4, 0xCA94, 0xCA74, 0xCA74, 0xCA74, 0xCA54, 0x20FD, 0x009F, 0x007F, 0x005F, 0x003F, 0x105D, 0xC0B1, 0xC0D1, 0x029F, 0x03BF, 0x04DF, 0x05FF, 0x06FF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x54D9, 0xB8D1, 0xB8D1, 0xB8B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x78F1, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CE, 0x20CF, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AD, 0x20AE, 0x61D0, 0xBB14, 0x412F, 0x20AE, 0x20AE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x28CE, 0x20CE, 0x20CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x28CF, 0x28F0, 0x30D0, 0x28EF, 0x28CF, 0x30CF, 0x30F0, 0x30D0, 0x30D0, 0x28F0, 0x30F0, 0x30F0, 0x30F0, 0x30D0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x3911, 0x61B2, 0xD375, 0xD335, 0xD2F4, 0xCAD4, 0xCA74, 0xD233, 0xCA13, 0x1D9D, 0x05FF, 0x05FF, 0x1D3D, 0xC0D1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB0D1, 0x6132, 0x4933, 0x4933, 0x4932, 0x4132, 0x4112, 0x4112, 0x4112, 0x4132, 0x4112, 0x4111, 0x4111, 0x4112, 0x4112, 0x4111, 0x3911, 0x3911, 0x4111, 0x4112, 0x4112, 0x3912, 0x4132, 0x4112, 0x4112, 0x4112, 0x4912, 0x4132, 0x4132, 0x4932, 0x4933, 0x4953, 0x4933, 0x6173, 0x8A14, 0xAA74, 0xCAF4, 0xD2F5, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2B4, 0xCAB4, 0xD2B4, 0xD294, 0xCA94, 0xCA73, 0xD274, 0xD253, 0xD254, 0x597A, 0x00BF, 0x00BF, 0x009F, 0x009F, 0x005F, 0xA8B3, 0xC0B1, 0x31FC, 0x039F, 0x04DF, 0x05DF, 0x06DF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x2E3C, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8B1, 0xB8D1, 0xB8D1, 0x78F1, 0x3911, 0x30F0, 0x30F0, 0x28EF, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AD, 0x20AE, 0x18CE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AF, 0x18AF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AF, 0x18AF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AE, 0x390F, 0x28CE, 0x20AE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x28EF, 0x28CF, 0x28EF, 0x28EF, 0x30EF, 0x28EF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x3911, 0x71F2, 0xD335, 0xD2F4, 0xD2B4, 0xCA74, 0xD233, 0xCA13, 0xA295, 0x05FF, 0x05FF, 0x05FF, 0x5399, 0xC0D1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB0D1, 0x7912, 0x4952, 0x4132, 0x4112, 0x4132, 0x4132, 0x4132, 0x4112, 0x3911, 0x3911, 0x3911, 0x3911, 0x38F1, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x4111, 0x4112, 0x4112, 0x4112, 0x4112, 0x4132, 0x4932, 0x4932, 0x4933, 0x4933, 0x5133, 0x6194, 0x9A34, 0xC2B4, 0xD2B5, 0xD2B3, 0xCAB4, 0xD294, 0xD294, 0xCA93, 0xD274, 0xD274, 0xCA53, 0xCA54, 0xCA53, 0x81D8, 0x00DF, 0x00DF, 0x00DF, 0x00BF, 0x00BF, 0x68B7, 0xB8D1, 0x31DC, 0x033F, 0x049F, 0x05DF, 0x06FF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x26BD, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D2, 0xB8D1, 0xB8D1, 0x78F1, 0x3911, 0x38F1, 0x30F0, 0x30EF, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x0118, 0x0119, 0x0119, 0x00F6, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x00F8, 0x0119, 0x011A, 0x00F6, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x20CF, 0x20CF, 0x20CF, 0x20CF, 0x20CF, 0x20CF, 0x20CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28F0, 0x28F0, 0x30F0, 0x30F0, 0x38F0, 0x8213, 0xD2F5, 0xCAD4, 0xD274, 0xCA53, 0xC9F3, 0xC9D2, 0x7398, 0x05FF, 0x05FF, 0x05DF, 0xA953, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x98F2, 0x4132, 0x4132, 0x4112, 0x4111, 0x4111, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x38F0, 0x38F0, 0x38F0, 0x38F0, 0x3911, 0x38F0, 0x38F0, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x4112, 0x4112, 0x4112, 0x4132, 0x4132, 0x4933, 0x4933, 0x4933, 0x5153, 0x5974, 0x9214, 0xCA94, 0xD294, 0xCA94, 0xD274, 0xCA74, 0xD274, 0xCA53, 0xCA54, 0xCA53, 0xCA34, 0x99F6, 0x011F, 0x011F, 0x00FF, 0x00FF, 0x00FF, 0x38DB, 0xC0B1, 0x28FC, 0x02DF, 0x047F, 0x059F, 0x06DF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x78F1, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18CD, 0x18AD, 0x18AE, 0x18B0, 0x0119, 0x00F9, 0x0119, 0x00F9, 0x0119, 0x08F6, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18D0, 0x00F9, 0x0119, 0x0119, 0x011A, 0x0119, 0x08F6, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x310E, 0x7A32, 0xAAD3, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD335, 0xD2B4, 0xCA94, 0xCA33, 0xD1F3, 0xC9D3, 0xC993, 0xC972, 0xC992, 0xC972, 0xC932, 0xC0D1, 0xC0B1, 0xB8D1, 0xB0D2, 0xB9F2, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xCA13, 0x015F, 0x013F, 0x013F, 0x013F, 0x011F, 0x093F, 0xC0B1, 0x311C, 0x01BF, 0x03FF, 0x059F, 0x069F, 0x079F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xB8B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x78F1, 0x3911, 0x3911, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AE, 0x18B0, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x10CF, 0x0118, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x20AD, 0x18AD, 0x496F, 0xAAD3, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD2F4, 0xCA74, 0xCA33, 0xCA13, 0xC9D3, 0xC992, 0xC952, 0xC111, 0xC0D1, 0xC0B1, 0xC0D1, 0xB8B1, 0xB8D1, 0xB8D1, 0xCA53, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xCA13, 0x097F, 0x017F, 0x015F, 0x017F, 0x015F, 0x015F, 0x88F5, 0x293C, 0x013F, 0x02DF, 0x053E, 0x067F, 0x077F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x9234, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x78F1, 0x3911, 0x3911, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AE, 0x10D0, 0x0118, 0x0119, 0x011A, 0x011A, 0x0119, 0x011A, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x00F8, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20EE, 0x8252, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD3B5, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD2B4, 0xD233, 0xCA13, 0xC9B3, 0xC992, 0xC952, 0xC912, 0xC8D1, 0xC0B1, 0xC0B1, 0xB8B1, 0xB8D1, 0xB8D1, 0xC253, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDB95, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xCA13, 0x31BC, 0x01BF, 0x019F, 0x019F, 0x019F, 0x019F, 0x5139, 0x315C, 0x017F, 0x01BF, 0x045E, 0x063E, 0x077F, 0x07FE, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x8A95, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB8D1, 0x78F1, 0x3911, 0x3911, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x10D0, 0x0118, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x10D0, 0x00F9, 0x0119, 0x0119, 0x00FA, 0x0119, 0x0119, 0x011A, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x28EE, 0xB314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD4F8, 0xD65C, 0xD6DD, 0xD6FD, 0xD7FF, 0xD7FF, 0xDFFF, 0xD7FF, 0xD7FF, 0xDFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xDFFF, 0xD7FF, 0xCB15, 0xCA13, 0xC9D3, 0xC992, 0xC932, 0xC911, 0xC0D1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xC397, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xDFFF, 0xD539, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDB95, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xC9F3, 0x31FC, 0x01DF, 0x01DF, 0x01DF, 0x01DF, 0x01DF, 0x01BF, 0x01DF, 0x01BF, 0x01BF, 0x02DF, 0x05FD, 0x073E, 0x07FE, 0x07FE, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x8AB5, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0F1, 0xB8D1, 0x78F1, 0x3911, 0x3911, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x10D0, 0x00F8, 0x0119, 0x011A, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AE, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x28EE, 0xCB55, 0xD375, 0xD395, 0xD395, 0xD3D6, 0xD5DB, 0xD7BF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xDFFF, 0xDFFF, 0xCA13, 0xC9B3, 0xC992, 0xC952, 0xC912, 0xC0D1, 0xC0B1, 0xC0D1, 0xB8B1, 0xB8D1, 0xB0F1, 0xBA95, 0xDFFF, 0xD7FF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xD7FF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xDFFF, 0xD539, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xC9F3, 0x31FD, 0x021F, 0x01FF, 0x01FF, 0x01FF, 0x01FF, 0x01FF, 0x01FF, 0x01FF, 0x01DF, 0x01FF, 0x051D, 0x071D, 0x07FD, 0x07FE, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x6BF7, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0x78F1, 0x3911, 0x3911, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18CF, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x28EE, 0xB314, 0xD395, 0xD395, 0xD395, 0xD477, 0xD77E, 0xD7FF, 0xD7FF, 0xDFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xDFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xC9D3, 0xC992, 0xC952, 0xC912, 0xC8D1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB152, 0xD79E, 0xDFFF, 0xDFFF, 0xDFFF, 0xD7FF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xD7FF, 0xDFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD539, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xC9D3, 0x323C, 0x023F, 0x023F, 0x021F, 0x023F, 0x023F, 0x021F, 0x021F, 0x021F, 0x021F, 0x021F, 0x037E, 0x06DC, 0x07FD, 0x07FD, 0x07FE, 0x07FF, 0x07FF, 0x07FF, 0x5C78, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB8D1, 0xB0F1, 0x7911, 0x3911, 0x3911, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x011A, 0x00F9, 0x0119, 0x0119, 0x0119, 0x011A, 0x0117, 0x18AE, 0x18AD, 0x10D0, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x8252, 0xD395, 0xD395, 0xD396, 0xD4B8, 0xD7BF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xC972, 0xC952, 0xC912, 0xC8D1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0F1, 0xD63C, 0xDFFF, 0xDFFF, 0xD7FF, 0xDFFF, 0xDFFF, 0xD7FF, 0xDFFF, 0xDFFF, 0xD7FF, 0xD7FF, 0xDFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xDFFF, 0xD7FF, 0xDFFF, 0xD539, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xC9D3, 0x325C, 0x027F, 0x025F, 0x025F, 0x025F, 0x023F, 0x025F, 0x025F, 0x023F, 0x023F, 0x023F, 0x029F, 0x067C, 0x07FC, 0x07FC, 0x07FE, 0x07FF, 0x07FF, 0x07FF, 0x5C78, 0xB8D1, 0xB0D1, 0xB8D1, 0xB0D1, 0xB0D1, 0xB8D1, 0x70F1, 0x3911, 0x3911, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x10CF, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x496F, 0xD395, 0xD395, 0xD395, 0xD457, 0xD7BF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7DF, 0xD7FF, 0xCF3E, 0xC67C, 0xC53A, 0xC951, 0xC912, 0xC0D1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB0F1, 0xBB97, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD65B, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD396, 0xD395, 0xC9B3, 0x327C, 0x029F, 0x029F, 0x029F, 0x029F, 0x027F, 0x027F, 0x027F, 0x027F, 0x027F, 0x025F, 0x027F, 0x05BC, 0x07DB, 0x07FC, 0x07FD, 0x07FF, 0x07FF, 0x07FF, 0x5C78, 0xB8D1, 0xB0D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0x58F1, 0x3911, 0x3111, 0x30F0, 0x28F0, 0x28F0, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x011A, 0x0119, 0x0119, 0x011A, 0x0117, 0x18CE, 0x18AE, 0x18D0, 0x0118, 0x00F9, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0xA2D3, 0xD395, 0xD395, 0xD3D6, 0xD75E, 0xCFFF, 0xCFFF, 0xD7FF, 0xD7FF, 0xCFFF, 0xCFFF, 0xD7FF, 0xD7FF, 0xD7DF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7DF, 0xD7FF, 0xD7FF, 0xCFDF, 0xCFFF, 0xD7FF, 0xD7DF, 0xD7FF, 0xCFFF, 0xD7FF, 0xD7DF, 0xD7FF, 0xCFFF, 0xD7DF, 0xCFFF, 0xCFFF, 0xD7FF, 0xD7FF, 0xCFFF, 0xD7FF, 0xCFFF, 0xD7FF, 0xD7DF, 0xD7DF, 0xCFFF, 0xD7DF, 0xCFFF, 0xD7FF, 0xD7FF, 0xCFFF, 0xD7FF, 0xCFFF, 0xD7FF, 0xD7DF, 0xD7FF, 0xD7FF, 0xCFFF, 0xCFFF, 0xD7FF, 0xCFFF, 0xD7DF, 0xCFFF, 0xD7FF, 0xD7DF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xCFFF, 0xD7FF, 0xCFDF, 0xD7DF, 0xCFDF, 0xCFFF, 0xD7DF, 0xACD8, 0x8191, 0x9151, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0xA8F1, 0xA972, 0xD77E, 0xD7FF, 0xD7FF, 0xD7DF, 0xD7DF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7DF, 0xCFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7DF, 0xD7DF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7DF, 0xD7FF, 0xD7DF, 0xD7FF, 0xD7DF, 0xD65C, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xC193, 0x0A7F, 0x02FF, 0x02DF, 0x02BF, 0x02BF, 0x02BF, 0x029F, 0x029F, 0x029F, 0x027F, 0x029F, 0x027F, 0x04DD, 0x07BB, 0x07FB, 0x07FD, 0x07FF, 0x07FF, 0x07FF, 0x3DBB, 0xB8D1, 0xB8D1, 0xB0F1, 0xB0D1, 0xB0D1, 0xB0D1, 0x5911, 0x3911, 0x30F0, 0x30F0, 0x28F0, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x00F9, 0x0119, 0x011A, 0x00F7, 0x18AE, 0x18AD, 0x18AF, 0x0118, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x310E, 0xD395, 0xD375, 0xD375, 0xD5BA, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xC77E, 0xBE5B, 0xBE3C, 0xB57A, 0xACB8, 0xBDBB, 0xC63C, 0xBE3B, 0xC71E, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xC77E, 0xBE5C, 0xB5DB, 0xACB8, 0xAC98, 0xBD5A, 0xBE3C, 0xC61C, 0xC69D, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xACB9, 0x8191, 0x9151, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0xA111, 0xA911, 0xBC78, 0xCFDF, 0xCFDF, 0xCFDF, 0xD7DF, 0xCFDF, 0xCF5E, 0xBE5C, 0xBE5C, 0xC63C, 0xC61C, 0xCEFD, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFFF, 0xCFDF, 0xD63B, 0xD375, 0xD395, 0xD375, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD395, 0xD375, 0xD375, 0xD375, 0xD395, 0x089F, 0x011F, 0x031F, 0x02FF, 0x02FF, 0x02DF, 0x02DF, 0x02DF, 0x02BF, 0x02BF, 0x02BF, 0x02BF, 0x02BF, 0x03FD, 0x079A, 0x07FA, 0x07FC, 0x07FE, 0x07FF, 0x07FF, 0x2E5C, 0xB0D1, 0xB8D1, 0xB8D1, 0xB0F1, 0xB0D1, 0xB8D1, 0x5912, 0x3911, 0x38F1, 0x30F0, 0x28F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x0119, 0x0119, 0x0117, 0x18CE, 0x18AD, 0x18AD, 0x0118, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x79F1, 0xD355, 0xD355, 0xD355, 0xCF7E, 0xC7DF, 0xCFBF, 0xCFDF, 0xC7DF, 0xC7DF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFBF, 0xCFDF, 0xCFDF, 0xCFBF, 0xBEFD, 0xACB8, 0x8A52, 0x9151, 0x9131, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0xA192, 0xAB96, 0xBE7D, 0xCFDF, 0xC7DF, 0xCFBF, 0xC7DF, 0xCFDF, 0xCFBF, 0xC75E, 0xAD19, 0x92B4, 0x8971, 0x9151, 0x9931, 0x9931, 0x9911, 0x9911, 0xA111, 0x9931, 0xA111, 0x9911, 0xAB36, 0xBD5A, 0xC75E, 0xCFDF, 0xC7BF, 0xC7BF, 0xCFDF, 0xC7DF, 0xC7BF, 0xC7DF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xC7DF, 0xCFBF, 0xC7DF, 0xC7BF, 0xCFBF, 0xC7DF, 0xA4B8, 0x8191, 0x9151, 0x9931, 0x9911, 0x9931, 0x9931, 0x9911, 0x9931, 0x9912, 0xBE3B, 0xCFBF, 0xCFDF, 0xCFBF, 0xCFDF, 0xCFDF, 0xB5DA, 0x8A12, 0x8971, 0x9931, 0x9931, 0xA111, 0x9931, 0xAB35, 0xC75E, 0xCFBF, 0xCFDF, 0xC7DF, 0xC7DF, 0xCFDF, 0xCFDF, 0xCFBF, 0xC7DF, 0xC7DF, 0xCFDF, 0xCFDF, 0xCFDF, 0xC7DF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCE1B, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0x007F, 0x009E, 0x023F, 0x033F, 0x031F, 0x031F, 0x031F, 0x02FF, 0x031F, 0x02FF, 0x02DF, 0x02DF, 0x02DF, 0x039E, 0x075A, 0x07F9, 0x07FB, 0x07FD, 0x07FF, 0x07FF, 0x2E3C, 0xB8D2, 0xB8D1, 0xB0D1, 0xB8D1, 0xB0D1, 0xB0D1, 0x4911, 0x3911, 0x38F0, 0x30F0, 0x28F0, 0x28EF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0xA293, 0xD335, 0xD335, 0xCC98, 0xC7BF, 0xC7BE, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC75E, 0xA4B8, 0x8191, 0x9151, 0x9911, 0xA131, 0xA111, 0xA111, 0x9931, 0xA111, 0xA112, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xAB35, 0xBEFE, 0xC7BF, 0xC7BE, 0xC7BF, 0xB5DB, 0x89F1, 0x8971, 0x9931, 0x9911, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA132, 0x9911, 0xA111, 0xA111, 0xA111, 0xA111, 0xA172, 0xBD3A, 0xC7BE, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BE, 0xC79F, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC79F, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xAC98, 0x8191, 0x9151, 0x9931, 0xA111, 0xA131, 0xA111, 0xA131, 0xA111, 0x9931, 0xBE1B, 0xC79F, 0xC7BF, 0xC7BF, 0xC7BF, 0xBEFD, 0x89F2, 0x8991, 0x9931, 0xA112, 0xA131, 0xA111, 0xA111, 0xA111, 0xAB97, 0xC7BF, 0xC7BF, 0xC7BE, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC6DD, 0xD375, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD334, 0xD335, 0xD335, 0x009F, 0x009F, 0x013F, 0x033F, 0x037F, 0x035F, 0x033F, 0x031F, 0x031F, 0x031F, 0x031F, 0x02FF, 0x02FF, 0x033F, 0x06F9, 0x07F9, 0x07FB, 0x07FD, 0x07FF, 0x07FF, 0x2E3C, 0xB8D2, 0xB0F1, 0xB8D1, 0xB0D1, 0xB0F1, 0xB0D1, 0x3911, 0x3911, 0x38F0, 0x30F0, 0x3110, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00F9, 0x0119, 0x0119, 0x0139, 0x0119, 0x011A, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0xD315, 0xD315, 0xD314, 0xC5FB, 0xC79F, 0xC79E, 0xC7BF, 0xC7BF, 0xC79E, 0xC79E, 0xC7BF, 0xC79F, 0xBF9E, 0xBFBF, 0xBFBE, 0xB67C, 0x8A53, 0x8971, 0xA131, 0xA112, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA112, 0xA111, 0xA111, 0xA172, 0xB539, 0xBF9F, 0x9BF6, 0x8191, 0x9151, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA112, 0xA111, 0xA111, 0xAB15, 0xBF3D, 0xC79F, 0xC7BE, 0xC79F, 0xC79F, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79F, 0xC79E, 0xC79F, 0xC79E, 0xC79E, 0xC7BF, 0xC79F, 0xA4B8, 0x8191, 0x9151, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA112, 0xA111, 0xBDFB, 0xC79F, 0xC79E, 0xC7BE, 0xC79F, 0xACF9, 0x8191, 0x9171, 0xA111, 0xA111, 0xA111, 0xA112, 0xA111, 0xA131, 0xA111, 0xBF3E, 0xBFBF, 0xC79E, 0xC79E, 0xC79E, 0xC7BF, 0xC79E, 0xC79E, 0xC79E, 0xBFBF, 0xC79E, 0xC79E, 0xC79E, 0xBF9E, 0xC79F, 0xC79E, 0xBFBE, 0xC79E, 0xC6BD, 0xD355, 0xD2F5, 0xD315, 0xCB14, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD315, 0xD315, 0xD315, 0xD314, 0x007F, 0x007F, 0x00FF, 0x027F, 0x039F, 0x039F, 0x037F, 0x231D, 0x5259, 0x5A3A, 0x033F, 0x033F, 0x031F, 0x031F, 0x0699, 0x07F8, 0x07FA, 0x07FD, 0x07FF, 0x07FF, 0x363C, 0xB0D1, 0xB0F1, 0xB0D1, 0xB8D1, 0xB0D1, 0xB0D1, 0x4112, 0x38F1, 0x3911, 0x30F0, 0x30EF, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x20AD, 0x0915, 0x00F9, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20CD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xD2F4, 0xCAF4, 0xD2F4, 0xC65C, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF7F, 0xB67C, 0x8A12, 0x8971, 0xA111, 0xA111, 0xA911, 0xA111, 0xA911, 0xA111, 0xA111, 0xA111, 0xA911, 0xA911, 0xA111, 0xA111, 0xA111, 0xA911, 0xA111, 0xA111, 0xA111, 0xA912, 0xA911, 0xA1F3, 0x8191, 0x9931, 0xA111, 0xA111, 0xA912, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA911, 0xA911, 0xA911, 0xA911, 0xA911, 0xA111, 0xA111, 0xA111, 0xA112, 0xA911, 0xAA54, 0xBF1D, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xB79E, 0xBF9F, 0xA498, 0x8191, 0x9951, 0xA911, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA911, 0xB5FB, 0xBF9E, 0xBF9F, 0xBF9E, 0xBF9F, 0xA498, 0x8191, 0x9951, 0xA111, 0xA111, 0xA111, 0xA111, 0xA112, 0xA111, 0xA911, 0xB5FB, 0xBF7E, 0xBF9E, 0xBF9E, 0xBF9F, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBEBD, 0xD335, 0xCAF4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xCAF4, 0xD2F4, 0xD2F5, 0xCAF4, 0x007F, 0x007F, 0x00BF, 0x021F, 0x2ABD, 0x7A36, 0xB953, 0xC112, 0xC911, 0xC912, 0x0B3F, 0x035F, 0x035F, 0x033F, 0x05FA, 0x07F7, 0x07F9, 0x07FC, 0x07FE, 0x07FF, 0x2E3C, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0D1, 0xB0D1, 0xA0F1, 0x68F1, 0x4111, 0x30F0, 0x30F0, 0x28EF, 0x28EF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xD2D4, 0xD2D4, 0xD2D4, 0xBE5C, 0xB77E, 0xB79E, 0xB77E, 0xBF7E, 0xB77E, 0xB77E, 0xB77E, 0xB79E, 0xBF7E, 0xAE7B, 0x89F2, 0x8971, 0xA111, 0xA8F1, 0xA911, 0xA8F1, 0xA911, 0xA911, 0xA911, 0xA911, 0xA911, 0xA8F1, 0xA911, 0xA911, 0xA911, 0xA8F1, 0xA911, 0xA8F1, 0xA911, 0xA911, 0xA912, 0xA911, 0xA911, 0xA111, 0xA911, 0xA8F1, 0xA911, 0xA8F1, 0xA111, 0xA911, 0xA8F1, 0xA8F1, 0xA911, 0xA911, 0xA8F1, 0xA911, 0xA8F1, 0xA8F1, 0xA912, 0xA911, 0xA911, 0xA911, 0xA8F1, 0xA111, 0xAA34, 0xB71E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xB77E, 0xB77E, 0xBF7E, 0xB77E, 0xB77E, 0xBF7F, 0xB77E, 0x9C97, 0x8191, 0x9951, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA911, 0xA8F1, 0xB5DB, 0xBF7E, 0xB77E, 0xBF7E, 0xBF7E, 0xA478, 0x8191, 0x9951, 0xA911, 0xA8F1, 0xA8F1, 0xA911, 0xA911, 0xA8F1, 0xA911, 0xB5DB, 0xB77F, 0xB77E, 0xBF7E, 0xBF7E, 0xB77E, 0xBF7E, 0xBF7E, 0xBF7E, 0xB77E, 0xB77E, 0xBF7E, 0xB77E, 0xBF7E, 0xB77E, 0xBF7E, 0xBF7E, 0xB77E, 0xB77E, 0xBF7E, 0xBE9D, 0xCB75, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D5, 0x007F, 0x007F, 0x30BB, 0x9955, 0xC931, 0xC932, 0xC932, 0xC912, 0xC0F2, 0xC8F2, 0x32FC, 0x037F, 0x037F, 0x037F, 0x059B, 0x07F7, 0x07F9, 0x07FC, 0x07FE, 0x07FF, 0x2E3C, 0xB8D1, 0xB0D1, 0xB0D2, 0xB0D1, 0xB0F1, 0x98F1, 0xB0F1, 0x88F1, 0x3110, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xD2B4, 0xD2B4, 0xD2B4, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB71D, 0x8A53, 0x8191, 0xA111, 0xA8F1, 0xB0F1, 0xA911, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F2, 0xA8F1, 0xB0F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xB2F5, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB75E, 0xB77E, 0xB77E, 0xB77E, 0xB75E, 0xB75E, 0xB77E, 0xB75E, 0xB77E, 0xB77E, 0xB75E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB75E, 0xB75E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB75E, 0xB77E, 0xB77E, 0xB75E, 0xB77E, 0xB75E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0x9C78, 0x8191, 0x9951, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xB5DB, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0x9C77, 0x8191, 0x9151, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xB5DB, 0xB77E, 0xB77E, 0xB77E, 0xB75E, 0xB77E, 0xB75E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB75E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB75E, 0xB71D, 0xCB96, 0xD2B4, 0xD2B4, 0xCAB4, 0xD2B4, 0xCAB4, 0xD2B4, 0xCAB4, 0xD2B4, 0xCAB4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xCA94, 0xD2B4, 0xD2B4, 0xD2B4, 0xCAB4, 0x087E, 0x70F8, 0xC952, 0xC932, 0xC912, 0xC932, 0xC111, 0xC8F1, 0xC8F1, 0xC8D1, 0x331C, 0x03BF, 0x039F, 0x039F, 0x051B, 0x07D6, 0x07F7, 0x07FB, 0x07FE, 0x07FF, 0x2E3C, 0xB8D1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0D1, 0xA0F1, 0xB0F1, 0xB0D1, 0x50F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xD294, 0xD294, 0xCA94, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF5E, 0xB75E, 0x9416, 0x8991, 0x9951, 0xB0F1, 0xA8F1, 0xB0F1, 0xA8F1, 0xB0F1, 0xA8F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xA8F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xA8F1, 0xA8F1, 0xB0F1, 0xA8F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0F2, 0xA8F1, 0xB0F1, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0F2, 0xA8F1, 0xB0F2, 0xB0F1, 0xB0F1, 0xB0F1, 0xA8F1, 0xB0F1, 0xB0F1, 0xACF9, 0xAF5E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF7E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xB75E, 0xB75E, 0xAF5E, 0xB75E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xB75E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5D, 0xB75E, 0xAF5E, 0xAF5E, 0x9C77, 0x8191, 0x9951, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xADBB, 0xB75E, 0xB75E, 0xB75E, 0xB75E, 0x9C78, 0x8991, 0x9951, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB5BB, 0xB75E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF5E, 0xB75E, 0xB75E, 0xB75E, 0xAF5E, 0xB75E, 0xB75E, 0xB75E, 0xAF5E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF1D, 0xCB75, 0xCA93, 0xD294, 0xCA74, 0xCA94, 0xCA74, 0xD274, 0xCA74, 0xD294, 0xCA94, 0xCA94, 0xCA94, 0xCA94, 0xCA94, 0xCA94, 0xCA94, 0xCA94, 0xD294, 0xCA93, 0xCA94, 0xD293, 0xCA74, 0x9915, 0xC932, 0xC932, 0xC932, 0xC912, 0xC111, 0xC8F2, 0xC0F2, 0xC8D1, 0xC8D1, 0x333C, 0x03FF, 0x03DF, 0x03BF, 0x04DC, 0x07D6, 0x07F7, 0x07FB, 0x07FE, 0x07FF, 0x2E3C, 0xB0D1, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0F1, 0xA8F1, 0xB0F1, 0xB0F1, 0x90F1, 0x30F0, 0x28F0, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xD274, 0xD274, 0xCA53, 0xAF5E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3D, 0xAF5D, 0xAF3D, 0xAF3E, 0xA69C, 0x8191, 0x8191, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0D1, 0xB0F2, 0xB0D1, 0xB0D1, 0xB0F2, 0xB0F1, 0xB0F1, 0xAA13, 0xB418, 0xA438, 0x9AB4, 0x9931, 0xA8F1, 0xB0F1, 0xB0F2, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xAA74, 0xAC78, 0xACF9, 0x9B35, 0x9931, 0xA8F1, 0xB0F1, 0xB0F2, 0xB0F1, 0xB0D1, 0xB0D1, 0xB0F1, 0xB0F2, 0xB0D1, 0xB0F1, 0xA9B3, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3D, 0xAF3D, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3D, 0xAF3D, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3D, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0x9C77, 0x8191, 0x9931, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xADBB, 0xAF3E, 0xAF3E, 0xAF5D, 0xAF3E, 0x9477, 0x8191, 0x9951, 0xB0D1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0D1, 0xADBA, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3D, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF3D, 0xAF3D, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAEFD, 0xCB56, 0xCA53, 0xCA74, 0xD253, 0xD274, 0xD274, 0xD273, 0xCA73, 0xD274, 0xD274, 0xD274, 0xD274, 0xD274, 0xD274, 0xD274, 0xD274, 0xD254, 0xCA74, 0xCA54, 0xCA54, 0xCA74, 0xC932, 0xC932, 0xC932, 0xC912, 0xC912, 0xC912, 0xC0F1, 0xC8D1, 0xC8D1, 0xC8D1, 0x335C, 0x041F, 0x03FF, 0x03FF, 0x047D, 0x0795, 0x07F6, 0x07FA, 0x07FE, 0x07FF, 0x2E3C, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0F1, 0xA8F1, 0xB0F1, 0xB0D1, 0xB0F1, 0x40F0, 0x28CF, 0x28EF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xCA53, 0xCA53, 0xCA53, 0xA73E, 0xA73E, 0xA73E, 0xA73E, 0xA73D, 0xA73D, 0xA73D, 0xA73D, 0x9457, 0x8191, 0x9931, 0xB8D1, 0xB0D1, 0xB8D1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB1B3, 0xAD9A, 0xAF3D, 0xAF3D, 0xA73D, 0xA73D, 0x9DDA, 0x89D1, 0x9951, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0F1, 0xB213, 0xAD9B, 0xA73E, 0xA73D, 0xAF3E, 0xAF3E, 0x9DDA, 0x81F2, 0x9171, 0xB0F1, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0D1, 0xB8D1, 0xB8D2, 0xB0F1, 0xAD39, 0xA73D, 0xA73E, 0xA73D, 0xA73D, 0xA73D, 0xA73D, 0xA73D, 0xA73E, 0xA73D, 0xA73D, 0xA73D, 0xAF3D, 0xA73D, 0xA73D, 0xA73D, 0xA73E, 0xA73E, 0xA73D, 0xAF3D, 0xA73D, 0xA73D, 0xA73E, 0xAF3D, 0xA73E, 0xA73E, 0xA73D, 0xAF3D, 0xA73D, 0xA73D, 0xA73E, 0xAF3E, 0xAF1E, 0xA73E, 0xA73E, 0xA73E, 0xA73E, 0xA73E, 0xA73E, 0xA73E, 0xA73E, 0xAF3E, 0xA73E, 0xA73D, 0xAF3E, 0xA73E, 0xA73D, 0xA73D, 0xA73D, 0xAF3D, 0xA73E, 0xA73E, 0xA73E, 0xA73D, 0xAF3D, 0xA73D, 0xAF3D, 0xA73E, 0xA73E, 0xAF3D, 0xA73E, 0xA73D, 0xA73D, 0xA73E, 0x9478, 0x8191, 0x9931, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB8D1, 0xAD9A, 0xA73E, 0xA73D, 0xA73E, 0xA73D, 0xA73D, 0xA73D, 0xAF3D, 0xA73D, 0xA73D, 0xA73D, 0xA73D, 0xA73D, 0xAF3D, 0xA73D, 0xA73D, 0xA73D, 0xAF3E, 0xA73E, 0xA73D, 0xA73D, 0xA73D, 0xAF3D, 0xAF3E, 0xA73D, 0xAF3D, 0xAF3E, 0xA73D, 0xA73D, 0xAF3D, 0xA73E, 0xAF3D, 0xAF3D, 0xAF3D, 0xA73E, 0xA73D, 0xA73D, 0xAF3D, 0xA73D, 0xAEDD, 0xC376, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA33, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xD233, 0xCA53, 0xD253, 0xCA53, 0xCA53, 0x309C, 0x005F, 0x58B9, 0xC912, 0xC111, 0xC8F1, 0xC8D1, 0xC8D1, 0xC0D1, 0xC0D1, 0x337C, 0x045F, 0x041F, 0x041F, 0x045E, 0x0775, 0x07F5, 0x07FA, 0x07FE, 0x07FF, 0x2E3C, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0D1, 0xB0F1, 0xA8F1, 0xB0F1, 0xB0F1, 0xB0D1, 0x80F1, 0x28EF, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xCA13, 0xCA33, 0xCA13, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA73D, 0xA73D, 0xA73D, 0x8A53, 0x8191, 0xA8F1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB213, 0xA6BD, 0xA71D, 0xA73E, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0x9E1B, 0x81F1, 0x9171, 0xB0F1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB1F3, 0xA6BD, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA73D, 0xA71D, 0x9E1B, 0x89F2, 0x8991, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB8D1, 0xB336, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA73D, 0xA73D, 0xA73D, 0xA71D, 0xA71D, 0xA73D, 0xA71D, 0xA71E, 0xA71D, 0xA71D, 0xA73D, 0xA73E, 0xA71D, 0xA71D, 0xA71D, 0xA73E, 0xA71D, 0xA73E, 0xA73D, 0xA71D, 0xA71D, 0xA73D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA73D, 0xA73D, 0xA73D, 0xA73E, 0xA71D, 0xA73D, 0xA73D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA73D, 0xA71D, 0xA71D, 0xA73E, 0xA73D, 0xA73D, 0xA71D, 0xA71D, 0x9477, 0x8191, 0x9931, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xA59A, 0xA71D, 0xA73D, 0xA73E, 0xA71D, 0xA71D, 0xA71E, 0xA73D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA73D, 0xA73D, 0xA71E, 0xA71D, 0xA73D, 0xA71D, 0xA73D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA73D, 0xA73D, 0xA71D, 0xA73D, 0xA73D, 0xA71D, 0xA73E, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xBBF7, 0xCA13, 0xCA33, 0xCA13, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA13, 0xCA13, 0xCA14, 0xD233, 0xCA33, 0x003F, 0x003F, 0x005F, 0x78D7, 0xC0F2, 0xC8F1, 0xC0D1, 0xC0D1, 0xC0D1, 0xC8B1, 0x4B1A, 0x047F, 0x045F, 0x043F, 0x045F, 0x0735, 0x07F4, 0x07F9, 0x07FE, 0x07FF, 0x2E3C, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0D1, 0xB0D1, 0xA8F1, 0xB0F1, 0xB0D1, 0xB0F1, 0xA0F1, 0x28CF, 0x28EF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xCA13, 0xCA13, 0xCA13, 0x9F1D, 0x9F1D, 0xA71D, 0x9F1D, 0x9F1D, 0xA71D, 0x9F1D, 0x9F1D, 0x8191, 0x8191, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xA5DB, 0x9F1D, 0x9F1D, 0x9EFD, 0x9F1D, 0x9F1D, 0x9F1D, 0xA6FD, 0x9F1D, 0x94F9, 0x8191, 0x9931, 0xB8D1, 0xB8D1, 0xB8B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8B1, 0xA5DB, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0xA6FD, 0x9F1D, 0x9F1D, 0x9F1D, 0x94F9, 0x8191, 0x9931, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB932, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1E, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9E1B, 0x9457, 0x92D4, 0xA1F3, 0xA911, 0xB0F1, 0xB0F1, 0xA911, 0xB274, 0xB254, 0xB254, 0xABF7, 0xA5DB, 0xA6FD, 0xA6FD, 0xA71D, 0xA71D, 0x9F1D, 0x9F1D, 0xA6FD, 0x9F1D, 0x9F1D, 0xA71D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9E7C, 0x9498, 0x8B14, 0x9A13, 0xA131, 0xA912, 0xB0F1, 0xA8F1, 0xB255, 0xB274, 0xB254, 0xAB97, 0xAD1A, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0xA71D, 0x9F1D, 0xA71D, 0x9457, 0x8191, 0xA131, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xA57A, 0x9F1D, 0xA71D, 0x9F1D, 0xA71D, 0x9E7C, 0x9DBA, 0xA59A, 0xA57A, 0xA57A, 0xA57A, 0xA57A, 0xA57A, 0xA57A, 0xA57A, 0xA69C, 0x9F1D, 0x9F1D, 0x9F1D, 0xA71D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9E5C, 0x94B8, 0x8AF4, 0x9A13, 0xA131, 0xA8F1, 0xB0F1, 0xB0F1, 0xB932, 0xB274, 0xB254, 0xB336, 0xACB9, 0xA63C, 0x9F1D, 0xBBF7, 0xC9F3, 0xCA13, 0xCA13, 0xCA13, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xCA13, 0xCA13, 0xCA13, 0xCA13, 0xCA13, 0x003F, 0x003F, 0x005F, 0x58B9, 0xC0F1, 0xC0D1, 0xC8D1, 0xC8B2, 0xC0B1, 0xC0B1, 0x62B8, 0x04BF, 0x047F, 0x047F, 0x045F, 0x0715, 0x07F4, 0x07F9, 0x07FD, 0x07FF, 0x2E3C, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0D1, 0xA8F1, 0xA8F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0x58F0, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xC9D3, 0xC9D3, 0xC9D3, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x959A, 0x8191, 0x9151, 0xC0B1, 0xB8D1, 0xC0B1, 0xB8D1, 0xC0D1, 0xB8D1, 0xB8D1, 0xB2B5, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x8252, 0x8191, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xC0B1, 0xC0D1, 0xB8D1, 0xC0D1, 0xB1F3, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9F1D, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x8A93, 0x8191, 0xB8D1, 0xB8D1, 0xC0D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xC0B1, 0xA63C, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x94F8, 0x8A53, 0x9171, 0xB0F1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8B1, 0xB8B1, 0xC0B1, 0xC0D1, 0xC0D1, 0xB8D1, 0xC0D1, 0xB8B1, 0xB992, 0xACB9, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9E5C, 0x8B96, 0x8991, 0xA131, 0xB8D1, 0xB8D1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xC0B1, 0xB8D1, 0xB932, 0xABF7, 0x9E9C, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9437, 0x8191, 0xA131, 0xB8D1, 0xC0B1, 0xB8D1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB8D1, 0xA57A, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9437, 0x8191, 0xA131, 0xB8D1, 0xC0B1, 0xB8D1, 0xB8D1, 0xC0B1, 0xB8D1, 0xB8D1, 0xA57A, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9E9C, 0x8B96, 0x8971, 0xA131, 0xB8D1, 0xB8D1, 0xC0B1, 0xB8D1, 0xC0B1, 0xC0D1, 0xB8D1, 0xB8D1, 0xC0D1, 0xB8D1, 0xB8D1, 0xC0D1, 0xB335, 0xA63C, 0xBBD7, 0xC9D3, 0xC9F3, 0xC9D3, 0xC9D3, 0xC9D3, 0xC9D3, 0xC9D3, 0xC9D3, 0xC9D3, 0xC9D3, 0xC9D3, 0xC9F3, 0xC9D3, 0xC9D3, 0xC9F3, 0xC9D3, 0x001F, 0x003F, 0x003F, 0x00DF, 0x88F6, 0xC8D1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC8B1, 0x62D9, 0x04FF, 0x04BF, 0x049F, 0x047F, 0x06B6, 0x07F3, 0x07F8, 0x07FD, 0x07FF, 0x2E3C, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0F1, 0x98F2, 0xB0F1, 0xB0F1, 0xB0F1, 0x78F0, 0x90F1, 0x80D1, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0xC9B3, 0xC9B3, 0xC9B3, 0x9EDD, 0x96FD, 0x9EDD, 0x96FD, 0x9EFC, 0x96FD, 0x96FD, 0x9599, 0x8991, 0x9171, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xABD7, 0x9EFC, 0x96FD, 0x96FD, 0x96DD, 0x96FD, 0x9EFD, 0x9EDD, 0x96FD, 0x9EDD, 0x9EFD, 0x8C37, 0x8191, 0xA111, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xAB76, 0x9EDD, 0x9EFD, 0x9EFD, 0x9EDD, 0x9EDD, 0x96DD, 0x9EFD, 0x9EDD, 0x96FD, 0x9EDD, 0x8C37, 0x8191, 0xA131, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0D1, 0xA55A, 0x96FD, 0x9EDD, 0x9EFD, 0x96FD, 0x963B, 0x8AF4, 0x8991, 0xA911, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xB992, 0xA55A, 0x9EDD, 0x9EFC, 0x96FD, 0x9EDD, 0x96FD, 0x9EFD, 0x96FD, 0x96FD, 0x96FD, 0x96FD, 0x96FD, 0x96FD, 0x96FD, 0x96FD, 0x94F9, 0x81F1, 0x9171, 0xB8D2, 0xC0B1, 0xC0D1, 0xC0D1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xB992, 0x9DBB, 0x96FD, 0x9EDD, 0x96FD, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xA55A, 0x9EDD, 0x96FD, 0x96FD, 0x9EFD, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xA55A, 0x96FD, 0x9EFD, 0x96FD, 0x9EFD, 0x9EFD, 0x96FD, 0x9EFD, 0x96FD, 0x9539, 0x81F1, 0x9171, 0xB0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB911, 0xACFA, 0xB458, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9D2, 0xC9D3, 0xC9D3, 0xC9B3, 0x001F, 0x003F, 0x003F, 0x00BF, 0x311C, 0xC0D1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x6278, 0x053F, 0x04FF, 0x04BF, 0x049F, 0x0696, 0x07F2, 0x07F7, 0x07FC, 0x07FF, 0x2E3C, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0F1, 0x8912, 0xB0F1, 0xB0F1, 0xB0D1, 0x48F0, 0x28F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xC993, 0xC993, 0xC992, 0x96DC, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x8D79, 0x8191, 0x9151, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xABD7, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xABD7, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x9D5A, 0x96DD, 0x96DD, 0x96DD, 0x95DA, 0x89F2, 0x8971, 0xB8D1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xA499, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DC, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x8C37, 0x8191, 0x9931, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xA499, 0x96DC, 0x96DD, 0x8C37, 0x8191, 0xA111, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x9D5A, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x9D5A, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x8CD8, 0x8191, 0x9951, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xAC79, 0xACF9, 0xC992, 0xC993, 0xC9B2, 0xC992, 0xC992, 0xC993, 0xC993, 0xC993, 0xC992, 0xC992, 0xC992, 0xC993, 0xC993, 0xC993, 0x003F, 0x003F, 0x003F, 0x00BF, 0x011F, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x79D6, 0x051F, 0x051F, 0x04FF, 0x04BF, 0x0638, 0x07F1, 0x07F7, 0x07FC, 0x07FF, 0x2E3C, 0xB0F1, 0xB0F2, 0xB0F1, 0xB0F1, 0x80F2, 0xB0F1, 0xB0F1, 0xB0F2, 0x3110, 0x30F0, 0x28CF, 0x28EF, 0x20CE, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x10D2, 0x08F3, 0x10F3, 0x10D2, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xC972, 0xC972, 0xC972, 0x8EBC, 0x8EBD, 0x8EBD, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBD, 0x8D7A, 0x8191, 0x9151, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xABB7, 0x8EBD, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBD, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xABB7, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EDC, 0x8EBC, 0x8EDD, 0x8EBC, 0x8EBC, 0x8EBD, 0x8EBC, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x9D39, 0x8EBD, 0x8EDD, 0x8DBA, 0x81F2, 0x9171, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC8B1, 0xC8B2, 0xC0B1, 0xC8B2, 0xC8B1, 0xC8B1, 0xC0D1, 0xC0B1, 0xC0D1, 0xC0D1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xA437, 0x8EBC, 0x8EDD, 0x8EBC, 0x8EBD, 0x8EBC, 0x8EBC, 0x8EBD, 0x8EBC, 0x8EBD, 0x8EBD, 0x8CD8, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC8B2, 0xC8B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC8B1, 0xA4D9, 0x8EBC, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC8B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0x9D3A, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x9D5A, 0x8EBC, 0x8EBC, 0x8EDC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8CD8, 0x8191, 0x9951, 0xC8B1, 0xC0B1, 0xC8B1, 0xC8B2, 0xC8B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC8B1, 0xC8B1, 0xC8D1, 0xA478, 0xA4D9, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0x003F, 0x003F, 0x001F, 0x009F, 0x00DF, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x9174, 0x049F, 0x057F, 0x051F, 0x04FF, 0x0619, 0x07F1, 0x07F6, 0x07FC, 0x07FF, 0x35BB, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0F1, 0x6912, 0xB0F1, 0xB0F1, 0x98F1, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28EF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x011A, 0x00FA, 0x011A, 0x0119, 0x08F7, 0x18CE, 0x18AD, 0x20AD, 0x18AE, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0xC952, 0xC952, 0xC952, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8D59, 0x8191, 0x9171, 0xC8F2, 0xC8F1, 0xC8F2, 0xC8F2, 0xC8F2, 0xC8F1, 0xC8F2, 0xABD7, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8C36, 0x8191, 0xA931, 0xC8F2, 0xC8F1, 0xC8F2, 0xC8F2, 0xC8F2, 0xC8F2, 0xC0F2, 0xABB7, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8437, 0x8191, 0xA951, 0xC8F1, 0xC8F1, 0xC8F2, 0xC8F1, 0xC8F1, 0xC8F2, 0xC8F1, 0x9D3A, 0x8EBC, 0x8E1B, 0x81F2, 0x8971, 0xB912, 0xC8F1, 0xC8F1, 0xC8F2, 0xC8F1, 0xC8F1, 0xC8F1, 0xC8F2, 0xC8D1, 0xC112, 0xC8F2, 0xC8F2, 0xC8F2, 0xC8D1, 0xC8F2, 0xC8D1, 0xC8F2, 0xC0F1, 0xC8F1, 0xC8F2, 0xC8F1, 0xC8F2, 0xC0F1, 0xA498, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8DBA, 0x8991, 0x8991, 0xC0F1, 0xC8F2, 0xC0F2, 0xC8F1, 0xC8F2, 0xC8F1, 0xC0F1, 0xC8F2, 0xC8F1, 0xC8F2, 0xC0F2, 0xC8F1, 0xC0F1, 0xC8F2, 0xC8F1, 0xC8F2, 0xC8F2, 0xC8F2, 0xC8F1, 0xC8F1, 0xC0F2, 0xC132, 0x8E5C, 0x8C17, 0x8191, 0xA931, 0xC8F2, 0xC8F2, 0xC8F2, 0xC8F2, 0xC8F1, 0xC8F2, 0xC8F2, 0x9D59, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8C17, 0x8191, 0xA951, 0xC8F1, 0xC8F1, 0xC8F2, 0xC8F1, 0xC8F1, 0xC8F2, 0xC8F1, 0x9D5A, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBD, 0x8DBA, 0x81F2, 0x8991, 0xC111, 0xC8F1, 0xC8F1, 0xC8F1, 0xC0F2, 0xC8F1, 0xC8F1, 0xC0F2, 0xC8D2, 0xC8F1, 0xC8F2, 0xC0F1, 0xC0F1, 0xC8F2, 0xC0F1, 0xC8F1, 0xC8F2, 0xC8F2, 0xC8F1, 0xC8F1, 0xC8F2, 0xC152, 0x95FB, 0xA4B8, 0xC152, 0xC952, 0xC952, 0xC952, 0xC972, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0x001F, 0x001F, 0x001F, 0x007F, 0x00DF, 0x68B7, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xA8F3, 0x041F, 0x057F, 0x053F, 0x051F, 0x05F9, 0x07F0, 0x07F6, 0x07FC, 0x07FF, 0x5C78, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0F1, 0x5912, 0xB0F1, 0xB0F1, 0x90F1, 0x30F0, 0x30EF, 0x30EF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x0117, 0x00F7, 0x0119, 0x0119, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xC932, 0xC932, 0xC932, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8D79, 0x8191, 0x9171, 0xC132, 0xC131, 0xC912, 0xC912, 0xC132, 0xC911, 0xC912, 0xABF7, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x96BC, 0x8C36, 0x8191, 0xA951, 0xC912, 0xC911, 0xC912, 0xC912, 0xC112, 0xC912, 0xC912, 0xABF7, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8C36, 0x8191, 0xA951, 0xC912, 0xC912, 0xC912, 0xC911, 0xC911, 0xC912, 0xC912, 0x9D59, 0x8EBC, 0x8AD4, 0x8191, 0xB152, 0xC912, 0xC131, 0xC912, 0xC912, 0xC912, 0xC912, 0xC912, 0xC912, 0xC932, 0xC912, 0xC912, 0xC912, 0xC912, 0xC911, 0xC112, 0xC932, 0xC912, 0xC912, 0xC932, 0xC911, 0xC912, 0xC912, 0xC932, 0xC131, 0x9DBA, 0x8EBC, 0x96BC, 0x8EBC, 0x8EDC, 0x96BB, 0x8EBC, 0x8EDC, 0x82D4, 0x8191, 0xB932, 0xC912, 0xC112, 0xC912, 0xC112, 0xC912, 0xC112, 0xC912, 0xC911, 0xC911, 0xC932, 0xC911, 0xC131, 0xC912, 0xC132, 0xC131, 0xC912, 0xC912, 0xC911, 0xC911, 0xC131, 0xC912, 0xC912, 0xB356, 0x8C36, 0x8191, 0xA151, 0xC912, 0xC912, 0xC912, 0xC912, 0xC912, 0xC912, 0xC112, 0x9D59, 0x8EBC, 0x96BC, 0x8EBC, 0x8EBC, 0x8C37, 0x8191, 0xA951, 0xC912, 0xC912, 0xC912, 0xC911, 0xC911, 0xC912, 0xC912, 0x9D59, 0x8EBC, 0x8EBC, 0x8EBC, 0x96BC, 0x8EBC, 0x82F4, 0x8991, 0xB151, 0xC912, 0xC912, 0xC932, 0xC912, 0xC912, 0xC131, 0xC932, 0xC912, 0xC911, 0xC911, 0xC932, 0xC911, 0xC912, 0xC911, 0xC932, 0xC932, 0xC112, 0xC911, 0xC132, 0xC912, 0xC912, 0xC932, 0xB336, 0x96BC, 0xA4F9, 0xC192, 0xC932, 0xC932, 0xC932, 0xC932, 0xC932, 0xC932, 0xC932, 0xC932, 0xC932, 0xC932, 0x001F, 0x001F, 0x001F, 0x007F, 0x00BF, 0x009F, 0x90B5, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x0B9E, 0x053F, 0x057F, 0x053F, 0x05DA, 0x07EF, 0x07F5, 0x07FB, 0x07FF, 0x5478, 0xB0D1, 0xB0F1, 0xB0F1, 0x9111, 0x5912, 0xA8F1, 0xB0F1, 0x70F1, 0x30F0, 0x28EF, 0x20EF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xC912, 0xC912, 0xC912, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDC, 0x9EDB, 0x9EDB, 0x9EDB, 0x9578, 0x8191, 0x9991, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xB417, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9436, 0x8191, 0xA972, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xA518, 0x9EDB, 0x96DB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9436, 0x8191, 0xA171, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xA579, 0x94D8, 0x8191, 0x9991, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC152, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC253, 0xC2B4, 0xB952, 0xC152, 0xC952, 0xC152, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xBAB5, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9599, 0x8191, 0x91B1, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC1F3, 0xC2B5, 0xB952, 0xC152, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC972, 0xC952, 0xC952, 0xC972, 0xC1B2, 0x9436, 0x8191, 0xA972, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xA579, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x8C36, 0x8991, 0xA171, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xA579, 0x9EDB, 0x9EDC, 0x9EDB, 0x9EDB, 0x9598, 0x8191, 0x9191, 0xC952, 0xC952, 0xC952, 0xC952, 0xC152, 0xC952, 0xC172, 0xC952, 0xC952, 0xC952, 0xC1F3, 0xC2B4, 0xB952, 0xC152, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xA61A, 0x9EDC, 0xA5DA, 0xC172, 0xC912, 0xC911, 0xC911, 0xC912, 0xC912, 0xC111, 0xC912, 0xC912, 0xC912, 0x001F, 0x001F, 0x001F, 0x005F, 0x007F, 0x007F, 0x6098, 0xC0B1, 0xB8B1, 0xC0B1, 0xC0B1, 0x2AFC, 0x04FF, 0x05BF, 0x055F, 0x05FB, 0x07CF, 0x07F4, 0x07FC, 0x07FF, 0x5C79, 0xB0F1, 0xB0F1, 0xB0F1, 0x8112, 0x5912, 0xB0F1, 0xB0F1, 0x68F1, 0x30F0, 0x30EF, 0x30CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x18D0, 0x18AD, 0x18AD, 0x10D0, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xC8F1, 0xC8F1, 0xC8F2, 0xA6FB, 0xA6FA, 0xA6FA, 0xA6FB, 0xA6FA, 0xA6DA, 0xA6FA, 0x9D98, 0x8191, 0x9191, 0xC972, 0xC992, 0xC992, 0xC972, 0xC992, 0xC992, 0xC992, 0xB436, 0xA6FB, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0x9436, 0x8191, 0xA992, 0xC992, 0xC992, 0xC972, 0xC972, 0xC972, 0xC992, 0xC992, 0xAD98, 0xA6DA, 0xA6DA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0x9436, 0x8191, 0xA992, 0xC993, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xAD99, 0x8A32, 0x8991, 0xC192, 0xC992, 0xC992, 0xC972, 0xC992, 0xC992, 0xC973, 0xC992, 0xC992, 0xC992, 0xBC36, 0xA69A, 0xA6FA, 0xA6FA, 0xA69A, 0x9395, 0x8991, 0xB992, 0xC993, 0xC972, 0xC972, 0xC992, 0xC992, 0xC972, 0xC992, 0xC972, 0xC972, 0xAD98, 0xA6DB, 0xA6DA, 0xA6FA, 0xA6FB, 0xA6FA, 0x9395, 0x8191, 0xB192, 0xC992, 0xC992, 0xC992, 0xC993, 0xC972, 0xC972, 0xC992, 0xC972, 0xC233, 0xAD98, 0xA6FA, 0xA6FB, 0xA639, 0x8A93, 0x9992, 0xC192, 0xC972, 0xC992, 0xC992, 0xC992, 0xC972, 0xC992, 0xC972, 0xC972, 0x9A93, 0x8191, 0xA992, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xAD98, 0xA6FA, 0xA6FB, 0xA6FA, 0xA6FA, 0x9436, 0x8191, 0xA992, 0xC993, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xAD98, 0xA6DA, 0xA6DA, 0xA6FA, 0xA6DA, 0x8B95, 0x8191, 0xB192, 0xC972, 0xC992, 0xC972, 0xC992, 0xC992, 0xC972, 0xC992, 0xC972, 0xC294, 0xADF9, 0xA6FA, 0xA6DA, 0xA69A, 0x9334, 0x9191, 0xB992, 0xC992, 0xC993, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xB497, 0xAEFB, 0xAEFB, 0xB5D9, 0xC952, 0xC8F1, 0xC8F2, 0xC0F1, 0xC8F1, 0xC8F1, 0xC8F1, 0xC8F1, 0xC8F1, 0x001F, 0x001F, 0x001F, 0x003F, 0x007F, 0x005F, 0x7897, 0xC0B1, 0xC0D1, 0xC0B1, 0xB8D1, 0x6238, 0x04DF, 0x05BF, 0x059F, 0x05FA, 0x07CE, 0x07F4, 0x07FC, 0x07FF, 0x5C78, 0xB0F1, 0xB0F1, 0xB0F1, 0x7112, 0x5912, 0xB0F1, 0xA8F1, 0x5110, 0x30F0, 0x30CF, 0x28CF, 0x28CF, 0x28CF, 0x20AE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0xC0D1, 0xC0D1, 0xC8D2, 0xB71A, 0xB71A, 0xB71A, 0xAEFA, 0xB71A, 0xAF1A, 0xAEFA, 0xA598, 0x8191, 0x9191, 0xC9B3, 0xC9B3, 0xC9D3, 0xC9D3, 0xC9B2, 0xC9B3, 0xC9D3, 0xBC76, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0x9C55, 0x8191, 0xA9B2, 0xC9D3, 0xC9D3, 0xC9B3, 0xC9B2, 0xC9B3, 0xC9D3, 0xC9D3, 0xB5B8, 0xB71A, 0xAF1A, 0xB71A, 0xB6FA, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0xB6FA, 0xAF1A, 0x9C56, 0x8191, 0xA992, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xA3B5, 0x8191, 0x9992, 0xC9B2, 0xC9B3, 0xC9D2, 0xC9B2, 0xC9B3, 0xC9B2, 0xC9B3, 0xC9D3, 0xCA13, 0xBDB8, 0xAEFA, 0xAF1A, 0xB71A, 0xB6FA, 0xAEFA, 0xAF19, 0xA4F7, 0x8991, 0xB1B2, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9D2, 0xC9B3, 0xC9B3, 0xC314, 0xAF1A, 0xAF1A, 0xAEF9, 0xAF1A, 0xAF1A, 0x89F1, 0x8191, 0xC1B2, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B2, 0xC9B2, 0xC9D3, 0xC9B3, 0xCAB4, 0xB6B9, 0xAF1A, 0xB71A, 0xAEFA, 0xB71A, 0xB6B9, 0x8A93, 0x8991, 0xC1D2, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B2, 0xC9D3, 0xC9B2, 0xA992, 0x8191, 0xA9B2, 0xC9D3, 0xC9B3, 0xC9D3, 0xC9B2, 0xC9B2, 0xC9B2, 0xC9B3, 0xB5B8, 0xAF1A, 0xAEFA, 0xAF1A, 0xB71A, 0x9C56, 0x8191, 0xA992, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xB5B8, 0xB6FA, 0xAF1A, 0xAF1A, 0xB6FA, 0x89F2, 0x8191, 0xC1B2, 0xC9B3, 0xC9B2, 0xC9D3, 0xC9B3, 0xC9B3, 0xC9B2, 0xC9D3, 0xCAB4, 0xB6B9, 0xAF1A, 0xB71A, 0xB71A, 0xB6FA, 0xB71A, 0x92F3, 0x89B1, 0xC1B2, 0xC9D3, 0xC9B3, 0xC9B3, 0xC9D3, 0xC9D3, 0xC9B3, 0xC9D3, 0xC315, 0xB71A, 0xB71A, 0xB71A, 0xBDD9, 0xC132, 0xC0D1, 0xC8D1, 0xC8D1, 0xC8D1, 0xC8D1, 0xC0D1, 0xC0D1, 0x001F, 0x001F, 0x001F, 0x003F, 0x007F, 0x007F, 0x6878, 0xB8B1, 0xC0B1, 0xC0D1, 0xB8D1, 0x9954, 0x047F, 0x05BF, 0x05BF, 0x061A, 0x07CE, 0x07F2, 0x07FC, 0x07FF, 0x5C78, 0xB0F1, 0xB0F1, 0xB0F1, 0x6112, 0x5912, 0xA8F1, 0xA8F1, 0x60F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00F7, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x08F5, 0x0119, 0x0119, 0x00F7, 0x00F7, 0x0119, 0x0119, 0x08F4, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0xC0B1, 0xC8B1, 0xC0B1, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xA4B5, 0x8191, 0xA1B2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xD1F3, 0xC496, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xA455, 0x8191, 0xA9D2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xBDD8, 0xBF19, 0xBF19, 0xBF19, 0xBF39, 0xBF19, 0xBF19, 0xBF39, 0xBF19, 0xBF39, 0xBF39, 0xA455, 0x8191, 0xA9D2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0x99F2, 0x8991, 0xB1D2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F2, 0xC577, 0xBF19, 0xBF39, 0xBF39, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0x9BF5, 0x8191, 0xB1D2, 0xC9F3, 0xC9F3, 0xD1F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xBE78, 0xBF19, 0xBF19, 0xBF19, 0xB6B9, 0x8191, 0x8991, 0xC9F3, 0xC9F3, 0xC9F2, 0xC9F3, 0xC9F3, 0xC9D3, 0xC9F3, 0xC9F3, 0xBED8, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF39, 0xAD57, 0x8191, 0x99B2, 0xC9F3, 0xC9F2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xB9D3, 0x8191, 0xA9B2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xBDD8, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0x9C75, 0x8191, 0xA9D2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xBDD8, 0xBF19, 0xBF19, 0xBF19, 0xB6B8, 0x8191, 0x8191, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xBE78, 0xBF19, 0xBF39, 0xBF19, 0xBF39, 0xBF19, 0xBF19, 0xADB7, 0x8191, 0x91B1, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC71A, 0xBF1A, 0xC73A, 0xBF3A, 0xC659, 0xC9D3, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0x001F, 0x001F, 0x001F, 0x003F, 0x005F, 0x003F, 0x001F, 0x7076, 0xC0D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x0BFF, 0x05DF, 0x05BF, 0x0639, 0x07CD, 0x07F2, 0x07FC, 0x07FF, 0x63F7, 0xB0F1, 0xB0F1, 0xB0F1, 0x4132, 0x4111, 0xA0F1, 0xB0F1, 0x90F1, 0x30F0, 0x28EF, 0x28CE, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F8, 0x10D0, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0xC0B1, 0xC0B1, 0xC0B1, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xA475, 0x8991, 0xA9D2, 0xCA13, 0xCA33, 0xCA33, 0xCA34, 0xCA13, 0xCA33, 0xCA33, 0xCCB6, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xA455, 0x8191, 0xA9D2, 0xCA33, 0xCA33, 0xCA13, 0xCA33, 0xCA33, 0xCA33, 0xD213, 0xC5F7, 0xC738, 0xC738, 0xC738, 0xC738, 0xC739, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xA475, 0x8191, 0xA9D2, 0xCA13, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA13, 0xCA33, 0x91B1, 0x8191, 0xCA13, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA13, 0xCA33, 0xCA13, 0xC455, 0xC738, 0xC739, 0xC738, 0xC738, 0xC738, 0xC738, 0xC739, 0xC738, 0xC738, 0xC738, 0x8A52, 0x8991, 0xC213, 0xCA13, 0xCA13, 0xCA13, 0xCA13, 0xCA33, 0xCA13, 0xCA33, 0xCD56, 0xC738, 0xC738, 0xC739, 0xB5D7, 0x8191, 0x91B1, 0xCA13, 0xCA13, 0xCA13, 0xD233, 0xCA33, 0xCA33, 0xCA33, 0xCB55, 0xCF38, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC739, 0xC738, 0x8191, 0x8191, 0xCA13, 0xCA13, 0xCA13, 0xCA33, 0xCA13, 0xCA33, 0xD233, 0xCA13, 0x8191, 0xA9D2, 0xCA33, 0xCA33, 0xCA13, 0xCA13, 0xCA33, 0xCA13, 0xCA33, 0xCDF7, 0xC738, 0xC738, 0xC738, 0xC739, 0xA475, 0x8191, 0xA9D2, 0xCA13, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA13, 0xCA33, 0xC5F7, 0xC738, 0xC738, 0xC738, 0xB5D6, 0x8191, 0x99B2, 0xCA33, 0xCA33, 0xD213, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCB74, 0xC739, 0xC738, 0xC738, 0xC738, 0xC738, 0xC739, 0xC738, 0xC738, 0x8AB2, 0x8191, 0xBA13, 0xCA13, 0xCA13, 0xCA33, 0xCA13, 0xCA33, 0xCA33, 0xCA13, 0xCF39, 0xC739, 0xC759, 0xCF3A, 0xCF39, 0xCED9, 0xC9F3, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x003F, 0x001F, 0x001F, 0x9894, 0xB8D1, 0xB8D1, 0xB8D1, 0x42DA, 0x059F, 0x05FF, 0x0678, 0x07CC, 0x07F1, 0x07FC, 0x07FF, 0x82B5, 0xA8F1, 0xB0F1, 0x98F2, 0x4132, 0x3912, 0x70F1, 0xA8F1, 0xA8F1, 0x50F0, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F8, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x10D2, 0x10D3, 0x08F3, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0xC0B1, 0xC0B1, 0xC0B1, 0xCF57, 0xD758, 0xD758, 0xCF58, 0xD758, 0xCF58, 0xD758, 0xAC74, 0x8191, 0xA9F2, 0xCA53, 0xD253, 0xCA54, 0xCA53, 0xCA53, 0xCA53, 0xCA54, 0xCCD6, 0xCF58, 0xD758, 0xD758, 0xD758, 0xD758, 0xD758, 0xD758, 0xD758, 0xD758, 0xCF58, 0xAC75, 0x8191, 0xA9F2, 0xCA53, 0xCA53, 0xD253, 0xCA53, 0xCA53, 0xCA53, 0xD254, 0xCE17, 0xCF57, 0xD758, 0xCF58, 0xD758, 0xCF58, 0xD758, 0xD758, 0xCF58, 0xD758, 0xCF58, 0xAC74, 0x8191, 0xA9F2, 0xCA53, 0xCA54, 0xD253, 0xCA53, 0xCA53, 0xCA54, 0xCA53, 0x99D2, 0x89B1, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xD253, 0xCA53, 0xCA53, 0xCA54, 0xD6B7, 0xD758, 0xCF58, 0xCF57, 0xCF58, 0xD758, 0xD757, 0xD758, 0xD757, 0xD758, 0xCF58, 0xB535, 0x8191, 0xA1D2, 0xCA53, 0xCA53, 0xCA53, 0xD254, 0xCA73, 0xCA53, 0xCA53, 0xCC95, 0xD758, 0xD758, 0xCF58, 0xBDD6, 0x8191, 0x99D2, 0xCA53, 0xCA53, 0xCA54, 0xCA53, 0xCA53, 0xD254, 0xCA54, 0xD435, 0xD758, 0xD758, 0xCF58, 0xD758, 0xD758, 0xCF57, 0xD738, 0xCF58, 0x9AF3, 0x8991, 0xC213, 0xCA54, 0xCA53, 0xCA53, 0xD253, 0xCA53, 0xCA54, 0xCA73, 0x8191, 0xA9F2, 0xCA53, 0xD253, 0xD253, 0xCA54, 0xD253, 0xCA53, 0xCA54, 0xCE17, 0xCF58, 0xD758, 0xD758, 0xCF58, 0xAC74, 0x8191, 0xA9F2, 0xCA53, 0xCA54, 0xD253, 0xCA53, 0xCA53, 0xCA54, 0xCA53, 0xD617, 0xD758, 0xCF58, 0xCF58, 0xBDD6, 0x8191, 0x91B2, 0xCA53, 0xD254, 0xCA53, 0xCA53, 0xCA54, 0xD253, 0xD253, 0xCCD6, 0xD758, 0xD758, 0xD758, 0xD758, 0xCF57, 0xD757, 0xCF58, 0xD758, 0x9AF3, 0x8191, 0xBA33, 0xCA54, 0xCA53, 0xD253, 0xCA54, 0xCA53, 0xD253, 0xCA53, 0xD758, 0xD758, 0xDF59, 0xD779, 0xD759, 0xD759, 0xD6F9, 0xC1F2, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x001F, 0x001F, 0x001F, 0x003F, 0x001F, 0x001F, 0x001F, 0x001F, 0x183E, 0xB0D2, 0xB8D1, 0xB8D1, 0x9974, 0x059F, 0x061F, 0x0698, 0x07CC, 0x07F0, 0x07FC, 0x07FF, 0x82B5, 0xB0F1, 0xB0F1, 0x88F1, 0x4132, 0x4111, 0x3910, 0x98F1, 0xA8F2, 0x88F1, 0x28EF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x0118, 0x10D0, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0xC0B1, 0xC0B1, 0xC0B1, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xB494, 0x8191, 0xAA12, 0xCA94, 0xCA74, 0xCA94, 0xCA94, 0xCA94, 0xCA94, 0xD294, 0xD4F5, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xB474, 0x8191, 0xAA12, 0xCA94, 0xCA94, 0xD294, 0xCA94, 0xD294, 0xCA94, 0xD294, 0xDE36, 0xDF77, 0xDF77, 0xDF57, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xB494, 0x8191, 0xAA12, 0xCA94, 0xD294, 0xD294, 0xD294, 0xD294, 0xD294, 0xD294, 0x99D2, 0x91D2, 0xD294, 0xCA94, 0xD294, 0xCA94, 0xD294, 0xCA94, 0xCA94, 0xD3D4, 0xDF77, 0xDF77, 0xDF77, 0xDF76, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF57, 0xDF77, 0xDF77, 0x8191, 0x8992, 0xCA94, 0xCA94, 0xCA94, 0xD294, 0xCA94, 0xCA93, 0xCA94, 0xD3D5, 0xDF77, 0xDF77, 0xDF77, 0xC5F5, 0x8191, 0x99D2, 0xCA94, 0xCA94, 0xD273, 0xCA94, 0xD294, 0xCA94, 0xD294, 0xD515, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0x9B12, 0x8191, 0xBA53, 0xCA94, 0xCA94, 0xD294, 0xCA94, 0xCA93, 0xD294, 0xCA94, 0x8191, 0xAA12, 0xD294, 0xD294, 0xD294, 0xCA94, 0xCA94, 0xD294, 0xD294, 0xDE36, 0xDF77, 0xDF77, 0xDF57, 0xDF77, 0xB474, 0x8191, 0xAA12, 0xCA94, 0xD294, 0xD294, 0xD294, 0xD294, 0xD294, 0xD294, 0xDE36, 0xDF77, 0xDF77, 0xDF77, 0xC5F5, 0x8191, 0x99D2, 0xD294, 0xCA94, 0xCA94, 0xD294, 0xCA94, 0xCA94, 0xCA93, 0xD4F5, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0x9B12, 0x8191, 0xBA53, 0xD294, 0xCA94, 0xCA94, 0xD294, 0xCA94, 0xD294, 0xCA94, 0xDF78, 0xDF78, 0xDF78, 0xDF78, 0xDF78, 0xDF78, 0xE779, 0xDF19, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x385B, 0xB8D1, 0xB8D1, 0xB8D1, 0x2C3C, 0x061F, 0x06B7, 0x07CB, 0x07F0, 0x07FB, 0x07FF, 0xB0F1, 0xB0F1, 0xA8F1, 0x7912, 0x4132, 0x4111, 0x3911, 0x4110, 0xA0F1, 0xA8F1, 0x48EF, 0x28CE, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0118, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x208E, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xB8D1, 0xB8D1, 0xC0D1, 0xE776, 0xE796, 0xE797, 0xE797, 0xE796, 0xE796, 0xE796, 0xB494, 0x8191, 0xAA33, 0xD2B4, 0xD2B4, 0xD2B4, 0xCAB4, 0xD2D4, 0xD2B4, 0xD2B4, 0xDD35, 0xE776, 0xE796, 0xE796, 0xE796, 0xE796, 0xE796, 0xE796, 0xE796, 0xE796, 0xE796, 0xB474, 0x8191, 0xAA33, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2B4, 0xD2B4, 0xCAD4, 0xD2D4, 0xE656, 0xEF96, 0xE776, 0xE797, 0xE796, 0xE796, 0xE776, 0xE777, 0xE796, 0xE796, 0xE796, 0xB494, 0x8191, 0xAA33, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0x99D2, 0x99F2, 0xCAB4, 0xD2B4, 0xD2D4, 0xD2B4, 0xD2B4, 0xCAD4, 0xD2B4, 0xD3F5, 0xE777, 0xE797, 0xEF97, 0xE796, 0xE796, 0xE776, 0xE777, 0xE796, 0xE796, 0xE796, 0xE777, 0xEF97, 0x8191, 0x8191, 0xD2B4, 0xD2B4, 0xD2D4, 0xD2D4, 0xD2B4, 0xD2B4, 0xCAD4, 0xD3D5, 0xE796, 0xE796, 0xE796, 0xCE15, 0x8191, 0x99F2, 0xCAD4, 0xD2B4, 0xD2D4, 0xD2B4, 0xD2B4, 0xCAB4, 0xD2B4, 0xDD35, 0xE777, 0xEF76, 0xE796, 0xE797, 0xE797, 0xE776, 0xE796, 0xE776, 0xC534, 0xB494, 0xCC15, 0xD3F5, 0xDBF4, 0xDBF4, 0xDBF5, 0xD3F5, 0xD3F4, 0xCB34, 0x8191, 0xAA32, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2D4, 0xD2B4, 0xCAB4, 0xE656, 0xE776, 0xE796, 0xE796, 0xE776, 0xB494, 0x8191, 0xAA33, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xDE56, 0xE796, 0xE796, 0xE796, 0xCE15, 0x8191, 0x99F2, 0xD2B4, 0xD2B4, 0xD2D4, 0xD2B4, 0xD2D4, 0xCAD4, 0xCAD4, 0xDD15, 0xE796, 0xE796, 0xE776, 0xE796, 0xEF96, 0xE796, 0xE796, 0xE796, 0x9B13, 0x8191, 0xBA73, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xE797, 0xEF97, 0xEF77, 0xEF97, 0xEF78, 0xEF98, 0xEF98, 0xEF98, 0xC992, 0xB8D1, 0xC0D1, 0xC0B1, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x7096, 0xB8D1, 0xB8D1, 0x8A35, 0x063F, 0x06D6, 0x07EA, 0x07F1, 0x07FC, 0x07FF, 0xA8F1, 0xA8F1, 0xA8F1, 0x6132, 0x4132, 0x4111, 0x38F1, 0x3110, 0x48F0, 0xA8F1, 0x98F1, 0x30CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0118, 0x18D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xB8D1, 0xB8D1, 0xB8D1, 0xF796, 0xF7B6, 0xF796, 0xF795, 0xF795, 0xF796, 0xEFB6, 0xBC93, 0x8191, 0xAA52, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2F5, 0xD2F5, 0xD2F4, 0xDD55, 0xF7B6, 0xF7B6, 0xF7B6, 0xF7B6, 0xF7B6, 0xF7B6, 0xF7B6, 0xF7B6, 0xF7B6, 0xEFB6, 0xBC93, 0x8191, 0xAA53, 0xD2F5, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xE675, 0xF796, 0xF795, 0xF796, 0xF796, 0xF796, 0xF7B6, 0xF7B5, 0xF7B5, 0xEF96, 0xF796, 0xBC93, 0x8191, 0xAA33, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0x99F2, 0x99F2, 0xD2F5, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2D4, 0xD2F4, 0xD2F4, 0xDC75, 0xF795, 0xF795, 0xF795, 0xF796, 0xF7B5, 0xF796, 0xF796, 0xF796, 0xF796, 0xEFB6, 0xF7B5, 0xF796, 0x8191, 0x8991, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xDC15, 0xF796, 0xF796, 0xF796, 0xD615, 0x8191, 0x99F2, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2F4, 0xD2F5, 0xE535, 0xF7B6, 0xF7B5, 0xF796, 0xEFB6, 0xF796, 0xF795, 0xF7B6, 0xF796, 0xF7B6, 0xF795, 0xF796, 0xF796, 0xF795, 0xF7B6, 0xF795, 0xF7B6, 0xF796, 0xBC93, 0x8191, 0xAA53, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xEE75, 0xF796, 0xF796, 0xF7B5, 0xF796, 0xBC93, 0x8191, 0xAA33, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xEE75, 0xF796, 0xF7B5, 0xF795, 0xD634, 0x8191, 0x99F2, 0xD2F4, 0xD2F5, 0xD2F4, 0xD2F5, 0xD2F5, 0xD2F5, 0xD2D4, 0xE555, 0xF796, 0xF7B5, 0xF7B6, 0xF7B6, 0xF795, 0xF7B6, 0xF796, 0xF7B6, 0xA311, 0x8191, 0xBA94, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xF796, 0xF796, 0xF797, 0xF797, 0xF797, 0xF7B7, 0xF798, 0xF798, 0xD273, 0xB8D1, 0xB8D1, 0xB8D1, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x98B4, 0xB8D1, 0xB8D1, 0x3C9B, 0x06F5, 0x07E9, 0x07F1, 0x07FD, 0x26BD, 0xB0F1, 0xB0F2, 0xB0F1, 0x4932, 0x4132, 0x4111, 0x3911, 0x3110, 0x30F0, 0x60F0, 0xA911, 0x70F0, 0x20CE, 0x20CF, 0x20AE, 0x20CE, 0x20AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x0118, 0x18D0, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xB8D1, 0xB8D1, 0xB8D1, 0xFF94, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB4, 0xFFB5, 0xC493, 0x8191, 0xAA53, 0xD315, 0xD335, 0xD335, 0xD335, 0xD334, 0xD315, 0xD335, 0xE575, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xC493, 0x8191, 0xAA53, 0xD335, 0xD335, 0xD314, 0xD315, 0xD335, 0xD335, 0xD335, 0xF675, 0xFFB5, 0xFFB4, 0xFFB5, 0xFFB5, 0xFFB4, 0xFFB4, 0xFFB4, 0xFFB5, 0xFFB5, 0xFF95, 0xC493, 0x8191, 0xAA53, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xD315, 0xD335, 0x99F2, 0x99F2, 0xD335, 0xD314, 0xD315, 0xD335, 0xD335, 0xD315, 0xD335, 0xDC54, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB4, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB4, 0xFFB5, 0x8191, 0x8191, 0xD334, 0xD315, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xDC34, 0xFFB4, 0xFFB5, 0xFFB5, 0xDE34, 0x8191, 0x99F2, 0xD314, 0xD335, 0xD315, 0xD334, 0xD334, 0xD335, 0xD335, 0xE574, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB4, 0xFFB4, 0xFFB5, 0xFFB4, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB4, 0xFFB5, 0xFFB5, 0xC4B3, 0x8191, 0xAA53, 0xD335, 0xD335, 0xD314, 0xD315, 0xD335, 0xD335, 0xD335, 0xEDF5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xC493, 0x8191, 0xAA53, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xD315, 0xD335, 0xF694, 0xFFB5, 0xFFB5, 0xFFB5, 0xDE14, 0x8191, 0x99F2, 0xD335, 0xD335, 0xD314, 0xD334, 0xD314, 0xD334, 0xD315, 0xE555, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB4, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xA332, 0x8191, 0xBAB4, 0xD335, 0xD335, 0xD335, 0xD315, 0xD334, 0xD335, 0xD335, 0xFFB5, 0xFFB6, 0xFFB6, 0xFFB6, 0xFFB6, 0xFFB6, 0xFFB7, 0xFFB8, 0xDBD4, 0xB8D2, 0xB8D1, 0xB8D1, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x083F, 0x70F7, 0xB8D1, 0xA952, 0x0E94, 0x07C9, 0x07F2, 0x07FD, 0x2E3C, 0xA8F1, 0xA8F1, 0x9911, 0x4132, 0x4132, 0x3911, 0x3910, 0x30F0, 0x30F0, 0x30EF, 0x58F0, 0xA8F1, 0x40CF, 0x20AE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x00F7, 0x00F9, 0x0118, 0x18CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xB8D1, 0xB8D1, 0xB8D1, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE4E, 0xFE4E, 0xC3F0, 0x8191, 0xAA73, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xECD1, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xC3EF, 0x8191, 0xAA73, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD354, 0xF590, 0xFE4E, 0xFE4E, 0xFE2E, 0xFE2E, 0xFE4E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xC3EF, 0x8191, 0xAA73, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0x9A12, 0x91F2, 0xD355, 0xD354, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xDBD4, 0xFE4E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE4E, 0xFE2E, 0xFE4E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE4E, 0x8191, 0x8191, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xDC13, 0xFE4E, 0xFE2E, 0xFE2E, 0xE50F, 0x8191, 0x99F2, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD354, 0xECD1, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE4E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE4E, 0xFE4E, 0xFE2E, 0xFE2E, 0xC3CF, 0x8191, 0xAA73, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xE4D1, 0xFE4E, 0xFE2E, 0xFE2E, 0xFE4E, 0xC3D0, 0x8191, 0xAA73, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xF590, 0xFE4E, 0xFE2E, 0xFE2E, 0xE50F, 0x8191, 0x9A12, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xECD2, 0xFE2E, 0xFE4E, 0xFE2E, 0xFE4E, 0xFE4E, 0xFE4E, 0xFE4D, 0xFE2F, 0xA2B0, 0x8191, 0xC2F4, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xFE2F, 0xFE50, 0xFE50, 0xFE50, 0xFE51, 0xFE51, 0xFE52, 0xFE52, 0xE3D2, 0xB8D2, 0xB8D1, 0xB8D1, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x001F, 0x003F, 0x00DF, 0x59F8, 0xB8D1, 0x8291, 0x07C9, 0x07F2, 0x07FE, 0x455A, 0xB0F1, 0xA8F1, 0x8112, 0x4132, 0x4132, 0x3911, 0x38F0, 0x30F0, 0x30EF, 0x28EF, 0x28CF, 0x50CF, 0x48EF, 0x20AE, 0x20AE, 0x20CE, 0x20AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00F7, 0x0119, 0x00F8, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0xB8D1, 0xB0D1, 0xB0D2, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC6D, 0xC30F, 0x81B1, 0xAA73, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD375, 0xEC11, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC8D, 0xC30F, 0x8191, 0xAA93, 0xD375, 0xD375, 0xD395, 0xD395, 0xD375, 0xD395, 0xD396, 0xF42F, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC8D, 0xC30F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD395, 0x9A12, 0x8191, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xF44F, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC8D, 0xFC6D, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD396, 0xDBD3, 0xFC8D, 0xFC6D, 0xFC6D, 0xE3CE, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD376, 0xD395, 0xD395, 0xD395, 0xEC11, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC6D, 0xFC8D, 0xC30F, 0x8191, 0xAA93, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEBF1, 0xFC8D, 0xFC6D, 0xFC8D, 0xFC6D, 0xC30F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD395, 0xF42F, 0xFC6D, 0xFC6D, 0xFC8D, 0xE3CE, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD375, 0xD395, 0xD376, 0xD395, 0xD395, 0xEBF1, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC8D, 0xA250, 0x8191, 0xC314, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xFC8E, 0xFC8F, 0xFC8F, 0xFC8F, 0xFCB0, 0xFCB0, 0xFCB1, 0xFCB1, 0xF3B2, 0xB8D1, 0xB0F1, 0xB8D1, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x003F, 0x005F, 0x031F, 0x2D3B, 0x99B2, 0x454B, 0x07F3, 0x07FE, 0x5498, 0xB0F1, 0xA8F1, 0x6912, 0x4912, 0x4112, 0x3911, 0x3110, 0x30F0, 0x30EF, 0x30CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CD, 0x20CE, 0x20AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x00F7, 0x0119, 0x00F8, 0x18CF, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xB0F1, 0xB0F1, 0xB0D1, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xC30F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC11, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xC30F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF44F, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xC30F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0x9A12, 0x8191, 0xC334, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDBB4, 0xFC8E, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xDBD3, 0xFC8D, 0xFC8D, 0xFC8D, 0xE3CE, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC11, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xCB2F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xEC11, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xC30F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF44F, 0xFC8D, 0xFC8D, 0xFC8D, 0xCB6F, 0x8191, 0x9A32, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC11, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xA250, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFC8E, 0xFC8F, 0xFCAF, 0xFCAF, 0xFCB0, 0xFCB0, 0xFCB0, 0xFCB2, 0xF451, 0xB0D1, 0xB0D1, 0xB0D1, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x003F, 0x003F, 0x005F, 0x025F, 0x06FD, 0x0770, 0x0F88, 0x07F4, 0x07FF, 0x5478, 0xA8F1, 0xA8F1, 0x5932, 0x4132, 0x4111, 0x3911, 0x3911, 0x30F0, 0x30F0, 0x30EF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F8, 0x18CF, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xB0F1, 0xB0F1, 0xB0D1, 0xFCAD, 0xFCCD, 0xFCAD, 0xFCAD, 0xFCCD, 0xFCCD, 0xFCCD, 0xCB4E, 0x8191, 0xAA73, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC31, 0xFCAD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xC32F, 0x8991, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF46F, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCAD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCAD, 0xFCAD, 0xFCAD, 0xC32F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xBB11, 0x8191, 0xAA73, 0xD396, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xDBB4, 0xFCAE, 0xFCAD, 0xFCCD, 0xFCAD, 0xFCCD, 0xFCAD, 0xFCCD, 0xFCCD, 0xFCAD, 0xFCAD, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xDBD3, 0xFCAD, 0xFCCD, 0xFCCD, 0xDBEE, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC31, 0xFCCD, 0xFCAD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCAD, 0xFCCD, 0xFCAD, 0xFCCD, 0xDBEE, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDBD3, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xC32F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF46F, 0xFCAD, 0xFCCD, 0xFCCD, 0xC32F, 0x8991, 0xAA94, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC31, 0xFCCD, 0xFCCD, 0xFCAD, 0xFCCD, 0xFCAD, 0xFCAD, 0xFCAD, 0xFCAD, 0xA270, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFCCE, 0xFCCF, 0xFCCF, 0xFCEF, 0xFCD0, 0xFCF0, 0xFCF1, 0xFCF1, 0xFCF2, 0xB0F1, 0xB0F1, 0xB0F2, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x003F, 0x005F, 0x007F, 0x021F, 0x06FC, 0x078D, 0x07E7, 0x07F6, 0x07FF, 0x82B5, 0xA8F1, 0xA111, 0x4932, 0x4132, 0x4111, 0x38F1, 0x38F0, 0x30F0, 0x30EF, 0x30EF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x00F6, 0x0119, 0x0118, 0x18CF, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xB0F1, 0xA8F1, 0xB0F1, 0xFD0D, 0xFCED, 0xFCED, 0xFCED, 0xFD0D, 0xFCED, 0xFD0D, 0xE42E, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC51, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xC34F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF48F, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xC32F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC6F, 0x91D1, 0x89D1, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xDBB4, 0xEC70, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFD0D, 0xFCED, 0xFCED, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDBF3, 0xFCED, 0xFCED, 0xFCED, 0xE42E, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC51, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFD0D, 0xFCED, 0xEC6E, 0x8191, 0x91F2, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD376, 0xD395, 0xD395, 0xF4AF, 0xFD0D, 0xFCED, 0xFD0D, 0xC34F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF48F, 0xFCED, 0xFCED, 0xFCED, 0xC34F, 0x8191, 0xAA93, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC51, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xA270, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFD0E, 0xFD0F, 0xFD0F, 0xFD0F, 0xFD10, 0xFD10, 0xFD31, 0xFD31, 0xFD32, 0xB0F1, 0xB0F1, 0xB0F1, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x005F, 0x005F, 0x005F, 0x021F, 0x073B, 0x07AC, 0x07E7, 0x07F7, 0x07FF, 0x82B5, 0xA8F1, 0x8912, 0x4932, 0x4112, 0x3911, 0x3911, 0x3110, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F6, 0x0119, 0x0118, 0x10CF, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xB0F1, 0xA8F1, 0xB0F1, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xE44E, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC71, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xC34F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF4CF, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xC34F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF4CF, 0xC34F, 0x8191, 0xB2D4, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDBD4, 0xE431, 0xEC71, 0xEC71, 0xDBF0, 0xE450, 0xF4CF, 0xFD0E, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDBD4, 0xF4AF, 0xF4CF, 0xF4AF, 0xDC10, 0x9A12, 0xAA73, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC71, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2C, 0xFD2C, 0x9211, 0x8191, 0xD375, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC71, 0xFCEE, 0xFD2D, 0xC36F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDC10, 0xE44E, 0xDC2E, 0xE44E, 0xB2F0, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC71, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xA270, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFD2E, 0xFD2F, 0xFD2F, 0xFD4F, 0xFD50, 0xFD50, 0xFD51, 0xFD51, 0xFD71, 0xA8F1, 0xB0F1, 0xB0F2, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x005F, 0x005F, 0x007F, 0x007F, 0x023F, 0x073B, 0x07AB, 0x07E8, 0x07F9, 0x07FF, 0xA152, 0xA8F1, 0x7132, 0x4132, 0x4131, 0x3911, 0x3910, 0x38F0, 0x30F0, 0x30EF, 0x28CF, 0x28CE, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F6, 0x0119, 0x0118, 0x18CF, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xA8F1, 0xA8F1, 0xA8F2, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD4D, 0xFD6D, 0xFD6D, 0xE46E, 0x8191, 0x9212, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC71, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xC36F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF4EF, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xC36F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF4EF, 0xFD2D, 0x9211, 0x89B2, 0xCB75, 0xD396, 0xD375, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC91, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xCB95, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC71, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD4D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xBB2F, 0x8191, 0xB2D4, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xC314, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC71, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xA290, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFD6E, 0xFD6F, 0xFD6F, 0xFD8F, 0xFD90, 0xFD90, 0xFD91, 0xFD91, 0xFD92, 0xA8F1, 0xA8F1, 0xA8F1, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x003F, 0x005F, 0x005F, 0x007F, 0x009F, 0x023F, 0x0779, 0x07AA, 0x07E8, 0x07FB, 0x07FF, 0xA8F1, 0xA8F1, 0x5932, 0x4932, 0x4131, 0x3911, 0x3910, 0x38F0, 0x30EF, 0x30EF, 0x28CF, 0x28CE, 0x28CE, 0x20CE, 0x20CE, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x0116, 0x0119, 0x0118, 0x18CF, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0xA8F1, 0xA8F1, 0xA8F1, 0xEC6F, 0xFD8D, 0xFDAD, 0xFD8D, 0xFDAD, 0xFDAD, 0xFDAD, 0xE48E, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC91, 0xFDAD, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xC38F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF52F, 0xFDAD, 0xFD8D, 0xFDAD, 0xFD8D, 0xFD8D, 0xFDAD, 0xFD8D, 0xFD8D, 0xFDAD, 0xFDAD, 0xC38F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF52F, 0xFD8D, 0xE4AE, 0x8991, 0x9A32, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xE491, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC91, 0xFDAD, 0xFDAD, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFDAD, 0xFDAD, 0xFD8D, 0xFD8D, 0xFDAD, 0xFDAD, 0xFD8D, 0xFDAD, 0xF52D, 0x8191, 0x91F2, 0xD395, 0xD395, 0xD395, 0xD395, 0xD376, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xC314, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC91, 0xFD8D, 0xFD8D, 0xFDAD, 0xFDAD, 0xFDAD, 0xFDAD, 0xFDAD, 0xFD8D, 0xA290, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFDAF, 0xFDAF, 0xFDAF, 0xFDAF, 0xFDB0, 0xFDB0, 0xFDB1, 0xFDD1, 0xE4B2, 0xA911, 0xA8F1, 0xA8F1, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x005F, 0x005F, 0x007F, 0x007F, 0x009F, 0x02BF, 0x0778, 0x07C8, 0x07E9, 0x07FD, 0x173E, 0xA8F1, 0x9912, 0x4932, 0x4932, 0x4131, 0x4111, 0x3911, 0x38F0, 0x30EF, 0x30EF, 0x28CF, 0x28CE, 0x28CE, 0x20CE, 0x20CE, 0x20CD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x00F7, 0x0119, 0x0118, 0x18CF, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xA911, 0xA911, 0xA911, 0xEC8E, 0xFDED, 0xFDED, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDED, 0xE4CE, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECB1, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xC3AF, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF54F, 0xFDCD, 0xFDCD, 0xFDED, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDED, 0xFDCD, 0xC3AF, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF54F, 0xFDED, 0xFDCD, 0xD44F, 0x8191, 0xB2B3, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xECB1, 0x8991, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECB1, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xBB6F, 0x8191, 0xBAF4, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xC314, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECB1, 0xFDED, 0xFDED, 0xFDCD, 0xFDCD, 0xFDED, 0xFDED, 0xFDED, 0xFDED, 0xA2B0, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xFDEE, 0xFDEF, 0xFDEF, 0xFDF0, 0xFDF0, 0xFDF0, 0xFDF1, 0xFDF1, 0xECB1, 0xA0F1, 0xA911, 0xA911, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x005F, 0x005F, 0x005F, 0x007F, 0x009F, 0x009F, 0x041F, 0x0797, 0x07C7, 0x07EB, 0x07FE, 0x2E5C, 0xA8F1, 0x7932, 0x4932, 0x4932, 0x4111, 0x3911, 0x3910, 0x38F0, 0x30EF, 0x30EF, 0x28CE, 0x28CE, 0x28CE, 0x20CE, 0x20CE, 0x20CD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00F7, 0x0118, 0x0117, 0x18CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xA911, 0xA911, 0xA111, 0xE42E, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xE4EE, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECD1, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xC3CF, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF56F, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xC3CF, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF56F, 0xFE0D, 0xFE0D, 0xFE0D, 0xD44F, 0x8191, 0xBAD3, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD376, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xECD1, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECD1, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xF5AD, 0x9A70, 0x89B1, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xC314, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECD1, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0E, 0xFE0D, 0xFE0E, 0xFE0E, 0xFE0E, 0xA2B0, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFE0F, 0xFE0F, 0xFE0F, 0xFE30, 0xFE30, 0xFE30, 0xFE31, 0xFE31, 0xDC32, 0xA111, 0xA911, 0xA111, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x005F, 0x005F, 0x007F, 0x007F, 0x009F, 0x00BF, 0x043F, 0x0794, 0x07E6, 0x07EC, 0x07FE, 0x35DB, 0xA911, 0x5133, 0x4932, 0x4132, 0x4111, 0x4111, 0x3910, 0x30F0, 0x30EF, 0x30EF, 0x28CE, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AC, 0x18AD, 0x18AE, 0x00F6, 0x0119, 0x00F8, 0x18CF, 0x20AD, 0x18AD, 0x20AD, 0x18AC, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x80F0, 0xA111, 0xA111, 0xC2B0, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xE50E, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECF1, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xC3EF, 0x8991, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xF58F, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xC3EF, 0x8191, 0xAA93, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF58F, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xE50E, 0x89D1, 0xA253, 0xCB75, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD376, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECF1, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECF1, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xF60E, 0x9A70, 0x91F2, 0xCB75, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xC314, 0x8191, 0xAA93, 0xD395, 0xD396, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECF2, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4E, 0xFE4D, 0xFE4E, 0xFE4D, 0xFE4E, 0xA2D0, 0x8191, 0xC314, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFE4E, 0xFE4F, 0xFE6F, 0xFE70, 0xFE50, 0xFE50, 0xFE71, 0xFE51, 0xBA52, 0xA111, 0xA111, 0x78D5, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x005F, 0x007F, 0x007F, 0x009F, 0x00BF, 0x00BF, 0x043F, 0x07B3, 0x07C5, 0x07EE, 0x07FF, 0x5478, 0x6AD6, 0x4953, 0x4932, 0x4912, 0x4111, 0x3911, 0x3910, 0x30F0, 0x30EF, 0x28CF, 0x28CE, 0x28CE, 0x28CE, 0x20CE, 0x20CD, 0x20CD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x00F6, 0x0118, 0x00F8, 0x18CF, 0x18AC, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AC, 0x60EF, 0xA111, 0xA111, 0xA112, 0xFE2D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xE54E, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xED11, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE8D, 0xC40F, 0x8191, 0xAA93, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xF5CF, 0xFE6D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE6D, 0xC40F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF5CE, 0xFE6D, 0xFE6D, 0xFE8D, 0xFE6C, 0xFE8D, 0xF62D, 0xC40F, 0x9A12, 0xB2D4, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECF1, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xED11, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE8D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6C, 0xFE8D, 0xFE6D, 0xFE2D, 0xBBCF, 0x89B1, 0xBAF4, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD396, 0xC314, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xED12, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xA2D0, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE90, 0xFE90, 0xFE90, 0xFE91, 0xE471, 0xA111, 0xA112, 0xA111, 0x60D5, 0x001F, 0x283C, 0x7097, 0x405A, 0x001F, 0x001F, 0x001F, 0x003F, 0x007F, 0x009F, 0x00BF, 0x00BF, 0x00DF, 0x045F, 0x07D2, 0x07E4, 0x07EF, 0x07FF, 0x2E3C, 0x2D1A, 0x5133, 0x4932, 0x4132, 0x3911, 0x3911, 0x38F0, 0x30F0, 0x30EF, 0x28CF, 0x28CE, 0x28CE, 0x20CE, 0x20CE, 0x20CD, 0x20CD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x00F6, 0x0118, 0x00F7, 0x18CF, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x28CD, 0xA111, 0xA111, 0xA111, 0xCBCF, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xF5ED, 0x89D1, 0x91D2, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xED11, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xC42F, 0x81B1, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF5EF, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFECC, 0xFEAD, 0xC42F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xF5EF, 0xFEAD, 0xFEAC, 0xFEAD, 0xFEAD, 0xFEAC, 0xFEAD, 0xFEAD, 0xF64D, 0xD4CE, 0xBBD0, 0xC3B2, 0xC314, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xED12, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xED31, 0xFEAC, 0xFEAC, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xEE0D, 0xCC6F, 0xBB51, 0xBAD4, 0xCB55, 0xD395, 0xD395, 0xD395, 0xD395, 0xC334, 0x8191, 0xB294, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xED11, 0xFEAE, 0xFECE, 0xFEAD, 0xFEAE, 0xFEAD, 0xFECE, 0xFEAE, 0xFEAE, 0xA2F0, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDC34, 0xFEAF, 0xFED0, 0xFEAF, 0xFED0, 0xFEB0, 0xFED1, 0xE491, 0xA911, 0xA111, 0x9931, 0xA111, 0x58D6, 0x88B5, 0xB8D1, 0xB8D1, 0x5059, 0x001F, 0x001F, 0x001F, 0x001F, 0x007F, 0x009F, 0x00BF, 0x00FF, 0x00DF, 0x047F, 0x07D2, 0x07E3, 0x07F1, 0x07FF, 0x07FF, 0x2CBA, 0x4933, 0x4132, 0x4131, 0x4111, 0x38F0, 0x38F0, 0x30F0, 0x30EF, 0x28EF, 0x28CE, 0x28CE, 0x20CE, 0x20CD, 0x20CD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x00F6, 0x0118, 0x0118, 0x18CF, 0x20AD, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AC, 0x20AD, 0x18AD, 0x8110, 0x9911, 0xA111, 0xA171, 0xF5ED, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAC, 0xFE6D, 0xF5CF, 0xF5EF, 0xF5CF, 0xF5CF, 0xF5EF, 0xF5CF, 0xFE4D, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFE4E, 0xF5EF, 0xF5EF, 0xF5CF, 0xF5EE, 0xF5EF, 0xF5EF, 0xF5EF, 0xFE8D, 0xFEAC, 0xFEAC, 0xFEAC, 0xFEAC, 0xFEAD, 0xFE8D, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAC, 0xFEAC, 0xFEAD, 0xF64D, 0xF5EF, 0xF5CF, 0xF5EF, 0xF5CF, 0xF5EF, 0xF5EF, 0xF5EF, 0xFE6E, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAC, 0xFEAC, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAC, 0xFEAD, 0xFEAD, 0xF60E, 0xF5EF, 0xF5CF, 0xF5EF, 0xF5EF, 0xF5CF, 0xF64E, 0xFEAC, 0xFEAD, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5CF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5CF, 0xFE4D, 0xFEAC, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAC, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAC, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFE6D, 0xF5EF, 0xF5EF, 0xF5CF, 0xF5CF, 0xFEAD, 0xF62E, 0xF5EF, 0xF5D0, 0xF5EF, 0xF5CF, 0xF5F0, 0xF5F0, 0xF5EF, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5EF, 0xF5F0, 0xFE4F, 0xFECE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAF, 0xF610, 0xF5D0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF610, 0xFEAF, 0xFEAF, 0xFEAF, 0xFED0, 0xFEB0, 0xFEB1, 0xE471, 0xB8D1, 0xA111, 0x9931, 0x9931, 0x9912, 0x6933, 0xB0F1, 0xB0D1, 0xB0D1, 0x283C, 0x001F, 0x001F, 0x001F, 0x003F, 0x007F, 0x00BF, 0x00DF, 0x00FF, 0x011F, 0x047F, 0x07D1, 0x07E3, 0x07F3, 0x07FF, 0x07FF, 0x3B77, 0x4932, 0x4932, 0x4131, 0x4111, 0x38F0, 0x38F0, 0x30EF, 0x30EF, 0x28EF, 0x28CE, 0x28CE, 0x20CE, 0x20CD, 0x20CD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x0118, 0x0117, 0x18CF, 0x18AD, 0x18AC, 0x18AC, 0x18AD, 0x18AC, 0x20AD, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18CD, 0x18AC, 0x20AC, 0x38CE, 0x9931, 0x9931, 0x9931, 0xAA31, 0xFE2D, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFEAD, 0xFE8C, 0xFEAC, 0xFEAC, 0xFE8C, 0xFE8C, 0xFEAC, 0xFEAD, 0xFE8D, 0xFE8C, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFE8C, 0xFE8C, 0xFEAC, 0xFEAC, 0xFEAD, 0xFE8C, 0xFEAD, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8C, 0xFEAD, 0xFE8C, 0xFE8C, 0xFEAD, 0xFEAD, 0xFEAC, 0xFEAC, 0xFE8C, 0xFE8C, 0xFEAC, 0xFE8C, 0xFEAC, 0xFEAD, 0xFEAD, 0xFE8D, 0xFE8C, 0xFEAD, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8D, 0xFEAC, 0xFE8C, 0xFEAC, 0xFE8D, 0xFEAD, 0xFEAD, 0xFE8C, 0xFEAC, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8C, 0xFEAC, 0xFE8D, 0xFE8C, 0xFEAD, 0xFEAD, 0xFE8C, 0xFE8C, 0xFE8C, 0xFEAD, 0xFE8C, 0xFEAC, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFE8C, 0xFEAC, 0xFE8D, 0xFEAC, 0xFEAD, 0xFEAD, 0xFE8C, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAC, 0xFE8C, 0xFEAD, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFEAD, 0xFEAD, 0xFEAD, 0xFE8D, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFE8D, 0xFE8E, 0xFEAD, 0xFEAE, 0xFEAE, 0xFEAD, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFE8E, 0xFE8E, 0xFEAE, 0xFEAE, 0xFEAE, 0xFE8E, 0xFEAE, 0xFEAE, 0xFEAE, 0xFE8E, 0xFE8E, 0xFEAE, 0xFEAF, 0xFEAE, 0xFEAE, 0xFEAF, 0xFE8E, 0xFEAF, 0xFEAF, 0xFEAF, 0xFEAF, 0xFEAF, 0xFE8F, 0xFEB0, 0xFEAF, 0xFEB0, 0xFE90, 0xE471, 0xB8D2, 0xA111, 0x9911, 0x9931, 0x9931, 0x7132, 0x7133, 0xB0F1, 0xB0D1, 0xB0D2, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x007F, 0x00DF, 0x00DF, 0x011F, 0x011F, 0x049F, 0x07F0, 0x07E2, 0x07F4, 0x07FF, 0x07FF, 0x3AF6, 0x4932, 0x4932, 0x4111, 0x3911, 0x3910, 0x38F0, 0x30EF, 0x30EF, 0x28EE, 0x28CE, 0x28CE, 0x20CE, 0x20CD, 0x20CD, 0x20AD, 0x20AD, 0x20AD, 0x18AC, 0x20AC, 0x18AD, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, + 0x0117, 0x18CF, 0x20AC, 0x20AC, 0x20AD, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x20AD, 0x20AC, 0x60EF, 0x9912, 0x9931, 0x9931, 0xB270, 0xF62D, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE6D, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8E, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8F, 0xFE8E, 0xFE8E, 0xFE8F, 0xFE8F, 0xFE8E, 0xFE8F, 0xFE8F, 0xFE8E, 0xFE8F, 0xFE8E, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE90, 0xFE90, 0xFEB0, 0xFEB0, 0xE471, 0xB8D1, 0xA111, 0x9931, 0x9931, 0x9912, 0x8911, 0x5174, 0x6953, 0xB0F1, 0xB0D1, 0x90B4, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x009F, 0x00DF, 0x00FF, 0x011F, 0x015F, 0x049F, 0x07F1, 0x07E2, 0x07F6, 0x07FF, 0x0F9F, 0x4A35, 0x4933, 0x4932, 0x4131, 0x3910, 0x3910, 0x38F0, 0x30EF, 0x30EF, 0x28CE, 0x28CE, 0x28CE, 0x20CD, 0x20CD, 0x20CD, 0x20AD, 0x20AD, 0x20AD, 0x18AC, 0x20AC, 0x20AC, 0x18AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, + 0x18CE, 0x18AC, 0x20CC, 0x20AC, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AD, 0x18CC, 0x20AD, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x28AD, 0x8110, 0x9931, 0x9931, 0x9911, 0xAA31, 0xF5CD, 0xFE8C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE8C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE8C, 0xFE6D, 0xFE6D, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6C, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE8E, 0xFE8D, 0xFE8D, 0xFE6E, 0xFE8D, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE8F, 0xFE8F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE8F, 0xFE6F, 0xFE6F, 0xFE8F, 0xFE8F, 0xFE6F, 0xFE6F, 0xFE8F, 0xFE6F, 0xFE6F, 0xFE8F, 0xFE8F, 0xFE6F, 0xFE8F, 0xFE8F, 0xFE6F, 0xFE90, 0xFE8F, 0xFE8F, 0xFE90, 0xFE90, 0xE471, 0xB0D1, 0xA111, 0x9931, 0x9931, 0x9931, 0x9912, 0x5953, 0x5153, 0x7133, 0xB0D1, 0xB0D1, 0x7896, 0x001F, 0x001F, 0x001F, 0x003F, 0x005F, 0x00BF, 0x011F, 0x011F, 0x013F, 0x017F, 0x04BF, 0x07F2, 0x07E2, 0x07F5, 0x07FF, 0x7336, 0x5153, 0x4933, 0x4932, 0x4131, 0x4110, 0x3910, 0x30EF, 0x30EF, 0x30EF, 0x28CE, 0x28CE, 0x28CD, 0x20CD, 0x20CD, 0x20CD, 0x20AD, 0x20AD, 0x20AD, 0x20AC, 0x20AC, 0x20AD, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, + 0x20AC, 0x20AC, 0x18AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x18AC, 0x28AD, 0x9111, 0x9931, 0x9931, 0x9931, 0xA171, 0xCBCF, 0xF60D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6C, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6C, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6C, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6E, 0xFE6E, 0xFE4E, 0xFE6D, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6F, 0xFE6E, 0xFE6E, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE70, 0xFE70, 0xFE6F, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE90, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE71, 0xFE71, 0xFE71, 0xE471, 0xA8F1, 0xA111, 0x9931, 0x9932, 0x9931, 0x9931, 0x6933, 0x5153, 0x5953, 0x7153, 0xB0D1, 0xB0D1, 0x5878, 0x001F, 0x001F, 0x003F, 0x007F, 0x009F, 0x00FF, 0x013F, 0x013F, 0x017F, 0x019F, 0x033F, 0x07F3, 0x07E2, 0x07F3, 0x07FF, 0xA8F1, 0x6932, 0x4932, 0x4932, 0x4931, 0x4111, 0x3910, 0x3110, 0x30EF, 0x30EF, 0x28CE, 0x28CE, 0x28CD, 0x20CD, 0x20CD, 0x20CD, 0x20AD, 0x20AD, 0x20AD, 0x20AC, 0x20AC, 0x20AD, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, + 0x18CC, 0x18AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x18AC, 0x20AC, 0x28CD, 0x8111, 0x9931, 0x9912, 0x9931, 0x9931, 0x9911, 0xBAB0, 0xDC6F, 0xE50F, 0xE50E, 0xFE4E, 0xFE6E, 0xFE4E, 0xFE6D, 0xFE4E, 0xFE4E, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4E, 0xFE4E, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4E, 0xFE4E, 0xFE4E, 0xFE4E, 0xFE6E, 0xFE6E, 0xFE4E, 0xFE4E, 0xFE4E, 0xFE6E, 0xFE6E, 0xFE4E, 0xFE6F, 0xFE6E, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE4F, 0xFE6F, 0xFE70, 0xFE50, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xF612, 0xE531, 0xE512, 0xD472, 0xB271, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9911, 0x6153, 0x5153, 0x5954, 0x5954, 0x7154, 0xB0F1, 0xB0F1, 0x285C, 0x003F, 0x005F, 0x007F, 0x00BF, 0x00FF, 0x013F, 0x015F, 0x017F, 0x019F, 0x01BF, 0x02FF, 0x07F4, 0x07E3, 0x07F1, 0x2E5C, 0xA911, 0x6932, 0x5132, 0x4931, 0x4132, 0x4110, 0x3910, 0x3910, 0x30EF, 0x30EE, 0x28CE, 0x28CE, 0x28CD, 0x20CD, 0x20CD, 0x20CD, 0x20AC, 0x20AD, 0x20AD, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, + 0x20AC, 0x18AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x28CC, 0x610F, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9932, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9912, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9911, 0x9931, 0x9931, 0x9911, 0x9911, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9911, 0x9931, 0x9932, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9912, 0x9931, 0x9931, 0x9931, 0x9931, 0x8912, 0x5153, 0x5953, 0x5153, 0x5974, 0x5974, 0x7953, 0xB0F1, 0xB0D1, 0x087F, 0x009F, 0x00BF, 0x00DF, 0x011F, 0x015F, 0x019F, 0x019F, 0x019F, 0x01DF, 0x01DF, 0x01FF, 0x07F7, 0x07E3, 0x07EF, 0x5498, 0xA8F1, 0x7132, 0x4952, 0x4931, 0x4131, 0x4110, 0x3910, 0x30EF, 0x30EF, 0x30EE, 0x28CE, 0x28CE, 0x28CD, 0x20CD, 0x20CD, 0x20CD, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, + 0x20AC, 0x18AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x40CE, 0x7910, 0x9931, 0x9931, 0x9932, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0xA111, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9912, 0x7132, 0x5153, 0x5153, 0x5153, 0x5974, 0x5974, 0x6174, 0x9113, 0xB0F1, 0x98F3, 0x00DF, 0x00FF, 0x011F, 0x013F, 0x017F, 0x01BF, 0x01BF, 0x01DF, 0x01DF, 0x01FF, 0x01FF, 0x021F, 0x06D9, 0x07E5, 0x07EC, 0x7355, 0xA8F1, 0x7932, 0x4932, 0x4931, 0x4131, 0x4110, 0x3910, 0x390F, 0x30EF, 0x30EE, 0x28CE, 0x28CE, 0x28CD, 0x28CD, 0x20CD, 0x20CD, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, + 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AB, 0x30CC, 0x58CF, 0x7910, 0x9931, 0x9931, 0x9912, 0x9931, 0x9931, 0x9911, 0x9931, 0x9911, 0x9932, 0x9931, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9911, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0xA111, 0x9911, 0x8932, 0x6932, 0x5152, 0x5153, 0x5953, 0x5953, 0x5974, 0x6174, 0x6175, 0x7954, 0xA8F1, 0xB0F1, 0x80F5, 0x013F, 0x017F, 0x019F, 0x01BF, 0x01DF, 0x01FF, 0x01DF, 0x01FF, 0x021F, 0x023F, 0x023F, 0x023F, 0x057D, 0x07E8, 0x07E9, 0x82D5, 0xA0F1, 0x8132, 0x5132, 0x4931, 0x4131, 0x4110, 0x38F0, 0x38EF, 0x30EF, 0x30EE, 0x28CE, 0x28CD, 0x28CD, 0x28CD, 0x20CD, 0x20CD, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, + 0x18AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18CC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20CC, 0x20AD, 0x20CD, 0x20CD, 0x28CD, 0x28CD, 0x28CD, 0x28CD, 0x28CD, 0x28CE, 0x28EE, 0x28EE, 0x30EE, 0x30EF, 0x30EF, 0x30EE, 0x38EF, 0x5110, 0x6110, 0x5910, 0x6930, 0x7931, 0x8131, 0x8130, 0x9931, 0xA932, 0xA131, 0xB131, 0xC912, 0xC911, 0xC8F2, 0xC8F2, 0xC8F2, 0xC8D1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xB8B1, 0xC0D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0F1, 0x5158, 0x01BF, 0x01DF, 0x01FF, 0x021F, 0x023F, 0x023F, 0x021F, 0x023F, 0x025F, 0x025F, 0x025F, 0x025F, 0x041F, 0x07ED, 0x07E4, 0x7AB4, 0xA911, 0x9112, 0x5132, 0x4931, 0x4111, 0x4110, 0x3910, 0x38EF, 0x30EF, 0x30EE, 0x30EE, 0x28CD, 0x28CD, 0x28CD, 0x20CD, 0x20CC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, + 0x20CC, 0x20AC, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AB, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20CC, 0x20CD, 0x20CD, 0x28CD, 0x28CD, 0x28CD, 0x28CD, 0x28AD, 0x28CE, 0x30CE, 0x30CE, 0x30EE, 0x8151, 0xB192, 0xC9B3, 0xC9B2, 0xC992, 0xC992, 0xC992, 0xC972, 0xC972, 0xC972, 0xC952, 0xC952, 0xC932, 0xC932, 0xC932, 0xC912, 0xC912, 0xC111, 0xC8F1, 0xC8F1, 0xC8D1, 0xC0D1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xB8B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D2, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xA8F1, 0x39BB, 0x021F, 0x023F, 0x025F, 0x027F, 0x027F, 0x025F, 0x025F, 0x027F, 0x027F, 0x027F, 0x027F, 0x027F, 0x029F, 0x07F3, 0x07E2, 0x9972, 0xA911, 0xA112, 0x4952, 0x4932, 0x4131, 0x4110, 0x3910, 0x38EF, 0x30EF, 0x30EE, 0x30EE, 0x28CD, 0x28CD, 0x28CD, 0x20CD, 0x20CC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, + 0x20AB, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x18CC, 0x18AC, 0x20AB, 0x20AC, 0x20AC, 0x20AB, 0x20AC, 0x20AC, 0x18AC, 0x20AB, 0x20AB, 0x20AC, 0x20AC, 0x20AB, 0x20AB, 0x20AC, 0x20AC, 0x20AB, 0x20AB, 0x20AC, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20CC, 0x20CC, 0x20CC, 0x28CD, 0x28CD, 0x28CD, 0x28CD, 0x30CD, 0x28EE, 0x30EE, 0x490E, 0xA9B2, 0xC9D3, 0xC9D3, 0xC9B3, 0xC9B3, 0xC992, 0xC992, 0xC972, 0xC972, 0xC972, 0xC952, 0xC952, 0xC952, 0xC932, 0xC932, 0xC912, 0xC912, 0xC912, 0xC0F2, 0xC8D1, 0xC0D1, 0xC0D1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB0D1, 0xB8D2, 0xB8D1, 0xB0F1, 0xB0D1, 0xB0F2, 0xB0F1, 0xB0F1, 0xB0F1, 0xA8F1, 0xA8F1, 0x123E, 0x029F, 0x02BF, 0x02BF, 0x02BF, 0x029F, 0x029F, 0x029F, 0x02BF, 0x02BF, 0x02BF, 0x029F, 0x029F, 0x02DF, 0x06B9, 0x07E3, 0xA111, 0xA911, 0xA111, 0x5932, 0x4931, 0x4911, 0x4110, 0x4110, 0x390F, 0x38EF, 0x30EE, 0x30EE, 0x28CD, 0x28CD, 0x28CD, 0x20CD, 0x20CC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, + 0x20AB, 0x20AC, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AB, 0x20AC, 0x20AB, 0x20AC, 0x20AC, 0x20AB, 0x20AB, 0x18AC, 0x20AC, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x18AB, 0x20AB, 0x20AB, 0x20AC, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20CC, 0x20CD, 0x28CD, 0x28CD, 0x28CD, 0x28CD, 0x28CD, 0x28CD, 0x30ED, 0x692F, 0xC9D3, 0xC9D3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC992, 0xC992, 0xC972, 0xC972, 0xC972, 0xC952, 0xC952, 0xC932, 0xC932, 0xC132, 0xC912, 0xC912, 0xC8F2, 0xC8F1, 0xC8D1, 0xC0D1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB8D1, 0xB0F1, 0xB0D1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xA8F1, 0x9933, 0x02DF, 0x02DF, 0x02FF, 0x02FF, 0x02DF, 0x02BF, 0x02DF, 0x02DF, 0x02DF, 0x02DF, 0x02DF, 0x02BF, 0x02BF, 0x02FF, 0x051E, 0x07E8, 0xA912, 0xA111, 0xA111, 0x6932, 0x4931, 0x4931, 0x4130, 0x410F, 0x390F, 0x38EE, 0x30EE, 0x30EE, 0x28CD, 0x28CD, 0x28CD, 0x20CD, 0x20CC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AB, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, + 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x28AC, 0x20CC, 0x28CC, 0x28CC, 0x28CC, 0x28CD, 0x28CD, 0x28ED, 0x28CD, 0x30CD, 0x9191, 0xC9D3, 0xC9D3, 0xC9B3, 0xC9B3, 0xC992, 0xC9B3, 0xC992, 0xC992, 0xC972, 0xC972, 0xC952, 0xC952, 0xC932, 0xC932, 0xC912, 0xC932, 0xC912, 0xC112, 0xC8F2, 0xC8F2, 0xC8D1, 0xC8D1, 0x9095, 0x9095, 0x9075, 0x8875, 0x6078, 0x6059, 0x6059, 0x6058, 0x6058, 0x6078, 0x6078, 0x6059, 0x6078, 0x6078, 0x5878, 0x6078, 0x88B4, 0x88B5, 0x88B5, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0F1, 0xB0F1, 0xB0D1, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xA8F1, 0xA8F1, 0xA8F1, 0x69D6, 0x033F, 0x033F, 0x033F, 0x031F, 0x02FF, 0x02FF, 0x02FF, 0x02FF, 0x02FF, 0x02FF, 0x02FF, 0x02DF, 0x02FF, 0x035F, 0x03FF, 0x07F0, 0x8A4F, 0xA111, 0xA111, 0x8132, 0x4931, 0x4931, 0x4110, 0x410F, 0x390F, 0x30EE, 0x30EE, 0x30CD, 0x30CD, 0x28CD, 0x28CD, 0x28CC, 0x28CC, 0x20CC, 0x20AC, 0x20AC, 0x20AC, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, + 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CC, 0x20AC, 0x28CC, 0x28CC, 0x28CC, 0x20CC, 0x28CC, 0x28CC, 0x28CD, 0x40EE, 0xA9B2, 0xC9D3, 0xC9D3, 0xC9B3, 0xC9B2, 0xC9B3, 0xC992, 0xC992, 0xC972, 0xC972, 0xC952, 0xC952, 0xC952, 0xC932, 0xC932, 0x90D5, 0x88D6, 0x6098, 0x5879, 0x303C, 0x305C, 0x081E, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x005F, 0x007F, 0x009F, 0x00BF, 0x00DF, 0x291C, 0x411A, 0x6118, 0x8915, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F2, 0xA8F1, 0xB0F1, 0x429A, 0x039F, 0x039F, 0x035F, 0x035F, 0x033F, 0x033F, 0x033F, 0x033F, 0x033F, 0x033F, 0x031F, 0x031F, 0x031F, 0x037F, 0x03FF, 0x06D7, 0x7ACF, 0xA111, 0xA111, 0x9912, 0x5131, 0x4931, 0x4110, 0x410F, 0x40EF, 0x38EE, 0x30EE, 0x30ED, 0x30CD, 0x28CD, 0x28CD, 0x28CC, 0x28CC, 0x20CC, 0x20CC, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, + 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x20CB, 0x28CC, 0x28CC, 0x28CC, 0x28CD, 0x28CC, 0x490E, 0xC1D3, 0xC9D3, 0xC9D3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC992, 0xC992, 0xC972, 0xC952, 0x98F5, 0x60B8, 0x407B, 0x183E, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x003F, 0x007F, 0x007F, 0x009F, 0x00BF, 0x00FF, 0x011F, 0x013F, 0x017F, 0x019F, 0x01DF, 0x021F, 0x21FD, 0x49D9, 0x7996, 0xA112, 0xA8F1, 0xB0F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0x139E, 0x03DF, 0x03BF, 0x039F, 0x039F, 0x037F, 0x037F, 0x037F, 0x037F, 0x035F, 0x035F, 0x033F, 0x033F, 0x035F, 0x03BF, 0x041F, 0x05DE, 0x7AD1, 0xA111, 0xA111, 0xA111, 0x5931, 0x4931, 0x4130, 0x4130, 0x40EF, 0x38EE, 0x30EE, 0x30ED, 0x30ED, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, + 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x692F, 0xC9F3, 0xC9D3, 0xC9D3, 0xC9B2, 0xC9B3, 0xC992, 0xC9B2, 0xC972, 0xB973, 0x80F7, 0x387B, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x003F, 0x005F, 0x007F, 0x009F, 0x00BF, 0x00DF, 0x00FF, 0x013F, 0x015F, 0x019F, 0x01BF, 0x01FF, 0x023F, 0x025F, 0x029F, 0x02DF, 0x02FF, 0x033F, 0x2ADC, 0x5A58, 0x8994, 0xA8F1, 0xA8F1, 0x81D4, 0x041F, 0x041F, 0x03FF, 0x03DF, 0x03BF, 0x03BF, 0x03BF, 0x03BF, 0x03BF, 0x039F, 0x037F, 0x035F, 0x037F, 0x039F, 0x03FF, 0x047F, 0x04FF, 0x6375, 0xA112, 0xA111, 0xA111, 0x7111, 0x4931, 0x4110, 0x4110, 0x390F, 0x38EE, 0x30EE, 0x30ED, 0x30ED, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, + 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x28AC, 0x28CC, 0x28CC, 0x28CC, 0x692E, 0xC9F3, 0xC9D2, 0xC9D3, 0xC9B3, 0xC9B3, 0xC992, 0xC993, 0x80F7, 0x389B, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x083C, 0x085B, 0x105B, 0x2078, 0x2098, 0x2097, 0x2097, 0x2097, 0x2097, 0x2097, 0x2098, 0x187A, 0x105B, 0x085D, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x005F, 0x007F, 0x009F, 0x00DF, 0x00FF, 0x011F, 0x015F, 0x017F, 0x01BF, 0x01FF, 0x021F, 0x025F, 0x029F, 0x02DF, 0x02FF, 0x033F, 0x037F, 0x03BF, 0x03DF, 0x041F, 0x043F, 0x0C3F, 0x2BBC, 0x0C3F, 0x045F, 0x043F, 0x041F, 0x041F, 0x03FF, 0x03FF, 0x03FF, 0x03DF, 0x03DF, 0x03BF, 0x039F, 0x037F, 0x039F, 0x03DF, 0x043F, 0x04BF, 0x053F, 0x5398, 0xA111, 0xA111, 0xA111, 0x9111, 0x4931, 0x4910, 0x4110, 0x410F, 0x38EE, 0x38EE, 0x30ED, 0x30CD, 0x30CD, 0x28CC, 0x28CC, 0x28CC, 0x28CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x28CB, 0x28CB, 0x28CC, 0x28CB, 0x614E, 0xD1F3, 0xC9F3, 0xC9D3, 0xC9B2, 0xC9B3, 0xB173, 0x60D9, 0x081E, 0x003D, 0x083B, 0x1878, 0x1877, 0x28D2, 0x28D2, 0x40EE, 0x38EE, 0x390F, 0x390F, 0x390F, 0x410E, 0x410F, 0x410F, 0x410F, 0x410F, 0x410F, 0x410F, 0x410F, 0x4110, 0x410F, 0x4910, 0x4130, 0x38F3, 0x28B6, 0x189A, 0x003E, 0x001F, 0x001F, 0x003F, 0x005F, 0x005F, 0x007F, 0x00BF, 0x00DF, 0x00FF, 0x013F, 0x015F, 0x019F, 0x01DF, 0x021F, 0x023F, 0x027F, 0x029F, 0x02FF, 0x033F, 0x035F, 0x039F, 0x03DF, 0x041F, 0x045F, 0x047F, 0x04BF, 0x04DF, 0x04DF, 0x04BF, 0x04BF, 0x047F, 0x047F, 0x043F, 0x043F, 0x043F, 0x041F, 0x041F, 0x03FF, 0x03DF, 0x03BF, 0x03BF, 0x03DF, 0x043F, 0x047F, 0x04DF, 0x057F, 0x3C1A, 0xA111, 0xA111, 0xA111, 0xA111, 0x5931, 0x4910, 0x4110, 0x410F, 0x390E, 0x38EE, 0x30ED, 0x30ED, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x28CB, 0x20CB, 0x28AB, 0x692E, 0xC9D3, 0xC9D3, 0xC9D3, 0xC9B3, 0xB1B2, 0x58F3, 0x1895, 0x28B2, 0x30ED, 0x38ED, 0x30ED, 0x38ED, 0x38ED, 0x38ED, 0x38EE, 0x390E, 0x390E, 0x38EE, 0x38EE, 0x390E, 0x390E, 0x390E, 0x390E, 0x410F, 0x390E, 0x410F, 0x410F, 0x410F, 0x410F, 0x410F, 0x410F, 0x4110, 0x410F, 0x492F, 0x4930, 0x4910, 0x38F3, 0x20B8, 0x087D, 0x007F, 0x009F, 0x00DF, 0x00FF, 0x011F, 0x015F, 0x017F, 0x019F, 0x01DF, 0x021F, 0x025F, 0x02BF, 0x02DF, 0x031F, 0x035F, 0x039F, 0x03DF, 0x041F, 0x045F, 0x049F, 0x04DF, 0x04FF, 0x051F, 0x051F, 0x053F, 0x04FF, 0x04DF, 0x04BF, 0x049F, 0x047F, 0x047F, 0x045F, 0x045F, 0x043F, 0x041F, 0x03FF, 0x03DF, 0x03FF, 0x043F, 0x045F, 0x04BF, 0x053F, 0x05BF, 0x2CDC, 0xA112, 0xA111, 0xA111, 0xA111, 0x7131, 0x4930, 0x4130, 0x410F, 0x390E, 0x38EE, 0x30ED, 0x30ED, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x28AB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x28AB, 0x28CB, 0x28CB, 0x612E, 0xC9F3, 0xC9D3, 0xC9D3, 0xB992, 0x692E, 0x28CC, 0x28EC, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x38ED, 0x30ED, 0x38ED, 0x38ED, 0x390E, 0x38EE, 0x38EE, 0x38EE, 0x390F, 0x38EE, 0x40EE, 0x40EE, 0x390F, 0x390E, 0x410E, 0x40EF, 0x410F, 0x410F, 0x410F, 0x410F, 0x410F, 0x410F, 0x410F, 0x412F, 0x4910, 0x4910, 0x4930, 0x4113, 0x28F8, 0x08FE, 0x013F, 0x015F, 0x019F, 0x01DF, 0x021F, 0x023F, 0x029F, 0x02BF, 0x031F, 0x035F, 0x039F, 0x03DF, 0x041F, 0x045F, 0x049F, 0x04DF, 0x051F, 0x053F, 0x057F, 0x059F, 0x057F, 0x055F, 0x053F, 0x04FF, 0x04FF, 0x04DF, 0x04BF, 0x049F, 0x049F, 0x047F, 0x045F, 0x043F, 0x041F, 0x041F, 0x043F, 0x045F, 0x04BF, 0x04FF, 0x055F, 0x05DF, 0x0E1F, 0xA111, 0xA111, 0xA111, 0xA112, 0x8931, 0x4930, 0x4130, 0x410F, 0x410E, 0x38EE, 0x30ED, 0x30ED, 0x30CC, 0x28CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20CB, 0x20AB, 0x20AB, 0x20CB, 0x28AB, 0x20CB, 0x612E, 0xD1F3, 0xC9F3, 0xC1B2, 0x612E, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x38ED, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x390E, 0x38EE, 0x390E, 0x390E, 0x390E, 0x410F, 0x410F, 0x410F, 0x410F, 0x410F, 0x410F, 0x4130, 0x4930, 0x4930, 0x4931, 0x4930, 0x4133, 0x197A, 0x01DE, 0x021F, 0x027F, 0x02BF, 0x02FF, 0x033F, 0x037F, 0x03BF, 0x03FF, 0x045F, 0x049F, 0x04DF, 0x051F, 0x057F, 0x059F, 0x05DF, 0x05DF, 0x05DF, 0x05BF, 0x059F, 0x055F, 0x055F, 0x053F, 0x051F, 0x04FF, 0x04DF, 0x04DF, 0x04BF, 0x047F, 0x045F, 0x043F, 0x043F, 0x047F, 0x04BF, 0x04FF, 0x053F, 0x05BF, 0x061F, 0x069F, 0x9972, 0xA111, 0xA111, 0xA111, 0xA111, 0x5130, 0x4910, 0x410F, 0x390F, 0x390E, 0x38ED, 0x30ED, 0x30CD, 0x28CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20CB, 0x28AB, 0x510D, 0xD1F3, 0xC9D2, 0x816F, 0x30CC, 0x28AC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x30CD, 0x30ED, 0x30ED, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x38ED, 0x38ED, 0x38ED, 0x38ED, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x390E, 0x390E, 0x390E, 0x390E, 0x390E, 0x410F, 0x410F, 0x410F, 0x410F, 0x4110, 0x410F, 0x4910, 0x4930, 0x4930, 0x4930, 0x4931, 0x4932, 0x31B6, 0x0A9D, 0x02FF, 0x035F, 0x039F, 0x03FF, 0x043F, 0x047F, 0x04BF, 0x051F, 0x055F, 0x05BF, 0x05DF, 0x061F, 0x063F, 0x063F, 0x05FF, 0x05DF, 0x05BF, 0x059F, 0x059F, 0x057F, 0x055F, 0x053F, 0x051F, 0x04FF, 0x04DF, 0x04BF, 0x047F, 0x047F, 0x047F, 0x049F, 0x04DF, 0x053F, 0x057F, 0x05FF, 0x065F, 0x06DF, 0x7A95, 0xA111, 0xA111, 0xA111, 0xA111, 0x6911, 0x4930, 0x410F, 0x410F, 0x390E, 0x38EE, 0x30ED, 0x30CD, 0x28CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20CB, 0x20CB, 0x20AB, 0x20AB, 0x40EC, 0xC1D2, 0xC1B3, 0x490D, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x30EC, 0x30CD, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x38ED, 0x38ED, 0x38ED, 0x38ED, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x390E, 0x390E, 0x390F, 0x410F, 0x410F, 0x410F, 0x410F, 0x4910, 0x4910, 0x4930, 0x4931, 0x4951, 0x4951, 0x39D5, 0x131C, 0x041F, 0x047F, 0x04BF, 0x051F, 0x055F, 0x059F, 0x05DF, 0x061F, 0x067F, 0x069F, 0x069F, 0x067F, 0x065F, 0x061F, 0x05FF, 0x05FF, 0x05BF, 0x059F, 0x057F, 0x055F, 0x053F, 0x051F, 0x04FF, 0x04DF, 0x04BF, 0x04BF, 0x04BF, 0x04DF, 0x051F, 0x057F, 0x05BF, 0x063F, 0x069F, 0x071F, 0x5438, 0xA111, 0xA111, 0xA111, 0xA111, 0x8111, 0x4930, 0x410F, 0x410F, 0x390E, 0x38EE, 0x30ED, 0x30ED, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x30CB, 0xA992, 0xA9B1, 0x30CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x30CC, 0x30CC, 0x30EC, 0x30EC, 0x30CD, 0x30ED, 0x30ED, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x38ED, 0x38ED, 0x38ED, 0x38ED, 0x38EE, 0x38EE, 0x38EE, 0x390E, 0x390E, 0x390E, 0x410F, 0x410F, 0x410F, 0x410F, 0x410F, 0x412F, 0x4930, 0x4930, 0x5130, 0x4931, 0x5131, 0x3A15, 0x237B, 0x053F, 0x059F, 0x5358, 0x349B, 0x0E1F, 0x06BF, 0x06FF, 0x06FF, 0x06DF, 0x06BF, 0x069F, 0x065F, 0x063F, 0x061F, 0x05FF, 0x05DF, 0x05BF, 0x059F, 0x057F, 0x055F, 0x051F, 0x04FF, 0x04DF, 0x04DF, 0x04FF, 0x051F, 0x055F, 0x059F, 0x05FF, 0x065F, 0x06DF, 0x073F, 0x359B, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0x4930, 0x4910, 0x412F, 0x390E, 0x38EE, 0x30ED, 0x30ED, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x692F, 0x816F, 0x20AB, 0x20CB, 0x20AB, 0x28CB, 0x28CB, 0x28CB, 0x28AB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x30CC, 0x30CD, 0x30CD, 0x30CD, 0x30CD, 0x30CD, 0x30CD, 0x30CD, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x38ED, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x390E, 0x390E, 0x410F, 0x410F, 0x410F, 0x410F, 0x412F, 0x4930, 0x4930, 0x4930, 0x4931, 0x4931, 0x5131, 0x49D4, 0x243A, 0xA132, 0xA8F1, 0xA8F1, 0xA8F1, 0x8295, 0x8295, 0x5418, 0x351B, 0x06DF, 0x069F, 0x067F, 0x065F, 0x063F, 0x05FF, 0x05FF, 0x05BF, 0x059F, 0x057F, 0x055F, 0x053F, 0x051F, 0x051F, 0x053F, 0x057F, 0x059F, 0x05DF, 0x063F, 0x069F, 0x06FF, 0x077F, 0x0F5F, 0xA111, 0xA111, 0xA111, 0xA111, 0x9931, 0x6911, 0x4930, 0x410F, 0x390E, 0x38EE, 0x30ED, 0x30ED, 0x30CD, 0x30CC, 0x28CC, 0x28CB, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20CB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20CB, 0x20AB, 0x28CB, 0x28AB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x30CC, 0x30CC, 0x30CD, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30EE, 0x38ED, 0x38ED, 0x390E, 0x390E, 0x390E, 0x410E, 0x410F, 0x410F, 0x410F, 0x410F, 0x4130, 0x4930, 0x4930, 0x4930, 0x5131, 0x5131, 0x6992, 0xA8F1, 0xA911, 0xA8F1, 0xA911, 0xA8F1, 0xA8F1, 0xA8F1, 0xA172, 0x4C39, 0x2D5C, 0x069F, 0x065F, 0x063F, 0x061F, 0x05FF, 0x05DF, 0x059F, 0x057F, 0x055F, 0x055F, 0x055F, 0x057F, 0x059F, 0x05DF, 0x061F, 0x067F, 0x06DF, 0x073F, 0x079F, 0x07DF, 0x8254, 0xA111, 0xA131, 0xA111, 0x9911, 0x8131, 0x4910, 0x410F, 0x410E, 0x38EE, 0x38ED, 0x30ED, 0x30CD, 0x30CC, 0x28CC, 0x28CB, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x28AB, 0x28AB, 0x20CB, 0x20CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30EC, 0x30EC, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x390E, 0x390F, 0x410F, 0x410F, 0x410F, 0x412F, 0x4930, 0x4910, 0x4930, 0x5131, 0x5131, 0x6931, 0xA111, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA911, 0xA111, 0xA911, 0xA0F1, 0x9972, 0x4419, 0x067F, 0x065F, 0x061F, 0x05FF, 0x05DF, 0x05BF, 0x059F, 0x059F, 0x05BF, 0x05BF, 0x05DF, 0x061F, 0x065F, 0x06BF, 0x06FF, 0x075F, 0x07BF, 0x07FF, 0x5498, 0xA131, 0xA111, 0xA111, 0xA111, 0x9911, 0x4930, 0x410F, 0x410F, 0x38EE, 0x38EE, 0x30ED, 0x30CD, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20CA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20AB, 0x20AB, 0x28CB, 0x20CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x30CC, 0x30EC, 0x30EC, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x38ED, 0x38EE, 0x390E, 0x390E, 0x390E, 0x390F, 0x410F, 0x410F, 0x490F, 0x412F, 0x4910, 0x4930, 0x4931, 0x4931, 0x5931, 0x9111, 0xA8F1, 0xA8F1, 0xA911, 0xA8F1, 0xA8F1, 0xA911, 0xA911, 0xA911, 0xA111, 0x7A55, 0x34BB, 0x065F, 0x061F, 0x05FF, 0x05DF, 0x05DF, 0x05DF, 0x05DF, 0x05FF, 0x063F, 0x065F, 0x069F, 0x06DF, 0x071F, 0x077F, 0x07BF, 0x07FF, 0x2E3C, 0x9911, 0xA111, 0xA111, 0x9931, 0x9931, 0x6910, 0x410F, 0x410F, 0x38EE, 0x38EE, 0x30ED, 0x30ED, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x30EC, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x390E, 0x410F, 0x410F, 0x410F, 0x410F, 0x4910, 0x4930, 0x4931, 0x5131, 0x7931, 0xA911, 0xA8F1, 0xA911, 0xA911, 0xA911, 0xA911, 0xA8F1, 0xA111, 0xA111, 0xA111, 0xA111, 0x91B3, 0x62F6, 0x347B, 0x061F, 0x061F, 0x063F, 0x063F, 0x065F, 0x067F, 0x06BF, 0x071F, 0x073F, 0x079F, 0x07DF, 0x07FF, 0x07FF, 0xA111, 0x9912, 0x9911, 0x9931, 0x9932, 0x8131, 0x4130, 0x410F, 0x410E, 0x38EE, 0x30EE, 0x30ED, 0x30CD, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x28CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20AB, 0x28AB, 0x28AB, 0x28AB, 0x28AB, 0x28AB, 0x28AB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x390F, 0x410F, 0x410F, 0x410F, 0x4910, 0x4930, 0x4930, 0x4930, 0x7111, 0xA911, 0xA911, 0xA911, 0xA911, 0xA111, 0xA911, 0xA911, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0x91B3, 0x349B, 0x065F, 0x067F, 0x069F, 0x06BF, 0x06FF, 0x073F, 0x077F, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x7AD4, 0xA111, 0x9911, 0xA111, 0x9931, 0x9931, 0x4930, 0x410F, 0x390E, 0x38EE, 0x30EE, 0x30ED, 0x30ED, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x28CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x28AB, 0x28AB, 0x28AB, 0x28AB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x28CB, 0x28CB, 0x20CB, 0x20CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x30EC, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x38ED, 0x38EE, 0x38EE, 0x390E, 0x390E, 0x410F, 0x410F, 0x4110, 0x4930, 0x4930, 0x5130, 0x8111, 0xA111, 0xA911, 0xA111, 0xA111, 0xA911, 0xA112, 0xA111, 0xA911, 0xA111, 0xA112, 0xA0F1, 0xA111, 0xA111, 0xA111, 0x7A75, 0x15FD, 0x06BF, 0x06FF, 0x071F, 0x075F, 0x079F, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x5499, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x6930, 0x410F, 0x390E, 0x390E, 0x38EE, 0x30ED, 0x30CD, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x28AB, 0x20AB, 0x28AB, 0x28AB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30EC, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x38ED, 0x38EE, 0x38EE, 0x40EE, 0x410F, 0x410F, 0x410F, 0x4130, 0x4930, 0x4930, 0x5931, 0x90F1, 0xA911, 0xA912, 0xA111, 0xA111, 0xA111, 0xA911, 0xA911, 0xA111, 0xA112, 0xA111, 0xA111, 0xA111, 0xA111, 0x9972, 0x353B, 0x071F, 0x073F, 0x077F, 0x07BF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x2E3C, 0xA111, 0x9931, 0x9931, 0x9931, 0x9931, 0x8931, 0x410F, 0x410F, 0x38EE, 0x38EE, 0x30ED, 0x30ED, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x28AB, 0x20CB, 0x20CB, 0x20CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CD, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x38EE, 0x390E, 0x390E, 0x390E, 0x410F, 0x410F, 0x412F, 0x4130, 0x4930, 0x4930, 0x8111, 0xA911, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA112, 0xA112, 0xA111, 0xA111, 0x4499, 0x077F, 0x079F, 0x07BF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x9931, 0xA111, 0x9931, 0x9931, 0x9931, 0x9931, 0x490F, 0x410F, 0x38EE, 0x30EE, 0x38ED, 0x30ED, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x28AB, 0x28AB, 0x20CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x30CD, 0x30CD, 0x30ED, 0x30ED, 0x38ED, 0x310E, 0x38EE, 0x390E, 0x390E, 0x410F, 0x410F, 0x412F, 0x4930, 0x4930, 0x7131, 0xA111, 0xA111, 0xA112, 0xA111, 0xA0F1, 0xA111, 0xA111, 0xA112, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA131, 0x6397, 0x07BF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x7AD4, 0x9931, 0x9931, 0x9931, 0x9931, 0x9912, 0x7130, 0x390F, 0x38EE, 0x38EE, 0x38ED, 0x30ED, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x28AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30EC, 0x30EC, 0x30ED, 0x38EE, 0x30ED, 0x38ED, 0x390E, 0x38EE, 0x410E, 0x410F, 0x410F, 0x4930, 0x4930, 0x6931, 0xA111, 0xA111, 0xA112, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA112, 0x9931, 0x9911, 0x6397, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x5C14, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9131, 0x410F, 0x390E, 0x390E, 0x30ED, 0x30ED, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x28AB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x20CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CD, 0x30ED, 0x30ED, 0x38ED, 0x30EE, 0x38EE, 0x390E, 0x390E, 0x410F, 0x410F, 0x4130, 0x4930, 0x5931, 0x7911, 0x9131, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0x9931, 0xA111, 0x9931, 0x5498, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x35F5, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x510F, 0x390E, 0x390E, 0x38ED, 0x30ED, 0x30CC, 0x30CC, 0x28CC, 0x28CB, 0x28CB, 0x28AB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x28AB, 0x28CB, 0x20CB, 0x28AB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CD, 0x30ED, 0x30ED, 0x38ED, 0x38EE, 0x38EE, 0x390E, 0x410F, 0x410F, 0x412F, 0x4130, 0x4930, 0x4930, 0x6131, 0x8931, 0xA111, 0xA111, 0xA111, 0xA131, 0xA111, 0xA111, 0x9931, 0xA111, 0xA111, 0xA111, 0xA111, 0x3D7A, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07F6, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x7911, 0x390E, 0x38EE, 0x30EE, 0x30ED, 0x30CD, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28AB, 0x28AB, 0x20AB, 0x20AB, 0x20CA, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20CB, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20CA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x18AA, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20CA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x28CB, 0x20AB, 0x20CB, 0x20CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30EC, 0x30ED, 0x30ED, 0x30ED, 0x38EE, 0x38EE, 0x390E, 0x390E, 0x410F, 0x410F, 0x410F, 0x4930, 0x4930, 0x5131, 0x6131, 0x9911, 0xA111, 0xA111, 0xA111, 0x9931, 0xA111, 0xA111, 0xA112, 0x9931, 0x9911, 0x9192, 0x1EBD, 0x07FF, 0x07FF, 0x07FE, 0x07F6, 0x7A71, 0x9931, 0x9931, 0x9932, 0x9931, 0x9931, 0x9111, 0x410E, 0x38EE, 0x30ED, 0x30ED, 0x30ED, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20AB, 0x28AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20CA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20CA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AC, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CC, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x28CD, 0x28CD, 0x28CD, 0x28CD, 0x20CD, 0x28CE, 0x28CE, 0x28CE, 0x28EE, 0x28CE, 0x28EE, 0x30EE, 0x30EF, 0x30EF, 0x30EF, 0x390F, 0x390F, 0x3910, 0x3910, 0x4110, 0x4131, 0x4931, 0x4931, 0x4932, 0x4952, 0x5152, 0x9132, 0xA111, 0xA111, 0xA111, 0x9912, 0x9931, 0x9931, 0x9911, 0x9931, 0x9912, 0x8274, 0x07FF, 0x07FF, 0x07FD, 0x07F6, 0x5C32, 0x9911, 0x9931, 0x9932, 0x9931, 0x9931, 0x9931, 0x5910, 0x390F, 0x30EF, 0x30EF, 0x30EE, 0x30CE, 0x28CD, 0x28EE, 0x28ED, 0x28CD, 0x20CD, 0x20AC, 0x20CD, 0x20CD, 0x20AD, 0x20CD, 0x20AD, 0x20CC, 0x20CC, 0x20AD, 0x20CC, 0x20AC, 0x20CC, 0x20CC, 0x20AC, 0x20AC, 0x20CC, 0x20CC, 0x20CC, 0x20CC, 0x20CC, 0x20CC, 0x20CC, 0x20CC, + 0x18D2, 0x10F2, 0x18D2, 0x10F2, 0x10F2, 0x10F2, 0x10F2, 0x10F2, 0x10F2, 0x10F2, 0x10F2, 0x10F2, 0x18D2, 0x18D2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18D2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F3, 0x18F3, 0x18F2, 0x20F2, 0x18F2, 0x18F2, 0x20F2, 0x18F3, 0x18F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F2, 0x18F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x2113, 0x20F3, 0x20F3, 0x2113, 0x20F3, 0x20F3, 0x2113, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x2113, 0x2113, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x2113, 0x20F3, 0x2113, 0x2113, 0x2113, 0x28F3, 0x28F3, 0x2113, 0x28F3, 0x28F3, 0x2913, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2113, 0x2913, 0x2914, 0x2113, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2914, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2913, 0x2913, 0x28F3, 0x28F3, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x28F3, 0x2913, 0x2113, 0x2913, 0x2914, 0x2913, 0x2913, 0x2914, 0x2914, 0x2914, 0x2914, 0x2914, 0x3134, 0x3134, 0x3134, 0x3134, 0x3134, 0x3934, 0x3934, 0x3935, 0x3955, 0x4155, 0x4155, 0x4176, 0x4176, 0x4976, 0x4977, 0x5176, 0x9132, 0xA111, 0xA111, 0x9931, 0x9911, 0xA111, 0x9931, 0x9931, 0x9912, 0x9931, 0x5C38, 0x07FF, 0x07FD, 0x07F6, 0x44F2, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x7933, 0x3955, 0x3135, 0x3134, 0x3114, 0x2133, 0x2113, 0x2113, 0x20F3, 0x20F3, 0x2113, 0x1912, 0x18F2, 0x20F3, 0x18F2, 0x18F3, 0x18F2, 0x18F3, 0x18F3, 0x18F3, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, + 0x10F2, 0x18D2, 0x18D2, 0x10D2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18D2, 0x18F2, 0x18F2, 0x18D2, 0x18D2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F3, 0x18F3, 0x18F3, 0x18F3, 0x18F3, 0x18F2, 0x18F3, 0x18F3, 0x20F2, 0x18F3, 0x18F3, 0x18F3, 0x18F3, 0x18F3, 0x18F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x2112, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x2113, 0x20F2, 0x20F3, 0x20F2, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x2113, 0x28F3, 0x2113, 0x20F3, 0x2113, 0x28F3, 0x20F3, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x28F3, 0x28F3, 0x2113, 0x2113, 0x2113, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2113, 0x2913, 0x2913, 0x2913, 0x2914, 0x2913, 0x2913, 0x28F3, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x28F3, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2113, 0x2913, 0x2913, 0x2914, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2913, 0x28F3, 0x28F3, 0x2913, 0x2113, 0x2913, 0x2913, 0x2113, 0x2113, 0x28F3, 0x2913, 0x2113, 0x2914, 0x2914, 0x2914, 0x2914, 0x2914, 0x2914, 0x2914, 0x2914, 0x3134, 0x3134, 0x3134, 0x3135, 0x3935, 0x3935, 0x3955, 0x3955, 0x4155, 0x4156, 0x4176, 0x4976, 0x4956, 0x5176, 0x9132, 0xA111, 0xA112, 0xA111, 0x9931, 0x9931, 0x9911, 0x9932, 0x9931, 0x9911, 0x2E5C, 0x07FC, 0x07F6, 0x2E53, 0x9931, 0x9931, 0x9931, 0x9911, 0x9911, 0x9931, 0x9132, 0x3134, 0x3134, 0x3134, 0x2934, 0x2914, 0x2913, 0x2113, 0x2113, 0x20F3, 0x2112, 0x20F3, 0x20D3, 0x1912, 0x18F2, 0x18F3, 0x18F2, 0x18F2, 0x18F2, 0x18D2, 0x18F2, 0x20F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, + 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D9C, 0x1D9C, 0x1D9C, 0x1D9C, 0x1D9C, 0x1D9C, 0x1D9C, 0x1D9C, 0x1D9D, 0x1D9D, 0x1D9D, 0x1D9D, 0x259C, 0x1DBC, 0x1D9D, 0x259D, 0x1D9C, 0x259C, 0x259C, 0x259C, 0x259C, 0x259C, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25DD, 0x25DD, 0x25BD, 0x25BD, 0x1DDD, 0x25DD, 0x25DD, 0x25DD, 0x25BD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x2DFD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x2DFD, 0x2DFD, 0x2DFD, 0x2DFD, 0x2DFD, 0x25FD, 0x2DFE, 0x2DFD, 0x2DFD, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E3E, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E3D, 0x2E3D, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3D, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x365E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E3E, 0x365E, 0x365E, 0x2E5D, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3E, 0x2E3D, 0x2E3E, 0x2E3D, 0x363D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x361D, 0x361D, 0x361D, 0x361D, 0x361D, 0x3E1D, 0x3E1D, 0x3E1D, 0x3E1D, 0x3E1D, 0x3E1E, 0x461E, 0x461D, 0x4DFE, 0x4DFD, 0x4E3E, 0x4DFE, 0x55DD, 0x9214, 0x9931, 0x9931, 0x9931, 0x9932, 0x9931, 0x9911, 0x9911, 0x9931, 0x7A74, 0x07FB, 0x07F6, 0x07F6, 0x9931, 0x9931, 0x9911, 0x9932, 0x9931, 0x9931, 0x9931, 0x4CFB, 0x3DFE, 0x35DD, 0x35DD, 0x2DDD, 0x2DDD, 0x2DDD, 0x2DDD, 0x25DD, 0x25DD, 0x25BD, 0x25BD, 0x25DD, 0x25DD, 0x25BD, 0x25DC, 0x25BD, 0x25BD, 0x25BD, 0x1DBD, 0x25BC, 0x1DBD, 0x1DBD, 0x1DBC, 0x1DBC, 0x1DBC, 0x1DBC, 0x1DBC, 0x1DBC, 0x1D9D, 0x1D9D, 0x1D9D, 0x1D9D, + 0x1C7C, 0x1C7C, 0x1C7C, 0x1C7B, 0x1C7C, 0x1C7C, 0x1C7C, 0x1C7C, 0x1C7C, 0x1C7C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x249C, 0x1C9C, 0x1D9D, 0x1D7C, 0x1CFC, 0x1C9C, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x24BC, 0x1CBC, 0x1CBC, 0x24BC, 0x24BC, 0x24BC, 0x1CBC, 0x24DC, 0x24DC, 0x24DC, 0x253D, 0x25BD, 0x253D, 0x24DD, 0x24BC, 0x24BC, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24FD, 0x24DC, 0x24DC, 0x24FD, 0x24FD, 0x24FC, 0x24DD, 0x24FD, 0x251C, 0x25FD, 0x255D, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x24FC, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x251D, 0x24FD, 0x24FD, 0x251D, 0x2D1D, 0x24FD, 0x2CFD, 0x25BD, 0x25BD, 0x253C, 0x2CFC, 0x2D1D, 0x251D, 0x2CFD, 0x2CFD, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1C, 0x2D5D, 0x2DDE, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D1D, 0x2D3D, 0x2D1D, 0x2D1D, 0x2E1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2DDD, 0x2D5D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2D1D, 0x2D1D, 0x2CFD, 0x2CFD, 0x2CFD, 0x2DBD, 0x2DBD, 0x2CFD, 0x2D1D, 0x251C, 0x251C, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x34FD, 0x34FD, 0x34FD, 0x34FD, 0x34FD, 0x3CFD, 0x3CFD, 0x3CFD, 0x3CFD, 0x3D1D, 0x451D, 0x451D, 0x451D, 0x4D1D, 0x4D1D, 0x553D, 0x91B3, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0xA112, 0x9931, 0x9931, 0x5496, 0x07F7, 0x07F7, 0x8A13, 0xA111, 0x9931, 0x9931, 0x9912, 0x9932, 0x9911, 0x6318, 0x34DD, 0x34DD, 0x2CDD, 0x2CDC, 0x2CDD, 0x2CBC, 0x24DC, 0x24BC, 0x24BC, 0x253C, 0x25BD, 0x253C, 0x24BC, 0x24BC, 0x24BC, 0x1CBC, 0x24BC, 0x1CBC, 0x1CBC, 0x24BC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, + 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1B3B, 0x1CFC, 0x157C, 0x1C1C, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x22DB, 0x22DB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x22DB, 0x22DB, 0x22FB, 0x231C, 0x1D1C, 0x1D5C, 0x235B, 0x22DC, 0x22DB, 0x22DC, 0x22FB, 0x22FC, 0x22DC, 0x22DC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FB, 0x22FB, 0x22FB, 0x22FB, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x231B, 0x22FC, 0x233C, 0x253C, 0x1CFD, 0x22FC, 0x22FC, 0x22FB, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x2AFC, 0x2AFC, 0x231C, 0x2B1C, 0x2B1C, 0x259C, 0x247C, 0x231C, 0x231C, 0x2B1C, 0x231C, 0x231C, 0x2B1C, 0x231C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x25BD, 0x2BBC, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x231C, 0x2B1C, 0x2B1C, 0x25DD, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x231C, 0x2B1C, 0x2B7C, 0x259D, 0x2B1C, 0x2B1C, 0x231C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x245D, 0x259C, 0x22FC, 0x2AFC, 0x231C, 0x2AFC, 0x22FC, 0x231C, 0x231C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2AFC, 0x2B1C, 0x2B1C, 0x2B1C, 0x331C, 0x331C, 0x331C, 0x331C, 0x331C, 0x3B1C, 0x3B3D, 0x3B3D, 0x3B3D, 0x433C, 0x433D, 0x4B3D, 0x435D, 0x5A9A, 0x9932, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x1737, 0x07F9, 0x72D4, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x8194, 0x331C, 0x32FC, 0x2AFB, 0x2AFC, 0x2AFB, 0x22FB, 0x22DC, 0x22DC, 0x22FB, 0x22DB, 0x22DB, 0x235C, 0x1D5C, 0x1D1D, 0x231B, 0x1ADB, 0x1ADB, 0x1ADB, 0x22DB, 0x1ABB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ABB, 0x1ABB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, + 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x1B7B, 0x137B, 0x1B5B, 0x1B7B, 0x137B, 0x137B, 0x137B, 0x139B, 0x1BBB, 0x14FB, 0x153C, 0x13FB, 0x1B7B, 0x139B, 0x1B7B, 0x1B7C, 0x1B9B, 0x1B7B, 0x1B7B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9C, 0x1B9B, 0x1B9B, 0x1B9B, 0x139C, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9C, 0x1B9B, 0x1D3C, 0x1D5C, 0x1BFB, 0x1B9C, 0x1BBB, 0x1B9B, 0x1BBC, 0x1B9B, 0x1B9B, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBC, 0x1BBB, 0x1CDC, 0x1D7D, 0x23FC, 0x1BDC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x1BBC, 0x1BBC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23BC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x247C, 0x1D9C, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x241C, 0x259D, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x1DBD, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x1DBD, 0x243C, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23BC, 0x23DC, 0x23DC, 0x259C, 0x247C, 0x23BC, 0x23BC, 0x23DC, 0x23BC, 0x23DC, 0x23DC, 0x23BC, 0x23BC, 0x23BC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x2BDC, 0x2BDC, 0x2BDC, 0x2BDC, 0x2BDC, 0x33DC, 0x33DC, 0x33DC, 0x33DC, 0x3BDC, 0x3BFC, 0x3BFC, 0x3BDC, 0x43FC, 0x43FD, 0x6B18, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9932, 0x9931, 0x6B53, 0x07FA, 0x5437, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9912, 0x9931, 0x2BBC, 0x2BBC, 0x2BBC, 0x2BBB, 0x23BB, 0x23BB, 0x239B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1BDB, 0x1D5C, 0x1D1C, 0x1B9B, 0x1B9B, 0x139B, 0x139C, 0x1B9B, 0x1B7B, 0x1B7B, 0x139B, 0x1B9B, 0x1B9B, 0x1B7B, 0x1B9B, 0x139B, 0x1B7B, 0x1B7B, 0x1B9B, 0x1B9B, + 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x137B, 0x135A, 0x135A, 0x137B, 0x135A, 0x135B, 0x139B, 0x14BB, 0x14FB, 0x13FB, 0x137B, 0x137B, 0x135B, 0x137B, 0x137A, 0x137A, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x1B7B, 0x1B7B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x1BBB, 0x153C, 0x151C, 0x1B7B, 0x139B, 0x137B, 0x139B, 0x139B, 0x1B9B, 0x139B, 0x1B9B, 0x1B9B, 0x139B, 0x139B, 0x139B, 0x139B, 0x139B, 0x139B, 0x139B, 0x139B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x13BB, 0x139B, 0x1B9B, 0x139B, 0x1B9B, 0x1B9B, 0x1B9C, 0x1C3B, 0x1D5C, 0x1C3C, 0x1B9B, 0x1BBB, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1B9B, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBB, 0x1C9C, 0x1D1C, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BDB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1CFC, 0x1C7C, 0x1BBB, 0x1BDB, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBB, 0x1BDC, 0x23BC, 0x1BBB, 0x1D7C, 0x1BBB, 0x1BDC, 0x1BBB, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBC, 0x1B9C, 0x1BDC, 0x1BBB, 0x1C5B, 0x1CFB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBB, 0x1BBB, 0x1BBB, 0x1B9B, 0x1D3C, 0x1CBC, 0x1BBB, 0x1BBB, 0x1B9B, 0x1B9C, 0x1B9C, 0x1B9B, 0x1B9B, 0x1BBB, 0x1B9C, 0x1B9B, 0x1BBB, 0x239B, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x2BBC, 0x2BBC, 0x2BBC, 0x2BBC, 0x33BC, 0x33BC, 0x33DC, 0x3BDC, 0x3BDC, 0x3BDC, 0x3BDC, 0x8194, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9911, 0x9931, 0x2659, 0x4C98, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x4B19, 0x23BC, 0x239B, 0x239B, 0x239B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B7B, 0x1B7B, 0x1B7B, 0x1B7B, 0x137B, 0x137B, 0x137B, 0x14BB, 0x151B, 0x13DB, 0x137B, 0x137A, 0x137B, 0x137B, 0x137A, 0x137B, 0x137B, 0x137B, 0x135B, 0x137B, 0x135B, 0x135B, 0x135B, 0x137B, + 0x0999, 0x0999, 0x0999, 0x0999, 0x1199, 0x11BA, 0x11BA, 0x11B9, 0x09B9, 0x11BA, 0x1199, 0x11BA, 0x11BA, 0x1199, 0x11DA, 0x0B3A, 0x0C9B, 0x0BFB, 0x127A, 0x11BA, 0x119A, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x119A, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x119A, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x12BA, 0x14BB, 0x13FB, 0x11DB, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11DA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BB, 0x11BA, 0x11DA, 0x11BA, 0x11DA, 0x11BA, 0x11BA, 0x11DA, 0x11BA, 0x127A, 0x14DB, 0x137B, 0x11DA, 0x19BA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x19DA, 0x19DA, 0x19DA, 0x11DA, 0x11DB, 0x11DB, 0x11DB, 0x11DB, 0x11DB, 0x11DB, 0x11DB, 0x19DB, 0x11DA, 0x19DA, 0x1A3B, 0x14FB, 0x1AFB, 0x19DA, 0x11DB, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DA, 0x19DB, 0x19DA, 0x1A1B, 0x153C, 0x1A3B, 0x19DA, 0x19DA, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DB, 0x19DB, 0x19DA, 0x19DB, 0x153B, 0x19DB, 0x19DA, 0x19DB, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x11DB, 0x19DB, 0x19DA, 0x19DB, 0x19FB, 0x153C, 0x123A, 0x19DA, 0x19DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x19DA, 0x11DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x19DB, 0x19BA, 0x11DA, 0x11BA, 0x1ABB, 0x14FB, 0x1A5B, 0x19BA, 0x19BA, 0x11DA, 0x11DA, 0x19DB, 0x19DB, 0x19DA, 0x19DB, 0x19BA, 0x19DA, 0x19DA, 0x19DB, 0x19DB, 0x19DB, 0x21DB, 0x21DB, 0x21DB, 0x21FB, 0x21FB, 0x29FB, 0x29FB, 0x29FB, 0x29FB, 0x31FB, 0x321B, 0x31FB, 0x321B, 0x41FA, 0x9912, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9912, 0x72D4, 0x4C98, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x5996, 0x21DB, 0x21DA, 0x19DA, 0x19DA, 0x19DA, 0x11DA, 0x11DA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11D9, 0x137A, 0x149B, 0x131A, 0x11BA, 0x119A, 0x11B9, 0x11BA, 0x11BA, 0x119A, 0x11BA, 0x119A, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, + 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0B1A, 0x0B1A, 0x0AFA, 0x0AFA, 0x0B1A, 0x0AFA, 0x0B1A, 0x0AFA, 0x0B1A, 0x0B1A, 0x0C3A, 0x0C9A, 0x0BDA, 0x0B1A, 0x0AFA, 0x0AFA, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0BDB, 0x14BB, 0x0BFA, 0x0B1A, 0x0B1A, 0x0B3A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0B3A, 0x131A, 0x0B3A, 0x0B1A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x133B, 0x133B, 0x133A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x133A, 0x0B3A, 0x137A, 0x0CDB, 0x0C5B, 0x133B, 0x133B, 0x0B3A, 0x133A, 0x133A, 0x133A, 0x133A, 0x133A, 0x133A, 0x133A, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x135B, 0x135B, 0x135B, 0x135B, 0x133B, 0x133B, 0x135A, 0x0B5B, 0x133B, 0x143A, 0x147B, 0x135B, 0x135A, 0x133B, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135A, 0x13BB, 0x14DB, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135A, 0x135B, 0x133B, 0x14FB, 0x135A, 0x135B, 0x135A, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x133A, 0x135B, 0x135A, 0x135B, 0x135B, 0x149B, 0x13FB, 0x133A, 0x135B, 0x135B, 0x135A, 0x135A, 0x135A, 0x135B, 0x135B, 0x135B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133A, 0x133B, 0x133A, 0x135A, 0x133A, 0x143B, 0x147B, 0x133A, 0x133A, 0x133A, 0x133A, 0x133B, 0x133A, 0x133A, 0x133B, 0x133A, 0x133A, 0x133A, 0x135B, 0x133B, 0x133B, 0x1B3B, 0x1B5B, 0x1B5B, 0x1B3B, 0x1B5B, 0x235B, 0x235B, 0x235B, 0x235B, 0x2B5B, 0x2B5B, 0x2B7B, 0x2B7B, 0x335B, 0x7235, 0x9911, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x72D5, 0x9932, 0x9932, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x71B4, 0x1B3B, 0x1B3B, 0x133A, 0x133B, 0x133A, 0x131A, 0x131A, 0x131A, 0x131A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0AFA, 0x0B1A, 0x0AFA, 0x0BDA, 0x0CBB, 0x0BDA, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, + 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02F9, 0x02D9, 0x02DA, 0x0ADA, 0x0AFA, 0x0BFA, 0x0C5B, 0x0BFA, 0x0AD9, 0x02FA, 0x02F9, 0x02F9, 0x0AF9, 0x02F9, 0x0AF9, 0x02D9, 0x02F9, 0x0AF9, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AF9, 0x0AFA, 0x0AFA, 0x0AFA, 0x0C1A, 0x0C7B, 0x0B5A, 0x0AFA, 0x0AF9, 0x0B1A, 0x0AFA, 0x0AFA, 0x0AFA, 0x0B1A, 0x0AFA, 0x0AFA, 0x0B1A, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0B1A, 0x0B1A, 0x0B1A, 0x031A, 0x0AFA, 0x0B1A, 0x0B1A, 0x0AFA, 0x0B1A, 0x0B1A, 0x0B1A, 0x0AFA, 0x0C3A, 0x0C5A, 0x0B1A, 0x0AFA, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0C5B, 0x0C1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0C7B, 0x0B7A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0CBB, 0x0B1A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B7A, 0x0CBB, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0BDA, 0x0C7B, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x131A, 0x131A, 0x131A, 0x131A, 0x131A, 0x1B1A, 0x1B3A, 0x1B3A, 0x1B3A, 0x1B3A, 0x233A, 0x233A, 0x233B, 0x2B3B, 0x2B5B, 0x3AD9, 0x9931, 0x9931, 0x9931, 0x9912, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x8993, 0x1B1A, 0x131A, 0x131A, 0x12FA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x02FA, 0x0AFA, 0x035A, 0x045A, 0x0C3A, 0x0AFA, 0x02DA, 0x0AFA, 0x0AF9, 0x02F9, 0x0AFA, 0x0AFA, 0x0AFA, 0x02D9, 0x02D9, + 0x0158, 0x0158, 0x0158, 0x0158, 0x0138, 0x0158, 0x0158, 0x0158, 0x0138, 0x0238, 0x03B9, 0x03DA, 0x0259, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0138, 0x0178, 0x0158, 0x0158, 0x0159, 0x01B9, 0x037A, 0x0BDA, 0x0218, 0x0958, 0x0159, 0x0159, 0x0958, 0x0158, 0x0158, 0x0158, 0x0158, 0x0958, 0x0959, 0x0158, 0x0159, 0x0179, 0x0158, 0x0159, 0x0159, 0x0159, 0x0159, 0x0158, 0x0158, 0x0158, 0x0158, 0x0979, 0x0179, 0x0958, 0x0979, 0x0159, 0x0178, 0x0159, 0x0958, 0x033A, 0x041A, 0x01F9, 0x0959, 0x0179, 0x0958, 0x0959, 0x0158, 0x0159, 0x0159, 0x0159, 0x0159, 0x0979, 0x0979, 0x0979, 0x0979, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0979, 0x0979, 0x0959, 0x0959, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0A79, 0x043A, 0x0199, 0x0959, 0x0179, 0x0179, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0979, 0x0179, 0x09B9, 0x0C3B, 0x0179, 0x0979, 0x0179, 0x0179, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0179, 0x0979, 0x0179, 0x0C7A, 0x0979, 0x0179, 0x0179, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0979, 0x0979, 0x0979, 0x0979, 0x0BFA, 0x0259, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0959, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0179, 0x0958, 0x0979, 0x0178, 0x0958, 0x0159, 0x0999, 0x0BDA, 0x02D9, 0x0159, 0x0959, 0x0159, 0x0979, 0x0959, 0x0979, 0x0959, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x1179, 0x1179, 0x1179, 0x1179, 0x1179, 0x1999, 0x1999, 0x199A, 0x1999, 0x2199, 0x219A, 0x21BA, 0x7154, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x1179, 0x1179, 0x1179, 0x0979, 0x0979, 0x0958, 0x0958, 0x0958, 0x0958, 0x0158, 0x0158, 0x0158, 0x0958, 0x0158, 0x0158, 0x0158, 0x0158, 0x0159, 0x0158, 0x01D8, 0x0399, 0x0399, 0x01D9, 0x0158, 0x0158, 0x0138, 0x0138, 0x0158, 0x0158, 0x0158, 0x0158, + 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0138, 0x0137, 0x01D8, 0x0339, 0x0399, 0x0238, 0x0137, 0x0137, 0x0138, 0x0138, 0x0137, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0137, 0x0138, 0x0138, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0157, 0x0138, 0x0278, 0x03D9, 0x02B9, 0x0178, 0x0158, 0x0138, 0x0138, 0x0158, 0x0138, 0x0137, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0158, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0158, 0x0158, 0x0158, 0x0138, 0x0138, 0x0938, 0x0158, 0x0158, 0x0158, 0x0178, 0x0339, 0x0399, 0x0178, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x01D9, 0x03F9, 0x01F9, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x02D9, 0x0319, 0x0158, 0x0158, 0x0158, 0x0159, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0959, 0x0158, 0x0158, 0x0159, 0x041A, 0x0959, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x02B9, 0x0319, 0x0158, 0x0158, 0x0138, 0x0138, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0138, 0x0158, 0x01D8, 0x03F9, 0x01F8, 0x0138, 0x0138, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0958, 0x0958, 0x0958, 0x0958, 0x0958, 0x1158, 0x1158, 0x1158, 0x1178, 0x1179, 0x1979, 0x1979, 0x1979, 0x1979, 0x1999, 0x2179, 0x3178, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x3157, 0x0958, 0x1158, 0x0958, 0x0958, 0x0938, 0x0938, 0x0938, 0x0938, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0298, 0x03F9, 0x0298, 0x0137, 0x0138, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, + 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x01D7, 0x0318, 0x0379, 0x0238, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0137, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0137, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0137, 0x0117, 0x0117, 0x0177, 0x0318, 0x0379, 0x01D7, 0x0137, 0x0117, 0x0137, 0x0117, 0x0137, 0x0136, 0x0117, 0x0117, 0x0137, 0x0137, 0x0117, 0x0117, 0x0137, 0x0137, 0x0137, 0x0117, 0x0137, 0x0137, 0x0137, 0x0117, 0x0117, 0x0117, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0138, 0x0137, 0x0117, 0x0157, 0x0359, 0x02F8, 0x0157, 0x0117, 0x0137, 0x0117, 0x0137, 0x0117, 0x0137, 0x0137, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0158, 0x0359, 0x0278, 0x0137, 0x0138, 0x0137, 0x0138, 0x0138, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0138, 0x03B9, 0x01B8, 0x0137, 0x0138, 0x0138, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0137, 0x0137, 0x0138, 0x03F9, 0x0137, 0x0138, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0138, 0x0118, 0x0138, 0x0138, 0x0178, 0x03F9, 0x0158, 0x0137, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0137, 0x0137, 0x0138, 0x0138, 0x0137, 0x0137, 0x0118, 0x0238, 0x03B9, 0x0177, 0x0137, 0x0138, 0x0137, 0x0117, 0x0137, 0x0138, 0x0137, 0x0137, 0x0137, 0x0137, 0x0937, 0x0938, 0x0938, 0x0938, 0x0938, 0x0938, 0x0958, 0x1158, 0x1158, 0x1158, 0x1158, 0x1158, 0x1958, 0x1958, 0x1959, 0x1978, 0x6934, 0x9931, 0x9931, 0x9912, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9912, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9932, 0x4135, 0x0938, 0x0957, 0x0937, 0x0937, 0x0937, 0x0937, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0137, 0x0137, 0x0117, 0x0117, 0x0117, 0x0117, 0x0197, 0x0318, 0x0338, 0x01B7, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, + 0x02D8, 0x02D8, 0x02D7, 0x02D7, 0x02F7, 0x0358, 0x0378, 0x02F7, 0x02D8, 0x02D8, 0x02D8, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02D7, 0x02F8, 0x02F8, 0x0398, 0x0378, 0x02F8, 0x02D8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x0378, 0x0398, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x0318, 0x02F8, 0x0318, 0x02F7, 0x02F8, 0x02F8, 0x0318, 0x0358, 0x0399, 0x0318, 0x02F8, 0x02F8, 0x0318, 0x0318, 0x02F8, 0x0318, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0338, 0x03B8, 0x0318, 0x0318, 0x02F8, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x03B8, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x02F8, 0x0318, 0x0318, 0x02F8, 0x0318, 0x0378, 0x0338, 0x02F8, 0x02F8, 0x0318, 0x02F8, 0x0318, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x0318, 0x0318, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x0378, 0x0338, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x0AF8, 0x0AF8, 0x0AF8, 0x0AF8, 0x0B18, 0x0B18, 0x1318, 0x1319, 0x1319, 0x1319, 0x1319, 0x1319, 0x1B18, 0x2AF8, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9932, 0x9931, 0x9911, 0x9931, 0x9932, 0x9931, 0x9931, 0x9931, 0x5215, 0x0AF8, 0x0AF8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D7, 0x02D8, 0x02D8, 0x0378, 0x0378, 0x02D7, 0x02D8, 0x02D7, 0x02D7, 0x02D8, + 0x0176, 0x01B6, 0x02F8, 0x0317, 0x0217, 0x0196, 0x0176, 0x0196, 0x0196, 0x0196, 0x0196, 0x0176, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0176, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x01F7, 0x0337, 0x02D7, 0x01B6, 0x0197, 0x0196, 0x0196, 0x0176, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0197, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0237, 0x0358, 0x0217, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0196, 0x0196, 0x0197, 0x0197, 0x0196, 0x0196, 0x0277, 0x0318, 0x01B6, 0x0196, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x01B7, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x01B6, 0x02F7, 0x0257, 0x0197, 0x01B6, 0x01B7, 0x01B6, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x01B7, 0x01B6, 0x01B7, 0x0378, 0x01B7, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x01B6, 0x01F7, 0x0358, 0x0196, 0x0196, 0x01B6, 0x0196, 0x01B6, 0x0197, 0x0196, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0196, 0x0196, 0x0197, 0x0197, 0x02F7, 0x02F7, 0x0196, 0x0196, 0x0196, 0x0196, 0x0197, 0x0196, 0x0197, 0x01B6, 0x01B6, 0x0196, 0x0196, 0x0196, 0x0197, 0x0197, 0x0197, 0x09B7, 0x0997, 0x09B7, 0x09B7, 0x09B7, 0x11B7, 0x11B7, 0x11D7, 0x11B7, 0x11B7, 0x11B7, 0x7153, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x6174, 0x09B6, 0x0196, 0x0197, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0176, 0x0196, 0x0196, 0x0196, 0x0196, 0x0177, 0x0196, 0x02B7, 0x0337, 0x0216, 0x0196, 0x0196, + 0x0236, 0x0317, 0x0256, 0x00F4, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00F5, 0x00F5, 0x00D5, 0x00F5, 0x00D5, 0x00D5, 0x00F5, 0x01F6, 0x0317, 0x01F6, 0x00F5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00F5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00F5, 0x00F5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00F5, 0x00D5, 0x00F5, 0x01B6, 0x0337, 0x01B6, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x0155, 0x0337, 0x0156, 0x00D5, 0x00D5, 0x00F6, 0x00F6, 0x00F6, 0x00F5, 0x00D6, 0x00D6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F6, 0x00D5, 0x00F6, 0x00F6, 0x00F5, 0x00F5, 0x00F5, 0x00F6, 0x0115, 0x0338, 0x0115, 0x00F6, 0x00F5, 0x00F6, 0x00F5, 0x00D6, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00D5, 0x00F6, 0x00D5, 0x00F5, 0x0357, 0x00F5, 0x00F6, 0x00F6, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F6, 0x00F5, 0x00D5, 0x00D5, 0x00D6, 0x00D6, 0x00D5, 0x00F5, 0x02F7, 0x0176, 0x00F5, 0x00D5, 0x00F5, 0x00F6, 0x00F6, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00D5, 0x00F5, 0x00D5, 0x0116, 0x02F7, 0x01D6, 0x00D6, 0x00D5, 0x00F5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00F5, 0x00D5, 0x00D5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x08F6, 0x08F6, 0x08F6, 0x08F6, 0x0916, 0x0916, 0x10F6, 0x1117, 0x1116, 0x3135, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9911, 0x9912, 0x9931, 0x9931, 0x9931, 0x9931, 0x7113, 0x08F5, 0x08F6, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D4, 0x00D5, 0x00D5, 0x00D5, 0x01D6, 0x02F7, 0x0236, 0x0114, + 0x01F4, 0x0113, 0x00B3, 0x00D3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00D3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00D3, 0x00B3, 0x00D3, 0x00D4, 0x00B3, 0x00B3, 0x00D4, 0x00B3, 0x00B3, 0x00D4, 0x00B3, 0x00D3, 0x0133, 0x0275, 0x0255, 0x0134, 0x00D3, 0x00B3, 0x00D3, 0x00D3, 0x00D4, 0x00D4, 0x00B4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00B4, 0x00D4, 0x00B4, 0x00D4, 0x00D4, 0x00B4, 0x00B4, 0x01D4, 0x02B5, 0x0134, 0x00D4, 0x00B4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00F4, 0x02B5, 0x01B5, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x01B5, 0x0255, 0x00D5, 0x00B4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x02F6, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x01F5, 0x0235, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00B4, 0x00B4, 0x00B4, 0x00B4, 0x00B4, 0x00B4, 0x00B4, 0x00D4, 0x00D4, 0x00B4, 0x0154, 0x02B5, 0x0134, 0x00D4, 0x00B4, 0x00B4, 0x00D4, 0x00D4, 0x00D4, 0x00B4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x08D4, 0x08D4, 0x08D4, 0x08F4, 0x08F4, 0x08F4, 0x08F5, 0x10F4, 0x10D5, 0x7912, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x8132, 0x00D4, 0x00D4, 0x00D4, 0x00D3, 0x00D3, 0x00D3, 0x00D3, 0x00D3, 0x00B3, 0x00D3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B2, 0x00B3, 0x00D3, 0x00D3, 0x0214, 0x0295, + 0x00B1, 0x0091, 0x0091, 0x0091, 0x00B1, 0x0091, 0x00B1, 0x00B1, 0x0091, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x0091, 0x0091, 0x00D2, 0x01B2, 0x0273, 0x0172, 0x00B1, 0x00B2, 0x00B1, 0x00B1, 0x00B2, 0x00B1, 0x00B1, 0x00B2, 0x00B1, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B1, 0x00B1, 0x00B2, 0x00B2, 0x00B1, 0x00B2, 0x00B2, 0x00B2, 0x01D3, 0x0253, 0x0112, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x0213, 0x01D3, 0x0092, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x0253, 0x0153, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x0294, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00F2, 0x0293, 0x00D2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B1, 0x00B2, 0x0172, 0x0253, 0x00B1, 0x00B1, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B1, 0x00B1, 0x00B1, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x08B2, 0x08B2, 0x08B2, 0x08D2, 0x08B2, 0x08D2, 0x08D3, 0x10D3, 0x40F2, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x00D2, 0x00B2, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x0091, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x0091, 0x0131, + 0x0090, 0x0070, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0111, 0x0212, 0x01D1, 0x00D0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x01D2, 0x01F2, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x0171, 0x0212, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x00F1, 0x0252, 0x00B0, 0x0090, 0x00B0, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x0272, 0x00B0, 0x0090, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x01D1, 0x0171, 0x0091, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x01D1, 0x01D1, 0x0090, 0x00B0, 0x0090, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0091, 0x0091, 0x0091, 0x0091, 0x08B1, 0x08B1, 0x08B1, 0x08B1, 0x08B1, 0x08B1, 0x08B1, 0x8912, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9911, 0x9911, 0x9912, 0x9931, 0x0091, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, + 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x0191, 0x0232, 0x0151, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x01F2, 0x01D1, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0110, 0x0252, 0x00D0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x01B1, 0x0191, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x0090, 0x0090, 0x0252, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0151, 0x0232, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x01F1, 0x0171, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0091, 0x00B0, 0x00B0, 0x00B1, 0x08B1, 0x08B0, 0x08B1, 0x08B1, 0x50F1, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9911, 0x9931, 0x9911, 0x9931, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0070, 0x0090, 0x0090, + 0x008F, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x00D0, 0x0212, 0x01D2, 0x00D0, 0x0090, 0x008F, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0090, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x0090, 0x0090, 0x00F0, 0x0232, 0x01B1, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0232, 0x0130, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x0232, 0x00D0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0252, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0232, 0x00F0, 0x0090, 0x0070, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00F0, 0x0232, 0x00F1, 0x00B0, 0x008F, 0x008F, 0x0090, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x0890, 0x08B0, 0x0891, 0x10B0, 0x9931, 0x9911, 0x9911, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, + 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0171, 0x0232, 0x0151, 0x008F, 0x006F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0070, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x006F, 0x00F0, 0x0212, 0x0151, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x0070, 0x0090, 0x01F1, 0x01B1, 0x0070, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x008F, 0x0090, 0x008F, 0x008F, 0x0130, 0x01F1, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0252, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x0191, 0x01B1, 0x0090, 0x008F, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x0090, 0x0090, 0x008F, 0x0090, 0x006F, 0x008F, 0x0131, 0x0232, 0x00D0, 0x0090, 0x008F, 0x008F, 0x008F, 0x0090, 0x0090, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x60F1, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x0150, 0x0090, 0x0090, 0x0090, 0x006F, 0x0090, 0x006F, 0x008F, 0x008F, 0x0070, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, + 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x0070, 0x008F, 0x006F, 0x008F, 0x0110, 0x0232, 0x01B1, 0x00AF, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x0110, 0x0252, 0x0130, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x0170, 0x01F2, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x01D2, 0x0130, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x0252, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x00CF, 0x0232, 0x00AF, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x008F, 0x0191, 0x0212, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x18AF, 0x9911, 0x9912, 0x9911, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0xA111, 0x9931, 0xA111, 0x29D2, 0x01B1, 0x008F, 0x006F, 0x008F, 0x006F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, + 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x01B1, 0x0232, 0x010F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x0150, 0x0232, 0x00CF, 0x006F, 0x006F, 0x008E, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x006F, 0x010F, 0x0212, 0x00AF, 0x006F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x008F, 0x00AF, 0x0212, 0x00AF, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x0252, 0x006F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x006F, 0x006F, 0x01D1, 0x0130, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x01F1, 0x01B1, 0x008F, 0x006F, 0x006F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x0090, 0x8111, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9912, 0x9932, 0x9931, 0x9931, 0x28D0, 0x01F2, 0x01D1, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006E, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, + 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x008E, 0x0110, 0x0212, 0x01B1, 0x008F, 0x006F, 0x006E, 0x006F, 0x006F, 0x006E, 0x008F, 0x006E, 0x006E, 0x006E, 0x006F, 0x006F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006F, 0x008F, 0x006E, 0x006E, 0x006F, 0x006F, 0x008E, 0x006E, 0x0191, 0x01F1, 0x00CF, 0x006F, 0x006F, 0x006E, 0x008F, 0x006E, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x006E, 0x006E, 0x006F, 0x00CF, 0x0212, 0x0110, 0x008F, 0x006F, 0x006E, 0x008F, 0x006F, 0x006E, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x0150, 0x0191, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x0232, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x0110, 0x01F1, 0x008F, 0x006E, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x00AF, 0x0212, 0x0110, 0x006F, 0x006F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x48D0, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x008E, 0x008F, 0x01B1, 0x01F2, 0x00AF, 0x006F, 0x006E, 0x008F, 0x006E, 0x008F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, + 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x008E, 0x01B1, 0x0212, 0x00EF, 0x006E, 0x006E, 0x006E, 0x006F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006F, 0x006E, 0x006E, 0x008E, 0x01D1, 0x01F1, 0x008F, 0x006F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x00AE, 0x01F1, 0x0170, 0x006F, 0x006E, 0x006E, 0x006E, 0x006F, 0x006E, 0x006E, 0x006F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0211, 0x00CF, 0x008F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0232, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x008F, 0x0212, 0x00CF, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x00EF, 0x0212, 0x00CF, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006E, 0x108F, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x006E, 0x006F, 0x006E, 0x0190, 0x0212, 0x00CF, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, + 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0130, 0x0212, 0x0170, 0x008E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x00AF, 0x01D1, 0x0190, 0x008E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0190, 0x01F1, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x00EF, 0x0211, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0232, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0170, 0x0190, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0150, 0x01F1, 0x008E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x68F0, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x006E, 0x006E, 0x006E, 0x006E, 0x010F, 0x0212, 0x00EF, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, + 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x008E, 0x01B1, 0x01F2, 0x00CF, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x00AF, 0x0212, 0x0191, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x004E, 0x008E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x010F, 0x0212, 0x008E, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0190, 0x0150, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0232, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x008E, 0x0211, 0x008E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0190, 0x01B1, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x38B0, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9912, 0x004E, 0x006E, 0x006E, 0x004E, 0x006E, 0x010F, 0x0212, 0x010F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, + 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x004E, 0x004D, 0x0130, 0x01F2, 0x0150, 0x006D, 0x006D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x00EF, 0x0212, 0x010F, 0x004E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x004E, 0x00AF, 0x0212, 0x00CF, 0x004E, 0x006E, 0x004E, 0x004E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x008E, 0x0232, 0x008E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0232, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x004E, 0x006E, 0x006E, 0x01D1, 0x010F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x004E, 0x006E, 0x004E, 0x006E, 0x008E, 0x01F1, 0x012F, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x004E, 0x006E, 0x086E, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9912, 0x9931, 0x9931, 0x9911, 0x9931, 0x004E, 0x006D, 0x006E, 0x006E, 0x006E, 0x006E, 0x00AE, 0x0211, 0x0190, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, + 0x004D, 0x004D, 0x004D, 0x004D, 0x006E, 0x006D, 0x004D, 0x004D, 0x004E, 0x004D, 0x004D, 0x006D, 0x006D, 0x008E, 0x01B1, 0x01D1, 0x00CE, 0x006D, 0x004D, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x004D, 0x006E, 0x004D, 0x006E, 0x006E, 0x004E, 0x006D, 0x010F, 0x0212, 0x00EF, 0x006D, 0x006E, 0x006E, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004D, 0x006D, 0x006E, 0x006E, 0x006E, 0x004D, 0x006E, 0x004D, 0x006E, 0x01D1, 0x0150, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x0130, 0x0191, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x0232, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x004D, 0x004D, 0x004E, 0x010F, 0x01D1, 0x006E, 0x006E, 0x006E, 0x006E, 0x006D, 0x004E, 0x004E, 0x004D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006D, 0x006D, 0x00CE, 0x0212, 0x00CE, 0x006E, 0x006E, 0x006E, 0x006E, 0x006D, 0x004D, 0x004D, 0x006D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x70F0, 0x9932, 0x9931, 0x9931, 0x9911, 0x9931, 0x9911, 0x9931, 0x9931, 0x8110, 0x006E, 0x006E, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x008E, 0x01D1, 0x0190, 0x006D, 0x006D, 0x004E, 0x006E, 0x006E, 0x004D, 0x006D, 0x006E, 0x004D, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, + 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006D, 0x004D, 0x004D, 0x004D, 0x0150, 0x01F1, 0x0150, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006D, 0x004D, 0x004E, 0x004D, 0x004D, 0x004D, 0x0150, 0x01F1, 0x00AE, 0x006D, 0x004D, 0x004D, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x004D, 0x006D, 0x006D, 0x004D, 0x006D, 0x004D, 0x006D, 0x006D, 0x006D, 0x0170, 0x01B1, 0x006D, 0x006D, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006D, 0x004E, 0x006E, 0x01D1, 0x010F, 0x006D, 0x006D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004D, 0x006D, 0x006E, 0x004E, 0x0212, 0x004D, 0x004D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004D, 0x006D, 0x006D, 0x006D, 0x006E, 0x01F1, 0x008E, 0x006D, 0x006E, 0x004D, 0x004D, 0x006D, 0x006D, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x004D, 0x006D, 0x004D, 0x010F, 0x01F1, 0x006D, 0x006D, 0x004D, 0x006E, 0x006D, 0x006D, 0x006D, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x004E, 0x006D, 0x006D, 0x004D, 0x40CF, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x70F0, 0x004D, 0x006D, 0x004D, 0x004D, 0x006D, 0x006D, 0x004D, 0x004D, 0x006D, 0x0191, 0x01B1, 0x006D, 0x004D, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/bootscreen_480x320x16.cpp b/Marlin/src/lcd/tft/images/bootscreen_480x320x16.cpp new file mode 100644 index 000000000000..b90228af03a8 --- /dev/null +++ b/Marlin/src/lcd/tft/images/bootscreen_480x320x16.cpp @@ -0,0 +1,350 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint16_t marlin_logo_480x320x16[153600] = { + 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x10AE, 0x00F8, 0x00F9, 0x00D6, 0x18AD, 0x188C, 0x188C, 0x18AC, 0x188C, 0x18AC, 0x18AC, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188D, 0x188D, 0x188D, 0x188D, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x188D, 0x18AD, 0x18AC, 0x18AC, 0x188D, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x188D, 0x18AC, 0x18AC, 0x00F9, 0x00F9, 0x18AC, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188C, 0x188C, 0x18AB, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, + 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x10AE, 0x00F7, 0x00F9, 0x00F6, 0x188D, 0x18AC, 0x18AC, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x18AD, 0x188D, 0x18AC, 0x18AC, 0x188D, 0x188D, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x00F9, 0x00F9, 0x18AC, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, + 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x10AF, 0x00F8, 0x00F8, 0x00F7, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188D, 0x18AC, 0x18AD, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x00F9, 0x00F9, 0x18AC, 0x18AD, 0x18AC, 0x18AC, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, + 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x18AC, 0x18AC, 0x10AF, 0x00F7, 0x00F8, 0x00F6, 0x18AD, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x00F9, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, + 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x188C, 0x18AC, 0x18AC, 0x10AF, 0x00F8, 0x00F9, 0x00D6, 0x18AD, 0x18AD, 0x188C, 0x18AC, 0x18AD, 0x18AC, 0x18AD, 0x188D, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x208D, 0x18AD, 0x18AD, 0x208D, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00F9, 0x00F9, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, + 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188B, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x18AC, 0x188D, 0x18AC, 0x18AD, 0x18AF, 0x00F8, 0x00F9, 0x00F6, 0x18AE, 0x188D, 0x18AC, 0x188D, 0x18AC, 0x18AD, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D1, 0x10D3, 0x10D3, 0x10D1, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x00F9, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, + 0x188B, 0x188B, 0x188B, 0x188B, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188B, 0x188B, 0x188B, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AC, 0x188C, 0x18AC, 0x188D, 0x10AF, 0x00F8, 0x0119, 0x00D7, 0x18AE, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x011A, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x00F9, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, + 0x188B, 0x188C, 0x188C, 0x188C, 0x188B, 0x188B, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x188D, 0x18AD, 0x18AD, 0x18CF, 0x00F8, 0x0119, 0x00F6, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x00F7, 0x00F7, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, + 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CF, 0x00F9, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x188D, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18CD, 0x18AE, 0x0119, 0x0119, 0x10D3, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x188C, + 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CF, 0x00F8, 0x00F9, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AF, 0x011A, 0x0119, 0x10D1, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x18AC, 0x08B2, 0x08D2, + 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AF, 0x00F9, 0x0119, 0x00F8, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08F6, 0x0119, 0x0119, 0x0119, 0x0119, 0x0118, 0x08F6, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x08D3, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x00F9, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x00F8, 0x00F8, + 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x188D, 0x18AD, 0x18AD, 0x18B0, 0x0118, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18B0, 0x0118, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0117, 0x10D0, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x011A, 0x00F7, 0x00F7, 0x0119, 0x011A, 0x08F5, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x00F9, 0x00F9, + 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x20AD, 0x18B0, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AE, 0x18AD, 0x20AD, 0x18AE, 0x18AE, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AE, 0x10D2, 0x0119, 0x011A, 0x0119, 0x00F6, 0x10F2, 0x10D1, 0x10D0, 0x10D1, 0x10D3, 0x08F6, 0x00F9, 0x00F9, 0x0119, 0x10D2, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x011A, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x00F8, 0x00F8, + 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AE, 0x18D0, 0x0118, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x011A, 0x00F8, 0x18D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D0, 0x0119, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x10D1, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x0119, 0x011A, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x00F9, 0x00F9, + 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18CF, 0x00F9, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CF, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0118, 0x18AF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x10D2, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x20AD, 0x18AD, 0x18CD, 0x18CD, 0x20AE, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x00F9, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x18AC, 0x00F9, 0x00F8, + 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x08D5, 0x011A, 0x00F8, 0x18CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x011A, 0x011A, 0x10D2, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x011A, 0x08F3, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188D, 0x00F9, 0x00F8, + 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x188D, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x0118, 0x011A, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x011A, 0x011A, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x0118, 0x10D1, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x08F3, 0x0119, 0x011A, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D1, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x188C, 0x00F9, 0x00F9, + 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x00F8, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x00F9, 0x10D2, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x011A, 0x00F9, 0x0119, 0x011A, 0x0119, 0x08F4, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D1, 0x0119, 0x0119, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x00F7, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x00F7, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x10D1, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D1, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AE, 0x18CD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D1, 0x0119, 0x0119, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x18AC, 0x188C, 0x00F9, 0x00F9, + 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x0119, 0x0119, 0x0117, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0118, 0x0119, 0x0119, 0x0118, 0x10D1, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x08F3, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F3, 0x011A, 0x0119, 0x08F3, 0x10D1, 0x00F7, 0x0119, 0x00F9, 0x18AF, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x00F7, 0x18AD, 0x20AD, 0x18AD, 0x10D2, 0x011A, 0x0119, 0x08F3, 0x10D0, 0x10F4, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x0117, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00F9, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x0119, 0x011A, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x00F9, 0x00F9, + 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x188C, 0x188C, 0x188C, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AF, 0x08F5, 0x0139, 0x00FA, 0x011A, 0x0119, 0x08F5, 0x18AF, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x0119, 0x011A, 0x0117, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D1, 0x0119, 0x0119, 0x00FA, 0x0119, 0x0119, 0x0119, 0x10D1, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AE, 0x20AD, 0x08F5, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F6, 0x0119, 0x08F4, 0x20AD, 0x18AE, 0x18AE, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x08D4, 0x0119, 0x08F6, 0x18AD, 0x18AD, 0x18AD, 0x08D4, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x20AD, 0x00F7, 0x011A, 0x10D3, 0x18AD, 0x18AD, 0x18AD, 0x08F6, 0x011A, 0x08F3, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x00F9, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AE, 0x18AE, 0x011A, 0x0119, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08F3, 0x08F3, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AC, 0x00F9, 0x00F9, + 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x188C, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CF, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0118, 0x18CF, 0x20AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18B0, 0x00F9, 0x0119, 0x00F7, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x0118, 0x0119, 0x08F7, 0x10D1, 0x10D1, 0x00F7, 0x0119, 0x0118, 0x20AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x00F6, 0x011A, 0x08F3, 0x18AE, 0x18AD, 0x18AD, 0x00F9, 0x0119, 0x10D2, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x08D4, 0x0119, 0x08F6, 0x18AD, 0x18AD, 0x18AD, 0x08D4, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x20AD, 0x00F7, 0x011A, 0x10D3, 0x18AD, 0x18AD, 0x18AD, 0x08F6, 0x011A, 0x08F3, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x011A, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x00F9, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x00F9, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00F9, 0x00F9, + 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x011A, 0x0119, 0x0119, 0x00F9, 0x011A, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x10D1, 0x18CD, 0x18AD, 0x10D1, 0x00F9, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x08F4, 0x011A, 0x011A, 0x10F1, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x00F9, 0x10D0, 0x18AE, 0x08D5, 0x011A, 0x0119, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x00F7, 0x18AD, 0x20AD, 0x18AD, 0x10D2, 0x011A, 0x0119, 0x08F3, 0x10D0, 0x10F4, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x0117, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x10D2, 0x0119, 0x00F9, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x10F2, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, + 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x10B1, 0x18AD, 0x18AD, 0x10D1, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x08F5, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x00F9, 0x0119, 0x00F9, 0x0119, 0x0119, 0x0119, 0x00F6, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D1, 0x0119, 0x0119, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x00F7, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x00F7, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x10D1, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x00F9, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18CD, 0x18AE, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, + 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x18AE, 0x20AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x0118, 0x0119, 0x00F7, 0x10D1, 0x10D1, 0x00F7, 0x0119, 0x00F8, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x08D5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x0118, 0x0119, 0x0119, 0x011A, 0x08F5, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x08F3, 0x0119, 0x011A, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18CD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x08F5, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AF, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F8, 0x18CE, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, + 0x18AD, 0x188D, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x10F1, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x10F1, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x08D5, 0x011A, 0x00F8, 0x18CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08D5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x0119, 0x0119, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00F9, 0x0119, + 0x18AD, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x08F5, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x10D1, 0x00F8, 0x0119, 0x0119, 0x00F8, 0x10D1, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x08F5, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CF, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x18AF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x20AE, 0x18CD, 0x18AD, 0x20AD, 0x00F9, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x08F5, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x0118, 0x0119, 0x0117, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08D3, 0x10D3, + 0x18AD, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x08F5, 0x18AE, 0x18CD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x08F5, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x011A, 0x00F8, 0x18D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x0118, 0x0119, 0x0119, 0x10D1, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x011A, 0x0119, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x011A, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18CD, 0x18CD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x18D0, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AE, 0x10D2, 0x0119, 0x011A, 0x0119, 0x00F6, 0x10F2, 0x10D1, 0x10D0, 0x10D1, 0x10D3, 0x08F6, 0x011A, 0x0119, 0x0119, 0x10D2, 0x20AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08F3, 0x08F3, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10CF, 0x0119, 0x011A, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x10D2, 0x0119, 0x011A, 0x08F6, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x08F5, 0x013A, 0x00F8, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18B0, 0x0118, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0118, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x10D2, 0x00F9, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x011A, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x00F9, 0x10D2, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x0119, 0x00F9, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x20AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CF, 0x0119, 0x00F9, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08F6, 0x0119, 0x0119, 0x0119, 0x0119, 0x0118, 0x08F5, 0x10D1, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x10D2, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x10D2, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x10D2, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x00F9, 0x011A, 0x10D2, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AF, 0x0118, 0x0119, 0x0117, 0x18AE, 0x18AE, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x10D0, 0x0119, 0x0119, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x10D2, 0x00F9, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x00F9, 0x10D2, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x20AD, 0x18AE, 0x18AE, 0x18AD, 0x20AE, 0x18AD, 0x08D5, 0x0119, 0x00F9, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x10F3, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x10D0, 0x00F9, 0x011A, 0x00F7, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, + 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18D0, 0x00F9, 0x0119, 0x00F7, 0x18CE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x10D0, 0x10D3, 0x08F4, 0x08F3, 0x08F3, 0x10F3, 0x08F3, 0x08F3, 0x08F3, 0x08F3, 0x08F3, 0x08F3, 0x08F3, 0x08F3, 0x08F3, 0x10D3, 0x10D3, 0x08F3, 0x08F3, 0x08D4, 0x10D3, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18CF, 0x0118, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18B0, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18CF, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x20AD, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x011A, 0x0119, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x011A, 0x10D1, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x20AD, 0x18CD, 0x10F3, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08F3, 0x08F3, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AF, 0x00F9, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, + 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x10D1, 0x0119, 0x0119, 0x08F5, 0x18AE, 0x18AD, 0x18AF, 0x0119, 0x011A, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F3, 0x00F9, 0x011A, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x18D0, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x00F9, 0x0119, 0x08F5, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x10D2, 0x011A, 0x0119, 0x08F5, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x08F5, 0x0119, 0x00F9, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x08F5, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18CD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x20AE, 0x18AE, 0x18AE, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18D0, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x08F4, + 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08F7, 0x18AE, 0x18CD, 0x18AF, 0x0119, 0x011A, 0x00F9, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x10CF, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x18CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x08D5, 0x0119, 0x0119, 0x10D2, 0x18CE, 0x18AE, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D1, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x00F7, 0x00F7, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18B0, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, + 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x011A, 0x00F7, 0x18AE, 0x18AD, 0x18B0, 0x0118, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0118, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x20AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x00F9, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x011A, 0x10D2, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x10D1, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x08F3, 0x00F9, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AF, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x08F5, 0x0119, 0x0119, + 0x08F5, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x10D0, 0x00F9, 0x0119, 0x0117, 0x18AE, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F3, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x00F7, 0x18AF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x10D2, 0x00F9, 0x0119, 0x08F5, 0x20AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08D5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AE, 0x08F5, 0x0119, 0x00F9, 0x10D2, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x0119, 0x011A, 0x10D0, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x10D2, 0x011A, 0x011A, 0x10D2, + 0x18AD, 0x08F5, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x00F9, 0x00F9, 0x0119, 0x011A, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x10D0, 0x0119, 0x00F9, 0x00F7, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x0119, 0x0119, 0x08F6, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D1, 0x08F3, 0x08F3, 0x10D2, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x10D2, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x10D2, 0x0119, 0x011A, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x10D2, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x20AE, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x011A, 0x08D3, 0x18AD, 0x18AD, 0x08D3, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AF, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AE, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x0119, 0x0119, 0x10D3, 0x18AD, + 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x10B0, 0x0119, 0x0119, 0x08F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0139, 0x011A, 0x0119, 0x08F6, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AE, 0x18AD, 0x20CE, 0x00F7, 0x011A, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x10D2, 0x00F9, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x20AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x00F9, 0x10D2, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08D5, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x08D5, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x00F7, 0x00F7, 0x0139, 0x0119, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18B0, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x20AD, + 0x18AE, 0x18AD, 0x18AD, 0x08D5, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18B0, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D3, 0x011A, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0116, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18CD, 0x08F5, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08D5, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D0, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x08F7, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18D0, 0x00F9, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x10D1, 0x00F9, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, + 0x20AD, 0x18AE, 0x18AD, 0x20AD, 0x08F5, 0x0119, 0x011A, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x00F6, 0x18AE, 0x18AE, 0x18D0, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F6, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CF, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x011A, 0x0119, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18CD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x18CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x00FA, 0x18D1, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x10F3, 0x08D3, 0x10D2, 0x0117, 0x011A, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AF, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CF, 0x00F9, 0x0119, 0x08F5, 0x18CE, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F6, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x0116, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18D0, 0x00F9, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AF, 0x00F8, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F6, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00F9, 0x0119, 0x08D4, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D1, 0x011A, 0x0119, 0x08F5, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08D4, 0x0119, 0x00F9, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x08D5, 0x0119, 0x00F9, 0x18AD, 0x18AE, 0x208D, 0x18AE, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D0, 0x00F8, 0x0119, 0x0117, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x0118, 0x0119, 0x00F7, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, + 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CF, 0x00F8, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x00F9, 0x18AF, 0x20AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x0118, 0x011A, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F3, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F6, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x10D2, 0x0119, 0x00F9, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AE, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x0117, 0x18AE, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x0119, 0x011A, 0x08F6, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18B0, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18CD, 0x20AD, 0x18AE, 0x18AE, 0x00F7, + 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AF, 0x08F6, 0x0119, 0x0119, 0x011A, 0x0119, 0x0116, 0x18CF, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x00F9, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F3, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F6, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x08D5, 0x0119, 0x0119, 0x0119, 0x00F9, 0x0119, 0x0119, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18CF, 0x00F9, 0x011A, 0x08F5, 0x20AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x011A, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x011A, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x18AE, 0x00F8, 0x0119, 0x0117, 0x18AE, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18D0, 0x0118, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x00F9, 0x0119, 0x00F7, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F3, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F6, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x00F7, 0x011A, 0x0119, 0x011A, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AE, 0x00F8, 0x0119, 0x08F4, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x00F9, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18B0, 0x00F9, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x00F7, 0x011A, 0x00F9, + 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x00F9, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F3, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F6, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x10D2, 0x0119, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18CD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18CD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x20AE, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x08F5, 0x0119, 0x00F9, 0x18CF, + 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F6, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AE, 0x20AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D1, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x18AE, 0x00F8, 0x0119, 0x00F7, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x18D0, 0x18AD, + 0x011A, 0x0119, 0x08F5, 0x18AE, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F6, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x20AD, 0x18AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D1, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x18AE, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F7, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AE, 0x18AD, 0x20AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x20AE, + 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x20AD, 0x08F5, 0x0119, 0x011A, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F3, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x00F6, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x00FA, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x10D2, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F7, 0x18CE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x08D5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, + 0x08F7, 0x00F9, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x08F3, 0x08F3, 0x10F3, 0x08F3, 0x10D3, 0x08F3, 0x08F3, 0x08F3, 0x08F3, 0x08F3, 0x08F3, 0x08F3, 0x08F3, 0x08F3, 0x08F3, 0x08F3, 0x08F3, 0x08F3, 0x08F3, 0x08F3, 0x08F3, 0x08F3, 0x08F3, 0x08F3, 0x08F3, 0x10F2, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x00F9, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x10D2, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x08F3, 0x0119, 0x0119, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x310E, 0x18AD, 0x20AE, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x10F2, 0x0119, 0x0119, 0x10D2, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00FA, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18D0, + 0x18AE, 0x0117, 0x00F9, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18CE, 0x00F8, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F7, 0x18CE, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08D5, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x28EE, 0x8252, 0xCB54, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AE, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x0119, + 0x18AD, 0x18AE, 0x08F7, 0x0119, 0x011A, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x00F9, 0x0119, 0x00F7, 0x00F7, 0x0119, 0x0119, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AE, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x394F, 0xB313, 0xD395, 0x7211, 0x18AD, 0x18AD, 0x20CD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x00F9, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x20AD, 0x18CD, 0x18CD, 0x20AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x0119, + 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x011A, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x011A, 0x18CD, 0x20AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x0119, 0x011A, 0x08F3, 0x18AD, 0x18AD, 0x08F4, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x00F9, 0x10D2, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x496F, 0xCB55, 0xD395, 0xBB54, 0x28CE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x0119, 0x011A, 0x00F7, + 0x188D, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x10D2, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x208D, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00FA, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AF, 0x0119, 0x0119, 0x18D0, 0x18AD, 0x18AD, 0x10D0, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x61D0, 0xD395, 0xD395, 0xD395, 0x69F1, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08F3, 0x08F3, 0x10D2, 0x20CD, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18D0, 0x00F9, 0x011A, 0x00F7, 0x18AE, + 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x011A, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x00F9, 0x011A, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x08F3, 0x18AD, 0x18AD, 0x10D3, 0x011A, 0x011A, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x08F5, 0x0119, 0x00F9, 0x10D2, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x61D0, 0xD395, 0xD395, 0xD396, 0xD375, 0x310E, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x011A, 0x00F9, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x0117, 0x18AE, 0x18AD, + 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AE, 0x00F7, 0x0119, 0x011A, 0x0119, 0x08F5, 0x18AE, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08D4, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08D5, 0x0119, 0x0119, 0x00F7, 0x0117, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x20AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x392F, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0x28CE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x00F7, 0x00F7, 0x0119, 0x011A, 0x08F4, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AE, + 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x011A, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x0119, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x10D2, 0x0119, 0x00F9, 0x10F2, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x011A, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x310E, 0xCB55, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0x8252, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x10D2, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18CD, 0x18AD, 0x20AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x08F3, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AF, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AE, 0x18AD, 0x18AD, + 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x08F7, 0x00F9, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x10F2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x08F5, 0x0119, 0x00F9, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x10D2, 0x10D3, 0x08F3, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x00F9, 0x10D2, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0xB314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0x5190, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x011A, 0x011A, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x011A, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x00F9, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AF, 0x0119, 0x0119, 0x10D0, 0x18AD, 0x18AD, 0x18D0, 0x00F9, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, + 0x0119, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x00F9, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18EE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x011A, 0x011A, 0x0119, 0x0119, 0x00F9, 0x0119, 0x011A, 0x00F9, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x10F2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x08D5, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x08F5, 0x011A, 0x0119, 0x10D2, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x8252, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0x412F, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x08D5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F4, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x20AE, 0x20AD, 0x18AE, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x10F3, 0x18AD, 0x18AE, 0x08F3, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x011A, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x0118, 0x0119, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x188D, 0x18AD, 0x18AD, 0x18AE, 0x08F7, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18CD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0355, 0x190F, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F4, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AE, 0x10D2, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x00F9, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x208E, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x08F5, 0x0119, 0x00F9, 0x10D2, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x496F, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0x496F, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x00F9, 0x0119, 0x011A, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AE, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x20AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x08F5, 0x00F9, 0x011A, 0x0117, 0x0117, 0x0119, 0x0119, 0x08D5, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18B0, 0x0119, 0x00F9, 0x0119, 0x011A, 0x10D1, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x0119, 0x08D4, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x11D1, 0x03B7, 0x0A93, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x00F9, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AE, 0x10D2, 0x011A, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AE, 0x08F5, 0x0119, 0x00F9, 0x10D2, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x28EE, 0xBB34, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0x9AB3, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x00F9, 0x00F9, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x10AF, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x011A, 0x011A, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x10D0, 0x0118, 0x011A, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x188D, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x00F9, 0x10F2, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x208D, 0x18AD, 0x10D2, 0x08F3, 0x10D3, 0x10D2, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0356, 0x03B7, 0x03B7, 0x190F, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08F3, 0x08D4, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x00F9, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x10D2, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x0119, 0x0119, 0x00FA, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x7A31, 0xD395, 0xD395, 0xD375, 0xDB95, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD396, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08F3, 0x08F4, 0x10D2, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18CD, 0x18AD, 0x10CF, 0x0119, 0x0119, 0x0119, 0x0119, 0x10D1, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x0117, 0x00FA, 0x0119, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D1, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x11D1, 0x03B8, 0x03B7, 0x03B8, 0x0A94, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x10D2, 0x00F9, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x00F9, 0x10D2, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x08F5, 0x00F9, 0x011A, 0x0119, 0x011A, 0x0119, 0x011A, 0x08F5, 0x20AE, 0x18AD, 0x18CD, 0x18AD, 0x18CD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08D5, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AE, 0x18AD, 0x18CD, 0x18AD, 0x20AD, 0x18AD, 0x310E, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD396, 0xD395, 0xD395, 0xB313, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x011A, 0x011A, 0x011A, 0x0119, 0x08F5, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x08F5, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x08F5, 0x0119, 0x00F9, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AE, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x011A, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x10D2, 0x18CD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x00F8, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x0356, 0x03B7, 0x03B7, 0x03B8, 0x03B7, 0x190E, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x10D2, 0x011A, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x011A, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x08F5, 0x0119, 0x00F9, 0x10D2, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AE, 0xA2D3, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xA2D3, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x0119, 0x0119, 0x0119, 0x0117, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x00F9, 0x0119, 0x011A, 0x0119, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18CE, 0x00F7, 0x011A, 0x011A, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x011A, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x00F8, 0x10D0, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18CD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x11D1, 0x03B8, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x0A94, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AE, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08D4, 0x08F3, 0x10D2, 0x18CD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18B0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x496F, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xAAD3, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x10D1, 0x08F3, 0x08F3, 0x10D2, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18CD, 0x10D2, 0x08F3, 0x08D4, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F4, 0x0119, 0x0119, 0x10D1, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x0118, 0x00F9, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0356, 0x03B8, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x190F, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x00F9, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x08F5, 0x0119, 0x00F9, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0xB314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0x61D0, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18CD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x0119, 0x0119, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18CE, 0x08F5, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x00F9, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x0397, 0x03B8, 0x03B7, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x00F9, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x59D0, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD396, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F4, 0x011A, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18B0, 0x0118, 0x0119, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18CD, 0x20AE, 0x18AE, 0x00F7, 0x011A, 0x011A, 0x011A, 0x10D2, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x03B7, 0x03B7, 0x03B7, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x03B7, 0x03B7, 0x0397, 0x03B7, 0x03B8, 0x03B7, 0x03B7, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x011A, 0x10D1, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0xBB34, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xAAD3, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x00F9, 0x10D2, 0x18CD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18B0, 0x0119, 0x00F9, 0x0119, 0x011A, 0x10D2, 0x18CD, 0x18AE, 0x18CD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x00F9, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x011A, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x03B7, 0x03B7, 0x03B7, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x0397, 0x03B7, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x011A, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AE, 0x08F5, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x61B1, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0x8A92, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x08F5, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x08F4, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x0118, 0x011A, 0x0119, 0x0119, 0x10D2, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x188D, 0x18AD, 0x10D2, 0x08F3, 0x08F3, 0x10D2, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x03B7, 0x03B7, 0x03B7, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x03B8, 0x03B7, 0x03B8, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x10D2, 0x00F9, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18CD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0xAAD3, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0x310E, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x0119, 0x0119, 0x10D1, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x10CF, 0x0119, 0x0119, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x00F7, 0x011A, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x03D7, 0x0397, 0x03B7, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x03B7, 0x03B8, 0x0397, 0x03B7, 0x03B8, 0x03B7, 0x03B7, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x10D2, 0x00F9, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x10D0, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x496F, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0x7231, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x10D1, 0x10D3, 0x08D3, 0x10D2, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x011A, 0x0119, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x03B7, 0x03B7, 0x03B8, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x10D2, 0x011A, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x08F5, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x011A, 0x0119, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20CD, 0x20AE, 0x8A92, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0x7A31, 0x20AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x011A, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0118, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x03B7, 0x03B7, 0x03B7, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x03B7, 0x03B7, 0x03B8, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AE, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x28EE, 0xC374, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xA2D3, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x10D2, 0x08F3, 0x08F3, 0x10D2, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x0118, 0x00F9, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x18D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18CE, 0x194F, 0x18AE, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x03B7, 0x0397, 0x03B8, 0x18AD, 0x20AE, 0x20AD, 0x18AD, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B8, 0x03B7, 0x03B7, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x00F9, 0x0119, 0x08F5, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x20AE, 0x20AE, 0x61D1, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0x69F1, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x10D2, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18CE, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x011A, 0x011A, 0x011A, 0x00F9, 0x08F7, 0x18CE, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x0119, 0x0119, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x10CF, 0x00F9, 0x0119, 0x0119, 0x00F9, 0x18D0, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x1930, 0x02F5, 0x03B7, 0x03B8, 0x0356, 0x114F, 0x18AD, 0x18AD, 0x18AD, 0x03B8, 0x03B7, 0x03B7, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x03B7, 0x03B8, 0x03B7, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x00F9, 0x0119, 0x08F4, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AE, 0x20AE, 0x9AB3, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0x412F, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18CE, 0x00F8, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F7, 0x18CE, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x0397, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x18AD, 0x18AD, 0x18AD, 0x0A32, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x0356, 0x18AD, 0x18AD, 0x0A32, 0x03B7, 0x03B8, 0x03B8, 0x03B8, 0x0376, 0x18EE, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x0397, 0x03B7, 0x03B7, 0x03B7, 0x03B8, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18B0, 0x0118, 0x0119, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CF, 0x00F8, 0x0119, 0x00F9, 0x0119, 0x18B0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x190F, 0x0377, 0x0397, 0x03B8, 0x0398, 0x0397, 0x0B77, 0x18CE, 0x18AD, 0x18AD, 0x03B7, 0x0397, 0x03B8, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x03B7, 0x0BB7, 0x0398, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0xC355, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0x4970, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x00F9, 0x0119, 0x00F7, 0x00F7, 0x0119, 0x0119, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B8, 0x03B7, 0x03B7, 0x0397, 0x03B7, 0x18AD, 0x18AD, 0x18AD, 0x18EE, 0x0377, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x0A33, 0x190E, 0x0397, 0x03B8, 0x03B7, 0x03B7, 0x03B7, 0x11D1, 0x18AD, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x11B0, 0x0A93, 0x0356, 0x03B7, 0x03B7, 0x03B7, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00F9, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x011A, 0x0119, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x011A, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18B0, 0x0119, 0x00F9, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x00F9, 0x0119, 0x0119, 0x0119, 0x18B0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x1253, 0x0B78, 0x0B98, 0x0B78, 0x0B98, 0x0B98, 0x1378, 0x11F2, 0x18AD, 0x18AD, 0x0B98, 0x0B78, 0x0B78, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0B98, 0x1378, 0x0B78, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x20AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x4970, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0x8252, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x0119, 0x011A, 0x08F3, 0x18AD, 0x18AD, 0x08F4, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x18AD, 0x18AD, 0x03B8, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x11D1, 0x03B8, 0x03B7, 0x03B7, 0x03B8, 0x0377, 0x0AD4, 0x0397, 0x03B7, 0x03B7, 0x03B7, 0x02F5, 0x18AE, 0x18AD, 0x03B7, 0x03B8, 0x03B7, 0x03B8, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x192F, 0x03B7, 0x03B7, 0x03B8, 0x03B8, 0x03B7, 0x03B7, 0x20AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AF, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x00F7, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x0118, 0x011A, 0x0119, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D0, 0x00F9, 0x0119, 0x0119, 0x0119, 0x18D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x1AB5, 0x1B78, 0x1B58, 0x1358, 0x1B78, 0x1378, 0x1358, 0x1A13, 0x18AE, 0x18AE, 0x1358, 0x1358, 0x1378, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x1358, 0x1358, 0x1358, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x20AE, 0x20AE, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x7A32, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD375, 0xD395, 0xC354, 0x5990, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AF, 0x0119, 0x0119, 0x18D0, 0x18AD, 0x18AD, 0x10D0, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x0397, 0x03B7, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x0356, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x0397, 0x03B7, 0x03B7, 0x194F, 0x18AD, 0x18AD, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x03B7, 0x0397, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x20AD, 0x18AD, 0x0119, 0x0119, 0x00F9, 0x0119, 0x0119, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x0119, 0x0119, 0x00F8, 0x18AE, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x10CF, 0x0119, 0x011A, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CF, 0x00F9, 0x0119, 0x00F9, 0x00F9, 0x18D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x1A54, 0x1B38, 0x1B38, 0x2338, 0x1B38, 0x1B58, 0x2338, 0x21D2, 0x18AD, 0x18AD, 0x2338, 0x2338, 0x2358, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x1930, 0x2339, 0x2358, 0x2338, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0xA2B3, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0x4970, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x08F3, 0x18AD, 0x18AD, 0x10D3, 0x011A, 0x011A, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x1170, 0x03B8, 0x03B8, 0x03B7, 0x03B7, 0x03B8, 0x03B7, 0x03B7, 0x03B7, 0x0A53, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x03B7, 0x03B7, 0x0397, 0x03B7, 0x03B7, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x0396, 0x03B8, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18D0, 0x0118, 0x0119, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x10D0, 0x00F9, 0x0119, 0x0119, 0x0119, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x2150, 0x2B18, 0x2B39, 0x2B18, 0x2B19, 0x2B19, 0x2AF8, 0x18CE, 0x18AD, 0x18AD, 0x2B19, 0x2B18, 0x2B19, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x2192, 0x2B19, 0x2B19, 0x2B18, 0x2338, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0xBB34, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0x4970, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08D5, 0x0119, 0x0119, 0x00F7, 0x0117, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B8, 0x03B7, 0x03B7, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0AF5, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x0377, 0x18EE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x03B7, 0x03B8, 0x03B7, 0x03B7, 0x03B8, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x11B0, 0x03B7, 0x03B8, 0x03B7, 0x03B7, 0x03B7, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CE, 0x0117, 0x011A, 0x0119, 0x0119, 0x0119, 0x0117, 0x18AE, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x011A, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x10CF, 0x0118, 0x0119, 0x0119, 0x0119, 0x18D0, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08F3, 0x10D3, 0x10D2, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x2192, 0x2B19, 0x3319, 0x32F9, 0x2A15, 0x18EF, 0x20AD, 0x18AD, 0x18AD, 0x32F9, 0x3319, 0x32F9, 0x18AD, 0x18AD, 0x18AD, 0x2191, 0x3319, 0x2AF9, 0x3319, 0x2AF9, 0x2A97, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x0119, 0x0119, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x20CF, 0x20CF, 0x28CF, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0x71D1, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x20CD, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x011A, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B8, 0x0397, 0x03B7, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x190F, 0x03B7, 0x03B7, 0x03B8, 0x03B7, 0x03B7, 0x03B7, 0x11D1, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x03B7, 0x0397, 0x03B7, 0x03B7, 0x03B7, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x10D2, 0x08F3, 0x08F3, 0x10D2, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x0118, 0x00F9, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18D0, 0x0119, 0x011A, 0x0119, 0x0119, 0x18D0, 0x10D2, 0x08F3, 0x08F3, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x3AD9, 0x3AD9, 0x3AD9, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x3AF9, 0x3AD9, 0x3AD9, 0x18AD, 0x20AD, 0x3215, 0x3AD9, 0x3AF9, 0x3ADA, 0x3AD9, 0x3277, 0x18CE, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x011A, 0x20CD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CF, 0x28CF, 0x4950, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD374, 0xD375, 0xD355, 0xD355, 0xAAB3, 0x20CE, 0x18CE, 0x20CE, 0x20AE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x10D2, 0x10D3, 0x08F3, 0x10D2, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x0398, 0x0398, 0x0398, 0x0398, 0x03B7, 0x0397, 0x0397, 0x03B7, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x0AD5, 0x0397, 0x0398, 0x03B8, 0x0398, 0x03B8, 0x18EE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0398, 0x0398, 0x03B8, 0x0398, 0x0398, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0398, 0x0398, 0x0398, 0x0398, 0x0398, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x0119, 0x0119, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18D0, 0x00F8, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0139, 0x011A, 0x0117, 0x00F7, 0x011A, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x42D9, 0x42B9, 0x42B9, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x42B9, 0x42B9, 0x42BA, 0x18AE, 0x31F5, 0x42DA, 0x42D9, 0x42B9, 0x42D9, 0x3A77, 0x18CE, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x20AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x0119, 0x0119, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x5991, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD374, 0xD375, 0xD355, 0xD355, 0xD355, 0x9252, 0x30EF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x2338, 0x2338, 0x2318, 0x2319, 0x2338, 0x2338, 0x2338, 0x2338, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x2150, 0x2318, 0x2338, 0x2338, 0x2318, 0x2318, 0x2338, 0x21F3, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x2339, 0x2318, 0x2318, 0x2339, 0x2338, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x2338, 0x2338, 0x2338, 0x2338, 0x2338, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18B0, 0x0119, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18B0, 0x0118, 0x0119, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x0119, 0x0119, 0x0117, 0x00F7, 0x011A, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x00F9, 0x0119, 0x10D3, 0x18AD, 0x18AD, 0x10F3, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18B0, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x4A99, 0x4AB9, 0x4A9A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x4ABA, 0x4ABA, 0x4A9A, 0x4257, 0x4A99, 0x4A9A, 0x4A9A, 0x4ABA, 0x4237, 0x20CE, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AE, 0x20AE, 0x0119, 0x0119, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x69F1, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD375, 0xD355, 0xD355, 0xD355, 0xD335, 0xD355, 0xCB14, 0x4130, 0x20AF, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x18AD, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x18AD, 0x208E, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x42B9, 0x4A99, 0x42B9, 0x42BA, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x4257, 0x4ABA, 0x4A9A, 0x4A99, 0x42B9, 0x4A9A, 0x42B9, 0x4A9A, 0x20EF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x4A9A, 0x42B9, 0x42B9, 0x4ABA, 0x4AB9, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x4A99, 0x42B9, 0x4ABA, 0x4A99, 0x4A99, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x0119, 0x0119, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18B0, 0x0119, 0x00F9, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x0119, 0x011A, 0x08F3, 0x18AD, 0x18AD, 0x08F3, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AF, 0x011A, 0x00F9, 0x10D0, 0x18AD, 0x20AD, 0x10D0, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0118, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x527A, 0x527A, 0x527A, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x527A, 0x527A, 0x529A, 0x527A, 0x527A, 0x527A, 0x527A, 0x4A18, 0x20CE, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x00F9, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D1, 0x0117, 0x0119, 0x0119, 0x0917, 0x18D2, 0x20CE, 0x20CF, 0x28CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x8253, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD354, 0xD355, 0x7A11, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x6A3B, 0x6A3B, 0x6A3B, 0x621A, 0x6A3B, 0x6A3B, 0x6A1B, 0x6A3B, 0x6A3B, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x3932, 0x6A3B, 0x6A3B, 0x6A1B, 0x6A3B, 0x6A3B, 0x6A3B, 0x6A3B, 0x6A3B, 0x59D7, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x6A3B, 0x6A3B, 0x6A3B, 0x6A3B, 0x6A3B, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x6A1B, 0x6A3B, 0x6A3B, 0x6A1B, 0x6A3B, 0x18AD, 0x18AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x10D2, 0x08F3, 0x10F3, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x00F9, 0x011A, 0x00F7, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x0118, 0x011A, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AE, 0x18AD, 0x18AF, 0x0119, 0x0119, 0x10D1, 0x18AD, 0x18AE, 0x10D0, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x10D3, 0x18AD, 0x20AE, 0x08F3, 0x0119, 0x0119, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x00F9, 0x18D0, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x20AD, 0x5A5B, 0x5A5A, 0x5A7A, 0x2910, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x5A5A, 0x5A7B, 0x5A5A, 0x5A5A, 0x5A5A, 0x5A5A, 0x4A18, 0x20CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D1, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x091A, 0x18F2, 0x28CF, 0x28CE, 0x28CF, 0x28CF, 0x28EF, 0x28F0, 0x30F0, 0x8232, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xA293, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x20AE, 0x20AD, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x89BC, 0x89BC, 0x89BC, 0x91BC, 0x89BC, 0x899C, 0x89BC, 0x89BC, 0x89BB, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x899B, 0x89BC, 0x89BC, 0x89BC, 0x799A, 0x7179, 0x89BB, 0x899C, 0x89BC, 0x89BC, 0x38F1, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x89BC, 0x899C, 0x899C, 0x89BC, 0x89BC, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x89BC, 0x899C, 0x89BC, 0x899C, 0x89BC, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AE, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x10D0, 0x0118, 0x011A, 0x0117, 0x18AE, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x10CF, 0x0119, 0x0119, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x00F7, 0x0117, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x18D0, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x623A, 0x623B, 0x625A, 0x621A, 0x2910, 0x18CD, 0x18AD, 0x18AD, 0x623B, 0x623A, 0x625A, 0x623B, 0x623B, 0x51F8, 0x20CE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0118, 0x0119, 0x0917, 0x18D2, 0x18D2, 0x0918, 0x091A, 0x0918, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x30D0, 0x30F0, 0x30F0, 0x8252, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xD335, 0x9253, 0x30EF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xA93D, 0xA93D, 0xA93D, 0xB13D, 0xA93D, 0xA93D, 0xA93D, 0xB13D, 0xB11D, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x60F5, 0xA93D, 0xA93D, 0xB13D, 0xA93D, 0x60F5, 0x40D1, 0xB11D, 0xB13D, 0xA93D, 0xA93D, 0x991B, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xA93D, 0xA93D, 0xA93D, 0xA93D, 0xA93D, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xA93D, 0xA93D, 0xA93D, 0xB13D, 0xA93D, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x011A, 0x00F7, 0x00F7, 0x011A, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x00F9, 0x0119, 0x00F7, 0x18CE, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x00F7, 0x00F7, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x0117, 0x011A, 0x011A, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x00F7, 0x0119, 0x00F8, 0x18D0, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x59D8, 0x6A1B, 0x6A1B, 0x6A1B, 0x6A1B, 0x4133, 0x18AD, 0x18AD, 0x6A3B, 0x6A1B, 0x6A1B, 0x6A1B, 0x51B6, 0x20CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x00F9, 0x10D3, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18D1, 0x20CE, 0x20CE, 0x18D1, 0x093A, 0x093A, 0x28EF, 0x28CF, 0x28CF, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x9273, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD334, 0xD335, 0xD334, 0xD334, 0xD314, 0xD315, 0xAA93, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0xD0BE, 0xD0BE, 0xD0BE, 0xD0BE, 0xD0BE, 0xD0BE, 0xD09E, 0xD0BE, 0xD0BE, 0x18AD, 0x18AD, 0x18AD, 0x30B0, 0xD0BE, 0xD0BE, 0xD0BE, 0xD0BE, 0xD0BE, 0x20AE, 0x18AD, 0xB8BC, 0xD0BE, 0xD0BE, 0xD0BE, 0xD0BE, 0x68B5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xD0BE, 0xD0BE, 0xD0BE, 0xD0BE, 0xD0BE, 0x20AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xD0BE, 0xD0BE, 0xD0BE, 0xD0BE, 0xD0BE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x0119, 0x011A, 0x08F3, 0x18AD, 0x18AD, 0x08F3, 0x011A, 0x0119, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x10D0, 0x00F9, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x0118, 0x011A, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08D4, 0x08F3, 0x10D2, 0x18CD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x18D0, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20CE, 0x61B8, 0x721B, 0x71FB, 0x721B, 0x721B, 0x4133, 0x20AD, 0x71FB, 0x721B, 0x71FB, 0x4174, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x0119, 0x011A, 0x18D1, 0x20AE, 0x20CE, 0x20F1, 0x093A, 0x093A, 0x28CF, 0x28CF, 0x30EF, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0xAAF4, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD314, 0xD314, 0xD315, 0x28EF, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x28CE, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x18AE, 0x20AD, 0x20AD, 0x20AE, 0x30EE, 0x6150, 0x81B1, 0xA1F2, 0xC233, 0xCA53, 0xCA54, 0xCA53, 0xC233, 0xA1F2, 0x8191, 0x512F, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0xF03F, 0xF03F, 0xF03F, 0xF03F, 0xF03F, 0xF03F, 0xF03F, 0xF03F, 0xF03F, 0x18AD, 0x20AD, 0x18AD, 0xB079, 0xF03F, 0xF03F, 0xF03F, 0xF03F, 0xA058, 0x18AD, 0x18AD, 0x7095, 0xF03F, 0xF03F, 0xF03F, 0xF03F, 0xE83E, 0x28AE, 0x20AD, 0x18AD, 0x18AD, 0xF03F, 0xF01F, 0xF03F, 0xF03F, 0xF03F, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0xF03F, 0xF03F, 0xF03F, 0xF03F, 0xF03F, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AF, 0x00F9, 0x0119, 0x18D0, 0x18AD, 0x18AE, 0x10D0, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x0119, 0x00F9, 0x0119, 0x0119, 0x10D0, 0x20AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08F3, 0x08F3, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x0119, 0x18D0, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x20CE, 0x69B9, 0x81FB, 0x79DB, 0x79DC, 0x81FC, 0x5976, 0x79DB, 0x79DC, 0x81DC, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x0918, 0x0119, 0x0917, 0x18D0, 0x20D0, 0x0917, 0x093A, 0x1138, 0x28CF, 0x30CF, 0x30EF, 0x30F0, 0x30F0, 0x3911, 0x3911, 0xAAD4, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xD314, 0xD315, 0xD315, 0xD314, 0x69B2, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CE, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x410F, 0x6990, 0x99F2, 0xC253, 0xCA74, 0xD274, 0xCA74, 0xD253, 0xCA53, 0xCA53, 0xCA53, 0xD233, 0xD253, 0xCA53, 0xD233, 0xCA33, 0xC213, 0x8991, 0x410F, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x011A, 0x08F3, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x00F9, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x00F9, 0x0119, 0x011A, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18D0, 0x0119, 0x011A, 0x0119, 0x00F9, 0x10CF, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x0917, 0x0119, 0x0119, 0x10CF, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x20AE, 0x7199, 0x89DB, 0x89BC, 0x81BC, 0x89BC, 0x89BC, 0x89BC, 0x89BC, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x011A, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18D2, 0x0119, 0x0119, 0x093A, 0x093A, 0x093A, 0x093A, 0x20F2, 0x28CF, 0x28F0, 0x30F0, 0x30F0, 0x3111, 0x3911, 0x3911, 0xB2F5, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xD315, 0xD314, 0xD314, 0xD2F4, 0xD2F5, 0xCAD4, 0x5971, 0x30F0, 0x30D0, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CE, 0x38EF, 0x79B1, 0xBA53, 0xCA94, 0xCA94, 0xCA74, 0xD273, 0xD273, 0xCA73, 0xCA54, 0xCA53, 0xCA54, 0xCA53, 0xCA33, 0xCA53, 0xCA53, 0xCA33, 0xCA33, 0xCA33, 0xD213, 0xCA13, 0xCA13, 0xA1B2, 0x490F, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20CD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x00F7, 0x00F7, 0x0119, 0x0119, 0x08D5, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AE, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AF, 0x0118, 0x0119, 0x0119, 0x00F9, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x00F9, 0x18B0, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20CE, 0x7979, 0x919C, 0x919C, 0x91BC, 0x919C, 0x899C, 0x89BC, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x10F2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AE, 0x20AE, 0x20CE, 0x18F2, 0x0919, 0x091A, 0x091A, 0x0919, 0x20F3, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x3110, 0x3911, 0x3911, 0x4112, 0xB2F5, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xD314, 0xD314, 0xD314, 0xD2F4, 0xD314, 0xD2F5, 0xD2F4, 0xD2F4, 0x4930, 0x30F0, 0x30EF, 0x28F0, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28CE, 0x28CF, 0x28CF, 0x28CF, 0x4130, 0x89F1, 0xD294, 0xD294, 0xCA93, 0xCA74, 0xD274, 0xCA74, 0xCA74, 0xCA53, 0xCA73, 0xD253, 0xD254, 0xCA53, 0xCA53, 0xCA54, 0xC274, 0x9B36, 0x83B8, 0x6419, 0x6C39, 0x6439, 0x6C1A, 0x8B57, 0xB295, 0xCA13, 0x9191, 0x28CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18CD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18CF, 0x0119, 0x00F9, 0x0119, 0x00F9, 0x18CF, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x18AF, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x28AE, 0x8159, 0x917C, 0x997C, 0x997C, 0x999C, 0x999C, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08D5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x08F4, 0x0119, 0x00F9, 0x10D2, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20D0, 0x20D1, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x3110, 0x3910, 0x4111, 0x4112, 0x4112, 0x9294, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xD315, 0xD314, 0xD2F4, 0xD2F4, 0xD315, 0xD2F4, 0xD2F5, 0xD2F4, 0xD2D5, 0x79D2, 0x3110, 0x30F0, 0x30F0, 0x30F0, 0x28F0, 0x30D0, 0x28EF, 0x28F0, 0x28CF, 0x5150, 0xAA32, 0xD293, 0xD294, 0xD294, 0xCA93, 0xCA74, 0xCA74, 0xCA74, 0xCA74, 0xD274, 0xD254, 0xCA53, 0xCA54, 0xB2D5, 0x83B8, 0x44FC, 0x1DBE, 0x063F, 0x0CDB, 0x0B76, 0x1377, 0x1377, 0x0B76, 0x1356, 0x0B76, 0x0B77, 0x23F8, 0x6991, 0x510F, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08F3, 0x08F3, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AF, 0x0119, 0x0119, 0x0119, 0x00F9, 0x18CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x00F9, 0x18AF, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x20AD, 0x20AE, 0x8939, 0xA17C, 0xA17C, 0xA15D, 0xA15D, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x10D2, 0x0119, 0x011A, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28CE, 0x28CF, 0x28CF, 0x28EF, 0x28F0, 0x30F0, 0x3110, 0x3911, 0x3911, 0x3911, 0x4112, 0x4132, 0x8A54, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD315, 0xD315, 0xD315, 0xD314, 0xD314, 0xD314, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2F4, 0xD2F4, 0xD2D4, 0xCAD4, 0x5951, 0x38F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x4130, 0x91F2, 0xD294, 0xD294, 0xCA94, 0xCA74, 0xCA94, 0xCA94, 0xCA74, 0xD274, 0xD274, 0xD274, 0xD253, 0xB2D5, 0x7419, 0x257D, 0x063F, 0x061F, 0x057D, 0x12B5, 0x190F, 0x18CE, 0x20AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AE, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x10D0, 0x0119, 0x0119, 0x011A, 0x00F9, 0x18CF, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x0117, 0x0119, 0x0119, 0x18B0, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20CE, 0x913A, 0xA93D, 0xA95D, 0xA95C, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08F5, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x20AE, 0x18AE, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CE, 0x28CF, 0x28EF, 0x28F0, 0x30F0, 0x30F0, 0x3911, 0x3911, 0x3911, 0x4132, 0x4132, 0x4932, 0x9255, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xD315, 0xD315, 0xD314, 0xD314, 0xD314, 0xD2F4, 0xD2F5, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2D4, 0xD2D4, 0xCAB4, 0x5172, 0x3911, 0x38F1, 0x38F0, 0x30F0, 0x81D2, 0xC294, 0xD294, 0xD293, 0xD294, 0xD294, 0xCA93, 0xCA93, 0xD274, 0xD274, 0xCA73, 0xD274, 0x83D8, 0x353D, 0x061F, 0x063F, 0x063F, 0x063F, 0x4C5A, 0x4970, 0x20AE, 0x20AE, 0x20AD, 0x18CD, 0x20AD, 0x20AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18CD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18D0, 0x00F9, 0x0119, 0x0119, 0x00F9, 0x10CF, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18CD, 0x10D2, 0x08F3, 0x08D4, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x00F9, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0xB11D, 0xB11D, 0xB11D, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x08D5, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x20CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x4112, 0x4132, 0x4932, 0x4953, 0x6B36, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2D4, 0xD2D4, 0xD2D5, 0xD2D4, 0xCAD4, 0xCAB4, 0x5972, 0x3911, 0x5151, 0xB253, 0xCAB4, 0xD294, 0xCA94, 0xD294, 0xCA94, 0xD294, 0xCA94, 0xCA74, 0xD274, 0xC294, 0x645A, 0x1DBE, 0x063F, 0x063F, 0x063F, 0x1DBE, 0x6459, 0xC274, 0x99D2, 0x28CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18CE, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18CD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x20AE, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x0119, 0x0119, 0x0119, 0x00F9, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AF, 0x0117, 0x0119, 0x0119, 0x0119, 0x0119, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x18D0, 0x18CD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0xB8FE, 0xB8FD, 0xB8FE, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x00F9, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28F0, 0x30F0, 0x30F0, 0x3911, 0x3911, 0x4111, 0x4132, 0x4132, 0x4933, 0x4953, 0x253B, 0x465C, 0x6D7B, 0x6D9A, 0x6D9A, 0x6D7A, 0x84F9, 0x9C78, 0x9C77, 0x9C78, 0x9C78, 0x9C57, 0x9C78, 0x9C58, 0x9C58, 0xBBB6, 0xD334, 0xD315, 0xD334, 0xD315, 0xD314, 0xD315, 0xD2F4, 0xCAF4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2D4, 0xCAD4, 0xD2D4, 0xD2D4, 0xCAD4, 0xCAB4, 0xD2D4, 0x91F3, 0x5972, 0xCA74, 0xD2B4, 0xD2B4, 0xD294, 0xCA94, 0xD294, 0xD294, 0xCA94, 0xCA74, 0xC2B4, 0x6C5A, 0x0DFF, 0x063F, 0x063F, 0x063F, 0x353D, 0x83B8, 0xCA53, 0xCA33, 0x89B1, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x011A, 0x0119, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x20AE, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CE, 0x00F7, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x00F9, 0x00F9, 0x0119, 0x00F9, 0x18CF, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x08F5, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x0119, 0x18D0, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AE, 0xC0DE, 0xC0FE, 0xC0DD, 0x18AE, 0x18CD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00F9, 0x00FA, 0x08F4, 0x18AD, 0x18AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30EF, 0x30F0, 0x30F0, 0x3911, 0x38F1, 0x3911, 0x4112, 0x4132, 0x4932, 0x4953, 0x5153, 0x4D1A, 0x6D9A, 0x94B9, 0x9C98, 0x9C77, 0x9C78, 0x9C78, 0x9C78, 0x94B8, 0x6D7A, 0x6D7A, 0x6D7B, 0x367C, 0x367D, 0x1EFE, 0x077F, 0x075F, 0x1EDE, 0x363D, 0x6D3A, 0x9C17, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xCAD4, 0xD2B4, 0xCAD4, 0xD2B3, 0xCAB4, 0xC294, 0xCAB4, 0xCA94, 0xCA94, 0xD294, 0xCA94, 0xCA74, 0xCA74, 0xCA74, 0x7BD8, 0x0DFF, 0x063F, 0x061F, 0x063F, 0x4CBB, 0x9B57, 0xD233, 0xCA33, 0xCA53, 0x6150, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x08F3, 0x08F3, 0x08F3, 0x10D2, 0x20AE, 0x10D2, 0x10D3, 0x08F3, 0x08F3, 0x18D0, 0x18AD, 0x10D2, 0x08F3, 0x08F3, 0x08F3, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x08F3, 0x08F3, 0x08F3, 0x10D2, 0x18AD, 0x10D2, 0x08F3, 0x10D3, 0x08F3, 0x18D0, 0x18AE, 0x10D2, 0x08F3, 0x08F3, 0x08F3, 0x10D1, 0x18AD, 0x10D1, 0x08F3, 0x08F3, 0x08F3, 0x10D2, 0x18AD, 0x10D2, 0x08F3, 0x08F3, 0x08F3, 0x10D1, 0x18AD, 0x10D2, 0x08F3, 0x10F3, 0x08F3, 0x10D0, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x0119, 0x00F9, 0x10D0, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x0119, 0x0119, 0x011A, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x0917, 0x0119, 0x0119, 0x18CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xC8BE, 0xC8DE, 0xC8BE, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x3912, 0x4132, 0x4132, 0x4933, 0x5153, 0xA2B5, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD355, 0xD334, 0xD335, 0xD335, 0xD335, 0xD335, 0xBB96, 0xA437, 0x74F9, 0x4DBC, 0x2E7E, 0x0EDF, 0x559B, 0x8498, 0xC335, 0xD2F4, 0xD2D4, 0xD2F5, 0xD2D4, 0xD2D4, 0xD2B5, 0xCAB4, 0xD2B4, 0xD2B4, 0xCAB4, 0xD2B4, 0xD2B4, 0xBAB4, 0xBAF6, 0xCA94, 0xD294, 0xCA94, 0xD273, 0x9B76, 0x1DBE, 0x061F, 0x063F, 0x0DDF, 0x643A, 0xB2D5, 0xCA54, 0xD253, 0xCA53, 0xC294, 0x59B1, 0x28CE, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x011A, 0x0119, 0x00F7, 0x18AD, 0x00F6, 0x0119, 0x0119, 0x011A, 0x10D3, 0x18AD, 0x0116, 0x00F9, 0x0119, 0x011A, 0x10D3, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x10D3, 0x011A, 0x0119, 0x00F9, 0x00F6, 0x18AD, 0x08F6, 0x011A, 0x011A, 0x0119, 0x10D3, 0x18CD, 0x08F6, 0x0119, 0x0119, 0x0119, 0x10D3, 0x18AD, 0x08F3, 0x0119, 0x011A, 0x0119, 0x08F7, 0x18AE, 0x00F6, 0x0119, 0x0119, 0x0119, 0x08F3, 0x18CD, 0x00F7, 0x011A, 0x011A, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x10D2, 0x08F3, 0x08F3, 0x10D1, 0x18CE, 0x00F7, 0x0119, 0x0119, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x0119, 0x0119, 0x0119, 0x00F9, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x00F9, 0x18AF, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18CD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x40B0, 0xA09A, 0xD0BE, 0xD09E, 0xD0BE, 0xB89C, 0x78B5, 0x28AE, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x011A, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30EF, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x4112, 0x4112, 0x4932, 0x4933, 0x5173, 0xBB15, 0xD395, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD355, 0xD335, 0xD335, 0xD314, 0xD314, 0xD335, 0xD315, 0xD314, 0xD315, 0xD2F5, 0xD2F5, 0xD2F4, 0x9BF7, 0x6D1A, 0x2E3D, 0x45BC, 0x9418, 0xD2D4, 0xCAD4, 0xD2D4, 0xD2B4, 0xD2B4, 0xD2B4, 0xCAB4, 0xD2B4, 0xD294, 0xD294, 0xD294, 0xC2D4, 0x4CDB, 0x7BD8, 0x9B57, 0x44FC, 0x063F, 0x063F, 0x1DBE, 0x83D8, 0xC294, 0xCA53, 0xCA54, 0xCA33, 0xCA53, 0xB2B5, 0x33B8, 0x28F0, 0x28CF, 0x28CF, 0x28CF, 0x20CF, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x188E, 0x20CD, 0x10D1, 0x0119, 0x011A, 0x10D1, 0x20AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x08F3, 0x011A, 0x011A, 0x0119, 0x00F6, 0x18AD, 0x08F6, 0x011A, 0x0119, 0x0119, 0x10D3, 0x18AD, 0x00F7, 0x0119, 0x0139, 0x011A, 0x08F3, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F3, 0x011A, 0x0139, 0x0119, 0x08F7, 0x18AD, 0x08F6, 0x0119, 0x0119, 0x0119, 0x10D3, 0x18AD, 0x08F7, 0x011A, 0x0119, 0x011A, 0x10D3, 0x20AD, 0x08F3, 0x0119, 0x0119, 0x0119, 0x08F6, 0x18AD, 0x08F6, 0x011A, 0x0119, 0x011A, 0x10D3, 0x18AD, 0x08F7, 0x0119, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x18AE, 0x18AE, 0x18CF, 0x00F8, 0x011A, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x00F9, 0x10D0, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x0119, 0x00F9, 0x0119, 0x00F9, 0x18CF, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x00F7, 0x0119, 0x0118, 0x10D0, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x40B0, 0xD07D, 0xD87E, 0xD89F, 0xD89F, 0xE07F, 0xD89E, 0xD89F, 0xB87B, 0x28AE, 0x20AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x28EF, 0x30F0, 0x30F0, 0x3110, 0x3911, 0x3911, 0x3911, 0x4132, 0x4132, 0x4933, 0x5174, 0xBB14, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD334, 0xD335, 0xD335, 0xD335, 0xD314, 0xD335, 0xD315, 0xD314, 0xD314, 0xD315, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2D4, 0xC335, 0x8478, 0x4D7B, 0x4D5B, 0xAB96, 0xD2B4, 0xCAB4, 0xD2B4, 0xD2B4, 0xCA94, 0xCAB4, 0xD294, 0xD294, 0xD273, 0xC2B4, 0x5C9A, 0x061F, 0x061F, 0x063F, 0x7419, 0xD273, 0xD273, 0xCA53, 0xCA53, 0xD233, 0xCA53, 0xAAF6, 0x153C, 0x2951, 0x30F0, 0x30F0, 0x28EF, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x0119, 0x0119, 0x0119, 0x0117, 0x18CE, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x011A, 0x0119, 0x08F6, 0x18AD, 0x08F6, 0x0119, 0x011A, 0x0119, 0x08F3, 0x18AD, 0x00F6, 0x0119, 0x0119, 0x011A, 0x10D3, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D3, 0x011A, 0x0119, 0x0119, 0x08F6, 0x18AD, 0x00F6, 0x0119, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x08F6, 0x0119, 0x0119, 0x0119, 0x08F3, 0x18AE, 0x08F3, 0x0119, 0x0119, 0x0119, 0x00F6, 0x18AE, 0x08F6, 0x011A, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x00F6, 0x0119, 0x0119, 0x0119, 0x08F3, 0x18AE, 0x18AD, 0x18AD, 0x00F7, 0x0119, 0x011A, 0x0119, 0x00F9, 0x0119, 0x0119, 0x0118, 0x10CF, 0x20AE, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18D0, 0x00F9, 0x0119, 0x0119, 0x00F9, 0x18CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F6, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x10B0, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x208D, 0x18AD, 0x10D2, 0x08F3, 0x10D3, 0x10D2, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xB07A, 0xE85F, 0xE85F, 0xE07F, 0xE85F, 0xE87F, 0xE07F, 0xE85F, 0xE07F, 0x9898, 0x20AD, 0x18AD, 0x18CD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x3110, 0x3910, 0x3911, 0x3911, 0x4112, 0x4132, 0x4932, 0x5153, 0xBB15, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD354, 0xD355, 0xD335, 0xD355, 0xD335, 0xD335, 0xD315, 0xCB34, 0xD315, 0xD314, 0xD314, 0xD315, 0xD314, 0xD2F4, 0xD2F5, 0xD2F4, 0xCAF4, 0xD2F4, 0xD2D4, 0xD2D4, 0xD2D5, 0xD2D4, 0xD2D4, 0xBB55, 0x7499, 0x35DC, 0x8439, 0xC2F4, 0xD2B4, 0xD294, 0xD294, 0xD294, 0xCA93, 0xD294, 0xD274, 0xCA74, 0x9B76, 0x061F, 0x061F, 0x83D8, 0xC295, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0x7BB8, 0x063F, 0x2A34, 0x30F0, 0x30F0, 0x30EF, 0x30F0, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x00F9, 0x08D5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F3, 0x0119, 0x011A, 0x0119, 0x08F6, 0x18AD, 0x08F7, 0x0119, 0x011A, 0x0119, 0x08F3, 0x18AD, 0x08F6, 0x0119, 0x011A, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x011A, 0x0119, 0x00F6, 0x18AD, 0x00F6, 0x011A, 0x0119, 0x0119, 0x08F3, 0x18AE, 0x00F6, 0x0119, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x08D4, 0x0119, 0x0119, 0x011A, 0x08F6, 0x18AD, 0x08F6, 0x0119, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x08F6, 0x0119, 0x0119, 0x011A, 0x08F3, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0118, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x011A, 0x00F9, 0x18CF, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0118, 0x18D0, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x38B0, 0xF05F, 0xE83F, 0xF03F, 0xF05F, 0xF05F, 0xF03F, 0xF03F, 0xF03F, 0xF05F, 0xE83F, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30EF, 0x30F0, 0x30F0, 0x30F0, 0x3911, 0x3911, 0x3911, 0x4112, 0x4132, 0x4933, 0x5173, 0xBB35, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xCB35, 0xD315, 0xD314, 0xD314, 0xD314, 0xD314, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2F5, 0xCAD4, 0xD2F4, 0xCAD4, 0xD2D4, 0xD2D4, 0xCAB4, 0xD2B4, 0xCAB4, 0xCAB4, 0x8BF8, 0x3D5C, 0x6499, 0xC2D4, 0xD294, 0xD294, 0xCA74, 0xCA74, 0xD274, 0xCA74, 0xCA74, 0x54BB, 0x5C9A, 0x353D, 0x1DBE, 0x4CBB, 0x9377, 0x9B36, 0x44FC, 0x061F, 0x1BF9, 0x3911, 0x3910, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x0119, 0x00F6, 0x18AD, 0x08F7, 0x0119, 0x011A, 0x011A, 0x10D3, 0x18AD, 0x08F6, 0x0119, 0x00F9, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x00F9, 0x0119, 0x08F6, 0x18AD, 0x08F6, 0x0119, 0x0119, 0x011A, 0x08F3, 0x18AE, 0x00F6, 0x0119, 0x0119, 0x011A, 0x10D3, 0x18AD, 0x10D3, 0x0119, 0x011A, 0x011A, 0x08F6, 0x18AD, 0x08F6, 0x0119, 0x0119, 0x0119, 0x08F3, 0x20AD, 0x08F6, 0x011A, 0x0119, 0x011A, 0x08F3, 0x18AD, 0x18AD, 0x10D0, 0x011A, 0x011A, 0x011A, 0x0119, 0x011A, 0x011A, 0x0119, 0x00F9, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x00F9, 0x0119, 0x0119, 0x00F9, 0x10CF, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F4, 0x10F3, 0x10D2, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x00F7, 0x0119, 0x0118, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x5092, 0xF83F, 0xF83F, 0xF03F, 0xF83F, 0xF83F, 0xF83F, 0xF83F, 0xF81F, 0xF03F, 0xF83F, 0x5092, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x3911, 0x3911, 0x3911, 0x4112, 0x4132, 0x4932, 0x69B3, 0xC355, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xD335, 0xD335, 0xD314, 0xD314, 0xD314, 0xD2F5, 0xD2F5, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xCAD4, 0xCAB4, 0xD2B4, 0xD2B4, 0xCAB4, 0xD294, 0x9B97, 0x453C, 0x6C59, 0xC2B4, 0xCA74, 0xD274, 0xD273, 0xCA73, 0xD273, 0xC294, 0x6C39, 0xC294, 0xCA53, 0x8B98, 0x4CBB, 0x0DFF, 0x063F, 0x0D7E, 0x3972, 0x3911, 0x3911, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x011A, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x011A, 0x00F6, 0x18AD, 0x08F6, 0x0119, 0x0119, 0x0119, 0x10D3, 0x18AD, 0x00F6, 0x011A, 0x0119, 0x0119, 0x10D3, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D3, 0x0119, 0x0119, 0x011A, 0x08F6, 0x18AD, 0x08F6, 0x0119, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x00F6, 0x0119, 0x00F9, 0x011A, 0x08F3, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x0119, 0x00F6, 0x18AD, 0x00F6, 0x00F9, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x00F6, 0x0119, 0x011A, 0x0119, 0x10D3, 0x18AD, 0x18AD, 0x10D0, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0117, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x0119, 0x0119, 0x0119, 0x00F9, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x20AE, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x0119, 0x00F9, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x18CD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x5092, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0x5092, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x4111, 0x4112, 0x4132, 0x4933, 0x9254, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD375, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD314, 0xD314, 0xD314, 0xD314, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2F4, 0xD2D4, 0xD2D4, 0xCAD4, 0xD2D4, 0xCAD4, 0xD2D4, 0xD2B4, 0xCAB4, 0xD2B4, 0xD2B4, 0xCAB4, 0xD294, 0xD294, 0xD294, 0xCA94, 0x9B77, 0x44DC, 0x73F9, 0xCA73, 0xCA74, 0xD254, 0xCA73, 0xCA53, 0xC294, 0x351C, 0x6C3A, 0xC294, 0xD253, 0xCA34, 0x83B8, 0x5A55, 0x4132, 0x4132, 0x3912, 0x3911, 0x3911, 0x3910, 0x30F0, 0x30F0, 0x30F0, 0x28F0, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x18AD, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F3, 0x00FA, 0x0119, 0x0119, 0x08F6, 0x18AD, 0x00F6, 0x0119, 0x0119, 0x011A, 0x08F3, 0x18AE, 0x08F6, 0x011A, 0x0119, 0x0119, 0x08F3, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x08F3, 0x0119, 0x0119, 0x011A, 0x08F7, 0x18AD, 0x0116, 0x011A, 0x0119, 0x011A, 0x08F3, 0x18AD, 0x08F6, 0x0119, 0x011A, 0x0119, 0x08F3, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x0119, 0x08F6, 0x18AD, 0x00F6, 0x0119, 0x0119, 0x011A, 0x08F3, 0x18AD, 0x08F6, 0x0119, 0x011A, 0x0119, 0x10D3, 0x18AE, 0x18AD, 0x18AD, 0x00F7, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x00F9, 0x00F9, 0x0119, 0x00F9, 0x18CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18B0, 0x0119, 0x011A, 0x0119, 0x00F8, 0x18D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18CE, 0x0117, 0x0119, 0x0119, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x4090, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0x28AF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x28F0, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x4112, 0x4132, 0x4132, 0x69D3, 0xC355, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xCB55, 0xD335, 0xD335, 0xD335, 0xD315, 0xD314, 0xD314, 0xD314, 0xD314, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xCAD4, 0xD2F4, 0xD2D4, 0xD2D4, 0xD2B4, 0xD2B4, 0xD2B4, 0xCAB4, 0xCAB4, 0xCAB4, 0xD2B4, 0xCAB4, 0xD294, 0xD294, 0xD294, 0xCA94, 0xD274, 0xCA74, 0x8B78, 0x447C, 0xA316, 0xD253, 0xD253, 0xCA54, 0xCA53, 0xC294, 0x257D, 0x0DDF, 0x83B8, 0xD233, 0xCA33, 0xCA33, 0xBA13, 0x7993, 0x4112, 0x4112, 0x4111, 0x3911, 0x3911, 0x38F0, 0x30F0, 0x28F0, 0x30D0, 0x30D0, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x08F5, 0x0119, 0x011A, 0x011A, 0x0119, 0x011A, 0x00F9, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x0119, 0x08F7, 0x18AD, 0x00F6, 0x0119, 0x0119, 0x011A, 0x08F3, 0x18AD, 0x08F6, 0x0119, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x0119, 0x0116, 0x20AD, 0x08F6, 0x011A, 0x00F9, 0x0119, 0x10F3, 0x18AD, 0x0116, 0x0119, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x10D4, 0x011A, 0x011A, 0x0119, 0x08F6, 0x20AD, 0x00F6, 0x0119, 0x0119, 0x011A, 0x08F3, 0x18AD, 0x08F7, 0x0119, 0x011A, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x00F7, 0x011A, 0x011A, 0x0119, 0x0119, 0x08F4, 0x20CD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x0119, 0x00F9, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x0119, 0x00F9, 0x0119, 0x00F8, 0x18CF, 0x18AD, 0x18AE, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00F9, 0x011A, 0x0119, 0x011A, 0x00F9, 0x0119, 0x0119, 0x00F9, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x20AD, 0xD03C, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xD03C, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00F9, 0x0119, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x3911, 0x3911, 0x3911, 0x4111, 0x4112, 0x5193, 0xAAD4, 0xD375, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD314, 0xD314, 0xD315, 0xD314, 0xD314, 0xD314, 0xD314, 0xD315, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2D4, 0xD2D4, 0xD2D4, 0xCAD4, 0xD2B4, 0xD2B4, 0xD2D4, 0xD2B4, 0xCAB4, 0xD2B4, 0xD2B4, 0xD294, 0xD2B4, 0xCA94, 0xCA94, 0xD294, 0xCA74, 0xCA73, 0xCA74, 0xD274, 0xC295, 0x6BB9, 0x6B99, 0xCA54, 0xCA53, 0xD254, 0xCA33, 0xC294, 0x24FD, 0x063F, 0x351D, 0xB295, 0xCA13, 0xCA13, 0xCA13, 0xB9F3, 0x7992, 0x4111, 0x4112, 0x38F1, 0x3911, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CF, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x0117, 0x18CE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F3, 0x00F9, 0x011A, 0x0119, 0x08F6, 0x18AD, 0x00F6, 0x011A, 0x0119, 0x011A, 0x10D3, 0x18AD, 0x00F6, 0x0119, 0x0119, 0x0119, 0x10D3, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D3, 0x0119, 0x0119, 0x0119, 0x08F7, 0x18AD, 0x00F7, 0x0119, 0x0119, 0x011A, 0x08F3, 0x18AE, 0x00F6, 0x011A, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x011A, 0x08F6, 0x18AD, 0x08F6, 0x011A, 0x0119, 0x0119, 0x10D3, 0x18AD, 0x08F6, 0x011A, 0x0119, 0x011A, 0x08F3, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x10D2, 0x10F3, 0x08F3, 0x10D1, 0x18AD, 0x18AE, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x0119, 0x0119, 0x0119, 0x00F9, 0x18B0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CF, 0x0118, 0x00F9, 0x0119, 0x00F9, 0x18D0, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x00F9, 0x0119, 0x0119, 0x0119, 0x00FA, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x4090, 0xF03F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0x6073, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20CD, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30EF, 0x28F0, 0x30F0, 0x30F0, 0x30F0, 0x3910, 0x3911, 0x3912, 0x4112, 0x4112, 0x8233, 0xCB55, 0xD375, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD334, 0xD314, 0xD335, 0xD314, 0xD314, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2D4, 0xD2D4, 0xD2D4, 0xCAD4, 0xD2D4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xCAB4, 0xD2B4, 0xD2B4, 0xCAB4, 0xD294, 0xD294, 0xD294, 0xCA74, 0xCA74, 0xCA74, 0xCA73, 0xCA73, 0xCA53, 0xCA53, 0xCA74, 0xAAB6, 0x5B7A, 0xBA74, 0xCA53, 0xCA33, 0xCA33, 0xC254, 0x4BFB, 0x059F, 0x0D7F, 0x8B57, 0xC9F3, 0xCA13, 0xC9F3, 0xC9F3, 0xA9B3, 0x5952, 0x4112, 0x3931, 0x3911, 0x3111, 0x3110, 0x30F0, 0x30F0, 0x28F0, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x10D2, 0x08F3, 0x10D3, 0x10D2, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x10D3, 0x10D3, 0x08F3, 0x10D2, 0x18AD, 0x10D2, 0x08F3, 0x08F3, 0x08F3, 0x18D1, 0x18AD, 0x10D2, 0x08F3, 0x08F3, 0x10D3, 0x10B0, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10B0, 0x10D3, 0x08F3, 0x08F3, 0x10D2, 0x18AD, 0x10D2, 0x08F3, 0x08F3, 0x10D3, 0x10D0, 0x18AD, 0x10D2, 0x08F3, 0x10D3, 0x08F3, 0x10D0, 0x18AD, 0x10D0, 0x08F3, 0x08F3, 0x10D3, 0x10D2, 0x18AD, 0x10D2, 0x10D4, 0x08F3, 0x08F3, 0x18D1, 0x18AD, 0x10D2, 0x08F3, 0x08F3, 0x10D3, 0x18D1, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x20AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x0119, 0x00F9, 0x0119, 0x00F9, 0x18D0, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18D0, 0x00F9, 0x0119, 0x0119, 0x0118, 0x10CF, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x011A, 0x0119, 0x011A, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x4091, 0xE01D, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0xF81F, 0x7074, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x08F3, 0x10D2, 0x20CD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AD, 0x10D1, 0x0119, 0x0119, 0x10D2, 0x20AD, 0x18AD, 0x20AE, 0x18CD, 0x20AE, 0x20CD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x3910, 0x3911, 0x3911, 0x3912, 0x4132, 0x4953, 0xB2F4, 0xD395, 0xDB95, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD334, 0x84F9, 0x467D, 0x1F5E, 0x07DF, 0x07DF, 0x07DF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x079F, 0x1F1E, 0x367D, 0x367C, 0x4DDB, 0x653A, 0x8498, 0x9BF7, 0xC2F5, 0xD294, 0xD294, 0xD294, 0xD294, 0xCA94, 0xCA94, 0xCA74, 0xCA73, 0xD253, 0xD254, 0xCA74, 0xCA53, 0xCA53, 0xCA53, 0xD253, 0x72D9, 0xAA76, 0xCA33, 0xD233, 0xCA13, 0xCA33, 0x1C7E, 0x059F, 0x05FF, 0x5C7A, 0xCA13, 0xC9F3, 0xC9F3, 0xC9F3, 0xD1F3, 0x9193, 0x4911, 0x3911, 0x3911, 0x3911, 0x3110, 0x30F0, 0x30F0, 0x30F0, 0x28EF, 0x28EF, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x208D, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AE, 0x18AD, 0x18CD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18D0, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0118, 0x10B0, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x10D1, 0x08F3, 0x08F3, 0x10D2, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x7074, 0x9077, 0x8856, 0x8876, 0x388F, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18CD, 0x18AE, 0x18CE, 0x00F7, 0x0119, 0x011A, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x08F7, 0x0119, 0x011A, 0x0119, 0x0119, 0x08F7, 0x18CE, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30EF, 0x30F0, 0x30F0, 0x30F0, 0x3111, 0x3111, 0x38F1, 0x3911, 0x4111, 0x4132, 0x6193, 0xC355, 0xD396, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD375, 0xD355, 0xD355, 0xD335, 0xD335, 0xB3D6, 0x271D, 0x07FF, 0x07FF, 0x07BF, 0x079F, 0x079F, 0x077F, 0x079F, 0x077F, 0x077F, 0x077F, 0x077F, 0x077F, 0x077F, 0x077F, 0x075F, 0x077F, 0x077F, 0x077F, 0x077F, 0x077F, 0x077F, 0x077F, 0x079F, 0x079F, 0x1EFE, 0x461C, 0x6D1A, 0x9BD6, 0xCA74, 0xCA74, 0xCA74, 0xCA73, 0xD274, 0xCA74, 0xCA53, 0xD254, 0xCA54, 0xD253, 0xCA53, 0xCA33, 0xA275, 0x9A76, 0xCA33, 0xCA13, 0xCA33, 0x9AD6, 0x04FF, 0x05BF, 0x063F, 0x357C, 0xC254, 0xC9F3, 0xD1F3, 0xC9F3, 0xC9F3, 0xB9D3, 0x6152, 0x4111, 0x3911, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x00F8, 0x10D0, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x208E, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x00F9, 0x08F5, 0x18AE, 0x20AD, 0x18AD, 0x08F4, 0x0119, 0x011A, 0x00F7, 0x0117, 0x0119, 0x011A, 0x08F5, 0x20AE, 0x20AE, 0x20AD, 0x20CE, 0x20CE, 0x20CE, 0x20CD, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30EF, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x3910, 0x3911, 0x3911, 0x3911, 0x4112, 0x4132, 0x6193, 0xCB55, 0xD395, 0xD395, 0xD375, 0xD395, 0xD375, 0xD375, 0xD375, 0xD355, 0xD375, 0xD355, 0xD355, 0xD355, 0xCB55, 0xD334, 0xCB55, 0xAC17, 0x0FBF, 0x07FF, 0x07FF, 0x07BF, 0x07BF, 0x077F, 0x075F, 0x075F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x073F, 0x075F, 0x075F, 0x077F, 0x077F, 0x079F, 0x07BF, 0x365C, 0x74B9, 0xB315, 0xCA73, 0xCA54, 0xCA54, 0xCA53, 0xCA53, 0xCA53, 0xCA33, 0xD233, 0xCA33, 0xB235, 0xAA16, 0xCA33, 0xCA13, 0xCA13, 0x7B37, 0x055F, 0x05FF, 0x067F, 0x25DD, 0xA2F5, 0xD1D3, 0xC9F3, 0xC9D3, 0xC9D2, 0xC9D3, 0x9193, 0x4932, 0x4111, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x0118, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18B0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x0119, 0x00F9, 0x011A, 0x011A, 0x0119, 0x011A, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x10D3, 0x18CE, 0x20AD, 0x10F4, 0x011A, 0x0119, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x3911, 0x4111, 0x4132, 0x4132, 0x61B3, 0xCB75, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD375, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0x8CB8, 0x0FBF, 0x07FF, 0x07DF, 0x07BF, 0x079F, 0x077F, 0x075F, 0x073F, 0x071F, 0x06FF, 0x06FF, 0x06FF, 0x06FF, 0x06FF, 0x06FF, 0x06FF, 0x06DF, 0x06FF, 0x06DF, 0x06DF, 0x06DF, 0x06FF, 0x06FF, 0x06FF, 0x06FF, 0x071F, 0x071F, 0x071F, 0x073F, 0x073F, 0x073F, 0x073F, 0x075F, 0x075F, 0x071F, 0x2DFD, 0x7419, 0xB2B5, 0xCA53, 0xCA53, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xD233, 0xCA14, 0xA215, 0xCA13, 0xCA13, 0xC9F3, 0x8338, 0x05BF, 0x063F, 0x06BF, 0x0E9F, 0xAAD5, 0xC9D3, 0xC9D2, 0xC9D3, 0xC9D3, 0xC9B2, 0xB1B2, 0x5931, 0x3911, 0x3911, 0x3911, 0x30F0, 0x30F0, 0x28F0, 0x28EF, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18CF, 0x011A, 0x0119, 0x10D0, 0x18AD, 0x20AE, 0x18D0, 0x0119, 0x0119, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x3111, 0x38F1, 0x3911, 0x3911, 0x4112, 0x4112, 0x4132, 0x6193, 0xCB75, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD354, 0xD355, 0xD355, 0xC395, 0x5DFA, 0x07FF, 0x07DF, 0x07BF, 0x079F, 0x077F, 0x075F, 0x073F, 0x071F, 0x06FF, 0x06DF, 0x06BF, 0x06BF, 0x069F, 0x069F, 0x069F, 0x069F, 0x06BF, 0x06BF, 0x069F, 0x069F, 0x069F, 0x069F, 0x069F, 0x069F, 0x069F, 0x06BF, 0x06BF, 0x06BF, 0x06DF, 0x06DF, 0x06FF, 0x06FF, 0x06FF, 0x071F, 0x071F, 0x06FF, 0x06BF, 0x065F, 0x05BF, 0x443C, 0x8AF7, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA13, 0xCA13, 0xCA13, 0x99B6, 0xC9F3, 0xCA13, 0xC9F3, 0x4C3B, 0x061F, 0x069F, 0x06FF, 0x0EBE, 0xA2D5, 0xC9B3, 0xC9D3, 0xC9B2, 0xC9B3, 0xC9B2, 0xC1B3, 0x7152, 0x3911, 0x3911, 0x3110, 0x30F0, 0x30F0, 0x28F0, 0x30D0, 0x28CF, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CE, 0x08F7, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x011A, 0x0119, 0x20AE, 0x20AD, 0x18CE, 0x0119, 0x0119, 0x10D3, 0x20CE, 0x20AE, 0x10F4, 0x0119, 0x011A, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28CF, 0x28EF, 0x30EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x3911, 0x3911, 0x3911, 0x4112, 0x3912, 0x4112, 0x4132, 0x4133, 0x5153, 0xBB35, 0xD395, 0xD396, 0xD395, 0xD375, 0xD375, 0xD375, 0xD355, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xBBD6, 0x5DFB, 0x0FBF, 0x07FF, 0x07DF, 0x07BF, 0x077F, 0x075F, 0x073F, 0x071F, 0x06FF, 0x06DF, 0x06BF, 0x069F, 0x069F, 0x067F, 0x067F, 0x067F, 0x065F, 0x065F, 0x065F, 0x065F, 0x065F, 0x065F, 0x065F, 0x065F, 0x065F, 0x065F, 0x067F, 0x065F, 0x065F, 0x067F, 0x067F, 0x069F, 0x069F, 0x069F, 0x06BF, 0x06BF, 0x06DF, 0x06BF, 0x069F, 0x065F, 0x05FF, 0x053F, 0x049F, 0x1BBE, 0x8298, 0xCA13, 0xCA13, 0xCA13, 0xCA13, 0xCA13, 0xD1F3, 0x99B6, 0xC9F3, 0xC9F3, 0xB254, 0x0D9F, 0x067F, 0x06DF, 0x06FF, 0x0EBF, 0xA2D5, 0xC9D2, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B2, 0xC9B3, 0x8152, 0x3911, 0x3911, 0x3911, 0x30F0, 0x30F0, 0x28F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x00F9, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x08F5, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x08F5, 0x18AE, 0x20AE, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x0918, 0x0917, 0x0139, 0x011A, 0x10F5, 0x20CE, 0x20CF, 0x28CF, 0x28CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30EF, 0x30F0, 0x30F0, 0x30F0, 0x3110, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x3911, 0x4112, 0x4112, 0x4132, 0x4932, 0x4133, 0x4933, 0xBB35, 0xD395, 0xD396, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xAC37, 0x6D9A, 0x2EFE, 0x07FF, 0x07FF, 0x07DF, 0x07BF, 0x079F, 0x075F, 0x073F, 0x071F, 0x06DF, 0x06BF, 0x069F, 0x067F, 0x065F, 0x065F, 0x063F, 0x063F, 0x061F, 0x061F, 0x061F, 0x061F, 0x061F, 0x061F, 0x061F, 0x061F, 0x061F, 0x05FF, 0x061F, 0x061F, 0x061F, 0x061F, 0x061F, 0x061F, 0x063F, 0x063F, 0x063F, 0x065F, 0x065F, 0x065F, 0x065F, 0x067F, 0x067F, 0x063F, 0x05DF, 0x055F, 0x04BF, 0x043F, 0x037F, 0x1ABE, 0x7A18, 0xCA13, 0xCA13, 0xCA13, 0xC9F3, 0xC1F4, 0x7178, 0xC9F2, 0xD1F3, 0x8338, 0x061F, 0x06BF, 0x06FF, 0x071F, 0x0EDF, 0xA2D5, 0xC9B3, 0xC9B3, 0xC9B2, 0xC992, 0xC992, 0xC993, 0x9172, 0x3911, 0x3910, 0x3110, 0x30F0, 0x30F0, 0x30F0, 0x28EF, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x0119, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AE, 0x00F7, 0x011A, 0x0119, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x20AD, 0x20AE, 0x20AE, 0x18CE, 0x0918, 0x011A, 0x011A, 0x0919, 0x011A, 0x0917, 0x20CF, 0x28AE, 0x20CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x28EF, 0x30EF, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x38F0, 0x3911, 0x3911, 0x3911, 0x3911, 0x3912, 0x4112, 0x4132, 0x4932, 0x4933, 0x4933, 0x4953, 0xA2B4, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD355, 0xD375, 0xD355, 0xC3B6, 0x8519, 0x4E3C, 0x0F9F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x079F, 0x077F, 0x077F, 0x075F, 0x073F, 0x06FF, 0x06BF, 0x069F, 0x067F, 0x065F, 0x063F, 0x061F, 0x061F, 0x05FF, 0x05DF, 0x05DF, 0x05DF, 0x05DF, 0x05BF, 0x05BF, 0x05DF, 0x05DF, 0x05BF, 0x05BF, 0x05BF, 0x05BF, 0x05BF, 0x05BF, 0x05DF, 0x05DF, 0x05DF, 0x05DF, 0x05FF, 0x05FF, 0x061F, 0x061F, 0x061F, 0x061F, 0x061F, 0x061F, 0x05DF, 0x057F, 0x04FF, 0x047F, 0x03DF, 0x031F, 0x025F, 0x19DE, 0x79B8, 0xC9F3, 0xCA13, 0xC9F3, 0xB9D3, 0xA1B5, 0xC9D3, 0xC9F3, 0x4C5B, 0x065F, 0x06DF, 0x071F, 0x071F, 0x0EDF, 0xA2B5, 0xC9B3, 0xC9B3, 0xC992, 0xC992, 0xC993, 0xC992, 0xB172, 0x4911, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x30EF, 0x28EF, 0x28EF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x10D2, 0x10F3, 0x10F3, 0x10D2, 0x20AE, 0x18AE, 0x20AE, 0x18CE, 0x20CE, 0x20CE, 0x20CE, 0x18F2, 0x10F4, 0x1114, 0x18F3, 0x20CF, 0x28CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x30EF, 0x30F0, 0x30F0, 0x30F0, 0x3110, 0x38F0, 0x3911, 0x3911, 0x3911, 0x3912, 0x3911, 0x4112, 0x4132, 0x4132, 0x4933, 0x4933, 0x4933, 0x4953, 0xA2B5, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xC3B5, 0x7D59, 0x36BD, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07BF, 0x07BF, 0x079F, 0x079F, 0x077F, 0x077F, 0x071F, 0x06DE, 0x069E, 0x067E, 0x065E, 0x063F, 0x063F, 0x061E, 0x05FF, 0x05DF, 0x05BF, 0x05BF, 0x059F, 0x059F, 0x059F, 0x057F, 0x057F, 0x057F, 0x057F, 0x057F, 0x057F, 0x057F, 0x057F, 0x057F, 0x057F, 0x057F, 0x057F, 0x059F, 0x059F, 0x059F, 0x05BF, 0x05BF, 0x05BF, 0x05DF, 0x05DF, 0x05DF, 0x05BF, 0x057F, 0x04FF, 0x049F, 0x03FF, 0x037F, 0x02BF, 0x021F, 0x017F, 0x213D, 0x9996, 0xC9F3, 0xC9F3, 0xB9D4, 0x99B6, 0xC9D3, 0xC213, 0x0DBF, 0x069F, 0x06FF, 0x071F, 0x073F, 0x0EFF, 0xA2B5, 0xC992, 0xC992, 0xC992, 0xC992, 0xC972, 0xC972, 0xA972, 0x4911, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AE, 0x18CE, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AF, 0x20CE, 0x28CE, 0x28CF, 0x28EF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x3110, 0x3910, 0x3911, 0x3911, 0x3911, 0x3911, 0x4111, 0x4131, 0x4112, 0x4132, 0x4913, 0x4933, 0x4933, 0x4953, 0x5154, 0xAAB5, 0xD375, 0xD395, 0xD375, 0xD395, 0xD375, 0x94D8, 0x467C, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07DF, 0x07BF, 0x07BF, 0x079F, 0x079F, 0x077F, 0x077F, 0x06DE, 0x06BE, 0x067E, 0x067E, 0x065E, 0x063E, 0x061E, 0x05FE, 0x05DE, 0x05DE, 0x05BE, 0x059F, 0x057F, 0x057F, 0x055F, 0x055F, 0x053F, 0x053F, 0x053F, 0x053F, 0x053F, 0x053F, 0x053F, 0x053F, 0x053F, 0x053F, 0x053F, 0x053F, 0x053F, 0x055F, 0x055F, 0x055F, 0x057F, 0x057F, 0x057F, 0x057F, 0x057F, 0x055F, 0x04FF, 0x04BF, 0x041F, 0x039F, 0x031F, 0x025F, 0x01BF, 0x013F, 0x00BF, 0x40FB, 0xB1B5, 0xC9D2, 0xB1D5, 0xB1D4, 0xC9B3, 0x6399, 0x061F, 0x06DF, 0x071F, 0x073F, 0x073F, 0x0EFF, 0xA2B5, 0xC992, 0xC992, 0xC972, 0xC972, 0xC992, 0xC972, 0xB152, 0x4111, 0x3911, 0x30F0, 0x30F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x0117, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x18AD, 0x20AE, 0x20AE, 0x20CE, 0x20CD, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28CE, 0x20CF, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30EF, 0x30D0, 0x28F0, 0x3110, 0x30F0, 0x30F0, 0x30F1, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x4112, 0x4132, 0x4132, 0x4132, 0x4932, 0x4933, 0x4953, 0x4953, 0x5153, 0x4A16, 0xA2B5, 0xD395, 0xD395, 0xD395, 0xD375, 0x8539, 0x1F5E, 0x07FF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07DF, 0x07DF, 0x07BF, 0x07BF, 0x079F, 0x07BF, 0x075F, 0x06BE, 0x069D, 0x067D, 0x065D, 0x063D, 0x063D, 0x061D, 0x05FE, 0x05DE, 0x05DE, 0x05BE, 0x059E, 0x057E, 0x055F, 0x053F, 0x053F, 0x051F, 0x051F, 0x04FF, 0x04FF, 0x04FF, 0x04FF, 0x04FF, 0x04FF, 0x04FF, 0x04FF, 0x04FF, 0x04FF, 0x04FF, 0x051F, 0x051F, 0x051F, 0x051F, 0x051F, 0x051F, 0x053F, 0x053F, 0x051F, 0x04DF, 0x04BF, 0x043F, 0x03DF, 0x035F, 0x02BF, 0x021F, 0x017F, 0x00FF, 0x009F, 0x087F, 0x7119, 0xC9D3, 0xB1D4, 0xB9D3, 0xC9B3, 0x1CFE, 0x065F, 0x06FF, 0x071F, 0x073F, 0x073F, 0x1EBE, 0xB9F3, 0xC993, 0xC972, 0xC992, 0xC972, 0xC973, 0xC952, 0xB152, 0x4111, 0x3910, 0x38F0, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x011A, 0x0139, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AD, 0x20CD, 0x20CE, 0x20AE, 0x20AE, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x20CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28CF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x3910, 0x3911, 0x3911, 0x3911, 0x3911, 0x4132, 0x4132, 0x4132, 0x4932, 0x4933, 0x4933, 0x4933, 0x4953, 0x4A15, 0x3439, 0x16BD, 0x8519, 0xD395, 0xD395, 0xD395, 0x94D8, 0x1F5E, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x071E, 0x069D, 0x069D, 0x067D, 0x065D, 0x063D, 0x063D, 0x061D, 0x05FD, 0x05DD, 0x05BD, 0x059D, 0x059E, 0x057E, 0x055E, 0x053E, 0x051E, 0x04FF, 0x04FF, 0x04DF, 0x04BF, 0x04BF, 0x04BF, 0x049F, 0x049F, 0x049F, 0x049F, 0x049F, 0x04BF, 0x04BF, 0x04BF, 0x04BF, 0x04BF, 0x04BF, 0x04DF, 0x04BF, 0x04DF, 0x04DF, 0x04DF, 0x04BF, 0x049F, 0x043F, 0x03DF, 0x035F, 0x02FF, 0x025F, 0x01BF, 0x013F, 0x00DF, 0x007F, 0x005F, 0x185E, 0x8957, 0x61B9, 0xC9D3, 0x9A96, 0x059F, 0x067F, 0x06FF, 0x071F, 0x073F, 0x075F, 0x267D, 0xB9D3, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC952, 0xB152, 0x4111, 0x38F1, 0x30F0, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18CF, 0x00F7, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x011A, 0x00F6, 0x18CE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x00F8, 0x10D0, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CF, 0x20CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x3110, 0x38F1, 0x38F1, 0x3911, 0x3911, 0x4111, 0x4112, 0x4132, 0x4112, 0x4932, 0x4932, 0x4933, 0x4933, 0x69B4, 0x6336, 0x6CD9, 0x4E5B, 0x07DF, 0x8539, 0xD395, 0xD395, 0xBC17, 0x3E9C, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07FF, 0x07DF, 0x07DF, 0x07DF, 0x07BF, 0x07DF, 0x06BD, 0x069C, 0x069C, 0x067C, 0x065C, 0x065C, 0x063C, 0x061C, 0x05FC, 0x05DC, 0x05BC, 0x05BD, 0x059D, 0x057D, 0x055D, 0x053E, 0x051E, 0x04FE, 0x04DE, 0x04BE, 0x04BF, 0x049F, 0x047F, 0x047F, 0x047F, 0x045F, 0x045F, 0x045F, 0x047F, 0x047F, 0x047F, 0x047F, 0x047F, 0x047F, 0x047F, 0x047F, 0x047F, 0x047F, 0x049F, 0x047F, 0x045F, 0x041F, 0x03DF, 0x037F, 0x031F, 0x029F, 0x021F, 0x017F, 0x011F, 0x00BF, 0x005F, 0x001F, 0x001F, 0x00FF, 0x89B7, 0xC9B3, 0x447B, 0x065F, 0x06BF, 0x071F, 0x073F, 0x073F, 0x075F, 0x3D9B, 0xC972, 0xC972, 0xC972, 0xC972, 0xC952, 0xC952, 0xC952, 0xA132, 0x3911, 0x3911, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x20AE, 0x20CD, 0x18AD, 0x18D0, 0x00F9, 0x0119, 0x0119, 0x0119, 0x00FA, 0x0119, 0x0119, 0x011A, 0x08F4, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0118, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x3110, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x3931, 0x40F1, 0x4111, 0x4132, 0x4132, 0x4132, 0x61B3, 0x9274, 0xB2F5, 0xC355, 0xD395, 0xD395, 0xD395, 0xBC16, 0x469D, 0x8539, 0xD376, 0xD375, 0x6DBA, 0x0F9F, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x077F, 0x06BC, 0x06BB, 0x069B, 0x067B, 0x065B, 0x063B, 0x063B, 0x061B, 0x05FB, 0x05DB, 0x05BB, 0x059C, 0x059C, 0x057C, 0x055C, 0x053D, 0x051D, 0x04FD, 0x04DD, 0x04BE, 0x049E, 0x047F, 0x047F, 0x045F, 0x043F, 0x043F, 0x041F, 0x041F, 0x041F, 0x041F, 0x041F, 0x043F, 0x043F, 0x043F, 0x043F, 0x043F, 0x043F, 0x043F, 0x043F, 0x043F, 0x041F, 0x03FF, 0x03BF, 0x037F, 0x033F, 0x02BF, 0x023F, 0x01DF, 0x015F, 0x00DF, 0x009F, 0x005F, 0x001F, 0x005F, 0x097F, 0xB9B3, 0xB214, 0x0DBF, 0x06FF, 0x075F, 0x073F, 0x073F, 0x075F, 0x077F, 0x6479, 0xC972, 0xC972, 0xC952, 0xC952, 0xC952, 0xC952, 0xC932, 0x9132, 0x3911, 0x3111, 0x30F0, 0x28F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x18AD, 0x18D0, 0x00F9, 0x0119, 0x00F9, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x08F4, 0x20CD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x08F5, 0x0119, 0x00F9, 0x18D0, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x30EF, 0x30F0, 0x28F0, 0x30F0, 0x3110, 0x38F0, 0x38F1, 0x3911, 0x3911, 0x3912, 0x4111, 0x4132, 0x4132, 0x5152, 0x8234, 0xC335, 0xD395, 0xD395, 0xD395, 0xD395, 0xAC57, 0x7D7A, 0x469C, 0x0F9F, 0xA4B8, 0xD395, 0x8539, 0x1F5E, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07FF, 0x07DF, 0x075D, 0x06BB, 0x06BB, 0x069A, 0x067A, 0x065A, 0x065A, 0x063A, 0x061A, 0x05FA, 0x05DA, 0x05DB, 0x05BB, 0x059B, 0x057B, 0x055B, 0x053C, 0x053C, 0x051C, 0x04FC, 0x04DD, 0x04BD, 0x047E, 0x047E, 0x045E, 0x043F, 0x041F, 0x03FF, 0x03FF, 0x03DF, 0x03DF, 0x03DF, 0x03DF, 0x03DF, 0x03DF, 0x03DF, 0x03DF, 0x03DF, 0x03DF, 0x03DF, 0x03DF, 0x03DF, 0x03DF, 0x03BF, 0x035F, 0x031F, 0x02DF, 0x027F, 0x01FF, 0x019F, 0x011F, 0x00BF, 0x007F, 0x003F, 0x001F, 0x009F, 0x39DB, 0xC992, 0x6399, 0x069F, 0x079F, 0x07FF, 0x07DF, 0x07BF, 0x077F, 0x079F, 0x9AF6, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC932, 0x7112, 0x3110, 0x30F0, 0x30EF, 0x28F0, 0x28EF, 0x28CE, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CD, 0x20CE, 0x20AE, 0x18CF, 0x00F9, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x011A, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x00F9, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08F3, 0x08D3, 0x10D2, 0x20AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x3911, 0x4112, 0x4132, 0x4132, 0x5193, 0x9274, 0xCB75, 0xD395, 0xD395, 0xD395, 0xC3D6, 0x6DBA, 0x1F7E, 0x07FF, 0x07FF, 0x36DD, 0xBC17, 0x8539, 0x1F5E, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07DF, 0x071B, 0x06DA, 0x06BA, 0x06BA, 0x0699, 0x0679, 0x0659, 0x0639, 0x0619, 0x0619, 0x05F9, 0x05DA, 0x05BA, 0x059A, 0x057A, 0x055A, 0x055B, 0x053B, 0x051B, 0x04FC, 0x04DC, 0x04BC, 0x049D, 0x047D, 0x045D, 0x043E, 0x041E, 0x03FE, 0x03DF, 0x03DF, 0x03BF, 0x03BF, 0x039F, 0x039F, 0x039F, 0x039F, 0x039F, 0x039F, 0x039F, 0x039F, 0x039F, 0x039F, 0x039F, 0x037F, 0x035F, 0x031F, 0x02DF, 0x027F, 0x023F, 0x01BF, 0x015F, 0x00FF, 0x009F, 0x005F, 0x001F, 0x003F, 0x011F, 0x99B6, 0xB9D3, 0x0D9F, 0x06DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x0F7E, 0xB9B3, 0xC952, 0xC952, 0xC952, 0xC952, 0xC931, 0xC932, 0xC132, 0x6111, 0x38F0, 0x30F0, 0x28F0, 0x30EF, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x18CE, 0x08F5, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x0117, 0x0119, 0x00F9, 0x18B0, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x3110, 0x3910, 0x3911, 0x3911, 0x3912, 0x4132, 0x4132, 0x6173, 0xA2B4, 0xD395, 0xD375, 0xD395, 0xD395, 0xC3D6, 0x6DBA, 0x0FBF, 0x07FF, 0x07DF, 0x07FF, 0x07DF, 0x1F7E, 0x07DF, 0x07FF, 0x07FF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x06F9, 0x06F9, 0x06D9, 0x06B8, 0x0698, 0x0698, 0x0678, 0x0658, 0x0638, 0x0638, 0x0618, 0x05F8, 0x05D8, 0x05B8, 0x0598, 0x0579, 0x0559, 0x0559, 0x051A, 0x04FA, 0x04DB, 0x04BB, 0x049C, 0x047C, 0x045D, 0x043D, 0x041E, 0x03FE, 0x03DE, 0x03BF, 0x039F, 0x039F, 0x037F, 0x037F, 0x037F, 0x035F, 0x035F, 0x035F, 0x035F, 0x035F, 0x035F, 0x035F, 0x033F, 0x033F, 0x031F, 0x02FF, 0x02BF, 0x027F, 0x023F, 0x01FF, 0x019F, 0x013F, 0x00BF, 0x007F, 0x003F, 0x001F, 0x005F, 0x197E, 0xB993, 0x6379, 0x063F, 0x073F, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x3DFB, 0xC952, 0xC952, 0xC932, 0xC932, 0xC932, 0xC932, 0xC912, 0xB912, 0x4111, 0x30F0, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x08F6, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F5, 0x20AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x20AE, 0x18AE, 0x00F7, 0x0119, 0x00F8, 0x18D0, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x0117, 0x00F7, 0x0119, 0x0119, 0x08F4, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28EF, 0x28CF, 0x28EF, 0x30EF, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x3911, 0x4111, 0x4952, 0x79F3, 0xB2F4, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0x94F9, 0x0FBF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x079D, 0x0719, 0x06F8, 0x06F8, 0x06D7, 0x06B7, 0x06B7, 0x0697, 0x0676, 0x0656, 0x0637, 0x0636, 0x0617, 0x05F7, 0x05D7, 0x05B7, 0x0597, 0x0578, 0x0578, 0x0538, 0x0519, 0x04F9, 0x04DA, 0x04BB, 0x049B, 0x047C, 0x043C, 0x041D, 0x041D, 0x03FE, 0x03DE, 0x03BE, 0x039E, 0x037F, 0x035F, 0x035F, 0x033F, 0x031F, 0x031F, 0x031F, 0x031F, 0x02FF, 0x02FF, 0x02FF, 0x02FF, 0x02DF, 0x02BF, 0x029F, 0x027F, 0x023F, 0x01FF, 0x019F, 0x015F, 0x00FF, 0x009F, 0x005F, 0x003F, 0x001F, 0x00BF, 0x59BA, 0xB9B3, 0x0D3F, 0x06BF, 0x079F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x7438, 0xC952, 0xC132, 0xC932, 0xC932, 0xC932, 0xC911, 0xC912, 0xA111, 0x3911, 0x30F0, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x08F5, 0x011A, 0x0119, 0x00FA, 0x0119, 0x0119, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0139, 0x00F8, 0x18B0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x011A, 0x08F3, 0x18AD, 0x18AD, 0x10D3, 0x011A, 0x00F9, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x3911, 0x3911, 0x5151, 0x79F3, 0xA2B4, 0xCB75, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xC3D6, 0x469C, 0x07FF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0xC335, 0x45D7, 0x0738, 0x0717, 0x06F6, 0x06F6, 0x06D6, 0x06B5, 0x06B5, 0x0695, 0x0675, 0x0655, 0x0635, 0x0615, 0x05F5, 0x05F5, 0x05D6, 0x05B6, 0x0597, 0x0557, 0x0538, 0x0518, 0x04F9, 0x04D9, 0x049A, 0x047B, 0x045B, 0x043C, 0x041C, 0x03DD, 0x03DD, 0x03BE, 0x039E, 0x037E, 0x035F, 0x033F, 0x033F, 0x031F, 0x02FF, 0x02DF, 0x02DF, 0x02BF, 0x02BF, 0x02BF, 0x02BF, 0x029F, 0x029F, 0x027F, 0x025F, 0x021F, 0x01FF, 0x01BF, 0x017F, 0x011F, 0x00DF, 0x009F, 0x003F, 0x001F, 0x003F, 0x013F, 0xB174, 0x6339, 0x05FF, 0x071F, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x0F9F, 0xB992, 0xC932, 0xC932, 0xC931, 0xC912, 0xC912, 0xC912, 0xC911, 0x8111, 0x30F0, 0x30F0, 0x28EF, 0x30EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20D0, 0x0119, 0x0119, 0x0119, 0x0139, 0x08F5, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AF, 0x00F9, 0x0119, 0x18D0, 0x18CD, 0x18AD, 0x10D1, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CF, 0x28EF, 0x28EF, 0x28EF, 0x30F0, 0x30F0, 0x59B2, 0x7A13, 0x9A94, 0xBB55, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xAC77, 0x2F1E, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07BC, 0x0759, 0xABB5, 0xC314, 0x1E97, 0x0736, 0x0716, 0x0715, 0x06F4, 0x06F4, 0x06F3, 0x06D3, 0x06B3, 0x06B2, 0x0692, 0x0672, 0x0653, 0x0633, 0x0613, 0x05F4, 0x05D4, 0x0595, 0x0575, 0x0556, 0x0517, 0x04F8, 0x04B9, 0x0499, 0x045A, 0x043B, 0x041B, 0x03FC, 0x03DD, 0x03BD, 0x039D, 0x037E, 0x035E, 0x033E, 0x033F, 0x031F, 0x02FF, 0x02DF, 0x02BF, 0x02BF, 0x029F, 0x027F, 0x027F, 0x025F, 0x025F, 0x023F, 0x021F, 0x021F, 0x01DF, 0x019F, 0x017F, 0x013F, 0x00FF, 0x009F, 0x007F, 0x003F, 0x001F, 0x007F, 0x399B, 0xB993, 0x055F, 0x067F, 0x079F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x45DB, 0xC132, 0xC932, 0xC912, 0xC132, 0xC912, 0xC912, 0xC911, 0xC912, 0x5111, 0x38F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x18CE, 0x10D3, 0x10F4, 0x18D0, 0x18AD, 0x18AE, 0x20CD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x00F9, 0x10D0, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x08D4, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x20CD, 0x20AE, 0x20AD, 0x20AE, 0x18CE, 0x20AE, 0x20CE, 0x20CE, 0x28AE, 0x20CE, 0x28EE, 0x5171, 0x69D2, 0x8232, 0xAAF4, 0xC334, 0xD375, 0xD3B5, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0x757A, 0x0FBF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07BD, 0x079B, 0x077A, 0x0779, 0x74D6, 0xD2D4, 0x9BF5, 0x0756, 0x0735, 0x0734, 0x0734, 0x0733, 0x0712, 0x0711, 0x0711, 0x06F0, 0x06F0, 0x06D0, 0x06AF, 0x06AF, 0x066F, 0x0650, 0x0631, 0x0611, 0x05D2, 0x0594, 0x0554, 0x0515, 0x04F7, 0x04B8, 0x0478, 0x0459, 0x043A, 0x03FB, 0x03BC, 0x03BC, 0x039D, 0x037D, 0x035E, 0x033E, 0x031F, 0x031F, 0x02FF, 0x02DF, 0x02BF, 0x02BF, 0x027F, 0x027F, 0x025F, 0x023F, 0x023F, 0x021F, 0x01FF, 0x01DF, 0x01BF, 0x019F, 0x017F, 0x013F, 0x011F, 0x00BF, 0x007F, 0x005F, 0x001F, 0x001F, 0x00DF, 0xA175, 0x33BC, 0x05DF, 0x06FF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x92D5, 0xC911, 0xC132, 0xC912, 0xC912, 0xC8F2, 0xC112, 0xC912, 0xA8F1, 0x3110, 0x30F0, 0x30EF, 0x28EF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F8, 0x18CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x0117, 0x0119, 0x0119, 0x10CF, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x08F5, 0x0119, 0x0119, 0x00F7, 0x00F7, 0x011A, 0x011A, 0x08F5, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AD, 0x390F, 0x4970, 0x59B0, 0x7A32, 0x9293, 0xAAD3, 0xCB55, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0x9CB8, 0x271D, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DE, 0x07DD, 0x07BC, 0x079B, 0x079A, 0x079A, 0x0779, 0x55B7, 0xD2B4, 0xD2B4, 0x4DB5, 0x0775, 0x0774, 0x0753, 0x0773, 0x0752, 0x0750, 0x0750, 0x074F, 0x074E, 0x074D, 0x074D, 0x074C, 0x072B, 0x072B, 0x072A, 0x070A, 0x06EA, 0x06AC, 0x064D, 0x05D0, 0x0573, 0x04F5, 0x04B6, 0x0478, 0x0438, 0x041A, 0x03FB, 0x03BC, 0x039C, 0x037C, 0x033D, 0x033D, 0x031E, 0x02FE, 0x02FF, 0x02DF, 0x02BF, 0x029F, 0x029F, 0x027F, 0x025F, 0x023F, 0x021F, 0x01FF, 0x01DF, 0x01BF, 0x019F, 0x017F, 0x015F, 0x013F, 0x011F, 0x00DF, 0x009F, 0x005F, 0x003F, 0x001F, 0x003F, 0x213D, 0x1B1E, 0x051F, 0x065F, 0x077F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x1F3D, 0xC912, 0xC912, 0xC112, 0xC112, 0xC8F1, 0xC8F2, 0xC8F1, 0xC8F2, 0x80F1, 0x30F0, 0x30F0, 0x30EF, 0x28EF, 0x28CF, 0x28CE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x00F9, 0x0119, 0x10D0, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x10D0, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x392F, 0xD395, 0xC374, 0xA2D3, 0xAAD3, 0x7A31, 0x7A31, 0x7A11, 0x7231, 0x5190, 0x496F, 0x496F, 0x4970, 0x496F, 0x494F, 0x412F, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x4970, 0x494F, 0x496F, 0x496F, 0x69F1, 0x7A31, 0x7A31, 0x9272, 0xA2D3, 0xAAF3, 0xC355, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD375, 0xD395, 0xAC57, 0x565C, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07DE, 0x07BD, 0x07BC, 0x07BC, 0x07BB, 0x079A, 0x079A, 0x0799, 0x26B8, 0xCAD4, 0xD2B4, 0xC314, 0x0F35, 0x0794, 0x0794, 0x0792, 0x0792, 0x0791, 0x0790, 0x078F, 0x078E, 0x078E, 0x078D, 0x078C, 0x07AA, 0x07A9, 0x07A9, 0x07A8, 0x07C7, 0x07C5, 0x07C4, 0x07E4, 0x07A4, 0x0727, 0x068A, 0x05AF, 0x0496, 0x0438, 0x03F9, 0x03BA, 0x039B, 0x035C, 0x035D, 0x031D, 0x031D, 0x02FE, 0x02DF, 0x02BF, 0x02BF, 0x029F, 0x027F, 0x025F, 0x025F, 0x023F, 0x021F, 0x01FF, 0x01DF, 0x019F, 0x019F, 0x017F, 0x015F, 0x013F, 0x00FF, 0x00DF, 0x00BF, 0x007F, 0x005F, 0x001F, 0x001F, 0x007F, 0x023F, 0x041F, 0x05BF, 0x06FF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x6498, 0xC911, 0xC912, 0xC8F1, 0xC8F1, 0xC8F1, 0xC8F2, 0xC8F1, 0xC8D1, 0x50F1, 0x30F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0118, 0x18D0, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x0119, 0x0119, 0x0117, 0x10D2, 0x08F3, 0x10D3, 0x10D2, 0x18CD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x496F, 0xAAD3, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xC3D6, 0x8539, 0x36DD, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07DE, 0x07BD, 0x07BD, 0x07BC, 0x07BC, 0x07BB, 0x07BA, 0x07BA, 0x07B9, 0xD2B4, 0xD2B4, 0xD2B4, 0x6535, 0x07B5, 0x07B5, 0x07B4, 0x07B3, 0x07B2, 0x07B1, 0x07B0, 0x07AF, 0x07CE, 0x07CD, 0x07CC, 0x07CB, 0x07CA, 0x07CA, 0x07C9, 0x07E8, 0x07E7, 0x07E6, 0x07E5, 0x07E5, 0x07E3, 0x07E3, 0x07E2, 0x07E1, 0x0726, 0x060C, 0x04B4, 0x03B9, 0x037B, 0x035C, 0x033D, 0x031D, 0x02DE, 0x02DF, 0x02BE, 0x029F, 0x029F, 0x027F, 0x025F, 0x023F, 0x023F, 0x021F, 0x01FF, 0x01DF, 0x019F, 0x019F, 0x015F, 0x015F, 0x013F, 0x00FF, 0x00DF, 0x00BF, 0x007F, 0x007F, 0x003F, 0x001F, 0x001F, 0x011F, 0x02FF, 0x04DF, 0x063F, 0x077F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x0F9F, 0xB972, 0xC8F2, 0xC8F2, 0xC0F1, 0xC8F2, 0xC0F2, 0xC0F1, 0xC8D1, 0xA0F1, 0x30F0, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CE, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x011A, 0x0119, 0x10CF, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x00F9, 0x18B0, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D0, 0x00F9, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x412F, 0x8A72, 0xC334, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD375, 0xAC57, 0x469C, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x467C, 0x8519, 0x8519, 0x36DD, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DE, 0x07DE, 0x07DE, 0x07DD, 0x07DC, 0x07DC, 0x07DB, 0x07DB, 0x07DA, 0x07DA, 0x9BF5, 0xD2B4, 0xD2B4, 0xC2F4, 0x0F77, 0x07D6, 0x07D5, 0x07D4, 0x07D4, 0x07D3, 0x07D2, 0x07D1, 0x07D0, 0x07EF, 0x07EE, 0x07ED, 0x07EC, 0x07EC, 0x07EA, 0x07E9, 0x07E9, 0x07E7, 0x07E6, 0x07E6, 0x07E5, 0x07E5, 0x07E4, 0x07E4, 0x07E3, 0x07E3, 0x07E2, 0x0785, 0x060C, 0x04D3, 0x035B, 0x031C, 0x02DE, 0x02DE, 0x02BE, 0x029F, 0x027F, 0x025F, 0x025F, 0x023F, 0x021F, 0x01FF, 0x01DF, 0x01BF, 0x019F, 0x019F, 0x017F, 0x015F, 0x013F, 0x011F, 0x00DF, 0x00BF, 0x009F, 0x007F, 0x005F, 0x001F, 0x001F, 0x003F, 0x01DF, 0x03BF, 0x059F, 0x06DF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x4D7A, 0xC111, 0xC0F1, 0xC8F1, 0xC8F2, 0xC8D1, 0xC8F2, 0xC0D1, 0xC8D1, 0x68F1, 0x30F0, 0x30F0, 0x28F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08F3, 0x08F3, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x0117, 0x0119, 0x00F9, 0x18CF, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x00F8, 0x18D0, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x414F, 0x61D1, 0x8251, 0xA2D3, 0xBB34, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xBC16, 0x8539, 0x469C, 0x17BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x8518, 0xD355, 0xD355, 0xD335, 0xD335, 0x84F8, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07DE, 0x07FE, 0x07DD, 0x07DD, 0x07BC, 0x07DC, 0x07DB, 0x07DB, 0x07DA, 0x8C56, 0xCAB4, 0xCAB4, 0xD294, 0x4DF7, 0x07D7, 0x07D7, 0x07D6, 0x07F5, 0x07D5, 0x07F3, 0x07F3, 0x07F2, 0x07F1, 0x07F0, 0x07EF, 0x07EE, 0x07ED, 0x07EC, 0x07EB, 0x07EB, 0x07EA, 0x07E9, 0x07E8, 0x07E8, 0x07E7, 0x07E7, 0x07E6, 0x07E6, 0x07E5, 0x07E5, 0x07E5, 0x07E5, 0x07E4, 0x07A6, 0x060E, 0x03F8, 0x02DE, 0x02BE, 0x029F, 0x027F, 0x025F, 0x023F, 0x023F, 0x021F, 0x01FF, 0x01DF, 0x01BF, 0x019F, 0x019F, 0x017F, 0x015F, 0x013F, 0x011F, 0x00DF, 0x00BF, 0x009F, 0x007F, 0x005F, 0x003F, 0x001F, 0x001F, 0x00BF, 0x029F, 0x049F, 0x063F, 0x075F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xB1D3, 0xC8F1, 0xC8F2, 0xC0F1, 0xC8D1, 0xC8D1, 0xC0F1, 0xC8D1, 0xB8D1, 0x40F0, 0x30F0, 0x28F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CF, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CE, 0x08F7, 0x0119, 0x00F9, 0x10CF, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0139, 0x00F8, 0x18B0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10D0, 0x00F9, 0x0119, 0x00F7, 0x18AF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x310E, 0x496F, 0x5990, 0x7A12, 0x7A32, 0x9272, 0xA2D3, 0xA2D3, 0xC375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xAC77, 0x757A, 0x36FD, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x4E3C, 0xD355, 0xD335, 0xD355, 0xD335, 0xD335, 0xD334, 0x7539, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07FE, 0x07DD, 0x07DD, 0x07DD, 0x07DC, 0x07FC, 0x07DC, 0x07DB, 0x6D38, 0xCAB4, 0xD294, 0xD294, 0xAB95, 0x07D8, 0x07D8, 0x07F7, 0x07F7, 0x07F6, 0x07F5, 0x07F5, 0x07F4, 0x07F3, 0x07F2, 0x07F1, 0x07F0, 0x07EF, 0x07EE, 0x07ED, 0x07ED, 0x07EC, 0x07EC, 0x07EB, 0x07EA, 0x07EA, 0x07EA, 0x07E9, 0x07E9, 0x07E8, 0x07E8, 0x07E8, 0x07E8, 0x07E7, 0x07E7, 0x07E8, 0x07C8, 0x06EB, 0x0514, 0x033C, 0x027F, 0x025F, 0x023F, 0x021F, 0x01FF, 0x01DF, 0x01BF, 0x019F, 0x019F, 0x017F, 0x015F, 0x013F, 0x011F, 0x00FF, 0x00DF, 0x00BF, 0x009F, 0x009F, 0x005F, 0x005F, 0x003F, 0x001F, 0x001F, 0x015F, 0x037F, 0x057F, 0x06DF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x4D5A, 0xC8F1, 0xC8D1, 0xC0F1, 0xC8D1, 0xC8D1, 0xC0D1, 0xC0D1, 0xC8B1, 0x78D1, 0x3110, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x0117, 0x0117, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x0117, 0x0119, 0x00F9, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AF, 0x0118, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x496F, 0x496F, 0x4970, 0x7A12, 0x7A31, 0x8252, 0xAAD3, 0xA2D3, 0xBB34, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xCBD6, 0x94F8, 0x565B, 0x0FBF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xB3F6, 0xD335, 0xD335, 0xD334, 0xD335, 0xD335, 0xD335, 0xD334, 0x1F7E, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07DE, 0x07DD, 0x07FD, 0x07FD, 0x07FD, 0x07DD, 0x07DC, 0x6D38, 0xCAB4, 0xD294, 0xCA94, 0xD294, 0x1F39, 0x07F9, 0x07F8, 0x07F8, 0x07F8, 0x07F7, 0x07F7, 0x07F6, 0x07F5, 0x07F4, 0x07F3, 0x07F2, 0x07F2, 0x07F1, 0x07F0, 0x07EF, 0x07EF, 0x07EE, 0x07EE, 0x07ED, 0x07ED, 0x07EC, 0x07ED, 0x07EC, 0x07EB, 0x07EC, 0x07EB, 0x07EB, 0x07EA, 0x07EA, 0x07EA, 0x07CA, 0x07AB, 0x076C, 0x070D, 0x05B2, 0x039B, 0x023F, 0x021F, 0x01FF, 0x01DF, 0x01BF, 0x019F, 0x017F, 0x017F, 0x015F, 0x013F, 0x011F, 0x00FF, 0x00DF, 0x00DF, 0x009F, 0x009F, 0x007F, 0x005F, 0x003F, 0x003F, 0x001F, 0x60D9, 0x0A3F, 0x047F, 0x063F, 0x075F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xA9D3, 0xC0D1, 0xC8D1, 0xC0F1, 0xC8B1, 0xC0D1, 0xC8B1, 0xC0B1, 0xB8B1, 0x48F1, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x18AE, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x011A, 0x00F8, 0x10D0, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x00F9, 0x10D0, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18D0, 0x00F9, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x18CD, 0x20AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x4970, 0x4970, 0x5990, 0x7A31, 0x7231, 0x7A31, 0x7A31, 0x9AB3, 0xAAD4, 0xA2D4, 0xB314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0x94F8, 0x565C, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xD335, 0xD334, 0xD335, 0xD335, 0xD335, 0xD335, 0xD314, 0xD315, 0x5DDB, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FD, 0x07FD, 0x6D58, 0xD294, 0xD293, 0xCA94, 0xD274, 0x4DF8, 0x07FB, 0x07FA, 0x07FA, 0x07F9, 0x07F9, 0x07F8, 0x07F7, 0x07F6, 0x07F6, 0x07F5, 0x07F5, 0x07F4, 0x07F3, 0x07F3, 0x07F2, 0x07F1, 0x07F1, 0x07F0, 0x07F0, 0x07F0, 0x07EF, 0x07EF, 0x07EF, 0x07EF, 0x07EF, 0x07EE, 0x07EE, 0x07EE, 0x07EE, 0x07EE, 0x07ED, 0x07CD, 0x078E, 0x076E, 0x0710, 0x06B1, 0x0574, 0x037B, 0x01FF, 0x01DF, 0x01BF, 0x019F, 0x017F, 0x017F, 0x013F, 0x013F, 0x011F, 0x00FF, 0x00DF, 0x00BF, 0x009F, 0x009F, 0x007F, 0x005F, 0x003F, 0x003F, 0x001F, 0x88D6, 0x6159, 0x031F, 0x053F, 0x06DF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x4D5B, 0xC0D1, 0xC8D1, 0xC8D1, 0xC0B1, 0xC8B1, 0xC8B2, 0xC0B1, 0xC8B1, 0x90D1, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CF, 0x20CF, 0x20CF, 0x20CE, 0x20AE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x0119, 0x011A, 0x10D1, 0x18AD, 0x18AD, 0x10D1, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00FA, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F8, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x0117, 0x0119, 0x0119, 0x10CF, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18B0, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x10D2, 0x08F3, 0x08F3, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AE, 0x18AD, 0x18CE, 0x18AD, 0x20AE, 0x20AD, 0x20CE, 0x20CE, 0x290F, 0x5170, 0x5170, 0x69F1, 0x7A32, 0x8232, 0xAAF3, 0xAAF4, 0xCB75, 0xD395, 0xD396, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xC3B6, 0x8539, 0x1F7F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xD335, 0xD335, 0xD335, 0xD315, 0xD314, 0xD315, 0xD314, 0xD314, 0x659A, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x6D39, 0xD294, 0xCA94, 0xD274, 0xCA74, 0x7C96, 0x07FC, 0x07FC, 0x07FB, 0x07FB, 0x07FA, 0x07FA, 0x07F9, 0x07F8, 0x07F8, 0x07F7, 0x07F7, 0x07F6, 0x07F6, 0x07F5, 0x07F4, 0x07F4, 0x07F3, 0x07F3, 0x07F3, 0x07F2, 0x07F2, 0x07F2, 0x07F2, 0x07F2, 0x07F2, 0x07F2, 0x07F1, 0x07F1, 0x07F1, 0x07F1, 0x07F0, 0x07F1, 0x07D0, 0x0791, 0x0751, 0x0712, 0x0693, 0x0634, 0x0517, 0x02DD, 0x01BF, 0x019F, 0x017F, 0x015F, 0x015F, 0x013F, 0x011F, 0x00FF, 0x00DF, 0x00BF, 0x00BF, 0x007F, 0x005F, 0x005F, 0x003F, 0x003F, 0x001F, 0x60B8, 0xB8F3, 0x09BF, 0x041F, 0x061F, 0x073F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xB1B3, 0xC0D1, 0xC0D1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0x48F1, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AE, 0x18AE, 0x00F7, 0x011A, 0x00F9, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F8, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F7, 0x011A, 0x0118, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x00F9, 0x0119, 0x10D0, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AF, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x20AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18CD, 0x18AE, 0x00F7, 0x011A, 0x011A, 0x011A, 0x0119, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28CE, 0x28CF, 0x28EF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x5172, 0x61B2, 0x8A54, 0x9A94, 0xB335, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0x9C97, 0x36DD, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xAC17, 0xD335, 0xD314, 0xD335, 0xD314, 0xD315, 0xD315, 0xD2F4, 0x467C, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x6D59, 0xD274, 0xCA94, 0xD274, 0xCA74, 0xB334, 0x07FE, 0x07FD, 0x07FD, 0x07FD, 0x07FC, 0x07FC, 0x07FB, 0x07FA, 0x07FA, 0x07FA, 0x07F9, 0x07F8, 0x07F8, 0x07F8, 0x07F7, 0x07F6, 0x07F6, 0x07F6, 0x07F5, 0x07F5, 0x07F5, 0x07F5, 0x07F5, 0x07F5, 0x07F5, 0x07F5, 0x07F5, 0x07F5, 0x07F5, 0x07F4, 0x07F4, 0x07F4, 0x07D3, 0x07B3, 0x0793, 0x0753, 0x0714, 0x06B5, 0x5516, 0x0538, 0x037C, 0x01FF, 0x017F, 0x015F, 0x013F, 0x011F, 0x011F, 0x00FF, 0x00DF, 0x00BF, 0x009F, 0x009F, 0x007F, 0x005F, 0x005F, 0x003F, 0x001F, 0x6099, 0xC911, 0x491A, 0x02DF, 0x051F, 0x06BF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x6459, 0xC8B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x90D1, 0x30F1, 0x30F0, 0x30EF, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x00F7, 0x00F7, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x0118, 0x0119, 0x00F7, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x18D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AE, 0x10CF, 0x00F9, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CE, 0x00F7, 0x011A, 0x00F8, 0x10D0, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x08F5, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x20AD, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x3111, 0x3911, 0x3911, 0x4132, 0x4132, 0x5152, 0x69D3, 0x9274, 0xB2F5, 0xD395, 0xD395, 0xD375, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xA478, 0x36DD, 0x07FF, 0x07FF, 0x563C, 0xD335, 0xD334, 0xD315, 0xD315, 0xD2F4, 0xCB15, 0xBB96, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x8498, 0xCA94, 0xCA94, 0xD274, 0xCA74, 0xCA74, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FD, 0x07FD, 0x07FC, 0x07FC, 0x07FC, 0x07FB, 0x07FB, 0x07FA, 0x07FA, 0x07F9, 0x07F9, 0x07F8, 0x07F8, 0x07F8, 0x07F8, 0x07F7, 0x07F7, 0x07F7, 0x07F7, 0x07F7, 0x07F7, 0x07F7, 0x07F7, 0x07F7, 0x07F7, 0x07F7, 0x07F7, 0x07F6, 0x07F6, 0x07D6, 0x07B6, 0x0796, 0x0756, 0x0716, 0xA456, 0xBBD6, 0x3479, 0x02FD, 0x023F, 0x019F, 0x015F, 0x011F, 0x00FF, 0x00FF, 0x00BF, 0x00BF, 0x009F, 0x009F, 0x007F, 0x005F, 0x003F, 0x003F, 0x003F, 0x78B7, 0xC111, 0xA114, 0x01FF, 0x041F, 0x05FF, 0x075F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x0F9F, 0xC0B1, 0xC0D2, 0xC8B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x48F1, 0x30F0, 0x30EF, 0x28F0, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AE, 0x18B0, 0x00F9, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x10D0, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x18AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x10D0, 0x00F9, 0x0119, 0x00F7, 0x18AE, 0x10D2, 0x08F3, 0x08F3, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18CE, 0x08F7, 0x0119, 0x00F8, 0x10CF, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x00F9, 0x18B0, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AF, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AE, 0x20CD, 0x20CD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CE, 0x28CF, 0x28CF, 0x28CF, 0x28F0, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x4132, 0x4132, 0x4932, 0x4933, 0x4953, 0x5154, 0x5154, 0x71F4, 0x9A75, 0xB2F5, 0xD375, 0xD375, 0xD375, 0xD355, 0xD375, 0xD355, 0xD375, 0xD355, 0xD355, 0xD335, 0xD335, 0x9C78, 0x36DD, 0x07FF, 0x9C57, 0xD335, 0xD315, 0xD334, 0xD314, 0xC355, 0x271D, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x9BF7, 0xCA94, 0xD274, 0xCA73, 0xCA74, 0xD253, 0x2EFD, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07FE, 0x07FD, 0x07FD, 0x07FD, 0x07FC, 0x07FC, 0x07FB, 0x07FB, 0x07FB, 0x07FA, 0x07FA, 0x07FA, 0x07F9, 0x07F9, 0x07F9, 0x07F9, 0x07F9, 0x07F9, 0x07FA, 0x07FA, 0x07FA, 0x07FA, 0x07FA, 0x07FA, 0x07F9, 0x07F9, 0x07F9, 0x07F8, 0x07D8, 0x07B8, 0x0797, 0x0758, 0x0EF8, 0xBBF6, 0xD395, 0x6B99, 0x025F, 0x021F, 0x01BF, 0x013F, 0x011F, 0x00FF, 0x00DF, 0x00BF, 0x009F, 0x009F, 0x007F, 0x005F, 0x005F, 0x003F, 0x001F, 0x98D5, 0xC8F2, 0xC911, 0x195E, 0x033F, 0x053F, 0x06BF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x7B76, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0x88D1, 0x30F1, 0x30F0, 0x28F0, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08F3, 0x08F3, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x10CF, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x10D2, 0x00F6, 0x0119, 0x0119, 0x0119, 0x0119, 0x0118, 0x08D5, 0x10D0, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x0118, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x18AD, 0x18AE, 0x18AE, 0x00F7, 0x011A, 0x00F9, 0x18CF, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x00F8, 0x18D0, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18B0, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x00F9, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x00FA, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x20AE, 0x20AE, 0x18AD, 0x20AE, 0x20AE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CF, 0x28CE, 0x28CF, 0x28CF, 0x28EF, 0x30EF, 0x30F0, 0x30F0, 0x3111, 0x3910, 0x3911, 0x4111, 0x4912, 0x4133, 0x4932, 0x4933, 0x5154, 0x5154, 0x5955, 0x5955, 0x5975, 0x6996, 0x8A16, 0xAAD5, 0xCB55, 0xD375, 0xD355, 0xD354, 0xD355, 0xD335, 0xD335, 0xD335, 0xD335, 0xCB35, 0x84F9, 0x0FBF, 0x5DDB, 0xA457, 0x9C58, 0x84D8, 0x1F5E, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x9BD6, 0xCA74, 0xCA74, 0xCA74, 0xCA74, 0xCA74, 0x369C, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07FE, 0x07FE, 0x07FD, 0x07FD, 0x07FD, 0x07FC, 0x07FC, 0x07FC, 0x07FB, 0x07FB, 0x07FB, 0x07FB, 0x07FB, 0x07FB, 0x07FB, 0x07FB, 0x07FB, 0x07FC, 0x07FC, 0x07FC, 0x07FC, 0x07FB, 0x07FB, 0x07FB, 0x07FB, 0x07DA, 0x07DA, 0x07BA, 0x079A, 0x0779, 0x2E99, 0xC3D6, 0xD395, 0x8339, 0x0A3E, 0x01DF, 0x019F, 0x015F, 0x011F, 0x00FF, 0x00BF, 0x009F, 0x007F, 0x007F, 0x007F, 0x003F, 0x003F, 0x003F, 0x90D5, 0xC912, 0xC0F1, 0x7117, 0x027F, 0x049F, 0x065F, 0x077F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x269D, 0xC891, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xB8B1, 0x3110, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AD, 0x18AD, 0x18AD, 0x18B0, 0x0118, 0x0119, 0x08F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x0117, 0x011A, 0x00F9, 0x10D0, 0x18AD, 0x20AD, 0x20AD, 0x10D1, 0x00F8, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F6, 0x18AF, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x10D0, 0x0118, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x20AE, 0x18CD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x10CF, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0139, 0x00F8, 0x18B0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18D0, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x00F9, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20CD, 0x18CE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28EF, 0x28CF, 0x28EF, 0x28D0, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x3931, 0x4132, 0x4132, 0x4933, 0x5133, 0x5153, 0x5154, 0x5154, 0x5975, 0x6175, 0x6195, 0x9255, 0x8B14, 0x4AD3, 0x7A94, 0xAB14, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD315, 0xD314, 0xD335, 0xC355, 0x467C, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xC2D4, 0xCA74, 0xCA74, 0xD274, 0xCA74, 0xD253, 0x369C, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FD, 0x07FD, 0x07FD, 0x07FD, 0x07FD, 0x07FC, 0x07FC, 0x07FC, 0x07FD, 0x07FD, 0x07FD, 0x07FD, 0x07FD, 0x07FD, 0x07FE, 0x07FE, 0x07FE, 0x07FD, 0x07FD, 0x07FD, 0x07FC, 0x07FC, 0x07DB, 0x07BB, 0x07BB, 0x077B, 0x2EBA, 0xC3D6, 0xD395, 0xB337, 0x09DF, 0x01BF, 0x017F, 0x013F, 0x011F, 0x00DF, 0x009F, 0x009F, 0x007F, 0x005F, 0x005F, 0x003F, 0x003F, 0x7896, 0xC0F1, 0xC8F1, 0xA8F3, 0x01DF, 0x03DF, 0x05BF, 0x071F, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xA214, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0x68F1, 0x30F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x18AD, 0x18AD, 0x10D0, 0x00F9, 0x0139, 0x08F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x18D0, 0x18AD, 0x20AD, 0x18AD, 0x08F4, 0x0119, 0x011A, 0x0119, 0x08F6, 0x10D2, 0x10D0, 0x18CF, 0x18D0, 0x10D3, 0x0118, 0x0119, 0x011A, 0x00F9, 0x18CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x0119, 0x011A, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x00F9, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AF, 0x00F9, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20EF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30EF, 0x30F0, 0x30F0, 0x3911, 0x3911, 0x4111, 0x4132, 0x4932, 0x4933, 0x5133, 0x5153, 0x5154, 0x5954, 0x6195, 0x9A75, 0xCB55, 0xCB75, 0x5BB4, 0x3B34, 0x42B3, 0x4A33, 0x6253, 0x9AB4, 0xD335, 0xD335, 0xD315, 0xD334, 0xD314, 0xD315, 0xD314, 0xD314, 0x5DDB, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x1F5E, 0xD274, 0xD274, 0xD274, 0xD274, 0xD274, 0xCA53, 0x369D, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FE, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07FE, 0x07FE, 0x07FD, 0x07DD, 0x07DD, 0x07BD, 0x079C, 0x561A, 0xD395, 0xD395, 0xAB37, 0x099F, 0x015F, 0x013F, 0x011F, 0x00FF, 0x00BF, 0x009F, 0x007F, 0x007F, 0x005F, 0x003F, 0x003F, 0x305C, 0xC0F1, 0xC8F1, 0xC8D1, 0x215D, 0x033F, 0x051F, 0x06DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x5CD9, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x98D1, 0x38F0, 0x30F0, 0x30F0, 0x28CF, 0x28EF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18CE, 0x0117, 0x011A, 0x0118, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x0117, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x08F3, 0x0118, 0x0119, 0x0119, 0x10D0, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x011A, 0x00F8, 0x10D0, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18CE, 0x00F7, 0x0119, 0x00F8, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F8, 0x011A, 0x00F7, 0x18AE, 0x20AE, 0x18AD, 0x18AD, 0x18CD, 0x18B0, 0x00F9, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x0117, 0x0119, 0x0119, 0x011A, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x3911, 0x3911, 0x4111, 0x4131, 0x4132, 0x4933, 0x4933, 0x5154, 0x5974, 0x9255, 0xCB55, 0xD375, 0xBB95, 0x5474, 0x3C34, 0x3BB4, 0x4333, 0x42B3, 0x4A13, 0x49F3, 0x5A32, 0x9AB4, 0xD334, 0xD335, 0xD314, 0xD314, 0xD315, 0xD314, 0xD2F4, 0x84D8, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x4DDB, 0xD274, 0xCA74, 0xCA73, 0xD274, 0xCA54, 0xCA54, 0x369C, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07FE, 0x07DD, 0x07DE, 0x079D, 0x6D99, 0xD395, 0xD395, 0xAB17, 0x097F, 0x011F, 0x011F, 0x00FF, 0x00BF, 0x00BF, 0x009F, 0x007F, 0x007F, 0x003F, 0x003F, 0x003F, 0xC8F1, 0xC8F1, 0xC8D1, 0x5119, 0x02DF, 0x04FF, 0x06BF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x1F1E, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x4910, 0x30F0, 0x30F0, 0x28EF, 0x28EF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x10D2, 0x08F3, 0x08F3, 0x10D2, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AE, 0x20AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x00F8, 0x18CF, 0x18AD, 0x20AD, 0x18AD, 0x18D0, 0x00F9, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18D0, 0x00F8, 0x0119, 0x00F8, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F8, 0x10D0, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F7, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x00F7, 0x18AE, 0x20AE, 0x18AD, 0x18AD, 0x18AE, 0x10CF, 0x00F9, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AE, 0x10D2, 0x08F3, 0x08F3, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x3910, 0x3911, 0x4112, 0x4132, 0x4132, 0x4933, 0x5133, 0x8214, 0xCB55, 0xD375, 0xD375, 0xB3D5, 0x3D55, 0x3515, 0x3495, 0x3C14, 0x3B94, 0x3B13, 0x4293, 0x4212, 0x49F3, 0x49F3, 0x5A13, 0x9AB4, 0xD314, 0xD315, 0xCB15, 0xD2F4, 0xD2F5, 0xD2F4, 0x7539, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x8C37, 0xCA74, 0xD273, 0xD253, 0xCA54, 0xCA53, 0xD253, 0x1F5E, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07DF, 0x07DF, 0x94D8, 0xD396, 0xD395, 0x8299, 0x00FF, 0x00FF, 0x00FF, 0x00BF, 0x00BF, 0x009F, 0x007F, 0x005F, 0x005F, 0x003F, 0x001F, 0xC8D1, 0xC0F1, 0xC0D1, 0xA0D4, 0x027F, 0x04BF, 0x069F, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x8315, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x70F1, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x0117, 0x18CD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x10D2, 0x10D3, 0x08F3, 0x10D1, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AE, 0x0117, 0x0119, 0x0119, 0x10CF, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x08F6, 0x0119, 0x0118, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F7, 0x011A, 0x0118, 0x10D0, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AE, 0x00F7, 0x011A, 0x0119, 0x0119, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x011A, 0x0119, 0x0117, 0x18AE, 0x20CD, 0x18AD, 0x18AE, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CE, 0x28CF, 0x28CF, 0x28CF, 0x28F0, 0x30F0, 0x30F0, 0x30F0, 0x3911, 0x3911, 0x4132, 0x4132, 0x4132, 0x5973, 0xB2F4, 0xD375, 0xD375, 0xD375, 0x9435, 0x3D55, 0x2D55, 0x2D75, 0x3515, 0x3C94, 0x3414, 0x3B94, 0x4313, 0x4293, 0x4A13, 0x41F3, 0x49F2, 0x4A13, 0x5A33, 0xA2B4, 0xD314, 0xD2F4, 0xD2F4, 0xD2D4, 0xD2F4, 0x4E1B, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x179F, 0xD274, 0xCA53, 0xCA73, 0xCA53, 0xCA53, 0xCA53, 0xD253, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x0F9E, 0xBC16, 0xD395, 0xD395, 0x725A, 0x00BF, 0x00BF, 0x00BF, 0x009F, 0x007F, 0x007F, 0x005F, 0x005F, 0x003F, 0x001F, 0x90B5, 0xC8D1, 0xC8D1, 0xC0D1, 0x123E, 0x047F, 0x067F, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x54D9, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0x90D1, 0x38F1, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AF, 0x0119, 0x0119, 0x0117, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x011A, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x00F7, 0x0119, 0x0118, 0x18D0, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18D0, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AF, 0x08F6, 0x011A, 0x0119, 0x0118, 0x08F4, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0118, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18CE, 0x00F7, 0x011A, 0x0119, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CE, 0x00F7, 0x011A, 0x00F8, 0x10D0, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x20AE, 0x18AD, 0x18AE, 0x18AD, 0x18D0, 0x00F9, 0x00F9, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28F0, 0x30F0, 0x38F0, 0x30F0, 0x3911, 0x3911, 0x4112, 0x4132, 0x8234, 0xCB55, 0xD375, 0xD375, 0xD355, 0x9435, 0x3575, 0x3575, 0x2D75, 0x3555, 0x3555, 0x3514, 0x3474, 0x3BF4, 0x3B73, 0x42F4, 0x4273, 0x4A13, 0x4213, 0x49F2, 0x49F3, 0x49F3, 0x6A33, 0xBAD4, 0xD2F5, 0xD2F4, 0xD2D4, 0xC335, 0x177E, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x5D9A, 0xCA54, 0xD273, 0xCA54, 0xCA53, 0xCA53, 0xCA53, 0x9BB6, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07BF, 0x07BF, 0x07BF, 0x079F, 0x077F, 0x077F, 0x077E, 0x07BF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07BF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x36DD, 0xD395, 0xD395, 0xD395, 0x51BC, 0x009F, 0x009F, 0x007F, 0x007F, 0x007F, 0x005F, 0x005F, 0x003F, 0x001F, 0x7077, 0xC0D2, 0xC8D1, 0xC0D1, 0x49FA, 0x049F, 0x069F, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x1F1E, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0x3910, 0x30F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x20AD, 0x10D0, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x08F5, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x0119, 0x00F8, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D3, 0x011A, 0x0118, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F8, 0x0119, 0x0119, 0x011A, 0x011A, 0x011A, 0x08F5, 0x20AD, 0x18CD, 0x18AD, 0x18AF, 0x0119, 0x0119, 0x18D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08F3, 0x10F3, 0x10D2, 0x20AD, 0x188D, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18CE, 0x08F7, 0x0119, 0x00F8, 0x18B0, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x0119, 0x0119, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x4952, 0xAAB4, 0xD375, 0xD375, 0xD375, 0xD355, 0x9435, 0x3575, 0x3575, 0x2D75, 0x2D75, 0x2D75, 0x3555, 0x54D5, 0x6475, 0x83B5, 0x8B74, 0x9B34, 0xAB14, 0xAAD4, 0xB2D4, 0xAAD4, 0xAAB4, 0xAAB4, 0xB2B4, 0x6B15, 0x8A94, 0xC2D4, 0xD2F4, 0xD2D4, 0x84B8, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xB315, 0xD274, 0xCA53, 0xCA54, 0xCA53, 0xCA53, 0xD253, 0x653A, 0x07FF, 0x07FF, 0x07DF, 0x07DF, 0x07FF, 0x07DF, 0x07DF, 0x07BF, 0x07BF, 0x079F, 0x079F, 0x077F, 0x075F, 0x075F, 0x073F, 0x073F, 0x071F, 0x071E, 0x071E, 0x073E, 0x079F, 0x07DF, 0x07FF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x07BF, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x7D7A, 0xD395, 0xD395, 0xC375, 0x28FE, 0x007F, 0x007F, 0x005F, 0x005F, 0x003F, 0x005F, 0x003F, 0x003F, 0x183E, 0xC0D1, 0xC0D1, 0xC0D2, 0x7996, 0x04BF, 0x067F, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xA214, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0x58F1, 0x30F0, 0x30F0, 0x30F0, 0x28CF, 0x28EF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x00F9, 0x0119, 0x00F7, 0x18CE, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AF, 0x0119, 0x0119, 0x08F6, 0x20AE, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x0118, 0x18B0, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x08F7, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x08F4, 0x0139, 0x0119, 0x10F3, 0x18D0, 0x08F5, 0x0119, 0x0119, 0x18D0, 0x18AE, 0x18AE, 0x18CD, 0x0119, 0x011A, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x18AD, 0x18AE, 0x18AE, 0x00F7, 0x011A, 0x00F8, 0x18D0, 0x18AD, 0x18AD, 0x20CD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x20AD, 0x18CD, 0x20AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18D0, 0x00F9, 0x0119, 0x0117, 0x18CE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x5972, 0xCB55, 0xD375, 0xD375, 0xD375, 0xD375, 0xABD5, 0x4515, 0x54F5, 0x7C75, 0x8C35, 0xABD5, 0xCB55, 0xD335, 0xD335, 0xD334, 0xD335, 0xD335, 0xD315, 0xD314, 0xD314, 0xC355, 0x9C37, 0x659A, 0x467C, 0x0FBF, 0x07FF, 0x07FF, 0x269D, 0x9C17, 0xD2D4, 0x9C17, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x5D9A, 0xD274, 0xCA53, 0xCA54, 0xCA53, 0xCA33, 0xCA33, 0xCA33, 0x26DD, 0x07FF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07BF, 0x079F, 0x079F, 0x077F, 0x077F, 0x075F, 0x073F, 0x071E, 0x071E, 0x06FE, 0x06FE, 0x06FF, 0x06DE, 0x06DE, 0x06BE, 0x06BE, 0x06DE, 0x073E, 0x079F, 0x07BF, 0x07BF, 0x079F, 0x079F, 0x079F, 0x077F, 0x079F, 0x079F, 0x077F, 0x079F, 0x079F, 0x079F, 0x079F, 0x07BF, 0x07BF, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x0FBF, 0xC3F6, 0xD395, 0xD395, 0xAAF7, 0x003F, 0x003F, 0x003F, 0x003F, 0x003F, 0x003F, 0x003F, 0x001F, 0x001F, 0xA094, 0xC0D1, 0xC8B1, 0xA8F3, 0x04BF, 0x069F, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x73D8, 0xB8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0x78F1, 0x3911, 0x30F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18CF, 0x18AE, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x00F6, 0x0119, 0x08F3, 0x18AD, 0x20AD, 0x20AD, 0x00F6, 0x00F9, 0x08D4, 0x18AD, 0x18AD, 0x18AD, 0x00F8, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x18AD, 0x00F6, 0x0119, 0x10D3, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18CD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0118, 0x18D0, 0x18AD, 0x18AD, 0x18AD, 0x188D, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18CD, 0x10CF, 0x0119, 0x00F9, 0x0117, 0x18CE, 0x188D, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x3111, 0x71F2, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD375, 0xD355, 0xD355, 0xD335, 0xD335, 0xD355, 0xD335, 0xD335, 0xCB14, 0xD334, 0xD334, 0xAC16, 0x753A, 0x467D, 0x1F5E, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x369C, 0x4E1B, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x26FD, 0xC2B4, 0xCA53, 0xCA53, 0xCA53, 0xD253, 0xCA33, 0xCA33, 0xA356, 0x07FF, 0x07FF, 0x07DF, 0x07BF, 0x07BF, 0x079F, 0x077F, 0x077F, 0x075F, 0x073F, 0x071F, 0x071F, 0x06FF, 0x06FE, 0x06FE, 0x06DE, 0x06BE, 0x06BE, 0x069E, 0x069E, 0x069E, 0x067E, 0x067E, 0x065E, 0x065E, 0x06BE, 0x073E, 0x075F, 0x075F, 0x075F, 0x075F, 0x075F, 0x075F, 0x075F, 0x075F, 0x077F, 0x077F, 0x077F, 0x077F, 0x079F, 0x07BF, 0x07BF, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0x07DF, 0x6DDA, 0xD395, 0xD376, 0xD375, 0x79FA, 0x003F, 0x003F, 0x001F, 0x003F, 0x001F, 0x001F, 0x001F, 0x001F, 0x8896, 0xC0B1, 0xC0B1, 0xC8B1, 0x0C9F, 0x069F, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x3DBB, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xB8D1, 0xC0B1, 0xC0B1, 0x98D1, 0x3911, 0x30F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20AD, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x011A, 0x00F7, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x10CF, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x08F6, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x18AD, 0x00F6, 0x011A, 0x08F4, 0x18AD, 0x18AD, 0x18AD, 0x0118, 0x011A, 0x08F3, 0x20AD, 0x18AD, 0x18AD, 0x08F7, 0x0119, 0x08F3, 0x18CD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x011A, 0x0119, 0x18B0, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x00F9, 0x0119, 0x00F7, 0x18CE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x9A93, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD355, 0xD355, 0xD335, 0xD335, 0xC375, 0x84F9, 0x4E3C, 0x0FBF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x0F9F, 0xAB75, 0xCA54, 0xD253, 0xCA53, 0xCA33, 0xCA33, 0xD233, 0xCA33, 0x4DBB, 0x07DF, 0x07BF, 0x07BF, 0x079F, 0x077F, 0x075F, 0x075F, 0x073F, 0x071F, 0x071F, 0x06FF, 0x06DE, 0x06DE, 0x06DE, 0x06BE, 0x06BE, 0x069E, 0x067E, 0x067E, 0x067E, 0x065E, 0x063E, 0x063E, 0x061E, 0x061E, 0x05FE, 0x05FD, 0x067D, 0x06DE, 0x06FE, 0x06FE, 0x06FE, 0x06FE, 0x071E, 0x073F, 0x073F, 0x073F, 0x073E, 0x075F, 0x077F, 0x079F, 0x079F, 0x07BF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x0FBF, 0xC3D6, 0xD375, 0xD375, 0xD355, 0x30FD, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x001F, 0x001F, 0x6058, 0xC0B1, 0xC0B1, 0xC0B1, 0x33FC, 0x06BF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x0F9E, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xB8B1, 0xC0B1, 0xB8D1, 0xB8D1, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AD, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x08F5, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x00F9, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18CD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x08F6, 0x0119, 0x08D5, 0x18CD, 0x18AE, 0x18AD, 0x08D4, 0x0119, 0x0119, 0x10D3, 0x10D0, 0x08F4, 0x0119, 0x0119, 0x18B0, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0118, 0x18D0, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18B0, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x30F0, 0x3910, 0xAAF4, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xB3D6, 0x7539, 0x271D, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x2EFD, 0xB315, 0xCA53, 0xCA54, 0xCA33, 0xCA53, 0xCA34, 0xCA34, 0xCA33, 0xA335, 0x07BF, 0x07BF, 0x079F, 0x077F, 0x075F, 0x073F, 0x073F, 0x071F, 0x06FF, 0x06FF, 0x06DF, 0x06DE, 0x06BF, 0x06BE, 0x069E, 0x069E, 0x069E, 0x067E, 0x065E, 0x065E, 0x063E, 0x061E, 0x061E, 0x05FE, 0x05DE, 0x05BD, 0x05BE, 0x059D, 0x055E, 0x055E, 0x05BE, 0x05FE, 0x061D, 0x067E, 0x06BE, 0x06FE, 0x06FE, 0x071F, 0x071E, 0x073F, 0x073F, 0x075F, 0x077F, 0x079F, 0x07BF, 0x07BF, 0x07DF, 0x07FF, 0x07FF, 0x8539, 0xD375, 0xD355, 0xD355, 0xBAF6, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x403B, 0xC8B1, 0xC0B1, 0xC0B1, 0x6318, 0x06BF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xA9B3, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xB8D1, 0x4910, 0x3910, 0x30F0, 0x30F0, 0x28CF, 0x28EF, 0x28CF, 0x20CF, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x20AE, 0x18AD, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x10D3, 0x10D3, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x011A, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x08F3, 0x011A, 0x0118, 0x18AD, 0x18CD, 0x18AD, 0x18CE, 0x00F8, 0x011A, 0x0119, 0x011A, 0x0119, 0x011A, 0x08F5, 0x18AD, 0x20CD, 0x18AD, 0x10D0, 0x011A, 0x0119, 0x10D0, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x0117, 0x011A, 0x0119, 0x18AF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AE, 0x18CF, 0x00F8, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x20CF, 0x28CF, 0x28CF, 0x28EF, 0x30CF, 0x3910, 0xB314, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD354, 0xD355, 0xD355, 0xCB96, 0x8518, 0x36DD, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x0FBE, 0x653A, 0xCA54, 0xCA53, 0xD253, 0xCA53, 0xCA53, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0x2E9D, 0x077F, 0x077F, 0x075F, 0x073F, 0x073F, 0x071F, 0x06FF, 0x06FE, 0x06DF, 0x06DE, 0x06BF, 0x06BE, 0x06BF, 0x069E, 0x067E, 0x067E, 0x065E, 0x065E, 0x063E, 0x061E, 0x061E, 0x05FE, 0x05DE, 0x05BE, 0x05BE, 0x059E, 0x057E, 0x053E, 0x051E, 0x04FE, 0x04BE, 0x049E, 0x041E, 0x03DD, 0x04DE, 0x065E, 0x06BE, 0x06DE, 0x06DE, 0x06FE, 0x071F, 0x073E, 0x077F, 0x079F, 0x079F, 0x07BF, 0x07DF, 0x07DF, 0x07FF, 0x36DD, 0xD355, 0xD355, 0xD355, 0xD335, 0x699A, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0xB8B2, 0xC091, 0xC0B1, 0x7A96, 0x06BF, 0x079F, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x82F5, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB8D1, 0x60F1, 0x3911, 0x30F0, 0x30F0, 0x28EF, 0x28EF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x00F7, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x20CD, 0x10D2, 0x08D4, 0x08F3, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x011A, 0x0119, 0x10D2, 0x18AD, 0x20AD, 0x18AD, 0x18AF, 0x08F6, 0x0119, 0x0119, 0x00F9, 0x08F4, 0x18AD, 0x20AE, 0x18AD, 0x18AE, 0x08F5, 0x011A, 0x00F8, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F7, 0x0119, 0x08F7, 0x18CE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x10D0, 0x0118, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x20AD, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CE, 0x20CF, 0x28CF, 0x28EF, 0x3910, 0xB314, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD355, 0xBBD6, 0x5DFB, 0x0FBF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x0FBF, 0x5D9A, 0xB315, 0xD254, 0xCA53, 0xD254, 0xCA53, 0xCA53, 0xCA33, 0xD233, 0xCA33, 0xCA33, 0x64D9, 0x077F, 0x073F, 0x073F, 0x071F, 0x06FF, 0x06FF, 0x06DF, 0x06DF, 0x06DF, 0x06BF, 0x06BE, 0x069F, 0x069F, 0x067E, 0x065E, 0x065E, 0x063E, 0x063E, 0x061E, 0x05FE, 0x05FE, 0x05DE, 0x05BE, 0x059E, 0x059E, 0x055E, 0x055E, 0x051E, 0x04FE, 0x04DE, 0x049E, 0x043D, 0x03DE, 0x03BE, 0x039E, 0x037E, 0x03FE, 0x05FE, 0x069E, 0x069E, 0x06BE, 0x06FE, 0x071E, 0x073F, 0x075F, 0x079F, 0x079F, 0x07DF, 0x07DF, 0x07DF, 0x07FF, 0xBBF6, 0xD355, 0xD335, 0xD335, 0xC2F5, 0x083F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x9095, 0xC8B1, 0xC8B1, 0x91F5, 0x067F, 0x06FF, 0x073F, 0x075F, 0x077F, 0x07BF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x54D9, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xB8D1, 0xC0D1, 0xB8D1, 0xB8D1, 0x80F2, 0x3911, 0x30F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x20CD, 0x20AE, 0x18AD, 0x18AE, 0x20AE, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AE, 0x18AE, 0x0117, 0x0119, 0x0117, 0x18AE, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AE, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x00F6, 0x011A, 0x0117, 0x18CE, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x20AD, 0x18AD, 0x18AD, 0x18CD, 0x18D0, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CE, 0x08F7, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F6, 0x18CE, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CE, 0x28CF, 0x28CF, 0x3110, 0xB314, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0x9C77, 0x563B, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x1F7E, 0x65DB, 0x7CF9, 0x9C57, 0x9C57, 0x9C57, 0x9C57, 0x9C37, 0x9C37, 0x9C37, 0x9C37, 0x7539, 0x6D7A, 0x6579, 0x5DBB, 0x36BD, 0x36BD, 0x36BC, 0x2EFD, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x0FBF, 0x36BD, 0x5D9A, 0x8C37, 0xD274, 0xD273, 0xD254, 0xCA53, 0xD254, 0xD253, 0xCA33, 0xD233, 0xCA34, 0xCA13, 0xCA33, 0x8418, 0x075F, 0x073F, 0x071F, 0x06FF, 0x06FF, 0x06DF, 0x06DF, 0x06DF, 0x06BF, 0x06BF, 0x069E, 0x069F, 0x067E, 0x067E, 0x065E, 0x065E, 0x063E, 0x061E, 0x061E, 0x05FE, 0x05DE, 0x05DE, 0x05BE, 0x05BE, 0x057E, 0x055E, 0x051E, 0x051E, 0x04FE, 0x04BE, 0x045E, 0x03FE, 0x03BE, 0x039E, 0x037E, 0x037E, 0x035E, 0x033E, 0x035E, 0x061D, 0x067E, 0x067E, 0x069E, 0x06BE, 0x06FE, 0x073F, 0x075F, 0x077F, 0x079F, 0x07DF, 0x07DF, 0x07FF, 0x7D59, 0xD335, 0xD335, 0xD335, 0xD314, 0x699A, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x007F, 0x60D8, 0xC0B1, 0xC0B1, 0xB8F2, 0x05DF, 0x061F, 0x065F, 0x06DF, 0x073F, 0x077F, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x363C, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xB8D1, 0xC0D1, 0xB8D1, 0xB8D1, 0x90D1, 0x3911, 0x30F0, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x18AE, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x00F8, 0x0119, 0x0117, 0x18AE, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x20AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x10D0, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18D0, 0x00F8, 0x011A, 0x00F8, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x00F9, 0x0119, 0x0119, 0x011A, 0x08D5, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x20AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x28CE, 0x28CE, 0x30EF, 0xB314, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD375, 0xD355, 0x9C77, 0x3EDD, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x659A, 0xD315, 0xD314, 0xD315, 0xD314, 0xD314, 0xD314, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2D4, 0xD2D4, 0xD2F4, 0xCAD4, 0xD2D4, 0xD2B4, 0xD2B4, 0xD2B4, 0xCAB4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD294, 0xD294, 0xCA94, 0xCA94, 0xCA94, 0xCA94, 0xCA74, 0xCA74, 0xCA73, 0xCA73, 0xD274, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA33, 0xCA33, 0xCA33, 0xAB15, 0x0EDF, 0x06FF, 0x06FF, 0x06DF, 0x06DF, 0x06BF, 0x06BF, 0x06DF, 0x06BF, 0x069F, 0x069F, 0x067E, 0x067F, 0x067E, 0x065E, 0x063F, 0x061E, 0x061E, 0x05FE, 0x05FE, 0x05DE, 0x05BE, 0x059E, 0x059E, 0x055E, 0x053E, 0x051E, 0x04FE, 0x04DE, 0x049E, 0x043E, 0x03BE, 0x039E, 0x039E, 0x035E, 0x035E, 0x033E, 0x033E, 0x031E, 0x02FE, 0x037E, 0x05FE, 0x065E, 0x067E, 0x069E, 0x06DE, 0x06FE, 0x075F, 0x077F, 0x079F, 0x07BF, 0x07DF, 0x07FF, 0x271D, 0xD335, 0xD314, 0xD315, 0xD315, 0xC2D5, 0x083F, 0x001F, 0x001F, 0x001F, 0x001F, 0x009F, 0x60D8, 0xC0B1, 0xC0B2, 0xC0B1, 0x04BF, 0x053F, 0x05BF, 0x067F, 0x06DF, 0x075F, 0x079F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xC0B1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xC0B1, 0xB8D1, 0x98D1, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18CE, 0x20AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x08F3, 0x0119, 0x011A, 0x08F7, 0x10D0, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x10D2, 0x0118, 0x0119, 0x0119, 0x10D0, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AE, 0x18AD, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CE, 0x20CE, 0x30EF, 0xB314, 0xD375, 0xD375, 0xD375, 0xD375, 0xD355, 0xD375, 0xAC37, 0x36DD, 0x07FF, 0x07FF, 0x07FF, 0x0EBD, 0x1D7B, 0x1C99, 0x32F5, 0x3A75, 0x6193, 0x69B3, 0x79F4, 0x8A14, 0xB294, 0xCAF4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2B4, 0xD2B4, 0xCAD4, 0xD2B4, 0xCAB4, 0xD2B4, 0xD2B4, 0xD294, 0xD294, 0xD294, 0xD294, 0xCA94, 0xCA94, 0xCA74, 0xCA74, 0xD274, 0xD274, 0xCA53, 0xCA54, 0xCA54, 0xCA53, 0xD253, 0xCA53, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0x8B97, 0x35FD, 0x5D7B, 0x6D3A, 0x6D3A, 0x5D5B, 0x35FD, 0x06BF, 0x0E7E, 0x457C, 0x6C99, 0x6479, 0x6459, 0x4CBA, 0x0E1E, 0x063E, 0x063E, 0x061E, 0x05FE, 0x05FE, 0x05FE, 0x05DE, 0x05BE, 0x059E, 0x057E, 0x055E, 0x051E, 0x051E, 0x04FE, 0x04DE, 0x047E, 0x03DE, 0x03BE, 0x037E, 0x037F, 0x035E, 0x033E, 0x033E, 0x031E, 0x02FE, 0x02FE, 0x02FE, 0x02DE, 0x03FE, 0x05BE, 0x063E, 0x065E, 0x069E, 0x06DE, 0x071F, 0x073E, 0x077F, 0x079F, 0x07BF, 0x07DF, 0x07FF, 0xBBB6, 0xD314, 0xD315, 0xD2F4, 0xD2F4, 0x697A, 0x001F, 0x001F, 0x001F, 0x003F, 0x007F, 0x48FA, 0xC0B1, 0xC0B1, 0xC0B1, 0x331C, 0x047F, 0x053F, 0x05FF, 0x069F, 0x073F, 0x079F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x9A14, 0xB8D1, 0xB8D1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x20CF, 0x20AE, 0x18CF, 0x08F6, 0x011A, 0x0119, 0x0119, 0x08F4, 0x18CE, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x08D4, 0x0119, 0x0119, 0x0119, 0x08F6, 0x10D2, 0x10D0, 0x18D0, 0x18D1, 0x10D2, 0x00F8, 0x0119, 0x011A, 0x0119, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x20AD, 0x20AE, 0x18AD, 0x20AE, 0x20AE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x9273, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xC3B6, 0x5DFB, 0x07FF, 0x0E3B, 0x1C98, 0x2AD5, 0x3911, 0x3911, 0x3912, 0x4111, 0x4112, 0x4112, 0x4112, 0x4132, 0x4132, 0x4132, 0x4132, 0x4933, 0x5173, 0x79D3, 0x9A54, 0xC294, 0xD2F4, 0xD2D5, 0xCAD4, 0xD2D4, 0xD2B4, 0xCAD4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD294, 0xD294, 0xD294, 0xD294, 0xCA94, 0xCA94, 0xCA74, 0xCA74, 0xCA74, 0xCA73, 0xD253, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0x99D4, 0x6358, 0xD395, 0xD396, 0xD395, 0xD395, 0xD375, 0xD375, 0x06BF, 0x5CFA, 0xD2B4, 0xCA94, 0xCA33, 0xCA13, 0xC9D3, 0xB9D3, 0x4C5A, 0x061E, 0x061E, 0x05DE, 0x05DE, 0x05BE, 0x059E, 0x059E, 0x057E, 0x053E, 0x051E, 0x051D, 0x04DE, 0x04BE, 0x043E, 0x03BE, 0x03BE, 0x037F, 0x0B7E, 0x337C, 0x333C, 0x335C, 0x333C, 0x333C, 0x331C, 0x331C, 0x32FC, 0x32FC, 0x32DC, 0x2B7C, 0x05DE, 0x061E, 0x065E, 0x069E, 0x06DE, 0x071F, 0x073F, 0x077F, 0x07BF, 0x07DF, 0x07DF, 0x84F9, 0xD314, 0xCB14, 0xCAF4, 0xD2D5, 0xB275, 0x001F, 0x001F, 0x001F, 0x001F, 0x005F, 0x08DF, 0xB8D2, 0xC0B1, 0xC0B1, 0x3A7B, 0x03FF, 0x04DF, 0x05BF, 0x067F, 0x071F, 0x079F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x7B77, 0xB8D1, 0xB8B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x4111, 0x38F1, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CF, 0x20CF, 0x20AE, 0x20CF, 0x0918, 0x013A, 0x011A, 0x0119, 0x011A, 0x0119, 0x08F6, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x18AE, 0x00F8, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D1, 0x0118, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x011A, 0x08F6, 0x18CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x10D2, 0x0119, 0x011A, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x0139, 0x00F9, 0x10D2, 0x20AE, 0x18AD, 0x20AE, 0x20AE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x7A32, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0x9C78, 0x261B, 0x1B96, 0x3171, 0x30F0, 0x38F1, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x4111, 0x3912, 0x4112, 0x4112, 0x4112, 0x4132, 0x4112, 0x4132, 0x4132, 0x4912, 0x4132, 0x6172, 0x81F3, 0xAA73, 0xCAD4, 0xD2B4, 0xCAB4, 0xD2B4, 0xD2B4, 0xCAB4, 0xCAB4, 0xCA94, 0xCA94, 0xD294, 0xCA94, 0xCA94, 0xCA74, 0xCA74, 0xCA74, 0xD274, 0xCA54, 0xD274, 0xCA53, 0xCA53, 0xCA53, 0xD233, 0xCA33, 0xCA33, 0xD233, 0xC234, 0x7994, 0x5975, 0xB315, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xC375, 0x067F, 0x067F, 0x6C79, 0xCA33, 0xCA13, 0xC9D3, 0xC992, 0xC952, 0xC912, 0x34BB, 0x05FE, 0x05DE, 0x05BE, 0x059E, 0x055E, 0x055E, 0x053E, 0x051E, 0x04FE, 0x249D, 0x347B, 0x6BFA, 0x7B99, 0x9B98, 0xAB97, 0xDB95, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD396, 0xD395, 0xBBD6, 0x9C37, 0x8499, 0x6D1A, 0x363C, 0x1EDD, 0x079F, 0x07BF, 0x07DF, 0x4E1B, 0xD2F4, 0xD2F5, 0xD2D4, 0xD2D4, 0xD2D4, 0x40FC, 0x001F, 0x001F, 0x001F, 0x003F, 0x009F, 0x78D7, 0xC0B1, 0xC0B1, 0x61D8, 0x03BF, 0x049F, 0x057F, 0x065F, 0x071F, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x54D9, 0xB8D1, 0xB8B1, 0xB8D1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x4111, 0x3911, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CF, 0x20AE, 0x10F3, 0x013A, 0x0119, 0x0139, 0x0119, 0x0119, 0x0119, 0x011A, 0x18D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x18AE, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F7, 0x18CE, 0x10D2, 0x08F3, 0x08F4, 0x10D1, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x10F2, 0x00F7, 0x00F9, 0x0119, 0x0119, 0x011A, 0x0119, 0x08F5, 0x10D0, 0x18AE, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x10D2, 0x011A, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x18AD, 0x20AE, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x5170, 0xD395, 0xD375, 0xD375, 0xD375, 0xD355, 0x6519, 0x22B3, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x4112, 0x4112, 0x4112, 0x4112, 0x4132, 0x4112, 0x4132, 0x4112, 0x4952, 0x79B3, 0xA233, 0xD2B4, 0xCAB4, 0xD294, 0xCA94, 0xD294, 0xCA94, 0xCA74, 0xCA94, 0xCA74, 0xCA74, 0xD274, 0xCA54, 0xD274, 0xD253, 0xCA54, 0xCA54, 0xCA33, 0xD233, 0xCA34, 0xCA33, 0xCA33, 0xA1D3, 0x5954, 0x5954, 0x79F5, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD335, 0x8C18, 0x067F, 0x065F, 0x063F, 0xA2D5, 0xC9D3, 0xC972, 0xC952, 0xC111, 0xC8D1, 0x8A55, 0x05DE, 0x05BE, 0x059E, 0x057E, 0x055E, 0x34DC, 0x6C5A, 0xA3F7, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD355, 0xD355, 0xD335, 0xD335, 0xD335, 0xBBB6, 0x84D9, 0x4E1B, 0x465C, 0xD2F5, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2B4, 0x81D8, 0x001F, 0x001F, 0x001F, 0x001F, 0x005F, 0x6098, 0xC0B1, 0xC0D1, 0x59B8, 0x035F, 0x045F, 0x055F, 0x063F, 0x06FF, 0x079F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x363C, 0xC0D1, 0xB8D1, 0xB8B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x58F1, 0x3911, 0x30F0, 0x3110, 0x30CF, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x08F6, 0x013A, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x011A, 0x00F7, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x00F9, 0x08F8, 0x0118, 0x18AD, 0x18AD, 0x18AD, 0x00F8, 0x00F8, 0x08F8, 0x0118, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00FA, 0x00F8, 0x08F7, 0x08F7, 0x18B0, 0x18AD, 0x18AE, 0x08F4, 0x0119, 0x08F8, 0x08F8, 0x00F8, 0x18CF, 0x18AD, 0x18AD, 0x10D4, 0x10D0, 0x18AD, 0x20AD, 0x08F8, 0x10D3, 0x18AD, 0x18AD, 0x10F4, 0x10D1, 0x18AD, 0x18AD, 0x08F8, 0x00F7, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x00F9, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x011A, 0x011A, 0x0119, 0x0119, 0x011A, 0x00F8, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AE, 0x20CE, 0x20AE, 0x28EE, 0xCB55, 0xD375, 0xD375, 0xD375, 0xBB14, 0x34F9, 0x2930, 0x30EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x4112, 0x4111, 0x3931, 0x4112, 0x4111, 0x6993, 0x91F2, 0xC254, 0xCA93, 0xCA94, 0xCA94, 0xCA74, 0xCA74, 0xD274, 0xCA73, 0xD273, 0xCA73, 0xD254, 0xCA53, 0xCA53, 0xCA54, 0xCA33, 0xCA34, 0xA1F3, 0x6973, 0x4953, 0x5134, 0x5154, 0xAAF5, 0xD395, 0xD395, 0xD395, 0xD375, 0xD335, 0xD314, 0x5CDA, 0x065F, 0x063F, 0x063F, 0xB254, 0xC972, 0xC952, 0xC112, 0xC8D1, 0xC0B1, 0xC0B1, 0x05BE, 0x059E, 0x2D1C, 0x9438, 0xCBB6, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD375, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD314, 0xD314, 0xD315, 0xD2F4, 0xD2F5, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2B4, 0xD2B4, 0xCA94, 0x087F, 0x003F, 0x001F, 0x001F, 0x001F, 0x385B, 0xC0B1, 0xC0B1, 0x9135, 0x031F, 0x043F, 0x053F, 0x063F, 0x071F, 0x079F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8B1, 0xB8D1, 0xC0D1, 0xB8B1, 0xB8D1, 0x5911, 0x3911, 0x38F0, 0x30F0, 0x30CF, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x0917, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x011A, 0x08F7, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18CE, 0x0118, 0x0119, 0x011A, 0x00F7, 0x08F7, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x20AD, 0x10D1, 0x10D0, 0x18AD, 0x08D5, 0x10D1, 0x18AD, 0x20AE, 0x00F7, 0x18AD, 0x18AE, 0x18AD, 0x08F7, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00F8, 0x18AE, 0x18AD, 0x18AE, 0x0118, 0x18AE, 0x18AD, 0x08F4, 0x18D0, 0x18AD, 0x18AD, 0x10D1, 0x10D5, 0x18AE, 0x18AD, 0x08F5, 0x10D1, 0x20AD, 0x18AD, 0x00F8, 0x08F7, 0x18AF, 0x18AD, 0x08D4, 0x10D1, 0x18AD, 0x18AE, 0x18AD, 0x20AE, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0118, 0x011A, 0x00F9, 0x0119, 0x00F9, 0x10D2, 0x20AD, 0x18CD, 0x20AE, 0x18AD, 0x20AE, 0x20CE, 0x20CE, 0x8252, 0xD375, 0xD375, 0xD375, 0x9A93, 0x30EF, 0x20CF, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x28F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x38F0, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x38F1, 0x3911, 0x3911, 0x3911, 0x3911, 0x4111, 0x6972, 0x81D2, 0xAA13, 0xBA33, 0xCA54, 0xCA74, 0xCA53, 0xCA54, 0xCA53, 0xCA53, 0xB213, 0xA1F3, 0x8193, 0x5152, 0x4932, 0x4933, 0x4933, 0x4933, 0x5174, 0xD395, 0xD395, 0xD396, 0xD375, 0xD334, 0xD2F5, 0xD2B4, 0x2D9D, 0x063F, 0x063F, 0x061F, 0xC993, 0xC952, 0xC911, 0xC8F1, 0xC0B1, 0xC0B1, 0xB8D1, 0x059E, 0x057E, 0xABF7, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD315, 0xD335, 0xCB15, 0xD2F4, 0xD2F5, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2B4, 0xD2B4, 0xD294, 0xD294, 0x411C, 0x003F, 0x003F, 0x001F, 0x001F, 0x203C, 0xC0B1, 0xC0B1, 0x9135, 0x02FF, 0x041F, 0x051F, 0x061F, 0x06FF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xA1B3, 0xB8B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x68F1, 0x3911, 0x38F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x28CF, 0x20CE, 0x10F3, 0x0119, 0x0119, 0x0119, 0x00FA, 0x0119, 0x0119, 0x0119, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x00F9, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x0119, 0x0119, 0x08F3, 0x18AE, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x10F4, 0x08F7, 0x18AD, 0x18AE, 0x18AD, 0x08F8, 0x20AE, 0x18AD, 0x18AD, 0x10D1, 0x10F4, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F7, 0x18AD, 0x18AD, 0x10D1, 0x08F6, 0x18AD, 0x20AD, 0x08F4, 0x10D3, 0x18D1, 0x18D1, 0x08F5, 0x18D2, 0x18AD, 0x20AD, 0x08F4, 0x10D1, 0x18AD, 0x18AD, 0x08F7, 0x18AF, 0x08F7, 0x18AD, 0x08F4, 0x10D1, 0x18AD, 0x18AD, 0x208E, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x10D2, 0x00F9, 0x0119, 0x0119, 0x011A, 0x011A, 0x10D2, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x18AE, 0x18AE, 0x18AD, 0x20AE, 0x18AD, 0x20AE, 0x20CE, 0x412F, 0xD375, 0xD375, 0xD375, 0x71D1, 0x20CE, 0x28CF, 0x20CF, 0x28CE, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x3110, 0x3110, 0x38F0, 0x30F0, 0x3111, 0x3111, 0x38F1, 0x38F1, 0x38F0, 0x3910, 0x3910, 0x3910, 0x3911, 0x3911, 0x3911, 0x3910, 0x6152, 0x6152, 0x5131, 0x3911, 0x3911, 0x3911, 0x3912, 0x4112, 0x4132, 0x4112, 0x4932, 0x4932, 0x8A34, 0xD395, 0xD395, 0xD375, 0xD335, 0xD2F4, 0xCAD4, 0xB2F6, 0x065F, 0x061F, 0x061F, 0x34DC, 0xC952, 0xC912, 0xC8D2, 0xC0B1, 0xC0D1, 0xB8D1, 0x89B4, 0x2BBA, 0x4216, 0x5154, 0x5154, 0x4954, 0x5154, 0x6194, 0x71D4, 0x69F4, 0x71D3, 0x69D4, 0x71D3, 0x7A14, 0x8A75, 0x9274, 0x9254, 0x9254, 0x9A95, 0xB315, 0xBB14, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD314, 0xD315, 0xD2F4, 0xCB14, 0xD2F4, 0xD2F4, 0xD2D4, 0xCAD4, 0xCAB4, 0xD2B4, 0xCAB4, 0xCA94, 0xCA94, 0x81B8, 0x005F, 0x005F, 0x003F, 0x001F, 0x001F, 0xA8B3, 0xC0B1, 0xB0D2, 0x02DF, 0x03FF, 0x051F, 0x061F, 0x06FF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x8A95, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x78F2, 0x3911, 0x38F0, 0x30F0, 0x28F0, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CF, 0x0918, 0x0119, 0x0119, 0x011A, 0x00F9, 0x0119, 0x08F7, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x0117, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AF, 0x0119, 0x0119, 0x10D1, 0x18AD, 0x18AD, 0x10D0, 0x00FA, 0x0119, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x10D1, 0x08F7, 0x18D1, 0x18AD, 0x20AD, 0x08F8, 0x18AD, 0x18AD, 0x18AD, 0x18D1, 0x08D4, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x20AD, 0x18AE, 0x00FA, 0x08F8, 0x00F7, 0x08F6, 0x18AE, 0x18AD, 0x18AD, 0x08F4, 0x08F6, 0x08D4, 0x08F6, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x08F4, 0x10D1, 0x18AE, 0x18AE, 0x08F8, 0x18AD, 0x08F3, 0x10D3, 0x10D5, 0x10D0, 0x18AD, 0x18AD, 0x20AE, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x20AE, 0x20AE, 0x20CD, 0x20AE, 0x20CD, 0x9272, 0xD375, 0xC334, 0x61D1, 0x20CF, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x30EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x30F0, 0x3110, 0x3110, 0x30F0, 0x3110, 0x38F0, 0x30F0, 0x38F0, 0x3111, 0x38F0, 0x3911, 0x38F1, 0x3911, 0x3911, 0x3912, 0x4111, 0x4132, 0x4132, 0xB2F5, 0xD395, 0xD375, 0xD355, 0xD2F4, 0xD2B4, 0xD274, 0x83B8, 0x063F, 0x061F, 0x061E, 0x6398, 0xC912, 0xC8D1, 0xC0B1, 0xC0B1, 0xB8B1, 0xB8D1, 0x7933, 0x5153, 0x5134, 0x5154, 0x5133, 0x4953, 0x4933, 0x4933, 0x4933, 0x4133, 0x4933, 0x4932, 0x4932, 0x4932, 0x4933, 0x4933, 0x4933, 0x4932, 0x4932, 0x4933, 0x4933, 0x4933, 0x61B3, 0x7A34, 0x9A95, 0xB2F5, 0xD375, 0xD375, 0xD355, 0xD355, 0xD355, 0xD335, 0xD335, 0xD314, 0xD314, 0xD315, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2D4, 0xD2D4, 0xD2B4, 0xD2B4, 0xD294, 0xD294, 0xD274, 0xCA74, 0xC254, 0x007F, 0x005F, 0x005F, 0x003F, 0x001F, 0x5878, 0xB8D1, 0xC0B1, 0x02BF, 0x03BF, 0x04FF, 0x05FF, 0x06FF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x6478, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x78F1, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CF, 0x0917, 0x011A, 0x011A, 0x0119, 0x08F4, 0x18CE, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x00F7, 0x011A, 0x00F7, 0x18AE, 0x18AE, 0x18AD, 0x18AE, 0x188D, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x10F3, 0x0119, 0x0119, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18CE, 0x10D1, 0x18CF, 0x18AD, 0x10D1, 0x10F4, 0x18AD, 0x18AD, 0x08F7, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x10D1, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F8, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x08F5, 0x18D1, 0x18AD, 0x18AD, 0x08F6, 0x18CF, 0x18AE, 0x20AE, 0x10D4, 0x18D1, 0x18AD, 0x20AE, 0x00F8, 0x18AD, 0x18AD, 0x08F7, 0x08F6, 0x18B1, 0x18AE, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20CD, 0x18CE, 0x20AE, 0x390F, 0xD375, 0xCB35, 0x414F, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x28EF, 0x30EF, 0x30EF, 0x30EF, 0x30EF, 0x30EF, 0x30EF, 0x30EF, 0x30EF, 0x30F0, 0x28F0, 0x30F0, 0x30F0, 0x30F0, 0x28F0, 0x30F0, 0x30EF, 0x3110, 0x30F0, 0x30D0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F1, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3910, 0x3911, 0x38F1, 0x3911, 0x3912, 0x4952, 0xD395, 0xD375, 0xD335, 0xD2F4, 0xD2B4, 0xD274, 0xCA33, 0x4C9A, 0x05FF, 0x061F, 0x05FF, 0xA1F4, 0xC0D1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB8D1, 0xA0F1, 0x5134, 0x4933, 0x4933, 0x4933, 0x4933, 0x4933, 0x4932, 0x4932, 0x4932, 0x4132, 0x4132, 0x4132, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4132, 0x4132, 0x4132, 0x4132, 0x4132, 0x4133, 0x4933, 0x4932, 0x4953, 0x6193, 0x8214, 0xA274, 0xC315, 0xD335, 0xD314, 0xD315, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2B4, 0xCAB4, 0xCAB4, 0xCA94, 0xCA74, 0xCA74, 0xCA74, 0xCA54, 0x20FD, 0x009F, 0x007F, 0x005F, 0x003F, 0x105D, 0xC0B1, 0xC0D1, 0x029F, 0x03BF, 0x04DF, 0x05FF, 0x06FF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x54D9, 0xB8D1, 0xB8D1, 0xB8B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x78F1, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CE, 0x20CF, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AD, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x00F7, 0x00F9, 0x0117, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AD, 0x08F5, 0x0119, 0x0119, 0x0117, 0x00F7, 0x011A, 0x0119, 0x08D4, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AF, 0x0117, 0x10F4, 0x00F8, 0x18AF, 0x18AD, 0x18AD, 0x08F7, 0x08F4, 0x10D5, 0x00F7, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x08F8, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x08F4, 0x10D1, 0x18AD, 0x18CD, 0x10D1, 0x10D3, 0x18AD, 0x18AD, 0x08F4, 0x10D1, 0x18AD, 0x18AD, 0x08F8, 0x18AE, 0x18AD, 0x18AF, 0x00FA, 0x10D1, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x10D2, 0x011A, 0x0119, 0x00FA, 0x0119, 0x011A, 0x10D2, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AD, 0x20AE, 0x61D0, 0xBB14, 0x412F, 0x20AE, 0x20AE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x28CE, 0x20CE, 0x20CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x28CF, 0x28F0, 0x30D0, 0x28EF, 0x28CF, 0x30CF, 0x30F0, 0x30D0, 0x30D0, 0x28F0, 0x30F0, 0x30F0, 0x30F0, 0x30D0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x38F0, 0x3911, 0x3911, 0x3911, 0x61B2, 0xD375, 0xD335, 0xD2F4, 0xCAD4, 0xCA74, 0xD233, 0xCA13, 0x1D9D, 0x05FF, 0x05FF, 0x1D3D, 0xC0D1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB0D1, 0x6132, 0x4933, 0x4933, 0x4932, 0x4132, 0x4112, 0x4112, 0x4112, 0x4132, 0x4112, 0x4111, 0x4111, 0x4112, 0x4112, 0x4111, 0x3911, 0x3911, 0x4111, 0x4112, 0x4112, 0x3912, 0x4132, 0x4112, 0x4112, 0x4112, 0x4912, 0x4132, 0x4132, 0x4932, 0x4933, 0x4953, 0x4933, 0x6173, 0x8A14, 0xAA74, 0xCAF4, 0xD2F5, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2B4, 0xCAB4, 0xD2B4, 0xD294, 0xCA94, 0xCA73, 0xD274, 0xD253, 0xD254, 0x597A, 0x00BF, 0x00BF, 0x009F, 0x009F, 0x005F, 0xA8B3, 0xC0B1, 0x31FC, 0x039F, 0x04DF, 0x05DF, 0x06DF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x2E3C, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8B1, 0xB8D1, 0xB8D1, 0x78F1, 0x3911, 0x30F0, 0x30F0, 0x28EF, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AD, 0x20AE, 0x18CE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F7, 0x0119, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AE, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x00F9, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18B1, 0x18CE, 0x18AD, 0x18AD, 0x18AE, 0x18B0, 0x10D0, 0x10D1, 0x18AF, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CF, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x10D0, 0x18AE, 0x18AD, 0x18AF, 0x18AE, 0x18AD, 0x18AD, 0x10D0, 0x188D, 0x18AD, 0x18AE, 0x10D0, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x10D2, 0x00F9, 0x011A, 0x0119, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AF, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AF, 0x18AF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AF, 0x18AF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AE, 0x390F, 0x28CE, 0x20AE, 0x20CE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28EF, 0x28EF, 0x28CF, 0x28EF, 0x28EF, 0x30EF, 0x28EF, 0x28EF, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x30F0, 0x3911, 0x71F2, 0xD335, 0xD2F4, 0xD2B4, 0xCA74, 0xD233, 0xCA13, 0xA295, 0x05FF, 0x05FF, 0x05FF, 0x5399, 0xC0D1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB0D1, 0x7912, 0x4952, 0x4132, 0x4112, 0x4132, 0x4132, 0x4132, 0x4112, 0x3911, 0x3911, 0x3911, 0x3911, 0x38F1, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x4111, 0x4112, 0x4112, 0x4112, 0x4112, 0x4132, 0x4932, 0x4932, 0x4933, 0x4933, 0x5133, 0x6194, 0x9A34, 0xC2B4, 0xD2B5, 0xD2B3, 0xCAB4, 0xD294, 0xD294, 0xCA93, 0xD274, 0xD274, 0xCA53, 0xCA54, 0xCA53, 0x81D8, 0x00DF, 0x00DF, 0x00DF, 0x00BF, 0x00BF, 0x68B7, 0xB8D1, 0x31DC, 0x033F, 0x049F, 0x05DF, 0x06FF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x26BD, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D2, 0xB8D1, 0xB8D1, 0x78F1, 0x3911, 0x38F1, 0x30F0, 0x30EF, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0117, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x08D3, 0x08F3, 0x10D2, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AE, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x00F7, 0x011A, 0x0119, 0x0118, 0x18AF, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18B0, 0x0118, 0x0119, 0x0119, 0x00F6, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x00F8, 0x0119, 0x011A, 0x00F6, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20CF, 0x20CF, 0x20CF, 0x20CF, 0x20CF, 0x20CF, 0x20CF, 0x20CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28CF, 0x28EF, 0x28F0, 0x28F0, 0x30F0, 0x30F0, 0x38F0, 0x8213, 0xD2F5, 0xCAD4, 0xD274, 0xCA53, 0xC9F3, 0xC9D2, 0x7398, 0x05FF, 0x05FF, 0x05DF, 0xA953, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x98F2, 0x4132, 0x4132, 0x4112, 0x4111, 0x4111, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x38F0, 0x38F0, 0x38F0, 0x38F0, 0x3911, 0x38F0, 0x38F0, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x3911, 0x4112, 0x4112, 0x4112, 0x4132, 0x4132, 0x4933, 0x4933, 0x4933, 0x5153, 0x5974, 0x9214, 0xCA94, 0xD294, 0xCA94, 0xD274, 0xCA74, 0xD274, 0xCA53, 0xCA54, 0xCA53, 0xCA34, 0x99F6, 0x011F, 0x011F, 0x00FF, 0x00FF, 0x00FF, 0x38DB, 0xC0B1, 0x28FC, 0x02DF, 0x047F, 0x059F, 0x06DF, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x78F1, 0x3911, 0x38F0, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x011A, 0x00F7, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x011A, 0x011A, 0x00F9, 0x011A, 0x00F9, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x00F9, 0x0119, 0x0119, 0x011A, 0x0119, 0x0117, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AE, 0x18B0, 0x0119, 0x00F9, 0x0119, 0x00F9, 0x0119, 0x08F6, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18D0, 0x00F9, 0x0119, 0x0119, 0x011A, 0x0119, 0x08F6, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x310E, 0x7A32, 0xAAD3, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD335, 0xD2B4, 0xCA94, 0xCA33, 0xD1F3, 0xC9D3, 0xC993, 0xC972, 0xC992, 0xC972, 0xC932, 0xC0D1, 0xC0B1, 0xB8D1, 0xB0D2, 0xB9F2, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xCA13, 0x015F, 0x013F, 0x013F, 0x013F, 0x011F, 0x093F, 0xC0B1, 0x311C, 0x01BF, 0x03FF, 0x059F, 0x069F, 0x079F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0xB8B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x78F1, 0x3911, 0x3911, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x08D5, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x10F2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x00F8, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x18AF, 0x18AD, 0x18AD, 0x18AE, 0x18B0, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x10CF, 0x0118, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x20AD, 0x18AD, 0x496F, 0xAAD3, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD2F4, 0xCA74, 0xCA33, 0xCA13, 0xC9D3, 0xC992, 0xC952, 0xC111, 0xC0D1, 0xC0B1, 0xC0D1, 0xB8B1, 0xB8D1, 0xB8D1, 0xCA53, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xCA13, 0x097F, 0x017F, 0x015F, 0x017F, 0x015F, 0x015F, 0x88F5, 0x293C, 0x013F, 0x02DF, 0x053E, 0x067F, 0x077F, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x9234, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x78F1, 0x3911, 0x3911, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AE, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x18AF, 0x18CD, 0x18AE, 0x10D0, 0x0118, 0x0119, 0x011A, 0x011A, 0x0119, 0x011A, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x00F8, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20EE, 0x8252, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD3B5, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD2B4, 0xD233, 0xCA13, 0xC9B3, 0xC992, 0xC952, 0xC912, 0xC8D1, 0xC0B1, 0xC0B1, 0xB8B1, 0xB8D1, 0xB8D1, 0xC253, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDB95, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xCA13, 0x31BC, 0x01BF, 0x019F, 0x019F, 0x019F, 0x019F, 0x5139, 0x315C, 0x017F, 0x01BF, 0x045E, 0x063E, 0x077F, 0x07FE, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x8A95, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB8D1, 0x78F1, 0x3911, 0x3911, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x08D5, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x00F9, 0x0119, 0x00F9, 0x011A, 0x0119, 0x0119, 0x011A, 0x00F9, 0x08F7, 0x18AD, 0x20AD, 0x10D0, 0x0118, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x10D0, 0x00F9, 0x0119, 0x0119, 0x00FA, 0x0119, 0x0119, 0x011A, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x28EE, 0xB314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD4F8, 0xD65C, 0xD6DD, 0xD6FD, 0xD7FF, 0xD7FF, 0xDFFF, 0xD7FF, 0xD7FF, 0xDFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xDFFF, 0xD7FF, 0xCB15, 0xCA13, 0xC9D3, 0xC992, 0xC932, 0xC911, 0xC0D1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xC397, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xDFFF, 0xD539, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDB95, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xC9F3, 0x31FC, 0x01DF, 0x01DF, 0x01DF, 0x01DF, 0x01DF, 0x01BF, 0x01DF, 0x01BF, 0x01BF, 0x02DF, 0x05FD, 0x073E, 0x07FE, 0x07FE, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x8AB5, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0F1, 0xB8D1, 0x78F1, 0x3911, 0x3911, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08D5, 0x0119, 0x011A, 0x0119, 0x011A, 0x00F9, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x00F8, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x00F7, 0x18AE, 0x18AE, 0x18B0, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x10D0, 0x00F8, 0x0119, 0x011A, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AE, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x28EE, 0xCB55, 0xD375, 0xD395, 0xD395, 0xD3D6, 0xD5DB, 0xD7BF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xDFFF, 0xDFFF, 0xCA13, 0xC9B3, 0xC992, 0xC952, 0xC912, 0xC0D1, 0xC0B1, 0xC0D1, 0xB8B1, 0xB8D1, 0xB0F1, 0xBA95, 0xDFFF, 0xD7FF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xD7FF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xDFFF, 0xD539, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xC9F3, 0x31FD, 0x021F, 0x01FF, 0x01FF, 0x01FF, 0x01FF, 0x01FF, 0x01FF, 0x01FF, 0x01DF, 0x01FF, 0x051D, 0x071D, 0x07FD, 0x07FE, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x6BF7, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0x78F1, 0x3911, 0x3911, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x011A, 0x00F7, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x0119, 0x011A, 0x00F8, 0x18B0, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x00F7, 0x18AE, 0x18AD, 0x10CF, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18CF, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x011A, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x28EE, 0xB314, 0xD395, 0xD395, 0xD395, 0xD477, 0xD77E, 0xD7FF, 0xD7FF, 0xDFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xDFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xC9D3, 0xC992, 0xC952, 0xC912, 0xC8D1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB152, 0xD79E, 0xDFFF, 0xDFFF, 0xDFFF, 0xD7FF, 0xDFFF, 0xDFFF, 0xDFFF, 0xDFFF, 0xD7FF, 0xDFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD539, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xC9D3, 0x323C, 0x023F, 0x023F, 0x021F, 0x023F, 0x023F, 0x021F, 0x021F, 0x021F, 0x021F, 0x021F, 0x037E, 0x06DC, 0x07FD, 0x07FD, 0x07FE, 0x07FF, 0x07FF, 0x07FF, 0x5C78, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB8D1, 0xB0F1, 0x7911, 0x3911, 0x3911, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AE, 0x18AE, 0x011A, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x00F9, 0x18AF, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08D5, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x0118, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x10D0, 0x0119, 0x0119, 0x011A, 0x00F9, 0x0119, 0x0119, 0x0119, 0x011A, 0x0117, 0x18AE, 0x18AD, 0x10D0, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x8252, 0xD395, 0xD395, 0xD396, 0xD4B8, 0xD7BF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xC972, 0xC952, 0xC912, 0xC8D1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0F1, 0xD63C, 0xDFFF, 0xDFFF, 0xD7FF, 0xDFFF, 0xDFFF, 0xD7FF, 0xDFFF, 0xDFFF, 0xD7FF, 0xD7FF, 0xDFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xDFFF, 0xD7FF, 0xDFFF, 0xD539, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xC9D3, 0x325C, 0x027F, 0x025F, 0x025F, 0x025F, 0x023F, 0x025F, 0x025F, 0x023F, 0x023F, 0x023F, 0x029F, 0x067C, 0x07FC, 0x07FC, 0x07FE, 0x07FF, 0x07FF, 0x07FF, 0x5C78, 0xB8D1, 0xB0D1, 0xB8D1, 0xB0D1, 0xB0D1, 0xB8D1, 0x70F1, 0x3911, 0x3911, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00F9, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x10D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x011A, 0x011A, 0x0118, 0x10D1, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x011A, 0x00F7, 0x18AE, 0x18AD, 0x10D0, 0x0118, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x10CF, 0x0119, 0x0119, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x496F, 0xD395, 0xD395, 0xD395, 0xD457, 0xD7BF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7DF, 0xD7FF, 0xCF3E, 0xC67C, 0xC53A, 0xC951, 0xC912, 0xC0D1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB0F1, 0xBB97, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD65B, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD396, 0xD395, 0xC9B3, 0x327C, 0x029F, 0x029F, 0x029F, 0x029F, 0x027F, 0x027F, 0x027F, 0x027F, 0x027F, 0x025F, 0x027F, 0x05BC, 0x07DB, 0x07FC, 0x07FD, 0x07FF, 0x07FF, 0x07FF, 0x5C78, 0xB8D1, 0xB0D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0x58F1, 0x3911, 0x3111, 0x30F0, 0x28F0, 0x28F0, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x10D1, 0x18AD, 0x18AE, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x08F5, 0x0119, 0x011A, 0x0119, 0x0119, 0x00F9, 0x18B0, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18D0, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18CF, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x0117, 0x18CE, 0x18AE, 0x18D0, 0x0118, 0x00F9, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0xA2D3, 0xD395, 0xD395, 0xD3D6, 0xD75E, 0xCFFF, 0xCFFF, 0xD7FF, 0xD7FF, 0xCFFF, 0xCFFF, 0xD7FF, 0xD7FF, 0xD7DF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7DF, 0xD7FF, 0xD7FF, 0xCFDF, 0xCFFF, 0xD7FF, 0xD7DF, 0xD7FF, 0xCFFF, 0xD7FF, 0xD7DF, 0xD7FF, 0xCFFF, 0xD7DF, 0xCFFF, 0xCFFF, 0xD7FF, 0xD7FF, 0xCFFF, 0xD7FF, 0xCFFF, 0xD7FF, 0xD7DF, 0xD7DF, 0xCFFF, 0xD7DF, 0xCFFF, 0xD7FF, 0xD7FF, 0xCFFF, 0xD7FF, 0xCFFF, 0xD7FF, 0xD7DF, 0xD7FF, 0xD7FF, 0xCFFF, 0xCFFF, 0xD7FF, 0xCFFF, 0xD7DF, 0xCFFF, 0xD7FF, 0xD7DF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xCFFF, 0xD7FF, 0xCFDF, 0xD7DF, 0xCFDF, 0xCFFF, 0xD7DF, 0xACD8, 0x8191, 0x9151, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0xA8F1, 0xA972, 0xD77E, 0xD7FF, 0xD7FF, 0xD7DF, 0xD7DF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7DF, 0xCFFF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7DF, 0xD7DF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7FF, 0xD7DF, 0xD7FF, 0xD7DF, 0xD7FF, 0xD7DF, 0xD65C, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xC193, 0x0A7F, 0x02FF, 0x02DF, 0x02BF, 0x02BF, 0x02BF, 0x029F, 0x029F, 0x029F, 0x027F, 0x029F, 0x027F, 0x04DD, 0x07BB, 0x07FB, 0x07FD, 0x07FF, 0x07FF, 0x07FF, 0x3DBB, 0xB8D1, 0xB8D1, 0xB0F1, 0xB0D1, 0xB0D1, 0xB0D1, 0x5911, 0x3911, 0x30F0, 0x30F0, 0x28F0, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x20AD, 0x08F5, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x18D0, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x10D0, 0x00F8, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x20AD, 0x10D0, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x0119, 0x011A, 0x00F7, 0x18AE, 0x18AD, 0x18AF, 0x0118, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x310E, 0xD395, 0xD375, 0xD375, 0xD5BA, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xC77E, 0xBE5B, 0xBE3C, 0xB57A, 0xACB8, 0xBDBB, 0xC63C, 0xBE3B, 0xC71E, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xC77E, 0xBE5C, 0xB5DB, 0xACB8, 0xAC98, 0xBD5A, 0xBE3C, 0xC61C, 0xC69D, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xACB9, 0x8191, 0x9151, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0xA111, 0xA911, 0xBC78, 0xCFDF, 0xCFDF, 0xCFDF, 0xD7DF, 0xCFDF, 0xCF5E, 0xBE5C, 0xBE5C, 0xC63C, 0xC61C, 0xCEFD, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFFF, 0xCFDF, 0xD63B, 0xD375, 0xD395, 0xD375, 0xD395, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD375, 0xD395, 0xD375, 0xD375, 0xD375, 0xD395, 0x089F, 0x011F, 0x031F, 0x02FF, 0x02FF, 0x02DF, 0x02DF, 0x02DF, 0x02BF, 0x02BF, 0x02BF, 0x02BF, 0x02BF, 0x03FD, 0x079A, 0x07FA, 0x07FC, 0x07FE, 0x07FF, 0x07FF, 0x2E5C, 0xB0D1, 0xB8D1, 0xB8D1, 0xB0F1, 0xB0D1, 0xB8D1, 0x5912, 0x3911, 0x38F1, 0x30F0, 0x28F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x08F5, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x10D0, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x00F6, 0x0119, 0x0119, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AE, 0x0117, 0x011A, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0117, 0x18CE, 0x18AD, 0x18AD, 0x0118, 0x011A, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x79F1, 0xD355, 0xD355, 0xD355, 0xCF7E, 0xC7DF, 0xCFBF, 0xCFDF, 0xC7DF, 0xC7DF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFBF, 0xCFDF, 0xCFDF, 0xCFBF, 0xBEFD, 0xACB8, 0x8A52, 0x9151, 0x9131, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0xA192, 0xAB96, 0xBE7D, 0xCFDF, 0xC7DF, 0xCFBF, 0xC7DF, 0xCFDF, 0xCFBF, 0xC75E, 0xAD19, 0x92B4, 0x8971, 0x9151, 0x9931, 0x9931, 0x9911, 0x9911, 0xA111, 0x9931, 0xA111, 0x9911, 0xAB36, 0xBD5A, 0xC75E, 0xCFDF, 0xC7BF, 0xC7BF, 0xCFDF, 0xC7DF, 0xC7BF, 0xC7DF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCFDF, 0xC7DF, 0xCFBF, 0xC7DF, 0xC7BF, 0xCFBF, 0xC7DF, 0xA4B8, 0x8191, 0x9151, 0x9931, 0x9911, 0x9931, 0x9931, 0x9911, 0x9931, 0x9912, 0xBE3B, 0xCFBF, 0xCFDF, 0xCFBF, 0xCFDF, 0xCFDF, 0xB5DA, 0x8A12, 0x8971, 0x9931, 0x9931, 0xA111, 0x9931, 0xAB35, 0xC75E, 0xCFBF, 0xCFDF, 0xC7DF, 0xC7DF, 0xCFDF, 0xCFDF, 0xCFBF, 0xC7DF, 0xC7DF, 0xCFDF, 0xCFDF, 0xCFDF, 0xC7DF, 0xCFDF, 0xCFDF, 0xCFDF, 0xCE1B, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0x007F, 0x009E, 0x023F, 0x033F, 0x031F, 0x031F, 0x031F, 0x02FF, 0x031F, 0x02FF, 0x02DF, 0x02DF, 0x02DF, 0x039E, 0x075A, 0x07F9, 0x07FB, 0x07FD, 0x07FF, 0x07FF, 0x2E3C, 0xB8D2, 0xB8D1, 0xB0D1, 0xB8D1, 0xB0D1, 0xB0D1, 0x4911, 0x3911, 0x38F0, 0x30F0, 0x28F0, 0x28EF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x20AD, 0x20AD, 0x08F5, 0x00F9, 0x00FA, 0x0119, 0x011A, 0x0119, 0x10D2, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x10D0, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x011A, 0x00F9, 0x0119, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18CD, 0x0119, 0x00F9, 0x011A, 0x0119, 0x0119, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AE, 0x18AD, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x011A, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0xA293, 0xD335, 0xD335, 0xCC98, 0xC7BF, 0xC7BE, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC75E, 0xA4B8, 0x8191, 0x9151, 0x9911, 0xA131, 0xA111, 0xA111, 0x9931, 0xA111, 0xA112, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xAB35, 0xBEFE, 0xC7BF, 0xC7BE, 0xC7BF, 0xB5DB, 0x89F1, 0x8971, 0x9931, 0x9911, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA132, 0x9911, 0xA111, 0xA111, 0xA111, 0xA111, 0xA172, 0xBD3A, 0xC7BE, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BE, 0xC79F, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC79F, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xAC98, 0x8191, 0x9151, 0x9931, 0xA111, 0xA131, 0xA111, 0xA131, 0xA111, 0x9931, 0xBE1B, 0xC79F, 0xC7BF, 0xC7BF, 0xC7BF, 0xBEFD, 0x89F2, 0x8991, 0x9931, 0xA112, 0xA131, 0xA111, 0xA111, 0xA111, 0xAB97, 0xC7BF, 0xC7BF, 0xC7BE, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC7BF, 0xC6DD, 0xD375, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD335, 0xD334, 0xD335, 0xD335, 0x009F, 0x009F, 0x013F, 0x033F, 0x037F, 0x035F, 0x033F, 0x031F, 0x031F, 0x031F, 0x031F, 0x02FF, 0x02FF, 0x033F, 0x06F9, 0x07F9, 0x07FB, 0x07FD, 0x07FF, 0x07FF, 0x2E3C, 0xB8D2, 0xB0F1, 0xB8D1, 0xB0D1, 0xB0F1, 0xB0D1, 0x3911, 0x3911, 0x38F0, 0x30F0, 0x3110, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18B0, 0x10F2, 0x10D3, 0x08D3, 0x08F3, 0x10F3, 0x18B0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x08F5, 0x0119, 0x00F9, 0x011A, 0x0119, 0x011A, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F4, 0x0119, 0x0119, 0x011A, 0x011A, 0x00F9, 0x10CF, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x0119, 0x00F9, 0x011A, 0x011A, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00F9, 0x0119, 0x0119, 0x0139, 0x0119, 0x011A, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0xD315, 0xD315, 0xD314, 0xC5FB, 0xC79F, 0xC79E, 0xC7BF, 0xC7BF, 0xC79E, 0xC79E, 0xC7BF, 0xC79F, 0xBF9E, 0xBFBF, 0xBFBE, 0xB67C, 0x8A53, 0x8971, 0xA131, 0xA112, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA112, 0xA111, 0xA111, 0xA172, 0xB539, 0xBF9F, 0x9BF6, 0x8191, 0x9151, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA112, 0xA111, 0xA111, 0xAB15, 0xBF3D, 0xC79F, 0xC7BE, 0xC79F, 0xC79F, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79E, 0xC79F, 0xC79E, 0xC79F, 0xC79E, 0xC79E, 0xC7BF, 0xC79F, 0xA4B8, 0x8191, 0x9151, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA112, 0xA111, 0xBDFB, 0xC79F, 0xC79E, 0xC7BE, 0xC79F, 0xACF9, 0x8191, 0x9171, 0xA111, 0xA111, 0xA111, 0xA112, 0xA111, 0xA131, 0xA111, 0xBF3E, 0xBFBF, 0xC79E, 0xC79E, 0xC79E, 0xC7BF, 0xC79E, 0xC79E, 0xC79E, 0xBFBF, 0xC79E, 0xC79E, 0xC79E, 0xBF9E, 0xC79F, 0xC79E, 0xBFBE, 0xC79E, 0xC6BD, 0xD355, 0xD2F5, 0xD315, 0xCB14, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD314, 0xD315, 0xD315, 0xD315, 0xD314, 0x007F, 0x007F, 0x00FF, 0x027F, 0x039F, 0x039F, 0x037F, 0x231D, 0x5259, 0x5A3A, 0x033F, 0x033F, 0x031F, 0x031F, 0x0699, 0x07F8, 0x07FA, 0x07FD, 0x07FF, 0x07FF, 0x363C, 0xB0D1, 0xB0F1, 0xB0D1, 0xB8D1, 0xB0D1, 0xB0D1, 0x4112, 0x38F1, 0x3911, 0x30F0, 0x30EF, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D1, 0x08F7, 0x011A, 0x011A, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x00F7, 0x10D1, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10F2, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x0119, 0x0118, 0x18B0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x08F4, 0x0119, 0x0119, 0x0119, 0x011A, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0915, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x20AD, 0x0915, 0x00F9, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20CD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xD2F4, 0xCAF4, 0xD2F4, 0xC65C, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF7F, 0xB67C, 0x8A12, 0x8971, 0xA111, 0xA111, 0xA911, 0xA111, 0xA911, 0xA111, 0xA111, 0xA111, 0xA911, 0xA911, 0xA111, 0xA111, 0xA111, 0xA911, 0xA111, 0xA111, 0xA111, 0xA912, 0xA911, 0xA1F3, 0x8191, 0x9931, 0xA111, 0xA111, 0xA912, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA911, 0xA911, 0xA911, 0xA911, 0xA911, 0xA111, 0xA111, 0xA111, 0xA112, 0xA911, 0xAA54, 0xBF1D, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xB79E, 0xBF9F, 0xA498, 0x8191, 0x9951, 0xA911, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA911, 0xB5FB, 0xBF9E, 0xBF9F, 0xBF9E, 0xBF9F, 0xA498, 0x8191, 0x9951, 0xA111, 0xA111, 0xA111, 0xA111, 0xA112, 0xA111, 0xA911, 0xB5FB, 0xBF7E, 0xBF9E, 0xBF9E, 0xBF9F, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBF9E, 0xBEBD, 0xD335, 0xCAF4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xCAF4, 0xD2F4, 0xD2F5, 0xCAF4, 0x007F, 0x007F, 0x00BF, 0x021F, 0x2ABD, 0x7A36, 0xB953, 0xC112, 0xC911, 0xC912, 0x0B3F, 0x035F, 0x035F, 0x033F, 0x05FA, 0x07F7, 0x07F9, 0x07FC, 0x07FE, 0x07FF, 0x2E3C, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0D1, 0xB0D1, 0xA0F1, 0x68F1, 0x4111, 0x30F0, 0x30F0, 0x28EF, 0x28EF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x011A, 0x0119, 0x0119, 0x0118, 0x08F7, 0x08F6, 0x00F7, 0x0118, 0x0119, 0x0119, 0x0119, 0x08F5, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x10D2, 0x00F9, 0x011A, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08D4, 0x0118, 0x0119, 0x08F6, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x011A, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xD2D4, 0xD2D4, 0xD2D4, 0xBE5C, 0xB77E, 0xB79E, 0xB77E, 0xBF7E, 0xB77E, 0xB77E, 0xB77E, 0xB79E, 0xBF7E, 0xAE7B, 0x89F2, 0x8971, 0xA111, 0xA8F1, 0xA911, 0xA8F1, 0xA911, 0xA911, 0xA911, 0xA911, 0xA911, 0xA8F1, 0xA911, 0xA911, 0xA911, 0xA8F1, 0xA911, 0xA8F1, 0xA911, 0xA911, 0xA912, 0xA911, 0xA911, 0xA111, 0xA911, 0xA8F1, 0xA911, 0xA8F1, 0xA111, 0xA911, 0xA8F1, 0xA8F1, 0xA911, 0xA911, 0xA8F1, 0xA911, 0xA8F1, 0xA8F1, 0xA912, 0xA911, 0xA911, 0xA911, 0xA8F1, 0xA111, 0xAA34, 0xB71E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xBF7E, 0xB77E, 0xB77E, 0xBF7E, 0xB77E, 0xB77E, 0xBF7F, 0xB77E, 0x9C97, 0x8191, 0x9951, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA911, 0xA8F1, 0xB5DB, 0xBF7E, 0xB77E, 0xBF7E, 0xBF7E, 0xA478, 0x8191, 0x9951, 0xA911, 0xA8F1, 0xA8F1, 0xA911, 0xA911, 0xA8F1, 0xA911, 0xB5DB, 0xB77F, 0xB77E, 0xBF7E, 0xBF7E, 0xB77E, 0xBF7E, 0xBF7E, 0xBF7E, 0xB77E, 0xB77E, 0xBF7E, 0xB77E, 0xBF7E, 0xB77E, 0xBF7E, 0xBF7E, 0xB77E, 0xB77E, 0xBF7E, 0xBE9D, 0xCB75, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2D5, 0x007F, 0x007F, 0x30BB, 0x9955, 0xC931, 0xC932, 0xC932, 0xC912, 0xC0F2, 0xC8F2, 0x32FC, 0x037F, 0x037F, 0x037F, 0x059B, 0x07F7, 0x07F9, 0x07FC, 0x07FE, 0x07FF, 0x2E3C, 0xB8D1, 0xB0D1, 0xB0D2, 0xB0D1, 0xB0F1, 0x98F1, 0xB0F1, 0x88F1, 0x3110, 0x30F0, 0x30F0, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x011A, 0x0119, 0x00F7, 0x10D1, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D1, 0x00F7, 0x011A, 0x0119, 0x00F7, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x011A, 0x011A, 0x0119, 0x00F8, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xD2B4, 0xD2B4, 0xD2B4, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB71D, 0x8A53, 0x8191, 0xA111, 0xA8F1, 0xB0F1, 0xA911, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F2, 0xA8F1, 0xB0F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xB2F5, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB75E, 0xB77E, 0xB77E, 0xB77E, 0xB75E, 0xB75E, 0xB77E, 0xB75E, 0xB77E, 0xB77E, 0xB75E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB75E, 0xB75E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB75E, 0xB77E, 0xB77E, 0xB75E, 0xB77E, 0xB75E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0x9C78, 0x8191, 0x9951, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xB5DB, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0x9C77, 0x8191, 0x9151, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xB5DB, 0xB77E, 0xB77E, 0xB77E, 0xB75E, 0xB77E, 0xB75E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB75E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB77E, 0xB75E, 0xB71D, 0xCB96, 0xD2B4, 0xD2B4, 0xCAB4, 0xD2B4, 0xCAB4, 0xD2B4, 0xCAB4, 0xD2B4, 0xCAB4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xCA94, 0xD2B4, 0xD2B4, 0xD2B4, 0xCAB4, 0x087E, 0x70F8, 0xC952, 0xC932, 0xC912, 0xC932, 0xC111, 0xC8F1, 0xC8F1, 0xC8D1, 0x331C, 0x03BF, 0x039F, 0x039F, 0x051B, 0x07D6, 0x07F7, 0x07FB, 0x07FE, 0x07FF, 0x2E3C, 0xB8D1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0D1, 0xA0F1, 0xB0F1, 0xB0D1, 0x50F0, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0116, 0x0119, 0x0119, 0x08D5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x10D3, 0x00FA, 0x0119, 0x08F6, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AE, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AE, 0x10D2, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x0119, 0x011A, 0x0119, 0x0119, 0x00F9, 0x18D0, 0x188D, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xD294, 0xD294, 0xCA94, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF5E, 0xB75E, 0x9416, 0x8991, 0x9951, 0xB0F1, 0xA8F1, 0xB0F1, 0xA8F1, 0xB0F1, 0xA8F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xA8F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xA8F1, 0xA8F1, 0xB0F1, 0xA8F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0F2, 0xA8F1, 0xB0F1, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0F2, 0xA8F1, 0xB0F2, 0xB0F1, 0xB0F1, 0xB0F1, 0xA8F1, 0xB0F1, 0xB0F1, 0xACF9, 0xAF5E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF7E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xB75E, 0xB75E, 0xAF5E, 0xB75E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xB75E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5D, 0xB75E, 0xAF5E, 0xAF5E, 0x9C77, 0x8191, 0x9951, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xADBB, 0xB75E, 0xB75E, 0xB75E, 0xB75E, 0x9C78, 0x8991, 0x9951, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB5BB, 0xB75E, 0xB75E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF5E, 0xB75E, 0xB75E, 0xB75E, 0xAF5E, 0xB75E, 0xB75E, 0xB75E, 0xAF5E, 0xAF5E, 0xB75E, 0xAF5E, 0xAF1D, 0xCB75, 0xCA93, 0xD294, 0xCA74, 0xCA94, 0xCA74, 0xD274, 0xCA74, 0xD294, 0xCA94, 0xCA94, 0xCA94, 0xCA94, 0xCA94, 0xCA94, 0xCA94, 0xCA94, 0xD294, 0xCA93, 0xCA94, 0xD293, 0xCA74, 0x9915, 0xC932, 0xC932, 0xC932, 0xC912, 0xC111, 0xC8F2, 0xC0F2, 0xC8D1, 0xC8D1, 0x333C, 0x03FF, 0x03DF, 0x03BF, 0x04DC, 0x07D6, 0x07F7, 0x07FB, 0x07FE, 0x07FF, 0x2E3C, 0xB0D1, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0F1, 0xA8F1, 0xB0F1, 0xB0F1, 0x90F1, 0x30F0, 0x28F0, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x011A, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08D3, 0x0119, 0x0119, 0x10D1, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xD274, 0xD274, 0xCA53, 0xAF5E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3D, 0xAF5D, 0xAF3D, 0xAF3E, 0xA69C, 0x8191, 0x8191, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0D1, 0xB0F2, 0xB0D1, 0xB0D1, 0xB0F2, 0xB0F1, 0xB0F1, 0xAA13, 0xB418, 0xA438, 0x9AB4, 0x9931, 0xA8F1, 0xB0F1, 0xB0F2, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xAA74, 0xAC78, 0xACF9, 0x9B35, 0x9931, 0xA8F1, 0xB0F1, 0xB0F2, 0xB0F1, 0xB0D1, 0xB0D1, 0xB0F1, 0xB0F2, 0xB0D1, 0xB0F1, 0xA9B3, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3D, 0xAF3D, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3D, 0xAF3D, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3D, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0x9C77, 0x8191, 0x9931, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xADBB, 0xAF3E, 0xAF3E, 0xAF5D, 0xAF3E, 0x9477, 0x8191, 0x9951, 0xB0D1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0D1, 0xADBA, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3D, 0xAF5E, 0xAF5E, 0xAF5E, 0xAF3D, 0xAF3D, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF5E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAF3E, 0xAEFD, 0xCB56, 0xCA53, 0xCA74, 0xD253, 0xD274, 0xD274, 0xD273, 0xCA73, 0xD274, 0xD274, 0xD274, 0xD274, 0xD274, 0xD274, 0xD274, 0xD274, 0xD254, 0xCA74, 0xCA54, 0xCA54, 0xCA74, 0xC932, 0xC932, 0xC932, 0xC912, 0xC912, 0xC912, 0xC0F1, 0xC8D1, 0xC8D1, 0xC8D1, 0x335C, 0x041F, 0x03FF, 0x03FF, 0x047D, 0x0795, 0x07F6, 0x07FA, 0x07FE, 0x07FF, 0x2E3C, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0F1, 0xA8F1, 0xB0F1, 0xB0D1, 0xB0F1, 0x40F0, 0x28CF, 0x28EF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CD, 0x00F8, 0x011A, 0x08F6, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18CF, 0x08D3, 0x08F3, 0x08F3, 0x18AF, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x00F6, 0x0119, 0x0118, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xCA53, 0xCA53, 0xCA53, 0xA73E, 0xA73E, 0xA73E, 0xA73E, 0xA73D, 0xA73D, 0xA73D, 0xA73D, 0x9457, 0x8191, 0x9931, 0xB8D1, 0xB0D1, 0xB8D1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB1B3, 0xAD9A, 0xAF3D, 0xAF3D, 0xA73D, 0xA73D, 0x9DDA, 0x89D1, 0x9951, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0F1, 0xB213, 0xAD9B, 0xA73E, 0xA73D, 0xAF3E, 0xAF3E, 0x9DDA, 0x81F2, 0x9171, 0xB0F1, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0D1, 0xB8D1, 0xB8D2, 0xB0F1, 0xAD39, 0xA73D, 0xA73E, 0xA73D, 0xA73D, 0xA73D, 0xA73D, 0xA73D, 0xA73E, 0xA73D, 0xA73D, 0xA73D, 0xAF3D, 0xA73D, 0xA73D, 0xA73D, 0xA73E, 0xA73E, 0xA73D, 0xAF3D, 0xA73D, 0xA73D, 0xA73E, 0xAF3D, 0xA73E, 0xA73E, 0xA73D, 0xAF3D, 0xA73D, 0xA73D, 0xA73E, 0xAF3E, 0xAF1E, 0xA73E, 0xA73E, 0xA73E, 0xA73E, 0xA73E, 0xA73E, 0xA73E, 0xA73E, 0xAF3E, 0xA73E, 0xA73D, 0xAF3E, 0xA73E, 0xA73D, 0xA73D, 0xA73D, 0xAF3D, 0xA73E, 0xA73E, 0xA73E, 0xA73D, 0xAF3D, 0xA73D, 0xAF3D, 0xA73E, 0xA73E, 0xAF3D, 0xA73E, 0xA73D, 0xA73D, 0xA73E, 0x9478, 0x8191, 0x9931, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB8D1, 0xAD9A, 0xA73E, 0xA73D, 0xA73E, 0xA73D, 0xA73D, 0xA73D, 0xAF3D, 0xA73D, 0xA73D, 0xA73D, 0xA73D, 0xA73D, 0xAF3D, 0xA73D, 0xA73D, 0xA73D, 0xAF3E, 0xA73E, 0xA73D, 0xA73D, 0xA73D, 0xAF3D, 0xAF3E, 0xA73D, 0xAF3D, 0xAF3E, 0xA73D, 0xA73D, 0xAF3D, 0xA73E, 0xAF3D, 0xAF3D, 0xAF3D, 0xA73E, 0xA73D, 0xA73D, 0xAF3D, 0xA73D, 0xAEDD, 0xC376, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA33, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xD233, 0xCA53, 0xD253, 0xCA53, 0xCA53, 0x309C, 0x005F, 0x58B9, 0xC912, 0xC111, 0xC8F1, 0xC8D1, 0xC8D1, 0xC0D1, 0xC0D1, 0x337C, 0x045F, 0x041F, 0x041F, 0x045E, 0x0775, 0x07F5, 0x07FA, 0x07FE, 0x07FF, 0x2E3C, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0D1, 0xB0F1, 0xA8F1, 0xB0F1, 0xB0F1, 0xB0D1, 0x80F1, 0x28EF, 0x28CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x011A, 0x011A, 0x10D1, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x10D1, 0x0119, 0x0119, 0x10D0, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xCA13, 0xCA33, 0xCA13, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA73D, 0xA73D, 0xA73D, 0x8A53, 0x8191, 0xA8F1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB213, 0xA6BD, 0xA71D, 0xA73E, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0x9E1B, 0x81F1, 0x9171, 0xB0F1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB1F3, 0xA6BD, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA73D, 0xA71D, 0x9E1B, 0x89F2, 0x8991, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB8D1, 0xB336, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA73D, 0xA73D, 0xA73D, 0xA71D, 0xA71D, 0xA73D, 0xA71D, 0xA71E, 0xA71D, 0xA71D, 0xA73D, 0xA73E, 0xA71D, 0xA71D, 0xA71D, 0xA73E, 0xA71D, 0xA73E, 0xA73D, 0xA71D, 0xA71D, 0xA73D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA73D, 0xA73D, 0xA73D, 0xA73E, 0xA71D, 0xA73D, 0xA73D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA73D, 0xA71D, 0xA71D, 0xA73E, 0xA73D, 0xA73D, 0xA71D, 0xA71D, 0x9477, 0x8191, 0x9931, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xA59A, 0xA71D, 0xA73D, 0xA73E, 0xA71D, 0xA71D, 0xA71E, 0xA73D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA73D, 0xA73D, 0xA71E, 0xA71D, 0xA73D, 0xA71D, 0xA73D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA73D, 0xA73D, 0xA71D, 0xA73D, 0xA73D, 0xA71D, 0xA73E, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xA71D, 0xBBF7, 0xCA13, 0xCA33, 0xCA13, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA13, 0xCA13, 0xCA14, 0xD233, 0xCA33, 0x003F, 0x003F, 0x005F, 0x78D7, 0xC0F2, 0xC8F1, 0xC0D1, 0xC0D1, 0xC0D1, 0xC8B1, 0x4B1A, 0x047F, 0x045F, 0x043F, 0x045F, 0x0735, 0x07F4, 0x07F9, 0x07FE, 0x07FF, 0x2E3C, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0D1, 0xB0D1, 0xA8F1, 0xB0F1, 0xB0D1, 0xB0F1, 0xA0F1, 0x28CF, 0x28EF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x10D1, 0x08F3, 0x10F3, 0x10D2, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x10D3, 0x0119, 0x0119, 0x18CD, 0x18AD, 0x18AD, 0x18AF, 0x011A, 0x0119, 0x00F9, 0x08F6, 0x0119, 0x0119, 0x0119, 0x18AF, 0x20AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x10D3, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xCA13, 0xCA13, 0xCA13, 0x9F1D, 0x9F1D, 0xA71D, 0x9F1D, 0x9F1D, 0xA71D, 0x9F1D, 0x9F1D, 0x8191, 0x8191, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xA5DB, 0x9F1D, 0x9F1D, 0x9EFD, 0x9F1D, 0x9F1D, 0x9F1D, 0xA6FD, 0x9F1D, 0x94F9, 0x8191, 0x9931, 0xB8D1, 0xB8D1, 0xB8B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8B1, 0xA5DB, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0xA6FD, 0x9F1D, 0x9F1D, 0x9F1D, 0x94F9, 0x8191, 0x9931, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB932, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1E, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9E1B, 0x9457, 0x92D4, 0xA1F3, 0xA911, 0xB0F1, 0xB0F1, 0xA911, 0xB274, 0xB254, 0xB254, 0xABF7, 0xA5DB, 0xA6FD, 0xA6FD, 0xA71D, 0xA71D, 0x9F1D, 0x9F1D, 0xA6FD, 0x9F1D, 0x9F1D, 0xA71D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9E7C, 0x9498, 0x8B14, 0x9A13, 0xA131, 0xA912, 0xB0F1, 0xA8F1, 0xB255, 0xB274, 0xB254, 0xAB97, 0xAD1A, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0xA71D, 0x9F1D, 0xA71D, 0x9457, 0x8191, 0xA131, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xA57A, 0x9F1D, 0xA71D, 0x9F1D, 0xA71D, 0x9E7C, 0x9DBA, 0xA59A, 0xA57A, 0xA57A, 0xA57A, 0xA57A, 0xA57A, 0xA57A, 0xA57A, 0xA69C, 0x9F1D, 0x9F1D, 0x9F1D, 0xA71D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9F1D, 0x9E5C, 0x94B8, 0x8AF4, 0x9A13, 0xA131, 0xA8F1, 0xB0F1, 0xB0F1, 0xB932, 0xB274, 0xB254, 0xB336, 0xACB9, 0xA63C, 0x9F1D, 0xBBF7, 0xC9F3, 0xCA13, 0xCA13, 0xCA13, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xCA13, 0xCA13, 0xCA13, 0xCA13, 0xCA13, 0x003F, 0x003F, 0x005F, 0x58B9, 0xC0F1, 0xC0D1, 0xC8D1, 0xC8B2, 0xC0B1, 0xC0B1, 0x62B8, 0x04BF, 0x047F, 0x047F, 0x045F, 0x0715, 0x07F4, 0x07F9, 0x07FD, 0x07FF, 0x2E3C, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0D1, 0xA8F1, 0xA8F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0x58F0, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x0117, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x011A, 0x011A, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x00F6, 0x20AD, 0x20CD, 0x18AE, 0x08F3, 0x0119, 0x00F9, 0x18AE, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x10D4, 0x18AD, 0x18AD, 0x18AD, 0x00F6, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xC9D3, 0xC9D3, 0xC9D3, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x959A, 0x8191, 0x9151, 0xC0B1, 0xB8D1, 0xC0B1, 0xB8D1, 0xC0D1, 0xB8D1, 0xB8D1, 0xB2B5, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x8252, 0x8191, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xC0B1, 0xC0D1, 0xB8D1, 0xC0D1, 0xB1F3, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9F1D, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x8A93, 0x8191, 0xB8D1, 0xB8D1, 0xC0D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xC0B1, 0xA63C, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x94F8, 0x8A53, 0x9171, 0xB0F1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8B1, 0xB8B1, 0xC0B1, 0xC0D1, 0xC0D1, 0xB8D1, 0xC0D1, 0xB8B1, 0xB992, 0xACB9, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9E5C, 0x8B96, 0x8991, 0xA131, 0xB8D1, 0xB8D1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xC0B1, 0xB8D1, 0xB932, 0xABF7, 0x9E9C, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9437, 0x8191, 0xA131, 0xB8D1, 0xC0B1, 0xB8D1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB8D1, 0xA57A, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9437, 0x8191, 0xA131, 0xB8D1, 0xC0B1, 0xB8D1, 0xB8D1, 0xC0B1, 0xB8D1, 0xB8D1, 0xA57A, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9EFD, 0x9E9C, 0x8B96, 0x8971, 0xA131, 0xB8D1, 0xB8D1, 0xC0B1, 0xB8D1, 0xC0B1, 0xC0D1, 0xB8D1, 0xB8D1, 0xC0D1, 0xB8D1, 0xB8D1, 0xC0D1, 0xB335, 0xA63C, 0xBBD7, 0xC9D3, 0xC9F3, 0xC9D3, 0xC9D3, 0xC9D3, 0xC9D3, 0xC9D3, 0xC9D3, 0xC9D3, 0xC9D3, 0xC9D3, 0xC9F3, 0xC9D3, 0xC9D3, 0xC9F3, 0xC9D3, 0x001F, 0x003F, 0x003F, 0x00DF, 0x88F6, 0xC8D1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC8B1, 0x62D9, 0x04FF, 0x04BF, 0x049F, 0x047F, 0x06B6, 0x07F3, 0x07F8, 0x07FD, 0x07FF, 0x2E3C, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0F1, 0x98F2, 0xB0F1, 0xB0F1, 0xB0F1, 0x78F0, 0x90F1, 0x80D1, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x0119, 0x0119, 0x00F7, 0x08F7, 0x0119, 0x011A, 0x08F4, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x08F3, 0x0119, 0x00F6, 0x18AD, 0x18AD, 0x18CD, 0x08F3, 0x0119, 0x08F6, 0x18AD, 0x18AD, 0x18AD, 0x08F7, 0x0119, 0x08F5, 0x18CD, 0x18AD, 0x18AD, 0x08F6, 0x011A, 0x08F6, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0xC9B3, 0xC9B3, 0xC9B3, 0x9EDD, 0x96FD, 0x9EDD, 0x96FD, 0x9EFC, 0x96FD, 0x96FD, 0x9599, 0x8991, 0x9171, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xABD7, 0x9EFC, 0x96FD, 0x96FD, 0x96DD, 0x96FD, 0x9EFD, 0x9EDD, 0x96FD, 0x9EDD, 0x9EFD, 0x8C37, 0x8191, 0xA111, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xAB76, 0x9EDD, 0x9EFD, 0x9EFD, 0x9EDD, 0x9EDD, 0x96DD, 0x9EFD, 0x9EDD, 0x96FD, 0x9EDD, 0x8C37, 0x8191, 0xA131, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0D1, 0xA55A, 0x96FD, 0x9EDD, 0x9EFD, 0x96FD, 0x963B, 0x8AF4, 0x8991, 0xA911, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xB992, 0xA55A, 0x9EDD, 0x9EFC, 0x96FD, 0x9EDD, 0x96FD, 0x9EFD, 0x96FD, 0x96FD, 0x96FD, 0x96FD, 0x96FD, 0x96FD, 0x96FD, 0x96FD, 0x94F9, 0x81F1, 0x9171, 0xB8D2, 0xC0B1, 0xC0D1, 0xC0D1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xB992, 0x9DBB, 0x96FD, 0x9EDD, 0x96FD, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xA55A, 0x9EDD, 0x96FD, 0x96FD, 0x9EFD, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xA55A, 0x96FD, 0x9EFD, 0x96FD, 0x9EFD, 0x9EFD, 0x96FD, 0x9EFD, 0x96FD, 0x9539, 0x81F1, 0x9171, 0xB0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB911, 0xACFA, 0xB458, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9D2, 0xC9D3, 0xC9D3, 0xC9B3, 0x001F, 0x003F, 0x003F, 0x00BF, 0x311C, 0xC0D1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x6278, 0x053F, 0x04FF, 0x04BF, 0x049F, 0x0696, 0x07F2, 0x07F7, 0x07FC, 0x07FF, 0x2E3C, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0F1, 0x8912, 0xB0F1, 0xB0F1, 0xB0D1, 0x48F0, 0x28F0, 0x28EF, 0x28CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x011A, 0x011A, 0x08F3, 0x18AD, 0x18AD, 0x10D3, 0x0119, 0x00F9, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x00F6, 0x18AD, 0x18AD, 0x208D, 0x08F3, 0x0119, 0x00F9, 0x18AE, 0x18AE, 0x18CE, 0x00F9, 0x0119, 0x08F3, 0x18AD, 0x20AE, 0x18AD, 0x08F6, 0x011A, 0x08F3, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18CF, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x10D3, 0x08F3, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xC993, 0xC993, 0xC992, 0x96DC, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x8D79, 0x8191, 0x9151, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xABD7, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xABD7, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x9D5A, 0x96DD, 0x96DD, 0x96DD, 0x95DA, 0x89F2, 0x8971, 0xB8D1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xA499, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DC, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x8C37, 0x8191, 0x9931, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xA499, 0x96DC, 0x96DD, 0x8C37, 0x8191, 0xA111, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x9D5A, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x9D5A, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x96DD, 0x8CD8, 0x8191, 0x9951, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xAC79, 0xACF9, 0xC992, 0xC993, 0xC9B2, 0xC992, 0xC992, 0xC993, 0xC993, 0xC993, 0xC992, 0xC992, 0xC992, 0xC993, 0xC993, 0xC993, 0x003F, 0x003F, 0x003F, 0x00BF, 0x011F, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x79D6, 0x051F, 0x051F, 0x04FF, 0x04BF, 0x0638, 0x07F1, 0x07F7, 0x07FC, 0x07FF, 0x2E3C, 0xB0F1, 0xB0F2, 0xB0F1, 0xB0F1, 0x80F2, 0xB0F1, 0xB0F1, 0xB0F2, 0x3110, 0x30F0, 0x28CF, 0x28EF, 0x20CE, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AF, 0x011A, 0x0119, 0x10D0, 0x18AD, 0x18AD, 0x18D1, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0118, 0x18AE, 0x18AD, 0x18AD, 0x18CE, 0x0119, 0x0119, 0x0118, 0x08F5, 0x00F8, 0x0119, 0x0119, 0x18CF, 0x18AD, 0x18AD, 0x18AD, 0x00F8, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18D0, 0x0119, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18CE, 0x0117, 0x011A, 0x0119, 0x0119, 0x011A, 0x00F7, 0x18CE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x10D2, 0x08F3, 0x10F3, 0x10D2, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xC972, 0xC972, 0xC972, 0x8EBC, 0x8EBD, 0x8EBD, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBD, 0x8D7A, 0x8191, 0x9151, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xABB7, 0x8EBD, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBD, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xABB7, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EDC, 0x8EBC, 0x8EDD, 0x8EBC, 0x8EBC, 0x8EBD, 0x8EBC, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x9D39, 0x8EBD, 0x8EDD, 0x8DBA, 0x81F2, 0x9171, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC8B1, 0xC8B2, 0xC0B1, 0xC8B2, 0xC8B1, 0xC8B1, 0xC0D1, 0xC0B1, 0xC0D1, 0xC0D1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xA437, 0x8EBC, 0x8EDD, 0x8EBC, 0x8EBD, 0x8EBC, 0x8EBC, 0x8EBD, 0x8EBC, 0x8EBD, 0x8EBD, 0x8CD8, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC8B2, 0xC8B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC8B1, 0xA4D9, 0x8EBC, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC8B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0x9D3A, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8C37, 0x8191, 0xA131, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x9D5A, 0x8EBC, 0x8EBC, 0x8EDC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8CD8, 0x8191, 0x9951, 0xC8B1, 0xC0B1, 0xC8B1, 0xC8B2, 0xC8B1, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC8B1, 0xC8B1, 0xC8D1, 0xA478, 0xA4D9, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0xC972, 0x003F, 0x003F, 0x001F, 0x009F, 0x00DF, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x9174, 0x049F, 0x057F, 0x051F, 0x04FF, 0x0619, 0x07F1, 0x07F6, 0x07FC, 0x07FF, 0x35BB, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0F1, 0x6912, 0xB0F1, 0xB0F1, 0x98F1, 0x30F0, 0x30F0, 0x28EF, 0x28CF, 0x28EF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x10D3, 0x20AD, 0x18AD, 0x10D3, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18D0, 0x011A, 0x011A, 0x10D0, 0x18AD, 0x18AD, 0x20AD, 0x10D2, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x18B0, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AF, 0x0119, 0x00F9, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F5, 0x011A, 0x0119, 0x0117, 0x00F7, 0x00F9, 0x0119, 0x08F5, 0x20AD, 0x20AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x011A, 0x00FA, 0x011A, 0x0119, 0x08F7, 0x18CE, 0x18AD, 0x20AD, 0x18AE, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0xC952, 0xC952, 0xC952, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8D59, 0x8191, 0x9171, 0xC8F2, 0xC8F1, 0xC8F2, 0xC8F2, 0xC8F2, 0xC8F1, 0xC8F2, 0xABD7, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8C36, 0x8191, 0xA931, 0xC8F2, 0xC8F1, 0xC8F2, 0xC8F2, 0xC8F2, 0xC8F2, 0xC0F2, 0xABB7, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8437, 0x8191, 0xA951, 0xC8F1, 0xC8F1, 0xC8F2, 0xC8F1, 0xC8F1, 0xC8F2, 0xC8F1, 0x9D3A, 0x8EBC, 0x8E1B, 0x81F2, 0x8971, 0xB912, 0xC8F1, 0xC8F1, 0xC8F2, 0xC8F1, 0xC8F1, 0xC8F1, 0xC8F2, 0xC8D1, 0xC112, 0xC8F2, 0xC8F2, 0xC8F2, 0xC8D1, 0xC8F2, 0xC8D1, 0xC8F2, 0xC0F1, 0xC8F1, 0xC8F2, 0xC8F1, 0xC8F2, 0xC0F1, 0xA498, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8DBA, 0x8991, 0x8991, 0xC0F1, 0xC8F2, 0xC0F2, 0xC8F1, 0xC8F2, 0xC8F1, 0xC0F1, 0xC8F2, 0xC8F1, 0xC8F2, 0xC0F2, 0xC8F1, 0xC0F1, 0xC8F2, 0xC8F1, 0xC8F2, 0xC8F2, 0xC8F2, 0xC8F1, 0xC8F1, 0xC0F2, 0xC132, 0x8E5C, 0x8C17, 0x8191, 0xA931, 0xC8F2, 0xC8F2, 0xC8F2, 0xC8F2, 0xC8F1, 0xC8F2, 0xC8F2, 0x9D59, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8C17, 0x8191, 0xA951, 0xC8F1, 0xC8F1, 0xC8F2, 0xC8F1, 0xC8F1, 0xC8F2, 0xC8F1, 0x9D5A, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBD, 0x8DBA, 0x81F2, 0x8991, 0xC111, 0xC8F1, 0xC8F1, 0xC8F1, 0xC0F2, 0xC8F1, 0xC8F1, 0xC0F2, 0xC8D2, 0xC8F1, 0xC8F2, 0xC0F1, 0xC0F1, 0xC8F2, 0xC0F1, 0xC8F1, 0xC8F2, 0xC8F2, 0xC8F1, 0xC8F1, 0xC8F2, 0xC152, 0x95FB, 0xA4B8, 0xC152, 0xC952, 0xC952, 0xC952, 0xC972, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0x001F, 0x001F, 0x001F, 0x007F, 0x00DF, 0x68B7, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xA8F3, 0x041F, 0x057F, 0x053F, 0x051F, 0x05F9, 0x07F0, 0x07F6, 0x07FC, 0x07FF, 0x5C78, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0F1, 0x5912, 0xB0F1, 0xB0F1, 0x90F1, 0x30F0, 0x30EF, 0x30EF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20AE, 0x20CE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F4, 0x0119, 0x011A, 0x00F7, 0x00F8, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x0117, 0x0119, 0x08F6, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CF, 0x08F3, 0x00F6, 0x08F3, 0x18AF, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x00F6, 0x0119, 0x0118, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18CD, 0x20AD, 0x18AD, 0x10CF, 0x00F9, 0x0119, 0x0117, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0119, 0x0119, 0x08F3, 0x18CD, 0x20AE, 0x10D3, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x08F5, 0x0119, 0x0119, 0x0117, 0x00F7, 0x0119, 0x0119, 0x08F5, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xC932, 0xC932, 0xC932, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8D79, 0x8191, 0x9171, 0xC132, 0xC131, 0xC912, 0xC912, 0xC132, 0xC911, 0xC912, 0xABF7, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x96BC, 0x8C36, 0x8191, 0xA951, 0xC912, 0xC911, 0xC912, 0xC912, 0xC112, 0xC912, 0xC912, 0xABF7, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8EBC, 0x8C36, 0x8191, 0xA951, 0xC912, 0xC912, 0xC912, 0xC911, 0xC911, 0xC912, 0xC912, 0x9D59, 0x8EBC, 0x8AD4, 0x8191, 0xB152, 0xC912, 0xC131, 0xC912, 0xC912, 0xC912, 0xC912, 0xC912, 0xC912, 0xC932, 0xC912, 0xC912, 0xC912, 0xC912, 0xC911, 0xC112, 0xC932, 0xC912, 0xC912, 0xC932, 0xC911, 0xC912, 0xC912, 0xC932, 0xC131, 0x9DBA, 0x8EBC, 0x96BC, 0x8EBC, 0x8EDC, 0x96BB, 0x8EBC, 0x8EDC, 0x82D4, 0x8191, 0xB932, 0xC912, 0xC112, 0xC912, 0xC112, 0xC912, 0xC112, 0xC912, 0xC911, 0xC911, 0xC932, 0xC911, 0xC131, 0xC912, 0xC132, 0xC131, 0xC912, 0xC912, 0xC911, 0xC911, 0xC131, 0xC912, 0xC912, 0xB356, 0x8C36, 0x8191, 0xA151, 0xC912, 0xC912, 0xC912, 0xC912, 0xC912, 0xC912, 0xC112, 0x9D59, 0x8EBC, 0x96BC, 0x8EBC, 0x8EBC, 0x8C37, 0x8191, 0xA951, 0xC912, 0xC912, 0xC912, 0xC911, 0xC911, 0xC912, 0xC912, 0x9D59, 0x8EBC, 0x8EBC, 0x8EBC, 0x96BC, 0x8EBC, 0x82F4, 0x8991, 0xB151, 0xC912, 0xC912, 0xC932, 0xC912, 0xC912, 0xC131, 0xC932, 0xC912, 0xC911, 0xC911, 0xC932, 0xC911, 0xC912, 0xC911, 0xC932, 0xC932, 0xC112, 0xC911, 0xC132, 0xC912, 0xC912, 0xC932, 0xB336, 0x96BC, 0xA4F9, 0xC192, 0xC932, 0xC932, 0xC932, 0xC932, 0xC932, 0xC932, 0xC932, 0xC932, 0xC932, 0xC932, 0x001F, 0x001F, 0x001F, 0x007F, 0x00BF, 0x009F, 0x90B5, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x0B9E, 0x053F, 0x057F, 0x053F, 0x05DA, 0x07EF, 0x07F5, 0x07FB, 0x07FF, 0x5478, 0xB0D1, 0xB0F1, 0xB0F1, 0x9111, 0x5912, 0xA8F1, 0xB0F1, 0x70F1, 0x30F0, 0x28EF, 0x20EF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x011A, 0x0119, 0x10D3, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x10D2, 0x18AE, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x00F8, 0x0119, 0x08F7, 0x18AE, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18D0, 0x0118, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x10D0, 0x20AE, 0x18AD, 0x10D0, 0x0119, 0x0119, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xC912, 0xC912, 0xC912, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDC, 0x9EDB, 0x9EDB, 0x9EDB, 0x9578, 0x8191, 0x9991, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xB417, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9436, 0x8191, 0xA972, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xA518, 0x9EDB, 0x96DB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9436, 0x8191, 0xA171, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xA579, 0x94D8, 0x8191, 0x9991, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC152, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC253, 0xC2B4, 0xB952, 0xC152, 0xC952, 0xC152, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xBAB5, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x9599, 0x8191, 0x91B1, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC1F3, 0xC2B5, 0xB952, 0xC152, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC972, 0xC952, 0xC952, 0xC972, 0xC1B2, 0x9436, 0x8191, 0xA972, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xA579, 0x9EDB, 0x9EDB, 0x9EDB, 0x9EDB, 0x8C36, 0x8991, 0xA171, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xA579, 0x9EDB, 0x9EDC, 0x9EDB, 0x9EDB, 0x9598, 0x8191, 0x9191, 0xC952, 0xC952, 0xC952, 0xC952, 0xC152, 0xC952, 0xC172, 0xC952, 0xC952, 0xC952, 0xC1F3, 0xC2B4, 0xB952, 0xC152, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xC952, 0xA61A, 0x9EDC, 0xA5DA, 0xC172, 0xC912, 0xC911, 0xC911, 0xC912, 0xC912, 0xC111, 0xC912, 0xC912, 0xC912, 0x001F, 0x001F, 0x001F, 0x005F, 0x007F, 0x007F, 0x6098, 0xC0B1, 0xB8B1, 0xC0B1, 0xC0B1, 0x2AFC, 0x04FF, 0x05BF, 0x055F, 0x05FB, 0x07CF, 0x07F4, 0x07FC, 0x07FF, 0x5C79, 0xB0F1, 0xB0F1, 0xB0F1, 0x8112, 0x5912, 0xB0F1, 0xB0F1, 0x68F1, 0x30F0, 0x30EF, 0x30CF, 0x28CF, 0x20CF, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AE, 0x18AD, 0x10D2, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AE, 0x18AD, 0x0119, 0x011A, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x00F6, 0x0119, 0x0119, 0x10D2, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x10D3, 0x0119, 0x0119, 0x08D6, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0x18AD, 0x18AE, 0x18AD, 0x18D0, 0x00F8, 0x0119, 0x00F7, 0x18AE, 0x20AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x00F8, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x18AE, 0x08F3, 0x0119, 0x0119, 0x18AD, 0x20AD, 0x18AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x18D0, 0x18AD, 0x18AD, 0x10D0, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xC8F1, 0xC8F1, 0xC8F2, 0xA6FB, 0xA6FA, 0xA6FA, 0xA6FB, 0xA6FA, 0xA6DA, 0xA6FA, 0x9D98, 0x8191, 0x9191, 0xC972, 0xC992, 0xC992, 0xC972, 0xC992, 0xC992, 0xC992, 0xB436, 0xA6FB, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0x9436, 0x8191, 0xA992, 0xC992, 0xC992, 0xC972, 0xC972, 0xC972, 0xC992, 0xC992, 0xAD98, 0xA6DA, 0xA6DA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0xA6FA, 0x9436, 0x8191, 0xA992, 0xC993, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xAD99, 0x8A32, 0x8991, 0xC192, 0xC992, 0xC992, 0xC972, 0xC992, 0xC992, 0xC973, 0xC992, 0xC992, 0xC992, 0xBC36, 0xA69A, 0xA6FA, 0xA6FA, 0xA69A, 0x9395, 0x8991, 0xB992, 0xC993, 0xC972, 0xC972, 0xC992, 0xC992, 0xC972, 0xC992, 0xC972, 0xC972, 0xAD98, 0xA6DB, 0xA6DA, 0xA6FA, 0xA6FB, 0xA6FA, 0x9395, 0x8191, 0xB192, 0xC992, 0xC992, 0xC992, 0xC993, 0xC972, 0xC972, 0xC992, 0xC972, 0xC233, 0xAD98, 0xA6FA, 0xA6FB, 0xA639, 0x8A93, 0x9992, 0xC192, 0xC972, 0xC992, 0xC992, 0xC992, 0xC972, 0xC992, 0xC972, 0xC972, 0x9A93, 0x8191, 0xA992, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xAD98, 0xA6FA, 0xA6FB, 0xA6FA, 0xA6FA, 0x9436, 0x8191, 0xA992, 0xC993, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xAD98, 0xA6DA, 0xA6DA, 0xA6FA, 0xA6DA, 0x8B95, 0x8191, 0xB192, 0xC972, 0xC992, 0xC972, 0xC992, 0xC992, 0xC972, 0xC992, 0xC972, 0xC294, 0xADF9, 0xA6FA, 0xA6DA, 0xA69A, 0x9334, 0x9191, 0xB992, 0xC992, 0xC993, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xC992, 0xB497, 0xAEFB, 0xAEFB, 0xB5D9, 0xC952, 0xC8F1, 0xC8F2, 0xC0F1, 0xC8F1, 0xC8F1, 0xC8F1, 0xC8F1, 0xC8F1, 0x001F, 0x001F, 0x001F, 0x003F, 0x007F, 0x005F, 0x7897, 0xC0B1, 0xC0D1, 0xC0B1, 0xB8D1, 0x6238, 0x04DF, 0x05BF, 0x059F, 0x05FA, 0x07CE, 0x07F4, 0x07FC, 0x07FF, 0x5C78, 0xB0F1, 0xB0F1, 0xB0F1, 0x7112, 0x5912, 0xB0F1, 0xA8F1, 0x5110, 0x30F0, 0x30CF, 0x28CF, 0x28CF, 0x28CF, 0x20AE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x20AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x08F6, 0x18D0, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x08F6, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18D0, 0x00F8, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x00F8, 0x0119, 0x00F7, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x08F5, 0x0119, 0x0119, 0x00F7, 0x00F7, 0x0119, 0x0119, 0x08F5, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x011A, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F3, 0x18AD, 0x18AD, 0x08F3, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0xC0D1, 0xC0D1, 0xC8D2, 0xB71A, 0xB71A, 0xB71A, 0xAEFA, 0xB71A, 0xAF1A, 0xAEFA, 0xA598, 0x8191, 0x9191, 0xC9B3, 0xC9B3, 0xC9D3, 0xC9D3, 0xC9B2, 0xC9B3, 0xC9D3, 0xBC76, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0x9C55, 0x8191, 0xA9B2, 0xC9D3, 0xC9D3, 0xC9B3, 0xC9B2, 0xC9B3, 0xC9D3, 0xC9D3, 0xB5B8, 0xB71A, 0xAF1A, 0xB71A, 0xB6FA, 0xB71A, 0xB71A, 0xB71A, 0xB71A, 0xB6FA, 0xAF1A, 0x9C56, 0x8191, 0xA992, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xA3B5, 0x8191, 0x9992, 0xC9B2, 0xC9B3, 0xC9D2, 0xC9B2, 0xC9B3, 0xC9B2, 0xC9B3, 0xC9D3, 0xCA13, 0xBDB8, 0xAEFA, 0xAF1A, 0xB71A, 0xB6FA, 0xAEFA, 0xAF19, 0xA4F7, 0x8991, 0xB1B2, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9D2, 0xC9B3, 0xC9B3, 0xC314, 0xAF1A, 0xAF1A, 0xAEF9, 0xAF1A, 0xAF1A, 0x89F1, 0x8191, 0xC1B2, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B2, 0xC9B2, 0xC9D3, 0xC9B3, 0xCAB4, 0xB6B9, 0xAF1A, 0xB71A, 0xAEFA, 0xB71A, 0xB6B9, 0x8A93, 0x8991, 0xC1D2, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B2, 0xC9D3, 0xC9B2, 0xA992, 0x8191, 0xA9B2, 0xC9D3, 0xC9B3, 0xC9D3, 0xC9B2, 0xC9B2, 0xC9B2, 0xC9B3, 0xB5B8, 0xAF1A, 0xAEFA, 0xAF1A, 0xB71A, 0x9C56, 0x8191, 0xA992, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xB5B8, 0xB6FA, 0xAF1A, 0xAF1A, 0xB6FA, 0x89F2, 0x8191, 0xC1B2, 0xC9B3, 0xC9B2, 0xC9D3, 0xC9B3, 0xC9B3, 0xC9B2, 0xC9D3, 0xCAB4, 0xB6B9, 0xAF1A, 0xB71A, 0xB71A, 0xB6FA, 0xB71A, 0x92F3, 0x89B1, 0xC1B2, 0xC9D3, 0xC9B3, 0xC9B3, 0xC9D3, 0xC9D3, 0xC9B3, 0xC9D3, 0xC315, 0xB71A, 0xB71A, 0xB71A, 0xBDD9, 0xC132, 0xC0D1, 0xC8D1, 0xC8D1, 0xC8D1, 0xC8D1, 0xC0D1, 0xC0D1, 0x001F, 0x001F, 0x001F, 0x003F, 0x007F, 0x007F, 0x6878, 0xB8B1, 0xC0B1, 0xC0D1, 0xB8D1, 0x9954, 0x047F, 0x05BF, 0x05BF, 0x061A, 0x07CE, 0x07F2, 0x07FC, 0x07FF, 0x5C78, 0xB0F1, 0xB0F1, 0xB0F1, 0x6112, 0x5912, 0xA8F1, 0xA8F1, 0x60F0, 0x30F0, 0x28EF, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x0119, 0x00F9, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x08F6, 0x0119, 0x0119, 0x0119, 0x0118, 0x00F6, 0x10D3, 0x08F6, 0x0118, 0x0119, 0x0119, 0x0119, 0x08F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x208D, 0x18B0, 0x00F8, 0x0139, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AF, 0x00F8, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00F7, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x08F5, 0x0119, 0x0119, 0x00F7, 0x00F7, 0x0119, 0x0119, 0x08F4, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0xC0B1, 0xC8B1, 0xC0B1, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xA4B5, 0x8191, 0xA1B2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xD1F3, 0xC496, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xA455, 0x8191, 0xA9D2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xBDD8, 0xBF19, 0xBF19, 0xBF19, 0xBF39, 0xBF19, 0xBF19, 0xBF39, 0xBF19, 0xBF39, 0xBF39, 0xA455, 0x8191, 0xA9D2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0x99F2, 0x8991, 0xB1D2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F2, 0xC577, 0xBF19, 0xBF39, 0xBF39, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0x9BF5, 0x8191, 0xB1D2, 0xC9F3, 0xC9F3, 0xD1F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xBE78, 0xBF19, 0xBF19, 0xBF19, 0xB6B9, 0x8191, 0x8991, 0xC9F3, 0xC9F3, 0xC9F2, 0xC9F3, 0xC9F3, 0xC9D3, 0xC9F3, 0xC9F3, 0xBED8, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0xBF39, 0xAD57, 0x8191, 0x99B2, 0xC9F3, 0xC9F2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xB9D3, 0x8191, 0xA9B2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xBDD8, 0xBF19, 0xBF19, 0xBF19, 0xBF19, 0x9C75, 0x8191, 0xA9D2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xBDD8, 0xBF19, 0xBF19, 0xBF19, 0xB6B8, 0x8191, 0x8191, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xBE78, 0xBF19, 0xBF39, 0xBF19, 0xBF39, 0xBF19, 0xBF19, 0xADB7, 0x8191, 0x91B1, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F2, 0xC9F3, 0xC9F3, 0xC9F3, 0xC9F3, 0xC71A, 0xBF1A, 0xC73A, 0xBF3A, 0xC659, 0xC9D3, 0xC0B1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC8B1, 0xC0B1, 0x001F, 0x001F, 0x001F, 0x003F, 0x005F, 0x003F, 0x001F, 0x7076, 0xC0D1, 0xB8D1, 0xB8D1, 0xB8D1, 0x0BFF, 0x05DF, 0x05BF, 0x0639, 0x07CD, 0x07F2, 0x07FC, 0x07FF, 0x63F7, 0xB0F1, 0xB0F1, 0xB0F1, 0x4132, 0x4111, 0xA0F1, 0xB0F1, 0x90F1, 0x30F0, 0x28EF, 0x28CE, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x00F9, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D1, 0x0118, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F8, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x00F8, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18CD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x00F9, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x10D1, 0x08F3, 0x08F3, 0x10D2, 0x18CD, 0x20AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F8, 0x10D0, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CE, 0x00F7, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18CD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AE, 0xC0B1, 0xC0B1, 0xC0B1, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xA475, 0x8991, 0xA9D2, 0xCA13, 0xCA33, 0xCA33, 0xCA34, 0xCA13, 0xCA33, 0xCA33, 0xCCB6, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xA455, 0x8191, 0xA9D2, 0xCA33, 0xCA33, 0xCA13, 0xCA33, 0xCA33, 0xCA33, 0xD213, 0xC5F7, 0xC738, 0xC738, 0xC738, 0xC738, 0xC739, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xA475, 0x8191, 0xA9D2, 0xCA13, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA13, 0xCA33, 0x91B1, 0x8191, 0xCA13, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA13, 0xCA33, 0xCA13, 0xC455, 0xC738, 0xC739, 0xC738, 0xC738, 0xC738, 0xC738, 0xC739, 0xC738, 0xC738, 0xC738, 0x8A52, 0x8991, 0xC213, 0xCA13, 0xCA13, 0xCA13, 0xCA13, 0xCA33, 0xCA13, 0xCA33, 0xCD56, 0xC738, 0xC738, 0xC739, 0xB5D7, 0x8191, 0x91B1, 0xCA13, 0xCA13, 0xCA13, 0xD233, 0xCA33, 0xCA33, 0xCA33, 0xCB55, 0xCF38, 0xC738, 0xC738, 0xC738, 0xC738, 0xC738, 0xC739, 0xC738, 0x8191, 0x8191, 0xCA13, 0xCA13, 0xCA13, 0xCA33, 0xCA13, 0xCA33, 0xD233, 0xCA13, 0x8191, 0xA9D2, 0xCA33, 0xCA33, 0xCA13, 0xCA13, 0xCA33, 0xCA13, 0xCA33, 0xCDF7, 0xC738, 0xC738, 0xC738, 0xC739, 0xA475, 0x8191, 0xA9D2, 0xCA13, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCA13, 0xCA33, 0xC5F7, 0xC738, 0xC738, 0xC738, 0xB5D6, 0x8191, 0x99B2, 0xCA33, 0xCA33, 0xD213, 0xCA33, 0xCA33, 0xCA33, 0xCA33, 0xCB74, 0xC739, 0xC738, 0xC738, 0xC738, 0xC738, 0xC739, 0xC738, 0xC738, 0x8AB2, 0x8191, 0xBA13, 0xCA13, 0xCA13, 0xCA33, 0xCA13, 0xCA33, 0xCA33, 0xCA13, 0xCF39, 0xC739, 0xC759, 0xCF3A, 0xCF39, 0xCED9, 0xC9F3, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x003F, 0x001F, 0x001F, 0x9894, 0xB8D1, 0xB8D1, 0xB8D1, 0x42DA, 0x059F, 0x05FF, 0x0678, 0x07CC, 0x07F1, 0x07FC, 0x07FF, 0x82B5, 0xA8F1, 0xB0F1, 0x98F2, 0x4132, 0x3912, 0x70F1, 0xA8F1, 0xA8F1, 0x50F0, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CF, 0x10D4, 0x08F5, 0x08F6, 0x08F4, 0x08D3, 0x10CF, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x00F9, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x0118, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F8, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x10D2, 0x10D3, 0x08F3, 0x10D2, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0xC0B1, 0xC0B1, 0xC0B1, 0xCF57, 0xD758, 0xD758, 0xCF58, 0xD758, 0xCF58, 0xD758, 0xAC74, 0x8191, 0xA9F2, 0xCA53, 0xD253, 0xCA54, 0xCA53, 0xCA53, 0xCA53, 0xCA54, 0xCCD6, 0xCF58, 0xD758, 0xD758, 0xD758, 0xD758, 0xD758, 0xD758, 0xD758, 0xD758, 0xCF58, 0xAC75, 0x8191, 0xA9F2, 0xCA53, 0xCA53, 0xD253, 0xCA53, 0xCA53, 0xCA53, 0xD254, 0xCE17, 0xCF57, 0xD758, 0xCF58, 0xD758, 0xCF58, 0xD758, 0xD758, 0xCF58, 0xD758, 0xCF58, 0xAC74, 0x8191, 0xA9F2, 0xCA53, 0xCA54, 0xD253, 0xCA53, 0xCA53, 0xCA54, 0xCA53, 0x99D2, 0x89B1, 0xCA53, 0xCA53, 0xCA53, 0xCA53, 0xD253, 0xCA53, 0xCA53, 0xCA54, 0xD6B7, 0xD758, 0xCF58, 0xCF57, 0xCF58, 0xD758, 0xD757, 0xD758, 0xD757, 0xD758, 0xCF58, 0xB535, 0x8191, 0xA1D2, 0xCA53, 0xCA53, 0xCA53, 0xD254, 0xCA73, 0xCA53, 0xCA53, 0xCC95, 0xD758, 0xD758, 0xCF58, 0xBDD6, 0x8191, 0x99D2, 0xCA53, 0xCA53, 0xCA54, 0xCA53, 0xCA53, 0xD254, 0xCA54, 0xD435, 0xD758, 0xD758, 0xCF58, 0xD758, 0xD758, 0xCF57, 0xD738, 0xCF58, 0x9AF3, 0x8991, 0xC213, 0xCA54, 0xCA53, 0xCA53, 0xD253, 0xCA53, 0xCA54, 0xCA73, 0x8191, 0xA9F2, 0xCA53, 0xD253, 0xD253, 0xCA54, 0xD253, 0xCA53, 0xCA54, 0xCE17, 0xCF58, 0xD758, 0xD758, 0xCF58, 0xAC74, 0x8191, 0xA9F2, 0xCA53, 0xCA54, 0xD253, 0xCA53, 0xCA53, 0xCA54, 0xCA53, 0xD617, 0xD758, 0xCF58, 0xCF58, 0xBDD6, 0x8191, 0x91B2, 0xCA53, 0xD254, 0xCA53, 0xCA53, 0xCA54, 0xD253, 0xD253, 0xCCD6, 0xD758, 0xD758, 0xD758, 0xD758, 0xCF57, 0xD757, 0xCF58, 0xD758, 0x9AF3, 0x8191, 0xBA33, 0xCA54, 0xCA53, 0xD253, 0xCA54, 0xCA53, 0xD253, 0xCA53, 0xD758, 0xD758, 0xDF59, 0xD779, 0xD759, 0xD759, 0xD6F9, 0xC1F2, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x001F, 0x001F, 0x001F, 0x003F, 0x001F, 0x001F, 0x001F, 0x001F, 0x183E, 0xB0D2, 0xB8D1, 0xB8D1, 0x9974, 0x059F, 0x061F, 0x0698, 0x07CC, 0x07F0, 0x07FC, 0x07FF, 0x82B5, 0xB0F1, 0xB0F1, 0x88F1, 0x4132, 0x4111, 0x3910, 0x98F1, 0xA8F2, 0x88F1, 0x28EF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x10D0, 0x0118, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x10CF, 0x0118, 0x00F9, 0x08F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x0118, 0x10D0, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0xC0B1, 0xC0B1, 0xC0B1, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xB494, 0x8191, 0xAA12, 0xCA94, 0xCA74, 0xCA94, 0xCA94, 0xCA94, 0xCA94, 0xD294, 0xD4F5, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xB474, 0x8191, 0xAA12, 0xCA94, 0xCA94, 0xD294, 0xCA94, 0xD294, 0xCA94, 0xD294, 0xDE36, 0xDF77, 0xDF77, 0xDF57, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xB494, 0x8191, 0xAA12, 0xCA94, 0xD294, 0xD294, 0xD294, 0xD294, 0xD294, 0xD294, 0x99D2, 0x91D2, 0xD294, 0xCA94, 0xD294, 0xCA94, 0xD294, 0xCA94, 0xCA94, 0xD3D4, 0xDF77, 0xDF77, 0xDF77, 0xDF76, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF57, 0xDF77, 0xDF77, 0x8191, 0x8992, 0xCA94, 0xCA94, 0xCA94, 0xD294, 0xCA94, 0xCA93, 0xCA94, 0xD3D5, 0xDF77, 0xDF77, 0xDF77, 0xC5F5, 0x8191, 0x99D2, 0xCA94, 0xCA94, 0xD273, 0xCA94, 0xD294, 0xCA94, 0xD294, 0xD515, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0x9B12, 0x8191, 0xBA53, 0xCA94, 0xCA94, 0xD294, 0xCA94, 0xCA93, 0xD294, 0xCA94, 0x8191, 0xAA12, 0xD294, 0xD294, 0xD294, 0xCA94, 0xCA94, 0xD294, 0xD294, 0xDE36, 0xDF77, 0xDF77, 0xDF57, 0xDF77, 0xB474, 0x8191, 0xAA12, 0xCA94, 0xD294, 0xD294, 0xD294, 0xD294, 0xD294, 0xD294, 0xDE36, 0xDF77, 0xDF77, 0xDF77, 0xC5F5, 0x8191, 0x99D2, 0xD294, 0xCA94, 0xCA94, 0xD294, 0xCA94, 0xCA94, 0xCA93, 0xD4F5, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0xDF77, 0x9B12, 0x8191, 0xBA53, 0xD294, 0xCA94, 0xCA94, 0xD294, 0xCA94, 0xD294, 0xCA94, 0xDF78, 0xDF78, 0xDF78, 0xDF78, 0xDF78, 0xDF78, 0xE779, 0xDF19, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x385B, 0xB8D1, 0xB8D1, 0xB8D1, 0x2C3C, 0x061F, 0x06B7, 0x07CB, 0x07F0, 0x07FB, 0x07FF, 0xB0F1, 0xB0F1, 0xA8F1, 0x7912, 0x4132, 0x4111, 0x3911, 0x4110, 0xA0F1, 0xA8F1, 0x48EF, 0x28CE, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x18AD, 0x10CF, 0x0118, 0x00F9, 0x08F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x00F9, 0x0119, 0x08F7, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0118, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x208E, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xB8D1, 0xB8D1, 0xC0D1, 0xE776, 0xE796, 0xE797, 0xE797, 0xE796, 0xE796, 0xE796, 0xB494, 0x8191, 0xAA33, 0xD2B4, 0xD2B4, 0xD2B4, 0xCAB4, 0xD2D4, 0xD2B4, 0xD2B4, 0xDD35, 0xE776, 0xE796, 0xE796, 0xE796, 0xE796, 0xE796, 0xE796, 0xE796, 0xE796, 0xE796, 0xB474, 0x8191, 0xAA33, 0xD2D4, 0xD2D4, 0xD2D4, 0xD2B4, 0xD2B4, 0xCAD4, 0xD2D4, 0xE656, 0xEF96, 0xE776, 0xE797, 0xE796, 0xE796, 0xE776, 0xE777, 0xE796, 0xE796, 0xE796, 0xB494, 0x8191, 0xAA33, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0x99D2, 0x99F2, 0xCAB4, 0xD2B4, 0xD2D4, 0xD2B4, 0xD2B4, 0xCAD4, 0xD2B4, 0xD3F5, 0xE777, 0xE797, 0xEF97, 0xE796, 0xE796, 0xE776, 0xE777, 0xE796, 0xE796, 0xE796, 0xE777, 0xEF97, 0x8191, 0x8191, 0xD2B4, 0xD2B4, 0xD2D4, 0xD2D4, 0xD2B4, 0xD2B4, 0xCAD4, 0xD3D5, 0xE796, 0xE796, 0xE796, 0xCE15, 0x8191, 0x99F2, 0xCAD4, 0xD2B4, 0xD2D4, 0xD2B4, 0xD2B4, 0xCAB4, 0xD2B4, 0xDD35, 0xE777, 0xEF76, 0xE796, 0xE797, 0xE797, 0xE776, 0xE796, 0xE776, 0xC534, 0xB494, 0xCC15, 0xD3F5, 0xDBF4, 0xDBF4, 0xDBF5, 0xD3F5, 0xD3F4, 0xCB34, 0x8191, 0xAA32, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2D4, 0xD2B4, 0xCAB4, 0xE656, 0xE776, 0xE796, 0xE796, 0xE776, 0xB494, 0x8191, 0xAA33, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xDE56, 0xE796, 0xE796, 0xE796, 0xCE15, 0x8191, 0x99F2, 0xD2B4, 0xD2B4, 0xD2D4, 0xD2B4, 0xD2D4, 0xCAD4, 0xCAD4, 0xDD15, 0xE796, 0xE796, 0xE776, 0xE796, 0xEF96, 0xE796, 0xE796, 0xE796, 0x9B13, 0x8191, 0xBA73, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xD2B4, 0xE797, 0xEF97, 0xEF77, 0xEF97, 0xEF78, 0xEF98, 0xEF98, 0xEF98, 0xC992, 0xB8D1, 0xC0D1, 0xC0B1, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x7096, 0xB8D1, 0xB8D1, 0x8A35, 0x063F, 0x06D6, 0x07EA, 0x07F1, 0x07FC, 0x07FF, 0xA8F1, 0xA8F1, 0xA8F1, 0x6132, 0x4132, 0x4111, 0x38F1, 0x3110, 0x48F0, 0xA8F1, 0x98F1, 0x30CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x20AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10D0, 0x00F9, 0x0119, 0x08F7, 0x18AE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18CF, 0x00F8, 0x0119, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x0118, 0x18D0, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xB8D1, 0xB8D1, 0xB8D1, 0xF796, 0xF7B6, 0xF796, 0xF795, 0xF795, 0xF796, 0xEFB6, 0xBC93, 0x8191, 0xAA52, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2F5, 0xD2F5, 0xD2F4, 0xDD55, 0xF7B6, 0xF7B6, 0xF7B6, 0xF7B6, 0xF7B6, 0xF7B6, 0xF7B6, 0xF7B6, 0xF7B6, 0xEFB6, 0xBC93, 0x8191, 0xAA53, 0xD2F5, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xE675, 0xF796, 0xF795, 0xF796, 0xF796, 0xF796, 0xF7B6, 0xF7B5, 0xF7B5, 0xEF96, 0xF796, 0xBC93, 0x8191, 0xAA33, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0x99F2, 0x99F2, 0xD2F5, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2D4, 0xD2F4, 0xD2F4, 0xDC75, 0xF795, 0xF795, 0xF795, 0xF796, 0xF7B5, 0xF796, 0xF796, 0xF796, 0xF796, 0xEFB6, 0xF7B5, 0xF796, 0x8191, 0x8991, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xDC15, 0xF796, 0xF796, 0xF796, 0xD615, 0x8191, 0x99F2, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F5, 0xD2F4, 0xD2F5, 0xE535, 0xF7B6, 0xF7B5, 0xF796, 0xEFB6, 0xF796, 0xF795, 0xF7B6, 0xF796, 0xF7B6, 0xF795, 0xF796, 0xF796, 0xF795, 0xF7B6, 0xF795, 0xF7B6, 0xF796, 0xBC93, 0x8191, 0xAA53, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xEE75, 0xF796, 0xF796, 0xF7B5, 0xF796, 0xBC93, 0x8191, 0xAA33, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xEE75, 0xF796, 0xF7B5, 0xF795, 0xD634, 0x8191, 0x99F2, 0xD2F4, 0xD2F5, 0xD2F4, 0xD2F5, 0xD2F5, 0xD2F5, 0xD2D4, 0xE555, 0xF796, 0xF7B5, 0xF7B6, 0xF7B6, 0xF795, 0xF7B6, 0xF796, 0xF7B6, 0xA311, 0x8191, 0xBA94, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xD2F4, 0xF796, 0xF796, 0xF797, 0xF797, 0xF797, 0xF7B7, 0xF798, 0xF798, 0xD273, 0xB8D1, 0xB8D1, 0xB8D1, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x98B4, 0xB8D1, 0xB8D1, 0x3C9B, 0x06F5, 0x07E9, 0x07F1, 0x07FD, 0x26BD, 0xB0F1, 0xB0F2, 0xB0F1, 0x4932, 0x4132, 0x4111, 0x3911, 0x3110, 0x30F0, 0x60F0, 0xA911, 0x70F0, 0x20CE, 0x20CF, 0x20AE, 0x20CE, 0x20AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18CF, 0x00F8, 0x0119, 0x0117, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x00F8, 0x0119, 0x00F7, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x18AD, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x0118, 0x18D0, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xB8D1, 0xB8D1, 0xB8D1, 0xFF94, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB4, 0xFFB5, 0xC493, 0x8191, 0xAA53, 0xD315, 0xD335, 0xD335, 0xD335, 0xD334, 0xD315, 0xD335, 0xE575, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xC493, 0x8191, 0xAA53, 0xD335, 0xD335, 0xD314, 0xD315, 0xD335, 0xD335, 0xD335, 0xF675, 0xFFB5, 0xFFB4, 0xFFB5, 0xFFB5, 0xFFB4, 0xFFB4, 0xFFB4, 0xFFB5, 0xFFB5, 0xFF95, 0xC493, 0x8191, 0xAA53, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xD315, 0xD335, 0x99F2, 0x99F2, 0xD335, 0xD314, 0xD315, 0xD335, 0xD335, 0xD315, 0xD335, 0xDC54, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB4, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB4, 0xFFB5, 0x8191, 0x8191, 0xD334, 0xD315, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xDC34, 0xFFB4, 0xFFB5, 0xFFB5, 0xDE34, 0x8191, 0x99F2, 0xD314, 0xD335, 0xD315, 0xD334, 0xD334, 0xD335, 0xD335, 0xE574, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB4, 0xFFB4, 0xFFB5, 0xFFB4, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB4, 0xFFB5, 0xFFB5, 0xC4B3, 0x8191, 0xAA53, 0xD335, 0xD335, 0xD314, 0xD315, 0xD335, 0xD335, 0xD335, 0xEDF5, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xC493, 0x8191, 0xAA53, 0xD335, 0xD335, 0xD335, 0xD335, 0xD315, 0xD315, 0xD335, 0xF694, 0xFFB5, 0xFFB5, 0xFFB5, 0xDE14, 0x8191, 0x99F2, 0xD335, 0xD335, 0xD314, 0xD334, 0xD314, 0xD334, 0xD315, 0xE555, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB4, 0xFFB5, 0xFFB5, 0xFFB5, 0xFFB5, 0xA332, 0x8191, 0xBAB4, 0xD335, 0xD335, 0xD335, 0xD315, 0xD334, 0xD335, 0xD335, 0xFFB5, 0xFFB6, 0xFFB6, 0xFFB6, 0xFFB6, 0xFFB6, 0xFFB7, 0xFFB8, 0xDBD4, 0xB8D2, 0xB8D1, 0xB8D1, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x083F, 0x70F7, 0xB8D1, 0xA952, 0x0E94, 0x07C9, 0x07F2, 0x07FD, 0x2E3C, 0xA8F1, 0xA8F1, 0x9911, 0x4132, 0x4132, 0x3911, 0x3910, 0x30F0, 0x30F0, 0x30EF, 0x58F0, 0xA8F1, 0x40CF, 0x20AE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18B0, 0x00F8, 0x0119, 0x00F7, 0x18AE, 0x18CD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x18CF, 0x00F8, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x00F7, 0x00F9, 0x0118, 0x18CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xB8D1, 0xB8D1, 0xB8D1, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE4E, 0xFE4E, 0xC3F0, 0x8191, 0xAA73, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xECD1, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xC3EF, 0x8191, 0xAA73, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD354, 0xF590, 0xFE4E, 0xFE4E, 0xFE2E, 0xFE2E, 0xFE4E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xC3EF, 0x8191, 0xAA73, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0x9A12, 0x91F2, 0xD355, 0xD354, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xDBD4, 0xFE4E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE4E, 0xFE2E, 0xFE4E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE4E, 0x8191, 0x8191, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xDC13, 0xFE4E, 0xFE2E, 0xFE2E, 0xE50F, 0x8191, 0x99F2, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD354, 0xECD1, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE4E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE2E, 0xFE4E, 0xFE4E, 0xFE2E, 0xFE2E, 0xC3CF, 0x8191, 0xAA73, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xE4D1, 0xFE4E, 0xFE2E, 0xFE2E, 0xFE4E, 0xC3D0, 0x8191, 0xAA73, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xF590, 0xFE4E, 0xFE2E, 0xFE2E, 0xE50F, 0x8191, 0x9A12, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xECD2, 0xFE2E, 0xFE4E, 0xFE2E, 0xFE4E, 0xFE4E, 0xFE4E, 0xFE4D, 0xFE2F, 0xA2B0, 0x8191, 0xC2F4, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xD355, 0xFE2F, 0xFE50, 0xFE50, 0xFE50, 0xFE51, 0xFE51, 0xFE52, 0xFE52, 0xE3D2, 0xB8D2, 0xB8D1, 0xB8D1, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x001F, 0x003F, 0x00DF, 0x59F8, 0xB8D1, 0x8291, 0x07C9, 0x07F2, 0x07FE, 0x455A, 0xB0F1, 0xA8F1, 0x8112, 0x4132, 0x4132, 0x3911, 0x38F0, 0x30F0, 0x30EF, 0x28EF, 0x28CF, 0x50CF, 0x48EF, 0x20AE, 0x20AE, 0x20CE, 0x20AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AF, 0x00F8, 0x0139, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AF, 0x0118, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00F7, 0x0119, 0x00F8, 0x10CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0xB8D1, 0xB0D1, 0xB0D2, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC6D, 0xC30F, 0x81B1, 0xAA73, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD375, 0xEC11, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC8D, 0xC30F, 0x8191, 0xAA93, 0xD375, 0xD375, 0xD395, 0xD395, 0xD375, 0xD395, 0xD396, 0xF42F, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC8D, 0xC30F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD395, 0x9A12, 0x8191, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xF44F, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC8D, 0xFC6D, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD396, 0xDBD3, 0xFC8D, 0xFC6D, 0xFC6D, 0xE3CE, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD376, 0xD395, 0xD395, 0xD395, 0xEC11, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC6D, 0xFC8D, 0xC30F, 0x8191, 0xAA93, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEBF1, 0xFC8D, 0xFC6D, 0xFC8D, 0xFC6D, 0xC30F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD375, 0xD395, 0xF42F, 0xFC6D, 0xFC6D, 0xFC8D, 0xE3CE, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD375, 0xD395, 0xD376, 0xD395, 0xD395, 0xEBF1, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC8D, 0xFC6D, 0xFC6D, 0xFC6D, 0xFC8D, 0xA250, 0x8191, 0xC314, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xFC8E, 0xFC8F, 0xFC8F, 0xFC8F, 0xFCB0, 0xFCB0, 0xFCB1, 0xFCB1, 0xF3B2, 0xB8D1, 0xB0F1, 0xB8D1, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x003F, 0x005F, 0x031F, 0x2D3B, 0x99B2, 0x454B, 0x07F3, 0x07FE, 0x5498, 0xB0F1, 0xA8F1, 0x6912, 0x4912, 0x4112, 0x3911, 0x3110, 0x30F0, 0x30EF, 0x30CF, 0x28CF, 0x20CE, 0x20CE, 0x20CE, 0x20CD, 0x20CE, 0x20AE, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18CD, 0x10D1, 0x08F3, 0x08D3, 0x10D1, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x00F8, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F6, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x00F7, 0x0119, 0x00F8, 0x18CF, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xB0F1, 0xB0F1, 0xB0D1, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xC30F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC11, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xC30F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF44F, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xC30F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0x9A12, 0x8191, 0xC334, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDBB4, 0xFC8E, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xDBD3, 0xFC8D, 0xFC8D, 0xFC8D, 0xE3CE, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC11, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xCB2F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xEC11, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xC30F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF44F, 0xFC8D, 0xFC8D, 0xFC8D, 0xCB6F, 0x8191, 0x9A32, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC11, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xFC8D, 0xA250, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFC8E, 0xFC8F, 0xFCAF, 0xFCAF, 0xFCB0, 0xFCB0, 0xFCB0, 0xFCB2, 0xF451, 0xB0D1, 0xB0D1, 0xB0D1, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x003F, 0x003F, 0x005F, 0x025F, 0x06FD, 0x0770, 0x0F88, 0x07F4, 0x07FF, 0x5478, 0xA8F1, 0xA8F1, 0x5932, 0x4132, 0x4111, 0x3911, 0x3911, 0x30F0, 0x30F0, 0x30EF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F9, 0x0119, 0x0119, 0x00F7, 0x18AE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CF, 0x0118, 0x0119, 0x00F7, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x00F9, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0118, 0x0119, 0x00F6, 0x18CE, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F7, 0x0119, 0x00F8, 0x18CF, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xB0F1, 0xB0F1, 0xB0D1, 0xFCAD, 0xFCCD, 0xFCAD, 0xFCAD, 0xFCCD, 0xFCCD, 0xFCCD, 0xCB4E, 0x8191, 0xAA73, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC31, 0xFCAD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xC32F, 0x8991, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF46F, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCAD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCAD, 0xFCAD, 0xFCAD, 0xC32F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xBB11, 0x8191, 0xAA73, 0xD396, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xDBB4, 0xFCAE, 0xFCAD, 0xFCCD, 0xFCAD, 0xFCCD, 0xFCAD, 0xFCCD, 0xFCCD, 0xFCAD, 0xFCAD, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xDBD3, 0xFCAD, 0xFCCD, 0xFCCD, 0xDBEE, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC31, 0xFCCD, 0xFCAD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCAD, 0xFCCD, 0xFCAD, 0xFCCD, 0xDBEE, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDBD3, 0xFCCD, 0xFCCD, 0xFCCD, 0xFCCD, 0xC32F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF46F, 0xFCAD, 0xFCCD, 0xFCCD, 0xC32F, 0x8991, 0xAA94, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC31, 0xFCCD, 0xFCCD, 0xFCAD, 0xFCCD, 0xFCAD, 0xFCAD, 0xFCAD, 0xFCAD, 0xA270, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFCCE, 0xFCCF, 0xFCCF, 0xFCEF, 0xFCD0, 0xFCF0, 0xFCF1, 0xFCF1, 0xFCF2, 0xB0F1, 0xB0F1, 0xB0F2, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x003F, 0x005F, 0x007F, 0x021F, 0x06FC, 0x078D, 0x07E7, 0x07F6, 0x07FF, 0x82B5, 0xA8F1, 0xA111, 0x4932, 0x4132, 0x4111, 0x38F1, 0x38F0, 0x30F0, 0x30EF, 0x30EF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CE, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x20AD, 0x08F5, 0x0119, 0x0119, 0x0117, 0x0117, 0x0119, 0x0119, 0x08F4, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x10CF, 0x0118, 0x0119, 0x0117, 0x18AE, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AE, 0x00F6, 0x0119, 0x0118, 0x18CF, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xB0F1, 0xA8F1, 0xB0F1, 0xFD0D, 0xFCED, 0xFCED, 0xFCED, 0xFD0D, 0xFCED, 0xFD0D, 0xE42E, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC51, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xC34F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF48F, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xC32F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC6F, 0x91D1, 0x89D1, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xDBB4, 0xEC70, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFD0D, 0xFCED, 0xFCED, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDBF3, 0xFCED, 0xFCED, 0xFCED, 0xE42E, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC51, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFD0D, 0xFCED, 0xEC6E, 0x8191, 0x91F2, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD376, 0xD395, 0xD395, 0xF4AF, 0xFD0D, 0xFCED, 0xFD0D, 0xC34F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF48F, 0xFCED, 0xFCED, 0xFCED, 0xC34F, 0x8191, 0xAA93, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC51, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xFCED, 0xA270, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFD0E, 0xFD0F, 0xFD0F, 0xFD0F, 0xFD10, 0xFD10, 0xFD31, 0xFD31, 0xFD32, 0xB0F1, 0xB0F1, 0xB0F1, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x005F, 0x005F, 0x005F, 0x021F, 0x073B, 0x07AC, 0x07E7, 0x07F7, 0x07FF, 0x82B5, 0xA8F1, 0x8912, 0x4932, 0x4112, 0x3911, 0x3911, 0x3110, 0x30F0, 0x30EF, 0x28CF, 0x28CF, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AE, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x10F3, 0x18AD, 0x18AD, 0x10F3, 0x0119, 0x0119, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x0117, 0x0119, 0x00F7, 0x18AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x208D, 0x18AD, 0x20AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18CD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F6, 0x0119, 0x0118, 0x10CF, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xB0F1, 0xA8F1, 0xB0F1, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xE44E, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC71, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xC34F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF4CF, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xC34F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF4CF, 0xC34F, 0x8191, 0xB2D4, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDBD4, 0xE431, 0xEC71, 0xEC71, 0xDBF0, 0xE450, 0xF4CF, 0xFD0E, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDBD4, 0xF4AF, 0xF4CF, 0xF4AF, 0xDC10, 0x9A12, 0xAA73, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC71, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2C, 0xFD2C, 0x9211, 0x8191, 0xD375, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC71, 0xFCEE, 0xFD2D, 0xC36F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDC10, 0xE44E, 0xDC2E, 0xE44E, 0xB2F0, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC71, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xFD2D, 0xA270, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFD2E, 0xFD2F, 0xFD2F, 0xFD4F, 0xFD50, 0xFD50, 0xFD51, 0xFD51, 0xFD71, 0xA8F1, 0xB0F1, 0xB0F2, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x005F, 0x005F, 0x007F, 0x007F, 0x023F, 0x073B, 0x07AB, 0x07E8, 0x07F9, 0x07FF, 0xA152, 0xA8F1, 0x7132, 0x4132, 0x4131, 0x3911, 0x3910, 0x38F0, 0x30F0, 0x30EF, 0x28CF, 0x28CE, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18CE, 0x0119, 0x0119, 0x10D0, 0x18AD, 0x18AD, 0x18D0, 0x0119, 0x0119, 0x0119, 0x0118, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x08F7, 0x18AD, 0x20AD, 0x18AD, 0x20CD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AC, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F6, 0x0119, 0x0118, 0x18CF, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xA8F1, 0xA8F1, 0xA8F2, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD4D, 0xFD6D, 0xFD6D, 0xE46E, 0x8191, 0x9212, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC71, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xC36F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF4EF, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xC36F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF4EF, 0xFD2D, 0x9211, 0x89B2, 0xCB75, 0xD396, 0xD375, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC91, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xCB95, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC71, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD4D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xBB2F, 0x8191, 0xB2D4, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xC314, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC71, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xFD6D, 0xA290, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFD6E, 0xFD6F, 0xFD6F, 0xFD8F, 0xFD90, 0xFD90, 0xFD91, 0xFD91, 0xFD92, 0xA8F1, 0xA8F1, 0xA8F1, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x003F, 0x005F, 0x005F, 0x007F, 0x009F, 0x023F, 0x0779, 0x07AA, 0x07E8, 0x07FB, 0x07FF, 0xA8F1, 0xA8F1, 0x5932, 0x4932, 0x4131, 0x3911, 0x3910, 0x38F0, 0x30EF, 0x30EF, 0x28CF, 0x28CE, 0x28CE, 0x20CE, 0x20CE, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AC, 0x0119, 0x0119, 0x10D3, 0x18AD, 0x18AD, 0x10D3, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x00F6, 0x20AE, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x0116, 0x0119, 0x0118, 0x18CF, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0xA8F1, 0xA8F1, 0xA8F1, 0xEC6F, 0xFD8D, 0xFDAD, 0xFD8D, 0xFDAD, 0xFDAD, 0xFDAD, 0xE48E, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC91, 0xFDAD, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xC38F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF52F, 0xFDAD, 0xFD8D, 0xFDAD, 0xFD8D, 0xFD8D, 0xFDAD, 0xFD8D, 0xFD8D, 0xFDAD, 0xFDAD, 0xC38F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF52F, 0xFD8D, 0xE4AE, 0x8991, 0x9A32, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xE491, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC91, 0xFDAD, 0xFDAD, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFD8D, 0xFDAD, 0xFDAD, 0xFD8D, 0xFD8D, 0xFDAD, 0xFDAD, 0xFD8D, 0xFDAD, 0xF52D, 0x8191, 0x91F2, 0xD395, 0xD395, 0xD395, 0xD395, 0xD376, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xC314, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xEC91, 0xFD8D, 0xFD8D, 0xFDAD, 0xFDAD, 0xFDAD, 0xFDAD, 0xFDAD, 0xFD8D, 0xA290, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFDAF, 0xFDAF, 0xFDAF, 0xFDAF, 0xFDB0, 0xFDB0, 0xFDB1, 0xFDD1, 0xE4B2, 0xA911, 0xA8F1, 0xA8F1, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x005F, 0x005F, 0x007F, 0x007F, 0x009F, 0x02BF, 0x0778, 0x07C8, 0x07E9, 0x07FD, 0x173E, 0xA8F1, 0x9912, 0x4932, 0x4932, 0x4131, 0x4111, 0x3911, 0x38F0, 0x30EF, 0x30EF, 0x28CF, 0x28CE, 0x28CE, 0x20CE, 0x20CE, 0x20CD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x08F4, 0x0119, 0x0119, 0x00F7, 0x08F6, 0x0119, 0x0119, 0x08F4, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x00F7, 0x0119, 0x0118, 0x18CF, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18CD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xA911, 0xA911, 0xA911, 0xEC8E, 0xFDED, 0xFDED, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDED, 0xE4CE, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECB1, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xC3AF, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF54F, 0xFDCD, 0xFDCD, 0xFDED, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDED, 0xFDCD, 0xC3AF, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF54F, 0xFDED, 0xFDCD, 0xD44F, 0x8191, 0xB2B3, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xECB1, 0x8991, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECB1, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xFDCD, 0xBB6F, 0x8191, 0xBAF4, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xC314, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECB1, 0xFDED, 0xFDED, 0xFDCD, 0xFDCD, 0xFDED, 0xFDED, 0xFDED, 0xFDED, 0xA2B0, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xFDEE, 0xFDEF, 0xFDEF, 0xFDF0, 0xFDF0, 0xFDF0, 0xFDF1, 0xFDF1, 0xECB1, 0xA0F1, 0xA911, 0xA911, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x005F, 0x005F, 0x005F, 0x007F, 0x009F, 0x009F, 0x041F, 0x0797, 0x07C7, 0x07EB, 0x07FE, 0x2E5C, 0xA8F1, 0x7932, 0x4932, 0x4932, 0x4111, 0x3911, 0x3910, 0x38F0, 0x30EF, 0x30EF, 0x28CE, 0x28CE, 0x28CE, 0x20CE, 0x20CE, 0x20CD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AE, 0x00F6, 0x0118, 0x0118, 0x0119, 0x0119, 0x00F6, 0x18CE, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AC, 0x18AD, 0x18AC, 0x20AD, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x20AD, 0x18AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00F7, 0x0118, 0x0117, 0x18CF, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0xA911, 0xA911, 0xA111, 0xE42E, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xE4EE, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECD1, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xC3CF, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF56F, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xC3CF, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF56F, 0xFE0D, 0xFE0D, 0xFE0D, 0xD44F, 0x8191, 0xBAD3, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD376, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xECD1, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECD1, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0D, 0xF5AD, 0x9A70, 0x89B1, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xC314, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECD1, 0xFE0D, 0xFE0D, 0xFE0D, 0xFE0E, 0xFE0D, 0xFE0E, 0xFE0E, 0xFE0E, 0xA2B0, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFE0F, 0xFE0F, 0xFE0F, 0xFE30, 0xFE30, 0xFE30, 0xFE31, 0xFE31, 0xDC32, 0xA111, 0xA911, 0xA111, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x005F, 0x005F, 0x007F, 0x007F, 0x009F, 0x00BF, 0x043F, 0x0794, 0x07E6, 0x07EC, 0x07FE, 0x35DB, 0xA911, 0x5133, 0x4932, 0x4132, 0x4111, 0x4111, 0x3910, 0x30F0, 0x30EF, 0x30EF, 0x28CE, 0x28CE, 0x20CE, 0x20CE, 0x20CE, 0x20CD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x20AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0119, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x10D1, 0x10D3, 0x10F2, 0x10D1, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x20AD, 0x18AD, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x18AE, 0x00F6, 0x0119, 0x00F8, 0x18CF, 0x20AD, 0x18AD, 0x20AD, 0x18AC, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x80F0, 0xA111, 0xA111, 0xC2B0, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xE50E, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECF1, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xC3EF, 0x8991, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xF58F, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xC3EF, 0x8191, 0xAA93, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF58F, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xE50E, 0x89D1, 0xA253, 0xCB75, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD376, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECF1, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECF1, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xF60E, 0x9A70, 0x91F2, 0xCB75, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xC314, 0x8191, 0xAA93, 0xD395, 0xD396, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECF2, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4E, 0xFE4D, 0xFE4E, 0xFE4D, 0xFE4E, 0xA2D0, 0x8191, 0xC314, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFE4E, 0xFE4F, 0xFE6F, 0xFE70, 0xFE50, 0xFE50, 0xFE71, 0xFE51, 0xBA52, 0xA111, 0xA111, 0x78D5, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x005F, 0x007F, 0x007F, 0x009F, 0x00BF, 0x00BF, 0x043F, 0x07B3, 0x07C5, 0x07EE, 0x07FF, 0x5478, 0x6AD6, 0x4953, 0x4932, 0x4912, 0x4111, 0x3911, 0x3910, 0x30F0, 0x30EF, 0x28CF, 0x28CE, 0x28CE, 0x28CE, 0x20CE, 0x20CD, 0x20CD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0118, 0x0118, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0118, 0x0119, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AC, 0x18AD, 0x20AD, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x18AD, 0x00F6, 0x0118, 0x00F8, 0x18CF, 0x18AC, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18AC, 0x60EF, 0xA111, 0xA111, 0xA112, 0xFE2D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xE54E, 0x8191, 0x9A12, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xED11, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE8D, 0xC40F, 0x8191, 0xAA93, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xF5CF, 0xFE6D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE6D, 0xC40F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF5CE, 0xFE6D, 0xFE6D, 0xFE8D, 0xFE6C, 0xFE8D, 0xF62D, 0xC40F, 0x9A12, 0xB2D4, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xECF1, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xED11, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE8D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6C, 0xFE8D, 0xFE6D, 0xFE2D, 0xBBCF, 0x89B1, 0xBAF4, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD396, 0xC314, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xED12, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xA2D0, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE90, 0xFE90, 0xFE90, 0xFE91, 0xE471, 0xA111, 0xA112, 0xA111, 0x60D5, 0x001F, 0x283C, 0x7097, 0x405A, 0x001F, 0x001F, 0x001F, 0x003F, 0x007F, 0x009F, 0x00BF, 0x00BF, 0x00DF, 0x045F, 0x07D2, 0x07E4, 0x07EF, 0x07FF, 0x2E3C, 0x2D1A, 0x5133, 0x4932, 0x4132, 0x3911, 0x3911, 0x38F0, 0x30F0, 0x30EF, 0x28CF, 0x28CE, 0x28CE, 0x20CE, 0x20CE, 0x20CD, 0x20CD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0118, 0x0118, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x18AD, 0x20AD, 0x18AC, 0x0119, 0x0118, 0x18AD, 0x18AC, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18CC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x18AE, 0x18AD, 0x20AD, 0x18AC, 0x18AD, 0x18AD, 0x18AC, 0x20AD, 0x18AD, 0x20AD, 0x18CD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x00F6, 0x0118, 0x00F7, 0x18CF, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x20AD, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x28CD, 0xA111, 0xA111, 0xA111, 0xCBCF, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xF5ED, 0x89D1, 0x91D2, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD396, 0xD395, 0xED11, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xC42F, 0x81B1, 0xAA93, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xF5EF, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFECC, 0xFEAD, 0xC42F, 0x8191, 0xAA93, 0xD395, 0xD395, 0xD396, 0xD395, 0xD395, 0xD395, 0xD395, 0xF5EF, 0xFEAD, 0xFEAC, 0xFEAD, 0xFEAD, 0xFEAC, 0xFEAD, 0xFEAD, 0xF64D, 0xD4CE, 0xBBD0, 0xC3B2, 0xC314, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xED12, 0x8191, 0x8191, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xD395, 0xD395, 0xED31, 0xFEAC, 0xFEAC, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xEE0D, 0xCC6F, 0xBB51, 0xBAD4, 0xCB55, 0xD395, 0xD395, 0xD395, 0xD395, 0xC334, 0x8191, 0xB294, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD375, 0xD395, 0xED11, 0xFEAE, 0xFECE, 0xFEAD, 0xFEAE, 0xFEAD, 0xFECE, 0xFEAE, 0xFEAE, 0xA2F0, 0x8191, 0xC314, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xD395, 0xDC34, 0xFEAF, 0xFED0, 0xFEAF, 0xFED0, 0xFEB0, 0xFED1, 0xE491, 0xA911, 0xA111, 0x9931, 0xA111, 0x58D6, 0x88B5, 0xB8D1, 0xB8D1, 0x5059, 0x001F, 0x001F, 0x001F, 0x001F, 0x007F, 0x009F, 0x00BF, 0x00FF, 0x00DF, 0x047F, 0x07D2, 0x07E3, 0x07F1, 0x07FF, 0x07FF, 0x2CBA, 0x4933, 0x4132, 0x4131, 0x4111, 0x38F0, 0x38F0, 0x30F0, 0x30EF, 0x28EF, 0x28CE, 0x28CE, 0x20CE, 0x20CD, 0x20CD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x0118, 0x0118, 0x18AD, 0x18AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x0118, 0x0118, 0x18AD, 0x18AD, 0x18AD, 0x20AD, 0x18CD, 0x20AD, 0x20AD, 0x18AC, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x00F6, 0x18AD, 0x18AD, 0x18AC, 0x20AC, 0x18AC, 0x18AD, 0x18AC, 0x18AC, 0x18AD, 0x18AC, 0x20AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AC, 0x18AC, 0x18AD, 0x00F6, 0x0118, 0x0118, 0x18CF, 0x20AD, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x20AC, 0x20AD, 0x18AD, 0x8110, 0x9911, 0xA111, 0xA171, 0xF5ED, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAC, 0xFE6D, 0xF5CF, 0xF5EF, 0xF5CF, 0xF5CF, 0xF5EF, 0xF5CF, 0xFE4D, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFE4E, 0xF5EF, 0xF5EF, 0xF5CF, 0xF5EE, 0xF5EF, 0xF5EF, 0xF5EF, 0xFE8D, 0xFEAC, 0xFEAC, 0xFEAC, 0xFEAC, 0xFEAD, 0xFE8D, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAC, 0xFEAC, 0xFEAD, 0xF64D, 0xF5EF, 0xF5CF, 0xF5EF, 0xF5CF, 0xF5EF, 0xF5EF, 0xF5EF, 0xFE6E, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAC, 0xFEAC, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAC, 0xFEAD, 0xFEAD, 0xF60E, 0xF5EF, 0xF5CF, 0xF5EF, 0xF5EF, 0xF5CF, 0xF64E, 0xFEAC, 0xFEAD, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5CF, 0xF5EF, 0xF5EF, 0xF5EF, 0xF5CF, 0xFE4D, 0xFEAC, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAC, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAC, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFE6D, 0xF5EF, 0xF5EF, 0xF5CF, 0xF5CF, 0xFEAD, 0xF62E, 0xF5EF, 0xF5D0, 0xF5EF, 0xF5CF, 0xF5F0, 0xF5F0, 0xF5EF, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5EF, 0xF5F0, 0xFE4F, 0xFECE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAF, 0xF610, 0xF5D0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF5F0, 0xF610, 0xFEAF, 0xFEAF, 0xFEAF, 0xFED0, 0xFEB0, 0xFEB1, 0xE471, 0xB8D1, 0xA111, 0x9931, 0x9931, 0x9912, 0x6933, 0xB0F1, 0xB0D1, 0xB0D1, 0x283C, 0x001F, 0x001F, 0x001F, 0x003F, 0x007F, 0x00BF, 0x00DF, 0x00FF, 0x011F, 0x047F, 0x07D1, 0x07E3, 0x07F3, 0x07FF, 0x07FF, 0x3B77, 0x4932, 0x4932, 0x4131, 0x4111, 0x38F0, 0x38F0, 0x30EF, 0x30EF, 0x28EF, 0x28CE, 0x28CE, 0x20CE, 0x20CD, 0x20CD, 0x20AD, 0x20AD, 0x20AD, 0x20AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x18AC, 0x18AD, 0x0118, 0x0118, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AD, 0x20AD, 0x0118, 0x0118, 0x20AD, 0x20AC, 0x20AC, 0x18AD, 0x18AD, 0x18AC, 0x20AC, 0x18AD, 0x18AC, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, 0x18AD, + 0x0118, 0x00F6, 0x18CD, 0x18AC, 0x18AD, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x18AD, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18CC, 0x20AC, 0x18AD, 0x00F6, 0x0118, 0x0117, 0x18CF, 0x18AD, 0x18AC, 0x18AC, 0x18AD, 0x18AC, 0x20AD, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18CD, 0x18AC, 0x20AC, 0x38CE, 0x9931, 0x9931, 0x9931, 0xAA31, 0xFE2D, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFEAD, 0xFE8C, 0xFEAC, 0xFEAC, 0xFE8C, 0xFE8C, 0xFEAC, 0xFEAD, 0xFE8D, 0xFE8C, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFE8C, 0xFE8C, 0xFEAC, 0xFEAC, 0xFEAD, 0xFE8C, 0xFEAD, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8C, 0xFEAD, 0xFE8C, 0xFE8C, 0xFEAD, 0xFEAD, 0xFEAC, 0xFEAC, 0xFE8C, 0xFE8C, 0xFEAC, 0xFE8C, 0xFEAC, 0xFEAD, 0xFEAD, 0xFE8D, 0xFE8C, 0xFEAD, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8D, 0xFEAC, 0xFE8C, 0xFEAC, 0xFE8D, 0xFEAD, 0xFEAD, 0xFE8C, 0xFEAC, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8C, 0xFEAC, 0xFE8D, 0xFE8C, 0xFEAD, 0xFEAD, 0xFE8C, 0xFE8C, 0xFE8C, 0xFEAD, 0xFE8C, 0xFEAC, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFE8C, 0xFEAC, 0xFE8D, 0xFEAC, 0xFEAD, 0xFEAD, 0xFE8C, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAC, 0xFE8C, 0xFEAD, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFEAD, 0xFEAD, 0xFEAD, 0xFE8D, 0xFEAD, 0xFEAD, 0xFEAD, 0xFEAD, 0xFE8D, 0xFE8E, 0xFEAD, 0xFEAE, 0xFEAE, 0xFEAD, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFEAE, 0xFE8E, 0xFE8E, 0xFEAE, 0xFEAE, 0xFEAE, 0xFE8E, 0xFEAE, 0xFEAE, 0xFEAE, 0xFE8E, 0xFE8E, 0xFEAE, 0xFEAF, 0xFEAE, 0xFEAE, 0xFEAF, 0xFE8E, 0xFEAF, 0xFEAF, 0xFEAF, 0xFEAF, 0xFEAF, 0xFE8F, 0xFEB0, 0xFEAF, 0xFEB0, 0xFE90, 0xE471, 0xB8D2, 0xA111, 0x9911, 0x9931, 0x9931, 0x7132, 0x7133, 0xB0F1, 0xB0D1, 0xB0D2, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x007F, 0x00DF, 0x00DF, 0x011F, 0x011F, 0x049F, 0x07F0, 0x07E2, 0x07F4, 0x07FF, 0x07FF, 0x3AF6, 0x4932, 0x4932, 0x4111, 0x3911, 0x3910, 0x38F0, 0x30EF, 0x30EF, 0x28EE, 0x28CE, 0x28CE, 0x20CE, 0x20CD, 0x20CD, 0x20AD, 0x20AD, 0x20AD, 0x18AC, 0x20AC, 0x18AD, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x0118, 0x0118, 0x18AC, 0x18AC, 0x18AC, 0x20AC, 0x18AC, 0x20AD, 0x18AD, 0x0118, 0x0118, 0x18AC, 0x18AD, 0x18AD, 0x18AC, 0x18AD, 0x18AD, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, + 0x00F8, 0x0118, 0x00F5, 0x18AD, 0x20AC, 0x18AD, 0x20AD, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x20AD, 0x18CD, 0x0116, 0x0118, 0x0117, 0x18CF, 0x20AC, 0x20AC, 0x20AD, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x20AD, 0x20AC, 0x60EF, 0x9912, 0x9931, 0x9931, 0xB270, 0xF62D, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE6D, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8C, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8E, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8D, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8E, 0xFE8F, 0xFE8E, 0xFE8E, 0xFE8F, 0xFE8F, 0xFE8E, 0xFE8F, 0xFE8F, 0xFE8E, 0xFE8F, 0xFE8E, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE8F, 0xFE90, 0xFE90, 0xFEB0, 0xFEB0, 0xE471, 0xB8D1, 0xA111, 0x9931, 0x9931, 0x9912, 0x8911, 0x5174, 0x6953, 0xB0F1, 0xB0D1, 0x90B4, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x009F, 0x00DF, 0x00FF, 0x011F, 0x015F, 0x049F, 0x07F1, 0x07E2, 0x07F6, 0x07FF, 0x0F9F, 0x4A35, 0x4933, 0x4932, 0x4131, 0x3910, 0x3910, 0x38F0, 0x30EF, 0x30EF, 0x28CE, 0x28CE, 0x28CE, 0x20CD, 0x20CD, 0x20CD, 0x20AD, 0x20AD, 0x20AD, 0x18AC, 0x20AC, 0x20AC, 0x18AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x0118, 0x0118, 0x18AC, 0x18AC, 0x18AC, 0x20AC, 0x18AC, 0x18AD, 0x20AD, 0x0118, 0x0118, 0x18CE, 0x20AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x20AD, 0x20AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, + 0x18CE, 0x0117, 0x0118, 0x0115, 0x18AD, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AD, 0x00F6, 0x0118, 0x0117, 0x18CE, 0x18AC, 0x20CC, 0x20AC, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AD, 0x18CC, 0x20AD, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x28AD, 0x8110, 0x9931, 0x9931, 0x9911, 0xAA31, 0xF5CD, 0xFE8C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE8C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE8C, 0xFE6D, 0xFE6D, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6D, 0xFE6C, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6C, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE8E, 0xFE8D, 0xFE8D, 0xFE6E, 0xFE8D, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE8F, 0xFE8F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE8F, 0xFE6F, 0xFE6F, 0xFE8F, 0xFE8F, 0xFE6F, 0xFE6F, 0xFE8F, 0xFE6F, 0xFE6F, 0xFE8F, 0xFE8F, 0xFE6F, 0xFE8F, 0xFE8F, 0xFE6F, 0xFE90, 0xFE8F, 0xFE8F, 0xFE90, 0xFE90, 0xE471, 0xB0D1, 0xA111, 0x9931, 0x9931, 0x9931, 0x9912, 0x5953, 0x5153, 0x7133, 0xB0D1, 0xB0D1, 0x7896, 0x001F, 0x001F, 0x001F, 0x003F, 0x005F, 0x00BF, 0x011F, 0x011F, 0x013F, 0x017F, 0x04BF, 0x07F2, 0x07E2, 0x07F5, 0x07FF, 0x7336, 0x5153, 0x4933, 0x4932, 0x4131, 0x4110, 0x3910, 0x30EF, 0x30EF, 0x30EF, 0x28CE, 0x28CE, 0x28CD, 0x20CD, 0x20CD, 0x20CD, 0x20AD, 0x20AD, 0x20AD, 0x20AC, 0x20AC, 0x20AD, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x0118, 0x0118, 0x18AC, 0x20AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x20AC, 0x00F5, 0x0117, 0x00F7, 0x18CE, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x18AD, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, + 0x20AC, 0x18AE, 0x0117, 0x0118, 0x08F5, 0x18AD, 0x18AC, 0x18CD, 0x20AC, 0x18AC, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x08F3, 0x0118, 0x0117, 0x18CE, 0x20AC, 0x20AC, 0x18AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x18AC, 0x28AD, 0x9111, 0x9931, 0x9931, 0x9931, 0xA171, 0xCBCF, 0xF60D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6C, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6C, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6C, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6D, 0xFE6D, 0xFE6D, 0xFE4D, 0xFE6E, 0xFE6E, 0xFE4E, 0xFE6D, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6E, 0xFE6F, 0xFE6E, 0xFE6E, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE70, 0xFE70, 0xFE6F, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE90, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE71, 0xFE71, 0xFE71, 0xE471, 0xA8F1, 0xA111, 0x9931, 0x9932, 0x9931, 0x9931, 0x6933, 0x5153, 0x5953, 0x7153, 0xB0D1, 0xB0D1, 0x5878, 0x001F, 0x001F, 0x003F, 0x007F, 0x009F, 0x00FF, 0x013F, 0x013F, 0x017F, 0x019F, 0x033F, 0x07F3, 0x07E2, 0x07F3, 0x07FF, 0xA8F1, 0x6932, 0x4932, 0x4932, 0x4931, 0x4111, 0x3910, 0x3110, 0x30EF, 0x30EF, 0x28CE, 0x28CE, 0x28CD, 0x20CD, 0x20CD, 0x20CD, 0x20AD, 0x20AD, 0x20AD, 0x20AC, 0x20AC, 0x20AD, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x0118, 0x0118, 0x18AC, 0x20AC, 0x20AC, 0x18AC, 0x20AD, 0x20AC, 0x18AC, 0x18AD, 0x00F5, 0x0118, 0x0117, 0x18CE, 0x20AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, + 0x18AC, 0x20AC, 0x18CE, 0x08F5, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0117, 0x00F7, 0x18CE, 0x20AC, 0x18CC, 0x18AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x18AC, 0x20AC, 0x28CD, 0x8111, 0x9931, 0x9912, 0x9931, 0x9931, 0x9911, 0xBAB0, 0xDC6F, 0xE50F, 0xE50E, 0xFE4E, 0xFE6E, 0xFE4E, 0xFE6D, 0xFE4E, 0xFE4E, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4E, 0xFE4E, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4D, 0xFE4E, 0xFE4E, 0xFE4E, 0xFE4E, 0xFE6E, 0xFE6E, 0xFE4E, 0xFE4E, 0xFE4E, 0xFE6E, 0xFE6E, 0xFE4E, 0xFE6F, 0xFE6E, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE6F, 0xFE4F, 0xFE6F, 0xFE70, 0xFE50, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE70, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xFE71, 0xF612, 0xE531, 0xE512, 0xD472, 0xB271, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9911, 0x6153, 0x5153, 0x5954, 0x5954, 0x7154, 0xB0F1, 0xB0F1, 0x285C, 0x003F, 0x005F, 0x007F, 0x00BF, 0x00FF, 0x013F, 0x015F, 0x017F, 0x019F, 0x01BF, 0x02FF, 0x07F4, 0x07E3, 0x07F1, 0x2E5C, 0xA911, 0x6932, 0x5132, 0x4931, 0x4132, 0x4110, 0x3910, 0x3910, 0x30EF, 0x30EE, 0x28CE, 0x28CE, 0x28CD, 0x20CD, 0x20CD, 0x20CD, 0x20AC, 0x20AD, 0x20AD, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x18AC, 0x0118, 0x0118, 0x18AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x18CC, 0x20AC, 0x18AD, 0x0115, 0x0118, 0x00F7, 0x18AE, 0x18AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x10D0, 0x10D2, 0x08D2, 0x18AE, 0x20AC, 0x18AC, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, + 0x18AC, 0x20AC, 0x20AC, 0x18CD, 0x0116, 0x0117, 0x0118, 0x0118, 0x0117, 0x0117, 0x0118, 0x0118, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x18CE, 0x18AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x28CC, 0x610F, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9932, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9912, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9911, 0x9931, 0x9931, 0x9911, 0x9911, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9911, 0x9931, 0x9932, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9912, 0x9931, 0x9931, 0x9931, 0x9931, 0x8912, 0x5153, 0x5953, 0x5153, 0x5974, 0x5974, 0x7953, 0xB0F1, 0xB0D1, 0x087F, 0x009F, 0x00BF, 0x00DF, 0x011F, 0x015F, 0x019F, 0x019F, 0x019F, 0x01DF, 0x01DF, 0x01FF, 0x07F7, 0x07E3, 0x07EF, 0x5498, 0xA8F1, 0x7132, 0x4952, 0x4931, 0x4131, 0x4110, 0x3910, 0x30EF, 0x30EF, 0x30EE, 0x28CE, 0x28CE, 0x28CD, 0x20CD, 0x20CD, 0x20CD, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x0117, 0x0117, 0x20AC, 0x18AC, 0x18AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x18AD, 0x0115, 0x0117, 0x00F7, 0x18AE, 0x18AC, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AD, 0x00F5, 0x0117, 0x0118, 0x0117, 0x0117, 0x08F3, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x20CC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x18AC, + 0x20AC, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x40CE, 0x7910, 0x9931, 0x9931, 0x9932, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0xA111, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9912, 0x7132, 0x5153, 0x5153, 0x5153, 0x5974, 0x5974, 0x6174, 0x9113, 0xB0F1, 0x98F3, 0x00DF, 0x00FF, 0x011F, 0x013F, 0x017F, 0x01BF, 0x01BF, 0x01DF, 0x01DF, 0x01FF, 0x01FF, 0x021F, 0x06D9, 0x07E5, 0x07EC, 0x7355, 0xA8F1, 0x7932, 0x4932, 0x4931, 0x4131, 0x4110, 0x3910, 0x390F, 0x30EF, 0x30EE, 0x28CE, 0x28CE, 0x28CD, 0x28CD, 0x20CD, 0x20CD, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x18AC, 0x0117, 0x00F7, 0x20AC, 0x18AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AD, 0x00F5, 0x0117, 0x0116, 0x18CD, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x00F5, 0x0117, 0x0118, 0x08F5, 0x0116, 0x0117, 0x0117, 0x10F2, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x18AC, 0x20AB, 0x20AC, 0x20AC, + 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AB, 0x30CC, 0x58CF, 0x7910, 0x9931, 0x9931, 0x9912, 0x9931, 0x9931, 0x9911, 0x9931, 0x9911, 0x9932, 0x9931, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9911, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0xA111, 0x9911, 0x8932, 0x6932, 0x5152, 0x5153, 0x5953, 0x5953, 0x5974, 0x6174, 0x6175, 0x7954, 0xA8F1, 0xB0F1, 0x80F5, 0x013F, 0x017F, 0x019F, 0x01BF, 0x01DF, 0x01FF, 0x01DF, 0x01FF, 0x021F, 0x023F, 0x023F, 0x023F, 0x057D, 0x07E8, 0x07E9, 0x82D5, 0xA0F1, 0x8132, 0x5132, 0x4931, 0x4131, 0x4110, 0x38F0, 0x38EF, 0x30EF, 0x30EE, 0x28CE, 0x28CD, 0x28CD, 0x28CD, 0x20CD, 0x20CD, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x00F7, 0x0117, 0x10D0, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x18CD, 0x00F5, 0x0117, 0x08F5, 0x18AD, 0x20AC, 0x20CC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x18AD, 0x0117, 0x0117, 0x10D0, 0x20AC, 0x20AC, 0x08F3, 0x0117, 0x0115, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20CC, 0x20AC, 0x20AC, 0x20AC, 0x20CC, + 0x20AC, 0x20AC, 0x20AC, 0x20AB, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18CC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20CC, 0x20AD, 0x20CD, 0x20CD, 0x28CD, 0x28CD, 0x28CD, 0x28CD, 0x28CD, 0x28CE, 0x28EE, 0x28EE, 0x30EE, 0x30EF, 0x30EF, 0x30EE, 0x38EF, 0x5110, 0x6110, 0x5910, 0x6930, 0x7931, 0x8131, 0x8130, 0x9931, 0xA932, 0xA131, 0xB131, 0xC912, 0xC911, 0xC8F2, 0xC8F2, 0xC8F2, 0xC8D1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xB8B1, 0xC0D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0D1, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0F1, 0x5158, 0x01BF, 0x01DF, 0x01FF, 0x021F, 0x023F, 0x023F, 0x021F, 0x023F, 0x025F, 0x025F, 0x025F, 0x025F, 0x041F, 0x07ED, 0x07E4, 0x7AB4, 0xA911, 0x9112, 0x5132, 0x4931, 0x4111, 0x4110, 0x3910, 0x38EF, 0x30EF, 0x30EE, 0x30EE, 0x28CD, 0x28CD, 0x28CD, 0x20CD, 0x20CC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x10D0, 0x0117, 0x00F7, 0x10D0, 0x20AC, 0x20CC, 0x18AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x00F5, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x20AC, 0x20AC, 0x20AC, 0x10EF, 0x0117, 0x0117, 0x20AC, 0x20AC, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, + 0x20AC, 0x18AC, 0x18AC, 0x18CC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20CC, 0x20AC, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AB, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20CC, 0x20CD, 0x20CD, 0x28CD, 0x28CD, 0x28CD, 0x28CD, 0x28AD, 0x28CE, 0x30CE, 0x30CE, 0x30EE, 0x8151, 0xB192, 0xC9B3, 0xC9B2, 0xC992, 0xC992, 0xC992, 0xC972, 0xC972, 0xC972, 0xC952, 0xC952, 0xC932, 0xC932, 0xC932, 0xC912, 0xC912, 0xC111, 0xC8F1, 0xC8F1, 0xC8D1, 0xC0D1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0D1, 0xB8B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D2, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xA8F1, 0x39BB, 0x021F, 0x023F, 0x025F, 0x027F, 0x027F, 0x025F, 0x025F, 0x027F, 0x027F, 0x027F, 0x027F, 0x027F, 0x029F, 0x07F3, 0x07E2, 0x9972, 0xA911, 0xA112, 0x4952, 0x4932, 0x4131, 0x4110, 0x3910, 0x38EF, 0x30EF, 0x30EE, 0x30EE, 0x28CD, 0x28CD, 0x28CD, 0x20CD, 0x20CC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x08F2, 0x0117, 0x0116, 0x10D0, 0x20AC, 0x20AB, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AD, 0x00F4, 0x00F7, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0116, 0x0117, 0x0116, 0x0117, 0x0116, 0x0117, 0x18CF, 0x20AC, 0x20AC, 0x10D1, 0x00F7, 0x0115, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AB, 0x20AB, 0x20AC, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B8, 0x03B7, 0x03B7, 0x03B7, 0x03B7, + 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AB, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AB, 0x20AC, 0x20AB, 0x20AB, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x18CC, 0x18AC, 0x20AB, 0x20AC, 0x20AC, 0x20AB, 0x20AC, 0x20AC, 0x18AC, 0x20AB, 0x20AB, 0x20AC, 0x20AC, 0x20AB, 0x20AB, 0x20AC, 0x20AC, 0x20AB, 0x20AB, 0x20AC, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20CC, 0x20CC, 0x20CC, 0x28CD, 0x28CD, 0x28CD, 0x28CD, 0x30CD, 0x28EE, 0x30EE, 0x490E, 0xA9B2, 0xC9D3, 0xC9D3, 0xC9B3, 0xC9B3, 0xC992, 0xC992, 0xC972, 0xC972, 0xC972, 0xC952, 0xC952, 0xC952, 0xC932, 0xC932, 0xC912, 0xC912, 0xC912, 0xC0F2, 0xC8D1, 0xC0D1, 0xC0D1, 0xC8B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB0D1, 0xB8D2, 0xB8D1, 0xB0F1, 0xB0D1, 0xB0F2, 0xB0F1, 0xB0F1, 0xB0F1, 0xA8F1, 0xA8F1, 0x123E, 0x029F, 0x02BF, 0x02BF, 0x02BF, 0x029F, 0x029F, 0x029F, 0x02BF, 0x02BF, 0x02BF, 0x029F, 0x029F, 0x02DF, 0x06B9, 0x07E3, 0xA111, 0xA911, 0xA111, 0x5932, 0x4931, 0x4911, 0x4110, 0x4110, 0x390F, 0x38EF, 0x30EE, 0x30EE, 0x28CD, 0x28CD, 0x28CD, 0x20CD, 0x20CC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AB, 0x20AC, 0x20AB, 0x20AB, 0x20AC, 0x08D3, 0x0116, 0x0117, 0x10CF, 0x20AC, 0x20AB, 0x20AB, 0x20AB, 0x20AC, 0x20AC, 0x20AB, 0x20AC, 0x18AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AB, 0x20AC, 0x20AB, 0x20AC, 0x00F4, 0x0117, 0x0116, 0x08F2, 0x08F2, 0x0117, 0x0116, 0x08F2, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x03B7, 0x03B7, 0x03B8, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, + 0x20AC, 0x20AB, 0x20AB, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AB, 0x20AC, 0x20AC, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AC, 0x20AB, 0x20AB, 0x20AB, 0x20AC, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AB, 0x20AC, 0x20AB, 0x20AC, 0x20AC, 0x20AB, 0x20AB, 0x18AC, 0x20AC, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x18AB, 0x20AB, 0x20AB, 0x20AC, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20CC, 0x20CD, 0x28CD, 0x28CD, 0x28CD, 0x28CD, 0x28CD, 0x28CD, 0x30ED, 0x692F, 0xC9D3, 0xC9D3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC992, 0xC992, 0xC972, 0xC972, 0xC972, 0xC952, 0xC952, 0xC932, 0xC932, 0xC132, 0xC912, 0xC912, 0xC8F2, 0xC8F1, 0xC8D1, 0xC0D1, 0xC0D1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xC0B1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0D1, 0xB8D1, 0xB0F1, 0xB0D1, 0xB0D1, 0xB0F1, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xA8F1, 0x9933, 0x02DF, 0x02DF, 0x02FF, 0x02FF, 0x02DF, 0x02BF, 0x02DF, 0x02DF, 0x02DF, 0x02DF, 0x02DF, 0x02BF, 0x02BF, 0x02FF, 0x051E, 0x07E8, 0xA912, 0xA111, 0xA111, 0x6932, 0x4931, 0x4931, 0x4130, 0x410F, 0x390F, 0x38EE, 0x30EE, 0x30EE, 0x28CD, 0x28CD, 0x28CD, 0x20CD, 0x20CC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AB, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AB, 0x20AC, 0x20AB, 0x20AB, 0x20AC, 0x20AB, 0x20AB, 0x08F2, 0x0116, 0x0117, 0x10D0, 0x20AB, 0x20AB, 0x20AC, 0x20AB, 0x20AC, 0x20AB, 0x20AB, 0x20AC, 0x20AB, 0x20AB, 0x20AC, 0x20AC, 0x18CB, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AB, 0x20AB, 0x18AE, 0x0115, 0x0117, 0x0116, 0x0116, 0x0116, 0x00F4, 0x18CC, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x03B8, 0x03B8, 0x03B7, 0x03B7, 0x03B7, 0x03B8, 0x03B7, 0x03B7, 0x03B7, + 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AC, 0x20AC, 0x20AC, 0x28AC, 0x20CC, 0x28CC, 0x28CC, 0x28CC, 0x28CD, 0x28CD, 0x28ED, 0x28CD, 0x30CD, 0x9191, 0xC9D3, 0xC9D3, 0xC9B3, 0xC9B3, 0xC992, 0xC9B3, 0xC992, 0xC992, 0xC972, 0xC972, 0xC952, 0xC952, 0xC932, 0xC932, 0xC912, 0xC932, 0xC912, 0xC112, 0xC8F2, 0xC8F2, 0xC8D1, 0xC8D1, 0x9095, 0x9095, 0x9075, 0x8875, 0x6078, 0x6059, 0x6059, 0x6058, 0x6058, 0x6078, 0x6078, 0x6059, 0x6078, 0x6078, 0x5878, 0x6078, 0x88B4, 0x88B5, 0x88B5, 0xB8D1, 0xB8D1, 0xB8D1, 0xB8D1, 0xB0F1, 0xB0F1, 0xB0D1, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xA8F1, 0xA8F1, 0xA8F1, 0x69D6, 0x033F, 0x033F, 0x033F, 0x031F, 0x02FF, 0x02FF, 0x02FF, 0x02FF, 0x02FF, 0x02FF, 0x02FF, 0x02DF, 0x02FF, 0x035F, 0x03FF, 0x07F0, 0x8A4F, 0xA111, 0xA111, 0x8132, 0x4931, 0x4931, 0x4110, 0x410F, 0x390F, 0x30EE, 0x30EE, 0x30CD, 0x30CD, 0x28CD, 0x28CD, 0x28CC, 0x28CC, 0x20CC, 0x20AC, 0x20AC, 0x20AC, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x08F2, 0x0116, 0x0116, 0x10CF, 0x20AB, 0x20AB, 0x20AB, 0x20AC, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AC, 0x20AB, 0x20AB, 0x20CC, 0x08D1, 0x08F3, 0x08F3, 0x10D0, 0x20AB, 0x20AC, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x03B7, 0x03B8, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, + 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CC, 0x20AC, 0x28CC, 0x28CC, 0x28CC, 0x20CC, 0x28CC, 0x28CC, 0x28CD, 0x40EE, 0xA9B2, 0xC9D3, 0xC9D3, 0xC9B3, 0xC9B2, 0xC9B3, 0xC992, 0xC992, 0xC972, 0xC972, 0xC952, 0xC952, 0xC952, 0xC932, 0xC932, 0x90D5, 0x88D6, 0x6098, 0x5879, 0x303C, 0x305C, 0x081E, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x005F, 0x007F, 0x009F, 0x00BF, 0x00DF, 0x291C, 0x411A, 0x6118, 0x8915, 0xB0D1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F1, 0xB0F2, 0xA8F1, 0xB0F1, 0x429A, 0x039F, 0x039F, 0x035F, 0x035F, 0x033F, 0x033F, 0x033F, 0x033F, 0x033F, 0x033F, 0x031F, 0x031F, 0x031F, 0x037F, 0x03FF, 0x06D7, 0x7ACF, 0xA111, 0xA111, 0x9912, 0x5131, 0x4931, 0x4110, 0x410F, 0x40EF, 0x38EE, 0x30EE, 0x30ED, 0x30CD, 0x28CD, 0x28CD, 0x28CC, 0x28CC, 0x20CC, 0x20CC, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x08F2, 0x0116, 0x0116, 0x10CF, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x20AB, 0x20AB, 0x20AB, 0x20AB, + 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x20CB, 0x28CC, 0x28CC, 0x28CC, 0x28CD, 0x28CC, 0x490E, 0xC1D3, 0xC9D3, 0xC9D3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC9B3, 0xC992, 0xC992, 0xC972, 0xC952, 0x98F5, 0x60B8, 0x407B, 0x183E, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x003F, 0x007F, 0x007F, 0x009F, 0x00BF, 0x00FF, 0x011F, 0x013F, 0x017F, 0x019F, 0x01DF, 0x021F, 0x21FD, 0x49D9, 0x7996, 0xA112, 0xA8F1, 0xB0F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0x139E, 0x03DF, 0x03BF, 0x039F, 0x039F, 0x037F, 0x037F, 0x037F, 0x037F, 0x035F, 0x035F, 0x033F, 0x033F, 0x035F, 0x03BF, 0x041F, 0x05DE, 0x7AD1, 0xA111, 0xA111, 0xA111, 0x5931, 0x4931, 0x4130, 0x4130, 0x40EF, 0x38EE, 0x30EE, 0x30ED, 0x30ED, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x08F2, 0x0115, 0x0115, 0x10CF, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x18AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B8, + 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x692F, 0xC9F3, 0xC9D3, 0xC9D3, 0xC9B2, 0xC9B3, 0xC992, 0xC9B2, 0xC972, 0xB973, 0x80F7, 0x387B, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x003F, 0x005F, 0x007F, 0x009F, 0x00BF, 0x00DF, 0x00FF, 0x013F, 0x015F, 0x019F, 0x01BF, 0x01FF, 0x023F, 0x025F, 0x029F, 0x02DF, 0x02FF, 0x033F, 0x2ADC, 0x5A58, 0x8994, 0xA8F1, 0xA8F1, 0x81D4, 0x041F, 0x041F, 0x03FF, 0x03DF, 0x03BF, 0x03BF, 0x03BF, 0x03BF, 0x03BF, 0x039F, 0x037F, 0x035F, 0x037F, 0x039F, 0x03FF, 0x047F, 0x04FF, 0x6375, 0xA112, 0xA111, 0xA111, 0x7111, 0x4931, 0x4110, 0x4110, 0x390F, 0x38EE, 0x30EE, 0x30ED, 0x30ED, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x08F1, 0x0115, 0x0115, 0x10CF, 0x20AB, 0x20AB, 0x20AB, 0x20CA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, 0x03B7, + 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x28AC, 0x28CC, 0x28CC, 0x28CC, 0x692E, 0xC9F3, 0xC9D2, 0xC9D3, 0xC9B3, 0xC9B3, 0xC992, 0xC993, 0x80F7, 0x389B, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x083C, 0x085B, 0x105B, 0x2078, 0x2098, 0x2097, 0x2097, 0x2097, 0x2097, 0x2097, 0x2098, 0x187A, 0x105B, 0x085D, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x003F, 0x005F, 0x007F, 0x009F, 0x00DF, 0x00FF, 0x011F, 0x015F, 0x017F, 0x01BF, 0x01FF, 0x021F, 0x025F, 0x029F, 0x02DF, 0x02FF, 0x033F, 0x037F, 0x03BF, 0x03DF, 0x041F, 0x043F, 0x0C3F, 0x2BBC, 0x0C3F, 0x045F, 0x043F, 0x041F, 0x041F, 0x03FF, 0x03FF, 0x03FF, 0x03DF, 0x03DF, 0x03BF, 0x039F, 0x037F, 0x039F, 0x03DF, 0x043F, 0x04BF, 0x053F, 0x5398, 0xA111, 0xA111, 0xA111, 0x9111, 0x4931, 0x4910, 0x4110, 0x410F, 0x38EE, 0x38EE, 0x30ED, 0x30CD, 0x30CD, 0x28CC, 0x28CC, 0x28CC, 0x28CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x08F1, 0x0115, 0x0115, 0x10CE, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x1378, 0x1378, 0x1358, 0x1358, 0x1378, 0x1378, 0x1358, 0x1378, 0x1358, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x28CB, 0x28CB, 0x28CC, 0x28CB, 0x614E, 0xD1F3, 0xC9F3, 0xC9D3, 0xC9B2, 0xC9B3, 0xB173, 0x60D9, 0x081E, 0x003D, 0x083B, 0x1878, 0x1877, 0x28D2, 0x28D2, 0x40EE, 0x38EE, 0x390F, 0x390F, 0x390F, 0x410E, 0x410F, 0x410F, 0x410F, 0x410F, 0x410F, 0x410F, 0x410F, 0x4110, 0x410F, 0x4910, 0x4130, 0x38F3, 0x28B6, 0x189A, 0x003E, 0x001F, 0x001F, 0x003F, 0x005F, 0x005F, 0x007F, 0x00BF, 0x00DF, 0x00FF, 0x013F, 0x015F, 0x019F, 0x01DF, 0x021F, 0x023F, 0x027F, 0x029F, 0x02FF, 0x033F, 0x035F, 0x039F, 0x03DF, 0x041F, 0x045F, 0x047F, 0x04BF, 0x04DF, 0x04DF, 0x04BF, 0x04BF, 0x047F, 0x047F, 0x043F, 0x043F, 0x043F, 0x041F, 0x041F, 0x03FF, 0x03DF, 0x03BF, 0x03BF, 0x03DF, 0x043F, 0x047F, 0x04DF, 0x057F, 0x3C1A, 0xA111, 0xA111, 0xA111, 0xA111, 0x5931, 0x4910, 0x4110, 0x410F, 0x390E, 0x38EE, 0x30ED, 0x30ED, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x08F1, 0x0115, 0x0115, 0x10CF, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x3AF9, 0x3AD9, 0x3AD9, 0x3AD9, 0x3AD9, 0x3AD9, 0x3AF9, 0x3AF9, 0x3AF9, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x28CB, 0x20CB, 0x28AB, 0x692E, 0xC9D3, 0xC9D3, 0xC9D3, 0xC9B3, 0xB1B2, 0x58F3, 0x1895, 0x28B2, 0x30ED, 0x38ED, 0x30ED, 0x38ED, 0x38ED, 0x38ED, 0x38EE, 0x390E, 0x390E, 0x38EE, 0x38EE, 0x390E, 0x390E, 0x390E, 0x390E, 0x410F, 0x390E, 0x410F, 0x410F, 0x410F, 0x410F, 0x410F, 0x410F, 0x4110, 0x410F, 0x492F, 0x4930, 0x4910, 0x38F3, 0x20B8, 0x087D, 0x007F, 0x009F, 0x00DF, 0x00FF, 0x011F, 0x015F, 0x017F, 0x019F, 0x01DF, 0x021F, 0x025F, 0x02BF, 0x02DF, 0x031F, 0x035F, 0x039F, 0x03DF, 0x041F, 0x045F, 0x049F, 0x04DF, 0x04FF, 0x051F, 0x051F, 0x053F, 0x04FF, 0x04DF, 0x04BF, 0x049F, 0x047F, 0x047F, 0x045F, 0x045F, 0x043F, 0x041F, 0x03FF, 0x03DF, 0x03FF, 0x043F, 0x045F, 0x04BF, 0x053F, 0x05BF, 0x2CDC, 0xA112, 0xA111, 0xA111, 0xA111, 0x7131, 0x4930, 0x4130, 0x410F, 0x390E, 0x38EE, 0x30ED, 0x30ED, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x28AB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x08F1, 0x0115, 0x0114, 0x10CE, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x625A, 0x625B, 0x5A5A, 0x5A5A, 0x625B, 0x20CA, 0x20AA, 0x20AA, 0x20AA, + 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x28AB, 0x28CB, 0x28CB, 0x612E, 0xC9F3, 0xC9D3, 0xC9D3, 0xB992, 0x692E, 0x28CC, 0x28EC, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x38ED, 0x30ED, 0x38ED, 0x38ED, 0x390E, 0x38EE, 0x38EE, 0x38EE, 0x390F, 0x38EE, 0x40EE, 0x40EE, 0x390F, 0x390E, 0x410E, 0x40EF, 0x410F, 0x410F, 0x410F, 0x410F, 0x410F, 0x410F, 0x410F, 0x412F, 0x4910, 0x4910, 0x4930, 0x4113, 0x28F8, 0x08FE, 0x013F, 0x015F, 0x019F, 0x01DF, 0x021F, 0x023F, 0x029F, 0x02BF, 0x031F, 0x035F, 0x039F, 0x03DF, 0x041F, 0x045F, 0x049F, 0x04DF, 0x051F, 0x053F, 0x057F, 0x059F, 0x057F, 0x055F, 0x053F, 0x04FF, 0x04FF, 0x04DF, 0x04BF, 0x049F, 0x049F, 0x047F, 0x045F, 0x043F, 0x041F, 0x041F, 0x043F, 0x045F, 0x04BF, 0x04FF, 0x055F, 0x05DF, 0x0E1F, 0xA111, 0xA111, 0xA111, 0xA112, 0x8931, 0x4930, 0x4130, 0x410F, 0x410E, 0x38EE, 0x30ED, 0x30ED, 0x30CC, 0x28CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x08F1, 0x0115, 0x0114, 0x10CF, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20CB, 0x10CF, 0x10EF, 0x10EF, 0x18CE, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x81DB, 0x81DC, 0x81DB, 0x81DB, 0x81BC, 0x81BB, 0x81BC, 0x81DC, 0x81DC, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20CA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20CB, 0x20AB, 0x20AB, 0x20CB, 0x28AB, 0x20CB, 0x612E, 0xD1F3, 0xC9F3, 0xC1B2, 0x612E, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x38ED, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x390E, 0x38EE, 0x390E, 0x390E, 0x390E, 0x410F, 0x410F, 0x410F, 0x410F, 0x410F, 0x410F, 0x4130, 0x4930, 0x4930, 0x4931, 0x4930, 0x4133, 0x197A, 0x01DE, 0x021F, 0x027F, 0x02BF, 0x02FF, 0x033F, 0x037F, 0x03BF, 0x03FF, 0x045F, 0x049F, 0x04DF, 0x051F, 0x057F, 0x059F, 0x05DF, 0x05DF, 0x05DF, 0x05BF, 0x059F, 0x055F, 0x055F, 0x053F, 0x051F, 0x04FF, 0x04DF, 0x04DF, 0x04BF, 0x047F, 0x045F, 0x043F, 0x043F, 0x047F, 0x04BF, 0x04FF, 0x053F, 0x05BF, 0x061F, 0x069F, 0x9972, 0xA111, 0xA111, 0xA111, 0xA111, 0x5130, 0x4910, 0x410F, 0x390F, 0x390E, 0x38ED, 0x30ED, 0x30CD, 0x28CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x08F1, 0x0115, 0x00F4, 0x18CC, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x18CC, 0x00F3, 0x0115, 0x0114, 0x0115, 0x00F4, 0x00F2, 0x20CB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0xA93D, 0xA93D, 0xA95C, 0xA93D, 0xA95C, 0xA95D, 0xA93C, 0xA95D, 0xA93D, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20CB, 0x28AB, 0x510D, 0xD1F3, 0xC9D2, 0x816F, 0x30CC, 0x28AC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x30CD, 0x30ED, 0x30ED, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x38ED, 0x38ED, 0x38ED, 0x38ED, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x390E, 0x390E, 0x390E, 0x390E, 0x390E, 0x410F, 0x410F, 0x410F, 0x410F, 0x4110, 0x410F, 0x4910, 0x4930, 0x4930, 0x4930, 0x4931, 0x4932, 0x31B6, 0x0A9D, 0x02FF, 0x035F, 0x039F, 0x03FF, 0x043F, 0x047F, 0x04BF, 0x051F, 0x055F, 0x05BF, 0x05DF, 0x061F, 0x063F, 0x063F, 0x05FF, 0x05DF, 0x05BF, 0x059F, 0x059F, 0x057F, 0x055F, 0x053F, 0x051F, 0x04FF, 0x04DF, 0x04BF, 0x047F, 0x047F, 0x047F, 0x049F, 0x04DF, 0x053F, 0x057F, 0x05FF, 0x065F, 0x06DF, 0x7A95, 0xA111, 0xA111, 0xA111, 0xA111, 0x6911, 0x4930, 0x410F, 0x410F, 0x390E, 0x38EE, 0x30ED, 0x30CD, 0x28CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x08F1, 0x0114, 0x0114, 0x18CD, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x08F2, 0x0115, 0x0114, 0x0115, 0x0114, 0x0115, 0x0114, 0x10EF, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20CB, 0x20AB, 0xC8BE, 0xD0BE, 0xC8BE, 0xC8BE, 0xD0BE, 0xC8BE, 0xD0BE, 0xD0BE, 0xC8BE, + 0x20CA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20CB, 0x20CB, 0x20AB, 0x20AB, 0x40EC, 0xC1D2, 0xC1B3, 0x490D, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x30EC, 0x30CD, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x38ED, 0x38ED, 0x38ED, 0x38ED, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x390E, 0x390E, 0x390F, 0x410F, 0x410F, 0x410F, 0x410F, 0x4910, 0x4910, 0x4930, 0x4931, 0x4951, 0x4951, 0x39D5, 0x131C, 0x041F, 0x047F, 0x04BF, 0x051F, 0x055F, 0x059F, 0x05DF, 0x061F, 0x067F, 0x069F, 0x069F, 0x067F, 0x065F, 0x061F, 0x05FF, 0x05FF, 0x05BF, 0x059F, 0x057F, 0x055F, 0x053F, 0x051F, 0x04FF, 0x04DF, 0x04BF, 0x04BF, 0x04BF, 0x04DF, 0x051F, 0x057F, 0x05BF, 0x063F, 0x069F, 0x071F, 0x5438, 0xA111, 0xA111, 0xA111, 0xA111, 0x8111, 0x4930, 0x410F, 0x410F, 0x390E, 0x38EE, 0x30ED, 0x30ED, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x08F1, 0x0115, 0x00F4, 0x18CC, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x18CC, 0x00F5, 0x0115, 0x00F4, 0x0115, 0x0115, 0x0114, 0x0115, 0x00F4, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0xF03F, 0xF03F, 0xF03F, 0xF03F, 0xF03F, 0xF03F, 0xF03F, 0xF03F, 0xF03F, + 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x30CB, 0xA992, 0xA9B1, 0x30CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x30CC, 0x30CC, 0x30EC, 0x30EC, 0x30CD, 0x30ED, 0x30ED, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x38ED, 0x38ED, 0x38ED, 0x38ED, 0x38EE, 0x38EE, 0x38EE, 0x390E, 0x390E, 0x390E, 0x410F, 0x410F, 0x410F, 0x410F, 0x410F, 0x412F, 0x4930, 0x4930, 0x5130, 0x4931, 0x5131, 0x3A15, 0x237B, 0x053F, 0x059F, 0x5358, 0x349B, 0x0E1F, 0x06BF, 0x06FF, 0x06FF, 0x06DF, 0x06BF, 0x069F, 0x065F, 0x063F, 0x061F, 0x05FF, 0x05DF, 0x05BF, 0x059F, 0x057F, 0x055F, 0x051F, 0x04FF, 0x04DF, 0x04DF, 0x04FF, 0x051F, 0x055F, 0x059F, 0x05FF, 0x065F, 0x06DF, 0x073F, 0x359B, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0x4930, 0x4910, 0x412F, 0x390E, 0x38EE, 0x30ED, 0x30ED, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x00F3, 0x0115, 0x0114, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0114, 0x0114, 0x0114, 0x0115, 0x0114, 0x0114, 0x0115, 0x0115, 0x0114, 0x0114, 0x0114, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20CA, + 0x790F, 0x68EE, 0x50ED, 0x38CC, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x692F, 0x816F, 0x20AB, 0x20CB, 0x20AB, 0x28CB, 0x28CB, 0x28CB, 0x28AB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x30CC, 0x30CD, 0x30CD, 0x30CD, 0x30CD, 0x30CD, 0x30CD, 0x30CD, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x38ED, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x390E, 0x390E, 0x410F, 0x410F, 0x410F, 0x410F, 0x412F, 0x4930, 0x4930, 0x4930, 0x4931, 0x4931, 0x5131, 0x49D4, 0x243A, 0xA132, 0xA8F1, 0xA8F1, 0xA8F1, 0x8295, 0x8295, 0x5418, 0x351B, 0x06DF, 0x069F, 0x067F, 0x065F, 0x063F, 0x05FF, 0x05FF, 0x05BF, 0x059F, 0x057F, 0x055F, 0x053F, 0x051F, 0x051F, 0x053F, 0x057F, 0x059F, 0x05DF, 0x063F, 0x069F, 0x06FF, 0x077F, 0x0F5F, 0xA111, 0xA111, 0xA111, 0xA111, 0x9931, 0x6911, 0x4930, 0x410F, 0x390E, 0x38EE, 0x30ED, 0x30ED, 0x30CD, 0x30CC, 0x28CC, 0x28CB, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x18CB, 0x00F2, 0x0115, 0x0114, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0114, 0x00F5, 0x0114, 0x0115, 0x0114, 0x0115, 0x0115, 0x0115, 0x0115, 0x0114, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, + 0x8130, 0x8930, 0x8930, 0x8910, 0x8930, 0x790F, 0x690E, 0x48CD, 0x38CC, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20CA, 0x20CA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20CB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20CB, 0x20AB, 0x28CB, 0x28AB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x30CC, 0x30CC, 0x30CD, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30EE, 0x38ED, 0x38ED, 0x390E, 0x390E, 0x390E, 0x410E, 0x410F, 0x410F, 0x410F, 0x410F, 0x4130, 0x4930, 0x4930, 0x4930, 0x5131, 0x5131, 0x6992, 0xA8F1, 0xA911, 0xA8F1, 0xA911, 0xA8F1, 0xA8F1, 0xA8F1, 0xA172, 0x4C39, 0x2D5C, 0x069F, 0x065F, 0x063F, 0x061F, 0x05FF, 0x05DF, 0x059F, 0x057F, 0x055F, 0x055F, 0x055F, 0x057F, 0x059F, 0x05DF, 0x061F, 0x067F, 0x06DF, 0x073F, 0x079F, 0x07DF, 0x8254, 0xA111, 0xA131, 0xA111, 0x9911, 0x8131, 0x4910, 0x410F, 0x410E, 0x38EE, 0x38ED, 0x30ED, 0x30CD, 0x30CC, 0x28CC, 0x28CB, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x08F2, 0x00F5, 0x0114, 0x0114, 0x0115, 0x0115, 0x0114, 0x10F0, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AB, + 0x8930, 0x8910, 0x8910, 0x8930, 0x8930, 0x8930, 0x8910, 0x8930, 0x8910, 0x8130, 0x710F, 0x60EE, 0x48ED, 0x38CC, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x28AB, 0x28AB, 0x20CB, 0x20CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30EC, 0x30EC, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x390E, 0x390F, 0x410F, 0x410F, 0x410F, 0x412F, 0x4930, 0x4910, 0x4930, 0x5131, 0x5131, 0x6931, 0xA111, 0xA8F1, 0xA8F1, 0xA8F1, 0xA8F1, 0xA911, 0xA111, 0xA911, 0xA0F1, 0x9972, 0x4419, 0x067F, 0x065F, 0x061F, 0x05FF, 0x05DF, 0x05BF, 0x059F, 0x059F, 0x05BF, 0x05BF, 0x05DF, 0x061F, 0x065F, 0x06BF, 0x06FF, 0x075F, 0x07BF, 0x07FF, 0x5498, 0xA131, 0xA111, 0xA111, 0xA111, 0x9911, 0x4930, 0x410F, 0x410F, 0x38EE, 0x38EE, 0x30ED, 0x30CD, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20CA, 0x20AA, 0x20AA, 0x20AB, 0x20CC, 0x00F3, 0x00F4, 0x0114, 0x0114, 0x0114, 0x08F2, 0x20CB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20CA, 0x20AA, 0x20CA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, + 0x8110, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8930, 0x8910, 0x8930, 0x8930, 0x8930, 0x8930, 0x8930, 0x8930, 0x8130, 0x710F, 0x58ED, 0x48CC, 0x30CB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20CA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20AB, 0x20AB, 0x28CB, 0x20CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x30CC, 0x30EC, 0x30EC, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x38ED, 0x38EE, 0x390E, 0x390E, 0x390E, 0x390F, 0x410F, 0x410F, 0x490F, 0x412F, 0x4910, 0x4930, 0x4931, 0x4931, 0x5931, 0x9111, 0xA8F1, 0xA8F1, 0xA911, 0xA8F1, 0xA8F1, 0xA911, 0xA911, 0xA911, 0xA111, 0x7A55, 0x34BB, 0x065F, 0x061F, 0x05FF, 0x05DF, 0x05DF, 0x05DF, 0x05DF, 0x05FF, 0x063F, 0x065F, 0x069F, 0x06DF, 0x071F, 0x077F, 0x07BF, 0x07FF, 0x2E3C, 0x9911, 0xA111, 0xA111, 0x9931, 0x9931, 0x6910, 0x410F, 0x410F, 0x38EE, 0x38EE, 0x30ED, 0x30ED, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20CB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20CB, 0x10CF, 0x10D0, 0x10EF, 0x10CE, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20CA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, + 0x8910, 0x8910, 0x8910, 0x810F, 0x890F, 0x890F, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8930, 0x8930, 0x8930, 0x8930, 0x8930, 0x690F, 0x58EE, 0x40CD, 0x30CC, 0x20AB, 0x20CA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x30EC, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x390E, 0x410F, 0x410F, 0x410F, 0x410F, 0x4910, 0x4930, 0x4931, 0x5131, 0x7931, 0xA911, 0xA8F1, 0xA911, 0xA911, 0xA911, 0xA911, 0xA8F1, 0xA111, 0xA111, 0xA111, 0xA111, 0x91B3, 0x62F6, 0x347B, 0x061F, 0x061F, 0x063F, 0x063F, 0x065F, 0x067F, 0x06BF, 0x071F, 0x073F, 0x079F, 0x07DF, 0x07FF, 0x07FF, 0xA111, 0x9912, 0x9911, 0x9931, 0x9932, 0x8131, 0x4130, 0x410F, 0x410E, 0x38EE, 0x30EE, 0x30ED, 0x30CD, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x28CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x810F, 0x810F, 0x810F, 0x890F, 0x8910, 0x8910, 0x8110, 0x8110, 0x8110, 0x8110, 0x8910, 0x8130, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8930, 0x8910, 0x8930, 0x8930, 0x810F, 0x710F, 0x50ED, 0x40CC, 0x28AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20AB, 0x28AB, 0x28AB, 0x28AB, 0x28AB, 0x28AB, 0x28AB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x30ED, 0x38EE, 0x38EE, 0x38EE, 0x38EE, 0x390F, 0x410F, 0x410F, 0x410F, 0x4910, 0x4930, 0x4930, 0x4930, 0x7111, 0xA911, 0xA911, 0xA911, 0xA911, 0xA111, 0xA911, 0xA911, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0x91B3, 0x349B, 0x065F, 0x067F, 0x069F, 0x06BF, 0x06FF, 0x073F, 0x077F, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x7AD4, 0xA111, 0x9911, 0xA111, 0x9931, 0x9931, 0x4930, 0x410F, 0x390E, 0x38EE, 0x30EE, 0x30ED, 0x30ED, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x28CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x890F, 0x890F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x890F, 0x890F, 0x8910, 0x8910, 0x8110, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8930, 0x8930, 0x8930, 0x8130, 0x8930, 0x8930, 0x810F, 0x710F, 0x50ED, 0x38CC, 0x28AB, 0x20AB, 0x20AB, 0x20CA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20CA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20CA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x28AB, 0x28AB, 0x28AB, 0x28AB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x28CB, 0x28CB, 0x20CB, 0x20CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x30EC, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x38ED, 0x38EE, 0x38EE, 0x390E, 0x390E, 0x410F, 0x410F, 0x4110, 0x4930, 0x4930, 0x5130, 0x8111, 0xA111, 0xA911, 0xA111, 0xA111, 0xA911, 0xA112, 0xA111, 0xA911, 0xA111, 0xA112, 0xA0F1, 0xA111, 0xA111, 0xA111, 0x7A75, 0x15FD, 0x06BF, 0x06FF, 0x071F, 0x075F, 0x079F, 0x07BF, 0x07FF, 0x07FF, 0x07FF, 0x5499, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x6930, 0x410F, 0x390E, 0x390E, 0x38EE, 0x30ED, 0x30CD, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x8110, 0x8110, 0x8910, 0x8910, 0x8910, 0x8910, 0x8930, 0x8930, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8930, 0x8130, 0x8930, 0x8930, 0x8130, 0x8930, 0x8930, 0x790F, 0x690E, 0x50ED, 0x38CC, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x28AB, 0x20AB, 0x28AB, 0x28AB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30EC, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x38ED, 0x38EE, 0x38EE, 0x40EE, 0x410F, 0x410F, 0x410F, 0x4130, 0x4930, 0x4930, 0x5931, 0x90F1, 0xA911, 0xA912, 0xA111, 0xA111, 0xA111, 0xA911, 0xA911, 0xA111, 0xA112, 0xA111, 0xA111, 0xA111, 0xA111, 0x9972, 0x353B, 0x071F, 0x073F, 0x077F, 0x07BF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x2E3C, 0xA111, 0x9931, 0x9931, 0x9931, 0x9931, 0x8931, 0x410F, 0x410F, 0x38EE, 0x38EE, 0x30ED, 0x30ED, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x810F, 0x80EF, 0x810F, 0x810F, 0x810F, 0x810F, 0x890F, 0x890F, 0x890F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x8110, 0x8110, 0x8910, 0x8110, 0x8110, 0x8130, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8930, 0x8130, 0x8130, 0x8930, 0x8930, 0x790F, 0x690E, 0x50ED, 0x38CC, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x28AB, 0x20CB, 0x20CB, 0x20CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CD, 0x30CD, 0x30ED, 0x30ED, 0x30ED, 0x38EE, 0x390E, 0x390E, 0x390E, 0x410F, 0x410F, 0x412F, 0x4130, 0x4930, 0x4930, 0x8111, 0xA911, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA112, 0xA112, 0xA111, 0xA111, 0x4499, 0x077F, 0x079F, 0x07BF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x9931, 0xA111, 0x9931, 0x9931, 0x9931, 0x9931, 0x490F, 0x410F, 0x38EE, 0x30EE, 0x38ED, 0x30ED, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x90EF, 0x88EF, 0x80EF, 0x810F, 0x80EF, 0x80EF, 0x80EF, 0x810F, 0x810F, 0x890F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x890F, 0x890F, 0x810F, 0x8110, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8930, 0x8910, 0x8930, 0x8930, 0x8930, 0x8930, 0x8930, 0x8130, 0x710F, 0x60EE, 0x48ED, 0x38EC, 0x20AA, 0x20AA, 0x20CB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x28AB, 0x28AB, 0x20CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CC, 0x30CD, 0x30CD, 0x30ED, 0x30ED, 0x38ED, 0x310E, 0x38EE, 0x390E, 0x390E, 0x410F, 0x410F, 0x412F, 0x4930, 0x4930, 0x7131, 0xA111, 0xA111, 0xA112, 0xA111, 0xA0F1, 0xA111, 0xA111, 0xA112, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA131, 0x6397, 0x07BF, 0x07DF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x7AD4, 0x9931, 0x9931, 0x9931, 0x9931, 0x9912, 0x7130, 0x390F, 0x38EE, 0x38EE, 0x38ED, 0x30ED, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x28AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x990F, 0x990F, 0x910F, 0x910F, 0x890F, 0x88EF, 0x810F, 0x80EF, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x890F, 0x890F, 0x890F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x8910, 0x8110, 0x8110, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8930, 0x8910, 0x8910, 0x8910, 0x8930, 0x8930, 0x8130, 0x8930, 0x8930, 0x8930, 0x710F, 0x58EE, 0x48ED, 0x30CB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x20CB, 0x20CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30EC, 0x30EC, 0x30ED, 0x38EE, 0x30ED, 0x38ED, 0x390E, 0x38EE, 0x410E, 0x410F, 0x410F, 0x4930, 0x4930, 0x6931, 0xA111, 0xA111, 0xA112, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA112, 0x9931, 0x9911, 0x6397, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x5C14, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9131, 0x410F, 0x390E, 0x390E, 0x30ED, 0x30ED, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x28AB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x910F, 0x98EF, 0x910F, 0x910F, 0x98EF, 0x990F, 0x910F, 0x890F, 0x88EF, 0x80EF, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x890F, 0x810F, 0x810F, 0x810F, 0x890F, 0x890F, 0x810F, 0x810F, 0x8110, 0x8910, 0x8910, 0x8110, 0x8110, 0x8910, 0x8110, 0x8110, 0x8910, 0x8910, 0x8910, 0x8930, 0x8930, 0x8910, 0x8930, 0x8930, 0x8930, 0x8930, 0x8930, 0x8930, 0x8930, 0x8930, 0x8930, 0x8130, 0x710F, 0x58ED, 0x40ED, 0x30CB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x20CB, 0x20CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CD, 0x30ED, 0x30ED, 0x38ED, 0x30EE, 0x38EE, 0x390E, 0x390E, 0x410F, 0x410F, 0x4130, 0x4930, 0x5931, 0x7911, 0x9131, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0xA111, 0x9931, 0xA111, 0x9931, 0x5498, 0x07FF, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x35F5, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x510F, 0x390E, 0x390E, 0x38ED, 0x30ED, 0x30CC, 0x30CC, 0x28CC, 0x28CB, 0x28CB, 0x28AB, 0x20CB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x890F, 0x88EF, 0x88EF, 0x88EF, 0x88EF, 0x88EF, 0x88EF, 0x88EF, 0x88EF, 0x890F, 0x810F, 0x80EF, 0x80EF, 0x80EF, 0x80EF, 0x810F, 0x810F, 0x810F, 0x80EF, 0x810F, 0x810F, 0x810F, 0x810F, 0x890F, 0x890F, 0x890F, 0x890F, 0x890F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x890F, 0x8910, 0x8910, 0x8930, 0x8930, 0x8930, 0x8930, 0x8930, 0x8930, 0x8930, 0x8930, 0x8910, 0x8930, 0x8930, 0x8930, 0x8130, 0x68EF, 0x50ED, 0x40CC, 0x28CB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20CB, 0x28AB, 0x28CB, 0x20CB, 0x28AB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30CD, 0x30ED, 0x30ED, 0x38ED, 0x38EE, 0x38EE, 0x390E, 0x410F, 0x410F, 0x412F, 0x4130, 0x4930, 0x4930, 0x6131, 0x8931, 0xA111, 0xA111, 0xA111, 0xA131, 0xA111, 0xA111, 0x9931, 0xA111, 0xA111, 0xA111, 0xA111, 0x3D7A, 0x07FF, 0x07FF, 0x07FF, 0x07FE, 0x07F6, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x7911, 0x390E, 0x38EE, 0x30EE, 0x30ED, 0x30CD, 0x30CC, 0x28CC, 0x28CC, 0x28CB, 0x28AB, 0x28AB, 0x20AB, 0x20AB, 0x20CA, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x18AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x78EE, 0x78EE, 0x80EE, 0x80EE, 0x80EE, 0x78EE, 0x80EE, 0x80EE, 0x80EF, 0x80EF, 0x80EF, 0x80EE, 0x80EF, 0x810F, 0x80EF, 0x80EF, 0x80EF, 0x80EF, 0x810F, 0x80EF, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x890F, 0x890F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x890F, 0x890F, 0x8910, 0x8110, 0x8130, 0x8910, 0x810F, 0x8110, 0x810F, 0x8910, 0x8910, 0x8910, 0x8930, 0x8930, 0x8910, 0x8930, 0x8930, 0x8930, 0x8930, 0x8130, 0x8930, 0x8910, 0x8930, 0x8130, 0x8930, 0x8930, 0x8930, 0x8110, 0x690F, 0x50ED, 0x38CC, 0x28AB, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20CB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20CB, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20CA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x18AA, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20CA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x28CB, 0x20AB, 0x20CB, 0x20CB, 0x28CB, 0x28CB, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x28CC, 0x30CC, 0x30EC, 0x30ED, 0x30ED, 0x30ED, 0x38EE, 0x38EE, 0x390E, 0x390E, 0x410F, 0x410F, 0x410F, 0x4930, 0x4930, 0x5131, 0x6131, 0x9911, 0xA111, 0xA111, 0xA111, 0x9931, 0xA111, 0xA111, 0xA112, 0x9931, 0x9911, 0x9192, 0x1EBD, 0x07FF, 0x07FF, 0x07FE, 0x07F6, 0x7A71, 0x9931, 0x9931, 0x9932, 0x9931, 0x9931, 0x9111, 0x410E, 0x38EE, 0x30ED, 0x30ED, 0x30ED, 0x28CC, 0x28CC, 0x28CB, 0x28CB, 0x20AB, 0x28AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20CA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x208A, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, + 0x78EE, 0x78EE, 0x78EE, 0x78EE, 0x80EE, 0x78EE, 0x78EE, 0x80EE, 0x80EE, 0x80EF, 0x80EF, 0x80EE, 0x80EF, 0x80EF, 0x80EF, 0x80EF, 0x80EF, 0x810F, 0x810E, 0x810F, 0x80EF, 0x80EF, 0x80EF, 0x80EF, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x810F, 0x890F, 0x890F, 0x890F, 0x890F, 0x890F, 0x890F, 0x890F, 0x890F, 0x8110, 0x810F, 0x890F, 0x890F, 0x810F, 0x810F, 0x810F, 0x890F, 0x8910, 0x8910, 0x8910, 0x8910, 0x8910, 0x8130, 0x8910, 0x8930, 0x8130, 0x8930, 0x8930, 0x8910, 0x8910, 0x8130, 0x8930, 0x8930, 0x8930, 0x8930, 0x8130, 0x8130, 0x8930, 0x710F, 0x690E, 0x50ED, 0x38CC, 0x28AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20CB, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20CA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AA, 0x20CA, 0x20AA, 0x20AB, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AA, 0x20AB, 0x20AA, 0x20AB, 0x20AB, 0x20AC, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CC, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x20CD, 0x28CD, 0x28CD, 0x28CD, 0x28CD, 0x20CD, 0x28CE, 0x28CE, 0x28CE, 0x28EE, 0x28CE, 0x28EE, 0x30EE, 0x30EF, 0x30EF, 0x30EF, 0x390F, 0x390F, 0x3910, 0x3910, 0x4110, 0x4131, 0x4931, 0x4931, 0x4932, 0x4952, 0x5152, 0x9132, 0xA111, 0xA111, 0xA111, 0x9912, 0x9931, 0x9931, 0x9911, 0x9931, 0x9912, 0x8274, 0x07FF, 0x07FF, 0x07FD, 0x07F6, 0x5C32, 0x9911, 0x9931, 0x9932, 0x9931, 0x9931, 0x9931, 0x5910, 0x390F, 0x30EF, 0x30EF, 0x30EE, 0x30CE, 0x28CD, 0x28EE, 0x28ED, 0x28CD, 0x20CD, 0x20AC, 0x20CD, 0x20CD, 0x20AD, 0x20CD, 0x20AD, 0x20CC, 0x20CC, 0x20AD, 0x20CC, 0x20AC, 0x20CC, 0x20CC, 0x20AC, 0x20AC, 0x20CC, 0x20CC, 0x20CC, 0x20CC, 0x20CC, 0x20CC, 0x20CC, 0x20CC, 0x20CC, 0x20CC, 0x20CC, 0x20CC, 0x20CC, 0x20CD, 0x20AD, 0x18CC, 0x20CC, 0x20AC, 0x20CC, 0x20AD, 0x20CC, 0x20AC, 0x20AC, 0x20CC, 0x18CC, 0x18CC, 0x20CC, 0x20CC, 0x20CC, 0x20CC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x20AC, 0x18AC, 0x20AC, 0x20AC, 0x20AC, 0x20CC, 0x18AC, 0x18AC, 0x20AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AC, 0x18AB, 0x18AB, 0x18AB, 0x18AC, 0x18AC, 0x18AC, 0x18AB, + 0x78D0, 0x78D0, 0x78D0, 0x78F0, 0x78F0, 0x78F1, 0x78F0, 0x78F0, 0x78F0, 0x78F1, 0x78F1, 0x80F0, 0x78F1, 0x78F0, 0x80F1, 0x80D1, 0x80F1, 0x80F1, 0x80F1, 0x80F1, 0x80F0, 0x80F0, 0x80F0, 0x80F0, 0x80F0, 0x80F0, 0x80F0, 0x8111, 0x8110, 0x8110, 0x8110, 0x8111, 0x8111, 0x8111, 0x8111, 0x8111, 0x8110, 0x8110, 0x8110, 0x8111, 0x8911, 0x8110, 0x8110, 0x8111, 0x8110, 0x8911, 0x8911, 0x8911, 0x8111, 0x8911, 0x8911, 0x8910, 0x8911, 0x8911, 0x8911, 0x8911, 0x8111, 0x8131, 0x8131, 0x8931, 0x8911, 0x8911, 0x8911, 0x8911, 0x8931, 0x8911, 0x8131, 0x8131, 0x8931, 0x8130, 0x8131, 0x8911, 0x8931, 0x7931, 0x6111, 0x4911, 0x30D2, 0x18F2, 0x10F2, 0x18D2, 0x18D2, 0x10F2, 0x18D2, 0x10F2, 0x10F2, 0x10F2, 0x10F2, 0x10F2, 0x10F2, 0x10F2, 0x10F2, 0x10F2, 0x18D2, 0x18D2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18D2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F3, 0x18F3, 0x18F2, 0x20F2, 0x18F2, 0x18F2, 0x20F2, 0x18F3, 0x18F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F2, 0x18F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x2113, 0x20F3, 0x20F3, 0x2113, 0x20F3, 0x20F3, 0x2113, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x2113, 0x2113, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x2113, 0x20F3, 0x2113, 0x2113, 0x2113, 0x28F3, 0x28F3, 0x2113, 0x28F3, 0x28F3, 0x2913, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2113, 0x2913, 0x2914, 0x2113, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2914, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2913, 0x2913, 0x28F3, 0x28F3, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x28F3, 0x2913, 0x2113, 0x2913, 0x2914, 0x2913, 0x2913, 0x2914, 0x2914, 0x2914, 0x2914, 0x2914, 0x3134, 0x3134, 0x3134, 0x3134, 0x3134, 0x3934, 0x3934, 0x3935, 0x3955, 0x4155, 0x4155, 0x4176, 0x4176, 0x4976, 0x4977, 0x5176, 0x9132, 0xA111, 0xA111, 0x9931, 0x9911, 0xA111, 0x9931, 0x9931, 0x9912, 0x9931, 0x5C38, 0x07FF, 0x07FD, 0x07F6, 0x44F2, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x7933, 0x3955, 0x3135, 0x3134, 0x3114, 0x2133, 0x2113, 0x2113, 0x20F3, 0x20F3, 0x2113, 0x1912, 0x18F2, 0x20F3, 0x18F2, 0x18F3, 0x18F2, 0x18F3, 0x18F3, 0x18F3, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18D2, 0x18F2, 0x18D2, 0x10F2, 0x18F2, 0x18D2, 0x10F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x10F2, 0x10F2, 0x18F2, 0x18F2, 0x10F2, 0x10F2, 0x10F2, 0x10D2, 0x10D2, 0x10D2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, 0x10D2, 0x10D2, 0x10D2, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10B1, 0x10B1, 0x10B1, 0x10B1, 0x10D0, 0x10B0, 0x10D0, 0x10B0, 0x10B0, 0x10D0, 0x10B0, 0x08B0, 0x08B0, 0x08B0, 0x08B0, 0x08B0, + 0x0051, 0x0071, 0x0071, 0x0071, 0x0071, 0x0051, 0x0071, 0x0070, 0x0870, 0x0870, 0x0071, 0x0071, 0x0091, 0x0870, 0x0071, 0x0091, 0x0071, 0x0871, 0x0871, 0x0891, 0x0871, 0x0871, 0x0871, 0x0871, 0x0891, 0x0891, 0x0891, 0x0891, 0x0871, 0x0871, 0x0871, 0x0892, 0x0892, 0x0892, 0x0892, 0x0892, 0x0892, 0x0891, 0x0891, 0x0891, 0x0892, 0x0891, 0x0891, 0x08B1, 0x08B1, 0x08B1, 0x08B2, 0x10B2, 0x08B1, 0x08B2, 0x08B1, 0x08B2, 0x08B2, 0x08B2, 0x10B2, 0x10B2, 0x10B2, 0x10B2, 0x10B2, 0x08B2, 0x10B2, 0x10B2, 0x08B2, 0x08B2, 0x10B2, 0x10B2, 0x10B2, 0x10B2, 0x10B2, 0x10D2, 0x10D2, 0x10D2, 0x10F2, 0x10D2, 0x10D2, 0x10D2, 0x10D2, 0x10D2, 0x18D2, 0x18D2, 0x10F2, 0x18D2, 0x18D2, 0x10D2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18D2, 0x18F2, 0x18F2, 0x18D2, 0x18D2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F3, 0x18F3, 0x18F3, 0x18F3, 0x18F3, 0x18F2, 0x18F3, 0x18F3, 0x20F2, 0x18F3, 0x18F3, 0x18F3, 0x18F3, 0x18F3, 0x18F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x2112, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x2113, 0x20F2, 0x20F3, 0x20F2, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x20F3, 0x2113, 0x28F3, 0x2113, 0x20F3, 0x2113, 0x28F3, 0x20F3, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x28F3, 0x28F3, 0x2113, 0x2113, 0x2113, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2113, 0x2913, 0x2913, 0x2913, 0x2914, 0x2913, 0x2913, 0x28F3, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x28F3, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2113, 0x2913, 0x2913, 0x2914, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2913, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2113, 0x2913, 0x28F3, 0x28F3, 0x2913, 0x2113, 0x2913, 0x2913, 0x2113, 0x2113, 0x28F3, 0x2913, 0x2113, 0x2914, 0x2914, 0x2914, 0x2914, 0x2914, 0x2914, 0x2914, 0x2914, 0x3134, 0x3134, 0x3134, 0x3135, 0x3935, 0x3935, 0x3955, 0x3955, 0x4155, 0x4156, 0x4176, 0x4976, 0x4956, 0x5176, 0x9132, 0xA111, 0xA112, 0xA111, 0x9931, 0x9931, 0x9911, 0x9932, 0x9931, 0x9911, 0x2E5C, 0x07FC, 0x07F6, 0x2E53, 0x9931, 0x9931, 0x9931, 0x9911, 0x9911, 0x9931, 0x9132, 0x3134, 0x3134, 0x3134, 0x2934, 0x2914, 0x2913, 0x2113, 0x2113, 0x20F3, 0x2112, 0x20F3, 0x20D3, 0x1912, 0x18F2, 0x18F3, 0x18F2, 0x18F2, 0x18F2, 0x18D2, 0x18F2, 0x20F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18D2, 0x18D2, 0x18D2, 0x18D2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x18D2, 0x18F2, 0x18F2, 0x18F2, 0x18F2, 0x10F2, 0x10F2, 0x18F2, 0x18F2, 0x18D2, 0x18F2, 0x10F2, 0x18F2, 0x18D2, 0x10F2, 0x18F2, 0x10F2, 0x10F2, 0x10F2, 0x10F2, 0x10F2, 0x10F2, 0x10D2, 0x10D2, 0x10F2, 0x10F2, 0x10D2, 0x10D2, 0x10D2, 0x10D2, 0x10D2, 0x10D2, 0x10D2, 0x10D1, 0x10D1, 0x10D2, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10D1, 0x10B0, 0x10B0, 0x10B0, 0x10B0, 0x10B0, 0x10B0, 0x10B0, 0x10B0, 0x08B0, 0x10B0, 0x10B0, 0x08B0, 0x08B0, 0x10B0, 0x10D0, 0x08D0, 0x08B0, 0x08B0, 0x08B0, 0x08B0, + 0x0CDC, 0x0CDC, 0x0CDB, 0x0CDC, 0x0CFB, 0x0CDC, 0x14DC, 0x14FC, 0x0CDC, 0x14FC, 0x14DC, 0x0CFC, 0x0CFC, 0x14FC, 0x0CFC, 0x14FC, 0x14FC, 0x14FC, 0x14FC, 0x14FC, 0x14FC, 0x14FC, 0x151C, 0x151C, 0x151C, 0x151C, 0x151C, 0x151C, 0x151C, 0x151C, 0x151C, 0x151C, 0x151C, 0x151C, 0x151C, 0x151C, 0x151C, 0x151C, 0x153C, 0x153C, 0x153C, 0x153C, 0x151C, 0x153C, 0x153C, 0x153C, 0x153C, 0x153C, 0x153C, 0x153C, 0x153C, 0x153C, 0x153C, 0x155C, 0x153C, 0x153C, 0x1D5C, 0x1D5C, 0x1D5C, 0x155C, 0x155C, 0x155C, 0x1D5C, 0x1D5C, 0x1D5C, 0x1D5C, 0x1D5C, 0x155C, 0x1D5C, 0x1D5C, 0x1D5C, 0x1D5C, 0x1D5C, 0x1D5C, 0x1D5C, 0x1D5C, 0x157C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D9C, 0x1D9C, 0x1D9C, 0x1D9C, 0x1D9C, 0x1D9C, 0x1D9C, 0x1D9C, 0x1D9D, 0x1D9D, 0x1D9D, 0x1D9D, 0x259C, 0x1DBC, 0x1D9D, 0x259D, 0x1D9C, 0x259C, 0x259C, 0x259C, 0x259C, 0x259C, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25BD, 0x25DD, 0x25DD, 0x25BD, 0x25BD, 0x1DDD, 0x25DD, 0x25DD, 0x25DD, 0x25BD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25DD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x2DFD, 0x25FD, 0x25FD, 0x25FD, 0x25FD, 0x2DFD, 0x2DFD, 0x2DFD, 0x2DFD, 0x2DFD, 0x25FD, 0x2DFE, 0x2DFD, 0x2DFD, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E3E, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E3D, 0x2E3D, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3D, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x365E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E3E, 0x365E, 0x365E, 0x2E5D, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E5E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3E, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3E, 0x2E3D, 0x2E3E, 0x2E3D, 0x363D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E3D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x2E1D, 0x361D, 0x361D, 0x361D, 0x361D, 0x361D, 0x3E1D, 0x3E1D, 0x3E1D, 0x3E1D, 0x3E1D, 0x3E1E, 0x461E, 0x461D, 0x4DFE, 0x4DFD, 0x4E3E, 0x4DFE, 0x55DD, 0x9214, 0x9931, 0x9931, 0x9931, 0x9932, 0x9931, 0x9911, 0x9911, 0x9931, 0x7A74, 0x07FB, 0x07F6, 0x07F6, 0x9931, 0x9931, 0x9911, 0x9932, 0x9931, 0x9931, 0x9931, 0x4CFB, 0x3DFE, 0x35DD, 0x35DD, 0x2DDD, 0x2DDD, 0x2DDD, 0x2DDD, 0x25DD, 0x25DD, 0x25BD, 0x25BD, 0x25DD, 0x25DD, 0x25BD, 0x25DC, 0x25BD, 0x25BD, 0x25BD, 0x1DBD, 0x25BC, 0x1DBD, 0x1DBD, 0x1DBC, 0x1DBC, 0x1DBC, 0x1DBC, 0x1DBC, 0x1DBC, 0x1D9D, 0x1D9D, 0x1D9D, 0x1D9D, 0x1D9D, 0x1D9D, 0x1D9D, 0x1D9C, 0x1D9C, 0x1DBC, 0x1D9C, 0x1D9C, 0x1D9C, 0x1D9C, 0x1D9D, 0x1D9C, 0x1D9D, 0x1D9C, 0x1D7C, 0x1D7C, 0x1D7D, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D7C, 0x1D5C, 0x1D5C, 0x1D5C, 0x1D5C, 0x1D5C, 0x1D5C, 0x157C, 0x1D5C, 0x1D5C, 0x1D5C, 0x1D5C, 0x1D5C, 0x1D5C, 0x155C, 0x155C, 0x155C, 0x1D5C, 0x153C, 0x153C, 0x153C, 0x153C, 0x153C, 0x153C, 0x153C, 0x153C, 0x153C, 0x153C, 0x153C, 0x153C, 0x153C, 0x153C, 0x153C, 0x153C, 0x153C, 0x151C, 0x151C, 0x151C, 0x151C, 0x151C, 0x151B, 0x151B, 0x151B, 0x151C, 0x151C, 0x151C, 0x151C, 0x151C, 0x151C, 0x151C, 0x151C, + 0x0BFB, 0x0BFB, 0x0BFB, 0x0BFB, 0x0BFB, 0x0C1B, 0x0C1B, 0x0C1B, 0x0C1B, 0x141B, 0x141B, 0x145B, 0x14DC, 0x0CDB, 0x14BC, 0x143B, 0x141B, 0x0C1B, 0x0C1B, 0x141C, 0x141B, 0x141B, 0x141B, 0x141B, 0x141B, 0x141B, 0x143B, 0x143B, 0x143B, 0x143B, 0x143B, 0x143B, 0x143B, 0x143B, 0x143B, 0x143B, 0x143B, 0x143B, 0x143B, 0x143B, 0x143C, 0x143B, 0x145B, 0x151C, 0x0D1B, 0x151C, 0x145B, 0x143B, 0x145C, 0x143B, 0x145C, 0x1C5B, 0x143B, 0x145C, 0x145C, 0x145C, 0x145C, 0x145C, 0x145B, 0x145C, 0x145B, 0x145B, 0x1C5C, 0x145C, 0x147C, 0x147C, 0x147C, 0x145C, 0x1C7C, 0x1C5C, 0x147C, 0x147C, 0x1C7C, 0x1CDC, 0x1D5C, 0x155C, 0x1CBC, 0x1C7C, 0x1C7C, 0x1C7C, 0x1C7C, 0x1C7C, 0x1C7C, 0x1C7B, 0x1C7C, 0x1C7C, 0x1C7C, 0x1C7C, 0x1C7C, 0x1C7C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x249C, 0x1C9C, 0x1D9D, 0x1D7C, 0x1CFC, 0x1C9C, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x24BC, 0x1CBC, 0x1CBC, 0x24BC, 0x24BC, 0x24BC, 0x1CBC, 0x24DC, 0x24DC, 0x24DC, 0x253D, 0x25BD, 0x253D, 0x24DD, 0x24BC, 0x24BC, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24DD, 0x24FD, 0x24DC, 0x24DC, 0x24FD, 0x24FD, 0x24FC, 0x24DD, 0x24FD, 0x251C, 0x25FD, 0x255D, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x24FC, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x24FD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x251D, 0x24FD, 0x24FD, 0x251D, 0x2D1D, 0x24FD, 0x2CFD, 0x25BD, 0x25BD, 0x253C, 0x2CFC, 0x2D1D, 0x251D, 0x2CFD, 0x2CFD, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1C, 0x2D5D, 0x2DDE, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D1D, 0x2D3D, 0x2D1D, 0x2D1D, 0x2E1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D3D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2DDD, 0x2D5D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2D1D, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2D1D, 0x2D1D, 0x2CFD, 0x2CFD, 0x2CFD, 0x2DBD, 0x2DBD, 0x2CFD, 0x2D1D, 0x251C, 0x251C, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x2CFD, 0x34FD, 0x34FD, 0x34FD, 0x34FD, 0x34FD, 0x3CFD, 0x3CFD, 0x3CFD, 0x3CFD, 0x3D1D, 0x451D, 0x451D, 0x451D, 0x4D1D, 0x4D1D, 0x553D, 0x91B3, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0xA112, 0x9931, 0x9931, 0x5496, 0x07F7, 0x07F7, 0x8A13, 0xA111, 0x9931, 0x9931, 0x9912, 0x9932, 0x9911, 0x6318, 0x34DD, 0x34DD, 0x2CDD, 0x2CDC, 0x2CDD, 0x2CBC, 0x24DC, 0x24BC, 0x24BC, 0x253C, 0x25BD, 0x253C, 0x24BC, 0x24BC, 0x24BC, 0x1CBC, 0x24BC, 0x1CBC, 0x1CBC, 0x24BC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1CBC, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C7C, 0x1C9C, 0x1CDC, 0x1D7C, 0x1D5C, 0x1C9C, 0x1C9C, 0x1C7B, 0x1C7C, 0x1C9C, 0x1C7B, 0x1C9C, 0x1C9C, 0x1C9C, 0x1C7C, 0x1C9C, 0x1C7C, 0x1C7C, 0x1C7C, 0x1C7C, 0x147C, 0x147C, 0x147C, 0x1C7C, 0x1C7C, 0x1C7C, 0x1C7C, 0x1C7C, 0x1C7C, 0x1C7C, 0x1C7C, 0x1C5C, 0x1C9C, 0x153C, 0x155C, 0x14BC, 0x145B, 0x145B, 0x1C5C, 0x147B, 0x145B, 0x145B, 0x145B, 0x145B, 0x145B, 0x145B, 0x145B, 0x145C, 0x145C, 0x143B, 0x143B, 0x143B, 0x143B, 0x143B, 0x143B, 0x143B, 0x143B, 0x143B, 0x143B, 0x143B, 0x143B, 0x143B, 0x143B, 0x151C, 0x14FB, 0x14FC, 0x145B, 0x143B, 0x143B, 0x141B, 0x141B, 0x141B, 0x141B, 0x141B, 0x141B, + 0x0A5A, 0x0A5A, 0x0A5A, 0x0A5A, 0x0A7A, 0x0A5A, 0x0AFA, 0x0C1B, 0x0CBB, 0x0C9B, 0x0B9B, 0x0A9A, 0x125A, 0x0A7A, 0x0A7A, 0x0A7A, 0x0A7A, 0x127A, 0x127A, 0x0A7A, 0x127A, 0x127A, 0x127A, 0x127A, 0x127A, 0x127A, 0x127A, 0x127A, 0x127A, 0x127A, 0x127A, 0x127A, 0x127A, 0x127A, 0x127A, 0x129A, 0x129A, 0x129A, 0x133B, 0x145B, 0x0D1C, 0x149C, 0x131B, 0x129B, 0x129B, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129B, 0x129A, 0x129B, 0x129B, 0x129B, 0x129B, 0x129B, 0x129B, 0x129A, 0x129B, 0x1ABB, 0x129B, 0x131B, 0x147C, 0x153B, 0x145C, 0x12FB, 0x1ABB, 0x12BA, 0x1ABB, 0x1ABB, 0x12BB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1B3B, 0x1CFC, 0x157C, 0x1C1C, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x22DB, 0x22DB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x22DB, 0x22DB, 0x22FB, 0x231C, 0x1D1C, 0x1D5C, 0x235B, 0x22DC, 0x22DB, 0x22DC, 0x22FB, 0x22FC, 0x22DC, 0x22DC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FB, 0x22FB, 0x22FB, 0x22FB, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x231B, 0x22FC, 0x233C, 0x253C, 0x1CFD, 0x22FC, 0x22FC, 0x22FB, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x22FC, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x2AFC, 0x2AFC, 0x231C, 0x2B1C, 0x2B1C, 0x259C, 0x247C, 0x231C, 0x231C, 0x2B1C, 0x231C, 0x231C, 0x2B1C, 0x231C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x25BD, 0x2BBC, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x231C, 0x2B1C, 0x2B1C, 0x25DD, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x231C, 0x2B1C, 0x2B7C, 0x259D, 0x2B1C, 0x2B1C, 0x231C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x231C, 0x245D, 0x259C, 0x22FC, 0x2AFC, 0x231C, 0x2AFC, 0x22FC, 0x231C, 0x231C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2B1C, 0x2AFC, 0x2B1C, 0x2B1C, 0x2B1C, 0x331C, 0x331C, 0x331C, 0x331C, 0x331C, 0x3B1C, 0x3B3D, 0x3B3D, 0x3B3D, 0x433C, 0x433D, 0x4B3D, 0x435D, 0x5A9A, 0x9932, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x1737, 0x07F9, 0x72D4, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x8194, 0x331C, 0x32FC, 0x2AFB, 0x2AFC, 0x2AFB, 0x22FB, 0x22DC, 0x22DC, 0x22FB, 0x22DB, 0x22DB, 0x235C, 0x1D5C, 0x1D1D, 0x231B, 0x1ADB, 0x1ADB, 0x1ADB, 0x22DB, 0x1ABB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ABB, 0x1ABB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ADB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ADB, 0x1BFC, 0x1D5C, 0x14DC, 0x1B3B, 0x1ABB, 0x1ADB, 0x1ABB, 0x1ABB, 0x12DB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x1ABB, 0x129B, 0x12BB, 0x129A, 0x12BA, 0x129A, 0x12DB, 0x143B, 0x151B, 0x14BB, 0x1AFB, 0x12BA, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x129A, 0x127A, 0x127A, 0x127A, 0x131B, 0x147C, 0x14DB, 0x145B, 0x131A, 0x127A, 0x127A, 0x127A, 0x127A, + 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B5A, 0x0C1B, 0x0C9B, 0x0C9B, 0x0BBA, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0B3A, 0x0B3B, 0x0B3A, 0x0B3A, 0x0B3B, 0x133B, 0x0B3B, 0x0B3B, 0x0B3B, 0x133A, 0x0B3A, 0x0C3B, 0x14DC, 0x14BC, 0x13FB, 0x0B3A, 0x133B, 0x133B, 0x133B, 0x135B, 0x0B5B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135A, 0x135B, 0x135B, 0x0B5A, 0x135B, 0x135B, 0x135B, 0x135B, 0x0B5B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x13FB, 0x151C, 0x14FC, 0x13DB, 0x135B, 0x137B, 0x137B, 0x137B, 0x137B, 0x135B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x1B7B, 0x137B, 0x1B5B, 0x1B7B, 0x137B, 0x137B, 0x137B, 0x139B, 0x1BBB, 0x14FB, 0x153C, 0x13FB, 0x1B7B, 0x139B, 0x1B7B, 0x1B7C, 0x1B9B, 0x1B7B, 0x1B7B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9C, 0x1B9B, 0x1B9B, 0x1B9B, 0x139C, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9C, 0x1B9B, 0x1D3C, 0x1D5C, 0x1BFB, 0x1B9C, 0x1BBB, 0x1B9B, 0x1BBC, 0x1B9B, 0x1B9B, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBC, 0x1BBB, 0x1CDC, 0x1D7D, 0x23FC, 0x1BDC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x1BBC, 0x1BBC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23BC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x247C, 0x1D9C, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x241C, 0x259D, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x1DBD, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x1DBD, 0x243C, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x23BC, 0x23DC, 0x23DC, 0x259C, 0x247C, 0x23BC, 0x23BC, 0x23DC, 0x23BC, 0x23DC, 0x23DC, 0x23BC, 0x23BC, 0x23BC, 0x23DC, 0x23DC, 0x23DC, 0x23DC, 0x2BDC, 0x2BDC, 0x2BDC, 0x2BDC, 0x2BDC, 0x33DC, 0x33DC, 0x33DC, 0x33DC, 0x3BDC, 0x3BFC, 0x3BFC, 0x3BDC, 0x43FC, 0x43FD, 0x6B18, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9932, 0x9931, 0x6B53, 0x07FA, 0x5437, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9912, 0x9931, 0x2BBC, 0x2BBC, 0x2BBC, 0x2BBB, 0x23BB, 0x23BB, 0x239B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1BDB, 0x1D5C, 0x1D1C, 0x1B9B, 0x1B9B, 0x139B, 0x139C, 0x1B9B, 0x1B7B, 0x1B7B, 0x139B, 0x1B9B, 0x1B9B, 0x1B7B, 0x1B9B, 0x139B, 0x1B7B, 0x1B7B, 0x1B9B, 0x1B9B, 0x137B, 0x137B, 0x137B, 0x137B, 0x1B9B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x139B, 0x1BBB, 0x151C, 0x151C, 0x13DB, 0x137B, 0x137B, 0x135B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x135B, 0x135B, 0x135B, 0x137B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135A, 0x135B, 0x133B, 0x13DA, 0x14FB, 0x0CFB, 0x141B, 0x133A, 0x135B, 0x133B, 0x135B, 0x135B, 0x135A, 0x135B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133A, 0x133B, 0x0B5B, 0x133B, 0x133A, 0x0B3A, 0x133A, 0x133A, 0x0B3B, 0x0B3B, 0x0B3B, 0x0B3A, 0x133A, 0x0B1A, 0x0B3B, 0x0B3A, 0x0BDA, 0x14BB, 0x0CBB, 0x0C1B, 0x0B3A, 0x0B3B, 0x0B3A, + 0x0BDB, 0x0C7B, 0x0C7B, 0x0C1A, 0x0B3A, 0x0B1A, 0x0AFA, 0x0AFA, 0x0AFA, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0C1B, 0x0CBB, 0x0C9B, 0x0BBB, 0x0B5A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B1A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x133A, 0x133A, 0x133A, 0x0B3A, 0x133B, 0x0B3A, 0x133A, 0x0B3A, 0x133A, 0x0B3A, 0x135A, 0x133A, 0x133B, 0x133A, 0x133B, 0x0B3A, 0x0C7B, 0x0CFB, 0x147B, 0x137B, 0x0B5B, 0x0B5B, 0x135A, 0x135A, 0x135B, 0x135A, 0x135A, 0x135A, 0x135A, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x137B, 0x135A, 0x135A, 0x137B, 0x135A, 0x135B, 0x139B, 0x14BB, 0x14FB, 0x13FB, 0x137B, 0x137B, 0x135B, 0x137B, 0x137A, 0x137A, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x1B7B, 0x1B7B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x1BBB, 0x153C, 0x151C, 0x1B7B, 0x139B, 0x137B, 0x139B, 0x139B, 0x1B9B, 0x139B, 0x1B9B, 0x1B9B, 0x139B, 0x139B, 0x139B, 0x139B, 0x139B, 0x139B, 0x139B, 0x139B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x13BB, 0x139B, 0x1B9B, 0x139B, 0x1B9B, 0x1B9B, 0x1B9C, 0x1C3B, 0x1D5C, 0x1C3C, 0x1B9B, 0x1BBB, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1B9B, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBC, 0x1BBB, 0x1BBB, 0x1C9C, 0x1D1C, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BDB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1CFC, 0x1C7C, 0x1BBB, 0x1BDB, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBB, 0x1BDC, 0x23BC, 0x1BBB, 0x1D7C, 0x1BBB, 0x1BDC, 0x1BBB, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBC, 0x1B9C, 0x1BDC, 0x1BBB, 0x1C5B, 0x1CFB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBB, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBC, 0x1BBB, 0x1BBB, 0x1BBB, 0x1B9B, 0x1D3C, 0x1CBC, 0x1BBB, 0x1BBB, 0x1B9B, 0x1B9C, 0x1B9C, 0x1B9B, 0x1B9B, 0x1BBB, 0x1B9C, 0x1B9B, 0x1BBB, 0x239B, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x23BC, 0x2BBC, 0x2BBC, 0x2BBC, 0x2BBC, 0x33BC, 0x33BC, 0x33DC, 0x3BDC, 0x3BDC, 0x3BDC, 0x3BDC, 0x8194, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9911, 0x9931, 0x2659, 0x4C98, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x4B19, 0x23BC, 0x239B, 0x239B, 0x239B, 0x1B9B, 0x1B9B, 0x1B9B, 0x1B7B, 0x1B7B, 0x1B7B, 0x1B7B, 0x137B, 0x137B, 0x137B, 0x14BB, 0x151B, 0x13DB, 0x137B, 0x137A, 0x137B, 0x137B, 0x137A, 0x137B, 0x137B, 0x137B, 0x135B, 0x137B, 0x135B, 0x135B, 0x135B, 0x137B, 0x137B, 0x137B, 0x137B, 0x137B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135A, 0x135B, 0x135A, 0x13BB, 0x14DB, 0x14BB, 0x137B, 0x135A, 0x135B, 0x0B5A, 0x135B, 0x135B, 0x135A, 0x0B5A, 0x135A, 0x135B, 0x135A, 0x135A, 0x135A, 0x135A, 0x0B5A, 0x0B5A, 0x135A, 0x133A, 0x135A, 0x133A, 0x0B3A, 0x133B, 0x133A, 0x0B3A, 0x133B, 0x133B, 0x133A, 0x0B3A, 0x0B3A, 0x0C5B, 0x0CBB, 0x0C5B, 0x0B7A, 0x0B3A, 0x0B3B, 0x0B1A, 0x133B, 0x0B3A, 0x0B1A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B1A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B9A, 0x0C9B, 0x0C9B, + 0x0BDA, 0x02F9, 0x01F9, 0x0978, 0x0978, 0x0978, 0x0978, 0x0978, 0x0978, 0x0979, 0x0979, 0x0978, 0x0979, 0x0979, 0x0979, 0x0979, 0x0178, 0x0178, 0x0979, 0x0979, 0x0979, 0x0978, 0x0979, 0x0178, 0x0979, 0x0978, 0x0979, 0x0979, 0x0979, 0x0979, 0x0A1A, 0x0B1A, 0x0C3A, 0x0C1B, 0x0ADA, 0x09F9, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0999, 0x0999, 0x0979, 0x0999, 0x0999, 0x0979, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x09F9, 0x0B1A, 0x0C7B, 0x0C1B, 0x0ABA, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x1199, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x1199, 0x11BA, 0x11BA, 0x11B9, 0x09B9, 0x11BA, 0x1199, 0x11BA, 0x11BA, 0x1199, 0x11DA, 0x0B3A, 0x0C9B, 0x0BFB, 0x127A, 0x11BA, 0x119A, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x119A, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x119A, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x12BA, 0x14BB, 0x13FB, 0x11DB, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11DA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BB, 0x11BA, 0x11DA, 0x11BA, 0x11DA, 0x11BA, 0x11BA, 0x11DA, 0x11BA, 0x127A, 0x14DB, 0x137B, 0x11DA, 0x19BA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x19DA, 0x19DA, 0x19DA, 0x11DA, 0x11DB, 0x11DB, 0x11DB, 0x11DB, 0x11DB, 0x11DB, 0x11DB, 0x19DB, 0x11DA, 0x19DA, 0x1A3B, 0x14FB, 0x1AFB, 0x19DA, 0x11DB, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DA, 0x19DB, 0x19DA, 0x1A1B, 0x153C, 0x1A3B, 0x19DA, 0x19DA, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DB, 0x19DB, 0x19DA, 0x19DB, 0x153B, 0x19DB, 0x19DA, 0x19DB, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x19DA, 0x11DB, 0x19DB, 0x19DA, 0x19DB, 0x19FB, 0x153C, 0x123A, 0x19DA, 0x19DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x11DA, 0x19DA, 0x11DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x19DB, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x19DB, 0x19BA, 0x11DA, 0x11BA, 0x1ABB, 0x14FB, 0x1A5B, 0x19BA, 0x19BA, 0x11DA, 0x11DA, 0x19DB, 0x19DB, 0x19DA, 0x19DB, 0x19BA, 0x19DA, 0x19DA, 0x19DB, 0x19DB, 0x19DB, 0x21DB, 0x21DB, 0x21DB, 0x21FB, 0x21FB, 0x29FB, 0x29FB, 0x29FB, 0x29FB, 0x31FB, 0x321B, 0x31FB, 0x321B, 0x41FA, 0x9912, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9912, 0x72D4, 0x4C98, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x5996, 0x21DB, 0x21DA, 0x19DA, 0x19DA, 0x19DA, 0x11DA, 0x11DA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11D9, 0x137A, 0x149B, 0x131A, 0x11BA, 0x119A, 0x11B9, 0x11BA, 0x11BA, 0x119A, 0x11BA, 0x119A, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x11BA, 0x0999, 0x1199, 0x1199, 0x1199, 0x1199, 0x11BA, 0x11BA, 0x1199, 0x0999, 0x09B9, 0x0999, 0x0A1A, 0x0BFB, 0x0C9B, 0x131A, 0x09DA, 0x119A, 0x0999, 0x0999, 0x0999, 0x1199, 0x099A, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0ABA, 0x0BDA, 0x0C5B, 0x0B3A, 0x09F9, 0x0999, 0x0979, 0x0999, 0x0999, 0x0999, 0x0999, 0x0999, 0x0979, 0x0979, 0x0979, 0x0999, 0x0979, 0x0999, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0978, 0x0979, 0x0979, 0x0178, 0x0199, 0x0179, 0x0979, 0x0999, 0x02B9, + 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x0AB9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x0AB9, 0x02B9, 0x02B9, 0x02D9, 0x02D9, 0x02B9, 0x0AB9, 0x0AD9, 0x02D9, 0x0AD9, 0x0AB9, 0x0AB9, 0x03BA, 0x043A, 0x043A, 0x0359, 0x02D9, 0x0AD9, 0x02D9, 0x0AD9, 0x02D9, 0x02D9, 0x0AD9, 0x0AD9, 0x0AD9, 0x02D9, 0x0AD9, 0x02D9, 0x02D9, 0x0ADA, 0x0AFA, 0x02FA, 0x02FA, 0x02D9, 0x02FA, 0x0ADA, 0x0AFA, 0x02FA, 0x0AFA, 0x0AFA, 0x0AD9, 0x0AFA, 0x0ADA, 0x0AFA, 0x0B5A, 0x0C5B, 0x047A, 0x0BBA, 0x0AF9, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AF9, 0x0AF9, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0B1A, 0x0B1A, 0x0AFA, 0x0AFA, 0x0B1A, 0x0AFA, 0x0B1A, 0x0AFA, 0x0B1A, 0x0B1A, 0x0C3A, 0x0C9A, 0x0BDA, 0x0B1A, 0x0AFA, 0x0AFA, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0BDB, 0x14BB, 0x0BFA, 0x0B1A, 0x0B1A, 0x0B3A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0B3A, 0x131A, 0x0B3A, 0x0B1A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x133B, 0x133B, 0x133A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x0B3A, 0x133A, 0x0B3A, 0x137A, 0x0CDB, 0x0C5B, 0x133B, 0x133B, 0x0B3A, 0x133A, 0x133A, 0x133A, 0x133A, 0x133A, 0x133A, 0x133A, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x135B, 0x135B, 0x135B, 0x135B, 0x133B, 0x133B, 0x135A, 0x0B5B, 0x133B, 0x143A, 0x147B, 0x135B, 0x135A, 0x133B, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135A, 0x13BB, 0x14DB, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135A, 0x135B, 0x133B, 0x14FB, 0x135A, 0x135B, 0x135A, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135B, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x135A, 0x133A, 0x135B, 0x135A, 0x135B, 0x135B, 0x149B, 0x13FB, 0x133A, 0x135B, 0x135B, 0x135A, 0x135A, 0x135A, 0x135B, 0x135B, 0x135B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133B, 0x133A, 0x133B, 0x133A, 0x135A, 0x133A, 0x143B, 0x147B, 0x133A, 0x133A, 0x133A, 0x133A, 0x133B, 0x133A, 0x133A, 0x133B, 0x133A, 0x133A, 0x133A, 0x135B, 0x133B, 0x133B, 0x1B3B, 0x1B5B, 0x1B5B, 0x1B3B, 0x1B5B, 0x235B, 0x235B, 0x235B, 0x235B, 0x2B5B, 0x2B5B, 0x2B7B, 0x2B7B, 0x335B, 0x7235, 0x9911, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x72D5, 0x9932, 0x9932, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x71B4, 0x1B3B, 0x1B3B, 0x133A, 0x133B, 0x133A, 0x131A, 0x131A, 0x131A, 0x131A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0AFA, 0x0B1A, 0x0AFA, 0x0BDA, 0x0CBB, 0x0BDA, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0B1A, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0BBA, 0x049B, 0x0C3A, 0x0B3A, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x02FA, 0x0AFA, 0x0ADA, 0x0ADA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x02DA, 0x0ADA, 0x0ADA, 0x0ADA, 0x02D9, 0x02D9, 0x02DA, 0x02FA, 0x02D9, 0x0AD9, 0x0AD9, 0x0B5A, 0x045A, 0x045A, 0x033A, 0x0AD9, 0x02D9, 0x02D9, 0x02DA, 0x0ADA, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x0AB9, 0x0AB9, 0x02D9, 0x02D9, 0x0AB9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x0AB9, 0x02B9, 0x02D9, 0x02B9, 0x02D9, 0x0AB9, + 0x0299, 0x0299, 0x0298, 0x0298, 0x0298, 0x0299, 0x0299, 0x0299, 0x0299, 0x0298, 0x0299, 0x0299, 0x0299, 0x0299, 0x0299, 0x0299, 0x0299, 0x0299, 0x0299, 0x0299, 0x0299, 0x02B8, 0x02B9, 0x0299, 0x02B8, 0x039A, 0x041A, 0x03FA, 0x0339, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02D9, 0x02B9, 0x02B9, 0x02D9, 0x02B9, 0x02D9, 0x03BA, 0x043A, 0x03FA, 0x02F9, 0x02D9, 0x02D9, 0x0AB9, 0x0AB9, 0x02D9, 0x02B9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x0AD9, 0x0AD9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02F9, 0x02D9, 0x02DA, 0x0ADA, 0x0AFA, 0x0BFA, 0x0C5B, 0x0BFA, 0x0AD9, 0x02FA, 0x02F9, 0x02F9, 0x0AF9, 0x02F9, 0x0AF9, 0x02D9, 0x02F9, 0x0AF9, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AF9, 0x0AFA, 0x0AFA, 0x0AFA, 0x0C1A, 0x0C7B, 0x0B5A, 0x0AFA, 0x0AF9, 0x0B1A, 0x0AFA, 0x0AFA, 0x0AFA, 0x0B1A, 0x0AFA, 0x0AFA, 0x0B1A, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0B1A, 0x0B1A, 0x0B1A, 0x031A, 0x0AFA, 0x0B1A, 0x0B1A, 0x0AFA, 0x0B1A, 0x0B1A, 0x0B1A, 0x0AFA, 0x0C3A, 0x0C5A, 0x0B1A, 0x0AFA, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0C5B, 0x0C1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B3A, 0x0C7B, 0x0B7A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0CBB, 0x0B1A, 0x0B3A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B7A, 0x0CBB, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0BDA, 0x0C7B, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x0B1A, 0x131A, 0x131A, 0x131A, 0x131A, 0x131A, 0x1B1A, 0x1B3A, 0x1B3A, 0x1B3A, 0x1B3A, 0x233A, 0x233A, 0x233B, 0x2B3B, 0x2B5B, 0x3AD9, 0x9931, 0x9931, 0x9931, 0x9912, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x8993, 0x1B1A, 0x131A, 0x131A, 0x12FA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x0AFA, 0x02FA, 0x0AFA, 0x035A, 0x045A, 0x0C3A, 0x0AFA, 0x02DA, 0x0AFA, 0x0AF9, 0x02F9, 0x0AFA, 0x0AFA, 0x0AFA, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x0AD9, 0x02D9, 0x02DA, 0x0AD9, 0x0AD9, 0x02BA, 0x02D9, 0x039A, 0x043A, 0x03DA, 0x02D9, 0x0AB9, 0x02D9, 0x0AB9, 0x02B9, 0x02D9, 0x02B9, 0x02B9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02D9, 0x02B9, 0x0AB9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02D9, 0x02B9, 0x02D9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x02D9, 0x03FA, 0x041A, 0x03B9, 0x02B9, 0x02B9, 0x0299, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x0299, 0x02B9, 0x02B9, 0x02B9, 0x02B9, 0x0299, 0x02B9, 0x02B9, 0x0299, 0x0299, 0x0299, 0x0299, 0x0299, 0x0299, 0x0299, 0x02B8, 0x02B8, + 0x0117, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0117, 0x0137, 0x0137, 0x0137, 0x0117, 0x0117, 0x0137, 0x0137, 0x0137, 0x0117, 0x0117, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0198, 0x02B8, 0x0399, 0x0359, 0x0258, 0x0198, 0x0137, 0x0137, 0x0117, 0x0158, 0x0137, 0x0137, 0x0138, 0x0137, 0x0138, 0x0138, 0x0137, 0x0137, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0137, 0x0138, 0x0138, 0x0137, 0x0158, 0x0259, 0x0399, 0x0399, 0x0258, 0x0158, 0x0158, 0x0138, 0x0138, 0x0158, 0x0138, 0x0158, 0x0137, 0x0138, 0x0158, 0x0138, 0x0138, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0138, 0x0158, 0x0158, 0x0158, 0x0138, 0x0238, 0x03B9, 0x03DA, 0x0259, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0138, 0x0178, 0x0158, 0x0158, 0x0159, 0x01B9, 0x037A, 0x0BDA, 0x0218, 0x0958, 0x0159, 0x0159, 0x0958, 0x0158, 0x0158, 0x0158, 0x0158, 0x0958, 0x0959, 0x0158, 0x0159, 0x0179, 0x0158, 0x0159, 0x0159, 0x0159, 0x0159, 0x0158, 0x0158, 0x0158, 0x0158, 0x0979, 0x0179, 0x0958, 0x0979, 0x0159, 0x0178, 0x0159, 0x0958, 0x033A, 0x041A, 0x01F9, 0x0959, 0x0179, 0x0958, 0x0959, 0x0158, 0x0159, 0x0159, 0x0159, 0x0159, 0x0979, 0x0979, 0x0979, 0x0979, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0979, 0x0979, 0x0959, 0x0959, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0A79, 0x043A, 0x0199, 0x0959, 0x0179, 0x0179, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0979, 0x0179, 0x09B9, 0x0C3B, 0x0179, 0x0979, 0x0179, 0x0179, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0179, 0x0979, 0x0179, 0x0C7A, 0x0979, 0x0179, 0x0179, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0979, 0x0979, 0x0979, 0x0979, 0x0BFA, 0x0259, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0959, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0179, 0x0958, 0x0979, 0x0178, 0x0958, 0x0159, 0x0999, 0x0BDA, 0x02D9, 0x0159, 0x0959, 0x0159, 0x0979, 0x0959, 0x0979, 0x0959, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x0979, 0x1179, 0x1179, 0x1179, 0x1179, 0x1179, 0x1999, 0x1999, 0x199A, 0x1999, 0x2199, 0x219A, 0x21BA, 0x7154, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x1179, 0x1179, 0x1179, 0x0979, 0x0979, 0x0958, 0x0958, 0x0958, 0x0958, 0x0158, 0x0158, 0x0158, 0x0958, 0x0158, 0x0158, 0x0158, 0x0158, 0x0159, 0x0158, 0x01D8, 0x0399, 0x0399, 0x01D9, 0x0158, 0x0158, 0x0138, 0x0138, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0138, 0x0158, 0x0158, 0x0157, 0x0158, 0x0158, 0x0158, 0x0158, 0x0138, 0x0218, 0x0379, 0x03B9, 0x0258, 0x0158, 0x0138, 0x0158, 0x0138, 0x0138, 0x0158, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0137, 0x0138, 0x0138, 0x0137, 0x0138, 0x0137, 0x0138, 0x0137, 0x0138, 0x0138, 0x0138, 0x0137, 0x0238, 0x0359, 0x0399, 0x0298, 0x0178, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0117, 0x0117, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0117, 0x0137, 0x0137, + 0x0116, 0x0116, 0x0116, 0x00F7, 0x00F6, 0x0116, 0x0117, 0x0116, 0x0116, 0x0117, 0x0116, 0x0116, 0x0117, 0x0117, 0x0116, 0x0117, 0x0117, 0x0117, 0x0117, 0x0137, 0x0238, 0x0318, 0x0379, 0x0297, 0x0197, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0137, 0x0116, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0137, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0137, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0137, 0x0117, 0x0177, 0x02D8, 0x0399, 0x0318, 0x01D7, 0x0117, 0x0137, 0x0117, 0x0137, 0x0137, 0x0137, 0x0137, 0x0117, 0x0137, 0x0117, 0x0137, 0x0117, 0x0117, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0138, 0x0137, 0x01D8, 0x0339, 0x0399, 0x0238, 0x0137, 0x0137, 0x0138, 0x0138, 0x0137, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0137, 0x0138, 0x0138, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0157, 0x0138, 0x0278, 0x03D9, 0x02B9, 0x0178, 0x0158, 0x0138, 0x0138, 0x0158, 0x0138, 0x0137, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0158, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0158, 0x0158, 0x0158, 0x0138, 0x0138, 0x0938, 0x0158, 0x0158, 0x0158, 0x0178, 0x0339, 0x0399, 0x0178, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x01D9, 0x03F9, 0x01F9, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x02D9, 0x0319, 0x0158, 0x0158, 0x0158, 0x0159, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0959, 0x0158, 0x0158, 0x0159, 0x041A, 0x0959, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x02B9, 0x0319, 0x0158, 0x0158, 0x0138, 0x0138, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0138, 0x0158, 0x01D8, 0x03F9, 0x01F8, 0x0138, 0x0138, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0958, 0x0958, 0x0958, 0x0958, 0x0958, 0x1158, 0x1158, 0x1158, 0x1178, 0x1179, 0x1979, 0x1979, 0x1979, 0x1979, 0x1999, 0x2179, 0x3178, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x3157, 0x0958, 0x1158, 0x0958, 0x0958, 0x0938, 0x0938, 0x0938, 0x0938, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0298, 0x03F9, 0x0298, 0x0137, 0x0138, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0117, 0x0137, 0x0137, 0x0117, 0x0137, 0x0137, 0x0138, 0x0117, 0x0137, 0x0238, 0x0379, 0x0379, 0x0238, 0x0137, 0x0137, 0x0117, 0x0117, 0x0117, 0x0117, 0x0137, 0x0117, 0x0117, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0117, 0x0117, 0x0117, 0x0117, 0x0137, 0x0117, 0x0117, 0x0136, 0x0117, 0x0117, 0x0117, 0x0136, 0x0137, 0x01B7, 0x02B8, 0x0399, 0x02B8, 0x0197, 0x0137, 0x0117, 0x0137, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0116, 0x0117, 0x0117, 0x0117, 0x0117, 0x0116, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, + 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x0116, 0x00F6, 0x0116, 0x01B7, 0x02B7, 0x0378, 0x02B7, 0x01D6, 0x0116, 0x00F7, 0x00F6, 0x0116, 0x00F6, 0x0116, 0x0116, 0x00F6, 0x00F6, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0117, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0136, 0x0197, 0x02F8, 0x0378, 0x0297, 0x0177, 0x0116, 0x0116, 0x0117, 0x0116, 0x0116, 0x0117, 0x0117, 0x0116, 0x0117, 0x0117, 0x0117, 0x0117, 0x0116, 0x0116, 0x0116, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x01D7, 0x0318, 0x0379, 0x0238, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0137, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0137, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0137, 0x0117, 0x0117, 0x0177, 0x0318, 0x0379, 0x01D7, 0x0137, 0x0117, 0x0137, 0x0117, 0x0137, 0x0136, 0x0117, 0x0117, 0x0137, 0x0137, 0x0117, 0x0117, 0x0137, 0x0137, 0x0137, 0x0117, 0x0137, 0x0137, 0x0137, 0x0117, 0x0117, 0x0117, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0138, 0x0137, 0x0117, 0x0157, 0x0359, 0x02F8, 0x0157, 0x0117, 0x0137, 0x0117, 0x0137, 0x0117, 0x0137, 0x0137, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0158, 0x0359, 0x0278, 0x0137, 0x0138, 0x0137, 0x0138, 0x0138, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0138, 0x03B9, 0x01B8, 0x0137, 0x0138, 0x0138, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0137, 0x0137, 0x0138, 0x03F9, 0x0137, 0x0138, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0138, 0x0118, 0x0138, 0x0138, 0x0178, 0x03F9, 0x0158, 0x0137, 0x0137, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0137, 0x0137, 0x0137, 0x0138, 0x0138, 0x0137, 0x0137, 0x0118, 0x0238, 0x03B9, 0x0177, 0x0137, 0x0138, 0x0137, 0x0117, 0x0137, 0x0138, 0x0137, 0x0137, 0x0137, 0x0137, 0x0937, 0x0938, 0x0938, 0x0938, 0x0938, 0x0938, 0x0958, 0x1158, 0x1158, 0x1158, 0x1158, 0x1158, 0x1958, 0x1958, 0x1959, 0x1978, 0x6934, 0x9931, 0x9931, 0x9912, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9912, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9932, 0x4135, 0x0938, 0x0957, 0x0937, 0x0937, 0x0937, 0x0937, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0137, 0x0137, 0x0117, 0x0117, 0x0117, 0x0117, 0x0197, 0x0318, 0x0338, 0x01B7, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0116, 0x0117, 0x0117, 0x0117, 0x0116, 0x0117, 0x0116, 0x0117, 0x0116, 0x0117, 0x00F7, 0x0217, 0x0339, 0x02F8, 0x0197, 0x0136, 0x0116, 0x0117, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0117, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0117, 0x0116, 0x0116, 0x0116, 0x0156, 0x0237, 0x0358, 0x02D8, 0x01F7, 0x0116, 0x00F6, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x00F6, 0x00F6, 0x0116, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x0116, + 0x0297, 0x0297, 0x0297, 0x0297, 0x0297, 0x0297, 0x0297, 0x0297, 0x0297, 0x0297, 0x02B7, 0x0297, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x0318, 0x0357, 0x0338, 0x02D7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B8, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B8, 0x02B8, 0x02B7, 0x0317, 0x0358, 0x0338, 0x02F7, 0x02D7, 0x02B7, 0x02B7, 0x02B7, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02D8, 0x02D8, 0x02D7, 0x02D7, 0x02D7, 0x02D8, 0x02D8, 0x02D7, 0x02D8, 0x02D7, 0x02D8, 0x02D8, 0x02D8, 0x02D7, 0x02D7, 0x02F7, 0x0358, 0x0378, 0x02F7, 0x02D8, 0x02D8, 0x02D8, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02D7, 0x02F8, 0x02F8, 0x0398, 0x0378, 0x02F8, 0x02D8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x0378, 0x0398, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x0318, 0x02F8, 0x0318, 0x02F7, 0x02F8, 0x02F8, 0x0318, 0x0358, 0x0399, 0x0318, 0x02F8, 0x02F8, 0x0318, 0x0318, 0x02F8, 0x0318, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0338, 0x03B8, 0x0318, 0x0318, 0x02F8, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x03B8, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x0318, 0x02F8, 0x0318, 0x0318, 0x02F8, 0x0318, 0x0378, 0x0338, 0x02F8, 0x02F8, 0x0318, 0x02F8, 0x0318, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x0318, 0x0318, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x0378, 0x0338, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x0AF8, 0x0AF8, 0x0AF8, 0x0AF8, 0x0B18, 0x0B18, 0x1318, 0x1319, 0x1319, 0x1319, 0x1319, 0x1319, 0x1B18, 0x2AF8, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9932, 0x9931, 0x9911, 0x9931, 0x9932, 0x9931, 0x9931, 0x9931, 0x5215, 0x0AF8, 0x0AF8, 0x02F8, 0x02F8, 0x02F8, 0x02F8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D8, 0x02D7, 0x02D8, 0x02D8, 0x0378, 0x0378, 0x02D7, 0x02D8, 0x02D7, 0x02D7, 0x02D8, 0x02D8, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02D8, 0x02D8, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02D8, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02D7, 0x02B7, 0x02D7, 0x02D7, 0x02D7, 0x02B7, 0x02B7, 0x02F7, 0x0358, 0x0358, 0x02F7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02D7, 0x0338, 0x0357, 0x02F7, 0x0297, 0x0297, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x02B7, 0x0297, 0x0297, 0x0297, 0x02B7, 0x0297, 0x0297, 0x02B7, 0x0297, + 0x0175, 0x0155, 0x0155, 0x0156, 0x0175, 0x0176, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x01B6, 0x0257, 0x02F7, 0x02D7, 0x0216, 0x0176, 0x0155, 0x0175, 0x0156, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0176, 0x0176, 0x0155, 0x0176, 0x0176, 0x0176, 0x0175, 0x0176, 0x0175, 0x0156, 0x0176, 0x0176, 0x0176, 0x0155, 0x01B6, 0x0296, 0x0337, 0x0296, 0x01D6, 0x0176, 0x0196, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0196, 0x0176, 0x0176, 0x0176, 0x0196, 0x0196, 0x0176, 0x0176, 0x0196, 0x0176, 0x0196, 0x0176, 0x01B6, 0x02F8, 0x0317, 0x0217, 0x0196, 0x0176, 0x0196, 0x0196, 0x0196, 0x0196, 0x0176, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0176, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x01F7, 0x0337, 0x02D7, 0x01B6, 0x0197, 0x0196, 0x0196, 0x0176, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0197, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0237, 0x0358, 0x0217, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0196, 0x0196, 0x0197, 0x0197, 0x0196, 0x0196, 0x0277, 0x0318, 0x01B6, 0x0196, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x01B7, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x01B6, 0x02F7, 0x0257, 0x0197, 0x01B6, 0x01B7, 0x01B6, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x01B7, 0x01B6, 0x01B7, 0x0378, 0x01B7, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x01B6, 0x01F7, 0x0358, 0x0196, 0x0196, 0x01B6, 0x0196, 0x01B6, 0x0197, 0x0196, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0196, 0x0196, 0x0197, 0x0197, 0x02F7, 0x02F7, 0x0196, 0x0196, 0x0196, 0x0196, 0x0197, 0x0196, 0x0197, 0x01B6, 0x01B6, 0x0196, 0x0196, 0x0196, 0x0197, 0x0197, 0x0197, 0x09B7, 0x0997, 0x09B7, 0x09B7, 0x09B7, 0x11B7, 0x11B7, 0x11D7, 0x11B7, 0x11B7, 0x11B7, 0x7153, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x6174, 0x09B6, 0x0196, 0x0197, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0176, 0x0196, 0x0196, 0x0196, 0x0196, 0x0177, 0x0196, 0x02B7, 0x0337, 0x0216, 0x0196, 0x0196, 0x0196, 0x0176, 0x0176, 0x0176, 0x0176, 0x0196, 0x0196, 0x0176, 0x0176, 0x0196, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0175, 0x0196, 0x0195, 0x0216, 0x02F7, 0x0317, 0x0216, 0x0176, 0x0176, 0x0176, 0x0176, 0x0175, 0x0175, 0x0176, 0x0176, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0176, 0x0175, 0x0155, 0x0196, 0x0256, 0x0317, 0x02B7, 0x01B6, 0x0176, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0155, 0x0155, 0x0175, 0x0155, 0x0155, 0x0155, + 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B4, 0x00D3, 0x00D3, 0x00B4, 0x00D4, 0x0174, 0x0235, 0x02D6, 0x0235, 0x0174, 0x00D4, 0x00D4, 0x00B4, 0x00D4, 0x00B4, 0x00D4, 0x00B4, 0x00B4, 0x00B4, 0x00B4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00B4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00B4, 0x00D4, 0x00D4, 0x00D4, 0x0135, 0x0235, 0x02D6, 0x0236, 0x0134, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D4, 0x00D4, 0x00D4, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x0115, 0x0236, 0x0317, 0x0256, 0x00F4, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00F5, 0x00F5, 0x00D5, 0x00F5, 0x00D5, 0x00D5, 0x00F5, 0x01F6, 0x0317, 0x01F6, 0x00F5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00F5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00F5, 0x00F5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00F5, 0x00D5, 0x00F5, 0x01B6, 0x0337, 0x01B6, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x0155, 0x0337, 0x0156, 0x00D5, 0x00D5, 0x00F6, 0x00F6, 0x00F6, 0x00F5, 0x00D6, 0x00D6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F6, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F6, 0x00D5, 0x00F6, 0x00F6, 0x00F5, 0x00F5, 0x00F5, 0x00F6, 0x0115, 0x0338, 0x0115, 0x00F6, 0x00F5, 0x00F6, 0x00F5, 0x00D6, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00D5, 0x00F6, 0x00D5, 0x00F5, 0x0357, 0x00F5, 0x00F6, 0x00F6, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F6, 0x00F5, 0x00D5, 0x00D5, 0x00D6, 0x00D6, 0x00D5, 0x00F5, 0x02F7, 0x0176, 0x00F5, 0x00D5, 0x00F5, 0x00F6, 0x00F6, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00D5, 0x00F5, 0x00D5, 0x0116, 0x02F7, 0x01D6, 0x00D6, 0x00D5, 0x00F5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00F5, 0x00D5, 0x00D5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x08F6, 0x08F6, 0x08F6, 0x08F6, 0x0916, 0x0916, 0x10F6, 0x1117, 0x1116, 0x3135, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9911, 0x9912, 0x9931, 0x9931, 0x9931, 0x9931, 0x7113, 0x08F5, 0x08F6, 0x00F5, 0x00F5, 0x00F5, 0x00F5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D5, 0x00D4, 0x00D5, 0x00D5, 0x00D5, 0x01D6, 0x02F7, 0x0236, 0x0114, 0x00D5, 0x00D5, 0x00D4, 0x00D5, 0x00D5, 0x00D5, 0x00D4, 0x00D5, 0x00D4, 0x00D5, 0x00D5, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00B4, 0x00D4, 0x00D4, 0x00F4, 0x01D5, 0x02D6, 0x0236, 0x0114, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00B4, 0x00B4, 0x00B4, 0x00B4, 0x00B4, 0x00B4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D3, 0x0114, 0x01F5, 0x02B5, 0x0235, 0x0154, 0x00D3, 0x00B3, 0x00B3, 0x00D3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, + 0x00B1, 0x00B2, 0x00B1, 0x00B2, 0x00B2, 0x00B2, 0x00F2, 0x01D3, 0x0253, 0x0234, 0x0173, 0x00D2, 0x0092, 0x00B1, 0x00B1, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x0092, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B3, 0x00B2, 0x0153, 0x0234, 0x0274, 0x01B3, 0x00F3, 0x00B2, 0x00B2, 0x00B3, 0x00B3, 0x00B2, 0x00B3, 0x00B3, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00D3, 0x01B4, 0x02B5, 0x01F4, 0x0113, 0x00B3, 0x00D3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00D3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00D3, 0x00B3, 0x00D3, 0x00D4, 0x00B3, 0x00B3, 0x00D4, 0x00B3, 0x00B3, 0x00D4, 0x00B3, 0x00D3, 0x0133, 0x0275, 0x0255, 0x0134, 0x00D3, 0x00B3, 0x00D3, 0x00D3, 0x00D4, 0x00D4, 0x00B4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00B4, 0x00D4, 0x00B4, 0x00D4, 0x00D4, 0x00B4, 0x00B4, 0x01D4, 0x02B5, 0x0134, 0x00D4, 0x00B4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00F4, 0x02B5, 0x01B5, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x01B5, 0x0255, 0x00D5, 0x00B4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x02F6, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x01F5, 0x0235, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00B4, 0x00B4, 0x00B4, 0x00B4, 0x00B4, 0x00B4, 0x00B4, 0x00D4, 0x00D4, 0x00B4, 0x0154, 0x02B5, 0x0134, 0x00D4, 0x00B4, 0x00B4, 0x00D4, 0x00D4, 0x00D4, 0x00B4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x08D4, 0x08D4, 0x08D4, 0x08F4, 0x08F4, 0x08F4, 0x08F5, 0x10F4, 0x10D5, 0x7912, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x8132, 0x00D4, 0x00D4, 0x00D4, 0x00D3, 0x00D3, 0x00D3, 0x00D3, 0x00D3, 0x00B3, 0x00D3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B2, 0x00B3, 0x00D3, 0x00D3, 0x0214, 0x0295, 0x0153, 0x00B3, 0x00B3, 0x00B3, 0x00B2, 0x00B3, 0x00B3, 0x00B3, 0x00B2, 0x00B2, 0x00B2, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B3, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00D2, 0x01B3, 0x0274, 0x01D3, 0x00F2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B1, 0x00B2, 0x0092, 0x00B2, 0x00B1, 0x0172, 0x0253, 0x0233, 0x0152, 0x00B1, 0x0091, 0x00B1, 0x0091, 0x00B1, 0x00B1, 0x0091, 0x00B1, + 0x0090, 0x0090, 0x0090, 0x00B0, 0x0151, 0x0212, 0x0232, 0x0191, 0x00F0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0091, 0x0090, 0x0091, 0x00B1, 0x0171, 0x0232, 0x0213, 0x0151, 0x0090, 0x00B0, 0x0090, 0x0091, 0x00B1, 0x00B0, 0x0090, 0x00B1, 0x00B1, 0x0091, 0x0091, 0x0091, 0x0091, 0x0091, 0x0091, 0x0091, 0x0091, 0x0091, 0x0091, 0x0091, 0x0091, 0x0091, 0x0091, 0x0091, 0x0091, 0x0091, 0x00B1, 0x00B1, 0x0091, 0x0091, 0x0091, 0x00D1, 0x0172, 0x0253, 0x01B2, 0x00D1, 0x00B1, 0x0091, 0x0091, 0x0091, 0x00B1, 0x0091, 0x00B1, 0x00B1, 0x0091, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x0091, 0x0091, 0x00D2, 0x01B2, 0x0273, 0x0172, 0x00B1, 0x00B2, 0x00B1, 0x00B1, 0x00B2, 0x00B1, 0x00B1, 0x00B2, 0x00B1, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B1, 0x00B1, 0x00B2, 0x00B2, 0x00B1, 0x00B2, 0x00B2, 0x00B2, 0x01D3, 0x0253, 0x0112, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x0213, 0x01D3, 0x0092, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x0253, 0x0153, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x0294, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00F2, 0x0293, 0x00D2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B1, 0x00B2, 0x0172, 0x0253, 0x00B1, 0x00B1, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B1, 0x00B1, 0x00B1, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x08B2, 0x08B2, 0x08B2, 0x08D2, 0x08B2, 0x08D2, 0x08D3, 0x10D3, 0x40F2, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x00D2, 0x00B2, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x0091, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x00B1, 0x0091, 0x0131, 0x0252, 0x01F2, 0x00B1, 0x00B1, 0x00B1, 0x0091, 0x0091, 0x00B1, 0x0091, 0x0091, 0x00B0, 0x0091, 0x0091, 0x0091, 0x0091, 0x0091, 0x0091, 0x0091, 0x0091, 0x0091, 0x0091, 0x0091, 0x0091, 0x0091, 0x0091, 0x0090, 0x0090, 0x0091, 0x0091, 0x0091, 0x00B1, 0x0090, 0x00B0, 0x0091, 0x00B0, 0x01B2, 0x0252, 0x01B1, 0x00D0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0111, 0x01D1, 0x0232, 0x0191, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, + 0x008F, 0x0130, 0x01B1, 0x0232, 0x01B1, 0x0110, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00D0, 0x0191, 0x0232, 0x01D1, 0x00F0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x0171, 0x0232, 0x01D1, 0x00F1, 0x0090, 0x0090, 0x0090, 0x0070, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0111, 0x0212, 0x01D1, 0x00D0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x01D2, 0x01F2, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x0171, 0x0212, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x00F1, 0x0252, 0x00B0, 0x0090, 0x00B0, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x0272, 0x00B0, 0x0090, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x01D1, 0x0171, 0x0091, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x01D1, 0x01D1, 0x0090, 0x00B0, 0x0090, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0091, 0x0091, 0x0091, 0x0091, 0x08B1, 0x08B1, 0x08B1, 0x08B1, 0x08B1, 0x08B1, 0x08B1, 0x8912, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9911, 0x9911, 0x9912, 0x9931, 0x0091, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x01B1, 0x0252, 0x0131, 0x0090, 0x0090, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x01B1, 0x0232, 0x0191, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0070, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x0191, 0x0252, 0x01B1, 0x0110, 0x0090, 0x0090, 0x0090, + 0x0212, 0x01F1, 0x0150, 0x00AF, 0x008F, 0x008F, 0x006F, 0x0090, 0x0090, 0x0070, 0x006F, 0x006F, 0x008F, 0x008F, 0x0070, 0x0070, 0x006F, 0x008F, 0x006F, 0x008F, 0x0090, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0090, 0x006F, 0x008F, 0x008F, 0x008F, 0x0130, 0x01D1, 0x0212, 0x0191, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x0090, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0090, 0x0090, 0x008F, 0x0090, 0x0151, 0x0211, 0x01D1, 0x00F0, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x0191, 0x0232, 0x0151, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x01F2, 0x01D1, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0110, 0x0252, 0x00D0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x01B1, 0x0191, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x0090, 0x0090, 0x0252, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0151, 0x0232, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x01F1, 0x0171, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0091, 0x00B0, 0x00B0, 0x00B1, 0x08B1, 0x08B0, 0x08B1, 0x08B1, 0x50F1, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9911, 0x9931, 0x9911, 0x9931, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0070, 0x0090, 0x0090, 0x0090, 0x0090, 0x00F1, 0x0211, 0x01D2, 0x00D0, 0x0090, 0x0090, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x0090, 0x0090, 0x008F, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0090, 0x008F, 0x0090, 0x00B0, 0x01B1, 0x0232, 0x0151, 0x00B0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x008F, 0x0090, 0x008F, 0x008F, 0x008F, 0x0090, 0x008F, 0x0090, 0x008F, 0x00B0, 0x0151, 0x0211, 0x0212, 0x0130, 0x00AF, + 0x00CF, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x00AF, 0x0130, 0x01F2, 0x0212, 0x0131, 0x00AF, 0x006F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x006F, 0x006F, 0x008F, 0x006F, 0x0090, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0130, 0x0212, 0x01F2, 0x00F0, 0x0070, 0x008F, 0x006F, 0x008F, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x00D0, 0x0212, 0x01D2, 0x00D0, 0x0090, 0x008F, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0090, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x0090, 0x0090, 0x00F0, 0x0232, 0x01B1, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0232, 0x0130, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x0232, 0x00D0, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0252, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0232, 0x00F0, 0x0090, 0x0070, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00F0, 0x0232, 0x00F1, 0x00B0, 0x008F, 0x008F, 0x0090, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x00B0, 0x00B0, 0x0890, 0x08B0, 0x0891, 0x10B0, 0x9931, 0x9911, 0x9911, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0090, 0x008F, 0x008F, 0x0090, 0x0191, 0x0212, 0x0150, 0x008F, 0x0090, 0x008F, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0090, 0x0090, 0x006F, 0x008F, 0x006F, 0x0070, 0x008F, 0x006F, 0x008F, 0x008F, 0x006F, 0x00D0, 0x01D2, 0x0212, 0x0150, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x0110, 0x01D1, 0x0212, + 0x006F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x006F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x006F, 0x008F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x006F, 0x00AF, 0x0171, 0x0212, 0x01D1, 0x0110, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x006F, 0x0110, 0x01F2, 0x0212, 0x0130, 0x008F, 0x006F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0171, 0x0232, 0x0151, 0x008F, 0x006F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0070, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x006F, 0x00F0, 0x0212, 0x0151, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x0070, 0x0090, 0x01F1, 0x01B1, 0x0070, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x008F, 0x0090, 0x008F, 0x008F, 0x0130, 0x01F1, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0252, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x0191, 0x01B1, 0x0090, 0x008F, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x0090, 0x0090, 0x008F, 0x0090, 0x006F, 0x008F, 0x0131, 0x0232, 0x00D0, 0x0090, 0x008F, 0x008F, 0x008F, 0x0090, 0x0090, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x60F1, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x0150, 0x0090, 0x0090, 0x0090, 0x006F, 0x0090, 0x006F, 0x008F, 0x008F, 0x0070, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x0110, 0x01F2, 0x01D1, 0x00CF, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x006F, 0x006F, 0x00F0, 0x01B2, 0x0232, 0x0150, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x00F0, + 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x006F, 0x006E, 0x008F, 0x006E, 0x006E, 0x00EF, 0x01B1, 0x0212, 0x0191, 0x00D0, 0x006F, 0x006F, 0x008E, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x008F, 0x006F, 0x006F, 0x006F, 0x008F, 0x006F, 0x006F, 0x00EF, 0x01D1, 0x01F1, 0x0130, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x0070, 0x008F, 0x006F, 0x008F, 0x0110, 0x0232, 0x01B1, 0x00AF, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x0110, 0x0252, 0x0130, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x0170, 0x01F2, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x01D2, 0x0130, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x0252, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x00CF, 0x0232, 0x00AF, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x008F, 0x0191, 0x0212, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x0090, 0x008F, 0x18AF, 0x9911, 0x9912, 0x9911, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0xA111, 0x9931, 0xA111, 0x29D2, 0x01B1, 0x008F, 0x006F, 0x008F, 0x006F, 0x008F, 0x008F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x006F, 0x0150, 0x0232, 0x0150, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x006F, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x008F, 0x00F0, 0x01D1, 0x01F1, 0x0130, 0x008F, 0x006F, 0x008F, 0x006F, 0x006F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x006F, 0x006E, 0x008F, + 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006F, 0x006E, 0x0130, 0x01D1, 0x0212, 0x0150, 0x00AF, 0x006E, 0x006E, 0x008E, 0x006E, 0x006F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006E, 0x006F, 0x006F, 0x00CF, 0x01B1, 0x0212, 0x0130, 0x006E, 0x006E, 0x006F, 0x006F, 0x006F, 0x008F, 0x006F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x01B1, 0x0232, 0x010F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x0150, 0x0232, 0x00CF, 0x006F, 0x006F, 0x008E, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x006F, 0x010F, 0x0212, 0x00AF, 0x006F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x008F, 0x00AF, 0x0212, 0x00AF, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x006F, 0x006F, 0x0252, 0x006F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x006F, 0x006F, 0x01D1, 0x0130, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x01F1, 0x01B1, 0x008F, 0x006F, 0x006F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x0090, 0x8111, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9912, 0x9932, 0x9931, 0x9931, 0x28D0, 0x01F2, 0x01D1, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006E, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x006F, 0x00CF, 0x01F1, 0x01F1, 0x00CF, 0x006F, 0x006F, 0x006F, 0x006E, 0x006E, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006E, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006E, 0x006F, 0x00F0, 0x01D1, 0x01F1, 0x0110, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006F, 0x006E, 0x006E, 0x006E, + 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x008E, 0x0150, 0x0212, 0x01D1, 0x0110, 0x008E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x00AF, 0x01D1, 0x0212, 0x0150, 0x008F, 0x006E, 0x006F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x008E, 0x0110, 0x0212, 0x01B1, 0x008F, 0x006F, 0x006E, 0x006F, 0x006F, 0x006E, 0x008F, 0x006E, 0x006E, 0x006E, 0x006F, 0x006F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006F, 0x008F, 0x006E, 0x006E, 0x006F, 0x006F, 0x008E, 0x006E, 0x0191, 0x01F1, 0x00CF, 0x006F, 0x006F, 0x006E, 0x008F, 0x006E, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x006E, 0x006E, 0x006F, 0x00CF, 0x0212, 0x0110, 0x008F, 0x006F, 0x006E, 0x008F, 0x006F, 0x006E, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x0150, 0x0191, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x0232, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x0110, 0x01F1, 0x008F, 0x006E, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x00AF, 0x0212, 0x0110, 0x006F, 0x006F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x008F, 0x008F, 0x008F, 0x008F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x48D0, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x008E, 0x008F, 0x01B1, 0x01F2, 0x00AF, 0x006F, 0x006E, 0x008F, 0x006E, 0x008F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0150, 0x0232, 0x0150, 0x008E, 0x006E, 0x006E, 0x006E, 0x006E, 0x008E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006F, 0x006E, 0x006E, 0x006E, 0x0110, 0x01F1, 0x01F1, 0x0110, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, + 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x00AE, 0x0190, 0x0212, 0x0190, 0x00CF, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x00AF, 0x0170, 0x0212, 0x0150, 0x008E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x008E, 0x01B1, 0x0212, 0x00EF, 0x006E, 0x006E, 0x006E, 0x006F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006F, 0x006E, 0x006E, 0x008E, 0x01D1, 0x01F1, 0x008F, 0x006F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x00AE, 0x01F1, 0x0170, 0x006F, 0x006E, 0x006E, 0x006E, 0x006F, 0x006E, 0x006E, 0x006F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0211, 0x00CF, 0x008F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0232, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x008F, 0x0212, 0x00CF, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x00EF, 0x0212, 0x00CF, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006F, 0x006E, 0x108F, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x006E, 0x006F, 0x006E, 0x0190, 0x0212, 0x00CF, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x00AF, 0x01B1, 0x01F2, 0x00EF, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x010F, 0x01F1, 0x01B1, 0x00EF, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, + 0x006E, 0x006E, 0x006E, 0x004D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x004E, 0x006E, 0x006E, 0x004E, 0x006E, 0x00EF, 0x01B1, 0x01F1, 0x0150, 0x008F, 0x006E, 0x006E, 0x004E, 0x004E, 0x004E, 0x004E, 0x006E, 0x006E, 0x004E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x008E, 0x0170, 0x0212, 0x0171, 0x008E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0130, 0x0212, 0x0170, 0x008E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x00AF, 0x01D1, 0x0190, 0x008E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0190, 0x01F1, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x00EF, 0x0211, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0232, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0170, 0x0190, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0150, 0x01F1, 0x008E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x68F0, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x006E, 0x006E, 0x006E, 0x006E, 0x010F, 0x0212, 0x00EF, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x0130, 0x01F2, 0x0170, 0x008E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x010F, 0x01D1, 0x01B1, 0x00CF, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, + 0x006E, 0x006D, 0x004D, 0x006D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004D, 0x006E, 0x0130, 0x01D1, 0x01D1, 0x010F, 0x006E, 0x006D, 0x006D, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x004D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004D, 0x004D, 0x004D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x006D, 0x006E, 0x006E, 0x0170, 0x0212, 0x0170, 0x008E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x008E, 0x01B1, 0x01F2, 0x00CF, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x00AF, 0x0212, 0x0191, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x004E, 0x008E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x010F, 0x0212, 0x008E, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0190, 0x0150, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0232, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x008E, 0x0211, 0x008E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0190, 0x01B1, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x38B0, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x9912, 0x004E, 0x006E, 0x006E, 0x004E, 0x006E, 0x010F, 0x0212, 0x010F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x008E, 0x01B1, 0x01D1, 0x00CF, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x004E, 0x006E, 0x006E, 0x006D, 0x004D, 0x008E, 0x0150, 0x01F1, 0x01B1, 0x00CF, 0x004D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004D, 0x006E, 0x006E, 0x006D, + 0x004D, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006D, 0x004D, 0x008E, 0x0170, 0x01F1, 0x01B1, 0x00EF, 0x004D, 0x004D, 0x006D, 0x004D, 0x006D, 0x006D, 0x004D, 0x006D, 0x006D, 0x004D, 0x006D, 0x006D, 0x006D, 0x004D, 0x006D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x008E, 0x012F, 0x01F1, 0x0170, 0x008E, 0x006D, 0x006D, 0x006E, 0x004D, 0x006E, 0x006E, 0x006E, 0x004D, 0x004D, 0x006D, 0x006E, 0x006E, 0x004E, 0x004D, 0x006E, 0x006E, 0x006D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x004E, 0x004D, 0x0130, 0x01F2, 0x0150, 0x006D, 0x006D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x00EF, 0x0212, 0x010F, 0x004E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x004E, 0x00AF, 0x0212, 0x00CF, 0x004E, 0x006E, 0x004E, 0x004E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x008E, 0x0232, 0x008E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x0232, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x004E, 0x006E, 0x006E, 0x01D1, 0x010F, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x004E, 0x006E, 0x004E, 0x006E, 0x008E, 0x01F1, 0x012F, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x004E, 0x006E, 0x086E, 0x9911, 0x9931, 0x9931, 0x9931, 0x9931, 0x9912, 0x9931, 0x9931, 0x9911, 0x9931, 0x004E, 0x006D, 0x006E, 0x006E, 0x006E, 0x006E, 0x00AE, 0x0211, 0x0190, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x004E, 0x006E, 0x006E, 0x004D, 0x00EF, 0x01F2, 0x0190, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006D, 0x006D, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004D, 0x006E, 0x006E, 0x006E, 0x006D, 0x006D, 0x006D, 0x004D, 0x006E, 0x006E, 0x006D, 0x004E, 0x006E, 0x012F, 0x01F1, 0x0190, 0x008E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006E, 0x004D, 0x006D, 0x006D, + 0x006D, 0x004D, 0x004D, 0x006D, 0x004D, 0x004D, 0x004D, 0x006D, 0x006D, 0x004D, 0x006D, 0x004D, 0x00CE, 0x0190, 0x0211, 0x0170, 0x008E, 0x004D, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004E, 0x004D, 0x004D, 0x006D, 0x004D, 0x006D, 0x0150, 0x01F1, 0x01B1, 0x00CE, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006E, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006E, 0x006D, 0x004D, 0x004D, 0x004E, 0x004D, 0x004D, 0x006D, 0x006D, 0x008E, 0x01B1, 0x01D1, 0x00CE, 0x006D, 0x004D, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x004D, 0x006E, 0x004D, 0x006E, 0x006E, 0x004E, 0x006D, 0x010F, 0x0212, 0x00EF, 0x006D, 0x006E, 0x006E, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004D, 0x006D, 0x006E, 0x006E, 0x006E, 0x004D, 0x006E, 0x004D, 0x006E, 0x01D1, 0x0150, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x0130, 0x0191, 0x006E, 0x006E, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x0232, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x006E, 0x004D, 0x004D, 0x004E, 0x010F, 0x01D1, 0x006E, 0x006E, 0x006E, 0x006E, 0x006D, 0x004E, 0x004E, 0x004D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006D, 0x006D, 0x00CE, 0x0212, 0x00CE, 0x006E, 0x006E, 0x006E, 0x006E, 0x006D, 0x004D, 0x004D, 0x006D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004E, 0x70F0, 0x9932, 0x9931, 0x9931, 0x9911, 0x9931, 0x9911, 0x9931, 0x9931, 0x8110, 0x006E, 0x006E, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x008E, 0x01D1, 0x0190, 0x006D, 0x006D, 0x004E, 0x006E, 0x006E, 0x004D, 0x006D, 0x006E, 0x004D, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006E, 0x0171, 0x01F2, 0x00EF, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x008E, 0x012F, 0x01F1, 0x0170, 0x008E, 0x004D, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006D, 0x004D, 0x004D, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, + 0x004D, 0x004D, 0x004D, 0x006D, 0x004D, 0x004D, 0x006D, 0x004D, 0x004D, 0x006D, 0x00EF, 0x01D1, 0x01D1, 0x012F, 0x008D, 0x004D, 0x006D, 0x006D, 0x004D, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006D, 0x004D, 0x004D, 0x004D, 0x006D, 0x00EF, 0x01F1, 0x01B0, 0x00CE, 0x004D, 0x004D, 0x006D, 0x004D, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006D, 0x004D, 0x004D, 0x004D, 0x0150, 0x01F1, 0x0150, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006D, 0x004D, 0x004E, 0x004D, 0x004D, 0x004D, 0x0150, 0x01F1, 0x00AE, 0x006D, 0x004D, 0x004D, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x004D, 0x006D, 0x006D, 0x004D, 0x006D, 0x004D, 0x006D, 0x006D, 0x006D, 0x0170, 0x01B1, 0x006D, 0x006D, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006D, 0x004E, 0x006E, 0x01D1, 0x010F, 0x006D, 0x006D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004D, 0x006D, 0x006E, 0x004E, 0x0212, 0x004D, 0x004D, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x004D, 0x006D, 0x006D, 0x006D, 0x006E, 0x01F1, 0x008E, 0x006D, 0x006E, 0x004D, 0x004D, 0x006D, 0x006D, 0x004E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006E, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x004D, 0x006D, 0x004D, 0x010F, 0x01F1, 0x006D, 0x006D, 0x004D, 0x006E, 0x006D, 0x006D, 0x006D, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x004E, 0x006D, 0x006D, 0x004D, 0x40CF, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x70F0, 0x004D, 0x006D, 0x004D, 0x004D, 0x006D, 0x006D, 0x004D, 0x004D, 0x006D, 0x0191, 0x01B1, 0x006D, 0x004D, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006D, 0x004D, 0x006D, 0x004D, 0x006D, 0x004D, 0x006D, 0x00EE, 0x01F1, 0x0190, 0x008E, 0x004D, 0x006D, 0x006D, 0x004D, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006D, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006D, 0x004D, 0x004D, 0x006D, 0x006D, 0x004D, 0x004D, 0x006D, 0x0150, 0x0212, 0x0170, 0x008E, 0x006D, 0x006D, 0x004D, 0x004D, 0x004D, 0x006D, 0x004D, 0x006D, 0x004D, 0x004D, 0x006D, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, + 0x0211, 0x0211, 0x0212, 0x01F2, 0x0212, 0x01F2, 0x01F1, 0x0211, 0x0211, 0x01F1, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x01F1, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x01F1, 0x0211, 0x0211, 0x0211, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0211, 0x0212, 0x01F1, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0211, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0232, 0x0212, 0x0211, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0232, 0x0232, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0211, 0x0232, 0x0212, 0x0232, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0232, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0232, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x11F1, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0x9932, 0x9931, 0x9931, 0x5991, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x01F1, 0x0212, 0x0211, 0x0212, 0x0212, 0x01F2, 0x0212, 0x0211, 0x01F1, 0x0211, 0x0211, 0x01F1, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, + 0x004D, 0x004D, 0x004C, 0x004C, 0x004D, 0x00AE, 0x0170, 0x01F1, 0x0170, 0x00CE, 0x004D, 0x004C, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004D, 0x004D, 0x004C, 0x004C, 0x004D, 0x004D, 0x004D, 0x004C, 0x004D, 0x004D, 0x004D, 0x00EF, 0x01D1, 0x01D1, 0x00EE, 0x004C, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004C, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x012F, 0x0212, 0x012F, 0x004D, 0x004D, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006D, 0x01B1, 0x01D1, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x00AE, 0x0212, 0x00AE, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x004D, 0x004D, 0x0150, 0x014F, 0x004D, 0x006D, 0x004D, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x004D, 0x006D, 0x004D, 0x004D, 0x0212, 0x004D, 0x004D, 0x004D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x00AE, 0x01F1, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x01B1, 0x0150, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006D, 0x004D, 0x006D, 0x004D, 0x88F0, 0x9931, 0x9931, 0x9931, 0x9931, 0x9912, 0x9911, 0x9931, 0x40AF, 0x004D, 0x006D, 0x004D, 0x004D, 0x006D, 0x004D, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x010F, 0x0212, 0x00AE, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006D, 0x004D, 0x004C, 0x006D, 0x00CE, 0x01D1, 0x0190, 0x008E, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x008D, 0x0170, 0x01F1, 0x012F, 0x006D, 0x004C, 0x004C, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, + 0x004C, 0x004C, 0x004C, 0x00EE, 0x0190, 0x01D1, 0x012F, 0x008D, 0x004C, 0x004C, 0x004C, 0x004D, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004D, 0x004D, 0x004D, 0x004C, 0x004C, 0x004C, 0x00AE, 0x0190, 0x01D1, 0x00EE, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004C, 0x004D, 0x004D, 0x00AE, 0x01B1, 0x01B1, 0x008D, 0x004C, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006D, 0x008D, 0x01B1, 0x0170, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006D, 0x01D1, 0x010F, 0x004D, 0x004D, 0x004D, 0x004D, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x01F1, 0x008E, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x0212, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x01D1, 0x00EE, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x006D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x008D, 0x01F1, 0x00EF, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004C, 0x004D, 0x004D, 0x004D, 0x004D, 0x50CF, 0x9911, 0x9931, 0x9911, 0x9931, 0x9931, 0x9931, 0xA111, 0x186E, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004C, 0x004D, 0x00EF, 0x01F1, 0x00EF, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004C, 0x004C, 0x004D, 0x006D, 0x0150, 0x01F1, 0x010F, 0x004D, 0x004C, 0x004C, 0x006C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004D, 0x004D, 0x008E, 0x0190, 0x01D1, 0x012F, 0x006D, 0x004C, 0x006C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, + 0x006D, 0x010F, 0x01B1, 0x01D1, 0x00EE, 0x006D, 0x002C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x002C, 0x004C, 0x004C, 0x004C, 0x00AE, 0x0190, 0x01D1, 0x00EE, 0x004D, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004D, 0x004D, 0x004D, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x012F, 0x01F1, 0x012F, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004D, 0x004C, 0x004C, 0x004C, 0x008E, 0x01F1, 0x014F, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004D, 0x006D, 0x0170, 0x0190, 0x004D, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x010F, 0x01D1, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004C, 0x004D, 0x004D, 0x0212, 0x004D, 0x004C, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x010E, 0x01B0, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x00AE, 0x01F1, 0x00AD, 0x004D, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x308E, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x9111, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x008D, 0x01F1, 0x012F, 0x006D, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004D, 0x004D, 0x004D, 0x004D, 0x004D, 0x008D, 0x01B0, 0x01B1, 0x008D, 0x004D, 0x004C, 0x004C, 0x002C, 0x004C, 0x004C, 0x002C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x00CD, 0x0191, 0x01D1, 0x012F, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, + 0x01D1, 0x0170, 0x00AE, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x008D, 0x0190, 0x01D1, 0x010F, 0x006D, 0x002C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x00AE, 0x01D1, 0x0190, 0x008D, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x00EE, 0x01F1, 0x00EE, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x012F, 0x01B0, 0x006D, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x0170, 0x010F, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004D, 0x004C, 0x004C, 0x004C, 0x0212, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x006D, 0x01F1, 0x008D, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x006C, 0x004C, 0x012F, 0x01B0, 0x006D, 0x004C, 0x006C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x084D, 0x9931, 0x9931, 0x9931, 0x9931, 0x9911, 0x9931, 0x68F0, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x008D, 0x01B0, 0x016F, 0x004D, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x012F, 0x0211, 0x010F, 0x004D, 0x002C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x002C, 0x004C, 0x004C, 0x004C, 0x00AD, 0x0190, 0x01D1, 0x00EE, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, + 0x006C, 0x004C, 0x004C, 0x004C, 0x002C, 0x004C, 0x002C, 0x002C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x008D, 0x0150, 0x01F1, 0x012F, 0x006C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x002C, 0x006D, 0x014F, 0x01D1, 0x010F, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x002C, 0x00EE, 0x01D1, 0x00CE, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x00AE, 0x01F1, 0x008E, 0x004C, 0x004C, 0x002C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x008D, 0x0211, 0x004D, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x0212, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x0150, 0x012F, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x0170, 0x0170, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x80F0, 0x9931, 0x9931, 0x9931, 0x9931, 0x9931, 0x388E, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x006D, 0x01B0, 0x01B1, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x008E, 0x01B0, 0x01B0, 0x00AD, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x00AD, 0x01B0, 0x01B1, 0x00EE, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, + 0x004C, 0x004C, 0x002C, 0x002B, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x002B, 0x002B, 0x002B, 0x002B, 0x002C, 0x002C, 0x002C, 0x002C, 0x002B, 0x004C, 0x004C, 0x004C, 0x004B, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x002C, 0x004C, 0x004C, 0x002C, 0x004C, 0x008D, 0x0150, 0x01D1, 0x012F, 0x006C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x00AD, 0x01B0, 0x0190, 0x006C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x0150, 0x01F1, 0x008D, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x002C, 0x004C, 0x004C, 0x01D1, 0x00EE, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x010F, 0x016F, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x01F1, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x00AD, 0x01F1, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x006C, 0x01D1, 0x010E, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x50CF, 0xA111, 0x9931, 0x9931, 0x9931, 0x9931, 0x084C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x002C, 0x004C, 0x014F, 0x01B1, 0x008D, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x010E, 0x01D1, 0x014F, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x002C, 0x00CE, 0x01B1, 0x01B1, 0x00EE, 0x004C, 0x002C, 0x004C, + 0x004B, 0x002B, 0x004C, 0x004B, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x004C, 0x004B, 0x004C, 0x004C, 0x004C, 0x002B, 0x004C, 0x004B, 0x004B, 0x002B, 0x002B, 0x004C, 0x002C, 0x004C, 0x004C, 0x012F, 0x01F1, 0x014F, 0x006C, 0x004B, 0x004C, 0x002C, 0x004B, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x002C, 0x002C, 0x002C, 0x002C, 0x002C, 0x002C, 0x002C, 0x002C, 0x004C, 0x004C, 0x004C, 0x004C, 0x002B, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004B, 0x004C, 0x014F, 0x01D1, 0x00EE, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x0150, 0x01B0, 0x006D, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x0190, 0x014F, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x01B1, 0x00CE, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x01F1, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x01B1, 0x00EE, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x008D, 0x01F1, 0x00AE, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x388E, 0x9931, 0x9931, 0x9931, 0x9931, 0x68D0, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x002C, 0x004C, 0x012E, 0x01D1, 0x008D, 0x004C, 0x004C, 0x004B, 0x004C, 0x004B, 0x004C, 0x004C, 0x004C, 0x004C, 0x002C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x002C, 0x004C, 0x002C, 0x004C, 0x008C, 0x0170, 0x01B1, 0x00AD, 0x004C, 0x004C, 0x002B, 0x002B, 0x004C, 0x004C, 0x002B, 0x004B, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004B, 0x004B, 0x002B, 0x002B, 0x004B, 0x002B, 0x002C, 0x00EE, 0x01B1, 0x0190, 0x00AD, 0x002B, + 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x004B, 0x004B, 0x004B, 0x004C, 0x004C, 0x004B, 0x002B, 0x004C, 0x004B, 0x004B, 0x004B, 0x006C, 0x010E, 0x01D1, 0x014F, 0x006C, 0x004B, 0x004B, 0x002B, 0x004B, 0x004B, 0x004C, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x002B, 0x004B, 0x004C, 0x004C, 0x002C, 0x004B, 0x004B, 0x002B, 0x002B, 0x004B, 0x00CD, 0x01B1, 0x0170, 0x008C, 0x004B, 0x002C, 0x004B, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x002C, 0x004C, 0x002C, 0x004B, 0x004B, 0x004C, 0x0190, 0x0190, 0x004C, 0x004B, 0x004C, 0x004C, 0x002C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x002C, 0x004C, 0x004C, 0x004C, 0x002C, 0x004C, 0x004C, 0x012F, 0x0190, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x002C, 0x004C, 0x004C, 0x004C, 0x004C, 0x00AD, 0x01D1, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x01F2, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x010E, 0x0170, 0x002B, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x00CE, 0x01D1, 0x004C, 0x004C, 0x004C, 0x002B, 0x004C, 0x004C, 0x004C, 0x002C, 0x002C, 0x004C, 0x002C, 0x004C, 0x004C, 0x004C, 0x004C, 0x104C, 0xA111, 0x9931, 0x9931, 0x9931, 0x288D, 0x004B, 0x004C, 0x002B, 0x002B, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004B, 0x004C, 0x002B, 0x004B, 0x004C, 0x002B, 0x004B, 0x00EE, 0x01F2, 0x00CD, 0x004B, 0x004C, 0x002B, 0x004C, 0x004C, 0x002B, 0x004B, 0x002B, 0x002B, 0x002C, 0x004B, 0x004C, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004C, 0x004C, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x004C, 0x002B, 0x00EE, 0x01D1, 0x012F, 0x004C, 0x002B, 0x004C, 0x002B, 0x002B, 0x004B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004C, 0x002B, 0x004C, 0x00EE, 0x01B1, 0x0170, + 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x004B, 0x004B, 0x002B, 0x004C, 0x010E, 0x01B1, 0x0170, 0x008C, 0x002B, 0x004B, 0x002B, 0x004B, 0x002C, 0x002C, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x006C, 0x0170, 0x01D1, 0x00CD, 0x004B, 0x004B, 0x004C, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x004B, 0x004C, 0x004B, 0x004B, 0x008D, 0x0190, 0x014F, 0x004C, 0x002B, 0x004B, 0x004C, 0x004C, 0x004B, 0x002B, 0x004C, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x002B, 0x002B, 0x002B, 0x004C, 0x004C, 0x004C, 0x004B, 0x004C, 0x002B, 0x00CD, 0x01D1, 0x008C, 0x004C, 0x004C, 0x002B, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004B, 0x004C, 0x002B, 0x004B, 0x004B, 0x004B, 0x002B, 0x014F, 0x012E, 0x002C, 0x004B, 0x004C, 0x004B, 0x004C, 0x002B, 0x002B, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x01F1, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x002B, 0x004C, 0x01F1, 0x006C, 0x002B, 0x004B, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004B, 0x002C, 0x004C, 0x004C, 0x002B, 0x004C, 0x014F, 0x01B0, 0x004C, 0x004C, 0x004C, 0x004C, 0x004B, 0x004B, 0x004C, 0x004B, 0x004B, 0x002B, 0x004C, 0x002B, 0x004B, 0x004C, 0x004C, 0x9931, 0x9931, 0x9931, 0x8910, 0x002C, 0x004B, 0x004C, 0x002B, 0x004B, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x004C, 0x002C, 0x002B, 0x004C, 0x002B, 0x004C, 0x002B, 0x002B, 0x004C, 0x004C, 0x004B, 0x00AC, 0x01D1, 0x010F, 0x004B, 0x002C, 0x004C, 0x002C, 0x004C, 0x004B, 0x004B, 0x004B, 0x002B, 0x002B, 0x004C, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004C, 0x004B, 0x002B, 0x004C, 0x002B, 0x006C, 0x014F, 0x01D1, 0x00CD, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x004B, 0x004B, 0x002B, 0x004B, 0x002B, 0x004C, 0x010E, + 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x00ED, 0x01B1, 0x0170, 0x008D, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x00AD, 0x01D1, 0x016F, 0x004C, 0x004B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x004B, 0x004B, 0x002B, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x004B, 0x002B, 0x008D, 0x01D1, 0x012F, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x004C, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x006C, 0x01D1, 0x00CD, 0x004B, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004C, 0x002B, 0x004C, 0x004B, 0x004C, 0x004B, 0x004C, 0x01D1, 0x006C, 0x004C, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x01F1, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x002B, 0x014F, 0x010E, 0x004B, 0x004B, 0x002C, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x004B, 0x004C, 0x004B, 0x004B, 0x0190, 0x012F, 0x004B, 0x004C, 0x002B, 0x004B, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x004C, 0x004B, 0x004B, 0x002B, 0x70F0, 0x9931, 0x9931, 0x48AE, 0x004B, 0x004B, 0x004C, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x008C, 0x01B1, 0x014F, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x004B, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x00CD, 0x01D1, 0x0150, 0x004B, 0x002B, 0x002B, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x004B, 0x004B, 0x002B, + 0x002A, 0x002A, 0x004A, 0x004A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002A, 0x004A, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x00CD, 0x01B0, 0x0170, 0x00AC, 0x002A, 0x004B, 0x002B, 0x004B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x004A, 0x002A, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x004B, 0x004B, 0x016F, 0x01D1, 0x00AD, 0x002B, 0x002A, 0x002B, 0x002B, 0x004B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x004B, 0x002B, 0x00CE, 0x01D1, 0x00CD, 0x002B, 0x004B, 0x002B, 0x004B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x0190, 0x012F, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x00EE, 0x0190, 0x002B, 0x004B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x01F2, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x002B, 0x00AD, 0x01B1, 0x002B, 0x002C, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x004B, 0x002B, 0x002B, 0x006C, 0x01D1, 0x00CE, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x60CF, 0x9931, 0x9931, 0x104C, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x0190, 0x0190, 0x004C, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x004B, 0x014F, 0x01B1, 0x00AD, 0x002B, 0x002B, 0x002A, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002A, 0x002B, 0x002B, 0x002B, 0x002B, 0x002A, 0x004B, 0x004B, 0x002B, 0x002B, 0x004A, 0x002A, + 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x00CD, 0x0190, 0x01B0, 0x00CD, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x004A, 0x002A, 0x004A, 0x002A, 0x002A, 0x004A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004A, 0x002B, 0x002A, 0x004B, 0x00CD, 0x01D1, 0x012F, 0x004B, 0x004B, 0x002A, 0x004B, 0x002B, 0x002B, 0x004A, 0x002B, 0x002B, 0x004B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x004B, 0x002B, 0x004B, 0x00CE, 0x01D1, 0x00AD, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x004B, 0x014F, 0x0190, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x004B, 0x004B, 0x004B, 0x0190, 0x00CD, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x004B, 0x01D1, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x01B0, 0x00AD, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x004B, 0x004B, 0x002B, 0x002B, 0x004B, 0x002B, 0x004B, 0x00AD, 0x01D1, 0x008C, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x48AE, 0x9931, 0x68F0, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x004B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x014F, 0x0190, 0x006C, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004A, 0x004B, 0x004B, 0x002A, 0x002B, 0x004B, 0x002B, 0x002B, 0x002A, 0x002B, 0x004A, 0x00AC, 0x0190, 0x0170, 0x006C, 0x004A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, + 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x0029, 0x008C, 0x0170, 0x0190, 0x00CD, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x006B, 0x016F, 0x0190, 0x008C, 0x002A, 0x004A, 0x002A, 0x004A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x012F, 0x01B1, 0x006C, 0x004B, 0x002B, 0x002B, 0x002B, 0x004A, 0x002B, 0x002B, 0x002B, 0x002A, 0x002A, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x004B, 0x002B, 0x004B, 0x002B, 0x004B, 0x00CD, 0x01B1, 0x004B, 0x002B, 0x002B, 0x004A, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x006C, 0x01D1, 0x004B, 0x002B, 0x004B, 0x002B, 0x004B, 0x002B, 0x002B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x01D1, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x002B, 0x010E, 0x014F, 0x004B, 0x004B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004A, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x010E, 0x0190, 0x004B, 0x002A, 0x002B, 0x002A, 0x002B, 0x002B, 0x002A, 0x002B, 0x004B, 0x002B, 0x002B, 0x004B, 0x308D, 0x9911, 0x206C, 0x004B, 0x002B, 0x002B, 0x002A, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x002B, 0x004B, 0x004B, 0x002A, 0x004B, 0x004A, 0x004B, 0x004A, 0x002A, 0x002B, 0x002B, 0x004B, 0x002A, 0x002A, 0x002A, 0x002B, 0x010E, 0x01B1, 0x008C, 0x002A, 0x004A, 0x002B, 0x002A, 0x004A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x004B, 0x010E, 0x01B0, 0x00ED, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, + 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x002A, 0x0029, 0x0029, 0x0029, 0x002A, 0x002A, 0x002A, 0x0029, 0x008B, 0x016F, 0x01B0, 0x00CD, 0x002A, 0x0029, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x00ED, 0x01B1, 0x010E, 0x004A, 0x002A, 0x002A, 0x0029, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x004B, 0x014F, 0x016F, 0x004B, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002B, 0x002A, 0x002A, 0x008B, 0x01B1, 0x008C, 0x002B, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002B, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002B, 0x002A, 0x002B, 0x002A, 0x002A, 0x012E, 0x012F, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x01D2, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002B, 0x002A, 0x004B, 0x01D1, 0x006B, 0x002A, 0x002B, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002B, 0x002A, 0x014F, 0x014F, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x186B, 0x88F1, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x00CD, 0x01B1, 0x00CD, 0x002A, 0x004A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x0029, 0x00AC, 0x0190, 0x016F, 0x006B, 0x002A, 0x002A, 0x002A, 0x0029, 0x002A, 0x002A, 0x0029, 0x0029, 0x0029, 0x0029, 0x002A, 0x0029, 0x0029, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x0029, 0x0029, 0x0029, 0x0029, + 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x008B, 0x014F, 0x0190, 0x00ED, 0x004A, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x002A, 0x0029, 0x0029, 0x002A, 0x002A, 0x002A, 0x006A, 0x014F, 0x0190, 0x00AB, 0x0029, 0x002A, 0x0029, 0x0029, 0x0029, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x0029, 0x004A, 0x0170, 0x016F, 0x004A, 0x002A, 0x002A, 0x002A, 0x0029, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x004A, 0x0170, 0x00ED, 0x004A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x0190, 0x008C, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x01D1, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x012F, 0x010E, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x0029, 0x002A, 0x004B, 0x0190, 0x00ED, 0x002A, 0x002A, 0x002A, 0x002A, 0x004A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x286B, 0x0029, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x00AC, 0x01B1, 0x00ED, 0x0029, 0x002A, 0x0029, 0x0029, 0x002A, 0x002A, 0x0029, 0x002A, 0x0029, 0x002A, 0x002A, 0x0029, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x0029, 0x0029, 0x002A, 0x0029, 0x0029, 0x0029, 0x0029, 0x002A, 0x00EE, 0x01B1, 0x010D, 0x0029, 0x0029, 0x0029, 0x002A, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, + 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0029, 0x0028, 0x0028, 0x0028, 0x0029, 0x0029, 0x0028, 0x0028, 0x0029, 0x0029, 0x0029, 0x0009, 0x0029, 0x0049, 0x012E, 0x0190, 0x00ED, 0x004A, 0x0028, 0x0029, 0x0029, 0x0029, 0x0009, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x00CC, 0x01B0, 0x010E, 0x0049, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x006B, 0x0190, 0x012E, 0x0049, 0x002A, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x0029, 0x0029, 0x0029, 0x012E, 0x016F, 0x002A, 0x0029, 0x002A, 0x002A, 0x0029, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x00AC, 0x0190, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x01D1, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x0029, 0x002A, 0x0029, 0x00AC, 0x0190, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x002A, 0x0029, 0x002A, 0x008B, 0x01B1, 0x008B, 0x0029, 0x002A, 0x0029, 0x0029, 0x0029, 0x002A, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x002A, 0x002A, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x006B, 0x01B0, 0x012E, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x008B, 0x0170, 0x014F, 0x006A, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0009, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, + 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0069, 0x010D, 0x01B1, 0x00ED, 0x0049, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0029, 0x0029, 0x0029, 0x0028, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0028, 0x006A, 0x014F, 0x016F, 0x008B, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0028, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x006A, 0x01B0, 0x00ED, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0049, 0x00CD, 0x01B0, 0x004A, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x014F, 0x00CD, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x01D1, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x002A, 0x0029, 0x0029, 0x0029, 0x002A, 0x0190, 0x00AB, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x004A, 0x0029, 0x0029, 0x00CC, 0x01B1, 0x0049, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0049, 0x016F, 0x012E, 0x004A, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0028, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0028, 0x0028, 0x0009, 0x00ED, 0x01B1, 0x00ED, 0x0008, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, + 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0049, 0x010E, 0x0191, 0x010E, 0x0069, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x00ED, 0x01B1, 0x00EC, 0x0008, 0x0028, 0x0028, 0x0029, 0x0008, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0028, 0x0029, 0x00AB, 0x01B1, 0x00AC, 0x0029, 0x0029, 0x0029, 0x0028, 0x0029, 0x0029, 0x0029, 0x0028, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0028, 0x0029, 0x0029, 0x006A, 0x01B1, 0x006A, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x004A, 0x01B1, 0x006A, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x01B1, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x00ED, 0x012E, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0028, 0x0029, 0x0029, 0x0029, 0x0029, 0x012E, 0x016F, 0x0029, 0x0029, 0x0029, 0x0029, 0x0028, 0x0029, 0x0029, 0x0029, 0x0028, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0029, 0x0028, 0x0029, 0x0049, 0x012E, 0x016F, 0x0029, 0x0028, 0x0028, 0x0029, 0x0029, 0x0029, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0008, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x006A, 0x014F, 0x0170, 0x008A, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, + 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x00ED, 0x0190, 0x010E, 0x004A, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0008, 0x0028, 0x0028, 0x0028, 0x0029, 0x006A, 0x016F, 0x014F, 0x006A, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x00CC, 0x0190, 0x008A, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0049, 0x0190, 0x00CC, 0x0028, 0x0028, 0x0028, 0x0029, 0x0029, 0x0029, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x00CC, 0x012E, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x01B1, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x004A, 0x01B1, 0x0049, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0029, 0x0029, 0x0028, 0x016F, 0x00ED, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0008, 0x0029, 0x0028, 0x0029, 0x0028, 0x0008, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0008, 0x0028, 0x0028, 0x0028, 0x010D, 0x0190, 0x006A, 0x0028, 0x0029, 0x0028, 0x0028, 0x0029, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x00CC, 0x0190, 0x00ED, 0x0049, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, + 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0029, 0x0028, 0x0049, 0x00ED, 0x0190, 0x012F, 0x0069, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0029, 0x00EC, 0x01B0, 0x00ED, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x010E, 0x0190, 0x006A, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x012E, 0x012E, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x016F, 0x00AB, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x01B1, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x012E, 0x00EC, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0049, 0x0190, 0x00AB, 0x0029, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x00CC, 0x0190, 0x00AB, 0x0028, 0x0028, 0x0028, 0x0028, 0x0008, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0008, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0049, 0x014E, 0x0170, 0x008B, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, + 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x00CC, 0x0190, 0x014F, 0x008A, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x008A, 0x014F, 0x012F, 0x006A, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x012E, 0x014F, 0x0049, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0008, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x00CC, 0x016F, 0x0049, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x006A, 0x0190, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x01B1, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x008B, 0x018F, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x00AB, 0x0190, 0x006A, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0008, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x00AC, 0x0190, 0x00AC, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x00AC, 0x0190, 0x012E, 0x0049, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, + 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x00CB, 0x0170, 0x014F, 0x008A, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0009, 0x0028, 0x0049, 0x00ED, 0x0190, 0x00CC, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x014F, 0x014F, 0x0049, 0x0028, 0x0028, 0x0028, 0x0028, 0x0008, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x006A, 0x0190, 0x006A, 0x0028, 0x0028, 0x0028, 0x0028, 0x0008, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x010E, 0x00ED, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x01B1, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0170, 0x008A, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x00ED, 0x014F, 0x0048, 0x0029, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x006A, 0x0190, 0x010D, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0049, 0x012E, 0x0190, 0x00AB, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, + 0x0028, 0x0028, 0x0028, 0x0008, 0x0028, 0x00AC, 0x0170, 0x0170, 0x008B, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x008A, 0x016F, 0x014E, 0x0069, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0008, 0x0029, 0x0028, 0x006A, 0x0170, 0x010E, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0048, 0x0190, 0x00AB, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0008, 0x0028, 0x0190, 0x006A, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x01B1, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x00CD, 0x010D, 0x0008, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x012F, 0x012E, 0x0008, 0x0028, 0x0028, 0x0028, 0x0008, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0049, 0x014F, 0x010E, 0x0049, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x00AB, 0x0190, 0x010E, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, + 0x0028, 0x0028, 0x0028, 0x008A, 0x016F, 0x016F, 0x00AC, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0008, 0x0028, 0x0028, 0x0028, 0x0028, 0x0048, 0x010D, 0x0190, 0x00CC, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x006A, 0x0190, 0x00ED, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0008, 0x0008, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x014F, 0x010D, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x00CB, 0x016F, 0x0028, 0x0029, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x01B1, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0008, 0x0028, 0x0028, 0x0028, 0x0028, 0x0069, 0x01B1, 0x0049, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0049, 0x0170, 0x00CC, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0029, 0x014F, 0x014F, 0x0049, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0008, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x010D, 0x01B0, 0x00CC, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, + 0x0028, 0x008B, 0x014F, 0x0170, 0x00AB, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x008B, 0x0170, 0x014E, 0x0049, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x00AB, 0x0191, 0x00AB, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x00EC, 0x016F, 0x0049, 0x0008, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x012E, 0x00CC, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x01B1, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x012E, 0x00CC, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x006A, 0x0191, 0x008A, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0008, 0x0028, 0x0028, 0x010E, 0x0170, 0x006A, 0x0008, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x008A, 0x0170, 0x014F, 0x004A, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, + 0x012F, 0x0190, 0x00EC, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0049, 0x012E, 0x0190, 0x00AB, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x00ED, 0x0190, 0x006A, 0x0028, 0x0028, 0x0029, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x00AA, 0x0190, 0x008A, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0049, 0x01B1, 0x0049, 0x0008, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x01B1, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x00AB, 0x0170, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0008, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x00AC, 0x0190, 0x0048, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x00EC, 0x0190, 0x008B, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0029, 0x0028, 0x0028, 0x0048, 0x00ED, 0x0190, 0x00CC, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, + 0x00EC, 0x0049, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0029, 0x0008, 0x00AB, 0x0190, 0x012E, 0x0049, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x010E, 0x0170, 0x006A, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0069, 0x0190, 0x008B, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x00ED, 0x010E, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x01B1, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0190, 0x006A, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x010D, 0x014F, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0029, 0x0008, 0x00CB, 0x0191, 0x00CC, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x006B, 0x014F, 0x014E, 0x006A, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, + 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0049, 0x012E, 0x0190, 0x00AB, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x012F, 0x014F, 0x0029, 0x0028, 0x0029, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x014F, 0x00ED, 0x0029, 0x0028, 0x0008, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0170, 0x008A, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x01B1, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0029, 0x0028, 0x0029, 0x0028, 0x00ED, 0x010E, 0x0028, 0x0028, 0x0028, 0x0029, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0049, 0x014F, 0x00ED, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x006A, 0x0190, 0x00ED, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0008, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x00ED, 0x0191, 0x00ED, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/btn_rounded_64x52x4.cpp b/Marlin/src/lcd/tft/images/btn_rounded_64x52x4.cpp new file mode 100644 index 000000000000..4768f7e5fc89 --- /dev/null +++ b/Marlin/src/lcd/tft/images/btn_rounded_64x52x4.cpp @@ -0,0 +1,82 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t btn_rounded_64x52x4[1664] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x88, + 0x88, 0x88, 0x79, 0xCE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0x87, 0x77, 0x78, + 0x88, 0x78, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x66, 0x78, + 0x88, 0x8D, 0xFF, 0xB8, 0x54, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x45, 0x7B, 0xFF, 0xC6, 0x67, + 0x87, 0xBF, 0xF7, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x6F, 0xF9, 0x56, + 0x87, 0xEF, 0x84, 0x44, 0x45, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x58, 0xFD, 0x46, + 0x87, 0xFF, 0x54, 0x44, 0x56, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xFF, 0x45, + 0x87, 0xFF, 0x44, 0x45, 0x67, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0xFF, 0x45, + 0x87, 0xFF, 0x44, 0x56, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xFF, 0x44, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xFF, 0x44, + 0x87, 0xEF, 0x84, 0x56, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFE, 0x44, + 0x87, 0xAF, 0xF6, 0x56, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x9F, 0xF9, 0x44, + 0x87, 0x7D, 0xFF, 0xB8, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x9C, 0xFF, 0xD4, 0x45, + 0x87, 0x76, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x54, 0x45, + 0x87, 0x76, 0x56, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDB, 0x64, 0x44, 0x46, + 0x87, 0x77, 0x65, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x56, + 0x88, 0x77, 0x76, 0x55, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x55, 0x67, + 0x88, 0x77, 0x77, 0x66, 0x65, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x56, 0x66, 0x78, + 0x88, 0x88, 0x77, 0x77, 0x76, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x77, 0x78, +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/cancel_64x64x4.cpp b/Marlin/src/lcd/tft/images/cancel_64x64x4.cpp new file mode 100644 index 000000000000..a315e2df1cbe --- /dev/null +++ b/Marlin/src/lcd/tft/images/cancel_64x64x4.cpp @@ -0,0 +1,94 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t cancel_64x64x4[2048] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x88, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xDD, 0xB7, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8D, 0xBA, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xFA, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xDF, 0xFF, 0xA7, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xDF, 0xFF, 0xFF, 0xA7, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xFA, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xFF, 0xFA, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xDF, 0xFF, 0xFF, 0xFF, 0xA7, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x78, 0x88, 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x77, 0x88, 0x88, 0x88, 0x78, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x78, 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x97, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x77, 0x88, 0x78, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x76, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x77, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x78, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x76, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x66, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x76, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x66, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x76, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x66, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x76, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x66, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x6A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x66, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x96, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x79, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x66, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x76, 0x66, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x66, 0x67, 0x76, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x97, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x76, 0x66, 0x78, 0x87, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD7, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD7, 0x66, 0x67, 0x88, 0x88, 0x76, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x76, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x9F, 0xFF, 0xFF, 0xFF, 0xFC, 0x76, 0x66, 0x78, 0x88, 0x88, 0x87, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xD7, 0x66, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x69, 0xFF, 0xFF, 0xFF, 0xC7, 0x66, 0x67, 0x88, 0x88, 0x88, 0x88, 0x76, 0x9F, 0xFF, 0xFF, 0xFD, 0x76, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x9F, 0xFF, 0xFC, 0x76, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x87, 0x69, 0xFF, 0xFF, 0xD7, 0x66, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x69, 0xFF, 0xD7, 0x66, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x9F, 0xDD, 0x76, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0xA9, 0x76, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x68, 0x77, 0x66, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x66, 0x66, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x66, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x66, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/chamber_64x64x4.cpp b/Marlin/src/lcd/tft/images/chamber_64x64x4.cpp new file mode 100644 index 000000000000..23722f616d13 --- /dev/null +++ b/Marlin/src/lcd/tft/images/chamber_64x64x4.cpp @@ -0,0 +1,161 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t chamber_64x64x4[2048] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xAE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEA, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x67, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x8F, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x45, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x56, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x56, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x56, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x56, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x56, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x56, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x56, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x56, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x56, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x89, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x56, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x75, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x56, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x57, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +extern const uint8_t chamber_heated_64x64x4[2048] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xAE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEA, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x67, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x8F, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x45, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x77, 0x9B, 0x97, 0x88, 0x88, 0x87, 0x8B, 0xA8, 0x78, 0x88, 0x87, 0x8B, 0xB8, 0x78, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x56, 0x88, 0x88, 0x79, 0xFF, 0xF9, 0x78, 0x88, 0x78, 0xDF, 0xFB, 0x78, 0x88, 0x77, 0xCF, 0xFC, 0x87, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x7A, 0xFF, 0xFD, 0x77, 0x88, 0x79, 0xFF, 0xFF, 0x87, 0x88, 0x78, 0xDF, 0xFF, 0x97, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x56, 0x88, 0x88, 0x79, 0xFF, 0xFF, 0x86, 0x88, 0x78, 0xDF, 0xFF, 0xB6, 0x88, 0x77, 0xCF, 0xFF, 0xC6, 0x78, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xB6, 0x78, 0x87, 0x9F, 0xFF, 0xD6, 0x78, 0x87, 0x8E, 0xFF, 0xF7, 0x68, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x88, 0x7D, 0xFF, 0xE5, 0x67, 0x87, 0x7B, 0xFF, 0xF7, 0x57, 0x88, 0x79, 0xFF, 0xFA, 0x57, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x56, 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xE6, 0x57, 0x87, 0x8C, 0xFF, 0xF7, 0x57, 0x88, 0x7A, 0xFF, 0xFA, 0x56, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xD5, 0x57, 0x87, 0x8E, 0xFF, 0xE6, 0x57, 0x88, 0x7C, 0xFF, 0xF8, 0x56, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x77, 0xCF, 0xFF, 0xA5, 0x57, 0x87, 0xAF, 0xFF, 0xD5, 0x57, 0x87, 0x9F, 0xFF, 0xE6, 0x56, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x56, 0x88, 0x88, 0x79, 0xFF, 0xFF, 0x75, 0x57, 0x78, 0xEF, 0xFF, 0xA5, 0x57, 0x87, 0xCF, 0xFF, 0xB5, 0x56, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x87, 0x7C, 0xFF, 0xFB, 0x55, 0x67, 0x7B, 0xFF, 0xFE, 0x65, 0x57, 0x79, 0xFF, 0xFF, 0x85, 0x57, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x87, 0x9F, 0xFF, 0xF7, 0x55, 0x67, 0x8E, 0xFF, 0xF8, 0x55, 0x67, 0x7D, 0xFF, 0xFB, 0x55, 0x67, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x56, 0x88, 0x87, 0xCF, 0xFF, 0xB5, 0x55, 0x77, 0x9F, 0xFF, 0xD6, 0x55, 0x77, 0x8F, 0xFF, 0xE7, 0x55, 0x68, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x77, 0xDF, 0xFF, 0x75, 0x56, 0x87, 0xBF, 0xFF, 0xA5, 0x56, 0x77, 0xAF, 0xFF, 0xB5, 0x55, 0x78, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x78, 0xEF, 0xFD, 0x65, 0x67, 0x77, 0xCF, 0xFF, 0x85, 0x57, 0x87, 0xBF, 0xFF, 0x95, 0x56, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x56, 0x88, 0x78, 0xEF, 0xFD, 0x55, 0x68, 0x77, 0xCF, 0xFF, 0x75, 0x68, 0x87, 0xBF, 0xFF, 0x95, 0x67, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x78, 0xDF, 0xFF, 0x65, 0x78, 0x77, 0xBF, 0xFF, 0x95, 0x68, 0x87, 0xAF, 0xFF, 0xB5, 0x68, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x87, 0x9F, 0xFF, 0xF8, 0x68, 0x87, 0x8E, 0xFF, 0xF9, 0x68, 0x87, 0x7C, 0xFF, 0xFC, 0x67, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x56, 0x88, 0x88, 0x7B, 0xFF, 0xFA, 0x58, 0x88, 0x7B, 0xFF, 0xFC, 0x57, 0x88, 0x78, 0xFF, 0xFE, 0x67, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x77, 0xDF, 0xD7, 0x57, 0x88, 0x87, 0xBF, 0xF8, 0x56, 0x88, 0x87, 0xAF, 0xFA, 0x56, 0x78, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x87, 0x69, 0x75, 0x56, 0x88, 0x87, 0x68, 0x85, 0x56, 0x78, 0x87, 0x68, 0x85, 0x55, 0x78, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x56, 0x88, 0x88, 0x88, 0x65, 0x55, 0x57, 0x88, 0x88, 0x75, 0x55, 0x56, 0x88, 0x88, 0x75, 0x55, 0x56, 0x78, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x77, 0x77, 0x77, 0x77, 0x76, 0x55, 0x67, 0x77, 0x77, 0x76, 0x55, 0x67, 0x77, 0x77, 0x76, 0x55, 0x57, 0x77, 0x77, 0x77, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xF9, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x88, 0x88, 0x88, 0x88, 0x87, 0x88, 0x88, 0x88, 0x88, 0x87, 0x88, 0x88, 0x88, 0x88, 0xBF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x56, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x89, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x56, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x75, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x56, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x57, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/confirm_64x64x4.cpp b/Marlin/src/lcd/tft/images/confirm_64x64x4.cpp new file mode 100644 index 000000000000..ff623ed34917 --- /dev/null +++ b/Marlin/src/lcd/tft/images/confirm_64x64x4.cpp @@ -0,0 +1,94 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t confirm_64x64x4[2048] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xA8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFC, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xCF, 0xFF, 0xC7, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFB, 0x77, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xCF, 0xFF, 0xFF, 0xFF, 0xB7, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x55, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xA8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x94, 0x44, 0x68, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8D, 0xFB, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x44, 0x45, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xDF, 0xFF, 0xB7, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x94, 0x44, 0x57, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xFB, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x44, 0x45, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x78, 0xDF, 0xFF, 0xFF, 0xFF, 0xB7, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x44, 0x57, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x44, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB7, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x44, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x77, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x44, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x76, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x78, 0x88, 0x88, 0x88, 0x77, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x44, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x86, 0x4B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x77, 0x88, 0x88, 0x87, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x44, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x64, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB7, 0x78, 0x88, 0x77, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x44, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x4B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x77, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x44, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x64, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB7, 0x78, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x44, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x4B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x44, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x65, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x94, 0x44, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x5B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x44, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x64, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x94, 0x44, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x5B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x44, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x64, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x94, 0x44, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x4B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x44, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x65, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x44, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x4B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x44, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x65, 0xBF, 0xFF, 0xFF, 0xFF, 0x94, 0x44, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x4B, 0xFF, 0xFF, 0xFA, 0x44, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x64, 0xBF, 0xFF, 0x94, 0x44, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x4B, 0xFA, 0x44, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x65, 0x75, 0x44, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x44, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x65, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/decrease_64x64x4.cpp b/Marlin/src/lcd/tft/images/decrease_64x64x4.cpp new file mode 100644 index 000000000000..b58670098622 --- /dev/null +++ b/Marlin/src/lcd/tft/images/decrease_64x64x4.cpp @@ -0,0 +1,94 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t decrease_64x64x4[2048] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB5, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB3, 0x58, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB3, 0x58, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB3, 0x58, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB3, 0x58, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB3, 0x58, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB3, 0x58, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xAD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x94, 0x58, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x85, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x58, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x58, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/directory_32x32x4.cpp b/Marlin/src/lcd/tft/images/directory_32x32x4.cpp new file mode 100644 index 000000000000..5fa55c8468f0 --- /dev/null +++ b/Marlin/src/lcd/tft/images/directory_32x32x4.cpp @@ -0,0 +1,62 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t directory_32x32x4[512] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, + 0x88, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x78, 0x88, + 0x88, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x78, 0x88, + 0x88, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0x88, + 0x88, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0x88, + 0x88, 0x88, 0x76, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x68, 0x88, + 0x88, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0x88, + 0x88, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0x88, + 0x88, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0x88, + 0x88, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0x88, + 0x88, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0x88, + 0x88, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0x88, + 0x88, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0x88, + 0x88, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0x88, + 0x88, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0x88, + 0x88, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0x88, + 0x88, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0x88, + 0x88, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0x88, + 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x68, 0x88, + 0x88, 0x88, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x68, 0x88, + 0x88, 0x88, 0x87, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/down_32x32x4.cpp b/Marlin/src/lcd/tft/images/down_32x32x4.cpp new file mode 100644 index 000000000000..eabf6f97fec5 --- /dev/null +++ b/Marlin/src/lcd/tft/images/down_32x32x4.cpp @@ -0,0 +1,62 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t down_32x32x4[512] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x88, 0x88, 0x88, + 0x88, 0x87, 0x78, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x98, 0x88, 0x88, 0x88, + 0x88, 0x87, 0x8F, 0xB4, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xFA, 0x48, 0x88, 0x88, + 0x88, 0x78, 0xFF, 0xFA, 0x38, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8F, 0xFF, 0x84, 0x88, 0x88, + 0x88, 0x7F, 0xFF, 0xFF, 0xA3, 0x88, 0x88, 0x88, 0x88, 0x87, 0x78, 0xFF, 0xFF, 0xFA, 0x47, 0x88, + 0x88, 0x7A, 0xFF, 0xFF, 0xFA, 0x38, 0x88, 0x88, 0x88, 0x77, 0x8F, 0xFF, 0xFF, 0xC5, 0x35, 0x88, + 0x88, 0x77, 0x9F, 0xFF, 0xFF, 0xA3, 0x88, 0x88, 0x87, 0x79, 0xFF, 0xFF, 0xFC, 0x43, 0x46, 0x88, + 0x88, 0x87, 0x79, 0xFF, 0xFF, 0xFA, 0x47, 0x88, 0x77, 0x9F, 0xFF, 0xFF, 0xC4, 0x34, 0x78, 0x88, + 0x88, 0x88, 0x77, 0x9F, 0xFF, 0xFF, 0xA4, 0x78, 0x79, 0xFF, 0xFF, 0xFC, 0x43, 0x47, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x79, 0xFF, 0xFF, 0xF9, 0x47, 0x9F, 0xFF, 0xFF, 0xC3, 0x34, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x77, 0x9F, 0xFF, 0xFF, 0x96, 0xFF, 0xFF, 0xFC, 0x33, 0x47, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x79, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, 0x44, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x77, 0x9F, 0xFF, 0xFF, 0xFF, 0xFD, 0x34, 0x47, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x79, 0xFF, 0xFF, 0xFF, 0xC3, 0x44, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x9F, 0xFF, 0xFC, 0x33, 0x47, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x79, 0xFF, 0xC3, 0x34, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xAC, 0x43, 0x47, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x86, 0x34, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x66, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/fan_64x64x4.cpp b/Marlin/src/lcd/tft/images/fan_64x64x4.cpp new file mode 100644 index 000000000000..1a154a6ea415 --- /dev/null +++ b/Marlin/src/lcd/tft/images/fan_64x64x4.cpp @@ -0,0 +1,161 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t fan0_64x64x4[2048] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x78, 0x9A, 0xCC, 0xCB, 0xBA, 0x98, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x89, 0xBC, 0xEF, 0xFF, 0xFF, 0xFF, 0xED, 0xB9, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x9B, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8B, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB7, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x96, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x58, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x59, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x84, 0x58, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x75, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x64, 0x58, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x6D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x44, 0x58, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x45, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC5, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x74, 0x46, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x44, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC5, 0x44, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x64, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x44, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0x84, 0x44, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7B, 0xFE, 0xA7, 0x67, 0xBF, 0xF9, 0x44, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xC6, 0x44, 0x44, 0x48, 0x94, 0x44, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x88, 0x88, 0x88, 0x87, 0x8A, 0x64, 0x44, 0x44, 0x44, 0x44, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x87, 0x54, 0x6A, 0xCB, 0x86, 0x54, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x78, 0x9A, 0xBB, 0xBB, 0xBA, 0x98, 0x87, 0x77, 0x87, 0x46, 0xEF, 0xFF, 0xFA, 0x76, 0x88, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x78, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xDB, 0xA9, 0x87, 0x7C, 0xFF, 0xFF, 0xFD, 0x77, 0xAC, 0x87, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0x75, 0x9F, 0xEA, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x87, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x77, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x66, 0x8F, 0xFF, 0xFF, 0xFF, 0x74, 0x8E, 0xFF, 0xDA, 0x98, 0x87, 0x78, 0x89, 0xAB, 0xCD, 0xDA, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x79, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x54, 0x7C, 0xFF, 0xFF, 0xFC, 0x54, 0x8F, 0xFF, 0xFF, 0xEE, 0xDC, 0xDD, 0xEE, 0xFF, 0xFF, 0xFF, 0x97, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x74, 0x78, 0xCF, 0xFF, 0xD6, 0x44, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x95, 0x78, 0x88, + 0x88, 0x88, 0x88, 0x7B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC5, 0x77, 0x58, 0xA9, 0x54, 0x45, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x84, 0x68, 0x88, + 0x88, 0x88, 0x88, 0x7B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x77, 0x64, 0x44, 0x44, 0x5B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x74, 0x68, 0x88, + 0x88, 0x88, 0x88, 0x7B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDA, 0x86, 0x54, 0x59, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x54, 0x68, 0x88, + 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB8, 0x76, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x44, 0x68, 0x88, + 0x88, 0x88, 0x88, 0x79, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB7, 0x66, 0x78, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x45, 0x78, 0x88, + 0x88, 0x88, 0x88, 0x78, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0x44, 0x44, 0x57, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0x45, 0x78, 0x88, + 0x88, 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x64, 0x44, 0x45, 0x68, 0x78, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0x44, 0x45, 0x67, 0x88, 0x77, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x84, 0x47, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x7B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x84, 0x45, 0x57, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x64, 0x57, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x44, 0x46, 0x88, 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x44, 0x68, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x77, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x44, 0x57, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x44, 0x68, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB5, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, 0x78, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x74, 0x45, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0x84, 0x46, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x44, 0x46, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x85, 0x8F, 0xFF, 0xFF, 0xFF, 0xFD, 0x54, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x44, 0x68, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x59, 0xFF, 0xFF, 0xFF, 0xFB, 0x44, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x54, 0x45, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x75, 0x9F, 0xFF, 0xFF, 0xF7, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x44, 0x57, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x59, 0xFF, 0xFF, 0xD5, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x57, 0xDF, 0xFF, 0xFF, 0xD8, 0x44, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x75, 0x8D, 0xFF, 0x84, 0x46, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x75, 0x59, 0xCC, 0xC9, 0x64, 0x44, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x55, 0x76, 0x44, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x54, 0x55, 0x54, 0x44, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x75, 0x44, 0x44, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x44, 0x44, 0x45, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x65, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x55, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +extern const uint8_t fan1_64x64x4[2048] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x65, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x75, 0x45, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x65, 0x44, 0x44, 0x46, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x64, 0x44, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x75, 0x44, 0x44, 0x55, 0x54, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x54, 0x46, 0x75, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x54, 0x44, 0x69, 0xCC, 0xC9, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x44, 0x8F, 0xFD, 0x85, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x75, 0x44, 0x48, 0xDF, 0xFF, 0xFF, 0xD7, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x75, 0x45, 0xDF, 0xFF, 0xF9, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x54, 0x45, 0xAF, 0xFF, 0xFF, 0xFF, 0xFE, 0x76, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x75, 0x47, 0xFF, 0xFF, 0xFF, 0x95, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x75, 0x44, 0x5B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x64, 0x4B, 0xFF, 0xFF, 0xFF, 0xF9, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x64, 0x44, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x54, 0x5D, 0xFF, 0xFF, 0xFF, 0xFF, 0x85, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x86, 0x44, 0x48, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x97, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x44, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x75, 0x44, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x75, 0x45, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x87, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x64, 0x45, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x78, 0x88, 0x88, 0x88, 0x87, 0x54, 0x47, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB7, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x64, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x87, 0x88, 0x88, 0x88, 0x86, 0x44, 0x4B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x54, 0x6E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x97, 0x88, 0x88, 0x87, 0x55, 0x44, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x77, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x44, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x78, 0x87, 0x65, 0x44, 0x46, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x87, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x86, 0x44, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0x78, 0x65, 0x44, 0x44, 0x6D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x75, 0x46, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x77, 0x54, 0x44, 0x48, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD8, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x75, 0x48, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x88, 0x76, 0x67, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x64, 0x4B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x76, 0x78, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x64, 0x5D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD9, 0x54, 0x56, 0x8A, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x64, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x54, 0x44, 0x44, 0x67, 0x7B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x64, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x44, 0x59, 0xA8, 0x57, 0x75, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x75, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x94, 0x46, 0xDF, 0xFF, 0xC8, 0x74, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFE, 0xED, 0xDC, 0xDE, 0xEF, 0xFF, 0xFF, 0x84, 0x5C, 0xFF, 0xFF, 0xFC, 0x74, 0x5E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x8A, 0xDD, 0xCB, 0xA9, 0x88, 0x77, 0x88, 0x9A, 0xDF, 0xFE, 0x84, 0x7F, 0xFF, 0xFF, 0xFF, 0x86, 0x6E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x77, 0x88, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x8A, 0xEF, 0x95, 0x7F, 0xFF, 0xFF, 0xFF, 0x97, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x87, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x8C, 0xA7, 0x7D, 0xFF, 0xFF, 0xFC, 0x77, 0x89, 0xAB, 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xA8, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0x86, 0x7A, 0xFF, 0xFF, 0xE6, 0x47, 0x87, 0x77, 0x88, 0x9A, 0xBB, 0xBB, 0xBA, 0x98, 0x77, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x54, 0x56, 0x8B, 0xCA, 0x64, 0x57, 0x88, 0x88, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x75, 0x44, 0x44, 0x44, 0x44, 0x44, 0x6A, 0x87, 0x88, 0x88, 0x88, 0x87, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x54, 0x44, 0x98, 0x44, 0x44, 0x46, 0xCC, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x75, 0x44, 0x49, 0xFF, 0xB7, 0x67, 0xAE, 0xFB, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x64, 0x44, 0x8F, 0xFF, 0xFF, 0xEF, 0xFF, 0xFA, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x54, 0x47, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x75, 0x44, 0x6D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x64, 0x45, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x54, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x44, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x75, 0x45, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x65, 0x48, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x54, 0x4C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x66, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x54, 0x6E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB5, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x54, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x54, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x86, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x74, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x79, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDB, 0x97, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x79, 0xBD, 0xEF, 0xFF, 0xFF, 0xFF, 0xEC, 0xB9, 0x87, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x78, 0x9A, 0xBB, 0xCC, 0xCA, 0x98, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/fan_fast_64x64x4.cpp b/Marlin/src/lcd/tft/images/fan_fast_64x64x4.cpp new file mode 100644 index 000000000000..4586954ccf57 --- /dev/null +++ b/Marlin/src/lcd/tft/images/fan_fast_64x64x4.cpp @@ -0,0 +1,161 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t fan_fast0_64x64x4[2048] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x78, 0x89, 0x98, 0x88, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x8A, 0xBD, 0xEF, 0xFE, 0xEC, 0xBA, 0x87, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x89, 0xAC, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0x97, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x79, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x89, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x78, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0x9C, 0xED, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8A, 0xDE, 0xDD, 0xCE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xBD, 0xED, 0xDD, 0xDD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8A, 0xDD, 0xDD, 0xDD, 0xDC, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xAC, 0xDD, 0xDD, 0xDD, 0xDD, 0xCD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x85, 0x68, 0x88, 0x87, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x79, 0xCB, 0xCD, 0xDD, 0xDD, 0xDD, 0xDC, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x65, 0x68, 0x88, 0x78, 0x88, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x8B, 0xCA, 0xAC, 0xDD, 0xDD, 0xDD, 0xDD, 0xCE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x55, 0x68, 0x87, 0x8A, 0xBA, 0x87, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x78, 0xAC, 0xBA, 0xAA, 0xBC, 0xDD, 0xDD, 0xDD, 0xCD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0x55, 0x78, 0x78, 0xAC, 0xBB, 0x97, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x79, 0xCB, 0xAA, 0xAA, 0xAA, 0xBC, 0xDD, 0xDD, 0xDC, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x56, 0x78, 0x8A, 0xCB, 0xAA, 0xA8, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x8B, 0xCA, 0xAA, 0xAA, 0xAA, 0xAA, 0xCD, 0xDD, 0xDC, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x65, 0x57, 0x87, 0x9C, 0xBA, 0xAA, 0xB9, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x9B, 0xBA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0xDD, 0xDD, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x55, 0x67, 0x79, 0xBB, 0xBA, 0xAA, 0xAA, 0x77, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x9C, 0xBA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xBD, 0xDD, 0xCE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x95, 0x55, 0x77, 0x9B, 0xCB, 0xAA, 0xAA, 0xAA, 0x96, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x89, 0xAA, 0xAB, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0xDD, 0xCE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x55, 0x56, 0x79, 0xBC, 0xBA, 0xAA, 0xAA, 0xAA, 0xA6, 0x68, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x67, 0x88, 0x9A, 0xAA, 0xAA, 0xAA, 0xAA, 0xCD, 0xCD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC5, 0x55, 0x68, 0xAB, 0xCB, 0xAA, 0xAA, 0xAA, 0xAB, 0xB8, 0x68, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x55, 0x55, 0x56, 0x78, 0x9A, 0xAA, 0xAA, 0xBD, 0xCE, 0xFF, 0xFD, 0xDE, 0xFF, 0xFC, 0x65, 0x56, 0x9B, 0xCB, 0xBA, 0xAA, 0xAA, 0xAB, 0xCD, 0xDB, 0x67, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x65, 0x55, 0x55, 0x57, 0x9A, 0xAA, 0xAC, 0xDE, 0xFB, 0x86, 0x67, 0x8C, 0xE8, 0x77, 0x8A, 0xCC, 0xBA, 0xAA, 0xAA, 0xAA, 0xCD, 0xDD, 0xDD, 0x86, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x65, 0x55, 0x58, 0xAA, 0xAB, 0xDD, 0x95, 0x55, 0x55, 0x56, 0x68, 0xAA, 0xBB, 0xBB, 0xAA, 0xAA, 0xAA, 0xCD, 0xDD, 0xDD, 0xDD, 0x95, 0x78, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x76, 0x55, 0x7A, 0xAB, 0xC8, 0x55, 0x57, 0x87, 0x55, 0x56, 0xAC, 0xAA, 0xAA, 0xAA, 0xAB, 0xCD, 0xDD, 0xDD, 0xDD, 0xDD, 0xB5, 0x68, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x78, 0x88, 0x88, 0x88, 0x76, 0x56, 0xAB, 0x95, 0x55, 0xAE, 0xFF, 0xB7, 0x65, 0x7C, 0xDC, 0xCB, 0xCC, 0xCD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xC6, 0x57, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x8A, 0xCD, 0xEE, 0xEE, 0xED, 0xCB, 0x96, 0x89, 0x65, 0x5A, 0xFF, 0xFF, 0xFC, 0x77, 0x9C, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xC6, 0x57, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x79, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xDB, 0x65, 0x6E, 0xFF, 0xFF, 0xFE, 0x77, 0x9E, 0xEC, 0xCD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDC, 0xCC, 0xCD, 0xC6, 0x57, 0x88, + 0x88, 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x65, 0x8F, 0xFF, 0xFF, 0xFF, 0x75, 0x9F, 0xFF, 0xDD, 0xCC, 0xCC, 0xCC, 0xCC, 0xDD, 0xDD, 0xDD, 0xC6, 0x57, 0x88, + 0x88, 0x88, 0x88, 0x78, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x65, 0x8E, 0xFF, 0xFF, 0xFE, 0x65, 0x8F, 0xFF, 0xFF, 0xEE, 0xDD, 0xDD, 0xEE, 0xEF, 0xFF, 0xFF, 0xD6, 0x57, 0x88, + 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x85, 0x7A, 0xFF, 0xFF, 0xFA, 0x55, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0x57, 0x88, + 0x88, 0x88, 0x88, 0x7B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB5, 0x77, 0x9D, 0xFD, 0xA5, 0x55, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0x57, 0x88, + 0x88, 0x88, 0x88, 0x7B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x67, 0x66, 0x66, 0x55, 0x58, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC5, 0x57, 0x88, + 0x88, 0x88, 0x88, 0x7B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x97, 0x75, 0x55, 0x56, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x95, 0x57, 0x88, + 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xA8, 0x66, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x65, 0x67, 0x88, + 0x88, 0x88, 0x88, 0x79, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xCB, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x67, 0x88, + 0x88, 0x88, 0x88, 0x78, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDC, 0xDD, 0xCB, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x55, 0x68, 0x88, + 0x88, 0x88, 0x88, 0x87, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0xCD, 0xDB, 0xA9, 0x57, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0x55, 0x78, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xCC, 0xDD, 0xBA, 0xA8, 0x55, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB5, 0x56, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xDD, 0xDC, 0xAA, 0xA7, 0x55, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x85, 0x57, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDC, 0xDD, 0xDB, 0xAA, 0xA7, 0x56, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x65, 0x67, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x78, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xCD, 0xDD, 0xCA, 0xAA, 0xA7, 0x56, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x55, 0x68, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xDD, 0xDD, 0xCA, 0xAA, 0xA7, 0x56, 0x79, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x55, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x7B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xDD, 0xDD, 0xBA, 0xAA, 0xA8, 0x56, 0x87, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x56, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDC, 0xDD, 0xDD, 0xBA, 0xAA, 0xB9, 0x56, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0x55, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xCD, 0xDD, 0xDD, 0xBA, 0xAA, 0xA9, 0x56, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x85, 0x55, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x67, 0xEF, 0xFF, 0xFF, 0xFE, 0xCD, 0xDD, 0xDD, 0xBA, 0xAA, 0xAA, 0x76, 0x88, 0x76, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0x55, 0x56, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x7E, 0xFF, 0xFF, 0xFD, 0xCD, 0xDD, 0xDD, 0xBA, 0xAA, 0xAA, 0x85, 0x78, 0x87, 0x6B, 0xFF, 0xFF, 0xFF, 0xFD, 0x75, 0x55, 0x67, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x67, 0xDF, 0xFF, 0xEC, 0xDD, 0xDD, 0xDD, 0xBA, 0xAA, 0xAA, 0xA6, 0x68, 0x88, 0x76, 0xAE, 0xFF, 0xFE, 0xA6, 0x55, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x6B, 0xFF, 0xDC, 0xDD, 0xDD, 0xDD, 0xBA, 0xAA, 0xAA, 0xA7, 0x68, 0x88, 0x86, 0x56, 0x89, 0x86, 0x55, 0x55, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x65, 0x8B, 0xDD, 0xDD, 0xDD, 0xDD, 0xBA, 0xAA, 0xAA, 0xA9, 0x57, 0x88, 0x88, 0x65, 0x55, 0x55, 0x55, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x55, 0x8B, 0xDD, 0xDD, 0xDD, 0xAA, 0xAA, 0xAA, 0xAA, 0x66, 0x88, 0x88, 0x87, 0x65, 0x55, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x65, 0x56, 0x8B, 0xDD, 0xDC, 0xAA, 0xAA, 0xAA, 0xBA, 0x65, 0x78, 0x88, 0x88, 0x87, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x65, 0x55, 0x79, 0x99, 0x99, 0xAA, 0xAA, 0x97, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x65, 0x55, 0x55, 0x56, 0x66, 0x66, 0x65, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x66, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x76, 0x66, 0x66, 0x66, 0x66, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +extern const uint8_t fan_fast1_64x64x4[2048] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x66, 0x66, 0x66, 0x66, 0x66, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x75, 0x55, 0x55, 0x55, 0x55, 0x55, 0x56, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x75, 0x55, 0x66, 0x66, 0x66, 0x55, 0x55, 0x55, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x75, 0x57, 0x9A, 0xAA, 0xA9, 0x99, 0x99, 0x75, 0x55, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x88, 0x88, 0x88, 0x75, 0x6A, 0xBA, 0xAA, 0xAA, 0xAC, 0xDD, 0xDB, 0x86, 0x55, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x55, 0x55, 0x67, 0x88, 0x88, 0x86, 0x6A, 0xAA, 0xAA, 0xAA, 0xAD, 0xDD, 0xDD, 0xDB, 0x85, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x55, 0x55, 0x55, 0x55, 0x68, 0x88, 0x87, 0x59, 0xAA, 0xAA, 0xAA, 0xBD, 0xDD, 0xDD, 0xDD, 0xDB, 0x85, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x65, 0x55, 0x56, 0x89, 0x86, 0x56, 0x88, 0x88, 0x67, 0xAA, 0xAA, 0xAA, 0xBD, 0xDD, 0xDD, 0xDC, 0xDF, 0xFB, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x55, 0x56, 0xAE, 0xFF, 0xFE, 0xA6, 0x78, 0x88, 0x66, 0xAA, 0xAA, 0xAA, 0xBD, 0xDD, 0xDD, 0xDC, 0xEF, 0xFF, 0xD7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x65, 0x55, 0x7D, 0xFF, 0xFF, 0xFF, 0xFB, 0x67, 0x88, 0x75, 0x8A, 0xAA, 0xAA, 0xBD, 0xDD, 0xDD, 0xCD, 0xFF, 0xFF, 0xFE, 0x76, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x86, 0x55, 0x58, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x78, 0x86, 0x7A, 0xAA, 0xAA, 0xBD, 0xDD, 0xDD, 0xCE, 0xFF, 0xFF, 0xFF, 0xE7, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x75, 0x55, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x78, 0x86, 0x59, 0xAA, 0xAA, 0xBD, 0xDD, 0xDD, 0xCF, 0xFF, 0xFF, 0xFF, 0xFE, 0x76, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x65, 0x56, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x87, 0x86, 0x59, 0xBA, 0xAA, 0xBD, 0xDD, 0xDC, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x86, 0x55, 0x5C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x86, 0x58, 0xAA, 0xAA, 0xBD, 0xDD, 0xDC, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x75, 0x55, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x76, 0x57, 0xAA, 0xAA, 0xCD, 0xDD, 0xDD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x65, 0x58, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x76, 0x57, 0xAA, 0xAA, 0xCD, 0xDD, 0xCE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD8, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x65, 0x6D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x86, 0x57, 0xAA, 0xAB, 0xDD, 0xDC, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x55, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB5, 0x57, 0xAA, 0xAC, 0xDD, 0xDC, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x87, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x86, 0x55, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x58, 0xAA, 0xBD, 0xDC, 0xCE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x97, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x75, 0x56, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x59, 0xAB, 0xDD, 0xCD, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x65, 0x59, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x7B, 0xCD, 0xDC, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0x78, 0x88, 0x88, + 0x88, 0x87, 0x65, 0x5C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBB, 0xCC, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x78, 0x88, 0x88, + 0x88, 0x87, 0x65, 0x6E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x86, 0x68, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x78, 0x88, 0x88, + 0x88, 0x87, 0x55, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x96, 0x55, 0x55, 0x77, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x78, 0x88, 0x88, + 0x88, 0x87, 0x55, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x55, 0x56, 0x66, 0x67, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x78, 0x88, 0x88, + 0x88, 0x87, 0x56, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB5, 0x55, 0xAD, 0xFD, 0x97, 0x75, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x78, 0x88, 0x88, + 0x88, 0x87, 0x56, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x95, 0x5A, 0xFF, 0xFF, 0xFA, 0x75, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x78, 0x88, 0x88, + 0x88, 0x87, 0x56, 0xDF, 0xFF, 0xFF, 0xEE, 0xED, 0xDD, 0xDE, 0xEF, 0xFF, 0xFF, 0x85, 0x6E, 0xFF, 0xFF, 0xFE, 0x85, 0x6E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0x78, 0x88, 0x88, + 0x88, 0x87, 0x56, 0xCD, 0xDD, 0xDD, 0xDC, 0xCC, 0xCC, 0xCC, 0xCD, 0xDF, 0xFF, 0x95, 0x7F, 0xFF, 0xFF, 0xFF, 0x85, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x88, 0x88, 0x88, + 0x88, 0x87, 0x56, 0xCD, 0xCC, 0xCC, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xCC, 0xEE, 0x97, 0x7E, 0xFF, 0xFF, 0xFE, 0x65, 0x6B, 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD9, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x87, 0x56, 0xCD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDC, 0x97, 0x7C, 0xFF, 0xFF, 0xFA, 0x55, 0x69, 0x86, 0x9B, 0xCD, 0xEE, 0xEE, 0xED, 0xCA, 0x87, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x87, 0x56, 0xCD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xCC, 0xCB, 0xCC, 0xDC, 0x75, 0x67, 0xBF, 0xFE, 0xA5, 0x55, 0x9B, 0xA6, 0x56, 0x78, 0x88, 0x88, 0x88, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x65, 0xBD, 0xDD, 0xDD, 0xDD, 0xDD, 0xCB, 0xAA, 0xAA, 0xAA, 0xAC, 0xA6, 0x55, 0x57, 0x87, 0x55, 0x58, 0xCB, 0xAA, 0x75, 0x56, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x75, 0x9D, 0xDD, 0xDD, 0xDD, 0xCA, 0xAA, 0xAA, 0xAB, 0xBB, 0xBA, 0xA8, 0x66, 0x55, 0x55, 0x55, 0x9D, 0xDB, 0xAA, 0xA8, 0x55, 0x55, 0x67, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x86, 0x8D, 0xDD, 0xDD, 0xCA, 0xAA, 0xAA, 0xAA, 0xBC, 0xCA, 0x87, 0x78, 0xEC, 0x87, 0x66, 0x8B, 0xFE, 0xDC, 0xAA, 0xAA, 0x97, 0x55, 0x55, 0x55, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x6B, 0xDD, 0xCB, 0xAA, 0xAA, 0xAA, 0xBB, 0xCB, 0x96, 0x55, 0x6C, 0xFF, 0xFE, 0xDD, 0xFF, 0xFE, 0xCD, 0xBA, 0xAA, 0xAA, 0x98, 0x76, 0x55, 0x55, 0x57, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x68, 0xBB, 0xAA, 0xAA, 0xAA, 0xAB, 0xCB, 0xA8, 0x65, 0x55, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xCD, 0xCA, 0xAA, 0xAA, 0xAA, 0xAA, 0x98, 0x87, 0x67, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x66, 0xAA, 0xAA, 0xAA, 0xAA, 0xBC, 0xB9, 0x76, 0x55, 0x5B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xCD, 0xDB, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0xAA, 0xA9, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x76, 0x9A, 0xAA, 0xAA, 0xAB, 0xCB, 0x97, 0x75, 0x55, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xCD, 0xDD, 0xBA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xBC, 0x97, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x7A, 0xAA, 0xAA, 0xBB, 0xB9, 0x77, 0x65, 0x57, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCD, 0xDD, 0xDB, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0x97, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x69, 0xBA, 0xAA, 0xBC, 0x97, 0x87, 0x55, 0x6D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDC, 0xDD, 0xDD, 0xCA, 0xAA, 0xAA, 0xAA, 0xAA, 0xCB, 0x87, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x78, 0xAA, 0xAB, 0xCA, 0x88, 0x76, 0x55, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xDD, 0xDD, 0xDC, 0xBA, 0xAA, 0xAA, 0xAB, 0xC9, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x9B, 0xBC, 0xA8, 0x78, 0x75, 0x56, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xCD, 0xDD, 0xDD, 0xDC, 0xBA, 0xAA, 0xBC, 0xA8, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x8A, 0xBA, 0x87, 0x88, 0x65, 0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xCD, 0xDD, 0xDD, 0xDD, 0xDC, 0xAA, 0xCB, 0x87, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0x88, 0x78, 0x88, 0x65, 0x6D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDC, 0xDD, 0xDD, 0xDD, 0xDD, 0xCB, 0xC9, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x88, 0x88, 0x65, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xCD, 0xDD, 0xDD, 0xDD, 0xDC, 0xA7, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x65, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDC, 0xDD, 0xDD, 0xDD, 0xDA, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x65, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xDD, 0xDD, 0xED, 0xB8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x75, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xCD, 0xDE, 0xDA, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0xEC, 0x98, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xB8, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB9, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x9C, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xA9, 0x87, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x8A, 0xBC, 0xEE, 0xFF, 0xED, 0xBA, 0x87, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x78, 0x88, 0x99, 0x88, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/fan_slow_64x64x4.cpp b/Marlin/src/lcd/tft/images/fan_slow_64x64x4.cpp new file mode 100644 index 000000000000..7bbd149ae797 --- /dev/null +++ b/Marlin/src/lcd/tft/images/fan_slow_64x64x4.cpp @@ -0,0 +1,161 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t fan_slow0_64x64x4[2048] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x89, 0x9A, 0xBB, 0xBB, 0xAA, 0x99, 0x87, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x78, 0xAB, 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xDB, 0x97, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x79, 0xCE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x97, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xAE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x8B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x89, 0xBC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xAC, 0xCB, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8B, 0xCB, 0xBB, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xBC, 0xBB, 0xBB, 0xBC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8A, 0xCB, 0xBB, 0xBB, 0xBB, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8B, 0xCB, 0xBB, 0xBB, 0xBB, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x8A, 0xCC, 0xBB, 0xBB, 0xBB, 0xBB, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD7, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0x9B, 0xCB, 0xBB, 0xBB, 0xBB, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x78, 0xAC, 0xCB, 0xBB, 0xBB, 0xBC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x89, 0xBC, 0xBB, 0xBB, 0xBB, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x8A, 0xBC, 0xBB, 0xBB, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0x9B, 0xCB, 0xBB, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x79, 0xBC, 0xBB, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9B, 0xCB, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB7, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x79, 0xCB, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x88, 0x87, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xAC, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x78, 0xAB, 0xA8, 0x78, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9B, 0xBE, 0xFF, 0xCA, 0xAB, 0xCE, 0xFD, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x78, 0xAB, 0xCC, 0xCA, 0x78, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8B, 0xCF, 0xD9, 0x77, 0x77, 0x79, 0xC8, 0x77, 0x88, 0x88, 0x88, 0x88, 0x87, 0x78, 0x9B, 0xCC, 0xBB, 0xCB, 0x87, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x8A, 0xCC, 0x87, 0x77, 0x77, 0x77, 0x77, 0x88, 0x77, 0x77, 0x77, 0x77, 0x78, 0x9B, 0xCC, 0xBB, 0xBB, 0xCB, 0x87, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x79, 0xB8, 0x77, 0x8A, 0xCB, 0x97, 0x77, 0x8A, 0xA9, 0x88, 0x88, 0x89, 0xAB, 0xCC, 0xBB, 0xBB, 0xBB, 0xBC, 0x97, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x77, 0x78, 0x99, 0xAA, 0x99, 0x98, 0x87, 0x77, 0x79, 0x97, 0x78, 0xDF, 0xFF, 0xEA, 0x77, 0x8A, 0xCB, 0xBB, 0xBB, 0xBB, 0xCC, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0x97, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x7A, 0xCE, 0xFF, 0xFF, 0xFF, 0xEE, 0xDC, 0xA9, 0x88, 0x87, 0x8C, 0xFF, 0xFF, 0xFE, 0x97, 0x8C, 0xCB, 0xBC, 0xCC, 0xCB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0x97, 0x88, + 0x88, 0x88, 0x88, 0x78, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0x77, 0x9F, 0xFF, 0xFF, 0xFF, 0xB7, 0x7C, 0xFD, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0x97, 0x88, + 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x77, 0x9F, 0xFF, 0xFF, 0xFF, 0xC7, 0x7B, 0xFF, 0xEC, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0xCD, 0xCC, 0x97, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x77, 0x8E, 0xFF, 0xFF, 0xFF, 0xA7, 0x7B, 0xFF, 0xFF, 0xED, 0xDC, 0xCC, 0xCD, 0xDE, 0xFF, 0xFF, 0xFE, 0x97, 0x88, + 0x88, 0x88, 0x78, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x87, 0x7B, 0xFF, 0xFF, 0xFD, 0x87, 0x7D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x88, + 0x88, 0x88, 0x79, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x78, 0xBE, 0xFF, 0xC8, 0x77, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x88, + 0x88, 0x88, 0x79, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD8, 0x77, 0x79, 0x99, 0x87, 0x78, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x88, + 0x88, 0x88, 0x79, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x87, 0x77, 0x77, 0x77, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x97, 0x88, + 0x88, 0x88, 0x78, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0x97, 0x78, 0x7B, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x87, 0x88, + 0x88, 0x88, 0x78, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCA, 0x98, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x78, 0x88, + 0x88, 0x88, 0x77, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDC, 0xCC, 0xA8, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x78, 0x88, + 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xBB, 0xCA, 0x87, 0x78, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0x78, 0x88, + 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBB, 0xBC, 0xA8, 0x78, 0x77, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x7B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0xBB, 0xBB, 0x87, 0x88, 0x87, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x97, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x79, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCB, 0xBB, 0xCA, 0x78, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x87, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x77, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xBB, 0xBC, 0xB8, 0x78, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0xBB, 0xBC, 0xA8, 0x78, 0x88, 0x88, 0x79, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDB, 0xBB, 0xBC, 0x97, 0x88, 0x88, 0x88, 0x87, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x87, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x78, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBB, 0xBB, 0xBC, 0x97, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xBB, 0xBB, 0xBB, 0x87, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB7, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x79, 0xEF, 0xFF, 0xFF, 0xFF, 0xFC, 0xBB, 0xBB, 0xCB, 0x87, 0x88, 0x88, 0x88, 0x88, 0x78, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x77, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFF, 0xFF, 0xEB, 0xBB, 0xBB, 0xCB, 0x87, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xDB, 0xBB, 0xBB, 0xCB, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xEF, 0xFF, 0xFF, 0xFF, 0xFB, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xAE, 0xFF, 0xFF, 0xCB, 0xBB, 0xBB, 0xCB, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9D, 0xFF, 0xFF, 0xFD, 0x97, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x79, 0xDF, 0xFD, 0xBB, 0xBB, 0xBB, 0xCB, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xAC, 0xCB, 0x98, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8A, 0xCC, 0xBB, 0xBB, 0xBB, 0xCB, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x8A, 0xBC, 0xBB, 0xBB, 0xCB, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0x8A, 0xBC, 0xCB, 0xCA, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x8A, 0xBB, 0xB9, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +extern const uint8_t fan_slow1_64x64x4[2048] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x79, 0xBB, 0xBA, 0x87, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8A, 0xCB, 0xCC, 0xBA, 0x88, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8B, 0xCB, 0xBB, 0xBC, 0xBA, 0x87, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8B, 0xCB, 0xBB, 0xBB, 0xBC, 0xCA, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x78, 0x9B, 0xCC, 0xA8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8B, 0xCB, 0xBB, 0xBB, 0xBD, 0xFF, 0xD9, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x9D, 0xFF, 0xFF, 0xFD, 0x97, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8B, 0xCB, 0xBB, 0xBB, 0xCF, 0xFF, 0xFE, 0xA7, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7B, 0xFF, 0xFF, 0xFF, 0xFF, 0xEA, 0x78, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8B, 0xCB, 0xBB, 0xBB, 0xDF, 0xFF, 0xFF, 0xFA, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x97, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8B, 0xCB, 0xBB, 0xBB, 0xEF, 0xFF, 0xFF, 0xFF, 0xA7, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x7B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0x78, 0x88, 0x88, 0x88, 0x87, 0x8B, 0xCB, 0xBB, 0xBC, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x77, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x77, 0x88, 0x88, 0x88, 0x87, 0x8B, 0xBB, 0xBB, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x97, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x79, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x97, 0x88, 0x88, 0x88, 0x87, 0x9C, 0xBB, 0xBB, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD8, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x88, 0x88, 0x88, 0x87, 0x9C, 0xBB, 0xBB, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x77, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x77, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x78, 0x88, 0x88, 0x78, 0xAC, 0xBB, 0xBB, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x97, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x77, 0x88, 0x88, 0x78, 0xBC, 0xBB, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x87, 0x88, 0x88, 0x7A, 0xCB, 0xBB, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x88, 0x87, 0x8B, 0xBB, 0xBB, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x78, 0x78, 0xAC, 0xBB, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x87, 0x88, 0x88, + 0x88, 0x88, 0x78, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0x77, 0x8A, 0xCB, 0xBC, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x88, 0x88, + 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x78, 0xAC, 0xCC, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x78, 0x88, + 0x88, 0x88, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x78, 0x9A, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD8, 0x78, 0x88, + 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0x78, 0x77, 0x9B, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0x78, 0x88, + 0x88, 0x87, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x87, 0x77, 0x77, 0x77, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x78, 0x88, + 0x88, 0x87, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC8, 0x77, 0x89, 0x99, 0x77, 0x78, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x78, 0x88, + 0x88, 0x87, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x87, 0x78, 0xCF, 0xFE, 0xB8, 0x77, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x78, 0x88, + 0x88, 0x87, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x77, 0x8D, 0xFF, 0xFF, 0xFB, 0x77, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD8, 0x78, 0x88, + 0x88, 0x87, 0x9E, 0xFF, 0xFF, 0xFE, 0xDD, 0xCC, 0xCC, 0xDD, 0xEF, 0xFF, 0xFB, 0x77, 0xAF, 0xFF, 0xFF, 0xFE, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB7, 0x88, 0x88, + 0x88, 0x87, 0x9C, 0xCD, 0xCC, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0xEF, 0xFB, 0x77, 0xCF, 0xFF, 0xFF, 0xFF, 0x97, 0x7D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x87, 0x88, 0x88, + 0x88, 0x87, 0x9C, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBD, 0xFC, 0x77, 0xBF, 0xFF, 0xFF, 0xFF, 0x97, 0x7B, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC8, 0x78, 0x88, 0x88, + 0x88, 0x87, 0x9C, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xCC, 0xCC, 0xBB, 0xCC, 0x87, 0x9E, 0xFF, 0xFF, 0xFC, 0x87, 0x88, 0x89, 0xAC, 0xDE, 0xEF, 0xFF, 0xFF, 0xFE, 0xCA, 0x77, 0x88, 0x88, 0x88, + 0x88, 0x87, 0x9C, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0xCB, 0xBB, 0xBB, 0xBB, 0xCA, 0x87, 0x7A, 0xEF, 0xFF, 0xD8, 0x77, 0x99, 0x77, 0x77, 0x88, 0x99, 0x9A, 0xA9, 0x98, 0x77, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x87, 0x9C, 0xBB, 0xBB, 0xBB, 0xBC, 0xCB, 0xA9, 0x88, 0x88, 0x89, 0xAA, 0x87, 0x77, 0x9B, 0xCA, 0x87, 0x78, 0xB9, 0x78, 0x88, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x87, 0x8B, 0xCB, 0xBB, 0xBC, 0xCB, 0x98, 0x77, 0x77, 0x77, 0x77, 0x78, 0x87, 0x77, 0x77, 0x77, 0x77, 0x8C, 0xCA, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x87, 0x8B, 0xCB, 0xBC, 0xCB, 0x98, 0x77, 0x88, 0x88, 0x88, 0x88, 0x87, 0x78, 0xC9, 0x77, 0x77, 0x79, 0xDF, 0xCB, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x7A, 0xCC, 0xCB, 0xA8, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8D, 0xFE, 0xCB, 0xAA, 0xCF, 0xFE, 0xBB, 0x97, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x78, 0xAB, 0xA8, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xBC, 0xA8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x88, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xBB, 0xC9, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xBB, 0xCB, 0x97, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBB, 0xBC, 0xB9, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCB, 0xBB, 0xCB, 0x98, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDB, 0xBB, 0xBC, 0xBA, 0x87, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0xBB, 0xBB, 0xBC, 0xB9, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xBB, 0xBB, 0xBB, 0xCC, 0xA8, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCB, 0xBB, 0xBB, 0xBB, 0xCB, 0x98, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0xBB, 0xBB, 0xBB, 0xBC, 0xCA, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x79, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xBB, 0xBB, 0xBB, 0xBB, 0xCB, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCB, 0xBB, 0xBB, 0xBB, 0xCA, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xBB, 0xBB, 0xBC, 0xB8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBB, 0xBB, 0xCB, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDB, 0xCC, 0xA8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xB9, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x87, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xA8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x9D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xC9, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x9B, 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xDB, 0xA8, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x89, 0x9A, 0xAB, 0xBB, 0xBA, 0x99, 0x87, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/feedrate_32x32x4.cpp b/Marlin/src/lcd/tft/images/feedrate_32x32x4.cpp new file mode 100644 index 000000000000..52f9124fdbd9 --- /dev/null +++ b/Marlin/src/lcd/tft/images/feedrate_32x32x4.cpp @@ -0,0 +1,62 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t feedrate_32x32x4[512] = { + 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x78, 0x77, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x77, 0x8A, 0xCD, 0xA8, 0xCC, 0xB9, 0x87, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x77, 0x9C, 0xEF, 0xFF, 0xA8, 0xFF, 0xFF, 0xDA, 0x87, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x8B, 0xEF, 0xFF, 0xFF, 0x97, 0xFF, 0xFF, 0xFF, 0xD9, 0x77, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x78, 0xCF, 0xFF, 0xFF, 0xEC, 0x76, 0xBD, 0xEF, 0xFF, 0xFF, 0x97, 0x78, 0x88, 0x88, + 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xC9, 0x65, 0x55, 0x65, 0x6A, 0xEF, 0xFB, 0x67, 0x87, 0x88, 0x88, + 0x88, 0x77, 0xCF, 0xFF, 0xE9, 0x55, 0x55, 0x55, 0x65, 0x55, 0x6B, 0xB5, 0x7D, 0xB7, 0x78, 0x88, + 0x87, 0x7A, 0xFF, 0xFE, 0x85, 0x55, 0x56, 0x67, 0x77, 0x66, 0x55, 0x57, 0xDF, 0xF8, 0x78, 0x88, + 0x87, 0x8E, 0xFF, 0xF8, 0x55, 0x56, 0x67, 0x88, 0x88, 0x87, 0x76, 0x58, 0xFF, 0xFC, 0x67, 0x88, + 0x77, 0xBF, 0xFF, 0xA5, 0x55, 0x67, 0x88, 0x88, 0x87, 0x78, 0xB9, 0x66, 0xBF, 0xFF, 0x86, 0x88, + 0x78, 0xDF, 0xFD, 0x65, 0x56, 0x78, 0x88, 0x87, 0x77, 0xAE, 0xD8, 0x77, 0x7E, 0xFF, 0xB5, 0x78, + 0x79, 0xFF, 0xFA, 0x55, 0x67, 0x88, 0x88, 0x77, 0x9C, 0xFF, 0x86, 0x56, 0x7B, 0xFF, 0xE6, 0x68, + 0x7A, 0xFF, 0xF7, 0x55, 0x78, 0x88, 0x87, 0x8B, 0xFF, 0xFB, 0x55, 0x67, 0x79, 0xFF, 0xF8, 0x68, + 0x7B, 0xFF, 0xE6, 0x56, 0x78, 0x88, 0x78, 0xDF, 0xFF, 0xE7, 0x55, 0x78, 0x79, 0xEE, 0xE8, 0x57, + 0x7C, 0xFF, 0xD6, 0x57, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xA5, 0x56, 0x78, 0x78, 0x77, 0x76, 0x57, + 0x7C, 0xFF, 0xD6, 0x57, 0x88, 0x87, 0x7C, 0xFF, 0xFD, 0x65, 0x57, 0x88, 0x78, 0x98, 0x86, 0x57, + 0x7B, 0xFF, 0xD6, 0x57, 0x88, 0x88, 0x79, 0xEF, 0xE8, 0x55, 0x67, 0x88, 0x79, 0xFF, 0xF9, 0x67, + 0x7B, 0xFF, 0xF7, 0x57, 0x88, 0x88, 0x87, 0x78, 0x75, 0x55, 0x78, 0x88, 0x7A, 0xFF, 0xF8, 0x67, + 0x79, 0xFF, 0xF9, 0x57, 0x88, 0x88, 0x88, 0x65, 0x55, 0x56, 0x88, 0x87, 0x7C, 0xFF, 0xD6, 0x56, + 0x78, 0xEF, 0xFD, 0x57, 0x88, 0x88, 0x88, 0x76, 0x55, 0x67, 0x88, 0x87, 0x8F, 0xFF, 0xB5, 0x57, + 0x77, 0xBF, 0xFF, 0x96, 0x88, 0x88, 0x88, 0x88, 0x77, 0x78, 0x88, 0x77, 0xCF, 0xFF, 0x85, 0x67, + 0x87, 0x8E, 0xFF, 0xE8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7A, 0xFF, 0xFC, 0x55, 0x67, + 0x88, 0x7A, 0xFF, 0xFD, 0x87, 0x78, 0x88, 0x88, 0x88, 0x88, 0x77, 0x9E, 0xFF, 0xF7, 0x55, 0x68, + 0x88, 0x77, 0xBF, 0xFF, 0xEA, 0x77, 0x77, 0x88, 0x87, 0x77, 0x7A, 0xFF, 0xFF, 0x95, 0x56, 0x78, + 0x88, 0x87, 0x6C, 0xFF, 0xFF, 0xC9, 0x87, 0x77, 0x77, 0x89, 0xDF, 0xFF, 0xFB, 0x55, 0x56, 0x88, + 0x88, 0x88, 0x76, 0xCF, 0xFF, 0xFF, 0xDC, 0xBB, 0xBC, 0xEF, 0xFF, 0xFF, 0xA5, 0x55, 0x67, 0x88, + 0x88, 0x88, 0x86, 0x6A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0x55, 0x55, 0x78, 0x88, + 0x88, 0x88, 0x87, 0x65, 0x7B, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDA, 0x65, 0x55, 0x57, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x86, 0x55, 0x79, 0xBD, 0xDE, 0xDC, 0xB9, 0x65, 0x55, 0x56, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x76, 0x55, 0x56, 0x66, 0x66, 0x55, 0x55, 0x55, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x76, 0x55, 0x55, 0x55, 0x55, 0x56, 0x67, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x66, 0x66, 0x66, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/flowrate_32x32x4.cpp b/Marlin/src/lcd/tft/images/flowrate_32x32x4.cpp new file mode 100644 index 000000000000..2259472f792a --- /dev/null +++ b/Marlin/src/lcd/tft/images/flowrate_32x32x4.cpp @@ -0,0 +1,62 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t flowrate_32x32x4[512] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x88, 0x88, 0x88, 0x87, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x88, 0x88, 0x88, 0x87, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x77, 0x78, 0xCE, 0xEB, 0x77, 0x77, 0x87, 0x7C, 0xEA, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x87, 0x89, 0x77, 0xEF, 0xFD, 0x67, 0xA8, 0x77, 0x7E, 0xFB, 0x77, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x78, 0xDF, 0xBA, 0xFF, 0xFE, 0x8B, 0xFD, 0x87, 0x7D, 0xFA, 0x56, 0x87, 0x77, 0x88, 0x88, + 0x87, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x7D, 0xFA, 0x56, 0x77, 0x87, 0x77, 0x88, + 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC6, 0x7D, 0xFA, 0x56, 0x9C, 0xDC, 0x97, 0x78, + 0x87, 0x78, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x65, 0x6D, 0xFA, 0x59, 0xFF, 0xFF, 0xFB, 0x77, + 0x88, 0x89, 0xEF, 0xFF, 0xA7, 0x7B, 0xFF, 0xFD, 0x76, 0x5D, 0xF9, 0x7F, 0xFF, 0xFF, 0xFF, 0x97, + 0x7A, 0xDF, 0xFF, 0xFA, 0x55, 0x55, 0xCF, 0xFF, 0xEC, 0x9C, 0xF9, 0x9F, 0xFF, 0xFF, 0xFF, 0xC6, + 0x7C, 0xFF, 0xFF, 0xF7, 0x55, 0x55, 0x8F, 0xFF, 0xFF, 0xAC, 0xF9, 0xBF, 0xFD, 0x6C, 0xFF, 0xE5, + 0x7C, 0xFF, 0xFF, 0xF7, 0x56, 0x77, 0xAF, 0xFF, 0xFF, 0x9B, 0xF9, 0xBF, 0xFE, 0x8D, 0xFF, 0xE5, + 0x7A, 0xDE, 0xFF, 0xFB, 0x56, 0x77, 0xDF, 0xFF, 0xED, 0x8C, 0xF9, 0x8F, 0xFF, 0xFF, 0xFF, 0xB5, + 0x87, 0x67, 0xEF, 0xFF, 0xA8, 0x9C, 0xFF, 0xFD, 0x76, 0x5D, 0xF9, 0x6D, 0xFF, 0xFF, 0xFE, 0x75, + 0x88, 0x66, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x65, 0x5C, 0xFA, 0x57, 0xDF, 0xFF, 0xD8, 0x55, + 0x87, 0x7D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC6, 0x6D, 0xFA, 0x55, 0x68, 0xA9, 0x65, 0x55, + 0x87, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC6, 0x7D, 0xFA, 0x56, 0x65, 0x55, 0x55, 0x56, + 0x88, 0x78, 0xDF, 0xA8, 0xFF, 0xFE, 0x8A, 0xFC, 0x65, 0x6D, 0xFA, 0x56, 0x77, 0x65, 0x56, 0x67, + 0x88, 0x87, 0x78, 0x55, 0xEF, 0xFD, 0x55, 0x86, 0x55, 0x5D, 0xFA, 0x56, 0x88, 0x77, 0x77, 0x88, + 0x88, 0x88, 0x65, 0x55, 0xBE, 0xEA, 0x55, 0x55, 0x55, 0x6B, 0xD8, 0x56, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x77, 0x66, 0x76, 0x65, 0x56, 0x76, 0x68, 0xA9, 0x88, 0x88, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x77, 0x76, 0x55, 0x56, 0x87, 0x7B, 0xFF, 0xFF, 0xFB, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x66, 0x67, 0x88, 0x78, 0xEF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x78, 0x88, 0x87, 0xAF, 0xFF, 0x95, 0x56, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7D, 0xFD, 0x65, 0x56, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x79, 0xF8, 0x55, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x96, 0x55, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x65, 0x56, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x67, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/heated_bed_64x64x4.cpp b/Marlin/src/lcd/tft/images/heated_bed_64x64x4.cpp new file mode 100644 index 000000000000..5382ff7558ed --- /dev/null +++ b/Marlin/src/lcd/tft/images/heated_bed_64x64x4.cpp @@ -0,0 +1,161 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t bed_64x64x4[2048] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xAE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEA, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x67, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x56, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x89, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x56, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x75, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x56, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x57, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +extern const uint8_t bed_heated_64x64x4[2048] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x78, 0x88, 0x88, 0x88, 0x77, 0x77, 0x88, 0x88, 0x88, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x9B, 0x97, 0x88, 0x88, 0x87, 0x8B, 0xA8, 0x78, 0x88, 0x87, 0x8B, 0xB8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x79, 0xFF, 0xF9, 0x78, 0x88, 0x78, 0xDF, 0xFB, 0x78, 0x88, 0x77, 0xCF, 0xFC, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFD, 0x77, 0x88, 0x79, 0xFF, 0xFF, 0x87, 0x88, 0x78, 0xDF, 0xFF, 0x97, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x79, 0xFF, 0xFF, 0x86, 0x88, 0x78, 0xDF, 0xFF, 0xB6, 0x88, 0x77, 0xCF, 0xFF, 0xC6, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xB6, 0x78, 0x87, 0x9F, 0xFF, 0xD6, 0x78, 0x87, 0x8E, 0xFF, 0xF7, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7D, 0xFF, 0xE6, 0x68, 0x87, 0x7D, 0xFF, 0xE7, 0x68, 0x88, 0x7A, 0xFF, 0xF9, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7D, 0xFF, 0xE5, 0x67, 0x87, 0x7B, 0xFF, 0xF7, 0x57, 0x88, 0x79, 0xFF, 0xFA, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xE6, 0x57, 0x87, 0x8C, 0xFF, 0xF7, 0x57, 0x88, 0x7A, 0xFF, 0xFA, 0x56, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xD5, 0x57, 0x87, 0x8E, 0xFF, 0xE6, 0x57, 0x88, 0x7C, 0xFF, 0xF8, 0x56, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xCF, 0xFF, 0xA5, 0x57, 0x87, 0xAF, 0xFF, 0xD5, 0x57, 0x87, 0x9F, 0xFF, 0xE6, 0x56, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x79, 0xFF, 0xFF, 0x75, 0x57, 0x78, 0xEF, 0xFF, 0xA5, 0x57, 0x87, 0xCF, 0xFF, 0xB5, 0x56, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFB, 0x55, 0x67, 0x7B, 0xFF, 0xFE, 0x65, 0x57, 0x79, 0xFF, 0xFF, 0x85, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xF7, 0x55, 0x67, 0x8E, 0xFF, 0xF8, 0x55, 0x67, 0x7D, 0xFF, 0xFB, 0x55, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xCF, 0xFF, 0xB5, 0x55, 0x77, 0x9F, 0xFF, 0xD6, 0x55, 0x77, 0x8F, 0xFF, 0xE7, 0x55, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xDF, 0xFF, 0x75, 0x56, 0x87, 0xBF, 0xFF, 0xA5, 0x56, 0x77, 0xAF, 0xFF, 0xB5, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xEF, 0xFD, 0x65, 0x67, 0x77, 0xCF, 0xFF, 0x85, 0x57, 0x87, 0xBF, 0xFF, 0x95, 0x56, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xEF, 0xFD, 0x55, 0x68, 0x77, 0xCF, 0xFF, 0x75, 0x68, 0x87, 0xBF, 0xFF, 0x95, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xDF, 0xFF, 0x65, 0x78, 0x77, 0xBF, 0xFF, 0x95, 0x68, 0x87, 0xAF, 0xFF, 0xB5, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xCF, 0xFF, 0xB5, 0x78, 0x87, 0xAF, 0xFF, 0xD6, 0x68, 0x87, 0x9F, 0xFF, 0xE7, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xF8, 0x68, 0x87, 0x8E, 0xFF, 0xF9, 0x68, 0x87, 0x7C, 0xFF, 0xFC, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7B, 0xFF, 0xFA, 0x58, 0x88, 0x7B, 0xFF, 0xFC, 0x57, 0x88, 0x78, 0xFF, 0xFE, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xDF, 0xD7, 0x57, 0x88, 0x87, 0xBF, 0xF8, 0x56, 0x88, 0x87, 0xAF, 0xFA, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x69, 0x75, 0x56, 0x88, 0x87, 0x68, 0x85, 0x56, 0x78, 0x87, 0x68, 0x85, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x65, 0x55, 0x57, 0x88, 0x88, 0x75, 0x55, 0x56, 0x88, 0x88, 0x75, 0x55, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x55, 0x67, 0x77, 0x77, 0x76, 0x55, 0x67, 0x77, 0x77, 0x76, 0x55, 0x57, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x88, 0x88, 0x88, 0x88, 0x87, 0x88, 0x88, 0x88, 0x88, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xAE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEA, 0x78, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x67, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x46, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x56, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x89, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x56, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x75, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x56, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x57, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/home_64x64x4.cpp b/Marlin/src/lcd/tft/images/home_64x64x4.cpp new file mode 100644 index 000000000000..27384c99c0f7 --- /dev/null +++ b/Marlin/src/lcd/tft/images/home_64x64x4.cpp @@ -0,0 +1,94 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t home_64x64x4[2048] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x67, 0x88, 0x76, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x9D, 0xFF, 0xEA, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x69, 0xFF, 0xFF, 0xFF, 0xC6, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x9F, 0xFF, 0xFF, 0xFF, 0xFC, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC6, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x69, 0xFF, 0xFF, 0xFF, 0xEB, 0xFF, 0xFF, 0xFF, 0xC6, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x9F, 0xFF, 0xFF, 0xFF, 0x40, 0xBF, 0xFF, 0xFF, 0xFC, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x69, 0xFF, 0xFF, 0xFF, 0xF6, 0x54, 0xA, 0xFF, 0xFF, 0xFF, 0xC6, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x9F, 0xFF, 0xFF, 0xFF, 0x57, 0xFF, 0x80, 0xAF, 0xFF, 0xFF, 0xFC, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x69, 0xFF, 0xFF, 0xFF, 0xF5, 0x6F, 0xFF, 0xF9, 0xA, 0xFF, 0xFF, 0xFF, 0xC6, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x9F, 0xFF, 0xFF, 0xFF, 0x56, 0xFF, 0xFF, 0xFF, 0x90, 0xAF, 0xFF, 0xFF, 0xFC, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x69, 0xFF, 0xFF, 0xFF, 0xF5, 0x6F, 0xFF, 0xFF, 0xFF, 0xF9, 0xA, 0xFF, 0xFF, 0xFF, 0xC6, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x9F, 0xFF, 0xFF, 0xFF, 0x56, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0xAF, 0xFF, 0xFF, 0xFC, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x69, 0xFF, 0xFF, 0xFF, 0xF5, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xA, 0xFF, 0xFF, 0xFF, 0xC6, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x9F, 0xFF, 0xFF, 0xFF, 0x56, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0xAF, 0xFF, 0xFF, 0xFC, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x69, 0xFF, 0xFF, 0xFF, 0xF5, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xA, 0xFF, 0xFF, 0xFF, 0xC6, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x9F, 0xFF, 0xFF, 0xFF, 0x56, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0xAF, 0xFF, 0xFF, 0xFC, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x69, 0xFF, 0xFF, 0xFF, 0xF5, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xA, 0xFF, 0xFF, 0xFF, 0xC6, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x86, 0x9F, 0xFF, 0xFF, 0xFF, 0x56, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0xBF, 0xFF, 0xFF, 0xFC, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x69, 0xFF, 0xFF, 0xFF, 0xF5, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xA, 0xFF, 0xFF, 0xFF, 0xC6, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x86, 0x9F, 0xFF, 0xFF, 0xFF, 0x56, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0xAF, 0xFF, 0xFF, 0xFC, 0x67, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x69, 0xFF, 0xFF, 0xFF, 0xF5, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xA, 0xFF, 0xFF, 0xFF, 0xC6, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x86, 0x9F, 0xFF, 0xFF, 0xFF, 0x56, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0xAF, 0xFF, 0xFF, 0xFC, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x69, 0xFF, 0xFF, 0xFF, 0xF5, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xA, 0xFF, 0xFF, 0xFF, 0xC6, 0x78, 0x88, 0x88, + 0x88, 0x86, 0x9F, 0xFF, 0xFF, 0xFF, 0x56, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0xAF, 0xFF, 0xFF, 0xFC, 0x67, 0x88, 0x88, + 0x88, 0x69, 0xFF, 0xFF, 0xFF, 0xF5, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xB, 0xFF, 0xFF, 0xFF, 0xC6, 0x78, 0x88, + 0x87, 0x7F, 0xFF, 0xFF, 0xFF, 0x66, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0xBF, 0xFF, 0xFF, 0xFB, 0x68, 0x88, + 0x87, 0x7F, 0xFF, 0xFF, 0xF7, 0x3C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xB, 0xFF, 0xFF, 0xFD, 0x67, 0x88, + 0x87, 0x3D, 0xFF, 0xFF, 0x75, 0x59, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x30, 0xBF, 0xFF, 0xFA, 0x68, 0x88, + 0x88, 0x44, 0xCE, 0xD7, 0x58, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x74, 0x19, 0xEE, 0xA6, 0x88, 0x88, + 0x88, 0x73, 0x24, 0x56, 0x88, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x78, 0x52, 0x35, 0x68, 0x88, 0x88, + 0x88, 0x87, 0x66, 0x78, 0x88, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x78, 0x87, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x55, 0x55, 0x55, 0x5D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x92, 0x44, 0x44, 0x44, 0x12, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x77, 0x88, 0x88, 0x88, 0x72, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x97, 0x88, 0x88, 0x88, 0x84, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x96, 0x88, 0x88, 0x88, 0x84, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x96, 0x88, 0x88, 0x88, 0x84, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x96, 0x88, 0x88, 0x88, 0x84, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x96, 0x88, 0x88, 0x88, 0x84, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x96, 0x88, 0x88, 0x88, 0x84, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x96, 0x88, 0x88, 0x88, 0x84, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x96, 0x88, 0x88, 0x88, 0x84, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x96, 0x88, 0x88, 0x88, 0x84, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x96, 0x88, 0x88, 0x88, 0x84, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x96, 0x88, 0x88, 0x88, 0x84, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x96, 0x88, 0x88, 0x88, 0x84, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x64, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x96, 0x88, 0x88, 0x88, 0x84, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x83, 0x4C, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xFF, 0x97, 0x88, 0x88, 0x88, 0x84, 0xAE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEA, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x32, 0x44, 0x44, 0x44, 0x44, 0x33, 0x57, 0x88, 0x88, 0x88, 0x88, 0x86, 0x43, 0x34, 0x44, 0x44, 0x44, 0x34, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x55, 0x55, 0x55, 0x55, 0x55, 0x67, 0x88, 0x88, 0x88, 0x88, 0x87, 0x65, 0x55, 0x55, 0x55, 0x55, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/hotend_64x64x4.cpp b/Marlin/src/lcd/tft/images/hotend_64x64x4.cpp new file mode 100644 index 000000000000..7b068aa7e404 --- /dev/null +++ b/Marlin/src/lcd/tft/images/hotend_64x64x4.cpp @@ -0,0 +1,94 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t hotend_64x64x4[2048] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7A, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xA7, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB7, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x77, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x95, 0x67, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x8A, 0xAA, 0xAA, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB8, 0x9A, 0xAA, 0x97, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB5, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0x68, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0x68, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0x68, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0x68, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0x68, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0x68, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x9E, 0xEE, 0xEE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xEE, 0xA5, 0x68, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x66, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x77, 0x65, 0x68, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x55, 0x55, 0x57, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0x55, 0x55, 0x55, 0x68, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x66, 0x66, 0x65, 0x6C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x75, 0x55, 0x55, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x77, 0x65, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC6, 0x55, 0x56, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x58, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x55, 0x55, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x65, 0x7D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x85, 0x55, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x56, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x55, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x75, 0x59, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x55, 0x55, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x65, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x95, 0x55, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x56, 0xCF, 0xFF, 0xFF, 0xFF, 0xD7, 0x55, 0x55, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x75, 0x5A, 0xFF, 0xFF, 0xFB, 0x65, 0x55, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x65, 0x8D, 0xFE, 0xA5, 0x55, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x56, 0x87, 0x55, 0x55, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x75, 0x55, 0x55, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x65, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/increase_64x64x4.cpp b/Marlin/src/lcd/tft/images/increase_64x64x4.cpp new file mode 100644 index 000000000000..710fe8e78e13 --- /dev/null +++ b/Marlin/src/lcd/tft/images/increase_64x64x4.cpp @@ -0,0 +1,94 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t increase_64x64x4[2048] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xB5, 0x67, 0x77, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7B, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCD, 0xFF, 0xFF, 0xFF, 0xFF, 0xDB, 0xBC, 0xCC, 0xCC, 0xCC, 0xCC, 0xC8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x89, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9B, 0xFF, 0xFF, 0xFF, 0xFF, 0xD9, 0x99, 0x99, 0x99, 0x99, 0x99, 0x96, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x66, 0x66, 0x66, 0x66, 0x66, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x66, 0x66, 0x66, 0x66, 0x66, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x77, 0x77, 0x77, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x67, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xEE, 0xEE, 0xEE, 0xEE, 0xA6, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x66, 0x66, 0x66, 0x66, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x66, 0x66, 0x66, 0x66, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x66, 0x66, 0x66, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/left_32x32x4.cpp b/Marlin/src/lcd/tft/images/left_32x32x4.cpp new file mode 100644 index 000000000000..486518d5085d --- /dev/null +++ b/Marlin/src/lcd/tft/images/left_32x32x4.cpp @@ -0,0 +1,62 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t left_32x32x4[512] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xAF, 0x87, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7A, 0xFF, 0xF7, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xAF, 0xFF, 0xFF, 0x87, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7A, 0xFF, 0xFF, 0xFB, 0x46, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xAF, 0xFF, 0xFF, 0xA3, 0x34, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7A, 0xFF, 0xFF, 0xFB, 0x34, 0x47, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xAF, 0xFF, 0xFF, 0xB3, 0x44, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x79, 0xFF, 0xFF, 0xFB, 0x34, 0x48, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x77, 0x9F, 0xFF, 0xFF, 0xA3, 0x44, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x79, 0xFF, 0xFF, 0xFA, 0x34, 0x48, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x77, 0xAF, 0xFF, 0xFF, 0xA3, 0x34, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x7A, 0xFF, 0xFF, 0xFA, 0x33, 0x47, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xF6, 0x34, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x76, 0xBF, 0xFF, 0xFF, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x3B, 0xFF, 0xFF, 0xF8, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x73, 0xCF, 0xFF, 0xFF, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x3C, 0xFF, 0xFF, 0xF8, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x83, 0xCF, 0xFF, 0xFF, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x3B, 0xFF, 0xFF, 0xF7, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x74, 0xBF, 0xFF, 0xFF, 0x87, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x4B, 0xFF, 0xFF, 0xF8, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x74, 0xBF, 0xFF, 0xFF, 0x87, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x4B, 0xFF, 0xF9, 0x46, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x74, 0xCF, 0x93, 0x34, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x4B, 0x34, 0x47, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x73, 0x34, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x47, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/leveling_32x32x4.cpp b/Marlin/src/lcd/tft/images/leveling_32x32x4.cpp new file mode 100644 index 000000000000..3243d7f27f35 --- /dev/null +++ b/Marlin/src/lcd/tft/images/leveling_32x32x4.cpp @@ -0,0 +1,62 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t leveling_32x32x4[512] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x89, 0x99, 0x99, 0x99, 0x99, 0x87, 0x78, 0x88, 0x77, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0x88, 0x87, 0x7B, 0x77, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC4, 0x88, 0x87, 0x8F, 0x97, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x77, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD4, 0x88, 0x77, 0xEF, 0xF5, 0x88, 0x88, 0x88, + 0x88, 0x87, 0x77, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC5, 0x88, 0x7A, 0xFF, 0xFC, 0x78, 0x88, 0x88, + 0x88, 0x87, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x97, 0x7A, 0x88, 0x88, 0x58, 0x88, 0x88, + 0x88, 0x87, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x87, 0x45, 0x55, 0x57, 0x88, 0x88, + 0x88, 0x87, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x76, 0x88, 0x77, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x87, 0x85, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC5, 0x56, 0x7C, 0xFF, 0xFE, 0x67, 0x88, 0x88, + 0x88, 0x88, 0x86, 0x55, 0xEF, 0xFF, 0xFF, 0xF9, 0x45, 0x57, 0x86, 0xFF, 0xF5, 0x57, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x4C, 0xFF, 0xFF, 0x74, 0x57, 0x88, 0x87, 0x8F, 0xA4, 0x68, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x84, 0x9F, 0xD5, 0x45, 0x78, 0x88, 0x88, 0x7C, 0x55, 0x88, 0x88, 0x88, + 0x87, 0x77, 0x77, 0x77, 0x88, 0x65, 0x55, 0x68, 0x87, 0x77, 0x77, 0x86, 0x57, 0x87, 0x77, 0x78, + 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x56, 0x77, 0x77, 0x77, 0x77, 0x77, 0x67, 0x77, 0x77, 0x77, + 0x7B, 0xFE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEF, 0xB7, + 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, + 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB5, + 0x78, 0x67, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x66, + 0x87, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/menu_64x64x4.cpp b/Marlin/src/lcd/tft/images/menu_64x64x4.cpp new file mode 100644 index 000000000000..bbbe66ab1ba1 --- /dev/null +++ b/Marlin/src/lcd/tft/images/menu_64x64x4.cpp @@ -0,0 +1,94 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t menu_64x64x4[2048] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x79, 0xAA, 0x98, 0x88, 0x88, 0x88, 0x9A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x98, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x9E, 0xFF, 0xFA, 0x78, 0x88, 0x8A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFB, 0x66, 0x88, 0x8B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFB, 0x66, 0x88, 0x8B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFA, 0x66, 0x88, 0x8A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x8A, 0xBB, 0xA7, 0x67, 0x88, 0x88, 0xAB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xA6, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x66, 0x66, 0x67, 0x88, 0x88, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x66, 0x66, 0x67, 0x88, 0x88, 0x76, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x78, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x79, 0xAA, 0x98, 0x88, 0x88, 0x88, 0x9A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x98, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x9E, 0xFF, 0xFA, 0x78, 0x88, 0x8A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFB, 0x66, 0x88, 0x8B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFB, 0x66, 0x88, 0x8B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFA, 0x66, 0x88, 0x8A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x8A, 0xBB, 0xA7, 0x67, 0x88, 0x88, 0xAB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xA6, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x66, 0x66, 0x67, 0x88, 0x88, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x66, 0x66, 0x67, 0x88, 0x88, 0x76, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x78, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x79, 0xAA, 0x98, 0x88, 0x88, 0x88, 0x9A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x98, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x9E, 0xFF, 0xFA, 0x78, 0x88, 0x8A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFB, 0x66, 0x88, 0x8B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFB, 0x66, 0x88, 0x8B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFA, 0x66, 0x88, 0x8A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x8A, 0xBB, 0xA7, 0x67, 0x88, 0x88, 0xAB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xA6, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x66, 0x66, 0x67, 0x88, 0x88, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x66, 0x66, 0x67, 0x88, 0x88, 0x76, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x78, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x79, 0xAA, 0x98, 0x88, 0x88, 0x88, 0x9A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x98, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x9E, 0xFF, 0xFA, 0x78, 0x88, 0x8A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFB, 0x66, 0x88, 0x8B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFB, 0x66, 0x88, 0x8B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFA, 0x66, 0x88, 0x8A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x8A, 0xBB, 0xA7, 0x67, 0x88, 0x88, 0xAB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xA6, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x66, 0x66, 0x67, 0x88, 0x88, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x66, 0x66, 0x67, 0x88, 0x88, 0x76, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x78, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x79, 0xAA, 0x98, 0x88, 0x88, 0x88, 0x9A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x98, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x9E, 0xFF, 0xFA, 0x78, 0x88, 0x8A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFB, 0x66, 0x88, 0x8B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xFB, 0x66, 0x88, 0x8B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFA, 0x66, 0x88, 0x8A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x8A, 0xBB, 0xA7, 0x67, 0x88, 0x88, 0xAB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xA6, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x66, 0x66, 0x67, 0x88, 0x88, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x66, 0x66, 0x67, 0x88, 0x88, 0x76, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x78, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/pause_64x64x4.cpp b/Marlin/src/lcd/tft/images/pause_64x64x4.cpp new file mode 100644 index 000000000000..3079b22a17c9 --- /dev/null +++ b/Marlin/src/lcd/tft/images/pause_64x64x4.cpp @@ -0,0 +1,94 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t pause_64x64x4[2048] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xD8, 0x78, 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0x78, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x67, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xD7, 0x67, 0x88, 0x88, 0x87, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x77, 0x77, 0x76, 0x67, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x77, 0x77, 0x76, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x88, 0x88, 0x88, 0x87, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x66, 0x66, 0x66, 0x66, 0x66, 0x77, 0x88, 0x88, 0x88, 0x87, 0x76, 0x66, 0x66, 0x66, 0x66, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/refresh_32x32x4.cpp b/Marlin/src/lcd/tft/images/refresh_32x32x4.cpp new file mode 100644 index 000000000000..f8548d2837a4 --- /dev/null +++ b/Marlin/src/lcd/tft/images/refresh_32x32x4.cpp @@ -0,0 +1,62 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t refresh_32x32x4[512] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x79, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x79, 0xFF, 0x57, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xAF, 0xFF, 0x9A, 0x87, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x79, 0xFF, 0xFF, 0xFF, 0xFE, 0x97, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xAF, 0xFF, 0xCE, 0xFF, 0xFD, 0x77, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x77, 0x88, 0x6A, 0xFF, 0x55, 0x5C, 0xFF, 0xD7, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0xA7, 0x78, 0x86, 0x9F, 0x57, 0x75, 0x8F, 0xFB, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x78, 0xFC, 0x78, 0x88, 0x69, 0x67, 0x88, 0x69, 0xFF, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x7C, 0xFF, 0x58, 0x88, 0x87, 0x58, 0x88, 0x86, 0xFF, 0xA7, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x7E, 0xFA, 0x58, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xE5, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x7F, 0xF8, 0x68, 0x88, 0x88, 0x88, 0x88, 0x87, 0xAF, 0xF5, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x7F, 0xF8, 0x68, 0x88, 0x88, 0x88, 0x88, 0x87, 0xAF, 0xF5, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x7E, 0xFA, 0x68, 0x88, 0x88, 0x88, 0x88, 0x87, 0xCF, 0xE5, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x7C, 0xFF, 0x68, 0x88, 0x87, 0x78, 0x88, 0x77, 0xFF, 0xA5, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x78, 0xFF, 0xA7, 0x88, 0x78, 0xB7, 0x88, 0x77, 0xBF, 0x66, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0xBF, 0xF9, 0x77, 0x77, 0xFB, 0x78, 0x88, 0x68, 0x57, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x6D, 0xFF, 0xD8, 0x77, 0xFF, 0xB7, 0x78, 0x87, 0x68, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x85, 0xCF, 0xFF, 0xFD, 0xFF, 0xFB, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x57, 0xEF, 0xFF, 0xFF, 0xFF, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x55, 0x89, 0xFF, 0xF8, 0x47, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x65, 0xFF, 0x75, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0xF7, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0x75, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/right_32x32x4.cpp b/Marlin/src/lcd/tft/images/right_32x32x4.cpp new file mode 100644 index 000000000000..ab9c36eae069 --- /dev/null +++ b/Marlin/src/lcd/tft/images/right_32x32x4.cpp @@ -0,0 +1,62 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t right_32x32x4[512] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x77, 0x8F, 0xA7, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x78, 0xFF, 0xF9, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x8F, 0xFF, 0xFF, 0x97, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x7B, 0xFF, 0xFF, 0xF9, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x84, 0xAF, 0xFF, 0xFF, 0x97, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x3A, 0xFF, 0xFF, 0xF9, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x83, 0xAF, 0xFF, 0xFF, 0x97, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x3A, 0xFF, 0xFF, 0xF9, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x83, 0xAF, 0xFF, 0xFF, 0x97, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x4A, 0xFF, 0xFF, 0xF9, 0x77, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x74, 0x9F, 0xFF, 0xFF, 0x97, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x49, 0xFF, 0xFF, 0xFA, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0xFF, 0xFF, 0xFC, 0x67, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x9F, 0xFF, 0xFF, 0xC4, 0x36, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x79, 0xFF, 0xFF, 0xFC, 0x33, 0x46, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x9F, 0xFF, 0xFF, 0xC3, 0x34, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x79, 0xFF, 0xFF, 0xFD, 0x33, 0x47, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8F, 0xFF, 0xFF, 0xD3, 0x44, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xFF, 0xFF, 0xFC, 0x34, 0x47, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x77, 0x8F, 0xFF, 0xFF, 0xC3, 0x44, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x78, 0xFF, 0xFF, 0xFC, 0x33, 0x47, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xC4, 0x34, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x8A, 0xFF, 0xFC, 0x43, 0x47, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x84, 0x8F, 0xC4, 0x34, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x4A, 0x53, 0x47, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x84, 0x34, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x56, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/sd_64x64x4.cpp b/Marlin/src/lcd/tft/images/sd_64x64x4.cpp new file mode 100644 index 000000000000..3f786f46caa8 --- /dev/null +++ b/Marlin/src/lcd/tft/images/sd_64x64x4.cpp @@ -0,0 +1,94 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t sd_64x64x4[2048] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x66, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0xFF, 0xFE, 0xDF, 0xFF, 0xFD, 0xEF, 0xFF, 0xDE, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x85, 0xBF, 0xFA, 0x4B, 0xFF, 0xA4, 0xAF, 0xFB, 0x59, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x84, 0xBF, 0xF9, 0x3A, 0xFF, 0xA3, 0x9F, 0xFB, 0x48, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x84, 0xBF, 0xF9, 0x4B, 0xFF, 0xA4, 0xAF, 0xFB, 0x49, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x84, 0xCF, 0xF9, 0x4B, 0xFF, 0xA4, 0xAF, 0xFB, 0x49, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x84, 0xCF, 0xF9, 0x4B, 0xFF, 0xA4, 0xAF, 0xFB, 0x49, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x84, 0xCF, 0xF9, 0x4B, 0xFF, 0xA4, 0xAF, 0xFB, 0x49, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x84, 0xBF, 0xF9, 0x3A, 0xFF, 0xA3, 0xAF, 0xFB, 0x39, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x96, 0xCF, 0xFA, 0x5B, 0xFF, 0xB5, 0xBF, 0xFC, 0x5A, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xEF, 0xFF, 0xFE, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x45, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/settings_64x64x4.cpp b/Marlin/src/lcd/tft/images/settings_64x64x4.cpp new file mode 100644 index 000000000000..093e7ff61ef8 --- /dev/null +++ b/Marlin/src/lcd/tft/images/settings_64x64x4.cpp @@ -0,0 +1,94 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t settings_64x64x4[2048] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0xAD, 0xDD, 0xDD, 0xD9, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x78, 0x88, 0x77, 0xEF, 0xFF, 0xFF, 0xFB, 0x78, 0x88, 0x87, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x87, 0x78, 0x79, 0xFF, 0xFF, 0xFF, 0xFD, 0x67, 0x87, 0x78, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8D, 0xEB, 0x87, 0x7B, 0xFF, 0xFF, 0xFF, 0xFF, 0x75, 0x78, 0xCE, 0xB7, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xDF, 0xFF, 0xEA, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD8, 0xBF, 0xFF, 0xFB, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB7, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0x98, 0x8A, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7E, 0xFF, 0xFF, 0xFF, 0xFB, 0x65, 0x55, 0x55, 0x57, 0xDF, 0xFF, 0xFF, 0xFF, 0xB5, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x6C, 0xFF, 0xFF, 0xFF, 0x95, 0x56, 0x66, 0x66, 0x65, 0x5B, 0xFF, 0xFF, 0xFF, 0x95, 0x57, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x78, 0xAF, 0xFF, 0xFF, 0xFA, 0x56, 0x66, 0x67, 0x77, 0x77, 0x65, 0xDF, 0xFF, 0xFF, 0xD7, 0x67, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x89, 0xCE, 0xFF, 0xFF, 0xFF, 0xD5, 0x56, 0x67, 0x88, 0x88, 0x88, 0x86, 0x7F, 0xFF, 0xFF, 0xFF, 0xDB, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0x95, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x6C, 0xFF, 0xFF, 0xFF, 0xFF, 0xD7, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFE, 0x75, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFD, 0x65, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x79, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFD, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x79, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFE, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x79, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0x75, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x7B, 0xFF, 0xFF, 0xFF, 0xFF, 0xE5, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8C, 0xEF, 0xFF, 0xFF, 0xFF, 0xA5, 0x78, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0xA5, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x66, 0x79, 0xCF, 0xFF, 0xE7, 0x68, 0x88, 0x88, 0x88, 0x88, 0x77, 0xAF, 0xFF, 0xFF, 0xFC, 0x96, 0x56, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x55, 0x55, 0x58, 0xDF, 0xFD, 0x77, 0x78, 0x88, 0x88, 0x87, 0x79, 0xFF, 0xFF, 0xFF, 0xA5, 0x56, 0x66, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x9C, 0xDD, 0xDB, 0x96, 0x55, 0x5B, 0xFF, 0xD8, 0x77, 0x77, 0x77, 0x77, 0xAF, 0xFF, 0xFF, 0xFF, 0x95, 0x66, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xAD, 0xFF, 0xFF, 0xFF, 0xFE, 0xB7, 0x55, 0xBF, 0xFE, 0xB9, 0x77, 0x78, 0x9C, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0x67, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x86, 0x6D, 0xFF, 0xFF, 0xED, 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD8, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7A, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x77, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x66, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x78, 0xB7, 0x56, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0x86, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x77, 0xAF, 0xFF, 0xC6, 0x5D, 0xFF, 0xFF, 0xFF, 0xFF, 0xC6, 0x8C, 0xEF, 0xFF, 0xFF, 0xFF, 0xFD, 0xEF, 0xFF, 0xFE, 0x75, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x7A, 0xFF, 0xFF, 0xFC, 0x59, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x66, 0x68, 0xBD, 0xFF, 0xFF, 0xA5, 0x7B, 0xFF, 0xE7, 0x56, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x7B, 0xFF, 0xFF, 0xFD, 0x66, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x66, 0x55, 0x56, 0x8A, 0xEE, 0x65, 0x55, 0x7A, 0x75, 0x66, 0x68, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x79, 0xFF, 0xFF, 0xFF, 0x75, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDB, 0x97, 0x55, 0x55, 0x66, 0x66, 0x66, 0x55, 0x56, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x78, 0xFF, 0xFF, 0xFE, 0x65, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xCA, 0x76, 0x55, 0x56, 0x78, 0x76, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x79, 0x97, 0x9D, 0xFF, 0xD5, 0x6B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x97, 0x66, 0x77, 0x88, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x7B, 0xFD, 0xA7, 0x9A, 0x68, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDA, 0x97, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x79, 0xFF, 0xFF, 0xC9, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xB8, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x77, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDB, 0x98, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEA, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x76, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x89, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x59, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x55, 0x57, 0x9B, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x96, 0x87, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x75, 0x6A, 0xDF, 0xFF, 0xFE, 0xB8, 0x55, 0x66, 0x65, 0x55, 0x69, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x85, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x55, 0x67, 0x77, 0x76, 0x55, 0x66, 0x67, 0x76, 0x66, 0x55, 0x56, 0x7B, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x65, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x55, 0x55, 0x55, 0x66, 0x66, 0x78, 0x88, 0x87, 0x76, 0x65, 0x55, 0x68, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x55, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x88, 0x76, 0x66, 0x66, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x77, 0x66, 0x55, 0x55, 0x8A, 0xDF, 0xFF, 0xFF, 0xFF, 0xF8, 0x56, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x76, 0x65, 0x55, 0x67, 0x9C, 0xEF, 0xFF, 0xB5, 0x66, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x76, 0x55, 0x55, 0x79, 0xB9, 0x56, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x76, 0x66, 0x55, 0x55, 0x66, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x76, 0x56, 0x66, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/slider_8x16x4.cpp b/Marlin/src/lcd/tft/images/slider_8x16x4.cpp new file mode 100644 index 000000000000..2839cd980634 --- /dev/null +++ b/Marlin/src/lcd/tft/images/slider_8x16x4.cpp @@ -0,0 +1,46 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t slider_8x16x4[64] = { + 0x88, 0xFF, 0xFF, 0x88, + 0x8F, 0xFF, 0xFF, 0xF8, + 0x8F, 0xFF, 0xFF, 0xF8, + 0x8F, 0xFF, 0xFF, 0xF8, + 0x8F, 0xFF, 0xFF, 0xF8, + 0x8F, 0xFF, 0xFF, 0xF8, + 0x8F, 0xFF, 0xFF, 0xF8, + 0x8F, 0xFF, 0xFF, 0xF8, + 0x8F, 0xFF, 0xFF, 0xF8, + 0x8F, 0xFF, 0xFF, 0xF8, + 0x8F, 0xFF, 0xFF, 0xF8, + 0x8F, 0xFF, 0xFF, 0xF8, + 0x8F, 0xFF, 0xFF, 0xF8, + 0x8F, 0xFF, 0xFF, 0xF8, + 0x8F, 0xFF, 0xFF, 0xF8, + 0x88, 0xFF, 0xFF, 0x88, +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/images/up_32x32x4.cpp b/Marlin/src/lcd/tft/images/up_32x32x4.cpp new file mode 100644 index 000000000000..b36a028cc909 --- /dev/null +++ b/Marlin/src/lcd/tft/images/up_32x32x4.cpp @@ -0,0 +1,62 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_GRAPHICAL_TFT + +extern const uint8_t up_32x32x4[512] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x78, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0xAD, 0x67, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x7A, 0xFF, 0xB3, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x9F, 0xFF, 0xFB, 0x38, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x87, 0x79, 0xFF, 0xFF, 0xFF, 0xC3, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x77, 0x9F, 0xFF, 0xFF, 0xFF, 0xFC, 0x38, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x87, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x77, 0xAF, 0xFF, 0xFF, 0xA6, 0xFF, 0xFF, 0xFB, 0x47, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x7A, 0xFF, 0xFF, 0xFA, 0x33, 0x6F, 0xFF, 0xFF, 0xB4, 0x78, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x77, 0xAF, 0xFF, 0xFF, 0xA3, 0x34, 0x78, 0xFF, 0xFF, 0xFB, 0x47, 0x88, 0x88, 0x88, + 0x88, 0x87, 0x7A, 0xFF, 0xFF, 0xFA, 0x33, 0x47, 0x87, 0x8F, 0xFF, 0xFF, 0xB4, 0x78, 0x88, 0x88, + 0x88, 0x77, 0xAF, 0xFF, 0xFF, 0xB3, 0x44, 0x78, 0x87, 0x78, 0xFF, 0xFF, 0xFB, 0x47, 0x88, 0x88, + 0x88, 0x7A, 0xFF, 0xFF, 0xFB, 0x34, 0x47, 0x88, 0x88, 0x87, 0x7F, 0xFF, 0xFF, 0xC4, 0x78, 0x88, + 0x88, 0x7F, 0xFF, 0xFF, 0xB3, 0x44, 0x88, 0x88, 0x88, 0x88, 0x77, 0xFF, 0xFF, 0xFB, 0x37, 0x88, + 0x88, 0x78, 0xFF, 0xFA, 0x34, 0x48, 0x88, 0x88, 0x88, 0x88, 0x87, 0x8F, 0xFF, 0x93, 0x34, 0x88, + 0x88, 0x77, 0x7F, 0xB3, 0x44, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x78, 0xF9, 0x34, 0x47, 0x88, + 0x88, 0x87, 0x78, 0x43, 0x47, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x77, 0x84, 0x34, 0x88, 0x88, + 0x88, 0x88, 0x87, 0x64, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x76, 0x47, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 +}; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/tft.cpp b/Marlin/src/lcd/tft/tft.cpp new file mode 100644 index 000000000000..fa3c2c241f79 --- /dev/null +++ b/Marlin/src/lcd/tft/tft.cpp @@ -0,0 +1,42 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfig.h" + +#if HAS_GRAPHICAL_TFT + +#include "tft.h" + +//#define DEBUG_GRAPHICAL_TFT +#define DEBUG_OUT ENABLED(DEBUG_GRAPHICAL_TFT) +#include "../../core/debug_out.h" + +uint16_t TFT::buffer[]; + +void TFT::init() { + io.Init(); + io.InitTFT(); +} + +TFT tft; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/tft.h b/Marlin/src/lcd/tft/tft.h new file mode 100644 index 000000000000..ed3d5e35c157 --- /dev/null +++ b/Marlin/src/lcd/tft/tft.h @@ -0,0 +1,91 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "tft_queue.h" +#include "canvas.h" +#include "tft_color.h" +#include "tft_string.h" +#include "tft_image.h" +#include "../tft_io/tft_io.h" + +#include "../../inc/MarlinConfig.h" + +#if HAS_UI_320x240 + #define TFT_WIDTH 320 + #define TFT_HEIGHT 240 +#elif HAS_UI_480x320 + #define TFT_WIDTH 480 + #define TFT_HEIGHT 320 +#else + #error "Unsupported display resolution!" +#endif + +#ifndef TFT_BUFFER_SIZE + #ifdef STM32F103xB + #define TFT_BUFFER_SIZE 1024 + #elif defined(STM32F103xE) + #define TFT_BUFFER_SIZE 19200 // 320 * 60 + #elif defined(STM32F1) + #define TFT_BUFFER_SIZE 8192 + #else + #define TFT_BUFFER_SIZE 19200 // 320 * 60 + #endif +#endif + +#if TFT_BUFFER_SIZE > 65535 + // DMA Count parameter is uint16_t + #error "TFT_BUFFER_SIZE can not exceed 65535" +#endif + +class TFT { + private: + static TFT_String string; + static TFT_IO io; + + public: + static TFT_Queue queue; + + static uint16_t buffer[TFT_BUFFER_SIZE]; + + static void init(); + static inline void set_font(const uint8_t *Font) { string.set_font(Font); } + static inline void add_glyphs(const uint8_t *Font) { string.add_glyphs(Font); } + + static inline bool is_busy() { return io.isBusy(); } + static inline void abort() { io.Abort(); } + static inline void write_multiple(uint16_t Data, uint16_t Count) { io.WriteMultiple(Data, Count); } + static inline void write_sequence(uint16_t *Data, uint16_t Count) { io.WriteSequence(Data, Count); } + static inline void set_window(uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) { io.set_window(Xmin, Ymin, Xmax, Ymax); } + + static inline void fill(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color) { queue.fill(x, y, width, height, color); } + static inline void canvas(uint16_t x, uint16_t y, uint16_t width, uint16_t height) { queue.canvas(x, y, width, height); } + static inline void set_background(uint16_t color) { queue.set_background(color); } + static inline void add_text(uint16_t x, uint16_t y, uint16_t color, TFT_String tft_string, uint16_t maxWidth = 0) { queue.add_text(x, y, color, tft_string.string(), maxWidth); } + static inline void add_text(uint16_t x, uint16_t y, uint16_t color, const char *string, uint16_t maxWidth = 0) { queue.add_text(x, y, color, (uint8_t *)string, maxWidth); } + static inline void add_image(int16_t x, int16_t y, MarlinImage image, uint16_t *colors) { queue.add_image(x, y, image, colors); } + static inline void add_image(int16_t x, int16_t y, MarlinImage image, uint16_t color_main = COLOR_WHITE, uint16_t color_background = COLOR_BACKGROUND, uint16_t color_shadow = COLOR_BLACK) { queue.add_image(x, y, image, color_main, color_background, color_shadow); } + static inline void add_bar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color) { queue.add_bar(x, y, width, height, color); } + static inline void add_rectangle(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color) { queue.add_rectangle(x, y, width, height, color); } +}; + +extern TFT tft; diff --git a/Marlin/src/lcd/tft/tft_color.h b/Marlin/src/lcd/tft/tft_color.h new file mode 100644 index 000000000000..a72a079f6ee4 --- /dev/null +++ b/Marlin/src/lcd/tft/tft_color.h @@ -0,0 +1,176 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../../inc/MarlinConfigPre.h" + +#define RED(color) ((color >> 8) & 0xF8) +#define GREEN(color) ((color >> 3) & 0xFC) +#define BLUE(color) ((color << 3) & 0xF8) +#define RGB(red, green, blue) (((red << 8) & 0xF800) | ((green << 3) & 0x07E0) | ((blue >> 3) & 0x001F)) +#define COLOR(color) RGB(((color >> 16) & 0xFF), ((color >> 8) & 0xFF), (color & 0xFF)) +#define HALF(color) RGB(RED(color) >> 1, GREEN(color) >> 1, BLUE(color) >> 1) + +// see https://ee-programming-notepad.blogspot.com/2016/10/16-bit-color-generator-picker.html + +#define COLOR_BLACK 0x0000 // #000000 +#define COLOR_WHITE 0xFFFF // #FFFFFF +#define COLOR_SILVER 0xC618 // #C0C0C0 +#define COLOR_GREY 0x7BEF // #808080 +#define COLOR_DARKGREY 0x4208 // #404040 +#define COLOR_DARKGREY2 0x39E7 // #303030 +#define COLOR_DARK 0x0003 // Some dark color + +#define COLOR_RED 0xF800 // #FF0000 +#define COLOR_SCARLET 0xF904 // #FF2020 +#define COLOR_LIME 0x7E00 // #00FF00 +#define COLOR_BLUE 0x001F // #0000FF +#define COLOR_LIGHT_BLUE 0x061F // #00C3FF +#define COLOR_YELLOW 0xFFE0 // #FFFF00 +#define COLOR_MAGENTA 0xF81F // #FF00FF +#define COLOR_FUCHSIA 0xF81F // #FF00FF +#define COLOR_CYAN 0x07FF // #00FFFF +#define COLOR_AQUA 0x07FF // #00FFFF +#define COLOR_DODGER_BLUE 0x041F // #0080FF +#define COLOR_VIVID_VIOLET 0x7933 // #772399 + +#define COLOR_DARK_PURPLE 0x9930 // #992380 + +#define COLOR_MAROON 0x7800 // #800000 +#define COLOR_GREEN 0x03E0 // #008000 +#define COLOR_NAVY 0x000F // #000080 +#define COLOR_OLIVE 0x8400 // #808000 +#define COLOR_PURPLE 0x8010 // #800080 +#define COLOR_TEAL 0x0410 // #008080 + +#define COLOR_ORANGE 0xFC00 // #FF7F00 +#define COLOR_VIVID_GREEN 0x7FE0 // #7FFF00 +#define COLOR_DARK_ORANGE 0xFC40 // #FF8C00 +#define COLOR_CORAL_RED 0xF9E7 // #FF3F3F + +#define COLOR_DARK_PURPLE 0x9930 // #992380 + +#ifndef COLOR_BACKGROUND + #define COLOR_BACKGROUND 0x20AC // #1E156E +#endif +#ifndef COLOR_SELECTION_BG + #define COLOR_SELECTION_BG 0x9930 // #992380 +#endif +#ifndef COLOR_WEBSITE_URL + #define COLOR_WEBSITE_URL 0x03B7 +#endif + +#ifndef COLOR_INACTIVE + #define COLOR_INACTIVE COLOR_GREY +#endif +#ifndef COLOR_COLD + #define COLOR_COLD COLOR_AQUA +#endif +#ifndef COLOR_HOTEND + #define COLOR_HOTEND COLOR_SCARLET +#endif +#ifndef COLOR_HEATED_BED + #define COLOR_HEATED_BED COLOR_DARK_ORANGE +#endif +#ifndef COLOR_CHAMBER + #define COLOR_CHAMBER COLOR_DARK_ORANGE +#endif +#ifndef COLOR_FAN + #define COLOR_FAN COLOR_AQUA +#endif + +#ifndef COLOR_AXIS_HOMED + #define COLOR_AXIS_HOMED COLOR_WHITE +#endif +#ifndef COLOR_AXIS_NOT_HOMED + #define COLOR_AXIS_NOT_HOMED COLOR_YELLOW +#endif + +#ifndef COLOR_RATE_100 + #define COLOR_RATE_100 COLOR_VIVID_GREEN +#endif +#ifndef COLOR_RATE_ALTERED + #define COLOR_RATE_ALTERED COLOR_YELLOW +#endif + +#ifndef COLOR_PRINT_TIME + #define COLOR_PRINT_TIME COLOR_AQUA +#endif + +#ifndef COLOR_PROGRESS_FRAME + #define COLOR_PROGRESS_FRAME COLOR_WHITE +#endif +#ifndef COLOR_PROGRESS_BAR + #define COLOR_PROGRESS_BAR COLOR_BLUE +#endif +#ifndef COLOR_PROGRESS_BG + #define COLOR_PROGRESS_BG COLOR_BLACK +#endif + +#ifndef COLOR_STATUS_MESSAGE + #define COLOR_STATUS_MESSAGE COLOR_YELLOW +#endif + +#ifndef COLOR_CONTROL_ENABLED + #define COLOR_CONTROL_ENABLED COLOR_WHITE +#endif +#ifndef COLOR_CONTROL_DISABLED + #define COLOR_CONTROL_DISABLED COLOR_GREY +#endif +#ifndef COLOR_CONTROL_CANCEL + #define COLOR_CONTROL_CANCEL COLOR_SCARLET +#endif +#ifndef COLOR_CONTROL_CONFIRM + #define COLOR_CONTROL_CONFIRM COLOR_VIVID_GREEN +#endif +#ifndef COLOR_BUSY + #define COLOR_BUSY COLOR_SILVER +#endif + +#ifndef COLOR_MENU_TEXT + #define COLOR_MENU_TEXT COLOR_YELLOW +#endif +#ifndef COLOR_MENU_VALUE + #define COLOR_MENU_VALUE COLOR_WHITE +#endif + +#ifndef COLOR_SLIDER + #define COLOR_SLIDER COLOR_WHITE +#endif +#ifndef COLOR_SLIDER_INACTIVE + #define COLOR_SLIDER_INACTIVE COLOR_GREY +#endif + +#ifndef COLOR_UBL + #define COLOR_UBL COLOR_WHITE +#endif + +#ifndef COLOR_TOUCH_CALIBRATION + #define COLOR_TOUCH_CALIBRATION COLOR_WHITE +#endif + +#ifndef COLOR_KILL_SCREEN_BG + #define COLOR_KILL_SCREEN_BG COLOR_MAROON +#endif +#ifndef COLOR_KILL_SCREEN_TEXT + #define COLOR_KILL_SCREEN_TEXT COLOR_WHITE +#endif diff --git a/Marlin/src/lcd/tft/tft_image.cpp b/Marlin/src/lcd/tft/tft_image.cpp new file mode 100644 index 000000000000..27749cb7f3ae --- /dev/null +++ b/Marlin/src/lcd/tft/tft_image.cpp @@ -0,0 +1,71 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "tft_image.h" +#include + +const tImage NoLogo = { (void *)NULL, 0, 0, NOCOLORS }; + +const tImage MarlinLogo112x38x1 = { (void *)marlin_logo_112x38x1, 112, 38, GREYSCALE1 }; +const tImage MarlinLogo228x255x2 = { (void *)marlin_logo_228x255x2, 228, 255, GREYSCALE2 }; +const tImage MarlinLogo228x255x4 = { (void *)marlin_logo_228x255x4, 228, 255, GREYSCALE4 }; +const tImage MarlinLogo195x59x16 = { (void *)marlin_logo_195x59x16, 195, 59, HIGHCOLOR }; +const tImage MarlinLogo320x240x16 = { (void *)marlin_logo_320x240x16, 320, 240, HIGHCOLOR }; +const tImage MarlinLogo480x320x16 = { (void *)marlin_logo_480x320x16, 480, 320, HIGHCOLOR }; +const tImage Background320x30x16 = { (void *)background_320x30x16, 320, 30, HIGHCOLOR }; + +const tImage HotEnd_64x64x4 = { (void *)hotend_64x64x4, 64, 64, GREYSCALE4 }; +const tImage Bed_64x64x4 = { (void *)bed_64x64x4, 64, 64, GREYSCALE4 }; +const tImage Bed_Heated_64x64x4 = { (void *)bed_heated_64x64x4, 64, 64, GREYSCALE4 }; +const tImage Chamber_64x64x4 = { (void *)chamber_64x64x4, 64, 64, GREYSCALE4 }; +const tImage Chamber_Heated_64x64x4 = { (void *)chamber_heated_64x64x4, 64, 64, GREYSCALE4 }; +const tImage Fan0_64x64x4 = { (void *)fan0_64x64x4, 64, 64, GREYSCALE4 }; +const tImage Fan1_64x64x4 = { (void *)fan1_64x64x4, 64, 64, GREYSCALE4 }; +const tImage Fan_Slow0_64x64x4 = { (void *)fan_slow0_64x64x4, 64, 64, GREYSCALE4 }; +const tImage Fan_Slow1_64x64x4 = { (void *)fan_slow1_64x64x4, 64, 64, GREYSCALE4 }; +const tImage Fan_Fast0_64x64x4 = { (void *)fan_fast0_64x64x4, 64, 64, GREYSCALE4 }; +const tImage Fan_Fast1_64x64x4 = { (void *)fan_fast1_64x64x4, 64, 64, GREYSCALE4 }; +const tImage SD_64x64x4 = { (void *)sd_64x64x4, 64, 64, GREYSCALE4 }; +const tImage Home_64x64x4 = { (void *)home_64x64x4, 64, 64, GREYSCALE4 }; +const tImage BtnRounded_64x52x4 = { (void *)btn_rounded_64x52x4, 64, 52, GREYSCALE4 }; +const tImage Menu_64x64x4 = { (void *)menu_64x64x4, 64, 64, GREYSCALE4 }; +const tImage Settings_64x64x4 = { (void *)settings_64x64x4, 64, 64, GREYSCALE4 }; +const tImage Confirm_64x64x4 = { (void *)confirm_64x64x4, 64, 64, GREYSCALE4 }; +const tImage Cancel_64x64x4 = { (void *)cancel_64x64x4, 64, 64, GREYSCALE4 }; +const tImage Increase_64x64x4 = { (void *)increase_64x64x4, 64, 64, GREYSCALE4 }; +const tImage Decrease_64x64x4 = { (void *)decrease_64x64x4, 64, 64, GREYSCALE4 }; +const tImage Pause_64x64x4 = { (void *)pause_64x64x4, 64, 64, GREYSCALE4 }; + +const tImage Feedrate_32x32x4 = { (void *)feedrate_32x32x4, 32, 32, GREYSCALE4 }; +const tImage Flowrate_32x32x4 = { (void *)flowrate_32x32x4, 32, 32, GREYSCALE4 }; +const tImage Directory_32x32x4 = { (void *)directory_32x32x4, 32, 32, GREYSCALE4 }; +const tImage Back_32x32x4 = { (void *)back_32x32x4, 32, 32, GREYSCALE4 }; +const tImage Up_32x32x4 = { (void *)up_32x32x4, 32, 32, GREYSCALE4 }; +const tImage Down_32x32x4 = { (void *)down_32x32x4, 32, 32, GREYSCALE4 }; +const tImage Left_32x32x4 = { (void *)left_32x32x4, 32, 32, GREYSCALE4 }; +const tImage Right_32x32x4 = { (void *)right_32x32x4, 32, 32, GREYSCALE4 }; +const tImage Refresh_32x32x4 = { (void *)refresh_32x32x4, 32, 32, GREYSCALE4 }; +const tImage Leveling_32x32x4 = { (void *)leveling_32x32x4, 32, 32, GREYSCALE4 }; + +const tImage Slider8x16x4 = { (void *)slider_8x16x4, 8, 16, GREYSCALE4 }; + +extern const tImage Images[imgCount]; diff --git a/Marlin/src/lcd/tft/tft_image.h b/Marlin/src/lcd/tft/tft_image.h new file mode 100644 index 000000000000..1f13967ba248 --- /dev/null +++ b/Marlin/src/lcd/tft/tft_image.h @@ -0,0 +1,166 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "stdint.h" + + +extern const uint8_t marlin_logo_112x38x1[]; +extern const uint8_t marlin_logo_228x255x2[]; +extern const uint8_t marlin_logo_228x255x4[]; +extern const uint16_t marlin_logo_195x59x16[]; +extern const uint16_t marlin_logo_320x240x16[]; +extern const uint16_t marlin_logo_480x320x16[]; +extern const uint16_t background_320x30x16[]; + +extern const uint8_t hotend_64x64x4[]; +extern const uint8_t bed_64x64x4[], bed_heated_64x64x4[]; +extern const uint8_t chamber_64x64x4[], chamber_heated_64x64x4[]; +extern const uint8_t fan0_64x64x4[], fan1_64x64x4[]; +extern const uint8_t fan_slow0_64x64x4[], fan_slow1_64x64x4[]; +extern const uint8_t fan_fast0_64x64x4[], fan_fast1_64x64x4[]; +extern const uint8_t sd_64x64x4[]; +extern const uint8_t home_64x64x4[]; +extern const uint8_t btn_rounded_64x52x4[]; +extern const uint8_t menu_64x64x4[]; +extern const uint8_t settings_64x64x4[]; +extern const uint8_t confirm_64x64x4[]; +extern const uint8_t cancel_64x64x4[]; +extern const uint8_t increase_64x64x4[]; +extern const uint8_t decrease_64x64x4[]; +extern const uint8_t pause_64x64x4[]; + +extern const uint8_t feedrate_32x32x4[]; +extern const uint8_t flowrate_32x32x4[]; +extern const uint8_t directory_32x32x4[]; +extern const uint8_t back_32x32x4[]; +extern const uint8_t up_32x32x4[]; +extern const uint8_t down_32x32x4[]; +extern const uint8_t left_32x32x4[]; +extern const uint8_t right_32x32x4[]; +extern const uint8_t refresh_32x32x4[]; +extern const uint8_t leveling_32x32x4[]; + +extern const uint8_t slider_8x16x4[]; + +enum MarlinImage : uint8_t { + imgBootScreen = 0x00, + imgHotEnd, + imgBed, + imgBedHeated, + imgChamber, + imgChamberHeated, + imgFanIdle, + imgFanSlow0, + imgFanSlow1, + imgFanFast0, + imgFanFast1, + imgFeedRate, + imgFlowRate, + imgSD, + imgMenu, + imgSettings, + imgDirectory, + imgConfirm, + imgCancel, + imgIncrease, + imgDecrease, + imgBack, + imgUp, + imgDown, + imgLeft, + imgRight, + imgRefresh, + imgLeveling, + imgSlider, + imgHome, + imgBtn52Rounded, + imgCount, + noImage = imgCount, + imgPageUp = imgLeft, + imgPageDown = imgRight +}; + +enum colorMode_t : uint8_t { + NOCOLORS = 0x00, + MONOCHROME = 0x01, // 1 bit per pixel + GREYSCALE1 = 0x01, // 1 bit per pixel + GREYSCALE2, // 2 bits per pixel + GREYSCALE4, // 4 bits per pixel + HIGHCOLOR // 16 bits per pixel +}; + +typedef colorMode_t ColorMode; + +typedef struct __attribute__((__packed__)) { + void *data; + uint16_t width; + uint16_t height; + colorMode_t colorMode; +} tImage; + +extern const tImage NoLogo; + +extern const tImage MarlinLogo112x38x1; +extern const tImage MarlinLogo228x255x2; +extern const tImage MarlinLogo228x255x4; +extern const tImage MarlinLogo195x59x16; +extern const tImage MarlinLogo320x240x16; +extern const tImage MarlinLogo480x320x16; +extern const tImage Background320x30x16; + +extern const tImage HotEnd_64x64x4; +extern const tImage Bed_64x64x4; +extern const tImage Bed_Heated_64x64x4; +extern const tImage Chamber_64x64x4; +extern const tImage Chamber_Heated_64x64x4; +extern const tImage Fan0_64x64x4; +extern const tImage Fan1_64x64x4; +extern const tImage Fan_Slow0_64x64x4; +extern const tImage Fan_Slow1_64x64x4; +extern const tImage Fan_Fast0_64x64x4; +extern const tImage Fan_Fast1_64x64x4; +extern const tImage SD_64x64x4; +extern const tImage Home_64x64x4; +extern const tImage BtnRounded_64x52x4; +extern const tImage Menu_64x64x4; +extern const tImage Settings_64x64x4; +extern const tImage Confirm_64x64x4; +extern const tImage Cancel_64x64x4; +extern const tImage Increase_64x64x4; +extern const tImage Decrease_64x64x4; +extern const tImage Pause_64x64x4; + +extern const tImage Feedrate_32x32x4; +extern const tImage Flowrate_32x32x4; +extern const tImage Directory_32x32x4; +extern const tImage Back_32x32x4; +extern const tImage Up_32x32x4; +extern const tImage Down_32x32x4; +extern const tImage Left_32x32x4; +extern const tImage Right_32x32x4; +extern const tImage Refresh_32x32x4; +extern const tImage Leveling_32x32x4; + +extern const tImage Slider8x16x4; + +extern const tImage Images[imgCount]; diff --git a/Marlin/src/lcd/tft/tft_queue.cpp b/Marlin/src/lcd/tft/tft_queue.cpp new file mode 100644 index 000000000000..e77afaf716bf --- /dev/null +++ b/Marlin/src/lcd/tft/tft_queue.cpp @@ -0,0 +1,346 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfig.h" + +#if HAS_GRAPHICAL_TFT + +#include "tft_queue.h" +#include "tft.h" +#include "tft_image.h" + +uint8_t TFT_Queue::queue[]; +uint8_t *TFT_Queue::end_of_queue = queue; +uint8_t *TFT_Queue::current_task = NULL; +uint8_t *TFT_Queue::last_task = NULL; + +void TFT_Queue::reset() { + tft.abort(); + + end_of_queue = queue; + current_task = NULL; + last_task = NULL; +} + +void TFT_Queue::async() { + if (current_task == NULL) return; + queueTask_t *task = (queueTask_t *)current_task; + + // Check IO busy status + if (tft.is_busy()) return; + + if (task->state == TASK_STATE_COMPLETED) { + task = (queueTask_t *)task->nextTask; + current_task = (uint8_t *)task; + } + + finish_sketch(); + + switch (task->type) { + case TASK_END_OF_QUEUE: reset(); break; + case TASK_FILL: fill(task); break; + case TASK_CANVAS: canvas(task); break; + } +} + +void TFT_Queue::finish_sketch() { + if (last_task == NULL) return; + queueTask_t *task = (queueTask_t *)last_task; + + if (task->state == TASK_STATE_SKETCH) { + *end_of_queue = TASK_END_OF_QUEUE; + task->nextTask = end_of_queue; + task->state = TASK_STATE_READY; + + if (current_task == NULL) current_task = (uint8_t *)task; + } +} + +void TFT_Queue::fill(queueTask_t *task) { + uint16_t count; + parametersFill_t *task_parameters = (parametersFill_t *)(((uint8_t *)task) + sizeof(queueTask_t)); + + if (task->state == TASK_STATE_READY) { + tft.set_window(task_parameters->x, task_parameters->y, task_parameters->x + task_parameters->width - 1, task_parameters->y + task_parameters->height - 1); + task->state = TASK_STATE_IN_PROGRESS; + } + + if (task_parameters->count > 65535) { + count = 65535; + task_parameters->count -= 65535; + } + else { + count = task_parameters->count; + task_parameters->count = 0; + task->state = TASK_STATE_COMPLETED; + } + + tft.write_multiple(task_parameters->color, count); +} + +void TFT_Queue::canvas(queueTask_t *task) { + parametersCanvas_t *task_parameters = (parametersCanvas_t *)(((uint8_t *)task) + sizeof(queueTask_t)); + + uint16_t i; + uint8_t *item = ((uint8_t *)task_parameters) + sizeof(parametersCanvas_t); + + if (task->state == TASK_STATE_READY) { + task->state = TASK_STATE_IN_PROGRESS; + Canvas.New(task_parameters->x, task_parameters->y, task_parameters->width, task_parameters->height); + } + Canvas.Continue(); + + for (i = 0; i < task_parameters->count; i++) { + switch (*item) { + case CANVAS_SET_BACKGROUND: + Canvas.SetBackground(((parametersCanvasBackground_t *)item)->color); + item += sizeof(parametersCanvasBackground_t); + break; + case CANVAS_ADD_TEXT: + Canvas.AddText(((parametersCanvasText_t *)item)->x, ((parametersCanvasText_t *)item)->y, ((parametersCanvasText_t *)item)->color, item + sizeof(parametersCanvasText_t), ((parametersCanvasText_t *)item)->maxWidth); + item += sizeof(parametersCanvasText_t) + ((parametersCanvasText_t *)item)->stringLength; + break; + + case CANVAS_ADD_IMAGE: + MarlinImage image; + uint16_t *colors; + colorMode_t color_mode; + + image = ((parametersCanvasImage_t *)item)->image; + colors = (uint16_t *)(item + sizeof(parametersCanvasImage_t)); + Canvas.AddImage(((parametersCanvasImage_t *)item)->x, ((parametersCanvasImage_t *)item)->y, image, colors); + + item = (uint8_t *)colors; + color_mode = Images[image].colorMode; + + switch (color_mode) { + case GREYSCALE1: + item += sizeof(uint16_t); + break; + case GREYSCALE2: + item += sizeof(uint16_t) * 3; + break; + case GREYSCALE4: + item += sizeof(uint16_t) * 15; + break; + default: + break; + } + break; + + case CANVAS_ADD_BAR: + Canvas.AddBar(((parametersCanvasBar_t *)item)->x, ((parametersCanvasBar_t *)item)->y, ((parametersCanvasBar_t *)item)->width, ((parametersCanvasBar_t *)item)->height, ((parametersCanvasBar_t *)item)->color); + item += sizeof(parametersCanvasBar_t); + break; + case CANVAS_ADD_RECTANGLE: + Canvas.AddRectangle(((parametersCanvasRectangle_t *)item)->x, ((parametersCanvasRectangle_t *)item)->y, ((parametersCanvasRectangle_t *)item)->width, ((parametersCanvasRectangle_t *)item)->height, ((parametersCanvasRectangle_t *)item)->color); + item += sizeof(parametersCanvasRectangle_t); + break; + } + } + + if (Canvas.ToScreen()) task->state = TASK_STATE_COMPLETED; +} + + +void TFT_Queue::fill(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color) { + finish_sketch(); + + queueTask_t *task = (queueTask_t *)end_of_queue; + last_task = (uint8_t *)task; + + end_of_queue += sizeof(queueTask_t); + parametersFill_t *task_parameters = (parametersFill_t *)end_of_queue; + end_of_queue += sizeof(parametersFill_t); + + task_parameters->x = x; + task_parameters->y = y; + task_parameters->width = width; + task_parameters->height = height; + task_parameters->color = color; + task_parameters->count = width * height; + + *end_of_queue = TASK_END_OF_QUEUE; + task->nextTask = end_of_queue; + task->state = TASK_STATE_READY; + task->type = TASK_FILL; + + if (current_task == NULL) current_task = (uint8_t *)task; +} + +void TFT_Queue::canvas(uint16_t x, uint16_t y, uint16_t width, uint16_t height) { + finish_sketch(); + + queueTask_t *task = (queueTask_t *)end_of_queue; + last_task = (uint8_t *) task; + + task->state = TASK_STATE_SKETCH; + task->type = TASK_CANVAS; + task->nextTask = NULL; + + end_of_queue += sizeof(queueTask_t); + parametersCanvas_t *task_parameters = (parametersCanvas_t *)end_of_queue; + end_of_queue += sizeof(parametersCanvas_t); + + task_parameters->x = x; + task_parameters->y = y; + task_parameters->width = width; + task_parameters->height = height; + task_parameters->count = 0; + + if (current_task == NULL) current_task = (uint8_t *)task; +} + +void TFT_Queue::set_background(uint16_t color) { + parametersCanvas_t *task_parameters = (parametersCanvas_t *)(((uint8_t *)last_task) + sizeof(queueTask_t)); + parametersCanvasBackground_t *parameters = (parametersCanvasBackground_t *)end_of_queue; + + parameters->type = CANVAS_SET_BACKGROUND; + parameters->color = color; + + end_of_queue += sizeof(parametersCanvasBackground_t); + task_parameters->count++; +} + +void TFT_Queue::add_text(uint16_t x, uint16_t y, uint16_t color, uint8_t *string, uint16_t maxWidth) { + parametersCanvas_t *task_parameters = (parametersCanvas_t *)(((uint8_t *)last_task) + sizeof(queueTask_t)); + parametersCanvasText_t *parameters = (parametersCanvasText_t *)end_of_queue; + + uint8_t *pointer = string; + + parameters->type = CANVAS_ADD_TEXT; + parameters->x = x; + parameters->y = y; + parameters->color = color; + parameters->stringLength = 0; + parameters->maxWidth = maxWidth; + + end_of_queue += sizeof(parametersCanvasText_t); + + /* TODO: Deal with maxWidth */ + while ((*(end_of_queue++) = *pointer++) != 0x00); + + parameters->stringLength = pointer - string; + task_parameters->count++; +} + +void TFT_Queue::add_image(int16_t x, int16_t y, MarlinImage image, uint16_t *colors) { + parametersCanvas_t *task_parameters = (parametersCanvas_t *)(((uint8_t *)last_task) + sizeof(queueTask_t)); + parametersCanvasImage_t *parameters = (parametersCanvasImage_t *)end_of_queue; + + parameters->type = CANVAS_ADD_IMAGE; + parameters->x = x; + parameters->y = y; + parameters->image = image; + + end_of_queue += sizeof(parametersCanvasImage_t); + task_parameters->count++; + + colorMode_t color_mode = Images[image].colorMode; + + if (color_mode == HIGHCOLOR) return; + + uint16_t *color = (uint16_t *)end_of_queue; + uint8_t number_of_color = 0; + + switch (color_mode) { + case GREYSCALE1: number_of_color = 1; break; + case GREYSCALE2: number_of_color = 3; break; + case GREYSCALE4: number_of_color = 15; break; + default: + break; + } + + while (number_of_color--) { + *color++ = *colors++; + } + + end_of_queue = (uint8_t *)color; +} + +uint16_t gradient(uint16_t colorA, uint16_t colorB, uint16_t factor) { + uint16_t red, green, blue; + + red = ( RED(colorA) * factor + RED(colorB) * (256 - factor)) >> 8; + green = (GREEN(colorA) * factor + GREEN(colorB) * (256 - factor)) >> 8; + blue = ( BLUE(colorA) * factor + BLUE(colorB) * (256 - factor)) >> 8; + + return RGB(red, green, blue); +} + +void TFT_Queue::add_image(int16_t x, int16_t y, MarlinImage image, uint16_t color_main, uint16_t color_background, uint16_t color_shadow) { + uint16_t colors[16]; + colorMode_t color_mode = Images[image].colorMode; + uint16_t i; + + switch (color_mode) { + case GREYSCALE1: + colors[1] = color_main; + break; + case GREYSCALE2: + for (i = 1; i < 4; i++) + colors[i] = gradient(color_main, color_background, (i << 8) / 3); + break; + case GREYSCALE4: + for (i = 1; i < 8; i++) + colors[i] = gradient(color_background, color_shadow, i << 5); + for (i = 8; i < 16; i++) + colors[i] = gradient(color_main, color_background, ((i - 8) << 8) / 7); + break; + default: + break; + } + + add_image(x, y, image, colors + 1); +} + +void TFT_Queue::add_bar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color) { + parametersCanvas_t *task_parameters = (parametersCanvas_t *)(((uint8_t *)last_task) + sizeof(queueTask_t)); + parametersCanvasBar_t *parameters = (parametersCanvasBar_t *)end_of_queue; + + parameters->type = CANVAS_ADD_BAR; + parameters->x = x; + parameters->y = y; + parameters->width = width; + parameters->height = height; + parameters->color = color; + + end_of_queue += sizeof(parametersCanvasBar_t); + task_parameters->count++; +} + +void TFT_Queue::add_rectangle(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color) { + parametersCanvas_t *task_parameters = (parametersCanvas_t *)(((uint8_t *)last_task) + sizeof(queueTask_t)); + parametersCanvasRectangle_t *parameters = (parametersCanvasRectangle_t *)end_of_queue; + + parameters->type = CANVAS_ADD_RECTANGLE; + parameters->x = x; + parameters->y = y; + parameters->width = width; + parameters->height = height; + parameters->color = color; + + end_of_queue += sizeof(parametersCanvasRectangle_t); + task_parameters->count++; +} + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/tft_queue.h b/Marlin/src/lcd/tft/tft_queue.h new file mode 100644 index 000000000000..9aa0d5b6c91d --- /dev/null +++ b/Marlin/src/lcd/tft/tft_queue.h @@ -0,0 +1,140 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../../inc/MarlinConfig.h" +#include "tft_string.h" +#include "tft_image.h" + +#define QUEUE_SIZE 8192 + +enum QueueTaskType : uint8_t { + TASK_END_OF_QUEUE = 0x00, + TASK_FILL, + TASK_CANVAS, +}; + +enum QueueTaskState : uint8_t { + TASK_STATE_READY = 0x00, + TASK_STATE_IN_PROGRESS, + TASK_STATE_COMPLETED, + TASK_STATE_SKETCH = 0xFF, +}; + +enum CanvasSubtype : uint8_t { + CANVAS_SET_BACKGROUND = 0x00, + CANVAS_ADD_TEXT, + CANVAS_ADD_IMAGE, + CANVAS_ADD_BAR, + CANVAS_ADD_RECTANGLE, +}; + +typedef struct __attribute__((__packed__)) { + QueueTaskType type; + QueueTaskState state; + uint8_t *nextTask; +} queueTask_t; + +typedef struct __attribute__((__packed__)) { + uint16_t x; + uint16_t y; + uint16_t width; + uint16_t height; + uint16_t color; + uint32_t count; +} parametersFill_t; + +typedef struct __attribute__((__packed__)) { + uint16_t x; + uint16_t y; + uint16_t width; + uint16_t height; + uint32_t count; +} parametersCanvas_t; + +typedef struct __attribute__((__packed__)) { + CanvasSubtype type; + uint16_t color; +} parametersCanvasBackground_t; + +typedef struct __attribute__((__packed__)) { + CanvasSubtype type; + uint16_t x; + uint16_t y; + uint16_t color; + uint32_t count; + uint16_t maxWidth; + uint16_t stringLength; +} parametersCanvasText_t; + +typedef struct __attribute__((__packed__)) { + CanvasSubtype type; + int16_t x; + int16_t y; + MarlinImage image; +} parametersCanvasImage_t; + +typedef struct __attribute__((__packed__)) { + CanvasSubtype type; + uint16_t x; + uint16_t y; + uint16_t width; + uint16_t height; + uint16_t color; +} parametersCanvasBar_t; + +typedef struct __attribute__((__packed__)) { + CanvasSubtype type; + uint16_t x; + uint16_t y; + uint16_t width; + uint16_t height; + uint16_t color; +} parametersCanvasRectangle_t; + +class TFT_Queue { + private: + static uint8_t queue[QUEUE_SIZE]; + static uint8_t *end_of_queue; + static uint8_t *current_task; + static uint8_t *last_task; + + static void finish_sketch(); + static void fill(queueTask_t *task); + static void canvas(queueTask_t *task); + + public: + static void reset(); + static void async(); + static void sync() { while (current_task != NULL) async(); } + + static void fill(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color); + static void canvas(uint16_t x, uint16_t y, uint16_t width, uint16_t height); + static void set_background(uint16_t color); + static void add_text(uint16_t x, uint16_t y, uint16_t color, uint8_t *string, uint16_t maxWidth); + + static void add_image(int16_t x, int16_t y, MarlinImage image, uint16_t *colors); + static void add_image(int16_t x, int16_t y, MarlinImage image, uint16_t color_main, uint16_t color_background, uint16_t color_shadow); + + static void add_bar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color); + static void add_rectangle(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color); +}; diff --git a/Marlin/src/lcd/tft/tft_string.cpp b/Marlin/src/lcd/tft/tft_string.cpp new file mode 100644 index 000000000000..663ed97c36c8 --- /dev/null +++ b/Marlin/src/lcd/tft/tft_string.cpp @@ -0,0 +1,169 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfig.h" + +#if HAS_GRAPHICAL_TFT + +#include "tft_string.h" +#include "../fontutils.h" + +//#define DEBUG_TFT_FONT +#define DEBUG_OUT ENABLED(DEBUG_TFT_FONT) +#include "../../core/debug_out.h" + +glyph_t *TFT_String::glyphs[256]; +font_t *TFT_String::font_header; + +uint8_t TFT_String::data[]; +uint16_t TFT_String::span; +uint16_t TFT_String::length; + +void TFT_String::set_font(const uint8_t *font) { + font_header = (font_t *)font; + uint32_t glyph; + + for (glyph = 0; glyph < 256; glyph++) glyphs[glyph] = NULL; + + DEBUG_ECHOLNPAIR("Format: ", font_header->Format); + DEBUG_ECHOLNPAIR("BBXWidth: ", font_header->BBXWidth); + DEBUG_ECHOLNPAIR("BBXHeight: ", font_header->BBXHeight); + DEBUG_ECHOLNPAIR("BBXOffsetX: ", font_header->BBXOffsetX); + DEBUG_ECHOLNPAIR("BBXOffsetY: ", font_header->BBXOffsetY); + DEBUG_ECHOLNPAIR("CapitalAHeight: ", font_header->CapitalAHeight); + DEBUG_ECHOLNPAIR("Encoding65Pos: ", font_header->Encoding65Pos); + DEBUG_ECHOLNPAIR("Encoding97Pos: ", font_header->Encoding97Pos); + DEBUG_ECHOLNPAIR("FontStartEncoding: ", font_header->FontStartEncoding); + DEBUG_ECHOLNPAIR("FontEndEncoding: ", font_header->FontEndEncoding); + DEBUG_ECHOLNPAIR("LowerGDescent: ", font_header->LowerGDescent); + DEBUG_ECHOLNPAIR("FontAscent: ", font_header->FontAscent); + DEBUG_ECHOLNPAIR("FontDescent: ", font_header->FontDescent); + DEBUG_ECHOLNPAIR("FontXAscent: ", font_header->FontXAscent); + DEBUG_ECHOLNPAIR("FontXDescent: ", font_header->FontXDescent); + + add_glyphs(font); +} + +void TFT_String::add_glyphs(const uint8_t *font) { + uint32_t glyph; + uint8_t *pointer = (uint8_t *)font + sizeof(font_t); + + for (glyph = ((font_t *)font)->FontStartEncoding; glyph <= ((font_t *)font)->FontEndEncoding; glyph++) { + if (*pointer != NO_GLYPH) { + glyphs[glyph] = (glyph_t *)pointer; + pointer += sizeof(glyph_t) + ((glyph_t *)pointer)->DataSize; + } + else { + pointer++; + } + } +} + +void TFT_String::set() { + *data = 0x00; + span = 0; + length = 0; +} + +uint8_t read_byte(uint8_t *byte) { return *byte; } + +void TFT_String::add(uint8_t *string, int8_t index, uint8_t *itemString) { + wchar_t wchar; + + while (*string) { + string = get_utf8_value_cb(string, read_byte, &wchar); + if (wchar > 255) wchar |= 0x0080; + uint8_t ch = uint8_t(wchar & 0x00FF); + + if (ch == '=' || ch == '~' || ch == '*') { + if (index >= 0) { + int8_t inum = index + ((ch == '=') ? 0 : LCD_FIRST_TOOL); + if (ch == '*') add_character('E'); + if (inum >= 10) { add_character('0' + (inum / 10)); inum %= 10; } + add_character('0' + inum); + } + else { + add(index == -2 ? GET_TEXT(MSG_CHAMBER) : GET_TEXT(MSG_BED)); + } + continue; + } + else if (ch == '$' && itemString) { + add(itemString); + continue; + } + + add_character(ch); + } + eol(); +} + +void TFT_String::add(uint8_t *string) { + wchar_t wchar; + while (*string) { + string = get_utf8_value_cb(string, read_byte, &wchar); + if (wchar > 255) wchar |= 0x0080; + uint8_t ch = uint8_t(wchar & 0x00FF); + add_character(ch); + } + eol(); +} + +void TFT_String::add_character(uint8_t character) { + if (length < MAX_STRING_LENGTH) { + data[length] = character; + length++; + span += glyph(character)->DWidth; + } +} + +void TFT_String::rtrim(uint8_t character) { + while (length) { + if (data[length - 1] == 0x20 || data[length - 1] == character) { + length--; + span -= glyph(data[length])->DWidth; + eol(); + } + else { + break; + } + } +} + +void TFT_String::ltrim(uint8_t character) { + uint16_t i, j; + for (i = 0; (i < length) && (data[i] == 0x20 || data[i] == character); i++) { + span -= glyph(data[i])->DWidth; + } + if (i == 0) return; + for (j = 0; i < length; data[j++] = data[i++]); + length = j; + eol(); +} + +void TFT_String::trim(uint8_t character) { + rtrim(character); + ltrim(character); +} + +TFT_String tft_string; + +#endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/tft_string.h b/Marlin/src/lcd/tft/tft_string.h new file mode 100644 index 000000000000..924d6de43027 --- /dev/null +++ b/Marlin/src/lcd/tft/tft_string.h @@ -0,0 +1,104 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include + +extern const uint8_t ISO10646_1_5x7[]; +extern const uint8_t font10x20[]; + +extern const uint8_t Helvetica12Bold[]; + +extern const uint8_t Helvetica14[], Helvetica14_symbols[]; +extern const uint8_t Helvetica18[], Helvetica18_symbols[]; + +#define NO_GLYPH 0xFF + +typedef struct __attribute__((__packed__)) { + uint8_t Format; + uint8_t BBXWidth; + uint8_t BBXHeight; + int8_t BBXOffsetX; + int8_t BBXOffsetY; + uint8_t CapitalAHeight; + uint16_t Encoding65Pos; + uint16_t Encoding97Pos; + uint8_t FontStartEncoding; + uint8_t FontEndEncoding; + int8_t LowerGDescent; + int8_t FontAscent; + int8_t FontDescent; + int8_t FontXAscent; + int8_t FontXDescent; +} font_t; + +typedef struct __attribute__((__packed__)) { + uint8_t BBXWidth; + uint8_t BBXHeight; + uint8_t DataSize; + int8_t DWidth; + int8_t BBXOffsetX; + int8_t BBXOffsetY; +} glyph_t; + +#define MAX_STRING_LENGTH 64 + +class TFT_String { + private: + static glyph_t *glyphs[256]; + static font_t *font_header; + + static uint8_t data[MAX_STRING_LENGTH + 1]; + static uint16_t span; // in pixels + static uint16_t length; // in characters + + static void add_character(uint8_t character); + static void eol() { data[length] = 0x00; } + + public: + static void set_font(const uint8_t *font); + static void add_glyphs(const uint8_t *font); + + static font_t *font() { return font_header; }; + static uint16_t font_height() { return font_header->FontAscent - font_header->FontDescent; } + static glyph_t *glyph(uint8_t character) { return glyphs[character] == NULL ? glyphs[0x3F] : glyphs[character]; } /* Use '?' for unknown glyphs */ + static inline glyph_t *glyph(uint8_t *character) { return glyph(*character); } + + static void set(); + static void add(uint8_t character) { add_character(character); eol(); } + static void add(uint8_t *string); + static void add(uint8_t *string, int8_t index, uint8_t *itemString = NULL); + static void set(uint8_t *string) { set(); add(string); }; + static void set(uint8_t *string, int8_t index, const char *itemString = NULL) { set(); add(string, index, (uint8_t *)itemString); }; + static inline void set(const char *string) { set((uint8_t *)string); } + static inline void set(const char *string, int8_t index, const char *itemString = NULL) { set((uint8_t *)string, index, itemString); } + static inline void add(const char *string) { add((uint8_t *)string); } + + static void trim(uint8_t character = 0x20); + static void rtrim(uint8_t character = 0x20); + static void ltrim(uint8_t character = 0x20); + static uint16_t width() { return span; } + static uint8_t *string() { return data; } + static uint16_t center(uint16_t width) { return span > width ? 0 : (width - span) / 2; } +}; + +extern TFT_String tft_string; diff --git a/Marlin/src/lcd/tft/touch.cpp b/Marlin/src/lcd/tft/touch.cpp new file mode 100644 index 000000000000..80c65f074ae6 --- /dev/null +++ b/Marlin/src/lcd/tft/touch.cpp @@ -0,0 +1,316 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(TOUCH_SCREEN) + +#include "touch.h" + +#include "../ultralcd.h" // for ui methods +#include "../menu/menu_item.h" // for touch_screen_calibration + +#include "../../module/temperature.h" +#include "../../module/planner.h" + +#if ENABLED(AUTO_BED_LEVELING_UBL) + #include "../../feature/bedlevel/bedlevel.h" +#endif + +#include "tft.h" + +bool Touch::enabled = true; +int16_t Touch::x, Touch::y; +touch_control_t Touch::controls[]; +touch_control_t *Touch::current_control; +uint16_t Touch::controls_count; +millis_t Touch::now = 0; +millis_t Touch::time_to_hold; +millis_t Touch::repeat_delay; +millis_t Touch::touch_time; +TouchControlType Touch::touch_control_type = NONE; +touch_calibration_t Touch::calibration; +#if ENABLED(TOUCH_SCREEN_CALIBRATION) + calibrationState Touch::calibration_state = CALIBRATION_NONE; + touch_calibration_point_t Touch::calibration_points[4]; +#endif +#if HAS_RESUME_CONTINUE + extern bool wait_for_user; +#endif + +void Touch::init() { + calibration_reset(); + reset(); + io.Init(); + enable(); +} + +void Touch::add_control(TouchControlType type, uint16_t x, uint16_t y, uint16_t width, uint16_t height, int32_t data) { + if (controls_count == MAX_CONTROLS) return; + + controls[controls_count].type = type; + controls[controls_count].x = x; + controls[controls_count].y = y; + controls[controls_count].width = width; + controls[controls_count].height = height; + controls[controls_count].data = data; + controls_count++; +} + +void Touch::idle() { + uint16_t i; + int16_t _x, _y; + + if (!enabled) return; + + if (now == millis()) return; + now = millis(); + + if (get_point(&_x, &_y)) { + #if HAS_RESUME_CONTINUE + // UI is waiting for a click anywhere? + if (wait_for_user) { + touch_control_type = CLICK; + ui.lcd_clicked = true; + return; + } + #endif + + #if LCD_TIMEOUT_TO_STATUS + ui.return_to_status_ms = now + LCD_TIMEOUT_TO_STATUS; + #endif + + if (touch_time) { + #if ENABLED(TOUCH_SCREEN_CALIBRATION) + if (touch_control_type == NONE && ELAPSED(now, touch_time + TOUCH_SCREEN_HOLD_TO_CALIBRATE_MS) && ui.on_status_screen()) + ui.goto_screen(touch_screen_calibration); + #endif + return; + } + + if (time_to_hold == 0) time_to_hold = now + MINIMUM_HOLD_TIME; + if (PENDING(now, time_to_hold)) return; + + if (x != 0 && y != 0) { + if (current_control) { + if (WITHIN(x, current_control->x - FREE_MOVE_RANGE, current_control->x + current_control->width + FREE_MOVE_RANGE) && WITHIN(y, current_control->y - FREE_MOVE_RANGE, current_control->y + current_control->height + FREE_MOVE_RANGE)) { + NOLESS(x, current_control->x); + NOMORE(x, current_control->x + current_control->width); + NOLESS(y, current_control->y); + NOMORE(y, current_control->y + current_control->height); + touch(current_control); + } + else { + current_control = NULL; + } + } + else { + for (i = 0; i < controls_count; i++) { + if ((WITHIN(x, controls[i].x, controls[i].x + controls[i].width) && WITHIN(y, controls[i].y, controls[i].y + controls[i].height)) || (TERN(TOUCH_SCREEN_CALIBRATION, controls[i].type == CALIBRATE, false))) { + touch_control_type = controls[i].type; + touch(&controls[i]); + break; + } + } + } + + if (current_control == NULL) + touch_time = now; + } + x = _x; + y = _y; + } + else { + x = y = 0; + current_control = NULL; + touch_time = 0; + touch_control_type = NONE; + time_to_hold = 0; + repeat_delay = TOUCH_REPEAT_DELAY; + } +} + +void Touch::touch(touch_control_t *control) { + switch (control->type) { + #if ENABLED(TOUCH_SCREEN_CALIBRATION) + case CALIBRATE: + ui.refresh(); + + if (calibration_state < CALIBRATION_SUCCESS) { + calibration_points[calibration_state].x = int16_t(control->data >> 16); + calibration_points[calibration_state].y = int16_t(control->data & 0xFFFF); + calibration_points[calibration_state].raw_x = x; + calibration_points[calibration_state].raw_y = y; + } + + switch (calibration_state) { + case CALIBRATION_POINT_1: calibration_state = CALIBRATION_POINT_2; break; + case CALIBRATION_POINT_2: calibration_state = CALIBRATION_POINT_3; break; + case CALIBRATION_POINT_3: calibration_state = CALIBRATION_POINT_4; break; + case CALIBRATION_POINT_4: + if (validate_precision_x(0, 1) && validate_precision_x(2, 3) && validate_precision_y(0, 2) && validate_precision_y(1, 3)) { + calibration_state = CALIBRATION_SUCCESS; + calibration.x = ((calibration_points[2].x - calibration_points[0].x) << 17) / (calibration_points[3].raw_x + calibration_points[2].raw_x - calibration_points[1].raw_x - calibration_points[0].raw_x); + calibration.y = ((calibration_points[1].y - calibration_points[0].y) << 17) / (calibration_points[3].raw_y - calibration_points[2].raw_y + calibration_points[1].raw_y - calibration_points[0].raw_y); + calibration.offset_x = calibration_points[0].x - int16_t(((calibration_points[0].raw_x + calibration_points[1].raw_x) * calibration.x) >> 17); + calibration.offset_y = calibration_points[0].y - int16_t(((calibration_points[0].raw_y + calibration_points[2].raw_y) * calibration.y) >> 17); + calibration.orientation = TOUCH_LANDSCAPE; + } + else if (validate_precision_y(0, 1) && validate_precision_y(2, 3) && validate_precision_x(0, 2) && validate_precision_x(1, 3)) { + calibration_state = CALIBRATION_SUCCESS; + calibration.x = ((calibration_points[2].x - calibration_points[0].x) << 17) / (calibration_points[3].raw_y + calibration_points[2].raw_y - calibration_points[1].raw_y - calibration_points[0].raw_y); + calibration.y = ((calibration_points[1].y - calibration_points[0].y) << 17) / (calibration_points[3].raw_x - calibration_points[2].raw_x + calibration_points[1].raw_x - calibration_points[0].raw_x); + calibration.offset_x = calibration_points[0].x - int16_t(((calibration_points[0].raw_y + calibration_points[1].raw_y) * calibration.x) >> 17); + calibration.offset_y = calibration_points[0].y - int16_t(((calibration_points[0].raw_x + calibration_points[2].raw_x) * calibration.y) >> 17); + calibration.orientation = TOUCH_PORTRAIT; + } + else { + calibration_state = CALIBRATION_FAIL; + calibration_reset(); + } + + if (calibration_state == CALIBRATION_SUCCESS) { + SERIAL_ECHOLN("Touch screen calibration completed"); + SERIAL_ECHOLNPAIR("TOUCH_CALIBRATION_X ", calibration.x); + SERIAL_ECHOLNPAIR("TOUCH_CALIBRATION_Y ", calibration.y); + SERIAL_ECHOLNPAIR("TOUCH_OFFSET_X ", calibration.offset_x); + SERIAL_ECHOLNPAIR("TOUCH_OFFSET_Y ", calibration.offset_y); + SERIAL_ECHO("TOUCH_ORIENTATION "); if (calibration.orientation == TOUCH_LANDSCAPE) SERIAL_ECHOLN("TOUCH_LANDSCAPE"); else SERIAL_ECHOLN("TOUCH_PORTRAIT"); + } + break; + default: break; + } + break; + #endif // TOUCH_SCREEN_CALIBRATION + + case MENU_SCREEN: ui.goto_screen((screenFunc_t)control->data); break; + case BACK: ui.goto_previous_screen(); break; + case CLICK: ui.lcd_clicked = true; break; + #if HAS_RESUME_CONTINUE + case RESUME_CONTINUE: extern bool wait_for_user; wait_for_user = false; break; + #endif + case CANCEL: ui.encoderPosition = 0; ui.selection = false; ui.lcd_clicked = true; break; + case CONFIRM: ui.encoderPosition = 1; ui.selection = true; ui.lcd_clicked = true; break; + case MENU_ITEM: ui.encoderPosition = control->data; ui.refresh(); break; + case PAGE_UP: + encoderTopLine = encoderTopLine > LCD_HEIGHT ? encoderTopLine - LCD_HEIGHT : 0; + ui.encoderPosition = ui.encoderPosition > LCD_HEIGHT ? ui.encoderPosition - LCD_HEIGHT : 0; + ui.refresh(); + break; + case PAGE_DOWN: + encoderTopLine = encoderTopLine + 2 * LCD_HEIGHT < screen_items ? encoderTopLine + LCD_HEIGHT : screen_items - LCD_HEIGHT; + ui.encoderPosition = ui.encoderPosition + LCD_HEIGHT < (uint32_t)screen_items ? ui.encoderPosition + LCD_HEIGHT : screen_items; + ui.refresh(); + break; + case SLIDER: hold(control); ui.encoderPosition = (x - control->x) * control->data / control->width; break; + case INCREASE: hold(control, repeat_delay - 5); TERN(AUTO_BED_LEVELING_UBL, ui.external_control ? ubl.encoder_diff++ : ui.encoderPosition++, ui.encoderPosition++); break; + case DECREASE: hold(control, repeat_delay - 5); TERN(AUTO_BED_LEVELING_UBL, ui.external_control ? ubl.encoder_diff-- : ui.encoderPosition--, ui.encoderPosition--); break; + case HEATER: + int8_t heater; + heater = control->data; + ui.clear_lcd(); + if (heater >= 0) { // HotEnd + #if HOTENDS == 1 + MenuItem_int3::action((const char *)GET_TEXT_F(MSG_NOZZLE), &thermalManager.temp_hotend[0].target, 0, thermalManager.heater_maxtemp[0] - 15, []{ thermalManager.start_watching_hotend(0); }); + #else + MenuItemBase::itemIndex = heater; + MenuItem_int3::action((const char *)GET_TEXT_F(MSG_NOZZLE_N), &thermalManager.temp_hotend[heater].target, 0, thermalManager.heater_maxtemp[heater] - 15, []{ thermalManager.start_watching_hotend(MenuItemBase::itemIndex); }); + #endif + } + #if HAS_HEATED_BED + else if (heater == H_BED) { + MenuItem_int3::action((const char *)GET_TEXT_F(MSG_BED), &thermalManager.temp_bed.target, 0, BED_MAXTEMP - 10, thermalManager.start_watching_bed); + } + #endif + #if HAS_HEATED_CHAMBER + else if (heater == H_CHAMBER) { + MenuItem_int3::action((const char *)GET_TEXT_F(MSG_CHAMBER), &thermalManager.temp_chamber.target, 0, CHAMBER_MAXTEMP - 10, thermalManager.start_watching_chamber); + } + #endif + break; + case FAN: + ui.clear_lcd(); + static uint8_t fan, fan_speed; + fan = 0; + fan_speed = thermalManager.fan_speed[fan]; + MenuItem_percent::action((const char *)GET_TEXT_F(MSG_FIRST_FAN_SPEED), &fan_speed, 0, 255, []{ thermalManager.set_fan_speed(fan, fan_speed); }); + break; + case FEEDRATE: + ui.clear_lcd(); + MenuItem_int3::action((const char *)GET_TEXT_F(MSG_SPEED), &feedrate_percentage, 10, 999); + break; + case FLOWRATE: + ui.clear_lcd(); + MenuItemBase::itemIndex = control->data; + #if EXTRUDERS == 1 + MenuItem_int3::action((const char *)GET_TEXT_F(MSG_FLOW), &planner.flow_percentage[MenuItemBase::itemIndex], 10, 999, []{ planner.refresh_e_factor(MenuItemBase::itemIndex); }); + #else + MenuItem_int3::action((const char *)GET_TEXT_F(MSG_FLOW_N), &planner.flow_percentage[MenuItemBase::itemIndex], 10, 999, []{ planner.refresh_e_factor(MenuItemBase::itemIndex); }); + #endif + break; + + #if ENABLED(AUTO_BED_LEVELING_UBL) + case UBL: hold(control, UBL_REPEAT_DELAY); ui.encoderPosition += control->data; break; + #endif + + case MOVE_AXIS: + ui.goto_screen((screenFunc_t)ui.move_axis_screen); + break; + + // TODO: TOUCH could receive data to pass to the callback + case BUTTON: ((screenFunc_t)control->data)(); break; + + default: break; + } +} + +void Touch::hold(touch_control_t *control, millis_t delay) { + current_control = control; + if (delay) { + repeat_delay = delay > MIN_REPEAT_DELAY ? delay : MIN_REPEAT_DELAY; + time_to_hold = now + repeat_delay; + } + ui.refresh(); +} + +bool Touch::get_point(int16_t *x, int16_t *y) { + bool is_touched = (calibration.orientation == TOUCH_PORTRAIT ? io.getRawPoint(y, x) : io.getRawPoint(x, y)); + + if (is_touched && calibration.orientation != TOUCH_ORIENTATION_NONE) { + *x = int16_t((int32_t(*x) * calibration.x) >> 16) + calibration.offset_x; + *y = int16_t((int32_t(*y) * calibration.y) >> 16) + calibration.offset_y; + } + return is_touched; +} +Touch touch; + +bool MarlinUI::touch_pressed() { + return touch.is_clicked(); +} + +void add_control(uint16_t x, uint16_t y, TouchControlType control_type, int32_t data, MarlinImage image, bool is_enabled, uint16_t color_enabled, uint16_t color_disabled) { + uint16_t width = Images[image].width; + uint16_t height = Images[image].height; + tft.canvas(x, y, width, height); + tft.add_image(0, 0, image, is_enabled ? color_enabled : color_disabled); + if (is_enabled) + touch.add_control(control_type, x, y, width, height, data); +} + +#endif // TOUCH_SCREEN diff --git a/Marlin/src/lcd/tft/touch.h b/Marlin/src/lcd/tft/touch.h new file mode 100644 index 000000000000..7d8f222918db --- /dev/null +++ b/Marlin/src/lcd/tft/touch.h @@ -0,0 +1,185 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../../inc/MarlinConfigPre.h" + +#if ENABLED(TOUCH_SCREEN) + +#include "tft_color.h" +#include "tft_image.h" + +#include HAL_PATH(../../HAL, tft/xpt2046.h) +#define TOUCH_DRIVER XPT2046 + +#ifndef TOUCH_SCREEN_CALIBRATION_PRECISION + #define TOUCH_SCREEN_CALIBRATION_PRECISION 80 +#endif + +#ifndef TOUCH_SCREEN_HOLD_TO_CALIBRATE_MS + #define TOUCH_SCREEN_HOLD_TO_CALIBRATE_MS 2500 +#endif + +#define TOUCH_ORIENTATION_NONE 0 +#define TOUCH_LANDSCAPE 1 +#define TOUCH_PORTRAIT 2 + +#if !(defined(TOUCH_CALIBRATION_X) || defined(TOUCH_CALIBRATION_Y) || defined(TOUCH_OFFSET_X) || defined(TOUCH_OFFSET_Y) || defined(TOUCH_ORIENTATION)) + #if defined(XPT2046_X_CALIBRATION) && defined(XPT2046_Y_CALIBRATION) && defined(XPT2046_X_OFFSET) && defined(XPT2046_Y_OFFSET) + #define TOUCH_CALIBRATION_X XPT2046_X_CALIBRATION + #define TOUCH_CALIBRATION_Y XPT2046_Y_CALIBRATION + #define TOUCH_OFFSET_X XPT2046_X_OFFSET + #define TOUCH_OFFSET_Y XPT2046_Y_OFFSET + #define TOUCH_ORIENTATION TOUCH_LANDSCAPE + #else + #define TOUCH_CALIBRATION_X 0 + #define TOUCH_CALIBRATION_Y 0 + #define TOUCH_OFFSET_X 0 + #define TOUCH_OFFSET_Y 0 + #define TOUCH_ORIENTATION TOUCH_ORIENTATION_NONE + #endif +#endif + +// Menu Navigation +extern int8_t encoderTopLine, encoderLine, screen_items; + +enum TouchControlType : uint16_t { + NONE = 0x0000, + CALIBRATE, + MENU_SCREEN, + MENU_ITEM, + BACK, + PAGE_UP, + PAGE_DOWN, + CLICK, + RESUME_CONTINUE, + SLIDER, + INCREASE, + DECREASE, + CANCEL, + CONFIRM, + HEATER, + FAN, + FEEDRATE, + FLOWRATE, + UBL, + MOVE_AXIS, + BUTTON, +}; + +typedef void (*screenFunc_t)(); + +void add_control(uint16_t x, uint16_t y, TouchControlType control_type, int32_t data, MarlinImage image, bool is_enabled = true, uint16_t color_enabled = COLOR_CONTROL_ENABLED, uint16_t color_disabled = COLOR_CONTROL_DISABLED); +inline void add_control(uint16_t x, uint16_t y, TouchControlType control_type, MarlinImage image, bool is_enabled = true, uint16_t color_enabled = COLOR_CONTROL_ENABLED, uint16_t color_disabled = COLOR_CONTROL_DISABLED) { add_control(x, y, control_type, 0, image, is_enabled, color_enabled, color_disabled); } +inline void add_control(uint16_t x, uint16_t y, screenFunc_t screen, MarlinImage image, bool is_enabled = true, uint16_t color_enabled = COLOR_CONTROL_ENABLED, uint16_t color_disabled = COLOR_CONTROL_DISABLED) { add_control(x, y, MENU_SCREEN, (int32_t)screen, image, is_enabled, color_enabled, color_disabled); } + +typedef struct __attribute__((__packed__)) { + TouchControlType type; + uint16_t x; + uint16_t y; + uint16_t width; + uint16_t height; + int32_t data; +} touch_control_t; + +typedef struct __attribute__((__packed__)) { + int32_t x; + int32_t y; + int16_t offset_x; + int16_t offset_y; + uint8_t orientation; +} touch_calibration_t; + +typedef struct __attribute__((__packed__)) { + uint16_t x; + uint16_t y; + int16_t raw_x; + int16_t raw_y; +} touch_calibration_point_t; + +enum calibrationState : uint8_t { + CALIBRATION_POINT_1 = 0x00, + CALIBRATION_POINT_2, + CALIBRATION_POINT_3, + CALIBRATION_POINT_4, + CALIBRATION_SUCCESS, + CALIBRATION_FAIL, + CALIBRATION_NONE, +}; + +#define MAX_CONTROLS 16 +#define MINIMUM_HOLD_TIME 15 +#define TOUCH_REPEAT_DELAY 75 +#define MIN_REPEAT_DELAY 25 +#define UBL_REPEAT_DELAY 125 +#define FREE_MOVE_RANGE 32 + +class Touch { + private: + static TOUCH_DRIVER io; + static int16_t x, y; + static bool enabled; + + static touch_control_t controls[MAX_CONTROLS]; + static touch_control_t *current_control; + static uint16_t controls_count; + + static millis_t now; + static millis_t time_to_hold; + static millis_t repeat_delay; + static millis_t touch_time; + static TouchControlType touch_control_type; + + static inline bool get_point(int16_t *x, int16_t *y); + static void touch(touch_control_t *control); + static void hold(touch_control_t *control, millis_t delay = 0); + + #if ENABLED(TOUCH_SCREEN_CALIBRATION) + static calibrationState calibration_state; + static touch_calibration_point_t calibration_points[4]; + + static bool validate_precision(int32_t a, int32_t b) { return (a > b ? (100 * b) / a : (100 * a) / b) > TOUCH_SCREEN_CALIBRATION_PRECISION; } + static bool validate_precision_x(uint8_t a, uint8_t b) { return validate_precision(calibration_points[a].raw_x, calibration_points[b].raw_x); } + static bool validate_precision_y(uint8_t a, uint8_t b) { return validate_precision(calibration_points[a].raw_y, calibration_points[b].raw_y); } + #endif // TOUCH_SCREEN_CALIBRATION + + public: + static void init(); + static void reset() { controls_count = 0; touch_time = -1; current_control = NULL; } + static void clear() { controls_count = 0; } + static void idle(); + static bool is_clicked() { return touch_control_type == CLICK; } + static void disable() { enabled = false; } + static void enable() { enabled = true; } + + static void add_control(TouchControlType type, uint16_t x, uint16_t y, uint16_t width, uint16_t height, int32_t data = 0); + + static touch_calibration_t calibration; + static void calibration_reset() { calibration = {TOUCH_CALIBRATION_X, TOUCH_CALIBRATION_Y, TOUCH_OFFSET_X, TOUCH_OFFSET_Y, TOUCH_ORIENTATION}; } + + #if ENABLED(TOUCH_SCREEN_CALIBRATION) + static calibrationState calibration_start() { calibration = {0, 0, 0, 0, TOUCH_ORIENTATION_NONE}; return calibration_state = CALIBRATION_POINT_1; } + static void calibration_end() { calibration_state = CALIBRATION_NONE; } + static calibrationState get_calibration_state() { return calibration_state; } + #endif // TOUCH_SCREEN_CALIBRATION +}; + +extern Touch touch; + +#endif // TOUCH_SCREEN diff --git a/Marlin/src/lcd/tft/ui_320x240.cpp b/Marlin/src/lcd/tft/ui_320x240.cpp new file mode 100644 index 000000000000..de8498c5ff0f --- /dev/null +++ b/Marlin/src/lcd/tft/ui_320x240.cpp @@ -0,0 +1,656 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfigPre.h" + +#if HAS_UI_320x240 + +#include "ui_320x240.h" + +#include "../ultralcd.h" +#include "../menu/menu.h" +#include "../../libs/numtostr.h" + +#include "../../sd/cardreader.h" +#include "../../module/temperature.h" +#include "../../module/printcounter.h" +#include "../../module/planner.h" +#include "../../module/motion.h" + +#if DISABLED(LCD_PROGRESS_BAR) && BOTH(FILAMENT_LCD_DISPLAY, SDSUPPORT) + #include "../../feature/filwidth.h" + #include "../../gcode/parser.h" +#endif + +#if ENABLED(AUTO_BED_LEVELING_UBL) + #include "../../feature/bedlevel/bedlevel.h" +#endif + +#if !HAS_LCD_MENU + #error "Seriously? High resolution TFT screen without menu?" +#endif + +static bool draw_menu_navigation = false; + +void MarlinUI::tft_idle() { + #if ENABLED(TOUCH_SCREEN) + if (draw_menu_navigation) { + add_control(48, 206, PAGE_UP, imgPageUp, encoderTopLine > 0); + add_control(240, 206, PAGE_DOWN, imgPageDown, encoderTopLine + LCD_HEIGHT < screen_items); + add_control(144, 206, BACK, imgBack); + draw_menu_navigation = false; + } + #endif + + tft.queue.async(); + TERN_(TOUCH_SCREEN, touch.idle()); +} + +void MarlinUI::init_lcd() { + tft.init(); + tft.set_font(MENU_FONT_NAME); + #ifdef SYMBOLS_FONT_NAME + tft.add_glyphs(SYMBOLS_FONT_NAME); + #endif + TERN_(TOUCH_SCREEN, touch.init()); + clear_lcd(); +} + +bool MarlinUI::detected() { return true; } + +void MarlinUI::clear_lcd() { + #if ENABLED(TOUCH_SCREEN) + touch.reset(); + draw_menu_navigation = false; + #endif + + tft.queue.reset(); + tft.fill(0, 0, TFT_WIDTH, TFT_HEIGHT, COLOR_BACKGROUND); +} + +#if ENABLED(SHOW_BOOTSCREEN) + #ifndef BOOTSCREEN_TIMEOUT + #define BOOTSCREEN_TIMEOUT 1500 + #endif + + void MarlinUI::show_bootscreen() { + tft.queue.reset(); + + tft.canvas(0, 0, TFT_WIDTH, TFT_HEIGHT); + tft.add_image(0, 0, imgBootScreen); // MarlinLogo320x240x16 + + #ifdef WEBSITE_URL + tft.add_text(4, 188, COLOR_WEBSITE_URL, WEBSITE_URL); + #endif + + tft.queue.sync(); + safe_delay(BOOTSCREEN_TIMEOUT); + clear_lcd(); + } +#endif // SHOW_BOOTSCREEN + +void MarlinUI::draw_kill_screen() { + tft.queue.reset(); + tft.fill(0, 0, TFT_WIDTH, TFT_HEIGHT, COLOR_KILL_SCREEN_BG); + + tft.canvas(0, 60, TFT_WIDTH, 20); + tft.set_background(COLOR_KILL_SCREEN_BG); + tft_string.set(status_message); + tft_string.trim(); + tft.add_text(tft_string.center(TFT_WIDTH), 0, COLOR_KILL_SCREEN_TEXT, tft_string); + + tft.canvas(0, 120, TFT_WIDTH, 20); + tft.set_background(COLOR_KILL_SCREEN_BG); + tft_string.set(GET_TEXT(MSG_HALTED)); + tft_string.trim(); + tft.add_text(tft_string.center(TFT_WIDTH), 0, COLOR_KILL_SCREEN_TEXT, tft_string); + + tft.canvas(0, 160, TFT_WIDTH, 20); + tft.set_background(COLOR_KILL_SCREEN_BG); + tft_string.set(GET_TEXT(MSG_PLEASE_RESET)); + tft_string.trim(); + tft.add_text(tft_string.center(TFT_WIDTH), 0, COLOR_KILL_SCREEN_TEXT, tft_string); + + tft.queue.sync(); +} + +void draw_heater_status(uint16_t x, uint16_t y, const int8_t Heater) { + MarlinImage image = imgHotEnd; + uint16_t Color; + float currentTemperature, targetTemperature; + + if (Heater >= 0) { // HotEnd + currentTemperature = thermalManager.degHotend(Heater); + targetTemperature = thermalManager.degTargetHotend(Heater); + } +#if HAS_HEATED_BED + else if (Heater == H_BED) { + currentTemperature = thermalManager.degBed(); + targetTemperature = thermalManager.degTargetBed(); + } +#endif // HAS_HEATED_BED +#if HAS_TEMP_CHAMBER + else if (Heater == H_CHAMBER) { + currentTemperature = thermalManager.degChamber(); + #if HAS_HEATED_CHAMBER + targetTemperature = thermalManager.degTargetChamber(); + #else + targetTemperature = ABSOLUTE_ZERO; + #endif + } +#endif // HAS_TEMP_CHAMBER + else return; + + TERN_(TOUCH_SCREEN, if (targetTemperature >= 0) touch.add_control(HEATER, x, y, 64, 100, Heater)); + tft.canvas(x, y, 64, 100); + tft.set_background(COLOR_BACKGROUND); + + Color = currentTemperature < 0 ? COLOR_INACTIVE : COLOR_COLD; + + if (Heater >= 0) { // HotEnd + if (currentTemperature >= 50) Color = COLOR_HOTEND; + } + #if HAS_HEATED_BED + else if (Heater == H_BED) { + if (currentTemperature >= 50) Color = COLOR_HEATED_BED; + image = targetTemperature > 0 ? imgBedHeated : imgBed; + } + #endif // HAS_HEATED_BED + #if HAS_TEMP_CHAMBER + else if (Heater == H_CHAMBER) { + if (currentTemperature >= 50) Color = COLOR_CHAMBER; + image = targetTemperature > 0 ? imgChamberHeated : imgChamber; + } + #endif // HAS_TEMP_CHAMBER + + tft.add_image(0, 18, image, Color); + + tft_string.set((uint8_t *)i16tostr3rj(currentTemperature + 0.5)); + tft_string.add(LCD_STR_DEGREE); + tft_string.trim(); + tft.add_text(tft_string.center(64) + 2, 72, Color, tft_string); + + if (targetTemperature >= 0) { + tft_string.set((uint8_t *)i16tostr3rj(targetTemperature + 0.5)); + tft_string.add(LCD_STR_DEGREE); + tft_string.trim(); + tft.add_text(tft_string.center(64) + 2, 8, Color, tft_string); + + } +} + +void draw_fan_status(uint16_t x, uint16_t y, const bool blink) { + TERN_(TOUCH_SCREEN, touch.add_control(FAN, x, y, 64, 100)); + tft.canvas(x, y, 64, 100); + tft.set_background(COLOR_BACKGROUND); + + uint8_t fanSpeed = thermalManager.fan_speed[0]; + MarlinImage image; + + if (fanSpeed >= 127) + image = blink ? imgFanFast1 : imgFanFast0; + else if (fanSpeed > 0) + image = blink ? imgFanSlow1 : imgFanSlow0; + else + image = imgFanIdle; + + tft.add_image(0, 10, image, COLOR_FAN); + + tft_string.set((uint8_t *)ui8tostr4pctrj(thermalManager.fan_speed[0])); + tft_string.trim(); + tft.add_text(tft_string.center(64) + 6, 72, COLOR_FAN, tft_string); +} + +void MarlinUI::draw_status_screen() { + const bool blink = get_blink(); + + TERN_(TOUCH_SCREEN, touch.clear()); + + // heaters and fan + uint16_t i, x, y = POS_Y; + + for (i = 0 ; i < ITEMS_COUNT; i++) { + x = (320 / ITEMS_COUNT - 64) / 2 + (320 * i / ITEMS_COUNT); + switch (i) { + #ifdef ITEM_E0 + case ITEM_E0: draw_heater_status(x, y, H_E0); break; + #endif + #ifdef ITEM_E1 + case ITEM_E1: draw_heater_status(x, y, H_E1); break; + #endif + #ifdef ITEM_E2 + case ITEM_E2: draw_heater_status(x, y, H_E2); break; + #endif + #ifdef ITEM_BED + case ITEM_BED: draw_heater_status(x, y, H_BED); break; + #endif + #ifdef ITEM_CHAMBER + case ITEM_CHAMBER: draw_heater_status(x, y, H_CHAMBER); break; + #endif + #ifdef ITEM_FAN + case ITEM_FAN: draw_fan_status(x, y, blink); break; + #endif + } + } + + // coordinates + tft.canvas(4, 103, 312, 24); + tft.set_background(COLOR_BACKGROUND); + tft.add_rectangle(0, 0, 312, 24, COLOR_AXIS_HOMED); + + uint16_t color; + uint16_t offset; + bool is_homed; + + tft.add_text( 10, 3, COLOR_AXIS_HOMED , "X"); + tft.add_text(127, 3, COLOR_AXIS_HOMED , "Y"); + tft.add_text(219, 3, COLOR_AXIS_HOMED , "Z"); + + is_homed = TEST(axis_homed, X_AXIS); + tft_string.set(blink & !is_homed ? "?" : ftostr4sign(LOGICAL_X_POSITION(current_position.x))); + tft.add_text( 68 - tft_string.width(), 3, is_homed ? COLOR_AXIS_HOMED : COLOR_AXIS_NOT_HOMED, tft_string); + + is_homed = TEST(axis_homed, Y_AXIS); + tft_string.set(blink & !is_homed ? "?" : ftostr4sign(LOGICAL_Y_POSITION(current_position.y))); + tft.add_text(185 - tft_string.width(), 3, is_homed ? COLOR_AXIS_HOMED : COLOR_AXIS_NOT_HOMED, tft_string); + + is_homed = TEST(axis_homed, Z_AXIS); + if (blink & !is_homed) { + tft_string.set("?"); + offset = 25; // ".00" + } + else { + const float z = LOGICAL_Z_POSITION(current_position.z); + tft_string.set(ftostr52sp((int16_t)z)); + tft_string.rtrim(); + offset = tft_string.width(); + + tft_string.set(ftostr52sp(z)); + offset += 25 - tft_string.width(); + } + tft.add_text(301 - tft_string.width() - offset, 3, is_homed ? COLOR_AXIS_HOMED : COLOR_AXIS_NOT_HOMED, tft_string); + + // feed rate + tft.canvas(70, 136, 80, 32); + tft.set_background(COLOR_BACKGROUND); + color = feedrate_percentage == 100 ? COLOR_RATE_100 : COLOR_RATE_ALTERED; + tft.add_image(0, 0, imgFeedRate, color); + tft_string.set(i16tostr3rj(feedrate_percentage)); + tft_string.add('%'); + tft.add_text(32, 6, color , tft_string); + TERN_(TOUCH_SCREEN, touch.add_control(FEEDRATE, 70, 136, 80, 32)); + + // flow rate + tft.canvas(170, 136, 80, 32); + tft.set_background(COLOR_BACKGROUND); + color = planner.flow_percentage[0] == 100 ? COLOR_RATE_100 : COLOR_RATE_ALTERED; + tft.add_image(0, 0, imgFlowRate, color); + tft_string.set(i16tostr3rj(planner.flow_percentage[active_extruder])); + tft_string.add('%'); + tft.add_text(32, 6, color , tft_string); + TERN_(TOUCH_SCREEN, touch.add_control(FLOWRATE, 170, 136, 80, 32, active_extruder)); + + // print duration + char buffer[14]; + duration_t elapsed = print_job_timer.duration(); + elapsed.toDigital(buffer); + + tft.canvas(96, 176, 128, 20); + tft.set_background(COLOR_BACKGROUND); + tft_string.set(buffer); + tft.add_text(tft_string.center(128), 0, COLOR_PRINT_TIME, tft_string); + + // progress bar + const uint8_t progress = ui.get_progress_percent(); + tft.canvas(4, 198, 312, 9); + tft.set_background(COLOR_PROGRESS_BG); + tft.add_rectangle(0, 0, 312, 9, COLOR_PROGRESS_FRAME); + if (progress) + tft.add_bar(1, 1, (310 * progress) / 100, 7, COLOR_PROGRESS_BAR); + + // status message + tft.canvas(0, 216, 320, 20); + tft.set_background(COLOR_BACKGROUND); + tft_string.set(status_message); + tft_string.trim(); + tft.add_text(tft_string.center(TFT_WIDTH), 0, COLOR_STATUS_MESSAGE, tft_string); + + #if ENABLED(TOUCH_SCREEN) + add_control(256, 130, menu_main, imgSettings); + TERN_(SDSUPPORT, add_control(0, 130, menu_media, imgSD, card.isMounted() && !printingIsActive(), COLOR_CONTROL_ENABLED, card.isMounted() && printingIsActive() ? COLOR_BUSY : COLOR_CONTROL_DISABLED)); + #endif +} + +// Draw a static item with no left-right margin required. Centered by default. +void MenuItem_static::draw(const uint8_t row, PGM_P const pstr, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) { + menu_item(row); + tft_string.set(pstr, itemIndex, itemString); + if (vstr) + tft_string.add(vstr); + tft.add_text(tft_string.center(TFT_WIDTH), MENU_TEXT_Y_OFFSET, COLOR_YELLOW, tft_string); +} + +// Draw a generic menu item with pre_char (if selected) and post_char +void MenuItemBase::_draw(const bool sel, const uint8_t row, PGM_P const pstr, const char pre_char, const char post_char) { + menu_item(row, sel); + + uint8_t *string = (uint8_t *)pstr; + MarlinImage image = noImage; + switch (*string) { + case 0x01: image = imgRefresh; break; // LCD_STR_REFRESH + case 0x02: image = imgDirectory; break; // LCD_STR_FOLDER + } + + uint8_t offset = MENU_TEXT_X_OFFSET; + if (image != noImage) { + string++; + offset = 32; + tft.add_image(0, 0, image, COLOR_MENU_TEXT, sel ? COLOR_SELECTION_BG : COLOR_BACKGROUND); + } + + tft_string.set(string, itemIndex, itemString); + tft.add_text(offset, MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); +} + +// Draw a menu item with a (potentially) editable value +void MenuEditItemBase::draw(const bool sel, const uint8_t row, PGM_P const pstr, const char* const data, const bool pgm) { + menu_item(row, sel); + + tft_string.set(pstr, itemIndex, itemString); + tft.add_text(MENU_TEXT_X_OFFSET, MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); + if (data) { + tft_string.set(data); + tft.add_text(TFT_WIDTH - MENU_TEXT_X_OFFSET - tft_string.width(), MENU_TEXT_Y_OFFSET, COLOR_MENU_VALUE, tft_string); + } +} + +// Low-level draw_edit_screen can be used to draw an edit screen from anyplace +void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char* const value/*=nullptr*/) { + ui.encoder_direction_normal(); + TERN_(TOUCH_SCREEN, touch.clear()); + + uint16_t line = 1; + + menu_line(line++); + tft_string.set(pstr, itemIndex, itemString); + tft_string.trim(); + tft.add_text(tft_string.center(TFT_WIDTH), MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); + + TERN_(AUTO_BED_LEVELING_UBL, if (ui.external_control) line++); // ftostr52() will overwrite *value so *value has to be displayed first + + menu_line(line); + tft_string.set(value); + tft_string.trim(); + tft.add_text(tft_string.center(TFT_WIDTH), MENU_TEXT_Y_OFFSET, COLOR_MENU_VALUE, tft_string); + + #if ENABLED(AUTO_BED_LEVELING_UBL) + if (ui.external_control) { + menu_line(line - 1); + + tft_string.set(X_LBL); + tft.add_text(52, MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); + tft_string.set(ftostr52(LOGICAL_X_POSITION(current_position.x))); + tft_string.trim(); + tft.add_text(144 - tft_string.width(), MENU_TEXT_Y_OFFSET, COLOR_MENU_VALUE, tft_string); + + tft_string.set(Y_LBL); + tft.add_text(176, MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); + tft_string.set(ftostr52(LOGICAL_X_POSITION(current_position.y))); + tft_string.trim(); + tft.add_text(268 - tft_string.width(), MENU_TEXT_Y_OFFSET, COLOR_MENU_VALUE, tft_string); + } + #endif + + extern screenFunc_t _manual_move_func_ptr; + if (ui.currentScreen != _manual_move_func_ptr && !ui.external_control) { + + #define SLIDER_LENGHT 224 + #define SLIDER_Y_POSITION 140 + + tft.canvas((TFT_WIDTH - SLIDER_LENGHT) / 2, SLIDER_Y_POSITION, SLIDER_LENGHT, 16); + tft.set_background(COLOR_BACKGROUND); + + int16_t position = (SLIDER_LENGHT - 2) * ui.encoderPosition / maxEditValue; + tft.add_bar(0, 7, 1, 2, ui.encoderPosition == 0 ? COLOR_SLIDER_INACTIVE : COLOR_SLIDER); + tft.add_bar(1, 6, position, 4, COLOR_SLIDER); + tft.add_bar(position + 1, 6, SLIDER_LENGHT - 2 - position, 4, COLOR_SLIDER_INACTIVE); + tft.add_bar(SLIDER_LENGHT - 1, 7, 1, 2, int32_t(ui.encoderPosition) == maxEditValue ? COLOR_SLIDER : COLOR_SLIDER_INACTIVE); + + #if ENABLED(TOUCH_SCREEN) + tft.add_image((SLIDER_LENGHT - 8) * ui.encoderPosition / maxEditValue, 0, imgSlider, COLOR_SLIDER); + touch.add_control(SLIDER, (TFT_WIDTH - SLIDER_LENGHT) / 2, SLIDER_Y_POSITION - 8, SLIDER_LENGHT, 32, maxEditValue); + #endif + } + + #if ENABLED(TOUCH_SCREEN) + add_control(32, 176, DECREASE, imgDecrease); + add_control(224, 176, INCREASE, imgIncrease); + add_control(128, 176, CLICK, imgConfirm); + #endif +} + +// The Select Screen presents a prompt and two "buttons" +void MenuItem_confirm::draw_select_screen(PGM_P const yes, PGM_P const no, const bool yesno, PGM_P const pref, const char * const string/*=nullptr*/, PGM_P const suff/*=nullptr*/) { + uint16_t line = 1; + + if (string == NULL) line++; + + menu_line(line++); + tft_string.set(pref); + tft_string.trim(); + tft.add_text(tft_string.center(TFT_WIDTH), MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); + + if (string) { + menu_line(line++); + tft_string.set(string); + tft_string.trim(); + tft.add_text(tft_string.center(TFT_WIDTH), MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); + } + + if (suff) { + menu_line(line); + tft_string.set(suff); + tft_string.trim(); + tft.add_text(tft_string.center(TFT_WIDTH), MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); + } + #if ENABLED(TOUCH_SCREEN) + add_control(48, 176, CANCEL, imgCancel, true, yesno ? HALF(COLOR_CONTROL_CANCEL) : COLOR_CONTROL_CANCEL); + add_control(208, 176, CONFIRM, imgConfirm, true, yesno ? COLOR_CONTROL_CONFIRM : HALF(COLOR_CONTROL_CONFIRM)); + #endif +} + +#if ENABLED(SDSUPPORT) + void MenuItem_sdbase::draw(const bool sel, const uint8_t row, PGM_P const, CardReader &theCard, const bool isDir) { + menu_item(row, sel); + if (isDir) + tft.add_image(0, 0, imgDirectory, COLOR_MENU_TEXT, sel ? COLOR_SELECTION_BG : COLOR_BACKGROUND); + tft.add_text(32, MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, theCard.longest_filename()); + } +#endif + +#if ENABLED(ADVANCED_PAUSE_FEATURE) + void MarlinUI::draw_hotend_status(const uint8_t row, const uint8_t extruder) { + #if ENABLED(TOUCH_SCREEN) + touch.clear(); + draw_menu_navigation = false; + touch.add_control(RESUME_CONTINUE , 0, 0, 320, 240); + #endif + + menu_line(row); + tft_string.set(GET_TEXT(MSG_FILAMENT_CHANGE_NOZZLE)); + tft_string.add('E'); + tft_string.add((char)('1' + extruder)); + tft_string.add(' '); + tft_string.add(i16tostr3rj(thermalManager.degHotend(extruder))); + tft_string.add(LCD_STR_DEGREE); + tft_string.add(" / "); + tft_string.add(i16tostr3rj(thermalManager.degTargetHotend(extruder))); + tft_string.add(LCD_STR_DEGREE); + tft_string.trim(); + tft.add_text(tft_string.center(TFT_WIDTH), MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); + } +#endif // ADVANCED_PAUSE_FEATURE + +#if ENABLED(AUTO_BED_LEVELING_UBL) + #define GRID_OFFSET_X 8 + #define GRID_OFFSET_Y 8 + #define GRID_WIDTH 144 + #define GRID_HEIGHT 144 + #define CONTROL_OFFSET 8 + + void MarlinUI::ubl_plot(const uint8_t x_plot, const uint8_t y_plot) { + + tft.canvas(GRID_OFFSET_X, GRID_OFFSET_Y, GRID_WIDTH, GRID_HEIGHT); + tft.set_background(COLOR_BACKGROUND); + tft.add_rectangle(0, 0, GRID_WIDTH, GRID_HEIGHT, COLOR_WHITE); + + for (uint16_t x = 0; x < GRID_MAX_POINTS_X ; x++) + for (uint16_t y = 0; y < GRID_MAX_POINTS_Y ; y++) + if (position_is_reachable({ ubl.mesh_index_to_xpos(x), ubl.mesh_index_to_ypos(y) })) + tft.add_bar(1 + (x * 2 + 1) * (GRID_WIDTH - 4) / GRID_MAX_POINTS_X / 2, GRID_HEIGHT - 3 - ((y * 2 + 1) * (GRID_HEIGHT - 4) / GRID_MAX_POINTS_Y / 2), 2, 2, COLOR_UBL); + + tft.add_rectangle((x_plot * 2 + 1) * (GRID_WIDTH - 4) / GRID_MAX_POINTS_X / 2 - 1, GRID_HEIGHT - 5 - ((y_plot * 2 + 1) * (GRID_HEIGHT - 4) / GRID_MAX_POINTS_Y / 2), 6, 6, COLOR_UBL); + + const xy_pos_t pos = { ubl.mesh_index_to_xpos(x_plot), ubl.mesh_index_to_ypos(y_plot) }, + lpos = pos.asLogical(); + + tft.canvas(216, GRID_OFFSET_Y + (GRID_HEIGHT - 32) / 2 - 32, 96, 32); + tft.set_background(COLOR_BACKGROUND); + tft_string.set(X_LBL); + tft.add_text(0, MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); + tft_string.set(ftostr52(lpos.x)); + tft_string.trim(); + tft.add_text(96 - tft_string.width(), MENU_TEXT_Y_OFFSET, COLOR_MENU_VALUE, tft_string); + + tft.canvas(216, GRID_OFFSET_Y + (GRID_HEIGHT - 32) / 2, 96, 32); + tft.set_background(COLOR_BACKGROUND); + tft_string.set(Y_LBL); + tft.add_text(0, MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); + tft_string.set(ftostr52(lpos.y)); + tft_string.trim(); + tft.add_text(96 - tft_string.width(), MENU_TEXT_Y_OFFSET, COLOR_MENU_VALUE, tft_string); + + tft.canvas(216, GRID_OFFSET_Y + (GRID_HEIGHT - 32) / 2 + 32, 96, 32); + tft.set_background(COLOR_BACKGROUND); + tft_string.set(Z_LBL); + tft.add_text(0, MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); + tft_string.set(isnan(ubl.z_values[x_plot][y_plot]) ? "-----" : ftostr43sign(ubl.z_values[x_plot][y_plot])); + tft_string.trim(); + tft.add_text(96 - tft_string.width(), MENU_TEXT_Y_OFFSET, COLOR_MENU_VALUE, tft_string); + + + tft.canvas(GRID_OFFSET_X + (GRID_WIDTH - 32) / 2, GRID_OFFSET_Y + GRID_HEIGHT + CONTROL_OFFSET - 1, 32, 32); + tft.set_background(COLOR_BACKGROUND); + tft_string.set(ui8tostr3rj(x_plot)); + tft_string.trim(); + tft.add_text(tft_string.center(32), MENU_TEXT_Y_OFFSET, COLOR_MENU_VALUE, tft_string); + + tft.canvas(GRID_OFFSET_X + GRID_WIDTH + CONTROL_OFFSET, GRID_OFFSET_Y + (GRID_HEIGHT - 27) / 2, 32, 32); + tft.set_background(COLOR_BACKGROUND); + tft_string.set(ui8tostr3rj(y_plot)); + tft_string.trim(); + tft.add_text(tft_string.center(32), MENU_TEXT_Y_OFFSET, COLOR_MENU_VALUE, tft_string); + + #if ENABLED(TOUCH_SCREEN) + touch.clear(); + draw_menu_navigation = false; + add_control(GRID_OFFSET_X + GRID_WIDTH + CONTROL_OFFSET, GRID_OFFSET_Y + CONTROL_OFFSET, UBL, ENCODER_STEPS_PER_MENU_ITEM * GRID_MAX_POINTS_X, imgUp); + add_control(GRID_OFFSET_X + GRID_WIDTH + CONTROL_OFFSET, GRID_OFFSET_Y + GRID_HEIGHT - CONTROL_OFFSET - 32, UBL, - ENCODER_STEPS_PER_MENU_ITEM * GRID_MAX_POINTS_X, imgDown); + add_control(GRID_OFFSET_X + CONTROL_OFFSET, GRID_OFFSET_Y + GRID_HEIGHT + CONTROL_OFFSET, UBL, - ENCODER_STEPS_PER_MENU_ITEM, imgLeft); + add_control(GRID_OFFSET_X + GRID_WIDTH - CONTROL_OFFSET - 32, GRID_OFFSET_Y + GRID_HEIGHT + CONTROL_OFFSET, UBL, ENCODER_STEPS_PER_MENU_ITEM, imgRight); + add_control(224, GRID_OFFSET_Y + GRID_HEIGHT + CONTROL_OFFSET, CLICK, imgLeveling); + add_control(144, 206, BACK, imgBack); + #endif + } +#endif // AUTO_BED_LEVELING_UBL + +#if ENABLED(TOUCH_SCREEN_CALIBRATION) + void MarlinUI::touch_calibration() { + static uint16_t x, y; + + calibrationState calibration_stage = touch.get_calibration_state(); + + if (calibration_stage == CALIBRATION_NONE) { + defer_status_screen(true); + clear_lcd(); + calibration_stage = touch.calibration_start(); + } + else { + tft.canvas(x - 15, y - 15, 31, 31); + tft.set_background(COLOR_BACKGROUND); + } + + x = 20; y = 20; + touch.clear(); + + if (calibration_stage < CALIBRATION_SUCCESS) { + switch (calibration_stage) { + case CALIBRATION_POINT_1: tft_string.set("Top Left"); break; + case CALIBRATION_POINT_2: y = TFT_HEIGHT - 21; tft_string.set("Bottom Left"); break; + case CALIBRATION_POINT_3: x = TFT_WIDTH - 21; tft_string.set("Top Right"); break; + case CALIBRATION_POINT_4: x = TFT_WIDTH - 21; y = TFT_HEIGHT - 21; tft_string.set("Bottom Right"); break; + default: break; + } + + tft.canvas(x - 15, y - 15, 31, 31); + tft.set_background(COLOR_BACKGROUND); + tft.add_bar(0, 15, 31, 1, COLOR_TOUCH_CALIBRATION); + tft.add_bar(15, 0, 1, 31, COLOR_TOUCH_CALIBRATION); + + touch.add_control(CALIBRATE, 0, 0, TFT_WIDTH, TFT_HEIGHT, uint32_t(x) << 16 | uint32_t(y)); + } + else { + tft_string.set(calibration_stage == CALIBRATION_SUCCESS ? "Calibration Completed" : "Calibration Failed"); + defer_status_screen(false); + touch.calibration_end(); + touch.add_control(BACK, 0, 0, TFT_WIDTH, TFT_HEIGHT); + } + + tft.canvas(0, (TFT_HEIGHT - tft_string.font_height()) >> 1, TFT_WIDTH, tft_string.font_height()); + tft.set_background(COLOR_BACKGROUND); + tft.add_text(tft_string.center(TFT_WIDTH), 0, COLOR_MENU_TEXT, tft_string); + } +#endif // TOUCH_SCREEN_CALIBRATION + +void menu_line(const uint8_t row, uint16_t color) { + tft.canvas(0, 2 + 34 * row, TFT_WIDTH, 32); + tft.set_background(color); +} + +void menu_pause_option(); + +void menu_item(const uint8_t row, bool sel ) { + #if ENABLED(TOUCH_SCREEN) + if (row == 0) { + touch.clear(); + draw_menu_navigation = TERN(ADVANCED_PAUSE_FEATURE, ui.currentScreen != menu_pause_option, true); + } + #endif + + menu_line(row, sel ? COLOR_SELECTION_BG : COLOR_BACKGROUND); + TERN_(TOUCH_SCREEN, touch.add_control(sel ? CLICK : MENU_ITEM, 0, 2 + 34 * row, 320, 32, encoderTopLine + row)); +} + +void MarlinUI::move_axis_screen() { +} + +#endif // HAS_UI_320x240 diff --git a/Marlin/src/lcd/tft/ui_320x240.h b/Marlin/src/lcd/tft/ui_320x240.h new file mode 100644 index 000000000000..c9822f11cc69 --- /dev/null +++ b/Marlin/src/lcd/tft/ui_320x240.h @@ -0,0 +1,108 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../../inc/MarlinConfigPre.h" + +#include "tft.h" +#include "tft_image.h" + +#if ENABLED(TOUCH_SCREEN) + #include "touch.h" +#endif + +void draw_heater_status(uint16_t x, uint16_t y, const int8_t Heater); +void draw_fan_status(uint16_t x, uint16_t y, const bool blink); + +#define MENU_TEXT_X_OFFSET 10 +#define MENU_TEXT_Y_OFFSET 7 +void menu_line(const uint8_t row, uint16_t color = COLOR_BACKGROUND); +void menu_item(const uint8_t row, bool sel = false); + +#define MENU_FONT_NAME Helvetica14 +#define SYMBOLS_FONT_NAME Helvetica14_symbols + +#define ABSOLUTE_ZERO -273.15 + +const tImage Images[imgCount] = { + MarlinLogo320x240x16, + HotEnd_64x64x4, + Bed_64x64x4, + Bed_Heated_64x64x4, + Chamber_64x64x4, + Chamber_Heated_64x64x4, + Fan0_64x64x4, + Fan_Slow0_64x64x4, + Fan_Slow1_64x64x4, + Fan_Fast0_64x64x4, + Fan_Fast1_64x64x4, + Feedrate_32x32x4, + Flowrate_32x32x4, + SD_64x64x4, + Menu_64x64x4, + Settings_64x64x4, + Directory_32x32x4, + Confirm_64x64x4, + Cancel_64x64x4, + Increase_64x64x4, + Decrease_64x64x4, + Back_32x32x4, + Up_32x32x4, + Down_32x32x4, + Left_32x32x4, + Right_32x32x4, + Refresh_32x32x4, + Leveling_32x32x4, + Slider8x16x4, + Home_64x64x4, + BtnRounded_64x52x4, +}; + +#if HAS_TEMP_CHAMBER && HOTENDS > 1 + #define ITEM_E0 0 + #define ITEM_E1 1 + #define ITEM_BED 2 + #define ITEM_CHAMBER 3 + #define ITEM_FAN 4 + #define ITEMS_COUNT 5 + #define POS_Y 0 +#elif HAS_TEMP_CHAMBER + #define ITEM_E0 0 + #define ITEM_BED 1 + #define ITEM_CHAMBER 2 + #define ITEM_FAN 3 + #define ITEMS_COUNT 4 + #define POS_Y 0 +#elif HOTENDS > 1 + #define ITEM_E0 0 + #define ITEM_E1 1 + #define ITEM_BED 2 + #define ITEM_FAN 3 + #define ITEMS_COUNT 4 + #define POS_Y 0 +#else + #define ITEM_E0 0 + #define ITEM_BED 1 + #define ITEM_FAN 2 + #define ITEMS_COUNT 3 + #define POS_Y 0 +#endif diff --git a/Marlin/src/lcd/tft/ui_480x320.cpp b/Marlin/src/lcd/tft/ui_480x320.cpp new file mode 100644 index 000000000000..3dab9418f5fa --- /dev/null +++ b/Marlin/src/lcd/tft/ui_480x320.cpp @@ -0,0 +1,1068 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfigPre.h" + +#if HAS_UI_480x320 + +#include "ui_480x320.h" + +#include "../ultralcd.h" +#include "../menu/menu.h" +#include "../../libs/numtostr.h" + +#include "../../sd/cardreader.h" +#include "../../module/temperature.h" +#include "../../module/printcounter.h" +#include "../../module/planner.h" +#include "../../module/motion.h" + +#if DISABLED(LCD_PROGRESS_BAR) && BOTH(FILAMENT_LCD_DISPLAY, SDSUPPORT) + #include "../../feature/filwidth.h" + #include "../../gcode/parser.h" +#endif + +#if ENABLED(AUTO_BED_LEVELING_UBL) + #include "../../feature/bedlevel/bedlevel.h" +#endif + +#if !HAS_LCD_MENU + #error "Seriously? High resolution TFT screen without menu?" +#endif + +static bool draw_menu_navigation = false; + +void MarlinUI::tft_idle() { + #if ENABLED(TOUCH_SCREEN) + if (draw_menu_navigation) { + add_control(104, 286, PAGE_UP, imgPageUp, encoderTopLine > 0); + add_control(344, 286, PAGE_DOWN, imgPageDown, encoderTopLine + LCD_HEIGHT < screen_items); + add_control(224, 286, BACK, imgBack); + draw_menu_navigation = false; + } + #endif + + tft.queue.async(); + TERN_(TOUCH_SCREEN, touch.idle()); +} + +void MarlinUI::init_lcd() { + tft.init(); + tft.set_font(MENU_FONT_NAME); + #ifdef SYMBOLS_FONT_NAME + tft.add_glyphs(SYMBOLS_FONT_NAME); + #endif + TERN_(TOUCH_SCREEN, touch.init()); + clear_lcd(); +} + +bool MarlinUI::detected() { return true; } + +void MarlinUI::clear_lcd() { + #if ENABLED(TOUCH_SCREEN) + touch.reset(); + draw_menu_navigation = false; + #endif + + tft.queue.reset(); + tft.fill(0, 0, TFT_WIDTH, TFT_HEIGHT, COLOR_BACKGROUND); +} + +#if ENABLED(SHOW_BOOTSCREEN) + #ifndef BOOTSCREEN_TIMEOUT + #define BOOTSCREEN_TIMEOUT 1500 + #endif + + #undef BOOTSCREEN_TIMEOUT + #define BOOTSCREEN_TIMEOUT 5000 + + void MarlinUI::show_bootscreen() { + tft.queue.reset(); + + tft.canvas(0, 0, TFT_WIDTH, TFT_HEIGHT); + tft.set_background(COLOR_BACKGROUND); + tft.add_image(142, 130, imgBootScreen); // MarlinLogo195x59x16 + + #ifdef WEBSITE_URL + tft.add_text(8, 250, COLOR_WEBSITE_URL, WEBSITE_URL); + #endif + + tft.queue.sync(); + safe_delay(BOOTSCREEN_TIMEOUT); + clear_lcd(); + } +#endif // SHOW_BOOTSCREEN + +void MarlinUI::draw_kill_screen() { + tft.queue.reset(); + tft.fill(0, 0, TFT_WIDTH, TFT_HEIGHT, COLOR_KILL_SCREEN_BG); + + uint16_t line = 2; + + menu_line(line++, COLOR_KILL_SCREEN_BG); + tft_string.set(status_message); + tft_string.trim(); + tft.add_text(tft_string.center(TFT_WIDTH), 0, COLOR_MENU_TEXT, tft_string); + + line++; + menu_line(line++, COLOR_KILL_SCREEN_BG); + tft_string.set(GET_TEXT(MSG_HALTED)); + tft_string.trim(); + tft.add_text(tft_string.center(TFT_WIDTH), 0, COLOR_MENU_TEXT, tft_string); + + menu_line(line++, COLOR_KILL_SCREEN_BG); + tft_string.set(GET_TEXT(MSG_PLEASE_RESET)); + tft_string.trim(); + tft.add_text(tft_string.center(TFT_WIDTH), 0, COLOR_MENU_TEXT, tft_string); + + tft.queue.sync(); +} + +void draw_heater_status(uint16_t x, uint16_t y, const int8_t Heater) { + MarlinImage image = imgHotEnd; + uint16_t Color; + float currentTemperature, targetTemperature; + + if (Heater >= 0) { // HotEnd + currentTemperature = thermalManager.degHotend(Heater); + targetTemperature = thermalManager.degTargetHotend(Heater); + } +#if HAS_HEATED_BED + else if (Heater == H_BED) { + currentTemperature = thermalManager.degBed(); + targetTemperature = thermalManager.degTargetBed(); + } +#endif // HAS_HEATED_BED +#if HAS_TEMP_CHAMBER + else if (Heater == H_CHAMBER) { + currentTemperature = thermalManager.degChamber(); + #if HAS_HEATED_CHAMBER + targetTemperature = thermalManager.degTargetChamber(); + #else + targetTemperature = ABSOLUTE_ZERO; + #endif + } +#endif // HAS_TEMP_CHAMBER + else return; + + TERN_(TOUCH_SCREEN, if (targetTemperature >= 0) touch.add_control(HEATER, x, y, 80, 120, Heater)); + tft.canvas(x, y, 80, 120); + tft.set_background(COLOR_BACKGROUND); + + Color = currentTemperature < 0 ? COLOR_INACTIVE : COLOR_COLD; + + if (Heater >= 0) { // HotEnd + if (currentTemperature >= 50) Color = COLOR_HOTEND; + } + #if HAS_HEATED_BED + else if (Heater == H_BED) { + if (currentTemperature >= 50) Color = COLOR_HEATED_BED; + image = targetTemperature > 0 ? imgBedHeated : imgBed; + } + #endif // HAS_HEATED_BED + #if HAS_TEMP_CHAMBER + else if (Heater == H_CHAMBER) { + if (currentTemperature >= 50) Color = COLOR_CHAMBER; + image = targetTemperature > 0 ? imgChamberHeated : imgChamber; + } + #endif // HAS_TEMP_CHAMBER + + tft.add_image(8, 28, image, Color); + + tft_string.set((uint8_t *)i16tostr3rj(currentTemperature + 0.5)); + tft_string.add(LCD_STR_DEGREE); + tft_string.trim(); + tft.add_text(tft_string.center(80) + 2, 82, Color, tft_string); + + if (targetTemperature >= 0) { + tft_string.set((uint8_t *)i16tostr3rj(targetTemperature + 0.5)); + tft_string.add(LCD_STR_DEGREE); + tft_string.trim(); + tft.add_text(tft_string.center(80) + 2, 8, Color, tft_string); + } +} + +void draw_fan_status(uint16_t x, uint16_t y, const bool blink) { + TERN_(TOUCH_SCREEN, touch.add_control(FAN, x, y, 80, 120)); + tft.canvas(x, y, 80, 120); + tft.set_background(COLOR_BACKGROUND); + + uint8_t fanSpeed = thermalManager.fan_speed[0]; + MarlinImage image; + + if (fanSpeed >= 127) + image = blink ? imgFanFast1 : imgFanFast0; + else if (fanSpeed > 0) + image = blink ? imgFanSlow1 : imgFanSlow0; + else + image = imgFanIdle; + + tft.add_image(8, 20, image, COLOR_FAN); + + tft_string.set((uint8_t *)ui8tostr4pctrj(thermalManager.fan_speed[0])); + tft_string.trim(); + tft.add_text(tft_string.center(80) + 6, 82, COLOR_FAN, tft_string); +} + +void MarlinUI::draw_status_screen() { + const bool blink = get_blink(); + + TERN_(TOUCH_SCREEN, touch.clear()); + + // heaters and fan + uint16_t i, x, y = POS_Y; + + for (i = 0 ; i < ITEMS_COUNT; i++) { + x = (TFT_WIDTH / ITEMS_COUNT - 80) / 2 + (TFT_WIDTH * i / ITEMS_COUNT); + switch (i) { + #ifdef ITEM_E0 + case ITEM_E0: draw_heater_status(x, y, H_E0); break; + #endif + #ifdef ITEM_E1 + case ITEM_E1: draw_heater_status(x, y, H_E1); break; + #endif + #ifdef ITEM_E2 + case ITEM_E2: draw_heater_status(x, y, H_E2); break; + #endif + #ifdef ITEM_BED + case ITEM_BED: draw_heater_status(x, y, H_BED); break; + #endif + #ifdef ITEM_CHAMBER + case ITEM_CHAMBER: draw_heater_status(x, y, H_CHAMBER); break; + #endif + #ifdef ITEM_FAN + case ITEM_FAN: draw_fan_status(x, y, blink); break; + #endif + } + } + + // coordinates + tft.canvas(4, 132, TFT_WIDTH - 8, 34); + tft.set_background(COLOR_BACKGROUND); + tft.add_rectangle(0, 0, TFT_WIDTH - 8, 34, COLOR_AXIS_HOMED); + + uint16_t color; + uint16_t offset; + bool is_homed; + + tft.add_text( 16, 3, COLOR_AXIS_HOMED , "X"); + tft.add_text(192, 3, COLOR_AXIS_HOMED , "Y"); + tft.add_text(330, 3, COLOR_AXIS_HOMED , "Z"); + + is_homed = TEST(axis_homed, X_AXIS); + tft_string.set(blink & !is_homed ? "?" : ftostr4sign(LOGICAL_X_POSITION(current_position.x))); + tft.add_text(102 - tft_string.width(), 3, is_homed ? COLOR_AXIS_HOMED : COLOR_AXIS_NOT_HOMED, tft_string); + + is_homed = TEST(axis_homed, Y_AXIS); + tft_string.set(blink & !is_homed ? "?" : ftostr4sign(LOGICAL_Y_POSITION(current_position.y))); + tft.add_text(280 - tft_string.width(), 3, is_homed ? COLOR_AXIS_HOMED : COLOR_AXIS_NOT_HOMED, tft_string); + + is_homed = TEST(axis_homed, Z_AXIS); + if (blink & !is_homed) { + tft_string.set("?"); + offset = 32; // ".00" + } + else { + const float z = LOGICAL_Z_POSITION(current_position.z); + tft_string.set(ftostr52sp((int16_t)z)); + tft_string.rtrim(); + offset = tft_string.width(); + + tft_string.set(ftostr52sp(z)); + offset += 32 - tft_string.width(); + } + tft.add_text(455 - tft_string.width() - offset, 3, is_homed ? COLOR_AXIS_HOMED : COLOR_AXIS_NOT_HOMED, tft_string); + TERN_(TOUCH_SCREEN, touch.add_control(MOVE_AXIS, 4, 132, TFT_WIDTH - 8, 34)); + + // feed rate + tft.canvas(96, 180, 100, 32); + tft.set_background(COLOR_BACKGROUND); + color = feedrate_percentage == 100 ? COLOR_RATE_100 : COLOR_RATE_ALTERED; + tft.add_image(0, 0, imgFeedRate, color); + tft_string.set(i16tostr3rj(feedrate_percentage)); + tft_string.add('%'); + tft.add_text(36, 1, color , tft_string); + TERN_(TOUCH_SCREEN, touch.add_control(FEEDRATE, 96, 176, 100, 32)); + + // flow rate + tft.canvas(284, 180, 100, 32); + tft.set_background(COLOR_BACKGROUND); + color = planner.flow_percentage[0] == 100 ? COLOR_RATE_100 : COLOR_RATE_ALTERED; + tft.add_image(0, 0, imgFlowRate, color); + tft_string.set(i16tostr3rj(planner.flow_percentage[active_extruder])); + tft_string.add('%'); + tft.add_text(36, 1, color , tft_string); + TERN_(TOUCH_SCREEN, touch.add_control(FLOWRATE, 284, 176, 100, 32, active_extruder)); + + // print duration + char buffer[14]; + duration_t elapsed = print_job_timer.duration(); + elapsed.toDigital(buffer); + + tft.canvas((TFT_WIDTH - 128) / 2, 224, 128, 29); + tft.set_background(COLOR_BACKGROUND); + tft_string.set(buffer); + tft.add_text(tft_string.center(128), 0, COLOR_PRINT_TIME, tft_string); + + // progress bar + const uint8_t progress = ui.get_progress_percent(); + tft.canvas(4, 260, TFT_WIDTH - 8, 9); + tft.set_background(COLOR_PROGRESS_BG); + tft.add_rectangle(0, 0, TFT_WIDTH - 8, 9, COLOR_PROGRESS_FRAME); + if (progress) + tft.add_bar(1, 1, ((TFT_WIDTH - 10) * progress) / 100, 7, COLOR_PROGRESS_BAR); + + // status message + tft.canvas(0, 280, TFT_WIDTH, 29); + tft.set_background(COLOR_BACKGROUND); + tft_string.set(status_message); + tft_string.trim(); + tft.add_text(tft_string.center(TFT_WIDTH), 0, COLOR_STATUS_MESSAGE, tft_string); + + + #if ENABLED(TOUCH_SCREEN) + add_control(404, 180, menu_main, imgSettings); + TERN_(SDSUPPORT, add_control(12, 180, menu_media, imgSD, card.isMounted() && !printingIsActive(), COLOR_CONTROL_ENABLED, card.isMounted() && printingIsActive() ? COLOR_BUSY : COLOR_CONTROL_DISABLED)); + #endif +} + +// Draw a static item with no left-right margin required. Centered by default. +void MenuItem_static::draw(const uint8_t row, PGM_P const pstr, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) { + menu_item(row); + tft_string.set(pstr, itemIndex, itemString); + if (vstr) + tft_string.add(vstr); + tft.add_text(tft_string.center(TFT_WIDTH), MENU_TEXT_Y_OFFSET, COLOR_YELLOW, tft_string); +} + +// Draw a generic menu item with pre_char (if selected) and post_char +void MenuItemBase::_draw(const bool sel, const uint8_t row, PGM_P const pstr, const char pre_char, const char post_char) { + menu_item(row, sel); + + uint8_t *string = (uint8_t *)pstr; + MarlinImage image = noImage; + switch (*string) { + case 0x01: image = imgRefresh; break; // LCD_STR_REFRESH + case 0x02: image = imgDirectory; break; // LCD_STR_FOLDER + } + + uint8_t offset = MENU_TEXT_X_OFFSET; + if (image != noImage) { + string++; + offset = 42; + tft.add_image(5, 5, image, COLOR_MENU_TEXT, sel ? COLOR_SELECTION_BG : COLOR_BACKGROUND); + } + + tft_string.set(string, itemIndex, itemString); + tft.add_text(offset, MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); +} + +// Draw a menu item with a (potentially) editable value +void MenuEditItemBase::draw(const bool sel, const uint8_t row, PGM_P const pstr, const char* const data, const bool pgm) { + menu_item(row, sel); + + tft_string.set(pstr, itemIndex, itemString); + tft.add_text(MENU_TEXT_X_OFFSET, MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); + if (data) { + tft_string.set(data); + tft.add_text(TFT_WIDTH - MENU_TEXT_X_OFFSET - tft_string.width(), MENU_TEXT_Y_OFFSET, COLOR_MENU_VALUE, tft_string); + } +} + +// Low-level draw_edit_screen can be used to draw an edit screen from anyplace +void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char* const value/*=nullptr*/) { + ui.encoder_direction_normal(); + TERN_(TOUCH_SCREEN, touch.clear()); + + uint16_t line = 1; + + menu_line(line++); + tft_string.set(pstr, itemIndex, itemString); + tft_string.trim(); + tft.add_text(tft_string.center(TFT_WIDTH), MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); + + TERN_(AUTO_BED_LEVELING_UBL, if (ui.external_control) line++); // ftostr52() will overwrite *value so *value has to be displayed first + + menu_line(line); + tft_string.set(value); + tft_string.trim(); + tft.add_text(tft_string.center(TFT_WIDTH), MENU_TEXT_Y_OFFSET, COLOR_MENU_VALUE, tft_string); + + #if ENABLED(AUTO_BED_LEVELING_UBL) + if (ui.external_control) { + menu_line(line - 1); + + tft_string.set(X_LBL); + tft.add_text((TFT_WIDTH / 2 - 120), MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); + tft_string.set(ftostr52(LOGICAL_X_POSITION(current_position.x))); + tft_string.trim(); + tft.add_text((TFT_WIDTH / 2 - 16) - tft_string.width(), MENU_TEXT_Y_OFFSET, COLOR_MENU_VALUE, tft_string); + + tft_string.set(Y_LBL); + tft.add_text((TFT_WIDTH / 2 + 16), MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); + tft_string.set(ftostr52(LOGICAL_X_POSITION(current_position.y))); + tft_string.trim(); + tft.add_text((TFT_WIDTH / 2 + 120) - tft_string.width(), MENU_TEXT_Y_OFFSET, COLOR_MENU_VALUE, tft_string); + } + #endif + + extern screenFunc_t _manual_move_func_ptr; + if (ui.currentScreen != _manual_move_func_ptr && !ui.external_control) { + + #define SLIDER_LENGHT 336 + #define SLIDER_Y_POSITION 186 + + tft.canvas((TFT_WIDTH - SLIDER_LENGHT) / 2, SLIDER_Y_POSITION, SLIDER_LENGHT, 16); + tft.set_background(COLOR_BACKGROUND); + + int16_t position = (SLIDER_LENGHT - 2) * ui.encoderPosition / maxEditValue; + tft.add_bar(0, 7, 1, 2, ui.encoderPosition == 0 ? COLOR_SLIDER_INACTIVE : COLOR_SLIDER); + tft.add_bar(1, 6, position, 4, COLOR_SLIDER); + tft.add_bar(position + 1, 6, SLIDER_LENGHT - 2 - position, 4, COLOR_SLIDER_INACTIVE); + tft.add_bar(SLIDER_LENGHT - 1, 7, 1, 2, int32_t(ui.encoderPosition) == maxEditValue ? COLOR_SLIDER : COLOR_SLIDER_INACTIVE); + + #if ENABLED(TOUCH_SCREEN) + tft.add_image((SLIDER_LENGHT - 8) * ui.encoderPosition / maxEditValue, 0, imgSlider, COLOR_SLIDER); + touch.add_control(SLIDER, (TFT_WIDTH - SLIDER_LENGHT) / 2, SLIDER_Y_POSITION - 8, SLIDER_LENGHT, 32, maxEditValue); + #endif + } + + #if ENABLED(TOUCH_SCREEN) + add_control(64, 256, DECREASE, imgDecrease); + add_control(352, 256, INCREASE, imgIncrease); + add_control(208, 256, CLICK, imgConfirm); + #endif +} + +// The Select Screen presents a prompt and two "buttons" +void MenuItem_confirm::draw_select_screen(PGM_P const yes, PGM_P const no, const bool yesno, PGM_P const pref, const char * const string/*=nullptr*/, PGM_P const suff/*=nullptr*/) { + uint16_t line = 1; + + if (string == NULL) line++; + + menu_line(line++); + tft_string.set(pref); + tft_string.trim(); + tft.add_text(tft_string.center(TFT_WIDTH), 0, COLOR_MENU_TEXT, tft_string); + + if (string) { + menu_line(line++); + tft_string.set(string); + tft_string.trim(); + tft.add_text(tft_string.center(TFT_WIDTH), 0, COLOR_MENU_TEXT, tft_string); + } + + if (suff) { + menu_line(line); + tft_string.set(suff); + tft_string.trim(); + tft.add_text(tft_string.center(TFT_WIDTH), 0, COLOR_MENU_TEXT, tft_string); + } + #if ENABLED(TOUCH_SCREEN) + add_control(88, 256, CANCEL, imgCancel, true, yesno ? HALF(COLOR_CONTROL_CANCEL) : COLOR_CONTROL_CANCEL); + add_control(328, 256, CONFIRM, imgConfirm, true, yesno ? COLOR_CONTROL_CONFIRM : HALF(COLOR_CONTROL_CONFIRM)); + #endif +} + +#if ENABLED(SDSUPPORT) + void MenuItem_sdbase::draw(const bool sel, const uint8_t row, PGM_P const, CardReader &theCard, const bool isDir) { + menu_item(row, sel); + if (isDir) + tft.add_image(5, 5, imgDirectory, COLOR_MENU_TEXT, sel ? COLOR_SELECTION_BG : COLOR_BACKGROUND); + tft.add_text(42, MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, theCard.longest_filename()); + } +#endif + +#if ENABLED(ADVANCED_PAUSE_FEATURE) + void MarlinUI::draw_hotend_status(const uint8_t row, const uint8_t extruder) { + #if ENABLED(TOUCH_SCREEN) + touch.clear(); + draw_menu_navigation = false; + touch.add_control(RESUME_CONTINUE , 0, 0, TFT_WIDTH, TFT_HEIGHT); + #endif + + menu_line(row); + tft_string.set(GET_TEXT(MSG_FILAMENT_CHANGE_NOZZLE)); + tft_string.add('E'); + tft_string.add((char)('1' + extruder)); + tft_string.add(' '); + tft_string.add(i16tostr3rj(thermalManager.degHotend(extruder))); + tft_string.add(LCD_STR_DEGREE); + tft_string.add(" / "); + tft_string.add(i16tostr3rj(thermalManager.degTargetHotend(extruder))); + tft_string.add(LCD_STR_DEGREE); + tft_string.trim(); + tft.add_text(tft_string.center(TFT_WIDTH), 0, COLOR_MENU_TEXT, tft_string); + } +#endif // ADVANCED_PAUSE_FEATURE + +#if ENABLED(AUTO_BED_LEVELING_UBL) + #define GRID_OFFSET_X 8 + #define GRID_OFFSET_Y 8 + #define GRID_WIDTH 192 + #define GRID_HEIGHT 192 + #define CONTROL_OFFSET 16 + + void MarlinUI::ubl_plot(const uint8_t x_plot, const uint8_t y_plot) { + + tft.canvas(GRID_OFFSET_X, GRID_OFFSET_Y, GRID_WIDTH, GRID_HEIGHT); + tft.set_background(COLOR_BACKGROUND); + tft.add_rectangle(0, 0, GRID_WIDTH, GRID_HEIGHT, COLOR_WHITE); + + for (uint16_t x = 0; x < GRID_MAX_POINTS_X ; x++) + for (uint16_t y = 0; y < GRID_MAX_POINTS_Y ; y++) + if (position_is_reachable({ ubl.mesh_index_to_xpos(x), ubl.mesh_index_to_ypos(y) })) + tft.add_bar(1 + (x * 2 + 1) * (GRID_WIDTH - 4) / GRID_MAX_POINTS_X / 2, GRID_HEIGHT - 3 - ((y * 2 + 1) * (GRID_HEIGHT - 4) / GRID_MAX_POINTS_Y / 2), 2, 2, COLOR_UBL); + + tft.add_rectangle((x_plot * 2 + 1) * (GRID_WIDTH - 4) / GRID_MAX_POINTS_X / 2 - 1, GRID_HEIGHT - 5 - ((y_plot * 2 + 1) * (GRID_HEIGHT - 4) / GRID_MAX_POINTS_Y / 2), 6, 6, COLOR_UBL); + + const xy_pos_t pos = { ubl.mesh_index_to_xpos(x_plot), ubl.mesh_index_to_ypos(y_plot) }, + lpos = pos.asLogical(); + + tft.canvas(320, GRID_OFFSET_Y + (GRID_HEIGHT - 43) / 2 - 43, 120, 43); + tft.set_background(COLOR_BACKGROUND); + tft_string.set(X_LBL); + tft.add_text(0, MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); + tft_string.set(ftostr52(lpos.x)); + tft_string.trim(); + tft.add_text(120 - tft_string.width(), MENU_TEXT_Y_OFFSET, COLOR_MENU_VALUE, tft_string); + + tft.canvas(320, GRID_OFFSET_Y + (GRID_HEIGHT - 43) / 2, 120, 43); + tft.set_background(COLOR_BACKGROUND); + tft_string.set(Y_LBL); + tft.add_text(0, MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); + tft_string.set(ftostr52(lpos.y)); + tft_string.trim(); + tft.add_text(120 - tft_string.width(), MENU_TEXT_Y_OFFSET, COLOR_MENU_VALUE, tft_string); + + tft.canvas(320, GRID_OFFSET_Y + (GRID_HEIGHT - 43) / 2 + 43, 120, 43); + tft.set_background(COLOR_BACKGROUND); + tft_string.set(Z_LBL); + tft.add_text(0, MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); + tft_string.set(isnan(ubl.z_values[x_plot][y_plot]) ? "-----" : ftostr43sign(ubl.z_values[x_plot][y_plot])); + tft_string.trim(); + tft.add_text(120 - tft_string.width(), MENU_TEXT_Y_OFFSET, COLOR_MENU_VALUE, tft_string); + + + tft.canvas(GRID_OFFSET_X + (GRID_WIDTH - 48) / 2, GRID_OFFSET_Y + GRID_HEIGHT + CONTROL_OFFSET - 5, 48, 43); + tft.set_background(COLOR_BACKGROUND); + tft_string.set(ui8tostr3rj(x_plot)); + tft_string.trim(); + tft.add_text(tft_string.center(48), MENU_TEXT_Y_OFFSET, COLOR_MENU_VALUE, tft_string); + + tft.canvas(GRID_OFFSET_X + GRID_WIDTH + CONTROL_OFFSET + 16 - 24, GRID_OFFSET_Y + (GRID_HEIGHT - 43) / 2, 48, 43); + tft.set_background(COLOR_BACKGROUND); + tft_string.set(ui8tostr3rj(y_plot)); + tft_string.trim(); + tft.add_text(tft_string.center(48), MENU_TEXT_Y_OFFSET, COLOR_MENU_VALUE, tft_string); + + #if ENABLED(TOUCH_SCREEN) + touch.clear(); + draw_menu_navigation = false; + add_control(GRID_OFFSET_X + GRID_WIDTH + CONTROL_OFFSET, GRID_OFFSET_Y + CONTROL_OFFSET, UBL, ENCODER_STEPS_PER_MENU_ITEM * GRID_MAX_POINTS_X, imgUp); + add_control(GRID_OFFSET_X + GRID_WIDTH + CONTROL_OFFSET, GRID_OFFSET_Y + GRID_HEIGHT - CONTROL_OFFSET - 32, UBL, - ENCODER_STEPS_PER_MENU_ITEM * GRID_MAX_POINTS_X, imgDown); + add_control(GRID_OFFSET_X + CONTROL_OFFSET, GRID_OFFSET_Y + GRID_HEIGHT + CONTROL_OFFSET, UBL, - ENCODER_STEPS_PER_MENU_ITEM, imgLeft); + add_control(GRID_OFFSET_X + GRID_WIDTH - CONTROL_OFFSET - 32, GRID_OFFSET_Y + GRID_HEIGHT + CONTROL_OFFSET, UBL, ENCODER_STEPS_PER_MENU_ITEM, imgRight); + add_control(320, GRID_OFFSET_Y + GRID_HEIGHT + CONTROL_OFFSET, CLICK, imgLeveling); + add_control(224, 286, BACK, imgBack); + #endif + } +#endif // AUTO_BED_LEVELING_UBL + +#if ENABLED(TOUCH_SCREEN_CALIBRATION) + void MarlinUI::touch_calibration() { + static uint16_t x, y; + + calibrationState calibration_stage = touch.get_calibration_state(); + + if (calibration_stage == CALIBRATION_NONE) { + defer_status_screen(true); + clear_lcd(); + calibration_stage = touch.calibration_start(); + } + else { + tft.canvas(x - 15, y - 15, 31, 31); + tft.set_background(COLOR_BACKGROUND); + } + + x = 20; y = 20; + touch.clear(); + + if (calibration_stage < CALIBRATION_SUCCESS) { + switch (calibration_stage) { + case CALIBRATION_POINT_1: tft_string.set("Top Left"); break; + case CALIBRATION_POINT_2: y = TFT_HEIGHT - 21; tft_string.set("Bottom Left"); break; + case CALIBRATION_POINT_3: x = TFT_WIDTH - 21; tft_string.set("Top Right"); break; + case CALIBRATION_POINT_4: x = TFT_WIDTH - 21; y = TFT_HEIGHT - 21; tft_string.set("Bottom Right"); break; + default: break; + } + + tft.canvas(x - 15, y - 15, 31, 31); + tft.set_background(COLOR_BACKGROUND); + tft.add_bar(0, 15, 31, 1, COLOR_TOUCH_CALIBRATION); + tft.add_bar(15, 0, 1, 31, COLOR_TOUCH_CALIBRATION); + + touch.add_control(CALIBRATE, 0, 0, TFT_WIDTH, TFT_HEIGHT, uint32_t(x) << 16 | uint32_t(y)); + } + else { + tft_string.set(calibration_stage == CALIBRATION_SUCCESS ? "Calibration Completed" : "Calibration Failed"); + defer_status_screen(false); + touch.calibration_end(); + touch.add_control(BACK, 0, 0, TFT_WIDTH, TFT_HEIGHT); + } + + tft.canvas(0, (TFT_HEIGHT - tft_string.font_height()) >> 1, TFT_WIDTH, tft_string.font_height()); + tft.set_background(COLOR_BACKGROUND); + tft.add_text(tft_string.center(TFT_WIDTH), 0, COLOR_MENU_TEXT, tft_string); + } +#endif // TOUCH_SCREEN_CALIBRATION + +void menu_line(const uint8_t row, uint16_t color) { + tft.canvas(0, 4 + 45 * row, TFT_WIDTH, 43); + tft.set_background(color); +} + +void menu_pause_option(); + +void menu_item(const uint8_t row, bool sel ) { + #if ENABLED(TOUCH_SCREEN) + if (row == 0) { + touch.clear(); + draw_menu_navigation = TERN(ADVANCED_PAUSE_FEATURE, ui.currentScreen != menu_pause_option, true); + } + #endif + + menu_line(row, sel ? COLOR_SELECTION_BG : COLOR_BACKGROUND); + TERN_(TOUCH_SCREEN, touch.add_control(sel ? CLICK : MENU_ITEM, 0, 4 + 45 * row, TFT_WIDTH, 43, encoderTopLine + row)); +} + +#if ENABLED(BABYSTEP_ZPROBE_OFFSET) + #include "../../feature/babystep.h" +#endif + +#if HAS_BED_PROBE + #include "../../module/probe.h" +#endif + +#define Z_SELECTION_Z 1 +#define Z_SELECTION_Z_PROBE -1 + +struct MotionAxisState { + xy_int_t xValuePos, yValuePos, zValuePos, eValuePos, stepValuePos, zTypePos, eNamePos; + float currentStepSize = 10.0; + int z_selection = Z_SELECTION_Z; + uint8_t e_selection = 0; + bool homming = false; + bool blocked = false; + char message[32]; +}; + +MotionAxisState motionAxisState; + +#define E_BTN_COLOR COLOR_YELLOW +#define X_BTN_COLOR COLOR_CORAL_RED +#define Y_BTN_COLOR COLOR_VIVID_GREEN +#define Z_BTN_COLOR COLOR_LIGHT_BLUE + +#define BTN_WIDTH 64 +#define BTN_HEIGHT 52 +#define X_MARGIN 20 +#define Y_MARGIN 15 + +static void quick_feedback() { + #if HAS_CHIRP + ui.chirp(); // Buzz and wait. Is the delay needed for buttons to settle? + #if BOTH(HAS_LCD_MENU, USE_BEEPER) + for (int8_t i = 5; i--;) { buzzer.tick(); delay(2); } + #elif HAS_LCD_MENU + delay(10); + #endif + #endif +} + +#define CUR_STEP_VALUE_WIDTH 104 +static void drawCurStepValue() { + tft_string.set((uint8_t *)ftostr52sp(motionAxisState.currentStepSize)); + tft_string.add("mm"); + tft.canvas(motionAxisState.stepValuePos.x, motionAxisState.stepValuePos.y, CUR_STEP_VALUE_WIDTH, BTN_HEIGHT); + tft.set_background(COLOR_BACKGROUND); + tft.add_text(tft_string.center(CUR_STEP_VALUE_WIDTH), 0, COLOR_AXIS_HOMED, tft_string); +} + +static void drawCurZSelection() { + tft_string.set("Z"); + tft.canvas(motionAxisState.zTypePos.x, motionAxisState.zTypePos.y, tft_string.width(), 34); + tft.set_background(COLOR_BACKGROUND); + tft.add_text(0, 0, Z_BTN_COLOR, tft_string); + tft.queue.sync(); + tft_string.set("Offset"); + tft.canvas(motionAxisState.zTypePos.x, motionAxisState.zTypePos.y + 34, tft_string.width(), 34); + tft.set_background(COLOR_BACKGROUND); + if (motionAxisState.z_selection == Z_SELECTION_Z_PROBE) { + tft.add_text(0, 0, Z_BTN_COLOR, tft_string); + } +} + +static void drawCurESelection() { + tft.canvas(motionAxisState.eNamePos.x, motionAxisState.eNamePos.y, BTN_WIDTH, BTN_HEIGHT); + tft.set_background(COLOR_BACKGROUND); + tft_string.set("E"); + tft.add_text(0, 0, E_BTN_COLOR , tft_string); + tft.add_text(tft_string.width(), 0, E_BTN_COLOR, ui8tostr3rj(motionAxisState.e_selection)); +} + +static void drawMessage(const char *msg) { + tft.canvas(X_MARGIN, TFT_HEIGHT - Y_MARGIN - 34, TFT_HEIGHT / 2, 34); + tft.set_background(COLOR_BACKGROUND); + tft.add_text(0, 0, COLOR_YELLOW, msg); +} + +static void drawAxisValue(AxisEnum axis) { + const float value = + #if HAS_BED_PROBE + axis == Z_AXIS && motionAxisState.z_selection == Z_SELECTION_Z_PROBE ? + probe.offset.z : + #endif + NATIVE_TO_LOGICAL( + ui.manual_move.processing ? destination[axis] : current_position[axis] + TERN0(IS_KINEMATIC, ui.manual_move.offset), + axis + ); + xy_int_t pos; + uint16_t color; + switch (axis) { + case X_AXIS: pos = motionAxisState.xValuePos; color = X_BTN_COLOR; break; + case Y_AXIS: pos = motionAxisState.yValuePos; color = Y_BTN_COLOR; break; + case Z_AXIS: pos = motionAxisState.zValuePos; color = Z_BTN_COLOR; break; + case E_AXIS: pos = motionAxisState.eValuePos; color = E_BTN_COLOR; break; + default: return; + } + tft.canvas(pos.x, pos.y, BTN_WIDTH + X_MARGIN, BTN_HEIGHT); + tft.set_background(COLOR_BACKGROUND); + tft_string.set(ftostr52sp(value)); + tft.add_text(0, 0, color, tft_string); +} + +static void moveAxis(AxisEnum axis, const int8_t direction) { + quick_feedback(); + + if (axis == E_AXIS && thermalManager.temp_hotend[motionAxisState.e_selection].celsius < EXTRUDE_MINTEMP) { + drawMessage("Too cold"); + return; + } + + const float diff = motionAxisState.currentStepSize * direction; + + if (axis == Z_AXIS && motionAxisState.z_selection == Z_SELECTION_Z_PROBE) { + #if ENABLED(BABYSTEP_ZPROBE_OFFSET) + const int16_t babystep_increment = direction * BABYSTEP_SIZE_Z; + const bool do_probe = DISABLED(BABYSTEP_HOTEND_Z_OFFSET) || active_extruder == 0; + const float bsDiff = planner.steps_to_mm[Z_AXIS] * babystep_increment, + new_probe_offset = probe.offset.z + bsDiff, + new_offs = TERN(BABYSTEP_HOTEND_Z_OFFSET + , do_probe ? new_probe_offset : hotend_offset[active_extruder].z - bsDiff + , new_probe_offset + ); + if (WITHIN(new_offs, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX)) { + babystep.add_steps(Z_AXIS, babystep_increment); + if (do_probe) + probe.offset.z = new_offs; + else + TERN(BABYSTEP_HOTEND_Z_OFFSET, hotend_offset[active_extruder].z = new_offs, NOOP); + drawMessage(""); // clear the error + drawAxisValue(axis); + } + else { + drawMessage(GET_TEXT(MSG_LCD_SOFT_ENDSTOPS)); + } + #elif HAS_BED_PROBE + // only change probe.offset.z + probe.offset.z += diff; + if (direction < 0 && current_position[axis] < Z_PROBE_OFFSET_RANGE_MIN) { + current_position[axis] = Z_PROBE_OFFSET_RANGE_MIN; + drawMessage(GET_TEXT(MSG_LCD_SOFT_ENDSTOPS)); + } + else if (direction > 0 && current_position[axis] > Z_PROBE_OFFSET_RANGE_MAX) { + current_position[axis] = Z_PROBE_OFFSET_RANGE_MAX; + drawMessage(GET_TEXT(MSG_LCD_SOFT_ENDSTOPS)); + } + else { + drawMessage(""); // clear the error + } + drawAxisValue(axis); + #endif + return; + } + + if (!ui.manual_move.processing) { + // Get motion limit from software endstops, if any + float min, max; + soft_endstop.get_manual_axis_limits(axis, min, max); + + // Delta limits XY based on the current offset from center + // This assumes the center is 0,0 + #if ENABLED(DELTA) + if (axis != Z_AXIS && axis != E_AXIS) { + max = SQRT(sq((float)(DELTA_PRINTABLE_RADIUS)) - sq(current_position[Y_AXIS - axis])); // (Y_AXIS - axis) == the other axis + min = -max; + } + #endif + + // Get the new position + #if IS_KINEMATIC + ui.manual_move.offset += diff; + if (direction < 0) + NOLESS(ui.manual_move.offset, min - current_position[axis]); + else + NOMORE(ui.manual_move.offset, max - current_position[axis]); + #else + current_position[axis] += diff; + if (direction < 0 && current_position[axis] < min) { + current_position[axis] = min; + drawMessage(GET_TEXT(MSG_LCD_SOFT_ENDSTOPS)); + } + else if (direction > 0 && current_position[axis] > max) { + current_position[axis] = max; + drawMessage(GET_TEXT(MSG_LCD_SOFT_ENDSTOPS)); + } + else { + drawMessage(""); // clear the error + } + #endif + + ui.manual_move.soon(axis + #if MULTI_MANUAL + , motionAxisState.e_selection + #endif + ); + } + + drawAxisValue(axis); +} + +static void e_plus() { + moveAxis(E_AXIS, 1); +} + +static void e_minus() { + moveAxis(E_AXIS, -1); +} + +static void x_minus() { + moveAxis(X_AXIS, -1); +} + +static void x_plus() { + moveAxis(X_AXIS, 1); +} + +static void y_plus() { + moveAxis(Y_AXIS, 1); +} + +static void y_minus() { + moveAxis(Y_AXIS, -1); +} + +static void z_plus() { + moveAxis(Z_AXIS, 1); +} + +static void z_minus() { + moveAxis(Z_AXIS, -1); +} + +static void e_select() { + motionAxisState.e_selection++; + if (motionAxisState.e_selection >= EXTRUDERS) { + motionAxisState.e_selection = 0; + } + + quick_feedback(); + drawCurESelection(); + drawAxisValue(E_AXIS); +} + +static void do_home() { + quick_feedback(); + drawMessage(GET_TEXT(MSG_LEVEL_BED_HOMING)); + queue.inject_P(G28_STR); + // Disable touch until home is done + TERN_(HAS_TFT_XPT2046, touch.disable()); + drawAxisValue(E_AXIS); + drawAxisValue(X_AXIS); + drawAxisValue(Y_AXIS); + drawAxisValue(Z_AXIS); +} + +static void step_size() { + motionAxisState.currentStepSize = motionAxisState.currentStepSize / 10.0; + if (motionAxisState.currentStepSize < 0.0015) motionAxisState.currentStepSize = 10.0; + quick_feedback(); + drawCurStepValue(); +} + +#if HAS_BED_PROBE + static void z_select() { + motionAxisState.z_selection *= -1; + quick_feedback(); + drawCurZSelection(); + drawAxisValue(Z_AXIS); + } +#endif + +static void disable_steppers() { + quick_feedback(); + queue.inject_P(PSTR("M84")); +} + +static void drawBtn(int x, int y, const char* label, int32_t data, MarlinImage img, uint16_t bgColor, bool enabled = true) { + uint16_t width = Images[imgBtn52Rounded].width; + uint16_t height = Images[imgBtn52Rounded].height; + + if (!enabled) bgColor = COLOR_CONTROL_DISABLED; + + tft.canvas(x, y, width, height); + tft.set_background(COLOR_BACKGROUND); + tft.add_image(0, 0, imgBtn52Rounded, bgColor, COLOR_BACKGROUND, COLOR_DARKGREY); + + // TODO: Make an add_text() taking a font arg + if (label != NULL) { + tft_string.set(label); + tft_string.trim(); + tft.add_text(tft_string.center(width), height / 2 - tft_string.font_height() / 2, bgColor, tft_string); + } + else { + tft.add_image(0, 0, img, bgColor, COLOR_BACKGROUND, COLOR_DARKGREY); + } + + TERN_(HAS_TFT_XPT2046, if (enabled) touch.add_control(BUTTON, x, y, width, height, data)); +} + +void MarlinUI::move_axis_screen() { + // Reset + defer_status_screen(true); + motionAxisState.blocked = false; + TERN_(HAS_TFT_XPT2046, touch.enable()); + + ui.clear_lcd(); + + TERN_(TOUCH_SCREEN, touch.clear()); + + const bool busy = printingIsActive(); + + // if we have baby step and we are printing, select baby step + if (busy && ENABLED(BABYSTEP_ZPROBE_OFFSET)) motionAxisState.z_selection = Z_SELECTION_Z_PROBE; + + // ROW 1 -> E- Y- CurY Z+ + int x = X_MARGIN, y = Y_MARGIN, spacing = 0; + + drawBtn(x, y, "E+", (int32_t)e_plus, imgUp, E_BTN_COLOR, !busy); + + spacing = (TFT_WIDTH - X_MARGIN * 2 - 3 * BTN_WIDTH) / 2; + x += BTN_WIDTH + spacing; + drawBtn(x, y, "Y+", (int32_t)y_plus, imgUp, Y_BTN_COLOR, !busy); + + // Cur Y + x += BTN_WIDTH; + motionAxisState.yValuePos.x = x + 2; + motionAxisState.yValuePos.y = y; + drawAxisValue(Y_AXIS); + + x += spacing; + drawBtn(x, y, "Z+", (int32_t)z_plus, imgUp, Z_BTN_COLOR, !busy || ENABLED(BABYSTEP_ZPROBE_OFFSET)); //only enabled when not busy or have baby step + + // ROW 2 -> "Ex" X- HOME X+ "Z" + y += BTN_HEIGHT + (TFT_HEIGHT - Y_MARGIN * 2 - 4 * BTN_HEIGHT) / 3; + x = X_MARGIN; + spacing = (TFT_WIDTH - X_MARGIN * 2 - 5 * BTN_WIDTH) / 4; + + motionAxisState.eNamePos.x = x; + motionAxisState.eNamePos.y = y; + drawCurESelection(); + TERN_(HAS_TFT_XPT2046, if (!busy) touch.add_control(BUTTON, x, y, BTN_WIDTH, BTN_HEIGHT, (int32_t)e_select)); + + x += BTN_WIDTH + spacing; + drawBtn(x, y, "X-", (int32_t)x_minus, imgLeft, X_BTN_COLOR, !busy); + + x += BTN_WIDTH + spacing; //imgHome is 64x64 + TERN_(HAS_TFT_XPT2046, add_control(TFT_WIDTH / 2 - Images[imgHome].width / 2, y - (Images[imgHome].width - BTN_HEIGHT) / 2, BUTTON, (int32_t)do_home, imgHome, !busy)); + + x += BTN_WIDTH + spacing; + uint16_t xplus_x = x; + drawBtn(x, y, "X+", (int32_t)x_plus, imgRight, X_BTN_COLOR, !busy); + + x += BTN_WIDTH + spacing; + motionAxisState.zTypePos.x = x; + motionAxisState.zTypePos.y = y; + drawCurZSelection(); + #if HAS_BED_PROBE + if (!busy) touch.add_control(BUTTON, x, y, BTN_WIDTH, 34 * 2, (int32_t)z_select); + #endif + + // ROW 3 -> E- CurX Y- Z- + y += BTN_HEIGHT + (TFT_HEIGHT - Y_MARGIN * 2 - 4 * BTN_HEIGHT) / 3; + x = X_MARGIN; + spacing = (TFT_WIDTH - X_MARGIN * 2 - 3 * BTN_WIDTH) / 2; + + drawBtn(x, y, "E-", (int32_t)e_minus, imgDown, E_BTN_COLOR, !busy); + + // Cur E + motionAxisState.eValuePos.x = x; + motionAxisState.eValuePos.y = y + BTN_HEIGHT + 2; + drawAxisValue(E_AXIS); + + // Cur X + motionAxisState.xValuePos.x = BTN_WIDTH + (TFT_WIDTH - X_MARGIN * 2 - 5 * BTN_WIDTH) / 4; //X- pos + motionAxisState.xValuePos.y = y - 10; + drawAxisValue(X_AXIS); + + x += BTN_WIDTH + spacing; + drawBtn(x, y, "Y-", (int32_t)y_minus, imgDown, Y_BTN_COLOR, !busy); + + x += BTN_WIDTH + spacing; + drawBtn(x, y, "Z-", (int32_t)z_minus, imgDown, Z_BTN_COLOR, !busy || ENABLED(BABYSTEP_ZPROBE_OFFSET)); //only enabled when not busy or have baby step + + // Cur Z + motionAxisState.zValuePos.x = x; + motionAxisState.zValuePos.y = y + BTN_HEIGHT + 2; + drawAxisValue(Z_AXIS); + + // ROW 4 -> step_size disable steppers back + y = TFT_HEIGHT - Y_MARGIN - 32; // + x = TFT_WIDTH / 2 - CUR_STEP_VALUE_WIDTH / 2; + motionAxisState.stepValuePos.x = x; + motionAxisState.stepValuePos.y = y; + if (!busy) { + drawCurStepValue(); + TERN_(HAS_TFT_XPT2046, touch.add_control(BUTTON, motionAxisState.stepValuePos.x, motionAxisState.stepValuePos.y, CUR_STEP_VALUE_WIDTH, BTN_HEIGHT, (int32_t)step_size)); + } + + // alinged with x+ + drawBtn(xplus_x, TFT_HEIGHT - Y_MARGIN - BTN_HEIGHT, "off", (int32_t)disable_steppers, imgCancel, COLOR_WHITE, !busy); + + TERN_(HAS_TFT_XPT2046, add_control(TFT_WIDTH - X_MARGIN - BTN_WIDTH, y, BACK, imgBack)); +} + +#undef BTN_WIDTH +#undef BTN_HEIGHT + +#endif // HAS_UI_480x320 diff --git a/Marlin/src/lcd/tft/ui_480x320.h b/Marlin/src/lcd/tft/ui_480x320.h new file mode 100644 index 000000000000..053ee78158cb --- /dev/null +++ b/Marlin/src/lcd/tft/ui_480x320.h @@ -0,0 +1,108 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../../inc/MarlinConfigPre.h" + +#include "tft.h" +#include "tft_image.h" + +#if ENABLED(TOUCH_SCREEN) + #include "touch.h" +#endif + +void draw_heater_status(uint16_t x, uint16_t y, const int8_t Heater); +void draw_fan_status(uint16_t x, uint16_t y, const bool blink); + +#define MENU_TEXT_X_OFFSET 16 +#define MENU_TEXT_Y_OFFSET 7 +void menu_line(const uint8_t row, uint16_t color = COLOR_BACKGROUND); +void menu_item(const uint8_t row, bool sel = false); + +#define MENU_FONT_NAME Helvetica18 +#define SYMBOLS_FONT_NAME Helvetica18_symbols + +#define ABSOLUTE_ZERO -273.15 + +const tImage Images[imgCount] = { + MarlinLogo195x59x16, + HotEnd_64x64x4, + Bed_64x64x4, + Bed_Heated_64x64x4, + Chamber_64x64x4, + Chamber_Heated_64x64x4, + Fan0_64x64x4, + Fan_Slow0_64x64x4, + Fan_Slow1_64x64x4, + Fan_Fast0_64x64x4, + Fan_Fast1_64x64x4, + Feedrate_32x32x4, + Flowrate_32x32x4, + SD_64x64x4, + Menu_64x64x4, + Settings_64x64x4, + Directory_32x32x4, + Confirm_64x64x4, + Cancel_64x64x4, + Increase_64x64x4, + Decrease_64x64x4, + Back_32x32x4, + Up_32x32x4, + Down_32x32x4, + Left_32x32x4, + Right_32x32x4, + Refresh_32x32x4, + Leveling_32x32x4, + Slider8x16x4, + Home_64x64x4, + BtnRounded_64x52x4, +}; + +#if HAS_TEMP_CHAMBER && HOTENDS > 1 + #define ITEM_E0 0 + #define ITEM_E1 1 + #define ITEM_BED 2 + #define ITEM_CHAMBER 3 + #define ITEM_FAN 4 + #define ITEMS_COUNT 5 + #define POS_Y 4 +#elif HAS_TEMP_CHAMBER + #define ITEM_E0 0 + #define ITEM_BED 1 + #define ITEM_CHAMBER 2 + #define ITEM_FAN 3 + #define ITEMS_COUNT 4 + #define POS_Y 4 +#elif HOTENDS > 1 + #define ITEM_E0 0 + #define ITEM_E1 1 + #define ITEM_BED 2 + #define ITEM_FAN 3 + #define ITEMS_COUNT 4 + #define POS_Y 4 +#else + #define ITEM_E0 0 + #define ITEM_BED 1 + #define ITEM_FAN 2 + #define ITEMS_COUNT 3 + #define POS_Y 4 +#endif diff --git a/Marlin/src/lcd/tft_io/ili9328.h b/Marlin/src/lcd/tft_io/ili9328.h new file mode 100644 index 000000000000..b50517adfea5 --- /dev/null +++ b/Marlin/src/lcd/tft_io/ili9328.h @@ -0,0 +1,173 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "tft_io.h" + +#include "../../inc/MarlinConfig.h" + +#define ILI9328_DRVCTL_SM 0x0400 +#define ILI9328_DRVCTL_SS 0x0100 // Select the shift direction of outputs from the source driver. 0 - from S1 to S720 / 1 - from S720 to S1 + +#define ILI9328_GATE_SCANCTL_GS 0x8000 // Sets the direction of scan by the gate driver in the range determined by SCN[4:0] and NL[4:0]. + +#define ILI9328_ETMOD_TRI 0x8000 +#define ILI9328_ETMOD_DFM 0x4000 +#define ILI9328_ETMOD_BGR 0x1000 // RGB-BGR ORDER +#define ILI9328_ETMOD_RGB 0x0000 +#define ILI9328_ETMOD_ORG 0x0080 +#define ILI9328_ETMOD_ID1 0x0020 // 0 - Vertical Decrement / 1 - Vertical Increment +#define ILI9328_ETMOD_ID0 0x0010 // 0 - Horizontal Decrement / 1 - Horizontal Increment +#define ILI9328_ETMOD_AM 0x0008 // 0 - Horizontal / 1 - Vertical + +// MKS Robin TFT v1.1 - 320x240 ; Cable on the left side + +#if TFT_ROTATION == TFT_ROTATE_180 + #define ILI9328_DRVCTL_DATA 0x0000 + #define ILI9328_GATE_SCANCTL1_DATA 0xA700 +#else + #define ILI9328_DRVCTL_DATA ILI9328_DRVCTL_SS + #define ILI9328_GATE_SCANCTL1_DATA 0x2700 +#endif + +/* +#define ILI9328_ETMOD_ORIENTATION IF_0((TFT_ORIENTATION) & TFT_EXCHANGE_XY, ILI9328_ETMOD_AM) | \ + IF_0((TFT_ORIENTATION) & TFT_INVERT_X, ILI9328_ETMOD_ID1) | \ + IF_0((TFT_ORIENTATION) & TFT_INVERT_Y, ILI9328_ETMOD_ID0) +*/ + +#define ILI9328_ETMOD_ORIENTATION (ILI9328_ETMOD_AM | ILI9328_ETMOD_ID1 | ILI9328_ETMOD_ID0) + +#if !defined(TFT_COLOR) || TFT_COLOR == TFT_COLOR_BGR + #define ILI9328_ETMOD_COLOR ILI9328_ETMOD_BGR +#elif TFT_COLOR == TFT_COLOR_RGB + #define ILI9328_ETMOD_COLOR ILI9328_ETMOD_RGB +#endif + +#define ILI9328_ETMOD_DATA (ILI9328_ETMOD_ORIENTATION) | (ILI9328_ETMOD_COLOR) + + +#define ILI9328_RDDID 0x00 // ID code - 0x9328 +#define ILI9328_DRVCTL 0x01 // Driver Output Control +#define ILI9328_LCDCTL 0x02 // LCD Driving Wave Control +#define ILI9328_ETMOD 0x03 // Entry Mode - Control the GRAM update direction +#define ILI9328_RESIZECTL 0x04 // Resizing Control Register +#define ILI9328_DISCTRL1 0x07 // Display Control 1 +#define ILI9328_DISCTRL2 0x08 // Display Control 2 +#define ILI9328_DISCTRL3 0x09 // Display Control 3 +#define ILI9328_DISCTRL4 0x0A // Display Control 4 +#define ILI9328_RGBCTRL1 0x0C // RGB Display Interface Control 1 +#define ILI9328_FMARKERPOS 0x0D // Frame Marker Position +#define ILI9328_RGBCTRL2 0x0F // RGB Display Interface Control 2 +#define ILI9328_PWCTRL1 0x10 // Power Control 1 +#define ILI9328_PWCTRL2 0x11 // Power Control 2 +#define ILI9328_PWCTRL3 0x12 // Power Control 3 +#define ILI9328_PWCTRL4 0x13 // Power Control 4 + +// With landscape screen orientation 'Horizontal' is Y and 'Vertical' is X +#define ILI9328_HASET 0x20 // GRAM Horizontal Address Set (0-255) +#define ILI9328_VASET 0x21 // GRAM Vertical Address Set (0-511) +#define ILI9328_RAMWR 0x22 // Write data to GRAM +#define ILI9328_RAMRD 0x22 // Read Data from GRAM + +#define ILI9328_PWCTRL7 0x29 // Power Control 7 +#define ILI9328_FRMCTR 0x2B // Frame Rate and Color Control +#define ILI9328_GAMCTRL1 0x30 // Gamma Control +#define ILI9328_GAMCTRL2 0x31 // Gamma Control +#define ILI9328_GAMCTRL3 0x32 // Gamma Control +#define ILI9328_GAMCTRL4 0x35 // Gamma Control +#define ILI9328_GAMCTRL5 0x36 // Gamma Control +#define ILI9328_GAMCTRL6 0x37 // Gamma Control +#define ILI9328_GAMCTRL7 0x38 // Gamma Control +#define ILI9328_GAMCTRL8 0x39 // Gamma Control +#define ILI9328_GAMCTRL9 0x3C // Gamma Control +#define ILI9328_GAMCTRLA 0x3D // Gamma Control + +// With landscape screen orientation 'Horizontal' is Y and 'Vertical' is X +#define ILI9328_HASTART 0x50 // Horizontal Address Start Position (0-255) +#define ILI9328_HAEND 0x51 // Horizontal Address End Position (0-255) +#define ILI9328_VASTART 0x52 // Vertical Address Start Position (0-511) +#define ILI9328_VAEND 0x53 // Vertical Address End Position (0-511) + +#define ILI9328_GATE_SCANCTL1 0x60 // Gate Scan Control +#define ILI9328_GATE_SCANCTL2 0x61 // Gate Scan Control +#define ILI9328_GATE_SCANCTL3 0x6A // Gate Scan Control + +#define ILI9328_PLTPOS1 0x80 // Partial Image 1 Display Position +#define ILI9328_PLTSTART1 0x81 // Partial Image 1 RAM Start Address +#define ILI9328_PLTEND1 0x82 // Partial Image 1 RAM End Address +#define ILI9328_PLTPOS2 0x83 // Partial Image 2 Display Position +#define ILI9328_PLTSTART2 0x84 // Partial Image 2 RAM Start Address +#define ILI9328_PLTEND2 0x85 // Partial Image 2 RAM End Address + +#define ILI9328_IFCTL1 0x90 // Panel Interface Control 1 +#define ILI9328_IFCTL2 0x92 // Panel Interface Control 2 +#define ILI9328_IFCTL4 0x95 // Panel Interface Control 4 +#define ILI9328_IFCTL5 0x97 // Panel Interface Control 5 + +#define ILI9328_OTPWR 0xA1 // OTP VCM Programming Control +#define ILI9328_RDOTP 0xA2 // OTP VCM Status and Enable +#define ILI9328_OTPPKEY 0xA5 // OTP Programming ID Key + + +static const uint16_t ili9328_init[] = { + DATASIZE_16BIT, + ESC_REG(ILI9328_DRVCTL), ILI9328_DRVCTL_DATA, + ESC_REG(ILI9328_LCDCTL), 0x0400, // LCD Driving Wave Control + ESC_REG(ILI9328_ETMOD), ILI9328_ETMOD_DATA, + + ESC_REG(ILI9328_RESIZECTL), 0x0000, + ESC_REG(ILI9328_DISCTRL2), 0x0202, + ESC_REG(ILI9328_DISCTRL3), 0x0000, + ESC_REG(ILI9328_DISCTRL4), 0x0000, + ESC_REG(ILI9328_RGBCTRL1), 0x0000, + ESC_REG(ILI9328_FMARKERPOS), 0x0000, + ESC_REG(ILI9328_RGBCTRL2), 0x0000, + ESC_REG(ILI9328_PWCTRL1), 0x0000, + ESC_REG(ILI9328_PWCTRL2), 0x0007, + ESC_REG(ILI9328_PWCTRL3), 0x0000, + ESC_REG(ILI9328_PWCTRL4), 0x0000, + ESC_REG(ILI9328_DISCTRL1), 0x0001, + ESC_DELAY(200), + ESC_REG(ILI9328_PWCTRL1), 0x1690, + ESC_REG(ILI9328_PWCTRL2), 0x0227, + ESC_DELAY(50), + ESC_REG(ILI9328_PWCTRL3), 0x008C, + ESC_DELAY(50), + ESC_REG(ILI9328_PWCTRL4), 0x1500, + ESC_REG(ILI9328_PWCTRL7), 0x0004, + ESC_REG(ILI9328_FRMCTR), 0x000D, + ESC_DELAY(50), + ESC_REG(ILI9328_GATE_SCANCTL1), ILI9328_GATE_SCANCTL1_DATA, + ESC_REG(ILI9328_GATE_SCANCTL2), 0x0001, + ESC_REG(ILI9328_GATE_SCANCTL3), 0x0000, + ESC_REG(ILI9328_PLTPOS1), 0x0000, + ESC_REG(ILI9328_PLTSTART1), 0x0000, + ESC_REG(ILI9328_PLTEND1), 0x0000, + ESC_REG(ILI9328_PLTPOS2), 0x0000, + ESC_REG(ILI9328_PLTSTART2), 0x0000, + ESC_REG(ILI9328_PLTEND2), 0x0000, + ESC_REG(ILI9328_IFCTL1), 0x0010, + ESC_REG(ILI9328_IFCTL2), 0x0600, + ESC_REG(ILI9328_DISCTRL1), 0x0133, + ESC_END +}; diff --git a/Marlin/src/lcd/tft_io/ili9341.h b/Marlin/src/lcd/tft_io/ili9341.h new file mode 100644 index 000000000000..dda326df6d5b --- /dev/null +++ b/Marlin/src/lcd/tft_io/ili9341.h @@ -0,0 +1,170 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "tft_io.h" + +#include "../../inc/MarlinConfig.h" + +#define ILI9341_MADCTL_MY 0x80 // Row Address Order +#define ILI9341_MADCTL_MX 0x40 // Column Address Order +#define ILI9341_MADCTL_MV 0x20 // Row/Column Exchange +#define ILI9341_MADCTL_ML 0x10 // Vertical Refresh Order +#define ILI9341_MADCTL_BGR 0x08 // RGB-BGR ORDER +#define ILI9341_MADCTL_RGB 0x00 +#define ILI9341_MADCTL_MH 0x04 // Horizontal Refresh Order + +#define ILI9341_ORIENTATION_UP ILI9341_MADCTL_MY // 240x320 ; Cable on the upper side +#define ILI9341_ORIENTATION_RIGHT ILI9341_MADCTL_MV // 320x240 ; Cable on the right side +#define ILI9341_ORIENTATION_LEFT ILI9341_MADCTL_MY | ILI9341_MADCTL_MX | ILI9341_MADCTL_MV // 320x240 ; Cable on the left side +#define ILI9341_ORIENTATION_DOWN ILI9341_MADCTL_MX // 240x320 ; Cable on the upper side + +#define ILI9341_ORIENTATION IF_0((TFT_ORIENTATION) & TFT_EXCHANGE_XY, ILI9341_MADCTL_MV) | \ + IF_0((TFT_ORIENTATION) & TFT_INVERT_X, ILI9341_MADCTL_MX) | \ + IF_0((TFT_ORIENTATION) & TFT_INVERT_Y, ILI9341_MADCTL_MY) + +#if !defined(TFT_COLOR) || TFT_COLOR == TFT_COLOR_BGR + #define ILI9341_COLOR ILI9341_MADCTL_BGR +#elif TFT_COLOR == TFT_COLOR_RGB + #define ILI9341_COLOR ILI9341_MADCTL_RGB +#endif + +#define ILI9341_MADCTL_DATA (ILI9341_ORIENTATION) | (ILI9341_COLOR) + +#define ILI9341_NOP 0x00 // No Operation +#define ILI9341_SWRESET 0x01 // Software Reset +#define ILI9341_RDDIDIF 0x04 // Read display identification information +#define ILI9341_RDDST 0x09 // Read Display Status +#define ILI9341_RDDPM 0x0A // Read Display Power Mode +#define ILI9341_RDDMADCTL 0x0B // Read Display MADCTL +#define ILI9341_RDDCOLMOD 0x0C // Read Display Pixel Format +#define ILI9341_RDDIM 0x0D // Read Display Image Format +#define ILI9341_RDDSM 0x0E // Read Display Signal Mode +#define ILI9341_RDDSDR 0x0F // Read Display Self-Diagnostic Result +#define ILI9341_SPLIN 0x10 // Enter Sleep Mode +#define ILI9341_SLPOUT 0x11 // Sleep Out +#define ILI9341_PTLON 0x12 // Partial Mode ON +#define ILI9341_NORON 0x13 // Normal Display Mode ON +#define ILI9341_DINVOFF 0x20 // Display Inversion OFF +#define ILI9341_DINVON 0x21 // Display Inversion ON +#define ILI9341_GAMSET 0x26 // Gamma Set +#define ILI9341_DISPOFF 0x28 // Display OFF +#define ILI9341_DISPON 0x29 // Display ON +#define ILI9341_CASET 0x2A // Column Address Set +#define ILI9341_PASET 0x2B // Page Address Set +#define ILI9341_RAMWR 0x2C // Memory Write +#define ILI9341_RGBSET 0x2D // Color Set +#define ILI9341_RAMRD 0x2E // Memory Read +#define ILI9341_PLTAR 0x30 // Partial Area +#define ILI9341_VSCRDEF 0x33 // Vertical Scrolling Definition +#define ILI9341_TEOFF 0x34 // Tearing Effect Line OFF +#define ILI9341_TEON 0x35 // Tearing Effect Line ON +#define ILI9341_MADCTL 0x36 // Memory Access Control +#define ILI9341_VSCRSADD 0x37 // Vertical Scrolling Start Address +#define ILI9341_IDMOFF 0x38 // Idle Mode OFF +#define ILI9341_IDMON 0x39 // Idle Mode ON +#define ILI9341_PIXSET 0x3A // COLMOD: Pixel Format Set +#define ILI9341_WRMEMC 0x3C // Write Memory Continue +#define ILI9341_RDMEMC 0x3E // Read Memory Continue +#define ILI9341_STE 0x44 // Set Tear Scanline +#define ILI9341_GSCAN 0x45 // Get Scanline +#define ILI9341_WRDISBV 0x51 // Write Display Brightness +#define ILI9341_RDDISBV 0x52 // Read Display Brightness +#define ILI9341_WRCTRLD 0x53 // Write CTRL Display +#define ILI9341_RDCTRLD 0x54 // Read CTRL Display +#define ILI9341_WRCABC 0x55 // Write Content Adaptive Brightness Control +#define ILI9341_RDCABC 0x56 // Read Content Adaptive Brightness Control +#define ILI9341_WRCABCMB 0x5E // Write CABC Minimum Brightness / Backlight Control 1 +#define ILI9341_RDCABCMB 0x5F // Read CABC Minimum Brightness / Backlight Control 1 +#define ILI9341_RDID1 0xDA // Read ID1 +#define ILI9341_RDID2 0xDB // Read ID2 +#define ILI9341_RDID3 0xDC // Read ID3 + +#define ILI9341_IFMODE 0xB0 // RGB Interface Signal Control +#define ILI9341_FRMCTR1 0xB1 // Frame Rate Control (In Normal Mode/Full Colors) +#define ILI9341_FRMCTR2 0xB2 // Frame Rate Control (In Idle Mode/8 colors) +#define ILI9341_FRMCTR3 0xB3 // Frame Rate control (In Partial Mode/Full Colors) +#define ILI9341_INVTR 0xB4 // Display Inversion Control +#define ILI9341_PRCTR 0xB5 // Blanking Porch Control +#define ILI9341_DISCTRL 0xB6 // Display Function Control +#define ILI9341_ETMOD 0xB7 // Entry Mode Set +#define ILI9341_BLCTL1 0xB8 // Backlight Control 1 +#define ILI9341_BLCTL2 0xB9 // Backlight Control 2 +#define ILI9341_BLCTL3 0xBA // Backlight Control 3 +#define ILI9341_BLCTL4 0xBB // Backlight Control 4 +#define ILI9341_BLCTL5 0xBC // Backlight Control 5 +#define ILI9341_BLCTL7 0xBE // Backlight Control 7 +#define ILI9341_BLCTL8 0xBF // Backlight Control 8 +#define ILI9341_PWCTRL1 0xC0 // Power Control 1 +#define ILI9341_PWCTRL2 0xC1 // Power Control 2 +#define ILI9341_VMCTRL1 0xC5 // VCOM Control 1 +#define ILI9341_VMCTRL2 0xC7 // VCOM Control 2 +#define ILI9341_PWCTRLA 0xCB // Power control A +#define ILI9341_PWCTRLB 0xCF // Power control B +#define ILI9341_NVMWR 0xD0 // NV Memory Write +#define ILI9341_NVMPKEY 0xD1 // NV Memory Protection Key +#define ILI9341_RDNVM 0xD2 // NV Memory Status Read +#define ILI9341_RDID4 0xD3 // Read ID4 - 0x009341 +#define ILI9341_PGAMCTRL 0xE0 // Positive Gamma Correction +#define ILI9341_NGAMCTRL 0xE1 // Negative Gamma Correction +#define ILI9341_DGAMCTRL1 0xE2 // Digital Gamma Control 1 +#define ILI9341_DGAMCTRL2 0xE3 // Digital Gamma Control 2 +#define ILI9341_DRVTCTLA1 0xE8 // Driver timing control A +#define ILI9341_DRVTCTLA2 0xE9 // Driver timing control A +#define ILI9341_DRVTCTLB 0xEA // Driver timing control B +#define ILI9341_PONSEQCTL 0xED // Power on sequence control +#define ILI9341_EN3G 0xF2 // Enable 3G - 3 gamma control +#define ILI9341_IFCTL 0xF6 // Interface Control +#define ILI9341_PUMPRCTL 0xF7 // Pump ratio control + + +static const uint16_t ili9341_init[] = { + DATASIZE_8BIT, + ESC_REG(ILI9341_SWRESET), ESC_DELAY(100), + ESC_REG(ILI9341_SLPOUT), ESC_DELAY(20), +/* + ESC_REG(ILI9341_PWCTRLA), 0x0039, 0x002C, 0x0000, 0x0034, 0x0002, // Power control A + ESC_REG(ILI9341_PWCTRLB), 0x0000, 0x00C1, 0x0030, // Power control B + ESC_REG(ILI9341_DRVTCTLA1), 0x0085, 0x0000, 0x0078, // Driver timing control A + ESC_REG(ILI9341_DRVTCTLB), 0x0000, 0x0000, // Driver timing control B + ESC_REG(ILI9341_PONSEQCTL), 0x0064, 0x0003, 0x0012, 0x0081, // Power on sequence control + ESC_REG(ILI9341_DISCTRL), 0x0008, 0x0082, 0x0027, // Display Function Control + ESC_REG(ILI9341_PUMPRCTL), 0x0020, // Pump ratio control + ESC_REG(ILI9341_VMCTRL1), 0x003E, 0x0028, // VCOM Control 1 + ESC_REG(ILI9341_VMCTRL2), 0x0086, // VCOM Control 2 + ESC_REG(ILI9341_FRMCTR1), 0x0000, 0x0018, // Frame Rate Control (In Normal Mode/Full Colors) + ESC_REG(ILI9341_PWCTRL1), 0x0023, // Power Control 1 + ESC_REG(ILI9341_PWCTRL2), 0x0010, // Power Control 2 +*/ + ESC_REG(ILI9341_MADCTL), ILI9341_MADCTL_DATA, + ESC_REG(ILI9341_PIXSET), 0x0055, + + /* Gamma Correction */ + ESC_REG(ILI9341_EN3G), 0x0000, // 3Gamma Function Disable + ESC_REG(ILI9341_GAMSET), 0x0001, // Gamma curve selected + ESC_REG(ILI9341_PGAMCTRL), 0x000F, 0x0031, 0x002B, 0x000C, 0x000E, 0x0008, 0x004E, 0x00F1, 0x0037, 0x0007, 0x0010, 0x0003, 0x000E, 0x0009, 0x0000, + ESC_REG(ILI9341_NGAMCTRL), 0x0000, 0x000E, 0x0014, 0x0003, 0x0011, 0x0007, 0x0031, 0x00C1, 0x0048, 0x0008, 0x000F, 0x000C, 0x0031, 0x0036, 0x000F, + + ESC_REG(ILI9341_NORON), + ESC_REG(ILI9341_DISPON), + ESC_END +}; diff --git a/Marlin/src/lcd/tft_io/ili9488.h b/Marlin/src/lcd/tft_io/ili9488.h new file mode 100644 index 000000000000..e71c0d16d775 --- /dev/null +++ b/Marlin/src/lcd/tft_io/ili9488.h @@ -0,0 +1,164 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "tft_io.h" + +#include "../../inc/MarlinConfig.h" + +#define ILI9488_MADCTL_MY 0x80 // Row Address Order +#define ILI9488_MADCTL_MX 0x40 // Column Address Order +#define ILI9488_MADCTL_MV 0x20 // Row/Column Exchange +#define ILI9488_MADCTL_ML 0x10 // Vertical Refresh Order +#define ILI9488_MADCTL_BGR 0x08 // RGB-BGR ORDER +#define ILI9488_MADCTL_RGB 0x00 +#define ILI9488_MADCTL_MH 0x04 // Horizontal Refresh Order + +#define ILI9488_ORIENTATION_UP ILI9488_MADCTL_MY // 320x480 ; Cable on the upper side +#define ILI9488_ORIENTATION_RIGHT ILI9488_MADCTL_MV // 480x320 ; Cable on the right side +#define ILI9488_ORIENTATION_LEFT ILI9488_MADCTL_MY | ILI9488_MADCTL_MX | ILI9488_MADCTL_MV // 480x320 ; Cable on the left side +#define ILI9488_ORIENTATION_DOWN ILI9488_MADCTL_MX // 320x480 ; Cable on the upper side + +#define ILI9488_ORIENTATION IF_0((TFT_ORIENTATION) & TFT_EXCHANGE_XY, ILI9488_MADCTL_MV) | \ + IF_0((TFT_ORIENTATION) & TFT_INVERT_X, ILI9488_MADCTL_MX) | \ + IF_0((TFT_ORIENTATION) & TFT_INVERT_Y, ILI9488_MADCTL_MY) + +#if !defined(TFT_COLOR) || TFT_COLOR == TFT_COLOR_BGR + #define ILI9488_COLOR ILI9488_MADCTL_BGR +#elif TFT_COLOR == TFT_COLOR_RGB + #define ILI9488_COLOR ILI9488_MADCTL_RGB +#endif + +#define ILI9488_MADCTL_DATA (ILI9488_ORIENTATION) | (ILI9488_COLOR) + +#define ILI9488_NOP 0x00 // No Operation +#define ILI9488_SWRESET 0x01 // Software Reset +#define ILI9488_RDDIDIF 0x04 // Read Display Identification Information +#define ILI9488_RDNUMED 0x05 // Read Number of the Errors on DSI +#define ILI9488_RDDST 0x09 // Read Display Status +#define ILI9488_RDDPM 0x0A // Read Display Power Mode +#define ILI9488_RDDMADCTL 0x0B // Read Display MADCTL +#define ILI9488_RDDCOLMOD 0x0C // Read Display COLMOD +#define ILI9488_RDDIM 0x0D // Read Display Image Mode +#define ILI9488_RDDSM 0x0E // Read Display Signal Mode +#define ILI9488_RDDSDR 0x0F // Read Display Self-Diagnostic Result +#define ILI9488_SLPIN 0x10 // Sleep IN +#define ILI9488_SLPOUT 0x11 // Sleep OUT +#define ILI9488_PTLON 0x12 // Partial Mode ON +#define ILI9488_NORON 0x13 // Normal Display Mode ON +#define ILI9488_INVOFF 0x20 // Display Inversion OFF +#define ILI9488_INVON 0x21 // Display Inversion ON +#define ILI9488_ALLPOFF 0x22 // All Pixels OFF +#define ILI9488_ALLPON 0x23 // All Pixels ON +#define ILI9488_DISOFF 0x28 // Display OFF +#define ILI9488_DISON 0x29 // Display ON +#define ILI9488_CASET 0x2A // Column Address Set +#define ILI9488_PASET 0x2B // Page Address Set +#define ILI9488_RAMWR 0x2C // Memory Write +#define ILI9488_RAMRD 0x2E // Memory Read +#define ILI9488_PLTAR 0x30 // Partial Area +#define ILI9488_VSCRDEF 0x33 // Vertical Scrolling Definition +#define ILI9488_TEOFF 0x34 // Tearing Effect Line OFF +#define ILI9488_TEON 0x35 // Tearing Effect Line ON +#define ILI9488_MADCTL 0x36 // Memory Access Control +#define ILI9488_VSCRSADD 0x37 // Vertical Scrolling Start Address +#define ILI9488_IDMOFF 0x38 // Idle Mode OFF +#define ILI9488_IDMON 0x39 // Idle Mode ON +#define ILI9488_COLMOD 0x3A // Interface Pixel Format +#define ILI9488_RAMWRC 0x3C // Memory Write Continue +#define ILI9488_RAMRDRC 0x3E // Memory Read Continue +#define ILI9488_TESLWR 0x44 // Write Tear Scan Line +#define ILI9488_TESLRD 0x45 // Read Scan Line +#define ILI9488_WRDISBV 0x51 // Write Display Brightness Value +#define ILI9488_RDDISBV 0x52 // Read Display Brightness Value +#define ILI9488_WRCTRLD 0x53 // Write Control Display Value +#define ILI9488_RDCTRLD 0x54 // Read Control Display Value +#define ILI9488_WRCABC 0x55 // Write Content Adaptive Brightness Control Value +#define ILI9488_RDCABC 0x56 // Read Content Adaptive Brightness Control Value +#define ILI9488_WRCABCMB 0x5E // Write CABC Minimum Brightness +#define ILI9488_RDCABCMB 0x5F // Read CABC Minimum Brightness +#define ILI9488_RDABCSDR 0x68 // Read Automatic Brightness Control Self-diagnostic Result +#define ILI9488_RDID1 0xDA // Read ID1 +#define ILI9488_RDID2 0xDB // Read ID2 +#define ILI9488_RDID3 0xDC // Read ID3 + +#define ILI9488_IFMODE 0xB0 // Interface Mode Control +#define ILI9488_FRMCTR1 0xB1 // Frame Rate Control (In Normal Mode/Full Colors) +#define ILI9488_FRMCTR2 0xB2 // Frame Rate Control (In Idle Mode/8 Colors) +#define ILI9488_FRMCTR3 0xB3 // Frame Rate Control (In Partial Mode/Full Colors) +#define ILI9488_INVTR 0xB4 // Display Inversion Control +#define ILI9488_PRCTR 0xB5 // Blanking Porch Control +#define ILI9488_DISCTRL 0xB6 // Display Function Control +#define ILI9488_ETMOD 0xB7 // Entry Mode Set +#define ILI9488_CECTRL1 0xB9 // Color Enhancement Control 1 +#define ILI9488_CECTRL2 0xBA // Color Enhancement Control 2 +#define ILI9488_HSLCTRL 0xBE // HS Lanes Control +#define ILI9488_PWCTRL1 0xC0 // Power Control 1 +#define ILI9488_PWCTRL2 0xC1 // Power Control 2 +#define ILI9488_PWCTRL3 0xC2 // Power Control 3 (For Normal Mode) +#define ILI9488_PWCTRL4 0xC3 // Power Control 4 (For Idle Mode) +#define ILI9488_PWCTRL5 0xC4 // Power Control 5 (For Partial Mode) +#define ILI9488_VMCTRL 0xC5 // VCOM Control +#define ILI9488_CABCCTRL1 0xC6 // CABC Control 1 +#define ILI9488_CABCCTRL2 0xC8 // CABC Control 2 +#define ILI9488_CABCCTRL3 0xC9 // CABC Control 3 +#define ILI9488_CABCCTRL4 0xCA // CABC Control 4 +#define ILI9488_CABCCTRL5 0xCB // CABC Control 5 +#define ILI9488_CABCCTRL6 0xCC // CABC Control 6 +#define ILI9488_CABCCTRL7 0xCD // CABC Control 7 +#define ILI9488_CABCCTRL8 0xCE // CABC Control 8 +#define ILI9488_CABCCTRL9 0xCF // CABC Control 9 +#define ILI9488_NVMWR 0xD0 // NV Memory Write +#define ILI9488_NVMPKEY 0xD1 // NV Memory Protection Key +#define ILI9488_RDNVM 0xD2 // NV Memory Status Read +#define ILI9488_RDID4 0xD3 // Read ID4 - 0x009488 +#define ILI9488_ADJCTL1 0xD7 // Adjust Control 1 +#define ILI9488_RDIDV 0xD8 // Read ID Version +#define ILI9488_PGAMCTRL 0xE0 // Positive Gamma Control +#define ILI9488_NGAMCTRL 0xE1 // Negative Gamma Control +#define ILI9488_DGAMCTRL1 0xE2 // Ditigal Gamma Control 1 +#define ILI9488_DGAMCTRL2 0xE3 // Ditigal Gamma Control 2 +#define ILI9488_SETIMAGE 0xE9 // Set Image Function +#define ILI9488_ADJCTL2 0xF2 // Adjust Control 2 +#define ILI9488_ADJCTL3 0xF7 // Adjust Control 3 +#define ILI9488_ADJCTL4 0xF8 // Adjust Control 4 +#define ILI9488_ADJCTL5 0xF9 // Adjust Control 5 +#define ILI9488_RDEXTC 0xFB // Read EXTC command is SPI mode +#define ILI9488_ADJCTL6 0xFC // Adjust Control 6 +#define ILI9488_ADJCTL7 0xFF // Adjust Control 7 + +static const uint16_t ili9488_init[] = { + DATASIZE_8BIT, + ESC_REG(ILI9488_SWRESET), ESC_DELAY(120), + ESC_REG(ILI9488_SLPOUT), ESC_DELAY(20), + + ESC_REG(ILI9488_MADCTL), ILI9488_MADCTL_DATA, + ESC_REG(ILI9488_COLMOD), 0x0055, + + /* Gamma Correction. */ + ESC_REG(ILI9488_PGAMCTRL), 0x0000, 0x0003, 0x0009, 0x0008, 0x0016, 0x000A, 0x003F, 0x0078, 0x004C, 0x0009, 0x000A, 0x0008, 0x0016, 0x001A, 0x000F, + ESC_REG(ILI9488_NGAMCTRL), 0x0000, 0x0016, 0x0019, 0x0003, 0x000F, 0x0005, 0x0032, 0x0045, 0x0046, 0x0004, 0x000E, 0x000D, 0x0035, 0x0037, 0x000F, + + ESC_REG(ILI9488_NORON), + ESC_REG(ILI9488_DISON), + ESC_END +}; diff --git a/Marlin/src/lcd/tft_io/r65105.h b/Marlin/src/lcd/tft_io/r65105.h new file mode 100644 index 000000000000..8be2afe4423c --- /dev/null +++ b/Marlin/src/lcd/tft_io/r65105.h @@ -0,0 +1,176 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "tft_io.h" + +#include "../../inc/MarlinConfig.h" + +#define R61505_DRVCTL_SM 0x0400 +#define R61505_DRVCTL_SS 0x0100 // Select the shift direction of outputs from the source driver. 0 - from S1 to S720 / 1 - from S720 to S1 + +#define R61505_ETMOD_TRIGGER 0x8000 // 18-bit RAM when set; 16-bit RAM when not set +#define R61505_ETMOD_DFM 0x4000 +#define R61505_ETMOD_BGR 0x1000 // RGB-BGR ORDER +#define R61505_ETMOD_RGB 0x0000 + +#define R61505_ETMOD_HWM 0x0020 +#define R61505_ETMOD_ORG 0x0080 +#define R61505_ETMOD_ID1 0x0020 // 0 - Vertical Decrement / 1 - Vertical Increment +#define R61505_ETMOD_ID0 0x0010 // 0 - Horizontal Decrement / 1 - Horizontal Increment +#define R61505_ETMOD_AM 0x0008 // 0 - Horizontal / 1 - Vertical + +#define R61505_DRVCTRL_GS 0x8000 // Gate Scan direction + +// MKS Robin TFT v1.1 - 320x240 ; Cable on the left side + +#if TFT_ROTATION == TFT_ROTATE_180 + #define R61505_DRVCTL_DATA 0x0000 + #define R61505_DRVCTRL_DATA (0x2700 | R61505_DRVCTRL_GS) +#else + #define R61505_DRVCTL_DATA R61505_DRVCTL_SS + #define R61505_DRVCTRL_DATA 0x2700 +#endif + +/* +#define R61505_ETMOD_ORIENTATION IF_0((TFT_ORIENTATION) & TFT_EXCHANGE_XY, R61505_ETMOD_AM) | \ + IF_0((TFT_ORIENTATION) & TFT_INVERT_X, R61505_ETMOD_ID0) | \ + IF_0((TFT_ORIENTATION) & TFT_INVERT_Y, R61505_ETMOD_ID1) +*/ + +#define R61505_ETMOD_ORIENTATION (R61505_ETMOD_AM | R61505_ETMOD_ID0 | R61505_ETMOD_ID1) + +#if !defined(TFT_COLOR) || TFT_COLOR == TFT_COLOR_BGR + #define R61505_ETMOD_COLOR R61505_ETMOD_BGR +#elif TFT_COLOR == TFT_COLOR_RGB + #define R61505_ETMOD_COLOR R61505_ETMOD_RGB +#endif + +#define R61505_ETMOD_DATA (R61505_ETMOD_ORIENTATION) | (R61505_ETMOD_COLOR) + + +#define R61505_RDDID 0x00 // ID code - 0x1505 +#define R61505_DRVCTL 0x01 // Driver Output Control +#define R61505_LCDCTL 0x02 // LCD Driving Wave Control +#define R61505_ETMOD 0x03 // Entry Mode - Control the GRAM update direction +#define R61505_RESIZECTL 0x04 // Resizing Control Register +#define R61505_DISCTRL1 0x07 // Display Control 1 +#define R61505_DISCTRL2 0x08 // Display Control 2 +#define R61505_DISCTRL3 0x09 // Display Control 3 +#define R61505_DISCTRL4 0x0A // Display Control 4 +#define R61505_RGBCTRL1 0x0C // RGB Display Interface Control 1 +#define R61505_FMARKERPOS 0x0D // Frame Marker Position +#define R61505_RGBCTRL2 0x0F // RGB Display Interface Control 2 +#define R61505_PWCTRL1 0x10 // Power Control 1 +#define R61505_PWCTRL2 0x11 // Power Control 2 +#define R61505_PWCTRL3 0x12 // Power Control 3 +#define R61505_PWCTRL4 0x13 // Power Control 4 + +// With landscape screen orientation 'Horizontal' is Y and 'Vertical' is X +#define R61505_HASET 0x20 // GRAM Horizontal Address Set (0-255) +#define R61505_VASET 0x21 // GRAM Vertical Address Set (0-511) +#define R61505_RAMWR 0x22 // Write data to GRAM +#define R61505_RAMRD 0x22 // Read Data from GRAM + +#define R61505_PWCTRL7 0x29 // Power Control 7 +#define R61505_GAMCTRL1 0x30 // Gamma Control +#define R61505_GAMCTRL2 0x31 // Gamma Control +#define R61505_GAMCTRL3 0x32 // Gamma Control +#define R61505_GAMCTRL4 0x35 // Gamma Control +#define R61505_GAMCTRL5 0x36 // Gamma Control +#define R61505_GAMCTRL6 0x37 // Gamma Control +#define R61505_GAMCTRL7 0x38 // Gamma Control +#define R61505_GAMCTRL8 0x39 // Gamma Control +#define R61505_GAMCTRL9 0x3C // Gamma Control +#define R61505_GAMCTRLA 0x3D // Gamma Control + +// With landscape screen orientation 'Horizontal' is Y and 'Vertical' is X +#define R61505_HASTART 0x50 // Horizontal Address Start Position (0-255) +#define R61505_HAEND 0x51 // Horizontal Address End Position (0-255) +#define R61505_VASTART 0x52 // Vertical Address Start Position (0-511) +#define R61505_VAEND 0x53 // Vertical Address End Position (0-511) + +#define R61505_DRVCTRL 0x60 // Driver Output Control +#define R61505_BASE_IMAGE_CTRL 0x61 // Base Image Display Control +#define R61505_VSCROLL_CTRL 0x6A // Vertical Scroll Control + +#define R61505_PLTPOS1 0x80 // Partial Image 1 Display Position +#define R61505_PLTSTART1 0x81 // Partial Image 1 RAM Start Address +#define R61505_PLTEND1 0x82 // Partial Image 1 RAM End Address +#define R61505_PLTPOS2 0x83 // Partial Image 2 Display Position +#define R61505_PLTSTART2 0x84 // Partial Image 2 RAM Start Address +#define R61505_PLTEND2 0x85 // Partial Image 2 RAM End Address + +#define R61505_IFCTL1 0x90 // Panel Interface Control 1 +#define R61505_IFCTL2 0x92 // Panel Interface Control 2 +#define R61505_IFCTL3 0x93 // Panel Interface Control 3 +#define R61505_IFCTL4 0x95 // Panel Interface Control 4 +#define R61505_IFCTL5 0x97 // Panel Interface Control 5 +#define R61505_IFCTL6 0x98 // Panel Interface Control 6 + +#define R61505_OSC_CTRL 0xA4 // Oscillation Control + + +static const uint16_t r61505_init[] = { + DATASIZE_16BIT, + ESC_REG(R61505_DRVCTL), R61505_DRVCTL_DATA, + ESC_REG(R61505_LCDCTL), 0x0700, // LCD Driving Wave Control + ESC_REG(R61505_ETMOD), R61505_ETMOD_DATA, + + ESC_REG(R61505_RESIZECTL), 0x0000, + ESC_REG(R61505_DISCTRL1), 0x0173, + ESC_REG(R61505_DISCTRL2), 0x0202, + ESC_REG(R61505_DISCTRL3), 0x0000, + ESC_REG(R61505_DISCTRL4), 0x0000, + ESC_REG(R61505_RGBCTRL1), 0x0000, + ESC_REG(R61505_FMARKERPOS), 0x0000, + ESC_REG(R61505_RGBCTRL2), 0x0000, + + ESC_REG(R61505_PWCTRL1), 0x17B0, + ESC_REG(R61505_PWCTRL2), 0x0037, + ESC_REG(R61505_PWCTRL3), 0x0138, + ESC_REG(R61505_PWCTRL4), 0x1700, + ESC_REG(R61505_PWCTRL7), 0x000D, + + ESC_REG(R61505_GAMCTRL1), 0x0001, + ESC_REG(R61505_GAMCTRL2), 0x0606, + ESC_REG(R61505_GAMCTRL3), 0x0304, + ESC_REG(R61505_GAMCTRL4), 0x0103, + ESC_REG(R61505_GAMCTRL5), 0x011D, + ESC_REG(R61505_GAMCTRL6), 0x0404, + ESC_REG(R61505_GAMCTRL7), 0x0404, + ESC_REG(R61505_GAMCTRL8), 0x0404, + ESC_REG(R61505_GAMCTRL9), 0x0700, + ESC_REG(R61505_GAMCTRLA), 0x0A1F, + + ESC_REG(R61505_DRVCTRL), R61505_DRVCTRL_DATA, + ESC_REG(R61505_BASE_IMAGE_CTRL), 0x0001, + ESC_REG(R61505_VSCROLL_CTRL), 0x0000, + + ESC_REG(R61505_IFCTL1), 0x0010, + ESC_REG(R61505_IFCTL2), 0x0000, + ESC_REG(R61505_IFCTL3), 0x0003, + ESC_REG(R61505_IFCTL4), 0x0101, + ESC_REG(R61505_IFCTL5), 0x0000, + ESC_REG(R61505_IFCTL6), 0x0000, + ESC_END +}; diff --git a/Marlin/src/lcd/tft_io/ssd1963.h b/Marlin/src/lcd/tft_io/ssd1963.h new file mode 100644 index 000000000000..4953a96233e8 --- /dev/null +++ b/Marlin/src/lcd/tft_io/ssd1963.h @@ -0,0 +1,131 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "tft_io.h" + +#include "../../inc/MarlinConfig.h" + +#define SSD1963_MADCTL_MY 0x80 // Row Address Order +#define SSD1963_MADCTL_MX 0x40 // Column Address Order +#define SSD1963_MADCTL_MV 0x20 // Row/Column Exchange +#define SSD1963_MADCTL_MH 0x10 // Horizontal Refresh Order +#define SSD1963_MADCTL_BGR 0x08 // RGB-BGR ORDER +#define SSD1963_MADCTL_RGB 0x00 +#define SSD1963_MADCTL_ML 0x04 // Vertical Refresh Order +#define SSD1963_MADCTL_FH 0x02 // Flip Horizontal +#define SSD1963_MADCTL_FV 0x01 // Flip Vertical + +#define SSD1963_ORIENTATION IF_0((TFT_ORIENTATION) & TFT_EXCHANGE_XY, SSD1963_MADCTL_MV) | \ + IF_0((TFT_ORIENTATION) & TFT_INVERT_X, SSD1963_MADCTL_FH) | \ + IF_0((TFT_ORIENTATION) & TFT_INVERT_Y, SSD1963_MADCTL_FV) + +#if !defined(TFT_COLOR) || TFT_COLOR == TFT_COLOR_BGR + #define SSD1963_COLOR SSD1963_MADCTL_BGR +#elif TFT_COLOR == TFT_COLOR_RGB + #define SSD1963_COLOR SSD1963_MADCTL_RGB +#endif + +#define SSD1963_MADCTL_DATA (SSD1963_ORIENTATION) | (SSD1963_COLOR) + +#define SSD1963_NOP 0x00 // No Operation +#define SSD1963_SWRESET 0x01 // Software reset +#define SSD1963_RDDPM 0x0A // Read Display Power Mode +#define SSD1963_RDDMADCTL 0x0B // Read Display MADCTL +#define SSD1963_RDDCOLMOD 0x0C // Read Display Pixel Format +#define SSD1963_RDDIM 0x0D // Read Display Image Mode +#define SSD1963_RDDSM 0x0E // Read Display Signal Mode +#define SSD1963_SLPIN 0x10 // Sleep In +#define SSD1963_SLPOUT 0x11 // Sleep Out +#define SSD1963_PTLON 0x12 // Partial Display Mode On +#define SSD1963_NORON 0x13 // Normal Display Mode On +#define SSD1963_INVOFF 0x20 // Display Inversion Off +#define SSD1963_INVON 0x21 // Display Inversion On +#define SSD1963_GAMSET 0x26 // Gamma Set +#define SSD1963_DISPOFF 0x28 // Display Off +#define SSD1963_DISPON 0x29 // Display On +#define SSD1963_CASET 0x2A // Column Address Set +#define SSD1963_RASET 0x2B // Row Address Set +#define SSD1963_RAMWR 0x2C // Memory Write +#define SSD1963_RAMRD 0x2E // Memory Read +#define SSD1963_PTLAR 0x30 // Partial Area +#define SSD1963_VSCRDEF 0x33 // Vertical Scrolling Definition +#define SSD1963_TEOFF 0x34 // Tearing Effect Line OFF +#define SSD1963_TEON 0x35 // Tearing Effect Line ON +#define SSD1963_MADCTL 0x36 // Memory Data Access Control +#define SSD1963_VSCSAD 0x37 // Vertical Scroll Start Address of RAM +#define SSD1963_IDMOFF 0x38 // Idle Mode Off +#define SSD1963_IDMON 0x39 // Idle Mode On +#define SSD1963_WRMEMC 0x3C // Write Memory Continue +#define SSD1963_RDMEMC 0x3E // Read Memory Continue +#define SSD1963_STE 0x44 // Set Tear Scanline +#define SSD1963_GSCAN 0x45 // Get Scanline +#define SSD1963_WRDISBV 0x51 // Write Display Brightness +#define SSD1963_RDDISBV 0x52 // Read Display Brightness +#define SSD1963_WRCTRLD 0x53 // Write CTRL Display +#define SSD1963_RDCTRLD 0x54 // Read CTRL Value Display +#define SSD1963_WRCACE 0x55 // Write Content Adaptive Brightness Control and Color Enhancement +#define SSD1963_RDCABC 0x56 // Read Content Adaptive Brightness Control +#define SSD1963_WRCABCMB 0x5E // Write CABC Minimum Brightness +#define SSD1963_RDCABCMB 0x5F // Read CABC Minimum Brightness +#define SSD1963_RDABCSDR 0x68 // Read Automatic Brightness Control Self-Diagnostic Result +#define SSD1963_RDDDB 0xA1 // Read Device Descriptor Block +#define SSD1963_SLCDMODE 0xB0 // Set the LCD panel mode and resolution +#define SSD1963_SHSYNC 0xB4 // Set HSYNC +#define SSD1963_GHSYNC 0xB5 // Get HSYNC +#define SSD1963_SVSYNC 0xB6 // Set VSYNC +#define SSD1963_GVSYNC 0xB7 // Get VSYNC +#define SSD1963_SGPIOCFG 0xB8 // Set GPIO Conf +#define SSD1963_SGPIOV 0xBA // Set GPIO Value +#define SSD1963_SPWMCFG 0xBE // Set PWM Conf +#define SSD1963_GPWMCFG 0xBF // Get PWM Conf +#define SSD1963_SDBCCFG 0xD0 // Set Dynamic Back Light Config +#define SSD1963_GDBCCFG 0xD1 // Get Dynamic Back Light Config +#define SSD1963_PLLON 0xE0 // PLL Enable +#define SSD1963_PLLMN 0xE2 // Set PLL Multiplier +#define SSD1963_SLSHIFT 0xE6 // Set the LSHIFT (pixel clock) frequency +#define SSD1963_COLMOD 0xF0 // Interface Pixel Format + +static const uint16_t ssd1963_init[] = { + DATASIZE_8BIT, + ESC_REG(SSD1963_PLLMN), 0x0023, 0x0002, 0x0054, + ESC_REG(SSD1963_PLLON), 0x0001, ESC_DELAY(10), + ESC_REG(SSD1963_PLLON), 0x0003, ESC_DELAY(10), + ESC_REG(SSD1963_SWRESET), ESC_DELAY(100), + + ESC_REG(SSD1963_SLSHIFT), 0x0001, 0x001F, 0x00FF, + ESC_REG(SSD1963_SLCDMODE), 0x0020, 0x0000, 0x0001, 0x00DF, 0x0001, 0x000F, 0x0000, + ESC_REG(SSD1963_SHSYNC), 0x0002, 0x0013, 0x0000, 0x0008, 0x002B, 0x0000, 0x0002, 0x0000, + ESC_REG(SSD1963_SVSYNC), 0x0001, 0x0020, 0x0000, 0x0004, 0x000C, 0x0000, 0x0002, + ESC_REG(SSD1963_SGPIOV), 0x000F, + ESC_REG(SSD1963_SGPIOCFG), 0x0007, 0x0001, + + ESC_REG(SSD1963_MADCTL), SSD1963_MADCTL_DATA, + ESC_REG(SSD1963_COLMOD), 0x0003, ESC_DELAY(1),//RBG 565 + + ESC_REG(SSD1963_NORON), + ESC_REG(SSD1963_DISPON), + + ESC_REG(SSD1963_SPWMCFG), 0x0006, 0x00f0, 0x0001, 0x00f0, 0x0000, 0x0000, + ESC_REG(SSD1963_SDBCCFG), 0x000D, + ESC_END +}; diff --git a/Marlin/src/lcd/tft_io/st7735.h b/Marlin/src/lcd/tft_io/st7735.h new file mode 100644 index 000000000000..1b0d23b6c4b9 --- /dev/null +++ b/Marlin/src/lcd/tft_io/st7735.h @@ -0,0 +1,136 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "tft_io.h" + +#include "../../inc/MarlinConfig.h" + +#define ST7735_MADCTL_MY 0x80 // Row Address Order +#define ST7735_MADCTL_MX 0x40 // Column Address Order +#define ST7735_MADCTL_MV 0x20 // Row/Column Exchange +#define ST7735_MADCTL_ML 0x10 // Vertical Refresh Order +#define ST7735_MADCTL_BGR 0x08 // RGB-BGR ORDER +#define ST7735_MADCTL_RGB 0x00 +#define ST7735_MADCTL_MH 0x04 // Horizontal Refresh Order + +#define ST7735_ORIENTATION_UP 0x00 // 128x160 ; Cable on the upper side +#define ST7735_ORIENTATION_RIGHT ST7735_MADCTL_MV | ST7735_MADCTL_MY // 160x128 ; Cable on the right side +#define ST7735_ORIENTATION_LEFT ST7735_MADCTL_MV | ST7735_MADCTL_MX // 160x128 ; Cable on the left side +#define ST7735_ORIENTATION_DOWN ST7735_MADCTL_MX | ST7735_MADCTL_MY // 128x160 ; Cable on the lower side + +#define ST7735_ORIENTATION IF_0((TFT_ORIENTATION) & TFT_EXCHANGE_XY, ST7735_MADCTL_MV) | \ + IF_0((TFT_ORIENTATION) & TFT_INVERT_X, ST7735_MADCTL_MX) | \ + IF_0((TFT_ORIENTATION) & TFT_INVERT_Y, ST7735_MADCTL_MY) + +#if !defined(TFT_COLOR) || TFT_COLOR == TFT_COLOR_RGB + #define ST7735_COLOR ST7735_MADCTL_RGB +#elif TFT_COLOR == TFT_COLOR_BGR + #define ST7735_COLOR ST7735_MADCTL_BGR +#endif + +#define ST7735_MADCTL_DATA (ST7735_ORIENTATION) | (ST7735_COLOR) + +#define ST7735_NOP 0x00 // No Operation +#define ST7735_SWRESET 0x01 // Software reset +#define ST7735_RDDID 0x04 // Read Display ID +#define ST7735_RDDST 0x09 // Read Display Status +#define ST7735_RDDPM 0x0A // Read Display Power Mode +#define ST7735_RDDMADCTL 0x0B // Read Display MADCTL +#define ST7735_RDDCOLMOD 0x0C // Read Display Pixel Format +#define ST7735_RDDIM 0x0D // Read Display Image Mode +#define ST7735_RDDSM 0x0E // Read Display Signal Mode +#define ST7735_SLPIN 0x10 // Sleep In +#define ST7735_SLPOUT 0x11 // Sleep Out +#define ST7735_PTLON 0x12 // Partial Display Mode On +#define ST7735_NORON 0x13 // Normal Display Mode On +#define ST7735_INVOFF 0x20 // Display Inversion Off +#define ST7735_INVON 0x21 // Display Inversion On +#define ST7735_GAMSET 0x26 // Gamma Set +#define ST7735_DISPOFF 0x28 // Display Off // The delay time between DISPON and DISPOFF needs 120ms at least. +#define ST7735_DISPON 0x29 // Display On +#define ST7735_CASET 0x2A // Column Address Set +#define ST7735_RASET 0x2B // Row Address Set +#define ST7735_RAMWR 0x2C // Memory Write +#define ST7735_RAMRD 0x2E // Memory Read +#define ST7735_PTLAR 0x30 // Partial Area +#define ST7735_TEOFF 0x34 // Tearing Effect Line OFF +#define ST7735_TEON 0x35 // Tearing Effect Line ON +#define ST7735_MADCTL 0x36 // Memory Data Access Control +#define ST7735_IDMOFF 0x38 // Idle Mode Off +#define ST7735_IDMON 0x39 // Idle Mode On +#define ST7735_COLMOD 0x3A // Interface Pixel Format +#define ST7735_RDID1 0xDA // Read ID1 Value +#define ST7735_RDID2 0xDB // Read ID2 Value +#define ST7735_RDID3 0xDC // Read ID3 Value + +#define ST7735_FRMCTR1 0xB1 // Frame Rate Control (In normal mode/ Full colors) +#define ST7735_FRMCTR2 0xB2 // Frame Rate Control (In Idle mode/ 8-colors) +#define ST7735_FRMCTR3 0xB3 // Frame Rate Control (In Partial mode/ full colors) +#define ST7735_INVCTR 0xB4 // Display Inversion Control +#define ST7735_DISSET5 0xB6 // Display Function set 5 +#define ST7735_PWCTR1 0xC0 // Power Control 1 +#define ST7735_PWCTR2 0xC1 // Power Control 2 +#define ST7735_PWCTR3 0xC2 // Power Control 3 (in Normal mode/ Full colors) +#define ST7735_PWCTR4 0xC3 // Power Control 4 (in Idle mode/ 8-colors) +#define ST7735_PWCTR5 0xC4 // Power Control 5 (in Partial mode/ full-colors) +#define ST7735_VMCTR1 0xC5 // VCOM Control 1 +#define ST7735_VMOFCTR 0xC7 // VCOM Offset Control +#define ST7735_WRID2 0xD1 // Write ID2 Value +#define ST7735_WRID3 0xD2 // Write ID3 Value +#define ST7735_PWCTR6 0xFC // Power Control 5 (in Partial mode + Idle mode) +#define ST7735_NVFCTR1 0xD9 // EEPROM Control Status +#define ST7735_NVFCTR2 0xDE // EEPROM Read Command +#define ST7735_NVFCTR3 0xDF // EEPROM Write Command +#define ST7735_GMCTRP1 0xE0 // Gamma (‘+’polarity) Correction Characteristics Setting +#define ST7735_GMCTRN1 0xE1 // GMCTRN1 (E1h): Gamma ‘-’polarity Correction Characteristics Setting +#define ST7735_EXTCTRL 0xF0 // Extension Command Control +#define ST7735_VCOM4L 0xFF // Vcom 4 Level Control + +static const uint16_t st7735_init[] = { + DATASIZE_8BIT, + ESC_REG(ST7735_SWRESET), ESC_DELAY(100), + ESC_REG(ST7735_SLPOUT), ESC_DELAY(20), +/* + ESC_REG(ST7735_FRMCTR1), 0x0001, 0x002C, 0x002D, + ESC_REG(ST7735_FRMCTR2), 0x0001, 0x002C, 0x002D, + ESC_REG(ST7735_FRMCTR3), 0x0001, 0x002C, 0x002D, 0x0001, 0x002C, 0x002D, + ESC_REG(ST7735_INVCTR), 0x0007, + ESC_REG(ST7735_PWCTR1), 0x00A2, 0x0002, 0x0084, + ESC_REG(ST7735_PWCTR2), 0x00C5, + ESC_REG(ST7735_PWCTR3), 0x000A, 0x0000, + ESC_REG(ST7735_PWCTR4), 0x008A, 0x002A, + ESC_REG(ST7735_PWCTR5), 0x008A, 0x00EE, + ESC_REG(ST7735_VMCTR1), 0x000E, + ESC_REG(ST7735_INVOFF), +*/ + ESC_REG(ST7735_MADCTL), ST7735_MADCTL_DATA, + ESC_REG(ST7735_COLMOD), 0x0005, + + /* Gamma Correction. Colors with 'after-reset' settings are bleak */ + ESC_REG(ST7735_GMCTRP1), 0x0002, 0x001C, 0x0007, 0x0012, 0x0037, 0x0032, 0x0029, 0x002D, 0x0029, 0x0025, 0x002B, 0x0039, 0x0000, 0x0001, 0x0003, 0x0010, + ESC_REG(ST7735_GMCTRN1), 0x0003, 0x001D, 0x0007, 0x0006, 0x002E, 0x002C, 0x0029, 0x002D, 0x002E, 0x002E, 0x0037, 0x003F, 0x0000, 0x0000, 0x0002, 0x0010, + + ESC_REG(ST7735_NORON), + ESC_REG(ST7735_DISPON), + ESC_END +}; diff --git a/Marlin/src/lcd/tft_io/st7789v.h b/Marlin/src/lcd/tft_io/st7789v.h new file mode 100644 index 000000000000..d0cf969c66ce --- /dev/null +++ b/Marlin/src/lcd/tft_io/st7789v.h @@ -0,0 +1,156 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "tft_io.h" + +#include "../../inc/MarlinConfig.h" + +#define ST7789V_MADCTL_MY 0x80 // Row Address Order +#define ST7789V_MADCTL_MX 0x40 // Column Address Order +#define ST7789V_MADCTL_MV 0x20 // Row/Column Exchange +#define ST7789V_MADCTL_ML 0x10 // Vertical Refresh Order +#define ST7789V_MADCTL_BGR 0x08 // RGB-BGR ORDER +#define ST7789V_MADCTL_RGB 0x00 +#define ST7789V_MADCTL_MH 0x04 // Horizontal Refresh Order + +#define ST7789V_ORIENTATION_UP ST7789V_MADCTL_MX | ST7789V_MADCTL_MY // 240x320 ; Cable on the upper side +#define ST7789V_ORIENTATION_RIGHT ST7789V_MADCTL_MX | ST7789V_MADCTL_MV // 320x240 ; Cable on the right side +#define ST7789V_ORIENTATION_LEFT ST7789V_MADCTL_MY | ST7789V_MADCTL_MV // 320x240 ; Cable on the left side +#define ST7789V_ORIENTATION_DOWN 0 // 240x320 ; Cable on the lower side + +#define ST7789V_ORIENTATION IF_0((TFT_ORIENTATION) & TFT_EXCHANGE_XY, ST7789V_MADCTL_MV) | \ + IF_0((TFT_ORIENTATION) & TFT_INVERT_X, ST7789V_MADCTL_MX) | \ + IF_0((TFT_ORIENTATION) & TFT_INVERT_Y, ST7789V_MADCTL_MY) + +#if !defined(TFT_COLOR) || TFT_COLOR == TFT_COLOR_RGB + #define ST7789V_COLOR ST7789V_MADCTL_RGB +#elif TFT_COLOR == TFT_COLOR_BGR + #define ST7789V_COLOR ST7789V_MADCTL_BGR +#endif + +#define ST7789V_MADCTL_DATA (ST7789V_ORIENTATION) | (ST7789V_COLOR) + +#define ST7789V_NOP 0x00 // No Operation +#define ST7789V_SWRESET 0x01 // Software reset +#define ST7789V_RDDID 0x04 // Read Display ID +#define ST7789V_RDDST 0x09 // Read Display Status +#define ST7789V_RDDPM 0x0A // Read Display Power Mode +#define ST7789V_RDDMADCTL 0x0B // Read Display MADCTL +#define ST7789V_RDDCOLMOD 0x0C // Read Display Pixel Format +#define ST7789V_RDDIM 0x0D // Read Display Image Mode +#define ST7789V_RDDSM 0x0E // Read Display Signal Mode +#define ST7789V_RDDSDR 0x0F // Read Display Self-Diagnostic Result +#define ST7789V_SLPIN 0x10 // Sleep In +#define ST7789V_SLPOUT 0x11 // Sleep Out +#define ST7789V_PTLON 0x12 // Partial Display Mode On +#define ST7789V_NORON 0x13 // Normal Display Mode On +#define ST7789V_INVOFF 0x20 // Display Inversion Off +#define ST7789V_INVON 0x21 // Display Inversion On +#define ST7789V_GAMSET 0x26 // Gamma Set +#define ST7789V_DISPOFF 0x28 // Display Off +#define ST7789V_DISPON 0x29 // Display On +#define ST7789V_CASET 0x2A // Column Address Set +#define ST7789V_RASET 0x2B // Row Address Set +#define ST7789V_RAMWR 0x2C // Memory Write +#define ST7789V_RAMRD 0x2E // Memory Read +#define ST7789V_PTLAR 0x30 // Partial Area +#define ST7789V_VSCRDEF 0x33 // Vertical Scrolling Definition +#define ST7789V_TEOFF 0x34 // Tearing Effect Line OFF +#define ST7789V_TEON 0x35 // Tearing Effect Line ON +#define ST7789V_MADCTL 0x36 // Memory Data Access Control +#define ST7789V_VSCSAD 0x37 // Vertical Scroll Start Address of RAM +#define ST7789V_IDMOFF 0x38 // Idle Mode Off +#define ST7789V_IDMON 0x39 // Idle Mode On +#define ST7789V_COLMOD 0x3A // Interface Pixel Format +#define ST7789V_WRMEMC 0x3C // Write Memory Continue +#define ST7789V_RDMEMC 0x3E // Read Memory Continue +#define ST7789V_STE 0x44 // Set Tear Scanline +#define ST7789V_GSCAN 0x45 // Get Scanline +#define ST7789V_WRDISBV 0x51 // Write Display Brightness +#define ST7789V_RDDISBV 0x52 // Read Display Brightness +#define ST7789V_WRCTRLD 0x53 // Write CTRL Display +#define ST7789V_RDCTRLD 0x54 // Read CTRL Value Display +#define ST7789V_WRCACE 0x55 // Write Content Adaptive Brightness Control and Color Enhancement +#define ST7789V_RDCABC 0x56 // Read Content Adaptive Brightness Control +#define ST7789V_WRCABCMB 0x5E // Write CABC Minimum Brightness +#define ST7789V_RDCABCMB 0x5F // Read CABC Minimum Brightness +#define ST7789V_RDABCSDR 0x68 // Read Automatic Brightness Control Self-Diagnostic Result +#define ST7789V_RDID1 0xDA // Read ID1 Value +#define ST7789V_RDID2 0xDB // Read ID2 Value +#define ST7789V_RDID3 0xDC // Read ID3 Value + +#define ST7789V_RAMCTRL 0xB0 // RAM Control +#define ST7789V_RGBCTRL 0xB1 // RGB Interface Control +#define ST7789V_PORCTRL 0xB2 // Porch Setting +#define ST7789V_FRCTRL1 0xB3 // Frame Rate Control 1 (In partial mode/ idle colors) +#define ST7789V_GCTRL 0xB7 // Gate Control +#define ST7789V_DGMEN 0xBA // Digital Gamma Enable +#define ST7789V_VCOMS 0xBB // VCOM Setting +#define ST7789V_LCMCTRL 0xC0 // LCM Control +#define ST7789V_IDSET 0xC1 // ID Code Setting +#define ST7789V_VDVVRHEN 0xC2 // VDV and VRH Command Enable +#define ST7789V_VRHS 0xC3 // VRH Set +#define ST7789V_VDVS 0xC4 // VDV Set +#define ST7789V_VCMOFSET 0xC5 // VCOM Offset Set +#define ST7789V_FRCTRL2 0xC6 // Frame Rate Control in Normal Mode +#define ST7789V_CABCCTRL 0xC7 // CABC Control +#define ST7789V_REGSEL1 0xC8 // Register Value Selection 1 +#define ST7789V_REGSEL2 0xCA // Register Value Selection 2 +#define ST7789V_PWMFRSEL 0xCC // PWM Frequency Selection +#define ST7789V_PWCTRL1 0xD0 // Power Control 1 +#define ST7789V_VAPVANEN 0xD2 // Enable VAP/VAN signal output +#define ST7789V_CMD2EN 0xDF // Command 2 Enable +#define ST7789V_PVGAMCTRL 0xE0 // Positive Voltage Gamma Control +#define ST7789V_NVGAMCTRL 0xE1 // Negative Voltage Gamma Control +#define ST7789V_DGMLUTR 0xE2 // Digital Gamma Look-up Table for Red +#define ST7789V_DGMLUTB 0xE3 // Digital Gamma Look-up Table for Blue +#define ST7789V_GATECTRL 0xE4 // Gate Control +#define ST7789V_SPI2EN 0xE7 // SPI2 Enable +#define ST7789V_PWCTRL2 0xE8 // Power Control 2 +#define ST7789V_EQCTRL 0xE9 // Equalize time control +#define ST7789V_PROMCTRL 0xEC // Program Mode Control +#define ST7789V_PROMEN 0xFA // Program Mode Enable +#define ST7789V_NVMSET 0xFC // NVM Setting +#define ST7789V_PROMACT 0xFE // Program action + +static const uint16_t st7789v_init[] = { + DATASIZE_8BIT, + ESC_REG(ST7789V_SWRESET), ESC_DELAY(100), + ESC_REG(ST7789V_SLPOUT), ESC_DELAY(20), + + ESC_REG(ST7789V_PORCTRL), 0x000C, 0x000C, 0x0000, 0x0033, 0x0033, + ESC_REG(ST7789V_GCTRL), 0x0035, + ESC_REG(ST7789V_VCOMS), 0x001F, + ESC_REG(ST7789V_LCMCTRL), 0x002C, + ESC_REG(ST7789V_VDVVRHEN), 0x0001, 0x00C3, + ESC_REG(ST7789V_VDVS), 0x0020, + ESC_REG(ST7789V_FRCTRL2), 0x000F, + ESC_REG(ST7789V_PWCTRL1), 0x00A4, 0x00A1, + + ESC_REG(ST7789V_MADCTL), ST7789V_MADCTL_DATA, + ESC_REG(ST7789V_COLMOD), 0x0055, + + ESC_REG(ST7789V_NORON), + ESC_REG(ST7789V_DISPON), + ESC_END +}; diff --git a/Marlin/src/lcd/tft_io/st7796s.h b/Marlin/src/lcd/tft_io/st7796s.h new file mode 100644 index 000000000000..8653a49ca2ef --- /dev/null +++ b/Marlin/src/lcd/tft_io/st7796s.h @@ -0,0 +1,183 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "tft_io.h" + +#include "../../inc/MarlinConfig.h" + +#define ST7796S_MADCTL_MY 0x80 // Row Address Order +#define ST7796S_MADCTL_MX 0x40 // Column Address Order +#define ST7796S_MADCTL_MV 0x20 // Row/Column Exchange +#define ST7796S_MADCTL_ML 0x10 // Vertical Refresh Order +#define ST7796S_MADCTL_BGR 0x08 // RGB-BGR ORDER +#define ST7796S_MADCTL_RGB 0x00 +#define ST7796S_MADCTL_MH 0x04 // Horizontal Refresh Order + +#define ST7796S_ORIENTATION IF_0((TFT_ORIENTATION) & TFT_EXCHANGE_XY, ST7796S_MADCTL_MV) | \ + IF_0((TFT_ORIENTATION) & TFT_INVERT_X, ST7796S_MADCTL_MX) | \ + IF_0((TFT_ORIENTATION) & TFT_INVERT_Y, ST7796S_MADCTL_MY) + +#if !defined(TFT_COLOR) || TFT_COLOR == TFT_COLOR_BGR + #define ST7796S_COLOR ST7796S_MADCTL_BGR +#elif TFT_COLOR == TFT_COLOR_RGB + #define ST7796S_COLOR ST7796S_MADCTL_RGB +#endif + +#define ST7796S_MADCTL_DATA (ST7796S_ORIENTATION) | (ST7796S_COLOR) + +#define ST7796S_NOP 0x00 // No Operation +#define ST7796S_SWRESET 0x01 // Software reset +#define ST7796S_RDDID 0x04 // Read Display ID +#define ST7796S_RDNUMED 0x05 // Read Number of the Errors on DSI +#define ST7796S_RDDST 0x09 // Read Display Status +#define ST7796S_RDDPM 0x0A // Read Display Power Mode +#define ST7796S_RDDMADCTL 0x0B // Read Display MADCTL +#define ST7796S_RDDCOLMOD 0x0C // Read Display Pixel Format +#define ST7796S_RDDIM 0x0D // Read Display Image Mode +#define ST7796S_RDDSM 0x0E // Read Display Signal Status +#define ST7796S_RDDSDR 0x0F // Read Display Self-Diagnostic Result +#define ST7796S_SLPIN 0x10 // Sleep In +#define ST7796S_SLPOUT 0x11 // Sleep Out +#define ST7796S_PTLON 0x12 // Partial Display Mode On +#define ST7796S_NORON 0x13 // Normal Display Mode On +#define ST7796S_INVOFF 0x20 // Display Inversion Off +#define ST7796S_INVON 0x21 // Display Inversion On +#define ST7796S_DISPOFF 0x28 // Display Off +#define ST7796S_DISPON 0x29 // Display On +#define ST7796S_CASET 0x2A // Column Address Set +#define ST7796S_RASET 0x2B // Row Address Set +#define ST7796S_RAMWR 0x2C // Memory Write +#define ST7796S_RAMRD 0x2E // Memory Read +#define ST7796S_PTLAR 0x30 // Partial Area +#define ST7796S_VSCRDEF 0x33 // Vertical Scrolling Definition +#define ST7796S_TEOFF 0x34 // Tearing Effect Line OFF +#define ST7796S_TEON 0x35 // Tearing Effect Line On +#define ST7796S_MADCTL 0x36 // Memory Data Access Control +#define ST7796S_VSCSAD 0x37 // Vertical Scroll Start Address of RAM +#define ST7796S_IDMOFF 0x38 // Idle Mode Off +#define ST7796S_IDMON 0x39 // Idle Mode On +#define ST7796S_COLMOD 0x3A // Interface Pixel Format +#define ST7796S_WRMEMC 0x3C // Write Memory Continue +#define ST7796S_RDMEMC 0x3E // Read Memory Continue +#define ST7796S_STE 0x44 // Set Tear ScanLine +#define ST7796S_GSCAN 0x45 // Get ScanLine +#define ST7796S_WRDISBV 0x51 // Write Display Brightness +#define ST7796S_RDDISBV 0x52 // Read Display Brightness Value +#define ST7796S_WRCTRLD 0x53 // Write CTRL Display +#define ST7796S_RDCTRLD 0x54 // Read CTRL value Display +#define ST7796S_WRCABC 0x55 // Write Adaptive Brightness Control +#define ST7796S_RDCABC 0x56 // Read Content Adaptive Brightness Control +#define ST7796S_WRCABCMB 0x5E // Write CABC Minimum Brightness +#define ST7796S_RDCABCMB 0x5F // Read CABC Minimum Brightness +#define ST7796S_RDFCS 0xAA // Read First Checksum +#define ST7796S_RDCFCS 0xAF // Read Continue Checksum +#define ST7796S_RDID1 0xDA // Read ID1 +#define ST7796S_RDID2 0xDB // Read ID2 +#define ST7796S_RDID3 0xDC // Read ID3 + +#define ST7796S_IFMODE 0xB0 // Interface Mode Control +#define ST7796S_FRMCTR1 0xB1 // Frame Rate Control (In Normal Mode/Full Colors) +#define ST7796S_FRMCTR2 0xB2 // Frame Rate Control 2 (In Idle Mode/8 colors) +#define ST7796S_FRMCTR3 0xB3 // Frame Rate Control 3(In Partial Mode/Full Colors) +#define ST7796S_DIC 0xB4 // Display Inversion Control +#define ST7796S_BPC 0xB5 // Blanking Porch Control +#define ST7796S_DFC 0xB6 // Display Function Control +#define ST7796S_EM 0xB7 // Entry Mode Set +#define ST7796S_PWR1 0xC0 // Power Control 1 +#define ST7796S_PWR2 0xC1 // Power Control 2 +#define ST7796S_PWR3 0xC2 // Power Control 3 +#define ST7796S_VCMPCTL 0xC5 // VCOM Control +#define ST7796S_VCMOST 0xC6 // VCOM Offset Register +#define ST7796S_NVMADW 0xD0 // NVM Address/Data Write +#define ST7796S_NVMBPROG 0xD1 // NVM Byte Program +#define ST7796S_NVMSTRD 0xD2 // NVM Status Read +#define ST7796S_RDID4 0xD3 // Read ID4 +#define ST7796S_PGC 0xE0 // Positive Gamma Control +#define ST7796S_NGC 0xE1 // Negative Gamma Control +#define ST7796S_DGC1 0xE2 // Digital Gamma Control 1 +#define ST7796S_DGC2 0xE3 // Digital Gamma Control 2 +#define ST7796S_DOCA 0xE8 // Display Output Ctrl Adjust +#define ST7796S_CSCON 0xF0 // Command Set Control +#define ST7796S_SPIRC 0xFB // SPI Read Control + +static const uint16_t st7796s_init[] = { + DATASIZE_8BIT, + ESC_REG(ST7796S_SWRESET), ESC_DELAY(100), + ESC_REG(ST7796S_SLPOUT), ESC_DELAY(20), + + ESC_REG(ST7796S_CSCON), 0x00C3, // enable command 2 part I + ESC_REG(ST7796S_CSCON), 0x0096, // enable command 2 part II + + ESC_REG(ST7796S_MADCTL), ST7796S_MADCTL_DATA, + ESC_REG(ST7796S_COLMOD), 0x0055, + + ESC_REG(ST7796S_DIC), 0x0001, // 1-dot inversion + ESC_REG(ST7796S_EM), 0x00C6, + + ESC_REG(ST7796S_PWR2), 0x0015, + ESC_REG(ST7796S_PWR3), 0x00AF, + ESC_REG(ST7796S_VCMPCTL), 0x0022, + ESC_REG(ST7796S_VCMOST), 0x0000, + ESC_REG(ST7796S_DOCA), 0x0040, 0x008A, 0x0000, 0x0000, 0x0029, 0x0019, 0x00A5, 0x0033, + + /* Gamma Correction. */ + ESC_REG(ST7796S_PGC), 0x00F0, 0x0004, 0x0008, 0x0009, 0x0008, 0x0015, 0x002F, 0x0042, 0x0046, 0x0028, 0x0015, 0x0016, 0x0029, 0x002D, + ESC_REG(ST7796S_NGC), 0x00F0, 0x0004, 0x0009, 0x0009, 0x0008, 0x0015, 0x002E, 0x0046, 0x0046, 0x0028, 0x0015, 0x0015, 0x0029, 0x002D, + + ESC_REG(ST7796S_NORON), + ESC_REG(ST7796S_WRCTRLD), 0x0024, + ESC_REG(ST7796S_CSCON), 0x003C, // disable command 2 part I + ESC_REG(ST7796S_CSCON), 0x0069, // disable command 2 part II + ESC_REG(ST7796S_DISPON), + ESC_END +}; + +static const uint16_t lerdge_st7796s_init[] = { + DATASIZE_8BIT, + ESC_REG(ST7796S_CSCON), 0x00C3, // enable command 2 part I + ESC_REG(ST7796S_CSCON), 0x0096, // enable command 2 part II + + ESC_REG(ST7796S_MADCTL), ST7796S_MADCTL_DATA, + ESC_REG(ST7796S_COLMOD), 0x0055, + + ESC_REG(ST7796S_DIC), 0x0001, // 1-dot inversion + ESC_REG(ST7796S_EM), 0x00C6, + + ESC_REG(ST7796S_PWR2), 0x0015, + ESC_REG(ST7796S_PWR3), 0x00AF, + ESC_REG(0xC3), 0x0009, // Register not documented in datasheet + ESC_REG(ST7796S_VCMPCTL), 0x0022, + ESC_REG(ST7796S_VCMOST), 0x0000, + ESC_REG(ST7796S_DOCA), 0x0040, 0x008A, 0x0000, 0x0000, 0x0029, 0x0019, 0x00A5, 0x0033, + + /* Gamma Correction. */ + ESC_REG(ST7796S_PGC), 0x00F0, 0x0004, 0x0008, 0x0009, 0x0008, 0x0015, 0x002F, 0x0042, 0x0046, 0x0028, 0x0015, 0x0016, 0x0029, 0x002D, + ESC_REG(ST7796S_NGC), 0x00F0, 0x0004, 0x0009, 0x0009, 0x0008, 0x0015, 0x002E, 0x0046, 0x0046, 0x0028, 0x0015, 0x0015, 0x0029, 0x002D, + + ESC_REG(ST7796S_INVON), // Display inversion ON + ESC_REG(ST7796S_WRCTRLD), 0x0024, + ESC_REG(ST7796S_CSCON), 0x003C, // disable command 2 part I + ESC_REG(ST7796S_CSCON), 0x0069, // disable command 2 part II + ESC_REG(ST7796S_DISPON), + ESC_END +}; diff --git a/Marlin/src/lcd/tft_io/tft_io.cpp b/Marlin/src/lcd/tft_io/tft_io.cpp new file mode 100644 index 000000000000..cd535458a181 --- /dev/null +++ b/Marlin/src/lcd/tft_io/tft_io.cpp @@ -0,0 +1,226 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "tft_io.h" + +#if HAS_SPI_TFT || HAS_FSMC_TFT + +#include "st7735.h" +#include "st7789v.h" +#include "st7796s.h" +#include "r65105.h" +#include "ili9328.h" +#include "ili9341.h" +#include "ili9488.h" +#include "ssd1963.h" + +#define DEBUG_OUT ENABLED(DEBUG_GRAPHICAL_TFT) +#include "../../core/debug_out.h" + +TFT_IO_DRIVER TFT_IO::io; +uint32_t TFT_IO::lcd_id = 0xFFFFFFFF; + +void TFT_IO::InitTFT() { +if (lcd_id != 0xFFFFFFFF) return; + + #if PIN_EXISTS(TFT_BACKLIGHT) + OUT_WRITE(TFT_BACKLIGHT_PIN, LOW); + #endif + + #if PIN_EXISTS(TFT_RESET) + OUT_WRITE(TFT_RESET_PIN, HIGH); + delay(10); + OUT_WRITE(TFT_RESET_PIN, LOW); + delay(10); + OUT_WRITE(TFT_RESET_PIN, HIGH); + #endif + + #if PIN_EXISTS(TFT_BACKLIGHT) + OUT_WRITE(TFT_BACKLIGHT_PIN, DISABLED(DELAYED_BACKLIGHT_INIT)); + #endif + + // io.Init(); + delay(100); + + #if TFT_DRIVER != AUTO + lcd_id = TFT_DRIVER; + #endif + + #if TFT_DRIVER == ST7735 + write_esc_sequence(st7735_init); + #elif TFT_DRIVER == SSD1963 + write_esc_sequence(ssd1963_init); + #elif TFT_DRIVER == ST7789 + write_esc_sequence(st7789v_init); + #elif TFT_DRIVER == ST7796 + write_esc_sequence(st7796s_init); + #elif TFT_DRIVER == R61505 + write_esc_sequence(r61505_init); + #elif TFT_DRIVER == ILI9328 + write_esc_sequence(ili9328_init); + #elif TFT_DRIVER == ILI9341 + write_esc_sequence(ili9341_init); + #elif TFT_DRIVER == ILI9488 + write_esc_sequence(ili9488_init); + #elif TFT_DRIVER == LERDGE_ST7796 + lcd_id = ST7796; + write_esc_sequence(lerdge_st7796s_init); + + #elif TFT_DRIVER == AUTO // autodetect + + lcd_id = io.GetID() & 0xFFFF; + + switch (lcd_id) { + case ST7796: // ST7796S 480x320 + DEBUG_ECHO_MSG(" ST7796S"); + write_esc_sequence(st7796s_init); + break; + case ST7789: // ST7789V 320x240 + DEBUG_ECHO_MSG(" ST7789V"); + write_esc_sequence(st7789v_init); + break; + case SSD1963: // SSD1963 + DEBUG_ECHO_MSG(" SSD1963"); + write_esc_sequence(ssd1963_init); + break; + case ST7735: // ST7735 160x128 + DEBUG_ECHO_MSG(" ST7735"); + write_esc_sequence(st7735_init); + break; + case R61505: // R61505U 320x240 + DEBUG_ECHO_MSG(" R61505U"); + write_esc_sequence(r61505_init); + break; + case ILI9328: // ILI9328 320x240 + DEBUG_ECHO_MSG(" ILI9328"); + write_esc_sequence(ili9328_init); + break; + case ILI9341: // ILI9341 320x240 + DEBUG_ECHO_MSG(" ILI9341"); + write_esc_sequence(ili9341_init); + break; + case ILI9488: // ILI9488 480x320 + case ILI9488_ID1: // 0x8066 ILI9488 480x320 + DEBUG_ECHO_MSG(" ILI9488"); + write_esc_sequence(ili9488_init); + break; + default: + lcd_id = 0; + } + #else + #error Unsupported TFT driver + #endif + + #if PIN_EXISTS(TFT_BACKLIGHT) && ENABLED(DELAYED_BACKLIGHT_INIT) + OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH); + #endif +} + +void TFT_IO::set_window(uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) { + #ifdef OFFSET_X + Xmin += OFFSET_X; Xmax += OFFSET_X; + #endif + #ifdef OFFSET_Y + Ymin += OFFSET_Y; Ymax += OFFSET_Y; + #endif + + switch (lcd_id) { + case ST7735: // ST7735 160x128 + case ST7789: // ST7789V 320x240 + case ST7796: // ST7796 480x320 + case ILI9341: // ILI9341 320x240 + case ILI9488: // ILI9488 480x320 + case SSD1963: // SSD1963 + case ILI9488_ID1: // 0x8066 ILI9488 480x320 + io.DataTransferBegin(DATASIZE_8BIT); + + // CASET: Column Address Set + io.WriteReg(ILI9341_CASET); + io.WriteData((Xmin >> 8) & 0xFF); + io.WriteData(Xmin & 0xFF); + io.WriteData((Xmax >> 8) & 0xFF); + io.WriteData(Xmax & 0xFF); + + // RASET: Row Address Set + io.WriteReg(ILI9341_PASET); + io.WriteData((Ymin >> 8) & 0xFF); + io.WriteData(Ymin & 0xFF); + io.WriteData((Ymax >> 8) & 0xFF); + io.WriteData(Ymax & 0xFF); + + // RAMWR: Memory Write + io.WriteReg(ILI9341_RAMWR); + break; + case R61505: // R61505U 320x240 + case ILI9328: // ILI9328 320x240 + io.DataTransferBegin(DATASIZE_16BIT); + + // Mind the mess: with landscape screen orientation 'Horizontal' is Y and 'Vertical' is X + io.WriteReg(ILI9328_HASTART); + io.WriteData(Ymin); + io.WriteReg(ILI9328_HAEND); + io.WriteData(Ymax); + io.WriteReg(ILI9328_VASTART); + io.WriteData(Xmin); + io.WriteReg(ILI9328_VAEND); + io.WriteData(Xmax); + + io.WriteReg(ILI9328_HASET); + io.WriteData(Ymin); + io.WriteReg(ILI9328_VASET); + io.WriteData(Xmin); + + io.WriteReg(ILI9328_RAMWR); + break; + default: + break; + } + + io.DataTransferEnd(); +} + +void TFT_IO::write_esc_sequence(const uint16_t *Sequence) { + uint16_t dataWidth, data; + + dataWidth = *Sequence++; + io.DataTransferBegin(dataWidth); + + for (;;) { + data = *Sequence++; + if (data != 0xFFFF) { + io.WriteData(data); + continue; + } + data = *Sequence++; + if (data == 0x7FFF) return; + if (data == 0xFFFF) + io.WriteData(0xFFFF); + else if (data & 0x8000) + delay(data & 0x7FFF); + else if ((data & 0xFF00) == 0) + io.WriteReg(data); + } + + io.DataTransferEnd(); +} + +#endif // HAS_SPI_TFT || HAS_FSMC_TFT diff --git a/Marlin/src/lcd/tft_io/tft_io.h b/Marlin/src/lcd/tft_io/tft_io.h new file mode 100644 index 000000000000..63d6936ac0b8 --- /dev/null +++ b/Marlin/src/lcd/tft_io/tft_io.h @@ -0,0 +1,124 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../../inc/MarlinConfig.h" + +#if HAS_SPI_TFT || HAS_FSMC_TFT + +#if HAS_SPI_TFT + #include HAL_PATH(../../HAL, tft/tft_spi.h) +#elif HAS_FSMC_TFT + #include HAL_PATH(../../HAL, tft/tft_fsmc.h) +#else + #error "TFT IO only supports SPI or FSMC interface" +#endif + +#define TFT_EXCHANGE_XY (1UL << 1) +#define TFT_INVERT_X (1UL << 2) +#define TFT_INVERT_Y (1UL << 3) + +#define TFT_NO_ROTATION (0x00) +#define TFT_ROTATE_90 (TFT_EXCHANGE_XY | TFT_INVERT_X) +#define TFT_ROTATE_180 (TFT_INVERT_X | TFT_INVERT_Y) +#define TFT_ROTATE_270 (TFT_EXCHANGE_XY | TFT_INVERT_Y) + +#define TFT_MIRROR_X (TFT_INVERT_Y) +#define TFT_MIRROR_Y (TFT_INVERT_X) + +#define TFT_ROTATE_90_MIRROR_X (TFT_ROTATE_90 ^ TFT_INVERT_Y) +#define TFT_ROTATE_90_MIRROR_Y (TFT_ROTATE_90 ^ TFT_INVERT_X) + +#define TFT_ROTATE_180_MIRROR_X (TFT_ROTATE_180 ^ TFT_INVERT_Y) +#define TFT_ROTATE_180_MIRROR_Y (TFT_ROTATE_180 ^ TFT_INVERT_X) + +#define TFT_ROTATE_270_MIRROR_X (TFT_ROTATE_270 ^ TFT_INVERT_Y) +#define TFT_ROTATE_270_MIRROR_Y (TFT_ROTATE_270 ^ TFT_INVERT_X) + +// TFT_ROTATION is user configurable +#ifndef TFT_ROTATION + #define TFT_ROTATION TFT_NO_ROTATION +#endif + + +// TFT_ORIENTATION is the "sum" of TFT_DEFAULT_ORIENTATION plus user TFT_ROTATION +#define TFT_ORIENTATION ((TFT_DEFAULT_ORIENTATION) ^ (TFT_ROTATION)) + +#define TFT_COLOR_RGB (1UL << 3) +#define TFT_COLOR_BGR (1UL << 4) + +// Each TFT Driver is responsible for its default color mode. +// #ifndef TFT_COLOR +// #define TFT_COLOR TFT_COLOR_RGB +// #endif + +#define SSD1963 0x5761 +#define ST7735 0x89F0 +#define ST7789 0x8552 +#define ST7796 0x7796 +#define R61505 0x1505 +#define ILI9328 0x9328 +#define ILI9341 0x9341 +#define ILI9488 0x9488 +#define ILI9488_ID1 0x8066 //Some ILI9488 have 0x8066 in the 0x04 +#define LERDGE_ST7796 0xFFFE +#define AUTO 0xFFFF + +#ifndef TFT_DRIVER + #define TFT_DRIVER AUTO +#endif + +#define ESC_REG(x) 0xFFFF, 0x00FF & (uint16_t)x +#define ESC_DELAY(x) 0xFFFF, 0x8000 | (x & 0x7FFF) +#define ESC_END 0xFFFF, 0x7FFF +#define ESC_FFFF 0xFFFF, 0xFFFF + +class TFT_IO { +public: + static TFT_IO_DRIVER io; + + static void InitTFT(); + static void set_window(uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax); + static void write_esc_sequence(const uint16_t *Sequence); + + // Deletaged methods + inline static void Init() { io.Init(); }; + inline static bool isBusy() { return io.isBusy(); }; + inline static void Abort() { io.Abort(); }; + inline static uint32_t GetID() { return io.GetID(); }; + + inline static void DataTransferBegin(uint16_t DataWidth = DATASIZE_16BIT) { io.DataTransferBegin(DataWidth); } + inline static void DataTransferEnd() { io.DataTransferEnd(); }; + // inline static void DataTransferAbort() { io.DataTransferAbort(); }; + + inline static void WriteData(uint16_t Data) { io.WriteData(Data); }; + inline static void WriteReg(uint16_t Reg) { io.WriteReg(Reg); }; + + inline static void WriteSequence(uint16_t *Data, uint16_t Count) { io.WriteSequence(Data, Count); }; + // static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &Data, Count); } + inline static void WriteMultiple(uint16_t Color, uint32_t Count) { io.WriteMultiple(Color, Count); }; + +protected: + static uint32_t lcd_id; +}; + +#endif // HAS_SPI_TFT || HAS_FSMC_TFT diff --git a/Marlin/src/lcd/thermistornames.h b/Marlin/src/lcd/thermistornames.h index 7a464c30abc1..37f285d483cd 100644 --- a/Marlin/src/lcd/thermistornames.h +++ b/Marlin/src/lcd/thermistornames.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -50,8 +50,14 @@ // Standard thermistors #elif THERMISTOR_ID == 1 #define THERMISTOR_NAME "EPCOS 100K" +#elif THERMISTOR_ID == 331 + #define THERMISTOR_NAME "3.3V EPCOS 100K (MEGA)" +#elif THERMISTOR_ID == 332 + #define THERMISTOR_NAME "3.3V EPCOS 100K (DUE)" #elif THERMISTOR_ID == 2 #define THERMISTOR_NAME "ATC 204GT-2" +#elif THERMISTOR_ID == 202 + #define THERMISTOR_NAME "200k Copymaster 3D" #elif THERMISTOR_ID == 3 #define THERMISTOR_NAME "Mendel-parts" #elif THERMISTOR_ID == 4 @@ -60,6 +66,8 @@ #define THERMISTOR_NAME "ATC 104GT-2" #elif THERMISTOR_ID == 501 #define THERMISTOR_NAME "Zonestar (Tronxy X3A)" +#elif THERMISTOR_ID == 502 + #define THERMISTOR_NAME "Zonestar (P802M Hot Bed)" #elif THERMISTOR_ID == 512 #define THERMISTOR_NAME "RPW-Ultra" #elif THERMISTOR_ID == 6 @@ -96,8 +104,12 @@ #define THERMISTOR_NAME "Hephestos 2" #elif THERMISTOR_ID == 75 #define THERMISTOR_NAME "MGB18" +#elif THERMISTOR_ID == 99 + #define THERMISTOR_NAME "100k with 10k pull-up" // Modified thermistors +#elif THERMISTOR_ID == 30 + #define THERMISTOR_NAME "Kis3d EN AW NTC100K/3950" #elif THERMISTOR_ID == 51 #define THERMISTOR_NAME "EPCOS 1K" #elif THERMISTOR_ID == 52 diff --git a/Marlin/src/lcd/touch/touch_buttons.cpp b/Marlin/src/lcd/touch/touch_buttons.cpp new file mode 100644 index 000000000000..7d25c0df7eb9 --- /dev/null +++ b/Marlin/src/lcd/touch/touch_buttons.cpp @@ -0,0 +1,112 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfig.h" + +#if HAS_TOUCH_XPT2046 + +#include "touch_buttons.h" +#include "../scaled_tft.h" + +#include HAL_PATH(../../HAL, tft/xpt2046.h) +XPT2046 touchIO; + +#include "../../lcd/ultralcd.h" // For EN_C bit mask + +/** + * Draw and Touch processing + * + * LCD_PIXEL_WIDTH/HEIGHT (128x64) is the (emulated DOGM) Pixel Drawing resolution. + * TOUCH_SENSOR_WIDTH/HEIGHT (320x240) is the Touch Area resolution. + * TFT_WIDTH/HEIGHT (320x240 or 480x320) is the Actual (FSMC) Display resolution. + * + * - All native (u8g) drawing is done in LCD_PIXEL_* (128x64) + * - The DOGM pixels are is upscaled 2-3x (as needed) for display. + * - Touch coordinates use TOUCH_SENSOR_* resolution and are converted to + * click and scroll-wheel events (emulating of a common DOGM display). + * + * TOUCH_SCREEN resolution exists to fit our calibration values. The original touch code was made + * and originally calibrated for 320x240. If you decide to change the resolution of the touch code, + * new calibration values will be needed. + * + * The Marlin menus are drawn scaled in the upper region of the screen. The bottom region (in a + * fixed location in TOUCH_SCREEN* coordinate space) is used for 4 general-purpose buttons to + * navigate and select menu items. Both regions are touchable. + * + * The Marlin screen touchable area starts at TFT_PIXEL_OFFSET_X/Y (translated to SCREEN_PCT_LEFT/TOP) + * and spans LCD_PIXEL_WIDTH/HEIGHT (scaled to SCREEN_PCT_WIDTH/HEIGHT). + */ + +// Touch sensor resolution independent of display resolution +#define TOUCH_SENSOR_WIDTH 320 +#define TOUCH_SENSOR_HEIGHT 240 + +#define SCREEN_PCT_WIDE(X) ((X) * (TOUCH_SENSOR_WIDTH) / (TFT_WIDTH)) +#define SCREEN_PCT_HIGH(Y) ((Y) * (TOUCH_SENSOR_HEIGHT) / (TFT_HEIGHT)) + +#define SCREEN_PCT_LEFT SCREEN_PCT_WIDE(TFT_PIXEL_OFFSET_X) +#define SCREEN_PCT_TOP SCREEN_PCT_HIGH(TFT_PIXEL_OFFSET_Y) +#define SCREEN_PCT_WIDTH SCREEN_PCT_WIDE((GRAPHICAL_TFT_UPSCALE) * (LCD_PIXEL_WIDTH)) +#define SCREEN_PCT_HEIGHT SCREEN_PCT_HIGH((GRAPHICAL_TFT_UPSCALE) * (LCD_PIXEL_HEIGHT)) + +// Coordinates in terms of 240-unit-tall touch area +#define BUTTON_AREA_TOP 175 +#define BUTTON_AREA_BOT 234 + +TouchButtons touch; + +void TouchButtons::init() { touchIO.Init(); } + +uint8_t TouchButtons::read_buttons() { + #ifdef HAS_WIRED_LCD + int16_t x, y; + + if (!touchIO.getRawPoint(&x, &y)) return 0; + + x = uint16_t((uint32_t(x) * XPT2046_X_CALIBRATION) >> 16) + XPT2046_X_OFFSET; + y = uint16_t((uint32_t(y) * XPT2046_Y_CALIBRATION) >> 16) + XPT2046_Y_OFFSET; + + #if (TFT_ROTATION & TFT_ROTATE_180) + x = TOUCH_SENSOR_WIDTH - x; + y = TOUCH_SENSOR_HEIGHT - y; + #endif + + // Touch within the button area simulates an encoder button + if (y > BUTTON_AREA_TOP && y < BUTTON_AREA_BOT) + return WITHIN(x, 14, 77) ? EN_D + : WITHIN(x, 90, 153) ? EN_A + : WITHIN(x, 166, 229) ? EN_B + : WITHIN(x, 242, 305) ? EN_C + : 0; + + if ( !WITHIN(x, SCREEN_PCT_LEFT, SCREEN_PCT_LEFT + SCREEN_PCT_WIDTH) + || !WITHIN(y, SCREEN_PCT_TOP, SCREEN_PCT_TOP + SCREEN_PCT_HEIGHT) + ) return 0; + + // Column and row above BUTTON_AREA_TOP + int8_t col = (x - (SCREEN_PCT_LEFT)) * (LCD_WIDTH) / (SCREEN_PCT_WIDTH), + row = (y - (SCREEN_PCT_TOP)) * (LCD_HEIGHT) / (SCREEN_PCT_HEIGHT); + + // Send the touch to the UI (which will simulate the encoder wheel) + MarlinUI::screen_click(row, col, x, y); + #endif + return 0; +} + +#endif // HAS_TOUCH_XPT2046 diff --git a/Marlin/src/lcd/touch/touch_buttons.h b/Marlin/src/lcd/touch/touch_buttons.h new file mode 100644 index 000000000000..451e5a5a37ca --- /dev/null +++ b/Marlin/src/lcd/touch/touch_buttons.h @@ -0,0 +1,29 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include + +class TouchButtons { +public: + static void init(); + static uint8_t read_buttons(); +}; + +extern TouchButtons touch; diff --git a/Marlin/src/lcd/ultralcd.cpp b/Marlin/src/lcd/ultralcd.cpp index 422c8b0b81c4..7003d13fdd7a 100644 --- a/Marlin/src/lcd/ultralcd.cpp +++ b/Marlin/src/lcd/ultralcd.cpp @@ -16,11 +16,11 @@ * 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 . + * along with this program. If not, see . * */ -#include "../inc/MarlinConfigPre.h" +#include "../inc/MarlinConfig.h" #ifdef LED_BACKLIGHT_TIMEOUT #include "../feature/leds/leds.h" @@ -40,8 +40,8 @@ MarlinUI ui; #include "../gcode/queue.h" #include "fontutils.h" #include "../sd/cardreader.h" - #if ENABLED(EXTENSIBLE_UI) - #define START_OF_UTF8_CHAR(C) (((C) & 0xC0u) != 0x80u) + #if EITHER(EXTENSIBLE_UI, DWIN_CREALITY_LCD) + #define START_OF_UTF8_CHAR(C) (((C) & 0xC0u) != 0x80U) #endif #endif @@ -49,18 +49,20 @@ MarlinUI ui; bool MarlinUI::wait_for_move; // = false #endif -#if HAS_SPI_LCD +constexpr uint8_t epps = ENCODER_PULSES_PER_STEP; + +#if HAS_WIRED_LCD #if ENABLED(STATUS_MESSAGE_SCROLLING) uint8_t MarlinUI::status_scroll_offset; // = 0 constexpr uint8_t MAX_MESSAGE_LENGTH = _MAX(LONG_FILENAME_LENGTH, MAX_LANG_CHARSIZE * 2 * (LCD_WIDTH)); #else constexpr uint8_t MAX_MESSAGE_LENGTH = MAX_LANG_CHARSIZE * (LCD_WIDTH); #endif -#elif ENABLED(EXTENSIBLE_UI) +#elif EITHER(EXTENSIBLE_UI, DWIN_CREALITY_LCD) constexpr uint8_t MAX_MESSAGE_LENGTH = 63; #endif -#if HAS_SPI_LCD || ENABLED(EXTENSIBLE_UI) +#if EITHER(HAS_WIRED_LCD, EXTENSIBLE_UI) uint8_t MarlinUI::alert_level; // = 0 char MarlinUI::status_message[MAX_MESSAGE_LENGTH + 1]; #endif @@ -72,38 +74,69 @@ MarlinUI ui; #endif #endif -#if ENABLED(PCA9632_BUZZER) || USE_BEEPER +#if EITHER(PCA9632_BUZZER, USE_BEEPER) #include "../libs/buzzer.h" // for BUZZ() macro #if ENABLED(PCA9632_BUZZER) #include "../feature/leds/pca9632.h" #endif void MarlinUI::buzz(const long duration, const uint16_t freq) { #if ENABLED(PCA9632_BUZZER) - pca9632_buzz(duration, freq); + PCA9632_buzz(duration, freq); #elif USE_BEEPER buzzer.tone(duration, freq); #endif } #endif -#if HAS_SPI_LCD +#if PREHEAT_COUNT + preheat_t MarlinUI::material_preset[PREHEAT_COUNT]; // Initialized by settings.load() + PGM_P MarlinUI::get_preheat_label(const uint8_t m) { + #ifdef PREHEAT_1_LABEL + static PGMSTR(preheat_0_label, PREHEAT_1_LABEL); + #endif + #ifdef PREHEAT_2_LABEL + static PGMSTR(preheat_1_label, PREHEAT_2_LABEL); + #endif + #ifdef PREHEAT_3_LABEL + static PGMSTR(preheat_2_label, PREHEAT_3_LABEL); + #endif + #ifdef PREHEAT_4_LABEL + static PGMSTR(preheat_3_label, PREHEAT_4_LABEL); + #endif + #ifdef PREHEAT_5_LABEL + static PGMSTR(preheat_4_label, PREHEAT_5_LABEL); + #endif + + #define _PLBL(N) preheat_##N##_label, + static PGM_P const preheat_labels[PREHEAT_COUNT] PROGMEM = { REPEAT(PREHEAT_COUNT, _PLBL) }; + + return (PGM_P)pgm_read_ptr(&preheat_labels[m]); + } +#endif + +#if HAS_WIRED_LCD -#if HAS_GRAPHICAL_LCD +#if HAS_MARLINUI_U8GLIB #include "dogm/ultralcd_DOGM.h" #endif #include "lcdprint.h" #include "../sd/cardreader.h" + #include "../module/temperature.h" #include "../module/planner.h" #include "../module/motion.h" +#if HAS_LCD_MENU + #include "../module/settings.h" +#endif + #if ENABLED(AUTO_BED_LEVELING_UBL) #include "../feature/bedlevel/bedlevel.h" #endif -#if HAS_TRINAMIC +#if HAS_TRINAMIC_CONFIG #include "../feature/tmc_util.h" #endif @@ -111,21 +144,22 @@ MarlinUI ui; #include "../module/thermistor/thermistors.h" #endif +#if HAS_POWER_MONITOR + #include "../feature/power_monitor.h" +#endif + #if HAS_ENCODER_ACTION volatile uint8_t MarlinUI::buttons; #if HAS_SLOW_BUTTONS volatile uint8_t MarlinUI::slow_buttons; #endif - #if ENABLED(TOUCH_BUTTONS) - #include "../feature/touch/xpt2046.h" + #if HAS_TOUCH_XPT2046 + #include "touch/touch_buttons.h" + bool MarlinUI::on_edit_screen = false; #endif #endif -#if ENABLED(INIT_SDCARD_ON_BOOT) - uint8_t lcd_sd_status; -#endif - -#if HAS_LCD_MENU && LCD_TIMEOUT_TO_STATUS +#if HAS_LCD_MENU && LCD_TIMEOUT_TO_STATUS > 0 bool MarlinUI::defer_return_to_status; #endif @@ -137,7 +171,7 @@ uint8_t MarlinUI::lcd_status_update_delay = 1; // First update one loop delayed millis_t MarlinUI::next_button_update_ms; // = 0 -#if HAS_GRAPHICAL_LCD +#if HAS_MARLINUI_U8GLIB bool MarlinUI::drawing_screen, MarlinUI::first_page; // = false #endif @@ -147,40 +181,41 @@ millis_t MarlinUI::next_button_update_ms; // = 0 volatile int8_t encoderDiff; // Updated in update_buttons, added to encoderPosition every LCD update #endif -#if HAS_LCD_MENU - #include "menu/menu.h" - #include "../sd/cardreader.h" +#if ENABLED(SDSUPPORT) - #if ENABLED(SDSUPPORT) + #include "../sd/cardreader.h" - #if ENABLED(SCROLL_LONG_FILENAMES) - uint8_t MarlinUI::filename_scroll_pos, MarlinUI::filename_scroll_max; - #endif + #if MARLINUI_SCROLL_NAME + uint8_t MarlinUI::filename_scroll_pos, MarlinUI::filename_scroll_max; + #endif - const char * MarlinUI::scrolled_filename(CardReader &theCard, const uint8_t maxlen, uint8_t hash, const bool doScroll) { - const char *outstr = theCard.longest_filename(); - if (theCard.longFilename[0]) { - #if ENABLED(SCROLL_LONG_FILENAMES) - if (doScroll) { - for (uint8_t l = FILENAME_LENGTH; l--;) - hash = ((hash << 1) | (hash >> 7)) ^ theCard.filename[l]; // rotate, xor - static uint8_t filename_scroll_hash; - if (filename_scroll_hash != hash) { // If the hash changed... - filename_scroll_hash = hash; // Save the new hash - filename_scroll_max = _MAX(0, utf8_strlen(theCard.longFilename) - maxlen); // Update the scroll limit - filename_scroll_pos = 0; // Reset scroll to the start - lcd_status_update_delay = 8; // Don't scroll right away - } - outstr += filename_scroll_pos; + const char * MarlinUI::scrolled_filename(CardReader &theCard, const uint8_t maxlen, uint8_t hash, const bool doScroll) { + const char *outstr = theCard.longest_filename(); + if (theCard.longFilename[0]) { + #if MARLINUI_SCROLL_NAME + if (doScroll) { + for (uint8_t l = FILENAME_LENGTH; l--;) + hash = ((hash << 1) | (hash >> 7)) ^ theCard.filename[l]; // rotate, xor + static uint8_t filename_scroll_hash; + if (filename_scroll_hash != hash) { // If the hash changed... + filename_scroll_hash = hash; // Save the new hash + filename_scroll_max = _MAX(0, utf8_strlen(theCard.longFilename) - maxlen); // Update the scroll limit + filename_scroll_pos = 0; // Reset scroll to the start + lcd_status_update_delay = 8; // Don't scroll right away } - #else - theCard.longFilename[maxlen] = '\0'; // cutoff at screen edge - #endif - } - return outstr; + outstr += filename_scroll_pos; + } + #else + theCard.longFilename[maxlen] = '\0'; // cutoff at screen edge + #endif } + return outstr; + } - #endif +#endif + +#if HAS_LCD_MENU + #include "menu/menu.h" screenFunc_t MarlinUI::currentScreen; // Initialized in CTOR bool MarlinUI::screen_changed; @@ -198,13 +233,12 @@ millis_t MarlinUI::next_button_update_ms; // = 0 int8_t MarlinUI::encoderDirection = ENCODERBASE; #endif - #if ENABLED(TOUCH_BUTTONS) + #if HAS_TOUCH_XPT2046 uint8_t MarlinUI::touch_buttons; uint8_t MarlinUI::repeat_delay; #endif bool MarlinUI::lcd_clicked; - float move_menu_scale; bool MarlinUI::use_click() { const bool click = lcd_clicked; @@ -227,7 +261,7 @@ millis_t MarlinUI::next_button_update_ms; // = 0 SETCURSOR(col, row); if (!string) return; - auto _newline = [&col, &row]() { + auto _newline = [&col, &row]{ col = 0; row++; // Move col to string len (plus space) SETCURSOR(0, row); // Simulate carriage return }; @@ -342,26 +376,13 @@ void MarlinUI::init() { #endif // HAS_SHIFT_ENCODER - #if ENABLED(SDSUPPORT) - #if PIN_EXISTS(SD_DETECT) - SET_INPUT_PULLUP(SD_DETECT_PIN); - #endif - #if ENABLED(INIT_SDCARD_ON_BOOT) - lcd_sd_status = 2; // UNKNOWN - #endif - #endif - - #if HAS_ENCODER_ACTION - #if HAS_SLOW_BUTTONS - slow_buttons = 0; - #endif + #if BOTH(HAS_ENCODER_ACTION, HAS_SLOW_BUTTONS) + slow_buttons = 0; #endif update_buttons(); - #if HAS_ENCODER_ACTION - encoderDiff = 0; - #endif + TERN_(HAS_ENCODER_ACTION, encoderDiff = 0); } bool MarlinUI::get_blink() { @@ -379,7 +400,7 @@ bool MarlinUI::get_blink() { ///////////// Keypad Handling ////////////// //////////////////////////////////////////// -#if ENABLED(REPRAPWORLD_KEYPAD) && HAS_ENCODER_ACTION +#if BOTH(REPRAPWORLD_KEYPAD, HAS_ENCODER_ACTION) volatile uint8_t MarlinUI::keypad_buttons; @@ -390,8 +411,8 @@ bool MarlinUI::get_blink() { void lcd_move_z(); void _reprapworld_keypad_move(const AxisEnum axis, const int16_t dir) { - move_menu_scale = REPRAPWORLD_KEYPAD_MOVE_STEP; - encoderPosition = dir; + ui.manual_move.menu_scale = REPRAPWORLD_KEYPAD_MOVE_STEP; + ui.encoderPosition = dir; switch (axis) { case X_AXIS: lcd_move_x(); break; case Y_AXIS: lcd_move_y(); break; @@ -421,13 +442,13 @@ bool MarlinUI::get_blink() { #endif { #if HAS_LCD_MENU - if (RRK(EN_KEYPAD_UP)) encoderPosition -= ENCODER_PULSES_PER_STEP; - else if (RRK(EN_KEYPAD_DOWN)) encoderPosition += ENCODER_PULSES_PER_STEP; + if (RRK(EN_KEYPAD_UP)) encoderPosition -= epps; + else if (RRK(EN_KEYPAD_DOWN)) encoderPosition += epps; else if (RRK(EN_KEYPAD_LEFT)) { MenuItem_back::action(); quick_feedback(); } else if (RRK(EN_KEYPAD_RIGHT)) encoderPosition = 0; #else - if (RRK(EN_KEYPAD_UP) || RRK(EN_KEYPAD_LEFT)) encoderPosition -= ENCODER_PULSES_PER_STEP; - else if (RRK(EN_KEYPAD_DOWN) || RRK(EN_KEYPAD_RIGHT)) encoderPosition += ENCODER_PULSES_PER_STEP; + if (RRK(EN_KEYPAD_UP) || RRK(EN_KEYPAD_LEFT)) encoderPosition -= epps; + else if (RRK(EN_KEYPAD_DOWN) || RRK(EN_KEYPAD_RIGHT)) encoderPosition += epps; #endif } #endif @@ -489,7 +510,7 @@ bool MarlinUI::get_blink() { * This is very display-dependent, so the lcd implementation draws this. */ -#if ENABLED(LCD_PROGRESS_BAR) +#if ENABLED(LCD_PROGRESS_BAR) && !IS_TFTGLCD_PANEL millis_t MarlinUI::progress_bar_ms; // = 0 #if PROGRESS_MSG_EXPIRE > 0 millis_t MarlinUI::expire_status_ms; // = 0 @@ -498,11 +519,9 @@ bool MarlinUI::get_blink() { void MarlinUI::status_screen() { - #if HAS_LCD_MENU - ENCODER_RATE_MULTIPLY(false); - #endif + TERN_(HAS_LCD_MENU, ENCODER_RATE_MULTIPLY(false)); - #if ENABLED(LCD_PROGRESS_BAR) + #if ENABLED(LCD_PROGRESS_BAR) && !IS_TFTGLCD_PANEL // // HD44780 implements the following message blinking and @@ -524,7 +543,7 @@ void MarlinUI::status_screen() { #if PROGRESS_MSG_EXPIRE > 0 // Handle message expire - if (expire_status_ms > 0) { + if (expire_status_ms) { // Expire the message if a job is active and the bar has ticks if (get_progress_percent() > 2 && !print_job_timer.isPaused()) { @@ -545,7 +564,6 @@ void MarlinUI::status_screen() { #endif // LCD_PROGRESS_BAR #if HAS_LCD_MENU - if (use_click()) { #if BOTH(FILAMENT_LCD_DISPLAY, SDSUPPORT) next_filament_display = millis() + 5000UL; // Show status message for 5s @@ -581,7 +599,7 @@ void MarlinUI::status_screen() { if (old_frm != new_frm) { feedrate_percentage = new_frm; encoderPosition = 0; - #if HAS_BUZZER && ENABLED(BEEP_ON_FEEDRATE_CHANGE) + #if BOTH(HAS_BUZZER, BEEP_ON_FEEDRATE_CHANGE) static millis_t next_beep; #ifndef GOT_MS const millis_t ms = millis(); @@ -601,9 +619,7 @@ void MarlinUI::status_screen() { void MarlinUI::kill_screen(PGM_P lcd_error, PGM_P lcd_component) { init(); status_printf_P(1, PSTR(S_FMT ": " S_FMT), lcd_error, lcd_component); - #if HAS_LCD_MENU - return_to_status(); - #endif + TERN_(HAS_LCD_MENU, return_to_status()); // RED ALERT. RED ALERT. #ifdef LED_BACKLIGHT_TIMEOUT @@ -619,9 +635,7 @@ void MarlinUI::kill_screen(PGM_P lcd_error, PGM_P lcd_component) { void MarlinUI::quick_feedback(const bool clear_buttons/*=true*/) { - #if HAS_LCD_MENU - refresh(); - #endif + TERN_(HAS_LCD_MENU, refresh()); #if HAS_ENCODER_ACTION if (clear_buttons) buttons = 0; @@ -630,15 +644,12 @@ void MarlinUI::quick_feedback(const bool clear_buttons/*=true*/) { UNUSED(clear_buttons); #endif - #if HAS_BUZZER - // Buzz and wait. Is the delay needed for buttons to settle? - buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ); - #if HAS_LCD_MENU - #if USE_BEEPER - for (int8_t i = 5; i--;) { buzzer.tick(); delay(2); } - #else - delay(10); - #endif + #if HAS_CHIRP + chirp(); // Buzz and wait. Is the delay needed for buttons to settle? + #if BOTH(HAS_LCD_MENU, USE_BEEPER) + for (int8_t i = 5; i--;) { buzzer.tick(); delay(2); } + #elif HAS_LCD_MENU + delay(10); #endif #endif } @@ -649,67 +660,109 @@ void MarlinUI::quick_feedback(const bool clear_buttons/*=true*/) { #if HAS_LCD_MENU - extern bool no_reentry; // Flag to prevent recursion into menu handlers - - int8_t manual_move_axis = (int8_t)NO_AXIS; - millis_t manual_move_start_time = 0; + ManualMove MarlinUI::manual_move{}; - #if IS_KINEMATIC - bool MarlinUI::processing_manual_move = false; - float manual_move_offset = 0; - #endif - - #if E_MANUAL > 1 - int8_t MarlinUI::manual_move_e_index = 0; - #endif + millis_t ManualMove::start_time = 0; + float ManualMove::menu_scale = 1; + TERN_(IS_KINEMATIC, float ManualMove::offset = 0); + TERN_(IS_KINEMATIC, bool ManualMove::processing = false); + TERN_(MULTI_MANUAL, int8_t ManualMove::e_index = 0); + uint8_t ManualMove::axis = (uint8_t)NO_AXIS; /** - * If the most recent manual move hasn't been fed to the planner yet, - * and the planner can accept one, send a move immediately. + * If a manual move has been posted and its time has arrived, and if the planner + * has a space for it, then add a linear move to current_position the planner. + * + * If any manual move needs to be interrupted, make sure to force a manual move + * by setting manual_move.start_time to millis() after updating current_position. + * + * To post a manual move: + * - Update current_position to the new place you want to go. + * - Set manual_move.axis to an axis like X_AXIS. Use ALL_AXES for diagonal moves. + * - Set manual_move.start_time to a point in the future (in ms) when the move should be done. + * + * For kinematic machines: + * - Set manual_move.offset to modify one axis and post the move. + * This is used to achieve more rapid stepping on kinematic machines. + * + * Currently used by the _lcd_move_xyz function in menu_motion.cpp + * and the ubl_map_move_to_xy funtion in menu_ubl.cpp. */ - void MarlinUI::manage_manual_move() { + void ManualMove::task() { + + if (processing) return; // Prevent re-entry from idle() calls - if (processing_manual_move) return; + // Add a manual move to the queue? + if (axis != (uint8_t)NO_AXIS && ELAPSED(millis(), start_time) && !planner.is_full()) { - if (manual_move_axis != (int8_t)NO_AXIS && ELAPSED(millis(), manual_move_start_time) && !planner.is_full()) { + const feedRate_t fr_mm_s = (uint8_t(axis) <= E_AXIS) ? manual_feedrate_mm_s[axis] : XY_PROBE_FEEDRATE_MM_S; - const feedRate_t fr_mm_s = manual_feedrate_mm_s[manual_move_axis]; #if IS_KINEMATIC - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER const int8_t old_extruder = active_extruder; - if (manual_move_axis == E_AXIS) active_extruder = manual_move_e_index; + if (axis == E_AXIS) active_extruder = e_index; #endif - // Set movement on a single axis + // Apply a linear offset to a single axis destination = current_position; - destination[manual_move_axis] += manual_move_offset; + if (axis <= XYZE) destination[axis] += offset; // Reset for the next move - manual_move_offset = 0; - manual_move_axis = (int8_t)NO_AXIS; + offset = 0; + axis = (uint8_t)NO_AXIS; // DELTA and SCARA machines use segmented moves, which could fill the planner during the call to // move_to_destination. This will cause idle() to be called, which can then call this function while the - // previous invocation is being blocked. Modifications to manual_move_offset shouldn't be made while - // processing_manual_move is true or the planner will get out of sync. - processing_manual_move = true; + // previous invocation is being blocked. Modifications to offset shouldn't be made while + // processing is true or the planner will get out of sync. + processing = true; prepare_internal_move_to_destination(fr_mm_s); // will set current_position from destination - processing_manual_move = false; + processing = false; - #if EXTRUDERS > 1 - active_extruder = old_extruder; - #endif + TERN_(HAS_MULTI_EXTRUDER, active_extruder = old_extruder); #else - planner.buffer_line(current_position, fr_mm_s, manual_move_axis == E_AXIS ? manual_move_e_index : active_extruder); - manual_move_axis = (int8_t)NO_AXIS; + // For Cartesian / Core motion simply move to the current_position + planner.buffer_line(current_position, fr_mm_s, axis == E_AXIS ? e_index : active_extruder); + + //SERIAL_ECHOLNPAIR("Add planner.move with Axis ", int(axis), " at FR ", fr_mm_s); + + axis = (uint8_t)NO_AXIS; #endif } } + // + // Tell ui.update() to start a move to current_position after a short delay. + // + void ManualMove::soon(AxisEnum move_axis + #if MULTI_MANUAL + , const int8_t eindex/*=-1*/ + #endif + ) { + #if MULTI_MANUAL + if (move_axis == E_AXIS) e_index = eindex >= 0 ? eindex : active_extruder; + #endif + start_time = millis() + (menu_scale < 0.99f ? 0UL : 250UL); // delay for bigger moves + axis = (uint8_t)move_axis; + //SERIAL_ECHOLNPAIR("Post Move with Axis ", int(axis), " soon."); + } + + #if ENABLED(AUTO_BED_LEVELING_UBL) + + void MarlinUI::external_encoder() { + if (external_control && encoderDiff) { + ubl.encoder_diff += encoderDiff; // Encoder for UBL G29 mesh editing + encoderDiff = 0; // Hide encoder events from the screen handler + refresh(LCDVIEW_REDRAW_NOW); // ...but keep the refresh. + } + } + + #endif + #endif // HAS_LCD_MENU /** @@ -746,15 +799,17 @@ void MarlinUI::quick_feedback(const bool clear_buttons/*=true*/) { */ LCDViewAction MarlinUI::lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; +millis_t next_lcd_update_ms; +#if HAS_LCD_MENU && LCD_TIMEOUT_TO_STATUS + millis_t MarlinUI::return_to_status_ms = 0; +#endif void MarlinUI::update() { static uint16_t max_display_update_time = 0; - static millis_t next_lcd_update_ms; millis_t ms = millis(); - #if HAS_LCD_MENU && LCD_TIMEOUT_TO_STATUS - static millis_t return_to_status_ms = 0; + #if HAS_LCD_MENU && LCD_TIMEOUT_TO_STATUS > 0 #define RESET_STATUS_TIMEOUT() (return_to_status_ms = ms + LCD_TIMEOUT_TO_STATUS) #else #define RESET_STATUS_TIMEOUT() NOOP @@ -767,7 +822,7 @@ void MarlinUI::update() { #if HAS_LCD_MENU // Handle any queued Move Axis motion - manage_manual_move(); + manual_move.task(); // Update button states for button_pressed(), etc. // If the state changes the next update may be delayed 300-500ms. @@ -776,46 +831,40 @@ void MarlinUI::update() { // If the action button is pressed... static bool wait_for_unclick; // = false - #if ENABLED(TOUCH_BUTTONS) + auto do_click = [&]{ + wait_for_unclick = true; // - Set debounce flag to ignore continous clicks + lcd_clicked = !wait_for_user; // - Keep the click if not waiting for a user-click + wait_for_user = false; // - Any click clears wait for user + quick_feedback(); // - Always make a click sound + }; + + #if HAS_TOUCH_XPT2046 if (touch_buttons) { RESET_STATUS_TIMEOUT(); if (touch_buttons & (EN_A | EN_B)) { // Menu arrows, in priority if (ELAPSED(ms, next_button_update_ms)) { - encoderDiff = (ENCODER_STEPS_PER_MENU_ITEM) * (ENCODER_PULSES_PER_STEP) * encoderDirection; + encoderDiff = (ENCODER_STEPS_PER_MENU_ITEM) * epps * encoderDirection; if (touch_buttons & EN_A) encoderDiff *= -1; - #if ENABLED(AUTO_BED_LEVELING_UBL) - if (external_control) ubl.encoder_diff = encoderDiff; - #endif + TERN_(AUTO_BED_LEVELING_UBL, external_encoder()); next_button_update_ms = ms + repeat_delay; // Assume the repeat delay if (!wait_for_unclick) { next_button_update_ms += 250; // Longer delay on first press wait_for_unclick = true; // Avoid Back/Select click while repeating - #if HAS_BUZZER - buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ); - #endif + chirp(); } } } - else if (!wait_for_unclick && (buttons & EN_C)) { // OK button, if not waiting for a debounce release: - wait_for_unclick = true; // - Set debounce flag to ignore continous clicks - lcd_clicked = !wait_for_user && !no_reentry; // - Keep the click if not waiting for a user-click - wait_for_user = false; // - Any click clears wait for user - quick_feedback(); // - Always make a click sound - } + else if (!wait_for_unclick && (buttons & EN_C)) // OK button, if not waiting for a debounce release: + do_click(); } else // keep wait_for_unclick value - #endif // TOUCH_BUTTONS + #endif // HAS_TOUCH_XPT2046 { // Integrated LCD click handling via button_pressed if (!external_control && button_pressed()) { - if (!wait_for_unclick) { // If not waiting for a debounce release: - wait_for_unclick = true; // - Set debounce flag to ignore continous clicks - lcd_clicked = !wait_for_user && !no_reentry; // - Keep the click if not waiting for a user-click - wait_for_user = false; // - Any click clears wait for user - quick_feedback(); // - Always make a click sound - } + if (!wait_for_unclick) do_click(); // Handle the click } else wait_for_unclick = false; @@ -828,96 +877,56 @@ void MarlinUI::update() { #endif // HAS_LCD_MENU - #if ENABLED(INIT_SDCARD_ON_BOOT) - // - // SPI SD Card detection (and first card init when the LCD is present) - // - const uint8_t sd_status = (uint8_t)IS_SD_INSERTED(); - if (sd_status != lcd_sd_status && detected()) { - - uint8_t old_sd_status = lcd_sd_status; // prevent re-entry to this block! - lcd_sd_status = sd_status; - - if (sd_status) { - safe_delay(500); // Some boards need a delay to get settled - card.mount(); - if (old_sd_status == 2) - card.beginautostart(); // Initial boot - else - set_status_P(GET_TEXT(MSG_MEDIA_INSERTED)); - } - #if PIN_EXISTS(SD_DETECT) - else { - card.release(); - if (old_sd_status != 2) { - set_status_P(GET_TEXT(MSG_MEDIA_REMOVED)); - #if HAS_LCD_MENU - return_to_status(); - #endif - } - } - - #if DISABLED(NO_LCD_REINIT) - init_lcd(); // May revive the LCD if static electricity killed it - #endif - - #endif - - refresh(); - - ms = millis(); - next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL; // delay LCD update until after SD activity completes - - #ifdef LED_BACKLIGHT_TIMEOUT - leds.reset_timeout(ms); - #endif - } - - #endif // INIT_SDCARD_ON_BOOT - - if (ELAPSED(ms, next_lcd_update_ms) - #if HAS_GRAPHICAL_LCD - || drawing_screen - #endif - ) { + if (ELAPSED(ms, next_lcd_update_ms) || TERN0(HAS_MARLINUI_U8GLIB, drawing_screen)) { next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL; - #if ENABLED(TOUCH_BUTTONS) + #if HAS_TOUCH_XPT2046 if (on_status_screen()) next_lcd_update_ms += (LCD_UPDATE_INTERVAL) * 2; - #if HAS_ENCODER_ACTION - touch_buttons = touch.read_buttons(); - #endif + TERN_(HAS_ENCODER_ACTION, touch_buttons = touch.read_buttons()); #endif - #if ENABLED(LCD_HAS_STATUS_INDICATORS) - update_indicators(); - #endif + TERN_(LCD_HAS_STATUS_INDICATORS, update_indicators()); #if HAS_ENCODER_ACTION - #if HAS_SLOW_BUTTONS - slow_buttons = read_slow_buttons(); // Buttons that take too long to read in interrupt context - #endif + TERN_(HAS_SLOW_BUTTONS, slow_buttons = read_slow_buttons()); // Buttons that take too long to read in interrupt context + + if (TERN0(REPRAPWORLD_KEYPAD, handle_keypad())) + RESET_STATUS_TIMEOUT(); - #if ENABLED(REPRAPWORLD_KEYPAD) - if (handle_keypad()) RESET_STATUS_TIMEOUT(); + uint8_t abs_diff = ABS(encoderDiff); + + #if ENCODER_PULSES_PER_STEP > 1 + // When reversing the encoder direction, a movement step can be missed because + // encoderDiff has a non-zero residual value, making the controller unresponsive. + // The fix clears the residual value when the encoder is idle. + // Also check if past half the threshold to compensate for missed single steps. + static int8_t lastEncoderDiff; + + // Timeout? No decoder change since last check. 10 or 20 times per second. + if (encoderDiff == lastEncoderDiff && abs_diff <= epps / 2) // Same direction & size but not over a half-step? + encoderDiff = 0; // Clear residual pulses. + else if (WITHIN(abs_diff, epps / 2 + 1, epps - 1)) { // Past half of threshold? + abs_diff = epps; // Treat as a full step size + encoderDiff = (encoderDiff < 0 ? -1 : 1) * abs_diff; // ...in the spin direction. + } + lastEncoderDiff = encoderDiff; #endif - const float abs_diff = ABS(encoderDiff); - const bool encoderPastThreshold = (abs_diff >= (ENCODER_PULSES_PER_STEP)); + const bool encoderPastThreshold = (abs_diff >= epps); if (encoderPastThreshold || lcd_clicked) { - if (encoderPastThreshold) { + if (encoderPastThreshold && TERN1(IS_TFTGLCD_PANEL, !external_control)) { - #if HAS_LCD_MENU && ENABLED(ENCODER_RATE_MULTIPLIER) + #if BOTH(HAS_LCD_MENU, ENCODER_RATE_MULTIPLIER) int32_t encoderMultiplier = 1; if (encoderRateMultiplierEnabled) { - const float encoderMovementSteps = abs_diff / (ENCODER_PULSES_PER_STEP); + const float encoderMovementSteps = float(abs_diff) / epps; if (lastEncoderMovementMillis) { // Note that the rate is always calculated between two passes through the @@ -927,6 +936,8 @@ void MarlinUI::update() { if (encoderStepRate >= ENCODER_100X_STEPS_PER_SEC) encoderMultiplier = 100; else if (encoderStepRate >= ENCODER_10X_STEPS_PER_SEC) encoderMultiplier = 10; + // Enable to output the encoder steps per second value + //#define ENCODER_RATE_MULTIPLIER_DEBUG #if ENABLED(ENCODER_RATE_MULTIPLIER_DEBUG) SERIAL_ECHO_START(); SERIAL_ECHOPAIR("Enc Step Rate: ", encoderStepRate); @@ -946,7 +957,7 @@ void MarlinUI::update() { #endif // ENCODER_RATE_MULTIPLIER - encoderPosition += (encoderDiff * encoderMultiplier) / (ENCODER_PULSES_PER_STEP); + encoderPosition += (encoderDiff * encoderMultiplier) / epps; encoderDiff = 0; } @@ -964,16 +975,12 @@ void MarlinUI::update() { // This runs every ~100ms when idling often enough. // Instead of tracking changes just redraw the Status Screen once per second. if (on_status_screen() && !lcd_status_update_delay--) { - lcd_status_update_delay = 9 - #if HAS_GRAPHICAL_LCD - + 3 - #endif - ; - max_display_update_time--; + lcd_status_update_delay = TERN(HAS_MARLINUI_U8GLIB, 12, 9); + if (max_display_update_time) max_display_update_time--; // Be sure never go to a very big number refresh(LCDVIEW_REDRAW_NOW); } - #if HAS_LCD_MENU && ENABLED(SCROLL_LONG_FILENAMES) + #if BOTH(HAS_LCD_MENU, SCROLL_LONG_FILENAMES) // If scrolling of long file names is enabled and we are in the sd card menu, // cause a refresh to occur until all the text has scrolled into view. if (currentScreen == menu_media && !lcd_status_update_delay--) { @@ -987,8 +994,8 @@ void MarlinUI::update() { } #endif - // then we want to use 1/2 of the time only. - uint16_t bbr2 = planner.block_buffer_runtime() >> 1; + // Then we want to use only 50% of the time + const uint16_t bbr2 = planner.block_buffer_runtime() >> 1; if ((should_draw() || drawing_screen) && (!bbr2 || bbr2 > max_display_update_time)) { @@ -1005,11 +1012,9 @@ void MarlinUI::update() { break; } // switch - #if HAS_ADC_BUTTONS - keypad_buttons = 0; - #endif + TERN_(HAS_ADC_BUTTONS, keypad_buttons = 0); - #if HAS_GRAPHICAL_LCD + #if HAS_MARLINUI_U8GLIB #if ENABLED(LIGHTWEIGHT_UI) const bool in_status = on_status_screen(), @@ -1046,9 +1051,7 @@ void MarlinUI::update() { #endif - #if HAS_LCD_MENU - lcd_clicked = false; - #endif + TERN_(HAS_LCD_MENU, lcd_clicked = false); // Keeping track of the longest time for an individual LCD update. // Used to do screen throttling when the planner starts to fill up. @@ -1056,7 +1059,7 @@ void MarlinUI::update() { NOLESS(max_display_update_time, millis() - ms); } - #if HAS_LCD_MENU && LCD_TIMEOUT_TO_STATUS + #if HAS_LCD_MENU && LCD_TIMEOUT_TO_STATUS > 0 // Return to Status Screen after a timeout if (on_status_screen() || defer_return_to_status) RESET_STATUS_TIMEOUT(); @@ -1077,6 +1080,8 @@ void MarlinUI::update() { } // switch } // ELAPSED(ms, next_lcd_update_ms) + + TERN_(HAS_GRAPHICAL_TFT, tft_idle()); } #if HAS_ADC_BUTTONS @@ -1136,7 +1141,7 @@ void MarlinUI::update() { thermalManager.current_ADCKey_raw = HAL_ADC_RANGE; thermalManager.ADCKey_count = 0; if (currentkpADCValue < adc_other_button) - for (uint8_t i = 0; i < ADC_KEY_NUM; i++) { + LOOP_L_N(i, ADC_KEY_NUM) { const uint16_t lo = pgm_read_word(&stADCKeyTable[i].ADCKeyValueMin), hi = pgm_read_word(&stADCKeyTable[i].ADCKeyValueMax); if (WITHIN(currentkpADCValue, lo, hi)) return pgm_read_byte(&stADCKeyTable[i].ADCKeyNo); @@ -1149,27 +1154,6 @@ void MarlinUI::update() { #if HAS_ENCODER_ACTION - #if DISABLED(ADC_KEYPAD) && (ENABLED(REPRAPWORLD_KEYPAD) || !HAS_DIGITAL_BUTTONS) - - /** - * Setup Rotary Encoder Bit Values (for two pin encoders to indicate movement) - * These values are independent of which pins are used for EN_A and EN_B indications - * The rotary encoder part is also independent to the chipset used for the LCD - */ - #define GET_SHIFT_BUTTON_STATES(DST) \ - uint8_t new_##DST = 0; \ - WRITE(SHIFT_LD, LOW); \ - WRITE(SHIFT_LD, HIGH); \ - for (int8_t i = 0; i < 8; i++) { \ - new_##DST >>= 1; \ - if (READ(SHIFT_OUT)) SBI(new_##DST, 7); \ - WRITE(SHIFT_CLK, HIGH); \ - WRITE(SHIFT_CLK, LOW); \ - } \ - DST = ~new_##DST; //invert it, because a pressed switch produces a logical 0 - - #endif - /** * Read encoder buttons from the hardware registers * Warning: This function is called from interrupt context! @@ -1208,7 +1192,7 @@ void MarlinUI::update() { // #if ANY_BUTTON(UP, DWN, LFT, RT) - const int8_t pulses = (ENCODER_PULSES_PER_STEP) * encoderDirection; + const int8_t pulses = epps * encoderDirection; if (false) { // for the else-ifs below @@ -1244,12 +1228,8 @@ void MarlinUI::update() { #if HAS_SLOW_BUTTONS | slow_buttons #endif - #if ENABLED(TOUCH_BUTTONS) && HAS_ENCODER_ACTION - | (touch_buttons - #if HAS_ENCODER_WHEEL - & (~(EN_A | EN_B)) - #endif - ) + #if BOTH(HAS_TOUCH_XPT2046, HAS_ENCODER_ACTION) + | (touch_buttons & TERN(HAS_ENCODER_WHEEL, ~(EN_A | EN_B), 0xFF)) #endif ); @@ -1267,15 +1247,27 @@ void MarlinUI::update() { #endif #if HAS_SHIFT_ENCODER + /** + * Set up Rotary Encoder bit values (for two pin encoders to indicate movement). + * These values are independent of which pins are used for EN_A / EN_B indications. + * The rotary encoder part is also independent of the LCD chipset. + */ + uint8_t val = 0; + WRITE(SHIFT_LD, LOW); + WRITE(SHIFT_LD, HIGH); + LOOP_L_N(i, 8) { + val >>= 1; + if (READ(SHIFT_OUT)) SBI(val, 7); + WRITE(SHIFT_CLK, HIGH); + WRITE(SHIFT_CLK, LOW); + } + TERN(REPRAPWORLD_KEYPAD, keypad_buttons, buttons) = ~val; + #endif - GET_SHIFT_BUTTON_STATES(( - #if ENABLED(REPRAPWORLD_KEYPAD) - keypad_buttons - #else - buttons - #endif - )); - + #if IS_TFTGLCD_PANEL + next_button_update_ms = now + (LCD_UPDATE_INTERVAL / 2); + buttons = slow_buttons; + TERN_(AUTO_BED_LEVELING_UBL, external_encoder()); #endif } // next_button_update_ms @@ -1301,12 +1293,9 @@ void MarlinUI::update() { case encrot2: ENCODER_SPIN(encrot1, encrot3); break; case encrot3: ENCODER_SPIN(encrot2, encrot0); break; } - if (external_control) { - #if ENABLED(AUTO_BED_LEVELING_UBL) - ubl.encoder_diff = encoderDiff; // Make encoder rotation available to UBL G29 mesh editing. - #endif - encoderDiff = 0; // Hide the encoder event from the current screen handler. - } + #if BOTH(HAS_LCD_MENU, AUTO_BED_LEVELING_UBL) + external_encoder(); + #endif lastEncoderBits = enc; } @@ -1315,12 +1304,12 @@ void MarlinUI::update() { #endif // HAS_ENCODER_ACTION -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD #if HAS_DISPLAY #if ENABLED(EXTENSIBLE_UI) - #include "extensible_ui/ui_api.h" + #include "extui/ui_api.h" #endif //////////////////////////////////////////// @@ -1344,28 +1333,30 @@ void MarlinUI::update() { void MarlinUI::finish_status(const bool persist) { - #if !(ENABLED(LCD_PROGRESS_BAR) && (PROGRESS_MSG_EXPIRE > 0)) + #if !(ENABLED(LCD_PROGRESS_BAR) && (PROGRESS_MSG_EXPIRE) > 0) UNUSED(persist); #endif - #if ENABLED(LCD_PROGRESS_BAR) - progress_bar_ms = millis(); + #if ENABLED(LCD_PROGRESS_BAR) || BOTH(FILAMENT_LCD_DISPLAY, SDSUPPORT) + const millis_t ms = millis(); + #endif + + #if ENABLED(LCD_PROGRESS_BAR) && !IS_TFTGLCD_PANEL + progress_bar_ms = ms; #if PROGRESS_MSG_EXPIRE > 0 - expire_status_ms = persist ? 0 : progress_bar_ms + PROGRESS_MSG_EXPIRE; + expire_status_ms = persist ? 0 : ms + PROGRESS_MSG_EXPIRE; #endif #endif #if BOTH(FILAMENT_LCD_DISPLAY, SDSUPPORT) - next_filament_display = millis() + 5000UL; // Show status message for 5s + next_filament_display = ms + 5000UL; // Show status message for 5s #endif - #if HAS_SPI_LCD && ENABLED(STATUS_MESSAGE_SCROLLING) + #if BOTH(HAS_WIRED_LCD, STATUS_MESSAGE_SCROLLING) status_scroll_offset = 0; #endif - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onStatusChanged(status_message); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onStatusChanged(status_message)); } bool MarlinUI::has_status() { return (status_message[0] != '\0'); } @@ -1373,9 +1364,7 @@ void MarlinUI::update() { void MarlinUI::set_status(const char * const message, const bool persist) { if (alert_level) return; - #if ENABLED(HOST_PROMPT_SUPPORT) - host_action_notify(message); - #endif + TERN_(HOST_PROMPT_SUPPORT, host_action_notify(message)); // Here we have a problem. The message is encoded in UTF8, so // arbitrarily cutting it will be a problem. We MUST be sure @@ -1416,9 +1405,7 @@ void MarlinUI::update() { if (level < alert_level) return; alert_level = level; - #if ENABLED(HOST_PROMPT_SUPPORT) - host_action_notify(message); - #endif + TERN_(HOST_PROMPT_SUPPORT, host_action_notify_P(message)); // Since the message is encoded in UTF8 it must // only be cut on a character boundary. @@ -1443,9 +1430,7 @@ void MarlinUI::update() { void MarlinUI::set_alert_status_P(PGM_P const message) { set_status_P(message, 1); - #if HAS_LCD_MENU - return_to_status(); - #endif + TERN_(HAS_LCD_MENU, return_to_status()); } PGM_P print_paused = GET_TEXT(MSG_PRINT_PAUSED); @@ -1457,13 +1442,13 @@ void MarlinUI::update() { PGM_P printing = GET_TEXT(MSG_PRINTING); PGM_P welcome = GET_TEXT(WELCOME_MSG); #if SERVICE_INTERVAL_1 > 0 - static const char service1[] PROGMEM = { "> " SERVICE_NAME_1 "!" }; + static PGMSTR(service1, "> " SERVICE_NAME_1 "!"); #endif #if SERVICE_INTERVAL_2 > 0 - static const char service2[] PROGMEM = { "> " SERVICE_NAME_2 "!" }; + static PGMSTR(service2, "> " SERVICE_NAME_2 "!"); #endif #if SERVICE_INTERVAL_3 > 0 - static const char service3[] PROGMEM = { "> " SERVICE_NAME_3 "!" }; + static PGMSTR(service3, "> " SERVICE_NAME_3 "!"); #endif PGM_P msg; if (printingIsPaused()) @@ -1505,14 +1490,10 @@ void MarlinUI::update() { #ifdef ACTION_ON_CANCEL host_action_cancel(); #endif - #if ENABLED(HOST_PROMPT_SUPPORT) - host_prompt_open(PROMPT_INFO, PSTR("UI Aborted"), DISMISS_STR); - #endif + TERN_(HOST_PROMPT_SUPPORT, host_prompt_open(PROMPT_INFO, PSTR("UI Aborted"), DISMISS_STR)); print_job_timer.stop(); set_status_P(GET_TEXT(MSG_PRINT_ABORTED)); - #if HAS_LCD_MENU - return_to_status(); - #endif + TERN_(HAS_LCD_MENU, return_to_status()); } #if ANY(PARK_HEAD_ON_PAUSE, SDSUPPORT) @@ -1521,19 +1502,16 @@ void MarlinUI::update() { void MarlinUI::pause_print() { #if HAS_LCD_MENU - synchronize(GET_TEXT(MSG_PAUSE_PRINT)); + synchronize(GET_TEXT(MSG_PAUSING)); + defer_status_screen(); #endif - #if ENABLED(HOST_PROMPT_SUPPORT) - host_prompt_open(PROMPT_PAUSE_RESUME, PSTR("UI Pause"), PSTR("Resume")); - #endif + TERN_(HOST_PROMPT_SUPPORT, host_prompt_open(PROMPT_PAUSE_RESUME, PSTR("UI Pause"), PSTR("Resume"))); set_status_P(print_paused); #if ENABLED(PARK_HEAD_ON_PAUSE) - #if HAS_SPI_LCD - lcd_pause_show_message(PAUSE_MESSAGE_PAUSING, PAUSE_MODE_PAUSE_PRINT); // Show message immediately to let user know about pause in progress - #endif + TERN_(HAS_WIRED_LCD, lcd_pause_show_message(PAUSE_MESSAGE_PARKING, PAUSE_MODE_PAUSE_PRINT)); // Show message immediately to let user know about pause in progress queue.inject_P(PSTR("M25 P\nM24")); #elif ENABLED(SDSUPPORT) queue.inject_P(PSTR("M25")); @@ -1544,9 +1522,7 @@ void MarlinUI::update() { void MarlinUI::resume_print() { reset_status(); - #if ENABLED(PARK_HEAD_ON_PAUSE) - wait_for_heatup = wait_for_user = false; - #endif + TERN_(PARK_HEAD_ON_PAUSE, wait_for_heatup = wait_for_user = false); if (IS_SD_PAUSED()) queue.inject_P(M24_STR); #ifdef ACTION_ON_RESUME host_action_resume(); @@ -1557,52 +1533,160 @@ void MarlinUI::update() { #if HAS_PRINT_PROGRESS MarlinUI::progress_t MarlinUI::_get_progress() { - #if ENABLED(LCD_SET_PROGRESS_MANUALLY) - const progress_t p = progress_override & PROGRESS_MASK; - #else - constexpr progress_t p = 0; - #endif - return (p + return ( + TERN0(LCD_SET_PROGRESS_MANUALLY, (progress_override & PROGRESS_MASK)) #if ENABLED(SDSUPPORT) - #if HAS_PRINT_PROGRESS_PERMYRIAD - ?: card.permyriadDone() - #else - ?: card.percentDone() - #endif + ?: TERN(HAS_PRINT_PROGRESS_PERMYRIAD, card.permyriadDone(), card.percentDone()) #endif ); } #endif + #if HAS_TOUCH_XPT2046 + + // + // Screen Click + // - On menu screens move directly to the touched item + // - On menu screens, right side (last 3 cols) acts like a scroll - half up => prev page, half down = next page + // - On select screens (and others) touch the Right Half for +, Left Half for - + // - On edit screens, touch Up Half for -, Bottom Half to + + // + void MarlinUI::screen_click(const uint8_t row, const uint8_t col, const uint8_t, const uint8_t) { + const millis_t now = millis(); + if (PENDING(now, next_button_update_ms)) return; + next_button_update_ms = now + repeat_delay; // Assume the repeat delay + const int8_t xdir = col < (LCD_WIDTH ) / 2 ? -1 : 1, + ydir = row < (LCD_HEIGHT) / 2 ? -1 : 1; + if (on_edit_screen) + encoderDiff = epps * ydir; + else if (screen_items > 0) { + // Last 5 cols act as a scroll :-) + if (col > (LCD_WIDTH) - 5) + // 2 * LCD_HEIGHT to scroll to bottom of next page. (LCD_HEIGHT would only go 1 item down.) + encoderDiff = epps * (encoderLine - encoderTopLine + 2 * (LCD_HEIGHT)) * ydir; + else + encoderDiff = epps * (row - encoderPosition + encoderTopLine); + } + else if (!on_status_screen()) + encoderDiff = epps * xdir; + } + + #endif + #else // !HAS_DISPLAY // // Send the status line as a host notification // - void MarlinUI::set_status(const char * const message, const bool) { - #if ENABLED(HOST_PROMPT_SUPPORT) - host_action_notify(message); - #else - UNUSED(message); - #endif + TERN(HOST_PROMPT_SUPPORT, host_action_notify(message), UNUSED(message)); } - void MarlinUI::set_status_P(PGM_P message, const int8_t) { - #if ENABLED(HOST_PROMPT_SUPPORT) - host_action_notify(message); - #else - UNUSED(message); - #endif + TERN(HOST_PROMPT_SUPPORT, host_action_notify_P(message), UNUSED(message)); } - void MarlinUI::status_printf_P(const uint8_t, PGM_P const message, ...) { - #if ENABLED(HOST_PROMPT_SUPPORT) - host_action_notify(message); - #else - UNUSED(message); - #endif + TERN(HOST_PROMPT_SUPPORT, host_action_notify_P(message), UNUSED(message)); } #endif // !HAS_DISPLAY + +#if ENABLED(SDSUPPORT) + + void MarlinUI::media_changed(const uint8_t old_status, const uint8_t status) { + if (old_status == status) { + TERN_(EXTENSIBLE_UI, ExtUI::onMediaError()); // Failed to mount/unmount + return; + } + + if (status) { + if (old_status < 2) { + TERN_(EXTENSIBLE_UI, ExtUI::onMediaInserted()); // ExtUI response + set_status_P(GET_TEXT(MSG_MEDIA_INSERTED)); + } + } + else { + if (old_status < 2) { + TERN_(EXTENSIBLE_UI, ExtUI::onMediaRemoved()); // ExtUI response + #if PIN_EXISTS(SD_DETECT) + set_status_P(GET_TEXT(MSG_MEDIA_REMOVED)); + #if HAS_LCD_MENU + if (!defer_return_to_status) return_to_status(); + #endif + #endif + } + } + + #if PIN_EXISTS(SD_DETECT) && DISABLED(NO_LCD_REINIT) + init_lcd(); // Revive a noisy shared SPI LCD + #endif + + refresh(); + + #if HAS_WIRED_LCD || defined(LED_BACKLIGHT_TIMEOUT) + const millis_t ms = millis(); + #endif + + TERN_(HAS_WIRED_LCD, next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL); // Delay LCD update for SD activity + + #ifdef LED_BACKLIGHT_TIMEOUT + leds.reset_timeout(ms); + #endif + } + +#endif // SDSUPPORT + +#if HAS_LCD_MENU + void MarlinUI::reset_settings() { settings.reset(); completion_feedback(); } +#endif + +#if ENABLED(EEPROM_SETTINGS) + + #if HAS_LCD_MENU + void MarlinUI::init_eeprom() { + const bool good = settings.init_eeprom(); + completion_feedback(good); + return_to_status(); + } + void MarlinUI::load_settings() { + const bool good = settings.load(); + completion_feedback(good); + } + void MarlinUI::store_settings() { + const bool good = settings.save(); + completion_feedback(good); + } + #endif + + #if DISABLED(EEPROM_AUTO_INIT) + + static inline PGM_P eeprom_err(const uint8_t msgid) { + switch (msgid) { + default: + case 0: return GET_TEXT(MSG_ERR_EEPROM_CRC); + case 1: return GET_TEXT(MSG_ERR_EEPROM_INDEX); + case 2: return GET_TEXT(MSG_ERR_EEPROM_VERSION); + } + } + + void MarlinUI::eeprom_alert(const uint8_t msgid) { + #if HAS_LCD_MENU + editable.uint8 = msgid; + goto_screen([]{ + PGM_P const restore_msg = GET_TEXT(MSG_INIT_EEPROM); + char msg[utf8_strlen_P(restore_msg) + 1]; + strcpy_P(msg, restore_msg); + MenuItem_confirm::select_screen( + GET_TEXT(MSG_BUTTON_RESET), GET_TEXT(MSG_BUTTON_IGNORE), + init_eeprom, return_to_status, + eeprom_err(editable.uint8), msg, PSTR("?") + ); + }); + #else + set_status_P(eeprom_err(msgid)); + #endif + } + + #endif // EEPROM_AUTO_INIT + +#endif // EEPROM_SETTINGS diff --git a/Marlin/src/lcd/ultralcd.h b/Marlin/src/lcd/ultralcd.h index f614e2009b82..c7ef41596df5 100644 --- a/Marlin/src/lcd/ultralcd.h +++ b/Marlin/src/lcd/ultralcd.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -27,15 +27,33 @@ #include "../libs/buzzer.h" #endif -#define HAS_ENCODER_ACTION (HAS_LCD_MENU || ENABLED(ULTIPANEL_FEEDMULTIPLY)) -#define HAS_ENCODER_WHEEL ((!HAS_ADC_BUTTONS && ENABLED(NEWPANEL)) || BUTTONS_EXIST(EN1, EN2)) -#define HAS_DIGITAL_BUTTONS (HAS_ENCODER_WHEEL || ANY_BUTTON(ENC, BACK, UP, DWN, LFT, RT)) -#define HAS_SHIFT_ENCODER (!HAS_ADC_BUTTONS && (ENABLED(REPRAPWORLD_KEYPAD) || (HAS_SPI_LCD && DISABLED(NEWPANEL)))) +#if ENABLED(SDSUPPORT) + #include "../sd/cardreader.h" +#endif + +#if EITHER(HAS_LCD_MENU, ULTIPANEL_FEEDMULTIPLY) + #define HAS_ENCODER_ACTION 1 +#endif +#if ((!HAS_ADC_BUTTONS && ENABLED(NEWPANEL)) || BUTTONS_EXIST(EN1, EN2)) && !IS_TFTGLCD_PANEL + #define HAS_ENCODER_WHEEL 1 +#endif +#if HAS_ENCODER_WHEEL || ANY_BUTTON(ENC, BACK, UP, DWN, LFT, RT) + #define HAS_DIGITAL_BUTTONS 1 +#endif +#if !HAS_ADC_BUTTONS && (ENABLED(REPRAPWORLD_KEYPAD) || (HAS_WIRED_LCD && DISABLED(NEWPANEL))) + #define HAS_SHIFT_ENCODER 1 +#endif // I2C buttons must be read in the main thread -#define HAS_SLOW_BUTTONS EITHER(LCD_I2C_VIKI, LCD_I2C_PANELOLU2) +#if ANY(LCD_I2C_VIKI, LCD_I2C_PANELOLU2, IS_TFTGLCD_PANEL) + #define HAS_SLOW_BUTTONS 1 +#endif -#if HAS_SPI_LCD +#if E_MANUAL > 1 + #define MULTI_MANUAL 1 +#endif + +#if HAS_WIRED_LCD #include "../MarlinCore.h" @@ -56,22 +74,10 @@ uint8_t get_ADC_keyValue(); #endif - #if ENABLED(TOUCH_BUTTONS) - #define LCD_UPDATE_INTERVAL 50 - #else - #define LCD_UPDATE_INTERVAL 100 - #endif + #define LCD_UPDATE_INTERVAL TERN(HAS_TOUCH_XPT2046, 50, 100) #if HAS_LCD_MENU - #if HAS_GRAPHICAL_LCD - #define SETCURSOR(col, row) lcd_moveto(col * (MENU_FONT_WIDTH), (row + 1) * (MENU_FONT_HEIGHT)) - #define SETCURSOR_RJ(len, row) lcd_moveto(LCD_PIXEL_WIDTH - (len) * (MENU_FONT_WIDTH), (row + 1) * (MENU_FONT_HEIGHT)) - #else - #define SETCURSOR(col, row) lcd_moveto(col, row) - #define SETCURSOR_RJ(len, row) lcd_moveto(LCD_WIDTH - (len), row) - #endif - #include "lcdprint.h" void _wrap_string(uint8_t &col, uint8_t &row, const char * const string, read_byte_cb_t cb_read_byte, const bool wordwrap=false); @@ -85,9 +91,6 @@ typedef void (*screenFunc_t)(); typedef void (*menuAction_t)(); - // Manual Movement - extern float move_menu_scale; - #if ENABLED(ADVANCED_PAUSE_FEATURE) void lcd_pause_show_message(const PauseMessage message, const PauseMode mode=PAUSE_MODE_SAME, @@ -101,7 +104,7 @@ #endif // HAS_LCD_MENU -#endif +#endif // HAS_WIRED_LCD // REPRAPWORLD_KEYPAD (and ADC_KEYPAD) #if ENABLED(REPRAPWORLD_KEYPAD) @@ -146,7 +149,7 @@ #define BUTTON_PRESSED(BN) !READ(BTN_## BN) - #if BUTTON_EXISTS(ENC) || ENABLED(TOUCH_BUTTONS) + #if BUTTON_EXISTS(ENC) || HAS_TOUCH_XPT2046 #define BLEN_C 2 #define EN_C _BV(BLEN_C) #endif @@ -199,12 +202,12 @@ #define BL_DW 4 // Down #define BL_RI 3 // Right #define BL_ST 2 // Red Button - #define B_LE (_BV(BL_LE)) - #define B_UP (_BV(BL_UP)) - #define B_MI (_BV(BL_MI)) - #define B_DW (_BV(BL_DW)) - #define B_RI (_BV(BL_RI)) - #define B_ST (_BV(BL_ST)) + #define B_LE _BV(BL_LE) + #define B_UP _BV(BL_UP) + #define B_MI _BV(BL_MI) + #define B_DW _BV(BL_DW) + #define B_RI _BV(BL_RI) + #define B_ST _BV(BL_ST) #ifndef BUTTON_CLICK #define BUTTON_CLICK() (buttons & (B_MI|B_ST)) @@ -212,7 +215,7 @@ #endif -#if BUTTON_EXISTS(BACK) || ENABLED(TOUCH_BUTTONS) +#if BUTTON_EXISTS(BACK) || EITHER(HAS_TOUCH_XPT2046, IS_TFTGLCD_PANEL) #define BLEN_D 3 #define EN_D _BV(BLEN_D) #define LCD_BACK_CLICKED() (buttons & EN_D) @@ -228,7 +231,7 @@ #endif #endif -#if HAS_GRAPHICAL_LCD +#if HAS_MARLINUI_U8GLIB enum MarlinFont : uint8_t { FONT_STATUSMENU = 1, FONT_EDIT, @@ -242,6 +245,43 @@ }; #endif +#if PREHEAT_COUNT + typedef struct { + TERN_(HAS_HOTEND, uint16_t hotend_temp); + TERN_(HAS_HEATED_BED, uint16_t bed_temp ); + TERN_(HAS_FAN, uint16_t fan_speed ); + } preheat_t; +#endif + +#if HAS_LCD_MENU + + // Manual Movement class + class ManualMove { + public: + static millis_t start_time; + static float menu_scale; + TERN_(IS_KINEMATIC, static float offset); + #if IS_KINEMATIC + static bool processing; + #else + static bool constexpr processing = false; + #endif + #if MULTI_MANUAL + static int8_t e_index; + #else + static int8_t constexpr e_index = 0; + #endif + static uint8_t axis; + static void task(); + static void soon(AxisEnum axis + #if MULTI_MANUAL + , const int8_t eindex=-1 + #endif + ); + }; + +#endif + //////////////////////////////////////////// //////////// MarlinUI Singleton //////////// //////////////////////////////////////////// @@ -250,22 +290,74 @@ class MarlinUI { public: MarlinUI() { - #if HAS_LCD_MENU - currentScreen = status_screen; - #endif + TERN_(HAS_LCD_MENU, currentScreen = status_screen); } #if HAS_BUZZER static void buzz(const long duration, const uint16_t freq); #endif + FORCE_INLINE static void chirp() { + TERN_(HAS_CHIRP, buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ)); + } + #if ENABLED(LCD_HAS_STATUS_INDICATORS) static void update_indicators(); #endif // LCD implementations static void clear_lcd(); - static void init_lcd(); + + #if ENABLED(SDSUPPORT) + static void media_changed(const uint8_t old_stat, const uint8_t stat); + #endif + + #if ENABLED(DWIN_CREALITY_LCD) + static void refresh(); + #else + FORCE_INLINE static void refresh() { + TERN_(HAS_WIRED_LCD, refresh(LCDVIEW_CLEAR_CALL_REDRAW)); + } + #endif + + #if HAS_WIRED_LCD + static bool detected(); + static void init_lcd(); + #else + static inline bool detected() { return true; } + static inline void init_lcd() {} + #endif + + #if HAS_PRINT_PROGRESS + #if HAS_PRINT_PROGRESS_PERMYRIAD + typedef uint16_t progress_t; + #define PROGRESS_SCALE 100U + #define PROGRESS_MASK 0x7FFF + #else + typedef uint8_t progress_t; + #define PROGRESS_SCALE 1U + #define PROGRESS_MASK 0x7F + #endif + #if ENABLED(LCD_SET_PROGRESS_MANUALLY) + static progress_t progress_override; + static void set_progress(const progress_t p) { progress_override = _MIN(p, 100U * (PROGRESS_SCALE)); } + static void set_progress_done() { progress_override = (PROGRESS_MASK + 1U) + 100U * (PROGRESS_SCALE); } + static void progress_reset() { if (progress_override & (PROGRESS_MASK + 1U)) set_progress(0); } + #if BOTH(LCD_SET_PROGRESS_MANUALLY, USE_M73_REMAINING_TIME) + static uint32_t remaining_time; + FORCE_INLINE static void set_remaining_time(const uint32_t r) { remaining_time = r; } + FORCE_INLINE static uint32_t get_remaining_time() { return remaining_time; } + FORCE_INLINE static void reset_remaining_time() { set_remaining_time(0); } + #endif + #endif + static progress_t _get_progress(); + #if HAS_PRINT_PROGRESS_PERMYRIAD + FORCE_INLINE static uint16_t get_progress_permyriad() { return _get_progress(); } + #endif + static uint8_t get_progress_percent() { return uint8_t(_get_progress() / (PROGRESS_SCALE)); } + #else + static constexpr uint8_t get_progress_percent() { return 0; } + #endif #if HAS_DISPLAY @@ -289,47 +381,13 @@ class MarlinUI { static void pause_print(); static void resume_print(); - #if HAS_PRINT_PROGRESS - #if HAS_PRINT_PROGRESS_PERMYRIAD - typedef uint16_t progress_t; - #define PROGRESS_SCALE 100U - #define PROGRESS_MASK 0x7FFF - #else - typedef uint8_t progress_t; - #define PROGRESS_SCALE 1U - #define PROGRESS_MASK 0x7F - #endif - #if ENABLED(LCD_SET_PROGRESS_MANUALLY) - static progress_t progress_override; - static void set_progress(const progress_t p) { progress_override = _MIN(p, 100U * (PROGRESS_SCALE)); } - static void set_progress_done() { progress_override = (PROGRESS_MASK + 1U) + 100U * (PROGRESS_SCALE); } - static void progress_reset() { if (progress_override & (PROGRESS_MASK + 1U)) set_progress(0); } - #if BOTH(LCD_SET_PROGRESS_MANUALLY, USE_M73_REMAINING_TIME) - static uint32_t remaining_time; - FORCE_INLINE static void set_remaining_time(const uint32_t r) { remaining_time = r; } - FORCE_INLINE static uint32_t get_remaining_time() { return remaining_time; } - FORCE_INLINE static void reset_remaining_time() { set_remaining_time(0); } - #endif - #endif - static progress_t _get_progress(); - #if HAS_PRINT_PROGRESS_PERMYRIAD - FORCE_INLINE static uint16_t get_progress_permyriad() { return _get_progress(); } - #endif - static uint8_t get_progress_percent() { return uint8_t(_get_progress() / (PROGRESS_SCALE)); } - #else - static constexpr uint8_t get_progress_percent() { return 0; } - #endif - - #if HAS_SPI_LCD + #if HAS_WIRED_LCD static millis_t next_button_update_ms; - static bool detected(); - static LCDViewAction lcdDrawUpdate; FORCE_INLINE static bool should_draw() { return bool(lcdDrawUpdate); } FORCE_INLINE static void refresh(const LCDViewAction type) { lcdDrawUpdate = type; } - FORCE_INLINE static void refresh() { refresh(LCDVIEW_CLEAR_CALL_REDRAW); } #if ENABLED(SHOW_CUSTOM_BOOTSCREEN) static void draw_custom_bootscreen(const uint8_t frame=0); @@ -337,21 +395,20 @@ class MarlinUI { #endif #if ENABLED(SHOW_BOOTSCREEN) + #ifndef BOOTSCREEN_TIMEOUT + #define BOOTSCREEN_TIMEOUT 2500 + #endif static void draw_marlin_bootscreen(const bool line2=false); static void show_marlin_bootscreen(); static void show_bootscreen(); #endif - #if HAS_GRAPHICAL_LCD - - static bool drawing_screen, first_page; + #if HAS_MARLINUI_U8GLIB static void set_font(const MarlinFont font_nr); #else - static constexpr bool drawing_screen = false, first_page = true; - static void set_custom_characters(const HD44780CharSet screen_charset=CHARSET_INFO); #if ENABLED(LCD_PROGRESS_BAR) @@ -380,6 +437,8 @@ class MarlinUI { static void quick_feedback(const bool clear_buttons=true); #if HAS_BUZZER static void completion_feedback(const bool good=true); + #else + static inline void completion_feedback(const bool=true) {} #endif #if DISABLED(LIGHTWEIGHT_UI) @@ -390,10 +449,19 @@ class MarlinUI { static void draw_hotend_status(const uint8_t row, const uint8_t extruder); #endif + #if HAS_TOUCH_XPT2046 + static bool on_edit_screen; + static void screen_click(const uint8_t row, const uint8_t col, const uint8_t x, const uint8_t y); + #endif + static void status_screen(); + #endif + + #if HAS_MARLINUI_U8GLIB + static bool drawing_screen, first_page; #else - static void refresh() {} + static constexpr bool drawing_screen = false, first_page = true; #endif static bool get_blink(); @@ -407,13 +475,12 @@ class MarlinUI { #else // No LCD // Send status to host as a notification - void set_status(const char* message, const bool=false); - void set_status_P(PGM_P message, const int8_t=0); - void status_printf_P(const uint8_t, PGM_P message, ...); + static void set_status(const char* message, const bool=false); + static void set_status_P(PGM_P message, const int8_t=0); + static void status_printf_P(const uint8_t, PGM_P message, ...); static inline void init() {} static inline void update() {} - static inline void refresh() {} static inline void return_to_status() {} static inline void set_alert_status_P(PGM_P const) {} static inline void reset_status(const bool=false) {} @@ -422,9 +489,27 @@ class MarlinUI { #endif + #if ENABLED(SDSUPPORT) + #if BOTH(SCROLL_LONG_FILENAMES, HAS_LCD_MENU) + #define MARLINUI_SCROLL_NAME 1 + #endif + #if MARLINUI_SCROLL_NAME + static uint8_t filename_scroll_pos, filename_scroll_max; + #endif + static const char * scrolled_filename(CardReader &theCard, const uint8_t maxlen, uint8_t hash, const bool doScroll); + #endif + + #if PREHEAT_COUNT + static preheat_t material_preset[PREHEAT_COUNT]; + static PGM_P get_preheat_label(const uint8_t m); + #endif + #if HAS_LCD_MENU + #if LCD_TIMEOUT_TO_STATUS + static millis_t return_to_status_ms; + #endif - #if ENABLED(TOUCH_BUTTONS) + #if HAS_TOUCH_XPT2046 static uint8_t touch_buttons; static uint8_t repeat_delay; #endif @@ -433,37 +518,19 @@ class MarlinUI { static bool encoderRateMultiplierEnabled; static millis_t lastEncoderMovementMillis; static void enable_encoder_multiplier(const bool onoff); - #endif - - #if ENABLED(SDSUPPORT) - #if ENABLED(SCROLL_LONG_FILENAMES) - static uint8_t filename_scroll_pos, filename_scroll_max; - #endif - static const char * scrolled_filename(CardReader &theCard, const uint8_t maxlen, uint8_t hash, const bool doScroll); - #endif - - #if IS_KINEMATIC - static bool processing_manual_move; + #define ENCODER_RATE_MULTIPLY(F) (ui.encoderRateMultiplierEnabled = F) #else - static constexpr bool processing_manual_move = false; + #define ENCODER_RATE_MULTIPLY(F) NOOP #endif - #if E_MANUAL > 1 - static int8_t manual_move_e_index; - #else - static constexpr int8_t manual_move_e_index = 0; - #endif - - static int16_t preheat_hotend_temp[2], preheat_bed_temp[2]; - static uint8_t preheat_fan_speed[2]; + // Manual Movement + static ManualMove manual_move; // Select Screen (modal NO/YES style dialog) static bool selection; static void set_selection(const bool sel) { selection = sel; } static bool update_selection(); - static void manage_manual_move(); - static bool lcd_clicked; static bool use_click(); @@ -475,15 +542,9 @@ class MarlinUI { static void save_previous_screen(); // goto_previous_screen and go_back may also be used as menu item callbacks - #if ENABLED(TURBO_BACK_MENU_ITEM) - static void _goto_previous_screen(const bool is_back); - static inline void goto_previous_screen() { _goto_previous_screen(false); } - static inline void go_back() { _goto_previous_screen(true); } - #else - static void _goto_previous_screen(); - FORCE_INLINE static void goto_previous_screen() { _goto_previous_screen(); } - FORCE_INLINE static void go_back() { _goto_previous_screen(); } - #endif + static void _goto_previous_screen(TERN_(TURBO_BACK_MENU_ITEM, const bool is_back)); + static inline void goto_previous_screen() { _goto_previous_screen(TERN_(TURBO_BACK_MENU_ITEM, false)); } + static inline void go_back() { _goto_previous_screen(TERN_(TURBO_BACK_MENU_ITEM, true)); } static void return_to_status(); static inline bool on_status_screen() { return currentScreen == status_screen; } @@ -494,7 +555,7 @@ class MarlinUI { #endif FORCE_INLINE static void defer_status_screen(const bool defer=true) { - #if LCD_TIMEOUT_TO_STATUS + #if LCD_TIMEOUT_TO_STATUS > 0 defer_return_to_status = defer; #else UNUSED(defer); @@ -510,21 +571,13 @@ class MarlinUI { static void reselect_last_file(); #endif - #if ENABLED(G26_MESH_VALIDATION) - FORCE_INLINE static void chirp() { - #if HAS_BUZZER - buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ); - #endif - } - #endif - #if ENABLED(AUTO_BED_LEVELING_UBL) static void ubl_plot(const uint8_t x_plot, const uint8_t y_plot); #endif static void draw_select_screen_prompt(PGM_P const pref, const char * const string=nullptr, PGM_P const suff=nullptr); - #elif HAS_SPI_LCD + #elif HAS_WIRED_LCD static constexpr bool lcd_clicked = false; static constexpr bool on_status_screen() { return true; } @@ -532,18 +585,47 @@ class MarlinUI { #endif - #define LCD_HAS_WAIT_FOR_MOVE EITHER(DELTA_CALIBRATION_MENU, DELTA_AUTO_CALIBRATION) || (ENABLED(LCD_BED_LEVELING) && EITHER(PROBE_MANUALLY, MESH_BED_LEVELING)) + // + // EEPROM: Reset / Init / Load / Store + // + #if HAS_LCD_MENU + static void reset_settings(); + #endif - #if LCD_HAS_WAIT_FOR_MOVE + #if ENABLED(EEPROM_SETTINGS) + #if HAS_LCD_MENU + static void init_eeprom(); + static void load_settings(); + static void store_settings(); + #endif + #if DISABLED(EEPROM_AUTO_INIT) + static void eeprom_alert(const uint8_t msgid); + static inline void eeprom_alert_crc() { eeprom_alert(0); } + static inline void eeprom_alert_index() { eeprom_alert(1); } + static inline void eeprom_alert_version() { eeprom_alert(2); } + #endif + #endif + + // + // Special handling if a move is underway + // + #if EITHER(DELTA_CALIBRATION_MENU, DELTA_AUTO_CALIBRATION) || (ENABLED(LCD_BED_LEVELING) && EITHER(PROBE_MANUALLY, MESH_BED_LEVELING)) + #define LCD_HAS_WAIT_FOR_MOVE 1 static bool wait_for_move; #else static constexpr bool wait_for_move = false; #endif + // + // Block interaction while under external control + // #if HAS_LCD_MENU && EITHER(AUTO_BED_LEVELING_UBL, G26_MESH_VALIDATION) static bool external_control; FORCE_INLINE static void capture() { external_control = true; } FORCE_INLINE static void release() { external_control = false; } + #if ENABLED(AUTO_BED_LEVELING_UBL) + static void external_encoder(); + #endif #else static constexpr bool external_control = false; #endif @@ -561,18 +643,14 @@ class MarlinUI { #endif static void update_buttons(); - static inline bool button_pressed() { return BUTTON_CLICK(); } + static inline bool button_pressed() { return BUTTON_CLICK() || TERN(TOUCH_SCREEN, touch_pressed(), false); } #if EITHER(AUTO_BED_LEVELING_UBL, G26_MESH_VALIDATION) static void wait_for_release(); #endif static uint32_t encoderPosition; - #if ENABLED(REVERSE_ENCODER_DIRECTION) - #define ENCODERBASE -1 - #else - #define ENCODERBASE +1 - #endif + #define ENCODERBASE (TERN(REVERSE_ENCODER_DIRECTION, -1, +1)) #if EITHER(REVERSE_MENU_DIRECTION, REVERSE_SELECT_DIRECTION) static int8_t encoderDirection; @@ -587,15 +665,11 @@ class MarlinUI { } FORCE_INLINE static void encoder_direction_menus() { - #if ENABLED(REVERSE_MENU_DIRECTION) - encoderDirection = -(ENCODERBASE); - #endif + TERN_(REVERSE_MENU_DIRECTION, encoderDirection = -(ENCODERBASE)); } FORCE_INLINE static void encoder_direction_select() { - #if ENABLED(REVERSE_SELECT_DIRECTION) - encoderDirection = -(ENCODERBASE); - #endif + TERN_(REVERSE_SELECT_DIRECTION, encoderDirection = -(ENCODERBASE)); } #else @@ -604,23 +678,33 @@ class MarlinUI { #endif -private: + #if ENABLED(TOUCH_SCREEN_CALIBRATION) + static void touch_calibration(); + #endif + + #if HAS_GRAPHICAL_TFT + static void move_axis_screen(); + #endif - static void _synchronize(); +private: #if HAS_DISPLAY static void finish_status(const bool persist); #endif - #if HAS_SPI_LCD - #if HAS_LCD_MENU - #if LCD_TIMEOUT_TO_STATUS - static bool defer_return_to_status; - #else - static constexpr bool defer_return_to_status = false; - #endif + #if HAS_WIRED_LCD + #if HAS_LCD_MENU && LCD_TIMEOUT_TO_STATUS > 0 + static bool defer_return_to_status; + #else + static constexpr bool defer_return_to_status = false; #endif static void draw_status_screen(); + #if HAS_GRAPHICAL_TFT + static void tft_idle(); + #if ENABLED(TOUCH_SCREEN) + static bool touch_pressed(); + #endif + #endif #endif }; diff --git a/Marlin/src/libs/BL24CXX.cpp b/Marlin/src/libs/BL24CXX.cpp new file mode 100644 index 000000000000..d34ed8340f83 --- /dev/null +++ b/Marlin/src/libs/BL24CXX.cpp @@ -0,0 +1,273 @@ +/** + * Marlin 3D Printer Firmware + * + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../inc/MarlinConfig.h" + +#if ENABLED(IIC_BL24CXX_EEPROM) + +/** + * PersistentStore for Arduino-style EEPROM interface + * with simple implementations supplied by Marlin. + */ + +#include "BL24CXX.h" +#include + +#ifndef EEPROM_WRITE_DELAY + #define EEPROM_WRITE_DELAY 10 +#endif +#ifndef EEPROM_DEVICE_ADDRESS + #define EEPROM_DEVICE_ADDRESS (0x50 << 1) +#endif + +// IO direction setting +#define SDA_IN() do{ PIN_MAP[IIC_EEPROM_SDA].gpio_device->regs->CRH &= 0XFFFF0FFF; PIN_MAP[IIC_EEPROM_SDA].gpio_device->regs->CRH |= 8 << 12; }while(0) +#define SDA_OUT() do{ PIN_MAP[IIC_EEPROM_SDA].gpio_device->regs->CRH &= 0XFFFF0FFF; PIN_MAP[IIC_EEPROM_SDA].gpio_device->regs->CRH |= 3 << 12; }while(0) + +// IO ops +#define IIC_SCL_0() WRITE(IIC_EEPROM_SCL, LOW) +#define IIC_SCL_1() WRITE(IIC_EEPROM_SCL, HIGH) +#define IIC_SDA_0() WRITE(IIC_EEPROM_SDA, LOW) +#define IIC_SDA_1() WRITE(IIC_EEPROM_SDA, HIGH) +#define READ_SDA() READ(IIC_EEPROM_SDA) + +// +// Simple IIC interface via libmaple +// + +// Initialize IIC +void IIC::init() { + SET_OUTPUT(IIC_EEPROM_SDA); + SET_OUTPUT(IIC_EEPROM_SCL); + IIC_SCL_1(); + IIC_SDA_1(); +} + +// Generate IIC start signal +void IIC::start() { + SDA_OUT(); // SDA line output + IIC_SDA_1(); + IIC_SCL_1(); + delay_us(4); + IIC_SDA_0(); // START:when CLK is high, DATA change from high to low + delay_us(4); + IIC_SCL_0(); // Clamp the I2C bus, ready to send or receive data +} + +// Generate IIC stop signal +void IIC::stop() { + SDA_OUT(); // SDA line output + IIC_SCL_0(); + IIC_SDA_0(); // STOP:when CLK is high DATA change from low to high + delay_us(4); + IIC_SCL_1(); + IIC_SDA_1(); // Send I2C bus end signal + delay_us(4); +} + +// Wait for the response signal to arrive +// 1 = failed to receive response +// 0 = response received +uint8_t IIC::wait_ack() { + uint8_t ucErrTime = 0; + SDA_IN(); // SDA is set as input + IIC_SDA_1(); delay_us(1); + IIC_SCL_1(); delay_us(1); + while (READ_SDA()) { + if (++ucErrTime > 250) { + stop(); + return 1; + } + } + IIC_SCL_0(); // Clock output 0 + return 0; +} + +// Generate ACK response +void IIC::ack() { + IIC_SCL_0(); + SDA_OUT(); + IIC_SDA_0(); + delay_us(2); + IIC_SCL_1(); + delay_us(2); + IIC_SCL_0(); +} + +// No ACK response +void IIC::nAck() { + IIC_SCL_0(); + SDA_OUT(); + IIC_SDA_1(); + delay_us(2); + IIC_SCL_1(); + delay_us(2); + IIC_SCL_0(); +} + +// Send one IIC byte +// Return whether the slave responds +// 1 = there is a response +// 0 = no response +void IIC::send_byte(uint8_t txd) { + SDA_OUT(); + IIC_SCL_0(); // Pull down the clock to start data transmission + LOOP_L_N(t, 8) { + // IIC_SDA = (txd & 0x80) >> 7; + if (txd & 0x80) IIC_SDA_1(); else IIC_SDA_0(); + txd <<= 1; + delay_us(2); // All three delays are necessary for TEA5767 + IIC_SCL_1(); + delay_us(2); + IIC_SCL_0(); + delay_us(2); + } +} + +// Read 1 byte, when ack=1, send ACK, ack=0, send nACK +uint8_t IIC::read_byte(unsigned char ack_chr) { + unsigned char receive = 0; + SDA_IN(); // SDA is set as input + LOOP_L_N(i, 8) { + IIC_SCL_0(); + delay_us(2); + IIC_SCL_1(); + receive <<= 1; + if (READ_SDA()) receive++; + delay_us(1); + } + ack_chr ? ack() : nAck(); // Send ACK / send nACK + return receive; +} + +/******************** EEPROM ********************/ + +// Initialize the IIC interface +void BL24CXX::init() { IIC::init(); } + +// Read a byte at the specified address +// ReadAddr: the address to start reading +// Return: the byte read +uint8_t BL24CXX::readOneByte(uint16_t ReadAddr) { + uint8_t temp = 0; + IIC::start(); + if (EE_TYPE > BL24C16) { + IIC::send_byte(EEPROM_DEVICE_ADDRESS); // Send write command + IIC::wait_ack(); + IIC::send_byte(ReadAddr >> 8); // Send high address + IIC::wait_ack(); + } + else + IIC::send_byte(EEPROM_DEVICE_ADDRESS + ((ReadAddr >> 8) << 1)); // Send device address 0xA0, write data + + IIC::wait_ack(); + IIC::send_byte(ReadAddr & 0xFF); // Send low address + IIC::wait_ack(); + IIC::start(); + IIC::send_byte(EEPROM_DEVICE_ADDRESS | 0x01); // Send byte + IIC::wait_ack(); + temp = IIC::read_byte(0); + IIC::stop(); // Generate a stop condition + return temp; +} + +// Write a data at the address specified by BL24CXX +// WriteAddr: The destination address for writing data +// DataToWrite: the data to be written +void BL24CXX::writeOneByte(uint16_t WriteAddr, uint8_t DataToWrite) { + IIC::start(); + if (EE_TYPE > BL24C16) { + IIC::send_byte(EEPROM_DEVICE_ADDRESS); // Send write command + IIC::wait_ack(); + IIC::send_byte(WriteAddr >> 8); // Send high address + } + else + IIC::send_byte(EEPROM_DEVICE_ADDRESS + ((WriteAddr >> 8) << 1)); // Send device address 0xA0, write data + + IIC::wait_ack(); + IIC::send_byte(WriteAddr & 0xFF); // Send low address + IIC::wait_ack(); + IIC::send_byte(DataToWrite); // Receiving mode + IIC::wait_ack(); + IIC::stop(); // Generate a stop condition + delay(10); +} + +// Start writing data of length Len at the specified address in BL24CXX +// This function is used to write 16bit or 32bit data. +// WriteAddr: the address to start writing +// DataToWrite: the first address of the data array +// Len: The length of the data to be written 2, 4 +void BL24CXX::writeLenByte(uint16_t WriteAddr, uint32_t DataToWrite, uint8_t Len) { + LOOP_L_N(t, Len) + writeOneByte(WriteAddr + t, (DataToWrite >> (8 * t)) & 0xFF); +} + +// Start reading data of length Len from the specified address in BL24CXX +// This function is used to read 16bit or 32bit data. +// ReadAddr: the address to start reading +// Return value: data +// Len: The length of the data to be read 2,4 +uint32_t BL24CXX::readLenByte(uint16_t ReadAddr, uint8_t Len) { + uint32_t temp = 0; + LOOP_L_N(t, Len) { + temp <<= 8; + temp += readOneByte(ReadAddr + Len - t - 1); + } + return temp; +} + +// Check if BL24CXX is normal +// Return 1: Detection failed +// return 0: detection is successful +#define BL24CXX_TEST_ADDRESS 0x00 +#define BL24CXX_TEST_VALUE 0x55 + +bool BL24CXX::_check() { + return (readOneByte(BL24CXX_TEST_ADDRESS) != BL24CXX_TEST_VALUE); // false = success! +} + +bool BL24CXX::check() { + if (_check()) { // Value was written? Good EEPROM! + writeOneByte(BL24CXX_TEST_ADDRESS, BL24CXX_TEST_VALUE); // Write now and check. + return _check(); + } + return false; // success! +} + +// Start reading the specified number of data at the specified address in BL24CXX +// ReadAddr: The address to start reading is 0~255 for 24c02 +// pBuffer: the first address of the data array +// NumToRead: the number of data to be read +void BL24CXX::read(uint16_t ReadAddr, uint8_t *pBuffer, uint16_t NumToRead) { + for (; NumToRead; NumToRead--) + *pBuffer++ = readOneByte(ReadAddr++); +} + +// Start writing the specified number of data at the specified address in BL24CXX +// WriteAddr: the address to start writing, 0~255 for 24c02 +// pBuffer: the first address of the data array +// NumToWrite: the number of data to be written +void BL24CXX::write(uint16_t WriteAddr, uint8_t *pBuffer, uint16_t NumToWrite) { + for (; NumToWrite; NumToWrite--, WriteAddr++) + writeOneByte(WriteAddr, *pBuffer++); +} + +#endif // IIC_BL24CXX_EEPROM diff --git a/Marlin/src/libs/BL24CXX.h b/Marlin/src/libs/BL24CXX.h new file mode 100644 index 000000000000..b069c196c035 --- /dev/null +++ b/Marlin/src/libs/BL24CXX.h @@ -0,0 +1,72 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/******************************************************************************** + * @file BL24CXX.h + * @brief i2c EEPROM for Ender 3 v2 board (4.2.2) + ********************************************************************************/ + +/******************** IIC ********************/ + +class BL24CXX; + +// All operation functions of IIC +class IIC { +friend class BL24CXX; +protected: + static void init(); // Initialize the IO port of IIC + static void start(); // Send IIC start signal + static void stop(); // Send IIC stop signal + static void send_byte(uint8_t txd); // IIC sends a byte + static uint8_t read_byte(unsigned char ack); // IIC reads a byte + static uint8_t wait_ack(); // IIC waits for ACK signal + static void ack(); // IIC sends ACK signal + static void nAck(); // IIC does not send ACK signal +}; + +/******************** EEPROM ********************/ + +#define BL24C01 127 +#define BL24C02 255 +#define BL24C04 511 +#define BL24C08 1023 +#define BL24C16 2047 +#define BL24C32 4095 +#define BL24C64 8191 +#define BL24C128 16383 +#define BL24C256 32767 +#define EE_TYPE BL24C16 + +class BL24CXX { +private: + static bool _check(); // Check the device +public: + static void init(); // Initialize IIC + static bool check(); // Check / recheck the device + static uint8_t readOneByte(uint16_t ReadAddr); // Read a byte at the specified address + static void writeOneByte(uint16_t WriteAddr, uint8_t DataToWrite); // Write a byte at the specified address + static void writeLenByte(uint16_t WriteAddr, uint32_t DataToWrite, uint8_t Len); // The specified address begins to write the data of the specified length + static uint32_t readLenByte(uint16_t ReadAddr, uint8_t Len); // The specified address starts to read the data of the specified length + static void write(uint16_t WriteAddr, uint8_t *pBuffer, uint16_t NumToWrite); // Write the specified length of data from the specified address + static void read(uint16_t ReadAddr, uint8_t *pBuffer, uint16_t NumToRead); // Read the data of the specified length from the specified address +}; diff --git a/Marlin/src/libs/L64XX/L64XX_Marlin.cpp b/Marlin/src/libs/L64XX/L64XX_Marlin.cpp index 37fbf021d17f..dd85473e9802 100644 --- a/Marlin/src/libs/L64XX/L64XX_Marlin.cpp +++ b/Marlin/src/libs/L64XX/L64XX_Marlin.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -508,7 +508,7 @@ uint8_t L64XX_Marlin::get_user_input(uint8_t &driver_count, L64XX_axis_t axis_in // Work on the drivers // - for (uint8_t k = 0; k < driver_count; k++) { + LOOP_L_N(k, driver_count) { uint8_t not_found = true; for (j = 1; j <= L64XX::chain[0]; j++) { PGM_P const str = (PGM_P)pgm_read_ptr(&index_to_axis[L64XX::chain[j]]); @@ -923,9 +923,7 @@ void L64XX_Marlin::say_axis(const L64XX_axis_t axis, const uint8_t label/*=true* monitor_update(E5); #endif - #if ENABLED(L6470_DEBUG) - if (report_L6470_status) DEBUG_EOL(); - #endif + if (TERN0(L6470_DEBUG, report_L6470_status)) DEBUG_EOL(); spi_active = false; // done with all SPI transfers - clear handshake flags spi_abort = false; diff --git a/Marlin/src/libs/L64XX/L64XX_Marlin.h b/Marlin/src/libs/L64XX/L64XX_Marlin.h index 371f0991c23c..c8d273990f5a 100644 --- a/Marlin/src/libs/L64XX/L64XX_Marlin.h +++ b/Marlin/src/libs/L64XX/L64XX_Marlin.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/libs/W25Qxx.cpp b/Marlin/src/libs/W25Qxx.cpp new file mode 100644 index 000000000000..03e002f66f82 --- /dev/null +++ b/Marlin/src/libs/W25Qxx.cpp @@ -0,0 +1,388 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../inc/MarlinConfig.h" + +#if HAS_SPI_FLASH + +#include "W25Qxx.h" +#include + +W25QXXFlash W25QXX; + +#ifndef SPI_FLASH_MISO_PIN + #define SPI_FLASH_MISO_PIN W25QXX_MISO_PIN +#endif +#ifndef SPI_FLASH_MOSI_PIN + #define SPI_FLASH_MOSI_PIN W25QXX_MOSI_PIN +#endif +#ifndef SPI_FLASH_SCK_PIN + #define SPI_FLASH_SCK_PIN W25QXX_SCK_PIN +#endif +#ifndef SPI_FLASH_CS_PIN + #define SPI_FLASH_CS_PIN W25QXX_CS_PIN +#endif + +#define W25QXX_CS_H OUT_WRITE(SPI_FLASH_CS_PIN, HIGH) +#define W25QXX_CS_L OUT_WRITE(SPI_FLASH_CS_PIN, LOW) + +void W25QXXFlash::init(uint8_t spiRate) { + + OUT_WRITE(SPI_FLASH_CS_PIN, HIGH); + + /** + * STM32F1 APB2 = 72MHz, APB1 = 36MHz, max SPI speed of this MCU if 18Mhz + * STM32F1 has 3 SPI ports, SPI1 in APB2, SPI2/SPI3 in APB1 + * so the minimum prescale of SPI1 is DIV4, SPI2/SPI3 is DIV2 + */ + #if SPI_DEVICE == 1 + #define SPI_CLOCK_MAX SPI_CLOCK_DIV4 + #else + #define SPI_CLOCK_MAX SPI_CLOCK_DIV2 + #endif + uint8_t clock; + switch (spiRate) { + case SPI_FULL_SPEED: clock = SPI_CLOCK_MAX; break; + case SPI_HALF_SPEED: clock = SPI_CLOCK_DIV4; break; + case SPI_QUARTER_SPEED: clock = SPI_CLOCK_DIV8; break; + case SPI_EIGHTH_SPEED: clock = SPI_CLOCK_DIV16; break; + case SPI_SPEED_5: clock = SPI_CLOCK_DIV32; break; + case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break; + default: clock = SPI_CLOCK_DIV2;// Default from the SPI library + } + SPI.setModule(SPI_DEVICE); + SPI.begin(); + SPI.setClockDivider(clock); + SPI.setBitOrder(MSBFIRST); + SPI.setDataMode(SPI_MODE0); +} + +/** + * @brief Receive a single byte from the SPI port. + * + * @return Byte received + */ +uint8_t W25QXXFlash::spi_flash_Rec() { + const uint8_t returnByte = SPI.transfer(0xFF); + return returnByte; +} + +uint8_t W25QXXFlash::spi_flash_read_write_byte(uint8_t data) { + const uint8_t returnByte = SPI.transfer(data); + return returnByte; +} + +/** + * @brief Receive a number of bytes from the SPI port to a buffer + * + * @param buf Pointer to starting address of buffer to write to. + * @param nbyte Number of bytes to receive. + * @return Nothing + * + * @details Uses DMA + */ +void W25QXXFlash::spi_flash_Read(uint8_t* buf, uint16_t nbyte) { SPI.dmaTransfer(0, const_cast(buf), nbyte); } + +/** + * @brief Send a single byte on SPI port + * + * @param b Byte to send + * + * @details + */ +void W25QXXFlash::spi_flash_Send(uint8_t b) { SPI.send(b); } + +/** + * @brief Write token and then write from 512 byte buffer to SPI (for SD card) + * + * @param buf Pointer with buffer start address + * @return Nothing + * + * @details Use DMA + */ +void W25QXXFlash::spi_flash_SendBlock(uint8_t token, const uint8_t* buf) { + SPI.send(token); + SPI.dmaSend(const_cast(buf), 512); +} + +uint16_t W25QXXFlash::W25QXX_ReadID(void) { + uint16_t Temp = 0; + W25QXX_CS_L; + spi_flash_Send(0x90); + spi_flash_Send(0x00); + spi_flash_Send(0x00); + spi_flash_Send(0x00); + Temp |= spi_flash_Rec() << 8; + Temp |= spi_flash_Rec(); + W25QXX_CS_H; + return Temp; +} + +void W25QXXFlash::SPI_FLASH_WriteEnable(void) { + /* Select the FLASH: Chip Select low */ + W25QXX_CS_L; + /* Send "Write Enable" instruction */ + spi_flash_Send(W25X_WriteEnable); + /* Deselect the FLASH: Chip Select high */ + W25QXX_CS_H; +} + +/******************************************************************************* +* Function Name : SPI_FLASH_WaitForWriteEnd +* Description : Polls the status of the Write In Progress (WIP) flag in the +* FLASH's status register and loop until write opertaion +* has completed. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void W25QXXFlash::SPI_FLASH_WaitForWriteEnd(void) { + uint8_t FLASH_Status = 0; + + /* Select the FLASH: Chip Select low */ + W25QXX_CS_L; + /* Send "Read Status Register" instruction */ + spi_flash_Send(W25X_ReadStatusReg); + + /* Loop as long as the memory is busy with a write cycle */ + do + /* Send a dummy byte to generate the clock needed by the FLASH + and put the value of the status register in FLASH_Status variable */ + FLASH_Status = spi_flash_Rec(); + while ((FLASH_Status & WIP_Flag) == 0x01); /* Write in progress */ + + /* Deselect the FLASH: Chip Select high */ + W25QXX_CS_H; +} + +void W25QXXFlash::SPI_FLASH_SectorErase(uint32_t SectorAddr) { + /* Send write enable instruction */ + SPI_FLASH_WriteEnable(); + + /* Sector Erase */ + /* Select the FLASH: Chip Select low */ + W25QXX_CS_L; + /* Send Sector Erase instruction */ + spi_flash_Send(W25X_SectorErase); + /* Send SectorAddr high nibble address byte */ + spi_flash_Send((SectorAddr & 0xFF0000) >> 16); + /* Send SectorAddr medium nibble address byte */ + spi_flash_Send((SectorAddr & 0xFF00) >> 8); + /* Send SectorAddr low nibble address byte */ + spi_flash_Send(SectorAddr & 0xFF); + /* Deselect the FLASH: Chip Select high */ + + W25QXX_CS_H; + /* Wait the end of Flash writing */ + SPI_FLASH_WaitForWriteEnd(); +} + +void W25QXXFlash::SPI_FLASH_BlockErase(uint32_t BlockAddr) { + SPI_FLASH_WriteEnable(); + W25QXX_CS_L; + /* Send Sector Erase instruction */ + spi_flash_Send(W25X_BlockErase); + /* Send SectorAddr high nibble address byte */ + spi_flash_Send((BlockAddr & 0xFF0000) >> 16); + /* Send SectorAddr medium nibble address byte */ + spi_flash_Send((BlockAddr & 0xFF00) >> 8); + /* Send SectorAddr low nibble address byte */ + spi_flash_Send(BlockAddr & 0xFF); + + W25QXX_CS_H; + + SPI_FLASH_WaitForWriteEnd(); +} + +/******************************************************************************* +* Function Name : SPI_FLASH_BulkErase +* Description : Erases the entire FLASH. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void W25QXXFlash::SPI_FLASH_BulkErase(void) { + /* Send write enable instruction */ + SPI_FLASH_WriteEnable(); + + /* Bulk Erase */ + /* Select the FLASH: Chip Select low */ + W25QXX_CS_L; + + /* Send Bulk Erase instruction */ + spi_flash_Send(W25X_ChipErase); + /* Deselect the FLASH: Chip Select high */ + W25QXX_CS_H; + /* Wait the end of Flash writing */ + SPI_FLASH_WaitForWriteEnd(); +} + +/******************************************************************************* +* Function Name : SPI_FLASH_PageWrite +* Description : Writes more than one byte to the FLASH with a single WRITE +* cycle(Page WRITE sequence). The number of byte can't exceed +* the FLASH page size. +* Input : - pBuffer : pointer to the buffer containing the data to be +* written to the FLASH. +* - WriteAddr : FLASH's internal address to write to. +* - NumByteToWrite : number of bytes to write to the FLASH, +* must be equal or less than "SPI_FLASH_PageSize" value. +* Output : None +* Return : None +*******************************************************************************/ +void W25QXXFlash::SPI_FLASH_PageWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite) { + /* Enable the write access to the FLASH */ + SPI_FLASH_WriteEnable(); + + /* Select the FLASH: Chip Select low */ + W25QXX_CS_L; + /* Send "Write to Memory " instruction */ + spi_flash_Send(W25X_PageProgram); + /* Send WriteAddr high nibble address byte to write to */ + spi_flash_Send((WriteAddr & 0xFF0000) >> 16); + /* Send WriteAddr medium nibble address byte to write to */ + spi_flash_Send((WriteAddr & 0xFF00) >> 8); + /* Send WriteAddr low nibble address byte to write to */ + spi_flash_Send(WriteAddr & 0xFF); + + NOMORE(NumByteToWrite, SPI_FLASH_PerWritePageSize); + + /* while there is data to be written on the FLASH */ + while (NumByteToWrite--) { + /* Send the current byte */ + spi_flash_Send(*pBuffer); + /* Point on the next byte to be written */ + pBuffer++; + } + + /* Deselect the FLASH: Chip Select high */ + W25QXX_CS_H; + + /* Wait the end of Flash writing */ + SPI_FLASH_WaitForWriteEnd(); +} + +/******************************************************************************* +* Function Name : SPI_FLASH_BufferWrite +* Description : Writes block of data to the FLASH. In this function, the +* number of WRITE cycles are reduced, using Page WRITE sequence. +* Input : - pBuffer : pointer to the buffer containing the data to be +* written to the FLASH. +* - WriteAddr : FLASH's internal address to write to. +* - NumByteToWrite : number of bytes to write to the FLASH. +* Output : None +* Return : None +*******************************************************************************/ +void W25QXXFlash::SPI_FLASH_BufferWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite) { + uint8_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0; + + Addr = WriteAddr % SPI_FLASH_PageSize; + count = SPI_FLASH_PageSize - Addr; + NumOfPage = NumByteToWrite / SPI_FLASH_PageSize; + NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize; + + if (Addr == 0) { /* WriteAddr is SPI_FLASH_PageSize aligned */ + if (NumOfPage == 0) { /* NumByteToWrite < SPI_FLASH_PageSize */ + SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite); + } + else { /* NumByteToWrite > SPI_FLASH_PageSize */ + while (NumOfPage--) { + SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize); + WriteAddr += SPI_FLASH_PageSize; + pBuffer += SPI_FLASH_PageSize; + } + SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle); + } + } + else { /* WriteAddr is not SPI_FLASH_PageSize aligned */ + if (NumOfPage == 0) { /* NumByteToWrite < SPI_FLASH_PageSize */ + if (NumOfSingle > count) { /* (NumByteToWrite + WriteAddr) > SPI_FLASH_PageSize */ + temp = NumOfSingle - count; + SPI_FLASH_PageWrite(pBuffer, WriteAddr, count); + WriteAddr += count; + pBuffer += count; + SPI_FLASH_PageWrite(pBuffer, WriteAddr, temp); + } + else { + SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite); + } + } + else { /* NumByteToWrite > SPI_FLASH_PageSize */ + NumByteToWrite -= count; + NumOfPage = NumByteToWrite / SPI_FLASH_PageSize; + NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize; + + SPI_FLASH_PageWrite(pBuffer, WriteAddr, count); + WriteAddr += count; + pBuffer += count; + + while (NumOfPage--) { + SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize); + WriteAddr += SPI_FLASH_PageSize; + pBuffer += SPI_FLASH_PageSize; + } + + if (NumOfSingle != 0) + SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle); + } + } +} + +/******************************************************************************* +* Function Name : SPI_FLASH_BufferRead +* Description : Reads a block of data from the FLASH. +* Input : - pBuffer : pointer to the buffer that receives the data read +* from the FLASH. +* - ReadAddr : FLASH's internal address to read from. +* - NumByteToRead : number of bytes to read from the FLASH. +* Output : None +* Return : None +*******************************************************************************/ +void W25QXXFlash::SPI_FLASH_BufferRead(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead) { + /* Select the FLASH: Chip Select low */ + W25QXX_CS_L; + + /* Send "Read from Memory " instruction */ + spi_flash_Send(W25X_ReadData); + + /* Send ReadAddr high nibble address byte to read from */ + spi_flash_Send((ReadAddr & 0xFF0000) >> 16); + /* Send ReadAddr medium nibble address byte to read from */ + spi_flash_Send((ReadAddr & 0xFF00) >> 8); + /* Send ReadAddr low nibble address byte to read from */ + spi_flash_Send(ReadAddr & 0xFF); + + if (NumByteToRead < 33) { + while (NumByteToRead--) { /* while there is data to be read */ + /* Read a byte from the FLASH */ + *pBuffer = spi_flash_Rec(); + /* Point to the next location where the byte read will be saved */ + pBuffer++; + } + } + else { + spi_flash_Read(pBuffer, NumByteToRead); + } + W25QXX_CS_H; +} + +#endif // HAS_SPI_FLASH diff --git a/Marlin/src/libs/W25Qxx.h b/Marlin/src/libs/W25Qxx.h new file mode 100644 index 000000000000..ac3e8a169b24 --- /dev/null +++ b/Marlin/src/libs/W25Qxx.h @@ -0,0 +1,70 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include + +#define W25X_WriteEnable 0x06 +#define W25X_WriteDisable 0x04 +#define W25X_ReadStatusReg 0x05 +#define W25X_WriteStatusReg 0x01 +#define W25X_ReadData 0x03 +#define W25X_FastReadData 0x0B +#define W25X_FastReadDual 0x3B +#define W25X_PageProgram 0x02 +#define W25X_BlockErase 0xD8 +#define W25X_SectorErase 0x20 +#define W25X_ChipErase 0xC7 +#define W25X_PowerDown 0xB9 +#define W25X_ReleasePowerDown 0xAB +#define W25X_DeviceID 0xAB +#define W25X_ManufactDeviceID 0x90 +#define W25X_JedecDeviceID 0x9F + +#define WIP_Flag 0x01 /* Write In Progress (WIP) flag */ + +#define Dummy_Byte 0xA5 + +#define SPI_FLASH_SectorSize 4096 +#define SPI_FLASH_PageSize 256 +#define SPI_FLASH_PerWritePageSize 256 + +class W25QXXFlash { +public: + void init(uint8_t spiRate); + static uint8_t spi_flash_Rec(); + static uint8_t spi_flash_read_write_byte(uint8_t data); + static void spi_flash_Read(uint8_t* buf, uint16_t nbyte); + static void spi_flash_Send(uint8_t b); + static void spi_flash_SendBlock(uint8_t token, const uint8_t* buf); + static uint16_t W25QXX_ReadID(void); + static void SPI_FLASH_WriteEnable(void); + static void SPI_FLASH_WaitForWriteEnd(void); + static void SPI_FLASH_SectorErase(uint32_t SectorAddr); + static void SPI_FLASH_BlockErase(uint32_t BlockAddr); + static void SPI_FLASH_BulkErase(void); + static void SPI_FLASH_PageWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite); + static void SPI_FLASH_BufferWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite); + static void SPI_FLASH_BufferRead(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead); +}; + +extern W25QXXFlash W25QXX; diff --git a/Marlin/src/libs/bresenham.h b/Marlin/src/libs/bresenham.h index e18531498b11..ade231e26dc7 100644 --- a/Marlin/src/libs/bresenham.h +++ b/Marlin/src/libs/bresenham.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/libs/buzzer.cpp b/Marlin/src/libs/buzzer.cpp index 35631708c425..84596953596c 100644 --- a/Marlin/src/libs/buzzer.cpp +++ b/Marlin/src/libs/buzzer.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -28,7 +28,7 @@ #include "../module/temperature.h" #if ENABLED(EXTENSIBLE_UI) - #include "../lcd/extensible_ui/ui_api.h" + #include "../lcd/extui/ui_api.h" #endif Buzzer::state_t Buzzer::state; @@ -66,7 +66,8 @@ void Buzzer::tick() { CRITICAL_SECTION_START(); ExtUI::onPlayTone(state.tone.frequency, state.tone.duration); CRITICAL_SECTION_END(); - #elif ENABLED(SPEAKER) + #endif + #if ENABLED(SPEAKER) && (DISABLED(EXTENSIBLE_UI) || ENABLED(EXTUI_LOCAL_BEEPER)) CRITICAL_SECTION_START(); ::tone(BEEPER_PIN, state.tone.frequency, state.tone.duration); CRITICAL_SECTION_END(); diff --git a/Marlin/src/libs/buzzer.h b/Marlin/src/libs/buzzer.h index 3a72a0bd86a6..e901660c87d1 100644 --- a/Marlin/src/libs/buzzer.h +++ b/Marlin/src/libs/buzzer.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -84,9 +84,9 @@ public: /** - * @brief Class constructor + * @brief Init Buzzer */ - Buzzer() { + static inline void init() { SET_OUTPUT(BEEPER_PIN); reset(); } diff --git a/Marlin/src/libs/circularqueue.h b/Marlin/src/libs/circularqueue.h index 54a6edaabe20..4d4a464b9c6a 100644 --- a/Marlin/src/libs/circularqueue.h +++ b/Marlin/src/libs/circularqueue.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/libs/crc16.cpp b/Marlin/src/libs/crc16.cpp index 71cda50aebaa..c2195619c772 100644 --- a/Marlin/src/libs/crc16.cpp +++ b/Marlin/src/libs/crc16.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/libs/crc16.h b/Marlin/src/libs/crc16.h index 65e036d08999..1760ecd6f880 100644 --- a/Marlin/src/libs/crc16.h +++ b/Marlin/src/libs/crc16.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/libs/duration_t.h b/Marlin/src/libs/duration_t.h index 897ea1e8694d..31d8bab38581 100644 --- a/Marlin/src/libs/duration_t.h +++ b/Marlin/src/libs/duration_t.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/libs/heatshrink/heatshrink_decoder.cpp b/Marlin/src/libs/heatshrink/heatshrink_decoder.cpp index 4684af975e80..3f0f828cd78b 100644 --- a/Marlin/src/libs/heatshrink/heatshrink_decoder.cpp +++ b/Marlin/src/libs/heatshrink/heatshrink_decoder.cpp @@ -1,9 +1,36 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfigPre.h" + +#if ENABLED(BINARY_FILE_TRANSFER) + /** * libs/heatshrink/heatshrink_decoder.cpp */ +#include "heatshrink_decoder.h" + #include #include -#include "heatshrink_decoder.h" #pragma GCC optimize ("O3") @@ -353,3 +380,5 @@ static void push_byte(heatshrink_decoder *hsd, output_info *oi, uint8_t byte) { oi->buf[(*oi->output_size)++] = byte; (void)hsd; } + +#endif // BINARY_FILE_TRANSFER diff --git a/Marlin/src/libs/heatshrink/heatshrink_decoder.h b/Marlin/src/libs/heatshrink/heatshrink_decoder.h index 11fafe617fff..eb113aa5e568 100644 --- a/Marlin/src/libs/heatshrink/heatshrink_decoder.h +++ b/Marlin/src/libs/heatshrink/heatshrink_decoder.h @@ -1,13 +1,36 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + /** * libs/heatshrink/heatshrink_decoder.h */ #pragma once -#include -#include #include "heatshrink_common.h" #include "heatshrink_config.h" +#include +#include + typedef enum { HSDR_SINK_OK, /* data sunk, ready to poll */ HSDR_SINK_FULL, /* out of space in internal buffer */ diff --git a/Marlin/src/libs/hex_print.cpp b/Marlin/src/libs/hex_print.cpp new file mode 100644 index 000000000000..0f746d628470 --- /dev/null +++ b/Marlin/src/libs/hex_print.cpp @@ -0,0 +1,90 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../inc/MarlinConfigPre.h" + +#if NEED_HEX_PRINT + +#include "hex_print.h" +#include "../core/serial.h" + +#ifdef CPU_32_BIT + constexpr int byte_start = 4; + static char _hex[] = "0x00000000"; +#else + constexpr int byte_start = 0; + static char _hex[] = "0x0000"; +#endif + +char* hex_byte(const uint8_t b) { + _hex[byte_start + 4] = hex_nybble(b >> 4); + _hex[byte_start + 5] = hex_nybble(b); + return &_hex[byte_start + 4]; +} + +inline void _hex_word(const uint16_t w) { + _hex[byte_start + 2] = hex_nybble(w >> 12); + _hex[byte_start + 3] = hex_nybble(w >> 8); + _hex[byte_start + 4] = hex_nybble(w >> 4); + _hex[byte_start + 5] = hex_nybble(w); +} + +char* hex_word(const uint16_t w) { + _hex_word(w); + return &_hex[byte_start + 2]; +} + +#ifdef CPU_32_BIT + char* hex_long(const uintptr_t l) { + _hex[2] = hex_nybble(l >> 28); + _hex[3] = hex_nybble(l >> 24); + _hex[4] = hex_nybble(l >> 20); + _hex[5] = hex_nybble(l >> 16); + _hex_word((uint16_t)(l & 0xFFFF)); + return &_hex[2]; + } +#endif + +char* hex_address(const void * const w) { + #ifdef CPU_32_BIT + (void)hex_long((uintptr_t)w); + #else + (void)hex_word((uintptr_t)w); + #endif + return _hex; +} + +void print_hex_nybble(const uint8_t n) { SERIAL_CHAR(hex_nybble(n)); } +void print_hex_byte(const uint8_t b) { SERIAL_ECHO(hex_byte(b)); } +void print_hex_word(const uint16_t w) { SERIAL_ECHO(hex_word(w)); } +void print_hex_address(const void * const w) { SERIAL_ECHO(hex_address(w)); } + +void print_hex_long(const uint32_t w, const char delimiter) { + SERIAL_ECHOPGM("0x"); + for (int B = 24; B >= 8; B -= 8){ + print_hex_byte(w >> B); + SERIAL_CHAR(delimiter); + } + print_hex_byte(w); +} + +#endif // NEED_HEX_PRINT diff --git a/Marlin/src/libs/hex_print_routines.h b/Marlin/src/libs/hex_print.h similarity index 89% rename from Marlin/src/libs/hex_print_routines.h rename to Marlin/src/libs/hex_print.h index ac47ed7701c6..40baa15bcc11 100644 --- a/Marlin/src/libs/hex_print_routines.h +++ b/Marlin/src/libs/hex_print.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -39,9 +39,3 @@ void print_hex_byte(const uint8_t b); void print_hex_word(const uint16_t w); void print_hex_address(const void * const w); void print_hex_long(const uint32_t w, const char delimiter); - -#ifdef CPU_32_BIT - typedef uint32_t ptr_int_t; -#else - typedef uint16_t ptr_int_t; -#endif diff --git a/Marlin/src/libs/hex_print_routines.cpp b/Marlin/src/libs/hex_print_routines.cpp deleted file mode 100644 index 293192e6efbf..000000000000 --- a/Marlin/src/libs/hex_print_routines.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfig.h" -#include "../gcode/parser.h" - -#if ANY(AUTO_BED_LEVELING_UBL, M100_FREE_MEMORY_WATCHER, DEBUG_GCODE_PARSER, TMC_DEBUG) - - #include "hex_print_routines.h" - - #ifdef CPU_32_BIT - constexpr int byte_start = 4; - static char _hex[] = "0x00000000"; - #else - constexpr int byte_start = 0; - static char _hex[] = "0x0000"; - #endif - - char* hex_byte(const uint8_t b) { - _hex[byte_start + 4] = hex_nybble(b >> 4); - _hex[byte_start + 5] = hex_nybble(b); - return &_hex[byte_start + 4]; - } - - inline void _hex_word(const uint16_t w) { - _hex[byte_start + 2] = hex_nybble(w >> 12); - _hex[byte_start + 3] = hex_nybble(w >> 8); - _hex[byte_start + 4] = hex_nybble(w >> 4); - _hex[byte_start + 5] = hex_nybble(w); - } - - char* hex_word(const uint16_t w) { - _hex_word(w); - return &_hex[byte_start + 2]; - } - - #ifdef CPU_32_BIT - char* hex_long(const uint32_t l) { - _hex[2] = hex_nybble(l >> 28); - _hex[3] = hex_nybble(l >> 24); - _hex[4] = hex_nybble(l >> 20); - _hex[5] = hex_nybble(l >> 16); - _hex_word((uint16_t)(l & 0xFFFF)); - return &_hex[2]; - } - #endif - - char* hex_address(const void * const w) { - #ifdef CPU_32_BIT - (void)hex_long((ptr_int_t)w); - #else - (void)hex_word((ptr_int_t)w); - #endif - return _hex; - } - - void print_hex_nybble(const uint8_t n) { SERIAL_CHAR(hex_nybble(n)); } - void print_hex_byte(const uint8_t b) { SERIAL_ECHO(hex_byte(b)); } - void print_hex_word(const uint16_t w) { SERIAL_ECHO(hex_word(w)); } - void print_hex_address(const void * const w) { SERIAL_ECHO(hex_address(w)); } - - void print_hex_long(const uint32_t w, const char delimiter) { - SERIAL_ECHOPGM("0x"); - for (int B = 24; B >= 8; B -= 8){ - print_hex_byte(w >> B); - SERIAL_CHAR(delimiter); - } - print_hex_byte(w); - } - -#endif // AUTO_BED_LEVELING_UBL || M100_FREE_MEMORY_WATCHER || DEBUG_GCODE_PARSER diff --git a/Marlin/src/libs/least_squares_fit.cpp b/Marlin/src/libs/least_squares_fit.cpp index aac83f9aca8e..c7593c049fc4 100644 --- a/Marlin/src/libs/least_squares_fit.cpp +++ b/Marlin/src/libs/least_squares_fit.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -29,12 +29,11 @@ * it saves roughly 10K of program memory. It also does not require all of * coordinates to be present during the calculations. Each point can be * probed and then discarded. - * */ #include "../inc/MarlinConfig.h" -#if ANY(AUTO_BED_LEVELING_UBL, AUTO_BED_LEVELING_LINEAR, Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS) +#if NEED_LSF #include "least_squares_fit.h" @@ -67,4 +66,4 @@ int finish_incremental_LSF(struct linear_fit_data *lsf) { return 0; } -#endif // AUTO_BED_LEVELING_UBL || ENABLED(AUTO_BED_LEVELING_LINEAR) +#endif // NEED_LSF diff --git a/Marlin/src/libs/least_squares_fit.h b/Marlin/src/libs/least_squares_fit.h index 721c499decad..44ca8afc76d8 100644 --- a/Marlin/src/libs/least_squares_fit.h +++ b/Marlin/src/libs/least_squares_fit.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -30,7 +30,6 @@ * it saves roughly 10K of program memory. And even better... the data * fed into the algorithm does not need to all be present at the same time. * A point can be probed and its values fed into the algorithm and then discarded. - * */ #include "../inc/MarlinConfig.h" diff --git a/Marlin/src/libs/nozzle.cpp b/Marlin/src/libs/nozzle.cpp index 58ba57e42571..10021005e5b3 100644 --- a/Marlin/src/libs/nozzle.cpp +++ b/Marlin/src/libs/nozzle.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -42,26 +42,31 @@ Nozzle nozzle; * @param strokes number of strokes to execute */ void Nozzle::stroke(const xyz_pos_t &start, const xyz_pos_t &end, const uint8_t &strokes) { - #if ENABLED(NOZZLE_CLEAN_GOBACK) - const xyz_pos_t oldpos = current_position; - #endif + TERN_(NOZZLE_CLEAN_GOBACK, const xyz_pos_t oldpos = current_position); // Move to the starting point #if ENABLED(NOZZLE_CLEAN_NO_Z) - do_blocking_move_to_xy(start); + #if ENABLED(NOZZLE_CLEAN_NO_Y) + do_blocking_move_to_x(start.x); + #else + do_blocking_move_to_xy(start); + #endif #else do_blocking_move_to(start); #endif // Start the stroke pattern - for (uint8_t i = 0; i < (strokes >> 1); i++) { - do_blocking_move_to_xy(end); - do_blocking_move_to_xy(start); + LOOP_L_N(i, strokes >> 1) { + #if ENABLED(NOZZLE_CLEAN_NO_Y) + do_blocking_move_to_x(end.x); + do_blocking_move_to_x(start.x); + #else + do_blocking_move_to_xy(end); + do_blocking_move_to_xy(start); + #endif } - #if ENABLED(NOZZLE_CLEAN_GOBACK) - do_blocking_move_to(oldpos); - #endif + TERN_(NOZZLE_CLEAN_GOBACK, do_blocking_move_to(oldpos)); } /** @@ -77,9 +82,7 @@ Nozzle nozzle; const xy_pos_t diff = end - start; if (!diff.x || !diff.y) return; - #if ENABLED(NOZZLE_CLEAN_GOBACK) - const xyz_pos_t back = current_position; - #endif + TERN_(NOZZLE_CLEAN_GOBACK, const xyz_pos_t back = current_position); #if ENABLED(NOZZLE_CLEAN_NO_Z) do_blocking_move_to_xy(start); @@ -91,7 +94,7 @@ Nozzle nozzle; const bool horiz = ABS(diff.x) >= ABS(diff.y); // Do a horizontal wipe? const float P = (horiz ? diff.x : diff.y) / zigs; // Period of each zig / zag const xyz_pos_t *side; - for (uint8_t j = 0; j < strokes; j++) { + LOOP_L_N(j, strokes) { for (int8_t i = 0; i < zigs; i++) { side = (i & 1) ? &end : &start; if (horiz) @@ -108,9 +111,7 @@ Nozzle nozzle; } } - #if ENABLED(NOZZLE_CLEAN_GOBACK) - do_blocking_move_to(back); - #endif + TERN_(NOZZLE_CLEAN_GOBACK, do_blocking_move_to(back)); } /** @@ -124,18 +125,11 @@ Nozzle nozzle; void Nozzle::circle(const xyz_pos_t &start, const xyz_pos_t &middle, const uint8_t &strokes, const float &radius) { if (strokes == 0) return; - #if ENABLED(NOZZLE_CLEAN_GOBACK) - const xyz_pos_t back = current_position; - #endif - - #if ENABLED(NOZZLE_CLEAN_NO_Z) - do_blocking_move_to_xy(start); - #else - do_blocking_move_to(start); - #endif + TERN_(NOZZLE_CLEAN_GOBACK, const xyz_pos_t back = current_position); + TERN(NOZZLE_CLEAN_NO_Z, do_blocking_move_to_xy, do_blocking_move_to)(start); - for (uint8_t s = 0; s < strokes; s++) - for (uint8_t i = 0; i < NOZZLE_CLEAN_CIRCLE_FN; i++) + LOOP_L_N(s, strokes) + LOOP_L_N(i, NOZZLE_CLEAN_CIRCLE_FN) do_blocking_move_to_xy( middle.x + sin((RADIANS(360) / NOZZLE_CLEAN_CIRCLE_FN) * i) * radius, middle.y + cos((RADIANS(360) / NOZZLE_CLEAN_CIRCLE_FN) * i) * radius @@ -144,9 +138,7 @@ Nozzle nozzle; // Let's be safe do_blocking_move_to_xy(start); - #if ENABLED(NOZZLE_CLEAN_GOBACK) - do_blocking_move_to(back); - #endif + TERN_(NOZZLE_CLEAN_GOBACK, do_blocking_move_to(back)); } /** @@ -159,22 +151,50 @@ Nozzle nozzle; void Nozzle::clean(const uint8_t &pattern, const uint8_t &strokes, const float &radius, const uint8_t &objects, const uint8_t cleans) { xyz_pos_t start[HOTENDS] = NOZZLE_CLEAN_START_POINT, end[HOTENDS] = NOZZLE_CLEAN_END_POINT, middle[HOTENDS] = NOZZLE_CLEAN_CIRCLE_MIDDLE; + const uint8_t arrPos = ANY(SINGLENOZZLE, MIXING_EXTRUDER) ? 0 : active_extruder; + + #if HAS_SOFTWARE_ENDSTOPS + + #define LIMIT_AXIS(A) do{ \ + LIMIT( start[arrPos].A, soft_endstop.min.A, soft_endstop.max.A); \ + LIMIT(middle[arrPos].A, soft_endstop.min.A, soft_endstop.max.A); \ + LIMIT( end[arrPos].A, soft_endstop.min.A, soft_endstop.max.A); \ + }while(0) + + if (soft_endstop.enabled()) { + + LIMIT_AXIS(x); + LIMIT_AXIS(y); + LIMIT_AXIS(z); + const bool radiusOutOfRange = (middle[arrPos].x + radius > soft_endstop.max.x) + || (middle[arrPos].x - radius < soft_endstop.min.x) + || (middle[arrPos].y + radius > soft_endstop.max.y) + || (middle[arrPos].y - radius < soft_endstop.min.y); + if (radiusOutOfRange && pattern == 2) { + SERIAL_ECHOLNPGM("Warning: Radius Out of Range"); + return; + } + + } + + #endif + if (pattern == 2) { if (!(cleans & (_BV(X_AXIS) | _BV(Y_AXIS)))) { - SERIAL_ECHOLNPGM("Warning : Clean Circle requires XY"); + SERIAL_ECHOLNPGM("Warning: Clean Circle requires XY"); return; } } else { - if (!TEST(cleans, X_AXIS)) start[active_extruder].x = end[active_extruder].x = current_position.x; - if (!TEST(cleans, Y_AXIS)) start[active_extruder].y = end[active_extruder].y = current_position.y; + if (!TEST(cleans, X_AXIS)) start[arrPos].x = end[arrPos].x = current_position.x; + if (!TEST(cleans, Y_AXIS)) start[arrPos].y = end[arrPos].y = current_position.y; } - if (!TEST(cleans, Z_AXIS)) start[active_extruder].z = end[active_extruder].z = current_position.z; + if (!TEST(cleans, Z_AXIS)) start[arrPos].z = end[arrPos].z = current_position.z; switch (pattern) { - case 1: zigzag(start[active_extruder], end[active_extruder], strokes, objects); break; - case 2: circle(start[active_extruder], middle[active_extruder], strokes, radius); break; - default: stroke(start[active_extruder], end[active_extruder], strokes); + case 1: zigzag(start[arrPos], end[arrPos], strokes, objects); break; + case 2: circle(start[arrPos], middle[arrPos], strokes, radius); break; + default: stroke(start[arrPos], end[arrPos], strokes); } } @@ -194,11 +214,22 @@ Nozzle nozzle; do_blocking_move_to_z(_MIN(current_position.z + park.z, Z_MAX_POS), fr_z); break; - default: // Raise to at least the Z-park height - do_blocking_move_to_z(_MAX(park.z, current_position.z), fr_z); + default: { + // Apply a minimum raise, overriding G27 Z + const float min_raised_z =_MIN(Z_MAX_POS, current_position.z + #ifdef NOZZLE_PARK_Z_RAISE_MIN + + NOZZLE_PARK_Z_RAISE_MIN + #endif + ); + do_blocking_move_to_z(_MAX(park.z, min_raised_z), fr_z); + } break; } - do_blocking_move_to_xy(park, fr_xy); + do_blocking_move_to_xy( + TERN(NOZZLE_PARK_Y_ONLY, current_position, park).x, + TERN(NOZZLE_PARK_X_ONLY, current_position, park).y, + fr_xy + ); report_current_position(); } diff --git a/Marlin/src/libs/nozzle.h b/Marlin/src/libs/nozzle.h index 3ff0670ce837..81594b13817d 100644 --- a/Marlin/src/libs/nozzle.h +++ b/Marlin/src/libs/nozzle.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/libs/numtostr.cpp b/Marlin/src/libs/numtostr.cpp index e5ddc147489b..c3efb2b25a84 100644 --- a/Marlin/src/libs/numtostr.cpp +++ b/Marlin/src/libs/numtostr.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -31,9 +31,11 @@ char conv[8] = { 0 }; #define DIGIMOD(n, f) DIGIT((n)/(f) % 10) #define RJDIGIT(n, f) ((n) >= (f) ? DIGIMOD(n, f) : ' ') #define MINUSOR(n, alt) (n >= 0 ? (alt) : (n = -n, '-')) +#define INTFLOAT(V,N) (((V) * 10 * pow(10, N) + ((V) < 0 ? -5: 5)) / 10) // pow10? +#define UINTFLOAT(V,N) INTFLOAT((V) < 0 ? -(V) : (V), N) // Convert a full-range unsigned 8bit int to a percentage -const char* ui8tostr4pct(const uint8_t i) { +const char* ui8tostr4pctrj(const uint8_t i) { const uint8_t n = ui8_to_percent(i); conv[3] = RJDIGIT(n, 100); conv[4] = RJDIGIT(n, 10); @@ -43,15 +45,22 @@ const char* ui8tostr4pct(const uint8_t i) { } // Convert unsigned 8bit int to string 123 format -const char* ui8tostr3(const uint8_t i) { +const char* ui8tostr3rj(const uint8_t i) { conv[4] = RJDIGIT(i, 100); conv[5] = RJDIGIT(i, 10); conv[6] = DIGIMOD(i, 1); return &conv[4]; } +// Convert uint8_t to string with 12 format +const char* ui8tostr2(const uint8_t i) { + conv[5] = DIGIMOD(i, 10); + conv[6] = DIGIMOD(i, 1); + return &conv[5]; +} + // Convert signed 8bit int to rj string with 123 or -12 format -const char* i8tostr3(const int8_t x) { +const char* i8tostr3rj(const int8_t x) { int xx = x; conv[4] = MINUSOR(xx, RJDIGIT(xx, 100)); conv[5] = RJDIGIT(xx, 10); @@ -88,7 +97,7 @@ const char* i8tostr3(const int8_t x) { #endif // Convert unsigned 16bit int to string 12345 format -const char* ui16tostr5(const uint16_t xx) { +const char* ui16tostr5rj(const uint16_t xx) { conv[2] = RJDIGIT(xx, 10000); conv[3] = RJDIGIT(xx, 1000); conv[4] = RJDIGIT(xx, 100); @@ -98,7 +107,7 @@ const char* ui16tostr5(const uint16_t xx) { } // Convert unsigned 16bit int to string 1234 format -const char* ui16tostr4(const uint16_t xx) { +const char* ui16tostr4rj(const uint16_t xx) { conv[3] = RJDIGIT(xx, 1000); conv[4] = RJDIGIT(xx, 100); conv[5] = RJDIGIT(xx, 10); @@ -107,7 +116,7 @@ const char* ui16tostr4(const uint16_t xx) { } // Convert unsigned 16bit int to string 123 format -const char* ui16tostr3(const uint16_t xx) { +const char* ui16tostr3rj(const uint16_t xx) { conv[4] = RJDIGIT(xx, 100); conv[5] = RJDIGIT(xx, 10); conv[6] = DIGIMOD(xx, 1); @@ -115,7 +124,7 @@ const char* ui16tostr3(const uint16_t xx) { } // Convert signed 16bit int to rj string with 123 or -12 format -const char* i16tostr3(const int16_t x) { +const char* i16tostr3rj(const int16_t x) { int xx = x; conv[4] = MINUSOR(xx, RJDIGIT(xx, 100)); conv[5] = RJDIGIT(xx, 10); @@ -136,7 +145,7 @@ const char* i16tostr3left(const int16_t i) { } // Convert signed 16bit int to rj string with 1234, _123, -123, _-12, or __-1 format -const char* i16tostr4sign(const int16_t i) { +const char* i16tostr4signrj(const int16_t i) { const bool neg = i < 0; const int ii = neg ? -i : i; if (i >= 1000) { @@ -166,7 +175,7 @@ const char* i16tostr4sign(const int16_t i) { // Convert unsigned float to string with 1.23 format const char* ftostr12ns(const float &f) { - const long i = ((f < 0 ? -f : f) * 1000 + 5) / 10; + const long i = UINTFLOAT(f, 2); conv[3] = DIGIMOD(i, 100); conv[4] = '.'; conv[5] = DIGIMOD(i, 10); @@ -174,10 +183,31 @@ const char* ftostr12ns(const float &f) { return &conv[3]; } -// Convert signed float to fixed-length string with 12.34 / -2.34 format or 123.45 / -23.45 format +// Convert unsigned float to string with 12.3 format +const char* ftostr31ns(const float &f) { + const long i = UINTFLOAT(f, 1); + conv[3] = DIGIMOD(i, 100); + conv[4] = DIGIMOD(i, 10); + conv[5] = '.'; + conv[6] = DIGIMOD(i, 1); + return &conv[3]; +} + +// Convert unsigned float to string with 123.4 format +const char* ftostr41ns(const float &f) { + const long i = UINTFLOAT(f, 1); + conv[2] = DIGIMOD(i, 1000); + conv[3] = DIGIMOD(i, 100); + conv[4] = DIGIMOD(i, 10); + conv[5] = '.'; + conv[6] = DIGIMOD(i, 1); + return &conv[2]; +} + +// Convert signed float to fixed-length string with 12.34 / _2.34 / -2.34 or -23.45 / 123.45 format const char* ftostr42_52(const float &f) { - if (f <= -10 || f >= 100) return ftostr52(f); // need more digits - long i = (f * 1000 + (f < 0 ? -5: 5)) / 10; + if (f <= -10 || f >= 100) return ftostr52(f); // -23.45 / 123.45 + long i = INTFLOAT(f, 2); conv[2] = (f >= 0 && f < 10) ? ' ' : MINUSOR(i, DIGIMOD(i, 1000)); conv[3] = DIGIMOD(i, 100); conv[4] = '.'; @@ -188,7 +218,7 @@ const char* ftostr42_52(const float &f) { // Convert signed float to fixed-length string with 023.45 / -23.45 format const char* ftostr52(const float &f) { - long i = (f * 1000 + (f < 0 ? -5: 5)) / 10; + long i = INTFLOAT(f, 2); conv[1] = MINUSOR(i, DIGIMOD(i, 10000)); conv[2] = DIGIMOD(i, 1000); conv[3] = DIGIMOD(i, 100); @@ -198,12 +228,38 @@ const char* ftostr52(const float &f) { return &conv[1]; } +// Convert signed float to fixed-length string with 12.345 / _2.345 / -2.345 or -23.45 / 123.45 format +const char* ftostr53_63(const float &f) { + if (f <= -10 || f >= 100) return ftostr63(f); // -23.456 / 123.456 + long i = INTFLOAT(f, 3); + conv[1] = (f >= 0 && f < 10) ? ' ' : MINUSOR(i, DIGIMOD(i, 10000)); + conv[2] = DIGIMOD(i, 1000); + conv[3] = '.'; + conv[4] = DIGIMOD(i, 100); + conv[5] = DIGIMOD(i, 10); + conv[6] = DIGIMOD(i, 1); + return &conv[1]; +} + +// Convert signed float to fixed-length string with 023.456 / -23.456 format +const char* ftostr63(const float &f) { + long i = INTFLOAT(f, 3); + conv[0] = MINUSOR(i, DIGIMOD(i, 100000)); + conv[1] = DIGIMOD(i, 10000); + conv[2] = DIGIMOD(i, 1000); + conv[3] = '.'; + conv[4] = DIGIMOD(i, 100); + conv[5] = DIGIMOD(i, 10); + conv[6] = DIGIMOD(i, 1); + return &conv[0]; +} + #if ENABLED(LCD_DECIMAL_SMALL_XY) // Convert float to rj string with 1234, _123, -123, _-12, 12.3, _1.2, or -1.2 format const char* ftostr4sign(const float &f) { - const int i = (f * 100 + (f < 0 ? -5: 5)) / 10; - if (!WITHIN(i, -99, 999)) return i16tostr4sign((int)f); + const int i = INTFLOAT(f, 1); + if (!WITHIN(i, -99, 999)) return i16tostr4signrj((int)f); const bool neg = i < 0; const int ii = neg ? -i : i; conv[3] = neg ? '-' : (ii >= 100 ? DIGIMOD(ii, 100) : ' '); @@ -215,9 +271,20 @@ const char* ftostr52(const float &f) { #endif +// Convert float to fixed-length string with +12.3 / -12.3 format +const char* ftostr31sign(const float &f) { + int i = INTFLOAT(f, 1); + conv[2] = MINUSOR(i, '+'); + conv[3] = DIGIMOD(i, 100); + conv[4] = DIGIMOD(i, 10); + conv[5] = '.'; + conv[6] = DIGIMOD(i, 1); + return &conv[2]; +} + // Convert float to fixed-length string with +123.4 / -123.4 format const char* ftostr41sign(const float &f) { - int i = (f * 100 + (f < 0 ? -5: 5)) / 10; + int i = INTFLOAT(f, 1); conv[1] = MINUSOR(i, '+'); conv[2] = DIGIMOD(i, 1000); conv[3] = DIGIMOD(i, 100); @@ -229,7 +296,7 @@ const char* ftostr41sign(const float &f) { // Convert signed float to string (6 digit) with -1.234 / _0.000 / +1.234 format const char* ftostr43sign(const float &f, char plus/*=' '*/) { - long i = (f * 10000 + (f < 0 ? -5: 5)) / 10; + long i = INTFLOAT(f, 3); conv[1] = i ? MINUSOR(i, plus) : ' '; conv[2] = DIGIMOD(i, 1000); conv[3] = '.'; @@ -241,7 +308,7 @@ const char* ftostr43sign(const float &f, char plus/*=' '*/) { // Convert signed float to string (5 digit) with -1.2345 / _0.0000 / +1.2345 format const char* ftostr54sign(const float &f, char plus/*=' '*/) { - long i = (f * 100000 + (f < 0 ? -5: 5)) / 10; + long i = INTFLOAT(f, 4); conv[0] = i ? MINUSOR(i, plus) : ' '; conv[1] = DIGIMOD(i, 10000); conv[2] = '.'; @@ -254,13 +321,13 @@ const char* ftostr54sign(const float &f, char plus/*=' '*/) { // Convert unsigned float to rj string with 12345 format const char* ftostr5rj(const float &f) { - const long i = ((f < 0 ? -f : f) * 10 + 5) / 10; - return ui16tostr5(i); + const long i = UINTFLOAT(f, 0); + return ui16tostr5rj(i); } // Convert signed float to string with +1234.5 format const char* ftostr51sign(const float &f) { - long i = (f * 100 + (f < 0 ? -5: 5)) / 10; + long i = INTFLOAT(f, 1); conv[0] = MINUSOR(i, '+'); conv[1] = DIGIMOD(i, 10000); conv[2] = DIGIMOD(i, 1000); @@ -273,7 +340,7 @@ const char* ftostr51sign(const float &f) { // Convert signed float to string with +123.45 format const char* ftostr52sign(const float &f) { - long i = (f * 1000 + (f < 0 ? -5: 5)) / 10; + long i = INTFLOAT(f, 2); conv[0] = MINUSOR(i, '+'); conv[1] = DIGIMOD(i, 10000); conv[2] = DIGIMOD(i, 1000); @@ -284,9 +351,22 @@ const char* ftostr52sign(const float &f) { return conv; } -// Convert unsigned float to string with 1234.5 format omitting trailing zeros +// Convert signed float to string with +12.345 format +const char* ftostr53sign(const float &f) { + long i = INTFLOAT(f, 3); + conv[0] = MINUSOR(i, '+'); + conv[1] = DIGIMOD(i, 10000); + conv[2] = DIGIMOD(i, 1000); + conv[3] = '.'; + conv[4] = DIGIMOD(i, 100); + conv[5] = DIGIMOD(i, 10); + conv[6] = DIGIMOD(i, 1); + return conv; +} + +// Convert unsigned float to string with ____4.5, __34.5, _234.5, 1234.5 format const char* ftostr51rj(const float &f) { - const long i = ((f < 0 ? -f : f) * 100 + 5) / 10; + const long i = UINTFLOAT(f, 1); conv[0] = ' '; conv[1] = RJDIGIT(i, 10000); conv[2] = RJDIGIT(i, 1000); @@ -299,7 +379,7 @@ const char* ftostr51rj(const float &f) { // Convert signed float to space-padded string with -_23.4_ format const char* ftostr52sp(const float &f) { - long i = (f * 1000 + (f < 0 ? -5: 5)) / 10; + long i = INTFLOAT(f, 2); uint8_t dig; conv[0] = MINUSOR(i, ' '); conv[1] = RJDIGIT(i, 10000); diff --git a/Marlin/src/libs/numtostr.h b/Marlin/src/libs/numtostr.h index ee29b26ab08e..e7c1e67e12d5 100644 --- a/Marlin/src/libs/numtostr.h +++ b/Marlin/src/libs/numtostr.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -24,13 +24,16 @@ #include // Convert a full-range unsigned 8bit int to a percentage -const char* ui8tostr4pct(const uint8_t i); +const char* ui8tostr4pctrj(const uint8_t i); + +// Convert uint8_t to string with 12 format +const char* ui8tostr2(const uint8_t x); // Convert uint8_t to string with 123 format -const char* ui8tostr3(const uint8_t i); +const char* ui8tostr3rj(const uint8_t i); // Convert int8_t to string with 123 format -const char* i8tostr3(const int8_t x); +const char* i8tostr3rj(const int8_t x); #if HAS_PRINT_PROGRESS_PERMYRIAD // Convert 16-bit unsigned permyriad value to percent: 100 / 23 / 23.4 / 3.45 @@ -38,32 +41,47 @@ const char* i8tostr3(const int8_t x); #endif // Convert uint16_t to string with 12345 format -const char* ui16tostr5(const uint16_t x); +const char* ui16tostr5rj(const uint16_t x); // Convert uint16_t to string with 1234 format -const char* ui16tostr4(const uint16_t x); +const char* ui16tostr4rj(const uint16_t x); // Convert uint16_t to string with 123 format -const char* ui16tostr3(const uint16_t x); +const char* ui16tostr3rj(const uint16_t x); // Convert int16_t to string with 123 format -const char* i16tostr3(const int16_t x); +const char* i16tostr3rj(const int16_t x); // Convert unsigned int to lj string with 123 format const char* i16tostr3left(const int16_t xx); // Convert signed int to rj string with _123, -123, _-12, or __-1 format -const char* i16tostr4sign(const int16_t x); +const char* i16tostr4signrj(const int16_t x); // Convert unsigned float to string with 1.23 format const char* ftostr12ns(const float &x); -// Convert signed float to fixed-length string with 12.34 / -2.34 or 023.45 / -23.45 format +// Convert unsigned float to string with 12.3 format +const char* ftostr31ns(const float &x); + +// Convert unsigned float to string with 123.4 format +const char* ftostr41ns(const float &x); + +// Convert signed float to fixed-length string with 12.34 / _2.34 / -2.34 or -23.45 / 123.45 format const char* ftostr42_52(const float &x); // Convert signed float to fixed-length string with 023.45 / -23.45 format const char* ftostr52(const float &x); +// Convert signed float to fixed-length string with 12.345 / -2.345 or 023.456 / -23.456 format +const char* ftostr53_63(const float &x); + +// Convert signed float to fixed-length string with 023.456 / -23.456 format +const char* ftostr63(const float &x); + +// Convert float to fixed-length string with +12.3 / -12.3 format +const char* ftostr31sign(const float &x); + // Convert float to fixed-length string with +123.4 / -123.4 format const char* ftostr41sign(const float &x); @@ -85,13 +103,16 @@ const char* ftostr52sp(const float &x); // Convert signed float to string with +123.45 format const char* ftostr52sign(const float &x); +// Convert signed float to string with +12.345 format +const char* ftostr53sign(const float &f); + // Convert unsigned float to string with 1234.5 format omitting trailing zeros const char* ftostr51rj(const float &x); #include "../core/macros.h" // Convert float to rj string with 123 or -12 format -FORCE_INLINE const char* ftostr3(const float &x) { return i16tostr3(int16_t(x + (x < 0 ? -0.5f : 0.5f))); } +FORCE_INLINE const char* ftostr3(const float &x) { return i16tostr3rj(int16_t(x + (x < 0 ? -0.5f : 0.5f))); } #include "../inc/MarlinConfigPre.h" @@ -100,5 +121,5 @@ FORCE_INLINE const char* ftostr3(const float &x) { return i16tostr3(int16_t(x + const char* ftostr4sign(const float &fx); #else // Convert float to rj string with 1234, _123, -123, __12, _-12, ___1, or __-1 format - FORCE_INLINE const char* ftostr4sign(const float &x) { return i16tostr4sign(int16_t(x + (x < 0 ? -0.5f : 0.5f))); } + FORCE_INLINE const char* ftostr4sign(const float &x) { return i16tostr4signrj(int16_t(x + (x < 0 ? -0.5f : 0.5f))); } #endif diff --git a/Marlin/src/libs/private_spi.h b/Marlin/src/libs/private_spi.h index 9ce68c4909b2..9c0ffe7486d7 100644 --- a/Marlin/src/libs/private_spi.h +++ b/Marlin/src/libs/private_spi.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -43,7 +43,7 @@ class SPIclass { SET_INPUT_PULLUP(MISO_PIN); } FORCE_INLINE static uint8_t receive() { - #if defined(__AVR__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) + #if defined(__AVR__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__IMXRT1062__) SPDR = 0; for (;!TEST(SPSR, SPIF);); return SPDR; diff --git a/Marlin/src/libs/softspi.h b/Marlin/src/libs/softspi.h index 300eb9387118..5d48f9fd8cb9 100644 --- a/Marlin/src/libs/softspi.h +++ b/Marlin/src/libs/softspi.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/libs/stopwatch.cpp b/Marlin/src/libs/stopwatch.cpp index fe80b17462b9..601efe55178f 100644 --- a/Marlin/src/libs/stopwatch.cpp +++ b/Marlin/src/libs/stopwatch.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -25,7 +25,7 @@ #include "../inc/MarlinConfig.h" #if ENABLED(EXTENSIBLE_UI) - #include "../lcd/extensible_ui/ui_api.h" + #include "../lcd/extui/ui_api.h" #endif Stopwatch::State Stopwatch::state; @@ -34,14 +34,10 @@ millis_t Stopwatch::startTimestamp; millis_t Stopwatch::stopTimestamp; bool Stopwatch::stop() { - #if ENABLED(DEBUG_STOPWATCH) - Stopwatch::debug(PSTR("stop")); - #endif + Stopwatch::debug(PSTR("stop")); if (isRunning() || isPaused()) { - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onPrintTimerStopped(); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onPrintTimerStopped()); state = STOPPED; stopTimestamp = millis(); return true; @@ -50,14 +46,10 @@ bool Stopwatch::stop() { } bool Stopwatch::pause() { - #if ENABLED(DEBUG_STOPWATCH) - Stopwatch::debug(PSTR("pause")); - #endif + Stopwatch::debug(PSTR("pause")); if (isRunning()) { - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onPrintTimerPaused(); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onPrintTimerPaused()); state = PAUSED; stopTimestamp = millis(); return true; @@ -66,13 +58,9 @@ bool Stopwatch::pause() { } bool Stopwatch::start() { - #if ENABLED(DEBUG_STOPWATCH) - Stopwatch::debug(PSTR("start")); - #endif + Stopwatch::debug(PSTR("start")); - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onPrintTimerStarted(); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onPrintTimerStarted()); if (!isRunning()) { if (isPaused()) accumulator = duration(); @@ -86,18 +74,14 @@ bool Stopwatch::start() { } void Stopwatch::resume(const millis_t with_time) { - #if ENABLED(DEBUG_STOPWATCH) - Stopwatch::debug(PSTR("resume")); - #endif + Stopwatch::debug(PSTR("resume")); reset(); if ((accumulator = with_time)) state = RUNNING; } void Stopwatch::reset() { - #if ENABLED(DEBUG_STOPWATCH) - Stopwatch::debug(PSTR("reset")); - #endif + Stopwatch::debug(PSTR("reset")); state = STOPPED; startTimestamp = 0; @@ -106,8 +90,7 @@ void Stopwatch::reset() { } millis_t Stopwatch::duration() { - return ((isRunning() ? millis() : stopTimestamp) - - startTimestamp) / 1000UL + accumulator; + return accumulator + MS_TO_SEC((isRunning() ? millis() : stopTimestamp) - startTimestamp); } #if ENABLED(DEBUG_STOPWATCH) diff --git a/Marlin/src/libs/stopwatch.h b/Marlin/src/libs/stopwatch.h index 4aac815c8d4a..6e8e95a9a5f1 100644 --- a/Marlin/src/libs/stopwatch.h +++ b/Marlin/src/libs/stopwatch.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -114,5 +114,9 @@ class Stopwatch { */ static void debug(const char func[]); + #else + + static inline void debug(const char[]) {} + #endif }; diff --git a/Marlin/src/libs/vector_3.cpp b/Marlin/src/libs/vector_3.cpp index d2af0f3d5630..75a30aef8222 100644 --- a/Marlin/src/libs/vector_3.cpp +++ b/Marlin/src/libs/vector_3.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -96,8 +96,8 @@ void apply_rotation_xyz(const matrix_3x3 &matrix, float &_x, float &_y, float &_ // Reset to identity. No rotate or translate. void matrix_3x3::set_to_identity() { - for (uint8_t i = 0; i < 3; i++) - for (uint8_t j = 0; j < 3; j++) + LOOP_L_N(i, 3) + LOOP_L_N(j, 3) vectors[i][j] = float(i == j); } @@ -134,8 +134,8 @@ matrix_3x3 matrix_3x3::create_look_at(const vector_3 &target) { // Get a transposed copy of the matrix matrix_3x3 matrix_3x3::transpose(const matrix_3x3 &original) { matrix_3x3 new_matrix; - for (uint8_t i = 0; i < 3; i++) - for (uint8_t j = 0; j < 3; j++) + LOOP_L_N(i, 3) + LOOP_L_N(j, 3) new_matrix.vectors[i][j] = original.vectors[j][i]; return new_matrix; } @@ -145,8 +145,8 @@ void matrix_3x3::debug(PGM_P const title) { serialprintPGM(title); SERIAL_EOL(); } - for (uint8_t i = 0; i < 3; i++) { - for (uint8_t j = 0; j < 3; j++) { + LOOP_L_N(i, 3) { + LOOP_L_N(j, 3) { if (vectors[i][j] >= 0.0) SERIAL_CHAR('+'); SERIAL_ECHO_F(vectors[i][j], 6); SERIAL_CHAR(' '); diff --git a/Marlin/src/libs/vector_3.h b/Marlin/src/libs/vector_3.h index bd596f2343ab..58428314d9d4 100644 --- a/Marlin/src/libs/vector_3.h +++ b/Marlin/src/libs/vector_3.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/module/delta.cpp b/Marlin/src/module/delta.cpp index 8821236fd113..df6cae6e0a97 100644 --- a/Marlin/src/module/delta.cpp +++ b/Marlin/src/module/delta.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -59,6 +59,7 @@ abc_float_t delta_tower_angle_trim; xy_float_t delta_tower[ABC]; abc_float_t delta_diagonal_rod_2_tower; float delta_clip_start_height = Z_MAX_POS; +abc_float_t delta_diagonal_rod_trim; float delta_safe_distance_from_top(); @@ -67,17 +68,16 @@ float delta_safe_distance_from_top(); * settings have been changed (e.g., by M665). */ void recalc_delta_settings() { - constexpr abc_float_t trt = DELTA_RADIUS_TRIM_TOWER, - drt = DELTA_DIAGONAL_ROD_TRIM_TOWER; + constexpr abc_float_t trt = DELTA_RADIUS_TRIM_TOWER; delta_tower[A_AXIS].set(cos(RADIANS(210 + delta_tower_angle_trim.a)) * (delta_radius + trt.a), // front left tower sin(RADIANS(210 + delta_tower_angle_trim.a)) * (delta_radius + trt.a)); delta_tower[B_AXIS].set(cos(RADIANS(330 + delta_tower_angle_trim.b)) * (delta_radius + trt.b), // front right tower sin(RADIANS(330 + delta_tower_angle_trim.b)) * (delta_radius + trt.b)); delta_tower[C_AXIS].set(cos(RADIANS( 90 + delta_tower_angle_trim.c)) * (delta_radius + trt.c), // back middle tower sin(RADIANS( 90 + delta_tower_angle_trim.c)) * (delta_radius + trt.c)); - delta_diagonal_rod_2_tower.set(sq(delta_diagonal_rod + drt.a), - sq(delta_diagonal_rod + drt.b), - sq(delta_diagonal_rod + drt.c)); + delta_diagonal_rod_2_tower.set(sq(delta_diagonal_rod + delta_diagonal_rod_trim.a), + sq(delta_diagonal_rod + delta_diagonal_rod_trim.b), + sq(delta_diagonal_rod + delta_diagonal_rod_trim.c)); update_software_endstops(Z_AXIS); set_all_unhomed(); } @@ -95,7 +95,7 @@ void recalc_delta_settings() { float delta_calibration_radius() { return calibration_radius_factor * ( #if HAS_BED_PROBE - FLOOR((DELTA_PRINTABLE_RADIUS) - _MAX(HYPOT(probe.offset_xy.x, probe.offset_xy.y), MIN_PROBE_EDGE)) + FLOOR((DELTA_PRINTABLE_RADIUS) - _MAX(HYPOT(probe.offset_xy.x, probe.offset_xy.y), PROBING_MARGIN)) #else DELTA_PRINTABLE_RADIUS #endif @@ -122,7 +122,7 @@ void recalc_delta_settings() { #define DELTA_DEBUG(VAR) do { \ SERIAL_ECHOLNPAIR_P(PSTR("Cartesian X"), VAR.x, SP_Y_STR, VAR.y, SP_Z_STR, VAR.z); \ - SERIAL_ECHOLNPAIR("Delta A", delta.a, " B", delta.b, " C", delta.c); \ + SERIAL_ECHOLNPAIR_P(PSTR("Delta A"), delta.a, SP_B_STR, delta.b, SP_C_STR, delta.c); \ }while(0) void inverse_kinematics(const xyz_pos_t &raw) { @@ -233,7 +233,8 @@ void forward_kinematics_DELTA(const float &z1, const float &z2, const float &z3) * This is like quick_home_xy() but for 3 towers. */ void home_delta() { - if (DEBUGGING(LEVELING)) DEBUG_POS(">>> home_delta", current_position); + DEBUG_SECTION(log_home_delta, "home_delta", DEBUGGING(LEVELING)); + // Init the current position of all carriages to 0,0,0 current_position.reset(); destination.reset(); @@ -241,27 +242,21 @@ void home_delta() { // Disable stealthChop if used. Enable diag1 pin on driver. #if ENABLED(SENSORLESS_HOMING) - sensorless_t stealth_states { - tmc_enable_stallguard(stepperX), - tmc_enable_stallguard(stepperY), - tmc_enable_stallguard(stepperZ) - }; + TERN_(X_SENSORLESS, sensorless_t stealth_states_x = start_sensorless_homing_per_axis(X_AXIS)); + TERN_(Y_SENSORLESS, sensorless_t stealth_states_y = start_sensorless_homing_per_axis(Y_AXIS)); + TERN_(Z_SENSORLESS, sensorless_t stealth_states_z = start_sensorless_homing_per_axis(Z_AXIS)); #endif // Move all carriages together linearly until an endstop is hit. - current_position.z = (delta_height + 10 - #if HAS_BED_PROBE - - probe.offset.z - #endif - ); + current_position.z = (delta_height + 10 - TERN0(HAS_BED_PROBE, probe.offset.z)); line_to_current_position(homing_feedrate(Z_AXIS)); planner.synchronize(); // Re-enable stealthChop if used. Disable diag1 pin on driver. #if ENABLED(SENSORLESS_HOMING) - tmc_disable_stallguard(stepperX, stealth_states.x); - tmc_disable_stallguard(stepperY, stealth_states.y); - tmc_disable_stallguard(stepperZ, stealth_states.z); + TERN_(X_SENSORLESS, end_sensorless_homing_per_axis(X_AXIS, stealth_states_x)); + TERN_(Y_SENSORLESS, end_sensorless_homing_per_axis(Y_AXIS, stealth_states_y)); + TERN_(Z_SENSORLESS, end_sensorless_homing_per_axis(Z_AXIS, stealth_states_z)); #endif endstops.validate_homing_move(); @@ -280,15 +275,13 @@ void home_delta() { sync_plan_position(); - #if DISABLED(DELTA_HOME_TO_SAFE_ZONE) && defined(HOMING_BACKOFF_MM) - constexpr xyz_float_t endstop_backoff = HOMING_BACKOFF_MM; + #if DISABLED(DELTA_HOME_TO_SAFE_ZONE) && defined(HOMING_BACKOFF_POST_MM) + constexpr xyz_float_t endstop_backoff = HOMING_BACKOFF_POST_MM; if (endstop_backoff.z) { current_position.z -= ABS(endstop_backoff.z) * Z_HOME_DIR; line_to_current_position(homing_feedrate(Z_AXIS)); } #endif - - if (DEBUGGING(LEVELING)) DEBUG_POS("<<< home_delta", current_position); } #endif // DELTA diff --git a/Marlin/src/module/delta.h b/Marlin/src/module/delta.h index f263a28ddd31..5e9a78bd8672 100644 --- a/Marlin/src/module/delta.h +++ b/Marlin/src/module/delta.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -37,6 +37,7 @@ extern abc_float_t delta_tower_angle_trim; extern xy_float_t delta_tower[ABC]; extern abc_float_t delta_diagonal_rod_2_tower; extern float delta_clip_start_height; +extern abc_float_t delta_diagonal_rod_trim; /** * Recalculate factors used for delta kinematics whenever diff --git a/Marlin/src/module/endstops.cpp b/Marlin/src/module/endstops.cpp index 58de4a8d05f9..712182a0ea40 100644 --- a/Marlin/src/module/endstops.cpp +++ b/Marlin/src/module/endstops.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -276,27 +276,17 @@ void Endstops::init() { #endif #endif - #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) - setup_endstop_interrupts(); - #endif + TERN_(ENDSTOP_INTERRUPTS_FEATURE, setup_endstop_interrupts()); // Enable endstops - enable_globally( - #if ENABLED(ENDSTOPS_ALWAYS_ON_DEFAULT) - true - #else - false - #endif - ); + enable_globally(ENABLED(ENDSTOPS_ALWAYS_ON_DEFAULT)); } // Endstops::init // Called at ~1KHz from Temperature ISR: Poll endstop state if required void Endstops::poll() { - #if ENABLED(PINS_DEBUGGING) - run_monitor(); // report changes in endstop status - #endif + TERN_(PINS_DEBUGGING, run_monitor()); // Report changes in endstop status #if DISABLED(ENDSTOP_INTERRUPTS_FEATURE) update(); @@ -325,7 +315,7 @@ void Endstops::not_homing() { // If the last move failed to trigger an endstop, call kill void Endstops::validate_homing_move() { if (trigger_state()) hit_on_purpose(); - else kill(GET_TEXT(MSG_LCD_HOMING_FAILED)); + else kill(GET_TEXT(MSG_KILL_HOMING_FAILED)); } #endif @@ -341,14 +331,9 @@ void Endstops::not_homing() { void Endstops::resync() { if (!abort_enabled()) return; // If endstops/probes are disabled the loop below can hang - #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) - update(); - #else - safe_delay(2); // Wait for Temperature ISR to run at least once (runs at 1KHz) - #endif - #if ENDSTOP_NOISE_THRESHOLD - while (endstop_poll_count) safe_delay(1); - #endif + // Wait for Temperature ISR to run at least once (runs at 1KHz) + TERN(ENDSTOP_INTERRUPTS_FEATURE, update(), safe_delay(2)); + while (TERN0(ENDSTOP_NOISE_THRESHOLD, endstop_poll_count)) safe_delay(1); } #if ENABLED(PINS_DEBUGGING) @@ -366,7 +351,7 @@ void Endstops::event_handler() { if (hit_state == prev_hit_state) return; prev_hit_state = hit_state; if (hit_state) { - #if HAS_SPI_LCD + #if HAS_WIRED_LCD char chrX = ' ', chrY = ' ', chrZ = ' ', chrP = ' '; #define _SET_STOP_CHAR(A,C) (chr## A = C) #else @@ -397,9 +382,7 @@ void Endstops::event_handler() { #endif SERIAL_EOL(); - #if HAS_SPI_LCD - ui.status_printf_P(0, PSTR(S_FMT " %c %c %c %c"), GET_TEXT(MSG_LCD_ENDSTOPS), chrX, chrY, chrZ, chrP); - #endif + TERN_(HAS_WIRED_LCD, ui.status_printf_P(0, PSTR(S_FMT " %c %c %c %c"), GET_TEXT(MSG_LCD_ENDSTOPS), chrX, chrY, chrZ, chrP)); #if BOTH(SD_ABORT_ON_ENDSTOP_HIT, SDSUPPORT) if (planner.abort_on_endstop_hit) { @@ -420,9 +403,7 @@ static void print_es_state(const bool is_hit, PGM_P const label=nullptr) { } void _O2 Endstops::report_states() { - #if ENABLED(BLTOUCH) - bltouch._set_SW_mode(); - #endif + TERN_(BLTOUCH, bltouch._set_SW_mode()); SERIAL_ECHOLNPGM(STR_M119_REPORT); #define ES_REPORT(S) print_es_state(READ(S##_PIN) != S##_ENDSTOP_INVERTING, PSTR(STR_##S)) #if HAS_X_MIN @@ -478,10 +459,10 @@ void _O2 Endstops::report_states() { #endif #if HAS_FILAMENT_SENSOR #if NUM_RUNOUT_SENSORS == 1 - print_es_state(READ(FIL_RUNOUT_PIN) != FIL_RUNOUT_INVERTING, PSTR(STR_FILAMENT_RUNOUT_SENSOR)); + print_es_state(READ(FIL_RUNOUT_PIN) != FIL_RUNOUT_STATE, PSTR(STR_FILAMENT_RUNOUT_SENSOR)); #else #define _CASE_RUNOUT(N) case N: pin = FIL_RUNOUT##N##_PIN; break; - for (uint8_t i = 1; i <= NUM_RUNOUT_SENSORS; i++) { + LOOP_S_LE_N(i, 1, NUM_RUNOUT_SENSORS) { pin_t pin; switch (i) { default: continue; @@ -489,18 +470,14 @@ void _O2 Endstops::report_states() { } SERIAL_ECHOPGM(STR_FILAMENT_RUNOUT_SENSOR); if (i > 1) SERIAL_CHAR(' ', '0' + i); - print_es_state(extDigitalRead(pin) != FIL_RUNOUT_INVERTING); + print_es_state(extDigitalRead(pin) != FIL_RUNOUT_STATE); } #undef _CASE_RUNOUT #endif #endif - #if ENABLED(BLTOUCH) - bltouch._reset_SW_mode(); - #endif - #if ENABLED(JOYSTICK_DEBUG) - joystick.report(); - #endif + TERN_(BLTOUCH, bltouch._reset_SW_mode()); + TERN_(JOYSTICK_DEBUG, joystick.report()); } // Endstops::report_states @@ -521,14 +498,14 @@ void Endstops::update() { #define UPDATE_ENDSTOP_BIT(AXIS, MINMAX) SET_BIT_TO(live_state, _ENDSTOP(AXIS, MINMAX), (READ(_ENDSTOP_PIN(AXIS, MINMAX)) != _ENDSTOP_INVERTING(AXIS, MINMAX))) #define COPY_LIVE_STATE(SRC_BIT, DST_BIT) SET_BIT_TO(live_state, DST_BIT, TEST(live_state, SRC_BIT)) - #if ENABLED(G38_PROBE_TARGET) && PIN_EXISTS(Z_MIN_PROBE) && !(CORE_IS_XY || CORE_IS_XZ) + #if ENABLED(G38_PROBE_TARGET) && PIN_EXISTS(Z_MIN_PROBE) && NONE(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY) // If G38 command is active check Z_MIN_PROBE for ALL movement if (G38_move) UPDATE_ENDSTOP_BIT(Z, MIN_PROBE); #endif // With Dual X, endstops are only checked in the homing direction for the active extruder #if ENABLED(DUAL_X_CARRIAGE) - #define E0_ACTIVE stepper.movement_extruder() == 0 + #define E0_ACTIVE stepper.last_moved_extruder == 0 #define X_MIN_TEST() ((X_HOME_DIR < 0 && E0_ACTIVE) || (X2_HOME_DIR < 0 && !E0_ACTIVE)) #define X_MAX_TEST() ((X_HOME_DIR > 0 && E0_ACTIVE) || (X2_HOME_DIR > 0 && !E0_ACTIVE)) #else @@ -537,12 +514,12 @@ void Endstops::update() { #endif // Use HEAD for core axes, AXIS for others - #if CORE_IS_XY || CORE_IS_XZ + #if ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY) #define X_AXIS_HEAD X_HEAD #else #define X_AXIS_HEAD X_AXIS #endif - #if CORE_IS_XY || CORE_IS_YZ + #if ANY(CORE_IS_XY, CORE_IS_YZ, MARKFORGED_XY) #define Y_AXIS_HEAD Y_HEAD #else #define Y_AXIS_HEAD Y_AXIS @@ -697,6 +674,15 @@ void Endstops::update() { } \ }while(0) + // Core Sensorless Homing needs to test an Extra Pin + #define CORE_DIAG(QQ,A,MM) (CORE_IS_##QQ && A##_SENSORLESS && !A##_SPI_SENSORLESS && HAS_##A##_##MM) + #define PROCESS_CORE_ENDSTOP(A1,M1,A2,M2) do { \ + if (TEST_ENDSTOP(_ENDSTOP(A1,M1))) { \ + _ENDSTOP_HIT(A2,M2); \ + planner.endstop_triggered(_AXIS(A2)); \ + } \ + }while(0) + // Call the endstop triggered routine for dual endstops #define PROCESS_DUAL_ENDSTOP(A, MINMAX) do { \ const byte dual_hit = TEST_ENDSTOP(_ENDSTOP(A, MINMAX)) | (TEST_ENDSTOP(_ENDSTOP(A##2, MINMAX)) << 1); \ @@ -750,7 +736,7 @@ void Endstops::update() { #define PROCESS_ENDSTOP_Z(MINMAX) PROCESS_DUAL_ENDSTOP(Z, MINMAX) #endif - #if ENABLED(G38_PROBE_TARGET) && PIN_EXISTS(Z_MIN_PROBE) && !(CORE_IS_XY || CORE_IS_XZ) + #if ENABLED(G38_PROBE_TARGET) && PIN_EXISTS(Z_MIN_PROBE) && NONE(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY) #if ENABLED(G38_PROBE_AWAY) #define _G38_OPEN_STATE (G38_move >= 4) #else @@ -765,16 +751,35 @@ void Endstops::update() { } #endif - // Now, we must signal, after validation, if an endstop limit is pressed or not + // Signal, after validation, if an endstop limit is pressed or not + if (stepper.axis_is_moving(X_AXIS)) { if (stepper.motor_direction(X_AXIS_HEAD)) { // -direction #if HAS_X_MIN || (X_SPI_SENSORLESS && X_HOME_DIR < 0) PROCESS_ENDSTOP_X(MIN); + #if CORE_DIAG(XY, Y, MIN) + PROCESS_CORE_ENDSTOP(Y,MIN,X,MIN); + #elif CORE_DIAG(XY, Y, MAX) + PROCESS_CORE_ENDSTOP(Y,MAX,X,MIN); + #elif CORE_DIAG(XZ, Z, MIN) + PROCESS_CORE_ENDSTOP(Z,MIN,X,MIN); + #elif CORE_DIAG(XZ, Z, MAX) + PROCESS_CORE_ENDSTOP(Z,MAX,X,MIN); + #endif #endif } else { // +direction #if HAS_X_MAX || (X_SPI_SENSORLESS && X_HOME_DIR > 0) PROCESS_ENDSTOP_X(MAX); + #if CORE_DIAG(XY, Y, MIN) + PROCESS_CORE_ENDSTOP(Y,MIN,X,MAX); + #elif CORE_DIAG(XY, Y, MAX) + PROCESS_CORE_ENDSTOP(Y,MAX,X,MAX); + #elif CORE_DIAG(XZ, Z, MIN) + PROCESS_CORE_ENDSTOP(Z,MIN,X,MAX); + #elif CORE_DIAG(XZ, Z, MAX) + PROCESS_CORE_ENDSTOP(Z,MAX,X,MAX); + #endif #endif } } @@ -783,11 +788,29 @@ void Endstops::update() { if (stepper.motor_direction(Y_AXIS_HEAD)) { // -direction #if HAS_Y_MIN || (Y_SPI_SENSORLESS && Y_HOME_DIR < 0) PROCESS_ENDSTOP_Y(MIN); + #if CORE_DIAG(XY, X, MIN) + PROCESS_CORE_ENDSTOP(X,MIN,Y,MIN); + #elif CORE_DIAG(XY, X, MAX) + PROCESS_CORE_ENDSTOP(X,MAX,Y,MIN); + #elif CORE_DIAG(YZ, Z, MIN) + PROCESS_CORE_ENDSTOP(Z,MIN,Y,MIN); + #elif CORE_DIAG(YZ, Z, MAX) + PROCESS_CORE_ENDSTOP(Z,MAX,Y,MIN); + #endif #endif } else { // +direction #if HAS_Y_MAX || (Y_SPI_SENSORLESS && Y_HOME_DIR > 0) PROCESS_ENDSTOP_Y(MAX); + #if CORE_DIAG(XY, X, MIN) + PROCESS_CORE_ENDSTOP(X,MIN,Y,MAX); + #elif CORE_DIAG(XY, X, MAX) + PROCESS_CORE_ENDSTOP(X,MAX,Y,MAX); + #elif CORE_DIAG(YZ, Z, MIN) + PROCESS_CORE_ENDSTOP(Z,MIN,Y,MAX); + #elif CORE_DIAG(YZ, Z, MAX) + PROCESS_CORE_ENDSTOP(Z,MAX,Y,MAX); + #endif #endif } } @@ -796,13 +819,18 @@ void Endstops::update() { if (stepper.motor_direction(Z_AXIS_HEAD)) { // Z -direction. Gantry down, bed up. #if HAS_Z_MIN || (Z_SPI_SENSORLESS && Z_HOME_DIR < 0) - if (true - #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) - && z_probe_enabled - #elif HAS_CUSTOM_PROBE_PIN - && !z_probe_enabled - #endif + if ( TERN1(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN, z_probe_enabled) + && TERN1(HAS_CUSTOM_PROBE_PIN, !z_probe_enabled) ) PROCESS_ENDSTOP_Z(MIN); + #if CORE_DIAG(XZ, X, MIN) + PROCESS_CORE_ENDSTOP(X,MIN,Z,MIN); + #elif CORE_DIAG(XZ, X, MAX) + PROCESS_CORE_ENDSTOP(X,MAX,Z,MIN); + #elif CORE_DIAG(YZ, Y, MIN) + PROCESS_CORE_ENDSTOP(Y,MIN,Z,MIN); + #elif CORE_DIAG(YZ, Y, MAX) + PROCESS_CORE_ENDSTOP(Y,MAX,Z,MIN); + #endif #endif // When closing the gap check the enabled probe @@ -817,6 +845,15 @@ void Endstops::update() { #elif !HAS_CUSTOM_PROBE_PIN || Z_MAX_PIN != Z_MIN_PROBE_PIN // No probe or probe is Z_MIN || Probe is not Z_MAX PROCESS_ENDSTOP(Z, MAX); #endif + #if CORE_DIAG(XZ, X, MIN) + PROCESS_CORE_ENDSTOP(X,MIN,Z,MAX); + #elif CORE_DIAG(XZ, X, MAX) + PROCESS_CORE_ENDSTOP(X,MAX,Z,MAX); + #elif CORE_DIAG(YZ, Y, MIN) + PROCESS_CORE_ENDSTOP(Y,MIN,Z,MAX); + #elif CORE_DIAG(YZ, Y, MAX) + PROCESS_CORE_ENDSTOP(Y,MAX,Z,MAX); + #endif #endif } } @@ -824,27 +861,41 @@ void Endstops::update() { #if ENABLED(SPI_ENDSTOPS) - #define X_STOP (X_HOME_DIR < 0 ? X_MIN : X_MAX) - #define Y_STOP (Y_HOME_DIR < 0 ? Y_MIN : Y_MAX) - #define Z_STOP (Z_HOME_DIR < 0 ? Z_MIN : Z_MAX) - bool Endstops::tmc_spi_homing_check() { bool hit = false; #if X_SPI_SENSORLESS - if (tmc_spi_homing.x && stepperX.test_stall_status()) { - SBI(live_state, X_STOP); + if (tmc_spi_homing.x && (stepperX.test_stall_status() + #if ANY(CORE_IS_XY, MARKFORGED_XY) && Y_SPI_SENSORLESS + || stepperY.test_stall_status() + #elif CORE_IS_XZ && Z_SPI_SENSORLESS + || stepperZ.test_stall_status() + #endif + )) { + SBI(live_state, X_ENDSTOP); hit = true; } #endif #if Y_SPI_SENSORLESS - if (tmc_spi_homing.y && stepperY.test_stall_status()) { - SBI(live_state, Y_STOP); + if (tmc_spi_homing.y && (stepperY.test_stall_status() + #if ANY(CORE_IS_XY, MARKFORGED_XY) && X_SPI_SENSORLESS + || stepperX.test_stall_status() + #elif CORE_IS_YZ && Z_SPI_SENSORLESS + || stepperZ.test_stall_status() + #endif + )) { + SBI(live_state, Y_ENDSTOP); hit = true; } #endif #if Z_SPI_SENSORLESS - if (tmc_spi_homing.z && stepperZ.test_stall_status()) { - SBI(live_state, Z_STOP); + if (tmc_spi_homing.z && (stepperZ.test_stall_status() + #if CORE_IS_XZ && X_SPI_SENSORLESS + || stepperX.test_stall_status() + #elif CORE_IS_YZ && Y_SPI_SENSORLESS + || stepperY.test_stall_status() + #endif + )) { + SBI(live_state, Z_ENDSTOP); hit = true; } #endif @@ -852,15 +903,9 @@ void Endstops::update() { } void Endstops::clear_endstop_state() { - #if X_SPI_SENSORLESS - CBI(live_state, X_STOP); - #endif - #if Y_SPI_SENSORLESS - CBI(live_state, Y_STOP); - #endif - #if Z_SPI_SENSORLESS - CBI(live_state, Z_STOP); - #endif + TERN_(X_SPI_SENSORLESS, CBI(live_state, X_ENDSTOP)); + TERN_(Y_SPI_SENSORLESS, CBI(live_state, Y_ENDSTOP)); + TERN_(Z_SPI_SENSORLESS, CBI(live_state, Z_ENDSTOP)); } #endif // SPI_ENDSTOPS diff --git a/Marlin/src/module/endstops.h b/Marlin/src/module/endstops.h index 71353abb34b0..888d25a8bdf3 100644 --- a/Marlin/src/module/endstops.h +++ b/Marlin/src/module/endstops.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -38,19 +38,17 @@ enum EndstopEnum : char { Z4_MIN, Z4_MAX }; +#define X_ENDSTOP (X_HOME_DIR < 0 ? X_MIN : X_MAX) +#define Y_ENDSTOP (Y_HOME_DIR < 0 ? Y_MIN : Y_MAX) +#define Z_ENDSTOP (Z_HOME_DIR < 0 ? TERN(HOMING_Z_WITH_PROBE, Z_MIN, Z_MIN_PROBE) : Z_MAX) + class Endstops { public: #if HAS_EXTRA_ENDSTOPS typedef uint16_t esbits_t; - #if ENABLED(X_DUAL_ENDSTOPS) - static float x2_endstop_adj; - #endif - #if ENABLED(Y_DUAL_ENDSTOPS) - static float y2_endstop_adj; - #endif - #if ENABLED(Z_MULTI_ENDSTOPS) - static float z2_endstop_adj; - #endif + TERN_(X_DUAL_ENDSTOPS, static float x2_endstop_adj); + TERN_(Y_DUAL_ENDSTOPS, static float y2_endstop_adj); + TERN_(Z_MULTI_ENDSTOPS, static float z2_endstop_adj); #if ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPER_DRIVERS >= 3 static float z3_endstop_adj; #endif @@ -83,11 +81,7 @@ class Endstops { * Are endstops or the probe set to abort the move? */ FORCE_INLINE static bool abort_enabled() { - return (enabled - #if HAS_BED_PROBE - || z_probe_enabled - #endif - ); + return enabled || TERN0(HAS_BED_PROBE, z_probe_enabled); } static inline bool global_enabled() { return enabled_globally; } diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp index 9f6cbf1b387b..a39ce5267427 100644 --- a/Marlin/src/module/motion.cpp +++ b/Marlin/src/module/motion.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -55,6 +55,10 @@ #include "../lcd/ultralcd.h" #endif +#if HAS_FILAMENT_SENSOR + #include "../feature/runout.h" +#endif + #if ENABLED(SENSORLESS_HOMING) #include "../feature/tmc_util.h" #endif @@ -70,15 +74,6 @@ #define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) #include "../core/debug_out.h" -#define XYZ_CONSTS(T, NAME, OPT) const PROGMEM XYZval NAME##_P = { X_##OPT, Y_##OPT, Z_##OPT } - -XYZ_CONSTS(float, base_min_pos, MIN_POS); -XYZ_CONSTS(float, base_max_pos, MAX_POS); -XYZ_CONSTS(float, base_home_pos, HOME_POS); -XYZ_CONSTS(float, max_length, MAX_LENGTH); -XYZ_CONSTS(float, home_bump_mm, HOME_BUMP_MM); -XYZ_CONSTS(signed char, home_dir, HOME_DIR); - /** * axis_homed * Flags that each linear axis was homed. @@ -104,7 +99,7 @@ xyze_pos_t current_position = { X_HOME_POS, Y_HOME_POS, Z_HOME_POS }; /** * Cartesian Destination * The destination for a move, filled in by G-code movement commands, - * and expected by functions like 'prepare_move_to_destination'. + * and expected by functions like 'prepare_line_to_destination'. * G-codes can set destination using 'get_destination_from_command' */ xyze_pos_t destination; // {0} @@ -116,7 +111,7 @@ xyze_pos_t destination; // {0} #endif // The active extruder (tool). Set with T command. -#if EXTRUDERS > 1 +#if HAS_MULTI_EXTRUDER uint8_t active_extruder = 0; // = 0 #endif @@ -206,15 +201,48 @@ xyz_pos_t cartes; /** * Output the current position to serial */ -void report_current_position() { - const xyz_pos_t lpos = current_position.asLogical(); - SERIAL_ECHOPAIR("X:", lpos.x, " Y:", lpos.y, " Z:", lpos.z, " E:", current_position.e); +inline void report_more_positions() { stepper.report_positions(); + TERN_(IS_SCARA, scara_report_positions()); +} - #if IS_SCARA - scara_report_positions(); +// Report the logical position for a given machine position +inline void report_logical_position(const xyze_pos_t &rpos) { + const xyze_pos_t lpos = rpos.asLogical(); + SERIAL_ECHOPAIR_P(X_LBL, lpos.x, SP_Y_LBL, lpos.y, SP_Z_LBL, lpos.z, SP_E_LBL, lpos.e); +} + +// Report the real current position according to the steppers. +// Forward kinematics and un-leveling are applied. +void report_real_position() { + get_cartesian_from_steppers(); + xyze_pos_t npos = cartes; + npos.e = planner.get_axis_position_mm(E_AXIS); + + #if HAS_POSITION_MODIFIERS + planner.unapply_modifiers(npos, true); #endif + + report_logical_position(npos); + report_more_positions(); +} + +// Report the logical current position according to the most recent G-code command +void report_current_position() { + report_logical_position(current_position); + report_more_positions(); +} + +/** + * Report the logical current position according to the most recent G-code command. + * The planner.position always corresponds to the last G-code too. This makes M114 + * suitable for debugging kinematics and leveling while avoiding planner sync that + * definitively interrupts the printing flow. + */ +void report_current_position_projected() { + report_logical_position(current_position); + stepper.report_a_position(planner.position); } /** @@ -241,11 +269,7 @@ void sync_plan_position_e() { planner.set_e_position_mm(current_position.e); } */ void get_cartesian_from_steppers() { #if ENABLED(DELTA) - forward_kinematics_DELTA( - planner.get_axis_position_mm(A_AXIS), - planner.get_axis_position_mm(B_AXIS), - planner.get_axis_position_mm(C_AXIS) - ); + forward_kinematics_DELTA(planner.get_axis_positions_mm()); #else #if IS_SCARA forward_kinematics_SCARA( @@ -272,20 +296,17 @@ void get_cartesian_from_steppers() { */ void set_current_from_steppers_for_axis(const AxisEnum axis) { get_cartesian_from_steppers(); + xyze_pos_t pos = cartes; + pos.e = planner.get_axis_position_mm(E_AXIS); #if HAS_POSITION_MODIFIERS - xyze_pos_t pos = { cartes.x, cartes.y, cartes.z, current_position.e }; - planner.unapply_modifiers(pos - #if HAS_LEVELING - , true - #endif - ); - const xyze_pos_t &cartes = pos; + planner.unapply_modifiers(pos, true); #endif + if (axis == ALL_AXES) - current_position = cartes; + current_position = pos; else - current_position[axis] = cartes[axis]; + current_position[axis] = pos[axis]; } /** @@ -296,6 +317,15 @@ void line_to_current_position(const feedRate_t &fr_mm_s/*=feedrate_mm_s*/) { planner.buffer_line(current_position, fr_mm_s, active_extruder); } +#if EXTRUDERS + void unscaled_e_move(const float &length, const feedRate_t &fr_mm_s) { + TERN_(HAS_FILAMENT_SENSOR, runout.reset()); + current_position.e += length / planner.e_factor[active_extruder]; + line_to_current_position(fr_mm_s); + planner.synchronize(); + } +#endif + #if IS_KINEMATIC /** @@ -318,6 +348,11 @@ void line_to_current_position(const feedRate_t &fr_mm_s/*=feedrate_mm_s*/) { #endif // IS_KINEMATIC +/** + * Do a fast or normal move to 'destination' with an optional FR. + * - Move at normal speed regardless of feedrate percentage. + * - Extrude the specified length regardless of flow percentage. + */ void _internal_move_to_destination(const feedRate_t &fr_mm_s/*=0.0f*/ #if IS_KINEMATIC , const bool is_fast/*=false*/ @@ -330,8 +365,8 @@ void _internal_move_to_destination(const feedRate_t &fr_mm_s/*=0.0f*/ feedrate_percentage = 100; #if EXTRUDERS - const float old_fac = planner.e_factor[active_extruder]; - planner.e_factor[active_extruder] = 1.0f; + const float old_fac = planner.e_factor[active_extruder]; + planner.e_factor[active_extruder] = 1.0f; #endif #if IS_KINEMATIC @@ -339,7 +374,7 @@ void _internal_move_to_destination(const feedRate_t &fr_mm_s/*=0.0f*/ prepare_fast_move_to_destination(); else #endif - prepare_move_to_destination(); + prepare_line_to_destination(); feedrate_mm_s = old_feedrate; feedrate_percentage = old_pct; @@ -352,7 +387,8 @@ void _internal_move_to_destination(const feedRate_t &fr_mm_s/*=0.0f*/ * Plan a move to (X, Y, Z) and set the current_position */ void do_blocking_move_to(const float rx, const float ry, const float rz, const feedRate_t &fr_mm_s/*=0.0*/) { - if (DEBUGGING(LEVELING)) DEBUG_XYZ(">>> do_blocking_move_to", rx, ry, rz); + DEBUG_SECTION(log_move, "do_blocking_move_to", DEBUGGING(LEVELING)); + if (DEBUGGING(LEVELING)) DEBUG_XYZ("> ", rx, ry, rz); const feedRate_t z_feedrate = fr_mm_s ?: homing_feedrate(Z_AXIS), xy_feedrate = fr_mm_s ?: feedRate_t(XY_PROBE_FEEDRATE_MM_S); @@ -436,8 +472,6 @@ void do_blocking_move_to(const float rx, const float ry, const float rz, const f #endif - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("<<< do_blocking_move_to"); - planner.synchronize(); } @@ -472,6 +506,13 @@ void do_blocking_move_to_xy_z(const xy_pos_t &raw, const float &z, const feedRat do_blocking_move_to(raw.x, raw.y, z, fr_mm_s); } +void do_z_clearance(const float &zclear, const bool z_known/*=true*/, const bool raise_on_unknown/*=true*/, const bool lower_allowed/*=false*/) { + const bool rel = raise_on_unknown && !z_known; + float zdest = zclear + (rel ? current_position.z : 0.0f); + if (!lower_allowed) NOLESS(zdest, current_position.z); + do_blocking_move_to_z(_MIN(zdest, Z_MAX_POS), MMM_TO_MMS(TERN(HAS_BED_PROBE, Z_PROBE_SPEED_FAST, HOMING_FEEDRATE_Z))); +} + // // Prepare to do endstop or probe moves with custom feedrates. // - Save / restore current feedrate and multiplier @@ -493,10 +534,9 @@ void restore_feedrate_and_scaling() { #if HAS_SOFTWARE_ENDSTOPS - bool soft_endstops_enabled = true; - // Software Endstops are based on the configured limits. - axis_limits_t soft_endstop = { + soft_endstops_t soft_endstop = { + true, false, { X_MIN_POS, Y_MIN_POS, Z_MIN_POS }, { X_MAX_POS, Y_MAX_POS, Z_MAX_POS } }; @@ -512,7 +552,8 @@ void restore_feedrate_and_scaling() { */ void update_software_endstops(const AxisEnum axis #if HAS_HOTEND_OFFSET - , const uint8_t old_tool_index/*=0*/, const uint8_t new_tool_index/*=0*/ + , const uint8_t old_tool_index/*=0*/ + , const uint8_t new_tool_index/*=0*/ #endif ) { @@ -545,11 +586,7 @@ void restore_feedrate_and_scaling() { #elif ENABLED(DELTA) soft_endstop.min[axis] = base_min_pos(axis); - soft_endstop.max[axis] = (axis == Z_AXIS ? delta_height - #if HAS_BED_PROBE - - probe.offset.z - #endif - : base_max_pos(axis)); + soft_endstop.max[axis] = (axis == Z_AXIS) ? delta_height - TERN0(HAS_BED_PROBE, probe.offset.z) : base_max_pos(axis); switch (axis) { case X_AXIS: @@ -586,9 +623,9 @@ void restore_feedrate_and_scaling() { #endif - if (DEBUGGING(LEVELING)) - SERIAL_ECHOLNPAIR("Axis ", axis_codes[axis], " min:", soft_endstop.min[axis], " max:", soft_endstop.max[axis]); -} + if (DEBUGGING(LEVELING)) + SERIAL_ECHOLNPAIR("Axis ", XYZ_CHAR(axis), " min:", soft_endstop.min[axis], " max:", soft_endstop.max[axis]); + } /** * Constrain the given coordinates to the software endstops. @@ -598,15 +635,13 @@ void restore_feedrate_and_scaling() { */ void apply_motion_limits(xyz_pos_t &target) { - if (!soft_endstops_enabled) return; + if (!soft_endstop._enabled) return; #if IS_KINEMATIC - #if ENABLED(DELTA) - if (!all_axes_homed()) return; - #endif + if (TERN0(DELTA, !all_axes_homed())) return; - #if HAS_HOTEND_OFFSET && ENABLED(DELTA) + #if BOTH(HAS_HOTEND_OFFSET, DELTA) // The effector center position will be the target minus the hotend offset. const xy_pos_t offs = hotend_offset[active_extruder]; #else @@ -614,14 +649,10 @@ void restore_feedrate_and_scaling() { constexpr xy_pos_t offs{0}; #endif - if (true - #if IS_SCARA - && TEST(axis_homed, X_AXIS) && TEST(axis_homed, Y_AXIS) - #endif - ) { + if (TERN1(IS_SCARA, TEST(axis_homed, X_AXIS) && TEST(axis_homed, Y_AXIS))) { const float dist_2 = HYPOT2(target.x - offs.x, target.y - offs.y); if (dist_2 > delta_max_radius_2) - target *= delta_max_radius / SQRT(dist_2); // 200 / 300 = 0.66 + target *= float(delta_max_radius / SQRT(dist_2)); // 200 / 300 = 0.66 } #else @@ -656,9 +687,23 @@ void restore_feedrate_and_scaling() { } } -#endif // HAS_SOFTWARE_ENDSTOPS +#else // !HAS_SOFTWARE_ENDSTOPS + + soft_endstops_t soft_endstop; + +#endif // !HAS_SOFTWARE_ENDSTOPS #if !UBL_SEGMENTED + +FORCE_INLINE void segment_idle(millis_t &next_idle_ms) { + const millis_t ms = millis(); + if (ELAPSED(ms, next_idle_ms)) { + next_idle_ms = ms + 200UL; + return idle(); + } + thermalManager.manage_heater(); // Returns immediately on most calls +} + #if IS_KINEMATIC #if IS_SCARA @@ -678,7 +723,7 @@ void restore_feedrate_and_scaling() { /** * Prepare a linear move in a DELTA or SCARA setup. * - * Called from prepare_move_to_destination as the + * Called from prepare_line_to_destination as the * default Delta/SCARA segmenter. * * This calls planner.buffer_line several times, adding @@ -751,23 +796,15 @@ void restore_feedrate_and_scaling() { xyze_pos_t raw = current_position; // Calculate and execute the segments + millis_t next_idle_ms = millis() + 200UL; while (--segments) { - - static millis_t next_idle_ms = millis() + 200UL; - thermalManager.manage_heater(); // This returns immediately if not really needed. - if (ELAPSED(millis(), next_idle_ms)) { - next_idle_ms = millis() + 200UL; - idle(); - } - + segment_idle(next_idle_ms); raw += segment_distance; - if (!planner.buffer_line(raw, scaled_fr_mm_s, active_extruder, cartesian_segment_mm #if ENABLED(SCARA_FEEDRATE_SCALING) , inv_duration #endif - )) - break; + )) break; } // Ensure last segment arrives at target location. @@ -830,20 +867,15 @@ void restore_feedrate_and_scaling() { xyze_pos_t raw = current_position; // Calculate and execute the segments + millis_t next_idle_ms = millis() + 200UL; while (--segments) { - static millis_t next_idle_ms = millis() + 200UL; - thermalManager.manage_heater(); // This returns immediately if not really needed. - if (ELAPSED(millis(), next_idle_ms)) { - next_idle_ms = millis() + 200UL; - idle(); - } + segment_idle(next_idle_ms); raw += segment_distance; if (!planner.buffer_line(raw, fr_mm_s, active_extruder, cartesian_segment_mm #if ENABLED(SCARA_FEEDRATE_SCALING) , inv_duration #endif - )) - break; + )) break; } // Since segment_distance is only approximate, @@ -865,7 +897,7 @@ void restore_feedrate_and_scaling() { * * Return true if 'current_position' was set to 'destination' */ - inline bool prepare_move_to_destination_cartesian() { + inline bool line_to_destination_cartesian() { const float scaled_fr_mm_s = MMS_SCALED(feedrate_mm_s); #if HAS_MESH if (planner.leveling_active && planner.leveling_active_at_z(destination.z)) { @@ -917,7 +949,7 @@ void restore_feedrate_and_scaling() { millis_t delayed_move_time = 0; // used in mode 1 int16_t duplicate_extruder_temp_offset = 0; // used in mode 2 - float x_home_pos(const int extruder) { + float x_home_pos(const uint8_t extruder) { if (extruder == 0) return base_home_pos(X_AXIS); else @@ -1008,7 +1040,7 @@ void restore_feedrate_and_scaling() { * * Before exit, current_position is set to destination. */ -void prepare_move_to_destination() { +void prepare_line_to_destination() { apply_motion_limits(destination); #if EITHER(PREVENT_COLD_EXTRUSION, PREVENT_LENGTHY_EXTRUDE) @@ -1049,42 +1081,35 @@ void prepare_move_to_destination() { #endif // PREVENT_COLD_EXTRUSION || PREVENT_LENGTHY_EXTRUDE - #if ENABLED(DUAL_X_CARRIAGE) - if (dual_x_carriage_unpark()) return; - #endif + if (TERN0(DUAL_X_CARRIAGE, dual_x_carriage_unpark())) return; if ( #if UBL_SEGMENTED #if IS_KINEMATIC // UBL using Kinematic / Cartesian cases as a workaround for now. ubl.line_to_destination_segmented(MMS_SCALED(feedrate_mm_s)) #else - prepare_move_to_destination_cartesian() + line_to_destination_cartesian() #endif #elif IS_KINEMATIC line_to_destination_kinematic() #else - prepare_move_to_destination_cartesian() + line_to_destination_cartesian() #endif ) return; current_position = destination; } -uint8_t axes_need_homing(uint8_t axis_bits/*=0x07*/) { - #if ENABLED(HOME_AFTER_DEACTIVATE) - #define HOMED_FLAGS axis_known_position - #else - #define HOMED_FLAGS axis_homed - #endif - // Clear test bits that are homed - if (TEST(axis_bits, X_AXIS) && TEST(HOMED_FLAGS, X_AXIS)) CBI(axis_bits, X_AXIS); - if (TEST(axis_bits, Y_AXIS) && TEST(HOMED_FLAGS, Y_AXIS)) CBI(axis_bits, Y_AXIS); - if (TEST(axis_bits, Z_AXIS) && TEST(HOMED_FLAGS, Z_AXIS)) CBI(axis_bits, Z_AXIS); +uint8_t axes_should_home(uint8_t axis_bits/*=0x07*/) { + // Clear test bits that are trusted + if (TEST(axis_bits, X_AXIS) && TEST(axis_homed, X_AXIS)) CBI(axis_bits, X_AXIS); + if (TEST(axis_bits, Y_AXIS) && TEST(axis_homed, Y_AXIS)) CBI(axis_bits, Y_AXIS); + if (TEST(axis_bits, Z_AXIS) && TEST(axis_homed, Z_AXIS)) CBI(axis_bits, Z_AXIS); return axis_bits; } -bool axis_unhomed_error(uint8_t axis_bits/*=0x07*/) { - if ((axis_bits = axes_need_homing(axis_bits))) { +bool homing_needed_error(uint8_t axis_bits/*=0x07*/) { + if ((axis_bits = axes_should_home(axis_bits))) { PGM_P home_first = GET_TEXT(MSG_HOME_FIRST); char msg[strlen_P(home_first)+1]; sprintf_P(msg, home_first, @@ -1094,9 +1119,7 @@ bool axis_unhomed_error(uint8_t axis_bits/*=0x07*/) { ); SERIAL_ECHO_START(); SERIAL_ECHOLN(msg); - #if HAS_DISPLAY - ui.set_status(msg); - #endif + TERN_(HAS_DISPLAY, ui.set_status(msg)); return true; } return false; @@ -1133,7 +1156,7 @@ feedRate_t get_homing_bump_feedrate(const AxisEnum axis) { #if AXIS_HAS_STALLGUARD(X2) stealth_states.x2 = tmc_enable_stallguard(stepperX2); #endif - #if CORE_IS_XY && Y_SENSORLESS + #if EITHER(CORE_IS_XY, MARKFORGED_XY) && Y_SENSORLESS stealth_states.y = tmc_enable_stallguard(stepperY); #elif CORE_IS_XZ && Z_SENSORLESS stealth_states.z = tmc_enable_stallguard(stepperZ); @@ -1146,7 +1169,7 @@ feedRate_t get_homing_bump_feedrate(const AxisEnum axis) { #if AXIS_HAS_STALLGUARD(Y2) stealth_states.y2 = tmc_enable_stallguard(stepperY2); #endif - #if CORE_IS_XY && X_SENSORLESS + #if EITHER(CORE_IS_XY, MARKFORGED_XY) && X_SENSORLESS stealth_states.x = tmc_enable_stallguard(stepperX); #elif CORE_IS_YZ && Z_SENSORLESS stealth_states.z = tmc_enable_stallguard(stepperZ); @@ -1176,22 +1199,14 @@ feedRate_t get_homing_bump_feedrate(const AxisEnum axis) { #if ENABLED(SPI_ENDSTOPS) switch (axis) { - #if X_SPI_SENSORLESS - case X_AXIS: endstops.tmc_spi_homing.x = true; break; - #endif - #if Y_SPI_SENSORLESS - case Y_AXIS: endstops.tmc_spi_homing.y = true; break; - #endif - #if Z_SPI_SENSORLESS - case Z_AXIS: endstops.tmc_spi_homing.z = true; break; - #endif + case X_AXIS: if (ENABLED(X_SPI_SENSORLESS)) endstops.tmc_spi_homing.x = true; break; + case Y_AXIS: if (ENABLED(Y_SPI_SENSORLESS)) endstops.tmc_spi_homing.y = true; break; + case Z_AXIS: if (ENABLED(Z_SPI_SENSORLESS)) endstops.tmc_spi_homing.z = true; break; default: break; } #endif - #if ENABLED(IMPROVE_HOMING_RELIABILITY) - sg_guard_period = millis() + default_sg_guard_duration; - #endif + TERN_(IMPROVE_HOMING_RELIABILITY, sg_guard_period = millis() + default_sg_guard_duration); return stealth_states; } @@ -1205,7 +1220,7 @@ feedRate_t get_homing_bump_feedrate(const AxisEnum axis) { #if AXIS_HAS_STALLGUARD(X2) tmc_disable_stallguard(stepperX2, enable_stealth.x2); #endif - #if CORE_IS_XY && Y_SENSORLESS + #if EITHER(CORE_IS_XY, MARKFORGED_XY) && Y_SENSORLESS tmc_disable_stallguard(stepperY, enable_stealth.y); #elif CORE_IS_XZ && Z_SENSORLESS tmc_disable_stallguard(stepperZ, enable_stealth.z); @@ -1218,7 +1233,7 @@ feedRate_t get_homing_bump_feedrate(const AxisEnum axis) { #if AXIS_HAS_STALLGUARD(Y2) tmc_disable_stallguard(stepperY2, enable_stealth.y2); #endif - #if CORE_IS_XY && X_SENSORLESS + #if EITHER(CORE_IS_XY, MARKFORGED_XY) && X_SENSORLESS tmc_disable_stallguard(stepperX, enable_stealth.x); #elif CORE_IS_YZ && Z_SENSORLESS tmc_disable_stallguard(stepperZ, enable_stealth.z); @@ -1248,15 +1263,9 @@ feedRate_t get_homing_bump_feedrate(const AxisEnum axis) { #if ENABLED(SPI_ENDSTOPS) switch (axis) { - #if X_SPI_SENSORLESS - case X_AXIS: endstops.tmc_spi_homing.x = false; break; - #endif - #if Y_SPI_SENSORLESS - case Y_AXIS: endstops.tmc_spi_homing.y = false; break; - #endif - #if Z_SPI_SENSORLESS - case Z_AXIS: endstops.tmc_spi_homing.z = false; break; - #endif + case X_AXIS: if (ENABLED(X_SPI_SENSORLESS)) endstops.tmc_spi_homing.x = false; break; + case Y_AXIS: if (ENABLED(Y_SPI_SENSORLESS)) endstops.tmc_spi_homing.y = false; break; + case Z_AXIS: if (ENABLED(Z_SPI_SENSORLESS)) endstops.tmc_spi_homing.z = false; break; default: break; } #endif @@ -1268,36 +1277,28 @@ feedRate_t get_homing_bump_feedrate(const AxisEnum axis) { * Home an individual linear axis */ void do_homing_move(const AxisEnum axis, const float distance, const feedRate_t fr_mm_s=0.0) { + DEBUG_SECTION(log_move, "do_homing_move", DEBUGGING(LEVELING)); + + const feedRate_t real_fr_mm_s = fr_mm_s ?: homing_feedrate(axis); if (DEBUGGING(LEVELING)) { - DEBUG_ECHOPAIR(">>> do_homing_move(", axis_codes[axis], ", ", distance, ", "); + DEBUG_ECHOPAIR("...(", axis_codes[axis], ", ", distance, ", "); if (fr_mm_s) DEBUG_ECHO(fr_mm_s); else - DEBUG_ECHOPAIR("[", homing_feedrate(axis), "]"); + DEBUG_ECHOPAIR("[", real_fr_mm_s, "]"); DEBUG_ECHOLNPGM(")"); } - #if HOMING_Z_WITH_PROBE && HAS_HEATED_BED && ENABLED(WAIT_FOR_BED_HEATER) + #if ALL(HOMING_Z_WITH_PROBE, HAS_HEATED_BED, WAIT_FOR_BED_HEATER) // Wait for bed to heat back up between probing points - if (axis == Z_AXIS && distance < 0 && thermalManager.isHeatingBed()) { - serialprintPGM(probe.msg_wait_for_bed_heating); - #if HAS_DISPLAY - LCD_MESSAGEPGM(MSG_BED_HEATING); - #endif - thermalManager.wait_for_bed(); - #if HAS_DISPLAY - ui.reset_status(); - #endif - } + if (axis == Z_AXIS && distance < 0) + thermalManager.wait_for_bed_heating(); #endif // Only do some things when moving towards an endstop - const int8_t axis_home_dir = - #if ENABLED(DUAL_X_CARRIAGE) - (axis == X_AXIS) ? x_home_dir(active_extruder) : - #endif - home_dir(axis); + const int8_t axis_home_dir = TERN0(DUAL_X_CARRIAGE, axis == X_AXIS) + ? x_home_dir(active_extruder) : home_dir(axis); const bool is_home_dir = (axis_home_dir > 0) == (distance > 0); #if ENABLED(SENSORLESS_HOMING) @@ -1311,12 +1312,9 @@ void do_homing_move(const AxisEnum axis, const float distance, const feedRate_t #endif // Disable stealthChop if used. Enable diag1 pin on driver. - #if ENABLED(SENSORLESS_HOMING) - stealth_states = start_sensorless_homing_per_axis(axis); - #endif + TERN_(SENSORLESS_HOMING, stealth_states = start_sensorless_homing_per_axis(axis)); } - const feedRate_t real_fr_mm_s = fr_mm_s ?: homing_feedrate(axis); #if IS_SCARA // Tell the planner the axis is at 0 current_position[axis] = 0; @@ -1324,19 +1322,21 @@ void do_homing_move(const AxisEnum axis, const float distance, const feedRate_t current_position[axis] = distance; line_to_current_position(real_fr_mm_s); #else - abce_pos_t target = { planner.get_axis_position_mm(A_AXIS), planner.get_axis_position_mm(B_AXIS), planner.get_axis_position_mm(C_AXIS), planner.get_axis_position_mm(E_AXIS) }; - target[axis] = 0; - planner.set_machine_position_mm(target); - target[axis] = distance; + // Get the ABC or XYZ positions in mm + abce_pos_t target = planner.get_axis_positions_mm(); + + target[axis] = 0; // Set the single homing axis to 0 + planner.set_machine_position_mm(target); // Update the machine position - #if IS_KINEMATIC && DISABLED(CLASSIC_JERK) - const xyze_float_t delta_mm_cart{0}; + #if HAS_DIST_MM_ARG + const xyze_float_t cart_dist_mm{0}; #endif // Set delta/cartesian axes directly + target[axis] = distance; // The move will be towards the endstop planner.buffer_segment(target - #if IS_KINEMATIC && DISABLED(CLASSIC_JERK) - , delta_mm_cart + #if HAS_DIST_MM_ARG + , cart_dist_mm #endif , real_fr_mm_s, active_extruder ); @@ -1353,12 +1353,8 @@ void do_homing_move(const AxisEnum axis, const float distance, const feedRate_t endstops.validate_homing_move(); // Re-enable stealthChop if used. Disable diag1 pin on driver. - #if ENABLED(SENSORLESS_HOMING) - end_sensorless_homing_per_axis(axis, stealth_states); - #endif + TERN_(SENSORLESS_HOMING, end_sensorless_homing_per_axis(axis, stealth_states)); } - - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("<<< do_homing_move(", axis_codes[axis], ")"); } /** @@ -1395,11 +1391,7 @@ void set_axis_is_at_home(const AxisEnum axis) { #if ENABLED(MORGAN_SCARA) scara_set_axis_is_at_home(axis); #elif ENABLED(DELTA) - current_position[axis] = (axis == Z_AXIS ? delta_height - #if HAS_BED_PROBE - - probe.offset.z - #endif - : base_home_pos(axis)); + current_position[axis] = (axis == Z_AXIS) ? delta_height - TERN0(HAS_BED_PROBE, probe.offset.z) : base_home_pos(axis); #else current_position[axis] = base_home_pos(axis); #endif @@ -1423,13 +1415,9 @@ void set_axis_is_at_home(const AxisEnum axis) { } #endif - #if ENABLED(I2C_POSITION_ENCODERS) - I2CPEM.homed(axis); - #endif + TERN_(I2C_POSITION_ENCODERS, I2CPEM.homed(axis)); - #if ENABLED(BABYSTEP_DISPLAY_TOTAL) - babystep.reset_total(axis); - #endif + TERN_(BABYSTEP_DISPLAY_TOTAL, babystep.reset_total(axis)); #if HAS_POSITION_SHIFT position_shift[axis] = 0; @@ -1446,21 +1434,98 @@ void set_axis_is_at_home(const AxisEnum axis) { } /** - * Set an axis' to be unhomed. + * Set an axis to be unhomed. */ -void set_axis_is_not_at_home(const AxisEnum axis) { - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR(">>> set_axis_is_not_at_home(", axis_codes[axis], ")"); +void set_axis_never_homed(const AxisEnum axis) { + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR(">>> set_axis_never_homed(", axis_codes[axis], ")"); CBI(axis_known_position, axis); CBI(axis_homed, axis); - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("<<< set_axis_is_not_at_home(", axis_codes[axis], ")"); + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("<<< set_axis_never_homed(", axis_codes[axis], ")"); - #if ENABLED(I2C_POSITION_ENCODERS) - I2CPEM.unhomed(axis); - #endif + TERN_(I2C_POSITION_ENCODERS, I2CPEM.unhomed(axis)); } +#ifdef TMC_HOME_PHASE + /** + * Move the axis back to its home_phase if set and driver is capable (TMC) + * + * Improves homing repeatability by homing to stepper coil's nearest absolute + * phase position. Trinamic drivers use a stepper phase table with 1024 values + * spanning 4 full steps with 256 positions each (ergo, 1024 positions). + */ + void backout_to_tmc_homing_phase(const AxisEnum axis) { + const xyz_long_t home_phase = TMC_HOME_PHASE; + + // check if home phase is disabled for this axis. + if (home_phase[axis] < 0) return; + + int16_t phasePerUStep, // TMC µsteps(phase) per Marlin µsteps + phaseCurrent, // The TMC µsteps(phase) count of the current position + effectorBackoutDir, // Direction in which the effector mm coordinates move away from endstop. + stepperBackoutDir; // Direction in which the TMC µstep count(phase) move away from endstop. + + #define PHASE_PER_MICROSTEP(N) (256 / _MAX(1, N##_MICROSTEPS)) + + switch (axis) { + #ifdef X_MICROSTEPS + case X_AXIS: + phasePerUStep = PHASE_PER_MICROSTEP(X); + phaseCurrent = stepperX.get_microstep_counter(); + effectorBackoutDir = -X_HOME_DIR; + stepperBackoutDir = INVERT_X_DIR ? effectorBackoutDir : -effectorBackoutDir; + break; + #endif + #ifdef Y_MICROSTEPS + case Y_AXIS: + phasePerUStep = PHASE_PER_MICROSTEP(Y); + phaseCurrent = stepperY.get_microstep_counter(); + effectorBackoutDir = -Y_HOME_DIR; + stepperBackoutDir = INVERT_Y_DIR ? effectorBackoutDir : -effectorBackoutDir; + break; + #endif + #ifdef Z_MICROSTEPS + case Z_AXIS: + phasePerUStep = PHASE_PER_MICROSTEP(Z); + phaseCurrent = stepperZ.get_microstep_counter(); + effectorBackoutDir = -Z_HOME_DIR; + stepperBackoutDir = INVERT_Z_DIR ? effectorBackoutDir : -effectorBackoutDir; + break; + #endif + default: return; + } + + // Phase distance to nearest home phase position when moving in the backout direction from endstop(may be negative). + int16_t phaseDelta = (home_phase[axis] - phaseCurrent) * stepperBackoutDir; + + // Check if home distance within endstop assumed repeatability noise of .05mm and warn. + if (ABS(phaseDelta) * planner.steps_to_mm[axis] / phasePerUStep < 0.05f) + SERIAL_ECHOLNPAIR("Selected home phase ", home_phase[axis], + " too close to endstop trigger phase ", phaseCurrent, + ". Pick a different phase for ", axis_codes[axis]); + + // Skip to next if target position is behind current. So it only moves away from endstop. + if (phaseDelta < 0) phaseDelta += 1024; + + // Convert TMC µsteps(phase) to whole Marlin µsteps to effector backout direction to mm + const float mmDelta = int16_t(phaseDelta / phasePerUStep) * effectorBackoutDir * planner.steps_to_mm[axis]; + + // Optional debug messages + if (DEBUGGING(LEVELING)) { + DEBUG_ECHOLNPAIR( + "Endstop ", axis_codes[axis], " hit at Phase:", phaseCurrent, + " Delta:", phaseDelta, " Distance:", mmDelta + ); + } + + if (mmDelta != 0) { + // Retrace by the amount computed in mmDelta. + do_homing_move(axis, mmDelta, get_homing_bump_feedrate(axis)); + } + } +#endif + /** * Home an individual "raw axis" to its endstop. * This applies to XYZ on Cartesian and Core robots, and @@ -1478,53 +1543,31 @@ void homeaxis(const AxisEnum axis) { // Only Z homing (with probe) is permitted if (axis != Z_AXIS) { BUZZ(100, 880); return; } #else - #define _CAN_HOME(A) \ - (axis == _AXIS(A) && ((A##_MIN_PIN > -1 && A##_HOME_DIR < 0) || (A##_MAX_PIN > -1 && A##_HOME_DIR > 0))) - #if X_SPI_SENSORLESS - #define CAN_HOME_X true - #else - #define CAN_HOME_X _CAN_HOME(X) - #endif - #if Y_SPI_SENSORLESS - #define CAN_HOME_Y true - #else - #define CAN_HOME_Y _CAN_HOME(Y) - #endif - #if Z_SPI_SENSORLESS - #define CAN_HOME_Z true - #else - #define CAN_HOME_Z _CAN_HOME(Z) - #endif - if (!CAN_HOME_X && !CAN_HOME_Y && !CAN_HOME_Z) return; + #define _CAN_HOME(A) (axis == _AXIS(A) && ( \ + ENABLED(A##_SPI_SENSORLESS) \ + || (_AXIS(A) == Z_AXIS && ENABLED(HOMING_Z_WITH_PROBE)) \ + || (A##_MIN_PIN > -1 && A##_HOME_DIR < 0) \ + || (A##_MAX_PIN > -1 && A##_HOME_DIR > 0) \ + )) + if (!_CAN_HOME(X) && !_CAN_HOME(Y) && !_CAN_HOME(Z)) return; #endif if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR(">>> homeaxis(", axis_codes[axis], ")"); - const int axis_home_dir = ( - #if ENABLED(DUAL_X_CARRIAGE) - axis == X_AXIS ? x_home_dir(active_extruder) : - #endif - home_dir(axis) - ); + const int axis_home_dir = TERN0(DUAL_X_CARRIAGE, axis == X_AXIS) + ? x_home_dir(active_extruder) : home_dir(axis); // Homing Z towards the bed? Deploy the Z probe or endstop. - #if HOMING_Z_WITH_PROBE - if (axis == Z_AXIS && probe.deploy()) return; - #endif + if (TERN0(HOMING_Z_WITH_PROBE, axis == Z_AXIS && probe.deploy())) + return; // Set flags for X, Y, Z motor locking #if HAS_EXTRA_ENDSTOPS switch (axis) { - #if ENABLED(X_DUAL_ENDSTOPS) - case X_AXIS: - #endif - #if ENABLED(Y_DUAL_ENDSTOPS) - case Y_AXIS: - #endif - #if ENABLED(Z_MULTI_ENDSTOPS) - case Z_AXIS: - #endif - stepper.set_separate_multi_axis(true); + TERN_(X_DUAL_ENDSTOPS, case X_AXIS:) + TERN_(Y_DUAL_ENDSTOPS, case Y_AXIS:) + TERN_(Z_MULTI_ENDSTOPS, case Z_AXIS:) + stepper.set_separate_multi_axis(true); default: break; } #endif @@ -1532,34 +1575,31 @@ void homeaxis(const AxisEnum axis) { // Fast move towards endstop until triggered if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Home 1 Fast:"); - #if HOMING_Z_WITH_PROBE && ENABLED(BLTOUCH) + #if BOTH(HOMING_Z_WITH_PROBE, BLTOUCH) if (axis == Z_AXIS && bltouch.deploy()) return; // The initial DEPLOY #endif - do_homing_move(axis, 1.5f * max_length( - #if ENABLED(DELTA) - Z_AXIS - #else - axis - #endif - ) * axis_home_dir - ); + #if DISABLED(DELTA) && defined(SENSORLESS_BACKOFF_MM) + const xy_float_t backoff = SENSORLESS_BACKOFF_MM; + if (((ENABLED(X_SENSORLESS) && axis == X_AXIS) || (ENABLED(Y_SENSORLESS) && axis == Y_AXIS)) && backoff[axis]) + do_homing_move(axis, -ABS(backoff[axis]) * axis_home_dir, homing_feedrate(axis)); + #endif + + do_homing_move(axis, 1.5f * max_length(TERN(DELTA, Z_AXIS, axis)) * axis_home_dir); - #if HOMING_Z_WITH_PROBE && ENABLED(BLTOUCH) && DISABLED(BLTOUCH_HS_MODE) + #if BOTH(HOMING_Z_WITH_PROBE, BLTOUCH) && DISABLED(BLTOUCH_HS_MODE) if (axis == Z_AXIS) bltouch.stow(); // Intermediate STOW (in LOW SPEED MODE) #endif // When homing Z with probe respect probe clearance + const bool use_probe_bump = TERN0(HOMING_Z_WITH_PROBE, axis == Z_AXIS && home_bump_mm(Z_AXIS)); const float bump = axis_home_dir * ( - #if HOMING_Z_WITH_PROBE - (axis == Z_AXIS && (Z_HOME_BUMP_MM)) ? _MAX(Z_CLEARANCE_BETWEEN_PROBES, Z_HOME_BUMP_MM) : - #endif - home_bump_mm(axis) + use_probe_bump ? _MAX(TERN0(HOMING_Z_WITH_PROBE, Z_CLEARANCE_BETWEEN_PROBES), home_bump_mm(Z_AXIS)) : home_bump_mm(axis) ); // If a second homing move is configured... if (bump) { - // Move away from the endstop by the axis HOME_BUMP_MM + // Move away from the endstop by the axis HOMING_BUMP_MM if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Move Away:"); do_homing_move(axis, -bump #if HOMING_Z_WITH_PROBE @@ -1567,16 +1607,31 @@ void homeaxis(const AxisEnum axis) { #endif ); + #if ENABLED(DETECT_BROKEN_ENDSTOP) + // Check for a broken endstop + EndstopEnum es; + switch (axis) { + default: + case X_AXIS: es = X_ENDSTOP; break; + case Y_AXIS: es = Y_ENDSTOP; break; + case Z_AXIS: es = Z_ENDSTOP; break; + } + if (TEST(endstops.state(), es)) { + SERIAL_ECHO_MSG("Bad ", axis_codes[axis], " Endstop?"); + kill(GET_TEXT(MSG_KILL_HOMING_FAILED)); + } + #endif + // Slow move towards endstop until triggered if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Home 2 Slow:"); - #if HOMING_Z_WITH_PROBE && ENABLED(BLTOUCH) && DISABLED(BLTOUCH_HS_MODE) + #if BOTH(HOMING_Z_WITH_PROBE, BLTOUCH) && DISABLED(BLTOUCH_HS_MODE) if (axis == Z_AXIS && bltouch.deploy()) return; // Intermediate DEPLOY (in LOW SPEED MODE) #endif do_homing_move(axis, 2 * bump, get_homing_bump_feedrate(axis)); - #if HOMING_Z_WITH_PROBE && ENABLED(BLTOUCH) + #if BOTH(HOMING_Z_WITH_PROBE, BLTOUCH) if (axis == Z_AXIS) bltouch.stow(); // The final STOW #endif } @@ -1613,9 +1668,9 @@ void homeaxis(const AxisEnum axis) { const float adj = ABS(endstops.z2_endstop_adj); if (adj) { - if (pos_dir ? (endstops.z2_endstop_adj > 0) : (endstops.z2_endstop_adj < 0)) stepper.set_z_lock(true); else stepper.set_z2_lock(true); + if (pos_dir ? (endstops.z2_endstop_adj > 0) : (endstops.z2_endstop_adj < 0)) stepper.set_z1_lock(true); else stepper.set_z2_lock(true); do_homing_move(axis, pos_dir ? -adj : adj); - stepper.set_z_lock(false); + stepper.set_z1_lock(false); stepper.set_z2_lock(false); } @@ -1626,7 +1681,7 @@ void homeaxis(const AxisEnum axis) { typedef void (*adjustFunc_t)(const bool); adjustFunc_t lock[] = { - stepper.set_z_lock, stepper.set_z2_lock, stepper.set_z3_lock + stepper.set_z1_lock, stepper.set_z2_lock, stepper.set_z3_lock #if NUM_Z_STEPPER_DRIVERS >= 4 , stepper.set_z4_lock #endif @@ -1694,7 +1749,7 @@ void homeaxis(const AxisEnum axis) { do_homing_move(axis, adj[0] - adj[1]); } - stepper.set_z_lock(false); + stepper.set_z1_lock(false); stepper.set_z2_lock(false); stepper.set_z3_lock(false); #if NUM_Z_STEPPER_DRIVERS >= 4 @@ -1708,19 +1763,18 @@ void homeaxis(const AxisEnum axis) { // Reset flags for X, Y, Z motor locking switch (axis) { default: break; - #if ENABLED(X_DUAL_ENDSTOPS) - case X_AXIS: - #endif - #if ENABLED(Y_DUAL_ENDSTOPS) - case Y_AXIS: - #endif - #if ENABLED(Z_MULTI_ENDSTOPS) - case Z_AXIS: - #endif - stepper.set_separate_multi_axis(false); + TERN_(X_DUAL_ENDSTOPS, case X_AXIS:) + TERN_(Y_DUAL_ENDSTOPS, case Y_AXIS:) + TERN_(Z_MULTI_ENDSTOPS, case Z_AXIS:) + stepper.set_separate_multi_axis(false); } #endif + #ifdef TMC_HOME_PHASE + // move back to homing phase if configured and capable + backout_to_tmc_homing_phase(axis); + #endif + #if IS_SCARA set_axis_is_at_home(axis); @@ -1732,13 +1786,16 @@ void homeaxis(const AxisEnum axis) { // so here it re-homes each tower in turn. // Delta homing treats the axes as normal linear axes. - // retrace by the amount specified in delta_endstop_adj + additional dist in order to have minimum steps - if (delta_endstop_adj[axis] * Z_HOME_DIR <= 0) { - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("delta_endstop_adj:"); - do_homing_move(axis, delta_endstop_adj[axis] - (MIN_STEPS_PER_SEGMENT + 1) * planner.steps_to_mm[axis] * Z_HOME_DIR); + const float adjDistance = delta_endstop_adj[axis], + minDistance = (MIN_STEPS_PER_SEGMENT) * planner.steps_to_mm[axis]; + + // Retrace by the amount specified in delta_endstop_adj if more than min steps. + if (adjDistance * (Z_HOME_DIR) < 0 && ABS(adjDistance) > minDistance) { // away from endstop, more than min distance + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("adjDistance:", adjDistance); + do_homing_move(axis, adjDistance, get_homing_bump_feedrate(axis)); } - #else // CARTESIAN / CORE + #else // CARTESIAN / CORE / MARKFORGED_XY set_axis_is_at_home(axis); sync_plan_position(); @@ -1754,8 +1811,8 @@ void homeaxis(const AxisEnum axis) { if (axis == Z_AXIS && probe.stow()) return; #endif - #if DISABLED(DELTA) && defined(HOMING_BACKOFF_MM) - const xyz_float_t endstop_backoff = HOMING_BACKOFF_MM; + #if DISABLED(DELTA) && defined(HOMING_BACKOFF_POST_MM) + const xyz_float_t endstop_backoff = HOMING_BACKOFF_POST_MM; if (endstop_backoff[axis]) { current_position[axis] -= ABS(endstop_backoff[axis]) * axis_home_dir; line_to_current_position( @@ -1764,6 +1821,15 @@ void homeaxis(const AxisEnum axis) { #endif homing_feedrate(axis) ); + + #if ENABLED(SENSORLESS_HOMING) + planner.synchronize(); + if (false + #if EITHER(IS_CORE, MARKFORGED_XY) + || axis != NORMAL_AXIS + #endif + ) safe_delay(200); // Short delay to allow belts to spring back + #endif } #endif @@ -1779,7 +1845,7 @@ void homeaxis(const AxisEnum axis) { #if HAS_WORKSPACE_OFFSET void update_workspace_offset(const AxisEnum axis) { workspace_offset[axis] = home_offset[axis] + position_shift[axis]; - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Axis ", axis_codes[axis], " home_offset = ", home_offset[axis], " position_shift = ", position_shift[axis]); + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Axis ", XYZ_CHAR(axis), " home_offset = ", home_offset[axis], " position_shift = ", position_shift[axis]); } #endif diff --git a/Marlin/src/module/motion.h b/Marlin/src/module/motion.h index c50da25a3e27..85b70c057aa9 100644 --- a/Marlin/src/module/motion.h +++ b/Marlin/src/module/motion.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -30,10 +30,6 @@ #include "../inc/MarlinConfig.h" -#if HAS_BED_PROBE - #include "probe.h" -#endif - #if IS_SCARA #include "scara.h" #endif @@ -44,21 +40,15 @@ constexpr uint8_t xyz_bits = _BV(X_AXIS) | _BV(Y_AXIS) | _BV(Z_AXIS); FORCE_INLINE bool no_axes_homed() { return !axis_homed; } FORCE_INLINE bool all_axes_homed() { return (axis_homed & xyz_bits) == xyz_bits; } FORCE_INLINE bool all_axes_known() { return (axis_known_position & xyz_bits) == xyz_bits; } -FORCE_INLINE void set_all_unhomed() { axis_homed = 0; } -FORCE_INLINE void set_all_unknown() { axis_known_position = 0; } +FORCE_INLINE void set_all_homed() { axis_homed = axis_known_position = xyz_bits; } +FORCE_INLINE void set_all_unhomed() { axis_homed = axis_known_position = 0; } FORCE_INLINE bool homing_needed() { - return !( - #if ENABLED(HOME_AFTER_DEACTIVATE) - all_axes_known() - #else - all_axes_homed() - #endif - ); + return !TERN(HOME_AFTER_DEACTIVATE, all_axes_known, all_axes_homed)(); } // Error margin to work around float imprecision -constexpr float slop = 0.0001; +constexpr float fslop = 0.0001; extern bool relative_mode; @@ -108,7 +98,7 @@ extern feedRate_t feedrate_mm_s; extern int16_t feedrate_percentage; // The active extruder (tool). Set with T command. -#if EXTRUDERS > 1 +#if HAS_MULTI_EXTRUDER extern uint8_t active_extruder; #else constexpr uint8_t active_extruder = 0; @@ -118,24 +108,35 @@ extern int16_t feedrate_percentage; extern float e_move_accumulator; #endif -FORCE_INLINE float pgm_read_any(const float *p) { return pgm_read_float(p); } -FORCE_INLINE signed char pgm_read_any(const signed char *p) { return pgm_read_byte(p); } +#ifdef __IMXRT1062__ + #define DEFS_PROGMEM +#else + #define DEFS_PROGMEM PROGMEM +#endif + +inline float pgm_read_any(const float *p) { return TERN(__IMXRT1062__, *p, pgm_read_float(p)); } +inline int8_t pgm_read_any(const int8_t *p) { return TERN(__IMXRT1062__, *p, pgm_read_byte(p)); } #define XYZ_DEFS(T, NAME, OPT) \ - extern const XYZval NAME##_P; \ - FORCE_INLINE T NAME(AxisEnum axis) { return pgm_read_any(&NAME##_P[axis]); } - + inline T NAME(const AxisEnum axis) { \ + static const XYZval NAME##_P DEFS_PROGMEM = { X_##OPT, Y_##OPT, Z_##OPT }; \ + return pgm_read_any(&NAME##_P[axis]); \ + } XYZ_DEFS(float, base_min_pos, MIN_POS); XYZ_DEFS(float, base_max_pos, MAX_POS); XYZ_DEFS(float, base_home_pos, HOME_POS); XYZ_DEFS(float, max_length, MAX_LENGTH); -XYZ_DEFS(float, home_bump_mm, HOME_BUMP_MM); -XYZ_DEFS(signed char, home_dir, HOME_DIR); +XYZ_DEFS(int8_t, home_dir, HOME_DIR); + +inline float home_bump_mm(const AxisEnum axis) { + static const xyz_pos_t home_bump_mm_P DEFS_PROGMEM = HOMING_BUMP_MM; + return pgm_read_any(&home_bump_mm_P[axis]); +} #if HAS_WORKSPACE_OFFSET void update_workspace_offset(const AxisEnum axis); #else - #define update_workspace_offset(x) NOOP + inline void update_workspace_offset(const AxisEnum) {} #endif #if HAS_HOTEND_OFFSET @@ -147,26 +148,63 @@ XYZ_DEFS(signed char, home_dir, HOME_DIR); constexpr xyz_pos_t hotend_offset[1] = { { 0 } }; #endif -typedef struct { xyz_pos_t min, max; } axis_limits_t; #if HAS_SOFTWARE_ENDSTOPS - extern bool soft_endstops_enabled; - extern axis_limits_t soft_endstop; + + typedef struct { + bool _enabled, _loose; + bool enabled() { return _enabled && !_loose; } + + xyz_pos_t min, max; + void get_manual_axis_limits(const AxisEnum axis, float &amin, float &amax) { + amin = -100000; amax = 100000; // "No limits" + #if HAS_SOFTWARE_ENDSTOPS + if (enabled()) switch (axis) { + case X_AXIS: + TERN_(MIN_SOFTWARE_ENDSTOP_X, amin = min.x); + TERN_(MAX_SOFTWARE_ENDSTOP_X, amax = max.x); + break; + case Y_AXIS: + TERN_(MIN_SOFTWARE_ENDSTOP_Y, amin = min.y); + TERN_(MAX_SOFTWARE_ENDSTOP_Y, amax = max.y); + break; + case Z_AXIS: + TERN_(MIN_SOFTWARE_ENDSTOP_Z, amin = min.z); + TERN_(MAX_SOFTWARE_ENDSTOP_Z, amax = max.z); + default: break; + } + #endif + } + } soft_endstops_t; + + extern soft_endstops_t soft_endstop; void apply_motion_limits(xyz_pos_t &target); void update_software_endstops(const AxisEnum axis #if HAS_HOTEND_OFFSET , const uint8_t old_tool_index=0, const uint8_t new_tool_index=0 #endif ); -#else - constexpr bool soft_endstops_enabled = false; - //constexpr axis_limits_t soft_endstop = { - // { X_MIN_POS, Y_MIN_POS, Z_MIN_POS }, - // { X_MAX_POS, Y_MAX_POS, Z_MAX_POS } }; - #define apply_motion_limits(V) NOOP + #define SET_SOFT_ENDSTOP_LOOSE(loose) (soft_endstop._loose = loose) + +#else // !HAS_SOFTWARE_ENDSTOPS + + typedef struct { + bool enabled() { return false; } + void get_manual_axis_limits(const AxisEnum axis, float &amin, float &amax) { + // No limits + amin = current_position[axis] - 1000; + amax = current_position[axis] + 1000; + } + } soft_endstops_t; + extern soft_endstops_t soft_endstop; + #define apply_motion_limits(V) NOOP #define update_software_endstops(...) NOOP -#endif + #define SET_SOFT_ENDSTOP_LOOSE(V) NOOP + +#endif // !HAS_SOFTWARE_ENDSTOPS +void report_real_position(); void report_current_position(); +void report_current_position_projected(); void get_cartesian_from_steppers(); void set_current_from_steppers_for_axis(const AxisEnum axis); @@ -186,7 +224,11 @@ void sync_plan_position_e(); */ void line_to_current_position(const feedRate_t &fr_mm_s=feedrate_mm_s); -void prepare_move_to_destination(); +#if EXTRUDERS + void unscaled_e_move(const float &length, const feedRate_t &fr_mm_s); +#endif + +void prepare_line_to_destination(); void _internal_move_to_destination(const feedRate_t &fr_mm_s=0.0f #if IS_KINEMATIC @@ -231,25 +273,23 @@ void remember_feedrate_and_scaling(); void remember_feedrate_scaling_off(); void restore_feedrate_and_scaling(); +void do_z_clearance(const float &zclear, const bool z_known=true, const bool raise_on_unknown=true, const bool lower_allowed=false); + // // Homing // - -uint8_t axes_need_homing(uint8_t axis_bits=0x07); -bool axis_unhomed_error(uint8_t axis_bits=0x07); +void homeaxis(const AxisEnum axis); +void set_axis_is_at_home(const AxisEnum axis); +void set_axis_never_homed(const AxisEnum axis); +uint8_t axes_should_home(uint8_t axis_bits=0x07); +bool homing_needed_error(uint8_t axis_bits=0x07); #if ENABLED(NO_MOTION_BEFORE_HOMING) - #define MOTION_CONDITIONS (IsRunning() && !axis_unhomed_error()) + #define MOTION_CONDITIONS (IsRunning() && !homing_needed_error()) #else #define MOTION_CONDITIONS IsRunning() #endif -void set_axis_is_at_home(const AxisEnum axis); - -void set_axis_is_not_at_home(const AxisEnum axis); - -void homeaxis(const AxisEnum axis); - /** * Workspace offsets */ @@ -306,7 +346,7 @@ void homeaxis(const AxisEnum axis); // Return true if the given point is within the printable area inline bool position_is_reachable(const float &rx, const float &ry, const float inset=0) { #if ENABLED(DELTA) - return HYPOT2(rx, ry) <= sq(DELTA_PRINTABLE_RADIUS - inset + slop); + return HYPOT2(rx, ry) <= sq(DELTA_PRINTABLE_RADIUS - inset + fslop); #elif IS_SCARA const float R2 = HYPOT2(rx - SCARA_OFFSET_X, ry - SCARA_OFFSET_Y); return ( @@ -322,67 +362,24 @@ void homeaxis(const AxisEnum axis); return position_is_reachable(pos.x, pos.y, inset); } - #if HAS_BED_PROBE - - #if HAS_PROBE_XY_OFFSET - - // Return true if the both nozzle and the probe can reach the given point. - // Note: This won't work on SCARA since the probe offset rotates with the arm. - inline bool position_is_reachable_by_probe(const float &rx, const float &ry) { - return position_is_reachable(rx - probe.offset_xy.x, ry - probe.offset_xy.y) - && position_is_reachable(rx, ry, ABS(MIN_PROBE_EDGE)); - } - - #else - - FORCE_INLINE bool position_is_reachable_by_probe(const float &rx, const float &ry) { - return position_is_reachable(rx, ry, MIN_PROBE_EDGE); - } - - #endif - - #endif // HAS_BED_PROBE - #else // CARTESIAN // Return true if the given position is within the machine bounds. inline bool position_is_reachable(const float &rx, const float &ry) { - if (!WITHIN(ry, Y_MIN_POS - slop, Y_MAX_POS + slop)) return false; + if (!WITHIN(ry, Y_MIN_POS - fslop, Y_MAX_POS + fslop)) return false; #if ENABLED(DUAL_X_CARRIAGE) if (active_extruder) - return WITHIN(rx, X2_MIN_POS - slop, X2_MAX_POS + slop); + return WITHIN(rx, X2_MIN_POS - fslop, X2_MAX_POS + fslop); else - return WITHIN(rx, X1_MIN_POS - slop, X1_MAX_POS + slop); + return WITHIN(rx, X1_MIN_POS - fslop, X1_MAX_POS + fslop); #else - return WITHIN(rx, X_MIN_POS - slop, X_MAX_POS + slop); + return WITHIN(rx, X_MIN_POS - fslop, X_MAX_POS + fslop); #endif } inline bool position_is_reachable(const xy_pos_t &pos) { return position_is_reachable(pos.x, pos.y); } - #if HAS_BED_PROBE - - /** - * Return whether the given position is within the bed, and whether the nozzle - * can reach the position required to put the probe at the given position. - * - * Example: For a probe offset of -10,+10, then for the probe to reach 0,0 the - * nozzle must be be able to reach +10,-10. - */ - inline bool position_is_reachable_by_probe(const float &rx, const float &ry) { - return position_is_reachable(rx - probe.offset_xy.x, ry - probe.offset_xy.y) - && WITHIN(rx, probe.min_x() - slop, probe.max_x() + slop) - && WITHIN(ry, probe.min_y() - slop, probe.max_y() + slop); - } - - #endif // HAS_BED_PROBE - #endif // CARTESIAN -#if !HAS_BED_PROBE - FORCE_INLINE bool position_is_reachable_by_probe(const float &rx, const float &ry) { return position_is_reachable(rx, ry); } -#endif -FORCE_INLINE bool position_is_reachable_by_probe(const xy_pos_t &pos) { return position_is_reachable_by_probe(pos.x, pos.y); } - /** * Duplication mode */ @@ -416,18 +413,26 @@ FORCE_INLINE bool position_is_reachable_by_probe(const xy_pos_t &pos) { return p FORCE_INLINE bool dxc_is_duplicating() { return dual_x_carriage_mode >= DXC_DUPLICATION_MODE; } - float x_home_pos(const int extruder); + float x_home_pos(const uint8_t extruder); FORCE_INLINE int x_home_dir(const uint8_t extruder) { return extruder ? X2_HOME_DIR : X_HOME_DIR; } -#elif ENABLED(MULTI_NOZZLE_DUPLICATION) +#else - enum DualXMode : char { - DXC_DUPLICATION_MODE = 2 - }; + #if ENABLED(MULTI_NOZZLE_DUPLICATION) + enum DualXMode : char { DXC_DUPLICATION_MODE = 2 }; + #endif + + FORCE_INLINE int x_home_dir(const uint8_t) { return home_dir(X_AXIS); } #endif #if HAS_M206_COMMAND void set_home_offset(const AxisEnum axis, const float v); #endif + +#if USE_SENSORLESS + struct sensorless_t; + sensorless_t start_sensorless_homing_per_axis(const AxisEnum axis); + void end_sensorless_homing_per_axis(const AxisEnum axis, sensorless_t enable_stealth); +#endif diff --git a/Marlin/src/module/planner.cpp b/Marlin/src/module/planner.cpp index 2067ecc23f56..4ad7c4ccf044 100644 --- a/Marlin/src/module/planner.cpp +++ b/Marlin/src/module/planner.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -67,7 +67,6 @@ #include "motion.h" #include "temperature.h" #include "../lcd/ultralcd.h" -#include "../core/language.h" #include "../gcode/parser.h" #include "../MarlinCore.h" @@ -92,6 +91,10 @@ #include "../feature/power.h" #endif +#if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER) + #include "../feature/closedloop.h" +#endif + #if ENABLED(BACKLASH_COMPENSATION) #include "../feature/backlash.h" #endif @@ -101,7 +104,7 @@ #endif #if ENABLED(POWER_LOSS_RECOVERY) - #include "../feature/power_loss_recovery.h" + #include "../feature/powerloss.h" #endif #if HAS_CUTTER @@ -114,7 +117,7 @@ Planner planner; - // public: +// public: /** * A ring buffer of moves described in steps @@ -129,26 +132,23 @@ uint8_t Planner::delay_before_delivering; // This counter delays delivery planner_settings_t Planner::settings; // Initialized by settings.load() +#if ENABLED(LASER_POWER_INLINE) + laser_state_t Planner::laser_inline; // Current state for blocks +#endif + uint32_t Planner::max_acceleration_steps_per_s2[XYZE_N]; // (steps/s^2) Derived from mm_per_s2 -float Planner::steps_to_mm[XYZE_N]; // (mm) Millimeters per step +float Planner::steps_to_mm[XYZE_N]; // (mm) Millimeters per step -#if DISABLED(CLASSIC_JERK) - float Planner::junction_deviation_mm; // (mm) M205 J - #if ENABLED(LIN_ADVANCE) - #if ENABLED(DISTINCT_E_FACTORS) - float Planner::max_e_jerk[EXTRUDERS]; // Calculated from junction_deviation_mm - #else - float Planner::max_e_jerk; - #endif +#if HAS_JUNCTION_DEVIATION + float Planner::junction_deviation_mm; // (mm) M205 J + #if HAS_LINEAR_E_JERK + float Planner::max_e_jerk[DISTINCT_E]; // Calculated from junction_deviation_mm #endif #endif + #if HAS_CLASSIC_JERK - #if HAS_LINEAR_E_JERK - xyz_pos_t Planner::max_jerk; // (mm/s^2) M205 XYZ - The largest speed change requiring no acceleration. - #else - xyze_pos_t Planner::max_jerk; // (mm/s^2) M205 XYZE - The largest speed change requiring no acceleration. - #endif + TERN(HAS_LINEAR_E_JERK, xyz_pos_t, xyze_pos_t) Planner::max_jerk; #endif #if ENABLED(SD_ABORT_ON_ENDSTOP_HIT) @@ -159,6 +159,11 @@ float Planner::steps_to_mm[XYZE_N]; // (mm) Millimeters per step uint8_t Planner::last_extruder = 0; // Respond to extruder change #endif +#if ENABLED(DIRECT_STEPPING) + uint32_t Planner::last_page_step_rate = 0; + xyze_bool_t Planner::last_page_dir{0}; +#endif + #if EXTRUDERS int16_t Planner::flow_percentage[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(100); // Extrusion factor for each extruder float Planner::e_factor[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(1.0f); // The flow percentage and volumetric multiplier combine to scale E movement @@ -170,6 +175,11 @@ float Planner::steps_to_mm[XYZE_N]; // (mm) Millimeters per step Planner::volumetric_multiplier[EXTRUDERS]; // Reciprocal of cross-sectional area of filament (in mm^2). Pre-calculated to reduce computation in the planner #endif +#if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) + float Planner::volumetric_extruder_limit[EXTRUDERS], // max mm^3/sec the extruder is able to handle + Planner::volumetric_extruder_feedrate_limit[EXTRUDERS]; // pre calculated extruder feedrate limit based on volumetric_extruder_limit; pre-calculated to reduce computation in the planner +#endif + #if HAS_LEVELING bool Planner::leveling_active = false; // Flag that auto bed leveling is enabled #if ABL_PLANAR @@ -207,10 +217,9 @@ float Planner::previous_nominal_speed_sqr; #endif #ifdef XY_FREQUENCY_LIMIT - // Old direction bits. Used for speed calculations - unsigned char Planner::old_direction_bits = 0; - // Segment times (in µs). Used for speed calculations - xy_ulong_t Planner::axis_segment_time_us[3] = { { MAX_FREQ_TIME_US + 1, MAX_FREQ_TIME_US + 1 } }; + int8_t Planner::xy_freq_limit_hz = XY_FREQUENCY_LIMIT; + float Planner::xy_freq_min_speed_factor = (XY_FREQUENCY_MIN_PERCENT) * 0.01f; + int32_t Planner::xy_freq_min_interval_us = LROUND(1000000.0 / (XY_FREQUENCY_LIMIT)); #endif #if ENABLED(LIN_ADVANCE) @@ -225,7 +234,7 @@ float Planner::previous_nominal_speed_sqr; xyze_pos_t Planner::position_cart; #endif -#if HAS_SPI_LCD +#if HAS_WIRED_LCD volatile uint32_t Planner::block_buffer_runtime_us = 0; #endif @@ -237,19 +246,17 @@ Planner::Planner() { init(); } void Planner::init() { position.reset(); - #if HAS_POSITION_FLOAT - position_float.reset(); - #endif - #if IS_KINEMATIC - position_cart.reset(); - #endif + TERN_(HAS_POSITION_FLOAT, position_float.reset()); + TERN_(IS_KINEMATIC, position_cart.reset()); previous_speed.reset(); previous_nominal_speed_sqr = 0; - #if ABL_PLANAR - bed_level_matrix.set_to_identity(); - #endif + TERN_(ABL_PLANAR, bed_level_matrix.set_to_identity()); clear_block_buffer(); delay_before_delivering = 0; + #if ENABLED(DIRECT_STEPPING) + last_page_step_rate = 0; + last_page_dir.reset(); + #endif } #if ENABLED(S_CURVE_ACCELERATION) @@ -332,7 +339,6 @@ void Planner::init() { * const uint32_t r = _BV(24) - x * d; // Estimate remainder * if (r >= d) x++; // Check whether to adjust result * return uint32_t(x); // x holds the proper estimation - * */ static uint32_t get_period_inverse(uint32_t d) { @@ -739,9 +745,8 @@ block_t* Planner::get_current_block() { // No trapezoid calculated? Don't execute yet. if (TEST(block->flag, BLOCK_BIT_RECALCULATE)) return nullptr; - #if HAS_SPI_LCD - block_buffer_runtime_us -= block->segment_time_us; // We can't be sure how long an active block will take, so don't count it. - #endif + // We can't be sure how long an active block will take, so don't count it. + TERN_(HAS_WIRED_LCD, block_buffer_runtime_us -= block->segment_time_us); // As this block is busy, advance the nonbusy block pointer block_buffer_nonbusy = next_block_index(block_buffer_tail); @@ -755,9 +760,7 @@ block_t* Planner::get_current_block() { } // The queue became empty - #if HAS_SPI_LCD - clear_block_buffer_runtime(); // paranoia. Buffer is empty now - so reset accumulated time to zero. - #endif + TERN_(HAS_WIRED_LCD, clear_block_buffer_runtime()); // paranoia. Buffer is empty now - so reset accumulated time to zero. return nullptr; } @@ -815,11 +818,10 @@ void Planner::calculate_trapezoid_for_block(block_t* const block, const float &e #if ENABLED(S_CURVE_ACCELERATION) // Jerk controlled speed requires to express speed versus time, NOT steps uint32_t acceleration_time = ((float)(cruise_rate - initial_rate) / accel) * (STEPPER_TIMER_RATE), - deceleration_time = ((float)(cruise_rate - final_rate) / accel) * (STEPPER_TIMER_RATE); - + deceleration_time = ((float)(cruise_rate - final_rate) / accel) * (STEPPER_TIMER_RATE), // And to offload calculations from the ISR, we also calculate the inverse of those times here - uint32_t acceleration_time_inverse = get_period_inverse(acceleration_time); - uint32_t deceleration_time_inverse = get_period_inverse(deceleration_time); + acceleration_time_inverse = get_period_inverse(acceleration_time), + deceleration_time_inverse = get_period_inverse(deceleration_time); #endif // Store new block parameters @@ -834,6 +836,47 @@ void Planner::calculate_trapezoid_for_block(block_t* const block, const float &e block->cruise_rate = cruise_rate; #endif block->final_rate = final_rate; + + /** + * Laser trapezoid calculations + * + * Approximate the trapezoid with the laser, incrementing the power every `entry_per` while accelerating + * and decrementing it every `exit_power_per` while decelerating, thus ensuring power is related to feedrate. + * + * LASER_POWER_INLINE_TRAPEZOID_CONT doesn't need this as it continuously approximates + * + * Note this may behave unreliably when running with S_CURVE_ACCELERATION + */ + #if ENABLED(LASER_POWER_INLINE_TRAPEZOID) + if (block->laser.power > 0) { // No need to care if power == 0 + const uint8_t entry_power = block->laser.power * entry_factor; // Power on block entry + #if DISABLED(LASER_POWER_INLINE_TRAPEZOID_CONT) + // Speedup power + const uint8_t entry_power_diff = block->laser.power - entry_power; + if (entry_power_diff) { + block->laser.entry_per = accelerate_steps / entry_power_diff; + block->laser.power_entry = entry_power; + } + else { + block->laser.entry_per = 0; + block->laser.power_entry = block->laser.power; + } + // Slowdown power + const uint8_t exit_power = block->laser.power * exit_factor, // Power on block entry + exit_power_diff = block->laser.power - exit_power; + if (exit_power_diff) { + block->laser.exit_per = (block->step_event_count - block->decelerate_after) / exit_power_diff; + block->laser.power_exit = exit_power; + } + else { + block->laser.exit_per = 0; + block->laser.power_exit = block->laser.power; + } + #else + block->laser.power_entry = entry_power; + #endif + } + #endif } /* PLANNER SPEED DEFINITION @@ -884,7 +927,7 @@ void Planner::calculate_trapezoid_for_block(block_t* const block, const float &e streaming operating conditions. Use for planning optimizations by avoiding recomputing parts of the planner buffer that don't change with the addition of a new block, as describe above. In addition, this block can never be less than block_buffer_tail and will always be pushed forward and maintain - this requirement when encountered by the Planner::discard_current_block() routine during a cycle. + this requirement when encountered by the Planner::release_current_block() routine during a cycle. NOTE: Since the planner only computes on what's in the planner buffer, some motions with lots of short line segments, like G2/3 arcs or complex curves, may seem to move slow. This is because there simply isn't @@ -972,8 +1015,8 @@ void Planner::reverse_pass() { // Perform the reverse pass block_t *current = &block_buffer[block_index]; - // Only consider non sync blocks - if (!TEST(current->flag, BLOCK_BIT_SYNC_POSITION)) { + // Only consider non sync and page blocks + if (!TEST(current->flag, BLOCK_BIT_SYNC_POSITION) && !IS_PAGE(current)) { reverse_pass_kernel(current, next); next = current; } @@ -1067,8 +1110,8 @@ void Planner::forward_pass() { // Perform the forward pass block = &block_buffer[block_index]; - // Skip SYNC blocks - if (!TEST(block->flag, BLOCK_BIT_SYNC_POSITION)) { + // Skip SYNC and page blocks + if (!TEST(block->flag, BLOCK_BIT_SYNC_POSITION) && !IS_PAGE(block)) { // If there's no previous block or the previous block is not // BUSY (thus, modifiable) run the forward_pass_kernel. Otherwise, // the previous block became BUSY, so assume the current block's @@ -1117,8 +1160,8 @@ void Planner::recalculate_trapezoids() { next = &block_buffer[block_index]; - // Skip sync blocks - if (!TEST(next->flag, BLOCK_BIT_SYNC_POSITION)) { + // Skip sync and page blocks + if (!TEST(next->flag, BLOCK_BIT_SYNC_POSITION) && !IS_PAGE(next)) { next_entry_speed = SQRT(next->entry_speed_sqr); if (block) { @@ -1240,7 +1283,7 @@ void Planner::check_axes_activity() { xyze_bool_t axis_active = { false }; #endif - #if FAN_COUNT > 0 + #if HAS_FAN uint8_t tail_fan_speed[FAN_COUNT]; #endif @@ -1255,72 +1298,57 @@ void Planner::check_axes_activity() { if (has_blocks_queued()) { - #if FAN_COUNT > 0 || ENABLED(BARICUDA) + #if HAS_FAN || ENABLED(BARICUDA) block_t *block = &block_buffer[block_buffer_tail]; #endif - #if FAN_COUNT > 0 + #if HAS_FAN FANS_LOOP(i) tail_fan_speed[i] = thermalManager.scaledFanSpeed(i, block->fan_speed[i]); #endif #if ENABLED(BARICUDA) - #if HAS_HEATER_1 - tail_valve_pressure = block->valve_pressure; - #endif - #if HAS_HEATER_2 - tail_e_to_p_pressure = block->e_to_p_pressure; - #endif + TERN_(HAS_HEATER_1, tail_valve_pressure = block->valve_pressure); + TERN_(HAS_HEATER_2, tail_e_to_p_pressure = block->e_to_p_pressure); #endif #if ANY(DISABLE_X, DISABLE_Y, DISABLE_Z, DISABLE_E) for (uint8_t b = block_buffer_tail; b != block_buffer_head; b = next_block_index(b)) { block_t *block = &block_buffer[b]; - LOOP_XYZE(i) if (block->steps[i]) axis_active[i] = true; + if (ENABLED(DISABLE_X) && block->steps.x) axis_active.x = true; + if (ENABLED(DISABLE_Y) && block->steps.y) axis_active.y = true; + if (ENABLED(DISABLE_Z) && block->steps.z) axis_active.z = true; + if (ENABLED(DISABLE_E) && block->steps.e) axis_active.e = true; } #endif } else { - #if HAS_CUTTER - cutter.refresh(); - #endif + TERN_(HAS_CUTTER, cutter.refresh()); - #if FAN_COUNT > 0 + #if HAS_FAN FANS_LOOP(i) tail_fan_speed[i] = thermalManager.scaledFanSpeed(i); #endif #if ENABLED(BARICUDA) - #if HAS_HEATER_1 - tail_valve_pressure = baricuda_valve_pressure; - #endif - #if HAS_HEATER_2 - tail_e_to_p_pressure = baricuda_e_to_p_pressure; - #endif + TERN_(HAS_HEATER_1, tail_valve_pressure = baricuda_valve_pressure); + TERN_(HAS_HEATER_2, tail_e_to_p_pressure = baricuda_e_to_p_pressure); #endif } // // Disable inactive axes // - #if ENABLED(DISABLE_X) - if (!axis_active.x) DISABLE_AXIS_X(); - #endif - #if ENABLED(DISABLE_Y) - if (!axis_active.y) DISABLE_AXIS_Y(); - #endif - #if ENABLED(DISABLE_Z) - if (!axis_active.z) DISABLE_AXIS_Z(); - #endif - #if ENABLED(DISABLE_E) - if (!axis_active.e) disable_e_steppers(); - #endif + if (TERN0(DISABLE_X, !axis_active.x)) DISABLE_AXIS_X(); + if (TERN0(DISABLE_Y, !axis_active.y)) DISABLE_AXIS_Y(); + if (TERN0(DISABLE_Z, !axis_active.z)) DISABLE_AXIS_Z(); + if (TERN0(DISABLE_E, !axis_active.e)) disable_e_steppers(); // // Update Fan speeds // - #if FAN_COUNT > 0 + #if HAS_FAN #if FAN_KICKSTART_TIME > 0 static millis_t fan_kick_end[FAN_COUNT] = { 0 }; @@ -1352,43 +1380,21 @@ void Planner::check_axes_activity() { #endif #define FAN_SET(F) do{ KICKSTART_FAN(F); _FAN_SET(F); }while(0) - #if HAS_FAN0 - FAN_SET(0); - #endif - #if HAS_FAN1 - FAN_SET(1); - #endif - #if HAS_FAN2 - FAN_SET(2); - #endif - #if HAS_FAN3 - FAN_SET(3); - #endif - #if HAS_FAN4 - FAN_SET(4); - #endif - #if HAS_FAN5 - FAN_SET(5); - #endif - #if HAS_FAN6 - FAN_SET(6); - #endif - #if HAS_FAN7 - FAN_SET(7); - #endif - #endif // FAN_COUNT > 0 + TERN_(HAS_FAN0, FAN_SET(0)); + TERN_(HAS_FAN1, FAN_SET(1)); + TERN_(HAS_FAN2, FAN_SET(2)); + TERN_(HAS_FAN3, FAN_SET(3)); + TERN_(HAS_FAN4, FAN_SET(4)); + TERN_(HAS_FAN5, FAN_SET(5)); + TERN_(HAS_FAN6, FAN_SET(6)); + TERN_(HAS_FAN7, FAN_SET(7)); + #endif // HAS_FAN - #if ENABLED(AUTOTEMP) - getHighESpeed(); - #endif + TERN_(AUTOTEMP, getHighESpeed()); #if ENABLED(BARICUDA) - #if HAS_HEATER_1 - analogWrite(pin_t(HEATER_1_PIN), tail_valve_pressure); - #endif - #if HAS_HEATER_2 - analogWrite(pin_t(HEATER_2_PIN), tail_e_to_p_pressure); - #endif + TERN_(HAS_HEATER_1, analogWrite(pin_t(HEATER_1_PIN), tail_valve_pressure)); + TERN_(HAS_HEATER_2, analogWrite(pin_t(HEATER_2_PIN), tail_e_to_p_pressure)); #endif } @@ -1408,14 +1414,32 @@ void Planner::check_axes_activity() { * The multiplier converts a given E value into a length. */ void Planner::calculate_volumetric_multipliers() { - for (uint8_t i = 0; i < COUNT(filament_size); i++) { + LOOP_L_N(i, COUNT(filament_size)) { volumetric_multiplier[i] = calculate_volumetric_multiplier(filament_size[i]); refresh_e_factor(i); } + #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) + calculate_volumetric_extruder_limits(); // update volumetric_extruder_limits as well. + #endif } #endif // !NO_VOLUMETRICS +#if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) + + /** + * Convert volumetric based limits into pre calculated extruder feedrate limits. + */ + void Planner::calculate_volumetric_extruder_limit(const uint8_t e) { + const float &lim = volumetric_extruder_limit[e], &siz = filament_size[e]; + volumetric_extruder_feedrate_limit[e] = (lim && siz) ? lim / CIRCLE_AREA(siz * 0.5f) : 0; + } + void Planner::calculate_volumetric_extruder_limits() { + LOOP_L_N(e, EXTRUDERS) calculate_volumetric_extruder_limit(e); + } + +#endif + #if ENABLED(FILAMENT_WIDTH_SENSOR) /** * Convert the ratio value given by the filament width sensor @@ -1438,11 +1462,8 @@ void Planner::check_axes_activity() { #if HAS_LEVELING constexpr xy_pos_t level_fulcrum = { - #if ENABLED(Z_SAFE_HOMING) - Z_SAFE_HOMING_X_POINT, Z_SAFE_HOMING_Y_POINT - #else - X_HOME_POS, Y_HOME_POS - #endif + TERN(Z_SAFE_HOMING, Z_SAFE_HOMING_X_POINT, X_HOME_POS), + TERN(Z_SAFE_HOMING, Z_SAFE_HOMING_Y_POINT, Y_HOME_POS) }; /** @@ -1519,10 +1540,6 @@ void Planner::check_axes_activity() { #endif } - - #if ENABLED(SKEW_CORRECTION) - unskew(raw); - #endif } #endif // HAS_LEVELING @@ -1560,13 +1577,13 @@ void Planner::quick_stop() { // forced to empty, there's no risk the ISR will touch this. delay_before_delivering = BLOCK_DELAY_FOR_1ST_MOVE; - #if HAS_SPI_LCD + #if HAS_WIRED_LCD // Clear the accumulated runtime clear_block_buffer_runtime(); #endif - // Make sure to drop any attempt of queuing moves for at least 1 second - cleaning_buffer_counter = 1000; + // Make sure to drop any attempt of queuing moves for 1 second + cleaning_buffer_counter = TEMP_TIMER_FREQUENCY; // Reenable Stepper ISR if (was_enabled) stepper.wake_up(); @@ -1596,6 +1613,7 @@ void Planner::finish_and_disable() { float Planner::get_axis_position_mm(const AxisEnum axis) { float axis_steps; #if IS_CORE + // Requesting one of the "core" axes? if (axis == CORE_AXIS_1 || axis == CORE_AXIS_2) { @@ -1613,9 +1631,30 @@ float Planner::get_axis_position_mm(const AxisEnum axis) { } else axis_steps = stepper.position(axis); + + #elif ENABLED(MARKFORGED_XY) + + // Requesting one of the joined axes? + if (axis == CORE_AXIS_1 || axis == CORE_AXIS_2) { + // Protect the access to the position. + const bool was_enabled = stepper.suspend(); + + const int32_t p1 = stepper.position(CORE_AXIS_1), + p2 = stepper.position(CORE_AXIS_2); + + if (was_enabled) stepper.wake_up(); + + axis_steps = ((axis == CORE_AXIS_1) ? p1 - p2 : p2); + } + else + axis_steps = stepper.position(axis); + #else + axis_steps = stepper.position(axis); + #endif + return axis_steps * steps_to_mm[axis]; } @@ -1623,11 +1662,8 @@ float Planner::get_axis_position_mm(const AxisEnum axis) { * Block until all buffered steps are executed / cleaned */ void Planner::synchronize() { - while ( - has_blocks_queued() || cleaning_buffer_counter - #if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER) - || (READ(CLOSED_LOOP_ENABLE_PIN) && !READ(CLOSED_LOOP_MOVE_COMPLETE_PIN)) - #endif + while (has_blocks_queued() || cleaning_buffer_counter + || TERN0(EXTERNAL_CLOSED_LOOP_CONTROLLER, CLOSED_LOOP_WAITING()) ) idle(); } @@ -1642,14 +1678,14 @@ void Planner::synchronize() { * extruder - target extruder * millimeters - the length of the movement, if known * - * Returns true if movement was properly queued, false otherwise + * Returns true if movement was properly queued, false otherwise (if cleaning) */ bool Planner::_buffer_steps(const xyze_long_t &target #if HAS_POSITION_FLOAT , const xyze_pos_t &target_float #endif - #if IS_KINEMATIC && DISABLED(CLASSIC_JERK) - , const xyze_float_t &delta_mm_cart + #if HAS_DIST_MM_ARG + , const xyze_float_t &cart_dist_mm #endif , feedRate_t fr_mm_s, const uint8_t extruder, const float &millimeters ) { @@ -1666,8 +1702,8 @@ bool Planner::_buffer_steps(const xyze_long_t &target #if HAS_POSITION_FLOAT , target_float #endif - #if IS_KINEMATIC && DISABLED(CLASSIC_JERK) - , delta_mm_cart + #if HAS_DIST_MM_ARG + , cart_dist_mm #endif , fr_mm_s, extruder, millimeters )) { @@ -1705,15 +1741,15 @@ bool Planner::_buffer_steps(const xyze_long_t &target * fr_mm_s - (target) speed of the move * extruder - target extruder * - * Returns true is movement is acceptable, false otherwise + * Returns true if movement is acceptable, false otherwise */ bool Planner::_populate_block(block_t * const block, bool split_move, const abce_long_t &target #if HAS_POSITION_FLOAT , const xyze_pos_t &target_float #endif - #if IS_KINEMATIC && DISABLED(CLASSIC_JERK) - , const xyze_float_t &delta_mm_cart + #if HAS_DIST_MM_ARG + , const xyze_float_t &cart_dist_mm #endif , feedRate_t fr_mm_s, const uint8_t extruder, const float &millimeters/*=0.0*/ ) { @@ -1744,9 +1780,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move, #if ENABLED(PREVENT_COLD_EXTRUSION) if (thermalManager.tooColdToExtrude(extruder)) { position.e = target.e; // Behave as if the move really took place, but ignore E part - #if HAS_POSITION_FLOAT - position_float.e = target_float.e; - #endif + TERN_(HAS_POSITION_FLOAT, position_float.e = target_float.e); de = 0; // no difference SERIAL_ECHO_MSG(STR_ERR_COLD_EXTRUDE_STOP); } @@ -1766,9 +1800,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move, #endif if (ignore_e) { position.e = target.e; // Behave as if the move really took place, but ignore E part - #if HAS_POSITION_FLOAT - position_float.e = target_float.e; - #endif + TERN_(HAS_POSITION_FLOAT, position_float.e = target_float.e); de = 0; // no difference SERIAL_ECHO_MSG(STR_ERR_LONG_EXTRUDE_STOP); } @@ -1797,6 +1829,12 @@ bool Planner::_populate_block(block_t * const block, bool split_move, if (dc < 0) SBI(dm, Z_HEAD); // ...and Z if (db + dc < 0) SBI(dm, B_AXIS); // Motor B direction if (CORESIGN(db - dc) < 0) SBI(dm, C_AXIS); // Motor C direction + #elif ENABLED(MARKFORGED_XY) + if (da < 0) SBI(dm, X_HEAD); // Save the real Extruder (head) direction in X Axis + if (db < 0) SBI(dm, Y_HEAD); // ...and Y + if (dc < 0) SBI(dm, Z_AXIS); + if (da + db < 0) SBI(dm, A_AXIS); // Motor A direction + if (db < 0) SBI(dm, B_AXIS); // Motor B direction #else if (da < 0) SBI(dm, X_AXIS); if (db < 0) SBI(dm, Y_AXIS); @@ -1817,14 +1855,23 @@ bool Planner::_populate_block(block_t * const block, bool split_move, // Set direction bits block->direction_bits = dm; + // Update block laser power + #if ENABLED(LASER_POWER_INLINE) + laser_inline.status.isPlanned = true; + block->laser.status = laser_inline.status; + block->laser.power = laser_inline.power; + #endif + // Number of steps for each axis - // See http://www.corexy.com/theory.html + // See https://www.corexy.com/theory.html #if CORE_IS_XY block->steps.set(ABS(da + db), ABS(da - db), ABS(dc)); #elif CORE_IS_XZ block->steps.set(ABS(da + dc), ABS(db), ABS(da - dc)); #elif CORE_IS_YZ block->steps.set(ABS(da), ABS(db + dc), ABS(db - dc)); + #elif ENABLED(MARKFORGED_XY) + block->steps.set(ABS(da + db), ABS(db), ABS(dc)); #elif IS_SCARA block->steps.set(ABS(da), ABS(db), ABS(dc)); #else @@ -1840,51 +1887,55 @@ bool Planner::_populate_block(block_t * const block, bool split_move, * So we need to create other 2 "AXIS", named X_HEAD and Y_HEAD, meaning the real displacement of the Head. * Having the real displacement of the head, we can calculate the total movement length and apply the desired speed. */ - struct DeltaMM : abce_float_t { - #if IS_CORE + struct DistanceMM : abce_float_t { + #if EITHER(IS_CORE, MARKFORGED_XY) xyz_pos_t head; #endif - } delta_mm; + } steps_dist_mm; #if IS_CORE #if CORE_IS_XY - delta_mm.head.x = da * steps_to_mm[A_AXIS]; - delta_mm.head.y = db * steps_to_mm[B_AXIS]; - delta_mm.z = dc * steps_to_mm[Z_AXIS]; - delta_mm.a = (da + db) * steps_to_mm[A_AXIS]; - delta_mm.b = CORESIGN(da - db) * steps_to_mm[B_AXIS]; + steps_dist_mm.head.x = da * steps_to_mm[A_AXIS]; + steps_dist_mm.head.y = db * steps_to_mm[B_AXIS]; + steps_dist_mm.z = dc * steps_to_mm[Z_AXIS]; + steps_dist_mm.a = (da + db) * steps_to_mm[A_AXIS]; + steps_dist_mm.b = CORESIGN(da - db) * steps_to_mm[B_AXIS]; #elif CORE_IS_XZ - delta_mm.head.x = da * steps_to_mm[A_AXIS]; - delta_mm.y = db * steps_to_mm[Y_AXIS]; - delta_mm.head.z = dc * steps_to_mm[C_AXIS]; - delta_mm.a = (da + dc) * steps_to_mm[A_AXIS]; - delta_mm.c = CORESIGN(da - dc) * steps_to_mm[C_AXIS]; + steps_dist_mm.head.x = da * steps_to_mm[A_AXIS]; + steps_dist_mm.y = db * steps_to_mm[Y_AXIS]; + steps_dist_mm.head.z = dc * steps_to_mm[C_AXIS]; + steps_dist_mm.a = (da + dc) * steps_to_mm[A_AXIS]; + steps_dist_mm.c = CORESIGN(da - dc) * steps_to_mm[C_AXIS]; #elif CORE_IS_YZ - delta_mm.x = da * steps_to_mm[X_AXIS]; - delta_mm.head.y = db * steps_to_mm[B_AXIS]; - delta_mm.head.z = dc * steps_to_mm[C_AXIS]; - delta_mm.b = (db + dc) * steps_to_mm[B_AXIS]; - delta_mm.c = CORESIGN(db - dc) * steps_to_mm[C_AXIS]; + steps_dist_mm.x = da * steps_to_mm[X_AXIS]; + steps_dist_mm.head.y = db * steps_to_mm[B_AXIS]; + steps_dist_mm.head.z = dc * steps_to_mm[C_AXIS]; + steps_dist_mm.b = (db + dc) * steps_to_mm[B_AXIS]; + steps_dist_mm.c = CORESIGN(db - dc) * steps_to_mm[C_AXIS]; #endif + #elif ENABLED(MARKFORGED_XY) + steps_dist_mm.head.x = da * steps_to_mm[A_AXIS]; + steps_dist_mm.head.y = db * steps_to_mm[B_AXIS]; + steps_dist_mm.z = dc * steps_to_mm[Z_AXIS]; + steps_dist_mm.a = (da - db) * steps_to_mm[A_AXIS]; + steps_dist_mm.b = db * steps_to_mm[B_AXIS]; #else - delta_mm.a = da * steps_to_mm[A_AXIS]; - delta_mm.b = db * steps_to_mm[B_AXIS]; - delta_mm.c = dc * steps_to_mm[C_AXIS]; + steps_dist_mm.a = da * steps_to_mm[A_AXIS]; + steps_dist_mm.b = db * steps_to_mm[B_AXIS]; + steps_dist_mm.c = dc * steps_to_mm[C_AXIS]; #endif #if EXTRUDERS - delta_mm.e = esteps_float * steps_to_mm[E_AXIS_N(extruder)]; + steps_dist_mm.e = esteps_float * steps_to_mm[E_AXIS_N(extruder)]; #else - delta_mm.e = 0.0f; + steps_dist_mm.e = 0.0f; #endif - #if ENABLED(LCD_SHOW_E_TOTAL) - e_move_accumulator += delta_mm.e; - #endif + TERN_(LCD_SHOW_E_TOTAL, e_move_accumulator += steps_dist_mm.e); if (block->steps.a < MIN_STEPS_PER_SEGMENT && block->steps.b < MIN_STEPS_PER_SEGMENT && block->steps.c < MIN_STEPS_PER_SEGMENT) { block->millimeters = (0 #if EXTRUDERS - + ABS(delta_mm.e) + + ABS(steps_dist_mm.e) #endif ); } @@ -1893,14 +1944,14 @@ bool Planner::_populate_block(block_t * const block, bool split_move, block->millimeters = millimeters; else block->millimeters = SQRT( - #if CORE_IS_XY - sq(delta_mm.head.x) + sq(delta_mm.head.y) + sq(delta_mm.z) + #if EITHER(CORE_IS_XY, MARKFORGED_XY) + sq(steps_dist_mm.head.x) + sq(steps_dist_mm.head.y) + sq(steps_dist_mm.z) #elif CORE_IS_XZ - sq(delta_mm.head.x) + sq(delta_mm.y) + sq(delta_mm.head.z) + sq(steps_dist_mm.head.x) + sq(steps_dist_mm.y) + sq(steps_dist_mm.head.z) #elif CORE_IS_YZ - sq(delta_mm.x) + sq(delta_mm.head.y) + sq(delta_mm.head.z) + sq(steps_dist_mm.x) + sq(steps_dist_mm.head.y) + sq(steps_dist_mm.head.z) #else - sq(delta_mm.x) + sq(delta_mm.y) + sq(delta_mm.z) + sq(steps_dist_mm.x) + sq(steps_dist_mm.y) + sq(steps_dist_mm.z) #endif ); @@ -1913,9 +1964,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move, * A correction function is permitted to add steps to an axis, it * should *never* remove steps! */ - #if ENABLED(BACKLASH_COMPENSATION) - backlash.add_correction_steps(da, db, dc, dm, block); - #endif + TERN_(BACKLASH_COMPENSATION, backlash.add_correction_steps(da, db, dc, dm, block)); } #if EXTRUDERS @@ -1931,11 +1980,9 @@ bool Planner::_populate_block(block_t * const block, bool split_move, MIXER_POPULATE_BLOCK(); #endif - #if HAS_CUTTER - block->cutter_power = cutter.power; - #endif + TERN_(HAS_CUTTER, block->cutter_power = cutter.power); - #if FAN_COUNT > 0 + #if HAS_FAN FANS_LOOP(i) block->fan_speed[i] = thermalManager.fan_speed[i]; #endif @@ -1944,7 +1991,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move, block->e_to_p_pressure = baricuda_e_to_p_pressure; #endif - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER block->extruder = extruder; #endif @@ -1954,7 +2001,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move, #endif // Enable active axes - #if CORE_IS_XY + #if EITHER(CORE_IS_XY, MARKFORGED_XY) if (block->steps.a || block->steps.b) { ENABLE_AXIS_X(); ENABLE_AXIS_Y(); @@ -1985,13 +2032,11 @@ bool Planner::_populate_block(block_t * const block, bool split_move, // Enable extruder(s) #if EXTRUDERS if (esteps) { - #if ENABLED(AUTO_POWER_CONTROL) - powerManager.power_on(); - #endif + TERN_(AUTO_POWER_CONTROL, powerManager.power_on()); #if ENABLED(DISABLE_INACTIVE_EXTRUDER) // Enable only the selected extruder - for (uint8_t i = 0; i < EXTRUDERS; i++) + LOOP_L_N(i, EXTRUDERS) if (g_uc_extruder_last_move[i] > 0) g_uc_extruder_last_move[i]--; #if HAS_DUPLICATION_MODE @@ -2035,25 +2080,29 @@ bool Planner::_populate_block(block_t * const block, bool split_move, const uint8_t moves_queued = nonbusy_movesplanned(); // Slow down when the buffer starts to empty, rather than wait at the corner for a buffer refill - #if EITHER(SLOWDOWN, ULTRA_LCD) || defined(XY_FREQUENCY_LIMIT) + #if EITHER(SLOWDOWN, HAS_WIRED_LCD) || defined(XY_FREQUENCY_LIMIT) // Segment time im micro seconds - uint32_t segment_time_us = LROUND(1000000.0f / inverse_secs); + int32_t segment_time_us = LROUND(1000000.0f / inverse_secs); #endif #if ENABLED(SLOWDOWN) - if (WITHIN(moves_queued, 2, (BLOCK_BUFFER_SIZE) / 2 - 1)) { - if (segment_time_us < settings.min_segment_time_us) { - // buffer is draining, add extra time. The amount of time added increases if the buffer is still emptied more. - const uint32_t nst = segment_time_us + LROUND(2 * (settings.min_segment_time_us - segment_time_us) / moves_queued); + #ifndef SLOWDOWN_DIVISOR + #define SLOWDOWN_DIVISOR 2 + #endif + if (WITHIN(moves_queued, 2, (BLOCK_BUFFER_SIZE) / (SLOWDOWN_DIVISOR) - 1)) { + const int32_t time_diff = settings.min_segment_time_us - segment_time_us; + if (time_diff > 0) { + // Buffer is draining so add extra time. The amount of time added increases if the buffer is still emptied more. + const int32_t nst = segment_time_us + LROUND(2 * time_diff / moves_queued); inverse_secs = 1000000.0f / nst; - #if defined(XY_FREQUENCY_LIMIT) || HAS_SPI_LCD + #if defined(XY_FREQUENCY_LIMIT) || HAS_WIRED_LCD segment_time_us = nst; #endif } } #endif - #if HAS_SPI_LCD + #if HAS_WIRED_LCD // Protect the access to the position. const bool was_enabled = stepper.suspend(); @@ -2068,7 +2117,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move, #if ENABLED(FILAMENT_WIDTH_SENSOR) if (extruder == FILAMENT_SENSOR_EXTRUDER_NUM) // Only for extruder with filament sensor - filwidth.advance_e(delta_mm.e); + filwidth.advance_e(steps_dist_mm.e); #endif // Calculate and limit speed in mm/sec @@ -2078,7 +2127,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move, // Linear axes first with less logic LOOP_XYZ(i) { - current_speed[i] = delta_mm[i] * inverse_secs; + current_speed[i] = steps_dist_mm[i] * inverse_secs; const feedRate_t cs = ABS(current_speed[i]), max_fr = settings.max_feedrate_mm_s[i]; if (cs > max_fr) NOMORE(speed_factor, max_fr / cs); @@ -2087,58 +2136,72 @@ bool Planner::_populate_block(block_t * const block, bool split_move, // Limit speed on extruders, if any #if EXTRUDERS { - current_speed.e = delta_mm.e * inverse_secs; - #if BOTH(MIXING_EXTRUDER, RETRACT_SYNC_MIXING) + current_speed.e = steps_dist_mm.e * inverse_secs; + #if HAS_MIXER_SYNC_CHANNEL // Move all mixing extruders at the specified rate if (mixer.get_current_vtool() == MIXER_AUTORETRACT_TOOL) current_speed.e *= MIXING_STEPPERS; #endif + const feedRate_t cs = ABS(current_speed.e), - max_fr = (settings.max_feedrate_mm_s[E_AXIS_N(extruder)] - #if BOTH(MIXING_EXTRUDER, RETRACT_SYNC_MIXING) - * MIXING_STEPPERS - #endif - ); - if (cs > max_fr) NOMORE(speed_factor, max_fr / cs); + max_fr = settings.max_feedrate_mm_s[E_AXIS_N(extruder)] + * TERN(HAS_MIXER_SYNC_CHANNEL, MIXING_STEPPERS, 1); + + if (cs > max_fr) NOMORE(speed_factor, max_fr / cs); //respect max feedrate on any movement (doesn't matter if E axes only or not) + + #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) + const feedRate_t max_vfr = volumetric_extruder_feedrate_limit[extruder] + * TERN(HAS_MIXER_SYNC_CHANNEL, MIXING_STEPPERS, 1); + + // TODO: Doesn't work properly for joined segments. Set MIN_STEPS_PER_SEGMENT 1 as workaround. + + if (block->steps.a || block->steps.b || block->steps.c) { + + if (max_vfr > 0 && cs > max_vfr) { + NOMORE(speed_factor, max_vfr / cs); // respect volumetric extruder limit (if any) + /* <-- add a slash to enable + SERIAL_ECHOPAIR("volumetric extruder limit enforced: ", (cs * CIRCLE_AREA(filament_size[extruder] * 0.5f))); + SERIAL_ECHOPAIR(" mm^3/s (", cs); + SERIAL_ECHOPAIR(" mm/s) limited to ", (max_vfr * CIRCLE_AREA(filament_size[extruder] * 0.5f))); + SERIAL_ECHOPAIR(" mm^3/s (", max_vfr); + SERIAL_ECHOLNPGM(" mm/s)"); + //*/ + } + } + #endif } #endif - // Max segment time in µs. #ifdef XY_FREQUENCY_LIMIT - // Check and limit the xy direction change frequency - const unsigned char direction_change = block->direction_bits ^ old_direction_bits; - old_direction_bits = block->direction_bits; - segment_time_us = LROUND((float)segment_time_us / speed_factor); - - uint32_t xs0 = axis_segment_time_us[0].x, - xs1 = axis_segment_time_us[1].x, - xs2 = axis_segment_time_us[2].x, - ys0 = axis_segment_time_us[0].y, - ys1 = axis_segment_time_us[1].y, - ys2 = axis_segment_time_us[2].y; - - if (TEST(direction_change, X_AXIS)) { - xs2 = axis_segment_time_us[2].x = xs1; - xs1 = axis_segment_time_us[1].x = xs0; - xs0 = 0; - } - xs0 = axis_segment_time_us[0].x = xs0 + segment_time_us; + static uint8_t old_direction_bits; // = 0 - if (TEST(direction_change, Y_AXIS)) { - ys2 = axis_segment_time_us[2].y = axis_segment_time_us[1].y; - ys1 = axis_segment_time_us[1].y = axis_segment_time_us[0].y; - ys0 = 0; - } - ys0 = axis_segment_time_us[0].y = ys0 + segment_time_us; - - const uint32_t max_x_segment_time = _MAX(xs0, xs1, xs2), - max_y_segment_time = _MAX(ys0, ys1, ys2), - min_xy_segment_time = _MIN(max_x_segment_time, max_y_segment_time); - if (min_xy_segment_time < MAX_FREQ_TIME_US) { - const float low_sf = speed_factor * min_xy_segment_time / (MAX_FREQ_TIME_US); - NOMORE(speed_factor, low_sf); + if (xy_freq_limit_hz) { + // Check and limit the xy direction change frequency + const uint8_t direction_change = block->direction_bits ^ old_direction_bits; + old_direction_bits = block->direction_bits; + segment_time_us = LROUND(float(segment_time_us) / speed_factor); + + static int32_t xs0, xs1, xs2, ys0, ys1, ys2; + if (segment_time_us > xy_freq_min_interval_us) + xs2 = xs1 = ys2 = ys1 = xy_freq_min_interval_us; + else { + xs2 = xs1; xs1 = xs0; + ys2 = ys1; ys1 = ys0; + } + xs0 = TEST(direction_change, X_AXIS) ? segment_time_us : xy_freq_min_interval_us; + ys0 = TEST(direction_change, Y_AXIS) ? segment_time_us : xy_freq_min_interval_us; + + if (segment_time_us < xy_freq_min_interval_us) { + const int32_t least_xy_segment_time = _MIN(_MAX(xs0, xs1, xs2), _MAX(ys0, ys1, ys2)); + if (least_xy_segment_time < xy_freq_min_interval_us) { + float freq_xy_feedrate = (speed_factor * least_xy_segment_time) / xy_freq_min_interval_us; + NOLESS(freq_xy_feedrate, xy_freq_min_speed_factor); + NOMORE(speed_factor, freq_xy_feedrate); + } + } } + #endif // XY_FREQUENCY_LIMIT // Correct the speed @@ -2154,9 +2217,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move, if (!block->steps.a && !block->steps.b && !block->steps.c) { // convert to: acceleration steps/sec^2 accel = CEIL(settings.retract_acceleration * steps_per_mm); - #if ENABLED(LIN_ADVANCE) - block->use_advance_lead = false; - #endif + TERN_(LIN_ADVANCE, block->use_advance_lead = false); } else { #define LIMIT_ACCEL_LONG(AXIS,INDX) do{ \ @@ -2178,18 +2239,9 @@ bool Planner::_populate_block(block_t * const block, bool split_move, #if ENABLED(LIN_ADVANCE) - #if DISABLED(CLASSIC_JERK) - #if ENABLED(DISTINCT_E_FACTORS) - #define MAX_E_JERK max_e_jerk[extruder] - #else - #define MAX_E_JERK max_e_jerk - #endif - #else - #define MAX_E_JERK max_jerk.e - #endif + #define MAX_E_JERK(N) TERN(HAS_LINEAR_E_JERK, max_e_jerk[E_INDEX_N(N)], max_jerk.e) /** - * * Use LIN_ADVANCE for blocks if all these are true: * * esteps : This is a print move, because we checked for A, B, C steps before. @@ -2218,33 +2270,26 @@ bool Planner::_populate_block(block_t * const block, bool split_move, if (block->e_D_ratio > 3.0f) block->use_advance_lead = false; else { - const uint32_t max_accel_steps_per_s2 = MAX_E_JERK / (extruder_advance_K[active_extruder] * block->e_D_ratio) * steps_per_mm; - #if ENABLED(LA_DEBUG) - if (accel > max_accel_steps_per_s2) SERIAL_ECHOLNPGM("Acceleration limited."); - #endif + const uint32_t max_accel_steps_per_s2 = MAX_E_JERK(extruder) / (extruder_advance_K[active_extruder] * block->e_D_ratio) * steps_per_mm; + if (TERN0(LA_DEBUG, accel > max_accel_steps_per_s2)) + SERIAL_ECHOLNPGM("Acceleration limited."); NOMORE(accel, max_accel_steps_per_s2); } } #endif - #if ENABLED(DISTINCT_E_FACTORS) - #define ACCEL_IDX extruder - #else - #define ACCEL_IDX 0 - #endif - // Limit acceleration per axis if (block->step_event_count <= cutoff_long) { LIMIT_ACCEL_LONG(A_AXIS, 0); LIMIT_ACCEL_LONG(B_AXIS, 0); LIMIT_ACCEL_LONG(C_AXIS, 0); - LIMIT_ACCEL_LONG(E_AXIS, ACCEL_IDX); + LIMIT_ACCEL_LONG(E_AXIS, E_INDEX_N(extruder)); } else { LIMIT_ACCEL_FLOAT(A_AXIS, 0); LIMIT_ACCEL_FLOAT(B_AXIS, 0); LIMIT_ACCEL_FLOAT(C_AXIS, 0); - LIMIT_ACCEL_FLOAT(E_AXIS, ACCEL_IDX); + LIMIT_ACCEL_FLOAT(E_AXIS, E_INDEX_N(extruder)); } } block->acceleration_steps_per_s2 = accel; @@ -2266,7 +2311,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move, float vmax_junction_sqr; // Initial limit on the segment entry velocity (mm/s)^2 - #if DISABLED(CLASSIC_JERK) + #if HAS_JUNCTION_DEVIATION /** * Compute maximum allowable entry speed at junction by centripetal acceleration approximation. * Let a circle be tangent to both previous and current path line segments, where the junction @@ -2305,22 +2350,23 @@ bool Planner::_populate_block(block_t * const block, bool split_move, static xyze_float_t prev_unit_vec; xyze_float_t unit_vec = - #if IS_KINEMATIC && DISABLED(CLASSIC_JERK) - delta_mm_cart + #if HAS_DIST_MM_ARG + cart_dist_mm #else - { delta_mm.x, delta_mm.y, delta_mm.z, delta_mm.e } + { steps_dist_mm.x, steps_dist_mm.y, steps_dist_mm.z, steps_dist_mm.e } #endif ; - unit_vec *= inverse_millimeters; - #if IS_CORE && DISABLED(CLASSIC_JERK) - /** - * On CoreXY the length of the vector [A,B] is SQRT(2) times the length of the head movement vector [X,Y]. - * So taking Z and E into account, we cannot scale to a unit vector with "inverse_millimeters". - * => normalize the complete junction vector - */ - normalize_junction_vector(unit_vec); - #endif + /** + * On CoreXY the length of the vector [A,B] is SQRT(2) times the length of the head movement vector [X,Y]. + * So taking Z and E into account, we cannot scale to a unit vector with "inverse_millimeters". + * => normalize the complete junction vector. + * Elsewise, when needed JD will factor-in the E component + */ + if (EITHER(IS_CORE, MARKFORGED_XY) || esteps > 0) + normalize_junction_vector(unit_vec); // Normalize with XYZE components + else + unit_vec *= inverse_millimeters; // Use pre-calculated (1 / SQRT(x^2 + y^2 + z^2)) // Skip first block or when previous_nominal_speed is used as a flag for homing and offset cycles. if (moves_queued && !UNEAR_ZERO(previous_nominal_speed_sqr)) { @@ -2344,18 +2390,95 @@ bool Planner::_populate_block(block_t * const block, bool split_move, const float junction_acceleration = limit_value_by_axis_maximum(block->acceleration, junction_unit_vec), sin_theta_d2 = SQRT(0.5f * (1.0f - junction_cos_theta)); // Trig half angle identity. Always positive. - vmax_junction_sqr = (junction_acceleration * junction_deviation_mm * sin_theta_d2) / (1.0f - sin_theta_d2); - if (block->millimeters < 1) { + vmax_junction_sqr = junction_acceleration * junction_deviation_mm * sin_theta_d2 / (1.0f - sin_theta_d2); + + #if ENABLED(JD_HANDLE_SMALL_SEGMENTS) + + // For small moves with >135° junction (octagon) find speed for approximate arc + if (block->millimeters < 1 && junction_cos_theta < -0.7071067812f) { + + #if ENABLED(JD_USE_MATH_ACOS) + + #error "TODO: Inline maths with the MCU / FPU." + + #elif ENABLED(JD_USE_LOOKUP_TABLE) + + // Fast acos approximation (max. error +-0.01 rads) + // Based on LUT table and linear interpolation + + /** + * // Generate the JD Lookup Table + * constexpr float c = 1.00751495f; // Correction factor to center error around 0 + * for (int i = 0; i < jd_lut_count - 1; ++i) { + * const float x0 = (sq(i) - 1) / sq(i), + * y0 = acos(x0) * (i == 0 ? 1 : c), + * x1 = i < jd_lut_count - 1 ? 0.5 * x0 + 0.5 : 0.999999f, + * y1 = acos(x1) * (i < jd_lut_count - 1 ? c : 1); + * jd_lut_k[i] = (y0 - y1) / (x0 - x1); + * jd_lut_b[i] = (y1 * x0 - y0 * x1) / (x0 - x1); + * } + * + * // Compute correction factor (Set c to 1.0f first!) + * float min = INFINITY, max = -min; + * for (float t = 0; t <= 1; t += 0.0003f) { + * const float e = acos(t) / approx(t); + * if (isfinite(e)) { + * if (e < min) min = e; + * if (e > max) max = e; + * } + * } + * fprintf(stderr, "%.9gf, ", (min + max) / 2); + */ + static constexpr int16_t jd_lut_count = 16; + static constexpr uint16_t jd_lut_tll = _BV(jd_lut_count - 1); + static constexpr int16_t jd_lut_tll0 = __builtin_clz(jd_lut_tll) + 1; // i.e., 16 - jd_lut_count + 1 + static constexpr float jd_lut_k[jd_lut_count] PROGMEM = { + -1.03145837f, -1.30760646f, -1.75205851f, -2.41705704f, + -3.37769222f, -4.74888992f, -6.69649887f, -9.45661736f, + -13.3640480f, -18.8928222f, -26.7136841f, -37.7754593f, + -53.4201813f, -75.5458374f, -106.836761f, -218.532821f }; + static constexpr float jd_lut_b[jd_lut_count] PROGMEM = { + 1.57079637f, 1.70887053f, 2.04220939f, 2.62408352f, + 3.52467871f, 4.85302639f, 6.77020454f, 9.50875854f, + 13.4009285f, 18.9188995f, 26.7321243f, 37.7885055f, + 53.4293975f, 75.5523529f, 106.841369f, 218.534011f }; + + const float neg = junction_cos_theta < 0 ? -1 : 1, + t = neg * junction_cos_theta; + + const int16_t idx = (t < 0.00000003f) ? 0 : __builtin_clz(uint16_t((1.0f - t) * jd_lut_tll)) - jd_lut_tll0; + + float junction_theta = t * pgm_read_float(&jd_lut_k[idx]) + pgm_read_float(&jd_lut_b[idx]); + if (neg > 0) junction_theta = RADIANS(180) - junction_theta; // acos(-t) + + #else + + // Fast acos(-t) approximation (max. error +-0.033rad = 1.89°) + // Based on MinMax polynomial published by W. Randolph Franklin, see + // https://wrf.ecse.rpi.edu/Research/Short_Notes/arcsin/onlyelem.html + // acos( t) = pi / 2 - asin(x) + // acos(-t) = pi - acos(t) ... pi / 2 + asin(x) + + const float neg = junction_cos_theta < 0 ? -1 : 1, + t = neg * junction_cos_theta, + asinx = 0.032843707f + + t * (-1.451838349f + + t * ( 29.66153956f + + t * (-131.1123477f + + t * ( 262.8130562f + + t * (-242.7199627f + + t * ( 84.31466202f ) ))))), + junction_theta = RADIANS(90) + neg * asinx; // acos(-t) + + // NOTE: junction_theta bottoms out at 0.033 which avoids divide by 0. - // Fast acos approximation, minus the error bar to be safe - const float junction_theta = (RADIANS(-40) * sq(junction_cos_theta) - RADIANS(50)) * junction_cos_theta + RADIANS(90) - 0.18f; + #endif - // If angle is greater than 135 degrees (octagon), find speed for approximate arc - if (junction_theta > RADIANS(135)) { - const float limit_sqr = block->millimeters / (RADIANS(180) - junction_theta) * junction_acceleration; + const float limit_sqr = (block->millimeters * junction_acceleration) / junction_theta; NOMORE(vmax_junction_sqr, limit_sqr); } - } + + #endif // JD_HANDLE_SMALL_SEGMENTS } // Get the lowest speed @@ -2390,26 +2513,15 @@ bool Planner::_populate_block(block_t * const block, bool split_move, // Start with a safe speed (from which the machine may halt to stop immediately). float safe_speed = nominal_speed; - #ifdef TRAVEL_EXTRA_XYJERK - const float extra_xyjerk = (de <= 0) ? TRAVEL_EXTRA_XYJERK : 0; - #else - constexpr float extra_xyjerk = 0; + #ifndef TRAVEL_EXTRA_XYJERK + #define TRAVEL_EXTRA_XYJERK 0 #endif + const float extra_xyjerk = (de <= 0) ? TRAVEL_EXTRA_XYJERK : 0; uint8_t limited = 0; - #if HAS_LINEAR_E_JERK - LOOP_XYZ(i) - #else - LOOP_XYZE(i) - #endif - { + TERN(HAS_LINEAR_E_JERK, LOOP_XYZ, LOOP_XYZE)(i) { const float jerk = ABS(current_speed[i]), // cs : Starting from zero, change in speed for this axis - maxj = (max_jerk[i] // mj : The max jerk setting for this axis - #ifdef TRAVEL_EXTRA_XYJERK - + (i == X_AXIS || i == Y_AXIS ? extra_xyjerk : 0) - #endif - ); - + maxj = (max_jerk[i] + (i == X_AXIS || i == Y_AXIS ? extra_xyjerk : 0.0f)); // mj : The max jerk setting for this axis if (jerk > maxj) { // cs > mj : New current speed too fast? if (limited) { // limited already? const float mjerk = nominal_speed * maxj; // ns*mj @@ -2436,16 +2548,16 @@ bool Planner::_populate_block(block_t * const block, bool split_move, // Pick the smaller of the nominal speeds. Higher speed shall not be achieved at the junction during coasting. CACHED_SQRT(previous_nominal_speed, previous_nominal_speed_sqr); - vmax_junction = _MIN(nominal_speed, previous_nominal_speed); + float smaller_speed_factor = 1.0f; + if (nominal_speed < previous_nominal_speed) { + vmax_junction = nominal_speed; + smaller_speed_factor = vmax_junction / previous_nominal_speed; + } + else + vmax_junction = previous_nominal_speed; // Now limit the jerk in all axes. - const float smaller_speed_factor = vmax_junction / previous_nominal_speed; - #if HAS_LINEAR_E_JERK - LOOP_XYZ(axis) - #else - LOOP_XYZE(axis) - #endif - { + TERN(HAS_LINEAR_E_JERK, LOOP_XYZ, LOOP_XYZE)(axis) { // Limit an axis. We have to differentiate: coasting, reversal of an axis, full stop. float v_exit = previous_speed[axis] * smaller_speed_factor, v_entry = current_speed[axis]; @@ -2461,11 +2573,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move, : // v_exit <= v_entry coasting axis reversal ( (v_entry < 0 || v_exit > 0) ? (v_entry - v_exit) : _MAX(-v_exit, v_entry) ); - const float maxj = (max_jerk[axis] - #ifdef TRAVEL_EXTRA_XYJERK - + (axis == X_AXIS || axis == Y_AXIS ? extra_xyjerk : 0) - #endif - ); + const float maxj = (max_jerk[axis] + (axis == X_AXIS || axis == Y_AXIS ? extra_xyjerk : 0.0f)); if (jerk > maxj) { v_factor *= maxj / jerk; @@ -2484,10 +2592,10 @@ bool Planner::_populate_block(block_t * const block, bool split_move, previous_safe_speed = safe_speed; - #if DISABLED(CLASSIC_JERK) - vmax_junction_sqr = _MIN(vmax_junction_sqr, sq(vmax_junction)); + #if HAS_JUNCTION_DEVIATION + NOMORE(vmax_junction_sqr, sq(vmax_junction)); // Throttle down to max speed #else - vmax_junction_sqr = sq(vmax_junction); + vmax_junction_sqr = sq(vmax_junction); // Go up or down to the new speed #endif #endif // Classic Jerk Limiting @@ -2516,22 +2624,14 @@ bool Planner::_populate_block(block_t * const block, bool split_move, previous_speed = current_speed; previous_nominal_speed_sqr = block->nominal_speed_sqr; - // Update the position - position = target; - #if HAS_POSITION_FLOAT - position_float = target_float; - #endif + position = target; // Update the position - #if ENABLED(GRADIENT_MIX) - mixer.gradient_control(target_float.z); - #endif + TERN_(HAS_POSITION_FLOAT, position_float = target_float); + TERN_(GRADIENT_MIX, mixer.gradient_control(target_float.z)); + TERN_(POWER_LOSS_RECOVERY, block->sdpos = recovery.command_sdpos()); - #if ENABLED(POWER_LOSS_RECOVERY) - block->sdpos = recovery.command_sdpos(); - #endif + return true; // Movement was accepted - // Movement was accepted - return true; } // _populate_block() /** @@ -2576,10 +2676,12 @@ void Planner::buffer_sync_block() { * fr_mm_s - (target) speed of the move * extruder - target extruder * millimeters - the length of the movement, if known + * + * Return 'false' if no segment was queued due to cleaning, cold extrusion, full queue, etc. */ bool Planner::buffer_segment(const float &a, const float &b, const float &c, const float &e - #if IS_KINEMATIC && DISABLED(CLASSIC_JERK) - , const xyze_float_t &delta_mm_cart + #if HAS_DIST_MM_ARG + , const xyze_float_t &cart_dist_mm #endif , const feedRate_t &fr_mm_s, const uint8_t extruder, const float &millimeters/*=0.0*/ ) { @@ -2609,15 +2711,9 @@ bool Planner::buffer_segment(const float &a, const float &b, const float &c, con #endif // DRYRUN prevents E moves from taking place - if (DEBUGGING(DRYRUN) - #if ENABLED(CANCEL_OBJECTS) - || cancelable.skipping - #endif - ) { + if (DEBUGGING(DRYRUN) || TERN0(CANCEL_OBJECTS, cancelable.skipping)) { position.e = target.e; - #if HAS_POSITION_FLOAT - position_float.e = e; - #endif + TERN_(HAS_POSITION_FLOAT, position_float.e = e); } /* <-- add a slash to enable @@ -2628,37 +2724,38 @@ bool Planner::buffer_segment(const float &a, const float &b, const float &c, con SERIAL_ECHOPAIR("->", target.a); SERIAL_ECHOPAIR(") B:", b); #else - SERIAL_ECHOPAIR(" X:", a); + SERIAL_ECHOPAIR_P(SP_X_LBL, a); SERIAL_ECHOPAIR(" (", position.x); SERIAL_ECHOPAIR("->", target.x); - SERIAL_ECHOPAIR(") Y:", b); + SERIAL_CHAR(')'); + SERIAL_ECHOPAIR_P(SP_Y_LBL, b); #endif SERIAL_ECHOPAIR(" (", position.y); SERIAL_ECHOPAIR("->", target.y); #if ENABLED(DELTA) SERIAL_ECHOPAIR(") C:", c); #else - SERIAL_ECHOPAIR(") Z:", c); + SERIAL_CHAR(')'); + SERIAL_ECHOPAIR_P(SP_Z_LBL, c); #endif SERIAL_ECHOPAIR(" (", position.z); SERIAL_ECHOPAIR("->", target.z); - SERIAL_ECHOPAIR(") E:", e); + SERIAL_CHAR(')'); + SERIAL_ECHOPAIR_P(SP_E_LBL, e); SERIAL_ECHOPAIR(" (", position.e); SERIAL_ECHOPAIR("->", target.e); SERIAL_ECHOLNPGM(")"); //*/ - // Queue the movement - if ( - !_buffer_steps(target + // Queue the movement. Return 'false' if the move was not queued. + if (!_buffer_steps(target #if HAS_POSITION_FLOAT , target_float #endif - #if IS_KINEMATIC && DISABLED(CLASSIC_JERK) - , delta_mm_cart + #if HAS_DIST_MM_ARG + , cart_dist_mm #endif - , fr_mm_s, extruder, millimeters - ) + , fr_mm_s, extruder, millimeters) ) return false; stepper.wake_up(); @@ -2682,24 +2779,22 @@ bool Planner::buffer_line(const float &rx, const float &ry, const float &rz, con #endif ) { xyze_pos_t machine = { rx, ry, rz, e }; - #if HAS_POSITION_MODIFIERS - apply_modifiers(machine); - #endif + TERN_(HAS_POSITION_MODIFIERS, apply_modifiers(machine)); #if IS_KINEMATIC - #if DISABLED(CLASSIC_JERK) - const xyze_pos_t delta_mm_cart = { + #if HAS_JUNCTION_DEVIATION + const xyze_pos_t cart_dist_mm = { rx - position_cart.x, ry - position_cart.y, rz - position_cart.z, e - position_cart.e }; #else - const xyz_pos_t delta_mm_cart = { rx - position_cart.x, ry - position_cart.y, rz - position_cart.z }; + const xyz_pos_t cart_dist_mm = { rx - position_cart.x, ry - position_cart.y, rz - position_cart.z }; #endif float mm = millimeters; if (mm == 0.0) - mm = (delta_mm_cart.x != 0.0 || delta_mm_cart.y != 0.0) ? delta_mm_cart.magnitude() : ABS(delta_mm_cart.z); + mm = (cart_dist_mm.x != 0.0 || cart_dist_mm.y != 0.0) ? cart_dist_mm.magnitude() : ABS(cart_dist_mm.z); // Cartesian XYZ to kinematic ABC, stored in global 'delta' inverse_kinematics(machine); @@ -2714,8 +2809,8 @@ bool Planner::buffer_line(const float &rx, const float &ry, const float &rz, con const feedRate_t feedrate = fr_mm_s; #endif if (buffer_segment(delta.a, delta.b, delta.c, machine.e - #if DISABLED(CLASSIC_JERK) - , delta_mm_cart + #if HAS_JUNCTION_DEVIATION + , cart_dist_mm #endif , feedrate, extruder, mm )) { @@ -2729,6 +2824,69 @@ bool Planner::buffer_line(const float &rx, const float &ry, const float &rz, con #endif } // buffer_line() +#if ENABLED(DIRECT_STEPPING) + + void Planner::buffer_page(const page_idx_t page_idx, const uint8_t extruder, const uint16_t num_steps) { + if (!last_page_step_rate) { + kill(GET_TEXT(MSG_BAD_PAGE_SPEED)); + return; + } + + uint8_t next_buffer_head; + block_t * const block = get_next_free_block(next_buffer_head); + + block->flag = BLOCK_FLAG_IS_PAGE; + + #if FAN_COUNT > 0 + FANS_LOOP(i) block->fan_speed[i] = thermalManager.fan_speed[i]; + #endif + + #if HAS_MULTI_EXTRUDER + block->extruder = extruder; + #endif + + block->page_idx = page_idx; + + block->step_event_count = num_steps; + block->initial_rate = + block->final_rate = + block->nominal_rate = last_page_step_rate; // steps/s + + block->accelerate_until = 0; + block->decelerate_after = block->step_event_count; + + // Will be set to last direction later if directional format. + block->direction_bits = 0; + + #define PAGE_UPDATE_DIR(AXIS) \ + if (!last_page_dir[_AXIS(AXIS)]) SBI(block->direction_bits, _AXIS(AXIS)); + + if (!DirectStepping::Config::DIRECTIONAL) { + PAGE_UPDATE_DIR(X); + PAGE_UPDATE_DIR(Y); + PAGE_UPDATE_DIR(Z); + PAGE_UPDATE_DIR(E); + } + + // If this is the first added movement, reload the delay, otherwise, cancel it. + if (block_buffer_head == block_buffer_tail) { + // If it was the first queued block, restart the 1st block delivery delay, to + // give the planner an opportunity to queue more movements and plan them + // As there are no queued movements, the Stepper ISR will not touch this + // variable, so there is no risk setting this here (but it MUST be done + // before the following line!!) + delay_before_delivering = BLOCK_DELAY_FOR_1ST_MOVE; + } + + // Move buffer head + block_buffer_head = next_buffer_head; + + enable_all_steppers(); + stepper.wake_up(); + } + +#endif // DIRECT_STEPPING + /** * Directly set the planner ABC position (and stepper positions) * converting mm (or angles for SCARA) into steps. @@ -2737,12 +2895,8 @@ bool Planner::buffer_line(const float &rx, const float &ry, const float &rz, con */ void Planner::set_machine_position_mm(const float &a, const float &b, const float &c, const float &e) { - #if ENABLED(DISTINCT_E_FACTORS) - last_extruder = active_extruder; - #endif - #if HAS_POSITION_FLOAT - position_float.set(a, b, c, e); - #endif + TERN_(DISTINCT_E_FACTORS, last_extruder = active_extruder); + TERN_(HAS_POSITION_FLOAT, position_float.set(a, b, c, e)); position.set(LROUND(a * settings.axis_steps_per_mm[A_AXIS]), LROUND(b * settings.axis_steps_per_mm[B_AXIS]), LROUND(c * settings.axis_steps_per_mm[C_AXIS]), @@ -2759,13 +2913,7 @@ void Planner::set_machine_position_mm(const float &a, const float &b, const floa void Planner::set_position_mm(const float &rx, const float &ry, const float &rz, const float &e) { xyze_pos_t machine = { rx, ry, rz, e }; #if HAS_POSITION_MODIFIERS - { - apply_modifiers(machine - #if HAS_LEVELING - , true - #endif - ); - } + apply_modifiers(machine, true); #endif #if IS_KINEMATIC position_cart.set(rx, ry, rz, e); @@ -2781,21 +2929,13 @@ void Planner::set_position_mm(const float &rx, const float &ry, const float &rz, */ void Planner::set_e_position_mm(const float &e) { const uint8_t axis_index = E_AXIS_N(active_extruder); - #if ENABLED(DISTINCT_E_FACTORS) - last_extruder = active_extruder; - #endif - #if ENABLED(FWRETRACT) - float e_new = e - fwretract.current_retract[active_extruder]; - #else - const float e_new = e; - #endif + TERN_(DISTINCT_E_FACTORS, last_extruder = active_extruder); + + const float e_new = e - TERN0(FWRETRACT, fwretract.current_retract[active_extruder]); position.e = LROUND(settings.axis_steps_per_mm[axis_index] * e_new); - #if HAS_POSITION_FLOAT - position_float.e = e_new; - #endif - #if IS_KINEMATIC - position_cart.e = e; - #endif + TERN_(HAS_POSITION_FLOAT, position_float.e = e_new); + TERN_(IS_KINEMATIC, position_cart.e = e); + if (has_blocks_queued()) buffer_sync_block(); else @@ -2815,9 +2955,7 @@ void Planner::reset_acceleration_rates() { if (AXIS_CONDITION) NOLESS(highest_rate, max_acceleration_steps_per_s2[i]); } cutoff_long = 4294967295UL / highest_rate; // 0xFFFFFFFFUL - #if HAS_LINEAR_E_JERK - recalculate_max_e_jerk(); - #endif + TERN_(HAS_LINEAR_E_JERK, recalculate_max_e_jerk()); } // Recalculate position, steps_to_mm if settings.axis_steps_per_mm changes! @@ -2846,7 +2984,7 @@ void Planner::set_max_acceleration(const uint8_t axis, float targetValue) { const xyze_float_t &max_acc_edit_scaled = max_accel_edit; #else constexpr xyze_float_t max_accel_edit = DEFAULT_MAX_ACCELERATION; - constexpr xyze_float_t max_acc_edit_scaled = max_accel_edit * 2; + const xyze_float_t max_acc_edit_scaled = max_accel_edit * 2; #endif limit_and_warn(targetValue, axis, PSTR("Acceleration"), max_acc_edit_scaled); #endif @@ -2863,7 +3001,7 @@ void Planner::set_max_feedrate(const uint8_t axis, float targetValue) { const xyze_float_t &max_fr_edit_scaled = max_fr_edit; #else constexpr xyze_float_t max_fr_edit = DEFAULT_MAX_FEEDRATE; - constexpr xyze_float_t max_fr_edit_scaled = max_fr_edit * 2; + const xyze_float_t max_fr_edit_scaled = max_fr_edit * 2; #endif limit_and_warn(targetValue, axis, PSTR("Feedrate"), max_fr_edit_scaled); #endif @@ -2889,7 +3027,7 @@ void Planner::set_max_jerk(const AxisEnum axis, float targetValue) { #endif } -#if HAS_SPI_LCD +#if HAS_WIRED_LCD uint16_t Planner::block_buffer_runtime() { #ifdef __AVR__ @@ -2898,7 +3036,7 @@ void Planner::set_max_jerk(const AxisEnum axis, float targetValue) { const bool was_enabled = stepper.suspend(); #endif - millis_t bbru = block_buffer_runtime_us; + uint32_t bbru = block_buffer_runtime_us; #ifdef __AVR__ // Reenable Stepper ISR @@ -2910,7 +3048,7 @@ void Planner::set_max_jerk(const AxisEnum axis, float targetValue) { // Doesn't matter because block_buffer_runtime_us is already too small an estimation. bbru >>= 10; // limit to about a minute. - NOMORE(bbru, 0xFFFFul); + NOMORE(bbru, 0x0000FFFFUL); return bbru; } @@ -2933,10 +3071,30 @@ void Planner::set_max_jerk(const AxisEnum axis, float targetValue) { #if ENABLED(AUTOTEMP) +void Planner::autotemp_update() { + #if ENABLED(AUTOTEMP_PROPORTIONAL) + const int16_t target = thermalManager.degTargetHotend(active_extruder); + autotemp_min = target + AUTOTEMP_MIN_P; + autotemp_max = target + AUTOTEMP_MAX_P; + #endif + autotemp_factor = TERN(AUTOTEMP_PROPORTIONAL, AUTOTEMP_FACTOR_P, 0); + autotemp_enabled = autotemp_factor != 0; +} + void Planner::autotemp_M104_M109() { - if ((autotemp_enabled = parser.seen('F'))) autotemp_factor = parser.value_float(); - if (parser.seen('S')) autotemp_min = parser.value_celsius(); - if (parser.seen('B')) autotemp_max = parser.value_celsius(); - } + #if ENABLED(AUTOTEMP_PROPORTIONAL) + const int16_t target = thermalManager.degTargetHotend(active_extruder); + autotemp_min = target + AUTOTEMP_MIN_P; + autotemp_max = target + AUTOTEMP_MAX_P; + #endif + + if (parser.seenval('S')) autotemp_min = parser.value_celsius(); + if (parser.seenval('B')) autotemp_max = parser.value_celsius(); + + // When AUTOTEMP_PROPORTIONAL is enabled, F0 disables autotemp. + // Normally, leaving off F also disables autotemp. + autotemp_factor = parser.seen('F') ? parser.value_float() : TERN(AUTOTEMP_PROPORTIONAL, AUTOTEMP_FACTOR_P, 0); + autotemp_enabled = autotemp_factor != 0; + } #endif diff --git a/Marlin/src/module/planner.h b/Marlin/src/module/planner.h index 6942ec602876..c4e11490b161 100644 --- a/Marlin/src/module/planner.h +++ b/Marlin/src/module/planner.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -32,6 +32,17 @@ #include "../MarlinCore.h" +#if ENABLED(JD_HANDLE_SMALL_SEGMENTS) + // Enable this option for perfect accuracy but maximum + // computation. Should be fine on ARM processors. + //#define JD_USE_MATH_ACOS + + // Disable this option to save 120 bytes of PROGMEM, + // but incur increased computation and a reduction + // in accuracy. + #define JD_USE_LOOKUP_TABLE +#endif + #include "motion.h" #include "../gcode/queue.h" @@ -52,7 +63,14 @@ #endif #if HAS_CUTTER - #include "../feature/spindle_laser.h" + #include "../feature/spindle_laser_types.h" +#endif + +#if ENABLED(DIRECT_STEPPING) + #include "../feature/direct_stepping.h" + #define IS_PAGE(B) TEST(B->flag, BLOCK_BIT_IS_PAGE) +#else + #define IS_PAGE(B) false #endif // Feedrate for manual moves @@ -61,6 +79,10 @@ manual_feedrate_mm_s { _mf.x / 60.0f, _mf.y / 60.0f, _mf.z / 60.0f, _mf.e / 60.0f }; #endif +#if IS_KINEMATIC && HAS_JUNCTION_DEVIATION + #define HAS_DIST_MM_ARG 1 +#endif + enum BlockFlagBit : char { // Recalculate trapezoids on entry junction. For optimization. BLOCK_BIT_RECALCULATE, @@ -75,15 +97,47 @@ enum BlockFlagBit : char { // Sync the stepper counts from the block BLOCK_BIT_SYNC_POSITION + + // Direct stepping page + #if ENABLED(DIRECT_STEPPING) + , BLOCK_BIT_IS_PAGE + #endif }; enum BlockFlag : char { - BLOCK_FLAG_RECALCULATE = _BV(BLOCK_BIT_RECALCULATE), - BLOCK_FLAG_NOMINAL_LENGTH = _BV(BLOCK_BIT_NOMINAL_LENGTH), - BLOCK_FLAG_CONTINUED = _BV(BLOCK_BIT_CONTINUED), - BLOCK_FLAG_SYNC_POSITION = _BV(BLOCK_BIT_SYNC_POSITION) + BLOCK_FLAG_RECALCULATE = _BV(BLOCK_BIT_RECALCULATE) + , BLOCK_FLAG_NOMINAL_LENGTH = _BV(BLOCK_BIT_NOMINAL_LENGTH) + , BLOCK_FLAG_CONTINUED = _BV(BLOCK_BIT_CONTINUED) + , BLOCK_FLAG_SYNC_POSITION = _BV(BLOCK_BIT_SYNC_POSITION) + #if ENABLED(DIRECT_STEPPING) + , BLOCK_FLAG_IS_PAGE = _BV(BLOCK_BIT_IS_PAGE) + #endif }; +#if ENABLED(LASER_POWER_INLINE) + + typedef struct { + bool isPlanned:1; + bool isEnabled:1; + bool dir:1; + bool Reserved:6; + } power_status_t; + + typedef struct { + power_status_t status; // See planner settings for meaning + uint8_t power; // Ditto; When in trapezoid mode this is nominal power + #if ENABLED(LASER_POWER_INLINE_TRAPEZOID) + uint8_t power_entry; // Entry power for the laser + #if DISABLED(LASER_POWER_INLINE_TRAPEZOID_CONT) + uint8_t power_exit; // Exit power for the laser + uint32_t entry_per, // Steps per power increment (to avoid floats in stepper calcs) + exit_per; // Steps per power decrement + #endif + #endif + } block_laser_t; + +#endif + /** * struct block_t * @@ -110,15 +164,13 @@ typedef struct block_t { }; uint32_t step_event_count; // The number of step events required to complete this block - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER uint8_t extruder; // The extruder to move (if E move) #else static constexpr uint8_t extruder = 0; #endif - #if ENABLED(MIXING_EXTRUDER) - MIXER_BLOCK_FIELD; // Normalized color for the mixing steppers - #endif + TERN_(MIXING_EXTRUDER, MIXER_BLOCK_FIELD); // Normalized color for the mixing steppers // Settings for the trapezoid generator uint32_t accelerate_until, // The index of the step event on which to stop acceleration @@ -150,11 +202,15 @@ typedef struct block_t { final_rate, // The minimal rate at exit acceleration_steps_per_s2; // acceleration steps/sec^2 + #if ENABLED(DIRECT_STEPPING) + page_idx_t page_idx; // Page index used for direct stepping + #endif + #if HAS_CUTTER cutter_power_t cutter_power; // Power level for Spindle, Laser, etc. #endif - #if FAN_COUNT > 0 + #if HAS_FAN uint8_t fan_speed[FAN_COUNT]; #endif @@ -162,7 +218,7 @@ typedef struct block_t { uint8_t valve_pressure, e_to_p_pressure; #endif - #if HAS_SPI_LCD + #if HAS_WIRED_LCD uint32_t segment_time_us; #endif @@ -170,12 +226,35 @@ typedef struct block_t { uint32_t sdpos; #endif + #if ENABLED(LASER_POWER_INLINE) + block_laser_t laser; + #endif + } block_t; -#define HAS_POSITION_FLOAT ANY(LIN_ADVANCE, SCARA_FEEDRATE_SCALING, GRADIENT_MIX, LCD_SHOW_E_TOTAL) +#if ANY(LIN_ADVANCE, SCARA_FEEDRATE_SCALING, GRADIENT_MIX, LCD_SHOW_E_TOTAL) + #define HAS_POSITION_FLOAT 1 +#endif #define BLOCK_MOD(n) ((n)&(BLOCK_BUFFER_SIZE-1)) +#if ENABLED(LASER_POWER_INLINE) + typedef struct { + /** + * Laser status flags + */ + power_status_t status; + /** + * Laser power: 0 or 255 in case of PWM-less laser, + * or the OCR (oscillator count register) value; + * + * Using OCR instead of raw power, because it avoids + * floating point operations during the move loop. + */ + uint8_t power; + } laser_state_t; +#endif + typedef struct { uint32_t max_acceleration_mm_per_s2[XYZE_N], // (mm/s^2) M201 XYZE min_segment_time_us; // (µs) M205 B @@ -237,6 +316,11 @@ class Planner { static uint8_t last_extruder; // Respond to extruder change #endif + #if ENABLED(DIRECT_STEPPING) + static uint32_t last_page_step_rate; // Last page step rate given + static xyze_bool_t last_page_dir; // Last page direction given + #endif + #if EXTRUDERS static int16_t flow_percentage[EXTRUDERS]; // Extrusion factor for each extruder static float e_factor[EXTRUDERS]; // The flow percentage and volumetric multiplier combine to scale E movement @@ -249,28 +333,30 @@ class Planner { // May be auto-adjusted by a filament width sensor #endif + #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) + static float volumetric_extruder_limit[EXTRUDERS], // Maximum mm^3/sec the extruder can handle + volumetric_extruder_feedrate_limit[EXTRUDERS]; // Feedrate limit (mm/s) calculated from volume limit + #endif + static planner_settings_t settings; + #if ENABLED(LASER_POWER_INLINE) + static laser_state_t laser_inline; + #endif + static uint32_t max_acceleration_steps_per_s2[XYZE_N]; // (steps/s^2) Derived from mm_per_s2 static float steps_to_mm[XYZE_N]; // Millimeters per step - #if DISABLED(CLASSIC_JERK) + #if HAS_JUNCTION_DEVIATION static float junction_deviation_mm; // (mm) M205 J - #if ENABLED(LIN_ADVANCE) - static float max_e_jerk // Calculated from junction_deviation_mm - #if ENABLED(DISTINCT_E_FACTORS) - [EXTRUDERS] - #endif - ; + #if HAS_LINEAR_E_JERK + static float max_e_jerk[DISTINCT_E]; // Calculated from junction_deviation_mm #endif #endif #if HAS_CLASSIC_JERK - #if HAS_LINEAR_E_JERK - static xyz_pos_t max_jerk; // (mm/s^2) M205 XYZ - The largest speed change requiring no acceleration. - #else - static xyze_pos_t max_jerk; // (mm/s^2) M205 XYZE - The largest speed change requiring no acceleration. - #endif + // (mm/s^2) M205 XYZ(E) - The largest speed change requiring no acceleration. + static TERN(HAS_LINEAR_E_JERK, xyz_pos_t, xyze_pos_t) max_jerk; #endif #if HAS_LEVELING @@ -289,6 +375,12 @@ class Planner { static float extruder_advance_K[EXTRUDERS]; #endif + /** + * The current position of the tool in absolute steps + * Recalculated if any axis_steps_per_mm are changed by gcode + */ + static xyze_long_t position; + #if HAS_POSITION_FLOAT static xyze_pos_t position_float; #endif @@ -302,15 +394,26 @@ class Planner { #if ENABLED(SD_ABORT_ON_ENDSTOP_HIT) static bool abort_on_endstop_hit; #endif + #ifdef XY_FREQUENCY_LIMIT + static int8_t xy_freq_limit_hz; // Minimum XY frequency setting + static float xy_freq_min_speed_factor; // Minimum speed factor setting + static int32_t xy_freq_min_interval_us; // Minimum segment time based on xy_freq_limit_hz + static inline void refresh_frequency_limit() { + //xy_freq_min_interval_us = xy_freq_limit_hz ?: LROUND(1000000.0f / xy_freq_limit_hz); + if (xy_freq_limit_hz) + xy_freq_min_interval_us = LROUND(1000000.0f / xy_freq_limit_hz); + } + static inline void set_min_speed_factor_u8(const uint8_t v255) { + xy_freq_min_speed_factor = float(ui8_to_percent(v255)) / 100; + } + static inline void set_frequency_limit(const uint8_t hz) { + xy_freq_limit_hz = constrain(hz, 0, 100); + refresh_frequency_limit(); + } + #endif private: - /** - * The current position of the tool in absolute steps - * Recalculated if any axis_steps_per_mm are changed by gcode - */ - static xyze_long_t position; - /** * Speed of previous path line segment */ @@ -331,23 +434,12 @@ class Planner { #endif #if ENABLED(DISABLE_INACTIVE_EXTRUDER) - /** - * Counters to manage disabling inactive extruders - */ + // Counters to manage disabling inactive extruders static uint8_t g_uc_extruder_last_move[EXTRUDERS]; - #endif // DISABLE_INACTIVE_EXTRUDER - - #ifdef XY_FREQUENCY_LIMIT - // Used for the frequency limit - #define MAX_FREQ_TIME_US (uint32_t)(1000000.0 / XY_FREQUENCY_LIMIT) - // Old direction bits. Used for speed calculations - static unsigned char old_direction_bits; - // Segment times (in µs). Used for speed calculations - static xy_ulong_t axis_segment_time_us[3]; #endif - #if HAS_SPI_LCD - volatile static uint32_t block_buffer_runtime_us; //Theoretical block buffer runtime in µs + #if HAS_WIRED_LCD + volatile static uint32_t block_buffer_runtime_us; // Theoretical block buffer runtime in µs #endif public: @@ -373,20 +465,19 @@ class Planner { #if EXTRUDERS FORCE_INLINE static void refresh_e_factor(const uint8_t e) { - e_factor[e] = (flow_percentage[e] * 0.01f - #if DISABLED(NO_VOLUMETRICS) - * volumetric_multiplier[e] - #endif - ); + e_factor[e] = flow_percentage[e] * 0.01f * TERN(NO_VOLUMETRICS, 1.0f, volumetric_multiplier[e]); + } + + static inline void set_flow(const uint8_t e, const int16_t flow) { + flow_percentage[e] = flow; + refresh_e_factor(e); } + #endif // Manage fans, paste pressure, etc. static void check_axes_activity(); - // Update multipliers based on new diameter measurements - static void calculate_volumetric_multipliers(); - #if ENABLED(FILAMENT_WIDTH_SENSOR) void apply_filament_width_sensor(const int8_t encoded_ratio); @@ -400,15 +491,32 @@ class Planner { #if DISABLED(NO_VOLUMETRICS) + // Update multipliers based on new diameter measurements + static void calculate_volumetric_multipliers(); + + #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) + // Update pre calculated extruder feedrate limits based on volumetric values + static void calculate_volumetric_extruder_limit(const uint8_t e); + static void calculate_volumetric_extruder_limits(); + #endif + FORCE_INLINE static void set_filament_size(const uint8_t e, const float &v) { filament_size[e] = v; + if (v > 0) volumetric_area_nominal = CIRCLE_AREA(v * 0.5); //TODO: should it be per extruder // make sure all extruders have some sane value for the filament size - for (uint8_t i = 0; i < COUNT(filament_size); i++) + LOOP_L_N(i, COUNT(filament_size)) if (!filament_size[i]) filament_size[i] = DEFAULT_NOMINAL_FILAMENT_DIA; } #endif + #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) + FORCE_INLINE static void set_volumetric_extruder_limit(const uint8_t e, const float &v) { + volumetric_extruder_limit[e] = v; + calculate_volumetric_extruder_limit(e); + } + #endif + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) /** @@ -487,6 +595,9 @@ class Planner { unapply_leveling(raw); leveling_active = false; } + #else + FORCE_INLINE static void apply_leveling(xyz_pos_t&) {} + FORCE_INLINE static void unapply_leveling(xyz_pos_t&) {} #endif #if ENABLED(FWRETRACT) @@ -497,46 +608,16 @@ class Planner { #endif #if HAS_POSITION_MODIFIERS - FORCE_INLINE static void apply_modifiers(xyze_pos_t &pos - #if HAS_LEVELING - , bool leveling = - #if PLANNER_LEVELING - true - #else - false - #endif - #endif - ) { - #if ENABLED(SKEW_CORRECTION) - skew(pos); - #endif - #if HAS_LEVELING - if (leveling) apply_leveling(pos); - #endif - #if ENABLED(FWRETRACT) - apply_retract(pos); - #endif + FORCE_INLINE static void apply_modifiers(xyze_pos_t &pos, bool leveling=ENABLED(PLANNER_LEVELING)) { + TERN_(SKEW_CORRECTION, skew(pos)); + if (leveling) apply_leveling(pos); + TERN_(FWRETRACT, apply_retract(pos)); } - FORCE_INLINE static void unapply_modifiers(xyze_pos_t &pos - #if HAS_LEVELING - , bool leveling = - #if PLANNER_LEVELING - true - #else - false - #endif - #endif - ) { - #if ENABLED(FWRETRACT) - unapply_retract(pos); - #endif - #if HAS_LEVELING - if (leveling) unapply_leveling(pos); - #endif - #if ENABLED(SKEW_CORRECTION) - unskew(pos); - #endif + FORCE_INLINE static void unapply_modifiers(xyze_pos_t &pos, bool leveling=ENABLED(PLANNER_LEVELING)) { + TERN_(FWRETRACT, unapply_retract(pos)); + if (leveling) unapply_leveling(pos); + TERN_(SKEW_CORRECTION, unskew(pos)); } #endif // HAS_POSITION_MODIFIERS @@ -588,8 +669,8 @@ class Planner { #if HAS_POSITION_FLOAT , const xyze_pos_t &target_float #endif - #if IS_KINEMATIC && DISABLED(CLASSIC_JERK) - , const xyze_float_t &delta_mm_cart + #if HAS_DIST_MM_ARG + , const xyze_float_t &cart_dist_mm #endif , feedRate_t fr_mm_s, const uint8_t extruder, const float &millimeters=0.0 ); @@ -611,8 +692,8 @@ class Planner { #if HAS_POSITION_FLOAT , const xyze_pos_t &target_float #endif - #if IS_KINEMATIC && DISABLED(CLASSIC_JERK) - , const xyze_float_t &delta_mm_cart + #if HAS_DIST_MM_ARG + , const xyze_float_t &cart_dist_mm #endif , feedRate_t fr_mm_s, const uint8_t extruder, const float &millimeters=0.0 ); @@ -643,21 +724,21 @@ class Planner { * millimeters - the length of the movement, if known */ static bool buffer_segment(const float &a, const float &b, const float &c, const float &e - #if IS_KINEMATIC && DISABLED(CLASSIC_JERK) - , const xyze_float_t &delta_mm_cart + #if HAS_DIST_MM_ARG + , const xyze_float_t &cart_dist_mm #endif , const feedRate_t &fr_mm_s, const uint8_t extruder, const float &millimeters=0.0 ); FORCE_INLINE static bool buffer_segment(abce_pos_t &abce - #if IS_KINEMATIC && DISABLED(CLASSIC_JERK) - , const xyze_float_t &delta_mm_cart + #if HAS_DIST_MM_ARG + , const xyze_float_t &cart_dist_mm #endif , const feedRate_t &fr_mm_s, const uint8_t extruder, const float &millimeters=0.0 ) { return buffer_segment(abce.a, abce.b, abce.c, abce.e - #if IS_KINEMATIC && DISABLED(CLASSIC_JERK) - , delta_mm_cart + #if HAS_DIST_MM_ARG + , cart_dist_mm #endif , fr_mm_s, extruder, millimeters); } @@ -693,6 +774,10 @@ class Planner { ); } + #if ENABLED(DIRECT_STEPPING) + static void buffer_page(const page_idx_t page_idx, const uint8_t extruder, const uint16_t num_steps); + #endif + /** * Set the planner.position and individual stepper positions. * Used by G92, G28, G29, and other procedures. @@ -725,6 +810,16 @@ class Planner { */ static float get_axis_position_mm(const AxisEnum axis); + static inline abce_pos_t get_axis_positions_mm() { + const abce_pos_t out = { + get_axis_position_mm(A_AXIS), + get_axis_position_mm(B_AXIS), + get_axis_position_mm(C_AXIS), + get_axis_position_mm(E_AXIS) + }; + return out; + } + // SCARA AB axes are in degrees, not mm #if IS_SCARA FORCE_INLINE static float get_axis_position_degrees(const AxisEnum axis) { return get_axis_position_mm(axis); } @@ -749,12 +844,7 @@ class Planner { // Periodic tick to handle cleaning timeouts // Called from the Temperature ISR at ~1kHz static void tick() { - if (cleaning_buffer_counter) { - --cleaning_buffer_counter; - #if ENABLED(SD_FINISHED_STEPPERRELEASE) && defined(SD_FINISHED_RELEASECOMMAND) - if (!cleaning_buffer_counter) queue.inject_P(PSTR(SD_FINISHED_RELEASECOMMAND)); - #endif - } + if (cleaning_buffer_counter) --cleaning_buffer_counter; } /** @@ -773,15 +863,15 @@ class Planner { static block_t* get_current_block(); /** - * "Discard" the block and "release" the memory. + * "Release" the current block so its slot can be reused. * Called when the current block is no longer needed. */ - FORCE_INLINE static void discard_current_block() { + FORCE_INLINE static void release_current_block() { if (has_blocks_queued()) block_buffer_tail = next_block_index(block_buffer_tail); } - #if HAS_SPI_LCD + #if HAS_WIRED_LCD static uint16_t block_buffer_runtime(); static void clear_block_buffer_runtime(); #endif @@ -791,17 +881,14 @@ class Planner { static bool autotemp_enabled; static void getHighESpeed(); static void autotemp_M104_M109(); + static void autotemp_update(); #endif #if HAS_LINEAR_E_JERK FORCE_INLINE static void recalculate_max_e_jerk() { - #define GET_MAX_E_JERK(N) SQRT(SQRT(0.5) * junction_deviation_mm * (N) * RECIPROCAL(1.0 - SQRT(0.5))) - #if ENABLED(DISTINCT_E_FACTORS) - for (uint8_t i = 0; i < EXTRUDERS; i++) - max_e_jerk[i] = GET_MAX_E_JERK(settings.max_acceleration_mm_per_s2[E_AXIS_N(i)]); - #else - max_e_jerk = GET_MAX_E_JERK(settings.max_acceleration_mm_per_s2[E_AXIS]); - #endif + const float prop = junction_deviation_mm * SQRT(0.5) / (1.0f - SQRT(0.5)); + LOOP_L_N(i, EXTRUDERS) + max_e_jerk[E_INDEX_N(i)] = SQRT(prop * settings.max_acceleration_mm_per_s2[E_INDEX_N(i)]); } #endif @@ -865,7 +952,7 @@ class Planner { static void recalculate(); - #if DISABLED(CLASSIC_JERK) + #if HAS_JUNCTION_DEVIATION FORCE_INLINE static void normalize_junction_vector(xyze_float_t &vector) { float magnitude_sq = 0; @@ -875,8 +962,12 @@ class Planner { FORCE_INLINE static float limit_value_by_axis_maximum(const float &max_value, xyze_float_t &unit_vec) { float limit_value = max_value; - LOOP_XYZE(idx) if (unit_vec[idx]) // Avoid divide by zero - NOMORE(limit_value, ABS(settings.max_acceleration_mm_per_s2[idx] / unit_vec[idx])); + LOOP_XYZE(idx) { + if (unit_vec[idx]) { + if (limit_value * ABS(unit_vec[idx]) > settings.max_acceleration_mm_per_s2[idx]) + limit_value = ABS(settings.max_acceleration_mm_per_s2[idx] / unit_vec[idx]); + } + } return limit_value; } diff --git a/Marlin/src/module/planner_bezier.cpp b/Marlin/src/module/planner_bezier.cpp index 7ea3956436a0..02d878d5f51a 100644 --- a/Marlin/src/module/planner_bezier.cpp +++ b/Marlin/src/module/planner_bezier.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -24,7 +24,6 @@ * planner_bezier.cpp * * Compute and buffer movement commands for bezier curves - * */ #include "../inc/MarlinConfig.h" @@ -36,7 +35,6 @@ #include "temperature.h" #include "../MarlinCore.h" -#include "../core/language.h" #include "../gcode/queue.h" // See the meaning in the documentation of cubic_b_spline(). diff --git a/Marlin/src/module/planner_bezier.h b/Marlin/src/module/planner_bezier.h index e7ef4719e1b0..72048c42739a 100644 --- a/Marlin/src/module/planner_bezier.h +++ b/Marlin/src/module/planner_bezier.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,6 @@ * planner_bezier.h * * Compute and buffer movement commands for Bézier curves - * */ #include "../core/types.h" diff --git a/Marlin/src/module/printcounter.cpp b/Marlin/src/module/printcounter.cpp index 3fa09c8834ec..86aedf2161a9 100644 --- a/Marlin/src/module/printcounter.cpp +++ b/Marlin/src/module/printcounter.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -30,12 +30,12 @@ Stopwatch print_job_timer; // Global Print Job Timer instance #else // PRINTCOUNTER #if ENABLED(EXTENSIBLE_UI) - #include "../lcd/extensible_ui/ui_api.h" + #include "../lcd/extui/ui_api.h" #endif #include "printcounter.h" #include "../MarlinCore.h" -#include "../HAL/shared/persistent_store_api.h" +#include "../HAL/shared/eeprom_api.h" #if HAS_BUZZER && SERVICE_WARNING_BUZZES > 0 #include "../libs/buzzer.h" @@ -70,19 +70,14 @@ millis_t PrintCounter::lastDuration; bool PrintCounter::loaded = false; millis_t PrintCounter::deltaDuration() { - #if ENABLED(DEBUG_PRINTCOUNTER) - debug(PSTR("deltaDuration")); - #endif - + TERN_(DEBUG_PRINTCOUNTER, debug(PSTR("deltaDuration"))); millis_t tmp = lastDuration; lastDuration = duration(); return lastDuration - tmp; } void PrintCounter::incFilamentUsed(float const &amount) { - #if ENABLED(DEBUG_PRINTCOUNTER) - debug(PSTR("incFilamentUsed")); - #endif + TERN_(DEBUG_PRINTCOUNTER, debug(PSTR("incFilamentUsed"))); // Refuses to update data if object is not loaded if (!isLoaded()) return; @@ -91,9 +86,7 @@ void PrintCounter::incFilamentUsed(float const &amount) { } void PrintCounter::initStats() { - #if ENABLED(DEBUG_PRINTCOUNTER) - debug(PSTR("initStats")); - #endif + TERN_(DEBUG_PRINTCOUNTER, debug(PSTR("initStats"))); loaded = true; data = { 0, 0, 0, 0, 0.0 @@ -129,9 +122,7 @@ void PrintCounter::initStats() { #endif void PrintCounter::loadStats() { - #if ENABLED(DEBUG_PRINTCOUNTER) - debug(PSTR("loadStats")); - #endif + TERN_(DEBUG_PRINTCOUNTER, debug(PSTR("loadStats"))); // Check if the EEPROM block is initialized uint8_t value = 0; @@ -164,9 +155,7 @@ void PrintCounter::loadStats() { } void PrintCounter::saveStats() { - #if ENABLED(DEBUG_PRINTCOUNTER) - debug(PSTR("saveStats")); - #endif + TERN_(DEBUG_PRINTCOUNTER, debug(PSTR("saveStats"))); // Refuses to save data if object is not loaded if (!isLoaded()) return; @@ -176,9 +165,7 @@ void PrintCounter::saveStats() { persistentStore.write_data(address + sizeof(uint8_t), (uint8_t*)&data, sizeof(printStatistics)); persistentStore.access_finish(); - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onConfigurationStoreWritten(true); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onConfigurationStoreWritten(true)); } #if HAS_SERVICE_INTERVALS @@ -239,9 +226,7 @@ void PrintCounter::tick() { static uint32_t update_next; // = 0 if (ELAPSED(now, update_next)) { - #if ENABLED(DEBUG_PRINTCOUNTER) - debug(PSTR("tick")); - #endif + TERN_(DEBUG_PRINTCOUNTER, debug(PSTR("tick"))); millis_t delta = deltaDuration(); data.printTime += delta; @@ -267,9 +252,7 @@ void PrintCounter::tick() { // @Override bool PrintCounter::start() { - #if ENABLED(DEBUG_PRINTCOUNTER) - debug(PSTR("start")); - #endif + TERN_(DEBUG_PRINTCOUNTER, debug(PSTR("start"))); bool paused = isPaused(); @@ -286,9 +269,7 @@ bool PrintCounter::start() { // @Override bool PrintCounter::stop() { - #if ENABLED(DEBUG_PRINTCOUNTER) - debug(PSTR("stop")); - #endif + TERN_(DEBUG_PRINTCOUNTER, debug(PSTR("stop"))); if (super::stop()) { data.finishedPrints++; @@ -305,9 +286,7 @@ bool PrintCounter::stop() { // @Override void PrintCounter::reset() { - #if ENABLED(DEBUG_PRINTCOUNTER) - debug(PSTR("stop")); - #endif + TERN_(DEBUG_PRINTCOUNTER, debug(PSTR("stop"))); super::reset(); lastDuration = 0; diff --git a/Marlin/src/module/printcounter.h b/Marlin/src/module/printcounter.h index 1630de988dde..66d8cbb7b38e 100644 --- a/Marlin/src/module/printcounter.h +++ b/Marlin/src/module/printcounter.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -28,12 +28,8 @@ // Print debug messages with M111 S2 //#define DEBUG_PRINTCOUNTER -#if EITHER(I2C_EEPROM, SPI_EEPROM) - // round up address to next page boundary (assuming 32 byte pages) - #define STATS_EEPROM_ADDRESS 0x40 -#else - #define STATS_EEPROM_ADDRESS 0x32 -#endif +// Round up I2C / SPI address to next page boundary (assuming 32 byte pages) +#define STATS_EEPROM_ADDRESS TERN(USE_WIRED_EEPROM, 0x40, 0x32) struct printStatistics { // 16 bytes //const uint8_t magic; // Magic header, it will always be 0x16 @@ -57,7 +53,7 @@ class PrintCounter: public Stopwatch { private: typedef Stopwatch super; - #if EITHER(I2C_EEPROM, SPI_EEPROM) || defined(CPU_32_BIT) + #if EITHER(USE_WIRED_EEPROM, CPU_32_BIT) typedef uint32_t eeprom_address_t; #else typedef uint16_t eeprom_address_t; diff --git a/Marlin/src/module/probe.cpp b/Marlin/src/module/probe.cpp index 858dcae747ac..192c6ed26e61 100644 --- a/Marlin/src/module/probe.cpp +++ b/Marlin/src/module/probe.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -78,7 +78,7 @@ #endif #if ENABLED(EXTENSIBLE_UI) - #include "../lcd/extensible_ui/ui_api.h" + #include "../lcd/extui/ui_api.h" #endif #define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) @@ -89,7 +89,7 @@ Probe probe; xyz_pos_t Probe::offset; // Initialized by settings.load() #if HAS_PROBE_XY_OFFSET - const xyz_pos_t &Probe::offset_xy = probe.offset; + const xyz_pos_t &Probe::offset_xy = Probe::offset; #endif #if ENABLED(Z_PROBE_SLED) @@ -134,12 +134,8 @@ xyz_pos_t Probe::offset; // Initialized by settings.load() LCD_MESSAGEPGM(MSG_MANUAL_DEPLOY_TOUCHMI); ui.return_to_status(); - KEEPALIVE_STATE(PAUSED_FOR_USER); - wait_for_user = true; // LCD click or M108 will clear this - #if ENABLED(HOST_PROMPT_SUPPORT) - host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Deploy TouchMI probe."), CONTINUE_STR); - #endif - while (wait_for_user) idle(); + TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Deploy TouchMI"), CONTINUE_STR)); + wait_for_user_response(); ui.reset_status(); ui.goto_screen(prev_screen); @@ -242,26 +238,32 @@ xyz_pos_t Probe::offset; // Initialized by settings.load() #if QUIET_PROBING - void Probe::set_probing_paused(const bool p) { - #if ENABLED(PROBING_HEATERS_OFF) - thermalManager.pause(p); - #endif - #if ENABLED(PROBING_FANS_OFF) - thermalManager.set_fans_paused(p); - #endif + #ifndef DELAY_BEFORE_PROBING + #define DELAY_BEFORE_PROBING 25 + #endif + + void Probe::set_probing_paused(const bool dopause) { + TERN_(PROBING_HEATERS_OFF, thermalManager.pause(dopause)); + TERN_(PROBING_FANS_OFF, thermalManager.set_fans_paused(dopause)); #if ENABLED(PROBING_STEPPERS_OFF) - disable_e_steppers(); - #if NONE(DELTA, HOME_AFTER_DEACTIVATE) - DISABLE_AXIS_X(); DISABLE_AXIS_Y(); - #endif + IF_DISABLED(DELTA, static uint8_t old_known); + if (dopause) { + #if DISABLED(DELTA) + old_known = axis_known_position; + DISABLE_AXIS_X(); + DISABLE_AXIS_Y(); + #endif + disable_e_steppers(); + } + else { + #if DISABLED(DELTA) + if (TEST(old_known, X_AXIS)) ENABLE_AXIS_X(); + if (TEST(old_known, Y_AXIS)) ENABLE_AXIS_Y(); + #endif + axis_known_position = old_trusted; + } #endif - if (p) safe_delay( - #if DELAY_BEFORE_PROBING > 25 - DELAY_BEFORE_PROBING - #else - 25 - #endif - ); + if (dopause) safe_delay(_MAX(DELAY_BEFORE_PROBING, 25)); } #endif // QUIET_PROBING @@ -270,22 +272,23 @@ xyz_pos_t Probe::offset; // Initialized by settings.load() * Raise Z to a minimum height to make room for a probe to move */ void Probe::do_z_raise(const float z_raise) { - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Probe::move_z(", z_raise, ")"); - + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Probe::do_z_raise(", z_raise, ")"); float z_dest = z_raise; if (offset.z < 0) z_dest -= offset.z; - - NOMORE(z_dest, Z_MAX_POS); - - if (z_dest > current_position.z) - do_blocking_move_to_z(z_dest); + do_z_clearance(z_dest); } FORCE_INLINE void probe_specific_action(const bool deploy) { #if ENABLED(PAUSE_BEFORE_DEPLOY_STOW) do { #if ENABLED(PAUSE_PROBE_DEPLOY_WHEN_TRIGGERED) - if (deploy == (READ(Z_MIN_PROBE_PIN) == Z_MIN_PROBE_ENDSTOP_INVERTING)) break; + if (deploy == ( + #if HAS_CUSTOM_PROBE_PIN + READ(Z_MIN_PROBE_PIN) == Z_MIN_PROBE_ENDSTOP_INVERTING + #else + READ(Z_MIN_PIN) == Z_MIN_ENDSTOP_INVERTING + #endif + )) break; #endif BUZZ(100, 659); @@ -297,24 +300,13 @@ FORCE_INLINE void probe_specific_action(const bool deploy) { serialprintPGM(ds_str); SERIAL_EOL(); - KEEPALIVE_STATE(PAUSED_FOR_USER); - wait_for_user = true; - #if ENABLED(HOST_PROMPT_SUPPORT) - host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Stow Probe"), CONTINUE_STR); - #endif - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onUserConfirmRequired_P(PSTR("Stow Probe")); - #endif - while (wait_for_user) idle(); + TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Stow Probe"), CONTINUE_STR)); + TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(PSTR("Stow Probe"))); + + wait_for_user_response(); ui.reset_status(); - } while( - #if ENABLED(PAUSE_PROBE_DEPLOY_WHEN_TRIGGERED) - true - #else - false - #endif - ); + } while (ENABLED(PAUSE_PROBE_DEPLOY_WHEN_TRIGGERED)); #endif // PAUSE_BEFORE_DEPLOY_STOW @@ -328,15 +320,13 @@ FORCE_INLINE void probe_specific_action(const bool deploy) { dock_sled(!deploy); + #elif ENABLED(BLTOUCH) + + deploy ? bltouch.deploy() : bltouch.stow(); + #elif HAS_Z_SERVO_PROBE - #if DISABLED(BLTOUCH) - MOVE_SERVO(Z_PROBE_SERVO_NR, servo_angles[Z_PROBE_SERVO_NR][deploy ? 0 : 1]); - #elif ENABLED(BLTOUCH_HS_MODE) - // In HIGH SPEED MODE, use the normal retractable probe logic in this code - // i.e. no intermediate STOWs and DEPLOYs in between individual probe actions - if (deploy) bltouch.deploy(); else bltouch.stow(); - #endif + MOVE_SERVO(Z_PROBE_SERVO_NR, servo_angles[Z_PROBE_SERVO_NR][deploy ? 0 : 1]); #elif EITHER(TOUCH_MI_PROBE, Z_PROBE_ALLEN_KEY) @@ -387,11 +377,7 @@ bool Probe::set_deployed(const bool deploy) { do_z_raise(_MAX(Z_CLEARANCE_BETWEEN_PROBES, Z_CLEARANCE_DEPLOY_PROBE)); #if EITHER(Z_PROBE_SLED, Z_PROBE_ALLEN_KEY) - if (axis_unhomed_error( - #if ENABLED(Z_PROBE_SLED) - _BV(X_AXIS) - #endif - )) { + if (homing_needed_error(TERN_(Z_PROBE_SLED, _BV(X_AXIS)))) { SERIAL_ERROR_MSG(STR_STOP_UNHOMED); stop(); return true; @@ -437,16 +423,6 @@ bool Probe::set_deployed(const bool deploy) { return false; } -#ifdef Z_AFTER_PROBING - // After probing move to a preferred Z position - void Probe::move_z_after_probing() { - if (current_position.z != Z_AFTER_PROBING) { - do_blocking_move_to_z(Z_AFTER_PROBING); - current_position.z = Z_AFTER_PROBING; - } - } -#endif - /** * @brief Used by run_z_probe to do a single Z probe move. * @@ -455,10 +431,6 @@ bool Probe::set_deployed(const bool deploy) { * @return true to indicate an error */ -#if HAS_BED_PROBE && HAS_HEATED_BED && ENABLED(WAIT_FOR_BED_HEATER) - const char Probe::msg_wait_for_bed_heating[25] PROGMEM = "Wait for bed heating...\n"; -#endif - /** * @brief Move down until the probe triggers or the low limit is reached * @@ -470,16 +442,10 @@ bool Probe::set_deployed(const bool deploy) { * @return TRUE if the probe failed to trigger. */ bool Probe::probe_down_to_z(const float z, const feedRate_t fr_mm_s) { - if (DEBUGGING(LEVELING)) DEBUG_POS(">>> Probe::probe_down_to_z", current_position); - - #if HAS_HEATED_BED && ENABLED(WAIT_FOR_BED_HEATER) - // Wait for bed to heat back up between probing points - if (thermalManager.isHeatingBed()) { - serialprintPGM(msg_wait_for_bed_heating); - LCD_MESSAGEPGM(MSG_BED_HEATING); - thermalManager.wait_for_bed(); - ui.reset_status(); - } + DEBUG_SECTION(log_probe, "Probe::probe_down_to_z", DEBUGGING(LEVELING)); + + #if BOTH(HAS_HEATED_BED, WAIT_FOR_BED_HEATER) + thermalManager.wait_for_bed_heating(); #endif #if ENABLED(BLTOUCH) && DISABLED(BLTOUCH_HS_MODE) @@ -497,9 +463,7 @@ bool Probe::probe_down_to_z(const float z, const feedRate_t fr_mm_s) { endstops.enable(true); #endif - #if QUIET_PROBING - set_probing_paused(true); - #endif + TERN_(QUIET_PROBING, set_probing_paused(true)); // Move down until the probe is triggered do_blocking_move_to_z(z, fr_mm_s); @@ -509,19 +473,11 @@ bool Probe::probe_down_to_z(const float z, const feedRate_t fr_mm_s) { #if BOTH(DELTA, SENSORLESS_PROBING) endstops.trigger_state() & (_BV(X_MIN) | _BV(Y_MIN) | _BV(Z_MIN)) #else - TEST(endstops.trigger_state(), - #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) - Z_MIN - #else - Z_MIN_PROBE - #endif - ) + TEST(endstops.trigger_state(), TERN(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN, Z_MIN, Z_MIN_PROBE)) #endif ; - #if QUIET_PROBING - set_probing_paused(false); - #endif + TERN_(QUIET_PROBING, set_probing_paused(false)); // Re-enable stealthChop if used. Disable diag1 pin on driver. #if ENABLED(SENSORLESS_PROBING) @@ -546,8 +502,6 @@ bool Probe::probe_down_to_z(const float z, const feedRate_t fr_mm_s) { // Tell the planner where we actually are sync_plan_position(); - if (DEBUGGING(LEVELING)) DEBUG_POS("<<< Probe::probe_down_to_z", current_position); - return !probe_triggered; } @@ -560,8 +514,25 @@ bool Probe::probe_down_to_z(const float z, const feedRate_t fr_mm_s) { * @return The Z position of the bed at the current XY or NAN on error. */ float Probe::run_z_probe(const bool sanity_check/*=true*/) { + DEBUG_SECTION(log_probe, "Probe::run_z_probe", DEBUGGING(LEVELING)); - if (DEBUGGING(LEVELING)) DEBUG_POS(">>> Probe::run_z_probe", current_position); + auto try_to_probe = [&](PGM_P const plbl, const float &z_probe_low_point, const feedRate_t fr_mm_s, const bool scheck, const float clearance) { + // Do a first probe at the fast speed + const bool probe_fail = probe_down_to_z(z_probe_low_point, fr_mm_s), // No probe trigger? + early_fail = (scheck && current_position.z > -offset.z + clearance); // Probe triggered too high? + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING) && (probe_fail || early_fail)) { + DEBUG_PRINT_P(plbl); + DEBUG_ECHOPGM(" Probe fail! -"); + if (probe_fail) DEBUG_ECHOPGM(" No trigger."); + if (early_fail) DEBUG_ECHOPGM(" Triggered early."); + DEBUG_EOL(); + } + #else + UNUSED(plbl); + #endif + return probe_fail || early_fail; + }; // Stop the probe before it goes too low to prevent damage. // If Z isn't known then probe to -10mm. @@ -571,15 +542,8 @@ float Probe::run_z_probe(const bool sanity_check/*=true*/) { #if TOTAL_PROBING == 2 // Do a first probe at the fast speed - if (probe_down_to_z(z_probe_low_point, MMM_TO_MMS(Z_PROBE_SPEED_FAST)) // No probe trigger? - || (sanity_check && current_position.z > -offset.z + _MAX(Z_CLEARANCE_BETWEEN_PROBES, 4) / 2) // Probe triggered too high? - ) { - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOLNPGM("FAST Probe fail!"); - DEBUG_POS("<<< run_z_probe", current_position); - } - return NAN; - } + if (try_to_probe(PSTR("FAST"), z_probe_low_point, MMM_TO_MMS(Z_PROBE_SPEED_FAST), + sanity_check, Z_CLEARANCE_BETWEEN_PROBES) ) return NAN; const float first_probe_z = current_position.z; @@ -600,14 +564,14 @@ float Probe::run_z_probe(const bool sanity_check/*=true*/) { } #endif - #ifdef EXTRA_PROBING + #if EXTRA_PROBING > 0 float probes[TOTAL_PROBING]; #endif #if TOTAL_PROBING > 2 float probes_z_sum = 0; for ( - #if EXTRA_PROBING + #if EXTRA_PROBING > 0 uint8_t p = 0; p < TOTAL_PROBING; p++ #else uint8_t p = TOTAL_PROBING; p--; @@ -616,25 +580,16 @@ float Probe::run_z_probe(const bool sanity_check/*=true*/) { #endif { // Probe downward slowly to find the bed - if (probe_down_to_z(z_probe_low_point, MMM_TO_MMS(Z_PROBE_SPEED_SLOW)) // No probe trigger? - || (sanity_check && current_position.z > -offset.z + _MAX(Z_CLEARANCE_MULTI_PROBE, 4) / 2) // Probe triggered too high? - ) { - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOLNPGM("SLOW Probe fail!"); - DEBUG_POS("<<< run_z_probe", current_position); - } - return NAN; - } + if (try_to_probe(PSTR("SLOW"), z_probe_low_point, MMM_TO_MMS(Z_PROBE_SPEED_SLOW), + sanity_check, Z_CLEARANCE_MULTI_PROBE) ) return NAN; - #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING) - backlash.measure_with_probe(); - #endif + TERN_(MEASURE_BACKLASH_WHEN_PROBING, backlash.measure_with_probe()); const float z = current_position.z; - #if EXTRA_PROBING + #if EXTRA_PROBING > 0 // Insert Z measurement into probes[]. Keep it sorted ascending. - for (uint8_t i = 0; i <= p; i++) { // Iterate the saved Zs to insert the new Z + LOOP_LE_N(i, p) { // Iterate the saved Zs to insert the new Z if (i == p || probes[i] > z) { // Last index or new Z is smaller than this Z for (int8_t m = p; --m >= i;) probes[m + 1] = probes[m]; // Shift items down after the insertion point probes[i] = z; // Insert the new Z measurement @@ -650,7 +605,7 @@ float Probe::run_z_probe(const bool sanity_check/*=true*/) { #if TOTAL_PROBING > 2 // Small Z raise after all but the last probe if (p - #if EXTRA_PROBING + #if EXTRA_PROBING > 0 < TOTAL_PROBING - 1 #endif ) do_blocking_move_to_z(z + Z_CLEARANCE_MULTI_PROBE, MMM_TO_MMS(Z_PROBE_SPEED_FAST)); @@ -659,7 +614,7 @@ float Probe::run_z_probe(const bool sanity_check/*=true*/) { #if TOTAL_PROBING > 2 - #if EXTRA_PROBING + #if EXTRA_PROBING > 0 // Take the center value (or average the two middle values) as the median static constexpr int PHALF = (TOTAL_PROBING - 1) / 2; const float middle = probes[PHALF], @@ -672,7 +627,7 @@ float Probe::run_z_probe(const bool sanity_check/*=true*/) { max_avg_idx--; else min_avg_idx++; // Return the average value of all remaining probes. - for (uint8_t i = min_avg_idx; i <= max_avg_idx; i++) + LOOP_S_LE_N(i, min_avg_idx, max_avg_idx) probes_z_sum += probes[i]; #endif @@ -695,8 +650,6 @@ float Probe::run_z_probe(const bool sanity_check/*=true*/) { #endif - if (DEBUGGING(LEVELING)) DEBUG_POS("<<< run_z_probe", current_position); - return measured_z; } @@ -710,9 +663,11 @@ float Probe::run_z_probe(const bool sanity_check/*=true*/) { * - Return the probed Z position */ float Probe::probe_at_point(const float &rx, const float &ry, const ProbePtRaise raise_after/*=PROBE_PT_NONE*/, const uint8_t verbose_level/*=0*/, const bool probe_relative/*=true*/, const bool sanity_check/*=true*/) { + DEBUG_SECTION(log_probe, "Probe::probe_at_point", DEBUGGING(LEVELING)); + if (DEBUGGING(LEVELING)) { DEBUG_ECHOLNPAIR( - ">>> Probe::probe_at_point(", LOGICAL_X_POSITION(rx), ", ", LOGICAL_Y_POSITION(ry), + "...(", LOGICAL_X_POSITION(rx), ", ", LOGICAL_Y_POSITION(ry), ", ", raise_after == PROBE_PT_RAISE ? "raise" : raise_after == PROBE_PT_STOW ? "stow" : "none", ", ", int(verbose_level), ", ", probe_relative ? "probe" : "nozzle", "_relative)" @@ -727,7 +682,7 @@ float Probe::probe_at_point(const float &rx, const float &ry, const ProbePtRaise // TODO: Adapt for SCARA, where the offset rotates xyz_pos_t npos = { rx, ry }; if (probe_relative) { // The given position is in terms of the probe - if (!position_is_reachable_by_probe(npos)) { + if (!can_reach(npos)) { if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Position Not Reachable"); return NAN; } @@ -759,11 +714,8 @@ float Probe::probe_at_point(const float &rx, const float &ry, const ProbePtRaise else if (raise_after == PROBE_PT_STOW) if (stow()) measured_z = NAN; // Error on stow? - if (verbose_level > 2) { - SERIAL_ECHOPAIR_F("Bed X: ", LOGICAL_X_POSITION(rx), 3); - SERIAL_ECHOPAIR_F( " Y: ", LOGICAL_Y_POSITION(ry), 3); - SERIAL_ECHOLNPAIR_F( " Z: ", measured_z, 3); - } + if (verbose_level > 2) + SERIAL_ECHOLNPAIR("Bed X: ", LOGICAL_X_POSITION(rx), " Y: ", LOGICAL_Y_POSITION(ry), " Z: ", measured_z); } feedrate_mm_s = old_feedrate_mm_s; @@ -771,11 +723,11 @@ float Probe::probe_at_point(const float &rx, const float &ry, const ProbePtRaise if (isnan(measured_z)) { stow(); LCD_MESSAGEPGM(MSG_LCD_PROBING_FAILED); - SERIAL_ERROR_MSG(STR_ERR_PROBING_FAILED); + #if DISABLED(G29_RETRY_AND_RECOVER) + SERIAL_ERROR_MSG(STR_ERR_PROBING_FAILED); + #endif } - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("<<< Probe::probe_at_point"); - return measured_z; } @@ -789,7 +741,6 @@ float Probe::probe_at_point(const float &rx, const float &ry, const ProbePtRaise * when starting up the machine or rebooting the board. * There's no way to know where the nozzle is positioned until * homing has been done - no homing with z-probe without init! - * */ STOW_Z_SERVO(); } diff --git a/Marlin/src/module/probe.h b/Marlin/src/module/probe.h index 6f17090e69c0..f0f56ec19199 100644 --- a/Marlin/src/module/probe.h +++ b/Marlin/src/module/probe.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -27,6 +27,8 @@ #include "../inc/MarlinConfig.h" +#include "motion.h" + #if HAS_BED_PROBE enum ProbePtRaise : uint8_t { PROBE_PT_NONE, // No raise or stow after run_z_probe @@ -45,16 +47,47 @@ class Probe { static bool set_deployed(const bool deploy); - #ifdef Z_AFTER_PROBING - static void move_z_after_probing(); + #if IS_KINEMATIC + + #if HAS_PROBE_XY_OFFSET + // Return true if the both nozzle and the probe can reach the given point. + // Note: This won't work on SCARA since the probe offset rotates with the arm. + static inline bool can_reach(const float &rx, const float &ry) { + return position_is_reachable(rx - offset_xy.x, ry - offset_xy.y) // The nozzle can go where it needs to go? + && position_is_reachable(rx, ry, ABS(PROBING_MARGIN)); // Can the nozzle also go near there? + } + #else + FORCE_INLINE static bool can_reach(const float &rx, const float &ry) { + return position_is_reachable(rx, ry, PROBING_MARGIN); + } + #endif + + #else + + /** + * Return whether the given position is within the bed, and whether the nozzle + * can reach the position required to put the probe at the given position. + * + * Example: For a probe offset of -10,+10, then for the probe to reach 0,0 the + * nozzle must be be able to reach +10,-10. + */ + static inline bool can_reach(const float &rx, const float &ry) { + return position_is_reachable(rx - offset_xy.x, ry - offset_xy.y) + && WITHIN(rx, min_x() - fslop, max_x() + fslop) + && WITHIN(ry, min_y() - fslop, max_y() + fslop); + } + #endif + + static inline void move_z_after_probing() { + #ifdef Z_AFTER_PROBING + do_z_clearance(Z_AFTER_PROBING, true, true, true); // Move down still permitted + #endif + } static float probe_at_point(const float &rx, const float &ry, const ProbePtRaise raise_after=PROBE_PT_NONE, const uint8_t verbose_level=0, const bool probe_relative=true, const bool sanity_check=true); static inline float probe_at_point(const xy_pos_t &pos, const ProbePtRaise raise_after=PROBE_PT_NONE, const uint8_t verbose_level=0, const bool probe_relative=true, const bool sanity_check=true) { - return probe_at_point(pos.x, pos.y, raise_after, verbose_level, probe_relative); + return probe_at_point(pos.x, pos.y, raise_after, verbose_level, probe_relative, sanity_check); } - #if HAS_HEATED_BED && ENABLED(WAIT_FOR_BED_HEATER) - static const char msg_wait_for_bed_heating[25]; - #endif #else @@ -62,8 +95,30 @@ class Probe { static bool set_deployed(const bool) { return false; } + FORCE_INLINE static bool can_reach(const float &rx, const float &ry) { return position_is_reachable(rx, ry); } + #endif + static inline void move_z_after_homing() { + #ifdef Z_AFTER_HOMING + do_z_clearance(Z_AFTER_HOMING, true, true, true); + #elif BOTH(Z_AFTER_PROBING,HAS_BED_PROBE) + move_z_after_probing(); + #endif + } + + FORCE_INLINE static bool can_reach(const xy_pos_t &pos) { return can_reach(pos.x, pos.y); } + + FORCE_INLINE static bool good_bounds(const xy_pos_t &lf, const xy_pos_t &rb) { + return ( + #if IS_KINEMATIC + can_reach(lf.x, 0) && can_reach(rb.x, 0) && can_reach(0, lf.y) && can_reach(0, rb.y) + #else + can_reach(lf) && can_reach(rb) + #endif + ); + } + // Use offset_xy for read only access // More optimal the XY offset is known to always be zero. #if HAS_PROBE_XY_OFFSET @@ -86,7 +141,7 @@ class Probe { ); static inline float probe_radius() { - return printable_radius - _MAX(MIN_PROBE_EDGE, HYPOT(offset_xy.x, offset_xy.y)); + return printable_radius - _MAX(PROBING_MARGIN, HYPOT(offset_xy.x, offset_xy.y)); } #endif @@ -95,7 +150,7 @@ class Probe { #if IS_KINEMATIC (X_CENTER) - probe_radius() #else - _MAX((X_MIN_BED) + (MIN_PROBE_EDGE_LEFT), (X_MIN_POS) + offset_xy.x) + _MAX((X_MIN_BED) + (PROBING_MARGIN_LEFT), (X_MIN_POS) + offset_xy.x) #endif ); } @@ -104,7 +159,7 @@ class Probe { #if IS_KINEMATIC (X_CENTER) + probe_radius() #else - _MIN((X_MAX_BED) - (MIN_PROBE_EDGE_RIGHT), (X_MAX_POS) + offset_xy.x) + _MIN((X_MAX_BED) - (PROBING_MARGIN_RIGHT), (X_MAX_POS) + offset_xy.x) #endif ); } @@ -113,7 +168,7 @@ class Probe { #if IS_KINEMATIC (Y_CENTER) - probe_radius() #else - _MAX((Y_MIN_BED) + (MIN_PROBE_EDGE_FRONT), (Y_MIN_POS) + offset_xy.y) + _MAX((Y_MIN_BED) + (PROBING_MARGIN_FRONT), (Y_MIN_POS) + offset_xy.y) #endif ); } @@ -122,7 +177,7 @@ class Probe { #if IS_KINEMATIC (Y_CENTER) + probe_radius() #else - _MIN((Y_MAX_BED) - (MIN_PROBE_EDGE_BACK), (Y_MAX_POS) + offset_xy.y) + _MIN((Y_MAX_BED) - (PROBING_MARGIN_BACK), (Y_MAX_POS) + offset_xy.y) #endif ); } @@ -131,7 +186,7 @@ class Probe { // Retrieve three points to probe the bed. Any type exposing set(X,Y) may be used. template static inline void get_three_points(T points[3]) { - #if ENABLED(HAS_FIXED_3POINT) + #if HAS_FIXED_3POINT points[0].set(PROBE_PT_1_X, PROBE_PT_1_Y); points[1].set(PROBE_PT_2_X, PROBE_PT_2_Y); points[2].set(PROBE_PT_3_X, PROBE_PT_3_Y); @@ -145,7 +200,7 @@ class Probe { #else points[0].set(min_x(), min_y()); points[1].set(max_x(), min_y()); - points[2].set((max_x() - min_x()) / 2, max_y()); + points[2].set((min_x() + max_x()) / 2, max_y()); #endif #endif } diff --git a/Marlin/src/module/scara.cpp b/Marlin/src/module/scara.cpp index f7eb8d192b93..e4b2f0b75c51 100644 --- a/Marlin/src/module/scara.cpp +++ b/Marlin/src/module/scara.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -53,11 +53,13 @@ void scara_set_axis_is_at_home(const AxisEnum axis) { current_position[axis] = cartes[axis]; #else // MP_SCARA uses a Cartesian XY home position - // SERIAL_ECHOLNPAIR("homeposition X:", homeposition.x, " Y:", homeposition.y); + // SERIAL_ECHOPGM("homeposition"); + // SERIAL_ECHOLNPAIR_P(SP_X_LBL, homeposition.x, SP_Y_LBL, homeposition.y); current_position[axis] = homeposition[axis]; #endif - // SERIAL_ECHOLNPAIR("Cartesian X:", current_position.x, " Y:", current_position.y); + // SERIAL_ECHOPGM("Cartesian"); + // SERIAL_ECHOLNPAIR_P(SP_X_LBL, current_position.x, SP_Y_LBL, current_position.y); update_software_endstops(axis); } } @@ -98,7 +100,7 @@ void inverse_kinematics(const xyz_pos_t &raw) { /** * Morgan SCARA Inverse Kinematics. Results in 'delta'. * - * See http://forums.reprap.org/read.php?185,283327 + * See https://reprap.org/forum/read.php?185,283327 * * Maths and first version by QHARLEY. * Integrated into Marlin and slightly restructured by Joachim Cerny. diff --git a/Marlin/src/module/scara.h b/Marlin/src/module/scara.h index 2f60ebbf1579..e2acaf30822c 100644 --- a/Marlin/src/module/scara.h +++ b/Marlin/src/module/scara.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/module/servo.cpp b/Marlin/src/module/servo.cpp index c49f939d0ff4..27e5a2af2e03 100644 --- a/Marlin/src/module/servo.cpp +++ b/Marlin/src/module/servo.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -32,9 +32,7 @@ HAL_SERVO_LIB servo[NUM_SERVOS]; -#if ENABLED(EDITABLE_SERVO_ANGLES) - uint16_t servo_angles[NUM_SERVOS][2]; -#endif +TERN_(EDITABLE_SERVO_ANGLES, uint16_t servo_angles[NUM_SERVOS][2]); void servo_init() { #if NUM_SERVOS >= 1 && HAS_SERVO_0 diff --git a/Marlin/src/module/servo.h b/Marlin/src/module/servo.h index 335ce698e012..29bd3b8798d4 100644 --- a/Marlin/src/module/servo.h +++ b/Marlin/src/module/servo.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/module/configuration_store.cpp b/Marlin/src/module/settings.cpp similarity index 77% rename from Marlin/src/module/configuration_store.cpp rename to Marlin/src/module/settings.cpp index 3fe38d4ade8f..33e5c351abc1 100644 --- a/Marlin/src/module/configuration_store.cpp +++ b/Marlin/src/module/settings.cpp @@ -16,12 +16,12 @@ * 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 . + * along with this program. If not, see . * */ /** - * configuration_store.cpp + * settings.cpp * * Settings and EEPROM storage * @@ -33,31 +33,34 @@ * ALSO: Variables in the Store and Retrieve sections must be in the same order. * If a feature is disabled, some data must still be written that, when read, * either sets a Sane Default, or results in No Change to the existing value. - * */ // Change EEPROM version if the structure changes -#define EEPROM_VERSION "V76" +#define EEPROM_VERSION "V82" #define EEPROM_OFFSET 100 // Check the integrity of data offsets. // Can be disabled for production build. //#define DEBUG_EEPROM_READWRITE -#include "configuration_store.h" +#include "settings.h" #include "endstops.h" #include "planner.h" #include "stepper.h" #include "temperature.h" + +#if ENABLED(DWIN_CREALITY_LCD) + #include "../lcd/dwin/e3v2/dwin.h" +#endif + #include "../lcd/ultralcd.h" -#include "../core/language.h" #include "../libs/vector_3.h" // for matrix_3x3 #include "../gcode/gcode.h" #include "../MarlinCore.h" #if EITHER(EEPROM_SETTINGS, SD_FIRMWARE_UPDATE) - #include "../HAL/shared/persistent_store_api.h" + #include "../HAL/shared/eeprom_api.h" #endif #include "probe.h" @@ -71,7 +74,7 @@ #endif #if ENABLED(EXTENSIBLE_UI) - #include "../lcd/extensible_ui/ui_api.h" + #include "../lcd/extui/ui_api.h" #endif #if HAS_SERVOS @@ -87,7 +90,11 @@ #include "../feature/fwretract.h" #if ENABLED(POWER_LOSS_RECOVERY) - #include "../feature/power_loss_recovery.h" + #include "../feature/powerloss.h" +#endif + +#if HAS_POWER_MONITOR + #include "../feature/power_monitor.h" #endif #include "../feature/pause.h" @@ -98,13 +105,16 @@ #if HAS_FILAMENT_SENSOR #include "../feature/runout.h" + #ifndef FIL_RUNOUT_ENABLED_DEFAULT + #define FIL_RUNOUT_ENABLED_DEFAULT true + #endif #endif #if ENABLED(EXTRA_LIN_ADVANCE_K) - extern float saved_extruder_advance_K[EXTRUDERS]; + extern float other_extruder_advance_K[EXTRUDERS]; #endif -#if EXTRUDERS > 1 +#if HAS_MULTI_EXTRUDER #include "tool_change.h" void M217_report(const bool eeprom); #endif @@ -113,24 +123,42 @@ #include "../feature/bltouch.h" #endif -#if HAS_TRINAMIC +#if HAS_TRINAMIC_CONFIG #include "stepper/indirection.h" #include "../feature/tmc_util.h" #endif #if ENABLED(PROBE_TEMP_COMPENSATION) - #include "../feature/probe_temp_compensation.h" + #include "../feature/probe_temp_comp.h" +#endif + +#include "../feature/controllerfan.h" +#if ENABLED(CONTROLLER_FAN_EDITABLE) + void M710_report(const bool forReplay); +#endif + +#if ENABLED(CASE_LIGHT_ENABLE) && DISABLED(CASE_LIGHT_NO_BRIGHTNESS) + #include "../feature/caselight.h" + #define HAS_CASE_LIGHT_BRIGHTNESS 1 +#endif + +#if ENABLED(PASSWORD_FEATURE) + #include "../feature/password/password.h" +#endif + +#if ENABLED(TOUCH_SCREEN_CALIBRATION) + #include "../lcd/tft/touch.h" #endif #pragma pack(push, 1) // No padding between variables -typedef struct { uint16_t X, Y, Z, X2, Y2, Z2, Z3, Z4, E0, E1, E2, E3, E4, E5; } tmc_stepper_current_t; -typedef struct { uint32_t X, Y, Z, X2, Y2, Z2, Z3, Z4, E0, E1, E2, E3, E4, E5; } tmc_hybrid_threshold_t; -typedef struct { int16_t X, Y, Z, X2; } tmc_sgt_t; -typedef struct { bool X, Y, Z, X2, Y2, Z2, Z3, Z4, E0, E1, E2, E3, E4, E5; } tmc_stealth_enabled_t; +typedef struct { uint16_t X, Y, Z, X2, Y2, Z2, Z3, Z4, E0, E1, E2, E3, E4, E5, E6, E7; } tmc_stepper_current_t; +typedef struct { uint32_t X, Y, Z, X2, Y2, Z2, Z3, Z4, E0, E1, E2, E3, E4, E5, E6, E7; } tmc_hybrid_threshold_t; +typedef struct { int16_t X, Y, Z, X2, Y2, Z2, Z3, Z4; } tmc_sgt_t; +typedef struct { bool X, Y, Z, X2, Y2, Z2, Z3, Z4, E0, E1, E2, E3, E4, E5, E6, E7; } tmc_stealth_enabled_t; // Limit an index to an array size -#define ALIM(I,ARR) _MIN(I, COUNT(ARR) - 1) +#define ALIM(I,ARR) _MIN(I, (signed)COUNT(ARR) - 1) // Defaults for reset / fill in on load static const uint32_t _DMA[] PROGMEM = DEFAULT_MAX_ACCELERATION; @@ -181,11 +209,8 @@ typedef struct SettingsDataStruct { // float mbl_z_offset; // mbl.z_offset uint8_t mesh_num_x, mesh_num_y; // GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y - #if ENABLED(MESH_BED_LEVELING) - float mbl_z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y]; // mbl.z_values - #else - float mbl_z_values[3][3]; - #endif + float mbl_z_values[TERN(MESH_BED_LEVELING, GRID_MAX_POINTS_X, 3)] // mbl.z_values + [TERN(MESH_BED_LEVELING, GRID_MAX_POINTS_Y, 3)]; // // HAS_BED_PROBE @@ -229,7 +254,7 @@ typedef struct SettingsDataStruct { #if ENABLED(USE_TEMP_EXT_COMPENSATION) , z_offsets_ext[COUNT(temp_comp.z_offsets_ext)] // M871 E I V #endif - ; + ; #endif // @@ -242,11 +267,12 @@ typedef struct SettingsDataStruct { // #if ENABLED(DELTA) float delta_height; // M666 H - abc_float_t delta_endstop_adj; // M666 XYZ + abc_float_t delta_endstop_adj; // M666 X Y Z float delta_radius, // M665 R delta_diagonal_rod, // M665 L delta_segments_per_second; // M665 S - abc_float_t delta_tower_angle_trim; // M665 XYZ + abc_float_t delta_tower_angle_trim, // M665 X Y Z + delta_diagonal_rod_trim; // M665 A B C #elif HAS_EXTRA_ENDSTOPS float x2_endstop_adj, // M666 X y2_endstop_adj, // M666 Y @@ -266,11 +292,11 @@ typedef struct SettingsDataStruct { #endif // - // ULTIPANEL + // Material Presets // - int16_t ui_preheat_hotend_temp[2], // M145 S0 H - ui_preheat_bed_temp[2]; // M145 S0 B - uint8_t ui_preheat_fan_speed[2]; // M145 S0 F + #if PREHEAT_COUNT + preheat_t ui_material_preset[PREHEAT_COUNT]; // M145 S0 H B F + #endif // // PIDTEMP @@ -290,11 +316,21 @@ typedef struct SettingsDataStruct { user_thermistor_t user_thermistor[USER_THERMISTORS]; // M305 P0 R4700 T100000 B3950 #endif + // + // Power monitor + // + uint8_t power_monitor_flags; // M430 I V W + // // HAS_LCD_CONTRAST // int16_t lcd_contrast; // M250 C + // + // Controller fan settings + // + controllerFan_settings_t controllerFan_settings; // M710 + // // POWER_LOSS_RECOVERY // @@ -309,15 +345,16 @@ typedef struct SettingsDataStruct { // // !NO_VOLUMETRIC // - bool parser_volumetric_enabled; // M200 D parser.volumetric_enabled + bool parser_volumetric_enabled; // M200 S parser.volumetric_enabled float planner_filament_size[EXTRUDERS]; // M200 T D planner.filament_size[] + float planner_volumetric_extruder_limit[EXTRUDERS]; // M200 T L planner.volumetric_extruder_limit[] // - // HAS_TRINAMIC + // HAS_TRINAMIC_CONFIG // tmc_stepper_current_t tmc_stepper_current; // M906 X Y Z X2 Y2 Z2 Z3 Z4 E0 E1 E2 E3 E4 E5 tmc_hybrid_threshold_t tmc_hybrid_threshold; // M913 X Y Z X2 Y2 Z2 Z3 Z4 E0 E1 E2 E3 E4 E5 - tmc_sgt_t tmc_sgt; // M914 X Y Z X2 + tmc_sgt_t tmc_sgt; // M914 X Y Z X2 Y2 Z2 Z3 Z4 tmc_stealth_enabled_t tmc_stealth_enabled; // M569 X Y Z X2 Y2 Z2 Z3 Z4 E0 E1 E2 E3 E4 E5 // @@ -328,7 +365,10 @@ typedef struct SettingsDataStruct { // // HAS_MOTOR_CURRENT_PWM // - uint32_t motor_current_setting[3]; // M907 X Z E + #ifndef MOTOR_CURRENT_COUNT + #define MOTOR_CURRENT_COUNT 3 + #endif + uint32_t motor_current_setting[MOTOR_CURRENT_COUNT]; // M907 X Z E // // CNC_COORDINATE_SYSTEMS @@ -350,7 +390,7 @@ typedef struct SettingsDataStruct { // // Tool-change settings // - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER toolchange_settings_t toolchange_settings; // M217 S P R #endif @@ -369,9 +409,31 @@ typedef struct SettingsDataStruct { uint8_t extui_data[ExtUI::eeprom_data_size]; #endif + // + // HAS_CASE_LIGHT_BRIGHTNESS + // + #if HAS_CASE_LIGHT_BRIGHTNESS + uint8_t caselight_brightness; // M355 P + #endif + + // + // PASSWORD_FEATURE + // + #if ENABLED(PASSWORD_FEATURE) + bool password_is_set; + uint32_t password_value; + #endif + + // + // TOUCH_SCREEN_CALIBRATION + // + #if ENABLED(TOUCH_SCREEN_CALIBRATION) + touch_calibration_t touch_calibration; + #endif + } SettingsData; -//static_assert(sizeof(SettingsData) <= E2END + 1, "EEPROM too small to contain SettingsData!"); +//static_assert(sizeof(SettingsData) <= MARLIN_EEPROM_SIZE, "EEPROM too small to contain SettingsData!"); MarlinSettings settings; @@ -393,13 +455,9 @@ void MarlinSettings::postprocess() { // Make sure delta kinematics are updated before refreshing the // planner position so the stepper counts will be set correctly. - #if ENABLED(DELTA) - recalc_delta_settings(); - #endif + TERN_(DELTA, recalc_delta_settings()); - #if ENABLED(PIDTEMP) - thermalManager.updatePID(); - #endif + TERN_(PIDTEMP, thermalManager.updatePID()); #if DISABLED(NO_VOLUMETRICS) planner.calculate_volumetric_multipliers(); @@ -414,25 +472,17 @@ void MarlinSettings::postprocess() { update_software_endstops((AxisEnum)i); } - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - set_z_fade_height(new_z_fade_height, false); // false = no report - #endif + TERN_(ENABLE_LEVELING_FADE_HEIGHT, set_z_fade_height(new_z_fade_height, false)); // false = no report - #if ENABLED(AUTO_BED_LEVELING_BILINEAR) - refresh_bed_level(); - #endif + TERN_(AUTO_BED_LEVELING_BILINEAR, refresh_bed_level()); - #if HAS_MOTOR_CURRENT_PWM - stepper.refresh_motor_power(); - #endif + TERN_(HAS_MOTOR_CURRENT_PWM, stepper.refresh_motor_power()); - #if ENABLED(FWRETRACT) - fwretract.refresh_autoretract(); - #endif + TERN_(FWRETRACT, fwretract.refresh_autoretract()); - #if HAS_LINEAR_E_JERK - planner.recalculate_max_e_jerk(); - #endif + TERN_(HAS_LINEAR_E_JERK, planner.recalculate_max_e_jerk()); + + TERN_(HAS_CASE_LIGHT_BRIGHTNESS, caselight.update_brightness()); // Refresh steps_to_mm with the reciprocal of axis_steps_per_mm // and init stepper.count[], planner.position[] with current_position @@ -525,7 +575,7 @@ void MarlinSettings::postprocess() { * M500 - Store Configuration */ bool MarlinSettings::save() { - float dummy = 0; + float dummyf = 0; char ver[4] = "ERR"; uint16_t working_crc = 0; @@ -533,11 +583,10 @@ void MarlinSettings::postprocess() { EEPROM_START(); eeprom_error = false; - #if ENABLED(FLASH_EEPROM_EMULATION) - EEPROM_SKIP(ver); // Flash doesn't allow rewriting without erase - #else - EEPROM_WRITE(ver); // invalidate data first - #endif + + // Write or Skip version. (Flash doesn't allow rewrite without erase.) + TERN(FLASH_EEPROM_EMULATION, EEPROM_SKIP, EEPROM_WRITE)(ver); + EEPROM_SKIP(working_crc); // Skip the checksum slot working_crc = 0; // clear before first "real data" @@ -556,20 +605,16 @@ void MarlinSettings::postprocess() { #if HAS_CLASSIC_JERK EEPROM_WRITE(planner.max_jerk); #if HAS_LINEAR_E_JERK - dummy = float(DEFAULT_EJERK); - EEPROM_WRITE(dummy); + dummyf = float(DEFAULT_EJERK); + EEPROM_WRITE(dummyf); #endif #else const xyze_pos_t planner_max_jerk = { 10, 10, 0.4, float(DEFAULT_EJERK) }; EEPROM_WRITE(planner_max_jerk); #endif - #if DISABLED(CLASSIC_JERK) - EEPROM_WRITE(planner.junction_deviation_mm); - #else - dummy = 0.02f; - EEPROM_WRITE(dummy); - #endif + TERN_(CLASSIC_JERK, dummyf = 0.02f); + EEPROM_WRITE(TERN(CLASSIC_JERK, dummyf, planner.junction_deviation_mm)); } // @@ -586,10 +631,15 @@ void MarlinSettings::postprocess() { #endif EEPROM_WRITE(home_offset); #endif + } + // + // Hotend Offsets, if any + // + { #if HAS_HOTEND_OFFSET // Skip hotend 0 which must be 0 - for (uint8_t e = 1; e < HOTENDS; e++) + LOOP_S_L_N(e, 1, HOTENDS) EEPROM_WRITE(hotend_offset[e]); #endif } @@ -601,15 +651,16 @@ void MarlinSettings::postprocess() { #if HAS_FILAMENT_SENSOR const bool &runout_sensor_enabled = runout.enabled; #else - constexpr bool runout_sensor_enabled = true; + constexpr int8_t runout_sensor_enabled = -1; #endif - #if HAS_FILAMENT_SENSOR && defined(FILAMENT_RUNOUT_DISTANCE_MM) + _FIELD_TEST(runout_sensor_enabled); + EEPROM_WRITE(runout_sensor_enabled); + + #if HAS_FILAMENT_RUNOUT_DISTANCE const float &runout_distance_mm = runout.runout_distance(); #else constexpr float runout_distance_mm = 0; #endif - _FIELD_TEST(runout_sensor_enabled); - EEPROM_WRITE(runout_sensor_enabled); EEPROM_WRITE(runout_distance_mm); } @@ -617,13 +668,7 @@ void MarlinSettings::postprocess() { // Global Leveling // { - const float zfh = ( - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - planner.z_fade_height - #else - 10.0 - #endif - ); + const float zfh = TERN(ENABLE_LEVELING_FADE_HEIGHT, planner.z_fade_height, 10.0f); EEPROM_WRITE(zfh); } @@ -632,23 +677,25 @@ void MarlinSettings::postprocess() { // { #if ENABLED(MESH_BED_LEVELING) - // Compile time test that sizeof(mbl.z_values) is as expected static_assert( sizeof(mbl.z_values) == (GRID_MAX_POINTS) * sizeof(mbl.z_values[0][0]), "MBL Z array is the wrong size." ); - const uint8_t mesh_num_x = GRID_MAX_POINTS_X, mesh_num_y = GRID_MAX_POINTS_Y; - EEPROM_WRITE(mbl.z_offset); - EEPROM_WRITE(mesh_num_x); - EEPROM_WRITE(mesh_num_y); + #else + dummyf = 0; + #endif + + const uint8_t mesh_num_x = TERN(MESH_BED_LEVELING, GRID_MAX_POINTS_X, 3), + mesh_num_y = TERN(MESH_BED_LEVELING, GRID_MAX_POINTS_Y, 3); + + EEPROM_WRITE(TERN(MESH_BED_LEVELING, mbl.z_offset, dummyf)); + EEPROM_WRITE(mesh_num_x); + EEPROM_WRITE(mesh_num_y); + + #if ENABLED(MESH_BED_LEVELING) EEPROM_WRITE(mbl.z_values); - #else // For disabled MBL write a default mesh - dummy = 0; - const uint8_t mesh_num_x = 3, mesh_num_y = 3; - EEPROM_WRITE(dummy); // z_offset - EEPROM_WRITE(mesh_num_x); - EEPROM_WRITE(mesh_num_y); - for (uint8_t q = mesh_num_x * mesh_num_y; q--;) EEPROM_WRITE(dummy); + #else + for (uint8_t q = mesh_num_x * mesh_num_y; q--;) EEPROM_WRITE(dummyf); #endif } @@ -672,8 +719,8 @@ void MarlinSettings::postprocess() { #if ABL_PLANAR EEPROM_WRITE(planner.bed_level_matrix); #else - dummy = 0; - for (uint8_t q = 9; q--;) EEPROM_WRITE(dummy); + dummyf = 0; + for (uint8_t q = 9; q--;) EEPROM_WRITE(dummyf); #endif } @@ -682,27 +729,26 @@ void MarlinSettings::postprocess() { // { #if ENABLED(AUTO_BED_LEVELING_BILINEAR) - // Compile time test that sizeof(z_values) is as expected static_assert( sizeof(z_values) == (GRID_MAX_POINTS) * sizeof(z_values[0][0]), "Bilinear Z array is the wrong size." ); - const uint8_t grid_max_x = GRID_MAX_POINTS_X, grid_max_y = GRID_MAX_POINTS_Y; - EEPROM_WRITE(grid_max_x); // 1 byte - EEPROM_WRITE(grid_max_y); // 1 byte - EEPROM_WRITE(bilinear_grid_spacing); // 2 ints - EEPROM_WRITE(bilinear_start); // 2 ints - EEPROM_WRITE(z_values); // 9-256 floats #else - // For disabled Bilinear Grid write an empty 3x3 grid - const uint8_t grid_max_x = 3, grid_max_y = 3; const xy_pos_t bilinear_start{0}, bilinear_grid_spacing{0}; - dummy = 0; - EEPROM_WRITE(grid_max_x); - EEPROM_WRITE(grid_max_y); - EEPROM_WRITE(bilinear_grid_spacing); - EEPROM_WRITE(bilinear_start); - for (uint16_t q = grid_max_x * grid_max_y; q--;) EEPROM_WRITE(dummy); + #endif + + const uint8_t grid_max_x = TERN(AUTO_BED_LEVELING_BILINEAR, GRID_MAX_POINTS_X, 3), + grid_max_y = TERN(AUTO_BED_LEVELING_BILINEAR, GRID_MAX_POINTS_Y, 3); + EEPROM_WRITE(grid_max_x); + EEPROM_WRITE(grid_max_y); + EEPROM_WRITE(bilinear_grid_spacing); + EEPROM_WRITE(bilinear_start); + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + EEPROM_WRITE(z_values); // 9-256 floats + #else + dummyf = 0; + for (uint16_t q = grid_max_x * grid_max_y; q--;) EEPROM_WRITE(dummyf); #endif } @@ -711,16 +757,10 @@ void MarlinSettings::postprocess() { // { _FIELD_TEST(planner_leveling_active); - - #if ENABLED(AUTO_BED_LEVELING_UBL) - EEPROM_WRITE(planner.leveling_active); - EEPROM_WRITE(ubl.storage_slot); - #else - const bool ubl_active = false; - const int8_t storage_slot = -1; - EEPROM_WRITE(ubl_active); - EEPROM_WRITE(storage_slot); - #endif // AUTO_BED_LEVELING_UBL + const bool ubl_active = TERN(AUTO_BED_LEVELING_UBL, planner.leveling_active, false); + const int8_t storage_slot = TERN(AUTO_BED_LEVELING_UBL, ubl.storage_slot, -1); + EEPROM_WRITE(ubl_active); + EEPROM_WRITE(storage_slot); } // @@ -728,7 +768,6 @@ void MarlinSettings::postprocess() { // { _FIELD_TEST(servo_angles); - #if !HAS_SERVO_ANGLES uint16_t servo_angles[EEPROM_NUM_SERVOS][2] = { { 0, 0 } }; #endif @@ -753,11 +792,7 @@ void MarlinSettings::postprocess() { // { _FIELD_TEST(bltouch_last_written_mode); - #if ENABLED(BLTOUCH) - const bool &bltouch_last_written_mode = bltouch.last_written_mode; - #else - constexpr bool bltouch_last_written_mode = false; - #endif + const bool bltouch_last_written_mode = TERN(BLTOUCH, bltouch.last_written_mode, false); EEPROM_WRITE(bltouch_last_written_mode); } @@ -775,41 +810,28 @@ void MarlinSettings::postprocess() { EEPROM_WRITE(delta_diagonal_rod); // 1 float EEPROM_WRITE(delta_segments_per_second); // 1 float EEPROM_WRITE(delta_tower_angle_trim); // 3 floats + EEPROM_WRITE(delta_diagonal_rod_trim); // 3 floats #elif HAS_EXTRA_ENDSTOPS _FIELD_TEST(x2_endstop_adj); // Write dual endstops in X, Y, Z order. Unused = 0.0 - dummy = 0; - #if ENABLED(X_DUAL_ENDSTOPS) - EEPROM_WRITE(endstops.x2_endstop_adj); // 1 float - #else - EEPROM_WRITE(dummy); - #endif - - #if ENABLED(Y_DUAL_ENDSTOPS) - EEPROM_WRITE(endstops.y2_endstop_adj); // 1 float - #else - EEPROM_WRITE(dummy); - #endif - - #if ENABLED(Z_MULTI_ENDSTOPS) - EEPROM_WRITE(endstops.z2_endstop_adj); // 1 float - #else - EEPROM_WRITE(dummy); - #endif + dummyf = 0; + EEPROM_WRITE(TERN(X_DUAL_ENDSTOPS, endstops.x2_endstop_adj, dummyf)); // 1 float + EEPROM_WRITE(TERN(Y_DUAL_ENDSTOPS, endstops.y2_endstop_adj, dummyf)); // 1 float + EEPROM_WRITE(TERN(Z_MULTI_ENDSTOPS, endstops.z2_endstop_adj, dummyf)); // 1 float #if ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPER_DRIVERS >= 3 EEPROM_WRITE(endstops.z3_endstop_adj); // 1 float #else - EEPROM_WRITE(dummy); + EEPROM_WRITE(dummyf); #endif #if ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPER_DRIVERS >= 4 EEPROM_WRITE(endstops.z4_endstop_adj); // 1 float #else - EEPROM_WRITE(dummy); + EEPROM_WRITE(dummyf); #endif #endif @@ -825,23 +847,10 @@ void MarlinSettings::postprocess() { // // LCD Preheat settings // - { - _FIELD_TEST(ui_preheat_hotend_temp); - - #if HOTENDS && HAS_LCD_MENU - const int16_t (&ui_preheat_hotend_temp)[2] = ui.preheat_hotend_temp, - (&ui_preheat_bed_temp)[2] = ui.preheat_bed_temp; - const uint8_t (&ui_preheat_fan_speed)[2] = ui.preheat_fan_speed; - #else - constexpr int16_t ui_preheat_hotend_temp[2] = { PREHEAT_1_TEMP_HOTEND, PREHEAT_2_TEMP_HOTEND }, - ui_preheat_bed_temp[2] = { PREHEAT_1_TEMP_BED, PREHEAT_2_TEMP_BED }; - constexpr uint8_t ui_preheat_fan_speed[2] = { PREHEAT_1_FAN_SPEED, PREHEAT_2_FAN_SPEED }; - #endif - - EEPROM_WRITE(ui_preheat_hotend_temp); - EEPROM_WRITE(ui_preheat_bed_temp); - EEPROM_WRITE(ui_preheat_fan_speed); - } + #if PREHEAT_COUNT + _FIELD_TEST(ui_material_preset); + EEPROM_WRITE(ui.material_preset); + #endif // // PIDTEMP @@ -851,8 +860,8 @@ void MarlinSettings::postprocess() { HOTEND_LOOP() { PIDCF_t pidcf = { #if DISABLED(PIDTEMP) - DUMMY_PID_VALUE, DUMMY_PID_VALUE, DUMMY_PID_VALUE, - DUMMY_PID_VALUE, DUMMY_PID_VALUE + NAN, NAN, NAN, + NAN, NAN #else PID_PARAM(Kp, e), unscalePID_i(PID_PARAM(Ki, e)), @@ -865,12 +874,10 @@ void MarlinSettings::postprocess() { } _FIELD_TEST(lpq_len); - #if ENABLED(PID_EXTRUSION_SCALING) - EEPROM_WRITE(thermalManager.lpq_len); - #else + #if DISABLED(PID_EXTRUSION_SCALING) const int16_t lpq_len = 20; - EEPROM_WRITE(lpq_len); #endif + EEPROM_WRITE(TERN(PID_EXTRUSION_SCALING, thermalManager.lpq_len, lpq_len)); } // @@ -881,7 +888,7 @@ void MarlinSettings::postprocess() { const PID_t bed_pid = { #if DISABLED(PIDTEMPBED) - DUMMY_PID_VALUE, DUMMY_PID_VALUE, DUMMY_PID_VALUE + NAN, NAN, NAN #else // Store the unscaled PID values thermalManager.temp_bed.pid.Kp, @@ -902,6 +909,19 @@ void MarlinSettings::postprocess() { } #endif + // + // Power monitor + // + { + #if HAS_POWER_MONITOR + const uint8_t &power_monitor_flags = power_monitor.flags; + #else + constexpr uint8_t power_monitor_flags = 0x00; + #endif + _FIELD_TEST(power_monitor_flags); + EEPROM_WRITE(power_monitor_flags); + } + // // LCD Contrast // @@ -911,8 +931,6 @@ void MarlinSettings::postprocess() { const int16_t lcd_contrast = #if HAS_LCD_CONTRAST ui.contrast - #elif defined(DEFAULT_LCD_CONTRAST) - DEFAULT_LCD_CONTRAST #else 127 #endif @@ -920,19 +938,25 @@ void MarlinSettings::postprocess() { EEPROM_WRITE(lcd_contrast); } + // + // Controller Fan + // + { + _FIELD_TEST(controllerFan_settings); + #if ENABLED(USE_CONTROLLER_FAN) + const controllerFan_settings_t &cfs = controllerFan.settings; + #else + controllerFan_settings_t cfs = controllerFan_defaults; + #endif + EEPROM_WRITE(cfs); + } + // // Power-Loss Recovery // { _FIELD_TEST(recovery_enabled); - - const bool recovery_enabled = - #if ENABLED(POWER_LOSS_RECOVERY) - recovery.enabled - #else - true - #endif - ; + const bool recovery_enabled = TERN(POWER_LOSS_RECOVERY, recovery.enabled, ENABLED(PLR_ENABLED_DEFAULT)); EEPROM_WRITE(recovery_enabled); } @@ -941,19 +965,15 @@ void MarlinSettings::postprocess() { // { _FIELD_TEST(fwretract_settings); - - #if ENABLED(FWRETRACT) - EEPROM_WRITE(fwretract.settings); - #else + #if DISABLED(FWRETRACT) const fwretract_settings_t autoretract_defaults = { 3, 45, 0, 0, 0, 13, 0, 8 }; - EEPROM_WRITE(autoretract_defaults); #endif - #if BOTH(FWRETRACT, FWRETRACT_AUTORETRACT) - EEPROM_WRITE(fwretract.autoretract_enabled); - #else + EEPROM_WRITE(TERN(FWRETRACT, fwretract.settings, autoretract_defaults)); + + #if DISABLED(FWRETRACT_AUTORETRACT) const bool autoretract_enabled = false; - EEPROM_WRITE(autoretract_enabled); #endif + EEPROM_WRITE(TERN(FWRETRACT_AUTORETRACT, fwretract.autoretract_enabled, autoretract_enabled)); } // @@ -966,13 +986,21 @@ void MarlinSettings::postprocess() { EEPROM_WRITE(parser.volumetric_enabled); EEPROM_WRITE(planner.filament_size); + #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) + EEPROM_WRITE(planner.volumetric_extruder_limit); + #else + dummyf = DEFAULT_VOLUMETRIC_EXTRUDER_LIMIT; + for (uint8_t q = EXTRUDERS; q--;) EEPROM_WRITE(dummyf); + #endif #else const bool volumetric_enabled = false; - dummy = DEFAULT_NOMINAL_FILAMENT_DIA; EEPROM_WRITE(volumetric_enabled); - for (uint8_t q = EXTRUDERS; q--;) EEPROM_WRITE(dummy); + dummyf = DEFAULT_NOMINAL_FILAMENT_DIA; + for (uint8_t q = EXTRUDERS; q--;) EEPROM_WRITE(dummyf); + dummyf = DEFAULT_VOLUMETRIC_EXTRUDER_LIMIT; + for (uint8_t q = EXTRUDERS; q--;) EEPROM_WRITE(dummyf); #endif } @@ -985,7 +1013,7 @@ void MarlinSettings::postprocess() { tmc_stepper_current_t tmc_stepper_current = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - #if HAS_TRINAMIC + #if HAS_TRINAMIC_CONFIG #if AXIS_IS_TMC(X) tmc_stepper_current.X = stepperX.getMilliamps(); #endif @@ -1143,18 +1171,14 @@ void MarlinSettings::postprocess() { { tmc_sgt_t tmc_sgt{0}; #if USE_SENSORLESS - #if X_SENSORLESS - tmc_sgt.X = stepperX.homing_threshold(); - #endif - #if X2_SENSORLESS - tmc_sgt.X2 = stepperX2.homing_threshold(); - #endif - #if Y_SENSORLESS - tmc_sgt.Y = stepperY.homing_threshold(); - #endif - #if Z_SENSORLESS - tmc_sgt.Z = stepperZ.homing_threshold(); - #endif + TERN_(X_SENSORLESS, tmc_sgt.X = stepperX.homing_threshold()); + TERN_(X2_SENSORLESS, tmc_sgt.X2 = stepperX2.homing_threshold()); + TERN_(Y_SENSORLESS, tmc_sgt.Y = stepperY.homing_threshold()); + TERN_(Y2_SENSORLESS, tmc_sgt.Y2 = stepperY2.homing_threshold()); + TERN_(Z_SENSORLESS, tmc_sgt.Z = stepperZ.homing_threshold()); + TERN_(Z2_SENSORLESS, tmc_sgt.Z2 = stepperZ2.homing_threshold()); + TERN_(Z3_SENSORLESS, tmc_sgt.Z3 = stepperZ3.homing_threshold()); + TERN_(Z4_SENSORLESS, tmc_sgt.Z4 = stepperZ4.homing_threshold()); #endif EEPROM_WRITE(tmc_sgt); } @@ -1169,60 +1193,60 @@ void MarlinSettings::postprocess() { #if HAS_STEALTHCHOP #if AXIS_HAS_STEALTHCHOP(X) - tmc_stealth_enabled.X = stepperX.get_stealthChop_status(); + tmc_stealth_enabled.X = stepperX.get_stored_stealthChop_status(); #endif #if AXIS_HAS_STEALTHCHOP(Y) - tmc_stealth_enabled.Y = stepperY.get_stealthChop_status(); + tmc_stealth_enabled.Y = stepperY.get_stored_stealthChop_status(); #endif #if AXIS_HAS_STEALTHCHOP(Z) - tmc_stealth_enabled.Z = stepperZ.get_stealthChop_status(); + tmc_stealth_enabled.Z = stepperZ.get_stored_stealthChop_status(); #endif #if AXIS_HAS_STEALTHCHOP(X2) - tmc_stealth_enabled.X2 = stepperX2.get_stealthChop_status(); + tmc_stealth_enabled.X2 = stepperX2.get_stored_stealthChop_status(); #endif #if AXIS_HAS_STEALTHCHOP(Y2) - tmc_stealth_enabled.Y2 = stepperY2.get_stealthChop_status(); + tmc_stealth_enabled.Y2 = stepperY2.get_stored_stealthChop_status(); #endif #if AXIS_HAS_STEALTHCHOP(Z2) - tmc_stealth_enabled.Z2 = stepperZ2.get_stealthChop_status(); + tmc_stealth_enabled.Z2 = stepperZ2.get_stored_stealthChop_status(); #endif #if AXIS_HAS_STEALTHCHOP(Z3) - tmc_stealth_enabled.Z3 = stepperZ3.get_stealthChop_status(); + tmc_stealth_enabled.Z3 = stepperZ3.get_stored_stealthChop_status(); #endif #if AXIS_HAS_STEALTHCHOP(Z4) - tmc_stealth_enabled.Z4 = stepperZ4.get_stealthChop_status(); + tmc_stealth_enabled.Z4 = stepperZ4.get_stored_stealthChop_status(); #endif #if MAX_EXTRUDERS #if AXIS_HAS_STEALTHCHOP(E0) - tmc_stealth_enabled.E0 = stepperE0.get_stealthChop_status(); + tmc_stealth_enabled.E0 = stepperE0.get_stored_stealthChop_status(); #endif #if MAX_EXTRUDERS > 1 #if AXIS_HAS_STEALTHCHOP(E1) - tmc_stealth_enabled.E1 = stepperE1.get_stealthChop_status(); + tmc_stealth_enabled.E1 = stepperE1.get_stored_stealthChop_status(); #endif #if MAX_EXTRUDERS > 2 #if AXIS_HAS_STEALTHCHOP(E2) - tmc_stealth_enabled.E2 = stepperE2.get_stealthChop_status(); + tmc_stealth_enabled.E2 = stepperE2.get_stored_stealthChop_status(); #endif #if MAX_EXTRUDERS > 3 #if AXIS_HAS_STEALTHCHOP(E3) - tmc_stealth_enabled.E3 = stepperE3.get_stealthChop_status(); + tmc_stealth_enabled.E3 = stepperE3.get_stored_stealthChop_status(); #endif #if MAX_EXTRUDERS > 4 #if AXIS_HAS_STEALTHCHOP(E4) - tmc_stealth_enabled.E4 = stepperE4.get_stealthChop_status(); + tmc_stealth_enabled.E4 = stepperE4.get_stored_stealthChop_status(); #endif #if MAX_EXTRUDERS > 5 #if AXIS_HAS_STEALTHCHOP(E5) - tmc_stealth_enabled.E5 = stepperE5.get_stealthChop_status(); + tmc_stealth_enabled.E5 = stepperE5.get_stored_stealthChop_status(); #endif #if MAX_EXTRUDERS > 6 #if AXIS_HAS_STEALTHCHOP(E6) - tmc_stealth_enabled.E6 = stepperE6.get_stealthChop_status(); + tmc_stealth_enabled.E6 = stepperE6.get_stored_stealthChop_status(); #endif #if MAX_EXTRUDERS > 7 #if AXIS_HAS_STEALTHCHOP(E7) - tmc_stealth_enabled.E7 = stepperE7.get_stealthChop_status(); + tmc_stealth_enabled.E7 = stepperE7.get_stored_stealthChop_status(); #endif #endif // MAX_EXTRUDERS > 7 #endif // MAX_EXTRUDERS > 6 @@ -1245,8 +1269,8 @@ void MarlinSettings::postprocess() { #if ENABLED(LIN_ADVANCE) EEPROM_WRITE(planner.extruder_advance_K); #else - dummy = 0; - for (uint8_t q = _MAX(EXTRUDERS, 1); q--;) EEPROM_WRITE(dummy); + dummyf = 0; + for (uint8_t q = _MAX(EXTRUDERS, 1); q--;) EEPROM_WRITE(dummyf); #endif } @@ -1256,10 +1280,10 @@ void MarlinSettings::postprocess() { { _FIELD_TEST(motor_current_setting); - #if HAS_MOTOR_CURRENT_PWM + #if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM EEPROM_WRITE(stepper.motor_current_setting); #else - const xyz_ulong_t no_current{0}; + const uint32_t no_current[MOTOR_CURRENT_COUNT] = { 0 }; EEPROM_WRITE(no_current); #endif } @@ -1270,12 +1294,10 @@ void MarlinSettings::postprocess() { _FIELD_TEST(coordinate_system); - #if ENABLED(CNC_COORDINATE_SYSTEMS) - EEPROM_WRITE(gcode.coordinate_system); - #else + #if DISABLED(CNC_COORDINATE_SYSTEMS) const xyz_pos_t coordinate_system[MAX_COORDINATE_SYSTEMS] = { { 0 } }; - EEPROM_WRITE(coordinate_system); #endif + EEPROM_WRITE(TERN(CNC_COORDINATE_SYSTEMS, gcode.coordinate_system, coordinate_system)); // // Skew correction factors @@ -1300,7 +1322,7 @@ void MarlinSettings::postprocess() { // Multiple Extruders // - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER _FIELD_TEST(toolchange_settings); EEPROM_WRITE(toolchange_settings); #endif @@ -1339,6 +1361,28 @@ void MarlinSettings::postprocess() { } #endif + // + // Case Light Brightness + // + #if HAS_CASE_LIGHT_BRIGHTNESS + EEPROM_WRITE(caselight.brightness); + #endif + + // + // Password feature + // + #if ENABLED(PASSWORD_FEATURE) + EEPROM_WRITE(password.is_set); + EEPROM_WRITE(password.value); + #endif + + // + // TOUCH_SCREEN_CALIBRATION + // + #if ENABLED(TOUCH_SCREEN_CALIBRATION) + EEPROM_WRITE(touch.calibration); + #endif + // // Validate CRC and Data Size // @@ -1368,9 +1412,9 @@ void MarlinSettings::postprocess() { store_mesh(ubl.storage_slot); #endif - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onConfigurationStoreWritten(!eeprom_error); - #endif + if (!eeprom_error) LCD_MESSAGEPGM(MSG_SETTINGS_STORED); + + TERN_(EXTENSIBLE_UI, ExtUI::onConfigurationStoreWritten(!eeprom_error)); return !eeprom_error; } @@ -1397,13 +1441,11 @@ void MarlinSettings::postprocess() { } DEBUG_ECHO_START(); DEBUG_ECHOLNPAIR("EEPROM version mismatch (EEPROM=", stored_ver, " Marlin=" EEPROM_VERSION ")"); - #if HAS_LCD_MENU && DISABLED(EEPROM_AUTO_INIT) - ui.set_status_P(GET_TEXT(MSG_ERR_EEPROM_VERSION)); - #endif + TERN(EEPROM_AUTO_INIT,,ui.eeprom_alert_version()); eeprom_error = true; } else { - float dummy = 0; + float dummyf = 0; working_crc = 0; // Init to 0. Accumulated by EEPROM_READ _FIELD_TEST(esteppers); @@ -1442,17 +1484,13 @@ void MarlinSettings::postprocess() { #if HAS_CLASSIC_JERK EEPROM_READ(planner.max_jerk); #if HAS_LINEAR_E_JERK - EEPROM_READ(dummy); + EEPROM_READ(dummyf); #endif #else - for (uint8_t q = 4; q--;) EEPROM_READ(dummy); + for (uint8_t q = 4; q--;) EEPROM_READ(dummyf); #endif - #if DISABLED(CLASSIC_JERK) - EEPROM_READ(planner.junction_deviation_mm); - #else - EEPROM_READ(dummy); - #endif + EEPROM_READ(TERN(CLASSIC_JERK, dummyf, planner.junction_deviation_mm)); } // @@ -1477,7 +1515,7 @@ void MarlinSettings::postprocess() { { #if HAS_HOTEND_OFFSET // Skip hotend 0 which must be 0 - for (uint8_t e = 1; e < HOTENDS; e++) + LOOP_S_L_N(e, 1, HOTENDS) EEPROM_READ(hotend_offset[e]); #endif } @@ -1486,17 +1524,18 @@ void MarlinSettings::postprocess() { // Filament Runout Sensor // { - #if HAS_FILAMENT_SENSOR - const bool &runout_sensor_enabled = runout.enabled; - #else - bool runout_sensor_enabled; - #endif + int8_t runout_sensor_enabled; _FIELD_TEST(runout_sensor_enabled); EEPROM_READ(runout_sensor_enabled); + #if HAS_FILAMENT_SENSOR + runout.enabled = runout_sensor_enabled < 0 ? FIL_RUNOUT_ENABLED_DEFAULT : runout_sensor_enabled; + #endif + + TERN_(HAS_FILAMENT_SENSOR, if (runout.enabled) runout.reset()); float runout_distance_mm; EEPROM_READ(runout_distance_mm); - #if HAS_FILAMENT_SENSOR && defined(FILAMENT_RUNOUT_DISTANCE_MM) + #if HAS_FILAMENT_RUNOUT_DISTANCE if (!validating) runout.set_runout_distance(runout_distance_mm); #endif } @@ -1504,25 +1543,19 @@ void MarlinSettings::postprocess() { // // Global Leveling // - { - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - EEPROM_READ(new_z_fade_height); - #else - EEPROM_READ(dummy); - #endif - } + EEPROM_READ(TERN(ENABLE_LEVELING_FADE_HEIGHT, new_z_fade_height, dummyf)); // // Mesh (Manual) Bed Leveling // { uint8_t mesh_num_x, mesh_num_y; - EEPROM_READ(dummy); + EEPROM_READ(dummyf); EEPROM_READ_ALWAYS(mesh_num_x); EEPROM_READ_ALWAYS(mesh_num_y); #if ENABLED(MESH_BED_LEVELING) - if (!validating) mbl.z_offset = dummy; + if (!validating) mbl.z_offset = dummyf; if (mesh_num_x == GRID_MAX_POINTS_X && mesh_num_y == GRID_MAX_POINTS_Y) { // EEPROM data fits the current mesh EEPROM_READ(mbl.z_values); @@ -1530,11 +1563,11 @@ void MarlinSettings::postprocess() { else { // EEPROM data is stale if (!validating) mbl.reset(); - for (uint16_t q = mesh_num_x * mesh_num_y; q--;) EEPROM_READ(dummy); + for (uint16_t q = mesh_num_x * mesh_num_y; q--;) EEPROM_READ(dummyf); } #else // MBL is disabled - skip the stored data - for (uint16_t q = mesh_num_x * mesh_num_y; q--;) EEPROM_READ(dummy); + for (uint16_t q = mesh_num_x * mesh_num_y; q--;) EEPROM_READ(dummyf); #endif // MESH_BED_LEVELING } @@ -1558,7 +1591,7 @@ void MarlinSettings::postprocess() { #if ABL_PLANAR EEPROM_READ(planner.bed_level_matrix); #else - for (uint8_t q = 9; q--;) EEPROM_READ(dummy); + for (uint8_t q = 9; q--;) EEPROM_READ(dummyf); #endif } @@ -1567,8 +1600,8 @@ void MarlinSettings::postprocess() { // { uint8_t grid_max_x, grid_max_y; - EEPROM_READ_ALWAYS(grid_max_x); // 1 byte - EEPROM_READ_ALWAYS(grid_max_y); // 1 byte + EEPROM_READ_ALWAYS(grid_max_x); // 1 byte + EEPROM_READ_ALWAYS(grid_max_y); // 1 byte #if ENABLED(AUTO_BED_LEVELING_BILINEAR) if (grid_max_x == GRID_MAX_POINTS_X && grid_max_y == GRID_MAX_POINTS_Y) { if (!validating) set_bed_leveling_enabled(false); @@ -1583,7 +1616,7 @@ void MarlinSettings::postprocess() { xy_pos_t bgs, bs; EEPROM_READ(bgs); EEPROM_READ(bs); - for (uint16_t q = grid_max_x * grid_max_y; q--;) EEPROM_READ(dummy); + for (uint16_t q = grid_max_x * grid_max_y; q--;) EEPROM_READ(dummyf); } } @@ -1592,16 +1625,15 @@ void MarlinSettings::postprocess() { // { _FIELD_TEST(planner_leveling_active); - #if ENABLED(AUTO_BED_LEVELING_UBL) - EEPROM_READ(planner.leveling_active); - EEPROM_READ(ubl.storage_slot); + const bool &planner_leveling_active = planner.leveling_active; + const int8_t &ubl_storage_slot = ubl.storage_slot; #else bool planner_leveling_active; - uint8_t ubl_storage_slot; - EEPROM_READ(planner_leveling_active); - EEPROM_READ(ubl_storage_slot); + int8_t ubl_storage_slot; #endif + EEPROM_READ(planner_leveling_active); + EEPROM_READ(ubl_storage_slot); } // @@ -1609,7 +1641,6 @@ void MarlinSettings::postprocess() { // { _FIELD_TEST(servo_angles); - #if ENABLED(EDITABLE_SERVO_ANGLES) uint16_t (&servo_angles_arr)[EEPROM_NUM_SERVOS][2] = servo_angles; #else @@ -1659,35 +1690,25 @@ void MarlinSettings::postprocess() { EEPROM_READ(delta_diagonal_rod); // 1 float EEPROM_READ(delta_segments_per_second); // 1 float EEPROM_READ(delta_tower_angle_trim); // 3 floats + EEPROM_READ(delta_diagonal_rod_trim); // 3 floats #elif HAS_EXTRA_ENDSTOPS _FIELD_TEST(x2_endstop_adj); - #if ENABLED(X_DUAL_ENDSTOPS) - EEPROM_READ(endstops.x2_endstop_adj); // 1 float - #else - EEPROM_READ(dummy); - #endif - #if ENABLED(Y_DUAL_ENDSTOPS) - EEPROM_READ(endstops.y2_endstop_adj); // 1 float - #else - EEPROM_READ(dummy); - #endif - #if ENABLED(Z_MULTI_ENDSTOPS) - EEPROM_READ(endstops.z2_endstop_adj); // 1 float - #else - EEPROM_READ(dummy); - #endif + EEPROM_READ(TERN(X_DUAL_ENDSTOPS, endstops.x2_endstop_adj, dummyf)); // 1 float + EEPROM_READ(TERN(Y_DUAL_ENDSTOPS, endstops.y2_endstop_adj, dummyf)); // 1 float + EEPROM_READ(TERN(Z_MULTI_ENDSTOPS, endstops.z2_endstop_adj, dummyf)); // 1 float + #if ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPER_DRIVERS >= 3 EEPROM_READ(endstops.z3_endstop_adj); // 1 float #else - EEPROM_READ(dummy); + EEPROM_READ(dummyf); #endif #if ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPER_DRIVERS >= 4 EEPROM_READ(endstops.z4_endstop_adj); // 1 float #else - EEPROM_READ(dummy); + EEPROM_READ(dummyf); #endif #endif @@ -1703,21 +1724,10 @@ void MarlinSettings::postprocess() { // // LCD Preheat settings // - { - _FIELD_TEST(ui_preheat_hotend_temp); - - #if HOTENDS && HAS_LCD_MENU - int16_t (&ui_preheat_hotend_temp)[2] = ui.preheat_hotend_temp, - (&ui_preheat_bed_temp)[2] = ui.preheat_bed_temp; - uint8_t (&ui_preheat_fan_speed)[2] = ui.preheat_fan_speed; - #else - int16_t ui_preheat_hotend_temp[2], ui_preheat_bed_temp[2]; - uint8_t ui_preheat_fan_speed[2]; - #endif - EEPROM_READ(ui_preheat_hotend_temp); // 2 floats - EEPROM_READ(ui_preheat_bed_temp); // 2 floats - EEPROM_READ(ui_preheat_fan_speed); // 2 floats - } + #if PREHEAT_COUNT + _FIELD_TEST(ui_material_preset); + EEPROM_READ(ui.material_preset); + #endif // // Hotend PID @@ -1727,17 +1737,13 @@ void MarlinSettings::postprocess() { PIDCF_t pidcf; EEPROM_READ(pidcf); #if ENABLED(PIDTEMP) - if (!validating && pidcf.Kp != DUMMY_PID_VALUE) { + if (!validating && !isnan(pidcf.Kp)) { // Scale PID values since EEPROM values are unscaled PID_PARAM(Kp, e) = pidcf.Kp; PID_PARAM(Ki, e) = scalePID_i(pidcf.Ki); PID_PARAM(Kd, e) = scalePID_d(pidcf.Kd); - #if ENABLED(PID_EXTRUSION_SCALING) - PID_PARAM(Kc, e) = pidcf.Kc; - #endif - #if ENABLED(PID_FAN_SCALING) - PID_PARAM(Kf, e) = pidcf.Kf; - #endif + TERN_(PID_EXTRUSION_SCALING, PID_PARAM(Kc, e) = pidcf.Kc); + TERN_(PID_FAN_SCALING, PID_PARAM(Kf, e) = pidcf.Kf); } #endif } @@ -1749,11 +1755,11 @@ void MarlinSettings::postprocess() { { _FIELD_TEST(lpq_len); #if ENABLED(PID_EXTRUSION_SCALING) - EEPROM_READ(thermalManager.lpq_len); + const int16_t &lpq_len = thermalManager.lpq_len; #else int16_t lpq_len; - EEPROM_READ(lpq_len); #endif + EEPROM_READ(lpq_len); } // @@ -1763,7 +1769,7 @@ void MarlinSettings::postprocess() { PID_t pid; EEPROM_READ(pid); #if ENABLED(PIDTEMPBED) - if (!validating && pid.Kp != DUMMY_PID_VALUE) { + if (!validating && !isnan(pid.Kp)) { // Scale PID values since EEPROM values are unscaled thermalManager.temp_bed.pid.Kp = pid.Kp; thermalManager.temp_bed.pid.Ki = scalePID_i(pid.Ki); @@ -1782,17 +1788,42 @@ void MarlinSettings::postprocess() { } #endif + // + // Power monitor + // + { + #if HAS_POWER_MONITOR + uint8_t &power_monitor_flags = power_monitor.flags; + #else + uint8_t power_monitor_flags; + #endif + _FIELD_TEST(power_monitor_flags); + EEPROM_READ(power_monitor_flags); + } + // // LCD Contrast // { _FIELD_TEST(lcd_contrast); - int16_t lcd_contrast; EEPROM_READ(lcd_contrast); - #if HAS_LCD_CONTRAST - ui.set_contrast(lcd_contrast); + if (!validating) { + TERN_(HAS_LCD_CONTRAST, ui.set_contrast(lcd_contrast)); + } + } + + // + // Controller Fan + // + { + _FIELD_TEST(controllerFan_settings); + #if ENABLED(CONTROLLER_FAN_EDITABLE) + const controllerFan_settings_t &cfs = controllerFan.settings; + #else + controllerFan_settings_t cfs = { 0 }; #endif + EEPROM_READ(cfs); } // @@ -1800,13 +1831,12 @@ void MarlinSettings::postprocess() { // { _FIELD_TEST(recovery_enabled); - #if ENABLED(POWER_LOSS_RECOVERY) - EEPROM_READ(recovery.enabled); + const bool &recovery_enabled = recovery.enabled; #else bool recovery_enabled; - EEPROM_READ(recovery_enabled); #endif + EEPROM_READ(recovery_enabled); } // @@ -1836,6 +1866,7 @@ void MarlinSettings::postprocess() { struct { bool volumetric_enabled; float filament_size[EXTRUDERS]; + float volumetric_extruder_limit[EXTRUDERS]; } storage; _FIELD_TEST(parser_volumetric_enabled); @@ -1845,6 +1876,9 @@ void MarlinSettings::postprocess() { if (!validating) { parser.volumetric_enabled = storage.volumetric_enabled; COPY(planner.filament_size, storage.filament_size); + #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) + COPY(planner.volumetric_extruder_limit, storage.volumetric_extruder_limit); + #endif } #endif } @@ -1862,7 +1896,7 @@ void MarlinSettings::postprocess() { tmc_stepper_current_t currents; EEPROM_READ(currents); - #if HAS_TRINAMIC + #if HAS_TRINAMIC_CONFIG #define SET_CURR(Q) stepper##Q.rms_current(currents.Q ? currents.Q : Q##_CURRENT) if (!validating) { @@ -1980,9 +2014,6 @@ void MarlinSettings::postprocess() { // // TMC StallGuard threshold. - // X and X2 use the same value - // Y and Y2 use the same value - // Z, Z2, Z3 and Z4 use the same value // { tmc_sgt_t tmc_sgt; @@ -1990,39 +2021,14 @@ void MarlinSettings::postprocess() { EEPROM_READ(tmc_sgt); #if USE_SENSORLESS if (!validating) { - #ifdef X_STALL_SENSITIVITY - #if AXIS_HAS_STALLGUARD(X) - stepperX.homing_threshold(tmc_sgt.X); - #endif - #if AXIS_HAS_STALLGUARD(X2) && !X2_SENSORLESS - stepperX2.homing_threshold(tmc_sgt.X); - #endif - #endif - #if X2_SENSORLESS - stepperX2.homing_threshold(tmc_sgt.X2); - #endif - #ifdef Y_STALL_SENSITIVITY - #if AXIS_HAS_STALLGUARD(Y) - stepperY.homing_threshold(tmc_sgt.Y); - #endif - #if AXIS_HAS_STALLGUARD(Y2) - stepperY2.homing_threshold(tmc_sgt.Y); - #endif - #endif - #ifdef Z_STALL_SENSITIVITY - #if AXIS_HAS_STALLGUARD(Z) - stepperZ.homing_threshold(tmc_sgt.Z); - #endif - #if AXIS_HAS_STALLGUARD(Z2) - stepperZ2.homing_threshold(tmc_sgt.Z); - #endif - #if AXIS_HAS_STALLGUARD(Z3) - stepperZ3.homing_threshold(tmc_sgt.Z); - #endif - #if AXIS_HAS_STALLGUARD(Z4) - stepperZ4.homing_threshold(tmc_sgt.Z); - #endif - #endif + TERN_(X_SENSORLESS, stepperX.homing_threshold(tmc_sgt.X)); + TERN_(X2_SENSORLESS, stepperX2.homing_threshold(tmc_sgt.X2)); + TERN_(Y_SENSORLESS, stepperY.homing_threshold(tmc_sgt.Y)); + TERN_(Y2_SENSORLESS, stepperY2.homing_threshold(tmc_sgt.Y2)); + TERN_(Z_SENSORLESS, stepperZ.homing_threshold(tmc_sgt.Z)); + TERN_(Z2_SENSORLESS, stepperZ2.homing_threshold(tmc_sgt.Z2)); + TERN_(Z3_SENSORLESS, stepperZ3.homing_threshold(tmc_sgt.Z3)); + TERN_(Z4_SENSORLESS, stepperZ4.homing_threshold(tmc_sgt.Z4)); } #endif } @@ -2034,7 +2040,7 @@ void MarlinSettings::postprocess() { tmc_stealth_enabled_t tmc_stealth_enabled; EEPROM_READ(tmc_stealth_enabled); - #if HAS_TRINAMIC + #if HAS_TRINAMIC_CONFIG #define SET_STEPPING_MODE(ST) stepper##ST.stored.stealthChop_enabled = tmc_stealth_enabled.ST; stepper##ST.refresh_stepping_mode(); if (!validating) { @@ -2107,10 +2113,16 @@ void MarlinSettings::postprocess() { // Motor Current PWM // { - uint32_t motor_current_setting[3]; _FIELD_TEST(motor_current_setting); + uint32_t motor_current_setting[MOTOR_CURRENT_COUNT] + #if HAS_MOTOR_CURRENT_SPI + = DIGIPOT_MOTOR_CURRENT + #endif + ; + DEBUG_ECHOLNPGM("DIGIPOTS Loading"); EEPROM_READ(motor_current_setting); - #if HAS_MOTOR_CURRENT_PWM + DEBUG_ECHOLNPGM("DIGIPOTS Loaded"); + #if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM if (!validating) COPY(stepper.motor_current_setting, motor_current_setting); #endif @@ -2164,7 +2176,7 @@ void MarlinSettings::postprocess() { // // Tool-change settings // - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER _FIELD_TEST(toolchange_settings); EEPROM_READ(toolchange_settings); #endif @@ -2204,21 +2216,42 @@ void MarlinSettings::postprocess() { } #endif + // + // Case Light Brightness + // + #if HAS_CASE_LIGHT_BRIGHTNESS + _FIELD_TEST(caselight_brightness); + EEPROM_READ(caselight.brightness); + #endif + + // + // Password feature + // + #if ENABLED(PASSWORD_FEATURE) + _FIELD_TEST(password_is_set); + EEPROM_READ(password.is_set); + EEPROM_READ(password.value); + #endif + + // + // TOUCH_SCREEN_CALIBRATION + // + #if ENABLED(TOUCH_SCREEN_CALIBRATION) + _FIELD_TEST(touch.calibration); + EEPROM_READ(touch.calibration); + #endif + eeprom_error = size_error(eeprom_index - (EEPROM_OFFSET)); if (eeprom_error) { DEBUG_ECHO_START(); DEBUG_ECHOLNPAIR("Index: ", int(eeprom_index - (EEPROM_OFFSET)), " Size: ", datasize()); - #if HAS_LCD_MENU && DISABLED(EEPROM_AUTO_INIT) - ui.set_status_P(GET_TEXT(MSG_ERR_EEPROM_INDEX)); - #endif + TERN(EEPROM_AUTO_INIT,,ui.eeprom_alert_index()); } else if (working_crc != stored_crc) { eeprom_error = true; DEBUG_ERROR_START(); DEBUG_ECHOLNPAIR("EEPROM CRC mismatch - (stored) ", stored_crc, " != ", working_crc, " (calculated)!"); - #if HAS_LCD_MENU && DISABLED(EEPROM_AUTO_INIT) - ui.set_status_P(GET_TEXT(MSG_ERR_EEPROM_CRC)); - #endif + TERN(EEPROM_AUTO_INIT,,ui.eeprom_alert_crc()); } else if (!validating) { DEBUG_ECHO_START(); @@ -2262,8 +2295,10 @@ void MarlinSettings::postprocess() { } #if ENABLED(EEPROM_CHITCHAT) && DISABLED(DISABLE_M503) - if (!validating) report(); + // Report the EEPROM settings + if (!validating && (DISABLED(EEPROM_BOOT_SILENT) || IsRunning())) report(); #endif + EEPROM_FINISH(); return !eeprom_error; @@ -2291,9 +2326,7 @@ void MarlinSettings::postprocess() { bool MarlinSettings::load() { if (validate()) { const bool success = _load(); - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onConfigurationStoreRead(success); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onConfigurationStoreRead(success)); return success; } reset(); @@ -2435,12 +2468,10 @@ void MarlinSettings::reset() { #define DEFAULT_ZJERK 0 #endif planner.max_jerk.set(DEFAULT_XJERK, DEFAULT_YJERK, DEFAULT_ZJERK); - #if HAS_CLASSIC_E_JERK - planner.max_jerk.e = DEFAULT_EJERK; - #endif + TERN_(HAS_CLASSIC_E_JERK, planner.max_jerk.e = DEFAULT_EJERK;); #endif - #if DISABLED(CLASSIC_JERK) + #if HAS_JUNCTION_DEVIATION planner.junction_deviation_mm = float(JUNCTION_DEVIATION_MM); #endif @@ -2450,38 +2481,50 @@ void MarlinSettings::reset() { home_offset.reset(); #endif - #if HAS_HOTEND_OFFSET - reset_hotend_offsets(); - #endif + TERN_(HAS_HOTEND_OFFSET, reset_hotend_offsets()); // // Filament Runout Sensor // #if HAS_FILAMENT_SENSOR - runout.enabled = true; + runout.enabled = FIL_RUNOUT_ENABLED_DEFAULT; runout.reset(); - #ifdef FILAMENT_RUNOUT_DISTANCE_MM - runout.set_runout_distance(FILAMENT_RUNOUT_DISTANCE_MM); - #endif + TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, runout.set_runout_distance(FILAMENT_RUNOUT_DISTANCE_MM)); #endif // // Tool-change Settings // - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) - toolchange_settings.swap_length = TOOLCHANGE_FIL_SWAP_LENGTH; - toolchange_settings.extra_prime = TOOLCHANGE_FIL_EXTRA_PRIME; - toolchange_settings.prime_speed = TOOLCHANGE_FIL_SWAP_PRIME_SPEED; - toolchange_settings.retract_speed = TOOLCHANGE_FIL_SWAP_RETRACT_SPEED; + toolchange_settings.swap_length = TOOLCHANGE_FS_LENGTH; + toolchange_settings.extra_resume = TOOLCHANGE_FS_EXTRA_RESUME_LENGTH; + toolchange_settings.retract_speed = TOOLCHANGE_FS_RETRACT_SPEED; + toolchange_settings.unretract_speed = TOOLCHANGE_FS_UNRETRACT_SPEED; + toolchange_settings.extra_prime = TOOLCHANGE_FS_EXTRA_PRIME; + toolchange_settings.prime_speed = TOOLCHANGE_FS_PRIME_SPEED; + toolchange_settings.fan_speed = TOOLCHANGE_FS_FAN_SPEED; + toolchange_settings.fan_time = TOOLCHANGE_FS_FAN_TIME; #endif + + #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED) + enable_first_prime = false; + #endif + #if ENABLED(TOOLCHANGE_PARK) constexpr xyz_pos_t tpxy = TOOLCHANGE_PARK_XY; + toolchange_settings.enable_park = true; toolchange_settings.change_point = tpxy; #endif + toolchange_settings.z_raise = TOOLCHANGE_ZRAISE; + + #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) + migration = migration_defaults; + #endif + #endif #if ENABLED(BACKLASH_GCODE) @@ -2493,29 +2536,28 @@ void MarlinSettings::reset() { #endif #endif - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onFactoryReset(); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onFactoryReset()); // - // Magnetic Parking Extruder + // Case Light Brightness // - - #if ENABLED(MAGNETIC_PARKING_EXTRUDER) - mpe_settings_init(); - #endif + TERN_(HAS_CASE_LIGHT_BRIGHTNESS, caselight.brightness = CASE_LIGHT_DEFAULT_BRIGHTNESS); // - // Global Leveling + // TOUCH_SCREEN_CALIBRATION // + TERN_(TOUCH_SCREEN_CALIBRATION, touch.calibration_reset()); - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - new_z_fade_height = 0.0; - #endif + // + // Magnetic Parking Extruder + // + TERN_(MAGNETIC_PARKING_EXTRUDER, mpe_settings_init()); - #if HAS_LEVELING - reset_bed_level(); - #endif + // + // Global Leveling + // + TERN_(ENABLE_LEVELING_FADE_HEIGHT, new_z_fade_height = 0.0); + TERN_(HAS_LEVELING, reset_bed_level()); #if HAS_BED_PROBE constexpr float dpo[] = NOZZLE_TO_PROBE_OFFSET; @@ -2523,26 +2565,19 @@ void MarlinSettings::reset() { #if HAS_PROBE_XY_OFFSET LOOP_XYZ(a) probe.offset[a] = dpo[a]; #else - probe.offset.x = probe.offset.y = 0; - probe.offset.z = dpo[Z_AXIS]; + probe.offset.set(0, 0, dpo[Z_AXIS]); #endif #endif // // Z Stepper Auto-alignment points // - - #if ENABLED(Z_STEPPER_AUTO_ALIGN) - z_stepper_align.reset_to_default(); - #endif + TERN_(Z_STEPPER_AUTO_ALIGN, z_stepper_align.reset_to_default()); // // Servo Angles // - - #if ENABLED(EDITABLE_SERVO_ANGLES) - COPY(servo_angles, base_servo_angles); // When not editable only one copy of servo angles exists - #endif + TERN_(EDITABLE_SERVO_ANGLES, COPY(servo_angles, base_servo_angles)); // When not editable only one copy of servo angles exists // // BLTOUCH @@ -2556,14 +2591,14 @@ void MarlinSettings::reset() { // #if ENABLED(DELTA) - const abc_float_t adj = DELTA_ENDSTOP_ADJ, dta = DELTA_TOWER_ANGLE_TRIM; + const abc_float_t adj = DELTA_ENDSTOP_ADJ, dta = DELTA_TOWER_ANGLE_TRIM, ddr = DELTA_DIAGONAL_ROD_TRIM_TOWER; delta_height = DELTA_HEIGHT; delta_endstop_adj = adj; delta_radius = DELTA_RADIUS; delta_diagonal_rod = DELTA_DIAGONAL_ROD; delta_segments_per_second = DELTA_SEGMENTS_PER_SECOND; delta_tower_angle_trim = dta; - + delta_diagonal_rod_trim = ddr; #endif #if ENABLED(X_DUAL_ENDSTOPS) @@ -2602,14 +2637,27 @@ void MarlinSettings::reset() { // // Preheat parameters // - - #if HOTENDS && HAS_LCD_MENU - ui.preheat_hotend_temp[0] = PREHEAT_1_TEMP_HOTEND; - ui.preheat_hotend_temp[1] = PREHEAT_2_TEMP_HOTEND; - ui.preheat_bed_temp[0] = PREHEAT_1_TEMP_BED; - ui.preheat_bed_temp[1] = PREHEAT_2_TEMP_BED; - ui.preheat_fan_speed[0] = PREHEAT_1_FAN_SPEED; - ui.preheat_fan_speed[1] = PREHEAT_2_FAN_SPEED; + #if PREHEAT_COUNT + #if HAS_HOTEND + constexpr uint16_t hpre[] = ARRAY_N(PREHEAT_COUNT, PREHEAT_1_TEMP_HOTEND, PREHEAT_2_TEMP_HOTEND, PREHEAT_3_TEMP_HOTEND, PREHEAT_4_TEMP_HOTEND, PREHEAT_5_TEMP_HOTEND); + #endif + #if HAS_HEATED_BED + constexpr uint16_t bpre[] = ARRAY_N(PREHEAT_COUNT, PREHEAT_1_TEMP_BED, PREHEAT_2_TEMP_BED, PREHEAT_3_TEMP_BED, PREHEAT_4_TEMP_BED, PREHEAT_5_TEMP_BED); + #endif + #if HAS_FAN + constexpr uint8_t fpre[] = ARRAY_N(PREHEAT_COUNT, PREHEAT_1_FAN_SPEED, PREHEAT_2_FAN_SPEED, PREHEAT_3_FAN_SPEED, PREHEAT_4_FAN_SPEED, PREHEAT_5_FAN_SPEED); + #endif + LOOP_L_N(i, PREHEAT_COUNT) { + #if HAS_HOTEND + ui.material_preset[i].hotend_temp = hpre[i]; + #endif + #if HAS_HEATED_BED + ui.material_preset[i].bed_temp = bpre[i]; + #endif + #if HAS_FAN + ui.material_preset[i].fan_speed = fpre[i]; + #endif + } #endif // @@ -2617,27 +2665,66 @@ void MarlinSettings::reset() { // #if ENABLED(PIDTEMP) - HOTEND_LOOP() { - PID_PARAM(Kp, e) = float(DEFAULT_Kp); - PID_PARAM(Ki, e) = scalePID_i(DEFAULT_Ki); - PID_PARAM(Kd, e) = scalePID_d(DEFAULT_Kd); + #if ENABLED(PID_PARAMS_PER_HOTEND) + constexpr float defKp[] = + #ifdef DEFAULT_Kp_LIST + DEFAULT_Kp_LIST + #else + ARRAY_BY_HOTENDS1(DEFAULT_Kp) + #endif + , defKi[] = + #ifdef DEFAULT_Ki_LIST + DEFAULT_Ki_LIST + #else + ARRAY_BY_HOTENDS1(DEFAULT_Ki) + #endif + , defKd[] = + #ifdef DEFAULT_Kd_LIST + DEFAULT_Kd_LIST + #else + ARRAY_BY_HOTENDS1(DEFAULT_Kd) + #endif + ; + static_assert(WITHIN(COUNT(defKp), 1, HOTENDS), "DEFAULT_Kp_LIST must have between 1 and HOTENDS items."); + static_assert(WITHIN(COUNT(defKi), 1, HOTENDS), "DEFAULT_Ki_LIST must have between 1 and HOTENDS items."); + static_assert(WITHIN(COUNT(defKd), 1, HOTENDS), "DEFAULT_Kd_LIST must have between 1 and HOTENDS items."); #if ENABLED(PID_EXTRUSION_SCALING) - PID_PARAM(Kc, e) = DEFAULT_Kc; + constexpr float defKc[] = + #ifdef DEFAULT_Kc_LIST + DEFAULT_Kc_LIST + #else + ARRAY_BY_HOTENDS1(DEFAULT_Kc) + #endif + ; + static_assert(WITHIN(COUNT(defKc), 1, HOTENDS), "DEFAULT_Kc_LIST must have between 1 and HOTENDS items."); #endif - #if ENABLED(PID_FAN_SCALING) - PID_PARAM(Kf, e) = DEFAULT_Kf; + constexpr float defKf[] = + #ifdef DEFAULT_Kf_LIST + DEFAULT_Kf_LIST + #else + ARRAY_BY_HOTENDS1(DEFAULT_Kf) + #endif + ; + static_assert(WITHIN(COUNT(defKf), 1, HOTENDS), "DEFAULT_Kf_LIST must have between 1 and HOTENDS items."); #endif + #define PID_DEFAULT(N,E) def##N[E] + #else + #define PID_DEFAULT(N,E) DEFAULT_##N + #endif + HOTEND_LOOP() { + PID_PARAM(Kp, e) = float(PID_DEFAULT(Kp, ALIM(e, defKp))); + PID_PARAM(Ki, e) = scalePID_i(PID_DEFAULT(Ki, ALIM(e, defKi))); + PID_PARAM(Kd, e) = scalePID_d(PID_DEFAULT(Kd, ALIM(e, defKd))); + TERN_(PID_EXTRUSION_SCALING, PID_PARAM(Kc, e) = float(PID_DEFAULT(Kc, ALIM(e, defKc)))); + TERN_(PID_FAN_SCALING, PID_PARAM(Kf, e) = float(PID_DEFAULT(Kf, ALIM(e, defKf)))); } #endif // // PID Extrusion Scaling // - - #if ENABLED(PID_EXTRUSION_SCALING) - thermalManager.lpq_len = 20; // Default last-position-queue size - #endif + TERN_(PID_EXTRUSION_SCALING, thermalManager.lpq_len = 20); // Default last-position-queue size // // Heated Bed PID @@ -2652,60 +2739,48 @@ void MarlinSettings::reset() { // // User-Defined Thermistors // + TERN_(HAS_USER_THERMISTORS, thermalManager.reset_user_thermistors()); - #if HAS_USER_THERMISTORS - thermalManager.reset_user_thermistors(); - #endif + // + // Power Monitor + // + TERN_(POWER_MONITOR, power_monitor.reset()); // // LCD Contrast // + TERN_(HAS_LCD_CONTRAST, ui.set_contrast(DEFAULT_LCD_CONTRAST)); - #if HAS_LCD_CONTRAST - ui.set_contrast(DEFAULT_LCD_CONTRAST); - #endif + // + // Controller Fan + // + TERN_(USE_CONTROLLER_FAN, controllerFan.reset()); // // Power-Loss Recovery // - - #if ENABLED(POWER_LOSS_RECOVERY) - recovery.enable(true); - #endif + TERN_(POWER_LOSS_RECOVERY, recovery.enable(ENABLED(PLR_ENABLED_DEFAULT))); // // Firmware Retraction // - - #if ENABLED(FWRETRACT) - fwretract.reset(); - #endif + TERN_(FWRETRACT, fwretract.reset()); // // Volumetric & Filament Size // #if DISABLED(NO_VOLUMETRICS) - - parser.volumetric_enabled = - #if ENABLED(VOLUMETRIC_DEFAULT_ON) - true - #else - false - #endif - ; + parser.volumetric_enabled = ENABLED(VOLUMETRIC_DEFAULT_ON); LOOP_L_N(q, COUNT(planner.filament_size)) planner.filament_size[q] = DEFAULT_NOMINAL_FILAMENT_DIA; - + #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) + LOOP_L_N(q, COUNT(planner.volumetric_extruder_limit)) + planner.volumetric_extruder_limit[q] = DEFAULT_VOLUMETRIC_EXTRUDER_LIMIT; + #endif #endif - endstops.enable_globally( - #if ENABLED(ENDSTOPS_ALWAYS_ON_DEFAULT) - true - #else - false - #endif - ); + endstops.enable_globally(ENABLED(ENDSTOPS_ALWAYS_ON_DEFAULT)); reset_stepper_drivers(); @@ -2716,9 +2791,7 @@ void MarlinSettings::reset() { #if ENABLED(LIN_ADVANCE) LOOP_L_N(i, EXTRUDERS) { planner.extruder_advance_K[i] = LIN_ADVANCE_K; - #if ENABLED(EXTRA_LIN_ADVANCE_K) - saved_extruder_advance_K[i] = LIN_ADVANCE_K; - #endif + TERN_(EXTRA_LIN_ADVANCE_K, other_extruder_advance_K[i] = LIN_ADVANCE_K); } #endif @@ -2727,23 +2800,30 @@ void MarlinSettings::reset() { // #if HAS_MOTOR_CURRENT_PWM - constexpr uint32_t tmp_motor_current_setting[3] = PWM_MOTOR_CURRENT; - for (uint8_t q = 3; q--;) - stepper.digipot_current(q, (stepper.motor_current_setting[q] = tmp_motor_current_setting[q])); + constexpr uint32_t tmp_motor_current_setting[MOTOR_CURRENT_COUNT] = PWM_MOTOR_CURRENT; + LOOP_L_N(q, MOTOR_CURRENT_COUNT) + stepper.set_digipot_current(q, (stepper.motor_current_setting[q] = tmp_motor_current_setting[q])); #endif // - // CNC Coordinate System + // DIGIPOTS // - - #if ENABLED(CNC_COORDINATE_SYSTEMS) - (void)gcode.select_coordinate_system(-1); // Go back to machine space + #if HAS_MOTOR_CURRENT_SPI + static constexpr uint32_t tmp_motor_current_setting[] = DIGIPOT_MOTOR_CURRENT; + DEBUG_ECHOLNPGM("Writing Digipot"); + LOOP_L_N(q, COUNT(tmp_motor_current_setting)) + stepper.set_digipot_current(q, tmp_motor_current_setting[q]); + DEBUG_ECHOLNPGM("Digipot Written"); #endif // - // Skew Correction + // CNC Coordinate System // + TERN_(CNC_COORDINATE_SYSTEMS, (void)gcode.select_coordinate_system(-1)); // Go back to machine space + // + // Skew Correction + // #if ENABLED(SKEW_CORRECTION_GCODE) planner.skew_factor.xy = XY_SKEW_FACTOR; #if ENABLED(SKEW_CORRECTION_FOR_Z) @@ -2755,7 +2835,6 @@ void MarlinSettings::reset() { // // Advanced Pause filament load & unload lengths // - #if ENABLED(ADVANCED_PAUSE_FEATURE) LOOP_L_N(e, EXTRUDERS) { fc_settings[e].unload_length = FILAMENT_CHANGE_UNLOAD_LENGTH; @@ -2763,14 +2842,21 @@ void MarlinSettings::reset() { } #endif + #if ENABLED(PASSWORD_FEATURE) + #ifdef PASSWORD_DEFAULT_VALUE + password.is_set = true; + password.value = PASSWORD_DEFAULT_VALUE; + #else + password.is_set = false; + #endif + #endif + postprocess(); DEBUG_ECHO_START(); DEBUG_ECHOLNPGM("Hardcoded Default Settings Loaded"); - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onFactoryReset(); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onFactoryReset()); } #if DISABLED(DISABLE_M503) @@ -2788,7 +2874,7 @@ void MarlinSettings::reset() { #define CONFIG_ECHO_MSG(STR) do{ CONFIG_ECHO_START(); SERIAL_ECHOLNPGM(STR); }while(0) #define CONFIG_ECHO_HEADING(STR) config_heading(forReplay, PSTR(STR)) - #if HAS_TRINAMIC + #if HAS_TRINAMIC_CONFIG inline void say_M906(const bool forReplay) { CONFIG_ECHO_START(); SERIAL_ECHOPGM(" M906"); } #if HAS_STEALTHCHOP void say_M569(const bool forReplay, const char * const etc=nullptr, const bool newLine = false) { @@ -2864,7 +2950,7 @@ void MarlinSettings::reset() { SERIAL_EOL(); - #if DISABLED(NO_VOLUMETRICS) + #if EXTRUDERS && DISABLED(NO_VOLUMETRICS) /** * Volumetric extrusion M200 @@ -2879,20 +2965,26 @@ void MarlinSettings::reset() { #if EXTRUDERS == 1 CONFIG_ECHO_START(); - SERIAL_ECHOLNPAIR(" M200 D", LINEAR_UNIT(planner.filament_size[0])); - #elif EXTRUDERS + SERIAL_ECHOLNPAIR(" M200 S", int(parser.volumetric_enabled) + , " D", LINEAR_UNIT(planner.filament_size[0]) + #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) + , " L", LINEAR_UNIT(planner.volumetric_extruder_limit[0]) + #endif + ); + #else LOOP_L_N(i, EXTRUDERS) { CONFIG_ECHO_START(); - SERIAL_ECHOPGM(" M200"); - if (i) SERIAL_ECHOPAIR_P(SP_T_STR, int(i)); - SERIAL_ECHOLNPAIR(" D", LINEAR_UNIT(planner.filament_size[i])); + SERIAL_ECHOLNPAIR(" M200 T", int(i) + , " D", LINEAR_UNIT(planner.filament_size[i]) + #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) + , " L", LINEAR_UNIT(planner.volumetric_extruder_limit[i]) + #endif + ); } + CONFIG_ECHO_START(); + SERIAL_ECHOLNPAIR(" M200 S", int(parser.volumetric_enabled)); #endif - - if (!parser.volumetric_enabled) - CONFIG_ECHO_MSG(" M200 D0"); - - #endif // !NO_VOLUMETRICS + #endif // EXTRUDERS && !NO_VOLUMETRICS CONFIG_ECHO_HEADING("Steps per unit:"); report_M92(!forReplay); @@ -2908,8 +3000,8 @@ void MarlinSettings::reset() { #endif ); #if ENABLED(DISTINCT_E_FACTORS) - CONFIG_ECHO_START(); LOOP_L_N(i, E_STEPPERS) { + CONFIG_ECHO_START(); SERIAL_ECHOLNPAIR_P( PSTR(" M203 T"), (int)i , SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_feedrate_mm_s[E_AXIS_N(i)]) @@ -2928,12 +3020,13 @@ void MarlinSettings::reset() { #endif ); #if ENABLED(DISTINCT_E_FACTORS) - CONFIG_ECHO_START(); - LOOP_L_N(i, E_STEPPERS) + LOOP_L_N(i, E_STEPPERS) { + CONFIG_ECHO_START(); SERIAL_ECHOLNPAIR_P( PSTR(" M201 T"), (int)i , SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(i)]) ); + } #endif CONFIG_ECHO_HEADING("Acceleration (units/s2): P R T"); @@ -2946,14 +3039,12 @@ void MarlinSettings::reset() { CONFIG_ECHO_HEADING( "Advanced: B S T" - #if DISABLED(CLASSIC_JERK) + #if HAS_JUNCTION_DEVIATION " J" #endif #if HAS_CLASSIC_JERK " X Y Z" - #if HAS_CLASSIC_E_JERK - " E" - #endif + TERN_(HAS_CLASSIC_E_JERK, " E") #endif ); CONFIG_ECHO_START(); @@ -2961,7 +3052,7 @@ void MarlinSettings::reset() { PSTR(" M205 B"), LINEAR_UNIT(planner.settings.min_segment_time_us) , PSTR(" S"), LINEAR_UNIT(planner.settings.min_feedrate_mm_s) , SP_T_STR, LINEAR_UNIT(planner.settings.min_travel_feedrate_mm_s) - #if DISABLED(CLASSIC_JERK) + #if HAS_JUNCTION_DEVIATION , PSTR(" J"), LINEAR_UNIT(planner.junction_deviation_mm) #endif #if HAS_CLASSIC_JERK @@ -2992,7 +3083,7 @@ void MarlinSettings::reset() { #if HAS_HOTEND_OFFSET CONFIG_ECHO_HEADING("Hotend offsets:"); CONFIG_ECHO_START(); - for (uint8_t e = 1; e < HOTENDS; e++) { + LOOP_S_L_N(e, 1, HOTENDS) { SERIAL_ECHOPAIR_P( PSTR(" M218 T"), (int)e, SP_X_STR, LINEAR_UNIT(hotend_offset[e].x), @@ -3123,7 +3214,7 @@ void MarlinSettings::reset() { , SP_Z_STR, LINEAR_UNIT(delta_endstop_adj.c) ); - CONFIG_ECHO_HEADING("Delta settings: L R H S XYZ"); + CONFIG_ECHO_HEADING("Delta settings: L R H S XYZ ABC"); CONFIG_ECHO_START(); SERIAL_ECHOLNPAIR_P( PSTR(" M665 L"), LINEAR_UNIT(delta_diagonal_rod) @@ -3133,6 +3224,9 @@ void MarlinSettings::reset() { , SP_X_STR, LINEAR_UNIT(delta_tower_angle_trim.a) , SP_Y_STR, LINEAR_UNIT(delta_tower_angle_trim.b) , SP_Z_STR, LINEAR_UNIT(delta_tower_angle_trim.c) + , PSTR(" A"), LINEAR_UNIT(delta_diagonal_rod_trim.a) + , PSTR(" B"), LINEAR_UNIT(delta_diagonal_rod_trim.b) + , PSTR(" C"), LINEAR_UNIT(delta_diagonal_rod_trim.c) ); #elif HAS_EXTRA_ENDSTOPS @@ -3162,16 +3256,22 @@ void MarlinSettings::reset() { #endif // [XYZ]_DUAL_ENDSTOPS - #if HOTENDS && HAS_LCD_MENU + #if PREHEAT_COUNT CONFIG_ECHO_HEADING("Material heatup parameters:"); - LOOP_L_N(i, COUNT(ui.preheat_hotend_temp)) { + LOOP_L_N(i, PREHEAT_COUNT) { CONFIG_ECHO_START(); - SERIAL_ECHOLNPAIR( - " M145 S", (int)i - , " H", TEMP_UNIT(ui.preheat_hotend_temp[i]) - , " B", TEMP_UNIT(ui.preheat_bed_temp[i]) - , " F", int(ui.preheat_fan_speed[i]) + SERIAL_ECHOLNPAIR_P( + PSTR(" M145 S"), (int)i + #if HAS_HOTEND + , PSTR(" H"), TEMP_UNIT(ui.material_preset[i].hotend_temp) + #endif + #if HAS_HEATED_BED + , SP_B_STR, TEMP_UNIT(ui.material_preset[i].bed_temp) + #endif + #if HAS_FAN + , PSTR(" F"), ui.material_preset[i].fan_speed + #endif ); } @@ -3185,7 +3285,7 @@ void MarlinSettings::reset() { HOTEND_LOOP() { CONFIG_ECHO_START(); SERIAL_ECHOPAIR_P( - #if HOTENDS > 1 && ENABLED(PID_PARAMS_PER_HOTEND) + #if ENABLED(PID_PARAMS_PER_HOTEND) PSTR(" M301 E"), e, SP_P_STR #else @@ -3196,7 +3296,7 @@ void MarlinSettings::reset() { , PSTR(" D"), unscalePID_d(PID_PARAM(Kd, e)) ); #if ENABLED(PID_EXTRUSION_SCALING) - SERIAL_ECHOPAIR(" C", PID_PARAM(Kc, e)); + SERIAL_ECHOPAIR_P(SP_C_STR, PID_PARAM(Kc, e)); if (e == 0) SERIAL_ECHOPAIR(" L", thermalManager.lpq_len); #endif #if ENABLED(PID_FAN_SCALING) @@ -3229,6 +3329,8 @@ void MarlinSettings::reset() { SERIAL_ECHOLNPAIR(" M250 C", ui.contrast); #endif + TERN_(CONTROLLER_FAN_EDITABLE, M710_report(forReplay)); + #if ENABLED(POWER_LOSS_RECOVERY) CONFIG_ECHO_HEADING("Power-Loss Recovery:"); CONFIG_ECHO_START(); @@ -3298,7 +3400,7 @@ void MarlinSettings::reset() { #endif #endif - #if HAS_TRINAMIC + #if HAS_TRINAMIC_CONFIG /** * TMC stepper driver current @@ -3385,34 +3487,30 @@ void MarlinSettings::reset() { CONFIG_ECHO_HEADING("Hybrid Threshold:"); #if AXIS_HAS_STEALTHCHOP(X) || AXIS_HAS_STEALTHCHOP(Y) || AXIS_HAS_STEALTHCHOP(Z) say_M913(forReplay); - #endif - #if AXIS_HAS_STEALTHCHOP(X) - SERIAL_ECHOPAIR_P(SP_X_STR, stepperX.get_pwm_thrs()); - #endif - #if AXIS_HAS_STEALTHCHOP(Y) - SERIAL_ECHOPAIR_P(SP_Y_STR, stepperY.get_pwm_thrs()); - #endif - #if AXIS_HAS_STEALTHCHOP(Z) - SERIAL_ECHOPAIR_P(SP_Z_STR, stepperZ.get_pwm_thrs()); - #endif - #if AXIS_HAS_STEALTHCHOP(X) || AXIS_HAS_STEALTHCHOP(Y) || AXIS_HAS_STEALTHCHOP(Z) + #if AXIS_HAS_STEALTHCHOP(X) + SERIAL_ECHOPAIR_P(SP_X_STR, stepperX.get_pwm_thrs()); + #endif + #if AXIS_HAS_STEALTHCHOP(Y) + SERIAL_ECHOPAIR_P(SP_Y_STR, stepperY.get_pwm_thrs()); + #endif + #if AXIS_HAS_STEALTHCHOP(Z) + SERIAL_ECHOPAIR_P(SP_Z_STR, stepperZ.get_pwm_thrs()); + #endif SERIAL_EOL(); #endif #if AXIS_HAS_STEALTHCHOP(X2) || AXIS_HAS_STEALTHCHOP(Y2) || AXIS_HAS_STEALTHCHOP(Z2) say_M913(forReplay); SERIAL_ECHOPGM(" I1"); - #endif - #if AXIS_HAS_STEALTHCHOP(X2) - SERIAL_ECHOPAIR_P(SP_X_STR, stepperX2.get_pwm_thrs()); - #endif - #if AXIS_HAS_STEALTHCHOP(Y2) - SERIAL_ECHOPAIR_P(SP_Y_STR, stepperY2.get_pwm_thrs()); - #endif - #if AXIS_HAS_STEALTHCHOP(Z2) - SERIAL_ECHOPAIR_P(SP_Z_STR, stepperZ2.get_pwm_thrs()); - #endif - #if AXIS_HAS_STEALTHCHOP(X2) || AXIS_HAS_STEALTHCHOP(Y2) || AXIS_HAS_STEALTHCHOP(Z2) + #if AXIS_HAS_STEALTHCHOP(X2) + SERIAL_ECHOPAIR_P(SP_X_STR, stepperX2.get_pwm_thrs()); + #endif + #if AXIS_HAS_STEALTHCHOP(Y2) + SERIAL_ECHOPAIR_P(SP_Y_STR, stepperY2.get_pwm_thrs()); + #endif + #if AXIS_HAS_STEALTHCHOP(Z2) + SERIAL_ECHOPAIR_P(SP_Z_STR, stepperZ2.get_pwm_thrs()); + #endif SERIAL_EOL(); #endif @@ -3517,112 +3615,123 @@ void MarlinSettings::reset() { #if HAS_STEALTHCHOP CONFIG_ECHO_HEADING("Driver stepping mode:"); #if AXIS_HAS_STEALTHCHOP(X) - const bool chop_x = stepperX.get_stealthChop_status(); + const bool chop_x = stepperX.get_stored_stealthChop_status(); #else constexpr bool chop_x = false; #endif #if AXIS_HAS_STEALTHCHOP(Y) - const bool chop_y = stepperY.get_stealthChop_status(); + const bool chop_y = stepperY.get_stored_stealthChop_status(); #else constexpr bool chop_y = false; #endif #if AXIS_HAS_STEALTHCHOP(Z) - const bool chop_z = stepperZ.get_stealthChop_status(); + const bool chop_z = stepperZ.get_stored_stealthChop_status(); #else constexpr bool chop_z = false; #endif if (chop_x || chop_y || chop_z) { say_M569(forReplay); - if (chop_x) SERIAL_ECHO_P(SP_X_STR); - if (chop_y) SERIAL_ECHO_P(SP_Y_STR); - if (chop_z) SERIAL_ECHO_P(SP_Z_STR); + if (chop_x) SERIAL_ECHOPGM_P(SP_X_STR); + if (chop_y) SERIAL_ECHOPGM_P(SP_Y_STR); + if (chop_z) SERIAL_ECHOPGM_P(SP_Z_STR); SERIAL_EOL(); } #if AXIS_HAS_STEALTHCHOP(X2) - const bool chop_x2 = stepperX2.get_stealthChop_status(); + const bool chop_x2 = stepperX2.get_stored_stealthChop_status(); #else constexpr bool chop_x2 = false; #endif #if AXIS_HAS_STEALTHCHOP(Y2) - const bool chop_y2 = stepperY2.get_stealthChop_status(); + const bool chop_y2 = stepperY2.get_stored_stealthChop_status(); #else constexpr bool chop_y2 = false; #endif #if AXIS_HAS_STEALTHCHOP(Z2) - const bool chop_z2 = stepperZ2.get_stealthChop_status(); + const bool chop_z2 = stepperZ2.get_stored_stealthChop_status(); #else constexpr bool chop_z2 = false; #endif if (chop_x2 || chop_y2 || chop_z2) { say_M569(forReplay, PSTR("I1")); - if (chop_x2) SERIAL_ECHO_P(SP_X_STR); - if (chop_y2) SERIAL_ECHO_P(SP_Y_STR); - if (chop_z2) SERIAL_ECHO_P(SP_Z_STR); + if (chop_x2) SERIAL_ECHOPGM_P(SP_X_STR); + if (chop_y2) SERIAL_ECHOPGM_P(SP_Y_STR); + if (chop_z2) SERIAL_ECHOPGM_P(SP_Z_STR); SERIAL_EOL(); } #if AXIS_HAS_STEALTHCHOP(Z3) - if (stepperZ3.get_stealthChop_status()) { say_M569(forReplay, PSTR("I2 Z"), true); } + if (stepperZ3.get_stored_stealthChop_status()) { say_M569(forReplay, PSTR("I2 Z"), true); } #endif #if AXIS_HAS_STEALTHCHOP(Z4) - if (stepperZ4.get_stealthChop_status()) { say_M569(forReplay, PSTR("I3 Z"), true); } + if (stepperZ4.get_stored_stealthChop_status()) { say_M569(forReplay, PSTR("I3 Z"), true); } #endif #if AXIS_HAS_STEALTHCHOP(E0) - if (stepperE0.get_stealthChop_status()) { say_M569(forReplay, PSTR("T0 E"), true); } + if (stepperE0.get_stored_stealthChop_status()) { say_M569(forReplay, PSTR("T0 E"), true); } #endif #if AXIS_HAS_STEALTHCHOP(E1) - if (stepperE1.get_stealthChop_status()) { say_M569(forReplay, PSTR("T1 E"), true); } + if (stepperE1.get_stored_stealthChop_status()) { say_M569(forReplay, PSTR("T1 E"), true); } #endif #if AXIS_HAS_STEALTHCHOP(E2) - if (stepperE2.get_stealthChop_status()) { say_M569(forReplay, PSTR("T2 E"), true); } + if (stepperE2.get_stored_stealthChop_status()) { say_M569(forReplay, PSTR("T2 E"), true); } #endif #if AXIS_HAS_STEALTHCHOP(E3) - if (stepperE3.get_stealthChop_status()) { say_M569(forReplay, PSTR("T3 E"), true); } + if (stepperE3.get_stored_stealthChop_status()) { say_M569(forReplay, PSTR("T3 E"), true); } #endif #if AXIS_HAS_STEALTHCHOP(E4) - if (stepperE4.get_stealthChop_status()) { say_M569(forReplay, PSTR("T4 E"), true); } + if (stepperE4.get_stored_stealthChop_status()) { say_M569(forReplay, PSTR("T4 E"), true); } #endif #if AXIS_HAS_STEALTHCHOP(E5) - if (stepperE5.get_stealthChop_status()) { say_M569(forReplay, PSTR("T5 E"), true); } + if (stepperE5.get_stored_stealthChop_status()) { say_M569(forReplay, PSTR("T5 E"), true); } #endif #if AXIS_HAS_STEALTHCHOP(E6) - if (stepperE6.get_stealthChop_status()) { say_M569(forReplay, PSTR("T6 E"), true); } + if (stepperE6.get_stored_stealthChop_status()) { say_M569(forReplay, PSTR("T6 E"), true); } #endif #if AXIS_HAS_STEALTHCHOP(E7) - if (stepperE7.get_stealthChop_status()) { say_M569(forReplay, PSTR("T7 E"), true); } + if (stepperE7.get_stored_stealthChop_status()) { say_M569(forReplay, PSTR("T7 E"), true); } #endif #endif // HAS_STEALTHCHOP - #endif // HAS_TRINAMIC + #endif // HAS_TRINAMIC_CONFIG /** * Linear Advance */ #if ENABLED(LIN_ADVANCE) CONFIG_ECHO_HEADING("Linear Advance:"); - CONFIG_ECHO_START(); #if EXTRUDERS < 2 + CONFIG_ECHO_START(); SERIAL_ECHOLNPAIR(" M900 K", planner.extruder_advance_K[0]); #else - LOOP_L_N(i, EXTRUDERS) + LOOP_L_N(i, EXTRUDERS) { + CONFIG_ECHO_START(); SERIAL_ECHOLNPAIR(" M900 T", int(i), " K", planner.extruder_advance_K[i]); + } #endif #endif - #if HAS_MOTOR_CURRENT_PWM + #if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM CONFIG_ECHO_HEADING("Stepper motor currents:"); CONFIG_ECHO_START(); - SERIAL_ECHOLNPAIR_P( - PSTR(" M907 X"), stepper.motor_current_setting[0] - , SP_Z_STR, stepper.motor_current_setting[1] - , SP_E_STR, stepper.motor_current_setting[2] - ); + #if HAS_MOTOR_CURRENT_PWM + SERIAL_ECHOLNPAIR_P( + PSTR(" M907 X"), stepper.motor_current_setting[0] + , SP_Z_STR, stepper.motor_current_setting[1] + , SP_E_STR, stepper.motor_current_setting[2] + ); + #elif HAS_MOTOR_CURRENT_SPI + SERIAL_ECHOPGM(" M907"); + LOOP_L_N(q, MOTOR_CURRENT_COUNT) { + SERIAL_CHAR(' '); + SERIAL_CHAR(axis_codes[q]); + SERIAL_ECHO(stepper.motor_current_setting[q]); + } + #endif #endif /** @@ -3639,7 +3748,7 @@ void MarlinSettings::reset() { #endif #endif - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER CONFIG_ECHO_HEADING("Tool-changing:"); CONFIG_ECHO_START(); M217_report(true); @@ -3664,7 +3773,7 @@ void MarlinSettings::reset() { CONFIG_ECHO_START(); SERIAL_ECHOLNPAIR( " M412 S", int(runout.enabled) - #ifdef FILAMENT_RUNOUT_DISTANCE_MM + #if HAS_FILAMENT_RUNOUT_DISTANCE , " D", LINEAR_UNIT(runout.runout_distance()) #endif ); diff --git a/Marlin/src/module/configuration_store.h b/Marlin/src/module/settings.h similarity index 93% rename from Marlin/src/module/configuration_store.h rename to Marlin/src/module/settings.h index a2c8d97dfad1..b213de93a433 100644 --- a/Marlin/src/module/configuration_store.h +++ b/Marlin/src/module/settings.h @@ -16,15 +16,19 @@ * 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 . + * along with this program. If not, see . * */ #pragma once +// +// settings.cpp - Settings and EEPROM storage +// + #include "../inc/MarlinConfig.h" #if ENABLED(EEPROM_SETTINGS) - #include "../HAL/shared/persistent_store_api.h" + #include "../HAL/shared/eeprom_api.h" #endif class MarlinSettings { @@ -38,9 +42,7 @@ class MarlinSettings { reset(); #if ENABLED(EEPROM_SETTINGS) const bool success = save(); - #if ENABLED(EEPROM_CHITCHAT) - if (success) report(); - #endif + if (TERN0(EEPROM_CHITCHAT, success)) report(); return success; #else return true; diff --git a/Marlin/src/module/speed_lookuptable.h b/Marlin/src/module/speed_lookuptable.h index 088cb23c7ff6..b173ebec0847 100644 --- a/Marlin/src/module/speed_lookuptable.h +++ b/Marlin/src/module/speed_lookuptable.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index 68639d40f003..6d451f8f0240 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -38,7 +38,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Grbl. If not, see . + * along with Grbl. If not, see . */ /** @@ -83,10 +83,6 @@ Stepper stepper; // Singleton #define BABYSTEPPING_EXTRA_DIR_WAIT -#if HAS_MOTOR_CURRENT_PWM - bool Stepper::initialized; // = false -#endif - #ifdef __AVR__ #include "speed_lookuptable.h" #endif @@ -97,7 +93,6 @@ Stepper stepper; // Singleton #include "temperature.h" #include "../lcd/ultralcd.h" -#include "../core/language.h" #include "../gcode/queue.h" #include "../sd/cardreader.h" #include "../MarlinCore.h" @@ -111,7 +106,7 @@ Stepper stepper; // Singleton #include "../feature/dac/dac_dac084s085.h" #endif -#if HAS_DIGIPOTSS +#if HAS_MOTOR_CURRENT_SPI #include #endif @@ -119,7 +114,7 @@ Stepper stepper; // Singleton #include "../feature/mixing.h" #endif -#ifdef FILAMENT_RUNOUT_DISTANCE_MM +#if HAS_FILAMENT_RUNOUT_DISTANCE #include "../feature/runout.h" #endif @@ -130,17 +125,25 @@ Stepper stepper; // Singleton #endif #if ENABLED(POWER_LOSS_RECOVERY) - #include "../feature/power_loss_recovery.h" + #include "../feature/powerloss.h" +#endif + +#if HAS_CUTTER + #include "../feature/spindle_laser.h" #endif // public: -#if HAS_EXTRA_ENDSTOPS || ENABLED(Z_STEPPER_AUTO_ALIGN) +#if EITHER(HAS_EXTRA_ENDSTOPS, Z_STEPPER_AUTO_ALIGN) bool Stepper::separate_multi_axis = false; #endif -#if HAS_MOTOR_CURRENT_PWM - uint32_t Stepper::motor_current_setting[3]; // Initialized by settings.load() +#if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM + bool Stepper::initialized; // = false + uint32_t Stepper::motor_current_setting[MOTOR_CURRENT_COUNT]; // Initialized by settings.load() + #if HAS_MOTOR_CURRENT_SPI + constexpr uint32_t Stepper::digipot_count[]; + #endif #endif // private: @@ -152,7 +155,7 @@ uint8_t Stepper::last_direction_bits, // = 0 bool Stepper::abort_current_block; -#if DISABLED(MIXING_EXTRUDER) && EXTRUDERS > 1 +#if DISABLED(MIXING_EXTRUDER) && HAS_MULTI_EXTRUDER uint8_t Stepper::last_moved_extruder = 0xFF; #endif @@ -165,22 +168,19 @@ bool Stepper::abort_current_block; #if EITHER(Z_MULTI_ENDSTOPS, Z_STEPPER_AUTO_ALIGN) bool Stepper::locked_Z_motor = false, Stepper::locked_Z2_motor = false - #if NUM_Z_STEPPER_DRIVERS >= 3 - , Stepper::locked_Z3_motor = false - #if NUM_Z_STEPPER_DRIVERS >= 4 - , Stepper::locked_Z4_motor = false - #endif - #endif - ; + #if NUM_Z_STEPPER_DRIVERS >= 3 + , Stepper::locked_Z3_motor = false + #if NUM_Z_STEPPER_DRIVERS >= 4 + , Stepper::locked_Z4_motor = false + #endif + #endif + ; #endif uint32_t Stepper::acceleration_time, Stepper::deceleration_time; uint8_t Stepper::steps_per_isr; -#if DISABLED(ADAPTIVE_STEP_SMOOTHING) - constexpr -#endif - uint8_t Stepper::oversampling_factor; +TERN(ADAPTIVE_STEP_SMOOTHING,,constexpr) uint8_t Stepper::oversampling_factor; xyze_long_t Stepper::delta_error{0}; @@ -191,7 +191,7 @@ uint32_t Stepper::advance_divisor = 0, Stepper::decelerate_after, // The count at which to start decelerating Stepper::step_event_count; // The total event count for the current block -#if EXTRUDERS > 1 || ENABLED(MIXING_EXTRUDER) +#if EITHER(HAS_MULTI_EXTRUDER, MIXING_EXTRUDER) uint8_t Stepper::stepper_extruder; #else constexpr uint8_t Stepper::stepper_extruder; @@ -227,6 +227,10 @@ uint32_t Stepper::advance_divisor = 0, uint32_t Stepper::nextBabystepISR = BABYSTEP_NEVER; #endif +#if ENABLED(DIRECT_STEPPING) + page_step_state_t Stepper::page_step_state; +#endif + int32_t Stepper::ticks_nominal = -1; #if DISABLED(S_CURVE_ACCELERATION) uint32_t Stepper::acc_step_rate; // needed for deceleration start point @@ -236,6 +240,20 @@ xyz_long_t Stepper::endstops_trigsteps; xyze_long_t Stepper::count_position{0}; xyze_int8_t Stepper::count_direction{0}; +#if ENABLED(LASER_POWER_INLINE_TRAPEZOID) + Stepper::stepper_laser_t Stepper::laser_trap = { + .enabled = false, + .cur_power = 0, + .cruise_set = false, + #if DISABLED(LASER_POWER_INLINE_TRAPEZOID_CONT) + .last_step_count = 0, + .acc_step_count = 0 + #else + .till_update = 0 + #endif + }; +#endif + #define DUAL_ENDSTOP_APPLY_STEP(A,V) \ if (separate_multi_axis) { \ if (A##_HOME_DIR < 0) { \ @@ -339,11 +357,11 @@ xyze_int8_t Stepper::count_direction{0}; #elif ENABLED(DUAL_X_CARRIAGE) #define X_APPLY_DIR(v,ALWAYS) do{ \ if (extruder_duplication_enabled || ALWAYS) { X_DIR_WRITE(v); X2_DIR_WRITE(mirrored_duplication_mode ? !(v) : v); } \ - else if (movement_extruder()) X2_DIR_WRITE(v); else X_DIR_WRITE(v); \ + else if (last_moved_extruder) X2_DIR_WRITE(v); else X_DIR_WRITE(v); \ }while(0) #define X_APPLY_STEP(v,ALWAYS) do{ \ if (extruder_duplication_enabled || ALWAYS) { X_STEP_WRITE(v); X2_STEP_WRITE(v); } \ - else if (movement_extruder()) X2_STEP_WRITE(v); else X_STEP_WRITE(v); \ + else if (last_moved_extruder) X2_STEP_WRITE(v); else X_STEP_WRITE(v); \ }while(0) #else #define X_APPLY_DIR(v,Q) X_DIR_WRITE(v) @@ -399,10 +417,10 @@ xyze_int8_t Stepper::count_direction{0}; #endif #define CYCLES_TO_NS(CYC) (1000UL * (CYC) / ((F_CPU) / 1000000)) -constexpr uint32_t NS_PER_PULSE_TIMER_TICK = 1000000000UL / (STEPPER_TIMER_RATE); +#define NS_PER_PULSE_TIMER_TICK (1000000000UL / (STEPPER_TIMER_RATE)) // Round up when converting from ns to timer ticks -constexpr uint32_t NS_TO_PULSE_TIMER_TICKS(uint32_t NS) { return (NS + (NS_PER_PULSE_TIMER_TICK) / 2) / (NS_PER_PULSE_TIMER_TICK); } +#define NS_TO_PULSE_TIMER_TICKS(NS) (((NS) + (NS_PER_PULSE_TIMER_TICK) / 2) / (NS_PER_PULSE_TIMER_TICK)) #define TIMER_SETUP_NS (CYCLES_TO_NS(TIMER_READ_ADD_AND_STORE_CYCLES)) @@ -453,11 +471,9 @@ void Stepper::set_directions() { #if HAS_X_DIR SET_STEP_DIR(X); // A #endif - #if HAS_Y_DIR SET_STEP_DIR(Y); // B #endif - #if HAS_Z_DIR SET_STEP_DIR(Z); // C #endif @@ -1248,7 +1264,7 @@ void Stepper::set_directions() { } FORCE_INLINE int32_t Stepper::_eval_bezier_curve(const uint32_t curr_step) { - #if defined(__ARM__) || defined(__thumb__) + #if defined(__arm__) || defined(__thumb__) // For ARM Cortex M3/M4 CPUs, we have the optimized assembler version, that takes 43 cycles to execute uint32_t flo = 0; @@ -1486,8 +1502,12 @@ void Stepper::isr() { ENABLE_ISRS(); } -#define ISR_PULSE_CONTROL (MINIMUM_STEPPER_PULSE || MAXIMUM_STEPPER_RATE) -#define ISR_MULTI_STEPS (ISR_PULSE_CONTROL && DISABLED(I2S_STEPPER_STREAM)) +#if MINIMUM_STEPPER_PULSE || MAXIMUM_STEPPER_RATE + #define ISR_PULSE_CONTROL 1 +#endif +#if ISR_PULSE_CONTROL && DISABLED(I2S_STEPPER_STREAM) + #define ISR_MULTI_STEPS 1 +#endif /** * This phase of the ISR should ONLY create the pulses for the steppers. @@ -1501,11 +1521,7 @@ void Stepper::pulse_phase_isr() { // If we must abort the current block, do so! if (abort_current_block) { abort_current_block = false; - if (current_block) { - axis_did_move = 0; - current_block = nullptr; - planner.discard_current_block(); - } + if (current_block) discard_current_block(); } // If there is no current block, do nothing @@ -1539,46 +1555,158 @@ void Stepper::pulse_phase_isr() { } \ }while(0) - // Start an active pulse, if Bresenham says so, and update position + // Start an active pulse if needed #define PULSE_START(AXIS) do{ \ if (step_needed[_AXIS(AXIS)]) { \ _APPLY_STEP(AXIS, !_INVERT_STEP_PIN(AXIS), 0); \ } \ }while(0) - // Stop an active pulse, if any, and adjust error term + // Stop an active pulse if needed #define PULSE_STOP(AXIS) do { \ if (step_needed[_AXIS(AXIS)]) { \ _APPLY_STEP(AXIS, _INVERT_STEP_PIN(AXIS), 0); \ } \ }while(0) - // Determine if pulses are needed - #if HAS_X_STEP - PULSE_PREP(X); - #endif - #if HAS_Y_STEP - PULSE_PREP(Y); - #endif - #if HAS_Z_STEP - PULSE_PREP(Z); - #endif + // Direct Stepping page? + const bool is_page = IS_PAGE(current_block); + + #if ENABLED(DIRECT_STEPPING) + + if (is_page) { + + #if STEPPER_PAGE_FORMAT == SP_4x4D_128 + + #define PAGE_SEGMENT_UPDATE(AXIS, VALUE) do{ \ + if ((VALUE) < 7) SBI(dm, _AXIS(AXIS)); \ + else if ((VALUE) > 7) CBI(dm, _AXIS(AXIS)); \ + page_step_state.sd[_AXIS(AXIS)] = VALUE; \ + page_step_state.bd[_AXIS(AXIS)] += VALUE; \ + }while(0) + + #define PAGE_PULSE_PREP(AXIS) do{ \ + step_needed[_AXIS(AXIS)] = \ + pgm_read_byte(&segment_table[page_step_state.sd[_AXIS(AXIS)]][page_step_state.segment_steps & 0x7]); \ + }while(0) + + switch (page_step_state.segment_steps) { + case DirectStepping::Config::SEGMENT_STEPS: + page_step_state.segment_idx += 2; + page_step_state.segment_steps = 0; + // fallthru + case 0: { + const uint8_t low = page_step_state.page[page_step_state.segment_idx], + high = page_step_state.page[page_step_state.segment_idx + 1]; + uint8_t dm = last_direction_bits; + + PAGE_SEGMENT_UPDATE(X, low >> 4); + PAGE_SEGMENT_UPDATE(Y, low & 0xF); + PAGE_SEGMENT_UPDATE(Z, high >> 4); + PAGE_SEGMENT_UPDATE(E, high & 0xF); + + if (dm != last_direction_bits) { + last_direction_bits = dm; + set_directions(); + } + } break; + + default: break; + } + + PAGE_PULSE_PREP(X); + PAGE_PULSE_PREP(Y); + PAGE_PULSE_PREP(Z); + PAGE_PULSE_PREP(E); + + page_step_state.segment_steps++; + + #elif STEPPER_PAGE_FORMAT == SP_4x2_256 + + #define PAGE_SEGMENT_UPDATE(AXIS, VALUE) \ + page_step_state.sd[_AXIS(AXIS)] = VALUE; \ + page_step_state.bd[_AXIS(AXIS)] += VALUE; + + #define PAGE_PULSE_PREP(AXIS) do{ \ + step_needed[_AXIS(AXIS)] = \ + pgm_read_byte(&segment_table[page_step_state.sd[_AXIS(AXIS)]][page_step_state.segment_steps & 0x3]); \ + }while(0) + + switch (page_step_state.segment_steps) { + case DirectStepping::Config::SEGMENT_STEPS: + page_step_state.segment_idx++; + page_step_state.segment_steps = 0; + // fallthru + case 0: { + const uint8_t b = page_step_state.page[page_step_state.segment_idx]; + PAGE_SEGMENT_UPDATE(X, (b >> 6) & 0x3); + PAGE_SEGMENT_UPDATE(Y, (b >> 4) & 0x3); + PAGE_SEGMENT_UPDATE(Z, (b >> 2) & 0x3); + PAGE_SEGMENT_UPDATE(E, (b >> 0) & 0x3); + } break; + default: break; + } + + PAGE_PULSE_PREP(X); + PAGE_PULSE_PREP(Y); + PAGE_PULSE_PREP(Z); + PAGE_PULSE_PREP(E); + + page_step_state.segment_steps++; + + #elif STEPPER_PAGE_FORMAT == SP_4x1_512 + + #define PAGE_PULSE_PREP(AXIS, BITS) do{ \ + step_needed[_AXIS(AXIS)] = (steps >> BITS) & 0x1; \ + if (step_needed[_AXIS(AXIS)]) \ + page_step_state.bd[_AXIS(AXIS)]++; \ + }while(0) + + uint8_t steps = page_step_state.page[page_step_state.segment_idx >> 1]; + if (page_step_state.segment_idx & 0x1) steps >>= 4; + + PAGE_PULSE_PREP(X, 3); + PAGE_PULSE_PREP(Y, 2); + PAGE_PULSE_PREP(Z, 1); + PAGE_PULSE_PREP(E, 0); + + page_step_state.segment_idx++; - #if EITHER(LIN_ADVANCE, MIXING_EXTRUDER) - delta_error.e += advance_dividend.e; - if (delta_error.e >= 0) { - count_position.e += count_direction.e; - #if ENABLED(LIN_ADVANCE) - delta_error.e -= advance_divisor; - // Don't step E here - But remember the number of steps to perform - motor_direction(E_AXIS) ? --LA_steps : ++LA_steps; #else - step_needed.e = true; + #error "Unknown direct stepping page format!" #endif } - #elif HAS_E0_STEP - PULSE_PREP(E); - #endif + + #endif // DIRECT_STEPPING + + if (!is_page) { + // Determine if pulses are needed + #if HAS_X_STEP + PULSE_PREP(X); + #endif + #if HAS_Y_STEP + PULSE_PREP(Y); + #endif + #if HAS_Z_STEP + PULSE_PREP(Z); + #endif + + #if EITHER(LIN_ADVANCE, MIXING_EXTRUDER) + delta_error.e += advance_dividend.e; + if (delta_error.e >= 0) { + count_position.e += count_direction.e; + #if ENABLED(LIN_ADVANCE) + delta_error.e -= advance_divisor; + // Don't step E here - But remember the number of steps to perform + motor_direction(E_AXIS) ? --LA_steps : ++LA_steps; + #else + step_needed.e = true; + #endif + } + #elif HAS_E0_STEP + PULSE_PREP(E); + #endif + } #if ISR_MULTI_STEPS if (firstStep) @@ -1657,14 +1785,26 @@ uint32_t Stepper::block_phase_isr() { // If there is a current block if (current_block) { - // If current block is finished, reset pointer + // If current block is finished, reset pointer and finalize state if (step_events_completed >= step_event_count) { - #ifdef FILAMENT_RUNOUT_DISTANCE_MM - runout.block_completed(current_block); + #if ENABLED(DIRECT_STEPPING) + #if STEPPER_PAGE_FORMAT == SP_4x4D_128 + #define PAGE_SEGMENT_UPDATE_POS(AXIS) \ + count_position[_AXIS(AXIS)] += page_step_state.bd[_AXIS(AXIS)] - 128 * 7; + #elif STEPPER_PAGE_FORMAT == SP_4x1_512 || STEPPER_PAGE_FORMAT == SP_4x2_256 + #define PAGE_SEGMENT_UPDATE_POS(AXIS) \ + count_position[_AXIS(AXIS)] += page_step_state.bd[_AXIS(AXIS)] * count_direction[_AXIS(AXIS)]; + #endif + + if (IS_PAGE(current_block)) { + PAGE_SEGMENT_UPDATE_POS(X); + PAGE_SEGMENT_UPDATE_POS(Y); + PAGE_SEGMENT_UPDATE_POS(Z); + PAGE_SEGMENT_UPDATE_POS(E); + } #endif - axis_did_move = 0; - current_block = nullptr; - planner.discard_current_block(); + TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, runout.block_completed(current_block)); + discard_current_block(); } else { // Step events not completed yet... @@ -1674,10 +1814,9 @@ uint32_t Stepper::block_phase_isr() { #if ENABLED(S_CURVE_ACCELERATION) // Get the next speed to use (Jerk limited!) - uint32_t acc_step_rate = - acceleration_time < current_block->acceleration_time - ? _eval_bezier_curve(acceleration_time) - : current_block->cruise_rate; + uint32_t acc_step_rate = acceleration_time < current_block->acceleration_time + ? _eval_bezier_curve(acceleration_time) + : current_block->cruise_rate; #else acc_step_rate = STEP_MULTIPLY(acceleration_time, current_block->acceleration_rate) + current_block->initial_rate; NOMORE(acc_step_rate, current_block->nominal_rate); @@ -1690,9 +1829,40 @@ uint32_t Stepper::block_phase_isr() { acceleration_time += interval; #if ENABLED(LIN_ADVANCE) - // Fire ISR if final adv_rate is reached - if (LA_steps && (!LA_use_advance_lead || LA_isr_rate != current_block->advance_speed)) - initiateLA(); + if (LA_use_advance_lead) { + // Fire ISR if final adv_rate is reached + if (LA_steps && LA_isr_rate != current_block->advance_speed) nextAdvanceISR = 0; + } + else if (LA_steps) nextAdvanceISR = 0; + #endif + + // Update laser - Accelerating + #if ENABLED(LASER_POWER_INLINE_TRAPEZOID) + if (laser_trap.enabled) { + #if DISABLED(LASER_POWER_INLINE_TRAPEZOID_CONT) + if (current_block->laser.entry_per) { + laser_trap.acc_step_count -= step_events_completed - laser_trap.last_step_count; + laser_trap.last_step_count = step_events_completed; + + // Should be faster than a divide, since this should trip just once + if (laser_trap.acc_step_count < 0) { + while (laser_trap.acc_step_count < 0) { + laser_trap.acc_step_count += current_block->laser.entry_per; + if (laser_trap.cur_power < current_block->laser.power) laser_trap.cur_power++; + } + cutter.set_ocr_power(laser_trap.cur_power); + } + } + #else + if (laser_trap.till_update) + laser_trap.till_update--; + else { + laser_trap.till_update = LASER_POWER_INLINE_TRAPEZOID_CONT_PER; + laser_trap.cur_power = (current_block->laser.power * acc_step_rate) / current_block->nominal_rate; + cutter.set_ocr_power(laser_trap.cur_power); // Cycle efficiency is irrelevant it the last line was many cycles + } + #endif + } #endif } // Are we in Deceleration phase ? @@ -1740,10 +1910,39 @@ uint32_t Stepper::block_phase_isr() { LA_isr_rate = current_block->advance_speed; } } - else if (LA_steps) initiateLA(); + else if (LA_steps) nextAdvanceISR = 0; + #endif // LIN_ADVANCE + + // Update laser - Decelerating + #if ENABLED(LASER_POWER_INLINE_TRAPEZOID) + if (laser_trap.enabled) { + #if DISABLED(LASER_POWER_INLINE_TRAPEZOID_CONT) + if (current_block->laser.exit_per) { + laser_trap.acc_step_count -= step_events_completed - laser_trap.last_step_count; + laser_trap.last_step_count = step_events_completed; + + // Should be faster than a divide, since this should trip just once + if (laser_trap.acc_step_count < 0) { + while (laser_trap.acc_step_count < 0) { + laser_trap.acc_step_count += current_block->laser.exit_per; + if (laser_trap.cur_power > current_block->laser.power_exit) laser_trap.cur_power--; + } + cutter.set_ocr_power(laser_trap.cur_power); + } + } + #else + if (laser_trap.till_update) + laser_trap.till_update--; + else { + laser_trap.till_update = LASER_POWER_INLINE_TRAPEZOID_CONT_PER; + laser_trap.cur_power = (current_block->laser.power * step_rate) / current_block->nominal_rate; + cutter.set_ocr_power(laser_trap.cur_power); // Cycle efficiency isn't relevant when the last line was many cycles + } + #endif + } #endif } - // We must be in cruise phase otherwise + // Must be in cruise phase otherwise else { #if ENABLED(LIN_ADVANCE) @@ -1759,6 +1958,22 @@ uint32_t Stepper::block_phase_isr() { // The timer interval is just the nominal value for the nominal speed interval = ticks_nominal; + + // Update laser - Cruising + #if ENABLED(LASER_POWER_INLINE_TRAPEZOID) + if (laser_trap.enabled) { + if (!laser_trap.cruise_set) { + laser_trap.cur_power = current_block->laser.power; + cutter.set_ocr_power(laser_trap.cur_power); + laser_trap.cruise_set = true; + } + #if ENABLED(LASER_POWER_INLINE_TRAPEZOID_CONT) + laser_trap.till_update = LASER_POWER_INLINE_TRAPEZOID_CONT_PER; + #else + laser_trap.last_step_count = step_events_completed; + #endif + } + #endif } } } @@ -1773,19 +1988,35 @@ uint32_t Stepper::block_phase_isr() { // Sync block? Sync the stepper counts and return while (TEST(current_block->flag, BLOCK_BIT_SYNC_POSITION)) { _set_position(current_block->position); - planner.discard_current_block(); + discard_current_block(); // Try to get a new block if (!(current_block = planner.get_current_block())) return interval; // No more queued movements! } - #if HAS_CUTTER + // For non-inline cutter, grossly apply power + #if ENABLED(LASER_FEATURE) && DISABLED(LASER_POWER_INLINE) cutter.apply_power(current_block->cutter_power); #endif - #if ENABLED(POWER_LOSS_RECOVERY) - recovery.info.sdpos = current_block->sdpos; + TERN_(POWER_LOSS_RECOVERY, recovery.info.sdpos = current_block->sdpos); + + #if ENABLED(DIRECT_STEPPING) + if (IS_PAGE(current_block)) { + page_step_state.segment_steps = 0; + page_step_state.segment_idx = 0; + page_step_state.page = page_manager.get_page(current_block->page_idx); + page_step_state.bd.reset(); + + if (DirectStepping::Config::DIRECTIONAL) + current_block->direction_bits = last_direction_bits; + + if (!page_step_state.page) { + discard_current_block(); + return interval; + } + } #endif // Flag all moving axes for proper endstop handling @@ -1805,11 +2036,13 @@ uint32_t Stepper::block_phase_isr() { * If DeltaA == DeltaB, the movement is only in the 1st axis (X) */ #if EITHER(COREXY, COREXZ) - #define X_CMP == + #define X_CMP(A,B) ((A)==(B)) #else - #define X_CMP != + #define X_CMP(A,B) ((A)!=(B)) #endif - #define X_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && D_(1) X_CMP D_(2)) ) + #define X_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && X_CMP(D_(1),D_(2))) ) + #elif ENABLED(MARKFORGED_XY) + #define X_MOVE_TEST (current_block->steps.a != current_block->steps.b) #else #define X_MOVE_TEST !!current_block->steps.a #endif @@ -1823,11 +2056,11 @@ uint32_t Stepper::block_phase_isr() { * If DeltaA == -DeltaB, the movement is only in the 2nd axis (Y or Z) */ #if EITHER(COREYX, COREYZ) - #define Y_CMP == + #define Y_CMP(A,B) ((A)==(B)) #else - #define Y_CMP != + #define Y_CMP(A,B) ((A)!=(B)) #endif - #define Y_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && D_(1) Y_CMP D_(2)) ) + #define Y_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && Y_CMP(D_(1),D_(2))) ) #else #define Y_MOVE_TEST !!current_block->steps.b #endif @@ -1841,11 +2074,11 @@ uint32_t Stepper::block_phase_isr() { * If DeltaA == -DeltaB, the movement is only in the 2nd axis (Z) */ #if EITHER(COREZX, COREZY) - #define Z_CMP == + #define Z_CMP(A,B) ((A)==(B)) #else - #define Z_CMP != + #define Z_CMP(A,B) ((A)!=(B)) #endif - #define Z_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && D_(1) Z_CMP D_(2)) ) + #define Z_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && Z_CMP(D_(1),D_(2))) ) #else #define Z_MOVE_TEST !!current_block->steps.c #endif @@ -1863,17 +2096,18 @@ uint32_t Stepper::block_phase_isr() { // No acceleration / deceleration time elapsed so far acceleration_time = deceleration_time = 0; - uint8_t oversampling = 0; // Assume no axis smoothing (via oversampling) - #if ENABLED(ADAPTIVE_STEP_SMOOTHING) + uint8_t oversampling = 0; // Assume no axis smoothing (via oversampling) // Decide if axis smoothing is possible - uint32_t max_rate = current_block->nominal_rate; // Get the maximum rate (maximum event speed) + uint32_t max_rate = current_block->nominal_rate; // Get the step event rate while (max_rate < MIN_STEP_ISR_FREQUENCY) { // As long as more ISRs are possible... max_rate <<= 1; // Try to double the rate - if (max_rate >= MAX_STEP_ISR_FREQUENCY_1X) break; // Don't exceed the estimated ISR limit - ++oversampling; // Increase the oversampling (used for left-shift) + if (max_rate < MIN_STEP_ISR_FREQUENCY) // Don't exceed the estimated ISR limit + ++oversampling; // Increase the oversampling (used for left-shift) } oversampling_factor = oversampling; // For all timer interval calculations + #else + constexpr uint8_t oversampling = 0; #endif // Based on the oversampling factor, do the calculations @@ -1897,7 +2131,7 @@ uint32_t Stepper::block_phase_isr() { MIXER_STEPPER_SETUP(); #endif - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER stepper_extruder = current_block->extruder; #endif @@ -1917,27 +2151,50 @@ uint32_t Stepper::block_phase_isr() { else LA_isr_rate = LA_ADV_NEVER; #endif - if ( - #if HAS_L64XX - true // Always set direction for L64xx (This also enables the chips) - #else - current_block->direction_bits != last_direction_bits - #if DISABLED(MIXING_EXTRUDER) - || stepper_extruder != last_moved_extruder - #endif - #endif + if ( ENABLED(HAS_L64XX) // Always set direction for L64xx (Also enables the chips) + || current_block->direction_bits != last_direction_bits + || TERN(MIXING_EXTRUDER, false, stepper_extruder != last_moved_extruder) ) { last_direction_bits = current_block->direction_bits; - #if EXTRUDERS > 1 + #if HAS_MULTI_EXTRUDER last_moved_extruder = stepper_extruder; #endif - #if HAS_L64XX - L64XX_OK_to_power_up = true; - #endif + TERN_(HAS_L64XX, L64XX_OK_to_power_up = true); set_directions(); } + #if ENABLED(LASER_POWER_INLINE) + const power_status_t stat = current_block->laser.status; + #if ENABLED(LASER_POWER_INLINE_TRAPEZOID) + laser_trap.enabled = stat.isPlanned && stat.isEnabled; + laser_trap.cur_power = current_block->laser.power_entry; // RESET STATE + laser_trap.cruise_set = false; + #if DISABLED(LASER_POWER_INLINE_TRAPEZOID_CONT) + laser_trap.last_step_count = 0; + laser_trap.acc_step_count = current_block->laser.entry_per / 2; + #else + laser_trap.till_update = 0; + #endif + // Always have PWM in this case + if (stat.isPlanned) { // Planner controls the laser + cutter.set_ocr_power( + stat.isEnabled ? laser_trap.cur_power : 0 // ON with power or OFF + ); + } + #else + if (stat.isPlanned) { // Planner controls the laser + #if ENABLED(SPINDLE_LASER_PWM) + cutter.set_ocr_power( + stat.isEnabled ? current_block->laser.power : 0 // ON with power or OFF + ); + #else + cutter.set_enabled(stat.isEnabled); + #endif + } + #endif + #endif // LASER_POWER_INLINE + // At this point, we must ensure the movement about to execute isn't // trying to force the head against a limit switch. If using interrupt- // driven change detection, and already against a limit then no call to @@ -1957,21 +2214,34 @@ uint32_t Stepper::block_phase_isr() { // Mark the time_nominal as not calculated yet ticks_nominal = -1; - #if DISABLED(S_CURVE_ACCELERATION) - // Set as deceleration point the initial rate of the block - acc_step_rate = current_block->initial_rate; - #endif - #if ENABLED(S_CURVE_ACCELERATION) // Initialize the Bézier speed curve _calc_bezier_curve_coeffs(current_block->initial_rate, current_block->cruise_rate, current_block->acceleration_time_inverse); // We haven't started the 2nd half of the trapezoid bezier_2nd_half = false; + #else + // Set as deceleration point the initial rate of the block + acc_step_rate = current_block->initial_rate; #endif // Calculate the initial timer interval interval = calc_timer_interval(current_block->initial_rate, &steps_per_isr); } + #if ENABLED(LASER_POWER_INLINE_CONTINUOUS) + else { // No new block found; so apply inline laser parameters + // This should mean ending file with 'M5 I' will stop the laser; thus the inline flag isn't needed + const power_status_t stat = planner.laser_inline.status; + if (stat.isPlanned) { // Planner controls the laser + #if ENABLED(SPINDLE_LASER_PWM) + cutter.set_ocr_power( + stat.isEnabled ? planner.laser_inline.power : 0 // ON with power or OFF + ); + #else + cutter.set_enabled(stat.isEnabled); + #endif + } + } + #endif } // Return the interval to wait @@ -1991,7 +2261,6 @@ uint32_t Stepper::block_phase_isr() { interval = LA_isr_rate; } else if (step_events_completed < decelerate_after && LA_current_adv_steps < LA_max_adv_steps) { - //step_events_completed <= (uint32_t)accelerate_until) { LA_steps++; LA_current_adv_steps++; interval = LA_isr_rate; @@ -2002,19 +2271,21 @@ uint32_t Stepper::block_phase_isr() { else interval = LA_ADV_NEVER; + if (!LA_steps) return interval; // Leave pins alone if there are no steps! + DIR_WAIT_BEFORE(); #if ENABLED(MIXING_EXTRUDER) // We don't know which steppers will be stepped because LA loop follows, // with potentially multiple steps. Set all. - if (LA_steps >= 0) + if (LA_steps > 0) MIXER_STEPPER_LOOP(j) NORM_E_DIR(j); - else + else if (LA_steps < 0) MIXER_STEPPER_LOOP(j) REV_E_DIR(j); #else - if (LA_steps >= 0) + if (LA_steps > 0) NORM_E_DIR(stepper_extruder); - else + else if (LA_steps < 0) REV_E_DIR(stepper_extruder); #endif @@ -2116,27 +2387,21 @@ void Stepper::init() { #if MB(ALLIGATOR) const float motor_current[] = MOTOR_CURRENT; unsigned int digipot_motor = 0; - for (uint8_t i = 0; i < 3 + EXTRUDERS; i++) { + LOOP_L_N(i, 3 + EXTRUDERS) { digipot_motor = 255 * (motor_current[i] / 2.5); dac084s085::setValue(i, digipot_motor); } #endif // Init Microstepping Pins - #if HAS_MICROSTEPS - microstep_init(); - #endif + TERN_(HAS_MICROSTEPS, microstep_init()); // Init Dir Pins - #if HAS_X_DIR - X_DIR_INIT(); - #endif - #if HAS_X2_DIR - X2_DIR_INIT(); - #endif + TERN_(HAS_X_DIR, X_DIR_INIT()); + TERN_(HAS_X2_DIR, X2_DIR_INIT()); #if HAS_Y_DIR Y_DIR_INIT(); - #if ENABLED(Y_DUAL_STEPPER_DRIVERS) && HAS_Y2_DIR + #if BOTH(Y_DUAL_STEPPER_DRIVERS, HAS_Y2_DIR) Y2_DIR_INIT(); #endif #endif @@ -2189,7 +2454,7 @@ void Stepper::init() { #if HAS_Y_ENABLE Y_ENABLE_INIT(); if (!Y_ENABLE_ON) Y_ENABLE_WRITE(HIGH); - #if ENABLED(Y_DUAL_STEPPER_DRIVERS) && HAS_Y2_ENABLE + #if BOTH(Y_DUAL_STEPPER_DRIVERS, HAS_Y2_ENABLE) Y2_ENABLE_INIT(); if (!Y_ENABLE_ON) Y2_ENABLE_WRITE(HIGH); #endif @@ -2287,7 +2552,7 @@ void Stepper::init() { AXIS_INIT(Z, Z); #endif - #if E_STEPPERS > 0 && HAS_E0_STEP + #if E_STEPPERS && HAS_E0_STEP E_AXIS_INIT(0); #endif #if E_STEPPERS > 1 && HAS_E1_STEP @@ -2326,10 +2591,8 @@ void Stepper::init() { set_directions(); - #if HAS_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM - #if HAS_MOTOR_CURRENT_PWM - initialized = true; - #endif + #if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM + initialized = true; digipot_init(); #endif } @@ -2346,7 +2609,7 @@ void Stepper::init() { void Stepper::_set_position(const int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e) { #if CORE_IS_XY // corexy positioning - // these equations follow the form of the dA and dB equations on http://www.corexy.com/theory.html + // these equations follow the form of the dA and dB equations on https://www.corexy.com/theory.html count_position.set(a + b, CORESIGN(a - b), c); #elif CORE_IS_XZ // corexz planning @@ -2354,6 +2617,8 @@ void Stepper::_set_position(const int32_t &a, const int32_t &b, const int32_t &c #elif CORE_IS_YZ // coreyz planning count_position.set(a, b + c, CORESIGN(b - c)); + #elif ENABLED(MARKFORGED_XY) + count_position.set(a - b, b, c); #else // default non-h-bot planning count_position.set(a, b, c); @@ -2420,6 +2685,10 @@ void Stepper::endstop_triggered(const AxisEnum axis) { ? CORESIGN(count_position[CORE_AXIS_1] - count_position[CORE_AXIS_2]) : count_position[CORE_AXIS_1] + count_position[CORE_AXIS_2] ) * double(0.5) + #elif ENABLED(MARKFORGED_XY) + axis == CORE_AXIS_1 + ? count_position[CORE_AXIS_1] - count_position[CORE_AXIS_2] + : count_position[CORE_AXIS_2] #else // !IS_CORE count_position[axis] #endif @@ -2448,6 +2717,19 @@ int32_t Stepper::triggered_position(const AxisEnum axis) { return v; } +void Stepper::report_a_position(const xyz_long_t &pos) { + #if ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY, DELTA, IS_SCARA) + SERIAL_ECHOPAIR(STR_COUNT_A, pos.x, " B:", pos.y); + #else + SERIAL_ECHOPAIR_P(PSTR(STR_COUNT_X), pos.x, SP_Y_LBL, pos.y); + #endif + #if ANY(CORE_IS_XZ, CORE_IS_YZ, DELTA) + SERIAL_ECHOLNPAIR(" C:", pos.z); + #else + SERIAL_ECHOLNPAIR_P(SP_Z_LBL, pos.z); + #endif +} + void Stepper::report_positions() { #ifdef __AVR__ @@ -2461,16 +2743,7 @@ void Stepper::report_positions() { if (was_enabled) wake_up(); #endif - #if CORE_IS_XY || CORE_IS_XZ || ENABLED(DELTA) || IS_SCARA - SERIAL_ECHOPAIR(STR_COUNT_A, pos.x, " B:", pos.y); - #else - SERIAL_ECHOPAIR(STR_COUNT_X, pos.x, " Y:", pos.y); - #endif - #if CORE_IS_XZ || CORE_IS_YZ || ENABLED(DELTA) - SERIAL_ECHOLNPAIR(" C:", pos.z); - #else - SERIAL_ECHOLNPAIR(" Z:", pos.z); - #endif + report_a_position(pos); } #if ENABLED(BABYSTEPPING) @@ -2534,7 +2807,9 @@ void Stepper::report_positions() { EXTRA_DIR_WAIT_AFTER(); \ }while(0) - #elif IS_CORE + #endif + + #if IS_CORE #define BABYSTEP_CORE(A, B, INV, DIR, ALT) do{ \ const xy_byte_t old_dir = { _READ_DIR(A), _READ_DIR(B) }; \ @@ -2580,7 +2855,7 @@ void Stepper::report_positions() { case Y_AXIS: #if CORE_IS_XY - BABYSTEP_CORE(X, Y, 0, direction, (CORESIGN(1)<0)); + BABYSTEP_CORE(X, Y, 1, !direction, (CORESIGN(1)>0)); #elif CORE_IS_YZ BABYSTEP_CORE(Y, Z, 0, direction, (CORESIGN(1)<0)); #else @@ -2656,10 +2931,10 @@ void Stepper::report_positions() { * Software-controlled Stepper Motor Current */ -#if HAS_DIGIPOTSS +#if HAS_MOTOR_CURRENT_SPI // From Arduino DigitalPotControl example - void Stepper::digitalPotWrite(const int16_t address, const int16_t value) { + void Stepper::set_digipot_value_spi(const int16_t address, const int16_t value) { WRITE(DIGIPOTSS_PIN, LOW); // Take the SS pin low to select the chip SPI.transfer(address); // Send the address and value via SPI SPI.transfer(value); @@ -2667,7 +2942,7 @@ void Stepper::report_positions() { //delay(10); } -#endif // HAS_DIGIPOTSS +#endif // HAS_MOTOR_CURRENT_SPI #if HAS_MOTOR_CURRENT_PWM @@ -2684,7 +2959,7 @@ void Stepper::report_positions() { #if ANY_PIN(MOTOR_CURRENT_PWM_E, MOTOR_CURRENT_PWM_E0, MOTOR_CURRENT_PWM_E1) case 2: #endif - digipot_current(i, motor_current_setting[i]); + set_digipot_current(i, motor_current_setting[i]); default: break; } } @@ -2694,21 +2969,22 @@ void Stepper::report_positions() { #if !MB(PRINTRBOARD_G2) - #if HAS_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM + #if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM - void Stepper::digipot_current(const uint8_t driver, const int16_t current) { + void Stepper::set_digipot_current(const uint8_t driver, const int16_t current) { + if (WITHIN(driver, 0, COUNT(motor_current_setting) - 1)) + motor_current_setting[driver] = current; // update motor_current_setting - #if HAS_DIGIPOTSS + if (!initialized) return; - const uint8_t digipot_ch[] = DIGIPOT_CHANNELS; - digitalPotWrite(digipot_ch[driver], current); + #if HAS_MOTOR_CURRENT_SPI - #elif HAS_MOTOR_CURRENT_PWM + //SERIAL_ECHOLNPAIR("Digipotss current ", current); - if (!initialized) return; + const uint8_t digipot_ch[] = DIGIPOT_CHANNELS; + set_digipot_value_spi(digipot_ch[driver], current); - if (WITHIN(driver, 0, COUNT(motor_current_setting) - 1)) - motor_current_setting[driver] = current; // update motor_current_setting + #elif HAS_MOTOR_CURRENT_PWM #define _WRITE_CURRENT_PWM(P) analogWrite(pin_t(MOTOR_CURRENT_PWM_## P ##_PIN), 255L * current / (MOTOR_CURRENT_PWM_RANGE)) switch (driver) { @@ -2745,17 +3021,13 @@ void Stepper::report_positions() { void Stepper::digipot_init() { - #if HAS_DIGIPOTSS - - static const uint8_t digipot_motor_current[] = DIGIPOT_MOTOR_CURRENT; + #if HAS_MOTOR_CURRENT_SPI SPI.begin(); SET_OUTPUT(DIGIPOTSS_PIN); - for (uint8_t i = 0; i < COUNT(digipot_motor_current); i++) { - //digitalPotWrite(digipot_ch[i], digipot_motor_current[i]); - digipot_current(i, digipot_motor_current[i]); - } + LOOP_L_N(i, COUNT(motor_current_setting)) + set_digipot_current(i, motor_current_setting[i]); #elif HAS_MOTOR_CURRENT_PWM @@ -2805,112 +3077,112 @@ void Stepper::report_positions() { */ void Stepper::microstep_init() { - #if HAS_X_MICROSTEPS + #if HAS_X_MS_PINS SET_OUTPUT(X_MS1_PIN); SET_OUTPUT(X_MS2_PIN); #if PIN_EXISTS(X_MS3) SET_OUTPUT(X_MS3_PIN); #endif #endif - #if HAS_X2_MICROSTEPS + #if HAS_X2_MS_PINS SET_OUTPUT(X2_MS1_PIN); SET_OUTPUT(X2_MS2_PIN); #if PIN_EXISTS(X2_MS3) SET_OUTPUT(X2_MS3_PIN); #endif #endif - #if HAS_Y_MICROSTEPS + #if HAS_Y_MS_PINS SET_OUTPUT(Y_MS1_PIN); SET_OUTPUT(Y_MS2_PIN); #if PIN_EXISTS(Y_MS3) SET_OUTPUT(Y_MS3_PIN); #endif #endif - #if HAS_Y2_MICROSTEPS + #if HAS_Y2_MS_PINS SET_OUTPUT(Y2_MS1_PIN); SET_OUTPUT(Y2_MS2_PIN); #if PIN_EXISTS(Y2_MS3) SET_OUTPUT(Y2_MS3_PIN); #endif #endif - #if HAS_Z_MICROSTEPS + #if HAS_Z_MS_PINS SET_OUTPUT(Z_MS1_PIN); SET_OUTPUT(Z_MS2_PIN); #if PIN_EXISTS(Z_MS3) SET_OUTPUT(Z_MS3_PIN); #endif #endif - #if HAS_Z2_MICROSTEPS + #if HAS_Z2_MS_PINS SET_OUTPUT(Z2_MS1_PIN); SET_OUTPUT(Z2_MS2_PIN); #if PIN_EXISTS(Z2_MS3) SET_OUTPUT(Z2_MS3_PIN); #endif #endif - #if HAS_Z3_MICROSTEPS + #if HAS_Z3_MS_PINS SET_OUTPUT(Z3_MS1_PIN); SET_OUTPUT(Z3_MS2_PIN); #if PIN_EXISTS(Z3_MS3) SET_OUTPUT(Z3_MS3_PIN); #endif #endif - #if HAS_Z4_MICROSTEPS + #if HAS_Z4_MS_PINS SET_OUTPUT(Z4_MS1_PIN); SET_OUTPUT(Z4_MS2_PIN); #if PIN_EXISTS(Z4_MS3) SET_OUTPUT(Z4_MS3_PIN); #endif #endif - #if HAS_E0_MICROSTEPS + #if HAS_E0_MS_PINS SET_OUTPUT(E0_MS1_PIN); SET_OUTPUT(E0_MS2_PIN); #if PIN_EXISTS(E0_MS3) SET_OUTPUT(E0_MS3_PIN); #endif #endif - #if HAS_E1_MICROSTEPS + #if HAS_E1_MS_PINS SET_OUTPUT(E1_MS1_PIN); SET_OUTPUT(E1_MS2_PIN); #if PIN_EXISTS(E1_MS3) SET_OUTPUT(E1_MS3_PIN); #endif #endif - #if HAS_E2_MICROSTEPS + #if HAS_E2_MS_PINS SET_OUTPUT(E2_MS1_PIN); SET_OUTPUT(E2_MS2_PIN); #if PIN_EXISTS(E2_MS3) SET_OUTPUT(E2_MS3_PIN); #endif #endif - #if HAS_E3_MICROSTEPS + #if HAS_E3_MS_PINS SET_OUTPUT(E3_MS1_PIN); SET_OUTPUT(E3_MS2_PIN); #if PIN_EXISTS(E3_MS3) SET_OUTPUT(E3_MS3_PIN); #endif #endif - #if HAS_E4_MICROSTEPS + #if HAS_E4_MS_PINS SET_OUTPUT(E4_MS1_PIN); SET_OUTPUT(E4_MS2_PIN); #if PIN_EXISTS(E4_MS3) SET_OUTPUT(E4_MS3_PIN); #endif #endif - #if HAS_E5_MICROSTEPS + #if HAS_E5_MS_PINS SET_OUTPUT(E5_MS1_PIN); SET_OUTPUT(E5_MS2_PIN); #if PIN_EXISTS(E5_MS3) SET_OUTPUT(E5_MS3_PIN); #endif #endif - #if HAS_E6_MICROSTEPS + #if HAS_E6_MS_PINS SET_OUTPUT(E6_MS1_PIN); SET_OUTPUT(E6_MS2_PIN); #if PIN_EXISTS(E6_MS3) SET_OUTPUT(E6_MS3_PIN); #endif #endif - #if HAS_E7_MICROSTEPS + #if HAS_E7_MS_PINS SET_OUTPUT(E7_MS1_PIN); SET_OUTPUT(E7_MS2_PIN); #if PIN_EXISTS(E7_MS3) @@ -2925,188 +3197,188 @@ void Stepper::report_positions() { void Stepper::microstep_ms(const uint8_t driver, const int8_t ms1, const int8_t ms2, const int8_t ms3) { if (ms1 >= 0) switch (driver) { - #if HAS_X_MICROSTEPS || HAS_X2_MICROSTEPS + #if HAS_X_MS_PINS || HAS_X2_MS_PINS case 0: - #if HAS_X_MICROSTEPS + #if HAS_X_MS_PINS WRITE(X_MS1_PIN, ms1); #endif - #if HAS_X2_MICROSTEPS + #if HAS_X2_MS_PINS WRITE(X2_MS1_PIN, ms1); #endif break; #endif - #if HAS_Y_MICROSTEPS || HAS_Y2_MICROSTEPS + #if HAS_Y_MS_PINS || HAS_Y2_MS_PINS case 1: - #if HAS_Y_MICROSTEPS + #if HAS_Y_MS_PINS WRITE(Y_MS1_PIN, ms1); #endif - #if HAS_Y2_MICROSTEPS + #if HAS_Y2_MS_PINS WRITE(Y2_MS1_PIN, ms1); #endif break; #endif - #if HAS_SOME_Z_MICROSTEPS + #if HAS_SOME_Z_MS_PINS case 2: - #if HAS_Z_MICROSTEPS + #if HAS_Z_MS_PINS WRITE(Z_MS1_PIN, ms1); #endif - #if HAS_Z2_MICROSTEPS + #if HAS_Z2_MS_PINS WRITE(Z2_MS1_PIN, ms1); #endif - #if HAS_Z3_MICROSTEPS + #if HAS_Z3_MS_PINS WRITE(Z3_MS1_PIN, ms1); #endif - #if HAS_Z4_MICROSTEPS + #if HAS_Z4_MS_PINS WRITE(Z4_MS1_PIN, ms1); #endif break; #endif - #if HAS_E0_MICROSTEPS + #if HAS_E0_MS_PINS case 3: WRITE(E0_MS1_PIN, ms1); break; #endif - #if HAS_E1_MICROSTEPS + #if HAS_E1_MS_PINS case 4: WRITE(E1_MS1_PIN, ms1); break; #endif - #if HAS_E2_MICROSTEPS + #if HAS_E2_MS_PINS case 5: WRITE(E2_MS1_PIN, ms1); break; #endif - #if HAS_E3_MICROSTEPS + #if HAS_E3_MS_PINS case 6: WRITE(E3_MS1_PIN, ms1); break; #endif - #if HAS_E4_MICROSTEPS + #if HAS_E4_MS_PINS case 7: WRITE(E4_MS1_PIN, ms1); break; #endif - #if HAS_E5_MICROSTEPS + #if HAS_E5_MS_PINS case 8: WRITE(E5_MS1_PIN, ms1); break; #endif - #if HAS_E6_MICROSTEPS + #if HAS_E6_MS_PINS case 9: WRITE(E6_MS1_PIN, ms1); break; #endif - #if HAS_E7_MICROSTEPS + #if HAS_E7_MS_PINS case 10: WRITE(E7_MS1_PIN, ms1); break; #endif } if (ms2 >= 0) switch (driver) { - #if HAS_X_MICROSTEPS || HAS_X2_MICROSTEPS + #if HAS_X_MS_PINS || HAS_X2_MS_PINS case 0: - #if HAS_X_MICROSTEPS + #if HAS_X_MS_PINS WRITE(X_MS2_PIN, ms2); #endif - #if HAS_X2_MICROSTEPS + #if HAS_X2_MS_PINS WRITE(X2_MS2_PIN, ms2); #endif break; #endif - #if HAS_Y_MICROSTEPS || HAS_Y2_MICROSTEPS + #if HAS_Y_MS_PINS || HAS_Y2_MS_PINS case 1: - #if HAS_Y_MICROSTEPS + #if HAS_Y_MS_PINS WRITE(Y_MS2_PIN, ms2); #endif - #if HAS_Y2_MICROSTEPS + #if HAS_Y2_MS_PINS WRITE(Y2_MS2_PIN, ms2); #endif break; #endif - #if HAS_SOME_Z_MICROSTEPS + #if HAS_SOME_Z_MS_PINS case 2: - #if HAS_Z_MICROSTEPS + #if HAS_Z_MS_PINS WRITE(Z_MS2_PIN, ms2); #endif - #if HAS_Z2_MICROSTEPS + #if HAS_Z2_MS_PINS WRITE(Z2_MS2_PIN, ms2); #endif - #if HAS_Z3_MICROSTEPS + #if HAS_Z3_MS_PINS WRITE(Z3_MS2_PIN, ms2); #endif - #if HAS_Z4_MICROSTEPS + #if HAS_Z4_MS_PINS WRITE(Z4_MS2_PIN, ms2); #endif break; #endif - #if HAS_E0_MICROSTEPS + #if HAS_E0_MS_PINS case 3: WRITE(E0_MS2_PIN, ms2); break; #endif - #if HAS_E1_MICROSTEPS + #if HAS_E1_MS_PINS case 4: WRITE(E1_MS2_PIN, ms2); break; #endif - #if HAS_E2_MICROSTEPS + #if HAS_E2_MS_PINS case 5: WRITE(E2_MS2_PIN, ms2); break; #endif - #if HAS_E3_MICROSTEPS + #if HAS_E3_MS_PINS case 6: WRITE(E3_MS2_PIN, ms2); break; #endif - #if HAS_E4_MICROSTEPS + #if HAS_E4_MS_PINS case 7: WRITE(E4_MS2_PIN, ms2); break; #endif - #if HAS_E5_MICROSTEPS + #if HAS_E5_MS_PINS case 8: WRITE(E5_MS2_PIN, ms2); break; #endif - #if HAS_E6_MICROSTEPS + #if HAS_E6_MS_PINS case 9: WRITE(E6_MS2_PIN, ms2); break; #endif - #if HAS_E7_MICROSTEPS + #if HAS_E7_MS_PINS case 10: WRITE(E7_MS2_PIN, ms2); break; #endif } if (ms3 >= 0) switch (driver) { - #if HAS_X_MICROSTEPS || HAS_X2_MICROSTEPS + #if HAS_X_MS_PINS || HAS_X2_MS_PINS case 0: - #if HAS_X_MICROSTEPS && PIN_EXISTS(X_MS3) + #if HAS_X_MS_PINS && PIN_EXISTS(X_MS3) WRITE(X_MS3_PIN, ms3); #endif - #if HAS_X2_MICROSTEPS && PIN_EXISTS(X2_MS3) + #if HAS_X2_MS_PINS && PIN_EXISTS(X2_MS3) WRITE(X2_MS3_PIN, ms3); #endif break; #endif - #if HAS_Y_MICROSTEPS || HAS_Y2_MICROSTEPS + #if HAS_Y_MS_PINS || HAS_Y2_MS_PINS case 1: - #if HAS_Y_MICROSTEPS && PIN_EXISTS(Y_MS3) + #if HAS_Y_MS_PINS && PIN_EXISTS(Y_MS3) WRITE(Y_MS3_PIN, ms3); #endif - #if HAS_Y2_MICROSTEPS && PIN_EXISTS(Y2_MS3) + #if HAS_Y2_MS_PINS && PIN_EXISTS(Y2_MS3) WRITE(Y2_MS3_PIN, ms3); #endif break; #endif - #if HAS_SOME_Z_MICROSTEPS + #if HAS_SOME_Z_MS_PINS case 2: - #if HAS_Z_MICROSTEPS && PIN_EXISTS(Z_MS3) + #if HAS_Z_MS_PINS && PIN_EXISTS(Z_MS3) WRITE(Z_MS3_PIN, ms3); #endif - #if HAS_Z2_MICROSTEPS && PIN_EXISTS(Z2_MS3) + #if HAS_Z2_MS_PINS && PIN_EXISTS(Z2_MS3) WRITE(Z2_MS3_PIN, ms3); #endif - #if HAS_Z3_MICROSTEPS && PIN_EXISTS(Z3_MS3) + #if HAS_Z3_MS_PINS && PIN_EXISTS(Z3_MS3) WRITE(Z3_MS3_PIN, ms3); #endif - #if HAS_Z4_MICROSTEPS && PIN_EXISTS(Z4_MS3) + #if HAS_Z4_MS_PINS && PIN_EXISTS(Z4_MS3) WRITE(Z4_MS3_PIN, ms3); #endif break; #endif - #if HAS_E0_MICROSTEPS && PIN_EXISTS(E0_MS3) + #if HAS_E0_MS_PINS && PIN_EXISTS(E0_MS3) case 3: WRITE(E0_MS3_PIN, ms3); break; #endif - #if HAS_E1_MICROSTEPS && PIN_EXISTS(E1_MS3) + #if HAS_E1_MS_PINS && PIN_EXISTS(E1_MS3) case 4: WRITE(E1_MS3_PIN, ms3); break; #endif - #if HAS_E2_MICROSTEPS && PIN_EXISTS(E2_MS3) + #if HAS_E2_MS_PINS && PIN_EXISTS(E2_MS3) case 5: WRITE(E2_MS3_PIN, ms3); break; #endif - #if HAS_E3_MICROSTEPS && PIN_EXISTS(E3_MS3) + #if HAS_E3_MS_PINS && PIN_EXISTS(E3_MS3) case 6: WRITE(E3_MS3_PIN, ms3); break; #endif - #if HAS_E4_MICROSTEPS && PIN_EXISTS(E4_MS3) + #if HAS_E4_MS_PINS && PIN_EXISTS(E4_MS3) case 7: WRITE(E4_MS3_PIN, ms3); break; #endif - #if HAS_E5_MICROSTEPS && PIN_EXISTS(E5_MS3) + #if HAS_E5_MS_PINS && PIN_EXISTS(E5_MS3) case 8: WRITE(E5_MS3_PIN, ms3); break; #endif - #if HAS_E6_MICROSTEPS && PIN_EXISTS(E6_MS3) + #if HAS_E6_MS_PINS && PIN_EXISTS(E6_MS3) case 9: WRITE(E6_MS3_PIN, ms3); break; #endif - #if HAS_E7_MICROSTEPS && PIN_EXISTS(E7_MS3) + #if HAS_E7_MS_PINS && PIN_EXISTS(E7_MS3) case 10: WRITE(E7_MS3_PIN, ms3); break; #endif } @@ -3144,95 +3416,76 @@ void Stepper::report_positions() { } void Stepper::microstep_readings() { - SERIAL_ECHOLNPGM("MS1|MS2|MS3 Pins"); - #if HAS_X_MICROSTEPS - SERIAL_ECHOPGM("X: "); - SERIAL_CHAR('0' + READ(X_MS1_PIN), '0' + READ(X_MS2_PIN) - #if PIN_EXISTS(X_MS3) - , '0' + READ(X_MS3_PIN) - #endif - ); + #define PIN_CHAR(P) SERIAL_CHAR('0' + READ(P##_PIN)) + #define MS_LINE(A) do{ SERIAL_ECHOPGM(" " STRINGIFY(A) ":"); PIN_CHAR(A##_MS1); PIN_CHAR(A##_MS2); }while(0) + SERIAL_ECHOPGM("MS1|2|3 Pins"); + #if HAS_X_MS_PINS + MS_LINE(X); + #if PIN_EXISTS(X_MS3) + PIN_CHAR(X_MS3); + #endif #endif - #if HAS_Y_MICROSTEPS - SERIAL_ECHOPGM("Y: "); - SERIAL_CHAR('0' + READ(Y_MS1_PIN), '0' + READ(Y_MS2_PIN) - #if PIN_EXISTS(Y_MS3) - , '0' + READ(Y_MS3_PIN) - #endif - ); + #if HAS_Y_MS_PINS + MS_LINE(Y); + #if PIN_EXISTS(Y_MS3) + PIN_CHAR(Y_MS3); + #endif #endif - #if HAS_Z_MICROSTEPS - SERIAL_ECHOPGM("Z: "); - SERIAL_CHAR('0' + READ(Z_MS1_PIN), '0' + READ(Z_MS2_PIN) - #if PIN_EXISTS(Z_MS3) - , '0' + READ(Z_MS3_PIN) - #endif - ); + #if HAS_Z_MS_PINS + MS_LINE(Z); + #if PIN_EXISTS(Z_MS3) + PIN_CHAR(Z_MS3); + #endif #endif - #if HAS_E0_MICROSTEPS - SERIAL_ECHOPGM("E0: "); - SERIAL_CHAR('0' + READ(E0_MS1_PIN), '0' + READ(E0_MS2_PIN) - #if PIN_EXISTS(E0_MS3) - , '0' + READ(E0_MS3_PIN) - #endif - ); + #if HAS_E0_MS_PINS + MS_LINE(E0); + #if PIN_EXISTS(E0_MS3) + PIN_CHAR(E0_MS3); + #endif #endif - #if HAS_E1_MICROSTEPS - SERIAL_ECHOPGM("E1: "); - SERIAL_CHAR('0' + READ(E1_MS1_PIN), '0' + READ(E1_MS2_PIN) - #if PIN_EXISTS(E1_MS3) - , '0' + READ(E1_MS3_PIN) - #endif - ); + #if HAS_E1_MS_PINS + MS_LINE(E1); + #if PIN_EXISTS(E1_MS3) + PIN_CHAR(E1_MS3); + #endif #endif - #if HAS_E2_MICROSTEPS - SERIAL_ECHOPGM("E2: "); - SERIAL_CHAR('0' + READ(E2_MS1_PIN), '0' + READ(E2_MS2_PIN) - #if PIN_EXISTS(E2_MS3) - , '0' + READ(E2_MS3_PIN) - #endif - ); + #if HAS_E2_MS_PINS + MS_LINE(E2); + #if PIN_EXISTS(E2_MS3) + PIN_CHAR(E2_MS3); + #endif #endif - #if HAS_E3_MICROSTEPS - SERIAL_ECHOPGM("E3: "); - SERIAL_CHAR('0' + READ(E3_MS1_PIN), '0' + READ(E3_MS2_PIN) - #if PIN_EXISTS(E3_MS3) - , '0' + READ(E3_MS3_PIN) - #endif - ); + #if HAS_E3_MS_PINS + MS_LINE(E3); + #if PIN_EXISTS(E3_MS3) + PIN_CHAR(E3_MS3); + #endif #endif - #if HAS_E4_MICROSTEPS - SERIAL_ECHOPGM("E4: "); - SERIAL_CHAR('0' + READ(E4_MS1_PIN), '0' + READ(E4_MS2_PIN) - #if PIN_EXISTS(E4_MS3) - , '0' + READ(E4_MS3_PIN) - #endif - ); + #if HAS_E4_MS_PINS + MS_LINE(E4); + #if PIN_EXISTS(E4_MS3) + PIN_CHAR(E4_MS3); + #endif #endif - #if HAS_E5_MICROSTEPS - SERIAL_ECHOPGM("E5: "); - SERIAL_CHAR('0' + READ(E5_MS1_PIN), '0' + READ(E5_MS2_PIN) - #if PIN_EXISTS(E5_MS3) - , '0' + READ(E5_MS3_PIN) - #endif - ); + #if HAS_E5_MS_PINS + MS_LINE(E5); + #if PIN_EXISTS(E5_MS3) + PIN_CHAR(E5_MS3); + #endif #endif - #if HAS_E6_MICROSTEPS - SERIAL_ECHOPGM("E6: "); - SERIAL_CHAR('0' + READ(E6_MS1_PIN), '0' + READ(E6_MS2_PIN) - #if PIN_EXISTS(E6_MS3) - , '0' + READ(E6_MS3_PIN) - #endif - ); + #if HAS_E6_MS_PINS + MS_LINE(E6); + #if PIN_EXISTS(E6_MS3) + PIN_CHAR(E6_MS3); + #endif #endif - #if HAS_E7_MICROSTEPS - SERIAL_ECHOPGM("E7: "); - SERIAL_CHAR('0' + READ(E7_MS1_PIN), '0' + READ(E7_MS2_PIN) - #if PIN_EXISTS(E7_MS3) - , '0' + READ(E7_MS3_PIN) - #endif - ); + #if HAS_E7_MS_PINS + MS_LINE(E7); + #if PIN_EXISTS(E7_MS3) + PIN_CHAR(E7_MS3); + #endif #endif + SERIAL_EOL(); } #endif // HAS_MICROSTEPS diff --git a/Marlin/src/module/stepper.h b/Marlin/src/module/stepper.h index 6671b946dfcf..572c3f3f9b2d 100644 --- a/Marlin/src/module/stepper.h +++ b/Marlin/src/module/stepper.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -38,7 +38,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Grbl. If not, see . + * along with Grbl. If not, see . */ #include "../inc/MarlinConfig.h" @@ -191,7 +191,6 @@ #error "Expected at least one of MINIMUM_STEPPER_PULSE or MAXIMUM_STEPPER_RATE to be defined" #endif - // But the user could be enforcing a minimum time, so the loop time is #define ISR_LOOP_CYCLES (ISR_LOOP_BASE_CYCLES + _MAX(MIN_STEPPER_PULSE_CYCLES, MIN_ISR_LOOP_CYCLES)) @@ -230,8 +229,10 @@ #define MAX_STEP_ISR_FREQUENCY_2X ((F_CPU) / ISR_EXECUTION_CYCLES(2)) #define MAX_STEP_ISR_FREQUENCY_1X ((F_CPU) / ISR_EXECUTION_CYCLES(1)) -// The minimum allowable frequency for step smoothing will be 1/10 of the maximum nominal frequency (in Hz) -#define MIN_STEP_ISR_FREQUENCY MAX_STEP_ISR_FREQUENCY_1X +// The minimum step ISR rate used by ADAPTIVE_STEP_SMOOTHING to target 50% CPU usage +// This does not account for the possibility of multi-stepping. +// Perhaps DISABLE_MULTI_STEPPING should be required with ADAPTIVE_STEP_SMOOTHING. +#define MIN_STEP_ISR_FREQUENCY (MAX_STEP_ISR_FREQUENCY_1X / 2) // // Stepper class definition @@ -240,16 +241,29 @@ class Stepper { public: - #if HAS_EXTRA_ENDSTOPS || ENABLED(Z_STEPPER_AUTO_ALIGN) + #if EITHER(HAS_EXTRA_ENDSTOPS, Z_STEPPER_AUTO_ALIGN) static bool separate_multi_axis; #endif - #if HAS_MOTOR_CURRENT_PWM - #ifndef PWM_MOTOR_CURRENT - #define PWM_MOTOR_CURRENT DEFAULT_PWM_MOTOR_CURRENT + #if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM + #if HAS_MOTOR_CURRENT_PWM + #ifndef PWM_MOTOR_CURRENT + #define PWM_MOTOR_CURRENT DEFAULT_PWM_MOTOR_CURRENT + #endif + #define MOTOR_CURRENT_COUNT 3 + #elif HAS_MOTOR_CURRENT_SPI + static constexpr uint32_t digipot_count[] = DIGIPOT_MOTOR_CURRENT; + #define MOTOR_CURRENT_COUNT COUNT(Stepper::digipot_count) #endif - static uint32_t motor_current_setting[3]; static bool initialized; + static uint32_t motor_current_setting[MOTOR_CURRENT_COUNT]; // Initialized by settings.load() + #endif + + // Last-moved extruder, as set when the last movement was fetched from planner + #if HAS_MULTI_EXTRUDER + static uint8_t last_moved_extruder; + #else + static constexpr uint8_t last_moved_extruder = 0; #endif private: @@ -261,13 +275,6 @@ class Stepper { static bool abort_current_block; // Signals to the stepper that current block should be aborted - // Last-moved extruder, as set when the last movement was fetched from planner - #if EXTRUDERS < 2 - static constexpr uint8_t last_moved_extruder = 0; - #elif DISABLED(MIXING_EXTRUDER) - static uint8_t last_moved_extruder; - #endif - #if ENABLED(X_DUAL_ENDSTOPS) static bool locked_X_motor, locked_X2_motor; #endif @@ -303,7 +310,7 @@ class Stepper { decelerate_after, // The point from where we need to start decelerating step_event_count; // The total event count for the current block - #if EXTRUDERS > 1 || ENABLED(MIXING_EXTRUDER) + #if EITHER(HAS_MULTI_EXTRUDER, MIXING_EXTRUDER) static uint8_t stepper_extruder; #else static constexpr uint8_t stepper_extruder = 0; @@ -334,28 +341,44 @@ class Stepper { static uint32_t nextBabystepISR; #endif + #if ENABLED(DIRECT_STEPPING) + static page_step_state_t page_step_state; + #endif + static int32_t ticks_nominal; #if DISABLED(S_CURVE_ACCELERATION) static uint32_t acc_step_rate; // needed for deceleration start point #endif - // // Exact steps at which an endstop was triggered - // static xyz_long_t endstops_trigsteps; - // // Positions of stepper motors, in step units - // static xyze_long_t count_position; - // - // Current direction of stepper motors (+1 or -1) - // + // Current stepper motor directions (+1 or -1) static xyze_int8_t count_direction; - public: + #if ENABLED(LASER_POWER_INLINE_TRAPEZOID) + + typedef struct { + bool enabled; // Trapezoid needed flag (i.e., laser on, planner in control) + uint8_t cur_power; // Current laser power + bool cruise_set; // Power set up for cruising? + + #if DISABLED(LASER_POWER_INLINE_TRAPEZOID_CONT) + uint32_t last_step_count, // Step count from the last update + acc_step_count; // Bresenham counter for laser accel/decel + #else + uint16_t till_update; // Countdown to the next update + #endif + } stepper_laser_t; + static stepper_laser_t laser_trap; + + #endif + + public: // Initialize stepper hardware static void init(); @@ -411,8 +434,20 @@ class Stepper { static void set_axis_position(const AxisEnum a, const int32_t &v); // Report the positions of the steppers, in steps + static void report_a_position(const xyz_long_t &pos); static void report_positions(); + // Discard current block and free any resources + FORCE_INLINE static void discard_current_block() { + #if ENABLED(DIRECT_STEPPING) + if (IS_PAGE(current_block)) + page_manager.free_page(current_block->page_idx); + #endif + current_block = nullptr; + axis_did_move = 0; + planner.release_current_block(); + } + // Quickly stop all steppers FORCE_INLINE static void quick_stop() { abort_current_block = true; } @@ -422,24 +457,15 @@ class Stepper { // The last movement direction was not null on the specified axis. Note that motor direction is not necessarily the same. FORCE_INLINE static bool axis_is_moving(const AxisEnum axis) { return TEST(axis_did_move, axis); } - // The extruder associated to the last movement - FORCE_INLINE static uint8_t movement_extruder() { - return (0 - #if EXTRUDERS > 1 && DISABLED(MIXING_EXTRUDER) - + last_moved_extruder - #endif - ); - } - // Handle a triggered endstop static void endstop_triggered(const AxisEnum axis); // Triggered position of an axis in steps static int32_t triggered_position(const AxisEnum axis); - #if HAS_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM - static void digitalPotWrite(const int16_t address, const int16_t value); - static void digipot_current(const uint8_t driver, const int16_t current); + #if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM + static void set_digipot_value_spi(const int16_t address, const int16_t value); + static void set_digipot_current(const uint8_t driver, const int16_t current); #endif #if HAS_MICROSTEPS @@ -448,7 +474,7 @@ class Stepper { static void microstep_readings(); #endif - #if HAS_EXTRA_ENDSTOPS || ENABLED(Z_STEPPER_AUTO_ALIGN) + #if EITHER(HAS_EXTRA_ENDSTOPS, Z_STEPPER_AUTO_ALIGN) FORCE_INLINE static void set_separate_multi_axis(const bool state) { separate_multi_axis = state; } #endif #if ENABLED(X_DUAL_ENDSTOPS) @@ -460,7 +486,7 @@ class Stepper { FORCE_INLINE static void set_y2_lock(const bool state) { locked_Y2_motor = state; } #endif #if EITHER(Z_MULTI_ENDSTOPS, Z_STEPPER_AUTO_ALIGN) - FORCE_INLINE static void set_z_lock(const bool state) { locked_Z_motor = state; } + FORCE_INLINE static void set_z1_lock(const bool state) { locked_Z_motor = state; } FORCE_INLINE static void set_z2_lock(const bool state) { locked_Z2_motor = state; } #if NUM_Z_STEPPER_DRIVERS >= 3 FORCE_INLINE static void set_z3_lock(const bool state) { locked_Z3_motor = state; } @@ -468,6 +494,16 @@ class Stepper { FORCE_INLINE static void set_z4_lock(const bool state) { locked_Z4_motor = state; } #endif #endif + static inline void set_all_z_lock(const bool lock, const int8_t except=-1) { + set_z1_lock(lock ^ (except == 0)); + set_z2_lock(lock ^ (except == 1)); + #if NUM_Z_STEPPER_DRIVERS >= 3 + set_z3_lock(lock ^ (except == 2)); + #if NUM_Z_STEPPER_DRIVERS >= 4 + set_z4_lock(lock ^ (except == 3)); + #endif + #endif + } #endif #if ENABLED(BABYSTEPPING) @@ -524,7 +560,7 @@ class Stepper { // In case of high-performance processor, it is able to calculate in real-time timer = uint32_t(STEPPER_TIMER_RATE) / step_rate; #else - constexpr uint32_t min_step_rate = F_CPU / 500000U; + constexpr uint32_t min_step_rate = (F_CPU) / 500000U; NOLESS(step_rate, min_step_rate); step_rate -= min_step_rate; // Correct for minimal speed if (step_rate >= (8 * 256)) { // higher step rate @@ -552,7 +588,7 @@ class Stepper { static int32_t _eval_bezier_curve(const uint32_t curr_step); #endif - #if HAS_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM + #if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM static void digipot_init(); #endif diff --git a/Marlin/src/module/stepper/L64xx.cpp b/Marlin/src/module/stepper/L64xx.cpp index 74f2e12feda9..3e2bf0944666 100644 --- a/Marlin/src/module/stepper/L64xx.cpp +++ b/Marlin/src/module/stepper/L64xx.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/module/stepper/L64xx.h b/Marlin/src/module/stepper/L64xx.h index 4449618e0bec..9c8b0b1bddee 100644 --- a/Marlin/src/module/stepper/L64xx.h +++ b/Marlin/src/module/stepper/L64xx.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -45,7 +45,7 @@ #if AXIS_IS_L64XX(X) extern L64XX_CLASS(X) stepperX; #define X_ENABLE_INIT() NOOP - #define X_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperX.free()) + #define X_ENABLE_WRITE(STATE) (STATE ? stepperX.hardStop() : stepperX.free()) #define X_ENABLE_READ() (stepperX.getStatus() & STATUS_HIZ) #if AXIS_DRIVER_TYPE_X(L6474) #define X_DIR_INIT() SET_OUTPUT(X_DIR_PIN) @@ -65,7 +65,7 @@ #if AXIS_IS_L64XX(Y) extern L64XX_CLASS(Y) stepperY; #define Y_ENABLE_INIT() NOOP - #define Y_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperY.free()) + #define Y_ENABLE_WRITE(STATE) (STATE ? stepperY.hardStop() : stepperY.free()) #define Y_ENABLE_READ() (stepperY.getStatus() & STATUS_HIZ) #if AXIS_DRIVER_TYPE_Y(L6474) #define Y_DIR_INIT() SET_OUTPUT(Y_DIR_PIN) @@ -85,7 +85,7 @@ #if AXIS_IS_L64XX(Z) extern L64XX_CLASS(Z) stepperZ; #define Z_ENABLE_INIT() NOOP - #define Z_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperZ.free()) + #define Z_ENABLE_WRITE(STATE) (STATE ? stepperZ.hardStop() : stepperZ.free()) #define Z_ENABLE_READ() (stepperZ.getStatus() & STATUS_HIZ) #if AXIS_DRIVER_TYPE_Z(L6474) #define Z_DIR_INIT() SET_OUTPUT(Z_DIR_PIN) @@ -105,7 +105,7 @@ #if HAS_X2_ENABLE && AXIS_IS_L64XX(X2) extern L64XX_CLASS(X2) stepperX2; #define X2_ENABLE_INIT() NOOP - #define X2_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperX2.free()) + #define X2_ENABLE_WRITE(STATE) (STATE ? stepperX2.hardStop() : stepperX2.free()) #define X2_ENABLE_READ() (stepperX2.getStatus() & STATUS_HIZ) #if AXIS_DRIVER_TYPE_X2(L6474) #define X2_DIR_INIT() SET_OUTPUT(X2_DIR_PIN) @@ -126,7 +126,7 @@ #if HAS_Y2_ENABLE && AXIS_IS_L64XX(Y2) extern L64XX_CLASS(Y2) stepperY2; #define Y2_ENABLE_INIT() NOOP - #define Y2_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperY2.free()) + #define Y2_ENABLE_WRITE(STATE) (STATE ? stepperY2.hardStop() : stepperY2.free()) #define Y2_ENABLE_READ() (stepperY2.getStatus() & STATUS_HIZ) #if AXIS_DRIVER_TYPE_Y2(L6474) #define Y2_DIR_INIT() SET_OUTPUT(Y2_DIR_PIN) @@ -147,7 +147,7 @@ #if HAS_Z2_ENABLE && AXIS_IS_L64XX(Z2) extern L64XX_CLASS(Z2) stepperZ2; #define Z2_ENABLE_INIT() NOOP - #define Z2_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperZ2.free()) + #define Z2_ENABLE_WRITE(STATE) (STATE ? stepperZ2.hardStop() : stepperZ2.free()) #define Z2_ENABLE_READ() (stepperZ2.getStatus() & STATUS_HIZ) #if AXIS_DRIVER_TYPE_Z2(L6474) #define Z2_DIR_INIT() SET_OUTPUT(Z2_DIR_PIN) @@ -168,7 +168,7 @@ #if HAS_Z3_ENABLE && AXIS_IS_L64XX(Z3) extern L64XX_CLASS(Z3) stepperZ3; #define Z3_ENABLE_INIT() NOOP - #define Z3_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperZ3.free()) + #define Z3_ENABLE_WRITE(STATE) (STATE ? stepperZ3.hardStop() : stepperZ3.free()) #define Z3_ENABLE_READ() (stepperZ3.getStatus() & STATUS_HIZ) #if AXIS_DRIVER_TYPE_Z3(L6474) #define Z3_DIR_INIT() SET_OUTPUT(Z3_DIR_PIN) @@ -189,7 +189,7 @@ #if HAS_Z4_ENABLE && AXIS_IS_L64XX(Z4) extern L64XX_CLASS(Z4) stepperZ4; #define Z4_ENABLE_INIT() NOOP - #define Z4_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperZ4.free()) + #define Z4_ENABLE_WRITE(STATE) (STATE ? stepperZ4.hardStop() : stepperZ4.free()) #define Z4_ENABLE_READ() (stepperZ4.getStatus() & STATUS_HIZ) #if AXIS_DRIVER_TYPE_Z4(L6474) #define Z4_DIR_INIT() SET_OUTPUT(Z4_DIR_PIN) @@ -210,7 +210,7 @@ #if AXIS_IS_L64XX(E0) extern L64XX_CLASS(E0) stepperE0; #define E0_ENABLE_INIT() NOOP - #define E0_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperE0.free()) + #define E0_ENABLE_WRITE(STATE) (STATE ? stepperE0.hardStop() : stepperE0.free()) #define E0_ENABLE_READ() (stepperE0.getStatus() & STATUS_HIZ) #if AXIS_DRIVER_TYPE_E0(L6474) #define E0_DIR_INIT() SET_OUTPUT(E0_DIR_PIN) @@ -221,7 +221,7 @@ #define E0_DIR_WRITE(STATE) L64XX_DIR_WRITE(E0, STATE) #define E0_DIR_READ() (stepper##E0.getStatus() & STATUS_DIR); #if AXIS_DRIVER_TYPE_E0(L6470) - #define DISABLE_STEPPER_E0() do{ stepperE0.free(); CBI(axis_known_position, E_AXIS); }while(0) + #define DISABLE_STEPPER_E0() do{ stepperE0.free(); }while(0) #endif #endif #endif @@ -230,7 +230,7 @@ #if AXIS_IS_L64XX(E1) extern L64XX_CLASS(E1) stepperE1; #define E1_ENABLE_INIT() NOOP - #define E1_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperE1.free()) + #define E1_ENABLE_WRITE(STATE) (STATE ? stepperE1.hardStop() : stepperE1.free()) #define E1_ENABLE_READ() (stepperE1.getStatus() & STATUS_HIZ) #if AXIS_DRIVER_TYPE_E1(L6474) #define E1_DIR_INIT() SET_OUTPUT(E1_DIR_PIN) @@ -241,7 +241,7 @@ #define E1_DIR_WRITE(STATE) L64XX_DIR_WRITE(E1, STATE) #define E1_DIR_READ() (stepper##E1.getStatus() & STATUS_DIR); #if AXIS_DRIVER_TYPE_E1(L6470) - #define DISABLE_STEPPER_E1() do{ stepperE1.free(); CBI(axis_known_position, E_AXIS); }while(0) + #define DISABLE_STEPPER_E1() do{ stepperE1.free(); }while(0) #endif #endif #endif @@ -250,7 +250,7 @@ #if AXIS_IS_L64XX(E2) extern L64XX_CLASS(E2) stepperE2; #define E2_ENABLE_INIT() NOOP - #define E2_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperE2.free()) + #define E2_ENABLE_WRITE(STATE) (STATE ? stepperE2.hardStop() : stepperE2.free()) #define E2_ENABLE_READ() (stepperE2.getStatus() & STATUS_HIZ) #if AXIS_DRIVER_TYPE_E2(L6474) #define E2_DIR_INIT() SET_OUTPUT(E2_DIR_PIN) @@ -261,7 +261,7 @@ #define E2_DIR_WRITE(STATE) L64XX_DIR_WRITE(E2, STATE) #define E2_DIR_READ() (stepper##E2.getStatus() & STATUS_DIR); #if AXIS_DRIVER_TYPE_E2(L6470) - #define DISABLE_STEPPER_E2() do{ stepperE2.free(); CBI(axis_known_position, E_AXIS); }while(0) + #define DISABLE_STEPPER_E2() do{ stepperE2.free(); }while(0) #endif #endif #endif @@ -270,7 +270,7 @@ #if AXIS_IS_L64XX(E3) extern L64XX_CLASS(E3) stepperE3; #define E3_ENABLE_INIT() NOOP - #define E3_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperE3.free()) + #define E3_ENABLE_WRITE(STATE) (STATE ? stepperE3.hardStop() : stepperE3.free()) #define E3_ENABLE_READ() (stepperE3.getStatus() & STATUS_HIZ) #if AXIS_DRIVER_TYPE_E3(L6474) #define E3_DIR_INIT() SET_OUTPUT(E3_DIR_PIN) @@ -287,7 +287,7 @@ #if AXIS_IS_L64XX(E4) extern L64XX_CLASS(E4) stepperE4; #define E4_ENABLE_INIT() NOOP - #define E4_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperE4.free()) + #define E4_ENABLE_WRITE(STATE) (STATE ? stepperE4.hardStop() : stepperE4.free()) #define E4_ENABLE_READ() (stepperE4.getStatus() & STATUS_HIZ) #if AXIS_DRIVER_TYPE_E4(L6474) #define E4_DIR_INIT() SET_OUTPUT(E4_DIR_PIN) @@ -298,7 +298,7 @@ #define E4_DIR_WRITE(STATE) L64XX_DIR_WRITE(E4, STATE) #define E4_DIR_READ() (stepper##E4.getStatus() & STATUS_DIR); #if AXIS_DRIVER_TYPE_E4(L6470) - #define DISABLE_STEPPER_E4() do{ stepperE4.free(); CBI(axis_known_position, E_AXIS); }while(0) + #define DISABLE_STEPPER_E4() do{ stepperE4.free(); }while(0) #endif #endif #endif @@ -307,7 +307,7 @@ #if AXIS_IS_L64XX(E5) extern L64XX_CLASS(E5) stepperE5; #define E5_ENABLE_INIT() NOOP - #define E5_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperE5.free()) + #define E5_ENABLE_WRITE(STATE) (STATE ? stepperE5.hardStop() : stepperE5.free()) #define E5_ENABLE_READ() (stepperE5.getStatus() & STATUS_HIZ) #if AXIS_DRIVER_TYPE_E5(L6474) #define E5_DIR_INIT() SET_OUTPUT(E5_DIR_PIN) @@ -318,7 +318,7 @@ #define E5_DIR_WRITE(STATE) L64XX_DIR_WRITE(E5, STATE) #define E5_DIR_READ() (stepper##E5.getStatus() & STATUS_DIR); #if AXIS_DRIVER_TYPE_E5(L6470) - #define DISABLE_STEPPER_E5() do{ stepperE5.free(); CBI(axis_known_position, E_AXIS); }while(0) + #define DISABLE_STEPPER_E5() do{ stepperE5.free(); }while(0) #endif #endif #endif @@ -327,7 +327,7 @@ #if AXIS_IS_L64XX(E6) extern L64XX_CLASS(E6) stepperE6; #define E6_ENABLE_INIT() NOOP - #define E6_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperE6.free()) + #define E6_ENABLE_WRITE(STATE) (STATE ? stepperE6.hardStop() : stepperE6.free()) #define E6_ENABLE_READ() (stepperE6.getStatus() & STATUS_HIZ) #if AXIS_DRIVER_TYPE_E6(L6474) #define E6_DIR_INIT() SET_OUTPUT(E6_DIR_PIN) @@ -338,7 +338,7 @@ #define E6_DIR_WRITE(STATE) L64XX_DIR_WRITE(E6, STATE) #define E6_DIR_READ() (stepper##E6.getStatus() & STATUS_DIR); #if AXIS_DRIVER_TYPE_E6(L6470) - #define DISABLE_STEPPER_E6() do{ stepperE6.free(); CBI(axis_known_position, E_AXIS); }while(0) + #define DISABLE_STEPPER_E6() do{ stepperE6.free(); }while(0) #endif #endif #endif @@ -347,7 +347,7 @@ #if AXIS_IS_L64XX(E7) extern L64XX_CLASS(E7) stepperE7; #define E7_ENABLE_INIT() NOOP - #define E7_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperE7.free()) + #define E7_ENABLE_WRITE(STATE) (STATE ? stepperE7.hardStop() : stepperE7.free()) #define E7_ENABLE_READ() (stepperE7.getStatus() & STATUS_HIZ) #if AXIS_DRIVER_TYPE_E7(L6474) #define E7_DIR_INIT() SET_OUTPUT(E7_DIR_PIN) @@ -358,7 +358,7 @@ #define E7_DIR_WRITE(STATE) L64XX_DIR_WRITE(E7, STATE) #define E7_DIR_READ() (stepper##E7.getStatus() & STATUS_DIR); #if AXIS_DRIVER_TYPE_E7(L6470) - #define DISABLE_STEPPER_E7() do{ stepperE7.free(); CBI(axis_known_position, E_AXIS); }while(0) + #define DISABLE_STEPPER_E7() do{ stepperE7.free(); }while(0) #endif #endif #endif diff --git a/Marlin/src/module/stepper/TMC26X.cpp b/Marlin/src/module/stepper/TMC26X.cpp index 08c0b3e7828f..926f1a4e089f 100644 --- a/Marlin/src/module/stepper/TMC26X.cpp +++ b/Marlin/src/module/stepper/TMC26X.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -30,7 +30,7 @@ // // TMC26X Driver objects and inits // -#if HAS_DRIVER(TMC26X) +#if HAS_TMC26X #include "TMC26X.h" @@ -141,4 +141,4 @@ void tmc26x_init_to_defaults() { #endif } -#endif // TMC26X +#endif // HAS_TMC26X diff --git a/Marlin/src/module/stepper/TMC26X.h b/Marlin/src/module/stepper/TMC26X.h index d44bc19a7486..8977266b47bf 100644 --- a/Marlin/src/module/stepper/TMC26X.h +++ b/Marlin/src/module/stepper/TMC26X.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -32,7 +32,7 @@ #include #if defined(STM32GENERIC) && defined(STM32F7) - #include "../../HAL/HAL_STM32_F4_F7/STM32F7/TMC2660.h" + #include "../../HAL/STM32_F4_F7/STM32F7/TMC2660.h" #else #include #endif diff --git a/Marlin/src/module/stepper/indirection.cpp b/Marlin/src/module/stepper/indirection.cpp index d468a2afdd62..6f9ac9ba0ab1 100644 --- a/Marlin/src/module/stepper/indirection.cpp +++ b/Marlin/src/module/stepper/indirection.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -33,21 +33,13 @@ #include "indirection.h" void restore_stepper_drivers() { - #if HAS_TRINAMIC - restore_trinamic_drivers(); - #endif + TERN_(HAS_TRINAMIC_CONFIG, restore_trinamic_drivers()); } void reset_stepper_drivers() { #if HAS_DRIVER(TMC26X) tmc26x_init_to_defaults(); #endif - - #if HAS_L64XX - L64xxManager.init_to_defaults(); - #endif - - #if HAS_TRINAMIC - reset_trinamic_drivers(); - #endif + TERN_(HAS_L64XX, L64xxManager.init_to_defaults()); + TERN_(HAS_TRINAMIC_CONFIG, reset_trinamic_drivers()); } diff --git a/Marlin/src/module/stepper/indirection.h b/Marlin/src/module/stepper/indirection.h index 295c3aca2e90..ec0d63a89d97 100644 --- a/Marlin/src/module/stepper/indirection.h +++ b/Marlin/src/module/stepper/indirection.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -40,7 +40,7 @@ #include "TMC26X.h" #endif -#if HAS_TRINAMIC +#if HAS_TRINAMIC_CONFIG #include "trinamic.h" #endif @@ -185,18 +185,18 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #ifndef Z4_ENABLE_INIT #define Z4_ENABLE_INIT() SET_OUTPUT(Z4_ENABLE_PIN) #define Z4_ENABLE_WRITE(STATE) WRITE(Z4_ENABLE_PIN,STATE) - #define Z4_ENABLE_READ() READ(Z4_ENABLE_PIN) + #define Z4_ENABLE_READ() bool(READ(Z4_ENABLE_PIN)) #endif #ifndef Z4_DIR_INIT #define Z4_DIR_INIT() SET_OUTPUT(Z4_DIR_PIN) #define Z4_DIR_WRITE(STATE) WRITE(Z4_DIR_PIN,STATE) - #define Z4_DIR_READ() READ(Z4_DIR_PIN) + #define Z4_DIR_READ() bool(READ(Z4_DIR_PIN)) #endif - #define Z4_STEP_INIT SET_OUTPUT(Z4_STEP_PIN) + #define Z4_STEP_INIT() SET_OUTPUT(Z4_STEP_PIN) #ifndef Z4_STEP_WRITE #define Z4_STEP_WRITE(STATE) WRITE(Z4_STEP_PIN,STATE) #endif - #define Z4_STEP_READ READ(Z4_STEP_PIN) + #define Z4_STEP_READ() bool(READ(Z4_STEP_PIN)) #else #define Z4_DIR_WRITE(STATE) NOOP #endif @@ -840,15 +840,22 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset // // Axis steppers enable / disable macros // +#define FORGET_AXIS(A) TERN(HOME_AFTER_DEACTIVATE, set_axis_never_homed(A), CBI(axis_known_position, A)) #define ENABLE_AXIS_X() do{ ENABLE_STEPPER_X(); ENABLE_STEPPER_X2(); }while(0) -#define DISABLE_AXIS_X() do{ DISABLE_STEPPER_X(); DISABLE_STEPPER_X2(); CBI(axis_known_position, X_AXIS); }while(0) +#define DISABLE_AXIS_X() do{ DISABLE_STEPPER_X(); DISABLE_STEPPER_X2(); FORGET_AXIS(X_AXIS); }while(0) #define ENABLE_AXIS_Y() do{ ENABLE_STEPPER_Y(); ENABLE_STEPPER_Y2(); }while(0) -#define DISABLE_AXIS_Y() do{ DISABLE_STEPPER_Y(); DISABLE_STEPPER_Y2(); CBI(axis_known_position, Y_AXIS); }while(0) +#define DISABLE_AXIS_Y() do{ DISABLE_STEPPER_Y(); DISABLE_STEPPER_Y2(); FORGET_AXIS(Y_AXIS); }while(0) #define ENABLE_AXIS_Z() do{ ENABLE_STEPPER_Z(); ENABLE_STEPPER_Z2(); ENABLE_STEPPER_Z3(); ENABLE_STEPPER_Z4(); }while(0) -#define DISABLE_AXIS_Z() do{ DISABLE_STEPPER_Z(); DISABLE_STEPPER_Z2(); DISABLE_STEPPER_Z3(); DISABLE_STEPPER_Z4(); CBI(axis_known_position, Z_AXIS); }while(0) + +#ifdef Z_AFTER_DEACTIVATE + #define Z_RESET() do{ current_position.z = Z_AFTER_DEACTIVATE; sync_plan_position(); }while(0) +#else + #define Z_RESET() +#endif +#define DISABLE_AXIS_Z() do{ DISABLE_STEPPER_Z(); DISABLE_STEPPER_Z2(); DISABLE_STEPPER_Z3(); DISABLE_STEPPER_Z4(); FORGET_AXIS(Z_AXIS); Z_RESET(); }while(0) // // Extruder steppers enable / disable macros @@ -865,14 +872,14 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #endif #ifndef ENABLE_AXIS_E0 - #if E_STEPPERS > 0 && HAS_E0_ENABLE + #if E_STEPPERS && HAS_E0_ENABLE #define ENABLE_AXIS_E0() ENABLE_STEPPER_E0() #else #define ENABLE_AXIS_E0() NOOP #endif #endif #ifndef DISABLE_AXIS_E0 - #if E_STEPPERS > 0 && HAS_E0_ENABLE + #if E_STEPPERS && HAS_E0_ENABLE #define DISABLE_AXIS_E0() DISABLE_STEPPER_E0() #else #define DISABLE_AXIS_E0() NOOP diff --git a/Marlin/src/module/stepper/trinamic.cpp b/Marlin/src/module/stepper/trinamic.cpp index 0b14aaf64779..d5a861d71ba0 100644 --- a/Marlin/src/module/stepper/trinamic.cpp +++ b/Marlin/src/module/stepper/trinamic.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -27,7 +27,7 @@ #include "../../inc/MarlinConfig.h" -#if HAS_TRINAMIC +#if HAS_TRINAMIC_CONFIG #include "trinamic.h" #include "../stepper.h" @@ -49,8 +49,12 @@ enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E }; #define __TMC_SPI_DEFINE(IC, ST, L, AI) TMCMarlin stepper##ST(ST##_CS_PIN, float(ST##_RSENSE), ST##_CHAIN_POS) #endif -#define TMC_UART_HW_DEFINE(IC, ST, L, AI) TMCMarlin stepper##ST(&ST##_HARDWARE_SERIAL, float(ST##_RSENSE), ST##_SLAVE_ADDRESS) -#define TMC_UART_SW_DEFINE(IC, ST, L, AI) TMCMarlin stepper##ST(ST##_SERIAL_RX_PIN, ST##_SERIAL_TX_PIN, float(ST##_RSENSE), ST##_SLAVE_ADDRESS, ST##_SERIAL_RX_PIN > -1) +#if ENABLED(TMC_SERIAL_MULTIPLEXER) + #define TMC_UART_HW_DEFINE(IC, ST, L, AI) TMCMarlin stepper##ST(&ST##_HARDWARE_SERIAL, float(ST##_RSENSE), ST##_SLAVE_ADDRESS, SERIAL_MUL_PIN1, SERIAL_MUL_PIN2) +#else + #define TMC_UART_HW_DEFINE(IC, ST, L, AI) TMCMarlin stepper##ST(&ST##_HARDWARE_SERIAL, float(ST##_RSENSE), ST##_SLAVE_ADDRESS) +#endif +#define TMC_UART_SW_DEFINE(IC, ST, L, AI) TMCMarlin stepper##ST(ST##_SERIAL_RX_PIN, ST##_SERIAL_TX_PIN, float(ST##_RSENSE), ST##_SLAVE_ADDRESS) #define _TMC_SPI_DEFINE(IC, ST, AI) __TMC_SPI_DEFINE(IC, ST, TMC_##ST##_LABEL, AI) #define TMC_SPI_DEFINE(ST, AI) _TMC_SPI_DEFINE(ST##_DRIVER_TYPE, ST, AI##_AXIS) @@ -58,7 +62,7 @@ enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E }; #define _TMC_UART_DEFINE(SWHW, IC, ST, AI) TMC_UART_##SWHW##_DEFINE(IC, ST, TMC_##ST##_LABEL, AI) #define TMC_UART_DEFINE(SWHW, ST, AI) _TMC_UART_DEFINE(SWHW, ST##_DRIVER_TYPE, ST, AI##_AXIS) -#if ENABLED(DISTINCT_E_FACTORS) && E_STEPPERS > 1 +#if DISTINCT_E > 1 #define TMC_SPI_DEFINE_E(AI) TMC_SPI_DEFINE(E##AI, E##AI) #define TMC_UART_DEFINE_E(SWHW, AI) TMC_UART_DEFINE(SWHW, E##AI, E##AI) #else @@ -117,16 +121,12 @@ enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E }; #endif #ifndef TMC_BAUD_RATE - #if HAS_TMC_SW_SERIAL - // Reduce baud rate for boards not already overriding TMC_BAUD_RATE for software serial. - // Testing has shown that 115200 is not 100% reliable on AVR platforms, occasionally - // failing to read status properly. 32-bit platforms typically define an even lower - // TMC_BAUD_RATE, due to differences in how SoftwareSerial libraries work on different - // platforms. - #define TMC_BAUD_RATE 57600 - #else - #define TMC_BAUD_RATE 115200 - #endif + // Reduce baud rate for boards not already overriding TMC_BAUD_RATE for software serial. + // Testing has shown that 115200 is not 100% reliable on AVR platforms, occasionally + // failing to read status properly. 32-bit platforms typically define an even lower + // TMC_BAUD_RATE, due to differences in how SoftwareSerial libraries work on different + // platforms. + #define TMC_BAUD_RATE TERN(HAS_TMC_SW_SERIAL, 57600, 115200) #endif #if HAS_DRIVER(TMC2130) @@ -140,9 +140,7 @@ enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E }; chopconf.intpol = INTERPOLATE; chopconf.hend = chopper_timing.hend + 3; chopconf.hstrt = chopper_timing.hstrt - 1; - #if ENABLED(SQUARE_WAVE_STEPPING) - chopconf.dedge = true; - #endif + TERN_(SQUARE_WAVE_STEPPING, chopconf.dedge = true); st.CHOPCONF(chopconf.sr); st.rms_current(mA, HOLD_MULTIPLIER); @@ -160,11 +158,7 @@ enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E }; pwmconf.pwm_ampl = 180; st.PWMCONF(pwmconf.sr); - #if ENABLED(HYBRID_THRESHOLD) - st.set_pwm_thrs(hyb_thrs); - #else - UNUSED(hyb_thrs); - #endif + TERN(HYBRID_THRESHOLD, st.set_pwm_thrs(hyb_thrs), UNUSED(hyb_thrs)); st.GSTAT(); // Clear GSTAT } @@ -181,9 +175,7 @@ enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E }; chopconf.intpol = INTERPOLATE; chopconf.hend = chopper_timing.hend + 3; chopconf.hstrt = chopper_timing.hstrt - 1; - #if ENABLED(SQUARE_WAVE_STEPPING) - chopconf.dedge = true; - #endif + TERN_(SQUARE_WAVE_STEPPING, chopconf.dedge = true); st.CHOPCONF(chopconf.sr); st.rms_current(mA, HOLD_MULTIPLIER); @@ -204,11 +196,7 @@ enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E }; pwmconf.pwm_ofs = 36; st.PWMCONF(pwmconf.sr); - #if ENABLED(HYBRID_THRESHOLD) - st.set_pwm_thrs(hyb_thrs); - #else - UNUSED(hyb_thrs); - #endif + TERN(HYBRID_THRESHOLD, st.set_pwm_thrs(hyb_thrs), UNUSED(hyb_thrs)); st.GSTAT(); // Clear GSTAT } @@ -221,225 +209,272 @@ enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E }; #if AXIS_HAS_UART(X) #ifdef X_HARDWARE_SERIAL TMC_UART_DEFINE(HW, X, X); + #define X_HAS_HW_SERIAL 1 #else TMC_UART_DEFINE(SW, X, X); + #define X_HAS_SW_SERIAL 1 #endif #endif #if AXIS_HAS_UART(X2) #ifdef X2_HARDWARE_SERIAL TMC_UART_DEFINE(HW, X2, X); + #define X2_HAS_HW_SERIAL 1 #else TMC_UART_DEFINE(SW, X2, X); + #define X2_HAS_SW_SERIAL 1 #endif #endif #if AXIS_HAS_UART(Y) #ifdef Y_HARDWARE_SERIAL TMC_UART_DEFINE(HW, Y, Y); + #define Y_HAS_HW_SERIAL 1 #else TMC_UART_DEFINE(SW, Y, Y); + #define Y_HAS_SW_SERIAL 1 #endif #endif #if AXIS_HAS_UART(Y2) #ifdef Y2_HARDWARE_SERIAL TMC_UART_DEFINE(HW, Y2, Y); + #define Y2_HAS_HW_SERIAL 1 #else TMC_UART_DEFINE(SW, Y2, Y); + #define Y2_HAS_SW_SERIAL 1 #endif #endif #if AXIS_HAS_UART(Z) #ifdef Z_HARDWARE_SERIAL TMC_UART_DEFINE(HW, Z, Z); + #define Z_HAS_HW_SERIAL 1 #else TMC_UART_DEFINE(SW, Z, Z); + #define Z_HAS_SW_SERIAL 1 #endif #endif #if AXIS_HAS_UART(Z2) #ifdef Z2_HARDWARE_SERIAL TMC_UART_DEFINE(HW, Z2, Z); + #define Z2_HAS_HW_SERIAL 1 #else TMC_UART_DEFINE(SW, Z2, Z); + #define Z2_HAS_SW_SERIAL 1 #endif #endif #if AXIS_HAS_UART(Z3) #ifdef Z3_HARDWARE_SERIAL TMC_UART_DEFINE(HW, Z3, Z); + #define Z3_HAS_HW_SERIAL 1 #else TMC_UART_DEFINE(SW, Z3, Z); + #define Z3_HAS_SW_SERIAL 1 #endif #endif #if AXIS_HAS_UART(Z4) #ifdef Z4_HARDWARE_SERIAL TMC_UART_DEFINE(HW, Z4, Z); + #define Z4_HAS_HW_SERIAL 1 #else TMC_UART_DEFINE(SW, Z4, Z); + #define Z4_HAS_SW_SERIAL 1 #endif #endif #if AXIS_HAS_UART(E0) #ifdef E0_HARDWARE_SERIAL TMC_UART_DEFINE_E(HW, 0); + #define E0_HAS_HW_SERIAL 1 #else TMC_UART_DEFINE_E(SW, 0); + #define E0_HAS_SW_SERIAL 1 #endif #endif #if AXIS_HAS_UART(E1) #ifdef E1_HARDWARE_SERIAL TMC_UART_DEFINE_E(HW, 1); + #define E1_HAS_HW_SERIAL 1 #else TMC_UART_DEFINE_E(SW, 1); + #define E1_HAS_SW_SERIAL 1 #endif #endif #if AXIS_HAS_UART(E2) #ifdef E2_HARDWARE_SERIAL TMC_UART_DEFINE_E(HW, 2); + #define E2_HAS_HW_SERIAL 1 #else TMC_UART_DEFINE_E(SW, 2); + #define E2_HAS_SW_SERIAL 1 #endif #endif #if AXIS_HAS_UART(E3) #ifdef E3_HARDWARE_SERIAL TMC_UART_DEFINE_E(HW, 3); + #define E3_HAS_HW_SERIAL 1 #else TMC_UART_DEFINE_E(SW, 3); + #define E3_HAS_SW_SERIAL 1 #endif #endif #if AXIS_HAS_UART(E4) #ifdef E4_HARDWARE_SERIAL TMC_UART_DEFINE_E(HW, 4); + #define E4_HAS_HW_SERIAL 1 #else TMC_UART_DEFINE_E(SW, 4); + #define E4_HAS_SW_SERIAL 1 #endif #endif #if AXIS_HAS_UART(E5) #ifdef E5_HARDWARE_SERIAL TMC_UART_DEFINE_E(HW, 5); + #define E5_HAS_HW_SERIAL 1 #else TMC_UART_DEFINE_E(SW, 5); + #define E5_HAS_SW_SERIAL 1 #endif #endif #if AXIS_HAS_UART(E6) #ifdef E6_HARDWARE_SERIAL TMC_UART_DEFINE_E(HW, 6); + #define E6_HAS_HW_SERIAL 1 #else TMC_UART_DEFINE_E(SW, 6); + #define E6_HAS_SW_SERIAL 1 #endif #endif #if AXIS_HAS_UART(E7) #ifdef E7_HARDWARE_SERIAL TMC_UART_DEFINE_E(HW, 7); + #define E7_HAS_HW_SERIAL 1 #else TMC_UART_DEFINE_E(SW, 7); + #define E7_HAS_SW_SERIAL 1 #endif #endif + enum TMCAxis : uint8_t { X, Y, Z, X2, Y2, Z2, Z3, Z4, E0, E1, E2, E3, E4, E5, E6, E7, TOTAL }; + void tmc_serial_begin() { + #if HAS_TMC_HW_SERIAL + struct { + const void *ptr[TMCAxis::TOTAL]; + bool began(const TMCAxis a, const void * const p) { + LOOP_L_N(i, a) if (p == ptr[i]) return true; + ptr[a] = p; return false; + }; + } sp_helper; + + #define HW_SERIAL_BEGIN(A) do{ if (!sp_helper.began(TMCAxis::A, &A##_HARDWARE_SERIAL)) \ + A##_HARDWARE_SERIAL.begin(TMC_BAUD_RATE); }while(0) + #endif + #if AXIS_HAS_UART(X) #ifdef X_HARDWARE_SERIAL - X_HARDWARE_SERIAL.begin(TMC_BAUD_RATE); + HW_SERIAL_BEGIN(X); #else stepperX.beginSerial(TMC_BAUD_RATE); #endif #endif #if AXIS_HAS_UART(X2) #ifdef X2_HARDWARE_SERIAL - X2_HARDWARE_SERIAL.begin(TMC_BAUD_RATE); + HW_SERIAL_BEGIN(X2); #else stepperX2.beginSerial(TMC_BAUD_RATE); #endif #endif #if AXIS_HAS_UART(Y) #ifdef Y_HARDWARE_SERIAL - Y_HARDWARE_SERIAL.begin(TMC_BAUD_RATE); + HW_SERIAL_BEGIN(Y); #else stepperY.beginSerial(TMC_BAUD_RATE); #endif #endif #if AXIS_HAS_UART(Y2) #ifdef Y2_HARDWARE_SERIAL - Y2_HARDWARE_SERIAL.begin(TMC_BAUD_RATE); + HW_SERIAL_BEGIN(Y2); #else stepperY2.beginSerial(TMC_BAUD_RATE); #endif #endif #if AXIS_HAS_UART(Z) #ifdef Z_HARDWARE_SERIAL - Z_HARDWARE_SERIAL.begin(TMC_BAUD_RATE); + HW_SERIAL_BEGIN(Z); #else stepperZ.beginSerial(TMC_BAUD_RATE); #endif #endif #if AXIS_HAS_UART(Z2) #ifdef Z2_HARDWARE_SERIAL - Z2_HARDWARE_SERIAL.begin(TMC_BAUD_RATE); + HW_SERIAL_BEGIN(Z2); #else stepperZ2.beginSerial(TMC_BAUD_RATE); #endif #endif #if AXIS_HAS_UART(Z3) #ifdef Z3_HARDWARE_SERIAL - Z3_HARDWARE_SERIAL.begin(TMC_BAUD_RATE); + HW_SERIAL_BEGIN(Z3); #else stepperZ3.beginSerial(TMC_BAUD_RATE); #endif #endif #if AXIS_HAS_UART(Z4) #ifdef Z4_HARDWARE_SERIAL - Z4_HARDWARE_SERIAL.begin(TMC_BAUD_RATE); + HW_SERIAL_BEGIN(Z4); #else stepperZ4.beginSerial(TMC_BAUD_RATE); #endif #endif #if AXIS_HAS_UART(E0) #ifdef E0_HARDWARE_SERIAL - E0_HARDWARE_SERIAL.begin(TMC_BAUD_RATE); + HW_SERIAL_BEGIN(E0); #else stepperE0.beginSerial(TMC_BAUD_RATE); #endif #endif #if AXIS_HAS_UART(E1) #ifdef E1_HARDWARE_SERIAL - E1_HARDWARE_SERIAL.begin(TMC_BAUD_RATE); + HW_SERIAL_BEGIN(E1); #else stepperE1.beginSerial(TMC_BAUD_RATE); #endif #endif #if AXIS_HAS_UART(E2) #ifdef E2_HARDWARE_SERIAL - E2_HARDWARE_SERIAL.begin(TMC_BAUD_RATE); + HW_SERIAL_BEGIN(E2); #else stepperE2.beginSerial(TMC_BAUD_RATE); #endif #endif #if AXIS_HAS_UART(E3) #ifdef E3_HARDWARE_SERIAL - E3_HARDWARE_SERIAL.begin(TMC_BAUD_RATE); + HW_SERIAL_BEGIN(E3); #else stepperE3.beginSerial(TMC_BAUD_RATE); #endif #endif #if AXIS_HAS_UART(E4) #ifdef E4_HARDWARE_SERIAL - E4_HARDWARE_SERIAL.begin(TMC_BAUD_RATE); + HW_SERIAL_BEGIN(E4); #else stepperE4.beginSerial(TMC_BAUD_RATE); #endif #endif #if AXIS_HAS_UART(E5) #ifdef E5_HARDWARE_SERIAL - E5_HARDWARE_SERIAL.begin(TMC_BAUD_RATE); + HW_SERIAL_BEGIN(E5); #else stepperE5.beginSerial(TMC_BAUD_RATE); #endif #endif #if AXIS_HAS_UART(E6) #ifdef E6_HARDWARE_SERIAL - E6_HARDWARE_SERIAL.begin(TMC_BAUD_RATE); + HW_SERIAL_BEGIN(E6); #else stepperE6.beginSerial(TMC_BAUD_RATE); #endif #endif #if AXIS_HAS_UART(E7) #ifdef E7_HARDWARE_SERIAL - E7_HARDWARE_SERIAL.begin(TMC_BAUD_RATE); + HW_SERIAL_BEGIN(E7); #else stepperE7.beginSerial(TMC_BAUD_RATE); #endif @@ -464,9 +499,7 @@ enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E }; chopconf.intpol = INTERPOLATE; chopconf.hend = chopper_timing.hend + 3; chopconf.hstrt = chopper_timing.hstrt - 1; - #if ENABLED(SQUARE_WAVE_STEPPING) - chopconf.dedge = true; - #endif + TERN_(SQUARE_WAVE_STEPPING, chopconf.dedge = true); st.CHOPCONF(chopconf.sr); st.rms_current(mA, HOLD_MULTIPLIER); @@ -484,11 +517,7 @@ enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E }; pwmconf.pwm_ofs = 36; st.PWMCONF(pwmconf.sr); - #if ENABLED(HYBRID_THRESHOLD) - st.set_pwm_thrs(hyb_thrs); - #else - UNUSED(hyb_thrs); - #endif + TERN(HYBRID_THRESHOLD, st.set_pwm_thrs(hyb_thrs), UNUSED(hyb_thrs)); st.GSTAT(0b111); // Clear delay(200); @@ -512,9 +541,7 @@ enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E }; chopconf.intpol = INTERPOLATE; chopconf.hend = chopper_timing.hend + 3; chopconf.hstrt = chopper_timing.hstrt - 1; - #if ENABLED(SQUARE_WAVE_STEPPING) - chopconf.dedge = true; - #endif + TERN_(SQUARE_WAVE_STEPPING, chopconf.dedge = true); st.CHOPCONF(chopconf.sr); st.rms_current(mA, HOLD_MULTIPLIER); @@ -532,11 +559,7 @@ enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E }; pwmconf.pwm_ofs = 36; st.PWMCONF(pwmconf.sr); - #if ENABLED(HYBRID_THRESHOLD) - st.set_pwm_thrs(hyb_thrs); - #else - UNUSED(hyb_thrs); - #endif + TERN(HYBRID_THRESHOLD, st.set_pwm_thrs(hyb_thrs), UNUSED(hyb_thrs)); st.GSTAT(0b111); // Clear delay(200); @@ -558,15 +581,10 @@ enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E }; st.sdoff(0); st.rms_current(mA); st.microsteps(microsteps); - #if ENABLED(SQUARE_WAVE_STEPPING) - st.dedge(true); - #endif + TERN_(SQUARE_WAVE_STEPPING, st.dedge(true)); st.intpol(INTERPOLATE); st.diss2g(true); // Disable short to ground protection. Too many false readings? - - #if ENABLED(TMC_DEBUG) - st.rdsel(0b01); - #endif + TERN_(TMC_DEBUG, st.rdsel(0b01)); } #endif // TMC2660 @@ -581,9 +599,7 @@ enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E }; chopconf.intpol = INTERPOLATE; chopconf.hend = chopper_timing.hend + 3; chopconf.hstrt = chopper_timing.hstrt - 1; - #if ENABLED(SQUARE_WAVE_STEPPING) - chopconf.dedge = true; - #endif + TERN_(SQUARE_WAVE_STEPPING, chopconf.dedge = true); st.CHOPCONF(chopconf.sr); st.rms_current(mA, HOLD_MULTIPLIER); @@ -601,11 +617,7 @@ enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E }; pwmconf.pwm_ampl = 180; st.PWMCONF(pwmconf.sr); - #if ENABLED(HYBRID_THRESHOLD) - st.set_pwm_thrs(hyb_thrs); - #else - UNUSED(hyb_thrs); - #endif + TERN(HYBRID_THRESHOLD, st.set_pwm_thrs(hyb_thrs), UNUSED(hyb_thrs)); st.GSTAT(); // Clear GSTAT } @@ -622,9 +634,7 @@ enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E }; chopconf.intpol = INTERPOLATE; chopconf.hend = chopper_timing.hend + 3; chopconf.hstrt = chopper_timing.hstrt - 1; - #if ENABLED(SQUARE_WAVE_STEPPING) - chopconf.dedge = true; - #endif + TERN_(SQUARE_WAVE_STEPPING, chopconf.dedge = true); st.CHOPCONF(chopconf.sr); st.rms_current(mA, HOLD_MULTIPLIER); @@ -706,25 +716,7 @@ void restore_trinamic_drivers() { } void reset_trinamic_drivers() { - static constexpr bool stealthchop_by_axis[] = { - #if ENABLED(STEALTHCHOP_XY) - true - #else - false - #endif - , - #if ENABLED(STEALTHCHOP_Z) - true - #else - false - #endif - , - #if ENABLED(STEALTHCHOP_E) - true - #else - false - #endif - }; + static constexpr bool stealthchop_by_axis[] = { ENABLED(STEALTHCHOP_XY), ENABLED(STEALTHCHOP_Z), ENABLED(STEALTHCHOP_E) }; #if AXIS_IS_TMC(X) TMC_INIT(X, STEALTH_AXIS_XY); @@ -777,36 +769,27 @@ void reset_trinamic_drivers() { #if USE_SENSORLESS #if X_SENSORLESS - #if AXIS_HAS_STALLGUARD(X) - stepperX.homing_threshold(X_STALL_SENSITIVITY); - #endif - #if AXIS_HAS_STALLGUARD(X2) && !X2_SENSORLESS - stepperX2.homing_threshold(X_STALL_SENSITIVITY); + stepperX.homing_threshold(X_STALL_SENSITIVITY); + #if AXIS_HAS_STALLGUARD(X2) + stepperX2.homing_threshold(CAT(TERN(X2_SENSORLESS, X2, X), _STALL_SENSITIVITY)); #endif #endif - #if X2_SENSORLESS - stepperX2.homing_threshold(X2_STALL_SENSITIVITY); - #endif #if Y_SENSORLESS - #if AXIS_HAS_STALLGUARD(Y) - stepperY.homing_threshold(Y_STALL_SENSITIVITY); - #endif + stepperY.homing_threshold(Y_STALL_SENSITIVITY); #if AXIS_HAS_STALLGUARD(Y2) - stepperY2.homing_threshold(Y_STALL_SENSITIVITY); + stepperY2.homing_threshold(CAT(TERN(Y2_SENSORLESS, Y2, Y), _STALL_SENSITIVITY)); #endif #endif #if Z_SENSORLESS - #if AXIS_HAS_STALLGUARD(Z) - stepperZ.homing_threshold(Z_STALL_SENSITIVITY); - #endif + stepperZ.homing_threshold(Z_STALL_SENSITIVITY); #if AXIS_HAS_STALLGUARD(Z2) - stepperZ2.homing_threshold(Z_STALL_SENSITIVITY); + stepperZ2.homing_threshold(CAT(TERN(Z2_SENSORLESS, Z2, Z), _STALL_SENSITIVITY)); #endif #if AXIS_HAS_STALLGUARD(Z3) - stepperZ3.homing_threshold(Z_STALL_SENSITIVITY); + stepperZ3.homing_threshold(CAT(TERN(Z3_SENSORLESS, Z3, Z), _STALL_SENSITIVITY)); #endif #if AXIS_HAS_STALLGUARD(Z4) - stepperZ4.homing_threshold(Z_STALL_SENSITIVITY); + stepperZ4.homing_threshold(CAT(TERN(Z4_SENSORLESS, Z4, Z), _STALL_SENSITIVITY)); #endif #endif #endif @@ -818,4 +801,77 @@ void reset_trinamic_drivers() { stepper.set_directions(); } -#endif // HAS_TRINAMIC +// TMC Slave Address Conflict Detection +// +// Conflict detection is performed in the following way. Similar methods are used for +// hardware and software serial, but the implementations are indepenent. +// +// 1. Populate a data structure with UART parameters and addresses for all possible axis. +// If an axis is not in use, populate it with recognizable placeholder data. +// 2. For each axis in use, static_assert using a constexpr function, which counts the +// number of matching/conflicting axis. If the value is not exactly 1, fail. + +#if ANY_AXIS_HAS(HW_SERIAL) + // Hardware serial names are compared as strings, since actually resolving them cannot occur in a constexpr. + // Using a fixed-length character array for the port name allows this to be constexpr compatible. + struct SanityHwSerialDetails { const char port[20]; uint32_t address; }; + #define TMC_HW_DETAIL_ARGS(A) TERN(A##_HAS_HW_SERIAL, STRINGIFY(A##_HARDWARE_SERIAL), ""), TERN0(A##_HAS_HW_SERIAL, A##_SLAVE_ADDRESS) + #define TMC_HW_DETAIL(A) {TMC_HW_DETAIL_ARGS(A)} + constexpr SanityHwSerialDetails sanity_tmc_hw_details[] = { + TMC_HW_DETAIL(X), TMC_HW_DETAIL(X2), + TMC_HW_DETAIL(Y), TMC_HW_DETAIL(Y2), + TMC_HW_DETAIL(Z), TMC_HW_DETAIL(Z2), TMC_HW_DETAIL(Z3), TMC_HW_DETAIL(Z4), + TMC_HW_DETAIL(E0), TMC_HW_DETAIL(E1), TMC_HW_DETAIL(E2), TMC_HW_DETAIL(E3), TMC_HW_DETAIL(E4), TMC_HW_DETAIL(E5), TMC_HW_DETAIL(E6), TMC_HW_DETAIL(E7) + }; + + // constexpr compatible string comparison + constexpr bool str_eq_ce(const char * a, const char * b) { + return *a == *b && (*a == '\0' || str_eq_ce(a+1,b+1)); + } + + constexpr bool sc_hw_done(size_t start, size_t end) { return start == end; } + constexpr bool sc_hw_skip(const char* port_name) { return !(*port_name); } + constexpr bool sc_hw_match(const char* port_name, uint32_t address, size_t start, size_t end) { + return !sc_hw_done(start, end) && !sc_hw_skip(port_name) && (address == sanity_tmc_hw_details[start].address && str_eq_ce(port_name, sanity_tmc_hw_details[start].port)); + } + constexpr int count_tmc_hw_serial_matches(const char* port_name, uint32_t address, size_t start, size_t end) { + return sc_hw_done(start, end) ? 0 : ((sc_hw_skip(port_name) ? 0 : (sc_hw_match(port_name, address, start, end) ? 1 : 0)) + count_tmc_hw_serial_matches(port_name, address, start + 1, end)); + } + + #define TMC_HWSERIAL_CONFLICT_MSG(A) STRINGIFY(A) "_SLAVE_ADDRESS conflicts with another driver using the same " STRINGIFY(A) "_HARDWARE_SERIAL" + #define SA_NO_TMC_HW_C(A) static_assert(1 >= count_tmc_hw_serial_matches(TMC_HW_DETAIL_ARGS(A), 0, COUNT(sanity_tmc_hw_details)), TMC_HWSERIAL_CONFLICT_MSG(A)); + SA_NO_TMC_HW_C(X);SA_NO_TMC_HW_C(X2); + SA_NO_TMC_HW_C(Y);SA_NO_TMC_HW_C(Y2); + SA_NO_TMC_HW_C(Z);SA_NO_TMC_HW_C(Z2);SA_NO_TMC_HW_C(Z3);SA_NO_TMC_HW_C(Z4); + SA_NO_TMC_HW_C(E0);SA_NO_TMC_HW_C(E1);SA_NO_TMC_HW_C(E2);SA_NO_TMC_HW_C(E3);SA_NO_TMC_HW_C(E4);SA_NO_TMC_HW_C(E5);SA_NO_TMC_HW_C(E6);SA_NO_TMC_HW_C(E7); +#endif + +#if ANY_AXIS_HAS(SW_SERIAL) + struct SanitySwSerialDetails { int32_t txpin; int32_t rxpin; uint32_t address; }; + #define TMC_SW_DETAIL_ARGS(A) TERN(A##_HAS_SW_SERIAL, A##_SERIAL_TX_PIN, -1), TERN(A##_HAS_SW_SERIAL, A##_SERIAL_RX_PIN, -1), TERN0(A##_HAS_SW_SERIAL, A##_SLAVE_ADDRESS) + #define TMC_SW_DETAIL(A) TMC_SW_DETAIL_ARGS(A) + constexpr SanitySwSerialDetails sanity_tmc_sw_details[] = { + TMC_SW_DETAIL(X), TMC_SW_DETAIL(X2), + TMC_SW_DETAIL(Y), TMC_SW_DETAIL(Y2), + TMC_SW_DETAIL(Z), TMC_SW_DETAIL(Z2), TMC_SW_DETAIL(Z3), TMC_SW_DETAIL(Z4), + TMC_SW_DETAIL(E0), TMC_SW_DETAIL(E1), TMC_SW_DETAIL(E2), TMC_SW_DETAIL(E3), TMC_SW_DETAIL(E4), TMC_SW_DETAIL(E5), TMC_SW_DETAIL(E6), TMC_SW_DETAIL(E7) + }; + + constexpr bool sc_sw_done(size_t start, size_t end) { return start == end; } + constexpr bool sc_sw_skip(int32_t txpin) { return txpin < 0; } + constexpr bool sc_sw_match(int32_t txpin, int32_t rxpin, uint32_t address, size_t start, size_t end) { + return !sc_sw_done(start, end) && !sc_sw_skip(txpin) && (txpin == sanity_tmc_sw_details[start].txpin || rxpin == sanity_tmc_sw_details[start].rxpin) && (address == sanity_tmc_sw_details[start].address); + } + constexpr int count_tmc_sw_serial_matches(int32_t txpin, int32_t rxpin, uint32_t address, size_t start, size_t end) { + return sc_sw_done(start, end) ? 0 : ((sc_sw_skip(txpin) ? 0 : (sc_sw_match(txpin, rxpin, address, start, end) ? 1 : 0)) + count_tmc_sw_serial_matches(txpin, rxpin, address, start + 1, end)); + } + + #define TMC_SWSERIAL_CONFLICT_MSG(A) STRINGIFY(A) "_SLAVE_ADDRESS conflicts with another driver using the same " STRINGIFY(A) "_SERIAL_RX_PIN or " STRINGIFY(A) "_SERIAL_TX_PIN" + #define SA_NO_TMC_SW_C(A) static_assert(1 >= count_tmc_sw_serial_matches(TMC_SW_DETAIL_ARGS(A), 0, COUNT(sanity_tmc_sw_details)), TMC_SWSERIAL_CONFLICT_MSG(A)); + SA_NO_TMC_SW_C(X);SA_NO_TMC_SW_C(X2); + SA_NO_TMC_SW_C(Y);SA_NO_TMC_SW_C(Y2); + SA_NO_TMC_SW_C(Z);SA_NO_TMC_SW_C(Z2);SA_NO_TMC_SW_C(Z3);SA_NO_TMC_SW_C(Z4); + SA_NO_TMC_SW_C(E0);SA_NO_TMC_SW_C(E1);SA_NO_TMC_SW_C(E2);SA_NO_TMC_SW_C(E3);SA_NO_TMC_SW_C(E4);SA_NO_TMC_SW_C(E5);SA_NO_TMC_SW_C(E6);SA_NO_TMC_SW_C(E7); +#endif + +#endif // HAS_TRINAMIC_CONFIG diff --git a/Marlin/src/module/stepper/trinamic.h b/Marlin/src/module/stepper/trinamic.h index 262e20840ef4..9cc3404cd2d7 100644 --- a/Marlin/src/module/stepper/trinamic.h +++ b/Marlin/src/module/stepper/trinamic.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index 7cee5fb1ea6d..cf35bbcd8f12 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -24,20 +24,28 @@ * temperature.cpp - temperature control */ +// Useful when debugging thermocouples +//#define IGNORE_THERMOCOUPLE_ERRORS + #include "temperature.h" #include "endstops.h" #include "../MarlinCore.h" -#include "../lcd/ultralcd.h" #include "planner.h" -#include "../core/language.h" #include "../HAL/shared/Delay.h" + +#include "../lcd/ultralcd.h" + +#if ENABLED(DWIN_CREALITY_LCD) + #include "../lcd/dwin/e3v2/dwin.h" +#endif + #if ENABLED(EXTENSIBLE_UI) - #include "../lcd/extensible_ui/ui_api.h" + #include "../lcd/extui/ui_api.h" #endif #if ENABLED(MAX6675_IS_MAX31865) - #include "Adafruit_MAX31865.h" + #include #ifndef MAX31865_CS_PIN #define MAX31865_CS_PIN MAX6675_SS_PIN // HW:49 SW:65 for example #endif @@ -79,8 +87,12 @@ #include "../feature/filwidth.h" #endif +#if HAS_POWER_MONITOR + #include "../feature/power_monitor.h" +#endif + #if ENABLED(EMERGENCY_PARSER) - #include "../feature/emergency_parser.h" + #include "../feature/e_parser.h" #endif #if ENABLED(PRINTER_EVENT_LEDS) @@ -99,13 +111,18 @@ #include "../libs/buzzer.h" #endif +#if HAS_SERVOS + #include "./servo.h" +#endif #if HOTEND_USES_THERMISTOR #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) - static void* heater_ttbl_map[2] = { (void*)HEATER_0_TEMPTABLE, (void*)HEATER_1_TEMPTABLE }; + static const temp_entry_t* heater_ttbl_map[2] = { HEATER_0_TEMPTABLE, HEATER_1_TEMPTABLE }; static constexpr uint8_t heater_ttbllen_map[2] = { HEATER_0_TEMPTABLE_LEN, HEATER_1_TEMPTABLE_LEN }; #else - static void* heater_ttbl_map[HOTENDS] = ARRAY_BY_HOTENDS((void*)HEATER_0_TEMPTABLE, (void*)HEATER_1_TEMPTABLE, (void*)HEATER_2_TEMPTABLE, (void*)HEATER_3_TEMPTABLE, (void*)HEATER_4_TEMPTABLE, (void*)HEATER_5_TEMPTABLE); - static constexpr uint8_t heater_ttbllen_map[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_TEMPTABLE_LEN, HEATER_1_TEMPTABLE_LEN, HEATER_2_TEMPTABLE_LEN, HEATER_3_TEMPTABLE_LEN, HEATER_4_TEMPTABLE_LEN, HEATER_5_TEMPTABLE_LEN); + #define NEXT_TEMPTABLE(N) ,HEATER_##N##_TEMPTABLE + #define NEXT_TEMPTABLE_LEN(N) ,HEATER_##N##_TEMPTABLE_LEN + static const temp_entry_t* heater_ttbl_map[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_TEMPTABLE REPEAT_S(1, HOTENDS, NEXT_TEMPTABLE)); + static constexpr uint8_t heater_ttbllen_map[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_TEMPTABLE_LEN REPEAT_S(1, HOTENDS, NEXT_TEMPTABLE_LEN)); #endif #endif @@ -138,8 +155,9 @@ const char str_t_thermal_runaway[] PROGMEM = STR_T_THERMAL_RUNAWAY, bool Temperature::adaptive_fan_slowing = true; #endif -#if HOTENDS +#if HAS_HOTEND hotend_info_t Temperature::temp_hotend[HOTEND_TEMPS]; // = { 0 } + const uint16_t Temperature::heater_maxtemp[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP, HEATER_2_MAXTEMP, HEATER_3_MAXTEMP, HEATER_4_MAXTEMP, HEATER_5_MAXTEMP, HEATER_6_MAXTEMP, HEATER_7_MAXTEMP); #endif #if ENABLED(AUTO_POWER_E_FANS) @@ -150,7 +168,7 @@ const char str_t_thermal_runaway[] PROGMEM = STR_T_THERMAL_RUNAWAY, uint8_t Temperature::chamberfan_speed; // = 0 #endif -#if FAN_COUNT > 0 +#if HAS_FAN uint8_t Temperature::fan_speed[FAN_COUNT]; // = { 0 } @@ -180,7 +198,7 @@ const char str_t_thermal_runaway[] PROGMEM = STR_T_THERMAL_RUNAWAY, #endif #if ENABLED(ADAPTIVE_FAN_SLOWING) - uint8_t Temperature::fan_speed_scaler[FAN_COUNT] = ARRAY_N(FAN_COUNT, 128, 128, 128, 128, 128, 128); + uint8_t Temperature::fan_speed_scaler[FAN_COUNT] = ARRAY_N(FAN_COUNT, 128, 128, 128, 128, 128, 128, 128, 128); #endif /** @@ -190,19 +208,33 @@ const char str_t_thermal_runaway[] PROGMEM = STR_T_THERMAL_RUNAWAY, NOMORE(speed, 255U); - #if ENABLED(SINGLENOZZLE) + #if ENABLED(SINGLENOZZLE_STANDBY_FAN) if (target != active_extruder) { if (target < EXTRUDERS) singlenozzle_fan_speed[target] = speed; return; } - target = 0; // Always use fan index 0 with SINGLENOZZLE #endif + TERN_(SINGLENOZZLE, target = 0); // Always use fan index 0 with SINGLENOZZLE + if (target >= FAN_COUNT) return; fan_speed[target] = speed; + + TERN_(REPORT_FAN_CHANGE, report_fan_speed(target)); } + #if ENABLED(REPORT_FAN_CHANGE) + /** + * Report print fan speed for a target extruder + */ + void Temperature::report_fan_speed(const uint8_t target) { + if (target >= FAN_COUNT) return; + PORT_REDIRECT(SERIAL_BOTH); + SERIAL_ECHOLNPAIR("M106 P", target, " S", fan_speed[target]); + } + #endif + #if EITHER(PROBING_FANS_OFF, ADVANCED_PAUSE_FANS_PAUSE) void Temperature::set_fans_paused(const bool p) { @@ -217,13 +249,13 @@ const char str_t_thermal_runaway[] PROGMEM = STR_T_THERMAL_RUNAWAY, #endif -#endif // FAN_COUNT > 0 +#endif // HAS_FAN #if WATCH_HOTENDS hotend_watch_t Temperature::watch_hotend[HOTENDS]; // = { { 0 } } #endif #if HEATER_IDLE_HANDLER - hotend_idle_t Temperature::hotend_idle[HOTENDS]; // = { { 0 } } + Temperature::heater_idle_t Temperature::heater_idle[NR_HEATER_IDLE]; // = { { 0 } } #endif #if HAS_HEATED_BED @@ -235,20 +267,18 @@ const char str_t_thermal_runaway[] PROGMEM = STR_T_THERMAL_RUNAWAY, #ifdef BED_MAXTEMP int16_t Temperature::maxtemp_raw_BED = HEATER_BED_RAW_HI_TEMP; #endif - #if WATCH_BED - bed_watch_t Temperature::watch_bed; // = { 0 } - #endif - #if DISABLED(PIDTEMPBED) - millis_t Temperature::next_bed_check_ms; - #endif - #if HEATER_IDLE_HANDLER - hotend_idle_t Temperature::bed_idle; // = { 0 } - #endif + TERN_(WATCH_BED, bed_watch_t Temperature::watch_bed); // = { 0 } + TERN(PIDTEMPBED,, millis_t Temperature::next_bed_check_ms); #endif // HAS_HEATED_BED #if HAS_TEMP_CHAMBER chamber_info_t Temperature::temp_chamber; // = { 0 } #if HAS_HEATED_CHAMBER + int16_t fan_chamber_pwm; + bool flag_chamber_off; + bool flag_chamber_excess_heat = false; + millis_t next_cool_check_ms_2 = 0; + float old_temp = 9999; #ifdef CHAMBER_MINTEMP int16_t Temperature::mintemp_raw_CHAMBER = HEATER_CHAMBER_RAW_LO_TEMP; #endif @@ -296,7 +326,7 @@ volatile bool Temperature::raw_temps_ready = false; #define TEMPDIR(N) ((HEATER_##N##_RAW_LO_TEMP) < (HEATER_##N##_RAW_HI_TEMP) ? 1 : -1) -#if HOTENDS +#if HAS_HOTEND // Init mintemp and maxtemp with extreme values to prevent false errors during startup constexpr temp_range_t sensor_heater_0 { HEATER_0_RAW_LO_TEMP, HEATER_0_RAW_HI_TEMP, 0, 16383 }, sensor_heater_1 { HEATER_1_RAW_LO_TEMP, HEATER_1_RAW_HI_TEMP, 0, 16383 }, @@ -335,11 +365,11 @@ volatile bool Temperature::raw_temps_ready = false; #if HAS_ADC_BUTTONS uint32_t Temperature::current_ADCKey_raw = HAL_ADC_RANGE; - uint8_t Temperature::ADCKey_count = 0; + uint16_t Temperature::ADCKey_count = 0; #endif #if ENABLED(PID_EXTRUSION_SCALING) - int16_t Temperature::lpq_len; // Initialized in configuration_store + int16_t Temperature::lpq_len; // Initialized in settings.cpp #endif #if HAS_PID_HEATING @@ -354,7 +384,7 @@ volatile bool Temperature::raw_temps_ready = false; * Needs sufficient heater power to make some overshoot at target * temperature to succeed. */ - void Temperature::PID_autotune(const float &target, const heater_ind_t heater, const int8_t ncycles, const bool set_result/*=false*/) { + void Temperature::PID_autotune(const float &target, const heater_id_t heater_id, const int8_t ncycles, const bool set_result/*=false*/) { float current_temp = 0.0; int cycles = 0; bool heating = true; @@ -366,11 +396,11 @@ volatile bool Temperature::raw_temps_ready = false; PID_t tune_pid = { 0, 0, 0 }; float maxT = 0, minT = 10000; - const bool isbed = (heater == H_BED); + const bool isbed = (heater_id == H_BED); #if HAS_PID_FOR_BOTH #define GHV(B,H) (isbed ? (B) : (H)) - #define SHV(B,H) do{ if (isbed) temp_bed.soft_pwm_amount = B; else temp_hotend[heater].soft_pwm_amount = H; }while(0) + #define SHV(B,H) do{ if (isbed) temp_bed.soft_pwm_amount = B; else temp_hotend[heater_id].soft_pwm_amount = H; }while(0) #define ONHEATINGSTART() (isbed ? printerEventLEDs.onBedHeatingStart() : printerEventLEDs.onHotendHeatingStart()) #define ONHEATING(S,C,T) (isbed ? printerEventLEDs.onBedHeating(S,C,T) : printerEventLEDs.onHotendHeating(S,C,T)) #elif ENABLED(PIDTEMPBED) @@ -380,57 +410,52 @@ volatile bool Temperature::raw_temps_ready = false; #define ONHEATING(S,C,T) printerEventLEDs.onBedHeating(S,C,T) #else #define GHV(B,H) H - #define SHV(B,H) (temp_hotend[heater].soft_pwm_amount = H) + #define SHV(B,H) (temp_hotend[heater_id].soft_pwm_amount = H) #define ONHEATINGSTART() printerEventLEDs.onHotendHeatingStart() #define ONHEATING(S,C,T) printerEventLEDs.onHotendHeating(S,C,T) #endif + #define WATCH_PID BOTH(WATCH_BED, PIDTEMPBED) || BOTH(WATCH_HOTENDS, PIDTEMP) - #if WATCH_BED || WATCH_HOTENDS - #define HAS_TP_BED BOTH(THERMAL_PROTECTION_BED, PIDTEMPBED) - #if HAS_TP_BED && BOTH(THERMAL_PROTECTION_HOTENDS, PIDTEMP) + #if WATCH_PID + #if ALL(THERMAL_PROTECTION_HOTENDS, PIDTEMP, THERMAL_PROTECTION_BED, PIDTEMPBED) #define GTV(B,H) (isbed ? (B) : (H)) - #elif HAS_TP_BED - #define GTV(B,H) (B) - #else + #elif BOTH(THERMAL_PROTECTION_HOTENDS, PIDTEMP) #define GTV(B,H) (H) + #else + #define GTV(B,H) (B) #endif const uint16_t watch_temp_period = GTV(WATCH_BED_TEMP_PERIOD, WATCH_TEMP_PERIOD); const uint8_t watch_temp_increase = GTV(WATCH_BED_TEMP_INCREASE, WATCH_TEMP_INCREASE); const float watch_temp_target = target - float(watch_temp_increase + GTV(TEMP_BED_HYSTERESIS, TEMP_HYSTERESIS) + 1); - millis_t temp_change_ms = next_temp_ms + watch_temp_period * 1000UL; + millis_t temp_change_ms = next_temp_ms + SEC_TO_MS(watch_temp_period); float next_watch_temp = 0.0; bool heated = false; #endif - #if HAS_AUTO_FAN - next_auto_fan_check_ms = next_temp_ms + 2500UL; - #endif + TERN_(HAS_AUTO_FAN, next_auto_fan_check_ms = next_temp_ms + 2500UL); - if (target > GHV(BED_MAXTEMP - 10, temp_range[heater].maxtemp - 15)) { + if (target > GHV(BED_MAX_TARGET, temp_range[heater_id].maxtemp - HOTEND_OVERSHOOT)) { SERIAL_ECHOLNPGM(STR_PID_TEMP_TOO_HIGH); - #if ENABLED(EXTENSIBLE_UI) - ExtUI::OnPidTuning(ExtUI::result_t::PID_TEMP_TOO_HIGH); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_TEMP_TOO_HIGH)); return; } SERIAL_ECHOLNPGM(STR_PID_AUTOTUNE_START); disable_all_heaters(); + TERN_(AUTO_POWER_CONTROL, powerManager.power_on()); SHV(bias = d = (MAX_BED_POWER) >> 1, bias = d = (PID_MAX) >> 1); - wait_for_heatup = true; // Can be interrupted with M108 #if ENABLED(PRINTER_EVENT_LEDS) - const float start_temp = GHV(temp_bed.celsius, temp_hotend[heater].celsius); + const float start_temp = GHV(temp_bed.celsius, temp_hotend[heater_id].celsius); LEDColor color = ONHEATINGSTART(); #endif - #if ENABLED(NO_FAN_SLOWING_IN_PID_TUNING) - adaptive_fan_slowing = false; - #endif + TERN_(NO_FAN_SLOWING_IN_PID_TUNING, adaptive_fan_slowing = false); // PID Tuning loop + wait_for_heatup = true; // Can be interrupted with M108 while (wait_for_heatup) { const millis_t ms = millis(); @@ -439,7 +464,7 @@ volatile bool Temperature::raw_temps_ready = false; updateTemperaturesFromRawValues(); // Get the current temperature and constrain it - current_temp = GHV(temp_bed.celsius, temp_hotend[heater].celsius); + current_temp = GHV(temp_bed.celsius, temp_hotend[heater_id].celsius); NOLESS(maxT, current_temp); NOMORE(minT, current_temp); @@ -524,42 +549,32 @@ volatile bool Temperature::raw_temps_ready = false; #endif if (current_temp > target + MAX_OVERSHOOT_PID_AUTOTUNE) { SERIAL_ECHOLNPGM(STR_PID_TEMP_TOO_HIGH); - #if ENABLED(EXTENSIBLE_UI) - ExtUI::OnPidTuning(ExtUI::result_t::PID_TEMP_TOO_HIGH); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_TEMP_TOO_HIGH)); break; } // Report heater states every 2 seconds if (ELAPSED(ms, next_temp_ms)) { #if HAS_TEMP_SENSOR - print_heater_states(isbed ? active_extruder : heater); + print_heater_states(isbed ? active_extruder : heater_id); SERIAL_EOL(); #endif next_temp_ms = ms + 2000UL; // Make sure heating is actually working - #if WATCH_BED || WATCH_HOTENDS - if ( - #if WATCH_BED && WATCH_HOTENDS - true - #elif WATCH_HOTENDS - !isbed - #else - isbed - #endif - ) { - if (!heated) { // If not yet reached target... - if (current_temp > next_watch_temp) { // Over the watch temp? - next_watch_temp = current_temp + watch_temp_increase; // - set the next temp to watch for - temp_change_ms = ms + watch_temp_period * 1000UL; // - move the expiration timer up - if (current_temp > watch_temp_target) heated = true; // - Flag if target temperature reached + #if WATCH_PID + if (BOTH(WATCH_BED, WATCH_HOTENDS) || isbed == DISABLED(WATCH_HOTENDS)) { + if (!heated) { // If not yet reached target... + if (current_temp > next_watch_temp) { // Over the watch temp? + next_watch_temp = current_temp + watch_temp_increase; // - set the next temp to watch for + temp_change_ms = ms + SEC_TO_MS(watch_temp_period); // - move the expiration timer up + if (current_temp > watch_temp_target) heated = true; // - Flag if target temperature reached } - else if (ELAPSED(ms, temp_change_ms)) // Watch timer expired - _temp_error(heater, str_t_heating_failed, GET_TEXT(MSG_HEATING_FAILED_LCD)); + else if (ELAPSED(ms, temp_change_ms)) // Watch timer expired + _temp_error(heater_id, str_t_heating_failed, GET_TEXT(MSG_HEATING_FAILED_LCD)); } else if (current_temp < target - (MAX_OVERSHOOT_PID_AUTOTUNE)) // Heated, then temperature fell too far? - _temp_error(heater, str_t_thermal_runaway, GET_TEXT(MSG_THERMAL_RUNAWAY)); + _temp_error(heater_id, str_t_thermal_runaway, GET_TEXT(MSG_THERMAL_RUNAWAY)); } #endif } // every 2 seconds @@ -568,10 +583,9 @@ volatile bool Temperature::raw_temps_ready = false; #ifndef MAX_CYCLE_TIME_PID_AUTOTUNE #define MAX_CYCLE_TIME_PID_AUTOTUNE 20L #endif - if (((ms - t1) + (ms - t2)) > (MAX_CYCLE_TIME_PID_AUTOTUNE * 60L * 1000L)) { - #if ENABLED(EXTENSIBLE_UI) - ExtUI::OnPidTuning(ExtUI::result_t::PID_TUNING_TIMEOUT); - #endif + if ((ms - _MIN(t1, t2)) > (MAX_CYCLE_TIME_PID_AUTOTUNE * 60L * 1000L)) { + TERN_(DWIN_CREALITY_LCD, DWIN_Popup_Temperature(0)); + TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_TUNING_TIMEOUT)); SERIAL_ECHOLNPGM(STR_PID_TIMEOUT); break; } @@ -601,9 +615,9 @@ volatile bool Temperature::raw_temps_ready = false; }while(0) #define _SET_EXTRUDER_PID() do { \ - PID_PARAM(Kp, heater) = tune_pid.Kp; \ - PID_PARAM(Ki, heater) = scalePID_i(tune_pid.Ki); \ - PID_PARAM(Kd, heater) = scalePID_d(tune_pid.Kd); \ + PID_PARAM(Kp, heater_id) = tune_pid.Kp; \ + PID_PARAM(Ki, heater_id) = scalePID_i(tune_pid.Ki); \ + PID_PARAM(Kd, heater_id) = scalePID_d(tune_pid.Kd); \ updatePID(); }while(0) // Use the result? (As with "M303 U1") @@ -617,31 +631,29 @@ volatile bool Temperature::raw_temps_ready = false; #endif } - #if ENABLED(PRINTER_EVENT_LEDS) - printerEventLEDs.onPidTuningDone(color); - #endif - #if ENABLED(EXTENSIBLE_UI) - ExtUI::OnPidTuning(ExtUI::result_t::PID_DONE); - #endif + TERN_(PRINTER_EVENT_LEDS, printerEventLEDs.onPidTuningDone(color)); + + TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_DONE)); goto EXIT_M303; } - ui.update(); + + // Run HAL idle tasks + TERN_(HAL_IDLETASK, HAL_idletask()); + + // Run UI update + TERN(DWIN_CREALITY_LCD, DWIN_Update(), ui.update()); } + wait_for_heatup = false; disable_all_heaters(); - #if ENABLED(PRINTER_EVENT_LEDS) - printerEventLEDs.onPidTuningDone(color); - #endif - #if ENABLED(EXTENSIBLE_UI) - ExtUI::OnPidTuning(ExtUI::result_t::PID_DONE); - #endif + TERN_(PRINTER_EVENT_LEDS, printerEventLEDs.onPidTuningDone(color)); + + TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_DONE)); EXIT_M303: - #if ENABLED(NO_FAN_SLOWING_IN_PID_TUNING) - adaptive_fan_slowing = true; - #endif + TERN_(NO_FAN_SLOWING_IN_PID_TUNING, adaptive_fan_slowing = true); return; } @@ -651,7 +663,7 @@ volatile bool Temperature::raw_temps_ready = false; * Class and Instance Methods */ -int16_t Temperature::getHeaterPower(const heater_ind_t heater_id) { +int16_t Temperature::getHeaterPower(const heater_id_t heater_id) { switch (heater_id) { #if HAS_HEATED_BED case H_BED: return temp_bed.soft_pwm_amount; @@ -660,11 +672,7 @@ int16_t Temperature::getHeaterPower(const heater_ind_t heater_id) { case H_CHAMBER: return temp_chamber.soft_pwm_amount; #endif default: - return (0 - #if HOTENDS - + temp_hotend[heater_id].soft_pwm_amount - #endif - ); + return TERN0(HAS_HOTEND, temp_hotend[heater_id].soft_pwm_amount); } } @@ -678,7 +686,7 @@ int16_t Temperature::getHeaterPower(const heater_ind_t heater_id) { #define _EFAN(B,A) _EFANOVERLAP(A,B) ? B : static const uint8_t fanBit[] PROGMEM = { 0 - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND #define _NEXT_FAN(N) , REPEAT2(N,_EFAN,N) N RREPEAT_S(1, HOTENDS, _NEXT_FAN) #endif @@ -706,7 +714,7 @@ int16_t Temperature::getHeaterPower(const heater_ind_t heater_id) { }while(0) uint8_t fanDone = 0; - for (uint8_t f = 0; f < COUNT(fanBit); f++) { + LOOP_L_N(f, COUNT(fanBit)) { const uint8_t realFan = pgm_read_byte(&fanBit[f]); if (TEST(fanDone, realFan)) continue; const bool fan_on = TEST(fanState, realFan); @@ -762,8 +770,8 @@ int16_t Temperature::getHeaterPower(const heater_ind_t heater_id) { // Temperature Error Handlers // -inline void loud_kill(PGM_P const lcd_msg, const heater_ind_t heater) { - Running = false; +inline void loud_kill(PGM_P const lcd_msg, const heater_id_t heater_id) { + marlin_state = MF_KILLED; #if USE_BEEPER for (uint8_t i = 20; i--;) { WRITE(BEEPER_PIN, HIGH); delay(25); @@ -771,26 +779,23 @@ inline void loud_kill(PGM_P const lcd_msg, const heater_ind_t heater) { } WRITE(BEEPER_PIN, HIGH); #endif - kill(lcd_msg, HEATER_PSTR(heater)); + kill(lcd_msg, HEATER_PSTR(heater_id)); } -void Temperature::_temp_error(const heater_ind_t heater, PGM_P const serial_msg, PGM_P const lcd_msg) { +void Temperature::_temp_error(const heater_id_t heater_id, PGM_P const serial_msg, PGM_P const lcd_msg) { static uint8_t killed = 0; - if (IsRunning() - #if BOGUS_TEMPERATURE_GRACE_PERIOD - && killed == 2 - #endif - ) { + if (IsRunning() && TERN1(BOGUS_TEMPERATURE_GRACE_PERIOD, killed == 2)) { SERIAL_ERROR_START(); serialprintPGM(serial_msg); SERIAL_ECHOPGM(STR_STOPPED_HEATER); - if (heater >= 0) SERIAL_ECHO((int)heater); - #if HAS_HEATED_CHAMBER - else if (heater == H_CHAMBER) SERIAL_ECHOPGM(STR_HEATER_CHAMBER); - #endif - else SERIAL_ECHOPGM(STR_HEATER_BED); + if (heater_id >= 0) + SERIAL_ECHO((int)heater_id); + else if (TERN0(HAS_HEATED_CHAMBER, heater_id == H_CHAMBER)) + SERIAL_ECHOPGM(STR_HEATER_CHAMBER); + else + SERIAL_ECHOPGM(STR_HEATER_BED); SERIAL_EOL(); } @@ -808,26 +813,35 @@ void Temperature::_temp_error(const heater_ind_t heater, PGM_P const serial_msg, if (ELAPSED(ms, expire_ms)) ++killed; break; case 2: - loud_kill(lcd_msg, heater); + loud_kill(lcd_msg, heater_id); ++killed; break; } #elif defined(BOGUS_TEMPERATURE_GRACE_PERIOD) UNUSED(killed); #else - if (!killed) { killed = 1; loud_kill(lcd_msg, heater); } + if (!killed) { killed = 1; loud_kill(lcd_msg, heater_id); } #endif } -void Temperature::max_temp_error(const heater_ind_t heater) { - _temp_error(heater, PSTR(STR_T_MAXTEMP), GET_TEXT(MSG_ERR_MAXTEMP)); +void Temperature::max_temp_error(const heater_id_t heater_id) { + #if ENABLED(DWIN_CREALITY_LCD) && (HAS_HOTEND || HAS_HEATED_BED) + DWIN_Popup_Temperature(1); + #endif + _temp_error(heater_id, PSTR(STR_T_MAXTEMP), GET_TEXT(MSG_ERR_MAXTEMP)); } -void Temperature::min_temp_error(const heater_ind_t heater) { - _temp_error(heater, PSTR(STR_T_MINTEMP), GET_TEXT(MSG_ERR_MINTEMP)); +void Temperature::min_temp_error(const heater_id_t heater_id) { + #if ENABLED(DWIN_CREALITY_LCD) && (HAS_HOTEND || HAS_HEATED_BED) + DWIN_Popup_Temperature(0); + #endif + _temp_error(heater_id, PSTR(STR_T_MINTEMP), GET_TEXT(MSG_ERR_MINTEMP)); } -#if HOTENDS +#if HAS_HOTEND + #if ENABLED(PID_DEBUG) + extern bool pid_debug_flag; + #endif float Temperature::get_pid_output_hotend(const uint8_t E_NAME) { const uint8_t ee = HOTEND_INDEX; @@ -843,9 +857,7 @@ void Temperature::min_temp_error(const heater_ind_t heater) { if (temp_hotend[ee].target == 0 || pid_error < -(PID_FUNCTIONAL_RANGE) - #if HEATER_IDLE_HANDLER - || hotend_idle[ee].timed_out - #endif + || TERN0(HEATER_IDLE_HANDLER, heater_idle[ee].timed_out) ) { pid_output = 0; pid_reset[ee] = true; @@ -909,13 +921,9 @@ void Temperature::min_temp_error(const heater_ind_t heater) { #endif // PID_OPENLOOP #if ENABLED(PID_DEBUG) - if (ee == active_extruder) { + if (ee == active_extruder && pid_debug_flag) { SERIAL_ECHO_START(); - SERIAL_ECHOPAIR( - STR_PID_DEBUG, ee, - STR_PID_DEBUG_INPUT, temp_hotend[ee].celsius, - STR_PID_DEBUG_OUTPUT, pid_output - ); + SERIAL_ECHOPAIR(STR_PID_DEBUG, ee, STR_PID_DEBUG_INPUT, temp_hotend[ee].celsius, STR_PID_DEBUG_OUTPUT, pid_output); #if DISABLED(PID_OPENLOOP) { SERIAL_ECHOPAIR( @@ -934,11 +942,7 @@ void Temperature::min_temp_error(const heater_ind_t heater) { #else // No PID enabled - #if HEATER_IDLE_HANDLER - const bool is_idling = hotend_idle[ee].timed_out; - #else - constexpr bool is_idling = false; - #endif + const bool is_idling = TERN0(HEATER_IDLE_HANDLER, heater_idle[ee].timed_out); const float pid_output = (!is_idling && temp_hotend[ee].celsius < temp_hotend[ee].target) ? BANG_MAX : 0; #endif @@ -946,7 +950,7 @@ void Temperature::min_temp_error(const heater_ind_t heater) { return pid_output; } -#endif // HOTENDS +#endif // HAS_HOTEND #if ENABLED(PIDTEMPBED) @@ -1028,45 +1032,38 @@ void Temperature::manage_heater() { if (!inited) return watchdog_refresh(); #endif - #if BOTH(PROBING_HEATERS_OFF, BED_LIMIT_SWITCHING) - static bool last_pause_state; - #endif - - #if ENABLED(EMERGENCY_PARSER) - if (emergency_parser.killed_by_M112) kill(M112_KILL_STR, nullptr, true); - #endif + if (TERN0(EMERGENCY_PARSER, emergency_parser.killed_by_M112)) + kill(M112_KILL_STR, nullptr, true); if (!raw_temps_ready) return; updateTemperaturesFromRawValues(); // also resets the watchdog - #if ENABLED(HEATER_0_USES_MAX6675) - if (temp_hotend[0].celsius > _MIN(HEATER_0_MAXTEMP, HEATER_0_MAX6675_TMAX - 1.0)) max_temp_error(H_E0); - if (temp_hotend[0].celsius < _MAX(HEATER_0_MINTEMP, HEATER_0_MAX6675_TMIN + .01)) min_temp_error(H_E0); - #endif - - #if ENABLED(HEATER_1_USES_MAX6675) - if (temp_hotend[1].celsius > _MIN(HEATER_1_MAXTEMP, HEATER_1_MAX6675_TMAX - 1.0)) max_temp_error(H_E1); - if (temp_hotend[1].celsius < _MAX(HEATER_1_MINTEMP, HEATER_1_MAX6675_TMIN + .01)) min_temp_error(H_E1); + #if DISABLED(IGNORE_THERMOCOUPLE_ERRORS) + #if ENABLED(HEATER_0_USES_MAX6675) + if (temp_hotend[0].celsius > _MIN(HEATER_0_MAXTEMP, HEATER_0_MAX6675_TMAX - 1.0)) max_temp_error(H_E0); + if (temp_hotend[0].celsius < _MAX(HEATER_0_MINTEMP, HEATER_0_MAX6675_TMIN + .01)) min_temp_error(H_E0); + #endif + #if ENABLED(HEATER_1_USES_MAX6675) + if (temp_hotend[1].celsius > _MIN(HEATER_1_MAXTEMP, HEATER_1_MAX6675_TMAX - 1.0)) max_temp_error(H_E1); + if (temp_hotend[1].celsius < _MAX(HEATER_1_MINTEMP, HEATER_1_MAX6675_TMIN + .01)) min_temp_error(H_E1); + #endif #endif millis_t ms = millis(); - #if HOTENDS + #if HAS_HOTEND HOTEND_LOOP() { #if ENABLED(THERMAL_PROTECTION_HOTENDS) - if (degHotend(e) > temp_range[e].maxtemp) - _temp_error((heater_ind_t)e, str_t_thermal_runaway, GET_TEXT(MSG_THERMAL_RUNAWAY)); + if (degHotend(e) > temp_range[e].maxtemp) max_temp_error((heater_id_t)e); #endif - #if HEATER_IDLE_HANDLER - hotend_idle[e].update(ms); - #endif + TERN_(HEATER_IDLE_HANDLER, heater_idle[e].update(ms)); #if ENABLED(THERMAL_PROTECTION_HOTENDS) // Check for thermal runaway - thermal_runaway_protection(tr_state_machine[e], temp_hotend[e].celsius, temp_hotend[e].target, (heater_ind_t)e, THERMAL_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS); + tr_state_machine[e].run(temp_hotend[e].celsius, temp_hotend[e].target, (heater_id_t)e, THERMAL_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS); #endif temp_hotend[e].soft_pwm_amount = (temp_hotend[e].celsius > temp_range[e].mintemp || is_preheating(e)) && temp_hotend[e].celsius < temp_range[e].maxtemp ? (int)get_pid_output_hotend(e) >> 1 : 0; @@ -1074,8 +1071,10 @@ void Temperature::manage_heater() { #if WATCH_HOTENDS // Make sure temperature is increasing if (watch_hotend[e].next_ms && ELAPSED(ms, watch_hotend[e].next_ms)) { // Time to check this extruder? - if (degHotend(e) < watch_hotend[e].target) // Failed to increase enough? - _temp_error((heater_ind_t)e, str_t_heating_failed, GET_TEXT(MSG_HEATING_FAILED_LCD)); + if (degHotend(e) < watch_hotend[e].target) { // Failed to increase enough? + TERN_(DWIN_CREALITY_LCD, DWIN_Popup_Temperature(0)); + _temp_error((heater_id_t)e, str_t_heating_failed, GET_TEXT(MSG_HEATING_FAILED_LCD)); + } else // Start again if the target is still far off start_watching_hotend(e); } @@ -1089,7 +1088,7 @@ void Temperature::manage_heater() { } // HOTEND_LOOP - #endif // HOTENDS + #endif // HAS_HOTEND #if HAS_AUTO_FAN if (ELAPSED(ms, next_auto_fan_check_ms)) { // only need to check fan state very infrequently @@ -1109,44 +1108,47 @@ void Temperature::manage_heater() { #if HAS_HEATED_BED #if ENABLED(THERMAL_PROTECTION_BED) - if (degBed() > BED_MAXTEMP) - _temp_error(H_BED, str_t_thermal_runaway, GET_TEXT(MSG_THERMAL_RUNAWAY)); + if (degBed() > BED_MAXTEMP) max_temp_error(H_BED); #endif #if WATCH_BED // Make sure temperature is increasing if (watch_bed.elapsed(ms)) { // Time to check the bed? - if (degBed() < watch_bed.target) // Failed to increase enough? + if (degBed() < watch_bed.target) { // Failed to increase enough? + TERN_(DWIN_CREALITY_LCD, DWIN_Popup_Temperature(0)); _temp_error(H_BED, str_t_heating_failed, GET_TEXT(MSG_HEATING_FAILED_LCD)); + } else // Start again if the target is still far off start_watching_bed(); } #endif // WATCH_BED + #if BOTH(PROBING_HEATERS_OFF, BED_LIMIT_SWITCHING) + #define PAUSE_CHANGE_REQD 1 + #endif + + #if PAUSE_CHANGE_REQD + static bool last_pause_state; + #endif + do { #if DISABLED(PIDTEMPBED) if (PENDING(ms, next_bed_check_ms) - #if BOTH(PROBING_HEATERS_OFF, BED_LIMIT_SWITCHING) - && paused == last_pause_state - #endif + && TERN1(PAUSE_CHANGE_REQD, paused == last_pause_state) ) break; next_bed_check_ms = ms + BED_CHECK_INTERVAL; - #if BOTH(PROBING_HEATERS_OFF, BED_LIMIT_SWITCHING) - last_pause_state = paused; - #endif + TERN_(PAUSE_CHANGE_REQD, last_pause_state = paused); #endif - #if HEATER_IDLE_HANDLER - bed_idle.update(ms); - #endif + TERN_(HEATER_IDLE_HANDLER, heater_idle[IDLE_INDEX_BED].update(ms)); #if HAS_THERMALLY_PROTECTED_BED - thermal_runaway_protection(tr_state_machine_bed, temp_bed.celsius, temp_bed.target, H_BED, THERMAL_PROTECTION_BED_PERIOD, THERMAL_PROTECTION_BED_HYSTERESIS); + tr_state_machine[RUNAWAY_IND_BED].run(temp_bed.celsius, temp_bed.target, H_BED, THERMAL_PROTECTION_BED_PERIOD, THERMAL_PROTECTION_BED_HYSTERESIS); #endif #if HEATER_IDLE_HANDLER - if (bed_idle.timed_out) { + if (heater_idle[IDLE_INDEX_BED].timed_out) { temp_bed.soft_pwm_amount = 0; #if DISABLED(PIDTEMPBED) WRITE_HEATER_BED(LOW); @@ -1187,8 +1189,7 @@ void Temperature::manage_heater() { #endif #if ENABLED(THERMAL_PROTECTION_CHAMBER) - if (degChamber() > CHAMBER_MAXTEMP) - _temp_error(H_CHAMBER, str_t_thermal_runaway, GET_TEXT(MSG_THERMAL_RUNAWAY)); + if (degChamber() > CHAMBER_MAXTEMP) max_temp_error(H_CHAMBER); #endif #if WATCH_CHAMBER @@ -1201,18 +1202,84 @@ void Temperature::manage_heater() { } #endif + #if EITHER(CHAMBER_FAN, CHAMBER_VENT) + if (temp_chamber.target > CHAMBER_MINTEMP) { + flag_chamber_off = false; + + #if ENABLED(CHAMBER_FAN) + #if CHAMBER_FAN_MODE == 0 + fan_chamber_pwm = CHAMBER_FAN_BASE + #elif CHAMBER_FAN_MODE == 1 + fan_chamber_pwm = (temp_chamber.celsius > temp_chamber.target) ? (CHAMBER_FAN_BASE) + (CHAMBER_FAN_FACTOR) * (temp_chamber.celsius - temp_chamber.target) : 0; + #elif CHAMBER_FAN_MODE == 2 + fan_chamber_pwm = (CHAMBER_FAN_BASE) + (CHAMBER_FAN_FACTOR) * ABS(temp_chamber.celsius - temp_chamber.target); + if (temp_chamber.soft_pwm_amount) + fan_chamber_pwm += (CHAMBER_FAN_FACTOR) * 2; + #endif + NOMORE(fan_chamber_pwm, 225); + thermalManager.set_fan_speed(2, fan_chamber_pwm); // TODO: instead of fan 2, set to chamber fan + #endif + + #if ENABLED(CHAMBER_VENT) + #ifndef MIN_COOLING_SLOPE_TIME_CHAMBER_VENT + #define MIN_COOLING_SLOPE_TIME_CHAMBER_VENT 20 + #endif + #ifndef MIN_COOLING_SLOPE_DEG_CHAMBER_VENT + #define MIN_COOLING_SLOPE_DEG_CHAMBER_VENT 1.5 + #endif + if( (temp_chamber.celsius - temp_chamber.target >= HIGH_EXCESS_HEAT_LIMIT) && !flag_chamber_excess_heat) { + // open vent after MIN_COOLING_SLOPE_TIME_CHAMBER_VENT seconds + // if the temperature did not drop at least MIN_COOLING_SLOPE_DEG_CHAMBER_VENT + if (next_cool_check_ms_2 == 0 || ELAPSED(ms, next_cool_check_ms_2)) { + if (old_temp - temp_chamber.celsius < float(MIN_COOLING_SLOPE_DEG_CHAMBER_VENT)) flag_chamber_excess_heat = true; //the bed is heating the chamber too much + next_cool_check_ms_2 = ms + 1000UL * MIN_COOLING_SLOPE_TIME_CHAMBER_VENT; + old_temp = temp_chamber.celsius; + } + } + else { + next_cool_check_ms_2 = 0; + old_temp = 9999; + } + if (flag_chamber_excess_heat && (temp_chamber.celsius - temp_chamber.target <= -LOW_EXCESS_HEAT_LIMIT) ) { + flag_chamber_excess_heat = false; + } + #endif + } + else if (!flag_chamber_off) { + #if ENABLED(CHAMBER_FAN) + flag_chamber_off = true; + thermalManager.set_fan_speed(2, 0); + #endif + #if ENABLED(CHAMBER_VENT) + flag_chamber_excess_heat = false; + MOVE_SERVO(CHAMBER_VENT_SERVO_NR, 90); + #endif + } + #endif + if (ELAPSED(ms, next_chamber_check_ms)) { next_chamber_check_ms = ms + CHAMBER_CHECK_INTERVAL; if (WITHIN(temp_chamber.celsius, CHAMBER_MINTEMP, CHAMBER_MAXTEMP)) { - #if ENABLED(CHAMBER_LIMIT_SWITCHING) - if (temp_chamber.celsius >= temp_chamber.target + TEMP_CHAMBER_HYSTERESIS) - temp_chamber.soft_pwm_amount = 0; - else if (temp_chamber.celsius <= temp_chamber.target - (TEMP_CHAMBER_HYSTERESIS)) - temp_chamber.soft_pwm_amount = MAX_CHAMBER_POWER >> 1; - #else - temp_chamber.soft_pwm_amount = temp_chamber.celsius < temp_chamber.target ? MAX_CHAMBER_POWER >> 1 : 0; - #endif + if (flag_chamber_excess_heat) { + temp_chamber.soft_pwm_amount = 0; + #if ENABLED(CHAMBER_VENT) + if (!flag_chamber_off) MOVE_SERVO(CHAMBER_VENT_SERVO_NR, temp_chamber.celsius <= temp_chamber.target ? 0 : 90); + #endif + } + else { + #if ENABLED(CHAMBER_LIMIT_SWITCHING) + if (temp_chamber.celsius >= temp_chamber.target + TEMP_CHAMBER_HYSTERESIS) + temp_chamber.soft_pwm_amount = 0; + else if (temp_chamber.celsius <= temp_chamber.target - (TEMP_CHAMBER_HYSTERESIS)) + temp_chamber.soft_pwm_amount = (MAX_CHAMBER_POWER) >> 1; + #else + temp_chamber.soft_pwm_amount = temp_chamber.celsius < temp_chamber.target ? (MAX_CHAMBER_POWER) >> 1 : 0; + #endif + #if ENABLED(CHAMBER_VENT) + if (!flag_chamber_off) MOVE_SERVO(CHAMBER_VENT_SERVO_NR, 0); + #endif + } } else { temp_chamber.soft_pwm_amount = 0; @@ -1220,7 +1287,7 @@ void Temperature::manage_heater() { } #if ENABLED(THERMAL_PROTECTION_CHAMBER) - thermal_runaway_protection(tr_state_machine_chamber, temp_chamber.celsius, temp_chamber.target, H_CHAMBER, THERMAL_PROTECTION_CHAMBER_PERIOD, THERMAL_PROTECTION_CHAMBER_HYSTERESIS); + tr_state_machine[RUNAWAY_IND_CHAMBER].run(temp_chamber.celsius, temp_chamber.target, H_CHAMBER, THERMAL_PROTECTION_CHAMBER_PERIOD, THERMAL_PROTECTION_CHAMBER_HYSTERESIS); #endif } @@ -1232,29 +1299,29 @@ void Temperature::manage_heater() { UNUSED(ms); } -#define TEMP_AD595(RAW) ((RAW) * 5.0 * 100.0 / 1024.0 / (OVERSAMPLENR) * (TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET) -#define TEMP_AD8495(RAW) ((RAW) * 6.6 * 100.0 / 1024.0 / (OVERSAMPLENR) * (TEMP_SENSOR_AD8495_GAIN) + TEMP_SENSOR_AD8495_OFFSET) +#define TEMP_AD595(RAW) ((RAW) * 5.0 * 100.0 / float(HAL_ADC_RANGE) / (OVERSAMPLENR) * (TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET) +#define TEMP_AD8495(RAW) ((RAW) * 6.6 * 100.0 / float(HAL_ADC_RANGE) / (OVERSAMPLENR) * (TEMP_SENSOR_AD8495_GAIN) + TEMP_SENSOR_AD8495_OFFSET) /** * Bisect search for the range of the 'raw' value, then interpolate * proportionally between the under and over values. */ -#define SCAN_THERMISTOR_TABLE(TBL,LEN) do{ \ - uint8_t l = 0, r = LEN, m; \ - for (;;) { \ - m = (l + r) >> 1; \ - if (!m) return short(pgm_read_word(&TBL[0][1])); \ - if (m == l || m == r) return short(pgm_read_word(&TBL[LEN-1][1])); \ - short v00 = pgm_read_word(&TBL[m-1][0]), \ - v10 = pgm_read_word(&TBL[m-0][0]); \ - if (raw < v00) r = m; \ - else if (raw > v10) l = m; \ - else { \ - const short v01 = short(pgm_read_word(&TBL[m-1][1])), \ - v11 = short(pgm_read_word(&TBL[m-0][1])); \ - return v01 + (raw - v00) * float(v11 - v01) / float(v10 - v00); \ - } \ - } \ +#define SCAN_THERMISTOR_TABLE(TBL,LEN) do{ \ + uint8_t l = 0, r = LEN, m; \ + for (;;) { \ + m = (l + r) >> 1; \ + if (!m) return int16_t(pgm_read_word(&TBL[0].celsius)); \ + if (m == l || m == r) return int16_t(pgm_read_word(&TBL[LEN-1].celsius)); \ + int16_t v00 = pgm_read_word(&TBL[m-1].value), \ + v10 = pgm_read_word(&TBL[m-0].value); \ + if (raw < v00) r = m; \ + else if (raw > v10) l = m; \ + else { \ + const int16_t v01 = int16_t(pgm_read_word(&TBL[m-1].celsius)), \ + v11 = int16_t(pgm_read_word(&TBL[m-0].celsius)); \ + return v01 + (raw - v00) * float(v11 - v01) / float(v10 - v00); \ + } \ + } \ }while(0) #if HAS_USER_THERMISTORS @@ -1310,40 +1377,20 @@ void Temperature::manage_heater() { SERIAL_ECHOPAIR_F(" R", t.series_res, 1); SERIAL_ECHOPAIR_F_P(SP_T_STR, t.res_25, 1); - SERIAL_ECHOPAIR_F(" B", t.beta, 1); - SERIAL_ECHOPAIR_F(" C", t.sh_c_coeff, 9); + SERIAL_ECHOPAIR_F_P(SP_B_STR, t.beta, 1); + SERIAL_ECHOPAIR_F_P(SP_C_STR, t.sh_c_coeff, 9); SERIAL_ECHOPGM(" ; "); serialprintPGM( - #if ENABLED(HEATER_0_USER_THERMISTOR) - t_index == CTI_HOTEND_0 ? PSTR("HOTEND 0") : - #endif - #if ENABLED(HEATER_1_USER_THERMISTOR) - t_index == CTI_HOTEND_1 ? PSTR("HOTEND 1") : - #endif - #if ENABLED(HEATER_2_USER_THERMISTOR) - t_index == CTI_HOTEND_2 ? PSTR("HOTEND 2") : - #endif - #if ENABLED(HEATER_3_USER_THERMISTOR) - t_index == CTI_HOTEND_3 ? PSTR("HOTEND 3") : - #endif - #if ENABLED(HEATER_4_USER_THERMISTOR) - t_index == CTI_HOTEND_4 ? PSTR("HOTEND 4") : - #endif - #if ENABLED(HEATER_5_USER_THERMISTOR) - t_index == CTI_HOTEND_5 ? PSTR("HOTEND 5") : - #endif - #if ENABLED(HEATER_6_USER_THERMISTOR) - t_index == CTI_HOTEND_6 ? PSTR("HOTEND 6") : - #endif - #if ENABLED(HEATER_7_USER_THERMISTOR) - t_index == CTI_HOTEND_7 ? PSTR("HOTEND 7") : - #endif - #if ENABLED(HEATER_BED_USER_THERMISTOR) - t_index == CTI_BED ? PSTR("BED") : - #endif - #if ENABLED(HEATER_CHAMBER_USER_THERMISTOR) - t_index == CTI_CHAMBER ? PSTR("CHAMBER") : - #endif + TERN_(HEATER_0_USER_THERMISTOR, t_index == CTI_HOTEND_0 ? PSTR("HOTEND 0") :) + TERN_(HEATER_1_USER_THERMISTOR, t_index == CTI_HOTEND_1 ? PSTR("HOTEND 1") :) + TERN_(HEATER_2_USER_THERMISTOR, t_index == CTI_HOTEND_2 ? PSTR("HOTEND 2") :) + TERN_(HEATER_3_USER_THERMISTOR, t_index == CTI_HOTEND_3 ? PSTR("HOTEND 3") :) + TERN_(HEATER_4_USER_THERMISTOR, t_index == CTI_HOTEND_4 ? PSTR("HOTEND 4") :) + TERN_(HEATER_5_USER_THERMISTOR, t_index == CTI_HOTEND_5 ? PSTR("HOTEND 5") :) + TERN_(HEATER_6_USER_THERMISTOR, t_index == CTI_HOTEND_6 ? PSTR("HOTEND 6") :) + TERN_(HEATER_7_USER_THERMISTOR, t_index == CTI_HOTEND_7 ? PSTR("HOTEND 7") :) + TERN_(HEATER_BED_USER_THERMISTOR, t_index == CTI_BED ? PSTR("BED") :) + TERN_(HEATER_CHAMBER_USER_THERMISTOR, t_index == CTI_CHAMBER ? PSTR("CHAMBER") :) nullptr ); SERIAL_EOL(); @@ -1395,16 +1442,11 @@ void Temperature::manage_heater() { } #endif -#if HOTENDS +#if HAS_HOTEND // Derived from RepRap FiveD extruder::getTemperature() // For hot end temperature measurement. float Temperature::analog_to_celsius_hotend(const int raw, const uint8_t e) { - #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) - if (e > HOTENDS) - #else - if (e >= HOTENDS) - #endif - { + if (e > HOTENDS - DISABLED(TEMP_SENSOR_1_AS_REDUNDANT)) { SERIAL_ERROR_START(); SERIAL_ECHO((int)e); SERIAL_ECHOLNPGM(STR_INVALID_EXTRUDER_NUM); @@ -1419,7 +1461,7 @@ void Temperature::manage_heater() { #elif ENABLED(HEATER_0_USES_MAX6675) return ( #if ENABLED(MAX6675_IS_MAX31865) - max31865.temperature(100, 400) // 100 ohms = PT100 resistance. 400 ohms = calibration resistor + max31865.temperature(MAX31865_SENSOR_OHMS, MAX31865_CALIBRATION_OHMS) #else raw * 0.25 #endif @@ -1508,13 +1550,13 @@ void Temperature::manage_heater() { #if HOTEND_USES_THERMISTOR // Thermistor with conversion table? - const short(*tt)[][2] = (short(*)[][2])(heater_ttbl_map[e]); + const temp_entry_t(*tt)[] = (temp_entry_t(*)[])(heater_ttbl_map[e]); SCAN_THERMISTOR_TABLE((*tt), heater_ttbllen_map[e]); #endif return 0; } -#endif // HOTENDS +#endif // HAS_HOTEND #if HAS_HEATED_BED // Derived from RepRap FiveD extruder::getTemperature() @@ -1586,24 +1628,16 @@ void Temperature::updateTemperaturesFromRawValues() { #if ENABLED(HEATER_1_USES_MAX6675) temp_hotend[1].raw = READ_MAX6675(1); #endif - #if HOTENDS + #if HAS_HOTEND HOTEND_LOOP() temp_hotend[e].celsius = analog_to_celsius_hotend(temp_hotend[e].raw, e); #endif - #if HAS_HEATED_BED - temp_bed.celsius = analog_to_celsius_bed(temp_bed.raw); - #endif - #if HAS_TEMP_CHAMBER - temp_chamber.celsius = analog_to_celsius_chamber(temp_chamber.raw); - #endif - #if HAS_TEMP_PROBE - temp_probe.celsius = analog_to_celsius_probe(temp_probe.raw); - #endif - #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) - redundant_temperature = analog_to_celsius_hotend(redundant_temperature_raw, 1); - #endif - #if ENABLED(FILAMENT_WIDTH_SENSOR) - filwidth.update_measured_mm(); - #endif + + TERN_(HAS_HEATED_BED, temp_bed.celsius = analog_to_celsius_bed(temp_bed.raw)); + TERN_(HAS_TEMP_CHAMBER, temp_chamber.celsius = analog_to_celsius_chamber(temp_chamber.raw)); + TERN_(HAS_TEMP_PROBE, temp_probe.celsius = analog_to_celsius_probe(temp_probe.raw)); + TERN_(TEMP_SENSOR_1_AS_REDUNDANT, redundant_temperature = analog_to_celsius_hotend(redundant_temperature_raw, 1)); + TERN_(FILAMENT_WIDTH_SENSOR, filwidth.update_measured_mm()); + TERN_(HAS_POWER_MONITOR, power_monitor.capture_values()); // Reset the watchdog on good temperature measurement watchdog_refresh(); @@ -1612,6 +1646,7 @@ void Temperature::updateTemperaturesFromRawValues() { } #if MAX6675_SEPARATE_SPI + template SoftSPI SPIclass::softSPI; SPIclass max6675_spi; #endif @@ -1633,12 +1668,12 @@ void Temperature::updateTemperaturesFromRawValues() { #endif #define INIT_FAN_PIN(P) do{ _INIT_FAN_PIN(P); SET_FAST_PWM_FREQ(P); }while(0) #if EXTRUDER_AUTO_FAN_SPEED != 255 - #define INIT_E_AUTO_FAN_PIN(P) do{ if (P == FAN1_PIN || P == FAN2_PIN) { SET_PWM(P); SET_FAST_PWM_FREQ(FAST_PWM_FAN_FREQUENCY); } else SET_OUTPUT(P); }while(0) + #define INIT_E_AUTO_FAN_PIN(P) do{ if (P == FAN1_PIN || P == FAN2_PIN) { SET_PWM(P); SET_FAST_PWM_FREQ(P); } else SET_OUTPUT(P); }while(0) #else #define INIT_E_AUTO_FAN_PIN(P) SET_OUTPUT(P) #endif #if CHAMBER_AUTO_FAN_SPEED != 255 - #define INIT_CHAMBER_AUTO_FAN_PIN(P) do{ if (P == FAN1_PIN || P == FAN2_PIN) { SET_PWM(P); SET_FAST_PWM_FREQ(FAST_PWM_FAN_FREQUENCY); } else SET_OUTPUT(P); }while(0) + #define INIT_CHAMBER_AUTO_FAN_PIN(P) do{ if (P == FAN1_PIN || P == FAN2_PIN) { SET_PWM(P); SET_FAST_PWM_FREQ(P); } else SET_OUTPUT(P); }while(0) #else #define INIT_CHAMBER_AUTO_FAN_PIN(P) SET_OUTPUT(P) #endif @@ -1649,9 +1684,7 @@ void Temperature::updateTemperaturesFromRawValues() { */ void Temperature::init() { - #if ENABLED(MAX6675_IS_MAX31865) - max31865.begin(MAX31865_2WIRE); // MAX31865_2WIRE, MAX31865_3WIRE, MAX31865_4WIRE - #endif + TERN_(MAX6675_IS_MAX31865, max31865.begin(MAX31865_2WIRE)); // MAX31865_2WIRE, MAX31865_3WIRE, MAX31865_4WIRE #if EARLY_WATCHDOG // Flag that the thermalManager should be running @@ -1660,15 +1693,22 @@ void Temperature::init() { #endif #if MB(RUMBA) + // Disable RUMBA JTAG in case the thermocouple extension is plugged on top of JTAG connector #define _AD(N) ANY(HEATER_##N##_USES_AD595, HEATER_##N##_USES_AD8495) - #if _AD(0) || _AD(1) || _AD(2) /* RUMBA has 3 E plugs // || _AD(3) || _AD(4) || _AD(5) || _AD(6) || _AD(7) */ \ - || _AD(BED) || _AD(CHAMBER) - // Disable RUMBA JTAG in case the thermocouple extension is plugged on top of JTAG connector + #if _AD(0) || _AD(1) || _AD(2) || _AD(BED) || _AD(CHAMBER) MCUCR = _BV(JTD); MCUCR = _BV(JTD); #endif #endif + // Thermistor activation by MCU pin + #if PIN_EXISTS(TEMP_0_TR_ENABLE) + OUT_WRITE(TEMP_0_TR_ENABLE_PIN, ENABLED(HEATER_0_USES_MAX6675)); + #endif + #if PIN_EXISTS(TEMP_1_TR_ENABLE) + OUT_WRITE(TEMP_1_TR_ENABLE_PIN, ENABLED(HEATER_1_USES_MAX6675)); + #endif + #if BOTH(PIDTEMP, PID_EXTRUSION_SCALING) last_e_position = 0; #endif @@ -1813,6 +1853,12 @@ void Temperature::init() { #if HAS_ADC_BUTTONS HAL_ANALOG_SELECT(ADC_KEYPAD_PIN); #endif + #if ENABLED(POWER_MONITOR_CURRENT) + HAL_ANALOG_SELECT(POWER_MONITOR_CURRENT_PIN); + #endif + #if ENABLED(POWER_MONITOR_VOLTAGE) + HAL_ANALOG_SELECT(POWER_MONITOR_VOLTAGE_PIN); + #endif HAL_timer_start(TEMP_TIMER_NUM, TEMP_TIMER_FREQUENCY); ENABLE_TEMPERATURE_INTERRUPT(); @@ -1848,83 +1894,73 @@ void Temperature::init() { // Wait for temperature measurement to settle delay(250); - #if HOTENDS + #if HAS_HOTEND #define _TEMP_MIN_E(NR) do{ \ - temp_range[NR].mintemp = HEATER_ ##NR## _MINTEMP; \ - while (analog_to_celsius_hotend(temp_range[NR].raw_min, NR) < HEATER_ ##NR## _MINTEMP) \ + const int16_t tmin = _MAX(HEATER_ ##NR## _MINTEMP, TERN(HEATER_##NR##_USER_THERMISTOR, 0, (int16_t)pgm_read_word(&HEATER_ ##NR## _TEMPTABLE[HEATER_ ##NR## _SENSOR_MINTEMP_IND].celsius))); \ + temp_range[NR].mintemp = tmin; \ + while (analog_to_celsius_hotend(temp_range[NR].raw_min, NR) < tmin) \ temp_range[NR].raw_min += TEMPDIR(NR) * (OVERSAMPLENR); \ }while(0) #define _TEMP_MAX_E(NR) do{ \ - temp_range[NR].maxtemp = HEATER_ ##NR## _MAXTEMP; \ - while (analog_to_celsius_hotend(temp_range[NR].raw_max, NR) > HEATER_ ##NR## _MAXTEMP) \ + const int16_t tmax = _MIN(HEATER_ ##NR## _MAXTEMP, TERN(HEATER_##NR##_USER_THERMISTOR, 2000, (int16_t)pgm_read_word(&HEATER_ ##NR## _TEMPTABLE[HEATER_ ##NR## _SENSOR_MAXTEMP_IND].celsius) - 1)); \ + temp_range[NR].maxtemp = tmax; \ + while (analog_to_celsius_hotend(temp_range[NR].raw_max, NR) > tmax) \ temp_range[NR].raw_max -= TEMPDIR(NR) * (OVERSAMPLENR); \ }while(0) - #ifdef HEATER_0_MINTEMP + #define _MINMAX_TEST(N,M) (HOTENDS > N && THERMISTOR_HEATER_##N && THERMISTOR_HEATER_##N != 998 && THERMISTOR_HEATER_##N != 999 && defined(HEATER_##N##_##M##TEMP)) + + #if _MINMAX_TEST(0, MIN) _TEMP_MIN_E(0); #endif - #ifdef HEATER_0_MAXTEMP + #if _MINMAX_TEST(0, MAX) _TEMP_MAX_E(0); #endif - #if HOTENDS > 1 - #ifdef HEATER_1_MINTEMP - _TEMP_MIN_E(1); - #endif - #ifdef HEATER_1_MAXTEMP - _TEMP_MAX_E(1); - #endif - #if HOTENDS > 2 - #ifdef HEATER_2_MINTEMP - _TEMP_MIN_E(2); - #endif - #ifdef HEATER_2_MAXTEMP - _TEMP_MAX_E(2); - #endif - #if HOTENDS > 3 - #ifdef HEATER_3_MINTEMP - _TEMP_MIN_E(3); - #endif - #ifdef HEATER_3_MAXTEMP - _TEMP_MAX_E(3); - #endif - #if HOTENDS > 4 - #ifdef HEATER_4_MINTEMP - _TEMP_MIN_E(4); - #endif - #ifdef HEATER_4_MAXTEMP - _TEMP_MAX_E(4); - #endif - #if HOTENDS > 5 - #ifdef HEATER_5_MINTEMP - _TEMP_MIN_E(5); - #endif - #ifdef HEATER_5_MAXTEMP - _TEMP_MAX_E(5); - #endif - #if HOTENDS > 6 - #ifdef HEATER_6_MINTEMP - _TEMP_MIN_E(6); - #endif - #ifdef HEATER_6_MAXTEMP - _TEMP_MAX_E(6); - #endif - #if HOTENDS > 7 - #ifdef HEATER_7_MINTEMP - _TEMP_MIN_E(7); - #endif - #ifdef HEATER_7_MAXTEMP - _TEMP_MAX_E(7); - #endif - #endif // HOTENDS > 7 - #endif // HOTENDS > 6 - #endif // HOTENDS > 5 - #endif // HOTENDS > 4 - #endif // HOTENDS > 3 - #endif // HOTENDS > 2 - #endif // HOTENDS > 1 - - #endif // HOTENDS + #if _MINMAX_TEST(1, MIN) + _TEMP_MIN_E(1); + #endif + #if _MINMAX_TEST(1, MAX) + _TEMP_MAX_E(1); + #endif + #if _MINMAX_TEST(2, MIN) + _TEMP_MIN_E(2); + #endif + #if _MINMAX_TEST(2, MAX) + _TEMP_MAX_E(2); + #endif + #if _MINMAX_TEST(3, MIN) + _TEMP_MIN_E(3); + #endif + #if _MINMAX_TEST(3, MAX) + _TEMP_MAX_E(3); + #endif + #if _MINMAX_TEST(4, MIN) + _TEMP_MIN_E(4); + #endif + #if _MINMAX_TEST(4, MAX) + _TEMP_MAX_E(4); + #endif + #if _MINMAX_TEST(5, MIN) + _TEMP_MIN_E(5); + #endif + #if _MINMAX_TEST(5, MAX) + _TEMP_MAX_E(5); + #endif + #if _MINMAX_TEST(6, MIN) + _TEMP_MIN_E(6); + #endif + #if _MINMAX_TEST(6, MAX) + _TEMP_MAX_E(6); + #endif + #if _MINMAX_TEST(7, MIN) + _TEMP_MIN_E(7); + #endif + #if _MINMAX_TEST(7, MAX) + _TEMP_MAX_E(7); + #endif + + #endif // HAS_HOTEND #if HAS_HEATED_BED #ifdef BED_MINTEMP @@ -1944,9 +1980,7 @@ void Temperature::init() { #endif #endif - #if ENABLED(PROBING_HEATERS_OFF) - paused = false; - #endif + TERN_(PROBING_HEATERS_OFF, paused = false); } #if WATCH_HOTENDS @@ -1985,63 +2019,66 @@ void Temperature::init() { #if HAS_THERMAL_PROTECTION - #if ENABLED(THERMAL_PROTECTION_HOTENDS) - Temperature::tr_state_machine_t Temperature::tr_state_machine[HOTENDS]; // = { { TRInactive, 0 } }; - #endif - #if HAS_THERMALLY_PROTECTED_BED - Temperature::tr_state_machine_t Temperature::tr_state_machine_bed; // = { TRInactive, 0 }; - #endif - #if ENABLED(THERMAL_PROTECTION_CHAMBER) - Temperature::tr_state_machine_t Temperature::tr_state_machine_chamber; // = { TRInactive, 0 }; - #endif + Temperature::tr_state_machine_t Temperature::tr_state_machine[NR_HEATER_RUNAWAY]; // = { { TRInactive, 0 } }; - void Temperature::thermal_runaway_protection(Temperature::tr_state_machine_t &sm, const float ¤t, const float &target, const heater_ind_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc) { + /** + * @brief Thermal Runaway state machine for a single heater + * @param current current measured temperature + * @param target current target temperature + * @param heater_id extruder index + * @param period_seconds missed temperature allowed time + * @param hysteresis_degc allowed distance from target + * + * TODO: Embed the last 3 parameters during init, if not less optimal + */ + void Temperature::tr_state_machine_t::run(const float ¤t, const float &target, const heater_id_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc) { - static float tr_target_temperature[HOTENDS + 1] = { 0.0 }; + #if HEATER_IDLE_HANDLER + // Convert the given heater_id_t to an idle array index + const IdleIndex idle_index = idle_index_for_id(heater_id); + #endif /** SERIAL_ECHO_START(); - SERIAL_ECHOPGM("Thermal Thermal Runaway Running. Heater ID: "); - if (heater_id == H_CHAMBER) SERIAL_ECHOPGM("chamber"); - if (heater_id < 0) SERIAL_ECHOPGM("bed"); else SERIAL_ECHO(heater_id); - SERIAL_ECHOPAIR(" ; State:", sm.state, " ; Timer:", sm.timer, " ; Temperature:", current, " ; Target Temp:", target); - if (heater_id >= 0) - SERIAL_ECHOPAIR(" ; Idle Timeout:", hotend_idle[heater_id].timed_out); - else - SERIAL_ECHOPAIR(" ; Idle Timeout:", bed_idle.timed_out); - SERIAL_EOL(); + SERIAL_ECHOPGM("Thermal Runaway Running. Heater ID: "); + switch (heater_id) { + case H_BED: SERIAL_ECHOPGM("bed"); break; + case H_CHAMBER: SERIAL_ECHOPGM("chamber"); break; + default: SERIAL_ECHO(heater_id); + } + SERIAL_ECHOLNPAIR( + " ; sizeof(running_temp):", sizeof(running_temp), + " ; State:", state, " ; Timer:", timer, " ; Temperature:", current, " ; Target Temp:", target + #if HEATER_IDLE_HANDLER + , " ; Idle Timeout:", heater_idle[idle_index].timed_out + #endif + ); //*/ - const int heater_index = heater_id >= 0 ? heater_id : HOTENDS; - #if HEATER_IDLE_HANDLER // If the heater idle timeout expires, restart - if ((heater_id >= 0 && hotend_idle[heater_id].timed_out) - #if HAS_HEATED_BED - || (heater_id < 0 && bed_idle.timed_out) - #endif - ) { - sm.state = TRInactive; - tr_target_temperature[heater_index] = 0; + if (heater_idle[idle_index].timed_out) { + state = TRInactive; + running_temp = 0; } else #endif { // If the target temperature changes, restart - if (tr_target_temperature[heater_index] != target) { - tr_target_temperature[heater_index] = target; - sm.state = target > 0 ? TRFirstHeating : TRInactive; + if (running_temp != target) { + running_temp = target; + state = target > 0 ? TRFirstHeating : TRInactive; } } - switch (sm.state) { + switch (state) { // Inactive state waits for a target temperature to be set case TRInactive: break; // When first heating, wait for the temperature to be reached then go to Stable state case TRFirstHeating: - if (current < tr_target_temperature[heater_index]) break; - sm.state = TRStable; + if (current < running_temp) break; + state = TRStable; // While the temperature is stable watch for a bad temperature case TRStable: @@ -2049,27 +2086,28 @@ void Temperature::init() { #if ENABLED(ADAPTIVE_FAN_SLOWING) if (adaptive_fan_slowing && heater_id >= 0) { const int fan_index = _MIN(heater_id, FAN_COUNT - 1); - if (fan_speed[fan_index] == 0 || current >= tr_target_temperature[heater_id] - (hysteresis_degc * 0.25f)) + if (fan_speed[fan_index] == 0 || current >= running_temp - (hysteresis_degc * 0.25f)) fan_speed_scaler[fan_index] = 128; - else if (current >= tr_target_temperature[heater_id] - (hysteresis_degc * 0.3335f)) + else if (current >= running_temp - (hysteresis_degc * 0.3335f)) fan_speed_scaler[fan_index] = 96; - else if (current >= tr_target_temperature[heater_id] - (hysteresis_degc * 0.5f)) + else if (current >= running_temp - (hysteresis_degc * 0.5f)) fan_speed_scaler[fan_index] = 64; - else if (current >= tr_target_temperature[heater_id] - (hysteresis_degc * 0.8f)) + else if (current >= running_temp - (hysteresis_degc * 0.8f)) fan_speed_scaler[fan_index] = 32; else fan_speed_scaler[fan_index] = 0; } #endif - if (current >= tr_target_temperature[heater_index] - hysteresis_degc) { - sm.timer = millis() + period_seconds * 1000UL; + if (current >= running_temp - hysteresis_degc) { + timer = millis() + SEC_TO_MS(period_seconds); break; } - else if (PENDING(millis(), sm.timer)) break; - sm.state = TRRunaway; + else if (PENDING(millis(), timer)) break; + state = TRRunaway; case TRRunaway: + TERN_(DWIN_CREALITY_LCD, DWIN_Popup_Temperature(0)); _temp_error(heater_id, str_t_thermal_runaway, GET_TEXT(MSG_THERMAL_RUNAWAY)); } } @@ -2078,45 +2116,31 @@ void Temperature::init() { void Temperature::disable_all_heaters() { - #if ENABLED(AUTOTEMP) - planner.autotemp_enabled = false; - #endif - - #if HOTENDS - HOTEND_LOOP() setTargetHotend(0, e); - #endif - - #if HAS_HEATED_BED - setTargetBed(0); - #endif - - #if HAS_HEATED_CHAMBER - setTargetChamber(0); - #endif + TERN_(AUTOTEMP, planner.autotemp_enabled = false); // Unpause and reset everything - #if ENABLED(PROBING_HEATERS_OFF) - pause(false); - #endif + TERN_(PROBING_HEATERS_OFF, pause(false)); - #define DISABLE_HEATER(N) { \ - setTargetHotend(0, N); \ - temp_hotend[N].soft_pwm_amount = 0; \ - WRITE_HEATER_##N(LOW); \ - } + #if HAS_HOTEND + HOTEND_LOOP() { + setTargetHotend(0, e); + temp_hotend[e].soft_pwm_amount = 0; + } + #endif #if HAS_TEMP_HOTEND + #define DISABLE_HEATER(N) WRITE_HEATER_##N(LOW); REPEAT(HOTENDS, DISABLE_HEATER); #endif #if HAS_HEATED_BED - temp_bed.target = 0; + setTargetBed(0); temp_bed.soft_pwm_amount = 0; WRITE_HEATER_BED(LOW); #endif #if HAS_HEATED_CHAMBER - temp_chamber.target = 0; + setTargetChamber(0); temp_chamber.soft_pwm_amount = 0; WRITE_HEATER_CHAMBER(LOW); #endif @@ -2125,16 +2149,11 @@ void Temperature::disable_all_heaters() { #if ENABLED(PRINTJOB_TIMER_AUTOSTART) bool Temperature::over_autostart_threshold() { - #if HOTENDS + #if HAS_HOTEND HOTEND_LOOP() if (degTargetHotend(e) > (EXTRUDE_MINTEMP) / 2) return true; #endif - #if HAS_HEATED_BED - if (degTargetBed() > BED_MINTEMP) return true; - #endif - #if HAS_HEATED_CHAMBER - if (degTargetChamber() > CHAMBER_MINTEMP) return true; - #endif - return false; + return TERN0(HAS_HEATED_BED, degTargetBed() > BED_MINTEMP) + || TERN0(HAS_HEATED_CHAMBER, degTargetChamber() > CHAMBER_MINTEMP); } void Temperature::check_timer_autostart(const bool can_start, const bool can_stop) { @@ -2156,16 +2175,12 @@ void Temperature::disable_all_heaters() { if (p != paused) { paused = p; if (p) { - HOTEND_LOOP() hotend_idle[e].expire(); // timeout immediately - #if HAS_HEATED_BED - bed_idle.expire(); // timeout immediately - #endif + HOTEND_LOOP() heater_idle[e].expire(); // Timeout immediately + TERN_(HAS_HEATED_BED, heater_idle[IDLE_INDEX_BED].expire()); // Timeout immediately } else { HOTEND_LOOP() reset_hotend_idle_timer(e); - #if HAS_HEATED_BED - reset_bed_idle_timer(); - #endif + TERN_(HAS_HEATED_BED, reset_bed_idle_timer()); } } } @@ -2174,6 +2189,10 @@ void Temperature::disable_all_heaters() { #if HAS_MAX6675 + #ifndef THERMOCOUPLE_MAX_ERRORS + #define THERMOCOUPLE_MAX_ERRORS 15 + #endif + int Temperature::read_max6675( #if COUNT_6675 > 1 const uint8_t hindex @@ -2186,6 +2205,8 @@ void Temperature::disable_all_heaters() { static uint16_t max6675_temp_previous[COUNT_6675] = { 0 }; #endif + static uint8_t max6675_errors[COUNT_6675] = { 0 }; + #define MAX6675_HEAT_INTERVAL 250UL #if ENABLED(MAX6675_IS_MAX31855) @@ -2215,7 +2236,7 @@ void Temperature::disable_all_heaters() { next_max6675_ms[hindex] = ms + MAX6675_HEAT_INTERVAL; #if ENABLED(MAX6675_IS_MAX31865) - max6675_temp = int(max31865.temperature(100, 400)); // 100 ohms = PT100 resistance. 400 ohms = calibration resistor + max6675_temp = int(max31865.temperature(MAX31865_SENSOR_OHMS, MAX31865_CALIBRATION_OHMS)); #endif // @@ -2257,34 +2278,39 @@ void Temperature::disable_all_heaters() { WRITE_MAX6675(HIGH); // disable TT_MAX6675 - if (max6675_temp & MAX6675_ERROR_MASK) { - SERIAL_ERROR_START(); - SERIAL_ECHOPGM("Temp measurement error! "); - #if MAX6675_ERROR_MASK == 7 - SERIAL_ECHOPGM("MAX31855 "); - if (max6675_temp & 1) - SERIAL_ECHOLNPGM("Open Circuit"); - else if (max6675_temp & 2) - SERIAL_ECHOLNPGM("Short to GND"); - else if (max6675_temp & 4) - SERIAL_ECHOLNPGM("Short to VCC"); - #else - SERIAL_ECHOLNPGM("MAX6675"); - #endif - - // Thermocouple open - max6675_temp = 4 * ( - #if COUNT_6675 > 1 - hindex ? HEATER_1_MAX6675_TMAX : HEATER_0_MAX6675_TMAX - #elif ENABLED(HEATER_1_USES_MAX6675) - HEATER_1_MAX6675_TMAX + if (DISABLED(IGNORE_THERMOCOUPLE_ERRORS) && (max6675_temp & MAX6675_ERROR_MASK)) { + max6675_errors[hindex] += 1; + if (max6675_errors[hindex] > THERMOCOUPLE_MAX_ERRORS) { + SERIAL_ERROR_START(); + SERIAL_ECHOPGM("Temp measurement error! "); + #if MAX6675_ERROR_MASK == 7 + SERIAL_ECHOPGM("MAX31855 "); + if (max6675_temp & 1) + SERIAL_ECHOLNPGM("Open Circuit"); + else if (max6675_temp & 2) + SERIAL_ECHOLNPGM("Short to GND"); + else if (max6675_temp & 4) + SERIAL_ECHOLNPGM("Short to VCC"); #else - HEATER_0_MAX6675_TMAX + SERIAL_ECHOLNPGM("MAX6675"); #endif - ); + + // Thermocouple open + max6675_temp = 4 * ( + #if COUNT_6675 > 1 + hindex ? HEATER_1_MAX6675_TMAX : HEATER_0_MAX6675_TMAX + #else + TERN(HEATER_1_USES_MAX6675, HEATER_1_MAX6675_TMAX, HEATER_0_MAX6675_TMAX) + #endif + ); + } + else + max6675_temp >>= MAX6675_DISCARD_BITS; } - else + else { max6675_temp >>= MAX6675_DISCARD_BITS; + max6675_errors[hindex] = 0; + } #if ENABLED(MAX6675_IS_MAX31855) if (max6675_temp & 0x00002000) max6675_temp |= 0xFFFFC000; // Support negative temperature @@ -2316,46 +2342,19 @@ void Temperature::update_raw_temperatures() { #endif #endif - #if HAS_TEMP_ADC_2 - temp_hotend[2].update(); - #endif - #if HAS_TEMP_ADC_3 - temp_hotend[3].update(); - #endif - #if HAS_TEMP_ADC_4 - temp_hotend[4].update(); - #endif - #if HAS_TEMP_ADC_5 - temp_hotend[5].update(); - #endif - #if HAS_TEMP_ADC_6 - temp_hotend[6].update(); - #endif - #if HAS_TEMP_ADC_7 - temp_hotend[7].update(); - #endif - - #if HAS_HEATED_BED - temp_bed.update(); - #endif - - #if HAS_TEMP_CHAMBER - temp_chamber.update(); - #endif - - #if HAS_TEMP_PROBE - temp_probe.update(); - #endif + TERN_(HAS_TEMP_ADC_2, temp_hotend[2].update()); + TERN_(HAS_TEMP_ADC_3, temp_hotend[3].update()); + TERN_(HAS_TEMP_ADC_4, temp_hotend[4].update()); + TERN_(HAS_TEMP_ADC_5, temp_hotend[5].update()); + TERN_(HAS_TEMP_ADC_6, temp_hotend[6].update()); + TERN_(HAS_TEMP_ADC_7, temp_hotend[7].update()); + TERN_(HAS_HEATED_BED, temp_bed.update()); + TERN_(HAS_TEMP_CHAMBER, temp_chamber.update()); + TERN_(HAS_TEMP_PROBE, temp_probe.update()); - #if HAS_JOY_ADC_X - joystick.x.update(); - #endif - #if HAS_JOY_ADC_Y - joystick.y.update(); - #endif - #if HAS_JOY_ADC_Z - joystick.z.update(); - #endif + TERN_(HAS_JOY_ADC_X, joystick.x.update()); + TERN_(HAS_JOY_ADC_Y, joystick.y.update()); + TERN_(HAS_JOY_ADC_Z, joystick.z.update()); raw_temps_ready = true; } @@ -2366,75 +2365,47 @@ void Temperature::readings_ready() { if (!raw_temps_ready) update_raw_temperatures(); // Filament Sensor - can be read any time since IIR filtering is used - #if ENABLED(FILAMENT_WIDTH_SENSOR) - filwidth.reading_ready(); - #endif + TERN_(FILAMENT_WIDTH_SENSOR, filwidth.reading_ready()); - #if HOTENDS + #if HAS_HOTEND HOTEND_LOOP() temp_hotend[e].reset(); - #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) - temp_hotend[1].reset(); - #endif - #endif - - #if HAS_HEATED_BED - temp_bed.reset(); - #endif - - #if HAS_TEMP_CHAMBER - temp_chamber.reset(); + TERN_(TEMP_SENSOR_1_AS_REDUNDANT, temp_hotend[1].reset()); #endif - #if HAS_TEMP_PROBE - temp_probe.reset(); - #endif + TERN_(HAS_HEATED_BED, temp_bed.reset()); + TERN_(HAS_TEMP_CHAMBER, temp_chamber.reset()); + TERN_(HAS_TEMP_PROBE, temp_probe.reset()); - #if HAS_JOY_ADC_X - joystick.x.reset(); - #endif - #if HAS_JOY_ADC_Y - joystick.y.reset(); - #endif - #if HAS_JOY_ADC_Z - joystick.z.reset(); - #endif + TERN_(HAS_JOY_ADC_X, joystick.x.reset()); + TERN_(HAS_JOY_ADC_Y, joystick.y.reset()); + TERN_(HAS_JOY_ADC_Z, joystick.z.reset()); - #if HOTENDS + #if HAS_HOTEND static constexpr int8_t temp_dir[] = { - #if ENABLED(HEATER_0_USES_MAX6675) - 0 - #else - TEMPDIR(0) - #endif - #if HOTENDS > 1 - #define _TEMPDIR(N) , TEMPDIR(N) - #if ENABLED(HEATER_1_USES_MAX6675) - , 0 - #else - _TEMPDIR(1) - #endif + TERN(HEATER_0_USES_MAX6675, 0, TEMPDIR(0)) + #if HAS_MULTI_HOTEND + , TERN(HEATER_1_USES_MAX6675, 0, TEMPDIR(1)) #if HOTENDS > 2 + #define _TEMPDIR(N) , TEMPDIR(N) REPEAT_S(2, HOTENDS, _TEMPDIR) - #endif // HOTENDS > 2 - #endif // HOTENDS > 1 + #endif + #endif }; - for (uint8_t e = 0; e < COUNT(temp_dir); e++) { + LOOP_L_N(e, COUNT(temp_dir)) { const int8_t tdir = temp_dir[e]; if (tdir) { const int16_t rawtemp = temp_hotend[e].raw * tdir; // normal direction, +rawtemp, else -rawtemp const bool heater_on = (temp_hotend[e].target > 0 - #if ENABLED(PIDTEMP) - || temp_hotend[e].soft_pwm_amount > 0 - #endif + || TERN0(PIDTEMP, temp_hotend[e].soft_pwm_amount) > 0 ); - if (rawtemp > temp_range[e].raw_max * tdir) max_temp_error((heater_ind_t)e); + if (rawtemp > temp_range[e].raw_max * tdir) max_temp_error((heater_id_t)e); if (heater_on && rawtemp < temp_range[e].raw_min * tdir && !is_preheating(e)) { #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED if (++consecutive_low_temperature_error[e] >= MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED) #endif - min_temp_error((heater_ind_t)e); + min_temp_error((heater_id_t)e); } #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED else @@ -2443,28 +2414,24 @@ void Temperature::readings_ready() { } } - #endif // HOTENDS + #endif // HAS_HOTEND #if HAS_HEATED_BED #if TEMPDIR(BED) < 0 - #define BEDCMP(A,B) ((A)<=(B)) + #define BEDCMP(A,B) ((A)<(B)) #else - #define BEDCMP(A,B) ((A)>=(B)) + #define BEDCMP(A,B) ((A)>(B)) #endif - const bool bed_on = (temp_bed.target > 0) - #if ENABLED(PIDTEMPBED) - || (temp_bed.soft_pwm_amount > 0) - #endif - ; + const bool bed_on = (temp_bed.target > 0) || TERN0(PIDTEMPBED, temp_bed.soft_pwm_amount > 0); if (BEDCMP(temp_bed.raw, maxtemp_raw_BED)) max_temp_error(H_BED); if (bed_on && BEDCMP(mintemp_raw_BED, temp_bed.raw)) min_temp_error(H_BED); #endif #if HAS_HEATED_CHAMBER #if TEMPDIR(CHAMBER) < 0 - #define CHAMBERCMP(A,B) ((A)<=(B)) + #define CHAMBERCMP(A,B) ((A)<(B)) #else - #define CHAMBERCMP(A,B) ((A)>=(B)) + #define CHAMBERCMP(A,B) ((A)>(B)) #endif const bool chamber_on = (temp_chamber.target > 0); if (CHAMBERCMP(temp_chamber.raw, maxtemp_raw_CHAMBER)) max_temp_error(H_CHAMBER); @@ -2543,7 +2510,7 @@ void Temperature::tick() { static bool ADCKey_pressed = false; #endif - #if HOTENDS + #if HAS_HOTEND static SoftPWM soft_pwm_hotend[HOTENDS]; #endif @@ -2557,14 +2524,8 @@ void Temperature::tick() { #if DISABLED(SLOW_PWM_HEATERS) - #if HOTENDS || HAS_HEATED_BED || HAS_HEATED_CHAMBER - constexpr uint8_t pwm_mask = - #if ENABLED(SOFT_PWM_DITHER) - _BV(SOFT_PWM_SCALE) - 1 - #else - 0 - #endif - ; + #if ANY(HAS_HOTEND, HAS_HEATED_BED, HAS_HEATED_CHAMBER, FAN_SOFT_PWM) + constexpr uint8_t pwm_mask = TERN0(SOFT_PWM_DITHER, _BV(SOFT_PWM_SCALE) - 1); #define _PWM_MOD(N,S,T) do{ \ const bool on = S.add(pwm_mask, T.soft_pwm_amount); \ WRITE_HEATER_##N(on); \ @@ -2577,7 +2538,7 @@ void Temperature::tick() { if (pwm_count_tmp >= 127) { pwm_count_tmp -= 127; - #if HOTENDS + #if HAS_HOTEND #define _PWM_MOD_E(N) _PWM_MOD(N,soft_pwm_hotend[N],temp_hotend[N]); REPEAT(HOTENDS, _PWM_MOD_E); #endif @@ -2624,7 +2585,7 @@ void Temperature::tick() { } else { #define _PWM_LOW(N,S) do{ if (S.count <= pwm_count_tmp) WRITE_HEATER_##N(LOW); }while(0) - #if HOTENDS + #if HAS_HOTEND #define _PWM_LOW_E(N) _PWM_LOW(N, soft_pwm_hotend[N]); REPEAT(HOTENDS, _PWM_LOW_E); #endif @@ -2690,7 +2651,7 @@ void Temperature::tick() { if (slow_pwm_count == 0) { - #if HOTENDS + #if HAS_HOTEND #define _SLOW_PWM_E(N) _SLOW_PWM(N, soft_pwm_hotend[N], temp_hotend[N]); REPEAT(HOTENDS, _SLOW_PWM_E); #endif @@ -2699,9 +2660,13 @@ void Temperature::tick() { _SLOW_PWM(BED, soft_pwm_bed, temp_bed); #endif + #if HAS_HEATED_CHAMBER + _SLOW_PWM(CHAMBER, soft_pwm_chamber, temp_chamber); + #endif + } // slow_pwm_count == 0 - #if HOTENDS + #if HAS_HOTEND #define _PWM_OFF_E(N) _PWM_OFF(N, soft_pwm_hotend[N]); REPEAT(HOTENDS, _PWM_OFF_E); #endif @@ -2710,6 +2675,10 @@ void Temperature::tick() { _PWM_OFF(BED, soft_pwm_bed); #endif + #if HAS_HEATED_CHAMBER + _PWM_OFF(CHAMBER, soft_pwm_chamber); + #endif + #if ENABLED(FAN_SOFT_PWM) if (pwm_count_tmp >= 127) { pwm_count_tmp = 0; @@ -2784,13 +2753,12 @@ void Temperature::tick() { slow_pwm_count++; slow_pwm_count &= 0x7F; - #if HOTENDS + #if HAS_HOTEND HOTEND_LOOP() soft_pwm_hotend[e].dec(); #endif - #if HAS_HEATED_BED - soft_pwm_bed.dec(); - #endif - } // ((pwm_count >> SOFT_PWM_SCALE) & 0x3F) == 0 + TERN_(HAS_HEATED_BED, soft_pwm_bed.dec()); + TERN_(HAS_HEATED_CHAMBER, soft_pwm_chamber.dec()); + } #endif // SLOW_PWM_HEATERS @@ -2900,13 +2868,31 @@ void Temperature::tick() { #if ENABLED(FILAMENT_WIDTH_SENSOR) case Prepare_FILWIDTH: HAL_START_ADC(FILWIDTH_PIN); break; case Measure_FILWIDTH: - if (!HAL_ADC_READY()) - next_sensor_state = adc_sensor_state; // redo this state - else - filwidth.accumulate(HAL_READ_ADC()); + if (!HAL_ADC_READY()) next_sensor_state = adc_sensor_state; // Redo this state + else filwidth.accumulate(HAL_READ_ADC()); break; #endif + #if ENABLED(POWER_MONITOR_CURRENT) + case Prepare_POWER_MONITOR_CURRENT: + HAL_START_ADC(POWER_MONITOR_CURRENT_PIN); + break; + case Measure_POWER_MONITOR_CURRENT: + if (!HAL_ADC_READY()) next_sensor_state = adc_sensor_state; // Redo this state + else power_monitor.add_current_sample(HAL_READ_ADC()); + break; + #endif + + #if ENABLED(POWER_MONITOR_VOLTAGE) + case Prepare_POWER_MONITOR_VOLTAGE: + HAL_START_ADC(POWER_MONITOR_VOLTAGE_PIN); + break; + case Measure_POWER_MONITOR_VOLTAGE: + if (!HAL_ADC_READY()) next_sensor_state = adc_sensor_state; // Redo this state + else power_monitor.add_voltage_sample(HAL_READ_ADC()); + break; + #endif + #if HAS_JOY_ADC_X case PrepareJoy_X: HAL_START_ADC(JOY_X_PIN); break; case MeasureJoy_X: ACCUMULATE_ADC(joystick.x); break; @@ -2978,7 +2964,7 @@ void Temperature::tick() { #if ENABLED(SHOW_TEMP_ADC_VALUES) , const float r #endif - , const heater_ind_t e=INDEX_NONE + , const heater_id_t e=INDEX_NONE ) { char k; switch (e) { @@ -3002,7 +2988,7 @@ void Temperature::tick() { } SERIAL_CHAR(' '); SERIAL_CHAR(k); - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND if (e >= 0) SERIAL_CHAR('0' + e); #endif SERIAL_CHAR(':'); @@ -3064,26 +3050,26 @@ void Temperature::tick() { , H_PROBE ); #endif // HAS_TEMP_PROBE - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND HOTEND_LOOP() print_heater_state(degHotend(e), degTargetHotend(e) #if ENABLED(SHOW_TEMP_ADC_VALUES) , rawHotendTemp(e) #endif - , (heater_ind_t)e + , (heater_id_t)e ); #endif - SERIAL_ECHOPAIR(" @:", getHeaterPower((heater_ind_t)target_extruder)); + SERIAL_ECHOPAIR(" @:", getHeaterPower((heater_id_t)target_extruder)); #if HAS_HEATED_BED SERIAL_ECHOPAIR(" B@:", getHeaterPower(H_BED)); #endif #if HAS_HEATED_CHAMBER SERIAL_ECHOPAIR(" C@:", getHeaterPower(H_CHAMBER)); #endif - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND HOTEND_LOOP() { SERIAL_ECHOPAIR(" @", e); SERIAL_CHAR(':'); - SERIAL_ECHO(getHeaterPower((heater_ind_t)e)); + SERIAL_ECHO(getHeaterPower((heater_id_t)e)); } #endif } @@ -3104,11 +3090,11 @@ void Temperature::tick() { #endif // AUTO_REPORT_TEMPERATURES - #if HOTENDS && HAS_DISPLAY + #if HAS_HOTEND && HAS_DISPLAY void Temperature::set_heating_message(const uint8_t e) { const bool heating = isHeatingHotend(e); ui.status_printf_P(0, - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND PSTR("E%c " S_FMT), '1' + e #else PSTR("E " S_FMT) @@ -3132,11 +3118,16 @@ void Temperature::tick() { , const bool click_to_cancel/*=false*/ #endif ) { + + #if ENABLED(AUTOTEMP) + REMEMBER(1, planner.autotemp_enabled, false); + #endif + #if TEMP_RESIDENCY_TIME > 0 millis_t residency_start_ms = 0; bool first_loop = true; // Loop until the temperature has stabilized - #define TEMP_CONDITIONS (!residency_start_ms || PENDING(now, residency_start_ms + (TEMP_RESIDENCY_TIME) * 1000UL)) + #define TEMP_CONDITIONS (!residency_start_ms || PENDING(now, residency_start_ms + SEC_TO_MS(TEMP_RESIDENCY_TIME))) #else // Loop until the temperature is very close target #define TEMP_CONDITIONS (wants_to_cool ? isCoolingHotend(target_extruder) : isHeatingHotend(target_extruder)) @@ -3151,10 +3142,10 @@ void Temperature::tick() { printerEventLEDs.onHotendHeatingStart(); #endif - float target_temp = -1.0, old_temp = 9999.0; bool wants_to_cool = false; - wait_for_heatup = true; + float target_temp = -1.0, old_temp = 9999.0; millis_t now, next_temp_ms = 0, next_cool_check_ms = 0; + wait_for_heatup = true; do { // Target temperature might be changed during the loop if (target_temp != degTargetHotend(target_extruder)) { @@ -3172,7 +3163,7 @@ void Temperature::tick() { #if TEMP_RESIDENCY_TIME > 0 SERIAL_ECHOPGM(" W:"); if (residency_start_ms) - SERIAL_ECHO(long((((TEMP_RESIDENCY_TIME) * 1000UL) - (now - residency_start_ms)) / 1000UL)); + SERIAL_ECHO(long((SEC_TO_MS(TEMP_RESIDENCY_TIME) - (now - residency_start_ms)) / 1000UL)); else SERIAL_CHAR('?'); #endif @@ -3195,10 +3186,8 @@ void Temperature::tick() { if (!residency_start_ms) { // Start the TEMP_RESIDENCY_TIME timer when we reach target temp for the first time. - if (temp_diff < TEMP_WINDOW) { - residency_start_ms = now; - if (first_loop) residency_start_ms += (TEMP_RESIDENCY_TIME) * 1000UL; - } + if (temp_diff < TEMP_WINDOW) + residency_start_ms = now + (first_loop ? SEC_TO_MS(TEMP_RESIDENCY_TIME) / 3 : 0); } else if (temp_diff > TEMP_HYSTERESIS) { // Restart the timer whenever the temperature falls outside the hysteresis. @@ -3230,13 +3219,19 @@ void Temperature::tick() { } while (wait_for_heatup && TEMP_CONDITIONS); if (wait_for_heatup) { - ui.reset_status(); - #if ENABLED(PRINTER_EVENT_LEDS) - printerEventLEDs.onHeatingDone(); + wait_for_heatup = false; + #if ENABLED(DWIN_CREALITY_LCD) + HMI_flag.heat_flag = 0; + duration_t elapsed = print_job_timer.duration(); // print timer + dwin_heat_time = elapsed.value; + #else + ui.reset_status(); #endif + TERN_(PRINTER_EVENT_LEDS, printerEventLEDs.onHeatingDone()); + return true; } - return wait_for_heatup; + return false; } #endif // HAS_TEMP_HOTEND @@ -3244,7 +3239,7 @@ void Temperature::tick() { #if HAS_HEATED_BED #ifndef MIN_COOLING_SLOPE_DEG_BED - #define MIN_COOLING_SLOPE_DEG_BED 1.50 + #define MIN_COOLING_SLOPE_DEG_BED 1.00 #endif #ifndef MIN_COOLING_SLOPE_TIME_BED #define MIN_COOLING_SLOPE_TIME_BED 60 @@ -3259,17 +3254,12 @@ void Temperature::tick() { millis_t residency_start_ms = 0; bool first_loop = true; // Loop until the temperature has stabilized - #define TEMP_BED_CONDITIONS (!residency_start_ms || PENDING(now, residency_start_ms + (TEMP_BED_RESIDENCY_TIME) * 1000UL)) + #define TEMP_BED_CONDITIONS (!residency_start_ms || PENDING(now, residency_start_ms + SEC_TO_MS(TEMP_BED_RESIDENCY_TIME))) #else // Loop until the temperature is very close target #define TEMP_BED_CONDITIONS (wants_to_cool ? isCoolingBed() : isHeatingBed()) #endif - float target_temp = -1, old_temp = 9999; - bool wants_to_cool = false; - wait_for_heatup = true; - millis_t now, next_temp_ms = 0, next_cool_check_ms = 0; - #if DISABLED(BUSY_WHILE_HEATING) && ENABLED(HOST_KEEPALIVE_FEATURE) KEEPALIVE_STATE(NOT_BUSY); #endif @@ -3279,6 +3269,10 @@ void Temperature::tick() { printerEventLEDs.onBedHeatingStart(); #endif + bool wants_to_cool = false; + float target_temp = -1, old_temp = 9999; + millis_t now, next_temp_ms = 0, next_cool_check_ms = 0; + wait_for_heatup = true; do { // Target temperature might be changed during the loop if (target_temp != degTargetBed()) { @@ -3296,7 +3290,7 @@ void Temperature::tick() { #if TEMP_BED_RESIDENCY_TIME > 0 SERIAL_ECHOPGM(" W:"); if (residency_start_ms) - SERIAL_ECHO(long((((TEMP_BED_RESIDENCY_TIME) * 1000UL) - (now - residency_start_ms)) / 1000UL)); + SERIAL_ECHO(long((SEC_TO_MS(TEMP_BED_RESIDENCY_TIME) - (now - residency_start_ms)) / 1000UL)); else SERIAL_CHAR('?'); #endif @@ -3319,10 +3313,8 @@ void Temperature::tick() { if (!residency_start_ms) { // Start the TEMP_BED_RESIDENCY_TIME timer when we reach target temp for the first time. - if (temp_diff < TEMP_BED_WINDOW) { - residency_start_ms = now; - if (first_loop) residency_start_ms += (TEMP_BED_RESIDENCY_TIME) * 1000UL; - } + if (temp_diff < TEMP_BED_WINDOW) + residency_start_ms = now + (first_loop ? SEC_TO_MS(TEMP_BED_RESIDENCY_TIME) / 3 : 0); } else if (temp_diff > TEMP_BED_HYSTERESIS) { // Restart the timer whenever the temperature falls outside the hysteresis. @@ -3355,20 +3347,104 @@ void Temperature::tick() { } while (wait_for_heatup && TEMP_BED_CONDITIONS); - if (wait_for_heatup) ui.reset_status(); + if (wait_for_heatup) { + wait_for_heatup = false; + ui.reset_status(); + return true; + } + + return false; + } - return wait_for_heatup; + void Temperature::wait_for_bed_heating() { + if (isHeatingBed()) { + SERIAL_ECHOLNPGM("Wait for bed heating..."); + LCD_MESSAGEPGM(MSG_BED_HEATING); + wait_for_bed(); + ui.reset_status(); + } } #endif // HAS_HEATED_BED + #if HAS_TEMP_PROBE + + #ifndef MIN_DELTA_SLOPE_DEG_PROBE + #define MIN_DELTA_SLOPE_DEG_PROBE 1.0 + #endif + #ifndef MIN_DELTA_SLOPE_TIME_PROBE + #define MIN_DELTA_SLOPE_TIME_PROBE 600 + #endif + + bool Temperature::wait_for_probe(const float target_temp, bool no_wait_for_cooling/*=true*/) { + + const bool wants_to_cool = isProbeAboveTemp(target_temp); + const bool will_wait = !(wants_to_cool && no_wait_for_cooling); + if (will_wait) + SERIAL_ECHOLNPAIR("Waiting for probe to ", (wants_to_cool ? PSTR("cool down") : PSTR("heat up")), " to ", target_temp, " degrees."); + + #if DISABLED(BUSY_WHILE_HEATING) && ENABLED(HOST_KEEPALIVE_FEATURE) + KEEPALIVE_STATE(NOT_BUSY); + #endif + + float old_temp = 9999; + millis_t next_temp_ms = 0, next_delta_check_ms = 0; + wait_for_heatup = true; + while (will_wait && wait_for_heatup) { + + // Print Temp Reading every 10 seconds while heating up. + millis_t now = millis(); + if (!next_temp_ms || ELAPSED(now, next_temp_ms)) { + next_temp_ms = now + 10000UL; + print_heater_states(active_extruder); + SERIAL_EOL(); + } + + idle(); + gcode.reset_stepper_timeout(); // Keep steppers powered + + // Break after MIN_DELTA_SLOPE_TIME_PROBE seconds if the temperature + // did not drop at least MIN_DELTA_SLOPE_DEG_PROBE. This avoids waiting + // forever as the probe is not actively heated. + if (!next_delta_check_ms || ELAPSED(now, next_delta_check_ms)) { + const float temp = degProbe(), + delta_temp = old_temp > temp ? old_temp - temp : temp - old_temp; + if (delta_temp < float(MIN_DELTA_SLOPE_DEG_PROBE)) { + SERIAL_ECHOLNPGM("Timed out waiting for probe temperature."); + break; + } + next_delta_check_ms = now + 1000UL * MIN_DELTA_SLOPE_TIME_PROBE; + old_temp = temp; + } + + // Loop until the temperature is very close target + if (!(wants_to_cool ? isProbeAboveTemp(target_temp) : isProbeBelowTemp(target_temp))) { + SERIAL_ECHOLN(wants_to_cool ? PSTR("Cooldown") : PSTR("Heatup")); + SERIAL_ECHOLNPGM(" complete, target probe temperature reached."); + break; + } + } + + if (wait_for_heatup) { + wait_for_heatup = false; + ui.reset_status(); + return true; + } + else if (will_wait) + SERIAL_ECHOLNPGM("Canceled wait for probe temperature."); + + return false; + } + + #endif // HAS_TEMP_PROBE + #if HAS_HEATED_CHAMBER #ifndef MIN_COOLING_SLOPE_DEG_CHAMBER #define MIN_COOLING_SLOPE_DEG_CHAMBER 1.50 #endif #ifndef MIN_COOLING_SLOPE_TIME_CHAMBER - #define MIN_COOLING_SLOPE_TIME_CHAMBER 60 + #define MIN_COOLING_SLOPE_TIME_CHAMBER 120 #endif bool Temperature::wait_for_chamber(const bool no_wait_for_cooling/*=true*/) { @@ -3376,21 +3452,20 @@ void Temperature::tick() { millis_t residency_start_ms = 0; bool first_loop = true; // Loop until the temperature has stabilized - #define TEMP_CHAMBER_CONDITIONS (!residency_start_ms || PENDING(now, residency_start_ms + (TEMP_CHAMBER_RESIDENCY_TIME) * 1000UL)) + #define TEMP_CHAMBER_CONDITIONS (!residency_start_ms || PENDING(now, residency_start_ms + SEC_TO_MS(TEMP_CHAMBER_RESIDENCY_TIME))) #else // Loop until the temperature is very close target #define TEMP_CHAMBER_CONDITIONS (wants_to_cool ? isCoolingChamber() : isHeatingChamber()) #endif - float target_temp = -1, old_temp = 9999; - bool wants_to_cool = false; - wait_for_heatup = true; - millis_t now, next_temp_ms = 0, next_cool_check_ms = 0; - #if DISABLED(BUSY_WHILE_HEATING) && ENABLED(HOST_KEEPALIVE_FEATURE) KEEPALIVE_STATE(NOT_BUSY); #endif + bool wants_to_cool = false; + float target_temp = -1, old_temp = 9999; + millis_t now, next_temp_ms = 0, next_cool_check_ms = 0; + wait_for_heatup = true; do { // Target temperature might be changed during the loop if (target_temp != degTargetChamber()) { @@ -3402,13 +3477,13 @@ void Temperature::tick() { } now = millis(); - if (ELAPSED(now, next_temp_ms)) { //Print Temp Reading every 1 second while heating up. + if (ELAPSED(now, next_temp_ms)) { // Print Temp Reading every 1 second while heating up. next_temp_ms = now + 1000UL; print_heater_states(active_extruder); #if TEMP_CHAMBER_RESIDENCY_TIME > 0 SERIAL_ECHOPGM(" W:"); if (residency_start_ms) - SERIAL_ECHO(long((((TEMP_CHAMBER_RESIDENCY_TIME) * 1000UL) - (now - residency_start_ms)) / 1000UL)); + SERIAL_ECHO(long((SEC_TO_MS(TEMP_CHAMBER_RESIDENCY_TIME) - (now - residency_start_ms)) / 1000UL)); else SERIAL_CHAR('?'); #endif @@ -3426,10 +3501,8 @@ void Temperature::tick() { if (!residency_start_ms) { // Start the TEMP_CHAMBER_RESIDENCY_TIME timer when we reach target temp for the first time. - if (temp_diff < TEMP_CHAMBER_WINDOW) { - residency_start_ms = now; - if (first_loop) residency_start_ms += (TEMP_CHAMBER_RESIDENCY_TIME) * 1000UL; - } + if (temp_diff < TEMP_CHAMBER_WINDOW) + residency_start_ms = now + (first_loop ? SEC_TO_MS(TEMP_CHAMBER_RESIDENCY_TIME) / 3 : 0); } else if (temp_diff > TEMP_CHAMBER_HYSTERESIS) { // Restart the timer whenever the temperature falls outside the hysteresis. @@ -3451,9 +3524,13 @@ void Temperature::tick() { } } while (wait_for_heatup && TEMP_CHAMBER_CONDITIONS); - if (wait_for_heatup) ui.reset_status(); + if (wait_for_heatup) { + wait_for_heatup = false; + ui.reset_status(); + return true; + } - return wait_for_heatup; + return false; } #endif // HAS_HEATED_CHAMBER diff --git a/Marlin/src/module/temperature.h b/Marlin/src/module/temperature.h index 66d6bd56e154..57b0fecbcc99 100644 --- a/Marlin/src/module/temperature.h +++ b/Marlin/src/module/temperature.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -37,20 +37,15 @@ #define SOFT_PWM_SCALE 0 #endif -#if HOTENDS <= 1 - #define HOTEND_INDEX 0 - #define E_NAME -#else - #define HOTEND_INDEX e - #define E_NAME e -#endif +#define HOTEND_INDEX TERN(HAS_MULTI_HOTEND, e, 0) +#define E_NAME TERN_(HAS_MULTI_HOTEND, e) -// Identifiers for other heaters +// Heater identifiers. Positive values are hotends. Negative values are other heaters. typedef enum : int8_t { INDEX_NONE = -5, H_PROBE, H_REDUNDANT, H_CHAMBER, H_BED, H_E0, H_E1, H_E2, H_E3, H_E4, H_E5, H_E6, H_E7 -} heater_ind_t; +} heater_id_t; // PID storage typedef struct { float Kp, Ki, Kd; } PID_t; @@ -74,32 +69,18 @@ hotend_pid_t; typedef IF<(LPQ_MAX_LEN > 255), uint16_t, uint8_t>::type lpq_ptr_t; #endif -#define DUMMY_PID_VALUE 3000.0f - +#define PID_PARAM(F,H) _PID_##F(TERN(PID_PARAMS_PER_HOTEND, H, 0)) +#define _PID_Kp(H) TERN(PIDTEMP, Temperature::temp_hotend[H].pid.Kp, NAN) +#define _PID_Ki(H) TERN(PIDTEMP, Temperature::temp_hotend[H].pid.Ki, NAN) +#define _PID_Kd(H) TERN(PIDTEMP, Temperature::temp_hotend[H].pid.Kd, NAN) #if ENABLED(PIDTEMP) - #define _PID_Kp(H) Temperature::temp_hotend[H].pid.Kp - #define _PID_Ki(H) Temperature::temp_hotend[H].pid.Ki - #define _PID_Kd(H) Temperature::temp_hotend[H].pid.Kd - #if ENABLED(PID_EXTRUSION_SCALING) - #define _PID_Kc(H) Temperature::temp_hotend[H].pid.Kc - #else - #define _PID_Kc(H) 1 - #endif - - #if ENABLED(PID_FAN_SCALING) - #define _PID_Kf(H) Temperature::temp_hotend[H].pid.Kf - #else - #define _PID_Kf(H) 0 - #endif + #define _PID_Kc(H) TERN(PID_EXTRUSION_SCALING, Temperature::temp_hotend[H].pid.Kc, 1) + #define _PID_Kf(H) TERN(PID_FAN_SCALING, Temperature::temp_hotend[H].pid.Kf, 0) #else - #define _PID_Kp(H) DUMMY_PID_VALUE - #define _PID_Ki(H) DUMMY_PID_VALUE - #define _PID_Kd(H) DUMMY_PID_VALUE #define _PID_Kc(H) 1 + #define _PID_Kf(H) 0 #endif -#define PID_PARAM(F,H) _PID_##F(H) - /** * States for ADC reading in the ISR */ @@ -150,6 +131,14 @@ enum ADCSensorState : char { #if ENABLED(FILAMENT_WIDTH_SENSOR) Prepare_FILWIDTH, Measure_FILWIDTH, #endif + #if ENABLED(POWER_MONITOR_CURRENT) + Prepare_POWER_MONITOR_CURRENT, + Measure_POWER_MONITOR_CURRENT, + #endif + #if ENABLED(POWER_MONITOR_VOLTAGE) + Prepare_POWER_MONITOR_VOLTAGE, + Measure_POWER_MONITOR_VOLTAGE, + #endif #if HAS_ADC_BUTTONS Prepare_ADC_KEY, Measure_ADC_KEY, #endif @@ -175,7 +164,9 @@ enum ADCSensorState : char { #define unscalePID_d(d) ( float(d) * PID_dT ) #endif -#define G26_CLICK_CAN_CANCEL (HAS_LCD_MENU && ENABLED(G26_MESH_VALIDATION)) +#if BOTH(HAS_LCD_MENU, G26_MESH_VALIDATION) + #define G26_CLICK_CAN_CANCEL 1 +#endif // A temperature sensor typedef struct TempInfo { @@ -220,16 +211,6 @@ struct PIDHeaterInfo : public HeaterInfo { typedef temp_info_t chamber_info_t; #endif -// Heater idle handling -typedef struct { - millis_t timeout_ms; - bool timed_out; - inline void update(const millis_t &ms) { if (!timed_out && timeout_ms && ELAPSED(ms, timeout_ms)) timed_out = true; } - inline void start(const millis_t &ms) { timeout_ms = millis() + ms; timed_out = false; } - inline void reset() { timeout_ms = 0; timed_out = false; } - inline void expire() { start(0); } -} hotend_idle_t; - // Heater watch handling template struct HeaterWatch { @@ -243,7 +224,7 @@ struct HeaterWatch { const int16_t newtarget = curr + INCREASE; if (newtarget < tgt - HYSTERESIS - 1) { target = newtarget; - next_ms = millis() + PERIOD * 1000UL; + next_ms = millis() + SEC_TO_MS(PERIOD); return; } } @@ -319,30 +300,17 @@ class Temperature { public: - #if HOTENDS - #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) - #define HOTEND_TEMPS (HOTENDS + 1) - #else - #define HOTEND_TEMPS HOTENDS - #endif + #if HAS_HOTEND + #define HOTEND_TEMPS (HOTENDS + ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)) static hotend_info_t temp_hotend[HOTEND_TEMPS]; + static const uint16_t heater_maxtemp[HOTENDS]; #endif - #if HAS_HEATED_BED - static bed_info_t temp_bed; - #endif - #if HAS_TEMP_PROBE - static probe_info_t temp_probe; - #endif - #if HAS_TEMP_CHAMBER - static chamber_info_t temp_chamber; - #endif + TERN_(HAS_HEATED_BED, static bed_info_t temp_bed); + TERN_(HAS_TEMP_PROBE, static probe_info_t temp_probe); + TERN_(HAS_TEMP_CHAMBER, static chamber_info_t temp_chamber); - #if ENABLED(AUTO_POWER_E_FANS) - static uint8_t autofan_speed[HOTENDS]; - #endif - #if ENABLED(AUTO_POWER_CHAMBER_FAN) - static uint8_t chamberfan_speed; - #endif + TERN_(AUTO_POWER_E_FANS, static uint8_t autofan_speed[HOTENDS]); + TERN_(AUTO_POWER_CHAMBER_FAN, static uint8_t chamberfan_speed); #if ENABLED(FAN_SOFT_PWM) static uint8_t soft_pwm_amount_fan[FAN_COUNT], @@ -352,7 +320,7 @@ class Temperature { #if ENABLED(PREVENT_COLD_EXTRUSION) static bool allow_cold_extrude; static int16_t extrude_min_temp; - FORCE_INLINE static bool tooCold(const int16_t temp) { return allow_cold_extrude ? false : temp < extrude_min_temp; } + FORCE_INLINE static bool tooCold(const int16_t temp) { return allow_cold_extrude ? false : temp < extrude_min_temp - (TEMP_WINDOW); } FORCE_INLINE static bool tooColdToExtrude(const uint8_t E_NAME) { return tooCold(degHotend(HOTEND_INDEX)); } @@ -368,26 +336,47 @@ class Temperature { FORCE_INLINE static bool targetHotEnoughToExtrude(const uint8_t e) { return !targetTooColdToExtrude(e); } #if HEATER_IDLE_HANDLER - static hotend_idle_t hotend_idle[HOTENDS]; - #if HAS_HEATED_BED - static hotend_idle_t bed_idle; - #endif - #if HAS_HEATED_CHAMBER - static hotend_idle_t chamber_idle; - #endif + + // Heater idle handling. Marlin creates one per hotend and one for the heated bed. + typedef struct { + millis_t timeout_ms; + bool timed_out; + inline void update(const millis_t &ms) { if (!timed_out && timeout_ms && ELAPSED(ms, timeout_ms)) timed_out = true; } + inline void start(const millis_t &ms) { timeout_ms = millis() + ms; timed_out = false; } + inline void reset() { timeout_ms = 0; timed_out = false; } + inline void expire() { start(0); } + } heater_idle_t; + + // Indices and size for the heater_idle array + #define _ENUM_FOR_E(N) IDLE_INDEX_E##N, + enum IdleIndex : uint8_t { + REPEAT(HOTENDS, _ENUM_FOR_E) + #if ENABLED(HAS_HEATED_BED) + IDLE_INDEX_BED, + #endif + NR_HEATER_IDLE + }; + #undef _ENUM_FOR_E + + // Convert the given heater_id_t to idle array index + static inline IdleIndex idle_index_for_id(const int8_t heater_id) { + #if HAS_HEATED_BED + if (heater_id == H_BED) return IDLE_INDEX_BED; + #endif + return (IdleIndex)_MAX(heater_id, 0); + } + + static heater_idle_t heater_idle[NR_HEATER_IDLE]; + #endif private: - #if EARLY_WATCHDOG - static bool inited; // If temperature controller is running - #endif + TERN_(EARLY_WATCHDOG, static bool inited); // If temperature controller is running static volatile bool raw_temps_ready; - #if WATCH_HOTENDS - static hotend_watch_t watch_hotend[HOTENDS]; - #endif + TERN_(WATCH_HOTENDS, static hotend_watch_t watch_hotend[HOTENDS]); #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) static uint16_t redundant_temperature_raw; @@ -399,17 +388,11 @@ class Temperature { static lpq_ptr_t lpq_ptr; #endif - #if HOTENDS - static temp_range_t temp_range[HOTENDS]; - #endif + TERN_(HAS_HOTEND, static temp_range_t temp_range[HOTENDS]); #if HAS_HEATED_BED - #if WATCH_BED - static bed_watch_t watch_bed; - #endif - #if DISABLED(PIDTEMPBED) - static millis_t next_bed_check_ms; - #endif + TERN_(WATCH_BED, static bed_watch_t watch_bed); + TERN(PIDTEMPBED,,static millis_t next_bed_check_ms); #ifdef BED_MINTEMP static int16_t mintemp_raw_BED; #endif @@ -419,9 +402,7 @@ class Temperature { #endif #if HAS_HEATED_CHAMBER - #if WATCH_CHAMBER - static chamber_watch_t watch_chamber; - #endif + TERN_(WATCH_CHAMBER, static chamber_watch_t watch_chamber); static millis_t next_chamber_check_ms; #ifdef CHAMBER_MINTEMP static int16_t mintemp_raw_CHAMBER; @@ -439,23 +420,17 @@ class Temperature { static millis_t preheat_end_time[HOTENDS]; #endif - #if HAS_AUTO_FAN - static millis_t next_auto_fan_check_ms; - #endif + TERN_(HAS_AUTO_FAN, static millis_t next_auto_fan_check_ms); - #if ENABLED(PROBING_HEATERS_OFF) - static bool paused; - #endif + TERN_(PROBING_HEATERS_OFF, static bool paused); public: #if HAS_ADC_BUTTONS static uint32_t current_ADCKey_raw; - static uint8_t ADCKey_count; + static uint16_t ADCKey_count; #endif - #if ENABLED(PID_EXTRUSION_SCALING) - static int16_t lpq_len; - #endif + TERN_(PID_EXTRUSION_SCALING, static int16_t lpq_len); /** * Instance Methods @@ -498,7 +473,7 @@ class Temperature { } #endif - #if HOTENDS + #if HAS_HOTEND static float analog_to_celsius_hotend(const int raw, const uint8_t e); #endif @@ -512,13 +487,17 @@ class Temperature { static float analog_to_celsius_chamber(const int raw); #endif - #if FAN_COUNT > 0 + #if HAS_FAN static uint8_t fan_speed[FAN_COUNT]; #define FANS_LOOP(I) LOOP_L_N(I, FAN_COUNT) static void set_fan_speed(const uint8_t target, const uint16_t speed); + #if ENABLED(REPORT_FAN_CHANGE) + static void report_fan_speed(const uint8_t target); + #endif + #if EITHER(PROBING_FANS_OFF, ADVANCED_PAUSE_FANS_PAUSE) static bool fans_paused; static uint8_t saved_fan_speed[FAN_COUNT]; @@ -526,19 +505,11 @@ class Temperature { static constexpr inline uint8_t fanPercent(const uint8_t speed) { return ui8_to_percent(speed); } - #if ENABLED(ADAPTIVE_FAN_SLOWING) - static uint8_t fan_speed_scaler[FAN_COUNT]; - #endif + TERN_(ADAPTIVE_FAN_SLOWING, static uint8_t fan_speed_scaler[FAN_COUNT]); static inline uint8_t scaledFanSpeed(const uint8_t target, const uint8_t fs) { UNUSED(target); // Potentially unused! - return (fs * uint16_t( - #if ENABLED(ADAPTIVE_FAN_SLOWING) - fan_speed_scaler[target] - #else - 128 - #endif - )) >> 7; + return (fs * uint16_t(TERN(ADAPTIVE_FAN_SLOWING, fan_speed_scaler[target], 128))) >> 7; } static inline uint8_t scaledFanSpeed(const uint8_t target) { @@ -554,10 +525,10 @@ class Temperature { void set_fans_paused(const bool p); #endif - #endif // FAN_COUNT > 0 + #endif // HAS_FAN static inline void zero_fan_speeds() { - #if FAN_COUNT > 0 + #if HAS_FAN FANS_LOOP(i) set_fan_speed(i, 0); #endif } @@ -595,29 +566,17 @@ class Temperature { //deg=degreeCelsius FORCE_INLINE static float degHotend(const uint8_t E_NAME) { - return (0 - #if HOTENDS - + temp_hotend[HOTEND_INDEX].celsius - #endif - ); + return TERN0(HAS_HOTEND, temp_hotend[HOTEND_INDEX].celsius); } #if ENABLED(SHOW_TEMP_ADC_VALUES) FORCE_INLINE static int16_t rawHotendTemp(const uint8_t E_NAME) { - return (0 - #if HOTENDS - + temp_hotend[HOTEND_INDEX].raw - #endif - ); + return TERN0(HAS_HOTEND, temp_hotend[HOTEND_INDEX].raw); } #endif FORCE_INLINE static int16_t degTargetHotend(const uint8_t E_NAME) { - return (0 - #if HOTENDS - + temp_hotend[HOTEND_INDEX].target - #endif - ); + return TERN0(HAS_HOTEND, temp_hotend[HOTEND_INDEX].target); } #if WATCH_HOTENDS @@ -626,7 +585,7 @@ class Temperature { static inline void start_watching_hotend(const uint8_t=0) {} #endif - #if HOTENDS + #if HAS_HOTEND static void setTargetHotend(const int16_t celsius, const uint8_t E_NAME) { const uint8_t ee = HOTEND_INDEX; @@ -636,10 +595,8 @@ class Temperature { else if (temp_hotend[ee].target == 0) start_preheat_time(ee); #endif - #if ENABLED(AUTO_POWER_CONTROL) - powerManager.power_on(); - #endif - temp_hotend[ee].target = _MIN(celsius, temp_range[ee].maxtemp - 15); + TERN_(AUTO_POWER_CONTROL, if (celsius) powerManager.power_on()); + temp_hotend[ee].target = _MIN(celsius, temp_range[ee].maxtemp - HOTEND_OVERSHOOT); start_watching_hotend(ee); } @@ -663,7 +620,11 @@ class Temperature { return degTargetHotend(e) > TEMP_HYSTERESIS && ABS(degHotend(e) - degTargetHotend(e)) > TEMP_HYSTERESIS; } - #endif // HOTENDS + FORCE_INLINE static bool degHotendNear(const uint8_t e, const float &temp) { + return ABS(degHotend(e) - temp) < (TEMP_HYSTERESIS); + } + + #endif // HAS_HOTEND #if HAS_HEATED_BED @@ -682,12 +643,10 @@ class Temperature { #endif static void setTargetBed(const int16_t celsius) { - #if ENABLED(AUTO_POWER_CONTROL) - powerManager.power_on(); - #endif + TERN_(AUTO_POWER_CONTROL, if (celsius) powerManager.power_on()); temp_bed.target = - #ifdef BED_MAXTEMP - _MIN(celsius, BED_MAXTEMP - 10) + #ifdef BED_MAX_TARGET + _MIN(celsius, BED_MAX_TARGET) #else celsius #endif @@ -701,6 +660,12 @@ class Temperature { #endif ); + static void wait_for_bed_heating(); + + FORCE_INLINE static bool degBedNear(const float &temp) { + return ABS(degBed() - temp) < (TEMP_BED_HYSTERESIS); + } + #endif // HAS_HEATED_BED #if HAS_TEMP_PROBE @@ -708,6 +673,9 @@ class Temperature { FORCE_INLINE static int16_t rawProbeTemp() { return temp_probe.raw; } #endif FORCE_INLINE static float degProbe() { return temp_probe.celsius; } + FORCE_INLINE static bool isProbeBelowTemp(const float target_temp) { return temp_probe.celsius < target_temp; } + FORCE_INLINE static bool isProbeAboveTemp(const float target_temp) { return temp_probe.celsius > target_temp; } + static bool wait_for_probe(const float target_temp, bool no_wait_for_cooling=true); #endif #if WATCH_PROBE @@ -752,7 +720,7 @@ class Temperature { /** * The software PWM power for a heater */ - static int16_t getHeaterPower(const heater_ind_t heater); + static int16_t getHeaterPower(const heater_id_t heater_id); /** * Switch off all heaters, set all target temperatures to 0 @@ -771,7 +739,7 @@ class Temperature { * Perform auto-tuning for hotend or bed in response to M303 */ #if HAS_PID_HEATING - static void PID_autotune(const float &target, const heater_ind_t hotend, const int8_t ncycles, const bool set_result=false); + static void PID_autotune(const float &target, const heater_id_t heater_id, const int8_t ncycles, const bool set_result=false); #if ENABLED(NO_FAN_SLOWING_IN_PID_TUNING) static bool adaptive_fan_slowing; @@ -784,9 +752,7 @@ class Temperature { */ #if ENABLED(PIDTEMP) FORCE_INLINE static void updatePID() { - #if ENABLED(PID_EXTRUSION_SCALING) - last_e_position = 0; - #endif + TERN_(PID_EXTRUSION_SCALING, last_e_position = 0); } #endif @@ -800,13 +766,13 @@ class Temperature { #if HEATER_IDLE_HANDLER static void reset_hotend_idle_timer(const uint8_t E_NAME) { - hotend_idle[HOTEND_INDEX].reset(); + heater_idle[HOTEND_INDEX].reset(); start_watching_hotend(HOTEND_INDEX); } #if HAS_HEATED_BED static void reset_bed_idle_timer() { - bed_idle.reset(); + heater_idle[IDLE_INDEX_BED].reset(); start_watching_bed(); } #endif @@ -831,8 +797,10 @@ class Temperature { #endif #endif - #if HAS_DISPLAY - static void set_heating_message(const uint8_t e); + TERN_(HAS_DISPLAY, static void set_heating_message(const uint8_t e)); + + #if HAS_LCD_MENU && HAS_TEMPERATURE + static void lcd_preheat(const int16_t e, const int8_t indh, const int8_t indb); #endif private: @@ -841,11 +809,7 @@ class Temperature { #define HAS_MAX6675 EITHER(HEATER_0_USES_MAX6675, HEATER_1_USES_MAX6675) #if HAS_MAX6675 - #if BOTH(HEATER_0_USES_MAX6675, HEATER_1_USES_MAX6675) - #define COUNT_6675 2 - #else - #define COUNT_6675 1 - #endif + #define COUNT_6675 1 + BOTH(HEATER_0_USES_MAX6675, HEATER_1_USES_MAX6675) #if COUNT_6675 > 1 #define READ_MAX6675(N) read_max6675(N) #else @@ -862,40 +826,55 @@ class Temperature { static float get_pid_output_hotend(const uint8_t e); - #if ENABLED(PIDTEMPBED) - static float get_pid_output_bed(); - #endif + TERN_(PIDTEMPBED, static float get_pid_output_bed()); - #if HAS_HEATED_CHAMBER - static float get_pid_output_chamber(); - #endif + TERN_(HAS_HEATED_CHAMBER, static float get_pid_output_chamber()); - static void _temp_error(const heater_ind_t e, PGM_P const serial_msg, PGM_P const lcd_msg); - static void min_temp_error(const heater_ind_t e); - static void max_temp_error(const heater_ind_t e); + static void _temp_error(const heater_id_t e, PGM_P const serial_msg, PGM_P const lcd_msg); + static void min_temp_error(const heater_id_t e); + static void max_temp_error(const heater_id_t e); - #define HAS_THERMAL_PROTECTION (EITHER(THERMAL_PROTECTION_HOTENDS, THERMAL_PROTECTION_CHAMBER) || HAS_THERMALLY_PROTECTED_BED) + #define HAS_THERMAL_PROTECTION ANY(THERMAL_PROTECTION_HOTENDS, THERMAL_PROTECTION_CHAMBER, HAS_THERMALLY_PROTECTED_BED) #if HAS_THERMAL_PROTECTION + // Indices and size for the tr_state_machine array. One for each protected heater. + #define _ENUM_FOR_E(N) RUNAWAY_IND_E##N, + enum RunawayIndex : uint8_t { + #if ENABLED(THERMAL_PROTECTION_HOTENDS) + REPEAT(HOTENDS, _ENUM_FOR_E) + #endif + #if ENABLED(HAS_THERMALLY_PROTECTED_BED) + RUNAWAY_IND_BED, + #endif + #if ENABLED(THERMAL_PROTECTION_CHAMBER) + RUNAWAY_IND_CHAMBER, + #endif + NR_HEATER_RUNAWAY + }; + #undef _ENUM_FOR_E + + // Convert the given heater_id_t to runaway state array index + static inline RunawayIndex runaway_index_for_id(const int8_t heater_id) { + #if HAS_THERMALLY_PROTECTED_CHAMBER + if (heater_id == H_CHAMBER) return RUNAWAY_IND_CHAMBER; + #endif + #if HAS_THERMALLY_PROTECTED_BED + if (heater_id == H_BED) return RUNAWAY_IND_BED; + #endif + return (RunawayIndex)_MAX(heater_id, 0); + } + enum TRState : char { TRInactive, TRFirstHeating, TRStable, TRRunaway }; typedef struct { millis_t timer = 0; TRState state = TRInactive; + float running_temp; + void run(const float ¤t, const float &target, const heater_id_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc); } tr_state_machine_t; - #if ENABLED(THERMAL_PROTECTION_HOTENDS) - static tr_state_machine_t tr_state_machine[HOTENDS]; - #endif - #if HAS_THERMALLY_PROTECTED_BED - static tr_state_machine_t tr_state_machine_bed; - #endif - #if ENABLED(THERMAL_PROTECTION_CHAMBER) - static tr_state_machine_t tr_state_machine_chamber; - #endif - - static void thermal_runaway_protection(tr_state_machine_t &state, const float ¤t, const float &target, const heater_ind_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc); + static tr_state_machine_t tr_state_machine[NR_HEATER_RUNAWAY]; #endif // HAS_THERMAL_PROTECTION }; diff --git a/Marlin/src/module/thermistor/thermistor_1.h b/Marlin/src/module/thermistor/thermistor_1.h index f3226da4754a..fad790837571 100644 --- a/Marlin/src/module/thermistor/thermistor_1.h +++ b/Marlin/src/module/thermistor/thermistor_1.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once // R25 = 100 kOhm, beta25 = 4092 K, 4.7 kOhm pull-up, bed thermistor -const short temptable_1[][2] PROGMEM = { +const temp_entry_t temptable_1[] PROGMEM = { { OV( 23), 300 }, { OV( 25), 295 }, { OV( 27), 290 }, diff --git a/Marlin/src/module/thermistor/thermistor_10.h b/Marlin/src/module/thermistor/thermistor_10.h index 9e89eab84a43..c24ad40bf483 100644 --- a/Marlin/src/module/thermistor/thermistor_10.h +++ b/Marlin/src/module/thermistor/thermistor_10.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once // R25 = 100 kOhm, beta25 = 3960 K, 4.7 kOhm pull-up, RS thermistor 198-961 -const short temptable_10[][2] PROGMEM = { +const temp_entry_t temptable_10[] PROGMEM = { { OV( 1), 929 }, { OV( 36), 299 }, { OV( 71), 246 }, diff --git a/Marlin/src/module/thermistor/thermistor_1010.h b/Marlin/src/module/thermistor/thermistor_1010.h index 200d9aed56f5..8ab5e3b364c6 100644 --- a/Marlin/src/module/thermistor/thermistor_1010.h +++ b/Marlin/src/module/thermistor/thermistor_1010.h @@ -16,13 +16,15 @@ * 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 . + * along with this program. If not, see . * */ #pragma once +#define REVERSE_TEMP_SENSOR_RANGE_1010 1 + // Pt1000 with 1k0 pullup -const short temptable_1010[][2] PROGMEM = { +const temp_entry_t temptable_1010[] PROGMEM = { PtLine( 0, 1000, 1000), PtLine( 25, 1000, 1000), PtLine( 50, 1000, 1000), diff --git a/Marlin/src/module/thermistor/thermistor_1047.h b/Marlin/src/module/thermistor/thermistor_1047.h index af41a20a10c7..6e1b61f9d073 100644 --- a/Marlin/src/module/thermistor/thermistor_1047.h +++ b/Marlin/src/module/thermistor/thermistor_1047.h @@ -16,13 +16,15 @@ * 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 . + * along with this program. If not, see . * */ #pragma once +#define REVERSE_TEMP_SENSOR_RANGE_1047 1 + // Pt1000 with 4k7 pullup -const short temptable_1047[][2] PROGMEM = { +const temp_entry_t temptable_1047[] PROGMEM = { // only a few values are needed as the curve is very flat PtLine( 0, 1000, 4700), PtLine( 50, 1000, 4700), @@ -30,5 +32,9 @@ const short temptable_1047[][2] PROGMEM = { PtLine(150, 1000, 4700), PtLine(200, 1000, 4700), PtLine(250, 1000, 4700), - PtLine(300, 1000, 4700) + PtLine(300, 1000, 4700), + PtLine(350, 1000, 4700), + PtLine(400, 1000, 4700), + PtLine(450, 1000, 4700), + PtLine(500, 1000, 4700) }; diff --git a/Marlin/src/module/thermistor/thermistor_11.h b/Marlin/src/module/thermistor/thermistor_11.h index 1b2da4a71a8b..345d009a6498 100644 --- a/Marlin/src/module/thermistor/thermistor_11.h +++ b/Marlin/src/module/thermistor/thermistor_11.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once // R25 = 100 kOhm, beta25 = 3950 K, 4.7 kOhm pull-up, QU-BD silicone bed QWG-104F-3950 thermistor -const short temptable_11[][2] PROGMEM = { +const temp_entry_t temptable_11[] PROGMEM = { { OV( 1), 938 }, { OV( 31), 314 }, { OV( 41), 290 }, diff --git a/Marlin/src/module/thermistor/thermistor_110.h b/Marlin/src/module/thermistor/thermistor_110.h index fe8f4fbb8070..215495e2c6a1 100644 --- a/Marlin/src/module/thermistor/thermistor_110.h +++ b/Marlin/src/module/thermistor/thermistor_110.h @@ -16,13 +16,15 @@ * 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 . + * along with this program. If not, see . * */ #pragma once +#define REVERSE_TEMP_SENSOR_RANGE_110 1 + // Pt100 with 1k0 pullup -const short temptable_110[][2] PROGMEM = { +const temp_entry_t temptable_110[] PROGMEM = { // only a few values are needed as the curve is very flat PtLine( 0, 100, 1000), PtLine( 50, 100, 1000), diff --git a/Marlin/src/module/thermistor/thermistor_12.h b/Marlin/src/module/thermistor/thermistor_12.h index f9e994a959c2..d1ee23b2b7f7 100644 --- a/Marlin/src/module/thermistor/thermistor_12.h +++ b/Marlin/src/module/thermistor/thermistor_12.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once // R25 = 100 kOhm, beta25 = 4700 K, 4.7 kOhm pull-up, (personal calibration for Makibox hot bed) -const short temptable_12[][2] PROGMEM = { +const temp_entry_t temptable_12[] PROGMEM = { { OV( 35), 180 }, // top rating 180C { OV( 211), 140 }, { OV( 233), 135 }, diff --git a/Marlin/src/module/thermistor/thermistor_13.h b/Marlin/src/module/thermistor/thermistor_13.h index 44c5243c1fe2..bb622240c82d 100644 --- a/Marlin/src/module/thermistor/thermistor_13.h +++ b/Marlin/src/module/thermistor/thermistor_13.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once // R25 = 100 kOhm, beta25 = 4100 K, 4.7 kOhm pull-up, Hisens thermistor -const short temptable_13[][2] PROGMEM = { +const temp_entry_t temptable_13[] PROGMEM = { { OV( 20.04), 300 }, { OV( 23.19), 290 }, { OV( 26.71), 280 }, diff --git a/Marlin/src/module/thermistor/thermistor_147.h b/Marlin/src/module/thermistor/thermistor_147.h index 8fead6c42991..6d846ad5bed7 100644 --- a/Marlin/src/module/thermistor/thermistor_147.h +++ b/Marlin/src/module/thermistor/thermistor_147.h @@ -16,13 +16,15 @@ * 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 . + * along with this program. If not, see . * */ #pragma once +#define REVERSE_TEMP_SENSOR_RANGE_147 1 + // Pt100 with 4k7 pullup -const short temptable_147[][2] PROGMEM = { +const temp_entry_t temptable_147[] PROGMEM = { // only a few values are needed as the curve is very flat PtLine( 0, 100, 4700), PtLine( 50, 100, 4700), diff --git a/Marlin/src/module/thermistor/thermistor_15.h b/Marlin/src/module/thermistor/thermistor_15.h index 85602abb3a9c..46dcce8c1e4f 100644 --- a/Marlin/src/module/thermistor/thermistor_15.h +++ b/Marlin/src/module/thermistor/thermistor_15.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once // 100k bed thermistor in JGAurora A5. Calibrated by Sam Pinches 21st Jan 2018 using cheap k-type thermocouple inserted into heater block, using TM-902C meter. -const short temptable_15[][2] PROGMEM = { +const temp_entry_t temptable_15[] PROGMEM = { { OV( 31), 275 }, { OV( 33), 270 }, { OV( 35), 260 }, diff --git a/Marlin/src/module/thermistor/thermistor_18.h b/Marlin/src/module/thermistor/thermistor_18.h index f6a3edec4974..9c2d81b3e698 100644 --- a/Marlin/src/module/thermistor/thermistor_18.h +++ b/Marlin/src/module/thermistor/thermistor_18.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once // ATC Semitec 204GT-2 (4.7k pullup) Dagoma.Fr - MKS_Base_DKU001327 - version (measured/tested/approved) -const short temptable_18[][2] PROGMEM = { +const temp_entry_t temptable_18[] PROGMEM = { { OV( 1), 713 }, { OV( 17), 284 }, { OV( 20), 275 }, diff --git a/Marlin/src/module/thermistor/thermistor_2.h b/Marlin/src/module/thermistor/thermistor_2.h index f3fe470603c9..d0e1e4f3dfca 100644 --- a/Marlin/src/module/thermistor/thermistor_2.h +++ b/Marlin/src/module/thermistor/thermistor_2.h @@ -16,17 +16,17 @@ * 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 . + * along with this program. If not, see . * */ #pragma once // // R25 = 200 kOhm, beta25 = 4338 K, 4.7 kOhm pull-up, ATC Semitec 204GT-2 -// Verified by linagee. Source: http://shop.arcol.hu/static/datasheets/thermistors.pdf +// Verified by linagee. Source: https://www.mouser.com/datasheet/2/362/semitec%20usa%20corporation_gtthermistor-1202937.pdf // Calculated using 4.7kohm pullup, voltage divider math, and manufacturer provided temp/resistance // -const short temptable_2[][2] PROGMEM = { +const temp_entry_t temptable_2[] PROGMEM = { { OV( 1), 848 }, { OV( 30), 300 }, // top rating 300C { OV( 34), 290 }, diff --git a/Marlin/src/module/thermistor/thermistor_20.h b/Marlin/src/module/thermistor/thermistor_20.h index 49b212da50b0..73094f14604d 100644 --- a/Marlin/src/module/thermistor/thermistor_20.h +++ b/Marlin/src/module/thermistor/thermistor_20.h @@ -16,15 +16,15 @@ * 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 . + * along with this program. If not, see . * */ #pragma once -#define REVERSE_TEMP_SENSOR_RANGE +#define REVERSE_TEMP_SENSOR_RANGE_20 1 // Pt100 with INA826 amp on Ultimaker v2.0 electronics -const short temptable_20[][2] PROGMEM = { +const temp_entry_t temptable_20[] PROGMEM = { { OV( 0), 0 }, { OV(227), 1 }, { OV(236), 10 }, diff --git a/Marlin/src/module/thermistor/thermistor_201.h b/Marlin/src/module/thermistor/thermistor_201.h index d92f95756175..44d52806813a 100644 --- a/Marlin/src/module/thermistor/thermistor_201.h +++ b/Marlin/src/module/thermistor/thermistor_201.h @@ -16,15 +16,15 @@ * 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 . + * along with this program. If not, see . * */ #pragma once -#define REVERSE_TEMP_SENSOR_RANGE +#define REVERSE_TEMP_SENSOR_RANGE_201 1 // Pt100 with LMV324 amp on Overlord v1.1 electronics -const short temptable_201[][2] PROGMEM = { +const temp_entry_t temptable_201[] PROGMEM = { { OV( 0), 0 }, { OV( 8), 1 }, { OV( 23), 6 }, diff --git a/Marlin/src/module/thermistor/thermistor_202.h b/Marlin/src/module/thermistor/thermistor_202.h new file mode 100644 index 000000000000..c5229607ae33 --- /dev/null +++ b/Marlin/src/module/thermistor/thermistor_202.h @@ -0,0 +1,69 @@ +// +// Unknown 200K thermistor on a Copymaster 3D hotend +// Temptable sent from dealer technologyoutlet.co.uk +// + +const temp_entry_t temptable_202[] PROGMEM = { + { OV( 1), 864 }, + { OV( 35), 300 }, + { OV( 38), 295 }, + { OV( 41), 290 }, + { OV( 44), 285 }, + { OV( 47), 280 }, + { OV( 51), 275 }, + { OV( 55), 270 }, + { OV( 60), 265 }, + { OV( 65), 260 }, + { OV( 70), 255 }, + { OV( 76), 250 }, + { OV( 83), 245 }, + { OV( 90), 240 }, + { OV( 98), 235 }, + { OV( 107), 230 }, + { OV( 116), 225 }, + { OV( 127), 220 }, + { OV( 138), 215 }, + { OV( 151), 210 }, + { OV( 164), 205 }, + { OV( 179), 200 }, + { OV( 195), 195 }, + { OV( 213), 190 }, + { OV( 232), 185 }, + { OV( 253), 180 }, + { OV( 275), 175 }, + { OV( 299), 170 }, + { OV( 325), 165 }, + { OV( 352), 160 }, + { OV( 381), 155 }, + { OV( 411), 150 }, + { OV( 443), 145 }, + { OV( 476), 140 }, + { OV( 511), 135 }, + { OV( 546), 130 }, + { OV( 581), 125 }, + { OV( 617), 120 }, + { OV( 652), 115 }, + { OV( 687), 110 }, + { OV( 720), 105 }, + { OV( 753), 100 }, + { OV( 783), 95 }, + { OV( 812), 90 }, + { OV( 839), 85 }, + { OV( 864), 80 }, + { OV( 886), 75 }, + { OV( 906), 70 }, + { OV( 924), 65 }, + { OV( 940), 60 }, + { OV( 954), 55 }, + { OV( 966), 50 }, + { OV( 976), 45 }, + { OV( 985), 40 }, + { OV( 992), 35 }, + { OV( 998), 30 }, + { OV(1003), 25 }, + { OV(1007), 20 }, + { OV(1011), 15 }, + { OV(1014), 10 }, + { OV(1016), 5 }, + { OV(1018), 0 } +}; diff --git a/Marlin/src/module/thermistor/thermistor_21.h b/Marlin/src/module/thermistor/thermistor_21.h index 655f56685dac..cd867df29103 100644 --- a/Marlin/src/module/thermistor/thermistor_21.h +++ b/Marlin/src/module/thermistor/thermistor_21.h @@ -16,18 +16,18 @@ * 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 . + * along with this program. If not, see . * */ #pragma once -#define REVERSE_TEMP_SENSOR_RANGE +#define REVERSE_TEMP_SENSOR_RANGE_21 1 #undef OV_SCALE #define OV_SCALE(N) (float((N) * 5) / 3.3f) // Pt100 with INA826 amp with 3.3v excitation based on "Pt100 with INA826 amp on Ultimaker v2.0 electronics" -const short temptable_21[][2] PROGMEM = { +const temp_entry_t temptable_21[] PROGMEM = { { OV( 0), 0 }, { OV(227), 1 }, { OV(236), 10 }, diff --git a/Marlin/src/module/thermistor/thermistor_22.h b/Marlin/src/module/thermistor/thermistor_22.h new file mode 100644 index 000000000000..6f4a31050add --- /dev/null +++ b/Marlin/src/module/thermistor/thermistor_22.h @@ -0,0 +1,72 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +// 100k hotend thermistor with 4.7k pull up to 3.3v and 220R to analog input as in GTM32 Pro vB +const temp_entry_t temptable_22[] PROGMEM = { + { OV( 1), 352 }, + { OV( 6), 341 }, + { OV( 11), 330 }, + { OV( 16), 319 }, + { OV( 20), 307 }, + { OV( 26), 296 }, + { OV( 31), 285 }, + { OV( 40), 274 }, + { OV( 51), 263 }, + { OV( 61), 251 }, + { OV( 72), 245 }, + { OV( 77), 240 }, + { OV( 82), 237 }, + { OV( 87), 232 }, + { OV( 91), 229 }, + { OV( 94), 227 }, + { OV( 97), 225 }, + { OV( 100), 223 }, + { OV( 104), 221 }, + { OV( 108), 219 }, + { OV( 115), 214 }, + { OV( 126), 209 }, + { OV( 137), 204 }, + { OV( 147), 200 }, + { OV( 158), 193 }, + { OV( 167), 192 }, + { OV( 177), 189 }, + { OV( 197), 163 }, + { OV( 230), 174 }, + { OV( 267), 165 }, + { OV( 310), 158 }, + { OV( 336), 151 }, + { OV( 379), 143 }, + { OV( 413), 138 }, + { OV( 480), 127 }, + { OV( 580), 110 }, + { OV( 646), 100 }, + { OV( 731), 88 }, + { OV( 768), 84 }, + { OV( 861), 69 }, + { OV( 935), 50 }, + { OV( 975), 38 }, + { OV(1001), 27 }, + { OV(1011), 22 }, + { OV(1015), 13 }, + { OV(1020), 6 }, + { OV(1023), 0 } +}; diff --git a/Marlin/src/module/thermistor/thermistor_23.h b/Marlin/src/module/thermistor/thermistor_23.h new file mode 100644 index 000000000000..02ff9fb2b6c8 --- /dev/null +++ b/Marlin/src/module/thermistor/thermistor_23.h @@ -0,0 +1,128 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +// 100k hotbed thermistor with 4.7k pull up to 3.3v and 220R to analog input as in GTM32 Pro vB +const temp_entry_t temptable_23[] PROGMEM = { + { OV( 1), 938 }, + { OV( 11), 423 }, + { OV( 21), 351 }, + { OV( 31), 314 }, + { OV( 41), 290 }, + { OV( 51), 272 }, + { OV( 61), 258 }, + { OV( 71), 247 }, + { OV( 81), 237 }, + { OV( 91), 229 }, + { OV( 101), 221 }, + { OV( 111), 215 }, + { OV( 121), 209 }, + { OV( 131), 204 }, + { OV( 141), 199 }, + { OV( 151), 195 }, + { OV( 161), 190 }, + { OV( 171), 187 }, + { OV( 181), 183 }, + { OV( 191), 179 }, + { OV( 201), 176 }, + { OV( 211), 173 }, + { OV( 221), 170 }, + { OV( 231), 167 }, + { OV( 241), 165 }, + { OV( 251), 162 }, + { OV( 261), 160 }, + { OV( 271), 157 }, + { OV( 281), 155 }, + { OV( 291), 153 }, + { OV( 301), 150 }, + { OV( 311), 148 }, + { OV( 321), 146 }, + { OV( 331), 144 }, + { OV( 341), 142 }, + { OV( 351), 140 }, + { OV( 361), 139 }, + { OV( 371), 137 }, + { OV( 381), 135 }, + { OV( 391), 133 }, + { OV( 401), 131 }, + { OV( 411), 130 }, + { OV( 421), 128 }, + { OV( 431), 126 }, + { OV( 441), 125 }, + { OV( 451), 123 }, + { OV( 461), 122 }, + { OV( 471), 120 }, + { OV( 481), 119 }, + { OV( 491), 117 }, + { OV( 501), 116 }, + { OV( 511), 114 }, + { OV( 521), 113 }, + { OV( 531), 111 }, + { OV( 541), 110 }, + { OV( 551), 108 }, + { OV( 561), 107 }, + { OV( 571), 105 }, + { OV( 581), 104 }, + { OV( 591), 102 }, + { OV( 601), 101 }, + { OV( 611), 100 }, + { OV( 621), 98 }, + { OV( 631), 97 }, + { OV( 641), 95 }, + { OV( 651), 94 }, + { OV( 661), 92 }, + { OV( 671), 91 }, + { OV( 681), 90 }, + { OV( 691), 88 }, + { OV( 701), 87 }, + { OV( 711), 85 }, + { OV( 721), 84 }, + { OV( 731), 82 }, + { OV( 741), 81 }, + { OV( 751), 79 }, + { OV( 761), 77 }, + { OV( 771), 76 }, + { OV( 781), 74 }, + { OV( 791), 72 }, + { OV( 801), 71 }, + { OV( 811), 69 }, + { OV( 821), 67 }, + { OV( 831), 65 }, + { OV( 841), 63 }, + { OV( 851), 62 }, + { OV( 861), 60 }, + { OV( 871), 57 }, + { OV( 881), 55 }, + { OV( 891), 53 }, + { OV( 901), 51 }, + { OV( 911), 48 }, + { OV( 921), 45 }, + { OV( 931), 42 }, + { OV( 941), 39 }, + { OV( 951), 36 }, + { OV( 961), 32 }, + { OV( 971), 28 }, + { OV( 981), 25 }, + { OV( 991), 23 }, + { OV(1001), 21 }, + { OV(1011), 19 }, + { OV(1021), 5 } +}; diff --git a/Marlin/src/module/thermistor/thermistor_3.h b/Marlin/src/module/thermistor/thermistor_3.h index e37c2ace7b8d..74e00e2ba4f4 100644 --- a/Marlin/src/module/thermistor/thermistor_3.h +++ b/Marlin/src/module/thermistor/thermistor_3.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once // R25 = 100 kOhm, beta25 = 4120 K, 4.7 kOhm pull-up, mendel-parts -const short temptable_3[][2] PROGMEM = { +const temp_entry_t temptable_3[] PROGMEM = { { OV( 1), 864 }, { OV( 21), 300 }, { OV( 25), 290 }, diff --git a/Marlin/src/module/thermistor/thermistor_30.h b/Marlin/src/module/thermistor/thermistor_30.h new file mode 100644 index 000000000000..bc1781b1351c --- /dev/null +++ b/Marlin/src/module/thermistor/thermistor_30.h @@ -0,0 +1,66 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +// R25 = 100 kOhm, beta25 = 3950 K, 4.7 kOhm pull-up +// Resistance 100k Ohms at 25deg. C +// Resistance Tolerance + / -1% +// B Value 3950K at 25/50 deg. C +// B Value Tolerance + / - 1% +// Kis3d Silicone Heater 24V 200W/300W with 6mm Precision cast plate (EN AW 5083) +// Temperature setting time 10 min to determine the 12Bit ADC value on the surface. (le3tspeak) +const temp_entry_t temptable_30[] PROGMEM = { + { OV( 1), 938 }, + { OV( 298), 125 }, // 1193 - 125° + { OV( 321), 121 }, // 1285 - 121° + { OV( 348), 117 }, // 1392 - 117° + { OV( 387), 113 }, // 1550 - 113° + { OV( 411), 110 }, // 1644 - 110° + { OV( 445), 106 }, // 1780 - 106° + { OV( 480), 101 }, // 1920 - 101° + { OV( 516), 97 }, // 2064 - 97° + { OV( 553), 92 }, // 2212 - 92° + { OV( 591), 88 }, // 2364 - 88° + { OV( 628), 84 }, // 2512 - 84° + { OV( 665), 79 }, // 2660 - 79° + { OV( 702), 75 }, // 2808 - 75° + { OV( 736), 71 }, // 2945 - 71° + { OV( 770), 67 }, // 3080 - 67° + { OV( 801), 63 }, // 3204 - 63° + { OV( 830), 59 }, // 3320 - 59° + { OV( 857), 55 }, // 3428 - 55° + { OV( 881), 51 }, // 3524 - 51° + { OV( 902), 47 }, // 3611 - 47° + { OV( 922), 42 }, // 3688 - 42° + { OV( 938), 38 }, // 3754 - 38° + { OV( 952), 34 }, // 3811 - 34° + { OV( 964), 29 }, // 3857 - 29° + { OV( 975), 25 }, // 3900 - 25° + { OV( 980), 23 }, // 3920 - 23° + { OV( 991), 17 }, // 3964 - 17° + { OV(1001), 9 }, // Calculated + { OV(1004), 5 }, // Calculated + { OV(1008), 0 }, // Calculated + { OV(1012), -5 }, // Calculated + { OV(1016), -10 }, // Calculated + { OV(1020), -15 } // Calculated +}; diff --git a/Marlin/src/module/thermistor/thermistor_331.h b/Marlin/src/module/thermistor/thermistor_331.h index 434492d7e78c..ccb0f6b62d2b 100644 --- a/Marlin/src/module/thermistor/thermistor_331.h +++ b/Marlin/src/module/thermistor/thermistor_331.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -24,7 +24,7 @@ #define OVM(V) OV((V)*(0.327/0.5)) // R25 = 100 kOhm, beta25 = 4092 K, 4.7 kOhm pull-up, bed thermistor -const short temptable_331[][2] PROGMEM = { +const temp_entry_t temptable_331[] PROGMEM = { { OVM( 23), 300 }, { OVM( 25), 295 }, { OVM( 27), 290 }, diff --git a/Marlin/src/module/thermistor/thermistor_332.h b/Marlin/src/module/thermistor/thermistor_332.h index 3112751b95e4..9502f1bdae9e 100644 --- a/Marlin/src/module/thermistor/thermistor_332.h +++ b/Marlin/src/module/thermistor/thermistor_332.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -24,7 +24,7 @@ #define OVM(V) OV((V)*(0.327/0.327)) // R25 = 100 kOhm, beta25 = 4092 K, 4.7 kOhm pull-up, bed thermistor -const short temptable_332[][2] PROGMEM = { +const temp_entry_t temptable_332[] PROGMEM = { { OVM( 268), 150 }, { OVM( 293), 145 }, { OVM( 320), 141 }, diff --git a/Marlin/src/module/thermistor/thermistor_4.h b/Marlin/src/module/thermistor/thermistor_4.h index 00e0d9ed9755..92d907249be9 100644 --- a/Marlin/src/module/thermistor/thermistor_4.h +++ b/Marlin/src/module/thermistor/thermistor_4.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once // R25 = 10 kOhm, beta25 = 3950 K, 4.7 kOhm pull-up, Generic 10k thermistor -const short temptable_4[][2] PROGMEM = { +const temp_entry_t temptable_4[] PROGMEM = { { OV( 1), 430 }, { OV( 54), 137 }, { OV( 107), 107 }, diff --git a/Marlin/src/module/thermistor/thermistor_5.h b/Marlin/src/module/thermistor/thermistor_5.h index 8f414de15e8f..1d5fa2fec739 100644 --- a/Marlin/src/module/thermistor/thermistor_5.h +++ b/Marlin/src/module/thermistor/thermistor_5.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -24,9 +24,9 @@ // R25 = 100 kOhm, beta25 = 4267 K, 4.7 kOhm pull-up // 100k ParCan thermistor (104GT-2) // ATC Semitec 104GT-2/104NT-4-R025H42G (Used in ParCan) -// Verified by linagee. Source: http://shop.arcol.hu/static/datasheets/thermistors.pdf +// Verified by linagee. Source: https://www.mouser.com/datasheet/2/362/semitec%20usa%20corporation_gtthermistor-1202937.pdf // Calculated using 4.7kohm pullup, voltage divider math, and manufacturer provided temp/resistance -const short temptable_5[][2] PROGMEM = { +const temp_entry_t temptable_5[] PROGMEM = { { OV( 1), 713 }, { OV( 17), 300 }, // top rating 300C { OV( 20), 290 }, diff --git a/Marlin/src/module/thermistor/thermistor_501.h b/Marlin/src/module/thermistor/thermistor_501.h index 3db433644edd..d40e341f7e31 100644 --- a/Marlin/src/module/thermistor/thermistor_501.h +++ b/Marlin/src/module/thermistor/thermistor_501.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once // 100k Zonestar thermistor. Adjusted By Hally -const short temptable_501[][2] PROGMEM = { +const temp_entry_t temptable_501[] PROGMEM = { { OV( 1), 713 }, { OV( 14), 300 }, // Top rating 300C { OV( 16), 290 }, diff --git a/Marlin/src/module/thermistor/thermistor_502.h b/Marlin/src/module/thermistor/thermistor_502.h new file mode 100644 index 000000000000..69cee2431c5f --- /dev/null +++ b/Marlin/src/module/thermistor/thermistor_502.h @@ -0,0 +1,60 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +// Unknown thermistor for the Zonestar P802M hot bed. Adjusted By Nerseth +// These were the shipped settings from Zonestar in original firmware: P802M_8_Repetier_V1.6_Zonestar.zip +const temp_entry_t temptable_502[] PROGMEM = { + { OV( 56.0 / 4), 300 }, + { OV( 187.0 / 4), 250 }, + { OV( 615.0 / 4), 190 }, + { OV( 690.0 / 4), 185 }, + { OV( 750.0 / 4), 180 }, + { OV( 830.0 / 4), 175 }, + { OV( 920.0 / 4), 170 }, + { OV(1010.0 / 4), 165 }, + { OV(1118.0 / 4), 160 }, + { OV(1215.0 / 4), 155 }, + { OV(1330.0 / 4), 145 }, + { OV(1460.0 / 4), 140 }, + { OV(1594.0 / 4), 135 }, + { OV(1752.0 / 4), 130 }, + { OV(1900.0 / 4), 125 }, + { OV(2040.0 / 4), 120 }, + { OV(2200.0 / 4), 115 }, + { OV(2350.0 / 4), 110 }, + { OV(2516.0 / 4), 105 }, + { OV(2671.0 / 4), 98 }, + { OV(2831.0 / 4), 92 }, + { OV(2975.0 / 4), 85 }, + { OV(3115.0 / 4), 76 }, + { OV(3251.0 / 4), 72 }, + { OV(3480.0 / 4), 62 }, + { OV(3580.0 / 4), 52 }, + { OV(3660.0 / 4), 46 }, + { OV(3740.0 / 4), 40 }, + { OV(3869.0 / 4), 30 }, + { OV(3912.0 / 4), 25 }, + { OV(3948.0 / 4), 20 }, + { OV(4077.0 / 4), -20 }, + { OV(4094.0 / 4), -55 } +}; diff --git a/Marlin/src/module/thermistor/thermistor_51.h b/Marlin/src/module/thermistor/thermistor_51.h index f314777a5285..d02dd47ba5d1 100644 --- a/Marlin/src/module/thermistor/thermistor_51.h +++ b/Marlin/src/module/thermistor/thermistor_51.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -26,7 +26,7 @@ // Verified by linagee. // Calculated using 1kohm pullup, voltage divider math, and manufacturer provided temp/resistance // Advantage: Twice the resolution and better linearity from 150C to 200C -const short temptable_51[][2] PROGMEM = { +const temp_entry_t temptable_51[] PROGMEM = { { OV( 1), 350 }, { OV( 190), 250 }, // top rating 250C { OV( 203), 245 }, diff --git a/Marlin/src/module/thermistor/thermistor_512.h b/Marlin/src/module/thermistor/thermistor_512.h index 5528e56b9763..e8021e1e48c4 100644 --- a/Marlin/src/module/thermistor/thermistor_512.h +++ b/Marlin/src/module/thermistor/thermistor_512.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ // 100k thermistor supplied with RPW-Ultra hotend, 4.7k pullup -const short temptable_512[][2] PROGMEM = { +const temp_entry_t temptable_512[] PROGMEM = { { OV(26), 300 }, { OV(28), 295 }, { OV(30), 290 }, diff --git a/Marlin/src/module/thermistor/thermistor_52.h b/Marlin/src/module/thermistor/thermistor_52.h index 9a54ef4b6f66..5c9cb9dc4df9 100644 --- a/Marlin/src/module/thermistor/thermistor_52.h +++ b/Marlin/src/module/thermistor/thermistor_52.h @@ -16,17 +16,17 @@ * 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 . + * along with this program. If not, see . * */ #pragma once // R25 = 200 kOhm, beta25 = 4338 K, 1 kOhm pull-up, // 200k ATC Semitec 204GT-2 (WITH 1kohm RESISTOR FOR PULLUP, R9 ON SANGUINOLOLU! NOT FOR 4.7kohm PULLUP! THIS IS NOT NORMAL!) -// Verified by linagee. Source: http://shop.arcol.hu/static/datasheets/thermistors.pdf +// Verified by linagee. Source: https://www.mouser.com/datasheet/2/362/semitec%20usa%20corporation_gtthermistor-1202937.pdf // Calculated using 1kohm pullup, voltage divider math, and manufacturer provided temp/resistance // Advantage: More resolution and better linearity from 150C to 200C -const short temptable_52[][2] PROGMEM = { +const temp_entry_t temptable_52[] PROGMEM = { { OV( 1), 500 }, { OV( 125), 300 }, // top rating 300C { OV( 142), 290 }, diff --git a/Marlin/src/module/thermistor/thermistor_55.h b/Marlin/src/module/thermistor/thermistor_55.h index ead481e8655a..707b7d420a12 100644 --- a/Marlin/src/module/thermistor/thermistor_55.h +++ b/Marlin/src/module/thermistor/thermistor_55.h @@ -16,17 +16,17 @@ * 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 . + * along with this program. If not, see . * */ #pragma once // R25 = 100 kOhm, beta25 = 4267 K, 1 kOhm pull-up, // 100k ATC Semitec 104GT-2 (Used on ParCan) (WITH 1kohm RESISTOR FOR PULLUP, R9 ON SANGUINOLOLU! NOT FOR 4.7kohm PULLUP! THIS IS NOT NORMAL!) -// Verified by linagee. Source: http://shop.arcol.hu/static/datasheets/thermistors.pdf +// Verified by linagee. Source: https://www.mouser.com/datasheet/2/362/semitec%20usa%20corporation_gtthermistor-1202937.pdf // Calculated using 1kohm pullup, voltage divider math, and manufacturer provided temp/resistance // Advantage: More resolution and better linearity from 150C to 200C -const short temptable_55[][2] PROGMEM = { +const temp_entry_t temptable_55[] PROGMEM = { { OV( 1), 500 }, { OV( 76), 300 }, { OV( 87), 290 }, diff --git a/Marlin/src/module/thermistor/thermistor_6.h b/Marlin/src/module/thermistor/thermistor_6.h index f84c64413c1f..68113419e583 100644 --- a/Marlin/src/module/thermistor/thermistor_6.h +++ b/Marlin/src/module/thermistor/thermistor_6.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once // R25 = 100 kOhm, beta25 = 4092 K, 8.2 kOhm pull-up, 100k Epcos (?) thermistor -const short temptable_6[][2] PROGMEM = { +const temp_entry_t temptable_6[] PROGMEM = { { OV( 1), 350 }, { OV( 28), 250 }, // top rating 250C { OV( 31), 245 }, diff --git a/Marlin/src/module/thermistor/thermistor_60.h b/Marlin/src/module/thermistor/thermistor_60.h index 167e0edcf88b..a3fe50559fd0 100644 --- a/Marlin/src/module/thermistor/thermistor_60.h +++ b/Marlin/src/module/thermistor/thermistor_60.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -31,7 +31,7 @@ // beta: 3950 // min adc: 1 at 0.0048828125 V // max adc: 1023 at 4.9951171875 V -const short temptable_60[][2] PROGMEM = { +const temp_entry_t temptable_60[] PROGMEM = { { OV( 51), 272 }, { OV( 61), 258 }, { OV( 71), 247 }, diff --git a/Marlin/src/module/thermistor/thermistor_61.h b/Marlin/src/module/thermistor/thermistor_61.h index 5f8171a1d4b6..ed4c4c885956 100644 --- a/Marlin/src/module/thermistor/thermistor_61.h +++ b/Marlin/src/module/thermistor/thermistor_61.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -30,7 +30,7 @@ // Resistance Tolerance + / -1% // B Value 3950K at 25/50 deg. C // B Value Tolerance + / - 1% -const short temptable_61[][2] PROGMEM = { +const temp_entry_t temptable_61[] PROGMEM = { { OV( 2.00), 420 }, // Guestimate to ensure we dont lose a reading and drop temps to -50 when over { OV( 12.07), 350 }, { OV( 12.79), 345 }, diff --git a/Marlin/src/module/thermistor/thermistor_66.h b/Marlin/src/module/thermistor/thermistor_66.h index 97f082348657..0ad5994ea811 100644 --- a/Marlin/src/module/thermistor/thermistor_66.h +++ b/Marlin/src/module/thermistor/thermistor_66.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once // R25 = 2.5 MOhm, beta25 = 4500 K, 4.7 kOhm pull-up, DyzeDesign 500 °C Thermistor -const short temptable_66[][2] PROGMEM = { +const temp_entry_t temptable_66[] PROGMEM = { { OV( 17.5), 850 }, { OV( 17.9), 500 }, { OV( 21.7), 480 }, diff --git a/Marlin/src/module/thermistor/thermistor_666.h b/Marlin/src/module/thermistor/thermistor_666.h index ab8b0380f10b..490dbd5f3ee9 100644 --- a/Marlin/src/module/thermistor/thermistor_666.h +++ b/Marlin/src/module/thermistor/thermistor_666.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -33,8 +33,7 @@ * B: 0.00031362 * C: -2.03978e-07 */ -#define NUMTEMPS 61 -const short temptable_666[NUMTEMPS][2] PROGMEM = { +const temp_entry_t temptable_666[] PROGMEM = { { OV( 1), 794 }, { OV( 18), 288 }, { OV( 35), 234 }, diff --git a/Marlin/src/module/thermistor/thermistor_67.h b/Marlin/src/module/thermistor/thermistor_67.h index 5af203c8abd2..7d6d7f697df3 100644 --- a/Marlin/src/module/thermistor/thermistor_67.h +++ b/Marlin/src/module/thermistor/thermistor_67.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once // R25 = 500 KOhm, beta25 = 3800 K, 4.7 kOhm pull-up, SliceEngineering 450 °C Thermistor -const short temptable_67[][2] PROGMEM = { +const temp_entry_t temptable_67[] PROGMEM = { { OV( 22 ), 500 }, { OV( 23 ), 490 }, { OV( 25 ), 480 }, diff --git a/Marlin/src/module/thermistor/thermistor_7.h b/Marlin/src/module/thermistor/thermistor_7.h index e791d0c33304..7a737559841c 100644 --- a/Marlin/src/module/thermistor/thermistor_7.h +++ b/Marlin/src/module/thermistor/thermistor_7.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once // R25 = 100 kOhm, beta25 = 3974 K, 4.7 kOhm pull-up, Honeywell 135-104LAG-J01 -const short temptable_7[][2] PROGMEM = { +const temp_entry_t temptable_7[] PROGMEM = { { OV( 1), 941 }, { OV( 19), 362 }, { OV( 37), 299 }, // top rating 300C diff --git a/Marlin/src/module/thermistor/thermistor_70.h b/Marlin/src/module/thermistor/thermistor_70.h index b49804106970..466b9255533e 100644 --- a/Marlin/src/module/thermistor/thermistor_70.h +++ b/Marlin/src/module/thermistor/thermistor_70.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -26,7 +26,7 @@ // ANENG AN8009 DMM with a K-type probe used for measurements. // R25 = 100 kOhm, beta25 = 4100 K, 4.7 kOhm pull-up, bqh2 stock thermistor -const short temptable_70[][2] PROGMEM = { +const temp_entry_t temptable_70[] PROGMEM = { { OV( 18), 270 }, { OV( 27), 248 }, { OV( 34), 234 }, diff --git a/Marlin/src/module/thermistor/thermistor_71.h b/Marlin/src/module/thermistor/thermistor_71.h index c3a9193b79bb..abd7fc5b986e 100644 --- a/Marlin/src/module/thermistor/thermistor_71.h +++ b/Marlin/src/module/thermistor/thermistor_71.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -27,7 +27,7 @@ // Beta = 3974 // R1 = 0 Ohm // R2 = 4700 Ohm -const short temptable_71[][2] PROGMEM = { +const temp_entry_t temptable_71[] PROGMEM = { { OV( 35), 300 }, { OV( 51), 269 }, { OV( 59), 258 }, diff --git a/Marlin/src/module/thermistor/thermistor_75.h b/Marlin/src/module/thermistor/thermistor_75.h index 3a3cdc636409..79800d2e4048 100644 --- a/Marlin/src/module/thermistor/thermistor_75.h +++ b/Marlin/src/module/thermistor/thermistor_75.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -34,7 +34,7 @@ //#define HIGH_TEMP_RANGE_75 -const short temptable_75[][2] PROGMEM = { // Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor +const temp_entry_t temptable_75[] PROGMEM = { // Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor { OV(111.06), 200 }, // v=0.542 r=571.747 res=0.501 degC/count #ifdef HIGH_TEMP_RANGE_75 diff --git a/Marlin/src/module/thermistor/thermistor_8.h b/Marlin/src/module/thermistor/thermistor_8.h index f6e407a730da..9e19168fed0d 100644 --- a/Marlin/src/module/thermistor/thermistor_8.h +++ b/Marlin/src/module/thermistor/thermistor_8.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once // R25 = 100 kOhm, beta25 = 3950 K, 10 kOhm pull-up, NTCS0603E3104FHT -const short temptable_8[][2] PROGMEM = { +const temp_entry_t temptable_8[] PROGMEM = { { OV( 1), 704 }, { OV( 54), 216 }, { OV( 107), 175 }, diff --git a/Marlin/src/module/thermistor/thermistor_9.h b/Marlin/src/module/thermistor/thermistor_9.h index 5023fbe1d01a..29097420ec11 100644 --- a/Marlin/src/module/thermistor/thermistor_9.h +++ b/Marlin/src/module/thermistor/thermistor_9.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ #pragma once // R25 = 100 kOhm, beta25 = 3960 K, 4.7 kOhm pull-up, GE Sensing AL03006-58.2K-97-G1 -const short temptable_9[][2] PROGMEM = { +const temp_entry_t temptable_9[] PROGMEM = { { OV( 1), 936 }, { OV( 36), 300 }, { OV( 71), 246 }, diff --git a/Marlin/src/module/thermistor/thermistor_99.h b/Marlin/src/module/thermistor/thermistor_99.h index 045a42b73804..839a511c0918 100644 --- a/Marlin/src/module/thermistor/thermistor_99.h +++ b/Marlin/src/module/thermistor/thermistor_99.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -24,7 +24,7 @@ // 100k bed thermistor with a 10K pull-up resistor - made by $ buildroot/share/scripts/createTemperatureLookupMarlin.py --rp=10000 -const short temptable_99[][2] PROGMEM = { +const temp_entry_t temptable_99[] PROGMEM = { { OV( 5.81), 350 }, // v=0.028 r= 57.081 res=13.433 degC/count { OV( 6.54), 340 }, // v=0.032 r= 64.248 res=11.711 degC/count { OV( 7.38), 330 }, // v=0.036 r= 72.588 res=10.161 degC/count diff --git a/Marlin/src/module/thermistor/thermistor_998.h b/Marlin/src/module/thermistor/thermistor_998.h index 6f631d4b9abe..e4cfbbaa0d2f 100644 --- a/Marlin/src/module/thermistor/thermistor_998.h +++ b/Marlin/src/module/thermistor/thermistor_998.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -27,7 +27,7 @@ #define DUMMY_THERMISTOR_998_VALUE 25 #endif -const short temptable_998[][2] PROGMEM = { +const temp_entry_t temptable_998[] PROGMEM = { { OV( 1), DUMMY_THERMISTOR_998_VALUE }, { OV(1023), DUMMY_THERMISTOR_998_VALUE } }; diff --git a/Marlin/src/module/thermistor/thermistor_999.h b/Marlin/src/module/thermistor/thermistor_999.h index d750d5597c38..0271c47f8585 100644 --- a/Marlin/src/module/thermistor/thermistor_999.h +++ b/Marlin/src/module/thermistor/thermistor_999.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -27,7 +27,7 @@ #define DUMMY_THERMISTOR_999_VALUE 25 #endif -const short temptable_999[][2] PROGMEM = { +const temp_entry_t temptable_999[] PROGMEM = { { OV( 1), DUMMY_THERMISTOR_999_VALUE }, { OV(1023), DUMMY_THERMISTOR_999_VALUE } }; diff --git a/Marlin/src/module/thermistor/thermistors.h b/Marlin/src/module/thermistor/thermistors.h index 2a1500eebe3a..0b0419c52034 100644 --- a/Marlin/src/module/thermistor/thermistors.h +++ b/Marlin/src/module/thermistor/thermistors.h @@ -16,15 +16,15 @@ * 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 . + * along with this program. If not, see . * */ #pragma once #include "../../inc/MarlinConfig.h" -#define THERMISTOR_TABLE_ADC_RESOLUTION 1024 -#define THERMISTOR_TABLE_SCALE (HAL_ADC_RANGE / (THERMISTOR_TABLE_ADC_RESOLUTION)) +#define THERMISTOR_TABLE_ADC_RESOLUTION 10 +#define THERMISTOR_TABLE_SCALE (HAL_ADC_RANGE / _BV(THERMISTOR_TABLE_ADC_RESOLUTION)) #if ENABLED(HAL_ADC_FILTERED) #define OVERSAMPLENR 1 #else @@ -42,6 +42,8 @@ #define ANY_THERMISTOR_IS(n) (THERMISTOR_HEATER_0 == n || THERMISTOR_HEATER_1 == n || THERMISTOR_HEATER_2 == n || THERMISTOR_HEATER_3 == n || THERMISTOR_HEATER_4 == n || THERMISTOR_HEATER_5 == n || THERMISTOR_HEATER_6 == n || THERMISTOR_HEATER_7 == n || THERMISTORBED == n || THERMISTORCHAMBER == n || THERMISTORPROBE == n) +typedef struct { int16_t value, celsius; } temp_entry_t; + // Pt1000 and Pt100 handling // // Rt=R0*(1+a*T+b*T*T) [for T>0] @@ -70,6 +72,9 @@ #if ANY_THERMISTOR_IS(501) // 100K Zonestar thermistor #include "thermistor_501.h" #endif +#if ANY_THERMISTOR_IS(502) // Unknown thermistor used by the Zonestar Průša P802M hot bed + #include "thermistor_502.h" +#endif #if ANY_THERMISTOR_IS(512) // 100k thermistor in RPW-Ultra hotend, Pull-up = 4.7 kOhm, "unknown model" #include "thermistor_512.h" #endif @@ -109,6 +114,15 @@ #if ANY_THERMISTOR_IS(21) // Pt100 with INA826 amp with 3.3v excitation based on "Pt100 with INA826 amp on Ultimaker v2.0 electronics" #include "thermistor_21.h" #endif +#if ANY_THERMISTOR_IS(22) // Thermistor in a Rostock 301 hot end, calibrated with a multimeter + #include "thermistor_22.h" +#endif +#if ANY_THERMISTOR_IS(23) // By AluOne #12622. Formerly 22 above. May need calibration/checking. + #include "thermistor_23.h" +#endif +#if ANY_THERMISTOR_IS(30) // Kis3d Silicone mat 24V 200W/300W with 6mm Precision cast plate (EN AW 5083) + #include "thermistor_30.h" +#endif #if ANY_THERMISTOR_IS(51) // beta25 = 4092 K, R25 = 100 kOhm, Pull-up = 1 kOhm, "EPCOS" #include "thermistor_51.h" #endif @@ -151,6 +165,9 @@ #if ANY_THERMISTOR_IS(201) // Pt100 with LMV324 Overlord #include "thermistor_201.h" #endif +#if ANY_THERMISTOR_IS(202) // 200K thermistor in Copymaker3D hotend + #include "thermistor_202.h" +#endif #if ANY_THERMISTOR_IS(331) // Like table 1, but with 3V3 as input voltage for MEGA #include "thermistor_331.h" #endif @@ -173,12 +190,13 @@ #include "thermistor_999.h" #endif #if ANY_THERMISTOR_IS(1000) // Custom - const short temptable_1000[][2] PROGMEM = { { 0, 0 } }; + const temp_entry_t temptable_1000[] PROGMEM = { { 0, 0 } }; #endif #define _TT_NAME(_N) temptable_ ## _N #define TT_NAME(_N) _TT_NAME(_N) + #if THERMISTOR_HEATER_0 #define HEATER_0_TEMPTABLE TT_NAME(THERMISTOR_HEATER_0) #define HEATER_0_TEMPTABLE_LEN COUNT(HEATER_0_TEMPTABLE) @@ -276,9 +294,12 @@ #else #define CHAMBER_TEMPTABLE_LEN 0 #endif + #ifdef THERMISTORPROBE #define PROBE_TEMPTABLE TT_NAME(THERMISTORPROBE) #define PROBE_TEMPTABLE_LEN COUNT(PROBE_TEMPTABLE) +#elif defined(HEATER_PROBE_USES_THERMISTOR) + #error "No probe thermistor table specified" #else #define PROBE_TEMPTABLE_LEN 0 #endif @@ -288,7 +309,7 @@ static_assert( HEATER_0_TEMPTABLE_LEN < 256 && HEATER_1_TEMPTABLE_LEN < 256 && HEATER_2_TEMPTABLE_LEN < 256 && HEATER_3_TEMPTABLE_LEN < 256 && HEATER_4_TEMPTABLE_LEN < 256 && HEATER_5_TEMPTABLE_LEN < 256 - && HEATER_6_TEMPTABLE_LEN < 258 && HEATER_7_TEMPTABLE_LEN < 258 + && HEATER_6_TEMPTABLE_LEN < 256 && HEATER_7_TEMPTABLE_LEN < 256 && BED_TEMPTABLE_LEN < 256 && CHAMBER_TEMPTABLE_LEN < 256 && PROBE_TEMPTABLE_LEN < 256, "Temperature conversion tables over 255 entries need special consideration." @@ -297,8 +318,85 @@ static_assert( // Set the high and low raw values for the heaters // For thermistors the highest temperature results in the lowest ADC value // For thermocouples the highest temperature results in the highest ADC value + +#define _TT_REV(N) REVERSE_TEMP_SENSOR_RANGE_##N +#define TT_REV(N) _TT_REV(N) + +#ifdef HEATER_0_TEMPTABLE + #if TT_REV(THERMISTOR_HEATER_0) + #define HEATER_0_SENSOR_MINTEMP_IND 0 + #define HEATER_0_SENSOR_MAXTEMP_IND HEATER_0_TEMPTABLE_LEN - 1 + #else + #define HEATER_0_SENSOR_MINTEMP_IND HEATER_0_TEMPTABLE_LEN - 1 + #define HEATER_0_SENSOR_MAXTEMP_IND 0 + #endif +#endif +#ifdef HEATER_1_TEMPTABLE + #if TT_REV(THERMISTOR_HEATER_1) + #define HEATER_1_SENSOR_MINTEMP_IND 0 + #define HEATER_1_SENSOR_MAXTEMP_IND HEATER_1_TEMPTABLE_LEN - 1 + #else + #define HEATER_1_SENSOR_MINTEMP_IND HEATER_1_TEMPTABLE_LEN - 1 + #define HEATER_1_SENSOR_MAXTEMP_IND 0 + #endif +#endif +#ifdef HEATER_2_TEMPTABLE + #if TT_REV(THERMISTOR_HEATER_2) + #define HEATER_2_SENSOR_MINTEMP_IND 0 + #define HEATER_2_SENSOR_MAXTEMP_IND HEATER_2_TEMPTABLE_LEN - 1 + #else + #define HEATER_2_SENSOR_MINTEMP_IND HEATER_2_TEMPTABLE_LEN - 1 + #define HEATER_2_SENSOR_MAXTEMP_IND 0 + #endif +#endif +#ifdef HEATER_3_TEMPTABLE + #if TT_REV(THERMISTOR_HEATER_3) + #define HEATER_3_SENSOR_MINTEMP_IND 0 + #define HEATER_3_SENSOR_MAXTEMP_IND HEATER_3_TEMPTABLE_LEN - 1 + #else + #define HEATER_3_SENSOR_MINTEMP_IND HEATER_3_TEMPTABLE_LEN - 1 + #define HEATER_3_SENSOR_MAXTEMP_IND 0 + #endif +#endif +#ifdef HEATER_4_TEMPTABLE + #if TT_REV(THERMISTOR_HEATER_4) + #define HEATER_4_SENSOR_MINTEMP_IND 0 + #define HEATER_4_SENSOR_MAXTEMP_IND HEATER_4_TEMPTABLE_LEN - 1 + #else + #define HEATER_4_SENSOR_MINTEMP_IND HEATER_4_TEMPTABLE_LEN - 1 + #define HEATER_4_SENSOR_MAXTEMP_IND 0 + #endif +#endif +#ifdef HEATER_5_TEMPTABLE + #if TT_REV(THERMISTOR_HEATER_5) + #define HEATER_5_SENSOR_MINTEMP_IND 0 + #define HEATER_5_SENSOR_MAXTEMP_IND HEATER_5_TEMPTABLE_LEN - 1 + #else + #define HEATER_5_SENSOR_MINTEMP_IND HEATER_5_TEMPTABLE_LEN - 1 + #define HEATER_5_SENSOR_MAXTEMP_IND 0 + #endif +#endif +#ifdef HEATER_6_TEMPTABLE + #if TT_REV(THERMISTOR_HEATER_6) + #define HEATER_6_SENSOR_MINTEMP_IND 0 + #define HEATER_6_SENSOR_MAXTEMP_IND HEATER_6_TEMPTABLE_LEN - 1 + #else + #define HEATER_6_SENSOR_MINTEMP_IND HEATER_6_TEMPTABLE_LEN - 1 + #define HEATER_6_SENSOR_MAXTEMP_IND 0 + #endif +#endif +#ifdef HEATER_7_TEMPTABLE + #if TT_REV(THERMISTOR_HEATER_7) + #define HEATER_7_SENSOR_MINTEMP_IND 0 + #define HEATER_7_SENSOR_MAXTEMP_IND HEATER_7_TEMPTABLE_LEN - 1 + #else + #define HEATER_7_SENSOR_MINTEMP_IND HEATER_7_TEMPTABLE_LEN - 1 + #define HEATER_7_SENSOR_MAXTEMP_IND 0 + #endif +#endif + #ifndef HEATER_0_RAW_HI_TEMP - #if defined(REVERSE_TEMP_SENSOR_RANGE) || !defined(HEATER_0_USES_THERMISTOR) + #if TT_REV(THERMISTOR_HEATER_0) || !defined(HEATER_0_USES_THERMISTOR) #define HEATER_0_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE #define HEATER_0_RAW_LO_TEMP 0 #else @@ -307,7 +405,7 @@ static_assert( #endif #endif #ifndef HEATER_1_RAW_HI_TEMP - #if defined(REVERSE_TEMP_SENSOR_RANGE) || !defined(HEATER_1_USES_THERMISTOR) + #if TT_REV(THERMISTOR_HEATER_1) || !defined(HEATER_1_USES_THERMISTOR) #define HEATER_1_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE #define HEATER_1_RAW_LO_TEMP 0 #else @@ -316,7 +414,7 @@ static_assert( #endif #endif #ifndef HEATER_2_RAW_HI_TEMP - #if defined(REVERSE_TEMP_SENSOR_RANGE) || !defined(HEATER_2_USES_THERMISTOR) + #if TT_REV(THERMISTOR_HEATER_2) || !defined(HEATER_2_USES_THERMISTOR) #define HEATER_2_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE #define HEATER_2_RAW_LO_TEMP 0 #else @@ -325,7 +423,7 @@ static_assert( #endif #endif #ifndef HEATER_3_RAW_HI_TEMP - #if defined(REVERSE_TEMP_SENSOR_RANGE) || !defined(HEATER_3_USES_THERMISTOR) + #if TT_REV(THERMISTOR_HEATER_3) || !defined(HEATER_3_USES_THERMISTOR) #define HEATER_3_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE #define HEATER_3_RAW_LO_TEMP 0 #else @@ -334,7 +432,7 @@ static_assert( #endif #endif #ifndef HEATER_4_RAW_HI_TEMP - #if defined(REVERSE_TEMP_SENSOR_RANGE) || !defined(HEATER_4_USES_THERMISTOR) + #if TT_REV(THERMISTOR_HEATER_4) || !defined(HEATER_4_USES_THERMISTOR) #define HEATER_4_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE #define HEATER_4_RAW_LO_TEMP 0 #else @@ -343,7 +441,7 @@ static_assert( #endif #endif #ifndef HEATER_5_RAW_HI_TEMP - #if defined(REVERSE_TEMP_SENSOR_RANGE) || !defined(HEATER_5_USES_THERMISTOR) + #if TT_REV(THERMISTOR_HEATER_5) || !defined(HEATER_5_USES_THERMISTOR) #define HEATER_5_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE #define HEATER_5_RAW_LO_TEMP 0 #else @@ -352,7 +450,7 @@ static_assert( #endif #endif #ifndef HEATER_6_RAW_HI_TEMP - #if defined(REVERSE_TEMP_SENSOR_RANGE) || !defined(HEATER_6_USES_THERMISTOR) + #if TT_REV(THERMISTOR_HEATER_6) || !defined(HEATER_6_USES_THERMISTOR) #define HEATER_6_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE #define HEATER_6_RAW_LO_TEMP 0 #else @@ -361,7 +459,7 @@ static_assert( #endif #endif #ifndef HEATER_7_RAW_HI_TEMP - #if defined(REVERSE_TEMP_SENSOR_RANGE) || !defined(HEATER_7_USES_THERMISTOR) + #if TT_REV(THERMISTOR_HEATER_7) || !defined(HEATER_7_USES_THERMISTOR) #define HEATER_7_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE #define HEATER_7_RAW_LO_TEMP 0 #else @@ -370,7 +468,7 @@ static_assert( #endif #endif #ifndef HEATER_BED_RAW_HI_TEMP - #if defined(REVERSE_TEMP_SENSOR_RANGE) || !defined(HEATER_BED_USES_THERMISTOR) + #if TT_REV(THERMISTORBED) || !defined(HEATER_BED_USES_THERMISTOR) #define HEATER_BED_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE #define HEATER_BED_RAW_LO_TEMP 0 #else @@ -379,7 +477,7 @@ static_assert( #endif #endif #ifndef HEATER_CHAMBER_RAW_HI_TEMP - #if defined(REVERSE_TEMP_SENSOR_RANGE) || !defined(HEATER_CHAMBER_USES_THERMISTOR) + #if TT_REV(THERMISTORCHAMBER) || !defined(HEATER_CHAMBER_USES_THERMISTOR) #define HEATER_CHAMBER_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE #define HEATER_CHAMBER_RAW_LO_TEMP 0 #else @@ -387,5 +485,15 @@ static_assert( #define HEATER_CHAMBER_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE #endif #endif +#ifndef HEATER_PROBE_RAW_HI_TEMP + #if TT_REV(THERMISTORPROBE) || !defined(HEATER_PROBE_USES_THERMISTOR) + #define HEATER_PROBE_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE + #define HEATER_PROBE_RAW_LO_TEMP 0 + #else + #define HEATER_PROBE_RAW_HI_TEMP 0 + #define HEATER_PROBE_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE + #endif +#endif -#undef REVERSE_TEMP_SENSOR_RANGE +#undef _TT_REV +#undef TT_REV diff --git a/Marlin/src/module/tool_change.cpp b/Marlin/src/module/tool_change.cpp index 021878c1eaf8..4ab818f41d2e 100644 --- a/Marlin/src/module/tool_change.cpp +++ b/Marlin/src/module/tool_change.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -31,18 +31,30 @@ #include "../MarlinCore.h" -#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) +//#define DEBUG_TOOL_CHANGE + +#define DEBUG_OUT ENABLED(DEBUG_TOOL_CHANGE) #include "../core/debug_out.h" -#if EXTRUDERS > 1 +#if HAS_MULTI_EXTRUDER toolchange_settings_t toolchange_settings; // Initialized by settings.load() #endif -#if ENABLED(SINGLENOZZLE) +#if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) + migration_settings_t migration = migration_defaults; + bool enable_first_prime; +#endif + +#if ENABLED(TOOLCHANGE_FS_INIT_BEFORE_SWAP) + bool toolchange_extruder_ready[EXTRUDERS]; +#endif + +#if ENABLED(SINGLENOZZLE_STANDBY_TEMP) uint16_t singlenozzle_temp[EXTRUDERS]; - #if FAN_COUNT > 0 - uint8_t singlenozzle_fan_speed[EXTRUDERS]; - #endif +#endif + +#if BOTH(HAS_FAN, SINGLENOZZLE_STANDBY_FAN) + uint8_t singlenozzle_fan_speed[EXTRUDERS]; #endif #if ENABLED(MAGNETIC_PARKING_EXTRUDER) || defined(EVENT_GCODE_AFTER_TOOLCHANGE) || (ENABLED(PARKING_EXTRUDER) && PARKING_EXTRUDER_SOLENOIDS_DELAY > 0) @@ -74,7 +86,7 @@ #endif #if ENABLED(PRUSA_MMU2) - #include "../feature/prusa_MMU2/mmu2.h" + #include "../feature/mmu2/mmu2.h" #endif #if HAS_LCD_MENU @@ -85,6 +97,14 @@ #include "../feature/pause.h" #endif +#if ENABLED(TOOLCHANGE_FILAMENT_SWAP) + #include "../gcode/gcode.h" + #if TOOLCHANGE_FS_WIPE_RETRACT <= 0 + #undef TOOLCHANGE_FS_WIPE_RETRACT + #define TOOLCHANGE_FS_WIPE_RETRACT 0 + #endif +#endif + #if DO_SWITCH_EXTRUDER #if EXTRUDERS > 3 @@ -152,13 +172,9 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a const float oldx = current_position.x, grabpos = mpe_settings.parking_xpos[new_tool] + (new_tool ? mpe_settings.grab_distance : -mpe_settings.grab_distance), - offsetcompensation = (0 - #if HAS_HOTEND_OFFSET - + hotend_offset[active_extruder].x * mpe_settings.compensation_factor - #endif - ); + offsetcompensation = TERN0(HAS_HOTEND_OFFSET, hotend_offset[active_extruder].x * mpe_settings.compensation_factor); - if (axis_unhomed_error(_BV(X_AXIS))) return; + if (homing_needed_error(_BV(X_AXIS))) return; /** * Z Lift and Nozzle Offset shift ar defined in caller method to work equal with any Multi Hotend realization @@ -176,10 +192,8 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a current_position.x = mpe_settings.parking_xpos[new_tool] + offsetcompensation; - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOPAIR("(1) Move extruder ", int(new_tool)); - DEBUG_POS(" to new extruder ParkPos", current_position); - } + DEBUG_ECHOPAIR("(1) Move extruder ", int(new_tool)); + DEBUG_POS(" to new extruder ParkPos", current_position); planner.buffer_line(current_position, mpe_settings.fast_feedrate, new_tool); planner.synchronize(); @@ -188,10 +202,8 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a current_position.x = grabpos + offsetcompensation; - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOPAIR("(2) Couple extruder ", int(new_tool)); - DEBUG_POS(" to new extruder GrabPos", current_position); - } + DEBUG_ECHOPAIR("(2) Couple extruder ", int(new_tool)); + DEBUG_POS(" to new extruder GrabPos", current_position); planner.buffer_line(current_position, mpe_settings.slow_feedrate, new_tool); planner.synchronize(); @@ -202,10 +214,9 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a // STEP 3 current_position.x = mpe_settings.parking_xpos[new_tool] + offsetcompensation; - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOPAIR("(3) Move extruder ", int(new_tool)); - DEBUG_POS(" back to new extruder ParkPos", current_position); - } + + DEBUG_ECHOPAIR("(3) Move extruder ", int(new_tool)); + DEBUG_POS(" back to new extruder ParkPos", current_position); planner.buffer_line(current_position, mpe_settings.slow_feedrate, new_tool); planner.synchronize(); @@ -213,10 +224,9 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a // STEP 4 current_position.x = mpe_settings.parking_xpos[active_extruder] + (active_extruder == 0 ? MPE_TRAVEL_DISTANCE : -MPE_TRAVEL_DISTANCE) + offsetcompensation; - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOPAIR("(4) Move extruder ", int(new_tool)); - DEBUG_POS(" close to old extruder ParkPos", current_position); - } + + DEBUG_ECHOPAIR("(4) Move extruder ", int(new_tool)); + DEBUG_POS(" close to old extruder ParkPos", current_position); planner.buffer_line(current_position, mpe_settings.fast_feedrate, new_tool); planner.synchronize(); @@ -225,10 +235,8 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a current_position.x = mpe_settings.parking_xpos[active_extruder] + offsetcompensation; - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOPAIR("(5) Park extruder ", int(new_tool)); - DEBUG_POS(" at old extruder ParkPos", current_position); - } + DEBUG_ECHOPAIR("(5) Park extruder ", int(new_tool)); + DEBUG_POS(" at old extruder ParkPos", current_position); planner.buffer_line(current_position, mpe_settings.slow_feedrate, new_tool); planner.synchronize(); @@ -237,21 +245,19 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a current_position.x = oldx; - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOPAIR("(6) Move extruder ", int(new_tool)); - DEBUG_POS(" to starting position", current_position); - } + DEBUG_ECHOPAIR("(6) Move extruder ", int(new_tool)); + DEBUG_POS(" to starting position", current_position); planner.buffer_line(current_position, mpe_settings.fast_feedrate, new_tool); planner.synchronize(); - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Autopark done."); + DEBUG_ECHOLNPGM("Autopark done."); } #elif ENABLED(PARKING_EXTRUDER) void pe_solenoid_init() { - for (uint8_t n = 0; n <= 1; ++n) + LOOP_LE_N(n, 1) #if ENABLED(PARKING_EXTRUDER_SOLENOIDS_INVERT) pe_activate_solenoid(n); #else @@ -294,37 +300,37 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a // STEP 1 - if (DEBUGGING(LEVELING)) DEBUG_POS("Start PE Tool-Change", current_position); + DEBUG_POS("Start PE Tool-Change", current_position); current_position.x = parkingposx[active_extruder] + x_offset; - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOLNPAIR("(1) Park extruder ", int(active_extruder)); - DEBUG_POS("Moving ParkPos", current_position); - } + + DEBUG_ECHOLNPAIR("(1) Park extruder ", int(active_extruder)); + DEBUG_POS("Moving ParkPos", current_position); + fast_line_to_current(X_AXIS); // STEP 2 planner.synchronize(); - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("(2) Disengage magnet"); + DEBUG_ECHOLNPGM("(2) Disengage magnet"); pe_deactivate_solenoid(active_extruder); // STEP 3 current_position.x += active_extruder ? -10 : 10; // move 10mm away from parked extruder - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOLNPGM("(3) Move near new extruder"); - DEBUG_POS("Move away from parked extruder", current_position); - } + + DEBUG_ECHOLNPGM("(3) Move near new extruder"); + DEBUG_POS("Move away from parked extruder", current_position); + fast_line_to_current(X_AXIS); // STEP 4 planner.synchronize(); - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("(4) Engage magnetic field"); - #if ENABLED(PARKING_EXTRUDER_SOLENOIDS_INVERT) - pe_activate_solenoid(active_extruder); // Just save power for inverted magnets - #endif + DEBUG_ECHOLNPGM("(4) Engage magnetic field"); + + // Just save power for inverted magnets + TERN_(PARKING_EXTRUDER_SOLENOIDS_INVERT, pe_activate_solenoid(active_extruder)); pe_activate_solenoid(new_tool); // STEP 5 @@ -333,34 +339,29 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a fast_line_to_current(X_AXIS); current_position.x = grabpos; - if (DEBUGGING(LEVELING)) { - planner.synchronize(); - DEBUG_POS("(5) Unpark extruder", current_position); - } + + DEBUG_SYNCHRONIZE(); + DEBUG_POS("(5) Unpark extruder", current_position); + slow_line_to_current(X_AXIS); // STEP 6 - current_position.x = midpos - #if HAS_HOTEND_OFFSET - - hotend_offset[new_tool].x - #endif - ; - if (DEBUGGING(LEVELING)) { - planner.synchronize(); - DEBUG_POS("(6) Move midway between hotends", current_position); - } + current_position.x = midpos - TERN0(HAS_HOTEND_OFFSET, hotend_offset[new_tool].x); + + DEBUG_SYNCHRONIZE(); + DEBUG_POS("(6) Move midway between hotends", current_position); + fast_line_to_current(X_AXIS); planner.synchronize(); // Always sync the final move - if (DEBUGGING(LEVELING)) DEBUG_POS("PE Tool-Change done.", current_position); + DEBUG_POS("PE Tool-Change done.", current_position); } else { // nomove == true // Only engage magnetic field for new extruder pe_activate_solenoid(new_tool); - #if ENABLED(PARKING_EXTRUDER_SOLENOIDS_INVERT) - pe_activate_solenoid(active_extruder); // Just save power for inverted magnets - #endif + // Just save power for inverted magnets + TERN_(PARKING_EXTRUDER_SOLENOIDS_INVERT, pe_activate_solenoid(active_extruder)); } } @@ -368,11 +369,16 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a #if ENABLED(SWITCHING_TOOLHEAD) + inline void swt_lock(const bool locked=true) { + const uint16_t swt_angles[2] = SWITCHING_TOOLHEAD_SERVO_ANGLES; + MOVE_SERVO(SWITCHING_TOOLHEAD_SERVO_NR, swt_angles[locked ? 0 : 1]); + } + + void swt_init() { swt_lock(); } + inline void switching_toolhead_tool_change(const uint8_t new_tool, bool no_move/*=false*/) { if (no_move) return; - constexpr uint16_t angles[2] = SWITCHING_TOOLHEAD_SERVO_ANGLES; - constexpr float toolheadposx[] = SWITCHING_TOOLHEAD_X_POS; const float placexpos = toolheadposx[active_extruder], grabxpos = toolheadposx[new_tool]; @@ -386,31 +392,31 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a // 1. Move to switch position of current toolhead - if (DEBUGGING(LEVELING)) DEBUG_POS("Start ST Tool-Change", current_position); + DEBUG_POS("Start ST Tool-Change", current_position); current_position.x = placexpos; - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOLNPAIR("(1) Place old tool ", int(active_extruder)); - DEBUG_POS("Move X SwitchPos", current_position); - } + + DEBUG_ECHOLNPAIR("(1) Place old tool ", int(active_extruder)); + DEBUG_POS("Move X SwitchPos", current_position); + fast_line_to_current(X_AXIS); current_position.y = SWITCHING_TOOLHEAD_Y_POS - (SWITCHING_TOOLHEAD_Y_SECURITY); - if (DEBUGGING(LEVELING)) { - planner.synchronize(); - DEBUG_POS("Move Y SwitchPos + Security", current_position); - } + + DEBUG_SYNCHRONIZE(); + DEBUG_POS("Move Y SwitchPos + Security", current_position); + fast_line_to_current(Y_AXIS); // 2. Unlock tool and drop it in the dock planner.synchronize(); - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("(2) Unlock and Place Toolhead"); - MOVE_SERVO(SWITCHING_TOOLHEAD_SERVO_NR, angles[1]); + DEBUG_ECHOLNPGM("(2) Unlock and Place Toolhead"); + swt_lock(false); safe_delay(500); current_position.y = SWITCHING_TOOLHEAD_Y_POS; - if (DEBUGGING(LEVELING)) DEBUG_POS("Move Y SwitchPos", current_position); + DEBUG_POS("Move Y SwitchPos", current_position); slow_line_to_current(Y_AXIS); // Wait for move to complete, then another 0.2s @@ -418,48 +424,48 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a safe_delay(200); current_position.y -= SWITCHING_TOOLHEAD_Y_CLEAR; - if (DEBUGGING(LEVELING)) DEBUG_POS("Move back Y clear", current_position); + DEBUG_POS("Move back Y clear", current_position); fast_line_to_current(Y_AXIS); // move away from docked toolhead // 3. Move to the new toolhead current_position.x = grabxpos; - if (DEBUGGING(LEVELING)) { - planner.synchronize(); - DEBUG_ECHOLNPGM("(3) Move to new toolhead position"); - DEBUG_POS("Move to new toolhead X", current_position); - } + + DEBUG_SYNCHRONIZE(); + DEBUG_ECHOLNPGM("(3) Move to new toolhead position"); + DEBUG_POS("Move to new toolhead X", current_position); + fast_line_to_current(X_AXIS); current_position.y = SWITCHING_TOOLHEAD_Y_POS - (SWITCHING_TOOLHEAD_Y_SECURITY); - if (DEBUGGING(LEVELING)) { - planner.synchronize(); - DEBUG_POS("Move Y SwitchPos + Security", current_position); - } + + DEBUG_SYNCHRONIZE(); + DEBUG_POS("Move Y SwitchPos + Security", current_position); + fast_line_to_current(Y_AXIS); // 4. Grab and lock the new toolhead current_position.y = SWITCHING_TOOLHEAD_Y_POS; - if (DEBUGGING(LEVELING)) { - planner.synchronize(); - DEBUG_ECHOLNPGM("(4) Grab and lock new toolhead"); - DEBUG_POS("Move Y SwitchPos", current_position); - } + + DEBUG_SYNCHRONIZE(); + DEBUG_ECHOLNPGM("(4) Grab and lock new toolhead"); + DEBUG_POS("Move Y SwitchPos", current_position); + slow_line_to_current(Y_AXIS); // Wait for move to finish, pause 0.2s, move servo, pause 0.5s planner.synchronize(); safe_delay(200); - MOVE_SERVO(SWITCHING_TOOLHEAD_SERVO_NR, angles[0]); + swt_lock(); safe_delay(500); current_position.y -= SWITCHING_TOOLHEAD_Y_CLEAR; - if (DEBUGGING(LEVELING)) DEBUG_POS("Move back Y clear", current_position); + DEBUG_POS("Move back Y clear", current_position); fast_line_to_current(Y_AXIS); // Move away from docked toolhead planner.synchronize(); // Always sync the final move - if (DEBUGGING(LEVELING)) DEBUG_POS("ST Tool-Change done.", current_position); + DEBUG_POS("ST Tool-Change done.", current_position); } #elif ENABLED(MAGNETIC_SWITCHING_TOOLHEAD) @@ -482,83 +488,77 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a * 4. Grab the new toolhead and move to security position */ - if (DEBUGGING(LEVELING)) DEBUG_POS("Start MST Tool-Change", current_position); + DEBUG_POS("Start MST Tool-Change", current_position); // 1. Move to switch position current toolhead current_position.y = SWITCHING_TOOLHEAD_Y_POS + SWITCHING_TOOLHEAD_Y_CLEAR; - if (DEBUGGING(LEVELING)) { - SERIAL_ECHOLNPAIR("(1) Place old tool ", int(active_extruder)); - DEBUG_POS("Move Y SwitchPos + Security", current_position); - } + + SERIAL_ECHOLNPAIR("(1) Place old tool ", int(active_extruder)); + DEBUG_POS("Move Y SwitchPos + Security", current_position); + fast_line_to_current(Y_AXIS); current_position.x = placexclear; - if (DEBUGGING(LEVELING)) { - planner.synchronize(); - DEBUG_POS("Move X SwitchPos + Security", current_position); - } + + DEBUG_SYNCHRONIZE(); + DEBUG_POS("Move X SwitchPos + Security", current_position); + fast_line_to_current(X_AXIS); current_position.y = SWITCHING_TOOLHEAD_Y_POS; - if (DEBUGGING(LEVELING)) { - planner.synchronize(); - DEBUG_POS("Move Y SwitchPos", current_position); - } + + DEBUG_SYNCHRONIZE(); + DEBUG_POS("Move Y SwitchPos", current_position); + fast_line_to_current(Y_AXIS); current_position.x = placexpos; - if (DEBUGGING(LEVELING)) { - planner.synchronize(); - DEBUG_POS("Move X SwitchPos", current_position); - } + + DEBUG_SYNCHRONIZE(); + DEBUG_POS("Move X SwitchPos", current_position); + line_to_current_position(planner.settings.max_feedrate_mm_s[X_AXIS] * 0.25f); // 2. Release and place toolhead in the dock - if (DEBUGGING(LEVELING)) { - planner.synchronize(); - DEBUG_ECHOLNPGM("(2) Release and Place Toolhead"); - } + DEBUG_SYNCHRONIZE(); + DEBUG_ECHOLNPGM("(2) Release and Place Toolhead"); current_position.y = SWITCHING_TOOLHEAD_Y_POS + SWITCHING_TOOLHEAD_Y_RELEASE; - if (DEBUGGING(LEVELING)) DEBUG_POS("Move Y SwitchPos + Release", current_position); + DEBUG_POS("Move Y SwitchPos + Release", current_position); line_to_current_position(planner.settings.max_feedrate_mm_s[Y_AXIS] * 0.1f); current_position.y = SWITCHING_TOOLHEAD_Y_POS + SWITCHING_TOOLHEAD_Y_SECURITY; - if (DEBUGGING(LEVELING)) { - planner.synchronize(); - DEBUG_POS("Move Y SwitchPos + Security", current_position); - } + + DEBUG_SYNCHRONIZE(); + DEBUG_POS("Move Y SwitchPos + Security", current_position); + line_to_current_position(planner.settings.max_feedrate_mm_s[Y_AXIS]); // 3. Move to new toolhead position - if (DEBUGGING(LEVELING)) { - planner.synchronize(); - DEBUG_ECHOLNPGM("(3) Move to new toolhead position"); - } + DEBUG_SYNCHRONIZE(); + DEBUG_ECHOLNPGM("(3) Move to new toolhead position"); current_position.x = grabxpos; - if (DEBUGGING(LEVELING)) DEBUG_POS("Move to new toolhead X", current_position); + DEBUG_POS("Move to new toolhead X", current_position); fast_line_to_current(X_AXIS); // 4. Grab the new toolhead and move to security position - if (DEBUGGING(LEVELING)) { - planner.synchronize(); - DEBUG_ECHOLNPGM("(4) Grab new toolhead, move to security position"); - } + DEBUG_SYNCHRONIZE(); + DEBUG_ECHOLNPGM("(4) Grab new toolhead, move to security position"); current_position.y = SWITCHING_TOOLHEAD_Y_POS + SWITCHING_TOOLHEAD_Y_RELEASE; - if (DEBUGGING(LEVELING)) DEBUG_POS("Move Y SwitchPos + Release", current_position); + DEBUG_POS("Move Y SwitchPos + Release", current_position); line_to_current_position(planner.settings.max_feedrate_mm_s[Y_AXIS]); current_position.y = SWITCHING_TOOLHEAD_Y_POS; - if (DEBUGGING(LEVELING)) { - planner.synchronize(); - DEBUG_POS("Move Y SwitchPos", current_position); - } + + DEBUG_SYNCHRONIZE(); + DEBUG_POS("Move Y SwitchPos", current_position); + _line_to_current(Y_AXIS, 0.2f); #if ENABLED(PRIME_BEFORE_REMOVE) && (SWITCHING_TOOLHEAD_PRIME_MM || SWITCHING_TOOLHEAD_RETRACT_MM) @@ -576,17 +576,17 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a #endif current_position.x = grabxclear; - if (DEBUGGING(LEVELING)) DEBUG_POS("Move to new toolhead X + Security", current_position); + DEBUG_POS("Move to new toolhead X + Security", current_position); _line_to_current(X_AXIS, 0.1f); planner.synchronize(); safe_delay(100); // Give switch time to settle current_position.y += SWITCHING_TOOLHEAD_Y_CLEAR; - if (DEBUGGING(LEVELING)) DEBUG_POS("Move back Y clear", current_position); + DEBUG_POS("Move back Y clear", current_position); fast_line_to_current(Y_AXIS); // move away from docked toolhead planner.synchronize(); // Always sync last tool-change move - if (DEBUGGING(LEVELING)) DEBUG_POS("MST Tool-Change done.", current_position); + DEBUG_POS("MST Tool-Change done.", current_position); } #elif ENABLED(ELECTROMAGNETIC_SWITCHING_TOOLHEAD) @@ -615,32 +615,29 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a * 9. Apply Z hotend offset to current position */ - if (DEBUGGING(LEVELING)) DEBUG_POS("Start EMST Tool-Change", current_position); + DEBUG_POS("Start EMST Tool-Change", current_position); // 1. Raise Z-Axis to give enough clearance current_position.z += SWITCHING_TOOLHEAD_Z_HOP; - if (DEBUGGING(LEVELING)) DEBUG_POS("(1) Raise Z-Axis ", current_position); + DEBUG_POS("(1) Raise Z-Axis ", current_position); fast_line_to_current(Z_AXIS); // 2. Move to position near active extruder parking - if (DEBUGGING(LEVELING)) { - planner.synchronize(); - SERIAL_ECHOLNPAIR("(2) Move near active extruder parking", active_extruder); - DEBUG_POS("Moving ParkPos", current_position); - } + DEBUG_SYNCHRONIZE(); + DEBUG_ECHOLNPAIR("(2) Move near active extruder parking", active_extruder); + DEBUG_POS("Moving ParkPos", current_position); + current_position.set(hoffs.x + placexpos, hoffs.y + SWITCHING_TOOLHEAD_Y_POS + SWITCHING_TOOLHEAD_Y_CLEAR); fast_line_to_current(X_AXIS); // 3. Move gently to park position of active extruder - if (DEBUGGING(LEVELING)) { - planner.synchronize(); - SERIAL_ECHOLNPAIR("(3) Move gently to park position of active extruder", active_extruder); - DEBUG_POS("Moving ParkPos", current_position); - } + DEBUG_SYNCHRONIZE(); + SERIAL_ECHOLNPAIR("(3) Move gently to park position of active extruder", active_extruder); + DEBUG_POS("Moving ParkPos", current_position); current_position.y -= SWITCHING_TOOLHEAD_Y_CLEAR; slow_line_to_current(Y_AXIS); @@ -648,15 +645,13 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a // 4. Disengage magnetic field, wait for delay planner.synchronize(); - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("(4) Disengage magnet"); + DEBUG_ECHOLNPGM("(4) Disengage magnet"); est_deactivate_solenoid(); // 5. Leave extruder and move to position near new extruder parking - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOLNPGM("(5) Move near new extruder parking"); - DEBUG_POS("Moving ParkPos", current_position); - } + DEBUG_ECHOLNPGM("(5) Move near new extruder parking"); + DEBUG_POS("Moving ParkPos", current_position); current_position.y += SWITCHING_TOOLHEAD_Y_CLEAR; slow_line_to_current(Y_AXIS); @@ -675,23 +670,23 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a // 7. Engage magnetic field for new extruder parking - planner.synchronize(); - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("(7) Engage magnetic field"); + DEBUG_SYNCHRONIZE(); + DEBUG_ECHOLNPGM("(7) Engage magnetic field"); est_activate_solenoid(); // 8. Unpark extruder current_position.y += SWITCHING_TOOLHEAD_Y_CLEAR; - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("(8) Unpark extruder"); + DEBUG_ECHOLNPGM("(8) Unpark extruder"); slow_line_to_current(X_AXIS); planner.synchronize(); // Always sync the final move // 9. Apply Z hotend offset to current position - if (DEBUGGING(LEVELING)) DEBUG_POS("(9) Applying Z-offset", current_position); + DEBUG_POS("(9) Applying Z-offset", current_position); current_position.z += hoffs.z - hotend_offset[new_tool].z; - if (DEBUGGING(LEVELING)) DEBUG_POS("EMST Tool-Change done.", current_position); + DEBUG_POS("EMST Tool-Change done.", current_position); } #endif // ELECTROMAGNETIC_SWITCHING_TOOLHEAD @@ -707,14 +702,13 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a #if ENABLED(DUAL_X_CARRIAGE) inline void dualx_tool_change(const uint8_t new_tool, bool &no_move) { - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOPGM("Dual X Carriage Mode "); - switch (dual_x_carriage_mode) { - case DXC_FULL_CONTROL_MODE: DEBUG_ECHOLNPGM("FULL_CONTROL"); break; - case DXC_AUTO_PARK_MODE: DEBUG_ECHOLNPGM("AUTO_PARK"); break; - case DXC_DUPLICATION_MODE: DEBUG_ECHOLNPGM("DUPLICATION"); break; - case DXC_MIRRORED_MODE: DEBUG_ECHOLNPGM("MIRRORED"); break; - } + + DEBUG_ECHOPGM("Dual X Carriage Mode "); + switch (dual_x_carriage_mode) { + case DXC_FULL_CONTROL_MODE: DEBUG_ECHOLNPGM("FULL_CONTROL"); break; + case DXC_AUTO_PARK_MODE: DEBUG_ECHOLNPGM("AUTO_PARK"); break; + case DXC_DUPLICATION_MODE: DEBUG_ECHOLNPGM("DUPLICATION"); break; + case DXC_MIRRORED_MODE: DEBUG_ECHOLNPGM("MIRRORED"); break; } const float xhome = x_home_pos(active_extruder); @@ -723,7 +717,7 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a && (delayed_move_time || current_position.x != xhome) ) { - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("MoveX to ", xhome); + DEBUG_ECHOLNPAIR("MoveX to ", xhome); // Park old head current_position.x = xhome; @@ -737,7 +731,7 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a // This function resets the max/min values - the current position may be overwritten below. set_axis_is_at_home(X_AXIS); - if (DEBUGGING(LEVELING)) DEBUG_POS("New Extruder", current_position); + DEBUG_POS("New Extruder", current_position); switch (dual_x_carriage_mode) { case DXC_FULL_CONTROL_MODE: @@ -756,23 +750,95 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a break; } - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOLNPAIR("Active extruder parked: ", active_extruder_parked ? "yes" : "no"); - DEBUG_POS("New extruder (parked)", current_position); - } + DEBUG_ECHOLNPAIR("Active extruder parked: ", active_extruder_parked ? "yes" : "no"); + DEBUG_POS("New extruder (parked)", current_position); } #endif // DUAL_X_CARRIAGE +/** + * Prime active tool using TOOLCHANGE_FILAMENT_SWAP settings + */ +#if ENABLED(TOOLCHANGE_FILAMENT_SWAP) + +void tool_change_prime() { + if (toolchange_settings.extra_prime > 0 + && TERN(PREVENT_COLD_EXTRUSION, !thermalManager.targetTooColdToExtrude(active_extruder), 1) + ) { + destination = current_position; // Remember the old position + + const bool ok = TERN1(TOOLCHANGE_PARK, all_axes_homed() && toolchange_settings.enable_park); + + #if HAS_FAN && TOOLCHANGE_FS_FAN >= 0 + // Store and stop fan. Restored on any exit. + REMEMBER(fan, thermalManager.fan_speed[TOOLCHANGE_FS_FAN], 0); + #endif + + // Z raise + if (ok) { + // Do a small lift to avoid the workpiece in the move back (below) + current_position.z += toolchange_settings.z_raise; + #if HAS_SOFTWARE_ENDSTOPS + NOMORE(current_position.z, soft_endstop.max.z); + #endif + fast_line_to_current(Z_AXIS); + planner.synchronize(); + } + + // Park + #if ENABLED(TOOLCHANGE_PARK) + if (ok) { + TERN(TOOLCHANGE_PARK_Y_ONLY,,current_position.x = toolchange_settings.change_point.x); + TERN(TOOLCHANGE_PARK_X_ONLY,,current_position.y = toolchange_settings.change_point.y); + planner.buffer_line(current_position, MMM_TO_MMS(TOOLCHANGE_PARK_XY_FEEDRATE), active_extruder); + planner.synchronize(); + } + #endif + + // Prime (All distances are added and slowed down to ensure secure priming in all circumstances) + unscaled_e_move(toolchange_settings.swap_length + toolchange_settings.extra_prime, MMM_TO_MMS(toolchange_settings.prime_speed)); + + // Cutting retraction + #if TOOLCHANGE_FS_WIPE_RETRACT + unscaled_e_move(-(TOOLCHANGE_FS_WIPE_RETRACT), MMM_TO_MMS(toolchange_settings.retract_speed)); + #endif + + // Cool down with fan + #if HAS_FAN && TOOLCHANGE_FS_FAN >= 0 + thermalManager.fan_speed[TOOLCHANGE_FS_FAN] = toolchange_settings.fan_speed; + gcode.dwell(toolchange_settings.fan_time * 1000); + thermalManager.fan_speed[TOOLCHANGE_FS_FAN] = 0; + #endif + + // Move back + #if ENABLED(TOOLCHANGE_PARK) + if (ok) { + #if ENABLED(TOOLCHANGE_NO_RETURN) + do_blocking_move_to_z(destination.z, planner.settings.max_feedrate_mm_s[Z_AXIS]); + #else + do_blocking_move_to(destination, MMM_TO_MMS(TOOLCHANGE_PARK_XY_FEEDRATE)); + #endif + } + #endif + + // Cutting recover + unscaled_e_move(toolchange_settings.extra_resume + TOOLCHANGE_FS_WIPE_RETRACT, MMM_TO_MMS(toolchange_settings.unretract_speed)); + + planner.synchronize(); + current_position.e = destination.e; + sync_plan_position_e(); // Resume at the old E position + } +} +#endif + /** * Perform a tool-change, which may result in moving the * previous tool out of the way and the new tool into place. */ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) { - #if ENABLED(MAGNETIC_SWITCHING_TOOLHEAD) - if (new_tool == active_extruder) return; - #endif + if (TERN0(MAGNETIC_SWITCHING_TOOLHEAD, new_tool == active_extruder)) + return; #if ENABLED(MIXING_EXTRUDER) @@ -804,7 +870,7 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) { if (new_tool) invalid_extruder_error(new_tool); return; - #else // EXTRUDERS > 1 + #elif HAS_MULTI_EXTRUDER planner.synchronize(); @@ -816,14 +882,12 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) { if (new_tool >= EXTRUDERS) return invalid_extruder_error(new_tool); - if (!no_move && !all_axes_homed()) { + if (!no_move && homing_needed()) { no_move = true; - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("No move (not homed)"); + DEBUG_ECHOLNPGM("No move (not homed)"); } - #if HAS_LCD_MENU - if (!no_move) ui.return_to_status(); - #endif + TERN_(HAS_LCD_MENU, if (!no_move) ui.return_to_status()); #if ENABLED(DUAL_X_CARRIAGE) const bool idex_full_control = dual_x_carriage_mode == DXC_FULL_CONTROL_MODE; @@ -834,44 +898,66 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) { const uint8_t old_tool = active_extruder; const bool can_move_away = !no_move && !idex_full_control; - #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) - const bool should_swap = can_move_away && toolchange_settings.swap_length; - #if ENABLED(PREVENT_COLD_EXTRUSION) - const bool too_cold = !DEBUGGING(DRYRUN) && (thermalManager.targetTooColdToExtrude(old_tool) || thermalManager.targetTooColdToExtrude(new_tool)); - #else - constexpr bool too_cold = false; - #endif - if (should_swap) { - if (too_cold) { - SERIAL_ECHO_MSG(STR_ERR_HOTEND_TOO_COLD); - #if ENABLED(SINGLENOZZLE) - active_extruder = new_tool; - return; - #endif - } - else { - #if ENABLED(ADVANCED_PAUSE_FEATURE) - do_pause_e_move(-toolchange_settings.swap_length, MMM_TO_MMS(toolchange_settings.retract_speed)); - #else - current_position.e -= toolchange_settings.swap_length / planner.e_factor[old_tool]; - planner.buffer_line(current_position, MMM_TO_MMS(toolchange_settings.retract_speed), old_tool); - planner.synchronize(); - #endif - } - } - #endif // TOOLCHANGE_FILAMENT_SWAP - - #if HAS_LEVELING && DISABLED(SINGLENOZZLE) + #if HAS_LEVELING // Set current position to the physical position TEMPORARY_BED_LEVELING_STATE(false); #endif + // First tool priming. To prime again, reboot the machine. + #if BOTH(TOOLCHANGE_FILAMENT_SWAP, TOOLCHANGE_FS_PRIME_FIRST_USED) + static bool first_tool_is_primed = false; + if (new_tool == old_tool && !first_tool_is_primed && enable_first_prime) { + tool_change_prime(); + first_tool_is_primed = true; + toolchange_extruder_ready[old_tool] = true; // Primed and initialized + } + #endif + if (new_tool != old_tool) { + destination = current_position; - #if SWITCHING_NOZZLE_TWO_SERVOS - raise_nozzle(old_tool); + #if BOTH(TOOLCHANGE_FILAMENT_SWAP, HAS_FAN) && TOOLCHANGE_FS_FAN >= 0 + // Store and stop fan. Restored on any exit. + REMEMBER(fan, thermalManager.fan_speed[TOOLCHANGE_FS_FAN], 0); + #endif + + // Z raise before retraction + #if ENABLED(TOOLCHANGE_ZRAISE_BEFORE_RETRACT) && DISABLED(SWITCHING_NOZZLE) + if (can_move_away && TERN1(TOOLCHANGE_PARK, toolchange_settings.enable_park)) { + // Do a small lift to avoid the workpiece in the move back (below) + current_position.z += toolchange_settings.z_raise; + #if HAS_SOFTWARE_ENDSTOPS + NOMORE(current_position.z, soft_endstop.max.z); + #endif + fast_line_to_current(Z_AXIS); + planner.synchronize(); + } #endif + // Unload / Retract + #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) + const bool should_swap = can_move_away && toolchange_settings.swap_length, + too_cold = TERN0(PREVENT_COLD_EXTRUSION, + !DEBUGGING(DRYRUN) && (thermalManager.targetTooColdToExtrude(old_tool) || thermalManager.targetTooColdToExtrude(new_tool)) + ); + if (should_swap) { + if (too_cold) { + SERIAL_ECHO_MSG(STR_ERR_HOTEND_TOO_COLD); + if (ENABLED(SINGLENOZZLE)) { active_extruder = new_tool; return; } + } + else { + #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED) + // For first new tool, change without unloading the old. 'Just prime/init the new' + if (first_tool_is_primed) + unscaled_e_move(-toolchange_settings.swap_length, MMM_TO_MMS(toolchange_settings.retract_speed)); + first_tool_is_primed = true; // The first new tool will be primed by toolchanging + #endif + } + } + #endif + + TERN_(SWITCHING_NOZZLE_TWO_SERVOS, raise_nozzle(old_tool)); + REMEMBER(fr, feedrate_mm_s, XY_PROBE_FEEDRATE_MM_S); #if HAS_SOFTWARE_ENDSTOPS @@ -887,29 +973,30 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) { #endif #endif - destination = current_position; - - #if DISABLED(SWITCHING_NOZZLE) - if (can_move_away) { + #if DISABLED(TOOLCHANGE_ZRAISE_BEFORE_RETRACT) && DISABLED(SWITCHING_NOZZLE) + if (can_move_away && TERN1(TOOLCHANGE_PARK, toolchange_settings.enable_park)) { // Do a small lift to avoid the workpiece in the move back (below) current_position.z += toolchange_settings.z_raise; #if HAS_SOFTWARE_ENDSTOPS NOMORE(current_position.z, soft_endstop.max.z); #endif fast_line_to_current(Z_AXIS); - #if ENABLED(TOOLCHANGE_PARK) - current_position = toolchange_settings.change_point; - #endif - planner.buffer_line(current_position, feedrate_mm_s, old_tool); + } + #endif + + // Toolchange park + #if ENABLED(TOOLCHANGE_PARK) && DISABLED(SWITCHING_NOZZLE) + if (can_move_away && toolchange_settings.enable_park) { + TERN(TOOLCHANGE_PARK_Y_ONLY,,current_position.x = toolchange_settings.change_point.x); + TERN(TOOLCHANGE_PARK_X_ONLY,,current_position.y = toolchange_settings.change_point.y); + planner.buffer_line(current_position, MMM_TO_MMS(TOOLCHANGE_PARK_XY_FEEDRATE), old_tool); planner.synchronize(); } #endif #if HAS_HOTEND_OFFSET xyz_pos_t diff = hotend_offset[new_tool] - hotend_offset[old_tool]; - #if ENABLED(DUAL_X_CARRIAGE) - diff.x = 0; - #endif + TERN_(DUAL_X_CARRIAGE, diff.x = 0); #else constexpr xyz_pos_t diff{0}; #endif @@ -930,14 +1017,10 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) { // Raise by a configured distance to avoid workpiece, except with // SWITCHING_NOZZLE_TWO_SERVOS, as both nozzles will lift instead. if (!no_move) { - #if HAS_SOFTWARE_ENDSTOPS - const float maxz = _MIN(soft_endstop.max.z, Z_MAX_POS); - #else - constexpr float maxz = Z_MAX_POS; - #endif + const float newz = current_position.z + _MAX(-diff.z, 0.0); // Check if Z has space to compensate at least z_offset, and if not, just abort now - const float newz = current_position.z + _MAX(-diff.z, 0.0); + const float maxz = _MIN(TERN(HAS_SOFTWARE_ENDSTOPS, soft_endstop.max.z, Z_MAX_POS), Z_MAX_POS); if (newz > maxz) return; current_position.z = _MIN(newz + toolchange_settings.z_raise, maxz); @@ -946,12 +1029,11 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) { move_nozzle_servo(new_tool); #endif - #if DISABLED(DUAL_X_CARRIAGE) - active_extruder = new_tool; // Set the new active extruder - #endif + // Set the new active extruder + if (DISABLED(DUAL_X_CARRIAGE)) active_extruder = new_tool; // The newly-selected extruder XYZ is actually at... - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Offset Tool XYZ by { ", diff.x, ", ", diff.y, ", ", diff.z, " }"); + DEBUG_ECHOLNPAIR("Offset Tool XYZ by { ", diff.x, ", ", diff.y, ", ", diff.z, " }"); current_position += diff; // Tell the planner the new "current position" @@ -965,37 +1047,54 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) { #endif // Return to position and lower again - if (safe_to_move && !no_move && IsRunning()) { + const bool should_move = safe_to_move && !no_move && IsRunning(); + if (should_move) { - #if ENABLED(SINGLENOZZLE) - #if FAN_COUNT > 0 - singlenozzle_fan_speed[old_tool] = thermalManager.fan_speed[0]; - thermalManager.fan_speed[0] = singlenozzle_fan_speed[new_tool]; - #endif + #if BOTH(HAS_FAN, SINGLENOZZLE_STANDBY_FAN) + singlenozzle_fan_speed[old_tool] = thermalManager.fan_speed[0]; + thermalManager.fan_speed[0] = singlenozzle_fan_speed[new_tool]; + #endif + #if ENABLED(SINGLENOZZLE_STANDBY_TEMP) singlenozzle_temp[old_tool] = thermalManager.temp_hotend[0].target; if (singlenozzle_temp[new_tool] && singlenozzle_temp[new_tool] != singlenozzle_temp[old_tool]) { thermalManager.setTargetHotend(singlenozzle_temp[new_tool], 0); - #if HAS_DISPLAY - thermalManager.set_heating_message(0); - #endif + TERN_(AUTOTEMP, planner.autotemp_update()); + TERN_(HAS_DISPLAY, thermalManager.set_heating_message(0)); (void)thermalManager.wait_for_hotend(0, false); // Wait for heating or cooling } #endif #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) if (should_swap && !too_cold) { - #if ENABLED(ADVANCED_PAUSE_FEATURE) - do_pause_e_move(toolchange_settings.swap_length, MMM_TO_MMS(toolchange_settings.prime_speed)); - do_pause_e_move(toolchange_settings.extra_prime, ADVANCED_PAUSE_PURGE_FEEDRATE); - #else - current_position.e += toolchange_settings.swap_length / planner.e_factor[new_tool]; - planner.buffer_line(current_position, MMM_TO_MMS(toolchange_settings.prime_speed), new_tool); - current_position.e += toolchange_settings.extra_prime / planner.e_factor[new_tool]; - planner.buffer_line(current_position, MMM_TO_MMS(toolchange_settings.prime_speed * 0.2f), new_tool); + + float fr = toolchange_settings.unretract_speed; + + #if ENABLED(TOOLCHANGE_FS_INIT_BEFORE_SWAP) + if (!toolchange_extruder_ready[new_tool]) { + toolchange_extruder_ready[new_tool] = true; + fr = toolchange_settings.prime_speed; // Next move is a prime + unscaled_e_move(0, MMM_TO_MMS(fr)); // Init planner with 0 length move + } + #endif + + // Unretract (or Prime) + unscaled_e_move(toolchange_settings.swap_length, MMM_TO_MMS(fr)); + + // Extra Prime + unscaled_e_move(toolchange_settings.extra_prime, MMM_TO_MMS(toolchange_settings.prime_speed)); + + // Cutting retraction + #if TOOLCHANGE_FS_WIPE_RETRACT + unscaled_e_move(-(TOOLCHANGE_FS_WIPE_RETRACT), MMM_TO_MMS(toolchange_settings.retract_speed)); + #endif + + // Cool down with fan + #if HAS_FAN && TOOLCHANGE_FS_FAN >= 0 + thermalManager.fan_speed[TOOLCHANGE_FS_FAN] = toolchange_settings.fan_speed; + gcode.dwell(toolchange_settings.fan_time * 1000); + thermalManager.fan_speed[TOOLCHANGE_FS_FAN] = 0; #endif - planner.synchronize(); - planner.set_e_position_mm((destination.e = current_position.e = current_position.e - (TOOLCHANGE_FIL_EXTRA_PRIME))); } #endif @@ -1015,34 +1114,55 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) { if (can_move_away) { #if ENABLED(TOOLCHANGE_NO_RETURN) // Just move back down - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Move back Z only"); + DEBUG_ECHOLNPGM("Move back Z only"); + + #if ENABLED(TOOLCHANGE_PARK) + if (toolchange_settings.enable_park) + #endif do_blocking_move_to_z(destination.z, planner.settings.max_feedrate_mm_s[Z_AXIS]); + #else // Move back to the original (or adjusted) position - if (DEBUGGING(LEVELING)) DEBUG_POS("Move back", destination); - do_blocking_move_to(destination); + DEBUG_POS("Move back", destination); + + #if ENABLED(TOOLCHANGE_PARK) + if (toolchange_settings.enable_park) do_blocking_move_to_xy_z(destination, destination.z, MMM_TO_MMS(TOOLCHANGE_PARK_XY_FEEDRATE)); + #else + do_blocking_move_to_xy(destination, planner.settings.max_feedrate_mm_s[X_AXIS]); + do_blocking_move_to_z(destination.z, planner.settings.max_feedrate_mm_s[Z_AXIS]); + #endif + #endif } - else if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Move back skipped"); - #if ENABLED(DUAL_X_CARRIAGE) - active_extruder_parked = false; + else DEBUG_ECHOLNPGM("Move back skipped"); + + #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) + if (should_swap && !too_cold) { + // Cutting recover + unscaled_e_move(toolchange_settings.extra_resume + TOOLCHANGE_FS_WIPE_RETRACT, MMM_TO_MMS(toolchange_settings.unretract_speed)); + current_position.e = 0; + sync_plan_position_e(); // New extruder primed and set to 0 + + // Restart Fan + #if HAS_FAN && TOOLCHANGE_FS_FAN >= 0 + RESTORE(fan); + #endif + } #endif + + TERN_(DUAL_X_CARRIAGE, active_extruder_parked = false); } + #if ENABLED(SWITCHING_NOZZLE) - else { - // Move back down. (Including when the new tool is higher.) + // Move back down. (Including when the new tool is higher.) + if (!should_move) do_blocking_move_to_z(destination.z, planner.settings.max_feedrate_mm_s[Z_AXIS]); - } #endif - #if ENABLED(PRUSA_MMU2) - mmu2.tool_change(new_tool); - #endif + TERN_(PRUSA_MMU2, mmu2.tool_change(new_tool)); - #if SWITCHING_NOZZLE_TWO_SERVOS - lower_nozzle(new_tool); - #endif + TERN_(SWITCHING_NOZZLE_TWO_SERVOS, lower_nozzle(new_tool)); } // (new_tool != old_tool) @@ -1063,17 +1183,119 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) { move_extruder_servo(active_extruder); #endif - #if HAS_FANMUX - fanmux_switch(active_extruder); - #endif + TERN_(HAS_FANMUX, fanmux_switch(active_extruder)); #ifdef EVENT_GCODE_AFTER_TOOLCHANGE - if (!no_move) + if (!no_move && TERN1(DUAL_X_CARRIAGE, dual_x_carriage_mode == DXC_AUTO_PARK_MODE)) gcode.process_subcommands_now_P(PSTR(EVENT_GCODE_AFTER_TOOLCHANGE)); #endif SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR(STR_ACTIVE_EXTRUDER, int(active_extruder)); - #endif // EXTRUDERS > 1 + #endif // HAS_MULTI_EXTRUDER } + +#if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) + + bool extruder_migration() { + + #if ENABLED(PREVENT_COLD_EXTRUSION) + if (thermalManager.targetTooColdToExtrude(active_extruder)) { + #if ENABLED(DEBUG_TOOLCHANGE_MIGRATION_FEATURE) + SERIAL_ECHOLN("Migration Source Too Cold"); + #endif + return false; + } + #endif + + // No auto-migration or specified target? + if (!migration.target && active_extruder >= migration.last) { + #if ENABLED(DEBUG_TOOLCHANGE_MIGRATION_FEATURE) + SERIAL_ECHO_MSG("No Migration Target"); + SERIAL_ECHO_MSG("Target: ", migration.target, + " Last: ", migration.last, + " Active: ", active_extruder); + #endif + migration.automode = false; + return false; + } + + // Migrate to a target or the next extruder + + uint8_t migration_extruder = active_extruder; + + if (migration.target) { + #if ENABLED(DEBUG_TOOLCHANGE_MIGRATION_FEATURE) + SERIAL_ECHOLN("Migration using fixed target"); + #endif + // Specified target ok? + const int16_t t = migration.target - 1; + if (t != active_extruder) migration_extruder = t; + } + else if (migration.automode && migration_extruder < migration.last && migration_extruder < EXTRUDERS - 1) + migration_extruder++; + + if (migration_extruder == active_extruder) { + #if ENABLED(DEBUG_TOOLCHANGE_MIGRATION_FEATURE) + SERIAL_ECHOLN("Migration source matches active"); + #endif + return false; + } + + // Migration begins + #if ENABLED(DEBUG_TOOLCHANGE_MIGRATION_FEATURE) + SERIAL_ECHOLN("Beginning migration"); + #endif + + migration.in_progress = true; // Prevent runout script + planner.synchronize(); + + // Remember position before migration + const float resume_current_e = current_position.e; + + // Migrate the flow + planner.set_flow(migration_extruder, planner.flow_percentage[active_extruder]); + + // Migrate the retracted state + #if ENABLED(FWRETRACT) + fwretract.retracted[migration_extruder] = fwretract.retracted[active_extruder]; + #endif + + // Migrate the temperature to the new hotend + #if HAS_MULTI_HOTEND + thermalManager.setTargetHotend(thermalManager.temp_hotend[active_extruder].target, migration_extruder); + TERN_(AUTOTEMP, planner.autotemp_update()); + TERN_(HAS_DISPLAY, thermalManager.set_heating_message(0)); + thermalManager.wait_for_hotend(active_extruder); + #endif + + // Migrate Linear Advance K factor to the new extruder + TERN_(LIN_ADVANCE, planner.extruder_advance_K[active_extruder] = planner.extruder_advance_K[migration_extruder]); + + // Perform the tool change + tool_change(migration_extruder); + + // Retract if previously retracted + #if ENABLED(FWRETRACT) + if (fwretract.retracted[active_extruder]) + unscaled_e_move(-fwretract.settings.retract_length, fwretract.settings.retract_feedrate_mm_s); + #endif + + // If no available extruder + if (EXTRUDERS < 2 || active_extruder >= EXTRUDERS - 2 || active_extruder == migration.last) + migration.automode = false; + + migration.in_progress = false; + + current_position.e = resume_current_e; + + planner.synchronize(); + planner.set_e_position_mm(current_position.e); // New extruder primed and ready + #if ENABLED(DEBUG_TOOLCHANGE_MIGRATION_FEATURE) + SERIAL_ECHOLN("Migration Complete"); + #endif + return true; + } + +#endif // TOOLCHANGE_MIGRATION_FEATURE diff --git a/Marlin/src/module/tool_change.h b/Marlin/src/module/tool_change.h index 025d2997d1cc..38347191d390 100644 --- a/Marlin/src/module/tool_change.h +++ b/Marlin/src/module/tool_change.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -24,14 +24,15 @@ #include "../inc/MarlinConfigPre.h" #include "../core/types.h" -#if EXTRUDERS > 1 +#if HAS_MULTI_EXTRUDER typedef struct { #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) - float swap_length, extra_prime; - int16_t prime_speed, retract_speed; + float swap_length, extra_prime, extra_resume; + int16_t prime_speed, retract_speed, unretract_speed, fan, fan_speed, fan_time; #endif #if ENABLED(TOOLCHANGE_PARK) + bool enable_park; xy_pos_t change_point; #endif float z_raise; @@ -39,6 +40,27 @@ extern toolchange_settings_t toolchange_settings; + #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) + extern void tool_change_prime(); + #endif + + #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED) + extern bool enable_first_prime; + #endif + + #if ENABLED(TOOLCHANGE_FS_INIT_BEFORE_SWAP) + extern bool toolchange_extruder_ready[EXTRUDERS]; + #endif + + #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) + typedef struct { + uint8_t target, last; + bool automode, in_progress; + } migration_settings_t; + constexpr migration_settings_t migration_defaults = { 0, 0, false, false }; + extern migration_settings_t migration; + bool extruder_migration(); + #endif #endif #if DO_SWITCH_EXTRUDER @@ -86,17 +108,18 @@ #endif -#if ENABLED(SINGLENOZZLE) +#if ENABLED(SINGLENOZZLE_STANDBY_TEMP) extern uint16_t singlenozzle_temp[EXTRUDERS]; - #if FAN_COUNT > 0 - extern uint8_t singlenozzle_fan_speed[EXTRUDERS]; - #endif #endif -#if ENABLED(ELECTROMAGNETIC_SWITCHING_TOOLHEAD) - void est_init(); +#if BOTH(HAS_FAN, SINGLENOZZLE_STANDBY_FAN) + extern uint8_t singlenozzle_fan_speed[EXTRUDERS]; #endif +TERN_(ELECTROMAGNETIC_SWITCHING_TOOLHEAD, void est_init()); + +TERN_(SWITCHING_TOOLHEAD, void swt_init()); + /** * Perform a tool-change, which may result in moving the * previous tool out of the way and the new tool into place. diff --git a/Marlin/src/pins/esp32/pins_E4D.h b/Marlin/src/pins/esp32/pins_E4D.h index 409f38129712..7b5595444cf1 100644 --- a/Marlin/src/pins/esp32/pins_E4D.h +++ b/Marlin/src/pins/esp32/pins_E4D.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -24,10 +24,10 @@ /** * E4d@Box pin assignments * E4d@Box is a small factor 3D printer control board based on the ESP32 microcontroller for Laser, CNC and 3d printers - * for more info check http://atbox.tech/ and join to Facebook page E4d@box. + * for more info check https://atbox.tech/ and join to Facebook page E4d@box. */ -#ifndef ARDUINO_ARCH_ESP32 +#if NOT_TARGET(ARDUINO_ARCH_ESP32) #error "Oops! Select an ESP32 board in 'Tools > Board.'" #elif EXTRUDERS > 1 || E_STEPPERS > 1 #error "E4d@box only supports one E Stepper. Comment out this line to continue." @@ -42,49 +42,49 @@ // // Limit Switches // -#define X_MIN_PIN 34 -#define Y_MIN_PIN 35 -#define Z_MIN_PIN 16 // 15 +#define X_MIN_PIN 34 +#define Y_MIN_PIN 35 +#define Z_MIN_PIN 16 // 15 // // Steppers // -#define X_STEP_PIN 12 // 34//27 -#define X_DIR_PIN 13 // 35//26 -#define X_ENABLE_PIN 17 // 0//17//25 // used free pin -//#define X_CS_PIN 0 +#define X_STEP_PIN 12 // 34//27 +#define X_DIR_PIN 13 // 35//26 +#define X_ENABLE_PIN 17 // 0//17//25 // used free pin +//#define X_CS_PIN 0 -#define Y_STEP_PIN 32 // 33 -#define Y_DIR_PIN 33 // 32 -#define Y_ENABLE_PIN X_ENABLE_PIN -//#define Y_CS_PIN 13 +#define Y_STEP_PIN 32 // 33 +#define Y_DIR_PIN 33 // 32 +#define Y_ENABLE_PIN X_ENABLE_PIN +//#define Y_CS_PIN 13 -#define Z_STEP_PIN 25 // 14 -#define Z_DIR_PIN 26 // 12 -#define Z_ENABLE_PIN X_ENABLE_PIN -//#define Z_CS_PIN 5 // SS_PIN +#define Z_STEP_PIN 25 // 14 +#define Z_DIR_PIN 26 // 12 +#define Z_ENABLE_PIN X_ENABLE_PIN +//#define Z_CS_PIN 5 // SS_PIN -#define E0_STEP_PIN 27 // 16 -#define E0_DIR_PIN 14 // 17 -#define E0_ENABLE_PIN X_ENABLE_PIN -//#define E0_CS_PIN 21 +#define E0_STEP_PIN 27 // 16 +#define E0_DIR_PIN 14 // 17 +#define E0_ENABLE_PIN X_ENABLE_PIN +//#define E0_CS_PIN 21 // // Temperature Sensors // -#define TEMP_0_PIN 36 // Analog Input -#define TEMP_BED_PIN 39 // Analog Input +#define TEMP_0_PIN 36 // Analog Input +#define TEMP_BED_PIN 39 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 2 // 4//2//(D8) -#define FAN_PIN 0 // 2//15//13 (D9) -#define HEATER_BED_PIN 15 // 15//0 //(D10) +#define HEATER_0_PIN 2 // 4//2//(D8) +#define FAN_PIN 0 // 2//15//13 (D9) +#define HEATER_BED_PIN 15 // 15//0 //(D10) // SPI -#define SDSS 5 +#define SDSS 5 #define I2S_STEPPER_STREAM -#define I2S_WS 23 -#define I2S_BCK 22 -#define I2S_DATA 21 +#define I2S_WS 23 +#define I2S_BCK 22 +#define I2S_DATA 21 diff --git a/Marlin/src/pins/esp32/pins_ESP32.h b/Marlin/src/pins/esp32/pins_ESP32.h index 99a5ea2f76df..d54a92b9c4e5 100644 --- a/Marlin/src/pins/esp32/pins_ESP32.h +++ b/Marlin/src/pins/esp32/pins_ESP32.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Espressif ESP32 (Tensilica Xtensa LX6) pin assignments */ -#ifndef ARDUINO_ARCH_ESP32 +#if NOT_TARGET(ARDUINO_ARCH_ESP32) "Oops! Select an ESP32 board in 'Tools > Board.'" #endif @@ -35,52 +35,52 @@ // I2S (steppers & other output-only pins) // #define I2S_STEPPER_STREAM -#define I2S_WS 25 -#define I2S_BCK 26 -#define I2S_DATA 27 +#define I2S_WS 25 +#define I2S_BCK 26 +#define I2S_DATA 27 // // Limit Switches // -#define X_MIN_PIN 34 -#define Y_MIN_PIN 35 -#define Z_MIN_PIN 15 +#define X_MIN_PIN 34 +#define Y_MIN_PIN 35 +#define Z_MIN_PIN 15 // // Steppers // -#define X_STEP_PIN 128 -#define X_DIR_PIN 129 -#define X_ENABLE_PIN 130 -//#define X_CS_PIN 0 +#define X_STEP_PIN 128 +#define X_DIR_PIN 129 +#define X_ENABLE_PIN 130 +//#define X_CS_PIN 0 -#define Y_STEP_PIN 131 -#define Y_DIR_PIN 132 -#define Y_ENABLE_PIN 133 -//#define Y_CS_PIN 13 +#define Y_STEP_PIN 131 +#define Y_DIR_PIN 132 +#define Y_ENABLE_PIN 133 +//#define Y_CS_PIN 13 -#define Z_STEP_PIN 134 -#define Z_DIR_PIN 135 -#define Z_ENABLE_PIN 136 -//#define Z_CS_PIN 5 // SS_PIN +#define Z_STEP_PIN 134 +#define Z_DIR_PIN 135 +#define Z_ENABLE_PIN 136 +//#define Z_CS_PIN 5 // SS_PIN -#define E0_STEP_PIN 137 -#define E0_DIR_PIN 138 -#define E0_ENABLE_PIN 139 -//#define E0_CS_PIN 21 +#define E0_STEP_PIN 137 +#define E0_DIR_PIN 138 +#define E0_ENABLE_PIN 139 +//#define E0_CS_PIN 21 // // Temperature Sensors // -#define TEMP_0_PIN 36 // Analog Input -#define TEMP_BED_PIN 39 // Analog Input +#define TEMP_0_PIN 36 // Analog Input +#define TEMP_BED_PIN 39 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 2 -#define FAN_PIN 13 -#define HEATER_BED_PIN 4 +#define HEATER_0_PIN 2 +#define FAN_PIN 13 +#define HEATER_BED_PIN 4 // SPI -#define SDSS 5 +#define SDSS 5 diff --git a/Marlin/src/pins/esp32/pins_MRR_ESPA.h b/Marlin/src/pins/esp32/pins_MRR_ESPA.h index a93f0f05c4aa..0457b0afca53 100644 --- a/Marlin/src/pins/esp32/pins_MRR_ESPA.h +++ b/Marlin/src/pins/esp32/pins_MRR_ESPA.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -27,7 +27,7 @@ * Supports 4 stepper drivers, heated bed, single hotend. */ -#ifndef ARDUINO_ARCH_ESP32 +#if NOT_TARGET(ARDUINO_ARCH_ESP32) #error "Oops! Select an ESP32 board in 'Tools > Board.'" #elif EXTRUDERS > 1 || E_STEPPERS > 1 #error "MRR ESPA only supports one E Stepper. Comment out this line to continue." @@ -45,66 +45,66 @@ #ifdef I2S_STEPPER_STREAM #undef I2S_STEPPER_STREAM #endif -#define I2S_WS -1 -#define I2S_BCK -1 -#define I2S_DATA -1 +#define I2S_WS -1 +#define I2S_BCK -1 +#define I2S_DATA -1 // // Limit Switches // -#define X_STOP_PIN 34 -#define Y_STOP_PIN 35 -#define Z_STOP_PIN 15 +#define X_STOP_PIN 34 +#define Y_STOP_PIN 35 +#define Z_STOP_PIN 15 // // Steppers // -#define X_STEP_PIN 27 -#define X_DIR_PIN 26 -#define X_ENABLE_PIN 25 -//#define X_CS_PIN 21 +#define X_STEP_PIN 27 +#define X_DIR_PIN 26 +#define X_ENABLE_PIN 25 +//#define X_CS_PIN 21 -#define Y_STEP_PIN 33 -#define Y_DIR_PIN 32 -#define Y_ENABLE_PIN X_ENABLE_PIN -//#define Y_CS_PIN 22 +#define Y_STEP_PIN 33 +#define Y_DIR_PIN 32 +#define Y_ENABLE_PIN X_ENABLE_PIN +//#define Y_CS_PIN 22 -#define Z_STEP_PIN 14 -#define Z_DIR_PIN 12 -#define Z_ENABLE_PIN X_ENABLE_PIN -//#define Z_CS_PIN 5 // SS_PIN +#define Z_STEP_PIN 14 +#define Z_DIR_PIN 12 +#define Z_ENABLE_PIN X_ENABLE_PIN +//#define Z_CS_PIN 5 // SS_PIN -#define E0_STEP_PIN 16 -#define E0_DIR_PIN 17 -#define E0_ENABLE_PIN X_ENABLE_PIN -//#define E0_CS_PIN 21 +#define E0_STEP_PIN 16 +#define E0_DIR_PIN 17 +#define E0_ENABLE_PIN X_ENABLE_PIN +//#define E0_CS_PIN 21 // // Temperature Sensors // -#define TEMP_0_PIN 36 // Analog Input -#define TEMP_BED_PIN 39 // Analog Input +#define TEMP_0_PIN 36 // Analog Input +#define TEMP_BED_PIN 39 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 2 -#define FAN_PIN 13 -#define HEATER_BED_PIN 4 +#define HEATER_0_PIN 2 +#define FAN_PIN 13 +#define HEATER_BED_PIN 4 // // MicroSD card // -#define MOSI_PIN 23 -#define MISO_PIN 19 -#define SCK_PIN 18 -#define SDSS 5 -#define USES_SHARED_SPI // SPI is shared by SD card with TMC SPI drivers +#define MOSI_PIN 23 +#define MISO_PIN 19 +#define SCK_PIN 18 +#define SDSS 5 +#define USES_SHARED_SPI // SPI is shared by SD card with TMC SPI drivers // Hardware serial pins // Add the following to Configuration.h or Configuration_adv.h to assign // specific pins to hardware Serial1. // Note: Serial2 can be defined using HARDWARE_SERIAL2_RX and HARDWARE_SERIAL2_TX but // MRR ESPA does not have enough spare pins for such reassignment. -//#define HARDWARE_SERIAL1_RX 21 -//#define HARDWARE_SERIAL1_TX 22 +//#define HARDWARE_SERIAL1_RX 21 +//#define HARDWARE_SERIAL1_TX 22 diff --git a/Marlin/src/pins/esp32/pins_MRR_ESPE.h b/Marlin/src/pins/esp32/pins_MRR_ESPE.h index 0096027158e9..95f761f26ad9 100644 --- a/Marlin/src/pins/esp32/pins_MRR_ESPE.h +++ b/Marlin/src/pins/esp32/pins_MRR_ESPE.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -28,7 +28,7 @@ * single hotend, and LCD controller. */ -#ifndef ARDUINO_ARCH_ESP32 +#if NOT_TARGET(ARDUINO_ARCH_ESP32) #error "Oops! Select an ESP32 board in 'Tools > Board.'" #elif EXTRUDERS > 2 || E_STEPPERS > 2 #error "MRR ESPE only supports two E Steppers. Comment out this line to continue." @@ -43,9 +43,9 @@ // // Limit Switches // -#define X_STOP_PIN 35 -#define Y_STOP_PIN 32 -#define Z_STOP_PIN 33 +#define X_STOP_PIN 35 +#define Y_STOP_PIN 32 +#define Z_STOP_PIN 33 // // Enable I2S stepper stream @@ -53,94 +53,94 @@ #undef I2S_STEPPER_STREAM #define I2S_STEPPER_STREAM -#undef LIN_ADVANCE // Currently, I2S stream does not work with linear advance +#undef LIN_ADVANCE // Currently, I2S stream does not work with linear advance -#define I2S_WS 26 -#define I2S_BCK 25 -#define I2S_DATA 27 +#define I2S_WS 26 +#define I2S_BCK 25 +#define I2S_DATA 27 // // Steppers // -#define X_STEP_PIN 129 -#define X_DIR_PIN 130 -#define X_ENABLE_PIN 128 -//#define X_CS_PIN 21 - -#define Y_STEP_PIN 132 -#define Y_DIR_PIN 133 -#define Y_ENABLE_PIN 131 -//#define Y_CS_PIN 22 - -#define Z_STEP_PIN 135 -#define Z_DIR_PIN 136 -#define Z_ENABLE_PIN 134 -//#define Z_CS_PIN 5 // SS_PIN - -#define E0_STEP_PIN 138 -#define E0_DIR_PIN 139 -#define E0_ENABLE_PIN 137 -//#define E0_CS_PIN 21 - -#define E1_STEP_PIN 141 -#define E1_DIR_PIN 142 -#define E1_ENABLE_PIN 140 -//#define E1_CS_PIN 22 - -#define Z2_STEP_PIN 141 -#define Z2_DIR_PIN 142 -#define Z2_ENABLE_PIN 140 -//#define Z2_CS_PIN 5 +#define X_STEP_PIN 129 +#define X_DIR_PIN 130 +#define X_ENABLE_PIN 128 +//#define X_CS_PIN 21 + +#define Y_STEP_PIN 132 +#define Y_DIR_PIN 133 +#define Y_ENABLE_PIN 131 +//#define Y_CS_PIN 22 + +#define Z_STEP_PIN 135 +#define Z_DIR_PIN 136 +#define Z_ENABLE_PIN 134 +//#define Z_CS_PIN 5 // SS_PIN + +#define E0_STEP_PIN 138 +#define E0_DIR_PIN 139 +#define E0_ENABLE_PIN 137 +//#define E0_CS_PIN 21 + +#define E1_STEP_PIN 141 +#define E1_DIR_PIN 142 +#define E1_ENABLE_PIN 140 +//#define E1_CS_PIN 22 + +#define Z2_STEP_PIN 141 +#define Z2_DIR_PIN 142 +#define Z2_ENABLE_PIN 140 +//#define Z2_CS_PIN 5 // // Temperature Sensors // -#define TEMP_0_PIN 36 // Analog Input -#define TEMP_1_PIN 34 // Analog Input -#define TEMP_BED_PIN 39 // Analog Input +#define TEMP_0_PIN 36 // Analog Input +#define TEMP_1_PIN 34 // Analog Input +#define TEMP_BED_PIN 39 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 145 // 2 -#define FAN_PIN 146 // 15 -#define HEATER_BED_PIN 144 // 4 +#define HEATER_0_PIN 145 // 2 +#define FAN_PIN 146 // 15 +#define HEATER_BED_PIN 144 // 4 -#define CONTROLLER_FAN_PIN 147 -//#define E0_AUTO_FAN_PIN 148 // need to update Configuration_adv.h @section extruder -//#define E1_AUTO_FAN_PIN 149 // need to update Configuration_adv.h @section extruder -#define FAN1_PIN 149 +#define CONTROLLER_FAN_PIN 147 +//#define E0_AUTO_FAN_PIN 148 // need to update Configuration_adv.h @section extruder +//#define E1_AUTO_FAN_PIN 149 // need to update Configuration_adv.h @section extruder +#define FAN1_PIN 149 // // MicroSD card // -#define MOSI_PIN 23 -#define MISO_PIN 19 -#define SCK_PIN 18 -#define SDSS 5 -#define USES_SHARED_SPI // SPI is shared by SD card with TMC SPI drivers +#define MOSI_PIN 23 +#define MISO_PIN 19 +#define SCK_PIN 18 +#define SDSS 5 +#define USES_SHARED_SPI // SPI is shared by SD card with TMC SPI drivers ////////////////////////// // LCDs and Controllers // ////////////////////////// -#if HAS_GRAPHICAL_LCD +#if HAS_MARLINUI_U8GLIB - #define LCD_PINS_RS 13 - #define LCD_PINS_ENABLE 17 - #define LCD_PINS_D4 16 + #define LCD_PINS_RS 13 + #define LCD_PINS_ENABLE 17 + #define LCD_PINS_D4 16 #if ENABLED(CR10_STOCKDISPLAY) - #define BEEPER_PIN 151 + #define BEEPER_PIN 151 #elif ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) - #define BEEPER_PIN 151 + #define BEEPER_PIN 151 - //#define LCD_PINS_D5 150 - //#define LCD_PINS_D6 152 - //#define LCD_PINS_D7 153 + //#define LCD_PINS_D5 150 + //#define LCD_PINS_D6 152 + //#define LCD_PINS_D7 153 #else @@ -148,18 +148,18 @@ #endif - #define BTN_EN1 0 - #define BTN_EN2 12 - #define BTN_ENC 14 + #define BTN_EN1 0 + #define BTN_EN2 12 + #define BTN_ENC 14 -#endif // HAS_GRAPHICAL_LCD +#endif // HAS_MARLINUI_U8GLIB // Hardware serial pins // Add the following to Configuration.h or Configuration_adv.h to assign // specific pins to hardware Serial1 and Serial2. // Note: Serial2 can be defined using HARDWARE_SERIAL2_RX and HARDWARE_SERIAL2_TX but // MRR ESPA does not have enough spare pins for such reassignment. -//#define HARDWARE_SERIAL1_RX 21 -//#define HARDWARE_SERIAL1_TX 22 -//#define HARDWARE_SERIAL2_RX 2 -//#define HARDWARE_SERIAL2_TX 4 +//#define HARDWARE_SERIAL1_RX 21 +//#define HARDWARE_SERIAL1_TX 22 +//#define HARDWARE_SERIAL2_RX 2 +//#define HARDWARE_SERIAL2_TX 4 diff --git a/Marlin/src/pins/linux/pins_RAMPS_LINUX.h b/Marlin/src/pins/linux/pins_RAMPS_LINUX.h index d206547ab8ba..002d2ebd9c62 100644 --- a/Marlin/src/pins/linux/pins_RAMPS_LINUX.h +++ b/Marlin/src/pins/linux/pins_RAMPS_LINUX.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -49,7 +49,9 @@ #define BOARD_INFO_NAME "RAMPS 1.4" #endif -#define E2END 0xFFF // 4KB +#ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE 0x1000 // 4KB +#endif #define IS_RAMPS_EFB @@ -57,92 +59,92 @@ // Servos // #ifdef IS_RAMPS_13 - #define SERVO0_PIN 7 // RAMPS_13 // Will conflict with BTN_EN2 on LCD_I2C_VIKI + #define SERVO0_PIN 7 // RAMPS_13 // Will conflict with BTN_EN2 on LCD_I2C_VIKI #else - #define SERVO0_PIN 11 + #define SERVO0_PIN 11 #endif -#define SERVO1_PIN 6 -#define SERVO2_PIN 5 +#define SERVO1_PIN 6 +#define SERVO2_PIN 5 #ifndef SERVO3_PIN - #define SERVO3_PIN 4 + #define SERVO3_PIN 4 #endif // // Limit Switches // -#define X_MIN_PIN 3 +#define X_MIN_PIN 3 #ifndef X_MAX_PIN - #define X_MAX_PIN 2 + #define X_MAX_PIN 2 #endif -#define Y_MIN_PIN 14 -#define Y_MAX_PIN 15 -#define Z_MIN_PIN 18 -#define Z_MAX_PIN 19 +#define Y_MIN_PIN 14 +#define Y_MAX_PIN 15 +#define Z_MIN_PIN 18 +#define Z_MAX_PIN 19 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 32 + #define Z_MIN_PROBE_PIN 32 #endif // // Steppers // -#define X_STEP_PIN 54 -#define X_DIR_PIN 55 -#define X_ENABLE_PIN 38 +#define X_STEP_PIN 54 +#define X_DIR_PIN 55 +#define X_ENABLE_PIN 38 #ifndef X_CS_PIN - #define X_CS_PIN 53 + #define X_CS_PIN 53 #endif -#define Y_STEP_PIN 60 -#define Y_DIR_PIN 61 -#define Y_ENABLE_PIN 56 +#define Y_STEP_PIN 60 +#define Y_DIR_PIN 61 +#define Y_ENABLE_PIN 56 #ifndef Y_CS_PIN - #define Y_CS_PIN 49 + #define Y_CS_PIN 49 #endif -#define Z_STEP_PIN 46 -#define Z_DIR_PIN 48 -#define Z_ENABLE_PIN 62 +#define Z_STEP_PIN 46 +#define Z_DIR_PIN 48 +#define Z_ENABLE_PIN 62 #ifndef Z_CS_PIN - #define Z_CS_PIN 40 + #define Z_CS_PIN 40 #endif -#define E0_STEP_PIN 26 -#define E0_DIR_PIN 28 -#define E0_ENABLE_PIN 24 +#define E0_STEP_PIN 26 +#define E0_DIR_PIN 28 +#define E0_ENABLE_PIN 24 #ifndef E0_CS_PIN - #define E0_CS_PIN 42 + #define E0_CS_PIN 42 #endif -#define E1_STEP_PIN 36 -#define E1_DIR_PIN 34 -#define E1_ENABLE_PIN 30 +#define E1_STEP_PIN 36 +#define E1_DIR_PIN 34 +#define E1_ENABLE_PIN 30 #ifndef E1_CS_PIN - #define E1_CS_PIN 44 + #define E1_CS_PIN 44 #endif // // Temperature Sensors // -#define TEMP_0_PIN 0 // Analog Input -#define TEMP_1_PIN 1 // Analog Input -#define TEMP_BED_PIN 2 // Analog Input +#define TEMP_0_PIN 0 // Analog Input +#define TEMP_1_PIN 1 // Analog Input +#define TEMP_BED_PIN 2 // Analog Input // SPI for Max6675 or Max31855 Thermocouple #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 66 // Don't use 53 if using Display/SD card + #define MAX6675_SS_PIN 66 // Don't use 53 if using Display/SD card #else - #define MAX6675_SS_PIN 66 // Don't use 49 (SD_DETECT_PIN) + #define MAX6675_SS_PIN 66 // Don't use 49 (SD_DETECT_PIN) #endif // // Augmentation for auto-assigning RAMPS plugs // #if NONE(IS_RAMPS_EEB, IS_RAMPS_EEF, IS_RAMPS_EFB, IS_RAMPS_EFF, IS_RAMPS_SF) && !PIN_EXISTS(MOSFET_D) - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND #if TEMP_SENSOR_BED #define IS_RAMPS_EEB #else @@ -159,72 +161,72 @@ // Heaters / Fans // #ifndef MOSFET_D_PIN - #define MOSFET_D_PIN -1 + #define MOSFET_D_PIN -1 #endif #ifndef RAMPS_D8_PIN - #define RAMPS_D8_PIN 8 + #define RAMPS_D8_PIN 8 #endif #ifndef RAMPS_D9_PIN - #define RAMPS_D9_PIN 9 + #define RAMPS_D9_PIN 9 #endif #ifndef RAMPS_D10_PIN - #define RAMPS_D10_PIN 10 + #define RAMPS_D10_PIN 10 #endif -#define HEATER_0_PIN RAMPS_D10_PIN - -#if ENABLED(IS_RAMPS_EFB) // Hotend, Fan, Bed - #define FAN_PIN RAMPS_D9_PIN - #define HEATER_BED_PIN RAMPS_D8_PIN -#elif ENABLED(IS_RAMPS_EEF) // Hotend, Hotend, Fan - #define HEATER_1_PIN RAMPS_D9_PIN - #define FAN_PIN RAMPS_D8_PIN -#elif ENABLED(IS_RAMPS_EEB) // Hotend, Hotend, Bed - #define HEATER_1_PIN RAMPS_D9_PIN - #define HEATER_BED_PIN RAMPS_D8_PIN -#elif ENABLED(IS_RAMPS_EFF) // Hotend, Fan, Fan - #define FAN_PIN RAMPS_D9_PIN - #define FAN1_PIN RAMPS_D8_PIN -#elif ENABLED(IS_RAMPS_SF) // Spindle, Fan - #define FAN_PIN RAMPS_D8_PIN -#else // Non-specific are "EFB" (i.e., "EFBF" or "EFBE") - #define FAN_PIN RAMPS_D9_PIN - #define HEATER_BED_PIN RAMPS_D8_PIN +#define HEATER_0_PIN RAMPS_D10_PIN + +#if ENABLED(IS_RAMPS_EFB) // Hotend, Fan, Bed + #define FAN_PIN RAMPS_D9_PIN + #define HEATER_BED_PIN RAMPS_D8_PIN +#elif ENABLED(IS_RAMPS_EEF) // Hotend, Hotend, Fan + #define HEATER_1_PIN RAMPS_D9_PIN + #define FAN_PIN RAMPS_D8_PIN +#elif ENABLED(IS_RAMPS_EEB) // Hotend, Hotend, Bed + #define HEATER_1_PIN RAMPS_D9_PIN + #define HEATER_BED_PIN RAMPS_D8_PIN +#elif ENABLED(IS_RAMPS_EFF) // Hotend, Fan, Fan + #define FAN_PIN RAMPS_D9_PIN + #define FAN1_PIN RAMPS_D8_PIN +#elif ENABLED(IS_RAMPS_SF) // Spindle, Fan + #define FAN_PIN RAMPS_D8_PIN +#else // Non-specific are "EFB" (i.e., "EFBF" or "EFBE") + #define FAN_PIN RAMPS_D9_PIN + #define HEATER_BED_PIN RAMPS_D8_PIN #if HOTENDS == 1 - #define FAN1_PIN MOSFET_D_PIN + #define FAN1_PIN MOSFET_D_PIN #else - #define HEATER_1_PIN MOSFET_D_PIN + #define HEATER_1_PIN MOSFET_D_PIN #endif #endif #ifndef FAN_PIN - #define FAN_PIN 4 // IO pin. Buffer needed + #define FAN_PIN 4 // IO pin. Buffer needed #endif // // Misc. Functions // -#define SDSS 53 -#define LED_PIN 13 +#define SDSS 53 +#define LED_PIN 13 #ifndef FILWIDTH_PIN - #define FILWIDTH_PIN 5 // Analog Input on AUX2 + #define FILWIDTH_PIN 5 // Analog Input on AUX2 #endif // define digital pin 4 for the filament runout sensor. Use the RAMPS 1.4 digital input 4 on the servos connector #ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN 4 + #define FIL_RUNOUT_PIN 4 #endif #ifndef PS_ON_PIN - #define PS_ON_PIN 12 + #define PS_ON_PIN 12 #endif #if ENABLED(CASE_LIGHT_ENABLE) && !defined(CASE_LIGHT_PIN) && !defined(SPINDLE_LASER_ENA_PIN) - #if NUM_SERVOS <= 1 // Prefer the servo connector - #define CASE_LIGHT_PIN 6 // Hardware PWM - #elif HAS_FREE_AUX2_PINS // try to use AUX 2 - #define CASE_LIGHT_PIN 44 // Hardware PWM + #if NUM_SERVOS <= 1 // Prefer the servo connector + #define CASE_LIGHT_PIN 6 // Hardware PWM + #elif HAS_FREE_AUX2_PINS // try to use AUX 2 + #define CASE_LIGHT_PIN 44 // Hardware PWM #endif #endif @@ -232,14 +234,14 @@ // M3/M4/M5 - Spindle/Laser Control // #if HAS_CUTTER && !PIN_EXISTS(SPINDLE_LASER_ENA) - #if !defined(NUM_SERVOS) || NUM_SERVOS == 0 // Prefer the servo connector - #define SPINDLE_LASER_ENA_PIN 4 // Pullup or pulldown! - #define SPINDLE_LASER_PWM_PIN 6 // Hardware PWM - #define SPINDLE_DIR_PIN 5 - #elif HAS_FREE_AUX2_PINS // try to use AUX 2 - #define SPINDLE_LASER_ENA_PIN 40 // Pullup or pulldown! - #define SPINDLE_LASER_PWM_PIN 44 // Hardware PWM - #define SPINDLE_DIR_PIN 65 + #if !defined(NUM_SERVOS) || NUM_SERVOS == 0 // Prefer the servo connector + #define SPINDLE_LASER_ENA_PIN 4 // Pullup or pulldown! + #define SPINDLE_LASER_PWM_PIN 6 // Hardware PWM + #define SPINDLE_DIR_PIN 5 + #elif HAS_FREE_AUX2_PINS // try to use AUX 2 + #define SPINDLE_LASER_ENA_PIN 40 // Pullup or pulldown! + #define SPINDLE_LASER_PWM_PIN 44 // Hardware PWM + #define SPINDLE_DIR_PIN 65 #endif #endif @@ -247,13 +249,13 @@ // Průša i3 MK2 Multiplexer Support // #ifndef E_MUX0_PIN - #define E_MUX0_PIN 40 // Z_CS_PIN + #define E_MUX0_PIN 40 // Z_CS_PIN #endif #ifndef E_MUX1_PIN - #define E_MUX1_PIN 42 // E0_CS_PIN + #define E_MUX1_PIN 42 // E0_CS_PIN #endif #ifndef E_MUX2_PIN - #define E_MUX2_PIN 44 // E1_CS_PIN + #define E_MUX2_PIN 44 // E1_CS_PIN #endif /** @@ -261,17 +263,17 @@ */ #if ENABLED(TMC_USE_SW_SPI) #ifndef TMC_SW_MOSI - #define TMC_SW_MOSI 66 + #define TMC_SW_MOSI 66 #endif #ifndef TMC_SW_MISO - #define TMC_SW_MISO 44 + #define TMC_SW_MISO 44 #endif #ifndef TMC_SW_SCK - #define TMC_SW_SCK 64 + #define TMC_SW_SCK 64 #endif #endif -#if HAS_TMC220x +#if HAS_TMC_UART /** * TMC2208/TMC2209 stepper drivers * @@ -295,91 +297,91 @@ */ #ifndef X_SERIAL_TX_PIN - #define X_SERIAL_TX_PIN 40 + #define X_SERIAL_TX_PIN 40 #endif #ifndef X_SERIAL_RX_PIN - #define X_SERIAL_RX_PIN 63 + #define X_SERIAL_RX_PIN 63 #endif #ifndef X2_SERIAL_TX_PIN - #define X2_SERIAL_TX_PIN -1 + #define X2_SERIAL_TX_PIN -1 #endif #ifndef X2_SERIAL_RX_PIN - #define X2_SERIAL_RX_PIN -1 + #define X2_SERIAL_RX_PIN -1 #endif #ifndef Y_SERIAL_TX_PIN - #define Y_SERIAL_TX_PIN 59 + #define Y_SERIAL_TX_PIN 59 #endif #ifndef Y_SERIAL_RX_PIN - #define Y_SERIAL_RX_PIN 64 + #define Y_SERIAL_RX_PIN 64 #endif #ifndef Y2_SERIAL_TX_PIN - #define Y2_SERIAL_TX_PIN -1 + #define Y2_SERIAL_TX_PIN -1 #endif #ifndef Y2_SERIAL_RX_PIN - #define Y2_SERIAL_RX_PIN -1 + #define Y2_SERIAL_RX_PIN -1 #endif #ifndef Z_SERIAL_TX_PIN - #define Z_SERIAL_TX_PIN 42 + #define Z_SERIAL_TX_PIN 42 #endif #ifndef Z_SERIAL_RX_PIN - #define Z_SERIAL_RX_PIN 65 + #define Z_SERIAL_RX_PIN 65 #endif #ifndef Z2_SERIAL_TX_PIN - #define Z2_SERIAL_TX_PIN -1 + #define Z2_SERIAL_TX_PIN -1 #endif #ifndef Z2_SERIAL_RX_PIN - #define Z2_SERIAL_RX_PIN -1 + #define Z2_SERIAL_RX_PIN -1 #endif #ifndef E0_SERIAL_TX_PIN - #define E0_SERIAL_TX_PIN 44 + #define E0_SERIAL_TX_PIN 44 #endif #ifndef E0_SERIAL_RX_PIN - #define E0_SERIAL_RX_PIN 66 + #define E0_SERIAL_RX_PIN 66 #endif #ifndef E1_SERIAL_TX_PIN - #define E1_SERIAL_TX_PIN -1 + #define E1_SERIAL_TX_PIN -1 #endif #ifndef E1_SERIAL_RX_PIN - #define E1_SERIAL_RX_PIN -1 + #define E1_SERIAL_RX_PIN -1 #endif #ifndef E2_SERIAL_TX_PIN - #define E2_SERIAL_TX_PIN -1 + #define E2_SERIAL_TX_PIN -1 #endif #ifndef E2_SERIAL_RX_PIN - #define E2_SERIAL_RX_PIN -1 + #define E2_SERIAL_RX_PIN -1 #endif #ifndef E3_SERIAL_TX_PIN - #define E3_SERIAL_TX_PIN -1 + #define E3_SERIAL_TX_PIN -1 #endif #ifndef E3_SERIAL_RX_PIN - #define E3_SERIAL_RX_PIN -1 + #define E3_SERIAL_RX_PIN -1 #endif #ifndef E4_SERIAL_TX_PIN - #define E4_SERIAL_TX_PIN -1 + #define E4_SERIAL_TX_PIN -1 #endif #ifndef E4_SERIAL_RX_PIN - #define E4_SERIAL_RX_PIN -1 + #define E4_SERIAL_RX_PIN -1 #endif #ifndef E5_SERIAL_TX_PIN - #define E5_SERIAL_TX_PIN -1 + #define E5_SERIAL_TX_PIN -1 #endif #ifndef E5_SERIAL_RX_PIN - #define E5_SERIAL_RX_PIN -1 + #define E5_SERIAL_RX_PIN -1 #endif #ifndef E6_SERIAL_TX_PIN - #define E6_SERIAL_TX_PIN -1 + #define E6_SERIAL_TX_PIN -1 #endif #ifndef E6_SERIAL_RX_PIN - #define E6_SERIAL_RX_PIN -1 + #define E6_SERIAL_RX_PIN -1 #endif #ifndef E7_SERIAL_TX_PIN - #define E7_SERIAL_TX_PIN -1 + #define E7_SERIAL_TX_PIN -1 #endif #ifndef E7_SERIAL_RX_PIN - #define E7_SERIAL_RX_PIN -1 + #define E7_SERIAL_RX_PIN -1 #endif #endif @@ -387,69 +389,69 @@ // LCDs and Controllers // ////////////////////////// -#if HAS_SPI_LCD +#if HAS_WIRED_LCD // // LCD Display output pins // #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) - #define LCD_PINS_RS 49 // CS chip select /SS chip slave select - #define LCD_PINS_ENABLE 51 // SID (MOSI) - #define LCD_PINS_D4 52 // SCK (CLK) clock + #define LCD_PINS_RS 49 // CS chip select /SS chip slave select + #define LCD_PINS_ENABLE 51 // SID (MOSI) + #define LCD_PINS_D4 52 // SCK (CLK) clock #elif BOTH(NEWPANEL, PANEL_ONE) - #define LCD_PINS_RS 40 - #define LCD_PINS_ENABLE 42 - #define LCD_PINS_D4 65 - #define LCD_PINS_D5 66 - #define LCD_PINS_D6 44 - #define LCD_PINS_D7 64 + #define LCD_PINS_RS 40 + #define LCD_PINS_ENABLE 42 + #define LCD_PINS_D4 65 + #define LCD_PINS_D5 66 + #define LCD_PINS_D6 44 + #define LCD_PINS_D7 64 #else #if ENABLED(CR10_STOCKDISPLAY) - #define LCD_PINS_RS 27 - #define LCD_PINS_ENABLE 29 - #define LCD_PINS_D4 25 + #define LCD_PINS_RS 27 + #define LCD_PINS_ENABLE 29 + #define LCD_PINS_D4 25 #if DISABLED(NEWPANEL) - #define BEEPER_PIN 37 + #define BEEPER_PIN 37 #endif #elif ENABLED(ZONESTAR_LCD) - #define LCD_PINS_RS 64 - #define LCD_PINS_ENABLE 44 - #define LCD_PINS_D4 63 - #define LCD_PINS_D5 40 - #define LCD_PINS_D6 42 - #define LCD_PINS_D7 65 + #define LCD_PINS_RS 64 + #define LCD_PINS_ENABLE 44 + #define LCD_PINS_D4 63 + #define LCD_PINS_D5 40 + #define LCD_PINS_D6 42 + #define LCD_PINS_D7 65 #else #if EITHER(MKS_12864OLED, MKS_12864OLED_SSD1306) - #define LCD_PINS_DC 25 // Set as output on init - #define LCD_PINS_RS 27 // Pull low for 1s to init + #define LCD_PINS_DC 25 // Set as output on init + #define LCD_PINS_RS 27 // Pull low for 1s to init // DOGM SPI LCD Support - #define DOGLCD_CS 16 - #define DOGLCD_MOSI 17 - #define DOGLCD_SCK 23 - #define DOGLCD_A0 LCD_PINS_DC + #define DOGLCD_CS 16 + #define DOGLCD_MOSI 17 + #define DOGLCD_SCK 23 + #define DOGLCD_A0 LCD_PINS_DC #else - #define LCD_PINS_RS 16 - #define LCD_PINS_ENABLE 17 - #define LCD_PINS_D4 23 - #define LCD_PINS_D5 25 - #define LCD_PINS_D6 27 + #define LCD_PINS_RS 16 + #define LCD_PINS_ENABLE 17 + #define LCD_PINS_D4 23 + #define LCD_PINS_D5 25 + #define LCD_PINS_D6 27 #endif - #define LCD_PINS_D7 29 + #define LCD_PINS_D7 29 #if DISABLED(NEWPANEL) - #define BEEPER_PIN 33 + #define BEEPER_PIN 33 #endif #endif @@ -457,10 +459,10 @@ #if DISABLED(NEWPANEL) // Buttons attached to a shift register // Not wired yet - //#define SHIFT_CLK 38 - //#define SHIFT_LD 42 - //#define SHIFT_OUT 40 - //#define SHIFT_EN 17 + //#define SHIFT_CLK 38 + //#define SHIFT_LD 42 + //#define SHIFT_OUT 40 + //#define SHIFT_EN 17 #endif #endif @@ -472,85 +474,85 @@ #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) - #define BEEPER_PIN 37 + #define BEEPER_PIN 37 #if ENABLED(CR10_STOCKDISPLAY) - #define BTN_EN1 17 - #define BTN_EN2 23 + #define BTN_EN1 17 + #define BTN_EN2 23 #else - #define BTN_EN1 31 - #define BTN_EN2 33 + #define BTN_EN1 31 + #define BTN_EN2 33 #endif - #define BTN_ENC 35 - #define SD_DETECT_PIN 49 - #define KILL_PIN 41 + #define BTN_ENC 35 + #define SD_DETECT_PIN 49 + #define KILL_PIN 41 #if ENABLED(BQ_LCD_SMART_CONTROLLER) - #define LCD_BACKLIGHT_PIN 39 + #define LCD_BACKLIGHT_PIN 39 #endif #elif ENABLED(REPRAPWORLD_GRAPHICAL_LCD) - #define BTN_EN1 64 - #define BTN_EN2 59 - #define BTN_ENC 63 - #define SD_DETECT_PIN 42 + #define BTN_EN1 64 + #define BTN_EN2 59 + #define BTN_ENC 63 + #define SD_DETECT_PIN 42 #elif ENABLED(LCD_I2C_PANELOLU2) - #define BTN_EN1 47 - #define BTN_EN2 43 - #define BTN_ENC 32 - #define LCD_SDSS SDSS - #define KILL_PIN 41 + #define BTN_EN1 47 + #define BTN_EN2 43 + #define BTN_ENC 32 + #define LCD_SDSS SDSS + #define KILL_PIN 41 #elif ENABLED(LCD_I2C_VIKI) - #define BTN_EN1 22 // http://files.panucatt.com/datasheets/viki_wiring_diagram.pdf explains 40/42. - #define BTN_EN2 7 // 22/7 are unused on RAMPS_14. 22 is unused and 7 the SERVO0_PIN on RAMPS_13. - #define BTN_ENC -1 + #define BTN_EN1 22 // https://files.panucatt.com/datasheets/viki_wiring_diagram.pdf explains 40/42. + #define BTN_EN2 7 // 22/7 are unused on RAMPS_14. 22 is unused and 7 the SERVO0_PIN on RAMPS_13. + #define BTN_ENC -1 - #define LCD_SDSS SDSS - #define SD_DETECT_PIN 49 + #define LCD_SDSS SDSS + #define SD_DETECT_PIN 49 #elif ANY(VIKI2, miniVIKI) - #define DOGLCD_CS 45 - #define DOGLCD_A0 44 + #define DOGLCD_CS 45 + #define DOGLCD_A0 44 #define LCD_SCREEN_ROT_180 - #define BEEPER_PIN 33 - #define STAT_LED_RED_PIN 32 - #define STAT_LED_BLUE_PIN 35 + #define BEEPER_PIN 33 + #define STAT_LED_RED_PIN 32 + #define STAT_LED_BLUE_PIN 35 - #define BTN_EN1 22 - #define BTN_EN2 7 - #define BTN_ENC 39 + #define BTN_EN1 22 + #define BTN_EN2 7 + #define BTN_ENC 39 - #define SD_DETECT_PIN -1 // Pin 49 for display sd interface, 72 for easy adapter board - #define KILL_PIN 31 + #define SD_DETECT_PIN -1 // Pin 49 for display sd interface, 72 for easy adapter board + #define KILL_PIN 31 #elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) - #define DOGLCD_CS 29 - #define DOGLCD_A0 27 + #define DOGLCD_CS 29 + #define DOGLCD_A0 27 - #define BEEPER_PIN 23 - #define LCD_BACKLIGHT_PIN 33 + #define BEEPER_PIN 23 + #define LCD_BACKLIGHT_PIN 33 - #define BTN_EN1 35 - #define BTN_EN2 37 - #define BTN_ENC 31 + #define BTN_EN1 35 + #define BTN_EN2 37 + #define BTN_ENC 31 - #define LCD_SDSS SDSS - #define SD_DETECT_PIN 49 - #define KILL_PIN 41 + #define LCD_SDSS SDSS + #define SD_DETECT_PIN 49 + #define KILL_PIN 41 #elif ENABLED(MKS_MINI_12864) - #define DOGLCD_A0 27 - #define DOGLCD_CS 25 + #define DOGLCD_A0 27 + #define DOGLCD_CS 25 // GLCD features // Uncomment screen orientation @@ -558,25 +560,25 @@ //#define LCD_SCREEN_ROT_180 //#define LCD_SCREEN_ROT_270 - #define BEEPER_PIN 37 + #define BEEPER_PIN 37 // not connected to a pin - #define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65 + #define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65 - #define BTN_EN1 31 - #define BTN_EN2 33 - #define BTN_ENC 35 + #define BTN_EN1 31 + #define BTN_EN2 33 + #define BTN_ENC 35 - #define SD_DETECT_PIN 49 - #define KILL_PIN 64 + #define SD_DETECT_PIN 49 + #define KILL_PIN 64 #elif ENABLED(MINIPANEL) - #define BEEPER_PIN 42 + #define BEEPER_PIN 42 // not connected to a pin - #define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65 + #define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65 - #define DOGLCD_A0 44 - #define DOGLCD_CS 66 + #define DOGLCD_A0 44 + #define DOGLCD_CS 66 // GLCD features // Uncomment screen orientation @@ -584,16 +586,16 @@ //#define LCD_SCREEN_ROT_180 //#define LCD_SCREEN_ROT_270 - #define BTN_EN1 40 - #define BTN_EN2 63 - #define BTN_ENC 59 + #define BTN_EN1 40 + #define BTN_EN2 63 + #define BTN_ENC 59 - #define SD_DETECT_PIN 49 - #define KILL_PIN 64 + #define SD_DETECT_PIN 49 + #define KILL_PIN 64 #elif ENABLED(ZONESTAR_LCD) - #define ADC_KEYPAD_PIN 12 + #define ADC_KEYPAD_PIN 12 #elif ENABLED(AZSMZ_12864) @@ -602,32 +604,32 @@ #else // Beeper on AUX-4 - #define BEEPER_PIN 33 + #define BEEPER_PIN 33 // Buttons are directly attached to AUX-2 #if ENABLED(REPRAPWORLD_KEYPAD) - #define SHIFT_OUT 40 - #define SHIFT_CLK 44 - #define SHIFT_LD 42 - #define BTN_EN1 64 - #define BTN_EN2 59 - #define BTN_ENC 63 + #define SHIFT_OUT 40 + #define SHIFT_CLK 44 + #define SHIFT_LD 42 + #define BTN_EN1 64 + #define BTN_EN2 59 + #define BTN_ENC 63 #elif ENABLED(PANEL_ONE) - #define BTN_EN1 59 // AUX2 PIN 3 - #define BTN_EN2 63 // AUX2 PIN 4 - #define BTN_ENC 49 // AUX3 PIN 7 + #define BTN_EN1 59 // AUX2 PIN 3 + #define BTN_EN2 63 // AUX2 PIN 4 + #define BTN_ENC 49 // AUX3 PIN 7 #else - #define BTN_EN1 37 - #define BTN_EN2 35 - #define BTN_ENC 31 + #define BTN_EN1 37 + #define BTN_EN2 35 + #define BTN_ENC 31 #endif #if ENABLED(G3D_PANEL) - #define SD_DETECT_PIN 49 - #define KILL_PIN 41 + #define SD_DETECT_PIN 49 + #define KILL_PIN 41 #endif #endif #endif // NEWPANEL -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD diff --git a/Marlin/src/pins/lpc1768/pins_AZSMZ_MINI.h b/Marlin/src/pins/lpc1768/pins_AZSMZ_MINI.h index 1f02f9299e35..78e742667497 100644 --- a/Marlin/src/pins/lpc1768/pins_AZSMZ_MINI.h +++ b/Marlin/src/pins/lpc1768/pins_AZSMZ_MINI.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * AZSMZ MINI pin assignments */ -#ifndef MCU_LPC1768 +#if NOT_TARGET(MCU_LPC1768) #error "Oops! Make sure you have the LPC1768 environment selected in your IDE." #endif @@ -34,84 +34,84 @@ // // Servos // -#define SERVO0_PIN P1_23 +#define SERVO0_PIN P1_23 // // Limit Switches // -#define X_MIN_PIN P1_24 -#define Y_MIN_PIN P1_26 -#define Z_MIN_PIN P1_28 -#define Z_MAX_PIN P1_29 +#define X_MIN_PIN P1_24 +#define Y_MIN_PIN P1_26 +#define Z_MIN_PIN P1_28 +#define Z_MAX_PIN P1_29 // // Steppers // -#define X_STEP_PIN P2_00 -#define X_DIR_PIN P0_05 -#define X_ENABLE_PIN P0_04 +#define X_STEP_PIN P2_00 +#define X_DIR_PIN P0_05 +#define X_ENABLE_PIN P0_04 -#define Y_STEP_PIN P2_01 -#define Y_DIR_PIN P0_11 -#define Y_ENABLE_PIN P0_10 +#define Y_STEP_PIN P2_01 +#define Y_DIR_PIN P0_11 +#define Y_ENABLE_PIN P0_10 -#define Z_STEP_PIN P2_02 -#define Z_DIR_PIN P0_20 -#define Z_ENABLE_PIN P0_19 +#define Z_STEP_PIN P2_02 +#define Z_DIR_PIN P0_20 +#define Z_ENABLE_PIN P0_19 -#define E0_STEP_PIN P2_03 -#define E0_DIR_PIN P0_22 -#define E0_ENABLE_PIN P0_21 +#define E0_STEP_PIN P2_03 +#define E0_DIR_PIN P0_22 +#define E0_ENABLE_PIN P0_21 -#define E1_STEP_PIN P2_08 -#define E1_DIR_PIN P2_13 -#define E1_ENABLE_PIN P4_29 +#define E1_STEP_PIN P2_08 +#define E1_DIR_PIN P2_13 +#define E1_ENABLE_PIN P4_29 // // Temperature Sensors // 3.3V max when defined as an analog input // -#define TEMP_0_PIN P0_23_A0 // A0 (TH1) -#define TEMP_BED_PIN P0_24_A1 // A1 (TH2) -#define TEMP_1_PIN P0_25_A2 // A2 (TH3) +#define TEMP_0_PIN P0_23_A0 // A0 (TH1) +#define TEMP_BED_PIN P0_24_A1 // A1 (TH2) +#define TEMP_1_PIN P0_25_A2 // A2 (TH3) // // Heaters / Fans // // EFB -#define HEATER_0_PIN P2_04 -#define HEATER_BED_PIN P2_05 +#define HEATER_0_PIN P2_04 +#define HEATER_BED_PIN P2_05 #ifndef FAN_PIN - #define FAN_PIN P2_07 + #define FAN_PIN P2_07 #endif -#define FAN1_PIN P0_26 +#define FAN1_PIN P0_26 -#define LCD_SDSS P0_16 // LCD SD chip select -#define ONBOARD_SD_CS_PIN P0_06 // Chip select for "System" SD card +#define LCD_SDSS P0_16 // LCD SD chip select +#define ONBOARD_SD_CS_PIN P0_06 // Chip select for "System" SD card #if ENABLED(AZSMZ_12864) - #define BEEPER_PIN P1_30 - #define DOGLCD_A0 P2_06 - #define DOGLCD_CS P1_22 - #define BTN_EN1 P4_28 - #define BTN_EN2 P1_27 - #define BTN_ENC P3_26 + #define BEEPER_PIN P1_30 + #define DOGLCD_A0 P2_06 + #define DOGLCD_CS P1_22 + #define BTN_EN1 P4_28 + #define BTN_EN2 P1_27 + #define BTN_ENC P3_26 #ifndef SDCARD_CONNECTION - #define SDCARD_CONNECTION LCD + #define SDCARD_CONNECTION LCD #endif #endif #if SD_CONNECTION_IS(LCD) - #define SCK_PIN P0_15 - #define MISO_PIN P0_17 - #define MOSI_PIN P0_18 - #define SS_PIN LCD_SDSS - #define SD_DETECT_PIN P3_25 + #define SCK_PIN P0_15 + #define MISO_PIN P0_17 + #define MOSI_PIN P0_18 + #define SS_PIN LCD_SDSS + #define SD_DETECT_PIN P3_25 #elif SD_CONNECTION_IS(ONBOARD) - #define SCK_PIN P0_07 - #define MISO_PIN P0_08 - #define MOSI_PIN P0_09 - #define SS_PIN ONBOARD_SD_CS_PIN + #define SCK_PIN P0_07 + #define MISO_PIN P0_08 + #define MOSI_PIN P0_09 + #define SS_PIN ONBOARD_SD_CS_PIN #elif SD_CONNECTION_IS(CUSTOM_CABLE) #error "No custom SD drive cable defined for this board." #endif @@ -119,16 +119,16 @@ // // Ethernet pins // -#define ENET_MDIO P1_17 -#define ENET_RX_ER P1_14 -#define ENET_RXD1 P1_10 -#define ENET_MOC P1_16 -#define REF_CLK P1_15 -#define ENET_RXD0 P1_09 -#define ENET_CRS P1_08 -#define ENET_TX_EN P1_04 -#define ENET_TXD0 P1_00 -#define ENET_TXD1 P1_01 +#define ENET_MDIO P1_17 +#define ENET_RX_ER P1_14 +#define ENET_RXD1 P1_10 +#define ENET_MOC P1_16 +#define REF_CLK P1_15 +#define ENET_RXD0 P1_09 +#define ENET_CRS P1_08 +#define ENET_TX_EN P1_04 +#define ENET_TXD0 P1_00 +#define ENET_TXD1 P1_01 /** * PWMs diff --git a/Marlin/src/pins/lpc1768/pins_BIQU_B300_V1.0.h b/Marlin/src/pins/lpc1768/pins_BIQU_B300_V1.0.h index 4ff4ebc73bde..df182049f994 100644 --- a/Marlin/src/pins/lpc1768/pins_BIQU_B300_V1.0.h +++ b/Marlin/src/pins/lpc1768/pins_BIQU_B300_V1.0.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -27,10 +27,9 @@ * Applies to the following boards: * * BOARD_BIQU_BQ111_A4 (Hotend, Fan, Bed) - * */ -#ifndef MCU_LPC1768 +#if NOT_TARGET(MCU_LPC1768) #error "Oops! Make sure you have the LPC1768 environment selected in your IDE." #endif @@ -41,42 +40,42 @@ // // Limit Switches // -#define X_MIN_PIN P1_24 // 10k pullup to 3.3V, 1K series -#define X_MAX_PIN P1_25 // 10k pullup to 3.3V, 1K series -#define Y_MIN_PIN P1_26 // 10k pullup to 3.3V, 1K series -#define Y_MAX_PIN P1_27 // 10k pullup to 3.3V, 1K series -#define Z_MIN_PIN P1_28 // 10k pullup to 3.3V, 1K series -#define Z_MAX_PIN P1_29 // 10k pullup to 3.3V, 1K series +#define X_MIN_PIN P1_24 // 10k pullup to 3.3V, 1K series +#define X_MAX_PIN P1_25 // 10k pullup to 3.3V, 1K series +#define Y_MIN_PIN P1_26 // 10k pullup to 3.3V, 1K series +#define Y_MAX_PIN P1_27 // 10k pullup to 3.3V, 1K series +#define Z_MIN_PIN P1_28 // 10k pullup to 3.3V, 1K series +#define Z_MAX_PIN P1_29 // 10k pullup to 3.3V, 1K series // // Steppers // -#define X_STEP_PIN P2_00 -#define X_DIR_PIN P0_05 -#define X_ENABLE_PIN P0_04 +#define X_STEP_PIN P2_00 +#define X_DIR_PIN P0_05 +#define X_ENABLE_PIN P0_04 #ifndef X_CS_PIN - #define X_CS_PIN P1_15 // ETH + #define X_CS_PIN P1_15 // ETH #endif -#define Y_STEP_PIN P2_01 -#define Y_DIR_PIN P0_11 -#define Y_ENABLE_PIN P0_10 +#define Y_STEP_PIN P2_01 +#define Y_DIR_PIN P0_11 +#define Y_ENABLE_PIN P0_10 #ifndef Y_CS_PIN - #define Y_CS_PIN P1_14 // ETH + #define Y_CS_PIN P1_14 // ETH #endif -#define Z_STEP_PIN P2_02 -#define Z_DIR_PIN P0_20 -#define Z_ENABLE_PIN P0_19 +#define Z_STEP_PIN P2_02 +#define Z_DIR_PIN P0_20 +#define Z_ENABLE_PIN P0_19 #ifndef Z_CS_PIN - #define Z_CS_PIN P1_16 // ETH + #define Z_CS_PIN P1_16 // ETH #endif -#define E0_STEP_PIN P2_03 -#define E0_DIR_PIN P0_22 -#define E0_ENABLE_PIN P0_21 +#define E0_STEP_PIN P2_03 +#define E0_DIR_PIN P0_22 +#define E0_ENABLE_PIN P0_21 #ifndef E0_CS_PIN - #define E0_CS_PIN P1_17 // ETH + #define E0_CS_PIN P1_17 // ETH #endif // @@ -84,13 +83,13 @@ // #if ENABLED(TMC_USE_SW_SPI) #ifndef TMC_SW_MOSI - #define TMC_SW_MOSI P0_18 // ETH + #define TMC_SW_MOSI P0_18 // ETH #endif #ifndef TMC_SW_MISO - #define TMC_SW_MISO P0_17 // ETH + #define TMC_SW_MISO P0_17 // ETH #endif #ifndef TMC_SW_SCK - #define TMC_SW_SCK P0_15 // ETH + #define TMC_SW_SCK P0_15 // ETH #endif #endif @@ -98,23 +97,23 @@ // Temperature Sensors // 3.3V max when defined as an analog input // -#define TEMP_0_PIN P0_24_A1 // A0 (T0) -#define TEMP_BED_PIN P0_23_A0 // A1 (T1) +#define TEMP_0_PIN P0_24_A1 // A0 (T0) +#define TEMP_BED_PIN P0_23_A0 // A1 (T1) // // Heaters / Fans // -#define HEATER_0_PIN P2_07 -#define HEATER_BED_PIN P2_05 +#define HEATER_0_PIN P2_07 +#define HEATER_BED_PIN P2_05 #ifndef FAN_PIN - #define FAN_PIN P2_04 + #define FAN_PIN P2_04 #endif // // Unused // -//#define PIN_P2_10 P2_10 // IBOOT-1 -//#define PIN_P0_27 P0_27 // Onboard SD Detect +//#define PIN_P2_10 P2_10 // IBOOT-1 +//#define PIN_P0_27 P0_27 // Onboard SD Detect /** * LCD / Controller @@ -126,20 +125,20 @@ * for the onboard SD card, and a chip select signal is not provided for the remote * SD card. */ -#if HAS_SPI_LCD +#if HAS_WIRED_LCD - #define BEEPER_PIN P1_31 // EXP1-1 + #define BEEPER_PIN P1_31 // EXP1-1 - #define BTN_EN1 P3_26 // EXP2-3 - #define BTN_EN2 P3_25 // EXP2-5 - #define BTN_ENC P1_30 // EXP1-2 + #define BTN_EN1 P3_26 // EXP2-3 + #define BTN_EN2 P3_25 // EXP2-5 + #define BTN_ENC P1_30 // EXP1-2 - #define SD_DETECT_PIN P0_27 // EXP2-7 - #define LCD_PINS_RS P0_16 // EXP1-4 - #define LCD_PINS_ENABLE P0_18 // (MOSI) EXP1-3 - #define LCD_PINS_D4 P0_15 // (SCK) EXP1-5 + #define SD_DETECT_PIN P0_27 // EXP2-7 + #define LCD_PINS_RS P0_16 // EXP1-4 + #define LCD_PINS_ENABLE P0_18 // (MOSI) EXP1-3 + #define LCD_PINS_D4 P0_15 // (SCK) EXP1-5 - #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) && HAS_CHARACTER_LCD + #if BOTH(HAS_MARLINUI_HD44780, REPRAP_DISCOUNT_SMART_CONTROLLER) #error "REPRAP_DISCOUNT_SMART_CONTROLLER is not supported by the BIQU B300 v1.0" #endif @@ -147,7 +146,7 @@ #error "SDSUPPORT is not supported by the BIQU B300 v1.0 when an LCD controller is used" #endif -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD /** * SD Card Reader @@ -156,11 +155,11 @@ * Hardware SPI can't be used because P0_17 (MISO) is not brought out on this board. */ #if ENABLED(SDSUPPORT) - #define SCK_PIN P0_15 // EXP1-5 - #define MISO_PIN P0_16 // EXP1-4 - #define MOSI_PIN P0_18 // EXP1-3 - #define SS_PIN P1_30 // EXP1-2 - #define SDSS SS_PIN + #define SCK_PIN P0_15 // EXP1-5 + #define MISO_PIN P0_16 // EXP1-4 + #define MOSI_PIN P0_18 // EXP1-3 + #define SS_PIN P1_30 // EXP1-2 + #define SDSS SS_PIN #endif /** diff --git a/Marlin/src/pins/lpc1768/pins_BIQU_BQ111_A4.h b/Marlin/src/pins/lpc1768/pins_BIQU_BQ111_A4.h index 17a9b7d58da8..bcff04eb85e8 100644 --- a/Marlin/src/pins/lpc1768/pins_BIQU_BQ111_A4.h +++ b/Marlin/src/pins/lpc1768/pins_BIQU_BQ111_A4.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -27,10 +27,9 @@ * Applies to the following boards: * * BOARD_BIQU_BQ111_A4 (Hotend, Fan, Bed) - * */ -#ifndef MCU_LPC1768 +#if NOT_TARGET(MCU_LPC1768) #error "Oops! Make sure you have the LPC1768 environment selected in your IDE." #endif @@ -39,56 +38,53 @@ // // Limit Switches // -#define X_MIN_PIN P1_24 // 10k pullup to 3.3V, 1K series -#define X_MAX_PIN P1_25 // 10k pullup to 3.3V, 1K series -#define Y_MIN_PIN P1_26 // 10k pullup to 3.3V, 1K series -#define Y_MAX_PIN P1_27 // 10k pullup to 3.3V, 1K series -#define Z_MIN_PIN P1_28 // 10k pullup to 3.3V, 1K series -#define Z_MAX_PIN P1_29 // 10k pullup to 3.3V, 1K series - +#define X_MIN_PIN P1_24 // 10k pullup to 3.3V, 1K series +#define X_MAX_PIN P1_25 // 10k pullup to 3.3V, 1K series +#define Y_MIN_PIN P1_26 // 10k pullup to 3.3V, 1K series +#define Y_MAX_PIN P1_27 // 10k pullup to 3.3V, 1K series +#define Z_MIN_PIN P1_28 // 10k pullup to 3.3V, 1K series +#define Z_MAX_PIN P1_29 // 10k pullup to 3.3V, 1K series // // Steppers // -#define X_STEP_PIN P2_0 -#define X_DIR_PIN P0_5 -#define X_ENABLE_PIN P0_4 - -#define Y_STEP_PIN P2_1 -#define Y_DIR_PIN P0_11 -#define Y_ENABLE_PIN P0_10 +#define X_STEP_PIN P2_00 +#define X_DIR_PIN P0_05 +#define X_ENABLE_PIN P0_04 -#define Z_STEP_PIN P2_2 -#define Z_DIR_PIN P0_20 -#define Z_ENABLE_PIN P0_19 +#define Y_STEP_PIN P2_01 +#define Y_DIR_PIN P0_11 +#define Y_ENABLE_PIN P0_10 -#define E0_STEP_PIN P2_3 -#define E0_DIR_PIN P0_22 -#define E0_ENABLE_PIN P0_21 +#define Z_STEP_PIN P2_02 +#define Z_DIR_PIN P0_20 +#define Z_ENABLE_PIN P0_19 +#define E0_STEP_PIN P2_03 +#define E0_DIR_PIN P0_22 +#define E0_ENABLE_PIN P0_21 // // Temperature Sensors // 3.3V max when defined as an analog input // -#define TEMP_0_PIN P0_23_A0 // A0 (T0) -#define TEMP_BED_PIN P0_24_A1 // A1 (T1) - +#define TEMP_0_PIN P0_23_A0 // A0 (T0) +#define TEMP_BED_PIN P0_24_A1 // A1 (T1) // // Heaters / Fans // -#define HEATER_0_PIN P2_7 -#define HEATER_BED_PIN P2_5 +#define HEATER_0_PIN P2_07 +#define HEATER_BED_PIN P2_05 #ifndef FAN_PIN - #define FAN_PIN P2_4 + #define FAN_PIN P2_04 #endif // // Unused // -//#define PIN_P2_10 P2_10 // IBOOT-1 -//#define PIN_P0_27 P0_27 // Onboard SD Detect +//#define PIN_P2_10 P2_10 // IBOOT-1 +//#define PIN_P0_27 P0_27 // Onboard SD Detect /** * LCD / Controller @@ -100,20 +96,20 @@ * for the onboard SD card, and a chip select signal is not provided for the remote * SD card. */ -#if HAS_SPI_LCD +#if HAS_WIRED_LCD - #define BEEPER_PIN P1_31 // EXP1-1 + #define BEEPER_PIN P1_31 // EXP1-1 - #define BTN_EN1 P3_26 // EXP2-3 - #define BTN_EN2 P3_25 // EXP2-5 - #define BTN_ENC P1_30 // EXP1-2 + #define BTN_EN1 P3_26 // EXP2-3 + #define BTN_EN2 P3_25 // EXP2-5 + #define BTN_ENC P1_30 // EXP1-2 - #define SD_DETECT_PIN P0_27 // EXP2-7 - #define LCD_PINS_RS P0_16 // EXP1-4 - #define LCD_PINS_ENABLE P0_18 // (MOSI) EXP1-3 - #define LCD_PINS_D4 P0_15 // (SCK) EXP1-5 + #define SD_DETECT_PIN P0_27 // EXP2-7 + #define LCD_PINS_RS P0_16 // EXP1-4 + #define LCD_PINS_ENABLE P0_18 // (MOSI) EXP1-3 + #define LCD_PINS_D4 P0_15 // (SCK) EXP1-5 - #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) && HAS_CHARACTER_LCD + #if BOTH(HAS_MARLINUI_HD44780, REPRAP_DISCOUNT_SMART_CONTROLLER) #error "REPRAP_DISCOUNT_SMART_CONTROLLER is not supported by the BIQU BQ111-A4" #endif @@ -121,8 +117,7 @@ #error "SDSUPPORT is not supported by the BIQU BQ111-A4 when an LCD controller is used" #endif -#endif // HAS_SPI_LCD - +#endif // HAS_WIRED_LCD /** * SD Card Reader @@ -132,15 +127,14 @@ */ #if ENABLED(SDSUPPORT) - #define SCK_PIN P0_15 // EXP1-5 - #define MISO_PIN P0_16 // EXP1-4 - #define MOSI_PIN P0_18 // EXP1-3 - #define SS_PIN P1_30 // EXP1-2 - #define SDSS SS_PIN + #define SCK_PIN P0_15 // EXP1-5 + #define MISO_PIN P0_16 // EXP1-4 + #define MOSI_PIN P0_18 // EXP1-3 + #define SS_PIN P1_30 // EXP1-2 + #define SDSS SS_PIN #endif // SDSUPPORT - /** * PWMS * diff --git a/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_1.h b/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_1.h index 15b63494094b..0701e45992eb 100644 --- a/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_1.h +++ b/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_1.h @@ -16,42 +16,41 @@ * 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 . + * along with this program. If not, see . * */ #pragma once -#define BOARD_INFO_NAME "BIGTREE SKR 1.1" +#define BOARD_INFO_NAME "BTT SKR V1.1" // // Limit Switches // - -#define X_MIN_PIN P1_29 -#define X_MAX_PIN P1_28 -#define Y_MIN_PIN P1_27 -#define Y_MAX_PIN P1_26 -#define Z_MIN_PIN P1_25 -#define Z_MAX_PIN P1_24 +#define X_MIN_PIN P1_29 +#define X_MAX_PIN P1_28 +#define Y_MIN_PIN P1_27 +#define Y_MAX_PIN P1_26 +#define Z_MIN_PIN P1_25 +#define Z_MAX_PIN P1_24 // // Steppers // -#define X_STEP_PIN P0_04 -#define X_DIR_PIN P0_05 -#define X_ENABLE_PIN P4_28 +#define X_STEP_PIN P0_04 +#define X_DIR_PIN P0_05 +#define X_ENABLE_PIN P4_28 -#define Y_STEP_PIN P2_01 -#define Y_DIR_PIN P2_02 -#define Y_ENABLE_PIN P2_00 +#define Y_STEP_PIN P2_01 +#define Y_DIR_PIN P2_02 +#define Y_ENABLE_PIN P2_00 -#define Z_STEP_PIN P0_20 -#define Z_DIR_PIN P0_21 -#define Z_ENABLE_PIN P0_19 +#define Z_STEP_PIN P0_20 +#define Z_DIR_PIN P0_21 +#define Z_ENABLE_PIN P0_19 -#define E0_STEP_PIN P0_11 -#define E0_DIR_PIN P2_13 -#define E0_ENABLE_PIN P2_12 +#define E0_STEP_PIN P0_11 +#define E0_DIR_PIN P2_13 +#define E0_ENABLE_PIN P2_12 /** * LCD / Controller @@ -66,22 +65,32 @@ * by redrawing the screen after SD card accesses. */ -#if HAS_SPI_LCD - #define BTN_EN1 P3_26 - #define BTN_EN2 P3_25 - #define BTN_ENC P2_11 +#if IS_TFTGLCD_PANEL + + #if ENABLED(TFTGLCD_PANEL_SPI) + #define TFTGLCD_CS P3_26 + #endif + + #define SD_DETECT_PIN P1_31 + +#elif HAS_WIRED_LCD - #define SD_DETECT_PIN P1_31 - #define LCD_SDSS P1_23 - #define LCD_PINS_RS P0_16 - #define LCD_PINS_ENABLE P0_18 - #define LCD_PINS_D4 P0_15 + #define BTN_EN1 P3_26 + #define BTN_EN2 P3_25 + #define BTN_ENC P2_11 + + #define SD_DETECT_PIN P1_31 + #define LCD_SDSS P1_23 + #define LCD_PINS_RS P0_16 + #define LCD_PINS_ENABLE P0_18 + #define LCD_PINS_D4 P0_15 #if ENABLED(MKS_MINI_12864) - #define DOGLCD_CS P2_06 - #define DOGLCD_A0 P0_16 + #define DOGLCD_CS P2_06 + #define DOGLCD_A0 P0_16 #endif -#endif + +#endif // HAS_WIRED_LCD // // SD Support @@ -90,20 +99,20 @@ // requires jumpers on the SKR V1.1 board as documented here: // https://www.facebook.com/groups/505736576548648/permalink/630639874058317/ #ifndef SDCARD_CONNECTION - #if EITHER(MKS_MINI_12864, ENDER2_STOCKDISPLAY) - #define SDCARD_CONNECTION LCD + #if ANY(MKS_MINI_12864, ENDER2_STOCKDISPLAY, IS_TFTGLCD_PANEL) + #define SDCARD_CONNECTION LCD #else - #define SDCARD_CONNECTION ONBOARD + #define SDCARD_CONNECTION ONBOARD #endif #endif #if SD_CONNECTION_IS(LCD) - #define SS_PIN P1_23 + #define SS_PIN P1_23 #endif // Trinamic driver support -#if HAS_TRINAMIC +#if HAS_TRINAMIC_CONFIG // Using TMC devices in intelligent mode requires extra connections to each device. Unfortunately // the SKR does not have many free pins (especially if a display is in use). The SPI-based devices // will require 3 connections (clock, mosi, miso), plus a chip select line (CS) for each driver. @@ -131,49 +140,43 @@ // When using any TMC SPI-based drivers, software SPI is used // because pins may be shared with the display or SD card. #define TMC_USE_SW_SPI - #define TMC_SW_MOSI P0_18 - #define TMC_SW_MISO P0_17 + #define TMC_SW_MOSI P0_18 + #define TMC_SW_MISO P0_17 // To minimize pin usage use the same clock pin as the display/SD card reader. (May generate LCD noise.) - #define TMC_SW_SCK P0_15 + #define TMC_SW_SCK P0_15 // If pin 2_06 is unused, it can be used for the clock to avoid the LCD noise. - //#define TMC_SW_SCK P2_06 + //#define TMC_SW_SCK P2_06 #if ENABLED(SOFTWARE_DRIVER_ENABLE) // Software enable allows the enable pins to be repurposed as chip-select pins. // Note: Requires the driver modules to be modified to always be enabled with the enable pin removed. #if AXIS_DRIVER_TYPE_X(TMC2130) - #define X_CS_PIN P4_28 - #undef X_ENABLE_PIN - #define X_ENABLE_PIN -1 + #define X_CS_PIN P4_28 + #undef X_ENABLE_PIN #endif #if AXIS_DRIVER_TYPE_Y(TMC2130) - #define Y_CS_PIN P2_00 - #undef Y_ENABLE_PIN - #define Y_ENABLE_PIN -1 + #define Y_CS_PIN P2_00 + #undef Y_ENABLE_PIN #endif #if AXIS_DRIVER_TYPE_Z(TMC2130) - #define Z_CS_PIN P0_19 - #undef Z_ENABLE_PIN - #define Z_ENABLE_PIN -1 + #define Z_CS_PIN P0_19 + #undef Z_ENABLE_PIN #endif #if AXIS_DRIVER_TYPE_E0(TMC2130) - #define E0_CS_PIN P2_12 - #undef E0_ENABLE_PIN - #define E0_ENABLE_PIN -1 + #define E0_CS_PIN P2_12 + #undef E0_ENABLE_PIN #endif - #if AXIS_DRIVER_TYPE_E1(TMC2130) - #define E1_CS_PIN P0_10 - #undef E1_ENABLE_PIN - #define E1_ENABLE_PIN -1 + #define E1_CS_PIN P0_10 + #undef E1_ENABLE_PIN #endif - #else // !SOFTWARE_DRIVER_ENABLE + #else // !SOFTWARE_DRIVER_ENABLE // A chip-select pin is needed for each driver. @@ -186,11 +189,11 @@ #if SD_CONNECTION_IS(LCD) #error "SDCARD_CONNECTION must not be 'LCD' with SKR_USE_LCD_PINS_FOR_CS." #endif - #define X_CS_PIN P1_23 - #define Y_CS_PIN P3_26 - #define Z_CS_PIN P2_11 - #define E0_CS_PIN P3_25 - #define E1_CS_PIN P1_31 + #define X_CS_PIN P1_23 + #define Y_CS_PIN P3_26 + #define Z_CS_PIN P2_11 + #define E0_CS_PIN P3_25 + #define E1_CS_PIN P1_31 #endif // Example 2: A REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER @@ -201,16 +204,16 @@ #if SD_CONNECTION_IS(LCD) #error "SDCARD_CONNECTION must not be 'LCD' with SKR_USE_LCD_SD_CARD_PINS_FOR_CS." #endif - #define X_CS_PIN P0_02 - #define Y_CS_PIN P0_03 - #define Z_CS_PIN P2_06 + #define X_CS_PIN P0_02 + #define Y_CS_PIN P0_03 + #define Z_CS_PIN P2_06 // We use SD_DETECT_PIN for E0 #undef SD_DETECT_PIN - #define E0_CS_PIN P1_31 + #define E0_CS_PIN P1_31 // We use LCD_SDSS pin for E1 - #undef LCD_SDSS - #define LCD_SDSS -1 - #define E1_CS_PIN P1_23 + #undef LCD_SDSS + #define LCD_SDSS -1 + #define E1_CS_PIN P1_23 #endif // Example 3: Use the driver enable pins for chip-select. @@ -218,11 +221,11 @@ // advanced features (like driver monitoring) will not be available. //#define SKR_USE_ENABLE_CS #if ENABLED(SKR_USE_ENABLE_FOR_CS) - #define X_CS_PIN X_ENABLE_PIN - #define Y_CS_PIN Y_ENABLE_PIN - #define Z_CS_PIN Z_ENABLE_PIN - #define E0_CS_PIN E0_ENABLE_PIN - #define E1_CS_PIN E1_ENABLE_PIN + #define X_CS_PIN X_ENABLE_PIN + #define Y_CS_PIN Y_ENABLE_PIN + #define Z_CS_PIN Z_ENABLE_PIN + #define E0_CS_PIN E0_ENABLE_PIN + #define E1_CS_PIN E1_ENABLE_PIN #endif #endif // SOFTWARE_DRIVER_ENABLE diff --git a/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_3.h b/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_3.h index bd0ad468de0b..31373fedff66 100644 --- a/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_3.h +++ b/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_3.h @@ -16,117 +16,117 @@ * 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 . + * along with this program. If not, see . * */ #pragma once -#define BOARD_INFO_NAME "BIGTREE SKR 1.3" +#define BOARD_INFO_NAME "BTT SKR V1.3" -/** - * Trinamic Stallguard pins - */ -#define X_DIAG_PIN P1_29 // X- -#define Y_DIAG_PIN P1_27 // Y- -#define Z_DIAG_PIN P1_25 // Z- -#define E0_DIAG_PIN P1_28 // X+ -#define E1_DIAG_PIN P1_26 // Y+ +// +// Trinamic Stallguard pins +// +#define X_DIAG_PIN P1_29 // X- +#define Y_DIAG_PIN P1_27 // Y- +#define Z_DIAG_PIN P1_25 // Z- +#define E0_DIAG_PIN P1_28 // X+ +#define E1_DIAG_PIN P1_26 // Y+ -/** - * Limit Switches - */ -#if X_STALL_SENSITIVITY - #define X_STOP_PIN X_DIAG_PIN +// +// Limit Switches +// +#ifdef X_STALL_SENSITIVITY + #define X_STOP_PIN X_DIAG_PIN #if X_HOME_DIR < 0 - #define X_MAX_PIN P1_28 // X+ + #define X_MAX_PIN P1_28 // X+ #else - #define X_MIN_PIN P1_28 // X+ + #define X_MIN_PIN P1_28 // X+ #endif #else - #define X_MIN_PIN P1_29 // X- - #define X_MAX_PIN P1_28 // X+ + #define X_MIN_PIN P1_29 // X- + #define X_MAX_PIN P1_28 // X+ #endif -#if Y_STALL_SENSITIVITY - #define Y_STOP_PIN Y_DIAG_PIN +#ifdef Y_STALL_SENSITIVITY + #define Y_STOP_PIN Y_DIAG_PIN #if Y_HOME_DIR < 0 - #define Y_MAX_PIN P1_26 // Y+ + #define Y_MAX_PIN P1_26 // Y+ #else - #define Y_MIN_PIN P1_26 // Y+ + #define Y_MIN_PIN P1_26 // Y+ #endif #else - #define Y_MIN_PIN P1_27 // Y- - #define Y_MAX_PIN P1_26 // Y+ + #define Y_MIN_PIN P1_27 // Y- + #define Y_MAX_PIN P1_26 // Y+ #endif -#if Z_STALL_SENSITIVITY - #define Z_STOP_PIN Z_DIAG_PIN +#ifdef Z_STALL_SENSITIVITY + #define Z_STOP_PIN Z_DIAG_PIN #if Z_HOME_DIR < 0 - #define Z_MAX_PIN P1_24 // Z+ + #define Z_MAX_PIN P1_24 // Z+ #else - #define Z_MIN_PIN P1_24 // Z+ + #define Z_MIN_PIN P1_24 // Z+ #endif #else - #define Z_MIN_PIN P1_25 // Z- - #define Z_MAX_PIN P1_24 // Z+ + #define Z_MIN_PIN P1_25 // Z- + #define Z_MAX_PIN P1_24 // Z+ #endif -#define ONBOARD_ENDSTOPPULLUPS // Board has built-in pullups +#define ONBOARD_ENDSTOPPULLUPS // Board has built-in pullups // // Servos // #ifndef SERVO0_PIN - #define SERVO0_PIN P2_00 + #define SERVO0_PIN P2_00 #endif // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN P1_24 + #define Z_MIN_PROBE_PIN P1_24 #endif // // Filament Runout Sensor // #ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN P1_28 + #define FIL_RUNOUT_PIN P1_28 #endif // // Steppers // -#define X_STEP_PIN P2_02 -#define X_DIR_PIN P2_06 -#define X_ENABLE_PIN P2_01 +#define X_STEP_PIN P2_02 +#define X_DIR_PIN P2_06 +#define X_ENABLE_PIN P2_01 #ifndef X_CS_PIN - #define X_CS_PIN P1_17 + #define X_CS_PIN P1_17 #endif -#define Y_STEP_PIN P0_19 -#define Y_DIR_PIN P0_20 -#define Y_ENABLE_PIN P2_08 +#define Y_STEP_PIN P0_19 +#define Y_DIR_PIN P0_20 +#define Y_ENABLE_PIN P2_08 #ifndef Y_CS_PIN - #define Y_CS_PIN P1_15 + #define Y_CS_PIN P1_15 #endif -#define Z_STEP_PIN P0_22 -#define Z_DIR_PIN P2_11 -#define Z_ENABLE_PIN P0_21 +#define Z_STEP_PIN P0_22 +#define Z_DIR_PIN P2_11 +#define Z_ENABLE_PIN P0_21 #ifndef Z_CS_PIN - #define Z_CS_PIN P1_10 + #define Z_CS_PIN P1_10 #endif -#define E0_STEP_PIN P2_13 -#define E0_DIR_PIN P0_11 -#define E0_ENABLE_PIN P2_12 +#define E0_STEP_PIN P2_13 +#define E0_DIR_PIN P0_11 +#define E0_ENABLE_PIN P2_12 #ifndef E0_CS_PIN - #define E0_CS_PIN P1_08 + #define E0_CS_PIN P1_08 #endif #ifndef E1_CS_PIN - #define E1_CS_PIN P1_01 + #define E1_CS_PIN P1_01 #endif // @@ -134,24 +134,24 @@ // #if ENABLED(TMC_USE_SW_SPI) #ifndef TMC_SW_MOSI - #define TMC_SW_MOSI P4_28 + #define TMC_SW_MOSI P4_28 #endif #ifndef TMC_SW_MISO - #define TMC_SW_MISO P0_05 + #define TMC_SW_MISO P0_05 #endif #ifndef TMC_SW_SCK - #define TMC_SW_SCK P0_04 + #define TMC_SW_SCK P0_04 #endif #endif -#if HAS_TMC220x +#if HAS_TMC_UART /** * TMC2208/TMC2209 stepper drivers * * Hardware serial communication ports. * If undefined software serial is used according to the pins below */ - //#define X_HARDWARE_SERIAL Serial + //#define X_HARDWARE_SERIAL Serial1 //#define X2_HARDWARE_SERIAL Serial1 //#define Y_HARDWARE_SERIAL Serial1 //#define Y2_HARDWARE_SERIAL Serial1 @@ -166,23 +166,23 @@ // // Software serial // - #define X_SERIAL_TX_PIN P4_29 - #define X_SERIAL_RX_PIN P1_17 + #define X_SERIAL_TX_PIN P4_29 + #define X_SERIAL_RX_PIN P1_17 - #define Y_SERIAL_TX_PIN P1_16 - #define Y_SERIAL_RX_PIN P1_15 + #define Y_SERIAL_TX_PIN P1_16 + #define Y_SERIAL_RX_PIN P1_15 - #define Z_SERIAL_TX_PIN P1_14 - #define Z_SERIAL_RX_PIN P1_10 + #define Z_SERIAL_TX_PIN P1_14 + #define Z_SERIAL_RX_PIN P1_10 - #define E0_SERIAL_TX_PIN P1_09 - #define E0_SERIAL_RX_PIN P1_08 + #define E0_SERIAL_TX_PIN P1_09 + #define E0_SERIAL_RX_PIN P1_08 - #define E1_SERIAL_TX_PIN P1_04 - #define E1_SERIAL_RX_PIN P1_01 + #define E1_SERIAL_TX_PIN P1_04 + #define E1_SERIAL_RX_PIN P1_01 // Reduce baud rate to improve software serial reliability - #define TMC_BAUD_RATE 19200 + #define TMC_BAUD_RATE 19200 #endif /** @@ -196,25 +196,25 @@ * EXP2 EXP1 */ -#define EXPA1_03_PIN P1_23 -#define EXPA1_04_PIN P1_22 -#define EXPA1_05_PIN P1_21 -#define EXPA1_06_PIN P1_20 -#define EXPA1_07_PIN P1_19 -#define EXPA1_08_PIN P1_18 -#define EXPA1_09_PIN P0_28 -#define EXPA1_10_PIN P1_30 - -#define EXPA2_03_PIN -1 -#define EXPA2_04_PIN P1_31 -#define EXPA2_05_PIN P0_18 -#define EXPA2_06_PIN P3_25 -#define EXPA2_07_PIN P0_16 -#define EXPA2_08_PIN P3_26 -#define EXPA2_09_PIN P0_15 -#define EXPA2_10_PIN P0_17 - -#if HAS_SPI_LCD +#define EXPA1_03_PIN P1_23 +#define EXPA1_04_PIN P1_22 +#define EXPA1_05_PIN P1_21 +#define EXPA1_06_PIN P1_20 +#define EXPA1_07_PIN P1_19 +#define EXPA1_08_PIN P1_18 +#define EXPA1_09_PIN P0_28 +#define EXPA1_10_PIN P1_30 + +#define EXPA2_03_PIN -1 +#define EXPA2_04_PIN P1_31 +#define EXPA2_05_PIN P0_18 +#define EXPA2_06_PIN P3_25 +#define EXPA2_07_PIN P0_16 +#define EXPA2_08_PIN P3_26 +#define EXPA2_09_PIN P0_15 +#define EXPA2_10_PIN P0_17 + +#if HAS_WIRED_LCD #if ENABLED(ANET_FULL_GRAPHICS_LCD) @@ -241,75 +241,87 @@ * LCD LCD */ - #define LCD_PINS_RS EXPA1_03_PIN + #define LCD_PINS_RS EXPA1_03_PIN - #define BTN_EN1 EXPA1_06_PIN - #define BTN_EN2 EXPA1_04_PIN - #define BTN_ENC EXPA1_08_PIN + #define BTN_EN1 EXPA1_06_PIN + #define BTN_EN2 EXPA1_04_PIN + #define BTN_ENC EXPA1_08_PIN - #define LCD_PINS_ENABLE EXPA1_05_PIN - #define LCD_PINS_D4 EXPA1_07_PIN + #define LCD_PINS_ENABLE EXPA1_05_PIN + #define LCD_PINS_D4 EXPA1_07_PIN #elif ENABLED(CR10_STOCKDISPLAY) - #define LCD_PINS_RS EXPA1_04_PIN + #define LCD_PINS_RS EXPA1_04_PIN + + #define BTN_EN1 EXPA1_08_PIN + #define BTN_EN2 EXPA1_06_PIN + #define BTN_ENC EXPA1_09_PIN // (58) open-drain + + #define LCD_PINS_ENABLE EXPA1_03_PIN + #define LCD_PINS_D4 EXPA1_05_PIN + + #elif HAS_ADC_BUTTONS + + #error "ADC BUTTONS do not work unmodifed on SKR 1.3, The ADC ports cannot take more than 3.3v." + + #elif IS_TFTGLCD_PANEL - #define BTN_EN1 EXPA1_08_PIN - #define BTN_EN2 EXPA1_06_PIN - #define BTN_ENC EXPA1_09_PIN // (58) open-drain + #if ENABLED(TFTGLCD_PANEL_SPI) + #define TFTGLCD_CS EXPA2_08_PIN + #endif - #define LCD_PINS_ENABLE EXPA1_03_PIN - #define LCD_PINS_D4 EXPA1_05_PIN + #define SD_DETECT_PIN EXPA2_04_PIN - #else // !CR10_STOCKDISPLAY + #else // !CR10_STOCKDISPLAY - #define LCD_PINS_RS EXPA1_07_PIN + #define LCD_PINS_RS EXPA1_07_PIN - #define BTN_EN1 EXPA2_08_PIN // (31) J3-2 & AUX-4 - #define BTN_EN2 EXPA2_06_PIN // (33) J3-4 & AUX-4 - #define BTN_ENC EXPA1_09_PIN // (58) open-drain + #define BTN_EN1 EXPA2_08_PIN // (31) J3-2 & AUX-4 + #define BTN_EN2 EXPA2_06_PIN // (33) J3-4 & AUX-4 + #define BTN_ENC EXPA1_09_PIN // (58) open-drain - #define LCD_PINS_ENABLE EXPA1_08_PIN - #define LCD_PINS_D4 EXPA1_06_PIN + #define LCD_PINS_ENABLE EXPA1_08_PIN + #define LCD_PINS_D4 EXPA1_06_PIN - #define LCD_SDSS EXPA2_07_PIN // (16) J3-7 & AUX-4 - #define SD_DETECT_PIN EXPA2_04_PIN // (49) (NOT 5V tolerant) + #define LCD_SDSS EXPA2_07_PIN // (16) J3-7 & AUX-4 + #define SD_DETECT_PIN EXPA2_04_PIN // (49) (NOT 5V tolerant) #if ENABLED(FYSETC_MINI_12864) - #define DOGLCD_CS EXPA1_08_PIN - #define DOGLCD_A0 EXPA1_07_PIN - #define DOGLCD_SCK EXPA2_09_PIN - #define DOGLCD_MOSI EXPA2_05_PIN + #define DOGLCD_CS EXPA1_08_PIN + #define DOGLCD_A0 EXPA1_07_PIN + #define DOGLCD_SCK EXPA2_09_PIN + #define DOGLCD_MOSI EXPA2_05_PIN - #define LCD_BACKLIGHT_PIN -1 + #define LCD_BACKLIGHT_PIN -1 - #define FORCE_SOFT_SPI // Use this if default of hardware SPI causes display problems - // results in LCD soft SPI mode 3, SD soft SPI mode 0 + #define FORCE_SOFT_SPI // Use this if default of hardware SPI causes display problems + // results in LCD soft SPI mode 3, SD soft SPI mode 0 - #define LCD_RESET_PIN EXPA1_06_PIN // Must be high or open for LCD to operate normally. + #define LCD_RESET_PIN EXPA1_06_PIN // Must be high or open for LCD to operate normally. #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) #ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN EXPA1_05_PIN + #define RGB_LED_R_PIN EXPA1_05_PIN #endif #ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN EXPA1_04_PIN + #define RGB_LED_G_PIN EXPA1_04_PIN #endif #ifndef RGB_LED_B_PIN - #define RGB_LED_B_PIN EXPA1_03_PIN + #define RGB_LED_B_PIN EXPA1_03_PIN #endif #elif ENABLED(FYSETC_MINI_12864_2_1) - #define NEOPIXEL_PIN EXPA1_05_PIN + #define NEOPIXEL_PIN EXPA1_05_PIN #endif - #else // !FYSETC_MINI_12864 + #else // !FYSETC_MINI_12864 #if ENABLED(MKS_MINI_12864) - #define DOGLCD_CS EXPA1_05_PIN - #define DOGLCD_A0 EXPA1_04_PIN - #define DOGLCD_SCK EXPA2_09_PIN - #define DOGLCD_MOSI EXPA2_05_PIN + #define DOGLCD_CS EXPA1_05_PIN + #define DOGLCD_A0 EXPA1_04_PIN + #define DOGLCD_SCK EXPA2_09_PIN + #define DOGLCD_MOSI EXPA2_05_PIN #elif ENABLED(ENDER2_STOCKDISPLAY) @@ -325,39 +337,39 @@ * EXP1 */ - #define BTN_EN1 EXPA1_08_PIN - #define BTN_EN2 EXPA1_06_PIN - #define BTN_ENC EXPA1_09_PIN - #define DOGLCD_CS EXPA1_04_PIN - #define DOGLCD_A0 EXPA1_05_PIN - #define DOGLCD_SCK EXPA1_10_PIN - #define DOGLCD_MOSI EXPA1_03_PIN + #define BTN_EN1 EXPA1_08_PIN + #define BTN_EN2 EXPA1_06_PIN + #define BTN_ENC EXPA1_09_PIN + #define DOGLCD_CS EXPA1_04_PIN + #define DOGLCD_A0 EXPA1_05_PIN + #define DOGLCD_SCK EXPA1_10_PIN + #define DOGLCD_MOSI EXPA1_03_PIN #define FORCE_SOFT_SPI - #define LCD_BACKLIGHT_PIN -1 + #define LCD_BACKLIGHT_PIN -1 #endif #if ENABLED(ULTIPANEL) - #define LCD_PINS_D5 EXPA1_05_PIN - #define LCD_PINS_D6 EXPA1_04_PIN - #define LCD_PINS_D7 EXPA1_03_PIN + #define LCD_PINS_D5 EXPA1_05_PIN + #define LCD_PINS_D6 EXPA1_04_PIN + #define LCD_PINS_D7 EXPA1_03_PIN #endif #endif // !FYSETC_MINI_12864 #endif // !CR10_STOCKDISPLAY -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD // // SD Support // #ifndef SDCARD_CONNECTION - #define SDCARD_CONNECTION LCD + #define SDCARD_CONNECTION LCD #endif #if SD_CONNECTION_IS(LCD) - #define SS_PIN EXPA2_07_PIN + #define SS_PIN EXPA2_07_PIN #endif /** diff --git a/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_4.h b/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_4.h index 316049d6b127..4686e984b088 100644 --- a/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_4.h +++ b/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_4.h @@ -16,163 +16,169 @@ * 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 . + * along with this program. If not, see . * */ #pragma once #ifndef BOARD_INFO_NAME - #define BOARD_INFO_NAME "BIGTREE SKR 1.4" + #define BOARD_INFO_NAME "BTT SKR V1.4" +#endif + +#ifndef BOARD_CUSTOM_BUILD_FLAGS + #define BOARD_CUSTOM_BUILD_FLAGS -DLPC_PINCFG_UART3_P4_28 #endif // // SD Connection // #ifndef SDCARD_CONNECTION - #define SDCARD_CONNECTION LCD + #define SDCARD_CONNECTION LCD #endif // // Servos // -#define SERVO0_PIN P2_00 +#define SERVO0_PIN P2_00 // // TMC StallGuard DIAG pins // -#define X_DIAG_PIN P1_29 // X-STOP -#define Y_DIAG_PIN P1_28 // Y-STOP -#define Z_DIAG_PIN P1_27 // Z-STOP -#define E0_DIAG_PIN P1_26 // E0DET -#define E1_DIAG_PIN P1_25 // E1DET +#define X_DIAG_PIN P1_29 // X-STOP +#define Y_DIAG_PIN P1_28 // Y-STOP +#define Z_DIAG_PIN P1_27 // Z-STOP +#define E0_DIAG_PIN P1_26 // E0DET +#define E1_DIAG_PIN P1_25 // E1DET // // Limit Switches // -#if X_STALL_SENSITIVITY - #define X_STOP_PIN X_DIAG_PIN +#ifdef X_STALL_SENSITIVITY + #define X_STOP_PIN X_DIAG_PIN #if X_HOME_DIR < 0 - #define X_MAX_PIN P1_26 // E0DET + #define X_MAX_PIN P1_26 // E0DET #else - #define X_MIN_PIN P1_26 // E0DET + #define X_MIN_PIN P1_26 // E0DET #endif #else - #define X_STOP_PIN P1_29 // X-STOP + #define X_STOP_PIN P1_29 // X-STOP #endif -#if Y_STALL_SENSITIVITY - #define Y_STOP_PIN Y_DIAG_PIN +#ifdef Y_STALL_SENSITIVITY + #define Y_STOP_PIN Y_DIAG_PIN #if Y_HOME_DIR < 0 - #define Y_MAX_PIN P1_25 // E1DET + #define Y_MAX_PIN P1_25 // E1DET #else - #define Y_MIN_PIN P1_25 // E1DET + #define Y_MIN_PIN P1_25 // E1DET #endif #else - #define Y_STOP_PIN P1_28 // Y-STOP + #define Y_STOP_PIN P1_28 // Y-STOP #endif -#if Z_STALL_SENSITIVITY - #define Z_STOP_PIN Z_DIAG_PIN +#ifdef Z_STALL_SENSITIVITY + #define Z_STOP_PIN Z_DIAG_PIN #if Z_HOME_DIR < 0 - #define Z_MAX_PIN P1_00 // PWRDET + #define Z_MAX_PIN P1_00 // PWRDET #else - #define Z_MIN_PIN P1_00 // PWRDET + #define Z_MIN_PIN P1_00 // PWRDET #endif #else - #define Z_STOP_PIN P1_27 // Z-STOP + #ifndef Z_STOP_PIN + #define Z_STOP_PIN P1_27 // Z-STOP + #endif #endif // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN P0_10 + #define Z_MIN_PROBE_PIN P0_10 #endif // // Filament Runout Sensor // -#define FIL_RUNOUT_PIN P1_26 // E0DET -#define FIL_RUNOUT2_PIN P1_25 // E1DET +#define FIL_RUNOUT_PIN P1_26 // E0DET +#define FIL_RUNOUT2_PIN P1_25 // E1DET // // Power Supply Control // #ifndef PS_ON_PIN - #define PS_ON_PIN P1_00 // PWRDET + #define PS_ON_PIN P1_00 // PWRDET #endif // // Power Loss Detection // #ifndef POWER_LOSS_PIN - #define POWER_LOSS_PIN P1_00 // PWRDET + #define POWER_LOSS_PIN P1_00 // PWRDET #endif // // Steppers // -#define X_STEP_PIN P2_02 -#define X_DIR_PIN P2_06 -#define X_ENABLE_PIN P2_01 +#define X_STEP_PIN P2_02 +#define X_DIR_PIN P2_06 +#define X_ENABLE_PIN P2_01 #ifndef X_CS_PIN - #define X_CS_PIN P1_10 + #define X_CS_PIN P1_10 #endif -#define Y_STEP_PIN P0_19 -#define Y_DIR_PIN P0_20 -#define Y_ENABLE_PIN P2_08 +#define Y_STEP_PIN P0_19 +#define Y_DIR_PIN P0_20 +#define Y_ENABLE_PIN P2_08 #ifndef Y_CS_PIN - #define Y_CS_PIN P1_09 + #define Y_CS_PIN P1_09 #endif -#define Z_STEP_PIN P0_22 -#define Z_DIR_PIN P2_11 -#define Z_ENABLE_PIN P0_21 +#define Z_STEP_PIN P0_22 +#define Z_DIR_PIN P2_11 +#define Z_ENABLE_PIN P0_21 #ifndef Z_CS_PIN - #define Z_CS_PIN P1_08 + #define Z_CS_PIN P1_08 #endif -#define E0_STEP_PIN P2_13 -#define E0_DIR_PIN P0_11 -#define E0_ENABLE_PIN P2_12 +#define E0_STEP_PIN P2_13 +#define E0_DIR_PIN P0_11 +#define E0_ENABLE_PIN P2_12 #ifndef E0_CS_PIN - #define E0_CS_PIN P1_04 + #define E0_CS_PIN P1_04 #endif -#define E1_STEP_PIN P1_15 -#define E1_DIR_PIN P1_14 -#define E1_ENABLE_PIN P1_16 +#define E1_STEP_PIN P1_15 +#define E1_DIR_PIN P1_14 +#define E1_ENABLE_PIN P1_16 #ifndef E1_CS_PIN - #define E1_CS_PIN P1_01 + #define E1_CS_PIN P1_01 #endif -#define TEMP_1_PIN P0_23_A0 // A2 (T2) - (69) - TEMP_1_PIN -#define TEMP_BED_PIN P0_25_A2 // A0 (T0) - (67) - TEMP_BED_PIN +#define TEMP_1_PIN P0_23_A0 // A0 (T0) - (67) - TEMP_1_PIN +#define TEMP_BED_PIN P0_25_A2 // A2 (T2) - (69) - TEMP_BED_PIN // // Software SPI pins for TMC2130 stepper drivers // #if ENABLED(TMC_USE_SW_SPI) #ifndef TMC_SW_MOSI - #define TMC_SW_MOSI P1_17 + #define TMC_SW_MOSI P1_17 #endif #ifndef TMC_SW_MISO - #define TMC_SW_MISO P0_05 + #define TMC_SW_MISO P0_05 #endif #ifndef TMC_SW_SCK - #define TMC_SW_SCK P0_04 + #define TMC_SW_SCK P0_04 #endif #endif -#if HAS_TMC220x +#if HAS_TMC_UART /** * TMC2208/TMC2209 stepper drivers * * Hardware serial communication ports. * If undefined software serial is used according to the pins below */ - //#define X_HARDWARE_SERIAL Serial + //#define X_HARDWARE_SERIAL Serial1 //#define X2_HARDWARE_SERIAL Serial1 //#define Y_HARDWARE_SERIAL Serial1 //#define Y2_HARDWARE_SERIAL Serial1 @@ -187,137 +193,232 @@ // // Software serial // - #define X_SERIAL_TX_PIN P1_10 - #define X_SERIAL_RX_PIN P1_10 + #define X_SERIAL_TX_PIN P1_10 + #define X_SERIAL_RX_PIN P1_10 - #define Y_SERIAL_TX_PIN P1_09 - #define Y_SERIAL_RX_PIN P1_09 + #define Y_SERIAL_TX_PIN P1_09 + #define Y_SERIAL_RX_PIN P1_09 - #define Z_SERIAL_TX_PIN P1_08 - #define Z_SERIAL_RX_PIN P1_08 + #define Z_SERIAL_TX_PIN P1_08 + #define Z_SERIAL_RX_PIN P1_08 - #define E0_SERIAL_TX_PIN P1_04 - #define E0_SERIAL_RX_PIN P1_04 + #define E0_SERIAL_TX_PIN P1_04 + #define E0_SERIAL_RX_PIN P1_04 - #define E1_SERIAL_TX_PIN P1_01 - #define E1_SERIAL_RX_PIN P1_01 + #define E1_SERIAL_TX_PIN P1_01 + #define E1_SERIAL_RX_PIN P1_01 - #define Z2_SERIAL_TX_PIN P1_01 - #define Z2_SERIAL_RX_PIN P1_01 + #define Z2_SERIAL_TX_PIN P1_01 + #define Z2_SERIAL_RX_PIN P1_01 // Reduce baud rate to improve software serial reliability - #define TMC_BAUD_RATE 19200 + #define TMC_BAUD_RATE 19200 #endif // // SD Connection // #if SD_CONNECTION_IS(LCD) - #define SS_PIN P0_16 + #define SS_PIN P0_16 #endif /** - * _____ _____ - * NC | · · | GND 5V | · · | GND - * RESET | · · | 1.31(SD_DETECT) (LCD_D7) 1.23 | · · | 1.22 (LCD_D6) - * (MOSI)0.18 | · · | 3.25(BTN_EN2) (LCD_D5) 1.21 | · · | 1.20 (LCD_D4) - * (SD_SS)0.16 | · · | 3.26(BTN_EN1) (LCD_RS) 1.19 | · · | 1.18 (LCD_EN) - * (SCK)0.15 | · · | 0.17(MISO) (BTN_ENC) 0.28 | · · | 1.30 (BEEPER) - * ----- ----- - * EXP2 EXP1 + * _____ _____ + * NC | · · | GND 5V | · · | GND + * RESET | · · | 1.31 (SD_DETECT) (LCD_D7) 1.23 | · · | 1.22 (LCD_D6) + * (MOSI) 0.18 | · · | 3.25 (BTN_EN2) (LCD_D5) 1.21 | · · | 1.20 (LCD_D4) + * (SD_SS) 0.16 | · · | 3.26 (BTN_EN1) (LCD_RS) 1.19 | · · | 1.18 (LCD_EN) + * (SCK) 0.15 | · · | 0.17 (MISO) (BTN_ENC) 0.28 | · · | 1.30 (BEEPER) + * ----- ----- + * EXP2 EXP1 */ -#if HAS_SPI_LCD +#if HAS_WIRED_LCD #if ENABLED(ANET_FULL_GRAPHICS_LCD) - #define LCD_PINS_RS P1_23 + #define LCD_PINS_RS P1_23 - #define BTN_EN1 P1_20 - #define BTN_EN2 P1_22 - #define BTN_ENC P1_18 + #define BTN_EN1 P1_20 + #define BTN_EN2 P1_22 + #define BTN_ENC P1_18 - #define LCD_PINS_ENABLE P1_21 - #define LCD_PINS_D4 P1_19 + #define LCD_PINS_ENABLE P1_21 + #define LCD_PINS_D4 P1_19 #elif ENABLED(CR10_STOCKDISPLAY) - #define BTN_ENC P0_28 // (58) open-drain - #define LCD_PINS_RS P1_22 + #define BTN_ENC P0_28 // (58) open-drain + #define LCD_PINS_RS P1_22 + + #define BTN_EN1 P1_18 + #define BTN_EN2 P1_20 + + #define LCD_PINS_ENABLE P1_23 + #define LCD_PINS_D4 P1_21 + + #elif ENABLED(ENDER2_STOCKDISPLAY) + + /** Creality Ender-2 display pinout + * _____ + * 5V | 1 2 | GND + * (MOSI) 1.23 | 3 4 | 1.22 (LCD_RS) + * (LCD_A0) 1.21 | 5 6 | 1.20 (BTN_EN2) + * RESET 1.19 | 7 8 | 1.18 (BTN_EN1) + * (BTN_ENC) 0.28 | 9 10| 1.30 (SCK) + * ----- + * EXP1 + */ + + #define BTN_EN1 P1_18 + #define BTN_EN2 P1_20 + #define BTN_ENC P0_28 + + #define DOGLCD_CS P1_22 + #define DOGLCD_A0 P1_21 + #define DOGLCD_SCK P1_30 + #define DOGLCD_MOSI P1_23 + #define FORCE_SOFT_SPI + #define LCD_BACKLIGHT_PIN -1 + + #elif HAS_SPI_TFT // Config for Classic UI (emulated DOGM) and Color UI + #define TFT_CS_PIN P1_22 + #define TFT_A0_PIN P1_23 + #define TFT_DC_PIN P1_23 + #define TFT_MISO_PIN P0_17 + #define TFT_BACKLIGHT_PIN P1_18 + #define TFT_RESET_PIN P1_19 + + #define LCD_USE_DMA_SPI + + #define TOUCH_INT_PIN P1_21 + #define TOUCH_CS_PIN P1_20 + #define TOUCH_BUTTONS_HW_SPI + #define TOUCH_BUTTONS_HW_SPI_DEVICE 1 + + #ifndef GRAPHICAL_TFT_UPSCALE + #define GRAPHICAL_TFT_UPSCALE 3 + #endif + // SPI 1 + #define SCK_PIN P0_15 + #define MISO_PIN P0_17 + #define MOSI_PIN P0_18 + + // Disable any LCD related PINs config + #define LCD_PINS_ENABLE -1 + #define LCD_PINS_RS -1 + + // XPT2046 Touch Screen calibration + #if ENABLED(TFT_CLASSIC_UI) + #ifndef XPT2046_X_CALIBRATION + #define XPT2046_X_CALIBRATION -11245 + #endif + #ifndef XPT2046_Y_CALIBRATION + #define XPT2046_Y_CALIBRATION 8629 + #endif + #ifndef XPT2046_X_OFFSET + #define XPT2046_X_OFFSET 685 + #endif + #ifndef XPT2046_Y_OFFSET + #define XPT2046_Y_OFFSET -285 + #endif + #elif ENABLED(TFT_480x320_SPI) + #ifndef XPT2046_X_CALIBRATION + #define XPT2046_X_CALIBRATION -17232 + #endif + #ifndef XPT2046_Y_CALIBRATION + #define XPT2046_Y_CALIBRATION 11196 + #endif + #ifndef XPT2046_X_OFFSET + #define XPT2046_X_OFFSET 1047 + #endif + #ifndef XPT2046_Y_OFFSET + #define XPT2046_Y_OFFSET -358 + #endif + + #define TFT_BUFFER_SIZE 2400 + #endif + + #elif IS_TFTGLCD_PANEL - #define BTN_EN1 P1_18 - #define BTN_EN2 P1_20 + #if ENABLED(TFTGLCD_PANEL_SPI) + #define TFTGLCD_CS P3_26 + #endif - #define LCD_PINS_ENABLE P1_23 - #define LCD_PINS_D4 P1_21 + #define SD_DETECT_PIN P1_31 #else - #define BTN_ENC P0_28 // (58) open-drain - #define LCD_PINS_RS P1_19 - #define BTN_EN1 P3_26 // (31) J3-2 & AUX-4 - #define BTN_EN2 P3_25 // (33) J3-4 & AUX-4 + #define BTN_ENC P0_28 // (58) open-drain + #define LCD_PINS_RS P1_19 + + #define BTN_EN1 P3_26 // (31) J3-2 & AUX-4 + #define BTN_EN2 P3_25 // (33) J3-4 & AUX-4 - #define LCD_PINS_ENABLE P1_18 - #define LCD_PINS_D4 P1_20 + #define LCD_PINS_ENABLE P1_18 + #define LCD_PINS_D4 P1_20 - #define LCD_SDSS P0_16 // (16) J3-7 & AUX-4 + #define LCD_SDSS P0_16 // (16) J3-7 & AUX-4 #if SD_CONNECTION_IS(LCD) - #define SD_DETECT_PIN P1_31 // (49) (NOT 5V tolerant) + #define SD_DETECT_PIN P1_31 // (49) (NOT 5V tolerant) #endif #if ENABLED(FYSETC_MINI_12864) - #define DOGLCD_CS P1_18 - #define DOGLCD_A0 P1_19 - #define DOGLCD_SCK P0_15 - #define DOGLCD_MOSI P0_18 + #define DOGLCD_CS P1_18 + #define DOGLCD_A0 P1_19 + #define DOGLCD_SCK P0_15 + #define DOGLCD_MOSI P0_18 - #define LCD_BACKLIGHT_PIN -1 + #define LCD_BACKLIGHT_PIN -1 - #define FORCE_SOFT_SPI // Use this if default of hardware SPI causes display problems - // results in LCD soft SPI mode 3, SD soft SPI mode 0 + #define FORCE_SOFT_SPI // Use this if default of hardware SPI causes display problems + // results in LCD soft SPI mode 3, SD soft SPI mode 0 - #define LCD_RESET_PIN P1_20 // Must be high or open for LCD to operate normally. + #define LCD_RESET_PIN P1_20 // Must be high or open for LCD to operate normally. #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) #ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN P1_21 + #define RGB_LED_R_PIN P1_21 #endif #ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN P1_22 + #define RGB_LED_G_PIN P1_22 #endif #ifndef RGB_LED_B_PIN - #define RGB_LED_B_PIN P1_23 + #define RGB_LED_B_PIN P1_23 #endif #elif ENABLED(FYSETC_MINI_12864_2_1) - #define NEOPIXEL_PIN P1_21 + #define NEOPIXEL_PIN P1_21 #endif - #else // !FYSETC_MINI_12864 + #else // !FYSETC_MINI_12864 #if ENABLED(MKS_MINI_12864) - #define DOGLCD_CS P1_21 - #define DOGLCD_A0 P1_22 - #define DOGLCD_SCK P0_15 - #define DOGLCD_MOSI P0_18 + #define DOGLCD_CS P1_21 + #define DOGLCD_A0 P1_22 + #define DOGLCD_SCK P0_15 + #define DOGLCD_MOSI P0_18 #define FORCE_SOFT_SPI #endif #if ENABLED(ULTIPANEL) - #define LCD_PINS_D5 P1_21 - #define LCD_PINS_D6 P1_22 - #define LCD_PINS_D7 P1_23 + #define LCD_PINS_D5 P1_21 + #define LCD_PINS_D6 P1_22 + #define LCD_PINS_D7 P1_23 #endif #endif // !FYSETC_MINI_12864 - #endif + #endif // HAS_MARLINUI_U8GLIB -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD + +#if HAS_ADC_BUTTONS + #error "ADC BUTTONS do not work unmodifed on SKR 1.4, The ADC ports cannot take more than 3.3v." +#endif // -// Neopixel LED +// NeoPixel LED // #ifndef NEOPIXEL_PIN - #define NEOPIXEL_PIN P1_24 + #define NEOPIXEL_PIN P1_24 #endif /** diff --git a/Marlin/src/pins/lpc1768/pins_BTT_SKR_common.h b/Marlin/src/pins/lpc1768/pins_BTT_SKR_common.h index fc08a60b91d6..820c35a01cb9 100644 --- a/Marlin/src/pins/lpc1768/pins_BTT_SKR_common.h +++ b/Marlin/src/pins/lpc1768/pins_BTT_SKR_common.h @@ -16,33 +16,33 @@ * 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 . + * along with this program. If not, see . * */ #pragma once #ifdef SKR_HAS_LPC1769 - #ifndef MCU_LPC1769 + #if NOT_TARGET(MCU_LPC1769) #error "Oops! Make sure you have the LPC1769 environment selected in your IDE." #endif -#elif !defined(MCU_LPC1768) +#elif NOT_TARGET(MCU_LPC1768) #error "Oops! Make sure you have the LPC1768 environment selected in your IDE." #endif // Ignore temp readings during development. -//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 +//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 // // Steppers // #ifndef E1_STEP_PIN - #define E1_STEP_PIN P0_01 + #define E1_STEP_PIN P0_01 #endif #ifndef E1_DIR_PIN - #define E1_DIR_PIN P0_00 + #define E1_DIR_PIN P0_00 #endif #ifndef E1_ENABLE_PIN - #define E1_ENABLE_PIN P0_10 + #define E1_ENABLE_PIN P0_10 #endif // @@ -50,63 +50,68 @@ // 3.3V max when defined as an analog input // #ifndef TEMP_0_PIN - #define TEMP_0_PIN P0_24_A1 // A1 (T1) - (68) - TEMP_0_PIN + #define TEMP_0_PIN P0_24_A1 // A1 (T1) - (68) - TEMP_0_PIN #endif #ifndef TEMP_1_PIN - #define TEMP_1_PIN P0_25_A2 // A2 (T2) - (69) - TEMP_1_PIN + #define TEMP_1_PIN P0_25_A2 // A2 (T2) - (69) - TEMP_1_PIN #endif #ifndef TEMP_BED_PIN - #define TEMP_BED_PIN P0_23_A0 // A0 (T0) - (67) - TEMP_BED_PIN + #define TEMP_BED_PIN P0_23_A0 // A0 (T0) - (67) - TEMP_BED_PIN #endif -#if HOTENDS == 1 && TEMP_SENSOR_PROBE - #define TEMP_PROBE_PIN P0_25_A2 // TEMP_1_PIN + +#if HOTENDS == 1 + #if TEMP_SENSOR_PROBE + #define TEMP_PROBE_PIN TEMP_1_PIN + #elif TEMP_SENSOR_CHAMBER + #define TEMP_CHAMBER_PIN TEMP_1_PIN + #endif #endif // // Heaters / Fans // #ifndef HEATER_0_PIN - #define HEATER_0_PIN P2_07 + #define HEATER_0_PIN P2_07 #endif #if HOTENDS == 1 #ifndef FAN1_PIN - #define FAN1_PIN P2_04 + #define FAN1_PIN P2_04 #endif #else #ifndef HEATER_1_PIN - #define HEATER_1_PIN P2_04 + #define HEATER_1_PIN P2_04 #endif #endif #ifndef FAN_PIN - #define FAN_PIN P2_03 + #define FAN_PIN P2_03 #endif #ifndef HEATER_BED_PIN - #define HEATER_BED_PIN P2_05 + #define HEATER_BED_PIN P2_05 #endif // // LCD / Controller // -#if HAS_SPI_LCD - #define BEEPER_PIN P1_30 // (37) not 5V tolerant +#if HAS_WIRED_LCD && DISABLED(LCD_USE_I2C_BUZZER) + #define BEEPER_PIN P1_30 // (37) not 5V tolerant #endif // // SD Support // -#define ONBOARD_SD_CS_PIN P0_06 // Chip select for "System" SD card +#define ONBOARD_SD_CS_PIN P0_06 // Chip select for "System" SD card #if SD_CONNECTION_IS(LCD) - #define SCK_PIN P0_15 - #define MISO_PIN P0_17 - #define MOSI_PIN P0_18 + #define SCK_PIN P0_15 + #define MISO_PIN P0_17 + #define MOSI_PIN P0_18 #elif SD_CONNECTION_IS(ONBOARD) #undef SD_DETECT_PIN - #define SD_DETECT_PIN P0_27 - #define SCK_PIN P0_07 - #define MISO_PIN P0_08 - #define MOSI_PIN P0_09 - #define SS_PIN ONBOARD_SD_CS_PIN + #define SD_DETECT_PIN P0_27 + #define SCK_PIN P0_07 + #define MISO_PIN P0_08 + #define MOSI_PIN P0_09 + #define SS_PIN ONBOARD_SD_CS_PIN #elif SD_CONNECTION_IS(CUSTOM_CABLE) #error "No custom SD drive cable defined for this board." #endif diff --git a/Marlin/src/pins/lpc1768/pins_GMARSH_X6_REV1.h b/Marlin/src/pins/lpc1768/pins_GMARSH_X6_REV1.h index 28445962ac7b..5132081a5591 100644 --- a/Marlin/src/pins/lpc1768/pins_GMARSH_X6_REV1.h +++ b/Marlin/src/pins/lpc1768/pins_GMARSH_X6_REV1.h @@ -16,19 +16,19 @@ * 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 . + * along with this program. If not, see . * */ #pragma once -#ifndef MCU_LPC1768 +#if NOT_TARGET(MCU_LPC1768) #error "Oops! Make sure you have the LPC1768 environment selected in your IDE." #endif #define BOARD_INFO_NAME "GMARSH X6 REV1" // Ignore temp readings during develpment. -//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 +//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 // // Enable 12MHz clock output on P1.27 pin to sync TMC2208 chip clocks @@ -38,66 +38,66 @@ // // Servos // -#define SERVO0_PIN P1_26 // PWM1[6] -#define SERVO1_PIN P1_18 // PWM1[1] +#define SERVO0_PIN P1_26 // PWM1[6] +#define SERVO1_PIN P1_18 // PWM1[1] // // Limit Switches // -#define X_MIN_PIN P0_00 -#define X_MAX_PIN P0_01 -#define Y_MIN_PIN P0_10 -#define Y_MAX_PIN P0_21 -#define Z_MIN_PIN P2_13 -#define Z_MAX_PIN P2_22 +#define X_MIN_PIN P0_00 +#define X_MAX_PIN P0_01 +#define Y_MIN_PIN P0_10 +#define Y_MAX_PIN P0_21 +#define Z_MIN_PIN P2_13 +#define Z_MAX_PIN P2_22 // // Steppers // -#define X_STEP_PIN P1_01 -#define X_DIR_PIN P1_04 -#define X_ENABLE_PIN P0_26 +#define X_STEP_PIN P1_01 +#define X_DIR_PIN P1_04 +#define X_ENABLE_PIN P0_26 -#define Y_STEP_PIN P1_10 -#define Y_DIR_PIN P1_14 -#define Y_ENABLE_PIN P1_08 +#define Y_STEP_PIN P1_10 +#define Y_DIR_PIN P1_14 +#define Y_ENABLE_PIN P1_08 -#define Z_STEP_PIN P1_17 -#define Z_DIR_PIN P4_29 -#define Z_ENABLE_PIN P1_15 +#define Z_STEP_PIN P1_17 +#define Z_DIR_PIN P4_29 +#define Z_ENABLE_PIN P1_15 -#define E0_STEP_PIN P0_05 -#define E0_DIR_PIN P2_00 -#define E0_ENABLE_PIN P4_28 +#define E0_STEP_PIN P0_05 +#define E0_DIR_PIN P2_00 +#define E0_ENABLE_PIN P4_28 -#define E1_STEP_PIN P2_03 -#define E1_DIR_PIN P2_04 -#define E1_ENABLE_PIN P2_01 +#define E1_STEP_PIN P2_03 +#define E1_DIR_PIN P2_04 +#define E1_ENABLE_PIN P2_01 -#define E2_STEP_PIN P2_07 -#define E2_DIR_PIN P2_08 -#define E2_ENABLE_PIN P2_05 +#define E2_STEP_PIN P2_07 +#define E2_DIR_PIN P2_08 +#define E2_ENABLE_PIN P2_05 // // TMC2208 UART pins // #if HAS_TMC_UART - #define X_SERIAL_TX_PIN P1_00 - #define X_SERIAL_RX_PIN P1_00 - #define Y_SERIAL_TX_PIN P1_09 - #define Y_SERIAL_RX_PIN P1_09 - #define Z_SERIAL_TX_PIN P1_16 - #define Z_SERIAL_RX_PIN P1_16 - #define E0_SERIAL_TX_PIN P0_04 - #define E0_SERIAL_RX_PIN P0_04 - #define E1_SERIAL_TX_PIN P2_02 - #define E1_SERIAL_RX_PIN P2_02 - #define E2_SERIAL_TX_PIN P2_06 - #define E2_SERIAL_RX_PIN P2_06 + #define X_SERIAL_TX_PIN P1_00 + #define X_SERIAL_RX_PIN P1_00 + #define Y_SERIAL_TX_PIN P1_09 + #define Y_SERIAL_RX_PIN P1_09 + #define Z_SERIAL_TX_PIN P1_16 + #define Z_SERIAL_RX_PIN P1_16 + #define E0_SERIAL_TX_PIN P0_04 + #define E0_SERIAL_RX_PIN P0_04 + #define E1_SERIAL_TX_PIN P2_02 + #define E1_SERIAL_RX_PIN P2_02 + #define E2_SERIAL_TX_PIN P2_06 + #define E2_SERIAL_RX_PIN P2_06 // Reduce baud rate to improve software serial reliability - #define TMC_BAUD_RATE 19200 + #define TMC_BAUD_RATE 19200 #else #error "TMC2208 UART configuration is required for GMarsh X6." #endif @@ -106,36 +106,36 @@ // Temperature Sensors // 3.3V max when defined as an analog input // -#define TEMP_0_PIN P0_24_A1 // AD0[0] on P0_23 -#define TEMP_BED_PIN P0_23_A0 // AD0[1] on P0_24 +#define TEMP_0_PIN P0_24_A1 // AD0[0] on P0_23 +#define TEMP_BED_PIN P0_23_A0 // AD0[1] on P0_24 // // Heaters / Fans // -#define HEATER_BED_PIN P1_19 // Not a PWM pin, software PWM required -#define HEATER_0_PIN P3_26 // PWM1[3] -#define FAN_PIN P3_25 // Part cooling fan - connected to PWM1[2] -#define E0_AUTO_FAN_PIN P0_27 // Extruder cooling fan +#define HEATER_BED_PIN P1_19 // Not a PWM pin, software PWM required +#define HEATER_0_PIN P3_26 // PWM1[3] +#define FAN_PIN P3_25 // Part cooling fan - connected to PWM1[2] +#define E0_AUTO_FAN_PIN P0_27 // Extruder cooling fan // // Misc. Functions // -#define LED_PIN P1_31 +#define LED_PIN P1_31 // // LCD // #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) - #define BEEPER_PIN P0_19 - #define BTN_EN1 P1_23 - #define BTN_EN2 P1_24 - #define BTN_ENC P1_25 - #define LCD_PINS_RS P0_20 - #define LCD_PINS_ENABLE P0_21 - #define LCD_PINS_D4 P2_11 - #define LCD_PINS_D5 P0_22 - #define LCD_PINS_D6 P1_29 - #define LCD_PINS_D7 P1_28 + #define BEEPER_PIN P0_19 + #define BTN_EN1 P1_23 + #define BTN_EN2 P1_24 + #define BTN_ENC P1_25 + #define LCD_PINS_RS P0_20 + #define LCD_PINS_ENABLE P0_21 + #define LCD_PINS_D4 P2_11 + #define LCD_PINS_D5 P0_22 + #define LCD_PINS_D6 P1_29 + #define LCD_PINS_D7 P1_28 #endif // @@ -143,21 +143,21 @@ // #ifndef SDCARD_CONNECTION - #define SDCARD_CONNECTION LCD + #define SDCARD_CONNECTION LCD #endif -#define ONBOARD_SD_CS_PIN P0_06 // Chip select for "System" SD card +#define ONBOARD_SD_CS_PIN P0_06 // Chip select for "System" SD card #if SD_CONNECTION_IS(LCD) - #define SCK_PIN P0_15 - #define MISO_PIN P0_17 - #define MOSI_PIN P0_18 - #define SS_PIN P0_16 + #define SCK_PIN P0_15 + #define MISO_PIN P0_17 + #define MOSI_PIN P0_18 + #define SS_PIN P0_16 #elif SD_CONNECTION_IS(ONBOARD) #undef SD_DETECT_PIN - #define SD_DETECT_PIN P0_27 - #define SCK_PIN P0_07 - #define MISO_PIN P0_08 - #define MOSI_PIN P0_09 - #define SS_PIN ONBOARD_SD_CS_PIN + #define SD_DETECT_PIN P0_27 + #define SCK_PIN P0_07 + #define MISO_PIN P0_08 + #define MOSI_PIN P0_09 + #define SS_PIN ONBOARD_SD_CS_PIN #endif diff --git a/Marlin/src/pins/lpc1768/pins_MKS_SBASE.h b/Marlin/src/pins/lpc1768/pins_MKS_SBASE.h index b3dba6794c9a..6c6a9ea306ec 100644 --- a/Marlin/src/pins/lpc1768/pins_MKS_SBASE.h +++ b/Marlin/src/pins/lpc1768/pins_MKS_SBASE.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,9 +25,9 @@ * MKS SBASE pin assignments */ -#if defined(MKS_HAS_LPC1769) && !defined(MCU_LPC1769) +#if defined(MKS_HAS_LPC1769) && NOT_TARGET(MCU_LPC1769) #error "Oops! Make sure you have the LPC1769 environment selected in your IDE." -#elif !defined(MKS_HAS_LPC1769) && !defined(MCU_LPC1768) +#elif NOT_TARGET(MKS_HAS_LPC1769, MCU_LPC1768) #error "Oops! Make sure you have the LPC1768 environment selected in your IDE." #endif @@ -38,73 +38,73 @@ #define BOARD_WEBSITE_URL "github.com/makerbase-mks/MKS-SBASE" #endif -#define LED_PIN P1_18 // Used as a status indicator -#define LED2_PIN P1_19 -#define LED3_PIN P1_20 -#define LED4_PIN P1_21 +#define LED_PIN P1_18 // Used as a status indicator +#define LED2_PIN P1_19 +#define LED3_PIN P1_20 +#define LED4_PIN P1_21 // // Servos // -#define SERVO0_PIN P1_23 // J8-3 (low jitter) -#define SERVO1_PIN P2_12 // J8-4 -#define SERVO2_PIN P2_11 // J8-5 -#define SERVO3_PIN P4_28 // J8-6 +#define SERVO0_PIN P1_23 // J8-3 (low jitter) +#define SERVO1_PIN P2_12 // J8-4 +#define SERVO2_PIN P2_11 // J8-5 +#define SERVO3_PIN P4_28 // J8-6 // // Limit Switches - Not Interrupt Capable // -#define X_MIN_PIN P1_24 // 10k pullup to 3.3V, 1K series -#define X_MAX_PIN P1_25 // 10k pullup to 3.3V, 1K series -#define Y_MIN_PIN P1_26 // 10k pullup to 3.3V, 1K series -#define Y_MAX_PIN P1_27 // 10k pullup to 3.3V, 1K series -#define Z_MIN_PIN P1_28 // The original Mks Sbase DIO19 has a 10k pullup to 3.3V or 5V, 1K series, so when using a Zprobe we must use DIO41 (J8 P1.22) -#define Z_MAX_PIN P1_29 // 10k pullup to 3.3V, 1K series +#define X_MIN_PIN P1_24 // 10k pullup to 3.3V, 1K series +#define X_MAX_PIN P1_25 // 10k pullup to 3.3V, 1K series +#define Y_MIN_PIN P1_26 // 10k pullup to 3.3V, 1K series +#define Y_MAX_PIN P1_27 // 10k pullup to 3.3V, 1K series +#define Z_MIN_PIN P1_28 // The original Mks Sbase DIO19 has a 10k pullup to 3.3V or 5V, 1K series, so when using a Zprobe we must use DIO41 (J8 P1.22) +#define Z_MAX_PIN P1_29 // 10k pullup to 3.3V, 1K series #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN P4_28 // Connector J8 + #define Z_MIN_PROBE_PIN P4_28 // Connector J8 #endif // // Steppers // -#define X_STEP_PIN P2_00 -#define X_DIR_PIN P0_05 -#define X_ENABLE_PIN P0_04 +#define X_STEP_PIN P2_00 +#define X_DIR_PIN P0_05 +#define X_ENABLE_PIN P0_04 -#define Y_STEP_PIN P2_01 -#define Y_DIR_PIN P0_11 -#define Y_ENABLE_PIN P0_10 +#define Y_STEP_PIN P2_01 +#define Y_DIR_PIN P0_11 +#define Y_ENABLE_PIN P0_10 -#define Z_STEP_PIN P2_02 -#define Z_DIR_PIN P0_20 -#define Z_ENABLE_PIN P0_19 +#define Z_STEP_PIN P2_02 +#define Z_DIR_PIN P0_20 +#define Z_ENABLE_PIN P0_19 -#define E0_STEP_PIN P2_03 -#define E0_DIR_PIN P0_22 -#define E0_ENABLE_PIN P0_21 +#define E0_STEP_PIN P2_03 +#define E0_DIR_PIN P0_22 +#define E0_ENABLE_PIN P0_21 -#define E1_STEP_PIN P2_08 -#define E1_DIR_PIN P2_13 -#define E1_ENABLE_PIN P4_29 +#define E1_STEP_PIN P2_08 +#define E1_DIR_PIN P2_13 +#define E1_ENABLE_PIN P4_29 // // Temperature Sensors // 3.3V max when defined as an analog input // -#define TEMP_BED_PIN P0_23_A0 // A0 (TH1) -#define TEMP_0_PIN P0_24_A1 // A1 (TH2) -#define TEMP_1_PIN P0_25_A2 // A2 (TH3) -#define TEMP_2_PIN P0_26_A3 // A3 (TH4) +#define TEMP_BED_PIN P0_23_A0 // A0 (TH1) +#define TEMP_0_PIN P0_24_A1 // A1 (TH2) +#define TEMP_1_PIN P0_25_A2 // A2 (TH3) +#define TEMP_2_PIN P0_26_A3 // A3 (TH4) // // Heaters / Fans // -#define HEATER_BED_PIN P2_05 -#define HEATER_0_PIN P2_07 -#define HEATER_1_PIN P2_06 +#define HEATER_BED_PIN P2_05 +#define HEATER_0_PIN P2_07 +#define HEATER_1_PIN P2_06 #ifndef FAN_PIN - #define FAN_PIN P2_04 + #define FAN_PIN P2_04 #endif // @@ -116,56 +116,56 @@ // 5V // NC // GND -#define PIN_P0_17 P0_17 -#define PIN_P0_16 P0_16 -#define PIN_P0_15 P0_15 +#define PIN_P0_17 P0_17 +#define PIN_P0_16 P0_16 +#define PIN_P0_15 P0_15 // // Connector J8 // // GND -#define PIN_P1_22 P1_22 -#define PIN_P1_23 P1_23 // PWM Capable -#define PIN_P2_12 P2_12 // Interrupt Capable -#define PIN_P2_11 P2_11 // Interrupt Capable +#define PIN_P1_22 P1_22 +#define PIN_P1_23 P1_23 // PWM Capable +#define PIN_P2_12 P2_12 // Interrupt Capable +#define PIN_P2_11 P2_11 // Interrupt Capable // // Průša i3 MK2 Multi Material Multiplexer Support // #if ENABLED(MK2_MULTIPLEXER) - #define E_MUX0_PIN P1_23 // J8-3 - #define E_MUX1_PIN P2_12 // J8-4 - #define E_MUX2_PIN P2_11 // J8-5 + #define E_MUX0_PIN P1_23 // J8-3 + #define E_MUX1_PIN P2_12 // J8-4 + #define E_MUX2_PIN P2_11 // J8-5 #endif // // Misc. Functions // -#define PS_ON_PIN P0_25 // TH3 Connector +#define PS_ON_PIN P0_25 // TH3 Connector // // Ethernet pins // #ifndef ULTIPANEL - #define ENET_MDIO P1_17 // J12-4 - #define ENET_RX_ER P1_14 // J12-6 - #define ENET_RXD1 P1_10 // J12-8 + #define ENET_MDIO P1_17 // J12-4 + #define ENET_RX_ER P1_14 // J12-6 + #define ENET_RXD1 P1_10 // J12-8 #endif -#define ENET_MOC P1_16 // J12-3 -#define REF_CLK P1_15 // J12-5 -#define ENET_RXD0 P1_09 // J12-7 -#define ENET_CRS P1_08 // J12-9 -#define ENET_TX_EN P1_04 // J12-10 -#define ENET_TXD0 P1_00 // J12-11 -#define ENET_TXD1 P1_01 // J12-12 +#define ENET_MOC P1_16 // J12-3 +#define REF_CLK P1_15 // J12-5 +#define ENET_RXD0 P1_09 // J12-7 +#define ENET_CRS P1_08 // J12-9 +#define ENET_TX_EN P1_04 // J12-10 +#define ENET_TXD0 P1_00 // J12-11 +#define ENET_TXD1 P1_01 // J12-12 #ifndef SDCARD_CONNECTION - #define SDCARD_CONNECTION ONBOARD + #define SDCARD_CONNECTION ONBOARD #endif -#define ONBOARD_SD_CS_PIN P0_06 // Chip select for "System" SD card +#define ONBOARD_SD_CS_PIN P0_06 // Chip select for "System" SD card #if SD_CONNECTION_IS(CUSTOM_CABLE) @@ -181,27 +181,27 @@ * If you can't find a pin to use for the LCD's SD_DETECT then comment out * SD_DETECT_PIN entirely and remove that wire from the the custom cable. */ - #define SD_DETECT_PIN P2_11 // J8-5 (moved from EXP2 P0.27) - #define SCK_PIN P1_22 // J8-2 (moved from EXP2 P0.7) - #define MISO_PIN P1_23 // J8-3 (moved from EXP2 P0.8) - #define MOSI_PIN P2_12 // J8-4 (moved from EXP2 P0.9) - #define SS_PIN P0_28 - #define LPC_SOFTWARE_SPI // With a custom cable we need software SPI because the - // selected pins are not on a hardware SPI controller + #define SD_DETECT_PIN P2_11 // J8-5 (moved from EXP2 P0.27) + #define SCK_PIN P1_22 // J8-2 (moved from EXP2 P0.7) + #define MISO_PIN P1_23 // J8-3 (moved from EXP2 P0.8) + #define MOSI_PIN P2_12 // J8-4 (moved from EXP2 P0.9) + #define SS_PIN P0_28 + #define LPC_SOFTWARE_SPI // With a custom cable we need software SPI because the + // selected pins are not on a hardware SPI controller #elif SD_CONNECTION_IS(LCD) // use standard cable and header, SPI and SD detect sre shared with on-board SD card // hardware SPI is used for both SD cards. The detect pin is shred between the // LCD and onboard SD readers so we disable it. - #define SCK_PIN P0_07 - #define MISO_PIN P0_08 - #define MOSI_PIN P0_09 - #define SS_PIN P0_28 + #define SCK_PIN P0_07 + #define MISO_PIN P0_08 + #define MOSI_PIN P0_09 + #define SS_PIN P0_28 #elif SD_CONNECTION_IS(ONBOARD) - #define SD_DETECT_PIN P0_27 - #define SCK_PIN P0_07 - #define MISO_PIN P0_08 - #define MOSI_PIN P0_09 - #define SS_PIN ONBOARD_SD_CS_PIN + #define SD_DETECT_PIN P0_27 + #define SCK_PIN P0_07 + #define MISO_PIN P0_08 + #define MOSI_PIN P0_09 + #define SS_PIN ONBOARD_SD_CS_PIN #endif /** @@ -217,18 +217,29 @@ * that the garbage/lines are erased immediately after the SD card accesses are completed. */ -#if HAS_SPI_LCD - #define BEEPER_PIN P1_31 // EXP1.1 - #define BTN_ENC P1_30 // EXP1.2 - #define BTN_EN1 P3_26 // EXP2.5 - #define BTN_EN2 P3_25 // EXP2.3 - #define LCD_PINS_RS P0_16 // EXP1.4 - #define LCD_SDSS P0_28 // EXP2.4 - #define LCD_PINS_ENABLE P0_18 // EXP1.3 - #define LCD_PINS_D4 P0_15 // EXP1.5 +#if IS_TFTGLCD_PANEL + + #if ENABLED(TFTGLCD_PANEL_SPI) + #define TFTGLCD_CS P3_25 // EXP2.3 + #endif + + #if SD_CONNECTION_IS(LCD) + #define SD_DETECT_PIN P0_28 // EXP2.4 + #endif + +#elif HAS_WIRED_LCD + + #define BEEPER_PIN P1_31 // EXP1.1 + #define BTN_ENC P1_30 // EXP1.2 + #define BTN_EN1 P3_26 // EXP2.5 + #define BTN_EN2 P3_25 // EXP2.3 + #define LCD_PINS_RS P0_16 // EXP1.4 + #define LCD_SDSS P0_28 // EXP2.4 + #define LCD_PINS_ENABLE P0_18 // EXP1.3 + #define LCD_PINS_D4 P0_15 // EXP1.5 #if ANY(VIKI2, miniVIKI) - #define DOGLCD_SCK SCK_PIN - #define DOGLCD_MOSI MOSI_PIN + #define DOGLCD_SCK SCK_PIN + #define DOGLCD_MOSI MOSI_PIN #endif #if ENABLED(FYSETC_MINI_12864) @@ -243,26 +254,26 @@ * Pins 6, 7 & 8 on EXP2 are no connects. That means a second special * cable will be needed if the RGB LEDs are to be active. */ - #define DOGLCD_CS LCD_PINS_ENABLE // EXP1.3 (LCD_EN on FYSETC schematic) - #define DOGLCD_A0 LCD_PINS_RS // EXP1.4 (LCD_A0 on FYSETC schematic) - #define DOGLCD_SCK P2_11 // J8-5 (SCK on FYSETC schematic) - #define DOGLCD_MOSI P4_28 // J8-6 (MOSI on FYSETC schematic) + #define DOGLCD_CS LCD_PINS_ENABLE // EXP1.3 (LCD_EN on FYSETC schematic) + #define DOGLCD_A0 LCD_PINS_RS // EXP1.4 (LCD_A0 on FYSETC schematic) + #define DOGLCD_SCK P2_11 // J8-5 (SCK on FYSETC schematic) + #define DOGLCD_MOSI P4_28 // J8-6 (MOSI on FYSETC schematic) - //#define FORCE_SOFT_SPI // Use this if default of hardware SPI causes display problems - // results in LCD soft SPI mode 3, SD soft SPI mode 0 + //#define FORCE_SOFT_SPI // Use this if default of hardware SPI causes display problems + // results in LCD soft SPI mode 3, SD soft SPI mode 0 #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) #ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN P2_12 // J8-4 (LCD_D6 on FYSETC schematic) + #define RGB_LED_R_PIN P2_12 // J8-4 (LCD_D6 on FYSETC schematic) #endif #ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN P1_23 // J8-3 (LCD_D5 on FYSETC schematic) + #define RGB_LED_G_PIN P1_23 // J8-3 (LCD_D5 on FYSETC schematic) #endif #ifndef RGB_LED_B_PIN - #define RGB_LED_B_PIN P1_22 // J8-2 (LCD_D7 on FYSETC schematic) + #define RGB_LED_B_PIN P1_22 // J8-2 (LCD_D7 on FYSETC schematic) #endif #elif ENABLED(FYSETC_MINI_12864_2_1) - #define NEOPIXEL_PIN P2_12 + #define NEOPIXEL_PIN P2_12 #endif #elif ENABLED(MINIPANEL) @@ -273,7 +284,7 @@ //#define LCD_SCREEN_ROT_270 #endif -#endif +#endif // HAS_WIRED_LCD /** * Example for trinamic drivers using the J8 connector on MKs Sbase. @@ -283,29 +294,30 @@ #if HAS_DRIVER(TMC2130) // J8 - #define X_CS_PIN P1_22 - #define Y_CS_PIN P1_23 - #define Z_CS_PIN P2_12 - #define E0_CS_PIN P2_11 - #define E1_CS_PIN P4_28 - -// Hardware SPI is on EXP2. See if you can make it work: -// https://github.com/makerbase-mks/MKS-SBASE/issues/25 -#define TMC_USE_SW_SPI -#if ENABLED(TMC_USE_SW_SPI) - #ifndef TMC_SW_MOSI - #define TMC_SW_MOSI P0_03 // AUX1 - #endif - #ifndef TMC_SW_MISO - #define TMC_SW_MISO P0_02 // AUX1 - #endif - #ifndef TMC_SW_SCK - #define TMC_SW_SCK P0_26 // TH4 + #define X_CS_PIN P1_22 + #define Y_CS_PIN P1_23 + #define Z_CS_PIN P2_12 + #define E0_CS_PIN P2_11 + #define E1_CS_PIN P4_28 + + // Hardware SPI is on EXP2. See if you can make it work: + // https://github.com/makerbase-mks/MKS-SBASE/issues/25 + #define TMC_USE_SW_SPI + #if ENABLED(TMC_USE_SW_SPI) + #ifndef TMC_SW_MOSI + #define TMC_SW_MOSI P0_03 // AUX1 + #endif + #ifndef TMC_SW_MISO + #define TMC_SW_MISO P0_02 // AUX1 + #endif + #ifndef TMC_SW_SCK + #define TMC_SW_SCK P0_26 // TH4 + #endif #endif - #endif + #endif -#if MB(MKS_SBASE) && HAS_TMC220x +#if MB(MKS_SBASE) && HAS_TMC_UART /** * TMC2208/TMC2209 stepper drivers @@ -314,24 +326,24 @@ * Worst case you may have to give up the LCD * RX pins need to be interrupt capable */ - #define X_SERIAL_TX_PIN P1_22 // J8-2 - #define X_SERIAL_RX_PIN P2_12 // J8-4 Interrupt Capable - #define Y_SERIAL_TX_PIN P1_23 // J8-3 - #define Y_SERIAL_RX_PIN P2_11 // J8-5 Interrupt Capable - #define Z_SERIAL_TX_PIN P2_12 // J8-4 - #define Z_SERIAL_RX_PIN P0_25 // TH3 - #define E0_SERIAL_TX_PIN P4_28 // J8-6 - #define E0_SERIAL_RX_PIN P0_26 // TH4 + #define X_SERIAL_TX_PIN P1_22 // J8-2 + #define X_SERIAL_RX_PIN P2_12 // J8-4 Interrupt Capable + #define Y_SERIAL_TX_PIN P1_23 // J8-3 + #define Y_SERIAL_RX_PIN P2_11 // J8-5 Interrupt Capable + #define Z_SERIAL_TX_PIN P2_12 // J8-4 + #define Z_SERIAL_RX_PIN P0_25 // TH3 + #define E0_SERIAL_TX_PIN P4_28 // J8-6 + #define E0_SERIAL_RX_PIN P0_26 // TH4 // Reduce baud rate to improve software serial reliability - #define TMC_BAUD_RATE 19200 + #define TMC_BAUD_RATE 19200 #endif // UNUSED -#define PIN_P0_27 P0_27 // EXP2/Onboard SD -#define PIN_P0_28 P0_28 // EXP2 -#define PIN_P0_02 P0_02 // AUX1 (Interrupt Capable/ADC/Serial Port 0) -#define PIN_P0_03 P0_03 // AUX1 (Interrupt Capable/ADC/Serial Port 0) +#define PIN_P0_27 P0_27 // EXP2/Onboard SD +#define PIN_P0_28 P0_28 // EXP2 +#define PIN_P0_02 P0_02 // AUX1 (Interrupt Capable/ADC/Serial Port 0) +#define PIN_P0_03 P0_03 // AUX1 (Interrupt Capable/ADC/Serial Port 0) /** * PWMs @@ -360,7 +372,6 @@ * P1_31 - not 5V tolerant - EXP1 * P0_27 - open collector - EXP2 * P0_28 - open collector - EXP2 - * */ /** @@ -375,5 +386,4 @@ * P0_03 - AUX1 * P0_29 - Port -1 * P0_30 - USB - * */ diff --git a/Marlin/src/pins/lpc1768/pins_MKS_SGEN_L.h b/Marlin/src/pins/lpc1768/pins_MKS_SGEN_L.h index 58f9eb549337..d269ecbdc90d 100644 --- a/Marlin/src/pins/lpc1768/pins_MKS_SGEN_L.h +++ b/Marlin/src/pins/lpc1768/pins_MKS_SGEN_L.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * MKS SGEN-L pin assignments */ -#ifndef MCU_LPC1768 +#if NOT_TARGET(MCU_LPC1768) #error "Oops! Make sure you have the LPC1768 environment selected in your IDE." #endif @@ -35,100 +35,100 @@ // // Servos // -#define SERVO0_PIN P1_23 // SERVO P1.23 -#define SERVO1_PIN P2_00 // SERVO P2.0 +#define SERVO0_PIN P1_23 // SERVO P1.23 +#define SERVO1_PIN P2_00 // SERVO P2.0 // // Trinamic Stallguard pins // -#define X_DIAG_PIN P1_29 // X- -#define Y_DIAG_PIN P1_27 // Y- -#define Z_DIAG_PIN P1_25 // Z- -#define E0_DIAG_PIN P1_28 // X+ -#define E1_DIAG_PIN P1_26 // Y+ +#define X_DIAG_PIN P1_29 // X- +#define Y_DIAG_PIN P1_27 // Y- +#define Z_DIAG_PIN P1_25 // Z- +#define E0_DIAG_PIN P1_28 // X+ +#define E1_DIAG_PIN P1_26 // Y+ // // Limit Switches // -#if X_STALL_SENSITIVITY - #define X_STOP_PIN X_DIAG_PIN +#ifdef X_STALL_SENSITIVITY + #define X_STOP_PIN X_DIAG_PIN #if X_HOME_DIR < 0 - #define X_MAX_PIN P1_28 // X+ + #define X_MAX_PIN P1_28 // X+ #else - #define X_MIN_PIN P1_28 // X+ + #define X_MIN_PIN P1_28 // X+ #endif #else - #define X_MIN_PIN P1_29 // X- - #define X_MAX_PIN P1_28 // X+ + #define X_MIN_PIN P1_29 // X- + #define X_MAX_PIN P1_28 // X+ #endif -#if Y_STALL_SENSITIVITY - #define Y_STOP_PIN Y_DIAG_PIN +#ifdef Y_STALL_SENSITIVITY + #define Y_STOP_PIN Y_DIAG_PIN #if Y_HOME_DIR < 0 - #define Y_MAX_PIN P1_26 // Y+ + #define Y_MAX_PIN P1_26 // Y+ #else - #define Y_MIN_PIN P1_26 // Y+ + #define Y_MIN_PIN P1_26 // Y+ #endif #else - #define Y_MIN_PIN P1_27 // Y- - #define Y_MAX_PIN P1_26 // Y+ + #define Y_MIN_PIN P1_27 // Y- + #define Y_MAX_PIN P1_26 // Y+ #endif -#if Z_STALL_SENSITIVITY - #define Z_STOP_PIN Z_DIAG_PIN +#ifdef Z_STALL_SENSITIVITY + #define Z_STOP_PIN Z_DIAG_PIN #if Z_HOME_DIR < 0 - #define Z_MAX_PIN P1_24 // Z+ + #define Z_MAX_PIN P1_24 // Z+ #else - #define Z_MIN_PIN P1_24 // Z+ + #define Z_MIN_PIN P1_24 // Z+ #endif #else - #define Z_MIN_PIN P1_25 // Z- - #define Z_MAX_PIN P1_24 // Z+ + #define Z_MIN_PIN P1_25 // Z- + #define Z_MAX_PIN P1_24 // Z+ #endif // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN P1_24 + #define Z_MIN_PROBE_PIN P1_24 #endif // // Steppers // -#define X_STEP_PIN P2_02 -#define X_DIR_PIN P2_03 -#define X_ENABLE_PIN P2_01 +#define X_STEP_PIN P2_02 +#define X_DIR_PIN P2_03 +#define X_ENABLE_PIN P2_01 #ifndef X_CS_PIN - #define X_CS_PIN P1_01 + #define X_CS_PIN P1_01 #endif -#define Y_STEP_PIN P0_19 -#define Y_DIR_PIN P0_20 -#define Y_ENABLE_PIN P2_08 +#define Y_STEP_PIN P0_19 +#define Y_DIR_PIN P0_20 +#define Y_ENABLE_PIN P2_08 #ifndef Y_CS_PIN - #define Y_CS_PIN P1_08 + #define Y_CS_PIN P1_08 #endif -#define Z_STEP_PIN P0_22 -#define Z_DIR_PIN P2_11 -#define Z_ENABLE_PIN P0_21 +#define Z_STEP_PIN P0_22 +#define Z_DIR_PIN P2_11 +#define Z_ENABLE_PIN P0_21 #ifndef Z_CS_PIN - #define Z_CS_PIN P1_10 + #define Z_CS_PIN P1_10 #endif -#define E0_STEP_PIN P2_13 -#define E0_DIR_PIN P0_11 -#define E0_ENABLE_PIN P2_12 +#define E0_STEP_PIN P2_13 +#define E0_DIR_PIN P0_11 +#define E0_ENABLE_PIN P2_12 #ifndef E0_CS_PIN - #define E0_CS_PIN P1_15 + #define E0_CS_PIN P1_15 #endif -#define E1_STEP_PIN P0_01 -#define E1_DIR_PIN P0_00 -#define E1_ENABLE_PIN P0_10 +#define E1_STEP_PIN P0_01 +#define E1_DIR_PIN P0_00 +#define E1_ENABLE_PIN P0_10 #ifndef E1_CS_PIN - #define E1_CS_PIN P1_17 + #define E1_CS_PIN P1_17 #endif // @@ -136,24 +136,24 @@ // #if ENABLED(TMC_USE_SW_SPI) #ifndef TMC_SW_MOSI - #define TMC_SW_MOSI P4_28 + #define TMC_SW_MOSI P4_28 #endif #ifndef TMC_SW_MISO - #define TMC_SW_MISO P0_05 + #define TMC_SW_MISO P0_05 #endif #ifndef TMC_SW_SCK - #define TMC_SW_SCK P0_04 + #define TMC_SW_SCK P0_04 #endif #endif -#if HAS_TMC220x +#if HAS_TMC_UART /** * TMC2208/TMC2209 stepper drivers * * Hardware serial communication ports. * If undefined software serial is used according to the pins below */ - //#define X_HARDWARE_SERIAL Serial + //#define X_HARDWARE_SERIAL Serial1 //#define X2_HARDWARE_SERIAL Serial1 //#define Y_HARDWARE_SERIAL Serial1 //#define Y2_HARDWARE_SERIAL Serial1 @@ -169,150 +169,160 @@ // Software serial // - #define X_SERIAL_TX_PIN P1_04 - #define X_SERIAL_RX_PIN P1_01 + #define X_SERIAL_TX_PIN P1_04 + #define X_SERIAL_RX_PIN P1_01 - #define Y_SERIAL_TX_PIN P1_09 - #define Y_SERIAL_RX_PIN P1_08 + #define Y_SERIAL_TX_PIN P1_09 + #define Y_SERIAL_RX_PIN P1_08 - #define Z_SERIAL_TX_PIN P1_14 - #define Z_SERIAL_RX_PIN P1_10 + #define Z_SERIAL_TX_PIN P1_14 + #define Z_SERIAL_RX_PIN P1_10 - #define E0_SERIAL_TX_PIN P1_16 - #define E0_SERIAL_RX_PIN P1_15 + #define E0_SERIAL_TX_PIN P1_16 + #define E0_SERIAL_RX_PIN P1_15 - #define E1_SERIAL_TX_PIN P4_29 - #define E1_SERIAL_RX_PIN P1_17 + #define E1_SERIAL_TX_PIN P4_29 + #define E1_SERIAL_RX_PIN P1_17 - #define Z2_SERIAL_TX_PIN P4_29 - #define Z2_SERIAL_RX_PIN P1_17 + #define Z2_SERIAL_TX_PIN P4_29 + #define Z2_SERIAL_RX_PIN P1_17 // Reduce baud rate to improve software serial reliability - #define TMC_BAUD_RATE 19200 + #define TMC_BAUD_RATE 19200 #endif // TMC2208 || TMC2209 // // Temperature Sensors // 3.3V max when defined as an analog input // -#define TEMP_0_PIN P0_23_A0 // Analog Input A0 (TH1) -#define TEMP_BED_PIN P0_24_A1 // Analog Input A1 (TB) -#define TEMP_1_PIN P0_25_A2 // Analog Input A2 (TH2) +#define TEMP_0_PIN P0_23_A0 // Analog Input A0 (TH1) +#define TEMP_BED_PIN P0_24_A1 // Analog Input A1 (TB) +#define TEMP_1_PIN P0_25_A2 // Analog Input A2 (TH2) // // Heaters / Fans // -#define HEATER_BED_PIN P2_05 -#define HEATER_0_PIN P2_07 +#define HEATER_BED_PIN P2_05 +#define HEATER_0_PIN P2_07 #if HOTENDS == 1 #ifndef FAN1_PIN - #define FAN1_PIN P2_06 + #define FAN1_PIN P2_06 #endif #else #ifndef HEATER_1_PIN - #define HEATER_1_PIN P2_06 + #define HEATER_1_PIN P2_06 #endif #endif #ifndef FAN_PIN - #define FAN_PIN P2_04 + #define FAN_PIN P2_04 #endif // // Misc. Functions // -#define LED_PIN P1_18 // Used as a status indicator -#define LED2_PIN P1_19 -#define LED3_PIN P1_20 -#define LED4_PIN P1_21 +#define LED_PIN P1_18 // Used as a status indicator +#define LED2_PIN P1_19 +#define LED3_PIN P1_20 +#define LED4_PIN P1_21 /** * _____ _____ * (BEEPER) 1.31 | · · | 1.30 (BTN_ENC) (MISO) 0.8 | · · | 0.7 (SD_SCK) * (LCD_EN) 0.18 | · · | 0.16 (LCD_RS) (BTN_EN1) 3.25 | · · | 0.28 (SD_CS2) - * (LCD_D4) 0.15 | · · | 0.17 (LCD_D5) (BTN_EN2) 3.26 | · · | 1.20 (SD_MOSI) + * (LCD_D4) 0.15 | · · | 0.17 (LCD_D5) (BTN_EN2) 3.26 | · · | 0.9 (SD_MOSI) * (LCD_D6) 1.0 | · · | 1.22 (LCD_D7) (SD_DETECT) 0.27 | · · | RST * GND | · · | 5V GND | · · | NC * ----- ----- * EXP1 EXP2 */ -#if HAS_SPI_LCD - #define BEEPER_PIN P1_31 - #define BTN_ENC P1_30 +#if HAS_WIRED_LCD + + #define BEEPER_PIN P1_31 + #define BTN_ENC P1_30 #if ENABLED(CR10_STOCKDISPLAY) - #define LCD_PINS_RS P1_00 + #define LCD_PINS_RS P1_00 + + #define BTN_EN1 P0_18 + #define BTN_EN2 P0_15 + + #define LCD_PINS_ENABLE P1_22 + #define LCD_PINS_D4 P0_17 + + #elif IS_TFTGLCD_PANEL - #define BTN_EN1 P0_18 - #define BTN_EN2 P0_15 + #undef BEEPER_PIN + #undef BTN_ENC - #define LCD_PINS_ENABLE P1_22 - #define LCD_PINS_D4 P0_17 + #if ENABLED(TFTGLCD_PANEL_SPI) + #define TFTGLCD_CS P3_25 + #endif #else - #define BTN_EN1 P3_25 - #define BTN_EN2 P3_26 + #define BTN_EN1 P3_25 + #define BTN_EN2 P3_26 - #define LCD_SDSS P0_28 + #define LCD_SDSS P0_28 #if ENABLED(MKS_12864OLED_SSD1306) - #define LCD_PINS_DC P0_17 - #define DOGLCD_CS P0_16 - #define DOGLCD_A0 LCD_PINS_DC - #define DOGLCD_SCK P0_15 - #define DOGLCD_MOSI P0_18 + #define LCD_PINS_DC P0_17 + #define DOGLCD_CS P0_16 + #define DOGLCD_A0 LCD_PINS_DC + #define DOGLCD_SCK P0_15 + #define DOGLCD_MOSI P0_18 - #define LCD_PINS_RS P1_00 - #define LCD_PINS_D7 P1_22 - #define KILL_PIN -1 // NC + #define LCD_PINS_RS P1_00 + #define LCD_PINS_D7 P1_22 + #define KILL_PIN -1 // NC - #else // !MKS_12864OLED_SSD1306 + #else // !MKS_12864OLED_SSD1306 - #define LCD_PINS_RS P0_16 + #define LCD_PINS_RS P0_16 - #define LCD_PINS_ENABLE P0_18 - #define LCD_PINS_D4 P0_15 + #define LCD_PINS_ENABLE P0_18 + #define LCD_PINS_D4 P0_15 #if ENABLED(FYSETC_MINI_12864) - #define DOGLCD_CS P0_18 - #define DOGLCD_A0 P0_16 - #define DOGLCD_SCK P0_07 - #define DOGLCD_MOSI P1_20 + #define DOGLCD_CS P0_18 + #define DOGLCD_A0 P0_16 + #define DOGLCD_SCK P0_07 + #define DOGLCD_MOSI P0_09 - #define LCD_BACKLIGHT_PIN -1 + #define LCD_BACKLIGHT_PIN -1 - #define FORCE_SOFT_SPI // Use this if default of hardware SPI causes display problems - // results in LCD soft SPI mode 3, SD soft SPI mode 0 + #define FORCE_SOFT_SPI // Use this if default of hardware SPI causes display problems + // results in LCD soft SPI mode 3, SD soft SPI mode 0 - #define LCD_RESET_PIN P0_15 // Must be high or open for LCD to operate normally. + #define LCD_RESET_PIN P0_15 // Must be high or open for LCD to operate normally. #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) #ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN P0_17 + #define RGB_LED_R_PIN P0_17 #endif #ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN P1_00 + #define RGB_LED_G_PIN P1_00 #endif #ifndef RGB_LED_B_PIN - #define RGB_LED_B_PIN P1_22 + #define RGB_LED_B_PIN P1_22 #endif #elif ENABLED(FYSETC_MINI_12864_2_1) - #define NEOPIXEL_PIN P0_17 + #define NEOPIXEL_PIN P0_17 #endif - #else // !FYSETC_MINI_12864 + #else // !FYSETC_MINI_12864 #if ENABLED(MKS_MINI_12864) - #define DOGLCD_CS P0_17 - #define DOGLCD_A0 P1_00 + #define DOGLCD_CS P0_17 + #define DOGLCD_A0 P1_00 #endif #if ENABLED(ULTIPANEL) - #define LCD_PINS_D5 P0_17 - #define LCD_PINS_D6 P1_00 - #define LCD_PINS_D7 P1_22 + #define LCD_PINS_D5 P0_17 + #define LCD_PINS_D6 P1_00 + #define LCD_PINS_D7 P1_22 #endif #endif // !FYSETC_MINI_12864 @@ -321,23 +331,23 @@ #endif // !CR10_STOCKDISPLAY -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD #ifndef SDCARD_CONNECTION - #define SDCARD_CONNECTION ONBOARD + #define SDCARD_CONNECTION ONBOARD #endif -#define ONBOARD_SD_CS_PIN P0_06 // Chip select for "System" SD card +#define ONBOARD_SD_CS_PIN P0_06 // Chip select for "System" SD card #if SD_CONNECTION_IS(LCD) || SD_CONNECTION_IS(ONBOARD) - #define SD_DETECT_PIN P0_27 - #define SCK_PIN P0_07 - #define MISO_PIN P0_08 - #define MOSI_PIN P0_09 + #define SD_DETECT_PIN P0_27 + #define SCK_PIN P0_07 + #define MISO_PIN P0_08 + #define MOSI_PIN P0_09 #if SD_CONNECTION_IS(ONBOARD) - #define SS_PIN ONBOARD_SD_CS_PIN + #define SS_PIN ONBOARD_SD_CS_PIN #else - #define SS_PIN P0_28 + #define SS_PIN P0_28 #endif #elif SD_CONNECTION_IS(CUSTOM_CABLE) #error "No custom SD drive cable defined for this board." @@ -346,6 +356,6 @@ // // Other Pins // -//#define PIN_P0_02 P0_02 // AUX1 (Interrupt Capable/ADC/Serial Port 0) -//#define PIN_P0_03 P0_03 // AUX1 (Interrupt Capable/ADC/Serial Port 0) -//#define PS_ON_PIN P1_23 // SERVO P1.23 +//#define PIN_P0_02 P0_02 // AUX1 (Interrupt Capable/ADC/Serial Port 0) +//#define PIN_P0_03 P0_03 // AUX1 (Interrupt Capable/ADC/Serial Port 0) +//#define PS_ON_PIN P1_23 // SERVO P1.23 diff --git a/Marlin/src/pins/lpc1768/pins_RAMPS_RE_ARM.h b/Marlin/src/pins/lpc1768/pins_RAMPS_RE_ARM.h index bf989798fd1d..294e7527a875 100644 --- a/Marlin/src/pins/lpc1768/pins_RAMPS_RE_ARM.h +++ b/Marlin/src/pins/lpc1768/pins_RAMPS_RE_ARM.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -31,12 +31,11 @@ * RAMPS_14_EFF (Hotend, Fan0, Fan1) * RAMPS_14_EEF (Hotend0, Hotend1, Fan) * RAMPS_14_SF (Spindle, Controller Fan) - * */ // Numbers in parentheses () are the corresponding mega2560 pin numbers -#ifndef MCU_LPC1768 +#if NOT_TARGET(MCU_LPC1768) #error "Oops! Make sure you have the LPC1768 environment selected in your IDE." #endif @@ -45,58 +44,58 @@ // // Servos // -#define SERVO0_PIN P1_20 // (11) -#define SERVO1_PIN P1_21 // ( 6) also on J5-1 -#define SERVO2_PIN P1_19 // ( 5) -#define SERVO3_PIN P1_18 // ( 4) 5V output +#define SERVO0_PIN P1_20 // (11) +#define SERVO1_PIN P1_21 // ( 6) also on J5-1 +#define SERVO2_PIN P1_19 // ( 5) +#define SERVO3_PIN P1_18 // ( 4) 5V output // // Limit Switches // -#define X_MIN_PIN P1_24 // ( 3) 10k pullup to 3.3V, 1K series -#define X_MAX_PIN P1_25 // ( 2) 10k pullup to 3.3V, 1K series -#define Y_MIN_PIN P1_26 // (14) 10k pullup to 3.3V, 1K series -#define Y_MAX_PIN P1_27 // (15) 10k pullup to 3.3V, 1K series -#define Z_MIN_PIN P1_29 // (18) 10k pullup to 3.3V, 1K series -#define Z_MAX_PIN P1_28 // (19) 10k pullup to 3.3V, 1K series -#define ONBOARD_ENDSTOPPULLUPS // Board has built-in pullups +#define X_MIN_PIN P1_24 // ( 3) 10k pullup to 3.3V, 1K series +#define X_MAX_PIN P1_25 // ( 2) 10k pullup to 3.3V, 1K series +#define Y_MIN_PIN P1_26 // (14) 10k pullup to 3.3V, 1K series +#define Y_MAX_PIN P1_27 // (15) 10k pullup to 3.3V, 1K series +#define Z_MIN_PIN P1_29 // (18) 10k pullup to 3.3V, 1K series +#define Z_MAX_PIN P1_28 // (19) 10k pullup to 3.3V, 1K series +#define ONBOARD_ENDSTOPPULLUPS // Board has built-in pullups // // Steppers // -#define X_STEP_PIN P2_01 // (54) -#define X_DIR_PIN P0_11 // (55) -#define X_ENABLE_PIN P0_10 // (38) +#define X_STEP_PIN P2_01 // (54) +#define X_DIR_PIN P0_11 // (55) +#define X_ENABLE_PIN P0_10 // (38) #ifndef X_CS_PIN - #define X_CS_PIN P1_01 // ETH + #define X_CS_PIN P1_01 // ETH #endif -#define Y_STEP_PIN P2_02 // (60) -#define Y_DIR_PIN P0_20 // (61) -#define Y_ENABLE_PIN P0_19 // (56) +#define Y_STEP_PIN P2_02 // (60) +#define Y_DIR_PIN P0_20 // (61) +#define Y_ENABLE_PIN P0_19 // (56) #ifndef Y_CS_PIN - #define Y_CS_PIN P1_04 // ETH + #define Y_CS_PIN P1_04 // ETH #endif -#define Z_STEP_PIN P2_03 // (46) -#define Z_DIR_PIN P0_22 // (48) -#define Z_ENABLE_PIN P0_21 // (62) +#define Z_STEP_PIN P2_03 // (46) +#define Z_DIR_PIN P0_22 // (48) +#define Z_ENABLE_PIN P0_21 // (62) #ifndef Z_CS_PIN - #define Z_CS_PIN P1_10 // ETH + #define Z_CS_PIN P1_10 // ETH #endif -#define E0_STEP_PIN P2_00 // (26) -#define E0_DIR_PIN P0_05 // (28) -#define E0_ENABLE_PIN P0_04 // (24) +#define E0_STEP_PIN P2_00 // (26) +#define E0_DIR_PIN P0_05 // (28) +#define E0_ENABLE_PIN P0_04 // (24) #ifndef E0_CS_PIN - #define E0_CS_PIN P1_14 // ETH + #define E0_CS_PIN P1_14 // ETH #endif -#define E1_STEP_PIN P2_08 // (36) -#define E1_DIR_PIN P2_13 // (34) -#define E1_ENABLE_PIN P4_29 // (30) +#define E1_STEP_PIN P2_08 // (36) +#define E1_DIR_PIN P2_13 // (34) +#define E1_ENABLE_PIN P4_29 // (30) #ifndef E1_CS_PIN - #define E1_CS_PIN -1 + #define E1_CS_PIN -1 #endif // @@ -104,17 +103,17 @@ // #if ENABLED(TMC_USE_SW_SPI) #ifndef TMC_SW_MOSI - #define TMC_SW_MOSI P1_00 // ETH + #define TMC_SW_MOSI P1_00 // ETH #endif #ifndef TMC_SW_MISO - #define TMC_SW_MISO P1_08 // ETH + #define TMC_SW_MISO P1_08 // ETH #endif #ifndef TMC_SW_SCK - #define TMC_SW_SCK P1_09 // ETH + #define TMC_SW_SCK P1_09 // ETH #endif #endif -#if HAS_TMC220x +#if HAS_TMC_UART /** * TMC2208/TMC2209 stepper drivers * @@ -130,55 +129,55 @@ // P2_13 E1-Dir #ifndef X_SERIAL_TX_PIN - #define X_SERIAL_TX_PIN P0_01 + #define X_SERIAL_TX_PIN P0_01 #endif #ifndef X_SERIAL_RX_PIN - #define X_SERIAL_RX_PIN P0_01 + #define X_SERIAL_RX_PIN P0_01 #endif #ifndef Y_SERIAL_TX_PIN - #define Y_SERIAL_TX_PIN P0_00 + #define Y_SERIAL_TX_PIN P0_00 #endif #ifndef Y_SERIAL_RX_PIN - #define Y_SERIAL_RX_PIN P0_00 + #define Y_SERIAL_RX_PIN P0_00 #endif #ifndef Z_SERIAL_TX_PIN - #define Z_SERIAL_TX_PIN P2_13 + #define Z_SERIAL_TX_PIN P2_13 #endif #ifndef Z_SERIAL_RX_PIN - #define Z_SERIAL_RX_PIN P2_13 + #define Z_SERIAL_RX_PIN P2_13 #endif #ifndef E0_SERIAL_TX_PIN - #define E0_SERIAL_TX_PIN P2_08 + #define E0_SERIAL_TX_PIN P2_08 #endif #ifndef E0_SERIAL_RX_PIN - #define E0_SERIAL_RX_PIN P2_08 + #define E0_SERIAL_RX_PIN P2_08 #endif // Reduce baud rate to improve software serial reliability - #define TMC_BAUD_RATE 19200 + #define TMC_BAUD_RATE 19200 #endif // // Temperature Sensors // 3.3V max when defined as an analog input // -#define TEMP_0_PIN P0_23_A0 // A0 (T0) - (67) - TEMP_0_PIN -#define TEMP_BED_PIN P0_24_A1 // A1 (T1) - (68) - TEMP_BED_PIN -#define TEMP_1_PIN P0_25_A2 // A2 (T2) - (69) - TEMP_1_PIN -#define TEMP_2_PIN P0_26_A3 // A3 - (63) - J5-3 & AUX-2 -#define TEMP_3_PIN P1_30_A4 // A4 - (37) - BUZZER_PIN -//#define TEMP_4_PIN P1_31_A5 // A5 - (49) - SD_DETECT_PIN -//#define ?? P0_03_A6 // A6 - ( 0) - RXD0 - J4-4 & AUX-1 -#define FILWIDTH_PIN P0_02_A7 // A7 - ( 1) - TXD0 - J4-5 & AUX-1 +#define TEMP_0_PIN P0_23_A0 // A0 (T0) - (67) - TEMP_0_PIN +#define TEMP_BED_PIN P0_24_A1 // A1 (T1) - (68) - TEMP_BED_PIN +#define TEMP_1_PIN P0_25_A2 // A2 (T2) - (69) - TEMP_1_PIN +#define TEMP_2_PIN P0_26_A3 // A3 - (63) - J5-3 & AUX-2 +#define TEMP_3_PIN P1_30_A4 // A4 - (37) - BUZZER_PIN +//#define TEMP_4_PIN P1_31_A5 // A5 - (49) - SD_DETECT_PIN +//#define ?? P0_03_A6 // A6 - ( 0) - RXD0 - J4-4 & AUX-1 +#define FILWIDTH_PIN P0_02_A7 // A7 - ( 1) - TXD0 - J4-5 & AUX-1 // // Augmentation for auto-assigning RAMPS plugs // #if NONE(IS_RAMPS_EEB, IS_RAMPS_EEF, IS_RAMPS_EFB, IS_RAMPS_EFF, IS_RAMPS_SF) && !PIN_EXISTS(MOSFET_D) - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND #if TEMP_SENSOR_BED #define IS_RAMPS_EEB #else @@ -195,69 +194,69 @@ // Heaters / Fans // #ifndef MOSFET_D_PIN - #define MOSFET_D_PIN -1 + #define MOSFET_D_PIN -1 #endif #ifndef RAMPS_D8_PIN - #define RAMPS_D8_PIN P2_07 // (8) + #define RAMPS_D8_PIN P2_07 // (8) #endif #ifndef RAMPS_D9_PIN - #define RAMPS_D9_PIN P2_04 // (9) + #define RAMPS_D9_PIN P2_04 // (9) #endif #ifndef RAMPS_D10_PIN - #define RAMPS_D10_PIN P2_05 // (10) + #define RAMPS_D10_PIN P2_05 // (10) #endif -#define HEATER_0_PIN RAMPS_D10_PIN - -#if ENABLED(IS_RAMPS_EFB) // Hotend, Fan, Bed - #define HEATER_BED_PIN RAMPS_D8_PIN -#elif ENABLED(IS_RAMPS_EEF) // Hotend, Hotend, Fan - #define HEATER_1_PIN RAMPS_D9_PIN -#elif ENABLED(IS_RAMPS_EEB) // Hotend, Hotend, Bed - #define HEATER_1_PIN RAMPS_D9_PIN - #define HEATER_BED_PIN RAMPS_D8_PIN -#elif ENABLED(IS_RAMPS_EFF) // Hotend, Fan, Fan - #define FAN1_PIN RAMPS_D8_PIN -#elif DISABLED(IS_RAMPS_SF) // Not Spindle, Fan (i.e., "EFBF" or "EFBE") - #define HEATER_BED_PIN RAMPS_D8_PIN +#define HEATER_0_PIN RAMPS_D10_PIN + +#if ENABLED(IS_RAMPS_EFB) // Hotend, Fan, Bed + #define HEATER_BED_PIN RAMPS_D8_PIN +#elif ENABLED(IS_RAMPS_EEF) // Hotend, Hotend, Fan + #define HEATER_1_PIN RAMPS_D9_PIN +#elif ENABLED(IS_RAMPS_EEB) // Hotend, Hotend, Bed + #define HEATER_1_PIN RAMPS_D9_PIN + #define HEATER_BED_PIN RAMPS_D8_PIN +#elif ENABLED(IS_RAMPS_EFF) // Hotend, Fan, Fan + #define FAN1_PIN RAMPS_D8_PIN +#elif DISABLED(IS_RAMPS_SF) // Not Spindle, Fan (i.e., "EFBF" or "EFBE") + #define HEATER_BED_PIN RAMPS_D8_PIN #if HOTENDS == 1 - #define FAN1_PIN MOSFET_D_PIN + #define FAN1_PIN MOSFET_D_PIN #else - #define HEATER_1_PIN MOSFET_D_PIN + #define HEATER_1_PIN MOSFET_D_PIN #endif #endif #ifndef FAN_PIN #if EITHER(IS_RAMPS_EFB, IS_RAMPS_EFF) // Hotend, Fan, Bed or Hotend, Fan, Fan - #define FAN_PIN RAMPS_D9_PIN + #define FAN_PIN RAMPS_D9_PIN #elif EITHER(IS_RAMPS_EEF, IS_RAMPS_SF) // Hotend, Hotend, Fan or Spindle, Fan - #define FAN_PIN RAMPS_D8_PIN - #elif ENABLED(IS_RAMPS_EEB) // Hotend, Hotend, Bed - #define FAN_PIN P1_18 // (4) IO pin. Buffer needed - #else // Non-specific are "EFB" (i.e., "EFBF" or "EFBE") - #define FAN_PIN RAMPS_D9_PIN + #define FAN_PIN RAMPS_D8_PIN + #elif ENABLED(IS_RAMPS_EEB) // Hotend, Hotend, Bed + #define FAN_PIN P1_18 // (4) IO pin. Buffer needed + #else // Non-specific are "EFB" (i.e., "EFBF" or "EFBE") + #define FAN_PIN RAMPS_D9_PIN #endif #endif // // Misc. Functions // -#define LED_PIN P4_28 // (13) +#define LED_PIN P4_28 // (13) // define digital pin 5 for the filament runout sensor. Use the RAMPS 1.4 digital input 5 on the servos connector #ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN P1_19 // (5) + #define FIL_RUNOUT_PIN P1_19 // (5) #endif -#define PS_ON_PIN P2_12 // (12) +#define PS_ON_PIN P2_12 // (12) #if !defined(MAX6675_SS_PIN) && DISABLED(USE_ZMAX_PLUG) - #define MAX6675_SS_PIN P1_28 + #define MAX6675_SS_PIN P1_28 #endif #if ENABLED(CASE_LIGHT_ENABLE) && !PIN_EXISTS(CASE_LIGHT) && !defined(SPINDLE_LASER_ENA_PIN) - #if !defined(NUM_SERVOS) || NUM_SERVOS < 4 // Try to use servo connector - #define CASE_LIGHT_PIN P1_18 // (4) MUST BE HARDWARE PWM + #if !defined(NUM_SERVOS) || NUM_SERVOS < 4 // Try to use servo connector + #define CASE_LIGHT_PIN P1_18 // (4) MUST BE HARDWARE PWM #endif #endif @@ -273,19 +272,19 @@ #error "LASER_FEATURE requires 3 free servo pins." #endif #endif - #define SPINDLE_LASER_ENA_PIN SERVO1_PIN // (6) Pin should have a pullup/pulldown! - #define SPINDLE_LASER_PWM_PIN SERVO3_PIN // (4) MUST BE HARDWARE PWM - #define SPINDLE_DIR_PIN SERVO2_PIN // (5) + #define SPINDLE_LASER_ENA_PIN SERVO1_PIN // (6) Pin should have a pullup/pulldown! + #define SPINDLE_LASER_PWM_PIN SERVO3_PIN // (4) MUST BE HARDWARE PWM + #define SPINDLE_DIR_PIN SERVO2_PIN // (5) #endif // // Průša i3 MK2 Multiplexer Support // #if SERIAL_PORT != 0 && SERIAL_PORT_2 != 0 - #define E_MUX0_PIN P0_03 // ( 0) Z_CS_PIN - #define E_MUX1_PIN P0_02 // ( 1) E0_CS_PIN + #define E_MUX0_PIN P0_03 // ( 0) Z_CS_PIN + #define E_MUX1_PIN P0_02 // ( 1) E0_CS_PIN #endif -#define E_MUX2_PIN P0_26 // (63) E1_CS_PIN +#define E_MUX2_PIN P0_26 // (63) E1_CS_PIN /** * LCD / Controller @@ -293,7 +292,7 @@ * All controllers can use J3 and J5 on the Re-ARM board. Custom cabling will be required. * * - https://github.com/wolfmanjm/universal-panel-adapter - * - http://panucattdevices.freshdesk.com/support/solutions/articles/1000243195-lcd-display-installation + * - https://panucattdevices.freshdesk.com/support/solutions/articles/1000243195-lcd-display-installation */ /** @@ -316,101 +315,111 @@ // 10-pin IDC connector trimmed or replaced with a 12-pin IDC connector to fit J3. // Requires REVERSE_ENCODER_DIRECTION in Configuration.h - #define BEEPER_PIN P2_11 // J3-3 & AUX-4 + #define BEEPER_PIN P2_11 // J3-3 & AUX-4 + + #define BTN_EN1 P0_16 // J3-7 & AUX-4 + #define BTN_EN2 P1_23 // J3-5 & AUX-4 + #define BTN_ENC P3_25 // J3-4 & AUX-4 + + #define LCD_PINS_RS P0_15 // J3-9 & AUX-4 (CS) + #define LCD_PINS_ENABLE P0_18 // J3-10 & AUX-3 (SID, MOSI) + #define LCD_PINS_D4 P2_06 // J3-8 & AUX-3 (SCK, CLK) + +#elif IS_TFTGLCD_PANEL - #define BTN_EN1 P0_16 // J3-7 & AUX-4 - #define BTN_EN2 P1_23 // J3-5 & AUX-4 - #define BTN_ENC P3_25 // J3-4 & AUX-4 + #if ENABLED(TFTGLCD_PANEL_SPI) + #define TFTGLCD_CS P3_26 // (31) J3-2 & AUX-4 + #endif - #define LCD_PINS_RS P0_15 // J3-9 & AUX-4 (CS) - #define LCD_PINS_ENABLE P0_18 // J3-10 & AUX-3 (SID, MOSI) - #define LCD_PINS_D4 P2_06 // J3-8 & AUX-3 (SCK, CLK) + #define SD_DETECT_PIN P1_31 // (49) J3-1 & AUX-3 (NOT 5V tolerant) + #define KILL_PIN P1_22 // (41) J5-4 & AUX-4 -#elif HAS_SPI_LCD +#elif HAS_WIRED_LCD - //#define SCK_PIN P0_15 // (52) system defined J3-9 & AUX-3 - //#define MISO_PIN P0_17 // (50) system defined J3-10 & AUX-3 - //#define MOSI_PIN P0_18 // (51) system defined J3-10 & AUX-3 - //#define SS_PIN P1_23 // (53) system defined J3-5 & AUX-3 (Sometimes called SDSS) + //#define SCK_PIN P0_15 // (52) system defined J3-9 & AUX-3 + //#define MISO_PIN P0_17 // (50) system defined J3-10 & AUX-3 + //#define MOSI_PIN P0_18 // (51) system defined J3-10 & AUX-3 + //#define SS_PIN P1_23 // (53) system defined J3-5 & AUX-3 (Sometimes called SDSS) #if ENABLED(FYSETC_MINI_12864) - #define BEEPER_PIN P1_01 - #define BTN_ENC P1_04 + #define BEEPER_PIN P1_01 + #define BTN_ENC P1_04 #else - #define BEEPER_PIN P1_30 // (37) not 5V tolerant - #define BTN_ENC P2_11 // (35) J3-3 & AUX-4 + #define BEEPER_PIN P1_30 // (37) not 5V tolerant + #define BTN_ENC P2_11 // (35) J3-3 & AUX-4 #endif - #define BTN_EN1 P3_26 // (31) J3-2 & AUX-4 - #define BTN_EN2 P3_25 // (33) J3-4 & AUX-4 + #define BTN_EN1 P3_26 // (31) J3-2 & AUX-4 + #define BTN_EN2 P3_25 // (33) J3-4 & AUX-4 - #define SD_DETECT_PIN P1_31 // (49) J3-1 & AUX-3 (NOT 5V tolerant) - #define KILL_PIN P1_22 // (41) J5-4 & AUX-4 - #define LCD_PINS_RS P0_16 // (16) J3-7 & AUX-4 - #define LCD_SDSS P0_16 // (16) J3-7 & AUX-4 + #define SD_DETECT_PIN P1_31 // (49) J3-1 & AUX-3 (NOT 5V tolerant) + #define KILL_PIN P1_22 // (41) J5-4 & AUX-4 + #define LCD_PINS_RS P0_16 // (16) J3-7 & AUX-4 + #define LCD_SDSS P1_23 // (53) J3-5 & AUX-3 #if ENABLED(NEWPANEL) #if ENABLED(REPRAPWORLD_KEYPAD) - #define SHIFT_OUT P0_18 // (51) (MOSI) J3-10 & AUX-3 - #define SHIFT_CLK P0_15 // (52) (SCK) J3-9 & AUX-3 - #define SHIFT_LD P1_31 // (49) J3-1 & AUX-3 (NOT 5V tolerant) + #define SHIFT_OUT P0_18 // (51) (MOSI) J3-10 & AUX-3 + #define SHIFT_CLK P0_15 // (52) (SCK) J3-9 & AUX-3 + #define SHIFT_LD P1_31 // (49) J3-1 & AUX-3 (NOT 5V tolerant) #endif #else - //#define SHIFT_CLK P3_26 // (31) J3-2 & AUX-4 - //#define SHIFT_LD P3_25 // (33) J3-4 & AUX-4 - //#define SHIFT_OUT P2_11 // (35) J3-3 & AUX-4 - //#define SHIFT_EN P1_22 // (41) J5-4 & AUX-4 + //#define SHIFT_CLK P3_26 // (31) J3-2 & AUX-4 + //#define SHIFT_LD P3_25 // (33) J3-4 & AUX-4 + //#define SHIFT_OUT P2_11 // (35) J3-3 & AUX-4 + //#define SHIFT_EN P1_22 // (41) J5-4 & AUX-4 #endif #if ANY(VIKI2, miniVIKI) - // #define LCD_SCREEN_ROT_180 + //#define LCD_SCREEN_ROT_180 - #define DOGLCD_CS P0_16 // (16) - #define DOGLCD_A0 P2_06 // (59) J3-8 & AUX-2 - #define DOGLCD_SCK SCK_PIN - #define DOGLCD_MOSI MOSI_PIN + #define DOGLCD_CS P0_16 // (16) + #define DOGLCD_A0 P2_06 // (59) J3-8 & AUX-2 + #define DOGLCD_SCK SCK_PIN + #define DOGLCD_MOSI MOSI_PIN + + #define STAT_LED_BLUE_PIN P0_26 // (63) may change if cable changes + #define STAT_LED_RED_PIN P1_21 // ( 6) may change if cable changes - #define STAT_LED_BLUE_PIN P0_26 //(63) may change if cable changes - #define STAT_LED_RED_PIN P1_21 // ( 6) may change if cable changes #else #if ENABLED(FYSETC_MINI_12864) - #define DOGLCD_SCK P0_15 - #define DOGLCD_MOSI P0_18 + #define DOGLCD_SCK P0_15 + #define DOGLCD_MOSI P0_18 // EXP1 on LCD adapter is not usable - using Ethernet connector instead - #define DOGLCD_CS P1_09 - #define DOGLCD_A0 P1_14 - //#define FORCE_SOFT_SPI // Use this if default of hardware SPI causes display problems - // results in LCD soft SPI mode 3, SD soft SPI mode 0 + #define DOGLCD_CS P1_09 + #define DOGLCD_A0 P1_14 + //#define FORCE_SOFT_SPI // Use this if default of hardware SPI causes display problems + // results in LCD soft SPI mode 3, SD soft SPI mode 0 - #define LCD_RESET_PIN P0_16 // Must be high or open for LCD to operate normally. + #define LCD_RESET_PIN P0_16 // Must be high or open for LCD to operate normally. #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) #ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN P1_00 + #define RGB_LED_R_PIN P1_00 #endif #ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN P1_01 + #define RGB_LED_G_PIN P1_01 #endif #ifndef RGB_LED_B_PIN - #define RGB_LED_B_PIN P1_08 + #define RGB_LED_B_PIN P1_08 #endif #elif ENABLED(FYSETC_MINI_12864_2_1) - #define NEOPIXEL_PIN P1_00 + #define NEOPIXEL_PIN P1_00 #endif #else - #define DOGLCD_CS P0_26 // (63) J5-3 & AUX-2 - #define DOGLCD_A0 P2_06 // (59) J3-8 & AUX-2 + #define DOGLCD_CS P0_26 // (63) J5-3 & AUX-2 + #define DOGLCD_A0 P2_06 // (59) J3-8 & AUX-2 #endif - #define LCD_BACKLIGHT_PIN P0_16 //(16) J3-7 & AUX-4 - only used on DOGLCD controllers - #define LCD_PINS_ENABLE P0_18 // (51) (MOSI) J3-10 & AUX-3 - #define LCD_PINS_D4 P0_15 // (52) (SCK) J3-9 & AUX-3 + #define LCD_BACKLIGHT_PIN P0_16 //(16) J3-7 & AUX-4 - only used on DOGLCD controllers + #define LCD_PINS_ENABLE P0_18 // (51) (MOSI) J3-10 & AUX-3 + #define LCD_PINS_D4 P0_15 // (52) (SCK) J3-9 & AUX-3 #if ENABLED(ULTIPANEL) - #define LCD_PINS_D5 P1_17 // (71) ENET_MDIO - #define LCD_PINS_D6 P1_14 // (73) ENET_RX_ER - #define LCD_PINS_D7 P1_10 // (75) ENET_RXD1 + #define LCD_PINS_D5 P1_17 // (71) ENET_MDIO + #define LCD_PINS_D6 P1_14 // (73) ENET_RX_ER + #define LCD_PINS_D7 P1_10 // (75) ENET_RXD1 #endif #endif @@ -420,46 +429,46 @@ //#define LCD_SCREEN_ROT_90 //#define LCD_SCREEN_ROT_180 //#define LCD_SCREEN_ROT_270 - #endif + #endif -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD // // Ethernet pins // #if DISABLED(ULTIPANEL) - #define ENET_MDIO P1_17 // (71) J12-4 - #define ENET_RX_ER P1_14 // (73) J12-6 - #define ENET_RXD1 P1_10 // (75) J12-8 + #define ENET_MDIO P1_17 // (71) J12-4 + #define ENET_RX_ER P1_14 // (73) J12-6 + #define ENET_RXD1 P1_10 // (75) J12-8 #endif -#define ENET_MOC P1_16 // (70) J12-3 -#define REF_CLK P1_15 // (72) J12-5 -#define ENET_RXD0 P1_09 // (74) J12-7 -#define ENET_CRS P1_08 // (76) J12-9 -#define ENET_TX_EN P1_04 // (77) J12-10 -#define ENET_TXD0 P1_00 // (78) J12-11 -#define ENET_TXD1 P1_01 // (79) J12-12 +#define ENET_MOC P1_16 // (70) J12-3 +#define REF_CLK P1_15 // (72) J12-5 +#define ENET_RXD0 P1_09 // (74) J12-7 +#define ENET_CRS P1_08 // (76) J12-9 +#define ENET_TX_EN P1_04 // (77) J12-10 +#define ENET_TXD0 P1_00 // (78) J12-11 +#define ENET_TXD1 P1_01 // (79) J12-12 // // SD Support // #ifndef SDCARD_CONNECTION - #define SDCARD_CONNECTION ONBOARD + #define SDCARD_CONNECTION ONBOARD #endif -#define ONBOARD_SD_CS_PIN P0_06 // Chip select for "System" SD card +#define ONBOARD_SD_CS_PIN P0_06 // Chip select for "System" SD card #if SD_CONNECTION_IS(LCD) - #define SCK_PIN P0_15 // (52) system defined J3-9 & AUX-3 - #define MISO_PIN P0_17 // (50) system defined J3-10 & AUX-3 - #define MOSI_PIN P0_18 // (51) system defined J3-10 & AUX-3 - #define SS_PIN P1_23 // (53) system defined J3-5 & AUX-3 (Sometimes called SDSS) - CS used by Marlin + #define SCK_PIN P0_15 // (52) system defined J3-9 & AUX-3 + #define MISO_PIN P0_17 // (50) system defined J3-10 & AUX-3 + #define MOSI_PIN P0_18 // (51) system defined J3-10 & AUX-3 + #define SS_PIN P1_23 // (53) system defined J3-5 & AUX-3 (Sometimes called SDSS) - CS used by Marlin #elif SD_CONNECTION_IS(ONBOARD) #undef SD_DETECT_PIN - #define SCK_PIN P0_07 - #define MISO_PIN P0_08 - #define MOSI_PIN P0_09 - #define SS_PIN ONBOARD_SD_CS_PIN + #define SCK_PIN P0_07 + #define MISO_PIN P0_08 + #define MOSI_PIN P0_09 + #define SS_PIN ONBOARD_SD_CS_PIN #elif SD_CONNECTION_IS(CUSTOM_CABLE) #error "No custom SD drive cable defined for this board." #endif diff --git a/Marlin/src/pins/lpc1768/pins_SELENA_COMPACT.h b/Marlin/src/pins/lpc1768/pins_SELENA_COMPACT.h index 1a8e997eb2c7..f9b9db918d55 100644 --- a/Marlin/src/pins/lpc1768/pins_SELENA_COMPACT.h +++ b/Marlin/src/pins/lpc1768/pins_SELENA_COMPACT.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Selena Compact pin assignments */ -#ifndef MCU_LPC1768 +#if NOT_TARGET(MCU_LPC1768) #error "Oops! Make sure you have the LPC1768 environment selected in your IDE." #endif @@ -35,80 +35,79 @@ // // Servos // -#define SERVO0_PIN P1_23 +#define SERVO0_PIN P1_23 // // Limit Switches // -#define X_MIN_PIN P1_28 -#define X_MAX_PIN P1_25 -#define Y_MIN_PIN P2_11 -#define Y_MAX_PIN -1 -#define Z_MIN_PIN P1_27 -#define Z_MAX_PIN -1 -#define Z_PROBE P1_22 +#define X_MIN_PIN P1_28 +#define X_MAX_PIN P1_25 +#define Y_MIN_PIN P2_11 +#define Y_MAX_PIN -1 +#define Z_MIN_PIN P1_27 +#define Z_MAX_PIN -1 +#define Z_PROBE P1_22 // // Steppers // -#define X_STEP_PIN P2_00 -#define X_DIR_PIN P0_05 -#define X_ENABLE_PIN P0_04 +#define X_STEP_PIN P2_00 +#define X_DIR_PIN P0_05 +#define X_ENABLE_PIN P0_04 -#define Y_STEP_PIN P2_01 -#define Y_DIR_PIN P0_11 -#define Y_ENABLE_PIN P0_10 +#define Y_STEP_PIN P2_01 +#define Y_DIR_PIN P0_11 +#define Y_ENABLE_PIN P0_10 -#define Z_STEP_PIN P2_02 -#define Z_DIR_PIN P0_20 -#define Z_ENABLE_PIN P0_19 +#define Z_STEP_PIN P2_02 +#define Z_DIR_PIN P0_20 +#define Z_ENABLE_PIN P0_19 -#define E0_STEP_PIN P2_03 -#define E0_DIR_PIN P0_22 -#define E0_ENABLE_PIN P0_21 +#define E0_STEP_PIN P2_03 +#define E0_DIR_PIN P0_22 +#define E0_ENABLE_PIN P0_21 -#define E1_STEP_PIN P2_08 -#define E1_DIR_PIN P2_13 -#define E1_ENABLE_PIN P4_29 +#define E1_STEP_PIN P2_08 +#define E1_DIR_PIN P2_13 +#define E1_ENABLE_PIN P4_29 // // Temperature Sensors // 3.3V max when defined as an analog input // -#define TEMP_BED_PIN P0_23_A0 // A0 (TH1) -#define TEMP_0_PIN P0_24_A1 // A1 (TH2) -#define TEMP_1_PIN P0_25_A2 // A2 (TH3) - +#define TEMP_BED_PIN P0_23_A0 // A0 (TH1) +#define TEMP_0_PIN P0_24_A1 // A1 (TH2) +#define TEMP_1_PIN P0_25_A2 // A2 (TH3) // // Heaters / Fans // -#define HEATER_BED_PIN P2_05 -#define HEATER_BED2_PIN P2_04 -#define HEATER_0_PIN P2_07 -#define HEATER_1_PIN P2_06 +#define HEATER_BED_PIN P2_05 +#define HEATER_BED2_PIN P2_04 +#define HEATER_0_PIN P2_07 +#define HEATER_1_PIN P2_06 #ifndef FAN_PIN - #define FAN_PIN P1_24 + #define FAN_PIN P1_24 #endif -#define FAN1_PIN P1_26 +#define FAN1_PIN P1_26 // // Display // #if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) - #define LCD_PINS_RS P0_16 - #define LCD_PINS_ENABLE P0_18 - #define LCD_PINS_D4 P0_15 - #define LCD_PINS_D5 P1_00 - #define LCD_PINS_D6 P1_01 - #define LCD_PINS_D7 P1_04 - #define BEEPER_PIN P1_31 - - #define BTN_EN1 P3_25 - #define BTN_EN2 P3_26 - #define BTN_ENC P1_30 - - #define SD_DETECT_PIN -1 + #define LCD_PINS_RS P0_16 + #define LCD_PINS_ENABLE P0_18 + #define LCD_PINS_D4 P0_15 + #define LCD_PINS_D5 P1_00 + #define LCD_PINS_D6 P1_01 + #define LCD_PINS_D7 P1_04 + #define BEEPER_PIN P1_31 + + #define BTN_EN1 P3_25 + #define BTN_EN2 P3_26 + #define BTN_ENC P1_30 + + #define SD_DETECT_PIN -1 #endif // REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER diff --git a/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_GT.h b/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_GT.h index 5ee0e5856621..adf9085262a0 100644 --- a/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_GT.h +++ b/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_GT.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Azteeg X5 GT pin assignments */ -#ifndef MCU_LPC1769 +#if NOT_TARGET(MCU_LPC1769) #error "Oops! Make sure you have the LPC1769 environment selected in your IDE." #endif @@ -35,94 +35,92 @@ // // Servos // -#define SERVO0_PIN P1_23 +#define SERVO0_PIN P1_23 // // Limit Switches // -#define X_MIN_PIN P1_24 -#define X_MAX_PIN P1_27 -#define Y_MIN_PIN P1_25 -#define Y_MAX_PIN P1_28 -#define Z_MIN_PIN P1_26 -#define Z_MAX_PIN P1_29 - +#define X_MIN_PIN P1_24 +#define X_MAX_PIN P1_27 +#define Y_MIN_PIN P1_25 +#define Y_MAX_PIN P1_28 +#define Z_MIN_PIN P1_26 +#define Z_MAX_PIN P1_29 // // Steppers // -#define X_STEP_PIN P2_01 -#define X_DIR_PIN P0_11 -#define X_ENABLE_PIN P0_10 +#define X_STEP_PIN P2_01 +#define X_DIR_PIN P0_11 +#define X_ENABLE_PIN P0_10 #ifndef X_CS_PIN - #define X_CS_PIN P0_10 // BSD2660 default + #define X_CS_PIN P0_10 // BSD2660 default #endif -#define Y_STEP_PIN P2_02 -#define Y_DIR_PIN P0_20 -#define Y_ENABLE_PIN P0_19 +#define Y_STEP_PIN P2_02 +#define Y_DIR_PIN P0_20 +#define Y_ENABLE_PIN P0_19 #ifndef Y_CS_PIN - #define Y_CS_PIN P0_19 // BSD2660 default + #define Y_CS_PIN P0_19 // BSD2660 default #endif -#define Z_STEP_PIN P2_03 -#define Z_DIR_PIN P0_22 -#define Z_ENABLE_PIN P0_21 +#define Z_STEP_PIN P2_03 +#define Z_DIR_PIN P0_22 +#define Z_ENABLE_PIN P0_21 #ifndef Z_CS_PIN - #define Z_CS_PIN P0_21 // BSD2660 default + #define Z_CS_PIN P0_21 // BSD2660 default #endif -#define E0_STEP_PIN P2_00 -#define E0_DIR_PIN P0_05 -#define E0_ENABLE_PIN P0_04 +#define E0_STEP_PIN P2_00 +#define E0_DIR_PIN P0_05 +#define E0_ENABLE_PIN P0_04 #ifndef E0_CS_PIN - #define E0_CS_PIN P0_04 // BSD2660 default + #define E0_CS_PIN P0_04 // BSD2660 default #endif -#define E1_STEP_PIN P2_08 -#define E1_DIR_PIN P2_13 -#define E1_ENABLE_PIN P4_29 +#define E1_STEP_PIN P2_08 +#define E1_DIR_PIN P2_13 +#define E1_ENABLE_PIN P4_29 #ifndef E1_CS_PIN - #define E1_CS_PIN P4_29 // BSD2660 default + #define E1_CS_PIN P4_29 // BSD2660 default #endif // // Temperature Sensors // 3.3V max when defined as an analog input // -#define TEMP_BED_PIN P0_23_A0 // A0 (TH1) -#define TEMP_0_PIN P0_24_A1 // A1 (TH2) -#define TEMP_1_PIN P0_25_A2 // A2 (TH3) - +#define TEMP_BED_PIN P0_23_A0 // A0 (TH1) +#define TEMP_0_PIN P0_24_A1 // A1 (TH2) +#define TEMP_1_PIN P0_25_A2 // A2 (TH3) // // Heaters / Fans // -#define HEATER_BED_PIN P2_07 -#define HEATER_0_PIN P2_04 -#define HEATER_1_PIN P2_05 +#define HEATER_BED_PIN P2_07 +#define HEATER_0_PIN P2_04 +#define HEATER_1_PIN P2_05 #ifndef FAN_PIN - #define FAN_PIN P0_26 + #define FAN_PIN P0_26 #endif -#define FAN1_PIN P1_22 +#define FAN1_PIN P1_22 // // Display // #if ANY(VIKI2, miniVIKI) - #define BEEPER_PIN P1_31 - #define DOGLCD_A0 P2_06 - #define DOGLCD_CS P0_16 + #define BEEPER_PIN P1_31 + #define DOGLCD_A0 P2_06 + #define DOGLCD_CS P0_16 - #define BTN_EN1 P3_25 - #define BTN_EN2 P3_26 - #define BTN_ENC P2_11 + #define BTN_EN1 P3_25 + #define BTN_EN2 P3_26 + #define BTN_ENC P2_11 - #define SD_DETECT_PIN P1_18 - #define SDSS P1_21 + #define SD_DETECT_PIN P1_18 + #define SDSS P1_21 - #define STAT_LED_RED_PIN P1_19 - #define STAT_LED_BLUE_PIN P1_20 + #define STAT_LED_RED_PIN P1_19 + #define STAT_LED_BLUE_PIN P1_20 #endif diff --git a/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_MINI.h b/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_MINI.h index 2c54bd603527..6331d6aa7c0a 100644 --- a/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_MINI.h +++ b/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_MINI.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Azteeg X5 MINI pin assignments */ -#ifndef MCU_LPC1769 +#if NOT_TARGET(MCU_LPC1769) #error "Oops! Make sure you have the LPC1769 environment selected in your IDE." #endif @@ -37,79 +37,79 @@ // // LED // -#define LED_PIN P1_18 +#define LED_PIN P1_18 // // Servos // -#define SERVO0_PIN P1_29 +#define SERVO0_PIN P1_29 // // Limit Switches // -#define X_STOP_PIN P1_24 -#define Y_STOP_PIN P1_26 -#define Z_STOP_PIN P1_28 +#define X_STOP_PIN P1_24 +#define Y_STOP_PIN P1_26 +#define Z_STOP_PIN P1_28 #ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN P2_04 + #define FIL_RUNOUT_PIN P2_04 #endif #ifndef FILWIDTH_PIN - #define FILWIDTH_PIN P0_25_A2 // Analog Input (P0_25) + #define FILWIDTH_PIN P0_25_A2 // Analog Input (P0_25) #endif // // Steppers // -#define X_STEP_PIN P2_01 -#define X_DIR_PIN P0_11 -#define X_ENABLE_PIN P0_10 +#define X_STEP_PIN P2_01 +#define X_DIR_PIN P0_11 +#define X_ENABLE_PIN P0_10 -#define Y_STEP_PIN P2_02 -#define Y_DIR_PIN P0_20 -#define Y_ENABLE_PIN P0_19 +#define Y_STEP_PIN P2_02 +#define Y_DIR_PIN P0_20 +#define Y_ENABLE_PIN P0_19 -#define Z_STEP_PIN P2_03 -#define Z_DIR_PIN P0_22 -#define Z_ENABLE_PIN P0_21 +#define Z_STEP_PIN P2_03 +#define Z_DIR_PIN P0_22 +#define Z_ENABLE_PIN P0_21 -#define E0_STEP_PIN P2_00 -#define E0_DIR_PIN P0_05 -#define E0_ENABLE_PIN P0_04 +#define E0_STEP_PIN P2_00 +#define E0_DIR_PIN P0_05 +#define E0_ENABLE_PIN P0_04 // // DIGIPOT slave addresses // #ifndef DIGIPOT_I2C_ADDRESS_A - #define DIGIPOT_I2C_ADDRESS_A 0x2C // unshifted slave address for first DIGIPOT + #define DIGIPOT_I2C_ADDRESS_A 0x2C // unshifted slave address for first DIGIPOT #endif #ifndef DIGIPOT_I2C_ADDRESS_B - #define DIGIPOT_I2C_ADDRESS_B 0x2E // unshifted slave address for second DIGIPOT + #define DIGIPOT_I2C_ADDRESS_B 0x2E // unshifted slave address for second DIGIPOT #endif // // Temperature Sensors // 3.3V max when defined as an analog input // -#define TEMP_BED_PIN P0_23_A0 // A0 (TH1) -#define TEMP_0_PIN P0_24_A1 // A1 (TH2) +#define TEMP_BED_PIN P0_23_A0 // A0 (TH1) +#define TEMP_0_PIN P0_24_A1 // A1 (TH2) // // Heaters / Fans // -#define HEATER_BED_PIN P2_07 -#define HEATER_0_PIN P2_05 +#define HEATER_BED_PIN P2_07 +#define HEATER_0_PIN P2_05 #ifndef FAN_PIN - #define FAN_PIN P0_26 + #define FAN_PIN P0_26 #endif -#define FAN1_PIN P1_25 +#define FAN1_PIN P1_25 // // Display // -#if HAS_SPI_LCD +#if HAS_WIRED_LCD #if ENABLED(CR10_STOCKDISPLAY) @@ -118,61 +118,61 @@ // 10-pin IDC connector trimmed or replaced with a 12-pin IDC connector to fit J3. // Requires REVERSE_ENCODER_DIRECTION in Configuration.h - #define BEEPER_PIN P2_11 // J3-3 & AUX-4 + #define BEEPER_PIN P2_11 // J3-3 & AUX-4 - #define BTN_EN1 P0_16 // J3-7 & AUX-4 - #define BTN_EN2 P1_23 // J3-5 & AUX-4 - #define BTN_ENC P3_25 // J3-4 & AUX-4 + #define BTN_EN1 P0_16 // J3-7 & AUX-4 + #define BTN_EN2 P1_23 // J3-5 & AUX-4 + #define BTN_ENC P3_25 // J3-4 & AUX-4 - #define LCD_PINS_RS P0_15 // J3-9 & AUX-4 (CS) - #define LCD_PINS_ENABLE P0_18 // J3-10 & AUX-3 (SID, MOSI) - #define LCD_PINS_D4 P2_06 // J3-8 & AUX-3 (SCK, CLK) + #define LCD_PINS_RS P0_15 // J3-9 & AUX-4 (CS) + #define LCD_PINS_ENABLE P0_18 // J3-10 & AUX-3 (SID, MOSI) + #define LCD_PINS_D4 P2_06 // J3-8 & AUX-3 (SCK, CLK) #else - #define BTN_EN1 P3_26 // (31) J3-2 & AUX-4 - #define BTN_EN2 P3_25 // (33) J3-4 & AUX-4 - #define BTN_ENC P2_11 // (35) J3-3 & AUX-4 + #define BTN_EN1 P3_26 // (31) J3-2 & AUX-4 + #define BTN_EN2 P3_25 // (33) J3-4 & AUX-4 + #define BTN_ENC P2_11 // (35) J3-3 & AUX-4 - #define SD_DETECT_PIN P1_31 // (49) not 5V tolerant J3-1 & AUX-3 - #define KILL_PIN P1_22 // (41) J5-4 & AUX-4 - #define LCD_PINS_RS P0_16 // (16) J3-7 & AUX-4 - #define LCD_SDSS P0_16 // (16) J3-7 & AUX-4 - #define LCD_BACKLIGHT_PIN P0_16 // (16) J3-7 & AUX-4 - only used on DOGLCD controllers - #define LCD_PINS_ENABLE P0_18 // (51) (MOSI) J3-10 & AUX-3 - #define LCD_PINS_D4 P0_15 // (52) (SCK) J3-9 & AUX-3 + #define SD_DETECT_PIN P1_31 // (49) not 5V tolerant J3-1 & AUX-3 + #define KILL_PIN P1_22 // (41) J5-4 & AUX-4 + #define LCD_PINS_RS P0_16 // (16) J3-7 & AUX-4 + #define LCD_SDSS P0_16 // (16) J3-7 & AUX-4 + #define LCD_BACKLIGHT_PIN P0_16 // (16) J3-7 & AUX-4 - only used on DOGLCD controllers + #define LCD_PINS_ENABLE P0_18 // (51) (MOSI) J3-10 & AUX-3 + #define LCD_PINS_D4 P0_15 // (52) (SCK) J3-9 & AUX-3 - #define DOGLCD_A0 P2_06 // (59) J3-8 & AUX-2 + #define DOGLCD_A0 P2_06 // (59) J3-8 & AUX-2 #if ENABLED(REPRAPWORLD_KEYPAD) - #define SHIFT_OUT P0_18 // (51) (MOSI) J3-10 & AUX-3 - #define SHIFT_CLK P0_15 // (52) (SCK) J3-9 & AUX-3 - #define SHIFT_LD P1_31 // (49) not 5V tolerant J3-1 & AUX-3 + #define SHIFT_OUT P0_18 // (51) (MOSI) J3-10 & AUX-3 + #define SHIFT_CLK P0_15 // (52) (SCK) J3-9 & AUX-3 + #define SHIFT_LD P1_31 // (49) not 5V tolerant J3-1 & AUX-3 #elif DISABLED(NEWPANEL) - //#define SHIFT_OUT P2_11 // (35) J3-3 & AUX-4 - //#define SHIFT_CLK P3_26 // (31) J3-2 & AUX-4 - //#define SHIFT_LD P3_25 // (33) J3-4 & AUX-4 - //#define SHIFT_EN P1_22 // (41) J5-4 & AUX-4 + //#define SHIFT_OUT P2_11 // (35) J3-3 & AUX-4 + //#define SHIFT_CLK P3_26 // (31) J3-2 & AUX-4 + //#define SHIFT_LD P3_25 // (33) J3-4 & AUX-4 + //#define SHIFT_EN P1_22 // (41) J5-4 & AUX-4 #endif #if ANY(VIKI2, miniVIKI) //#define LCD_SCREEN_ROT_180 - #define BEEPER_PIN P1_30 // (37) may change if cable changes - #define DOGLCD_CS P0_26 // (63) J5-3 & AUX-2 - #define DOGLCD_SCK SCK_PIN - #define DOGLCD_MOSI MOSI_PIN + #define BEEPER_PIN P1_30 // (37) may change if cable changes + #define DOGLCD_CS P0_26 // (63) J5-3 & AUX-2 + #define DOGLCD_SCK SCK_PIN + #define DOGLCD_MOSI MOSI_PIN - #define STAT_LED_BLUE_PIN P0_26 // (63) may change if cable changes - #define STAT_LED_RED_PIN P1_21 // ( 6) may change if cable changes + #define STAT_LED_BLUE_PIN P0_26 // (63) may change if cable changes + #define STAT_LED_RED_PIN P1_21 // ( 6) may change if cable changes #else #if ENABLED(ULTIPANEL) - #define LCD_PINS_D5 P1_17 // (71) ENET_MDIO - #define LCD_PINS_D6 P1_14 // (73) ENET_RX_ER - #define LCD_PINS_D7 P1_10 // (75) ENET_RXD1 + #define LCD_PINS_D5 P1_17 // (71) ENET_MDIO + #define LCD_PINS_D6 P1_14 // (73) ENET_RX_ER + #define LCD_PINS_D7 P1_10 // (75) ENET_RXD1 #endif - #define BEEPER_PIN P1_30 // (37) not 5V tolerant - #define DOGLCD_CS P0_16 // (16) + #define BEEPER_PIN P1_30 // (37) not 5V tolerant + #define DOGLCD_CS P0_16 // (16) #endif #if ENABLED(MINIPANEL) @@ -185,28 +185,28 @@ #endif -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD // // SD Support // #ifndef SDCARD_CONNECTION - #define SDCARD_CONNECTION ONBOARD + #define SDCARD_CONNECTION ONBOARD #endif -#define ONBOARD_SD_CS_PIN P0_06 // Chip select for "System" SD card +#define ONBOARD_SD_CS_PIN P0_06 // Chip select for "System" SD card #if SD_CONNECTION_IS(LCD) - #define SCK_PIN P0_15 - #define MISO_PIN P0_17 - #define MOSI_PIN P0_18 - #define SS_PIN P1_23 + #define SCK_PIN P0_15 + #define MISO_PIN P0_17 + #define MOSI_PIN P0_18 + #define SS_PIN P1_23 #elif SD_CONNECTION_IS(ONBOARD) #undef SD_DETECT_PIN - #define SCK_PIN P0_07 - #define MISO_PIN P0_08 - #define MOSI_PIN P0_09 - #define SS_PIN ONBOARD_SD_CS_PIN + #define SCK_PIN P0_07 + #define MISO_PIN P0_08 + #define MOSI_PIN P0_09 + #define SS_PIN ONBOARD_SD_CS_PIN #elif SD_CONNECTION_IS(CUSTOM_CABLE) #error "No custom SD drive cable defined for this board." #endif diff --git a/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_MINI_WIFI.h b/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_MINI_WIFI.h index 4b731ae9d343..99ff0fd25a14 100644 --- a/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_MINI_WIFI.h +++ b/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_MINI_WIFI.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Azteeg X5 MINI pin assignments */ -#ifndef MCU_LPC1769 +#if NOT_TARGET(MCU_LPC1769) #error "Oops! Make sure you have the LPC1769 environment selected in your IDE." #endif diff --git a/Marlin/src/pins/lpc1769/pins_BTT_SKR_E3_TURBO.h b/Marlin/src/pins/lpc1769/pins_BTT_SKR_E3_TURBO.h new file mode 100644 index 000000000000..6d6d7557f57d --- /dev/null +++ b/Marlin/src/pins/lpc1769/pins_BTT_SKR_E3_TURBO.h @@ -0,0 +1,260 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifndef BOARD_INFO_NAME + #define BOARD_INFO_NAME "BTT SKR E3 Turbo" +#endif + +// Onboard I2C EEPROM +#define I2C_EEPROM +#define MARLIN_EEPROM_SIZE 0x1000 // 4KB (AT24C32) + +// +// Servos +// +#define SERVO0_PIN P1_23 + +// +// TMC StallGuard DIAG pins +// +#define X_DIAG_PIN P1_29 // X-STOP +#define Y_DIAG_PIN P1_28 // Y-STOP +#define Z_DIAG_PIN P1_27 // Z-STOP +#define E0_DIAG_PIN P1_26 // E0DET +#define E1_DIAG_PIN P1_25 // E1DET + +// +// Limit Switches +#define X_STOP_PIN X_DIAG_PIN +#define Y_STOP_PIN Y_DIAG_PIN +#define Z_STOP_PIN Z_DIAG_PIN + +// +// Z Probe +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN P1_22 +#endif + +// +// Filament Runout Sensor +// +#define FIL_RUNOUT_PIN P1_26 // E0DET +#define FIL_RUNOUT2_PIN P1_25 // E1DET + +// +// Power Supply Control +// +#ifndef PS_ON_PIN + #define PS_ON_PIN P1_21 +#endif + +// LED driving pin +#define NEOPIXEL_PIN P1_24 + +// +// Power Loss Detection +// +#ifndef POWER_LOSS_PIN + #define POWER_LOSS_PIN P1_20 // PWRDET +#endif + +// +// Steppers +// +#define X_STEP_PIN P1_04 +#define X_DIR_PIN P1_08 +#define X_ENABLE_PIN P1_00 +#ifndef X_CS_PIN + #define X_CS_PIN P1_01 +#endif + +#define Y_STEP_PIN P1_14 +#define Y_DIR_PIN P1_15 +#define Y_ENABLE_PIN P1_09 +#ifndef Y_CS_PIN + #define Y_CS_PIN P1_10 +#endif + +#define Z_STEP_PIN P4_29 +#define Z_DIR_PIN P4_28 +#define Z_ENABLE_PIN P1_16 +#ifndef Z_CS_PIN + #define Z_CS_PIN P1_17 +#endif + +#define E0_STEP_PIN P2_06 +#define E0_DIR_PIN P2_07 +#define E0_ENABLE_PIN P0_04 +#ifndef E0_CS_PIN + #define E0_CS_PIN P0_05 +#endif + +#define E1_STEP_PIN P2_11 +#define E1_DIR_PIN P2_12 +#define E1_ENABLE_PIN P0_21 +#ifndef E1_CS_PIN + #define E1_CS_PIN P0_22 +#endif + +#if HAS_TMC_UART + /** + * TMC2208/TMC2209 stepper drivers + * + * Hardware serial communication ports. + * If undefined software serial is used according to the pins below + */ + + // + // Software serial + // + #define X_SERIAL_TX_PIN P1_01 + #define X_SERIAL_RX_PIN P1_01 + + #define Y_SERIAL_TX_PIN P1_10 + #define Y_SERIAL_RX_PIN P1_10 + + #define Z_SERIAL_TX_PIN P1_17 + #define Z_SERIAL_RX_PIN P1_17 + + #define E0_SERIAL_TX_PIN P0_05 + #define E0_SERIAL_RX_PIN P0_05 + + #define E1_SERIAL_TX_PIN P0_22 + #define E1_SERIAL_RX_PIN P0_22 + + // Reduce baud rate to improve software serial reliability + #define TMC_BAUD_RATE 19200 +#endif + +// +// TMC Low Power Standby pins +// +#define X_STDBY_PIN P3_26 +#define Y_STDBY_PIN P3_25 +#define Z_STDBY_PIN P1_18 +#define E0_STDBY_PIN P1_19 +#define E1_STDBY_PIN P2_13 + +// +// Temperature Sensors +// +#define TEMP_0_PIN P0_24 +#define TEMP_1_PIN P0_23 +//#define TEMP_2_PIN P1_30 // Onboard thermistor +#define TEMP_BED_PIN P0_25 + +// +// Heaters / Fans +// +#define HEATER_0_PIN P2_03 // EXTRUDER 0 +#define HEATER_1_PIN P2_04 // EXTRUDER 1 +#define HEATER_BED_PIN P2_05 // BED +#define FAN_PIN P2_01 +#define FAN1_PIN P2_02 + +/** + * _____ + * 5V | 1 2 | GND + * (LCD_EN) P0_18 | 3 4 | P0_17 (LCD_RS) + * (LCD_D4) P0_15 | 5 6 P0_20 (BTN_EN2) + * RESET | 7 8 | P0_19 (BTN_EN1) + * (BTN_ENC) P0_16 | 9 10| P2_08 (BEEPER) + * ----- + * EXP + */ + +#define EXPA1_03_PIN P0_18 +#define EXPA1_04_PIN P0_17 +#define EXPA1_05_PIN P0_15 +#define EXPA1_06_PIN P0_20 +#define EXPA1_07_PIN -1 +#define EXPA1_08_PIN P0_19 +#define EXPA1_09_PIN P0_16 +#define EXPA1_10_PIN P2_08 + +#if HAS_WIRED_LCD + + #if ENABLED(CR10_STOCKDISPLAY) + + #define BEEPER_PIN EXPA1_10_PIN + + #define BTN_EN1 EXPA1_08_PIN + #define BTN_EN2 EXPA1_06_PIN + #define BTN_ENC EXPA1_09_PIN + + #define LCD_PINS_RS EXPA1_04_PIN + #define LCD_PINS_ENABLE EXPA1_03_PIN + #define LCD_PINS_D4 EXPA1_05_PIN + + #elif ENABLED(ZONESTAR_LCD) // ANET A8 LCD Controller - Must convert to 3.3V - CONNECTING TO 5V WILL DAMAGE THE BOARD! + + #error "CAUTION! ZONESTAR_LCD requires wiring modifications. See 'pins_BTT_SKR_E3_TURBO.h' for details. Comment out this line to continue." + + #define LCD_PINS_RS EXPA1_05_PIN + #define LCD_PINS_ENABLE EXPA1_09_PIN + #define LCD_PINS_D4 EXPA1_04_PIN + #define LCD_PINS_D5 EXPA1_06_PIN + #define LCD_PINS_D6 EXPA1_08_PIN + #define LCD_PINS_D7 EXPA1_10_PIN + #define ADC_KEYPAD_PIN P1_23 // Repurpose servo pin for ADC - CONNECTING TO 5V WILL DAMAGE THE BOARD! + + #elif EITHER(MKS_MINI_12864, ENDER2_STOCKDISPLAY) + + #define BTN_EN1 EXPA1_08_PIN + #define BTN_EN2 EXPA1_06_PIN + #define BTN_ENC EXPA1_09_PIN + + #define DOGLCD_CS EXPA1_04_PIN + #define DOGLCD_A0 EXPA1_05_PIN + #define DOGLCD_SCK EXPA1_10_PIN + #define DOGLCD_MOSI EXPA1_03_PIN + #define FORCE_SOFT_SPI + #define LCD_BACKLIGHT_PIN -1 + + #else + + #error "Only ZONESTAR_LCD, MKS_MINI_12864, ENDER2_STOCKDISPLAY, and CR10_STOCKDISPLAY are currently supported on the BTT_SKR_E3_TURBO." + + #endif + +#endif // HAS_WIRED_LCD + +// +// SD Support +// +#ifndef SDCARD_CONNECTION + #define SDCARD_CONNECTION ONBOARD +#endif + +#if SD_CONNECTION_IS(ONBOARD) + #define SD_DETECT_PIN P2_00 + #define SCK_PIN P0_07 + #define MISO_PIN P0_08 + #define MOSI_PIN P0_09 + #define SS_PIN P0_06 +#elif SD_CONNECTION_IS(CUSTOM_CABLE) + #error "SD CUSTOM_CABLE is not compatible with SKR E3 Turbo." +#endif + +#define ON_BOARD_SPI_DEVICE 1 // SPI1 diff --git a/Marlin/src/pins/lpc1769/pins_BTT_SKR_V1_4_TURBO.h b/Marlin/src/pins/lpc1769/pins_BTT_SKR_V1_4_TURBO.h index 937ba56bb729..a751286e3a81 100644 --- a/Marlin/src/pins/lpc1769/pins_BTT_SKR_V1_4_TURBO.h +++ b/Marlin/src/pins/lpc1769/pins_BTT_SKR_V1_4_TURBO.h @@ -16,12 +16,12 @@ * 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 . + * along with this program. If not, see . * */ #pragma once -#define BOARD_INFO_NAME "BIGTREE SKR 1.4 TURBO" +#define BOARD_INFO_NAME "BTT SKR V1.4 TURBO" #define SKR_HAS_LPC1769 // diff --git a/Marlin/src/pins/lpc1769/pins_COHESION3D_MINI.h b/Marlin/src/pins/lpc1769/pins_COHESION3D_MINI.h index 739603e2b644..d66ffbe4e5d3 100644 --- a/Marlin/src/pins/lpc1769/pins_COHESION3D_MINI.h +++ b/Marlin/src/pins/lpc1769/pins_COHESION3D_MINI.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Cohesion3D Mini pin assignments */ -#ifndef MCU_LPC1769 +#if NOT_TARGET(MCU_LPC1769) #error "Oops! Make sure you have the LPC1769 environment selected in your IDE." #endif @@ -34,53 +34,53 @@ // // Servos // -#define SERVO0_PIN P1_23 +#define SERVO0_PIN P1_23 // // Limit Switches // -#define X_MIN_PIN P1_24 // 10k pullup to 3.3V -#define X_MAX_PIN P1_25 // 10k pullup to 3.3V -#define Y_MIN_PIN P1_26 // 10k pullup to 3.3V -#define Y_MAX_PIN P1_27 // 10k pullup to 3.3V -#define Z_MIN_PIN P1_28 // 10k pullup to 3.3V -#define Z_MAX_PIN P1_29 // 10k pullup to 3.3V +#define X_MIN_PIN P1_24 // 10k pullup to 3.3V +#define X_MAX_PIN P1_25 // 10k pullup to 3.3V +#define Y_MIN_PIN P1_26 // 10k pullup to 3.3V +#define Y_MAX_PIN P1_27 // 10k pullup to 3.3V +#define Z_MIN_PIN P1_28 // 10k pullup to 3.3V +#define Z_MAX_PIN P1_29 // 10k pullup to 3.3V // // Steppers // -#define X_STEP_PIN P2_00 -#define X_DIR_PIN P0_05 -#define X_ENABLE_PIN P0_04 -#define X_CS_PIN P1_10 // Ethernet Expansion - Pin 9 +#define X_STEP_PIN P2_00 +#define X_DIR_PIN P0_05 +#define X_ENABLE_PIN P0_04 +#define X_CS_PIN P1_10 // Ethernet Expansion - Pin 9 -#define Y_STEP_PIN P2_01 -#define Y_DIR_PIN P0_11 -#define Y_ENABLE_PIN P0_10 -#define Y_CS_PIN P1_09 // Ethernet Expansion - Pin 10 +#define Y_STEP_PIN P2_01 +#define Y_DIR_PIN P0_11 +#define Y_ENABLE_PIN P0_10 +#define Y_CS_PIN P1_09 // Ethernet Expansion - Pin 10 -#define Z_STEP_PIN P2_02 -#define Z_DIR_PIN P0_20 -#define Z_ENABLE_PIN P0_19 -#define Z_CS_PIN P1_00 // Ethernet Expansion - Pin 11 +#define Z_STEP_PIN P2_02 +#define Z_DIR_PIN P0_20 +#define Z_ENABLE_PIN P0_19 +#define Z_CS_PIN P1_00 // Ethernet Expansion - Pin 11 -#define E0_STEP_PIN P2_03 -#define E0_DIR_PIN P0_22 -#define E0_ENABLE_PIN P0_21 -#define E0_CS_PIN P1_04 // Ethernet Expansion - Pin 12 +#define E0_STEP_PIN P2_03 +#define E0_DIR_PIN P0_22 +#define E0_ENABLE_PIN P0_21 +#define E0_CS_PIN P1_04 // Ethernet Expansion - Pin 12 // // Default pins for TMC software SPI // #if ENABLED(TMC_USE_SW_SPI) #ifndef TMC_SW_MOSI - #define TMC_SW_MOSI P1_16 // Ethernet Expansion - Pin 5 + #define TMC_SW_MOSI P1_16 // Ethernet Expansion - Pin 5 #endif #ifndef TMC_SW_MISO - #define TMC_SW_MISO P1_17 // Ethernet Expansion - Pin 6 + #define TMC_SW_MISO P1_17 // Ethernet Expansion - Pin 6 #endif #ifndef TMC_SW_SCK - #define TMC_SW_SCK P1_08 // Ethernet Expansion - Pin 7 + #define TMC_SW_SCK P1_08 // Ethernet Expansion - Pin 7 #endif #endif @@ -88,42 +88,47 @@ // Analog Inputs // 3.3V max when defined as an analog input // -#define TEMP_0_PIN P0_23_A0 // P0_23 -#define TEMP_BED_PIN P0_24_A1 // P0_24 +#define TEMP_0_PIN P0_23_A0 // P0_23 +#define TEMP_BED_PIN P0_24_A1 // P0_24 // // Heaters / Fans // -#define HEATER_BED_PIN P2_05 -#define HEATER_0_PIN P2_07 // FET 1 +#define HEATER_BED_PIN P2_05 +#define HEATER_0_PIN P2_07 // FET 1 #ifndef FAN_PIN - #define FAN_PIN P2_06 // FET 3 + #define FAN_PIN P2_06 // FET 3 #endif // // Auto fans // -#define AUTO_FAN_PIN P2_04 // FET 4 - -#define ORIG_E0_AUTO_FAN_PIN AUTO_FAN_PIN -#define ORIG_E1_AUTO_FAN_PIN AUTO_FAN_PIN -#define ORIG_E2_AUTO_FAN_PIN AUTO_FAN_PIN +#define AUTO_FAN_PIN P2_04 // FET 4 +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN AUTO_FAN_PIN +#endif +#ifndef E1_AUTO_FAN_PIN + #define E1_AUTO_FAN_PIN AUTO_FAN_PIN +#endif +#ifndef E2_AUTO_FAN_PIN + #define E2_AUTO_FAN_PIN AUTO_FAN_PIN +#endif // // Misc. Functions // -#define LED_PIN P4_28 // Play LED +#define LED_PIN P4_28 // Play LED // // M3/M4/M5 - Spindle/Laser Control // #if HAS_CUTTER #undef HEATER_0_PIN - #define SPINDLE_LASER_ENA_PIN P2_07 // FET 1 + #define SPINDLE_LASER_ENA_PIN P2_07 // FET 1 #undef HEATER_BED_PIN - #define SPINDLE_LASER_PWM_PIN P2_05 // Bed FET + #define SPINDLE_LASER_PWM_PIN P2_05 // Bed FET #undef FAN_PIN - #define SPINDLE_DIR_PIN P2_06 // FET 3 + #define SPINDLE_DIR_PIN P2_06 // FET 3 #endif // @@ -136,37 +141,37 @@ // connector are shared with the onboard SD card, and Marlin does not support reading // G-code files from the onboard SD card. // -#if HAS_SPI_LCD +#if HAS_WIRED_LCD - #define BEEPER_PIN P0_27 // EXP2-7 - open drain + #define BEEPER_PIN P0_27 // EXP2-7 - open drain - #define BTN_EN1 P3_26 // EXP2-5 - #define BTN_EN2 P3_25 // EXP2-3 - #define BTN_ENC P1_30 // EXP1-2 + #define BTN_EN1 P3_26 // EXP2-5 + #define BTN_EN2 P3_25 // EXP2-3 + #define BTN_ENC P1_30 // EXP1-2 - #define LCD_PINS_RS P0_16 // EXP1-4 - #define LCD_SDSS P0_28 // EXP2-4 - #define LCD_PINS_ENABLE P0_18 // EXP1-3 - #define LCD_PINS_D4 P0_15 // EXP1-5 + #define LCD_PINS_RS P0_16 // EXP1-4 + #define LCD_SDSS P0_28 // EXP2-4 + #define LCD_PINS_ENABLE P0_18 // EXP1-3 + #define LCD_PINS_D4 P0_15 // EXP1-5 - #define KILL_PIN P2_11 // EXP2-10 + #define KILL_PIN P2_11 // EXP2-10 #if ENABLED(SDSUPPORT) #error "SDSUPPORT is not currently supported by the Cohesion3D boards" #endif -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD // // Ethernet pins // -#define ENET_MDIO P1_17 -#define ENET_RX_ER P1_14 -#define ENET_RXD1 P1_10 -#define ENET_MOC P1_16 -#define REF_CLK P1_15 -#define ENET_RXD0 P1_09 -#define ENET_CRS P1_08 -#define ENET_TX_EN P1_04 -#define ENET_TXD0 P1_00 -#define ENET_TXD1 P1_01 +#define ENET_MDIO P1_17 +#define ENET_RX_ER P1_14 +#define ENET_RXD1 P1_10 +#define ENET_MOC P1_16 +#define REF_CLK P1_15 +#define ENET_RXD0 P1_09 +#define ENET_CRS P1_08 +#define ENET_TX_EN P1_04 +#define ENET_TXD0 P1_00 +#define ENET_TXD1 P1_01 diff --git a/Marlin/src/pins/lpc1769/pins_COHESION3D_REMIX.h b/Marlin/src/pins/lpc1769/pins_COHESION3D_REMIX.h index ea40c01c08f0..66604ef6359f 100644 --- a/Marlin/src/pins/lpc1769/pins_COHESION3D_REMIX.h +++ b/Marlin/src/pins/lpc1769/pins_COHESION3D_REMIX.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Cohesion3D ReMix pin assignments */ -#ifndef MCU_LPC1769 +#if NOT_TARGET(MCU_LPC1769) #error "Oops! Make sure you have the LPC1769 environment selected in your IDE." #endif @@ -34,63 +34,70 @@ // // Servos // -#define SERVO0_PIN P2_04 +#define SERVO0_PIN P2_04 // // Limit Switches // -#define X_MIN_PIN P1_24 // 10k pullup to 3.3V -#define X_MAX_PIN P1_25 // 10k pullup to 3.3V -#define Y_MIN_PIN P1_26 // 10k pullup to 3.3V -#define Y_MAX_PIN P1_27 // 10k pullup to 3.3V -#define Z_MIN_PIN P1_28 // 10k pullup to 3.3V -#define Z_MAX_PIN P1_29 // 10k pullup to 3.3V +#define X_MIN_PIN P1_24 // 10k pullup to 3.3V +#define X_MAX_PIN P1_25 // 10k pullup to 3.3V +#define Y_MIN_PIN P1_26 // 10k pullup to 3.3V +#define Y_MAX_PIN P1_27 // 10k pullup to 3.3V +#define Z_MIN_PIN P1_28 // 10k pullup to 3.3V +#define Z_MAX_PIN P1_29 // 10k pullup to 3.3V + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN P1_29 +#endif // // Steppers // -#define X_STEP_PIN P2_00 -#define X_DIR_PIN P0_05 -#define X_ENABLE_PIN P0_04 -#define X_CS_PIN P1_10 // Ethernet Expansion - Pin 9 - -#define Y_STEP_PIN P2_01 -#define Y_DIR_PIN P0_11 -#define Y_ENABLE_PIN P0_10 -#define Y_CS_PIN P1_09 // Ethernet Expansion - Pin 10 - -#define Z_STEP_PIN P2_02 -#define Z_DIR_PIN P0_20 -#define Z_ENABLE_PIN P0_19 -#define Z_CS_PIN P1_00 // Ethernet Expansion - Pin 11 - -#define E0_STEP_PIN P2_03 -#define E0_DIR_PIN P0_22 -#define E0_ENABLE_PIN P0_21 -#define E0_CS_PIN P1_04 // Ethernet Expansion - Pin 12 - -#define E1_STEP_PIN P2_08 -#define E1_DIR_PIN P2_13 -#define E1_ENABLE_PIN P4_29 -#define E1_CS_PIN P1_01 // Ethernet Expansion - Pin 14 - -#define E2_STEP_PIN P1_20 -#define E2_DIR_PIN P1_19 -#define E2_ENABLE_PIN P1_21 -#define E2_CS_PIN P1_18 // FET 6 +#define X_STEP_PIN P2_00 +#define X_DIR_PIN P0_05 +#define X_ENABLE_PIN P0_04 +#define X_CS_PIN P1_10 // Ethernet Expansion - Pin 9 + +#define Y_STEP_PIN P2_01 +#define Y_DIR_PIN P0_11 +#define Y_ENABLE_PIN P0_10 +#define Y_CS_PIN P1_09 // Ethernet Expansion - Pin 10 + +#define Z_STEP_PIN P2_02 +#define Z_DIR_PIN P0_20 +#define Z_ENABLE_PIN P0_19 +#define Z_CS_PIN P1_00 // Ethernet Expansion - Pin 11 + +#define E0_STEP_PIN P2_03 +#define E0_DIR_PIN P0_22 +#define E0_ENABLE_PIN P0_21 +#define E0_CS_PIN P1_04 // Ethernet Expansion - Pin 12 + +#define E1_STEP_PIN P2_08 +#define E1_DIR_PIN P2_13 +#define E1_ENABLE_PIN P4_29 +#define E1_CS_PIN P1_01 // Ethernet Expansion - Pin 14 + +#define E2_STEP_PIN P1_20 +#define E2_DIR_PIN P1_19 +#define E2_ENABLE_PIN P1_21 +#define E2_CS_PIN P1_18 // FET 6 // // Default pins for TMC software SPI // #if ENABLED(TMC_USE_SW_SPI) #ifndef TMC_SW_MOSI - #define TMC_SW_MOSI P1_16 // Ethernet Expansion - Pin 5 + #define TMC_SW_MOSI P1_16 // Ethernet Expansion - Pin 5 #endif #ifndef TMC_SW_MISO - #define TMC_SW_MISO P1_17 // Ethernet Expansion - Pin 6 + #define TMC_SW_MISO P1_17 // Ethernet Expansion - Pin 6 #endif #ifndef TMC_SW_SCK - #define TMC_SW_SCK P1_08 // Ethernet Expansion - Pin 7 + #define TMC_SW_SCK P1_08 // Ethernet Expansion - Pin 7 #endif #endif @@ -98,42 +105,48 @@ // Analog Inputs // 3.3V max when defined as an analog input // -#define TEMP_0_PIN P0_23_A0 -#define TEMP_BED_PIN P0_24_A1 -#define TEMP_1_PIN P0_25_A2 +#define TEMP_0_PIN P0_23_A0 +#define TEMP_BED_PIN P0_24_A1 +#define TEMP_1_PIN P0_25_A2 #if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILWIDTH_PIN P0_26_A3 + #define FILWIDTH_PIN P0_26_A3 #else - #define TEMP_2_PIN P0_26_A3 + #define TEMP_2_PIN P0_26_A3 #endif // // Heaters / Fans // -#define HEATER_BED_PIN P2_05 -#define HEATER_0_PIN P2_07 // FET 1 -#define HEATER_1_PIN P1_23 // FET 2 -#define HEATER_2_PIN P1_22 // FET 3 +#define HEATER_BED_PIN P2_05 +#define HEATER_0_PIN P2_07 // FET 1 +#define HEATER_1_PIN P1_23 // FET 2 +#define HEATER_2_PIN P1_22 // FET 3 #ifndef FAN_PIN - #define FAN_PIN P2_06 // FET 4 + #define FAN_PIN P2_06 // FET 4 #endif // // Auto fans // #if HOTENDS == 3 - #define AUTO_FAN_PIN P1_18 // FET 6 + #define AUTO_FAN_PIN P1_18 // FET 6 #else - #define AUTO_FAN_PIN P1_22 // FET 3 + #define AUTO_FAN_PIN P1_22 // FET 3 +#endif +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN AUTO_FAN_PIN +#endif +#ifndef E1_AUTO_FAN_PIN + #define E1_AUTO_FAN_PIN AUTO_FAN_PIN +#endif +#ifndef E2_AUTO_FAN_PIN + #define E2_AUTO_FAN_PIN AUTO_FAN_PIN #endif -#define ORIG_E0_AUTO_FAN_PIN AUTO_FAN_PIN -#define ORIG_E1_AUTO_FAN_PIN AUTO_FAN_PIN -#define ORIG_E2_AUTO_FAN_PIN AUTO_FAN_PIN // // Misc. Functions // -#define LED_PIN P4_28 // Play LED +#define LED_PIN P4_28 // Play LED // // M3/M4/M5 - Spindle/Laser Control @@ -142,9 +155,9 @@ #undef HEATER_0_PIN #undef HEATER_BED_PIN #undef FAN_PIN - #define SPINDLE_LASER_ENA_PIN P2_07 // FET 1 - #define SPINDLE_LASER_PWM_PIN P2_05 // Bed FET - #define SPINDLE_DIR_PIN P2_06 // FET 4 + #define SPINDLE_LASER_ENA_PIN P2_07 // FET 1 + #define SPINDLE_LASER_PWM_PIN P2_05 // Bed FET + #define SPINDLE_DIR_PIN P2_06 // FET 4 #endif // @@ -160,77 +173,77 @@ #if ENABLED(FYSETC_MINI_12864) - #define FORCE_SOFT_SPI // REQUIRED - results in LCD soft SPI mode 3 + #define FORCE_SOFT_SPI // REQUIRED - results in LCD soft SPI mode 3 - #define BEEPER_PIN P1_31 // EXP1-1 - #define BTN_ENC P1_30 // EXP1-2 - #define DOGLCD_CS P0_18 // EXP1-3 - #define DOGLCD_A0 P0_16 // EXP1-4 - #define LCD_RESET_PIN P0_15 // EXP1-5 + #define BEEPER_PIN P1_31 // EXP1-1 + #define BTN_ENC P1_30 // EXP1-2 + #define DOGLCD_CS P0_18 // EXP1-3 + #define DOGLCD_A0 P0_16 // EXP1-4 + #define LCD_RESET_PIN P0_15 // EXP1-5 // A custom cable is REQUIRED for EXP2 cable because the SCK & MOSI on the card's EXP2 are dedicated // to the onboard SD card. All required EXP2 signals come from the Ethernet connector. Pin 1 of this // connector is the one nearest the motor power connector. - #define DOGLCD_SCK P1_17 // EXP2-2 => Ethernet pin 5 (bottom, 3 from left) - #define BTN_EN2 P1_09 // EXP2-3 => Ethernet pin 9 (bottom, 5 from left) - #define BTN_EN1 P1_04 // EXP2-5 => Ethernet pin 11 (bottom, 6 from left) - #define DOGLCD_MOSI P1_01 // EXP2-6 => Ethernet pin 13 (bottom, 7 from left) + #define DOGLCD_SCK P1_17 // EXP2-2 => Ethernet pin 5 (bottom, 3 from left) + #define BTN_EN2 P1_09 // EXP2-3 => Ethernet pin 9 (bottom, 5 from left) + #define BTN_EN1 P1_04 // EXP2-5 => Ethernet pin 11 (bottom, 6 from left) + #define DOGLCD_MOSI P1_01 // EXP2-6 => Ethernet pin 13 (bottom, 7 from left) // A custom EXP1 cable is required colored LEDs. Pins 1-5, 9, 10 of the cable go to pins 1-5, 9, 10 // on the board's EXP1 connector. Pins 6, 7, and 8 of the EXP1 cable go to the Ethernet connector. // Rev 1.2 displays do NOT require the RGB LEDs. 2.0 and 2.1 displays do require RGB. #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) #ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN P1_16 // EXP1-6 => Ethernet pin 6 (top row, 3 from left) + #define RGB_LED_R_PIN P1_16 // EXP1-6 => Ethernet pin 6 (top row, 3 from left) #endif #ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN P1_10 // EXP1-7 => Ethernet pin 10 (top row, 5 from left) + #define RGB_LED_G_PIN P1_10 // EXP1-7 => Ethernet pin 10 (top row, 5 from left) #endif #ifndef RGB_LED_B_PIN - #define RGB_LED_B_PIN P1_00 // EXP1-8 => Ethernet pin 12 (top row, 6 from left) + #define RGB_LED_B_PIN P1_00 // EXP1-8 => Ethernet pin 12 (top row, 6 from left) #endif #elif ENABLED(FYSETC_MINI_12864_2_1) - #define NEOPIXEL_PIN P1_16 // EXP1-6 => Ethernet pin 6 (top row, 3 from left) + #define NEOPIXEL_PIN P1_16 // EXP1-6 => Ethernet pin 6 (top row, 3 from left) #endif -#elif HAS_SPI_LCD +#elif HAS_WIRED_LCD - #define BEEPER_PIN P1_31 // EXP1-1 - //#define SD_DETECT_PIN P0_27 // EXP2-7 + #define BEEPER_PIN P1_31 // EXP1-1 + //#define SD_DETECT_PIN P0_27 // EXP2-7 - #define BTN_EN1 P3_26 // EXP2-5 - #define BTN_EN2 P3_25 // EXP2-3 - #define BTN_ENC P1_30 // EXP1-2 + #define BTN_EN1 P3_26 // EXP2-5 + #define BTN_EN2 P3_25 // EXP2-3 + #define BTN_ENC P1_30 // EXP1-2 - #define LCD_PINS_RS P0_16 // EXP1-4 - #define LCD_SDSS P0_28 // EXP2-4 - #define LCD_PINS_ENABLE P0_18 // EXP1-3 - #define LCD_PINS_D4 P0_15 // EXP1-5 + #define LCD_PINS_RS P0_16 // EXP1-4 + #define LCD_SDSS P0_28 // EXP2-4 + #define LCD_PINS_ENABLE P0_18 // EXP1-3 + #define LCD_PINS_D4 P0_15 // EXP1-5 - #define KILL_PIN P2_11 // EXP2-10 + #define KILL_PIN P2_11 // EXP2-10 -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD // // SD Support // #ifndef SDCARD_CONNECTION - #define SDCARD_CONNECTION ONBOARD + #define SDCARD_CONNECTION ONBOARD #endif -#define ONBOARD_SD_CS_PIN P0_06 // Chip select for "System" SD card +#define ONBOARD_SD_CS_PIN P0_06 // Chip select for "System" SD card #if SD_CONNECTION_IS(LCD) - #define SCK_PIN P0_07 // (52) system defined J3-9 & AUX-3 - #define MISO_PIN P0_08 // (50) system defined J3-10 & AUX-3 - #define MOSI_PIN P0_09 // (51) system defined J3-10 & AUX-3 - #define SS_PIN P1_23 // (53) system defined J3-5 & AUX-3 (Sometimes called SDSS) - CS used by Marlin + #define SCK_PIN P0_07 // (52) system defined J3-9 & AUX-3 + #define MISO_PIN P0_08 // (50) system defined J3-10 & AUX-3 + #define MOSI_PIN P0_09 // (51) system defined J3-10 & AUX-3 + #define SS_PIN P1_23 // (53) system defined J3-5 & AUX-3 (Sometimes called SDSS) - CS used by Marlin #elif SD_CONNECTION_IS(ONBOARD) #undef SD_DETECT_PIN - #define SCK_PIN P0_07 - #define MISO_PIN P0_08 - #define MOSI_PIN P0_09 - #define SS_PIN ONBOARD_SD_CS_PIN + #define SCK_PIN P0_07 + #define MISO_PIN P0_08 + #define MOSI_PIN P0_09 + #define SS_PIN ONBOARD_SD_CS_PIN #elif SD_CONNECTION_IS(CUSTOM_CABLE) #error "No custom SD drive cable defined for this board." #endif @@ -238,16 +251,16 @@ // // Ethernet pins // -//#define ENET_MDIO P1_17 // Ethernet pin 5 (bottom, 3 from left) -//#define ENET_RX_ER P1_14 -//#define ENET_RXD1 P1_10 // Ethernet pin 10 (top row, 5 from left) -//#define ENET_MOC P1_16 // Ethernet pin 6 (top row, 3 from left) -//#define REF_CLK P1_15 -//#define ENET_RXD0 P1_09 // Ethernet pin 9 (bottom, 5 from left) -//#define ENET_CRS P1_08 // Ethernet pin 8 (top row, 4 from left) - INPUT ONLY -//#define ENET_TX_EN P1_04 // Ethernet pin 11 (bottom, 6 from left) -//#define ENET_TXD0 P1_00 // Ethernet pin 12 (top row, 6 from left) -//#define ENET_TXD1 P1_01 // Ethernet pin 13 (bottom, 7 from left) +//#define ENET_MDIO P1_17 // Ethernet pin 5 (bottom, 3 from left) +//#define ENET_RX_ER P1_14 +//#define ENET_RXD1 P1_10 // Ethernet pin 10 (top row, 5 from left) +//#define ENET_MOC P1_16 // Ethernet pin 6 (top row, 3 from left) +//#define REF_CLK P1_15 +//#define ENET_RXD0 P1_09 // Ethernet pin 9 (bottom, 5 from left) +//#define ENET_CRS P1_08 // Ethernet pin 8 (top row, 4 from left) - INPUT ONLY +//#define ENET_TX_EN P1_04 // Ethernet pin 11 (bottom, 6 from left) +//#define ENET_TXD0 P1_00 // Ethernet pin 12 (top row, 6 from left) +//#define ENET_TXD1 P1_01 // Ethernet pin 13 (bottom, 7 from left) /** * EXP1 pins diff --git a/Marlin/src/pins/lpc1769/pins_MKS_SGEN.h b/Marlin/src/pins/lpc1769/pins_MKS_SGEN.h index a5a91f6207b9..d67549997be5 100644 --- a/Marlin/src/pins/lpc1769/pins_MKS_SGEN.h +++ b/Marlin/src/pins/lpc1769/pins_MKS_SGEN.h @@ -16,53 +16,44 @@ * 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 . + * along with this program. If not, see . * */ #pragma once /** * MKS SGen pin assignments + * + * The pins diagram can be found and the following URL: + * https://github.com/makerbase-mks/MKS-SGen/blob/master/Hardware/MKS%20SGEN%20V1.0_001/MKS%20SGEN%20V1.0_001%20PIN.pdf */ -#ifndef MCU_LPC1769 +#if NOT_TARGET(MCU_LPC1769) #error "Oops! Make sure you have the LPC1769 environment selected in your IDE." #endif #define BOARD_INFO_NAME "MKS SGen" #define BOARD_WEBSITE_URL "github.com/makerbase-mks/MKS-SGEN" -#define MKS_HAS_LPC1769 +#define MKS_HAS_LPC1769 #include "../lpc1768/pins_MKS_SBASE.h" -#undef E1_STEP_PIN -#undef E1_DIR_PIN -#undef E1_ENABLE_PIN - -//#undef BTN_EN1 -//#undef BTN_EN2 -//#define BTN_EN1 P1_23 // EXP2.5 -//#define BTN_EN2 P1_22 // EXP2.3 - -#if HAS_TMC220x +#if HAS_TMC_UART /** * TMC2208/TMC2209 stepper drivers - * - * The shortage of pins becomes apparent. - * In the worst case you may have to give up the LCD. - * RX pins must be interrupt-capable. */ - #define X_SERIAL_TX_PIN P4_29 // J8-2 - #define X_SERIAL_RX_PIN P4_29 // J8-2 - - #define Y_SERIAL_TX_PIN P2_08 // J8-3 - #define Y_SERIAL_RX_PIN P2_08 // J8-3 - #define Z_SERIAL_TX_PIN P2_11 // J8-4 - #define Z_SERIAL_RX_PIN P2_11 // J8-4 - #define E0_SERIAL_TX_PIN P2_13 // J8-5 - #define E0_SERIAL_RX_PIN P2_13 // J8-5 + #define X_SERIAL_TX_PIN P1_22 // J8-2 + #define X_SERIAL_RX_PIN P1_22 // J8-2 + #define Y_SERIAL_TX_PIN P1_23 // J8-3 + #define Y_SERIAL_RX_PIN P1_23 // J8-3 + #define Z_SERIAL_TX_PIN P2_12 // J8-4 + #define Z_SERIAL_RX_PIN P2_12 // J8-4 + #define E0_SERIAL_TX_PIN P2_11 // J8-5 + #define E0_SERIAL_RX_PIN P2_11 // J8-5 + #define E1_SERIAL_TX_PIN P4_28 // J8-6 + #define E1_SERIAL_RX_PIN P4_28 // J8-6 // Reduce baud rate to improve software serial reliability - #define TMC_BAUD_RATE 19200 + #define TMC_BAUD_RATE 19200 #endif diff --git a/Marlin/src/pins/lpc1769/pins_MKS_SGEN_L_V2.h b/Marlin/src/pins/lpc1769/pins_MKS_SGEN_L_V2.h new file mode 100644 index 000000000000..62660935f5bd --- /dev/null +++ b/Marlin/src/pins/lpc1769/pins_MKS_SGEN_L_V2.h @@ -0,0 +1,367 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * MKS SGen pin assignments + */ + +#if NOT_TARGET(MCU_LPC1769) + #error "Oops! Make sure you have the LPC1769 environment selected in your IDE." +#endif + +#define BOARD_INFO_NAME "MKS SGEN_L V2" +#define BOARD_WEBSITE_URL "github.com/makerbase-mks" + +// +// EEPROM, MKS SGEN_L V2.0 hardware has 4K EEPROM on the board +// +#if NO_EEPROM_SELECTED + //#define SDCARD_EEPROM_EMULATION + //#define I2C_EEPROM // AT24C32 + #define FLASH_EEPROM_EMULATION + #define MARLIN_EEPROM_SIZE 0x1000 // 4KB +#endif + +// +// Servos +// +#define SERVO0_PIN P1_23 // SERVO P1.23 +#define SERVO1_PIN P2_00 // SERVO P2.0 + +// +// Trinamic Stallguard pins, can connect or disconnect by jumpers cap on the board +// +#define X_DIAG_PIN P1_29 // X- +#define Y_DIAG_PIN P1_27 // Y- +#define Z_DIAG_PIN P1_25 // Z- +#define E0_DIAG_PIN P1_28 // X+ +#define E1_DIAG_PIN P1_26 // Y+ + +// +// Limit Switches +// +#if X_STALL_SENSITIVITY + #define X_STOP_PIN X_DIAG_PIN + #if X_HOME_DIR < 0 + #define X_MAX_PIN P1_28 // X+ + #else + #define X_MIN_PIN P1_28 // X+ + #endif +#else + #define X_MIN_PIN P1_29 // X- + #define X_MAX_PIN P1_28 // X+ +#endif + +#if Y_STALL_SENSITIVITY + #define Y_STOP_PIN Y_DIAG_PIN + #if Y_HOME_DIR < 0 + #define Y_MAX_PIN P1_26 // Y+ + #else + #define Y_MIN_PIN P1_26 // Y+ + #endif +#else + #define Y_MIN_PIN P1_27 // Y- + #define Y_MAX_PIN P1_26 // Y+ +#endif + +#if Z_STALL_SENSITIVITY + #define Z_STOP_PIN Z_DIAG_PIN + #if Z_HOME_DIR < 0 + #define Z_MAX_PIN P1_24 // Z+ + #else + #define Z_MIN_PIN P1_24 // Z+ + #endif +#else + #define Z_MIN_PIN P1_25 // Z- + #define Z_MAX_PIN P1_24 // Z+ +#endif + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN P1_24 +#endif + +// +// Steppers +// +#define X_STEP_PIN P2_02 +#define X_DIR_PIN P2_03 +#define X_ENABLE_PIN P2_01 +#ifndef X_CS_PIN + #define X_CS_PIN P1_01 +#endif + +#define Y_STEP_PIN P0_19 +#define Y_DIR_PIN P0_20 +#define Y_ENABLE_PIN P2_08 +#ifndef Y_CS_PIN + #define Y_CS_PIN P1_08 +#endif + +#define Z_STEP_PIN P0_22 +#define Z_DIR_PIN P2_11 +#define Z_ENABLE_PIN P0_21 +#ifndef Z_CS_PIN + #define Z_CS_PIN P1_10 +#endif + +#define E0_STEP_PIN P2_13 +#define E0_DIR_PIN P0_11 +#define E0_ENABLE_PIN P2_12 +#ifndef E0_CS_PIN + #define E0_CS_PIN P1_15 +#endif + +#define E1_STEP_PIN P1_09 +#define E1_DIR_PIN P1_14 +#define E1_ENABLE_PIN P0_10 +#ifndef E1_CS_PIN + #define E1_CS_PIN P1_17 +#endif + +// +// Software SPI pins for TMC2130 stepper drivers +// +#if ENABLED(TMC_USE_SW_SPI) + #ifndef TMC_SW_MOSI + #define TMC_SW_MOSI P1_16 + #endif + #ifndef TMC_SW_MISO + #define TMC_SW_MISO P0_05 + #endif + #ifndef TMC_SW_SCK + #define TMC_SW_SCK P0_04 + #endif +#endif + +#if HAS_TMC_UART + /** + * TMC2208/TMC2209 stepper drivers + * + * Hardware serial communication ports. + * If undefined software serial is used according to the pins below + */ + //#define X_HARDWARE_SERIAL Serial1 + //#define X2_HARDWARE_SERIAL Serial1 + //#define Y_HARDWARE_SERIAL Serial1 + //#define Y2_HARDWARE_SERIAL Serial1 + //#define Z_HARDWARE_SERIAL Serial1 + //#define Z2_HARDWARE_SERIAL Serial1 + //#define E0_HARDWARE_SERIAL Serial1 + //#define E1_HARDWARE_SERIAL Serial1 + //#define E2_HARDWARE_SERIAL Serial1 + //#define E3_HARDWARE_SERIAL Serial1 + //#define E4_HARDWARE_SERIAL Serial1 + + // + // Software serial + // + #define X_SERIAL_TX_PIN P1_01 + #define X_SERIAL_RX_PIN P1_01 + #define Y_SERIAL_TX_PIN P1_08 + #define Y_SERIAL_RX_PIN P1_08 + #define Z_SERIAL_TX_PIN P1_10 + #define Z_SERIAL_RX_PIN P1_10 + #define E0_SERIAL_TX_PIN P1_15 + #define E0_SERIAL_RX_PIN P1_15 + #define E1_SERIAL_TX_PIN P1_17 + #define E1_SERIAL_RX_PIN P1_17 + + // Reduce baud rate to improve software serial reliability + #define TMC_BAUD_RATE 19200 +#endif // HAS_TMC_UART + +// +// Temperature Sensors +// 3.3V max when defined as an analog input +// +#define TEMP_0_PIN P0_23_A0 // Analog Input A0 (TH1) +#define TEMP_BED_PIN P0_24_A1 // Analog Input A1 (TB) +#define TEMP_1_PIN P0_25_A2 // Analog Input A2 (TH2) +#define TEMP_2_PIN P0_26_A3 // Analog Input A3 (P0.26, No pull up) + +// +// Heaters / Fans +// +#define HEATER_BED_PIN P2_05 +#define HEATER_0_PIN P2_07 +#if HAS_MULTI_HOTEND + #ifndef HEATER_1_PIN + #define HEATER_1_PIN P2_06 + #endif +#else + #ifndef FAN2_PIN + #define FAN2_PIN P2_06 // HE1 for FAN3 + #endif +#endif +#ifndef FAN_PIN + #define FAN_PIN P2_04 // FAN1 +#endif +#ifndef FAN1_PIN + #define FAN1_PIN P1_04 // FAN2 +#endif + +// +// Misc. Functions +// +#define LED_PIN P1_18 // Used as a status indicator +#define LED2_PIN P1_19 +#define LED3_PIN P1_20 +#define LED4_PIN P1_21 + +/** + * _____ _____ + * (BEEPER) 1.31 | · · | 1.30 (BTN_ENC) (MISO) 0.8 | · · | 0.7 (SD_SCK) + * (LCD_EN) 0.18 | · · | 0.16 (LCD_RS) (BTN_EN1) 3.25 | · · | 0.28 (SD_CS2) + * (LCD_D4) 0.15 | · ·| 0.17 (LCD_D5) (BTN_EN2) 3.26 | · ·| 0.9 (SD_MOSI) + * (LCD_D6) 1.0 | · · | 1.22 (LCD_D7) (SD_DETECT) 0.27 | · · | RST + * GND | · · | 5V GND | · · | NC + * ----- ----- + * EXP1 EXP2 + */ +#if IS_TFTGLCD_PANEL + + #if ENABLED(TFTGLCD_PANEL_SPI) + #define TFTGLCD_CS P3_25 + #endif + + #define SD_DETECT_PIN P0_27 + +#elif HAS_WIRED_LCD + + #define BEEPER_PIN P1_31 + #define BTN_ENC P1_30 + + #if ENABLED(CR10_STOCKDISPLAY) + + #define LCD_PINS_RS P1_00 + + #define BTN_EN1 P0_18 + #define BTN_EN2 P0_15 + + #define LCD_PINS_ENABLE P1_22 + #define LCD_PINS_D4 P0_17 + + #else + + #define BTN_EN1 P3_25 + #define BTN_EN2 P3_26 + + #define LCD_SDSS P0_28 + + #if ENABLED(MKS_12864OLED_SSD1306) + + #define LCD_PINS_DC P0_17 + #define DOGLCD_CS P0_16 + #define DOGLCD_A0 LCD_PINS_DC + #define DOGLCD_SCK P0_15 + #define DOGLCD_MOSI P0_18 + + #define LCD_PINS_RS P1_00 + #define LCD_PINS_D7 P1_22 + #define KILL_PIN -1 // NC + + #else // !MKS_12864OLED_SSD1306 + + #define LCD_PINS_RS P0_16 + + #define LCD_PINS_ENABLE P0_18 + #define LCD_PINS_D4 P0_15 + + #if ENABLED(FYSETC_MINI_12864) + + #define DOGLCD_CS P0_18 + #define DOGLCD_A0 P0_16 + #define DOGLCD_SCK P0_07 + #define DOGLCD_MOSI P1_20 + + #define LCD_BACKLIGHT_PIN -1 + + #define FORCE_SOFT_SPI // Use this if default of hardware SPI causes display problems + // results in LCD soft SPI mode 3, SD soft SPI mode 0 + + #define LCD_RESET_PIN P0_15 // Must be high or open for LCD to operate normally. + + #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) + #ifndef RGB_LED_R_PIN + #define RGB_LED_R_PIN P0_17 + #endif + #ifndef RGB_LED_G_PIN + #define RGB_LED_G_PIN P1_00 + #endif + #ifndef RGB_LED_B_PIN + #define RGB_LED_B_PIN P1_22 + #endif + #elif ENABLED(FYSETC_MINI_12864_2_1) + #define NEOPIXEL_PIN P0_17 + #endif + + #else // !FYSETC_MINI_12864 + + #if ENABLED(MKS_MINI_12864) + #define DOGLCD_CS P0_17 + #define DOGLCD_A0 P1_00 + #endif + + #if ENABLED(ULTIPANEL) + #define LCD_PINS_D5 P0_17 + #define LCD_PINS_D6 P1_00 + #define LCD_PINS_D7 P1_22 + #endif + + #endif // !FYSETC_MINI_12864 + + #endif // !MKS_12864OLED_SSD1306 + + #endif // !CR10_STOCKDISPLAY + +#endif // HAS_WIRED_LCD + +#ifndef SDCARD_CONNECTION + #define SDCARD_CONNECTION ONBOARD +#endif + +#define ONBOARD_SD_CS_PIN P0_06 // Chip select for "System" SD card + +#if SD_CONNECTION_IS(LCD) || SD_CONNECTION_IS(ONBOARD) + #define SD_DETECT_PIN P0_27 + #define SCK_PIN P0_07 + #define MISO_PIN P0_08 + #define MOSI_PIN P0_09 + #if SD_CONNECTION_IS(ONBOARD) + #define SS_PIN ONBOARD_SD_CS_PIN + #else + #define SS_PIN P0_28 + #endif +#elif SD_CONNECTION_IS(CUSTOM_CABLE) + #error "No custom SD drive cable defined for this board." +#endif + +// +// Other Pins +// +//#define PIN_P0_02 P0_02 // AUX1 (Interrupt Capable/ADC/Serial Port 0) +//#define PIN_P0_03 P0_03 // AUX1 (Interrupt Capable/ADC/Serial Port 0) +//#define PS_ON_PIN P1_23 // SERVO P1.23 diff --git a/Marlin/src/pins/lpc1769/pins_SMOOTHIEBOARD.h b/Marlin/src/pins/lpc1769/pins_SMOOTHIEBOARD.h index 5bf64e9d02fa..f2811b14abdc 100644 --- a/Marlin/src/pins/lpc1769/pins_SMOOTHIEBOARD.h +++ b/Marlin/src/pins/lpc1769/pins_SMOOTHIEBOARD.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Smoothieboard pin assignments */ -#ifndef MCU_LPC1769 +#if NOT_TARGET(MCU_LPC1769) #error "Oops! Make sure you have the LPC1769 environment selected in your IDE." #endif @@ -35,82 +35,147 @@ // // Servos // -#define SERVO0_PIN P1_23 +#define SERVO0_PIN P1_23 // // Limit Switches // -#define X_MIN_PIN P1_24 -#define X_MAX_PIN P1_25 -#define Y_MIN_PIN P1_26 -#define Y_MAX_PIN P1_27 -#define Z_MIN_PIN P1_28 -#define Z_MAX_PIN P1_29 +#define X_MIN_PIN P1_24 +#define X_MAX_PIN P1_25 +#define Y_MIN_PIN P1_26 +#define Y_MAX_PIN P1_27 +#define Z_MIN_PIN P1_28 +#define Z_MAX_PIN P1_29 // // Steppers // -#define X_STEP_PIN P2_00 -#define X_DIR_PIN P0_05 -#define X_ENABLE_PIN P0_04 +#define X_STEP_PIN P2_00 +#define X_DIR_PIN P0_05 +#define X_ENABLE_PIN P0_04 -#define Y_STEP_PIN P2_01 -#define Y_DIR_PIN P0_11 -#define Y_ENABLE_PIN P0_10 +#define Y_STEP_PIN P2_01 +#define Y_DIR_PIN P0_11 +#define Y_ENABLE_PIN P0_10 -#define Z_STEP_PIN P2_02 -#define Z_DIR_PIN P0_20 -#define Z_ENABLE_PIN P0_19 +#define Z_STEP_PIN P2_02 +#define Z_DIR_PIN P0_20 +#define Z_ENABLE_PIN P0_19 -#define E0_STEP_PIN P2_03 -#define E0_DIR_PIN P0_22 -#define E0_ENABLE_PIN P0_21 +#define E0_STEP_PIN P2_03 +#define E0_DIR_PIN P0_22 +#define E0_ENABLE_PIN P0_21 -#define E1_STEP_PIN P2_08 -#define E1_DIR_PIN P2_13 -#define E1_ENABLE_PIN P4_29 +#define E1_STEP_PIN P2_08 +#define E1_DIR_PIN P2_13 +#define E1_ENABLE_PIN P4_29 // // Temperature Sensors // 3.3V max when defined as an analog input // -#define TEMP_0_PIN P0_23_A0 // (T1) -#define TEMP_BED_PIN P0_24_A1 // (T2) -#define TEMP_1_PIN P0_25_A2 // (T3) -#define TEMP_2_PIN P0_26_A3 // (T4) +#define TEMP_0_PIN P0_23_A0 // (T1) +#define TEMP_BED_PIN P0_24_A1 // (T2) +#define TEMP_1_PIN P0_25_A2 // (T3) +#define TEMP_2_PIN P0_26_A3 // (T4) // // Heaters / Fans // -#define HEATER_BED_PIN P2_05 -#define HEATER_0_PIN P2_07 -#define HEATER_1_PIN P1_23 +#define HEATER_BED_PIN P2_05 +#define HEATER_0_PIN P2_07 +#define HEATER_1_PIN P1_23 #ifndef FAN_PIN - #define FAN_PIN P2_06 + #define FAN_PIN P2_06 #endif -#define FAN1_PIN P2_04 +#define FAN1_PIN P2_04 // // LCD / Controller // #if ANY(VIKI2, miniVIKI) - #define BEEPER_PIN P1_31 - #define DOGLCD_A0 P2_11 - #define DOGLCD_CS P0_16 + #define BEEPER_PIN P1_31 + #define DOGLCD_A0 P2_11 + #define DOGLCD_CS P0_16 + + #define BTN_EN1 P3_25 + #define BTN_EN2 P3_26 + #define BTN_ENC P1_30 + + #define SD_DETECT_PIN P1_18 + #define SDSS P1_21 + + #define STAT_LED_RED_PIN P1_19 + #define STAT_LED_BLUE_PIN P1_20 + +#elif HAS_WIRED_LCD + + /** + * SD Support + * + * For the RRD GLCD it CANNOT share the same SPI as the LCD so it must be + * hooked up to the onboard SDCard SPI and use a spare pin for the SDCS. + * Also note that an external SDCard sharing the SPI port with the + * onboard/internal SDCard must be ejected before rebooting as the bootloader + * does not like the external card. NOTE Smoothie will not boot if the external + * sdcard is inserted in the RRD LCD sdcard slot at boot time, it must be + * inserted after it has booted. + */ + #define SD_DETECT_PIN P0_27 // EXP2 Pin 7 (SD_CD, SD_DET) + + #define MISO_PIN P0_08 // EXP2 Pin 1 (PB3, SD_MISO) + #define SCK_PIN P0_07 // EXP2 Pin 2 (SD_SCK) + #define SS_PIN P0_28 // EXP2 Pin 4 (SD_CSEL, SD_CS) + #define MOSI_PIN P0_09 // EXP2 Pin 6 (PB2, SD_MOSI) + + /** + * The Smoothieboard supports the REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER with either + * a custom cable with breakouts to the pins indicated below or the RRD GLCD Adapter board + * found at http://smoothieware.org/rrdglcdadapter + * + * Other links to information about setting up a display panel with Smoothieboard + * http://chibidibidiwah.wdfiles.com/local--files/panel/smoothieboard2sd.jpg + * http://smoothieware.org/panel + */ + #if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) + // EXP1 Pins + #define BEEPER_PIN P1_31 // EXP1 Pin 1 + #define BTN_ENC P1_30 // EXP1 Pin 2 + #define LCD_PINS_ENABLE P0_18 // EXP1 Pin 3 (MOSI) + #define LCD_PINS_RS P0_16 // EXP1 Pin 4 (CS) + #define LCD_PINS_D4 P0_15 // EXP1 Pin 5 (SCK) + // EXP2 Pins + #define BTN_EN2 P3_26 // EXP2 Pin 3 + #define BTN_EN1 P3_25 // EXP2 Pin 5 + + #elif IS_TFTGLCD_PANEL + + #define SD_DETECT_PIN P0_27 // EXP2 Pin 7 (SD_CD, SD_DET) + + #if ENABLED(TFTGLCD_PANEL_SPI) + #define TFTGLCD_CS P3_26 // EXP2 Pin 3 + #endif + + #else + #error "Marlin's Smoothieboard support cannot drive your LCD." + #endif - #define BTN_EN1 P3_25 - #define BTN_EN2 P3_26 - #define BTN_ENC P1_30 - - #define SD_DETECT_PIN P1_18 - #define SDSS P1_21 - - #define STAT_LED_RED_PIN P1_19 - #define STAT_LED_BLUE_PIN P1_20 - -#elif HAS_SPI_LCD - - #error "Marlin's Smoothieboard support cannot drive your LCD." +#endif +/** + * I2C Digipots - MCP4451 + * Address 58 (2C << 1) + * Set from 0 - 127 with stop bit. + * (Ex. 3F << 1 | 1) + */ +#define DIGIPOTS_I2C_SCL P0_0 +#define DIGIPOTS_I2C_SDA_X P0_04 +#define DIGIPOTS_I2C_SDA_Y P0_10 +#define DIGIPOTS_I2C_SDA_Z P0_19 +#define DIGIPOTS_I2C_SDA_E0 P0_21 +#define DIGIPOTS_I2C_SDA_E1 P4_29 + +#ifndef DIGIPOT_I2C_ADDRESS_A + #define DIGIPOT_I2C_ADDRESS_A 0x2C // unshifted slave address (58 <- 2C << 1) #endif diff --git a/Marlin/src/pins/lpc1769/pins_TH3D_EZBOARD.h b/Marlin/src/pins/lpc1769/pins_TH3D_EZBOARD.h index 8f7d00bb3bdd..a0174f260298 100644 --- a/Marlin/src/pins/lpc1769/pins_TH3D_EZBOARD.h +++ b/Marlin/src/pins/lpc1769/pins_TH3D_EZBOARD.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * TH3D EZBoard pin assignments */ -#ifndef MCU_LPC1769 +#if NOT_TARGET(MCU_LPC1769) #error "Oops! Make sure you have the LPC1769 environment selected in your IDE." #endif @@ -35,111 +35,117 @@ // // Servos // -#define SERVO0_PIN P2_04 +#define SERVO0_PIN P2_04 // // Limit Switches // -#define X_STOP_PIN P1_24 -#define Y_STOP_PIN P1_25 -#define Z_STOP_PIN P1_26 +#define X_STOP_PIN P1_24 +#define Y_STOP_PIN P1_25 +#define Z_STOP_PIN P1_26 // // Filament Runout Sensor // #ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN P1_27 + #define FIL_RUNOUT_PIN P1_27 #endif // // Steppers // -#define X_STEP_PIN P2_00 -#define X_DIR_PIN P1_16 -#define X_ENABLE_PIN P1_17 +#define X_STEP_PIN P2_00 +#define X_DIR_PIN P1_16 +#define X_ENABLE_PIN P1_17 -#define Y_STEP_PIN P2_01 -#define Y_DIR_PIN P1_10 -#define Y_ENABLE_PIN P1_09 +#define Y_STEP_PIN P2_01 +#define Y_DIR_PIN P1_10 +#define Y_ENABLE_PIN P1_09 -#define Z_STEP_PIN P2_02 -#define Z_DIR_PIN P1_15 -#define Z_ENABLE_PIN P1_14 +#define Z_STEP_PIN P2_02 +#define Z_DIR_PIN P1_15 +#define Z_ENABLE_PIN P1_14 -#define E0_STEP_PIN P2_03 -#define E0_DIR_PIN P1_04 -#define E0_ENABLE_PIN P1_08 +#define E0_STEP_PIN P2_03 +#define E0_DIR_PIN P1_04 +#define E0_ENABLE_PIN P1_08 -#define E1_STEP_PIN P2_08 -#define E1_DIR_PIN P2_13 -#define E1_ENABLE_PIN P4_29 +#define E1_STEP_PIN P2_08 +#define E1_DIR_PIN P2_13 +#define E1_ENABLE_PIN P4_29 #if HAS_TMC_UART // // TMC220x stepper drivers // Software serial // - #define X_SERIAL_TX_PIN P0_04 - #define X_SERIAL_RX_PIN P0_05 - #define Y_SERIAL_TX_PIN P0_10 - #define Y_SERIAL_RX_PIN P0_11 - #define Z_SERIAL_TX_PIN P0_19 - #define Z_SERIAL_RX_PIN P0_20 - #define E0_SERIAL_TX_PIN P0_22 - #define E0_SERIAL_RX_PIN P0_21 + #define X_SERIAL_TX_PIN P0_04 + #define X_SERIAL_RX_PIN P0_05 + #define Y_SERIAL_TX_PIN P0_10 + #define Y_SERIAL_RX_PIN P0_11 + #define Z_SERIAL_TX_PIN P0_19 + #define Z_SERIAL_RX_PIN P0_20 + #define E0_SERIAL_TX_PIN P0_22 + #define E0_SERIAL_RX_PIN P0_21 // Reduce baud rate to improve software serial reliability - #define TMC_BAUD_RATE 19200 + #define TMC_BAUD_RATE 19200 #endif // // Temp Sensors // 3.3V max when defined as an Analog Input! // -#if TEMP_SENSOR_0 == 20 // PT100 Adapter - #define TEMP_0_PIN P0_02_A7 // Analog Input +#if TEMP_SENSOR_0 == 20 // PT100 Adapter + #define TEMP_0_PIN P0_02_A7 // Analog Input #else - #define TEMP_0_PIN P0_23_A0 // Analog Input P0_23 + #define TEMP_0_PIN P0_23_A0 // Analog Input P0_23 #endif -#define TEMP_BED_PIN P0_24_A1 // Analog Input P0_24 -#define TEMP_1_PIN P0_25_A2 // Analog Input P0_25 +#define TEMP_BED_PIN P0_24_A1 // Analog Input P0_24 +#define TEMP_1_PIN P0_25_A2 // Analog Input P0_25 #if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILWIDTH_PIN P0_26_A3 // Analog Input P0_26 + #define FILWIDTH_PIN P0_26_A3 // Analog Input P0_26 #else - #define TEMP_2_PIN P0_26_A3 // Analog Input P0_26 + #define TEMP_2_PIN P0_26_A3 // Analog Input P0_26 #endif // // Heaters / Fans // -#define HEATER_BED_PIN P2_05 -#define HEATER_0_PIN P2_07 +#define HEATER_BED_PIN P2_05 +#define HEATER_0_PIN P2_07 #ifndef FAN_PIN - #define FAN_PIN P2_06 + #define FAN_PIN P2_06 #endif -#define FAN1_PIN P1_22 +#define FAN1_PIN P1_22 // // Auto fans // -#define AUTO_FAN_PIN P1_22 // FET 3 -#define ORIG_E0_AUTO_FAN_PIN AUTO_FAN_PIN -#define ORIG_E1_AUTO_FAN_PIN AUTO_FAN_PIN -#define ORIG_E2_AUTO_FAN_PIN AUTO_FAN_PIN +#define AUTO_FAN_PIN P1_22 // FET 3 +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN AUTO_FAN_PIN +#endif +#ifndef E1_AUTO_FAN_PIN + #define E1_AUTO_FAN_PIN AUTO_FAN_PIN +#endif +#ifndef E2_AUTO_FAN_PIN + #define E2_AUTO_FAN_PIN AUTO_FAN_PIN +#endif // // SD Card // -#define SDCARD_CONNECTION ONBOARD +#define SDCARD_CONNECTION ONBOARD -#define SCK_PIN P0_07 -#define MISO_PIN P0_08 -#define MOSI_PIN P0_09 -#define ONBOARD_SD_CS_PIN P0_06 -#define SS_PIN ONBOARD_SD_CS_PIN +#define SCK_PIN P0_07 +#define MISO_PIN P0_08 +#define MOSI_PIN P0_09 +#define ONBOARD_SD_CS_PIN P0_06 +#define SS_PIN ONBOARD_SD_CS_PIN // // LCD / Controller @@ -160,18 +166,17 @@ * * A remote SD card is currently not supported because the pins routed to the EXP2 * connector are shared with the onboard SD card. - * */ #if ENABLED(CR10_STOCKDISPLAY) - #define BEEPER_PIN P1_31 - #define BTN_EN1 P3_26 - #define BTN_EN2 P3_25 - #define BTN_ENC P1_30 - #define LCD_PINS_RS P0_16 - #define LCD_PINS_ENABLE P0_18 - #define LCD_PINS_D4 P0_15 - #define KILL_PIN P2_11 -#elif HAS_SPI_LCD + #define BEEPER_PIN P1_31 + #define BTN_EN1 P3_26 + #define BTN_EN2 P3_25 + #define BTN_ENC P1_30 + #define LCD_PINS_RS P0_16 + #define LCD_PINS_ENABLE P0_18 + #define LCD_PINS_D4 P0_15 + #define KILL_PIN P2_11 +#elif HAS_WIRED_LCD #error "Only the CR10_STOCKDISPLAY is supported with TH3D EZBoard." #endif diff --git a/Marlin/src/pins/mega/pins_CHEAPTRONIC.h b/Marlin/src/pins/mega/pins_CHEAPTRONIC.h index de064559af70..98427d9e592a 100644 --- a/Marlin/src/pins/mega/pins_CHEAPTRONIC.h +++ b/Marlin/src/pins/mega/pins_CHEAPTRONIC.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Cheaptronic v1.0 pin assignments */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -33,46 +33,46 @@ // // Limit Switches // -#define X_STOP_PIN 3 -#define Y_STOP_PIN 2 -#define Z_STOP_PIN 5 +#define X_STOP_PIN 3 +#define Y_STOP_PIN 2 +#define Z_STOP_PIN 5 // // Steppers // -#define X_STEP_PIN 14 -#define X_DIR_PIN 15 -#define X_ENABLE_PIN 24 +#define X_STEP_PIN 14 +#define X_DIR_PIN 15 +#define X_ENABLE_PIN 24 -#define Y_STEP_PIN 35 -#define Y_DIR_PIN 36 -#define Y_ENABLE_PIN 31 +#define Y_STEP_PIN 35 +#define Y_DIR_PIN 36 +#define Y_ENABLE_PIN 31 -#define Z_STEP_PIN 40 -#define Z_DIR_PIN 41 -#define Z_ENABLE_PIN 37 +#define Z_STEP_PIN 40 +#define Z_DIR_PIN 41 +#define Z_ENABLE_PIN 37 -#define E0_STEP_PIN 26 -#define E0_DIR_PIN 28 -#define E0_ENABLE_PIN 25 +#define E0_STEP_PIN 26 +#define E0_DIR_PIN 28 +#define E0_ENABLE_PIN 25 -#define E1_STEP_PIN 33 -#define E1_DIR_PIN 34 -#define E1_ENABLE_PIN 30 +#define E1_STEP_PIN 33 +#define E1_DIR_PIN 34 +#define E1_ENABLE_PIN 30 // // Temperature sensors // -#define TEMP_0_PIN 15 // Analog Input -#define TEMP_1_PIN 14 // Analog Input -#define TEMP_BED_PIN 13 // Analog Input +#define TEMP_0_PIN 15 // Analog Input +#define TEMP_1_PIN 14 // Analog Input +#define TEMP_BED_PIN 13 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 19 // EXTRUDER 1 -#define HEATER_1_PIN 23 // EXTRUDER 2 -#define HEATER_BED_PIN 22 +#define HEATER_0_PIN 19 // EXTRUDER 1 +#define HEATER_1_PIN 23 // EXTRUDER 2 +#define HEATER_BED_PIN 22 // // LCD / Controller diff --git a/Marlin/src/pins/mega/pins_CHEAPTRONICv2.h b/Marlin/src/pins/mega/pins_CHEAPTRONICv2.h index 5fd5bfdef13f..3a84f4395f3a 100644 --- a/Marlin/src/pins/mega/pins_CHEAPTRONICv2.h +++ b/Marlin/src/pins/mega/pins_CHEAPTRONICv2.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -27,7 +27,7 @@ * www.reprapobchod.cz */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -36,101 +36,101 @@ // // Limit Switches // -#define X_MIN_PIN 30 -#define X_MAX_PIN 31 -#define Y_MIN_PIN 32 -#define Y_MAX_PIN 33 -#define Z_MIN_PIN 34 -#define Z_MAX_PIN 35 +#define X_MIN_PIN 30 +#define X_MAX_PIN 31 +#define Y_MIN_PIN 32 +#define Y_MAX_PIN 33 +#define Z_MIN_PIN 34 +#define Z_MAX_PIN 35 // // Steppers // -#define X_STEP_PIN 17 -#define X_DIR_PIN 16 -#define X_ENABLE_PIN 48 +#define X_STEP_PIN 17 +#define X_DIR_PIN 16 +#define X_ENABLE_PIN 48 -#define Y_STEP_PIN 54 -#define Y_DIR_PIN 47 -#define Y_ENABLE_PIN 55 +#define Y_STEP_PIN 54 +#define Y_DIR_PIN 47 +#define Y_ENABLE_PIN 55 -#define Z_STEP_PIN 57 -#define Z_DIR_PIN 56 -#define Z_ENABLE_PIN 62 +#define Z_STEP_PIN 57 +#define Z_DIR_PIN 56 +#define Z_ENABLE_PIN 62 -#define E0_STEP_PIN 23 -#define E0_DIR_PIN 22 -#define E0_ENABLE_PIN 24 +#define E0_STEP_PIN 23 +#define E0_DIR_PIN 22 +#define E0_ENABLE_PIN 24 -#define E1_STEP_PIN 26 -#define E1_DIR_PIN 25 -#define E1_ENABLE_PIN 27 +#define E1_STEP_PIN 26 +#define E1_DIR_PIN 25 +#define E1_ENABLE_PIN 27 -#define E2_STEP_PIN 29 -#define E2_DIR_PIN 28 -#define E2_ENABLE_PIN 39 +#define E2_STEP_PIN 29 +#define E2_DIR_PIN 28 +#define E2_ENABLE_PIN 39 // // Temperature sensors // -#define TEMP_0_PIN 15 -#define TEMP_1_PIN 13 -#define TEMP_2_PIN 14 -#define TEMP_3_PIN 11 // should be used for chamber temperature control -#define TEMP_BED_PIN 12 +#define TEMP_0_PIN 15 +#define TEMP_1_PIN 13 +#define TEMP_2_PIN 14 +#define TEMP_3_PIN 11 // should be used for chamber temperature control +#define TEMP_BED_PIN 12 // // Heaters / Fans // -#define HEATER_0_PIN 6 -#define HEATER_1_PIN 7 -#define HEATER_2_PIN 8 -#define HEATER_BED_PIN 9 +#define HEATER_0_PIN 6 +#define HEATER_1_PIN 7 +#define HEATER_2_PIN 8 +#define HEATER_BED_PIN 9 #ifndef FAN_PIN - #define FAN_PIN 3 + #define FAN_PIN 3 #endif -#define FAN2_PIN 58 // additional fan or light control output +#define FAN2_PIN 58 // additional fan or light control output // // Other board specific pins // #ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN 37 // board input labeled as F-DET + #define FIL_RUNOUT_PIN 37 // board input labeled as F-DET #endif -#define Z_MIN_PROBE_PIN 36 // additional external board input labeled as E-SENS (should be used for Z-probe) -#define LED_PIN 13 -#define SPINDLE_ENABLE_PIN 4 // additional PWM pin 1 at JP1 connector - should be used for laser control too -#define EXT_2 5 // additional PWM pin 2 at JP1 connector -#define EXT_3 2 // additional PWM pin 3 at JP1 connector -#define PS_ON_PIN 45 -#define KILL_PIN 46 +#define Z_MIN_PROBE_PIN 36 // additional external board input labeled as E-SENS (should be used for Z-probe) +#define LED_PIN 13 +#define SPINDLE_ENABLE_PIN 4 // additional PWM pin 1 at JP1 connector - should be used for laser control too +#define EXT_2 5 // additional PWM pin 2 at JP1 connector +#define EXT_3 2 // additional PWM pin 3 at JP1 connector +#define PS_ON_PIN 45 +#define KILL_PIN 46 #ifndef FILWIDTH_PIN - #define FILWIDTH_PIN 11 // shared with TEMP_3 analog input + #define FILWIDTH_PIN 11 // shared with TEMP_3 analog input #endif // // LCD / Controller // -#define LCD_PINS_RS 19 -#define LCD_PINS_ENABLE 42 -#define LCD_PINS_D4 18 -#define LCD_PINS_D5 38 -#define LCD_PINS_D6 41 -#define LCD_PINS_D7 40 +#define LCD_PINS_RS 19 +#define LCD_PINS_ENABLE 42 +#define LCD_PINS_D4 18 +#define LCD_PINS_D5 38 +#define LCD_PINS_D6 41 +#define LCD_PINS_D7 40 // // Beeper, SD Card, Encoder // -#define BEEPER_PIN 44 +#define BEEPER_PIN 44 #if ENABLED(SDSUPPORT) - #define SDSS 53 - #define SD_DETECT_PIN 49 + #define SDSS 53 + #define SD_DETECT_PIN 49 #endif #if ENABLED(NEWPANEL) - #define BTN_EN1 11 - #define BTN_EN2 12 - #define BTN_ENC 43 + #define BTN_EN1 11 + #define BTN_EN2 12 + #define BTN_ENC 43 #endif diff --git a/Marlin/src/pins/mega/pins_CNCONTROLS_11.h b/Marlin/src/pins/mega/pins_CNCONTROLS_11.h index 047dc8ef5afa..675d4b7262f8 100644 --- a/Marlin/src/pins/mega/pins_CNCONTROLS_11.h +++ b/Marlin/src/pins/mega/pins_CNCONTROLS_11.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * CartesioV11 pin assignments */ -#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) +#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -34,115 +34,127 @@ // // Limit Switches // -#define X_STOP_PIN 43 -#define Y_STOP_PIN 45 -#define Z_STOP_PIN 42 +#define X_STOP_PIN 43 +#define Y_STOP_PIN 45 +#define Z_STOP_PIN 42 // // Steppers // -#define X_STEP_PIN 34 -#define X_DIR_PIN 36 -#define X_ENABLE_PIN 35 +#define X_STEP_PIN 34 +#define X_DIR_PIN 36 +#define X_ENABLE_PIN 35 -#define Y_STEP_PIN 37 -#define Y_DIR_PIN 39 -#define Y_ENABLE_PIN 38 +#define Y_STEP_PIN 37 +#define Y_DIR_PIN 39 +#define Y_ENABLE_PIN 38 -#define Z_STEP_PIN 40 -#define Z_DIR_PIN 48 -#define Z_ENABLE_PIN 41 +#define Z_STEP_PIN 40 +#define Z_DIR_PIN 48 +#define Z_ENABLE_PIN 41 -#define E0_STEP_PIN 29 -#define E0_DIR_PIN 28 -#define E0_ENABLE_PIN 3 +#define E0_STEP_PIN 29 +#define E0_DIR_PIN 28 +#define E0_ENABLE_PIN 3 -#define E1_STEP_PIN 61 -#define E1_DIR_PIN 62 -#define E1_ENABLE_PIN 60 +#define E1_STEP_PIN 61 +#define E1_DIR_PIN 62 +#define E1_ENABLE_PIN 60 -#define E2_STEP_PIN 15 -#define E2_DIR_PIN 14 -#define E2_ENABLE_PIN 16 +#define E2_STEP_PIN 15 +#define E2_DIR_PIN 14 +#define E2_ENABLE_PIN 16 -#define E3_STEP_PIN 44 -#define E3_DIR_PIN 49 -#define E3_ENABLE_PIN 47 +#define E3_STEP_PIN 44 +#define E3_DIR_PIN 49 +#define E3_ENABLE_PIN 47 // // Temperature Sensors // -#define TEMP_0_PIN 0 // Analog Input -#define TEMP_1_PIN 3 // Analog Input. 3 for tool2 -> 2 for chambertemp -#define TEMP_2_PIN 2 // Analog Input. 9 for tool3 -> 2 for chambertemp -#define TEMP_3_PIN 11 // Analog Input. 11 for tool4 -> 2 for chambertemp -#define TEMP_BED_PIN 1 // Analog Input +#define TEMP_0_PIN 0 // Analog Input +#define TEMP_1_PIN 3 // Analog Input. 3 for tool2 -> 2 for chambertemp +#define TEMP_2_PIN 2 // Analog Input. 9 for tool3 -> 2 for chambertemp +#define TEMP_3_PIN 11 // Analog Input. 11 for tool4 -> 2 for chambertemp +#define TEMP_BED_PIN 1 // Analog Input #ifndef TEMP_CHAMBER_PIN - //#define TEMP_CHAMBER_PIN 2 // Analog Input + //#define TEMP_CHAMBER_PIN 2 // Analog Input #endif // // Heaters / Fans // -#define HEATER_0_PIN 5 -#define HEATER_1_PIN 58 -#define HEATER_2_PIN 64 -#define HEATER_3_PIN 46 -#define HEATER_BED_PIN 2 +#define HEATER_0_PIN 5 +#define HEATER_1_PIN 58 +#define HEATER_2_PIN 64 +#define HEATER_3_PIN 46 +#define HEATER_BED_PIN 2 #ifndef FAN_PIN - //#define FAN_PIN 7 // common PWM pin for all tools + //#define FAN_PIN 7 // common PWM pin for all tools #endif -#define ORIG_E0_AUTO_FAN_PIN 7 -#define ORIG_E1_AUTO_FAN_PIN 7 -#define ORIG_E2_AUTO_FAN_PIN 7 -#define ORIG_E3_AUTO_FAN_PIN 7 +// +// Auto fans +// +#define AUTO_FAN_PIN 7 +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN AUTO_FAN_PIN +#endif +#ifndef E1_AUTO_FAN_PIN + #define E1_AUTO_FAN_PIN AUTO_FAN_PIN +#endif +#ifndef E2_AUTO_FAN_PIN + #define E2_AUTO_FAN_PIN AUTO_FAN_PIN +#endif +#ifndef E3_AUTO_FAN_PIN + #define E3_AUTO_FAN_PIN AUTO_FAN_PIN +#endif // // Misc. Functions // -#define SDSS 53 -#define SD_DETECT_PIN 13 +#define SDSS 53 +#define SD_DETECT_PIN 13 // Tools -//#define TOOL_0_PIN 4 -//#define TOOL_1_PIN 59 -//#define TOOL_2_PIN 8 -//#define TOOL_3_PIN 30 -//#define TOOL_PWM_PIN 7 // common PWM pin for all tools +//#define TOOL_0_PIN 4 +//#define TOOL_1_PIN 59 +//#define TOOL_2_PIN 8 +//#define TOOL_3_PIN 30 +//#define TOOL_PWM_PIN 7 // common PWM pin for all tools // Common I/O -//#define FIL_RUNOUT_PIN -1 -//#define PWM_1_PIN 11 -//#define PWM_2_PIN 10 -//#define SPARE_IO 12 +//#define FIL_RUNOUT_PIN -1 +//#define PWM_1_PIN 11 +//#define PWM_2_PIN 10 +//#define SPARE_IO 12 // // LCD / Controller // -#define BEEPER_PIN 6 +#define BEEPER_PIN 6 // Pins for DOGM SPI LCD Support -#define DOGLCD_A0 26 -#define DOGLCD_CS 24 -#define DOGLCD_MOSI -1 -#define DOGLCD_SCK -1 +#define DOGLCD_A0 26 +#define DOGLCD_CS 24 +#define DOGLCD_MOSI -1 +#define DOGLCD_SCK -1 -#define BTN_EN1 23 -#define BTN_EN2 25 -#define BTN_ENC 27 +#define BTN_EN1 23 +#define BTN_EN2 25 +#define BTN_ENC 27 // Hardware buttons for manual movement of XYZ -#define SHIFT_OUT 19 -#define SHIFT_LD 18 -#define SHIFT_CLK 17 +#define SHIFT_OUT 19 +#define SHIFT_LD 18 +#define SHIFT_CLK 17 -//#define UI1 31 -//#define UI2 22 +//#define UI1 31 +//#define UI2 22 -#define STAT_LED_BLUE_PIN -1 -#define STAT_LED_RED_PIN 31 +#define STAT_LED_BLUE_PIN -1 +#define STAT_LED_RED_PIN 31 diff --git a/Marlin/src/pins/mega/pins_CNCONTROLS_12.h b/Marlin/src/pins/mega/pins_CNCONTROLS_12.h index 246a5964f063..35426a453139 100644 --- a/Marlin/src/pins/mega/pins_CNCONTROLS_12.h +++ b/Marlin/src/pins/mega/pins_CNCONTROLS_12.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * CartesioV12 pin assignments */ -#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) +#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -34,122 +34,134 @@ // // Limit Switches // -#define X_STOP_PIN 19 -#define Y_STOP_PIN 22 -#define Z_STOP_PIN 23 +#define X_STOP_PIN 19 +#define Y_STOP_PIN 22 +#define Z_STOP_PIN 23 // // Steppers // -#define X_STEP_PIN 25 -#define X_DIR_PIN 27 -#define X_ENABLE_PIN 26 +#define X_STEP_PIN 25 +#define X_DIR_PIN 27 +#define X_ENABLE_PIN 26 -#define Y_STEP_PIN 28 -#define Y_DIR_PIN 30 -#define Y_ENABLE_PIN 29 +#define Y_STEP_PIN 28 +#define Y_DIR_PIN 30 +#define Y_ENABLE_PIN 29 -#define Z_STEP_PIN 31 -#define Z_DIR_PIN 33 -#define Z_ENABLE_PIN 32 +#define Z_STEP_PIN 31 +#define Z_DIR_PIN 33 +#define Z_ENABLE_PIN 32 -#define E0_STEP_PIN 57 -#define E0_DIR_PIN 55 -#define E0_ENABLE_PIN 58 +#define E0_STEP_PIN 57 +#define E0_DIR_PIN 55 +#define E0_ENABLE_PIN 58 -#define E1_STEP_PIN 61 -#define E1_DIR_PIN 62 -#define E1_ENABLE_PIN 60 +#define E1_STEP_PIN 61 +#define E1_DIR_PIN 62 +#define E1_ENABLE_PIN 60 -#define E2_STEP_PIN 46 -#define E2_DIR_PIN 66 -#define E2_ENABLE_PIN 44 +#define E2_STEP_PIN 46 +#define E2_DIR_PIN 66 +#define E2_ENABLE_PIN 44 -#define E3_STEP_PIN 45 -#define E3_DIR_PIN 69 -#define E3_ENABLE_PIN 47 +#define E3_STEP_PIN 45 +#define E3_DIR_PIN 69 +#define E3_ENABLE_PIN 47 // // Temperature Sensors // -#define TEMP_0_PIN 0 // Analog Input -#define TEMP_1_PIN 9 // Analog Input. 9 for tool2 -> 13 for chambertemp -#define TEMP_2_PIN 13 // Analog Input. 10 for tool3 -> 13 for chambertemp -#define TEMP_3_PIN 11 // Analog Input. 11 for tool4 -> 13 for chambertemp -#define TEMP_BED_PIN 14 // Analog Input +#define TEMP_0_PIN 0 // Analog Input +#define TEMP_1_PIN 9 // Analog Input. 9 for tool2 -> 13 for chambertemp +#define TEMP_2_PIN 13 // Analog Input. 10 for tool3 -> 13 for chambertemp +#define TEMP_3_PIN 11 // Analog Input. 11 for tool4 -> 13 for chambertemp +#define TEMP_BED_PIN 14 // Analog Input #ifndef TEMP_CHAMBER_PIN - //#define TEMP_CHAMBER_PIN 13 // Analog Input + //#define TEMP_CHAMBER_PIN 13 // Analog Input #endif // // Heaters / Fans // -#define HEATER_0_PIN 11 -#define HEATER_1_PIN 9 -#define HEATER_2_PIN 6 -#define HEATER_3_PIN 3 -#define HEATER_BED_PIN 24 +#define HEATER_0_PIN 11 +#define HEATER_1_PIN 9 +#define HEATER_2_PIN 6 +#define HEATER_3_PIN 3 +#define HEATER_BED_PIN 24 #ifndef FAN_PIN - #define FAN_PIN 5 // 5 is PWMtool3 -> 7 is common PWM pin for all tools + #define FAN_PIN 5 // 5 is PWMtool3 -> 7 is common PWM pin for all tools #endif -#define ORIG_E0_AUTO_FAN_PIN 7 -#define ORIG_E1_AUTO_FAN_PIN 7 -#define ORIG_E2_AUTO_FAN_PIN 7 -#define ORIG_E3_AUTO_FAN_PIN 7 +// +// Auto fans +// +#define AUTO_FAN_PIN 7 +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN AUTO_FAN_PIN +#endif +#ifndef E1_AUTO_FAN_PIN + #define E1_AUTO_FAN_PIN AUTO_FAN_PIN +#endif +#ifndef E2_AUTO_FAN_PIN + #define E2_AUTO_FAN_PIN AUTO_FAN_PIN +#endif +#ifndef E3_AUTO_FAN_PIN + #define E3_AUTO_FAN_PIN AUTO_FAN_PIN +#endif // // Misc. Functions // -#define SDSS 53 -#define SD_DETECT_PIN 15 +#define SDSS 53 +#define SD_DETECT_PIN 15 // Tools -//#define TOOL_0_PIN 56 -//#define TOOL_0_PWM_PIN 10 // red warning led at dual extruder -//#define TOOL_1_PIN 59 -//#define TOOL_1_PWM_PIN 8 // lights at dual extruder -//#define TOOL_2_PIN 4 -//#define TOOL_2_PWM_PIN 5 -//#define TOOL_3_PIN 14 -//#define TOOL_3_PWM_PIN 2 +//#define TOOL_0_PIN 56 +//#define TOOL_0_PWM_PIN 10 // red warning led at dual extruder +//#define TOOL_1_PIN 59 +//#define TOOL_1_PWM_PIN 8 // lights at dual extruder +//#define TOOL_2_PIN 4 +//#define TOOL_2_PWM_PIN 5 +//#define TOOL_3_PIN 14 +//#define TOOL_3_PWM_PIN 2 // Common I/O #ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN 18 + #define FIL_RUNOUT_PIN 18 #endif -//#define PWM_1_PIN 12 -//#define PWM_2_PIN 13 -//#define SPARE_IO 17 +//#define PWM_1_PIN 12 +//#define PWM_2_PIN 13 +//#define SPARE_IO 17 // // LCD / Controller // -#define BEEPER_PIN 16 +#define BEEPER_PIN 16 // Pins for DOGM SPI LCD Support -#define DOGLCD_A0 39 -#define DOGLCD_CS 35 -#define DOGLCD_MOSI 48 -#define DOGLCD_SCK 49 +#define DOGLCD_A0 39 +#define DOGLCD_CS 35 +#define DOGLCD_MOSI 48 +#define DOGLCD_SCK 49 #define LCD_SCREEN_ROT_180 // The encoder and click button -#define BTN_EN1 36 -#define BTN_EN2 34 -#define BTN_ENC 38 +#define BTN_EN1 36 +#define BTN_EN2 34 +#define BTN_ENC 38 // Hardware buttons for manual movement of XYZ -#define SHIFT_OUT 42 -#define SHIFT_LD 41 -#define SHIFT_CLK 40 +#define SHIFT_OUT 42 +#define SHIFT_LD 41 +#define SHIFT_CLK 40 -//#define UI1 43 -//#define UI2 37 +//#define UI1 43 +//#define UI2 37 -#define STAT_LED_BLUE_PIN -1 -#define STAT_LED_RED_PIN 10 // TOOL_0_PWM_PIN +#define STAT_LED_BLUE_PIN -1 +#define STAT_LED_RED_PIN 10 // TOOL_0_PWM_PIN diff --git a/Marlin/src/pins/mega/pins_CNCONTROLS_15.h b/Marlin/src/pins/mega/pins_CNCONTROLS_15.h index bf7d65f7e7b0..8bafbdf00058 100644 --- a/Marlin/src/pins/mega/pins_CNCONTROLS_15.h +++ b/Marlin/src/pins/mega/pins_CNCONTROLS_15.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * CNControls V15 for HMS434 pin assignments */ -#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) +#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -34,79 +34,94 @@ // // Servos // -#define SERVO0_PIN 6 +#define SERVO0_PIN 6 // // Limit Switches // -#define X_STOP_PIN 34 -#define Y_STOP_PIN 39 -#define Z_STOP_PIN 62 +#define X_STOP_PIN 34 +#define Y_STOP_PIN 39 +#define Z_STOP_PIN 62 #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 49 + #define Z_MIN_PROBE_PIN 49 #endif // // Steppers // -#define X_STEP_PIN 14 -#define X_DIR_PIN 25 -#define X_ENABLE_PIN 26 +#define X_STEP_PIN 14 +#define X_DIR_PIN 25 +#define X_ENABLE_PIN 26 -#define Y_STEP_PIN 11 -#define Y_DIR_PIN 12 -#define Y_ENABLE_PIN 15 +#define Y_STEP_PIN 11 +#define Y_DIR_PIN 12 +#define Y_ENABLE_PIN 15 -#define Z_STEP_PIN 24 -#define Z_DIR_PIN 27 -#define Z_ENABLE_PIN 28 +#define Z_STEP_PIN 24 +#define Z_DIR_PIN 27 +#define Z_ENABLE_PIN 28 -#define E0_STEP_PIN 64 -#define E0_DIR_PIN 65 -#define E0_ENABLE_PIN 63 +#define E0_STEP_PIN 64 +#define E0_DIR_PIN 65 +#define E0_ENABLE_PIN 63 // // Temperature Sensors // Analog Inputs // -#define TEMP_0_PIN 2 // Analog Input -#define TEMP_BED_PIN 4 // Analog Input +#define TEMP_0_PIN 2 // Analog Input +#define TEMP_BED_PIN 4 // Analog Input #ifndef TEMP_CHAMBER_PIN - #define TEMP_CHAMBER_PIN 5 // Analog Input + #define TEMP_CHAMBER_PIN 5 // Analog Input #endif // // Heaters // -#define HEATER_0_PIN 4 -#define HEATER_BED_PIN 32 -#define HEATER_CHAMBER_PIN 33 +#define HEATER_0_PIN 4 +#define HEATER_BED_PIN 32 +#define HEATER_CHAMBER_PIN 33 // // Fans // -#define FAN_PIN 8 -#define ORIG_E0_AUTO_FAN_PIN 30 -#define ORIG_E1_AUTO_FAN_PIN 30 -#define ORIG_E2_AUTO_FAN_PIN 30 -#define ORIG_E3_AUTO_FAN_PIN 30 -//#define ORIG_CHAMBER_AUTO_FAN_PIN 10 +#define FAN_PIN 8 + +// +// Auto fans +// +#define AUTO_FAN_PIN 30 +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN AUTO_FAN_PIN +#endif +#ifndef E1_AUTO_FAN_PIN + #define E1_AUTO_FAN_PIN AUTO_FAN_PIN +#endif +#ifndef E2_AUTO_FAN_PIN + #define E2_AUTO_FAN_PIN AUTO_FAN_PIN +#endif +#ifndef E3_AUTO_FAN_PIN + #define E3_AUTO_FAN_PIN AUTO_FAN_PIN +#endif +#ifndef CHAMBER_AUTO_FAN_PIN + //#define CHAMBER_AUTO_FAN_PIN 10 +#endif // // Misc. Functions // -#define SDSS 53 -#define SD_DETECT_PIN 40 +#define SDSS 53 +#define SD_DETECT_PIN 40 // Common I/O -#define FIL_RUNOUT_PIN 9 -//#define FIL_RUNOUT_PIN 29 // encoder sensor -//#define PWM_1_PIN 12 -//#define PWM_2_PIN 13 -//#define SPARE_IO 17 -#define BEEPER_PIN 13 -#define STAT_LED_BLUE_PIN -1 -#define STAT_LED_RED_PIN 10 // 31 +#define FIL_RUNOUT_PIN 9 +//#define FIL_RUNOUT_PIN 29 // encoder sensor +//#define PWM_1_PIN 12 +//#define PWM_2_PIN 13 +//#define SPARE_IO 17 +#define BEEPER_PIN 13 +#define STAT_LED_BLUE_PIN -1 +#define STAT_LED_RED_PIN 10 // 31 diff --git a/Marlin/src/pins/mega/pins_EINSTART-S.h b/Marlin/src/pins/mega/pins_EINSTART-S.h index 45b500363e92..40d65c353e8c 100644 --- a/Marlin/src/pins/mega/pins_EINSTART-S.h +++ b/Marlin/src/pins/mega/pins_EINSTART-S.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -26,7 +26,7 @@ * PCB Silkscreen: 3DPrinterCon_v3.5 */ -#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) +#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -35,48 +35,48 @@ // // Limit Switches // -#define X_STOP_PIN 44 -#define Y_STOP_PIN 43 -#define Z_STOP_PIN 42 +#define X_STOP_PIN 44 +#define Y_STOP_PIN 43 +#define Z_STOP_PIN 42 // // Steppers // -#define X_STEP_PIN 76 -#define X_DIR_PIN 75 -#define X_ENABLE_PIN 73 +#define X_STEP_PIN 76 +#define X_DIR_PIN 75 +#define X_ENABLE_PIN 73 -#define Y_STEP_PIN 31 -#define Y_DIR_PIN 32 -#define Y_ENABLE_PIN 72 +#define Y_STEP_PIN 31 +#define Y_DIR_PIN 32 +#define Y_ENABLE_PIN 72 -#define Z_STEP_PIN 34 -#define Z_DIR_PIN 35 -#define Z_ENABLE_PIN 33 +#define Z_STEP_PIN 34 +#define Z_DIR_PIN 35 +#define Z_ENABLE_PIN 33 -#define E0_STEP_PIN 36 -#define E0_DIR_PIN 37 -#define E0_ENABLE_PIN 30 +#define E0_STEP_PIN 36 +#define E0_DIR_PIN 37 +#define E0_ENABLE_PIN 30 // // Temperature Sensors // -#define TEMP_0_PIN 0 // Analog Input -#define TEMP_BED_PIN 1 // Analog Input +#define TEMP_0_PIN 0 // Analog Input +#define TEMP_BED_PIN 1 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 83 -#define HEATER_BED_PIN 38 +#define HEATER_0_PIN 83 +#define HEATER_BED_PIN 38 -#define FAN_PIN 82 +#define FAN_PIN 82 // // Misc. Functions // -#define SDSS 53 -#define LED_PIN 4 +#define SDSS 53 +#define LED_PIN 4 ////////////////////////// // LCDs and Controllers // @@ -90,24 +90,24 @@ // u8glib constructor // U8GLIB_SH1106_128X64 u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, LCD_PINS_DC, LCD_PINS_RS); -#define LCD_PINS_DC 78 -#define LCD_PINS_RS 79 +#define LCD_PINS_DC 78 +#define LCD_PINS_RS 79 // DOGM SPI LCD Support -#define DOGLCD_CS 3 -#define DOGLCD_MOSI 2 -#define DOGLCD_SCK 5 -#define DOGLCD_A0 2 +#define DOGLCD_CS 3 +#define DOGLCD_MOSI 2 +#define DOGLCD_SCK 5 +#define DOGLCD_A0 2 // // LCD Display input pins // -#define BTN_UP 25 -#define BTN_DWN 26 -#define BTN_LFT 27 -#define BTN_RT 28 +#define BTN_UP 25 +#define BTN_DWN 26 +#define BTN_LFT 27 +#define BTN_RT 28 // 'OK' button -#define BTN_ENC 29 +#define BTN_ENC 29 // Set Kill to right arrow, same as RIGID_PANEL -#define KILL_PIN 28 +#define KILL_PIN 28 diff --git a/Marlin/src/pins/mega/pins_ELEFU_3.h b/Marlin/src/pins/mega/pins_ELEFU_3.h index 30b4ab40af04..af93c408a25a 100644 --- a/Marlin/src/pins/mega/pins_ELEFU_3.h +++ b/Marlin/src/pins/mega/pins_ELEFU_3.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Elefu RA Board Pin Assignments */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -34,115 +34,115 @@ // // Limit Switches // -#define X_MIN_PIN 35 -#define X_MAX_PIN 34 -#define Y_MIN_PIN 33 -#define Y_MAX_PIN 32 -#define Z_MIN_PIN 31 -#define Z_MAX_PIN 30 +#define X_MIN_PIN 35 +#define X_MAX_PIN 34 +#define Y_MIN_PIN 33 +#define Y_MAX_PIN 32 +#define Z_MIN_PIN 31 +#define Z_MAX_PIN 30 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 30 + #define Z_MIN_PROBE_PIN 30 #endif // // Steppers // -#define X_STEP_PIN 49 -#define X_DIR_PIN 13 -#define X_ENABLE_PIN 48 +#define X_STEP_PIN 49 +#define X_DIR_PIN 13 +#define X_ENABLE_PIN 48 -#define Y_STEP_PIN 11 -#define Y_DIR_PIN 9 -#define Y_ENABLE_PIN 12 +#define Y_STEP_PIN 11 +#define Y_DIR_PIN 9 +#define Y_ENABLE_PIN 12 -#define Z_STEP_PIN 7 -#define Z_DIR_PIN 6 -#define Z_ENABLE_PIN 8 +#define Z_STEP_PIN 7 +#define Z_DIR_PIN 6 +#define Z_ENABLE_PIN 8 -#define E0_STEP_PIN 40 -#define E0_DIR_PIN 41 -#define E0_ENABLE_PIN 37 +#define E0_STEP_PIN 40 +#define E0_DIR_PIN 41 +#define E0_ENABLE_PIN 37 -#define E1_STEP_PIN 18 -#define E1_DIR_PIN 19 -#define E1_ENABLE_PIN 38 +#define E1_STEP_PIN 18 +#define E1_DIR_PIN 19 +#define E1_ENABLE_PIN 38 -#define E2_STEP_PIN 43 -#define E2_DIR_PIN 47 -#define E2_ENABLE_PIN 42 +#define E2_STEP_PIN 43 +#define E2_DIR_PIN 47 +#define E2_ENABLE_PIN 42 // // Temperature Sensors // -#define TEMP_0_PIN 3 // Analog Input -#define TEMP_1_PIN 2 // Analog Input -#define TEMP_2_PIN 1 // Analog Input -#define TEMP_BED_PIN 0 // Analog Input +#define TEMP_0_PIN 3 // Analog Input +#define TEMP_1_PIN 2 // Analog Input +#define TEMP_2_PIN 1 // Analog Input +#define TEMP_BED_PIN 0 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 45 // 12V PWM1 -#define HEATER_1_PIN 46 // 12V PWM2 -#define HEATER_2_PIN 17 // 12V PWM3 -#define HEATER_BED_PIN 44 // DOUBLE 12V PWM +#define HEATER_0_PIN 45 // 12V PWM1 +#define HEATER_1_PIN 46 // 12V PWM2 +#define HEATER_2_PIN 17 // 12V PWM3 +#define HEATER_BED_PIN 44 // DOUBLE 12V PWM #ifndef FAN_PIN - #define FAN_PIN 16 // 5V PWM + #define FAN_PIN 16 // 5V PWM #endif // // Misc. Functions // -#define PS_ON_PIN 10 // Set to -1 if using a manual switch on the PWRSW Connector -#define SLEEP_WAKE_PIN 26 // This feature still needs work -#define PHOTOGRAPH_PIN 29 +#define PS_ON_PIN 10 // Set to -1 if using a manual switch on the PWRSW Connector +#define SLEEP_WAKE_PIN 26 // This feature still needs work +#define PHOTOGRAPH_PIN 29 // // LCD / Controller // -#define BEEPER_PIN 36 +#define BEEPER_PIN 36 #if ENABLED(RA_CONTROL_PANEL) - #define SDSS 53 - #define SD_DETECT_PIN 28 + #define SDSS 53 + #define SD_DETECT_PIN 28 - #define BTN_EN1 14 - #define BTN_EN2 39 - #define BTN_ENC 15 + #define BTN_EN1 14 + #define BTN_EN2 39 + #define BTN_ENC 15 #endif // RA_CONTROL_PANEL #if ENABLED(RA_DISCO) // variables for which pins the TLC5947 is using - #define TLC_CLOCK_PIN 25 - #define TLC_BLANK_PIN 23 - #define TLC_XLAT_PIN 22 - #define TLC_DATA_PIN 24 + #define TLC_CLOCK_PIN 25 + #define TLC_BLANK_PIN 23 + #define TLC_XLAT_PIN 22 + #define TLC_DATA_PIN 24 // We also need to define pin to port number mapping for the 2560 to match the pins listed above. // If you change the TLC pins, update this as well per the 2560 datasheet! This currently only works with the RA Board. - #define TLC_CLOCK_BIT 3 + #define TLC_CLOCK_BIT 3 #define TLC_CLOCK_PORT &PORTA - #define TLC_BLANK_BIT 1 + #define TLC_BLANK_BIT 1 #define TLC_BLANK_PORT &PORTA - #define TLC_DATA_BIT 2 + #define TLC_DATA_BIT 2 #define TLC_DATA_PORT &PORTA - #define TLC_XLAT_BIT 0 + #define TLC_XLAT_BIT 0 #define TLC_XLAT_PORT &PORTA // Change this to match your situation. Lots of TLCs takes up the arduino SRAM very quickly, so be careful // Leave it at at least 1 if you have enabled RA_LIGHTING // The number of TLC5947 boards chained together for use with the animation, additional ones will repeat the animation on them, but are not individually addressable and mimic those before them. You can leave the default at 2 even if you only have 1 TLC5947 module. - #define NUM_TLCS 2 + #define NUM_TLCS 2 // These TRANS_ARRAY values let you change the order the LEDs on the lighting modules will animate for chase functions. // Modify them according to your specific situation. diff --git a/Marlin/src/pins/mega/pins_GT2560_REV_A.h b/Marlin/src/pins/mega/pins_GT2560_REV_A.h index 6590f06d6cb3..2fe9a43ba136 100644 --- a/Marlin/src/pins/mega/pins_GT2560_REV_A.h +++ b/Marlin/src/pins/mega/pins_GT2560_REV_A.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -27,7 +27,7 @@ * Richard Smith */ -#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) +#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -39,103 +39,113 @@ // // Limit Switches // -#define X_MIN_PIN 22 -#define X_MAX_PIN 24 -#define Y_MIN_PIN 26 -#define Y_MAX_PIN 28 -#define Z_MIN_PIN 30 -#define Z_MAX_PIN 32 +#define X_MIN_PIN 22 +#define X_MAX_PIN 24 +#define Y_MIN_PIN 26 +#define Y_MAX_PIN 28 +#define Z_MIN_PIN 30 + +#if ENABLED(BLTOUCH) + #if MB(GT2560_REV_A_PLUS) + #define SERVO0_PIN 11 + #else + #define SERVO0_PIN 32 + #endif + #define Z_MAX_PIN -1 +#else + #define Z_MAX_PIN 32 +#endif // // Steppers // -#define X_STEP_PIN 25 -#define X_DIR_PIN 23 -#define X_ENABLE_PIN 27 +#define X_STEP_PIN 25 +#define X_DIR_PIN 23 +#define X_ENABLE_PIN 27 -#define Y_STEP_PIN 31 -#define Y_DIR_PIN 33 -#define Y_ENABLE_PIN 29 +#define Y_STEP_PIN 31 +#define Y_DIR_PIN 33 +#define Y_ENABLE_PIN 29 -#define Z_STEP_PIN 37 -#define Z_DIR_PIN 39 -#define Z_ENABLE_PIN 35 +#define Z_STEP_PIN 37 +#define Z_DIR_PIN 39 +#define Z_ENABLE_PIN 35 -#define E0_STEP_PIN 43 -#define E0_DIR_PIN 45 -#define E0_ENABLE_PIN 41 +#define E0_STEP_PIN 43 +#define E0_DIR_PIN 45 +#define E0_ENABLE_PIN 41 -#define E1_STEP_PIN 49 -#define E1_DIR_PIN 47 -#define E1_ENABLE_PIN 48 +#define E1_STEP_PIN 49 +#define E1_DIR_PIN 47 +#define E1_ENABLE_PIN 48 // // Temperature Sensors // -#define TEMP_0_PIN 8 -#define TEMP_1_PIN 9 -#define TEMP_BED_PIN 10 +#define TEMP_0_PIN 8 +#define TEMP_1_PIN 9 +#define TEMP_BED_PIN 10 // // Heaters / Fans // -#define HEATER_0_PIN 2 -#define HEATER_1_PIN 3 -#define HEATER_BED_PIN 4 +#define HEATER_0_PIN 2 +#define HEATER_1_PIN 3 +#define HEATER_BED_PIN 4 #ifndef FAN_PIN - #define FAN_PIN 7 + #define FAN_PIN 7 #endif // // Misc. Functions // -#define SDSS 53 -#define LED_PIN 13 -#define PS_ON_PIN 12 -#define SUICIDE_PIN 54 // Must be enabled at startup to keep power flowing -#define KILL_PIN -1 +#define SDSS 53 +#define LED_PIN 13 +#define PS_ON_PIN 12 +#define SUICIDE_PIN 54 // Must be enabled at startup to keep power flowing +#define KILL_PIN -1 -#if HAS_SPI_LCD +#if HAS_WIRED_LCD - #define BEEPER_PIN 18 + #define BEEPER_PIN 18 #if ENABLED(NEWPANEL) #if ENABLED(MKS_MINI_12864) - #define DOGLCD_A0 5 - #define DOGLCD_CS 21 - #define BTN_EN1 40 - #define BTN_EN2 42 + #define DOGLCD_A0 5 + #define DOGLCD_CS 21 + #define BTN_EN1 40 + #define BTN_EN2 42 #else - #define LCD_PINS_RS 20 - #define LCD_PINS_ENABLE 17 - #define LCD_PINS_D4 16 - #define LCD_PINS_D5 21 - #define LCD_PINS_D6 5 - #define LCD_PINS_D7 6 - #define BTN_EN1 42 - #define BTN_EN2 40 + #define LCD_PINS_RS 20 + #define LCD_PINS_ENABLE 17 + #define LCD_PINS_D4 16 + #define LCD_PINS_D5 21 + #define LCD_PINS_D6 5 + #define LCD_PINS_D7 6 + #define BTN_EN1 42 + #define BTN_EN2 40 #endif - #define BTN_ENC 19 - #define SD_DETECT_PIN 38 + #define BTN_ENC 19 + #define SD_DETECT_PIN 38 - #else // !NEWPANEL + #else // !NEWPANEL - #define SHIFT_CLK 38 - #define SHIFT_LD 42 - #define SHIFT_OUT 40 - #define SHIFT_EN 17 + #define SHIFT_CLK 38 + #define SHIFT_LD 42 + #define SHIFT_OUT 40 + #define SHIFT_EN 17 - #define LCD_PINS_RS 16 - #define LCD_PINS_ENABLE 5 - #define LCD_PINS_D4 6 - #define LCD_PINS_D5 21 - #define LCD_PINS_D6 20 - #define LCD_PINS_D7 19 + #define LCD_PINS_RS 16 + #define LCD_PINS_ENABLE 5 + #define LCD_PINS_D4 6 + #define LCD_PINS_D5 21 + #define LCD_PINS_D6 20 + #define LCD_PINS_D7 19 - #define SD_DETECT_PIN -1 + #define SD_DETECT_PIN -1 #endif // !NEWPANEL -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD diff --git a/Marlin/src/pins/mega/pins_GT2560_REV_A_PLUS.h b/Marlin/src/pins/mega/pins_GT2560_REV_A_PLUS.h index 3ce4627dce12..7e2ce20c6798 100644 --- a/Marlin/src/pins/mega/pins_GT2560_REV_A_PLUS.h +++ b/Marlin/src/pins/mega/pins_GT2560_REV_A_PLUS.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -29,8 +29,6 @@ #include "pins_GT2560_REV_A.h" -#if ENABLED(BLTOUCH) - #define SERVO0_PIN 11 -#else +#if DISABLED(BLTOUCH) #define SERVO0_PIN 32 #endif diff --git a/Marlin/src/pins/mega/pins_GT2560_V3.h b/Marlin/src/pins/mega/pins_GT2560_V3.h index 4d6cee56f42b..d71a19541914 100644 --- a/Marlin/src/pins/mega/pins_GT2560_V3.h +++ b/Marlin/src/pins/mega/pins_GT2560_V3.h @@ -16,16 +16,16 @@ * 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 . + * along with this program. If not, see . * */ #pragma once /** - * GT2560 V3.0 pin assignment + * GT2560 RevB + GT2560 V3.0 + GT2560 V3.1 + GT2560 V4.0 pin assignment */ -#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) +#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -36,33 +36,33 @@ // // Servos // -#define SERVO0_PIN 11 //13 untested 3Dtouch +#define SERVO0_PIN 11 //13 untested 3Dtouch // // Limit Switches // #ifndef X_STOP_PIN #ifndef X_MIN_PIN - #define X_MIN_PIN 24 + #define X_MIN_PIN 24 #endif #ifndef X_MAX_PIN - #define X_MAX_PIN 22 + #define X_MAX_PIN 22 #endif #endif #ifndef Y_STOP_PIN #ifndef Y_MIN_PIN - #define Y_MIN_PIN 28 + #define Y_MIN_PIN 28 #endif #ifndef Y_MAX_PIN - #define Y_MAX_PIN 26 + #define Y_MAX_PIN 26 #endif #endif #ifndef Z_STOP_PIN #ifndef Z_MIN_PIN - #define Z_MIN_PIN 30 + #define Z_MIN_PIN 30 #endif #ifndef Z_MAX_PIN - #define Z_MAX_PIN 32 + #define Z_MAX_PIN 32 #endif #endif @@ -70,116 +70,116 @@ // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 32 + #define Z_MIN_PROBE_PIN 32 #endif // // Runout Sensor // #ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN 66 + #define FIL_RUNOUT_PIN 66 #endif #ifndef FIL_RUNOUT2_PIN - #define FIL_RUNOUT2_PIN 67 + #define FIL_RUNOUT2_PIN 67 #endif // // Power Recovery // -#define POWER_LOSS_PIN 69 // Pin to detect power loss -#define POWER_LOSS_STATE LOW +#define POWER_LOSS_PIN 69 // Pin to detect power loss +#define POWER_LOSS_STATE LOW // // Steppers // -#define X_STEP_PIN 37 -#define X_DIR_PIN 39 -#define X_ENABLE_PIN 35 +#define X_STEP_PIN 37 +#define X_DIR_PIN 39 +#define X_ENABLE_PIN 35 -#define Y_STEP_PIN 31 -#define Y_DIR_PIN 33 -#define Y_ENABLE_PIN 29 +#define Y_STEP_PIN 31 +#define Y_DIR_PIN 33 +#define Y_ENABLE_PIN 29 -#define Z_STEP_PIN 25 -#define Z_DIR_PIN 23 -#define Z_ENABLE_PIN 27 +#define Z_STEP_PIN 25 +#define Z_DIR_PIN 23 +#define Z_ENABLE_PIN 27 -#define E0_STEP_PIN 46 -#define E0_DIR_PIN 44 -#define E0_ENABLE_PIN 12 +#define E0_STEP_PIN 46 +#define E0_DIR_PIN 44 +#define E0_ENABLE_PIN 12 -#define E1_STEP_PIN 49 -#define E1_DIR_PIN 47 -#define E1_ENABLE_PIN 48 +#define E1_STEP_PIN 49 +#define E1_DIR_PIN 47 +#define E1_ENABLE_PIN 48 -#define E2_STEP_PIN 43 -#define E2_DIR_PIN 45 -#define E2_ENABLE_PIN 41 +#define E2_STEP_PIN 43 +#define E2_DIR_PIN 45 +#define E2_ENABLE_PIN 41 // // Temperature Sensors // -#define TEMP_0_PIN 11 // Analog Input -#define TEMP_1_PIN 9 // Analog Input -#define TEMP_2_PIN 1 // Analog Input -#define TEMP_BED_PIN 10 // Analog Input +#define TEMP_0_PIN 11 // Analog Input +#define TEMP_1_PIN 9 // Analog Input +#define TEMP_2_PIN 8 // Analog Input +#define TEMP_BED_PIN 10 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 10 -#define HEATER_1_PIN 3 -#define HEATER_2_PIN 1 -#define HEATER_BED_PIN 4 -#define FAN_PIN 9 -#define FAN1_PIN 8 -#define FAN2_PIN 7 +#define HEATER_0_PIN 10 +#define HEATER_1_PIN 3 +#define HEATER_2_PIN 2 +#define HEATER_BED_PIN 4 +#define FAN_PIN 9 +#define FAN1_PIN 8 +#define FAN2_PIN 7 // // Misc. Functions // -#define SD_DETECT_PIN 38 -#define SDSS 53 -#define LED_PIN 6 -#define PS_ON_PIN 12 -#define SUICIDE_PIN 54 // This pin must be enabled at boot to keep power flowing +#define SD_DETECT_PIN 38 +#define SDSS 53 +#define LED_PIN 13 // Use 6 (case light) for external LED. 13 is internal (yellow) LED. +#define PS_ON_PIN 12 +#define SUICIDE_PIN 54 // This pin must be enabled at boot to keep power flowing #ifndef CASE_LIGHT_PIN - #define CASE_LIGHT_PIN 6 // 21 + #define CASE_LIGHT_PIN 6 // 21 #endif // // LCD Controller // -#define BEEPER_PIN 18 +#define BEEPER_PIN 18 #ifndef LCD_PINS_RS - #define LCD_PINS_RS 20 + #define LCD_PINS_RS 20 #endif #ifndef LCD_PINS_ENABLE - #define LCD_PINS_ENABLE 17 + #define LCD_PINS_ENABLE 17 #endif #ifndef LCD_PINS_D4 - #define LCD_PINS_D4 16 + #define LCD_PINS_D4 16 #endif #ifndef LCD_PINS_D5 - #define LCD_PINS_D5 21 + #define LCD_PINS_D5 21 #endif #ifndef LCD_PINS_D6 - #define LCD_PINS_D6 5 + #define LCD_PINS_D6 5 #endif #ifndef LCD_PINS_D7 - #define LCD_PINS_D7 36 + #define LCD_PINS_D7 36 #endif #if ENABLED(NEWPANEL) #ifndef BTN_EN1 - #define BTN_EN1 42 + #define BTN_EN1 42 #endif #ifndef BTN_EN2 - #define BTN_EN2 40 + #define BTN_EN2 40 #endif #ifndef BTN_ENC - #define BTN_ENC 19 + #define BTN_ENC 19 #endif #endif diff --git a/Marlin/src/pins/mega/pins_GT2560_V3_A20.h b/Marlin/src/pins/mega/pins_GT2560_V3_A20.h index 037ea1324444..e1956488c6c7 100644 --- a/Marlin/src/pins/mega/pins_GT2560_V3_A20.h +++ b/Marlin/src/pins/mega/pins_GT2560_V3_A20.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,15 +25,17 @@ * Geeetech A20M pin assignment */ -#define LCD_PINS_RS 5 -#define LCD_PINS_ENABLE 36 -#define LCD_PINS_D4 21 -#define LCD_PINS_D7 6 +#define LCD_PINS_RS 5 +#define LCD_PINS_ENABLE 36 +#define LCD_PINS_D4 21 +#define LCD_PINS_D7 6 + +#define SPEAKER // The speaker can produce tones #if ENABLED(NEWPANEL) - #define BTN_EN1 16 - #define BTN_EN2 17 - #define BTN_ENC 19 + #define BTN_EN1 16 + #define BTN_EN2 17 + #define BTN_ENC 19 #endif #include "pins_GT2560_V3.h" diff --git a/Marlin/src/pins/mega/pins_GT2560_V3_MC2.h b/Marlin/src/pins/mega/pins_GT2560_V3_MC2.h index 7ba9112d4e72..26721df3641e 100644 --- a/Marlin/src/pins/mega/pins_GT2560_V3_MC2.h +++ b/Marlin/src/pins/mega/pins_GT2560_V3_MC2.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -27,9 +27,9 @@ #define BOARD_INFO_NAME "GT2560 V3.0 (MC2)" -#define X_MIN_PIN 22 -#define X_MAX_PIN 24 -#define Y_MIN_PIN 26 -#define Y_MAX_PIN 28 +#define X_MIN_PIN 22 +#define X_MAX_PIN 24 +#define Y_MIN_PIN 26 +#define Y_MAX_PIN 28 #include "pins_GT2560_V3.h" diff --git a/Marlin/src/pins/mega/pins_HJC2560C_REV2.h b/Marlin/src/pins/mega/pins_HJC2560C_REV2.h index b66756668805..e30a65b90e1b 100644 --- a/Marlin/src/pins/mega/pins_HJC2560C_REV2.h +++ b/Marlin/src/pins/mega/pins_HJC2560C_REV2.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * HJC2560-C Rev2.x pin assignments */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -42,129 +42,132 @@ // // Limit Switches // -#define X_STOP_PIN 22 -#define Y_STOP_PIN 26 -#define Z_STOP_PIN 29 -//#define EXP_STOP_PIN 28 +#define X_STOP_PIN 22 +#define Y_STOP_PIN 26 +#define Z_STOP_PIN 29 +//#define EXP_STOP_PIN 28 // // Steppers // -#define X_STEP_PIN 25 -#define X_DIR_PIN 23 -#define X_ENABLE_PIN 27 +#define X_STEP_PIN 25 +#define X_DIR_PIN 23 +#define X_ENABLE_PIN 27 -#define Y_STEP_PIN 32 -#define Y_DIR_PIN 33 -#define Y_ENABLE_PIN 31 +#define Y_STEP_PIN 32 +#define Y_DIR_PIN 33 +#define Y_ENABLE_PIN 31 -#define Z_STEP_PIN 35 -#define Z_DIR_PIN 36 -#define Z_ENABLE_PIN 34 +#define Z_STEP_PIN 35 +#define Z_DIR_PIN 36 +#define Z_ENABLE_PIN 34 -#define E0_STEP_PIN 42 -#define E0_DIR_PIN 43 -#define E0_ENABLE_PIN 37 +#define E0_STEP_PIN 42 +#define E0_DIR_PIN 43 +#define E0_ENABLE_PIN 37 -#define E1_STEP_PIN 49 -#define E1_DIR_PIN 47 -#define E1_ENABLE_PIN 48 +#define E1_STEP_PIN 49 +#define E1_DIR_PIN 47 +#define E1_ENABLE_PIN 48 -#define MOTOR_CURRENT_PWM_XY_PIN 44 -#define MOTOR_CURRENT_PWM_Z_PIN 45 -#define MOTOR_CURRENT_PWM_E_PIN 46 +#define MOTOR_CURRENT_PWM_XY_PIN 44 +#define MOTOR_CURRENT_PWM_Z_PIN 45 +#define MOTOR_CURRENT_PWM_E_PIN 46 // Motor current PWM conversion, PWM value = MotorCurrentSetting * 255 / range #ifndef MOTOR_CURRENT_PWM_RANGE - #define MOTOR_CURRENT_PWM_RANGE 2000 + #define MOTOR_CURRENT_PWM_RANGE 2000 #endif #define DEFAULT_PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // // Temperature Sensors // -#define TEMP_0_PIN 8 // Analog Input -#define TEMP_1_PIN 9 // Analog Input -#define TEMP_BED_PIN 10 // Analog Input +#define TEMP_0_PIN 8 // Analog Input +#define TEMP_1_PIN 9 // Analog Input +#define TEMP_BED_PIN 10 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 2 -#define HEATER_1_PIN 3 -#define HEATER_BED_PIN 4 +#define HEATER_0_PIN 2 +#define HEATER_1_PIN 3 +#define HEATER_BED_PIN 4 #ifndef FAN_PIN - #define FAN_PIN 7 //默认不使用PWM_FAN冷却喷嘴,如果需要,则取消注释 + #define FAN_PIN 7 //默认不使用PWM_FAN冷却喷嘴,如果需要,则取消注释 #endif // // Misc. Functions // -#define SDSS 53 -#define SD_DETECT_PIN 39 -//#define LED_PIN 8 -#define CASE_LIGHT_PIN 8 // 8 默认挤出机风扇作为Case LED,如果需要PWM FAN,则需要将FAN_PIN置为7,LED_PIN置为8 +#define SDSS 53 +#define SD_DETECT_PIN 39 +//#define LED_PIN 8 -//#define SAFETY_TRIGGERED_PIN 28 // PIN to detect the safety circuit has triggered -//#define MAIN_VOLTAGE_MEASURE_PIN 14 // ANALOG PIN to measure the main voltage, with a 100k - 4k7 resitor divider. +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN 8 // 8 默认挤出机风扇作为Case LED,如果需要PWM FAN,则需要将FAN_PIN置为7,LED_PIN置为8 +#endif + +//#define SAFETY_TRIGGERED_PIN 28 // PIN to detect the safety circuit has triggered +//#define MAIN_VOLTAGE_MEASURE_PIN 14 // ANALOG PIN to measure the main voltage, with a 100k - 4k7 resitor divider. // // M3/M4/M5 - Spindle/Laser Control // #if ENABLED(SPINDLE_LASER_ENABLE) - #define SPINDLE_DIR_PIN 16 - #define SPINDLE_LASER_ENABLE_PIN 17 // Pin should have a pullup! - #define SPINDLE_LASER_PWM_PIN 9 // Hardware PWM + #define SPINDLE_DIR_PIN 16 + #define SPINDLE_LASER_ENABLE_PIN 17 // Pin should have a pullup! + #define SPINDLE_LASER_PWM_PIN 9 // Hardware PWM #endif // // LCD / Controller // -#if HAS_SPI_LCD +#if HAS_WIRED_LCD - #define BEEPER_PIN 18 + #define BEEPER_PIN 18 #if ENABLED(NEWPANEL) - #define LCD_PINS_RS 20 // LCD_CS - #define LCD_PINS_ENABLE 15 // LCD_SDA - #define LCD_PINS_D4 14 // LCD_SCK + #define LCD_PINS_RS 20 // LCD_CS + #define LCD_PINS_ENABLE 15 // LCD_SDA + #define LCD_PINS_D4 14 // LCD_SCK #if ENABLED(HJC_LCD_SMART_CONTROLLER) - #define LCD_BACKLIGHT_PIN 5 // LCD_Backlight + #define LCD_BACKLIGHT_PIN 5 // LCD_Backlight //#ifndef LCD_CONTRAST_PIN // #define LCD_CONTRAST_PIN 5 // LCD_Contrast //#endif #ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN 24 // Filament runout + #define FIL_RUNOUT_PIN 24 // Filament runout #endif #else - #define LCD_PINS_D5 21 - #define LCD_PINS_D6 5 - #define LCD_PINS_D7 6 + #define LCD_PINS_D5 21 + #define LCD_PINS_D6 5 + #define LCD_PINS_D7 6 #endif - #define BTN_EN1 41 - #define BTN_EN2 40 - #define BTN_ENC 19 + #define BTN_EN1 41 + #define BTN_EN2 40 + #define BTN_ENC 19 - #define SD_DETECT_PIN 39 + #define SD_DETECT_PIN 39 #else // Buttons attached to a shift register - #define SHIFT_CLK 38 - #define SHIFT_LD 42 - #define SHIFT_OUT 40 - #define SHIFT_EN 17 - - #define LCD_PINS_RS 16 - #define LCD_PINS_ENABLE 5 - #define LCD_PINS_D4 6 - #define LCD_PINS_D5 21 - #define LCD_PINS_D6 20 - #define LCD_PINS_D7 19 + #define SHIFT_CLK 38 + #define SHIFT_LD 42 + #define SHIFT_OUT 40 + #define SHIFT_EN 17 + + #define LCD_PINS_RS 16 + #define LCD_PINS_ENABLE 5 + #define LCD_PINS_D4 6 + #define LCD_PINS_D5 21 + #define LCD_PINS_D6 20 + #define LCD_PINS_D7 19 #endif // !NEWPANEL -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD diff --git a/Marlin/src/pins/mega/pins_INTAMSYS40.h b/Marlin/src/pins/mega/pins_INTAMSYS40.h new file mode 100644 index 000000000000..be5f461dda38 --- /dev/null +++ b/Marlin/src/pins/mega/pins_INTAMSYS40.h @@ -0,0 +1,151 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * Intamsys Funmat HT V4.0 Mainboard + * 4988 Drivers Tested + * 2208 version exists and may or may not work + */ + +#if NOT_TARGET(__AVR_ATmega2560__) + #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" +#endif + +#define BOARD_INFO_NAME "Intamsys 4.0" + +// +// Servos +// +#define SERVO0_PIN 12 // Uses High Temp Present Jumper Pin + +// +// Limit Switches +// +#define X_STOP_PIN 22 +#define Y_STOP_PIN 26 +#define Z_MIN_PIN 29 +#define Z_MAX_PIN 69 + +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 69 +#endif + +#define FIL_RUNOUT_PIN 10 + +// +// Steppers +// +#define X_STEP_PIN 25 +#define X_DIR_PIN 23 +#define X_ENABLE_PIN 27 // 44 + +#define Y_STEP_PIN 32 // 33 +#define Y_DIR_PIN 33 // 31, 32 +#define Y_ENABLE_PIN 31 // 32 + +#define Z_STEP_PIN 35 // 35 +#define Z_DIR_PIN 36 +#define Z_ENABLE_PIN 34 // 34 + +#define E0_STEP_PIN 42 +#define E0_DIR_PIN 43 +#define E0_ENABLE_PIN 37 + +#define E1_STEP_PIN 49 +#define E1_DIR_PIN 47 +#define E1_ENABLE_PIN 48 + +#define MOTOR_CURRENT_PWM_X_PIN 11 +#define MOTOR_CURRENT_PWM_Y_PIN 44 +#define MOTOR_CURRENT_PWM_Z_PIN 45 +#define MOTOR_CURRENT_PWM_E_PIN 46 + +// Motor current PWM conversion, PWM value = MotorCurrentSetting * 255 / range +#ifndef MOTOR_CURRENT_PWM_RANGE + #define MOTOR_CURRENT_PWM_RANGE 2000 +#endif +#define DEFAULT_PWM_MOTOR_CURRENT { 1300, 1300, 1250 } + +// +// Temperature Sensors +// +#define TEMP_0_PIN 8 // Analog Input D62 +#define TEMP_BED_PIN 10 // Analog Input D64 + +#define TEMP_CHAMBER_PIN 9 // Analog Input D63 + +// +// Heaters / Fans +// +#define HEATER_0_PIN 2 // PWM +#define HEATER_BED_PIN 4 // PWM +#define HEATER_CHAMBER_PIN 3 // PWM +#define FAN_PIN 7 // PWM + +// +// Misc. Functions +// +#define SDSS 53 +#define SD_DETECT_PIN 39 + +#if ENABLED(CASE_LIGHT_ENABLE) + #define CASE_LIGHT_PIN 8 +#endif + +#if ENABLED(PSU_CONTROL) + #define PS_ON_PIN 38 // UPS Module +#endif + +// +// LCD Controller +// + +#define BEEPER_PIN 18 + +#if HAS_WIRED_LCD + #define LCD_PINS_RS 20 + #define LCD_PINS_ENABLE 30 + #define LCD_PINS_D4 14 + #define LCD_PINS_D5 21 + #define LCD_PINS_D6 5 + #define LCD_PINS_D7 6 + #define BTN_EN1 40 + #define BTN_EN2 41 + #define BTN_ENC 19 +#endif + +///////////////////// SPARE HEADERS ////////////// + +/** + * J25 + * 1 D54 + * 2 D55 + * 3 D56 + * 4 D57 + * 5 D58 + * 6 D59 + * 7 D60 + * 8 D61 + +Hotend High Temp Connected : D12 +*/ diff --git a/Marlin/src/pins/mega/pins_LEAPFROG.h b/Marlin/src/pins/mega/pins_LEAPFROG.h index f04b89d4bcb0..9e6802b24bd7 100644 --- a/Marlin/src/pins/mega/pins_LEAPFROG.h +++ b/Marlin/src/pins/mega/pins_LEAPFROG.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Leapfrog Driver board pin assignments */ -#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) +#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__) #error "Oops! Select 'Mega 1280' or 'Mega 2560' in 'Tools > Board.'" #endif @@ -34,59 +34,59 @@ // // Limit Switches // -#define X_MIN_PIN 47 -#define X_MAX_PIN 2 -#define Y_MIN_PIN 48 -#define Y_MAX_PIN 15 -#define Z_MIN_PIN 49 -#define Z_MAX_PIN -1 +#define X_MIN_PIN 47 +#define X_MAX_PIN 2 +#define Y_MIN_PIN 48 +#define Y_MAX_PIN 15 +#define Z_MIN_PIN 49 +#define Z_MAX_PIN -1 // // Steppers // -#define X_STEP_PIN 28 -#define X_DIR_PIN 63 -#define X_ENABLE_PIN 29 +#define X_STEP_PIN 28 +#define X_DIR_PIN 63 +#define X_ENABLE_PIN 29 -#define Y_STEP_PIN 14 // A6 -#define Y_DIR_PIN 15 // A0 -#define Y_ENABLE_PIN 39 +#define Y_STEP_PIN 14 // A6 +#define Y_DIR_PIN 15 // A0 +#define Y_ENABLE_PIN 39 -#define Z_STEP_PIN 31 // A2 -#define Z_DIR_PIN 32 // A6 -#define Z_ENABLE_PIN 30 // A1 +#define Z_STEP_PIN 31 // A2 +#define Z_DIR_PIN 32 // A6 +#define Z_ENABLE_PIN 30 // A1 -#define E0_STEP_PIN 34 // 34 -#define E0_DIR_PIN 35 // 35 -#define E0_ENABLE_PIN 33 // 33 +#define E0_STEP_PIN 34 // 34 +#define E0_DIR_PIN 35 // 35 +#define E0_ENABLE_PIN 33 // 33 -#define E1_STEP_PIN 37 // 37 -#define E1_DIR_PIN 40 // 40 -#define E1_ENABLE_PIN 36 // 36 +#define E1_STEP_PIN 37 // 37 +#define E1_DIR_PIN 40 // 40 +#define E1_ENABLE_PIN 36 // 36 // // Temperature Sensors // -#define TEMP_0_PIN 13 // Analog Input (D27) -#define TEMP_1_PIN 15 // Analog Input (1) -#define TEMP_BED_PIN 14 // Analog Input (1,2 or I2C) +#define TEMP_0_PIN 13 // Analog Input (D27) +#define TEMP_1_PIN 15 // Analog Input (1) +#define TEMP_BED_PIN 14 // Analog Input (1,2 or I2C) // // Heaters / Fans // -#define HEATER_0_PIN 9 -#define HEATER_1_PIN 8 // 12 -#define HEATER_2_PIN 11 // 13 -#define HEATER_BED_PIN 10 // 14/15 +#define HEATER_0_PIN 9 +#define HEATER_1_PIN 8 // 12 +#define HEATER_2_PIN 11 // 13 +#define HEATER_BED_PIN 10 // 14/15 -#define FAN_PIN 7 +#define FAN_PIN 7 // // Misc. Functions // -#define SDSS 11 -#define LED_PIN 13 -#define SOL1_PIN 16 -#define SOL2_PIN 17 +#define SDSS 11 +#define LED_PIN 13 +#define SOL1_PIN 16 +#define SOL2_PIN 17 /* Unused (1) (2) (3) 4 5 6 7 8 9 10 11 12 13 (14) (15) (16) 17 (18) (19) (20) (21) (22) (23) 24 (25) (26) (27) 28 (29) (30) (31) */ diff --git a/Marlin/src/pins/mega/pins_LEAPFROG_XEED2015.h b/Marlin/src/pins/mega/pins_LEAPFROG_XEED2015.h index ab6299a9b05c..9c316aa75951 100644 --- a/Marlin/src/pins/mega/pins_LEAPFROG_XEED2015.h +++ b/Marlin/src/pins/mega/pins_LEAPFROG_XEED2015.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -29,7 +29,7 @@ * printer models. As such this file is currently specific to the Xeed. */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Mega 2560' in 'Tools > Board.'" #endif @@ -38,9 +38,9 @@ // // Limit Switches // -#define X_STOP_PIN 47 // 'X Min' -#define Y_STOP_PIN 48 // 'Y Min' -#define Z_STOP_PIN 49 // 'Z Min' +#define X_STOP_PIN 47 // 'X Min' +#define Y_STOP_PIN 48 // 'Y Min' +#define Z_STOP_PIN 49 // 'Z Min' // // Steppers @@ -51,65 +51,65 @@ // // X-axis signal-level connector -#define X_STEP_PIN 65 -#define X_DIR_PIN 64 -#define X_ENABLE_PIN 66 // Not actually used on Xeed, could be repurposed +#define X_STEP_PIN 65 +#define X_DIR_PIN 64 +#define X_ENABLE_PIN 66 // Not actually used on Xeed, could be repurposed // Y-axis signal-level connector -#define Y_STEP_PIN 23 -#define Y_DIR_PIN 22 -#define Y_ENABLE_PIN 24 // Not actually used on Xeed, could be repurposed +#define Y_STEP_PIN 23 +#define Y_DIR_PIN 22 +#define Y_ENABLE_PIN 24 // Not actually used on Xeed, could be repurposed // ZMOT connector (Front Right Z Motor) -#define Z_STEP_PIN 31 -#define Z_DIR_PIN 32 -#define Z_ENABLE_PIN 30 +#define Z_STEP_PIN 31 +#define Z_DIR_PIN 32 +#define Z_ENABLE_PIN 30 // XMOT connector (Rear Z Motor) -#define Z2_STEP_PIN 28 -#define Z2_DIR_PIN 63 -#define Z2_ENABLE_PIN 29 +#define Z2_STEP_PIN 28 +#define Z2_DIR_PIN 63 +#define Z2_ENABLE_PIN 29 // YMOT connector (Front Left Z Motor) -#define Z3_STEP_PIN 14 -#define Z3_DIR_PIN 15 -#define Z3_ENABLE_PIN 39 +#define Z3_STEP_PIN 14 +#define Z3_DIR_PIN 15 +#define Z3_ENABLE_PIN 39 // EMOT2 connector -#define E0_STEP_PIN 37 -#define E0_DIR_PIN 40 -#define E0_ENABLE_PIN 36 +#define E0_STEP_PIN 37 +#define E0_DIR_PIN 40 +#define E0_ENABLE_PIN 36 // EMOT connector -#define E1_STEP_PIN 34 -#define E1_DIR_PIN 35 -#define E1_ENABLE_PIN 33 +#define E1_STEP_PIN 34 +#define E1_DIR_PIN 35 +#define E1_ENABLE_PIN 33 // // Filament runout // -#define FIL_RUNOUT_PIN 42 // ROT2 Connector -#define FIL_RUNOUT2_PIN 44 // ROT1 Connector +#define FIL_RUNOUT_PIN 42 // ROT2 Connector +#define FIL_RUNOUT2_PIN 44 // ROT1 Connector // // Temperature Sensors // -#define TEMP_0_PIN 15 // T3 Connector -#define TEMP_1_PIN 13 // T1 Connector -#define TEMP_BED_PIN 14 // BED Connector (Between T1 and T3) +#define TEMP_0_PIN 15 // T3 Connector +#define TEMP_1_PIN 13 // T1 Connector +#define TEMP_BED_PIN 14 // BED Connector (Between T1 and T3) // // Heaters / Fans // -#define HEATER_0_PIN 8 // Misc Connector, pins 3 and 4 (Out2) -#define HEATER_1_PIN 9 // Misc Connector, pins 5 and 6 (Out3) -#define HEATER_BED_PIN 6 // Misc Connector, pins 9(-) and 10(+) (OutA) +#define HEATER_0_PIN 8 // Misc Connector, pins 3 and 4 (Out2) +#define HEATER_1_PIN 9 // Misc Connector, pins 5 and 6 (Out3) +#define HEATER_BED_PIN 6 // Misc Connector, pins 9(-) and 10(+) (OutA) -#define FAN_PIN 10 // Misc Connector, pins 7(-) and 8 (+) (Out4) +#define FAN_PIN 10 // Misc Connector, pins 7(-) and 8 (+) (Out4) -#define LED_PIN 13 +#define LED_PIN 13 -#define SOL1_PIN 7 // Misc Connector, pins 1(-) and 2(+) (Out1) +#define SOL1_PIN 7 // Misc Connector, pins 1(-) and 2(+) (Out1) // Door Closed Sensor -//#define DOOR_PIN 45 // HM1 Connector +//#define DOOR_PIN 45 // HM1 Connector diff --git a/Marlin/src/pins/mega/pins_MEGACONTROLLER.h b/Marlin/src/pins/mega/pins_MEGACONTROLLER.h index 8fecc71bac88..938ad82eff03 100644 --- a/Marlin/src/pins/mega/pins_MEGACONTROLLER.h +++ b/Marlin/src/pins/mega/pins_MEGACONTROLLER.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Mega controller pin assignments */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #elif HOTENDS > 2 || E_STEPPERS > 2 #error "Mega Controller supports up to 2 hotends / E-steppers. Comment out this line to continue." @@ -36,89 +36,89 @@ // // Servos // -#define SERVO0_PIN 30 -#define SERVO1_PIN 31 -#define SERVO2_PIN 32 -#define SERVO3_PIN 33 +#define SERVO0_PIN 30 +#define SERVO1_PIN 31 +#define SERVO2_PIN 32 +#define SERVO3_PIN 33 // // Limit Switches // -#define X_MIN_PIN 43 -#define X_MAX_PIN 42 -#define Y_MIN_PIN 38 -#define Y_MAX_PIN 41 -#define Z_MIN_PIN 40 -#define Z_MAX_PIN 37 +#define X_MIN_PIN 43 +#define X_MAX_PIN 42 +#define Y_MIN_PIN 38 +#define Y_MAX_PIN 41 +#define Z_MIN_PIN 40 +#define Z_MAX_PIN 37 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 37 + #define Z_MIN_PROBE_PIN 37 #endif // // Steppers // -#define X_STEP_PIN 62 // A8 -#define X_DIR_PIN 63 // A9 -#define X_ENABLE_PIN 61 // A7 +#define X_STEP_PIN 62 // A8 +#define X_DIR_PIN 63 // A9 +#define X_ENABLE_PIN 61 // A7 -#define Y_STEP_PIN 65 // A11 -#define Y_DIR_PIN 66 // A12 -#define Y_ENABLE_PIN 64 // A10 +#define Y_STEP_PIN 65 // A11 +#define Y_DIR_PIN 66 // A12 +#define Y_ENABLE_PIN 64 // A10 -#define Z_STEP_PIN 68 // A14 -#define Z_DIR_PIN 69 // A15 -#define Z_ENABLE_PIN 67 // A13 +#define Z_STEP_PIN 68 // A14 +#define Z_DIR_PIN 69 // A15 +#define Z_ENABLE_PIN 67 // A13 -#define E0_STEP_PIN 23 -#define E0_DIR_PIN 24 -#define E0_ENABLE_PIN 22 +#define E0_STEP_PIN 23 +#define E0_DIR_PIN 24 +#define E0_ENABLE_PIN 22 -#define E1_STEP_PIN 26 -#define E1_DIR_PIN 27 -#define E1_ENABLE_PIN 25 +#define E1_STEP_PIN 26 +#define E1_DIR_PIN 27 +#define E1_ENABLE_PIN 25 // // Temperature Sensors // #if TEMP_SENSOR_0 == -1 - #define TEMP_0_PIN 4 // Analog Input + #define TEMP_0_PIN 4 // Analog Input #else - #define TEMP_0_PIN 0 // Analog Input + #define TEMP_0_PIN 0 // Analog Input #endif #if TEMP_SENSOR_1 == -1 - #define TEMP_1_PIN 5 // Analog Input + #define TEMP_1_PIN 5 // Analog Input #else - #define TEMP_1_PIN 2 // Analog Input + #define TEMP_1_PIN 2 // Analog Input #endif -#define TEMP_2_PIN 3 // Analog Input +#define TEMP_2_PIN 3 // Analog Input #if TEMP_SENSOR_BED == -1 - #define TEMP_BED_PIN 6 // Analog Input + #define TEMP_BED_PIN 6 // Analog Input #else - #define TEMP_BED_PIN 1 // Analog Input + #define TEMP_BED_PIN 1 // Analog Input #endif // // Heaters / Fans // -#define HEATER_0_PIN 29 -#define HEATER_1_PIN 34 -#define HEATER_BED_PIN 28 +#define HEATER_0_PIN 29 +#define HEATER_1_PIN 34 +#define HEATER_BED_PIN 28 #ifndef FAN_PIN - #define FAN_PIN 39 + #define FAN_PIN 39 #endif -#define FAN1_PIN 35 -#define FAN2_PIN 36 +#define FAN1_PIN 35 +#define FAN2_PIN 36 #ifndef CONTROLLER_FAN_PIN - #define CONTROLLER_FAN_PIN FAN2_PIN + #define CONTROLLER_FAN_PIN FAN2_PIN #endif #define FAN_SOFT_PWM @@ -126,39 +126,42 @@ // // Misc. Functions // -#define SDSS 53 -#define LED_PIN 13 -#define CASE_LIGHT_PIN 2 +#define SDSS 53 +#define LED_PIN 13 + +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN 2 +#endif // // LCD / Controller // #if ENABLED(MINIPANEL) - #define BEEPER_PIN 46 + #define BEEPER_PIN 46 // Pins for DOGM SPI LCD Support - #define DOGLCD_A0 47 - #define DOGLCD_CS 45 - #define LCD_BACKLIGHT_PIN 44 // backlight LED on PA3 + #define DOGLCD_A0 47 + #define DOGLCD_CS 45 + #define LCD_BACKLIGHT_PIN 44 // backlight LED on PA3 - #define KILL_PIN 12 + #define KILL_PIN 12 // GLCD features // Uncomment screen orientation //#define LCD_SCREEN_ROT_90 //#define LCD_SCREEN_ROT_180 //#define LCD_SCREEN_ROT_270 - #define BTN_EN1 48 - #define BTN_EN2 11 - #define BTN_ENC 10 + #define BTN_EN1 48 + #define BTN_EN2 11 + #define BTN_ENC 10 - #define SD_DETECT_PIN 49 + #define SD_DETECT_PIN 49 #endif // MINIPANEL // // M3/M4/M5 - Spindle/Laser Control // -#define SPINDLE_LASER_PWM_PIN 6 // Hardware PWM -#define SPINDLE_LASER_ENA_PIN 7 // Pullup! -#define SPINDLE_DIR_PIN 8 +#define SPINDLE_LASER_PWM_PIN 6 // Hardware PWM +#define SPINDLE_LASER_ENA_PIN 7 // Pullup! +#define SPINDLE_DIR_PIN 8 diff --git a/Marlin/src/pins/mega/pins_MEGATRONICS.h b/Marlin/src/pins/mega/pins_MEGATRONICS.h index d3015340de09..1c37b21ab707 100644 --- a/Marlin/src/pins/mega/pins_MEGATRONICS.h +++ b/Marlin/src/pins/mega/pins_MEGATRONICS.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * MegaTronics pin assignments */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -33,99 +33,102 @@ // // Limit Switches // -#define X_MIN_PIN 41 -#define X_MAX_PIN 37 -#define Y_MIN_PIN 14 -#define Y_MAX_PIN 15 -#define Z_MIN_PIN 18 -#define Z_MAX_PIN 19 +#define X_MIN_PIN 41 +#define X_MAX_PIN 37 +#define Y_MIN_PIN 14 +#define Y_MAX_PIN 15 +#define Z_MIN_PIN 18 +#define Z_MAX_PIN 19 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 19 + #define Z_MIN_PROBE_PIN 19 #endif // // Steppers // -#define X_STEP_PIN 26 -#define X_DIR_PIN 28 -#define X_ENABLE_PIN 24 +#define X_STEP_PIN 26 +#define X_DIR_PIN 28 +#define X_ENABLE_PIN 24 -#define Y_STEP_PIN 60 // A6 -#define Y_DIR_PIN 61 // A7 -#define Y_ENABLE_PIN 22 +#define Y_STEP_PIN 60 // A6 +#define Y_DIR_PIN 61 // A7 +#define Y_ENABLE_PIN 22 -#define Z_STEP_PIN 54 // A0 -#define Z_DIR_PIN 55 // A1 -#define Z_ENABLE_PIN 56 // A2 +#define Z_STEP_PIN 54 // A0 +#define Z_DIR_PIN 55 // A1 +#define Z_ENABLE_PIN 56 // A2 -#define E0_STEP_PIN 31 -#define E0_DIR_PIN 32 -#define E0_ENABLE_PIN 38 +#define E0_STEP_PIN 31 +#define E0_DIR_PIN 32 +#define E0_ENABLE_PIN 38 -#define E1_STEP_PIN 34 -#define E1_DIR_PIN 36 -#define E1_ENABLE_PIN 30 +#define E1_STEP_PIN 34 +#define E1_DIR_PIN 36 +#define E1_ENABLE_PIN 30 // // Temperature Sensors // #if TEMP_SENSOR_0 == -1 - #define TEMP_0_PIN 8 // Analog Input + #define TEMP_0_PIN 8 // Analog Input #else - #define TEMP_0_PIN 13 // Analog Input + #define TEMP_0_PIN 13 // Analog Input #endif -#define TEMP_1_PIN 15 // Analog Input -#define TEMP_BED_PIN 14 // Analog Input +#define TEMP_1_PIN 15 // Analog Input +#define TEMP_BED_PIN 14 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 9 -#define HEATER_1_PIN 8 -#define HEATER_BED_PIN 10 +#define HEATER_0_PIN 9 +#define HEATER_1_PIN 8 +#define HEATER_BED_PIN 10 #ifndef FAN_PIN - #define FAN_PIN 7 // IO pin. Buffer needed + #define FAN_PIN 7 // IO pin. Buffer needed #endif // // Misc. Functions // -#define SDSS 53 -#define LED_PIN 13 -#define PS_ON_PIN 12 -#define CASE_LIGHT_PIN 2 +#define SDSS 53 +#define LED_PIN 13 +#define PS_ON_PIN 12 + +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN 2 +#endif // // LCD / Controller // -#define BEEPER_PIN 33 +#define BEEPER_PIN 33 #if BOTH(ULTRA_LCD, NEWPANEL) - #define LCD_PINS_RS 16 - #define LCD_PINS_ENABLE 17 - #define LCD_PINS_D4 23 - #define LCD_PINS_D5 25 - #define LCD_PINS_D6 27 - #define LCD_PINS_D7 29 + #define LCD_PINS_RS 16 + #define LCD_PINS_ENABLE 17 + #define LCD_PINS_D4 23 + #define LCD_PINS_D5 25 + #define LCD_PINS_D6 27 + #define LCD_PINS_D7 29 // Buttons directly attached to AUX-2 - #define BTN_EN1 59 - #define BTN_EN2 64 - #define BTN_ENC 43 + #define BTN_EN1 59 + #define BTN_EN2 64 + #define BTN_ENC 43 - #define SD_DETECT_PIN -1 // RAMPS doesn't use this + #define SD_DETECT_PIN -1 // RAMPS doesn't use this -#endif // HAS_SPI_LCD && NEWPANEL +#endif // ULTRA_LCD && NEWPANEL // // M3/M4/M5 - Spindle/Laser Control // -#define SPINDLE_LASER_PWM_PIN 3 // Hardware PWM -#define SPINDLE_LASER_ENA_PIN 4 // Pullup! -#define SPINDLE_DIR_PIN 11 +#define SPINDLE_LASER_PWM_PIN 3 // Hardware PWM +#define SPINDLE_LASER_ENA_PIN 4 // Pullup! +#define SPINDLE_DIR_PIN 11 diff --git a/Marlin/src/pins/mega/pins_MEGATRONICS_2.h b/Marlin/src/pins/mega/pins_MEGATRONICS_2.h index 160d9d4b786a..ff7cf1571465 100644 --- a/Marlin/src/pins/mega/pins_MEGATRONICS_2.h +++ b/Marlin/src/pins/mega/pins_MEGATRONICS_2.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * MegaTronics v2.0 pin assignments */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -33,120 +33,123 @@ // // Limit Switches // -#define X_MIN_PIN 37 -#define X_MAX_PIN 40 -#define Y_MIN_PIN 41 -#define Y_MAX_PIN 38 -#define Z_MIN_PIN 18 -#define Z_MAX_PIN 19 +#define X_MIN_PIN 37 +#define X_MAX_PIN 40 +#define Y_MIN_PIN 41 +#define Y_MAX_PIN 38 +#define Z_MIN_PIN 18 +#define Z_MAX_PIN 19 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 19 + #define Z_MIN_PROBE_PIN 19 #endif // // Steppers // -#define X_STEP_PIN 26 -#define X_DIR_PIN 27 -#define X_ENABLE_PIN 25 +#define X_STEP_PIN 26 +#define X_DIR_PIN 27 +#define X_ENABLE_PIN 25 -#define Y_STEP_PIN 4 // A6 -#define Y_DIR_PIN 54 // A0 -#define Y_ENABLE_PIN 5 +#define Y_STEP_PIN 4 // A6 +#define Y_DIR_PIN 54 // A0 +#define Y_ENABLE_PIN 5 -#define Z_STEP_PIN 56 // A2 -#define Z_DIR_PIN 60 // A6 -#define Z_ENABLE_PIN 55 // A1 +#define Z_STEP_PIN 56 // A2 +#define Z_DIR_PIN 60 // A6 +#define Z_ENABLE_PIN 55 // A1 -#define E0_STEP_PIN 35 -#define E0_DIR_PIN 36 -#define E0_ENABLE_PIN 34 +#define E0_STEP_PIN 35 +#define E0_DIR_PIN 36 +#define E0_ENABLE_PIN 34 -#define E1_STEP_PIN 29 -#define E1_DIR_PIN 39 -#define E1_ENABLE_PIN 28 +#define E1_STEP_PIN 29 +#define E1_DIR_PIN 39 +#define E1_ENABLE_PIN 28 -#define E2_STEP_PIN 23 // ? schematic says 24 -#define E2_DIR_PIN 24 // ? schematic says 23 -#define E2_ENABLE_PIN 22 +#define E2_STEP_PIN 23 // ? schematic says 24 +#define E2_DIR_PIN 24 // ? schematic says 23 +#define E2_ENABLE_PIN 22 // // Temperature Sensors // #if TEMP_SENSOR_0 == -1 - #define TEMP_0_PIN 4 // Analog Input + #define TEMP_0_PIN 4 // Analog Input #else - #define TEMP_0_PIN 13 // Analog Input + #define TEMP_0_PIN 13 // Analog Input #endif #if TEMP_SENSOR_1 == -1 - #define TEMP_1_PIN 8 // Analog Input + #define TEMP_1_PIN 8 // Analog Input #else - #define TEMP_1_PIN 15 // Analog Input + #define TEMP_1_PIN 15 // Analog Input #endif #if TEMP_SENSOR_BED == -1 - #define TEMP_BED_PIN 8 // Analog Input + #define TEMP_BED_PIN 8 // Analog Input #else - #define TEMP_BED_PIN 14 // Analog Input + #define TEMP_BED_PIN 14 // Analog Input #endif // // Heaters / Fans // -#define HEATER_0_PIN 9 -#define HEATER_1_PIN 8 -#define HEATER_BED_PIN 10 +#define HEATER_0_PIN 9 +#define HEATER_1_PIN 8 +#define HEATER_BED_PIN 10 #ifndef FAN_PIN - #define FAN_PIN 7 + #define FAN_PIN 7 #endif -#define FAN1_PIN 6 +#define FAN1_PIN 6 // // Misc. Functions // -#define SDSS 53 -#define LED_PIN 13 -#define PS_ON_PIN 12 -#define CASE_LIGHT_PIN 2 +#define SDSS 53 +#define LED_PIN 13 +#define PS_ON_PIN 12 + +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN 2 +#endif // // M3/M4/M5 - Spindle/Laser Control // -#define SPINDLE_LASER_PWM_PIN 3 // Hardware PWM -#define SPINDLE_LASER_ENA_PIN 16 // Pullup! -#define SPINDLE_DIR_PIN 11 +#define SPINDLE_LASER_PWM_PIN 3 // Hardware PWM +#define SPINDLE_LASER_ENA_PIN 16 // Pullup! +#define SPINDLE_DIR_PIN 11 // // LCD / Controller // -#define BEEPER_PIN 64 +#define BEEPER_PIN 64 -#if HAS_SPI_LCD +#if HAS_WIRED_LCD - #define LCD_PINS_RS 14 - #define LCD_PINS_ENABLE 15 - #define LCD_PINS_D4 30 - #define LCD_PINS_D5 31 - #define LCD_PINS_D6 32 - #define LCD_PINS_D7 33 + #define LCD_PINS_RS 14 + #define LCD_PINS_ENABLE 15 + #define LCD_PINS_D4 30 + #define LCD_PINS_D5 31 + #define LCD_PINS_D6 32 + #define LCD_PINS_D7 33 #if ENABLED(NEWPANEL) // Buttons are directly attached using keypad - #define BTN_EN1 61 - #define BTN_EN2 59 - #define BTN_ENC 43 + #define BTN_EN1 61 + #define BTN_EN2 59 + #define BTN_ENC 43 #else // Buttons attached to shift register of reprapworld keypad v1.1 - #define SHIFT_CLK 63 - #define SHIFT_LD 42 - #define SHIFT_OUT 17 - #define SHIFT_EN 17 + #define SHIFT_CLK 63 + #define SHIFT_LD 42 + #define SHIFT_OUT 17 + #define SHIFT_EN 17 #endif -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD diff --git a/Marlin/src/pins/mega/pins_MEGATRONICS_3.h b/Marlin/src/pins/mega/pins_MEGATRONICS_3.h index fe0f4826be32..45ebd163a79f 100644 --- a/Marlin/src/pins/mega/pins_MEGATRONICS_3.h +++ b/Marlin/src/pins/mega/pins_MEGATRONICS_3.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * MegaTronics v3.0 / v3.1 / v3.2 pin assignments */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -40,132 +40,135 @@ // // Servos // -#define SERVO0_PIN 46 // AUX3-6 -#define SERVO1_PIN 47 // AUX3-5 -#define SERVO2_PIN 48 // AUX3-4 -#define SERVO3_PIN 49 // AUX3-3 +#define SERVO0_PIN 46 // AUX3-6 +#define SERVO1_PIN 47 // AUX3-5 +#define SERVO2_PIN 48 // AUX3-4 +#define SERVO3_PIN 49 // AUX3-3 // // Limit Switches // -#define X_MIN_PIN 37 // No INT -#define X_MAX_PIN 40 // No INT -#define Y_MIN_PIN 41 // No INT -#define Y_MAX_PIN 38 // No INT -#define Z_MIN_PIN 18 // No INT -#define Z_MAX_PIN 19 // No INT +#define X_MIN_PIN 37 // No INT +#define X_MAX_PIN 40 // No INT +#define Y_MIN_PIN 41 // No INT +#define Y_MAX_PIN 38 // No INT +#define Z_MIN_PIN 18 // No INT +#define Z_MAX_PIN 19 // No INT // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 19 + #define Z_MIN_PROBE_PIN 19 #endif // // Steppers // -#define X_STEP_PIN 58 -#define X_DIR_PIN 57 -#define X_ENABLE_PIN 59 +#define X_STEP_PIN 58 +#define X_DIR_PIN 57 +#define X_ENABLE_PIN 59 -#define Y_STEP_PIN 5 -#define Y_DIR_PIN 17 -#define Y_ENABLE_PIN 4 +#define Y_STEP_PIN 5 +#define Y_DIR_PIN 17 +#define Y_ENABLE_PIN 4 -#define Z_STEP_PIN 16 -#define Z_DIR_PIN 11 -#define Z_ENABLE_PIN 3 +#define Z_STEP_PIN 16 +#define Z_DIR_PIN 11 +#define Z_ENABLE_PIN 3 -#define E0_STEP_PIN 28 -#define E0_DIR_PIN 27 -#define E0_ENABLE_PIN 29 +#define E0_STEP_PIN 28 +#define E0_DIR_PIN 27 +#define E0_ENABLE_PIN 29 -#define E1_STEP_PIN 25 -#define E1_DIR_PIN 24 -#define E1_ENABLE_PIN 26 +#define E1_STEP_PIN 25 +#define E1_DIR_PIN 24 +#define E1_ENABLE_PIN 26 -#define E2_STEP_PIN 22 -#define E2_DIR_PIN 60 -#define E2_ENABLE_PIN 23 +#define E2_STEP_PIN 22 +#define E2_DIR_PIN 60 +#define E2_ENABLE_PIN 23 // // Temperature Sensors // #if TEMP_SENSOR_0 == -1 - #define TEMP_0_PIN 11 // Analog Input + #define TEMP_0_PIN 11 // Analog Input #else - #define TEMP_0_PIN 15 // Analog Input + #define TEMP_0_PIN 15 // Analog Input #endif #if TEMP_SENSOR_1 == -1 - #define TEMP_1_PIN 10 // Analog Input + #define TEMP_1_PIN 10 // Analog Input #else - #define TEMP_1_PIN 13 // Analog Input + #define TEMP_1_PIN 13 // Analog Input #endif #if TEMP_SENSOR_2 == -1 - #define TEMP_2_PIN 9 // Analog Input + #define TEMP_2_PIN 9 // Analog Input #else - #define TEMP_2_PIN 12 // Analog Input + #define TEMP_2_PIN 12 // Analog Input #endif #if TEMP_SENSOR_BED == -1 - #define TEMP_BED_PIN 8 // Analog Input + #define TEMP_BED_PIN 8 // Analog Input #else - #define TEMP_BED_PIN 14 // Analog Input + #define TEMP_BED_PIN 14 // Analog Input #endif // // Heaters / Fans // -#define HEATER_0_PIN 2 -#define HEATER_1_PIN 9 -#define HEATER_2_PIN 8 -#define HEATER_BED_PIN 10 +#define HEATER_0_PIN 2 +#define HEATER_1_PIN 9 +#define HEATER_2_PIN 8 +#define HEATER_BED_PIN 10 #ifndef FAN_PIN - #define FAN_PIN 6 + #define FAN_PIN 6 #endif -#define FAN1_PIN 7 +#define FAN1_PIN 7 // // Misc. Functions // -#define SDSS 53 -#define LED_PIN 13 -#define PS_ON_PIN 12 -#define CASE_LIGHT_PIN 45 // Try the keypad connector +#define SDSS 53 +#define LED_PIN 13 +#define PS_ON_PIN 12 + +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN 45 // Try the keypad connector +#endif // // LCD / Controller // -#define BEEPER_PIN 61 +#define BEEPER_PIN 61 -#define BTN_EN1 44 -#define BTN_EN2 45 -#define BTN_ENC 33 +#define BTN_EN1 44 +#define BTN_EN2 45 +#define BTN_ENC 33 #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) - #define LCD_PINS_RS 56 // CS chip select / SS chip slave select - #define LCD_PINS_ENABLE 51 // SID (MOSI) - #define LCD_PINS_D4 52 // SCK (CLK) clock - #define SD_DETECT_PIN 35 + #define LCD_PINS_RS 56 // CS chip select / SS chip slave select + #define LCD_PINS_ENABLE 51 // SID (MOSI) + #define LCD_PINS_D4 52 // SCK (CLK) clock + #define SD_DETECT_PIN 35 #else - #define LCD_PINS_RS 32 - #define LCD_PINS_ENABLE 31 - #define LCD_PINS_D4 14 - #define LCD_PINS_D5 30 - #define LCD_PINS_D6 39 - #define LCD_PINS_D7 15 + #define LCD_PINS_RS 32 + #define LCD_PINS_ENABLE 31 + #define LCD_PINS_D4 14 + #define LCD_PINS_D5 30 + #define LCD_PINS_D6 39 + #define LCD_PINS_D7 15 - #define SHIFT_CLK 43 - #define SHIFT_LD 35 - #define SHIFT_OUT 34 - #define SHIFT_EN 44 + #define SHIFT_CLK 43 + #define SHIFT_LD 35 + #define SHIFT_OUT 34 + #define SHIFT_EN 44 #if MB(MEGATRONICS_31, MEGATRONICS_32) - #define SD_DETECT_PIN 56 + #define SD_DETECT_PIN 56 #endif #endif @@ -173,23 +176,23 @@ // // M3/M4/M5 - Spindle/Laser Control // -#if DISABLED(REPRAPWORLD_KEYPAD) // try to use the keypad connector first - #define SPINDLE_LASER_PWM_PIN 44 // Hardware PWM - #define SPINDLE_LASER_ENA_PIN 43 // Pullup! - #define SPINDLE_DIR_PIN 42 +#if DISABLED(REPRAPWORLD_KEYPAD) // try to use the keypad connector first + #define SPINDLE_LASER_PWM_PIN 44 // Hardware PWM + #define SPINDLE_LASER_ENA_PIN 43 // Pullup! + #define SPINDLE_DIR_PIN 42 #elif EXTRUDERS <= 2 // Hijack the last extruder so that we can get the PWM signal off the Y breakout // Move Y to the E2 plug. This makes dual Y steppers harder - #undef Y_ENABLE_PIN // 4 - #undef Y_STEP_PIN // 5 - #undef Y_DIR_PIN // 17 - #undef E2_ENABLE_PIN // 23 - #undef E2_STEP_PIN // 22 - #undef E2_DIR_PIN // 60 - #define Y_ENABLE_PIN 23 - #define Y_STEP_PIN 22 - #define Y_DIR_PIN 60 - #define SPINDLE_LASER_PWM_PIN 4 // Hardware PWM - #define SPINDLE_LASER_ENA_PIN 17 // Pullup! - #define SPINDLE_DIR_PIN 5 + #undef Y_ENABLE_PIN // 4 + #undef Y_STEP_PIN // 5 + #undef Y_DIR_PIN // 17 + #undef E2_ENABLE_PIN // 23 + #undef E2_STEP_PIN // 22 + #undef E2_DIR_PIN // 60 + #define Y_ENABLE_PIN 23 + #define Y_STEP_PIN 22 + #define Y_DIR_PIN 60 + #define SPINDLE_LASER_PWM_PIN 4 // Hardware PWM + #define SPINDLE_LASER_ENA_PIN 17 // Pullup! + #define SPINDLE_DIR_PIN 5 #endif diff --git a/Marlin/src/pins/mega/pins_MIGHTYBOARD_REVE.h b/Marlin/src/pins/mega/pins_MIGHTYBOARD_REVE.h index 6d3102172bb8..963911ec5d70 100644 --- a/Marlin/src/pins/mega/pins_MIGHTYBOARD_REVE.h +++ b/Marlin/src/pins/mega/pins_MIGHTYBOARD_REVE.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -37,7 +37,7 @@ * number (B5) agrees with the schematic but B5 is assigned to logical pin 11. */ -#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) +#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__) #error "Oops! Select 'Mega 1280' or 'Mega 2560' in 'Tools > Board.'" #endif @@ -47,60 +47,60 @@ // // Servos // -#define SERVO0_PIN 36 // C1 (1280-EX1) -#define SERVO1_PIN 37 // C0 (1280-EX2) -#define SERVO2_PIN 40 // G1 (1280-EX3) -#define SERVO3_PIN 41 // G0 (1280-EX4) +#define SERVO0_PIN 36 // C1 (1280-EX1) +#define SERVO1_PIN 37 // C0 (1280-EX2) +#define SERVO2_PIN 40 // G1 (1280-EX3) +#define SERVO3_PIN 41 // G0 (1280-EX4) // // Limit Switches // -#define X_MIN_PIN 49 // L0 -#define X_MAX_PIN 48 // L1 -#define Y_MIN_PIN 47 // L2 -#define Y_MAX_PIN 46 // L3 -#define Z_MIN_PIN 43 // L6 -#define Z_MAX_PIN 42 // L7 +#define X_MIN_PIN 49 // L0 +#define X_MAX_PIN 48 // L1 +#define Y_MIN_PIN 47 // L2 +#define Y_MAX_PIN 46 // L3 +#define Z_MIN_PIN 43 // L6 +#define Z_MAX_PIN 42 // L7 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 42 + #define Z_MIN_PROBE_PIN 42 #endif // // Filament Runout Pins // #ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN 49 + #define FIL_RUNOUT_PIN 49 #endif #ifndef FIL_RUNOUT2_PIN - #define FIL_RUNOUT2_PIN 47 + #define FIL_RUNOUT2_PIN 47 #endif // // Steppers // -#define X_STEP_PIN 55 // F1 -#define X_DIR_PIN 54 // F0 -#define X_ENABLE_PIN 56 // F2 +#define X_STEP_PIN 55 // F1 +#define X_DIR_PIN 54 // F0 +#define X_ENABLE_PIN 56 // F2 -#define Y_STEP_PIN 59 // F5 -#define Y_DIR_PIN 58 // F4 -#define Y_ENABLE_PIN 60 // F6 +#define Y_STEP_PIN 59 // F5 +#define Y_DIR_PIN 58 // F4 +#define Y_ENABLE_PIN 60 // F6 -#define Z_STEP_PIN 63 // K1 -#define Z_DIR_PIN 62 // K0 -#define Z_ENABLE_PIN 64 // K2 +#define Z_STEP_PIN 63 // K1 +#define Z_DIR_PIN 62 // K0 +#define Z_ENABLE_PIN 64 // K2 -#define E0_STEP_PIN 25 // A3 -#define E0_DIR_PIN 24 // A2 -#define E0_ENABLE_PIN 26 // A4 +#define E0_STEP_PIN 25 // A3 +#define E0_DIR_PIN 24 // A2 +#define E0_ENABLE_PIN 26 // A4 -#define E1_STEP_PIN 29 // A7 -#define E1_DIR_PIN 28 // A6 -#define E1_ENABLE_PIN 39 // G2 +#define E1_STEP_PIN 29 // A7 +#define E1_DIR_PIN 28 // A6 +#define E1_ENABLE_PIN 39 // G2 // // I2C Digipots - MCP4018 @@ -108,22 +108,22 @@ // Set from 0 - 127 with stop bit. // (Ex. 3F << 1 | 1) // -#define DIGIPOTS_I2C_SCL 76 // J5 -#define DIGIPOTS_I2C_SDA_X 57 // F3 -#define DIGIPOTS_I2C_SDA_Y 61 // F7 -#define DIGIPOTS_I2C_SDA_Z 65 // K3 -#define DIGIPOTS_I2C_SDA_E0 27 // A5 -#define DIGIPOTS_I2C_SDA_E1 77 // J6 +#define DIGIPOTS_I2C_SCL 76 // J5 +#define DIGIPOTS_I2C_SDA_X 57 // F3 +#define DIGIPOTS_I2C_SDA_Y 61 // F7 +#define DIGIPOTS_I2C_SDA_Z 65 // K3 +#define DIGIPOTS_I2C_SDA_E0 27 // A5 +#define DIGIPOTS_I2C_SDA_E1 77 // J6 #ifndef DIGIPOT_I2C_ADDRESS_A - #define DIGIPOT_I2C_ADDRESS_A 0x2F // unshifted slave address (5E <- 2F << 1) + #define DIGIPOT_I2C_ADDRESS_A 0x2F // unshifted slave address (5E <- 2F << 1) #endif // // Temperature Sensors // // K7 - 69 / ADC15 - 15 -#define TEMP_BED_PIN 15 +#define TEMP_BED_PIN 15 // SPI for Max6675 or Max31855 Thermocouple // Uses a separate SPI bus @@ -133,15 +133,15 @@ // 2 E4 CS2 // 78 E2 SCK // -#define THERMO_SCK_PIN 78 // E2 -#define THERMO_DO_PIN 3 // E5 -#define THERMO_CS1_PIN 5 // E3 -#define THERMO_CS2_PIN 2 // E4 +#define THERMO_SCK_PIN 78 // E2 +#define THERMO_DO_PIN 3 // E5 +#define THERMO_CS1_PIN 5 // E3 +#define THERMO_CS2_PIN 2 // E4 -#define MAX6675_SS_PIN THERMO_CS1_PIN -#define MAX6675_SS2_PIN THERMO_CS2_PIN -#define MAX6675_SCK_PIN THERMO_SCK_PIN -#define MAX6675_DO_PIN THERMO_DO_PIN +#define MAX6675_SS_PIN THERMO_CS1_PIN +#define MAX6675_SS2_PIN THERMO_CS2_PIN +#define MAX6675_SCK_PIN THERMO_SCK_PIN +#define MAX6675_DO_PIN THERMO_DO_PIN // // Augmentation for auto-assigning plugs @@ -152,14 +152,14 @@ // // Labels from the schematic: -#define EX1_HEAT_PIN 6 // H3 -#define EX1_FAN_PIN 7 // H4 -#define EX2_HEAT_PIN 11 // B5 -#define EX2_FAN_PIN 12 // B6 -#define HBP_PIN 45 // L4 -#define EXTRA_FET_PIN 44 // L5 - -#if HOTENDS > 1 +#define EX1_HEAT_PIN 6 // H3 +#define EX1_FAN_PIN 7 // H4 +#define EX2_HEAT_PIN 11 // B5 +#define EX2_FAN_PIN 12 // B6 +#define HBP_PIN 45 // L4 +#define EXTRA_FET_PIN 44 // L5 + +#if HAS_MULTI_HOTEND #if TEMP_SENSOR_BED #define IS_EEB #else @@ -174,94 +174,99 @@ // // Heaters / Fans (24V) // -#define HEATER_0_PIN EX1_HEAT_PIN - -#if ENABLED(IS_EFB) // Hotend, Fan, Bed - #define HEATER_BED_PIN HBP_PIN -#elif ENABLED(IS_EEF) // Hotend, Hotend, Fan - #define HEATER_1_PIN EX2_HEAT_PIN -#elif ENABLED(IS_EEB) // Hotend, Hotend, Bed - #define HEATER_1_PIN EX2_HEAT_PIN - #define HEATER_BED_PIN HBP_PIN -#elif ENABLED(IS_EFF) // Hotend, Fan, Fan - #define FAN1_PIN HBP_PIN +#define HEATER_0_PIN EX1_HEAT_PIN + +#if ENABLED(IS_EFB) // Hotend, Fan, Bed + #define HEATER_BED_PIN HBP_PIN +#elif ENABLED(IS_EEF) // Hotend, Hotend, Fan + #define HEATER_1_PIN EX2_HEAT_PIN +#elif ENABLED(IS_EEB) // Hotend, Hotend, Bed + #define HEATER_1_PIN EX2_HEAT_PIN + #define HEATER_BED_PIN HBP_PIN +#elif ENABLED(IS_EFF) // Hotend, Fan, Fan + #define FAN1_PIN HBP_PIN #endif #ifndef FAN_PIN #if EITHER(IS_EFB, IS_EFF) // Hotend, Fan, Bed or Hotend, Fan, Fan - #define FAN_PIN EX2_HEAT_PIN + #define FAN_PIN EX2_HEAT_PIN #elif EITHER(IS_EEF, IS_SF) // Hotend, Hotend, Fan or Spindle, Fan - #define FAN_PIN HBP_PIN + #define FAN_PIN HBP_PIN #else - #define FAN_PIN EXTRA_FET_PIN + #define FAN_PIN EXTRA_FET_PIN #endif #endif +#ifndef CONTROLLER_FAN_PIN + #define CONTROLLER_FAN_PIN EX2_FAN_PIN +#endif + // // Misc. Functions // -#define LED_PIN 13 // B7 -#define CUTOFF_RESET_PIN 16 // H1 -#define CUTOFF_TEST_PIN 17 // H0 +#define LED_PIN 13 // B7 +#define CUTOFF_RESET_PIN 16 // H1 +#define CUTOFF_TEST_PIN 17 // H0 +#define CUTOFF_SR_CHECK_PIN 70 // G4 (TOSC1) // // LCD / Controller // -#if HAS_SPI_LCD +#if HAS_WIRED_LCD #if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) - #define LCD_PINS_RS 33 // C4: LCD-STROBE - #define LCD_PINS_ENABLE 72 // J2: LEFT - #define LCD_PINS_D4 35 // C2: LCD-CLK - #define LCD_PINS_D5 32 // C5: RLED - #define LCD_PINS_D6 34 // C3: LCD-DATA - #define LCD_PINS_D7 31 // C6: GLED + #define LCD_PINS_RS 33 // C4: LCD-STROBE + #define LCD_PINS_ENABLE 72 // J2: LEFT + #define LCD_PINS_D4 35 // C2: LCD-CLK + #define LCD_PINS_D5 32 // C5: RLED + #define LCD_PINS_D6 34 // C3: LCD-DATA + #define LCD_PINS_D7 31 // C6: GLED - #define BTN_EN2 75 // J4, UP - #define BTN_EN1 73 // J3, DOWN + #define BTN_EN2 75 // J4, UP + #define BTN_EN1 73 // J3, DOWN //STOP button connected as KILL_PIN - #define KILL_PIN 14 // J1, RIGHT + #define KILL_PIN 14 // J1, RIGHT //KILL - not connected - #define BEEPER_PIN 8 // H5, SD_WP + #define BEEPER_PIN 8 // H5, SD_WP //on board leds - #define STAT_LED_RED_LED SERVO0_PIN // C1 (1280-EX1, DEBUG2) - #define STAT_LED_BLUE_PIN SERVO1_PIN // C0 (1280-EX2, DEBUG3) + #define STAT_LED_RED_LED SERVO0_PIN // C1 (1280-EX1, DEBUG2) + #define STAT_LED_BLUE_PIN SERVO1_PIN // C0 (1280-EX2, DEBUG3) #else // Replicator uses a 3-wire SR controller with HD44780 - #define SR_DATA_PIN 34 // C3 - #define SR_CLK_PIN 35 // C2 - #define SR_STROBE_PIN 33 // C4 + #define SR_DATA_PIN 34 // C3 + #define SR_CLK_PIN 35 // C2 + #define SR_STROBE_PIN 33 // C4 - #define BTN_UP 75 // J4 - #define BTN_DWN 73 // J3 - #define BTN_LFT 72 // J2 - #define BTN_RT 14 // J1 + #define BTN_UP 75 // J4 + #define BTN_DWN 73 // J3 + #define BTN_LFT 72 // J2 + #define BTN_RT 14 // J1 // Disable encoder #undef BTN_EN1 #undef BTN_EN2 - #define BEEPER_PIN 4 // G5 + #define BEEPER_PIN 4 // G5 - #define STAT_LED_RED_PIN 32 // C5 - #define STAT_LED_BLUE_PIN 31 // C6 (Actually green) + #define STAT_LED_RED_PIN 32 // C5 + #define STAT_LED_BLUE_PIN 31 // C6 (Actually green) #endif - #define BTN_CENTER 15 // J0 - #define BTN_ENC BTN_CENTER + #define BTN_CENTER 15 // J0 + #define BTN_ENC BTN_CENTER -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD // // SD Card // -#define SDSS 53 // B0 -#define SD_DETECT_PIN 9 // H6 +#define SDSS 53 // B0 +#define SD_DETECT_PIN 9 // H6 // // TMC 220x @@ -280,19 +285,19 @@ * Software serial */ - #define X_SERIAL_TX_PIN 16 - #define X_SERIAL_RX_PIN 17 + #define X_SERIAL_TX_PIN 16 + #define X_SERIAL_RX_PIN 17 - #define Y_SERIAL_TX_PIN 18 - #define Y_SERIAL_RX_PIN 19 + #define Y_SERIAL_TX_PIN 18 + #define Y_SERIAL_RX_PIN 19 - #define Z_SERIAL_TX_PIN 41 - #define Z_SERIAL_RX_PIN 66 + #define Z_SERIAL_TX_PIN 41 + #define Z_SERIAL_RX_PIN 66 - #define E0_SERIAL_TX_PIN 40 - #define E0_SERIAL_RX_PIN 67 + #define E0_SERIAL_TX_PIN 40 + #define E0_SERIAL_RX_PIN 67 - #define E1_SERIAL_TX_PIN 37 - #define E1_SERIAL_RX_PIN 68 + #define E1_SERIAL_TX_PIN 37 + #define E1_SERIAL_RX_PIN 68 #endif diff --git a/Marlin/src/pins/mega/pins_MINITRONICS.h b/Marlin/src/pins/mega/pins_MINITRONICS.h index 5b06e3b83590..bbe746461eca 100644 --- a/Marlin/src/pins/mega/pins_MINITRONICS.h +++ b/Marlin/src/pins/mega/pins_MINITRONICS.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -29,10 +29,9 @@ * Rev B 2 JAN 2017 * * Added pin definitions for M3, M4 & M5 spindle control commands - * */ -#ifndef __AVR_ATmega1281__ +#if NOT_TARGET(__AVR_ATmega1281__) #error "Oops! Select 'Minitronics' in 'Tools > Board.'" #elif HOTENDS > 2 || E_STEPPERS > 2 #error "Minitronics supports up to 2 hotends / E-steppers. Comment out this line to continue." @@ -42,102 +41,102 @@ // // Limit Switches // -#define X_MIN_PIN 5 -#define X_MAX_PIN 2 -#define Y_MIN_PIN 2 -#define Y_MAX_PIN 15 -#define Z_MIN_PIN 6 -#define Z_MAX_PIN -1 +#define X_MIN_PIN 5 +#define X_MAX_PIN 2 +#define Y_MIN_PIN 2 +#define Y_MAX_PIN 15 +#define Z_MIN_PIN 6 +#define Z_MAX_PIN -1 // // Steppers // -#define X_STEP_PIN 48 -#define X_DIR_PIN 47 -#define X_ENABLE_PIN 49 +#define X_STEP_PIN 48 +#define X_DIR_PIN 47 +#define X_ENABLE_PIN 49 -#define Y_STEP_PIN 39 // A6 -#define Y_DIR_PIN 40 // A0 -#define Y_ENABLE_PIN 38 +#define Y_STEP_PIN 39 // A6 +#define Y_DIR_PIN 40 // A0 +#define Y_ENABLE_PIN 38 -#define Z_STEP_PIN 42 // A2 -#define Z_DIR_PIN 43 // A6 -#define Z_ENABLE_PIN 41 // A1 +#define Z_STEP_PIN 42 // A2 +#define Z_DIR_PIN 43 // A6 +#define Z_ENABLE_PIN 41 // A1 -#define E0_STEP_PIN 45 -#define E0_DIR_PIN 44 -#define E0_ENABLE_PIN 27 +#define E0_STEP_PIN 45 +#define E0_DIR_PIN 44 +#define E0_ENABLE_PIN 27 -#define E1_STEP_PIN 36 -#define E1_DIR_PIN 35 -#define E1_ENABLE_PIN 37 +#define E1_STEP_PIN 36 +#define E1_DIR_PIN 35 +#define E1_ENABLE_PIN 37 // // Temperature Sensors // -#define TEMP_0_PIN 7 // Analog Input -#define TEMP_1_PIN 6 // Analog Input -#define TEMP_BED_PIN 6 // Analog Input +#define TEMP_0_PIN 7 // Analog Input +#define TEMP_1_PIN 6 // Analog Input +#define TEMP_BED_PIN 6 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 7 // EXTRUDER 1 -#define HEATER_1_PIN 8 // EXTRUDER 2 -#define HEATER_BED_PIN 3 // BED +#define HEATER_0_PIN 7 // EXTRUDER 1 +#define HEATER_1_PIN 8 // EXTRUDER 2 +#define HEATER_BED_PIN 3 // BED #ifndef FAN_PIN - #define FAN_PIN 9 + #define FAN_PIN 9 #endif // // Misc. Functions // -#define SDSS 16 -#define LED_PIN 46 +#define SDSS 16 +#define LED_PIN 46 // // LCD / Controller // -#define BEEPER_PIN -1 +#define BEEPER_PIN -1 #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) - #define LCD_PINS_RS 15 // CS chip select /SS chip slave select - #define LCD_PINS_ENABLE 11 // SID (MOSI) - #define LCD_PINS_D4 10 // SCK (CLK) clock + #define LCD_PINS_RS 15 // CS chip select /SS chip slave select + #define LCD_PINS_ENABLE 11 // SID (MOSI) + #define LCD_PINS_D4 10 // SCK (CLK) clock - #define BTN_EN1 18 - #define BTN_EN2 17 - #define BTN_ENC 25 + #define BTN_EN1 18 + #define BTN_EN2 17 + #define BTN_ENC 25 - #define SD_DETECT_PIN 30 + #define SD_DETECT_PIN 30 #else - #define LCD_PINS_RS -1 - #define LCD_PINS_ENABLE -1 + #define LCD_PINS_RS -1 + #define LCD_PINS_ENABLE -1 // Buttons are directly attached using keypad - #define BTN_EN1 -1 - #define BTN_EN2 -1 - #define BTN_ENC -1 + #define BTN_EN1 -1 + #define BTN_EN2 -1 + #define BTN_ENC -1 - #define SD_DETECT_PIN -1 // Minitronics doesn't use this + #define SD_DETECT_PIN -1 // Minitronics doesn't use this #endif // // M3/M4/M5 - Spindle/Laser Control // -#if HAS_CUTTER // assumes we're only doing CNC work (no 3D printing) +#if HAS_CUTTER // assumes we're only doing CNC work (no 3D printing) #undef HEATER_BED_PIN - #undef TEMP_BED_PIN // need to free up some pins but also need to - #undef TEMP_0_PIN // re-assign them (to unused pins) because Marlin - #undef TEMP_1_PIN // requires the presence of certain pins or else it - #define HEATER_BED_PIN 4 // won't compile - #define TEMP_BED_PIN 50 - #define TEMP_0_PIN 51 - #define SPINDLE_LASER_ENA_PIN 52 // using A6 because it already has a pullup - #define SPINDLE_LASER_PWM_PIN 3 // WARNING - LED & resistor pull up to +12/+24V stepper voltage - #define SPINDLE_DIR_PIN 53 + #undef TEMP_BED_PIN // need to free up some pins but also need to + #undef TEMP_0_PIN // re-assign them (to unused pins) because Marlin + #undef TEMP_1_PIN // requires the presence of certain pins or else it + #define HEATER_BED_PIN 4 // won't compile + #define TEMP_BED_PIN 50 + #define TEMP_0_PIN 51 + #define SPINDLE_LASER_ENA_PIN 52 // using A6 because it already has a pullup + #define SPINDLE_LASER_PWM_PIN 3 // WARNING - LED & resistor pull up to +12/+24V stepper voltage + #define SPINDLE_DIR_PIN 53 #endif diff --git a/Marlin/src/pins/mega/pins_OVERLORD.h b/Marlin/src/pins/mega/pins_OVERLORD.h index 80f72d04e902..045c1bc0fa6c 100644 --- a/Marlin/src/pins/mega/pins_OVERLORD.h +++ b/Marlin/src/pins/mega/pins_OVERLORD.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Dreammaker Overlord v1.1 pin assignments */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #elif HOTENDS > 2 || E_STEPPERS > 2 #error "Overlord Controller supports up to 2 hotends / E-steppers. Comment out this line to continue." @@ -37,108 +37,108 @@ // // Limit Switches // -#define X_STOP_PIN 24 -#define Y_STOP_PIN 28 -#define Z_MIN_PIN 46 -#define Z_MAX_PIN 32 +#define X_STOP_PIN 24 +#define Y_STOP_PIN 28 +#define Z_MIN_PIN 46 +#define Z_MAX_PIN 32 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 46 // JP4, Tfeed1 + #define Z_MIN_PROBE_PIN 46 // JP4, Tfeed1 #endif #if ENABLED(FILAMENT_RUNOUT_SENSOR) - #define FIL_RUNOUT_PIN 44 // JP3, Tfeed2 + #define FIL_RUNOUT_PIN 44 // JP3, Tfeed2 #endif // // Steppers // -#define X_STEP_PIN 25 -#define X_DIR_PIN 23 -#define X_ENABLE_PIN 27 +#define X_STEP_PIN 25 +#define X_DIR_PIN 23 +#define X_ENABLE_PIN 27 -#define Y_STEP_PIN 31 -#define Y_DIR_PIN 33 -#define Y_ENABLE_PIN 29 +#define Y_STEP_PIN 31 +#define Y_DIR_PIN 33 +#define Y_ENABLE_PIN 29 -#define Z_STEP_PIN 37 -#define Z_DIR_PIN 39 -#define Z_ENABLE_PIN 35 +#define Z_STEP_PIN 37 +#define Z_DIR_PIN 39 +#define Z_ENABLE_PIN 35 -#define E0_STEP_PIN 43 -#define E0_DIR_PIN 45 -#define E0_ENABLE_PIN 41 +#define E0_STEP_PIN 43 +#define E0_DIR_PIN 45 +#define E0_ENABLE_PIN 41 -#define E1_STEP_PIN 49 -#define E1_DIR_PIN 47 -#define E1_ENABLE_PIN 48 +#define E1_STEP_PIN 49 +#define E1_DIR_PIN 47 +#define E1_ENABLE_PIN 48 // // Temperature Sensors // -#define TEMP_0_PIN 8 // Analog Input -#define TEMP_1_PIN 9 // Analog Input - Redundant temp sensor -#define TEMP_2_PIN 12 // Analog Input -#define TEMP_3_PIN 14 // Analog Input -#define TEMP_BED_PIN 10 // Analog Input +#define TEMP_0_PIN 8 // Analog Input +#define TEMP_1_PIN 9 // Analog Input - Redundant temp sensor +#define TEMP_2_PIN 12 // Analog Input +#define TEMP_3_PIN 14 // Analog Input +#define TEMP_BED_PIN 10 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 2 -#define HEATER_1_PIN 3 -#define HEATER_BED_PIN 4 +#define HEATER_0_PIN 2 +#define HEATER_1_PIN 3 +#define HEATER_BED_PIN 4 -#define FAN_PIN 7 // material cooling fan +#define FAN_PIN 7 // material cooling fan // // SD Card // -#define SDSS 53 -#define SD_DETECT_PIN 38 +#define SDSS 53 +#define SD_DETECT_PIN 38 // // Misc. Functions // -#define LED_PIN 13 // On PCB status led -#define PS_ON_PIN 12 // For stepper/heater/fan power. Active HIGH. -#define POWER_LOSS_PIN 34 // Power check - whether hotends/steppers/fans have power +#define LED_PIN 13 // On PCB status led +#define PS_ON_PIN 12 // For stepper/heater/fan power. Active HIGH. +#define POWER_LOSS_PIN 34 // Power check - whether hotends/steppers/fans have power #if ENABLED(BATTERY_STATUS_AVAILABLE) #undef BATTERY_STATUS_PIN - #define BATTERY_STATUS_PIN 26 // Status of power loss battery, whether it is charged (low) or charging (high) + #define BATTERY_STATUS_PIN 26 // Status of power loss battery, whether it is charged (low) or charging (high) #endif #if ENABLED(INPUT_VOLTAGE_AVAILABLE) #undef VOLTAGE_DETECTION_PIN - #define VOLTAGE_DETECTION_PIN 11 // Analog Input - ADC Voltage level of main input + #define VOLTAGE_DETECTION_PIN 11 // Analog Input - ADC Voltage level of main input #endif // // LCD / Controller // -#if HAS_GRAPHICAL_LCD +#if HAS_MARLINUI_U8GLIB // OVERLORD OLED pins - #define LCD_PINS_RS 20 - #define LCD_PINS_D5 21 - #define LCD_PINS_ENABLE 15 - #define LCD_PINS_D4 14 - #define LCD_PINS_D6 5 - #define LCD_PINS_D7 6 + #define LCD_PINS_RS 20 + #define LCD_PINS_D5 21 + #define LCD_PINS_ENABLE 15 + #define LCD_PINS_D4 14 + #define LCD_PINS_D6 5 + #define LCD_PINS_D7 6 #ifndef LCD_RESET_PIN - #define LCD_RESET_PIN 5 // LCD_PINS_D6 + #define LCD_RESET_PIN 5 // LCD_PINS_D6 #endif #endif #if ENABLED(NEWPANEL) - #define BTN_ENC 16 // Enter Pin - #define BTN_UP 19 // Button UP Pin - #define BTN_DWN 17 // Button DOWN Pin + #define BTN_ENC 16 // Enter Pin + #define BTN_UP 19 // Button UP Pin + #define BTN_DWN 17 // Button DOWN Pin #endif // Additional connectors/pins on the Overlord V1.X board -#define PCB_VERSION_PIN 22 -#define APPROACH_PIN 11 // JP7, Tpd -#define GATE_PIN 36 // Threshold, JP6, Tg +#define PCB_VERSION_PIN 22 +#define APPROACH_PIN 11 // JP7, Tpd +#define GATE_PIN 36 // Threshold, JP6, Tg diff --git a/Marlin/src/pins/mega/pins_PICA.h b/Marlin/src/pins/mega/pins_PICA.h index 4c618bda4e33..ff4d3e834d05 100644 --- a/Marlin/src/pins/mega/pins_PICA.h +++ b/Marlin/src/pins/mega/pins_PICA.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -29,8 +29,8 @@ * Applies to PICA, PICA_REVB */ -#ifndef BOARD_NAME - #define BOARD_NAME "PICA" +#ifndef BOARD_INFO_NAME + #define BOARD_INFO_NAME "PICA" #endif /* @@ -42,102 +42,112 @@ AD12 = 66; AD13 = 67; AD14 = 68; AD15 = 69; */ -#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) +#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__) #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." #endif +// +// Servos +// +#define SERVO0_PIN 3 +#define SERVO1_PIN 4 +#define SERVO2_PIN 5 // // Limit Switches // -#define X_MIN_PIN 14 -#define X_MAX_PIN 15 -#define Y_MIN_PIN 16 -#define Y_MAX_PIN 17 -#define Z_MIN_PIN 23 -#define Z_MAX_PIN 22 +#define X_MIN_PIN 14 +#define X_MAX_PIN 15 +#define Y_MIN_PIN 16 +#define Y_MAX_PIN 17 +#define Z_MIN_PIN 23 +#define Z_MAX_PIN 22 // // Steppers // -#define X_STEP_PIN 55 -#define X_DIR_PIN 54 -#define X_ENABLE_PIN 60 +#define X_STEP_PIN 55 +#define X_DIR_PIN 54 +#define X_ENABLE_PIN 60 + +#define Y_STEP_PIN 57 +#define Y_DIR_PIN 56 +#define Y_ENABLE_PIN 61 -#define Y_STEP_PIN 57 -#define Y_DIR_PIN 56 -#define Y_ENABLE_PIN 61 +#define Z_STEP_PIN 59 +#define Z_DIR_PIN 58 +#define Z_ENABLE_PIN 62 -#define Z_STEP_PIN 59 -#define Z_DIR_PIN 58 -#define Z_ENABLE_PIN 62 +#define E0_STEP_PIN 67 +#define E0_DIR_PIN 24 +#define E0_ENABLE_PIN 26 -#define E0_STEP_PIN 67 -#define E0_DIR_PIN 24 -#define E0_ENABLE_PIN 26 +#define E1_STEP_PIN 68 +#define E1_DIR_PIN 28 +#define E1_ENABLE_PIN 27 // // Temperature Sensors // -#define TEMP_0_PIN 9 // Analog Input -#define TEMP_1_PIN 10 -#define TEMP_BED_PIN 10 -#define TEMP_2_PIN 11 -#define TEMP_3_PIN 12 +#define TEMP_0_PIN 9 // Analog Input +#define TEMP_1_PIN 10 +#define TEMP_BED_PIN 10 +#define TEMP_2_PIN 11 +#define TEMP_3_PIN 12 // // Heaters / Fans // #ifndef HEATER_0_PIN - #define HEATER_0_PIN 10 // E0 + #define HEATER_0_PIN 10 // E0 #endif #ifndef HEATER_1_PIN - #define HEATER_1_PIN 2 // E1 + #define HEATER_1_PIN 2 // E1 #endif -#define HEATER_BED_PIN 8 // HEAT-BED +#define HEATER_BED_PIN 8 // HEAT-BED #ifndef FAN_PIN - #define FAN_PIN 9 + #define FAN_PIN 9 #endif #ifndef FAN_2_PIN - #define FAN_2_PIN 7 + #define FAN_2_PIN 7 #endif -#define SDPOWER_PIN -1 -#define LED_PIN -1 -#define PS_ON_PIN -1 -#define KILL_PIN -1 +#define SDPOWER_PIN -1 +#define LED_PIN -1 +#define PS_ON_PIN -1 +#define KILL_PIN -1 -#define SSR_PIN 6 +#define SSR_PIN 6 // SPI for Max6675 or Max31855 Thermocouple #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 66 // Don't use 53 if using Display/SD card + #define MAX6675_SS_PIN 66 // Don't use 53 if using Display/SD card #else - #define MAX6675_SS_PIN 66 // Don't use 49 (SD_DETECT_PIN) + #define MAX6675_SS_PIN 66 // Don't use 49 (SD_DETECT_PIN) #endif // // SD Support // -#define SD_DETECT_PIN 49 -#define SDSS 53 +#define SD_DETECT_PIN 49 +#define SDSS 53 // // LCD / Controller // -#define BEEPER_PIN 29 +#define BEEPER_PIN 29 -#if HAS_SPI_LCD - #define LCD_PINS_RS 33 - #define LCD_PINS_ENABLE 30 - #define LCD_PINS_D4 35 - #define LCD_PINS_D5 32 - #define LCD_PINS_D6 37 - #define LCD_PINS_D7 36 +#if HAS_WIRED_LCD + #define LCD_PINS_RS 33 + #define LCD_PINS_ENABLE 30 + #define LCD_PINS_D4 35 + #define LCD_PINS_D5 32 + #define LCD_PINS_D6 37 + #define LCD_PINS_D7 36 - #define BTN_EN1 47 - #define BTN_EN2 48 - #define BTN_ENC 31 + #define BTN_EN1 47 + #define BTN_EN2 48 + #define BTN_ENC 31 - #define LCD_SDSS 53 + #define LCD_SDSS 53 #endif diff --git a/Marlin/src/pins/mega/pins_PICAOLD.h b/Marlin/src/pins/mega/pins_PICAOLD.h index 88fa1ada29c0..f53a4cdcd258 100644 --- a/Marlin/src/pins/mega/pins_PICAOLD.h +++ b/Marlin/src/pins/mega/pins_PICAOLD.h @@ -16,13 +16,13 @@ * 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 . + * along with this program. If not, see . * */ -#define HEATER_0_PIN 9 // E0 -#define HEATER_1_PIN 10 // E1 -#define FAN_PIN 11 -#define FAN2_PIN 12 +#define HEATER_0_PIN 9 // E0 +#define HEATER_1_PIN 10 // E1 +#define FAN_PIN 11 +#define FAN2_PIN 12 #include "pins_PICA.h" diff --git a/Marlin/src/pins/mega/pins_SILVER_GATE.h b/Marlin/src/pins/mega/pins_SILVER_GATE.h index bde1f8708892..41cbe5e0e078 100644 --- a/Marlin/src/pins/mega/pins_SILVER_GATE.h +++ b/Marlin/src/pins/mega/pins_SILVER_GATE.h @@ -16,78 +16,84 @@ * 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 . + * along with this program. If not, see . * */ #pragma once -#if !defined(__AVR_ATmega1281__) && !defined(__AVR_ATmega2561__) +#if NOT_TARGET(__AVR_ATmega1281__, __AVR_ATmega2561__) #error "Oops! Select 'Silvergate' in 'Tools > Board.'" #endif #define BOARD_INFO_NAME "Silver Gate" -#define X_STEP_PIN 43 -#define X_DIR_PIN 44 -#define X_ENABLE_PIN 42 -#define X_MIN_PIN 31 -#define X_MAX_PIN 34 +#define X_STEP_PIN 43 +#define X_DIR_PIN 44 +#define X_ENABLE_PIN 42 +#define X_MIN_PIN 31 +#define X_MAX_PIN 34 -#define Y_STEP_PIN 40 -#define Y_DIR_PIN 41 -#define Y_ENABLE_PIN 39 -#define Y_MIN_PIN 32 -#define Y_MAX_PIN 35 +#define Y_STEP_PIN 40 +#define Y_DIR_PIN 41 +#define Y_ENABLE_PIN 39 +#define Y_MIN_PIN 32 +#define Y_MAX_PIN 35 -#define Z_STEP_PIN 13 -#define Z_DIR_PIN 38 -#define Z_ENABLE_PIN 14 -#define Z_MIN_PIN 33 -#define Z_MAX_PIN 36 +#define Z_STEP_PIN 13 +#define Z_DIR_PIN 38 +#define Z_ENABLE_PIN 14 +#define Z_MIN_PIN 33 +#define Z_MAX_PIN 36 -#define E0_STEP_PIN 27 -#define E0_DIR_PIN 37 -#define E0_ENABLE_PIN 45 +#define E0_STEP_PIN 27 +#define E0_DIR_PIN 37 +#define E0_ENABLE_PIN 45 -#define SDSS 16 +#define SDSS 16 #ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN 34 // X_MAX unless overridden + #define FIL_RUNOUT_PIN 34 // X_MAX unless overridden #endif #ifndef FAN_PIN - #define FAN_PIN 5 + #define FAN_PIN 5 #endif -#define HEATER_0_PIN 7 +#define HEATER_0_PIN 7 -#define ORIG_E0_AUTO_FAN_PIN 3 // Use this by NOT overriding E0_AUTO_FAN_PIN -#define CONTROLLER_FAN_PIN 2 +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN 3 +#endif + +#define CONTROLLER_FAN_PIN 2 -#define TEMP_0_PIN 7 // Analog Input +#define TEMP_0_PIN 7 // Analog Input -#define HEATER_BED_PIN 8 -#define TEMP_BED_PIN 6 +#define HEATER_BED_PIN 8 +#define TEMP_BED_PIN 6 -#if HAS_GRAPHICAL_LCD - #if ENABLED(U8GLIB_ST7920) // SPI GLCD 12864 ST7920 - #define LCD_PINS_RS 30 - #define LCD_PINS_ENABLE 20 - #define LCD_PINS_D4 25 - #define BEEPER_PIN 29 - #define BTN_EN1 19 - #define BTN_EN2 22 - #define BTN_ENC 24 - #define LCD_BACKLIGHT_PIN 6 +#if HAS_MARLINUI_U8GLIB + #if ENABLED(U8GLIB_ST7920) // SPI GLCD 12864 ST7920 + #define LCD_PINS_RS 30 + #define LCD_PINS_ENABLE 20 + #define LCD_PINS_D4 25 + #define BEEPER_PIN 29 + #define BTN_EN1 19 + #define BTN_EN2 22 + #define BTN_ENC 24 + #define LCD_BACKLIGHT_PIN 6 #if ENABLED(SILVER_GATE_GLCD_CONTROLLER) - #define KILL_PIN 21 - #define HOME_PIN 28 + #define KILL_PIN 21 + #define HOME_PIN 28 #endif #endif #endif -#define SD_DETECT_PIN 15 +#define SD_DETECT_PIN 15 -#define STAT_LED_RED_PIN 23 -#define STAT_LED_BLUE_PIN 26 -#define CASE_LIGHT_PIN 51 +#define STAT_LED_RED_PIN 23 +#define STAT_LED_BLUE_PIN 26 + +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN 51 +#endif diff --git a/Marlin/src/pins/mega/pins_WANHAO_ONEPLUS.h b/Marlin/src/pins/mega/pins_WANHAO_ONEPLUS.h index c011d9daa765..52e757c53408 100644 --- a/Marlin/src/pins/mega/pins_WANHAO_ONEPLUS.h +++ b/Marlin/src/pins/mega/pins_WANHAO_ONEPLUS.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Wanhao 0ne+ pin assignments */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -36,76 +36,76 @@ // // Limit Switches // -#define X_STOP_PIN 19 -#define Y_STOP_PIN 18 -#define Z_STOP_PIN 38 +#define X_STOP_PIN 19 +#define Y_STOP_PIN 18 +#define Z_STOP_PIN 38 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 38 + #define Z_MIN_PROBE_PIN 38 #endif // // Steppers // -#define X_STEP_PIN 22 -#define X_DIR_PIN 23 -#define X_ENABLE_PIN 57 +#define X_STEP_PIN 22 +#define X_DIR_PIN 23 +#define X_ENABLE_PIN 57 -#define Y_STEP_PIN 25 -#define Y_DIR_PIN 26 -#define Y_ENABLE_PIN 24 +#define Y_STEP_PIN 25 +#define Y_DIR_PIN 26 +#define Y_ENABLE_PIN 24 -#define Z_STEP_PIN 29 -#define Z_DIR_PIN 39 -#define Z_ENABLE_PIN 28 +#define Z_STEP_PIN 29 +#define Z_DIR_PIN 39 +#define Z_ENABLE_PIN 28 -#define E0_STEP_PIN 55 -#define E0_DIR_PIN 56 -#define E0_ENABLE_PIN 54 +#define E0_STEP_PIN 55 +#define E0_DIR_PIN 56 +#define E0_ENABLE_PIN 54 // // Temperature Sensors // -#define TEMP_0_PIN 13 -#define TEMP_BED_PIN 14 +#define TEMP_0_PIN 13 +#define TEMP_BED_PIN 14 // // Heaters / Fans // -#define HEATER_0_PIN 4 -#define HEATER_BED_PIN 44 -#define FAN_PIN 12 // IO pin. Buffer needed +#define HEATER_0_PIN 4 +#define HEATER_BED_PIN 44 +#define FAN_PIN 12 // IO pin. Buffer needed // // SD Card // -#define SD_DETECT_PIN -1 -#define SDSS 53 +#define SD_DETECT_PIN -1 +#define SDSS 53 // // Misc. Functions // -#define BEEPER_PIN 37 -#define KILL_PIN 64 +#define BEEPER_PIN 37 +#define KILL_PIN 64 // // LCD / Controller (Integrated MINIPANEL) // #if ENABLED(MINIPANEL) - #define DOGLCD_A0 40 - #define DOGLCD_CS 41 - #define LCD_BACKLIGHT_PIN 65 // Backlight LED on A11/D65 - #define LCD_RESET_PIN 27 + #define DOGLCD_A0 40 + #define DOGLCD_CS 41 + #define LCD_BACKLIGHT_PIN 65 // Backlight LED on A11/D65 + #define LCD_RESET_PIN 27 - #define BTN_EN1 2 - #define BTN_EN2 3 - #define BTN_ENC 5 + #define BTN_EN1 2 + #define BTN_EN2 3 + #define BTN_ENC 5 // This display has adjustable contrast - #define LCD_CONTRAST_MIN 0 - #define LCD_CONTRAST_MAX 255 - #define LCD_CONTRAST_INIT LCD_CONTRAST_MAX + #define LCD_CONTRAST_MIN 0 + #define LCD_CONTRAST_MAX 255 + #define LCD_CONTRAST_INIT LCD_CONTRAST_MAX #endif diff --git a/Marlin/src/pins/pins.h b/Marlin/src/pins/pins.h index ce03a3468d31..c5dbd2087627 100644 --- a/Marlin/src/pins/pins.h +++ b/Marlin/src/pins/pins.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -35,7 +35,7 @@ * These numbers are the same in any pin mapping. */ -#define MAX_EXTRUDERS 6 +#define MAX_EXTRUDERS 8 #if MB(RAMPS_13_EFB, RAMPS_14_EFB, RAMPS_PLUS_EFB, RAMPS_14_RE_ARM_EFB, RAMPS_SMART_EFB, RAMPS_DUO_EFB, RAMPS4DUE_EFB) #define IS_RAMPS_EFB @@ -51,143 +51,160 @@ #define HAS_FREE_AUX2_PINS !(BOTH(ULTRA_LCD, NEWPANEL) && ANY(PANEL_ONE, VIKI2, miniVIKI, MINIPANEL, REPRAPWORLD_KEYPAD)) +// Test the target within the included pins file +#ifdef __MARLIN_DEPS__ + #define NOT_TARGET(V...) 0 +#else + #define NOT_TARGET(V...) NONE(V) +#endif + // // RAMPS 1.3 / 1.4 - ATmega1280, ATmega2560 // #if MB(RAMPS_OLD) - #include "ramps/pins_RAMPS_OLD.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_RAMPS_OLD.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(RAMPS_13_EFB) - #include "ramps/pins_RAMPS_13.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_RAMPS_13.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(RAMPS_13_EEB) - #include "ramps/pins_RAMPS_13.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_RAMPS_13.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(RAMPS_13_EFF) - #include "ramps/pins_RAMPS_13.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_RAMPS_13.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(RAMPS_13_EEF) - #include "ramps/pins_RAMPS_13.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_RAMPS_13.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(RAMPS_13_SF) - #include "ramps/pins_RAMPS_13.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_RAMPS_13.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(RAMPS_14_EFB) - #include "ramps/pins_RAMPS.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_RAMPS.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(RAMPS_14_EEB) - #include "ramps/pins_RAMPS.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_RAMPS.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(RAMPS_14_EFF) - #include "ramps/pins_RAMPS.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_RAMPS.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(RAMPS_14_EEF) - #include "ramps/pins_RAMPS.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_RAMPS.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(RAMPS_14_SF) - #include "ramps/pins_RAMPS.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_RAMPS.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(RAMPS_PLUS_EFB) - #include "ramps/pins_RAMPS_PLUS.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_RAMPS_PLUS.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(RAMPS_PLUS_EEB) - #include "ramps/pins_RAMPS_PLUS.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_RAMPS_PLUS.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(RAMPS_PLUS_EFF) - #include "ramps/pins_RAMPS_PLUS.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_RAMPS_PLUS.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(RAMPS_PLUS_EEF) - #include "ramps/pins_RAMPS_PLUS.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_RAMPS_PLUS.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(RAMPS_PLUS_SF) - #include "ramps/pins_RAMPS_PLUS.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_RAMPS_PLUS.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 // // RAMPS Derivatives - ATmega1280, ATmega2560 // #elif MB(3DRAG) - #include "ramps/pins_3DRAG.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_3DRAG.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(K8200) - #include "ramps/pins_K8200.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 (3DRAG) + #include "ramps/pins_K8200.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 (3DRAG) #elif MB(K8400) - #include "ramps/pins_K8400.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 (3DRAG) + #include "ramps/pins_K8400.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 (3DRAG) +#elif MB(K8600) + #include "ramps/pins_K8600.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(K8800) - #include "ramps/pins_K8800.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 (3DRAG) + #include "ramps/pins_K8800.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 (3DRAG) #elif MB(BAM_DICE) - #include "ramps/pins_RAMPS.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_RAMPS.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(BAM_DICE_DUE) - #include "ramps/pins_BAM_DICE_DUE.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_BAM_DICE_DUE.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(MKS_BASE) - #include "ramps/pins_MKS_BASE_10.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_MKS_BASE_10.h" // ATmega2560 env:mega2560 #elif MB(MKS_BASE_14) - #include "ramps/pins_MKS_BASE_14.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_MKS_BASE_14.h" // ATmega2560 env:mega2560 #elif MB(MKS_BASE_15) - #include "ramps/pins_MKS_BASE_15.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_MKS_BASE_15.h" // ATmega2560 env:mega2560 #elif MB(MKS_BASE_16) - #include "ramps/pins_MKS_BASE_16.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_MKS_BASE_16.h" // ATmega2560 env:mega2560 #elif MB(MKS_BASE_HEROIC) - #include "ramps/pins_MKS_BASE_HEROIC.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_MKS_BASE_HEROIC.h" // ATmega2560 env:mega2560 #elif MB(MKS_GEN_13) - #include "ramps/pins_MKS_GEN_13.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_MKS_GEN_13.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(MKS_GEN_L) - #include "ramps/pins_MKS_GEN_L.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_MKS_GEN_L.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(KFB_2) - #include "ramps/pins_BIQU_KFB_2.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_BIQU_KFB_2.h" // ATmega2560 env:mega2560 #elif MB(ZRIB_V20) - #include "ramps/pins_ZRIB_V20.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 (MKS_GEN_13) + #include "ramps/pins_ZRIB_V20.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 (MKS_GEN_13) #elif MB(FELIX2) - #include "ramps/pins_FELIX2.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_FELIX2.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(RIGIDBOARD) - #include "ramps/pins_RIGIDBOARD.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_RIGIDBOARD.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(RIGIDBOARD_V2) - #include "ramps/pins_RIGIDBOARD_V2.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_RIGIDBOARD_V2.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(SAINSMART_2IN1) - #include "ramps/pins_SAINSMART_2IN1.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_SAINSMART_2IN1.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(ULTIMAKER) - #include "ramps/pins_ULTIMAKER.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_ULTIMAKER.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(ULTIMAKER_OLD) - #include "ramps/pins_ULTIMAKER_OLD.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "ramps/pins_ULTIMAKER_OLD.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(AZTEEG_X3) - #include "ramps/pins_AZTEEG_X3.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_AZTEEG_X3.h" // ATmega2560 env:mega2560 #elif MB(AZTEEG_X3_PRO) - #include "ramps/pins_AZTEEG_X3_PRO.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_AZTEEG_X3_PRO.h" // ATmega2560 env:mega2560 #elif MB(ULTIMAIN_2) - #include "ramps/pins_ULTIMAIN_2.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_ULTIMAIN_2.h" // ATmega2560 env:mega2560ext #elif MB(FORMBOT_RAPTOR) - #include "ramps/pins_FORMBOT_RAPTOR.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_FORMBOT_RAPTOR.h" // ATmega2560 env:mega2560 #elif MB(FORMBOT_RAPTOR2) - #include "ramps/pins_FORMBOT_RAPTOR2.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_FORMBOT_RAPTOR2.h" // ATmega2560 env:mega2560 #elif MB(FORMBOT_TREX2PLUS) - #include "ramps/pins_FORMBOT_TREX2PLUS.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_FORMBOT_TREX2PLUS.h" // ATmega2560 env:mega2560 #elif MB(FORMBOT_TREX3) - #include "ramps/pins_FORMBOT_TREX3.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_FORMBOT_TREX3.h" // ATmega2560 env:mega2560 #elif MB(RUMBA) - #include "ramps/pins_RUMBA.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_RUMBA.h" // ATmega2560 env:mega2560 #elif MB(RUMBA_RAISE3D) - #include "ramps/pins_RUMBA_RAISE3D.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_RUMBA_RAISE3D.h" // ATmega2560 env:mega2560 #elif MB(RL200) - #include "ramps/pins_RL200.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_RL200.h" // ATmega2560 env:mega2560 #elif MB(BQ_ZUM_MEGA_3D) - #include "ramps/pins_BQ_ZUM_MEGA_3D.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_BQ_ZUM_MEGA_3D.h" // ATmega2560 env:mega2560ext #elif MB(MAKEBOARD_MINI) - #include "ramps/pins_MAKEBOARD_MINI.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_MAKEBOARD_MINI.h" // ATmega2560 env:mega2560 #elif MB(TRIGORILLA_13) - #include "ramps/pins_TRIGORILLA_13.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_TRIGORILLA_13.h" // ATmega2560 env:mega2560 #elif MB(TRIGORILLA_14) - #include "ramps/pins_TRIGORILLA_14.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_TRIGORILLA_14.h" // ATmega2560 env:mega2560 #elif MB(TRIGORILLA_14_11) - #include "ramps/pins_TRIGORILLA_14.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_TRIGORILLA_14.h" // ATmega2560 env:mega2560 #elif MB(RAMPS_ENDER_4) - #include "ramps/pins_RAMPS_ENDER_4.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_RAMPS_ENDER_4.h" // ATmega2560 env:mega2560 #elif MB(RAMPS_CREALITY) - #include "ramps/pins_RAMPS_CREALITY.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_RAMPS_CREALITY.h" // ATmega2560 env:mega2560 #elif MB(RAMPS_DAGOMA) - #include "ramps/pins_RAMPS_DAGOMA.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_RAMPS_DAGOMA.h" // ATmega2560 env:mega2560 #elif MB(FYSETC_F6_13) #include "ramps/pins_FYSETC_F6_13.h" // ATmega2560 env:FYSETC_F6_13 #elif MB(FYSETC_F6_14) #include "ramps/pins_FYSETC_F6_14.h" // ATmega2560 env:FYSETC_F6_14 #elif MB(DUPLICATOR_I3_PLUS) - #include "ramps/pins_DUPLICATOR_I3_PLUS.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_DUPLICATOR_I3_PLUS.h" // ATmega2560 env:mega2560 #elif MB(VORON) - #include "ramps/pins_VORON.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_VORON.h" // ATmega2560 env:mega2560 #elif MB(TRONXY_V3_1_0) - #include "ramps/pins_TRONXY_V3_1_0.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_TRONXY_V3_1_0.h" // ATmega2560 env:mega2560 #elif MB(Z_BOLT_X_SERIES) - #include "ramps/pins_Z_BOLT_X_SERIES.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_Z_BOLT_X_SERIES.h" // ATmega2560 env:mega2560 #elif MB(TT_OSCAR) - #include "ramps/pins_TT_OSCAR.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_TT_OSCAR.h" // ATmega2560 env:mega2560 #elif MB(TANGO) - #include "ramps/pins_TANGO.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_TANGO.h" // ATmega2560 env:mega2560 #elif MB(MKS_GEN_L_V2) - #include "ramps/pins_MKS_GEN_L_V2.h" // ATmega2560 env:megaatmega2560 + #include "ramps/pins_MKS_GEN_L_V2.h" // ATmega2560 env:mega2560 +#elif MB(COPYMASTER_3D) + #include "ramps/pins_COPYMASTER_3D.h" // ATmega2560 env:mega2560 +#elif MB(ORTUR_4) + #include "ramps/pins_ORTUR_4.h" // ATmega2560 env:mega2560 +#elif MB(TENLOG_D3_HERO) + #include "ramps/pins_TENLOG_D3_HERO.h" // ATmega2560 env:mega2560 +#elif MB(MKS_GEN_L_V21) + #include "ramps/pins_MKS_GEN_L_V21.h" // ATmega2560 env:mega2560 // // RAMBo and derivatives @@ -209,114 +226,120 @@ // #elif MB(CNCONTROLS_11) - #include "mega/pins_CNCONTROLS_11.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "mega/pins_CNCONTROLS_11.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(CNCONTROLS_12) - #include "mega/pins_CNCONTROLS_12.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "mega/pins_CNCONTROLS_12.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(CNCONTROLS_15) - #include "mega/pins_CNCONTROLS_15.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "mega/pins_CNCONTROLS_15.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(MIGHTYBOARD_REVE) - #include "mega/pins_MIGHTYBOARD_REVE.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "mega/pins_MIGHTYBOARD_REVE.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560ext #elif MB(CHEAPTRONIC) - #include "mega/pins_CHEAPTRONIC.h" // ATmega2560 env:megaatmega2560 + #include "mega/pins_CHEAPTRONIC.h" // ATmega2560 env:mega2560 #elif MB(CHEAPTRONIC_V2) - #include "mega/pins_CHEAPTRONICv2.h" // ATmega2560 env:megaatmega2560 + #include "mega/pins_CHEAPTRONICv2.h" // ATmega2560 env:mega2560 #elif MB(MEGATRONICS) - #include "mega/pins_MEGATRONICS.h" // ATmega2560 env:megaatmega2560 + #include "mega/pins_MEGATRONICS.h" // ATmega2560 env:mega2560 #elif MB(MEGATRONICS_2) - #include "mega/pins_MEGATRONICS_2.h" // ATmega2560 env:megaatmega2560 + #include "mega/pins_MEGATRONICS_2.h" // ATmega2560 env:mega2560 #elif MB(MEGATRONICS_3, MEGATRONICS_31, MEGATRONICS_32) - #include "mega/pins_MEGATRONICS_3.h" // ATmega2560 env:megaatmega2560 + #include "mega/pins_MEGATRONICS_3.h" // ATmega2560 env:mega2560 #elif MB(ELEFU_3) - #include "mega/pins_ELEFU_3.h" // ATmega2560 env:megaatmega2560 + #include "mega/pins_ELEFU_3.h" // ATmega2560 env:mega2560 #elif MB(LEAPFROG) - #include "mega/pins_LEAPFROG.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "mega/pins_LEAPFROG.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(MEGACONTROLLER) - #include "mega/pins_MEGACONTROLLER.h" // ATmega2560 env:megaatmega2560 + #include "mega/pins_MEGACONTROLLER.h" // ATmega2560 env:mega2560 #elif MB(GT2560_REV_A) - #include "mega/pins_GT2560_REV_A.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "mega/pins_GT2560_REV_A.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(GT2560_REV_A_PLUS) - #include "mega/pins_GT2560_REV_A_PLUS.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "mega/pins_GT2560_REV_A_PLUS.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560 #elif MB(GT2560_V3) - #include "mega/pins_GT2560_V3.h" // ATmega2560 env:megaatmega2560 + #include "mega/pins_GT2560_V3.h" // ATmega2560 env:mega2560 #elif MB(GT2560_V3_MC2) - #include "mega/pins_GT2560_V3_MC2.h" // ATmega2560 env:megaatmega2560 + #include "mega/pins_GT2560_V3_MC2.h" // ATmega2560 env:mega2560 #elif MB(GT2560_V3_A20) - #include "mega/pins_GT2560_V3_A20.h" // ATmega2560 env:megaatmega2560 + #include "mega/pins_GT2560_V3_A20.h" // ATmega2560 env:mega2560 #elif MB(EINSTART_S) - #include "mega/pins_EINSTART-S.h" // ATmega1280, ATmega2560 env:megaatmega1280 env:megaatmega2560 + #include "mega/pins_EINSTART-S.h" // ATmega1280, ATmega2560 env:mega1280 env:mega2560ext #elif MB(WANHAO_ONEPLUS) - #include "mega/pins_WANHAO_ONEPLUS.h" // ATmega2560 env:megaatmega2560 + #include "mega/pins_WANHAO_ONEPLUS.h" // ATmega2560 env:mega2560 #elif MB(OVERLORD) - #include "mega/pins_OVERLORD.h" // ATmega2560 env:megaatmega2560 + #include "mega/pins_OVERLORD.h" // ATmega2560 env:mega2560 #elif MB(HJC2560C_REV2) - #include "mega/pins_HJC2560C_REV2.h" // ATmega2560 env:megaatmega2560 + #include "mega/pins_HJC2560C_REV2.h" // ATmega2560 env:mega2560 #elif MB(LEAPFROG_XEED2015) - #include "mega/pins_LEAPFROG_XEED2015.h" // ATmega2560 env:megaatmega2560 + #include "mega/pins_LEAPFROG_XEED2015.h" // ATmega2560 env:mega2560 #elif MB(PICA) - #include "mega/pins_PICA.h" // ATmega2560 env:megaatmega2560 + #include "mega/pins_PICA.h" // ATmega2560 env:mega2560 #elif MB(PICA_REVB) - #include "mega/pins_PICAOLD.h" // ATmega2560 env:megaatmega2560 + #include "mega/pins_PICAOLD.h" // ATmega2560 env:mega2560 +#elif MB(INTAMSYS40) + #include "mega/pins_INTAMSYS40.h" // ATmega2560 env:mega2560 // // ATmega1281, ATmega2561 // #elif MB(MINITRONICS) - #include "mega/pins_MINITRONICS.h" // ATmega1281 env:megaatmega1280 + #include "mega/pins_MINITRONICS.h" // ATmega1281 env:mega1280 #elif MB(SILVER_GATE) - #include "mega/pins_SILVER_GATE.h" // ATmega2561 env:megaatmega2560 + #include "mega/pins_SILVER_GATE.h" // ATmega2561 env:mega2560 // // Sanguinololu and Derivatives - ATmega644P, ATmega1284P // #elif MB(SANGUINOLOLU_11) - #include "sanguino/pins_SANGUINOLOLU_11.h" // ATmega644P, ATmega1284P env:sanguino_atmega644p env:sanguino_atmega1284p + #include "sanguino/pins_SANGUINOLOLU_11.h" // ATmega644P, ATmega1284P env:sanguino644p env:sanguino1284p #elif MB(SANGUINOLOLU_12) - #include "sanguino/pins_SANGUINOLOLU_12.h" // ATmega644P, ATmega1284P env:sanguino_atmega644p env:sanguino_atmega1284p + #include "sanguino/pins_SANGUINOLOLU_12.h" // ATmega644P, ATmega1284P env:sanguino644p env:sanguino1284p #elif MB(MELZI) - #include "sanguino/pins_MELZI.h" // ATmega644P, ATmega1284P env:sanguino_atmega644p env:sanguino_atmega1284p + #include "sanguino/pins_MELZI.h" // ATmega644P, ATmega1284P env:sanguino644p env:sanguino1284p +#elif MB(MELZI_V2) + #include "sanguino/pins_MELZI_V2.h" // ATmega644P, ATmega1284P env:sanguino644p env:sanguino1284p #elif MB(MELZI_MAKR3D) - #include "sanguino/pins_MELZI_MAKR3D.h" // ATmega644P, ATmega1284P env:sanguino_atmega644p env:sanguino_atmega1284p + #include "sanguino/pins_MELZI_MAKR3D.h" // ATmega644P, ATmega1284P env:sanguino644p env:sanguino1284p #elif MB(MELZI_CREALITY) - #include "sanguino/pins_MELZI_CREALITY.h" // ATmega644P, ATmega1284P env:sanguino_atmega644p env:sanguino_atmega1284p + #include "sanguino/pins_MELZI_CREALITY.h" // ATmega1284P env:melzi env:melzi_optimized env:melzi_optiboot #elif MB(MELZI_MALYAN) - #include "sanguino/pins_MELZI_MALYAN.h" // ATmega644P, ATmega1284P env:sanguino_atmega644p env:sanguino_atmega1284p + #include "sanguino/pins_MELZI_MALYAN.h" // ATmega644P, ATmega1284P env:sanguino644p env:sanguino1284p #elif MB(MELZI_TRONXY) - #include "sanguino/pins_MELZI_TRONXY.h" // ATmega644P, ATmega1284P env:sanguino_atmega644p env:sanguino_atmega1284p + #include "sanguino/pins_MELZI_TRONXY.h" // ATmega644P, ATmega1284P env:sanguino644p env:sanguino1284p #elif MB(STB_11) - #include "sanguino/pins_STB_11.h" // ATmega644P, ATmega1284P env:sanguino_atmega644p env:sanguino_atmega1284p + #include "sanguino/pins_STB_11.h" // ATmega644P, ATmega1284P env:sanguino644p env:sanguino1284p #elif MB(AZTEEG_X1) - #include "sanguino/pins_AZTEEG_X1.h" // ATmega644P, ATmega1284P env:sanguino_atmega644p env:sanguino_atmega1284p + #include "sanguino/pins_AZTEEG_X1.h" // ATmega644P, ATmega1284P env:sanguino644p env:sanguino1284p +#elif MB(ZMIB_V2) + #include "sanguino/pins_ZMIB_V2.h" // ATmega644P, ATmega1284P env:sanguino_atmega644p env:sanguino_atmega1284p // // Other ATmega644P, ATmega644, ATmega1284P // #elif MB(GEN3_MONOLITHIC) - #include "sanguino/pins_GEN3_MONOLITHIC.h" // ATmega644P env:sanguino_atmega644p + #include "sanguino/pins_GEN3_MONOLITHIC.h" // ATmega644P env:sanguino644p #elif MB(GEN3_PLUS) - #include "sanguino/pins_GEN3_PLUS.h" // ATmega644P, ATmega1284P env:sanguino_atmega644p env:sanguino_atmega1284p + #include "sanguino/pins_GEN3_PLUS.h" // ATmega644P, ATmega1284P env:sanguino644p env:sanguino1284p #elif MB(GEN6) - #include "sanguino/pins_GEN6.h" // ATmega644P, ATmega1284P env:sanguino_atmega644p env:sanguino_atmega1284p + #include "sanguino/pins_GEN6.h" // ATmega644P, ATmega1284P env:sanguino644p env:sanguino1284p #elif MB(GEN6_DELUXE) - #include "sanguino/pins_GEN6_DELUXE.h" // ATmega644P, ATmega1284P env:sanguino_atmega644p env:sanguino_atmega1284p + #include "sanguino/pins_GEN6_DELUXE.h" // ATmega644P, ATmega1284P env:sanguino644p env:sanguino1284p #elif MB(GEN7_CUSTOM) - #include "sanguino/pins_GEN7_CUSTOM.h" // ATmega644P, ATmega644, ATmega1284P env:sanguino_atmega644p env:sanguino_atmega1284p + #include "sanguino/pins_GEN7_CUSTOM.h" // ATmega644P, ATmega644, ATmega1284P env:sanguino644p env:sanguino1284p #elif MB(GEN7_12) - #include "sanguino/pins_GEN7_12.h" // ATmega644P, ATmega644, ATmega1284P env:sanguino_atmega644p env:sanguino_atmega1284p + #include "sanguino/pins_GEN7_12.h" // ATmega644P, ATmega644, ATmega1284P env:sanguino644p env:sanguino1284p #elif MB(GEN7_13) - #include "sanguino/pins_GEN7_13.h" // ATmega644P, ATmega644, ATmega1284P env:sanguino_atmega644p env:sanguino_atmega1284p + #include "sanguino/pins_GEN7_13.h" // ATmega644P, ATmega644, ATmega1284P env:sanguino644p env:sanguino1284p #elif MB(GEN7_14) - #include "sanguino/pins_GEN7_14.h" // ATmega644P, ATmega644, ATmega1284P env:sanguino_atmega644p env:sanguino_atmega1284p + #include "sanguino/pins_GEN7_14.h" // ATmega644P, ATmega644, ATmega1284P env:sanguino644p env:sanguino1284p #elif MB(OMCA_A) - #include "sanguino/pins_OMCA_A.h" // ATmega644 env:sanguino_atmega644p + #include "sanguino/pins_OMCA_A.h" // ATmega644 env:sanguino644p #elif MB(OMCA) - #include "sanguino/pins_OMCA.h" // ATmega644P, ATmega644 env:sanguino_atmega644p + #include "sanguino/pins_OMCA.h" // ATmega644P, ATmega644 env:sanguino644p #elif MB(ANET_10) - #include "sanguino/pins_ANET_10.h" // ATmega1284P env:sanguino_atmega1284p + #include "sanguino/pins_ANET_10.h" // ATmega1284P env:sanguino1284p #elif MB(SETHI) - #include "sanguino/pins_SETHI.h" // ATmega644P, ATmega644, ATmega1284P env:sanguino_atmega644p env:sanguino_atmega1284p + #include "sanguino/pins_SETHI.h" // ATmega644P, ATmega644, ATmega1284P env:sanguino644p env:sanguino1284p // // Teensyduino - AT90USB1286, AT90USB1286P @@ -396,6 +419,10 @@ #include "lpc1769/pins_TH3D_EZBOARD.h" // LPC1769 env:LPC1769 #elif MB(BTT_SKR_V1_4_TURBO) #include "lpc1769/pins_BTT_SKR_V1_4_TURBO.h" // LPC1769 env:LPC1769 +#elif MB(MKS_SGEN_L_V2) + #include "lpc1769/pins_MKS_SGEN_L_V2.h" // LPC1769 env:LPC1769 +#elif MB(BTT_SKR_E3_TURBO) + #include "lpc1769/pins_BTT_SKR_E3_TURBO.h" // LPC1769 env:LPC1769 // // Due (ATSAM) boards @@ -450,7 +477,7 @@ #elif MB(ARCHIM1) #include "sam/pins_ARCHIM1.h" // SAM3X8E env:DUE env:DUE_debug #elif MB(ARCHIM2) - #include "sam/pins_ARCHIM2.h" // SAM3X8E env:DUE env:DUE_debug + #include "sam/pins_ARCHIM2.h" // SAM3X8E env:DUE_archim env:DUE_archim_debug #elif MB(ALLIGATOR) #include "sam/pins_ALLIGATOR_R2.h" // SAM3X8E env:DUE env:DUE_debug #elif MB(ADSK) @@ -460,58 +487,90 @@ #elif MB(CNCONTROLS_15D) #include "sam/pins_CNCONTROLS_15D.h" // SAM3X8E env:DUE env:DUE_USB +// +// STM32 ARM Cortex-M0 +// +#elif MB(MALYAN_M200_V2) + #include "stm32f0/pins_MALYAN_M200_V2.h" // STM32F0 env:STM32F070RB_malyan env:STM32F070CB_malyan +#elif MB(MALYAN_M300) + #include "stm32f0/pins_MALYAN_M300.h" // STM32F070 env:malyan_M300 + // // STM32 ARM Cortex-M3 // #elif MB(STM32F103RE) - #include "stm32/pins_STM32F1R.h" // STM32F1 env:STM32F103RE + #include "stm32f1/pins_STM32F1R.h" // STM32F1 env:STM32F103RE #elif MB(MALYAN_M200) - #include "stm32/pins_MALYAN_M200.h" // STM32F1 env:STM32F103CB_malyan + #include "stm32f1/pins_MALYAN_M200.h" // STM32F1 env:STM32F103CB_malyan #elif MB(STM3R_MINI) - #include "stm32/pins_STM3R_MINI.h" // STM32F1 env:STM32F103RE + #include "stm32f1/pins_STM3R_MINI.h" // STM32F1 env:STM32F103RE #elif MB(GTM32_PRO_VB) - #include "stm32/pins_GTM32_PRO_VB.h" // STM32F1 env:STM32F103RE -#elif MB(GTM32_MINI_A30) - #include "stm32/pins_GTM32_MINI_A30.h" // STM32F1 env:STM32F103RE + #include "stm32f1/pins_GTM32_PRO_VB.h" // STM32F1 env:STM32F103RE #elif MB(GTM32_MINI) - #include "stm32/pins_GTM32_MINI.h" // STM32F1 env:STM32F103RE + #include "stm32f1/pins_GTM32_MINI.h" // STM32F1 env:STM32F103RE +#elif MB(GTM32_MINI_A30) + #include "stm32f1/pins_GTM32_MINI_A30.h" // STM32F1 env:STM32F103RE #elif MB(GTM32_REV_B) - #include "stm32/pins_GTM32_REV_B.h" // STM32F1 env:STM32F103RE + #include "stm32f1/pins_GTM32_REV_B.h" // STM32F1 env:STM32F103RE #elif MB(MORPHEUS) - #include "stm32/pins_MORPHEUS.h" // STM32F1 env:STM32F103RE + #include "stm32f1/pins_MORPHEUS.h" // STM32F1 env:STM32F103RE #elif MB(CHITU3D) - #include "stm32/pins_CHITU3D.h" // STM32F1 env:STM32F103RE + #include "stm32f1/pins_CHITU3D.h" // STM32F1 env:STM32F103RE #elif MB(MKS_ROBIN) - #include "stm32/pins_MKS_ROBIN.h" // STM32F1 env:mks_robin + #include "stm32f1/pins_MKS_ROBIN.h" // STM32F1 env:mks_robin env:mks_robin_stm32 #elif MB(MKS_ROBIN_MINI) - #include "stm32/pins_MKS_ROBIN_MINI.h" // STM32F1 env:mks_robin_mini + #include "stm32f1/pins_MKS_ROBIN_MINI.h" // STM32F1 env:mks_robin_mini #elif MB(MKS_ROBIN_NANO) - #include "stm32/pins_MKS_ROBIN_NANO.h" // STM32F1 env:mks_robin_nano + #include "stm32f1/pins_MKS_ROBIN_NANO.h" // STM32F1 env:mks_robin_nano35 +#elif MB(MKS_ROBIN_NANO_V2) + #include "stm32f1/pins_MKS_ROBIN_NANO_V2.h" // STM32F1 env:mks_robin_nano35 #elif MB(MKS_ROBIN_LITE) - #include "stm32/pins_MKS_ROBIN_LITE.h" // STM32F1 env:mks_robin_lite + #include "stm32f1/pins_MKS_ROBIN_LITE.h" // STM32F1 env:mks_robin_lite +#elif MB(MKS_ROBIN_LITE3) + #include "stm32f1/pins_MKS_ROBIN_LITE3.h" // STM32F1 env:mks_robin_lite3 +#elif MB(MKS_ROBIN_PRO) + #include "stm32f1/pins_MKS_ROBIN_PRO.h" // STM32F1 env:mks_robin_pro +#elif MB(MKS_ROBIN_E3) + #include "stm32f1/pins_MKS_ROBIN_E3.h" // STM32F1 env:mks_robin_e3 +#elif MB(MKS_ROBIN_E3D) + #include "stm32f1/pins_MKS_ROBIN_E3D.h" // STM32F1 env:mks_robin_e3 +#elif MB(MKS_ROBIN_E3P) + #include "stm32f1/pins_MKS_ROBIN_E3P.h" // STM32F1 env:mks_robin_e3p #elif MB(BTT_SKR_MINI_V1_1) - #include "stm32/pins_BTT_SKR_MINI_V1_1.h" // STM32F1 env:STM32F103RC_bigtree env:STM32F103RC_bigtree_512K env:STM32F103RC_bigtree_USB env:STM32F103RC_bigtree_512K_USB + #include "stm32f1/pins_BTT_SKR_MINI_V1_1.h" // STM32F1 env:STM32F103RC_btt env:STM32F103RC_btt_512K env:STM32F103RC_btt_USB env:STM32F103RC_btt_512K_USB #elif MB(BTT_SKR_MINI_E3_V1_0) - #include "stm32/pins_BTT_SKR_MINI_E3_V1_0.h" // STM32F1 env:STM32F103RC_bigtree env:STM32F103RC_bigtree_512K env:STM32F103RC_bigtree_USB env:STM32F103RC_bigtree_512K_USB + #include "stm32f1/pins_BTT_SKR_MINI_E3_V1_0.h" // STM32F1 env:STM32F103RC_btt env:STM32F103RC_btt_512K env:STM32F103RC_btt_USB env:STM32F103RC_btt_512K_USB #elif MB(BTT_SKR_MINI_E3_V1_2) - #include "stm32/pins_BTT_SKR_MINI_E3_V1_2.h" // STM32F1 env:STM32F103RC_bigtree env:STM32F103RC_bigtree_512K env:STM32F103RC_bigtree_USB env:STM32F103RC_bigtree_512K_USB + #include "stm32f1/pins_BTT_SKR_MINI_E3_V1_2.h" // STM32F1 env:STM32F103RC_btt env:STM32F103RC_btt_512K env:STM32F103RC_btt_USB env:STM32F103RC_btt_512K_USB +#elif MB(BTT_SKR_MINI_E3_V2_0) + #include "stm32f1/pins_BTT_SKR_MINI_E3_V2_0.h" // STM32F1 env:STM32F103RC_btt env:STM32F103RC_btt_512K env:STM32F103RC_btt_USB env:STM32F103RC_btt_512K_USB #elif MB(BTT_SKR_E3_DIP) - #include "stm32/pins_BTT_SKR_E3_DIP.h" // STM32F1 env:STM32F103RE_bigtree env:STM32F103RE_bigtree_USB env:STM32F103RC_bigtree env:STM32F103RC_bigtree_512K env:STM32F103RC_bigtree_USB env:STM32F103RC_bigtree_512K_USB + #include "stm32f1/pins_BTT_SKR_E3_DIP.h" // STM32F1 env:STM32F103RE_btt env:STM32F103RE_btt_USB env:STM32F103RC_btt env:STM32F103RC_btt_512K env:STM32F103RC_btt_USB env:STM32F103RC_btt_512K_USB #elif MB(JGAURORA_A5S_A1) - #include "stm32/pins_JGAURORA_A5S_A1.h" // STM32F1 env:jgaurora_a5s_a1 + #include "stm32f1/pins_JGAURORA_A5S_A1.h" // STM32F1 env:jgaurora_a5s_a1 #elif MB(FYSETC_AIO_II) - #include "stm32/pins_FYSETC_AIO_II.h" // STM32F1 env:STM32F103RC_fysetc + #include "stm32f1/pins_FYSETC_AIO_II.h" // STM32F1 env:STM32F103RC_fysetc #elif MB(FYSETC_CHEETAH) - #include "stm32/pins_FYSETC_CHEETAH.h" // STM32F1 env:STM32F103RC_fysetc + #include "stm32f1/pins_FYSETC_CHEETAH.h" // STM32F1 env:STM32F103RC_fysetc #elif MB(FYSETC_CHEETAH_V12) - #include "stm32/pins_FYSETC_CHEETAH_V12.h" // STM32F1 env:STM32F103RC_fysetc + #include "stm32f1/pins_FYSETC_CHEETAH_V12.h" // STM32F1 env:STM32F103RC_fysetc #elif MB(LONGER3D_LK) - #include "stm32/pins_LONGER3D_LK.h" // STM32F1 env:STM32F103VE_longer -#elif MB(MKS_ROBIN_LITE3) - #include "stm32/pins_MKS_ROBIN_LITE3.h" // STM32F1 env:mks_robin_lite3 -#elif MB(MKS_ROBIN_PRO) - #include "stm32/pins_MKS_ROBIN_PRO.h" // STM32F1 env:mks_robin_pro + #include "stm32f1/pins_LONGER3D_LK.h" // STM32F1 env:STM32F103VE_longer +#elif MB(CCROBOT_MEEB_3DP) + #include "stm32f1/pins_CCROBOT_MEEB_3DP.h" // STM32F1 env:STM32F103RC_meeb +#elif MB(CHITU3D_V5) + #include "stm32f1/pins_CHITU3D_V5.h" // STM32F1 env:chitu_f103 env:chitu_v5_gpio_init +#elif MB(CHITU3D_V6) + #include "stm32f1/pins_CHITU3D_V6.h" // STM32F1 env:chitu_f103 +#elif MB(CREALITY_V4) + #include "stm32f1/pins_CREALITY_V4.h" // STM32F1 env:STM32F103RET6_creality +#elif MB(CREALITY_V427) + #include "stm32f1/pins_CREALITY_V427.h" // STM32F1 env:STM32F103RET6_creality +#elif MB(TRIGORILLA_PRO) + #include "stm32f1/pins_TRIGORILLA_PRO.h" // STM32F1 env:trigorilla_pro +#elif MB(FLY_MINI) + #include "stm32f1/pins_FLY_MINI.h" // STM32F1 env:FLY_MINI // // ARM Cortex-M4F @@ -527,53 +586,66 @@ // #elif MB(BEAST) - #include "stm32/pins_BEAST.h" // STM32F4 env:STM32F4 + #include "stm32f4/pins_BEAST.h" // STM32F4 env:STM32F4 #elif MB(GENERIC_STM32F4) - #include "stm32/pins_GENERIC_STM32F4.h" // STM32F4 env:STM32F4 + #include "stm32f4/pins_GENERIC_STM32F4.h" // STM32F4 env:STM32F4 #elif MB(ARMED) - #include "stm32/pins_ARMED.h" // STM32F4 env:ARMED -#elif MB(RUMBA32_AUS3D) - #include "stm32/pins_RUMBA32_AUS3D.h" // STM32F4 env:rumba32_f446ve + #include "stm32f4/pins_ARMED.h" // STM32F4 env:ARMED +#elif MB(RUMBA32_V1_0) + #include "stm32f4/pins_RUMBA32_AUS3D.h" // STM32F4 env:rumba32 +#elif MB(RUMBA32_V1_1) + #include "stm32f4/pins_RUMBA32_AUS3D.h" // STM32F4 env:rumba32 #elif MB(RUMBA32_MKS) - #include "stm32/pins_RUMBA32_MKS.h" // STM32F4 env:rumba32_mks + #include "stm32f4/pins_RUMBA32_MKS.h" // STM32F4 env:rumba32 #elif MB(BLACK_STM32F407VE) - #include "stm32/pins_BLACK_STM32F407VE.h" // STM32F4 env:STM32F407VE_black + #include "stm32f4/pins_BLACK_STM32F407VE.h" // STM32F4 env:STM32F407VE_black #elif MB(STEVAL_3DP001V1) - #include "stm32/pins_STEVAL_3DP001V1.h" // STM32F4 env:STM32F401VE_STEVAL + #include "stm32f4/pins_STEVAL_3DP001V1.h" // STM32F4 env:STM32F401VE_STEVAL #elif MB(BTT_SKR_PRO_V1_1) - #include "stm32/pins_BTT_SKR_PRO_V1_1.h" // STM32F4 env:BIGTREE_SKR_PRO + #include "stm32f4/pins_BTT_SKR_PRO_V1_1.h" // STM32F4 env:BIGTREE_SKR_PRO +#elif MB(BTT_SKR_PRO_V1_2) + #include "stm32f4/pins_BTT_SKR_PRO_V1_2.h" // STM32F4 env:BIGTREE_SKR_PRO #elif MB(BTT_GTR_V1_0) - #include "stm32/pins_BTT_GTR_V1_0.h" // STM32F4 env:BIGTREE_GTR_V1_0 + #include "stm32f4/pins_BTT_GTR_V1_0.h" // STM32F4 env:BIGTREE_GTR_V1_0 #elif MB(BTT_BTT002_V1_0) - #include "stm32/pins_BTT_BTT002_V1_0.h" // STM32F4 env:BIGTREE_BTT002 + #include "stm32f4/pins_BTT_BTT002_V1_0.h" // STM32F4 env:BIGTREE_BTT002 #elif MB(LERDGE_K) - #include "stm32/pins_LERDGE_K.h" // STM32F4 env:STM32F4 + #include "stm32f4/pins_LERDGE_K.h" // STM32F4 env:STM32F4 +#elif MB(LERDGE_S) + #include "stm32f4/pins_LERDGE_S.h" // STM32F4 env:LERDGE_S #elif MB(LERDGE_X) - #include "stm32/pins_LERDGE_X.h" // STM32F4 env:STM32F4 + #include "stm32f4/pins_LERDGE_X.h" // STM32F4 env:LERDGE_X #elif MB(VAKE403D) - #include "stm32/pins_VAKE403D.h" // STM32F4 env:STM32F4 + #include "stm32f4/pins_VAKE403D.h" // STM32F4 env:STM32F4 #elif MB(FYSETC_S6) - #include "stm32/pins_FYSETC_S6.h" // STM32F4 env:FYSETC_S6 + #include "stm32f4/pins_FYSETC_S6.h" // STM32F4 env:FYSETC_S6 #elif MB(FLYF407ZG) - #include "stm32/pins_FLYF407ZG.h" // STM32F4 env:FLYF407ZG + #include "stm32f4/pins_FLYF407ZG.h" // STM32F4 env:FLYF407ZG #elif MB(MKS_ROBIN2) - #include "pins_MKS_ROBIN2.h" // STM32F4 env:MKS_ROBIN2 + #include "stm32f4/pins_MKS_ROBIN2.h" // STM32F4 env:MKS_ROBIN2 +#elif MB(FYSETC_S6_V2_0) + #include "stm32f4/pins_FYSETC_S6_V2_0.h" // STM32F4 env:FYSETC_S6 // // ARM Cortex M7 // #elif MB(THE_BORG) - #include "stm32/pins_THE_BORG.h" // STM32F7 env:STM32F7 + #include "stm32f7/pins_THE_BORG.h" // STM32F7 env:STM32F7 #elif MB(REMRAM_V1) - #include "stm32/pins_REMRAM_V1.h" // STM32F7 env:STM32F7 + #include "stm32f7/pins_REMRAM_V1.h" // STM32F7 env:STM32F7 +#elif MB(NUCLEO_F767ZI) + #include "stm32f7/pins_NUCLEO_F767ZI.h" // STM32F7 env:NUCLEO_F767ZI +#elif MB(TEENSY41) + #include "teensy4/pins_TEENSY41.h" // Teensy-4.x env:teensy41 +#elif MB(T41U5XBB) + #include "teensy4/pins_T41U5XBB.h" // Teensy-4.x env:teensy41 // // Espressif ESP32 // #elif MB(ESPRESSIF_ESP32) - #include "esp32/pins_ESP32.h" // ESP32 env:esp32 #elif MB(MRR_ESPA) #include "esp32/pins_MRR_ESPA.h" // ESP32 env:esp32 @@ -589,6 +661,12 @@ #elif MB(AGCM4_RAMPS_144) #include "samd/pins_RAMPS_144.h" // SAMD51 env:SAMD51_grandcentral_m4 +// +// Custom board (with custom PIO env) +// +#elif MB(CUSTOM) + #include "pins_custom.h" // env:custom + // // Linux Native Debug board // @@ -621,6 +699,7 @@ #define BOARD_BIGTREE_SKR_MINI_E3 -1016 #define BOARD_BIGTREE_SKR_E3_DIP -1017 #define BOARD_RUMBA32 -1018 + #define BOARD_RUMBA32_AUS3D -1019 #if MB(MKS_13) #error "BOARD_MKS_13 has been renamed BOARD_MKS_GEN_13. Please update your configuration." @@ -661,7 +740,9 @@ #elif MB(STEVAL) #error "BOARD_STEVAL has been renamed BOARD_STEVAL_3DP001V1. Please update your configuration." #elif MB(RUMBA32) - #error "BOARD_RUMBA32 is now BOARD_RUMBA32_MKS or BOARD_RUMBA32_AUS3D. Please update your configuration." + #error "BOARD_RUMBA32 is now BOARD_RUMBA32_MKS or BOARD_RUMBA32_V1_0. Please update your configuration." + #elif MB(RUMBA32_AUS3D) + #error "BOARD_RUMBA32_AUS3D is now BOARD_RUMBA32_V1_0. Please update your configuration." #else #error "Unknown MOTHERBOARD value set in Configuration.h" #endif @@ -685,6 +766,7 @@ #undef BOARD_BIGTREE_SKR_MINI_V1_1 #undef BOARD_BIGTREE_SKR_E3_DIP #undef BOARD_RUMBA32 + #undef BOARD_RUMBA32_AUS3D #endif @@ -862,6 +944,43 @@ #define E7_ENABLE_PIN -1 #endif +// +// Destroy unused CS pins +// +#if !AXIS_HAS_SPI(X) + #undef X_CS_PIN +#endif +#if !AXIS_HAS_SPI(Y) + #undef Y_CS_PIN +#endif +#if !AXIS_HAS_SPI(Z) + #undef Z_CS_PIN +#endif +#if E_STEPPERS && !AXIS_HAS_SPI(E0) + #undef E0_CS_PIN +#endif +#if E_STEPPERS > 1 && !AXIS_HAS_SPI(E1) + #undef E1_CS_PIN +#endif +#if E_STEPPERS > 2 && !AXIS_HAS_SPI(E2) + #undef E2_CS_PIN +#endif +#if E_STEPPERS > 3 && !AXIS_HAS_SPI(E3) + #undef E3_CS_PIN +#endif +#if E_STEPPERS > 4 && !AXIS_HAS_SPI(E4) + #undef E4_CS_PIN +#endif +#if E_STEPPERS > 5 && !AXIS_HAS_SPI(E5) + #undef E5_CS_PIN +#endif +#if E_STEPPERS > 6 && !AXIS_HAS_SPI(E6) + #undef E6_CS_PIN +#endif +#if E_STEPPERS > 7 && !AXIS_HAS_SPI(E7) + #undef E7_CS_PIN +#endif + #ifndef X_CS_PIN #define X_CS_PIN -1 #endif @@ -1006,73 +1125,6 @@ #define NUM_SERVO_PLUGS 4 #endif -// -// Assign auto fan pins if needed -// -#ifndef E0_AUTO_FAN_PIN - #ifdef ORIG_E0_AUTO_FAN_PIN - #define E0_AUTO_FAN_PIN ORIG_E0_AUTO_FAN_PIN - #else - #define E0_AUTO_FAN_PIN -1 - #endif -#endif -#ifndef E1_AUTO_FAN_PIN - #ifdef ORIG_E1_AUTO_FAN_PIN - #define E1_AUTO_FAN_PIN ORIG_E1_AUTO_FAN_PIN - #else - #define E1_AUTO_FAN_PIN -1 - #endif -#endif -#ifndef E2_AUTO_FAN_PIN - #ifdef ORIG_E2_AUTO_FAN_PIN - #define E2_AUTO_FAN_PIN ORIG_E2_AUTO_FAN_PIN - #else - #define E2_AUTO_FAN_PIN -1 - #endif -#endif -#ifndef E3_AUTO_FAN_PIN - #ifdef ORIG_E3_AUTO_FAN_PIN - #define E3_AUTO_FAN_PIN ORIG_E3_AUTO_FAN_PIN - #else - #define E3_AUTO_FAN_PIN -1 - #endif -#endif -#ifndef E4_AUTO_FAN_PIN - #ifdef ORIG_E4_AUTO_FAN_PIN - #define E4_AUTO_FAN_PIN ORIG_E4_AUTO_FAN_PIN - #else - #define E4_AUTO_FAN_PIN -1 - #endif -#endif -#ifndef E5_AUTO_FAN_PIN - #ifdef ORIG_E5_AUTO_FAN_PIN - #define E5_AUTO_FAN_PIN ORIG_E5_AUTO_FAN_PIN - #else - #define E5_AUTO_FAN_PIN -1 - #endif -#endif -#ifndef E6_AUTO_FAN_PIN - #ifdef ORIG_E6_AUTO_FAN_PIN - #define E6_AUTO_FAN_PIN ORIG_E6_AUTO_FAN_PIN - #else - #define E6_AUTO_FAN_PIN -1 - #endif -#endif -#ifndef E7_AUTO_FAN_PIN - #ifdef ORIG_E7_AUTO_FAN_PIN - #define E7_AUTO_FAN_PIN ORIG_E7_AUTO_FAN_PIN - #else - #define E7_AUTO_FAN_PIN -1 - #endif -#endif -#ifndef CHAMBER_AUTO_FAN_PIN - #ifdef ORIG_CHAMBER_AUTO_FAN_PIN - #define CHAMBER_AUTO_FAN_PIN ORIG_CHAMBER_AUTO_FAN_PIN - #else - #define CHAMBER_AUTO_FAN_PIN -1 - #endif -#endif - // // Assign endstop pins for boards with only 3 connectors // @@ -1170,13 +1222,16 @@ #if HAS_FILAMENT_SENSOR #define FIL_RUNOUT1_PIN FIL_RUNOUT_PIN +#else + #undef FIL_RUNOUT_PIN + #undef FIL_RUNOUT1_PIN #endif #ifndef LCD_PINS_D4 #define LCD_PINS_D4 -1 #endif -#if HAS_CHARACTER_LCD || TOUCH_UI_ULTIPANEL +#if HAS_MARLINUI_HD44780 || TOUCH_UI_ULTIPANEL #ifndef LCD_PINS_D5 #define LCD_PINS_D5 -1 #endif @@ -1238,7 +1293,7 @@ // // Auto-assign pins for stallGuard sensorless homing // - #if X2_STALL_SENSITIVITY && ENABLED(X_DUAL_ENDSTOPS) && _PEXI(X2_E_INDEX, DIAG) + #if defined(X2_STALL_SENSITIVITY) && ENABLED(X_DUAL_ENDSTOPS) && _PEXI(X2_E_INDEX, DIAG) #define X2_DIAG_PIN _EPIN(X2_E_INDEX, DIAG) #if DIAG_REMAPPED(X2, X_MIN) // If already remapped in the pins file... #define X2_USE_ENDSTOP _XMIN_ @@ -1307,7 +1362,7 @@ #define Y2_SERIAL_RX_PIN _EPIN(Y2_E_INDEX, SERIAL_RX) #endif #endif - #if Y2_STALL_SENSITIVITY && ENABLED(Y_DUAL_ENDSTOPS) && _PEXI(Y2_E_INDEX, DIAG) + #if defined(Y2_STALL_SENSITIVITY) && ENABLED(Y_DUAL_ENDSTOPS) && _PEXI(Y2_E_INDEX, DIAG) #define Y2_DIAG_PIN _EPIN(Y2_E_INDEX, DIAG) #if DIAG_REMAPPED(Y2, X_MIN) #define Y2_USE_ENDSTOP _XMIN_ @@ -1375,7 +1430,7 @@ #define Z2_SERIAL_RX_PIN _EPIN(Z2_E_INDEX, SERIAL_RX) #endif #endif - #if Z2_STALL_SENSITIVITY && ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPER_DRIVERS >= 2 && _PEXI(Z2_E_INDEX, DIAG) + #if defined(Z2_STALL_SENSITIVITY) && ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPER_DRIVERS >= 2 && _PEXI(Z2_E_INDEX, DIAG) #define Z2_DIAG_PIN _EPIN(Z2_E_INDEX, DIAG) #if DIAG_REMAPPED(Z2, X_MIN) #define Z2_USE_ENDSTOP _XMIN_ @@ -1444,7 +1499,7 @@ #define Z3_SERIAL_RX_PIN _EPIN(Z3_E_INDEX, SERIAL_RX) #endif #endif - #if Z3_STALL_SENSITIVITY && ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPER_DRIVERS >= 3 && _PEXI(Z3_E_INDEX, DIAG) + #if defined(Z3_STALL_SENSITIVITY) && ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPER_DRIVERS >= 3 && _PEXI(Z3_E_INDEX, DIAG) #define Z3_DIAG_PIN _EPIN(Z3_E_INDEX, DIAG) #if DIAG_REMAPPED(Z3, X_MIN) #define Z3_USE_ENDSTOP _XMIN_ @@ -1511,7 +1566,7 @@ #define Z4_SERIAL_RX_PIN _EPIN(Z4_E_INDEX, SERIAL_RX) #endif #endif - #if Z4_STALL_SENSITIVITY && ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPER_DRIVERS >= 4 && _PEXI(Z4_E_INDEX, DIAG) + #if defined(Z4_STALL_SENSITIVITY) && ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPER_DRIVERS >= 4 && _PEXI(Z4_E_INDEX, DIAG) #define Z4_DIAG_PIN _EPIN(Z4_E_INDEX, DIAG) #if DIAG_REMAPPED(Z4, X_MIN) #define Z4_USE_ENDSTOP _XMIN_ @@ -1546,7 +1601,7 @@ #define Z4_MS3_PIN -1 #endif -#if HAS_GRAPHICAL_LCD +#if HAS_MARLINUI_U8GLIB #if !defined(ST7920_DELAY_1) && defined(BOARD_ST7920_DELAY_1) #define ST7920_DELAY_1 BOARD_ST7920_DELAY_1 #endif diff --git a/Marlin/src/pins/pinsDebug.h b/Marlin/src/pins/pinsDebug.h index f247c7cacf7a..5f153cfa2b0f 100644 --- a/Marlin/src/pins/pinsDebug.h +++ b/Marlin/src/pins/pinsDebug.h @@ -13,7 +13,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -31,7 +31,6 @@ * * Both passes use the same pin list. The list contains two macro names. The * actual macro definitions are changed depending on which pass is being done. - * */ // first pass - put the name strings into FLASH @@ -45,7 +44,7 @@ #line 46 // manually add pins that have names that are macros which don't play well with these macros -#if (AVR_ATmega2560_FAMILY || AVR_ATmega1284_FAMILY || defined(ARDUINO_ARCH_SAM) || defined(TARGET_LPC1768)) +#if ANY(AVR_ATmega2560_FAMILY, AVR_ATmega1284_FAMILY, ARDUINO_ARCH_SAM, TARGET_LPC1768) #if SERIAL_PORT == 0 static const char RXD_NAME_0[] PROGMEM = { "RXD0" }; static const char TXD_NAME_0[] PROGMEM = { "TXD0" }; @@ -110,83 +109,119 @@ const PinInfo pin_array[] PROGMEM = { // manually add pins ... #if SERIAL_PORT == 0 - #if (AVR_ATmega2560_FAMILY || defined(ARDUINO_ARCH_SAM)) + #if EITHER(AVR_ATmega2560_FAMILY, ARDUINO_ARCH_SAM) { RXD_NAME_0, 0, true }, { TXD_NAME_0, 1, true }, #elif AVR_ATmega1284_FAMILY { RXD_NAME_0, 8, true }, { TXD_NAME_0, 9, true }, - #elif defined(TARGET_LPC1768) + #elif defined(TARGET_LPC1768) // TX P0_02 RX P0_03 { RXD_NAME_0, 3, true }, { TXD_NAME_0, 2, true }, #endif #elif SERIAL_PORT == 1 - #if (AVR_ATmega2560_FAMILY || defined(ARDUINO_ARCH_SAM)) + #if EITHER(AVR_ATmega2560_FAMILY, ARDUINO_ARCH_SAM) { RXD_NAME_1, 19, true }, { TXD_NAME_1, 18, true }, #elif AVR_ATmega1284_FAMILY { RXD_NAME_1, 10, true }, { TXD_NAME_1, 11, true }, #elif defined(TARGET_LPC1768) - { RXD_NAME_1, 16, true }, - { TXD_NAME_1, 15, true }, + #ifdef LPC_PINCFG_UART1_P2_00 // TX P2_00 RX P2_01 + { RXD_NAME_1, 0x41, true }, + { TXD_NAME_1, 0x40, true }, + #else // TX P0_15 RX P0_16 + { RXD_NAME_1, 16, true }, + { TXD_NAME_1, 15, true }, + #endif #endif #elif SERIAL_PORT == 2 - #if (AVR_ATmega2560_FAMILY || defined(ARDUINO_ARCH_SAM)) + #if EITHER(AVR_ATmega2560_FAMILY, ARDUINO_ARCH_SAM) { RXD_NAME_2, 17, true }, { TXD_NAME_2, 16, true }, #elif defined(TARGET_LPC1768) - { RXD_NAME_2, 11, true }, - { TXD_NAME_2, 10, true }, + #ifdef LPC_PINCFG_UART2_P2_08 // TX P2_08 RX P2_09 + { RXD_NAME_2, 0x49, true }, + { TXD_NAME_2, 0x48, true }, + #else // TX P0_10 RX P0_11 + { RXD_NAME_2, 11, true }, + { TXD_NAME_2, 10, true }, + #endif #endif #elif SERIAL_PORT == 3 - #if (AVR_ATmega2560_FAMILY || defined(ARDUINO_ARCH_SAM)) + #if EITHER(AVR_ATmega2560_FAMILY, ARDUINO_ARCH_SAM) { RXD_NAME_3, 15, true }, { TXD_NAME_3, 14, true }, #elif defined(TARGET_LPC1768) - { RXD_NAME_3, 1, true }, - { TXD_NAME_3, 0, true }, + #ifdef LPC_PINCFG_UART3_P0_25 // TX P0_25 RX P0_26 + { RXD_NAME_3, 0x1A, true }, + { TXD_NAME_3, 0x19, true }, + #elif defined(LPC_PINCFG_UART3_P4_28) // TX P4_28 RX P4_29 + { RXD_NAME_3, 0x9D, true }, + { TXD_NAME_3, 0x9C, true }, + #else // TX P0_00 RX P0_01 + { RXD_NAME_3, 1, true }, + { TXD_NAME_3, 0, true }, + #endif #endif #endif #ifdef SERIAL_PORT_2 #if SERIAL_PORT_2 == 0 - #if (AVR_ATmega2560_FAMILY || defined(ARDUINO_ARCH_SAM)) + #if EITHER(AVR_ATmega2560_FAMILY, ARDUINO_ARCH_SAM) { RXD_NAME_0, 0, true }, { TXD_NAME_0, 1, true }, #elif AVR_ATmega1284_FAMILY { RXD_NAME_0, 8, true }, { TXD_NAME_0, 9, true }, - #elif defined(TARGET_LPC1768) + #elif defined(TARGET_LPC1768) // TX P0_02 RX P0_03 { RXD_NAME_0, 3, true }, { TXD_NAME_0, 2, true }, #endif #elif SERIAL_PORT_2 == 1 - #if (AVR_ATmega2560_FAMILY || defined(ARDUINO_ARCH_SAM)) + #if EITHER(AVR_ATmega2560_FAMILY, ARDUINO_ARCH_SAM) { RXD_NAME_1, 19, true }, { TXD_NAME_1, 18, true }, #elif AVR_ATmega1284_FAMILY { RXD_NAME_1, 10, true }, { TXD_NAME_1, 11, true }, #elif defined(TARGET_LPC1768) - { RXD_NAME_1, 16, true }, - { TXD_NAME_1, 15, true }, + #ifdef LPC_PINCFG_UART1_P2_00 // TX P2_00 RX P2_01 + { RXD_NAME_1, 0x41, true }, + { TXD_NAME_1, 0x40, true }, + #else // TX P0_15 RX P0_16 + { RXD_NAME_1, 16, true }, + { TXD_NAME_1, 15, true }, + #endif #endif #elif SERIAL_PORT_2 == 2 - #if (AVR_ATmega2560_FAMILY || defined(ARDUINO_ARCH_SAM)) + #if EITHER(AVR_ATmega2560_FAMILY, ARDUINO_ARCH_SAM) { RXD_NAME_2, 17, true }, { TXD_NAME_2, 16, true }, #elif defined(TARGET_LPC1768) - { RXD_NAME_2, 11, true }, - { TXD_NAME_2, 10, true }, + #ifdef LPC_PINCFG_UART2_P2_08 // TX P2_08 RX P2_09 + { RXD_NAME_2, 0x49, true }, + { TXD_NAME_2, 0x48, true }, + #else // TX P0_10 RX P0_11 + { RXD_NAME_2, 11, true }, + { TXD_NAME_2, 10, true }, + #endif #endif #elif SERIAL_PORT_2 == 3 - #if (AVR_ATmega2560_FAMILY || defined(ARDUINO_ARCH_SAM)) + #if EITHER(AVR_ATmega2560_FAMILY, ARDUINO_ARCH_SAM) { RXD_NAME_3, 15, true }, { TXD_NAME_3, 14, true }, #elif defined(TARGET_LPC1768) - { RXD_NAME_3, 1, true }, - { TXD_NAME_3, 0, true }, + #ifdef LPC_PINCFG_UART3_P0_25 // TX P0_25 RX P0_26 + { RXD_NAME_3, 0x1A, true }, + { TXD_NAME_3, 0x19, true }, + #elif defined(LPC_PINCFG_UART3_P4_28) // TX P4_28 RX P4_29 + { RXD_NAME_3, 0x9D, true }, + { TXD_NAME_3, 0x9C, true }, + #else // TX P0_00 RX P0_01 + { RXD_NAME_3, 1, true }, + { TXD_NAME_3, 0, true }, + #endif #endif #endif #endif @@ -207,17 +242,32 @@ static void print_input_or_output(const bool isout) { } // pretty report with PWM info -inline void report_pin_state_extended(pin_t pin, bool ignore, bool extended = false, const char *start_string = "") { +inline void report_pin_state_extended(pin_t pin, const bool ignore, const bool extended=false, PGM_P const start_string=nullptr) { char buffer[MAX_NAME_LENGTH + 1]; // for the sprintf statements bool found = false, multi_name_pin = false; - for (uint8_t x = 0; x < COUNT(pin_array); x++) { // scan entire array and report all instances of this pin + auto alt_pin_echo = [](const pin_t &pin) { + #if AVR_AT90USB1286_FAMILY + // Use FastIO for pins Teensy doesn't expose + if (pin == 46) { + print_input_or_output(IS_OUTPUT(46)); + SERIAL_CHAR('0' + READ(46)); + return false; + } + else if (pin == 47) { + print_input_or_output(IS_OUTPUT(47)); + SERIAL_CHAR('0' + READ(47)); + return false; + } + #endif + return true; + }; + + LOOP_L_N(x, COUNT(pin_array)) { // scan entire array and report all instances of this pin if (GET_ARRAY_PIN(x) == pin) { - if (found) multi_name_pin = true; - found = true; - if (!multi_name_pin) { // report digital and analog pin number only on the first time through - sprintf_P(buffer, PSTR("%sPIN: "), start_string); // digital pin number - SERIAL_ECHO(buffer); + if (!found) { // report digital and analog pin number only on the first time through + if (start_string) serialprintPGM(start_string); + serialprintPGM(PSTR("PIN: ")); PRINT_PIN(pin); PRINT_PORT(pin); if (int8_t(DIGITAL_PIN_TO_ANALOG_PIN(pin)) >= 0) { @@ -228,27 +278,14 @@ inline void report_pin_state_extended(pin_t pin, bool ignore, bool extended = fa } else { SERIAL_CHAR('.'); - SERIAL_ECHO_SP(MULTI_NAME_PAD + strlen(start_string)); // add padding if not the first instance found + SERIAL_ECHO_SP(MULTI_NAME_PAD + (start_string ? strlen_P(start_string) : 0)); // add padding if not the first instance found } PRINT_ARRAY_NAME(x); if (extended) { if (pin_is_protected(pin) && !ignore) SERIAL_ECHOPGM("protected "); else { - #if AVR_AT90USB1286_FAMILY //Teensy IDEs don't know about these pins so must use FASTIO - if (pin == 46 || pin == 47) { - if (pin == 46) { - print_input_or_output(IS_OUTPUT(46)); - SERIAL_CHAR('0' + READ(46)); - } - else if (pin == 47) { - print_input_or_output(IS_OUTPUT(47)); - SERIAL_CHAR('0' + READ(47)); - } - } - else - #endif - { + if (alt_pin_echo(pin)) { if (!GET_ARRAY_IS_DIGITAL(x)) { sprintf_P(buffer, PSTR("Analog in = %5ld"), (long)analogRead(DIGITAL_PIN_TO_ANALOG_PIN(pin))); SERIAL_ECHO(buffer); @@ -274,12 +311,14 @@ inline void report_pin_state_extended(pin_t pin, bool ignore, bool extended = fa } } SERIAL_EOL(); + multi_name_pin = found; + found = true; } // end of IF } // end of for loop if (!found) { - sprintf_P(buffer, PSTR("%sPIN: "), start_string); - SERIAL_ECHO(buffer); + if (start_string) serialprintPGM(start_string); + serialprintPGM(PSTR("PIN: ")); PRINT_PIN(pin); PRINT_PORT(pin); if (int8_t(DIGITAL_PIN_TO_ANALOG_PIN(pin)) >= 0) { @@ -290,21 +329,8 @@ inline void report_pin_state_extended(pin_t pin, bool ignore, bool extended = fa SERIAL_ECHO_SP(8); // add padding if not an analog pin SERIAL_ECHOPGM(""); if (extended) { - #if AVR_AT90USB1286_FAMILY //Teensy IDEs don't know about these pins so must use FASTIO - if (pin == 46 || pin == 47) { - SERIAL_ECHO_SP(12); - if (pin == 46) { - print_input_or_output(IS_OUTPUT(46)); - SERIAL_CHAR('0' + READ(46)); - } - else { - print_input_or_output(IS_OUTPUT(47)); - SERIAL_CHAR('0' + READ(47)); - } - } - else - #endif - { + + if (alt_pin_echo(pin)) { if (pwm_status(pin)) { // do nothing } diff --git a/Marlin/src/pins/pinsDebug_list.h b/Marlin/src/pins/pinsDebug_list.h index dae4bde450f0..704f2a487fb1 100644 --- a/Marlin/src/pins/pinsDebug_list.h +++ b/Marlin/src/pins/pinsDebug_list.h @@ -13,7 +13,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -30,7 +30,7 @@ // Analog Pin Assignments // -#define ANALOG_OK(PN) ((PN) >= 0 && (PN) < NUM_ANALOG_PINS) +#define ANALOG_OK(PN) ((PN) >= 0 && (PN) < NUM_ANALOG_INPUTS) #if defined(EXT_AUX_A0) && ANALOG_OK(EXT_AUX_A0) REPORT_NAME_ANALOG(__LINE__, EXT_AUX_A0) @@ -168,6 +168,18 @@ #if defined(BTN_UP) && BTN_UP >= 0 REPORT_NAME_DIGITAL(__LINE__, BTN_UP) #endif +#if PIN_EXISTS(JOY_X) + REPORT_NAME_DIGITAL(__LINE__, JOY_X_PIN) +#endif +#if PIN_EXISTS(JOY_Y) + REPORT_NAME_DIGITAL(__LINE__, JOY_Y_PIN) +#endif +#if PIN_EXISTS(JOY_Z) + REPORT_NAME_DIGITAL(__LINE__, JOY_Z_PIN) +#endif +#if PIN_EXISTS(JOY_EN) + REPORT_NAME_DIGITAL(__LINE__, JOY_EN_PIN) +#endif #if PIN_EXISTS(CASE_LIGHT) REPORT_NAME_DIGITAL(__LINE__, CASE_LIGHT_PIN) #endif @@ -249,6 +261,9 @@ #if defined(TMC_SW_SCK) && TMC_SW_SCK >= 0 REPORT_NAME_DIGITAL(__LINE__, TMC_SW_SCK) #endif +#if defined(TFTGLCD_CS) && TFTGLCD_CS >= 0 + REPORT_NAME_DIGITAL(__LINE__, TFTGLCD_CS) +#endif #if PIN_EXISTS(E_MUX0) REPORT_NAME_DIGITAL(__LINE__, E_MUX0_PIN) #endif @@ -547,6 +562,18 @@ #if PIN_EXISTS(FAN7) REPORT_NAME_DIGITAL(__LINE__, FAN7_PIN) #endif +#if PIN_EXISTS(FAN_MUX0) + REPORT_NAME_DIGITAL(__LINE__, FAN_MUX0_PIN) +#endif +#if PIN_EXISTS(FAN_MUX1) + REPORT_NAME_DIGITAL(__LINE__, FAN_MUX1_PIN) +#endif +#if PIN_EXISTS(FAN_MUX2) + REPORT_NAME_DIGITAL(__LINE__, FAN_MUX2_PIN) +#endif +#if PIN_EXISTS(POWER_LOSS) + REPORT_NAME_DIGITAL(__LINE__, POWER_LOSS_PIN) +#endif #if PIN_EXISTS(FIL_RUNOUT) REPORT_NAME_DIGITAL(__LINE__, FIL_RUNOUT_PIN) #endif @@ -565,6 +592,12 @@ #if PIN_EXISTS(FIL_RUNOUT6) REPORT_NAME_DIGITAL(__LINE__, FIL_RUNOUT6_PIN) #endif +#if PIN_EXISTS(FIL_RUNOUT7) + REPORT_NAME_DIGITAL(__LINE__, FIL_RUNOUT7_PIN) +#endif +#if PIN_EXISTS(FIL_RUNOUT8) + REPORT_NAME_DIGITAL(__LINE__, FIL_RUNOUT8_PIN) +#endif #if PIN_EXISTS(HEATER_0) REPORT_NAME_DIGITAL(__LINE__, HEATER_0_PIN) #endif @@ -592,6 +625,9 @@ #if PIN_EXISTS(HEATER_BED) REPORT_NAME_DIGITAL(__LINE__, HEATER_BED_PIN) #endif +#if PIN_EXISTS(HEATER_CHAMBER) + REPORT_NAME_DIGITAL(__LINE__, HEATER_CHAMBER_PIN) +#endif #if PIN_EXISTS(HOME) REPORT_NAME_DIGITAL(__LINE__, HOME_PIN) #endif @@ -637,9 +673,6 @@ #if PIN_EXISTS(LED_RED) REPORT_NAME_DIGITAL(__LINE__, LED_RED_PIN) #endif -#if PIN_EXISTS(MAX) - REPORT_NAME_DIGITAL(__LINE__, MAX_PIN) -#endif #if PIN_EXISTS(MAX6675_DO) REPORT_NAME_DIGITAL(__LINE__, MAX6675_DO_PIN) #endif @@ -652,6 +685,16 @@ #if PIN_EXISTS(MAX6675_SS2) REPORT_NAME_DIGITAL(__LINE__, MAX6675_SS2_PIN) #endif +#if PIN_EXISTS(MAX7219_CLK) + REPORT_NAME_DIGITAL(__LINE__, MAX7219_CLK_PIN) +#endif +#if PIN_EXISTS(MAX7219_DIN) + REPORT_NAME_DIGITAL(__LINE__, MAX7219_DIN_PIN) +#endif +#if PIN_EXISTS(MAX7219_LOAD) + REPORT_NAME_DIGITAL(__LINE__, MAX7219_LOAD_PIN) +#endif + // #if defined(MISO) && MISO >= 0 // REPORT_NAME_DIGITAL(__LINE__, MISO) // #endif @@ -700,33 +743,12 @@ #if PIN_EXISTS(MOTOR_FAULT) REPORT_NAME_DIGITAL(__LINE__, MOTOR_FAULT_PIN) #endif -#if PIN_EXISTS(ORIG_E0_AUTO_FAN) - REPORT_NAME_DIGITAL(__LINE__, ORIG_E0_AUTO_FAN_PIN) -#endif -#if PIN_EXISTS(ORIG_E1_AUTO_FAN) - REPORT_NAME_DIGITAL(__LINE__, ORIG_E1_AUTO_FAN_PIN) -#endif -#if PIN_EXISTS(ORIG_E2_AUTO_FAN) - REPORT_NAME_DIGITAL(__LINE__, ORIG_E2_AUTO_FAN_PIN) -#endif -#if PIN_EXISTS(ORIG_E3_AUTO_FAN) - REPORT_NAME_DIGITAL(__LINE__, ORIG_E3_AUTO_FAN_PIN) -#endif -#if PIN_EXISTS(ORIG_E4_AUTO_FAN) - REPORT_NAME_DIGITAL(__LINE__, ORIG_E4_AUTO_FAN_PIN) -#endif -#if PIN_EXISTS(ORIG_E5_AUTO_FAN) - REPORT_NAME_DIGITAL(__LINE__, ORIG_E5_AUTO_FAN_PIN) -#endif -#if PIN_EXISTS(ORIG_E6_AUTO_FAN) - REPORT_NAME_DIGITAL(__LINE__, ORIG_E6_AUTO_FAN_PIN) -#endif -#if PIN_EXISTS(ORIG_E7_AUTO_FAN) - REPORT_NAME_DIGITAL(__LINE__, ORIG_E7_AUTO_FAN_PIN) -#endif #if PIN_EXISTS(PHOTOGRAPH) REPORT_NAME_DIGITAL(__LINE__, PHOTOGRAPH_PIN) #endif +#if PIN_EXISTS(CHDK) + REPORT_NAME_DIGITAL(__LINE__, CHDK_PIN) +#endif #if PIN_EXISTS(PS_ON) REPORT_NAME_DIGITAL(__LINE__, PS_ON_PIN) #endif @@ -748,6 +770,12 @@ #if PIN_EXISTS(RAMPS_D9) REPORT_NAME_DIGITAL(__LINE__, RAMPS_D9_PIN) #endif +#if PIN_EXISTS(NEOPIXEL) + REPORT_NAME_DIGITAL(__LINE__, NEOPIXEL_PIN) +#endif +#if PIN_EXISTS(NEOPIXEL2) + REPORT_NAME_DIGITAL(__LINE__, NEOPIXEL2_PIN) +#endif #if PIN_EXISTS(RGB_LED_R) REPORT_NAME_DIGITAL(__LINE__, RGB_LED_R_PIN) #endif @@ -838,6 +866,12 @@ #if PIN_EXISTS(SOL5) REPORT_NAME_DIGITAL(__LINE__, SOL5_PIN) #endif +#if PIN_EXISTS(SOL6) + REPORT_NAME_DIGITAL(__LINE__, SOL6_PIN) +#endif +#if PIN_EXISTS(SOL7) + REPORT_NAME_DIGITAL(__LINE__, SOL7_PIN) +#endif #if defined(SPARE_IO) && SPARE_IO >= 0 REPORT_NAME_DIGITAL(__LINE__, SPARE_IO) #endif @@ -988,6 +1022,9 @@ #if PIN_EXISTS(X_STOP) REPORT_NAME_DIGITAL(__LINE__, X_STOP_PIN) #endif +#if PIN_EXISTS(X2_CS) + REPORT_NAME_DIGITAL(__LINE__, X2_CS_PIN) +#endif #if PIN_EXISTS(X2_DIR) REPORT_NAME_DIGITAL(__LINE__, X2_DIR_PIN) #endif @@ -1048,6 +1085,9 @@ #if PIN_EXISTS(Y_STOP) REPORT_NAME_DIGITAL(__LINE__, Y_STOP_PIN) #endif +#if PIN_EXISTS(Y2_CS) + REPORT_NAME_DIGITAL(__LINE__, Y2_CS_PIN) +#endif #if PIN_EXISTS(Y2_DIR) REPORT_NAME_DIGITAL(__LINE__, Y2_DIR_PIN) #endif @@ -1351,6 +1391,55 @@ #if PIN_EXISTS(TOUCH_INT) REPORT_NAME_DIGITAL(__LINE__, TOUCH_INT_PIN) #endif +#if PIN_EXISTS(USB_CS) + REPORT_NAME_DIGITAL(__LINE__, USB_CS_PIN) +#endif +#if PIN_EXISTS(USB_INTR) + REPORT_NAME_DIGITAL(__LINE__, USB_INTR_PIN) +#endif +#if PIN_EXISTS(MMU2_RST) + REPORT_NAME_DIGITAL(__LINE__, MMU2_RST_PIN) +#endif +#if PIN_EXISTS(CALIBRATION) + REPORT_NAME_DIGITAL(__LINE__, CALIBRATION_PIN) +#endif #if PIN_EXISTS(SMART_EFFECTOR_MOD) REPORT_NAME_DIGITAL(__LINE__, SMART_EFFECTOR_MOD_PIN) #endif +#if PIN_EXISTS(CLOSED_LOOP_ENABLE) + REPORT_NAME_DIGITAL(__LINE__, CLOSED_LOOP_ENABLE_PIN) +#endif +#if PIN_EXISTS(CLOSED_LOOP_MOVE_COMPLETE) + REPORT_NAME_DIGITAL(__LINE__, CLOSED_LOOP_MOVE_COMPLETE_PIN) +#endif +#if PIN_EXISTS(ESP_WIFI_MODULE_RESET) + REPORT_NAME_DIGITAL(__LINE__, ESP_WIFI_MODULE_RESET_PIN) +#endif +#if PIN_EXISTS(ESP_WIFI_MODULE_ENABLE) + REPORT_NAME_DIGITAL(__LINE__, ESP_WIFI_MODULE_ENABLE_PIN) +#endif +#if PIN_EXISTS(ESP_WIFI_MODULE_GPIO0) + REPORT_NAME_DIGITAL(__LINE__, ESP_WIFI_MODULE_GPIO0_PIN) +#endif +#if PIN_EXISTS(ESP_WIFI_MODULE_GPIO2) + REPORT_NAME_DIGITAL(__LINE__, ESP_WIFI_MODULE_GPIO2_PIN) +#endif +// TFT PINS +#if PIN_EXISTS(TFT_CS) + REPORT_NAME_DIGITAL(__LINE__, TFT_CS_PIN) +#endif +#if PIN_EXISTS(TFT_A0) + REPORT_NAME_DIGITAL(__LINE__, TFT_A0_PIN) +#endif +#if PIN_EXISTS(TFT_DC) + REPORT_NAME_DIGITAL(__LINE__, TFT_DC_PIN) +#endif +#if PIN_EXISTS(TFT_MISO) + REPORT_NAME_DIGITAL(__LINE__, TFT_MISO_PIN) +#endif +#if PIN_EXISTS(TFT_BACKLIGHT) + REPORT_NAME_DIGITAL(__LINE__, TFT_BACKLIGHT_PIN) +#endif +#if PIN_EXISTS(TFT_RESET) + REPORT_NAME_DIGITAL(__LINE__, TFT_RESET_PIN) +#endif diff --git a/Marlin/src/pins/rambo/pins_EINSY_RAMBO.h b/Marlin/src/pins/rambo/pins_EINSY_RAMBO.h index 4cfa3261655d..2ea15c97d332 100644 --- a/Marlin/src/pins/rambo/pins_EINSY_RAMBO.h +++ b/Marlin/src/pins/rambo/pins_EINSY_RAMBO.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Einsy-Rambo pin assignments */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino Mega 2560 or Rambo' in 'Tools > Board.'" #endif @@ -39,10 +39,10 @@ #endif // TMC2130 Diag Pins (currently just for reference) -#define X_DIAG_PIN 64 -#define Y_DIAG_PIN 69 -#define Z_DIAG_PIN 68 -#define E0_DIAG_PIN 65 +#define X_DIAG_PIN 64 +#define Y_DIAG_PIN 69 +#define Z_DIAG_PIN 68 +#define E0_DIAG_PIN 65 // // Limit Switches @@ -55,20 +55,20 @@ #if DISABLED(SENSORLESS_HOMING) - #define X_STOP_PIN 12 - #define Y_STOP_PIN 11 - #define Z_STOP_PIN 10 + #define X_STOP_PIN 12 + #define Y_STOP_PIN 11 + #define Z_STOP_PIN 10 #else - #define X_STOP_PIN X_DIAG_PIN - #define Y_STOP_PIN Y_DIAG_PIN + #define X_STOP_PIN X_DIAG_PIN + #define Y_STOP_PIN Y_DIAG_PIN #if ENABLED(BLTOUCH) - #define Z_STOP_PIN 11 // Y-MIN - #define SERVO0_PIN 10 // Z-MIN + #define Z_STOP_PIN 11 // Y-MIN + #define SERVO0_PIN 10 // Z-MIN #else - #define Z_STOP_PIN 10 + #define Z_STOP_PIN 10 #endif #endif @@ -77,104 +77,115 @@ // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 10 + #define Z_MIN_PROBE_PIN 10 +#endif + +// +// Filament Runout Sensor +// +#ifndef FIL_RUNOUT_PIN + #define FIL_RUNOUT_PIN 62 #endif // // Steppers // -#define X_STEP_PIN 37 -#define X_DIR_PIN 49 -#define X_ENABLE_PIN 29 -#define X_CS_PIN 41 +#define X_STEP_PIN 37 +#define X_DIR_PIN 49 +#define X_ENABLE_PIN 29 +#define X_CS_PIN 41 -#define Y_STEP_PIN 36 -#define Y_DIR_PIN 48 -#define Y_ENABLE_PIN 28 -#define Y_CS_PIN 39 +#define Y_STEP_PIN 36 +#define Y_DIR_PIN 48 +#define Y_ENABLE_PIN 28 +#define Y_CS_PIN 39 -#define Z_STEP_PIN 35 -#define Z_DIR_PIN 47 -#define Z_ENABLE_PIN 27 -#define Z_CS_PIN 67 +#define Z_STEP_PIN 35 +#define Z_DIR_PIN 47 +#define Z_ENABLE_PIN 27 +#define Z_CS_PIN 67 -#define E0_STEP_PIN 34 -#define E0_DIR_PIN 43 -#define E0_ENABLE_PIN 26 -#define E0_CS_PIN 66 +#define E0_STEP_PIN 34 +#define E0_DIR_PIN 43 +#define E0_ENABLE_PIN 26 +#define E0_CS_PIN 66 // // Temperature Sensors // -#define TEMP_0_PIN 0 // Analog Input -#define TEMP_1_PIN 1 // Analog Input -#define TEMP_BED_PIN 2 // Analog Input +#define TEMP_0_PIN 0 // Analog Input +#define TEMP_1_PIN 1 // Analog Input +#define TEMP_BED_PIN 2 // Analog Input +#define TEMP_PROBE_PIN 3 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 3 -#define HEATER_BED_PIN 4 +#define HEATER_0_PIN 3 +#define HEATER_BED_PIN 4 #ifndef FAN_PIN - #define FAN_PIN 8 + #define FAN_PIN 8 #endif #ifndef FAN1_PIN - #define FAN1_PIN 6 + #define FAN1_PIN 6 #endif // // Misc. Functions // -#define SDSS 77 -#define LED_PIN 13 -#define CASE_LIGHT_PIN 9 +#define SDSS 77 +#define LED_PIN 13 + +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN 9 +#endif // // M3/M4/M5 - Spindle/Laser Control // // use P1 connector for spindle pins -#define SPINDLE_LASER_PWM_PIN 9 // Hardware PWM -#define SPINDLE_LASER_ENA_PIN 18 // Pullup! -#define SPINDLE_DIR_PIN 19 +#define SPINDLE_LASER_PWM_PIN 9 // Hardware PWM +#define SPINDLE_LASER_ENA_PIN 18 // Pullup! +#define SPINDLE_DIR_PIN 19 // // Průša i3 MK2 Multiplexer Support // -#define E_MUX0_PIN 17 -#define E_MUX1_PIN 16 -#define E_MUX2_PIN 78 // 84 in MK2 Firmware, with BEEPER as 78 +#define E_MUX0_PIN 17 +#define E_MUX1_PIN 16 +#define E_MUX2_PIN 78 // 84 in MK2 Firmware, with BEEPER as 78 // // LCD / Controller // -#if HAS_SPI_LCD || TOUCH_UI_ULTIPANEL +#if HAS_WIRED_LCD || TOUCH_UI_ULTIPANEL - #define KILL_PIN 32 + #define KILL_PIN 32 #if ENABLED(ULTIPANEL) || TOUCH_UI_ULTIPANEL #if ENABLED(CR10_STOCKDISPLAY) - #define LCD_PINS_RS 85 - #define LCD_PINS_ENABLE 71 - #define LCD_PINS_D4 70 - #define BTN_EN1 61 - #define BTN_EN2 59 + #define LCD_PINS_RS 85 + #define LCD_PINS_ENABLE 71 + #define LCD_PINS_D4 70 + #define BTN_EN1 61 + #define BTN_EN2 59 #else - #define LCD_PINS_RS 82 - #define LCD_PINS_ENABLE 61 - #define LCD_PINS_D4 59 - #define LCD_PINS_D5 70 - #define LCD_PINS_D6 85 - #define LCD_PINS_D7 71 - #define BTN_EN1 14 - #define BTN_EN2 72 + #define LCD_PINS_RS 82 + #define LCD_PINS_ENABLE 61 + #define LCD_PINS_D4 59 + #define LCD_PINS_D5 70 + #define LCD_PINS_D6 85 + #define LCD_PINS_D7 71 + #define BTN_EN1 14 + #define BTN_EN2 72 #endif - #define BTN_ENC 9 // AUX-2 - #define BEEPER_PIN 84 // AUX-4 - #define SD_DETECT_PIN 15 + #define BTN_ENC 9 // AUX-2 + #define BEEPER_PIN 84 // AUX-4 + #define SD_DETECT_PIN 15 #endif // ULTIPANEL || TOUCH_UI_ULTIPANEL -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD diff --git a/Marlin/src/pins/rambo/pins_EINSY_RETRO.h b/Marlin/src/pins/rambo/pins_EINSY_RETRO.h index 2bc577313ecc..4a1bf70b6eaa 100644 --- a/Marlin/src/pins/rambo/pins_EINSY_RETRO.h +++ b/Marlin/src/pins/rambo/pins_EINSY_RETRO.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Einsy-Retro pin assignments */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino Mega 2560 or Rambo' in 'Tools > Board.'" #endif @@ -39,10 +39,10 @@ #endif // TMC2130 Diag Pins -#define X_DIAG_PIN 64 -#define Y_DIAG_PIN 69 -#define Z_DIAG_PIN 68 -#define E0_DIAG_PIN 65 +#define X_DIAG_PIN 64 +#define Y_DIAG_PIN 69 +#define Z_DIAG_PIN 68 +#define E0_DIAG_PIN 65 // // Limit Switches @@ -55,141 +55,145 @@ #if DISABLED(SENSORLESS_HOMING) - #define X_MIN_PIN 12 // X- - #define Y_MIN_PIN 11 // Y- - #define Z_MIN_PIN 10 // Z- - #define X_MAX_PIN 81 // X+ - #define Y_MAX_PIN 57 // Y+ + #define X_MIN_PIN 12 // X- + #define Y_MIN_PIN 11 // Y- + #define Z_MIN_PIN 10 // Z- + #define X_MAX_PIN 81 // X+ + #define Y_MAX_PIN 57 // Y+ #else #if X_HOME_DIR < 0 - #define X_MIN_PIN X_DIAG_PIN - #define X_MAX_PIN 81 // X+ + #define X_MIN_PIN X_DIAG_PIN + #define X_MAX_PIN 81 // X+ #else - #define X_MIN_PIN 12 // X- - #define X_MAX_PIN X_DIAG_PIN + #define X_MIN_PIN 12 // X- + #define X_MAX_PIN X_DIAG_PIN #endif #if Y_HOME_DIR < 0 - #define Y_MIN_PIN Y_DIAG_PIN - #define Y_MAX_PIN 57 // Y+ + #define Y_MIN_PIN Y_DIAG_PIN + #define Y_MAX_PIN 57 // Y+ #else - #define Y_MIN_PIN 11 // Y- - #define Y_MAX_PIN Y_DIAG_PIN + #define Y_MIN_PIN 11 // Y- + #define Y_MAX_PIN Y_DIAG_PIN #endif #if ENABLED(BLTOUCH) - #define Z_MIN_PIN 11 // Y-MIN - #define SERVO0_PIN 10 // Z-MIN + #define Z_MIN_PIN 11 // Y-MIN + #define SERVO0_PIN 10 // Z-MIN #else - #define Z_MIN_PIN 10 + #define Z_MIN_PIN 10 #endif #endif -#define Z_MAX_PIN 7 +#define Z_MAX_PIN 7 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 10 + #define Z_MIN_PROBE_PIN 10 #endif // // Steppers // -#define X_STEP_PIN 37 -#define X_DIR_PIN 49 -#define X_ENABLE_PIN 29 -#define X_CS_PIN 41 +#define X_STEP_PIN 37 +#define X_DIR_PIN 49 +#define X_ENABLE_PIN 29 +#define X_CS_PIN 41 -#define Y_STEP_PIN 36 -#define Y_DIR_PIN 48 -#define Y_ENABLE_PIN 28 -#define Y_CS_PIN 39 +#define Y_STEP_PIN 36 +#define Y_DIR_PIN 48 +#define Y_ENABLE_PIN 28 +#define Y_CS_PIN 39 -#define Z_STEP_PIN 35 -#define Z_DIR_PIN 47 -#define Z_ENABLE_PIN 27 -#define Z_CS_PIN 67 +#define Z_STEP_PIN 35 +#define Z_DIR_PIN 47 +#define Z_ENABLE_PIN 27 +#define Z_CS_PIN 67 -#define E0_STEP_PIN 34 -#define E0_DIR_PIN 43 -#define E0_ENABLE_PIN 26 -#define E0_CS_PIN 66 +#define E0_STEP_PIN 34 +#define E0_DIR_PIN 43 +#define E0_ENABLE_PIN 26 +#define E0_CS_PIN 66 // // Temperature Sensors // -#define TEMP_0_PIN 0 // Analog Input -#define TEMP_1_PIN 1 // Analog Input -#define TEMP_BED_PIN 2 // Analog Input +#define TEMP_0_PIN 0 // Analog Input +#define TEMP_1_PIN 1 // Analog Input +#define TEMP_BED_PIN 2 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 3 -#define HEATER_BED_PIN 4 +#define HEATER_0_PIN 3 +#define HEATER_BED_PIN 4 #ifndef FAN_PIN - #define FAN_PIN 8 + #define FAN_PIN 8 #endif -#define FAN1_PIN 6 +#define FAN1_PIN 6 // // Misc. Functions // -#define SDSS 53 -#define LED_PIN 13 -#define CASE_LIGHT_PIN 9 +#define SDSS 53 +#define LED_PIN 13 + +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN 9 +#endif // // M3/M4/M5 - Spindle/Laser Control // // use P1 connector for spindle pins -#define SPINDLE_LASER_PWM_PIN 9 // Hardware PWM -#define SPINDLE_LASER_ENA_PIN 18 // Pullup! -#define SPINDLE_DIR_PIN 19 +#define SPINDLE_LASER_PWM_PIN 9 // Hardware PWM +#define SPINDLE_LASER_ENA_PIN 18 // Pullup! +#define SPINDLE_DIR_PIN 19 // // Průša i3 MK2 Multiplexer Support // -#define E_MUX0_PIN 17 -#define E_MUX1_PIN 16 -#define E_MUX2_PIN 78 // 84 in MK2 Firmware, with BEEPER as 78 +#define E_MUX0_PIN 17 +#define E_MUX1_PIN 16 +#define E_MUX2_PIN 78 // 84 in MK2 Firmware, with BEEPER as 78 // // LCD / Controller // -#if HAS_SPI_LCD || TOUCH_UI_ULTIPANEL || ENABLED(TOUCH_UI_FTDI_EVE) +#if ANY(HAS_WIRED_LCD, TOUCH_UI_ULTIPANEL, TOUCH_UI_FTDI_EVE) - #define KILL_PIN 32 + #define KILL_PIN 32 - #if ENABLED(ULTIPANEL) || TOUCH_UI_ULTIPANEL || ENABLED(TOUCH_UI_FTDI_EVE) + #if ANY(ULTIPANEL, TOUCH_UI_ULTIPANEL, TOUCH_UI_FTDI_EVE) #if ENABLED(CR10_STOCKDISPLAY) - #define LCD_PINS_RS 85 - #define LCD_PINS_ENABLE 71 - #define LCD_PINS_D4 70 - #define BTN_EN1 18 - #define BTN_EN2 19 + #define LCD_PINS_RS 85 + #define LCD_PINS_ENABLE 71 + #define LCD_PINS_D4 70 + #define BTN_EN1 18 + #define BTN_EN2 19 #else - #define LCD_PINS_RS 82 - #define LCD_PINS_ENABLE 18 // On 0.6b, use 61 - #define LCD_PINS_D4 19 // On 0.6b, use 59 - #define LCD_PINS_D5 70 - #define LCD_PINS_D6 85 - #define LCD_PINS_D7 71 - #define BTN_EN1 14 - #define BTN_EN2 72 + #define LCD_PINS_RS 82 + #define LCD_PINS_ENABLE 18 // On 0.6b, use 61 + #define LCD_PINS_D4 19 // On 0.6b, use 59 + #define LCD_PINS_D5 70 + #define LCD_PINS_D6 85 + #define LCD_PINS_D7 71 + #define BTN_EN1 14 + #define BTN_EN2 72 #endif - #define BTN_ENC 9 // AUX-2 - #define BEEPER_PIN 84 // AUX-4 + #define BTN_ENC 9 // AUX-2 + #define BEEPER_PIN 84 // AUX-4 + + #define SD_DETECT_PIN 15 - #define SD_DETECT_PIN 15 + #endif // ULTIPANEL || TOUCH_UI_ULTIPANEL || TOUCH_UI_FTDI_EVE - #endif // ULTIPANEL || TOUCH_UI_ULTIPANEL -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD || TOUCH_UI_ULTIPANEL || TOUCH_UI_FTDI_EVE diff --git a/Marlin/src/pins/rambo/pins_MINIRAMBO.h b/Marlin/src/pins/rambo/pins_MINIRAMBO.h index 6aabf594ac20..6314bc07b8c0 100644 --- a/Marlin/src/pins/rambo/pins_MINIRAMBO.h +++ b/Marlin/src/pins/rambo/pins_MINIRAMBO.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,8 +25,8 @@ * Mini-RAMBo pin assignments */ -#ifndef __AVR_ATmega2560__ - #error "Oops! Select 'RAMBo' in 'Tools > Board.'" +#if NOT_TARGET(__AVR_ATmega2560__) + #error "Oops! Select 'RAMBo' in 'Tools > Board' or the Mega2560 environment in PlatformIO." #endif #if MB(MINIRAMBO_10A) @@ -38,155 +38,155 @@ // // Limit Switches // -#define X_MIN_PIN 12 -#define X_MAX_PIN 30 -#define Y_MIN_PIN 11 -#define Y_MAX_PIN 24 -#define Z_MIN_PIN 10 -#define Z_MAX_PIN 23 +#define X_MIN_PIN 12 +#define X_MAX_PIN 30 +#define Y_MIN_PIN 11 +#define Y_MAX_PIN 24 +#define Z_MIN_PIN 10 +#define Z_MAX_PIN 23 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 23 + #define Z_MIN_PROBE_PIN 23 #endif // // Steppers // -#define X_STEP_PIN 37 -#define X_DIR_PIN 48 -#define X_ENABLE_PIN 29 +#define X_STEP_PIN 37 +#define X_DIR_PIN 48 +#define X_ENABLE_PIN 29 -#define Y_STEP_PIN 36 -#define Y_DIR_PIN 49 -#define Y_ENABLE_PIN 28 +#define Y_STEP_PIN 36 +#define Y_DIR_PIN 49 +#define Y_ENABLE_PIN 28 -#define Z_STEP_PIN 35 -#define Z_DIR_PIN 47 -#define Z_ENABLE_PIN 27 +#define Z_STEP_PIN 35 +#define Z_DIR_PIN 47 +#define Z_ENABLE_PIN 27 -#define E0_STEP_PIN 34 -#define E0_DIR_PIN 43 -#define E0_ENABLE_PIN 26 +#define E0_STEP_PIN 34 +#define E0_DIR_PIN 43 +#define E0_ENABLE_PIN 26 // Microstepping pins - Mapping not from fastio.h (?) -#define X_MS1_PIN 40 -#define X_MS2_PIN 41 -#define Y_MS1_PIN 69 -#define Y_MS2_PIN 39 -#define Z_MS1_PIN 68 -#define Z_MS2_PIN 67 -#define E0_MS1_PIN 65 -#define E0_MS2_PIN 66 - -#define MOTOR_CURRENT_PWM_XY_PIN 46 -#define MOTOR_CURRENT_PWM_Z_PIN 45 -#define MOTOR_CURRENT_PWM_E_PIN 44 +#define X_MS1_PIN 40 +#define X_MS2_PIN 41 +#define Y_MS1_PIN 69 +#define Y_MS2_PIN 39 +#define Z_MS1_PIN 68 +#define Z_MS2_PIN 67 +#define E0_MS1_PIN 65 +#define E0_MS2_PIN 66 + +#define MOTOR_CURRENT_PWM_XY_PIN 46 +#define MOTOR_CURRENT_PWM_Z_PIN 45 +#define MOTOR_CURRENT_PWM_E_PIN 44 // Motor current PWM conversion, PWM value = MotorCurrentSetting * 255 / range #ifndef MOTOR_CURRENT_PWM_RANGE - #define MOTOR_CURRENT_PWM_RANGE 2000 + #define MOTOR_CURRENT_PWM_RANGE 2000 #endif #define DEFAULT_PWM_MOTOR_CURRENT {1300, 1300, 1250} // // Temperature Sensors // -#define TEMP_0_PIN 0 // Analog Input -#define TEMP_1_PIN 1 // Analog Input -#define TEMP_BED_PIN 2 // Analog Input +#define TEMP_0_PIN 0 // Analog Input +#define TEMP_1_PIN 1 // Analog Input +#define TEMP_BED_PIN 2 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 3 -#define HEATER_1_PIN 7 +#define HEATER_0_PIN 3 +#define HEATER_1_PIN 7 #if !MB(MINIRAMBO_10A) - #define HEATER_2_PIN 6 + #define HEATER_2_PIN 6 #endif -#define HEATER_BED_PIN 4 +#define HEATER_BED_PIN 4 #ifndef FAN_PIN - #define FAN_PIN 8 + #define FAN_PIN 8 #endif -#define FAN1_PIN 6 +#define FAN1_PIN 6 // // Misc. Functions // -#define SDSS 53 -#define LED_PIN 13 +#define SDSS 53 +#define LED_PIN 13 #if !MB(MINIRAMBO_10A) - #define CASE_LIGHT_PIN 9 + #define CASE_LIGHT_PIN 9 #endif // // M3/M4/M5 - Spindle/Laser Control // // use P1 connector for spindle pins -#define SPINDLE_LASER_PWM_PIN 9 // Hardware PWM -#define SPINDLE_LASER_ENA_PIN 18 // Pullup! -#define SPINDLE_DIR_PIN 19 +#define SPINDLE_LASER_PWM_PIN 9 // Hardware PWM +#define SPINDLE_LASER_ENA_PIN 18 // Pullup! +#define SPINDLE_DIR_PIN 19 // // Průša i3 MK2 Multiplexer Support // -#define E_MUX0_PIN 17 -#define E_MUX1_PIN 16 +#define E_MUX0_PIN 17 +#define E_MUX1_PIN 16 #if !MB(MINIRAMBO_10A) - #define E_MUX2_PIN 78 // 84 in MK2 Firmware, with BEEPER as 78 + #define E_MUX2_PIN 78 // 84 in MK2 Firmware, with BEEPER as 78 #endif // // LCD / Controller // -#if HAS_SPI_LCD || TOUCH_UI_ULTIPANEL +#if HAS_WIRED_LCD || TOUCH_UI_ULTIPANEL #if !MB(MINIRAMBO_10A) - #define KILL_PIN 32 + #define KILL_PIN 32 #endif #if ENABLED(ULTIPANEL) || TOUCH_UI_ULTIPANEL #if MB(MINIRAMBO_10A) - #define BEEPER_PIN 78 + #define BEEPER_PIN 78 - #define BTN_EN1 80 - #define BTN_EN2 73 - #define BTN_ENC 21 + #define BTN_EN1 80 + #define BTN_EN2 73 + #define BTN_ENC 21 - #define LCD_PINS_RS 38 - #define LCD_PINS_ENABLE 5 - #define LCD_PINS_D4 14 - #define LCD_PINS_D5 15 - #define LCD_PINS_D6 32 - #define LCD_PINS_D7 31 + #define LCD_PINS_RS 38 + #define LCD_PINS_ENABLE 5 + #define LCD_PINS_D4 14 + #define LCD_PINS_D5 15 + #define LCD_PINS_D6 32 + #define LCD_PINS_D7 31 - #define SD_DETECT_PIN 72 + #define SD_DETECT_PIN 72 - #else // !MINIRAMBO_10A + #else // !MINIRAMBO_10A // AUX-4 - #define BEEPER_PIN 84 + #define BEEPER_PIN 84 // AUX-2 - #define BTN_EN1 14 - #define BTN_EN2 72 - #define BTN_ENC 9 + #define BTN_EN1 14 + #define BTN_EN2 72 + #define BTN_ENC 9 - #define LCD_PINS_RS 82 - #define LCD_PINS_ENABLE 18 - #define LCD_PINS_D4 19 - #define LCD_PINS_D5 70 - #define LCD_PINS_D6 85 - #define LCD_PINS_D7 71 + #define LCD_PINS_RS 82 + #define LCD_PINS_ENABLE 18 + #define LCD_PINS_D4 19 + #define LCD_PINS_D5 70 + #define LCD_PINS_D6 85 + #define LCD_PINS_D7 71 - #define SD_DETECT_PIN 15 + #define SD_DETECT_PIN 15 #endif // !MINIRAMBO_10A #endif // ULTIPANEL || TOUCH_UI_ULTIPANEL -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD || TOUCH_UI_ULTIPANEL diff --git a/Marlin/src/pins/rambo/pins_RAMBO.h b/Marlin/src/pins/rambo/pins_RAMBO.h index 2e52e9427c28..735852b2ff79 100644 --- a/Marlin/src/pins/rambo/pins_RAMBO.h +++ b/Marlin/src/pins/rambo/pins_RAMBO.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -34,14 +34,14 @@ * * Instructions for installing the Arduino RAMBo board type for the * Arduino IDE are available at: - * http://reprap.org/wiki/Rambo_firmware + * https://reprap.org/wiki/Rambo_firmware */ /** * Rambo pin assignments */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -50,65 +50,69 @@ // // Servos // -#define SERVO0_PIN 22 // Motor header MX1 -#define SERVO1_PIN 23 // Motor header MX2 -#define SERVO2_PIN 24 // Motor header MX3 -#define SERVO3_PIN 5 // PWM header pin 5 +#define SERVO0_PIN 22 // Motor header MX1 +#define SERVO1_PIN 23 // Motor header MX2 +#define SERVO2_PIN 24 // Motor header MX3 +#define SERVO3_PIN 5 // PWM header pin 5 // // Limit Switches // -#define X_MIN_PIN 12 -#define X_MAX_PIN 24 -#define Y_MIN_PIN 11 -#define Y_MAX_PIN 23 -#define Z_MIN_PIN 10 -#define Z_MAX_PIN 30 +#define X_MIN_PIN 12 +#define X_MAX_PIN 24 +#define Y_MIN_PIN 11 +#define Y_MAX_PIN 23 +#define Z_MIN_PIN 10 +#define Z_MAX_PIN 30 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 30 + #define Z_MIN_PROBE_PIN 30 +#endif + +#ifndef FIL_RUNOUT_PIN + #define FIL_RUNOUT_PIN 5 #endif // // Steppers // -#define X_STEP_PIN 37 -#define X_DIR_PIN 48 -#define X_ENABLE_PIN 29 +#define X_STEP_PIN 37 +#define X_DIR_PIN 48 +#define X_ENABLE_PIN 29 -#define Y_STEP_PIN 36 -#define Y_DIR_PIN 49 -#define Y_ENABLE_PIN 28 +#define Y_STEP_PIN 36 +#define Y_DIR_PIN 49 +#define Y_ENABLE_PIN 28 -#define Z_STEP_PIN 35 -#define Z_DIR_PIN 47 -#define Z_ENABLE_PIN 27 +#define Z_STEP_PIN 35 +#define Z_DIR_PIN 47 +#define Z_ENABLE_PIN 27 -#define E0_STEP_PIN 34 -#define E0_DIR_PIN 43 -#define E0_ENABLE_PIN 26 +#define E0_STEP_PIN 34 +#define E0_DIR_PIN 43 +#define E0_ENABLE_PIN 26 -#define E1_STEP_PIN 33 -#define E1_DIR_PIN 42 -#define E1_ENABLE_PIN 25 +#define E1_STEP_PIN 33 +#define E1_DIR_PIN 42 +#define E1_ENABLE_PIN 25 // Microstepping pins - Mapping not from fastio.h (?) -#define X_MS1_PIN 40 -#define X_MS2_PIN 41 -#define Y_MS1_PIN 69 -#define Y_MS2_PIN 39 -#define Z_MS1_PIN 68 -#define Z_MS2_PIN 67 -#define E0_MS1_PIN 65 -#define E0_MS2_PIN 66 -#define E1_MS1_PIN 63 -#define E1_MS2_PIN 64 - -#define DIGIPOTSS_PIN 38 -#define DIGIPOT_CHANNELS { 4,5,3,0,1 } // X Y Z E0 E1 digipot channels to stepper driver mapping +#define X_MS1_PIN 40 +#define X_MS2_PIN 41 +#define Y_MS1_PIN 69 +#define Y_MS2_PIN 39 +#define Z_MS1_PIN 68 +#define Z_MS2_PIN 67 +#define E0_MS1_PIN 65 +#define E0_MS2_PIN 66 +#define E1_MS1_PIN 63 +#define E1_MS2_PIN 64 + +#define DIGIPOTSS_PIN 38 +#define DIGIPOT_CHANNELS { 4,5,3,0,1 } // X Y Z E0 E1 digipot channels to stepper driver mapping #ifndef DIGIPOT_MOTOR_CURRENT #define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 } // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A) #endif @@ -116,123 +120,133 @@ // // Temperature Sensors // -#define TEMP_0_PIN 0 // Analog Input -#define TEMP_1_PIN 1 // Analog Input -#define TEMP_BED_PIN 2 // Analog Input +#define TEMP_0_PIN 0 // Analog Input +#define TEMP_1_PIN 1 // Analog Input +#define TEMP_BED_PIN 2 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 9 -#define HEATER_1_PIN 7 -#define HEATER_2_PIN 6 -#define HEATER_BED_PIN 3 +#define HEATER_0_PIN 9 +#define HEATER_1_PIN 7 +#define HEATER_2_PIN 6 +#define HEATER_BED_PIN 3 #ifndef FAN_PIN - #define FAN_PIN 8 + #define FAN_PIN 8 #endif -#define FAN1_PIN 6 -#define FAN2_PIN 2 +#define FAN1_PIN 6 +#define FAN2_PIN 2 // // Misc. Functions // -#define SDSS 53 -#define LED_PIN 13 -#define PS_ON_PIN 4 -#define CASE_LIGHT_PIN 46 +#define SDSS 53 +#define LED_PIN 13 +#define PS_ON_PIN 4 + +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN 46 +#endif #ifndef FILWIDTH_PIN - #define FILWIDTH_PIN 3 // Analog Input + #define FILWIDTH_PIN 3 // Analog Input #endif // // M3/M4/M5 - Spindle/Laser Control // -#define SPINDLE_LASER_PWM_PIN 45 // Hardware PWM -#define SPINDLE_LASER_ENA_PIN 31 // Pullup! -#define SPINDLE_DIR_PIN 32 +#define SPINDLE_LASER_PWM_PIN 45 // Hardware PWM +#define SPINDLE_LASER_ENA_PIN 31 // Pullup! +#define SPINDLE_DIR_PIN 32 + +// +// SPI for Max6675 or Max31855 Thermocouple +// +#ifndef MAX6675_SS_PIN + #define MAX6675_SS_PIN 32 // SPINDLE_DIR_PIN / STAT_LED_BLUE_PIN +#endif // // M7/M8/M9 - Coolant Control // -#define COOLANT_MIST_PIN 22 -#define COOLANT_FLOOD_PIN 44 +#define COOLANT_MIST_PIN 22 +#define COOLANT_FLOOD_PIN 44 // // Průša i3 MK2 Multiplexer Support // -#define E_MUX0_PIN 17 -#define E_MUX1_PIN 16 -#define E_MUX2_PIN 84 // 84 in MK2 Firmware +#define E_MUX0_PIN 17 +#define E_MUX1_PIN 16 +#define E_MUX2_PIN 84 // 84 in MK2 Firmware // // LCD / Controller // -#if HAS_SPI_LCD || TOUCH_UI_ULTIPANEL +#if HAS_WIRED_LCD || TOUCH_UI_ULTIPANEL - #define KILL_PIN 80 + #define KILL_PIN 80 #if ENABLED(ULTIPANEL) || TOUCH_UI_ULTIPANEL - #define LCD_PINS_RS 70 - #define LCD_PINS_ENABLE 71 - #define LCD_PINS_D4 72 - #define LCD_PINS_D5 73 - #define LCD_PINS_D6 74 - #define LCD_PINS_D7 75 + #define LCD_PINS_RS 70 + #define LCD_PINS_ENABLE 71 + #define LCD_PINS_D4 72 + #define LCD_PINS_D5 73 + #define LCD_PINS_D6 74 + #define LCD_PINS_D7 75 #if ANY(VIKI2, miniVIKI) - #define BEEPER_PIN 44 + #define BEEPER_PIN 44 // NB: Panucatt's Viki 2.0 wiring diagram (v1.2) indicates that the // beeper/buzzer is connected to pin 33; however, the pin used in the // diagram is actually pin 44, so this is correct. - #define DOGLCD_A0 70 - #define DOGLCD_CS 71 + #define DOGLCD_A0 70 + #define DOGLCD_CS 71 #define LCD_SCREEN_ROT_180 - #define BTN_EN1 85 - #define BTN_EN2 84 - #define BTN_ENC 83 + #define BTN_EN1 85 + #define BTN_EN2 84 + #define BTN_ENC 83 - #define SD_DETECT_PIN -1 // Pin 72 if using easy adapter board + #define SD_DETECT_PIN -1 // Pin 72 if using easy adapter board - #define STAT_LED_RED_PIN 22 - #define STAT_LED_BLUE_PIN 32 + #define STAT_LED_RED_PIN 22 + #define STAT_LED_BLUE_PIN 32 - #else // !VIKI2 && !miniVIKI + #else // !VIKI2 && !miniVIKI - #define BEEPER_PIN 79 // AUX-4 + #define BEEPER_PIN 79 // AUX-4 // AUX-2 - #define BTN_EN1 76 - #define BTN_EN2 77 - #define BTN_ENC 78 + #define BTN_EN1 76 + #define BTN_EN2 77 + #define BTN_ENC 78 - #define SD_DETECT_PIN 81 + #define SD_DETECT_PIN 81 #endif // !VIKI2 && !miniVIKI - #else // !NEWPANEL - old style panel with shift register + #else // !NEWPANEL - old style panel with shift register // No Beeper added - #define BEEPER_PIN 33 + #define BEEPER_PIN 33 // Buttons attached to a shift register // Not wired yet - //#define SHIFT_CLK 38 - //#define SHIFT_LD 42 - //#define SHIFT_OUT 40 - //#define SHIFT_EN 17 - - #define LCD_PINS_RS 75 - #define LCD_PINS_ENABLE 17 - #define LCD_PINS_D4 23 - #define LCD_PINS_D5 25 - #define LCD_PINS_D6 27 - #define LCD_PINS_D7 29 + //#define SHIFT_CLK 38 + //#define SHIFT_LD 42 + //#define SHIFT_OUT 40 + //#define SHIFT_EN 17 + + #define LCD_PINS_RS 75 + #define LCD_PINS_ENABLE 17 + #define LCD_PINS_D4 23 + #define LCD_PINS_D5 25 + #define LCD_PINS_D6 27 + #define LCD_PINS_D7 29 #endif // !NEWPANEL -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD diff --git a/Marlin/src/pins/rambo/pins_SCOOVO_X9H.h b/Marlin/src/pins/rambo/pins_SCOOVO_X9H.h index 2bb6e9b97925..4af38e1de36b 100644 --- a/Marlin/src/pins/rambo/pins_SCOOVO_X9H.h +++ b/Marlin/src/pins/rambo/pins_SCOOVO_X9H.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Rambo pin assignments MODIFIED FOR Scoovo X9H ************************************************/ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -34,126 +34,126 @@ // // Servos // -#define SERVO0_PIN 22 // Motor header MX1 -#define SERVO1_PIN 23 // Motor header MX2 -#define SERVO2_PIN 24 // Motor header MX3 -#define SERVO3_PIN 5 // PWM header pin 5 +#define SERVO0_PIN 22 // Motor header MX1 +#define SERVO1_PIN 23 // Motor header MX2 +#define SERVO2_PIN 24 // Motor header MX3 +#define SERVO3_PIN 5 // PWM header pin 5 // // Limit Switches // -#define X_MIN_PIN 12 -#define X_MAX_PIN 24 -#define Y_MIN_PIN 11 -#define Y_MAX_PIN 23 -#define Z_MIN_PIN 10 -#define Z_MAX_PIN 30 +#define X_MIN_PIN 12 +#define X_MAX_PIN 24 +#define Y_MIN_PIN 11 +#define Y_MAX_PIN 23 +#define Z_MIN_PIN 10 +#define Z_MAX_PIN 30 // // Z Probe (when not Z_MIN_IN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 30 + #define Z_MIN_PROBE_PIN 30 #endif // // Steppers // -#define X_STEP_PIN 37 -#define X_DIR_PIN 48 -#define X_ENABLE_PIN 29 +#define X_STEP_PIN 37 +#define X_DIR_PIN 48 +#define X_ENABLE_PIN 29 -#define Y_STEP_PIN 36 -#define Y_DIR_PIN 49 -#define Y_ENABLE_PIN 28 +#define Y_STEP_PIN 36 +#define Y_DIR_PIN 49 +#define Y_ENABLE_PIN 28 -#define Z_STEP_PIN 35 -#define Z_DIR_PIN 47 -#define Z_ENABLE_PIN 27 +#define Z_STEP_PIN 35 +#define Z_DIR_PIN 47 +#define Z_ENABLE_PIN 27 -#define E0_STEP_PIN 34 -#define E0_DIR_PIN 43 -#define E0_ENABLE_PIN 26 +#define E0_STEP_PIN 34 +#define E0_DIR_PIN 43 +#define E0_ENABLE_PIN 26 -#define E1_STEP_PIN 33 -#define E1_DIR_PIN 42 -#define E1_ENABLE_PIN 25 +#define E1_STEP_PIN 33 +#define E1_DIR_PIN 42 +#define E1_ENABLE_PIN 25 // Microstepping pins - Mapping not from fastio.h (?) -#define X_MS1_PIN 40 -#define X_MS2_PIN 41 -#define Y_MS1_PIN 69 -#define Y_MS2_PIN 39 -#define Z_MS1_PIN 68 -#define Z_MS2_PIN 67 -#define E0_MS1_PIN 65 -#define E0_MS2_PIN 66 -#define E1_MS1_PIN 63 -#define E1_MS2_PIN 64 +#define X_MS1_PIN 40 +#define X_MS2_PIN 41 +#define Y_MS1_PIN 69 +#define Y_MS2_PIN 39 +#define Z_MS1_PIN 68 +#define Z_MS2_PIN 67 +#define E0_MS1_PIN 65 +#define E0_MS2_PIN 66 +#define E1_MS1_PIN 63 +#define E1_MS2_PIN 64 -#define DIGIPOTSS_PIN 38 -#define DIGIPOT_CHANNELS {4,5,3,0,1} // X Y Z E0 E1 digipot channels to stepper driver mapping +#define DIGIPOTSS_PIN 38 +#define DIGIPOT_CHANNELS {4,5,3,0,1} // X Y Z E0 E1 digipot channels to stepper driver mapping // // Temperature Sensors // -#define TEMP_0_PIN 0 // Analog Input -#define TEMP_BED_PIN 7 // Analog Input +#define TEMP_0_PIN 0 // Analog Input +#define TEMP_BED_PIN 7 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 9 -#define HEATER_1_PIN 7 -#define HEATER_BED_PIN 3 +#define HEATER_0_PIN 9 +#define HEATER_1_PIN 7 +#define HEATER_BED_PIN 3 #ifndef FAN_PIN - #define FAN_PIN 8 + #define FAN_PIN 8 #endif -#define FAN1_PIN 6 -#define FAN2_PIN 2 +#define FAN1_PIN 6 +#define FAN2_PIN 2 // // Misc. Functions // -#define SDSS 53 -#define LED_PIN 13 -#define PS_ON_PIN 4 +#define SDSS 53 +#define LED_PIN 13 +#define PS_ON_PIN 4 #ifndef FILWIDTH_PIN - #define FILWIDTH_PIN 3 // Analog Input + #define FILWIDTH_PIN 3 // Analog Input #endif // // LCD / Controller // -#define LCD_PINS_RS 70 // Ext2_5 -#define LCD_PINS_ENABLE 71 // Ext2_7 -#define LCD_PINS_D4 72 // Ext2_9 ? -#define LCD_PINS_D5 73 // Ext2_11 ? -#define LCD_PINS_D6 74 // Ext2_13 -#define LCD_PINS_D7 75 // Ext2_15 ? -#define BEEPER_PIN -1 +#define LCD_PINS_RS 70 // Ext2_5 +#define LCD_PINS_ENABLE 71 // Ext2_7 +#define LCD_PINS_D4 72 // Ext2_9 ? +#define LCD_PINS_D5 73 // Ext2_11 ? +#define LCD_PINS_D6 74 // Ext2_13 +#define LCD_PINS_D7 75 // Ext2_15 ? +#define BEEPER_PIN -1 -#define BTN_HOME 80 // Ext_16 -#define BTN_CENTER 81 // Ext_14 -#define BTN_ENC BTN_CENTER -#define BTN_RIGHT 82 // Ext_12 -#define BTN_LEFT 83 // Ext_10 -#define BTN_UP 84 // Ext2_8 -#define BTN_DOWN 85 // Ext2_6 +#define BTN_HOME 80 // Ext_16 +#define BTN_CENTER 81 // Ext_14 +#define BTN_ENC BTN_CENTER +#define BTN_RIGHT 82 // Ext_12 +#define BTN_LEFT 83 // Ext_10 +#define BTN_UP 84 // Ext2_8 +#define BTN_DOWN 85 // Ext2_6 -#define HOME_PIN BTN_HOME +#define HOME_PIN BTN_HOME #if ANY(VIKI2, miniVIKI) - #define BEEPER_PIN 44 + #define BEEPER_PIN 44 // Pins for DOGM SPI LCD Support - #define DOGLCD_A0 70 - #define DOGLCD_CS 71 + #define DOGLCD_A0 70 + #define DOGLCD_CS 71 #define LCD_SCREEN_ROT_180 - #define SD_DETECT_PIN -1 // Pin 72 if using easy adapter board + #define SD_DETECT_PIN -1 // Pin 72 if using easy adapter board - #define STAT_LED_RED_PIN 22 - #define STAT_LED_BLUE_PIN 32 + #define STAT_LED_RED_PIN 22 + #define STAT_LED_BLUE_PIN 32 #endif // VIKI2/miniVIKI diff --git a/Marlin/src/pins/ramps/pins_3DRAG.h b/Marlin/src/pins/ramps/pins_3DRAG.h index 3f537a6663f1..f0057e1fc980 100644 --- a/Marlin/src/pins/ramps/pins_3DRAG.h +++ b/Marlin/src/pins/ramps/pins_3DRAG.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -34,17 +34,19 @@ #endif #ifndef DEFAULT_SOURCE_CODE_URL - #define DEFAULT_SOURCE_CODE_URL "http://3dprint.elettronicain.it/" + #define DEFAULT_SOURCE_CODE_URL "https://3dprint.elettronicain.it/" #endif // // Heaters / Fans // -#define RAMPS_D8_PIN 9 -#define RAMPS_D9_PIN 8 -#define MOSFET_D_PIN 12 +#define RAMPS_D8_PIN 9 +#define RAMPS_D9_PIN 8 +#define MOSFET_D_PIN 12 -#define CASE_LIGHT_PIN -1 // Hardware PWM but one is not available on expansion header +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN -1 // Hardware PWM but one is not available on expansion header +#endif #include "pins_RAMPS.h" @@ -57,21 +59,21 @@ // Steppers // #undef Z_ENABLE_PIN -#define Z_ENABLE_PIN 63 +#define Z_ENABLE_PIN 63 // // Heaters / Fans // -#define HEATER_2_PIN 6 +#define HEATER_2_PIN 6 // // Misc. Functions // #undef SDSS -#define SDSS 25 +#define SDSS 25 #undef SD_DETECT_PIN -#define SD_DETECT_PIN 53 +#define SD_DETECT_PIN 53 // // LCD / Controller @@ -85,26 +87,26 @@ #undef LCD_PINS_D5 #undef LCD_PINS_D6 #undef LCD_PINS_D7 - #define LCD_PINS_RS 27 - #define LCD_PINS_ENABLE 29 - #define LCD_PINS_D4 37 - #define LCD_PINS_D5 35 - #define LCD_PINS_D6 33 - #define LCD_PINS_D7 31 + #define LCD_PINS_RS 27 + #define LCD_PINS_ENABLE 29 + #define LCD_PINS_D4 37 + #define LCD_PINS_D5 35 + #define LCD_PINS_D6 33 + #define LCD_PINS_D7 31 // Buttons #undef BTN_EN1 #undef BTN_EN2 #undef BTN_ENC - #define BTN_EN1 16 - #define BTN_EN2 17 - #define BTN_ENC 23 + #define BTN_EN1 16 + #define BTN_EN2 17 + #define BTN_ENC 23 #else - #define BEEPER_PIN 33 + #define BEEPER_PIN 33 -#endif // HAS_SPI_LCD && NEWPANEL +#endif // ULTRA_LCD && NEWPANEL /** * M3/M4/M5 - Spindle/Laser Control @@ -137,7 +139,7 @@ * * Note: Socket names vary from vendor to vendor */ -#undef SPINDLE_LASER_PWM_PIN // Definitions in pins_RAMPS.h are not good with 3DRAG +#undef SPINDLE_LASER_PWM_PIN // Definitions in pins_RAMPS.h are not good with 3DRAG #undef SPINDLE_LASER_ENA_PIN #undef SPINDLE_DIR_PIN @@ -149,14 +151,14 @@ #undef Z_DIR_PIN #undef Z_ENABLE_PIN #undef Z_STEP_PIN - #define Z_DIR_PIN 28 - #define Z_ENABLE_PIN 24 - #define Z_STEP_PIN 26 - #define SPINDLE_LASER_PWM_PIN 46 // Hardware PWM - #define SPINDLE_LASER_ENA_PIN 62 // Pullup! - #define SPINDLE_DIR_PIN 48 - #elif !BOTH(ULTRA_LCD, NEWPANEL) // use expansion header if no LCD in use - #define SPINDLE_LASER_ENA_PIN 16 // Pullup or pulldown! - #define SPINDLE_DIR_PIN 17 + #define Z_DIR_PIN 28 + #define Z_ENABLE_PIN 24 + #define Z_STEP_PIN 26 + #define SPINDLE_LASER_PWM_PIN 46 // Hardware PWM + #define SPINDLE_LASER_ENA_PIN 62 // Pullup! + #define SPINDLE_DIR_PIN 48 + #elif !BOTH(ULTRA_LCD, NEWPANEL) // use expansion header if no LCD in use + #define SPINDLE_LASER_ENA_PIN 16 // Pullup or pulldown! + #define SPINDLE_DIR_PIN 17 #endif #endif diff --git a/Marlin/src/pins/ramps/pins_AZTEEG_X3.h b/Marlin/src/pins/ramps/pins_AZTEEG_X3.h index 99b75d5e0024..e919b30cf982 100644 --- a/Marlin/src/pins/ramps/pins_AZTEEG_X3.h +++ b/Marlin/src/pins/ramps/pins_AZTEEG_X3.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,22 +25,22 @@ * AZTEEG_X3 Arduino Mega with RAMPS v1.4 pin assignments */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #elif HOTENDS > 2 || E_STEPPERS > 2 #error "Azteeg X3 supports up to 2 hotends / E-steppers. Comment out this line to continue." #endif #if ENABLED(CASE_LIGHT_ENABLE) && !PIN_EXISTS(CASE_LIGHT) - #define CASE_LIGHT_PIN 6 // Define before RAMPS pins include + #define CASE_LIGHT_PIN 6 // Define before RAMPS pins include #endif #define BOARD_INFO_NAME "Azteeg X3" // // Servos // -#define SERVO0_PIN 44 // SERVO1 port -#define SERVO1_PIN 55 // SERVO2 port +#define SERVO0_PIN 44 // SERVO1 port +#define SERVO1_PIN 55 // SERVO2 port #include "pins_RAMPS_13.h" @@ -55,17 +55,17 @@ #undef DOGLCD_A0 #undef DOGLCD_CS #undef BTN_ENC - #define DOGLCD_A0 31 - #define DOGLCD_CS 32 - #define BTN_ENC 12 + #define DOGLCD_A0 31 + #define DOGLCD_CS 32 + #define BTN_ENC 12 - #define STAT_LED_RED_PIN 64 - #define STAT_LED_BLUE_PIN 63 + #define STAT_LED_RED_PIN 64 + #define STAT_LED_BLUE_PIN 63 #else - #define STAT_LED_RED_PIN 6 - #define STAT_LED_BLUE_PIN 11 + #define STAT_LED_RED_PIN 6 + #define STAT_LED_BLUE_PIN 11 #endif @@ -79,18 +79,18 @@ // // M3/M4/M5 - Spindle/Laser Control // -#undef SPINDLE_LASER_PWM_PIN // Definitions in pins_RAMPS.h are no good with the AzteegX3 board +#undef SPINDLE_LASER_PWM_PIN // Definitions in pins_RAMPS.h are no good with the AzteegX3 board #undef SPINDLE_LASER_ENA_PIN #undef SPINDLE_DIR_PIN #if HAS_CUTTER - #undef SDA // use EXP3 header + #undef SDA // use EXP3 header #undef SCL #if SERVO0_PIN == 7 #undef SERVO0_PIN - #define SERVO0_PIN 11 + #define SERVO0_PIN 11 #endif - #define SPINDLE_LASER_PWM_PIN 7 // Hardware PWM - #define SPINDLE_LASER_ENA_PIN 20 // Pullup! - #define SPINDLE_DIR_PIN 21 + #define SPINDLE_LASER_PWM_PIN 7 // Hardware PWM + #define SPINDLE_LASER_ENA_PIN 20 // Pullup! + #define SPINDLE_DIR_PIN 21 #endif diff --git a/Marlin/src/pins/ramps/pins_AZTEEG_X3_PRO.h b/Marlin/src/pins/ramps/pins_AZTEEG_X3_PRO.h index 627eaabfd69e..9ba6a0c1ac45 100644 --- a/Marlin/src/pins/ramps/pins_AZTEEG_X3_PRO.h +++ b/Marlin/src/pins/ramps/pins_AZTEEG_X3_PRO.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * AZTEEG_X3_PRO (Arduino Mega) pin assignments */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #elif HOTENDS > 5 || E_STEPPERS > 5 #error "Azteeg X3 Pro supports up to 5 hotends / E-steppers. Comment out this line to continue." @@ -43,21 +43,21 @@ // Tested this pin with bed leveling on a Delta with 1 servo. // Physical wire attachment on EXT1: GND, 5V, D47. // -#define SERVO0_PIN 47 +#define SERVO0_PIN 47 // // Limit Switches // -#define X_STOP_PIN 3 -#define Y_STOP_PIN 14 -#define Z_STOP_PIN 18 +#define X_STOP_PIN 3 +#define Y_STOP_PIN 14 +#define Z_STOP_PIN 18 #ifndef FAN_PIN - #define FAN_PIN 6 + #define FAN_PIN 6 #endif #if ENABLED(CASE_LIGHT_ENABLE) && !PIN_EXISTS(CASE_LIGHT) - #define CASE_LIGHT_PIN 44 + #define CASE_LIGHT_PIN 44 #endif // @@ -67,100 +67,111 @@ // DIGIPOT slave addresses #ifndef DIGIPOT_I2C_ADDRESS_A - #define DIGIPOT_I2C_ADDRESS_A 0x2C // unshifted slave address for first DIGIPOT 0x2C (0x58 <- 0x2C << 1) + #define DIGIPOT_I2C_ADDRESS_A 0x2C // unshifted slave address for first DIGIPOT 0x2C (0x58 <- 0x2C << 1) #endif #ifndef DIGIPOT_I2C_ADDRESS_B - #define DIGIPOT_I2C_ADDRESS_B 0x2E // unshifted slave address for second DIGIPOT 0x2E (0x5C <- 0x2E << 1) + #define DIGIPOT_I2C_ADDRESS_B 0x2E // unshifted slave address for second DIGIPOT 0x2E (0x5C <- 0x2E << 1) #endif // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 18 + #define Z_MIN_PROBE_PIN 18 #endif // // Steppers // -#define E2_STEP_PIN 23 -#define E2_DIR_PIN 25 -#define E2_ENABLE_PIN 40 +#define E2_STEP_PIN 23 +#define E2_DIR_PIN 25 +#define E2_ENABLE_PIN 40 -#define E3_STEP_PIN 27 -#define E3_DIR_PIN 29 -#define E3_ENABLE_PIN 41 +#define E3_STEP_PIN 27 +#define E3_DIR_PIN 29 +#define E3_ENABLE_PIN 41 -#define E4_STEP_PIN 43 -#define E4_DIR_PIN 37 -#define E4_ENABLE_PIN 42 +#define E4_STEP_PIN 43 +#define E4_DIR_PIN 37 +#define E4_ENABLE_PIN 42 // // Temperature Sensors // -#define TEMP_2_PIN 12 // Analog Input -#define TEMP_3_PIN 11 // Analog Input -#define TEMP_4_PIN 10 // Analog Input -#define TC1 4 // Analog Input (Thermo couple on Azteeg X3Pro) -#define TC2 5 // Analog Input (Thermo couple on Azteeg X3Pro) +#define TEMP_2_PIN 12 // Analog Input +#define TEMP_3_PIN 11 // Analog Input +#define TEMP_4_PIN 10 // Analog Input +#define TC1 4 // Analog Input (Thermo couple on Azteeg X3Pro) +#define TC2 5 // Analog Input (Thermo couple on Azteeg X3Pro) // // Heaters / Fans // -#define HEATER_2_PIN 16 -#define HEATER_3_PIN 17 -#define HEATER_4_PIN 4 -#define HEATER_5_PIN 5 -#define HEATER_6_PIN 6 -#define HEATER_7_PIN 11 +#define HEATER_2_PIN 16 +#define HEATER_3_PIN 17 +#define HEATER_4_PIN 4 +#define HEATER_5_PIN 5 +#define HEATER_6_PIN 6 +#define HEATER_7_PIN 11 #ifndef CONTROLLER_FAN_PIN - #define CONTROLLER_FAN_PIN 4 // Pin used for the fan to cool motherboard (-1 to disable) + #define CONTROLLER_FAN_PIN 4 // Pin used for the fan to cool motherboard (-1 to disable) #endif -// Fans/Water Pump to cool the hotend cool side. -#define ORIG_E0_AUTO_FAN_PIN 5 -#define ORIG_E1_AUTO_FAN_PIN 5 -#define ORIG_E2_AUTO_FAN_PIN 5 -#define ORIG_E3_AUTO_FAN_PIN 5 +// +// Auto fans +// +#define AUTO_FAN_PIN 5 +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN AUTO_FAN_PIN +#endif +#ifndef E1_AUTO_FAN_PIN + #define E1_AUTO_FAN_PIN AUTO_FAN_PIN +#endif +#ifndef E2_AUTO_FAN_PIN + #define E2_AUTO_FAN_PIN AUTO_FAN_PIN +#endif +#ifndef E3_AUTO_FAN_PIN + #define E3_AUTO_FAN_PIN AUTO_FAN_PIN +#endif // // LCD / Controller // #undef BEEPER_PIN -#define BEEPER_PIN 33 +#define BEEPER_PIN 33 #if ANY(VIKI2, miniVIKI) #undef SD_DETECT_PIN - #define SD_DETECT_PIN 49 // For easy adapter board + #define SD_DETECT_PIN 49 // For easy adapter board #undef BEEPER_PIN - #define BEEPER_PIN 12 // 33 isn't physically available to the LCD display + #define BEEPER_PIN 12 // 33 isn't physically available to the LCD display #else - #define STAT_LED_RED_PIN 32 - #define STAT_LED_BLUE_PIN 35 + #define STAT_LED_RED_PIN 32 + #define STAT_LED_BLUE_PIN 35 #endif // // Misc. Functions // #if ENABLED(CASE_LIGHT_ENABLE) && PIN_EXISTS(CASE_LIGHT) && defined(DOGLCD_A0) && DOGLCD_A0 == CASE_LIGHT_PIN - #undef DOGLCD_A0 // Steal pin 44 for the case light; if you have a Viki2 and have connected it - #define DOGLCD_A0 57 // following the Panucatt wiring diagram, you may need to tweak these pin assignments + #undef DOGLCD_A0 // Steal pin 44 for the case light; if you have a Viki2 and have connected it + #define DOGLCD_A0 57 // following the Panucatt wiring diagram, you may need to tweak these pin assignments // as the wiring diagram uses pin 44 for DOGLCD_A0 #endif // // M3/M4/M5 - Spindle/Laser Control // -#undef SPINDLE_LASER_PWM_PIN // Definitions in pins_RAMPS.h are no good with the AzteegX3pro board +#undef SPINDLE_LASER_PWM_PIN // Definitions in pins_RAMPS.h are no good with the AzteegX3pro board #undef SPINDLE_LASER_ENA_PIN #undef SPINDLE_DIR_PIN -#if HAS_CUTTER // EXP2 header +#if HAS_CUTTER // EXP2 header #if ANY(VIKI2, miniVIKI) - #define BTN_EN2 31 // Pin 7 needed for Spindle PWM + #define BTN_EN2 31 // Pin 7 needed for Spindle PWM #endif - #define SPINDLE_LASER_PWM_PIN 7 // Hardware PWM - #define SPINDLE_LASER_ENA_PIN 20 // Pullup! - #define SPINDLE_DIR_PIN 21 + #define SPINDLE_LASER_PWM_PIN 7 // Hardware PWM + #define SPINDLE_LASER_ENA_PIN 20 // Pullup! + #define SPINDLE_DIR_PIN 21 #endif diff --git a/Marlin/src/pins/ramps/pins_BAM_DICE_DUE.h b/Marlin/src/pins/ramps/pins_BAM_DICE_DUE.h index 9945c94d7627..af1adabbbcd2 100644 --- a/Marlin/src/pins/ramps/pins_BAM_DICE_DUE.h +++ b/Marlin/src/pins/ramps/pins_BAM_DICE_DUE.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -34,9 +34,9 @@ // // M3/M4/M5 - Spindle/Laser Control // -#define SPINDLE_LASER_ENA_PIN 66 // Pullup or pulldown! -#define SPINDLE_DIR_PIN 67 -#define SPINDLE_LASER_PWM_PIN 44 // Hardware PWM +#define SPINDLE_LASER_ENA_PIN 66 // Pullup or pulldown! +#define SPINDLE_DIR_PIN 67 +#define SPINDLE_LASER_PWM_PIN 44 // Hardware PWM #include "pins_RAMPS.h" @@ -45,5 +45,5 @@ // #undef TEMP_0_PIN #undef TEMP_1_PIN -#define TEMP_0_PIN 9 // Analog Input -#define TEMP_1_PIN 11 // Analog Input +#define TEMP_0_PIN 9 // Analog Input +#define TEMP_1_PIN 11 // Analog Input diff --git a/Marlin/src/pins/ramps/pins_BIQU_KFB_2.h b/Marlin/src/pins/ramps/pins_BIQU_KFB_2.h index 738b522e6680..b31df115637d 100644 --- a/Marlin/src/pins/ramps/pins_BIQU_KFB_2.h +++ b/Marlin/src/pins/ramps/pins_BIQU_KFB_2.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/pins/ramps/pins_BQ_ZUM_MEGA_3D.h b/Marlin/src/pins/ramps/pins_BQ_ZUM_MEGA_3D.h index bf75c1a2a2ab..967fec7b47de 100644 --- a/Marlin/src/pins/ramps/pins_BQ_ZUM_MEGA_3D.h +++ b/Marlin/src/pins/ramps/pins_BQ_ZUM_MEGA_3D.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * bq ZUM Mega 3D board definition */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -34,30 +34,38 @@ // // Heaters / Fans // -#define RAMPS_D8_PIN 10 -#define RAMPS_D9_PIN 12 -#define RAMPS_D10_PIN 9 -#define MOSFET_D_PIN 7 +#define RAMPS_D8_PIN 10 +#define RAMPS_D9_PIN 12 +#define RAMPS_D10_PIN 9 +#define MOSFET_D_PIN 7 // // Auto fans // -#define ORIG_E0_AUTO_FAN_PIN 11 -#define ORIG_E1_AUTO_FAN_PIN 6 -#define ORIG_E2_AUTO_FAN_PIN 6 -#define ORIG_E3_AUTO_FAN_PIN 6 +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN 11 +#endif +#ifndef E1_AUTO_FAN_PIN + #define E1_AUTO_FAN_PIN 6 +#endif +#ifndef E2_AUTO_FAN_PIN + #define E2_AUTO_FAN_PIN 6 +#endif +#ifndef E3_AUTO_FAN_PIN + #define E3_AUTO_FAN_PIN 6 +#endif // // M3/M4/M5 - Spindle/Laser Control // -#define SPINDLE_LASER_ENA_PIN 40 // Pullup or pulldown! -#define SPINDLE_LASER_PWM_PIN 44 // Hardware PWM -#define SPINDLE_DIR_PIN 42 +#define SPINDLE_LASER_ENA_PIN 40 // Pullup or pulldown! +#define SPINDLE_LASER_PWM_PIN 44 // Hardware PWM +#define SPINDLE_DIR_PIN 42 // // Limit Switches // -#define X_MAX_PIN 79 // 2 +#define X_MAX_PIN 79 // 2 // // Import RAMPS 1.3 pins @@ -68,34 +76,35 @@ // Z Probe (when not Z_MIN_PIN) // #undef Z_MIN_PROBE_PIN -#define Z_MIN_PROBE_PIN 19 // IND_S_5V +#define Z_MIN_PROBE_PIN 19 // IND_S_5V #undef Z_ENABLE_PIN -#define Z_ENABLE_PIN 77 // 62 +#define Z_ENABLE_PIN 77 // 62 // // Steppers // -#define DIGIPOTSS_PIN 22 +#define DIGIPOTSS_PIN 22 #define DIGIPOT_CHANNELS { 4, 5, 3, 0, 1 } // // Temperature Sensors // #undef TEMP_1_PIN -#define TEMP_1_PIN 14 // Analog Input (15) +#define TEMP_1_PIN 14 // Analog Input (15) #undef TEMP_BED_PIN -#define TEMP_BED_PIN 15 // Analog Input (14) +#define TEMP_BED_PIN 15 // Analog Input (14) // // Misc. Functions // -#undef PS_ON_PIN // 12 -#define PS_ON_PIN 81 // External Power Supply - -#define CASE_LIGHT_PIN 44 // Hardware PWM +#undef PS_ON_PIN // 12 +#define PS_ON_PIN 81 // External Power Supply +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN 44 // Hardware PWM +#endif // This board has headers for Z-min, Z-max and IND_S_5V *but* as the bq team // decided to ship the printer only with the probe and no additional Z-min @@ -104,8 +113,8 @@ #ifdef Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN #undef Z_MIN_PIN #undef Z_MAX_PIN - #define Z_MIN_PIN 19 // IND_S_5V - #define Z_MAX_PIN 18 // Z-MIN Label + #define Z_MIN_PIN 19 // IND_S_5V + #define Z_MAX_PIN 18 // Z-MIN Label #endif // @@ -113,5 +122,5 @@ // #if ENABLED(HEPHESTOS2_HEATED_BED_KIT) #undef HEATER_BED_PIN - #define HEATER_BED_PIN 8 + #define HEATER_BED_PIN 8 #endif diff --git a/Marlin/src/pins/ramps/pins_COPYMASTER_3D.h b/Marlin/src/pins/ramps/pins_COPYMASTER_3D.h new file mode 100644 index 000000000000..b9eee6bd5329 --- /dev/null +++ b/Marlin/src/pins/ramps/pins_COPYMASTER_3D.h @@ -0,0 +1,34 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#define BOARD_INFO_NAME "Copymaster 3D RAMPS" + +#define Z_STEP_PIN 47 +#define Y_MAX_PIN 14 +#define FIL_RUNOUT_PIN 15 +#define SD_DETECT_PIN 66 + +// +// Import RAMPS 1.4 pins +// +#include "pins_RAMPS.h" diff --git a/Marlin/src/pins/ramps/pins_DUPLICATOR_I3_PLUS.h b/Marlin/src/pins/ramps/pins_DUPLICATOR_I3_PLUS.h index 6a9897334755..87d24890c99c 100644 --- a/Marlin/src/pins/ramps/pins_DUPLICATOR_I3_PLUS.h +++ b/Marlin/src/pins/ramps/pins_DUPLICATOR_I3_PLUS.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Wanhao Duplicator i3 Plus pin assignments */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -34,68 +34,68 @@ // // Limit Switches // -#define X_STOP_PIN 54 // PF0 / A0 -#define Y_STOP_PIN 24 // PA2 / AD2 -#define Z_MIN_PIN 23 // PA1 / AD1 -#define Z_MAX_PIN 25 // PA3 / AD3 -#define SERVO0_PIN 40 // PG1 / !RD +#define X_STOP_PIN 54 // PF0 / A0 +#define Y_STOP_PIN 24 // PA2 / AD2 +#define Z_MIN_PIN 23 // PA1 / AD1 +#define Z_MAX_PIN 25 // PA3 / AD3 +#define SERVO0_PIN 40 // PG1 / !RD // // Steppers // -#define X_STEP_PIN 61 // PF7 / A7 -#define X_DIR_PIN 62 // PK0 / A8 -#define X_ENABLE_PIN 60 // PF6 / A6 +#define X_STEP_PIN 61 // PF7 / A7 +#define X_DIR_PIN 62 // PK0 / A8 +#define X_ENABLE_PIN 60 // PF6 / A6 -#define Y_STEP_PIN 64 // PK2 / A10 -#define Y_DIR_PIN 65 // PK3 / A11 -#define Y_ENABLE_PIN 63 // PK1 / A9 +#define Y_STEP_PIN 64 // PK2 / A10 +#define Y_DIR_PIN 65 // PK3 / A11 +#define Y_ENABLE_PIN 63 // PK1 / A9 -#define Z_STEP_PIN 67 // PK5 / A13 -#define Z_DIR_PIN 69 // PK7 / A15 -#define Z_ENABLE_PIN 66 // PK4 / A12 -#define Z_MIN_PROBE_PIN 25 // PA3 / AD3 +#define Z_STEP_PIN 67 // PK5 / A13 +#define Z_DIR_PIN 69 // PK7 / A15 +#define Z_ENABLE_PIN 66 // PK4 / A12 +#define Z_MIN_PROBE_PIN 25 // PA3 / AD3 -#define E0_STEP_PIN 58 // PF4 / A4 -#define E0_DIR_PIN 59 // PF5 / A5 -#define E0_ENABLE_PIN 57 // PF3 / A3 +#define E0_STEP_PIN 58 // PF4 / A4 +#define E0_DIR_PIN 59 // PF5 / A5 +#define E0_ENABLE_PIN 57 // PF3 / A3 // // Temperature Sensors // -#define TEMP_0_PIN 1 // PF1 / A1 Analog -#define TEMP_BED_PIN 14 // PK6 / A14 Analog +#define TEMP_0_PIN 1 // PF1 / A1 Analog +#define TEMP_BED_PIN 14 // PK6 / A14 Analog // // Heaters / Fans // -#define HEATER_0_PIN 4 // PG5 / PWM4 -#define HEATER_BED_PIN 3 // PE5 / PWM3 +#define HEATER_0_PIN 4 // PG5 / PWM4 +#define HEATER_BED_PIN 3 // PE5 / PWM3 -#define FAN_PIN 5 // PE3 / PWM5 +#define FAN_PIN 5 // PE3 / PWM5 // // Misc. Functions // -#define SDSS 53 // PB0 / SS -#define LED_PIN 13 // PB7 / PWM13 +#define SDSS 53 // PB0 / SS +#define LED_PIN 13 // PB7 / PWM13 -#define MISO_PIN 50 // PB3 -#define MOSI_PIN 51 // PB2 -#define SCK_PIN 52 // PB1 +#define MISO_PIN 50 // PB3 +#define MOSI_PIN 51 // PB2 +#define SCK_PIN 52 // PB1 // // LCDs and Controllers // -#if HAS_SPI_LCD +#if HAS_WIRED_LCD #if ENABLED(ZONESTAR_LCD) - #define LCD_PINS_RS 2 - #define LCD_PINS_ENABLE 36 - #define LCD_PINS_D4 37 - #define LCD_PINS_D5 34 - #define LCD_PINS_D6 35 - #define LCD_PINS_D7 32 - #define ADC_KEYPAD_PIN 12 // Analog + #define LCD_PINS_RS 2 + #define LCD_PINS_ENABLE 36 + #define LCD_PINS_D4 37 + #define LCD_PINS_D5 34 + #define LCD_PINS_D6 35 + #define LCD_PINS_D7 32 + #define ADC_KEYPAD_PIN 12 // Analog #endif #endif @@ -113,7 +113,7 @@ * # Pin | ATMEGA2560 Pin | Arduino # * ################################## * # 1 | 52 / PG1 (!RD) | 40 # - * # 2 | 95 / PF2 (A2) | 2 # + * # 2 | 95 / PF2 (A2) | 56 # * # 3 | 54 / PC1 (A9) | 36 # * # 4 | 53 / PC0 (A8) | 37 # * # 5 | 56 / PC3 (A11) | 34 # diff --git a/Marlin/src/pins/ramps/pins_FELIX2.h b/Marlin/src/pins/ramps/pins_FELIX2.h index f5a49db53302..6cc6997adc56 100644 --- a/Marlin/src/pins/ramps/pins_FELIX2.h +++ b/Marlin/src/pins/ramps/pins_FELIX2.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -35,29 +35,29 @@ // Heaters / Fans // // Power outputs EFBF or EFBE -#define MOSFET_D_PIN 7 +#define MOSFET_D_PIN 7 #include "pins_RAMPS.h" // // Misc. Functions // -#define SDPOWER_PIN 1 +#define SDPOWER_PIN 1 -#define PS_ON_PIN 12 +#define PS_ON_PIN 12 // // LCD / Controller // #if BOTH(ULTRA_LCD, NEWPANEL) - #define SD_DETECT_PIN 6 + #define SD_DETECT_PIN 6 #endif // NEWPANEL && ULTRA_LCD // // M3/M4/M5 - Spindle/Laser Control // -#undef SPINDLE_LASER_PWM_PIN // Definitions in pins_RAMPS.h are not valid with this board +#undef SPINDLE_LASER_PWM_PIN // Definitions in pins_RAMPS.h are not valid with this board #undef SPINDLE_LASER_ENA_PIN #undef SPINDLE_DIR_PIN diff --git a/Marlin/src/pins/ramps/pins_FORMBOT_RAPTOR.h b/Marlin/src/pins/ramps/pins_FORMBOT_RAPTOR.h index 3dcd7e57bc08..0877d168d60f 100644 --- a/Marlin/src/pins/ramps/pins_FORMBOT_RAPTOR.h +++ b/Marlin/src/pins/ramps/pins_FORMBOT_RAPTOR.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Formbot Raptor pin assignments */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #elif HOTENDS > 3 || E_STEPPERS > 3 #error "Formbot supports up to 3 hotends / E-steppers. Comment out this line to continue." @@ -41,90 +41,90 @@ // // Servos // -#define SERVO0_PIN 11 -#define SERVO1_PIN 6 -#define SERVO2_PIN 5 +#define SERVO0_PIN 11 +#define SERVO1_PIN 6 +#define SERVO2_PIN 5 // // Limit Switches // -#define X_MIN_PIN 3 +#define X_MIN_PIN 3 #ifndef X_MAX_PIN - #define X_MAX_PIN 2 + #define X_MAX_PIN 2 #endif -#define Y_MIN_PIN 14 -#define Y_MAX_PIN 15 -#define Z_MIN_PIN 18 -#define Z_MAX_PIN 19 +#define Y_MIN_PIN 14 +#define Y_MAX_PIN 15 +#define Z_MIN_PIN 18 +#define Z_MAX_PIN 19 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 32 + #define Z_MIN_PROBE_PIN 32 #endif // // Steppers // -#define X_STEP_PIN 54 -#define X_DIR_PIN 55 -#define X_ENABLE_PIN 38 +#define X_STEP_PIN 54 +#define X_DIR_PIN 55 +#define X_ENABLE_PIN 38 #ifndef X_CS_PIN - #define X_CS_PIN 53 + #define X_CS_PIN 53 #endif -#define Y_STEP_PIN 60 -#define Y_DIR_PIN 61 -#define Y_ENABLE_PIN 56 +#define Y_STEP_PIN 60 +#define Y_DIR_PIN 61 +#define Y_ENABLE_PIN 56 #ifndef Y_CS_PIN - #define Y_CS_PIN 49 + #define Y_CS_PIN 49 #endif -#define Z_STEP_PIN 46 -#define Z_DIR_PIN 48 -#define Z_ENABLE_PIN 62 +#define Z_STEP_PIN 46 +#define Z_DIR_PIN 48 +#define Z_ENABLE_PIN 62 #ifndef Z_CS_PIN - #define Z_CS_PIN 40 + #define Z_CS_PIN 40 #endif -#define E0_STEP_PIN 26 -#define E0_DIR_PIN 28 -#define E0_ENABLE_PIN 24 +#define E0_STEP_PIN 26 +#define E0_DIR_PIN 28 +#define E0_ENABLE_PIN 24 #ifndef E0_CS_PIN - #define E0_CS_PIN 42 + #define E0_CS_PIN 42 #endif -#define E1_STEP_PIN 36 -#define E1_DIR_PIN 34 -#define E1_ENABLE_PIN 30 +#define E1_STEP_PIN 36 +#define E1_DIR_PIN 34 +#define E1_ENABLE_PIN 30 #ifndef E1_CS_PIN - #define E1_CS_PIN 44 + #define E1_CS_PIN 44 #endif -#define E2_STEP_PIN 42 -#define E2_DIR_PIN 43 -#define E2_ENABLE_PIN 44 +#define E2_STEP_PIN 42 +#define E2_DIR_PIN 43 +#define E2_ENABLE_PIN 44 // // Temperature Sensors // -#define TEMP_0_PIN 13 // Analog Input -#define TEMP_1_PIN 15 // Analog Input -#define TEMP_BED_PIN 14 // Analog Input +#define TEMP_0_PIN 13 // Analog Input +#define TEMP_1_PIN 15 // Analog Input +#define TEMP_BED_PIN 14 // Analog Input // SPI for Max6675 or Max31855 Thermocouple #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 66 // Don't use 53 if using Display/SD card + #define MAX6675_SS_PIN 66 // Don't use 53 if using Display/SD card #else - #define MAX6675_SS_PIN 66 // Don't use 49 (SD_DETECT_PIN) + #define MAX6675_SS_PIN 66 // Don't use 49 (SD_DETECT_PIN) #endif // // Augmentation for auto-assigning RAMPS plugs // #if NONE(IS_RAMPS_EEB, IS_RAMPS_EEF, IS_RAMPS_EFB, IS_RAMPS_EFF, IS_RAMPS_SF) && !PIN_EXISTS(MOSFET_D) - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND #if TEMP_SENSOR_BED #define IS_RAMPS_EEB #else @@ -140,39 +140,41 @@ // // Heaters / Fans // -#define HEATER_0_PIN 10 -#define HEATER_1_PIN 7 -#define HEATER_BED_PIN 8 +#define HEATER_0_PIN 10 +#define HEATER_1_PIN 7 +#define HEATER_BED_PIN 8 #ifndef FAN_PIN - #define FAN_PIN 9 + #define FAN_PIN 9 #endif #ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN 57 + #define FIL_RUNOUT_PIN 57 #endif #if !HAS_FILAMENT_SENSOR - #define FAN1_PIN 4 + #define FAN1_PIN 4 #endif // // Misc. Functions // #ifndef SDSS - #define SDSS 53 + #define SDSS 53 #endif -#define LED_PIN 13 -#define LED4_PIN 5 +#define LED_PIN 13 +#define LED4_PIN 5 // Use the RAMPS 1.4 Analog input 5 on the AUX2 connector -#define FILWIDTH_PIN 5 // Analog Input +#define FILWIDTH_PIN 5 // Analog Input #ifndef PS_ON_PIN - #define PS_ON_PIN 12 + #define PS_ON_PIN 12 #endif -#define CASE_LIGHT_PIN 5 +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN 5 +#endif // // LCD / Controller @@ -180,16 +182,16 @@ // Formbot only supports REPRAP_DISCOUNT_SMART_CONTROLLER // #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) - #define BEEPER_PIN 37 - #define BTN_EN1 31 - #define BTN_EN2 33 - #define BTN_ENC 35 - #define SD_DETECT_PIN 49 - #define KILL_PIN 41 - #define LCD_PINS_RS 16 - #define LCD_PINS_ENABLE 17 - #define LCD_PINS_D4 23 - #define LCD_PINS_D5 25 - #define LCD_PINS_D6 27 - #define LCD_PINS_D7 29 + #define BEEPER_PIN 37 + #define BTN_EN1 31 + #define BTN_EN2 33 + #define BTN_ENC 35 + #define SD_DETECT_PIN 49 + #define KILL_PIN 41 + #define LCD_PINS_RS 16 + #define LCD_PINS_ENABLE 17 + #define LCD_PINS_D4 23 + #define LCD_PINS_D5 25 + #define LCD_PINS_D6 27 + #define LCD_PINS_D7 29 #endif diff --git a/Marlin/src/pins/ramps/pins_FORMBOT_RAPTOR2.h b/Marlin/src/pins/ramps/pins_FORMBOT_RAPTOR2.h index 3bbff7f8f212..843eadb432fe 100644 --- a/Marlin/src/pins/ramps/pins_FORMBOT_RAPTOR2.h +++ b/Marlin/src/pins/ramps/pins_FORMBOT_RAPTOR2.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -28,10 +28,10 @@ #define BOARD_INFO_NAME "Formbot Raptor2" #define DEFAULT_MACHINE_NAME BOARD_INFO_NAME -#define FAN_PIN 6 +#define FAN_PIN 6 #ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN 22 + #define FIL_RUNOUT_PIN 22 #endif #include "pins_FORMBOT_RAPTOR.h" @@ -42,22 +42,22 @@ // M3/M4/M5 - Spindle/Laser Control // #if HAS_CUTTER && !PIN_EXISTS(SPINDLE_LASER_ENA) - #if !NUM_SERVOS // Try to use servo connector first - #define SPINDLE_LASER_ENA_PIN 6 // Pullup or pulldown! - #define SPINDLE_LASER_PWM_PIN 4 // Hardware PWM - #define SPINDLE_DIR_PIN 5 - #elif !GREEDY_PANEL // Try to use AUX2 - #define SPINDLE_LASER_ENA_PIN 4 // Pullup or pulldown! - #define SPINDLE_LASER_PWM_PIN 44 // Hardware PWM - #define SPINDLE_DIR_PIN 65 + #if !NUM_SERVOS // Try to use servo connector first + #define SPINDLE_LASER_ENA_PIN 6 // Pullup or pulldown! + #define SPINDLE_LASER_PWM_PIN 4 // Hardware PWM + #define SPINDLE_DIR_PIN 5 + #elif !GREEDY_PANEL // Try to use AUX2 + #define SPINDLE_LASER_ENA_PIN 4 // Pullup or pulldown! + #define SPINDLE_LASER_PWM_PIN 44 // Hardware PWM + #define SPINDLE_DIR_PIN 65 #endif #endif #if ENABLED(CASE_LIGHT_ENABLE) && !PIN_EXISTS(CASE_LIGHT) - #if NUM_SERVOS <= 1 // Try to use servo connector first - #define CASE_LIGHT_PIN 6 // Hardware PWM - #elif !GREEDY_PANEL // Try to use AUX2 - #define CASE_LIGHT_PIN 44 // Hardware PWM + #if NUM_SERVOS <= 1 // Try to use servo connector first + #define CASE_LIGHT_PIN 6 // Hardware PWM + #elif !GREEDY_PANEL // Try to use AUX2 + #define CASE_LIGHT_PIN 44 // Hardware PWM #endif #endif diff --git a/Marlin/src/pins/ramps/pins_FORMBOT_TREX2PLUS.h b/Marlin/src/pins/ramps/pins_FORMBOT_TREX2PLUS.h index 1c911cd125df..75a219c177de 100644 --- a/Marlin/src/pins/ramps/pins_FORMBOT_TREX2PLUS.h +++ b/Marlin/src/pins/ramps/pins_FORMBOT_TREX2PLUS.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Formbot pin assignments */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #elif HOTENDS > 2 || E_STEPPERS > 2 #error "Formbot supports up to 2 hotends / E-steppers. Comment out this line to continue." @@ -37,91 +37,91 @@ // // Servos // -#define SERVO0_PIN 11 -#define SERVO1_PIN -1 // was 6 -#define SERVO2_PIN -1 // was 5 -#define SERVO3_PIN -1 +#define SERVO0_PIN 11 +#define SERVO1_PIN -1 // was 6 +#define SERVO2_PIN -1 // was 5 +#define SERVO3_PIN -1 // // Limit Switches // -#define X_MIN_PIN 3 +#define X_MIN_PIN 3 #ifndef X_MAX_PIN - #define X_MAX_PIN 2 + #define X_MAX_PIN 2 #endif -#define Y_MIN_PIN 14 -#define Y_MAX_PIN 15 -#define Z_MIN_PIN 18 -#define Z_MAX_PIN 19 +#define Y_MIN_PIN 14 +#define Y_MAX_PIN 15 +#define Z_MIN_PIN 18 +#define Z_MAX_PIN 19 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 32 + #define Z_MIN_PROBE_PIN 32 #endif // // Steppers // -#define X_STEP_PIN 54 -#define X_DIR_PIN 55 -#define X_ENABLE_PIN 38 +#define X_STEP_PIN 54 +#define X_DIR_PIN 55 +#define X_ENABLE_PIN 38 #ifndef X_CS_PIN - #define X_CS_PIN 53 + #define X_CS_PIN 53 #endif -#define Y_STEP_PIN 60 -#define Y_DIR_PIN 61 -#define Y_ENABLE_PIN 56 +#define Y_STEP_PIN 60 +#define Y_DIR_PIN 61 +#define Y_ENABLE_PIN 56 #ifndef Y_CS_PIN - #define Y_CS_PIN 49 + #define Y_CS_PIN 49 #endif -#define Z_STEP_PIN 46 -#define Z_DIR_PIN 48 -#define Z_ENABLE_PIN 62 +#define Z_STEP_PIN 46 +#define Z_DIR_PIN 48 +#define Z_ENABLE_PIN 62 #ifndef Z_CS_PIN - #define Z_CS_PIN 40 + #define Z_CS_PIN 40 #endif -#define E0_STEP_PIN 26 -#define E0_DIR_PIN 28 -#define E0_ENABLE_PIN 24 +#define E0_STEP_PIN 26 +#define E0_DIR_PIN 28 +#define E0_ENABLE_PIN 24 #ifndef E0_CS_PIN - #define E0_CS_PIN 42 + #define E0_CS_PIN 42 #endif -#define E1_STEP_PIN 36 -#define E1_DIR_PIN 34 -#define E1_ENABLE_PIN 30 +#define E1_STEP_PIN 36 +#define E1_DIR_PIN 34 +#define E1_ENABLE_PIN 30 #ifndef E1_CS_PIN - #define E1_CS_PIN 44 + #define E1_CS_PIN 44 #endif -#define E2_STEP_PIN 42 -#define E2_DIR_PIN 43 -#define E2_ENABLE_PIN 44 +#define E2_STEP_PIN 42 +#define E2_DIR_PIN 43 +#define E2_ENABLE_PIN 44 // // Temperature Sensors // -#define TEMP_0_PIN 13 // Analog Input -#define TEMP_1_PIN 15 // Analog Input -#define TEMP_BED_PIN 3 // Analog Input +#define TEMP_0_PIN 13 // Analog Input +#define TEMP_1_PIN 15 // Analog Input +#define TEMP_BED_PIN 3 // Analog Input // SPI for Max6675 or Max31855 Thermocouple #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 66 // Don't use 53 if using Display/SD card + #define MAX6675_SS_PIN 66 // Don't use 53 if using Display/SD card #else - #define MAX6675_SS_PIN 66 // Don't use 49 (SD_DETECT_PIN) + #define MAX6675_SS_PIN 66 // Don't use 49 (SD_DETECT_PIN) #endif // // Augmentation for auto-assigning RAMPS plugs // #if NONE(IS_RAMPS_EEB, IS_RAMPS_EEF, IS_RAMPS_EFB, IS_RAMPS_EFF, IS_RAMPS_SF) && !PIN_EXISTS(MOSFET_D) - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND #if TEMP_SENSOR_BED #define IS_RAMPS_EEB #else @@ -137,36 +137,38 @@ // // Heaters / Fans // -#define HEATER_0_PIN 10 -#define HEATER_1_PIN 7 -#define HEATER_BED_PIN 58 +#define HEATER_0_PIN 10 +#define HEATER_1_PIN 7 +#define HEATER_BED_PIN 58 -#define FAN_PIN 9 +#define FAN_PIN 9 #if HAS_FILAMENT_SENSOR - #define FIL_RUNOUT_PIN 4 - //#define FIL_RUNOUT2_PIN -1 + #define FIL_RUNOUT_PIN 4 + //#define FIL_RUNOUT2_PIN -1 #else // Though defined as a fan pin, it is utilized as a dedicated laser pin by Formbot. - #define FAN1_PIN 4 + #define FAN1_PIN 4 #endif // // Misc. Functions // -#define SDSS 53 +#define SDSS 53 #ifndef LED_PIN - #define LED_PIN 13 // The Formbot v 1 board has almost no unassigned pins on it. The Board's LED + #define LED_PIN 13 // The Formbot v 1 board has almost no unassigned pins on it. The Board's LED #endif // is a good place to get a signal to control the Max7219 LED Matrix. // Use the RAMPS 1.4 Analog input 5 on the AUX2 connector -#define FILWIDTH_PIN 5 // Analog Input +#define FILWIDTH_PIN 5 // Analog Input #ifndef PS_ON_PIN - #define PS_ON_PIN 12 + #define PS_ON_PIN 12 #endif -#define CASE_LIGHT_PIN 8 +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN 8 +#endif // // LCD / Controller @@ -175,22 +177,34 @@ // #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) #ifndef BEEPER_PIN - #define BEEPER_PIN 37 + #define BEEPER_PIN 37 #endif - #define BTN_EN1 31 - #define BTN_EN2 33 - #define BTN_ENC 35 - #define SD_DETECT_PIN 49 + #define BTN_EN1 31 + #define BTN_EN2 33 + #define BTN_ENC 35 + #define SD_DETECT_PIN 49 // Allow MAX7219 to steal the KILL pin #if !defined(KILL_PIN) && MAX7219_CLK_PIN != 41 && MAX7219_DIN_PIN != 41 && MAX7219_LOAD_PIN != 41 - #define KILL_PIN 41 + #define KILL_PIN 41 #endif - #define LCD_PINS_RS 16 - #define LCD_PINS_ENABLE 17 - #define LCD_PINS_D4 23 - #define LCD_PINS_D5 25 - #define LCD_PINS_D6 27 - #define LCD_PINS_D7 29 + #define LCD_PINS_RS 16 + #define LCD_PINS_ENABLE 17 + #define LCD_PINS_D4 23 + #define LCD_PINS_D5 25 + #define LCD_PINS_D6 27 + #define LCD_PINS_D7 29 +#endif + +#if HAS_MARLINUI_U8GLIB + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(200) + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(200) + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(200) + #endif #endif diff --git a/Marlin/src/pins/ramps/pins_FORMBOT_TREX3.h b/Marlin/src/pins/ramps/pins_FORMBOT_TREX3.h index bdcb28dac211..0470fc47e98b 100644 --- a/Marlin/src/pins/ramps/pins_FORMBOT_TREX3.h +++ b/Marlin/src/pins/ramps/pins_FORMBOT_TREX3.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Formbot pin assignments */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #elif HOTENDS > 2 || E_STEPPERS > 2 #error "Formbot supports up to 2 hotends / E-steppers. Comment out this line to continue." @@ -37,116 +37,118 @@ // // Servos // -#define SERVO0_PIN 11 -#define SERVO1_PIN -1 // was 6 -#define SERVO2_PIN -1 -#define SERVO3_PIN -1 +#define SERVO0_PIN 11 +#define SERVO1_PIN -1 // was 6 +#define SERVO2_PIN -1 +#define SERVO3_PIN -1 // // Limit Switches // -#define X_MIN_PIN 3 +#define X_MIN_PIN 3 #ifndef X_MAX_PIN - #define X_MAX_PIN 2 + #define X_MAX_PIN 2 #endif -#define Y_MIN_PIN 14 -#define Y_MAX_PIN 15 -#define Z_MIN_PIN 18 -#define Z_MAX_PIN 19 +#define Y_MIN_PIN 14 +#define Y_MAX_PIN 15 +#define Z_MIN_PIN 18 +#define Z_MAX_PIN 19 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 32 + #define Z_MIN_PROBE_PIN 32 #endif // // Steppers // -#define X_STEP_PIN 54 -#define X_DIR_PIN 55 -#define X_ENABLE_PIN 38 +#define X_STEP_PIN 54 +#define X_DIR_PIN 55 +#define X_ENABLE_PIN 38 #ifndef X_CS_PIN - #define X_CS_PIN 53 + #define X_CS_PIN 53 #endif -#define Y_STEP_PIN 60 -#define Y_DIR_PIN 61 -#define Y_ENABLE_PIN 56 +#define Y_STEP_PIN 60 +#define Y_DIR_PIN 61 +#define Y_ENABLE_PIN 56 #ifndef Y_CS_PIN - #define Y_CS_PIN 49 + #define Y_CS_PIN 49 #endif -#define Z_STEP_PIN 46 -#define Z_DIR_PIN 48 -#define Z_ENABLE_PIN 62 +#define Z_STEP_PIN 46 +#define Z_DIR_PIN 48 +#define Z_ENABLE_PIN 62 #ifndef Z_CS_PIN - #define Z_CS_PIN 40 + #define Z_CS_PIN 40 #endif -#define E0_STEP_PIN 26 -#define E0_DIR_PIN 28 -#define E0_ENABLE_PIN 24 +#define E0_STEP_PIN 26 +#define E0_DIR_PIN 28 +#define E0_ENABLE_PIN 24 #ifndef E0_CS_PIN - #define E0_CS_PIN 42 + #define E0_CS_PIN 42 #endif -#define E1_STEP_PIN 36 -#define E1_DIR_PIN 34 -#define E1_ENABLE_PIN 30 +#define E1_STEP_PIN 36 +#define E1_DIR_PIN 34 +#define E1_ENABLE_PIN 30 #ifndef E1_CS_PIN - #define E1_CS_PIN 44 + #define E1_CS_PIN 44 #endif -#define E2_STEP_PIN 42 -#define E2_DIR_PIN 43 -#define E2_ENABLE_PIN 44 +#define E2_STEP_PIN 42 +#define E2_DIR_PIN 43 +#define E2_ENABLE_PIN 44 // // Temperature Sensors // -#define TEMP_0_PIN 13 // Analog Input -#define TEMP_1_PIN 15 // Analog Input -#define TEMP_BED_PIN 14 // Analog Input +#define TEMP_0_PIN 13 // Analog Input +#define TEMP_1_PIN 15 // Analog Input +#define TEMP_BED_PIN 14 // Analog Input // SPI for Max6675 or Max31855 Thermocouple #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 66 // Don't use 53 if using Display/SD card + #define MAX6675_SS_PIN 66 // Don't use 53 if using Display/SD card #else - #define MAX6675_SS_PIN 66 // Don't use 49 (SD_DETECT_PIN) + #define MAX6675_SS_PIN 66 // Don't use 49 (SD_DETECT_PIN) #endif - - // // Heaters / Fans // -#define HEATER_0_PIN 10 -#define HEATER_1_PIN 7 -#define HEATER_BED_PIN 8 +#define HEATER_0_PIN 10 +#define HEATER_1_PIN 7 +#define HEATER_BED_PIN 8 -#define FAN_PIN 9 -#define FAN1_PIN 12 +#define FAN_PIN 9 +#define FAN1_PIN 12 -#define NUM_RUNOUT_SENSORS 2 -#define FIL_RUNOUT_PIN 22 -#define FIL_RUNOUT2_PIN 21 +#define NUM_RUNOUT_SENSORS 2 +#define FIL_RUNOUT_PIN 22 +#define FIL_RUNOUT2_PIN 21 // // Misc. Functions // -#define CASE_LIGHT_PIN 5 -#define SDSS 53 +#define SDSS 53 + #ifndef LED_PIN - #define LED_PIN 13 + #define LED_PIN 13 +#endif + +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN 5 #endif -#define SPINDLE_LASER_PWM_PIN -1 // Hardware PWM -#define SPINDLE_LASER_ENA_PIN 4 // Pullup! +#define SPINDLE_LASER_PWM_PIN -1 // Hardware PWM +#define SPINDLE_LASER_ENA_PIN 4 // Pullup! // Use the RAMPS 1.4 Analog input 5 on the AUX2 connector -#define FILWIDTH_PIN 5 // Analog Input +#define FILWIDTH_PIN 5 // Analog Input // // LCD / Controller @@ -154,20 +156,20 @@ // Formbot only supports REPRAP_DISCOUNT_SMART_CONTROLLER // #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) - #define LCD_PINS_RS 16 - #define LCD_PINS_ENABLE 17 - #define LCD_PINS_D4 23 - #define LCD_PINS_D5 25 - #define LCD_PINS_D6 27 - #define LCD_PINS_D7 29 - #define BTN_EN1 31 - #define BTN_EN2 33 - #define BTN_ENC 35 - #define SD_DETECT_PIN 49 + #define LCD_PINS_RS 16 + #define LCD_PINS_ENABLE 17 + #define LCD_PINS_D4 23 + #define LCD_PINS_D5 25 + #define LCD_PINS_D6 27 + #define LCD_PINS_D7 29 + #define BTN_EN1 31 + #define BTN_EN2 33 + #define BTN_ENC 35 + #define SD_DETECT_PIN 49 #ifndef KILL_PIN - #define KILL_PIN 41 + #define KILL_PIN 41 #endif #ifndef BEEPER_PIN - #define BEEPER_PIN 37 + #define BEEPER_PIN 37 #endif #endif diff --git a/Marlin/src/pins/ramps/pins_FYSETC_F6_13.h b/Marlin/src/pins/ramps/pins_FYSETC_F6_13.h index 475551ad6bc1..3fa3cc9e8c9c 100644 --- a/Marlin/src/pins/ramps/pins_FYSETC_F6_13.h +++ b/Marlin/src/pins/ramps/pins_FYSETC_F6_13.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,95 +25,91 @@ // FYSETC F6 1.3 (and 1.4) pin assignments // -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'FYSETC F6' in 'Tools > Board.'" #endif -#if ENABLED(SD_DETECT_INVERTED) - //#error "SD_DETECT_INVERTED must be disabled for the FYSETC_F6_13 board." -#endif - #ifndef BOARD_INFO_NAME #define BOARD_INFO_NAME "FYSETC F6 1.3" #endif -#define RESET_PIN 30 -#define SPI_FLASH_CS 83 +#define RESET_PIN 30 +#define SPI_FLASH_CS 83 // // Servos // -#define SERVO0_PIN 13 -#define SERVO1_PIN 11 // (PS_ON_PIN) -#define SERVO2_PIN 10 // (FIL_RUNOUT_PIN) -#define SERVO3_PIN 4 // (RGB_LED_G_PIN) +#define SERVO0_PIN 13 +#define SERVO1_PIN 11 // (PS_ON_PIN) +#define SERVO2_PIN 10 // (FIL_RUNOUT_PIN) +#define SERVO3_PIN 4 // (RGB_LED_G_PIN) // // Limit Switches // -#define X_MIN_PIN 63 -#define X_MAX_PIN 64 -#define Y_MIN_PIN 14 -#define Y_MAX_PIN 15 -#define Z_MIN_PIN 12 +#define X_MIN_PIN 63 +#define X_MAX_PIN 64 +#define Y_MIN_PIN 14 +#define Y_MAX_PIN 15 +#define Z_MIN_PIN 12 #ifndef Z_MAX_PIN - #define Z_MAX_PIN 9 + #define Z_MAX_PIN 9 #endif #ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN SERVO2_PIN + #define FIL_RUNOUT_PIN SERVO2_PIN #endif // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 9 // Servos pin + #define Z_MIN_PROBE_PIN 9 // Servos pin #endif // // Steppers // -#define X_STEP_PIN 54 -#define X_DIR_PIN 55 -#define X_ENABLE_PIN 38 +#define X_STEP_PIN 54 +#define X_DIR_PIN 55 +#define X_ENABLE_PIN 38 #ifndef X_CS_PIN - #define X_CS_PIN 70 + #define X_CS_PIN 70 #endif -#define Y_STEP_PIN 60 -#define Y_DIR_PIN 61 -#define Y_ENABLE_PIN 56 +#define Y_STEP_PIN 60 +#define Y_DIR_PIN 61 +#define Y_ENABLE_PIN 56 #ifndef Y_CS_PIN - #define Y_CS_PIN 39 + #define Y_CS_PIN 39 #endif -#define Z_STEP_PIN 43 -#define Z_DIR_PIN 48 -#define Z_ENABLE_PIN 58 +#define Z_STEP_PIN 43 +#define Z_DIR_PIN 48 +#define Z_ENABLE_PIN 58 #ifndef Z_CS_PIN - #define Z_CS_PIN 74 + #define Z_CS_PIN 74 #endif -#define E0_STEP_PIN 26 -#define E0_DIR_PIN 28 -#define E0_ENABLE_PIN 24 +#define E0_STEP_PIN 26 +#define E0_DIR_PIN 28 +#define E0_ENABLE_PIN 24 #ifndef E0_CS_PIN - #define E0_CS_PIN 47 + #define E0_CS_PIN 47 #endif -#define E1_STEP_PIN 36 -#define E1_DIR_PIN 34 -#define E1_ENABLE_PIN 30 +#define E1_STEP_PIN 36 +#define E1_DIR_PIN 34 +#define E1_ENABLE_PIN 30 #ifndef E1_CS_PIN - #define E1_CS_PIN 32 + #define E1_CS_PIN 32 #endif -#define E2_STEP_PIN 59 -#define E2_DIR_PIN 57 -#define E2_ENABLE_PIN 40 +#define E2_STEP_PIN 59 +#define E2_DIR_PIN 57 +#define E2_ENABLE_PIN 40 #ifndef E2_CS_PIN - #define E2_CS_PIN 42 + #define E2_CS_PIN 42 #endif // @@ -121,7 +117,7 @@ // the jumper next to the limit switch socket when using sensorless homing. // -#if HAS_TMC220x +#if HAS_TMC_UART /** * TMC2208/TMC2209 stepper drivers * @@ -129,76 +125,76 @@ * At the moment, F6 rx pins are not pc interrupt pins */ #ifndef X_SERIAL_RX_PIN - #define X_SERIAL_RX_PIN -1 // 71 + #define X_SERIAL_RX_PIN -1 // 71 #endif #ifndef X_SERIAL_TX_PIN - #define X_SERIAL_TX_PIN 72 + #define X_SERIAL_TX_PIN 72 #endif #ifndef Y_SERIAL_RX_PIN - #define Y_SERIAL_RX_PIN -1 // 73 + #define Y_SERIAL_RX_PIN -1 // 73 #endif #ifndef Y_SERIAL_TX_PIN - #define Y_SERIAL_TX_PIN 75 + #define Y_SERIAL_TX_PIN 75 #endif #ifndef Z_SERIAL_RX_PIN - #define Z_SERIAL_RX_PIN -1 // 78 + #define Z_SERIAL_RX_PIN -1 // 78 #endif #ifndef Z_SERIAL_TX_PIN - #define Z_SERIAL_TX_PIN 79 + #define Z_SERIAL_TX_PIN 79 #endif #ifndef E0_SERIAL_RX_PIN - #define E0_SERIAL_RX_PIN -1 // 76 + #define E0_SERIAL_RX_PIN -1 // 76 #endif #ifndef E0_SERIAL_TX_PIN - #define E0_SERIAL_TX_PIN 77 + #define E0_SERIAL_TX_PIN 77 #endif #ifndef E1_SERIAL_RX_PIN - #define E1_SERIAL_RX_PIN -1 // 80 + #define E1_SERIAL_RX_PIN -1 // 80 #endif #ifndef E1_SERIAL_TX_PIN - #define E1_SERIAL_TX_PIN 81 + #define E1_SERIAL_TX_PIN 81 #endif #ifndef E2_SERIAL_RX_PIN - #define E2_SERIAL_RX_PIN -1 // 22 + #define E2_SERIAL_RX_PIN -1 // 22 #endif #ifndef E2_SERIAL_TX_PIN - #define E2_SERIAL_TX_PIN 82 + #define E2_SERIAL_TX_PIN 82 #endif #endif // // Temperature Sensors // -#define TEMP_0_PIN 12 // Analog Input -#define TEMP_1_PIN 13 // Analog Input -#define TEMP_2_PIN 14 // Analog Input -#define TEMP_BED_PIN 15 // Analog Input +#define TEMP_0_PIN 12 // Analog Input +#define TEMP_1_PIN 13 // Analog Input +#define TEMP_2_PIN 14 // Analog Input +#define TEMP_BED_PIN 15 // Analog Input #ifndef FILWIDTH_PIN - #define FILWIDTH_PIN 9 // Analog Input on X+ endstop + #define FILWIDTH_PIN 9 // Analog Input on X+ endstop #endif // // Heaters / Fans // -#define HEATER_0_PIN 5 -#define HEATER_1_PIN 6 -#define HEATER_2_PIN 7 -#define HEATER_BED_PIN 8 +#define HEATER_0_PIN 5 +#define HEATER_1_PIN 6 +#define HEATER_2_PIN 7 +#define HEATER_BED_PIN 8 -#define FAN_PIN 44 -#define FAN1_PIN 45 -#define FAN2_PIN 46 +#define FAN_PIN 44 +#define FAN1_PIN 45 +#define FAN2_PIN 46 // // Misc. Functions // -#define SDSS 53 -#define LED_PIN 13 -#define KILL_PIN 41 +#define SDSS 53 +#define LED_PIN 13 +#define KILL_PIN 41 #ifndef PS_ON_PIN - #define PS_ON_PIN SERVO1_PIN + #define PS_ON_PIN SERVO1_PIN #endif /** @@ -215,69 +211,88 @@ // // LCDs and Controllers // -#define BEEPER_PIN 37 -#define SD_DETECT_PIN 49 - -#if ENABLED(FYSETC_MINI_12864) - // - // See https://wiki.fysetc.com/Mini12864_Panel/?fbclid=IwAR1FyjuNdVOOy9_xzky3qqo_WeM5h-4gpRnnWhQr_O1Ef3h0AFnFXmCehK8 - // - #define DOGLCD_A0 16 - #define DOGLCD_CS 17 - - #if ENABLED(FYSETC_GENERIC_12864_1_1) - #define LCD_BACKLIGHT_PIN 27 - #endif - - #define KILL_PIN 41 - #define LCD_RESET_PIN 23 // Must be high or open for LCD to operate normally. - // Seems to work best if left open. - - #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) - #ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN 25 - #endif - #ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN 27 +#define SD_DETECT_PIN 49 + +#if ENABLED(FYSETC_242_OLED_12864) + #define BTN_EN1 37 + #define BTN_EN2 29 + #define BTN_ENC 35 + #define BEEPER_PIN 31 + + #define LCD_PINS_DC 25 + #define LCD_PINS_RS 33 + #define DOGLCD_CS 16 + #define DOGLCD_MOSI 23 + #define DOGLCD_SCK 17 + #define DOGLCD_A0 LCD_PINS_DC + + #define KILL_PIN -1 // NC + #define NEOPIXEL_PIN 27 + +#else + #define BEEPER_PIN 37 + + #if ENABLED(FYSETC_MINI_12864) + // + // See https://wiki.fysetc.com/Mini12864_Panel/?fbclid=IwAR1FyjuNdVOOy9_xzky3qqo_WeM5h-4gpRnnWhQr_O1Ef3h0AFnFXmCehK8 + // + #define DOGLCD_A0 16 + #define DOGLCD_CS 17 + + #if ENABLED(FYSETC_GENERIC_12864_1_1) + #define LCD_BACKLIGHT_PIN 27 #endif - #ifndef RGB_LED_B_PIN - #define RGB_LED_B_PIN 29 + + #define KILL_PIN 41 + #define LCD_RESET_PIN 23 // Must be high or open for LCD to operate normally. + // Seems to work best if left open. + + #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) + #ifndef RGB_LED_R_PIN + #define RGB_LED_R_PIN 25 + #endif + #ifndef RGB_LED_G_PIN + #define RGB_LED_G_PIN 27 + #endif + #ifndef RGB_LED_B_PIN + #define RGB_LED_B_PIN 29 + #endif + #elif ENABLED(FYSETC_MINI_12864_2_1) + #define NEOPIXEL_PIN 25 #endif - #elif ENABLED(FYSETC_MINI_12864_2_1) - #define NEOPIXEL_PIN 25 - #endif -#elif HAS_GRAPHICAL_LCD + #elif HAS_MARLINUI_U8GLIB - #define LCD_PINS_RS 16 - #define LCD_PINS_ENABLE 17 - #define LCD_PINS_D4 23 - #define LCD_PINS_D5 25 - #define LCD_PINS_D6 27 - #define LCD_PINS_D7 29 + #define LCD_PINS_RS 16 + #define LCD_PINS_ENABLE 17 + #define LCD_PINS_D4 23 + #define LCD_PINS_D5 25 + #define LCD_PINS_D6 27 + #define LCD_PINS_D7 29 - #if ENABLED(MKS_MINI_12864) - #define DOGLCD_CS 25 - #define DOGLCD_A0 27 - #endif + #if ENABLED(MKS_MINI_12864) + #define DOGLCD_CS 25 + #define DOGLCD_A0 27 + #endif -#endif + #endif -#if ENABLED(NEWPANEL) - #define BTN_EN1 31 - #define BTN_EN2 33 - #define BTN_ENC 35 + #if ENABLED(NEWPANEL) + #define BTN_EN1 31 + #define BTN_EN2 33 + #define BTN_ENC 35 + #endif #endif #ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN 3 + #define RGB_LED_R_PIN 3 #endif #ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN 4 + #define RGB_LED_G_PIN 4 #endif #ifndef RGB_LED_B_PIN - #define RGB_LED_B_PIN 9 + #define RGB_LED_B_PIN 9 #endif #ifndef RGB_LED_W_PIN - #define RGB_LED_W_PIN -1 + #define RGB_LED_W_PIN -1 #endif diff --git a/Marlin/src/pins/ramps/pins_FYSETC_F6_14.h b/Marlin/src/pins/ramps/pins_FYSETC_F6_14.h index be5b92d4c17f..4280204b99d9 100644 --- a/Marlin/src/pins/ramps/pins_FYSETC_F6_14.h +++ b/Marlin/src/pins/ramps/pins_FYSETC_F6_14.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,26 +25,26 @@ // FYSETC F6 v1.4 pin assignments // -#define BOARD_NAME "FYSETC F6 1.4" +#define BOARD_INFO_NAME "FYSETC F6 1.4" -#define Z_MAX_PIN 2 +#define Z_MAX_PIN 2 -#if HAS_TMC220x +#if HAS_TMC_UART /** * TMC2208/TMC2209 stepper drivers */ - #define X_SERIAL_RX_PIN 72 - #define X_SERIAL_TX_PIN 71 - #define Y_SERIAL_RX_PIN 73 - #define Y_SERIAL_TX_PIN 78 - #define Z_SERIAL_RX_PIN 75 - #define Z_SERIAL_TX_PIN 79 - #define E0_SERIAL_RX_PIN 77 - #define E0_SERIAL_TX_PIN 81 - #define E1_SERIAL_RX_PIN 76 - #define E1_SERIAL_TX_PIN 80 - #define E2_SERIAL_RX_PIN 62 - #define E2_SERIAL_TX_PIN 82 + #define X_SERIAL_RX_PIN 72 + #define X_SERIAL_TX_PIN 71 + #define Y_SERIAL_RX_PIN 73 + #define Y_SERIAL_TX_PIN 78 + #define Z_SERIAL_RX_PIN 75 + #define Z_SERIAL_TX_PIN 79 + #define E0_SERIAL_RX_PIN 77 + #define E0_SERIAL_TX_PIN 81 + #define E1_SERIAL_RX_PIN 76 + #define E1_SERIAL_TX_PIN 80 + #define E2_SERIAL_RX_PIN 62 + #define E2_SERIAL_TX_PIN 82 #endif #include "pins_FYSETC_F6_13.h" diff --git a/Marlin/src/pins/ramps/pins_K8200.h b/Marlin/src/pins/ramps/pins_K8200.h index 605223290780..5d4d2d7022a5 100644 --- a/Marlin/src/pins/ramps/pins_K8200.h +++ b/Marlin/src/pins/ramps/pins_K8200.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/pins/ramps/pins_K8400.h b/Marlin/src/pins/ramps/pins_K8400.h index f0928b0ed11f..c36e291598eb 100644 --- a/Marlin/src/pins/ramps/pins_K8400.h +++ b/Marlin/src/pins/ramps/pins_K8400.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -40,8 +40,8 @@ // // Limit Switches // -#define X_STOP_PIN 3 -#define Y_STOP_PIN 14 +#define X_STOP_PIN 3 +#define Y_STOP_PIN 14 #undef X_MIN_PIN #undef X_MAX_PIN @@ -52,13 +52,13 @@ // Steppers // #undef E1_STEP_PIN -#define E1_STEP_PIN 32 +#define E1_STEP_PIN 32 // // Heaters / Fans // #undef HEATER_1_PIN -#define HEATER_1_PIN 11 +#define HEATER_1_PIN 11 // // Misc. Functions @@ -69,5 +69,5 @@ #if Z_STEP_PIN == 26 #undef Z_STEP_PIN - #define Z_STEP_PIN 32 + #define Z_STEP_PIN 32 #endif diff --git a/Marlin/src/pins/ramps/pins_K8600.h b/Marlin/src/pins/ramps/pins_K8600.h new file mode 100644 index 000000000000..0de01927528c --- /dev/null +++ b/Marlin/src/pins/ramps/pins_K8600.h @@ -0,0 +1,127 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * VERTEX NANO Arduino Mega with RAMPS EFB v1.4 pin assignments. + */ + +#if HOTENDS > 1 + #error "Only 1 hotend is supported for Vertex Nano." +#endif + +#define BOARD_INFO_NAME "K8600" +#define DEFAULT_MACHINE_NAME "Vertex Nano" + +// +// Limit Switches +// +#define X_MIN_PIN 3 +#define Y_MAX_PIN 14 +#define Z_MAX_PIN 18 +#define Z_MIN_PIN -1 + +// +// Heaters / Fans +// +#define FAN_PIN 8 + +// +// Misc. Functions +// +#define CASE_LIGHT_PIN 7 + +// +// Other RAMPS pins +// +#define IS_RAMPS_EFB // Override autodetection. Bed will be undefined. +#include "pins_RAMPS.h" + +// +// Steppers +// +#undef X_STEP_PIN +#undef X_DIR_PIN +#undef X_ENABLE_PIN +#define X_STEP_PIN 54 +#define X_DIR_PIN 55 +#define X_ENABLE_PIN 38 + +#undef Y_STEP_PIN +#undef Y_DIR_PIN +#undef Y_ENABLE_PIN +#define Y_STEP_PIN 60 +#define Y_DIR_PIN 61 +#define Y_ENABLE_PIN 56 + +#undef Z_ENABLE_PIN +#define Z_ENABLE_PIN 63 + +#undef E0_STEP_PIN +#undef E0_DIR_PIN +#undef E0_ENABLE_PIN +#define E0_STEP_PIN 26 +#define E0_DIR_PIN 28 +#define E0_ENABLE_PIN 24 + +// +// Heaters / Fans +// +#undef HEATER_BED_PIN + +// +// Misc. Functions +// +#undef SDSS +#define SDSS 25 // 53 + +// +// LCD / Controller +// +#if BOTH(ULTRA_LCD, NEWPANEL) + #undef BEEPER_PIN + + #undef LCD_PINS_RS + #undef LCD_PINS_ENABLE + #undef LCD_PINS_D4 + #undef LCD_PINS_D5 + #undef LCD_PINS_D6 + #undef LCD_PINS_D7 + #define LCD_PINS_RS 27 + #define LCD_PINS_ENABLE 29 + #define LCD_PINS_D4 37 + #define LCD_PINS_D5 35 + #define LCD_PINS_D6 33 + #define LCD_PINS_D7 31 + + // Buttons + #undef BTN_EN1 + #undef BTN_EN2 + #undef BTN_ENC + #define BTN_EN1 17 + #define BTN_EN2 16 + #define BTN_ENC 23 + +#else + + #define BEEPER_PIN 33 + +#endif diff --git a/Marlin/src/pins/ramps/pins_K8800.h b/Marlin/src/pins/ramps/pins_K8800.h index 8c426af17c5b..7e8c245a4158 100644 --- a/Marlin/src/pins/ramps/pins_K8800.h +++ b/Marlin/src/pins/ramps/pins_K8800.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Velleman K8800 (Vertex) */ -#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) +#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -37,73 +37,86 @@ // // Limit Switches // -#define X_STOP_PIN 3 -#define Y_STOP_PIN 14 -#define Z_MIN_PIN 68 // Used for bed leveling -#define Z_MAX_PIN 66 +#define X_STOP_PIN 3 +#define Y_STOP_PIN 14 +#define Z_STOP_PIN 66 + +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 68 +#endif + +#define FIL_RUNOUT_PIN 69 // PK7 // // Steppers // -#define X_STEP_PIN 54 -#define X_DIR_PIN 55 -#define X_ENABLE_PIN 38 - -#define Y_STEP_PIN 60 -#define Y_DIR_PIN 61 -#define Y_ENABLE_PIN 56 +#define X_STEP_PIN 54 +#define X_DIR_PIN 55 +#define X_ENABLE_PIN 38 -#define Z_STEP_PIN 46 -#define Z_DIR_PIN 48 -#define Z_ENABLE_PIN 63 +#define Y_STEP_PIN 60 +#define Y_DIR_PIN 61 +#define Y_ENABLE_PIN 56 -#define E0_STEP_PIN 26 -#define E0_DIR_PIN 28 -#define E0_ENABLE_PIN 24 +#define Z_STEP_PIN 46 +#define Z_DIR_PIN 48 +#define Z_ENABLE_PIN 63 -#define E1_STEP_PIN 32 -#define E1_DIR_PIN 34 -#define E1_ENABLE_PIN 30 +#define E0_STEP_PIN 26 +#define E0_DIR_PIN 28 +#define E0_ENABLE_PIN 24 // // Temperature Sensors // -#define TEMP_0_PIN 13 +#define TEMP_0_PIN 13 // // Heaters / Fans // -#define HEATER_0_PIN 10 -#define FAN_PIN 8 -#define CONTROLLER_FAN_PIN 9 +#define HEATER_0_PIN 10 +#define FAN_PIN 8 +#define CONTROLLER_FAN_PIN 9 // // Misc. Functions // -#define SDSS 25 +#define KILL_PIN 20 // PD1 +#define CASE_LIGHT_PIN 7 -#define FIL_RUNOUT_PIN 69 // PK7 -#define KILL_PIN 20 // PD1 +// +// SD Card +// +#define SDSS 25 +#define SD_DETECT_PIN 21 // PD0 // // LCD / Controller // -#define SD_DETECT_PIN 21 // PD0 -#define LCD_SDSS 53 -#define BEEPER_PIN 6 - -#define DOGLCD_CS 29 -#define DOGLCD_A0 27 - -#define LCD_PINS_RS 27 -#define LCD_PINS_ENABLE 29 -#define LCD_PINS_D4 37 -#define LCD_PINS_D5 35 -#define LCD_PINS_D6 33 -#define LCD_PINS_D7 31 - -#if ENABLED(NEWPANEL) - #define BTN_EN1 17 - #define BTN_EN2 16 - #define BTN_ENC 23 -#endif +#define BEEPER_PIN 6 + +#if HAS_WIRED_LCD + + #define LCD_SDSS 53 + + #define DOGLCD_CS 29 + #define DOGLCD_A0 27 + + #define LCD_PINS_RS 27 + #define LCD_PINS_ENABLE 29 + #define LCD_PINS_D4 37 + #define LCD_PINS_D5 35 + #define LCD_PINS_D6 33 + #define LCD_PINS_D7 31 + + #define LCD_CONTRAST_MIN 0 + #define LCD_CONTRAST_MAX 100 + #define DEFAULT_LCD_CONTRAST 30 + + #if ENABLED(NEWPANEL) + #define BTN_EN1 17 + #define BTN_EN2 16 + #define BTN_ENC 23 + #endif + +#endif // HAS_WIRED_LCD diff --git a/Marlin/src/pins/ramps/pins_MAKEBOARD_MINI.h b/Marlin/src/pins/ramps/pins_MAKEBOARD_MINI.h index 6a31142450ae..a42dba874f41 100644 --- a/Marlin/src/pins/ramps/pins_MAKEBOARD_MINI.h +++ b/Marlin/src/pins/ramps/pins_MAKEBOARD_MINI.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/pins/ramps/pins_MKS_BASE_10.h b/Marlin/src/pins/ramps/pins_MKS_BASE_10.h index b1010482c168..0be58653aadf 100644 --- a/Marlin/src/pins/ramps/pins_MKS_BASE_10.h +++ b/Marlin/src/pins/ramps/pins_MKS_BASE_10.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/pins/ramps/pins_MKS_BASE_14.h b/Marlin/src/pins/ramps/pins_MKS_BASE_14.h index b1564ea2c326..3612f9b894c6 100644 --- a/Marlin/src/pins/ramps/pins_MKS_BASE_14.h +++ b/Marlin/src/pins/ramps/pins_MKS_BASE_14.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -30,28 +30,32 @@ #endif #define BOARD_INFO_NAME "MKS BASE 1.4" -#define MKS_BASE_VERSION 14 +#define MKS_BASE_VERSION 14 // // Heaters / Fans // -#define FAN_PIN 9 // PH6 ** Pin18 ** PWM9 +#define FAN_PIN 9 // PH6 ** Pin18 ** PWM9 // Other Mods -#define CASE_LIGHT_PIN 11 // PB5 ** Pin24 ** PWM11 -#define SERVO3_PIN 12 // PB6 ** Pin25 ** D12 -#define PS_ON_PIN 2 // X+ // PE4 ** Pin6 ** PWM2 **MUST BE HARDWARE PWM -#define FILWIDTH_PIN 15 // Y+ // PJ0 ** Pin63 ** USART3_RX **Pin should have a pullup! -#define FIL_RUNOUT_PIN 19 // Z+ // PD2 ** Pin45 ** USART1_RX + +#define SERVO3_PIN 12 // PB6 ** Pin25 ** D12 +#define PS_ON_PIN 2 // X+ // PE4 ** Pin6 ** PWM2 **MUST BE HARDWARE PWM +#define FILWIDTH_PIN 15 // Y+ // PJ0 ** Pin63 ** USART3_RX **Pin should have a pullup! +#define FIL_RUNOUT_PIN 19 // Z+ // PD2 ** Pin45 ** USART1_RX #ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN 50 + #define RGB_LED_R_PIN 50 #endif #ifndef RGB_LED_R_PIN - #define RGB_LED_G_PIN 51 + #define RGB_LED_G_PIN 51 #endif #ifndef RGB_LED_R_PIN - #define RGB_LED_B_PIN 52 + #define RGB_LED_B_PIN 52 +#endif + +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN 11 // PB5 ** Pin24 ** PWM11 #endif #include "pins_MKS_BASE_common.h" diff --git a/Marlin/src/pins/ramps/pins_MKS_BASE_15.h b/Marlin/src/pins/ramps/pins_MKS_BASE_15.h index 683c6b7d0ee9..9e670d1bbdc8 100644 --- a/Marlin/src/pins/ramps/pins_MKS_BASE_15.h +++ b/Marlin/src/pins/ramps/pins_MKS_BASE_15.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/pins/ramps/pins_MKS_BASE_16.h b/Marlin/src/pins/ramps/pins_MKS_BASE_16.h index 985aa056b81a..42796acf8b6a 100644 --- a/Marlin/src/pins/ramps/pins_MKS_BASE_16.h +++ b/Marlin/src/pins/ramps/pins_MKS_BASE_16.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -30,30 +30,30 @@ #endif #define BOARD_INFO_NAME "MKS BASE 1.6" -#define MKS_BASE_VERSION 16 +#define MKS_BASE_VERSION 16 // // Servos // -#define SERVO1_PIN 12 // Digital 12 / Pin 25 +#define SERVO1_PIN 12 // Digital 12 / Pin 25 // // Omitted RAMPS pins // #ifndef SERVO2_PIN - #define SERVO2_PIN -1 + #define SERVO2_PIN -1 #endif #ifndef SERVO3_PIN - #define SERVO3_PIN -1 + #define SERVO3_PIN -1 #endif #ifndef FILWIDTH_PIN - #define FILWIDTH_PIN -1 + #define FILWIDTH_PIN -1 #endif #ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN -1 + #define FIL_RUNOUT_PIN -1 #endif #ifndef PS_ON_PIN - #define PS_ON_PIN -1 + #define PS_ON_PIN -1 #endif #include "pins_MKS_BASE_common.h" diff --git a/Marlin/src/pins/ramps/pins_MKS_BASE_HEROIC.h b/Marlin/src/pins/ramps/pins_MKS_BASE_HEROIC.h index 1b06657f09a9..3ce138b9751e 100644 --- a/Marlin/src/pins/ramps/pins_MKS_BASE_HEROIC.h +++ b/Marlin/src/pins/ramps/pins_MKS_BASE_HEROIC.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/pins/ramps/pins_MKS_BASE_common.h b/Marlin/src/pins/ramps/pins_MKS_BASE_common.h index 0406da560503..9047a4bcf0e6 100644 --- a/Marlin/src/pins/ramps/pins_MKS_BASE_common.h +++ b/Marlin/src/pins/ramps/pins_MKS_BASE_common.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -29,24 +29,24 @@ #define BOARD_INFO_NAME "MKS BASE" #endif -#if MKS_BASE_VERSION == 14 || MKS_BASE_VERSION == 15 +#if MKS_BASE_VERSION >= 14 // // Heaters / Fans // // Power outputs EFBF or EFBE - #define MOSFET_D_PIN 7 + #define MOSFET_D_PIN 7 // // M3/M4/M5 - Spindle/Laser Control // #if HAS_CUTTER - #define SPINDLE_LASER_PWM_PIN 2 // Hardware PWM - #define SPINDLE_LASER_ENA_PIN 15 // Pullup! - #define SPINDLE_DIR_PIN 19 + #define SPINDLE_LASER_PWM_PIN 2 // Hardware PWM + #define SPINDLE_LASER_ENA_PIN 15 // Pullup! + #define SPINDLE_DIR_PIN 19 #endif #ifndef CASE_LIGHT_PIN - #define CASE_LIGHT_PIN 2 + #define CASE_LIGHT_PIN 2 #endif #endif @@ -54,22 +54,22 @@ // // Microstepping pins // -#if MKS_BASE_VERSION >= 14 // |===== 1.4 =====|===== 1.5+ =====| - #define X_MS1_PIN 5 // PE3 | Pin 5 | PWM5 | | D3 | SERVO2_PIN - #define X_MS2_PIN 6 // PH3 | Pin 15 | PWM6 | Pin 14 | D6 | SERVO1_PIN - #define Y_MS1_PIN 59 // PF5 | Pin 92 | A5 | | | - #define Y_MS2_PIN 58 // PF4 | Pin 93 | A4 | | | - #define Z_MS1_PIN 22 // PA0 | Pin 78 | D22 | | | - #define Z_MS2_PIN 39 // PG2 | Pin 70 | D39 | | | +#if MKS_BASE_VERSION >= 14 // |===== 1.4 =====|===== 1.5+ =====| + #define X_MS1_PIN 5 // PE3 | Pin 5 | PWM5 | | D3 | SERVO2_PIN + #define X_MS2_PIN 6 // PH3 | Pin 15 | PWM6 | Pin 14 | D6 | SERVO1_PIN + #define Y_MS1_PIN 59 // PF5 | Pin 92 | A5 | | | + #define Y_MS2_PIN 58 // PF4 | Pin 93 | A4 | | | + #define Z_MS1_PIN 22 // PA0 | Pin 78 | D22 | | | + #define Z_MS2_PIN 39 // PG2 | Pin 70 | D39 | | | #if MKS_BASE_VERSION == 14 - #define E0_MS1_PIN 64 // PK2 | Pin 87 | A10 | | | - #define E0_MS2_PIN 63 // PK1 | Pin 88 | A9 | | | + #define E0_MS1_PIN 64 // PK2 | Pin 87 | A10 | | | + #define E0_MS2_PIN 63 // PK1 | Pin 88 | A9 | | | #else - #define E0_MS1_PIN 63 // PK1 | | | Pin 86 | A9 | - #define E0_MS2_PIN 64 // PK2 | | | Pin 87 | A10 | + #define E0_MS1_PIN 63 // PK1 | | | Pin 86 | A9 | + #define E0_MS2_PIN 64 // PK2 | | | Pin 87 | A10 | #endif - #define E1_MS1_PIN 57 // PF3 | Pin 94 | A3 | Pin 93 | A3 | - #define E1_MS2_PIN 4 // PG5 | Pin 1 | PWM4 | | D4 | SERVO3_PIN + #define E1_MS1_PIN 57 // PF3 | Pin 94 | A3 | Pin 93 | A3 | + #define E1_MS2_PIN 4 // PG5 | Pin 1 | PWM4 | | D4 | SERVO3_PIN #endif #include "pins_RAMPS.h" diff --git a/Marlin/src/pins/ramps/pins_MKS_GEN_13.h b/Marlin/src/pins/ramps/pins_MKS_GEN_13.h index 82a21118100a..08dd0f44bdfe 100644 --- a/Marlin/src/pins/ramps/pins_MKS_GEN_13.h +++ b/Marlin/src/pins/ramps/pins_MKS_GEN_13.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -40,7 +40,7 @@ // Heaters / Fans // // Power outputs EFBF or EFBE -#define MOSFET_D_PIN 7 +#define MOSFET_D_PIN 7 // // PSU / SERVO @@ -48,8 +48,8 @@ // If PSU_CONTROL is specified, always hijack Servo 3 // #if ENABLED(PSU_CONTROL) - #define SERVO3_PIN -1 - #define PS_ON_PIN 4 + #define SERVO3_PIN -1 + #define PS_ON_PIN 4 #endif #include "pins_RAMPS.h" @@ -104,44 +104,44 @@ // // orange/white SDCD - #define SD_DETECT_PIN 49 + #define SD_DETECT_PIN 49 // white ENCA - #define BTN_EN1 35 + #define BTN_EN1 35 // green ENCB - #define BTN_EN2 37 + #define BTN_EN2 37 // purple ENCBTN - #define BTN_ENC 31 + #define BTN_ENC 31 // brown A0 - #define DOGLCD_A0 27 + #define DOGLCD_A0 27 // green/white LCS - #define DOGLCD_CS 29 + #define DOGLCD_CS 29 // 50 gray MISO // 51 yellow MOSI // 52 orange SCK // blue SDCS - //#define SDSS 53 + //#define SDSS 53 // // VIKI2 4-wire lead // // blue BTN - #define KILL_PIN 23 + #define KILL_PIN 23 // green BUZZER - #define BEEPER_PIN 25 + #define BEEPER_PIN 25 // yellow RED-LED - #define STAT_LED_RED_PIN 16 + #define STAT_LED_RED_PIN 16 // white BLUE-LED - #define STAT_LED_BLUE_PIN 17 + #define STAT_LED_BLUE_PIN 17 #endif diff --git a/Marlin/src/pins/ramps/pins_MKS_GEN_L.h b/Marlin/src/pins/ramps/pins_MKS_GEN_L.h index ea45f912381a..522a34cda199 100644 --- a/Marlin/src/pins/ramps/pins_MKS_GEN_L.h +++ b/Marlin/src/pins/ramps/pins_MKS_GEN_L.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/pins/ramps/pins_MKS_GEN_L_V2.h b/Marlin/src/pins/ramps/pins_MKS_GEN_L_V2.h index d56bbd1e45c1..20f3dece4273 100644 --- a/Marlin/src/pins/ramps/pins_MKS_GEN_L_V2.h +++ b/Marlin/src/pins/ramps/pins_MKS_GEN_L_V2.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -35,7 +35,7 @@ // Heaters / Fans // // Power outputs EFBF or EFBE -#define MOSFET_D_PIN 7 +#define MOSFET_D_PIN 7 // // CS Pins wired to avoid conflict with the LCD @@ -43,47 +43,47 @@ // #ifndef X_CS_PIN - #define X_CS_PIN 63 + #define X_CS_PIN 63 #endif #ifndef Y_CS_PIN - #define Y_CS_PIN 64 + #define Y_CS_PIN 64 #endif #ifndef Z_CS_PIN - #define Z_CS_PIN 65 + #define Z_CS_PIN 65 #endif #ifndef E0_CS_PIN - #define E0_CS_PIN 66 + #define E0_CS_PIN 66 #endif #ifndef E1_CS_PIN - #define E1_CS_PIN 21 + #define E1_CS_PIN 21 #endif // TMC2130 Diag Pins (currently just for reference) -#define X_DIAG_PIN 3 -#define Y_DIAG_PIN 14 -#define Z_DIAG_PIN 18 -#define E0_DIAG_PIN 2 -#define E1_DIAG_PIN 15 +#define X_DIAG_PIN 3 +#define Y_DIAG_PIN 14 +#define Z_DIAG_PIN 18 +#define E0_DIAG_PIN 2 +#define E1_DIAG_PIN 15 #ifndef SERVO1_PIN - #define SERVO1_PIN 12 + #define SERVO1_PIN 12 #endif #ifndef SERVO2_PIN - #define SERVO2_PIN 39 + #define SERVO2_PIN 39 #endif #ifndef SERVO3_PIN - #define SERVO3_PIN 32 + #define SERVO3_PIN 32 #endif #ifndef E1_SERIAL_TX_PIN - #define E1_SERIAL_TX_PIN 20 + #define E1_SERIAL_TX_PIN 20 #endif #ifndef E1_SERIAL_RX_PIN - #define E1_SERIAL_RX_PIN 21 + #define E1_SERIAL_RX_PIN 21 #endif #include "pins_RAMPS.h" diff --git a/Marlin/src/pins/ramps/pins_MKS_GEN_L_V21.h b/Marlin/src/pins/ramps/pins_MKS_GEN_L_V21.h new file mode 100644 index 000000000000..24e04a39ff1f --- /dev/null +++ b/Marlin/src/pins/ramps/pins_MKS_GEN_L_V21.h @@ -0,0 +1,85 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * MKS GEN L V2 – Arduino Mega2560 with RAMPS v1.4 pin assignments + */ + +#if HOTENDS > 2 || E_STEPPERS > 2 + #error "MKS GEN L V2.1 supports up to 2 hotends / E-steppers. Comment out this line to continue." +#endif + +#define BOARD_INFO_NAME "MKS GEN L V2.1" + +// +// Heaters / Fans +// +// Power outputs EFBF or EFBE +#define MOSFET_D_PIN 7 + +// +// CS Pins wired to avoid conflict with the LCD +// See https://www.thingiverse.com/asset:66604 +// + +#ifndef X_CS_PIN + #define X_CS_PIN 63 +#endif +#ifndef Y_CS_PIN + #define Y_CS_PIN 64 +#endif +#ifndef Z_CS_PIN + #define Z_CS_PIN 65 +#endif +#ifndef E0_CS_PIN + #define E0_CS_PIN 66 +#endif +#ifndef E1_CS_PIN + #define E1_CS_PIN 12 +#endif + +// TMC2130 Diag Pins (currently just for reference) +#define X_DIAG_PIN 3 +#define Y_DIAG_PIN 14 +#define Z_DIAG_PIN 18 +#define E0_DIAG_PIN 2 +#define E1_DIAG_PIN 15 + +#ifndef SERVO1_PIN + #define SERVO1_PIN 21 +#endif +#ifndef SERVO2_PIN + #define SERVO2_PIN 39 +#endif +#ifndef SERVO3_PIN + #define SERVO3_PIN 32 +#endif + +#ifndef E1_SERIAL_TX_PIN + #define E1_SERIAL_TX_PIN 20 +#endif +#ifndef E1_SERIAL_RX_PIN + #define E1_SERIAL_RX_PIN 12 +#endif + +#include "pins_RAMPS.h" diff --git a/Marlin/src/pins/ramps/pins_ORTUR_4.h b/Marlin/src/pins/ramps/pins_ORTUR_4.h new file mode 100644 index 000000000000..cef01bf62a46 --- /dev/null +++ b/Marlin/src/pins/ramps/pins_ORTUR_4.h @@ -0,0 +1,116 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * Ortur 4 Arduino Mega based on RAMPS v1.4 pin assignments + */ + +#define BOARD_INFO_NAME "Ortur 4.3" +#define DEFAULT_MACHINE_NAME BOARD_INFO_NAME + +// +// Servos +// +#define SERVO0_PIN 29 + +// +// Limit Switches +// +#define X_MAX_PIN 18 +#define Z_MIN_PIN 63 + +#define Z_MIN_PROBE_PIN 2 +#define FIL_RUNOUT_PIN 59 + +// +// Steppers +// +#define E0_CS_PIN 44 +#define E1_CS_PIN 42 + +// +// Temperature Sensors +// +#define TEMP_0_PIN 15 // Analog Input +#define TEMP_1_PIN 13 // Analog Input + +// +// Software serial +// +#define X_SERIAL_TX_PIN 59 +#define X_SERIAL_RX_PIN 63 + +#define Y_SERIAL_TX_PIN 64 +#define Y_SERIAL_RX_PIN 40 + +#define Z_SERIAL_TX_PIN 44 +#define Z_SERIAL_RX_PIN 42 + +#define E0_SERIAL_TX_PIN 66 +#define E0_SERIAL_RX_PIN 65 + +#include "pins_RAMPS.h" + +// +// Steppers +// +#undef E0_STEP_PIN +#undef E0_DIR_PIN +#undef E0_ENABLE_PIN +#define E0_STEP_PIN 36 +#define E0_DIR_PIN 34 +#define E0_ENABLE_PIN 30 + +#undef E1_STEP_PIN +#undef E1_DIR_PIN +#undef E1_ENABLE_PIN +#define E1_STEP_PIN 26 +#define E1_DIR_PIN 28 +#define E1_ENABLE_PIN 24 + +// +// LCD / Controller +// +#if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) + #undef BEEPER_PIN + #define BEEPER_PIN 35 + + #undef LCD_PINS_RS + #undef LCD_PINS_ENABLE + #undef LCD_PINS_D4 + #define LCD_PINS_RS 27 + #define LCD_PINS_ENABLE 23 + #define LCD_PINS_D4 37 + + #undef LCD_SDSS + #undef SD_DETECT_PIN + #define LCD_SDSS 53 + #define SD_DETECT_PIN 49 + + #undef BTN_EN1 + #undef BTN_EN2 + #undef BTN_ENC + #define BTN_EN1 29 + #define BTN_EN2 25 + #define BTN_ENC 16 +#endif diff --git a/Marlin/src/pins/ramps/pins_RAMPS.h b/Marlin/src/pins/ramps/pins_RAMPS.h index 82c19dd1535f..de56d2b59d9b 100644 --- a/Marlin/src/pins/ramps/pins_RAMPS.h +++ b/Marlin/src/pins/ramps/pins_RAMPS.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -51,12 +51,13 @@ #error "Oops! Set MOTHERBOARD to an STM32F1-based board when building for STM32F1." #endif -#if NONE(IS_RAMPS_SMART, IS_RAMPS_DUO, IS_RAMPS4DUE, TARGET_LPC1768) - #if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) - #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" - #endif +#if NOT_TARGET(IS_RAMPS_SMART, IS_RAMPS_DUO, IS_RAMPS4DUE, TARGET_LPC1768, __AVR_ATmega1280__, __AVR_ATmega2560__) + #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif +// Custom flags and defines for the build +//#define BOARD_CUSTOM_BUILD_FLAGS -D__FOO__ + #ifndef BOARD_INFO_NAME #define BOARD_INFO_NAME "RAMPS 1.4" #endif @@ -66,19 +67,19 @@ // #ifndef SERVO0_PIN #ifdef IS_RAMPS_13 - #define SERVO0_PIN 7 + #define SERVO0_PIN 7 #else - #define SERVO0_PIN 11 + #define SERVO0_PIN 11 #endif #endif #ifndef SERVO1_PIN - #define SERVO1_PIN 6 + #define SERVO1_PIN 6 #endif #ifndef SERVO2_PIN - #define SERVO2_PIN 5 + #define SERVO2_PIN 5 #endif #ifndef SERVO3_PIN - #define SERVO3_PIN 4 + #define SERVO3_PIN 4 #endif // @@ -86,26 +87,26 @@ // #ifndef X_STOP_PIN #ifndef X_MIN_PIN - #define X_MIN_PIN 3 + #define X_MIN_PIN 3 #endif #ifndef X_MAX_PIN - #define X_MAX_PIN 2 + #define X_MAX_PIN 2 #endif #endif #ifndef Y_STOP_PIN #ifndef Y_MIN_PIN - #define Y_MIN_PIN 14 + #define Y_MIN_PIN 14 #endif #ifndef Y_MAX_PIN - #define Y_MAX_PIN 15 + #define Y_MAX_PIN 15 #endif #endif #ifndef Z_STOP_PIN #ifndef Z_MIN_PIN - #define Z_MIN_PIN 18 + #define Z_MIN_PIN 18 #endif #ifndef Z_MAX_PIN - #define Z_MAX_PIN 19 + #define Z_MAX_PIN 19 #endif #endif @@ -113,72 +114,74 @@ // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 32 + #define Z_MIN_PROBE_PIN 32 #endif // // Steppers // -#define X_STEP_PIN 54 -#define X_DIR_PIN 55 -#define X_ENABLE_PIN 38 +#define X_STEP_PIN 54 +#define X_DIR_PIN 55 +#define X_ENABLE_PIN 38 #ifndef X_CS_PIN - #define X_CS_PIN 53 + #define X_CS_PIN 53 #endif -#define Y_STEP_PIN 60 -#define Y_DIR_PIN 61 -#define Y_ENABLE_PIN 56 +#define Y_STEP_PIN 60 +#define Y_DIR_PIN 61 +#define Y_ENABLE_PIN 56 #ifndef Y_CS_PIN - #define Y_CS_PIN 49 + #define Y_CS_PIN 49 #endif -#define Z_STEP_PIN 46 -#define Z_DIR_PIN 48 -#define Z_ENABLE_PIN 62 +#ifndef Z_STEP_PIN + #define Z_STEP_PIN 46 +#endif +#define Z_DIR_PIN 48 +#define Z_ENABLE_PIN 62 #ifndef Z_CS_PIN - #define Z_CS_PIN 40 + #define Z_CS_PIN 40 #endif -#define E0_STEP_PIN 26 -#define E0_DIR_PIN 28 -#define E0_ENABLE_PIN 24 +#define E0_STEP_PIN 26 +#define E0_DIR_PIN 28 +#define E0_ENABLE_PIN 24 #ifndef E0_CS_PIN - #define E0_CS_PIN 42 + #define E0_CS_PIN 42 #endif -#define E1_STEP_PIN 36 -#define E1_DIR_PIN 34 -#define E1_ENABLE_PIN 30 +#define E1_STEP_PIN 36 +#define E1_DIR_PIN 34 +#define E1_ENABLE_PIN 30 #ifndef E1_CS_PIN - #define E1_CS_PIN 44 + #define E1_CS_PIN 44 #endif // // Temperature Sensors // #ifndef TEMP_0_PIN - #define TEMP_0_PIN 13 // Analog Input + #define TEMP_0_PIN 13 // Analog Input #endif #ifndef TEMP_1_PIN - #define TEMP_1_PIN 15 // Analog Input + #define TEMP_1_PIN 15 // Analog Input #endif #ifndef TEMP_BED_PIN - #define TEMP_BED_PIN 14 // Analog Input + #define TEMP_BED_PIN 14 // Analog Input #endif +// // SPI for Max6675 or Max31855 Thermocouple -#if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 66 // Don't use 53 if using Display/SD card -#else - #define MAX6675_SS_PIN 66 // Don't use 49 (SD_DETECT_PIN) +// +#ifndef MAX6675_SS_PIN + #define MAX6675_SS_PIN 66 // Don't use 53 if using Display/SD card (SDSS) or 49 (SD_DETECT_PIN) #endif // // Augmentation for auto-assigning RAMPS plugs // #if NONE(IS_RAMPS_EEB, IS_RAMPS_EEF, IS_RAMPS_EFB, IS_RAMPS_EFF, IS_RAMPS_SF) && !PIN_EXISTS(MOSFET_D) - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND #if TEMP_SENSOR_BED #define IS_RAMPS_EEB #else @@ -195,74 +198,74 @@ // Heaters / Fans // #ifndef MOSFET_D_PIN - #define MOSFET_D_PIN -1 + #define MOSFET_D_PIN -1 #endif #ifndef RAMPS_D8_PIN - #define RAMPS_D8_PIN 8 + #define RAMPS_D8_PIN 8 #endif #ifndef RAMPS_D9_PIN - #define RAMPS_D9_PIN 9 + #define RAMPS_D9_PIN 9 #endif #ifndef RAMPS_D10_PIN - #define RAMPS_D10_PIN 10 -#endif - -#define HEATER_0_PIN RAMPS_D10_PIN - -#if ENABLED(IS_RAMPS_EFB) // Hotend, Fan, Bed - #define HEATER_BED_PIN RAMPS_D8_PIN -#elif ENABLED(IS_RAMPS_EEF) // Hotend, Hotend, Fan - #define HEATER_1_PIN RAMPS_D9_PIN -#elif ENABLED(IS_RAMPS_EEB) // Hotend, Hotend, Bed - #define HEATER_1_PIN RAMPS_D9_PIN - #define HEATER_BED_PIN RAMPS_D8_PIN -#elif ENABLED(IS_RAMPS_EFF) // Hotend, Fan, Fan - #define FAN1_PIN RAMPS_D8_PIN -#elif DISABLED(IS_RAMPS_SF) // Not Spindle, Fan (i.e., "EFBF" or "EFBE") - #define HEATER_BED_PIN RAMPS_D8_PIN + #define RAMPS_D10_PIN 10 +#endif + +#define HEATER_0_PIN RAMPS_D10_PIN + +#if ENABLED(IS_RAMPS_EFB) // Hotend, Fan, Bed + #define HEATER_BED_PIN RAMPS_D8_PIN +#elif ENABLED(IS_RAMPS_EEF) // Hotend, Hotend, Fan + #define HEATER_1_PIN RAMPS_D9_PIN +#elif ENABLED(IS_RAMPS_EEB) // Hotend, Hotend, Bed + #define HEATER_1_PIN RAMPS_D9_PIN + #define HEATER_BED_PIN RAMPS_D8_PIN +#elif ENABLED(IS_RAMPS_EFF) // Hotend, Fan, Fan + #define FAN1_PIN RAMPS_D8_PIN +#elif DISABLED(IS_RAMPS_SF) // Not Spindle, Fan (i.e., "EFBF" or "EFBE") + #define HEATER_BED_PIN RAMPS_D8_PIN #if HOTENDS == 1 - #define FAN1_PIN MOSFET_D_PIN + #define FAN1_PIN MOSFET_D_PIN #else - #define HEATER_1_PIN MOSFET_D_PIN + #define HEATER_1_PIN MOSFET_D_PIN #endif #endif #ifndef FAN_PIN #if EITHER(IS_RAMPS_EFB, IS_RAMPS_EFF) // Hotend, Fan, Bed or Hotend, Fan, Fan - #define FAN_PIN RAMPS_D9_PIN + #define FAN_PIN RAMPS_D9_PIN #elif EITHER(IS_RAMPS_EEF, IS_RAMPS_SF) // Hotend, Hotend, Fan or Spindle, Fan - #define FAN_PIN RAMPS_D8_PIN - #elif ENABLED(IS_RAMPS_EEB) // Hotend, Hotend, Bed - #define FAN_PIN 4 // IO pin. Buffer needed - #else // Non-specific are "EFB" (i.e., "EFBF" or "EFBE") - #define FAN_PIN RAMPS_D9_PIN + #define FAN_PIN RAMPS_D8_PIN + #elif ENABLED(IS_RAMPS_EEB) // Hotend, Hotend, Bed + #define FAN_PIN 4 // IO pin. Buffer needed + #else // Non-specific are "EFB" (i.e., "EFBF" or "EFBE") + #define FAN_PIN RAMPS_D9_PIN #endif #endif // // Misc. Functions // -#define SDSS 53 -#define LED_PIN 13 +#define SDSS 53 +#define LED_PIN 13 #ifndef FILWIDTH_PIN - #define FILWIDTH_PIN 5 // Analog Input on AUX2 + #define FILWIDTH_PIN 5 // Analog Input on AUX2 #endif // RAMPS 1.4 DIO 4 on the servos connector #ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN 4 + #define FIL_RUNOUT_PIN 4 #endif #ifndef PS_ON_PIN - #define PS_ON_PIN 12 + #define PS_ON_PIN 12 #endif #if ENABLED(CASE_LIGHT_ENABLE) && !defined(CASE_LIGHT_PIN) && !defined(SPINDLE_LASER_ENA_PIN) - #if NUM_SERVOS <= 1 // Prefer the servo connector - #define CASE_LIGHT_PIN 6 // Hardware PWM + #if NUM_SERVOS <= 1 // Prefer the servo connector + #define CASE_LIGHT_PIN 6 // Hardware PWM #elif HAS_FREE_AUX2_PINS - #define CASE_LIGHT_PIN 44 // Hardware PWM + #define CASE_LIGHT_PIN 44 // Hardware PWM #endif #endif @@ -270,14 +273,14 @@ // M3/M4/M5 - Spindle/Laser Control // #if HAS_CUTTER && !defined(SPINDLE_LASER_ENA_PIN) - #if !NUM_SERVOS // Use servo connector if possible - #define SPINDLE_LASER_ENA_PIN 4 // Pullup or pulldown! - #define SPINDLE_LASER_PWM_PIN 6 // Hardware PWM - #define SPINDLE_DIR_PIN 5 + #if !NUM_SERVOS // Use servo connector if possible + #define SPINDLE_LASER_ENA_PIN 4 // Pullup or pulldown! + #define SPINDLE_LASER_PWM_PIN 6 // Hardware PWM + #define SPINDLE_DIR_PIN 5 #elif HAS_FREE_AUX2_PINS - #define SPINDLE_LASER_ENA_PIN 40 // Pullup or pulldown! - #define SPINDLE_LASER_PWM_PIN 44 // Hardware PWM - #define SPINDLE_DIR_PIN 65 + #define SPINDLE_LASER_ENA_PIN 40 // Pullup or pulldown! + #define SPINDLE_LASER_PWM_PIN 44 // Hardware PWM + #define SPINDLE_DIR_PIN 65 #else #error "No auto-assignable Spindle/Laser pins available." #endif @@ -288,28 +291,28 @@ // #if ENABLED(TMC_USE_SW_SPI) #ifndef TMC_SW_MOSI - #define TMC_SW_MOSI 66 + #define TMC_SW_MOSI 66 #endif #ifndef TMC_SW_MISO - #define TMC_SW_MISO 44 + #define TMC_SW_MISO 44 #endif #ifndef TMC_SW_SCK - #define TMC_SW_SCK 64 + #define TMC_SW_SCK 64 #endif #endif -#if HAS_TMC220x +#if HAS_TMC_UART /** * TMC2208/TMC2209 stepper drivers * * Hardware serial communication ports. * If undefined software serial is used according to the pins below */ - //#define X_HARDWARE_SERIAL Serial1 + //#define X_HARDWARE_SERIAL Serial1 //#define X2_HARDWARE_SERIAL Serial1 - //#define Y_HARDWARE_SERIAL Serial1 + //#define Y_HARDWARE_SERIAL Serial1 //#define Y2_HARDWARE_SERIAL Serial1 - //#define Z_HARDWARE_SERIAL Serial1 + //#define Z_HARDWARE_SERIAL Serial1 //#define Z2_HARDWARE_SERIAL Serial1 //#define E0_HARDWARE_SERIAL Serial1 //#define E1_HARDWARE_SERIAL Serial1 @@ -322,91 +325,91 @@ // #ifndef X_SERIAL_TX_PIN - #define X_SERIAL_TX_PIN 40 + #define X_SERIAL_TX_PIN 40 #endif #ifndef X_SERIAL_RX_PIN - #define X_SERIAL_RX_PIN 63 + #define X_SERIAL_RX_PIN 63 #endif #ifndef X2_SERIAL_TX_PIN - #define X2_SERIAL_TX_PIN -1 + #define X2_SERIAL_TX_PIN -1 #endif #ifndef X2_SERIAL_RX_PIN - #define X2_SERIAL_RX_PIN -1 + #define X2_SERIAL_RX_PIN -1 #endif #ifndef Y_SERIAL_TX_PIN - #define Y_SERIAL_TX_PIN 59 + #define Y_SERIAL_TX_PIN 59 #endif #ifndef Y_SERIAL_RX_PIN - #define Y_SERIAL_RX_PIN 64 + #define Y_SERIAL_RX_PIN 64 #endif #ifndef Y2_SERIAL_TX_PIN - #define Y2_SERIAL_TX_PIN -1 + #define Y2_SERIAL_TX_PIN -1 #endif #ifndef Y2_SERIAL_RX_PIN - #define Y2_SERIAL_RX_PIN -1 + #define Y2_SERIAL_RX_PIN -1 #endif #ifndef Z_SERIAL_TX_PIN - #define Z_SERIAL_TX_PIN 42 + #define Z_SERIAL_TX_PIN 42 #endif #ifndef Z_SERIAL_RX_PIN - #define Z_SERIAL_RX_PIN 65 + #define Z_SERIAL_RX_PIN 65 #endif #ifndef Z2_SERIAL_TX_PIN - #define Z2_SERIAL_TX_PIN -1 + #define Z2_SERIAL_TX_PIN -1 #endif #ifndef Z2_SERIAL_RX_PIN - #define Z2_SERIAL_RX_PIN -1 + #define Z2_SERIAL_RX_PIN -1 #endif #ifndef E0_SERIAL_TX_PIN - #define E0_SERIAL_TX_PIN 44 + #define E0_SERIAL_TX_PIN 44 #endif #ifndef E0_SERIAL_RX_PIN - #define E0_SERIAL_RX_PIN 66 + #define E0_SERIAL_RX_PIN 66 #endif #ifndef E1_SERIAL_TX_PIN - #define E1_SERIAL_TX_PIN -1 + #define E1_SERIAL_TX_PIN -1 #endif #ifndef E1_SERIAL_RX_PIN - #define E1_SERIAL_RX_PIN -1 + #define E1_SERIAL_RX_PIN -1 #endif #ifndef E2_SERIAL_TX_PIN - #define E2_SERIAL_TX_PIN -1 + #define E2_SERIAL_TX_PIN -1 #endif #ifndef E2_SERIAL_RX_PIN - #define E2_SERIAL_RX_PIN -1 + #define E2_SERIAL_RX_PIN -1 #endif #ifndef E3_SERIAL_TX_PIN - #define E3_SERIAL_TX_PIN -1 + #define E3_SERIAL_TX_PIN -1 #endif #ifndef E3_SERIAL_RX_PIN - #define E3_SERIAL_RX_PIN -1 + #define E3_SERIAL_RX_PIN -1 #endif #ifndef E4_SERIAL_TX_PIN - #define E4_SERIAL_TX_PIN -1 + #define E4_SERIAL_TX_PIN -1 #endif #ifndef E4_SERIAL_RX_PIN - #define E4_SERIAL_RX_PIN -1 + #define E4_SERIAL_RX_PIN -1 #endif #ifndef E5_SERIAL_TX_PIN - #define E5_SERIAL_TX_PIN -1 + #define E5_SERIAL_TX_PIN -1 #endif #ifndef E5_SERIAL_RX_PIN - #define E5_SERIAL_RX_PIN -1 + #define E5_SERIAL_RX_PIN -1 #endif #ifndef E6_SERIAL_TX_PIN - #define E6_SERIAL_TX_PIN -1 + #define E6_SERIAL_TX_PIN -1 #endif #ifndef E6_SERIAL_RX_PIN - #define E6_SERIAL_RX_PIN -1 + #define E6_SERIAL_RX_PIN -1 #endif #ifndef E7_SERIAL_TX_PIN - #define E7_SERIAL_TX_PIN -1 + #define E7_SERIAL_TX_PIN -1 #endif #ifndef E7_SERIAL_RX_PIN - #define E7_SERIAL_RX_PIN -1 + #define E7_SERIAL_RX_PIN -1 #endif #endif @@ -414,82 +417,86 @@ // Průša i3 MK2 Multiplexer Support // #ifndef E_MUX0_PIN - #define E_MUX0_PIN 40 // Z_CS_PIN + #define E_MUX0_PIN 40 // Z_CS_PIN #endif #ifndef E_MUX1_PIN - #define E_MUX1_PIN 42 // E0_CS_PIN + #define E_MUX1_PIN 42 // E0_CS_PIN #endif #ifndef E_MUX2_PIN - #define E_MUX2_PIN 44 // E1_CS_PIN + #define E_MUX2_PIN 44 // E1_CS_PIN #endif ////////////////////////// // LCDs and Controllers // ////////////////////////// -#if HAS_SPI_LCD +#if HAS_WIRED_LCD // // LCD Display output pins // #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) - #define LCD_PINS_RS 49 // CS chip select /SS chip slave select - #define LCD_PINS_ENABLE 51 // SID (MOSI) - #define LCD_PINS_D4 52 // SCK (CLK) clock + #define LCD_PINS_RS 49 // CS chip select /SS chip slave select + #define LCD_PINS_ENABLE 51 // SID (MOSI) + #define LCD_PINS_D4 52 // SCK (CLK) clock #elif BOTH(NEWPANEL, PANEL_ONE) - #define LCD_PINS_RS 40 - #define LCD_PINS_ENABLE 42 - #define LCD_PINS_D4 65 - #define LCD_PINS_D5 66 - #define LCD_PINS_D6 44 - #define LCD_PINS_D7 64 + #define LCD_PINS_RS 40 + #define LCD_PINS_ENABLE 42 + #define LCD_PINS_D4 65 + #define LCD_PINS_D5 66 + #define LCD_PINS_D6 44 + #define LCD_PINS_D7 64 + + #elif ENABLED(TFTGLCD_PANEL_SPI) + + #define TFTGLCD_CS 33 #else #if ENABLED(CR10_STOCKDISPLAY) - #define LCD_PINS_RS 27 - #define LCD_PINS_ENABLE 29 - #define LCD_PINS_D4 25 + #define LCD_PINS_RS 27 + #define LCD_PINS_ENABLE 29 + #define LCD_PINS_D4 25 #if DISABLED(NEWPANEL) - #define BEEPER_PIN 37 + #define BEEPER_PIN 37 #endif #elif ENABLED(ZONESTAR_LCD) - #define LCD_PINS_RS 64 - #define LCD_PINS_ENABLE 44 - #define LCD_PINS_D4 63 - #define LCD_PINS_D5 40 - #define LCD_PINS_D6 42 - #define LCD_PINS_D7 65 + #define LCD_PINS_RS 64 + #define LCD_PINS_ENABLE 44 + #define LCD_PINS_D4 63 + #define LCD_PINS_D5 40 + #define LCD_PINS_D6 42 + #define LCD_PINS_D7 65 #else #if EITHER(MKS_12864OLED, MKS_12864OLED_SSD1306) - #define LCD_PINS_DC 25 // Set as output on init - #define LCD_PINS_RS 27 // Pull low for 1s to init + #define LCD_PINS_DC 25 // Set as output on init + #define LCD_PINS_RS 27 // Pull low for 1s to init // DOGM SPI LCD Support - #define DOGLCD_CS 16 - #define DOGLCD_MOSI 17 - #define DOGLCD_SCK 23 - #define DOGLCD_A0 LCD_PINS_DC + #define DOGLCD_CS 16 + #define DOGLCD_MOSI 17 + #define DOGLCD_SCK 23 + #define DOGLCD_A0 LCD_PINS_DC #else - #define LCD_PINS_RS 16 - #define LCD_PINS_ENABLE 17 - #define LCD_PINS_D4 23 - #define LCD_PINS_D5 25 - #define LCD_PINS_D6 27 + #define LCD_PINS_RS 16 + #define LCD_PINS_ENABLE 17 + #define LCD_PINS_D4 23 + #define LCD_PINS_D5 25 + #define LCD_PINS_D6 27 #endif - #define LCD_PINS_D7 29 + #define LCD_PINS_D7 29 #if DISABLED(NEWPANEL) - #define BEEPER_PIN 33 + #define BEEPER_PIN 33 #endif #endif @@ -497,10 +504,10 @@ #if DISABLED(NEWPANEL) // Buttons attached to a shift register // Not wired yet - //#define SHIFT_CLK 38 - //#define SHIFT_LD 42 - //#define SHIFT_OUT 40 - //#define SHIFT_EN 17 + //#define SHIFT_CLK 38 + //#define SHIFT_LD 42 + //#define SHIFT_OUT 40 + //#define SHIFT_EN 17 #endif #endif @@ -512,99 +519,99 @@ #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) - #define BEEPER_PIN 37 + #define BEEPER_PIN 37 #if ENABLED(CR10_STOCKDISPLAY) - #define BTN_EN1 17 - #define BTN_EN2 23 + #define BTN_EN1 17 + #define BTN_EN2 23 #else - #define BTN_EN1 31 - #define BTN_EN2 33 + #define BTN_EN1 31 + #define BTN_EN2 33 #endif - #define BTN_ENC 35 + #define BTN_ENC 35 #ifndef SD_DETECT_PIN - #define SD_DETECT_PIN 49 + #define SD_DETECT_PIN 49 #endif #ifndef KILL_PIN - #define KILL_PIN 41 + #define KILL_PIN 41 #endif #if ENABLED(BQ_LCD_SMART_CONTROLLER) - #define LCD_BACKLIGHT_PIN 39 + #define LCD_BACKLIGHT_PIN 39 #endif #elif ENABLED(REPRAPWORLD_GRAPHICAL_LCD) - #define BTN_EN1 64 - #define BTN_EN2 59 - #define BTN_ENC 63 - #define SD_DETECT_PIN 42 + #define BTN_EN1 64 + #define BTN_EN2 59 + #define BTN_ENC 63 + #define SD_DETECT_PIN 42 #elif ENABLED(LCD_I2C_PANELOLU2) - #define BTN_EN1 47 - #define BTN_EN2 43 - #define BTN_ENC 32 - #define LCD_SDSS SDSS - #define KILL_PIN 41 + #define BTN_EN1 47 + #define BTN_EN2 43 + #define BTN_ENC 32 + #define LCD_SDSS SDSS + #define KILL_PIN 41 #elif ENABLED(LCD_I2C_VIKI) - #define BTN_EN1 40 // http://files.panucatt.com/datasheets/viki_wiring_diagram.pdf explains 40/42. - #define BTN_EN2 42 - #define BTN_ENC -1 + #define BTN_EN1 40 // https://files.panucatt.com/datasheets/viki_wiring_diagram.pdf explains 40/42. + #define BTN_EN2 42 + #define BTN_ENC -1 - #define LCD_SDSS SDSS - #define SD_DETECT_PIN 49 + #define LCD_SDSS SDSS + #define SD_DETECT_PIN 49 #elif ANY(VIKI2, miniVIKI) - #define DOGLCD_CS 45 - #define DOGLCD_A0 44 + #define DOGLCD_CS 45 + #define DOGLCD_A0 44 #define LCD_SCREEN_ROT_180 - #define BEEPER_PIN 33 - #define STAT_LED_RED_PIN 32 - #define STAT_LED_BLUE_PIN 35 + #define BEEPER_PIN 33 + #define STAT_LED_RED_PIN 32 + #define STAT_LED_BLUE_PIN 35 - #define BTN_EN1 22 - #define BTN_EN2 7 - #define BTN_ENC 39 + #define BTN_EN1 22 + #define BTN_EN2 7 + #define BTN_ENC 39 - #define SD_DETECT_PIN -1 // Pin 49 for display SD interface, 72 for easy adapter board - #define KILL_PIN 31 + #define SD_DETECT_PIN -1 // Pin 49 for display SD interface, 72 for easy adapter board + #define KILL_PIN 31 #elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) - #define DOGLCD_CS 29 - #define DOGLCD_A0 27 + #define DOGLCD_CS 29 + #define DOGLCD_A0 27 - #define BEEPER_PIN 23 - #define LCD_BACKLIGHT_PIN 33 + #define BEEPER_PIN 23 + #define LCD_BACKLIGHT_PIN 33 - #define BTN_EN1 35 - #define BTN_EN2 37 - #define BTN_ENC 31 + #define BTN_EN1 35 + #define BTN_EN2 37 + #define BTN_ENC 31 - #define LCD_SDSS SDSS - #define SD_DETECT_PIN 49 - #define KILL_PIN 41 + #define LCD_SDSS SDSS + #define SD_DETECT_PIN 49 + #define KILL_PIN 41 #elif EITHER(MKS_MINI_12864, FYSETC_MINI_12864) - #define BEEPER_PIN 37 - #define BTN_ENC 35 - #define SD_DETECT_PIN 49 + #define BEEPER_PIN 37 + #define BTN_ENC 35 + #define SD_DETECT_PIN 49 #ifndef KILL_PIN - #define KILL_PIN 41 + #define KILL_PIN 41 #endif - #if ENABLED(MKS_MINI_12864) // Added in Marlin 1.1.6 + #if ENABLED(MKS_MINI_12864) - #define DOGLCD_A0 27 - #define DOGLCD_CS 25 + #define DOGLCD_A0 27 + #define DOGLCD_CS 25 // GLCD features // Uncomment screen orientation @@ -613,50 +620,50 @@ //#define LCD_SCREEN_ROT_270 // not connected to a pin - #define LCD_BACKLIGHT_PIN -1 // 65 (MKS mini12864 can't adjust backlight by software!) + #define LCD_BACKLIGHT_PIN -1 // 65 (MKS mini12864 can't adjust backlight by software!) - #define BTN_EN1 31 - #define BTN_EN2 33 + #define BTN_EN1 31 + #define BTN_EN2 33 #elif ENABLED(FYSETC_MINI_12864) // From https://wiki.fysetc.com/Mini12864_Panel/?fbclid=IwAR1FyjuNdVOOy9_xzky3qqo_WeM5h-4gpRnnWhQr_O1Ef3h0AFnFXmCehK8 - #define DOGLCD_A0 16 - #define DOGLCD_CS 17 + #define DOGLCD_A0 16 + #define DOGLCD_CS 17 - #define BTN_EN1 33 - #define BTN_EN2 31 + #define BTN_EN1 33 + #define BTN_EN2 31 - //#define FORCE_SOFT_SPI // Use this if default of hardware SPI causes display problems - // results in LCD soft SPI mode 3, SD soft SPI mode 0 + //#define FORCE_SOFT_SPI // Use this if default of hardware SPI causes display problems + // results in LCD soft SPI mode 3, SD soft SPI mode 0 - #define LCD_RESET_PIN 23 // Must be high or open for LCD to operate normally. + #define LCD_RESET_PIN 23 // Must be high or open for LCD to operate normally. #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) #ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN 25 + #define RGB_LED_R_PIN 25 #endif #ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN 27 + #define RGB_LED_G_PIN 27 #endif #ifndef RGB_LED_B_PIN - #define RGB_LED_B_PIN 29 + #define RGB_LED_B_PIN 29 #endif #elif ENABLED(FYSETC_MINI_12864_2_1) - #define NEOPIXEL_PIN 25 + #define NEOPIXEL_PIN 25 #endif - #endif + #endif #elif ENABLED(MINIPANEL) - #define BEEPER_PIN 42 + #define BEEPER_PIN 42 // not connected to a pin - #define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65 + #define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65 - #define DOGLCD_A0 44 - #define DOGLCD_CS 66 + #define DOGLCD_A0 44 + #define DOGLCD_CS 66 // GLCD features // Uncomment screen orientation @@ -664,50 +671,105 @@ //#define LCD_SCREEN_ROT_180 //#define LCD_SCREEN_ROT_270 - #define BTN_EN1 40 - #define BTN_EN2 63 - #define BTN_ENC 59 + #define BTN_EN1 40 + #define BTN_EN2 63 + #define BTN_ENC 59 - #define SD_DETECT_PIN 49 - #define KILL_PIN 64 + #define SD_DETECT_PIN 49 + #define KILL_PIN 64 #elif ENABLED(ZONESTAR_LCD) - #define ADC_KEYPAD_PIN 12 + #define ADC_KEYPAD_PIN 12 #elif ENABLED(AZSMZ_12864) // Pins only defined for RAMPS_SMART currently + #elif IS_TFTGLCD_PANEL + + #define SD_DETECT_PIN 49 + #else // Beeper on AUX-4 - #define BEEPER_PIN 33 + #define BEEPER_PIN 33 // Buttons are directly attached to AUX-2 - #if ENABLED(REPRAPWORLD_KEYPAD) - #define SHIFT_OUT 40 - #define SHIFT_CLK 44 - #define SHIFT_LD 42 - #define BTN_EN1 64 - #define BTN_EN2 59 - #define BTN_ENC 63 - #elif ENABLED(PANEL_ONE) - #define BTN_EN1 59 // AUX2 PIN 3 - #define BTN_EN2 63 // AUX2 PIN 4 - #define BTN_ENC 49 // AUX3 PIN 7 + #if ENABLED(PANEL_ONE) + #define BTN_EN1 59 // AUX2 PIN 3 + #define BTN_EN2 63 // AUX2 PIN 4 + #define BTN_ENC 49 // AUX3 PIN 7 #else - #define BTN_EN1 37 - #define BTN_EN2 35 - #define BTN_ENC 31 + #define BTN_EN1 37 + #define BTN_EN2 35 + #define BTN_ENC 31 #endif #if ENABLED(G3D_PANEL) - #define SD_DETECT_PIN 49 - #define KILL_PIN 41 + #define SD_DETECT_PIN 49 + #define KILL_PIN 41 #endif #endif #endif // NEWPANEL -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD + +#if ENABLED(REPRAPWORLD_KEYPAD) && DISABLED(ADC_KEYPAD) + #define SHIFT_OUT 40 + #define SHIFT_CLK 44 + #define SHIFT_LD 42 + #ifndef BTN_EN1 + #define BTN_EN1 64 + #endif + #ifndef BTN_EN2 + #define BTN_EN2 59 + #endif + #ifndef BTN_ENC + #define BTN_ENC 63 + #endif +#endif + +#if BOTH(TOUCH_UI_FTDI_EVE, LCD_FYSETC_TFT81050) + + #error "CAUTION! LCD_FYSETC_TFT81050 requires wiring modifications. See 'pins_RAMPS.h' for details. Comment out this line to continue." + + /** FYSETC TFT TFT81050 display pinout + * + * Board Display + * _____ _____ + * (SCK) D52 | 1 2 | D50 (MISO) MISO | 1 2 | SCK + * (SD_CS) D53 | 3 4 | D33 (BNT_EN2) (BNT_EN2) MOD_RESET | 3 4 | SD_CS + * (MOSI) D51 | 5 6 D31 (BNT_EN1) (BNT_EN1) LCD_CS | 5 6 MOSI + * RESET | 7 8 | D49 (SD_DET) SD_DET | 7 8 | RESET + * NC | 9 10| GND GND | 9 10| 5V + * ----- ----- + * EXP2 EXP1 + * + * Needs custom cable: + * + * Board Adapter Display + * _________ + * EXP2-1 ----------- EXP1-10 + * EXP2-2 ----------- EXP1-9 + * EXP2-4 ----------- EXP1-8 + * EXP2-4 ----------- EXP1-7 + * EXP2-3 ----------- EXP1-6 + * EXP2-6 ----------- EXP1-5 + * EXP2-7 ----------- EXP1-4 + * EXP2-8 ----------- EXP1-3 + * EXP2-1 ----------- EXP1-2 + * EXP1-10 ----------- EXP1-1 + * + * NOTE: The MISO pin should not get a 5V signal. + * To fix, insert a 1N4148 diode in the MISO line. + */ + + #define BEEPER_PIN 37 + + #define SD_DETECT_PIN 49 + + #define CLCD_MOD_RESET 31 + #define CLCD_SPI_CS 33 +#endif // TOUCH_UI_FTDI_EVE && LCD_FYSETC_TFT81050 diff --git a/Marlin/src/pins/ramps/pins_RAMPS_13.h b/Marlin/src/pins/ramps/pins_RAMPS_13.h index 1eb883f4db0d..6e7c8cbab592 100644 --- a/Marlin/src/pins/ramps/pins_RAMPS_13.h +++ b/Marlin/src/pins/ramps/pins_RAMPS_13.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -31,7 +31,6 @@ * RAMPS_13_EFF (Extruder, Fan, Fan) * RAMPS_13_EEF (Extruder, Extruder, Fan) * RAMPS_13_SF (Spindle, Controller Fan) - * */ #ifndef BOARD_INFO_NAME @@ -39,4 +38,5 @@ #endif #define IS_RAMPS_13 + #include "pins_RAMPS.h" diff --git a/Marlin/src/pins/ramps/pins_RAMPS_CREALITY.h b/Marlin/src/pins/ramps/pins_RAMPS_CREALITY.h index ea2ace7e86fd..1dc898e6ca9a 100644 --- a/Marlin/src/pins/ramps/pins_RAMPS_CREALITY.h +++ b/Marlin/src/pins/ramps/pins_RAMPS_CREALITY.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -32,31 +32,37 @@ // // Power outputs EFBF or EFBE -#define MOSFET_D_PIN 7 +#define MOSFET_D_PIN 7 -#define FIL_RUNOUT_PIN 2 +#define FIL_RUNOUT_PIN 2 #if NUM_RUNOUT_SENSORS > 1 - #define FIL_RUNOUT2_PIN 15 // Creality CR-X can use dual runout sensors + #define FIL_RUNOUT2_PIN 15 // Creality CR-X can use dual runout sensors #endif -#define SD_DETECT_PIN 49 // Always define onboard SD detect +#ifndef SD_DETECT_PIN + #define SD_DETECT_PIN 49 // Always define onboard SD detect +#endif -#define PS_ON_PIN 40 // Used by CR2020 Industrial series +#ifndef PS_ON_PIN + #define PS_ON_PIN 40 // Used by CR2020 Industrial series +#endif #if ENABLED(CASE_LIGHT_ENABLE) && !defined(CASE_LIGHT_PIN) - #define CASE_LIGHT_PIN 65 + #define CASE_LIGHT_PIN 65 #endif #include "pins_RAMPS.h" #ifndef BEEPER_PIN - #define BEEPER_PIN 37 // Always define beeper pin so Play Tone works with ExtUI + #define BEEPER_PIN 37 // Always define beeper pin so Play Tone works with ExtUI #endif -#define EXP1_PIN 65 // A11 - Used by CR2020 Industrial series for case -#define EXP2_PIN 66 // A12 -#define EXP3_PIN 11 // SERVO0_PIN -#define EXP4_PIN 12 // PS_ON_PIN +#define EXP1_PIN 65 // A11 - Used by CR2020 Industrial series for case +#define EXP2_PIN 66 // A12 +#define EXP3_PIN 11 // SERVO0_PIN +#define EXP4_PIN 12 // PS_ON_PIN -#define SUICIDE_PIN 12 // Used by CR2020 Industrial series -#define SUICIDE_PIN_INVERTING true // Used by CR2020 Industrial series +#define SUICIDE_PIN 12 // Used by CR2020 Industrial series +#ifndef SUICIDE_PIN_INVERTING + #define SUICIDE_PIN_INVERTING true +#endif diff --git a/Marlin/src/pins/ramps/pins_RAMPS_DAGOMA.h b/Marlin/src/pins/ramps/pins_RAMPS_DAGOMA.h index 39aecb0bc77a..ad56b7f9d1e9 100644 --- a/Marlin/src/pins/ramps/pins_RAMPS_DAGOMA.h +++ b/Marlin/src/pins/ramps/pins_RAMPS_DAGOMA.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -27,12 +27,14 @@ #define BOARD_INFO_NAME "Dagoma3D F5 RAMPS" -#define X_STOP_PIN 2 -#define Y_STOP_PIN 3 -#define Z_STOP_PIN 15 -#define FIL_RUNOUT_PIN 39 +#define X_STOP_PIN 2 +#define Y_STOP_PIN 3 +#define Z_STOP_PIN 15 +#define FIL_RUNOUT_PIN 39 -#define ORIG_E0_AUTO_FAN_PIN 7 +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN 7 +#endif // // Import RAMPS 1.4 pins diff --git a/Marlin/src/pins/ramps/pins_RAMPS_ENDER_4.h b/Marlin/src/pins/ramps/pins_RAMPS_ENDER_4.h index d6b08a1d6806..513c7fe8d5d6 100644 --- a/Marlin/src/pins/ramps/pins_RAMPS_ENDER_4.h +++ b/Marlin/src/pins/ramps/pins_RAMPS_ENDER_4.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/pins/ramps/pins_RAMPS_OLD.h b/Marlin/src/pins/ramps/pins_RAMPS_OLD.h index aa45370e6a07..6d2dad231491 100644 --- a/Marlin/src/pins/ramps/pins_RAMPS_OLD.h +++ b/Marlin/src/pins/ramps/pins_RAMPS_OLD.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Arduino Mega with RAMPS v1.0, v1.1, v1.2 pin assignments */ -#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) +#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -37,80 +37,83 @@ // // Limit Switches // -#define X_MIN_PIN 3 -#define X_MAX_PIN 2 -#define Y_MIN_PIN 16 -#define Y_MAX_PIN 17 -#define Z_MIN_PIN 18 -#define Z_MAX_PIN 19 +#define X_MIN_PIN 3 +#define X_MAX_PIN 2 +#define Y_MIN_PIN 16 +#define Y_MAX_PIN 17 +#define Z_MIN_PIN 18 +#define Z_MAX_PIN 19 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 19 + #define Z_MIN_PROBE_PIN 19 #endif // // Steppers // -#define X_STEP_PIN 26 -#define X_DIR_PIN 28 -#define X_ENABLE_PIN 24 +#define X_STEP_PIN 26 +#define X_DIR_PIN 28 +#define X_ENABLE_PIN 24 -#define Y_STEP_PIN 38 -#define Y_DIR_PIN 40 -#define Y_ENABLE_PIN 36 +#define Y_STEP_PIN 38 +#define Y_DIR_PIN 40 +#define Y_ENABLE_PIN 36 -#define Z_STEP_PIN 44 -#define Z_DIR_PIN 46 -#define Z_ENABLE_PIN 42 +#define Z_STEP_PIN 44 +#define Z_DIR_PIN 46 +#define Z_ENABLE_PIN 42 -#define E0_STEP_PIN 32 -#define E0_DIR_PIN 34 -#define E0_ENABLE_PIN 30 +#define E0_STEP_PIN 32 +#define E0_DIR_PIN 34 +#define E0_ENABLE_PIN 30 // // Temperature Sensors // -#define TEMP_0_PIN 2 // Analog Input -#define TEMP_BED_PIN 1 // Analog Input +#define TEMP_0_PIN 2 // Analog Input +#define TEMP_BED_PIN 1 // Analog Input // SPI for Max6675 or Max31855 Thermocouple #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 66 // Don't use 53 if using Display/SD card + #define MAX6675_SS_PIN 66 // Don't use 53 if using Display/SD card #else - #define MAX6675_SS_PIN 66 // Don't use 49 (SD_DETECT_PIN) + #define MAX6675_SS_PIN 66 // Don't use 49 (SD_DETECT_PIN) #endif // // Heaters / Fans // #if ENABLED(RAMPS_V_1_0) - #define HEATER_0_PIN 12 - #define HEATER_BED_PIN -1 + #define HEATER_0_PIN 12 + #define HEATER_BED_PIN -1 #ifndef FAN_PIN - #define FAN_PIN 11 + #define FAN_PIN 11 #endif -#else // RAMPS_V_1_1 or RAMPS_V_1_2 - #define HEATER_0_PIN 10 - #define HEATER_BED_PIN 8 +#else // RAMPS_V_1_1 or RAMPS_V_1_2 + #define HEATER_0_PIN 10 + #define HEATER_BED_PIN 8 #ifndef FAN_PIN - #define FAN_PIN 9 + #define FAN_PIN 9 #endif #endif // // Misc. Functions // -#define SDPOWER_PIN 48 -#define SDSS 53 -#define LED_PIN 13 -#define CASE_LIGHT_PIN 45 // Hardware PWM +#define SDPOWER_PIN 48 +#define SDSS 53 +#define LED_PIN 13 + +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN 45 // Hardware PWM +#endif // // M3/M4/M5 - Spindle/Laser Control // -#define SPINDLE_LASER_ENA_PIN 41 // Pullup or pulldown! -#define SPINDLE_LASER_PWM_PIN 45 // Hardware PWM -#define SPINDLE_DIR_PIN 43 +#define SPINDLE_LASER_ENA_PIN 41 // Pullup or pulldown! +#define SPINDLE_LASER_PWM_PIN 45 // Hardware PWM +#define SPINDLE_DIR_PIN 43 diff --git a/Marlin/src/pins/ramps/pins_RAMPS_PLUS.h b/Marlin/src/pins/ramps/pins_RAMPS_PLUS.h index 24aa7b9c9032..9908d9494f34 100644 --- a/Marlin/src/pins/ramps/pins_RAMPS_PLUS.h +++ b/Marlin/src/pins/ramps/pins_RAMPS_PLUS.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -35,17 +35,16 @@ * RAMPS_PLUS_EFF (Extruder, Fan, Fan) * RAMPS_PLUS_EEF (Extruder, Extruder, Fan) * RAMPS_PLUS_SF (Spindle, Controller Fan) - * */ -#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) +#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif #define BOARD_INFO_NAME "RAMPS 1.4 Plus" -#define RAMPS_D8_PIN 10 -#define RAMPS_D10_PIN 8 +#define RAMPS_D8_PIN 10 +#define RAMPS_D10_PIN 8 #include "pins_RAMPS.h" @@ -60,13 +59,13 @@ #undef E1_DIR_PIN #undef E1_ENABLE_PIN -#define E0_STEP_PIN 36 -#define E0_DIR_PIN 34 -#define E0_ENABLE_PIN 30 +#define E0_STEP_PIN 36 +#define E0_DIR_PIN 34 +#define E0_ENABLE_PIN 30 -#define E1_STEP_PIN 26 -#define E1_DIR_PIN 28 -#define E1_ENABLE_PIN 24 +#define E1_STEP_PIN 26 +#define E1_DIR_PIN 28 +#define E1_ENABLE_PIN 24 #undef X_CS_PIN #undef Y_CS_PIN @@ -74,13 +73,13 @@ #undef E0_CS_PIN #undef E1_CS_PIN -#if ENABLED(ULTRA_LCD, REPRAPWORLD_GRAPHICAL_LCD, CR10_STOCKDISPLAY) && !BOTH(NEWPANEL, PANEL_ONE) +#if ENABLED(ULTRA_LCD) && NONE(REPRAPWORLD_GRAPHICAL_LCD, CR10_STOCKDISPLAY) && !BOTH(NEWPANEL, PANEL_ONE) #if DISABLED(MKS_12864OLED) || ENABLED(MKS_12864OLED_SSD1306) #undef LCD_PINS_RS - #define LCD_PINS_RS 42 // 3DYMY boards pin 16 -> 42 + #define LCD_PINS_RS 42 // 3DYMY boards pin 16 -> 42 #undef LCD_PINS_ENABLE - #define LCD_PINS_ENABLE 44 // 3DYMY boards pin 17 -> 44 + #define LCD_PINS_ENABLE 44 // 3DYMY boards pin 17 -> 44 #endif #undef LCD_PINS_D7 - #define LCD_PINS_D7 53 // 3DYMY boards pin 29 -> 53 + #define LCD_PINS_D7 53 // 3DYMY boards pin 29 -> 53 #endif diff --git a/Marlin/src/pins/ramps/pins_RIGIDBOARD.h b/Marlin/src/pins/ramps/pins_RIGIDBOARD.h index da6b6e4187fb..c43d786aa2e2 100644 --- a/Marlin/src/pins/ramps/pins_RIGIDBOARD.h +++ b/Marlin/src/pins/ramps/pins_RIGIDBOARD.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -33,15 +33,15 @@ // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 19 // Z-MAX pin J14 End Stops + #define Z_MIN_PROBE_PIN 19 // Z-MAX pin J14 End Stops #endif // // MOSFET changes // -#define RAMPS_D9_PIN 8 // FAN (by default) -#define RAMPS_D10_PIN 9 // EXTRUDER 1 -#define MOSFET_D_PIN 12 // EXTRUDER 2 or FAN +#define RAMPS_D9_PIN 8 // FAN (by default) +#define RAMPS_D10_PIN 9 // EXTRUDER 1 +#define MOSFET_D_PIN 12 // EXTRUDER 2 or FAN #include "pins_RAMPS.h" @@ -52,18 +52,18 @@ #undef E0_STEP_PIN #undef E0_DIR_PIN #undef E0_ENABLE_PIN -#define E0_STEP_PIN 36 -#define E0_DIR_PIN 34 -#define E0_ENABLE_PIN 30 +#define E0_STEP_PIN 36 +#define E0_DIR_PIN 34 +#define E0_ENABLE_PIN 30 #undef E1_STEP_PIN #undef E1_DIR_PIN #undef E1_ENABLE_PIN -#define E1_STEP_PIN 26 -#define E1_DIR_PIN 28 -#define E1_ENABLE_PIN 24 +#define E1_STEP_PIN 26 +#define E1_DIR_PIN 28 +#define E1_ENABLE_PIN 24 -#define STEPPER_RESET_PIN 41 // Stepper drivers have a reset on RigidBot +#define STEPPER_RESET_PIN 41 // Stepper drivers have a reset on RigidBot // // Temperature Sensors @@ -71,33 +71,32 @@ #undef TEMP_0_PIN #undef TEMP_1_PIN #undef TEMP_BED_PIN -#define TEMP_0_PIN 14 // Analog Input -#define TEMP_1_PIN 13 // Analog Input -#define TEMP_BED_PIN 15 // Analog Input +#define TEMP_0_PIN 14 // Analog Input +#define TEMP_1_PIN 13 // Analog Input +#define TEMP_BED_PIN 15 // Analog Input // SPI for Max6675 or Max31855 Thermocouple #undef MAX6675_SS_PIN #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 53 // Don't use pin 53 if there is even the remote possibility of using Display/SD card + #define MAX6675_SS_PIN 53 // Don't use pin 53 if there is even the remote possibility of using Display/SD card #else - #define MAX6675_SS_PIN 49 // Don't use pin 49 as this is tied to the switch inside the SD card socket to detect if there is an SD card present + #define MAX6675_SS_PIN 49 // Don't use pin 49 as this is tied to the switch inside the SD card socket to detect if there is an SD card present #endif // // Heaters / Fans // #undef HEATER_BED_PIN -#define HEATER_BED_PIN 10 +#define HEATER_BED_PIN 10 #ifndef FAN_PIN - #define FAN_PIN 8 // Same as RAMPS_13_EEF + #define FAN_PIN 8 // Same as RAMPS_13_EEF #endif // // Misc. Functions // #undef PS_ON_PIN -#define PS_ON_PIN -1 // // LCD / Controller @@ -106,33 +105,31 @@ #if ENABLED(RIGIDBOT_PANEL) #undef BEEPER_PIN - #define BEEPER_PIN -1 + #define BEEPER_PIN -1 // Direction buttons - #define BTN_UP 37 - #define BTN_DWN 35 - #define BTN_LFT 33 - #define BTN_RT 32 + #define BTN_UP 37 + #define BTN_DWN 35 + #define BTN_LFT 33 + #define BTN_RT 32 // 'R' button #undef BTN_ENC - #define BTN_ENC 31 + #define BTN_ENC 31 // Disable encoder #undef BTN_EN1 - #define BTN_EN1 -1 #undef BTN_EN2 - #define BTN_EN2 -1 #undef SD_DETECT_PIN - #define SD_DETECT_PIN 22 + #define SD_DETECT_PIN 22 #elif ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) #undef SD_DETECT_PIN - #define SD_DETECT_PIN 22 + #define SD_DETECT_PIN 22 #undef KILL_PIN - #define KILL_PIN 32 + #define KILL_PIN 32 #endif diff --git a/Marlin/src/pins/ramps/pins_RIGIDBOARD_V2.h b/Marlin/src/pins/ramps/pins_RIGIDBOARD_V2.h index eb46ec9eaafc..1428de31a22b 100644 --- a/Marlin/src/pins/ramps/pins_RIGIDBOARD_V2.h +++ b/Marlin/src/pins/ramps/pins_RIGIDBOARD_V2.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -34,18 +34,18 @@ // // I2C based DAC like on the Printrboard REVF -#define DAC_STEPPER_CURRENT +#define HAS_MOTOR_CURRENT_DAC // Channels available for DAC, For Rigidboard there are 4 #define DAC_STEPPER_ORDER { 0, 1, 2, 3 } #define DAC_STEPPER_SENSE 0.05 // sense resistors on rigidboard stepper chips are .05 value -#define DAC_STEPPER_ADDRESS 0 -#define DAC_STEPPER_MAX 4096 // was 5000 but max allowable value is actually 4096 -#define DAC_STEPPER_VREF 1 // internal Vref, gain 2x = 4.096V -#define DAC_STEPPER_GAIN 1 // value of 1 here sets gain of 2 -#define DAC_DISABLE_PIN 42 // set low to enable DAC -#define DAC_OR_ADDRESS 0x01 +#define DAC_STEPPER_ADDRESS 0 +#define DAC_STEPPER_MAX 4096 // was 5000 but max allowable value is actually 4096 +#define DAC_STEPPER_VREF 1 // internal Vref, gain 2x = 4.096V +#define DAC_STEPPER_GAIN 1 // value of 1 here sets gain of 2 +#define DAC_DISABLE_PIN 42 // set low to enable DAC +#define DAC_OR_ADDRESS 0x01 #ifndef DAC_MOTOR_CURRENT_DEFAULT #define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 } // Default drive percent - X, Y, Z, E axis diff --git a/Marlin/src/pins/ramps/pins_RL200.h b/Marlin/src/pins/ramps/pins_RL200.h index 570a9c26f94b..3fccb90276f4 100644 --- a/Marlin/src/pins/ramps/pins_RL200.h +++ b/Marlin/src/pins/ramps/pins_RL200.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -37,16 +37,16 @@ #error "You must set ([XYZ]|Z2|E0)_DRIVER_TYPE to DRV8825 in Configuration.h for RL200." #endif -#define E0_STEP_PIN 26 // (RUMBA E1 pins) -#define E0_DIR_PIN 25 -#define E0_ENABLE_PIN 27 +#define E0_STEP_PIN 26 // (RUMBA E1 pins) +#define E0_DIR_PIN 25 +#define E0_ENABLE_PIN 27 -#define E1_STEP_PIN 29 // (RUMBA E2 pins) -#define E1_DIR_PIN 28 -#define E1_ENABLE_PIN 39 +#define E1_STEP_PIN 29 // (RUMBA E2 pins) +#define E1_DIR_PIN 28 +#define E1_ENABLE_PIN 39 -#define Z2_STEP_PIN 23 // (RUMBA E0 pins) -#define Z2_DIR_PIN 22 -#define Z2_ENABLE_PIN 24 +#define Z2_STEP_PIN 23 // (RUMBA E0 pins) +#define Z2_DIR_PIN 22 +#define Z2_ENABLE_PIN 24 #include "pins_RUMBA.h" diff --git a/Marlin/src/pins/ramps/pins_RUMBA.h b/Marlin/src/pins/ramps/pins_RUMBA.h index e613b9cb6c03..5be2896e18c0 100644 --- a/Marlin/src/pins/ramps/pins_RUMBA.h +++ b/Marlin/src/pins/ramps/pins_RUMBA.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * RUMBA pin assignments */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #elif HOTENDS > 3 || E_STEPPERS > 3 #error "RUMBA supports up to 3 hotends / E-steppers. Comment out this line to continue." @@ -41,56 +41,56 @@ // // Servos // -#define SERVO0_PIN 5 +#define SERVO0_PIN 5 // // Limit Switches // -#define X_MIN_PIN 37 -#define X_MAX_PIN 36 -#define Y_MIN_PIN 35 -#define Y_MAX_PIN 34 -#define Z_MIN_PIN 33 -#define Z_MAX_PIN 32 +#define X_MIN_PIN 37 +#define X_MAX_PIN 36 +#define Y_MIN_PIN 35 +#define Y_MAX_PIN 34 +#define Z_MIN_PIN 33 +#define Z_MAX_PIN 32 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 32 + #define Z_MIN_PROBE_PIN 32 #endif // // Steppers // -#define X_STEP_PIN 17 -#define X_DIR_PIN 16 -#define X_ENABLE_PIN 48 +#define X_STEP_PIN 17 +#define X_DIR_PIN 16 +#define X_ENABLE_PIN 48 -#define Y_STEP_PIN 54 -#define Y_DIR_PIN 47 -#define Y_ENABLE_PIN 55 +#define Y_STEP_PIN 54 +#define Y_DIR_PIN 47 +#define Y_ENABLE_PIN 55 -#define Z_STEP_PIN 57 -#define Z_DIR_PIN 56 -#define Z_ENABLE_PIN 62 +#define Z_STEP_PIN 57 +#define Z_DIR_PIN 56 +#define Z_ENABLE_PIN 62 #ifndef E0_STEP_PIN - #define E0_STEP_PIN 23 - #define E0_DIR_PIN 22 - #define E0_ENABLE_PIN 24 + #define E0_STEP_PIN 23 + #define E0_DIR_PIN 22 + #define E0_ENABLE_PIN 24 #endif #ifndef E1_STEP_PIN - #define E1_STEP_PIN 26 - #define E1_DIR_PIN 25 - #define E1_ENABLE_PIN 27 + #define E1_STEP_PIN 26 + #define E1_DIR_PIN 25 + #define E1_ENABLE_PIN 27 #endif #if E1_STEP_PIN != 29 - #define E2_STEP_PIN 29 - #define E2_DIR_PIN 28 - #define E2_ENABLE_PIN 39 + #define E2_STEP_PIN 29 + #define E2_DIR_PIN 28 + #define E2_ENABLE_PIN 39 #endif // @@ -98,134 +98,137 @@ // #ifndef TEMP_0_PIN #if TEMP_SENSOR_0 == -1 - #define TEMP_0_PIN 6 // Analog Input (connector *K1* on RUMBA thermocouple ADD ON is used) + #define TEMP_0_PIN 6 // Analog Input (connector *K1* on RUMBA thermocouple ADD ON is used) #else - #define TEMP_0_PIN 15 // Analog Input (default connector for thermistor *T0* on rumba board is used) + #define TEMP_0_PIN 15 // Analog Input (default connector for thermistor *T0* on rumba board is used) #endif #endif #ifndef TEMP_1_PIN #if TEMP_SENSOR_1 == -1 - #define TEMP_1_PIN 5 // Analog Input (connector *K2* on RUMBA thermocouple ADD ON is used) + #define TEMP_1_PIN 5 // Analog Input (connector *K2* on RUMBA thermocouple ADD ON is used) #else - #define TEMP_1_PIN 14 // Analog Input (default connector for thermistor *T1* on rumba board is used) + #define TEMP_1_PIN 14 // Analog Input (default connector for thermistor *T1* on rumba board is used) #endif #endif #if TEMP_SENSOR_2 == -1 - #define TEMP_2_PIN 7 // Analog Input (connector *K3* on RUMBA thermocouple ADD ON is used <-- this can't be used when TEMP_SENSOR_BED is defined as thermocouple) + #define TEMP_2_PIN 7 // Analog Input (connector *K3* on RUMBA thermocouple ADD ON is used <-- this can't be used when TEMP_SENSOR_BED is defined as thermocouple) #else - #define TEMP_2_PIN 13 // Analog Input (default connector for thermistor *T2* on rumba board is used) + #define TEMP_2_PIN 13 // Analog Input (default connector for thermistor *T2* on rumba board is used) #endif // Optional for extruder 4 or chamber: -//#define TEMP_X_PIN 12 // Analog Input (default connector for thermistor *T3* on rumba board is used) +//#define TEMP_X_PIN 12 // Analog Input (default connector for thermistor *T3* on rumba board is used) #ifndef TEMP_CHAMBER_PIN - //#define TEMP_CHAMBER_PIN 12 // Analog Input (default connector for thermistor *T3* on rumba board is used) + //#define TEMP_CHAMBER_PIN 12 // Analog Input (default connector for thermistor *T3* on rumba board is used) #endif #if TEMP_SENSOR_BED == -1 - #define TEMP_BED_PIN 7 // Analog Input (connector *K3* on RUMBA thermocouple ADD ON is used <-- this can't be used when TEMP_SENSOR_2 is defined as thermocouple) + #define TEMP_BED_PIN 7 // Analog Input (connector *K3* on RUMBA thermocouple ADD ON is used <-- this can't be used when TEMP_SENSOR_2 is defined as thermocouple) #else - #define TEMP_BED_PIN 11 // Analog Input (default connector for thermistor *THB* on rumba board is used) + #define TEMP_BED_PIN 11 // Analog Input (default connector for thermistor *THB* on rumba board is used) #endif // // Heaters / Fans // -#define HEATER_0_PIN 2 -#define HEATER_1_PIN 3 -#define HEATER_2_PIN 6 -#define HEATER_3_PIN 8 -#define HEATER_BED_PIN 9 +#define HEATER_0_PIN 2 +#define HEATER_1_PIN 3 +#define HEATER_2_PIN 6 +#define HEATER_3_PIN 8 +#define HEATER_BED_PIN 9 #ifndef FAN_PIN - #define FAN_PIN 7 + #define FAN_PIN 7 #endif #ifndef FAN1_PIN - #define FAN1_PIN 8 + #define FAN1_PIN 8 #endif // // Misc. Functions // -#define LED_PIN 13 -#define PS_ON_PIN 45 -#define KILL_PIN 46 -#define CASE_LIGHT_PIN 45 +#define LED_PIN 13 +#define PS_ON_PIN 45 +#define KILL_PIN 46 + +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN 45 +#endif // // M3/M4/M5 - Spindle/Laser Control // #ifndef SPINDLE_LASER_PWM_PIN - #define SPINDLE_LASER_PWM_PIN 4 // Hardware PWM. Pin 4 interrupts OC0* and OC1* always in use? + #define SPINDLE_LASER_PWM_PIN 4 // Hardware PWM. Pin 4 interrupts OC0* and OC1* always in use? #endif #ifndef SPINDLE_LASER_ENA_PIN - #define SPINDLE_LASER_ENA_PIN 14 // Pullup! + #define SPINDLE_LASER_ENA_PIN 14 // Pullup! #endif #ifndef SPINDLE_DIR_PIN - #define SPINDLE_DIR_PIN 15 + #define SPINDLE_DIR_PIN 15 #endif // // LCD / Controller // #if EITHER(MKS_12864OLED, MKS_12864OLED_SSD1306) - #define LCD_PINS_DC 38 // Set as output on init - #define LCD_PINS_RS 41 // Pull low for 1s to init + #define LCD_PINS_DC 38 // Set as output on init + #define LCD_PINS_RS 41 // Pull low for 1s to init // DOGM SPI LCD Support - #define DOGLCD_CS 19 - #define DOGLCD_MOSI 42 - #define DOGLCD_SCK 18 - #define DOGLCD_A0 LCD_PINS_DC + #define DOGLCD_CS 19 + #define DOGLCD_MOSI 42 + #define DOGLCD_SCK 18 + #define DOGLCD_A0 LCD_PINS_DC #elif ENABLED(FYSETC_MINI_12864) - #define DOGLCD_CS 42 - #define DOGLCD_A0 19 - #define DOGLCD_MOSI 51 - #define DOGLCD_SCK 52 + #define DOGLCD_CS 42 + #define DOGLCD_A0 19 + #define DOGLCD_MOSI 51 + #define DOGLCD_SCK 52 - //#define FORCE_SOFT_SPI // Use this if default of hardware SPI causes display problems - // results in LCD soft SPI mode 3, SD soft SPI mode 0 + //#define FORCE_SOFT_SPI // Use this if default of hardware SPI causes display problems + // results in LCD soft SPI mode 3, SD soft SPI mode 0 - #define LCD_RESET_PIN 18 // Must be high or open for LCD to operate normally. + #define LCD_RESET_PIN 18 // Must be high or open for LCD to operate normally. #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) #ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN 41 + #define RGB_LED_R_PIN 41 #endif #ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN 38 + #define RGB_LED_G_PIN 38 #endif #ifndef RGB_LED_B_PIN - #define RGB_LED_B_PIN 40 + #define RGB_LED_B_PIN 40 #endif #elif ENABLED(FYSETC_MINI_12864_2_1) - #define NEOPIXEL_PIN 25 + #define NEOPIXEL_PIN 25 #endif #else - #define LCD_PINS_RS 19 - #define LCD_PINS_ENABLE 42 - #define LCD_PINS_D4 18 - #define LCD_PINS_D5 38 - #define LCD_PINS_D6 41 + #define LCD_PINS_RS 19 + #define LCD_PINS_ENABLE 42 + #define LCD_PINS_D4 18 + #define LCD_PINS_D5 38 + #define LCD_PINS_D6 41 #endif -#define LCD_PINS_D7 40 +#define LCD_PINS_D7 40 // // Beeper, SD Card, Encoder // -#define BEEPER_PIN 44 +#define BEEPER_PIN 44 #if ENABLED(SDSUPPORT) - #define SDSS 53 - #define SD_DETECT_PIN 49 + #define SDSS 53 + #define SD_DETECT_PIN 49 #endif #if ENABLED(NEWPANEL) - #define BTN_EN1 11 - #define BTN_EN2 12 - #define BTN_ENC 43 + #define BTN_EN1 11 + #define BTN_EN2 12 + #define BTN_ENC 43 #endif diff --git a/Marlin/src/pins/ramps/pins_RUMBA_RAISE3D.h b/Marlin/src/pins/ramps/pins_RUMBA_RAISE3D.h index 7dfa747bf450..39942613ffbf 100644 --- a/Marlin/src/pins/ramps/pins_RUMBA_RAISE3D.h +++ b/Marlin/src/pins/ramps/pins_RUMBA_RAISE3D.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/pins/ramps/pins_SAINSMART_2IN1.h b/Marlin/src/pins/ramps/pins_SAINSMART_2IN1.h index 2e944904604c..e15fc94ac4f4 100644 --- a/Marlin/src/pins/ramps/pins_SAINSMART_2IN1.h +++ b/Marlin/src/pins/ramps/pins_SAINSMART_2IN1.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/pins/ramps/pins_TANGO.h b/Marlin/src/pins/ramps/pins_TANGO.h index d3b7413fa282..715444cee216 100644 --- a/Marlin/src/pins/ramps/pins_TANGO.h +++ b/Marlin/src/pins/ramps/pins_TANGO.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -27,24 +27,26 @@ #define BOARD_INFO_NAME "Tango" -#define FAN_PIN 8 -#define FAN1_PIN -1 +#define FAN_PIN 8 +#define FAN1_PIN -1 -#define ORIG_E0_AUTO_FAN_PIN 7 +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN 7 +#endif #ifndef TEMP_0_PIN #if TEMP_SENSOR_0 == -1 - #define TEMP_0_PIN 10 // Analog Input (connector *K1* on Tango thermocouple ADD ON is used) + #define TEMP_0_PIN 10 // Analog Input (connector *K1* on Tango thermocouple ADD ON is used) #else - #define TEMP_0_PIN 15 // Analog Input (default connector for thermistor *T0* on rumba board is used) + #define TEMP_0_PIN 15 // Analog Input (default connector for thermistor *T0* on rumba board is used) #endif #endif #ifndef TEMP_1_PIN #if TEMP_SENSOR_1 == -1 - #define TEMP_1_PIN 9 // Analog Input (connector *K2* on Tango thermocouple ADD ON is used) + #define TEMP_1_PIN 9 // Analog Input (connector *K2* on Tango thermocouple ADD ON is used) #else - #define TEMP_1_PIN 14 // Analog Input (default connector for thermistor *T1* on rumba board is used) + #define TEMP_1_PIN 14 // Analog Input (default connector for thermistor *T1* on rumba board is used) #endif #endif diff --git a/Marlin/src/pins/ramps/pins_TENLOG_D3_HERO.h b/Marlin/src/pins/ramps/pins_TENLOG_D3_HERO.h new file mode 100644 index 000000000000..e7a59a69dffe --- /dev/null +++ b/Marlin/src/pins/ramps/pins_TENLOG_D3_HERO.h @@ -0,0 +1,185 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * Tenlog pin assignments + */ + +#if NOT_TARGET(__AVR_ATmega2560__) + #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" +#elif HOTENDS > 2 || E_STEPPERS > 2 + #error "Tenlog supports up to 2 hotends / E-steppers. Comment out this line to continue." +#endif + +#define BOARD_INFO_NAME "Tenlog D3 Hero" +#define DEFAULT_MACHINE_NAME BOARD_INFO_NAME + +// +// Servos +// +#define SERVO0_PIN 11 +#define SERVO1_PIN 6 +#define SERVO2_PIN -1 // Original pin 5 used for hotend fans +#define SERVO3_PIN 4 + +// +// Limit Switches +// +#define X_MIN_PIN 3 +#define X_MAX_PIN 2 +#define Y_MIN_PIN 14 +//#define Y_MAX_PIN 15 // Connected to "DJ" plug on extruder heads +#define Z_MIN_PIN 18 +#define Z_MAX_PIN 19 + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 15 // Ramps is normally 32 +#endif + +// +// Steppers +// +#define X_STEP_PIN 54 +#define X_DIR_PIN 55 +#define X_ENABLE_PIN 38 +//#ifndef X_CS_PIN + //#define X_CS_PIN 53 +//#endif + +#define X2_STEP_PIN 36 +#define X2_DIR_PIN 34 +#define X2_ENABLE_PIN 30 +//#ifndef X2_CS_PIN + //#define X2_CS_PIN 53 +//#endif + +#define Y_STEP_PIN 60 +#define Y_DIR_PIN 61 +#define Y_ENABLE_PIN 56 +//#ifndef Y_CS_PIN + //#define Y_CS_PIN 49 +//#endif + +#define Z_STEP_PIN 46 +#define Z_DIR_PIN 48 +#define Z_ENABLE_PIN 62 +//#ifndef Z_CS_PIN + //#define Z_CS_PIN 40 +//#endif + +#define Z2_STEP_PIN 65 +#define Z2_DIR_PIN 66 +#define Z2_ENABLE_PIN 64 +//#ifndef Z2_CS_PIN + //#define Z2_CS_PIN 40 +//#endif + +#define E0_STEP_PIN 26 +#define E0_DIR_PIN 28 +#define E0_ENABLE_PIN 24 +//#ifndef E0_CS_PIN + //define E0_CS_PIN 42 +//#endif + +#define E1_STEP_PIN 57 +#define E1_DIR_PIN 58 +#define E1_ENABLE_PIN 59 +//#ifndef E1_CS_PIN + //define E1_CS_PIN 44 +//#endif + +//#define E2_STEP_PIN 42 +//#define E2_DIR_PIN 43 +//#define E2_ENABLE_PIN 44 + +// +// Temperature Sensors +// +#define TEMP_0_PIN 13 // Analog Input +#define TEMP_1_PIN 15 // Analog Input +#define TEMP_BED_PIN 14 // Analog Input + +// SPI for Max6675 or Max31855 Thermocouple +#if DISABLED(SDSUPPORT) + #define MAX6675_SS_PIN -1 // Don't use 53 if using Display/SD card +#else + #define MAX6675_SS_PIN -1 // Don't use 49 (SD_DETECT_PIN) +#endif + +// +// Heaters / Fans +// +#define HEATER_0_PIN 10 +#define HEATER_1_PIN 11 +#define HEATER_BED_PIN 8 + +#define FAN_PIN 9 +#define FAN1_PIN 5 // Normall this would be a servo pin + +// XXX Runout support unknown? +//#define NUM_RUNOUT_SENSORS 0 +//#define FIL_RUNOUT_PIN 22 +//#define FIL_RUNOUT2_PIN 21 + +// +// Misc. Functions +// +//#define CASE_LIGHT_PIN 5 +#define SDSS 53 +//#ifndef LED_PIN + //#define LED_PIN 13 +//#endif + +//#define SPINDLE_LASER_PWM_PIN -1 // Hardware PWM +//#define SPINDLE_LASER_ENA_PIN 4 // Pullup! + +// Use the RAMPS 1.4 Analog input 5 on the AUX2 connector +//#define FILWIDTH_PIN 5 // Analog Input + +// +// LCD / Controller +// + +//#if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) + +#define LCD_PINS_RS -1 +#define LCD_PINS_ENABLE -1 +#define LCD_PINS_D4 -1 +#define LCD_PINS_D5 -1 +#define LCD_PINS_D6 -1 +#define LCD_PINS_D7 -1 +//#define BTN_EN1 31 +//#define BTN_EN2 33 +//#define BTN_ENC 35 +#define SD_DETECT_PIN 49 +//#ifndef KILL_PIN + //#define KILL_PIN 41 +//#endif +//#ifndef BEEPER_PIN +#define BEEPER_PIN -1 +//#endif + +//#endif // REPRAP_DISCOUNT_SMART_CONTROLLER diff --git a/Marlin/src/pins/ramps/pins_TRIGORILLA_13.h b/Marlin/src/pins/ramps/pins_TRIGORILLA_13.h index c0b863035404..9508be0173d6 100644 --- a/Marlin/src/pins/ramps/pins_TRIGORILLA_13.h +++ b/Marlin/src/pins/ramps/pins_TRIGORILLA_13.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -28,9 +28,12 @@ #define BOARD_INFO_NAME "Anycubic RAMPS 1.3" #define IS_RAMPS_EFB -#define RAMPS_D9_PIN 44 -#define FAN2_PIN 9 -#define ORIG_E0_AUTO_FAN_PIN 9 +#define RAMPS_D9_PIN 44 +#define FAN2_PIN 9 + +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN 9 +#endif #include "pins_RAMPS_13.h" diff --git a/Marlin/src/pins/ramps/pins_TRIGORILLA_14.h b/Marlin/src/pins/ramps/pins_TRIGORILLA_14.h index 1c5ea39279d5..1c2cb609579e 100644 --- a/Marlin/src/pins/ramps/pins_TRIGORILLA_14.h +++ b/Marlin/src/pins/ramps/pins_TRIGORILLA_14.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -27,63 +27,100 @@ #define BOARD_INFO_NAME "Anycubic RAMPS 1.4" +// Board labeled pins: + +#define TG_HEATER_BED_PIN 8 +#define TG_HEATER_0_PIN 10 +#define TG_HEATER_1_PIN 45 // Anycubic Kossel: Unused + +#define TG_FAN0_PIN 9 // Anycubic Kossel: Usually the part cooling fan +#define TG_FAN1_PIN 7 // Anycubic Kossel: Unused +#define TG_FAN2_PIN 44 // Anycubic Kossel: Hotend fan + // // Servos // #if MB(TRIGORILLA_14_11) - #define SERVO0_PIN 5 - #define SERVO1_PIN 4 - #define SERVO2_PIN 11 - #define SERVO3_PIN 6 + #define SERVO0_PIN 5 + #define SERVO1_PIN 4 + #define SERVO2_PIN 11 + #define SERVO3_PIN 6 #endif -// -// Custom Limit Switches -// -//#define ANYCUBIC_4_MAX_PRO_ENDSTOPS -#if ENABLED(ANYCUBIC_4_MAX_PRO_ENDSTOPS) - #define X_MAX_PIN 43 - #define Y_MIN_PIN 19 -#endif - -// Labeled pins -#define TRIGORILLA_HEATER_BED_PIN 8 -#define TRIGORILLA_HEATER_0_PIN 10 -#define TRIGORILLA_HEATER_1_PIN 45 // Anycubic Kossel: Unused - -#define TRIGORILLA_FAN0_PIN 9 // Anycubic Kossel: Usually the part cooling fan -#define TRIGORILLA_FAN1_PIN 7 // Anycubic Kossel: Unused -#define TRIGORILLA_FAN2_PIN 44 // Anycubic Kossel: Hotend fan - // Remap MOSFET pins to common usages: -#define RAMPS_D10_PIN TRIGORILLA_HEATER_0_PIN // HEATER_0_PIN is always RAMPS_D10_PIN in pins_RAMPS.h +#define RAMPS_D10_PIN TG_HEATER_0_PIN // HEATER_0_PIN is always RAMPS_D10_PIN in pins_RAMPS.h -#if HOTENDS > 1 // EEF and EEB - #define RAMPS_D9_PIN TRIGORILLA_HEATER_1_PIN +#if HAS_MULTI_HOTEND // EEF and EEB + #define RAMPS_D9_PIN TG_HEATER_1_PIN #if !TEMP_SENSOR_BED // EEF - #define RAMPS_D8_PIN TRIGORILLA_FAN0_PIN + #define RAMPS_D8_PIN TG_FAN0_PIN #else // EEB - #define RAMPS_D8_PIN TRIGORILLA_HEATER_BED_PIN - #define FAN_PIN TRIGORILLA_FAN0_PIN // Override pin 4 in pins_RAMPS.h + #define RAMPS_D8_PIN TG_HEATER_BED_PIN + #define FAN_PIN TG_FAN0_PIN // Override pin 4 in pins_RAMPS.h #endif #elif TEMP_SENSOR_BED // EFB (Anycubic Kossel default) - #define RAMPS_D9_PIN TRIGORILLA_FAN0_PIN - #define RAMPS_D8_PIN TRIGORILLA_HEATER_BED_PIN + #define RAMPS_D9_PIN TG_FAN0_PIN + #if ENABLED(ANYCUBIC_LCD_CHIRON) + #define RAMPS_D8_PIN TG_HEATER_1_PIN // Heated bed is connected to HEATER1 output + #else + #define RAMPS_D8_PIN TG_HEATER_BED_PIN + #endif #else // EFF - #define RAMPS_D9_PIN TRIGORILLA_FAN1_PIN - #define RAMPS_D8_PIN TRIGORILLA_FAN0_PIN + #define RAMPS_D9_PIN TG_FAN1_PIN + #define RAMPS_D8_PIN TG_FAN0_PIN +#endif + +#if HAS_MULTI_HOTEND || TEMP_SENSOR_BED // EEF, EEB, EFB + #define FAN1_PIN TG_FAN1_PIN #endif +#define FAN2_PIN TG_FAN2_PIN -#if HOTENDS > 1 || TEMP_SENSOR_BED // EEF, EEB, EFB - #define FAN1_PIN TRIGORILLA_FAN1_PIN +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN TG_FAN2_PIN // Used in Anycubic Kossel example config +#endif + +#if ENABLED(ANYCUBIC_LCD_I3MEGA) + #define CONTROLLER_FAN_PIN TG_FAN1_PIN +#endif + +// +// AnyCubic standard pin mappings +// +// On most printers, endstops are NOT all wired to the appropriate pins on the Trigorilla board. +// For instance, on a Chiron, Y axis goes to an aux connector. +// There are also other things that have been wired in creative ways. +// To enable PIN definitions for a specific printer model, #define the appropriate symbol after +// MOTHERBOARD in Configuration.h + +// +// Limit Switches +// +//#define ANYCUBIC_4_MAX_PRO_ENDSTOPS + +#if ENABLED(ANYCUBIC_4_MAX_PRO_ENDSTOPS) + #define X_MAX_PIN 43 + #define Y_STOP_PIN 19 +#elif EITHER(ANYCUBIC_LCD_CHIRON, ANYCUBIC_LCD_I3MEGA) + #define Y_STOP_PIN 42 + #define Z2_MIN_PIN 43 + #ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 2 + #endif + #ifndef FIL_RUNOUT_PIN + #if ENABLED(ANYCUBIC_LCD_CHIRON) + #define FIL_RUNOUT_PIN 33 + #else + #define FIL_RUNOUT_PIN 19 + #endif + #endif + #define BEEPER_PIN 31 + #define SD_DETECT_PIN 49 #endif -#define FAN2_PIN TRIGORILLA_FAN2_PIN -#define ORIG_E0_AUTO_FAN_PIN TRIGORILLA_FAN2_PIN // Used in Anycubic Kossel example config #include "pins_RAMPS.h" @@ -91,30 +128,30 @@ // AnyCubic made the following changes to 1.1.0-RC8 // If these are appropriate for your LCD let us know. // -#if 0 && HAS_SPI_LCD +#if 0 && HAS_WIRED_LCD // LCD Display output pins #if BOTH(NEWPANEL, PANEL_ONE) #undef LCD_PINS_D6 - #define LCD_PINS_D6 57 + #define LCD_PINS_D6 57 #endif // LCD Display input pins #if ENABLED(NEWPANEL) #if ANY(VIKI2, miniVIKI) #undef DOGLCD_A0 - #define DOGLCD_A0 23 + #define DOGLCD_A0 23 #elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) #undef BEEPER_PIN - #define BEEPER_PIN 33 + #define BEEPER_PIN 33 #undef LCD_BACKLIGHT_PIN - #define LCD_BACKLIGHT_PIN 67 + #define LCD_BACKLIGHT_PIN 67 #endif #elif ENABLED(MINIPANEL) #undef BEEPER_PIN - #define BEEPER_PIN 33 + #define BEEPER_PIN 33 #undef DOGLCD_A0 - #define DOGLCD_A0 42 + #define DOGLCD_A0 42 #endif -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD diff --git a/Marlin/src/pins/ramps/pins_TRONXY_V3_1_0.h b/Marlin/src/pins/ramps/pins_TRONXY_V3_1_0.h index 92ed852867e9..f342eff8aa6c 100644 --- a/Marlin/src/pins/ramps/pins_TRONXY_V3_1_0.h +++ b/Marlin/src/pins/ramps/pins_TRONXY_V3_1_0.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Arduino Mega for Tronxy X5S-2E, etc. */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #elif HOTENDS > 2 || E_STEPPERS > 2 #error "TRONXY-V3-1.0 supports only 2 hotends/E-steppers. Comment out this line to continue." diff --git a/Marlin/src/pins/ramps/pins_TT_OSCAR.h b/Marlin/src/pins/ramps/pins_TT_OSCAR.h index 3b2d3c8b8d92..1568288e69bc 100644 --- a/Marlin/src/pins/ramps/pins_TT_OSCAR.h +++ b/Marlin/src/pins/ramps/pins_TT_OSCAR.h @@ -16,11 +16,11 @@ * 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 . + * along with this program. If not, see . * */ -#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) +#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -34,72 +34,72 @@ // // Servos // -#define SERVO0_PIN 11 -#define SERVO1_PIN 12 -#define SERVO2_PIN 5 -#define SERVO3_PIN 4 +#define SERVO0_PIN 11 +#define SERVO1_PIN 12 +#define SERVO2_PIN 5 +#define SERVO3_PIN 4 // // Limit Switches // -#define X_MIN_PIN 3 -#define X_MAX_PIN 2 -#define Y_MIN_PIN 14 -#define Y_MAX_PIN 15 -#define Z_MIN_PIN 18 -#define Z_MAX_PIN 19 +#define X_MIN_PIN 3 +#define X_MAX_PIN 2 +#define Y_MIN_PIN 14 +#define Y_MAX_PIN 15 +#define Z_MIN_PIN 18 +#define Z_MAX_PIN 19 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN SERVO3_PIN + #define Z_MIN_PROBE_PIN SERVO3_PIN #endif // // Steppers // -#define X_STEP_PIN 54 -#define X_DIR_PIN 55 -#define X_ENABLE_PIN 38 -#define X_CS_PIN 57 - -#define Y_STEP_PIN 60 -#define Y_DIR_PIN 61 -#define Y_ENABLE_PIN 56 -#define Y_CS_PIN 58 - -#define Z_STEP_PIN 46 -#define Z_DIR_PIN 48 -#define Z_ENABLE_PIN 62 -#define Z_CS_PIN 53 - -#define E0_STEP_PIN 26 -#define E0_DIR_PIN 28 -#define E0_ENABLE_PIN 24 -#define E0_CS_PIN 49 - -#define E1_STEP_PIN 36 -#define E1_DIR_PIN 34 -#define E1_ENABLE_PIN 30 -#define E1_CS_PIN E0_CS_PIN - -#define E2_STEP_PIN 63 -#define E2_DIR_PIN 22 -#define E2_ENABLE_PIN 59 -#define E2_CS_PIN E0_CS_PIN - -#define E3_STEP_PIN 32 -#define E3_DIR_PIN 40 -#define E3_ENABLE_PIN 39 -#define E3_CS_PIN E0_CS_PIN - -#define E4_STEP_PIN 43 -#define E4_DIR_PIN 42 -#define E4_ENABLE_PIN 47 -#define E4_CS_PIN E0_CS_PIN - -#if HAS_TMC220x +#define X_STEP_PIN 54 +#define X_DIR_PIN 55 +#define X_ENABLE_PIN 38 +#define X_CS_PIN 57 + +#define Y_STEP_PIN 60 +#define Y_DIR_PIN 61 +#define Y_ENABLE_PIN 56 +#define Y_CS_PIN 58 + +#define Z_STEP_PIN 46 +#define Z_DIR_PIN 48 +#define Z_ENABLE_PIN 62 +#define Z_CS_PIN 53 + +#define E0_STEP_PIN 26 +#define E0_DIR_PIN 28 +#define E0_ENABLE_PIN 24 +#define E0_CS_PIN 49 + +#define E1_STEP_PIN 36 +#define E1_DIR_PIN 34 +#define E1_ENABLE_PIN 30 +#define E1_CS_PIN E0_CS_PIN + +#define E2_STEP_PIN 63 +#define E2_DIR_PIN 22 +#define E2_ENABLE_PIN 59 +#define E2_CS_PIN E0_CS_PIN + +#define E3_STEP_PIN 32 +#define E3_DIR_PIN 40 +#define E3_ENABLE_PIN 39 +#define E3_CS_PIN E0_CS_PIN + +#define E4_STEP_PIN 43 +#define E4_DIR_PIN 42 +#define E4_ENABLE_PIN 47 +#define E4_CS_PIN E0_CS_PIN + +#if HAS_TMC_UART /** * TMC2208/TMC2209 stepper drivers * @@ -122,34 +122,34 @@ // Software serial // - #define X_SERIAL_TX_PIN -1 // 59 - #define X_SERIAL_RX_PIN -1 // 63 - #define X2_SERIAL_TX_PIN -1 - #define X2_SERIAL_RX_PIN -1 - - #define Y_SERIAL_TX_PIN -1 // 64 - #define Y_SERIAL_RX_PIN -1 // 40 - #define Y2_SERIAL_TX_PIN -1 - #define Y2_SERIAL_RX_PIN -1 - - #define Z_SERIAL_TX_PIN -1 // 44 - #define Z_SERIAL_RX_PIN -1 // 42 - #define Z2_SERIAL_TX_PIN -1 - #define Z2_SERIAL_RX_PIN -1 - - #define E0_SERIAL_TX_PIN -1 // 66 - #define E0_SERIAL_RX_PIN -1 // 65 - #define E1_SERIAL_TX_PIN -1 - #define E1_SERIAL_RX_PIN -1 - #define E2_SERIAL_TX_PIN -1 - #define E2_SERIAL_RX_PIN -1 - #define E3_SERIAL_TX_PIN -1 - #define E3_SERIAL_RX_PIN -1 - #define E4_SERIAL_TX_PIN -1 - #define E4_SERIAL_RX_PIN -1 - #define E5_SERIAL_RX_PIN -1 - #define E6_SERIAL_RX_PIN -1 - #define E7_SERIAL_RX_PIN -1 + #define X_SERIAL_TX_PIN -1 // 59 + #define X_SERIAL_RX_PIN -1 // 63 + #define X2_SERIAL_TX_PIN -1 + #define X2_SERIAL_RX_PIN -1 + + #define Y_SERIAL_TX_PIN -1 // 64 + #define Y_SERIAL_RX_PIN -1 // 40 + #define Y2_SERIAL_TX_PIN -1 + #define Y2_SERIAL_RX_PIN -1 + + #define Z_SERIAL_TX_PIN -1 // 44 + #define Z_SERIAL_RX_PIN -1 // 42 + #define Z2_SERIAL_TX_PIN -1 + #define Z2_SERIAL_RX_PIN -1 + + #define E0_SERIAL_TX_PIN -1 // 66 + #define E0_SERIAL_RX_PIN -1 // 65 + #define E1_SERIAL_TX_PIN -1 + #define E1_SERIAL_RX_PIN -1 + #define E2_SERIAL_TX_PIN -1 + #define E2_SERIAL_RX_PIN -1 + #define E3_SERIAL_TX_PIN -1 + #define E3_SERIAL_RX_PIN -1 + #define E4_SERIAL_TX_PIN -1 + #define E4_SERIAL_RX_PIN -1 + #define E5_SERIAL_RX_PIN -1 + #define E6_SERIAL_RX_PIN -1 + #define E7_SERIAL_RX_PIN -1 #endif // @@ -170,16 +170,16 @@ // // Temperature Sensors // -#define TEMP_0_PIN 13 -#define TEMP_1_PIN 15 -#define TEMP_2_PIN 10 -#define TEMP_3_PIN 11 -#define TEMP_BED_PIN 14 +#define TEMP_0_PIN 13 +#define TEMP_1_PIN 15 +#define TEMP_2_PIN 10 +#define TEMP_3_PIN 11 +#define TEMP_BED_PIN 14 #if TEMP_SENSOR_CHAMBER > 0 - #define TEMP_CHAMBER_PIN 12 + #define TEMP_CHAMBER_PIN 12 #else - #define TEMP_4_PIN 12 + #define TEMP_4_PIN 12 #endif // SPI for Max6675 or Max31855 Thermocouple @@ -192,50 +192,50 @@ // // Heaters / Fans // -#define HEATER_0_PIN 10 -#define HEATER_1_PIN 7 -#define HEATER_2_PIN 44 -#define HEATER_BED_PIN 8 +#define HEATER_0_PIN 10 +#define HEATER_1_PIN 7 +#define HEATER_2_PIN 44 +#define HEATER_BED_PIN 8 -#define FAN_PIN 9 +#define FAN_PIN 9 #if EXTRUDERS >= 5 - #define HEATER_4_PIN 6 + #define HEATER_4_PIN 6 #else - #define FAN1_PIN 6 + #define FAN1_PIN 6 #endif #if EXTRUDERS >= 4 - #define HEATER_3_PIN 45 + #define HEATER_3_PIN 45 #else - #define FAN2_PIN 45 + #define FAN2_PIN 45 #endif // // Misc. Functions // -#define SDSS 53 -#define LED_PIN 13 +#define SDSS 53 +#define LED_PIN 13 //#ifndef FILWIDTH_PIN // #define FILWIDTH_PIN 5 // Analog Input //#endif // DIO 4 (Servos plug) for the runout sensor. -//#define FIL_RUNOUT_PIN SERVO3_PIN +//#define FIL_RUNOUT_PIN SERVO3_PIN #ifndef PS_ON_PIN - #define PS_ON_PIN 12 + #define PS_ON_PIN 12 #endif // // Case Light // #if ENABLED(CASE_LIGHT_ENABLE) && !PIN_EXISTS(CASE_LIGHT) && !defined(SPINDLE_LASER_ENABLE_PIN) - #if !NUM_SERVOS // Prefer the servo connector - #define CASE_LIGHT_PIN 6 // Hardware PWM - #elif HAS_FREE_AUX2_PINS // Try to use AUX 2 - #define CASE_LIGHT_PIN 44 // Hardware PWM + #if !NUM_SERVOS // Prefer the servo connector + #define CASE_LIGHT_PIN 6 // Hardware PWM + #elif HAS_FREE_AUX2_PINS // Try to use AUX 2 + #define CASE_LIGHT_PIN 44 // Hardware PWM #endif #endif @@ -243,14 +243,14 @@ // M3/M4/M5 - Spindle/Laser Control // #if ENABLED(SPINDLE_LASER_ENABLE) && !PIN_EXISTS(SPINDLE_LASER_ENABLE) - #if !NUM_SERVOS // Prefer the servo connector - #define SPINDLE_LASER_ENABLE_PIN 4 // Pullup or pulldown! - #define SPINDLE_LASER_PWM_PIN 6 // Hardware PWM - #define SPINDLE_DIR_PIN 5 - #elif HAS_FREE_AUX2_PINS // Try to use AUX 2 - #define SPINDLE_LASER_ENABLE_PIN 40 // Pullup or pulldown! - #define SPINDLE_LASER_PWM_PIN 44 // Hardware PWM - #define SPINDLE_DIR_PIN 65 + #if !NUM_SERVOS // Prefer the servo connector + #define SPINDLE_LASER_ENABLE_PIN 4 // Pullup or pulldown! + #define SPINDLE_LASER_PWM_PIN 6 // Hardware PWM + #define SPINDLE_DIR_PIN 5 + #elif HAS_FREE_AUX2_PINS // Try to use AUX 2 + #define SPINDLE_LASER_ENABLE_PIN 40 // Pullup or pulldown! + #define SPINDLE_LASER_PWM_PIN 44 // Hardware PWM + #define SPINDLE_DIR_PIN 65 #endif #endif @@ -271,70 +271,70 @@ // LCDs and Controllers // ////////////////////////// -#if HAS_SPI_LCD +#if HAS_WIRED_LCD // // LCD Display output pins // #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) - #define LCD_PINS_RS 49 // CS chip select /SS chip slave select - #define LCD_PINS_ENABLE 51 // SID (MOSI) - #define LCD_PINS_D4 52 // SCK (CLK) clock + #define LCD_PINS_RS 49 // CS chip select /SS chip slave select + #define LCD_PINS_ENABLE 51 // SID (MOSI) + #define LCD_PINS_D4 52 // SCK (CLK) clock #elif BOTH(NEWPANEL, PANEL_ONE) - #define LCD_PINS_RS 40 - #define LCD_PINS_ENABLE 42 - #define LCD_PINS_D4 65 - #define LCD_PINS_D5 66 - #define LCD_PINS_D6 44 - #define LCD_PINS_D7 64 + #define LCD_PINS_RS 40 + #define LCD_PINS_ENABLE 42 + #define LCD_PINS_D4 65 + #define LCD_PINS_D5 66 + #define LCD_PINS_D6 44 + #define LCD_PINS_D7 64 #elif ENABLED(ZONESTAR_LCD) - #define LCD_PINS_RS 64 - #define LCD_PINS_ENABLE 44 - #define LCD_PINS_D4 63 - #define LCD_PINS_D5 40 - #define LCD_PINS_D6 42 - #define LCD_PINS_D7 65 - #define ADC_KEYPAD_PIN 12 + #define LCD_PINS_RS 64 + #define LCD_PINS_ENABLE 44 + #define LCD_PINS_D4 63 + #define LCD_PINS_D5 40 + #define LCD_PINS_D6 42 + #define LCD_PINS_D7 65 + #define ADC_KEYPAD_PIN 12 #else #if ENABLED(CR10_STOCKDISPLAY) - #define LCD_PINS_RS 27 - #define LCD_PINS_ENABLE 29 - #define LCD_PINS_D4 25 + #define LCD_PINS_RS 27 + #define LCD_PINS_ENABLE 29 + #define LCD_PINS_D4 25 #if DISABLED(NEWPANEL) - #define BEEPER_PIN 37 + #define BEEPER_PIN 37 #endif #else #if EITHER(MKS_12864OLED, MKS_12864OLED_SSD1306) - #define LCD_PINS_DC 25 // Set as output on init - #define LCD_PINS_RS 27 // Pull low for 1s to init + #define LCD_PINS_DC 25 // Set as output on init + #define LCD_PINS_RS 27 // Pull low for 1s to init // DOGM SPI LCD Support - #define DOGLCD_CS 16 - #define DOGLCD_MOSI 17 - #define DOGLCD_SCK 23 - #define DOGLCD_A0 LCD_PINS_DC + #define DOGLCD_CS 16 + #define DOGLCD_MOSI 17 + #define DOGLCD_SCK 23 + #define DOGLCD_A0 LCD_PINS_DC #else - #define LCD_PINS_RS 16 - #define LCD_PINS_ENABLE 17 - #define LCD_PINS_D4 23 - #define LCD_PINS_D5 25 - #define LCD_PINS_D6 27 + #define LCD_PINS_RS 16 + #define LCD_PINS_ENABLE 17 + #define LCD_PINS_D4 23 + #define LCD_PINS_D5 25 + #define LCD_PINS_D6 27 #endif - #define LCD_PINS_D7 29 + #define LCD_PINS_D7 29 #if DISABLED(NEWPANEL) - #define BEEPER_PIN 33 + #define BEEPER_PIN 33 #endif #endif @@ -342,10 +342,10 @@ #if DISABLED(NEWPANEL) // Buttons attached to a shift register // Not wired yet - //#define SHIFT_CLK 38 - //#define SHIFT_LD 42 - //#define SHIFT_OUT 40 - //#define SHIFT_EN 17 + //#define SHIFT_CLK 38 + //#define SHIFT_LD 42 + //#define SHIFT_OUT 40 + //#define SHIFT_EN 17 #endif #endif @@ -357,155 +357,155 @@ #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) - #define BEEPER_PIN 37 + #define BEEPER_PIN 37 #if ENABLED(CR10_STOCKDISPLAY) - #define BTN_EN1 17 - #define BTN_EN2 23 + #define BTN_EN1 17 + #define BTN_EN2 23 #else - #define BTN_EN1 31 - #define BTN_EN2 33 + #define BTN_EN1 31 + #define BTN_EN2 33 #endif - #define BTN_ENC 35 - #define SD_DETECT_PIN 49 - //#define KILL_PIN 41 + #define BTN_ENC 35 + #define SD_DETECT_PIN 49 + //#define KILL_PIN 41 #if ENABLED(BQ_LCD_SMART_CONTROLLER) - #define LCD_BACKLIGHT_PIN 39 + #define LCD_BACKLIGHT_PIN 39 #endif #elif ENABLED(REPRAPWORLD_GRAPHICAL_LCD) - #define BTN_EN1 64 - #define BTN_EN2 59 - #define BTN_ENC 63 - #define SD_DETECT_PIN 42 + #define BTN_EN1 64 + #define BTN_EN2 59 + #define BTN_ENC 63 + #define SD_DETECT_PIN 42 #elif ENABLED(LCD_I2C_PANELOLU2) - #define BTN_EN1 47 - #define BTN_EN2 43 - #define BTN_ENC 32 - #define LCD_SDSS 53 - //#define KILL_PIN 41 + #define BTN_EN1 47 + #define BTN_EN2 43 + #define BTN_ENC 32 + #define LCD_SDSS 53 + //#define KILL_PIN 41 #elif ENABLED(LCD_I2C_VIKI) - #define BTN_EN1 22 // http://files.panucatt.com/datasheets/viki_wiring_diagram.pdf explains 40/42. - #define BTN_EN2 7 // 22/7 are unused on RAMPS_14. 22 is unused and 7 the SERVO0_PIN on RAMPS_13. - #define BTN_ENC -1 + #define BTN_EN1 22 // https://files.panucatt.com/datasheets/viki_wiring_diagram.pdf explains 40/42. + #define BTN_EN2 7 // 22/7 are unused on RAMPS_14. 22 is unused and 7 the SERVO0_PIN on RAMPS_13. + #define BTN_ENC -1 - #define LCD_SDSS 53 - #define SD_DETECT_PIN 49 + #define LCD_SDSS 53 + #define SD_DETECT_PIN 49 #elif EITHER(VIKI2, miniVIKI) - #define DOGLCD_CS 45 - #define DOGLCD_A0 44 + #define DOGLCD_CS 45 + #define DOGLCD_A0 44 #define LCD_SCREEN_ROT_180 - #define BEEPER_PIN 33 - #define STAT_LED_RED_PIN 32 - #define STAT_LED_BLUE_PIN 35 + #define BEEPER_PIN 33 + #define STAT_LED_RED_PIN 32 + #define STAT_LED_BLUE_PIN 35 - #define BTN_EN1 22 - #define BTN_EN2 7 - #define BTN_ENC 39 + #define BTN_EN1 22 + #define BTN_EN2 7 + #define BTN_ENC 39 - #define SDSS 53 - #define SD_DETECT_PIN -1 // Pin 49 for display SD interface, 72 for easy adapter board - //#define KILL_PIN 31 + #define SDSS 53 + #define SD_DETECT_PIN -1 // Pin 49 for display SD interface, 72 for easy adapter board + //#define KILL_PIN 31 #elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) - #define DOGLCD_CS 29 - #define DOGLCD_A0 27 + #define DOGLCD_CS 29 + #define DOGLCD_A0 27 - #define BEEPER_PIN 23 - #define LCD_BACKLIGHT_PIN 33 + #define BEEPER_PIN 23 + #define LCD_BACKLIGHT_PIN 33 - #define BTN_EN1 35 - #define BTN_EN2 37 - #define BTN_ENC 31 + #define BTN_EN1 35 + #define BTN_EN2 37 + #define BTN_ENC 31 - #define LCD_SDSS 53 - #define SD_DETECT_PIN 49 - //#define KILL_PIN 41 + #define LCD_SDSS 53 + #define SD_DETECT_PIN 49 + //#define KILL_PIN 41 #elif ENABLED(MKS_MINI_12864) - #define DOGLCD_A0 27 - #define DOGLCD_CS 25 + #define DOGLCD_A0 27 + #define DOGLCD_CS 25 // GLCD features - //#define LCD_CONTRAST_INIT 190 + //#define LCD_CONTRAST_INIT 190 // Uncomment screen orientation //#define LCD_SCREEN_ROT_90 //#define LCD_SCREEN_ROT_180 //#define LCD_SCREEN_ROT_270 - #define BEEPER_PIN 37 + #define BEEPER_PIN 37 - #define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65 + #define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65 - #define BTN_EN1 31 - #define BTN_EN2 33 - #define BTN_ENC 35 - //#define SDSS 53 - #define SD_DETECT_PIN 49 - //#define KILL_PIN 64 + #define BTN_EN1 31 + #define BTN_EN2 33 + #define BTN_ENC 35 + //#define SDSS 53 + #define SD_DETECT_PIN 49 + //#define KILL_PIN 64 #elif ENABLED(MINIPANEL) - #define BEEPER_PIN 42 + #define BEEPER_PIN 42 // not connected to a pin - #define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65 + #define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65 - #define DOGLCD_A0 44 - #define DOGLCD_CS 66 + #define DOGLCD_A0 44 + #define DOGLCD_CS 66 // GLCD features - //#define LCD_CONTRAST_INIT 190 + //#define LCD_CONTRAST_INIT 190 // Uncomment screen orientation //#define LCD_SCREEN_ROT_90 //#define LCD_SCREEN_ROT_180 //#define LCD_SCREEN_ROT_270 - #define BTN_EN1 40 - #define BTN_EN2 63 - #define BTN_ENC 59 + #define BTN_EN1 40 + #define BTN_EN2 63 + #define BTN_ENC 59 - #define SDSS 53 - #define SD_DETECT_PIN 49 - //#define KILL_PIN 64 + #define SDSS 53 + #define SD_DETECT_PIN 49 + //#define KILL_PIN 64 #else // Beeper on AUX-4 - #define BEEPER_PIN 33 + #define BEEPER_PIN 33 // Buttons are directly attached to AUX-2 #if ENABLED(REPRAPWORLD_KEYPAD) - #define SHIFT_OUT 40 - #define SHIFT_CLK 44 - #define SHIFT_LD 42 - #define BTN_EN1 64 - #define BTN_EN2 59 - #define BTN_ENC 63 + #define SHIFT_OUT 40 + #define SHIFT_CLK 44 + #define SHIFT_LD 42 + #define BTN_EN1 64 + #define BTN_EN2 59 + #define BTN_ENC 63 #elif ENABLED(PANEL_ONE) - #define BTN_EN1 59 // AUX2 PIN 3 - #define BTN_EN2 63 // AUX2 PIN 4 - #define BTN_ENC 49 // AUX3 PIN 7 + #define BTN_EN1 59 // AUX2 PIN 3 + #define BTN_EN2 63 // AUX2 PIN 4 + #define BTN_ENC 49 // AUX3 PIN 7 #else - #define BTN_EN1 37 - #define BTN_EN2 35 - #define BTN_ENC 31 + #define BTN_EN1 37 + #define BTN_EN2 35 + #define BTN_ENC 31 #endif #if ENABLED(G3D_PANEL) - #define SD_DETECT_PIN 49 - //#define KILL_PIN 41 + #define SD_DETECT_PIN 49 + //#define KILL_PIN 41 #endif #endif diff --git a/Marlin/src/pins/ramps/pins_ULTIMAIN_2.h b/Marlin/src/pins/ramps/pins_ULTIMAIN_2.h index 2af64bb2a065..c6251ae8175c 100644 --- a/Marlin/src/pins/ramps/pins_ULTIMAIN_2.h +++ b/Marlin/src/pins/ramps/pins_ULTIMAIN_2.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -33,7 +33,7 @@ * case light */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -44,97 +44,99 @@ // // Limit Switches // -#define X_STOP_PIN 22 -#define Y_STOP_PIN 26 -#define Z_STOP_PIN 29 +#define X_STOP_PIN 22 +#define Y_STOP_PIN 26 +#define Z_STOP_PIN 29 // // Steppers // -#define X_STEP_PIN 25 -#define X_DIR_PIN 23 -#define X_ENABLE_PIN 27 +#define X_STEP_PIN 25 +#define X_DIR_PIN 23 +#define X_ENABLE_PIN 27 -#define Y_STEP_PIN 32 -#define Y_DIR_PIN 33 -#define Y_ENABLE_PIN 31 +#define Y_STEP_PIN 32 +#define Y_DIR_PIN 33 +#define Y_ENABLE_PIN 31 -#define Z_STEP_PIN 35 -#define Z_DIR_PIN 36 -#define Z_ENABLE_PIN 34 +#define Z_STEP_PIN 35 +#define Z_DIR_PIN 36 +#define Z_ENABLE_PIN 34 -#define E0_STEP_PIN 42 -#define E0_DIR_PIN 43 -#define E0_ENABLE_PIN 37 +#define E0_STEP_PIN 42 +#define E0_DIR_PIN 43 +#define E0_ENABLE_PIN 37 -#define E1_STEP_PIN 49 -#define E1_DIR_PIN 47 -#define E1_ENABLE_PIN 48 +#define E1_STEP_PIN 49 +#define E1_DIR_PIN 47 +#define E1_ENABLE_PIN 48 -#define MOTOR_CURRENT_PWM_XY_PIN 44 -#define MOTOR_CURRENT_PWM_Z_PIN 45 -#define MOTOR_CURRENT_PWM_E_PIN 46 +#define MOTOR_CURRENT_PWM_XY_PIN 44 +#define MOTOR_CURRENT_PWM_Z_PIN 45 +#define MOTOR_CURRENT_PWM_E_PIN 46 // Motor current PWM conversion, PWM value = MotorCurrentSetting * 255 / range #ifndef MOTOR_CURRENT_PWM_RANGE - #define MOTOR_CURRENT_PWM_RANGE 2000 + #define MOTOR_CURRENT_PWM_RANGE 2000 #endif #define DEFAULT_PWM_MOTOR_CURRENT {1300, 1300, 1250} // // Temperature Sensors // -#define TEMP_0_PIN 8 // Analog Input -#define TEMP_1_PIN 9 // Analog Input -#define TEMP_BED_PIN 10 // Analog Input +#define TEMP_0_PIN 8 // Analog Input +#define TEMP_1_PIN 9 // Analog Input +#define TEMP_BED_PIN 10 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 2 -#define HEATER_1_PIN 3 -#define HEATER_BED_PIN 4 +#define HEATER_0_PIN 2 +#define HEATER_1_PIN 3 +#define HEATER_BED_PIN 4 #ifndef FAN_PIN - #define FAN_PIN 7 + #define FAN_PIN 7 #endif -#define ORIG_E0_AUTO_FAN_PIN 77 +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN 77 +#endif // // Misc. Functions // -#define SDSS 53 -#define SD_DETECT_PIN 39 -#define LED_PIN 8 -#define SAFETY_TRIGGERED_PIN 28 // PIN to detect the safety circuit has triggered -#define MAIN_VOLTAGE_MEASURE_PIN 14 // ANALOG PIN to measure the main voltage, with a 100k - 4k7 resitor divider. +#define SDSS 53 +#define SD_DETECT_PIN 39 +#define LED_PIN 8 +#define SAFETY_TRIGGERED_PIN 28 // PIN to detect the safety circuit has triggered +#define MAIN_VOLTAGE_MEASURE_PIN 14 // ANALOG PIN to measure the main voltage, with a 100k - 4k7 resitor divider. // // LCD / Controller // -#define BEEPER_PIN 18 +#define BEEPER_PIN 18 -#define LCD_PINS_RS 20 -#define LCD_PINS_ENABLE 15 -#define LCD_PINS_D4 14 -#define LCD_PINS_D5 21 -#define LCD_PINS_D6 5 -#define LCD_PINS_D7 6 +#define LCD_PINS_RS 20 +#define LCD_PINS_ENABLE 15 +#define LCD_PINS_D4 14 +#define LCD_PINS_D5 21 +#define LCD_PINS_D6 5 +#define LCD_PINS_D7 6 // Buttons are directly attached -#define BTN_EN1 40 -#define BTN_EN2 41 -#define BTN_ENC 19 +#define BTN_EN1 40 +#define BTN_EN2 41 +#define BTN_ENC 19 // // M3/M4/M5 - Spindle/Laser Control // -#if HAS_CUTTER // use the LED_PIN for spindle speed control or case light +#if HAS_CUTTER // use the LED_PIN for spindle speed control or case light #undef LED_PIN - #define SPINDLE_DIR_PIN 16 - #define SPINDLE_LASER_ENA_PIN 17 // Pullup! - #define SPINDLE_LASER_PWM_PIN 8 // Hardware PWM + #define SPINDLE_DIR_PIN 16 + #define SPINDLE_LASER_ENA_PIN 17 // Pullup! + #define SPINDLE_LASER_PWM_PIN 8 // Hardware PWM #else #undef LED_PIN - #define CASE_LIGHT_PIN 8 + #define CASE_LIGHT_PIN 8 #endif diff --git a/Marlin/src/pins/ramps/pins_ULTIMAKER.h b/Marlin/src/pins/ramps/pins_ULTIMAKER.h index 8a48b07de76b..597a37bdbc8b 100644 --- a/Marlin/src/pins/ramps/pins_ULTIMAKER.h +++ b/Marlin/src/pins/ramps/pins_ULTIMAKER.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -33,7 +33,7 @@ * case light */ -#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) +#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -44,122 +44,125 @@ // // Servos // -#define SERVO0_PIN 11 +#define SERVO0_PIN 11 // // Limit Switches // -#define X_MIN_PIN 22 -#define X_MAX_PIN 24 -#define Y_MIN_PIN 26 -#define Y_MAX_PIN 28 -#define Z_MIN_PIN 30 -#define Z_MAX_PIN 32 +#define X_MIN_PIN 22 +#define X_MAX_PIN 24 +#define Y_MIN_PIN 26 +#define Y_MAX_PIN 28 +#define Z_MIN_PIN 30 +#define Z_MAX_PIN 32 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 32 + #define Z_MIN_PROBE_PIN 32 #endif // // Steppers // -#define X_STEP_PIN 25 -#define X_DIR_PIN 23 -#define X_ENABLE_PIN 27 +#define X_STEP_PIN 25 +#define X_DIR_PIN 23 +#define X_ENABLE_PIN 27 -#define Y_STEP_PIN 31 -#define Y_DIR_PIN 33 -#define Y_ENABLE_PIN 29 +#define Y_STEP_PIN 31 +#define Y_DIR_PIN 33 +#define Y_ENABLE_PIN 29 -#define Z_STEP_PIN 37 -#define Z_DIR_PIN 39 -#define Z_ENABLE_PIN 35 +#define Z_STEP_PIN 37 +#define Z_DIR_PIN 39 +#define Z_ENABLE_PIN 35 -#define E0_STEP_PIN 43 -#define E0_DIR_PIN 45 -#define E0_ENABLE_PIN 41 +#define E0_STEP_PIN 43 +#define E0_DIR_PIN 45 +#define E0_ENABLE_PIN 41 -#define E1_STEP_PIN 49 -#define E1_DIR_PIN 47 -#define E1_ENABLE_PIN 48 +#define E1_STEP_PIN 49 +#define E1_DIR_PIN 47 +#define E1_ENABLE_PIN 48 // // Temperature Sensors // -#define TEMP_0_PIN 8 // Analog Input -#define TEMP_1_PIN 9 // Analog Input -#define TEMP_BED_PIN 10 // Analog Input +#define TEMP_0_PIN 8 // Analog Input +#define TEMP_1_PIN 9 // Analog Input +#define TEMP_BED_PIN 10 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 2 -#define HEATER_1_PIN 3 -#define HEATER_BED_PIN 4 +#define HEATER_0_PIN 2 +#define HEATER_1_PIN 3 +#define HEATER_BED_PIN 4 #ifndef FAN_PIN - #define FAN_PIN 7 + #define FAN_PIN 7 #endif // // Misc. Functions // -#define SDSS 53 -#define LED_PIN 13 -#define PS_ON_PIN 12 -#define SUICIDE_PIN 54 // PIN that has to be turned on right after start, to keep power flowing. -#define CASE_LIGHT_PIN 8 +#define SDSS 53 +#define LED_PIN 13 +#define PS_ON_PIN 12 +#define SUICIDE_PIN 54 // PIN that has to be turned on right after start, to keep power flowing. + +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN 8 +#endif // // LCD / Controller // -#if HAS_SPI_LCD +#if HAS_WIRED_LCD - #define BEEPER_PIN 18 + #define BEEPER_PIN 18 #if ENABLED(NEWPANEL) - #define LCD_PINS_RS 20 - #define LCD_PINS_ENABLE 17 - #define LCD_PINS_D4 16 - #define LCD_PINS_D5 21 - #define LCD_PINS_D6 5 - #define LCD_PINS_D7 6 + #define LCD_PINS_RS 20 + #define LCD_PINS_ENABLE 17 + #define LCD_PINS_D4 16 + #define LCD_PINS_D5 21 + #define LCD_PINS_D6 5 + #define LCD_PINS_D7 6 // Buttons directly attached - #define BTN_EN1 40 - #define BTN_EN2 42 - #define BTN_ENC 19 + #define BTN_EN1 40 + #define BTN_EN2 42 + #define BTN_ENC 19 - #define SD_DETECT_PIN 38 + #define SD_DETECT_PIN 38 - #else // !NEWPANEL - Old style panel with shift register + #else // !NEWPANEL - Old style panel with shift register // Buttons attached to a shift register - #define SHIFT_CLK 38 - #define SHIFT_LD 42 - #define SHIFT_OUT 40 - #define SHIFT_EN 17 + #define SHIFT_CLK 38 + #define SHIFT_LD 42 + #define SHIFT_OUT 40 + #define SHIFT_EN 17 - #define LCD_PINS_RS 16 - #define LCD_PINS_ENABLE 5 - #define LCD_PINS_D4 6 - #define LCD_PINS_D5 21 - #define LCD_PINS_D6 20 - #define LCD_PINS_D7 19 + #define LCD_PINS_RS 16 + #define LCD_PINS_ENABLE 5 + #define LCD_PINS_D4 6 + #define LCD_PINS_D5 21 + #define LCD_PINS_D6 20 + #define LCD_PINS_D7 19 - #define SD_DETECT_PIN -1 + #define SD_DETECT_PIN -1 #endif // !NEWPANEL -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD // // M3/M4/M5 - Spindle/Laser Control // -#define SPINDLE_LASER_PWM_PIN 9 // Hardware PWM -#define SPINDLE_LASER_ENA_PIN 10 // Pullup! -#define SPINDLE_DIR_PIN 11 // use the EXP3 PWM header +#define SPINDLE_LASER_PWM_PIN 9 // Hardware PWM +#define SPINDLE_LASER_ENA_PIN 10 // Pullup! +#define SPINDLE_DIR_PIN 11 // use the EXP3 PWM header diff --git a/Marlin/src/pins/ramps/pins_ULTIMAKER_OLD.h b/Marlin/src/pins/ramps/pins_ULTIMAKER_OLD.h index e128dc98d276..c5bbd02bf5a9 100644 --- a/Marlin/src/pins/ramps/pins_ULTIMAKER_OLD.h +++ b/Marlin/src/pins/ramps/pins_ULTIMAKER_OLD.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -60,7 +60,7 @@ //#define BOARD_REV_1_0 //#define BOARD_REV_1_5 -#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) +#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif @@ -80,134 +80,134 @@ // Limit Switches // #if ENABLED(BOARD_REV_1_1_TO_1_3) - #define X_MIN_PIN 15 // SW1 - #define X_MAX_PIN 14 // SW2 - #define Y_MIN_PIN 17 // SW3 - #define Y_MAX_PIN 16 // SW4 - #define Z_MIN_PIN 19 // SW5 - #define Z_MAX_PIN 18 // SW6 + #define X_MIN_PIN 15 // SW1 + #define X_MAX_PIN 14 // SW2 + #define Y_MIN_PIN 17 // SW3 + #define Y_MAX_PIN 16 // SW4 + #define Z_MIN_PIN 19 // SW5 + #define Z_MAX_PIN 18 // SW6 #endif #if ENABLED(BOARD_REV_1_0) #if HAS_CUTTER - #define X_STOP_PIN 13 // SW1 (didn't change) - also has a useable hardware PWM - #define Y_STOP_PIN 12 // SW2 - #define Z_STOP_PIN 11 // SW3 + #define X_STOP_PIN 13 // SW1 (didn't change) - also has a useable hardware PWM + #define Y_STOP_PIN 12 // SW2 + #define Z_STOP_PIN 11 // SW3 #else - #define X_MIN_PIN 13 // SW1 - #define X_MAX_PIN 12 // SW2 - #define Y_MIN_PIN 11 // SW3 - #define Y_MAX_PIN 10 // SW4 - #define Z_MIN_PIN 9 // SW5 - #define Z_MAX_PIN 8 // SW6 + #define X_MIN_PIN 13 // SW1 + #define X_MAX_PIN 12 // SW2 + #define Y_MIN_PIN 11 // SW3 + #define Y_MAX_PIN 10 // SW4 + #define Z_MIN_PIN 9 // SW5 + #define Z_MAX_PIN 8 // SW6 #endif #endif #if ENABLED(BOARD_REV_1_5) - #define X_MIN_PIN 22 - #define X_MAX_PIN 24 - #define Y_MIN_PIN 26 - #define Y_MAX_PIN 28 - #define Z_MIN_PIN 30 - #define Z_MAX_PIN 32 + #define X_MIN_PIN 22 + #define X_MAX_PIN 24 + #define Y_MIN_PIN 26 + #define Y_MAX_PIN 28 + #define Z_MIN_PIN 30 + #define Z_MAX_PIN 32 #endif // // Z Probe (when not Z_MIN_PIN) // -#if !defined(Z_MIN_PROBE_PIN) && !(HAS_CUTTER && ENABLED(BOARD_REV_1_0)) - #define Z_MIN_PROBE_PIN Z_MAX_PIN +#if !defined(Z_MIN_PROBE_PIN) && !BOTH(HAS_CUTTER, BOARD_REV_1_0) + #define Z_MIN_PROBE_PIN Z_MAX_PIN #endif // // Steppers // -#define X_STEP_PIN 25 -#define X_DIR_PIN 23 -#define X_ENABLE_PIN 27 +#define X_STEP_PIN 25 +#define X_DIR_PIN 23 +#define X_ENABLE_PIN 27 -#define Y_STEP_PIN 31 -#define Y_DIR_PIN 33 -#define Y_ENABLE_PIN 29 +#define Y_STEP_PIN 31 +#define Y_DIR_PIN 33 +#define Y_ENABLE_PIN 29 -#define Z_STEP_PIN 37 -#define Z_DIR_PIN 39 -#define Z_ENABLE_PIN 35 +#define Z_STEP_PIN 37 +#define Z_DIR_PIN 39 +#define Z_ENABLE_PIN 35 -#if HAS_CUTTER && ENABLED(BOARD_REV_1_1_TO_1_3) && EXTRUDERS == 1 +#if BOTH(HAS_CUTTER, BOARD_REV_1_1_TO_1_3) && EXTRUDERS == 1 // Move E0 to the spare and get Spindle/Laser signals from E0 - #define E0_STEP_PIN 49 - #define E0_DIR_PIN 47 - #define E0_ENABLE_PIN 48 + #define E0_STEP_PIN 49 + #define E0_DIR_PIN 47 + #define E0_ENABLE_PIN 48 #else - #define E0_STEP_PIN 43 - #define E0_DIR_PIN 45 - #define E0_ENABLE_PIN 41 + #define E0_STEP_PIN 43 + #define E0_DIR_PIN 45 + #define E0_ENABLE_PIN 41 - #define E1_STEP_PIN 49 - #define E1_DIR_PIN 47 - #define E1_ENABLE_PIN 48 + #define E1_STEP_PIN 49 + #define E1_DIR_PIN 47 + #define E1_ENABLE_PIN 48 #endif // // Temperature Sensors // -#define TEMP_0_PIN 8 // Analog Input -#define TEMP_1_PIN 1 // Analog Input +#define TEMP_0_PIN 8 // Analog Input +#define TEMP_1_PIN 1 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 2 -//#define HEATER_1_PIN 3 // used for case light Rev A said "1" -#define HEATER_BED_PIN 4 +#define HEATER_0_PIN 2 +//#define HEATER_1_PIN 3 // used for case light Rev A said "1" +#define HEATER_BED_PIN 4 // // LCD / Controller // #if ANY(BOARD_REV_1_0, BOARD_REV_1_1_TO_1_3) - #define LCD_PINS_RS 24 - #define LCD_PINS_ENABLE 22 - #define LCD_PINS_D4 36 - #define LCD_PINS_D5 34 - #define LCD_PINS_D6 32 - #define LCD_PINS_D7 30 + #define LCD_PINS_RS 24 + #define LCD_PINS_ENABLE 22 + #define LCD_PINS_D4 36 + #define LCD_PINS_D5 34 + #define LCD_PINS_D6 32 + #define LCD_PINS_D7 30 -#elif ENABLED(BOARD_REV_1_5, ULTRA_LCD) +#elif BOTH(BOARD_REV_1_5, ULTRA_LCD) - #define BEEPER_PIN 18 + #define BEEPER_PIN 18 #if ENABLED(NEWPANEL) - #define LCD_PINS_RS 20 - #define LCD_PINS_ENABLE 17 - #define LCD_PINS_D4 16 - #define LCD_PINS_D5 21 - #define LCD_PINS_D6 5 - #define LCD_PINS_D7 6 + #define LCD_PINS_RS 20 + #define LCD_PINS_ENABLE 17 + #define LCD_PINS_D4 16 + #define LCD_PINS_D5 21 + #define LCD_PINS_D6 5 + #define LCD_PINS_D7 6 // Buttons directly attached - #define BTN_EN1 40 - #define BTN_EN2 42 - #define BTN_ENC 19 + #define BTN_EN1 40 + #define BTN_EN2 42 + #define BTN_ENC 19 - #define SD_DETECT_PIN 38 + #define SD_DETECT_PIN 38 - #else // !NEWPANEL - Old style panel with shift register + #else // !NEWPANEL - Old style panel with shift register // Buttons attached to a shift register - #define SHIFT_CLK 38 - #define SHIFT_LD 42 - #define SHIFT_OUT 40 - #define SHIFT_EN 17 - - #define LCD_PINS_RS 16 - #define LCD_PINS_ENABLE 5 - #define LCD_PINS_D4 6 - #define LCD_PINS_D5 21 - #define LCD_PINS_D6 20 - #define LCD_PINS_D7 19 + #define SHIFT_CLK 38 + #define SHIFT_LD 42 + #define SHIFT_OUT 40 + #define SHIFT_EN 17 + + #define LCD_PINS_RS 16 + #define LCD_PINS_ENABLE 5 + #define LCD_PINS_D4 6 + #define LCD_PINS_D5 21 + #define LCD_PINS_D6 20 + #define LCD_PINS_D7 19 #endif // !NEWPANEL @@ -217,17 +217,17 @@ // case light - see spindle section for more info on available hardware PWMs // #if !PIN_EXISTS(CASE_LIGHT) && ENABLED(BOARD_REV_1_5) - #define CASE_LIGHT_PIN 7 // use PWM - MUST BE HARDWARE PWM + #define CASE_LIGHT_PIN 7 // use PWM - MUST BE HARDWARE PWM #endif // // M3/M4/M5 - Spindle/Laser Control // #if HAS_CUTTER - #if EITHER(BOARD_REV_1_0, BOARD_REV_1_5) // Use the last three SW positions - #define SPINDLE_DIR_PIN 10 // 1.0: SW4 1.5: EXP3-6 ("10") - #define SPINDLE_LASER_PWM_PIN 9 // 1.0: SW5 1.5: EXP3-7 ( "9") .. MUST BE HARDWARE PWM - #define SPINDLE_LASER_ENA_PIN 8 // 1.0: SW6 1.5: EXP3-8 ( "8") .. Pin should have a pullup! + #if EITHER(BOARD_REV_1_0, BOARD_REV_1_5) // Use the last three SW positions + #define SPINDLE_DIR_PIN 10 // 1.0: SW4 1.5: EXP3-6 ("10") + #define SPINDLE_LASER_PWM_PIN 9 // 1.0: SW5 1.5: EXP3-7 ( "9") .. MUST BE HARDWARE PWM + #define SPINDLE_LASER_ENA_PIN 8 // 1.0: SW6 1.5: EXP3-8 ( "8") .. Pin should have a pullup! #elif ENABLED(BOARD_REV_1_1_TO_1_3) /** * Only four hardware PWMs physically connected to anything on these boards: @@ -241,14 +241,14 @@ * They have an LED and resistor pullup to +24V which could damage 3.3V-5V ICs. */ #if EXTRUDERS == 1 - #define SPINDLE_DIR_PIN 43 - #define SPINDLE_LASER_PWM_PIN 45 // Hardware PWM - #define SPINDLE_LASER_ENA_PIN 41 // Pullup! - #elif TEMP_SENSOR_BED == 0 // Can't use E0 so see if HEATER_BED_PIN is available + #define SPINDLE_DIR_PIN 43 + #define SPINDLE_LASER_PWM_PIN 45 // Hardware PWM + #define SPINDLE_LASER_ENA_PIN 41 // Pullup! + #elif TEMP_SENSOR_BED == 0 // Can't use E0 so see if HEATER_BED_PIN is available #undef HEATER_BED_PIN - #define SPINDLE_DIR_PIN 38 // Probably pin 4 on 10 pin connector closest to the E0 socket - #define SPINDLE_LASER_PWM_PIN 4 // Hardware PWM - Special precautions usually needed. - #define SPINDLE_LASER_ENA_PIN 40 // Pullup! (Probably pin 6 on the 10-pin + #define SPINDLE_DIR_PIN 38 // Probably pin 4 on 10 pin connector closest to the E0 socket + #define SPINDLE_LASER_PWM_PIN 4 // Hardware PWM - Special precautions usually needed. + #define SPINDLE_LASER_ENA_PIN 40 // Pullup! (Probably pin 6 on the 10-pin // connector closest to the E0 socket) #endif #endif diff --git a/Marlin/src/pins/ramps/pins_VORON.h b/Marlin/src/pins/ramps/pins_VORON.h index a6cb05928aa4..40ec71b6f0fb 100644 --- a/Marlin/src/pins/ramps/pins_VORON.h +++ b/Marlin/src/pins/ramps/pins_VORON.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -28,7 +28,7 @@ #define BOARD_INFO_NAME "VORON Design v2" -#define RAMPS_D8_PIN 11 +#define RAMPS_D8_PIN 11 #include "pins_RAMPS.h" @@ -36,10 +36,18 @@ // Heaters / Fans // #undef FAN_PIN -#define FAN_PIN 5 // Using the pin for the controller fan since controller fan is always on. -#define CONTROLLER_FAN_PIN 8 -#define ORIG_E0_AUTO_FAN_PIN 6 // Servo pin 6 for E3D Fan -#define ORIG_E1_AUTO_FAN_PIN 6 // Servo pin 6 for E3D Fan (same pin for both extruders since it's the same fan) +#define FAN_PIN 5 // Using the pin for the controller fan since controller fan is always on. +#define CONTROLLER_FAN_PIN 8 + +// +// Auto fans +// +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN 6 // Servo pin 6 for E3D Fan +#endif +#ifndef E1_AUTO_FAN_PIN + #define E1_AUTO_FAN_PIN 6 // Servo pin 6 for E3D Fan (same pin for both extruders since it's the same fan) +#endif // // LCDs and Controllers diff --git a/Marlin/src/pins/ramps/pins_ZRIB_V20.h b/Marlin/src/pins/ramps/pins_ZRIB_V20.h index 450ad1f82548..90433c62d751 100644 --- a/Marlin/src/pins/ramps/pins_ZRIB_V20.h +++ b/Marlin/src/pins/ramps/pins_ZRIB_V20.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -28,24 +28,35 @@ #include "pins_MKS_GEN_13.h" -#define ZRIB_V20_D6_PIN 6 // Fan -#define ZRIB_V20_D9_PIN 9 // Fan2 -#define ZRIB_V20_A10_PIN 10 -#define ZRIB_V20_D16_PIN 16 -#define ZRIB_V20_D17_PIN 17 -#define ZRIB_V20_D23_PIN 23 -#define ZRIB_V20_D25_PIN 25 -#define ZRIB_V20_D27_PIN 27 -#define ZRIB_V20_D29_PIN 29 -#define ZRIB_V20_D37_PIN 37 +#define ZRIB_V20_D6_PIN 6 // Fan +#define ZRIB_V20_D9_PIN 9 // Fan2 +#define ZRIB_V20_A10_PIN 10 +#define ZRIB_V20_D16_PIN 16 +#define ZRIB_V20_D17_PIN 17 +#define ZRIB_V20_D23_PIN 23 +#define ZRIB_V20_D25_PIN 25 +#define ZRIB_V20_D27_PIN 27 +#define ZRIB_V20_D29_PIN 29 +#define ZRIB_V20_D37_PIN 37 -#define ORIG_E0_AUTO_FAN_PIN ZRIB_V20_D6_PIN -#define ORIG_E1_AUTO_FAN_PIN ZRIB_V20_D6_PIN -#define ORIG_E2_AUTO_FAN_PIN ZRIB_V20_D6_PIN -#define ORIG_E3_AUTO_FAN_PIN ZRIB_V20_D6_PIN +// +// Auto fans +// +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN ZRIB_V20_D6_PIN +#endif +#ifndef E1_AUTO_FAN_PIN + #define E1_AUTO_FAN_PIN ZRIB_V20_D6_PIN +#endif +#ifndef E2_AUTO_FAN_PIN + #define E2_AUTO_FAN_PIN ZRIB_V20_D6_PIN +#endif +#ifndef E3_AUTO_FAN_PIN + #define E3_AUTO_FAN_PIN ZRIB_V20_D6_PIN +#endif #ifndef FILWIDTH_PIN - #define FILWIDTH_PIN 11 // Analog Input + #define FILWIDTH_PIN 11 // Analog Input #endif #if ENABLED(ZONESTAR_LCD) @@ -58,12 +69,19 @@ #undef ADC_KEYPAD_PIN #undef BEEPER_PIN - #define LCD_PINS_RS ZRIB_V20_D16_PIN - #define LCD_PINS_ENABLE ZRIB_V20_D17_PIN - #define LCD_PINS_D4 ZRIB_V20_D23_PIN - #define LCD_PINS_D5 ZRIB_V20_D25_PIN - #define LCD_PINS_D6 ZRIB_V20_D27_PIN - #define LCD_PINS_D7 ZRIB_V20_D29_PIN - #define ADC_KEYPAD_PIN ZRIB_V20_A10_PIN - #define BEEPER_PIN ZRIB_V20_D37_PIN + #undef SHIFT_OUT + #undef SHIFT_CLK + #undef SHIFT_LD + #undef BTN_EN1 + #undef BTN_EN2 + #undef BTN_ENC + + #define LCD_PINS_RS ZRIB_V20_D16_PIN + #define LCD_PINS_ENABLE ZRIB_V20_D17_PIN + #define LCD_PINS_D4 ZRIB_V20_D23_PIN + #define LCD_PINS_D5 ZRIB_V20_D25_PIN + #define LCD_PINS_D6 ZRIB_V20_D27_PIN + #define LCD_PINS_D7 ZRIB_V20_D29_PIN + #define ADC_KEYPAD_PIN ZRIB_V20_A10_PIN + #define BEEPER_PIN ZRIB_V20_D37_PIN #endif diff --git a/Marlin/src/pins/ramps/pins_Z_BOLT_X_SERIES.h b/Marlin/src/pins/ramps/pins_Z_BOLT_X_SERIES.h index 9808646d32db..096d970871f2 100644 --- a/Marlin/src/pins/ramps/pins_Z_BOLT_X_SERIES.h +++ b/Marlin/src/pins/ramps/pins_Z_BOLT_X_SERIES.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * Z-Bolt X Series board – based on Arduino Mega2560 */ -#ifndef __AVR_ATmega2560__ +#if NOT_TARGET(__AVR_ATmega2560__) #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #elif HOTENDS > 4 || E_STEPPERS > 4 #error "Z-Bolt X Series board supports up to 4 hotends / E-steppers." @@ -37,129 +37,129 @@ // Servos // #ifndef SERVO0_PIN - #define SERVO0_PIN 11 + #define SERVO0_PIN 11 #endif #ifndef SERVO3_PIN - #define SERVO3_PIN 4 + #define SERVO3_PIN 4 #endif // // Limit Switches // -#define X_MIN_PIN 3 +#define X_MIN_PIN 3 #ifndef X_MAX_PIN - #define X_MAX_PIN 2 + #define X_MAX_PIN 2 #endif -#define Y_MIN_PIN 14 -#define Y_MAX_PIN 15 -#define Z_MIN_PIN 18 -#define Z_MAX_PIN 19 +#define Y_MIN_PIN 14 +#define Y_MAX_PIN 15 +#define Z_MIN_PIN 18 +#define Z_MAX_PIN 19 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 32 + #define Z_MIN_PROBE_PIN 32 #endif // // Steppers // -#define X_STEP_PIN 54 -#define X_DIR_PIN 55 -#define X_ENABLE_PIN 38 +#define X_STEP_PIN 54 +#define X_DIR_PIN 55 +#define X_ENABLE_PIN 38 #ifndef X_CS_PIN - #define X_CS_PIN -1 + #define X_CS_PIN -1 #endif -#define Y_STEP_PIN 60 -#define Y_DIR_PIN 61 -#define Y_ENABLE_PIN 56 +#define Y_STEP_PIN 60 +#define Y_DIR_PIN 61 +#define Y_ENABLE_PIN 56 #ifndef Y_CS_PIN - #define Y_CS_PIN -1 + #define Y_CS_PIN -1 #endif -#define Z_STEP_PIN 46 -#define Z_DIR_PIN 48 -#define Z_ENABLE_PIN 62 +#define Z_STEP_PIN 46 +#define Z_DIR_PIN 48 +#define Z_ENABLE_PIN 62 #ifndef Z_CS_PIN - #define Z_CS_PIN -1 + #define Z_CS_PIN -1 #endif -#define E0_STEP_PIN 26 -#define E0_DIR_PIN 28 -#define E0_ENABLE_PIN 24 +#define E0_STEP_PIN 26 +#define E0_DIR_PIN 28 +#define E0_ENABLE_PIN 24 #ifndef E0_CS_PIN - #define E0_CS_PIN -1 + #define E0_CS_PIN -1 #endif -#define E1_STEP_PIN 36 -#define E1_DIR_PIN 34 -#define E1_ENABLE_PIN 30 +#define E1_STEP_PIN 36 +#define E1_DIR_PIN 34 +#define E1_ENABLE_PIN 30 #ifndef E1_CS_PIN - #define E1_CS_PIN -1 + #define E1_CS_PIN -1 #endif // Red -#define E2_STEP_PIN 42 -#define E2_DIR_PIN 40 -#define E2_ENABLE_PIN 65 +#define E2_STEP_PIN 42 +#define E2_DIR_PIN 40 +#define E2_ENABLE_PIN 65 #ifndef E2_CS_PIN - #define E2_CS_PIN -1 + #define E2_CS_PIN -1 #endif // Black -#define E3_STEP_PIN 44 -#define E3_DIR_PIN 64 -#define E3_ENABLE_PIN 66 +#define E3_STEP_PIN 44 +#define E3_DIR_PIN 64 +#define E3_ENABLE_PIN 66 #ifndef E3_CS_PIN - #define E3_CS_PIN -1 + #define E3_CS_PIN -1 #endif // // Temperature Sensors // -#define TEMP_0_PIN 13 // Analog Input -#define TEMP_1_PIN 15 // Analog Input -#define TEMP_2_PIN 5 // Analog Input (BLACK) -#define TEMP_3_PIN 9 // Analog Input (RED) -#define TEMP_BED_PIN 14 // Analog Input +#define TEMP_0_PIN 13 // Analog Input +#define TEMP_1_PIN 15 // Analog Input +#define TEMP_2_PIN 5 // Analog Input (BLACK) +#define TEMP_3_PIN 9 // Analog Input (RED) +#define TEMP_BED_PIN 14 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 10 -#define HEATER_1_PIN 7 -#define HEATER_2_PIN 6 -#define HEATER_3_PIN 5 -#define HEATER_BED_PIN 8 +#define HEATER_0_PIN 10 +#define HEATER_1_PIN 7 +#define HEATER_2_PIN 6 +#define HEATER_3_PIN 5 +#define HEATER_BED_PIN 8 -#define FAN_PIN 9 +#define FAN_PIN 9 // // Misc. Functions // -#define SDSS 53 -#define LED_PIN 13 +#define SDSS 53 +#define LED_PIN 13 #ifndef FILWIDTH_PIN - #define FILWIDTH_PIN 5 // Analog Input on AUX2 + #define FILWIDTH_PIN 5 // Analog Input on AUX2 #endif // Оn the servos connector #ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN 4 + #define FIL_RUNOUT_PIN 4 #endif #ifndef PS_ON_PIN - #define PS_ON_PIN 12 + #define PS_ON_PIN 12 #endif #if ENABLED(CASE_LIGHT_ENABLE) && !defined(CASE_LIGHT_PIN) && !defined(SPINDLE_LASER_ENA_PIN) - #if NUM_SERVOS <= 1 // Prefer the servo connector - #define CASE_LIGHT_PIN 6 // Hardware PWM + #if NUM_SERVOS <= 1 // Prefer the servo connector + #define CASE_LIGHT_PIN 6 // Hardware PWM #elif HAS_FREE_AUX2_PINS - #define CASE_LIGHT_PIN 44 // Hardware PWM + #define CASE_LIGHT_PIN 44 // Hardware PWM #endif #endif @@ -167,14 +167,14 @@ // M3/M4/M5 - Spindle/Laser Control // #if HAS_CUTTER && !PIN_EXISTS(SPINDLE_LASER_ENA) - #if !defined(NUM_SERVOS) || NUM_SERVOS == 0 // Prefer the servo connector - #define SPINDLE_LASER_ENA_PIN 4 // Pullup or pulldown! - #define SPINDLE_LASER_PWM_PIN 6 // Hardware PWM - #define SPINDLE_DIR_PIN 5 + #if !defined(NUM_SERVOS) || NUM_SERVOS == 0 // Prefer the servo connector + #define SPINDLE_LASER_ENA_PIN 4 // Pullup or pulldown! + #define SPINDLE_LASER_PWM_PIN 6 // Hardware PWM + #define SPINDLE_DIR_PIN 5 #elif HAS_FREE_AUX2_PINS - #define SPINDLE_LASER_ENA_PIN 40 // Pullup or pulldown! - #define SPINDLE_LASER_PWM_PIN 44 // Hardware PWM - #define SPINDLE_DIR_PIN 65 + #define SPINDLE_LASER_ENA_PIN 40 // Pullup or pulldown! + #define SPINDLE_LASER_PWM_PIN 44 // Hardware PWM + #define SPINDLE_DIR_PIN 65 #endif #endif @@ -183,13 +183,13 @@ // #if ENABLED(TMC_USE_SW_SPI) #ifndef TMC_SW_MOSI - #define TMC_SW_MOSI 66 + #define TMC_SW_MOSI 66 #endif #ifndef TMC_SW_MISO - #define TMC_SW_MISO 44 + #define TMC_SW_MISO 44 #endif #ifndef TMC_SW_SCK - #define TMC_SW_SCK 64 + #define TMC_SW_SCK 64 #endif #endif @@ -217,90 +217,90 @@ // #ifndef X_SERIAL_TX_PIN - #define X_SERIAL_TX_PIN 40 + #define X_SERIAL_TX_PIN 40 #endif #ifndef X_SERIAL_RX_PIN - #define X_SERIAL_RX_PIN 63 + #define X_SERIAL_RX_PIN 63 #endif #ifndef X2_SERIAL_TX_PIN - #define X2_SERIAL_TX_PIN -1 + #define X2_SERIAL_TX_PIN -1 #endif #ifndef X2_SERIAL_RX_PIN - #define X2_SERIAL_RX_PIN -1 + #define X2_SERIAL_RX_PIN -1 #endif #ifndef Y_SERIAL_TX_PIN - #define Y_SERIAL_TX_PIN 59 + #define Y_SERIAL_TX_PIN 59 #endif #ifndef Y_SERIAL_RX_PIN - #define Y_SERIAL_RX_PIN 64 + #define Y_SERIAL_RX_PIN 64 #endif #ifndef Y2_SERIAL_TX_PIN - #define Y2_SERIAL_TX_PIN -1 + #define Y2_SERIAL_TX_PIN -1 #endif #ifndef Y2_SERIAL_RX_PIN - #define Y2_SERIAL_RX_PIN -1 + #define Y2_SERIAL_RX_PIN -1 #endif #ifndef Z_SERIAL_TX_PIN - #define Z_SERIAL_TX_PIN 42 + #define Z_SERIAL_TX_PIN 42 #endif #ifndef Z_SERIAL_RX_PIN - #define Z_SERIAL_RX_PIN 65 + #define Z_SERIAL_RX_PIN 65 #endif #ifndef Z2_SERIAL_TX_PIN - #define Z2_SERIAL_TX_PIN -1 + #define Z2_SERIAL_TX_PIN -1 #endif #ifndef Z2_SERIAL_RX_PIN - #define Z2_SERIAL_RX_PIN -1 + #define Z2_SERIAL_RX_PIN -1 #endif #ifndef E0_SERIAL_TX_PIN - #define E0_SERIAL_TX_PIN 44 + #define E0_SERIAL_TX_PIN 44 #endif #ifndef E0_SERIAL_RX_PIN - #define E0_SERIAL_RX_PIN 66 + #define E0_SERIAL_RX_PIN 66 #endif #ifndef E1_SERIAL_TX_PIN - #define E1_SERIAL_TX_PIN -1 + #define E1_SERIAL_TX_PIN -1 #endif #ifndef E1_SERIAL_RX_PIN - #define E1_SERIAL_RX_PIN -1 + #define E1_SERIAL_RX_PIN -1 #endif #ifndef E2_SERIAL_TX_PIN - #define E2_SERIAL_TX_PIN -1 + #define E2_SERIAL_TX_PIN -1 #endif #ifndef E2_SERIAL_RX_PIN - #define E2_SERIAL_RX_PIN -1 + #define E2_SERIAL_RX_PIN -1 #endif #ifndef E3_SERIAL_TX_PIN - #define E3_SERIAL_TX_PIN -1 + #define E3_SERIAL_TX_PIN -1 #endif #ifndef E3_SERIAL_RX_PIN - #define E3_SERIAL_RX_PIN -1 + #define E3_SERIAL_RX_PIN -1 #endif #ifndef E4_SERIAL_TX_PIN - #define E4_SERIAL_TX_PIN -1 + #define E4_SERIAL_TX_PIN -1 #endif #ifndef E4_SERIAL_RX_PIN - #define E4_SERIAL_RX_PIN -1 + #define E4_SERIAL_RX_PIN -1 #endif #ifndef E5_SERIAL_TX_PIN - #define E5_SERIAL_TX_PIN -1 + #define E5_SERIAL_TX_PIN -1 #endif #ifndef E5_SERIAL_RX_PIN - #define E5_SERIAL_RX_PIN -1 + #define E5_SERIAL_RX_PIN -1 #endif #ifndef E6_SERIAL_TX_PIN - #define E6_SERIAL_TX_PIN -1 + #define E6_SERIAL_TX_PIN -1 #endif #ifndef E6_SERIAL_RX_PIN - #define E6_SERIAL_RX_PIN -1 + #define E6_SERIAL_RX_PIN -1 #endif #ifndef E7_SERIAL_TX_PIN - #define E7_SERIAL_TX_PIN -1 + #define E7_SERIAL_TX_PIN -1 #endif #ifndef E7_SERIAL_RX_PIN - #define E7_SERIAL_RX_PIN -1 + #define E7_SERIAL_RX_PIN -1 #endif #endif diff --git a/Marlin/src/pins/sam/pins_ADSK.h b/Marlin/src/pins/sam/pins_ADSK.h index 3a38e5ce1668..b0e171cf1716 100644 --- a/Marlin/src/pins/sam/pins_ADSK.h +++ b/Marlin/src/pins/sam/pins_ADSK.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -27,7 +27,7 @@ #define BOARD_INFO_NAME "ADSK" -#if !defined(__SAM3X8E__) && !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) +#if NOT_TARGET(__SAM3X8E__, __AVR_ATmega1280__, __AVR_ATmega2560__) #error "Oops! Select 'Arduino Due or Mega' in 'Tools > Board.'" #endif @@ -81,55 +81,55 @@ A stepper for E0 extruder // // Servos // -#define SERVO0_PIN 61 // Analog pin 7, Digital pin 61 +#define SERVO0_PIN 61 // Analog pin 7, Digital pin 61 // // Limit Switches // -#define X_MIN_PIN 9 -#define Y_MIN_PIN 10 -#define Z_MIN_PIN 11 +#define X_MIN_PIN 9 +#define Y_MIN_PIN 10 +#define Z_MIN_PIN 11 -#define Z_MIN_PROBE_PIN 62 // Analog pin 8, Digital pin 62 +#define Z_MIN_PROBE_PIN 62 // Analog pin 8, Digital pin 62 // // Steppers // -#define X_STEP_PIN 2 -#define X_DIR_PIN 5 -#define X_ENABLE_PIN 8 +#define X_STEP_PIN 2 +#define X_DIR_PIN 5 +#define X_ENABLE_PIN 8 -#define Y_STEP_PIN 3 -#define Y_DIR_PIN 6 -#define Y_ENABLE_PIN 8 +#define Y_STEP_PIN 3 +#define Y_DIR_PIN 6 +#define Y_ENABLE_PIN 8 -#define Z_STEP_PIN 4 -#define Z_DIR_PIN 7 -#define Z_ENABLE_PIN 8 +#define Z_STEP_PIN 4 +#define Z_DIR_PIN 7 +#define Z_ENABLE_PIN 8 -#define E0_STEP_PIN 12 -#define E0_DIR_PIN 13 -#define E0_ENABLE_PIN 8 +#define E0_STEP_PIN 12 +#define E0_DIR_PIN 13 +#define E0_ENABLE_PIN 8 // // Heaters / Fans // -#define HEATER_0_PIN 55 // "Hold": Analog pin 1, Digital pin 55 -#define HEATER_BED_PIN 57 // "CoolEn": Analog pin 3, Digital pin 57 -#define FAN_PIN 54 // "Abort": Analog pin 0, Digital pin 54 +#define HEATER_0_PIN 55 // "Hold": Analog pin 1, Digital pin 55 +#define HEATER_BED_PIN 57 // "CoolEn": Analog pin 3, Digital pin 57 +#define FAN_PIN 54 // "Abort": Analog pin 0, Digital pin 54 #undef E0_AUTO_FAN_PIN -#define E0_AUTO_FAN_PIN 56 // "Resume": Analog pin 2, Digital pin 56 +#define E0_AUTO_FAN_PIN 56 // "Resume": Analog pin 2, Digital pin 56 // // Temperature Sensors // -#define TEMP_0_PIN 4 // "SDA": Analog pin 4, Digital pin 58 -#define TEMP_BED_PIN 5 // "SCL": Analog pin 5, Digital pin 59 +#define TEMP_0_PIN 4 // "SDA": Analog pin 4, Digital pin 58 +#define TEMP_BED_PIN 5 // "SCL": Analog pin 5, Digital pin 59 // // Misc. Functions // -#define SDSS 52 +#define SDSS 52 #if ENABLED(ZONESTAR_LCD) @@ -160,13 +160,13 @@ A stepper for E0 extruder // // LCD / Controller // - #define LCD_PINS_ENABLE 14 - #define LCD_PINS_RS 15 - #define LCD_PINS_D4 16 - #define LCD_PINS_D5 17 - #define LCD_PINS_D6 18 - #define LCD_PINS_D7 19 - #define ADC_KEYPAD_PIN 6 //60 // Analog pin 6, Digital pin 60 + #define LCD_PINS_ENABLE 14 + #define LCD_PINS_RS 15 + #define LCD_PINS_D4 16 + #define LCD_PINS_D5 17 + #define LCD_PINS_D6 18 + #define LCD_PINS_D7 19 + #define ADC_KEYPAD_PIN 6 //60 // Analog pin 6, Digital pin 60 /** * The below defines will scale all the values to work properly on both @@ -175,12 +175,12 @@ A stepper for E0 extruder #define ADC_BUTTONS_VALUE_SCALE (5.0/AREF_VOLTS) // The LCD module pullup voltage is 5.0V but ADC reference voltage is 3.3V - #define ADC_BUTTONS_R_PULLDOWN 4.7 // Moves voltage down to be bellow 3.3V instead of 5V + #define ADC_BUTTONS_R_PULLDOWN 4.7 // Moves voltage down to be bellow 3.3V instead of 5V // the resistors values will be scaled because of 4.7K pulldown parallel resistor #define _ADC_BUTTONS_R_SCALED(R) ((R) * (ADC_BUTTONS_R_PULLDOWN) / ((R) + ADC_BUTTONS_R_PULLDOWN)) // buttons pullup resistor - #define ADC_BUTTONS_R_PULLUP 4.7 // the resistor on the 2004 LCD panel + #define ADC_BUTTONS_R_PULLUP 4.7 // the resistor on the 2004 LCD panel // buttons resistors with scaled values because of parallel pulldown resistor #define ADC_BUTTONS_LEFT_R_PULLDOWN _ADC_BUTTONS_R_SCALED(0.47) #define ADC_BUTTONS_RIGHT_R_PULLDOWN _ADC_BUTTONS_R_SCALED(4.7) @@ -204,5 +204,4 @@ A stepper for E0 extruder * * Standard ethernet pairs: 1&2, 3&6, 4&5, 7&8 * Use CAT7 cable to have all pairs shielded - * */ diff --git a/Marlin/src/pins/sam/pins_ALLIGATOR_R2.h b/Marlin/src/pins/sam/pins_ALLIGATOR_R2.h index 619d7f62c747..8d6906117dd1 100644 --- a/Marlin/src/pins/sam/pins_ALLIGATOR_R2.h +++ b/Marlin/src/pins/sam/pins_ALLIGATOR_R2.h @@ -16,17 +16,17 @@ * 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 . + * along with this program. If not, see . * */ #pragma once /** * Alligator Board R2 - * http://www.3dartists.org/ + * https://reprap.org/wiki/Alligator_Board */ -#ifndef __SAM3X8E__ +#if NOT_TARGET(__SAM3X8E__) #error "Oops! Select 'Arduino Due' in 'Tools > Board.'" #endif @@ -35,126 +35,125 @@ // // Servos // -#define SERVO0_PIN 36 -#define SERVO1_PIN 40 -#define SERVO2_PIN 41 -#define SERVO3_PIN -1 +#define SERVO0_PIN 36 +#define SERVO1_PIN 40 +#define SERVO2_PIN 41 +#define SERVO3_PIN -1 // // Limit Switches // -#define X_MIN_PIN 33 // PC1 -#define X_MAX_PIN 34 // PC2 -#define Y_MIN_PIN 35 // PC3 -#define Y_MAX_PIN 37 // PC5 -#define Z_MIN_PIN 38 // PC6 -#define Z_MAX_PIN 39 // PC7 +#define X_MIN_PIN 33 // PC1 +#define X_MAX_PIN 34 // PC2 +#define Y_MIN_PIN 35 // PC3 +#define Y_MAX_PIN 37 // PC5 +#define Z_MIN_PIN 38 // PC6 +#define Z_MAX_PIN 39 // PC7 // // Steppers // -#define X_STEP_PIN 96 // PB24 -#define X_DIR_PIN 2 // PB25 -#define X_ENABLE_PIN 24 // PA15, motor RESET pin +#define X_STEP_PIN 96 // PB24 +#define X_DIR_PIN 2 // PB25 +#define X_ENABLE_PIN 24 // PA15, motor RESET pin -#define Y_STEP_PIN 94 // PB22 -#define Y_DIR_PIN 95 // PB23 -#define Y_ENABLE_PIN 24 // PA15, motor RESET pin +#define Y_STEP_PIN 94 // PB22 +#define Y_DIR_PIN 95 // PB23 +#define Y_ENABLE_PIN 24 // PA15, motor RESET pin -#define Z_STEP_PIN 98 // PC27 -#define Z_DIR_PIN 3 // PC28 -#define Z_ENABLE_PIN 24 // PA15, motor RESET pin +#define Z_STEP_PIN 98 // PC27 +#define Z_DIR_PIN 3 // PC28 +#define Z_ENABLE_PIN 24 // PA15, motor RESET pin -#define E0_STEP_PIN 5 // PC25 -#define E0_DIR_PIN 4 // PC26 -#define E0_ENABLE_PIN 24 // PA15, motor RESET pin +#define E0_STEP_PIN 5 // PC25 +#define E0_DIR_PIN 4 // PC26 +#define E0_ENABLE_PIN 24 // PA15, motor RESET pin -#define E1_STEP_PIN 28 // PD3 on piggy -#define E1_DIR_PIN 27 // PD2 on piggy -#define E1_ENABLE_PIN 24 // PA15, motor RESET pin +#define E1_STEP_PIN 28 // PD3 on piggy +#define E1_DIR_PIN 27 // PD2 on piggy +#define E1_ENABLE_PIN 24 // PA15, motor RESET pin -#define E2_STEP_PIN 11 // PD7 on piggy -#define E2_DIR_PIN 29 // PD6 on piggy -#define E2_ENABLE_PIN 24 // PA15, motor RESET pin +#define E2_STEP_PIN 11 // PD7 on piggy +#define E2_DIR_PIN 29 // PD6 on piggy +#define E2_ENABLE_PIN 24 // PA15, motor RESET pin -#define E3_STEP_PIN 30 // PD9 on piggy -#define E3_DIR_PIN 12 // PD8 on piggy -#define E3_ENABLE_PIN 24 // PA15, motor RESET pin +#define E3_STEP_PIN 30 // PD9 on piggy +#define E3_DIR_PIN 12 // PD8 on piggy +#define E3_ENABLE_PIN 24 // PA15, motor RESET pin // Microstepping pins - Mapping not from fastio.h (?) -#define X_MS1_PIN 99 // PC10 -#define Y_MS1_PIN 10 // PC29 -#define Z_MS1_PIN 44 // PC19 -#define E0_MS1_PIN 45 // PC18 +#define X_MS1_PIN 99 // PC10 +#define Y_MS1_PIN 10 // PC29 +#define Z_MS1_PIN 44 // PC19 +#define E0_MS1_PIN 45 // PC18 -//#define MOTOR_FAULT_PIN 22 // PB26 , motor X-Y-Z-E0 motor FAULT +//#define MOTOR_FAULT_PIN 22 // PB26 , motor X-Y-Z-E0 motor FAULT // // Temperature Sensors // -#define TEMP_0_PIN 1 // Analog Input (PA24) -#define TEMP_1_PIN 2 // Analog Input (PA23 on piggy) -#define TEMP_2_PIN 3 // Analog Input (PA22 on piggy) -#define TEMP_3_PIN 4 // Analog Input (PA6 on piggy) -#define TEMP_BED_PIN 0 // Analog Input (PA16) +#define TEMP_0_PIN 1 // Analog Input (PA24) +#define TEMP_1_PIN 2 // Analog Input (PA23 on piggy) +#define TEMP_2_PIN 3 // Analog Input (PA22 on piggy) +#define TEMP_3_PIN 4 // Analog Input (PA6 on piggy) +#define TEMP_BED_PIN 0 // Analog Input (PA16) // // Heaters / Fans // // Note that on the Due pin A0 on the board is channel 2 on the ARM chip -#define HEATER_0_PIN 68 // PA1 -#define HEATER_1_PIN 8 // PC22 on piggy -#define HEATER_2_PIN 9 // PC21 on piggy -#define HEATER_3_PIN 97 // PC20 on piggy -#define HEATER_BED_PIN 69 // PA0 +#define HEATER_0_PIN 68 // PA1 +#define HEATER_1_PIN 8 // PC22 on piggy +#define HEATER_2_PIN 9 // PC21 on piggy +#define HEATER_3_PIN 97 // PC20 on piggy +#define HEATER_BED_PIN 69 // PA0 #ifndef FAN_PIN - #define FAN_PIN 92 // PA5 + #define FAN_PIN 92 // PA5 #endif -#define FAN1_PIN 31 // PA7 +#define FAN1_PIN 31 // PA7 // // Misc. Functions // -#define SDSS 77 // PA28 -#define SD_DETECT_PIN 87 // PA29 -#define LED_RED_PIN 40 // PC8 -#define LED_GREEN_PIN 41 // PC9 +#define SDSS 77 // PA28 +#define SD_DETECT_PIN 87 // PA29 +#define LED_RED_PIN 40 // PC8 +#define LED_GREEN_PIN 41 // PC9 -#define EXP_VOLTAGE_LEVEL_PIN 65 +#define EXP_VOLTAGE_LEVEL_PIN 65 -#define SPI_CHAN_DAC 1 +#define SPI_CHAN_DAC 1 -#define DAC0_SYNC 53 // PB14 -#define DAC1_SYNC 6 // PC24 +#define DAC0_SYNC 53 // PB14 +#define DAC1_SYNC 6 // PC24 // 64K SPI EEPROM #define SPI_EEPROM -#define SPI_CHAN_EEPROM1 2 -#define SPI_EEPROM1_CS 25 // PD0 +#define SPI_CHAN_EEPROM1 2 +#define SPI_EEPROM1_CS 25 // PD0 // 2K SPI EEPROM -#define SPI_EEPROM2_CS 26 // PD1 +#define SPI_EEPROM2_CS 26 // PD1 // FLASH SPI // 32Mb -#define SPI_FLASH_CS 23 // PA14 +#define SPI_FLASH_CS 23 // PA14 // // LCD / Controller // #if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) - - #define LCD_PINS_RS 18 - #define LCD_PINS_ENABLE 15 - #define LCD_PINS_D4 19 - #define BEEPER_PIN 64 - - #define BTN_EN1 14 - #define BTN_EN2 16 - #define BTN_ENC 17 - + #define LCD_PINS_RS 18 + #define LCD_PINS_ENABLE 15 + #define LCD_PINS_D4 19 + #define BEEPER_PIN 64 #undef UI_VOLTAGE_LEVEL - #define UI_VOLTAGE_LEVEL 1 + #define UI_VOLTAGE_LEVEL 1 +#endif -#endif // REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER +#if ENABLED(NEWPANEL) + #define BTN_EN1 14 + #define BTN_EN2 16 + #define BTN_ENC 17 +#endif diff --git a/Marlin/src/pins/sam/pins_ARCHIM1.h b/Marlin/src/pins/sam/pins_ARCHIM1.h index ddc9f407ecd6..6e3768c663bc 100644 --- a/Marlin/src/pins/sam/pins_ARCHIM1.h +++ b/Marlin/src/pins/sam/pins_ARCHIM1.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -37,7 +37,7 @@ * https://github.com/ultimachine/Archim/wiki */ -#ifndef __SAM3X8E__ +#if NOT_TARGET(__SAM3X8E__) #error "Oops! Select 'Archim' in 'Tools > Board.'" #endif @@ -46,7 +46,8 @@ // // Timers // -#define STEP_TIMER_NUM 3 +// These are already defined in DUE, so must be undefined first +#define STEP_TIMER_NUM 3 #define HAL_STEP_TIMER_ISR() void TC3_Handler() // @@ -56,147 +57,145 @@ // // Servos // -#define SERVO0_PIN 20 // D20 PB12 (Header J20 20) -#define SERVO1_PIN 21 // D21 PB13 (Header J20 19) - +#define SERVO0_PIN 20 // D20 PB12 (Header J20 20) +#define SERVO1_PIN 21 // D21 PB13 (Header J20 19) // // Limit Switches // -#define X_MIN_PIN 14 // PD4 MIN ES1 -#define X_MAX_PIN 32 // PD10 MAX ES1 -#define Y_MIN_PIN 29 // PD6 MIN ES2 -#define Y_MAX_PIN 15 // PD5 MAX ES2 -#define Z_MIN_PIN 31 // PA7 MIN ES3 -#define Z_MAX_PIN 30 // PD9 MAX ES3 +#define X_MIN_PIN 14 // PD4 MIN ES1 +#define X_MAX_PIN 32 // PD10 MAX ES1 +#define Y_MIN_PIN 29 // PD6 MIN ES2 +#define Y_MAX_PIN 15 // PD5 MAX ES2 +#define Z_MIN_PIN 31 // PA7 MIN ES3 +#define Z_MAX_PIN 30 // PD9 MAX ES3 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 32 + #define Z_MIN_PROBE_PIN 32 #endif #ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN 66 // D66 PB15 (Header J20 15) + #define FIL_RUNOUT_PIN 66 // D66 PB15 (Header J20 15) #endif #ifndef FIL_RUNOUT2_PIN - #define FIL_RUNOUT2_PIN 67 // D67 PB16 (Header J20 16) + #define FIL_RUNOUT2_PIN 67 // D67 PB16 (Header J20 16) #endif - // // Steppers // -#define X_STEP_PIN 40 // PC8 STEP1 * -#define X_DIR_PIN 59 // PA4 DIR1 * -#define X_ENABLE_PIN 41 // PC9 EN1 +#define X_STEP_PIN 40 // PC8 STEP1 * +#define X_DIR_PIN 59 // PA4 DIR1 * +#define X_ENABLE_PIN 41 // PC9 EN1 -#define Y_STEP_PIN 49 // PC14 STEP2 * -#define Y_DIR_PIN 47 // PC16 DIR2 * -#define Y_ENABLE_PIN 48 // PC15 EN2 * +#define Y_STEP_PIN 49 // PC14 STEP2 * +#define Y_DIR_PIN 47 // PC16 DIR2 * +#define Y_ENABLE_PIN 48 // PC15 EN2 * -#define Z_STEP_PIN 36 // PC4 STEP Z * -#define Z_DIR_PIN 107 // PB10 DIR Z * -#define Z_ENABLE_PIN 96 // PC10 EN Z -AddOns * +#define Z_STEP_PIN 36 // PC4 STEP Z * +#define Z_DIR_PIN 107 // PB10 DIR Z * +#define Z_ENABLE_PIN 96 // PC10 EN Z -AddOns * -#define E0_STEP_PIN 78 // PB23 STEP3 * -#define E0_DIR_PIN 22 // PB26 DIR3 * -#define E0_ENABLE_PIN 97 // PB24 EN3 -Addons * +#define E0_STEP_PIN 78 // PB23 STEP3 * +#define E0_DIR_PIN 22 // PB26 DIR3 * +#define E0_ENABLE_PIN 97 // PB24 EN3 -Addons * -#define E1_STEP_PIN 26 // PD1 STEP4 * -#define E1_DIR_PIN 27 // PD2 DIR4 * -#define E1_ENABLE_PIN 28 // PD3 EN4 * +#define E1_STEP_PIN 26 // PD1 STEP4 * +#define E1_DIR_PIN 27 // PD2 DIR4 * +#define E1_ENABLE_PIN 28 // PD3 EN4 * // Microstepping mode pins * -#define X_MS1_PIN 39 // PC7 MOD0E1 - As listed in schematic -#define X_MS2_PIN 38 // PC6 MOD1E1 -#define X_MS3_PIN 37 // PC5 MOD2E1 +#define X_MS1_PIN 39 // PC7 MOD0E1 - As listed in schematic +#define X_MS2_PIN 38 // PC6 MOD1E1 +#define X_MS3_PIN 37 // PC5 MOD2E1 -#define Y_MS1_PIN 50 // PC13 MODE0E2 -#define Y_MS2_PIN 51 // PC12 MODE1E2 -#define Y_MS3_PIN 92 // PC11 MODE2E2 - AddOns +#define Y_MS1_PIN 50 // PC13 MODE0E2 +#define Y_MS2_PIN 51 // PC12 MODE1E2 +#define Y_MS3_PIN 92 // PC11 MODE2E2 - AddOns -#define Z_MS1_PIN 44 // PC19 MOD0E Z -#define Z_MS2_PIN 45 // PC18 MOD1E Z -#define Z_MS3_PIN 46 // PC17 MOD2E Z +#define Z_MS1_PIN 44 // PC19 MOD0E Z +#define Z_MS2_PIN 45 // PC18 MOD1E Z +#define Z_MS3_PIN 46 // PC17 MOD2E Z -#define E0_MS1_PIN 105 // PB22 MOD0E3 - AddOns -#define E0_MS2_PIN 106 // PC27 MOD1E3 - AddOns -#define E0_MS3_PIN 104 // PC20 MOD2E3 - AddOns +#define E0_MS1_PIN 105 // PB22 MOD0E3 - AddOns +#define E0_MS2_PIN 106 // PC27 MOD1E3 - AddOns +#define E0_MS3_PIN 104 // PC20 MOD2E3 - AddOns -#define E1_MS1_PIN 25 // PD0 MOD0E4 -#define E1_MS2_PIN 18 // PA11 MOD1E4 -#define E1_MS3_PIN 19 // PA10 MOD2E4 +#define E1_MS1_PIN 25 // PD0 MOD0E4 +#define E1_MS2_PIN 18 // PA11 MOD1E4 +#define E1_MS3_PIN 19 // PA10 MOD2E4 // Motor current PWM pins * -#define MOTOR_CURRENT_PWM_X_PIN 58 // PA6 X-REF TIOB2 -#define MOTOR_CURRENT_PWM_Y_PIN 12 // PD8 Y-REF TIOB8 -#define MOTOR_CURRENT_PWM_Z_PIN 10 // PC29 Z-REF TIOB7 -#define MOTOR_CURRENT_PWM_E0_PIN 3 // PC28 E1-REF TIOA7 -#define MOTOR_CURRENT_PWM_E1_PIN 11 // PD7 E2-REF TIOA8 +#define MOTOR_CURRENT_PWM_X_PIN 58 // PA6 X-REF TIOB2 +#define MOTOR_CURRENT_PWM_Y_PIN 12 // PD8 Y-REF TIOB8 +#define MOTOR_CURRENT_PWM_Z_PIN 10 // PC29 Z-REF TIOB7 +#define MOTOR_CURRENT_PWM_E0_PIN 3 // PC28 E1-REF TIOA7 +#define MOTOR_CURRENT_PWM_E1_PIN 11 // PD7 E2-REF TIOA8 -#define MOTOR_CURRENT_PWM_RANGE 2750 // (3.3 Volts * 100000 Ohms) / (100000 Ohms + 20000 Ohms) = 2.75 Volts (max vref) +#define MOTOR_CURRENT_PWM_RANGE 2750 // (3.3 Volts * 100000 Ohms) / (100000 Ohms + 20000 Ohms) = 2.75 Volts (max vref) #define DEFAULT_PWM_MOTOR_CURRENT { 1000, 1000, 1000 } //, 1000, 1000} // X Y Z E0 E1, 1000 = 1000mAh // // Temperature Sensors // -#define TEMP_0_PIN 10 // D10 PB19 THERM AN1 * -#define TEMP_1_PIN 9 // D9 PB18 THERM AN2 * -#define TEMP_2_PIN 8 // D8 PB17 THERM AN4 * -#define TEMP_BED_PIN 11 // D11 PB20 THERM AN3 * +#define TEMP_0_PIN 10 // D10 PB19 THERM AN1 * +#define TEMP_1_PIN 9 // D9 PB18 THERM AN2 * +#define TEMP_2_PIN 8 // D8 PB17 THERM AN4 * +#define TEMP_BED_PIN 11 // D11 PB20 THERM AN3 * // // Heaters / Fans // -#define HEATER_0_PIN 6 // D6 PC24 FET_PWM3 -#define HEATER_1_PIN 7 // D7 PC23 FET_PWM4 -#define HEATER_2_PIN 8 // D8 PC22 FET_PWM5 -#define HEATER_BED_PIN 9 // D9 PC21 BED_PWM +#define HEATER_0_PIN 6 // D6 PC24 FET_PWM3 +#define HEATER_1_PIN 7 // D7 PC23 FET_PWM4 +#define HEATER_2_PIN 8 // D8 PC22 FET_PWM5 +#define HEATER_BED_PIN 9 // D9 PC21 BED_PWM #ifndef FAN_PIN - #define FAN_PIN 4 // D4 PC26 FET_PWM1 + #define FAN_PIN 4 // D4 PC26 FET_PWM1 #endif -#define FAN1_PIN 5 // D5 PC25 FET_PWM2 +#define FAN1_PIN 5 // D5 PC25 FET_PWM2 // // Misc. Functions // // Internal MicroSD card reader on the PCB -#define INT_SCK_PIN 42 // D42 PA19/MCCK -#define INT_MISO_PIN 43 // D43 PA20/MCCDA -#define INT_MOSI_PIN 73 // D73 PA21/MCDA0 -#define INT_SDSS 55 // D55 PA24/MCDA3 +#define INT_SCK_PIN 42 // D42 PA19/MCCK +#define INT_MISO_PIN 43 // D43 PA20/MCCDA +#define INT_MOSI_PIN 73 // D73 PA21/MCDA0 +#define INT_SDSS 55 // D55 PA24/MCDA3 // External SD card reader on SC2 -#define SCK_PIN 76 // D76 PA27 -#define MISO_PIN 74 // D74 PA25 -#define MOSI_PIN 75 // D75 PA26 -#define SDSS 87 // D87 PA29 +#define SCK_PIN 76 // D76 PA27 +#define MISO_PIN 74 // D74 PA25 +#define MOSI_PIN 75 // D75 PA26 +#define SDSS 87 // D87 PA29 // 2MB SPI Flash -#define SPI_FLASH_SS 52 // D52 PB21 +#define SPI_FLASH_SS 52 // D52 PB21 // // LCD / Controller // -#if HAS_SPI_LCD - #define BEEPER_PIN 23 // D24 PA15_CTS1 - #define LCD_PINS_RS 17 // D17 PA12_RXD1 - #define LCD_PINS_ENABLE 24 // D23 PA14_RTS1 - #define LCD_PINS_D4 69 // D69 PA0_CANTX0 - #define LCD_PINS_D5 54 // D54 PA16_SCK1 - #define LCD_PINS_D6 68 // D68 PA1_CANRX0 - #define LCD_PINS_D7 34 // D34 PC2_PWML0 +#if HAS_WIRED_LCD + #define BEEPER_PIN 23 // D24 PA15_CTS1 + #define LCD_PINS_RS 17 // D17 PA12_RXD1 + #define LCD_PINS_ENABLE 24 // D23 PA14_RTS1 + #define LCD_PINS_D4 69 // D69 PA0_CANTX0 + #define LCD_PINS_D5 54 // D54 PA16_SCK1 + #define LCD_PINS_D6 68 // D68 PA1_CANRX0 + #define LCD_PINS_D7 34 // D34 PC2_PWML0 - #define SD_DETECT_PIN 2 // D2 PB25_TIOA0 + #define SD_DETECT_PIN 2 // D2 PB25_TIOA0 #if ENABLED(NEWPANEL) // Buttons on AUX-2 - #define BTN_EN1 60 // D60 PA3_TIOB1 - #define BTN_EN2 13 // D13 PB27_TIOB0 - #define BTN_ENC 16 // D16 PA13_TXD1 + #define BTN_EN1 60 // D60 PA3_TIOB1 + #define BTN_EN2 13 // D13 PB27_TIOB0 + #define BTN_ENC 16 // D16 PA13_TXD1 #endif // NEWPANEL -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD diff --git a/Marlin/src/pins/sam/pins_ARCHIM2.h b/Marlin/src/pins/sam/pins_ARCHIM2.h index acd515d8c156..5a3fe0e4d5c7 100644 --- a/Marlin/src/pins/sam/pins_ARCHIM2.h +++ b/Marlin/src/pins/sam/pins_ARCHIM2.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -37,7 +37,7 @@ * https://github.com/ultimachine/Archim/wiki */ -#ifndef __SAM3X8E__ +#if NOT_TARGET(__SAM3X8E__) #error "Oops! Select 'Archim' in 'Tools > Board.'" #elif DISABLED(TMC_USE_SW_SPI) #error "Archim2 requires Software SPI. Enable TMC_USE_SW_SPI in Configuration_adv.h." @@ -52,8 +52,8 @@ // // Servos // -#define SERVO0_PIN 20 // D20 PB12 (Header J20 20) -#define SERVO1_PIN 21 // D21 PB13 (Header J20 19) +#define SERVO0_PIN 20 // D20 PB12 (Header J20 20) +#define SERVO1_PIN 21 // D21 PB13 (Header J20 19) // // Limit Switches @@ -65,83 +65,83 @@ // Otherwise use a physical endstop based configuration. // TMC2130 Diag Pins - #define X_DIAG_PIN 59 // PA4 - #define Y_DIAG_PIN 48 // PC15 - #define Z_DIAG_PIN 36 // PC4 - #define E0_DIAG_PIN 78 // PB23 - #define E1_DIAG_PIN 25 // PD0 + #define X_DIAG_PIN 59 // PA4 + #define Y_DIAG_PIN 48 // PC15 + #define Z_DIAG_PIN 36 // PC4 + #define E0_DIAG_PIN 78 // PB23 + #define E1_DIAG_PIN 25 // PD0 #if X_HOME_DIR < 0 - #define X_MIN_PIN X_DIAG_PIN - #define X_MAX_PIN 32 + #define X_MIN_PIN X_DIAG_PIN + #define X_MAX_PIN 32 #else - #define X_MIN_PIN 14 - #define X_MAX_PIN X_DIAG_PIN + #define X_MIN_PIN 14 + #define X_MAX_PIN X_DIAG_PIN #endif #if Y_HOME_DIR < 0 - #define Y_MIN_PIN Y_DIAG_PIN - #define Y_MAX_PIN 15 + #define Y_MIN_PIN Y_DIAG_PIN + #define Y_MAX_PIN 15 #else - #define Y_MIN_PIN 29 - #define Y_MAX_PIN Y_DIAG_PIN + #define Y_MIN_PIN 29 + #define Y_MAX_PIN Y_DIAG_PIN #endif #else - #define X_MIN_PIN 14 // PD4 MIN ES1 - #define X_MAX_PIN 32 // PD10 MAX ES1 - #define Y_MIN_PIN 29 // PD6 MIN ES2 - #define Y_MAX_PIN 15 // PD5 MAX ES2 + #define X_MIN_PIN 14 // PD4 MIN ES1 + #define X_MAX_PIN 32 // PD10 MAX ES1 + #define Y_MIN_PIN 29 // PD6 MIN ES2 + #define Y_MAX_PIN 15 // PD5 MAX ES2 #endif -#define Z_MIN_PIN 31 // PA7 MIN ES3 -#define Z_MAX_PIN 30 // PD9 MAX ES3 +#define Z_MIN_PIN 31 // PA7 MIN ES3 +#define Z_MAX_PIN 30 // PD9 MAX ES3 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 32 + #define Z_MIN_PROBE_PIN 32 #endif // // Steppers // -#define X_STEP_PIN 38 // PC6 X-STEP * -#define X_DIR_PIN 37 // PC5 X-DIR * -#define X_ENABLE_PIN 41 // PC9 EN1 +#define X_STEP_PIN 38 // PC6 X-STEP * +#define X_DIR_PIN 37 // PC5 X-DIR * +#define X_ENABLE_PIN 41 // PC9 EN1 #ifndef X_CS_PIN - #define X_CS_PIN 39 // PC7 X_nCS + #define X_CS_PIN 39 // PC7 X_nCS #endif -#define Y_STEP_PIN 51 // PC12 Y-STEP * -#define Y_DIR_PIN 92 // PC11 Y-DIR -AddOns * -#define Y_ENABLE_PIN 49 // PC14 Y-EN * +#define Y_STEP_PIN 51 // PC12 Y-STEP * +#define Y_DIR_PIN 92 // PC11 Y-DIR -AddOns * +#define Y_ENABLE_PIN 49 // PC14 Y-EN * #ifndef Y_CS_PIN - #define Y_CS_PIN 50 // PC13 Y_nCS + #define Y_CS_PIN 50 // PC13 Y_nCS #endif -#define Z_STEP_PIN 46 // PC17 Z-STEP * -#define Z_DIR_PIN 47 // PC16 Z-DIR * -#define Z_ENABLE_PIN 44 // PC19 Z-END * +#define Z_STEP_PIN 46 // PC17 Z-STEP * +#define Z_DIR_PIN 47 // PC16 Z-DIR * +#define Z_ENABLE_PIN 44 // PC19 Z-END * #ifndef Z_CS_PIN - #define Z_CS_PIN 45 // PC18 Z_nCS + #define Z_CS_PIN 45 // PC18 Z_nCS #endif -#define E0_STEP_PIN 107 // PB10 E1-STEP -AddOns * -#define E0_DIR_PIN 96 // PC10 E1-DIR -AddOns * -#define E0_ENABLE_PIN 105 // PB22 E1-EN -AddOns * +#define E0_STEP_PIN 107 // PB10 E1-STEP -AddOns * +#define E0_DIR_PIN 96 // PC10 E1-DIR -AddOns * +#define E0_ENABLE_PIN 105 // PB22 E1-EN -AddOns * #ifndef E0_CS_PIN - #define E0_CS_PIN 104 // PC20 E1_nCS -AddOns * + #define E0_CS_PIN 104 // PC20 E1_nCS -AddOns * #endif -#define E1_STEP_PIN 22 // PB26 E2_STEP * -#define E1_DIR_PIN 97 // PB24 E2_DIR -AddOns * -#define E1_ENABLE_PIN 18 // PA11 E2-EN +#define E1_STEP_PIN 22 // PB26 E2_STEP * +#define E1_DIR_PIN 97 // PB24 E2_DIR -AddOns * +#define E1_ENABLE_PIN 18 // PA11 E2-EN #ifndef E1_CS_PIN - #define E1_CS_PIN 19 // PA10 E2_nCS + #define E1_CS_PIN 19 // PA10 E2_nCS #endif // @@ -150,106 +150,108 @@ // #if ENABLED(TMC_USE_SW_SPI) #ifndef TMC_SW_MOSI - #define TMC_SW_MOSI 28 // PD3 + #define TMC_SW_MOSI 28 // PD3 #endif #ifndef TMC_SW_MISO - #define TMC_SW_MISO 26 // PD1 + #define TMC_SW_MISO 26 // PD1 #endif #ifndef TMC_SW_SCK - #define TMC_SW_SCK 27 // PD2 + #define TMC_SW_SCK 27 // PD2 #endif #endif // // Temperature Sensors // -#define TEMP_0_PIN 10 // D10 PB19 THERM AN1 * -#define TEMP_1_PIN 9 // D9 PB18 THERM AN2 * -#define TEMP_2_PIN 8 // D8 PB17 THERM AN4 * -#define TEMP_BED_PIN 11 // D11 PB20 THERM AN3 * +#define TEMP_0_PIN 10 // D10 PB19 THERM AN1 * +#define TEMP_1_PIN 9 // D9 PB18 THERM AN2 * +#define TEMP_2_PIN 8 // D8 PB17 THERM AN4 * +#define TEMP_BED_PIN 11 // D11 PB20 THERM AN3 * // // Heaters / Fans // -#define HEATER_0_PIN 6 // D6 PC24 FET_PWM3 -#define HEATER_1_PIN 7 // D7 PC23 FET_PWM4 -#define HEATER_2_PIN 8 // D8 PC22 FET_PWM5 -#define HEATER_BED_PIN 9 // D9 PC21 BED_PWM +#define HEATER_0_PIN 6 // D6 PC24 FET_PWM3 +#define HEATER_1_PIN 7 // D7 PC23 FET_PWM4 +#define HEATER_2_PIN 8 // D8 PC22 FET_PWM5 +#define HEATER_BED_PIN 9 // D9 PC21 BED_PWM #ifndef FAN_PIN - #define FAN_PIN 4 // D4 PC26 FET_PWM1 + #define FAN_PIN 4 // D4 PC26 FET_PWM1 #endif -#define FAN1_PIN 5 // D5 PC25 FET_PWM2 +#define FAN1_PIN 5 // D5 PC25 FET_PWM2 // // Misc. Functions // // Internal MicroSD card reader on the PCB -#define INT_SCK_PIN 42 // D42 PA19/MCCK -#define INT_MISO_PIN 43 // D43 PA20/MCCDA -#define INT_MOSI_PIN 73 // D73 PA21/MCDA0 -#define INT_SDSS 55 // D55 PA24/MCDA3 +#define INT_SCK_PIN 42 // D42 PA19/MCCK +#define INT_MISO_PIN 43 // D43 PA20/MCCDA +#define INT_MOSI_PIN 73 // D73 PA21/MCDA0 +#define INT_SDSS 55 // D55 PA24/MCDA3 // External SD card reader on SC2 -#define SCK_PIN 76 // D76 PA27 -#define MISO_PIN 74 // D74 PA25 -#define MOSI_PIN 75 // D75 PA26 -#define SDSS 87 // D87 PA29 +#define SCK_PIN 76 // D76 PA27 +#define MISO_PIN 74 // D74 PA25 +#define MOSI_PIN 75 // D75 PA26 +#define SDSS 87 // D87 PA29 // Unused Digital GPIO J20 Pins -#define GPIO_PB1_J20_5 94 // D94 PB1 (Header J20 5) -#define GPIO_PB0_J20_6 95 // D95 PB0 (Header J20 6) -#define GPIO_PB3_J20_7 103 // D103 PB3 (Header J20 7) -#define GPIO_PB2_J20_8 93 // D93 PB2 (Header J20 8) -#define GPIO_PB6_J20_9 99 // D99 PB6 (Header J20 9) -#define GPIO_PB5_J20_10 101 // D101 PB5 (Header J20 10) -#define GPIO_PB8_J20_11 100 // D100 PB8 (Header J20 11) -#define GPIO_PB4_J20_12 102 // D102 PB4 (Header J20 12) -#define GPIO_PB9_J20_13 108 // D108 PB9 (Header J20 13) -#define GPIO_PB7_J20_14 98 // D98 PB7 (Header J20 14) -#define GPIO_PB15_J20_15 66 // D66 PB15 (Header J20 15) -#define GPIO_PB16_J20_16 67 // D67 PB16 (Header J20 16) -#define GPIO_PB14_J20_17 53 // D53 PB14 (Header J20 17) -#define GPIO_PA18_J20_21 71 // D71 PA17 (Header J20 21) -#define GPIO_PA17_J20_22 70 // D70 PA17 (Header J20 22) +#define GPIO_PB1_J20_5 94 // D94 PB1 (Header J20 5) +#define GPIO_PB0_J20_6 95 // D95 PB0 (Header J20 6) +#define GPIO_PB3_J20_7 103 // D103 PB3 (Header J20 7) +#define GPIO_PB2_J20_8 93 // D93 PB2 (Header J20 8) +#define GPIO_PB6_J20_9 99 // D99 PB6 (Header J20 9) +#define GPIO_PB5_J20_10 101 // D101 PB5 (Header J20 10) +#define GPIO_PB8_J20_11 100 // D100 PB8 (Header J20 11) +#define GPIO_PB4_J20_12 102 // D102 PB4 (Header J20 12) +#define GPIO_PB9_J20_13 108 // D108 PB9 (Header J20 13) +#define GPIO_PB7_J20_14 98 // D98 PB7 (Header J20 14) +#define GPIO_PB15_J20_15 66 // D66 PB15 (Header J20 15) +#define GPIO_PB16_J20_16 67 // D67 PB16 (Header J20 16) +#define GPIO_PB14_J20_17 53 // D53 PB14 (Header J20 17) +#define GPIO_PA18_J20_21 71 // D71 PA17 (Header J20 21) +#define GPIO_PA17_J20_22 70 // D70 PA17 (Header J20 22) // Case Light -#define CASE_LIGHT_PIN GPIO_PB1_J20_5 +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN GPIO_PB1_J20_5 +#endif // 2MB SPI Flash -#define SPI_FLASH_SS 52 // D52 PB21 +#define SPI_FLASH_SS 52 // D52 PB21 // // Filament Runout Sensor // #ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN GPIO_PB15_J20_15 + #define FIL_RUNOUT_PIN GPIO_PB15_J20_15 #endif #ifndef FIL_RUNOUT2_PIN - #define FIL_RUNOUT2_PIN GPIO_PB16_J20_16 + #define FIL_RUNOUT2_PIN GPIO_PB16_J20_16 #endif // // LCD / Controller // -#if HAS_SPI_LCD || TOUCH_UI_ULTIPANEL || ENABLED(TOUCH_UI_FTDI_EVE) - #define BEEPER_PIN 23 // D24 PA15_CTS1 - #define LCD_PINS_RS 17 // D17 PA12_RXD1 - #define LCD_PINS_ENABLE 24 // D23 PA14_RTS1 - #define LCD_PINS_D4 69 // D69 PA0_CANTX0 - #define LCD_PINS_D5 54 // D54 PA16_SCK1 - #define LCD_PINS_D6 68 // D68 PA1_CANRX0 - #define LCD_PINS_D7 34 // D34 PC2_PWML0 - - #define SD_DETECT_PIN 2 // D2 PB25_TIOA0 - - #if ENABLED(ULTIPANEL) || TOUCH_UI_ULTIPANEL || ENABLED(TOUCH_UI_FTDI_EVE) +#if ANY(HAS_WIRED_LCD, TOUCH_UI_ULTIPANEL, TOUCH_UI_FTDI_EVE) + #define BEEPER_PIN 23 // D24 PA15_CTS1 + #define LCD_PINS_RS 17 // D17 PA12_RXD1 + #define LCD_PINS_ENABLE 24 // D23 PA14_RTS1 + #define LCD_PINS_D4 69 // D69 PA0_CANTX0 + #define LCD_PINS_D5 54 // D54 PA16_SCK1 + #define LCD_PINS_D6 68 // D68 PA1_CANRX0 + #define LCD_PINS_D7 34 // D34 PC2_PWML0 + + #define SD_DETECT_PIN 2 // D2 PB25_TIOA0 + + #if ANY(ULTIPANEL, TOUCH_UI_ULTIPANEL, TOUCH_UI_FTDI_EVE) // Buttons on AUX-2 - #define BTN_EN1 60 // D60 PA3_TIOB1 - #define BTN_EN2 13 // D13 PB27_TIOB0 - #define BTN_ENC 16 // D16 PA13_TXD1 // the click - #endif // ULTIPANEL || TOUCH_UI_ULTIPANEL -#endif // HAS_SPI_LCD + #define BTN_EN1 60 // D60 PA3_TIOB1 + #define BTN_EN2 13 // D13 PB27_TIOB0 + #define BTN_ENC 16 // D16 PA13_TXD1 // the click + #endif +#endif diff --git a/Marlin/src/pins/sam/pins_CNCONTROLS_15D.h b/Marlin/src/pins/sam/pins_CNCONTROLS_15D.h index 69fb2a3dfc52..fcd2bb4c67bf 100644 --- a/Marlin/src/pins/sam/pins_CNCONTROLS_15D.h +++ b/Marlin/src/pins/sam/pins_CNCONTROLS_15D.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -24,7 +24,7 @@ * CNControls V15 for HMS434 with DUE pin assignments */ -#ifndef __SAM3X8E__ +#if NOT_TARGET(__SAM3X8E__) #error "Oops! Select 'Arduino Due' in 'Tools > Board.'" #endif @@ -33,91 +33,106 @@ // // Servos // -#define SERVO0_PIN 6 +#define SERVO0_PIN 6 // // Limit Switches // -#define X_STOP_PIN 34 -#define Y_STOP_PIN 39 -#define Z_STOP_PIN 62 +#define X_STOP_PIN 34 +#define Y_STOP_PIN 39 +#define Z_STOP_PIN 62 #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 49 + #define Z_MIN_PROBE_PIN 49 #endif // // Steppers // -#define X_STEP_PIN 14 -#define X_DIR_PIN 25 -#define X_ENABLE_PIN 26 +#define X_STEP_PIN 14 +#define X_DIR_PIN 25 +#define X_ENABLE_PIN 26 -#define Y_STEP_PIN 11 -#define Y_DIR_PIN 12 -#define Y_ENABLE_PIN 15 +#define Y_STEP_PIN 11 +#define Y_DIR_PIN 12 +#define Y_ENABLE_PIN 15 -#define Z_STEP_PIN 24 -#define Z_DIR_PIN 27 -#define Z_ENABLE_PIN 28 +#define Z_STEP_PIN 24 +#define Z_DIR_PIN 27 +#define Z_ENABLE_PIN 28 -#define E0_STEP_PIN 64 -#define E0_DIR_PIN 65 -#define E0_ENABLE_PIN 63 +#define E0_STEP_PIN 64 +#define E0_DIR_PIN 65 +#define E0_ENABLE_PIN 63 -#define E1_STEP_PIN 8 -#define E1_DIR_PIN 7 -#define E1_ENABLE_PIN 29 +#define E1_STEP_PIN 8 +#define E1_DIR_PIN 7 +#define E1_ENABLE_PIN 29 // // Temperature Sensors // Analog Inputs // -#define TEMP_0_PIN 1 -#define TEMP_1_PIN 2 -#define TEMP_BED_PIN 4 +#define TEMP_0_PIN 1 +#define TEMP_1_PIN 2 +#define TEMP_BED_PIN 4 #ifndef TEMP_CHAMBER_PIN - #define TEMP_CHAMBER_PIN 5 + #define TEMP_CHAMBER_PIN 5 #endif // // Heaters // -#define HEATER_0_PIN 3 -#define HEATER_1_PIN 4 -#define HEATER_BED_PIN 32 -#define HEATER_CHAMBER_PIN 33 +#define HEATER_0_PIN 3 +#define HEATER_1_PIN 4 +#define HEATER_BED_PIN 32 +#define HEATER_CHAMBER_PIN 33 // // Fans // -//#define FAN0_PIN 8 -#define ORIG_E0_AUTO_FAN_PIN 30 -#define ORIG_E1_AUTO_FAN_PIN 30 -#define ORIG_E2_AUTO_FAN_PIN 30 -#define ORIG_E3_AUTO_FAN_PIN 30 -#define ORIG_CHAMBER_AUTO_FAN_PIN 10 +//#define FAN_PIN 8 + +// +// Auto fans +// +#define AUTO_FAN_PIN 30 +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN AUTO_FAN_PIN +#endif +#ifndef E1_AUTO_FAN_PIN + #define E1_AUTO_FAN_PIN AUTO_FAN_PIN +#endif +#ifndef E2_AUTO_FAN_PIN + #define E2_AUTO_FAN_PIN AUTO_FAN_PIN +#endif +#ifndef E3_AUTO_FAN_PIN + #define E3_AUTO_FAN_PIN AUTO_FAN_PIN +#endif +#ifndef CHAMBER_AUTO_FAN_PIN + #define CHAMBER_AUTO_FAN_PIN 10 +#endif // // SD card // -#define SCK_PIN 76 -#define MISO_PIN 74 -#define MOSI_PIN 75 -#define SDSS 53 -#define SD_DETECT_PIN 40 +#define SCK_PIN 76 +#define MISO_PIN 74 +#define MOSI_PIN 75 +#define SDSS 53 +#define SD_DETECT_PIN 40 // Common I/O -//#define PWM_1_PIN 6 // probe -//#define PWM_2_PIN 13 -//#define SPARE_IO 17 -#define BEEPER_PIN 13 -#define STAT_LED_BLUE_PIN -1 -#define STAT_LED_RED_PIN 31 +//#define PWM_1_PIN 6 // probe +//#define PWM_2_PIN 13 +//#define SPARE_IO 17 +#define BEEPER_PIN 13 +#define STAT_LED_BLUE_PIN -1 +#define STAT_LED_RED_PIN 31 // G425 CALIBRATION_GCODE default pin #ifndef CALIBRATION_PIN - #define CALIBRATION_PIN 66 + #define CALIBRATION_PIN 66 #endif diff --git a/Marlin/src/pins/sam/pins_DUE3DOM.h b/Marlin/src/pins/sam/pins_DUE3DOM.h index 4f352ff1523e..cd4033aa6f1f 100644 --- a/Marlin/src/pins/sam/pins_DUE3DOM.h +++ b/Marlin/src/pins/sam/pins_DUE3DOM.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * DUE3DOM pin assignments */ -#ifndef __SAM3X8E__ +#if NOT_TARGET(__SAM3X8E__) #error "Oops! Select 'Arduino Due' in 'Tools > Board.'" #endif @@ -34,138 +34,138 @@ // // Servos // -#define SERVO0_PIN 5 -#define SERVO1_PIN 6 -#define SERVO2_PIN 13 -#define SERVO3_PIN -1 +#define SERVO0_PIN 5 +#define SERVO1_PIN 6 +#define SERVO2_PIN 13 +#define SERVO3_PIN -1 // // Limit Switches // -#define X_MIN_PIN 38 -#define X_MAX_PIN 36 -#define Y_MIN_PIN 34 -#define Y_MAX_PIN 32 -#define Z_MIN_PIN 30 -#define Z_MAX_PIN 28 +#define X_MIN_PIN 38 +#define X_MAX_PIN 36 +#define Y_MIN_PIN 34 +#define Y_MAX_PIN 32 +#define Z_MIN_PIN 30 +#define Z_MAX_PIN 28 // // Steppers // -#define X_STEP_PIN 2 -#define X_DIR_PIN 3 -#define X_ENABLE_PIN 22 +#define X_STEP_PIN 2 +#define X_DIR_PIN 3 +#define X_ENABLE_PIN 22 -#define Y_STEP_PIN 17 -#define Y_DIR_PIN 16 -#define Y_ENABLE_PIN 26 +#define Y_STEP_PIN 17 +#define Y_DIR_PIN 16 +#define Y_ENABLE_PIN 26 -#define Z_STEP_PIN 61 // Z1 STP -#define Z_DIR_PIN 60 // Z1 DIR -#define Z_ENABLE_PIN 15 // Z1 ENA +#define Z_STEP_PIN 61 // Z1 STP +#define Z_DIR_PIN 60 // Z1 DIR +#define Z_ENABLE_PIN 15 // Z1 ENA -#define E0_STEP_PIN 64 // Z2 STP -#define E0_DIR_PIN 63 // Z2 DIR -#define E0_ENABLE_PIN 62 // Z2 ENA +#define E0_STEP_PIN 64 // Z2 STP +#define E0_DIR_PIN 63 // Z2 DIR +#define E0_ENABLE_PIN 62 // Z2 ENA -#define E1_STEP_PIN 51 // E1 STP -#define E1_DIR_PIN 53 // E1 DIR -#define E1_ENABLE_PIN 65 // E1 ENA +#define E1_STEP_PIN 51 // E1 STP +#define E1_DIR_PIN 53 // E1 DIR +#define E1_ENABLE_PIN 65 // E1 ENA -#define E2_STEP_PIN 24 // E2 STP -#define E2_DIR_PIN 23 // E2 DIR -#define E2_ENABLE_PIN 49 // E2 ENA +#define E2_STEP_PIN 24 // E2 STP +#define E2_DIR_PIN 23 // E2 DIR +#define E2_ENABLE_PIN 49 // E2 ENA // // Temperature Sensors // -#define TEMP_0_PIN 0 // Analog Input (HOTEND0 thermistor) -#define TEMP_1_PIN 2 // Analog Input (HOTEND1 thermistor) -#define TEMP_2_PIN 5 // Analog Input (unused) -#define TEMP_BED_PIN 1 // Analog Input (BED thermistor) +#define TEMP_0_PIN 0 // Analog Input (HOTEND0 thermistor) +#define TEMP_1_PIN 2 // Analog Input (HOTEND1 thermistor) +#define TEMP_2_PIN 5 // Analog Input (unused) +#define TEMP_BED_PIN 1 // Analog Input (BED thermistor) // SPI for Max6675 or Max31855 Thermocouple #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN -1 + #define MAX6675_SS_PIN -1 #else - #define MAX6675_SS_PIN -1 + #define MAX6675_SS_PIN -1 #endif // // Heaters / Fans // -#define HEATER_0_PIN 7 // HOTEND0 MOSFET -#define HEATER_1_PIN 8 // HOTEND1 MOSFET -#define HEATER_BED_PIN 39 // BED MOSFET +#define HEATER_0_PIN 7 // HOTEND0 MOSFET +#define HEATER_1_PIN 8 // HOTEND1 MOSFET +#define HEATER_BED_PIN 39 // BED MOSFET #ifndef FAN_PIN - #define FAN_PIN 11 // FAN1 header on board - PRINT FAN + #define FAN_PIN 11 // FAN1 header on board - PRINT FAN #endif -#define FAN1_PIN 9 // FAN2 header on board - CONTROLLER FAN -#define FAN2_PIN 12 // FAN3 header on board - EXTRUDER0 FAN +#define FAN1_PIN 9 // FAN2 header on board - CONTROLLER FAN +#define FAN2_PIN 12 // FAN3 header on board - EXTRUDER0 FAN // // Misc. Functions // -#define SDSS 4 -#define PS_ON_PIN 40 +#define SDSS 4 +#define PS_ON_PIN 40 // // LCD / Controller // -#if HAS_SPI_LCD +#if HAS_WIRED_LCD - #define LCD_PINS_RS 42 - #define LCD_PINS_ENABLE 43 - #define LCD_PINS_D4 44 - #define LCD_PINS_D5 45 - #define LCD_PINS_D6 46 - #define LCD_PINS_D7 47 + #define LCD_PINS_RS 42 + #define LCD_PINS_ENABLE 43 + #define LCD_PINS_D4 44 + #define LCD_PINS_D5 45 + #define LCD_PINS_D6 46 + #define LCD_PINS_D7 47 #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) - #define BEEPER_PIN 41 + #define BEEPER_PIN 41 - #define BTN_EN1 50 - #define BTN_EN2 52 - #define BTN_ENC 48 + #define BTN_EN1 50 + #define BTN_EN2 52 + #define BTN_ENC 48 - #define SDSS 4 - #define SD_DETECT_PIN 14 + #define SDSS 4 + #define SD_DETECT_PIN 14 #elif ENABLED(RADDS_DISPLAY) - #define BEEPER_PIN 41 + #define BEEPER_PIN 41 - #define BTN_EN1 50 - #define BTN_EN2 52 - #define BTN_ENC 48 + #define BTN_EN1 50 + #define BTN_EN2 52 + #define BTN_ENC 48 - #define BTN_BACK 71 + #define BTN_BACK 71 #undef SDSS - #define SDSS 4 - #define SD_DETECT_PIN 14 + #define SDSS 4 + #define SD_DETECT_PIN 14 - #elif HAS_SSD1306_OLED_I2C + #elif HAS_U8GLIB_I2C_OLED - #define BTN_EN1 50 - #define BTN_EN2 52 - #define BTN_ENC 48 - #define BEEPER_PIN 41 - #define LCD_SDSS 4 - #define SD_DETECT_PIN 14 + #define BTN_EN1 50 + #define BTN_EN2 52 + #define BTN_ENC 48 + #define BEEPER_PIN 41 + #define LCD_SDSS 4 + #define SD_DETECT_PIN 14 #elif ENABLED(SPARK_FULL_GRAPHICS) - #define LCD_PINS_D4 29 - #define LCD_PINS_ENABLE 27 - #define LCD_PINS_RS 25 + #define LCD_PINS_D4 29 + #define LCD_PINS_ENABLE 27 + #define LCD_PINS_RS 25 - #define BTN_EN1 35 - #define BTN_EN2 33 - #define BTN_ENC 37 + #define BTN_EN1 35 + #define BTN_EN2 33 + #define BTN_ENC 37 - #define BEEPER_PIN -1 + #define BEEPER_PIN -1 #endif // SPARK_FULL_GRAPHICS -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD diff --git a/Marlin/src/pins/sam/pins_DUE3DOM_MINI.h b/Marlin/src/pins/sam/pins_DUE3DOM_MINI.h index 240204ced958..5f9ad48a08c4 100644 --- a/Marlin/src/pins/sam/pins_DUE3DOM_MINI.h +++ b/Marlin/src/pins/sam/pins_DUE3DOM_MINI.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * DUE3DOM MINI pin assignments */ -#ifndef __SAM3X8E__ +#if NOT_TARGET(__SAM3X8E__) #error "Oops! Select 'Arduino Due' in 'Tools > Board.'" #endif @@ -34,141 +34,141 @@ // // Servos // -#define SERVO0_PIN 5 -#define SERVO1_PIN 6 -#define SERVO2_PIN 8 // 4-pin header FAN0 -#define SERVO3_PIN -1 +#define SERVO0_PIN 5 +#define SERVO1_PIN 6 +#define SERVO2_PIN 8 // 4-pin header FAN0 +#define SERVO3_PIN -1 // // Limit Switches // -#define X_MIN_PIN 38 -#define X_MAX_PIN -1 -#define Y_MIN_PIN 34 -#define Y_MAX_PIN -1 -#define Z_MIN_PIN 30 -#define Z_MAX_PIN -1 +#define X_MIN_PIN 38 +#define X_MAX_PIN -1 +#define Y_MIN_PIN 34 +#define Y_MAX_PIN -1 +#define Z_MIN_PIN 30 +#define Z_MAX_PIN -1 // // Steppers // -#define X_STEP_PIN 17 -#define X_DIR_PIN 16 -#define X_ENABLE_PIN 22 +#define X_STEP_PIN 17 +#define X_DIR_PIN 16 +#define X_ENABLE_PIN 22 -#define Y_STEP_PIN 2 -#define Y_DIR_PIN 3 -#define Y_ENABLE_PIN 26 +#define Y_STEP_PIN 2 +#define Y_DIR_PIN 3 +#define Y_ENABLE_PIN 26 -#define Z_STEP_PIN 64 -#define Z_DIR_PIN 63 -#define Z_ENABLE_PIN 15 +#define Z_STEP_PIN 64 +#define Z_DIR_PIN 63 +#define Z_ENABLE_PIN 15 -#define E0_STEP_PIN 61 -#define E0_DIR_PIN 60 -#define E0_ENABLE_PIN 62 +#define E0_STEP_PIN 61 +#define E0_DIR_PIN 60 +#define E0_ENABLE_PIN 62 // // Temperature Sensors // -#define TEMP_0_PIN 0 // Analog Input (HOTEND0 thermistor) -#define TEMP_1_PIN 2 // Analog Input (unused) -#define TEMP_2_PIN 5 // Analog Input (OnBoard thermistor beta 3950) -#define TEMP_BED_PIN 1 // Analog Input (BED thermistor) +#define TEMP_0_PIN 0 // Analog Input (HOTEND0 thermistor) +#define TEMP_1_PIN 2 // Analog Input (unused) +#define TEMP_2_PIN 5 // Analog Input (OnBoard thermistor beta 3950) +#define TEMP_BED_PIN 1 // Analog Input (BED thermistor) // SPI for Max6675 or Max31855 Thermocouple #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 53 + #define MAX6675_SS_PIN 53 #else - #define MAX6675_SS_PIN 53 + #define MAX6675_SS_PIN 53 #endif // // Heaters / Fans // -#define HEATER_0_PIN 13 // HOTEND0 MOSFET -#define HEATER_BED_PIN 7 // BED MOSFET +#define HEATER_0_PIN 13 // HOTEND0 MOSFET +#define HEATER_BED_PIN 7 // BED MOSFET #ifndef FAN_PIN - #define FAN_PIN 11 // FAN1 header on board - PRINT FAN + #define FAN_PIN 11 // FAN1 header on board - PRINT FAN #endif -#define FAN1_PIN 12 // FAN2 header on board - CONTROLLER FAN -#define FAN2_PIN 9 // FAN3 header on board - EXTRUDER0 FAN -//#define FAN3_PIN 8 // FAN0 4-pin header on board +#define FAN1_PIN 12 // FAN2 header on board - CONTROLLER FAN +#define FAN2_PIN 9 // FAN3 header on board - EXTRUDER0 FAN +//#define FAN3_PIN 8 // FAN0 4-pin header on board // // Misc. Functions // -#define SDSS 4 -#define PS_ON_PIN 40 +#define SDSS 4 +#define PS_ON_PIN 40 // // LCD / Controller // -#if HAS_SPI_LCD +#if HAS_WIRED_LCD - #define LCD_PINS_RS 42 - #define LCD_PINS_ENABLE 43 - #define LCD_PINS_D4 44 - #define LCD_PINS_D5 45 - #define LCD_PINS_D6 46 - #define LCD_PINS_D7 47 + #define LCD_PINS_RS 42 + #define LCD_PINS_ENABLE 43 + #define LCD_PINS_D4 44 + #define LCD_PINS_D5 45 + #define LCD_PINS_D6 46 + #define LCD_PINS_D7 47 #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) - #define BEEPER_PIN 41 + #define BEEPER_PIN 41 - #define BTN_EN1 50 - #define BTN_EN2 52 - #define BTN_ENC 48 + #define BTN_EN1 50 + #define BTN_EN2 52 + #define BTN_ENC 48 - #define SDSS 4 - #define SD_DETECT_PIN 14 + #define SDSS 4 + #define SD_DETECT_PIN 14 #elif ENABLED(RADDS_DISPLAY) - #define BEEPER_PIN 41 + #define BEEPER_PIN 41 - #define BTN_EN1 50 - #define BTN_EN2 52 - #define BTN_ENC 48 + #define BTN_EN1 50 + #define BTN_EN2 52 + #define BTN_ENC 48 - #define BTN_BACK 71 + #define BTN_BACK 71 #undef SDSS - #define SDSS 4 - #define SD_DETECT_PIN 14 + #define SDSS 4 + #define SD_DETECT_PIN 14 - #elif HAS_SSD1306_OLED_I2C + #elif HAS_U8GLIB_I2C_OLED - #define BTN_EN1 50 - #define BTN_EN2 52 - #define BTN_ENC 48 - #define BEEPER_PIN 41 - #define LCD_SDSS 4 - #define SD_DETECT_PIN 14 + #define BTN_EN1 50 + #define BTN_EN2 52 + #define BTN_ENC 48 + #define BEEPER_PIN 41 + #define LCD_SDSS 4 + #define SD_DETECT_PIN 14 #elif ENABLED(SPARK_FULL_GRAPHICS) - #define LCD_PINS_D4 29 - #define LCD_PINS_ENABLE 27 - #define LCD_PINS_RS 25 + #define LCD_PINS_D4 29 + #define LCD_PINS_ENABLE 27 + #define LCD_PINS_RS 25 - #define BTN_EN1 35 - #define BTN_EN2 33 - #define BTN_ENC 37 + #define BTN_EN1 35 + #define BTN_EN2 33 + #define BTN_ENC 37 - #define BEEPER_PIN -1 + #define BEEPER_PIN -1 #elif ENABLED(MINIPANEL) - #define BTN_EN1 52 - #define BTN_EN2 50 - #define BTN_ENC 48 - #define LCD_SDSS 4 - #define SD_DETECT_PIN 14 - #define BEEPER_PIN 41 - #define DOGLCD_A0 46 - #define DOGLCD_CS 45 + #define BTN_EN1 52 + #define BTN_EN2 50 + #define BTN_ENC 48 + #define LCD_SDSS 4 + #define SD_DETECT_PIN 14 + #define BEEPER_PIN 41 + #define DOGLCD_A0 46 + #define DOGLCD_CS 45 #endif // SPARK_FULL_GRAPHICS -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD diff --git a/Marlin/src/pins/sam/pins_PRINTRBOARD_G2.h b/Marlin/src/pins/sam/pins_PRINTRBOARD_G2.h index c05c6169d6d3..22edb7021302 100644 --- a/Marlin/src/pins/sam/pins_PRINTRBOARD_G2.h +++ b/Marlin/src/pins/sam/pins_PRINTRBOARD_G2.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * PRINTRBOARD_G2 */ -#ifndef __SAM3X8E__ +#if NOT_TARGET(__SAM3X8E__) #error "Oops! Select 'Arduino Due' in 'Tools > Board.'" #endif @@ -36,38 +36,38 @@ // // Servos // -//#define SERVO0_PIN -1 -//#define SERVO1_PIN -1 +//#define SERVO0_PIN -1 +//#define SERVO1_PIN -1 // // Limit Switches // -#define X_MIN_PIN 22 // PB26 -#define Y_MAX_PIN 18 // PA11 -#define Z_MIN_PIN 19 // PA10 +#define X_MIN_PIN 22 // PB26 +#define Y_MAX_PIN 18 // PA11 +#define Z_MIN_PIN 19 // PA10 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 22 + #define Z_MIN_PROBE_PIN 22 #endif #ifndef FIL_RUNOUT_PIN - //#define FIL_RUNOUT_PIN 57 // PA22 + //#define FIL_RUNOUT_PIN 57 // PA22 #endif #ifndef FIL_RUNOUT2_PIN - //#define FIL_RUNOUT2_PIN 21 // PB13 + //#define FIL_RUNOUT2_PIN 21 // PB13 #endif // // LED defines // -//#define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) -//#define NEOPIXEL_PIN 20 // LED driving pin on motherboard -//#define NEOPIXEL_PIXELS 3 // Number of LEDs in the strip -//#define SDA0 20 // PB12 NeoPixel pin I2C data -//#define SCL0 21 // PB13 I2C clock +//#define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) +//#define NEOPIXEL_PIN 20 // LED driving pin on motherboard +//#define NEOPIXEL_PIXELS 3 // Number of LEDs in the strip +//#define SDA0 20 // PB12 NeoPixel pin I2C data +//#define SCL0 21 // PB13 I2C clock // D0_12 #REF! (INDICATOR_LED) // B28 JTAG-CLK @@ -79,82 +79,82 @@ //A15 UART_CTS //PB2 Unassigned //PB4 to PB9 Unassigned -//#define UART_RX_PIN 0 // PA8 "RX0" -//#define UART_TX_PIN 1 // PA9 "TX0" -//#define UART_RTS_PIN 23 // PA14 -//#define UART_CTS_PIN 24 // PA15 +//#define UART_RX_PIN 0 // PA8 "RX0" +//#define UART_TX_PIN 1 // PA9 "TX0" +//#define UART_RTS_PIN 23 // PA14 +//#define UART_CTS_PIN 24 // PA15 // // Steppers // -#define Z_STEP_PIN 73 // PA21 MOTOR 1 -#define Z_DIR_PIN 75 // PA26 -#define Z_ENABLE_PIN 74 // PA25 +#define Z_STEP_PIN 73 // PA21 MOTOR 1 +#define Z_DIR_PIN 75 // PA26 +#define Z_ENABLE_PIN 74 // PA25 -#define X_STEP_PIN 66 // PB15 MOTOR 2 -#define X_DIR_PIN 54 // PA16 -#define X_ENABLE_PIN 67 // PB16 +#define X_STEP_PIN 66 // PB15 MOTOR 2 +#define X_DIR_PIN 54 // PA16 +#define X_ENABLE_PIN 67 // PB16 -#define Y_STEP_PIN 34 // PA29 MOTOR 3 -#define Y_DIR_PIN 35 // PB1 -#define Y_ENABLE_PIN 36 // PB0 +#define Y_STEP_PIN 34 // PA29 MOTOR 3 +#define Y_DIR_PIN 35 // PB1 +#define Y_ENABLE_PIN 36 // PB0 -#define E0_STEP_PIN 53 // PB14 MOTOR 4 -#define E0_DIR_PIN 78 // PB23 -#define E0_ENABLE_PIN 37 // PB22 +#define E0_STEP_PIN 53 // PB14 MOTOR 4 +#define E0_DIR_PIN 78 // PB23 +#define E0_ENABLE_PIN 37 // PB22 // Microstepping mode pins -#define Z_MS1_PIN 52 // PB21 MODE0 MOTOR 1 -#define Z_MS2_PIN 52 // PB21 MODE1 -#define Z_MS3_PIN 65 // PB20 MODE2 +#define Z_MS1_PIN 52 // PB21 MODE0 MOTOR 1 +#define Z_MS2_PIN 52 // PB21 MODE1 +#define Z_MS3_PIN 65 // PB20 MODE2 -#define X_MS1_PIN 43 // PA20 MODE0 MOTOR 2 -#define X_MS2_PIN 43 // PA20 MODE1 -#define X_MS3_PIN 42 // PA19 MODE2 +#define X_MS1_PIN 43 // PA20 MODE0 MOTOR 2 +#define X_MS2_PIN 43 // PA20 MODE1 +#define X_MS3_PIN 42 // PA19 MODE2 -#define Y_MS1_PIN 77 // PA28 MODE0 MOTOR 3 -#define Y_MS2_PIN 77 // PA28 MODE1 -#define Y_MS3_PIN 76 // PA27 MODE2 +#define Y_MS1_PIN 77 // PA28 MODE0 MOTOR 3 +#define Y_MS2_PIN 77 // PA28 MODE1 +#define Y_MS3_PIN 76 // PA27 MODE2 -#define E0_MS1_PIN 38 // PB11 MODE0 MOTOR 4 -#define E0_MS2_PIN 38 // PB11 MODE1 -#define E0_MS3_PIN 39 // PB10 MODE2 +#define E0_MS1_PIN 38 // PB11 MODE0 MOTOR 4 +#define E0_MS2_PIN 38 // PB11 MODE1 +#define E0_MS3_PIN 39 // PB10 MODE2 // Motor current PWM pins -#define MOTOR_CURRENT_PWM_X_PIN 62 // PB17 MOTOR 1 -#define MOTOR_CURRENT_PWM_Z_PIN 63 // PB18 MOTOR 2 -#define MOTOR_CURRENT_PWM_Y_PIN 64 // PB19 MOTOR 3 -#define MOTOR_CURRENT_PWM_E_PIN 61 // PA2 MOTOR 4 +#define MOTOR_CURRENT_PWM_X_PIN 62 // PB17 MOTOR 1 +#define MOTOR_CURRENT_PWM_Z_PIN 63 // PB18 MOTOR 2 +#define MOTOR_CURRENT_PWM_Y_PIN 64 // PB19 MOTOR 3 +#define MOTOR_CURRENT_PWM_E_PIN 61 // PA2 MOTOR 4 #define DEFAULT_PWM_MOTOR_CURRENT { 300, 400, 1000} // XY Z E0, 1000 = 1000mAh // // Temperature Sensors // -#define TEMP_0_PIN 2 // digital 56 PA23 -#define TEMP_BED_PIN 5 // digital 59 PA4 +#define TEMP_0_PIN 2 // digital 56 PA23 +#define TEMP_BED_PIN 5 // digital 59 PA4 // // Heaters / Fans // -#define HEATER_0_PIN 40 // PA5 -#define HEATER_BED_PIN 41 // PB24 +#define HEATER_0_PIN 40 // PA5 +#define HEATER_BED_PIN 41 // PB24 #ifndef FAN_PIN - #define FAN_PIN 13 // PB27 Fan1A + #define FAN_PIN 13 // PB27 Fan1A #endif -#define FAN1_PIN 58 // PA6 Fan1B +#define FAN1_PIN 58 // PA6 Fan1B -#define FET_SAFETY_PIN 31 // PA7 must be pulsed low every 50 mS or FETs are turned off -#define FET_SAFETY_DELAY 50 // 50 mS delay between pulses -#define FET_SAFETY_INVERTED true // true - negative going pulse of 2 uS +#define FET_SAFETY_PIN 31 // PA7 must be pulsed low every 50 mS or FETs are turned off +#define FET_SAFETY_DELAY 50 // 50 mS delay between pulses +#define FET_SAFETY_INVERTED true // true - negative going pulse of 2 uS ///////////////////////////////////////////////////////// -#define MISO_PIN 68 // set to unused pins for now -#define MOSI_PIN 69 // set to unused pins for now -#define SCK_PIN 70 // set to unused pins for now -#define SDSS 71 // set to unused pins for now +#define MISO_PIN 68 // set to unused pins for now +#define MOSI_PIN 69 // set to unused pins for now +#define SCK_PIN 70 // set to unused pins for now +#define SDSS 71 // set to unused pins for now /** * G2 uses 8 pins that are not available in the DUE environment: @@ -170,5 +170,4 @@ * None of these are in the arduino_due_x variant so digitalWrite and digitalRead can't be used on them. * * They can be accessed via FASTIO functions WRITE, READ, OUT_WRITE, OUTPUT, ... - * */ diff --git a/Marlin/src/pins/sam/pins_RADDS.h b/Marlin/src/pins/sam/pins_RADDS.h index 41daba4e8e03..60fe3512378e 100644 --- a/Marlin/src/pins/sam/pins_RADDS.h +++ b/Marlin/src/pins/sam/pins_RADDS.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,265 +25,270 @@ * RADDS */ -#ifndef __SAM3X8E__ +#if NOT_TARGET(__SAM3X8E__) #error "Oops! Select 'Arduino Due' in 'Tools > Board.'" #endif #define BOARD_INFO_NAME "RADDS" +// +// EEPROM +// +#if EITHER(NO_EEPROM_SELECTED, I2C_EEPROM) + #define I2C_EEPROM + #define MARLIN_EEPROM_SIZE 0x2000 // 8KB +#endif + // // Servos // #if !HAS_CUTTER - #define SERVO0_PIN 5 + #define SERVO0_PIN 5 #endif -#define SERVO1_PIN 6 -#define SERVO2_PIN 39 -#define SERVO3_PIN 40 +#define SERVO1_PIN 6 +#define SERVO2_PIN 39 +#define SERVO3_PIN 40 // // Limit Switches // -#define X_MIN_PIN 28 -#define X_MAX_PIN 34 -#define Y_MIN_PIN 30 -#define Y_MAX_PIN 36 -#define Z_MIN_PIN 32 -#define Z_MAX_PIN 38 +#define X_MIN_PIN 28 +#define X_MAX_PIN 34 +#define Y_MIN_PIN 30 +#define Y_MAX_PIN 36 +#define Z_MIN_PIN 32 +#define Z_MAX_PIN 38 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 38 + #define Z_MIN_PROBE_PIN 38 #endif // // Steppers // -#define X_STEP_PIN 24 -#define X_DIR_PIN 23 -#define X_ENABLE_PIN 26 +#define X_STEP_PIN 24 +#define X_DIR_PIN 23 +#define X_ENABLE_PIN 26 #ifndef X_CS_PIN - #define X_CS_PIN 25 + #define X_CS_PIN 25 #endif -#define Y_STEP_PIN 17 -#define Y_DIR_PIN 16 -#define Y_ENABLE_PIN 22 +#define Y_STEP_PIN 17 +#define Y_DIR_PIN 16 +#define Y_ENABLE_PIN 22 #ifndef Y_CS_PIN - #define Y_CS_PIN 27 + #define Y_CS_PIN 27 #endif -#define Z_STEP_PIN 2 -#define Z_DIR_PIN 3 -#define Z_ENABLE_PIN 15 +#define Z_STEP_PIN 2 +#define Z_DIR_PIN 3 +#define Z_ENABLE_PIN 15 #ifndef Z_CS_PIN - #define Z_CS_PIN 29 + #define Z_CS_PIN 29 #endif -#define E0_STEP_PIN 61 -#define E0_DIR_PIN 60 -#define E0_ENABLE_PIN 62 +#define E0_STEP_PIN 61 +#define E0_DIR_PIN 60 +#define E0_ENABLE_PIN 62 #ifndef E0_CS_PIN - #define E0_CS_PIN 31 + #define E0_CS_PIN 31 #endif -#define E1_STEP_PIN 64 -#define E1_DIR_PIN 63 -#define E1_ENABLE_PIN 65 +#define E1_STEP_PIN 64 +#define E1_DIR_PIN 63 +#define E1_ENABLE_PIN 65 #ifndef E1_CS_PIN - #define E1_CS_PIN 33 + #define E1_CS_PIN 33 #endif -#define E2_STEP_PIN 51 -#define E2_DIR_PIN 53 -#define E2_ENABLE_PIN 49 +#define E2_STEP_PIN 51 +#define E2_DIR_PIN 53 +#define E2_ENABLE_PIN 49 #ifndef E2_CS_PIN - #define E2_CS_PIN 35 + #define E2_CS_PIN 35 #endif /** * RADDS Extension Board V2 / V3 * http://doku.radds.org/dokumentation/extension-board */ -//#define RADDS_EXTENSION 2 +//#define RADDS_EXTENSION 2 #if RADDS_EXTENSION >= 2 - #define E3_DIR_PIN 33 - #define E3_STEP_PIN 35 - #define E3_ENABLE_PIN 37 + #define E3_DIR_PIN 33 + #define E3_STEP_PIN 35 + #define E3_ENABLE_PIN 37 #ifndef E3_CS_PIN - #define E3_CS_PIN 6 + #define E3_CS_PIN 6 #endif #if RADDS_EXTENSION == 3 - #define E4_DIR_PIN 27 - #define E4_STEP_PIN 29 - #define E4_ENABLE_PIN 31 + #define E4_DIR_PIN 27 + #define E4_STEP_PIN 29 + #define E4_ENABLE_PIN 31 #ifndef E4_CS_PIN - #define E4_CS_PIN 39 + #define E4_CS_PIN 39 #endif - #define E5_DIR_PIN 66 - #define E5_STEP_PIN 67 - #define E5_ENABLE_PIN 68 + #define E5_DIR_PIN 66 + #define E5_STEP_PIN 67 + #define E5_ENABLE_PIN 68 #ifndef E5_CS_PIN - #define E5_CS_PIN 6 + #define E5_CS_PIN 6 #endif - #define RADDS_EXT_MSI_PIN 69 + #define RADDS_EXT_MSI_PIN 69 #define BOARD_INIT() OUT_WRITE(RADDS_EXT_VDD_PIN, HIGH) #else - #define E4_DIR_PIN 27 - #define E4_STEP_PIN 29 - #define E4_ENABLE_PIN 31 + #define E4_DIR_PIN 27 + #define E4_STEP_PIN 29 + #define E4_ENABLE_PIN 31 #ifndef E4_CS_PIN - #define E4_CS_PIN 39 + #define E4_CS_PIN 39 #endif // E3 and E4 share the same MSx pins - #define E3_MS1_PIN 67 - #define E4_MS1_PIN 67 - #define E3_MS2_PIN 68 - #define E4_MS2_PIN 68 - #define E3_MS3_PIN 69 - #define E4_MS3_PIN 69 + #define E3_MS1_PIN 67 + #define E4_MS1_PIN 67 + #define E3_MS2_PIN 68 + #define E4_MS2_PIN 68 + #define E3_MS3_PIN 69 + #define E4_MS3_PIN 69 - #define RADDS_EXT_VDD2_PIN 66 + #define RADDS_EXT_VDD2_PIN 66 #define BOARD_INIT() do{ OUT_WRITE(RADDS_EXT_VDD_PIN, HIGH); OUT_WRITE(RADDS_EXT_VDD2_PIN, HIGH); }while(0) #endif - #define RADDS_EXT_VDD_PIN 25 + #define RADDS_EXT_VDD_PIN 25 #endif // // Temperature Sensors // -#define TEMP_0_PIN 0 // Analog Input -#define TEMP_1_PIN 1 // Analog Input -#define TEMP_2_PIN 2 // Analog Input -#define TEMP_3_PIN 3 // Analog Input -#define TEMP_4_PIN 5 // dummy so will compile when PINS_DEBUGGING is enabled -#define TEMP_BED_PIN 4 // Analog Input +#define TEMP_0_PIN 0 // Analog Input +#define TEMP_1_PIN 1 // Analog Input +#define TEMP_2_PIN 2 // Analog Input +#define TEMP_3_PIN 3 // Analog Input +#define TEMP_4_PIN 5 // dummy so will compile when PINS_DEBUGGING is enabled +#define TEMP_BED_PIN 4 // Analog Input // SPI for Max6675 or Max31855 Thermocouple #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 53 + #define MAX6675_SS_PIN 53 #else - #define MAX6675_SS_PIN 49 + #define MAX6675_SS_PIN 49 #endif // // Heaters / Fans // -#define HEATER_0_PIN 13 -#define HEATER_1_PIN 12 -#define HEATER_2_PIN 11 +#define HEATER_0_PIN 13 +#define HEATER_1_PIN 12 +#define HEATER_2_PIN 11 #if !HAS_CUTTER - #define HEATER_BED_PIN 7 // BED + #define HEATER_BED_PIN 7 // BED #endif #ifndef FAN_PIN - #define FAN_PIN 9 + #define FAN_PIN 9 #endif -#define FAN1_PIN 8 +#define FAN1_PIN 8 // // Misc. Functions // -#define SD_DETECT_PIN 14 -#define PS_ON_PIN 40 // SERVO3_PIN +#define SD_DETECT_PIN 14 +#define PS_ON_PIN 40 // SERVO3_PIN #ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN 39 // SERVO2_PIN + #define FIL_RUNOUT_PIN 39 // SERVO2_PIN #endif -#define I2C_EEPROM -#define E2END 0x1FFF // 8KB - // // M3/M4/M5 - Spindle/Laser Control // #if HAS_CUTTER #if !NUM_SERVOS - #define SPINDLE_LASER_PWM_PIN 5 // SERVO0_PIN + #define SPINDLE_LASER_PWM_PIN 5 // SERVO0_PIN #endif - #define SPINDLE_LASER_ENA_PIN 7 // HEATER_BED_PIN - Pullup/down! + #define SPINDLE_LASER_ENA_PIN 7 // HEATER_BED_PIN - Pullup/down! #endif // // LCD / Controller // -#if HAS_SPI_LCD +#if HAS_WIRED_LCD #if ENABLED(RADDS_DISPLAY) - #define LCD_PINS_RS 42 - #define LCD_PINS_ENABLE 43 - #define LCD_PINS_D4 44 - #define LCD_PINS_D5 45 - #define LCD_PINS_D6 46 - #define LCD_PINS_D7 47 + #define LCD_PINS_RS 42 + #define LCD_PINS_ENABLE 43 + #define LCD_PINS_D4 44 + #define LCD_PINS_D5 45 + #define LCD_PINS_D6 46 + #define LCD_PINS_D7 47 - #define BEEPER_PIN 41 + #define BEEPER_PIN 41 - #define BTN_EN1 50 - #define BTN_EN2 52 - #define BTN_ENC 48 + #define BTN_EN1 50 + #define BTN_EN2 52 + #define BTN_ENC 48 - #define BTN_BACK 71 + #define BTN_BACK 71 - #define SDSS 10 - #define SD_DETECT_PIN 14 + #define SDSS 10 + #define SD_DETECT_PIN 14 #elif ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) // The REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER requires // an adapter such as https://www.thingiverse.com/thing:1740725 - #define LCD_PINS_RS 42 - #define LCD_PINS_ENABLE 43 - #define LCD_PINS_D4 44 + #define LCD_PINS_RS 42 + #define LCD_PINS_ENABLE 43 + #define LCD_PINS_D4 44 - #define BEEPER_PIN 41 + #define BEEPER_PIN 41 - #define BTN_EN1 50 - #define BTN_EN2 52 - #define BTN_ENC 48 + #define BTN_EN1 50 + #define BTN_EN2 52 + #define BTN_ENC 48 - #define SDSS 10 - #define SD_DETECT_PIN 14 + #define SDSS 10 + #define SD_DETECT_PIN 14 - #elif HAS_SSD1306_OLED_I2C + #elif HAS_U8GLIB_I2C_OLED - #define BTN_EN1 50 - #define BTN_EN2 52 - #define BTN_ENC 48 - #define BEEPER_PIN 41 - #define LCD_SDSS 10 - #define SD_DETECT_PIN 14 + #define BTN_EN1 50 + #define BTN_EN2 52 + #define BTN_ENC 48 + #define BEEPER_PIN 41 + #define LCD_SDSS 10 + #define SD_DETECT_PIN 14 #elif ENABLED(SPARK_FULL_GRAPHICS) - #define LCD_PINS_D4 29 - #define LCD_PINS_ENABLE 27 - #define LCD_PINS_RS 25 + #define LCD_PINS_D4 29 + #define LCD_PINS_ENABLE 27 + #define LCD_PINS_RS 25 - #define BTN_EN1 35 - #define BTN_EN2 33 - #define BTN_ENC 37 + #define BTN_EN1 35 + #define BTN_EN2 33 + #define BTN_ENC 37 #endif // SPARK_FULL_GRAPHICS -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD #ifndef SDSS - #define SDSS 4 + #define SDSS 4 #endif diff --git a/Marlin/src/pins/sam/pins_RAMPS4DUE.h b/Marlin/src/pins/sam/pins_RAMPS4DUE.h index 21a2055967e7..54548333b5fd 100644 --- a/Marlin/src/pins/sam/pins_RAMPS4DUE.h +++ b/Marlin/src/pins/sam/pins_RAMPS4DUE.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -39,11 +39,12 @@ * A15 | NC */ -#if !defined(__SAM3X8E__) && !defined(__AVR_ATmega2560__) +#if NOT_TARGET(__SAM3X8E__, __AVR_ATmega2560__) #error "Oops! Select 'Arduino Due' or 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif #define BOARD_INFO_NAME "RAMPS4DUE" + #define IS_RAMPS4DUE // diff --git a/Marlin/src/pins/sam/pins_RAMPS_DUO.h b/Marlin/src/pins/sam/pins_RAMPS_DUO.h index d25ef9e059ff..bfc3968ffac2 100644 --- a/Marlin/src/pins/sam/pins_RAMPS_DUO.h +++ b/Marlin/src/pins/sam/pins_RAMPS_DUO.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -43,49 +43,50 @@ * A15 | A11 */ -#if !defined(__SAM3X8E__) && !defined(__AVR_ATmega2560__) +#if NOT_TARGET(__SAM3X8E__, __AVR_ATmega2560__) #error "Oops! Select 'Arduino Due' or 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" #endif #define BOARD_INFO_NAME "RAMPS Duo" #define IS_RAMPS_DUO + #include "../ramps/pins_RAMPS.h" // // Temperature Sensors // #undef TEMP_0_PIN -#define TEMP_0_PIN 9 // Analog Input +#define TEMP_0_PIN 9 // Analog Input #undef TEMP_1_PIN -#define TEMP_1_PIN 11 // Analog Input +#define TEMP_1_PIN 11 // Analog Input #undef TEMP_BED_PIN -#define TEMP_BED_PIN 10 // Analog Input +#define TEMP_BED_PIN 10 // Analog Input // SPI for Max6675 or Max31855 Thermocouple #undef MAX6675_SS_PIN #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 69 // Don't use 53 if using Display/SD card + #define MAX6675_SS_PIN 69 // Don't use 53 if using Display/SD card #else - #define MAX6675_SS_PIN 69 // Don't use 49 (SD_DETECT_PIN) + #define MAX6675_SS_PIN 69 // Don't use 49 (SD_DETECT_PIN) #endif // // LCD / Controller // -#if HAS_SPI_LCD +#if HAS_WIRED_LCD #if BOTH(NEWPANEL, PANEL_ONE) #undef LCD_PINS_D4 - #define LCD_PINS_D4 68 + #define LCD_PINS_D4 68 #undef LCD_PINS_D5 - #define LCD_PINS_D5 69 + #define LCD_PINS_D5 69 #undef LCD_PINS_D7 - #define LCD_PINS_D7 67 + #define LCD_PINS_D7 67 #endif #if ENABLED(NEWPANEL) @@ -93,39 +94,39 @@ #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) #undef BTN_EN1 - #define BTN_EN1 67 + #define BTN_EN1 67 #undef BTN_ENC - #define BTN_ENC 66 + #define BTN_ENC 66 #elif ENABLED(MINIPANEL) #undef DOGLCD_CS - #define DOGLCD_CS 69 + #define DOGLCD_CS 69 #undef LCD_BACKLIGHT_PIN - #define LCD_BACKLIGHT_PIN 68 // backlight LED on A14/D68 + #define LCD_BACKLIGHT_PIN 68 // backlight LED on A14/D68 #undef KILL_PIN - #define KILL_PIN 67 + #define KILL_PIN 67 #undef BTN_EN2 - #define BTN_EN2 66 + #define BTN_EN2 66 #else #if ENABLED(REPRAPWORLD_KEYPAD) #undef BTN_EN1 - #define BTN_EN1 67 // encoder + #define BTN_EN1 67 // encoder #undef BTN_ENC - #define BTN_ENC 66 // enter button + #define BTN_ENC 66 // enter button #elif ENABLED(PANEL_ONE) #undef BTN_EN2 - #define BTN_EN2 66 // AUX2 PIN 4 + #define BTN_EN2 66 // AUX2 PIN 4 #endif #endif #endif // NEWPANEL -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD diff --git a/Marlin/src/pins/sam/pins_RAMPS_FD_V1.h b/Marlin/src/pins/sam/pins_RAMPS_FD_V1.h index 2e0350447547..ee525eefaa56 100644 --- a/Marlin/src/pins/sam/pins_RAMPS_FD_V1.h +++ b/Marlin/src/pins/sam/pins_RAMPS_FD_V1.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -28,7 +28,7 @@ * Use 4k7 thermistor tables */ -#ifndef __SAM3X8E__ +#if NOT_TARGET(__SAM3X8E__) #error "Oops! Select 'Arduino Due' in 'Tools > Board.'" #endif @@ -43,169 +43,169 @@ // // Servos // -#define SERVO0_PIN 7 -#define SERVO1_PIN 6 -#define SERVO2_PIN 5 -#define SERVO3_PIN 3 +#define SERVO0_PIN 7 +#define SERVO1_PIN 6 +#define SERVO2_PIN 5 +#define SERVO3_PIN 3 // // Limit Switches // -#define X_MIN_PIN 22 -#define X_MAX_PIN 30 -#define Y_MIN_PIN 24 -#define Y_MAX_PIN 38 -#define Z_MIN_PIN 26 -#define Z_MAX_PIN 34 +#define X_MIN_PIN 22 +#define X_MAX_PIN 30 +#define Y_MIN_PIN 24 +#define Y_MAX_PIN 38 +#define Z_MIN_PIN 26 +#define Z_MAX_PIN 34 // // Steppers // -#define X_STEP_PIN 63 -#define X_DIR_PIN 62 -#define X_ENABLE_PIN 48 +#define X_STEP_PIN 63 +#define X_DIR_PIN 62 +#define X_ENABLE_PIN 48 #ifndef X_CS_PIN - #define X_CS_PIN 68 + #define X_CS_PIN 68 #endif -#define Y_STEP_PIN 65 -#define Y_DIR_PIN 64 -#define Y_ENABLE_PIN 46 +#define Y_STEP_PIN 65 +#define Y_DIR_PIN 64 +#define Y_ENABLE_PIN 46 #ifndef Y_CS_PIN - #define Y_CS_PIN 60 + #define Y_CS_PIN 60 #endif -#define Z_STEP_PIN 67 -#define Z_DIR_PIN 66 -#define Z_ENABLE_PIN 44 +#define Z_STEP_PIN 67 +#define Z_DIR_PIN 66 +#define Z_ENABLE_PIN 44 #ifndef Z_CS_PIN - #define Z_CS_PIN 58 + #define Z_CS_PIN 58 #endif -#define E0_STEP_PIN 36 -#define E0_DIR_PIN 28 -#define E0_ENABLE_PIN 42 +#define E0_STEP_PIN 36 +#define E0_DIR_PIN 28 +#define E0_ENABLE_PIN 42 #ifndef E0_CS_PIN - #define E0_CS_PIN 67 + #define E0_CS_PIN 67 #endif -#define E1_STEP_PIN 43 -#define E1_DIR_PIN 41 -#define E1_ENABLE_PIN 39 +#define E1_STEP_PIN 43 +#define E1_DIR_PIN 41 +#define E1_ENABLE_PIN 39 #ifndef E1_CS_PIN - #define E1_CS_PIN 61 + #define E1_CS_PIN 61 #endif -#define E2_STEP_PIN 32 -#define E2_DIR_PIN 47 -#define E2_ENABLE_PIN 45 +#define E2_STEP_PIN 32 +#define E2_DIR_PIN 47 +#define E2_ENABLE_PIN 45 #ifndef E2_CS_PIN - #define E2_CS_PIN 59 + #define E2_CS_PIN 59 #endif // // Temperature Sensors // -#define TEMP_0_PIN 1 // Analog Input -#define TEMP_1_PIN 2 // Analog Input -#define TEMP_2_PIN 3 // Analog Input -#define TEMP_BED_PIN 0 // Analog Input +#define TEMP_0_PIN 1 // Analog Input +#define TEMP_1_PIN 2 // Analog Input +#define TEMP_2_PIN 3 // Analog Input +#define TEMP_BED_PIN 0 // Analog Input // SPI for Max6675 or Max31855 Thermocouple #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 53 + #define MAX6675_SS_PIN 53 #else - #define MAX6675_SS_PIN 49 + #define MAX6675_SS_PIN 49 #endif // // Heaters / Fans // -#define HEATER_0_PIN 9 -#define HEATER_1_PIN 10 -#define HEATER_2_PIN 11 -#define HEATER_BED_PIN 8 +#define HEATER_0_PIN 9 +#define HEATER_1_PIN 10 +#define HEATER_2_PIN 11 +#define HEATER_BED_PIN 8 #ifndef FAN_PIN - #define FAN_PIN 12 + #define FAN_PIN 12 #endif // // Misc. Functions // -#define SDSS 4 -#define LED_PIN 13 +#define SDSS 4 +#define LED_PIN 13 // // LCD / Controller // -#if HAS_SPI_LCD +#if HAS_WIRED_LCD // ramps-fd lcd adaptor - #define BEEPER_PIN 37 - #define BTN_EN1 33 - #define BTN_EN2 31 - #define BTN_ENC 35 - #define SD_DETECT_PIN 49 + #define BEEPER_PIN 37 + #define BTN_EN1 33 + #define BTN_EN2 31 + #define BTN_ENC 35 + #define SD_DETECT_PIN 49 #if ENABLED(NEWPANEL) - #define LCD_PINS_RS 16 - #define LCD_PINS_ENABLE 17 + #define LCD_PINS_RS 16 + #define LCD_PINS_ENABLE 17 #endif #if ENABLED(FYSETC_MINI_12864) - #define DOGLCD_CS LCD_PINS_ENABLE - #define DOGLCD_A0 LCD_PINS_RS - #define DOGLCD_SCK 76 - #define DOGLCD_MOSI 75 + #define DOGLCD_CS LCD_PINS_ENABLE + #define DOGLCD_A0 LCD_PINS_RS + #define DOGLCD_SCK 76 + #define DOGLCD_MOSI 75 - //#define FORCE_SOFT_SPI // Use this if default of hardware SPI causes display problems - // results in LCD soft SPI mode 3, SD soft SPI mode 0 + //#define FORCE_SOFT_SPI // Use this if default of hardware SPI causes display problems + // results in LCD soft SPI mode 3, SD soft SPI mode 0 - #define LCD_RESET_PIN 23 // Must be high or open for LCD to operate normally. + #define LCD_RESET_PIN 23 // Must be high or open for LCD to operate normally. #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) #ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN 25 + #define RGB_LED_R_PIN 25 #endif #ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN 27 + #define RGB_LED_G_PIN 27 #endif #ifndef RGB_LED_B_PIN - #define RGB_LED_B_PIN 29 + #define RGB_LED_B_PIN 29 #endif #elif ENABLED(FYSETC_MINI_12864_2_1) - #define NEOPIXEL_PIN 25 + #define NEOPIXEL_PIN 25 #endif #elif ENABLED(NEWPANEL) - #define LCD_PINS_D4 23 - #define LCD_PINS_D5 25 - #define LCD_PINS_D6 27 - #define LCD_PINS_D7 29 + #define LCD_PINS_D4 23 + #define LCD_PINS_D5 25 + #define LCD_PINS_D6 27 + #define LCD_PINS_D7 29 #if ENABLED(MINIPANEL) - #define DOGLCD_CS 25 - #define DOGLCD_A0 27 + #define DOGLCD_CS 25 + #define DOGLCD_A0 27 #endif #endif #if ANY(VIKI2, miniVIKI) - #define DOGLCD_A0 16 - #define KILL_PIN 51 - #define STAT_LED_BLUE_PIN 29 - #define STAT_LED_RED_PIN 23 - #define DOGLCD_CS 17 - #define DOGLCD_SCK 76 // SCK_PIN - Required for DUE Hardware SPI - #define DOGLCD_MOSI 75 // MOSI_PIN - #define DOGLCD_MISO 74 // MISO_PIN + #define DOGLCD_A0 16 + #define KILL_PIN 51 + #define STAT_LED_BLUE_PIN 29 + #define STAT_LED_RED_PIN 23 + #define DOGLCD_CS 17 + #define DOGLCD_SCK 76 // SCK_PIN - Required for DUE Hardware SPI + #define DOGLCD_MOSI 75 // MOSI_PIN + #define DOGLCD_MISO 74 // MISO_PIN #endif -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD -#if HAS_TMC220x +#if HAS_TMC_UART /** * TMC2208/TMC2209 stepper drivers * @@ -229,7 +229,7 @@ // M3/M4/M5 - Spindle/Laser Control // #if HOTENDS < 3 && HAS_CUTTER && !PIN_EXISTS(SPINDLE_LASER_ENA) - #define SPINDLE_LASER_ENA_PIN 45 // Use E2 ENA - #define SPINDLE_LASER_PWM_PIN 12 // Hardware PWM - #define SPINDLE_DIR_PIN 47 // Use E2 DIR + #define SPINDLE_LASER_ENA_PIN 45 // Use E2 ENA + #define SPINDLE_LASER_PWM_PIN 12 // Hardware PWM + #define SPINDLE_DIR_PIN 47 // Use E2 DIR #endif diff --git a/Marlin/src/pins/sam/pins_RAMPS_FD_V2.h b/Marlin/src/pins/sam/pins_RAMPS_FD_V2.h index 6e7d05506930..55a42b2a4709 100644 --- a/Marlin/src/pins/sam/pins_RAMPS_FD_V2.h +++ b/Marlin/src/pins/sam/pins_RAMPS_FD_V2.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -41,7 +41,7 @@ #undef INVERTED_FAN_PINS #define I2C_EEPROM -#define E2END 0xFFFF // 64K in a 24C512 +#define MARLIN_EEPROM_SIZE 0x10000 // 64K in a 24C512 #ifndef PS_ON_PIN #define PS_ON_PIN 12 diff --git a/Marlin/src/pins/sam/pins_RAMPS_SMART.h b/Marlin/src/pins/sam/pins_RAMPS_SMART.h index 455d40a99969..9b76ee290b96 100644 --- a/Marlin/src/pins/sam/pins_RAMPS_SMART.h +++ b/Marlin/src/pins/sam/pins_RAMPS_SMART.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -60,39 +60,38 @@ * (Search the web for "Arduino DUE Board Pinout" to see the correct header.) */ -#ifndef __SAM3X8E__ +#if NOT_TARGET(__SAM3X8E__) #error "Oops! Select 'Arduino Due' in 'Tools > Board.'" #endif #define BOARD_INFO_NAME "RAMPS-SMART" - #define IS_RAMPS_SMART #include "../ramps/pins_RAMPS.h" // I2C EEPROM with 4K of space #define I2C_EEPROM -#define E2END 0xFFF +#define MARLIN_EEPROM_SIZE 0x1000 -#define RESET_PIN 42 // Resets the board if the jumper is attached +#define RESET_PIN 42 // Resets the board if the jumper is attached // // Temperature Sensors // #undef TEMP_0_PIN -#define TEMP_0_PIN 9 // Analog Input +#define TEMP_0_PIN 9 // Analog Input #undef TEMP_1_PIN -#define TEMP_1_PIN 10 // Analog Input +#define TEMP_1_PIN 10 // Analog Input #undef TEMP_BED_PIN -#define TEMP_BED_PIN 11 // Analog Input +#define TEMP_BED_PIN 11 // Analog Input // SPI for Max6675 or Max31855 Thermocouple #undef MAX6675_SS_PIN #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 67 // Don't use 53 if using Display/SD card + #define MAX6675_SS_PIN 67 // Don't use 53 if using Display/SD card #else - #define MAX6675_SS_PIN 67 // Don't use 49 (SD_DETECT_PIN) + #define MAX6675_SS_PIN 67 // Don't use 49 (SD_DETECT_PIN) #endif // @@ -100,12 +99,12 @@ // // Support for AZSMZ 12864 LCD with SD Card 3D printer smart controller control panel #if ENABLED(AZSMZ_12864) - #define BEEPER_PIN 66 // Smart RAMPS 1.42 pinout diagram on RepRap WIKI erroneously says this should be pin 65 - #define DOGLCD_A0 59 - #define DOGLCD_CS 44 - #define BTN_EN1 58 - #define BTN_EN2 40 - #define BTN_ENC 67 // Smart RAMPS 1.42 pinout diagram on RepRap WIKI erroneously says this should be pin 66 - #define SD_DETECT_PIN 49 // Pin 49 for display sd interface, 72 for easy adapter board - #define KILL_PIN 42 + #define BEEPER_PIN 66 // Smart RAMPS 1.42 pinout diagram on RepRap WIKI erroneously says this should be pin 65 + #define DOGLCD_A0 59 + #define DOGLCD_CS 44 + #define BTN_EN1 58 + #define BTN_EN2 40 + #define BTN_ENC 67 // Smart RAMPS 1.42 pinout diagram on RepRap WIKI erroneously says this should be pin 66 + #define SD_DETECT_PIN 49 // Pin 49 for display sd interface, 72 for easy adapter board + #define KILL_PIN 42 #endif diff --git a/Marlin/src/pins/sam/pins_RURAMPS4D_11.h b/Marlin/src/pins/sam/pins_RURAMPS4D_11.h index 6963a164bbfe..b9e61fb27c53 100644 --- a/Marlin/src/pins/sam/pins_RURAMPS4D_11.h +++ b/Marlin/src/pins/sam/pins_RURAMPS4D_11.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * * Ported sys0724 & Vynt */ @@ -32,7 +32,7 @@ * | */ -#ifndef __SAM3X8E__ +#if NOT_TARGET(__SAM3X8E__) #error "Oops! Select 'Arduino Due' in 'Tools > Board.'" #endif @@ -41,76 +41,76 @@ // // Servos // -#define SERVO0_PIN 5 -#define SERVO1_PIN 3 +#define SERVO0_PIN 5 +#define SERVO1_PIN 3 // // Limit Switches // -#define X_MIN_PIN 45 -#define X_MAX_PIN 39 -#define Y_MIN_PIN 46 -#define Y_MAX_PIN 41 -#define Z_MIN_PIN 47 -#define Z_MAX_PIN 43 +#define X_MIN_PIN 45 +#define X_MAX_PIN 39 +#define Y_MIN_PIN 46 +#define Y_MAX_PIN 41 +#define Z_MIN_PIN 47 +#define Z_MAX_PIN 43 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 43 + #define Z_MIN_PROBE_PIN 43 #endif // // Steppers // -#define X_STEP_PIN 37 // Support Extension Board -#define X_DIR_PIN 36 -#define X_ENABLE_PIN 38 +#define X_STEP_PIN 37 // Support Extension Board +#define X_DIR_PIN 36 +#define X_ENABLE_PIN 38 #ifndef X_CS_PIN - #define X_CS_PIN -1 + #define X_CS_PIN -1 #endif -#define Y_STEP_PIN 32 // Support Extension Board -#define Y_DIR_PIN 35 -#define Y_ENABLE_PIN 34 +#define Y_STEP_PIN 32 // Support Extension Board +#define Y_DIR_PIN 35 +#define Y_ENABLE_PIN 34 #ifndef Y_CS_PIN - #define Y_CS_PIN -1 + #define Y_CS_PIN -1 #endif -#define Z_STEP_PIN 30 // Support Extension Board -#define Z_DIR_PIN 2 -#define Z_ENABLE_PIN 33 +#define Z_STEP_PIN 30 // Support Extension Board +#define Z_DIR_PIN 2 +#define Z_ENABLE_PIN 33 #ifndef Z_CS_PIN - #define Z_CS_PIN -1 + #define Z_CS_PIN -1 #endif -#define E0_STEP_PIN 29 -#define E0_DIR_PIN 28 -#define E0_ENABLE_PIN 31 +#define E0_STEP_PIN 29 +#define E0_DIR_PIN 28 +#define E0_ENABLE_PIN 31 #ifndef E0_CS_PIN - #define E0_CS_PIN -1 + #define E0_CS_PIN -1 #endif -#define E1_STEP_PIN 22 -#define E1_DIR_PIN 24 -#define E1_ENABLE_PIN 26 +#define E1_STEP_PIN 22 +#define E1_DIR_PIN 24 +#define E1_ENABLE_PIN 26 #ifndef E1_CS_PIN - #define E1_CS_PIN -1 + #define E1_CS_PIN -1 #endif -#define E2_STEP_PIN 25 -#define E2_DIR_PIN 23 -#define E2_ENABLE_PIN 27 +#define E2_STEP_PIN 25 +#define E2_DIR_PIN 23 +#define E2_ENABLE_PIN 27 #ifndef E2_CS_PIN - #define E2_CS_PIN -1 + #define E2_CS_PIN -1 #endif -#define E3_STEP_PIN 15 // Only For Extension Board -#define E3_DIR_PIN 14 -#define E3_ENABLE_PIN 61 +#define E3_STEP_PIN 15 // Only For Extension Board +#define E3_DIR_PIN 14 +#define E3_ENABLE_PIN 61 #ifndef E3_CS_PIN - #define E3_CS_PIN -1 + #define E3_CS_PIN -1 #endif // For Future: Microstepping pins - Mapping not from fastio.h (?) @@ -119,77 +119,77 @@ //#define E3_MS3_PIN ? #if HAS_CUSTOM_PROBE_PIN - #define Z_MIN_PROBE_PIN 49 + #define Z_MIN_PROBE_PIN 49 #endif #if HAS_FILAMENT_SENSOR #ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN Y_MIN_PIN + #define FIL_RUNOUT_PIN Y_MIN_PIN #endif #endif // // Heaters / Fans // -#define HEATER_0_PIN 13 -#define HEATER_1_PIN 12 -#define HEATER_2_PIN 11 -#define HEATER_BED_PIN 7 // BED H1 +#define HEATER_0_PIN 13 +#define HEATER_1_PIN 12 +#define HEATER_2_PIN 11 +#define HEATER_BED_PIN 7 // BED H1 #ifndef FAN_PIN - #define FAN_PIN 9 + #define FAN_PIN 9 #endif -#define FAN1_PIN 8 -#define CONTROLLER_FAN_PIN -1 +#define FAN1_PIN 8 +#define CONTROLLER_FAN_PIN -1 // // Temperature Sensors // -#define TEMP_0_PIN 0 // ANALOG A0 -#define TEMP_1_PIN 1 // ANALOG A1 -#define TEMP_2_PIN 2 // ANALOG A2 -#define TEMP_3_PIN 3 // ANALOG A3 -#define TEMP_BED_PIN 4 // ANALOG A4 +#define TEMP_0_PIN 0 // ANALOG A0 +#define TEMP_1_PIN 1 // ANALOG A1 +#define TEMP_2_PIN 2 // ANALOG A2 +#define TEMP_3_PIN 3 // ANALOG A3 +#define TEMP_BED_PIN 4 // ANALOG A4 // The thermocouple uses Analog pins -#if ENABLED(VER_WITH_THERMOCOUPLE) // Defined in Configuration.h - #define TEMP_4_PIN 5 // A5 - #define TEMP_5_PIN 6 // A6 (Marlin 2.0 not support) +#if ENABLED(VER_WITH_THERMOCOUPLE) // Defined in Configuration.h + #define TEMP_4_PIN 5 // A5 + #define TEMP_5_PIN 6 // A6 (Marlin 2.0 not support) #endif // SPI for Max6675 or Max31855 Thermocouple /* #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 53 + #define MAX6675_SS_PIN 53 #else - #define MAX6675_SS_PIN 49 + #define MAX6675_SS_PIN 49 #endif */ // // Misc. Functions // -#define SDSS 4 // 4,10,52 if using HW SPI. -#define LED_PIN -1 // 13 - HEATER_0_PIN -#define PS_ON_PIN -1 // 65 +#define SDSS 4 // 4,10,52 if using HW SPI. +#define LED_PIN -1 // 13 - HEATER_0_PIN +#define PS_ON_PIN -1 // 65 // MKS TFT / Nextion Use internal USART-1 -#define TFT_LCD_MODULE_COM 1 -#define TFT_LCD_MODULE_BAUDRATE 115600 +#define TFT_LCD_MODULE_COM 1 +#define TFT_LCD_MODULE_BAUDRATE 115600 // ESP WiFi Use internal USART-2 -#define ESP_WIFI_MODULE_COM 2 -#define ESP_WIFI_MODULE_BAUDRATE 115600 -#define ESP_WIFI_MODULE_RESET_PIN -1 -#define PIGGY_GPIO_PIN -1 +#define ESP_WIFI_MODULE_COM 2 +#define ESP_WIFI_MODULE_BAUDRATE 115600 +#define ESP_WIFI_MODULE_RESET_PIN -1 +#define PIGGY_GPIO_PIN -1 // // EEPROM // -#define E2END 0x7FFF // 32Kb (24lc256) -#define I2C_EEPROM // EEPROM on I2C-0 -//#define EEPROM_SD // EEPROM on SDCARD -//#define SPI_EEPROM // EEPROM on SPI-0 +#define MARLIN_EEPROM_SIZE 0x8000 // 32Kb (24lc256) +#define I2C_EEPROM // EEPROM on I2C-0 +//#define EEPROM_SD // EEPROM on SDCARD +//#define SPI_EEPROM // EEPROM on SPI-0 //#define SPI_CHAN_EEPROM1 ? //#define SPI_EEPROM1_CS ? // 2K EEPROM @@ -200,75 +200,75 @@ // // LCD / Controller // -#if HAS_SPI_LCD +#if HAS_WIRED_LCD #if ANY(RADDS_DISPLAY, REPRAP_DISCOUNT_SMART_CONTROLLER, REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) - #define BEEPER_PIN 62 - #define LCD_PINS_D4 48 - #define LCD_PINS_D5 50 - #define LCD_PINS_D6 52 - #define LCD_PINS_D7 53 - #define SD_DETECT_PIN 51 + #define BEEPER_PIN 62 + #define LCD_PINS_D4 48 + #define LCD_PINS_D5 50 + #define LCD_PINS_D6 52 + #define LCD_PINS_D7 53 + #define SD_DETECT_PIN 51 #endif #if EITHER(RADDS_DISPLAY, REPRAP_DISCOUNT_SMART_CONTROLLER) - #define LCD_PINS_RS 63 - #define LCD_PINS_ENABLE 64 + #define LCD_PINS_RS 63 + #define LCD_PINS_ENABLE 64 #elif ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) - #define LCD_PINS_RS 52 - #define LCD_PINS_ENABLE 53 + #define LCD_PINS_RS 52 + #define LCD_PINS_ENABLE 53 - #elif HAS_SSD1306_OLED_I2C + #elif HAS_U8GLIB_I2C_OLED - #define BEEPER_PIN 62 - #define LCD_SDSS 10 - #define SD_DETECT_PIN 51 + #define BEEPER_PIN 62 + #define LCD_SDSS 10 + #define SD_DETECT_PIN 51 #elif ENABLED(FYSETC_MINI_12864) - #define BEEPER_PIN 62 - #define DOGLCD_CS 64 - #define DOGLCD_A0 63 + #define BEEPER_PIN 62 + #define DOGLCD_CS 64 + #define DOGLCD_A0 63 - //#define FORCE_SOFT_SPI // Use this if default of hardware SPI causes display problems - // results in LCD soft SPI mode 3, SD soft SPI mode 0 + //#define FORCE_SOFT_SPI // Use this if default of hardware SPI causes display problems + // results in LCD soft SPI mode 3, SD soft SPI mode 0 - #define LCD_RESET_PIN 48 // Must be high or open for LCD to operate normally. + #define LCD_RESET_PIN 48 // Must be high or open for LCD to operate normally. #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) #ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN 50 // D5 + #define RGB_LED_R_PIN 50 // D5 #endif #ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN 52 // D6 + #define RGB_LED_G_PIN 52 // D6 #endif #ifndef RGB_LED_B_PIN - #define RGB_LED_B_PIN 53 // D7 + #define RGB_LED_B_PIN 53 // D7 #endif #elif ENABLED(FYSETC_MINI_12864_2_1) - #define NEOPIXEL_PIN 50 // D5 + #define NEOPIXEL_PIN 50 // D5 #endif #elif ENABLED(SPARK_FULL_GRAPHICS) //http://doku.radds.org/dokumentation/other-electronics/sparklcd/ #error "Oops! SPARK_FULL_GRAPHICS not supported with RURAMPS4D." - //#define LCD_PINS_D4 29 //? - //#define LCD_PINS_ENABLE 27 //? - //#define LCD_PINS_RS 25 //? - //#define BTN_EN1 35 //? - //#define BTN_EN2 33 //? - //#define BTN_ENC 37 //? + //#define LCD_PINS_D4 29 //? + //#define LCD_PINS_ENABLE 27 //? + //#define LCD_PINS_RS 25 //? + //#define BTN_EN1 35 //? + //#define BTN_EN2 33 //? + //#define BTN_ENC 37 //? #endif // SPARK_FULL_GRAPHICS #if ENABLED(NEWPANEL) - #define BTN_EN1 44 - #define BTN_EN2 42 - #define BTN_ENC 40 + #define BTN_EN1 44 + #define BTN_EN2 42 + #define BTN_ENC 40 #endif -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD diff --git a/Marlin/src/pins/sam/pins_RURAMPS4D_13.h b/Marlin/src/pins/sam/pins_RURAMPS4D_13.h index d0c24e68a358..dc0c1279954b 100644 --- a/Marlin/src/pins/sam/pins_RURAMPS4D_13.h +++ b/Marlin/src/pins/sam/pins_RURAMPS4D_13.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * * Ported sys0724 & Vynt */ @@ -32,7 +32,7 @@ * | */ -#ifndef __SAM3X8E__ +#if NOT_TARGET(__SAM3X8E__) #error "Oops! Select 'Arduino Due' in 'Tools > Board.'" #endif @@ -41,141 +41,141 @@ // // Servos // -#define SERVO0_PIN 5 -#define SERVO1_PIN 3 +#define SERVO0_PIN 5 +#define SERVO1_PIN 3 // // Limit Switches // -#define X_MIN_PIN 45 -#define X_MAX_PIN 39 -#define Y_MIN_PIN 46 -#define Y_MAX_PIN 41 -#define Z_MIN_PIN 47 -#define Z_MAX_PIN 43 +#define X_MIN_PIN 45 +#define X_MAX_PIN 39 +#define Y_MIN_PIN 46 +#define Y_MAX_PIN 41 +#define Z_MIN_PIN 47 +#define Z_MAX_PIN 43 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 49 + #define Z_MIN_PROBE_PIN 49 #endif // // Steppers // -#define X_STEP_PIN 37 // Support Extension Board -#define X_DIR_PIN 36 -#define X_ENABLE_PIN 31 +#define X_STEP_PIN 37 // Support Extension Board +#define X_DIR_PIN 36 +#define X_ENABLE_PIN 31 #ifndef X_CS_PIN - #define X_CS_PIN 38 + #define X_CS_PIN 38 #endif -#define Y_STEP_PIN 32 // Support Extension Board -#define Y_DIR_PIN 35 -#define Y_ENABLE_PIN 31 +#define Y_STEP_PIN 32 // Support Extension Board +#define Y_DIR_PIN 35 +#define Y_ENABLE_PIN 31 #ifndef Y_CS_PIN - #define Y_CS_PIN 34 + #define Y_CS_PIN 34 #endif -#define Z_STEP_PIN 30 // Support Extension Board -#define Z_DIR_PIN 2 -#define Z_ENABLE_PIN 31 +#define Z_STEP_PIN 30 // Support Extension Board +#define Z_DIR_PIN 2 +#define Z_ENABLE_PIN 31 #ifndef Z_CS_PIN - #define Z_CS_PIN 10 + #define Z_CS_PIN 10 #endif -#define E0_STEP_PIN 29 -#define E0_DIR_PIN 28 -#define E0_ENABLE_PIN 33 +#define E0_STEP_PIN 29 +#define E0_DIR_PIN 28 +#define E0_ENABLE_PIN 33 #ifndef E0_CS_PIN - #define E0_CS_PIN 14 + #define E0_CS_PIN 14 #endif -#define E1_STEP_PIN 22 -#define E1_DIR_PIN 24 -#define E1_ENABLE_PIN 26 +#define E1_STEP_PIN 22 +#define E1_DIR_PIN 24 +#define E1_ENABLE_PIN 26 #ifndef E1_CS_PIN - #define E1_CS_PIN 15 + #define E1_CS_PIN 15 #endif -#define E2_STEP_PIN 25 -#define E2_DIR_PIN 23 -#define E2_ENABLE_PIN 27 +#define E2_STEP_PIN 25 +#define E2_DIR_PIN 23 +#define E2_ENABLE_PIN 27 #ifndef E2_CS_PIN - #define E2_CS_PIN 61 + #define E2_CS_PIN 61 #endif #if HAS_CUSTOM_PROBE_PIN - #define Z_MIN_PROBE_PIN 49 + #define Z_MIN_PROBE_PIN 49 #endif #if HAS_FILAMENT_SENSOR #ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN Y_MIN_PIN + #define FIL_RUNOUT_PIN Y_MIN_PIN #endif #endif // // Heaters / Fans // -#define HEATER_0_PIN 13 -#define HEATER_1_PIN 12 -#define HEATER_2_PIN 11 -#define HEATER_BED_PIN 7 // BED H1 +#define HEATER_0_PIN 13 +#define HEATER_1_PIN 12 +#define HEATER_2_PIN 11 +#define HEATER_BED_PIN 7 // BED H1 -#define FAN_PIN 9 -#define FAN1_PIN 8 -#define CONTROLLER_FAN_PIN -1 +#define FAN_PIN 9 +#define FAN1_PIN 8 +#define CONTROLLER_FAN_PIN -1 // // Temperature Sensors // -#define TEMP_0_PIN 0 // ANALOG A0 -#define TEMP_1_PIN 1 // ANALOG A1 -#define TEMP_2_PIN 2 // ANALOG A2 -#define TEMP_3_PIN 3 // ANALOG A3 -#define TEMP_BED_PIN 4 // ANALOG A4 +#define TEMP_0_PIN 0 // ANALOG A0 +#define TEMP_1_PIN 1 // ANALOG A1 +#define TEMP_2_PIN 2 // ANALOG A2 +#define TEMP_3_PIN 3 // ANALOG A3 +#define TEMP_BED_PIN 4 // ANALOG A4 // The thermocouple uses Analog pins -#if ENABLED(VER_WITH_THERMOCOUPLE) // Defined in Configuration.h - #define TEMP_4_PIN 5 // A5 - #define TEMP_5_PIN 6 // A6 (Marlin 2.0 not support) +#if ENABLED(VER_WITH_THERMOCOUPLE) // Defined in Configuration.h + #define TEMP_4_PIN 5 // A5 + #define TEMP_5_PIN 6 // A6 (Marlin 2.0 not support) #endif // SPI for Max6675 or Max31855 Thermocouple /* #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 53 + #define MAX6675_SS_PIN 53 #else - #define MAX6675_SS_PIN 49 + #define MAX6675_SS_PIN 49 #endif */ // // Misc. Functions // -#define SDSS 4 // 4,10,52 if using HW SPI. -#define LED_PIN -1 // 13 - HEATER_0_PIN -#define PS_ON_PIN -1 // 65 +#define SDSS 4 // 4,10,52 if using HW SPI. +#define LED_PIN -1 // 13 - HEATER_0_PIN +#define PS_ON_PIN -1 // 65 // MKS TFT / Nextion Use internal USART-1 -#define TFT_LCD_MODULE_COM 1 -#define TFT_LCD_MODULE_BAUDRATE 115200 +#define TFT_LCD_MODULE_COM 1 +#define TFT_LCD_MODULE_BAUDRATE 115200 // ESP WiFi Use internal USART-2 -#define ESP_WIFI_MODULE_COM 2 -#define ESP_WIFI_MODULE_BAUDRATE 115200 -#define ESP_WIFI_MODULE_RESET_PIN -1 -#define PIGGY_GPIO_PIN -1 +#define ESP_WIFI_MODULE_COM 2 +#define ESP_WIFI_MODULE_BAUDRATE 115200 +#define ESP_WIFI_MODULE_RESET_PIN -1 +#define PIGGY_GPIO_PIN -1 // // EEPROM // -#define E2END 0x7FFF // 32Kb (24lc256) -#define I2C_EEPROM // EEPROM on I2C-0 -//#define EEPROM_SD // EEPROM on SDCARD -//#define SPI_EEPROM // EEPROM on SPI-0 +#define MARLIN_EEPROM_SIZE 0x8000 // 32Kb (24lc256) +#define I2C_EEPROM // EEPROM on I2C-0 +//#define EEPROM_SD // EEPROM on SDCARD +//#define SPI_EEPROM // EEPROM on SPI-0 //#define SPI_CHAN_EEPROM1 ? //#define SPI_EEPROM1_CS ? // 2K EEPROM @@ -186,73 +186,71 @@ // // LCD / Controller // -#if HAS_SPI_LCD +#if HAS_WIRED_LCD #if ANY(RADDS_DISPLAY, REPRAP_DISCOUNT_SMART_CONTROLLER, REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) - #define BEEPER_PIN 62 - #define LCD_PINS_D4 48 - #define LCD_PINS_D5 50 - #define LCD_PINS_D6 52 - #define LCD_PINS_D7 53 - #define SD_DETECT_PIN 51 + #define BEEPER_PIN 62 + #define LCD_PINS_D4 48 + #define LCD_PINS_D5 50 + #define LCD_PINS_D6 52 + #define LCD_PINS_D7 53 + #define SD_DETECT_PIN 51 #endif #if EITHER(RADDS_DISPLAY, REPRAP_DISCOUNT_SMART_CONTROLLER) - #define LCD_PINS_RS 63 - #define LCD_PINS_ENABLE 64 + #define LCD_PINS_RS 63 + #define LCD_PINS_ENABLE 64 #elif ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) - #define LCD_PINS_RS 52 - #define LCD_PINS_ENABLE 53 + #define LCD_PINS_RS 52 + #define LCD_PINS_ENABLE 53 - #elif HAS_SSD1306_OLED_I2C + #elif HAS_U8GLIB_I2C_OLED - #define BEEPER_PIN 62 - #define LCD_SDSS 10 - #define SD_DETECT_PIN 51 + #define BEEPER_PIN 62 + #define LCD_SDSS 10 + #define SD_DETECT_PIN 51 #elif ENABLED(FYSETC_MINI_12864) - #define BEEPER_PIN 62 - #define DOGLCD_CS 64 - #define DOGLCD_A0 63 + #define BEEPER_PIN 62 + #define DOGLCD_CS 64 + #define DOGLCD_A0 63 - //#define FORCE_SOFT_SPI // Use this if default of hardware SPI causes display problems - // results in LCD soft SPI mode 3, SD soft SPI mode 0 + //#define FORCE_SOFT_SPI // Use this if default of hardware SPI causes display problems + // results in LCD soft SPI mode 3, SD soft SPI mode 0 - #define LCD_RESET_PIN 48 // Must be high or open for LCD to operate normally. + #define LCD_RESET_PIN 48 // Must be high or open for LCD to operate normally. #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) #ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN 50 // D5 + #define RGB_LED_R_PIN 50 // D5 #endif #ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN 52 // D6 + #define RGB_LED_G_PIN 52 // D6 #endif #ifndef RGB_LED_B_PIN - #define RGB_LED_B_PIN 53 // D7 + #define RGB_LED_B_PIN 53 // D7 #endif #elif ENABLED(FYSETC_MINI_12864_2_1) - #define NEOPIXEL_PIN 50 // D5 + #define NEOPIXEL_PIN 50 // D5 #endif #elif ENABLED(MKS_MINI_12864) - #define ORIG_BEEPER_PIN 62 + #define DOGLCD_A0 52 + #define DOGLCD_CS 50 - #define DOGLCD_A0 52 - #define DOGLCD_CS 50 - - #define SD_DETECT_PIN 51 + #define SD_DETECT_PIN 51 #endif #if ENABLED(NEWPANEL) - #define BTN_EN1 44 - #define BTN_EN2 42 - #define BTN_ENC 40 + #define BTN_EN1 44 + #define BTN_EN2 42 + #define BTN_ENC 40 #endif -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD diff --git a/Marlin/src/pins/sam/pins_ULTRATRONICS_PRO.h b/Marlin/src/pins/sam/pins_ULTRATRONICS_PRO.h index db0826e7c9d7..0b91ba61d6df 100644 --- a/Marlin/src/pins/sam/pins_ULTRATRONICS_PRO.h +++ b/Marlin/src/pins/sam/pins_ULTRATRONICS_PRO.h @@ -16,16 +16,17 @@ * 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 . + * along with this program. If not, see . * */ #pragma once /** * ReprapWorld ULTRATRONICS v1.0 + * https://reprapworld.com/documentation/datasheet_ultratronics10_05.pdf */ -#ifndef ARDUINO_ARCH_SAM +#if NOT_TARGET(ARDUINO_ARCH_SAM) #error "Oops! Select 'Arduino Due' in 'Tools > Board.'" #endif @@ -35,140 +36,144 @@ // Servos // #if NUM_SERVOS > 0 - #define SERVO0_PIN 11 + #define SERVO0_PIN 11 #if NUM_SERVOS > 1 - #define SERVO1_PIN 12 + #define SERVO1_PIN 12 #endif #endif // // Limit Switches // -#define X_MIN_PIN 31 -#define X_MAX_PIN 30 -#define Y_MIN_PIN 12 -#define Y_MAX_PIN 11 -#define Z_MIN_PIN 29 -#define Z_MAX_PIN 28 +#define X_MIN_PIN 31 +#define X_MAX_PIN 30 +#define Y_MIN_PIN 12 +#define Y_MAX_PIN 11 +#define Z_MIN_PIN 29 +#define Z_MAX_PIN 28 // // Steppers // -#define X_STEP_PIN 35 -#define X_DIR_PIN 34 -#define X_ENABLE_PIN 37 +#define X_STEP_PIN 35 +#define X_DIR_PIN 34 +#define X_ENABLE_PIN 37 #ifndef X_CS_PIN - #define X_CS_PIN 18 + #define X_CS_PIN 18 #endif -#define Y_STEP_PIN 22 -#define Y_DIR_PIN 23 -#define Y_ENABLE_PIN 33 +#define Y_STEP_PIN 22 +#define Y_DIR_PIN 23 +#define Y_ENABLE_PIN 33 #ifndef Y_CS_PIN - #define Y_CS_PIN 19 + #define Y_CS_PIN 19 #endif -#define Z_STEP_PIN 25 -#define Z_DIR_PIN 26 -#define Z_ENABLE_PIN 24 +#define Z_STEP_PIN 25 +#define Z_DIR_PIN 26 +#define Z_ENABLE_PIN 24 #ifndef Z_CS_PIN - #define Z_CS_PIN 16 + #define Z_CS_PIN 16 #endif -#define E0_STEP_PIN 47 -#define E0_DIR_PIN 46 -#define E0_ENABLE_PIN 48 +#define E0_STEP_PIN 47 +#define E0_DIR_PIN 46 +#define E0_ENABLE_PIN 48 #ifndef E0_CS_PIN - #define E0_CS_PIN 17 + #define E0_CS_PIN 17 #endif -#define E1_STEP_PIN 44 -#define E1_DIR_PIN 36 -#define E1_ENABLE_PIN 45 +#define E1_STEP_PIN 44 +#define E1_DIR_PIN 36 +#define E1_ENABLE_PIN 45 #ifndef E1_CS_PIN - #define E1_CS_PIN -1 + #define E1_CS_PIN -1 #endif -#define E2_STEP_PIN 42 -#define E2_DIR_PIN 41 -#define E2_ENABLE_PIN 43 +#define E2_STEP_PIN 42 +#define E2_DIR_PIN 41 +#define E2_ENABLE_PIN 43 #ifndef E2_CS_PIN - #define E2_CS_PIN -1 + #define E2_CS_PIN -1 #endif -#define E3_STEP_PIN 39 -#define E3_DIR_PIN 38 -#define E3_ENABLE_PIN 40 +#define E3_STEP_PIN 39 +#define E3_DIR_PIN 38 +#define E3_ENABLE_PIN 40 #ifndef E3_CS_PIN - #define E3_CS_PIN -1 + #define E3_CS_PIN -1 #endif // // Temperature Sensors // -#define TEMP_0_PIN 0 // Analog Input -#define TEMP_1_PIN 2 // Analog Input -#define TEMP_2_PIN 3 // Analog Input -#define TEMP_3_PIN 4 // Analog Input -#define TEMP_BED_PIN 1 // Analog Input +#define TEMP_0_PIN 0 // Analog Input +#define TEMP_1_PIN 2 // Analog Input +#define TEMP_2_PIN 3 // Analog Input +#define TEMP_3_PIN 4 // Analog Input +#define TEMP_BED_PIN 1 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 3 -#define HEATER_1_PIN 8 -#define HEATER_2_PIN 7 -#define HEATER_3_PIN 9 -#define HEATER_BED_PIN 2 +#define HEATER_0_PIN 3 +#define HEATER_1_PIN 8 +#define HEATER_2_PIN 7 +#define HEATER_3_PIN 9 +#define HEATER_BED_PIN 2 #ifndef FAN_PIN - #define FAN_PIN 6 + #define FAN_PIN 6 #endif -#define FAN2_PIN 5 +#define FAN2_PIN 5 // // Misc. Functions // -#define SDSS 59 -#define SD_DETECT_PIN 60 -#define LED_PIN 13 -#define PS_ON_PIN 32 +#define SDSS 59 +#define SD_DETECT_PIN 60 +#define LED_PIN 13 +#define PS_ON_PIN 32 // // SPI Buses // -#define DAC0_SYNC 53 // PB14 -#define SPI_CHAN_DAC 1 +#define DAC0_SYNC 53 // PB14 +#define SPI_CHAN_DAC 1 -#define SPI_CHAN_EEPROM1 -1 -#define SPI_EEPROM1_CS -1 -#define SPI_EEPROM2_CS -1 -#define SPI_FLASH_CS -1 +#define SPI_CHAN_EEPROM1 -1 +#define SPI_EEPROM1_CS -1 +#define SPI_EEPROM2_CS -1 +#define SPI_FLASH_CS -1 + +#define SCK_PIN 76 +#define MISO_PIN 74 +#define MOSI_PIN 75 // SPI for Max6675 or Max31855 Thermocouple -#define MAX6675_SS_PIN 65 -#define MAX31855_SS0 65 -#define MAX31855_SS1 52 -#define MAX31855_SS2 50 -#define MAX31855_SS3 51 +#define MAX6675_SS_PIN 65 +#define MAX31855_SS0 65 +#define MAX31855_SS1 52 +#define MAX31855_SS2 50 +#define MAX31855_SS3 51 -#define ENC424_SS 61 +#define ENC424_SS 61 // // LCD / Controller // -#define BEEPER_PIN 27 +#define BEEPER_PIN 27 #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) - #define LCD_PINS_RS A8 // CS chip select / SS chip slave select - #define LCD_PINS_ENABLE MOSI // SID (MOSI) - #define LCD_PINS_D4 SCK // SCK (CLK) clock + #define LCD_PINS_RS A8 // CS chip select / SS chip slave select + #define LCD_PINS_ENABLE MOSI // SID (MOSI) + #define LCD_PINS_D4 SCK // SCK (CLK) clock - #define BTN_EN1 20 - #define BTN_EN2 21 - #define BTN_ENC 64 + #define BTN_EN1 20 + #define BTN_EN2 21 + #define BTN_ENC 64 #endif // REPRAPWORLD_GRAPHICAL_LCD diff --git a/Marlin/src/pins/samd/pins_RAMPS_144.h b/Marlin/src/pins/samd/pins_RAMPS_144.h index 107ef9f57e95..6076be07e9d4 100644 --- a/Marlin/src/pins/samd/pins_RAMPS_144.h +++ b/Marlin/src/pins/samd/pins_RAMPS_144.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -25,7 +25,7 @@ * AGCM4 with RAMPS v1.4.4 pin assignments */ -#ifndef ARDUINO_GRAND_CENTRAL_M4 +#if NOT_TARGET(ARDUINO_GRAND_CENTRAL_M4) #error "Oops! Select 'Adafruit Grand Central M4' in 'Tools > Board.'" #endif @@ -36,110 +36,110 @@ // // Servos // -#define SERVO0_PIN 11 -#define SERVO1_PIN 6 -#define SERVO2_PIN 5 -#define SERVO3_PIN 4 +#define SERVO0_PIN 11 +#define SERVO1_PIN 6 +#define SERVO2_PIN 5 +#define SERVO3_PIN 4 // // EEPROM // -#define E2END 0x7FFF // 32Kb (24lc256) -#define I2C_EEPROM // EEPROM on I2C-0 +//#define QSPI_EEPROM // Use AGCM4 onboard QSPI EEPROM (Uses 4K of RAM) +#define I2C_EEPROM // EEPROM on I2C-0 +#define MARLIN_EEPROM_SIZE 0x8000 // 32K (24lc256) // // Limit Switches // -#define X_MIN_PIN 3 -#define X_MAX_PIN 2 -#define Y_MIN_PIN 14 -#define Y_MAX_PIN 15 -#define Z_MIN_PIN 18 -#define Z_MAX_PIN 19 +#define X_MIN_PIN 3 +#define X_MAX_PIN 2 +#define Y_MIN_PIN 14 +#define Y_MAX_PIN 15 +#define Z_MIN_PIN 18 +#define Z_MAX_PIN 19 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 18 + #define Z_MIN_PROBE_PIN 18 #endif // // Steppers // -#define X_STEP_PIN 67 // Mega/Due:54 - AGCM4:67 -#define X_DIR_PIN 68 // Mega/Due:55 - AGCM4:68 -#define X_ENABLE_PIN 38 +#define X_STEP_PIN 67 // Mega/Due:54 - AGCM4:67 +#define X_DIR_PIN 68 // Mega/Due:55 - AGCM4:68 +#define X_ENABLE_PIN 38 #ifndef X_CS_PIN - #define X_CS_PIN 47 + #define X_CS_PIN 47 #endif -#define Y_STEP_PIN 73 // Mega/Due:60 - AGCM4:73 -#define Y_DIR_PIN 74 // Mega/Due:61 - AGCM4:74 -#define Y_ENABLE_PIN 69 // Mega/Due:56 - AGCM4:69 +#define Y_STEP_PIN 73 // Mega/Due:60 - AGCM4:73 +#define Y_DIR_PIN 74 // Mega/Due:61 - AGCM4:74 +#define Y_ENABLE_PIN 69 // Mega/Due:56 - AGCM4:69 #ifndef Y_CS_PIN - #define Y_CS_PIN 45 + #define Y_CS_PIN 45 #endif -#define Z_STEP_PIN 46 -#define Z_DIR_PIN 48 -#define Z_ENABLE_PIN 54 // Mega/Due:62 - AGCM4:54 +#define Z_STEP_PIN 46 +#define Z_DIR_PIN 48 +#define Z_ENABLE_PIN 54 // Mega/Due:62 - AGCM4:54 #ifndef Z_CS_PIN - #define Z_CS_PIN 32 + #define Z_CS_PIN 32 #endif -#define Z2_STEP_PIN 36 -#define Z2_DIR_PIN 34 -#define Z2_ENABLE_PIN 30 +#define Z2_STEP_PIN 36 +#define Z2_DIR_PIN 34 +#define Z2_ENABLE_PIN 30 #ifndef Z2_CS_PIN - #define Z2_CS_PIN 22 + #define Z2_CS_PIN 22 #endif -#define E0_STEP_PIN 26 -#define E0_DIR_PIN 28 -#define E0_ENABLE_PIN 24 +#define E0_STEP_PIN 26 +#define E0_DIR_PIN 28 +#define E0_ENABLE_PIN 24 #ifndef E0_CS_PIN - #define E0_CS_PIN 43 + #define E0_CS_PIN 43 #endif // // Temperature Sensors // -#define TEMP_0_PIN 13 -#define TEMP_BED_PIN 14 -#define TEMP_CHAMBER_PIN 15 +#define TEMP_0_PIN 13 +#define TEMP_BED_PIN 14 +#define TEMP_CHAMBER_PIN 15 // // Heaters / Fans // -#define HEATER_0_PIN 10 -#define HEATER_BED_PIN 8 -#define FAN_PIN 9 -#define FAN1_PIN 7 -#define FAN2_PIN 12 +#define HEATER_0_PIN 10 +#define HEATER_BED_PIN 8 +#define FAN_PIN 9 +#define FAN1_PIN 7 +#define FAN2_PIN 12 // // Misc. Functions // -#define SDSS 53 -#define LED_PIN 13 +#define SDSS 53 +#define LED_PIN 13 #ifndef FILWIDTH_PIN - #define FILWIDTH_PIN 5 // Analog Input on AUX2 + #define FILWIDTH_PIN 5 // Analog Input on AUX2 #endif -// RAMPS 1.4 DIO 4 on the servos connector #ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN 4 + #define FIL_RUNOUT_PIN 70 #endif #ifndef PS_ON_PIN - #define PS_ON_PIN 39 + #define PS_ON_PIN 39 #endif #if ENABLED(CASE_LIGHT_ENABLE) && !defined(CASE_LIGHT_PIN) && !defined(SPINDLE_LASER_ENA_PIN) - #if NUM_SERVOS <= 1 // Prefer the servo connector - #define CASE_LIGHT_PIN 6 // Hardware PWM + #if NUM_SERVOS <= 1 // Prefer the servo connector + #define CASE_LIGHT_PIN 6 // Hardware PWM #endif #endif @@ -147,10 +147,10 @@ // M3/M4/M5 - Spindle/Laser Control // #if HAS_CUTTER && !defined(SPINDLE_LASER_ENA_PIN) - #if !NUM_SERVOS // Use servo connector if possible - #define SPINDLE_LASER_ENA_PIN 4 // Pullup or pulldown! - #define SPINDLE_LASER_PWM_PIN 6 // Hardware PWM - #define SPINDLE_DIR_PIN 5 + #if !NUM_SERVOS // Use servo connector if possible + #define SPINDLE_LASER_ENA_PIN 4 // Pullup or pulldown! + #define SPINDLE_LASER_PWM_PIN 6 // Hardware PWM + #define SPINDLE_DIR_PIN 5 #else #error "No auto-assignable Spindle/Laser pins available." #endif @@ -161,17 +161,17 @@ // #if ENABLED(TMC_USE_SW_SPI) #ifndef TMC_SW_MOSI - #define TMC_SW_MOSI 58 // Mega/Due:66 - AGCM4:58 + #define TMC_SW_MOSI 58 // Mega/Due:66 - AGCM4:58 #endif #ifndef TMC_SW_MISO - #define TMC_SW_MISO 44 + #define TMC_SW_MISO 44 #endif #ifndef TMC_SW_SCK - #define TMC_SW_SCK 56 // Mega/Due:64 - AGCM4:56 + #define TMC_SW_SCK 56 // Mega/Due:64 - AGCM4:56 #endif #endif -#if HAS_TMC220x +#if HAS_TMC_UART /** * TMC2208/TMC2209 stepper drivers * @@ -195,91 +195,91 @@ // #ifndef X_SERIAL_TX_PIN - #define X_SERIAL_TX_PIN 47 + #define X_SERIAL_TX_PIN 47 #endif #ifndef X_SERIAL_RX_PIN - #define X_SERIAL_RX_PIN 47 + #define X_SERIAL_RX_PIN 47 #endif #ifndef X2_SERIAL_TX_PIN - #define X2_SERIAL_TX_PIN -1 + #define X2_SERIAL_TX_PIN -1 #endif #ifndef X2_SERIAL_RX_PIN - #define X2_SERIAL_RX_PIN -1 + #define X2_SERIAL_RX_PIN -1 #endif #ifndef Y_SERIAL_TX_PIN - #define Y_SERIAL_TX_PIN 45 + #define Y_SERIAL_TX_PIN 45 #endif #ifndef Y_SERIAL_RX_PIN - #define Y_SERIAL_RX_PIN 45 + #define Y_SERIAL_RX_PIN 45 #endif #ifndef Y2_SERIAL_TX_PIN - #define Y2_SERIAL_TX_PIN -1 + #define Y2_SERIAL_TX_PIN -1 #endif #ifndef Y2_SERIAL_RX_PIN - #define Y2_SERIAL_RX_PIN -1 + #define Y2_SERIAL_RX_PIN -1 #endif #ifndef Z_SERIAL_TX_PIN - #define Z_SERIAL_TX_PIN 32 + #define Z_SERIAL_TX_PIN 32 #endif #ifndef Z_SERIAL_RX_PIN - #define Z_SERIAL_RX_PIN 32 + #define Z_SERIAL_RX_PIN 32 #endif #ifndef Z2_SERIAL_TX_PIN - #define Z2_SERIAL_TX_PIN 22 + #define Z2_SERIAL_TX_PIN 22 #endif #ifndef Z2_SERIAL_RX_PIN - #define Z2_SERIAL_RX_PIN 22 + #define Z2_SERIAL_RX_PIN 22 #endif #ifndef E0_SERIAL_TX_PIN - #define E0_SERIAL_TX_PIN 43 + #define E0_SERIAL_TX_PIN 43 #endif #ifndef E0_SERIAL_RX_PIN - #define E0_SERIAL_RX_PIN 43 + #define E0_SERIAL_RX_PIN 43 #endif #ifndef E1_SERIAL_TX_PIN - #define E1_SERIAL_TX_PIN -1 + #define E1_SERIAL_TX_PIN -1 #endif #ifndef E1_SERIAL_RX_PIN - #define E1_SERIAL_RX_PIN -1 + #define E1_SERIAL_RX_PIN -1 #endif #ifndef E2_SERIAL_TX_PIN - #define E2_SERIAL_TX_PIN -1 + #define E2_SERIAL_TX_PIN -1 #endif #ifndef E2_SERIAL_RX_PIN - #define E2_SERIAL_RX_PIN -1 + #define E2_SERIAL_RX_PIN -1 #endif #ifndef E3_SERIAL_TX_PIN - #define E3_SERIAL_TX_PIN -1 + #define E3_SERIAL_TX_PIN -1 #endif #ifndef E3_SERIAL_RX_PIN - #define E3_SERIAL_RX_PIN -1 + #define E3_SERIAL_RX_PIN -1 #endif #ifndef E4_SERIAL_TX_PIN - #define E4_SERIAL_TX_PIN -1 + #define E4_SERIAL_TX_PIN -1 #endif #ifndef E4_SERIAL_RX_PIN - #define E4_SERIAL_RX_PIN -1 + #define E4_SERIAL_RX_PIN -1 #endif #ifndef E5_SERIAL_TX_PIN - #define E5_SERIAL_TX_PIN -1 + #define E5_SERIAL_TX_PIN -1 #endif #ifndef E5_SERIAL_RX_PIN - #define E5_SERIAL_RX_PIN -1 + #define E5_SERIAL_RX_PIN -1 #endif #ifndef E6_SERIAL_TX_PIN - #define E6_SERIAL_TX_PIN -1 + #define E6_SERIAL_TX_PIN -1 #endif #ifndef E6_SERIAL_RX_PIN - #define E6_SERIAL_RX_PIN -1 + #define E6_SERIAL_RX_PIN -1 #endif #ifndef E7_SERIAL_TX_PIN - #define E7_SERIAL_TX_PIN -1 + #define E7_SERIAL_TX_PIN -1 #endif #ifndef E7_SERIAL_RX_PIN - #define E7_SERIAL_RX_PIN -1 + #define E7_SERIAL_RX_PIN -1 #endif #endif @@ -287,7 +287,7 @@ // LCDs and Controllers // ////////////////////////// -#if HAS_SPI_LCD +#if HAS_WIRED_LCD // // LCD Display output pins @@ -295,67 +295,67 @@ #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) // TO TEST - // #define LCD_PINS_RS 49 // CS chip select /SS chip slave select - // #define LCD_PINS_ENABLE 51 // SID (MOSI) - // #define LCD_PINS_D4 52 // SCK (CLK) clock + //#define LCD_PINS_RS 49 // CS chip select /SS chip slave select + //#define LCD_PINS_ENABLE 51 // SID (MOSI) + //#define LCD_PINS_D4 52 // SCK (CLK) clock #elif BOTH(NEWPANEL, PANEL_ONE) // TO TEST - // #define LCD_PINS_RS 40 - // #define LCD_PINS_ENABLE 42 - // #define LCD_PINS_D4 57 // Mega/Due:65 - AGCM4:57 - // #define LCD_PINS_D5 58 // Mega/Due:66 - AGCM4:58 - // #define LCD_PINS_D6 44 - // #define LCD_PINS_D7 56 // Mega/Due:64 - AGCM4:56 + //#define LCD_PINS_RS 40 + //#define LCD_PINS_ENABLE 42 + //#define LCD_PINS_D4 57 // Mega/Due:65 - AGCM4:57 + //#define LCD_PINS_D5 58 // Mega/Due:66 - AGCM4:58 + //#define LCD_PINS_D6 44 + //#define LCD_PINS_D7 56 // Mega/Due:64 - AGCM4:56 #else #if ENABLED(CR10_STOCKDISPLAY) // TO TEST - // #define LCD_PINS_RS 27 - // #define LCD_PINS_ENABLE 29 - // #define LCD_PINS_D4 25 + //#define LCD_PINS_RS 27 + //#define LCD_PINS_ENABLE 29 + //#define LCD_PINS_D4 25 #if DISABLED(NEWPANEL) // TO TEST - // #define BEEPER_PIN 37 + //#define BEEPER_PIN 37 #endif #elif ENABLED(ZONESTAR_LCD) // TO TEST - // #define LCD_PINS_RS 56 // Mega/Due:64 - AGCM4:56 - // #define LCD_PINS_ENABLE 44 - // #define LCD_PINS_D4 55 // Mega/Due:63 - AGCM4:55 - // #define LCD_PINS_D5 40 - // #define LCD_PINS_D6 42 - // #define LCD_PINS_D7 57 // Mega/Due:65 - AGCM4:57 + //#define LCD_PINS_RS 56 // Mega/Due:64 - AGCM4:56 + //#define LCD_PINS_ENABLE 44 + //#define LCD_PINS_D4 55 // Mega/Due:63 - AGCM4:55 + //#define LCD_PINS_D5 40 + //#define LCD_PINS_D6 42 + //#define LCD_PINS_D7 57 // Mega/Due:65 - AGCM4:57 #else #if EITHER(MKS_12864OLED, MKS_12864OLED_SSD1306) // TO TEST - // #define LCD_PINS_DC 25 // Set as output on init - // #define LCD_PINS_RS 27 // Pull low for 1s to init + //#define LCD_PINS_DC 25 // Set as output on init + //#define LCD_PINS_RS 27 // Pull low for 1s to init // DOGM SPI LCD Support - // #define DOGLCD_CS 16 - // #define DOGLCD_MOSI 17 - // #define DOGLCD_SCK 23 - // #define DOGLCD_A0 LCD_PINS_DC + //#define DOGLCD_CS 16 + //#define DOGLCD_MOSI 17 + //#define DOGLCD_SCK 23 + //#define DOGLCD_A0 LCD_PINS_DC #else - #define LCD_PINS_RS 16 - #define LCD_PINS_ENABLE 17 - #define LCD_PINS_D4 23 - #define LCD_PINS_D5 25 - #define LCD_PINS_D6 27 + #define LCD_PINS_RS 16 + #define LCD_PINS_ENABLE 17 + #define LCD_PINS_D4 23 + #define LCD_PINS_D5 25 + #define LCD_PINS_D6 27 #endif - #define LCD_PINS_D7 29 + #define LCD_PINS_D7 29 #if DISABLED(NEWPANEL) - #define BEEPER_PIN 33 + #define BEEPER_PIN 33 #endif #endif @@ -363,10 +363,10 @@ #if DISABLED(NEWPANEL) // Buttons attached to a shift register // Not wired yet - //#define SHIFT_CLK 38 - //#define SHIFT_LD 42 - //#define SHIFT_OUT 40 - //#define SHIFT_EN 17 + //#define SHIFT_CLK 38 + //#define SHIFT_LD 42 + //#define SHIFT_OUT 40 + //#define SHIFT_EN 17 #endif #endif @@ -378,151 +378,151 @@ #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) - #define BEEPER_PIN 37 + #define BEEPER_PIN 37 #if ENABLED(CR10_STOCKDISPLAY) // TO TEST - // #define BTN_EN1 17 - // #define BTN_EN2 23 + //#define BTN_EN1 17 + //#define BTN_EN2 23 #else - #define BTN_EN1 31 - #define BTN_EN2 33 + #define BTN_EN1 31 + #define BTN_EN2 33 #endif - #define BTN_ENC 35 + #define BTN_ENC 35 #ifndef SD_DETECT_PIN - #define SD_DETECT_PIN 49 + #define SD_DETECT_PIN 49 #endif - #define KILL_PIN 41 + #define KILL_PIN 41 #if ENABLED(BQ_LCD_SMART_CONTROLLER) // TO TEST - // #define LCD_BACKLIGHT_PIN 39 + //#define LCD_BACKLIGHT_PIN 39 #endif #elif ENABLED(REPRAPWORLD_GRAPHICAL_LCD) // TO TEST - // #define BTN_EN1 56 // Mega/Due:64 - AGCM4:56 - // #define BTN_EN2 72 // Mega/Due:59 - AGCM4:72 - // #define BTN_ENC 55 - // #define SD_DETECT_PIN 42 + //#define BTN_EN1 56 // Mega/Due:64 - AGCM4:56 + //#define BTN_EN2 72 // Mega/Due:59 - AGCM4:72 + //#define BTN_ENC 55 + //#define SD_DETECT_PIN 42 #elif ENABLED(LCD_I2C_PANELOLU2) // TO TEST - // #define BTN_EN1 47 - // #define BTN_EN2 43 - // #define BTN_ENC 32 - // #define LCD_SDSS SDSS - // #define KILL_PIN 41 + //#define BTN_EN1 47 + //#define BTN_EN2 43 + //#define BTN_ENC 32 + //#define LCD_SDSS SDSS + //#define KILL_PIN 41 #elif ENABLED(LCD_I2C_VIKI) // TO TEST - // #define BTN_EN1 40 // http://files.panucatt.com/datasheets/viki_wiring_diagram.pdf explains 40/42. - // #define BTN_EN2 42 - // #define BTN_ENC -1 + //#define BTN_EN1 40 // https://files.panucatt.com/datasheets/viki_wiring_diagram.pdf explains 40/42. + //#define BTN_EN2 42 + //#define BTN_ENC -1 - // #define LCD_SDSS SDSS - // #define SD_DETECT_PIN 49 + //#define LCD_SDSS SDSS + //#define SD_DETECT_PIN 49 #elif ANY(VIKI2, miniVIKI) // TO TEST - // #define DOGLCD_CS 45 - // #define DOGLCD_A0 44 - // #define LCD_SCREEN_ROT_180 + //#define DOGLCD_CS 45 + //#define DOGLCD_A0 44 + //#define LCD_SCREEN_ROT_180 - // #define BEEPER_PIN 33 - // #define STAT_LED_RED_PIN 32 - // #define STAT_LED_BLUE_PIN 35 + //#define BEEPER_PIN 33 + //#define STAT_LED_RED_PIN 32 + //#define STAT_LED_BLUE_PIN 35 - // #define BTN_EN1 22 - // #define BTN_EN2 7 - // #define BTN_ENC 39 + //#define BTN_EN1 22 + //#define BTN_EN2 7 + //#define BTN_ENC 39 - // #define SD_DETECT_PIN -1 // Pin 49 for display SD interface, 72 for easy adapter board - // #define KILL_PIN 31 + //#define SD_DETECT_PIN -1 // Pin 49 for display SD interface, 72 for easy adapter board + //#define KILL_PIN 31 #elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) // TO TEST - // #define DOGLCD_CS 29 - // #define DOGLCD_A0 27 + //#define DOGLCD_CS 29 + //#define DOGLCD_A0 27 - // #define BEEPER_PIN 23 - // #define LCD_BACKLIGHT_PIN 33 + //#define BEEPER_PIN 23 + //#define LCD_BACKLIGHT_PIN 33 - // #define BTN_EN1 35 - // #define BTN_EN2 37 - // #define BTN_ENC 31 + //#define BTN_EN1 35 + //#define BTN_EN2 37 + //#define BTN_ENC 31 - // #define LCD_SDSS SDSS - // #define SD_DETECT_PIN 49 - // #define KILL_PIN 41 + //#define LCD_SDSS SDSS + //#define SD_DETECT_PIN 49 + //#define KILL_PIN 41 #elif EITHER(MKS_MINI_12864, FYSETC_MINI_12864) // TO TEST - //#define BEEPER_PIN 37 - //#define BTN_ENC 35 - //#define SD_DETECT_PIN 49 + //#define BEEPER_PIN 37 + //#define BTN_ENC 35 + //#define SD_DETECT_PIN 49 //#ifndef KILL_PIN // #define KILL_PIN 41 //#endif - #if ENABLED(MKS_MINI_12864) // Added in Marlin 1.1.6 + #if ENABLED(MKS_MINI_12864) // TO TEST - // #define DOGLCD_A0 27 - // #define DOGLCD_CS 25 + //#define DOGLCD_A0 27 + //#define DOGLCD_CS 25 // GLCD features // Uncomment screen orientation - // #define LCD_SCREEN_ROT_90 - // #define LCD_SCREEN_ROT_180 - // #define LCD_SCREEN_ROT_270 + //#define LCD_SCREEN_ROT_90 + //#define LCD_SCREEN_ROT_180 + //#define LCD_SCREEN_ROT_270 // not connected to a pin - // #define LCD_BACKLIGHT_PIN 57 // backlight LED on A11/D? (Mega/Due:65 - AGCM4:57) + //#define LCD_BACKLIGHT_PIN 57 // backlight LED on A11/D? (Mega/Due:65 - AGCM4:57) - // #define BTN_EN1 31 - // #define BTN_EN2 33 + //#define BTN_EN1 31 + //#define BTN_EN2 33 #elif ENABLED(FYSETC_MINI_12864) // From https://wiki.fysetc.com/Mini12864_Panel/?fbclid=IwAR1FyjuNdVOOy9_xzky3qqo_WeM5h-4gpRnnWhQr_O1Ef3h0AFnFXmCehK8 // TO TEST - // #define DOGLCD_A0 16 - // #define DOGLCD_CS 17 + //#define DOGLCD_A0 16 + //#define DOGLCD_CS 17 - // #define BTN_EN1 33 - // #define BTN_EN2 31 + //#define BTN_EN1 33 + //#define BTN_EN2 31 - //#define FORCE_SOFT_SPI // Use this if default of hardware SPI causes display problems - // results in LCD soft SPI mode 3, SD soft SPI mode 0 + //#define FORCE_SOFT_SPI // Use this if default of hardware SPI causes display problems + // results in LCD soft SPI mode 3, SD soft SPI mode 0 - // #define LCD_RESET_PIN 23 // Must be high or open for LCD to operate normally. + //#define LCD_RESET_PIN 23 // Must be high or open for LCD to operate normally. #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) #ifndef RGB_LED_R_PIN // TO TEST - // #define RGB_LED_R_PIN 25 + //#define RGB_LED_R_PIN 25 #endif #ifndef RGB_LED_G_PIN // TO TEST - // #define RGB_LED_G_PIN 27 + //#define RGB_LED_G_PIN 27 #endif #ifndef RGB_LED_B_PIN // TO TEST - // #define RGB_LED_B_PIN 29 + //#define RGB_LED_B_PIN 29 #endif #elif ENABLED(FYSETC_MINI_12864_2_1) // TO TEST - // #define NEOPIXEL_PIN 25 + //#define NEOPIXEL_PIN 25 #endif #endif @@ -530,30 +530,30 @@ #elif ENABLED(MINIPANEL) // TO TEST - // #define BEEPER_PIN 42 + //#define BEEPER_PIN 42 // not connected to a pin - // #define LCD_BACKLIGHT_PIN 57 // backlight LED on A11/D? (Mega/Due:65 - AGCM4:57) + //#define LCD_BACKLIGHT_PIN 57 // backlight LED on A11/D? (Mega/Due:65 - AGCM4:57) - // #define DOGLCD_A0 44 - // #define DOGLCD_CS 58 // Mega/Due:66 - AGCM4:58 + //#define DOGLCD_A0 44 + //#define DOGLCD_CS 58 // Mega/Due:66 - AGCM4:58 // GLCD features // Uncomment screen orientation - // #define LCD_SCREEN_ROT_90 - // #define LCD_SCREEN_ROT_180 - // #define LCD_SCREEN_ROT_270 + //#define LCD_SCREEN_ROT_90 + //#define LCD_SCREEN_ROT_180 + //#define LCD_SCREEN_ROT_270 - // #define BTN_EN1 40 - // #define BTN_EN2 55 // Mega/Due:63 - AGCM4:55 - // #define BTN_ENC 72 // Mega/Due:59 - AGCM4:72 + //#define BTN_EN1 40 + //#define BTN_EN2 55 // Mega/Due:63 - AGCM4:55 + //#define BTN_ENC 72 // Mega/Due:59 - AGCM4:72 - // #define SD_DETECT_PIN 49 - // #define KILL_PIN 56 // Mega/Due:64 - AGCM4:56 + //#define SD_DETECT_PIN 49 + //#define KILL_PIN 56 // Mega/Due:64 - AGCM4:56 #elif ENABLED(ZONESTAR_LCD) // TO TEST - // #define ADC_KEYPAD_PIN 12 + //#define ADC_KEYPAD_PIN 12 #elif ENABLED(AZSMZ_12864) @@ -562,50 +562,50 @@ #else // Beeper on AUX-4 - // #define BEEPER_PIN 33 + //#define BEEPER_PIN 33 // Buttons are directly attached to AUX-2 #if ENABLED(REPRAPWORLD_KEYPAD) // TO TEST - // #define SHIFT_OUT 40 - // #define SHIFT_CLK 44 - // #define SHIFT_LD 42 - // #define BTN_EN1 56 // Mega/Due:64 - AGCM4:56 - // #define BTN_EN2 72 // Mega/Due:59 - AGCM4:72 - // #define BTN_ENC 55 // Mega/Due:63 - AGCM4:55 + //#define SHIFT_OUT 40 + //#define SHIFT_CLK 44 + //#define SHIFT_LD 42 + //#define BTN_EN1 56 // Mega/Due:64 - AGCM4:56 + //#define BTN_EN2 72 // Mega/Due:59 - AGCM4:72 + //#define BTN_ENC 55 // Mega/Due:63 - AGCM4:55 #elif ENABLED(PANEL_ONE) // TO TEST - // #define BTN_EN1 72 // AUX2 PIN 3 (Mega/Due:59 - AGCM4:72) - // #define BTN_EN2 55 // AUX2 PIN 4 (Mega/Due:63 - AGCM4:55) - // #define BTN_ENC 49 // AUX3 PIN 7 + //#define BTN_EN1 72 // AUX2 PIN 3 (Mega/Due:59 - AGCM4:72) + //#define BTN_EN2 55 // AUX2 PIN 4 (Mega/Due:63 - AGCM4:55) + //#define BTN_ENC 49 // AUX3 PIN 7 #else // TO TEST - // #define BTN_EN1 37 - // #define BTN_EN2 35 - // #define BTN_ENC 31 + //#define BTN_EN1 37 + //#define BTN_EN2 35 + //#define BTN_ENC 31 #endif #if ENABLED(G3D_PANEL) // TO TEST - // #define SD_DETECT_PIN 49 - // #define KILL_PIN 41 + //#define SD_DETECT_PIN 49 + //#define KILL_PIN 41 #endif #endif #endif // NEWPANEL -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD // // SD Support // #ifndef SDCARD_CONNECTION - #define SDCARD_CONNECTION ONBOARD + #define SDCARD_CONNECTION ONBOARD #endif #if SD_CONNECTION_IS(ONBOARD) #undef SDSS - #define SDSS 83 + #define SDSS 83 #undef SD_DETECT_PIN - #define SD_DETECT_PIN 95 + #define SD_DETECT_PIN 95 #endif diff --git a/Marlin/src/pins/sanguino/pins_ANET_10.h b/Marlin/src/pins/sanguino/pins_ANET_10.h index ebd050371231..74692a21a390 100644 --- a/Marlin/src/pins/sanguino/pins_ANET_10.h +++ b/Marlin/src/pins/sanguino/pins_ANET_10.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -30,7 +30,6 @@ * * 1) no longer uses Sanguino files to define some of the pins * 2) added pointers to useable Arduino IDE extensions - * */ /** @@ -48,7 +47,6 @@ * "Anet V1.0 (Optiboot)" frees up another 3K of FLASH. You'll need to burn * a new bootloader to the board to be able to automatically download a * compiled image. - * */ /** @@ -66,7 +64,6 @@ * Just use the above JSON URL instead of Sparkfun's JSON. * * Once installed select the Sanguino board and then select the CPU. - * */ /** @@ -82,14 +79,14 @@ * Additional info: * * Anet Schematics - https://github.com/ralf-e/ANET-3D-Board-V1.0 - * Wiring RRDFG Smart Controller - http://www.thingiverse.com/thing:2103748 + * Wiring RRDFG Smart Controller - https://www.thingiverse.com/thing:2103748 * SkyNet3D Anet software development - https://github.com/SkyNet3D/Marlin/ * Anet Users / Skynet SW on Facebook - https://www.facebook.com/skynet3ddevelopment/ * * Many thanks to Hans Raaf (@oderwat) for developing the Anet-specific software and supporting the Anet community. */ -#ifndef __AVR_ATmega1284P__ +#if NOT_TARGET(__AVR_ATmega1284P__) #error "Oops! Select 'Sanguino' in 'Tools > Board' and 'ATmega1284P' in 'Tools > Processor.' (For PlatformIO, use 'melzi' or 'melzi_optiboot.')" #endif @@ -98,50 +95,50 @@ // // Limit Switches // -#define X_STOP_PIN 18 -#define Y_STOP_PIN 19 -#define Z_STOP_PIN 20 +#define X_STOP_PIN 18 +#define Y_STOP_PIN 19 +#define Z_STOP_PIN 20 // // Steppers // -#define X_STEP_PIN 15 -#define X_DIR_PIN 21 -#define X_ENABLE_PIN 14 +#define X_STEP_PIN 15 +#define X_DIR_PIN 21 +#define X_ENABLE_PIN 14 -#define Y_STEP_PIN 22 -#define Y_DIR_PIN 23 -#define Y_ENABLE_PIN 14 +#define Y_STEP_PIN 22 +#define Y_DIR_PIN 23 +#define Y_ENABLE_PIN 14 -#define Z_STEP_PIN 3 -#define Z_DIR_PIN 2 -#define Z_ENABLE_PIN 26 +#define Z_STEP_PIN 3 +#define Z_DIR_PIN 2 +#define Z_ENABLE_PIN 26 -#define E0_STEP_PIN 1 -#define E0_DIR_PIN 0 -#define E0_ENABLE_PIN 14 +#define E0_STEP_PIN 1 +#define E0_DIR_PIN 0 +#define E0_ENABLE_PIN 14 // // Temperature Sensors // -#define TEMP_0_PIN 7 // Analog Input (pin 33 extruder) -#define TEMP_BED_PIN 6 // Analog Input (pin 34 bed) +#define TEMP_0_PIN 7 // Analog Input (pin 33 extruder) +#define TEMP_BED_PIN 6 // Analog Input (pin 34 bed) // // Heaters / Fans // -#define HEATER_0_PIN 13 // (extruder) -#define HEATER_BED_PIN 12 // (bed) +#define HEATER_0_PIN 13 // (extruder) +#define HEATER_BED_PIN 12 // (bed) #ifndef FAN_PIN - #define FAN_PIN 4 + #define FAN_PIN 4 #endif // // Misc. Functions // -#define SDSS 31 -#define LED_PIN -1 +#define SDSS 31 +#define LED_PIN -1 /** * LCD / Controller @@ -152,37 +149,37 @@ * REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER */ -#if HAS_SPI_LCD - #define LCD_SDSS 28 +#if HAS_WIRED_LCD + #define LCD_SDSS 28 #if ENABLED(ADC_KEYPAD) - #define SERVO0_PIN 27 // free for BLTouch/3D-Touch - #define LCD_PINS_RS 28 - #define LCD_PINS_ENABLE 29 - #define LCD_PINS_D4 10 - #define LCD_PINS_D5 11 - #define LCD_PINS_D6 16 - #define LCD_PINS_D7 17 - #define ADC_KEYPAD_PIN 1 - #elif EITHER(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER, ANET_FULL_GRAPHICS_LCD) + #define SERVO0_PIN 27 // free for BLTouch/3D-Touch + #define LCD_PINS_RS 28 + #define LCD_PINS_ENABLE 29 + #define LCD_PINS_D4 10 + #define LCD_PINS_D5 11 + #define LCD_PINS_D6 16 + #define LCD_PINS_D7 17 + #define ADC_KEYPAD_PIN 1 + #elif ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) // Pin definitions for the Anet A6 Full Graphics display and the RepRapDiscount Full Graphics // display using an adapter board // https://go.aisler.net/benlye/anet-lcd-adapter/pcb // See below for alternative pin definitions for use with https://www.thingiverse.com/thing:2103748 - #define SERVO0_PIN 29 // free for BLTouch/3D-Touch - #define BEEPER_PIN 17 - #define LCD_PINS_RS 27 - #define LCD_PINS_ENABLE 28 - #define LCD_PINS_D4 30 - #define BTN_EN1 11 - #define BTN_EN2 10 - #define BTN_ENC 16 + #define SERVO0_PIN 29 // free for BLTouch/3D-Touch + #define BEEPER_PIN 17 + #define LCD_PINS_RS 27 + #define LCD_PINS_ENABLE 28 + #define LCD_PINS_D4 30 + #define BTN_EN1 11 + #define BTN_EN2 10 + #define BTN_ENC 16 #define BOARD_ST7920_DELAY_1 DELAY_NS(0) #define BOARD_ST7920_DELAY_2 DELAY_NS(63) #define BOARD_ST7920_DELAY_3 DELAY_NS(125) - #define STD_ENCODER_PULSES_PER_STEP 4 - #define STD_ENCODER_STEPS_PER_MENU_ITEM 1 + #define STD_ENCODER_PULSES_PER_STEP 4 + #define STD_ENCODER_STEPS_PER_MENU_ITEM 1 #endif #else - #define SERVO0_PIN 27 + #define SERVO0_PIN 27 #endif /** @@ -209,7 +206,7 @@ * ==================================================================== * * Anet V1.0 controller | ZONESTAR_LCD | ANET_FULL_ | RepRapDiscount Full | Thingiverse RepRap wiring - * physical logical alt | | GRAPHICS_LCD | Graphics Display Wiring | http://www.thingiverse + * physical logical alt | | GRAPHICS_LCD | Graphics Display Wiring | https://www.thingiverse * pin pin functions | | | | .com/thing:2103748 *------------------------------------------------------------------------------------------------------------------------ * ANET-J3.1 8 *** | N/A | J3_TX *** | | diff --git a/Marlin/src/pins/sanguino/pins_AZTEEG_X1.h b/Marlin/src/pins/sanguino/pins_AZTEEG_X1.h index 4c991c5e9ef9..c3c38eb6f308 100644 --- a/Marlin/src/pins/sanguino/pins_AZTEEG_X1.h +++ b/Marlin/src/pins/sanguino/pins_AZTEEG_X1.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/pins/sanguino/pins_GEN3_MONOLITHIC.h b/Marlin/src/pins/sanguino/pins_GEN3_MONOLITHIC.h index 833f99fb7f8f..29905c108954 100644 --- a/Marlin/src/pins/sanguino/pins_GEN3_MONOLITHIC.h +++ b/Marlin/src/pins/sanguino/pins_GEN3_MONOLITHIC.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -29,7 +29,6 @@ * Rev B 26 DEC 2016 * * added pointer to a current Arduino IDE extension - * */ /** @@ -47,55 +46,54 @@ * Just use the above JSON URL instead of Sparkfun's JSON. * * Once installed select the Sanguino board and then select the CPU. - * */ -#ifndef __AVR_ATmega644P__ +#if NOT_TARGET(__AVR_ATmega644P__) #error "Oops! Select 'Sanguino' in 'Tools > Board.'" #endif #define BOARD_INFO_NAME "Gen3 Monolithic" -#define DEBUG_PIN 0 +#define DEBUG_PIN 0 // // Limit Switches // -#define X_STOP_PIN 20 -#define Y_STOP_PIN 25 -#define Z_STOP_PIN 30 +#define X_STOP_PIN 20 +#define Y_STOP_PIN 25 +#define Z_STOP_PIN 30 // // Steppers // -#define X_STEP_PIN 15 -#define X_DIR_PIN 18 -#define X_ENABLE_PIN 24 // actually uses Y_enable_pin +#define X_STEP_PIN 15 +#define X_DIR_PIN 18 +#define X_ENABLE_PIN 24 // actually uses Y_enable_pin -#define Y_STEP_PIN 23 -#define Y_DIR_PIN 22 -#define Y_ENABLE_PIN 24 // shared with X_enable_pin +#define Y_STEP_PIN 23 +#define Y_DIR_PIN 22 +#define Y_ENABLE_PIN 24 // shared with X_enable_pin -#define Z_STEP_PIN 27 -#define Z_DIR_PIN 28 -#define Z_ENABLE_PIN 29 +#define Z_STEP_PIN 27 +#define Z_DIR_PIN 28 +#define Z_ENABLE_PIN 29 -#define E0_STEP_PIN 12 -#define E0_DIR_PIN 17 -#define E0_ENABLE_PIN 3 +#define E0_STEP_PIN 12 +#define E0_DIR_PIN 17 +#define E0_ENABLE_PIN 3 // // Temperature Sensors // -#define TEMP_0_PIN 0 // Analog Input +#define TEMP_0_PIN 0 // Analog Input // // Heaters // -#define HEATER_0_PIN 16 +#define HEATER_0_PIN 16 // // Misc. Functions // -#define PS_ON_PIN 14 // Alex, does this work on the card? +#define PS_ON_PIN 14 // Alex, does this work on the card? // Alex extras from Gen3+ diff --git a/Marlin/src/pins/sanguino/pins_GEN3_PLUS.h b/Marlin/src/pins/sanguino/pins_GEN3_PLUS.h index c7c037fd4d46..33fc233f7ab1 100644 --- a/Marlin/src/pins/sanguino/pins_GEN3_PLUS.h +++ b/Marlin/src/pins/sanguino/pins_GEN3_PLUS.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -29,7 +29,6 @@ * Rev B 26 DEC 2016 * * added pointer to a current Arduino IDE extension - * */ /** @@ -47,11 +46,9 @@ * Just use the above JSON URL instead of Sparkfun's JSON. * * Once installed select the SANGUINO board and then select the CPU. - * */ - -#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega1284P__) +#if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega1284P__) #error "Oops! Select 'Sanguino' in 'Tools > Boards' and 'ATmega644P' or 'ATmega1284P' in 'Tools > Processor.'" #endif @@ -60,43 +57,43 @@ // // Limit Switches // -#define X_STOP_PIN 20 -#define Y_STOP_PIN 25 -#define Z_STOP_PIN 30 +#define X_STOP_PIN 20 +#define Y_STOP_PIN 25 +#define Z_STOP_PIN 30 // // Steppers // -#define X_STEP_PIN 15 -#define X_DIR_PIN 18 -#define X_ENABLE_PIN 19 +#define X_STEP_PIN 15 +#define X_DIR_PIN 18 +#define X_ENABLE_PIN 19 -#define Y_STEP_PIN 23 -#define Y_DIR_PIN 22 -#define Y_ENABLE_PIN 24 +#define Y_STEP_PIN 23 +#define Y_DIR_PIN 22 +#define Y_ENABLE_PIN 24 -#define Z_STEP_PIN 27 -#define Z_DIR_PIN 28 -#define Z_ENABLE_PIN 29 +#define Z_STEP_PIN 27 +#define Z_DIR_PIN 28 +#define Z_ENABLE_PIN 29 -#define E0_STEP_PIN 17 -#define E0_DIR_PIN 21 -#define E0_ENABLE_PIN 13 +#define E0_STEP_PIN 17 +#define E0_DIR_PIN 21 +#define E0_ENABLE_PIN 13 // // Temperature Sensors // -#define TEMP_0_PIN 0 // Analog Input (pin 33 extruder) -#define TEMP_BED_PIN 5 // Analog Input (pin 34 bed) +#define TEMP_0_PIN 0 // Analog Input (pin 33 extruder) +#define TEMP_BED_PIN 5 // Analog Input (pin 34 bed) // // Heaters // -#define HEATER_0_PIN 12 -#define HEATER_BED_PIN 16 +#define HEATER_0_PIN 12 +#define HEATER_BED_PIN 16 // // Misc. Functions // -#define SDSS 4 -#define PS_ON_PIN 14 +#define SDSS 4 +#define PS_ON_PIN 14 diff --git a/Marlin/src/pins/sanguino/pins_GEN6.h b/Marlin/src/pins/sanguino/pins_GEN6.h index d1b8391bcdf7..bfca8e90d9cc 100644 --- a/Marlin/src/pins/sanguino/pins_GEN6.h +++ b/Marlin/src/pins/sanguino/pins_GEN6.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -31,7 +31,6 @@ * 1) added pointer to a current Arduino IDE extension * 2) added support for M3, M4 & M5 spindle control commands * 3) added case light pin definition - * */ /** @@ -49,10 +48,9 @@ * Just use the above JSON URL instead of Sparkfun's JSON. * * Once installed select the Sanguino board and then select the CPU. - * */ -#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega1284P__) +#if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega1284P__) #error "Oops! Select 'Sanguino' in 'Tools > Boards' and 'ATmega644P' or 'ATmega1284P' in 'Tools > Processor.'" #endif @@ -63,58 +61,61 @@ // // Limit Switches // -#define X_STOP_PIN 20 -#define Y_STOP_PIN 25 -#define Z_STOP_PIN 30 +#define X_STOP_PIN 20 +#define Y_STOP_PIN 25 +#define Z_STOP_PIN 30 // // Steppers // -#define X_STEP_PIN 15 -#define X_DIR_PIN 18 -#define X_ENABLE_PIN 19 +#define X_STEP_PIN 15 +#define X_DIR_PIN 18 +#define X_ENABLE_PIN 19 -#define Y_STEP_PIN 23 -#define Y_DIR_PIN 22 -#define Y_ENABLE_PIN 24 +#define Y_STEP_PIN 23 +#define Y_DIR_PIN 22 +#define Y_ENABLE_PIN 24 -#define Z_STEP_PIN 27 -#define Z_DIR_PIN 28 -#define Z_ENABLE_PIN 29 +#define Z_STEP_PIN 27 +#define Z_DIR_PIN 28 +#define Z_ENABLE_PIN 29 -#define E0_STEP_PIN 4 // Edited @ EJE Electronics 20100715 -#define E0_DIR_PIN 2 // Edited @ EJE Electronics 20100715 -#define E0_ENABLE_PIN 3 // Added @ EJE Electronics 20100715 +#define E0_STEP_PIN 4 // Edited @ EJE Electronics 20100715 +#define E0_DIR_PIN 2 // Edited @ EJE Electronics 20100715 +#define E0_ENABLE_PIN 3 // Added @ EJE Electronics 20100715 // // Temperature Sensor // -#define TEMP_0_PIN 5 // Analog Input +#define TEMP_0_PIN 5 // Analog Input // // Heaters // -#define HEATER_0_PIN 14 // changed @ rkoeppl 20110410 +#define HEATER_0_PIN 14 // changed @ rkoeppl 20110410 #if !MB(GEN6) - #define HEATER_BED_PIN 1 // changed @ rkoeppl 20110410 - #define TEMP_BED_PIN 0 // Analog Input + #define HEATER_BED_PIN 1 // changed @ rkoeppl 20110410 + #define TEMP_BED_PIN 0 // Analog Input #endif // // Misc. Functions // -#define SDSS 17 -#define DEBUG_PIN 0 -#define CASE_LIGHT_PIN 16 // Hardware PWM +#define SDSS 17 +#define DEBUG_PIN 0 + +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN 16 // Hardware PWM +#endif // RS485 pins -#define TX_ENABLE_PIN 12 -#define RX_ENABLE_PIN 13 +#define TX_ENABLE_PIN 12 +#define RX_ENABLE_PIN 13 // // M3/M4/M5 - Spindle/Laser Control // -#define SPINDLE_LASER_ENA_PIN 5 // Pullup or pulldown! -#define SPINDLE_LASER_PWM_PIN 16 // Hardware PWM -#define SPINDLE_DIR_PIN 6 +#define SPINDLE_LASER_ENA_PIN 5 // Pullup or pulldown! +#define SPINDLE_LASER_PWM_PIN 16 // Hardware PWM +#define SPINDLE_DIR_PIN 6 diff --git a/Marlin/src/pins/sanguino/pins_GEN6_DELUXE.h b/Marlin/src/pins/sanguino/pins_GEN6_DELUXE.h index 14e1c67b6fe8..9c635706202c 100644 --- a/Marlin/src/pins/sanguino/pins_GEN6_DELUXE.h +++ b/Marlin/src/pins/sanguino/pins_GEN6_DELUXE.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -29,7 +29,6 @@ * Rev B 26 DEC 2016 * * added pointer to a current Arduino IDE extension - * */ /** @@ -47,7 +46,6 @@ * Just use the above JSON URL instead of Sparkfun's JSON. * * Once installed select the SANGUINO board and then select the CPU. - * */ diff --git a/Marlin/src/pins/sanguino/pins_GEN7_12.h b/Marlin/src/pins/sanguino/pins_GEN7_12.h index 4ab53faa98c4..9db7d7214a5b 100644 --- a/Marlin/src/pins/sanguino/pins_GEN7_12.h +++ b/Marlin/src/pins/sanguino/pins_GEN7_12.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -31,7 +31,6 @@ * 1) added pointer to a current Arduino IDE extension * 2) added support for M3, M4 & M5 spindle control commands * 3) added case light pin definition - * */ /** @@ -49,10 +48,9 @@ * Just use the above JSON URL instead of Sparkfun's JSON. * * Once installed select the Sanguino board and then select the CPU. - * */ -#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega644__) && !defined(__AVR_ATmega1284P__) +#if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega644__, __AVR_ATmega1284P__) #error "Oops! Select 'Sanguino' in 'Tools > Boards' and 'ATmega644', 'ATmega644P', or 'ATmega1284P' in 'Tools > Processor.'" #endif @@ -61,90 +59,89 @@ #endif #ifndef GEN7_VERSION - #define GEN7_VERSION 12 // v1.x + #define GEN7_VERSION 12 // v1.x #endif // // Limit Switches // -#define X_MIN_PIN 7 -#define Y_MIN_PIN 5 -#define Z_MIN_PIN 1 -#define Z_MAX_PIN 0 -#define Y_MAX_PIN 2 -#define X_MAX_PIN 6 - +#define X_MIN_PIN 7 +#define Y_MIN_PIN 5 +#define Z_MIN_PIN 1 +#define Z_MAX_PIN 0 +#define Y_MAX_PIN 2 +#define X_MAX_PIN 6 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 0 + #define Z_MIN_PROBE_PIN 0 #endif // // Steppers // -#define X_STEP_PIN 19 -#define X_DIR_PIN 18 -#define X_ENABLE_PIN 24 +#define X_STEP_PIN 19 +#define X_DIR_PIN 18 +#define X_ENABLE_PIN 24 -#define Y_STEP_PIN 23 -#define Y_DIR_PIN 22 -#define Y_ENABLE_PIN 24 +#define Y_STEP_PIN 23 +#define Y_DIR_PIN 22 +#define Y_ENABLE_PIN 24 -#define Z_STEP_PIN 26 -#define Z_DIR_PIN 25 -#define Z_ENABLE_PIN 24 +#define Z_STEP_PIN 26 +#define Z_DIR_PIN 25 +#define Z_ENABLE_PIN 24 -#define E0_STEP_PIN 28 -#define E0_DIR_PIN 27 -#define E0_ENABLE_PIN 24 +#define E0_STEP_PIN 28 +#define E0_DIR_PIN 27 +#define E0_ENABLE_PIN 24 // // Temperature Sensors // -#define TEMP_0_PIN 1 // Analog Input -#define TEMP_BED_PIN 2 // Analog Input +#define TEMP_0_PIN 1 // Analog Input +#define TEMP_BED_PIN 2 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 4 -#define HEATER_BED_PIN 3 +#define HEATER_0_PIN 4 +#define HEATER_BED_PIN 3 -#if !defined(FAN_PIN) && GEN7_VERSION < 13 // Gen7 v1.3 removed the fan pin - #define FAN_PIN 31 +#if !defined(FAN_PIN) && GEN7_VERSION < 13 // Gen7 v1.3 removed the fan pin + #define FAN_PIN 31 #endif // // Misc. Functions // -#define PS_ON_PIN 15 +#define PS_ON_PIN 15 #if GEN7_VERSION < 13 - #define CASE_LIGHT_PIN 16 // Hardware PWM -#else // Gen7 v1.3 removed the I2C connector & signals so need to get PWM off the PC power supply header - #define CASE_LIGHT_PIN 15 // Hardware PWM + #define CASE_LIGHT_PIN 16 // Hardware PWM +#else // Gen7 v1.3 removed the I2C connector & signals so need to get PWM off the PC power supply header + #define CASE_LIGHT_PIN 15 // Hardware PWM #endif // All these generations of Gen7 supply thermistor power // via PS_ON, so ignore bad thermistor readings -//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 +//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 -#define DEBUG_PIN 0 +#define DEBUG_PIN 0 // RS485 pins -#define TX_ENABLE_PIN 12 -#define RX_ENABLE_PIN 13 +#define TX_ENABLE_PIN 12 +#define RX_ENABLE_PIN 13 // // M3/M4/M5 - Spindle/Laser Control // -#define SPINDLE_LASER_ENA_PIN 10 // Pullup or pulldown! -#define SPINDLE_DIR_PIN 11 +#define SPINDLE_LASER_ENA_PIN 10 // Pullup or pulldown! +#define SPINDLE_DIR_PIN 11 #if GEN7_VERSION < 13 - #define SPINDLE_LASER_PWM_PIN 16 // Hardware PWM -#else // Gen7 v1.3 removed the I2C connector & signals so need to get PWM off the PC power supply header - #define SPINDLE_LASER_PWM_PIN 15 // Hardware PWM + #define SPINDLE_LASER_PWM_PIN 16 // Hardware PWM +#else // Gen7 v1.3 removed the I2C connector & signals so need to get PWM off the PC power supply header + #define SPINDLE_LASER_PWM_PIN 15 // Hardware PWM #endif diff --git a/Marlin/src/pins/sanguino/pins_GEN7_13.h b/Marlin/src/pins/sanguino/pins_GEN7_13.h index 728dfd8a5ce4..55881aaff58e 100644 --- a/Marlin/src/pins/sanguino/pins_GEN7_13.h +++ b/Marlin/src/pins/sanguino/pins_GEN7_13.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -29,7 +29,6 @@ * Rev B 26 DEC 2016 * * added pointer to a current Arduino IDE extension - * */ /** @@ -47,7 +46,6 @@ * Just use the above JSON URL instead of Sparkfun's JSON. * * Once installed select the Sanguino board and then select the CPU. - * */ #define BOARD_INFO_NAME "Gen7 v1.3" diff --git a/Marlin/src/pins/sanguino/pins_GEN7_14.h b/Marlin/src/pins/sanguino/pins_GEN7_14.h index 5121b7d2e98c..66dba533e988 100644 --- a/Marlin/src/pins/sanguino/pins_GEN7_14.h +++ b/Marlin/src/pins/sanguino/pins_GEN7_14.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -31,7 +31,6 @@ * 1) added pointer to a current Arduino IDE extension * 2) added support for M3, M4 & M5 spindle control commands * 3) added case light pin definition - * */ /** @@ -49,71 +48,73 @@ * Just use the above JSON URL instead of Sparkfun's JSON. * * Once installed select the Sanguino board and then select the CPU. - * */ -#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega644__) && !defined(__AVR_ATmega1284P__) +#if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega644__, __AVR_ATmega1284P__) #error "Oops! Select 'Sanguino' in 'Tools > Boards' and 'ATmega644', 'ATmega644P', or 'ATmega1284P' in 'Tools > Processor.'" #endif #define BOARD_INFO_NAME "Gen7 v1.4" -#define GEN7_VERSION 14 // v1.4 +#define GEN7_VERSION 14 // v1.4 // // Limit switches // -#define X_STOP_PIN 0 -#define Y_STOP_PIN 1 -#define Z_STOP_PIN 2 +#define X_STOP_PIN 0 +#define Y_STOP_PIN 1 +#define Z_STOP_PIN 2 // // Steppers // -#define X_STEP_PIN 29 -#define X_DIR_PIN 28 -#define X_ENABLE_PIN 25 +#define X_STEP_PIN 29 +#define X_DIR_PIN 28 +#define X_ENABLE_PIN 25 -#define Y_STEP_PIN 27 -#define Y_DIR_PIN 26 -#define Y_ENABLE_PIN 25 +#define Y_STEP_PIN 27 +#define Y_DIR_PIN 26 +#define Y_ENABLE_PIN 25 -#define Z_STEP_PIN 23 -#define Z_DIR_PIN 22 -#define Z_ENABLE_PIN 25 +#define Z_STEP_PIN 23 +#define Z_DIR_PIN 22 +#define Z_ENABLE_PIN 25 -#define E0_STEP_PIN 19 -#define E0_DIR_PIN 18 -#define E0_ENABLE_PIN 25 +#define E0_STEP_PIN 19 +#define E0_DIR_PIN 18 +#define E0_ENABLE_PIN 25 // // Temperature Sensors // -#define TEMP_0_PIN 1 // Analog Input -#define TEMP_BED_PIN 0 // Analog Input +#define TEMP_0_PIN 1 // Analog Input +#define TEMP_BED_PIN 0 // Analog Input // // Heaters // -#define HEATER_0_PIN 4 -#define HEATER_BED_PIN 3 +#define HEATER_0_PIN 4 +#define HEATER_BED_PIN 3 // // Misc. Functions // -#define PS_ON_PIN 15 -#define CASE_LIGHT_PIN 15 // Hardware PWM +#define PS_ON_PIN 15 + +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN 15 // Hardware PWM +#endif // A pin for debugging -#define DEBUG_PIN 0 +#define DEBUG_PIN 0 // RS485 pins -#define TX_ENABLE_PIN 12 -#define RX_ENABLE_PIN 13 +#define TX_ENABLE_PIN 12 +#define RX_ENABLE_PIN 13 // // M3/M4/M5 - Spindle/Laser Control // -#define SPINDLE_LASER_ENA_PIN 20 // Pullup or pulldown! -#define SPINDLE_LASER_PWM_PIN 16 // Hardware PWM -#define SPINDLE_DIR_PIN 21 +#define SPINDLE_LASER_ENA_PIN 20 // Pullup or pulldown! +#define SPINDLE_LASER_PWM_PIN 16 // Hardware PWM +#define SPINDLE_DIR_PIN 21 diff --git a/Marlin/src/pins/sanguino/pins_GEN7_CUSTOM.h b/Marlin/src/pins/sanguino/pins_GEN7_CUSTOM.h index 0f8a92f08dea..0c4871fb27d5 100644 --- a/Marlin/src/pins/sanguino/pins_GEN7_CUSTOM.h +++ b/Marlin/src/pins/sanguino/pins_GEN7_CUSTOM.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -34,7 +34,6 @@ * 1) added pointer to a current Arduino IDE extension * 2) added support for M3, M4 & M5 spindle control commands * 3) added case light pin definition - * */ /** @@ -52,10 +51,9 @@ * Just use the above JSON URL instead of Sparkfun's JSON. * * Once installed select the Sanguino board and then select the CPU. - * */ -#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega644__) && !defined(__AVR_ATmega1284P__) +#if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega644__, __AVR_ATmega1284P__) #error "Oops! Select 'Sanguino' in 'Tools > Boards' and 'ATmega644', 'ATmega644P', or 'ATmega1284P' in 'Tools > Processor.'" #endif @@ -64,76 +62,79 @@ // // Limit Switches // -#define X_STOP_PIN 0 -#define Y_STOP_PIN 1 -#define Z_STOP_PIN 2 +#define X_STOP_PIN 0 +#define Y_STOP_PIN 1 +#define Z_STOP_PIN 2 // // Steppers // -#define X_STEP_PIN 21 // different from standard GEN7 -#define X_DIR_PIN 20 // different from standard GEN7 -#define X_ENABLE_PIN 24 +#define X_STEP_PIN 21 // different from standard GEN7 +#define X_DIR_PIN 20 // different from standard GEN7 +#define X_ENABLE_PIN 24 -#define Y_STEP_PIN 23 -#define Y_DIR_PIN 22 -#define Y_ENABLE_PIN 24 +#define Y_STEP_PIN 23 +#define Y_DIR_PIN 22 +#define Y_ENABLE_PIN 24 -#define Z_STEP_PIN 26 -#define Z_DIR_PIN 25 -#define Z_ENABLE_PIN 24 +#define Z_STEP_PIN 26 +#define Z_DIR_PIN 25 +#define Z_ENABLE_PIN 24 -#define E0_STEP_PIN 28 -#define E0_DIR_PIN 27 -#define E0_ENABLE_PIN 24 +#define E0_STEP_PIN 28 +#define E0_DIR_PIN 27 +#define E0_ENABLE_PIN 24 // // Temperature Sensors // -#define TEMP_0_PIN 2 // Analog Input -#define TEMP_BED_PIN 1 // Analog Input (pin 34 bed) +#define TEMP_0_PIN 2 // Analog Input +#define TEMP_BED_PIN 1 // Analog Input (pin 34 bed) // // Heaters // -#define HEATER_0_PIN 4 -#define HEATER_BED_PIN 3 // (bed) +#define HEATER_0_PIN 4 +#define HEATER_BED_PIN 3 // (bed) // // Misc. Functions // -#define SDSS 31 // SCL pin of I2C header || CS Pin for SD Card support -#define PS_ON_PIN 19 -#define CASE_LIGHT_PIN 15 // Hardware PWM +#define SDSS 31 // SCL pin of I2C header || CS Pin for SD Card support +#define PS_ON_PIN 19 + +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN 15 // Hardware PWM +#endif // A pin for debugging -#define DEBUG_PIN -1 +#define DEBUG_PIN -1 // // LCD / Controller // -#define BEEPER_PIN -1 +#define BEEPER_PIN -1 // 4bit LCD Support -#define LCD_PINS_RS 18 -#define LCD_PINS_ENABLE 17 -#define LCD_PINS_D4 16 -#define LCD_PINS_D5 15 -#define LCD_PINS_D6 13 -#define LCD_PINS_D7 14 +#define LCD_PINS_RS 18 +#define LCD_PINS_ENABLE 17 +#define LCD_PINS_D4 16 +#define LCD_PINS_D5 15 +#define LCD_PINS_D6 13 +#define LCD_PINS_D7 14 // Buttons are directly attached -#define BTN_EN1 11 -#define BTN_EN2 10 -#define BTN_ENC 12 +#define BTN_EN1 11 +#define BTN_EN2 10 +#define BTN_ENC 12 // RS485 pins -//#define TX_ENABLE_PIN 12 -//#define RX_ENABLE_PIN 13 +//#define TX_ENABLE_PIN 12 +//#define RX_ENABLE_PIN 13 // // M3/M4/M5 - Spindle/Laser Control // -#define SPINDLE_LASER_ENA_PIN 5 // Pullup or pulldown! -#define SPINDLE_LASER_PWM_PIN 16 // Hardware PWM -#define SPINDLE_DIR_PIN 6 +#define SPINDLE_LASER_ENA_PIN 5 // Pullup or pulldown! +#define SPINDLE_LASER_PWM_PIN 16 // Hardware PWM +#define SPINDLE_DIR_PIN 6 diff --git a/Marlin/src/pins/sanguino/pins_MELZI.h b/Marlin/src/pins/sanguino/pins_MELZI.h index b73c1150de9e..887aae18584a 100644 --- a/Marlin/src/pins/sanguino/pins_MELZI.h +++ b/Marlin/src/pins/sanguino/pins_MELZI.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/pins/sanguino/pins_MELZI_CREALITY.h b/Marlin/src/pins/sanguino/pins_MELZI_CREALITY.h index 958ea78da4b5..9f406c1f7856 100644 --- a/Marlin/src/pins/sanguino/pins_MELZI_CREALITY.h +++ b/Marlin/src/pins/sanguino/pins_MELZI_CREALITY.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -28,11 +28,26 @@ * If you don't have a chip programmer you can use a spare Arduino plus a few * electronic components to write the bootloader. * - * See http://www.instructables.com/id/Burn-Arduino-Bootloader-with-Arduino-MEGA/ + * See https://www.instructables.com/id/Burn-Arduino-Bootloader-with-Arduino-MEGA/ + * + * Schematic: https://bit.ly/2XOnsWb */ #define BOARD_INFO_NAME "Melzi (Creality)" +// Alter timing for graphical display +#if HAS_MARLINUI_U8GLIB + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(125) + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(125) + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(125) + #endif +#endif + #include "pins_MELZI.h" // @@ -46,28 +61,27 @@ #undef LCD_PINS_D5 #undef LCD_PINS_D6 #undef LCD_PINS_D7 -#undef FIL_RUNOUT_PIN // Uses Beeper/LED Pin Pulled to GND -#define LCD_SDSS 31 // Smart Controller SD card reader (rather than the Melzi) -#define LCD_PINS_RS 28 // ST9720 CS -#define LCD_PINS_ENABLE 17 // ST9720 DAT -#define LCD_PINS_D4 30 // ST9720 CLK +#define LCD_SDSS 31 // Smart Controller SD card reader (rather than the Melzi) +#define LCD_PINS_RS 28 // ST9720 CS +#define LCD_PINS_ENABLE 17 // ST9720 DAT +#define LCD_PINS_D4 30 // ST9720 CLK #if ENABLED(BLTOUCH) - #define SERVO0_PIN 27 + #define SERVO0_PIN 27 #undef BEEPER_PIN -#endif - -// Alter timing for graphical display -#if HAS_GRAPHICAL_LCD - #define BOARD_ST7920_DELAY_1 DELAY_NS(125) - #define BOARD_ST7920_DELAY_2 DELAY_NS(125) - #define BOARD_ST7920_DELAY_3 DELAY_NS(125) +#elif ENABLED(FILAMENT_RUNOUT_SENSOR) + #ifndef FIL_RUNOUT_PIN + #define FIL_RUNOUT_PIN 27 + #endif + #if FIL_RUNOUT_PIN == BEEPER_PIN + #undef BEEPER_PIN + #endif #endif #if ENABLED(MINIPANEL) #undef DOGLCD_CS - #define DOGLCD_CS LCD_PINS_RS + #define DOGLCD_CS LCD_PINS_RS #endif /** @@ -116,3 +130,14 @@ PIN: 30 Port: A1 LCD_PINS_D4 Output = 1 PIN: 31 Port: A0 SDSS Output = 1 */ + +/** + * EXP1 Connector EXP1 as CR10 STOCKDISPLAY + * _____ _____ + * PA4 | 6 5 | PC0 BEEPER_PIN | 6 5 | BTN_ENC + * PD3 | 7 4 | RESET BTN_EN1 | 7 4 | RESET + * PD2 8 3 | PA1 BTN_EN2 8 3 | LCD_PINS_D4 (ST9720 CLK) + * PA3 | 9 2 | PC1 (ST9720 CS) LCD_PINS_RS | 9 2 | LCD_PINS_ENABLE (ST9720 DAT) + * GND |10 1 | 5V GND |10 1 | 5V + * ----- ----- + */ diff --git a/Marlin/src/pins/sanguino/pins_MELZI_MAKR3D.h b/Marlin/src/pins/sanguino/pins_MELZI_MAKR3D.h index 59baa2d6dd9b..0e09c1f00558 100644 --- a/Marlin/src/pins/sanguino/pins_MELZI_MAKR3D.h +++ b/Marlin/src/pins/sanguino/pins_MELZI_MAKR3D.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/pins/sanguino/pins_MELZI_MALYAN.h b/Marlin/src/pins/sanguino/pins_MELZI_MALYAN.h index bf0e34a9ec8d..5014620c6b81 100644 --- a/Marlin/src/pins/sanguino/pins_MELZI_MALYAN.h +++ b/Marlin/src/pins/sanguino/pins_MELZI_MALYAN.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -26,6 +26,20 @@ */ #define BOARD_INFO_NAME "Melzi (Malyan)" + +// Alter timing for graphical display +#if HAS_MARLINUI_U8GLIB + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(125) + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(125) + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(125) + #endif +#endif + #include "pins_MELZI.h" #undef LCD_SDSS @@ -36,16 +50,9 @@ #undef BTN_EN2 #undef BTN_ENC -#define LCD_PINS_RS 17 // ST9720 CS -#define LCD_PINS_ENABLE 16 // ST9720 DAT -#define LCD_PINS_D4 11 // ST9720 CLK -#define BTN_EN1 30 -#define BTN_EN2 29 -#define BTN_ENC 28 - -// Alter timing for graphical display -#if HAS_GRAPHICAL_LCD - #define BOARD_ST7920_DELAY_1 DELAY_NS(125) - #define BOARD_ST7920_DELAY_2 DELAY_NS(125) - #define BOARD_ST7920_DELAY_3 DELAY_NS(125) -#endif +#define LCD_PINS_RS 17 // ST9720 CS +#define LCD_PINS_ENABLE 16 // ST9720 DAT +#define LCD_PINS_D4 11 // ST9720 CLK +#define BTN_EN1 30 +#define BTN_EN2 29 +#define BTN_ENC 28 diff --git a/Marlin/src/pins/sanguino/pins_MELZI_TRONXY.h b/Marlin/src/pins/sanguino/pins_MELZI_TRONXY.h index 50433f6244db..f87894103771 100644 --- a/Marlin/src/pins/sanguino/pins_MELZI_TRONXY.h +++ b/Marlin/src/pins/sanguino/pins_MELZI_TRONXY.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -26,6 +26,19 @@ */ #define BOARD_INFO_NAME "Melzi (Tronxy)" + +#if HAS_MARLINUI_U8GLIB + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(0) + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(125) + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(0) + #endif +#endif + #include "pins_MELZI.h" #undef Z_ENABLE_PIN @@ -40,19 +53,13 @@ #undef BTN_ENC #undef LCD_SDSS -#define Z_ENABLE_PIN 14 -#define LCD_PINS_RS 30 -#define LCD_PINS_ENABLE 28 -#define LCD_PINS_D4 16 -#define LCD_PINS_D5 17 -#define LCD_PINS_D6 27 -#define LCD_PINS_D7 29 -#define BTN_EN1 10 -#define BTN_EN2 11 -#define BTN_ENC 26 - -#if HAS_GRAPHICAL_LCD - #define BOARD_ST7920_DELAY_1 DELAY_NS(0) - #define BOARD_ST7920_DELAY_2 DELAY_NS(125) - #define BOARD_ST7920_DELAY_3 DELAY_NS(0) -#endif +#define Z_ENABLE_PIN 14 +#define LCD_PINS_RS 30 +#define LCD_PINS_ENABLE 28 +#define LCD_PINS_D4 16 +#define LCD_PINS_D5 17 +#define LCD_PINS_D6 27 +#define LCD_PINS_D7 29 +#define BTN_EN1 10 +#define BTN_EN2 11 +#define BTN_ENC 26 diff --git a/Marlin/src/pins/sanguino/pins_MELZI_V2.h b/Marlin/src/pins/sanguino/pins_MELZI_V2.h new file mode 100644 index 000000000000..275498d55813 --- /dev/null +++ b/Marlin/src/pins/sanguino/pins_MELZI_V2.h @@ -0,0 +1,39 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * Melzi V2.0 as found at https://www.reprap.org/wiki/Melzi + */ + +#define BOARD_INFO_NAME "Melzi V2" + +#if HAS_MARLINUI_U8GLIB + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(0) + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(188) + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(0) + #endif +#endif + +#include "pins_MELZI.h" diff --git a/Marlin/src/pins/sanguino/pins_OMCA.h b/Marlin/src/pins/sanguino/pins_OMCA.h index c2ba1ed7073b..7f18283d1c54 100644 --- a/Marlin/src/pins/sanguino/pins_OMCA.h +++ b/Marlin/src/pins/sanguino/pins_OMCA.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -49,14 +49,13 @@ * PWM (D 14) PD6 20| |21 PD7 (D 15) PWM * +--------+ * - * REF http://sanguino.cc/hardware + * REF http://sanguino.wikidot.com/hardware */ /** * Rev B 26 DEC 2016 * * added pointer to a current Arduino IDE extension - * */ /** @@ -70,14 +69,13 @@ * * When installing select 1.0.2 * - * Installation instructions can be found at https://learn.sparkfun.com/pages/CustomBoardsArduino + * Installation instructions can be found at http://learn.sparkfun.com/pages/CustomBoardsArduino * Just use the above JSON URL instead of Sparkfun's JSON. * * Once installed select the Sanguino board and then select the CPU. - * */ -#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega644__) +#if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega644__) #error "Oops! Select 'Sanguino' in 'Tools > Board' and 'ATmega644' or 'ATmega644P' in 'Tools > Processor.'" #endif @@ -86,66 +84,66 @@ // // Limit Switches // -#define X_STOP_PIN 0 -#define Y_STOP_PIN 1 -#define Z_STOP_PIN 2 +#define X_STOP_PIN 0 +#define Y_STOP_PIN 1 +#define Z_STOP_PIN 2 // // Steppers // -#define X_STEP_PIN 26 -#define X_DIR_PIN 25 -#define X_ENABLE_PIN 10 +#define X_STEP_PIN 26 +#define X_DIR_PIN 25 +#define X_ENABLE_PIN 10 -#define Y_STEP_PIN 28 -#define Y_DIR_PIN 27 -#define Y_ENABLE_PIN 10 +#define Y_STEP_PIN 28 +#define Y_DIR_PIN 27 +#define Y_ENABLE_PIN 10 -#define Z_STEP_PIN 23 -#define Z_DIR_PIN 22 -#define Z_ENABLE_PIN 10 +#define Z_STEP_PIN 23 +#define Z_DIR_PIN 22 +#define Z_ENABLE_PIN 10 -#define E0_STEP_PIN 24 -#define E0_DIR_PIN 21 -#define E0_ENABLE_PIN 10 +#define E0_STEP_PIN 24 +#define E0_DIR_PIN 21 +#define E0_ENABLE_PIN 10 -#define E1_STEP_PIN -1 // 21 -#define E1_DIR_PIN -1 // 20 -#define E1_ENABLE_PIN -1 // 19 +#define E1_STEP_PIN -1 // 21 +#define E1_DIR_PIN -1 // 20 +#define E1_ENABLE_PIN -1 // 19 -#define E2_STEP_PIN -1 // 21 -#define E2_DIR_PIN -1 // 20 -#define E2_ENABLE_PIN -1 // 18 +#define E2_STEP_PIN -1 // 21 +#define E2_DIR_PIN -1 // 20 +#define E2_ENABLE_PIN -1 // 18 // // Temperature Sensors // -#define TEMP_0_PIN 0 // Analog Input -#define TEMP_1_PIN 1 // Analog Input -#define TEMP_BED_PIN 2 // Analog Input (1,2 or I2C) +#define TEMP_0_PIN 0 // Analog Input +#define TEMP_1_PIN 1 // Analog Input +#define TEMP_BED_PIN 2 // Analog Input (1,2 or I2C) // // Heaters / Fans // -#define HEATER_0_PIN 3 // DONE PWM on RIGHT connector -#define HEATER_BED_PIN 4 +#define HEATER_0_PIN 3 // DONE PWM on RIGHT connector +#define HEATER_BED_PIN 4 #ifndef FAN_PIN - #define FAN_PIN 14 // PWM on MIDDLE connector + #define FAN_PIN 14 // PWM on MIDDLE connector #endif // // Misc. Functions // -#define SDSS 11 +#define SDSS 11 -#define I2C_SCL_PIN 16 -#define I2C_SDA_PIN 17 +#define I2C_SCL_PIN 16 +#define I2C_SDA_PIN 17 // future proofing -#define __FS 20 -#define __FD 19 -#define __GS 18 -#define __GD 13 +#define __FS 20 +#define __FD 19 +#define __GS 18 +#define __GD 13 -#define UNUSED_PWM 14 // PWM on LEFT connector +#define UNUSED_PWM 14 // PWM on LEFT connector diff --git a/Marlin/src/pins/sanguino/pins_OMCA_A.h b/Marlin/src/pins/sanguino/pins_OMCA_A.h index b8340a3debd8..770732051900 100644 --- a/Marlin/src/pins/sanguino/pins_OMCA_A.h +++ b/Marlin/src/pins/sanguino/pins_OMCA_A.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -48,14 +48,12 @@ * PWM (D 13) PD5 19| |22 PC0 (D 16) SCL * PWM (D 14) PD6 20| |21 PD7 (D 15) PWM * +--------+ - * */ /** * Rev B 26 DEC 2016 * * added pointer to a current Arduino IDE extension - * */ /** @@ -73,10 +71,9 @@ * Just use the above JSON URL instead of Sparkfun's JSON. * * Once installed select the Sanguino board and then select the CPU. - * */ -#ifndef __AVR_ATmega644__ +#if NOT_TARGET(__AVR_ATmega644__) #error "Oops! Select 'Sanguino' in 'Tools > Board' and ATmega644 in 'Tools > Processor.'" #endif @@ -85,54 +82,54 @@ // // Limit Switches // -#define X_STOP_PIN 0 -#define Y_STOP_PIN 1 -#define Z_STOP_PIN 2 +#define X_STOP_PIN 0 +#define Y_STOP_PIN 1 +#define Z_STOP_PIN 2 // // Steppers // -#define X_STEP_PIN 21 -#define X_DIR_PIN 20 -#define X_ENABLE_PIN 24 +#define X_STEP_PIN 21 +#define X_DIR_PIN 20 +#define X_ENABLE_PIN 24 -#define Y_STEP_PIN 23 -#define Y_DIR_PIN 22 -#define Y_ENABLE_PIN 24 +#define Y_STEP_PIN 23 +#define Y_DIR_PIN 22 +#define Y_ENABLE_PIN 24 -#define Z_STEP_PIN 26 -#define Z_DIR_PIN 25 -#define Z_ENABLE_PIN 24 +#define Z_STEP_PIN 26 +#define Z_DIR_PIN 25 +#define Z_ENABLE_PIN 24 -#define E0_STEP_PIN 28 -#define E0_DIR_PIN 27 -#define E0_ENABLE_PIN 24 +#define E0_STEP_PIN 28 +#define E0_DIR_PIN 27 +#define E0_ENABLE_PIN 24 -#define E1_STEP_PIN -1 // 19 -#define E1_DIR_PIN -1 // 18 -#define E1_ENABLE_PIN 24 +#define E1_STEP_PIN -1 // 19 +#define E1_DIR_PIN -1 // 18 +#define E1_ENABLE_PIN 24 -#define E2_STEP_PIN -1 // 17 -#define E2_DIR_PIN -1 // 16 -#define E2_ENABLE_PIN 24 +#define E2_STEP_PIN -1 // 17 +#define E2_DIR_PIN -1 // 16 +#define E2_ENABLE_PIN 24 // // Temperature Sensors // -#define TEMP_0_PIN 0 // Analog Input (D27) +#define TEMP_0_PIN 0 // Analog Input (D27) // // Heaters / Fans // -#define HEATER_0_PIN 4 +#define HEATER_0_PIN 4 #ifndef FAN_PIN - #define FAN_PIN 3 + #define FAN_PIN 3 #endif // // Misc. Functions // -#define SDSS 11 +#define SDSS 11 /* Unused (1) (2) (3) 4 5 6 7 8 9 10 11 12 13 (14) (15) (16) 17 (18) (19) (20) (21) (22) (23) 24 (25) (26) (27) 28 (29) (30) (31) */ diff --git a/Marlin/src/pins/sanguino/pins_SANGUINOLOLU_11.h b/Marlin/src/pins/sanguino/pins_SANGUINOLOLU_11.h index 977ba16daf22..438d49d615c8 100644 --- a/Marlin/src/pins/sanguino/pins_SANGUINOLOLU_11.h +++ b/Marlin/src/pins/sanguino/pins_SANGUINOLOLU_11.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -31,7 +31,6 @@ * 1) added pointer to a current Arduino IDE extension * 2) added support for M3, M4 & M5 spindle control commands * 3) added case light pin definition - * */ /** @@ -49,10 +48,9 @@ * Just use the above JSON URL instead of Sparkfun's JSON. * * Once installed select the Sanguino board and then select the CPU. - * */ -#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega1284P__) +#if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega1284P__) #error "Oops! Select 'Sanguino' in 'Tools > Boards' and 'ATmega644P' or 'ATmega1284P' in 'Tools > Processor.'" #endif @@ -63,60 +61,60 @@ // // Limit Switches // -#define X_STOP_PIN 18 -#define Y_STOP_PIN 19 -#define Z_STOP_PIN 20 +#define X_STOP_PIN 18 +#define Y_STOP_PIN 19 +#define Z_STOP_PIN 20 // // Steppers // -#define X_STEP_PIN 15 -#define X_DIR_PIN 21 +#define X_STEP_PIN 15 +#define X_DIR_PIN 21 -#define Y_STEP_PIN 22 -#define Y_DIR_PIN 23 +#define Y_STEP_PIN 22 +#define Y_DIR_PIN 23 -#define Z_STEP_PIN 3 -#define Z_DIR_PIN 2 +#define Z_STEP_PIN 3 +#define Z_DIR_PIN 2 -#define E0_STEP_PIN 1 -#define E0_DIR_PIN 0 +#define E0_STEP_PIN 1 +#define E0_DIR_PIN 0 // // Temperature Sensors // -#define TEMP_0_PIN 7 // Analog Input (pin 33 extruder) -#define TEMP_BED_PIN 6 // Analog Input (pin 34 bed) +#define TEMP_0_PIN 7 // Analog Input (pin 33 extruder) +#define TEMP_BED_PIN 6 // Analog Input (pin 34 bed) // // Heaters / Fans // -#define HEATER_0_PIN 13 // (extruder) +#define HEATER_0_PIN 13 // (extruder) #if ENABLED(SANGUINOLOLU_V_1_2) - #define HEATER_BED_PIN 12 // (bed) - #define X_ENABLE_PIN 14 - #define Y_ENABLE_PIN 14 - #define Z_ENABLE_PIN 26 - #define E0_ENABLE_PIN 14 + #define HEATER_BED_PIN 12 // (bed) + #define X_ENABLE_PIN 14 + #define Y_ENABLE_PIN 14 + #define Z_ENABLE_PIN 26 + #define E0_ENABLE_PIN 14 #if !defined(FAN_PIN) && ENABLED(LCD_I2C_PANELOLU2) - #define FAN_PIN 4 // Uses Transistor1 (PWM) on Panelolu2's Sanguino Adapter Board to drive the fan + #define FAN_PIN 4 // Uses Transistor1 (PWM) on Panelolu2's Sanguino Adapter Board to drive the fan #endif #else - #define HEATER_BED_PIN 14 // (bed) - #define X_ENABLE_PIN -1 - #define Y_ENABLE_PIN -1 - #define Z_ENABLE_PIN -1 - #define E0_ENABLE_PIN -1 + #define HEATER_BED_PIN 14 // (bed) + #define X_ENABLE_PIN -1 + #define Y_ENABLE_PIN -1 + #define Z_ENABLE_PIN -1 + #define E0_ENABLE_PIN -1 #endif #if !defined(FAN_PIN) && (MB(AZTEEG_X1, STB_11) || IS_MELZI) - #define FAN_PIN 4 // Works for Panelolu2 too + #define FAN_PIN 4 // Works for Panelolu2 too #endif // @@ -129,17 +127,17 @@ * If you encounter issues with these pins, upgrade your * Sanguino libraries! See #368. */ -//#define SDSS 24 -#define SDSS 31 +//#define SDSS 24 +#define SDSS 31 #if IS_MELZI - #define LED_PIN 27 + #define LED_PIN 27 #elif MB(STB_11) - #define LCD_BACKLIGHT_PIN 17 // LCD backlight LED + #define LCD_BACKLIGHT_PIN 17 // LCD backlight LED #endif -#if NONE(SPINDLE_FEATURE, LASER_FEATURE) && ENABLED(SANGUINOLOLU_V_1_2) && !BOTH(ULTRA_LCD, NEWPANEL) // try to use IO Header - #define CASE_LIGHT_PIN 4 // Hardware PWM - see if IO Header is available +#if NONE(SPINDLE_FEATURE, LASER_FEATURE) && ENABLED(SANGUINOLOLU_V_1_2) && !BOTH(ULTRA_LCD, NEWPANEL)// try to use IO Header + #define CASE_LIGHT_PIN 4 // Hardware PWM - see if IO Header is available #endif /** @@ -154,59 +152,78 @@ // // LCD / Controller // -#if HAS_SPI_LCD +#if HAS_WIRED_LCD - #define SD_DETECT_PIN -1 + #define SD_DETECT_PIN -1 - #if HAS_GRAPHICAL_LCD + #if HAS_MARLINUI_U8GLIB #if ENABLED(LCD_FOR_MELZI) - #define LCD_PINS_RS 17 - #define LCD_PINS_ENABLE 16 - #define LCD_PINS_D4 11 + #define LCD_PINS_RS 17 + #define LCD_PINS_ENABLE 16 + #define LCD_PINS_D4 11 - #define BOARD_ST7920_DELAY_1 DELAY_NS(0) - #define BOARD_ST7920_DELAY_2 DELAY_NS(188) - #define BOARD_ST7920_DELAY_3 DELAY_NS(0) + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(0) + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(188) + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(0) + #endif - #elif ENABLED(U8GLIB_ST7920) // SPI GLCD 12864 ST7920 ( like [www.digole.com] ) For Melzi V2.0 + #elif ENABLED(U8GLIB_ST7920) // SPI GLCD 12864 ST7920 ( like [www.digole.com] ) For Melzi V2.0 #if IS_MELZI - #define LCD_PINS_RS 30 // CS chip select /SS chip slave select - #define LCD_PINS_ENABLE 29 // SID (MOSI) - #define LCD_PINS_D4 17 // SCK (CLK) clock + #define LCD_PINS_RS 30 // CS chip select /SS chip slave select + #define LCD_PINS_ENABLE 29 // SID (MOSI) + #define LCD_PINS_D4 17 // SCK (CLK) clock // Pin 27 is taken by LED_PIN, but Melzi LED does nothing with // Marlin so this can be used for BEEPER_PIN. You can use this pin // with M42 instead of BEEPER_PIN. - #define BEEPER_PIN 27 - #else // Sanguinololu >=1.3 - #define LCD_PINS_RS 4 - #define LCD_PINS_ENABLE 17 - #define LCD_PINS_D4 30 - #define LCD_PINS_D5 29 - #define LCD_PINS_D6 28 - #define LCD_PINS_D7 27 + #define BEEPER_PIN 27 + + #if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(0) + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(188) + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(0) + #endif + #endif + + #else // Sanguinololu >=1.3 + #define LCD_PINS_RS 4 + #define LCD_PINS_ENABLE 17 + #define LCD_PINS_D4 30 + #define LCD_PINS_D5 29 + #define LCD_PINS_D6 28 + #define LCD_PINS_D7 27 #endif #else - #define DOGLCD_A0 30 + #define DOGLCD_A0 30 #if ENABLED(MAKRPANEL) - #define BEEPER_PIN 29 - #define DOGLCD_CS 17 - #define LCD_BACKLIGHT_PIN 28 // PA3 + #define BEEPER_PIN 29 + #define DOGLCD_CS 17 + #define LCD_BACKLIGHT_PIN 28 // PA3 #elif IS_MELZI - #define BEEPER_PIN 27 - #define DOGLCD_CS 28 + #define BEEPER_PIN 27 + #define DOGLCD_CS 28 - #else // !MAKRPANEL + #else // !MAKRPANEL - #define DOGLCD_CS 29 + #define DOGLCD_CS 29 #endif @@ -218,72 +235,72 @@ //#define LCD_SCREEN_ROT_180 //#define LCD_SCREEN_ROT_270 - #elif ENABLED(ZONESTAR_LCD) // For the Tronxy Melzi boards + #elif ENABLED(ZONESTAR_LCD) // For the Tronxy Melzi boards - #define LCD_PINS_RS 28 - #define LCD_PINS_ENABLE 29 - #define LCD_PINS_D4 10 - #define LCD_PINS_D5 11 - #define LCD_PINS_D6 16 - #define LCD_PINS_D7 17 + #define LCD_PINS_RS 28 + #define LCD_PINS_ENABLE 29 + #define LCD_PINS_D4 10 + #define LCD_PINS_D5 11 + #define LCD_PINS_D6 16 + #define LCD_PINS_D7 17 #else - #define LCD_PINS_RS 4 - #define LCD_PINS_ENABLE 17 - #define LCD_PINS_D4 30 - #define LCD_PINS_D5 29 - #define LCD_PINS_D6 28 - #define LCD_PINS_D7 27 + #define LCD_PINS_RS 4 + #define LCD_PINS_ENABLE 17 + #define LCD_PINS_D4 30 + #define LCD_PINS_D5 29 + #define LCD_PINS_D6 28 + #define LCD_PINS_D7 27 #endif #if ENABLED(LCD_FOR_MELZI) - #define BTN_ENC 28 - #define BTN_EN1 29 - #define BTN_EN2 30 + #define BTN_ENC 28 + #define BTN_EN1 29 + #define BTN_EN2 30 - #elif ENABLED(ZONESTAR_LCD) // For the Tronxy Melzi boards + #elif ENABLED(ZONESTAR_LCD) // For the Tronxy Melzi boards - #define ADC_KEYPAD_PIN 1 - #define BTN_EN1 -1 - #define BTN_EN2 -1 + #define ADC_KEYPAD_PIN 1 + #define BTN_EN1 -1 + #define BTN_EN2 -1 #elif ENABLED(LCD_I2C_PANELOLU2) #if IS_MELZI - #define BTN_ENC 29 - #define LCD_SDSS 30 // Panelolu2 SD card reader rather than the Melzi + #define BTN_ENC 29 + #define LCD_SDSS 30 // Panelolu2 SD card reader rather than the Melzi #else - #define BTN_ENC 30 + #define BTN_ENC 30 #endif - #else // !LCD_FOR_MELZI && !ZONESTAR_LCD && !LCD_I2C_PANELOLU2 + #else // !LCD_FOR_MELZI && !ZONESTAR_LCD && !LCD_I2C_PANELOLU2 - #define BTN_ENC 16 - #define LCD_SDSS 28 // Smart Controller SD card reader rather than the Melzi + #define BTN_ENC 16 + #define LCD_SDSS 28 // Smart Controller SD card reader rather than the Melzi #endif #if ENABLED(NEWPANEL) && !defined(BTN_EN1) - #define BTN_EN1 11 - #define BTN_EN2 10 + #define BTN_EN1 11 + #define BTN_EN2 10 #endif -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD // // M3/M4/M5 - Spindle/Laser Control // #if HAS_CUTTER - #if !MB(AZTEEG_X1) && ENABLED(SANGUINOLOLU_V_1_2) && !BOTH(ULTRA_LCD, NEWPANEL) // try to use IO Header + #if !MB(AZTEEG_X1) && ENABLED(SANGUINOLOLU_V_1_2) && !BOTH(ULTRA_LCD, NEWPANEL)// try to use IO Header - #define SPINDLE_LASER_ENA_PIN 10 // Pullup or pulldown! - #define SPINDLE_LASER_PWM_PIN 4 // Hardware PWM - #define SPINDLE_DIR_PIN 11 + #define SPINDLE_LASER_ENA_PIN 10 // Pullup or pulldown! + #define SPINDLE_LASER_PWM_PIN 4 // Hardware PWM + #define SPINDLE_DIR_PIN 11 - #elif !MB(MELZI) // use X stepper motor socket + #elif !MB(MELZI) // use X stepper motor socket /** * To control the spindle speed and have an LCD you must sacrifice @@ -315,11 +332,11 @@ #undef X_DIR_PIN #undef X_ENABLE_PIN #undef X_STEP_PIN - #define X_DIR_PIN 0 - #define X_ENABLE_PIN 14 - #define X_STEP_PIN 1 - #define SPINDLE_LASER_PWM_PIN 15 // Hardware PWM - #define SPINDLE_LASER_ENA_PIN 21 // Pullup! - #define SPINDLE_DIR_PIN -1 // No pin available on the socket for the direction pin + #define X_DIR_PIN 0 + #define X_ENABLE_PIN 14 + #define X_STEP_PIN 1 + #define SPINDLE_LASER_PWM_PIN 15 // Hardware PWM + #define SPINDLE_LASER_ENA_PIN 21 // Pullup! + #define SPINDLE_DIR_PIN -1 // No pin available on the socket for the direction pin #endif #endif diff --git a/Marlin/src/pins/sanguino/pins_SANGUINOLOLU_12.h b/Marlin/src/pins/sanguino/pins_SANGUINOLOLU_12.h index 3254a01a15bd..c5c8b4f57e57 100644 --- a/Marlin/src/pins/sanguino/pins_SANGUINOLOLU_12.h +++ b/Marlin/src/pins/sanguino/pins_SANGUINOLOLU_12.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/pins/sanguino/pins_SETHI.h b/Marlin/src/pins/sanguino/pins_SETHI.h index 528ec4455f48..dc2133e441dc 100644 --- a/Marlin/src/pins/sanguino/pins_SETHI.h +++ b/Marlin/src/pins/sanguino/pins_SETHI.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -47,79 +47,78 @@ * Just use the above JSON URL instead of Sparkfun's JSON. * * Once installed select the Sanguino board and then select the CPU. - * */ -#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega644__) && !defined(__AVR_ATmega1284P__) +#if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega644__, __AVR_ATmega1284P__) #error "Oops! Select 'Sanguino' in 'Tools > Boards' and 'ATmega644', 'ATmega644P', or 'ATmega1284P' in 'Tools > Processor.'" #endif #define BOARD_INFO_NAME "Sethi 3D_1" #ifndef GEN7_VERSION - #define GEN7_VERSION 12 // v1.x + #define GEN7_VERSION 12 // v1.x #endif // // Limit Switches // -#define X_STOP_PIN 2 -#define Y_STOP_PIN 0 -#define Z_MIN_PIN 1 -#define Z_MAX_PIN 0 +#define X_STOP_PIN 2 +#define Y_STOP_PIN 0 +#define Z_MIN_PIN 1 +#define Z_MAX_PIN 0 // // Steppers // -#define X_STEP_PIN 19 -#define X_DIR_PIN 18 -#define X_ENABLE_PIN 24 +#define X_STEP_PIN 19 +#define X_DIR_PIN 18 +#define X_ENABLE_PIN 24 -#define Y_STEP_PIN 23 -#define Y_DIR_PIN 22 -#define Y_ENABLE_PIN 24 +#define Y_STEP_PIN 23 +#define Y_DIR_PIN 22 +#define Y_ENABLE_PIN 24 -#define Z_STEP_PIN 26 -#define Z_DIR_PIN 25 -#define Z_ENABLE_PIN 24 +#define Z_STEP_PIN 26 +#define Z_DIR_PIN 25 +#define Z_ENABLE_PIN 24 -#define E0_STEP_PIN 28 -#define E0_DIR_PIN 27 -#define E0_ENABLE_PIN 24 +#define E0_STEP_PIN 28 +#define E0_DIR_PIN 27 +#define E0_ENABLE_PIN 24 // // Temperature Sensors // -#define TEMP_0_PIN 1 // Analog Input -#define TEMP_BED_PIN 2 // Analog Input +#define TEMP_0_PIN 1 // Analog Input +#define TEMP_BED_PIN 2 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 4 -#define HEATER_BED_PIN 3 +#define HEATER_0_PIN 4 +#define HEATER_BED_PIN 3 #ifndef FAN_PIN #if GEN7_VERSION >= 13 // Gen7 v1.3 removed the fan pin - #define FAN_PIN -1 + #define FAN_PIN -1 #else - #define FAN_PIN 31 + #define FAN_PIN 31 #endif #endif // // Misc. Functions // -#define PS_ON_PIN 15 +#define PS_ON_PIN 15 // All these generations of Gen7 supply thermistor power // via PS_ON, so ignore bad thermistor readings -//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 +//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 // our pin for debugging. -#define DEBUG_PIN 0 +#define DEBUG_PIN 0 // our RS485 pins -#define TX_ENABLE_PIN 12 -#define RX_ENABLE_PIN 13 +#define TX_ENABLE_PIN 12 +#define RX_ENABLE_PIN 13 diff --git a/Marlin/src/pins/sanguino/pins_STB_11.h b/Marlin/src/pins/sanguino/pins_STB_11.h index 774fb00403cb..b10a09840aaa 100644 --- a/Marlin/src/pins/sanguino/pins_STB_11.h +++ b/Marlin/src/pins/sanguino/pins_STB_11.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/pins/sanguino/pins_ZMIB_V2.h b/Marlin/src/pins/sanguino/pins_ZMIB_V2.h new file mode 100644 index 000000000000..838ffe38aa9a --- /dev/null +++ b/Marlin/src/pins/sanguino/pins_ZMIB_V2.h @@ -0,0 +1,234 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega1284P__) + #error "Oops! Select 'Sanguino' in 'Tools > Boards' and 'ATmega644P' or 'ATmega1284P' in 'Tools > Processor.'" +#endif + +#define BOARD_INFO_NAME "Zonestar ZMIB_V2" +#define BOARD_WEBSITE_URL "https://www.aliexpress.com/item/32957490744.html" + +#define IS_ZMIB_V2 + +/** + * ZMIB pin assignments + * + * The ZMIB board needs a bootloader installed before Marlin can be uploaded. + * If you don't have a chip programmer you can use a spare Arduino plus a few + * electronic components to write the bootloader. + * + * See http://www.instructables.com/id/Burn-Arduino-Bootloader-with-Arduino-MEGA/ + */ + +/** + * PIN: 0 Port: B0 HEATER_0_PIN + * PIN: 1 Port: B1 HEATER_BED_PIN + * PIN: 2 Port: B2 EXP1_4(BTN_EN2) + * PIN: 3 Port: B3 V1: SD_DETECT_PIN + * PIN: 3 Port: B3 V2: EXP1_6 + * PIN: 4 Port: B4 SDSS + * PIN: 4 Port: B4 V1: EXP1_6 + * PIN: 5 Port: B5 AVR_MOSI_PIN + * . MOSI_PIN + * PIN: 6 Port: B6 AVR_MISO_PIN + * . EXP1_9(MISO_PIN) + * PIN: 7 Port: B7 AVR_SCK_PIN + * . EXP1_10(SCK_PIN) + * PIN: 8 Port: D0 RXD + * PIN: 9 Port: D1 TXD + * PIN: 10 Port: D2 EXP1_8 + * PIN: 11 Port: D3 EXP1_7 + * PIN: 12 Port: D4 EXP1_5(BTN_EN1) + * PIN: 13 Port: D5 Z_MIN_PIN + * PIN: 14 Port: D6 E1_DIR_PIN + * PIN: 15 Port: D7 E1_STEP_PIN + * PIN: 16 Port: C0 Z_DIR_PIN + * PIN: 17 Port: C1 Z_STEP_PIN + * PIN: 18 Port: C2 Y_MIN_PIN + * PIN: 19 Port: C3 Y_DIR_PIN + * PIN: 20 Port: C4 Y_STEP_PIN + * PIN: 21 Port: C5 X_MIN_PIN + * PIN: 22 Port: C6 X_DIR_PIN + * PIN: 23 Port: C7 X_STEP_PIN + * PIN: 24 Port: A7 X_ENABLE_PIN + * Y_ENABLE_PIN + * Z_ENABLE_PIN + * E0_ENABLE_PIN + * E1_ENABLE_PIN + * PIN: 25 Port: A6 FIL_RUNOUT_PIN + * PIN: 26 Port: A5 E0_DIR_PIN + * PIN: 27 Port: A4 E0_STEP_PIN + * PIN: 28 Port: A3 FAN_PIN + * PIN: 29 Port: A2 EXP1_3(BTN_ENC) + * ADC_KEY_PIN + * PIN: 30 Port: A1 TEMP_0_PIN + * PIN: 31 Port: A0 TEMP_BED_PIN + */ + +// +// Limit Switches +// +#define X_MIN_PIN 21 +#define Y_MIN_PIN 18 + +#if EITHER(Z6S_ZFAULT, Z6BS_ZFAULT) + #define Z_MIN_PIN 25 +#else + #define Z_MIN_PIN 13 +#endif + +// +// Steppers +// +#define X_STEP_PIN 23 +#define X_DIR_PIN 22 +#define X_ENABLE_PIN 24 + +#define Y_STEP_PIN 20 +#define Y_DIR_PIN 19 +#define Y_ENABLE_PIN 24 + +#if EITHER(Z6S_ZFAULT, Z6BS_ZFAULT) + #define Z_STEP_PIN 27 + #define Z_DIR_PIN 26 +#else + #define Z_STEP_PIN 17 + #define Z_DIR_PIN 16 +#endif + +#define Z_ENABLE_PIN 24 + +#if EITHER(Z6S_ZFAULT, Z6BS_ZFAULT) + #define E0_STEP_PIN 15 + #define E0_DIR_PIN 14 +#else + #define E0_STEP_PIN 27 + #define E0_DIR_PIN 26 +#endif + +#define E0_ENABLE_PIN 24 + +#define E1_STEP_PIN 15 +#define E1_DIR_PIN 14 +#define E1_ENABLE_PIN 24 + +// +// Temperature Sensors +// +#define TEMP_0_PIN 1 // Analog Input +#define TEMP_BED_PIN 0 // Analog Input + +// +// Heaters / Fans +// +#define HEATER_0_PIN 0 +#define HEATER_BED_PIN 1 +#define FAN_PIN 28 +#define FAN1_PIN -1 + +// +//filament run out sensor +// +#if EITHER(Z6S_ZFAULT, Z6BS_ZFAULT) + #define FIL_RUNOUT_PIN 13 +#else + #define FIL_RUNOUT_PIN 25 // Z-MIN +#endif + +// +// SD card +// +#if ENABLED(SDSUPPORT) + #define SDSS 4 +#endif +#define SD_DETECT_PIN -1 + +/*=================================================== + * ZMIB Version 1 - EXP1 Connector + * MOSI(D5) TX1(D11) ENA(D12) ENC(D29/A2) 5V + * SCK(D7) RX1(D10) SCS(D4) ENB(D2) GND + *=================================================== + * ZMIB Version 2 - EXP1 Connector + * MOSI(D5) TX1(D11) ENA(D12) ENC(D29/A2) 5V + * SCK(D7) RX1(D10) SCS(D3) ENB(D2) GND + *=================================================== + * LCD 128x64 + *==================================================*/ + +#if ENABLED(ZONESTAR_12864LCD) + // + // LCD 128x64 + // + #define LCDSCREEN_NAME "ZONESTAR_12864LCD" + #define FORCE_SOFT_SPI + //#define LCD_SDSS 11 + #define LCD_PINS_RS 11 // ST7920_CS_PIN LCD_PIN_RS (PIN4 of LCD module) + #ifdef IS_ZMIB_V2 + #define LCD_PINS_ENABLE 3 // ST7920_DAT_PIN LCD_PIN_R/W (PIN5 of LCD module) + #else + #define LCD_PINS_ENABLE 4 // ST7920_DAT_PIN LCD_PIN_R/W (PIN5 of LCD module) + #endif + #define LCD_PINS_D4 10 // ST7920_CLK_PIN LCD_PIN_ENABLE (PIN6 of LCD module) + + // Alter timing for graphical display + #define ST7920_DELAY_1 DELAY_2_NOP + #define ST7920_DELAY_2 DELAY_2_NOP + #define ST7920_DELAY_3 DELAY_2_NOP + +#elif EITHER(ZONESTAR_12864OLED, ZONESTAR_12864OLED_SSD1306) + // + // OLED 128x64 + // + #define LCDSCREEN_NAME "ZONESTAR 12864OLED" + #define FORCE_SOFT_SPI + #ifdef IS_ZMIB_V2 + #define LCD_PINS_RS 3 // RESET + #else + #define LCD_PINS_RS 4 // RESET + #endif + #define LCD_PINS_DC 10 // DC + #define DOGLCD_CS 11 // CS + #if ENABLED(OLED_HW_IIC) + #error "Oops! can't choose HW IIC for ZMIB board!!" + #elif ENABLED(OLED_HW_SPI) + // HW SPI + #define DOGLCD_A0 LCD_PINS_DC // A0 = DC + #else + // SW SPI + #define DOGLCD_A0 LCD_PINS_DC // A0 = DC + #define DOGLCD_MOSI AVR_MOSI_PIN // SDA + #define DOGLCD_SCK AVR_SCK_PIN // SCK + #endif + +#endif + +// +// All the above are also RRDSC with rotary encoder +// +#if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) + #define BTN_EN1 2 + #define BTN_EN2 12 + #define BTN_ENC 29 + #define BEEPER_PIN -1 + #define KILL_PIN -1 +#endif diff --git a/Marlin/src/pins/sensitive_pins.h b/Marlin/src/pins/sensitive_pins.h index 807ee99e235f..d7eb1872458f 100644 --- a/Marlin/src/pins/sensitive_pins.h +++ b/Marlin/src/pins/sensitive_pins.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -278,9 +278,9 @@ #endif #define _E6_CS +#define _E6_MS1 #define _E6_MS2 #define _E6_MS3 -#define _E6_MS4 #if E_NEEDED(6) #if PIN_EXISTS(E6_CS) && AXIS_HAS_SPI(E6) @@ -302,9 +302,9 @@ #endif #define _E7_CS +#define _E7_MS1 +#define _E7_MS2 #define _E7_MS3 -#define _E7_MS4 -#define _E7_MS5 #if E_NEEDED(7) #if PIN_EXISTS(E7_CS) && AXIS_HAS_SPI(E7) @@ -354,7 +354,7 @@ #endif #endif -#elif EXTRUDERS > 1 || ENABLED(MIXING_EXTRUDER) +#elif EITHER(HAS_MULTI_EXTRUDER, MIXING_EXTRUDER) #undef _E1_PINS #define _E1_PINS E1_STEP_PIN, E1_DIR_PIN, E1_ENABLE_PIN, _E1_CS _E1_MS1 _E1_MS2 _E1_MS3 @@ -383,12 +383,37 @@ #endif // EXTRUDERS > 3 || MIXING_EXTRUDER > 3 #endif // EXTRUDERS > 2 || MIXING_EXTRUDER > 2 -#endif // EXTRUDERS > 1 || MIXING_EXTRUDER +#endif // HAS_MULTI_EXTRUDER || MIXING_EXTRUDER // // Heaters, Fans, Temp Sensors // +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN -1 +#endif +#ifndef E1_AUTO_FAN_PIN + #define E1_AUTO_FAN_PIN -1 +#endif +#ifndef E2_AUTO_FAN_PIN + #define E2_AUTO_FAN_PIN -1 +#endif +#ifndef E3_AUTO_FAN_PIN + #define E3_AUTO_FAN_PIN -1 +#endif +#ifndef E4_AUTO_FAN_PIN + #define E4_AUTO_FAN_PIN -1 +#endif +#ifndef E5_AUTO_FAN_PIN + #define E5_AUTO_FAN_PIN -1 +#endif +#ifndef E6_AUTO_FAN_PIN + #define E6_AUTO_FAN_PIN -1 +#endif +#ifndef E7_AUTO_FAN_PIN + #define E7_AUTO_FAN_PIN -1 +#endif + #define _H0_PINS #define _H1_PINS #define _H2_PINS @@ -398,10 +423,10 @@ #define _H6_PINS #define _H7_PINS -#if HOTENDS +#if HAS_HOTEND #undef _H0_PINS #define _H0_PINS HEATER_0_PIN, E0_AUTO_FAN_PIN, analogInputToDigitalPin(TEMP_0_PIN), - #if HOTENDS > 1 + #if HAS_MULTI_HOTEND #undef _H1_PINS #define _H1_PINS HEATER_1_PIN, E1_AUTO_FAN_PIN, analogInputToDigitalPin(TEMP_1_PIN), #if HOTENDS > 2 @@ -428,15 +453,9 @@ #endif // HOTENDS > 4 #endif // HOTENDS > 3 #endif // HOTENDS > 2 - #endif // HOTENDS > 1 + #endif // HAS_MULTI_HOTEND #endif // HOTENDS -#define _BED_PINS -#if PIN_EXISTS(HEATER_BED) && PIN_EXISTS(TEMP_BED) - #undef _BED_PINS - #define _BED_PINS HEATER_BED_PIN, analogInputToDigitalPin(TEMP_BED_PIN), -#endif - // // Dual X, Dual Y, Multi-Z // Chip Select and Digital Micro-stepping @@ -589,12 +608,6 @@ #define _Z_PROBE #endif -#if TEMP_SENSOR_BED && PIN_EXISTS(HEATER_BED) - #define _HEATER_BED HEATER_BED_PIN, -#else - #define _HEATER_BED -#endif - #if PIN_EXISTS(FAN) #define _FAN0 FAN_PIN, #else @@ -641,14 +654,36 @@ #define _FANC #endif +#if TEMP_SENSOR_BED && PINS_EXIST(TEMP_BED, HEATER_BED) + #define _BED_PINS HEATER_BED_PIN, analogInputToDigitalPin(TEMP_BED_PIN), +#else + #define _BED_PINS +#endif + +#if TEMP_SENSOR_CHAMBER && PIN_EXISTS(TEMP_CHAMBER) + #define _CHAMBER_TEMP analogInputToDigitalPin(TEMP_CHAMBER_PIN), +#else + #define _CHAMBER_TEMP +#endif +#if TEMP_SENSOR_CHAMBER && PINS_EXIST(TEMP_CHAMBER, HEATER_CHAMBER) + #define _CHAMBER_HEATER HEATER_CHAMBER_PIN, +#else + #define _CHAMBER_HEATER +#endif +#if TEMP_SENSOR_CHAMBER && PINS_EXIST(TEMP_CHAMBER, CHAMBER_AUTO_FAN) + #define _CHAMBER_FAN CHAMBER_AUTO_FAN_PIN, +#else + #define _CHAMBER_FAN +#endif + #ifndef HAL_SENSITIVE_PINS #define HAL_SENSITIVE_PINS #endif #define SENSITIVE_PINS { \ _X_PINS _Y_PINS _Z_PINS _X2_PINS _Y2_PINS _Z2_PINS _Z3_PINS _Z4_PINS _Z_PROBE \ - _E0_PINS _E1_PINS _E2_PINS _E3_PINS _E4_PINS _E5_PINS _E6_PINS _E7_PINS _BED_PINS \ + _E0_PINS _E1_PINS _E2_PINS _E3_PINS _E4_PINS _E5_PINS _E6_PINS _E7_PINS \ _H0_PINS _H1_PINS _H2_PINS _H3_PINS _H4_PINS _H5_PINS _H6_PINS _H7_PINS \ - _PS_ON _HEATER_BED _FAN0 _FAN1 _FAN2 _FAN3 _FAN4 _FAN5 _FAN6 _FAN7 _FANC \ - HAL_SENSITIVE_PINS \ + _PS_ON _FAN0 _FAN1 _FAN2 _FAN3 _FAN4 _FAN5 _FAN6 _FAN7 _FANC \ + _BED_PINS _CHAMBER_TEMP _CHAMBER_HEATER _CHAMBER_FAN HAL_SENSITIVE_PINS \ } diff --git a/Marlin/src/pins/stm32/pins_ARMED.h b/Marlin/src/pins/stm32/pins_ARMED.h deleted file mode 100644 index 03f267a3a456..000000000000 --- a/Marlin/src/pins/stm32/pins_ARMED.h +++ /dev/null @@ -1,201 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -// https://github.com/ktand/Armed - -#pragma once - -#ifndef STM32F4 - #error "Oops! Select an STM32F4 board in 'Tools > Board.'" -#elif HOTENDS > 2 || E_STEPPERS > 2 - #error "Arm'ed supports up to 2 hotends / E-steppers." -#endif - -#ifndef ARMED_V1_0 - #define ARMED_V1_1 -#endif - -#undef BOARD_INFO_NAME // Defined on the command line by Arduino Core STM32 -#define BOARD_INFO_NAME "Arm'ed" -#define DEFAULT_MACHINE_NAME BOARD_INFO_NAME - -#define I2C_EEPROM - -#undef E2END // Defined in Arduino Core STM32 to be used with EEPROM emulation. This board uses a real EEPROM. -#define E2END 0xFFF // 4KB - -// -// Limit Switches -// -#define X_STOP_PIN PE0 -#define Y_STOP_PIN PE1 -#define Z_STOP_PIN PE14 - -// -// Z Probe (when not Z_MIN_PIN) -// -//#ifndef Z_MIN_PROBE_PIN -// #define Z_MIN_PROBE_PIN PA4 -//#endif - -// -// Filament Runout Sensor -// -#ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN PA3 -#endif - -// -// Steppers -// - -#ifdef ARMED_SWAP_X_E1 - #define X_STEP_PIN PE4 - #define X_DIR_PIN PE2 - #define X_ENABLE_PIN PE3 - #define X_CS_PIN PE5 -#else - #define X_STEP_PIN PD3 - #define X_DIR_PIN PD2 - #define X_ENABLE_PIN PD0 - #define X_CS_PIN PD1 -#endif - -#define Y_STEP_PIN PE11 -#define Y_DIR_PIN PE10 -#define Y_ENABLE_PIN PE13 -#define Y_CS_PIN PE12 - -#define Z_STEP_PIN PD6 -#define Z_DIR_PIN PD7 -#define Z_ENABLE_PIN PD4 -#define Z_CS_PIN PD5 - -#define E0_STEP_PIN PB5 -#define E0_DIR_PIN PB6 -#ifdef ARMED_V1_1 - #define E0_ENABLE_PIN PC12 -#else - #define E0_ENABLE_PIN PB3 -#endif -#define E0_CS_PIN PB4 - -#ifdef ARMED_SWAP_X_E1 - #define E1_STEP_PIN PD3 - #define E1_DIR_PIN PD2 - #define E1_ENABLE_PIN PD0 - #define E1_CS_PIN PD1 -#else - #define E1_STEP_PIN PE4 - #define E1_DIR_PIN PE2 - #define E1_ENABLE_PIN PE3 - #define E1_CS_PIN PE5 -#endif - -// -// Temperature Sensors -// -#define TEMP_0_PIN PC0 // Analog Input -#define TEMP_1_PIN PC1 // Analog Input -#define TEMP_BED_PIN PC2 // Analog Input - -// -// Heaters / Fans -// -#define HEATER_0_PIN PA1 // Hardware PWM -#define HEATER_1_PIN PA2 // Hardware PWM -#define HEATER_BED_PIN PA0 // Hardware PWM - -#define FAN_PIN PC6 // Hardware PWM, Part cooling fan -#define FAN1_PIN PC7 // Hardware PWM, Extruder fan -#define FAN2_PIN PC8 // Hardware PWM, Controller fan - -// -// Misc functions -// -#define SDSS PE7 -#define LED_PIN PB7 // Heart beat -#define PS_ON_PIN PA10 -#define KILL_PIN PA8 -#define PWR_LOSS PA4 // Power loss / nAC_FAULT - -// -// LCD / Controller -// -#define SD_DETECT_PIN PA15 -#define BEEPER_PIN PC9 - -#if ENABLED(FYSETC_MINI_12864) - // - // See https://wiki.fysetc.com/Mini12864_Panel/?fbclid=IwAR1FyjuNdVOOy9_xzky3qqo_WeM5h-4gpRnnWhQr_O1Ef3h0AFnFXmCehK8 - // - #define DOGLCD_A0 PE9 - #define DOGLCD_CS PE8 - - #define LCD_BACKLIGHT_PIN -1 - - #define LCD_RESET_PIN PB12 // Must be high or open for LCD to operate normally. - - #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) - #ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN PB13 - #endif - #ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN PB14 - #endif - #ifndef RGB_LED_B_PIN - #define RGB_LED_B_PIN PB15 - #endif - #elif ENABLED(FYSETC_MINI_12864_2_1) - #define NEOPIXEL_PIN PB13 - #endif -#else - #define LCD_PINS_RS PE9 - #define LCD_PINS_ENABLE PE8 - #define LCD_PINS_D4 PB12 - #define LCD_PINS_D5 PB13 - #define LCD_PINS_D6 PB14 - #define LCD_PINS_D7 PB15 - - #if ENABLED(MKS_MINI_12864) - #define DOGLCD_CS PB13 - #define DOGLCD_A0 PB14 - #endif -#endif - -#define BTN_EN1 PC4 -#define BTN_EN2 PC5 -#define BTN_ENC PC3 - -// -// Extension pins -// -#define EXT0_PIN PB0 -#define EXT1_PIN PB1 -#define EXT2_PIN PB2 -#define EXT3_PIN PD8 -#define EXT4_PIN PD9 -#define EXT5_PIN PD10 -#define EXT6_PIN PD11 -#define EXT7_PIN PD12 -#define EXT8_PIN PB10 -#define EXT9_PIN PB11 diff --git a/Marlin/src/pins/stm32/pins_BEAST.h b/Marlin/src/pins/stm32/pins_BEAST.h deleted file mode 100644 index d779994d1926..000000000000 --- a/Marlin/src/pins/stm32/pins_BEAST.h +++ /dev/null @@ -1,285 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if !defined(__STM32F1__) && !defined(__STM32F4__) - #error "Oops! Select an STM32F1/4 board in 'Tools > Board.'" -#endif - -/** - * 21017 Victor Perez Marlin for stm32f1 test - */ - -#define BOARD_INFO_NAME "Beast STM32" -#define DEFAULT_MACHINE_NAME "STM32F103RET6" - -// Enable I2C_EEPROM for testing -#define I2C_EEPROM - -// Ignore temp readings during development. -//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 - -// -// Steppers -// -#define X_STEP_PIN PE0 -#define X_DIR_PIN PE1 -#define X_ENABLE_PIN PC0 -#define X_MIN_PIN PD5 -#define X_MAX_PIN -1 - -#define Y_STEP_PIN PE2 -#define Y_DIR_PIN PE3 -#define Y_ENABLE_PIN PC1 -#define Y_MIN_PIN PD6 -#define Y_MAX_PIN - -#define Z_STEP_PIN PE4 -#define Z_DIR_PIN PE5 -#define Z_ENABLE_PIN PC2 -#define Z_MIN_PIN PD7 -#define Z_MAX_PIN -1 - -#define Y2_STEP_PIN -1 -#define Y2_DIR_PIN -1 -#define Y2_ENABLE_PIN -1 - -#define Z2_STEP_PIN -1 -#define Z2_DIR_PIN -1 -#define Z2_ENABLE_PIN -1 - -#define E0_STEP_PIN PE6 -#define E0_DIR_PIN PE7 -#define E0_ENABLE_PIN PC3 - -/** - * TODO: Currently using same Enable pin to all steppers. - */ - -#define E1_STEP_PIN PE8 -#define E1_DIR_PIN PE9 -#define E1_ENABLE_PIN PC4 - -#define E2_STEP_PIN PE10 -#define E2_DIR_PIN PE11 -#define E2_ENABLE_PIN PC5 - -// -// Misc. Functions -// -#define SDSS PA15 -#define LED_PIN PB2 - -#define PS_ON_PIN -1 -#define KILL_PIN -1 - -// -// Heaters / Fans -// -#define HEATER_0_PIN PD12 // EXTRUDER 1 -#define HEATER_1_PIN PD13 -#define HEATER_2_PIN PD14 - -#define HEATER_BED_PIN PB9 // BED -#define HEATER_BED2_PIN -1 // BED2 -#define HEATER_BED3_PIN -1 // BED3 - -#ifndef FAN_PIN - #define FAN_PIN PB10 -#endif - -#define FAN_SOFT_PWM - -// -// Temperature Sensors -// -#define TEMP_BED_PIN PA0 // Analog Input -#define TEMP_0_PIN PA1 // Analog Input -#define TEMP_1_PIN PA2 // Analog Input -#define TEMP_2_PIN PA3 // Analog Input - -// -// LCD Pins -// -#if HAS_SPI_LCD - - #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) - #define LCD_PINS_RS 49 // CS chip select /SS chip slave select - #define LCD_PINS_ENABLE 51 // SID (MOSI) - #define LCD_PINS_D4 52 // SCK (CLK) clock - #elif BOTH(NEWPANEL, PANEL_ONE) - #define LCD_PINS_RS PB8 - #define LCD_PINS_ENABLE PD2 - #define LCD_PINS_D4 PB12 - #define LCD_PINS_D5 PB13 - #define LCD_PINS_D6 PB14 - #define LCD_PINS_D7 PB15 - #else - #define LCD_PINS_RS PB8 - #define LCD_PINS_ENABLE PD2 - #define LCD_PINS_D4 PB12 - #define LCD_PINS_D5 PB13 - #define LCD_PINS_D6 PB14 - #define LCD_PINS_D7 PB15 - #if DISABLED(NEWPANEL) - #define BEEPER_PIN 33 - // Buttons attached to a shift register - // Not wired yet - //#define SHIFT_CLK 38 - //#define SHIFT_LD 42 - //#define SHIFT_OUT 40 - //#define SHIFT_EN 17 - #endif - #endif - - #if ENABLED(NEWPANEL) - - #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) - - #define BEEPER_PIN 37 - - #define BTN_EN1 31 - #define BTN_EN2 33 - #define BTN_ENC 35 - - #define SD_DETECT_PIN 49 - #define KILL_PIN 41 - - #if ENABLED(BQ_LCD_SMART_CONTROLLER) - #define LCD_BACKLIGHT_PIN 39 - #endif - - #elif ENABLED(REPRAPWORLD_GRAPHICAL_LCD) - - #define BTN_EN1 64 - #define BTN_EN2 59 - #define BTN_ENC 63 - #define SD_DETECT_PIN 42 - - #elif ENABLED(LCD_I2C_PANELOLU2) - - #define BTN_EN1 47 - #define BTN_EN2 43 - #define BTN_ENC 32 - #define LCD_SDSS 53 - #define SD_DETECT_PIN -1 - #define KILL_PIN 41 - - #elif ENABLED(LCD_I2C_VIKI) - - #define BTN_EN1 22 // http://files.panucatt.com/datasheets/viki_wiring_diagram.pdf explains 40/42. - #define BTN_EN2 7 // 22/7 are unused on RAMPS_14. 22 is unused and 7 the SERVO0_PIN on RAMPS_13. - - #define BTN_ENC -1 - #define LCD_SDSS 53 - #define SD_DETECT_PIN 49 - - #elif ANY(VIKI2, miniVIKI) - - #define BEEPER_PIN 33 - - // Pins for DOGM SPI LCD Support - #define DOGLCD_A0 44 - #define DOGLCD_CS 45 - #define LCD_SCREEN_ROT_180 - - #define BTN_EN1 22 - #define BTN_EN2 7 - #define BTN_ENC 39 - - #define SDSS 53 - #define SD_DETECT_PIN -1 // Pin 49 for display sd interface, 72 for easy adapter board - - #define KILL_PIN 31 - - #define STAT_LED_RED_PIN 32 - #define STAT_LED_BLUE_PIN 35 - - #elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) - - #define BTN_EN1 35 - #define BTN_EN2 37 - #define BTN_ENC 31 - #define SD_DETECT_PIN 49 - #define LCD_SDSS 53 - #define KILL_PIN 41 - #define BEEPER_PIN 23 - #define DOGLCD_CS 29 - #define DOGLCD_A0 27 - #define LCD_BACKLIGHT_PIN 33 - - #elif ENABLED(MINIPANEL) - - #define BEEPER_PIN 42 - // Pins for DOGM SPI LCD Support - #define DOGLCD_A0 44 - #define DOGLCD_CS 66 - #define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65 - #define SDSS 53 - - #define KILL_PIN 64 - // GLCD features - // Uncomment screen orientation - //#define LCD_SCREEN_ROT_90 - //#define LCD_SCREEN_ROT_180 - //#define LCD_SCREEN_ROT_270 - // The encoder and click button - #define BTN_EN1 40 - #define BTN_EN2 63 - #define BTN_ENC 59 - // not connected to a pin - #define SD_DETECT_PIN 49 - - #else - - // Beeper on AUX-4 - #define BEEPER_PIN 33 - - // Buttons directly attached to AUX-2 - #if ENABLED(REPRAPWORLD_KEYPAD) - #define BTN_EN1 64 - #define BTN_EN2 59 - #define BTN_ENC 63 - #define SHIFT_OUT 40 - #define SHIFT_CLK 44 - #define SHIFT_LD 42 - #elif ENABLED(PANEL_ONE) - #define BTN_EN1 59 // AUX2 PIN 3 - #define BTN_EN2 63 // AUX2 PIN 4 - #define BTN_ENC 49 // AUX3 PIN 7 - #else - #define BTN_EN1 37 - #define BTN_EN2 35 - #define BTN_ENC 31 - #endif - - #if ENABLED(G3D_PANEL) - #define SD_DETECT_PIN 49 - #define KILL_PIN 41 - #else - //#define SD_DETECT_PIN -1 // Ramps doesn't use this - #endif - - #endif - #endif // NEWPANEL - -#endif // HAS_SPI_LCD diff --git a/Marlin/src/pins/stm32/pins_BLACK_STM32F407VE.h b/Marlin/src/pins/stm32/pins_BLACK_STM32F407VE.h deleted file mode 100644 index d0edf897f407..000000000000 --- a/Marlin/src/pins/stm32/pins_BLACK_STM32F407VE.h +++ /dev/null @@ -1,155 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * STM32F407VET6 with RAMPS-like shield - * 'Black' STM32F407VET6 board - http://wiki.stm32duino.com/index.php?title=STM32F407 - * Shield - https://github.com/jmz52/Hardware - */ - -#if !defined(STM32F4) && !defined(STM32F4xx) - #error "Oops! Select an STM32F4 board in 'Tools > Board.'" -#elif HOTENDS > 2 || E_STEPPERS > 2 - #error "Black STM32F4VET6 supports up to 2 hotends / E-steppers." -#endif - -#ifndef BOARD_INFO_NAME - #define BOARD_INFO_NAME "Black STM32F4VET6" -#endif - -#define DEFAULT_MACHINE_NAME "STM32F407VET6" - -//#define I2C_EEPROM -//#define E2END 0x1FFF // 8KB -#define SRAM_EEPROM_EMULATION - -// -// Servos -// -#define SERVO0_PIN PC6 -#define SERVO1_PIN PC7 - -// -// Limit Switches -// -#define X_MIN_PIN PC13 -#define X_MAX_PIN PA15 -#define Y_MIN_PIN PA5 -#define Y_MAX_PIN PD12 -#define Z_MIN_PIN PD14 -#define Z_MAX_PIN PD15 - -// -// Steppers -// -#define X_STEP_PIN PC4 -#define X_DIR_PIN PA4 -#define X_ENABLE_PIN PE7 - -#define Y_STEP_PIN PE5 -#define Y_DIR_PIN PE2 -#define Y_ENABLE_PIN PE6 - -#define Z_STEP_PIN PD5 -#define Z_DIR_PIN PD3 -#define Z_ENABLE_PIN PD6 - -#define E0_STEP_PIN PD7 -#define E0_DIR_PIN PD0 -#define E0_ENABLE_PIN PB9 - -#define E1_STEP_PIN PE0 -#define E1_DIR_PIN PE1 -#define E1_ENABLE_PIN PB8 - -// -// Temperature Sensors -// -#define TEMP_0_PIN PC0 // T0 -#define TEMP_1_PIN PC1 // T1 -#define TEMP_BED_PIN PC2 // TB - -#ifndef TEMP_CHAMBER_PIN - #define TEMP_CHAMBER_PIN PC3 // TC -#endif - -// -// Heaters / Fans -// -#define HEATER_0_PIN PA2 // Heater0 -#define HEATER_1_PIN PA3 // Heater1 -#define HEATER_BED_PIN PA1 // Hotbed - -#define FAN_PIN PE9 // Fan0 -#define FAN1_PIN PE11 // Fan1 -#define FAN2_PIN PE13 // Fan2 -#define FAN3_PIN PE14 // Fan3 - -// -// Misc. Functions -// -#define LED_PIN PA6 -//#define LED_PIN PA7 -#define KILL_PIN PB1 - -// -// LCD / Controller -// -//#define SD_DETECT_PIN PC5 -//#define SD_DETECT_PIN PA8 // SDIO SD_DETECT_PIN, external SDIO card reader only - -#define BEEPER_PIN PD10 -#define LCD_PINS_RS PE15 -#define LCD_PINS_ENABLE PD8 -#define LCD_PINS_D4 PE10 -#define LCD_PINS_D5 PE12 -#define LCD_PINS_D6 PD1 -#define LCD_PINS_D7 PE8 -#define BTN_ENC PD9 -#define BTN_EN1 PD4 -#define BTN_EN2 PD13 - -#define DOGLCD_CS LCD_PINS_D5 -#define DOGLCD_A0 LCD_PINS_D6 - -// -// Onboard SD support -// -#define SDIO_D0_PIN PC8 -#define SDIO_D1_PIN PC9 -#define SDIO_D2_PIN PC10 -#define SDIO_D3_PIN PC11 -#define SDIO_CK_PIN PC12 -#define SDIO_CMD_PIN PD2 - -#if !defined(SDCARD_CONNECTION) || SDCARD_CONNECTION == ONBOARD - #define SDIO_SUPPORT // Use SDIO for onboard SD - - #ifndef SDIO_SUPPORT - #define SOFTWARE_SPI // Use soft SPI for onboard SD - #define SDSS SDIO_D3_PIN - #define SCK_PIN SDIO_CK_PIN - #define MISO_PIN SDIO_D0_PIN - #define MOSI_PIN SDIO_CMD_PIN - #endif -#endif diff --git a/Marlin/src/pins/stm32/pins_BTT_BTT002_V1_0.h b/Marlin/src/pins/stm32/pins_BTT_BTT002_V1_0.h deleted file mode 100644 index bfae524743a8..000000000000 --- a/Marlin/src/pins/stm32/pins_BTT_BTT002_V1_0.h +++ /dev/null @@ -1,253 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#ifndef TARGET_STM32F4 - #error "Oops! Select an STM32F4 board in 'Tools > Board.'" -#elif HOTENDS > 1 || E_STEPPERS > 1 - #error "BIGTREE BTT002 V1.0 supports up to 1 hotends / E-steppers." -#endif - -#define BOARD_INFO_NAME "BIGTREE Btt002 1.0" - -// Use one of these or SDCard-based Emulation will be used -//#define SRAM_EEPROM_EMULATION // Use BackSRAM-based EEPROM emulation -#define FLASH_EEPROM_EMULATION // Use Flash-based EEPROM emulation - -// Ignore temp readings during development. -//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 - -// -// Limit Switches -// -#define X_STOP_PIN PD3 -#define Y_STOP_PIN PD2 -#define Z_STOP_PIN PD1 // Shares J4 connector with PC3 - -// -// Z Probe must be this pin -// -#ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN PD1 -#endif - -// -// Filament Runout Sensor -// -#ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN PA15 -#endif - -// -// Power Loss Detection -// -#ifndef POWER_LOSS_PIN - #define POWER_LOSS_PIN PD4 -#endif - -// -// Steppers -// -#define X_STEP_PIN PA9 -#define X_DIR_PIN PA10 -#define X_ENABLE_PIN PA8 -#ifndef X_CS_PIN - #define X_CS_PIN PE2 -#endif - -#define Y_STEP_PIN PC8 -#define Y_DIR_PIN PC9 -#define Y_ENABLE_PIN PC7 - #ifndef Y_CS_PIN - #define Y_CS_PIN PE3 -#endif - -#define Z_STEP_PIN PD15 -#define Z_DIR_PIN PC6 -#define Z_ENABLE_PIN PD14 -#ifndef Z_CS_PIN - #define Z_CS_PIN PE4 -#endif - -#define E0_STEP_PIN PD12 -#define E0_DIR_PIN PD13 -#define E0_ENABLE_PIN PD11 -#ifndef E0_CS_PIN - #define E0_CS_PIN PD7 -#endif - -// -// Software SPI pins for TMC2130 stepper drivers -// -#if ENABLED(TMC_USE_SW_SPI) - #ifndef TMC_SW_MOSI - #define TMC_SW_MOSI PB15 - #endif - #ifndef TMC_SW_MISO - #define TMC_SW_MISO PB14 - #endif - #ifndef TMC_SW_SCK - #define TMC_SW_SCK PB13 - #endif -#endif - -#if HAS_TMC220x - /** - * TMC2208/TMC2209 stepper drivers - * - * Hardware serial communication ports. - * If undefined software serial is used according to the pins below - */ - //#define X_HARDWARE_SERIAL Serial1 - //#define X2_HARDWARE_SERIAL Serial1 - //#define Y_HARDWARE_SERIAL Serial1 - //#define Y2_HARDWARE_SERIAL Serial1 - //#define Z_HARDWARE_SERIAL Serial1 - //#define Z2_HARDWARE_SERIAL Serial1 - //#define E0_HARDWARE_SERIAL Serial1 - //#define E1_HARDWARE_SERIAL Serial1 - //#define E2_HARDWARE_SERIAL Serial1 - //#define E3_HARDWARE_SERIAL Serial1 - //#define E4_HARDWARE_SERIAL Serial1 - - // - // Software serial ## - // - #define X_SERIAL_TX_PIN PE2 - #define X_SERIAL_RX_PIN PE2 - - #define Y_SERIAL_TX_PIN PE3 - #define Y_SERIAL_RX_PIN PE3 - - #define Z_SERIAL_TX_PIN PE4 - #define Z_SERIAL_RX_PIN PE4 - - #define E0_SERIAL_TX_PIN PD7 - #define E0_SERIAL_RX_PIN PD7 - - // Reduce baud rate to improve software serial reliability - #define TMC_BAUD_RATE 19200 -#endif - -// -// Temperature Sensors -// -#define TEMP_0_PIN PA2 // T0 <-> E0 -#define TEMP_1_PIN PA0 // T1 <-> E1 -#define TEMP_BED_PIN PA1 // T2 <-> Bed -#define TEMP_PROBE_PIN PC3 // Shares J4 connector with PD1 - -// -// Heaters / Fans -// -#define HEATER_0_PIN PE6 // Heater0 -#define HEATER_BED_PIN PE5 // Hotbed -#define FAN_PIN PB8 // Fan1 -#define FAN1_PIN PB9 // Fan0 - -// HAL SPI1 pins -#define CUSTOM_SPI_PINS -#if ENABLED(CUSTOM_SPI_PINS) - #define SCK_PIN PA5 // SPI1 SCLK - #define SS_PIN PA4 // SPI1 SSEL - #define MISO_PIN PA6 // SPI1 MISO - #define MOSI_PIN PA7 // SPI1 MOSI -#endif - -// -// Misc. Functions -// -#define SDSS PA4 - -/** - * -------------------------------------BTT002 V1.0----------------------------------------------- - * _____ _____ | - * PA3 | · · | GND 5V | · · | GND | - * NRESET | · · | PC4(SD_DET) (LCD_D7) PE13 | · · | PE12 (LCD_D6) | - * (MOSI)PA7 | · · | PB0(BTN_EN2) (LCD_D5) PE11 | · · | PE10 (LCD_D4) | - * (SD_SS)PA4 | · · | PC5(BTN_EN1) (LCD_RS) PE8 | · · | PE9 (LCD_EN) | - * (SCK)PA5 | · · | PA6(MISO) (BTN_ENC) PB1 | · · | PE7 (BEEPER) | - *  ̄ ̄  ̄ ̄ | - * EXP2 EXP1 | - * --------------------------------------------------------------------------------------------- - */ -// -// LCDs and Controllers -// -#if HAS_SPI_LCD - #define BEEPER_PIN PE7 - #define BTN_ENC PB1 - - #if ENABLED(CR10_STOCKDISPLAY) - #define LCD_PINS_RS PE12 - - #define BTN_EN1 PE9 - #define BTN_EN2 PE10 - - #define LCD_PINS_ENABLE PE13 - #define LCD_PINS_D4 PE11 - - #else - - #define LCD_PINS_RS PE8 - - #define BTN_EN1 PC5 - #define BTN_EN2 PB0 - #define SD_DETECT_PIN PC4 - - #define LCD_SDSS PA4 - - #define LCD_PINS_ENABLE PE9 - #define LCD_PINS_D4 PE10 - - #if ENABLED(ULTIPANEL) - #define LCD_PINS_D5 PE11 - #define LCD_PINS_D6 PE12 - #define LCD_PINS_D7 PE13 - #endif - - #endif - - // Alter timing for graphical display - #if HAS_GRAPHICAL_LCD - #define BOARD_ST7920_DELAY_1 DELAY_NS(96) - #define BOARD_ST7920_DELAY_2 DELAY_NS(48) - #define BOARD_ST7920_DELAY_3 DELAY_NS(600) - #endif - -#endif // HAS_SPI_LCD - -// -// RGB LEDs -// -#ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN PB5 -#endif -#ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN PB4 -#endif -#ifndef RGB_LED_B_PIN - #define RGB_LED_B_PIN PB3 -#endif -#ifndef RGB_LED_W_PIN - #define RGB_LED_W_PIN -1 -#endif diff --git a/Marlin/src/pins/stm32/pins_BTT_GTR_V1_0.h b/Marlin/src/pins/stm32/pins_BTT_GTR_V1_0.h deleted file mode 100644 index aa2152c84fae..000000000000 --- a/Marlin/src/pins/stm32/pins_BTT_GTR_V1_0.h +++ /dev/null @@ -1,391 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#ifndef TARGET_STM32F4 - #error "Oops! Select an STM32F4 board in 'Tools > Board.'" -#elif HOTENDS > 8 || E_STEPPERS > 8 - #error "BIGTREE GTR V1.0 supports up to 8 hotends / E-steppers." -#elif HOTENDS > MAX_EXTRUDERS || E_STEPPERS > MAX_EXTRUDERS - #error "Marlin extruder/hotends limit! Increase MAX_EXTRUDERS to continue." -#endif - -#define BOARD_INFO_NAME "BIGTREE GTR 1.0" - -// Use one of these or SDCard-based Emulation will be used -//#define I2C_EEPROM -//#define SRAM_EEPROM_EMULATION // Use BackSRAM-based EEPROM emulation -//#define FLASH_EEPROM_EMULATION // Use Flash-based EEPROM emulation - -#define TP // Enable to define servo and probe pins - -// -// Servos -// -#if ENABLED(TP) - #define SERVO0_PIN PB11 -#endif - -#define PS_ON_PIN PH6 - -// -// Limit Switches -// -#define X_MIN_PIN PF2 -#define X_MAX_PIN PG14 -#define Y_MIN_PIN PC13 -#define Y_MAX_PIN PG9 -#define Z_MIN_PIN PE0 -#define Z_MAX_PIN PD3 - -// -// Pins on the extender -// -//#define X_MIN_PIN PI4 -//#define X2_MIN_PIN PF12 -//#define Y_MIN_PIN PF4 -//#define Y2_MIN_PIN PI7 -//#define Z_MIN_PIN PF6 - -#if ENABLED(TP) && !defined(Z_MIN_PROBE_PIN) - #define Z_MIN_PROBE_PIN PH11 // Z Probe must be PH11 -#endif - -// -// Steppers -// -#define X_STEP_PIN PC15 -#define X_DIR_PIN PF0 -#define X_ENABLE_PIN PF1 -#ifndef X_CS_PIN - #define X_CS_PIN PC14 -#endif - -#define Y_STEP_PIN PE3 -#define Y_DIR_PIN PE2 -#define Y_ENABLE_PIN PE4 -#ifndef Y_CS_PIN - #define Y_CS_PIN PE1 -#endif - -#define Z_STEP_PIN PB8 -#define Z_DIR_PIN PB7 // PB7 -#define Z_ENABLE_PIN PB9 -#ifndef Z_CS_PIN - #define Z_CS_PIN PB5 -#endif - -#define E0_STEP_PIN PG12 -#define E0_DIR_PIN PG11 -#define E0_ENABLE_PIN PG13 -#ifndef E0_CS_PIN - #define E0_CS_PIN PG10 -#endif - -#define E1_STEP_PIN PD6 -#define E1_DIR_PIN PD5 -#define E1_ENABLE_PIN PD7 -#ifndef E1_CS_PIN - #define E1_CS_PIN PD4 -#endif - -#define E2_STEP_PIN PD1 -#define E2_DIR_PIN PD0 -#define E2_ENABLE_PIN PD2 -#ifndef E2_CS_PIN - #define E2_CS_PIN PC12 -#endif - -#define E3_STEP_PIN PF3 -#define E3_DIR_PIN PG3 -#define E3_ENABLE_PIN PF8 -#ifndef E3_CS_PIN - #define E3_CS_PIN PG4 -#endif - -#define E4_STEP_PIN PD14 -#define E4_DIR_PIN PD11 -#define E4_ENABLE_PIN PG2 -#ifndef E4_CS_PIN - #define E4_CS_PIN PE15 -#endif - -#define E5_STEP_PIN PE12 -#define E5_DIR_PIN PE10 -#define E5_ENABLE_PIN PF14 -#ifndef E5_CS_PIN - #define E5_CS_PIN PE7 -#endif - -#define E6_STEP_PIN PG0 -#define E6_DIR_PIN PG1 -#define E6_ENABLE_PIN PE8 -#ifndef E6_CS_PIN - #define E6_CS_PIN PF15 -#endif - -#define E7_STEP_PIN PH12 -#define E7_DIR_PIN PH15 -#define E7_ENABLE_PIN PI0 -#ifndef E7_CS_PIN - #define E7_CS_PIN PH14 -#endif - -// -// Software SPI pins for TMC2130 stepper drivers -// -#if ENABLED(TMC_USE_SW_SPI) - #ifndef TMC_SW_MOSI - #define TMC_SW_MOSI PG15 - #endif - #ifndef TMC_SW_MISO - #define TMC_SW_MISO PB6 - #endif - #ifndef TMC_SW_SCK - #define TMC_SW_SCK PB3 - #endif -#endif - -#if HAS_TMC220x - /** - * TMC2208/TMC2209 stepper drivers - * - * Hardware serial communication ports. - * If undefined software serial is used according to the pins below - */ - //#define X_HARDWARE_SERIAL Serial - //#define X2_HARDWARE_SERIAL Serial1 - //#define Y_HARDWARE_SERIAL Serial1 - //#define Y2_HARDWARE_SERIAL Serial1 - //#define Z_HARDWARE_SERIAL Serial1 - //#define Z2_HARDWARE_SERIAL Serial1 - //#define E0_HARDWARE_SERIAL Serial1 - //#define E1_HARDWARE_SERIAL Serial1 - //#define E2_HARDWARE_SERIAL Serial1 - //#define E3_HARDWARE_SERIAL Serial1 - //#define E4_HARDWARE_SERIAL Serial1 - //#define E5_HARDWARE_SERIAL Serial1 - //#define E6_HARDWARE_SERIAL Serial1 - //#define E7_HARDWARE_SERIAL Serial1 - - // - // Software serial - // - #define X_SERIAL_TX_PIN PC14 - #define X_SERIAL_RX_PIN PC14 - - #define Y_SERIAL_TX_PIN PE1 - #define Y_SERIAL_RX_PIN PE1 - - #define Z_SERIAL_TX_PIN PB5 - #define Z_SERIAL_RX_PIN PB5 - - #define E0_SERIAL_TX_PIN PG10 - #define E0_SERIAL_RX_PIN PG10 - - #define E1_SERIAL_TX_PIN PD4 - #define E1_SERIAL_RX_PIN PD4 - - #define E2_SERIAL_TX_PIN PC12 - #define E2_SERIAL_RX_PIN PC12 - - #define E3_SERIAL_TX_PIN PG4 - #define E3_SERIAL_RX_PIN PG4 - - #define E4_SERIAL_TX_PIN PE15 - #define E4_SERIAL_RX_PIN PE15 - - #define E5_SERIAL_TX_PIN PE7 - #define E5_SERIAL_RX_PIN PE7 - - #define E6_SERIAL_TX_PIN PF15 - #define E6_SERIAL_RX_PIN PF15 - - #define E7_SERIAL_TX_PIN PH14 - #define E7_SERIAL_RX_PIN PH14 - - // Reduce baud rate to improve software serial reliability - #define TMC_BAUD_RATE 19200 -#endif - -// -// Temperature Sensors -// -#define TEMP_0_PIN PC1 // T1 <-> E0 -#define TEMP_1_PIN PC2 // T2 <-> E1 -#define TEMP_2_PIN PC3 // T3 <-> E2 - -#define TEMP_3_PIN PA3 // T4 <-> E3 -#define TEMP_4_PIN PF9 // T5 <-> E4 -#define TEMP_5_PIN PF10 // T6 <-> E5 -//#define TEMP_6_PIN PF7 // T7 <-> E6 -//#define TEMP_7_PIN PF5 // T8 <-> E7 - -#define TEMP_BED_PIN PC0 // T0 <-> Bed - -// SPI for Max6675 or Max31855 Thermocouple -// Uses a separate SPI bus -// If you have a two-way thermocouple, you can customize two THERMO_CSx_PIN pins (x:1~2) - -#define THERMO_SCK_PIN PI1 // SCK -#define THERMO_DO_PIN PI2 // MISO -#define THERMO_CS1_PIN PH9 // CS1 -#define THERMO_CS2_PIN PH2 // CS2 - -#define MAX6675_SS_PIN THERMO_CS1_PIN -#define MAX6675_SS2_PIN THERMO_CS2_PIN -#define MAX6675_SCK_PIN THERMO_SCK_PIN -#define MAX6675_DO_PIN THERMO_DO_PIN - -// -// Heaters / Fans -// -#define HEATER_0_PIN PB1 // Heater0 -#define HEATER_1_PIN PA1 // Heater1 -#define HEATER_2_PIN PB0 // Heater2 - -#define HEATER_3_PIN PD15 // Heater3 -#define HEATER_4_PIN PD13 // Heater4 -#define HEATER_5_PIN PD12 // Heater5 -//#define HEATER_6_PIN PE13 // Heater6 -//#define HEATER_7_PIN PI6 // Heater7 - -#define HEATER_BED_PIN PA2 // Hotbed - -#define FAN_PIN PE5 // Fan0 -#define FAN1_PIN PE6 // Fan1 -#define FAN2_PIN PC8 // Fan2 - -#define FAN3_PIN PI5 // Fan3 -#define FAN4_PIN PE9 // Fan4 -#define FAN5_PIN PE11 // Fan5 -//#define FAN6_PIN PC9 // Fan6 -//#define FAN7_PIN PE14 // Fan7 - -// -// By default the onboard SD (SPI1) is enabled -// -#define CUSTOM_SPI_PINS -#if DISABLED(CUSTOM_SPI_PINS) - #define SDSS PB12 -#endif - -// HAL SPI1 pins group -#if ENABLED(CUSTOM_SPI_PINS) - #define SDSS PA4 - #define SD_DETECT_PIN PC4 - #define LCD_SDSS PA4 - - #define SCK_PIN PA5 - #define MISO_PIN PA6 - #define MOSI_PIN PA7 - #define SS_PIN PA4 // Chip select for SD card used by Marlin -#endif - -/** - * _____ _____ - * NC | · · | GND 5V | · · | GND - * RESET | · · | PB10(SD_DETECT) (LCD_D7) PG5 | · · | PG6 (LCD_D6) - * (MOSI)PB15 | · · | PH10(BTN_EN2) (LCD_D5) PG7 | · · | PG8 (LCD_D4) - * (SD_SS)PB12 | · · | PD10(BTN_EN1) (LCD_RS) PA8 | · · | PC10 (LCD_EN) - * (SCK)PB13 | · · | PB14(MISO) (BTN_ENC) PA15 | · · | PC11 (BEEPER) - *  ̄ ̄  ̄ ̄ - * EXP2 EXP1 - */ - -// -// LCDs and Controllers -// -#if HAS_SPI_LCD - #define BEEPER_PIN PC11 - #define BTN_ENC PA15 - - #if ENABLED(CR10_STOCKDISPLAY) - - #define LCD_PINS_RS PA8 - - #define BTN_EN1 PD10 - #define BTN_EN2 PH10 - - #define LCD_PINS_ENABLE PG7 - #define LCD_PINS_D4 PG8 - - //#undef ST7920_DELAY_1 - //#undef ST7920_DELAY_2 - //#undef ST7920_DELAY_3 - - #else - - #define LCD_PINS_RS PA8 - - #define BTN_EN1 PD10 - #define BTN_EN2 PH10 - - #if DISABLED(CUSTOM_SPI_PINS) - #define SD_DETECT_PIN PB10 - #define LCD_SDSS PB12 - #endif - - #define LCD_PINS_ENABLE PC10 - #define LCD_PINS_D4 PG8 - - #if ENABLED(FYSETC_MINI_12864) - #define DOGLCD_CS PC10 - #define DOGLCD_A0 PA8 - //#define LCD_BACKLIGHT_PIN -1 - #define LCD_RESET_PIN PG8 // Must be high or open for LCD to operate normally. - #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) - #ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN PG7 - #endif - #ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN PG6 - #endif - #ifndef RGB_LED_B_PIN - #define RGB_LED_B_PIN PG5 - #endif - #elif ENABLED(FYSETC_MINI_12864_2_1) - #define NEOPIXEL_PIN PF13 - #endif - #endif // !FYSETC_MINI_12864 - - #if ENABLED(ULTIPANEL) - #define LCD_PINS_D5 PG7 - #define LCD_PINS_D6 PG6 - #define LCD_PINS_D7 PG5 - #endif - - #endif - - // Alter timing for graphical display - #if HAS_GRAPHICAL_LCD - #define BOARD_ST7920_DELAY_1 DELAY_NS(96) - #define BOARD_ST7920_DELAY_2 DELAY_NS(48) - #define BOARD_ST7920_DELAY_3 DELAY_NS(600) - #endif - - //#define DOGLCD_CS PB12 - //#define DOGLCD_A0 PA8 - //#define LCD_PINS_DC PB14 - //#define DOGLCD_MOSI PB15 - -#endif // HAS_SPI_LCD diff --git a/Marlin/src/pins/stm32/pins_BTT_SKR_E3_DIP.h b/Marlin/src/pins/stm32/pins_BTT_SKR_E3_DIP.h deleted file mode 100644 index f5c35bbdcdd6..000000000000 --- a/Marlin/src/pins/stm32/pins_BTT_SKR_E3_DIP.h +++ /dev/null @@ -1,233 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#ifndef TARGET_STM32F1 - #error "Oops! Select an STM32F1 board in 'Tools > Board.'" -#endif - -#define BOARD_INFO_NAME "BIGTREE SKR E3 DIP V1.0" - -// Release PB3/PB4 (TMC_SW Pins) from JTAG pins -#define DISABLE_JTAG - -// Ignore temp readings during development. -//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 - -#define FLASH_EEPROM_EMULATION -#define EEPROM_PAGE_SIZE uint16(0x800) // 2KB -#define EEPROM_START_ADDRESS uint32(0x8000000 + (STM32_FLASH_SIZE) * 1024 - 2 * EEPROM_PAGE_SIZE) -#undef E2END -#define E2END (EEPROM_PAGE_SIZE - 1) // 2KB - -// -// Servos -// -#define SERVO0_PIN PA1 // SERVOS - -// -// Limit Switches -// -#define X_STOP_PIN PC1 // X-STOP -#define Y_STOP_PIN PC0 // Y-STOP -#define Z_STOP_PIN PC15 // Z-STOP - -// -// Z Probe must be this pin -// -#define Z_MIN_PROBE_PIN PC14 // PROBE - -// -// Filament Runout Sensor -// -#ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN PC2 // E0-STOP -#endif - -// -// Steppers -// -#define X_ENABLE_PIN PC7 -#define X_STEP_PIN PC6 -#define X_DIR_PIN PB15 -#ifndef X_CS_PIN - #define X_CS_PIN PC10 -#endif - -#define Y_ENABLE_PIN PB14 -#define Y_STEP_PIN PB13 -#define Y_DIR_PIN PB12 -#ifndef Y_CS_PIN - #define Y_CS_PIN PC11 -#endif - -#define Z_ENABLE_PIN PB11 -#define Z_STEP_PIN PB10 -#define Z_DIR_PIN PB2 -#ifndef Z_CS_PIN - #define Z_CS_PIN PC12 -#endif - -#define E0_ENABLE_PIN PB1 -#define E0_STEP_PIN PB0 -#define E0_DIR_PIN PC5 -#ifndef E0_CS_PIN - #define E0_CS_PIN PD2 -#endif - -// -// Software SPI pins for TMC2130 stepper drivers -// -#if ENABLED(TMC_USE_SW_SPI) - #ifndef TMC_SW_MOSI - #define TMC_SW_MOSI PB5 - #endif - #ifndef TMC_SW_MISO - #define TMC_SW_MISO PB4 - #endif - #ifndef TMC_SW_SCK - #define TMC_SW_SCK PB3 - #endif -#endif - -#if HAS_TMC220x - /** - * TMC2208/TMC2209 stepper drivers - * - * Hardware serial communication ports. - * If undefined software serial is used according to the pins below - */ - //#define X_HARDWARE_SERIAL Serial1 - //#define Y_HARDWARE_SERIAL Serial1 - //#define Z_HARDWARE_SERIAL Serial1 - //#define E0_HARDWARE_SERIAL Serial1 - - // - // Software serial - // - #define X_SERIAL_TX_PIN PC10 - #define X_SERIAL_RX_PIN PC10 - - #define Y_SERIAL_TX_PIN PC11 - #define Y_SERIAL_RX_PIN PC11 - - #define Z_SERIAL_TX_PIN PC12 - #define Z_SERIAL_RX_PIN PC12 - - #define E0_SERIAL_TX_PIN PD2 - #define E0_SERIAL_RX_PIN PD2 - - // Reduce baud rate to improve software serial reliability - #define TMC_BAUD_RATE 19200 -#endif - -// -// Temperature Sensors -// -#define TEMP_0_PIN PA0 // Analog Input "TH0" -#define TEMP_BED_PIN PC3 // Analog Input "TB0" - -// -// Heaters / Fans -// -#define HEATER_0_PIN PC8 // HE -#define HEATER_BED_PIN PC9 // HB -#define FAN_PIN PA8 // FAN0 - -// -// USB connect control -// -#define USB_CONNECT_PIN PC13 -#define USB_CONNECT_INVERTING false - -#define SD_DETECT_PIN PC4 - -/** - * _____ - * 5V | 1 2 | GND - * (LCD_EN) PB7 | 3 4 | PB8 (LCD_RS) - * (LCD_D4) PB9 | 5 6 PA10 (BTN_EN2) - * RESET | 7 8 | PA9 (BTN_EN1) - * (BTN_ENC) PB6 | 9 10| PA15 (BEEPER) - * ----- - * EXP1 - */ - -#define EXPA1_03_PIN PB7 -#define EXPA1_04_PIN PB8 -#define EXPA1_05_PIN PB9 -#define EXPA1_06_PIN PA10 -#define EXPA1_07_PIN -1 -#define EXPA1_08_PIN PA9 -#define EXPA1_09_PIN PB6 -#define EXPA1_10_PIN PA15 - -#if HAS_SPI_LCD - #define BTN_ENC EXPA1_09_PIN - #define BTN_EN1 EXPA1_08_PIN - #define BTN_EN2 EXPA1_06_PIN - - #if ENABLED(CR10_STOCKDISPLAY) - - #define BEEPER_PIN EXPA1_10_PIN - - #define LCD_PINS_RS EXPA1_04_PIN - #define LCD_PINS_ENABLE EXPA1_03_PIN - #define LCD_PINS_D4 EXPA1_05_PIN - - #elif EITHER(MKS_MINI_12864, ENDER2_STOCKDISPLAY) - - /** Creality Ender-2 display pinout - * _____ - * 5V | 1 2 | GND - * (MOSI) PB7 | 3 4 | PB8 (LCD_RS) - * (LCD_A0) PB9 | 5 6 PA10 (BTN_EN2) - * RESET | 7 8 | PA9 (BTN_EN1) - * (BTN_ENC) PB6 | 9 10| PA15 (SCK) - * ----- - * EXP1 - */ - - #define DOGLCD_CS EXPA1_04_PIN - #define DOGLCD_A0 EXPA1_05_PIN - #define DOGLCD_SCK EXPA1_10_PIN - #define DOGLCD_MOSI EXPA1_03_PIN - #define FORCE_SOFT_SPI - #define LCD_BACKLIGHT_PIN -1 - - #else - #error "Only CR10_STOCKDISPLAY, ENDER2_STOCKDISPLAY, and MKS_MINI_12864 are currently supported on the BIGTREE_SKR_E3_DIP." - #endif - -#endif // HAS_SPI_LCD - -// -// SD Support -// -#define HAS_ONBOARD_SD - -#ifndef SDCARD_CONNECTION - #define SDCARD_CONNECTION ONBOARD -#endif - -#define ON_BOARD_SPI_DEVICE 1 //SPI1 -#define ONBOARD_SD_CS_PIN PA4 // Chip select for "System" SD card diff --git a/Marlin/src/pins/stm32/pins_BTT_SKR_MINI_E3.h b/Marlin/src/pins/stm32/pins_BTT_SKR_MINI_E3.h deleted file mode 100644 index 77a412ad613b..000000000000 --- a/Marlin/src/pins/stm32/pins_BTT_SKR_MINI_E3.h +++ /dev/null @@ -1,191 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#ifndef TARGET_STM32F1 - #error "Oops! Select an STM32F1 board in 'Tools > Board.'" -#endif - -// Release PB3/PB4 (E0 STP/DIR) from JTAG pins -#define DISABLE_JTAG - -// Ignore temp readings during development. -//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 - -#define FLASH_EEPROM_EMULATION -#define EEPROM_PAGE_SIZE uint16(0x800) // 2KB -#define EEPROM_START_ADDRESS uint32(0x8000000 + (STM32_FLASH_SIZE) * 1024 - 2 * EEPROM_PAGE_SIZE) -#undef E2END -#define E2END (EEPROM_PAGE_SIZE - 1) // 2KB - -// -// Servos -// -#define SERVO0_PIN PA1 - -// -// Limit Switches -// -#define X_STOP_PIN PC0 -#define Y_STOP_PIN PC1 -#define Z_STOP_PIN PC2 - -// -// Z Probe must be this pins -// -#define Z_MIN_PROBE_PIN PC14 - -// -// Filament Runout Sensor -// -#ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN PC15 // "E0-STOP" -#endif - -// -// Steppers -// -#define X_ENABLE_PIN PB14 -#define X_STEP_PIN PB13 -#define X_DIR_PIN PB12 - -#define Y_ENABLE_PIN PB11 -#define Y_STEP_PIN PB10 -#define Y_DIR_PIN PB2 - -#define Z_ENABLE_PIN PB1 -#define Z_STEP_PIN PB0 -#define Z_DIR_PIN PC5 - -#define E0_ENABLE_PIN PD2 -#define E0_STEP_PIN PB3 -#define E0_DIR_PIN PB4 - -// -// Temperature Sensors -// -#define TEMP_0_PIN PA0 // Analog Input -#define TEMP_BED_PIN PC3 // Analog Input - -// -// Heaters / Fans -// -#define HEATER_0_PIN PC8 // EXTRUDER -#define HEATER_BED_PIN PC9 // BED -#define FAN_PIN PA8 - -// -// USB connect control -// -#define USB_CONNECT_PIN PC13 -#define USB_CONNECT_INVERTING false - -#define SD_DETECT_PIN PC4 - -/** - * _____ - * 5V | 1 2 | GND - * (LCD_EN) PB7 | 3 4 | PB8 (LCD_RS) - * (LCD_D4) PB9 | 5 6 PA10 (BTN_EN2) - * RESET | 7 8 | PA9 (BTN_EN1) - * (BTN_ENC) PB6 | 9 10| PB5 (BEEPER) - * ----- - * EXP1 - */ - -#define EXPA1_03_PIN PB7 -#define EXPA1_04_PIN PB8 -#define EXPA1_05_PIN PB9 -#define EXPA1_06_PIN PA10 -#define EXPA1_07_PIN -1 -#define EXPA1_08_PIN PA9 -#define EXPA1_09_PIN PB6 -#define EXPA1_10_PIN PB5 - -#if HAS_SPI_LCD - - #if ENABLED(CR10_STOCKDISPLAY) - - #define BEEPER_PIN EXPA1_10_PIN - - #define BTN_EN1 EXPA1_08_PIN - #define BTN_EN2 EXPA1_06_PIN - #define BTN_ENC EXPA1_09_PIN - - #define LCD_PINS_RS EXPA1_04_PIN - #define LCD_PINS_ENABLE EXPA1_03_PIN - #define LCD_PINS_D4 EXPA1_05_PIN - - #elif ENABLED(ZONESTAR_LCD) // ANET A8 LCD Controller - Must convert to 3.3V - CONNECTING TO 5V WILL DAMAGE THE BOARD! - - #error "CAUTION! ZONESTAR_LCD requires wiring modifications. See 'pins_BTT_SKR_MINI_E3.h' for details. Comment out this line to continue." - - #define LCD_PINS_RS EXPA1_05_PIN - #define LCD_PINS_ENABLE EXPA1_09_PIN - #define LCD_PINS_D4 EXPA1_04_PIN - #define LCD_PINS_D5 EXPA1_06_PIN - #define LCD_PINS_D6 EXPA1_08_PIN - #define LCD_PINS_D7 EXPA1_10_PIN - #define ADC_KEYPAD_PIN PA1 // Repurpose servo pin for ADC - CONNECTING TO 5V WILL DAMAGE THE BOARD! - - #elif EITHER(MKS_MINI_12864, ENDER2_STOCKDISPLAY) - - /** Creality Ender-2 display pinout - * _____ - * 5V | 1 2 | GND - * (MOSI) PB7 | 3 4 | PB8 (LCD_RS) - * (LCD_A0) PB9 | 5 6 PA10 (BTN_EN2) - * RESET | 7 8 | PA9 (BTN_EN1) - * (BTN_ENC) PB6 | 9 10| PB5 (SCK) - * ----- - * EXP1 - */ - #define BTN_EN1 EXPA1_08_PIN - #define BTN_EN2 EXPA1_06_PIN - #define BTN_ENC EXPA1_09_PIN - - #define DOGLCD_CS EXPA1_04_PIN - #define DOGLCD_A0 EXPA1_05_PIN - #define DOGLCD_SCK EXPA1_10_PIN - #define DOGLCD_MOSI EXPA1_03_PIN - #define FORCE_SOFT_SPI - #define LCD_BACKLIGHT_PIN -1 - - #else - - #error "Only ZONESTAR_LCD, MKS_MINI_12864, ENDER2_STOCKDISPLAY, and CR10_STOCKDISPLAY are currently supported on the BIGTREE_SKR_MINI_E3." - - #endif - -#endif // HAS_SPI_LCD - -// -// SD Support -// -#define HAS_ONBOARD_SD - -#ifndef SDCARD_CONNECTION - #define SDCARD_CONNECTION ONBOARD -#endif - -#define ON_BOARD_SPI_DEVICE 1 // SPI1 -#define ONBOARD_SD_CS_PIN PA4 // Chip select for "System" SD card diff --git a/Marlin/src/pins/stm32/pins_BTT_SKR_MINI_V1_1.h b/Marlin/src/pins/stm32/pins_BTT_SKR_MINI_V1_1.h deleted file mode 100644 index 08f666882eca..000000000000 --- a/Marlin/src/pins/stm32/pins_BTT_SKR_MINI_V1_1.h +++ /dev/null @@ -1,210 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#ifndef TARGET_STM32F1 - #error "Oops! Select an STM32F1 board in 'Tools > Board.'" -#endif - -#define BOARD_INFO_NAME "BIGTREE SKR Mini 1.1" - -//#define DISABLE_DEBUG -#define DISABLE_JTAG - -// Ignore temp readings during development. -//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 - -#define FLASH_EEPROM_EMULATION -#define EEPROM_PAGE_SIZE (0x800) // 2KB -#define EEPROM_START_ADDRESS uint32(0x8000000 + (STM32_FLASH_SIZE) * 1024 - 2 * EEPROM_PAGE_SIZE) -#define E2END (EEPROM_PAGE_SIZE - 1) - -// -// Limit Switches -// -#define X_MIN_PIN PC2 -#define X_MAX_PIN PA2 -#define Y_MIN_PIN PC1 -#define Y_MAX_PIN PA1 -#define Z_MIN_PIN PC0 -#define Z_MAX_PIN PC3 - -// -// Steppers -// - -#define X_STEP_PIN PC6 -#define X_DIR_PIN PC7 -#define X_ENABLE_PIN PB15 - -#define Y_STEP_PIN PB13 -#define Y_DIR_PIN PB14 -#define Y_ENABLE_PIN PB12 - -#define Z_STEP_PIN PB10 -#define Z_DIR_PIN PB11 -#define Z_ENABLE_PIN PB2 - -#define E0_STEP_PIN PC5 -#define E0_DIR_PIN PB0 -#define E0_ENABLE_PIN PC4 - -#if ENABLED(TMC_USE_SW_SPI) - #ifndef TMC_SW_SCK - #define TMC_SW_SCK PB3 - #endif - #ifndef TMC_SW_MISO - #define TMC_SW_MISO PB4 - #endif - #ifndef TMC_SW_MOSI - #define TMC_SW_MOSI PB5 - #endif -#endif - -// -// Heaters / Fans -// -#define HEATER_0_PIN PA8 -#define FAN_PIN PC8 -#define HEATER_BED_PIN PC9 - -// -// Temperature Sensors -// -#define TEMP_BED_PIN PB1 // Analog Input -#define TEMP_0_PIN PA0 // Analog Input - -// -// LCD Pins -// - -/** - * _____ _____ - * NC | · · | GND 5V | · · | GND - * RESET | · · | PB9 (SD_DETECT) (LCD_D7) PC14 | · · | PC15 (LCD_D6) - * (MOSI) PB5 | · · | PB8 (BTN_EN2) (LCD_D5) PB7 | · · | PC13 (LCD_D4) - * (SD_SS) PA15 | · · | PD2 (BTN_EN1) (LCD_RS) PC12 | · · | PB6 (LCD_EN) - * (SCK) PB3 | · · | PB4 (MISO) (BTN_ENC) PC11 | · · | PC10 (BEEPER) - * ----- ----- - * EXP2 EXP1 - */ - -#if HAS_SPI_LCD - #define BEEPER_PIN PC10 - #define BTN_ENC PC11 - - #if ENABLED(CR10_STOCKDISPLAY) - #define LCD_PINS_RS PC15 - - #define BTN_EN1 PB6 - #define BTN_EN2 PC13 - - #define LCD_PINS_ENABLE PC14 - #define LCD_PINS_D4 PB7 - - #else - - #define LCD_PINS_RS PC12 - - #define BTN_EN1 PD2 - #define BTN_EN2 PB8 - - #define LCD_PINS_ENABLE PB6 - - #if ENABLED(FYSETC_MINI_12864) - - #define LCD_BACKLIGHT_PIN -1 - #define LCD_RESET_PIN PC13 - #define DOGLCD_A0 PC12 - #define DOGLCD_CS PB6 - #define DOGLCD_SCK PB3 - #define DOGLCD_MOSI PB5 - - #define FORCE_SOFT_SPI // SPI MODE3 - - #define LED_PIN PB7 // red pwm - //#define LED_PIN PC15 // green - //#define LED_PIN PC14 // blue - - //#if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) - // #ifndef RGB_LED_R_PIN - // #define RGB_LED_R_PIN PB7 - // #endif - // #ifndef RGB_LED_G_PIN - // #define RGB_LED_G_PIN PC15 - // #endif - // #ifndef RGB_LED_B_PIN - // #define RGB_LED_B_PIN PC14 - // #endif - //#elif ENABLED(FYSETC_MINI_12864_2_1) - // #define NEOPIXEL_PIN PB7 - //#endif - - #else // !FYSETC_MINI_12864 - - #define LCD_PINS_D4 PC13 - #if ENABLED(ULTIPANEL) - #define LCD_PINS_D5 PB7 - #define LCD_PINS_D6 PC15 - #define LCD_PINS_D7 PC14 - #endif - - #endif // !FYSETC_MINI_12864 - - #endif - -#endif // HAS_SPI_LCD - -// -// SD Card -// - -// By default the onboard SD is enabled. -// set SDCARD_CONNECTION form 'ONBOARD' to 'LCD' and use an external SD (connected to LCD) -#define HAS_ONBOARD_SD -#ifndef SDCARD_CONNECTION - #define SDCARD_CONNECTION ONBOARD -#endif - -#if SD_CONNECTION_IS(LCD) - #define ENABLE_SPI3 - #define SD_DETECT_PIN PB9 - #define SCK_PIN PB3 - #define MISO_PIN PB4 - #define MOSI_PIN PB5 - #define SS_PIN PA15 -#elif SD_CONNECTION_IS(ONBOARD) - #define ENABLE_SPI1 - #define SD_DETECT_PIN PA3 - #define SCK_PIN PA5 - #define MISO_PIN PA6 - #define MOSI_PIN PA7 - #define SS_PIN PA4 -#endif -#define ON_BOARD_SPI_DEVICE 1 //SPI1 -#define ONBOARD_SD_CS_PIN PA4 // Chip select for "System" SD card - -#if HAS_GRAPHICAL_LCD - #define BOARD_ST7920_DELAY_1 DELAY_NS(125) - #define BOARD_ST7920_DELAY_2 DELAY_NS(125) - #define BOARD_ST7920_DELAY_3 DELAY_NS(125) -#endif diff --git a/Marlin/src/pins/stm32/pins_BTT_SKR_PRO_V1_1.h b/Marlin/src/pins/stm32/pins_BTT_SKR_PRO_V1_1.h deleted file mode 100644 index 8222bbe14392..000000000000 --- a/Marlin/src/pins/stm32/pins_BTT_SKR_PRO_V1_1.h +++ /dev/null @@ -1,286 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#ifndef TARGET_STM32F4 - #error "Oops! Select an STM32F4 board in 'Tools > Board.'" -#elif HOTENDS > 3 || E_STEPPERS > 3 - #error "BIGTREE SKR Pro V1.1 supports up to 3 hotends / E-steppers." -#endif - -#define BOARD_INFO_NAME "BIGTREE SKR Pro 1.1" // redefined? - -// Use one of these or SDCard-based Emulation will be used -//#define SRAM_EEPROM_EMULATION // Use BackSRAM-based EEPROM emulation -//#define FLASH_EEPROM_EMULATION // Use Flash-based EEPROM emulation - -// -// Servos -// -#define SERVO0_PIN PA1 - -// -// Limit Switches -// -#define X_MIN_PIN PB10 -#define X_MAX_PIN PE15 -#define Y_MIN_PIN PE12 -#define Y_MAX_PIN PE10 -#define Z_MIN_PIN PG8 -#define Z_MAX_PIN PG5 - -// -// Z Probe must be this pins -// -#ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN PA2 -#endif - -// -// Steppers -// -#define X_STEP_PIN PE9 -#define X_DIR_PIN PF1 -#define X_ENABLE_PIN PF2 -#ifndef X_CS_PIN - #define X_CS_PIN PA15 -#endif - -#define Y_STEP_PIN PE11 -#define Y_DIR_PIN PE8 -#define Y_ENABLE_PIN PD7 - #ifndef Y_CS_PIN - #define Y_CS_PIN PB8 -#endif - -#define Z_STEP_PIN PE13 -#define Z_DIR_PIN PC2 -#define Z_ENABLE_PIN PC0 -#ifndef Z_CS_PIN - #define Z_CS_PIN PB9 -#endif - -#define E0_STEP_PIN PE14 -#define E0_DIR_PIN PA0 -#define E0_ENABLE_PIN PC3 -#ifndef E0_CS_PIN - #define E0_CS_PIN PB3 -#endif - -#define E1_STEP_PIN PD15 -#define E1_DIR_PIN PE7 -#define E1_ENABLE_PIN PA3 -#ifndef E1_CS_PIN - #define E1_CS_PIN PG15 -#endif - -#define E2_STEP_PIN PD13 -#define E2_DIR_PIN PG9 -#define E2_ENABLE_PIN PF0 -#ifndef E2_CS_PIN - #define E2_CS_PIN PG12 -#endif - -// -// Software SPI pins for TMC2130 stepper drivers -// -#if ENABLED(TMC_USE_SW_SPI) - #ifndef TMC_SW_MOSI - #define TMC_SW_MOSI PC12 - #endif - #ifndef TMC_SW_MISO - #define TMC_SW_MISO PC11 - #endif - #ifndef TMC_SW_SCK - #define TMC_SW_SCK PC10 - #endif -#endif - -#if HAS_TMC220x - /** - * TMC2208/TMC2209 stepper drivers - * - * Hardware serial communication ports. - * If undefined software serial is used according to the pins below - */ - //#define X_HARDWARE_SERIAL Serial - //#define X2_HARDWARE_SERIAL Serial1 - //#define Y_HARDWARE_SERIAL Serial1 - //#define Y2_HARDWARE_SERIAL Serial1 - //#define Z_HARDWARE_SERIAL Serial1 - //#define Z2_HARDWARE_SERIAL Serial1 - //#define E0_HARDWARE_SERIAL Serial1 - //#define E1_HARDWARE_SERIAL Serial1 - //#define E2_HARDWARE_SERIAL Serial1 - //#define E3_HARDWARE_SERIAL Serial1 - //#define E4_HARDWARE_SERIAL Serial1 - - // - // Software serial - // - #define X_SERIAL_TX_PIN PC13 - #define X_SERIAL_RX_PIN PC13 - - #define Y_SERIAL_TX_PIN PE3 - #define Y_SERIAL_RX_PIN PE3 - - #define Z_SERIAL_TX_PIN PE1 - #define Z_SERIAL_RX_PIN PE1 - - #define E0_SERIAL_TX_PIN PD4 - #define E0_SERIAL_RX_PIN PD4 - - #define E1_SERIAL_TX_PIN PD1 - #define E1_SERIAL_RX_PIN PD1 - - #define E2_SERIAL_TX_PIN PD6 - #define E2_SERIAL_RX_PIN PD6 - - // Reduce baud rate to improve software serial reliability - #define TMC_BAUD_RATE 19200 -#endif - -// -// Temperature Sensors -// -#define TEMP_0_PIN PF4 // T1 <-> E0 -#define TEMP_1_PIN PF5 // T2 <-> E1 -#define TEMP_2_PIN PF6 // T3 <-> E2 -#define TEMP_BED_PIN PF3 // T0 <-> Bed - -// -// Heaters / Fans -// -#define HEATER_0_PIN PB1 // Heater0 -#define HEATER_1_PIN PD14 // Heater1 -#define HEATER_2_PIN PB0 // Heater1 -#define HEATER_BED_PIN PD12 // Hotbed -#define FAN_PIN PC8 // Fan0 -#define FAN1_PIN PE5 // Fan1 -#define FAN2_PIN PE6 // Fan2 - -// -// Misc. Functions -// - -#ifndef SDCARD_CONNECTION - #define SDCARD_CONNECTION LCD -#endif - -// -// Onboard SD card -// NOT compatible with LCD -// -#if SDCARD_CONNECTION == ONBOARD && !defined(HAS_SPI_LCD) - #define SOFTWARE_SPI // Use soft SPI for onboard SD - #define SDSS PA4 - #define SCK_PIN PA5 - #define MISO_PIN PA6 - #define MOSI_PIN PB5 -#else - #define SDSS PB12 -#endif - - -/** - * _____ _____ - * NC | · · | GND 5V | · · | GND - * RESET | · · | PF12(SD_DETECT) (LCD_D7) PG7 | · · | PG6 (LCD_D6) - * (MOSI)PB15 | · · | PF11(BTN_EN2) (LCD_D5) PG3 | · · | PG2 (LCD_D4) - * (SD_SS)PB12 | · · | PG10(BTN_EN1) (LCD_RS) PD10 | · · | PD11 (LCD_EN) - * (SCK)PB13 | · · | PB14(MISO) (BTN_ENC) PA8 | · · | PG4 (BEEPER) - *  ̄ ̄  ̄ ̄ - * EXP2 EXP1 - */ - -// -// LCDs and Controllers -// -#if HAS_SPI_LCD - #define BEEPER_PIN PG4 - #define BTN_ENC PA8 - - #if ENABLED(CR10_STOCKDISPLAY) - #define LCD_PINS_RS PG6 - - #define BTN_EN1 PD11 - #define BTN_EN2 PG2 - - #define LCD_PINS_ENABLE PG7 - #define LCD_PINS_D4 PG3 - - // CR10_Stock Display needs a different delay setting on SKR PRO v1.1, so undef it here. - // It will be defined again at the #HAS_GRAPHICAL_LCD section below. - #undef ST7920_DELAY_1 - #undef ST7920_DELAY_2 - #undef ST7920_DELAY_3 - - - #else - - #define LCD_PINS_RS PD10 - - #define BTN_EN1 PG10 - #define BTN_EN2 PF11 - #define SD_DETECT_PIN PF12 - - #define LCD_SDSS PB12 - - #define LCD_PINS_ENABLE PD11 - #define LCD_PINS_D4 PG2 - - #if ENABLED(FYSETC_MINI_12864) - #define DOGLCD_CS PD11 - #define DOGLCD_A0 PD10 - //#define LCD_BACKLIGHT_PIN -1 - #define LCD_RESET_PIN PG2 // Must be high or open for LCD to operate normally. - #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) - #ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN PG3 - #endif - #ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN PG6 - #endif - #ifndef RGB_LED_B_PIN - #define RGB_LED_B_PIN PG7 - #endif - #elif ENABLED(FYSETC_MINI_12864_2_1) - #define NEOPIXEL_PIN PG3 - #endif - #endif // !FYSETC_MINI_12864 - - #if ENABLED(ULTIPANEL) - #define LCD_PINS_D5 PG3 - #define LCD_PINS_D6 PG6 - #define LCD_PINS_D7 PG7 - #endif - - #endif - - // Alter timing for graphical display - #if HAS_GRAPHICAL_LCD - #define BOARD_ST7920_DELAY_1 DELAY_NS(96) - #define BOARD_ST7920_DELAY_2 DELAY_NS(48) - #define BOARD_ST7920_DELAY_3 DELAY_NS(600) - #endif - -#endif // HAS_SPI_LCD diff --git a/Marlin/src/pins/stm32/pins_CHITU3D.h b/Marlin/src/pins/stm32/pins_CHITU3D.h deleted file mode 100644 index 2411500fb2b9..000000000000 --- a/Marlin/src/pins/stm32/pins_CHITU3D.h +++ /dev/null @@ -1,283 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if !defined(__STM32F1__) && !defined(__STM32F4__) - #error "Oops! Select an STM32F1/4 board in 'Tools > Board.'" -#endif - -/** - * 2017 Victor Perez Marlin for stm32f1 test - */ - -#define BOARD_INFO_NAME "Chitu3D" -#define DEFAULT_MACHINE_NAME "STM32F103RET6" - -// Enable I2C_EEPROM for testing -//#define I2C_EEPROM - -// Ignore temp readings during development. -//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 - -// -// Steppers -// -#define X_STEP_PIN PE5 -#define X_DIR_PIN PE6 -#define X_ENABLE_PIN PC13 -#define X_MIN_PIN PG10 -#define X_MAX_PIN -1 - -#define Y_STEP_PIN PE2 -#define Y_DIR_PIN PE3 -#define Y_ENABLE_PIN PE4 -#define Y_MIN_PIN PA12 -#define Y_MAX_PIN - -#define Z_STEP_PIN PB9 -#define Z_DIR_PIN PE0 -#define Z_ENABLE_PIN PE1 -#define Z_MIN_PIN PA14 -#define Z_MAX_PIN -1 - -#define Y2_STEP_PIN -1 -#define Y2_DIR_PIN -1 -#define Y2_ENABLE_PIN -1 - -#define Z2_STEP_PIN -1 -#define Z2_DIR_PIN -1 -#define Z2_ENABLE_PIN -1 - -#define E0_STEP_PIN PB4 -#define E0_DIR_PIN PB5 -#define E0_ENABLE_PIN PB8 - - - -#define E1_STEP_PIN -1 -#define E1_DIR_PIN -1 -#define E1_ENABLE_PIN -1 - -#define E2_STEP_PIN -1 -#define E2_DIR_PIN -1 -#define E2_ENABLE_PIN -1 - -// -// Misc. Functions -// -#define SDSS -1 -#define LED_PIN -1 -#define CASE_LIGHT_PIN 8 - -#define PS_ON_PIN -1 -#define KILL_PIN PD6 // LED strip 24v - -// -// Heaters / Fans -// -#define HEATER_0_PIN PD12 // HOT-END -#define HEATER_1_PIN -1 -#define HEATER_2_PIN -1 - -#define HEATER_BED_PIN PG11 // HOT-BED -#define HEATER_BED2_PIN -1 // BED2 -#define HEATER_BED3_PIN -1 // BED3 - -#ifndef FAN_PIN - #define FAN_PIN PG14 // MAIN BOARD FAN -#endif - -#define FAN_SOFT_PWM - -// -// Temperature Sensors -// -#define TEMP_BED_PIN PA0 // Analog Input -#define TEMP_0_PIN PA1 // Analog Input -#define TEMP_1_PIN -1 // Analog Input -#define TEMP_2_PIN -1 // Analog Input - -// -// LCD Pins -// -#if HAS_SPI_LCD - - #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) - #define LCD_PINS_RS 49 // CS chip select /SS chip slave select - #define LCD_PINS_ENABLE 51 // SID (MOSI) - #define LCD_PINS_D4 52 // SCK (CLK) clock - #elif BOTH(NEWPANEL, PANEL_ONE) - #define LCD_PINS_RS PB8 - #define LCD_PINS_ENABLE PD2 - #define LCD_PINS_D4 PB12 - #define LCD_PINS_D5 PB13 - #define LCD_PINS_D6 PB14 - #define LCD_PINS_D7 PB15 - #else - #define LCD_PINS_RS PB8 - #define LCD_PINS_ENABLE PD2 - #define LCD_PINS_D4 PB12 - #define LCD_PINS_D5 PB13 - #define LCD_PINS_D6 PB14 - #define LCD_PINS_D7 PB15 - #if DISABLED(NEWPANEL) - #define BEEPER_PIN 33 - // Buttons attached to a shift register - // Not wired yet - //#define SHIFT_CLK 38 - //#define SHIFT_LD 42 - //#define SHIFT_OUT 40 - //#define SHIFT_EN 17 - #endif - #endif - - #if ENABLED(NEWPANEL) - - #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) - - #define BEEPER_PIN 37 - - #define BTN_EN1 31 - #define BTN_EN2 33 - #define BTN_ENC 35 - - #define SD_DETECT_PIN 49 - #define KILL_PIN 41 - - #if ENABLED(BQ_LCD_SMART_CONTROLLER) - #define LCD_BACKLIGHT_PIN 39 - #endif - - #elif ENABLED(REPRAPWORLD_GRAPHICAL_LCD) - - #define BTN_EN1 64 - #define BTN_EN2 59 - #define BTN_ENC 63 - #define SD_DETECT_PIN 42 - - #elif ENABLED(LCD_I2C_PANELOLU2) - - #define BTN_EN1 47 - #define BTN_EN2 43 - #define BTN_ENC 32 - #define LCD_SDSS 53 - #define SD_DETECT_PIN -1 - #define KILL_PIN 41 - - #elif ENABLED(LCD_I2C_VIKI) - - #define BTN_EN1 22 // http://files.panucatt.com/datasheets/viki_wiring_diagram.pdf explains 40/42. - #define BTN_EN2 7 // 22/7 are unused on RAMPS_14. 22 is unused and 7 the SERVO0_PIN on RAMPS_13. - - #define BTN_ENC -1 - #define LCD_SDSS 53 - #define SD_DETECT_PIN 49 - - #elif ANY(VIKI2, miniVIKI) - - #define BEEPER_PIN 33 - - // Pins for DOGM SPI LCD Support - #define DOGLCD_A0 44 - #define DOGLCD_CS 45 - #define LCD_SCREEN_ROT_180 - - #define BTN_EN1 22 - #define BTN_EN2 7 - #define BTN_ENC 39 - - #define SDSS 53 - #define SD_DETECT_PIN -1 // Pin 49 for display sd interface, 72 for easy adapter board - - #define KILL_PIN 31 - - #define STAT_LED_RED_PIN 32 - #define STAT_LED_BLUE_PIN 35 - - #elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) - #define BTN_EN1 35 - #define BTN_EN2 37 - #define BTN_ENC 31 - #define SD_DETECT_PIN 49 - #define LCD_SDSS 53 - #define KILL_PIN 41 - #define BEEPER_PIN 23 - #define DOGLCD_CS 29 - #define DOGLCD_A0 27 - #define LCD_BACKLIGHT_PIN 33 - - #elif ENABLED(MINIPANEL) - - #define BEEPER_PIN 42 - // Pins for DOGM SPI LCD Support - #define DOGLCD_A0 44 - #define DOGLCD_CS 66 - #define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65 - #define SDSS 53 - - #define KILL_PIN 64 - // GLCD features - // Uncomment screen orientation - //#define LCD_SCREEN_ROT_90 - //#define LCD_SCREEN_ROT_180 - //#define LCD_SCREEN_ROT_270 - // The encoder and click button - #define BTN_EN1 40 - #define BTN_EN2 63 - #define BTN_ENC 59 - // not connected to a pin - #define SD_DETECT_PIN 49 - - #else - - // Beeper on AUX-4 - #define BEEPER_PIN 33 - - // Buttons directly attached to AUX-2 - #if ENABLED(REPRAPWORLD_KEYPAD) - #define BTN_EN1 64 - #define BTN_EN2 59 - #define BTN_ENC 63 - #define SHIFT_OUT 40 - #define SHIFT_CLK 44 - #define SHIFT_LD 42 - #elif ENABLED(PANEL_ONE) - #define BTN_EN1 59 // AUX2 PIN 3 - #define BTN_EN2 63 // AUX2 PIN 4 - #define BTN_ENC 49 // AUX3 PIN 7 - #else - #define BTN_EN1 37 - #define BTN_EN2 35 - #define BTN_ENC 31 - #endif - - #if ENABLED(G3D_PANEL) - #define SD_DETECT_PIN 49 - #define KILL_PIN 41 - #else - //#define SD_DETECT_PIN -1 // Ramps doesn't use this - #endif - - #endif - #endif // NEWPANEL - -#endif // HAS_SPI_LCD diff --git a/Marlin/src/pins/stm32/pins_FLYF407ZG.h b/Marlin/src/pins/stm32/pins_FLYF407ZG.h deleted file mode 100644 index 97aaf3fdfc6a..000000000000 --- a/Marlin/src/pins/stm32/pins_FLYF407ZG.h +++ /dev/null @@ -1,266 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if !defined(STM32F4) && !defined(STM32F4xx) - #error "Oops! Select an STM32F4 board in 'Tools > Board.'" -#elif HOTENDS > 6 || E_STEPPERS > 6 - #error "FLYF407ZG supports up to 6 hotends / E-steppers." -#endif - -#define BOARD_INFO_NAME "FLYF407ZG" -#define BOARD_WEBSITE_URL "github.com/FLYmaker/FLYF407ZG" -#define DEFAULT_MACHINE_NAME BOARD_INFO_NAME - -#undef E2END -#define E2END 0xFFF // 4KB - -// -// Servos -// -#define SERVO0_PIN PE11 - -// -// Limit Switches -// -#define X_MIN_PIN PC3 -#define X_MAX_PIN PC2 -#define Y_MIN_PIN PF2 -#define Y_MAX_PIN PF1 -#define Z_MIN_PIN PF0 -#define Z_MAX_PIN PC15 - -// -// Z Probe (when not Z_MIN_PIN) -// -#define Z_MIN_PROBE_PIN PC14 // Z3_PIN - -// -// Steppers -// - -#define X_STEP_PIN PB9 -#define X_DIR_PIN PE0 -#define X_ENABLE_PIN PE1 -#ifndef X_CS_PIN - #define X_CS_PIN PG13 -#endif - -#define Y_STEP_PIN PB8 -#define Y_DIR_PIN PG11 -#define Y_ENABLE_PIN PG12 -#ifndef Y_CS_PIN - #define Y_CS_PIN PG10 -#endif - -#define Z_STEP_PIN PA8 -#define Z_DIR_PIN PD6 -#define Z_ENABLE_PIN PD7 -#ifndef Z_CS_PIN - #define Z_CS_PIN PD5 -#endif - -#define E0_STEP_PIN PC7 -#define E0_DIR_PIN PD3 -#define E0_ENABLE_PIN PD4 -#ifndef E0_CS_PIN - #define E0_CS_PIN PD1 -#endif - -#define E1_STEP_PIN PC6 -#define E1_DIR_PIN PA15 -#define E1_ENABLE_PIN PD0 -#ifndef E1_CS_PIN - #define E1_CS_PIN PA14 -#endif - -#define E2_STEP_PIN PD15 -#define E2_DIR_PIN PG7 -#define E2_ENABLE_PIN PG8 -#ifndef E2_CS_PIN - #define E2_CS_PIN PG6 -#endif - -#define E3_STEP_PIN PD14 -#define E3_DIR_PIN PG4 -#define E3_ENABLE_PIN PG5 -#ifndef E3_CS_PIN - #define E3_CS_PIN PG3 -#endif - -#define E4_STEP_PIN PD13 -#define E4_DIR_PIN PD11 -#define E4_ENABLE_PIN PG2 -#ifndef E4_CS_PIN - #define E4_CS_PIN PD10 -#endif - -#define E5_STEP_PIN PD12 -#define E5_DIR_PIN PD8 -#define E5_ENABLE_PIN PD9 -#ifndef E5_CS_PIN - #define E5_CS_PIN PB12 -#endif - -// -// Temperature Sensors -// -#define TEMP_0_PIN PA0 // Analog Input -#define TEMP_1_PIN PC1 // Analog Input -#define TEMP_2_PIN PC0 // Analog Input -#define TEMP_3_PIN PF10 // Analog Input -#define TEMP_4_PIN PF5 // Analog Input -#define TEMP_5_PIN PF4 // Analog Input -#define TEMP_BED_PIN PF3 // Analog Input - -// -// Heaters / Fans -// -#define HEATER_0_PIN PF7 -#define HEATER_1_PIN PF6 -#define HEATER_2_PIN PE6 -#define HEATER_3_PIN PE5 -#define HEATER_4_PIN PE4 -#define HEATER_5_PIN PA2 -#define HEATER_BED_PIN PE2 - -#ifndef FAN_PIN - #define FAN_PIN PF8 -#endif -#define FAN1_PIN PF9 -#define FAN2_PIN PE3 -#define FAN3_PIN PA1 -#define FAN4_PIN PE13 -#define FAN5_PIN PB11 - -// -// Onboard SD support -// - -#define SDIO_D0_PIN PC8 -#define SDIO_D1_PIN PC9 -//#define SD_CARD_DETECT_PIN PC13 -#define SDIO_D2_PIN PC10 -#define SDIO_D3_PIN PC11 -#define SDIO_CK_PIN PC12 -#define SDIO_CMD_PIN PD2 - -#if !defined(SDCARD_CONNECTION) || SDCARD_CONNECTION == ONBOARD - #define SDIO_SUPPORT // Use SDIO for onboard SD - - #ifndef SDIO_SUPPORT - #define SOFTWARE_SPI // Use soft SPI for onboard SD - #define SDSS SDIO_D3_PIN - #define SCK_PIN SDIO_CK_PIN - #define MISO_PIN SDIO_D0_PIN - #define MOSI_PIN SDIO_CMD_PIN - #endif -#endif - -// -// Trinamic Software SPI -// - -#if ENABLED(TMC_USE_SW_SPI) - #ifndef TMC_SW_MOSI - #define TMC_SW_MOSI PB15 - #endif - #ifndef TMC_SW_MISO - #define TMC_SW_MISO PB14 - #endif - #ifndef TMC_SW_SCK - #define TMC_SW_SCK PB13 - #endif -#endif - -// -// Trinamic Software Serial -// - -#if HAS_TMC220x - #define X_SERIAL_TX_PIN PG13 - #define X_SERIAL_RX_PIN PG13 - - #define Y_SERIAL_TX_PIN PG10 - #define Y_SERIAL_RX_PIN PG10 - - #define Z_SERIAL_TX_PIN PD5 - #define Z_SERIAL_RX_PIN PD5 - - #define E0_SERIAL_TX_PIN PD1 - #define E0_SERIAL_RX_PIN PD1 - - #define E1_SERIAL_TX_PIN PA14 - #define E1_SERIAL_RX_PIN PA14 - - #define E2_SERIAL_TX_PIN PG6 - #define E2_SERIAL_RX_PIN PG6 - - #define E3_SERIAL_TX_PIN PG3 - #define E3_SERIAL_RX_PIN PG3 - - #define E4_SERIAL_TX_PIN PD10 - #define E4_SERIAL_RX_PIN PD10 - - #define E5_SERIAL_TX_PIN PB12 - #define E5_SERIAL_RX_PIN PB12 - -#endif - - -// -// LCD / Controller -// -#define SCK_PIN PB13 -#define MISO_PIN PB14 -#define MOSI_PIN PB15 -#define SDSS PF11 -#define SD_DETECT_PIN PB2 -#define BEEPER_PIN PB10 -#define LCD_PINS_RS PE12 -#define LCD_PINS_ENABLE PE14 -#define LCD_PINS_D4 PE10 -#define LCD_PINS_D5 PE9 -#define LCD_PINS_D6 PE8 -#define LCD_PINS_D7 PE7 -#define BTN_EN1 PC4 -#define BTN_EN2 PC5 -#define BTN_ENC PE15 - -// -// Filament runout -// - -#define FIL_RUNOUT_PIN PA3 - -// -// ST7920 Delays -// -#ifndef ST7920_DELAY_1 - #define ST7920_DELAY_1 DELAY_NS(96) -#endif -#ifndef ST7920_DELAY_2 - #define ST7920_DELAY_2 DELAY_NS(48) -#endif -#ifndef ST7920_DELAY_3 - #define ST7920_DELAY_3 DELAY_NS(715) -#endif diff --git a/Marlin/src/pins/stm32/pins_FYSETC_AIO_II.h b/Marlin/src/pins/stm32/pins_FYSETC_AIO_II.h deleted file mode 100644 index db76042ab7f3..000000000000 --- a/Marlin/src/pins/stm32/pins_FYSETC_AIO_II.h +++ /dev/null @@ -1,189 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#ifndef __STM32F1__ - #error "Oops! Select an STM32F1 board in 'Tools > Board.'" -#endif - -#define BOARD_INFO_NAME "FYSETC AIO II" -#define BOARD_WEBSITE_URL "fysetc.com" - -#define DISABLE_JTAG - -#define pins_v2_20190128 // geo-f:add for new pins define - -// Ignore temp readings during development. -//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 - -// -// Flash EEPROM Emulation -// -#define FLASH_EEPROM_EMULATION -#define EEPROM_PAGE_SIZE uint16(0x800) // 2KB -#define EEPROM_START_ADDRESS uint32(0x8000000 + 256 * 1024 - 2 * EEPROM_PAGE_SIZE) -#undef E2END -#define E2END (EEPROM_PAGE_SIZE - 1) // 2KB -// -// Limit Switches -// -#define X_STOP_PIN PA1 -#define Y_STOP_PIN PA0 -#define Z_STOP_PIN PB14 - -// -// Filament runout -// -#ifdef pins_v2_20190128 - #define FIL_RUNOUT_PIN PB15 -#else - #define FIL_RUNOUT_PIN PB5 -#endif - -// -// Steppers -// -#define X_STEP_PIN PB8 -#define X_DIR_PIN PB9 -#define X_ENABLE_PIN PA8 - -#define Y_STEP_PIN PB2 -#ifdef pins_v2_20190128 - #define Y_DIR_PIN PB3 -#else - #define Y_DIR_PIN PB0 -#endif -#define Y_ENABLE_PIN PB1 - -#define Z_STEP_PIN PC0 -#define Z_DIR_PIN PC1 -#define Z_ENABLE_PIN PC2 - -#define E0_STEP_PIN PC15 -#define E0_DIR_PIN PC14 -#define E0_ENABLE_PIN PC13 - -// -// Stepper current PWM -// - -// X:PA2 Y:PA3 Z:PB12 E:PB13 // changed for test -//#define MOTOR_CURRENT_PWM_XY_PIN PA3 -//#define MOTOR_CURRENT_PWM_Z_PIN PA2 // PB12 -//#define MOTOR_CURRENT_PWM_XY_PIN PB6 -//#define MOTOR_CURRENT_PWM_Z_PIN PB7 // PB12 -//#define MOTOR_CURRENT_PWM_E_PIN -1 // PB13 -// Motor current PWM conversion, PWM value = MotorCurrentSetting * 255 / range -#ifndef MOTOR_CURRENT_PWM_RANGE - #define MOTOR_CURRENT_PWM_RANGE 1500 // geo-f:old 2000 -#endif -#define DEFAULT_PWM_MOTOR_CURRENT {500, 500, 400} // geo-f:old 1300 1300 1250 - -// 采用 SDIO PCB从左到右数 -// 1:PC10 - SDIO_D2 -// 2:PC11 - SDIO_D3 -// 3:PD2 - SDIO_CMD -// 4:VCC -// 5:PC12 - SDIO_CK -// 6:VDD -// 7:PC8 - SDIO_D0 -// 8:PC9 - SDIO_D1 -// 9:PA15 - SD_DETECT_PIN - -// -// Heaters / Fans -// -#define HEATER_0_PIN PC7 -#define HEATER_BED_PIN PC6 -#ifndef FAN_PIN - #define FAN_PIN PC8 -#endif - -// -// Temperature Sensors -// -#define TEMP_BED_PIN PC5 // Analog Input -#define TEMP_0_PIN PC4 // Analog Input - -// -// Misc. Functions -// -#define SDSS PA4 - -// -// LCD Pins -// -#if HAS_SPI_LCD - - #define BEEPER_PIN PC9 - - #if HAS_GRAPHICAL_LCD - - #define DOGLCD_A0 PA15 - #ifdef pins_v2_20190128 - #define DOGLCD_CS PB5 - #else - #define DOGLCD_CS PB7 - #endif - - //#define LCD_CONTRAST_INIT 190 - //#define LCD_SCREEN_ROT_90 - //#define LCD_SCREEN_ROT_180 - //#define LCD_SCREEN_ROT_270 - - #endif - - // not connected to a pin - #define SD_DETECT_PIN PC3 - - #if ENABLED(NEWPANEL) - // The encoder and click button - #define BTN_EN1 PC10 - #define BTN_EN2 PC11 - #define BTN_ENC PC12 - #endif - - #ifdef pins_v2_20190128 - #define LCD_RESET_PIN PB4 - #ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN PB0 - #endif - #ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN PB6 - #endif - #ifndef RGB_LED_B_PIN - #define RGB_LED_B_PIN PB7 - #endif - #else - #define LCD_RESET_PIN PB6 - #ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN PB3 - #endif - #ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN PB4 - #endif - #ifndef RGB_LED_B_PIN - #define RGB_LED_B_PIN PB5 - #endif - #endif - -#endif diff --git a/Marlin/src/pins/stm32/pins_FYSETC_CHEETAH.h b/Marlin/src/pins/stm32/pins_FYSETC_CHEETAH.h deleted file mode 100644 index a845ed161b7d..000000000000 --- a/Marlin/src/pins/stm32/pins_FYSETC_CHEETAH.h +++ /dev/null @@ -1,151 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#ifndef __STM32F1__ - #error "Oops! Select an STM32F1 board in 'Tools > Board.'" -#endif - -#define DEFAULT_MACHINE_NAME "3D Printer" - -#define BOARD_INFO_NAME "FYSETC Cheetah" -#define BOARD_WEBSITE_URL "fysetc.com" - -// Ignore temp readings during development. -//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 - -#define DISABLE_JTAG - -#define FLASH_EEPROM_EMULATION -#define EEPROM_PAGE_SIZE uint16(0x800) // 2KB -#define EEPROM_START_ADDRESS uint32(0x8000000 + 256 * 1024 - 2 * EEPROM_PAGE_SIZE) -#undef E2END -#define E2END (EEPROM_PAGE_SIZE - 1) // 2KB - -// -// Servos -// -#define SERVO0_PIN PA0 - -// -// Limit Switches -// -#define X_STOP_PIN PA1 -#define Y_STOP_PIN PB4 -#define Z_STOP_PIN PA15 - -// -// Filament runout -// -#define FIL_RUNOUT_PIN PB5 - -// -// Steppers -// -#define X_STEP_PIN PB8 -#define X_DIR_PIN PB9 -#define X_ENABLE_PIN PA8 - -#define Y_STEP_PIN PB2 -#define Y_DIR_PIN PB3 -#define Y_ENABLE_PIN PB1 - -#define Z_STEP_PIN PC0 -#define Z_DIR_PIN PC1 -#define Z_ENABLE_PIN PC2 - -#define E0_STEP_PIN PC15 -#define E0_DIR_PIN PC14 -#define E0_ENABLE_PIN PC13 - -#define X_HARDWARE_SERIAL MSerial2 -#define Y_HARDWARE_SERIAL MSerial2 -#define Z_HARDWARE_SERIAL MSerial2 -#define E0_HARDWARE_SERIAL MSerial2 - -// -// Heaters / Fans -// -#define HEATER_0_PIN PC6 -#define HEATER_BED_PIN PC7 -#ifndef FAN_PIN - #define FAN_PIN PC8 -#endif - -// -// Temperature Sensors -// -#define TEMP_BED_PIN PC5 // Analog Input -#define TEMP_0_PIN PC4 // Analog Input - -// -// Misc. Functions -// -#define SDSS PA4 - -// -// LCD Pins -// -#if HAS_SPI_LCD - - #define BEEPER_PIN PC9 - - #if HAS_GRAPHICAL_LCD - #define DOGLCD_A0 PB14 - #define DOGLCD_CS PB12 - #define DOGLCD_SCK PB13 - #define DOGLCD_MOSI PB15 - //#define LCD_SCREEN_ROT_90 - //#define LCD_SCREEN_ROT_180 - //#define LCD_SCREEN_ROT_270 - - #if EITHER(FYSETC_MINI_12864, U8GLIB_ST7920) - #define FORCE_SOFT_SPI - #endif - #endif - - #define LCD_PINS_RS PB12 // CS -- SOFT SPI for ENDER3 LCD - #define LCD_PINS_D4 PB13 // SCLK - #define LCD_PINS_ENABLE PB15 // DATA MOSI - - // not connected to a pin - #define SD_DETECT_PIN PC3 - - #ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN PB0 - #endif - #ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN PB7 - #endif - #ifndef RGB_LED_B_PIN - #define RGB_LED_B_PIN PB6 - #endif - - //#define LCD_CONTRAST_INIT 190 - - #if ENABLED(NEWPANEL) - #define BTN_EN1 PC11 - #define BTN_EN2 PC10 - #define BTN_ENC PC12 - #endif - -#endif diff --git a/Marlin/src/pins/stm32/pins_FYSETC_S6.h b/Marlin/src/pins/stm32/pins_FYSETC_S6.h deleted file mode 100644 index 16f176a376f7..000000000000 --- a/Marlin/src/pins/stm32/pins_FYSETC_S6.h +++ /dev/null @@ -1,262 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#ifndef STM32F4 - #error "Oops! Select an STM32F4 board in 'Tools > Board.'" -#elif HOTENDS > 3 || E_STEPPERS > 3 - #error "RUMBA32 supports up to 3 hotends / E-steppers." -#endif - -#ifndef BOARD_INFO_NAME - #define BOARD_INFO_NAME "FYSETC_S6" -#endif -#ifndef DEFAULT_MACHINE_NAME - #define DEFAULT_MACHINE_NAME BOARD_INFO_NAME -#endif - -// change the prio to 3 , 2 is for software serial -//#define TEMP_TIMER_IRQ_PRIO 3 - -// -// EEPROM Emulation -// -#define FLASH_EEPROM_EMULATION -//#define SRAM_EEPROM_EMULATION -//#define I2C_EEPROM -#ifdef I2C_EEPROM - #undef E2END // Defined in Arduino Core STM32 to be used with EEPROM emulation. This board uses a real EEPROM. - #define E2END 0xFFF // 4KB -#endif - -// -// Servos -// -#define SERVO0_PIN PA3 - -// -// Limit Switches -// -#define X_MIN_PIN PB14 -#define X_MAX_PIN PA1 -#define Y_MIN_PIN PB13 -#define Y_MAX_PIN PA2 -#define Z_MIN_PIN PA0 -#define Z_MAX_PIN PA3 - -// -// Filament Sensor -// -#ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN PA1 -#endif - -// -// Steppers -// -#define X_STEP_PIN PE11 -#define X_DIR_PIN PE10 -#define X_ENABLE_PIN PE12 -#define X_CS_PIN PE7 - -#define Y_STEP_PIN PD8 -#define Y_DIR_PIN PB12 -#define Y_ENABLE_PIN PD9 -#define Y_CS_PIN PE15 - -#define Z_STEP_PIN PD14 -#define Z_DIR_PIN PD13 -#define Z_ENABLE_PIN PD15 -#define Z_CS_PIN PD10 - -#define E0_STEP_PIN PD5 -#define E0_DIR_PIN PD6 -#define E0_ENABLE_PIN PD4 -#define E0_CS_PIN PD7 - -#define E1_STEP_PIN PE6 -#define E1_DIR_PIN PC13 -#define E1_ENABLE_PIN PE5 -#define E1_CS_PIN PC14 - -#define E2_STEP_PIN PE2 -#define E2_DIR_PIN PE4 -#define E2_ENABLE_PIN PE3 -#define E2_CS_PIN PC15 - -#if HAS_TMC220x - // - // TMC2208/TMC2209 stepper drivers - // - - // - // Software serial - // - #define X_SERIAL_TX_PIN PE9 - #define X_SERIAL_RX_PIN PE8 - - #define Y_SERIAL_TX_PIN PE14 - #define Y_SERIAL_RX_PIN PE13 - - #define Z_SERIAL_TX_PIN PD11 - #define Z_SERIAL_RX_PIN PD12 - - #define E0_SERIAL_TX_PIN PD3 - #define E0_SERIAL_RX_PIN PA15 - - #define E1_SERIAL_TX_PIN PC4 - #define E1_SERIAL_RX_PIN PC5 - - #define E2_SERIAL_TX_PIN PE1 - #define E2_SERIAL_RX_PIN PE0 -#endif - -// -// Temperature Sensors -// -#define TEMP_0_PIN PC0 -#define TEMP_1_PIN PC1 -#define TEMP_2_PIN PC2 -#define TEMP_BED_PIN PC3 - -// -// Heaters / Fans -// -#define HEATER_0_PIN PB3 -#define HEATER_1_PIN PB4 -#define HEATER_2_PIN PB15 -#define HEATER_BED_PIN PC8 - -#define FAN_PIN PB0 -#define FAN1_PIN PB1 -#define FAN2_PIN PB2 - -// -// SPI -// -#define SCK_PIN PA5 -#define MISO_PIN PA6 -#define MOSI_PIN PA7 - -// -// Misc. Functions -// -//#define LED_PIN PB14 -//#define BTN_PIN PC10 -//#define PS_ON_PIN PE11 -//#define KILL_PIN PC5 - -#define SDSS PA4 -#define SD_DETECT_PIN PB10 - -// -// LCD / Controller -// -#if HAS_SPI_LCD - #define BEEPER_PIN PC9 - #define BTN_ENC PA8 - - #if ENABLED(CR10_STOCKDISPLAY) - #define LCD_PINS_RS PD0 - - #define BTN_EN1 PC11 - #define BTN_EN2 PC10 - - #define LCD_PINS_ENABLE PD1 - #define LCD_PINS_D4 PC12 - - // CR10_Stock Display needs a different delay setting on SKR PRO v1.1, so undef it here. - // It will be defined again at the #HAS_GRAPHICAL_LCD section below. - #undef ST7920_DELAY_1 - #undef ST7920_DELAY_2 - #undef ST7920_DELAY_3 - - #else - - #define LCD_PINS_RS PD2 - - #define BTN_EN1 PC6 - #define BTN_EN2 PC7 - - #define LCD_SDSS PA4 - - #define LCD_PINS_ENABLE PC11 - #define LCD_PINS_D4 PC10 - - #if ENABLED(FYSETC_MINI_12864) - // See https://wiki.fysetc.com/Mini12864_Panel - #define DOGLCD_CS PC11 - #define DOGLCD_A0 PD2 - #if ENABLED(FYSETC_GENERIC_12864_1_1) - #define LCD_BACKLIGHT_PIN PD0 - #endif - #define LCD_RESET_PIN PC10 // Must be high or open for LCD to operate normally. - #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) - #ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN PC12 - #endif - #ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN PD0 - #endif - #ifndef RGB_LED_B_PIN - #define RGB_LED_B_PIN PD1 - #endif - #elif ENABLED(FYSETC_MINI_12864_2_1) - #define NEOPIXEL_PIN PC12 - #endif - #endif // !FYSETC_MINI_12864 - - #if ENABLED(ULTIPANEL) - #define LCD_PINS_D5 PC12 - #define LCD_PINS_D6 PD0 - #define LCD_PINS_D7 PD1 - #endif - - #endif - - // Alter timing for graphical display - #if HAS_GRAPHICAL_LCD - #ifndef ST7920_DELAY_1 - #define ST7920_DELAY_1 DELAY_NS(96) - #endif - #ifndef ST7920_DELAY_2 - #define ST7920_DELAY_2 DELAY_NS(48) - #endif - #ifndef ST7920_DELAY_3 - #define ST7920_DELAY_3 DELAY_NS(600) - #endif - #endif - -#endif // HAS_SPI_LCD - -#ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN PB6 -#endif -#ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN PB5 -#endif -#ifndef RGB_LED_B_PIN - #define RGB_LED_B_PIN PB7 -#endif -#ifndef RGB_LED_W_PIN - #define RGB_LED_W_PIN -1 -#endif diff --git a/Marlin/src/pins/stm32/pins_GENERIC_STM32F4.h b/Marlin/src/pins/stm32/pins_GENERIC_STM32F4.h deleted file mode 100644 index 2909b7c53824..000000000000 --- a/Marlin/src/pins/stm32/pins_GENERIC_STM32F4.h +++ /dev/null @@ -1,190 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * To build with Arduino IDE use "Discovery F407VG" - * To build with PlatformIO use environment "STM32F4" - */ -#if !defined(STM32F4) && !defined(STM32F4xx) - #error "Oops! Select an STM32F4 board in 'Tools > Board.'" -#elif HOTENDS > 2 || E_STEPPERS > 2 - #error "STM32F4 supports up to 2 hotends / E-steppers." -#endif - -#define BOARD_INFO_NAME "Misc. STM32F4" -#define DEFAULT_MACHINE_NAME "STM32F407VET6" - -//#define I2C_EEPROM - -#ifndef E2END - #define E2END 0xFFF // 4KB -#endif - -// Ignore temp readings during development. -//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 - -// -// Limit Switches -// -#define X_MIN_PIN PE0 -#define X_MAX_PIN -1 -#define Y_MIN_PIN PE1 -#define Y_MAX_PIN -1 -#define Z_MIN_PIN PE14 -#define Z_MAX_PIN -1 - -// -// Z Probe (when not Z_MIN_PIN) -// - -//#ifndef Z_MIN_PROBE_PIN -// #define Z_MIN_PROBE_PIN PA4 -//#endif - -// -// Steppers -// - -#define X_STEP_PIN PD3 -#define X_DIR_PIN PD2 -#define X_ENABLE_PIN PD0 -//#ifndef X_CS_PIN -// #define X_CS_PIN PD1 -//#endif - -#define Y_STEP_PIN PE11 -#define Y_DIR_PIN PE10 -#define Y_ENABLE_PIN PE13 -//#ifndef Y_CS_PIN -// #define Y_CS_PIN PE12 -//#endif - -#define Z_STEP_PIN PD6 -#define Z_DIR_PIN PD7 -#define Z_ENABLE_PIN PD4 -//#ifndef Z_CS_PIN -// #define Z_CS_PIN PD5 -//#endif - -#define E0_STEP_PIN PB5 -#define E0_DIR_PIN PB6 -#define E0_ENABLE_PIN PB3 -//#ifndef E0_CS_PIN -// #define E0_CS_PIN PB4 -//#endif - -#define E1_STEP_PIN PE4 -#define E1_DIR_PIN PE2 -#define E1_ENABLE_PIN PE3 -//#ifndef E1_CS_PIN -// #define E1_CS_PIN PE5 -//#endif - -#define SCK_PIN PA5 -#define MISO_PIN PA6 -#define MOSI_PIN PA7 - -// -// Temperature Sensors -// - -#define TEMP_0_PIN PC0 // Analog Input -#define TEMP_1_PIN PC1 // Analog Input -#define TEMP_BED_PIN PC2 // Analog Input - -// -// Heaters / Fans -// - -#define HEATER_0_PIN PA1 -#define HEATER_1_PIN PA2 -#define HEATER_BED_PIN PA0 - -#ifndef FAN_PIN - #define FAN_PIN PC6 -#endif -#define FAN1_PIN PC7 -#define FAN2_PIN PC8 - -#define ORIG_E0_AUTO_FAN_PIN FAN1_PIN // Use this by NOT overriding E0_AUTO_FAN_PIN - -// -// Misc. Functions -// - -//#define CASE_LIGHT_PIN_CI PF13 -//#define CASE_LIGHT_PIN_DO PF14 -//#define NEOPIXEL_PIN PF13 - -// -// Průša i3 MK2 Multi Material Multiplexer Support -// - -//#define E_MUX0_PIN PG3 -//#define E_MUX1_PIN PG4 - -// -// Servos -// - -//#define SERVO0_PIN PE13 -//#define SERVO1_PIN PE14 - - -#define SDSS PE7 -#define SS_PIN PE7 -#define LED_PIN PB7 //Alive -#define PS_ON_PIN PA10 -#define KILL_PIN PA8 -#define PWR_LOSS PA4 //Power loss / nAC_FAULT - -// -// LCD / Controller -// - -#define SD_DETECT_PIN PA15 -#define BEEPER_PIN PC9 -#define LCD_PINS_RS PE9 -#define LCD_PINS_ENABLE PE8 -#define LCD_PINS_D4 PB12 -#define LCD_PINS_D5 PB13 -#define LCD_PINS_D6 PB14 -#define LCD_PINS_D7 PB15 -#define BTN_EN1 PC4 -#define BTN_EN2 PC5 -#define BTN_ENC PC3 - -// -// Filament runout -// - -#define FIL_RUNOUT_PIN PA3 - -// -// ST7920 Delays -// -#if HAS_GRAPHICAL_LCD - #define BOARD_ST7920_DELAY_1 DELAY_NS(96) - #define BOARD_ST7920_DELAY_2 DELAY_NS(48) - #define BOARD_ST7920_DELAY_3 DELAY_NS(715) -#endif diff --git a/Marlin/src/pins/stm32/pins_GTM32_MINI.h b/Marlin/src/pins/stm32/pins_GTM32_MINI.h deleted file mode 100644 index a35bd298884b..000000000000 --- a/Marlin/src/pins/stm32/pins_GTM32_MINI.h +++ /dev/null @@ -1,230 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * 24 May 2018 - @chepo for STM32F103VET6 - * Schematic: https://github.com/chepo92/Smartto/blob/master/circuit_diagram/Rostock301/Hardware_GTM32_PRO_VB.pdf - */ - -#ifndef __STM32F1__ - #error "Oops! Select an STM32F1 board in 'Tools > Board.'" -#endif - -#define BOARD_INFO_NAME "GTM32 Pro VB" -#define DEFAULT_MACHINE_NAME "STM32F103VET6" - -//#define DISABLE_DEBUG - -// -// It is required to disable JTAG function because its pins are -// used as GPIO to drive the Y axis stepper. -// DO NOT ENABLE! -// -#define DISABLE_JTAG - -// -// If you don't need the SWDIO functionality (any more), you may -// disable SWD here to regain PA13/PA14 pins for other use. -// -//#define DISABLE_JTAGSWD - -// Ignore temp readings during development. -//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 - -// Enable EEPROM Emulation for this board as it doesn't have EEPROM -#define FLASH_EEPROM_EMULATION -#define E2END 0xFFF // 4KB - -// -// Limit Switches -// -#define X_MIN_PIN PE5 // ENDSTOPS 15,17 -#define X_MAX_PIN PE4 // ENDSTOPS 16,18 -#define Y_MIN_PIN PE3 // ENDSTOPS 9,11 -#define Y_MAX_PIN PE2 // ENDSTOPS 10,12 -#define Z_MIN_PIN PE1 // ENDSTOPS 3,5 -#define Z_MAX_PIN PE0 // ENDSTOPS 4,6 - -// -// Steppers -// -#define X_STEP_PIN PC6 -#define X_DIR_PIN PD13 -#define X_ENABLE_PIN PA8 - -#define Y_STEP_PIN PA12 -#define Y_DIR_PIN PA11 -#define Y_ENABLE_PIN PA15 - -#define Z_STEP_PIN PD6 -#define Z_DIR_PIN PD3 -#define Z_ENABLE_PIN PB3 - -// Extruder stepper pins -// NOTE: Numbering here is made according to EXT connector numbers, -// the FANx_PWM line numbering in the schematics is reverse. -// That is, E0_*_PIN are the E2_* lines connected to E2_A1 step -// stick that drives the EXT0 output on the board. -// -#define E0_STEP_PIN PC14 -#define E0_DIR_PIN PC13 -#define E0_ENABLE_PIN PC15 - -#define E1_STEP_PIN PA0 -#define E1_DIR_PIN PB6 -#define E1_ENABLE_PIN PA1 - -#define E2_STEP_PIN PB2 -#define E2_DIR_PIN PB11 -#define E2_ENABLE_PIN PC4 - -// -// Heaters / Fans -// -#define HEATER_0_PIN PB0 // EXT0 port -#define HEATER_1_PIN PB5 // EXT1 port -#define HEATER_2_PIN PB4 // EXT2 port -#define HEATER_BED_PIN PB1 // CON2X3 hotbed port - -// -// These are FAN PWM pins on EXT0..EXT2 connectors. -// -//#define FAN_PIN PB9 // EXT0 port -#define ORIG_E0_AUTO_FAN_PIN PB9 // EXT0 port, used as main extruder fan -#define FAN1_PIN PB8 // EXT1 port -#define FAN2_PIN PB7 // EXT2 port - -// -// Temperature Sensors -// -#define TEMP_0_PIN PC2 // EXT0 port -#define TEMP_1_PIN PC1 // EXT1 port -#define TEMP_2_PIN PC0 // EXT2 port -#define TEMP_BED_PIN PC3 // CON2X3 hotbed port - -// -// Misc. Functions -// -#define LED_PWM PD12 // External LED, pin 2 on LED labeled connector - -// -// LCD / Controller -// -#if HAS_SPI_LCD - - #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) - // - // LCD display on J2 FFC40 - // Geeetech's LCD2004A Control Panel is very much like - // RepRapDiscount Smart Controller, but adds an FFC40 connector - // - #define LCD_PINS_RS PE6 // CS chip select /SS chip slave select - #define LCD_PINS_ENABLE PE14 // SID (MOSI) - #define LCD_PINS_D4 PD8 // SCK (CLK) clock - #define LCD_PINS_D5 PD9 - #define LCD_PINS_D6 PD10 - #define LCD_PINS_D7 PE15 - - #else - // - // Serial LCDs can be implemented in ExtUI - // - //#define LCD_UART_TX PD8 - //#define LCD_UART_RX PD9 - #endif - - #if HAS_GRAPHICAL_LCD - #define BOARD_ST7920_DELAY_1 DELAY_NS(96) - #define BOARD_ST7920_DELAY_2 DELAY_NS(48) - #define BOARD_ST7920_DELAY_3 DELAY_NS(715) - #endif - -#endif // HAS_SPI_LCD - -#if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) - // - // Geeetech's LCD2004A Control Panel is very much like - // RepRapDiscount Smart Controller, but adds an FFC40 connector - // connected with a flat wire to J2 connector on the board. - // - #define BTN_EN1 PE8 - #define BTN_EN2 PE9 - #define BTN_ENC PE13 - - #define GTM32_PRO_VB_USE_LCD_BEEPER - #define GTM32_PRO_VB_USE_EXT_SDCARD -#endif - -// -// Beeper -// -#ifdef GTM32_PRO_VB_USE_LCD_BEEPER - // This is pin 32 on J2 FFC40 and pin, goes to the beeper - // on Geeetech's version of RepRapDiscount Smart Controller - // (e.g. on Rostock 301) - #define BEEPER_PIN PE12 -#else - // This is the beeper on the board itself - #define BEEPER_PIN PB10 -#endif - -/** - * The on-board TF_CARD_SOCKET microSD card socket has no SD Detect pin wired. - * - * The FFC10 (SD_CARD) connector has the same pins as those routed to the FFC40 (J2) - * connector, which usually go to the SD Card slot on the Geeetech version of the - * RepRapDiscount Smart Controller. Both connectors have the card detect signal. - * - * The on-board SD card and the external card (on either SD_CARD or J2) are two - * separate devices and can work simultaneously. Unfortunately, Marlin only supports - * a single SPI Flash device (as of 2019-07-05) so only one is enabled here. - */ -#if ENABLED(GTM32_PRO_VB_USE_EXT_SDCARD) - // - // SD Card on RepRapDiscount Smart Controller (J2) or on SD_CARD connector - // - #define SS_PIN PC11 - #define SCK_PIN PC12 - #define MOSI_PIN PD2 - #define MISO_PIN PC8 - #define SD_DETECT_PIN PC7 -#else - // - // Use the on-board card socket labeled TF_CARD_SOCKET - // - #define SS_PIN PA4 - #define SCK_PIN PA5 - #define MOSI_PIN PA7 - #define MISO_PIN PA6 - #define SD_DETECT_PIN -1 // Card detect is not connected -#endif - -#define SDSS SS_PIN - -// -// ESP WiFi can be soldered to J9 connector which is wired to USART2. -// Must define WIFISUPPORT in Configuration.h for the printer. -// -#define ESP_WIFI_MODULE_COM 2 -#define ESP_WIFI_MODULE_BAUDRATE 115200 -#define ESP_WIFI_MODULE_RESET_PIN -1 diff --git a/Marlin/src/pins/stm32/pins_GTM32_PRO_VB.h b/Marlin/src/pins/stm32/pins_GTM32_PRO_VB.h deleted file mode 100644 index a35bd298884b..000000000000 --- a/Marlin/src/pins/stm32/pins_GTM32_PRO_VB.h +++ /dev/null @@ -1,230 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * 24 May 2018 - @chepo for STM32F103VET6 - * Schematic: https://github.com/chepo92/Smartto/blob/master/circuit_diagram/Rostock301/Hardware_GTM32_PRO_VB.pdf - */ - -#ifndef __STM32F1__ - #error "Oops! Select an STM32F1 board in 'Tools > Board.'" -#endif - -#define BOARD_INFO_NAME "GTM32 Pro VB" -#define DEFAULT_MACHINE_NAME "STM32F103VET6" - -//#define DISABLE_DEBUG - -// -// It is required to disable JTAG function because its pins are -// used as GPIO to drive the Y axis stepper. -// DO NOT ENABLE! -// -#define DISABLE_JTAG - -// -// If you don't need the SWDIO functionality (any more), you may -// disable SWD here to regain PA13/PA14 pins for other use. -// -//#define DISABLE_JTAGSWD - -// Ignore temp readings during development. -//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 - -// Enable EEPROM Emulation for this board as it doesn't have EEPROM -#define FLASH_EEPROM_EMULATION -#define E2END 0xFFF // 4KB - -// -// Limit Switches -// -#define X_MIN_PIN PE5 // ENDSTOPS 15,17 -#define X_MAX_PIN PE4 // ENDSTOPS 16,18 -#define Y_MIN_PIN PE3 // ENDSTOPS 9,11 -#define Y_MAX_PIN PE2 // ENDSTOPS 10,12 -#define Z_MIN_PIN PE1 // ENDSTOPS 3,5 -#define Z_MAX_PIN PE0 // ENDSTOPS 4,6 - -// -// Steppers -// -#define X_STEP_PIN PC6 -#define X_DIR_PIN PD13 -#define X_ENABLE_PIN PA8 - -#define Y_STEP_PIN PA12 -#define Y_DIR_PIN PA11 -#define Y_ENABLE_PIN PA15 - -#define Z_STEP_PIN PD6 -#define Z_DIR_PIN PD3 -#define Z_ENABLE_PIN PB3 - -// Extruder stepper pins -// NOTE: Numbering here is made according to EXT connector numbers, -// the FANx_PWM line numbering in the schematics is reverse. -// That is, E0_*_PIN are the E2_* lines connected to E2_A1 step -// stick that drives the EXT0 output on the board. -// -#define E0_STEP_PIN PC14 -#define E0_DIR_PIN PC13 -#define E0_ENABLE_PIN PC15 - -#define E1_STEP_PIN PA0 -#define E1_DIR_PIN PB6 -#define E1_ENABLE_PIN PA1 - -#define E2_STEP_PIN PB2 -#define E2_DIR_PIN PB11 -#define E2_ENABLE_PIN PC4 - -// -// Heaters / Fans -// -#define HEATER_0_PIN PB0 // EXT0 port -#define HEATER_1_PIN PB5 // EXT1 port -#define HEATER_2_PIN PB4 // EXT2 port -#define HEATER_BED_PIN PB1 // CON2X3 hotbed port - -// -// These are FAN PWM pins on EXT0..EXT2 connectors. -// -//#define FAN_PIN PB9 // EXT0 port -#define ORIG_E0_AUTO_FAN_PIN PB9 // EXT0 port, used as main extruder fan -#define FAN1_PIN PB8 // EXT1 port -#define FAN2_PIN PB7 // EXT2 port - -// -// Temperature Sensors -// -#define TEMP_0_PIN PC2 // EXT0 port -#define TEMP_1_PIN PC1 // EXT1 port -#define TEMP_2_PIN PC0 // EXT2 port -#define TEMP_BED_PIN PC3 // CON2X3 hotbed port - -// -// Misc. Functions -// -#define LED_PWM PD12 // External LED, pin 2 on LED labeled connector - -// -// LCD / Controller -// -#if HAS_SPI_LCD - - #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) - // - // LCD display on J2 FFC40 - // Geeetech's LCD2004A Control Panel is very much like - // RepRapDiscount Smart Controller, but adds an FFC40 connector - // - #define LCD_PINS_RS PE6 // CS chip select /SS chip slave select - #define LCD_PINS_ENABLE PE14 // SID (MOSI) - #define LCD_PINS_D4 PD8 // SCK (CLK) clock - #define LCD_PINS_D5 PD9 - #define LCD_PINS_D6 PD10 - #define LCD_PINS_D7 PE15 - - #else - // - // Serial LCDs can be implemented in ExtUI - // - //#define LCD_UART_TX PD8 - //#define LCD_UART_RX PD9 - #endif - - #if HAS_GRAPHICAL_LCD - #define BOARD_ST7920_DELAY_1 DELAY_NS(96) - #define BOARD_ST7920_DELAY_2 DELAY_NS(48) - #define BOARD_ST7920_DELAY_3 DELAY_NS(715) - #endif - -#endif // HAS_SPI_LCD - -#if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) - // - // Geeetech's LCD2004A Control Panel is very much like - // RepRapDiscount Smart Controller, but adds an FFC40 connector - // connected with a flat wire to J2 connector on the board. - // - #define BTN_EN1 PE8 - #define BTN_EN2 PE9 - #define BTN_ENC PE13 - - #define GTM32_PRO_VB_USE_LCD_BEEPER - #define GTM32_PRO_VB_USE_EXT_SDCARD -#endif - -// -// Beeper -// -#ifdef GTM32_PRO_VB_USE_LCD_BEEPER - // This is pin 32 on J2 FFC40 and pin, goes to the beeper - // on Geeetech's version of RepRapDiscount Smart Controller - // (e.g. on Rostock 301) - #define BEEPER_PIN PE12 -#else - // This is the beeper on the board itself - #define BEEPER_PIN PB10 -#endif - -/** - * The on-board TF_CARD_SOCKET microSD card socket has no SD Detect pin wired. - * - * The FFC10 (SD_CARD) connector has the same pins as those routed to the FFC40 (J2) - * connector, which usually go to the SD Card slot on the Geeetech version of the - * RepRapDiscount Smart Controller. Both connectors have the card detect signal. - * - * The on-board SD card and the external card (on either SD_CARD or J2) are two - * separate devices and can work simultaneously. Unfortunately, Marlin only supports - * a single SPI Flash device (as of 2019-07-05) so only one is enabled here. - */ -#if ENABLED(GTM32_PRO_VB_USE_EXT_SDCARD) - // - // SD Card on RepRapDiscount Smart Controller (J2) or on SD_CARD connector - // - #define SS_PIN PC11 - #define SCK_PIN PC12 - #define MOSI_PIN PD2 - #define MISO_PIN PC8 - #define SD_DETECT_PIN PC7 -#else - // - // Use the on-board card socket labeled TF_CARD_SOCKET - // - #define SS_PIN PA4 - #define SCK_PIN PA5 - #define MOSI_PIN PA7 - #define MISO_PIN PA6 - #define SD_DETECT_PIN -1 // Card detect is not connected -#endif - -#define SDSS SS_PIN - -// -// ESP WiFi can be soldered to J9 connector which is wired to USART2. -// Must define WIFISUPPORT in Configuration.h for the printer. -// -#define ESP_WIFI_MODULE_COM 2 -#define ESP_WIFI_MODULE_BAUDRATE 115200 -#define ESP_WIFI_MODULE_RESET_PIN -1 diff --git a/Marlin/src/pins/stm32/pins_GTM32_REV_B.h b/Marlin/src/pins/stm32/pins_GTM32_REV_B.h deleted file mode 100644 index e02b8b9377b5..000000000000 --- a/Marlin/src/pins/stm32/pins_GTM32_REV_B.h +++ /dev/null @@ -1,232 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * 24 May 2018 - @chepo for STM32F103VET6 - * Schematic: https://github.com/chepo92/Smartto/blob/master/circuit_diagram/Rostock301/Hardware_GTM32_PRO_VB.pdf - */ - -#ifndef __STM32F1__ - #error "Oops! Select an STM32F1 board in 'Tools > Board.'" -#endif - -#define BOARD_NAME "GTM32 Pro VB" -#define DEFAULT_MACHINE_NAME "M201" - -//#define DISABLE_DEBUG - -// -// It is required to disable JTAG function because its pins are -// used as GPIO to drive the Y axis stepper. -// DO NOT ENABLE! -// -#define DISABLE_JTAG - -// -// If you don't need the SWDIO functionality (any more), you may -// disable SWD here to regain PA13/PA14 pins for other use. -// -//#define DISABLE_JTAGSWD - -// Ignore temp readings during development. -//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 - -// Enable EEPROM Emulation for this board as it doesn't have EEPROM -#define FLASH_EEPROM_EMULATION -#define E2END 0xFFF // 4KB - -// -// Limit Switches -// -#define X_MIN_PIN PE5 // ENDSTOPS 15,17 -#define X_MAX_PIN PE4 // ENDSTOPS 16,18 -#define Y_MIN_PIN PE3 // ENDSTOPS 9,11 -#define Y_MAX_PIN PE2 // ENDSTOPS 10,12 -#define Z_MIN_PIN PE1 // ENDSTOPS 3,5 -#define Z_MAX_PIN PE0 // ENDSTOPS 4,6 - -// -// Steppers -// -#define X_STEP_PIN PC6 -#define X_DIR_PIN PD13 -#define X_ENABLE_PIN PA8 - -#define Y_STEP_PIN PA12 -#define Y_DIR_PIN PA11 -#define Y_ENABLE_PIN PA15 - -#define Z_STEP_PIN PD6 -#define Z_DIR_PIN PD3 -#define Z_ENABLE_PIN PB3 - -// Extruder stepper pins -// NOTE: Numbering here is made according to EXT connector numbers, -// the FANx_PWM line numbering in the schematics is reverse. -// That is, E0_*_PIN are the E2_* lines connected to E2_A1 step -// stick that drives the EXT0 output on the board. -// -#define E0_STEP_PIN PC14 -#define E0_DIR_PIN PC13 -#define E0_ENABLE_PIN PC15 - -#define E1_STEP_PIN PA0 -#define E1_DIR_PIN PB6 -#define E1_ENABLE_PIN PA1 - -#define E2_STEP_PIN PB2 -#define E2_DIR_PIN PB11 -#define E2_ENABLE_PIN PC4 - -// -// Heaters / Fans - INFO: Extruders ports are in reverse order. Pin numbers here differ from schematic. Original firmware assumes heater, fan and temp sensor on port EXT0 PB0, PB9, PC2. -// -#define HEATER_0_PIN PB0 // EXT0 port. -#define HEATER_1_PIN PB5 // EXT1 port -#define HEATER_2_PIN PB4 // EXT2 port -#define HEATER_BED_PIN PB1 // CON2X3 hotbed port - -// -// These are FAN PWM pins on EXT0..EXT2 connectors. -// -//#define FAN_PIN PB9 // EXT0 port -#define FAN1_PIN PB8 // EXT1 port -#define FAN2_PIN PB7 // EXT2 port -#define ORIG_E0_AUTO_FAN_PIN PB9 // EXT0 port, used as main extruder fan - -// -// Temperature Sensors -// -#define TEMP_0_PIN PC2 // EXT0 port -#define TEMP_1_PIN PC1 // EXT1 port -#define TEMP_2_PIN PC0 // EXT2 port -#define TEMP_BED_PIN PC3 // CON2X3 hotbed port - -// -// Misc. Functions -// -#define LED_PWM PD12 // External LED, pin 2 on LED labeled connector - -// -// LCD / Controller -// -#if HAS_SPI_LCD - - #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) - - // - // LCD display on J2 FFC40 - // Geeetech's LCD2004A Control Panel is very much like - // RepRapDiscount Smart Controller, but adds an FFC40 connector - // connected with a flat wire to J2 connector on the board. - // - #define LCD_PINS_RS PE6 // CS chip select /SS chip slave select - #define LCD_PINS_ENABLE PE14 // SID (MOSI) - #define LCD_PINS_D4 PD8 // SCK (CLK) clock - #define LCD_PINS_D5 PD9 - #define LCD_PINS_D6 PD10 - #define LCD_PINS_D7 PE15 - - #define BTN_EN1 PE8 - #define BTN_EN2 PE9 - #define BTN_ENC PE13 - - //#define GTM32_PRO_VB_USE_LCD_BEEPER - #define GTM32_PRO_VB_USE_EXT_SDCARD - - #else - // - // Serial LCDs can be implemented in ExtUI - // - //#define LCD_UART_TX PD8 - //#define LCD_UART_RX PD9 - #endif - - #if HAS_GRAPHICAL_LCD - #ifndef ST7920_DELAY_1 - #define ST7920_DELAY_1 DELAY_NS(96) - #endif - #ifndef ST7920_DELAY_2 - #define ST7920_DELAY_2 DELAY_NS(48) - #endif - #ifndef ST7920_DELAY_3 - #define ST7920_DELAY_3 DELAY_NS(715) - #endif - #endif - -#endif // HAS_SPI_LCD - -// -// Beeper -// -#ifdef GTM32_PRO_VB_USE_LCD_BEEPER - // This is pin 32 on J2 FFC40 and pin, goes to the beeper - // on Geeetech's version of RepRapDiscount Smart Controller - // (e.g. on Rostock 301) - #define BEEPER_PIN PE12 -#else - // This is the beeper on the board itself - #define BEEPER_PIN PB10 -#endif - -/** - * The on-board TF_CARD_SOCKET microSD card socket has no SD Detect pin wired. - * - * The FFC10 (SD_CARD) connector has the same pins as those routed to the FFC40 (J2) - * connector, which usually go to the SD Card slot on the Geeetech version of the - * RepRapDiscount Smart Controller. Both connectors have the card detect signal. - * - * The on-board SD card and the external card (on either SD_CARD or J2) are two - * separate devices and can work simultaneously. Unfortunately, Marlin only supports - * a single SPI Flash device (as of 2019-07-05) so only one is enabled here. - */ -#if ENABLED(GTM32_PRO_VB_USE_EXT_SDCARD) - // - // SD Card on RepRapDiscount Smart Controller (J2) or on SD_CARD connector - // - #define SS_PIN PB12 // PC11 - #define SCK_PIN PB13 // PC12 // PC1 - #define MOSI_PIN PB15 // PD2 // PD2 - #define MISO_PIN PB14 // PC8 - #define SD_DETECT_PIN PC7 - -#else - // - // Use the on-board card socket labeled TF_CARD_SOCKET - // - #define SS_PIN PA4 - #define SCK_PIN PA5 - #define MOSI_PIN PA7 - #define MISO_PIN PA6 // PA6 - #define SD_DETECT_PIN -1 // Card detect is not connected -#endif - -#define SDSS SS_PIN - -// -// ESP WiFi can be soldered to J9 connector which is wired to USART2. -// Must define WIFISUPPORT in Configuration.h for the printer. -// -#define ESP_WIFI_MODULE_COM 2 -#define ESP_WIFI_MODULE_BAUDRATE 115200 -#define ESP_WIFI_MODULE_RESET_PIN -1 diff --git a/Marlin/src/pins/stm32/pins_JGAURORA_A5S_A1.h b/Marlin/src/pins/stm32/pins_JGAURORA_A5S_A1.h deleted file mode 100644 index 3849af3ae3a7..000000000000 --- a/Marlin/src/pins/stm32/pins_JGAURORA_A5S_A1.h +++ /dev/null @@ -1,130 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - - /** - * ╦╔═╗╔═╗┬ ┬┬─┐┌─┐┬─┐┌─┐╔═╗┌─┐┬─┐┬ ┬┌┬┐ ┌─┐┌─┐┌┬┐ - * ║║ ╦╠═╣│ │├┬┘│ │├┬┘├─┤╠╣ │ │├┬┘│ ││││ │ │ ││││ - * ╚╝╚═╝╩ ╩└─┘┴└─└─┘┴└─┴ ┴╚ └─┘┴└─└─┘┴ ┴o└─┘└─┘┴ ┴ - * Pin assignments for 32-bit JGAurora A5S & A1 - */ - -#ifndef __STM32F1__ - #error "Oops! Select an STM32F1 board in 'Tools > Board.'" -#elif HOTENDS > 1 || E_STEPPERS > 1 - #error "JGAurora 32-bit board only supports 1 hotend / E-stepper. Comment out this line to continue." -#endif -#define BOARD_INFO_NAME "JGAurora A5S A1 board" - -#ifndef STM32_XL_DENSITY - #define STM32_XL_DENSITY -#endif - -// #define MCU_STM32F103ZE // not yet required -// Enable EEPROM Emulation for this board, so that we don't overwrite factory data - -//#define I2C_EEPROM // AT24C64 -//#define E2END 0x7FFF // 64KB -//#define FLASH_EEPROM_EMULATION -//#define E2END 0xFFF // 4KB -//#define E2END uint32(EEPROM_START_ADDRESS + (EEPROM_PAGE_SIZE * 2) - 1) -//#define EEPROM_CHITCHAT -//#define DEBUG_EEPROM_READWRITE - -// -// Limit Switches -// -#define X_STOP_PIN PC6 -#define Y_STOP_PIN PG8 -#define Z_STOP_PIN PG7 -//#define X_MAX_PIN PC5 -//#define Y_MAX_PIN PC4 -//#define Z_MAX_PIN PB0 - -// -// Steppers -// -#define X_STEP_PIN PD6 -#define X_DIR_PIN PD3 -#define X_ENABLE_PIN PG9 - -#define Y_STEP_PIN PG12 -#define Y_DIR_PIN PG11 -#define Y_ENABLE_PIN PG13 - -#define Z_STEP_PIN PG15 -#define Z_DIR_PIN PG14 -#define Z_ENABLE_PIN PB8 - -#define E0_STEP_PIN PE2 -#define E0_DIR_PIN PB9 -#define E0_ENABLE_PIN PE3 - -#define E1_STEP_PIN PE5 -#define E1_DIR_PIN PE4 -#define E1_ENABLE_PIN PE6 - -// -// Temperature Sensors -// -#define TEMP_0_PIN PC2 -#define TEMP_BED_PIN PC1 - -// -// Heaters / Fans -// -#define HEATER_0_PIN PA2 -#define HEATER_BED_PIN PA3 - -#define FAN_PIN PA1 - -#define FIL_RUNOUT_PIN PC7 - -// -// LCD -// -#define LCD_BACKLIGHT_PIN PF11 -#define FSMC_CS_PIN PD7 -#define FSMC_RS_PIN PG0 - -#define LCD_USE_DMA_FSMC // Use DMA transfers to send data to the TFT -#define FSMC_DMA_DEV DMA2 -#define FSMC_DMA_CHANNEL DMA_CH5 - -// -// SD Card -// -#define SD_DETECT_PIN PF10 - -// -// Misc. -// -#define BEEPER_PIN PC3 // use PB7 to shut up if desired -#define LED_PIN PC13 - -// -// Touch support -// -#if ENABLED(TOUCH_BUTTONS) - #define TOUCH_CS_PIN PA4 - #define TOUCH_INT_PIN PC4 -#endif diff --git a/Marlin/src/pins/stm32/pins_LERDGE_K.h b/Marlin/src/pins/stm32/pins_LERDGE_K.h deleted file mode 100644 index 2b3ad6019920..000000000000 --- a/Marlin/src/pins/stm32/pins_LERDGE_K.h +++ /dev/null @@ -1,177 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if !defined(STM32F4) && !defined(STM32F4xx) - #error "Oops! Select an STM32F4 board in 'Tools > Board.'" -#elif HOTENDS > 2 || E_STEPPERS > 2 - #error "LERDGE K supports up to 2 hotends / E-steppers." -#endif - -#define BOARD_INFO_NAME "Lerdge K" -#define DEFAULT_MACHINE_NAME "LERDGE" - -#define I2C_EEPROM - -// Ignore temp readings during develpment. -//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 - -// -// Servos -// -//#define SERVO0_PIN PD12 - -// -// Limit Switches -// -#define X_STOP_PIN PG3 -#define Y_STOP_PIN PG4 -#define Z_STOP_PIN PG5 - -// -// Z Probe (when not Z_MIN_PIN) -// -//#ifndef Z_MIN_PROBE_PIN -// #define Z_MIN_PROBE_PIN PB15 -//#endif - -// -// Filament runout -// -#define FIL_RUNOUT_PIN PE6 -#define FIL_RUNOUT2_PIN PE7 - -// -// Steppers -// -#define X_STEP_PIN PG1 -#define X_DIR_PIN PB10 -#define X_ENABLE_PIN PG0 -//#ifndef X_CS_PIN -// #define X_CS_PIN PE0 -//#endif - -#define Y_STEP_PIN PF14 -#define Y_DIR_PIN PF15 -#define Y_ENABLE_PIN PF13 -//#ifndef Y_CS_PIN -// #define Y_CS_PIN PE1 -//#endif - -#define Z_STEP_PIN PF11 -#define Z_DIR_PIN PF12 -#define Z_ENABLE_PIN PC5 -//#ifndef Z_CS_PIN -// #define Z_CS_PIN PE2 -//#endif - -#define E0_STEP_PIN PC14 -#define E0_DIR_PIN PC13 -#define E0_ENABLE_PIN PC15 -//#ifndef E0_CS_PIN -// #define E0_CS_PIN PE3 -//#endif - -#define E1_STEP_PIN PF1 -#define E1_DIR_PIN PF0 -#define E1_ENABLE_PIN PF2 -//#ifndef E1_CS_PIN -// #define E1_CS_PIN PE4 -//#endif - -// -// Temperature Sensors -// -#define TEMP_0_PIN PC1 // Analog Input -#define TEMP_1_PIN PC2 // Analog Input -#define TEMP_BED_PIN PC0 // Analog Input - -// -// Heaters / Fans -// -#define HEATER_0_PIN PA1 -#define HEATER_1_PIN PA0 -#define HEATER_BED_PIN PA2 - -#ifndef FAN_PIN - #define FAN_PIN PC15 -#endif -#define FAN1_PIN PF6 -#define FAN2_PIN PF7 - -#define ORIG_E0_AUTO_FAN_PIN FAN1_PIN // Use this by NOT overriding E0_AUTO_FAN_PIN - -// -// LED / Lighting -// -//#define CASE_LIGHT_PIN_CI -1 -//#define CASE_LIGHT_PIN_DO -1 -//#define NEOPIXEL_PIN -1 - -// -// Prusa i3 MK2 Multi-Material Multiplexer Support -// -//#define E_MUX0_PIN -1 -//#define E_MUX1_PIN -1 - -// -// SD support -// -#define SDIO_SUPPORT - -// -// Misc. Functions -// -#define SDSS PC11 -#define LED_PIN PC7 // Alive -#define PS_ON_PIN -1 -#define KILL_PIN -1 -#define POWER_LOSS_PIN -1 // Power-loss / nAC_FAULT - -#define SCK_PIN PC12 -#define MISO_PIN PC8 -#define MOSI_PIN PD2 -#define SS_PIN PC11 - -// -// LCD / Controller -// - -// TODO: Replace these with the correct FSMC pins, once known -#define SD_DETECT_PIN -1 -#define BEEPER_PIN PD12 -#define LCD_PINS_RS -1 -#define LCD_PINS_ENABLE -1 -#define LCD_PINS_D4 -1 -#define LCD_PINS_D5 -1 -#define LCD_PINS_D6 -1 -#define LCD_PINS_D7 -1 - -#define BTN_EN1 PE3 -#define BTN_EN2 PE4 -#define BTN_ENC PE2 - -// -// ST7920 Delays -// -#if HAS_GRAPHICAL_LCD - #define BOARD_ST7920_DELAY_1 DELAY_NS(96) - #define BOARD_ST7920_DELAY_2 DELAY_NS(48) - #define BOARD_ST7920_DELAY_3 DELAY_NS(715) -#endif diff --git a/Marlin/src/pins/stm32/pins_LERDGE_X.h b/Marlin/src/pins/stm32/pins_LERDGE_X.h deleted file mode 100644 index f498b7d0b9f6..000000000000 --- a/Marlin/src/pins/stm32/pins_LERDGE_X.h +++ /dev/null @@ -1,174 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if !defined(STM32F4) && !defined(STM32F4xx) - #error "Oops! Select an STM32F4 board in 'Tools > Board.'" -#elif HOTENDS > 2 || E_STEPPERS > 2 - #error "LERDGE X supports up to 2 hotends / E-steppers." -#endif - -#define BOARD_INFO_NAME "Lerdge X" -#define DEFAULT_MACHINE_NAME "LERDGE" - -//#define I2C_EEPROM - -// -// Servos -// -//#define SERVO0_PIN PD12 -//#define SERVO1_PIN -1 - -// -// Limit Switches -// -#define X_STOP_PIN PB12 -#define Y_STOP_PIN PB13 -#define Z_STOP_PIN PB14 - -// -// Filament runout -// -#define FIL_RUNOUT_PIN PE1 - -// -// Z Probe (when not Z_MIN_PIN) -// -//#ifndef Z_MIN_PROBE_PIN -// #define Z_MIN_PROBE_PIN PB15 -//#endif - -// -// Steppers -// -#define X_STEP_PIN PB10 -#define X_DIR_PIN PB2 -#define X_ENABLE_PIN PB11 -//#ifndef X_CS_PIN -// #define X_CS_PIN PD1 -//#endif - -#define Y_STEP_PIN PB0 -#define Y_DIR_PIN PC5 -#define Y_ENABLE_PIN PB1 -//#ifndef Y_CS_PIN -// #define Y_CS_PIN PE12 -//#endif - -#define Z_STEP_PIN PA7 -#define Z_DIR_PIN PA6 -#define Z_ENABLE_PIN PC4 -//#ifndef Z_CS_PIN -// #define Z_CS_PIN PD5 -//#endif - -#define E0_STEP_PIN PA4 -#define E0_DIR_PIN PA3 -#define E0_ENABLE_PIN PA5 -//#ifndef E0_CS_PIN -// #define E0_CS_PIN PB4 -//#endif - -#define E1_STEP_PIN -1 -#define E1_DIR_PIN -1 -#define E1_ENABLE_PIN -1 -//#ifndef E1_CS_PIN -// #define E1_CS_PIN PE5 -//#endif - -// -// Temperature Sensors -// -#define TEMP_0_PIN PC0 // Analog Input -#define TEMP_1_PIN -1 // Analog Input -#define TEMP_BED_PIN PC1 // Analog Input - -// -// Heaters / Fans -// -#define HEATER_0_PIN PA1 -#define HEATER_1_PIN -1 -#define HEATER_BED_PIN PA2 - -#ifndef FAN_PIN -// #define FAN_PIN PC15 -#endif -#define FAN1_PIN PC15 -#define FAN2_PIN PA0 - -#define ORIG_E0_AUTO_FAN_PIN PC15 // Use this by NOT overriding E0_AUTO_FAN_PIN - -// -// Prusa i3 MK2 Multi Material Multiplexer Support -// -//#define E_MUX0_PIN -1 -//#define E_MUX1_PIN -1 - -// -// LED / Lighting -// -//#define CASE_LIGHT_PIN_CI -1 -//#define CASE_LIGHT_PIN_DO -1 -//#define NEOPIXEL_PIN -1 - -// -// Misc. Functions -// -#define SDSS PC11 -#define LED_PIN PC7 // Alive -#define PS_ON_PIN -1 -#define KILL_PIN -1 -#define POWER_LOSS_PIN -1 // Power-loss / nAC_FAULT - -#define SCK_PIN PC12 -#define MISO_PIN PC8 -#define MOSI_PIN PD2 -#define SS_PIN PC11 - -// -// SD support -// -#define SDIO_SUPPORT - -// -// LCD / Controller -// - -// The LCD is initialized in FSMC mode -#define SD_DETECT_PIN -1 -#define BEEPER_PIN PD12 - -#define BTN_EN1 PE3 -#define BTN_EN2 PE4 -#define BTN_ENC PE2 - -#define LCD_RESET_PIN PD6 -#define LCD_BACKLIGHT_PIN PD3 -#define FSMC_CS_PIN PD4 -#define FSMC_RS_PIN PD11 -#define TOUCH_CS PB6 - -// -// ST7920 Delays -// -#if HAS_GRAPHICAL_LCD - #define BOARD_ST7920_DELAY_1 DELAY_NS(96) - #define BOARD_ST7920_DELAY_2 DELAY_NS(48) - #define BOARD_ST7920_DELAY_3 DELAY_NS(715) -#endif diff --git a/Marlin/src/pins/stm32/pins_LONGER3D_LK.h b/Marlin/src/pins/stm32/pins_LONGER3D_LK.h deleted file mode 100644 index 66c5b55ecb74..000000000000 --- a/Marlin/src/pins/stm32/pins_LONGER3D_LK.h +++ /dev/null @@ -1,170 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Longer3D LK1/LK2 & Alfawise U20/U30 (STM32F103VET6) board pin assignments - */ - -#if !defined(__STM32F1__) && !defined(STM32F1xx) - #error "Oops! Select a STM32F1 board in 'Tools > Board.'" -#elif HOTENDS > 1 || E_STEPPERS > 1 - #error "Longer3D board only supports 1 hotend / E-stepper. Comment out this line to continue." -#endif - -#define BOARD_INFO_NAME "Longer3D" -#define ALFAWISE_UX0 // Common to all Longer3D STM32F1 boards (used for Open drain mosfets) - -//#define DISABLE_DEBUG // We still want to debug with STLINK... -#define DISABLE_JTAG // We free the jtag pins (PA15) but keep STLINK - // Release PB4 (STEP_X_PIN) from JTAG NRST role. -// -// Limit Switches -// -#define X_MIN_PIN PC1 // pin 16 -#define X_MAX_PIN PC0 // pin 15 (Filament sensor on Alfawise setup) -#define Y_MIN_PIN PC15 // pin 9 -#define Y_MAX_PIN PC14 // pin 8 (Unused in stock Alfawise setup) -#define Z_MIN_PIN PE6 // pin 5 Standard Endstop or Z_Probe endstop function -#define Z_MAX_PIN PE5 // pin 4 (Unused in stock Alfawise setup) - // May be used for BLTouch Servo function on older variants (<= V08) -#define ONBOARD_ENDSTOPPULLUPS - -// -// Filament Sensor -// -#ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN PC0 // XMAX plug on PCB used as filament runout sensor on Alfawise boards (inverting true) -#endif - -// -// Steppers -// -#define X_ENABLE_PIN PB5 // pin 91 -#define X_STEP_PIN PB4 // pin 90 -#define X_DIR_PIN PB3 // pin 89 - -#define Y_ENABLE_PIN PB8 // pin 95 -#define Y_STEP_PIN PB7 // pin 93 -#define Y_DIR_PIN PB6 // pin 92 - -#define Z_ENABLE_PIN PE1 // pin 98 -#define Z_STEP_PIN PE0 // pin 97 -#define Z_DIR_PIN PB9 // pin 96 - -#define E0_ENABLE_PIN PE4 // pin 3 -#define E0_STEP_PIN PE3 // pin 2 -#define E0_DIR_PIN PE2 // pin 1 - -// -// Temperature Sensors -// -#define TEMP_0_PIN PA0 // pin 23 (Nozzle 100K/3950 thermistor) -#define TEMP_BED_PIN PA1 // pin 24 (Hot Bed 100K/3950 thermistor) - -// -// Heaters / Fans -// -#define HEATER_0_PIN PD3 // pin 84 (Nozzle Heat Mosfet) -#define HEATER_BED_PIN PA8 // pin 67 (Hot Bed Mosfet) - -#define FAN_PIN PA15 // pin 77 (4cm Fan) -#define FAN_SOFT_PWM // Required to avoid issues with heating or STLink -#define FAN_MIN_PWM 35 // Fan will not start in 1-30 range -#define FAN_MAX_PWM 255 - -//#define BEEPER_PIN PD13 // pin 60 (Servo PWM output 5V/GND on Board V0G+) made for BL-Touch sensor - // Can drive a PC Buzzer, if connected between PWM and 5V pins - -#define LED_PIN PC2 // pin 17 - -// -// PWM for a servo probe -// Other servo devices are not supported on this board! -// -#if HAS_Z_SERVO_PROBE - #define SERVO0_PIN PD13 // Open drain PWM pin on the V0G (GND or floating 5V) - #define SERVO0_PWM_OD // Comment this if using PE5 - - //#define SERVO0_PIN PE5 // Pulled up PWM pin on the V08 (3.3V or 0) - //#undef Z_MAX_PIN // Uncomment if using ZMAX connector (PE5) -#endif - -/** - * Note: Alfawise screens use various TFT controllers. Supported screens - * are based on the ILI9341, ILI9328 and ST7798V. Define init sequences for - * other screens in u8g_dev_tft_320x240_upscale_from_128x64.cpp - * - * If the screen stays white, disable 'LCD_RESET_PIN' to let the bootloader - * init the screen. - * - * Setting an 'LCD_RESET_PIN' may cause a flicker when entering the LCD menu - * because Marlin uses the reset as a failsafe to revive a glitchy LCD. - */ - -#define LCD_RESET_PIN PC4 // pin 33 -#define LCD_BACKLIGHT_PIN PD12 // pin 59 -#define FSMC_CS_PIN PD7 // pin 88 = FSMC_NE1 -#define FSMC_RS_PIN PD11 // pin 58 A16 Register. Only one address needed - -#define LCD_USE_DMA_FSMC // Use DMA transfers to send data to the TFT -#define FSMC_DMA_DEV DMA2 -#define FSMC_DMA_CHANNEL DMA_CH5 - -#define DOGLCD_MOSI -1 // Prevent auto-define by Conditionals_post.h -#define DOGLCD_SCK -1 - -/** - * Note: Alfawise U20/U30 boards DON'T use SPI2, as the hardware designer - * mixed up MOSI and MISO pins. SPI is managed in SW, and needs pins - * declared below. - */ -#if ENABLED(TOUCH_BUTTONS) - #define TOUCH_CS_PIN PB12 // pin 51 SPI2_NSS - #define TOUCH_SCK_PIN PB13 // pin 52 - #define TOUCH_MOSI_PIN PB14 // pin 53 - #define TOUCH_MISO_PIN PB15 // pin 54 - #define TOUCH_INT_PIN PC6 // pin 63 (PenIRQ coming from ADS7843) -#endif - -// -// Persistent Storage -// If no option is selected below the SD Card will be used -// -//#define SPI_EEPROM -#define FLASH_EEPROM_EMULATION - -#undef E2END -#if ENABLED(SPI_EEPROM) - // SPI1 EEPROM Winbond W25Q64 (8MB/64Mbits) - #define SPI_CHAN_EEPROM1 1 - #define SPI_EEPROM1_CS PC5 // pin 34 - #define EEPROM_SCK BOARD_SPI1_SCK_PIN // PA5 pin 30 - #define EEPROM_MISO BOARD_SPI1_MISO_PIN // PA6 pin 31 - #define EEPROM_MOSI BOARD_SPI1_MOSI_PIN // PA7 pin 32 - #define EEPROM_PAGE_SIZE 0x1000U // 4KB (from datasheet) - #define E2END ((16 * EEPROM_PAGE_SIZE)-1) // Limit to 64KB for now... -#elif ENABLED(FLASH_EEPROM_EMULATION) - // SoC Flash (framework-arduinoststm32-maple/STM32F1/libraries/EEPROM/EEPROM.h) - #define EEPROM_START_ADDRESS (0x8000000UL + (512 * 1024) - 2 * EEPROM_PAGE_SIZE) - #define EEPROM_PAGE_SIZE (0x800U) // 2KB, but will use 2x more (4KB) - #define E2END (EEPROM_PAGE_SIZE - 1) -#else - #define E2END (0x7FFU) // On SD, Limit to 2KB, require this amount of RAM -#endif diff --git a/Marlin/src/pins/stm32/pins_MALYAN_M200.h b/Marlin/src/pins/stm32/pins_MALYAN_M200.h deleted file mode 100644 index 624c59ebea78..000000000000 --- a/Marlin/src/pins/stm32/pins_MALYAN_M200.h +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * MALYAN M200 pin assignments - */ - -#if NONE(__STM32F1__, STM32F1xx, STM32F0xx) - #error "Oops! Select an STM32 board in your IDE." -#endif - -#define BOARD_INFO_NAME "Malyan M200" - -// Enable EEPROM Emulation for this board -// This setting should probably be in configuration.h -// but it is literally the only board which uses it. -#define FLASH_EEPROM_EMULATION - -#define SDSS SS_PIN - -// Based on PWM timer usage, we have to use these timers and soft PWM for the fans -// On STM32F103: -// PB3, PB6, PB7, and PB8 can be used with pwm, which rules out TIM2 and TIM4. -// On STM32F070, 16 and 17 are in use, but 1 and 3 are available. -#undef STEP_TIMER -#undef TEMP_TIMER -#define STEP_TIMER 1 -#define TEMP_TIMER 3 - -// -// Limit Switches -// -#define X_MIN_PIN PB4 -#define Y_MIN_PIN PA15 -#define Z_MIN_PIN PB5 - -// -// Steppers -// -// X & Y enable are the same -#define X_STEP_PIN PB14 -#define X_DIR_PIN PB15 -#define X_ENABLE_PIN PA8 - -#define Y_STEP_PIN PB12 -#define Y_DIR_PIN PB13 -#define Y_ENABLE_PIN PA8 - -#define Z_STEP_PIN PB10 -#define Z_DIR_PIN PB2 -#define Z_ENABLE_PIN PB11 - -#define E0_STEP_PIN PB0 -#define E0_DIR_PIN PC13 -#define E0_ENABLE_PIN PB1 - -// -// Temperature Sensors -// -#define TEMP_0_PIN PA0 // Analog Input (HOTEND0 thermistor) -#define TEMP_BED_PIN PA1 // Analog Input (BED thermistor) - -// -// Heaters / Fans -// -#define HEATER_0_PIN PB6 // HOTEND0 MOSFET -#define HEATER_BED_PIN PB7 // BED MOSFET - -#define MALYAN_FAN1_PIN PB8 // FAN1 header on board - PRINT FAN -#define MALYAN_FAN2_PIN PB3 // FAN2 header on board - CONTROLLER FAN - -#define FAN1_PIN MALYAN_FAN2_PIN diff --git a/Marlin/src/pins/stm32/pins_MKS_ROBIN.h b/Marlin/src/pins/stm32/pins_MKS_ROBIN.h deleted file mode 100644 index 3b10bae139e4..000000000000 --- a/Marlin/src/pins/stm32/pins_MKS_ROBIN.h +++ /dev/null @@ -1,159 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * MKS Robin (STM32F130ZET6) board pin assignments - * - * https://github.com/makerbase-mks/MKS-Robin/tree/master/MKS%20Robin/Hardware - */ - -#ifndef __STM32F1__ - #error "Oops! Select an STM32F1 board in 'Tools > Board.'" -#elif HOTENDS > 2 || E_STEPPERS > 2 - #error "MKS Robin supports up to 2 hotends / E-steppers. Comment out this line to continue." -#endif - -#define BOARD_INFO_NAME "MKS Robin" - -// -// Release PB4 (Y_ENABLE_PIN) from JTAG NRST role -// -#define DISABLE_JTAG - -// -// Servos -// -#define SERVO0_PIN PC3 // XS1 - 5 -#define SERVO1_PIN PA1 // XS1 - 6 -#define SERVO2_PIN PF9 // XS2 - 5 -#define SERVO3_PIN PF8 // XS2 - 6 - -// -// Limit Switches -// -#define X_MIN_PIN PB12 -#define X_MAX_PIN PB0 -#define Y_MIN_PIN PC5 -#define Y_MAX_PIN PC4 -#define Z_MIN_PIN PA4 -#define Z_MAX_PIN PF7 - -// -// Steppers -// -#define X_ENABLE_PIN PB9 -#define X_STEP_PIN PB8 -#define X_DIR_PIN PB5 - -#define Y_ENABLE_PIN PB4 -#define Y_STEP_PIN PG15 -#define Y_DIR_PIN PG10 - -#define Z_ENABLE_PIN PD7 -#define Z_STEP_PIN PD3 -#define Z_DIR_PIN PG14 - -#define E0_ENABLE_PIN PG13 -#define E0_STEP_PIN PG8 -#define E0_DIR_PIN PA15 - -#define E1_ENABLE_PIN PA12 -#define E1_STEP_PIN PA11 -#define E1_DIR_PIN PA8 - -// -// Temperature Sensors -// -#define TEMP_0_PIN PC1 // TH1 -#define TEMP_1_PIN PC2 // TH2 -#define TEMP_BED_PIN PC0 // TB1 - -// -// Heaters / Fans -// -#define HEATER_0_PIN PC7 // HEATER1 -#define HEATER_1_PIN PA6 // HEATER2 -#define HEATER_BED_PIN PC6 // HOT BED - -#define FAN_PIN PA7 // FAN - -/** - * Note: MKS Robin board is using SPI2 interface. Make sure your stm32duino library is configured accordingly - */ -//#define MAX6675_SS_PIN PE5 // TC1 - CS1 -//#define MAX6675_SS_PIN PE6 // TC2 - CS2 - -#define POWER_LOSS_PIN PA2 // PW_DET -#define PS_ON_PIN PA3 // PW_OFF -#define FIL_RUNOUT_PIN PF11 // MT_DET - -#define BEEPER_PIN PC13 -#define LED_PIN PB2 - -/** - * Note: MKS Robin TFT screens use various TFT controllers - * Supported screens are based on the ILI9341, ST7789V and ILI9328 (320x240) - * ILI9488 is not supported - * Define init sequences for other screens in u8g_dev_tft_320x240_upscale_from_128x64.cpp - * - * If the screen stays white, disable 'LCD_RESET_PIN' - * to let the bootloader init the screen. - * - * Setting an 'LCD_RESET_PIN' may cause a flicker when entering the LCD menu - * because Marlin uses the reset as a failsafe to revive a glitchy LCD. - */ -//#define LCD_RESET_PIN PF6 -#define LCD_BACKLIGHT_PIN PG11 -#define FSMC_CS_PIN PG12 // NE4 -#define FSMC_RS_PIN PF0 // A0 - -#define LCD_USE_DMA_FSMC // Use DMA transfers to send data to the TFT -#define FSMC_DMA_DEV DMA2 -#define FSMC_DMA_CHANNEL DMA_CH5 - -#if ENABLED(TOUCH_BUTTONS) - #define TOUCH_CS_PIN PB1 // SPI2_NSS - #define TOUCH_SCK_PIN PB13 // SPI2_SCK - #define TOUCH_MISO_PIN PB14 // SPI2_MISO - #define TOUCH_MOSI_PIN PB15 // SPI2_MOSI -#endif - -// SPI1(PA7) & SPI3(PB5) not available -#define ENABLE_SPI2 - -#if ENABLED(SDIO_SUPPORT) - #define SCK_PIN PB13 // SPI2 - #define MISO_PIN PB14 // SPI2 - #define MOSI_PIN PB15 // SPI2 - #define SS_PIN -1 // PB12 is X- - #define SD_DETECT_PIN PF12 // SD_CD -#else - // SD as custom software SPI (SDIO pins) - #define SCK_PIN PC12 - #define MISO_PIN PC8 - #define MOSI_PIN PD2 - #define SS_PIN -1 - #define ONBOARD_SD_CS_PIN PC11 - #define SDSS PD2 - #define SD_DETECT_PIN -1 -#endif diff --git a/Marlin/src/pins/stm32/pins_MKS_ROBIN2.h b/Marlin/src/pins/stm32/pins_MKS_ROBIN2.h deleted file mode 100644 index 5d97de12ebf2..000000000000 --- a/Marlin/src/pins/stm32/pins_MKS_ROBIN2.h +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#ifndef STM32F4 - #error "Oops! Select an STM32F4 board in 'Tools > Board.'" -#elif HOTENDS > 2 || E_STEPPERS > 2 - #error "MKS_ROBIN2 supports up to 2 hotends / E-steppers." -#endif - -#ifndef BOARD_INFO_NAME - #define BOARD_NAME "MKS_ROBIN2" -#endif - -#ifndef DEFAULT_MACHINE_NAME - #define DEFAULT_MACHINE_NAME BOARD_INFO_NAME -#endif - -#define SRAM_EEPROM_EMULATION - -// -// Limit Switches -// -#define X_MIN_PIN PG8 -#define X_MAX_PIN PG7 -#define Y_MIN_PIN PG6 -#define Y_MAX_PIN PG5 -#define Z_MIN_PIN PG4 -#define Z_MAX_PIN PG3 - -// -// Servos -// -#define SERVO0_PIN PB0 // XS2-5 -#define SERVO1_PIN PF7 // XS1-5 -#define SERVO2_PIN PF8 // XS1-6 - -// -// Steppers -// -#define X_STEP_PIN PE6 -#define X_DIR_PIN PE5 -#define X_ENABLE_PIN PC13 - -#define Y_STEP_PIN PE3 -#define Y_DIR_PIN PE2 -#define Y_ENABLE_PIN PE4 - -#define Z_STEP_PIN PE0 -#define Z_DIR_PIN PB9 -#define Z_ENABLE_PIN PE1 - -#define E0_STEP_PIN PG10 -#define E0_DIR_PIN PG9 -#define E0_ENABLE_PIN PB8 - -#define E1_STEP_PIN PD3 -#define E1_DIR_PIN PA15 -#define E1_ENABLE_PIN PD6 - - -// -// Temperature Sensors -// -#define TEMP_0_PIN PC1 // T1 <-> E0 -#define TEMP_1_PIN PC2 // T2 <-> E1 -#define TEMP_BED_PIN PC0 // T0 <-> Bed - -// -// Heaters / Fans -// -#define HEATER_0_PIN PF3 // Heater0 -#define HEATER_1_PIN PF2 // Heater1 -#define HEATER_BED_PIN PF4 // Hotbed -#define FAN_PIN PA7 // Fan0 - -// -// Misc. Functions -// -#define SDSS -1 // PB12 - -#define SD_DETECT_PIN PF9 -#define BEEPER_PIN PG2 diff --git a/Marlin/src/pins/stm32/pins_MKS_ROBIN_LITE.h b/Marlin/src/pins/stm32/pins_MKS_ROBIN_LITE.h deleted file mode 100644 index 1a7d664899c6..000000000000 --- a/Marlin/src/pins/stm32/pins_MKS_ROBIN_LITE.h +++ /dev/null @@ -1,137 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#ifndef __STM32F1__ - #error "Oops! Select an STM32F1 board in 'Tools > Board.'" -#elif HOTENDS > 1 || E_STEPPERS > 1 - #error "MKS Robin Lite supports only 1 hotend / E-stepper. Comment out this line to continue." -#endif - -#ifndef BOARD_INFO_NAME - #define BOARD_INFO_NAME "MKS Robin Lite" -#endif -#define BOARD_WEBSITE_URL "github.com/makerbase-mks" - -//#define DISABLE_DEBUG -#define DISABLE_JTAG -#define ENABLE_SPI2 - -// -// Limit Switches -// -#define X_STOP_PIN PC13 -#define Y_STOP_PIN PC0 -#define Z_MIN_PIN PC12 -#define Z_MAX_PIN PB9 - -// -// Steppers -// -#define X_STEP_PIN PC6 -#define X_DIR_PIN PB12 -#define X_ENABLE_PIN PB10 - -#define Y_STEP_PIN PB11 -#define Y_DIR_PIN PB2 -#define Y_ENABLE_PIN PB10 - -#define Z_STEP_PIN PB1 -#define Z_DIR_PIN PC5 -#define Z_ENABLE_PIN PB10 - -#define E0_STEP_PIN PC4 -#define E0_DIR_PIN PA5 -#define E0_ENABLE_PIN PA4 - -// -// Heaters / Fans -// -#define HEATER_0_PIN PC9 -#define FAN_PIN PA8 -#define HEATER_BED_PIN PC8 - -// -// Temperature Sensors -// -#define TEMP_BED_PIN PA1 -#define TEMP_0_PIN PA0 - -#define FIL_RUNOUT_PIN PB8 // MT_DET - -// -// LCD Pins -// -#if HAS_SPI_LCD - #define BEEPER_PIN PD2 - #define BTN_ENC PB3 - #define LCD_PINS_RS PC3 - - #define BTN_EN1 PB5 - #define BTN_EN2 PB4 - - #define LCD_PINS_ENABLE PC2 - - #if ENABLED(MKS_MINI_12864) - - #define LCD_BACKLIGHT_PIN -1 - #define LCD_RESET_PIN -1 - #define DOGLCD_A0 PC1 - #define DOGLCD_CS PC2 - #define DOGLCD_SCK PB13 - #define DOGLCD_MOSI PB15 - - #else // !MKS_MINI_12864 - - #define LCD_PINS_D4 PC1 - #if ENABLED(ULTIPANEL) - #define LCD_PINS_D5 -1 - #define LCD_PINS_D6 -1 - #define LCD_PINS_D7 -1 - #endif - - #endif // !MKS_MINI_12864 - -#endif // HAS_SPI_LCD - -// Motor current PWM pins -#define MOTOR_CURRENT_PWM_XY_PIN PB0 -#define MOTOR_CURRENT_PWM_Z_PIN PA7 -#define MOTOR_CURRENT_PWM_E_PIN PA6 -#define MOTOR_CURRENT_PWM_RANGE (65535/10/3.3) // (255 * (1000mA / 65535)) * 257 = 1000 is equal 1.6v Vref in turn equal 1Amp -#define DEFAULT_PWM_MOTOR_CURRENT { 1000, 1000, 1000 } // 1.05Amp per driver, here is XY, Z and E. This values determined empirically. - -// -// SD Card -// -#define ENABLE_SPI2 -#define SD_DETECT_PIN PC10 -#define SCK_PIN PB13 -#define MISO_PIN P1B4 -#define MOSI_PIN P1B5 -#define SS_PIN PA15 - -#if HAS_GRAPHICAL_LCD - #define BOARD_ST7920_DELAY_1 DELAY_NS(125) - #define BOARD_ST7920_DELAY_2 DELAY_NS(125) - #define BOARD_ST7920_DELAY_3 DELAY_NS(125) -#endif diff --git a/Marlin/src/pins/stm32/pins_MKS_ROBIN_LITE3.h b/Marlin/src/pins/stm32/pins_MKS_ROBIN_LITE3.h deleted file mode 100644 index 9a404ec64d24..000000000000 --- a/Marlin/src/pins/stm32/pins_MKS_ROBIN_LITE3.h +++ /dev/null @@ -1,153 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * MKS Robin Lite 3 (STM32F103RCT6) board pin assignments - */ - -#ifndef __STM32F1__ - #error "Oops! Select an STM32F1 board in 'Tools > Board.'" -#elif HOTENDS > 2 || E_STEPPERS > 2 - #error "MKS Robin Lite3 supports up to 2 hotends / E-steppers. Comment out this line to continue." -#endif - -#ifndef BOARD_INFO_NAME - #define BOARD_INFO_NAME "MKS Robin Lite3" -#endif -#define BOARD_WEBSITE_URL "github.com/makerbase-mks" - -//#define DISABLE_DEBUG -#define DISABLE_JTAG -#define ENABLE_SPI2 - -// -// Servos -// -#define SERVO0_PIN PA3 - -// -// Limit Switches -// -#define X_STOP_PIN PA12 -#define Y_STOP_PIN PA11 -#define Z_MIN_PIN PC6 -#define Z_MAX_PIN PB1 - -// -// Steppers -// -#define X_STEP_PIN PC0 -#define X_DIR_PIN PB2 -#define X_ENABLE_PIN PC13 - -#define Y_STEP_PIN PC2 -#define Y_DIR_PIN PB9 -#define Y_ENABLE_PIN PB12 - -#define Z_STEP_PIN PB7 -#define Z_DIR_PIN PB6 -#define Z_ENABLE_PIN PB8 - -#define E0_STEP_PIN PB4 -#define E0_DIR_PIN PB3 -#define E0_ENABLE_PIN PB5 - -#define E1_STEP_PIN PC12 -#define E1_DIR_PIN PC11 -#define E1_ENABLE_PIN PD2 - -// -// Heaters 0,1 / Fans / Bed -// -#define HEATER_0_PIN PC9 -#define HEATER_1_PIN PC7 -#define FAN_PIN PA8 -#define HEATER_BED_PIN PC8 - -// -// Temperature Sensors -// -#define TEMP_BED_PIN PA1 //TB -#define TEMP_0_PIN PA0 //TH1 -#define TEMP_1_PIN PA2 //TH2 - -#define FIL_RUNOUT_PIN PB10 // MT_DET - -// -// LCD Pins -// -#if HAS_SPI_LCD - - #define BEEPER_PIN PC1 - #define BTN_ENC PC3 - #define LCD_PINS_ENABLE PA4 - #define LCD_PINS_RS PA5 - #define BTN_EN1 PB11 - #define BTN_EN2 PB0 - - // MKS MINI12864 and MKS LCD12864B; If using MKS LCD12864A (Need to remove RPK2 resistor) - #if ENABLED(MKS_MINI_12864) - - #define LCD_BACKLIGHT_PIN -1 - #define LCD_RESET_PIN -1 - #define DOGLCD_A0 PC4 - #define DOGLCD_CS PA7 - #define DOGLCD_SCK PB13 - #define DOGLCD_MOSI PB15 - - // Required for MKS_MINI_12864 with this board - #define MKS_LCD12864B - #undef SHOW_BOOTSCREEN - - #else // !MKS_MINI_12864 - - #define LCD_PINS_D4 PA6 - #if ENABLED(ULTIPANEL) - #define LCD_PINS_D5 PA7 - #define LCD_PINS_D6 PC4 - #define LCD_PINS_D7 PC5 - #endif - - #endif // !MKS_MINI_12864 - -#endif // HAS_SPI_LCD - -// -// SD Card -// -#define ENABLE_SPI2 -#define SD_DETECT_PIN PC10 -#define SCK_PIN PB13 -#define MISO_PIN PB14 -#define MOSI_PIN PB15 -#define SS_PIN PA15 - -#ifndef ST7920_DELAY_1 - #define ST7920_DELAY_1 DELAY_NS(125) -#endif -#ifndef ST7920_DELAY_2 - #define ST7920_DELAY_2 DELAY_NS(125) -#endif -#ifndef ST7920_DELAY_3 - #define ST7920_DELAY_3 DELAY_NS(125) -#endif diff --git a/Marlin/src/pins/stm32/pins_MKS_ROBIN_MINI.h b/Marlin/src/pins/stm32/pins_MKS_ROBIN_MINI.h deleted file mode 100644 index 16e74b169e97..000000000000 --- a/Marlin/src/pins/stm32/pins_MKS_ROBIN_MINI.h +++ /dev/null @@ -1,154 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * MKS Robin MINI (STM32F130VET6) board pin assignments - */ - -#ifndef __STM32F1__ - #error "Oops! Select an STM32F1 board in 'Tools > Board.'" -#elif HOTENDS > 1 || E_STEPPERS > 1 - #error "MKS Robin mini supports up to 1 hotends / E-steppers. Comment out this line to continue." -#endif - -#define BOARD_INFO_NAME "MKS Robin mini" - -// -// Release PB4 (Y_ENABLE_PIN) from JTAG NRST role -// -#define DISABLE_DEBUG - -#define FLASH_EEPROM_EMULATION -// 2K in a AT24C16N -#define EEPROM_PAGE_SIZE (uint16)0x800 // 2048 -#define EEPROM_START_ADDRESS ((uint32)(0x8000000 + 512 * 1024 - 2 * EEPROM_PAGE_SIZE)) -#define E2END (EEPROM_PAGE_SIZE - 1) - -// -// Note: MKS Robin mini board is using SPI2 interface. -// -#define SPI_MODULE 2 - -// -// Limit Switches -// -#define X_STOP_PIN PA15 -#define Y_STOP_PIN PA12 -#define Z_MIN_PIN PA11 -#define Z_MAX_PIN PC4 - -#ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN PA4 // MT_DET -#endif - -// -// Steppers -// -#define X_ENABLE_PIN PE4 -#define X_STEP_PIN PE3 -#define X_DIR_PIN PE2 - -#define Y_ENABLE_PIN PE1 -#define Y_STEP_PIN PE0 -#define Y_DIR_PIN PB9 - -#define Z_ENABLE_PIN PB8 -#define Z_STEP_PIN PB5 -#define Z_DIR_PIN PB4 - -#define E0_ENABLE_PIN PB3 -#define E0_STEP_PIN PD6 -#define E0_DIR_PIN PD3 - -// -// Temperature Sensors -// -#define TEMP_0_PIN PC1 // TH1 -#define TEMP_BED_PIN PC0 // TB1 - -// -// Heaters / Fans -// -#define HEATER_0_PIN PC3 // HEATER1 -#define HEATER_BED_PIN PA0 // HOT BED - -#define FAN_PIN PB1 // FAN - -// -// Thermocouples -// -//#define MAX6675_SS_PIN PE5 // TC1 - CS1 -//#define MAX6675_SS_PIN PE6 // TC2 - CS2 - -// -// Misc. Functions -// -#define POWER_LOSS_PIN PA2 // PW_DET -#define PS_ON_PIN PA3 // PW_OFF - -//#define LED_PIN PB2 - -// -// LCD / Controller -// -#define BEEPER_PIN PC5 -#define SD_DETECT_PIN PD12 - -/** - * Note: MKS Robin TFT screens use various TFT controllers. - * If the screen stays white, disable 'LCD_RESET_PIN' - * to let the bootloader init the screen. - */ -#if ENABLED(FSMC_GRAPHICAL_TFT) - #define FSMC_CS_PIN PD7 // NE4 - #define FSMC_RS_PIN PD11 // A0 - - #define LCD_RESET_PIN PC6 - #define NO_LCD_REINIT // Suppress LCD re-initialization - - #define LCD_BACKLIGHT_PIN PD13 - - #if ENABLED(TOUCH_BUTTONS) - #define TOUCH_CS_PIN PC2 - #define TOUCH_SCK_PIN PB13 - #define TOUCH_MOSI_PIN PB15 - #define TOUCH_MISO_PIN PB14 - #endif -#endif - -// Motor current PWM pins -#define MOTOR_CURRENT_PWM_XY_PIN PA6 -#define MOTOR_CURRENT_PWM_Z_PIN PA7 -#define MOTOR_CURRENT_PWM_E_PIN PB0 -#define MOTOR_CURRENT_PWM_RANGE 1500 // (255 * (1000mA / 65535)) * 257 = 1000 is equal 1.6v Vref in turn equal 1Amp -#define DEFAULT_PWM_MOTOR_CURRENT { 1030, 1030, 1030 } // 1.05Amp per driver, here is XY, Z and E. This values determined empirically. - -// This is a kind of workaround in case native marlin "digipot" interface won't work. -// Required to enable related code in STM32F1/HAL.cpp -//#ifndef MKS_ROBIN_MINI_VREF_PWM -// #define MKS_ROBIN_MINI_VREF_PWM -//#endif - -//#define VREF_XY_PIN PA6 -//#define VREF_Z_PIN PA7 -//#define VREF_E1_PIN PB0 diff --git a/Marlin/src/pins/stm32/pins_MKS_ROBIN_NANO.h b/Marlin/src/pins/stm32/pins_MKS_ROBIN_NANO.h deleted file mode 100644 index 223f520ebe2e..000000000000 --- a/Marlin/src/pins/stm32/pins_MKS_ROBIN_NANO.h +++ /dev/null @@ -1,137 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * MKS Robin nano (STM32F130VET6) board pin assignments - */ - -#ifndef __STM32F1__ - #error "Oops! Select an STM32F1 board in 'Tools > Board.'" -#elif HOTENDS > 2 || E_STEPPERS > 2 - #error "MKS Robin nano supports up to 2 hotends / E-steppers. Comment out this line to continue." -#endif - -#define BOARD_INFO_NAME "MKS Robin nano" - -// -// Release PB4 (Y_ENABLE_PIN) from JTAG NRST role -// -#define DISABLE_DEBUG - -// -// Limit Switches -// -#define X_STOP_PIN PA15 -#define Y_STOP_PIN PA12 -#define Z_MIN_PIN PA11 -#define Z_MAX_PIN PC4 - -#ifndef FIL_RUNOUT_PIN - #define FIL_RUNOUT_PIN PA4 // MT_DET -#endif - -// -// Steppers -// -#define X_ENABLE_PIN PE4 -#define X_STEP_PIN PE3 -#define X_DIR_PIN PE2 - -#define Y_ENABLE_PIN PE1 -#define Y_STEP_PIN PE0 -#define Y_DIR_PIN PB9 - -#define Z_ENABLE_PIN PB8 -#define Z_STEP_PIN PB5 -#define Z_DIR_PIN PB4 - -#define E0_ENABLE_PIN PB3 -#define E0_STEP_PIN PD6 -#define E0_DIR_PIN PD3 - -#define E1_ENABLE_PIN PA3 -#define E1_STEP_PIN PA6 -#define E1_DIR_PIN PA1 - -// -// Temperature Sensors -// -#define TEMP_0_PIN PC1 // TH1 -#define TEMP_1_PIN PC2 // TH2 -#define TEMP_BED_PIN PC0 // TB1 - -// -// Heaters / Fans -// -#define HEATER_0_PIN PC3 // HEATER1 -#define HEATER_1_PIN PB0 // HEATER2 -#define HEATER_BED_PIN PA0 // HOT BED - -#define FAN_PIN PB1 // FAN - -// -// Thermocouples -// -//#define MAX6675_SS_PIN PE5 // TC1 - CS1 -//#define MAX6675_SS_PIN PE6 // TC2 - CS2 - -// -// Misc. Functions -// -#define POWER_LOSS_PIN PA2 // PW_DET -#define PS_ON_PIN PA3 // PW_OFF - -#define LED_PIN PB2 - -// -// SD Card -// -#define SDIO_SUPPORT -#define SD_DETECT_PIN PD12 - -// -// LCD / Controller -// -#define BEEPER_PIN PC5 - -/** - * Note: MKS Robin TFT screens use various TFT controllers. - * If the screen stays white, disable 'LCD_RESET_PIN' - * to let the bootloader init the screen. - */ -#if ENABLED(FSMC_GRAPHICAL_TFT) - #define FSMC_CS_PIN PD7 // NE4 - #define FSMC_RS_PIN PD11 // A0 - - #define LCD_RESET_PIN PC6 // FSMC_RST - #define NO_LCD_REINIT // Suppress LCD re-initialization - - #define LCD_BACKLIGHT_PIN PD13 - - #if ENABLED(TOUCH_BUTTONS) - #define TOUCH_CS_PIN PA7 // SPI2_NSS - #define TOUCH_SCK_PIN PB13 // SPI2_SCK - #define TOUCH_MISO_PIN PB14 // SPI2_MISO - #define TOUCH_MOSI_PIN PB15 // SPI2_MOSI - #endif -#endif diff --git a/Marlin/src/pins/stm32/pins_MKS_ROBIN_PRO.h b/Marlin/src/pins/stm32/pins_MKS_ROBIN_PRO.h deleted file mode 100644 index ec43ab8fc3c7..000000000000 --- a/Marlin/src/pins/stm32/pins_MKS_ROBIN_PRO.h +++ /dev/null @@ -1,274 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * MKS Robin pro (STM32F103ZET6) board pin assignments - */ - -#ifndef __STM32F1__ - #error "Oops! Select an STM32F1 board in 'Tools > Board.'" -#elif HOTENDS > 3 || E_STEPPERS > 3 - #error "MKS Robin pro supports up to 3 hotends / E-steppers. Comment out this line to continue." -#endif - -#define BOARD_INFO_NAME "MKS Robin pro" - -// -// Release PB4 (Y_ENABLE_PIN) from JTAG NRST role -// -#define DISABLE_DEBUG - -// -// Note: MKS Robin board is using SPI2 interface. -// -//#define SPI_MODULE 2 -#define ENABLE_SPI2 - -// -// Servos -// -#define SERVO0_PIN PA8 // BLTOUCH - -// -// Limit Switches -// -#define X_MIN_PIN PA15 -#define X_MAX_PIN PG7 -#define Y_MIN_PIN PA12 -#define Y_MAX_PIN PG8 -#define Z_MIN_PIN PA11 -#define Z_MAX_PIN PC4 - -// -// Steppers -// -#define X_ENABLE_PIN PE4 -#define X_STEP_PIN PE3 -#define X_DIR_PIN PE2 -#ifndef X_CS_PIN - #define X_CS_PIN PF8 -#endif - -#define Y_ENABLE_PIN PE1 -#define Y_STEP_PIN PE0 -#define Y_DIR_PIN PB9 -#ifndef Y_CS_PIN - #define Y_CS_PIN PF3 -#endif - -#define Z_ENABLE_PIN PB8 -#define Z_STEP_PIN PB5 -#define Z_DIR_PIN PB4 -#ifndef Z_CS_PIN - #define Z_CS_PIN PF6 -#endif - -#define E0_ENABLE_PIN PB3 -#define E0_STEP_PIN PD6 -#define E0_DIR_PIN PD3 -#ifndef E0_CS_PIN - #define E0_CS_PIN PG15 -#endif - -#define E1_ENABLE_PIN PA3 -#define E1_STEP_PIN PA6 -#define E1_DIR_PIN PA1 -#ifndef E1_CS_PIN - #define E1_CS_PIN PG10 -#endif - -#define E2_ENABLE_PIN PF0 -#define E2_STEP_PIN PF2 -#define E2_DIR_PIN PF1 -#ifndef E2_CS_PIN - #define E2_CS_PIN PG9 -#endif -// -// Software SPI pins for TMC2130 stepper drivers -// -#if ENABLED(TMC_USE_SW_SPI) - #ifndef TMC_SW_MOSI - #define TMC_SW_MOSI PB15 - #endif - #ifndef TMC_SW_MISO - #define TMC_SW_MISO PB14 - #endif - #ifndef TMC_SW_SCK - #define TMC_SW_SCK PB13 - #endif -#endif - -#if HAS_TMC220x - /** - * TMC2208/TMC2209 stepper drivers - * - * Hardware serial communication ports. - * If undefined software serial is used according to the pins below - */ - //#define X_HARDWARE_SERIAL Serial - //#define X2_HARDWARE_SERIAL Serial1 - //#define Y_HARDWARE_SERIAL Serial1 - //#define Y2_HARDWARE_SERIAL Serial1 - //#define Z_HARDWARE_SERIAL Serial1 - //#define Z2_HARDWARE_SERIAL Serial1 - //#define E0_HARDWARE_SERIAL Serial1 - //#define E1_HARDWARE_SERIAL Serial1 - //#define E2_HARDWARE_SERIAL Serial1 - //#define E3_HARDWARE_SERIAL Serial1 - //#define E4_HARDWARE_SERIAL Serial1 - - // - // Software serial - // - #define X_SERIAL_TX_PIN PF7 - #define X_SERIAL_RX_PIN PF8 - - #define Y_SERIAL_TX_PIN PF4 - #define Y_SERIAL_RX_PIN PF3 - - #define Z_SERIAL_TX_PIN PF5 - #define Z_SERIAL_RX_PIN PF6 - - #define E0_SERIAL_TX_PIN PG13 - #define E0_SERIAL_RX_PIN PG15 - - #define E1_SERIAL_TX_PIN PG12 - #define E1_SERIAL_RX_PIN PG10 - - #define E2_SERIAL_TX_PIN PC13 - #define E2_SERIAL_RX_PIN PG9 -#endif - -// -// Temperature Sensors -// -#define TEMP_0_PIN PC1 // TH1 -#define TEMP_1_PIN PC2 // TH2 -#define TEMP_2_PIN PC3 // TH3 -#define TEMP_BED_PIN PC0 // TB1 - -// -// Heaters / Fans -// -#define HEATER_0_PIN PF10 // +HE0- -#define HEATER_1_PIN PB0 // +HE1- -#define HEATER_2_PIN PF9 // +HE2- -#define HEATER_BED_PIN PA0 // +HOT-BED- -#define FAN_PIN PB1 // +FAN- - -/** - * Note: MKS Robin Pro board is using SPI2 interface. Make sure your stm32duino library is configured accordingly - */ -//#define MAX6675_SS_PIN PE5 // TC1 - CS1 -//#define MAX6675_SS_PIN PF11 // TC2 - CS2 - -#define POWER_LOSS_PIN PA2 // PW_DET -#define PS_ON_PIN PG11 // PW_OFF -#define FIL_RUNOUT_PIN PA4 // MT_DET1 -//#define FIL_RUNOUT_PIN PE6 // MT_DET2 -//#define FIL_RUNOUT_PIN PG14 // MT_DET3 - -// -// SD Card -// -#ifndef SDCARD_CONNECTION - #define SDCARD_CONNECTION ONBOARD -#endif - -#if SD_CONNECTION_IS(LCD) - #define ENABLE_SPI2 - #define SD_DETECT_PIN PG3 - #define SCK_PIN PB13 - #define MISO_PIN PB14 - #define MOSI_PIN PB15 - #define SS_PIN PG6 -#elif SD_CONNECTION_IS(ONBOARD) - #define SDIO_SUPPORT - #define SD_DETECT_PIN PD12 -#elif SD_CONNECTION_IS(CUSTOM_CABLE) - #error "No custom SD drive cable defined for this board." -#endif - -/** - * Note: MKS Robin TFT screens use various TFT controllers. - * If the screen stays white, disable 'LCD_RESET_PIN' - * to let the bootloader init the screen. - */ -#if ENABLED(FSMC_GRAPHICAL_TFT) - #define FSMC_CS_PIN PD7 // NE4 - #define FSMC_RS_PIN PD11 // A0 - - #define LCD_RESET_PIN PF6 - #define NO_LCD_REINIT // Suppress LCD re-initialization - - #define LCD_BACKLIGHT_PIN PD13 - - #if ENABLED(TOUCH_BUTTONS) - #define TOUCH_CS_PIN PA7 - #else - #define BEEPER_PIN PC5 - #define BTN_ENC PG2 - #define BTN_EN1 PG5 - #define BTN_EN2 PG4 - #endif - -#elif HAS_SPI_LCD - - #define BEEPER_PIN PC5 - #define BTN_ENC PG2 - #define LCD_PINS_ENABLE PG0 - #define LCD_PINS_RS PG1 - #define BTN_EN1 PG5 - #define BTN_EN2 PG4 - - // MKS MINI12864 and MKS LCD12864B. If using MKS LCD12864A (Need to remove RPK2 resistor) - #if ENABLED(MKS_MINI_12864) - - #define LCD_BACKLIGHT_PIN -1 - #define LCD_RESET_PIN -1 - #define DOGLCD_A0 PF12 - #define DOGLCD_CS PF15 - #define DOGLCD_SCK PB13 - #define DOGLCD_MOSI PB15 - - #else // !MKS_MINI_12864 && !ENDER2_STOCKDISPLAY - - #define LCD_PINS_D4 PF14 - #if ENABLED(ULTIPANEL) - #define LCD_PINS_D5 PF15 - #define LCD_PINS_D6 PF12 - #define LCD_PINS_D7 PF13 - #endif - - #endif // !MKS_MINI_12864 && !ENDER2_STOCKDISPLAY -#endif - -#ifndef ST7920_DELAY_1 - #define ST7920_DELAY_1 DELAY_NS(125) -#endif -#ifndef ST7920_DELAY_2 - #define ST7920_DELAY_2 DELAY_NS(125) -#endif -#ifndef ST7920_DELAY_3 - #define ST7920_DELAY_3 DELAY_NS(125) -#endif diff --git a/Marlin/src/pins/stm32/pins_MORPHEUS.h b/Marlin/src/pins/stm32/pins_MORPHEUS.h deleted file mode 100644 index 8c583434e486..000000000000 --- a/Marlin/src/pins/stm32/pins_MORPHEUS.h +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - - /** - * 2017 Victor Perez Marlin for stm32f1 test - * 2018 Modified by Pablo Crespo for Morpheus Board (https://github.com/pscrespo/Morpheus-STM32) - */ - -/** - * MORPHEUS Board pin assignments - */ - -#ifndef __STM32F1__ - #error "Oops! Select an STM32F1 board in 'Tools > Board.'" -#endif - -#define BOARD_INFO_NAME "Bluepill based board" - -// -// Limit Switches -// -#define X_MIN_PIN PB14 -#define Y_MIN_PIN PB13 -#define Z_MIN_PIN PB12 - -// -// Z Probe (when not Z_MIN_PIN) -// -#ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN PB9 -#endif - -// -// Steppers -// -// X & Y enable are the same -#define X_STEP_PIN PB7 -#define X_DIR_PIN PB6 -#define X_ENABLE_PIN PB8 - -#define Y_STEP_PIN PB5 -#define Y_DIR_PIN PB4 -#define Y_ENABLE_PIN PB8 - -#define Z_STEP_PIN PA15 -#define Z_DIR_PIN PA10 -#define Z_ENABLE_PIN PB3 - -#define E0_STEP_PIN PA8 -#define E0_DIR_PIN PB15 -#define E0_ENABLE_PIN PA9 - -// -// Temperature Sensors -// -#define TEMP_0_PIN PB1 // Analog Input (HOTEND thermistor) -#define TEMP_BED_PIN PB0 // Analog Input (BED thermistor) - -// -// Heaters / Fans -// -#define HEATER_0_PIN PA2 // HOTEND MOSFET -#define HEATER_BED_PIN PA0 // BED MOSFET - -#define FAN_PIN PA1 // FAN1 header on board - PRINT FAN - -// -// Misc. -// -#define LED_PIN PC13 -#define SDSS PA3 diff --git a/Marlin/src/pins/stm32/pins_REMRAM_V1.h b/Marlin/src/pins/stm32/pins_REMRAM_V1.h deleted file mode 100644 index 45a1f68e5a3a..000000000000 --- a/Marlin/src/pins/stm32/pins_REMRAM_V1.h +++ /dev/null @@ -1,133 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#ifndef STM32F7xx - #error "Oops! Select an STM32F7 board in 'Tools > Board.'" -#endif - -#define BOARD_INFO_NAME "RemRam v1" -#define DEFAULT_MACHINE_NAME "RemRam" - -#define SRAM_EEPROM_EMULATION // Emulate the EEPROM using Backup SRAM - -#if HOTENDS > 1 || E_STEPPERS > 1 - #error "RemRam supports only one hotend / E-stepper." -#endif - -// -// Limit Switches -// -#if DISABLED(SENSORLESS_HOMING) - #define X_MIN_PIN 58 - #define X_MAX_PIN 59 - #define Y_MIN_PIN 60 - #define Y_MAX_PIN 61 - #define Z_MIN_PIN 62 - #define Z_MAX_PIN 63 -#else - #define X_STOP_PIN 36 - #define Y_STOP_PIN 39 - #define Z_MIN_PIN 62 - #define Z_MAX_PIN 42 -#endif - -// -// Z Probe (when not Z_MIN_PIN) -// -#ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 26 // EXT_D1 -#endif - -// -// Steppers -// -#define X_STEP_PIN 22 -#define X_DIR_PIN 35 -#define X_ENABLE_PIN 34 -#define X_CS_PIN 14 - -#define Y_STEP_PIN 23 -#define Y_DIR_PIN 38 -#define Y_ENABLE_PIN 37 -#define Y_CS_PIN 15 - -#define Z_STEP_PIN 24 -#define Z_DIR_PIN 41 -#define Z_ENABLE_PIN 40 -#define Z_CS_PIN 16 - -#define E0_STEP_PIN 25 -#define E0_DIR_PIN 44 -#define E0_ENABLE_PIN 43 -#define E0_CS_PIN 10 - -// -// Temperature Sensors -// -#define TEMP_0_PIN 64 // THERM_1 -#define TEMP_1_PIN 65 // THERM_2 -#define TEMP_BED_PIN 66 // THERM_3 - -// -// Heaters / Fans -// -#define HEATER_0_PIN 33 -#define HEATER_BED_PIN 31 - -#ifndef FAN_PIN - #define FAN_PIN 30 // "FAN1" -#endif -#define FAN1_PIN 32 // "FAN2" - -#define ORIG_E0_AUTO_FAN_PIN 32 // Use this by NOT overriding E0_AUTO_FAN_PIN - -// -// Servos -// -#define SERVO0_PIN 26 // PWM_EXT1 -#define SERVO1_PIN 27 // PWM_EXT2 - -#define SDSS 57 // Onboard SD card reader -//#define SDSS 9 // LCD SD card reader -#define LED_PIN 21 // STATUS_LED - -// -// LCD / Controller -// -#define SD_DETECT_PIN 56 // SD_CARD_DET -#define BEEPER_PIN 46 // LCD_BEEPER -#define LCD_PINS_RS 49 // LCD_RS -#define LCD_PINS_ENABLE 48 // LCD_EN -#define LCD_PINS_D4 50 // LCD_D4 -#define LCD_PINS_D5 51 // LCD_D5 -#define LCD_PINS_D6 52 // LCD_D6 -#define LCD_PINS_D7 53 // LCD_D7 -#define BTN_EN1 54 // BTN_EN1 -#define BTN_EN2 55 // BTN_EN2 -#define BTN_ENC 47 // BTN_ENC - -// -// Timers -// - -#define STEP_TIMER 2 diff --git a/Marlin/src/pins/stm32/pins_RUMBA32_AUS3D.h b/Marlin/src/pins/stm32/pins_RUMBA32_AUS3D.h deleted file mode 100644 index cff34a2d860b..000000000000 --- a/Marlin/src/pins/stm32/pins_RUMBA32_AUS3D.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Pin assignments for the MKS RUMBA32 - * - * https://aus3d.com.au/rumba32 - * https://github.com/Aus3D/RUMBA32 - * - * The MKS and Aus3D versions have the same pinout but the MKS version - * has some added resistors and LEDs. The resistors needed for the - * TMC2208/9 UART interface are among the additions. Also added were - * connectors and resistors dedicated to the TMC2130 sensorless homing - * interface. - */ - -#define BOARD_INFO_NAME "Aus3D RUMBA32" - -#define RUMBA32_V1_0 -//#define I2C_EEPROM - -#include "pins_RUMBA32_common.h" diff --git a/Marlin/src/pins/stm32/pins_RUMBA32_common.h b/Marlin/src/pins/stm32/pins_RUMBA32_common.h deleted file mode 100644 index 0fb469112d41..000000000000 --- a/Marlin/src/pins/stm32/pins_RUMBA32_common.h +++ /dev/null @@ -1,149 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Common pin assignments for all RUMBA32 boards - */ - -#ifndef STM32F4 - #error "Oops! Select an STM32F4 board in 'Tools > Board.'" -#elif HOTENDS > 3 || E_STEPPERS > 3 - #error "RUMBA32 boards support up to 3 hotends / E-steppers." -#endif - -#define RUMBA32_V1_0 -#define DEFAULT_MACHINE_NAME BOARD_INFO_NAME - -//#define I2C_EEPROM -#ifdef E2END - #undef E2END -#endif -#define E2END 0xFFF // 4KB - -// -// Limit Switches -// -#define X_MIN_PIN PB12 -#define X_MAX_PIN PB13 -#define Y_MIN_PIN PB15 -#define Y_MAX_PIN PD8 -#define Z_MIN_PIN PD9 -#define Z_MAX_PIN PD10 - -// -// Steppers -// -#define X_STEP_PIN PA0 -#define X_DIR_PIN PC15 -#define X_ENABLE_PIN PC11 -#define X_CS_PIN PC14 - -#define Y_STEP_PIN PE5 -#define Y_DIR_PIN PE6 -#define Y_ENABLE_PIN PE3 -#define Y_CS_PIN PE4 - -#define Z_STEP_PIN PE1 -#define Z_DIR_PIN PE2 -#define Z_ENABLE_PIN PB7 -#define Z_CS_PIN PE0 - -#define E0_STEP_PIN PB5 -#define E0_DIR_PIN PB6 -#define E0_ENABLE_PIN PC12 -#define E0_CS_PIN PC13 - -#define E1_STEP_PIN PD6 -#define E1_DIR_PIN PD7 -#define E1_ENABLE_PIN PD4 -#define E1_CS_PIN PD5 - -#define E2_STEP_PIN PD2 -#define E2_DIR_PIN PD3 -#define E2_ENABLE_PIN PD0 -#define E2_CS_PIN PD1 - -// -// Temperature Sensors -// -#define TEMP_0_PIN PC4 -#define TEMP_1_PIN PC3 -#define TEMP_2_PIN PC2 -#define TEMP_3_PIN PC1 -#define TEMP_BED_PIN PC0 - -// -// Heaters / Fans -// -#define HEATER_0_PIN PC6 -#define HEATER_1_PIN PC7 -#define HEATER_2_PIN PC8 -#define HEATER_BED_PIN PA1 - -#define FAN_PIN PC9 -#define FAN1_PIN PA8 - -// -// I2C -// -#define SCK_PIN PA5 -#define MISO_PIN PA6 -#define MOSI_PIN PA7 - -// -// Misc. Functions -// -#define LED_PIN PB14 -#define BTN_PIN PC10 -#define PS_ON_PIN PE11 -#define KILL_PIN PC5 - -#define SDSS PA2 -#define SD_DETECT_PIN PB0 -#define BEEPER_PIN PE8 - -// -// LCD / Controller -// -#if HAS_SPI_LCD - - #define BTN_EN1 PB2 - #define BTN_EN2 PB1 - #define BTN_ENC PE7 - - #define LCD_PINS_RS PE10 - #define LCD_PINS_ENABLE PE9 - #define LCD_PINS_D4 PE12 - - #if ENABLED(MKS_MINI_12864) - #define DOGLCD_CS PE13 - #define DOGLCD_A0 PE14 - #endif - - #if ENABLED(ULTIPANEL) - #define LCD_PINS_D5 PE13 - #define LCD_PINS_D6 PE14 - #define LCD_PINS_D7 PE15 - #endif - -#endif diff --git a/Marlin/src/pins/stm32/pins_STM32F1R.h b/Marlin/src/pins/stm32/pins_STM32F1R.h deleted file mode 100644 index b43492af21c3..000000000000 --- a/Marlin/src/pins/stm32/pins_STM32F1R.h +++ /dev/null @@ -1,261 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#ifndef __STM32F1__ - #error "Oops! Select an STM32F1 board in 'Tools > Board.'" -#endif - -/** - * 21017 Victor Perez Marlin for stm32f1 test - */ - -#define BOARD_INFO_NAME "Misc. STM32F1R" -#define DEFAULT_MACHINE_NAME "STM32F103RET6" - -// Ignore temp readings during development. -//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 - -// -// Limit Switches -// -#define X_STOP_PIN PB3 -#define Y_STOP_PIN PB4 -#define Z_STOP_PIN PB5 - -// -// Steppers -// -#define X_STEP_PIN PC0 -#define X_DIR_PIN PC1 -#define X_ENABLE_PIN PA8 - -#define Y_STEP_PIN PC2 -#define Y_DIR_PIN PC3 -#define Y_ENABLE_PIN PA8 - -#define Z_STEP_PIN PC4 -#define Z_DIR_PIN PC5 -#define Z_ENABLE_PIN PA8 - -#define E0_STEP_PIN PC6 -#define E0_DIR_PIN PC7 -#define E0_ENABLE_PIN PA8 - -/** - * TODO: Currently using same Enable pin to all steppers. - */ - -#define E1_STEP_PIN PC8 -#define E1_DIR_PIN PC9 -#define E1_ENABLE_PIN PA8 - -#define E2_STEP_PIN PC10 -#define E2_DIR_PIN PC11 -#define E2_ENABLE_PIN PA8 - -// -// Misc. Functions -// -#define SDSS PA4 -#define LED_PIN PD2 - -// -// Heaters / Fans -// -#define HEATER_0_PIN PB0 // EXTRUDER 1 -#define HEATER_1_PIN PB1 - -#define HEATER_BED_PIN PA3 // BED - -// -// Temperature Sensors -// -#define TEMP_BED_PIN PA0 // Analog Input -#define TEMP_0_PIN PA1 // Analog Input -#define TEMP_1_PIN PA2 // Analog Input - -// -// LCD Pins -// -#if HAS_SPI_LCD - - #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) - #define LCD_PINS_RS 49 // CS chip select /SS chip slave select - #define LCD_PINS_ENABLE 51 // SID (MOSI) - #define LCD_PINS_D4 52 // SCK (CLK) clock - #elif BOTH(NEWPANEL, PANEL_ONE) - #define LCD_PINS_RS PB8 - #define LCD_PINS_ENABLE PD2 - #define LCD_PINS_D4 PB12 - #define LCD_PINS_D5 PB13 - #define LCD_PINS_D6 PB14 - #define LCD_PINS_D7 PB15 - #else - #define LCD_PINS_RS PB8 - #define LCD_PINS_ENABLE PD2 - #define LCD_PINS_D4 PB12 - #define LCD_PINS_D5 PB13 - #define LCD_PINS_D6 PB14 - #define LCD_PINS_D7 PB15 - #if DISABLED(NEWPANEL) - #define BEEPER_PIN 33 - // Buttons attached to a shift register - // Not wired yet - //#define SHIFT_CLK 38 - //#define SHIFT_LD 42 - //#define SHIFT_OUT 40 - //#define SHIFT_EN 17 - #endif - #endif - - #if ENABLED(NEWPANEL) - - #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) - - #define BEEPER_PIN 37 - - #define BTN_EN1 31 - #define BTN_EN2 33 - #define BTN_ENC 35 - - #define SD_DETECT_PIN 49 - #define KILL_PIN 41 - - #if ENABLED(BQ_LCD_SMART_CONTROLLER) - #define LCD_BACKLIGHT_PIN 39 - #endif - - #elif ENABLED(REPRAPWORLD_GRAPHICAL_LCD) - - #define BTN_EN1 64 - #define BTN_EN2 59 - #define BTN_ENC 63 - #define SD_DETECT_PIN 42 - - #elif ENABLED(LCD_I2C_PANELOLU2) - - #define BTN_EN1 47 - #define BTN_EN2 43 - #define BTN_ENC 32 - #define LCD_SDSS 53 - #define SD_DETECT_PIN -1 - #define KILL_PIN 41 - - #elif ENABLED(LCD_I2C_VIKI) - - #define BTN_EN1 22 // http://files.panucatt.com/datasheets/viki_wiring_diagram.pdf explains 40/42. - #define BTN_EN2 7 // 22/7 are unused on RAMPS_14. 22 is unused and 7 the SERVO0_PIN on RAMPS_13. - - #define BTN_ENC -1 - #define LCD_SDSS 53 - #define SD_DETECT_PIN 49 - - #elif ANY(VIKI2, miniVIKI) - - #define BEEPER_PIN 33 - - // Pins for DOGM SPI LCD Support - #define DOGLCD_A0 44 - #define DOGLCD_CS 45 - #define LCD_SCREEN_ROT_180 - - #define BTN_EN1 22 - #define BTN_EN2 7 - #define BTN_ENC 39 - - #define SDSS 53 - #define SD_DETECT_PIN -1 // Pin 49 for display sd interface, 72 for easy adapter board - - #define KILL_PIN 31 - - #define STAT_LED_RED_PIN 32 - #define STAT_LED_BLUE_PIN 35 - - #elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) - #define BTN_EN1 35 - #define BTN_EN2 37 - #define BTN_ENC 31 - #define SD_DETECT_PIN 49 - #define LCD_SDSS 53 - #define KILL_PIN 41 - #define BEEPER_PIN 23 - #define DOGLCD_CS 29 - #define DOGLCD_A0 27 - #define LCD_BACKLIGHT_PIN 33 - - #elif ENABLED(MINIPANEL) - - #define BEEPER_PIN 42 - // Pins for DOGM SPI LCD Support - #define DOGLCD_A0 44 - #define DOGLCD_CS 66 - #define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65 - #define SDSS 53 - - #define KILL_PIN 64 - // GLCD features - // Uncomment screen orientation - //#define LCD_SCREEN_ROT_90 - //#define LCD_SCREEN_ROT_180 - //#define LCD_SCREEN_ROT_270 - // The encoder and click button - #define BTN_EN1 40 - #define BTN_EN2 63 - #define BTN_ENC 59 - // not connected to a pin - #define SD_DETECT_PIN 49 - - #else - - // Beeper on AUX-4 - #define BEEPER_PIN 33 - - // Buttons directly attached to AUX-2 - #if ENABLED(REPRAPWORLD_KEYPAD) - #define BTN_EN1 64 - #define BTN_EN2 59 - #define BTN_ENC 63 - #define SHIFT_OUT 40 - #define SHIFT_CLK 44 - #define SHIFT_LD 42 - #elif ENABLED(PANEL_ONE) - #define BTN_EN1 59 // AUX2 PIN 3 - #define BTN_EN2 63 // AUX2 PIN 4 - #define BTN_ENC 49 // AUX3 PIN 7 - #else - #define BTN_EN1 37 - #define BTN_EN2 35 - #define BTN_ENC 31 - #endif - - #if ENABLED(G3D_PANEL) - #define SD_DETECT_PIN 49 - #define KILL_PIN 41 - #else - //#define SD_DETECT_PIN -1 // Ramps doesn't use this - #endif - - #endif - #endif // NEWPANEL - -#endif // HAS_SPI_LCD diff --git a/Marlin/src/pins/stm32/pins_STM3R_MINI.h b/Marlin/src/pins/stm32/pins_STM3R_MINI.h deleted file mode 100644 index 99f1cea35ce3..000000000000 --- a/Marlin/src/pins/stm32/pins_STM3R_MINI.h +++ /dev/null @@ -1,285 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if !defined(__STM32F1__) && !defined(__STM32F4__) - #error "Oops! Select an STM32F1/4 board in 'Tools > Board.'" -#endif - -/** - * 21017 Victor Perez Marlin for stm32f1 test - */ - -#define BOARD_INFO_NAME "STM3R Mini" -#define DEFAULT_MACHINE_NAME BOARD_INFO_NAME - -// Enable I2C_EEPROM for testing -#define I2C_EEPROM - -// Ignore temp readings during development. -//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 - -// -// Limit Switches -// -#define X_STOP_PIN PD0 -#define Y_STOP_PIN PD1 -#define Z_STOP_PIN PD4 - -// -// Steppers -// -#define X_STEP_PIN PE1 -#define X_DIR_PIN PE0 -#define X_ENABLE_PIN PC0 - -#define Y_STEP_PIN PE3 -#define Y_DIR_PIN PE2 -#define Y_ENABLE_PIN PC1 - -#define Z_STEP_PIN PE5 -#define Z_DIR_PIN PE4 -#define Z_ENABLE_PIN PC2 - -#define E0_STEP_PIN PE7 -#define E0_DIR_PIN PE6 -#define E0_ENABLE_PIN PC3 - -#define E1_STEP_PIN PE9 -#define E1_DIR_PIN PE8 -#define E1_ENABLE_PIN PC4 - -#define E2_STEP_PIN PE11 -#define E2_DIR_PIN PE10 -#define E2_ENABLE_PIN PC5 - -// -// Misc. Functions -// -#define SDSS PA15 -#define LED_PIN PB2 - -// -// Heaters / Fans -// -#define HEATER_0_PIN PD12 // EXTRUDER 1 -//#define HEATER_1_PIN PD13 - -#define HEATER_BED_PIN PB9 // BED -//#define HEATER_BED2_PIN -1 // BED2 -//#define HEATER_BED3_PIN -1 // BED3 - -#ifndef FAN_PIN - #define FAN_PIN PD14 -#endif -#define FAN1_PIN PD13 - -#define FAN_SOFT_PWM - -// -// Temperature Sensors -// -#define TEMP_BED_PIN PA0 -#define TEMP_0_PIN PA1 -#define TEMP_1_PIN PA2 -#define TEMP_2_PIN PA3 - -// Laser control -#if HAS_CUTTER - #define SPINDLE_LASER_PWM_PIN PB8 - #define SPINDLE_LASER_ENA_PIN PD5 -#endif - -// -// LCD Pins -// -#if HAS_SPI_LCD - - #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) - #define LCD_PINS_RS 49 // CS chip select /SS chip slave select - #define LCD_PINS_ENABLE 51 // SID (MOSI) - #define LCD_PINS_D4 52 // SCK (CLK) clock - #elif BOTH(NEWPANEL, PANEL_ONE) - #define LCD_PINS_RS PB8 - #define LCD_PINS_ENABLE PD2 - #define LCD_PINS_D4 PB12 - #define LCD_PINS_D5 PB13 - #define LCD_PINS_D6 PB14 - #define LCD_PINS_D7 PB15 - #else - #define LCD_PINS_RS PB8 - #define LCD_PINS_ENABLE PD2 - #define LCD_PINS_D4 PB12 - #define LCD_PINS_D5 PB13 - #define LCD_PINS_D6 PB14 - #define LCD_PINS_D7 PB15 - #if DISABLED(NEWPANEL) - #define BEEPER_PIN 33 - // Buttons attached to a shift register - // Not wired yet - //#define SHIFT_CLK 38 - //#define SHIFT_LD 42 - //#define SHIFT_OUT 40 - //#define SHIFT_EN 17 - #endif - #endif - - #if ENABLED(TOUCH_BUTTONS) - - #define TOUCH_CS_PIN PB12 // SPI2_NSS - #define TOUCH_SCK_PIN PB13 - #define TOUCH_MOSI_PIN PB14 - #define TOUCH_MISO_PIN PB15 - #define TOUCH_INT_PIN PC6 // (PenIRQ coming from ADS7843) - - #elif ENABLED(NEWPANEL) - - #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) - - #define BEEPER_PIN 37 - - #define BTN_EN1 31 - #define BTN_EN2 33 - #define BTN_ENC 35 - - #define SD_DETECT_PIN 49 - #define KILL_PIN 41 - - #if ENABLED(BQ_LCD_SMART_CONTROLLER) - #define LCD_BACKLIGHT_PIN 39 - #endif - - #elif ENABLED(REPRAPWORLD_GRAPHICAL_LCD) - - #define BTN_EN1 64 - #define BTN_EN2 59 - #define BTN_ENC 63 - #define SD_DETECT_PIN 42 - - #elif ENABLED(LCD_I2C_PANELOLU2) - - #define BTN_EN1 47 - #define BTN_EN2 43 - #define BTN_ENC 32 - #define LCD_SDSS 53 - #define SD_DETECT_PIN -1 - #define KILL_PIN 41 - - #elif ENABLED(LCD_I2C_VIKI) - - #define BTN_EN1 22 // http://files.panucatt.com/datasheets/viki_wiring_diagram.pdf explains 40/42. - #define BTN_EN2 7 // 22/7 are unused on RAMPS_14. 22 is unused and 7 the SERVO0_PIN on RAMPS_13. - - #define BTN_ENC -1 - #define LCD_SDSS 53 - #define SD_DETECT_PIN 49 - - #elif ANY(VIKI2, miniVIKI) - - #define BEEPER_PIN 33 - - // Pins for DOGM SPI LCD Support - #define DOGLCD_A0 44 - #define DOGLCD_CS 45 - #define LCD_SCREEN_ROT_180 - - #define BTN_EN1 22 - #define BTN_EN2 7 - #define BTN_ENC 39 - - #define SDSS 53 - #define SD_DETECT_PIN -1 // Pin 49 for display sd interface, 72 for easy adapter board - - #define KILL_PIN 31 - - #define STAT_LED_RED_PIN 32 - #define STAT_LED_BLUE_PIN 35 - - #elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) - - #define BTN_EN1 35 - #define BTN_EN2 37 - #define BTN_ENC 31 - #define SD_DETECT_PIN 49 - #define LCD_SDSS 53 - #define KILL_PIN 41 - #define BEEPER_PIN 23 - #define DOGLCD_CS 29 - #define DOGLCD_A0 27 - #define LCD_BACKLIGHT_PIN 33 - - #elif ENABLED(MINIPANEL) - - #define BEEPER_PIN 42 - // Pins for DOGM SPI LCD Support - #define DOGLCD_A0 44 - #define DOGLCD_CS 66 - #define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65 - #define SDSS 53 - - #define KILL_PIN 64 - // GLCD features - // Uncomment screen orientation - //#define LCD_SCREEN_ROT_90 - //#define LCD_SCREEN_ROT_180 - //#define LCD_SCREEN_ROT_270 - // The encoder and click button - #define BTN_EN1 40 - #define BTN_EN2 63 - #define BTN_ENC 59 - // not connected to a pin - #define SD_DETECT_PIN 49 - - #else - - // Beeper on AUX-4 - #define BEEPER_PIN 33 - - // Buttons directly attached to AUX-2 - #if ENABLED(REPRAPWORLD_KEYPAD) - #define BTN_EN1 64 - #define BTN_EN2 59 - #define BTN_ENC 63 - #define SHIFT_OUT 40 - #define SHIFT_CLK 44 - #define SHIFT_LD 42 - #elif ENABLED(PANEL_ONE) - #define BTN_EN1 59 // AUX2 PIN 3 - #define BTN_EN2 63 // AUX2 PIN 4 - #define BTN_ENC 49 // AUX3 PIN 7 - #else - #define BTN_EN1 37 - #define BTN_EN2 35 - #define BTN_ENC 31 - #endif - - #if ENABLED(G3D_PANEL) - #define SD_DETECT_PIN 49 - #define KILL_PIN 41 - #else - //#define SD_DETECT_PIN -1 // Ramps doesn't use this - #endif - - #endif - #endif // NEWPANEL - -#endif // HAS_SPI_LCD diff --git a/Marlin/src/pins/stm32/pins_THE_BORG.h b/Marlin/src/pins/stm32/pins_THE_BORG.h deleted file mode 100644 index bfc9507c451e..000000000000 --- a/Marlin/src/pins/stm32/pins_THE_BORG.h +++ /dev/null @@ -1,187 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#ifndef STM32F7 - #error "Oops! Select an STM32F7 board in 'Tools > Board.'" -#elif HOTENDS > 3 || E_STEPPERS > 3 - #error "The-Borg supports up to 3 hotends / E-steppers." -#endif - -#define BOARD_INFO_NAME "The-Borge" -#define DEFAULT_MACHINE_NAME BOARD_INFO_NAME - -#ifndef E2END - #define E2END 0xFFF // EEPROM end address -#endif - -// Ignore temp readings during development. -//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 - -// -// Limit Switches -// -#define X_MIN_PIN PE9 -#define X_MAX_PIN PE10 -#define Y_MIN_PIN PE7 -#define Y_MAX_PIN PE8 -#define Z_MIN_PIN PF15 -#define Z_MAX_PIN PG0 -#define E_MIN_PIN PE2 -#define E_MAX_PIN PE3 - -// -// Z Probe (when not Z_MIN_PIN) -// -#ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN PA4 -#endif - -// -// Steppers -// -#define STEPPER_ENABLE_PIN PE0 - -#define X_STEP_PIN PC6 // 96, 39 in Arduino -#define X_DIR_PIN PC7 -#define X_ENABLE_PIN PC8 - - -#define Y_STEP_PIN PD9 -#define Y_DIR_PIN PD10 -#define Y_ENABLE_PIN PD11 - -#define Z_STEP_PIN PE15 -#define Z_DIR_PIN PG1 -#define Z_ENABLE_PIN PD8 - - -#define E0_STEP_PIN PB1 -#define E0_DIR_PIN PB2 -#define E0_ENABLE_PIN PE11 - - -#define E1_STEP_PIN PC4 -#define E1_DIR_PIN PC5 -#define E1_ENABLE_PIN PB0 - - -#define E2_STEP_PIN PC13 -#define E2_DIR_PIN PC14 -#define E2_ENABLE_PIN PC15 - -#define Z2_STEP_PIN PC13 -#define Z2_DIR_PIN PC14 -#define Z2_ENABLE_PIN PC15 - - -#define SCK_PIN PA5 -#define MISO_PIN PA6 -#define MOSI_PIN PA7 - -#define SPI1_SCK_PIN PA5 -#define SPI1_MISO_PIN PA6 -#define SPI1_MOSI_PIN PA7 - -#define SPI6_SCK_PIN PG13 -#define SPI6_MISO_PIN PG12 -#define SPI6_MOSI_PIN PG14 - -// -// Temperature Sensors -// - -#define TEMP_0_PIN PC3 // Analog Input -#define TEMP_1_PIN PC2 // Analog Input -#define TEMP_2_PIN PC1 // Analog Input -#define TEMP_3_PIN PC0 // Analog Input - -#define TEMP_BED_PIN PF10 // Analog Input - -#define TEMP_5_PIN PE12 // Analog Input, Probe temp - -// -// Heaters / Fans -// -#define HEATER_0_PIN PD15 -#define HEATER_1_PIN PD14 -#define HEATER_BED_PIN PF6 - -#ifndef FAN_PIN - #define FAN_PIN PD13 -#endif -#define FAN1_PIN PA0 -#define FAN2_PIN PA1 - -#define ORIG_E0_AUTO_FAN_PIN PA1 // Use this by NOT overriding E0_AUTO_FAN_PIN - -// -// Misc. Functions -// - -//#define CASE_LIGHT_PIN_CI PF13 -//#define CASE_LIGHT_PIN_DO PF14 -//#define NEOPIXEL_PIN PF13 - -// -// Průša i3 MK2 Multi Material Multiplexer Support -// - -#define E_MUX0_PIN PG3 -#define E_MUX1_PIN PG4 - -// -// Servos -// - -#define SERVO0_PIN PE13 -#define SERVO1_PIN PE14 - - -#define SDSS PA8 -#define SS_PIN PA8 -#define LED_PIN PA2 // Alive -#define PS_ON_PIN PA3 -#define KILL_PIN -1 //PD5 // EXP2-10 -#define PWR_LOSS PG5 // Power loss / nAC_FAULT - -// -// MAX7219_DEBUG -// -#define MAX7219_CLK_PIN PG10 // EXP1-1 -#define MAX7219_DIN_PIN PD7 // EXP1-3 -#define MAX7219_LOAD_PIN PD1 // EXP1-5 - -// -// LCD / Controller -// -//#define SD_DETECT_PIN -1 //PB6) // EXP2-4 -#define BEEPER_PIN PG10 // EXP1-1 -#define LCD_PINS_RS PG9 // EXP1-4 -#define LCD_PINS_ENABLE PD7 // EXP1-3 -#define LCD_PINS_D4 PD1 // EXP1-5 -#define LCD_PINS_D5 PF0 // EXP1-6 -#define LCD_PINS_D6 PD3 // EXP1-7 -#define LCD_PINS_D7 PD4 // EXP1-8 -#define BTN_EN1 PD6 // EXP2-5 -#define BTN_EN2 PD0 // EXP2-3 -#define BTN_ENC PG11 // EXP1-2 diff --git a/Marlin/src/pins/stm32/pins_VAKE403D.h b/Marlin/src/pins/stm32/pins_VAKE403D.h deleted file mode 100644 index 35faf076abb2..000000000000 --- a/Marlin/src/pins/stm32/pins_VAKE403D.h +++ /dev/null @@ -1,194 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if !defined(STM32F4) && !defined(STM32F4xx) - #error "Oops! Select an STM32F4 board in 'Tools > Board.'" -#elif HOTENDS > 2 || E_STEPPERS > 2 - #error "STM32F4 supports up to 2 hotends / E-steppers." -#endif - -#define DEFAULT_MACHINE_NAME "STM32F446VET6" -#define BOARD_NAME "STM32F4 VAkE" - -//#define I2C_EEPROM - -#define E2END 0xFFF // EEPROM end address (4kB) - -// -// Servos -// -//#define SERVO0_PIN PE13 -//#define SERVO1_PIN PE14 - -// -// Limit Switches -// -#define X_STOP_PIN PE10 -#define Y_STOP_PIN PE9 -#define Z_STOP_PIN PE8 - -// -// Z Probe (when not Z_MIN_PIN) -// -#ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN PA4 -#endif - -// -// Filament runout -// -#define FIL_RUNOUT_PIN PA3 - -// -// Steppers -// - -#define STEPPER_ENABLE_PIN PB2 - -#define X_STEP_PIN PC6 // X_STEP -#define X_DIR_PIN PC7 // X_DIR -#define X_ENABLE_PIN PB2 // -#ifndef X_CS_PIN - #define X_CS_PIN PC8 // X_CS -#endif - -#define Y_STEP_PIN PD9 // Y_STEP -#define Y_DIR_PIN PD10 // Y_DIR -#define Y_ENABLE_PIN PB2 // -#ifndef Y_CS_PIN - #define Y_CS_PIN PD11 // Y_CS -#endif - -#define Z_STEP_PIN PE15 // Z_STEP -#define Z_DIR_PIN PB10 // Z_DIR -#define Z_ENABLE_PIN PB2 -#ifndef Z_CS_PIN - #define Z_CS_PIN PD8 -#endif - -#define E0_STEP_PIN PB1 -#define E0_DIR_PIN PB13 -#define E0_ENABLE_PIN PB2 -#ifndef E0_CS_PIN - #define E0_CS_PIN PE11 -#endif - -#define E1_STEP_PIN PC4 -#define E1_DIR_PIN PC5 -#define E1_ENABLE_PIN PB2 -#ifndef E1_CS_PIN - #define E1_CS_PIN PB0 -#endif - -#define SCK_PIN PE12 // PA5 // SPI1 for SD card -#define MISO_PIN PE13 // PA6 -#define MOSI_PIN PE14 // PA7 - -// added for SD card : optional or not ??? -//#define SD_CHIP_SELECT_PIN SDSS // The default chip select pin for the SD card is SS. -// The following three pins must not be redefined for hardware SPI. -//#define SPI_MOSI_PIN MOSI_PIN // SPI Master Out Slave In pin -//#define SPI_MISO_PIN MISO_PIN // SPI Master In Slave Out pin -//#define SPI_SCK_PIN SCK_PIN // SPI Clock pin - -// -// Temperature Sensors (Analog inputs) -// - -#define TEMP_0_PIN PC0 // Analog Input -#define TEMP_1_PIN PC1 // Analog Input -#define TEMP_2_PIN PC2 // Analog Input -#define TEMP_3_PIN PC3 // Analog Input -#define TEMP_BED_PIN PC3 // Analog Input - -// -// Heaters / Fans -// - -#define HEATER_0_PIN PD15 -#define HEATER_1_PIN PD14 -#define HEATER_BED_PIN PD12 - -#ifndef FAN_PIN - #define FAN_PIN PD13 -#endif -#define FAN1_PIN PB5 // PA0 -#define FAN2_PIN PB4 // PA1 - -#define ORIG_E0_AUTO_FAN_PIN PD13 // Use this by NOT overriding E0_AUTO_FAN_PIN - -// -// Misc. Functions -// - -//#define CASE_LIGHT_PIN_CI PF13 -//#define CASE_LIGHT_PIN_DO PF14 -//#define NEOPIXEL_PIN PF13 - -// -// Prusa i3 MK2 Multi Material Multiplexer Support -// -//#define E_MUX0_PIN PG3 -//#define E_MUX1_PIN PG4 - -#define LED_PIN PB14 // Alive -#define PS_ON_PIN PE0 -#define KILL_PIN PD5 -#define POWER_LOSS_PIN PA4 // ?? Power loss / nAC_FAULT - -#if ENABLED(SDSUPPORT) - #define SD_DETECT_PIN PB7 - #define SS_PIN PB_15 // USD_CS -> CS for onboard SD -#endif - -// -// LCD / Controller -// -#if HAS_SPI_LCD - #if ENABLED(SDSUPPORT) - #define SDSS PB6 // CS for SD card in LCD - #endif - #define BEEPER_PIN PC9 - #define LCD_PINS_RS PC12 - #define LCD_PINS_ENABLE PD7 - #define LCD_PINS_D4 PD1 - #define LCD_PINS_D5 PD2 - #define LCD_PINS_D6 PD3 - #define LCD_PINS_D7 PD4 - #define BTN_EN1 PD6 - #define BTN_EN2 PD0 - #define BTN_ENC PB12 -#endif - -// -// ST7920 Delays -// -#ifndef ST7920_DELAY_1 - #define ST7920_DELAY_1 DELAY_NS(96) -#endif -#ifndef ST7920_DELAY_2 - #define ST7920_DELAY_2 DELAY_NS(48) -#endif -#ifndef ST7920_DELAY_3 - #define ST7920_DELAY_3 DELAY_NS(715) -#endif diff --git a/Marlin/src/pins/stm32f0/pins_MALYAN_M200_V2.h b/Marlin/src/pins/stm32f0/pins_MALYAN_M200_V2.h new file mode 100644 index 000000000000..abdd088f9bd3 --- /dev/null +++ b/Marlin/src/pins/stm32f0/pins_MALYAN_M200_V2.h @@ -0,0 +1,31 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#pragma once + +#if NOT_TARGET(STM32F0xx) + #error "Oops! Select an STM32F0 board in your IDE." +#endif + +#define BOARD_INFO_NAME "Malyan M200 V2" + +#include "../stm32f1/pins_MALYAN_M200.h" diff --git a/Marlin/src/pins/stm32f0/pins_MALYAN_M300.h b/Marlin/src/pins/stm32f0/pins_MALYAN_M300.h new file mode 100644 index 000000000000..a0e035a91688 --- /dev/null +++ b/Marlin/src/pins/stm32f0/pins_MALYAN_M300.h @@ -0,0 +1,91 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#pragma once + +#if NOT_TARGET(__STM32F1__, STM32F1xx, STM32F0xx) + #error "Oops! Select a 'Malyan M300' board in 'Tools > Board.'" +#endif + +#define BOARD_INFO_NAME "Malyan M300" + +// +// EEPROM Emulation +// +#if NO_EEPROM_SELECTED + #define FLASH_EEPROM_EMULATION + #ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE 0x800U // 2KB + #endif +#endif + +// +// SD CARD SPI +// +#define SDSS SS_PIN + +// +// Timers +// +#define STEP_TIMER 6 +#define TEMP_TIMER 7 + +// +// Limit Switches +// +#define X_MAX_PIN PC13 +#define Y_MAX_PIN PC14 +#define Z_MAX_PIN PC15 +#define Z_MIN_PIN PB7 + +// +// Steppers +// +#define X_STEP_PIN PB14 +#define X_DIR_PIN PB13 +#define X_ENABLE_PIN PB10 + +#define Y_STEP_PIN PB12 +#define Y_DIR_PIN PB11 +#define Y_ENABLE_PIN PB10 + +#define Z_STEP_PIN PB2 +#define Z_DIR_PIN PB1 +#define Z_ENABLE_PIN PB10 + +#define E0_STEP_PIN PA7 +#define E0_DIR_PIN PA6 +#define E0_ENABLE_PIN PB0 + +// +// Temperature Sensors +// +#define TEMP_0_PIN PA0 // Analog Input (HOTEND0 thermistor) +#define TEMP_BED_PIN PA4 // Analog Input (BED thermistor) + +// +// Heaters / Fans +// +#define HEATER_0_PIN PA1 // HOTEND0 MOSFET +#define HEATER_BED_PIN PA5 // BED MOSFET + +#define AUTO_FAN_PIN PA8 diff --git a/Marlin/src/pins/stm32f1/pins_BTT_SKR_E3_DIP.h b/Marlin/src/pins/stm32f1/pins_BTT_SKR_E3_DIP.h new file mode 100644 index 000000000000..63b97b666faf --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_BTT_SKR_E3_DIP.h @@ -0,0 +1,289 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(TARGET_STM32F1) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#endif + +#define BOARD_INFO_NAME "BTT SKR E3 DIP V1.0" + +// Release PB3/PB4 (TMC_SW Pins) from JTAG pins +#define DISABLE_JTAG + +// Ignore temp readings during development. +//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 + +#if EITHER(NO_EEPROM_SELECTED, FLASH_EEPROM_EMULATION) + #define FLASH_EEPROM_EMULATION + #define EEPROM_PAGE_SIZE (0x800U) // 2KB + #define EEPROM_START_ADDRESS (0x8000000UL + (STM32_FLASH_SIZE) * 1024UL - (EEPROM_PAGE_SIZE) * 2UL) + #define MARLIN_EEPROM_SIZE EEPROM_PAGE_SIZE // 2KB +#endif + +// +// Servos +// +#define SERVO0_PIN PA1 // SERVOS + +// +// Limit Switches +// +#define X_STOP_PIN PC1 // "X-STOP" +#define Y_STOP_PIN PC0 // "Y-STOP" +#define Z_STOP_PIN PC15 // "Z-STOP" + +// +// Z Probe must be this pin +// +#define Z_MIN_PROBE_PIN PC14 // "PROBE" + +// +// Filament Runout Sensor +// +#ifndef FIL_RUNOUT_PIN + #define FIL_RUNOUT_PIN PC2 // "E0-STOP" +#endif + +// +// Steppers +// +#define X_ENABLE_PIN PC7 +#define X_STEP_PIN PC6 +#define X_DIR_PIN PB15 +#ifndef X_CS_PIN + #define X_CS_PIN PC10 +#endif + +#define Y_ENABLE_PIN PB14 +#define Y_STEP_PIN PB13 +#define Y_DIR_PIN PB12 +#ifndef Y_CS_PIN + #define Y_CS_PIN PC11 +#endif + +#define Z_ENABLE_PIN PB11 +#define Z_STEP_PIN PB10 +#define Z_DIR_PIN PB2 +#ifndef Z_CS_PIN + #define Z_CS_PIN PC12 +#endif + +#define E0_ENABLE_PIN PB1 +#define E0_STEP_PIN PB0 +#define E0_DIR_PIN PC5 +#ifndef E0_CS_PIN + #define E0_CS_PIN PD2 +#endif + +// +// Software SPI pins for TMC2130 stepper drivers +// +#if ENABLED(TMC_USE_SW_SPI) + #ifndef TMC_SW_MOSI + #define TMC_SW_MOSI PB5 + #endif + #ifndef TMC_SW_MISO + #define TMC_SW_MISO PB4 + #endif + #ifndef TMC_SW_SCK + #define TMC_SW_SCK PB3 + #endif +#endif + +#if HAS_TMC_UART + /** + * TMC2208/TMC2209 stepper drivers + * + * Hardware serial communication ports. + * If undefined software serial is used according to the pins below + */ + //#define X_HARDWARE_SERIAL MSerial1 + //#define Y_HARDWARE_SERIAL MSerial1 + //#define Z_HARDWARE_SERIAL MSerial1 + //#define E0_HARDWARE_SERIAL MSerial1 + + // + // Software serial + // + #define X_SERIAL_TX_PIN PC10 + #define X_SERIAL_RX_PIN PC10 + + #define Y_SERIAL_TX_PIN PC11 + #define Y_SERIAL_RX_PIN PC11 + + #define Z_SERIAL_TX_PIN PC12 + #define Z_SERIAL_RX_PIN PC12 + + #define E0_SERIAL_TX_PIN PD2 + #define E0_SERIAL_RX_PIN PD2 + + // Reduce baud rate to improve software serial reliability + #define TMC_BAUD_RATE 19200 +#endif + +// +// Temperature Sensors +// +#define TEMP_0_PIN PA0 // Analog Input "TH0" +#define TEMP_BED_PIN PC3 // Analog Input "TB0" + +// +// Heaters / Fans +// +#define HEATER_0_PIN PC8 // "HE" +#define HEATER_BED_PIN PC9 // "HB" +#define FAN_PIN PA8 // "FAN0" + +// +// USB connect control +// +#define USB_CONNECT_PIN PC13 +#define USB_CONNECT_INVERTING false + +/** + * _____ + * 5V | 1 2 | GND + * (LCD_EN) PB7 | 3 4 | PB8 (LCD_RS) + * (LCD_D4) PB9 | 5 6 PA10 (BTN_EN2) + * RESET | 7 8 | PA9 (BTN_EN1) + * (BTN_ENC) PB6 | 9 10| PA15 (BEEPER) + * ----- + * EXP1 + */ + +#if HAS_WIRED_LCD + + #if ENABLED(CR10_STOCKDISPLAY) + + #define BEEPER_PIN PA15 + + #define BTN_ENC PB6 + #define BTN_EN1 PA9 + #define BTN_EN2 PA10 + + #define LCD_PINS_RS PB8 + #define LCD_PINS_ENABLE PB7 + #define LCD_PINS_D4 PB9 + + #elif ENABLED(ZONESTAR_LCD) // ANET A8 LCD Controller - Must convert to 3.3V - CONNECTING TO 5V WILL DAMAGE THE BOARD! + + #error "CAUTION! ZONESTAR_LCD requires wiring modifications. See 'pins_BTT_SKR_MINI_E3_common.h' for details. Comment out this line to continue." + + #define LCD_PINS_RS PB9 + #define LCD_PINS_ENABLE PB6 + #define LCD_PINS_D4 PB8 + #define LCD_PINS_D5 PA10 + #define LCD_PINS_D6 PA9 + #define LCD_PINS_D7 PA15 + #define ADC_KEYPAD_PIN PA1 // Repurpose servo pin for ADC - CONNECTING TO 5V WILL DAMAGE THE BOARD! + + #elif EITHER(MKS_MINI_12864, ENDER2_STOCKDISPLAY) + + /** Creality Ender-2 display pinout + * _____ + * 5V | 1 2 | GND + * (MOSI) PB7 | 3 4 | PB8 (LCD_RS) + * (LCD_A0) PB9 | 5 6 PA10 (BTN_EN2) + * RESET | 7 8 | PA9 (BTN_EN1) + * (BTN_ENC) PB6 | 9 10| PA15 (SCK) + * ----- + * EXP1 + */ + + #define BTN_ENC PB6 + #define BTN_EN1 PA9 + #define BTN_EN2 PA10 + + #define DOGLCD_CS PB8 + #define DOGLCD_A0 PB9 + #define DOGLCD_SCK PA15 + #define DOGLCD_MOSI PB7 + #define FORCE_SOFT_SPI + #define LCD_BACKLIGHT_PIN -1 + + #else + #error "Only CR10_STOCKDISPLAY, ZONESTAR_LCD, ENDER2_STOCKDISPLAY, MKS_MINI_12864, and MKS_LCD12864 are currently supported on the BIGTREE_SKR_E3_DIP." + #endif + +#endif // HAS_WIRED_LCD + +#if BOTH(TOUCH_UI_FTDI_EVE, LCD_FYSETC_TFT81050) + + #error "CAUTION! LCD_FYSETC_TFT81050 requires wiring modifications. See 'pins_BTT_SKR_E3_DIP.h' for details. Comment out this line to continue." + + /** FYSETC TFT TFT81050 display pinout + * + * Board Display + * _____ _____ + * 5V | 1 2 | GND (SPI1-MISO) MISO | 1 2 | SCK (SPI1-SCK) + * (FREE) PB7 | 3 4 | PB8 (LCD_CS) (PA9) MOD_RESET | 3 4 | SD_CS (PA10) + * (FREE) PB9 | 5 6 PA10 (SD_CS) (PB8) LCD_CS | 5 6 MOSI (SPI1-MOSI) + * RESET | 7 8 | PA9 (MOD_RESET) (PA15) SD_DET | 7 8 | RESET + * (BEEPER) PB6 | 9 10| PA15 (SD_DET) GND | 9 10| 5V + * ----- ----- + * EXP1 EXP1 + * + * Needs custom cable: + * + * Board Adapter Display + * _________ + * EXP1-1 ----------- EXP1-10 + * EXP1-2 ----------- EXP1-9 + * SPI1-4 ----------- EXP1-6 + * EXP1-4 ----------- EXP1-5 + * SP11-3 ----------- EXP1-2 + * EXP1-6 ----------- EXP1-4 + * EXP1-7 ----------- EXP1-8 + * EXP1-8 ----------- EXP1-3 + * SPI1-1 ----------- EXP1-1 + * EXP1-10 ----------- EXP1-7 + */ + + #define CLCD_SPI_BUS 1 // SPI1 connector + + #define BEEPER_PIN PB6 + + #define CLCD_MOD_RESET PA9 + #define CLCD_SPI_CS PA8 + +#endif // TOUCH_UI_FTDI_EVE && LCD_FYSETC_TFT81050 + +// +// SD Support +// + +#ifndef SDCARD_CONNECTION + #define SDCARD_CONNECTION ONBOARD +#endif + +#if SD_CONNECTION_IS(ONBOARD) + #define SD_DETECT_PIN PC4 +#elif SD_CONNECTION_IS(LCD) && BOTH(TOUCH_UI_FTDI_EVE, LCD_FYSETC_TFT81050) + #define SD_DETECT_PIN PA15 + #define SS_PIN PA10 +#elif SD_CONNECTION_IS(CUSTOM_CABLE) + #error "SD CUSTOM_CABLE is not compatible with SKR E3 DIP." +#endif + +#define ONBOARD_SPI_DEVICE 1 // SPI1 +#define ONBOARD_SD_CS_PIN PA4 // Chip select for "System" SD card diff --git a/Marlin/src/pins/stm32/pins_BTT_SKR_MINI_E3_V1_0.h b/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_V1_0.h similarity index 74% rename from Marlin/src/pins/stm32/pins_BTT_SKR_MINI_E3_V1_0.h rename to Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_V1_0.h index f909cce83a31..78751a6bac87 100644 --- a/Marlin/src/pins/stm32/pins_BTT_SKR_MINI_E3_V1_0.h +++ b/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_V1_0.h @@ -16,22 +16,22 @@ * 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 . + * along with this program. If not, see . * */ #pragma once -#include "pins_BTT_SKR_MINI_E3.h" +#include "pins_BTT_SKR_MINI_E3_common.h" -#define BOARD_INFO_NAME "BIGTREE SKR Mini E3" +#define BOARD_INFO_NAME "BTT SKR Mini E3 V1.0" /** * TMC220x stepper drivers * Hardware serial communication ports. */ #if HAS_TMC_UART - #define X_HARDWARE_SERIAL Serial4 - #define Y_HARDWARE_SERIAL Serial4 - #define Z_HARDWARE_SERIAL Serial4 - #define E0_HARDWARE_SERIAL Serial4 + #define X_HARDWARE_SERIAL MSerial4 + #define Y_HARDWARE_SERIAL MSerial4 + #define Z_HARDWARE_SERIAL MSerial4 + #define E0_HARDWARE_SERIAL MSerial4 #endif diff --git a/Marlin/src/pins/stm32/pins_BTT_SKR_MINI_E3_V1_2.h b/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_V1_2.h similarity index 60% rename from Marlin/src/pins/stm32/pins_BTT_SKR_MINI_E3_V1_2.h rename to Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_V1_2.h index 5701dd5c5629..8d384c739681 100644 --- a/Marlin/src/pins/stm32/pins_BTT_SKR_MINI_E3_V1_2.h +++ b/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_V1_2.h @@ -16,35 +16,35 @@ * 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 . + * along with this program. If not, see . * */ #pragma once -#include "pins_BTT_SKR_MINI_E3.h" +#include "pins_BTT_SKR_MINI_E3_common.h" -#define BOARD_INFO_NAME "BIGTREE SKR Mini E3 V1.2" +#define BOARD_INFO_NAME "BTT SKR Mini E3 V1.2" -#define NEOPIXEL_PIN PC7 // LED driving pin +#define NEOPIXEL_PIN PC7 // LED driving pin /** * TMC2208/TMC2209 stepper drivers */ -#if HAS_TMC220x +#if HAS_TMC_UART // // Software serial // - #define X_SERIAL_TX_PIN PB15 - #define X_SERIAL_RX_PIN PB15 + #define X_SERIAL_TX_PIN PB15 + #define X_SERIAL_RX_PIN PB15 - #define Y_SERIAL_TX_PIN PC6 - #define Y_SERIAL_RX_PIN PC6 + #define Y_SERIAL_TX_PIN PC6 + #define Y_SERIAL_RX_PIN PC6 - #define Z_SERIAL_TX_PIN PC10 - #define Z_SERIAL_RX_PIN PC10 + #define Z_SERIAL_TX_PIN PC10 + #define Z_SERIAL_RX_PIN PC10 - #define E0_SERIAL_TX_PIN PC11 - #define E0_SERIAL_RX_PIN PC11 + #define E0_SERIAL_TX_PIN PC11 + #define E0_SERIAL_RX_PIN PC11 // Reduce baud rate to improve software serial reliability #define TMC_BAUD_RATE 19200 diff --git a/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_V2_0.h b/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_V2_0.h new file mode 100644 index 000000000000..0a0d857db3f4 --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_V2_0.h @@ -0,0 +1,59 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#define SKR_MINI_E3_V2 + +// Onboard I2C EEPROM +#if NO_EEPROM_SELECTED + #define I2C_EEPROM + #define MARLIN_EEPROM_SIZE 0x1000 // 4KB + #undef NO_EEPROM_SELECTED +#endif + +#include "pins_BTT_SKR_MINI_E3_common.h" + +#define BOARD_INFO_NAME "BTT SKR Mini E3 V2.0" + +// Release PA13/PA14 (led, usb control) from SWD pins +#define DISABLE_DEBUG + +#define NEOPIXEL_PIN PA8 // LED driving pin + +#define PS_ON_PIN PC13 // Power Supply Control + +#define FAN1_PIN PC7 + +#ifndef CONTROLLER_FAN_PIN + #define CONTROLLER_FAN_PIN FAN1_PIN +#endif + +/** + * TMC220x stepper drivers + * Hardware serial communication ports. + */ +#if HAS_TMC_UART + #define X_HARDWARE_SERIAL MSerial4 + #define Y_HARDWARE_SERIAL MSerial4 + #define Z_HARDWARE_SERIAL MSerial4 + #define E0_HARDWARE_SERIAL MSerial4 +#endif diff --git a/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h b/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h new file mode 100644 index 000000000000..50257f4f4608 --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h @@ -0,0 +1,276 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(TARGET_STM32F1) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#endif + +// Release PB3/PB4 (E0 STP/DIR) from JTAG pins +#define DISABLE_JTAG + +// Ignore temp readings during development. +//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 + +#if EITHER(NO_EEPROM_SELECTED, FLASH_EEPROM_EMULATION) + #define FLASH_EEPROM_EMULATION + #define EEPROM_PAGE_SIZE (0x800U) // 2KB + #define EEPROM_START_ADDRESS (0x8000000UL + (STM32_FLASH_SIZE) * 1024UL - (EEPROM_PAGE_SIZE) * 2UL) + #define MARLIN_EEPROM_SIZE EEPROM_PAGE_SIZE // 2KB +#endif + +// +// Servos +// +#define SERVO0_PIN PA1 // "SERVOS" + +// +// Limit Switches +// +#define X_STOP_PIN PC0 // "X-STOP" +#define Y_STOP_PIN PC1 // "Y-STOP" +#define Z_STOP_PIN PC2 // "Z-STOP" + +// +// Z Probe must be this pin +// +#define Z_MIN_PROBE_PIN PC14 // "PROBE" + +// +// Filament Runout Sensor +// +#ifndef FIL_RUNOUT_PIN + #define FIL_RUNOUT_PIN PC15 // "E0-STOP" +#endif + +// +// Steppers +// +#define X_ENABLE_PIN PB14 +#define X_STEP_PIN PB13 +#define X_DIR_PIN PB12 + +#define Y_ENABLE_PIN PB11 +#define Y_STEP_PIN PB10 +#define Y_DIR_PIN PB2 + +#define Z_ENABLE_PIN PB1 +#define Z_STEP_PIN PB0 +#define Z_DIR_PIN PC5 + +#define E0_ENABLE_PIN PD2 +#define E0_STEP_PIN PB3 +#define E0_DIR_PIN PB4 + +// +// Temperature Sensors +// +#define TEMP_0_PIN PA0 // Analog Input "TH0" +#define TEMP_BED_PIN PC3 // Analog Input "TB0" + +// +// Heaters / Fans +// +#define HEATER_0_PIN PC8 // "HE" +#define HEATER_BED_PIN PC9 // "HB" + +#ifdef SKR_MINI_E3_V2 + #define FAN_PIN PC6 +#else + #define FAN_PIN PA8 // "FAN0" +#endif + +// +// USB connect control +// +#ifdef SKR_MINI_E3_V2 + #define USB_CONNECT_PIN PA14 +#else + #define USB_CONNECT_PIN PC13 +#endif + +#define USB_CONNECT_INVERTING false + +/** + * SKR Mini E3 V1.0, V1.2 SKR Mini E3 V2.0 + * _____ _____ + * 5V | 1 2 | GND 5V | 1 2 | GND + * (LCD_EN) PB7 | 3 4 | PB8 (LCD_RS) (LCD_EN) PB15 | 3 4 | PB8 (LCD_RS) + * (LCD_D4) PB9 | 5 6 PA10 (BTN_EN2) (LCD_D4) PB9 | 5 6 PA10 (BTN_EN2) + * RESET | 7 8 | PA9 (BTN_EN1) RESET | 7 8 | PA9 (BTN_EN1) + * (BTN_ENC) PB6 | 9 10| PB5 (BEEPER) (BTN_ENC) PA15 | 9 10| PB5 (BEEPER) + * ----- ----- + * EXP1 EXP1 + */ +#ifdef SKR_MINI_E3_V2 + #define EXP1_9 PA15 + #define EXP1_3 PB15 +#else + #define EXP1_9 PB6 + #define EXP1_3 PB7 +#endif + +#if HAS_WIRED_LCD + + #if ENABLED(CR10_STOCKDISPLAY) + + #define BEEPER_PIN PB5 + #define BTN_ENC EXP1_9 + + #define BTN_EN1 PA9 + #define BTN_EN2 PA10 + + #define LCD_PINS_RS PB8 + #define LCD_PINS_ENABLE EXP1_3 + #define LCD_PINS_D4 PB9 + + #elif ENABLED(ZONESTAR_LCD) // ANET A8 LCD Controller - Must convert to 3.3V - CONNECTING TO 5V WILL DAMAGE THE BOARD! + + #error "CAUTION! ZONESTAR_LCD requires wiring modifications. See 'pins_BTT_SKR_MINI_E3_common.h' for details. Comment out this line to continue." + + #define LCD_PINS_RS PB9 + #define LCD_PINS_ENABLE EXP1_9 + #define LCD_PINS_D4 PB8 + #define LCD_PINS_D5 PA10 + #define LCD_PINS_D6 PA9 + #define LCD_PINS_D7 PB5 + #define ADC_KEYPAD_PIN PA1 // Repurpose servo pin for ADC - CONNECTING TO 5V WILL DAMAGE THE BOARD! + + #elif EITHER(MKS_MINI_12864, ENDER2_STOCKDISPLAY) + + #define BTN_ENC EXP1_9 + #define BTN_EN1 PA9 + #define BTN_EN2 PA10 + + #define DOGLCD_CS PB8 + #define DOGLCD_A0 PB9 + #define DOGLCD_SCK PB5 + #define DOGLCD_MOSI EXP1_3 + + #define FORCE_SOFT_SPI + #define LCD_BACKLIGHT_PIN -1 + + #elif IS_TFTGLCD_PANEL + + #if ENABLED(TFTGLCD_PANEL_SPI) + + #error "CAUTION! TFTGLCD_PANEL_SPI requires wiring modifications. See 'pins_BTT_SKR_MINI_E3_common.h' for details. Comment out this line to continue." + + /** + * TFTGLCD_PANEL_SPI display pinout + * + * Board Display + * _____ _____ + * 5V | 1 2 | GND (SPI1-MISO) MISO | 1 2 | SCK (SPI1-SCK) + * (FREE) PB7 | 3 4 | PB8 (LCD_CS) (PA9) GLCD_CS | 3 4 | SD_CS (PA10) + * (FREE) PB9 | 5 6 | PA10 (SD_CS) (FREE) | 5 6 | MOSI (SPI1-MOSI) + * RESET | 7 8 | PA9 (MOD_RESET) (PB5) SD_DET | 7 8 | (FREE) + * (BEEPER) PB6 | 9 10| PB5 (SD_DET) GND | 9 10| 5V + * ----- ----- + * EXP1 EXP1 + * + * Needs custom cable: + * + * Board Adapter Display + * _________ + * EXP1-1 ----------- EXP1-10 + * EXP1-2 ----------- EXP1-9 + * SPI1-4 ----------- EXP1-6 + * EXP1-4 ----------- FREE + * SPI1-3 ----------- EXP1-2 + * EXP1-6 ----------- EXP1-4 + * EXP1-7 ----------- FREE + * EXP1-8 ----------- EXP1-3 + * SPI1-1 ----------- EXP1-1 + * EXP1-10 ----------- EXP1-7 + */ + + #define TFTGLCD_CS PA9 + + #endif + + #else + #error "Only CR10_STOCKDISPLAY, ZONESTAR_LCD, ENDER2_STOCKDISPLAY, MKS_MINI_12864, and TFTGLCD_PANEL_(SPI|I2C) are currently supported on the BIGTREE_SKR_MINI_E3." + #endif + +#endif // HAS_WIRED_LCD + +#if BOTH(TOUCH_UI_FTDI_EVE, LCD_FYSETC_TFT81050) + + #error "CAUTION! LCD_FYSETC_TFT81050 requires wiring modifications. See 'pins_BTT_SKR_MINI_E3_common.h' for details. Comment out this line to continue." + + /** FYSETC TFT TFT81050 display pinout + * + * Board Display + * _____ _____ + * 5V | 1 2 | GND (SPI1-MISO) MISO | 1 2 | SCK (SPI1-SCK) + * (FREE) PB7 | 3 4 | PB8 (LCD_CS) (PA9) MOD_RESET | 3 4 | SD_CS (PA10) + * (FREE) PB9 | 5 6 | PA10 (SD_CS) (PB8) LCD_CS | 5 6 | MOSI (SPI1-MOSI) + * RESET | 7 8 | PA9 (MOD_RESET) (PB5) SD_DET | 7 8 | RESET + * (BEEPER) PB6 | 9 10| PB5 (SD_DET) GND | 9 10| 5V + * ----- ----- + * EXP1 EXP1 + * + * Needs custom cable: + * + * Board Adapter Display + * _________ + * EXP1-1 ----------- EXP1-10 + * EXP1-2 ----------- EXP1-9 + * SPI1-4 ----------- EXP1-6 + * EXP1-4 ----------- EXP1-5 + * SPI1-3 ----------- EXP1-2 + * EXP1-6 ----------- EXP1-4 + * EXP1-7 ----------- EXP1-8 + * EXP1-8 ----------- EXP1-3 + * SPI1-1 ----------- EXP1-1 + * EXP1-10 ----------- EXP1-7 + */ + + #define CLCD_SPI_BUS 1 // SPI1 connector + + #define BEEPER_PIN EXP1_9 + + #define CLCD_MOD_RESET PA9 + #define CLCD_SPI_CS PB8 + +#endif // TOUCH_UI_FTDI_EVE && LCD_FYSETC_TFT81050 + +// +// SD Support +// + +#ifndef SDCARD_CONNECTION + #define SDCARD_CONNECTION ONBOARD +#endif + +#if SD_CONNECTION_IS(ONBOARD) + #define SD_DETECT_PIN PC4 +#elif SD_CONNECTION_IS(LCD) && (BOTH(TOUCH_UI_FTDI_EVE, LCD_FYSETC_TFT81050) || IS_TFTGLCD_PANEL) + #define SD_DETECT_PIN PB5 + #define SS_PIN PA10 +#elif SD_CONNECTION_IS(CUSTOM_CABLE) + #error "SD CUSTOM_CABLE is not compatible with SKR Mini E3." +#endif + +#define ONBOARD_SPI_DEVICE 1 // SPI1 +#define ONBOARD_SD_CS_PIN PA4 // Chip select for "System" SD card diff --git a/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_V1_1.h b/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_V1_1.h new file mode 100644 index 000000000000..47fff4467c72 --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_V1_1.h @@ -0,0 +1,228 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(TARGET_STM32F1) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#endif + +#define BOARD_INFO_NAME "BTT SKR Mini V1.1" + +//#define DISABLE_DEBUG +#define DISABLE_JTAG + +// Ignore temp readings during development. +//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 + +#if EITHER(NO_EEPROM_SELECTED, FLASH_EEPROM_EMULATION) + #define FLASH_EEPROM_EMULATION + #define EEPROM_PAGE_SIZE (0x800U) // 2KB + #define EEPROM_START_ADDRESS (0x8000000UL + (STM32_FLASH_SIZE) * 1024UL - (EEPROM_PAGE_SIZE) * 2UL) + #define MARLIN_EEPROM_SIZE EEPROM_PAGE_SIZE // 2KB +#endif + +// +// Limit Switches +// +#define X_MIN_PIN PC2 +#define X_MAX_PIN PA2 +#define Y_MIN_PIN PC1 +#define Y_MAX_PIN PA1 +#define Z_MIN_PIN PC0 +#define Z_MAX_PIN PC3 + +// +// Steppers +// + +#define X_STEP_PIN PC6 +#define X_DIR_PIN PC7 +#define X_ENABLE_PIN PB15 + +#define Y_STEP_PIN PB13 +#define Y_DIR_PIN PB14 +#define Y_ENABLE_PIN PB12 + +#define Z_STEP_PIN PB10 +#define Z_DIR_PIN PB11 +#define Z_ENABLE_PIN PB2 + +#define E0_STEP_PIN PC5 +#define E0_DIR_PIN PB0 +#define E0_ENABLE_PIN PC4 + +#if ENABLED(TMC_USE_SW_SPI) + #ifndef TMC_SW_SCK + #define TMC_SW_SCK PB3 + #endif + #ifndef TMC_SW_MISO + #define TMC_SW_MISO PB4 + #endif + #ifndef TMC_SW_MOSI + #define TMC_SW_MOSI PB5 + #endif +#endif + +// +// Heaters / Fans +// +#define HEATER_0_PIN PA8 +#define FAN_PIN PC8 +#define HEATER_BED_PIN PC9 + +// +// Temperature Sensors +// +#define TEMP_BED_PIN PB1 // Analog Input +#define TEMP_0_PIN PA0 // Analog Input + +// +// LCD Pins +// + +/** + * _____ _____ + * NC | · · | GND 5V | · · | GND + * RESET | · · | PB9 (SD_DETECT) (LCD_D7) PC14 | · · | PC15 (LCD_D6) + * (MOSI) PB5 | · · | PB8 (BTN_EN2) (LCD_D5) PB7 | · · | PC13 (LCD_D4) + * (SD_SS) PA15 | · · | PD2 (BTN_EN1) (LCD_RS) PC12 | · · | PB6 (LCD_EN) + * (SCK) PB3 | · · | PB4 (MISO) (BTN_ENC) PC11 | · · | PC10 (BEEPER) + * ----- ----- + * EXP2 EXP1 + */ + +#if HAS_WIRED_LCD + #define BEEPER_PIN PC10 + #define BTN_ENC PC11 + + #if ENABLED(CR10_STOCKDISPLAY) + #define LCD_PINS_RS PC15 + + #define BTN_EN1 PB6 + #define BTN_EN2 PC13 + + #define LCD_PINS_ENABLE PC14 + #define LCD_PINS_D4 PB7 + + #elif IS_TFTGLCD_PANEL + + #undef BEEPER_PIN + #undef BTN_ENC + + #if ENABLED(TFTGLCD_PANEL_SPI) + #define TFTGLCD_CS PD2 + #endif + + #define SD_DETECT_PIN PB9 + + #else + + #define LCD_PINS_RS PC12 + + #define BTN_EN1 PD2 + #define BTN_EN2 PB8 + + #define LCD_PINS_ENABLE PB6 + + #if ENABLED(FYSETC_MINI_12864) + + #define LCD_BACKLIGHT_PIN -1 + #define LCD_RESET_PIN PC13 + #define DOGLCD_A0 PC12 + #define DOGLCD_CS PB6 + #define DOGLCD_SCK PB3 + #define DOGLCD_MOSI PB5 + + #define FORCE_SOFT_SPI // SPI MODE3 + + #define LED_PIN PB7 // red pwm + //#define LED_PIN PC15 // green + //#define LED_PIN PC14 // blue + + //#if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) + // #ifndef RGB_LED_R_PIN + // #define RGB_LED_R_PIN PB7 + // #endif + // #ifndef RGB_LED_G_PIN + // #define RGB_LED_G_PIN PC15 + // #endif + // #ifndef RGB_LED_B_PIN + // #define RGB_LED_B_PIN PC14 + // #endif + //#elif ENABLED(FYSETC_MINI_12864_2_1) + // #define NEOPIXEL_PIN PB7 + //#endif + + #else // !FYSETC_MINI_12864 + + #define LCD_PINS_D4 PC13 + #if ENABLED(ULTIPANEL) + #define LCD_PINS_D5 PB7 + #define LCD_PINS_D6 PC15 + #define LCD_PINS_D7 PC14 + #endif + + #endif // !FYSETC_MINI_12864 + + #if HAS_MARLINUI_U8GLIB + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(125) + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(125) + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(125) + #endif + #endif + + #endif + +#endif // HAS_WIRED_LCD + +// +// SD Card +// + +// By default the onboard SD is enabled. +// Change SDCARD_CONNECTION from 'ONBOARD' to 'LCD' for an external (LCD module) SD +#ifndef SDCARD_CONNECTION + #define SDCARD_CONNECTION ONBOARD +#endif + +#if SD_CONNECTION_IS(LCD) + #define ENABLE_SPI3 + #define SD_DETECT_PIN PB9 + #define SCK_PIN PB3 + #define MISO_PIN PB4 + #define MOSI_PIN PB5 + #define SS_PIN PA15 +#elif SD_CONNECTION_IS(ONBOARD) + #define ENABLE_SPI1 + #define SD_DETECT_PIN PA3 + #define SCK_PIN PA5 + #define MISO_PIN PA6 + #define MOSI_PIN PA7 + #define SS_PIN PA4 +#endif +#define ONBOARD_SPI_DEVICE 1 // SPI1 +#define ONBOARD_SD_CS_PIN PA4 // Chip select for "System" SD card diff --git a/Marlin/src/pins/stm32f1/pins_CCROBOT_MEEB_3DP.h b/Marlin/src/pins/stm32f1/pins_CCROBOT_MEEB_3DP.h new file mode 100644 index 000000000000..66930a2ea5a6 --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_CCROBOT_MEEB_3DP.h @@ -0,0 +1,179 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(TARGET_STM32F1) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#elif HOTENDS > 1 || E_STEPPERS > 1 + #error "CCROBOT-ONLINE MEEB_3DP only supports 1 hotend / E-stepper. Comment out this line to continue." +#endif + +// https://github.com/ccrobot-online/MEEB_3DP +// Pin assignments for 32-bit MEEB_3DP +#define BOARD_INFO_NAME "CCROBOT-ONLINE MEEB_3DP" +#define DEFAULT_MACHINE_NAME "STM32F103RCT6" +#define BOARD_WEBSITE_URL "ccrobot-online.com" + +// +// Release PB4 from JTAG NRST role +// +#define DISABLE_JTAG + +// +// EEPROM +// +#if EITHER(NO_EEPROM_SELECTED, FLASH_EEPROM_EMULATION) + #define FLASH_EEPROM_EMULATION + #define EEPROM_PAGE_SIZE 0x800U // 2KB + #define EEPROM_START_ADDRESS (0x8000000UL + (STM32_FLASH_SIZE) * 1024UL - (EEPROM_PAGE_SIZE) * 2UL) + #define MARLIN_EEPROM_SIZE 0x1000 // 4KB +#endif + +// +// Servos +// +#define SERVO0_PIN PA1 + +// +// Limit Switches +// +#define X_STOP_PIN PC0 +#define Y_STOP_PIN PC1 +#define Z_STOP_PIN PC2 + +// +// Z Probe must be this pin +// +#define Z_MIN_PROBE_PIN PC15 // "PROBE" + +// +// TMC2208 stepper drivers +// +#define X_ENABLE_PIN PB4 +#define X_STEP_PIN PC12 +#define X_DIR_PIN PC11 + +#define Y_ENABLE_PIN PC10 +#define Y_STEP_PIN PB14 +#define Y_DIR_PIN PB13 + +#define Z_ENABLE_PIN PB12 +#define Z_STEP_PIN PB2 +#define Z_DIR_PIN PB1 + +#define E0_ENABLE_PIN PB0 +#define E0_STEP_PIN PA6 +#define E0_DIR_PIN PA5 + +// Stepper drivers Serial UART +#define X_SERIAL_TX_PIN PB3 +#define X_SERIAL_RX_PIN PD2 +#define Y_SERIAL_TX_PIN PA15 +#define Y_SERIAL_RX_PIN PC6 +#define Z_SERIAL_TX_PIN PB11 +#define Z_SERIAL_RX_PIN PB10 +#define E0_SERIAL_TX_PIN PC5 +#define E0_SERIAL_RX_PIN PC4 + +// Reduce baud rate to improve software serial reliability +#define TMC_BAUD_RATE 19200 + +// +// Temperature Sensors +// +#define TEMP_0_PIN PA0 // TH0 +#define TEMP_BED_PIN PC3 // THB + +// +// Heaters / Fans +// +#define HEATER_0_PIN PC8 // HEATER0 +#define HEATER_BED_PIN PC9 // HOT BED + +#define FAN_PIN PA7 // FAN (fan2 on board) model cool fan +#define FAN1_PIN PA8 // FAN (fan0 on board) e0 cool fan +#define FAN2_PIN PB9 // FAN (fan1 on board) controller cool fan + +// One NeoPixel onboard and a connector for other NeoPixels +#define NEOPIXEL_PIN PC7 // The NEOPIXEL LED driving pin + +/** + * 1 _____ 2 + * PB5 | · · | PB6 + * PA2 | · · | RESET + * PA3 | · · | PB8 + * PB7 | · · | PA4 + * GND | · · | VCC5 + * 9 ----- 10 + * LCD EXP + */ + +// +// LCD / Controller +// +#if ENABLED(CR10_STOCKDISPLAY) + #define BEEPER_PIN PB5 + #define BTN_EN1 PA2 + #define BTN_EN2 PA3 + #define BTN_ENC PB6 + + #define LCD_PINS_RS PB7 // CS -- SOFT SPI for ENDER3 LCD + #define LCD_PINS_D4 PB8 // SCLK + #define LCD_PINS_ENABLE PA4 // DATA MOSI +#endif + +// Alter timing for graphical display +#if HAS_MARLINUI_U8GLIB + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(125) + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(125) + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(125) + #endif +#endif + +// +// Camera +// +#define CHDK_PIN PB15 + +#if 0 + +// +// SD-NAND +// +#if SD_CONNECTION_IS(ONBOARD) + #define ENABLE_SPI1 + #define SD_DETECT_PIN -1 + #define SCK_PIN PA5 + #define MISO_PIN PA6 + #define MOSI_PIN PA7 + #define SS_PIN PA4 +#endif + +#define ONBOARD_SPI_DEVICE 1 // SPI1 +#define ONBOARD_SD_CS_PIN PA4 // Chip select for SD-NAND + +#endif diff --git a/Marlin/src/pins/stm32f1/pins_CHITU3D.h b/Marlin/src/pins/stm32f1/pins_CHITU3D.h new file mode 100644 index 000000000000..3a872db0253e --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_CHITU3D.h @@ -0,0 +1,284 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(__STM32F1__, __STM32F4__) + #error "Oops! Select an STM32F1/4 board in 'Tools > Board.'" +#endif + +/** + * 2017 Victor Perez Marlin for stm32f1 test + */ + +#define BOARD_INFO_NAME "Chitu3D" +#define DEFAULT_MACHINE_NAME "STM32F103RET6" + +// Enable I2C_EEPROM for testing +//#define I2C_EEPROM + +// Ignore temp readings during development. +//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 + +// +// Steppers +// +#define X_STEP_PIN PE5 +#define X_DIR_PIN PE6 +#define X_ENABLE_PIN PC13 +#define X_MIN_PIN PG10 +#define X_MAX_PIN -1 + +#define Y_STEP_PIN PE2 +#define Y_DIR_PIN PE3 +#define Y_ENABLE_PIN PE4 +#define Y_MIN_PIN PA12 +#define Y_MAX_PIN + +#define Z_STEP_PIN PB9 +#define Z_DIR_PIN PE0 +#define Z_ENABLE_PIN PE1 +#define Z_MIN_PIN PA14 +#define Z_MAX_PIN -1 + +#define Y2_STEP_PIN -1 +#define Y2_DIR_PIN -1 +#define Y2_ENABLE_PIN -1 + +#define Z2_STEP_PIN -1 +#define Z2_DIR_PIN -1 +#define Z2_ENABLE_PIN -1 + +#define E0_STEP_PIN PB4 +#define E0_DIR_PIN PB5 +#define E0_ENABLE_PIN PB8 + +#define E1_STEP_PIN -1 +#define E1_DIR_PIN -1 +#define E1_ENABLE_PIN -1 + +#define E2_STEP_PIN -1 +#define E2_DIR_PIN -1 +#define E2_ENABLE_PIN -1 + +// +// Misc. Functions +// +#define SDSS -1 +#define LED_PIN -1 + +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN PA8 // 8 +#endif + +#define PS_ON_PIN -1 +#define KILL_PIN PD6 // LED strip 24v + +// +// Heaters / Fans +// +#define HEATER_0_PIN PD12 // HOT-END +#define HEATER_1_PIN -1 +#define HEATER_2_PIN -1 + +#define HEATER_BED_PIN PG11 // HOT-BED +#define HEATER_BED2_PIN -1 // BED2 +#define HEATER_BED3_PIN -1 // BED3 + +#ifndef FAN_PIN + #define FAN_PIN PG14 // MAIN BOARD FAN +#endif + +#define FAN_SOFT_PWM + +// +// Temperature Sensors +// +#define TEMP_BED_PIN PA0 // Analog Input +#define TEMP_0_PIN PA1 // Analog Input +#define TEMP_1_PIN -1 // Analog Input +#define TEMP_2_PIN -1 // Analog Input + +// +// LCD Pins +// +#if HAS_WIRED_LCD + + #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) + #define LCD_PINS_RS PD1 // 49 // CS chip select /SS chip slave select + #define LCD_PINS_ENABLE PD3 // 51 // SID (MOSI) + #define LCD_PINS_D4 PD4 // 52 // SCK (CLK) clock + #elif BOTH(NEWPANEL, PANEL_ONE) + #define LCD_PINS_RS PB8 + #define LCD_PINS_ENABLE PD2 + #define LCD_PINS_D4 PB12 + #define LCD_PINS_D5 PB13 + #define LCD_PINS_D6 PB14 + #define LCD_PINS_D7 PB15 + #else + #define LCD_PINS_RS PB8 + #define LCD_PINS_ENABLE PD2 + #define LCD_PINS_D4 PB12 + #define LCD_PINS_D5 PB13 + #define LCD_PINS_D6 PB14 + #define LCD_PINS_D7 PB15 + #if DISABLED(NEWPANEL) + #define BEEPER_PIN PC1 // 33 + // Buttons attached to a shift register + // Not wired yet + //#define SHIFT_CLK PC6 // 38 + //#define SHIFT_LD PC10 // 42 + //#define SHIFT_OUT PC8 // 40 + //#define SHIFT_EN PA1 // 17 + #endif + #endif + + #if ENABLED(NEWPANEL) + + #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) + + #define BEEPER_PIN PC5 + + #define BTN_EN1 PB15 // 31 + #define BTN_EN2 PC1 // 33 + #define BTN_ENC PC3 // 35 + + #define SD_DETECT_PIN PD1 // 49 + #define KILL_PIN PC9 // 41 + + #if ENABLED(BQ_LCD_SMART_CONTROLLER) + #define LCD_BACKLIGHT_PIN PC7 // 39 + #endif + + #elif ENABLED(REPRAPWORLD_GRAPHICAL_LCD) + + #define BTN_EN1 PE0 // 64 + #define BTN_EN2 PD11 // 59 + #define BTN_ENC PD15 // 63 + #define SD_DETECT_PIN PC10 // 42 + + #elif ENABLED(LCD_I2C_PANELOLU2) + + #define BTN_EN1 PC15 // 47 + #define BTN_EN2 PC11 // 43 + #define BTN_ENC PC0 // 32 + #define LCD_SDSS PD5 // 53 + #define SD_DETECT_PIN -1 + #define KILL_PIN PC9 // 41 + + #elif ENABLED(LCD_I2C_VIKI) + + #define BTN_EN1 PB6 // 22 // https://files.panucatt.com/datasheets/viki_wiring_diagram.pdf explains 40/42. + #define BTN_EN2 PA7 // 7 // 22/7 are unused on RAMPS_14. 22 is unused and 7 the SERVO0_PIN on RAMPS_13. + + #define BTN_ENC -1 + #define LCD_SDSS PD5 // 53 + #define SD_DETECT_PIN PD1 // 49 + + #elif ANY(VIKI2, miniVIKI) + + #define BEEPER_PIN PC1 // 33 + + // Pins for DOGM SPI LCD Support + #define DOGLCD_A0 PC12 // 44 + #define DOGLCD_CS PC13 // 45 + #define LCD_SCREEN_ROT_180 + + #define BTN_EN1 PB6 // 22 + #define BTN_EN2 PA7 // 7 + #define BTN_ENC PC7 // 39 + + #define SDSS PD5 // 53 + #define SD_DETECT_PIN -1 // Pin 49 for display sd interface, 72 for easy adapter board + + #define KILL_PIN PB15 // 31 + + #define STAT_LED_RED_PIN PC0 // 32 + #define STAT_LED_BLUE_PIN PC3 // 35 + + #elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) + #define BTN_EN1 PC3 // 35 + #define BTN_EN2 PC5 // 37 + #define BTN_ENC PB15 // 31 + #define SD_DETECT_PIN PD1 // 49 + #define LCD_SDSS PD5 // 53 + #define KILL_PIN PC9 // 41 + #define BEEPER_PIN PB7 // 23 + #define DOGLCD_CS PB13 // 29 + #define DOGLCD_A0 PB11 // 27 + #define LCD_BACKLIGHT_PIN PC1 // 33 + + #elif ENABLED(MINIPANEL) + + #define BEEPER_PIN PC10 // 42 + // Pins for DOGM SPI LCD Support + #define DOGLCD_A0 PC12 // 44 + #define DOGLCD_CS PE2 // 66 + #define LCD_BACKLIGHT_PIN PE1 // 65 // backlight LED on A11/D65 + #define SDSS PD5 // 53 + + #define KILL_PIN PE0 // 64 + // GLCD features + // Uncomment screen orientation + //#define LCD_SCREEN_ROT_90 + //#define LCD_SCREEN_ROT_180 + //#define LCD_SCREEN_ROT_270 + // The encoder and click button + #define BTN_EN1 PC8 // 40 + #define BTN_EN2 PD15 // 63 + #define BTN_ENC PD11 // 59 + // not connected to a pin + #define SD_DETECT_PIN PD1 // 49 + + #else + + // Beeper on AUX-4 + #define BEEPER_PIN PC1 // 33 + + // Buttons directly attached to AUX-2 + #if ENABLED(REPRAPWORLD_KEYPAD) + #define BTN_EN1 PE0 // 64 + #define BTN_EN2 PD11 // 59 + #define BTN_ENC PD15 // 63 + #define SHIFT_OUT PC8 // 40 + #define SHIFT_CLK PC12 // 44 + #define SHIFT_LD PC10 // 42 + #elif ENABLED(PANEL_ONE) + #define BTN_EN1 PD11 // 59 // AUX2 PIN 3 + #define BTN_EN2 PD15 // 63 // AUX2 PIN 4 + #define BTN_ENC PD1 // 49 // AUX3 PIN 7 + #else + #define BTN_EN1 PC5 // 37 + #define BTN_EN2 PC3 // 35 + #define BTN_ENC PB15 // 31 + #endif + + #if ENABLED(G3D_PANEL) + #define SD_DETECT_PIN PD1 // 49 + #define KILL_PIN PC9 // 41 + #else + //#define SD_DETECT_PIN -1 // Ramps doesn't use this + #endif + + #endif + #endif // NEWPANEL + +#endif // HAS_WIRED_LCD diff --git a/Marlin/src/pins/stm32f1/pins_CHITU3D_V5.h b/Marlin/src/pins/stm32f1/pins_CHITU3D_V5.h new file mode 100644 index 000000000000..b02d414089ff --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_CHITU3D_V5.h @@ -0,0 +1,203 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(__STM32F1__, __STM32F4__) + #error "Oops! Select an STM32F1/4 board in 'Tools > Board.'" +#endif + +/** + * 2017 Victor Perez Marlin for stm32f1 test + */ + +#define BOARD_INFO_NAME "Chitu3D V5" +#define DEFAULT_MACHINE_NAME "STM32F103ZET6" + +#define DISABLE_JTAG + +// +// EEPROM +// +#define FLASH_EEPROM_EMULATION +#if ENABLED(FLASH_EEPROM_EMULATION) + // SoC Flash (framework-arduinoststm32-maple/STM32F1/libraries/EEPROM/EEPROM.h) + #define EEPROM_START_ADDRESS (0x8000000UL + (512 * 1024) - 2 * EEPROM_PAGE_SIZE) + #define EEPROM_PAGE_SIZE (0x800U) // 2KB, but will use 2x more (4KB) + #define MARLIN_EEPROM_SIZE EEPROM_PAGE_SIZE +#else + #define MARLIN_EEPROM_SIZE 0x800U // On SD, Limit to 2KB, require this amount of RAM +#endif + +// +// Limit Switches +// +#define X_STOP_PIN PG10 +#define Y_STOP_PIN PA12 +#define Z_STOP_PIN PA14 + +// +// Steppers +// +#define X_ENABLE_PIN PC13 +#define X_STEP_PIN PE5 +#define X_DIR_PIN PE6 + +#define Y_ENABLE_PIN PE4 +#define Y_STEP_PIN PE2 +#define Y_DIR_PIN PE3 + +#define Z_ENABLE_PIN PE1 +#define Z_STEP_PIN PB9 +#define Z_DIR_PIN PE0 + +#define E0_ENABLE_PIN PB8 +#define E0_STEP_PIN PB4 +#define E0_DIR_PIN PB5 + +#define E1_ENABLE_PIN PG8 +#define E1_STEP_PIN PC7 +#define E1_DIR_PIN PC6 + +// +// Temperature Sensors +// +#define TEMP_0_PIN PA1 // TH1 +#define TEMP_BED_PIN PA0 // TB1 + +// +// Heaters +// +#define HEATER_0_PIN PG12 // HEATER1 +#define HEATER_BED_PIN PG11 // HOT BED + +// +// Fans +// +#define CONTROLLER_FAN_PIN PD6 // BOARD FAN +#define FAN_PIN PG13 // FAN +#define FAN_PIN_2 PG14 + +// +// Misc +// +#define BEEPER_PIN PB0 +//#define LED_PIN -1 +//#define POWER_LOSS_PIN -1 +#define FIL_RUNOUT_PIN PA15 + +// SPI Flash +#define HAS_SPI_FLASH 1 +#if HAS_SPI_FLASH + #define SPI_FLASH_SIZE 0x200000 // 2MB +#endif + +// SPI 2 +#define W25QXX_CS_PIN PB12 +#define W25QXX_MOSI_PIN PB15 +#define W25QXX_MISO_PIN PB14 +#define W25QXX_SCK_PIN PB13 + +// +// TronXY TFT Support +// + +#if HAS_FSMC_TFT + + // Shared FSMC + + #define TOUCH_CS_PIN PB7 // SPI1_NSS + #define TOUCH_SCK_PIN PA5 // SPI1_SCK + #define TOUCH_MISO_PIN PA6 // SPI1_MISO + #define TOUCH_MOSI_PIN PA7 // SPI1_MOSI + + #define TFT_RESET_PIN PF11 + #define TFT_BACKLIGHT_PIN PD13 + + #define LCD_USE_DMA_FSMC // Use DMA transfers to send data to the TFT + #define FSMC_CS_PIN PD7 + #define FSMC_RS_PIN PD11 + #define FSMC_DMA_DEV DMA2 + #define FSMC_DMA_CHANNEL DMA_CH5 + +#endif + +#if ENABLED(TFT_LVGL_UI) + // LVGL + #define HAS_SPI_FLASH_FONT 1 + #define HAS_GCODE_PREVIEW 1 + #define HAS_GCODE_DEFAULT_VIEW_IN_FLASH 0 + #define HAS_LANG_SELECT_SCREEN 1 + #define HAS_BAK_VIEW_IN_FLASH 0 + #define HAS_LOGO_IN_FLASH 0 +#elif ENABLED(TFT_COLOR_UI) + // Color UI + #define TFT_DRIVER ILI9488 + #define TFT_BUFFER_SIZE 14400 +#elif ENABLED(TFT_CLASSIC_UI) + // Emulated DOGM + #define GRAPHICAL_TFT_UPSCALE 3 +#endif + +// XPT2046 Touch Screen calibration +#if EITHER(TFT_LVGL_UI, TFT_COLOR_UI) + #ifndef XPT2046_X_CALIBRATION + #define XPT2046_X_CALIBRATION -17181 + #endif + #ifndef XPT2046_Y_CALIBRATION + #define XPT2046_Y_CALIBRATION 11434 + #endif + #ifndef XPT2046_X_OFFSET + #define XPT2046_X_OFFSET 501 + #endif + #ifndef XPT2046_Y_OFFSET + #define XPT2046_Y_OFFSET -9 + #endif +#elif ENABLED(TFT_CLASSIC_UI) + #ifndef XPT2046_X_CALIBRATION + #define XPT2046_X_CALIBRATION -12316 + #endif + #ifndef XPT2046_Y_CALIBRATION + #define XPT2046_Y_CALIBRATION 8981 + #endif + #ifndef XPT2046_X_OFFSET + #define XPT2046_X_OFFSET 340 + #endif + #ifndef XPT2046_Y_OFFSET + #define XPT2046_Y_OFFSET -20 + #endif +#endif + +// SPI1(PA7)=LCD & SPI3(PB5)=STUFF, are not available +// Needs to use SPI2 +#define ENABLE_SPI2 +#define SCK_PIN PB13 +#define MISO_PIN PB14 +#define MOSI_PIN PB15 +#define SS_PIN PB12 + +// +// SD Card +// +#define SDIO_SUPPORT +#define SD_DETECT_PIN -1 // PF0, but it isn't connected +#define SDIO_CLOCK 4500000 +#define SDIO_READ_RETRIES 16 diff --git a/Marlin/src/pins/stm32f1/pins_CHITU3D_V6.h b/Marlin/src/pins/stm32f1/pins_CHITU3D_V6.h new file mode 100644 index 000000000000..cafd50dcf22c --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_CHITU3D_V6.h @@ -0,0 +1,218 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(__STM32F1__, __STM32F4__) + #error "Oops! Select an STM32F1/4 board in 'Tools > Board.'" +#endif + +/** + * 2017 Victor Perez Marlin for stm32f1 test + */ + +#define BOARD_INFO_NAME "Chitu3D" +#define DEFAULT_MACHINE_NAME "STM32F103ZET6" + +#define DISABLE_JTAG + +// +// EEPROM +// + +#if NO_EEPROM_SELECTED + #define FLASH_EEPROM_EMULATION +#endif + +#if ENABLED(FLASH_EEPROM_EMULATION) + // SoC Flash (framework-arduinoststm32-maple/STM32F1/libraries/EEPROM/EEPROM.h) + #define EEPROM_START_ADDRESS (0x8000000UL + (512 * 1024) - 2 * EEPROM_PAGE_SIZE) + #define EEPROM_PAGE_SIZE (0x800U) // 2KB, but will use 2x more (4KB) + #define MARLIN_EEPROM_SIZE EEPROM_PAGE_SIZE +#else + #define MARLIN_EEPROM_SIZE 0x800U // On SD, Limit to 2KB, require this amount of RAM +#endif + +// +// Limit Switches +// +#define X_STOP_PIN PG10 +#define Y_STOP_PIN PA12 +#define Z_STOP_PIN PG9 + +// +// Steppers +// +#define X_ENABLE_PIN PC13 +#define X_STEP_PIN PE5 +#define X_DIR_PIN PE6 + +#define Y_ENABLE_PIN PE4 +#define Y_STEP_PIN PE2 +#define Y_DIR_PIN PE3 + +#define Z_ENABLE_PIN PE1 +#define Z_STEP_PIN PB9 +#define Z_DIR_PIN PE0 + +#define Z2_ENABLE_PIN PF3 +#define Z2_STEP_PIN PF5 +#define Z2_DIR_PIN PF1 + +#define E0_ENABLE_PIN PB8 +#define E0_STEP_PIN PB4 +#define E0_DIR_PIN PB5 + +#define E1_ENABLE_PIN PG8 +#define E1_STEP_PIN PC7 +#define E1_DIR_PIN PC6 + +// +// Temperature Sensors +// +#define TEMP_0_PIN PA1 // TH1 +#define TEMP_BED_PIN PA0 // TB1 + +// +// Heaters +// +#define HEATER_0_PIN PG12 // HEATER1 +#define HEATER_BED_PIN PG11 // HOT BED +//#define HEATER_BED_INVERTING true + +// +// Fans +// +#define CONTROLLER_FAN_PIN PD6 // BOARD FAN +#define FAN_PIN PG13 // FAN +#define FAN_PIN_2 PG14 + +// +// Misc +// +#define BEEPER_PIN PB0 +//#define LED_PIN PD3 +//#define POWER_LOSS_PIN PG2 // PG4 PW_DET + +#ifndef FIL_RUNOUT_PIN + #define FIL_RUNOUT_PIN PA15 // MT_DET +#endif +#ifndef FIL_RUNOUT2_PIN + #define FIL_RUNOUT2_PIN PF13 +#endif + +// SPI Flash +#define HAS_SPI_FLASH 1 +#if HAS_SPI_FLASH + #define SPI_FLASH_SIZE 0x200000 // 2MB +#endif + +// SPI 2 +#define W25QXX_CS_PIN PB12 +#define W25QXX_MOSI_PIN PB15 +#define W25QXX_MISO_PIN PB14 +#define W25QXX_SCK_PIN PB13 + +// +// TronXY TFT Support +// + +#if HAS_FSMC_TFT + + // Shared FSMC + + #define TOUCH_CS_PIN PB7 // SPI1_NSS + #define TOUCH_SCK_PIN PA5 // SPI1_SCK + #define TOUCH_MISO_PIN PA6 // SPI1_MISO + #define TOUCH_MOSI_PIN PA7 // SPI1_MOSI + + #define TFT_RESET_PIN PF11 + #define TFT_BACKLIGHT_PIN PD13 + + #define LCD_USE_DMA_FSMC // Use DMA transfers to send data to the TFT + #define FSMC_CS_PIN PD7 + #define FSMC_RS_PIN PD11 + #define FSMC_DMA_DEV DMA2 + #define FSMC_DMA_CHANNEL DMA_CH5 + +#endif + +#if ENABLED(TFT_LVGL_UI) + // LVGL + #define HAS_SPI_FLASH_FONT 1 + #define HAS_GCODE_PREVIEW 1 + #define HAS_GCODE_DEFAULT_VIEW_IN_FLASH 0 + #define HAS_LANG_SELECT_SCREEN 1 + #define HAS_BAK_VIEW_IN_FLASH 0 + #define HAS_LOGO_IN_FLASH 0 +#elif ENABLED(TFT_COLOR_UI) + // Color UI + #define TFT_DRIVER ILI9488 + #define TFT_BUFFER_SIZE 14400 +#elif ENABLED(TFT_CLASSIC_UI) + // Emulated DOGM + #define GRAPHICAL_TFT_UPSCALE 3 +#endif + +// XPT2046 Touch Screen calibration +#if EITHER(TFT_LVGL_UI, TFT_COLOR_UI) + #ifndef XPT2046_X_CALIBRATION + #define XPT2046_X_CALIBRATION -17181 + #endif + #ifndef XPT2046_Y_CALIBRATION + #define XPT2046_Y_CALIBRATION 11434 + #endif + #ifndef XPT2046_X_OFFSET + #define XPT2046_X_OFFSET 501 + #endif + #ifndef XPT2046_Y_OFFSET + #define XPT2046_Y_OFFSET -9 + #endif +#elif ENABLED(TFT_CLASSIC_UI) + #ifndef XPT2046_X_CALIBRATION + #define XPT2046_X_CALIBRATION -12316 + #endif + #ifndef XPT2046_Y_CALIBRATION + #define XPT2046_Y_CALIBRATION 8981 + #endif + #ifndef XPT2046_X_OFFSET + #define XPT2046_X_OFFSET 340 + #endif + #ifndef XPT2046_Y_OFFSET + #define XPT2046_Y_OFFSET -20 + #endif +#endif + +// SPI1(PA7)=LCD & SPI3(PB5)=STUFF, are not available +// so SPI2 is required. +#define ENABLE_SPI2 +#define SCK_PIN PB13 +#define MISO_PIN PB14 +#define MOSI_PIN PB15 +#define SS_PIN PB12 + +// +// SD Card +// +#define SDIO_SUPPORT +#define SD_DETECT_PIN -1 // PF0, but it isn't connected +#define SDIO_CLOCK 4500000 +#define SDIO_READ_RETRIES 16 diff --git a/Marlin/src/pins/stm32f1/pins_CREALITY_V4.h b/Marlin/src/pins/stm32f1/pins_CREALITY_V4.h new file mode 100644 index 000000000000..eb910dd8466e --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_CREALITY_V4.h @@ -0,0 +1,208 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * CREALITY (STM32F103) board pin assignments + */ + +#if NOT_TARGET(__STM32F1__) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#endif + +#if HOTENDS > 1 || E_STEPPERS > 1 + #error "CREALITY supports up to 1 hotends / E-steppers. Comment out this line to continue." +#endif + +#ifndef BOARD_INFO_NAME + #define BOARD_INFO_NAME "Creality V4" +#endif +#ifndef DEFAULT_MACHINE_NAME + #define DEFAULT_MACHINE_NAME "Ender 3 V2" +#endif + +// +// EEPROM +// +#if NO_EEPROM_SELECTED + // FLASH + //#define FLASH_EEPROM_EMULATION + + // I2C + #define IIC_BL24CXX_EEPROM // EEPROM on I2C-0 used only for display settings + #if ENABLED(IIC_BL24CXX_EEPROM) + #define IIC_EEPROM_SDA PA11 + #define IIC_EEPROM_SCL PA12 + #define MARLIN_EEPROM_SIZE 0x800 // 2Kb (24C16) + #else + #define SDCARD_EEPROM_EMULATION // SD EEPROM until all EEPROM is BL24CXX + #define MARLIN_EEPROM_SIZE 0x800 // 2Kb + #endif + + // SPI + //#define SPI_EEPROM // EEPROM on SPI-0 + //#define SPI_CHAN_EEPROM1 ? + //#define SPI_EEPROM1_CS ? + + // 2K EEPROM + //#define SPI_EEPROM2_CS ? + + // 32Mb FLASH + //#define SPI_FLASH_CS ? +#endif + +// +// Servos +// +#define SERVO0_PIN PB0 // BLTouch OUT + +// +// Limit Switches +// +#define X_STOP_PIN PA5 +#define Y_STOP_PIN PA6 +#define Z_STOP_PIN PA7 + +#define Z_MIN_PROBE_PIN PB1 // BLTouch IN + +// +// Filament Runout Sensor +// +#ifndef FIL_RUNOUT_PIN + #define FIL_RUNOUT_PIN PA4 // "Pulled-high" +#endif + +// +// Steppers +// +#define X_ENABLE_PIN PC3 +#ifndef X_STEP_PIN + #define X_STEP_PIN PC2 +#endif +#ifndef X_DIR_PIN + #define X_DIR_PIN PB9 +#endif + +#define Y_ENABLE_PIN PC3 +#ifndef Y_STEP_PIN + #define Y_STEP_PIN PB8 +#endif +#ifndef Y_DIR_PIN + #define Y_DIR_PIN PB7 +#endif + +#define Z_ENABLE_PIN PC3 +#ifndef Z_STEP_PIN + #define Z_STEP_PIN PB6 +#endif +#ifndef Z_DIR_PIN + #define Z_DIR_PIN PB5 +#endif + +#define E0_ENABLE_PIN PC3 +#ifndef E0_STEP_PIN + #define E0_STEP_PIN PB4 +#endif +#ifndef E0_DIR_PIN + #define E0_DIR_PIN PB3 +#endif + +// +// Release PB4 (Y_ENABLE_PIN) from JTAG NRST role +// +#define DISABLE_DEBUG + +// +// Temperature Sensors +// +#define TEMP_0_PIN PC5 // TH1 +#define TEMP_BED_PIN PC4 // TB1 + +// +// Heaters / Fans +// +#define HEATER_0_PIN PA1 // HEATER1 +#define HEATER_BED_PIN PA2 // HOT BED + +#define FAN_PIN PA0 // FAN +#define FAN_SOFT_PWM + +// +// SD Card +// +#define SD_DETECT_PIN PC7 +#define SDCARD_CONNECTION ONBOARD +#define ONBOARD_SPI_DEVICE 1 +#define ONBOARD_SD_CS_PIN PA4 // SDSS +#define SDIO_SUPPORT +#define NO_SD_HOST_DRIVE // This board's SD is only seen by the printer + +#if ENABLED(CR10_STOCKDISPLAY) && NONE(RET6_12864_LCD, VET6_12864_LCD) + #error "Define RET6_12864_LCD or VET6_12864_LCD to select pins for CR10_STOCKDISPLAY with the Creality V4 controller." +#endif + +#if ENABLED(RET6_12864_LCD) + + // RET6 12864 LCD + #define LCD_PINS_RS PB12 + #define LCD_PINS_ENABLE PB15 + #define LCD_PINS_D4 PB13 + + #define BTN_ENC PB2 + #define BTN_EN1 PB10 + #define BTN_EN2 PB14 + + #define BEEPER_PIN PC6 + +#elif ENABLED(VET6_12864_LCD) + + // VET6 12864 LCD + #define LCD_PINS_RS PA4 + #define LCD_PINS_ENABLE PA7 + #define LCD_PINS_D4 PA5 + + #define BTN_ENC PC5 + #define BTN_EN1 PB10 + #define BTN_EN2 PA6 + +#elif ENABLED(DWIN_CREALITY_LCD) + + // RET6 DWIN ENCODER LCD + #define BTN_ENC PB14 + #define BTN_EN1 PB15 + #define BTN_EN2 PB12 + + //#define LCD_LED_PIN PB2 + #ifndef BEEPER_PIN + #define BEEPER_PIN PB13 + #undef SPEAKER + #endif + +#elif ENABLED(DWIN_VET6_CREALITY_LCD) + + // VET6 DWIN ENCODER LCD + #define BTN_ENC PA6 + #define BTN_EN1 PA7 + #define BTN_EN2 PA4 + + #define BEEPER_PIN PA5 + +#endif diff --git a/Marlin/src/pins/stm32f1/pins_CREALITY_V427.h b/Marlin/src/pins/stm32f1/pins_CREALITY_V427.h new file mode 100644 index 000000000000..5b51ece07f08 --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_CREALITY_V427.h @@ -0,0 +1,48 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * CREALITY v4.2.7 (STM32F103) board pin assignments + */ + +#if NOT_TARGET(__STM32F1__) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#endif + +#define BOARD_INFO_NAME "Creality v4.2.7" +#define DEFAULT_MACHINE_NAME "Creality3D" + +// +// Steppers +// +#define X_STEP_PIN PB9 +#define X_DIR_PIN PC2 +#define Y_STEP_PIN PB7 + +#define Y_DIR_PIN PB8 +#define Z_STEP_PIN PB5 +#define Z_DIR_PIN PB6 + +#define E0_STEP_PIN PB3 +#define E0_DIR_PIN PB4 + +#include "pins_CREALITY_V4.h" diff --git a/Marlin/src/pins/stm32f1/pins_FLY_MINI.h b/Marlin/src/pins/stm32f1/pins_FLY_MINI.h new file mode 100644 index 000000000000..55a809efab91 --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_FLY_MINI.h @@ -0,0 +1,172 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifndef __STM32F1__ + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#endif + +#define BOARD_INFO_NAME "FLY_MINI" +#define BOARD_WEBSITE_URL "github.com/FLYmaker" +#define DISABLE_JTAG + +// +// Flash EEPROM Emulation +// +#define FLASH_EEPROM_EMULATION +#define EEPROM_PAGE_SIZE 0x800 // 2KB +#define EEPROM_START_ADDRESS (0x8000000 + 256 * 1024 - 2 * EEPROM_PAGE_SIZE) // 256K firmware space +#define MARLIN_EEPROM_SIZE EEPROM_PAGE_SIZE + +// +// Servos +// +#define SERVO0_PIN PA8 + +// +// Limit Switches +// +#define X_MIN_PIN PC12 +#define X_MAX_PIN PC11 +#define Y_MIN_PIN PC10 +#define Y_MAX_PIN PA15 +#define Z_MIN_PIN PA14 +#define Z_MAX_PIN PA13 + +// +// Steppers +// +#define X_STEP_PIN PB1 +#define X_DIR_PIN PB2 +#define X_ENABLE_PIN PB10 +#ifndef X_CS_PIN + #define X_CS_PIN PB0 +#endif + +#define Y_STEP_PIN PA2 +#define Y_DIR_PIN PC4 +#define Y_ENABLE_PIN PC5 +#ifndef Y_CS_PIN + #define Y_CS_PIN PA7 +#endif + +#define Z_STEP_PIN PA3 +#define Z_DIR_PIN PA5 +#define Z_ENABLE_PIN PA6 +#ifndef Z_CS_PIN + #define Z_CS_PIN PA4 +#endif + +#define E0_STEP_PIN PA1 +#define E0_DIR_PIN PC3 +#define E0_ENABLE_PIN PA0 +#ifndef E0_CS_PIN + #define E0_CS_PIN PC2 +#endif + +#if ENABLED(TMC_USE_SW_SPI) + #ifndef TMC_SW_MOSI + #define TMC_SW_MOSI PB15 + #endif + #ifndef TMC_SW_MISO + #define TMC_SW_MISO PB14 + #endif + #ifndef TMC_SW_SCK + #define TMC_SW_SCK PB13 + #endif +#endif + +#if HAS_TMC_UART + // + // Software serial + // + #define X_SERIAL_TX_PIN PB0 + #define X_SERIAL_RX_PIN PB0 + #define Y_SERIAL_TX_PIN PA7 + #define Y_SERIAL_RX_PIN PA7 + #define Z_SERIAL_TX_PIN PA4 + #define Z_SERIAL_RX_PIN PA4 + #define E0_SERIAL_TX_PIN PC2 + #define E0_SERIAL_RX_PIN PC2 +#endif + +// +// Heaters / Fans +// +#define HEATER_0_PIN PC6 +#define HEATER_BED_PIN PC7 +#ifndef FAN_PIN + #define FAN_PIN PC8 +#endif +#define FAN1_PIN PC9 + +// +// Temperature Sensors +// +#define TEMP_BED_PIN PC0 // Analog Input +#define TEMP_0_PIN PC1 // Analog Input + +// +// LCD Pins +// + +// +// LCD / Controller +// +#define ENABLE_SPI2 +#define SS_PIN PB12 +#define SCK_PIN PB13 +#define MISO_PIN PB14 +#define MOSI_PIN PB15 + +#define SDSS SS_PIN +#define SD_DETECT_PIN PB11 + +#define BEEPER_PIN PC14 + +#define LCD_PINS_RS PB8 +#define LCD_PINS_ENABLE PB9 +#define LCD_PINS_D4 PB7 +#define LCD_PINS_D5 PB6 +#define LCD_PINS_D6 PB5 +#define LCD_PINS_D7 PB4 + +#define BTN_EN1 PD2 +#define BTN_EN2 PB3 +#define BTN_ENC PC13 + +// +// Filament runout +// + +// +// ST7920 Delays +// +#ifndef ST7920_DELAY_1 + #define ST7920_DELAY_1 DELAY_NS(96) +#endif +#ifndef ST7920_DELAY_2 + #define ST7920_DELAY_2 DELAY_NS(48) +#endif +#ifndef ST7920_DELAY_3 + #define ST7920_DELAY_3 DELAY_NS(715) +#endif diff --git a/Marlin/src/pins/stm32f1/pins_FYSETC_AIO_II.h b/Marlin/src/pins/stm32f1/pins_FYSETC_AIO_II.h new file mode 100644 index 000000000000..ebe5964d0588 --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_FYSETC_AIO_II.h @@ -0,0 +1,196 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(__STM32F1__) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#endif + +#define BOARD_INFO_NAME "FYSETC AIO II" +#define BOARD_WEBSITE_URL "fysetc.com" + +#define DISABLE_JTAG + +#define pins_v2_20190128 // new pins define + +// Ignore temp readings during development. +//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 + +// +// Flash EEPROM Emulation +// +#if EITHER(NO_EEPROM_SELECTED, FLASH_EEPROM_EMULATION) + #define FLASH_EEPROM_EMULATION + #define EEPROM_PAGE_SIZE (0x800U) // 2KB + #define EEPROM_START_ADDRESS (0x8000000UL + (STM32_FLASH_SIZE) * 1024UL - (EEPROM_PAGE_SIZE) * 2UL) + #define MARLIN_EEPROM_SIZE EEPROM_PAGE_SIZE // 2KB +#endif + +// +// Limit Switches +// +#define X_STOP_PIN PA1 +#define Y_STOP_PIN PA0 +#define Z_STOP_PIN PB14 + +// +// Filament runout +// +#ifdef pins_v2_20190128 + #define FIL_RUNOUT_PIN PB15 +#else + #define FIL_RUNOUT_PIN PB5 +#endif + +// +// Steppers +// +#define X_STEP_PIN PB8 +#define X_DIR_PIN PB9 +#define X_ENABLE_PIN PA8 + +#define Y_STEP_PIN PB2 +#ifdef pins_v2_20190128 + #define Y_DIR_PIN PB3 +#else + #define Y_DIR_PIN PB0 +#endif +#define Y_ENABLE_PIN PB1 + +#define Z_STEP_PIN PC0 +#define Z_DIR_PIN PC1 +#define Z_ENABLE_PIN PC2 + +#define E0_STEP_PIN PC15 +#define E0_DIR_PIN PC14 +#define E0_ENABLE_PIN PC13 + +#if HAS_TMC_UART + + /** + * TMC2208/TMC2209 stepper drivers + */ + + // + // Hardware serial with switch + // + #define X_HARDWARE_SERIAL MSerial1 + #define Y_HARDWARE_SERIAL MSerial1 + #define Z_HARDWARE_SERIAL MSerial1 + #define E0_HARDWARE_SERIAL MSerial1 + + // The 4xTMC2209 module doesn't have a serial multiplexer and + // needs to set *_SLAVE_ADDRESS in Configuration_adv.h for X,Y,Z,E0 + #if HAS_DRIVER(TMC2208) + #define TMC_SERIAL_MULTIPLEXER + #define SERIAL_MUL_PIN1 PB13 + #define SERIAL_MUL_PIN2 PB12 + #endif + +#endif + +// +// Stepper current PWM +// +#ifndef MOTOR_CURRENT_PWM_RANGE + #define MOTOR_CURRENT_PWM_RANGE 1500 // origin:2000 +#endif +#define DEFAULT_PWM_MOTOR_CURRENT { 500, 500, 400 } // origin: {1300,1300,1250} + +// +// Heaters / Fans +// +#define HEATER_0_PIN PC7 +#define HEATER_BED_PIN PC6 +#ifndef FAN_PIN + #define FAN_PIN PC8 +#endif + +// +// Temperature Sensors +// +#define TEMP_BED_PIN PC5 // Analog Input +#define TEMP_0_PIN PC4 // Analog Input + +// +// Misc. Functions +// +#define SDSS PA4 + +// +// LCD Pins +// +#if HAS_WIRED_LCD + + #define BEEPER_PIN PC9 + + #if HAS_MARLINUI_U8GLIB + + #define DOGLCD_A0 PA15 + #ifdef pins_v2_20190128 + #define DOGLCD_CS PB5 + #else + #define DOGLCD_CS PB7 + #endif + + //#define LCD_CONTRAST_INIT 190 + //#define LCD_SCREEN_ROT_90 + //#define LCD_SCREEN_ROT_180 + //#define LCD_SCREEN_ROT_270 + + #endif + + // not connected to a pin + #define SD_DETECT_PIN PC3 + + #if ENABLED(NEWPANEL) + // The encoder and click button + #define BTN_EN1 PC10 + #define BTN_EN2 PC11 + #define BTN_ENC PC12 + #endif + + #ifdef pins_v2_20190128 + #define LCD_RESET_PIN PB4 + #ifndef RGB_LED_R_PIN + #define RGB_LED_R_PIN PB0 + #endif + #ifndef RGB_LED_G_PIN + #define RGB_LED_G_PIN PB6 + #endif + #ifndef RGB_LED_B_PIN + #define RGB_LED_B_PIN PB7 + #endif + #else + #define LCD_RESET_PIN PB6 + #ifndef RGB_LED_R_PIN + #define RGB_LED_R_PIN PB3 + #endif + #ifndef RGB_LED_G_PIN + #define RGB_LED_G_PIN PB4 + #endif + #ifndef RGB_LED_B_PIN + #define RGB_LED_B_PIN PB5 + #endif + #endif + +#endif diff --git a/Marlin/src/pins/stm32f1/pins_FYSETC_CHEETAH.h b/Marlin/src/pins/stm32f1/pins_FYSETC_CHEETAH.h new file mode 100644 index 000000000000..de5ea45d44e8 --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_FYSETC_CHEETAH.h @@ -0,0 +1,177 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(__STM32F1__) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#endif + +#define DEFAULT_MACHINE_NAME "3D Printer" + +#define BOARD_INFO_NAME "FYSETC Cheetah" +#define BOARD_WEBSITE_URL "fysetc.com" +// https://github.com/FYSETC/Cheetah + +// Ignore temp readings during development. +//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 + +#define DISABLE_JTAG + +#if EITHER(NO_EEPROM_SELECTED, FLASH_EEPROM_EMULATION) + #define FLASH_EEPROM_EMULATION + #define EEPROM_PAGE_SIZE (0x800U) // 2KB + #define EEPROM_START_ADDRESS (0x8000000UL + (STM32_FLASH_SIZE) * 1024UL - (EEPROM_PAGE_SIZE) * 2UL) + #define MARLIN_EEPROM_SIZE EEPROM_PAGE_SIZE // 2KB +#endif + +// +// Servos +// +#define SERVO0_PIN PA0 + +// +// Limit Switches +// +#define X_STOP_PIN PA1 +#define Y_STOP_PIN PB4 +#define Z_STOP_PIN PA15 + +// +// Filament runout +// +#define FIL_RUNOUT_PIN PB5 + +// +// Steppers +// +#define X_STEP_PIN PB8 +#define X_DIR_PIN PB9 +#define X_ENABLE_PIN PA8 + +#define Y_STEP_PIN PB2 +#define Y_DIR_PIN PB3 +#define Y_ENABLE_PIN PB1 + +#define Z_STEP_PIN PC0 +#define Z_DIR_PIN PC1 +#define Z_ENABLE_PIN PC2 + +#define E0_STEP_PIN PC15 +#define E0_DIR_PIN PC14 +#define E0_ENABLE_PIN PC13 + +#define X_HARDWARE_SERIAL MSerial2 +#define Y_HARDWARE_SERIAL MSerial2 +#define Z_HARDWARE_SERIAL MSerial2 +#define E0_HARDWARE_SERIAL MSerial2 + +// +// Heaters / Fans +// +#define HEATER_0_PIN PC6 +#define HEATER_BED_PIN PC7 +#ifndef FAN_PIN + #define FAN_PIN PC8 +#endif + +// +// Temperature Sensors +// +#define TEMP_BED_PIN PC5 // Analog Input +#define TEMP_0_PIN PC4 // Analog Input + +// +// Misc. Functions +// +#define SDSS PA4 +#define SD_DETECT_PIN PC3 + +#ifndef RGB_LED_R_PIN + #define RGB_LED_R_PIN PB0 +#endif +#ifndef RGB_LED_G_PIN + #define RGB_LED_G_PIN PB7 +#endif +#ifndef RGB_LED_B_PIN + #define RGB_LED_B_PIN PB6 +#endif + +/* +* EXP1 pinout for the LCD according to Fysetcs schematic for the Cheetah board +* _____ +* (Beeper) PC9 | 1 2 | PC12 (BTN_ENC) +* (BTN_EN2) PC11 | 3 4 | PB14 (LCD_RS / MISO) +* (BTN_EN1) PC10 5 6 | PB13 (SCK) +* (LCD_EN) PB12 | 7 8 | PB15 (MOSI) +* GND | 9 10| 5V +* ----- +* EXP1 +* Note: The pin-numbers match the connector correctly and are not in reverse order like on the Ender-3 board. +* Note: Functionally the pins are assigned in the same order as on the Ender-3 board. +* Note: Pin 4 on the Cheetah board is assigned to an I/O, it is assigned to RESET on the Ender-3 board. +*/ + +#if HAS_WIRED_LCD + #define BEEPER_PIN PC9 + + #if HAS_MARLINUI_U8GLIB + #define DOGLCD_A0 PB14 + #define DOGLCD_CS PB12 + #define DOGLCD_SCK PB13 + #define DOGLCD_MOSI PB15 + //#define LCD_SCREEN_ROT_90 + //#define LCD_SCREEN_ROT_180 + //#define LCD_SCREEN_ROT_270 + + #if EITHER(FYSETC_MINI_12864, U8GLIB_ST7920) + #define FORCE_SOFT_SPI + #endif + #endif + + #define LCD_PINS_RS PB12 // CS -- SOFT SPI for ENDER3 LCD + #define LCD_PINS_D4 PB13 // SCLK + #define LCD_PINS_ENABLE PB15 // DATA MOSI + + //#define LCD_CONTRAST_INIT 190 + + #if ENABLED(NEWPANEL) + #define BTN_EN1 PC10 + #define BTN_EN2 PC11 + #define BTN_ENC PC12 + #endif +#endif + +#if ENABLED(TOUCH_UI_FTDI_EVE) + #define BEEPER_PIN PC9 + #define CLCD_MOD_RESET PC11 + #define CLCD_SPI_CS PB12 + + //#define CLCD_USE_SOFT_SPI // the Cheetah can use hardware-SPI so we do not really need this + + #if ENABLED(CLCD_USE_SOFT_SPI) + #define CLCD_SOFT_SPI_MOSI PB15 + #define CLCD_SOFT_SPI_MISO PB14 + #define CLCD_SOFT_SPI_SCLK PB13 + #else + #define CLCD_SPI_BUS 2 + #endif +#endif diff --git a/Marlin/src/pins/stm32/pins_FYSETC_CHEETAH_V12.h b/Marlin/src/pins/stm32f1/pins_FYSETC_CHEETAH_V12.h similarity index 69% rename from Marlin/src/pins/stm32/pins_FYSETC_CHEETAH_V12.h rename to Marlin/src/pins/stm32f1/pins_FYSETC_CHEETAH_V12.h index 5f7136c15654..5e8bd11b4bd0 100644 --- a/Marlin/src/pins/stm32/pins_FYSETC_CHEETAH_V12.h +++ b/Marlin/src/pins/stm32f1/pins_FYSETC_CHEETAH_V12.h @@ -16,12 +16,12 @@ * 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 . + * along with this program. If not, see . * */ #pragma once -#ifndef __STM32F1__ +#if NOT_TARGET(__STM32F1__) #error "Oops! Select an STM32F1 board in 'Tools > Board.'" #endif @@ -36,9 +36,9 @@ #undef RGB_LED_G_PIN #undef RGB_LED_B_PIN -#define FAN1_PIN PB0 // Fan1 +#define FAN1_PIN PB0 // Fan1 -#if HAS_TMC220x +#if HAS_TMC_UART /** * TMC2208/TMC2209 stepper drivers @@ -47,17 +47,17 @@ // // Software serial // - #define X_SERIAL_TX_PIN PA11 - #define X_SERIAL_RX_PIN PA12 + #define X_SERIAL_TX_PIN PA11 + #define X_SERIAL_RX_PIN PA12 - #define Y_SERIAL_TX_PIN PB6 - #define Y_SERIAL_RX_PIN PB7 + #define Y_SERIAL_TX_PIN PB6 + #define Y_SERIAL_RX_PIN PB7 - #define Z_SERIAL_TX_PIN PB10 - #define Z_SERIAL_RX_PIN PB11 + #define Z_SERIAL_TX_PIN PB10 + #define Z_SERIAL_RX_PIN PB11 - #define E0_SERIAL_TX_PIN PA2 - #define E0_SERIAL_RX_PIN PA3 + #define E0_SERIAL_TX_PIN PA2 + #define E0_SERIAL_RX_PIN PA3 // Reduce baud rate to improve software serial reliability #define TMC_BAUD_RATE 19200 diff --git a/Marlin/src/pins/stm32f1/pins_GTM32_MINI.h b/Marlin/src/pins/stm32f1/pins_GTM32_MINI.h new file mode 100644 index 000000000000..ca25c45a7bba --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_GTM32_MINI.h @@ -0,0 +1,241 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * 24 May 2018 - @chepo for STM32F103VET6 + * Schematic: https://github.com/chepo92/Smartto/blob/master/circuit_diagram/Rostock301/Hardware_GTM32_PRO_VB.pdf + */ + +#if NOT_TARGET(__STM32F1__) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#endif + +#define BOARD_INFO_NAME "GTM32 Pro VB" +#define DEFAULT_MACHINE_NAME "STM32F103VET6" + +//#define DISABLE_DEBUG + +// +// It is required to disable JTAG function because its pins are +// used as GPIO to drive the Y axis stepper. +// DO NOT ENABLE! +// +#define DISABLE_JTAG + +// +// If you don't need the SWDIO functionality (any more), you may +// disable SWD here to regain PA13/PA14 pins for other use. +// +//#define DISABLE_JTAGSWD + +// Ignore temp readings during development. +//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 + +// Enable EEPROM Emulation for this board as it doesn't have EEPROM +#if EITHER(NO_EEPROM_SELECTED, FLASH_EEPROM_EMULATION) + #define FLASH_EEPROM_EMULATION + #define MARLIN_EEPROM_SIZE 0x1000 // 4KB +#endif + +// +// Limit Switches +// +#define X_MIN_PIN PE5 // ENDSTOPS 15,17 +#define X_MAX_PIN PE4 // ENDSTOPS 16,18 +#define Y_MIN_PIN PE3 // ENDSTOPS 9,11 +#define Y_MAX_PIN PE2 // ENDSTOPS 10,12 +#define Z_MIN_PIN PE1 // ENDSTOPS 3,5 +#define Z_MAX_PIN PE0 // ENDSTOPS 4,6 + +// +// Steppers +// +#define X_STEP_PIN PC6 +#define X_DIR_PIN PD13 +#define X_ENABLE_PIN PA8 + +#define Y_STEP_PIN PA12 +#define Y_DIR_PIN PA11 +#define Y_ENABLE_PIN PA15 + +#define Z_STEP_PIN PD6 +#define Z_DIR_PIN PD3 +#define Z_ENABLE_PIN PB3 + +// Extruder stepper pins +// NOTE: Numbering here is made according to EXT connector numbers, +// the FANx_PWM line numbering in the schematics is reverse. +// That is, E0_*_PIN are the E2_* lines connected to E2_A1 step +// stick that drives the EXT0 output on the board. +// +#define E0_STEP_PIN PC14 +#define E0_DIR_PIN PC13 +#define E0_ENABLE_PIN PC15 + +#define E1_STEP_PIN PA0 +#define E1_DIR_PIN PB6 +#define E1_ENABLE_PIN PA1 + +#define E2_STEP_PIN PB2 +#define E2_DIR_PIN PB11 +#define E2_ENABLE_PIN PC4 + +// +// Heaters / Fans +// +#define HEATER_0_PIN PB0 // EXT0 port +#define HEATER_1_PIN PB5 // EXT1 port +#define HEATER_2_PIN PB4 // EXT2 port +#define HEATER_BED_PIN PB1 // CON2X3 hotbed port + +// +// These are FAN PWM pins on EXT0..EXT2 connectors. +// +//#define FAN_PIN PB9 // EXT0 port +#define FAN1_PIN PB8 // EXT1 port +#define FAN2_PIN PB7 // EXT2 port + +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN PB9 // EXT0 port, used as main extruder fan +#endif + +// +// Temperature Sensors +// +#define TEMP_0_PIN PC2 // EXT0 port +#define TEMP_1_PIN PC1 // EXT1 port +#define TEMP_2_PIN PC0 // EXT2 port +#define TEMP_BED_PIN PC3 // CON2X3 hotbed port + +// +// Misc. Functions +// +#define LED_PWM PD12 // External LED, pin 2 on LED labeled connector + +// +// LCD / Controller +// +#if HAS_WIRED_LCD + + #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) + // + // LCD display on J2 FFC40 + // Geeetech's LCD2004A Control Panel is very much like + // RepRapDiscount Smart Controller, but adds an FFC40 connector + // + #define LCD_PINS_RS PE6 // CS chip select /SS chip slave select + #define LCD_PINS_ENABLE PE14 // SID (MOSI) + #define LCD_PINS_D4 PD8 // SCK (CLK) clock + #define LCD_PINS_D5 PD9 + #define LCD_PINS_D6 PD10 + #define LCD_PINS_D7 PE15 + + #else + // + // Serial LCDs can be implemented in ExtUI + // + //#define LCD_UART_TX PD8 + //#define LCD_UART_RX PD9 + #endif + + #if HAS_MARLINUI_U8GLIB + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(96) + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(48) + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(715) + #endif + #endif + +#endif // HAS_WIRED_LCD + +#if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) + // + // Geeetech's LCD2004A Control Panel is very much like + // RepRapDiscount Smart Controller, but adds an FFC40 connector + // connected with a flat wire to J2 connector on the board. + // + #define BTN_EN1 PE8 + #define BTN_EN2 PE9 + #define BTN_ENC PE13 + + #define GTM32_PRO_VB_USE_LCD_BEEPER + #define GTM32_PRO_VB_USE_EXT_SDCARD +#endif + +// +// Beeper +// +#ifdef GTM32_PRO_VB_USE_LCD_BEEPER + // This is pin 32 on J2 FFC40 and pin, goes to the beeper + // on Geeetech's version of RepRapDiscount Smart Controller + // (e.g. on Rostock 301) + #define BEEPER_PIN PE12 +#else + // This is the beeper on the board itself + #define BEEPER_PIN PB10 +#endif + +/** + * The on-board TF_CARD_SOCKET microSD card socket has no SD Detect pin wired. + * + * The FFC10 (SD_CARD) connector has the same pins as those routed to the FFC40 (J2) + * connector, which usually go to the SD Card slot on the Geeetech version of the + * RepRapDiscount Smart Controller. Both connectors have the card detect signal. + * + * The on-board SD card and the external card (on either SD_CARD or J2) are two + * separate devices and can work simultaneously. Unfortunately, Marlin only supports + * a single SPI Flash device (as of 2019-07-05) so only one is enabled here. + */ +#if ENABLED(GTM32_PRO_VB_USE_EXT_SDCARD) + // + // SD Card on RepRapDiscount Smart Controller (J2) or on SD_CARD connector + // + #define SS_PIN PC11 + #define SCK_PIN PC12 + #define MOSI_PIN PD2 + #define MISO_PIN PC8 + #define SD_DETECT_PIN PC7 +#else + // + // Use the on-board card socket labeled TF_CARD_SOCKET + // + #define SS_PIN PA4 + #define SCK_PIN PA5 + #define MOSI_PIN PA7 + #define MISO_PIN PA6 + #define SD_DETECT_PIN -1 // Card detect is not connected +#endif + +#define SDSS SS_PIN + +// +// ESP WiFi can be soldered to J9 connector which is wired to USART2. +// Must define WIFISUPPORT in Configuration.h for the printer. +// +#define ESP_WIFI_MODULE_COM 2 +#define ESP_WIFI_MODULE_BAUDRATE 115200 +#define ESP_WIFI_MODULE_RESET_PIN -1 diff --git a/Marlin/src/pins/stm32/pins_GTM32_MINI_A30.h b/Marlin/src/pins/stm32f1/pins_GTM32_MINI_A30.h similarity index 50% rename from Marlin/src/pins/stm32/pins_GTM32_MINI_A30.h rename to Marlin/src/pins/stm32f1/pins_GTM32_MINI_A30.h index 4c14165f799d..02fd3bcae721 100644 --- a/Marlin/src/pins/stm32/pins_GTM32_MINI_A30.h +++ b/Marlin/src/pins/stm32f1/pins_GTM32_MINI_A30.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -26,7 +26,7 @@ * Schematic: https://github.com/chepo92/Smartto/blob/master/circuit_diagram/Rostock301/Hardware_GTM32_PRO_VB.pdf */ -#ifndef __STM32F1__ +#if NOT_TARGET(__STM32F1__) #error "Oops! Select an STM32F1 board in 'Tools > Board.'" #endif @@ -49,36 +49,38 @@ //#define DISABLE_JTAGSWD // Ignore temp readings during development. -//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 +//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 // Enable EEPROM Emulation for this board as it doesn't have EEPROM -#define FLASH_EEPROM_EMULATION -#define E2END 0xFFF // 4KB +#if EITHER(NO_EEPROM_SELECTED, FLASH_EEPROM_EMULATION) + #define FLASH_EEPROM_EMULATION + #define MARLIN_EEPROM_SIZE 0x1000 // 4KB +#endif // // Limit Switches // -#define X_MIN_PIN PE5 // ENDSTOPS 15,17 -#define X_MAX_PIN PE4 // ENDSTOPS 16,18 -#define Y_MIN_PIN PE3 // ENDSTOPS 9,11 -#define Y_MAX_PIN PE2 // ENDSTOPS 10,12 -#define Z_MIN_PIN PE0 // ENDSTOPS 3,5 -#define Z_MAX_PIN PE1 // ENDSTOPS 4,6 +#define X_MIN_PIN PE5 // ENDSTOPS 15,17 +#define X_MAX_PIN PE4 // ENDSTOPS 16,18 +#define Y_MIN_PIN PE3 // ENDSTOPS 9,11 +#define Y_MAX_PIN PE2 // ENDSTOPS 10,12 +#define Z_MIN_PIN PE0 // ENDSTOPS 3,5 +#define Z_MAX_PIN PE1 // ENDSTOPS 4,6 // // Steppers // -#define X_STEP_PIN PC6 -#define X_DIR_PIN PD13 -#define X_ENABLE_PIN PA8 +#define X_STEP_PIN PC6 +#define X_DIR_PIN PD13 +#define X_ENABLE_PIN PA8 -#define Y_STEP_PIN PA12 -#define Y_DIR_PIN PA11 -#define Y_ENABLE_PIN PA15 +#define Y_STEP_PIN PA12 +#define Y_DIR_PIN PA11 +#define Y_ENABLE_PIN PA15 -#define Z_STEP_PIN PD6 -#define Z_DIR_PIN PD3 -#define Z_ENABLE_PIN PB3 +#define Z_STEP_PIN PD6 +#define Z_DIR_PIN PD3 +#define Z_ENABLE_PIN PB3 // Extruder stepper pins // NOTE: Numbering here is made according to EXT connector numbers, @@ -86,51 +88,54 @@ // That is, E0_*_PIN are the E2_* lines connected to E2_A1 step // stick that drives the EXT0 output on the board. // -#define E0_STEP_PIN PC14 -#define E0_DIR_PIN PC13 -#define E0_ENABLE_PIN PC15 +#define E0_STEP_PIN PC14 +#define E0_DIR_PIN PC13 +#define E0_ENABLE_PIN PC15 -#define E1_STEP_PIN PA0 -#define E1_DIR_PIN PB6 -#define E1_ENABLE_PIN PA1 +#define E1_STEP_PIN PA0 +#define E1_DIR_PIN PB6 +#define E1_ENABLE_PIN PA1 -#define E2_STEP_PIN PB2 -#define E2_DIR_PIN PB11 -#define E2_ENABLE_PIN PC4 +#define E2_STEP_PIN PB2 +#define E2_DIR_PIN PB11 +#define E2_ENABLE_PIN PC4 // // Heaters / Fans // -#define HEATER_0_PIN PB0 // EXT0 port -#define HEATER_1_PIN PB5 // EXT1 port -#define HEATER_2_PIN PB4 // EXT2 port -#define HEATER_BED_PIN PB1 // CON2X3 hotbed port +#define HEATER_0_PIN PB0 // EXT0 port +#define HEATER_1_PIN PB5 // EXT1 port +#define HEATER_2_PIN PB4 // EXT2 port +#define HEATER_BED_PIN PB1 // CON2X3 hotbed port // // These are FAN PWM pins on EXT0..EXT2 connectors. // -//#define FAN_PIN PB9 // EXT0 port -#define ORIG_E0_AUTO_FAN_PIN PB9 // EXT0 port, used as main extruder fan -#define FAN1_PIN PB8 // EXT1 port -#define FAN2_PIN PB7 // EXT2 port +//#define FAN_PIN PB9 // EXT0 port +#define FAN1_PIN PB8 // EXT1 port +#define FAN2_PIN PB7 // EXT2 port + +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN PB9 // EXT0 port, used as main extruder fan +#endif // // Temperature Sensors // -#define TEMP_0_PIN PC2 // EXT0 port -#define TEMP_1_PIN PC1 // EXT1 port -#define TEMP_2_PIN PC0 // EXT2 port -#define TEMP_BED_PIN PC3 // CON2X3 hotbed port +#define TEMP_0_PIN PC2 // EXT0 port +#define TEMP_1_PIN PC1 // EXT1 port +#define TEMP_2_PIN PC0 // EXT2 port +#define TEMP_BED_PIN PC3 // CON2X3 hotbed port // // Misc. Functions // -#define LED_PWM PD12 // External LED, pin 2 on LED labeled connector +#define LED_PWM PD12 // External LED, pin 2 on LED labeled connector // // LCD / Controller // -#if HAS_SPI_LCD +#if HAS_WIRED_LCD #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) // @@ -139,16 +144,16 @@ // RepRapDiscount Smart Controller, but adds an FFC40 connector // connected with a flat wire to J2 connector on the board. // - #define LCD_PINS_RS PE6 // CS chip select /SS chip slave select - #define LCD_PINS_ENABLE PE14 // SID (MOSI) - #define LCD_PINS_D4 PD8 // SCK (CLK) clock - #define LCD_PINS_D5 PD9 - #define LCD_PINS_D6 PD10 - #define LCD_PINS_D7 PE15 + #define LCD_PINS_RS PE6 // CS chip select /SS chip slave select + #define LCD_PINS_ENABLE PE14 // SID (MOSI) + #define LCD_PINS_D4 PD8 // SCK (CLK) clock + #define LCD_PINS_D5 PD9 + #define LCD_PINS_D6 PD10 + #define LCD_PINS_D7 PE15 - #define BTN_EN1 PE8 - #define BTN_EN2 PE9 - #define BTN_ENC PE13 + #define BTN_EN1 PE8 + #define BTN_EN2 PE9 + #define BTN_ENC PE13 #define GTM32_PRO_VB_USE_LCD_BEEPER #define GTM32_PRO_VB_USE_EXT_SDCARD @@ -157,11 +162,11 @@ // // Serial LCDs can be implemented in ExtUI // - //#define LCD_UART_TX PD8 - //#define LCD_UART_RX PD9 + //#define LCD_UART_TX PD8 + //#define LCD_UART_RX PD9 #endif - #if HAS_GRAPHICAL_LCD + #if HAS_MARLINUI_U8GLIB #ifndef BOARD_ST7920_DELAY_1 #define BOARD_ST7920_DELAY_1 DELAY_NS(96) #endif @@ -173,7 +178,7 @@ #endif #endif -#endif // HAS_SPI_LCD +#endif // HAS_WIRED_LCD // // Beeper @@ -182,10 +187,10 @@ // This is pin 32 on J2 FFC40 and pin, goes to the beeper // on Geeetech's version of RepRapDiscount Smart Controller // (e.g. on Rostock 301) - #define BEEPER_PIN PE12 + #define BEEPER_PIN PE12 #else // This is the beeper on the board itself - #define BEEPER_PIN PB10 + #define BEEPER_PIN PB10 #endif /** @@ -203,28 +208,28 @@ // // SD Card on RepRapDiscount Smart Controller (J2) or on SD_CARD connector // - #define SS_PIN PC11 - #define SCK_PIN PC12 - #define MOSI_PIN PD2 - #define MISO_PIN PC8 - #define SD_DETECT_PIN PC7 + #define SS_PIN PC11 + #define SCK_PIN PC12 + #define MOSI_PIN PD2 + #define MISO_PIN PC8 + #define SD_DETECT_PIN PC7 #else // // Use the on-board card socket labeled TF_CARD_SOCKET // - #define SS_PIN PA4 - #define SCK_PIN PA5 - #define MOSI_PIN PA7 - #define MISO_PIN PA6 - #define SD_DETECT_PIN -1 // Card detect is not connected + #define SS_PIN PA4 + #define SCK_PIN PA5 + #define MOSI_PIN PA7 + #define MISO_PIN PA6 + #define SD_DETECT_PIN -1 // Card detect is not connected #endif -#define SDSS SS_PIN +#define SDSS SS_PIN // // ESP WiFi can be soldered to J9 connector which is wired to USART2. // Must define WIFISUPPORT in Configuration.h for the printer. // -#define ESP_WIFI_MODULE_COM 2 -#define ESP_WIFI_MODULE_BAUDRATE 115200 -#define ESP_WIFI_MODULE_RESET_PIN -1 +#define ESP_WIFI_MODULE_COM 2 +#define ESP_WIFI_MODULE_BAUDRATE 115200 +#define ESP_WIFI_MODULE_RESET_PIN -1 diff --git a/Marlin/src/pins/stm32f1/pins_GTM32_PRO_VB.h b/Marlin/src/pins/stm32f1/pins_GTM32_PRO_VB.h new file mode 100644 index 000000000000..ca25c45a7bba --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_GTM32_PRO_VB.h @@ -0,0 +1,241 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * 24 May 2018 - @chepo for STM32F103VET6 + * Schematic: https://github.com/chepo92/Smartto/blob/master/circuit_diagram/Rostock301/Hardware_GTM32_PRO_VB.pdf + */ + +#if NOT_TARGET(__STM32F1__) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#endif + +#define BOARD_INFO_NAME "GTM32 Pro VB" +#define DEFAULT_MACHINE_NAME "STM32F103VET6" + +//#define DISABLE_DEBUG + +// +// It is required to disable JTAG function because its pins are +// used as GPIO to drive the Y axis stepper. +// DO NOT ENABLE! +// +#define DISABLE_JTAG + +// +// If you don't need the SWDIO functionality (any more), you may +// disable SWD here to regain PA13/PA14 pins for other use. +// +//#define DISABLE_JTAGSWD + +// Ignore temp readings during development. +//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 + +// Enable EEPROM Emulation for this board as it doesn't have EEPROM +#if EITHER(NO_EEPROM_SELECTED, FLASH_EEPROM_EMULATION) + #define FLASH_EEPROM_EMULATION + #define MARLIN_EEPROM_SIZE 0x1000 // 4KB +#endif + +// +// Limit Switches +// +#define X_MIN_PIN PE5 // ENDSTOPS 15,17 +#define X_MAX_PIN PE4 // ENDSTOPS 16,18 +#define Y_MIN_PIN PE3 // ENDSTOPS 9,11 +#define Y_MAX_PIN PE2 // ENDSTOPS 10,12 +#define Z_MIN_PIN PE1 // ENDSTOPS 3,5 +#define Z_MAX_PIN PE0 // ENDSTOPS 4,6 + +// +// Steppers +// +#define X_STEP_PIN PC6 +#define X_DIR_PIN PD13 +#define X_ENABLE_PIN PA8 + +#define Y_STEP_PIN PA12 +#define Y_DIR_PIN PA11 +#define Y_ENABLE_PIN PA15 + +#define Z_STEP_PIN PD6 +#define Z_DIR_PIN PD3 +#define Z_ENABLE_PIN PB3 + +// Extruder stepper pins +// NOTE: Numbering here is made according to EXT connector numbers, +// the FANx_PWM line numbering in the schematics is reverse. +// That is, E0_*_PIN are the E2_* lines connected to E2_A1 step +// stick that drives the EXT0 output on the board. +// +#define E0_STEP_PIN PC14 +#define E0_DIR_PIN PC13 +#define E0_ENABLE_PIN PC15 + +#define E1_STEP_PIN PA0 +#define E1_DIR_PIN PB6 +#define E1_ENABLE_PIN PA1 + +#define E2_STEP_PIN PB2 +#define E2_DIR_PIN PB11 +#define E2_ENABLE_PIN PC4 + +// +// Heaters / Fans +// +#define HEATER_0_PIN PB0 // EXT0 port +#define HEATER_1_PIN PB5 // EXT1 port +#define HEATER_2_PIN PB4 // EXT2 port +#define HEATER_BED_PIN PB1 // CON2X3 hotbed port + +// +// These are FAN PWM pins on EXT0..EXT2 connectors. +// +//#define FAN_PIN PB9 // EXT0 port +#define FAN1_PIN PB8 // EXT1 port +#define FAN2_PIN PB7 // EXT2 port + +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN PB9 // EXT0 port, used as main extruder fan +#endif + +// +// Temperature Sensors +// +#define TEMP_0_PIN PC2 // EXT0 port +#define TEMP_1_PIN PC1 // EXT1 port +#define TEMP_2_PIN PC0 // EXT2 port +#define TEMP_BED_PIN PC3 // CON2X3 hotbed port + +// +// Misc. Functions +// +#define LED_PWM PD12 // External LED, pin 2 on LED labeled connector + +// +// LCD / Controller +// +#if HAS_WIRED_LCD + + #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) + // + // LCD display on J2 FFC40 + // Geeetech's LCD2004A Control Panel is very much like + // RepRapDiscount Smart Controller, but adds an FFC40 connector + // + #define LCD_PINS_RS PE6 // CS chip select /SS chip slave select + #define LCD_PINS_ENABLE PE14 // SID (MOSI) + #define LCD_PINS_D4 PD8 // SCK (CLK) clock + #define LCD_PINS_D5 PD9 + #define LCD_PINS_D6 PD10 + #define LCD_PINS_D7 PE15 + + #else + // + // Serial LCDs can be implemented in ExtUI + // + //#define LCD_UART_TX PD8 + //#define LCD_UART_RX PD9 + #endif + + #if HAS_MARLINUI_U8GLIB + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(96) + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(48) + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(715) + #endif + #endif + +#endif // HAS_WIRED_LCD + +#if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) + // + // Geeetech's LCD2004A Control Panel is very much like + // RepRapDiscount Smart Controller, but adds an FFC40 connector + // connected with a flat wire to J2 connector on the board. + // + #define BTN_EN1 PE8 + #define BTN_EN2 PE9 + #define BTN_ENC PE13 + + #define GTM32_PRO_VB_USE_LCD_BEEPER + #define GTM32_PRO_VB_USE_EXT_SDCARD +#endif + +// +// Beeper +// +#ifdef GTM32_PRO_VB_USE_LCD_BEEPER + // This is pin 32 on J2 FFC40 and pin, goes to the beeper + // on Geeetech's version of RepRapDiscount Smart Controller + // (e.g. on Rostock 301) + #define BEEPER_PIN PE12 +#else + // This is the beeper on the board itself + #define BEEPER_PIN PB10 +#endif + +/** + * The on-board TF_CARD_SOCKET microSD card socket has no SD Detect pin wired. + * + * The FFC10 (SD_CARD) connector has the same pins as those routed to the FFC40 (J2) + * connector, which usually go to the SD Card slot on the Geeetech version of the + * RepRapDiscount Smart Controller. Both connectors have the card detect signal. + * + * The on-board SD card and the external card (on either SD_CARD or J2) are two + * separate devices and can work simultaneously. Unfortunately, Marlin only supports + * a single SPI Flash device (as of 2019-07-05) so only one is enabled here. + */ +#if ENABLED(GTM32_PRO_VB_USE_EXT_SDCARD) + // + // SD Card on RepRapDiscount Smart Controller (J2) or on SD_CARD connector + // + #define SS_PIN PC11 + #define SCK_PIN PC12 + #define MOSI_PIN PD2 + #define MISO_PIN PC8 + #define SD_DETECT_PIN PC7 +#else + // + // Use the on-board card socket labeled TF_CARD_SOCKET + // + #define SS_PIN PA4 + #define SCK_PIN PA5 + #define MOSI_PIN PA7 + #define MISO_PIN PA6 + #define SD_DETECT_PIN -1 // Card detect is not connected +#endif + +#define SDSS SS_PIN + +// +// ESP WiFi can be soldered to J9 connector which is wired to USART2. +// Must define WIFISUPPORT in Configuration.h for the printer. +// +#define ESP_WIFI_MODULE_COM 2 +#define ESP_WIFI_MODULE_BAUDRATE 115200 +#define ESP_WIFI_MODULE_RESET_PIN -1 diff --git a/Marlin/src/pins/stm32f1/pins_GTM32_REV_B.h b/Marlin/src/pins/stm32f1/pins_GTM32_REV_B.h new file mode 100644 index 000000000000..fc18263fddf6 --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_GTM32_REV_B.h @@ -0,0 +1,238 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * 24 May 2018 - @chepo for STM32F103VET6 + * Schematic: https://github.com/chepo92/Smartto/blob/master/circuit_diagram/Rostock301/Hardware_GTM32_PRO_VB.pdf + */ + +#if NOT_TARGET(__STM32F1__) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#endif + +#define BOARD_INFO_NAME "GTM32 Pro VB" +#define DEFAULT_MACHINE_NAME "M201" + +//#define DISABLE_DEBUG + +// +// It is required to disable JTAG function because its pins are +// used as GPIO to drive the Y axis stepper. +// DO NOT ENABLE! +// +#define DISABLE_JTAG + +// +// If you don't need the SWDIO functionality (any more), you may +// disable SWD here to regain PA13/PA14 pins for other use. +// +//#define DISABLE_JTAGSWD + +// Ignore temp readings during development. +//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 + +// Enable EEPROM Emulation for this board as it doesn't have EEPROM +#if EITHER(NO_EEPROM_SELECTED, FLASH_EEPROM_EMULATION) + #define FLASH_EEPROM_EMULATION + #define MARLIN_EEPROM_SIZE 0x1000 // 4KB +#endif + +// +// Limit Switches +// +#define X_MIN_PIN PE5 // ENDSTOPS 15,17 +#define X_MAX_PIN PE4 // ENDSTOPS 16,18 +#define Y_MIN_PIN PE3 // ENDSTOPS 9,11 +#define Y_MAX_PIN PE2 // ENDSTOPS 10,12 +#define Z_MIN_PIN PE1 // ENDSTOPS 3,5 +#define Z_MAX_PIN PE0 // ENDSTOPS 4,6 + +// +// Steppers +// +#define X_STEP_PIN PC6 +#define X_DIR_PIN PD13 +#define X_ENABLE_PIN PA8 + +#define Y_STEP_PIN PA12 +#define Y_DIR_PIN PA11 +#define Y_ENABLE_PIN PA15 + +#define Z_STEP_PIN PD6 +#define Z_DIR_PIN PD3 +#define Z_ENABLE_PIN PB3 + +// Extruder stepper pins +// NOTE: Numbering here is made according to EXT connector numbers, +// the FANx_PWM line numbering in the schematics is reverse. +// That is, E0_*_PIN are the E2_* lines connected to E2_A1 step +// stick that drives the EXT0 output on the board. +// +#define E0_STEP_PIN PC14 +#define E0_DIR_PIN PC13 +#define E0_ENABLE_PIN PC15 + +#define E1_STEP_PIN PA0 +#define E1_DIR_PIN PB6 +#define E1_ENABLE_PIN PA1 + +#define E2_STEP_PIN PB2 +#define E2_DIR_PIN PB11 +#define E2_ENABLE_PIN PC4 + +// +// Heaters / Fans - INFO: Extruders ports are in reverse order. Pin numbers here differ from schematic. Original firmware assumes heater, fan and temp sensor on port EXT0 PB0, PB9, PC2. +// +#define HEATER_0_PIN PB0 // EXT0 port. +#define HEATER_1_PIN PB5 // EXT1 port +#define HEATER_2_PIN PB4 // EXT2 port +#define HEATER_BED_PIN PB1 // CON2X3 hotbed port + +// +// These are FAN PWM pins on EXT0..EXT2 connectors. +// +//#define FAN_PIN PB9 // EXT0 port +#define FAN1_PIN PB8 // EXT1 port +#define FAN2_PIN PB7 // EXT2 port + +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN PB9 // EXT0 port, used as main extruder fan +#endif + +// +// Temperature Sensors +// +#define TEMP_0_PIN PC2 // EXT0 port +#define TEMP_1_PIN PC1 // EXT1 port +#define TEMP_2_PIN PC0 // EXT2 port +#define TEMP_BED_PIN PC3 // CON2X3 hotbed port + +// +// Misc. Functions +// +#define LED_PWM PD12 // External LED, pin 2 on LED labeled connector + +// +// LCD / Controller +// +#if HAS_WIRED_LCD + + #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) + + // + // LCD display on J2 FFC40 + // Geeetech's LCD2004A Control Panel is very much like + // RepRapDiscount Smart Controller, but adds an FFC40 connector + // connected with a flat wire to J2 connector on the board. + // + #define LCD_PINS_RS PA12 // CS chip select /SS chip slave select + // RW is hardwired to VSS + #define LCD_PINS_ENABLE PC7 // SID (MOSI) + #define LCD_PINS_D4 PD1 // SCK (CLK) clock + #define LCD_PINS_D5 PD4 + #define LCD_PINS_D6 PD5 + #define LCD_PINS_D7 PD7 + + #define BTN_EN1 PE8 + #define BTN_EN2 PE9 + #define BTN_ENC PE13 + + //#define GTM32_PRO_VB_USE_LCD_BEEPER + #define GTM32_PRO_VB_USE_EXT_SDCARD + + #else + // + // Serial LCDs can be implemented in ExtUI + // + //#define LCD_UART_TX PD8 + //#define LCD_UART_RX PD9 + #endif + + #if HAS_MARLINUI_U8GLIB + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(96) + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(48) + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(715) + #endif + #endif + +#endif // HAS_WIRED_LCD + +// +// Beeper +// +#ifdef GTM32_PRO_VB_USE_LCD_BEEPER + // This is pin 32 on J2 FFC40 and pin, goes to the beeper + // on Geeetech's version of RepRapDiscount Smart Controller + // (e.g. on Rostock 301) + #define BEEPER_PIN PE12 +#else + // This is the beeper on the board itself + #define BEEPER_PIN PB10 +#endif + +/** + * The on-board TF_CARD_SOCKET microSD card socket has no SD Detect pin wired. + * + * The FFC10 (SD_CARD) connector has the same pins as those routed to the FFC40 (J2) + * connector, which usually go to the SD Card slot on the Geeetech version of the + * RepRapDiscount Smart Controller. Both connectors have the card detect signal. + * + * The on-board SD card and the external card (on either SD_CARD or J2) are two + * separate devices and can work simultaneously. Unfortunately, Marlin only supports + * a single SPI Flash device (as of 2019-07-05) so only one is enabled here. + */ +#if ENABLED(GTM32_PRO_VB_USE_EXT_SDCARD) + // + // SD Card on RepRapDiscount Smart Controller (J2) or on SD_CARD connector + // + #define SS_PIN PB12 // PC11 + #define SCK_PIN PB13 // PC12 // PC1 + #define MOSI_PIN PB15 // PD2 // PD2 + #define MISO_PIN PB14 // PC8 + #define SD_DETECT_PIN PC7 + +#else + // + // Use the on-board card socket labeled TF_CARD_SOCKET + // + #define SS_PIN PA4 + #define SCK_PIN PA5 + #define MOSI_PIN PA7 + #define MISO_PIN PA6 // PA6 + #define SD_DETECT_PIN -1 // Card detect is not connected +#endif + +#define SDSS SS_PIN + +// +// ESP WiFi can be soldered to J9 connector which is wired to USART2. +// Must define WIFISUPPORT in Configuration.h for the printer. +// +#define ESP_WIFI_MODULE_COM 2 +#define ESP_WIFI_MODULE_BAUDRATE 115200 +#define ESP_WIFI_MODULE_RESET_PIN -1 diff --git a/Marlin/src/pins/stm32f1/pins_JGAURORA_A5S_A1.h b/Marlin/src/pins/stm32f1/pins_JGAURORA_A5S_A1.h new file mode 100644 index 000000000000..3c277233d73e --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_JGAURORA_A5S_A1.h @@ -0,0 +1,132 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + + /** + * ╦╔═╗╔═╗┬ ┬┬─┐┌─┐┬─┐┌─┐╔═╗┌─┐┬─┐┬ ┬┌┬┐ ┌─┐┌─┐┌┬┐ + * ║║ ╦╠═╣│ │├┬┘│ │├┬┘├─┤╠╣ │ │├┬┘│ ││││ │ │ ││││ + * ╚╝╚═╝╩ ╩└─┘┴└─└─┘┴└─┴ ┴╚ └─┘┴└─└─┘┴ ┴o└─┘└─┘┴ ┴ + * Pin assignments for 32-bit JGAurora A5S & A1 + */ + +#if NOT_TARGET(__STM32F1__) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#elif HOTENDS > 1 || E_STEPPERS > 1 + #error "JGAurora 32-bit board only supports 1 hotend / E-stepper. Comment out this line to continue." +#endif +#define BOARD_INFO_NAME "JGAurora A5S A1 board" + +#ifndef STM32_XL_DENSITY + #define STM32_XL_DENSITY +#endif + +//#define MCU_STM32F103ZE // not yet required +// Enable EEPROM Emulation for this board, so that we don't overwrite factory data + +//#define I2C_EEPROM // AT24C64 +//#define MARLIN_EEPROM_SIZE 0x8000UL // 64KB + +//#define FLASH_EEPROM_EMULATION +//#define MARLIN_EEPROM_SIZE 0x1000UL // 4KB +//#define MARLIN_EEPROM_SIZE (EEPROM_START_ADDRESS + (EEPROM_PAGE_SIZE) * 2UL) + +//#define EEPROM_CHITCHAT +//#define DEBUG_EEPROM_READWRITE + +// +// Limit Switches +// +#define X_STOP_PIN PC6 +#define Y_STOP_PIN PG8 +#define Z_STOP_PIN PG7 +//#define X_MAX_PIN PC5 +//#define Y_MAX_PIN PC4 +//#define Z_MAX_PIN PB0 + +// +// Steppers +// +#define X_STEP_PIN PD6 +#define X_DIR_PIN PD3 +#define X_ENABLE_PIN PG9 + +#define Y_STEP_PIN PG12 +#define Y_DIR_PIN PG11 +#define Y_ENABLE_PIN PG13 + +#define Z_STEP_PIN PG15 +#define Z_DIR_PIN PG14 +#define Z_ENABLE_PIN PB8 + +#define E0_STEP_PIN PE2 +#define E0_DIR_PIN PB9 +#define E0_ENABLE_PIN PE3 + +#define E1_STEP_PIN PE5 +#define E1_DIR_PIN PE4 +#define E1_ENABLE_PIN PE6 + +// +// Temperature Sensors +// +#define TEMP_0_PIN PC2 +#define TEMP_BED_PIN PC1 + +// +// Heaters / Fans +// +#define HEATER_0_PIN PA2 +#define HEATER_BED_PIN PA3 + +#define FAN_PIN PA1 + +#define FIL_RUNOUT_PIN PC7 + +// +// LCD +// +#define LCD_BACKLIGHT_PIN PF11 +#define FSMC_CS_PIN PD7 +#define FSMC_RS_PIN PG0 + +#define LCD_USE_DMA_FSMC // Use DMA transfers to send data to the TFT +#define FSMC_DMA_DEV DMA2 +#define FSMC_DMA_CHANNEL DMA_CH5 + +// +// SD Card +// +#define SD_DETECT_PIN PF10 + +// +// Misc. +// +#define BEEPER_PIN PC3 // use PB7 to shut up if desired +#define LED_PIN PC13 + +// +// Touch support +// +#if NEED_TOUCH_PINS + #define TOUCH_CS_PIN PA4 + #define TOUCH_INT_PIN PC4 +#endif diff --git a/Marlin/src/pins/stm32f1/pins_LONGER3D_LK.h b/Marlin/src/pins/stm32f1/pins_LONGER3D_LK.h new file mode 100644 index 000000000000..af81bbebe2d4 --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_LONGER3D_LK.h @@ -0,0 +1,177 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * Longer3D LK1/LK2 & Alfawise U20/U30 (STM32F103VET6) board pin assignments + */ + +#if NOT_TARGET(__STM32F1__, STM32F1xx) + #error "Oops! Select a STM32F1 board in 'Tools > Board.'" +#elif HOTENDS > 1 || E_STEPPERS > 1 + #error "Longer3D board only supports 1 hotend / E-stepper. Comment out this line to continue." +#endif + +#define BOARD_INFO_NAME "Longer3D" +#define ALFAWISE_UX0 // Common to all Longer3D STM32F1 boards (used for Open drain mosfets) + +//#define DISABLE_DEBUG // We still want to debug with STLINK... +#define DISABLE_JTAG // We free the jtag pins (PA15) but keep STLINK + // Release PB4 (STEP_X_PIN) from JTAG NRST role. +// +// Limit Switches +// +#define X_MIN_PIN PC1 // pin 16 +#define X_MAX_PIN PC0 // pin 15 (Filament sensor on Alfawise setup) +#define Y_MIN_PIN PC15 // pin 9 +#define Y_MAX_PIN PC14 // pin 8 (Unused in stock Alfawise setup) +#define Z_MIN_PIN PE6 // pin 5 Standard Endstop or Z_Probe endstop function +#define Z_MAX_PIN PE5 // pin 4 (Unused in stock Alfawise setup) + // May be used for BLTouch Servo function on older variants (<= V08) +#define ONBOARD_ENDSTOPPULLUPS + +// +// Filament Sensor +// +#ifndef FIL_RUNOUT_PIN + #define FIL_RUNOUT_PIN PC0 // XMAX plug on PCB used as filament runout sensor on Alfawise boards (inverting true) +#endif + +// +// Steppers +// +#define X_ENABLE_PIN PB5 // pin 91 +#define X_STEP_PIN PB4 // pin 90 +#define X_DIR_PIN PB3 // pin 89 + +#define Y_ENABLE_PIN PB8 // pin 95 +#define Y_STEP_PIN PB7 // pin 93 +#define Y_DIR_PIN PB6 // pin 92 + +#define Z_ENABLE_PIN PE1 // pin 98 +#define Z_STEP_PIN PE0 // pin 97 +#define Z_DIR_PIN PB9 // pin 96 + +#define E0_ENABLE_PIN PE4 // pin 3 +#define E0_STEP_PIN PE3 // pin 2 +#define E0_DIR_PIN PE2 // pin 1 + +// +// Temperature Sensors +// +#define TEMP_0_PIN PA0 // pin 23 (Nozzle 100K/3950 thermistor) +#define TEMP_BED_PIN PA1 // pin 24 (Hot Bed 100K/3950 thermistor) + +// +// Heaters / Fans +// +#define HEATER_0_PIN PD3 // pin 84 (Nozzle Heat Mosfet) +#define HEATER_BED_PIN PA8 // pin 67 (Hot Bed Mosfet) + +#define FAN_PIN PA15 // pin 77 (4cm Fan) +#define FAN_SOFT_PWM // Required to avoid issues with heating or STLink +#define FAN_MIN_PWM 35 // Fan will not start in 1-30 range +#define FAN_MAX_PWM 255 + +//#define BEEPER_PIN PD13 // pin 60 (Servo PWM output 5V/GND on Board V0G+) made for BL-Touch sensor + // Can drive a PC Buzzer, if connected between PWM and 5V pins + +#define LED_PIN PC2 // pin 17 + +// +// PWM for a servo probe +// Other servo devices are not supported on this board! +// +#if HAS_Z_SERVO_PROBE + #define SERVO0_PIN PD13 // Open drain PWM pin on the V0G (GND or floating 5V) + #define SERVO0_PWM_OD // Comment this if using PE5 + + //#define SERVO0_PIN PE5 // Pulled up PWM pin on the V08 (3.3V or 0) + //#undef Z_MAX_PIN // Uncomment if using ZMAX connector (PE5) +#endif + +/** + * Note: Alfawise screens use various TFT controllers. Supported screens + * are based on the ILI9341, ILI9328 and ST7798V. Define init sequences for + * other screens in u8g_dev_tft_320x240_upscale_from_128x64.cpp + * + * If the screen stays white, disable 'LCD_RESET_PIN' to let the bootloader + * init the screen. + * + * Setting an 'LCD_RESET_PIN' may cause a flicker when entering the LCD menu + * because Marlin uses the reset as a failsafe to revive a glitchy LCD. + */ + +#define TFT_RESET_PIN PC4 // pin 33 +#define TFT_BACKLIGHT_PIN PD12 // pin 59 +#define FSMC_CS_PIN PD7 // pin 88 = FSMC_NE1 +#define FSMC_RS_PIN PD11 // pin 58 A16 Register. Only one address needed + +#define LCD_USE_DMA_FSMC // Use DMA transfers to send data to the TFT +#define FSMC_DMA_DEV DMA2 +#define FSMC_DMA_CHANNEL DMA_CH5 + +#define DOGLCD_MOSI -1 // Prevent auto-define by Conditionals_post.h +#define DOGLCD_SCK -1 + +// Longer/Alfawise TFT +#define LONGER_LK_TFT28 + +// Buffer for Color UI +#define TFT_BUFFER_SIZE 3200 + +/** + * Note: Alfawise U20/U30 boards DON'T use SPI2, as the hardware designer + * mixed up MOSI and MISO pins. SPI is managed in SW, and needs pins + * declared below. + */ +#if NEED_TOUCH_PINS + #define TOUCH_CS_PIN PB12 // pin 51 SPI2_NSS + #define TOUCH_SCK_PIN PB13 // pin 52 + #define TOUCH_MOSI_PIN PB14 // pin 53 + #define TOUCH_MISO_PIN PB15 // pin 54 + #define TOUCH_INT_PIN PC6 // pin 63 (PenIRQ coming from ADS7843) +#endif + +// +// Persistent Storage +// If no option is selected below the SD Card will be used +// +#if NO_EEPROM_SELECTED + //#define SPI_EEPROM + #define FLASH_EEPROM_EMULATION +#endif + +#if ENABLED(SPI_EEPROM) + // SPI1 EEPROM Winbond W25Q64 (8MB/64Mbits) + #define SPI_CHAN_EEPROM1 1 + #define SPI_EEPROM1_CS PC5 // pin 34 + #define EEPROM_SCK BOARD_SPI1_SCK_PIN // PA5 pin 30 + #define EEPROM_MISO BOARD_SPI1_MISO_PIN // PA6 pin 31 + #define EEPROM_MOSI BOARD_SPI1_MOSI_PIN // PA7 pin 32 + #define EEPROM_PAGE_SIZE 0x1000U // 4KB (from datasheet) + #define MARLIN_EEPROM_SIZE 16UL * (EEPROM_PAGE_SIZE) // Limit to 64KB for now... +#elif ENABLED(FLASH_EEPROM_EMULATION) + // SoC Flash (framework-arduinoststm32-maple/STM32F1/libraries/EEPROM/EEPROM.h) + #define EEPROM_PAGE_SIZE (0x800U) // 2KB + #define EEPROM_START_ADDRESS (0x8000000UL + (STM32_FLASH_SIZE) * 1024UL - (EEPROM_PAGE_SIZE) * 2UL) + #define MARLIN_EEPROM_SIZE (EEPROM_PAGE_SIZE) +#else + #define MARLIN_EEPROM_SIZE 0x800U // On SD, Limit to 2KB, require this amount of RAM +#endif diff --git a/Marlin/src/pins/stm32f1/pins_MALYAN_M200.h b/Marlin/src/pins/stm32f1/pins_MALYAN_M200.h new file mode 100644 index 000000000000..95e7e92174fa --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_MALYAN_M200.h @@ -0,0 +1,95 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * MALYAN M200 pin assignments + */ + +#if NOT_TARGET(__STM32F1__, STM32F1xx, STM32F0xx) + #error "Oops! Select an STM32 board in your IDE." +#endif + +#ifndef BOARD_INFO_NAME + #define BOARD_INFO_NAME "Malyan M200" +#endif + +// Prevents hanging from an extra watchdog init +#define DISABLE_WATCHDOG_INIT + +// Assume Flash EEPROM +#if NO_EEPROM_SELECTED + #define FLASH_EEPROM_EMULATION +#endif + +#define SDSS SS_PIN + +// Based on PWM timer usage, we have to use these timers and soft PWM for the fans +// On STM32F103: +// PB3, PB6, PB7, and PB8 can be used with pwm, which rules out TIM2 and TIM4. +// On STM32F070, 16 and 17 are in use, but 1 and 3 are available. +#define STEP_TIMER 1 +#define TEMP_TIMER 3 + +// +// Limit Switches +// +#define X_MIN_PIN PB4 +#define Y_MIN_PIN PA15 +#define Z_MIN_PIN PB5 + +// +// Steppers +// +// X & Y enable are the same +#define X_STEP_PIN PB14 +#define X_DIR_PIN PB15 +#define X_ENABLE_PIN PA8 + +#define Y_STEP_PIN PB12 +#define Y_DIR_PIN PB13 +#define Y_ENABLE_PIN PA8 + +#define Z_STEP_PIN PB10 +#define Z_DIR_PIN PB2 +#define Z_ENABLE_PIN PB11 + +#define E0_STEP_PIN PB0 +#define E0_DIR_PIN PC13 +#define E0_ENABLE_PIN PB1 + +// +// Temperature Sensors +// +#define TEMP_0_PIN PA0 // Analog Input (HOTEND0 thermistor) +#define TEMP_BED_PIN PA1 // Analog Input (BED thermistor) + +// +// Heaters / Fans +// +#define HEATER_0_PIN PB6 // HOTEND0 MOSFET +#define HEATER_BED_PIN PB7 // BED MOSFET + +#define MALYAN_FAN1_PIN PB8 // FAN1 header on board - PRINT FAN +#define MALYAN_FAN2_PIN PB3 // FAN2 header on board - CONTROLLER FAN + +#define FAN1_PIN MALYAN_FAN2_PIN diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN.h new file mode 100644 index 000000000000..8831d6804b05 --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN.h @@ -0,0 +1,213 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * MKS Robin (STM32F130ZET6) board pin assignments + * + * https://github.com/makerbase-mks/MKS-Robin/tree/master/MKS%20Robin/Hardware + */ + +#if NOT_TARGET(STM32F1, STM32F1xx) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#elif HOTENDS > 2 || E_STEPPERS > 2 + #error "MKS Robin supports up to 2 hotends / E-steppers. Comment out this line to continue." +#endif + +#define BOARD_INFO_NAME "MKS Robin" + +// +// Release PB4 (Y_ENABLE_PIN) from JTAG NRST role +// +#define DISABLE_JTAG + +// +// Enable SD EEPROM to prevent infinite boot loop +// +#ifdef ARDUINO_ARCH_STM32 + #define FLASH_EEPROM_EMULATION + #define EEPROM_PAGE_SIZE (0x800U) // 2KB + #define EEPROM_START_ADDRESS (0x8000000UL + (STM32_FLASH_SIZE) * 1024UL - (EEPROM_PAGE_SIZE) * 2UL) + #define MARLIN_EEPROM_SIZE (EEPROM_PAGE_SIZE) +#else + #define SDCARD_EEPROM_EMULATION +#endif + +// +// Servos +// +#define SERVO0_PIN PC3 // XS1 - 5 +#define SERVO1_PIN PA1 // XS1 - 6 +#define SERVO2_PIN PF9 // XS2 - 5 +#define SERVO3_PIN PF8 // XS2 - 6 + +// +// Limit Switches +// +#define X_MIN_PIN PB12 +#define X_MAX_PIN PB0 +#define Y_MIN_PIN PC5 +#define Y_MAX_PIN PC4 +#define Z_MIN_PIN PA4 +#define Z_MAX_PIN PF7 + +// +// Steppers +// +#define X_ENABLE_PIN PB9 +#define X_STEP_PIN PB8 +#define X_DIR_PIN PB5 + +#define Y_ENABLE_PIN PB4 +#define Y_STEP_PIN PG15 +#define Y_DIR_PIN PG10 + +#define Z_ENABLE_PIN PD7 +#define Z_STEP_PIN PD3 +#define Z_DIR_PIN PG14 + +#define E0_ENABLE_PIN PG13 +#define E0_STEP_PIN PG8 +#define E0_DIR_PIN PA15 + +#define E1_ENABLE_PIN PA12 +#define E1_STEP_PIN PA11 +#define E1_DIR_PIN PA8 + +// +// Temperature Sensors +// +#define TEMP_0_PIN PC1 // TH1 +#define TEMP_1_PIN PC2 // TH2 +#define TEMP_BED_PIN PC0 // TB1 + +// +// Heaters / Fans +// +#define HEATER_0_PIN PC7 // HEATER1 +#define HEATER_1_PIN PA6 // HEATER2 +#define HEATER_BED_PIN PC6 // HOT BED + +#define FAN_PIN PA7 // FAN + +/** + * Note: MKS Robin board is using SPI2 interface. Make sure your stm32duino library is configured accordingly + */ +//#define MAX6675_SS_PIN PE5 // TC1 - CS1 +//#define MAX6675_SS_PIN PE6 // TC2 - CS2 + +#define POWER_LOSS_PIN PA2 // PW_DET +#define PS_ON_PIN PA3 // PW_OFF +#define FIL_RUNOUT_PIN PF11 // MT_DET + +#ifdef ARDUINO_ARCH_STM32F1 + #define BEEPER_PIN PC13 +#else + #define BEEPER_PIN -1 +#endif +#define LED_PIN PB2 + +#if HAS_FSMC_TFT + /** + * Note: MKS Robin TFT screens use various TFT controllers + * Supported screens are based on the ILI9341, ST7789V and ILI9328 (320x240) + * ILI9488 is not supported + * Define init sequences for other screens in u8g_dev_tft_320x240_upscale_from_128x64.cpp + * + * If the screen stays white, disable 'LCD_RESET_PIN' + * to let the bootloader init the screen. + * + * Setting an 'LCD_RESET_PIN' may cause a flicker when entering the LCD menu + * because Marlin uses the reset as a failsafe to revive a glitchy LCD. + */ + //#define LCD_RESET_PIN PF6 + #define LCD_BACKLIGHT_PIN PG11 + #define FSMC_CS_PIN PG12 // NE4 + #define FSMC_RS_PIN PF0 // A0 + #define TFT_CS_PIN FSMC_CS_PIN + #define TFT_RS_PIN FSMC_RS_PIN + + #define LCD_USE_DMA_FSMC // Use DMA transfers to send data to the TFT + #define FSMC_DMA_DEV DMA2 + #define FSMC_DMA_CHANNEL DMA_CH5 +#elif HAS_GRAPHICAL_TFT + #define TFT_RESET_PIN PF6 + #define TFT_BACKLIGHT_PIN PG11 + #define TFT_CS_PIN PG12 // NE4 + #define TFT_RS_PIN PF0 // A0 +#endif + +#if NEED_TOUCH_PINS + #define TOUCH_CS_PIN PB1 // SPI2_NSS + #define TOUCH_SCK_PIN PB13 // SPI2_SCK + #define TOUCH_MISO_PIN PB14 // SPI2_MISO + #define TOUCH_MOSI_PIN PB15 // SPI2_MOSI + #define TOUCH_INT_PIN -1 +#endif + +// SPI1(PA7) & SPI3(PB5) not available +#define ENABLE_SPI2 + +#if ENABLED(SDIO_SUPPORT) + #define SCK_PIN PB13 // SPI2 + #define MISO_PIN PB14 // SPI2 + #define MOSI_PIN PB15 // SPI2 + #define SD_DETECT_PIN PF12 // SD_CD +#else + // SD as custom software SPI (SDIO pins) + #define SCK_PIN PC12 + #define MISO_PIN PC8 + #define MOSI_PIN PD2 + #define SS_PIN -1 + #define ONBOARD_SD_CS_PIN PC11 + #define SDSS PD2 + #define SD_DETECT_PIN -1 +#endif + +#if HAS_TMC_UART + /** + * TMC2208/TMC2209 stepper drivers + * + * Hardware serial communication ports. + * If undefined software serial is used according to the pins below + */ + //#define X_HARDWARE_SERIAL MSerial1 + //#define Y_HARDWARE_SERIAL MSerial1 + //#define Z_HARDWARE_SERIAL MSerial1 + //#define E0_HARDWARE_SERIAL MSerial1 + //#define E1_HARDWARE_SERIAL MSerial1 + + // Unused servo pins may be repurposed with SoftwareSerialM + //#define X_SERIAL_TX_PIN PF8 // SERVO3_PIN -- XS2 - 6 + //#define Y_SERIAL_TX_PIN PF9 // SERVO2_PIN -- XS2 - 5 + //#define Z_SERIAL_TX_PIN PA1 // SERVO1_PIN -- XS1 - 6 + //#define E0_SERIAL_TX_PIN PC3 // SERVO0_PIN -- XS1 - 5 + //#define X_SERIAL_RX_PIN X_SERIAL_TX_PIN + //#define Y_SERIAL_RX_PIN Y_SERIAL_TX_PIN + //#define Z_SERIAL_RX_PIN Z_SERIAL_TX_PIN + //#define E0_SERIAL_RX_PIN E0_SERIAL_TX_PIN + + // Reduce baud rate for software serial reliability + #if HAS_TMC_SW_SERIAL + #define TMC_BAUD_RATE 19200 + #endif +#endif diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3.h new file mode 100644 index 000000000000..2028cd9dd4d0 --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3.h @@ -0,0 +1,36 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * MKS Robin E3 (STM32F103RCT6) board pin assignments + */ + +#if HOTENDS > 1 || E_STEPPERS > 1 + #error "MKS Robin E3 supports up to 1 hotends / E-steppers. Comment out this line to continue." +#endif + +#ifndef BOARD_INFO_NAME + #define BOARD_INFO_NAME "MKS Robin E3" +#endif + +#include "pins_MKS_ROBIN_E3_common.h" diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3D.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3D.h new file mode 100644 index 000000000000..d1f6dece5c15 --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3D.h @@ -0,0 +1,67 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * MKS Robin E3D (STM32F103RCT6) board pin assignments + */ + +#if HOTENDS > 1 || E_STEPPERS > 1 + #error "MKS Robin E3D supports up to 1 hotends / E-steppers. Comment out this line to continue." +#endif + +#ifndef BOARD_INFO_NAME + #define BOARD_INFO_NAME "MKS Robin E3D" +#endif + +// +// Steppers +// +#ifndef X_CS_PIN + #define X_CS_PIN PC7 +#endif +#ifndef Y_CS_PIN + #define Y_CS_PIN PD2 +#endif +#ifndef Z_CS_PIN + #define Z_CS_PIN PC12 +#endif +#ifndef E0_CS_PIN + #define E0_CS_PIN PC11 +#endif + +// +// Software SPI pins for TMC2130 stepper drivers +// +#if ENABLED(TMC_USE_SW_SPI) + #ifndef TMC_SW_MOSI + #define TMC_SW_MOSI PB15 + #endif + #ifndef TMC_SW_MISO + #define TMC_SW_MISO PB14 + #endif + #ifndef TMC_SW_SCK + #define TMC_SW_SCK PB13 + #endif +#endif + +#include "pins_MKS_ROBIN_E3_common.h" diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3P.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3P.h new file mode 100644 index 000000000000..94a28953ccf3 --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3P.h @@ -0,0 +1,376 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * MKS Robin nano (STM32F130VET6) board pin assignments + */ + +#if NOT_TARGET(__STM32F1__) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#elif HOTENDS > 1 || E_STEPPERS > 1 + #error "MKS Robin e3p supports up to 1 hotends / E-steppers. Comment out this line to continue." +#elif HAS_FSMC_TFT + #error "MKS Robin e3p doesn't support FSMC-based TFT displays." +#endif + +#define BOARD_INFO_NAME "MKS Robin e3p" + +// +// Release PB4 (Y_ENABLE_PIN) from JTAG NRST role +// + +#define DISABLE_DEBUG + +// +// EEPROM +// +//#define FLASH_EEPROM_EMULATION +//#define SDCARD_EEPROM_EMULATION + +#if EITHER(NO_EEPROM_SELECTED, I2C_EEPROM) + #define I2C_EEPROM // EEPROM on I2C-0 + #define MARLIN_EEPROM_SIZE 0x1000 // 4KB +#endif + +// +// Note: MKS Robin board is using SPI2 interface. +// +//#define SPI_MODULE 2 +#define ENABLE_SPI2 + +// +// Limit Switches +// +#define X_DIAG_PIN PA15 +#define Y_DIAG_PIN PA12 +#define Z_DIAG_PIN PA11 +#define E0_DIAG_PIN PC4 + +#define X_STOP_PIN PA15 +#define Y_STOP_PIN PA12 +#define Z_MIN_PIN PA11 +#define Z_MAX_PIN PC4 + +// +// Steppers +// +#define X_ENABLE_PIN PE4 +#define X_STEP_PIN PE3 +#define X_DIR_PIN PE2 +#ifndef X_CS_PIN + #define X_CS_PIN PD5 +#endif + +#define Y_ENABLE_PIN PE1 +#define Y_STEP_PIN PE0 +#define Y_DIR_PIN PB9 +#ifndef Y_CS_PIN + #define Y_CS_PIN PD7 +#endif + +#define Z_ENABLE_PIN PB8 +#define Z_STEP_PIN PB5 +#define Z_DIR_PIN PB4 +#ifndef Z_CS_PIN + #define Z_CS_PIN PD4 +#endif + +#define E0_ENABLE_PIN PB3 +#define E0_STEP_PIN PD6 +#define E0_DIR_PIN PD3 +#ifndef E0_CS_PIN + #define E0_CS_PIN PD9 +#endif + +// +// Software SPI pins for TMC2130 stepper drivers +// +#if ENABLED(TMC_USE_SW_SPI) + #ifndef TMC_SW_MOSI + #define TMC_SW_MOSI PD14 + #endif + #ifndef TMC_SW_MISO + #define TMC_SW_MISO PD1 + #endif + #ifndef TMC_SW_SCK + #define TMC_SW_SCK PD0 + #endif +#endif + +#if HAS_TMC_UART + /** + * TMC2208/TMC2209 stepper drivers + * + * Hardware serial communication ports. + * If undefined software serial is used according to the pins below + */ + //#define X_HARDWARE_SERIAL Serial + //#define X2_HARDWARE_SERIAL Serial1 + //#define Y_HARDWARE_SERIAL Serial1 + //#define Y2_HARDWARE_SERIAL Serial1 + //#define Z_HARDWARE_SERIAL Serial1 + //#define Z2_HARDWARE_SERIAL Serial1 + //#define E0_HARDWARE_SERIAL Serial1 + //#define E1_HARDWARE_SERIAL Serial1 + //#define E2_HARDWARE_SERIAL Serial1 + //#define E3_HARDWARE_SERIAL Serial1 + //#define E4_HARDWARE_SERIAL Serial1 + + // + // Software serial + // + + #define X_SERIAL_TX_PIN PD5 + #define X_SERIAL_RX_PIN PD5 + + #define Y_SERIAL_TX_PIN PD7 + #define Y_SERIAL_RX_PIN PD7 + + #define Z_SERIAL_TX_PIN PD4 + #define Z_SERIAL_RX_PIN PD4 + + #define E0_SERIAL_TX_PIN PD9 + #define E0_SERIAL_RX_PIN PD9 + + // Reduce baud rate to improve software serial reliability + #define TMC_BAUD_RATE 19200 +#endif // TMC2208 || TMC2209 + +// +// Temperature Sensors +// +#define TEMP_0_PIN PC1 // TH1 +#define TEMP_BED_PIN PC0 // TB1 + +// +// Heaters / Fans +// +#define HEATER_0_PIN PC3 // HEATER1 +#define HEATER_BED_PIN PA0 // HOT BED + +#define FAN_PIN PB1 // FAN + +// +// Misc. Functions +// +#if HAS_TFT_LVGL_UI + //#define MKSPWC + #ifdef MKSPWC + #define SUICIDE_PIN PB2 // Enable MKSPWC SUICIDE PIN + #define SUICIDE_PIN_INVERTING false // Enable MKSPWC PIN STATE + #define KILL_PIN PA2 // Enable MKSPWC DET PIN + #define KILL_PIN_STATE true // Enable MKSPWC PIN STATE + #endif + + #define MT_DET_1_PIN PA4 // LVGL UI FILAMENT RUNOUT1 PIN + #define MT_DET_PIN_INVERTING false // LVGL UI filament RUNOUT PIN STATE + + #define WIFI_IO0_PIN PC13 // MKS ESP WIFI IO0 PIN + #define WIFI_IO1_PIN PC7 // MKS ESP WIFI IO1 PIN + #define WIFI_RESET_PIN PE9 // MKS ESP WIFI RESET PIN + + #if ENABLED(MKS_TEST) + #define MKS_TEST_POWER_LOSS_PIN PA2 // PW_DET + #define MKS_TEST_PS_ON_PIN PB0 // PW_OFF + #endif +#else + //#define POWER_LOSS_PIN PA2 // PW_DET + //#define PS_ON_PIN PB2 // PW_OFF + #define FIL_RUNOUT_PIN PA4 +#endif + +#define SERVO0_PIN PA8 // Enable BLTOUCH + +//#define LED_PIN PB2 + +// +// SD Card +// +#ifndef SDCARD_CONNECTION + #define SDCARD_CONNECTION ONBOARD +#endif + +#define SDIO_SUPPORT +#define SDIO_CLOCK 4500000 // 4.5 MHz +#define SD_DETECT_PIN PD12 +#define ONBOARD_SD_CS_PIN PC11 + +// +// LCD / Controller +// +#ifndef BEEPER_PIN + #define BEEPER_PIN PC5 +#endif + +/** + * Note: MKS Robin TFT screens use various TFT controllers. + * If the screen stays white, disable 'LCD_RESET_PIN' + * to let the bootloader init the screen. + */ + +#if HAS_SPI_TFT + + // Shared SPI TFT + + #define LCD_BACKLIGHT_PIN PD13 + + #define TOUCH_CS_PIN PE14 // SPI1_NSS + #define TOUCH_SCK_PIN PA5 // SPI1_SCK + #define TOUCH_MISO_PIN PA6 // SPI1_MISO + #define TOUCH_MOSI_PIN PA7 // SPI1_MOSI + + #define BTN_EN1 PE8 + #define BTN_EN2 PE11 + #define BTN_ENC PE13 + + #define TFT_CS_PIN PD11 + #define TFT_SCK_PIN PA5 + #define TFT_MISO_PIN PA6 + #define TFT_MOSI_PIN PA7 + #define TFT_DC_PIN PD10 + #define TFT_RST_PIN PC6 + #define TFT_A0_PIN TFT_DC_PIN + + #define TFT_RESET_PIN PC6 + #define TFT_BACKLIGHT_PIN PD13 + + #define TOUCH_BUTTONS_HW_SPI + #define TOUCH_BUTTONS_HW_SPI_DEVICE 1 + + #ifndef TFT_WIDTH + #define TFT_WIDTH 480 + #endif + #ifndef TFT_HEIGHT + #define TFT_HEIGHT 320 + #endif + + #define LCD_READ_ID 0xD3 + #define LCD_USE_DMA_SPI + +#endif + +#if ENABLED(SPI_GRAPHICAL_TFT) + // Emulated DOGM SPI + #ifndef GRAPHICAL_TFT_UPSCALE + #define GRAPHICAL_TFT_UPSCALE 3 + #endif + #ifndef TFT_PIXEL_OFFSET_Y + #define TFT_PIXEL_OFFSET_Y 32 + #endif + + #define BTN_ENC PE13 + #define BTN_EN1 PE8 + #define BTN_EN2 PE11 + + #define LCD_PINS_ENABLE PD13 + #define LCD_PINS_RS PC6 + +#elif ENABLED(TFT_480x320_SPI) + #define TFT_DRIVER ST7796 + #define TFT_BUFFER_SIZE 14400 +#endif + +// XPT2046 Touch Screen calibration +#if EITHER(HAS_TFT_LVGL_UI, TFT_480x320_SPI) + #ifndef XPT2046_X_CALIBRATION + #define XPT2046_X_CALIBRATION -17253 + #endif + #ifndef XPT2046_Y_CALIBRATION + #define XPT2046_Y_CALIBRATION 11579 + #endif + #ifndef XPT2046_X_OFFSET + #define XPT2046_X_OFFSET 514 + #endif + #ifndef XPT2046_Y_OFFSET + #define XPT2046_Y_OFFSET -24 + #endif +#elif ENABLED(SPI_GRAPHICAL_TFT) + #ifndef XPT2046_X_CALIBRATION + #define XPT2046_X_CALIBRATION -11386 + #endif + #ifndef XPT2046_Y_CALIBRATION + #define XPT2046_Y_CALIBRATION 8684 + #endif + #ifndef XPT2046_X_OFFSET + #define XPT2046_X_OFFSET 339 + #endif + #ifndef XPT2046_Y_OFFSET + #define XPT2046_Y_OFFSET -18 + #endif +#endif + +#if HAS_WIRED_LCD && !HAS_SPI_TFT + + // NON TFT Displays + + #if ENABLED(MKS_MINI_12864) + + // MKS MINI12864 and MKS LCD12864B + // If using MKS LCD12864A (Need to remove RPK2 resistor) + + #define LCD_BACKLIGHT_PIN -1 + #define LCD_RESET_PIN -1 + #define DOGLCD_A0 PD11 + #define DOGLCD_CS PE15 + #define DOGLCD_SCK PA5 + #define DOGLCD_MOSI PA7 + + // Required for MKS_MINI_12864 with this board + #define MKS_LCD12864B + #undef SHOW_BOOTSCREEN + + #else // !MKS_MINI_12864 + + #define LCD_PINS_D4 PE14 + #if ENABLED(ULTIPANEL) + #define LCD_PINS_D5 PE15 + #define LCD_PINS_D6 PD11 + #define LCD_PINS_D7 PD10 + #endif + + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(125) + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(125) + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(125) + #endif + + #endif // !MKS_MINI_12864 + +#endif // HAS_WIRED_LCD && !HAS_SPI_TFT + +#define HAS_SPI_FLASH 1 +#if HAS_SPI_FLASH + #define SPI_FLASH_SIZE 0x1000000 // 16MB + #define W25QXX_CS_PIN PB12 + #define W25QXX_MOSI_PIN PB15 + #define W25QXX_MISO_PIN PB14 + #define W25QXX_SCK_PIN PB13 +#endif + +#if ENABLED(SPEAKER) && BEEPER_PIN == PC5 + #error "MKS Robin nano default BEEPER_PIN is not a SPEAKER." +#endif diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3_common.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3_common.h new file mode 100644 index 000000000000..015e29bdbe60 --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3_common.h @@ -0,0 +1,185 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * MKS Robin E3 & E3D (STM32F103RCT6) common board pin assignments + */ + +#if NOT_TARGET(__STM32F1__) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#endif + +#define BOARD_WEBSITE_URL "github.com/makerbase-mks" + +//#define DISABLE_DEBUG +#define DISABLE_JTAG + +// +// EEPROM +// +#if EITHER(NO_EEPROM_SELECTED, FLASH_EEPROM_EMULATION) + #define FLASH_EEPROM_EMULATION + #define EEPROM_PAGE_SIZE (0x800U) // 2KB + #define EEPROM_START_ADDRESS (0x8000000UL + (STM32_FLASH_SIZE) * 1024UL - (EEPROM_PAGE_SIZE) * 2UL) + #define MARLIN_EEPROM_SIZE EEPROM_PAGE_SIZE // 2KB +#endif + +// +// Servos +// +#define SERVO0_PIN PA3 + +// +// Limit Switches +// +#define X_STOP_PIN PA12 +#define Y_STOP_PIN PA11 +#define Z_MIN_PIN PC6 +#define Z_MAX_PIN PB1 + +// +// Steppers +// +#define X_STEP_PIN PC0 +#define X_DIR_PIN PB2 +#define X_ENABLE_PIN PC13 + +#define Y_STEP_PIN PC2 +#define Y_DIR_PIN PB9 +#define Y_ENABLE_PIN PB12 + +#define Z_STEP_PIN PB7 +#define Z_DIR_PIN PB6 +#define Z_ENABLE_PIN PB8 + +#define E0_STEP_PIN PB4 +#define E0_DIR_PIN PB3 +#define E0_ENABLE_PIN PB5 + +#if HAS_TMC220x + /** + * TMC2208/TMC2209 stepper drivers + * + * Hardware serial communication ports. + * If undefined software serial is used according to the pins below + */ + //#define X_HARDWARE_SERIAL MSerial1 + //#define Y_HARDWARE_SERIAL MSerial1 + //#define Z_HARDWARE_SERIAL MSerial1 + //#define E0_HARDWARE_SERIAL MSerial1 + + // + // Software serial + // + #define X_SERIAL_TX_PIN PC7 + #define X_SERIAL_RX_PIN PC7 + + #define Y_SERIAL_TX_PIN PD2 + #define Y_SERIAL_RX_PIN PD2 + + #define Z_SERIAL_TX_PIN PC12 + #define Z_SERIAL_RX_PIN PC12 + + #define E0_SERIAL_TX_PIN PC11 + #define E0_SERIAL_RX_PIN PC11 + + // Reduce baud rate to improve software serial reliability + #define TMC_BAUD_RATE 19200 +#endif + +// +// Heaters 0,1 / Fans / Bed +// +#define HEATER_0_PIN PC9 +#define FAN_PIN PA8 +#define HEATER_BED_PIN PC8 + +// +// Temperature Sensors +// +#define TEMP_BED_PIN PA1 // TB +#define TEMP_0_PIN PA0 // TH1 + +#define FIL_RUNOUT_PIN PB10 // MT_DET + +/** + * _____ _____ _____ + * (BEEPER) PC1 | 1 2 | PC3 (BTN_ENC) (MISO) PB14 | 1 2 | PB13 (SD_SCK) 5V | 1 2 | GND + * (LCD_EN) PA4 | 3 4 | PA5 (LCD_RS) (BTN_EN1) PB11 | 3 4 | PA15 (SD_SS) (LCD_EN) PA4 | 3 4 | PA5 (LCD_RS) + * (LCD_D4) PA6 | 5 6 PA7 (LCD_D5) (BTN_EN2) PB0 | 5 6 PB15 (SD_MOSI) (LCD_D4) PA6 | 5 6 PB0 (BTN_EN2) + * (LCD_D6) PC4 | 7 8 | PC5 (LCD_D7) (SD_DETECT) PC10 | 7 8 | RESET RESET | 7 8 | PB11 (BTN_EN1) + * GND | 9 10| 5V GND | 9 10| NC (BTN_ENC) PC3 | 9 10| PC1 (BEEPER) + * ----- ----- ----- + * EXP1 EXP2 EXP3 + */ +#if HAS_WIRED_LCD + + #define BEEPER_PIN PC1 + #define BTN_ENC PC3 + #define LCD_PINS_ENABLE PA4 + #define LCD_PINS_RS PA5 + #define BTN_EN1 PB11 + #define BTN_EN2 PB0 + + // MKS MINI12864 and MKS LCD12864B; If using MKS LCD12864A (Need to remove RPK2 resistor) + #if ENABLED(MKS_MINI_12864) + + #define LCD_BACKLIGHT_PIN -1 + #define LCD_RESET_PIN -1 + #define DOGLCD_A0 PC4 + #define DOGLCD_CS PA7 + #define DOGLCD_SCK PB13 + #define DOGLCD_MOSI PB15 + + #else + + #define LCD_PINS_D4 PA6 + #if ENABLED(ULTIPANEL) + #define LCD_PINS_D5 PA7 + #define LCD_PINS_D6 PC4 + #define LCD_PINS_D7 PC5 + #endif + + #endif // !MKS_MINI_12864 + +#endif // HAS_WIRED_LCD + +// +// SD Card +// +#define ENABLE_SPI2 +#define SD_DETECT_PIN PC10 +#define SCK_PIN PB13 +#define MISO_PIN PB14 +#define MOSI_PIN PB15 +#define SS_PIN PA15 + +#ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(125) +#endif +#ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(125) +#endif +#ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(125) +#endif diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE.h new file mode 100644 index 000000000000..aa1ccedb3550 --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE.h @@ -0,0 +1,143 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(__STM32F1__) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#elif HOTENDS > 1 || E_STEPPERS > 1 + #error "MKS Robin Lite supports only 1 hotend / E-stepper. Comment out this line to continue." +#endif + +#ifndef BOARD_INFO_NAME + #define BOARD_INFO_NAME "MKS Robin Lite" +#endif +#define BOARD_WEBSITE_URL "github.com/makerbase-mks" + +//#define DISABLE_DEBUG +#define DISABLE_JTAG +#define ENABLE_SPI2 + +// +// Limit Switches +// +#define X_STOP_PIN PC13 +#define Y_STOP_PIN PC0 +#define Z_MIN_PIN PC12 +#define Z_MAX_PIN PB9 + +// +// Steppers +// +#define X_STEP_PIN PC6 +#define X_DIR_PIN PB12 +#define X_ENABLE_PIN PB10 + +#define Y_STEP_PIN PB11 +#define Y_DIR_PIN PB2 +#define Y_ENABLE_PIN PB10 + +#define Z_STEP_PIN PB1 +#define Z_DIR_PIN PC5 +#define Z_ENABLE_PIN PB10 + +#define E0_STEP_PIN PC4 +#define E0_DIR_PIN PA5 +#define E0_ENABLE_PIN PA4 + +// +// Heaters / Fans +// +#define HEATER_0_PIN PC9 +#define FAN_PIN PA8 +#define HEATER_BED_PIN PC8 + +// +// Temperature Sensors +// +#define TEMP_BED_PIN PA1 +#define TEMP_0_PIN PA0 + +#define FIL_RUNOUT_PIN PB8 // MT_DET + +// +// LCD Pins +// +#if HAS_WIRED_LCD + #define BEEPER_PIN PD2 + #define BTN_ENC PB3 + #define LCD_PINS_RS PC3 + + #define BTN_EN1 PB5 + #define BTN_EN2 PB4 + + #define LCD_PINS_ENABLE PC2 + + #if ENABLED(MKS_MINI_12864) + + #define LCD_BACKLIGHT_PIN -1 + #define LCD_RESET_PIN -1 + #define DOGLCD_A0 PC1 + #define DOGLCD_CS PC2 + #define DOGLCD_SCK PB13 + #define DOGLCD_MOSI PB15 + + #else // !MKS_MINI_12864 + + #define LCD_PINS_D4 PC1 + #if ENABLED(ULTIPANEL) + #define LCD_PINS_D5 -1 + #define LCD_PINS_D6 -1 + #define LCD_PINS_D7 -1 + #endif + + #endif // !MKS_MINI_12864 + + #if HAS_MARLINUI_U8GLIB + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(125) + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(125) + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(125) + #endif + #endif + +#endif // HAS_WIRED_LCD + +// Motor current PWM pins +#define MOTOR_CURRENT_PWM_XY_PIN PB0 +#define MOTOR_CURRENT_PWM_Z_PIN PA7 +#define MOTOR_CURRENT_PWM_E_PIN PA6 +#define MOTOR_CURRENT_PWM_RANGE (65535/10/3.3) // (255 * (1000mA / 65535)) * 257 = 1000 is equal 1.6v Vref in turn equal 1Amp +#define DEFAULT_PWM_MOTOR_CURRENT { 1000, 1000, 1000 } // 1.05Amp per driver, here is XY, Z and E. This values determined empirically. + +// +// SD Card +// +#define ENABLE_SPI2 +#define SD_DETECT_PIN PC10 +#define SCK_PIN PB13 +#define MISO_PIN P1B4 +#define MOSI_PIN P1B5 +#define SS_PIN PA15 diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE3.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE3.h new file mode 100644 index 000000000000..d5318b8e8787 --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE3.h @@ -0,0 +1,155 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * MKS Robin Lite 3 (STM32F103RCT6) board pin assignments + */ + +#if NOT_TARGET(__STM32F1__) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#elif HOTENDS > 2 || E_STEPPERS > 2 + #error "MKS Robin Lite3 supports up to 2 hotends / E-steppers. Comment out this line to continue." +#endif + +#ifndef BOARD_INFO_NAME + #define BOARD_INFO_NAME "MKS Robin Lite3" +#endif +#define BOARD_WEBSITE_URL "github.com/makerbase-mks" + +//#define DISABLE_DEBUG +#define DISABLE_JTAG +#define ENABLE_SPI2 + +// +// Servos +// +#define SERVO0_PIN PA3 + +// +// Limit Switches +// +#define X_STOP_PIN PA12 +#define Y_STOP_PIN PA11 +#define Z_MIN_PIN PC6 +#define Z_MAX_PIN PB1 + +// +// Steppers +// +#define X_STEP_PIN PC0 +#define X_DIR_PIN PB2 +#define X_ENABLE_PIN PC13 + +#define Y_STEP_PIN PC2 +#define Y_DIR_PIN PB9 +#define Y_ENABLE_PIN PB12 + +#define Z_STEP_PIN PB7 +#define Z_DIR_PIN PB6 +#define Z_ENABLE_PIN PB8 + +#define E0_STEP_PIN PB4 +#define E0_DIR_PIN PB3 +#define E0_ENABLE_PIN PB5 + +#define E1_STEP_PIN PC12 +#define E1_DIR_PIN PC11 +#define E1_ENABLE_PIN PD2 + +// +// Heaters 0,1 / Fans / Bed +// +#define HEATER_0_PIN PC9 +#define HEATER_1_PIN PC7 +#define FAN_PIN PA8 +#define HEATER_BED_PIN PC8 + +// +// Temperature Sensors +// +#define TEMP_BED_PIN PA1 //TB +#define TEMP_0_PIN PA0 //TH1 +#define TEMP_1_PIN PA2 //TH2 + +#define FIL_RUNOUT_PIN PB10 // MT_DET + +// +// LCD Pins +// +#if HAS_WIRED_LCD + + #define BEEPER_PIN PC1 + #define BTN_ENC PC3 + #define LCD_PINS_ENABLE PA4 + #define LCD_PINS_RS PA5 + #define BTN_EN1 PB11 + #define BTN_EN2 PB0 + + // MKS MINI12864 and MKS LCD12864B; If using MKS LCD12864A (Need to remove RPK2 resistor) + #if ENABLED(MKS_MINI_12864) + + #define LCD_BACKLIGHT_PIN -1 + #define LCD_RESET_PIN -1 + #define DOGLCD_A0 PC4 + #define DOGLCD_CS PA7 + #define DOGLCD_SCK PB13 + #define DOGLCD_MOSI PB15 + + #elif IS_TFTGLCD_PANEL + + #if ENABLED(TFTGLCD_PANEL_SPI) + #define TFTGLCD_CS PB11 + #endif + + #else // !MKS_MINI_12864 + + #define LCD_PINS_D4 PA6 + #if ENABLED(ULTIPANEL) + #define LCD_PINS_D5 PA7 + #define LCD_PINS_D6 PC4 + #define LCD_PINS_D7 PC5 + #endif + + #endif // !MKS_MINI_12864 + +#endif // HAS_WIRED_LCD + +// +// SD Card +// +#define ENABLE_SPI2 +#define SD_DETECT_PIN PC10 +#define SCK_PIN PB13 +#define MISO_PIN PB14 +#define MOSI_PIN PB15 +#define SS_PIN PA15 + +#ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(125) +#endif +#ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(125) +#endif +#ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(125) +#endif diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_MINI.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_MINI.h new file mode 100644 index 000000000000..2b099b3e9372 --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_MINI.h @@ -0,0 +1,210 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * MKS Robin mini (STM32F130VET6) board pin assignments + */ + +#if NOT_TARGET(__STM32F1__) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#elif HOTENDS > 1 || E_STEPPERS > 1 + #error "MKS Robin mini only supports 1 hotend / E-stepper. Comment out this line to continue." +#endif + +#define BOARD_INFO_NAME "MKS Robin Mini" + +// +// Release PB4 (Y_ENABLE_PIN) from JTAG NRST role +// +#define DISABLE_DEBUG + +// +// EEPROM +// +#if EITHER(NO_EEPROM_SELECTED, FLASH_EEPROM_EMULATION) + #define FLASH_EEPROM_EMULATION + #define EEPROM_PAGE_SIZE (0x800U) // 2KB + #define EEPROM_START_ADDRESS (0x8000000UL + (STM32_FLASH_SIZE) * 1024UL - (EEPROM_PAGE_SIZE) * 2UL) + #define MARLIN_EEPROM_SIZE EEPROM_PAGE_SIZE // 2KB +#endif + +#define ENABLE_SPI2 + +// +// Limit Switches +// +#define X_STOP_PIN PA15 +#define Y_STOP_PIN PA12 +#define Z_MIN_PIN PA11 +#define Z_MAX_PIN PC4 + +#ifndef FIL_RUNOUT_PIN + #define FIL_RUNOUT_PIN PA4 // MT_DET +#endif + +// +// Steppers +// +#define X_ENABLE_PIN PE4 +#define X_STEP_PIN PE3 +#define X_DIR_PIN PE2 + +#define Y_ENABLE_PIN PE1 +#define Y_STEP_PIN PE0 +#define Y_DIR_PIN PB9 + +#define Z_ENABLE_PIN PB8 +#define Z_STEP_PIN PB5 +#define Z_DIR_PIN PB4 + +#define E0_ENABLE_PIN PB3 +#define E0_STEP_PIN PD6 +#define E0_DIR_PIN PD3 + +// Motor current PWM pins +#define MOTOR_CURRENT_PWM_XY_PIN PA6 +#define MOTOR_CURRENT_PWM_Z_PIN PA7 +#define MOTOR_CURRENT_PWM_E_PIN PB0 +#define MOTOR_CURRENT_PWM_RANGE 1500 // (255 * (1000mA / 65535)) * 257 = 1000 is equal 1.6v Vref in turn equal 1Amp +#ifndef DEFAULT_PWM_MOTOR_CURRENT + #define DEFAULT_PWM_MOTOR_CURRENT { 800, 800, 800 } +#endif +// +// Temperature Sensors +// +#define TEMP_0_PIN PC1 // TH1 +#define TEMP_BED_PIN PC0 // TB1 + +// +// Heaters / Fans +// +#define HEATER_0_PIN PC3 +#define HEATER_BED_PIN PA0 + +#define FAN_PIN PB1 // FAN + +// +// Misc. Functions +// +#define POWER_LOSS_PIN PA2 // PW_DET +#define PS_ON_PIN PA3 // PW_OFF + +#define SERVO0_PIN PA8 // Enable BLTOUCH support on IO0 (WIFI connector) + +#define MT_DET_1_PIN PA4 +#define MT_DET_PIN_INVERTING false + +#define WIFI_IO0_PIN PC13 + +// +// SD Card +// +#ifndef SDCARD_CONNECTION + #define SDCARD_CONNECTION ONBOARD +#endif + +#define SDIO_SUPPORT +#define SDIO_CLOCK 4500000 // 4.5 MHz +#define SD_DETECT_PIN PD12 +#define ONBOARD_SPI_DEVICE 1 // SPI1 +#define ONBOARD_SD_CS_PIN PC11 + +// +// LCD / Controller +// +#define BEEPER_PIN PC5 + +/** + * Note: MKS Robin TFT screens use various TFT controllers. + * If the screen stays white, disable 'LCD_RESET_PIN' + * to let the bootloader init the screen. + */ +#if ENABLED(TOUCH_SCREEN) + #ifndef XPT2046_X_CALIBRATION + #define XPT2046_X_CALIBRATION 12033 + #endif + #ifndef XPT2046_Y_CALIBRATION + #define XPT2046_Y_CALIBRATION -9047 + #endif + #ifndef XPT2046_X_OFFSET + #define XPT2046_X_OFFSET -30 + #endif + #ifndef XPT2046_Y_OFFSET + #define XPT2046_Y_OFFSET 254 + #endif +#endif + +#if ENABLED(FSMC_GRAPHICAL_TFT) + + #define FSMC_CS_PIN PD7 // NE4 + #define FSMC_RS_PIN PD11 // A0 + + #define LCD_USE_DMA_FSMC // Use DMA transfers to send data to the TFT + #define FSMC_DMA_DEV DMA2 + #define FSMC_DMA_CHANNEL DMA_CH5 + + #define LCD_RESET_PIN PC6 // FSMC_RST + #define LCD_BACKLIGHT_PIN PD13 + + #if NEED_TOUCH_PINS + #define TOUCH_CS_PIN PC2 // SPI2_NSS + #define TOUCH_SCK_PIN PB13 // SPI2_SCK + #define TOUCH_MISO_PIN PB14 // SPI2_MISO + #define TOUCH_MOSI_PIN PB15 // SPI2_MOSI + #endif + +#elif ENABLED(TFT_320x240) //TFT32/28 + + #define TFT_RESET_PIN PC6 + #define TFT_BACKLIGHT_PIN PD13 + + #define LCD_USE_DMA_FSMC // Use DMA transfers to send data to the TFT + #define FSMC_CS_PIN PD7 + #define FSMC_RS_PIN PD11 + #define FSMC_DMA_DEV DMA2 + #define FSMC_DMA_CHANNEL DMA_CH5 + + #define TOUCH_CS_PIN PC2 // SPI2_NSS + #define TOUCH_SCK_PIN PB13 // SPI2_SCK + #define TOUCH_MISO_PIN PB14 // SPI2_MISO + #define TOUCH_MOSI_PIN PB15 // SPI2_MOSI + + #define TFT_DRIVER ILI9341 + #define TFT_BUFFER_SIZE 14400 + + // YV for normal screen mounting + #define ILI9341_ORIENTATION ILI9341_MADCTL_MY | ILI9341_MADCTL_MV + // XV for 180° rotated screen mounting + //#define ILI9341_ORIENTATION ILI9341_MADCTL_MX | ILI9341_MADCTL_MV + + #define ILI9341_COLOR_RGB +#endif + +#define HAS_SPI_FLASH 1 +#if HAS_SPI_FLASH + #define SPI_FLASH_SIZE 0x1000000 // 16MB + #define W25QXX_CS_PIN PB12 // Flash chip-select + #define W25QXX_MOSI_PIN PB15 + #define W25QXX_MISO_PIN PB14 + #define W25QXX_SCK_PIN PB13 +#endif diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO.h new file mode 100644 index 000000000000..16d6d2ffc442 --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO.h @@ -0,0 +1,249 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * MKS Robin nano (STM32F130VET6) board pin assignments + */ + +#if NOT_TARGET(STM32F1, STM32F1xx) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#elif HOTENDS > 2 || E_STEPPERS > 2 + #error "MKS Robin nano supports up to 2 hotends / E-steppers. Comment out this line to continue." +#endif + +#define BOARD_INFO_NAME "MKS Robin Nano" + +// +// Release PB4 (Y_ENABLE_PIN) from JTAG NRST role +// +#define DISABLE_JTAG + +// +// EEPROM +// +#if EITHER(NO_EEPROM_SELECTED, FLASH_EEPROM_EMULATION) + #define FLASH_EEPROM_EMULATION + #define EEPROM_PAGE_SIZE (0x800U) // 2KB + #define EEPROM_START_ADDRESS (0x8000000UL + (STM32_FLASH_SIZE) * 1024UL - (EEPROM_PAGE_SIZE) * 2UL) + #define MARLIN_EEPROM_SIZE EEPROM_PAGE_SIZE // 2KB +#endif + +#define ENABLE_SPI2 + +// +// Limit Switches +// +#define X_STOP_PIN PA15 +#define Y_STOP_PIN PA12 +#define Z_MIN_PIN PA11 +#define Z_MAX_PIN PC4 + +// +// Steppers +// +#define X_ENABLE_PIN PE4 +#define X_STEP_PIN PE3 +#define X_DIR_PIN PE2 + +#define Y_ENABLE_PIN PE1 +#define Y_STEP_PIN PE0 +#define Y_DIR_PIN PB9 + +#define Z_ENABLE_PIN PB8 +#define Z_STEP_PIN PB5 +#define Z_DIR_PIN PB4 + +#define E0_ENABLE_PIN PB3 +#define E0_STEP_PIN PD6 +#define E0_DIR_PIN PD3 + +#define E1_ENABLE_PIN PA3 +#define E1_STEP_PIN PA6 +#define E1_DIR_PIN PA1 + +// +// Temperature Sensors +// +#define TEMP_0_PIN PC1 // TH1 +#define TEMP_1_PIN PC2 // TH2 +#define TEMP_BED_PIN PC0 // TB1 + +// +// Heaters / Fans +// +#ifndef HEATER_0_PIN + #define HEATER_0_PIN PC3 +#endif +#if HOTENDS == 1 + #ifndef FAN1_PIN + #define FAN1_PIN PB0 + #endif +#else + #ifndef HEATER_1_PIN + #define HEATER_1_PIN PB0 + #endif +#endif +#ifndef FAN_PIN + #define FAN_PIN PB1 // FAN +#endif +#ifndef HEATER_BED_PIN + #define HEATER_BED_PIN PA0 +#endif + +// +// Thermocouples +// +//#define MAX6675_SS_PIN PE5 // TC1 - CS1 +//#define MAX6675_SS_PIN PE6 // TC2 - CS2 + +// +// Misc. Functions +// +#if HAS_TFT_LVGL_UI + //#define MKSPWC + #ifdef MKSPWC + #define SUICIDE_PIN PB2 // Enable MKSPWC SUICIDE PIN + #define SUICIDE_PIN_INVERTING false // Enable MKSPWC PIN STATE + #define KILL_PIN PA2 // Enable MKSPWC DET PIN + #define KILL_PIN_STATE true // Enable MKSPWC PIN STATE + #endif + + #define MT_DET_1_PIN PA4 // LVGL UI FILAMENT RUNOUT1 PIN + #define MT_DET_2_PIN PE6 // LVGL UI FILAMENT RUNOUT2 PIN + #define MT_DET_PIN_INVERTING false // LVGL UI filament RUNOUT PIN STATE + + #define WIFI_IO0_PIN PC13 // MKS ESP WIFI IO0 PIN + #define WIFI_IO1_PIN PC7 // MKS ESP WIFI IO1 PIN + #define WIFI_RESET_PIN PA5 // MKS ESP WIFI RESET PIN +#else + //#define POWER_LOSS_PIN PA2 // PW_DET + //#define PS_ON_PIN PB2 // PW_OFF + #define FIL_RUNOUT_PIN PA4 + #define FIL_RUNOUT2_PIN PE6 +#endif + +#define SERVO0_PIN PA8 // Enable BLTOUCH support + +//#define LED_PIN PB2 + +// +// SD Card +// +#ifndef SDCARD_CONNECTION + #define SDCARD_CONNECTION ONBOARD +#endif + +#define SDIO_SUPPORT +#define SDIO_CLOCK 4500000 // 4.5 MHz +#define SD_DETECT_PIN PD12 +#define ONBOARD_SD_CS_PIN PC11 + +// +// LCD / Controller +// +#define BEEPER_PIN PC5 + +/** + * Note: MKS Robin TFT screens use various TFT controllers. + * If the screen stays white, disable 'LCD_RESET_PIN' + * to let the bootloader init the screen. + */ + +// Shared FSMC Configs +#if HAS_FSMC_TFT + #define DOGLCD_MOSI -1 // prevent redefine Conditionals_post.h + #define DOGLCD_SCK -1 + + #define FSMC_CS_PIN PD7 // NE4 + #define FSMC_RS_PIN PD11 // A0 + + #define TOUCH_CS_PIN PA7 // SPI2_NSS + #define TOUCH_SCK_PIN PB13 // SPI2_SCK + #define TOUCH_MISO_PIN PB14 // SPI2_MISO + #define TOUCH_MOSI_PIN PB15 // SPI2_MOSI + + #define TFT_RESET_PIN PC6 // FSMC_RST + #define TFT_BACKLIGHT_PIN PD13 + + #define LCD_USE_DMA_FSMC // Use DMA transfers to send data to the TFT + #define FSMC_CS_PIN PD7 + #define FSMC_RS_PIN PD11 + #define FSMC_DMA_DEV DMA2 + #define FSMC_DMA_CHANNEL DMA_CH5 + + #define TOUCH_BUTTONS_HW_SPI + #define TOUCH_BUTTONS_HW_SPI_DEVICE 2 + + #define TFT_BUFFER_SIZE 14400 +#endif + +// XPT2046 Touch Screen calibration +#if EITHER(TFT_LVGL_UI_FSMC, TFT_480x320) + #ifndef XPT2046_X_CALIBRATION + #define XPT2046_X_CALIBRATION 17880 + #endif + #ifndef XPT2046_Y_CALIBRATION + #define XPT2046_Y_CALIBRATION -12234 + #endif + #ifndef XPT2046_X_OFFSET + #define XPT2046_X_OFFSET -45 + #endif + #ifndef XPT2046_Y_OFFSET + #define XPT2046_Y_OFFSET 349 + #endif +#elif ENABLED(TFT_CLASSIC_UI) + #ifndef XPT2046_X_CALIBRATION + #define XPT2046_X_CALIBRATION 12149 + #endif + #ifndef XPT2046_Y_CALIBRATION + #define XPT2046_Y_CALIBRATION -8746 + #endif + #ifndef XPT2046_X_OFFSET + #define XPT2046_X_OFFSET -35 + #endif + #ifndef XPT2046_Y_OFFSET + #define XPT2046_Y_OFFSET 256 + #endif +#elif ENABLED(TFT_320x240) + #ifndef XPT2046_X_CALIBRATION + #define XPT2046_X_CALIBRATION -12246 + #endif + #ifndef XPT2046_Y_CALIBRATION + #define XPT2046_Y_CALIBRATION 9453 + #endif + #ifndef XPT2046_X_OFFSET + #define XPT2046_X_OFFSET 360 + #endif + #ifndef XPT2046_Y_OFFSET + #define XPT2046_Y_OFFSET -22 + #endif +#endif + +#define HAS_SPI_FLASH 1 +#if HAS_SPI_FLASH + #define SPI_FLASH_SIZE 0x1000000 // 16MB + #define W25QXX_CS_PIN PB12 + #define W25QXX_MOSI_PIN PB15 + #define W25QXX_MISO_PIN PB14 + #define W25QXX_SCK_PIN PB13 +#endif diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO_V2.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO_V2.h new file mode 100644 index 000000000000..846fe80a08fa --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO_V2.h @@ -0,0 +1,392 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * MKS Robin nano (STM32F130VET6) board pin assignments + */ + +#if NOT_TARGET(__STM32F1__) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#elif HOTENDS > 2 || E_STEPPERS > 2 + #error "MKS Robin nano supports up to 2 hotends / E-steppers. Comment out this line to continue." +#elif HAS_FSMC_TFT + #error "MKS Robin nano v2 doesn't support FSMC-based TFT displays." +#endif + +#define BOARD_INFO_NAME "MKS Robin nano V2.0" + +// +// Release PB4 (Y_ENABLE_PIN) from JTAG NRST role +// + +#define DISABLE_DEBUG + +// +// EEPROM +// +//#define FLASH_EEPROM_EMULATION +//#define SDCARD_EEPROM_EMULATION + +#if EITHER(NO_EEPROM_SELECTED, I2C_EEPROM) + #define I2C_EEPROM // EEPROM on I2C-0 + #define MARLIN_EEPROM_SIZE 0x1000 // 4KB +#endif + +// +// Note: MKS Robin board is using SPI2 interface. +// +//#define SPI_MODULE 2 +#define ENABLE_SPI2 + +// +// Limit Switches +// +#define X_DIAG_PIN PA15 +#define Y_DIAG_PIN PA12 +#define Z_DIAG_PIN PA11 +#define E0_DIAG_PIN PC4 +#define E1_DIAG_PIN PE7 + +#define X_STOP_PIN PA15 +#define Y_STOP_PIN PA12 +#define Z_MIN_PIN PA11 +#define Z_MAX_PIN PC4 + +// +// Steppers +// +#define X_ENABLE_PIN PE4 +#define X_STEP_PIN PE3 +#define X_DIR_PIN PE2 +#ifndef X_CS_PIN + #define X_CS_PIN PD5 +#endif + +#define Y_ENABLE_PIN PE1 +#define Y_STEP_PIN PE0 +#define Y_DIR_PIN PB9 +#ifndef Y_CS_PIN + #define Y_CS_PIN PD7 +#endif + +#define Z_ENABLE_PIN PB8 +#define Z_STEP_PIN PB5 +#define Z_DIR_PIN PB4 +#ifndef Z_CS_PIN + #define Z_CS_PIN PD4 +#endif + +#define E0_ENABLE_PIN PB3 +#define E0_STEP_PIN PD6 +#define E0_DIR_PIN PD3 +#ifndef E0_CS_PIN + #define E0_CS_PIN PD9 +#endif + +#define E1_ENABLE_PIN PA3 +#define E1_STEP_PIN PD15 +#define E1_DIR_PIN PA1 +#ifndef E1_CS_PIN + #define E1_CS_PIN PD8 +#endif + +// +// Software SPI pins for TMC2130 stepper drivers +// +#if ENABLED(TMC_USE_SW_SPI) + #ifndef TMC_SW_MOSI + #define TMC_SW_MOSI PD14 + #endif + #ifndef TMC_SW_MISO + #define TMC_SW_MISO PD1 + #endif + #ifndef TMC_SW_SCK + #define TMC_SW_SCK PD0 + #endif +#endif + +#if HAS_TMC_UART + /** + * TMC2208/TMC2209 stepper drivers + * + * Hardware serial communication ports. + * If undefined software serial is used according to the pins below + */ + //#define X_HARDWARE_SERIAL MSerial1 + //#define Y_HARDWARE_SERIAL MSerial1 + //#define Z_HARDWARE_SERIAL MSerial1 + //#define E0_HARDWARE_SERIAL MSerial1 + //#define E1_HARDWARE_SERIAL MSerial1 + + // + // Software serial + // + + #define X_SERIAL_TX_PIN PD5 + #define X_SERIAL_RX_PIN PD5 + + #define Y_SERIAL_TX_PIN PD7 + #define Y_SERIAL_RX_PIN PD7 + + #define Z_SERIAL_TX_PIN PD4 + #define Z_SERIAL_RX_PIN PD4 + + #define E0_SERIAL_TX_PIN PD9 + #define E0_SERIAL_RX_PIN PD9 + + #define E1_SERIAL_TX_PIN PD8 + #define E1_SERIAL_RX_PIN PD8 + + // Reduce baud rate to improve software serial reliability + #define TMC_BAUD_RATE 19200 +#endif // TMC2208 || TMC2209 + +// +// Temperature Sensors +// +#define TEMP_0_PIN PC1 // TH1 +#define TEMP_1_PIN PC2 // TH2 +#define TEMP_BED_PIN PC0 // TB1 + +// +// Heaters / Fans +// +#define HEATER_0_PIN PC3 // HEATER1 +#define HEATER_1_PIN PB0 // HEATER2 +#define HEATER_BED_PIN PA0 // HOT BED + +#define FAN_PIN PB1 // FAN + +// +// Thermocouples +// +//#define MAX6675_SS_PIN PE5 // TC1 - CS1 +//#define MAX6675_SS_PIN PE6 // TC2 - CS2 + +// +// Misc. Functions +// +#if HAS_TFT_LVGL_UI + //#define MKSPWC + #ifdef MKSPWC + #define SUICIDE_PIN PB2 // Enable MKSPWC SUICIDE PIN + #define SUICIDE_PIN_INVERTING false // Enable MKSPWC PIN STATE + #define KILL_PIN PA2 // Enable MKSPWC DET PIN + #define KILL_PIN_STATE true // Enable MKSPWC PIN STATE + #endif + + #define MT_DET_1_PIN PA4 // LVGL UI FILAMENT RUNOUT1 PIN + #define MT_DET_2_PIN PE6 // LVGL UI FILAMENT RUNOUT2 PIN + #define MT_DET_PIN_INVERTING false // LVGL UI filament RUNOUT PIN STATE + + #define WIFI_IO0_PIN PC13 // MKS ESP WIFI IO0 PIN + #define WIFI_IO1_PIN PC7 // MKS ESP WIFI IO1 PIN + #define WIFI_RESET_PIN PE9 // MKS ESP WIFI RESET PIN + + #if ENABLED(MKS_TEST) + #define MKS_TEST_POWER_LOSS_PIN PA2 // PW_DET + #define MKS_TEST_PS_ON_PIN PB2 // PW_OFF + #endif +#else + //#define POWER_LOSS_PIN PA2 // PW_DET + //#define PS_ON_PIN PB2 // PW_OFF + #define FIL_RUNOUT_PIN PA4 + #define FIL_RUNOUT2_PIN PE6 +#endif + +#define SERVO0_PIN PA8 // Enable BLTOUCH + +//#define LED_PIN PB2 + +// +// SD Card +// +#ifndef SDCARD_CONNECTION + #define SDCARD_CONNECTION ONBOARD +#endif + +#define SDIO_SUPPORT +#define SDIO_CLOCK 4500000 // 4.5 MHz +#define SD_DETECT_PIN PD12 +#define ONBOARD_SD_CS_PIN PC11 + +// +// LCD / Controller +// + +/** + * Note: MKS Robin TFT screens use various TFT controllers. + * If the screen stays white, disable 'LCD_RESET_PIN' + * to let the bootloader init the screen. + */ + +#if HAS_SPI_TFT + + // Shared SPI TFT + + #define LCD_BACKLIGHT_PIN PD13 + + #define TOUCH_CS_PIN PE14 // SPI1_NSS + #define TOUCH_SCK_PIN PA5 // SPI1_SCK + #define TOUCH_MISO_PIN PA6 // SPI1_MISO + #define TOUCH_MOSI_PIN PA7 // SPI1_MOSI + + #define BTN_EN1 PE8 + #define BTN_EN2 PE11 + #define BTN_ENC PE13 + + #define TFT_CS_PIN PD11 + #define TFT_SCK_PIN PA5 + #define TFT_MISO_PIN PA6 + #define TFT_MOSI_PIN PA7 + #define TFT_DC_PIN PD10 + #define TFT_RST_PIN PC6 + #define TFT_A0_PIN TFT_DC_PIN + + #define TFT_RESET_PIN PC6 + #define TFT_BACKLIGHT_PIN PD13 + + #define TOUCH_BUTTONS_HW_SPI + #define TOUCH_BUTTONS_HW_SPI_DEVICE 1 + + #define LCD_USE_DMA_SPI + +#endif + +#if ENABLED(TFT_CLASSIC_UI) + // Emulated DOGM SPI + #ifndef GRAPHICAL_TFT_UPSCALE + #define GRAPHICAL_TFT_UPSCALE 3 + #endif + #ifndef TFT_PIXEL_OFFSET_Y + #define TFT_PIXEL_OFFSET_Y 32 + #endif + + #define BTN_ENC PE13 + #define BTN_EN1 PE8 + #define BTN_EN2 PE11 + + #define LCD_PINS_ENABLE PD13 + #define LCD_PINS_RS PC6 + +#elif ENABLED(TFT_COLOR_UI) + #define TFT_BUFFER_SIZE 14400 +#endif + +// XPT2046 Touch Screen calibration +#if EITHER(TFT_LVGL_UI, TFT_COLOR_UI) + #ifndef XPT2046_X_CALIBRATION + #define XPT2046_X_CALIBRATION -17253 + #endif + #ifndef XPT2046_Y_CALIBRATION + #define XPT2046_Y_CALIBRATION 11579 + #endif + #ifndef XPT2046_X_OFFSET + #define XPT2046_X_OFFSET 514 + #endif + #ifndef XPT2046_Y_OFFSET + #define XPT2046_Y_OFFSET -24 + #endif +#elif ENABLED(TFT_CLASSIC_UI) + #ifndef XPT2046_X_CALIBRATION + #define XPT2046_X_CALIBRATION -11386 + #endif + #ifndef XPT2046_Y_CALIBRATION + #define XPT2046_Y_CALIBRATION 8684 + #endif + #ifndef XPT2046_X_OFFSET + #define XPT2046_X_OFFSET 339 + #endif + #ifndef XPT2046_Y_OFFSET + #define XPT2046_Y_OFFSET -18 + #endif +#endif + +#if HAS_WIRED_LCD && !HAS_SPI_TFT + + // NON TFT Displays + + #if ENABLED(MKS_MINI_12864) + + // MKS MINI12864 and MKS LCD12864B + // If using MKS LCD12864A (Need to remove RPK2 resistor) + + #define LCD_BACKLIGHT_PIN -1 + #define LCD_RESET_PIN -1 + #define DOGLCD_A0 PD11 + #define DOGLCD_CS PE15 + #define DOGLCD_SCK PA5 + #define DOGLCD_MOSI PA7 + + #elif IS_TFTGLCD_PANEL + + #if ENABLED(TFTGLCD_PANEL_SPI) + #define PIN_SPI_SCK PA5 + #define PIN_TFT_MISO PA6 + #define PIN_TFT_MOSI PA7 + #define TFTGLCD_CS PE8 + #endif + + #ifndef BEEPER_PIN + #define BEEPER_PIN -1 + #endif + + #else // !MKS_MINI_12864 + + #define LCD_PINS_D4 PE14 + #if ENABLED(ULTIPANEL) + #define LCD_PINS_D5 PE15 + #define LCD_PINS_D6 PD11 + #define LCD_PINS_D7 PD10 + #endif + + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(125) + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(125) + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(125) + #endif + + #endif // !MKS_MINI_12864 + +#endif // HAS_WIRED_LCD && !HAS_SPI_TFT + +#define HAS_SPI_FLASH 1 +#if HAS_SPI_FLASH + #define SPI_FLASH_SIZE 0x1000000 // 16MB + #define W25QXX_CS_PIN PB12 + #define W25QXX_MOSI_PIN PB15 + #define W25QXX_MISO_PIN PB14 + #define W25QXX_SCK_PIN PB13 +#endif + +#ifndef BEEPER_PIN + #define BEEPER_PIN PC5 +#endif + +#if ENABLED(SPEAKER) && BEEPER_PIN == PC5 + #error "MKS Robin nano default BEEPER_PIN is not a SPEAKER." +#endif diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h new file mode 100644 index 000000000000..32203f52ea8d --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h @@ -0,0 +1,275 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * MKS Robin pro (STM32F103ZET6) board pin assignments + */ + +#if NOT_TARGET(__STM32F1__) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#elif HOTENDS > 3 || E_STEPPERS > 3 + #error "MKS Robin pro supports up to 3 hotends / E-steppers. Comment out this line to continue." +#endif + +#define BOARD_INFO_NAME "MKS Robin pro" + +// +// Release PB4 (Y_ENABLE_PIN) from JTAG NRST role +// +#define DISABLE_DEBUG + +// +// Note: MKS Robin board is using SPI2 interface. +// +//#define SPI_MODULE 2 +#define ENABLE_SPI2 + +// +// Servos +// +#define SERVO0_PIN PA8 // BLTOUCH + +// +// Limit Switches +// +#define X_MIN_PIN PA15 +#define X_MAX_PIN PG7 +#define Y_MIN_PIN PA12 +#define Y_MAX_PIN PG8 +#define Z_MIN_PIN PA11 +#define Z_MAX_PIN PC4 + +// +// Steppers +// +#define X_ENABLE_PIN PE4 +#define X_STEP_PIN PE3 +#define X_DIR_PIN PE2 +#ifndef X_CS_PIN + #define X_CS_PIN PF8 +#endif + +#define Y_ENABLE_PIN PE1 +#define Y_STEP_PIN PE0 +#define Y_DIR_PIN PB9 +#ifndef Y_CS_PIN + #define Y_CS_PIN PF3 +#endif + +#define Z_ENABLE_PIN PB8 +#define Z_STEP_PIN PB5 +#define Z_DIR_PIN PB4 +#ifndef Z_CS_PIN + #define Z_CS_PIN PF6 +#endif + +#define E0_ENABLE_PIN PB3 +#define E0_STEP_PIN PD6 +#define E0_DIR_PIN PD3 +#ifndef E0_CS_PIN + #define E0_CS_PIN PG15 +#endif + +#define E1_ENABLE_PIN PA3 +#define E1_STEP_PIN PA6 +#define E1_DIR_PIN PA1 +#ifndef E1_CS_PIN + #define E1_CS_PIN PG10 +#endif + +#define E2_ENABLE_PIN PF0 +#define E2_STEP_PIN PF2 +#define E2_DIR_PIN PF1 +#ifndef E2_CS_PIN + #define E2_CS_PIN PG9 +#endif +// +// Software SPI pins for TMC2130 stepper drivers +// +#if ENABLED(TMC_USE_SW_SPI) + #ifndef TMC_SW_MOSI + #define TMC_SW_MOSI PB15 + #endif + #ifndef TMC_SW_MISO + #define TMC_SW_MISO PB14 + #endif + #ifndef TMC_SW_SCK + #define TMC_SW_SCK PB13 + #endif +#endif + +#if HAS_TMC_UART + /** + * TMC2208/TMC2209 stepper drivers + * + * Hardware serial communication ports. + * If undefined software serial is used according to the pins below + */ + //#define X_HARDWARE_SERIAL MSerial1 + //#define Y_HARDWARE_SERIAL MSerial1 + //#define Z_HARDWARE_SERIAL MSerial1 + //#define E0_HARDWARE_SERIAL MSerial1 + //#define E1_HARDWARE_SERIAL MSerial1 + //#define E2_HARDWARE_SERIAL MSerial1 + + // + // Software serial + // + #define X_SERIAL_TX_PIN PF7 + #define X_SERIAL_RX_PIN PF8 + + #define Y_SERIAL_TX_PIN PF4 + #define Y_SERIAL_RX_PIN PF3 + + #define Z_SERIAL_TX_PIN PF5 + #define Z_SERIAL_RX_PIN PF6 + + #define E0_SERIAL_TX_PIN PG13 + #define E0_SERIAL_RX_PIN PG15 + + #define E1_SERIAL_TX_PIN PG12 + #define E1_SERIAL_RX_PIN PG10 + + #define E2_SERIAL_TX_PIN PC13 + #define E2_SERIAL_RX_PIN PG9 +#endif + +// +// Temperature Sensors +// +#define TEMP_0_PIN PC1 // TH1 +#define TEMP_1_PIN PC2 // TH2 +#define TEMP_2_PIN PC3 // TH3 +#define TEMP_BED_PIN PC0 // TB1 + +// +// Heaters / Fans +// +#define HEATER_0_PIN PF10 // +HE0- +#define HEATER_1_PIN PB0 // +HE1- +#define HEATER_2_PIN PF9 // +HE2- +#define HEATER_BED_PIN PA0 // +HOT-BED- +#define FAN_PIN PB1 // +FAN- + +/** + * Note: MKS Robin Pro board is using SPI2 interface. Make sure your stm32duino library is configured accordingly + */ +//#define MAX6675_SS_PIN PE5 // TC1 - CS1 +//#define MAX6675_SS_PIN PF11 // TC2 - CS2 + +#define POWER_LOSS_PIN PA2 // PW_DET +#define PS_ON_PIN PG11 // PW_OFF +#define FIL_RUNOUT_PIN PA4 // MT_DET1 +//#define FIL_RUNOUT_PIN PE6 // MT_DET2 +//#define FIL_RUNOUT_PIN PG14 // MT_DET3 + +// +// SD Card +// +#ifndef SDCARD_CONNECTION + #define SDCARD_CONNECTION ONBOARD +#endif + +#if SD_CONNECTION_IS(LCD) + #define ENABLE_SPI2 + #define SD_DETECT_PIN PG3 + #define SCK_PIN PB13 + #define MISO_PIN PB14 + #define MOSI_PIN PB15 + #define SS_PIN PG6 +#elif SD_CONNECTION_IS(ONBOARD) + #define SDIO_SUPPORT + #define SD_DETECT_PIN PD12 + #define ONBOARD_SD_CS_PIN PC11 +#elif SD_CONNECTION_IS(CUSTOM_CABLE) + #error "No custom SD drive cable defined for this board." +#endif + +/** + * Note: MKS Robin TFT screens use various TFT controllers. + * If the screen stays white, disable 'LCD_RESET_PIN' + * to let the bootloader init the screen. + */ +#if ENABLED(FSMC_GRAPHICAL_TFT) + #define FSMC_CS_PIN PD7 // NE4 + #define FSMC_RS_PIN PD11 // A0 + + #define LCD_RESET_PIN PF6 + #define LCD_BACKLIGHT_PIN PD13 + + #if NEED_TOUCH_PINS + #define TOUCH_CS_PIN PA7 + #else + #define BEEPER_PIN PC5 + #define BTN_ENC PG2 + #define BTN_EN1 PG5 + #define BTN_EN2 PG4 + #endif + +#elif IS_TFTGLCD_PANEL + + #if ENABLED(TFTGLCD_PANEL_SPI) + #define TFTGLCD_CS PG5 + #endif + +#elif HAS_WIRED_LCD + + #define BEEPER_PIN PC5 + #define BTN_ENC PG2 + #define LCD_PINS_ENABLE PG0 + #define LCD_PINS_RS PG1 + #define BTN_EN1 PG5 + #define BTN_EN2 PG4 + + // MKS MINI12864 and MKS LCD12864B. If using MKS LCD12864A (Need to remove RPK2 resistor) + #if ENABLED(MKS_MINI_12864) + + #define LCD_BACKLIGHT_PIN -1 + #define LCD_RESET_PIN -1 + #define DOGLCD_A0 PF12 + #define DOGLCD_CS PF15 + #define DOGLCD_SCK PB13 + #define DOGLCD_MOSI PB15 + + #else // !MKS_MINI_12864 && !ENDER2_STOCKDISPLAY + + #define LCD_PINS_D4 PF14 + #if ENABLED(ULTIPANEL) + #define LCD_PINS_D5 PF15 + #define LCD_PINS_D6 PF12 + #define LCD_PINS_D7 PF13 + #endif + + #endif // !MKS_MINI_12864 && !ENDER2_STOCKDISPLAY + +#endif + +#ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(125) +#endif +#ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(125) +#endif +#ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(125) +#endif diff --git a/Marlin/src/pins/stm32f1/pins_MORPHEUS.h b/Marlin/src/pins/stm32f1/pins_MORPHEUS.h new file mode 100644 index 000000000000..ccc92b7527d1 --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_MORPHEUS.h @@ -0,0 +1,92 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + + /** + * 2017 Victor Perez Marlin for stm32f1 test + * 2018 Modified by Pablo Crespo for Morpheus Board (https://github.com/pscrespo/Morpheus-STM32) + */ + +/** + * MORPHEUS Board pin assignments + */ + +#if NOT_TARGET(__STM32F1__) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#endif + +#define BOARD_INFO_NAME "Bluepill based board" + +// +// Limit Switches +// +#define X_MIN_PIN PB14 +#define Y_MIN_PIN PB13 +#define Z_MIN_PIN PB12 + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN PB9 +#endif + +// +// Steppers +// +// X & Y enable are the same +#define X_STEP_PIN PB7 +#define X_DIR_PIN PB6 +#define X_ENABLE_PIN PB8 + +#define Y_STEP_PIN PB5 +#define Y_DIR_PIN PB4 +#define Y_ENABLE_PIN PB8 + +#define Z_STEP_PIN PA15 +#define Z_DIR_PIN PA10 +#define Z_ENABLE_PIN PB3 + +#define E0_STEP_PIN PA8 +#define E0_DIR_PIN PB15 +#define E0_ENABLE_PIN PA9 + +// +// Temperature Sensors +// +#define TEMP_0_PIN PB1 // Analog Input (HOTEND thermistor) +#define TEMP_BED_PIN PB0 // Analog Input (BED thermistor) + +// +// Heaters / Fans +// +#define HEATER_0_PIN PA2 // HOTEND MOSFET +#define HEATER_BED_PIN PA0 // BED MOSFET + +#define FAN_PIN PA1 // FAN1 header on board - PRINT FAN + +// +// Misc. +// +#define LED_PIN PC13 +#define SDSS PA3 +#define TFTGLCD_CS PA4 diff --git a/Marlin/src/pins/stm32f1/pins_STM32F1R.h b/Marlin/src/pins/stm32f1/pins_STM32F1R.h new file mode 100644 index 000000000000..cf2ba2c5fa74 --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_STM32F1R.h @@ -0,0 +1,261 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(__STM32F1__) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#endif + +/** + * 21017 Victor Perez Marlin for stm32f1 test + */ + +#define BOARD_INFO_NAME "Misc. STM32F1R" +#define DEFAULT_MACHINE_NAME "STM32F103RET6" + +// Ignore temp readings during development. +//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 + +// +// Limit Switches +// +#define X_STOP_PIN PB3 +#define Y_STOP_PIN PB4 +#define Z_STOP_PIN PB5 + +// +// Steppers +// +#define X_STEP_PIN PC0 +#define X_DIR_PIN PC1 +#define X_ENABLE_PIN PA8 + +#define Y_STEP_PIN PC2 +#define Y_DIR_PIN PC3 +#define Y_ENABLE_PIN PA8 + +#define Z_STEP_PIN PC4 +#define Z_DIR_PIN PC5 +#define Z_ENABLE_PIN PA8 + +#define E0_STEP_PIN PC6 +#define E0_DIR_PIN PC7 +#define E0_ENABLE_PIN PA8 + +/** + * TODO: Currently using same Enable pin to all steppers. + */ + +#define E1_STEP_PIN PC8 +#define E1_DIR_PIN PC9 +#define E1_ENABLE_PIN PA8 + +#define E2_STEP_PIN PC10 +#define E2_DIR_PIN PC11 +#define E2_ENABLE_PIN PA8 + +// +// Misc. Functions +// +#define SDSS PA4 +#define LED_PIN PD2 + +// +// Heaters / Fans +// +#define HEATER_0_PIN PB0 // EXTRUDER 1 +#define HEATER_1_PIN PB1 + +#define HEATER_BED_PIN PA3 // BED + +// +// Temperature Sensors +// +#define TEMP_BED_PIN PA0 // Analog Input +#define TEMP_0_PIN PA1 // Analog Input +#define TEMP_1_PIN PA2 // Analog Input + +// +// LCD Pins +// +#if HAS_WIRED_LCD + + #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) + #define LCD_PINS_RS 49 // CS chip select /SS chip slave select + #define LCD_PINS_ENABLE 51 // SID (MOSI) + #define LCD_PINS_D4 52 // SCK (CLK) clock + #elif BOTH(NEWPANEL, PANEL_ONE) + #define LCD_PINS_RS PB8 + #define LCD_PINS_ENABLE PD2 + #define LCD_PINS_D4 PB12 + #define LCD_PINS_D5 PB13 + #define LCD_PINS_D6 PB14 + #define LCD_PINS_D7 PB15 + #else + #define LCD_PINS_RS PB8 + #define LCD_PINS_ENABLE PD2 + #define LCD_PINS_D4 PB12 + #define LCD_PINS_D5 PB13 + #define LCD_PINS_D6 PB14 + #define LCD_PINS_D7 PB15 + #if DISABLED(NEWPANEL) + #define BEEPER_PIN 33 + // Buttons attached to a shift register + // Not wired yet + //#define SHIFT_CLK 38 + //#define SHIFT_LD 42 + //#define SHIFT_OUT 40 + //#define SHIFT_EN 17 + #endif + #endif + + #if ENABLED(NEWPANEL) + + #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) + + #define BEEPER_PIN 37 + + #define BTN_EN1 31 + #define BTN_EN2 33 + #define BTN_ENC 35 + + #define SD_DETECT_PIN 49 + #define KILL_PIN 41 + + #if ENABLED(BQ_LCD_SMART_CONTROLLER) + #define LCD_BACKLIGHT_PIN 39 + #endif + + #elif ENABLED(REPRAPWORLD_GRAPHICAL_LCD) + + #define BTN_EN1 64 + #define BTN_EN2 59 + #define BTN_ENC 63 + #define SD_DETECT_PIN 42 + + #elif ENABLED(LCD_I2C_PANELOLU2) + + #define BTN_EN1 47 + #define BTN_EN2 43 + #define BTN_ENC 32 + #define LCD_SDSS 53 + #define SD_DETECT_PIN -1 + #define KILL_PIN 41 + + #elif ENABLED(LCD_I2C_VIKI) + + #define BTN_EN1 22 // https://files.panucatt.com/datasheets/viki_wiring_diagram.pdf explains 40/42. + #define BTN_EN2 7 // 22/7 are unused on RAMPS_14. 22 is unused and 7 the SERVO0_PIN on RAMPS_13. + + #define BTN_ENC -1 + #define LCD_SDSS 53 + #define SD_DETECT_PIN 49 + + #elif ANY(VIKI2, miniVIKI) + + #define BEEPER_PIN 33 + + // Pins for DOGM SPI LCD Support + #define DOGLCD_A0 44 + #define DOGLCD_CS 45 + #define LCD_SCREEN_ROT_180 + + #define BTN_EN1 22 + #define BTN_EN2 7 + #define BTN_ENC 39 + + #define SDSS 53 + #define SD_DETECT_PIN -1 // Pin 49 for display sd interface, 72 for easy adapter board + + #define KILL_PIN 31 + + #define STAT_LED_RED_PIN 32 + #define STAT_LED_BLUE_PIN 35 + + #elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) + #define BTN_EN1 35 + #define BTN_EN2 37 + #define BTN_ENC 31 + #define SD_DETECT_PIN 49 + #define LCD_SDSS 53 + #define KILL_PIN 41 + #define BEEPER_PIN 23 + #define DOGLCD_CS 29 + #define DOGLCD_A0 27 + #define LCD_BACKLIGHT_PIN 33 + + #elif ENABLED(MINIPANEL) + + #define BEEPER_PIN 42 + // Pins for DOGM SPI LCD Support + #define DOGLCD_A0 44 + #define DOGLCD_CS 66 + #define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65 + #define SDSS 53 + + #define KILL_PIN 64 + // GLCD features + // Uncomment screen orientation + //#define LCD_SCREEN_ROT_90 + //#define LCD_SCREEN_ROT_180 + //#define LCD_SCREEN_ROT_270 + // The encoder and click button + #define BTN_EN1 40 + #define BTN_EN2 63 + #define BTN_ENC 59 + // not connected to a pin + #define SD_DETECT_PIN 49 + + #else + + // Beeper on AUX-4 + #define BEEPER_PIN 33 + + // Buttons directly attached to AUX-2 + #if ENABLED(REPRAPWORLD_KEYPAD) + #define BTN_EN1 64 + #define BTN_EN2 59 + #define BTN_ENC 63 + #define SHIFT_OUT 40 + #define SHIFT_CLK 44 + #define SHIFT_LD 42 + #elif ENABLED(PANEL_ONE) + #define BTN_EN1 59 // AUX2 PIN 3 + #define BTN_EN2 63 // AUX2 PIN 4 + #define BTN_ENC 49 // AUX3 PIN 7 + #else + #define BTN_EN1 37 + #define BTN_EN2 35 + #define BTN_ENC 31 + #endif + + #if ENABLED(G3D_PANEL) + #define SD_DETECT_PIN 49 + #define KILL_PIN 41 + #else + //#define SD_DETECT_PIN -1 // Ramps doesn't use this + #endif + + #endif + #endif // NEWPANEL + +#endif // HAS_WIRED_LCD diff --git a/Marlin/src/pins/stm32f1/pins_STM3R_MINI.h b/Marlin/src/pins/stm32f1/pins_STM3R_MINI.h new file mode 100644 index 000000000000..e74698f89eff --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_STM3R_MINI.h @@ -0,0 +1,285 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(__STM32F1__, __STM32F4__) + #error "Oops! Select an STM32F1/4 board in 'Tools > Board.'" +#endif + +/** + * 21017 Victor Perez Marlin for stm32f1 test + */ + +#define BOARD_INFO_NAME "STM3R Mini" +#define DEFAULT_MACHINE_NAME BOARD_INFO_NAME + +// Enable I2C_EEPROM for testing +#define I2C_EEPROM + +// Ignore temp readings during development. +//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 + +// +// Limit Switches +// +#define X_STOP_PIN PD0 +#define Y_STOP_PIN PD1 +#define Z_STOP_PIN PD4 + +// +// Steppers +// +#define X_STEP_PIN PE1 +#define X_DIR_PIN PE0 +#define X_ENABLE_PIN PC0 + +#define Y_STEP_PIN PE3 +#define Y_DIR_PIN PE2 +#define Y_ENABLE_PIN PC1 + +#define Z_STEP_PIN PE5 +#define Z_DIR_PIN PE4 +#define Z_ENABLE_PIN PC2 + +#define E0_STEP_PIN PE7 +#define E0_DIR_PIN PE6 +#define E0_ENABLE_PIN PC3 + +#define E1_STEP_PIN PE9 +#define E1_DIR_PIN PE8 +#define E1_ENABLE_PIN PC4 + +#define E2_STEP_PIN PE11 +#define E2_DIR_PIN PE10 +#define E2_ENABLE_PIN PC5 + +// +// Misc. Functions +// +#define SDSS PA15 +#define LED_PIN PB2 + +// +// Heaters / Fans +// +#define HEATER_0_PIN PD12 // EXTRUDER 1 +//#define HEATER_1_PIN PD13 + +#define HEATER_BED_PIN PB9 // BED +//#define HEATER_BED2_PIN -1 // BED2 +//#define HEATER_BED3_PIN -1 // BED3 + +#ifndef FAN_PIN + #define FAN_PIN PD14 +#endif +#define FAN1_PIN PD13 + +#define FAN_SOFT_PWM + +// +// Temperature Sensors +// +#define TEMP_BED_PIN PA0 +#define TEMP_0_PIN PA1 +#define TEMP_1_PIN PA2 +#define TEMP_2_PIN PA3 + +// Laser control +#if HAS_CUTTER + #define SPINDLE_LASER_PWM_PIN PB8 + #define SPINDLE_LASER_ENA_PIN PD5 +#endif + +// +// LCD Pins +// +#if HAS_WIRED_LCD + + #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) + #define LCD_PINS_RS 49 // CS chip select /SS chip slave select + #define LCD_PINS_ENABLE 51 // SID (MOSI) + #define LCD_PINS_D4 52 // SCK (CLK) clock + #elif BOTH(NEWPANEL, PANEL_ONE) + #define LCD_PINS_RS PB8 + #define LCD_PINS_ENABLE PD2 + #define LCD_PINS_D4 PB12 + #define LCD_PINS_D5 PB13 + #define LCD_PINS_D6 PB14 + #define LCD_PINS_D7 PB15 + #else + #define LCD_PINS_RS PB8 + #define LCD_PINS_ENABLE PD2 + #define LCD_PINS_D4 PB12 + #define LCD_PINS_D5 PB13 + #define LCD_PINS_D6 PB14 + #define LCD_PINS_D7 PB15 + #if DISABLED(NEWPANEL) + #define BEEPER_PIN 33 + // Buttons attached to a shift register + // Not wired yet + //#define SHIFT_CLK 38 + //#define SHIFT_LD 42 + //#define SHIFT_OUT 40 + //#define SHIFT_EN 17 + #endif + #endif + + #if NEED_TOUCH_PINS + + #define TOUCH_CS_PIN PB12 // SPI2_NSS + #define TOUCH_SCK_PIN PB13 + #define TOUCH_MOSI_PIN PB14 + #define TOUCH_MISO_PIN PB15 + #define TOUCH_INT_PIN PC6 // (PenIRQ coming from ADS7843) + + #elif ENABLED(NEWPANEL) + + #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) + + #define BEEPER_PIN 37 + + #define BTN_EN1 31 + #define BTN_EN2 33 + #define BTN_ENC 35 + + #define SD_DETECT_PIN 49 + #define KILL_PIN 41 + + #if ENABLED(BQ_LCD_SMART_CONTROLLER) + #define LCD_BACKLIGHT_PIN 39 + #endif + + #elif ENABLED(REPRAPWORLD_GRAPHICAL_LCD) + + #define BTN_EN1 64 + #define BTN_EN2 59 + #define BTN_ENC 63 + #define SD_DETECT_PIN 42 + + #elif ENABLED(LCD_I2C_PANELOLU2) + + #define BTN_EN1 47 + #define BTN_EN2 43 + #define BTN_ENC 32 + #define LCD_SDSS 53 + #define SD_DETECT_PIN -1 + #define KILL_PIN 41 + + #elif ENABLED(LCD_I2C_VIKI) + + #define BTN_EN1 22 // https://files.panucatt.com/datasheets/viki_wiring_diagram.pdf explains 40/42. + #define BTN_EN2 7 // 22/7 are unused on RAMPS_14. 22 is unused and 7 the SERVO0_PIN on RAMPS_13. + + #define BTN_ENC -1 + #define LCD_SDSS 53 + #define SD_DETECT_PIN 49 + + #elif ANY(VIKI2, miniVIKI) + + #define BEEPER_PIN 33 + + // Pins for DOGM SPI LCD Support + #define DOGLCD_A0 44 + #define DOGLCD_CS 45 + #define LCD_SCREEN_ROT_180 + + #define BTN_EN1 22 + #define BTN_EN2 7 + #define BTN_ENC 39 + + #define SDSS 53 + #define SD_DETECT_PIN -1 // Pin 49 for display sd interface, 72 for easy adapter board + + #define KILL_PIN 31 + + #define STAT_LED_RED_PIN 32 + #define STAT_LED_BLUE_PIN 35 + + #elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) + + #define BTN_EN1 35 + #define BTN_EN2 37 + #define BTN_ENC 31 + #define SD_DETECT_PIN 49 + #define LCD_SDSS 53 + #define KILL_PIN 41 + #define BEEPER_PIN 23 + #define DOGLCD_CS 29 + #define DOGLCD_A0 27 + #define LCD_BACKLIGHT_PIN 33 + + #elif ENABLED(MINIPANEL) + + #define BEEPER_PIN 42 + // Pins for DOGM SPI LCD Support + #define DOGLCD_A0 44 + #define DOGLCD_CS 66 + #define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65 + #define SDSS 53 + + #define KILL_PIN 64 + // GLCD features + // Uncomment screen orientation + //#define LCD_SCREEN_ROT_90 + //#define LCD_SCREEN_ROT_180 + //#define LCD_SCREEN_ROT_270 + // The encoder and click button + #define BTN_EN1 40 + #define BTN_EN2 63 + #define BTN_ENC 59 + // not connected to a pin + #define SD_DETECT_PIN 49 + + #else + + // Beeper on AUX-4 + #define BEEPER_PIN 33 + + // Buttons directly attached to AUX-2 + #if ENABLED(REPRAPWORLD_KEYPAD) + #define BTN_EN1 64 + #define BTN_EN2 59 + #define BTN_ENC 63 + #define SHIFT_OUT 40 + #define SHIFT_CLK 44 + #define SHIFT_LD 42 + #elif ENABLED(PANEL_ONE) + #define BTN_EN1 59 // AUX2 PIN 3 + #define BTN_EN2 63 // AUX2 PIN 4 + #define BTN_ENC 49 // AUX3 PIN 7 + #else + #define BTN_EN1 37 + #define BTN_EN2 35 + #define BTN_ENC 31 + #endif + + #if ENABLED(G3D_PANEL) + #define SD_DETECT_PIN 49 + #define KILL_PIN 41 + #else + //#define SD_DETECT_PIN -1 // Ramps doesn't use this + #endif + + #endif + #endif // NEWPANEL + +#endif // HAS_WIRED_LCD diff --git a/Marlin/src/pins/stm32f1/pins_TRIGORILLA_PRO.h b/Marlin/src/pins/stm32f1/pins_TRIGORILLA_PRO.h new file mode 100644 index 000000000000..bfd1f2abdcbd --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_TRIGORILLA_PRO.h @@ -0,0 +1,193 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * ANYCUBIC Trigorilla Pro (STM32F130ZET6) board pin assignments. + * It is the same used by the Tronxy X5SA thanks to ftoz1 for sharing it + * https://github.com/MarlinFirmware/Marlin/issues/14655 + * https://github.com/MarlinFirmware/Marlin/files/3401484/x5sa-main_board-2.pdf + */ + +#if NOT_TARGET(__STM32F1__) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#elif HOTENDS > 2 || E_STEPPERS > 2 + #error "Trigorilla Pro supports up to 2 hotends / E-steppers. Comment out this line to continue." +#endif + +#define BOARD_INFO_NAME "Trigorilla Pro" +#define DISABLE_JTAG + +// +// EEPROM +// +#define FLASH_EEPROM_EMULATION +#if ENABLED(FLASH_EEPROM_EMULATION) + // SoC Flash (framework-arduinoststm32-maple/STM32F1/libraries/EEPROM/EEPROM.h) + #define EEPROM_START_ADDRESS (0x8000000UL + (512 * 1024) - 2 * EEPROM_PAGE_SIZE) + #define EEPROM_PAGE_SIZE (0x800U) // 2KB, but will use 2x more (4KB) + #define MARLIN_EEPROM_SIZE EEPROM_PAGE_SIZE +#else + #define MARLIN_EEPROM_SIZE (0x800U) // On SD, Limit to 2KB, require this amount of RAM +#endif + +// +// Limit Switches +// +#define X_MAX_PIN PG10 +#define Y_MAX_PIN PA12 +#define Z_MAX_PIN PA14 +#define Z_MIN_PIN PA13 + +// +// Steppers +// +#define X_ENABLE_PIN PC13 +#define X_STEP_PIN PE5 +#define X_DIR_PIN PE6 + +#define Y_ENABLE_PIN PE4 +#define Y_STEP_PIN PE2 +#define Y_DIR_PIN PE3 + +#define Z_ENABLE_PIN PE1 +#define Z_STEP_PIN PB9 +#define Z_DIR_PIN PE0 + +#define E0_ENABLE_PIN PB8 +#define E0_STEP_PIN PB4 +#define E0_DIR_PIN PB5 + +#define E1_ENABLE_PIN PG8 +#define E1_STEP_PIN PC7 +#define E1_DIR_PIN PC6 + +// +// Temperature Sensors +// +#define TEMP_0_PIN PA1 // TH1 +#define TEMP_BED_PIN PA0 // TB1 + +// +// Heaters +// +#define HEATER_0_PIN PG12 // HEATER1 +#define HEATER_BED_PIN PG11 // HOT BED +#define HEATER_BED_INVERTING true + +// +// Fans +// +#define CONTROLLER_FAN_PIN PD6 // FAN +#define FAN_PIN PG13 // FAN +#define FAN1_PIN PG14 // FAN + +// +// Misc +// +#define BEEPER_PIN PB0 +#define LED_PIN PD3 +//#define POWER_LOSS_PIN PG2 // PG4 PW_DET +#define FIL_RUNOUT_PIN PA15 // MT_DET + +/** + * Note: MKS Robin TFT screens use various TFT controllers + * Supported screens are based on the ILI9341, ST7789V and ILI9328 (320x240) + * ILI9488 is not supported. + * Define init sequences for other screens in u8g_dev_tft_320x240_upscale_from_128x64.cpp + * + * If the screen stays white, disable 'LCD_RESET_PIN' to let the bootloader init the screen. + * + * Setting an 'LCD_RESET_PIN' may cause a flicker when entering the LCD menu + * because Marlin uses the reset as a failsafe to revive a glitchy LCD. + */ +#if HAS_FSMC_TFT + #define TFT_RESET_PIN PF11 + #define TFT_BACKLIGHT_PIN PD13 + #define FSMC_CS_PIN PD7 // NE4 + #define FSMC_RS_PIN PD11 // A0 + + #define LCD_USE_DMA_FSMC // Use DMA transfers to send data to the TFT + #define FSMC_DMA_DEV DMA2 + #define FSMC_DMA_CHANNEL DMA_CH5 + + #define ANYCUBIC_TFT35 +#else + #define LCD_RESET_PIN PF11 + #define LCD_BACKLIGHT_PIN PD13 +#endif + +// XPT2046 Touch Screen calibration +#if ENABLED(TFT_COLOR_UI) || ENABLED(TFT_LVGL_UI) + #ifndef XPT2046_X_CALIBRATION + #define XPT2046_X_CALIBRATION -17181 + #endif + #ifndef XPT2046_Y_CALIBRATION + #define XPT2046_Y_CALIBRATION 11434 + #endif + #ifndef XPT2046_X_OFFSET + #define XPT2046_X_OFFSET 501 + #endif + #ifndef XPT2046_Y_OFFSET + #define XPT2046_Y_OFFSET -9 + #endif +#elif ENABLED(TFT_CLASSIC_UI) + #ifndef XPT2046_X_CALIBRATION + #define XPT2046_X_CALIBRATION -12316 + #endif + #ifndef XPT2046_Y_CALIBRATION + #define XPT2046_Y_CALIBRATION 8981 + #endif + #ifndef XPT2046_X_OFFSET + #define XPT2046_X_OFFSET 340 + #endif + #ifndef XPT2046_Y_OFFSET + #define XPT2046_Y_OFFSET -20 + #endif +#endif + +#if NEED_TOUCH_PINS + #define TOUCH_CS_PIN PB7 // SPI2_NSS + #define TOUCH_SCK_PIN PA5 // SPI2_SCK + #define TOUCH_MISO_PIN PA6 // SPI2_MISO + #define TOUCH_MOSI_PIN PA7 // SPI2_MOSI +#endif + +// SPI1(PA7) & SPI3(PB5) not available +#define ENABLE_SPI2 + +#if ENABLED(SDIO_SUPPORT) + #define SCK_PIN PB13 // SPI2 ok + #define MISO_PIN PB14 // SPI2 ok + #define MOSI_PIN PB15 // SPI2 ok + #define SS_PIN PC11 // PB12 is X- ok + #define SD_DETECT_PIN -1 // SD_CD ok +#else + // SD as custom software SPI (SDIO pins) + #define SCK_PIN PC12 + #define MISO_PIN PC8 + #define MOSI_PIN PD2 + #define SS_PIN -1 + #define ONBOARD_SD_CS_PIN PC11 + #define SDSS PD2 + #define SD_DETECT_PIN -1 +#endif diff --git a/Marlin/src/pins/stm32f4/pins_ARMED.h b/Marlin/src/pins/stm32f4/pins_ARMED.h new file mode 100644 index 000000000000..db57db14d549 --- /dev/null +++ b/Marlin/src/pins/stm32f4/pins_ARMED.h @@ -0,0 +1,229 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +// https://github.com/ktand/Armed + +#pragma once + +#if NOT_TARGET(STM32F4) + #error "Oops! Select an STM32F4 board in 'Tools > Board.'" +#elif HOTENDS > 2 || E_STEPPERS > 2 + #error "Arm'ed supports up to 2 hotends / E-steppers." +#endif + +#ifndef ARMED_V1_0 + #define ARMED_V1_1 +#endif + +#undef BOARD_INFO_NAME // Defined on the command line by Arduino Core STM32 +#define BOARD_INFO_NAME "Arm'ed" +#define DEFAULT_MACHINE_NAME BOARD_INFO_NAME + +#define I2C_EEPROM +#define MARLIN_EEPROM_SIZE 0x1000 // 4KB + +// +// Limit Switches +// +#define X_STOP_PIN PE0 +#define Y_STOP_PIN PE1 +#define Z_STOP_PIN PE14 + +// +// Z Probe (when not Z_MIN_PIN) +// +//#ifndef Z_MIN_PROBE_PIN +// #define Z_MIN_PROBE_PIN PA4 +//#endif + +// +// Filament Runout Sensor +// +#ifndef FIL_RUNOUT_PIN + #define FIL_RUNOUT_PIN PA3 +#endif + +// +// Steppers +// + +#ifdef ARMED_SWAP_X_E1 + #define X_STEP_PIN PE4 + #define X_DIR_PIN PE2 + #define X_ENABLE_PIN PE3 + #define X_CS_PIN PE5 +#else + #define X_STEP_PIN PD3 + #define X_DIR_PIN PD2 + #define X_ENABLE_PIN PD0 + #define X_CS_PIN PD1 +#endif + +#define Y_STEP_PIN PE11 +#define Y_DIR_PIN PE10 +#define Y_ENABLE_PIN PE13 +#define Y_CS_PIN PE12 + +#define Z_STEP_PIN PD6 +#define Z_DIR_PIN PD7 +#define Z_ENABLE_PIN PD4 +#define Z_CS_PIN PD5 + +#define E0_STEP_PIN PB5 +#define E0_DIR_PIN PB6 +#ifdef ARMED_V1_1 + #define E0_ENABLE_PIN PC12 +#else + #define E0_ENABLE_PIN PB3 +#endif +#define E0_CS_PIN PB4 + +#ifdef ARMED_SWAP_X_E1 + #define E1_STEP_PIN PD3 + #define E1_DIR_PIN PD2 + #define E1_ENABLE_PIN PD0 + #define E1_CS_PIN PD1 +#else + #define E1_STEP_PIN PE4 + #define E1_DIR_PIN PE2 + #define E1_ENABLE_PIN PE3 + #define E1_CS_PIN PE5 +#endif + +// +// Temperature Sensors +// +#define TEMP_0_PIN PC0 // Analog Input +#define TEMP_1_PIN PC1 // Analog Input +#define TEMP_BED_PIN PC2 // Analog Input + +#if HOTENDS == 1 && TEMP_SENSOR_PROBE + #define TEMP_PROBE_PIN PC1 +#endif + +// +// Heaters / Fans +// +#define HEATER_0_PIN PA1 // Hardware PWM +#define HEATER_1_PIN PA2 // Hardware PWM +#define HEATER_BED_PIN PA0 // Hardware PWM + +#define FAN_PIN PC6 // Hardware PWM, Part cooling fan +#define FAN1_PIN PC7 // Hardware PWM, Extruder fan +#define FAN2_PIN PC8 // Hardware PWM, Controller fan + +// +// Misc functions +// +#define SDSS PE7 +#define LED_PIN PB7 // Heart beat +#define PS_ON_PIN PA10 +#define KILL_PIN PA8 +#define PWR_LOSS PA4 // Power loss / nAC_FAULT + +// +// LCD / Controller +// +#define SD_DETECT_PIN PA15 +#define BEEPER_PIN PC9 + +#if ENABLED(FYSETC_MINI_12864) + // + // See https://wiki.fysetc.com/Mini12864_Panel/?fbclid=IwAR1FyjuNdVOOy9_xzky3qqo_WeM5h-4gpRnnWhQr_O1Ef3h0AFnFXmCehK8 + // + #define DOGLCD_A0 PE9 + #define DOGLCD_CS PE8 + + #define LCD_BACKLIGHT_PIN -1 + + #define LCD_RESET_PIN PB12 // Must be high or open for LCD to operate normally. + + #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) + #ifndef RGB_LED_R_PIN + #define RGB_LED_R_PIN PB13 + #endif + #ifndef RGB_LED_G_PIN + #define RGB_LED_G_PIN PB14 + #endif + #ifndef RGB_LED_B_PIN + #define RGB_LED_B_PIN PB15 + #endif + #elif ENABLED(FYSETC_MINI_12864_2_1) + #define NEOPIXEL_PIN PB13 + #endif +#else + #define LCD_PINS_RS PE9 + #define LCD_PINS_ENABLE PE8 + #define LCD_PINS_D4 PB12 + #define LCD_PINS_D5 PB13 + #define LCD_PINS_D6 PB14 + #define LCD_PINS_D7 PB15 + + #if ENABLED(MKS_MINI_12864) + #define DOGLCD_CS PB13 + #define DOGLCD_A0 PB14 + #endif +#endif + +#define BTN_EN1 PC4 +#define BTN_EN2 PC5 +#define BTN_ENC PC3 + +// +// Extension pins +// +#define EXT0_PIN PB0 +#define EXT1_PIN PB1 +#define EXT2_PIN PB2 +#define EXT3_PIN PD8 +#define EXT4_PIN PD9 +#define EXT5_PIN PD10 +#define EXT6_PIN PD11 +#define EXT7_PIN PD12 +#define EXT8_PIN PB10 +#define EXT9_PIN PB11 + +#if HAS_TMC_UART + // TMC2208/TMC2209 stepper drivers + // + // Software serial + // + #define X_SERIAL_TX_PIN EXT0_PIN + #define X_SERIAL_RX_PIN EXT0_PIN + + #define Y_SERIAL_TX_PIN EXT1_PIN + #define Y_SERIAL_RX_PIN EXT1_PIN + + #define Z_SERIAL_TX_PIN EXT2_PIN + #define Z_SERIAL_RX_PIN EXT2_PIN + + #define E0_SERIAL_TX_PIN EXT3_PIN + #define E0_SERIAL_RX_PIN EXT3_PIN + + #define E1_SERIAL_RX_PIN EXT4_PIN + #define E1_SERIAL_TX_PIN EXT4_PIN + + #define Z2_SERIAL_RX_PIN EXT4_PIN + #define Z2_SERIAL_TX_PIN EXT4_PIN + + #define TMC_BAUD_RATE 19200 +#endif diff --git a/Marlin/src/pins/stm32f4/pins_BEAST.h b/Marlin/src/pins/stm32f4/pins_BEAST.h new file mode 100644 index 000000000000..268b7b59cd45 --- /dev/null +++ b/Marlin/src/pins/stm32f4/pins_BEAST.h @@ -0,0 +1,285 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(__STM32F1__, __STM32F4__) + #error "Oops! Select an STM32F1/4 board in 'Tools > Board.'" +#endif + +/** + * 21017 Victor Perez Marlin for stm32f1 test + */ + +#define BOARD_INFO_NAME "Beast STM32" +#define DEFAULT_MACHINE_NAME "STM32F103RET6" + +// Enable I2C_EEPROM for testing +#define I2C_EEPROM + +// Ignore temp readings during development. +//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 + +// +// Steppers +// +#define X_STEP_PIN PE0 +#define X_DIR_PIN PE1 +#define X_ENABLE_PIN PC0 +#define X_MIN_PIN PD5 +#define X_MAX_PIN -1 + +#define Y_STEP_PIN PE2 +#define Y_DIR_PIN PE3 +#define Y_ENABLE_PIN PC1 +#define Y_MIN_PIN PD6 +#define Y_MAX_PIN + +#define Z_STEP_PIN PE4 +#define Z_DIR_PIN PE5 +#define Z_ENABLE_PIN PC2 +#define Z_MIN_PIN PD7 +#define Z_MAX_PIN -1 + +#define Y2_STEP_PIN -1 +#define Y2_DIR_PIN -1 +#define Y2_ENABLE_PIN -1 + +#define Z2_STEP_PIN -1 +#define Z2_DIR_PIN -1 +#define Z2_ENABLE_PIN -1 + +#define E0_STEP_PIN PE6 +#define E0_DIR_PIN PE7 +#define E0_ENABLE_PIN PC3 + +/** + * TODO: Currently using same Enable pin to all steppers. + */ + +#define E1_STEP_PIN PE8 +#define E1_DIR_PIN PE9 +#define E1_ENABLE_PIN PC4 + +#define E2_STEP_PIN PE10 +#define E2_DIR_PIN PE11 +#define E2_ENABLE_PIN PC5 + +// +// Misc. Functions +// +#define SDSS PA15 +#define LED_PIN PB2 + +#define PS_ON_PIN -1 +#define KILL_PIN -1 + +// +// Heaters / Fans +// +#define HEATER_0_PIN PD12 // EXTRUDER 1 +#define HEATER_1_PIN PD13 +#define HEATER_2_PIN PD14 + +#define HEATER_BED_PIN PB9 // BED +#define HEATER_BED2_PIN -1 // BED2 +#define HEATER_BED3_PIN -1 // BED3 + +#ifndef FAN_PIN + #define FAN_PIN PB10 +#endif + +#define FAN_SOFT_PWM + +// +// Temperature Sensors +// +#define TEMP_BED_PIN PA0 // Analog Input +#define TEMP_0_PIN PA1 // Analog Input +#define TEMP_1_PIN PA2 // Analog Input +#define TEMP_2_PIN PA3 // Analog Input + +// +// LCD Pins +// +#if HAS_WIRED_LCD + + #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) + #define LCD_PINS_RS 49 // CS chip select /SS chip slave select + #define LCD_PINS_ENABLE 51 // SID (MOSI) + #define LCD_PINS_D4 52 // SCK (CLK) clock + #elif BOTH(NEWPANEL, PANEL_ONE) + #define LCD_PINS_RS PB8 + #define LCD_PINS_ENABLE PD2 + #define LCD_PINS_D4 PB12 + #define LCD_PINS_D5 PB13 + #define LCD_PINS_D6 PB14 + #define LCD_PINS_D7 PB15 + #else + #define LCD_PINS_RS PB8 + #define LCD_PINS_ENABLE PD2 + #define LCD_PINS_D4 PB12 + #define LCD_PINS_D5 PB13 + #define LCD_PINS_D6 PB14 + #define LCD_PINS_D7 PB15 + #if DISABLED(NEWPANEL) + #define BEEPER_PIN 33 + // Buttons attached to a shift register + // Not wired yet + //#define SHIFT_CLK 38 + //#define SHIFT_LD 42 + //#define SHIFT_OUT 40 + //#define SHIFT_EN 17 + #endif + #endif + + #if ENABLED(NEWPANEL) + + #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) + + #define BEEPER_PIN 37 + + #define BTN_EN1 31 + #define BTN_EN2 33 + #define BTN_ENC 35 + + #define SD_DETECT_PIN 49 + #define KILL_PIN 41 + + #if ENABLED(BQ_LCD_SMART_CONTROLLER) + #define LCD_BACKLIGHT_PIN 39 + #endif + + #elif ENABLED(REPRAPWORLD_GRAPHICAL_LCD) + + #define BTN_EN1 64 + #define BTN_EN2 59 + #define BTN_ENC 63 + #define SD_DETECT_PIN 42 + + #elif ENABLED(LCD_I2C_PANELOLU2) + + #define BTN_EN1 47 + #define BTN_EN2 43 + #define BTN_ENC 32 + #define LCD_SDSS 53 + #define SD_DETECT_PIN -1 + #define KILL_PIN 41 + + #elif ENABLED(LCD_I2C_VIKI) + + #define BTN_EN1 22 // https://files.panucatt.com/datasheets/viki_wiring_diagram.pdf explains 40/42. + #define BTN_EN2 7 // 22/7 are unused on RAMPS_14. 22 is unused and 7 the SERVO0_PIN on RAMPS_13. + + #define BTN_ENC -1 + #define LCD_SDSS 53 + #define SD_DETECT_PIN 49 + + #elif ANY(VIKI2, miniVIKI) + + #define BEEPER_PIN 33 + + // Pins for DOGM SPI LCD Support + #define DOGLCD_A0 44 + #define DOGLCD_CS 45 + #define LCD_SCREEN_ROT_180 + + #define BTN_EN1 22 + #define BTN_EN2 7 + #define BTN_ENC 39 + + #define SDSS 53 + #define SD_DETECT_PIN -1 // Pin 49 for display sd interface, 72 for easy adapter board + + #define KILL_PIN 31 + + #define STAT_LED_RED_PIN 32 + #define STAT_LED_BLUE_PIN 35 + + #elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) + + #define BTN_EN1 35 + #define BTN_EN2 37 + #define BTN_ENC 31 + #define SD_DETECT_PIN 49 + #define LCD_SDSS 53 + #define KILL_PIN 41 + #define BEEPER_PIN 23 + #define DOGLCD_CS 29 + #define DOGLCD_A0 27 + #define LCD_BACKLIGHT_PIN 33 + + #elif ENABLED(MINIPANEL) + + #define BEEPER_PIN 42 + // Pins for DOGM SPI LCD Support + #define DOGLCD_A0 44 + #define DOGLCD_CS 66 + #define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65 + #define SDSS 53 + + #define KILL_PIN 64 + // GLCD features + // Uncomment screen orientation + //#define LCD_SCREEN_ROT_90 + //#define LCD_SCREEN_ROT_180 + //#define LCD_SCREEN_ROT_270 + // The encoder and click button + #define BTN_EN1 40 + #define BTN_EN2 63 + #define BTN_ENC 59 + // not connected to a pin + #define SD_DETECT_PIN 49 + + #else + + // Beeper on AUX-4 + #define BEEPER_PIN 33 + + // Buttons directly attached to AUX-2 + #if ENABLED(REPRAPWORLD_KEYPAD) + #define BTN_EN1 64 + #define BTN_EN2 59 + #define BTN_ENC 63 + #define SHIFT_OUT 40 + #define SHIFT_CLK 44 + #define SHIFT_LD 42 + #elif ENABLED(PANEL_ONE) + #define BTN_EN1 59 // AUX2 PIN 3 + #define BTN_EN2 63 // AUX2 PIN 4 + #define BTN_ENC 49 // AUX3 PIN 7 + #else + #define BTN_EN1 37 + #define BTN_EN2 35 + #define BTN_ENC 31 + #endif + + #if ENABLED(G3D_PANEL) + #define SD_DETECT_PIN 49 + #define KILL_PIN 41 + #else + //#define SD_DETECT_PIN -1 // Ramps doesn't use this + #endif + + #endif + #endif // NEWPANEL + +#endif // HAS_WIRED_LCD diff --git a/Marlin/src/pins/stm32f4/pins_BLACK_STM32F407VE.h b/Marlin/src/pins/stm32f4/pins_BLACK_STM32F407VE.h new file mode 100644 index 000000000000..b13d495542f8 --- /dev/null +++ b/Marlin/src/pins/stm32f4/pins_BLACK_STM32F407VE.h @@ -0,0 +1,159 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * STM32F407VET6 with RAMPS-like shield + * 'Black' STM32F407VET6 board - https://www.stm32duino.com/viewtopic.php?t=485 + * Shield - https://github.com/jmz52/Hardware + */ + +#if NOT_TARGET(STM32F4, STM32F4xx) + #error "Oops! Select an STM32F4 board in 'Tools > Board.'" +#elif HOTENDS > 2 || E_STEPPERS > 2 + #error "Black STM32F4VET6 supports up to 2 hotends / E-steppers." +#endif + +#ifndef BOARD_INFO_NAME + #define BOARD_INFO_NAME "Black STM32F4VET6" +#endif + +#define DEFAULT_MACHINE_NAME "STM32F407VET6" + +//#define I2C_EEPROM +#define SRAM_EEPROM_EMULATION +#define MARLIN_EEPROM_SIZE 0x2000 // 8KB + +// +// Servos +// +#define SERVO0_PIN PC6 +#define SERVO1_PIN PC7 + +// +// Limit Switches +// +#define X_MIN_PIN PC13 +#define X_MAX_PIN PA15 +#define Y_MIN_PIN PA5 +#define Y_MAX_PIN PD12 +#define Z_MIN_PIN PD14 +#define Z_MAX_PIN PD15 + +// +// Steppers +// +#define X_STEP_PIN PC4 +#define X_DIR_PIN PA4 +#define X_ENABLE_PIN PE7 + +#define Y_STEP_PIN PE5 +#define Y_DIR_PIN PE2 +#define Y_ENABLE_PIN PE6 + +#define Z_STEP_PIN PD5 +#define Z_DIR_PIN PD3 +#define Z_ENABLE_PIN PD6 + +#define E0_STEP_PIN PD7 +#define E0_DIR_PIN PD0 +#define E0_ENABLE_PIN PB9 + +#define E1_STEP_PIN PE0 +#define E1_DIR_PIN PE1 +#define E1_ENABLE_PIN PB8 + +// +// Temperature Sensors +// +#define TEMP_0_PIN PC0 // T0 +#define TEMP_1_PIN PC1 // T1 +#define TEMP_BED_PIN PC2 // TB + +#ifndef TEMP_CHAMBER_PIN + #define TEMP_CHAMBER_PIN PC3 // TC +#endif + +// +// Heaters / Fans +// +#define HEATER_0_PIN PA2 // Heater0 +#define HEATER_1_PIN PA3 // Heater1 +#define HEATER_BED_PIN PA1 // Hotbed + +#define FAN_PIN PE9 // Fan0 +#define FAN1_PIN PE11 // Fan1 +#define FAN2_PIN PE13 // Fan2 +#define FAN3_PIN PE14 // Fan3 + +// +// Misc. Functions +// +#define LED_PIN PA6 +//#define LED_PIN PA7 +#define KILL_PIN PB1 + +// +// LCD / Controller +// +//#define SD_DETECT_PIN PC5 +//#define SD_DETECT_PIN PA8 // SDIO SD_DETECT_PIN, external SDIO card reader only + +#define BEEPER_PIN PD10 +#define LCD_PINS_RS PE15 +#define LCD_PINS_ENABLE PD8 +#define LCD_PINS_D4 PE10 +#define LCD_PINS_D5 PE12 +#define LCD_PINS_D6 PD1 +#define LCD_PINS_D7 PE8 +#define BTN_ENC PD9 +#define BTN_EN1 PD4 +#define BTN_EN2 PD13 + +#define DOGLCD_CS LCD_PINS_D5 +#define DOGLCD_A0 LCD_PINS_D6 + +// +// Onboard SD support +// +#define SDIO_D0_PIN PC8 +#define SDIO_D1_PIN PC9 +#define SDIO_D2_PIN PC10 +#define SDIO_D3_PIN PC11 +#define SDIO_CK_PIN PC12 +#define SDIO_CMD_PIN PD2 + +#ifndef SDCARD_CONNECTION + #define SDCARD_CONNECTION ONBOARD +#endif + +#if SD_CONNECTION_IS(ONBOARD) + #define SDIO_SUPPORT // Use SDIO for onboard SD + + #ifndef SDIO_SUPPORT + #define SOFTWARE_SPI // Use soft SPI for onboard SD + #define SDSS SDIO_D3_PIN + #define SCK_PIN SDIO_CK_PIN + #define MISO_PIN SDIO_D0_PIN + #define MOSI_PIN SDIO_CMD_PIN + #endif +#endif diff --git a/Marlin/src/pins/stm32f4/pins_BTT_BTT002_V1_0.h b/Marlin/src/pins/stm32f4/pins_BTT_BTT002_V1_0.h new file mode 100644 index 000000000000..c37f6cce0445 --- /dev/null +++ b/Marlin/src/pins/stm32f4/pins_BTT_BTT002_V1_0.h @@ -0,0 +1,268 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(STM32F4) + #error "Oops! Select an STM32F4 board in 'Tools > Board.'" +#elif HOTENDS > 1 || E_STEPPERS > 1 + #error "BIGTREE BTT002 V1.0 supports up to 1 hotends / E-steppers." +#endif + +#define BOARD_INFO_NAME "BTT BTT002 V1.0" + +// Use one of these or SDCard-based Emulation will be used +#if NO_EEPROM_SELECTED + //#define SRAM_EEPROM_EMULATION // Use BackSRAM-based EEPROM emulation + #define FLASH_EEPROM_EMULATION // Use Flash-based EEPROM emulation +#endif + +#if ENABLED(FLASH_EEPROM_EMULATION) + // Decrease delays and flash wear by spreading writes across the + // 128 kB sector allocated for EEPROM emulation. + #define FLASH_EEPROM_LEVELING +#endif + +// Ignore temp readings during development. +//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 + +// +// Limit Switches +// +#define X_STOP_PIN PD3 +#define Y_STOP_PIN PD2 +#define Z_STOP_PIN PD1 // Shares J4 connector with PC3 + +// +// Z Probe must be this pin +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN PD1 +#endif + +// +// Filament Runout Sensor +// +#ifndef FIL_RUNOUT_PIN + #define FIL_RUNOUT_PIN PA15 +#endif + +// +// Power Loss Detection +// +#ifndef POWER_LOSS_PIN + #define POWER_LOSS_PIN PD4 +#endif + +// +// Steppers +// +#define X_STEP_PIN PA9 +#define X_DIR_PIN PA10 +#define X_ENABLE_PIN PA8 +#ifndef X_CS_PIN + #define X_CS_PIN PE2 +#endif + +#define Y_STEP_PIN PC8 +#define Y_DIR_PIN PC9 +#define Y_ENABLE_PIN PC7 + #ifndef Y_CS_PIN + #define Y_CS_PIN PE3 +#endif + +#define Z_STEP_PIN PD15 +#define Z_DIR_PIN PC6 +#define Z_ENABLE_PIN PD14 +#ifndef Z_CS_PIN + #define Z_CS_PIN PE4 +#endif + +#define E0_STEP_PIN PD12 +#define E0_DIR_PIN PD13 +#define E0_ENABLE_PIN PD11 +#ifndef E0_CS_PIN + #define E0_CS_PIN PD7 +#endif + +// +// Software SPI pins for TMC2130 stepper drivers +// +#if ENABLED(TMC_USE_SW_SPI) + #ifndef TMC_SW_MOSI + #define TMC_SW_MOSI PB15 + #endif + #ifndef TMC_SW_MISO + #define TMC_SW_MISO PB14 + #endif + #ifndef TMC_SW_SCK + #define TMC_SW_SCK PB13 + #endif +#endif + +#if HAS_TMC_UART + /** + * TMC2208/TMC2209 stepper drivers + * + * Hardware serial communication ports. + * If undefined software serial is used according to the pins below + */ + //#define X_HARDWARE_SERIAL Serial1 + //#define X2_HARDWARE_SERIAL Serial1 + //#define Y_HARDWARE_SERIAL Serial1 + //#define Y2_HARDWARE_SERIAL Serial1 + //#define Z_HARDWARE_SERIAL Serial1 + //#define Z2_HARDWARE_SERIAL Serial1 + //#define E0_HARDWARE_SERIAL Serial1 + //#define E1_HARDWARE_SERIAL Serial1 + //#define E2_HARDWARE_SERIAL Serial1 + //#define E3_HARDWARE_SERIAL Serial1 + //#define E4_HARDWARE_SERIAL Serial1 + + // + // Software serial ## + // + #define X_SERIAL_TX_PIN PE2 + #define X_SERIAL_RX_PIN PE2 + + #define Y_SERIAL_TX_PIN PE3 + #define Y_SERIAL_RX_PIN PE3 + + #define Z_SERIAL_TX_PIN PE4 + #define Z_SERIAL_RX_PIN PE4 + + #define E0_SERIAL_TX_PIN PD7 + #define E0_SERIAL_RX_PIN PD7 + + // Reduce baud rate to improve software serial reliability + #define TMC_BAUD_RATE 19200 +#endif + +// +// Temperature Sensors +// +#define TEMP_0_PIN PA2 // T0 <-> E0 +#define TEMP_1_PIN PA0 // T1 <-> E1 +#define TEMP_BED_PIN PA1 // T2 <-> Bed +#define TEMP_PROBE_PIN PC3 // Shares J4 connector with PD1 + +// +// Heaters / Fans +// +#define HEATER_0_PIN PE6 // Heater0 +#define HEATER_BED_PIN PE5 // Hotbed +#define FAN_PIN PB8 // Fan1 +#define FAN1_PIN PB9 // Fan0 + +// HAL SPI1 pins +#define CUSTOM_SPI_PINS +#if ENABLED(CUSTOM_SPI_PINS) + #define SCK_PIN PA5 // SPI1 SCLK + #define SS_PIN PA4 // SPI1 SSEL + #define MISO_PIN PA6 // SPI1 MISO + #define MOSI_PIN PA7 // SPI1 MOSI +#endif + +// +// Misc. Functions +// +#define SDSS PA4 + +/** + * -------------------------------------BTT002 V1.0-------------------------------------------- + * ----- ----- | + * PA3 | · · | GND 5V | · · | GND | + * NRESET | · · | PC4(SD_DET) (LCD_D7) PE13 | · · | PE12 (LCD_D6) | + * (MOSI)PA7 | · · | PB0(BTN_EN2) (LCD_D5) PE11 | · · | PE10 (LCD_D4) | + * (SD_SS)PA4 | · · | PC5(BTN_EN1) (LCD_RS) PE8 | · · | PE9 (LCD_EN) | + * (SCK)PA5 | · · | PA6(MISO) (BTN_ENC) PB1 | · · | PE7 (BEEPER) | + * ----- ----- | + * EXP2 EXP1 | + * -------------------------------------------------------------------------------------------- + */ + +// +// LCDs and Controllers +// +#if HAS_WIRED_LCD + #define BEEPER_PIN PE7 + #define BTN_ENC PB1 + + #if ENABLED(CR10_STOCKDISPLAY) + #define LCD_PINS_RS PE12 + + #define BTN_EN1 PE9 + #define BTN_EN2 PE10 + + #define LCD_PINS_ENABLE PE13 + #define LCD_PINS_D4 PE11 + + #else + + #define LCD_PINS_RS PE8 + + #define BTN_EN1 PC5 + #define BTN_EN2 PB0 + #define SD_DETECT_PIN PC4 + + #define LCD_SDSS PA4 + + #define LCD_PINS_ENABLE PE9 + #define LCD_PINS_D4 PE10 + + #if ENABLED(ULTIPANEL) + #define LCD_PINS_D5 PE11 + #define LCD_PINS_D6 PE12 + #define LCD_PINS_D7 PE13 + #endif + + #endif + + // Alter timing for graphical display + #if HAS_MARLINUI_U8GLIB + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(96) + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(48) + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(600) + #endif + #endif + +#endif // HAS_WIRED_LCD + +// +// RGB LEDs +// +#ifndef RGB_LED_R_PIN + #define RGB_LED_R_PIN PB5 +#endif +#ifndef RGB_LED_G_PIN + #define RGB_LED_G_PIN PB4 +#endif +#ifndef RGB_LED_B_PIN + #define RGB_LED_B_PIN PB3 +#endif +#ifndef RGB_LED_W_PIN + #define RGB_LED_W_PIN -1 +#endif diff --git a/Marlin/src/pins/stm32f4/pins_BTT_GTR_V1_0.h b/Marlin/src/pins/stm32f4/pins_BTT_GTR_V1_0.h new file mode 100644 index 000000000000..dc8ce9f2d1b2 --- /dev/null +++ b/Marlin/src/pins/stm32f4/pins_BTT_GTR_V1_0.h @@ -0,0 +1,411 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(STM32F4) + #error "Oops! Select an STM32F4 board in 'Tools > Board.'" +#elif HOTENDS > 8 || E_STEPPERS > 8 + #error "BIGTREE GTR V1.0 supports up to 8 hotends / E-steppers." +#elif HOTENDS > MAX_EXTRUDERS || E_STEPPERS > MAX_EXTRUDERS + #error "Marlin extruder/hotends limit! Increase MAX_EXTRUDERS to continue." +#endif + +#define BOARD_INFO_NAME "BTT GTR V1.0" + +// Onboard I2C EEPROM +#define I2C_EEPROM +#define MARLIN_EEPROM_SIZE 0x2000 // 8KB (24C64 ... 64Kb = 8KB) + +#define TP // Enable to define servo and probe pins + +// +// Servos +// +#if ENABLED(TP) + #define SERVO0_PIN PB11 +#endif + +#define PS_ON_PIN PH6 + +// +// Limit Switches +// +#define X_MIN_PIN PF2 +#define X_MAX_PIN PG14 +#define Y_MIN_PIN PC13 +#define Y_MAX_PIN PG9 +#define Z_MIN_PIN PE0 +#define Z_MAX_PIN PD3 + +// +// Pins on the extender +// +//#define X_MIN_PIN PI4 +//#define X2_MIN_PIN PF12 +//#define Y_MIN_PIN PF4 +//#define Y2_MIN_PIN PI7 +//#define Z_MIN_PIN PF6 + +#if ENABLED(TP) && !defined(Z_MIN_PROBE_PIN) + #define Z_MIN_PROBE_PIN PH11 // Z Probe must be PH11 +#endif + +// +// Steppers +// +#define X_STEP_PIN PC15 +#define X_DIR_PIN PF0 +#define X_ENABLE_PIN PF1 +#ifndef X_CS_PIN + #define X_CS_PIN PC14 +#endif + +#define Y_STEP_PIN PE3 +#define Y_DIR_PIN PE2 +#define Y_ENABLE_PIN PE4 +#ifndef Y_CS_PIN + #define Y_CS_PIN PE1 +#endif + +#define Z_STEP_PIN PB8 +#define Z_DIR_PIN PB7 // PB7 +#define Z_ENABLE_PIN PB9 +#ifndef Z_CS_PIN + #define Z_CS_PIN PB5 +#endif + +#define E0_STEP_PIN PG12 +#define E0_DIR_PIN PG11 +#define E0_ENABLE_PIN PG13 +#ifndef E0_CS_PIN + #define E0_CS_PIN PG10 +#endif + +#define E1_STEP_PIN PD6 +#define E1_DIR_PIN PD5 +#define E1_ENABLE_PIN PD7 +#ifndef E1_CS_PIN + #define E1_CS_PIN PD4 +#endif + +#define E2_STEP_PIN PD1 +#define E2_DIR_PIN PD0 +#define E2_ENABLE_PIN PD2 +#ifndef E2_CS_PIN + #define E2_CS_PIN PC12 +#endif + +#define E3_STEP_PIN PF3 +#define E3_DIR_PIN PG3 +#define E3_ENABLE_PIN PF8 +#ifndef E3_CS_PIN + #define E3_CS_PIN PG4 +#endif + +#define E4_STEP_PIN PD14 +#define E4_DIR_PIN PD11 +#define E4_ENABLE_PIN PG2 +#ifndef E4_CS_PIN + #define E4_CS_PIN PE15 +#endif + +#define E5_STEP_PIN PE12 +#define E5_DIR_PIN PE10 +#define E5_ENABLE_PIN PF14 +#ifndef E5_CS_PIN + #define E5_CS_PIN PE7 +#endif + +#define E6_STEP_PIN PG0 +#define E6_DIR_PIN PG1 +#define E6_ENABLE_PIN PE8 +#ifndef E6_CS_PIN + #define E6_CS_PIN PF15 +#endif + +#define E7_STEP_PIN PH12 +#define E7_DIR_PIN PH15 +#define E7_ENABLE_PIN PI0 +#ifndef E7_CS_PIN + #define E7_CS_PIN PH14 +#endif + +// +// Software SPI pins for TMC2130 stepper drivers +// +#if ENABLED(TMC_USE_SW_SPI) + #ifndef TMC_SW_MOSI + #define TMC_SW_MOSI PG15 + #endif + #ifndef TMC_SW_MISO + #define TMC_SW_MISO PB6 + #endif + #ifndef TMC_SW_SCK + #define TMC_SW_SCK PB3 + #endif +#endif + +#if HAS_TMC_UART + /** + * TMC2208/TMC2209 stepper drivers + * + * Hardware serial communication ports. + * If undefined software serial is used according to the pins below + */ + //#define X_HARDWARE_SERIAL Serial1 + //#define X2_HARDWARE_SERIAL Serial1 + //#define Y_HARDWARE_SERIAL Serial1 + //#define Y2_HARDWARE_SERIAL Serial1 + //#define Z_HARDWARE_SERIAL Serial1 + //#define Z2_HARDWARE_SERIAL Serial1 + //#define E0_HARDWARE_SERIAL Serial1 + //#define E1_HARDWARE_SERIAL Serial1 + //#define E2_HARDWARE_SERIAL Serial1 + //#define E3_HARDWARE_SERIAL Serial1 + //#define E4_HARDWARE_SERIAL Serial1 + //#define E5_HARDWARE_SERIAL Serial1 + //#define E6_HARDWARE_SERIAL Serial1 + //#define E7_HARDWARE_SERIAL Serial1 + + // + // Software serial + // + #define X_SERIAL_TX_PIN PC14 + #define X_SERIAL_RX_PIN PC14 + + #define Y_SERIAL_TX_PIN PE1 + #define Y_SERIAL_RX_PIN PE1 + + #define Z_SERIAL_TX_PIN PB5 + #define Z_SERIAL_RX_PIN PB5 + + #define E0_SERIAL_TX_PIN PG10 + #define E0_SERIAL_RX_PIN PG10 + + #define E1_SERIAL_TX_PIN PD4 + #define E1_SERIAL_RX_PIN PD4 + + #define E2_SERIAL_TX_PIN PC12 + #define E2_SERIAL_RX_PIN PC12 + + #define E3_SERIAL_TX_PIN PG4 + #define E3_SERIAL_RX_PIN PG4 + + #define E4_SERIAL_TX_PIN PE15 + #define E4_SERIAL_RX_PIN PE15 + + #define E5_SERIAL_TX_PIN PE7 + #define E5_SERIAL_RX_PIN PE7 + + #define E6_SERIAL_TX_PIN PF15 + #define E6_SERIAL_RX_PIN PF15 + + #define E7_SERIAL_TX_PIN PH14 + #define E7_SERIAL_RX_PIN PH14 + + // Reduce baud rate to improve software serial reliability + #define TMC_BAUD_RATE 19200 +#endif + +// +// Temperature Sensors +// +#define TEMP_0_PIN PC1 // T1 <-> E0 +#define TEMP_1_PIN PC2 // T2 <-> E1 +#define TEMP_2_PIN PC3 // T3 <-> E2 + +#define TEMP_3_PIN PA3 // T4 <-> E3 +#define TEMP_4_PIN PF9 // T5 <-> E4 +#define TEMP_5_PIN PF10 // T6 <-> E5 +#define TEMP_6_PIN PF7 // T7 <-> E6 +#define TEMP_7_PIN PF5 // T8 <-> E7 + +#define TEMP_BED_PIN PC0 // T0 <-> Bed + +// SPI for Max6675 or Max31855 Thermocouple +// Uses a separate SPI bus +// If you have a two-way thermocouple, you can customize two THERMO_CSx_PIN pins (x:1~2) + +#define THERMO_SCK_PIN PI1 // SCK +#define THERMO_DO_PIN PI2 // MISO +#define THERMO_CS1_PIN PH9 // CS1 +#define THERMO_CS2_PIN PH2 // CS2 + +#define MAX6675_SS_PIN THERMO_CS1_PIN +#define MAX6675_SS2_PIN THERMO_CS2_PIN +#define MAX6675_SCK_PIN THERMO_SCK_PIN +#define MAX6675_DO_PIN THERMO_DO_PIN + +// +// Heaters / Fans +// +#define HEATER_0_PIN PB1 // Heater0 +#define HEATER_1_PIN PA1 // Heater1 +#define HEATER_2_PIN PB0 // Heater2 + +#define HEATER_3_PIN PD15 // Heater3 +#define HEATER_4_PIN PD13 // Heater4 +#define HEATER_5_PIN PD12 // Heater5 +#define HEATER_6_PIN PE13 // Heater6 +#define HEATER_7_PIN PI6 // Heater7 + +#define HEATER_BED_PIN PA2 // Hotbed + +#define FAN_PIN PE5 // Fan0 +#define FAN1_PIN PE6 // Fan1 +#define FAN2_PIN PC8 // Fan2 + +#define FAN3_PIN PI5 // Fan3 +#define FAN4_PIN PE9 // Fan4 +#define FAN5_PIN PE11 // Fan5 +//#define FAN6_PIN PC9 // Fan6 +//#define FAN7_PIN PE14 // Fan7 + +#ifndef SDCARD_CONNECTION + #define SDCARD_CONNECTION ONBOARD +#endif + +// +// By default the LCD SD (SPI2) is enabled +// Onboard SD is on a completely separate SPI bus, and requires +// overriding pins to access. +// +#if SD_CONNECTION_IS(LCD) + + #define SD_DETECT_PIN PB10 + #define SDSS PB12 + +#elif SD_CONNECTION_IS(ONBOARD) + + // Instruct the STM32 HAL to override the default SPI pins from the variant.h file + #define CUSTOM_SPI_PINS + #define SDSS PA4 + #define SS_PIN SDSS + #define SCK_PIN PA5 + #define MISO_PIN PA6 + #define MOSI_PIN PA7 + #define SD_DETECT_PIN PC4 + +#elif SD_CONNECTION_IS(CUSTOM_CABLE) + #error "CUSTOM_CABLE is not a supported SDCARD_CONNECTION for this board" +#endif + +/** + * ----- ----- + * NC | · · | GND 5V | · · | GND + * RESET | · · | PB10(SD_DETECT) (LCD_D7) PG5 | · · | PG6 (LCD_D6) + * (MOSI)PB15 | · · | PH10(BTN_EN2) (LCD_D5) PG7 | · · | PG8 (LCD_D4) + * (SD_SS)PB12 | · · | PD10(BTN_EN1) (LCD_RS) PA8 | · · | PC10 (LCD_EN) + * (SCK)PB13 | · · | PB14(MISO) (BTN_ENC) PA15 | · · | PC11 (BEEPER) + * ----- ----- + * EXP2 EXP1 + */ + +// +// LCDs and Controllers +// +#if HAS_WIRED_LCD + #define BEEPER_PIN PC11 + #define BTN_ENC PA15 + + #if ENABLED(CR10_STOCKDISPLAY) + #define LCD_PINS_RS PG6 + + #define BTN_EN1 PC10 + #define BTN_EN2 PG8 + + #define LCD_PINS_ENABLE PG5 + #define LCD_PINS_D4 PG7 + + // CR10_STOCKDISPLAY default timing is too fast + #undef BOARD_ST7920_DELAY_1 + #undef BOARD_ST7920_DELAY_2 + #undef BOARD_ST7920_DELAY_3 + + #elif ENABLED(MKS_MINI_12864) + #define DOGLCD_A0 PG6 + #define DOGLCD_CS PG7 + #define BTN_EN1 PD10 + #define BTN_EN2 PH10 + + #if SD_CONNECTION_IS(ONBOARD) + #define SOFTWARE_SPI + #endif + #else + + #define LCD_PINS_RS PA8 + + #define BTN_EN1 PD10 + #define BTN_EN2 PH10 + + #define LCD_PINS_ENABLE PC10 + #define LCD_PINS_D4 PG8 + + #if ENABLED(FYSETC_MINI_12864) + #define DOGLCD_CS PC10 + #define DOGLCD_A0 PA8 + + #if SD_CONNECTION_IS(ONBOARD) + #define SOFTWARE_SPI + #endif + + //#define LCD_BACKLIGHT_PIN -1 + #define LCD_RESET_PIN PG8 // Must be high or open for LCD to operate normally. + #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) + #ifndef RGB_LED_R_PIN + #define RGB_LED_R_PIN PG7 + #endif + #ifndef RGB_LED_G_PIN + #define RGB_LED_G_PIN PG6 + #endif + #ifndef RGB_LED_B_PIN + #define RGB_LED_B_PIN PG5 + #endif + #elif ENABLED(FYSETC_MINI_12864_2_1) + #define NEOPIXEL_PIN PF13 + #endif + #endif // !FYSETC_MINI_12864 + + #if ENABLED(ULTIPANEL) + #define LCD_PINS_D5 PG7 + #define LCD_PINS_D6 PG6 + #define LCD_PINS_D7 PG5 + #endif + + #endif + + // Alter timing for graphical display + #if HAS_MARLINUI_U8GLIB + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(96) + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(48) + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(600) + #endif + #endif + +#endif // HAS_WIRED_LCD + +#undef TP diff --git a/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_V1_1.h b/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_V1_1.h new file mode 100644 index 000000000000..fb4b17b6fb22 --- /dev/null +++ b/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_V1_1.h @@ -0,0 +1,30 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if HOTENDS > 3 || E_STEPPERS > 3 + #error "BIGTREE SKR Pro V1.1 supports up to 3 hotends / E-steppers." +#endif + +#define BOARD_INFO_NAME "BTT SKR Pro V1.1" + +#include "pins_BTT_SKR_PRO_common.h" diff --git a/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_V1_2.h b/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_V1_2.h new file mode 100644 index 000000000000..615751b62d37 --- /dev/null +++ b/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_V1_2.h @@ -0,0 +1,30 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if HOTENDS > 3 || E_STEPPERS > 3 + #error "BIGTREE SKR Pro V1.2 supports up to 3 hotends / E-steppers." +#endif + +#define BOARD_INFO_NAME "BTT SKR Pro V1.2" + +#include "pins_BTT_SKR_PRO_common.h" diff --git a/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_common.h b/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_common.h new file mode 100644 index 000000000000..83fd987d9dbf --- /dev/null +++ b/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_common.h @@ -0,0 +1,394 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(STM32F4) + #error "Oops! Select an STM32F4 board in 'Tools > Board.'" +#endif + +// Use one of these or SDCard-based Emulation will be used +#if NO_EEPROM_SELECTED + //#define SRAM_EEPROM_EMULATION // Use BackSRAM-based EEPROM emulation + #define FLASH_EEPROM_EMULATION // Use Flash-based EEPROM emulation +#endif + +#if ENABLED(FLASH_EEPROM_EMULATION) + // Decrease delays and flash wear by spreading writes across the + // 128 kB sector allocated for EEPROM emulation. + #define FLASH_EEPROM_LEVELING +#endif + +// +// Servos +// +#define SERVO0_PIN PA1 +#define SERVO1_PIN PC9 + +// +// Trinamic Stallguard pins +// +#define X_DIAG_PIN PB10 // X- +#define Y_DIAG_PIN PE12 // Y- +#define Z_DIAG_PIN PG8 // Z- +#define E0_DIAG_PIN PE15 // E0 +#define E1_DIAG_PIN PE10 // E1 +#define E2_DIAG_PIN PG5 // E2 + +// +// Limit Switches +// +#ifdef X_STALL_SENSITIVITY + #define X_STOP_PIN X_DIAG_PIN + #if X_HOME_DIR < 0 + #define X_MAX_PIN PE15 // E0 + #else + #define X_MIN_PIN PE15 // E0 + #endif +#else + #define X_MIN_PIN PB10 // X- + #define X_MAX_PIN PE15 // E0 +#endif + +#ifdef Y_STALL_SENSITIVITY + #define Y_STOP_PIN Y_DIAG_PIN + #if Y_HOME_DIR < 0 + #define Y_MAX_PIN PE10 // E1 + #else + #define Y_MIN_PIN PE10 // E1 + #endif +#else + #define Y_MIN_PIN PE12 // Y- + #define Y_MAX_PIN PE10 // E1 +#endif + +#ifdef Z_STALL_SENSITIVITY + #define Z_STOP_PIN Z_DIAG_PIN + #if Z_HOME_DIR < 0 + #define Z_MAX_PIN PG5 // E2 + #else + #define Z_MIN_PIN PG5 // E2 + #endif +#else + #define Z_MIN_PIN PG8 // Z- + #define Z_MAX_PIN PG5 // E2 +#endif + +// +// Z Probe must be this pin +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN PA2 +#endif + +// +// Filament Runout Sensor +// +#ifndef FIL_RUNOUT_PIN + #define FIL_RUNOUT_PIN PE15 +#endif +#ifndef FIL_RUNOUT2_PIN + #define FIL_RUNOUT2_PIN PE10 +#endif +#ifndef FIL_RUNOUT3_PIN + #define FIL_RUNOUT3_PIN PG5 +#endif + +// +// Steppers +// +#define X_STEP_PIN PE9 +#define X_DIR_PIN PF1 +#define X_ENABLE_PIN PF2 +#ifndef X_CS_PIN + #define X_CS_PIN PA15 +#endif + +#define Y_STEP_PIN PE11 +#define Y_DIR_PIN PE8 +#define Y_ENABLE_PIN PD7 + #ifndef Y_CS_PIN + #define Y_CS_PIN PB8 +#endif + +#define Z_STEP_PIN PE13 +#define Z_DIR_PIN PC2 +#define Z_ENABLE_PIN PC0 +#ifndef Z_CS_PIN + #define Z_CS_PIN PB9 +#endif + +#define E0_STEP_PIN PE14 +#define E0_DIR_PIN PA0 +#define E0_ENABLE_PIN PC3 +#ifndef E0_CS_PIN + #define E0_CS_PIN PB3 +#endif + +#define E1_STEP_PIN PD15 +#define E1_DIR_PIN PE7 +#define E1_ENABLE_PIN PA3 +#ifndef E1_CS_PIN + #define E1_CS_PIN PG15 +#endif + +#define E2_STEP_PIN PD13 +#define E2_DIR_PIN PG9 +#define E2_ENABLE_PIN PF0 +#ifndef E2_CS_PIN + #define E2_CS_PIN PG12 +#endif + +// +// Software SPI pins for TMC2130 stepper drivers +// +#if ENABLED(TMC_USE_SW_SPI) + #ifndef TMC_SW_MOSI + #define TMC_SW_MOSI PC12 + #endif + #ifndef TMC_SW_MISO + #define TMC_SW_MISO PC11 + #endif + #ifndef TMC_SW_SCK + #define TMC_SW_SCK PC10 + #endif +#endif + +#if HAS_TMC_UART + /** + * TMC2208/TMC2209 stepper drivers + * + * Hardware serial communication ports. + * If undefined software serial is used according to the pins below + */ + //#define X_HARDWARE_SERIAL Serial1 + //#define X2_HARDWARE_SERIAL Serial1 + //#define Y_HARDWARE_SERIAL Serial1 + //#define Y2_HARDWARE_SERIAL Serial1 + //#define Z_HARDWARE_SERIAL Serial1 + //#define Z2_HARDWARE_SERIAL Serial1 + //#define E0_HARDWARE_SERIAL Serial1 + //#define E1_HARDWARE_SERIAL Serial1 + //#define E2_HARDWARE_SERIAL Serial1 + //#define E3_HARDWARE_SERIAL Serial1 + //#define E4_HARDWARE_SERIAL Serial1 + + // + // Software serial + // + #define X_SERIAL_TX_PIN PC13 + #define X_SERIAL_RX_PIN PC13 + + #define Y_SERIAL_TX_PIN PE3 + #define Y_SERIAL_RX_PIN PE3 + + #define Z_SERIAL_TX_PIN PE1 + #define Z_SERIAL_RX_PIN PE1 + + #define E0_SERIAL_TX_PIN PD4 + #define E0_SERIAL_RX_PIN PD4 + + #define E1_SERIAL_TX_PIN PD1 + #define E1_SERIAL_RX_PIN PD1 + + #define E2_SERIAL_TX_PIN PD6 + #define E2_SERIAL_RX_PIN PD6 + + // Reduce baud rate to improve software serial reliability + #define TMC_BAUD_RATE 19200 +#endif + +// +// Temperature Sensors +// +#define TEMP_0_PIN PF4 // T1 <-> E0 +#define TEMP_1_PIN PF5 // T2 <-> E1 +#define TEMP_2_PIN PF6 // T3 <-> E2 +#define TEMP_BED_PIN PF3 // T0 <-> Bed + +// +// Heaters / Fans +// +#define HEATER_0_PIN PB1 // Heater0 +#define HEATER_1_PIN PD14 // Heater1 +#define HEATER_2_PIN PB0 // Heater1 +#define HEATER_BED_PIN PD12 // Hotbed +#define FAN_PIN PC8 // Fan0 +#define FAN1_PIN PE5 // Fan1 +#define FAN2_PIN PE6 + +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN FAN1_PIN +#endif + +// +// Misc. Functions +// + +#ifndef SDCARD_CONNECTION + #define SDCARD_CONNECTION LCD +#endif + +// +// Onboard SD card +// Must use soft SPI because Marlin's default hardware SPI is tied to LCD's EXP2 +// +#if SD_CONNECTION_IS(LCD) + + #define SD_DETECT_PIN PF12 + #define SDSS PB12 + +#elif SD_CONNECTION_IS(ONBOARD) + + // The SKR Pro's ONBOARD SD interface is on SPI1. + // Due to a pull resistor on the clock line, it needs to use SPI Data Mode 3 to + // function with Hardware SPI. This is not currently configurable in the HAL, + // so force Software SPI to work around this issue. + #define SOFTWARE_SPI + #define SDSS PA4 + #define SCK_PIN PA5 + #define MISO_PIN PA6 + #define MOSI_PIN PB5 + #define SD_DETECT_PIN PB11 + +#elif SD_CONNECTION_IS(CUSTOM_CABLE) + #error "CUSTOM_CABLE is not a supported SDCARD_CONNECTION for this board" +#endif + +/** + * ----- ----- + * NC | · · | GND 5V | · · | GND + * RESET | · · | PF12(SD_DETECT) (LCD_D7) PG7 | · · | PG6 (LCD_D6) + * (MOSI)PB15 | · · | PF11(BTN_EN2) (LCD_D5) PG3 | · · | PG2 (LCD_D4) + * (SD_SS)PB12 | · · | PG10(BTN_EN1) (LCD_RS) PD10 | · · | PD11 (LCD_EN) + * (SCK)PB13 | · · | PB14(MISO) (BTN_ENC) PA8 | · · | PG4 (BEEPER) + * ----- ----- + * EXP2 EXP1 + */ + +// +// LCDs and Controllers +// +#if IS_TFTGLCD_PANEL + + #if ENABLED(TFTGLCD_PANEL_SPI) + #define TFTGLCD_CS PG10 + #endif + +#elif HAS_WIRED_LCD + + #define BEEPER_PIN PG4 + #define BTN_ENC PA8 + + #if ENABLED(CR10_STOCKDISPLAY) + + #define LCD_PINS_RS PG6 + + #define BTN_EN1 PD11 + #define BTN_EN2 PG2 + + #define LCD_PINS_ENABLE PG7 + #define LCD_PINS_D4 PG3 + + // CR10_STOCKDISPLAY default timing is too fast + #undef BOARD_ST7920_DELAY_1 + #undef BOARD_ST7920_DELAY_2 + #undef BOARD_ST7920_DELAY_3 + + #elif ENABLED(MKS_MINI_12864) + + #define DOGLCD_A0 PG6 + #define DOGLCD_CS PG3 + #define BTN_EN1 PG10 + #define BTN_EN2 PF11 + + #else + + #define LCD_PINS_RS PD10 + + #define BTN_EN1 PG10 + #define BTN_EN2 PF11 + + #define LCD_PINS_ENABLE PD11 + #define LCD_PINS_D4 PG2 + + #if ENABLED(FYSETC_MINI_12864) + #define DOGLCD_CS PD11 + #define DOGLCD_A0 PD10 + //#define LCD_BACKLIGHT_PIN -1 + #define LCD_RESET_PIN PG2 // Must be high or open for LCD to operate normally. + #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) + #ifndef RGB_LED_R_PIN + #define RGB_LED_R_PIN PG3 + #endif + #ifndef RGB_LED_G_PIN + #define RGB_LED_G_PIN PG6 + #endif + #ifndef RGB_LED_B_PIN + #define RGB_LED_B_PIN PG7 + #endif + #elif ENABLED(FYSETC_MINI_12864_2_1) + #define NEOPIXEL_PIN PG3 + #endif + #endif // !FYSETC_MINI_12864 + + #if ENABLED(ULTIPANEL) + #define LCD_PINS_D5 PG3 + #define LCD_PINS_D6 PG6 + #define LCD_PINS_D7 PG7 + #endif + + #endif + +#endif // HAS_WIRED_LCD + +// Alter timing for graphical display +#if HAS_MARLINUI_U8GLIB + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(96) + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(48) + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(600) + #endif +#endif + +// +// WIFI +// + +/** + * ----- + * TX | 1 2 | GND Enable PG1 // Must be high for module to run + * Enable | 3 4 | GPIO2 Reset PG0 // active low, probably OK to leave floating + * Reset | 5 6 | GPIO0 GPIO2 PF15 // must be high (ESP3D software configures this with a pullup so OK to leave as floating) + * 3.3V | 7 8 | RX GPIO0 PF14 // Leave as unused (ESP3D software configures this with a pullup so OK to leave as floating) + * ----- + * W1 + */ +#define ESP_WIFI_MODULE_COM 6 // Must also set either SERIAL_PORT or SERIAL_PORT_2 to this +#define ESP_WIFI_MODULE_BAUDRATE BAUDRATE // Must use same BAUDRATE as SERIAL_PORT & SERIAL_PORT_2 +#define ESP_WIFI_MODULE_RESET_PIN PG0 +#define ESP_WIFI_MODULE_ENABLE_PIN PG1 +#define ESP_WIFI_MODULE_GPIO0_PIN PF14 +#define ESP_WIFI_MODULE_GPIO2_PIN PF15 diff --git a/Marlin/src/pins/stm32f4/pins_FLYF407ZG.h b/Marlin/src/pins/stm32f4/pins_FLYF407ZG.h new file mode 100644 index 000000000000..808751d7a53d --- /dev/null +++ b/Marlin/src/pins/stm32f4/pins_FLYF407ZG.h @@ -0,0 +1,292 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(STM32F4, STM32F4xx) + #error "Oops! Select an STM32F4 board in 'Tools > Board.'" +#elif HOTENDS > 6 || E_STEPPERS > 6 + #error "FLYF407ZG supports up to 6 hotends / E-steppers." +#endif + +#define BOARD_INFO_NAME "FLYF407ZG" +#define BOARD_WEBSITE_URL "github.com/FLYmaker/FLYF407ZG" +#define DEFAULT_MACHINE_NAME BOARD_INFO_NAME + +// +// EEPROM Emulation +// +#if NO_EEPROM_SELECTED + #define FLASH_EEPROM_EMULATION + //#define SRAM_EEPROM_EMULATION + //#define I2C_EEPROM +#endif + +#if ENABLED(FLASH_EEPROM_EMULATION) + // Decrease delays and flash wear by spreading writes across + // the 128kB sector allocated for EEPROM emulation. + #define FLASH_EEPROM_LEVELING +#elif ENABLED(I2C_EEPROM) + #define MARLIN_EEPROM_SIZE 0x2000 // 8KB +#endif + +#ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE 0x1000 // 4KB +#endif + +// +// Servos +// +#define SERVO0_PIN PE11 + +// +// Limit Switches +// +#define X_MIN_PIN PC3 +#define X_MAX_PIN PC2 +#define Y_MIN_PIN PF2 +#define Y_MAX_PIN PF1 +#define Z_MIN_PIN PF0 +#define Z_MAX_PIN PC15 + +// +// Z Probe (when not Z_MIN_PIN) +// +#define Z_MIN_PROBE_PIN PC14 // Z3_PIN + +// +// Steppers +// + +#define X_STEP_PIN PB9 +#define X_DIR_PIN PE0 +#define X_ENABLE_PIN PE1 +#ifndef X_CS_PIN + #define X_CS_PIN PG13 +#endif + +#define Y_STEP_PIN PB8 +#define Y_DIR_PIN PG11 +#define Y_ENABLE_PIN PG12 +#ifndef Y_CS_PIN + #define Y_CS_PIN PG10 +#endif + +#define Z_STEP_PIN PA8 +#define Z_DIR_PIN PD6 +#define Z_ENABLE_PIN PD7 +#ifndef Z_CS_PIN + #define Z_CS_PIN PD5 +#endif + +#define E0_STEP_PIN PC7 +#define E0_DIR_PIN PD3 +#define E0_ENABLE_PIN PD4 +#ifndef E0_CS_PIN + #define E0_CS_PIN PD1 +#endif + +#define E1_STEP_PIN PC6 +#define E1_DIR_PIN PA15 +#define E1_ENABLE_PIN PD0 +#ifndef E1_CS_PIN + #define E1_CS_PIN PA14 +#endif + +#define E2_STEP_PIN PD15 +#define E2_DIR_PIN PG7 +#define E2_ENABLE_PIN PG8 +#ifndef E2_CS_PIN + #define E2_CS_PIN PG6 +#endif + +#define E3_STEP_PIN PD14 +#define E3_DIR_PIN PG4 +#define E3_ENABLE_PIN PG5 +#ifndef E3_CS_PIN + #define E3_CS_PIN PG3 +#endif + +#define E4_STEP_PIN PD13 +#define E4_DIR_PIN PD11 +#define E4_ENABLE_PIN PG2 +#ifndef E4_CS_PIN + #define E4_CS_PIN PD10 +#endif + +#define E5_STEP_PIN PD12 +#define E5_DIR_PIN PD8 +#define E5_ENABLE_PIN PD9 +#ifndef E5_CS_PIN + #define E5_CS_PIN PB12 +#endif + +// +// Temperature Sensors +// +#define TEMP_0_PIN PA0 // Analog Input +#define TEMP_1_PIN PC1 // Analog Input +#define TEMP_2_PIN PC0 // Analog Input +#define TEMP_3_PIN PF10 // Analog Input +#define TEMP_4_PIN PF5 // Analog Input +#define TEMP_5_PIN PF4 // Analog Input +#define TEMP_BED_PIN PF3 // Analog Input + +// +// Heaters / Fans +// +#define HEATER_0_PIN PF7 +#define HEATER_1_PIN PF6 +#define HEATER_2_PIN PE6 +#define HEATER_3_PIN PE5 +#define HEATER_4_PIN PE4 +#define HEATER_5_PIN PE3 +#define HEATER_BED_PIN PE2 + +#ifndef FAN_PIN + #define FAN_PIN PF8 +#endif +#define FAN1_PIN PF9 +#define FAN2_PIN PA2 +#define FAN3_PIN PA1 +#define FAN4_PIN PE13 +#define FAN5_PIN PB11 + +// +// Onboard SD support +// + +#define SDIO_D0_PIN PC8 +#define SDIO_D1_PIN PC9 +//#define SD_CARD_DETECT_PIN PC13 +#define SDIO_D2_PIN PC10 +#define SDIO_D3_PIN PC11 +#define SDIO_CK_PIN PC12 +#define SDIO_CMD_PIN PD2 + +#ifndef SDCARD_CONNECTION + #define SDCARD_CONNECTION ONBOARD +#endif + +#if SD_CONNECTION_IS(ONBOARD) + + #define SDIO_SUPPORT // Use SDIO for onboard SD + #ifndef SDIO_SUPPORT + #define SOFTWARE_SPI // Use soft SPI for onboard SD + #define SDSS SDIO_D3_PIN + #define SCK_PIN SDIO_CK_PIN + #define MISO_PIN SDIO_D0_PIN + #define MOSI_PIN SDIO_CMD_PIN + #endif + +#elif SD_CONNECTION_IS(LCD) + + #define SCK_PIN PB13 + #define MISO_PIN PB14 + #define MOSI_PIN PB15 + #define SDSS PF11 + #define SD_DETECT_PIN PB2 + +#endif + +// +// Trinamic Software SPI +// + +#if ENABLED(TMC_USE_SW_SPI) + #ifndef TMC_SW_MOSI + #define TMC_SW_MOSI PB15 + #endif + #ifndef TMC_SW_MISO + #define TMC_SW_MISO PB14 + #endif + #ifndef TMC_SW_SCK + #define TMC_SW_SCK PB13 + #endif +#endif + +// +// Trinamic Software Serial +// + +#if HAS_TMC_UART + #define X_SERIAL_TX_PIN PG13 + #define X_SERIAL_RX_PIN PG13 + + #define Y_SERIAL_TX_PIN PG10 + #define Y_SERIAL_RX_PIN PG10 + + #define Z_SERIAL_TX_PIN PD5 + #define Z_SERIAL_RX_PIN PD5 + + #define E0_SERIAL_TX_PIN PD1 + #define E0_SERIAL_RX_PIN PD1 + + #define E1_SERIAL_TX_PIN PA14 + #define E1_SERIAL_RX_PIN PA14 + + #define E2_SERIAL_TX_PIN PG6 + #define E2_SERIAL_RX_PIN PG6 + + #define E3_SERIAL_TX_PIN PG3 + #define E3_SERIAL_RX_PIN PG3 + + #define E4_SERIAL_TX_PIN PD10 + #define E4_SERIAL_RX_PIN PD10 + + #define E5_SERIAL_TX_PIN PB12 + #define E5_SERIAL_RX_PIN PB12 + +#endif + +// +// LCD / Controller +// + +#define BEEPER_PIN PB10 +#define LCD_PINS_RS PE12 +#define LCD_PINS_ENABLE PE14 +#define LCD_PINS_D4 PE10 +#define LCD_PINS_D5 PE9 +#define LCD_PINS_D6 PE8 +#define LCD_PINS_D7 PE7 +#define BTN_EN1 PC4 +#define BTN_EN2 PC5 +#define BTN_ENC PE15 + +// +// Filament runout +// + +#define FIL_RUNOUT_PIN PA3 + +// +// ST7920 Delays +// +#ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(96) +#endif +#ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(48) +#endif +#ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(715) +#endif diff --git a/Marlin/src/pins/stm32f4/pins_FYSETC_S6.h b/Marlin/src/pins/stm32f4/pins_FYSETC_S6.h new file mode 100644 index 000000000000..151f6c3bc06e --- /dev/null +++ b/Marlin/src/pins/stm32f4/pins_FYSETC_S6.h @@ -0,0 +1,289 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(STM32F4) + #error "Oops! Select an STM32F4 board in 'Tools > Board.'" +#elif HOTENDS > 3 || E_STEPPERS > 3 + #error "RUMBA32 supports up to 3 hotends / E-steppers." +#endif + +#ifndef BOARD_INFO_NAME + #define BOARD_INFO_NAME "FYSETC S6" +#endif +#ifndef DEFAULT_MACHINE_NAME + #define DEFAULT_MACHINE_NAME BOARD_INFO_NAME +#endif + +// Change the priority to 3. Priority 2 is for software serial. +//#define TEMP_TIMER_IRQ_PRIO 3 + +// +// EEPROM Emulation +// +#if NO_EEPROM_SELECTED + #define FLASH_EEPROM_EMULATION + //#define SRAM_EEPROM_EMULATION + //#define I2C_EEPROM +#endif + +#if ENABLED(FLASH_EEPROM_EMULATION) + // Decrease delays and flash wear by spreading writes across the + // 128 kB sector allocated for EEPROM emulation. + #define FLASH_EEPROM_LEVELING +#elif ENABLED(I2C_EEPROM) + #define MARLIN_EEPROM_SIZE 0x1000 // 4KB +#endif + +// +// Servos +// +#define SERVO0_PIN PA3 + +// +// Limit Switches +// +#define X_MIN_PIN PB14 +#define X_MAX_PIN PA1 +#define Y_MIN_PIN PB13 +#define Y_MAX_PIN PA2 +#define Z_MIN_PIN PA0 +#define Z_MAX_PIN PA3 + +// +// Filament Sensor +// share with X_MAX_PIN +// +#ifndef FIL_RUNOUT_PIN + #define FIL_RUNOUT_PIN PA1 +#endif + +// +// Steppers +// +#define X_STEP_PIN PE11 +#define X_DIR_PIN PE10 +#ifndef X_ENABLE_PIN + #define X_ENABLE_PIN PE12 +#endif +#define X_CS_PIN PE7 + +#define Y_STEP_PIN PD8 +#define Y_DIR_PIN PB12 +#define Y_ENABLE_PIN PD9 +#define Y_CS_PIN PE15 + +#define Z_STEP_PIN PD14 +#define Z_DIR_PIN PD13 +#define Z_ENABLE_PIN PD15 +#define Z_CS_PIN PD10 + +#define E0_STEP_PIN PD5 +#define E0_DIR_PIN PD6 +#define E0_ENABLE_PIN PD4 +#define E0_CS_PIN PD7 + +#define E1_STEP_PIN PE6 +#define E1_DIR_PIN PC13 +#define E1_ENABLE_PIN PE5 +#define E1_CS_PIN PC14 + +#define E2_STEP_PIN PE2 +#define E2_DIR_PIN PE4 +#define E2_ENABLE_PIN PE3 +#define E2_CS_PIN PC15 + +#if HAS_TMC_UART + // + // TMC2208/TMC2209 stepper drivers + // + + // + // Software serial + // + #ifndef X_SERIAL_TX_PIN + #define X_SERIAL_TX_PIN PE9 + #endif + #ifndef X_SERIAL_RX_PIN + #define X_SERIAL_RX_PIN PE8 + #endif + #ifndef Y_SERIAL_TX_PIN + #define Y_SERIAL_TX_PIN PE14 + #endif + #ifndef Y_SERIAL_RX_PIN + #define Y_SERIAL_RX_PIN PE13 + #endif + #ifndef Z_SERIAL_TX_PIN + #define Z_SERIAL_TX_PIN PD11 + #endif + #ifndef Z_SERIAL_RX_PIN + #define Z_SERIAL_RX_PIN PD12 + #endif + #ifndef E0_SERIAL_TX_PIN + #define E0_SERIAL_TX_PIN PD3 + #endif + #ifndef E0_SERIAL_RX_PIN + #define E0_SERIAL_RX_PIN PA15 + #endif + #ifndef E1_SERIAL_TX_PIN + #define E1_SERIAL_TX_PIN PC4 + #endif + #ifndef E1_SERIAL_RX_PIN + #define E1_SERIAL_RX_PIN PC5 + #endif + #ifndef E2_SERIAL_TX_PIN + #define E2_SERIAL_TX_PIN PE1 + #endif + #ifndef E2_SERIAL_RX_PIN + #define E2_SERIAL_RX_PIN PE0 + #endif +#endif + +// +// Temperature Sensors +// +#define TEMP_0_PIN PC0 +#define TEMP_1_PIN PC1 +#define TEMP_2_PIN PC2 +#define TEMP_BED_PIN PC3 + +// +// Heaters / Fans +// +#define HEATER_0_PIN PB3 +#define HEATER_1_PIN PB4 +#define HEATER_2_PIN PB15 +#define HEATER_BED_PIN PC8 + +#define FAN_PIN PB0 +#define FAN1_PIN PB1 +#define FAN2_PIN PB2 + +// +// SPI +// +#define SCK_PIN PA5 +#define MISO_PIN PA6 +#define MOSI_PIN PA7 + +// +// Misc. Functions +// +//#define LED_PIN PB14 +//#define BTN_PIN PC10 +//#define PS_ON_PIN PE11 +//#define KILL_PIN PC5 + +#define SDSS PA4 +#define SD_DETECT_PIN PB10 + +// +// LCD / Controller +// +#if HAS_WIRED_LCD + #define BEEPER_PIN PC9 + #define BTN_ENC PA8 + + #if ENABLED(CR10_STOCKDISPLAY) + #define LCD_PINS_RS PD0 + + #define BTN_EN1 PC11 + #define BTN_EN2 PC10 + + #define LCD_PINS_ENABLE PD1 + #define LCD_PINS_D4 PC12 + + // CR10_STOCKDISPLAY default timing is too fast + #undef BOARD_ST7920_DELAY_1 + #undef BOARD_ST7920_DELAY_2 + #undef BOARD_ST7920_DELAY_3 + + #else + + #define LCD_PINS_RS PD2 + + #define BTN_EN1 PC6 + #define BTN_EN2 PC7 + + #define LCD_SDSS PA4 + + #define LCD_PINS_ENABLE PC11 + #define LCD_PINS_D4 PC10 + + #if ENABLED(FYSETC_MINI_12864) + // See https://wiki.fysetc.com/Mini12864_Panel + #define DOGLCD_CS PC11 + #define DOGLCD_A0 PD2 + #if ENABLED(FYSETC_GENERIC_12864_1_1) + #define LCD_BACKLIGHT_PIN PD0 + #endif + #define LCD_RESET_PIN PC10 // Must be high or open for LCD to operate normally. + #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) + #ifndef RGB_LED_R_PIN + #define RGB_LED_R_PIN PC12 + #endif + #ifndef RGB_LED_G_PIN + #define RGB_LED_G_PIN PD0 + #endif + #ifndef RGB_LED_B_PIN + #define RGB_LED_B_PIN PD1 + #endif + #elif ENABLED(FYSETC_MINI_12864_2_1) + #define NEOPIXEL_PIN PC12 + #endif + #endif // !FYSETC_MINI_12864 + + #if ENABLED(ULTIPANEL) + #define LCD_PINS_D5 PC12 + #define LCD_PINS_D6 PD0 + #define LCD_PINS_D7 PD1 + #endif + + #endif + + // Alter timing for graphical display + #if HAS_MARLINUI_U8GLIB + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(96) + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(48) + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(600) + #endif + #endif + +#endif // HAS_WIRED_LCD + +#ifndef RGB_LED_R_PIN + #define RGB_LED_R_PIN PB6 +#endif +#ifndef RGB_LED_G_PIN + #define RGB_LED_G_PIN PB5 +#endif +#ifndef RGB_LED_B_PIN + #define RGB_LED_B_PIN PB7 +#endif +#ifndef RGB_LED_W_PIN + #define RGB_LED_W_PIN -1 +#endif diff --git a/Marlin/src/pins/stm32f4/pins_FYSETC_S6_V2_0.h b/Marlin/src/pins/stm32f4/pins_FYSETC_S6_V2_0.h new file mode 100644 index 000000000000..021ef1d5f6b8 --- /dev/null +++ b/Marlin/src/pins/stm32f4/pins_FYSETC_S6_V2_0.h @@ -0,0 +1,67 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#define BOARD_INFO_NAME "FYSETC S6 2.0" + +// +// EEPROM Emulation +// +#if NO_EEPROM_SELECTED + #undef NO_EEPROM_SELECTED + //#define FLASH_EEPROM_EMULATION + //#define SRAM_EEPROM_EMULATION + #define I2C_EEPROM +#endif + +// +// Steppers +// +#define X_ENABLE_PIN PE9 + +#if HAS_TMC_UART + #define X_SERIAL_TX_PIN PE8 + #define Y_SERIAL_TX_PIN PC4 + #define Y_SERIAL_RX_PIN PC4 + #define Z_SERIAL_TX_PIN PD12 + #define E0_SERIAL_TX_PIN PA15 + #define E1_SERIAL_TX_PIN PC5 + #define E2_SERIAL_TX_PIN PE0 +#endif + +// +// Software SPI pins for TMC2130 stepper drivers +// +#define TMC_USE_SW_SPI +#if ENABLED(TMC_USE_SW_SPI) + #ifndef TMC_SW_MOSI + #define TMC_SW_MOSI PE14 + #endif + #ifndef TMC_SW_MISO + #define TMC_SW_MISO PE13 + #endif + #ifndef TMC_SW_SCK + #define TMC_SW_SCK PE12 + #endif +#endif + +#include "pins_FYSETC_S6.h" diff --git a/Marlin/src/pins/stm32f4/pins_GENERIC_STM32F4.h b/Marlin/src/pins/stm32f4/pins_GENERIC_STM32F4.h new file mode 100644 index 000000000000..4acfd743b756 --- /dev/null +++ b/Marlin/src/pins/stm32f4/pins_GENERIC_STM32F4.h @@ -0,0 +1,197 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * To build with Arduino IDE use "Discovery F407VG" + * To build with PlatformIO use environment "STM32F4" + */ +#if NOT_TARGET(STM32F4, STM32F4xx) + #error "Oops! Select an STM32F4 board in 'Tools > Board.'" +#elif HOTENDS > 2 || E_STEPPERS > 2 + #error "STM32F4 supports up to 2 hotends / E-steppers." +#endif + +#define BOARD_INFO_NAME "Misc. STM32F4" +#define DEFAULT_MACHINE_NAME "STM32F407VET6" + +//#define I2C_EEPROM + +#ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE 0x1000 // 4KB +#endif + +// Ignore temp readings during development. +//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 + +// +// Limit Switches +// +#define X_MIN_PIN PE0 +#define X_MAX_PIN -1 +#define Y_MIN_PIN PE1 +#define Y_MAX_PIN -1 +#define Z_MIN_PIN PE14 +#define Z_MAX_PIN -1 + +// +// Z Probe (when not Z_MIN_PIN) +// + +//#ifndef Z_MIN_PROBE_PIN +// #define Z_MIN_PROBE_PIN PA4 +//#endif + +// +// Steppers +// + +#define X_STEP_PIN PD3 +#define X_DIR_PIN PD2 +#define X_ENABLE_PIN PD0 +//#ifndef X_CS_PIN +// #define X_CS_PIN PD1 +//#endif + +#define Y_STEP_PIN PE11 +#define Y_DIR_PIN PE10 +#define Y_ENABLE_PIN PE13 +//#ifndef Y_CS_PIN +// #define Y_CS_PIN PE12 +//#endif + +#define Z_STEP_PIN PD6 +#define Z_DIR_PIN PD7 +#define Z_ENABLE_PIN PD4 +//#ifndef Z_CS_PIN +// #define Z_CS_PIN PD5 +//#endif + +#define E0_STEP_PIN PB5 +#define E0_DIR_PIN PB6 +#define E0_ENABLE_PIN PB3 +//#ifndef E0_CS_PIN +// #define E0_CS_PIN PB4 +//#endif + +#define E1_STEP_PIN PE4 +#define E1_DIR_PIN PE2 +#define E1_ENABLE_PIN PE3 +//#ifndef E1_CS_PIN +// #define E1_CS_PIN PE5 +//#endif + +#define SCK_PIN PA5 +#define MISO_PIN PA6 +#define MOSI_PIN PA7 + +// +// Temperature Sensors +// + +#define TEMP_0_PIN PC0 // Analog Input +#define TEMP_1_PIN PC1 // Analog Input +#define TEMP_BED_PIN PC2 // Analog Input + +// +// Heaters / Fans +// + +#define HEATER_0_PIN PA1 +#define HEATER_1_PIN PA2 +#define HEATER_BED_PIN PA0 + +#ifndef FAN_PIN + #define FAN_PIN PC6 +#endif +#define FAN1_PIN PC7 +#define FAN2_PIN PC8 + +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN PC7 +#endif + +// +// Misc. Functions +// + +//#define CASE_LIGHT_PIN_CI PF13 +//#define CASE_LIGHT_PIN_DO PF14 +//#define NEOPIXEL_PIN PF13 + +// +// Průša i3 MK2 Multi Material Multiplexer Support +// + +//#define E_MUX0_PIN PG3 +//#define E_MUX1_PIN PG4 + +// +// Servos +// + +//#define SERVO0_PIN PE13 +//#define SERVO1_PIN PE14 + +#define SDSS PE7 +#define SS_PIN PE7 +#define LED_PIN PB7 //Alive +#define PS_ON_PIN PA10 +#define KILL_PIN PA8 +#define PWR_LOSS PA4 //Power loss / nAC_FAULT + +// +// LCD / Controller +// + +#define SD_DETECT_PIN PA15 +#define BEEPER_PIN PC9 +#define LCD_PINS_RS PE9 +#define LCD_PINS_ENABLE PE8 +#define LCD_PINS_D4 PB12 +#define LCD_PINS_D5 PB13 +#define LCD_PINS_D6 PB14 +#define LCD_PINS_D7 PB15 +#define BTN_EN1 PC4 +#define BTN_EN2 PC5 +#define BTN_ENC PC3 + +// +// Filament runout +// + +#define FIL_RUNOUT_PIN PA3 + +// +// ST7920 Delays +// +#if HAS_MARLINUI_U8GLIB + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(96) + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(48) + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(715) + #endif +#endif diff --git a/Marlin/src/pins/stm32f4/pins_LERDGE_K.h b/Marlin/src/pins/stm32f4/pins_LERDGE_K.h new file mode 100644 index 000000000000..48973688a058 --- /dev/null +++ b/Marlin/src/pins/stm32f4/pins_LERDGE_K.h @@ -0,0 +1,180 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(STM32F4, STM32F4xx) + #error "Oops! Select an STM32F4 board in 'Tools > Board.'" +#elif HOTENDS > 2 || E_STEPPERS > 2 + #error "LERDGE K supports up to 2 hotends / E-steppers." +#endif + +#define BOARD_INFO_NAME "Lerdge K" +#define DEFAULT_MACHINE_NAME "LERDGE" + +#define I2C_EEPROM + +// +// Servos +// +//#define SERVO0_PIN PB11 + +// +// Limit Switches +// +#define X_STOP_PIN PG3 +#define Y_STOP_PIN PG4 +#define Z_STOP_PIN PG5 + +// +// Z Probe (when not Z_MIN_PIN) +// +//#ifndef Z_MIN_PROBE_PIN +// #define Z_MIN_PROBE_PIN PG6 +//#endif + +// +// Filament runout +// +#define FIL_RUNOUT_PIN PE5 +#define FIL_RUNOUT2_PIN PE6 + +// +// Steppers +// +#define X_STEP_PIN PG1 +#define X_DIR_PIN PB10 +#define X_ENABLE_PIN PG0 +//#ifndef X_CS_PIN +// #define X_CS_PIN PE0 +//#endif + +#define Y_STEP_PIN PF14 +#define Y_DIR_PIN PF15 +#define Y_ENABLE_PIN PF13 +//#ifndef Y_CS_PIN +// #define Y_CS_PIN PE1 +//#endif + +#define Z_STEP_PIN PF11 +#define Z_DIR_PIN PF12 +#define Z_ENABLE_PIN PC5 +//#ifndef Z_CS_PIN +// #define Z_CS_PIN PE2 +//#endif + +#define E0_STEP_PIN PC14 +#define E0_DIR_PIN PC13 +#define E0_ENABLE_PIN PC15 +//#ifndef E0_CS_PIN +// #define E0_CS_PIN PE3 +//#endif + +#define E1_STEP_PIN PF1 +#define E1_DIR_PIN PF0 +#define E1_ENABLE_PIN PF2 +//#ifndef E1_CS_PIN +// #define E1_CS_PIN PE4 +//#endif + +// +// Temperature Sensors +// +#define TEMP_0_PIN PC1 // Analog Input +#define TEMP_1_PIN PC2 // Analog Input +#define TEMP_BED_PIN PC0 // Analog Input + +// Lergde-K can choose thermocouple/thermistor mode in software. +// For use with thermistors, these pins must be OUT/LOW. +// This is done automatically. +#define TEMP_0_TR_ENABLE_PIN PF10 +#define TEMP_1_TR_ENABLE_PIN PF9 + +// +// Heaters / Fans +// +#define HEATER_0_PIN PA1 +#define HEATER_1_PIN PA0 +#define HEATER_BED_PIN PA2 + +#ifndef FAN_PIN + #define FAN_PIN PF7 +#endif +#define FAN1_PIN PF6 +#define FAN2_PIN PF8 + +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN PF6 +#endif + +// +// LED / Lighting +// +//#define CASE_LIGHT_PIN_CI -1 +//#define CASE_LIGHT_PIN_DO -1 +//#define NEOPIXEL_PIN -1 +#ifndef RGB_LED_R_PIN + #define RGB_LED_R_PIN PB7 +#endif +#ifndef RGB_LED_G_PIN + #define RGB_LED_G_PIN PB8 +#endif +#ifndef RGB_LED_B_PIN + #define RGB_LED_B_PIN PB9 +#endif + +// +// SD support +// +#define SDIO_SUPPORT + +// +// Misc. Functions +// +#define SDSS PC11 +#define LED_PIN PA15 // Alive +#define PS_ON_PIN -1 +#define KILL_PIN -1 +#define POWER_LOSS_PIN PA4 // Power-loss / nAC_FAULT + +#define SCK_PIN PC12 +#define MISO_PIN PC8 +#define MOSI_PIN PD2 +#define SS_PIN PC11 + +#define SD_DETECT_PIN PA8 +#define BEEPER_PIN PC7 + +// +// LCD / Controller +// + +#define TFT_RESET_PIN PD6 +#define TFT_BACKLIGHT_PIN PD3 + +#define TFT_CS_PIN PD7 +#define TFT_RS_PIN PD11 + +#define TOUCH_CS_PIN PG15 +#define TOUCH_SCK_PIN PB3 +#define TOUCH_MOSI_PIN PB5 +#define TOUCH_MISO_PIN PB4 + +#define BTN_EN1 PG10 +#define BTN_EN2 PG11 +#define BTN_ENC PG9 diff --git a/Marlin/src/pins/stm32f4/pins_LERDGE_S.h b/Marlin/src/pins/stm32f4/pins_LERDGE_S.h new file mode 100644 index 000000000000..0600ed43389f --- /dev/null +++ b/Marlin/src/pins/stm32f4/pins_LERDGE_S.h @@ -0,0 +1,208 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(STM32F4, STM32F4xx) + #error "Oops! Select an STM32F4 board in 'Tools > Board.'" +#elif HOTENDS > 2 || E_STEPPERS > 2 + #error "LERDGE S supports up to 2 hotends / E-steppers." +#endif + +#define BOARD_INFO_NAME "Lerdge S" +#define DEFAULT_MACHINE_NAME "LERDGE" + +#define STEP_TIMER 4 +#define TEMP_TIMER 2 + +//#define I2C_EEPROM + +// +// Servos +// +#define SERVO0_PIN PD12 //confirmed +//#define SERVO1_PIN -1 + +// +// Limit Switches +// +#define X_MIN_PIN PG9 //confirmed +#define Y_MIN_PIN PG10 //confirmed +#define Z_MIN_PIN PG11 //confirmed + +#define X_MAX_PIN PG12 //confirmed +#define Y_MAX_PIN PG13 //confirmed +#define Z_MAX_PIN PG14 //confirmed + +// +// Filament runout +// +#define FIL_RUNOUT_PIN PC5 //confirmed + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN PG8 //confirmed +#endif + +// +// Steppers +// +#define X_STEP_PIN PF7 //confirmed +#define X_DIR_PIN PF8 //confirmed +#define X_ENABLE_PIN PF6 //confirmed + +#define Y_STEP_PIN PF10 //confirmed +#define Y_DIR_PIN PF11 //confirmed +#define Y_ENABLE_PIN PF9 //confirmed + +#define Z_STEP_PIN PF13 //confirmed +#define Z_DIR_PIN PF14 //confirmed +#define Z_ENABLE_PIN PF12 //confirmed + +#define E0_STEP_PIN PG0 //confirmed +#define E0_DIR_PIN PG1 //confirmed +#define E0_ENABLE_PIN PF15 //confirmed + +#define E1_STEP_PIN PG3 //confirmed +#define E1_DIR_PIN PG4 //confirmed +#define E1_ENABLE_PIN PG2 //confirmed + +// +// Temperature Sensors +// +#define TEMP_0_PIN PC0 // See below for activation of thermistor readings +#define TEMP_1_PIN PC1 // See below for activation of thermistor readings +#define TEMP_BED_PIN PC3 //confirmed + +// Lergde-S can choose thermocouple/thermistor mode in software. +// For use with thermistors, these pins must be OUT/LOW. +// This is done automatically. +#define TEMP_0_TR_ENABLE_PIN PF3 +#define TEMP_1_TR_ENABLE_PIN PF4 + +// MAX6675 Cold-Junction-Compensated K-Thermocouple to Digital Converter (0°C to +1024°C) +// https://datasheets.maximintegrated.com/en/ds/MAX6675.pdf + +#define MAX6675_SCK_PIN PB3 // max6675 datasheet: SCK pin, found with multimeter, not tested +#define MAX6675_DO_PIN PB4 // max6675 datasheet: SO pin, found with multimeter, not tested +#define MAX6675_SS_PIN PC4 // max6675 datasheet: /CS pin, found with multimeter, not tested and likely wrong + +// Expansion board with second max6675 +// Warning: Some boards leave the slot unpopulated. + +//#define MAX6675_SCK2_PIN PB3 // max6675 datasheet: SCK pin, found with multimeter, not tested +//#define MAX6675_DO2_PIN PB4 // max6675 datasheet: SO pin, found with multimeter, not tested +//#define MAX6675_SS2_PIN PF1 // max6675 datasheet: /CS pin, found with multimeter, not tested + +// +// Heaters / Fans +// +#define HEATER_0_PIN PA0 //confirmed +#define HEATER_1_PIN PA1 //confirmed +#define HEATER_BED_PIN PA3 //confirmed + +#define FAN_PIN PA15 // heater 0 fan 1 //confirmed +#define FAN1_PIN PB10 // heater 1 fan 2 //confirmed +#define FAN2_PIN PF5 // heater 0 fan 2 and heater 1 fan 1 (two sockets, switched together) //confirmed + +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN PF5 +#endif + +// +// Průša i3 MK2 Multi Material Multiplexer Support +// +//#define E_MUX0_PIN -1 +//#define E_MUX1_PIN -1 + +// +// LED / Lighting +// +//Lerdge-S board has two LED connectors (this is the one on the mainboard) +#define CASE_LIGHT_PIN PC7 //confirmed + +//on the dual extrusion addon board is a RGB connector +#define RGB_LED_R_PIN PC7 // Shared with the mainboard LED light connector (CASE_LIGHT_PIN), confirmed +#define RGB_LED_G_PIN PB0 //confirmed +#define RGB_LED_B_PIN PB1 //confirmed + +// +// Misc. Functions +// +#define SDSS PC11 // SD is working using SDIO, not sure if this definition is needed? +#define LED_PIN PC6 // Mainboard soldered green LED, confirmed +#define PS_ON_PIN PB2 // Board has a power module connector, confirmed +#define KILL_PIN -1 // There is no reset button on the LCD +#define POWER_LOSS_PIN -1 // PB2 could be used for this as well + +// +// SD support +// +#define SDIO_SUPPORT + +#define SCK_PIN PC12 //confirmed working +#define MISO_PIN PC8 //confirmed working +#define MOSI_PIN PD2 //confirmed working +#define SS_PIN PC11 //confirmed working + +#define SD_DETECT_PIN PG15 //confirmed + +// +// Persistent Storage +// If no option is selected below the SD Card will be used +// (this section modelled after pins_LONGER3D_LK.h) +// Warning: Not tested yet! Pins traced with multimeter, mistakes are possible +//#define SPI_EEPROM + +#if ENABLED(SPI_EEPROM) + // Lerdge has an SPI EEPROM Winbond W25Q128 (128Mbits) https://www.pjrc.com/teensy/W25Q128FV.pdf + #define SPI_CHAN_EEPROM1 1 + #define SPI_EEPROM1_CS PB12 // datasheet: /CS pin, found with multimeter, not tested + #define EEPROM_SCK PB13 // datasheet: CLK pin, found with multimeter, not tested + #define EEPROM_MISO PB14 // datasheet: DO pin, found with multimeter, not tested + #define EEPROM_MOSI PB15 // datasheet: DI pin, found with multimeter, not tested + #define EEPROM_PAGE_SIZE 0x1000U // 4KB (from datasheet) + #define MARLIN_EEPROM_SIZE 16UL * (EEPROM_PAGE_SIZE) // Limit to 64KB for now... +#else + #define MARLIN_EEPROM_SIZE 0x800U // On SD, Limit to 2KB, require this amount of RAM +#endif + +// +// LCD / Controller +// + +// The LCD is initialized in FSMC mode +#define BEEPER_PIN PD13 //confirmed + +#define BTN_EN1 PC14 //confirmed +#define BTN_EN2 PC15 //confirmed +#define BTN_ENC PC13 //confirmed + +#define TFT_RESET_PIN PD6 //confirmed +#define TFT_BACKLIGHT_PIN PD3 //confirmed + +#define TFT_CS_PIN PD7 // TFT works +#define TFT_RS_PIN PD11 // TFT works + +// There is touch, but calibration is off +#define TOUCH_CS_PIN PB6 +#define TOUCH_SCK_PIN PB3 +#define TOUCH_MOSI_PIN PB5 +#define TOUCH_MISO_PIN PB4 diff --git a/Marlin/src/pins/stm32f4/pins_LERDGE_X.h b/Marlin/src/pins/stm32f4/pins_LERDGE_X.h new file mode 100644 index 000000000000..bed51ca660cf --- /dev/null +++ b/Marlin/src/pins/stm32f4/pins_LERDGE_X.h @@ -0,0 +1,151 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(STM32F4, STM32F4xx) + #error "Oops! Select an STM32F4 board in 'Tools > Board.'" +#elif HOTENDS > 1 || E_STEPPERS > 1 + #error "LERDGE X supports only one hotend / E-steppers" +#endif + +#define BOARD_INFO_NAME "Lerdge X" +#define DEFAULT_MACHINE_NAME "LERDGE" + +#define STEP_TIMER 4 +#define TEMP_TIMER 2 + +#define I2C_EEPROM + +// +// Servos +// +//#define SERVO0_PIN PD13 + +// +// Limit Switches +// +#define X_STOP_PIN PB12 +#define Y_STOP_PIN PB13 +#define Z_STOP_PIN PB14 + +// +// Filament runout +// +#define FIL_RUNOUT_PIN PE1 + +// +// Z Probe (when not Z_MIN_PIN) +// +//#ifndef Z_MIN_PROBE_PIN +// #define Z_MIN_PROBE_PIN PB15 +//#endif + +// +// Steppers +// +#define X_STEP_PIN PB10 +#define X_DIR_PIN PB2 +#define X_ENABLE_PIN PB11 + +#define Y_STEP_PIN PB0 +#define Y_DIR_PIN PC5 +#define Y_ENABLE_PIN PB1 + +#define Z_STEP_PIN PA7 +#define Z_DIR_PIN PA6 +#define Z_ENABLE_PIN PC4 + +#define E0_STEP_PIN PA4 +#define E0_DIR_PIN PA3 +#define E0_ENABLE_PIN PA5 + +// +// Temperature Sensors +// +#define TEMP_0_PIN PC0 // Analog Input +#define TEMP_1_PIN -1 // Analog Input +#define TEMP_BED_PIN PC1 // Analog Input + +// +// Heaters / Fans +// +#define HEATER_0_PIN PA1 +#define HEATER_1_PIN -1 +#define HEATER_BED_PIN PA2 + +//#ifndef FAN_PIN +// #define FAN_PIN PC15 +//#endif +#define FAN1_PIN PC15 +#define FAN2_PIN PA0 + +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN PC15 // FAN1_PIN +#endif + +// +// LED / Lighting +// +//#define CASE_LIGHT_PIN_CI -1 +//#define CASE_LIGHT_PIN_DO -1 +//#define NEOPIXEL_PIN -1 + +// +// Misc. Functions +// +#define SDSS PC11 +#define LED_PIN PC7 // Alive +#define PS_ON_PIN -1 +#define KILL_PIN -1 + +// Lerdge supports auto-power off and power loss sense through a single pin. +#define POWER_LOSS_PIN PC14 // Power-loss / nAC_FAULT + +#define SCK_PIN PC12 +#define MISO_PIN PC8 +#define MOSI_PIN PD2 +#define SS_PIN PC11 + +// +// SD support +// +#define SDIO_SUPPORT +#define SD_DETECT_PIN PA8 + +// +// LCD / Controller +// + +// The LCD is initialized in FSMC mode +#define BEEPER_PIN PD12 + +#define BTN_EN1 PE3 +#define BTN_EN2 PE4 +#define BTN_ENC PE2 + +#define TFT_RESET_PIN PD6 +#define TFT_BACKLIGHT_PIN PD3 + +#define TFT_CS_PIN PD7 +#define TFT_RS_PIN PD11 + +#define TOUCH_CS_PIN PB6 +#define TOUCH_SCK_PIN PB3 +#define TOUCH_MOSI_PIN PB5 +#define TOUCH_MISO_PIN PB4 diff --git a/Marlin/src/pins/stm32f4/pins_MKS_ROBIN2.h b/Marlin/src/pins/stm32f4/pins_MKS_ROBIN2.h new file mode 100644 index 000000000000..c2f5f324ba28 --- /dev/null +++ b/Marlin/src/pins/stm32f4/pins_MKS_ROBIN2.h @@ -0,0 +1,101 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(STM32F4) + #error "Oops! Select an STM32F4 board in 'Tools > Board.'" +#elif HOTENDS > 2 || E_STEPPERS > 2 + #error "MKS_ROBIN2 supports up to 2 hotends / E-steppers." +#endif + +#ifndef BOARD_INFO_NAME + #define BOARD_INFO_NAME "MKS_ROBIN2" +#endif + +#ifndef DEFAULT_MACHINE_NAME + #define DEFAULT_MACHINE_NAME BOARD_INFO_NAME +#endif + +#define SRAM_EEPROM_EMULATION + +// +// Limit Switches +// +#define X_MIN_PIN PG8 +#define X_MAX_PIN PG7 +#define Y_MIN_PIN PG6 +#define Y_MAX_PIN PG5 +#define Z_MIN_PIN PG4 +#define Z_MAX_PIN PG3 + +// +// Servos +// +#define SERVO0_PIN PB0 // XS2-5 +#define SERVO1_PIN PF7 // XS1-5 +#define SERVO2_PIN PF8 // XS1-6 + +// +// Steppers +// +#define X_STEP_PIN PE6 +#define X_DIR_PIN PE5 +#define X_ENABLE_PIN PC13 + +#define Y_STEP_PIN PE3 +#define Y_DIR_PIN PE2 +#define Y_ENABLE_PIN PE4 + +#define Z_STEP_PIN PE0 +#define Z_DIR_PIN PB9 +#define Z_ENABLE_PIN PE1 + +#define E0_STEP_PIN PG10 +#define E0_DIR_PIN PG9 +#define E0_ENABLE_PIN PB8 + +#define E1_STEP_PIN PD3 +#define E1_DIR_PIN PA15 +#define E1_ENABLE_PIN PD6 + +// +// Temperature Sensors +// +#define TEMP_0_PIN PC1 // T1 <-> E0 +#define TEMP_1_PIN PC2 // T2 <-> E1 +#define TEMP_BED_PIN PC0 // T0 <-> Bed + +// +// Heaters / Fans +// +#define HEATER_0_PIN PF3 // Heater0 +#define HEATER_1_PIN PF2 // Heater1 +#define HEATER_BED_PIN PF4 // Hotbed +#define FAN_PIN PA7 // Fan0 + +// +// Misc. Functions +// +#define SDSS -1 // PB12 + +#define SD_DETECT_PIN PF9 +#define BEEPER_PIN PG2 diff --git a/Marlin/src/pins/stm32f4/pins_RUMBA32_AUS3D.h b/Marlin/src/pins/stm32f4/pins_RUMBA32_AUS3D.h new file mode 100644 index 000000000000..a60a2781495c --- /dev/null +++ b/Marlin/src/pins/stm32f4/pins_RUMBA32_AUS3D.h @@ -0,0 +1,78 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * Pin assignments for the RUMBA32 + * + * https://aus3d.com.au/rumba32 + * https://github.com/Aus3D/RUMBA32 + */ + +#define BOARD_INFO_NAME "RUMBA32" + +#if NO_EEPROM_SELECTED + #if MB(RUMBA32_V1_0) + #define FLASH_EEPROM_EMULATION + #define MARLIN_EEPROM_SIZE 0x1000 // 4KB + #elif MB(RUMBA32_V1_1) + #define I2C_EEPROM + #define MARLIN_EEPROM_SIZE 0x2000 // 8KB (24LC64T-I/OT) + #endif +#endif + +#if ENABLED(FLASH_EEPROM_EMULATION) + // Decrease delays and flash wear by spreading writes across the + // 128 kB sector allocated for EEPROM emulation. + #define FLASH_EEPROM_LEVELING +#endif + +#include "pins_RUMBA32_common.h" + +#if MB(RUMBA32_V1_1) + + #define SERVO0_PIN PA15 + #undef BTN_PIN + + #if HAS_TMC_UART + // + // TMC2208/TMC2209 stepper drivers - Software Serial is used according to below pins + // + #define X_SERIAL_TX_PIN PA14 + #define X_SERIAL_RX_PIN PC14 + + #define Y_SERIAL_TX_PIN PA13 + #define Y_SERIAL_RX_PIN PE4 + + #define Z_SERIAL_TX_PIN PB10 + #define Z_SERIAL_RX_PIN PE0 + + #define E0_SERIAL_TX_PIN PD11 + #define E0_SERIAL_RX_PIN PC13 + + #define E1_SERIAL_TX_PIN PB3 + #define E1_SERIAL_RX_PIN PD5 + + #define E2_SERIAL_TX_PIN PB4 + #define E2_SERIAL_RX_PIN PD1 + #endif +#endif diff --git a/Marlin/src/pins/stm32/pins_RUMBA32_MKS.h b/Marlin/src/pins/stm32f4/pins_RUMBA32_MKS.h similarity index 64% rename from Marlin/src/pins/stm32/pins_RUMBA32_MKS.h rename to Marlin/src/pins/stm32f4/pins_RUMBA32_MKS.h index 8e2bb3b8afbd..ab277d43722a 100644 --- a/Marlin/src/pins/stm32/pins_RUMBA32_MKS.h +++ b/Marlin/src/pins/stm32f4/pins_RUMBA32_MKS.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -35,35 +35,29 @@ #define BOARD_INFO_NAME "MKS RUMBA32" -#define RUMBA32_V1_0 +#if NO_EEPROM_SELECTED + #define FLASH_EEPROM_EMULATION + #define MARLIN_EEPROM_SIZE 0x1000 // 4KB +#endif + +#if ENABLED(FLASH_EEPROM_EMULATION) + // Decrease delays and flash wear by spreading writes across the + // 128 kB sector allocated for EEPROM emulation. + #define FLASH_EEPROM_LEVELING +#endif + #define ENABLE_SPI1 -//#define I2C_EEPROM #include "pins_RUMBA32_common.h" -// -// Software SPI pins for TMC2130 stepper drivers -// -#if ENABLED(TMC_USE_SW_SPI) - #ifndef TMC_SW_MOSI - #define TMC_SW_MOSI PA7 - #endif - #ifndef TMC_SW_MISO - #define TMC_SW_MISO PA6 - #endif - #ifndef TMC_SW_SCK - #define TMC_SW_SCK PA5 - #endif -#endif - -#if HAS_TMC220x +#if HAS_TMC_UART /** * TMC2208/TMC2209 stepper drivers * * Hardware serial communication ports. * If undefined software serial is used according to the pins below */ - //#define X_HARDWARE_SERIAL Serial + //#define X_HARDWARE_SERIAL Serial1 //#define X2_HARDWARE_SERIAL Serial1 //#define Y_HARDWARE_SERIAL Serial1 //#define Y2_HARDWARE_SERIAL Serial1 @@ -78,32 +72,21 @@ // // Software serial // - #define X_SERIAL_TX_PIN PA3 - #define X_SERIAL_RX_PIN PC14 - - #define Y_SERIAL_TX_PIN PA4 - #define Y_SERIAL_RX_PIN PE4 + #define X_SERIAL_TX_PIN PA3 + #define X_SERIAL_RX_PIN PC14 - #define Z_SERIAL_TX_PIN PD13 - #define Z_SERIAL_RX_PIN PE0 + #define Y_SERIAL_TX_PIN PA4 + #define Y_SERIAL_RX_PIN PE4 - #define E0_SERIAL_TX_PIN PD14 - #define E0_SERIAL_RX_PIN PC13 + #define Z_SERIAL_TX_PIN PD13 + #define Z_SERIAL_RX_PIN PE0 - #define E1_SERIAL_TX_PIN PD15 - #define E1_SERIAL_RX_PIN PD5 - - #define E2_SERIAL_TX_PIN PD12 - #define E2_SERIAL_RX_PIN PD1 -#endif + #define E0_SERIAL_TX_PIN PD14 + #define E0_SERIAL_RX_PIN PC13 -// -// LCD / Controller -// + #define E1_SERIAL_TX_PIN PD15 + #define E1_SERIAL_RX_PIN PD5 -// Alter timing for graphical display -#if HAS_GRAPHICAL_LCD - #define BOARD_ST7920_DELAY_1 DELAY_NS(96) - #define BOARD_ST7920_DELAY_2 DELAY_NS(48) - #define BOARD_ST7920_DELAY_3 DELAY_NS(600) + #define E2_SERIAL_TX_PIN PD12 + #define E2_SERIAL_RX_PIN PD1 #endif diff --git a/Marlin/src/pins/stm32f4/pins_RUMBA32_common.h b/Marlin/src/pins/stm32f4/pins_RUMBA32_common.h new file mode 100644 index 000000000000..d52bb11d1206 --- /dev/null +++ b/Marlin/src/pins/stm32f4/pins_RUMBA32_common.h @@ -0,0 +1,183 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * Common pin assignments for all RUMBA32 boards + */ + +#if NOT_TARGET(STM32F4) + #error "Oops! Select an STM32F4 board in 'Tools > Board.'" +#elif HOTENDS > 3 || E_STEPPERS > 3 + #error "RUMBA32 boards support up to 3 hotends / E-steppers." +#endif + +#define DEFAULT_MACHINE_NAME BOARD_INFO_NAME + +// Use soft PWM for fans - PWM is not working properly when paired with STM32 Arduino Core v1.7.0 +// This can be removed when Core version is updated and PWM behaviour is fixed. +#define FAN_SOFT_PWM + +// +// Configure Timers +// TIM6 is used for TONE +// TIM7 is used for SERVO +// TIMER_SERIAL defaults to TIM7 and must be overridden in the platformio.h file if SERVO will also be used. +// This will be difficult to solve from the Arduino IDE, without modifying the RUMBA32 variant +// included with the STM32 framework. + +#define STEP_TIMER 10 +#define TEMP_TIMER 14 +#define HAL_TIMER_RATE F_CPU + +// +// Limit Switches +// +#define X_MIN_PIN PB12 +#define X_MAX_PIN PB13 +#define Y_MIN_PIN PB15 +#define Y_MAX_PIN PD8 +#define Z_MIN_PIN PD9 +#define Z_MAX_PIN PD10 + +// +// Steppers +// +#define X_STEP_PIN PA0 +#define X_DIR_PIN PC15 +#define X_ENABLE_PIN PC11 +#define X_CS_PIN PC14 + +#define Y_STEP_PIN PE5 +#define Y_DIR_PIN PE6 +#define Y_ENABLE_PIN PE3 +#define Y_CS_PIN PE4 + +#define Z_STEP_PIN PE1 +#define Z_DIR_PIN PE2 +#define Z_ENABLE_PIN PB7 +#define Z_CS_PIN PE0 + +#define E0_STEP_PIN PB5 +#define E0_DIR_PIN PB6 +#define E0_ENABLE_PIN PC12 +#define E0_CS_PIN PC13 + +#define E1_STEP_PIN PD6 +#define E1_DIR_PIN PD7 +#define E1_ENABLE_PIN PD4 +#define E1_CS_PIN PD5 + +#define E2_STEP_PIN PD2 +#define E2_DIR_PIN PD3 +#define E2_ENABLE_PIN PD0 +#define E2_CS_PIN PD1 + +#if ENABLED(TMC_USE_SW_SPI) + #ifndef TMC_SW_MOSI + #define TMC_SW_MOSI PA7 + #endif + #ifndef TMC_SW_MISO + #define TMC_SW_MISO PA6 + #endif + #ifndef TMC_SW_SCK + #define TMC_SW_SCK PA5 + #endif +#endif + +// +// Temperature Sensors +// +#define TEMP_0_PIN PC4 +#define TEMP_1_PIN PC3 +#define TEMP_2_PIN PC2 +#define TEMP_3_PIN PC1 +#define TEMP_BED_PIN PC0 + +// +// Heaters / Fans +// +#define HEATER_0_PIN PC6 +#define HEATER_1_PIN PC7 +#define HEATER_2_PIN PC8 +#define HEATER_BED_PIN PA1 + +#define FAN_PIN PC9 +#define FAN1_PIN PA8 + +// +// SPI +// +#define SCK_PIN PA5 +#define MISO_PIN PA6 +#define MOSI_PIN PA7 + +// +// Misc. Functions +// +#define LED_PIN PB14 +#define BTN_PIN PC10 +#define PS_ON_PIN PE11 +#define KILL_PIN PC5 + +#define SDSS PA2 +#define SD_DETECT_PIN PB0 +#define BEEPER_PIN PE8 + +// +// LCD / Controller +// +#if HAS_WIRED_LCD + + #define BTN_EN1 PB2 + #define BTN_EN2 PB1 + #define BTN_ENC PE7 + + #define LCD_PINS_RS PE10 + #define LCD_PINS_ENABLE PE9 + #define LCD_PINS_D4 PE12 + + #if ENABLED(MKS_MINI_12864) + #define DOGLCD_CS PE13 + #define DOGLCD_A0 PE14 + #endif + + #if ENABLED(ULTIPANEL) + #define LCD_PINS_D5 PE13 + #define LCD_PINS_D6 PE14 + #define LCD_PINS_D7 PE15 + #endif + + // Alter timing for graphical display + #if HAS_MARLINUI_U8GLIB + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(96) + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(48) + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(600) + #endif + #endif + +#endif diff --git a/Marlin/src/pins/stm32/pins_STEVAL_3DP001V1.h b/Marlin/src/pins/stm32f4/pins_STEVAL_3DP001V1.h similarity index 52% rename from Marlin/src/pins/stm32/pins_STEVAL_3DP001V1.h rename to Marlin/src/pins/stm32f4/pins_STEVAL_3DP001V1.h index 2b6e6f6c335b..0278dd8434b6 100644 --- a/Marlin/src/pins/stm32/pins_STEVAL_3DP001V1.h +++ b/Marlin/src/pins/stm32f4/pins_STEVAL_3DP001V1.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -40,7 +40,7 @@ #pragma once -#ifndef STM32F4 +#if NOT_TARGET(STM32F4) #error "Oops! Select an STM32F4 board in 'Tools > Board.'" #endif @@ -51,13 +51,13 @@ // // Limit Switches // -#define X_MIN_PIN 39 // PD8 X_STOP -#define Y_MIN_PIN 40 // PD9 Y_STOP -#define Z_MIN_PIN 41 // PD10 Z_STOP +#define X_MIN_PIN 39 // PD8 X_STOP +#define Y_MIN_PIN 40 // PD9 Y_STOP +#define Z_MIN_PIN 41 // PD10 Z_STOP -#define X_MAX_PIN 44 // PD0 W_STOP -#define Y_MAX_PIN 43 // PA8 V_STOP -#define Z_MAX_PIN 42 // PD11 U_STOP +#define X_MAX_PIN 44 // PD0 W_STOP +#define Y_MAX_PIN 43 // PA8 V_STOP +#define Z_MAX_PIN 42 // PD11 U_STOP // // Z Probe (when not Z_MIN_PIN) @@ -69,64 +69,64 @@ // // Filament runout // -//#define FIL_RUNOUT_PIN 53 // PA3 BED_THE +//#define FIL_RUNOUT_PIN 53 // PA3 BED_THE // // Steppers // -#define X_STEP_PIN 61 // PE14 X_PWM -#define X_DIR_PIN 62 // PE15 X_DIR -#define X_ENABLE_PIN 60 // PE13 X_RES -#define X_CS_PIN 16 // PA4 SPI_CS +#define X_STEP_PIN 61 // PE14 X_PWM +#define X_DIR_PIN 62 // PE15 X_DIR +#define X_ENABLE_PIN 60 // PE13 X_RES +#define X_CS_PIN 16 // PA4 SPI_CS -#define Y_STEP_PIN 64 // PB10 Y_PWM -#define Y_DIR_PIN 65 // PE9 Y_DIR -#define Y_ENABLE_PIN 63 // PE10 Y_RES -#define Y_CS_PIN 16 // PA4 SPI_CS +#define Y_STEP_PIN 64 // PB10 Y_PWM +#define Y_DIR_PIN 65 // PE9 Y_DIR +#define Y_ENABLE_PIN 63 // PE10 Y_RES +#define Y_CS_PIN 16 // PA4 SPI_CS -#define Z_STEP_PIN 67 // PC6 Z_PWM -#define Z_DIR_PIN 68 // PC0 Z_DIR -#define Z_ENABLE_PIN 66 // PC15 Z_RES -#define Z_CS_PIN 16 // PA4 SPI_CS +#define Z_STEP_PIN 67 // PC6 Z_PWM +#define Z_DIR_PIN 68 // PC0 Z_DIR +#define Z_ENABLE_PIN 66 // PC15 Z_RES +#define Z_CS_PIN 16 // PA4 SPI_CS -#define E0_STEP_PIN 71 // PD12 E1_PW -#define E0_DIR_PIN 70 // PC13 E1_DIR -#define E0_ENABLE_PIN 69 // PC14 E1_RE -#define E0_CS_PIN 16 // PA4 SPI_CS +#define E0_STEP_PIN 71 // PD12 E1_PW +#define E0_DIR_PIN 70 // PC13 E1_DIR +#define E0_ENABLE_PIN 69 // PC14 E1_RE +#define E0_CS_PIN 16 // PA4 SPI_CS -#define E1_STEP_PIN 73 // PE5 E2_PWM -#define E1_DIR_PIN 74 // PE6 E2_DIR -#define E1_ENABLE_PIN 72 // PE4 E2_RESE -#define E1_CS_PIN 16 // PA4 SPI_CS +#define E1_STEP_PIN 73 // PE5 E2_PWM +#define E1_DIR_PIN 74 // PE6 E2_DIR +#define E1_ENABLE_PIN 72 // PE4 E2_RESE +#define E1_CS_PIN 16 // PA4 SPI_CS -#define E2_STEP_PIN 77 // PB8 E3_PWM -#define E2_DIR_PIN 76 // PE2 E3_DIR -#define E2_ENABLE_PIN 75 // PE3 E3_RESE -#define E2_CS_PIN 16 // PA4 SPI_CS +#define E2_STEP_PIN 77 // PB8 E3_PWM +#define E2_DIR_PIN 76 // PE2 E3_DIR +#define E2_ENABLE_PIN 75 // PE3 E3_RESE +#define E2_CS_PIN 16 // PA4 SPI_CS // needed to pass a sanity check -#define X2_CS_PIN 16 // PA4 SPI_CS -#define Y2_CS_PIN 16 // PA4 SPI_CS -#define Z2_CS_PIN 16 // PA4 SPI_CS -#define Z3_CS_PIN 16 // PA4 SPI_CS -#define E3_CS_PIN 16 // PA4 SPI_CS -#define E4_CS_PIN 16 // PA4 SPI_CS -#define E5_CS_PIN 16 // PA4 SPI_CS +#define X2_CS_PIN 16 // PA4 SPI_CS +#define Y2_CS_PIN 16 // PA4 SPI_CS +#define Z2_CS_PIN 16 // PA4 SPI_CS +#define Z3_CS_PIN 16 // PA4 SPI_CS +#define E3_CS_PIN 16 // PA4 SPI_CS +#define E4_CS_PIN 16 // PA4 SPI_CS +#define E5_CS_PIN 16 // PA4 SPI_CS #if HAS_L64XX - #define L6470_CHAIN_SCK_PIN 17 // PA5 - #define L6470_CHAIN_MISO_PIN 18 // PA6 - #define L6470_CHAIN_MOSI_PIN 19 // PA7 - #define L6470_CHAIN_SS_PIN 16 // PA4 - - //#define SCK_PIN L6470_CHAIN_SCK_PIN - //#define MISO_PIN L6470_CHAIN_MISO_PIN - //#define MOSI_PIN L6470_CHAIN_MOSI_PIN + #define L6470_CHAIN_SCK_PIN 17 // PA5 + #define L6470_CHAIN_MISO_PIN 18 // PA6 + #define L6470_CHAIN_MOSI_PIN 19 // PA7 + #define L6470_CHAIN_SS_PIN 16 // PA4 + + //#define SCK_PIN L6470_CHAIN_SCK_PIN + //#define MISO_PIN L6470_CHAIN_MISO_PIN + //#define MOSI_PIN L6470_CHAIN_MOSI_PIN #else - //#define SCK_PIN 13 // PB13 SPI_S - //#define MISO_PIN 12 // PB14 SPI_M - //#define MOSI_PIN 11 // PB15 SPI_M + //#define SCK_PIN 13 // PB13 SPI_S + //#define MISO_PIN 12 // PB14 SPI_M + //#define MOSI_PIN 11 // PB15 SPI_M #endif /** @@ -147,64 +147,67 @@ // // Temperature Sensors // -#define TEMP_0_PIN 3 // Analog input 3, digital pin 54 PA0 E1_THERMISTOR -#define TEMP_1_PIN 4 // Analog input 4, digital pin 55 PA1 E2_THERMISTOR -#define TEMP_2_PIN 5 // Analog input 5, digital pin 56 PA2 E3_THERMISTOR -#define TEMP_BED_PIN 0 // Analog input 0, digital pin 51 PC2 BED_THERMISTOR_1 -#define TEMP_BED_1_PIN 1 // Analog input 1, digital pin 52 PC3 BED_THERMISTOR_2 -#define TEMP_BED_2_PIN 2 // Analog input 2, digital pin 53 PA3 BED_THERMISTOR_3 +#define TEMP_0_PIN 3 // Analog input 3, digital pin 54 PA0 E1_THERMISTOR +#define TEMP_1_PIN 4 // Analog input 4, digital pin 55 PA1 E2_THERMISTOR +#define TEMP_2_PIN 5 // Analog input 5, digital pin 56 PA2 E3_THERMISTOR +#define TEMP_BED_PIN 0 // Analog input 0, digital pin 51 PC2 BED_THERMISTOR_1 +#define TEMP_BED_1_PIN 1 // Analog input 1, digital pin 52 PC3 BED_THERMISTOR_2 +#define TEMP_BED_2_PIN 2 // Analog input 2, digital pin 53 PA3 BED_THERMISTOR_3 // // Heaters / Fans // -#define HEATER_0_PIN 48 // PC7 E1_HEAT_PWM -#define HEATER_1_PIN 49 // PB0 E2_HEAT_PWM -#define HEATER_2_PIN 50 // PB1 E3_HEAT_PWM -#define HEATER_BED_PIN 46 // PD14 (BED_HEAT_1 FET -#define HEATER_BED_1_PIN 45 // PD13 (BED_HEAT_2 FET -#define HEATER_BED_2_PIN 47 // PD15 (BED_HEAT_3 FET - -#define FAN_PIN 57 // PC4 E1_FAN PWM pin, Part cooling fan FET -#define FAN1_PIN 58 // PC5 E2_FAN PWM pin, Extruder fan FET -#define ORIG_E0_AUTO_FAN_PIN FAN1_PIN -#define FAN2_PIN 59 // PE8 E3_FAN PWM pin, Controller fan FET +#define HEATER_0_PIN 48 // PC7 E1_HEAT_PWM +#define HEATER_1_PIN 49 // PB0 E2_HEAT_PWM +#define HEATER_2_PIN 50 // PB1 E3_HEAT_PWM +#define HEATER_BED_PIN 46 // PD14 (BED_HEAT_1 FET +#define HEATER_BED_1_PIN 45 // PD13 (BED_HEAT_2 FET +#define HEATER_BED_2_PIN 47 // PD15 (BED_HEAT_3 FET + +#define FAN_PIN 57 // PC4 E1_FAN PWM pin, Part cooling fan FET +#define FAN1_PIN 58 // PC5 E2_FAN PWM pin, Extruder fan FET +#define FAN2_PIN 59 // PE8 E3_FAN PWM pin, Controller fan FET + +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN 58 // FAN1_PIN +#endif // // Misc functions // -#define SDSS 16 // PA4 SPI_CS -#define LED_PIN -1 // 9 // PE1 green LED Heart beat -#define PS_ON_PIN -1 -#define KILL_PIN -1 -#define POWER_LOSS_PIN -1 // PWR_LOSS / nAC_FAULT +#define SDSS 16 // PA4 SPI_CS +#define LED_PIN -1 // 9 // PE1 green LED Heart beat +#define PS_ON_PIN -1 +#define KILL_PIN -1 +#define POWER_LOSS_PIN -1 // PWR_LOSS / nAC_FAULT // // LCD / Controller // -//#define SD_DETECT_PIN 66 // PA15 SD_CA -//#define BEEPER_PIN 24 // PC9 SDIO_D1 -//#define LCD_PINS_RS 65 // PE9 Y_DIR -//#define LCD_PINS_ENABLE 59 // PE8 E3_FAN -//#define LCD_PINS_D4 10 // PB12 SPI_C -//#define LCD_PINS_D5 13 // PB13 SPI_S -//#define LCD_PINS_D6 12 // PB14 SPI_M -//#define LCD_PINS_D7 11 // PB15 SPI_M -//#define BTN_EN1 57 // PC4 E1_FAN -//#define BTN_EN2 58 // PC5 E2_FAN -//#define BTN_ENC 52 // PC3 BED_THE +//#define SD_DETECT_PIN 66 // PA15 SD_CA +//#define BEEPER_PIN 24 // PC9 SDIO_D1 +//#define LCD_PINS_RS 65 // PE9 Y_DIR +//#define LCD_PINS_ENABLE 59 // PE8 E3_FAN +//#define LCD_PINS_D4 10 // PB12 SPI_C +//#define LCD_PINS_D5 13 // PB13 SPI_S +//#define LCD_PINS_D6 12 // PB14 SPI_M +//#define LCD_PINS_D7 11 // PB15 SPI_M +//#define BTN_EN1 57 // PC4 E1_FAN +//#define BTN_EN2 58 // PC5 E2_FAN +//#define BTN_ENC 52 // PC3 BED_THE // // Extension pins // -//#define EXT0_PIN 49 // PB0 E2_HEAT -//#define EXT1_PIN 50 // PB1 E3_HEAT -//#define EXT2_PIN // PB2 not used (tied to ground -//#define EXT3_PIN 39 // PD8 X_STOP -//#define EXT4_PIN 40 // PD9 Y_STOP -//#define EXT5_PIN 41 // PD10 Z_STOP -//#define EXT6_PIN 42 // PD11 -//#define EXT7_PIN 71 // PD12 E1_PW -//#define EXT8_PIN 64 // PB10 Y_PWM +//#define EXT0_PIN 49 // PB0 E2_HEAT +//#define EXT1_PIN 50 // PB1 E3_HEAT +//#define EXT2_PIN // PB2 not used (tied to ground +//#define EXT3_PIN 39 // PD8 X_STOP +//#define EXT4_PIN 40 // PD9 Y_STOP +//#define EXT5_PIN 41 // PD10 Z_STOP +//#define EXT6_PIN 42 // PD11 +//#define EXT7_PIN 71 // PD12 E1_PW +//#define EXT8_PIN 64 // PB10 Y_PWM // WIFI // 2 // PD3 CTS @@ -215,7 +218,6 @@ // 7 // PE11 WIFI_RESET // 8 // PE12 WIFI_BOOT - // I2C USER // 14 // PB7 SDA // 15 // PB6 SCL @@ -228,27 +230,28 @@ // // Onboard SD support // -#define SDIO_D0_PIN 23 // PC8 SDIO_D0 -#define SDIO_D1_PIN 24 // PC9 SDIO_D1 -//#define SD_CARD_DETECT_PIN 25 // PA15 SD_CARD_DETECT -#define SDIO_D2_PIN 26 // PC10 SDIO_D2 -#define SDIO_D3_PIN 27 // PC11 SDIO_D3 -#define SDIO_CK_PIN 28 // PC12 SDIO_CK -#define SDIO_CMD_PIN 29 // PD2 SDIO_CMD +#define SDIO_D0_PIN 23 // PC8 SDIO_D0 +#define SDIO_D1_PIN 24 // PC9 SDIO_D1 +//#define SD_CARD_DETECT_PIN 25 // PA15 SD_CARD_DETECT +#define SDIO_D2_PIN 26 // PC10 SDIO_D2 +#define SDIO_D3_PIN 27 // PC11 SDIO_D3 +#define SDIO_CK_PIN 28 // PC12 SDIO_CK +#define SDIO_CMD_PIN 29 // PD2 SDIO_CMD #ifndef SDCARD_CONNECTION - #define SDCARD_CONNECTION ONBOARD + #define SDCARD_CONNECTION ONBOARD #endif -#if SDCARD_CONNECTION == ONBOARD - #define SDIO_SUPPORT // Use SDIO for onboard SD +#if SD_CONNECTION_IS(ONBOARD) + #define SDIO_SUPPORT // Use SDIO for onboard SD #ifndef SDIO_SUPPORT - #define SOFTWARE_SPI // Use soft SPI for onboard SD - #define SDSS SDIO_D3_PIN - #define SCK_PIN SDIO_CK_PIN - #define MISO_PIN SDIO_D0_PIN - #define MOSI_PIN SDIO_CMD_PIN + #define SOFTWARE_SPI // Use soft SPI for onboard SD + #undef SDSS + #define SDSS SDIO_D3_PIN + #define SCK_PIN SDIO_CK_PIN + #define MISO_PIN SDIO_D0_PIN + #define MOSI_PIN SDIO_CMD_PIN #endif #endif @@ -265,16 +268,13 @@ // USERKET // 38 // PE7 USER_BUTTON - // 0 // PA9 TX // 1 // PA10 RX - // IR/PROBE // 32 // PD1 IR_OUT // 33 // PC1 IR_ON - /** * Logical pin vs. port/pin cross reference * diff --git a/Marlin/src/pins/stm32f4/pins_VAKE403D.h b/Marlin/src/pins/stm32f4/pins_VAKE403D.h new file mode 100644 index 000000000000..e2463fd47e6f --- /dev/null +++ b/Marlin/src/pins/stm32f4/pins_VAKE403D.h @@ -0,0 +1,195 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(STM32F4, STM32F4xx) + #error "Oops! Select an STM32F4 board in 'Tools > Board.'" +#elif HOTENDS > 2 || E_STEPPERS > 2 + #error "STM32F4 supports up to 2 hotends / E-steppers." +#endif + +#define DEFAULT_MACHINE_NAME "STM32F446VET6" +#define BOARD_INFO_NAME "STM32F4 VAkE" + +//#define I2C_EEPROM +#define MARLIN_EEPROM_SIZE 0x1000 // 4KB + +// +// Servos +// +//#define SERVO0_PIN PE13 +//#define SERVO1_PIN PE14 + +// +// Limit Switches +// +#define X_STOP_PIN PE10 +#define Y_STOP_PIN PE9 +#define Z_STOP_PIN PE8 + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN PA4 +#endif + +// +// Filament runout +// +#define FIL_RUNOUT_PIN PA3 + +// +// Steppers +// + +#define STEPPER_ENABLE_PIN PB2 + +#define X_STEP_PIN PC6 // X_STEP +#define X_DIR_PIN PC7 // X_DIR +#define X_ENABLE_PIN PB2 // +#ifndef X_CS_PIN + #define X_CS_PIN PC8 // X_CS +#endif + +#define Y_STEP_PIN PD9 // Y_STEP +#define Y_DIR_PIN PD10 // Y_DIR +#define Y_ENABLE_PIN PB2 // +#ifndef Y_CS_PIN + #define Y_CS_PIN PD11 // Y_CS +#endif + +#define Z_STEP_PIN PE15 // Z_STEP +#define Z_DIR_PIN PB10 // Z_DIR +#define Z_ENABLE_PIN PB2 +#ifndef Z_CS_PIN + #define Z_CS_PIN PD8 +#endif + +#define E0_STEP_PIN PB1 +#define E0_DIR_PIN PB13 +#define E0_ENABLE_PIN PB2 +#ifndef E0_CS_PIN + #define E0_CS_PIN PE11 +#endif + +#define E1_STEP_PIN PC4 +#define E1_DIR_PIN PC5 +#define E1_ENABLE_PIN PB2 +#ifndef E1_CS_PIN + #define E1_CS_PIN PB0 +#endif + +#define SCK_PIN PE12 // PA5 // SPI1 for SD card +#define MISO_PIN PE13 // PA6 +#define MOSI_PIN PE14 // PA7 + +// added for SD card : optional or not ??? +//#define SD_CHIP_SELECT_PIN SDSS // The default chip select pin for the SD card is SS. +// The following three pins must not be redefined for hardware SPI. +//#define SPI_MOSI_PIN MOSI_PIN // SPI Master Out Slave In pin +//#define SPI_MISO_PIN MISO_PIN // SPI Master In Slave Out pin +//#define SPI_SCK_PIN SCK_PIN // SPI Clock pin + +// +// Temperature Sensors (Analog inputs) +// + +#define TEMP_0_PIN PC0 // Analog Input +#define TEMP_1_PIN PC1 // Analog Input +#define TEMP_2_PIN PC2 // Analog Input +#define TEMP_3_PIN PC3 // Analog Input +#define TEMP_BED_PIN PC3 // Analog Input + +// +// Heaters / Fans +// + +#define HEATER_0_PIN PD15 +#define HEATER_1_PIN PD14 +#define HEATER_BED_PIN PD12 + +#ifndef FAN_PIN + #define FAN_PIN PD13 +#endif +#define FAN1_PIN PB5 // PA0 +#define FAN2_PIN PB4 // PA1 + +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN PD13 +#endif + +// +// Misc. Functions +// + +//#define CASE_LIGHT_PIN_CI PF13 +//#define CASE_LIGHT_PIN_DO PF14 +//#define NEOPIXEL_PIN PF13 + +// +// Průša i3 MK2 Multi Material Multiplexer Support +// +//#define E_MUX0_PIN PG3 +//#define E_MUX1_PIN PG4 + +#define LED_PIN PB14 // Alive +#define PS_ON_PIN PE0 +#define KILL_PIN PD5 +#define POWER_LOSS_PIN PA4 // ?? Power loss / nAC_FAULT + +#if ENABLED(SDSUPPORT) + #define SD_DETECT_PIN PB7 + #define SS_PIN PB_15 // USD_CS -> CS for onboard SD +#endif + +// +// LCD / Controller +// +#if HAS_WIRED_LCD + #if ENABLED(SDSUPPORT) + #define SDSS PB6 // CS for SD card in LCD + #endif + #define BEEPER_PIN PC9 + #define LCD_PINS_RS PC12 + #define LCD_PINS_ENABLE PD7 + #define LCD_PINS_D4 PD1 + #define LCD_PINS_D5 PD2 + #define LCD_PINS_D6 PD3 + #define LCD_PINS_D7 PD4 + #define BTN_EN1 PD6 + #define BTN_EN2 PD0 + #define BTN_ENC PB12 +#endif + +// +// ST7920 Delays +// +#ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(96) +#endif +#ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(48) +#endif +#ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(715) +#endif diff --git a/Marlin/src/pins/stm32f7/pins_NUCLEO_F767ZI.h b/Marlin/src/pins/stm32f7/pins_NUCLEO_F767ZI.h new file mode 100644 index 000000000000..5e3d5f4ab538 --- /dev/null +++ b/Marlin/src/pins/stm32f7/pins_NUCLEO_F767ZI.h @@ -0,0 +1,201 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifndef STM32F767xx + #error "Oops! Select an STM32F767 environment" +#endif + +#define BOARD_INFO_NAME "NUCLEO-F767ZI" +#define DEFAULT_MACHINE_NAME "Prototype Board" + +#if NO_EEPROM_SELECTED + #define FLASH_EEPROM_EMULATION // Use Flash-based EEPROM emulation +#endif + +#if ENABLED(FLASH_EEPROM_EMULATION) + // Decrease delays and flash wear by spreading writes across the + // 128 kB sector allocated for EEPROM emulation. + // Not yet supported on F7 hardware + // #define FLASH_EEPROM_LEVELING +#endif + +/** + * Timer assignments + * + * TIM1 - + * TIM2 - Hardware PWM (Fan/Heater Pins) + * TIM3 - Hardware PWM (Servo Pins) + * TIM4 - STEP_TIMER (Marlin) + * TIM5 - + * TIM6 - TIMER_TONE (variant.h) + * TIM7 - TIMER_SERVO (variant.h) + * TIM9 - TIMER_SERIAL (platformio.ini) + * TIM10 - For some reason trips Watchdog when used for SW Serial + * TIM11 - + * TIM12 - + * TIM13 - + * TIM14 - TEMP_TIMER (Marlin) + * + */ +#define STEP_TIMER 4 +#define TEMP_TIMER 14 + + +/** + * These pin assignments are arbitrary and intending for testing purposes. + * Assignments may not be ideal, and not every assignment has been tested. + * Proceed at your own risk. + * _CN7_ + * (X_STEP) PC6 | · · | PB8 (X_EN) + * (X_DIR) PB15 | · · | PB9 (X_CS) + * (LCD_D4) PB13 | · · | AVDD + * _CN8_ PB12 | · · | GND + * NC | · · | PC8 (HEATER_0) PA15 | · · | PA5 (SCLK) + * IOREF | · · | PC9 (BEEPER) PC7 | · · | PA6 (MISO) + * RESET | · · | PC10 (SERVO1_PIN) PB5 | · · | PA7 (MOSI) + * +3.3V | · · | PC11 (HEATER_BED) PB3 | · · | PD14 (SD_DETECT) + * +5V | · · | PC12 (SDSS) PA4 | · · | PD15 (LCD_ENABLE) + * GND | · · | PD2 (SERVO0_PIN) PB4 | · · | PF12 (LCD_RS) + * GND | · · | PG2  ̄ ̄ ̄ + * VIN | · · | PG3 +_*  ̄ ̄ ̄ _CN10 + * AVDD | · · | PF13 (BTN_EN1) + * _CN9_ AGND | · · | PE9 (BTN_EN2) + * (TEMP_0) PA3 | · · | PD7 GND | · · | PE11 (BTN_ENC) + * (TEMP_BED) PC0 | · · | PD6 PB1 | · · | PF14 + * PC3 | · · | PD5 PC2 | · · | PE13 + * PF3 | · · | PD4 PF4 | · · | PF15 + * PF5 | · · | PD3 (E_STEP) PB6 | · · | PG14 (E_EN) + * PF10 | · · | GND (E_DIR) PB2 | · · | PG9 (E_CS) + * NC | · · | PE2 GND | · · | PE8 + * PA7 | · · | PE4 PD13 | · · | PE7 + * PF2 | · · | PE5 PD12 | · · | GND + * (Y_STEP) PF1 | · · | PE6 (Y_EN) (Z_STEP) PD11 | · · | PE10 (Z_EN) + * (Y_DIR) PF0 | · · | PE3 (Y_CS) (Z_DIR) PE2 | · · | PE12 (Z_CS) + * GND | · · | PF8 GND | · · | PE14 + * (Z_MAX) PD0 | · · | PF7 (X_MIN) PA0 | · · | PE15 + * (Z_MIN) PD1 | · · | PF9 (X_MAX) PB0 | · · | PB10 (FAN) + * (Y_MAX) PG0 | · · | PG1 (Y_MIN) PE0 | · · | PB11 (FAN1) + *  ̄ ̄ ̄  ̄ ̄ ̄ ̄ + */ + +#define X_MIN_PIN PF7 +#define X_MAX_PIN PF9 +#define Y_MIN_PIN PG1 +#define Y_MAX_PIN PG0 +#define Z_MIN_PIN PD1 +#define Z_MAX_PIN PD0 + +// +// Steppers +// +#define X_STEP_PIN PC6 +#define X_DIR_PIN PB15 +#define X_ENABLE_PIN PB8 +#define X_CS_PIN PB9 + +#define Y_STEP_PIN PF1 +#define Y_DIR_PIN PF0 +#define Y_ENABLE_PIN PE6 +#define Y_CS_PIN PE3 + +#define Z_STEP_PIN PD11 +#define Z_DIR_PIN PE2 +#define Z_ENABLE_PIN PE10 +#define Z_CS_PIN PE12 + +#define E0_STEP_PIN PB6 +#define E0_DIR_PIN PB2 +#define E0_ENABLE_PIN PG14 +#define E0_CS_PIN PG9 + +#if HAS_TMC_UART + #define X_SERIAL_TX_PIN PB9 + #define X_SERIAL_RX_PIN PB9 + + #define Y_SERIAL_TX_PIN PE3 + #define Y_SERIAL_RX_PIN PE3 + + #define Z_SERIAL_TX_PIN PE12 + #define Z_SERIAL_RX_PIN PE12 + + #define E_SERIAL_TX_PIN PG9 + #define E_SERIAL_RX_PIN PG9 +#endif + +// +// Temperature Sensors +// +#define TEMP_0_PIN PA3 +#define TEMP_BED_PIN PC0 + +// +// Heaters / Fans +// +#define HEATER_0_PIN PA15 // PWM Capable, TIM2_CH1 +#define HEATER_BED_PIN PB3 // PWM Capable, TIM2_CH2 + +#ifndef FAN_PIN + #define FAN_PIN PB10 // PWM Capable, TIM2_CH3 +#endif +#define FAN1_PIN PB11 // PWM Capable, TIM2_CH4 + +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN FAN1_PIN +#endif + +// +// Servos +// +#define SERVO0_PIN PB4 // PWM Capable, TIM3_CH1 +#define SERVO1_PIN PB5 // PWM Capable, TIM3_CH2 + +// SPI for external SD Card (Not entirely sure this will work) +#define SCK_PIN PA5 +#define MISO_PIN PA6 +#define MOSI_PIN PA7 +#define SS_PIN PA4 +#define SDSS PA4 + +#define LED_PIN LED_BLUE + +// +// LCD / Controller +// +#if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) + #define BEEPER_PIN PC7 // LCD_BEEPER + #define BTN_ENC PE11 // BTN_ENC + #define SD_DETECT_PIN PD14 + #define LCD_PINS_RS PF12 // LCD_RS + #define LCD_PINS_ENABLE PD15 // LCD_EN + #define LCD_PINS_D4 PB13 // LCD_D4 + // #define LCD_PINS_D5 + // #define LCD_PINS_D6 + // #define LCD_PINS_D7 + #define BTN_EN1 PF13 // BTN_EN1 + #define BTN_EN2 PE9 // BTN_EN2 + + #define BOARD_ST7920_DELAY_1 DELAY_NS(125) + #define BOARD_ST7920_DELAY_2 DELAY_NS(63) + #define BOARD_ST7920_DELAY_3 DELAY_NS(780) +#endif diff --git a/Marlin/src/pins/stm32f7/pins_REMRAM_V1.h b/Marlin/src/pins/stm32f7/pins_REMRAM_V1.h new file mode 100644 index 000000000000..c3dc004728d8 --- /dev/null +++ b/Marlin/src/pins/stm32f7/pins_REMRAM_V1.h @@ -0,0 +1,137 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(STM32F7xx) + #error "Oops! Select an STM32F7 board in 'Tools > Board.'" +#endif + +#define BOARD_INFO_NAME "RemRam v1" +#define DEFAULT_MACHINE_NAME "RemRam" + +#if NO_EEPROM_SELECTED + #define SRAM_EEPROM_EMULATION // Emulate the EEPROM using Backup SRAM +#endif + +#if HOTENDS > 1 || E_STEPPERS > 1 + #error "RemRam supports only one hotend / E-stepper." +#endif + +// +// Limit Switches +// +#if DISABLED(SENSORLESS_HOMING) + #define X_MIN_PIN 58 + #define X_MAX_PIN 59 + #define Y_MIN_PIN 60 + #define Y_MAX_PIN 61 + #define Z_MIN_PIN 62 + #define Z_MAX_PIN 63 +#else + #define X_STOP_PIN 36 + #define Y_STOP_PIN 39 + #define Z_MIN_PIN 62 + #define Z_MAX_PIN 42 +#endif + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 26 // EXT_D1 +#endif + +// +// Steppers +// +#define X_STEP_PIN 22 +#define X_DIR_PIN 35 +#define X_ENABLE_PIN 34 +#define X_CS_PIN 14 + +#define Y_STEP_PIN 23 +#define Y_DIR_PIN 38 +#define Y_ENABLE_PIN 37 +#define Y_CS_PIN 15 + +#define Z_STEP_PIN 24 +#define Z_DIR_PIN 41 +#define Z_ENABLE_PIN 40 +#define Z_CS_PIN 16 + +#define E0_STEP_PIN 25 +#define E0_DIR_PIN 44 +#define E0_ENABLE_PIN 43 +#define E0_CS_PIN 10 + +// +// Temperature Sensors +// +#define TEMP_0_PIN 64 // THERM_1 +#define TEMP_1_PIN 65 // THERM_2 +#define TEMP_BED_PIN 66 // THERM_3 + +// +// Heaters / Fans +// +#define HEATER_0_PIN 33 +#define HEATER_BED_PIN 31 + +#ifndef FAN_PIN + #define FAN_PIN 30 // "FAN1" +#endif +#define FAN1_PIN 32 // "FAN2" + +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN 32 +#endif + +// +// Servos +// +#define SERVO0_PIN 26 // PWM_EXT1 +#define SERVO1_PIN 27 // PWM_EXT2 + +#define SDSS 57 // Onboard SD card reader +//#define SDSS 9 // LCD SD card reader +#define LED_PIN 21 // STATUS_LED + +// +// LCD / Controller +// +#define SD_DETECT_PIN 56 // SD_CARD_DET +#define BEEPER_PIN 46 // LCD_BEEPER +#define LCD_PINS_RS 49 // LCD_RS +#define LCD_PINS_ENABLE 48 // LCD_EN +#define LCD_PINS_D4 50 // LCD_D4 +#define LCD_PINS_D5 51 // LCD_D5 +#define LCD_PINS_D6 52 // LCD_D6 +#define LCD_PINS_D7 53 // LCD_D7 +#define BTN_EN1 54 // BTN_EN1 +#define BTN_EN2 55 // BTN_EN2 +#define BTN_ENC 47 // BTN_ENC + +// +// Timers +// + +#define STEP_TIMER 2 diff --git a/Marlin/src/pins/stm32f7/pins_THE_BORG.h b/Marlin/src/pins/stm32f7/pins_THE_BORG.h new file mode 100644 index 000000000000..c050824a83da --- /dev/null +++ b/Marlin/src/pins/stm32f7/pins_THE_BORG.h @@ -0,0 +1,183 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#if NOT_TARGET(STM32F7) + #error "Oops! Select an STM32F7 board in 'Tools > Board.'" +#elif HOTENDS > 3 || E_STEPPERS > 3 + #error "The-Borg supports up to 3 hotends / E-steppers." +#endif + +#define BOARD_INFO_NAME "The-Borge" +#define DEFAULT_MACHINE_NAME BOARD_INFO_NAME + +#ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE 0x1000 +#endif + +// Ignore temp readings during development. +//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 + +// +// Limit Switches +// +#define X_MIN_PIN PE9 +#define X_MAX_PIN PE10 +#define Y_MIN_PIN PE7 +#define Y_MAX_PIN PE8 +#define Z_MIN_PIN PF15 +#define Z_MAX_PIN PG0 +#define E_MIN_PIN PE2 +#define E_MAX_PIN PE3 + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN PA4 +#endif + +// +// Steppers +// +#define STEPPER_ENABLE_PIN PE0 + +#define X_STEP_PIN PC6 // 96, 39 in Arduino +#define X_DIR_PIN PC7 +#define X_ENABLE_PIN PC8 + +#define Y_STEP_PIN PD9 +#define Y_DIR_PIN PD10 +#define Y_ENABLE_PIN PD11 + +#define Z_STEP_PIN PE15 +#define Z_DIR_PIN PG1 +#define Z_ENABLE_PIN PD8 + +#define E0_STEP_PIN PB1 +#define E0_DIR_PIN PB2 +#define E0_ENABLE_PIN PE11 + +#define E1_STEP_PIN PC4 +#define E1_DIR_PIN PC5 +#define E1_ENABLE_PIN PB0 + +#define E2_STEP_PIN PC13 +#define E2_DIR_PIN PC14 +#define E2_ENABLE_PIN PC15 + +#define Z2_STEP_PIN PC13 +#define Z2_DIR_PIN PC14 +#define Z2_ENABLE_PIN PC15 + +#define SCK_PIN PA5 +#define MISO_PIN PA6 +#define MOSI_PIN PA7 + +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +#define SPI6_SCK_PIN PG13 +#define SPI6_MISO_PIN PG12 +#define SPI6_MOSI_PIN PG14 + +// +// Temperature Sensors +// + +#define TEMP_0_PIN PC3 // Analog Input +#define TEMP_1_PIN PC2 // Analog Input +#define TEMP_2_PIN PC1 // Analog Input +#define TEMP_3_PIN PC0 // Analog Input + +#define TEMP_BED_PIN PF10 // Analog Input + +#define TEMP_5_PIN PE12 // Analog Input, Probe temp + +// +// Heaters / Fans +// +#define HEATER_0_PIN PD15 +#define HEATER_1_PIN PD14 +#define HEATER_BED_PIN PF6 + +#ifndef FAN_PIN + #define FAN_PIN PD13 +#endif +#define FAN1_PIN PA0 +#define FAN2_PIN PA1 + +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN PA1 +#endif + +// +// Misc. Functions +// + +//#define CASE_LIGHT_PIN_CI PF13 +//#define CASE_LIGHT_PIN_DO PF14 +//#define NEOPIXEL_PIN PF13 + +// +// Průša i3 MK2 Multi Material Multiplexer Support +// + +#define E_MUX0_PIN PG3 +#define E_MUX1_PIN PG4 + +// +// Servos +// + +#define SERVO0_PIN PE13 +#define SERVO1_PIN PE14 + +#define SDSS PA8 +#define SS_PIN PA8 +#define LED_PIN PA2 // Alive +#define PS_ON_PIN PA3 +#define KILL_PIN -1 //PD5 // EXP2-10 +#define PWR_LOSS PG5 // Power loss / nAC_FAULT + +// +// MAX7219_DEBUG +// +#define MAX7219_CLK_PIN PG10 // EXP1-1 +#define MAX7219_DIN_PIN PD7 // EXP1-3 +#define MAX7219_LOAD_PIN PD1 // EXP1-5 + +// +// LCD / Controller +// +//#define SD_DETECT_PIN -1 //PB6) // EXP2-4 +#define BEEPER_PIN PG10 // EXP1-1 +#define LCD_PINS_RS PG9 // EXP1-4 +#define LCD_PINS_ENABLE PD7 // EXP1-3 +#define LCD_PINS_D4 PD1 // EXP1-5 +#define LCD_PINS_D5 PF0 // EXP1-6 +#define LCD_PINS_D6 PD3 // EXP1-7 +#define LCD_PINS_D7 PD4 // EXP1-8 +#define BTN_EN1 PD6 // EXP2-5 +#define BTN_EN2 PD0 // EXP2-3 +#define BTN_ENC PG11 // EXP1-2 diff --git a/Marlin/src/pins/teensy2/pins_5DPRINT.h b/Marlin/src/pins/teensy2/pins_5DPRINT.h index 206e22bb9cb7..908e12e0bae2 100644 --- a/Marlin/src/pins/teensy2/pins_5DPRINT.h +++ b/Marlin/src/pins/teensy2/pins_5DPRINT.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -31,7 +31,7 @@ * There are two Arduino IDE extensions that are compatible with this board * and with the mainstream Marlin software. * - * Teensyduino - http://www.pjrc.com/teensy/teensyduino.html + * Teensyduino - https://www.pjrc.com/teensy/teensyduino.html * Select Teensy++ 2.0 in Arduino IDE from the 'Tools > Board' menu * * Installation instructions are at the above URL. Don't bother loading the @@ -68,7 +68,7 @@ * https://bitbucket.org/makible/5dprint-d8-controller-board */ -#ifndef __AVR_AT90USB1286__ +#if NOT_TARGET(__AVR_AT90USB1286__) #error "Oops! Select 'Teensy++ 2.0' or 'Printrboard' in 'Tools > Board.'" #endif @@ -78,71 +78,71 @@ // // Servos // -#define SERVO0_PIN 41 -#define SERVO1_PIN 42 -#define SERVO2_PIN 43 -#define SERVO3_PIN 44 +#define SERVO0_PIN 41 +#define SERVO1_PIN 42 +#define SERVO2_PIN 43 +#define SERVO3_PIN 44 // // Limit Switches // -#define X_STOP_PIN 37 // E5 -#define Y_STOP_PIN 36 // E4 -#define Z_STOP_PIN 19 // E7 +#define X_STOP_PIN 37 // E5 +#define Y_STOP_PIN 36 // E4 +#define Z_STOP_PIN 19 // E7 // // Steppers // -#define X_STEP_PIN 28 // A0 -#define X_DIR_PIN 29 // A1 -#define X_ENABLE_PIN 17 // C7 +#define X_STEP_PIN 28 // A0 +#define X_DIR_PIN 29 // A1 +#define X_ENABLE_PIN 17 // C7 -#define Y_STEP_PIN 30 // A2 -#define Y_DIR_PIN 31 // A3 -#define Y_ENABLE_PIN 13 // C3 +#define Y_STEP_PIN 30 // A2 +#define Y_DIR_PIN 31 // A3 +#define Y_ENABLE_PIN 13 // C3 -#define Z_STEP_PIN 32 // A4 -#define Z_DIR_PIN 33 // A5 -#define Z_ENABLE_PIN 12 // C2 +#define Z_STEP_PIN 32 // A4 +#define Z_DIR_PIN 33 // A5 +#define Z_ENABLE_PIN 12 // C2 -#define E0_STEP_PIN 34 // A6 -#define E0_DIR_PIN 35 // A7 -#define E0_ENABLE_PIN 11 // C1 +#define E0_STEP_PIN 34 // A6 +#define E0_DIR_PIN 35 // A7 +#define E0_ENABLE_PIN 11 // C1 // // Digital Microstepping // -#define X_MS1_PIN 25 // B5 -#define X_MS2_PIN 26 // B6 -#define Y_MS1_PIN 9 // E1 -#define Y_MS2_PIN 8 // E0 -#define Z_MS1_PIN 7 // D7 -#define Z_MS2_PIN 6 // D6 -#define E0_MS1_PIN 5 // D5 -#define E0_MS2_PIN 4 // D4 +#define X_MS1_PIN 25 // B5 +#define X_MS2_PIN 26 // B6 +#define Y_MS1_PIN 9 // E1 +#define Y_MS2_PIN 8 // E0 +#define Z_MS1_PIN 7 // D7 +#define Z_MS2_PIN 6 // D6 +#define E0_MS1_PIN 5 // D5 +#define E0_MS2_PIN 4 // D4 // // Temperature Sensors // -#define TEMP_0_PIN 1 // F1 Analog Input -#define TEMP_BED_PIN 0 // F0 Analog Input +#define TEMP_0_PIN 1 // F1 Analog Input +#define TEMP_BED_PIN 0 // F0 Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 15 // C5 -#define HEATER_BED_PIN 14 // C4 +#define HEATER_0_PIN 15 // C5 +#define HEATER_BED_PIN 14 // C4 #ifndef FAN_PIN - #define FAN_PIN 16 // C6 PWM3A + #define FAN_PIN 16 // C6 PWM3A #endif // // Misc. Functions // -#define SDSS 20 // B0 +#define SDSS 20 // B0 //DIGIPOTS slave addresses #ifndef DIGIPOT_I2C_ADDRESS_A - #define DIGIPOT_I2C_ADDRESS_A 0x2C // unshifted slave address for DIGIPOT 0x2C (0x58 <- 0x2C << 1) + #define DIGIPOT_I2C_ADDRESS_A 0x2C // unshifted slave address for DIGIPOT 0x2C (0x58 <- 0x2C << 1) #endif diff --git a/Marlin/src/pins/teensy2/pins_BRAINWAVE.h b/Marlin/src/pins/teensy2/pins_BRAINWAVE.h index 22ceb975403f..97d210a0f852 100644 --- a/Marlin/src/pins/teensy2/pins_BRAINWAVE.h +++ b/Marlin/src/pins/teensy2/pins_BRAINWAVE.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -68,7 +68,7 @@ * 4. The programmer is no longer needed. Remove it. */ -#ifndef __AVR_AT90USB646__ +#if NOT_TARGET(__AVR_AT90USB646__) #error "Oops! Select 'AT90USB646_TEENSYPP' in 'Tools > Board.'" #endif @@ -77,50 +77,50 @@ // // Limit Switches // -#define X_STOP_PIN 35 // A7 -#define Y_STOP_PIN 34 // A6 -#define Z_STOP_PIN 33 // A5 +#define X_STOP_PIN 35 // A7 +#define Y_STOP_PIN 34 // A6 +#define Z_STOP_PIN 33 // A5 // // Steppers // -#define X_STEP_PIN 3 // D3 -#define X_DIR_PIN 5 // D5 -#define X_ENABLE_PIN 4 // D4 -#define X_ATT_PIN 2 // D2 - -#define Y_STEP_PIN 7 // D7 -#define Y_DIR_PIN 9 // E1 -#define Y_ENABLE_PIN 8 // E0 -#define Y_ATT_PIN 6 // D6 - -#define Z_STEP_PIN 11 // C1 -#define Z_DIR_PIN 13 // C3 -#define Z_ENABLE_PIN 12 // C2 -#define Z_ATT_PIN 10 // C0 - -#define E0_STEP_PIN 15 // C5 -#define E0_DIR_PIN 17 // C7 -#define E0_ENABLE_PIN 16 // C6 -#define E0_ATT_PIN 14 // C4 +#define X_STEP_PIN 3 // D3 +#define X_DIR_PIN 5 // D5 +#define X_ENABLE_PIN 4 // D4 +#define X_ATT_PIN 2 // D2 + +#define Y_STEP_PIN 7 // D7 +#define Y_DIR_PIN 9 // E1 +#define Y_ENABLE_PIN 8 // E0 +#define Y_ATT_PIN 6 // D6 + +#define Z_STEP_PIN 11 // C1 +#define Z_DIR_PIN 13 // C3 +#define Z_ENABLE_PIN 12 // C2 +#define Z_ATT_PIN 10 // C0 + +#define E0_STEP_PIN 15 // C5 +#define E0_DIR_PIN 17 // C7 +#define E0_ENABLE_PIN 16 // C6 +#define E0_ATT_PIN 14 // C4 // // Temperature Sensors // -#define TEMP_0_PIN 7 // F7 Analog Input -#define TEMP_BED_PIN 6 // F6 Analog Input +#define TEMP_0_PIN 7 // F7 Analog Input +#define TEMP_BED_PIN 6 // F6 Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 32 // A4 Extruder -#define HEATER_BED_PIN 18 // E6 Bed +#define HEATER_0_PIN 32 // A4 Extruder +#define HEATER_BED_PIN 18 // E6 Bed #ifndef FAN_PIN - #define FAN_PIN 31 // A3 Fan + #define FAN_PIN 31 // A3 Fan #endif // // Misc. Functions // -#define LED_PIN 19 // E7 +#define LED_PIN 19 // E7 diff --git a/Marlin/src/pins/teensy2/pins_BRAINWAVE_PRO.h b/Marlin/src/pins/teensy2/pins_BRAINWAVE_PRO.h index 88b045b833f6..e41fcaab9442 100644 --- a/Marlin/src/pins/teensy2/pins_BRAINWAVE_PRO.h +++ b/Marlin/src/pins/teensy2/pins_BRAINWAVE_PRO.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -44,7 +44,7 @@ * There are two Arduino IDE extensions that are compatible with this board * and with the mainstream Marlin software. * - * Teensyduino - http://www.pjrc.com/teensy/teensyduino.html + * Teensyduino - https://www.pjrc.com/teensy/teensyduino.html * Select Teensy++ 2.0 in Arduino IDE from the 'Tools > Board' menu * * Installation instructions are at the above URL. Don't bother loading the @@ -75,7 +75,7 @@ * 4. The programmer is no longer needed. Remove it. */ -#ifndef __AVR_AT90USB1286__ +#if NOT_TARGET(__AVR_AT90USB1286__) #error "Oops! Select 'Teensy++ 2.0' or 'Printrboard' in 'Tools > Board.'" #endif @@ -84,55 +84,55 @@ // // Limit Switches // -#define X_STOP_PIN 45 // F7 -#define Y_STOP_PIN 12 // C2 -#define Z_STOP_PIN 36 // E4 +#define X_STOP_PIN 45 // F7 +#define Y_STOP_PIN 12 // C2 +#define Z_STOP_PIN 36 // E4 // // Z Probe (when not Z_MIN_PIN) // #ifndef Z_MIN_PROBE_PIN - #define Z_MIN_PROBE_PIN 11 // C1 + #define Z_MIN_PROBE_PIN 11 // C1 #endif // // Steppers // -#define X_STEP_PIN 9 // E1 -#define X_DIR_PIN 8 // E0 -#define X_ENABLE_PIN 23 // B3 +#define X_STEP_PIN 9 // E1 +#define X_DIR_PIN 8 // E0 +#define X_ENABLE_PIN 23 // B3 -#define Y_STEP_PIN 7 // D7 -#define Y_DIR_PIN 6 // D6 -#define Y_ENABLE_PIN 20 // B0 +#define Y_STEP_PIN 7 // D7 +#define Y_DIR_PIN 6 // D6 +#define Y_ENABLE_PIN 20 // B0 -#define Z_STEP_PIN 5 // D5 -#define Z_DIR_PIN 4 // D4 -#define Z_ENABLE_PIN 37 // E5 +#define Z_STEP_PIN 5 // D5 +#define Z_DIR_PIN 4 // D4 +#define Z_ENABLE_PIN 37 // E5 -#define E0_STEP_PIN 47 // E3 -#define E0_DIR_PIN 46 // E2 -#define E0_ENABLE_PIN 25 // B5 +#define E0_STEP_PIN 47 // E3 +#define E0_DIR_PIN 46 // E2 +#define E0_ENABLE_PIN 25 // B5 // // Temperature Sensors // -#define TEMP_0_PIN 2 // F2 Analog Input -#define TEMP_1_PIN 1 // F1 Analog Input -#define TEMP_BED_PIN 0 // F0 Analog Input +#define TEMP_0_PIN 2 // F2 Analog Input +#define TEMP_1_PIN 1 // F1 Analog Input +#define TEMP_BED_PIN 0 // F0 Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 27 // B7 -#define HEATER_BED_PIN 26 // B6 Bed +#define HEATER_0_PIN 27 // B7 +#define HEATER_BED_PIN 26 // B6 Bed #ifndef FAN_PIN - #define FAN_PIN 16 // C6 Fan, PWM3A + #define FAN_PIN 16 // C6 Fan, PWM3A #endif // // Misc. Functions // -#define SDSS 20 // B0 -#define SD_DETECT_PIN 24 // B4 -#define LED_PIN 13 // C3 +#define SDSS 20 // B0 +#define SD_DETECT_PIN 24 // B4 +#define LED_PIN 13 // C3 diff --git a/Marlin/src/pins/teensy2/pins_PRINTRBOARD.h b/Marlin/src/pins/teensy2/pins_PRINTRBOARD.h index 4f10e08084ab..ffecc03b4a25 100644 --- a/Marlin/src/pins/teensy2/pins_PRINTRBOARD.h +++ b/Marlin/src/pins/teensy2/pins_PRINTRBOARD.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -31,7 +31,7 @@ * There are two Arduino IDE extensions that are compatible with this board * and with the mainstream Marlin software. * - * Teensyduino - http://www.pjrc.com/teensy/teensyduino.html + * Teensyduino - https://www.pjrc.com/teensy/teensyduino.html * Select Teensy++ 2.0 in Arduino IDE from the 'Tools > Board' menu * * Installation instructions are at the above URL. Don't bother loading the @@ -62,7 +62,7 @@ * 4. The programmer is no longer needed. Remove it. */ -#ifndef __AVR_AT90USB1286__ +#if NOT_TARGET(__AVR_AT90USB1286__) #error "Oops! Select 'Teensy++ 2.0' or 'Printrboard' in 'Tools > Board.'" #endif @@ -74,96 +74,96 @@ // // Limit Switches // -#define X_STOP_PIN 47 // E3 -#define Y_STOP_PIN 20 // B0 SS -#define Z_STOP_PIN 36 // E4 +#define X_STOP_PIN 47 // E3 +#define Y_STOP_PIN 20 // B0 SS +#define Z_STOP_PIN 36 // E4 // // Steppers // -#define X_STEP_PIN 28 // A0 -#define X_DIR_PIN 29 // A1 -#define X_ENABLE_PIN 19 // E7 +#define X_STEP_PIN 28 // A0 +#define X_DIR_PIN 29 // A1 +#define X_ENABLE_PIN 19 // E7 -#define Y_STEP_PIN 30 // A2 -#define Y_DIR_PIN 31 // A3 -#define Y_ENABLE_PIN 18 // E6 +#define Y_STEP_PIN 30 // A2 +#define Y_DIR_PIN 31 // A3 +#define Y_ENABLE_PIN 18 // E6 -#define Z_STEP_PIN 32 // A4 -#define Z_DIR_PIN 33 // A5 -#define Z_ENABLE_PIN 17 // C7 +#define Z_STEP_PIN 32 // A4 +#define Z_DIR_PIN 33 // A5 +#define Z_ENABLE_PIN 17 // C7 -#define E0_STEP_PIN 34 // A6 -#define E0_DIR_PIN 35 // A7 -#define E0_ENABLE_PIN 13 // C3 +#define E0_STEP_PIN 34 // A6 +#define E0_DIR_PIN 35 // A7 +#define E0_ENABLE_PIN 13 // C3 // // Temperature Sensors // -#define TEMP_0_PIN 1 // Analog Input -#define TEMP_BED_PIN 0 // Analog Input +#define TEMP_0_PIN 1 // Analog Input +#define TEMP_BED_PIN 0 // Analog Input // // Heaters / Fans // -#define HEATER_0_PIN 15 // C5 PWM3B - Extruder -#define HEATER_1_PIN 44 // F6 -#define HEATER_2_PIN 45 // F7 -#define HEATER_BED_PIN 14 // C4 PWM3C +#define HEATER_0_PIN 15 // C5 PWM3B - Extruder +#define HEATER_1_PIN 44 // F6 +#define HEATER_2_PIN 45 // F7 +#define HEATER_BED_PIN 14 // C4 PWM3C #ifndef FAN_PIN - #define FAN_PIN 16 // C6 PWM3A + #define FAN_PIN 16 // C6 PWM3A #endif // // Misc. Functions // -#define SDSS 26 // B6 SDCS -#define FILWIDTH_PIN 2 // Analog Input +#define SDSS 26 // B6 SDCS +#define FILWIDTH_PIN 2 // Analog Input // // LCD / Controller // #if BOTH(ULTRA_LCD, NEWPANEL) - #define LCD_PINS_RS 9 // E1 JP11-11 - #define LCD_PINS_ENABLE 8 // E0 JP11-10 - #define LCD_PINS_D4 7 // D7 JP11-8 - #define LCD_PINS_D5 6 // D6 JP11-7 - #define LCD_PINS_D6 5 // D5 JP11-6 - #define LCD_PINS_D7 4 // D4 JP11-5 + #define LCD_PINS_RS 9 // E1 JP11-11 + #define LCD_PINS_ENABLE 8 // E0 JP11-10 + #define LCD_PINS_D4 7 // D7 JP11-8 + #define LCD_PINS_D5 6 // D6 JP11-7 + #define LCD_PINS_D6 5 // D5 JP11-6 + #define LCD_PINS_D7 4 // D4 JP11-5 #if ANY(VIKI2, miniVIKI) - #define BEEPER_PIN 8 // E0 JP11-10 + #define BEEPER_PIN 8 // E0 JP11-10 - #define DOGLCD_A0 40 // F2 JP2-2 - #define DOGLCD_CS 41 // F3 JP2-4 + #define DOGLCD_A0 40 // F2 JP2-2 + #define DOGLCD_CS 41 // F3 JP2-4 #define LCD_SCREEN_ROT_180 - #define BTN_EN1 2 // D2 TX1 JP2-5 - #define BTN_EN2 3 // D3 RX1 JP2-7 - #define BTN_ENC 45 // F7 TDI JP2-12 + #define BTN_EN1 2 // D2 TX1 JP2-5 + #define BTN_EN2 3 // D3 RX1 JP2-7 + #define BTN_ENC 45 // F7 TDI JP2-12 #undef SDSS - #define SDSS 43 // F5 TMS JP2-8 + #define SDSS 43 // F5 TMS JP2-8 - #define STAT_LED_RED_PIN 12 // C2 JP11-14 - #define STAT_LED_BLUE_PIN 10 // C0 JP11-12 + #define STAT_LED_RED_PIN 12 // C2 JP11-14 + #define STAT_LED_BLUE_PIN 10 // C0 JP11-12 #elif ENABLED(LCD_I2C_PANELOLU2) - #define BTN_EN1 3 // D3 RX1 JP2-7 - #define BTN_EN2 2 // D2 TX1 JP2-5 - #define BTN_ENC 41 // F3 JP2-4 + #define BTN_EN1 3 // D3 RX1 JP2-7 + #define BTN_EN2 2 // D2 TX1 JP2-5 + #define BTN_ENC 41 // F3 JP2-4 #undef SDSS - #define SDSS 38 // F0 B-THERM connector - use SD card on Panelolu2 + #define SDSS 38 // F0 B-THERM connector - use SD card on Panelolu2 #else - #define BTN_EN1 10 // C0 JP11-12 - #define BTN_EN2 11 // C1 JP11-13 - #define BTN_ENC 12 // C2 JP11-14 + #define BTN_EN1 10 // C0 JP11-12 + #define BTN_EN2 11 // C1 JP11-13 + #define BTN_ENC 12 // C2 JP11-14 #endif -#endif // HAS_SPI_LCD && NEWPANEL +#endif // ULTRA_LCD && NEWPANEL diff --git a/Marlin/src/pins/teensy2/pins_PRINTRBOARD_REVF.h b/Marlin/src/pins/teensy2/pins_PRINTRBOARD_REVF.h index c1198a4d4bad..d4f9fc76415d 100644 --- a/Marlin/src/pins/teensy2/pins_PRINTRBOARD_REVF.h +++ b/Marlin/src/pins/teensy2/pins_PRINTRBOARD_REVF.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -63,11 +63,11 @@ * 4. The programmer is no longer needed. Remove it. */ -#ifndef __AVR_AT90USB1286__ +#if NOT_TARGET(__AVR_AT90USB1286__) #error "Oops! Select 'Teensy++ 2.0' or 'Printrboard' in 'Tools > Board.'" #endif -#ifndef USBCON +#if !defined(__MARLIN_DEPS__) && !defined(USBCON) #error "USBCON should be defined by the platform for this board." #endif @@ -99,51 +99,51 @@ // // Limit Switches // -#define X_STOP_PIN 47 // E3 -#define Y_STOP_PIN 24 // B4 PWM2A -#define Z_STOP_PIN 36 // E4 +#define X_STOP_PIN 47 // E3 +#define Y_STOP_PIN 24 // B4 PWM2A +#define Z_STOP_PIN 36 // E4 // // Steppers // -#define X_STEP_PIN 28 // A0 -#define X_DIR_PIN 29 // A1 -#define X_ENABLE_PIN 19 // E7 +#define X_STEP_PIN 28 // A0 +#define X_DIR_PIN 29 // A1 +#define X_ENABLE_PIN 19 // E7 -#define Y_STEP_PIN 30 // A2 -#define Y_DIR_PIN 31 // A3 -#define Y_ENABLE_PIN 18 // E6 +#define Y_STEP_PIN 30 // A2 +#define Y_DIR_PIN 31 // A3 +#define Y_ENABLE_PIN 18 // E6 -#define Z_STEP_PIN 32 // A4 -#define Z_DIR_PIN 33 // A5 -#define Z_ENABLE_PIN 17 // C7 +#define Z_STEP_PIN 32 // A4 +#define Z_DIR_PIN 33 // A5 +#define Z_ENABLE_PIN 17 // C7 -#define E0_STEP_PIN 34 // A6 -#define E0_DIR_PIN 35 // A7 -#define E0_ENABLE_PIN 13 // C3 +#define E0_STEP_PIN 34 // A6 +#define E0_DIR_PIN 35 // A7 +#define E0_ENABLE_PIN 13 // C3 #if DISABLED(NO_EXTRUDRBOARD) #if DISABLED(NO_EXTRUDRBOARD_OUTPUT_SWAP) - #define E1_STEP_PIN 25 // B5 - #define E1_DIR_PIN 37 // E5 - #define E1_ENABLE_PIN 42 // F4 + #define E1_STEP_PIN 25 // B5 + #define E1_DIR_PIN 37 // E5 + #define E1_ENABLE_PIN 42 // F4 - #define E2_STEP_PIN 2 // D2 - #define E2_DIR_PIN 3 // D3 - #define E2_ENABLE_PIN 43 // F5 + #define E2_STEP_PIN 2 // D2 + #define E2_DIR_PIN 3 // D3 + #define E2_ENABLE_PIN 43 // F5 #else - #define E1_STEP_PIN 2 // D2 - #define E1_DIR_PIN 3 // D3 - #define E1_ENABLE_PIN 43 // F5 + #define E1_STEP_PIN 2 // D2 + #define E1_DIR_PIN 3 // D3 + #define E1_ENABLE_PIN 43 // F5 - #define E2_STEP_PIN 25 // B5 - #define E2_DIR_PIN 37 // E5 - #define E2_ENABLE_PIN 42 // F4 + #define E2_STEP_PIN 25 // B5 + #define E2_DIR_PIN 37 // E5 + #define E2_ENABLE_PIN 42 // F4 #endif #endif // NO_EXTRUDRBOARD // Enable control of stepper motor currents with the I2C based MCP4728 DAC used on Printrboard REVF -#define DAC_STEPPER_CURRENT +#define HAS_MOTOR_CURRENT_DAC // Set default drive strength percents if not already defined - X, Y, Z, E axis #ifndef DAC_MOTOR_CURRENT_DEFAULT @@ -154,46 +154,46 @@ #define DAC_STEPPER_ORDER { 3, 2, 1, 0 } #define DAC_STEPPER_SENSE 0.11 -#define DAC_STEPPER_ADDRESS 0 -#define DAC_STEPPER_MAX 3520 -#define DAC_STEPPER_VREF 1 // internal Vref, gain 1x = 2.048V -#define DAC_STEPPER_GAIN 0 -#define DAC_OR_ADDRESS 0x00 +#define DAC_STEPPER_ADDRESS 0 +#define DAC_STEPPER_MAX 3520 +#define DAC_STEPPER_VREF 1 // internal Vref, gain 1x = 2.048V +#define DAC_STEPPER_GAIN 0 +#define DAC_OR_ADDRESS 0x00 // // Temperature Sensors // -#define TEMP_0_PIN 1 // Analog Input (Extruder) -#define TEMP_BED_PIN 0 // Analog Input (Bed) +#define TEMP_0_PIN 1 // Analog Input (Extruder) +#define TEMP_BED_PIN 0 // Analog Input (Bed) #if DISABLED(NO_EXTRUDRBOARD) #if DISABLED(NO_EXTRUDRBOARD_OUTPUT_SWAP) - #define TEMP_1_PIN 2 // Analog Input (Extrudrboard A THERM) - #define TEMP_2_PIN 3 // Analog Input (Extrudrboard B THERM) + #define TEMP_1_PIN 2 // Analog Input (Extrudrboard A THERM) + #define TEMP_2_PIN 3 // Analog Input (Extrudrboard B THERM) #else - #define TEMP_1_PIN 3 // Analog Input (Extrudrboard B THERM) - #define TEMP_2_PIN 2 // Analog Input (Extrudrboard A THERM) + #define TEMP_1_PIN 3 // Analog Input (Extrudrboard B THERM) + #define TEMP_2_PIN 2 // Analog Input (Extrudrboard A THERM) #endif #endif // // Heaters / Fans // -#define HEATER_0_PIN 15 // C5 PWM3B - Extruder -#define HEATER_BED_PIN 14 // C4 PWM3C +#define HEATER_0_PIN 15 // C5 PWM3B - Extruder +#define HEATER_BED_PIN 14 // C4 PWM3C #if DISABLED(NO_EXTRUDRBOARD) #if DISABLED(NO_EXTRUDRBOARD_OUTPUT_SWAP) - #define HEATER_1_PIN 44 // F6 - Extrudrboard A HOTEND - #define HEATER_2_PIN 45 // F7 - Extrudrboard B HOTEND + #define HEATER_1_PIN 44 // F6 - Extrudrboard A HOTEND + #define HEATER_2_PIN 45 // F7 - Extrudrboard B HOTEND #else - #define HEATER_1_PIN 45 // F7 - Extrudrboard B HOTEND - #define HEATER_2_PIN 44 // F6 - Extrudrboard A HOTEND + #define HEATER_1_PIN 45 // F7 - Extrudrboard B HOTEND + #define HEATER_2_PIN 44 // F6 - Extrudrboard A HOTEND #endif #endif #ifndef FAN_PIN - #define FAN_PIN 16 // C6 PWM3A + #define FAN_PIN 16 // C6 PWM3A #endif // @@ -201,61 +201,61 @@ // //#define USE_INTERNAL_SD -#if HAS_SPI_LCD - #define LCD_PINS_RS 9 // E1 JP11-11 - #define LCD_PINS_ENABLE 8 // E0 JP11-10 - #define LCD_PINS_D4 7 // D7 JP11-8 - #define LCD_PINS_D5 6 // D6 JP11-7 - #define LCD_PINS_D6 5 // D5 JP11-6 - #define LCD_PINS_D7 4 // D4 JP11-5 +#if HAS_WIRED_LCD + #define LCD_PINS_RS 9 // E1 JP11-11 + #define LCD_PINS_ENABLE 8 // E0 JP11-10 + #define LCD_PINS_D4 7 // D7 JP11-8 + #define LCD_PINS_D5 6 // D6 JP11-7 + #define LCD_PINS_D6 5 // D5 JP11-6 + #define LCD_PINS_D7 4 // D4 JP11-5 #if ANY(VIKI2, miniVIKI) - #define BEEPER_PIN 8 // E0 JP11-10 - #define DOGLCD_A0 40 // F2 JP2-2 - #define DOGLCD_CS 41 // F3 JP2-4 + #define BEEPER_PIN 8 // E0 JP11-10 + #define DOGLCD_A0 40 // F2 JP2-2 + #define DOGLCD_CS 41 // F3 JP2-4 #define LCD_SCREEN_ROT_180 - #define BTN_EN1 2 // D2 TX1 JP2-5 - #define BTN_EN2 3 // D3 RX1 JP2-7 - #define BTN_ENC 45 // F7 TDI JP2-12 + #define BTN_EN1 2 // D2 TX1 JP2-5 + #define BTN_EN2 3 // D3 RX1 JP2-7 + #define BTN_ENC 45 // F7 TDI JP2-12 - #define SDSS 3 // F5 TMS JP2-8 + #define SDSS 3 // F5 TMS JP2-8 - #define STAT_LED_RED_PIN 12 // C2 JP11-14 - #define STAT_LED_BLUE_PIN 10 // C0 JP11-12 + #define STAT_LED_RED_PIN 12 // C2 JP11-14 + #define STAT_LED_BLUE_PIN 10 // C0 JP11-12 #elif ENABLED(MINIPANEL) #if DISABLED(USE_INTERNAL_SD) // PIN FASTIO PIN# ATUSB90 PIN# Teensy2.0++ PIN# Printrboard RevF Conn. MKSLCD12864 PIN# - #define SDSS 11 // 36 C1 EXP2-13 EXP2-07 - #define SD_DETECT_PIN 9 // 34 E1 EXP2-11 EXP2-04 + #define SDSS 11 // 36 C1 EXP2-13 EXP2-07 + #define SD_DETECT_PIN 9 // 34 E1 EXP2-11 EXP2-04 #endif // PIN FASTIO PIN# ATUSB90 PIN# Teensy2.0++ PIN# Printrboard RevF Conn. MKSLCD12864 PIN# - #define DOGLCD_A0 4 // 29 D4 EXP2-05 EXP1-04 - #define DOGLCD_CS 5 // 30 D5 EXP2-06 EXP1-05 - #define BTN_ENC 6 // 31 D6 EXP2-07 EXP1-09 - #define BEEPER_PIN 7 // 32 D7 EXP2-08 EXP1-10 - #define KILL_PIN 8 // 33 E0 EXP2-10 EXP2-03 - #define BTN_EN1 10 // 35 C0 EXP2-12 EXP2-06 - #define BTN_EN2 12 // 37 C2 EXP2-14 EXP2-08 - //#define LCD_BACKLIGHT_PIN 43 // 56 F5 EXP1-12 Not Implemented - //#define SCK 21 // 11 B1 ICSP-04 EXP2-09 - //#define MOSI 22 // 12 B2 ICSP-03 EXP2-05 - //#define MISO 23 // 13 B3 ICSP-06 EXP2-05 - - // increase delays + #define DOGLCD_A0 4 // 29 D4 EXP2-05 EXP1-04 + #define DOGLCD_CS 5 // 30 D5 EXP2-06 EXP1-05 + #define BTN_ENC 6 // 31 D6 EXP2-07 EXP1-09 + #define BEEPER_PIN 7 // 32 D7 EXP2-08 EXP1-10 + #define KILL_PIN 8 // 33 E0 EXP2-10 EXP2-03 + #define BTN_EN1 10 // 35 C0 EXP2-12 EXP2-06 + #define BTN_EN2 12 // 37 C2 EXP2-14 EXP2-08 + //#define LCD_BACKLIGHT_PIN 43 // 56 F5 EXP1-12 Not Implemented + //#define SCK 21 // 11 B1 ICSP-04 EXP2-09 + //#define MOSI 22 // 12 B2 ICSP-03 EXP2-05 + //#define MISO 23 // 13 B3 ICSP-06 EXP2-05 + + // Alter timing for graphical display #define BOARD_ST7920_DELAY_1 DELAY_NS(313) #define BOARD_ST7920_DELAY_2 DELAY_NS(313) #define BOARD_ST7920_DELAY_3 DELAY_NS(313) #else - #define BTN_EN1 10 // C0 JP11-12 - #define BTN_EN2 11 // C1 JP11-13 - #define BTN_ENC 12 // C2 JP11-14 + #define BTN_EN1 10 // C0 JP11-12 + #define BTN_EN2 11 // C1 JP11-13 + #define BTN_ENC 12 // C2 JP11-14 #endif @@ -266,7 +266,7 @@ // // PIN FASTIO PIN# ATUSB90 PIN# Teensy2.0++ PIN# Printrboard RevF Conn. #ifndef SDSS - #define SDSS 20 // 10 B0 + #define SDSS 20 // 10 B0 #endif /** @@ -277,5 +277,5 @@ * which will let you use Channel B on the Extrudrboard as E1. */ #ifndef FILWIDTH_PIN - #define FILWIDTH_PIN 2 // Analog Input + #define FILWIDTH_PIN 2 // Analog Input #endif diff --git a/Marlin/src/pins/teensy2/pins_SAV_MKI.h b/Marlin/src/pins/teensy2/pins_SAV_MKI.h index 0ced699938c5..4d083ecd12e2 100644 --- a/Marlin/src/pins/teensy2/pins_SAV_MKI.h +++ b/Marlin/src/pins/teensy2/pins_SAV_MKI.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -31,7 +31,7 @@ * There are two Arduino IDE extensions that are compatible with this board * and with the mainstream Marlin software. * - * Teensyduino - http://www.pjrc.com/teensy/teensyduino.html + * Teensyduino - https://www.pjrc.com/teensy/teensyduino.html * Select Teensy++ 2.0 in Arduino IDE from the 'Tools > Board' menu * * Installation instructions are at the above URL. Don't bother loading the @@ -62,7 +62,7 @@ * 4. The programmer is no longer needed. Remove it. */ -#ifndef __AVR_AT90USB1286__ +#if NOT_TARGET(__AVR_AT90USB1286__) #error "Oops! Select 'Teensy++ 2.0' or 'Printrboard' in 'Tools > Board.'" #endif @@ -73,56 +73,56 @@ // // Servos // -#define SERVO0_PIN 39 // F1 In teensy's pin definition for pinMode (in servo.cpp) +#define SERVO0_PIN 39 // F1 In teensy's pin definition for pinMode (in servo.cpp) // // Limit Switches // -#define X_STOP_PIN 25 // B5 -#define Y_STOP_PIN 26 // B6 -//#define Z_STOP_PIN 27 // B7 -#define Z_STOP_PIN 36 // E4 For inductive sensor. -//#define E_STOP_PIN 36 // E4 +#define X_STOP_PIN 25 // B5 +#define Y_STOP_PIN 26 // B6 +//#define Z_STOP_PIN 27 // B7 +#define Z_STOP_PIN 36 // E4 For inductive sensor. +//#define E_STOP_PIN 36 // E4 // // Steppers // -#define X_STEP_PIN 28 // A0 -#define X_DIR_PIN 29 // A1 -#define X_ENABLE_PIN 19 // E7 +#define X_STEP_PIN 28 // A0 +#define X_DIR_PIN 29 // A1 +#define X_ENABLE_PIN 19 // E7 -#define Y_STEP_PIN 30 // A2 -#define Y_DIR_PIN 31 // A3 -#define Y_ENABLE_PIN 18 // E6 +#define Y_STEP_PIN 30 // A2 +#define Y_DIR_PIN 31 // A3 +#define Y_ENABLE_PIN 18 // E6 -#define Z_STEP_PIN 32 // A4 -#define Z_DIR_PIN 33 // A5 -#define Z_ENABLE_PIN 17 // C7 +#define Z_STEP_PIN 32 // A4 +#define Z_DIR_PIN 33 // A5 +#define Z_ENABLE_PIN 17 // C7 -#define E0_STEP_PIN 34 // A6 -#define E0_DIR_PIN 35 // A7 -#define E0_ENABLE_PIN 13 // C3 +#define E0_STEP_PIN 34 // A6 +#define E0_DIR_PIN 35 // A7 +#define E0_ENABLE_PIN 13 // C3 // // Temperature Sensors // -#define TEMP_0_PIN 7 // F7 Analog Input (Extruder) -#define TEMP_BED_PIN 6 // F6 Analog Input (Bed) +#define TEMP_0_PIN 7 // F7 Analog Input (Extruder) +#define TEMP_BED_PIN 6 // F6 Analog Input (Bed) // // Heaters / Fans // -#define HEATER_0_PIN 15 // C5 PWM3B - Extruder -#define HEATER_BED_PIN 14 // C4 PWM3C - Bed +#define HEATER_0_PIN 15 // C5 PWM3B - Extruder +#define HEATER_BED_PIN 14 // C4 PWM3C - Bed #ifndef FAN_PIN - #define FAN_PIN 16 // C6 PWM3A + #define FAN_PIN 16 // C6 PWM3A #endif // // Misc. Functions // -#define SDSS 20 // B0 +#define SDSS 20 // B0 // Extension header pin mapping // ---------------------------- @@ -133,53 +133,53 @@ // PWM-D24 A4 (An), IO // 5V GND // 12V GND -#define EXT_AUX_SCL_D0 0 // D0 PWM0B -#define EXT_AUX_SDA_D1 1 // D1 -#define EXT_AUX_RX1_D2 2 // D2 -#define EXT_AUX_TX1_D3 3 // D3 -#define EXT_AUX_PWM_D24 24 // B4 PWM2A -#define EXT_AUX_A0 0 // F0 Analog Input -#define EXT_AUX_A0_IO 38 // F0 Digital IO -#define EXT_AUX_A1 1 // F1 Analog Input -#define EXT_AUX_A1_IO 39 // F1 Digital IO -#define EXT_AUX_A2 2 // F2 Analog Input -#define EXT_AUX_A2_IO 40 // F2 Digital IO -#define EXT_AUX_A3 3 // F3 Analog Input -#define EXT_AUX_A3_IO 41 // F3 Digital IO -#define EXT_AUX_A4 4 // F4 Analog Input -#define EXT_AUX_A4_IO 42 // F4 Digital IO +#define EXT_AUX_SCL_D0 0 // D0 PWM0B +#define EXT_AUX_SDA_D1 1 // D1 +#define EXT_AUX_RX1_D2 2 // D2 +#define EXT_AUX_TX1_D3 3 // D3 +#define EXT_AUX_PWM_D24 24 // B4 PWM2A +#define EXT_AUX_A0 0 // F0 Analog Input +#define EXT_AUX_A0_IO 38 // F0 Digital IO +#define EXT_AUX_A1 1 // F1 Analog Input +#define EXT_AUX_A1_IO 39 // F1 Digital IO +#define EXT_AUX_A2 2 // F2 Analog Input +#define EXT_AUX_A2_IO 40 // F2 Digital IO +#define EXT_AUX_A3 3 // F3 Analog Input +#define EXT_AUX_A3_IO 41 // F3 Digital IO +#define EXT_AUX_A4 4 // F4 Analog Input +#define EXT_AUX_A4_IO 42 // F4 Digital IO // // LCD / Controller // -#define BEEPER_PIN -1 -#define LCD_PINS_RS -1 -#define LCD_PINS_ENABLE -1 +#define BEEPER_PIN -1 +#define LCD_PINS_RS -1 +#define LCD_PINS_ENABLE -1 #if ENABLED(SAV_3DLCD) // For LCD SHIFT register LCD - #define SR_DATA_PIN EXT_AUX_SDA_D1 - #define SR_CLK_PIN EXT_AUX_SCL_D0 + #define SR_DATA_PIN EXT_AUX_SDA_D1 + #define SR_CLK_PIN EXT_AUX_SCL_D0 #endif #if EITHER(SAV_3DLCD, SAV_3DGLCD) - #define BTN_EN1 EXT_AUX_A1_IO - #define BTN_EN2 EXT_AUX_A0_IO - #define BTN_ENC EXT_AUX_PWM_D24 + #define BTN_EN1 EXT_AUX_A1_IO + #define BTN_EN2 EXT_AUX_A0_IO + #define BTN_ENC EXT_AUX_PWM_D24 - #define KILL_PIN EXT_AUX_A2_IO - #define HOME_PIN EXT_AUX_A4_IO + #define KILL_PIN EXT_AUX_A2_IO + #define HOME_PIN EXT_AUX_A4_IO -#else // Use the expansion header for spindle control +#else // Use the expansion header for spindle control // // M3/M4/M5 - Spindle/Laser Control // - #define SPINDLE_LASER_PWM_PIN 24 // B4 PWM2A - #define SPINDLE_LASER_ENA_PIN 39 // F1 Pin should have a pullup! - #define SPINDLE_DIR_PIN 40 // F2 + #define SPINDLE_LASER_PWM_PIN 24 // B4 PWM2A + #define SPINDLE_LASER_ENA_PIN 39 // F1 Pin should have a pullup! + #define SPINDLE_DIR_PIN 40 // F2 - #define CASE_LIGHT_PIN 0 // D0 PWM0B + #define CASE_LIGHT_PIN 0 // D0 PWM0B #endif diff --git a/Marlin/src/pins/teensy2/pins_TEENSY2.h b/Marlin/src/pins/teensy2/pins_TEENSY2.h index 985cd46df427..4efd83d9bc5c 100644 --- a/Marlin/src/pins/teensy2/pins_TEENSY2.h +++ b/Marlin/src/pins/teensy2/pins_TEENSY2.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -31,7 +31,7 @@ * There are two Arduino IDE extensions that are compatible with this board * and with the mainstream Marlin software. * - * Teensyduino - http://www.pjrc.com/teensy/teensyduino.html + * Teensyduino - https://www.pjrc.com/teensy/teensyduino.html * Select Teensy++ 2.0 in Arduino IDE from the 'Tools > Board' menu * * Installation instructions are at the above URL. Don't bother loading the @@ -65,8 +65,8 @@ /** * Teensy++ 2.0 Breadboard pin assignments (AT90USB1286) * Requires the Teensyduino software with Teensy++ 2.0 selected in Arduino IDE! - * http://www.pjrc.com/teensy/teensyduino.html - * See http://reprap.org/wiki/Printrboard for more info + * https://www.pjrc.com/teensy/teensyduino.html + * See https://reprap.org/wiki/Printrboard for more info * * CLI build: HARDWARE_MOTHERBOARD=84 make * @@ -107,7 +107,7 @@ * E DIR 35 a7 a3 31 Y DIR */ -#ifndef __AVR_AT90USB1286__ +#if NOT_TARGET(__AVR_AT90USB1286__) #error "Oops! Select 'Teensy++ 2.0' or 'Printrboard' in 'Tools > Board.'" #endif @@ -116,70 +116,73 @@ // // Limit Switches // -#define X_STOP_PIN 2 // D2 -#define Y_STOP_PIN 3 // D3 -#define Z_STOP_PIN 4 // D4 +#define X_STOP_PIN 2 // D2 +#define Y_STOP_PIN 3 // D3 +#define Z_STOP_PIN 4 // D4 // // Steppers // -#define X_STEP_PIN 28 // A0 Marlin -#define X_DIR_PIN 29 // A1 Marlin -#define X_ENABLE_PIN 26 // B6 +#define X_STEP_PIN 28 // A0 Marlin +#define X_DIR_PIN 29 // A1 Marlin +#define X_ENABLE_PIN 26 // B6 -#define Y_STEP_PIN 30 // A2 Marlin -#define Y_DIR_PIN 31 // A3 -#define Y_ENABLE_PIN 26 // B6 Shared w/x +#define Y_STEP_PIN 30 // A2 Marlin +#define Y_DIR_PIN 31 // A3 +#define Y_ENABLE_PIN 26 // B6 Shared w/x -#define Z_STEP_PIN 32 // A4 -#define Z_DIR_PIN 33 // A5 -#define Z_ENABLE_PIN 26 // B6 Shared w/x +#define Z_STEP_PIN 32 // A4 +#define Z_DIR_PIN 33 // A5 +#define Z_ENABLE_PIN 26 // B6 Shared w/x -#define E0_STEP_PIN 34 // A6 -#define E0_DIR_PIN 35 // A7 -#define E0_ENABLE_PIN 26 // B6 Shared w/x +#define E0_STEP_PIN 34 // A6 +#define E0_DIR_PIN 35 // A7 +#define E0_ENABLE_PIN 26 // B6 Shared w/x // // Temperature Sensors // -#define TEMP_0_PIN 7 // F7 Analog Input (Extruder) -#define TEMP_BED_PIN 6 // F6 Analog Input (Bed) +#define TEMP_0_PIN 7 // F7 Analog Input (Extruder) +#define TEMP_BED_PIN 6 // F6 Analog Input (Bed) // // Heaters / Fans // -#define HEATER_0_PIN 15 // C5 PWM3B Extruder -#define HEATER_BED_PIN 14 // C4 PWM3C +#define HEATER_0_PIN 15 // C5 PWM3B Extruder +#define HEATER_BED_PIN 14 // C4 PWM3C #ifndef FAN_PIN - #define FAN_PIN 16 // C6 PWM3A Fan + #define FAN_PIN 16 // C6 PWM3A Fan #endif // // Misc. Functions // -#define SDSS 20 // B0 -#define LED_PIN 6 // D6 -#define PS_ON_PIN 27 // B7 -#define CASE_LIGHT_PIN 1 // D1 PWM2B MUST BE HARDWARE PWM +#define SDSS 20 // B0 +#define LED_PIN 6 // D6 +#define PS_ON_PIN 27 // B7 + +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN 1 // D1 PWM2B MUST BE HARDWARE PWM +#endif // // LCD / Controller // #if ENABLED(ULTIPANEL) - #define LCD_PINS_RS 8 // E0 - #define LCD_PINS_ENABLE 9 // E1 - #define LCD_PINS_D4 10 // C0 - #define LCD_PINS_D5 11 // C1 - #define LCD_PINS_D6 12 // C2 - #define LCD_PINS_D7 13 // C3 - #define BTN_EN1 38 // F0 - #define BTN_EN2 39 // F1 - #define BTN_ENC 40 // F2 + #define LCD_PINS_RS 8 // E0 + #define LCD_PINS_ENABLE 9 // E1 + #define LCD_PINS_D4 10 // C0 + #define LCD_PINS_D5 11 // C1 + #define LCD_PINS_D6 12 // C2 + #define LCD_PINS_D7 13 // C3 + #define BTN_EN1 38 // F0 + #define BTN_EN2 39 // F1 + #define BTN_ENC 40 // F2 #endif // // M3/M4/M5 - Spindle/Laser Control // -#define SPINDLE_LASER_ENA_PIN 5 // D5 Pin should have a pullup! -#define SPINDLE_LASER_PWM_PIN 0 // D0 PWM0B MUST BE HARDWARE PWM -#define SPINDLE_DIR_PIN 7 // D7 +#define SPINDLE_LASER_ENA_PIN 5 // D5 Pin should have a pullup! +#define SPINDLE_LASER_PWM_PIN 0 // D0 PWM0B MUST BE HARDWARE PWM +#define SPINDLE_DIR_PIN 7 // D7 diff --git a/Marlin/src/pins/teensy2/pins_TEENSYLU.h b/Marlin/src/pins/teensy2/pins_TEENSYLU.h index 72eb21c1aaac..9de119b62b4a 100644 --- a/Marlin/src/pins/teensy2/pins_TEENSYLU.h +++ b/Marlin/src/pins/teensy2/pins_TEENSYLU.h @@ -16,8 +16,7 @@ * 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 . - * + * along with this program. If not, see . */ /** @@ -30,7 +29,7 @@ * There are two Arduino IDE extensions that are compatible with this board * and with the mainstream Marlin software. All have been used with Arduino 1.6.12 * - * Teensyduino - http://www.pjrc.com/teensy/teensyduino.html + * Teensyduino - https://www.pjrc.com/teensy/teensyduino.html * Select Teensy++ 2.0 in Arduino IDE from the 'Tools > Board' menu * * Installation instructions are at the above URL. Don't bother loading the @@ -73,7 +72,7 @@ * The pin assignments in this file match the silkscreen. */ -#if !defined(__AVR_AT90USB1286__) && !defined(__AVR_AT90USB1286P__) +#if NOT_TARGET(__AVR_AT90USB1286__, __AVR_AT90USB1286P__) #error "Oops! Select 'Teensy++ 2.0' or 'Printrboard' in 'Tools > Board.'" #endif @@ -82,82 +81,84 @@ // // Limit Switch definitions that match the SCHEMATIC // -//#define X_STOP_PIN 25 // B5 -//#define Y_STOP_PIN 26 // B6 -//#define Z_STOP_PIN 27 // B7 -//#define E_STOP_PIN 36 // E4 - +//#define X_STOP_PIN 25 // B5 +//#define Y_STOP_PIN 26 // B6 +//#define Z_STOP_PIN 27 // B7 +//#define E_STOP_PIN 36 // E4 // // Limit Switch definitions that match the SILKSCREEN // -#define X_STOP_PIN 26 // B6 -#define Y_STOP_PIN 27 // B7 -#define Z_STOP_PIN 36 // E4 -//#define E_STOP_PIN 25 // B5 +#define X_STOP_PIN 26 // B6 +#define Y_STOP_PIN 27 // B7 +#define Z_STOP_PIN 36 // E4 +//#define E_STOP_PIN 25 // B5 // // Steppers // -#define X_STEP_PIN 28 // A0 -#define X_DIR_PIN 29 // A1 -#define X_ENABLE_PIN 19 // E7 +#define X_STEP_PIN 28 // A0 +#define X_DIR_PIN 29 // A1 +#define X_ENABLE_PIN 19 // E7 -#define Y_STEP_PIN 30 // A2 -#define Y_DIR_PIN 31 // A3 -#define Y_ENABLE_PIN 18 // E6 +#define Y_STEP_PIN 30 // A2 +#define Y_DIR_PIN 31 // A3 +#define Y_ENABLE_PIN 18 // E6 -#define Z_STEP_PIN 32 // A4 -#define Z_DIR_PIN 33 // A5 -#define Z_ENABLE_PIN 17 // C7 +#define Z_STEP_PIN 32 // A4 +#define Z_DIR_PIN 33 // A5 +#define Z_ENABLE_PIN 17 // C7 -#define E0_STEP_PIN 34 // A6 -#define E0_DIR_PIN 35 // A7 -#define E0_ENABLE_PIN 13 // C3 +#define E0_STEP_PIN 34 // A6 +#define E0_DIR_PIN 35 // A7 +#define E0_ENABLE_PIN 13 // C3 // // Temperature Sensors // -#define TEMP_0_PIN 7 // Analog Input (Extruder) -#define TEMP_BED_PIN 6 // Analog Input (Bed) +#define TEMP_0_PIN 7 // Analog Input (Extruder) +#define TEMP_BED_PIN 6 // Analog Input (Bed) // // Heaters / Fans // -#define HEATER_0_PIN 15 // C5 PWM3B - Extruder -#define HEATER_BED_PIN 14 // C4 PWM3C +#define HEATER_0_PIN 15 // C5 PWM3B - Extruder +#define HEATER_BED_PIN 14 // C4 PWM3C #ifndef FAN_PIN - #define FAN_PIN 16 // C6 PWM3A + #define FAN_PIN 16 // C6 PWM3A #endif // // Misc. Functions // -#define SDSS 20 // B0 JP31-6 -#define CASE_LIGHT_PIN 0 // D0 IO-14 PWM0B +#define SDSS 20 // B0 JP31-6 + +#ifndef CASE_LIGHT_PIN + #define CASE_LIGHT_PIN 0 // D0 IO-14 PWM0B +#endif // // LCD / Controller // #if BOTH(ULTRA_LCD, NEWPANEL) - #define BEEPER_PIN -1 + #define BEEPER_PIN -1 #if ENABLED(LCD_I2C_PANELOLU2) - #define BTN_EN1 3 // D3 IO-8 - #define BTN_EN2 2 // D2 IO-10 - #define BTN_ENC 41 // F3 IO-7 - #define SDSS 38 // F0 IO-13 use SD card on Panelolu2 + #define BTN_EN1 3 // D3 IO-8 + #define BTN_EN2 2 // D2 IO-10 + #define BTN_ENC 41 // F3 IO-7 + #define SDSS 38 // F0 IO-13 use SD card on Panelolu2 #endif - #define SD_DETECT_PIN -1 + #define SD_DETECT_PIN -1 -#endif // HAS_SPI_LCD && NEWPANEL +#endif // ULTRA_LCD && NEWPANEL // // M3/M4/M5 - Spindle/Laser Control // -#define SPINDLE_LASER_PWM_PIN 24 // B4 IO-3 PWM2A - MUST BE HARDWARE PWM -#define SPINDLE_LASER_ENA_PIN 39 // F1 IO-11 - Pin should have a pullup! -#define SPINDLE_DIR_PIN 40 // F2 IO-9 +#define SPINDLE_LASER_PWM_PIN 24 // B4 IO-3 PWM2A - MUST BE HARDWARE PWM +#define SPINDLE_LASER_ENA_PIN 39 // F1 IO-11 - Pin should have a pullup! +#define SPINDLE_DIR_PIN 40 // F2 IO-9 diff --git a/Marlin/src/pins/teensy3/pins_TEENSY31_32.h b/Marlin/src/pins/teensy3/pins_TEENSY31_32.h index 6c43c4aaa8a2..0edb5cb19dbd 100644 --- a/Marlin/src/pins/teensy3/pins_TEENSY31_32.h +++ b/Marlin/src/pins/teensy3/pins_TEENSY31_32.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -24,10 +24,10 @@ /** * Teensy 3.1 (MK20DX256) and Teensy 3.2 (MK20DX256) Breadboard pin assignments * Requires the Teensyduino software with Teensy 3.1 or Teensy 3.2 selected in Arduino IDE! - * http://www.pjrc.com/teensy/teensyduino.html + * https://www.pjrc.com/teensy/teensyduino.html */ -#if !IS_32BIT_TEENSY +#if NOT_TARGET(IS_TEENSY_31_32) #error "Oops! Select 'Teensy 3.1' or 'Teensy 3.2' in 'Tools > Board.'" #endif @@ -35,87 +35,78 @@ #define BOARD_INFO_NAME "Teensy3.2" #endif -#define AT90USB 1286 // Disable MarlinSerial etc. -#define USBCON //1286 // Disable MarlinSerial etc. - // // Limit Switches // -#define X_STOP_PIN 3 -#define Y_STOP_PIN 4 -#define Z_STOP_PIN 5 +#define X_STOP_PIN 3 +#define Y_STOP_PIN 4 +#define Z_STOP_PIN 5 // // Steppers // -#define X_STEP_PIN 5 -#define X_DIR_PIN 6 -#define X_ENABLE_PIN 2 +#define X_STEP_PIN 5 +#define X_DIR_PIN 6 +#define X_ENABLE_PIN 2 -#define Y_STEP_PIN 7 -#define Y_DIR_PIN 8 -#define Y_ENABLE_PIN 2 +#define Y_STEP_PIN 7 +#define Y_DIR_PIN 8 +#define Y_ENABLE_PIN 2 -#define Z_STEP_PIN 9 -#define Z_DIR_PIN 10 -#define Z_ENABLE_PIN 2 +#define Z_STEP_PIN 9 +#define Z_DIR_PIN 10 +#define Z_ENABLE_PIN 2 -#define E0_STEP_PIN 11 -#define E0_DIR_PIN 12 -#define E0_ENABLE_PIN 2 +#define E0_STEP_PIN 11 +#define E0_DIR_PIN 12 +#define E0_ENABLE_PIN 2 -//#define E1_STEP_PIN 33 -//#define E1_DIR_PIN 34 -//#define E1_ENABLE_PIN 35 +//#define E1_STEP_PIN 33 +//#define E1_DIR_PIN 34 +//#define E1_ENABLE_PIN 35 // // Heaters / Fans // -#define HEATER_0_PIN 20 -// #define HEATER_1_PIN 36 -#define HEATER_BED_PIN 21 +#define HEATER_0_PIN 20 +//#define HEATER_1_PIN 36 +#define HEATER_BED_PIN 21 #ifndef FAN_PIN - #define FAN_PIN 22 + #define FAN_PIN 22 #endif // // Temperature Sensors // -#define TEMP_0_PIN 14 // Analog Input - Extruder 2 => A2 -//#define TEMP_1_PIN 0 // Analog Input -#define TEMP_BED_PIN 15 // Analog Input - Bed +#define TEMP_0_PIN 14 // Analog Input - Extruder 2 => A2 +//#define TEMP_1_PIN 0 // Analog Input +#define TEMP_BED_PIN 15 // Analog Input - Bed #ifndef FILWIDTH_PIN - #define FILWIDTH_PIN 6 // Analog Input + #define FILWIDTH_PIN 6 // Analog Input #endif // // Misc. Functions // - -//#define SDSS 16 // 8 -#define LED_PIN 13 - -//#define SOL1_PIN 28 +#define LED_PIN 13 +//#define SOL1_PIN 28 +//#define SDSS 16 // 8 // // LCD / Controller // -//#define SCK_PIN 13 -//#define MISO_PIN 12 -//#define MOSI_PIN 11 - /* -#if HAS_SPI_LCD - #define LCD_PINS_RS 40 - #define LCD_PINS_ENABLE 41 - #define LCD_PINS_D4 42 - #define LCD_PINS_D5 43 - #define LCD_PINS_D6 44 - #define LCD_PINS_D7 45 - #define BTN_EN1 46 - #define BTN_EN2 47 - #define BTN_ENC 48 +#if HAS_WIRED_LCD + #define LCD_PINS_RS 40 + #define LCD_PINS_ENABLE 41 + #define LCD_PINS_D4 42 + #define LCD_PINS_D5 43 + #define LCD_PINS_D6 44 + #define LCD_PINS_D7 45 + #define BTN_EN1 46 + #define BTN_EN2 47 + #define BTN_ENC 48 #endif */ diff --git a/Marlin/src/pins/teensy3/pins_TEENSY35_36.h b/Marlin/src/pins/teensy3/pins_TEENSY35_36.h index 28fd51b8a058..2e09c8a425ca 100644 --- a/Marlin/src/pins/teensy3/pins_TEENSY35_36.h +++ b/Marlin/src/pins/teensy3/pins_TEENSY35_36.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -24,10 +24,10 @@ /**************************************************************************************** * Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) Breadboard pin assignments * Requires the Teensyduino software with Teensy 3.5 or Teensy 3.6 selected in Arduino IDE! -* http://www.pjrc.com/teensy/teensyduino.html +* https://www.pjrc.com/teensy/teensyduino.html ****************************************************************************************/ -#if !IS_32BIT_TEENSY +#if NOT_TARGET(IS_TEENSY_35_36) #error "Oops! Select 'Teensy 3.5' or 'Teensy 3.6' in 'Tools > Board.'" #endif @@ -37,126 +37,116 @@ #define BOARD_INFO_NAME "Teensy3.6" #endif -#define AT90USB 1286 // Disable MarlinSerial etc. -#define USBCON //1286 // Disable MarlinSerial etc. -/* - - teemuatlut plan for Teensy3.5 and Teensy3.6: - USB - GND |-----#####-----| VIN 5V - X_STEP_PIN MOSI1 RX1 0 | ##### | Analog GND - X_DIR_PIN MISO1 TX1 1 | | 3.3V - Y_STEP_PIN PWM 2 | *NC AREF* | 23 A9 PWM - Y_DIR_PIN SCL2 CAN0TX PWM 3 | *A26 A10* | 22 A8 PWM - Z_STEP_PIN SDA2 CAN0RX PWM 4 | *A25 A11* | 21 A7 PWM CS0 MOSI1 RX1 - Z_DIR_PIN MISO1 TX1 PWM 5 | *GND * * 57 | 20 A6 PWM CS0 SCK1 FILWIDTH_PIN - X_ENABLE_PIN PWM 6 | *GND * * 56 | 19 A5 SCL0 E0_STEP_PIN - Y_ENABLE_PIN SCL0 MOSI0 RX3 PWM 7 | * * 55 | 18 A4 SDA0 E0_DIR_PIN - Z_ENABLE_PIN SDA0 MISO0 TX3 PWM 8 | * * 54 | 17 A3 SDA0 E0_ENABLE_PIN - CS0 RX2 PWM 9 | | 16 A2 SCL0 TEMP_0_PIN - CS0 TX2 PWM 10 | | 15 A1 CS0 TEMP_BED_PIN - X_STOP_PIN MOSI0 11 | | 14 A0 PWM CS0 TEMP_1_PIN - Y_STOP_PIN MISO0 12 | | 13 LED SCK0 LED_PIN - 3.3V | | GND - Z_STOP_PIN 24 | 40 * * 53 | A22 DAC1 -AUX2 25 | 41 * * 52 | A21 DAC0 -AUX2 FAN_PIN SCL2 TX1 26 | 42 * * 51 | 39 A20 MISO0 SDSS -AUX2 Z-PROBE PWR SCK0 RX1 27 | * * * * * | 38 A19 PWM SDA1 -AUX2 SOL1_PIN MOSI0 28 | 43 * * 50 | 37 A18 PWM SCL1 -D10 CONTROLLER_FAN_PIN CAN0TX PWM 29 | 44 * * 49 | 36 A17 PWM -D9 HEATER_0_PIN CAN0RX PWM 30 | 45 * * 48 | 35 A16 PWM E1_ENABLE_PIN -D8 HEATER_BED_PIN CS1 RX4 A12 31 | 46 * * 47 | 34 A15 PWM SDA0 RX5 E1_DIR_PIN - SCK1 TX4 A13 32 |__GND_*_*_3.3V_| 33 A14 PWM SCL0 TX5 E1_STEP_PIN - - Interior pins: - LCD_PINS_RS 40 * * 53 SCK2 - LCD_PINS_ENABLE 41 * * 52 MOSI2 - LCD_PINS_D4 42 * * 51 MISO2 - LCD_PINS_D5 CS2 43 * * 50 A24 - LCD_PINS_D6 MOSI2 44 * * 49 A23 - LCD_PINS_D7 MISO2 45 * * 48 TX6 SDA0 BTN_ENC - BTN_EN1 SCK2 46 * * 47 RX6 SCL0 BTN_EN2 - GND * * 3.3V - -*/ +/** + * Plan for Teensy 3.5 and Teensy 3.6: + * USB + * GND |-----#####-----| VIN 5V + * X_STEP_PIN MOSI1 RX1 0 | ##### | Analog GND + * X_DIR_PIN MISO1 TX1 1 | | 3.3V + * Y_STEP_PIN PWM 2 | *NC AREF* | 23 A9 PWM + * Y_DIR_PIN SCL2 CAN0TX PWM 3 | *A26 A10* | 22 A8 PWM + * Z_STEP_PIN SDA2 CAN0RX PWM 4 | *A25 A11* | 21 A7 PWM CS0 MOSI1 RX1 + * Z_DIR_PIN MISO1 TX1 PWM 5 | *GND * * 57 | 20 A6 PWM CS0 SCK1 FILWIDTH_PIN + * X_ENABLE_PIN PWM 6 | *GND * * 56 | 19 A5 SCL0 E0_STEP_PIN + * Y_ENABLE_PIN SCL0 MOSI0 RX3 PWM 7 | * * 55 | 18 A4 SDA0 E0_DIR_PIN + * Z_ENABLE_PIN SDA0 MISO0 TX3 PWM 8 | * * 54 | 17 A3 SDA0 E0_ENABLE_PIN + * CS0 RX2 PWM 9 | | 16 A2 SCL0 TEMP_0_PIN + * CS0 TX2 PWM 10 | | 15 A1 CS0 TEMP_BED_PIN + * X_STOP_PIN MOSI0 11 | | 14 A0 PWM CS0 TEMP_1_PIN + * Y_STOP_PIN MISO0 12 | | 13 LED SCK0 LED_PIN + * 3.3V | | GND + * Z_STOP_PIN 24 | 40 * * 53 | A22 DAC1 + * AUX2 25 | 41 * * 52 | A21 DAC0 + * AUX2 FAN_PIN SCL2 TX1 26 | 42 * * 51 | 39 A20 MISO0 SDSS + * AUX2 Z-PROBE PWR SCK0 RX1 27 | * * * * * | 38 A19 PWM SDA1 + * AUX2 SOL1_PIN MOSI0 28 | 43 * * 50 | 37 A18 PWM SCL1 + * D10 CONTROLLER_FAN_PIN CAN0TX PWM 29 | 44 * * 49 | 36 A17 PWM + * D9 HEATER_0_PIN CAN0RX PWM 30 | 45 * * 48 | 35 A16 PWM E1_ENABLE_PIN + * D8 HEATER_BED_PIN CS1 RX4 A12 31 | 46 * * 47 | 34 A15 PWM SDA0 RX5 E1_DIR_PIN + * SCK1 TX4 A13 32 |__GND_*_*_3.3V_| 33 A14 PWM SCL0 TX5 E1_STEP_PIN + * + * Interior pins: + * LCD_PINS_RS 40 * * 53 SCK2 + * LCD_PINS_ENABLE 41 * * 52 MOSI2 + * LCD_PINS_D4 42 * * 51 MISO2 + * LCD_PINS_D5 CS2 43 * * 50 A24 + * LCD_PINS_D6 MOSI2 44 * * 49 A23 + * LCD_PINS_D7 MISO2 45 * * 48 TX6 SDA0 BTN_ENC + * BTN_EN1 SCK2 46 * * 47 RX6 SCL0 BTN_EN2 + * GND * * 3.3V + */ // // Limit Switches // -#define X_STOP_PIN 24 -#define Y_STOP_PIN 26 -#define Z_STOP_PIN 28 +#define X_STOP_PIN 24 +#define Y_STOP_PIN 26 +#define Z_STOP_PIN 28 // // Steppers // -#define X_STEP_PIN 22 -#define X_DIR_PIN 21 -#define X_ENABLE_PIN 39 +#define X_STEP_PIN 22 +#define X_DIR_PIN 21 +#define X_ENABLE_PIN 39 -#define Y_STEP_PIN 19 -#define Y_DIR_PIN 18 -#define Y_ENABLE_PIN 20 +#define Y_STEP_PIN 19 +#define Y_DIR_PIN 18 +#define Y_ENABLE_PIN 20 -#define Z_STEP_PIN 38 -#define Z_DIR_PIN 37 -#define Z_ENABLE_PIN 17 +#define Z_STEP_PIN 38 +#define Z_DIR_PIN 37 +#define Z_ENABLE_PIN 17 -#define E0_STEP_PIN 31 -#define E0_DIR_PIN 30 -#define E0_ENABLE_PIN 32 +#define E0_STEP_PIN 31 +#define E0_DIR_PIN 30 +#define E0_ENABLE_PIN 32 -#define E1_STEP_PIN 33 -#define E1_DIR_PIN 34 -#define E1_ENABLE_PIN 35 +#define E1_STEP_PIN 33 +#define E1_DIR_PIN 34 +#define E1_ENABLE_PIN 35 -#define HEATER_0_PIN 30 -#define HEATER_1_PIN 36 -#define HEATER_BED_PIN 31 +#define HEATER_0_PIN 30 +#define HEATER_1_PIN 36 +#define HEATER_BED_PIN 31 #ifndef FAN_PIN - #define FAN_PIN 2 + #define FAN_PIN 2 #endif -#define TEMP_0_PIN 2 // Extruder / Analog pin numbering: 2 => A2 -#define TEMP_1_PIN 0 -#define TEMP_BED_PIN 1 // Bed / Analog pin numbering - -#define SDSS 39 // 8 -#define LED_PIN 13 -#define PS_ON_PIN 1 -#define ALARM_PIN -1 - -#define FILWIDTH_PIN 6 -#define SOL1_PIN 28 - -#if 0 -// Pretty sure this is obsolete! -// Please use Marlin 1.1.x pins files as reference for new pins files. -#ifndef SDSUPPORT - // these are defined in the SD library if building with SD support - #define SCK_PIN 13 - #define MISO_PIN 12 - #define MOSI_PIN 11 -#endif -#endif +#define TEMP_0_PIN 2 // Extruder / Analog pin numbering: 2 => A2 +#define TEMP_1_PIN 0 +#define TEMP_BED_PIN 1 // Bed / Analog pin numbering -#if HAS_SPI_LCD - #define LCD_PINS_RS 40 - #define LCD_PINS_ENABLE 41 - #define LCD_PINS_D4 42 - #define LCD_PINS_D5 43 - #define LCD_PINS_D6 44 - #define LCD_PINS_D7 45 +// +// Misc. Functions +// +#define LED_PIN 13 +#define PS_ON_PIN 1 +#define FILWIDTH_PIN 6 +#define SOL1_PIN 28 + +// +// SD Card +// +#define SDSS 39 // 8 + +#if HAS_WIRED_LCD + #define LCD_PINS_RS 40 + #define LCD_PINS_ENABLE 41 + #define LCD_PINS_D4 42 + #define LCD_PINS_D5 43 + #define LCD_PINS_D6 44 + #define LCD_PINS_D7 45 #endif #if ENABLED(NEWPANEL) - #define BTN_EN1 46 - #define BTN_EN2 47 - #define BTN_ENC 48 + #define BTN_EN1 46 + #define BTN_EN2 47 + #define BTN_ENC 48 #endif #if ENABLED(REPRAPWORLD_KEYPAD) - #define SHIFT_OUT 40 - #define SHIFT_CLK 44 - #define SHIFT_LD 42 + #define SHIFT_OUT 40 + #define SHIFT_CLK 44 + #define SHIFT_LD 42 #endif diff --git a/Marlin/src/pins/teensy4/pins_T41U5XBB.h b/Marlin/src/pins/teensy4/pins_T41U5XBB.h new file mode 100644 index 000000000000..5f62bb05a64b --- /dev/null +++ b/Marlin/src/pins/teensy4/pins_T41U5XBB.h @@ -0,0 +1,126 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/**************************************************************************************** +* Teensy 4.1 (IMXRT1062) Breadboard pin assignments +* Requires the Teensyduino software with Teensy 4.1 selected in Arduino IDE! +* https://www.pjrc.com/teensy/teensyduino.html +****************************************************************************************/ + +#if NOT_TARGET(IS_TEENSY41) + #error "Oops! Select 'Teensy 4.1' in 'Tools > Board.'" +#endif + +#define BOARD_INFO_NAME "Teensy4.1" + +/** + * Plan for Teensy 4.0 and Teensy 4.1: + * USB + * GND |-----#####-----| VIN (3.65 TO 5.5V) + * RX1 CS1 RX1 PWM 0 | ##### | GND + * TX1 MISO1 TX1 PWM 1 | | 3.3V + * STPX PWM 2 | | 23 A9 PWM + * DIRX PWM 3 | | 22 A8 PWM LIMZ + * STPY PWM 4 | | 21 A7 RX5 LIMY + * DIRY PWM 5 | | 20 A6 TX5 LIMX + * STPZ PWM 6 | | 19 A5 PWM SCL0 COOL + * DIRZ RX2 PWM 7 | | 18 A4 PWM SDA0 MIST + * STPA TX2 PWM 8 | | 17 A3 RX4 SDA1 CYST + * DIRA PWM 9 | | 16 A2 TX4 SCL1 EHOLD + * STEN PWM 10 | | 15 A1 PWM RX3 PRB + * SPDI MOSI0 PWM 11 | | 14 A0 PWM TX3 PANIC + * SPEN MISO0 PWM 12 | | 13 LED PWM SCK0 SPWM + * 3.3V | | GND + * SCL PWM 24 | | 41 A17 KPSTR + * SDA PWM 25 | | 40 A16 STENY + * STPB MOSI1 26 | | 39 A15 MISO1 STENZ + * DIRB SCK1 27 | * * * * * | 38 A14 STENA + * LIMB RX7 PWM 28 | | 37 PWM STENB + * DOOR TX7 PWM 29 | | 36 PWM ST0 + * ST1 30 | | 35 TX8 ST3 + * AUX0 31 | SDCARD | 34 RX8 ST2 + * AUX1 32 |_______________| 33 PWM AUX2 + */ + +#ifndef SDCARD_CONNECTION + #define SDCARD_CONNECTION ONBOARD +#endif + +// +// Servos +// +#define SERVO0_PIN 24 +#define SERVO1_PIN 25 + +// +// Limit Switches +// +#define X_STOP_PIN 20 +#define Y_STOP_PIN 21 +#define Z_STOP_PIN 22 + +// +// Steppers +// +#define X_STEP_PIN 2 +#define X_DIR_PIN 3 +#define X_ENABLE_PIN 10 +//#define X_CS_PIN 30 + +#define Y_STEP_PIN 4 +#define Y_DIR_PIN 5 +#define Y_ENABLE_PIN 40 +//#define Y_CS_PIN 31 + +#define Z_STEP_PIN 6 +#define Z_DIR_PIN 7 +#define Z_ENABLE_PIN 39 +//#define Z_CS_PIN 32 + +#define E0_STEP_PIN 8 +#define E0_DIR_PIN 9 +#define E0_ENABLE_PIN 38 + +#define E1_STEP_PIN 26 +#define E1_DIR_PIN 27 +#define E1_ENABLE_PIN 37 + +// +// Heaters / Fans +// +#define HEATER_0_PIN 31 +#define HEATER_1_PIN 32 +#define HEATER_BED_PIN 33 + +// +// Temperature Sensors +// +#define TEMP_0_PIN 5 // Extruder / Analog pin numbering: 2 => A2 +#define TEMP_1_PIN 4 +#define TEMP_BED_PIN 15 // Bed / Analog pin numbering + +// +// Misc. Functions +// +#define LED_PIN 13 +#define SOL0_PIN 17 diff --git a/Marlin/src/pins/teensy4/pins_TEENSY41.h b/Marlin/src/pins/teensy4/pins_TEENSY41.h new file mode 100644 index 000000000000..21a1ff675f24 --- /dev/null +++ b/Marlin/src/pins/teensy4/pins_TEENSY41.h @@ -0,0 +1,131 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/**************************************************************************************** +* Teensy 4.1 (IMXRT1062) Breadboard pin assignments +* Requires the Teensyduino software with Teensy 4.1 selected in Arduino IDE! +* https://www.pjrc.com/teensy/teensyduino.html +****************************************************************************************/ + +#if NOT_TARGET(IS_TEENSY41) + #error "Oops! Select 'Teensy 4.1' in 'Tools > Board.'" +#endif + +#define BOARD_INFO_NAME "Teensy4.1" + +/** + * Plan for Teensy 4.0 and Teensy 4.1: + * USB + * GND |-----#####-----| VIN (3.65 TO 5.5V) + * X_STEP_PIN CS1 RX1 PWM 0 | ##### | GND + * X_DIR_PIN MISO1 TX1 PWM 1 | | 3.3V + * Y_STEP_PIN PWM 2 | | 23 A9 PWM SERVO1_PIN + * Y_DIR_PIN PWM 3 | | 22 A8 PWM SERVO0_PIN + * Z_STEP_PIN PWM 4 | | 21 A7 RX5 + * Z_DIR_PIN PWM 5 | | 20 A6 TX5 FILWIDTH_PIN + * X_ENABLE_PIN PWM 6 | | 19 A5 PWM SCL0 + * Y_ENABLE_PIN RX2 PWM 7 | | 18 A4 PWM SDA0 HEATER_1_PIN + * Z_ENABLE_PIN TX2 PWM 8 | | 17 A3 RX4 SDA1 + * E0_STEP_PIN PWM 9 | | 16 A2 TX4 SCL1 TEMP_0_PIN + * E0_DIR_PIN PWM 10 | | 15 A1 PWM RX3 TEMP_BED_PIN + * MOSI_PIN MOSI0 PWM 11 | | 14 A0 PWM TX3 TEMP_1_PIN + * MISO_PIN MISO0 PWM 12 | | 13 LED PWM SCK0 SCK_PIN + * 3.3V | | GND + * Z_STOP_PIN PWM 24 | | 41 A17 + * E0_ENABLE_PIN PWM 25 | | 40 A16 + * FAN_PIN MOSI1 26 | | 39 A15 MISO1 X_STOP_PIN + * Z-PROBE PWR SCK1 27 | * * * * * | 38 A14 Y_STOP_PIN + * SOL1_PIN RX7 PWM 28 | | 37 PWM HEATER_0_PIN + * FAN_PIN TX7 PWM 29 | | 36 PWM HEATER_BED_PIN + * X_CS_PIN 30 | | 35 TX8 E1_ENABLE_PIN + * y_CS_PIN 31 | SDCARD | 34 RX8 E1_DIR_PIN + * Z_CS_PIN 32 |_______________| 33 PWM E1_STEP_PIN + */ + +// +// Servos +// +#define SERVO0_PIN 22 +#define SERVO1_PIN 23 + +// +// Limit Switches +// +#define X_STOP_PIN 39 +#define Y_STOP_PIN 38 +#define Z_STOP_PIN 24 + +// +// Steppers +// +#define X_STEP_PIN 0 +#define X_DIR_PIN 1 +#define X_ENABLE_PIN 6 +//#define X_CS_PIN 30 + +#define Y_STEP_PIN 2 +#define Y_DIR_PIN 3 +#define Y_ENABLE_PIN 7 +//#define Y_CS_PIN 31 + +#define Z_STEP_PIN 4 +#define Z_DIR_PIN 5 +#define Z_ENABLE_PIN 8 +//#define Z_CS_PIN 32 + +#define E0_STEP_PIN 9 +#define E0_DIR_PIN 10 +#define E0_ENABLE_PIN 25 + +#define E1_STEP_PIN 33 +#define E1_DIR_PIN 34 +#define E1_ENABLE_PIN 35 + +// +// Heaters / Fans +// +#define HEATER_0_PIN 37 +#define HEATER_1_PIN 18 +#define HEATER_BED_PIN 36 +#ifndef FAN_PIN + #define FAN_PIN 29 +#endif + +// +// Temperature Sensors +// +#define TEMP_0_PIN 2 // Extruder / Analog pin numbering: 2 => A2 +#define TEMP_1_PIN 0 +#define TEMP_BED_PIN 1 // Bed / Analog pin numbering + +// +// Misc. Functions +// +#define LED_PIN 13 +#define SOL0_PIN 28 +//#define PS_ON_PIN 1 +//#define FILWIDTH_PIN 6 // A6 + +#ifndef SDCARD_CONNECTION + #define SDCARD_CONNECTION ONBOARD +#endif diff --git a/Marlin/src/sd/Sd2Card.cpp b/Marlin/src/sd/Sd2Card.cpp index f82fab1b50a8..491c0692c72f 100644 --- a/Marlin/src/sd/Sd2Card.cpp +++ b/Marlin/src/sd/Sd2Card.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -74,7 +74,7 @@ #else static uint8_t CRC7(const uint8_t* data, uint8_t n) { uint8_t crc = 0; - for (uint8_t i = 0; i < n; i++) { + LOOP_L_N(i, n) { uint8_t d = data[i]; d ^= crc << 1; if (d & 0x80) d ^= 9; @@ -106,7 +106,7 @@ uint8_t Sd2Card::cardCommand(const uint8_t cmd, const uint32_t arg) { d[5] = CRC7(d, 5); // Send message - for (uint8_t k = 0; k < 6; k++) spiSend(d[k]); + LOOP_L_N(k, 6) spiSend(d[k]); #else // Send command @@ -179,8 +179,11 @@ void Sd2Card::chipSelect() { * \return true for success, false for failure. */ bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) { + if (ENABLED(SDCARD_READONLY)) return false; + csd_t csd; if (!readCSD(&csd)) goto FAIL; + // check for single block erase if (!csd.v1.erase_blk_en) { // erase size mask @@ -228,6 +231,13 @@ bool Sd2Card::eraseSingleBlockEnable() { * The reason for failure can be determined by calling errorCode() and errorData(). */ bool Sd2Card::init(const uint8_t sckRateID, const pin_t chipSelectPin) { + #if IS_TEENSY_35_36 || IS_TEENSY_40_41 + chipSelectPin_ = BUILTIN_SDCARD; + const uint8_t ret = SDHC_CardInit(); + type_ = SDHC_CardGetType(); + return (ret == 0); + #endif + errorCode_ = type_ = 0; chipSelectPin_ = chipSelectPin; // 16-bit init start time allows over a minute @@ -237,8 +247,15 @@ bool Sd2Card::init(const uint8_t sckRateID, const pin_t chipSelectPin) { watchdog_refresh(); // In case init takes too long // Set pin modes - extDigitalWrite(chipSelectPin_, HIGH); // For some CPUs pinMode can write the wrong data so init desired data value first - pinMode(chipSelectPin_, OUTPUT); // Solution for #8746 by @benlye + #if ENABLED(ZONESTAR_12864OLED) + if (chipSelectPin_ != DOGLCD_CS) { + SET_OUTPUT(DOGLCD_CS); + WRITE(DOGLCD_CS, HIGH); + } + #else + extDigitalWrite(chipSelectPin_, HIGH); // For some CPUs pinMode can write the wrong data so init desired data value first + pinMode(chipSelectPin_, OUTPUT); // Solution for #8746 by @benlye + #endif spiBegin(); // Set SCK rate for initialization commands @@ -246,7 +263,7 @@ bool Sd2Card::init(const uint8_t sckRateID, const pin_t chipSelectPin) { spiInit(spiRate_); // Must supply min of 74 clock cycles with CS high. - for (uint8_t i = 0; i < 10; i++) spiSend(0xFF); + LOOP_L_N(i, 10) spiSend(0xFF); watchdog_refresh(); // In case init takes too long @@ -272,7 +289,7 @@ bool Sd2Card::init(const uint8_t sckRateID, const pin_t chipSelectPin) { } // Get the last byte of r7 response - for (uint8_t i = 0; i < 4; i++) status_ = spiRec(); + LOOP_L_N(i, 4) status_ = spiRec(); if (status_ == 0xAA) { type(SD_CARD_TYPE_SD2); break; @@ -303,7 +320,7 @@ bool Sd2Card::init(const uint8_t sckRateID, const pin_t chipSelectPin) { } if ((spiRec() & 0xC0) == 0xC0) type(SD_CARD_TYPE_SDHC); // Discard rest of ocr - contains allowed voltage range - for (uint8_t i = 0; i < 3; i++) spiRec(); + LOOP_L_N(i, 3) spiRec(); } chipDeselect(); @@ -322,6 +339,10 @@ bool Sd2Card::init(const uint8_t sckRateID, const pin_t chipSelectPin) { * \return true for success, false for failure. */ bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) { + #if IS_TEENSY_35_36 || IS_TEENSY_40_41 + return 0 == SDHC_CardReadBlock(dst, blockNumber); + #endif + if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; // Use address if not SDHC card #if ENABLED(SD_CHECK_AND_RETRY) @@ -535,9 +556,14 @@ bool Sd2Card::waitNotBusy(const millis_t timeout_ms) { * \return true for success, false for failure. */ bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) { - if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; // Use address if not SDHC card + if (ENABLED(SDCARD_READONLY)) return false; + + #if IS_TEENSY_35_36 || IS_TEENSY_40_41 + return 0 == SDHC_CardWriteBlock(src, blockNumber); + #endif bool success = false; + if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; // Use address if not SDHC card if (!cardCommand(CMD24, blockNumber)) { if (writeData(DATA_START_BLOCK, src)) { if (waitNotBusy(SD_WRITE_TIMEOUT)) { // Wait for flashing to complete @@ -561,6 +587,8 @@ bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) { * \return true for success, false for failure. */ bool Sd2Card::writeData(const uint8_t* src) { + if (ENABLED(SDCARD_READONLY)) return false; + bool success = true; chipSelect(); // Wait for previous write to finish @@ -574,14 +602,9 @@ bool Sd2Card::writeData(const uint8_t* src) { // Send one block of data for write block or write multiple blocks bool Sd2Card::writeData(const uint8_t token, const uint8_t* src) { + if (ENABLED(SDCARD_READONLY)) return false; - uint16_t crc = - #if ENABLED(SD_CHECK_AND_RETRY) - CRC_CCITT(src, 512) - #else - 0xFFFF - #endif - ; + const uint16_t crc = TERN(SD_CHECK_AND_RETRY, CRC_CCITT(src, 512), 0xFFFF); spiSendBlock(token, src); spiSend(crc >> 8); spiSend(crc & 0xFF); @@ -607,6 +630,8 @@ bool Sd2Card::writeData(const uint8_t token, const uint8_t* src) { * \return true for success, false for failure. */ bool Sd2Card::writeStart(uint32_t blockNumber, const uint32_t eraseCount) { + if (ENABLED(SDCARD_READONLY)) return false; + bool success = false; if (!cardAcmd(ACMD23, eraseCount)) { // Send pre-erase count if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; // Use address if not SDHC card @@ -626,6 +651,8 @@ bool Sd2Card::writeStart(uint32_t blockNumber, const uint32_t eraseCount) { * \return true for success, false for failure. */ bool Sd2Card::writeStop() { + if (ENABLED(SDCARD_READONLY)) return false; + bool success = false; chipSelect(); if (waitNotBusy(SD_WRITE_TIMEOUT)) { diff --git a/Marlin/src/sd/Sd2Card.h b/Marlin/src/sd/Sd2Card.h index 72590451bc0c..6900502e03e9 100644 --- a/Marlin/src/sd/Sd2Card.h +++ b/Marlin/src/sd/Sd2Card.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -78,13 +78,16 @@ uint8_t const SD_CARD_TYPE_SD1 = 1, // Standard capacity V1 SD_CARD_TYPE_SDHC = 3; // High Capacity SD card /** - * define SOFTWARE_SPI to use bit-bang SPI + * Define SOFTWARE_SPI to use bit-bang SPI */ -#if MEGA_SOFT_SPI +#if EITHER(MEGA_SOFT_SPI, USE_SOFTWARE_SPI) #define SOFTWARE_SPI -#elif USE_SOFTWARE_SPI - #define SOFTWARE_SPI -#endif // MEGA_SOFT_SPI +#endif + +#if IS_TEENSY_35_36 || IS_TEENSY_40_41 + #include "NXP_SDHC.h" + #define BUILTIN_SDCARD 254 +#endif /** * \class Sd2Card diff --git a/Marlin/src/sd/Sd2Card_sdio.h b/Marlin/src/sd/Sd2Card_sdio.h index 50399a3af960..10fb757359f4 100644 --- a/Marlin/src/sd/Sd2Card_sdio.h +++ b/Marlin/src/sd/Sd2Card_sdio.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/sd/SdBaseFile.cpp b/Marlin/src/sd/SdBaseFile.cpp index cdb1072cbef7..2bc9f96e8c92 100644 --- a/Marlin/src/sd/SdBaseFile.cpp +++ b/Marlin/src/sd/SdBaseFile.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -47,6 +47,8 @@ void (*SdBaseFile::dateTime_)(uint16_t* date, uint16_t* time) = 0; // add a cluster to a file bool SdBaseFile::addCluster() { + if (ENABLED(SDCARD_READONLY)) return false; + if (!vol_->allocContiguous(1, &curCluster_)) return false; // if first cluster of file link to directory entry @@ -60,6 +62,8 @@ bool SdBaseFile::addCluster() { // Add a cluster to a directory file and zero the cluster. // return with first block of cluster in the cache bool SdBaseFile::addDirCluster() { + if (ENABLED(SDCARD_READONLY)) return false; + uint32_t block; // max folder size if (fileSize_ / sizeof(dir_t) >= 0xFFFF) return false; @@ -150,9 +154,10 @@ bool SdBaseFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock) { * an invalid DOS 8.3 file name, the FAT volume has not been initialized, * a file is already open, the file already exists, the root * directory is full or an I/O error. - * */ bool SdBaseFile::createContiguous(SdBaseFile* dirFile, const char* path, uint32_t size) { + if (ENABLED(SDCARD_READONLY)) return false; + uint32_t count; // don't allow zero length file if (size == 0) return false; @@ -204,7 +209,7 @@ bool SdBaseFile::dirEntry(dir_t* dir) { */ void SdBaseFile::dirName(const dir_t& dir, char* name) { uint8_t j = 0; - for (uint8_t i = 0; i < 11; i++) { + LOOP_L_N(i, 11) { if (dir.name[i] == ' ')continue; if (i == 8) name[j++] = '.'; name[j++] = dir.name[i]; @@ -345,10 +350,10 @@ int8_t SdBaseFile::lsPrintNext(uint8_t flags, uint8_t indent) { && DIR_IS_FILE_OR_SUBDIR(&dir)) break; } // indent for dir level - for (uint8_t i = 0; i < indent; i++) SERIAL_CHAR(' '); + LOOP_L_N(i, indent) SERIAL_CHAR(' '); // print name - for (uint8_t i = 0; i < 11; i++) { + LOOP_L_N(i, 11) { if (dir.name[i] == ' ')continue; if (i == 8) { SERIAL_CHAR('.'); @@ -419,6 +424,8 @@ bool SdBaseFile::make83Name(const char* str, uint8_t* name, const char** ptr) { * directory, \a path is invalid or already exists in \a parent. */ bool SdBaseFile::mkdir(SdBaseFile* parent, const char* path, bool pFlag) { + if (ENABLED(SDCARD_READONLY)) return false; + uint8_t dname[11]; SdBaseFile dir1, dir2; SdBaseFile* sub = &dir1; @@ -449,6 +456,8 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const char* path, bool pFlag) { } bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) { + if (ENABLED(SDCARD_READONLY)) return false; + uint32_t block; dir_t d; dir_t* p; @@ -478,7 +487,7 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) { // make entry for '.' memcpy(&d, p, sizeof(d)); d.name[0] = '.'; - for (uint8_t i = 1; i < 11; i++) d.name[i] = ' '; + LOOP_S_L_N(i, 1, 11) d.name[i] = ' '; // cache block for '.' and '..' block = vol_->clusterStartBlock(firstCluster_); @@ -632,7 +641,7 @@ bool SdBaseFile::open(SdBaseFile* dirFile, const uint8_t dname[11], uint8_t ofla } else { // don't create unless O_CREAT and O_WRITE - if (!(oflag & O_CREAT) || !(oflag & O_WRITE)) return false; + if ((oflag & (O_CREAT | O_WRITE)) != (O_CREAT | O_WRITE)) return false; if (emptyFound) { index = dirIndex_; p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); @@ -716,8 +725,14 @@ bool SdBaseFile::open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag) { // open a cached directory entry. Assumes vol_ is initialized bool SdBaseFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) { + dir_t* p; + + #if ENABLED(SDCARD_READONLY) + if (oflag & (O_WRITE | O_CREAT | O_TRUNC)) goto FAIL; + #endif + // location of entry in cache - dir_t* p = &vol_->cache()->dir[dirIndex]; + p = &vol_->cache()->dir[dirIndex]; // write or truncate is an error for a directory or read-only file if (p->attributes & (DIR_ATT_READ_ONLY | DIR_ATT_DIRECTORY)) { @@ -1088,7 +1103,7 @@ int8_t SdBaseFile::readDir(dir_t* dir, char* longFilename) { if (WITHIN(seq, 1, MAX_VFAT_ENTRIES)) { // TODO: Store the filename checksum to verify if a long-filename-unaware system modified the file table. n = (seq - 1) * (FILENAME_LENGTH); - for (uint8_t i = 0; i < FILENAME_LENGTH; i++) + LOOP_L_N(i, FILENAME_LENGTH) longFilename[n + i] = (i < 5) ? VFAT->name1[i] : (i < 11) ? VFAT->name2[i - 5] : VFAT->name3[i - 11]; // If this VFAT entry is the last one, add a NUL terminator at the end of the string if (VFAT->sequenceNumber & 0x40) longFilename[n + FILENAME_LENGTH] = '\0'; @@ -1135,6 +1150,8 @@ dir_t* SdBaseFile::readDirCache() { * or an I/O error occurred. */ bool SdBaseFile::remove() { + if (ENABLED(SDCARD_READONLY)) return false; + dir_t* d; // free any clusters - will fail if read-only or directory if (!truncate(0)) return false; @@ -1172,6 +1189,8 @@ bool SdBaseFile::remove() { * or an I/O error occurred. */ bool SdBaseFile::remove(SdBaseFile* dirFile, const char* path) { + if (ENABLED(SDCARD_READONLY)) return false; + SdBaseFile file; return file.open(dirFile, path, O_WRITE) ? file.remove() : false; } @@ -1187,6 +1206,8 @@ bool SdBaseFile::remove(SdBaseFile* dirFile, const char* path) { * file, newPath is invalid or already exists, or an I/O error occurs. */ bool SdBaseFile::rename(SdBaseFile* dirFile, const char* newPath) { + if (ENABLED(SDCARD_READONLY)) return false; + dir_t entry; uint32_t dirCluster = 0; SdBaseFile file; @@ -1279,6 +1300,8 @@ bool SdBaseFile::rename(SdBaseFile* dirFile, const char* newPath) { * directory, is not empty, or an I/O error occurred. */ bool SdBaseFile::rmdir() { + if (ENABLED(SDCARD_READONLY)) return false; + // must be open subdirectory if (!isSubDir()) return false; @@ -1317,6 +1340,8 @@ bool SdBaseFile::rmdir() { * \return true for success, false for failure. */ bool SdBaseFile::rmRfStar() { + if (ENABLED(SDCARD_READONLY)) return false; + uint32_t index; SdBaseFile f; rewind(); @@ -1424,7 +1449,7 @@ void SdBaseFile::setpos(filepos_t* pos) { */ bool SdBaseFile::sync() { // only allow open files and directories - if (!isOpen()) goto FAIL; + if (ENABLED(SDCARD_READONLY) || !isOpen()) goto FAIL; if (flags_ & F_FILE_DIR_DIRTY) { dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); @@ -1524,6 +1549,8 @@ bool SdBaseFile::timestamp(SdBaseFile* file) { */ bool SdBaseFile::timestamp(uint8_t flags, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) { + if (ENABLED(SDCARD_READONLY)) return false; + uint16_t dirDate, dirTime; dir_t* d; @@ -1575,6 +1602,8 @@ bool SdBaseFile::timestamp(uint8_t flags, uint16_t year, uint8_t month, * \a length is greater than the current file size or an I/O error occurs. */ bool SdBaseFile::truncate(uint32_t length) { + if (ENABLED(SDCARD_READONLY)) return false; + uint32_t newPos; // error if not a normal file or read-only if (!isFile() || !(flags_ & O_WRITE)) return false; @@ -1633,9 +1662,12 @@ bool SdBaseFile::truncate(uint32_t length) { * \a nbyte. If an error occurs, write() returns -1. Possible errors * include write() is called before a file has been opened, write is called * for a read-only file, device is full, a corrupt file system or an I/O error. - * */ int16_t SdBaseFile::write(const void* buf, uint16_t nbyte) { + #if ENABLED(SDCARD_READONLY) + writeError = true; return -1; + #endif + // convert void* to uint8_t* - must be before goto statements const uint8_t* src = reinterpret_cast(buf); diff --git a/Marlin/src/sd/SdBaseFile.h b/Marlin/src/sd/SdBaseFile.h index dbdcf0b58226..13a1be863d0f 100644 --- a/Marlin/src/sd/SdBaseFile.h +++ b/Marlin/src/sd/SdBaseFile.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/sd/SdFatConfig.h b/Marlin/src/sd/SdFatConfig.h index 5057d16a8d3e..2e03a4181f7e 100644 --- a/Marlin/src/sd/SdFatConfig.h +++ b/Marlin/src/sd/SdFatConfig.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/sd/SdFatStructs.h b/Marlin/src/sd/SdFatStructs.h index 0412852cdd01..484d4e50c6c9 100644 --- a/Marlin/src/sd/SdFatStructs.h +++ b/Marlin/src/sd/SdFatStructs.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -39,7 +39,7 @@ /** * mostly from Microsoft document fatgen103.doc - * http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx + * https://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx */ uint8_t const BOOTSIG0 = 0x55, // Value for byte 510 of boot block or MBR @@ -128,7 +128,6 @@ typedef struct masterBootRecord mbr_t; * \struct fat_boot * * \brief Boot sector for a FAT12/FAT16 volume. - * */ struct fat_boot { /** @@ -409,7 +408,6 @@ uint32_t const FSINFO_LEAD_SIG = 0x41615252, // 'AaRR' Lead signature for a F * \struct fat32_fsinfo * * \brief FSINFO sector for a FAT32 volume. - * */ struct fat32_fsinfo { uint32_t leadSignature; // must be 0x52, 0x52, 0x61, 0x41 'RRaA' diff --git a/Marlin/src/sd/SdFatUtil.cpp b/Marlin/src/sd/SdFatUtil.cpp index 08b21e5f352e..e2c467c5b6d4 100644 --- a/Marlin/src/sd/SdFatUtil.cpp +++ b/Marlin/src/sd/SdFatUtil.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ diff --git a/Marlin/src/sd/SdFatUtil.h b/Marlin/src/sd/SdFatUtil.h index d820d3cb4d55..7afed2ede06b 100644 --- a/Marlin/src/sd/SdFatUtil.h +++ b/Marlin/src/sd/SdFatUtil.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/sd/SdFile.cpp b/Marlin/src/sd/SdFile.cpp index cc0e7fc347b9..c82fe2c5ed77 100644 --- a/Marlin/src/sd/SdFile.cpp +++ b/Marlin/src/sd/SdFile.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -57,7 +57,6 @@ SdFile::SdFile(const char* path, uint8_t oflag) : SdBaseFile(path, oflag) { } * \a nbyte. If an error occurs, write() returns -1. Possible errors * include write() is called before a file has been opened, write is called * for a read-only file, device is full, a corrupt file system or an I/O error. - * */ int16_t SdFile::write(const void* buf, uint16_t nbyte) { return SdBaseFile::write(buf, nbyte); } diff --git a/Marlin/src/sd/SdFile.h b/Marlin/src/sd/SdFile.h index 4f235f497686..52c8f1f0dbbc 100644 --- a/Marlin/src/sd/SdFile.h +++ b/Marlin/src/sd/SdFile.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/sd/SdInfo.h b/Marlin/src/sd/SdInfo.h index 9d6674dfa1fa..bfa5a01ae2af 100644 --- a/Marlin/src/sd/SdInfo.h +++ b/Marlin/src/sd/SdInfo.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -39,7 +39,7 @@ // Version 3.01 // May 18, 2010 // -// http://www.sdcard.org/developers/tech/sdcard/pls/simplified_specs +// https://www.sdcard.org/downloads/pls/index.html // SD card commands uint8_t const CMD0 = 0x00, // GO_IDLE_STATE - init card in spi mode if CS low diff --git a/Marlin/src/sd/SdVolume.cpp b/Marlin/src/sd/SdVolume.cpp index 1d4c56a344bd..63731f728c60 100644 --- a/Marlin/src/sd/SdVolume.cpp +++ b/Marlin/src/sd/SdVolume.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -46,6 +46,8 @@ // find a contiguous group of clusters bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) { + if (ENABLED(SDCARD_READONLY)) return false; + // start of group uint32_t bgnCluster; // end of group @@ -117,18 +119,20 @@ bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) { } bool SdVolume::cacheFlush() { - if (cacheDirty_) { - if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data)) - return false; - - // mirror FAT tables - if (cacheMirrorBlock_) { - if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data)) + #if DISABLED(SDCARD_READONLY) + if (cacheDirty_) { + if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data)) return false; - cacheMirrorBlock_ = 0; + + // mirror FAT tables + if (cacheMirrorBlock_) { + if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data)) + return false; + cacheMirrorBlock_ = 0; + } + cacheDirty_ = 0; } - cacheDirty_ = 0; - } + #endif return true; } @@ -190,6 +194,8 @@ bool SdVolume::fatGet(uint32_t cluster, uint32_t* value) { // Store a FAT entry bool SdVolume::fatPut(uint32_t cluster, uint32_t value) { + if (ENABLED(SDCARD_READONLY)) return false; + uint32_t lba; // error if reserved cluster if (cluster < 2) return false; diff --git a/Marlin/src/sd/SdVolume.h b/Marlin/src/sd/SdVolume.h index 1912b7adf665..1ffa888468be 100644 --- a/Marlin/src/sd/SdVolume.h +++ b/Marlin/src/sd/SdVolume.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp index b2b0d90e9671..e154ea9f314b 100644 --- a/Marlin/src/sd/cardreader.cpp +++ b/Marlin/src/sd/cardreader.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -24,36 +24,46 @@ #if ENABLED(SDSUPPORT) +//#define DEBUG_CARDREADER + #include "cardreader.h" #include "../MarlinCore.h" #include "../lcd/ultralcd.h" + +#if ENABLED(DWIN_CREALITY_LCD) + #include "../lcd/dwin/e3v2/dwin.h" +#endif + #include "../module/planner.h" // for synchronize #include "../module/printcounter.h" -#include "../core/language.h" #include "../gcode/queue.h" -#include "../module/configuration_store.h" +#include "../module/settings.h" +#include "../module/stepper/indirection.h" #if ENABLED(EMERGENCY_PARSER) - #include "../feature/emergency_parser.h" + #include "../feature/e_parser.h" #endif #if ENABLED(POWER_LOSS_RECOVERY) - #include "../feature/power_loss_recovery.h" + #include "../feature/powerloss.h" #endif #if ENABLED(ADVANCED_PAUSE_FEATURE) #include "../feature/pause.h" #endif +#define DEBUG_OUT EITHER(DEBUG_CARDREADER, MARLIN_DEV_MODE) +#include "../core/debug_out.h" +#include "../libs/hex_print.h" + // public: card_flags_t CardReader::flag; -uint8_t CardReader::sdprinting_done_state; char CardReader::filename[FILENAME_LENGTH], CardReader::longFilename[LONG_FILENAME_LENGTH]; int8_t CardReader::autostart_index; -#if ENABLED(BINARY_FILE_TRANSFER) && NUM_SERIAL > 1 +#if BOTH(HAS_MULTI_SERIAL, BINARY_FILE_TRANSFER) int8_t CardReader::transfer_port_index; #endif @@ -133,6 +143,10 @@ CardReader::CardReader() { // Disable autostart until card is initialized autostart_index = -1; + #if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_DETECT) + SET_INPUT_PULLUP(SD_DETECT_PIN); + #endif + #if PIN_EXISTS(SDPOWER) OUT_WRITE(SDPOWER_PIN, HIGH); // Power the SD reader #endif @@ -143,7 +157,7 @@ CardReader::CardReader() { // char *createFilename(char * const buffer, const dir_t &p) { char *pos = buffer; - for (uint8_t i = 0; i < 11; i++) { + LOOP_L_N(i, 11) { if (p.name[i] == ' ') continue; if (i == 8) *pos++ = '.'; *pos++ = p.name[i]; @@ -156,12 +170,13 @@ char *createFilename(char * const buffer, const dir_t &p) { // Return 'true' if the item is a folder or G-code file // bool CardReader::is_dir_or_gcode(const dir_t &p) { - uint8_t pn0 = p.name[0]; + //uint8_t pn0 = p.name[0]; - if ( pn0 == DIR_NAME_FREE || pn0 == DIR_NAME_DELETED // Clear or Deleted entry - || pn0 == '.' || longFilename[0] == '.' // Hidden file - || !DIR_IS_FILE_OR_SUBDIR(&p) // Not a File or Directory - || (p.attributes & DIR_ATT_HIDDEN) // Hidden by attribute + if ( (p.attributes & DIR_ATT_HIDDEN) // Hidden by attribute + // When readDir() > 0 these must be false: + //|| pn0 == DIR_NAME_FREE || pn0 == DIR_NAME_DELETED // Clear or Deleted entry + //|| pn0 == '.' || longFilename[0] == '.' // Hidden file + //|| !DIR_IS_FILE_OR_SUBDIR(&p) // Not a File or Directory ) return false; flag.filenameIsDir = DIR_IS_SUBDIR(&p); // We know it's a File or Folder @@ -181,7 +196,7 @@ int CardReader::countItems(SdFile dir) { while (dir.readDir(&p, longFilename) > 0) c += is_dir_or_gcode(p); - #if ENABLED(SDCARD_SORT_ALPHA) && SDSORT_USES_RAM && SDSORT_CACHE_NAMES + #if ALL(SDCARD_SORT_ALPHA, SDSORT_USES_RAM, SDSORT_CACHE_NAMES) nrFiles = c; #endif @@ -267,8 +282,10 @@ void CardReader::printListing(SdFile parent, const char * const prepend/*=nullpt // List all files on the SD card // void CardReader::ls() { - root.rewind(); - printListing(root); + if (flag.mounted) { + root.rewind(); + printListing(root); + } } #if ENABLED(LONG_FILENAME_HOST_SUPPORT) @@ -370,18 +387,76 @@ void CardReader::mount() { else { flag.mounted = true; SERIAL_ECHO_MSG(STR_SD_CARD_OK); - #if ENABLED(EEPROM_SETTINGS) && NONE(FLASH_EEPROM_EMULATION, SPI_EEPROM, I2C_EEPROM) - settings.first_load(); - #endif } - cdroot(); + + if (flag.mounted) + cdroot(); + #if ENABLED(USB_FLASH_DRIVE_SUPPORT) || PIN_EXISTS(SD_DETECT) + else if (marlin_state != MF_INITIALIZING) + ui.set_status_P(GET_TEXT(MSG_SD_INIT_FAIL), -1); + #endif ui.refresh(); } +/** + * Handle SD card events + */ +#if MB(FYSETC_CHEETAH, FYSETC_AIO_II) + #include "../module/stepper.h" +#endif + +void CardReader::manage_media() { + static uint8_t prev_stat = 2; // First call, no prior state + uint8_t stat = uint8_t(IS_SD_INSERTED()); + if (stat == prev_stat) return; + + DEBUG_ECHOLNPAIR("SD: Status changed from ", prev_stat, " to ", stat); + + flag.workDirIsRoot = true; // Return to root on mount/release + + if (ui.detected()) { + + uint8_t old_stat = prev_stat; + prev_stat = stat; // Change now to prevent re-entry + + if (stat) { // Media Inserted + safe_delay(500); // Some boards need a delay to get settled + mount(); // Try to mount the media + #if MB(FYSETC_CHEETAH, FYSETC_CHEETAH_V12, FYSETC_AIO_II) + reset_stepper_drivers(); // Workaround for Cheetah bug + #endif + if (!isMounted()) stat = 0; // Not mounted? + } + else { + #if PIN_EXISTS(SD_DETECT) + release(); // Card is released + #endif + } + + ui.media_changed(old_stat, stat); // Update the UI + + if (stat) { + TERN_(SDCARD_EEPROM_EMULATION, settings.first_load()); + if (old_stat == 2) // First mount? + DEBUG_ECHOLNPGM("First mount."); + TERN(POWER_LOSS_RECOVERY, + recovery.check(), // Check for PLR file. (If not there it will beginautostart) + beginautostart() // Look for auto0.g on the next loop + ); + } + } + else + DEBUG_ECHOLNPGM("SD: No UI Detected."); +} + void CardReader::release() { endFilePrint(); flag.mounted = false; + flag.workDirIsRoot = true; + #if ALL(SDCARD_SORT_ALPHA, SDSORT_USES_RAM, SDSORT_CACHE_NAMES) + nrFiles = 0; + #endif } void CardReader::openAndPrintFile(const char *name) { @@ -396,30 +471,21 @@ void CardReader::openAndPrintFile(const char *name) { void CardReader::startFileprint() { if (isMounted()) { flag.sdprinting = true; - #if SD_RESORT - flush_presort(); - #endif + TERN_(SD_RESORT, flush_presort()); } } -void CardReader::endFilePrint( - #if SD_RESORT - const bool re_sort/*=false*/ - #endif -) { - #if ENABLED(ADVANCED_PAUSE_FEATURE) - did_pause_print = 0; - #endif +void CardReader::endFilePrint(TERN_(SD_RESORT, const bool re_sort/*=false*/)) { + TERN_(ADVANCED_PAUSE_FEATURE, did_pause_print = 0); + TERN_(DWIN_CREALITY_LCD, HMI_flag.print_finish = flag.sdprinting); flag.sdprinting = flag.abort_sd_printing = false; if (isFileOpen()) file.close(); - #if SD_RESORT - if (re_sort) presort(); - #endif + TERN_(SD_RESORT, if (re_sort) presort()); } void CardReader::openLogFile(char * const path) { - flag.logging = true; - openFileWrite(path); + flag.logging = DISABLED(SDCARD_READONLY); + TERN(SDCARD_READONLY,,openFileWrite(path)); } // @@ -435,7 +501,7 @@ void CardReader::getAbsFilename(char *dst) { if (cnt < MAXPATHNAMELENGTH) { *dst = '/'; dst++; cnt++; } }; - for (uint8_t i = 0; i < workDirDepth; i++) // Loop down to current work dir + LOOP_L_N(i, workDirDepth) // Loop down to current work dir appendAtom(workDirParents[i]); if (cnt < MAXPATHNAMELENGTH - (FILENAME_LENGTH) - 1) { // Leave room for filename and nul @@ -451,10 +517,12 @@ void openFailed(const char * const fname) { void announceOpen(const uint8_t doing, const char * const path) { if (doing) { + PORT_REDIRECT(SERIAL_BOTH); SERIAL_ECHO_START(); SERIAL_ECHOPGM("Now "); serialprintPGM(doing == 1 ? PSTR("doing") : PSTR("fresh")); SERIAL_ECHOLNPAIR(" file: ", path); + PORT_RESTORE(); } } @@ -482,8 +550,8 @@ void CardReader::openFileRead(char * const path, const uint8_t subcall_type/*=0* // Too deep? The firmware has to bail. if (file_subcall_ctr > SD_PROCEDURE_DEPTH - 1) { - SERIAL_ERROR_MSG("trying to call sub-gcode files with too many levels. MAX level is:" STRINGIFY(SD_PROCEDURE_DEPTH)); - kill(); + SERIAL_ERROR_MSG("Exceeded max SUBROUTINE depth:" STRINGIFY(SD_PROCEDURE_DEPTH)); + kill(GET_TEXT(MSG_KILL_SUBCALL_OVERFLOW)); return; } @@ -504,15 +572,18 @@ void CardReader::openFileRead(char * const path, const uint8_t subcall_type/*=0* endFilePrint(); - SdFile *curDir; - const char * const fname = diveToFile(true, curDir, path); + SdFile *diveDir; + const char * const fname = diveToFile(true, diveDir, path); if (!fname) return; - if (file.open(curDir, fname, O_READ)) { + if (file.open(diveDir, fname, O_READ)) { filesize = file.fileSize(); sdpos = 0; + + PORT_REDIRECT(SERIAL_BOTH); SERIAL_ECHOLNPAIR(STR_SD_FILE_OPENED, fname, STR_SD_SIZE, filesize); SERIAL_ECHOLNPGM(STR_SD_FILE_SELECTED); + PORT_RESTORE(); selectFileByName(fname); ui.set_status(longFilename[0] ? longFilename : fname); @@ -536,21 +607,39 @@ void CardReader::openFileWrite(char * const path) { endFilePrint(); - SdFile *curDir; - const char * const fname = diveToFile(false, curDir, path); + SdFile *diveDir; + const char * const fname = diveToFile(false, diveDir, path); if (!fname) return; - if (file.open(curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) { - flag.saving = true; - selectFileByName(fname); - #if ENABLED(EMERGENCY_PARSER) - emergency_parser.disable(); - #endif - echo_write_to_file(fname); - ui.set_status(fname); - } - else + #if ENABLED(SDCARD_READONLY) openFailed(fname); + #else + if (file.open(diveDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) { + flag.saving = true; + selectFileByName(fname); + TERN_(EMERGENCY_PARSER, emergency_parser.disable()); + echo_write_to_file(fname); + ui.set_status(fname); + } + else + openFailed(fname); + #endif +} + +// +// Check if a file exists by absolute or workDir-relative path +// If the file exists, the long name can also be fetched. +// +bool CardReader::fileExists(const char * const path) { + if (!isMounted()) return false; + SdFile *diveDir = nullptr; + const char * const fname = diveToFile(false, diveDir, path); + if (fname) { + diveDir->rewind(); + selectByName(*diveDir, fname); + diveDir->close(); + } + return fname != nullptr; } // @@ -565,15 +654,17 @@ void CardReader::removeFile(const char * const name) { const char * const fname = diveToFile(false, curDir, name); if (!fname) return; - if (file.remove(curDir, fname)) { - SERIAL_ECHOLNPAIR("File deleted:", fname); - sdpos = 0; - #if ENABLED(SDCARD_SORT_ALPHA) - presort(); - #endif - } - else - SERIAL_ECHOLNPAIR("Deletion failed, File: ", fname, "."); + #if ENABLED(SDCARD_READONLY) + SERIAL_ECHOLNPAIR("Deletion failed (read-only), File: ", fname, "."); + #else + if (file.remove(curDir, fname)) { + SERIAL_ECHOLNPAIR("File deleted:", fname); + sdpos = 0; + TERN_(SDCARD_SORT_ALPHA, presort()); + } + else + SERIAL_ECHOLNPAIR("Deletion failed, File: ", fname, "."); + #endif } void CardReader::report_status() { @@ -617,15 +708,10 @@ void CardReader::checkautostart() { if (autostart_index < 0 || flag.sdprinting) return; if (!isMounted()) mount(); - #if ENABLED(EEPROM_SETTINGS) && NONE(FLASH_EEPROM_EMULATION, SPI_EEPROM, I2C_EEPROM) - else settings.first_load(); - #endif + TERN_(SDCARD_EEPROM_EMULATION, else settings.first_load()); - if (isMounted() - #if ENABLED(POWER_LOSS_RECOVERY) - && !recovery.valid() // Don't run auto#.g when a resume file exists - #endif - ) { + // Don't run auto#.g when a PLR file exists + if (isMounted() && TERN1(POWER_LOSS_RECOVERY, !recovery.valid())) { char autoname[8]; sprintf_P(autoname, PSTR("auto%c.g"), autostart_index + '0'); dir_t p; @@ -647,14 +733,12 @@ void CardReader::beginautostart() { cdroot(); } -void CardReader::closefile(const bool store_location) { +void CardReader::closefile(const bool store_location/*=false*/) { file.sync(); file.close(); flag.saving = flag.logging = false; sdpos = 0; - #if ENABLED(EMERGENCY_PARSER) - emergency_parser.enable(); - #endif + TERN_(EMERGENCY_PARSER, emergency_parser.enable()); if (store_location) { //future: store printer state, filename and position for continuing a stopped print @@ -703,13 +787,15 @@ uint16_t CardReader::countFilesInWorkDir() { /** * Dive to the given DOS 8.3 file path, with optional echo of the dive paths. * - * On exit, curDir contains an SdFile reference to the file's directory. + * On exit: + * - Your curDir pointer contains an SdFile reference to the file's directory. + * - If update_cwd was 'true' the workDir now points to the file's directory. * * Returns a pointer to the last segment (filename) of the given DOS 8.3 path. * * A nullptr result indicates an unrecoverable error. */ -const char* CardReader::diveToFile(const bool update_cwd, SdFile*& curDir, const char * const path, const bool echo/*=false*/) { +const char* CardReader::diveToFile(const bool update_cwd, SdFile*& diveDir, const char * const path, const bool echo/*=false*/) { // Track both parent and subfolder static SdFile newDir1, newDir2; SdFile *sub = &newDir1, *startDir; @@ -717,15 +803,21 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile*& curDir, const // Parsing the path string const char *item_name_adr = path; + DEBUG_ECHOLNPAIR("diveToFile: path = '", path, "'"); + if (path[0] == '/') { // Starting at the root directory? - curDir = &root; - if (update_cwd) workDirDepth = 0; // The cwd can be updated for the benefit of sub-programs + diveDir = &root; item_name_adr++; + DEBUG_ECHOLNPAIR("diveToFile: CWD to root: ", hex_address((void*)diveDir)); + if (update_cwd) workDirDepth = 0; // The cwd can be updated for the benefit of sub-programs } else - curDir = &workDir; // Dive from workDir (as set by the UI) + diveDir = &workDir; // Dive from workDir (as set by the UI) + + startDir = diveDir; + + DEBUG_ECHOLNPAIR("diveToFile: startDir = ", hex_address((void*)startDir)); - startDir = curDir; while (item_name_adr) { // Find next subdirectory delimiter char * const name_end = strchr(item_name_adr, '/'); @@ -741,30 +833,48 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile*& curDir, const if (echo) SERIAL_ECHOLN(dosSubdirname); - // Open curDir - if (!sub->open(curDir, dosSubdirname, O_READ)) { - SERIAL_ECHOLNPAIR(STR_SD_OPEN_FILE_FAIL, dosSubdirname, "."); - return nullptr; + DEBUG_ECHOLNPAIR("diveToFile: sub = ", hex_address((void*)sub)); + + // Open diveDir (closing first) + sub->close(); + if (!sub->open(diveDir, dosSubdirname, O_READ)) { + openFailed(dosSubdirname); + item_name_adr = nullptr; + break; } - // Close curDir if not at starting-point - if (curDir != startDir) curDir->close(); + // Close diveDir if not at starting-point + if (diveDir != startDir) { + DEBUG_ECHOLNPAIR("diveToFile: closing diveDir: ", hex_address((void*)diveDir)); + diveDir->close(); + } - // curDir now subDir - curDir = sub; + // diveDir now subDir + diveDir = sub; + DEBUG_ECHOLNPAIR("diveToFile: diveDir = sub: ", hex_address((void*)diveDir)); - // Update workDirParents, workDirDepth, and workDir + // Update workDirParents and workDirDepth if (update_cwd) { - if (workDirDepth < MAX_DIR_DEPTH) workDirParents[workDirDepth++] = *curDir; - workDir = *curDir; + DEBUG_ECHOLNPAIR("diveToFile: update_cwd"); + if (workDirDepth < MAX_DIR_DEPTH) + workDirParents[workDirDepth++] = *diveDir; } // Point sub at the other scratch object - sub = (curDir != &newDir1) ? &newDir1 : &newDir2; + sub = (diveDir != &newDir1) ? &newDir1 : &newDir2; + DEBUG_ECHOLNPAIR("diveToFile: swapping sub = ", hex_address((void*)sub)); // Next path atom address item_name_adr = name_end + 1; } + + if (update_cwd) { + workDir = *diveDir; + DEBUG_ECHOLNPAIR("diveToFile: final workDir = ", hex_address((void*)diveDir)); + flag.workDirIsRoot = (workDirDepth == 0); + TERN_(SDCARD_SORT_ALPHA, presort()); + } + return item_name_adr; } @@ -777,9 +887,7 @@ void CardReader::cd(const char * relpath) { flag.workDirIsRoot = false; if (workDirDepth < MAX_DIR_DEPTH) workDirParents[workDirDepth++] = workDir; - #if ENABLED(SDCARD_SORT_ALPHA) - presort(); - #endif + TERN_(SDCARD_SORT_ALPHA, presort()); } else { SERIAL_ECHO_START(); @@ -790,9 +898,7 @@ void CardReader::cd(const char * relpath) { int8_t CardReader::cdup() { if (workDirDepth > 0) { // At least 1 dir has been saved workDir = --workDirDepth ? workDirParents[workDirDepth - 1] : root; // Use parent, or root if none - #if ENABLED(SDCARD_SORT_ALPHA) - presort(); - #endif + TERN_(SDCARD_SORT_ALPHA, presort()); } if (!workDirDepth) flag.workDirIsRoot = true; return workDirDepth; @@ -801,9 +907,7 @@ int8_t CardReader::cdup() { void CardReader::cdroot() { workDir = root; flag.workDirIsRoot = true; - #if ENABLED(SDCARD_SORT_ALPHA) - presort(); - #endif + TERN_(SDCARD_SORT_ALPHA, presort()); } #if ENABLED(SDCARD_SORT_ALPHA) @@ -812,12 +916,8 @@ void CardReader::cdroot() { * Get the name of a file in the working directory by sort-index */ void CardReader::getfilename_sorted(const uint16_t nr) { - selectFileByIndex( - #if ENABLED(SDSORT_GCODE) - sort_alpha && - #endif - (nr < sort_count) ? sort_order[nr] : nr - ); + selectFileByIndex(TERN1(SDSORT_GCODE, sort_alpha) && (nr < sort_count) + ? sort_order[nr] : nr); } #if ENABLED(SDSORT_USES_RAM) @@ -863,9 +963,7 @@ void CardReader::cdroot() { flush_presort(); // Sorting may be turned off - #if ENABLED(SDSORT_GCODE) - if (!sort_alpha) return; - #endif + if (TERN0(SDSORT_GCODE, !sort_alpha)) return; // If there are files, sort up to the limit uint16_t fileCnt = countFilesInWorkDir(); @@ -876,9 +974,7 @@ void CardReader::cdroot() { NOMORE(fileCnt, uint16_t(SDSORT_LIMIT)); // Sort order is always needed. May be static or dynamic. - #if ENABLED(SDSORT_DYNAMIC_RAM) - sort_order = new uint8_t[fileCnt]; - #endif + TERN_(SDSORT_DYNAMIC_RAM, sort_order = new uint8_t[fileCnt]); // Use RAM to store the entire directory during pre-sort. // SDSORT_LIMIT should be set to prevent over-allocation. @@ -916,11 +1012,7 @@ void CardReader::cdroot() { // Init sort order. for (uint16_t i = 0; i < fileCnt; i++) { - sort_order[i] = ( - #if ENABLED(SDCARD_RATHERRECENTFIRST) - fileCnt - 1 - - #endif - i); + sort_order[i] = i; // If using RAM then read all filenames now. #if ENABLED(SDSORT_USES_RAM) selectFileByIndex(i); @@ -932,7 +1024,7 @@ void CardReader::cdroot() { #if HAS_FOLDER_SORTING const uint16_t bit = i & 0x07, ind = i >> 3; if (bit == 0) isDir[ind] = 0x00; - if (flag.filenameIsDir) isDir[ind] |= _BV(bit); + if (flag.filenameIsDir) SBI(isDir[ind], bit); #endif #endif } @@ -944,9 +1036,7 @@ void CardReader::cdroot() { #if DISABLED(SDSORT_USES_RAM) selectFileByIndex(o1); // Pre-fetch the first entry and save it strcpy(name1, longest_filename()); // so the loop only needs one fetch - #if HAS_FOLDER_SORTING - bool dir1 = flag.filenameIsDir; - #endif + TERN_(HAS_FOLDER_SORTING, bool dir1 = flag.filenameIsDir); #endif for (uint16_t j = 0; j < i; ++j) { @@ -962,7 +1052,7 @@ void CardReader::cdroot() { #if HAS_FOLDER_SORTING #if ENABLED(SDSORT_USES_RAM) // Folder sorting needs an index and bit to test for folder-ness. - #define _SORT_CMP_DIR(fs) IS_DIR(o1) == IS_DIR(o2) ? _SORT_CMP_NODIR() : IS_DIR(fs > 0 ? o1 : o2) + #define _SORT_CMP_DIR(fs) (IS_DIR(o1) == IS_DIR(o2) ? _SORT_CMP_NODIR() : IS_DIR(fs > 0 ? o1 : o2)) #else #define _SORT_CMP_DIR(fs) ((dir1 == flag.filenameIsDir) ? _SORT_CMP_NODIR() : (fs > 0 ? dir1 : !dir1)) #endif @@ -998,9 +1088,7 @@ void CardReader::cdroot() { // The next o1 is the current o2. No new fetch needed. o1 = o2; #if DISABLED(SDSORT_USES_RAM) - #if HAS_FOLDER_SORTING - dir1 = dir2; - #endif + TERN_(HAS_FOLDER_SORTING, dir1 = dir2); strcpy(name1, name2); #endif } @@ -1011,9 +1099,7 @@ void CardReader::cdroot() { #if ENABLED(SDSORT_USES_RAM) && DISABLED(SDSORT_CACHE_NAMES) #if ENABLED(SDSORT_DYNAMIC_RAM) for (uint16_t i = 0; i < fileCnt; ++i) free(sortnames[i]); - #if HAS_FOLDER_SORTING - free(isDir); - #endif + TERN_(HAS_FOLDER_SORTING, free(isDir)); #endif #endif } @@ -1041,7 +1127,7 @@ void CardReader::cdroot() { #if ENABLED(SDSORT_DYNAMIC_RAM) delete sort_order; #if ENABLED(SDSORT_CACHE_NAMES) - for (uint8_t i = 0; i < sort_count; ++i) { + LOOP_L_N(i, sort_count) { free(sortshort[i]); // strdup free(sortnames[i]); // strdup } @@ -1056,13 +1142,14 @@ void CardReader::cdroot() { #endif // SDCARD_SORT_ALPHA uint16_t CardReader::get_num_Files() { - return - #if ENABLED(SDCARD_SORT_ALPHA) && SDSORT_USES_RAM && SDSORT_CACHE_NAMES + if (!isMounted()) return 0; + return ( + #if ALL(SDCARD_SORT_ALPHA, SDSORT_USES_RAM, SDSORT_CACHE_NAMES) nrFiles // no need to access the SD card for filenames #else countFilesInWorkDir() #endif - ; + ); } // @@ -1078,20 +1165,16 @@ void CardReader::fileHasFinished() { startFileprint(); } else { - endFilePrint(); - - #if ENABLED(SDCARD_SORT_ALPHA) - presort(); - #endif + endFilePrint(TERN_(SD_RESORT, true)); - sdprinting_done_state = 1; + marlin_state = MF_SD_COMPLETE; } } #if ENABLED(AUTO_REPORT_SD_STATUS) uint8_t CardReader::auto_report_sd_interval = 0; millis_t CardReader::next_sd_report_ms; - #if NUM_SERIAL > 1 + #if HAS_MULTI_SERIAL int8_t CardReader::auto_report_port; #endif diff --git a/Marlin/src/sd/cardreader.h b/Marlin/src/sd/cardreader.h index be700401eed4..33645b6531eb 100644 --- a/Marlin/src/sd/cardreader.h +++ b/Marlin/src/sd/cardreader.h @@ -16,16 +16,26 @@ * 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 . + * along with this program. If not, see . * */ #pragma once #include "../inc/MarlinConfig.h" +#define IFSD(A,B) TERN(SDSUPPORT,A,B) + #if ENABLED(SDSUPPORT) -#define SD_RESORT BOTH(SDCARD_SORT_ALPHA, SDSORT_DYNAMIC_RAM) +#if BOTH(SDCARD_SORT_ALPHA, SDSORT_DYNAMIC_RAM) + #define SD_RESORT 1 +#endif + +#if ENABLED(SDCARD_RATHERRECENTFIRST) && DISABLED(SDCARD_SORT_ALPHA) + #define SD_ORDER(N,C) ((C) - 1 - (N)) +#else + #define SD_ORDER(N,C) N +#endif #define MAX_DIR_DEPTH 10 // Maximum folder depth #define MAXDIRNAMELENGTH 8 // DOS folder name size @@ -49,14 +59,13 @@ typedef struct { class CardReader { public: - static uint8_t sdprinting_done_state; static card_flags_t flag; // Flags (above) static char filename[FILENAME_LENGTH], // DOS 8.3 filename of the selected item longFilename[LONG_FILENAME_LENGTH]; // Long name of the selected item // Fast! binary file transfer #if ENABLED(BINARY_FILE_TRANSFER) - #if NUM_SERIAL > 1 + #if HAS_MULTI_SERIAL static int8_t transfer_port_index; #else static constexpr int8_t transfer_port_index = 0; @@ -74,6 +83,9 @@ class CardReader { static inline bool isMounted() { return flag.mounted; } static void ls(); + // Handle media insert/remove + static void manage_media(); + // SD Card Logging static void openLogFile(char * const path); static void write_command(char * const buf); @@ -87,6 +99,7 @@ class CardReader { static void openFileRead(char * const path, const uint8_t subcall=0); static void openFileWrite(char * const path); static void closefile(const bool store_location=false); + static bool fileExists(const char * const name); static void removeFile(const char * const name); static inline char* longest_filename() { return longFilename[0] ? longFilename : filename; } @@ -111,11 +124,7 @@ class CardReader { static void getAbsFilename(char *dst); static void printFilename(); static void startFileprint(); - static void endFilePrint( - #if SD_RESORT - const bool re_sort=false - #endif - ); + static void endFilePrint(TERN_(SD_RESORT, const bool re_sort=false)); static void report_status(); static inline void pauseSDPrint() { flag.sdprinting = false; } static inline bool isPaused() { return isFileOpen() && !flag.sdprinting; } @@ -148,6 +157,7 @@ class CardReader { static inline bool isFileOpen() { return isMounted() && file.isOpen(); } static inline uint32_t getIndex() { return sdpos; } + static inline uint32_t getFileSize() { return filesize; } static inline bool eof() { return sdpos >= filesize; } static inline void setIndex(const uint32_t index) { sdpos = index; file.seekSet(index); } static inline char* getWorkDirName() { workDir.getDosName(filename); return filename; } @@ -160,9 +170,7 @@ class CardReader { #if ENABLED(AUTO_REPORT_SD_STATUS) static void auto_report_sd_status(); static inline void set_auto_report_interval(uint8_t v) { - #if NUM_SERIAL > 1 - auto_report_port = serial_port_index; - #endif + TERN_(HAS_MULTI_SERIAL, auto_report_port = serial_port_index); NOMORE(v, 60); auto_report_sd_interval = v; next_sd_report_ms = millis() + 1000UL * v; @@ -254,7 +262,7 @@ class CardReader { #if ENABLED(AUTO_REPORT_SD_STATUS) static uint8_t auto_report_sd_interval; static millis_t next_sd_report_ms; - #if NUM_SERIAL > 1 + #if HAS_MULTI_SERIAL static int8_t auto_report_port; #endif #endif @@ -276,11 +284,7 @@ class CardReader { #if ENABLED(USB_FLASH_DRIVE_SUPPORT) #define IS_SD_INSERTED() Sd2Card::isInserted() #elif PIN_EXISTS(SD_DETECT) - #if ENABLED(SD_DETECT_INVERTED) - #define IS_SD_INSERTED() READ(SD_DETECT_PIN) - #else - #define IS_SD_INSERTED() !READ(SD_DETECT_PIN) - #endif + #define IS_SD_INSERTED() (READ(SD_DETECT_PIN) == SD_DETECT_STATE) #else // No card detect line? Assume the card is inserted. #define IS_SD_INSERTED() true diff --git a/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp b/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp index c132b4a3b64f..a097df510523 100644 --- a/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp +++ b/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ @@ -94,9 +94,7 @@ static_assert(USB_INTR_PIN != -1, "USB_INTR_PIN must be defined"); #include "Sd2Card_FlashDrive.h" -#if HAS_DISPLAY - #include "../../lcd/ultralcd.h" -#endif +#include "../../lcd/ultralcd.h" static enum { UNINITIALIZED, @@ -116,9 +114,7 @@ bool Sd2Card::usbStartup() { SERIAL_ECHOPGM("Starting USB host..."); if (!UHS_START) { SERIAL_ECHOLNPGM(" failed."); - #if EITHER(ULTRA_LCD, EXTENSIBLE_UI) - LCD_MESSAGEPGM(MSG_MEDIA_USB_FAILED); - #endif + LCD_MESSAGEPGM(MSG_MEDIA_USB_FAILED); return false; } @@ -213,9 +209,7 @@ void Sd2Card::idle() { #if USB_DEBUG >= 1 SERIAL_ECHOLNPGM("Waiting for media"); #endif - #if EITHER(ULTRA_LCD, EXTENSIBLE_UI) - LCD_MESSAGEPGM(MSG_MEDIA_WAITING); - #endif + LCD_MESSAGEPGM(MSG_MEDIA_WAITING); GOTO_STATE_AFTER_DELAY(state, 2000); } break; @@ -229,11 +223,9 @@ void Sd2Card::idle() { #if USB_DEBUG >= 1 SERIAL_ECHOLNPGM("USB device removed"); #endif - #if EITHER(ULTRA_LCD, EXTENSIBLE_UI) - if (state != MEDIA_READY) - LCD_MESSAGEPGM(MSG_MEDIA_USB_REMOVED); - #endif - GOTO_STATE_AFTER_DELAY( WAIT_FOR_DEVICE, 0 ); + if (state != MEDIA_READY) + LCD_MESSAGEPGM(MSG_MEDIA_USB_REMOVED); + GOTO_STATE_AFTER_DELAY(WAIT_FOR_DEVICE, 0); } else if (state > WAIT_FOR_LUN && !bulk.LUNIsGood(0)) { @@ -241,17 +233,13 @@ void Sd2Card::idle() { #if USB_DEBUG >= 1 SERIAL_ECHOLNPGM("Media removed"); #endif - #if EITHER(ULTRA_LCD, EXTENSIBLE_UI) - LCD_MESSAGEPGM(MSG_MEDIA_REMOVED); - #endif - GOTO_STATE_AFTER_DELAY( WAIT_FOR_DEVICE, 0 ); + LCD_MESSAGEPGM(MSG_MEDIA_REMOVED); + GOTO_STATE_AFTER_DELAY(WAIT_FOR_DEVICE, 0); } else if (task_state == UHS_STATE(ERROR)) { - #if EITHER(ULTRA_LCD, EXTENSIBLE_UI) - LCD_MESSAGEPGM(MSG_MEDIA_READ_ERROR); - #endif - GOTO_STATE_AFTER_DELAY( MEDIA_ERROR, 0 ); + LCD_MESSAGEPGM(MSG_MEDIA_READ_ERROR); + GOTO_STATE_AFTER_DELAY(MEDIA_ERROR, 0); } } } diff --git a/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.h b/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.h index f7e59a282afb..8ca95ba7061c 100644 --- a/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.h +++ b/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.h @@ -16,7 +16,7 @@ * 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 . + * along with this program. If not, see . * */ #pragma once @@ -30,19 +30,20 @@ #include "../SdInfo.h" /** - * define SOFTWARE_SPI to use bit-bang SPI + * Define SOFTWARE_SPI to use bit-bang SPI */ -#if MEGA_SOFT_SPI || USE_SOFTWARE_SPI +#if EITHER(MEGA_SOFT_SPI, USE_SOFTWARE_SPI) #define SOFTWARE_SPI #endif // SPI pin definitions - do not edit here - change in SdFatConfig.h -#if DISABLED(SOFTWARE_SPI) +#if ENABLED(SOFTWARE_SPI) + #warning "Auto-assigning '10' as the SD_CHIP_SELECT_PIN." + #define SD_CHIP_SELECT_PIN 10 // Software SPI chip select pin for the SD +#else // hardware pin defs #define SD_CHIP_SELECT_PIN SS_PIN // The default chip select pin for the SD card is SS. -#else // SOFTWARE_SPI - #define SD_CHIP_SELECT_PIN 10 // Software SPI chip select pin for the SD -#endif // SOFTWARE_SPI +#endif class Sd2Card { private: diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/Usb.cpp b/Marlin/src/sd/usb_flashdrive/lib-uhs2/Usb.cpp index 9092633b844f..8a989157b40a 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/Usb.cpp +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/Usb.cpp @@ -19,7 +19,7 @@ * ------------------- * * Circuits At Home, LTD - * Web : http://www.circuitsathome.com + * Web : https://www.circuitsathome.com * e-mail : support@circuitsathome.com */ /* USB functions */ @@ -428,7 +428,7 @@ void USB::Task() { //USB state machine uint8_t rcode; uint8_t tmpdata; static uint32_t delay = 0; - //USB_DEVICE_DESCRIPTOR buf; + //USB_FD_DEVICE_DESCRIPTOR buf; bool lowspeed = false; MAX3421E::Task(); @@ -640,15 +640,14 @@ uint8_t USB::AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lo * 7: for (each driver) { * 7a: Ask device if it knows this VID/PID. Acts exactly like 6a, but using VID/PID * 8: if we get here, no driver likes the device plugged in, so exit failure. - * */ uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) { //uint8_t bAddress = 0; //printf("Configuring: parent = %i, port = %i\r\n", parent, port); uint8_t devConfigIndex; uint8_t rcode = 0; - uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)]; - USB_DEVICE_DESCRIPTOR *udd = reinterpret_cast(buf); + uint8_t buf[sizeof (USB_FD_DEVICE_DESCRIPTOR)]; + USB_FD_DEVICE_DESCRIPTOR *udd = reinterpret_cast(buf); UsbDevice *p = nullptr; EpInfo *oldep_ptr = nullptr; EpInfo epInfo; @@ -678,13 +677,13 @@ uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) { p->lowspeed = lowspeed; // Get device descriptor - rcode = getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); + rcode = getDevDescr(0, 0, sizeof (USB_FD_DEVICE_DESCRIPTOR), (uint8_t*)buf); // Restore p->epinfo p->epinfo = oldep_ptr; if (rcode) { - //printf("Configuring error: Can't get USB_DEVICE_DESCRIPTOR\r\n"); + //printf("Configuring error: Can't get USB_FD_DEVICE_DESCRIPTOR\r\n"); return rcode; } @@ -762,7 +761,7 @@ uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t con uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint8_t conf, USBReadParser *p) { const uint8_t bufSize = 64; uint8_t buf[bufSize]; - USB_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast(buf); + USB_FD_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast(buf); uint8_t ret = getConfDescr(addr, ep, 9, conf, buf); if (ret) return ret; diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/Usb.h b/Marlin/src/sd/usb_flashdrive/lib-uhs2/Usb.h index 195b26e940ca..b1ec14699983 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/Usb.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/Usb.h @@ -19,7 +19,7 @@ * ------------------- * * Circuits At Home, LTD - * Web : http://www.circuitsathome.com + * Web : https://www.circuitsathome.com * e-mail : support@circuitsathome.com */ #pragma once diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/UsbCore.h b/Marlin/src/sd/usb_flashdrive/lib-uhs2/UsbCore.h index 472fed59cf6e..d94958dd5492 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/UsbCore.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/UsbCore.h @@ -19,7 +19,7 @@ * ------------------- * * Circuits At Home, LTD - * Web : http://www.circuitsathome.com + * Web : https://www.circuitsathome.com * e-mail : support@circuitsathome.com */ @@ -78,16 +78,16 @@ typedef MAX3421e MAX3421E; // Official Arduinos (UNO, Duemilanove, Mega #define USB_CLASS_PRINTER 0x07 // Printer #define USB_CLASS_MASS_STORAGE 0x08 // Mass Storage #define USB_CLASS_HUB 0x09 // Hub -#define USB_CLASS_CDC_DATA 0x0a // CDC-Data -#define USB_CLASS_SMART_CARD 0x0b // Smart-Card -#define USB_CLASS_CONTENT_SECURITY 0x0d // Content Security -#define USB_CLASS_VIDEO 0x0e // Video -#define USB_CLASS_PERSONAL_HEALTH 0x0f // Personal Healthcare -#define USB_CLASS_DIAGNOSTIC_DEVICE 0xdc // Diagnostic Device -#define USB_CLASS_WIRELESS_CTRL 0xe0 // Wireless Controller -#define USB_CLASS_MISC 0xef // Miscellaneous -#define USB_CLASS_APP_SPECIFIC 0xfe // Application Specific -#define USB_CLASS_VENDOR_SPECIFIC 0xff // Vendor Specific +#define USB_CLASS_CDC_DATA 0x0A // CDC-Data +#define USB_CLASS_SMART_CARD 0x0B // Smart-Card +#define USB_CLASS_CONTENT_SECURITY 0x0D // Content Security +#define USB_CLASS_VIDEO 0x0E // Video +#define USB_CLASS_PERSONAL_HEALTH 0x0F // Personal Healthcare +#define USB_CLASS_DIAGNOSTIC_DEVICE 0xDC // Diagnostic Device +#define USB_CLASS_WIRELESS_CTRL 0xE0 // Wireless Controller +#define USB_CLASS_MISC 0xEF // Miscellaneous +#define USB_CLASS_APP_SPECIFIC 0xFE // Application Specific +#define USB_CLASS_VENDOR_SPECIFIC 0xFF // Vendor Specific // Additional Error Codes #define USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED 0xD1 @@ -117,7 +117,7 @@ typedef MAX3421e MAX3421E; // Official Arduinos (UNO, Duemilanove, Mega #define HUB_PORT_RESET_DELAY 20 // hub port reset delay 10 ms recomended, can be up to 20 ms /* USB state machine states */ -#define USB_STATE_MASK 0xf0 +#define USB_STATE_MASK 0xF0 #define USB_STATE_DETACHED 0x10 #define USB_DETACHED_SUBSTATE_INITIALIZE 0x11 @@ -132,7 +132,7 @@ typedef MAX3421e MAX3421E; // Official Arduinos (UNO, Duemilanove, Mega #define USB_STATE_ADDRESSING 0x70 #define USB_STATE_CONFIGURING 0x80 #define USB_STATE_RUNNING 0x90 -#define USB_STATE_ERROR 0xa0 +#define USB_STATE_ERROR 0xA0 class USBDeviceConfig { public: diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/address.h b/Marlin/src/sd/usb_flashdrive/lib-uhs2/address.h index f51e43f0ea8c..373b95a7f9bf 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/address.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/address.h @@ -19,7 +19,7 @@ * ------------------- * * Circuits At Home, LTD - * Web : http://www.circuitsathome.com + * Web : https://www.circuitsathome.com * e-mail : support@circuitsathome.com */ #pragma once diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/confdescparser.h b/Marlin/src/sd/usb_flashdrive/lib-uhs2/confdescparser.h index 5d4ddaf175c9..9ed35fff65c8 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/confdescparser.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/confdescparser.h @@ -19,7 +19,7 @@ * ------------------- * * Circuits At Home, LTD - * Web : http://www.circuitsathome.com + * Web : https://www.circuitsathome.com * e-mail : support@circuitsathome.com */ #pragma once @@ -30,10 +30,10 @@ class UsbConfigXtracter { public: - //virtual void ConfigXtract(const USB_CONFIGURATION_DESCRIPTOR *conf) = 0; - //virtual void InterfaceXtract(uint8_t conf, const USB_INTERFACE_DESCRIPTOR *iface) = 0; + //virtual void ConfigXtract(const USB_FD_CONFIGURATION_DESCRIPTOR *conf) = 0; + //virtual void InterfaceXtract(uint8_t conf, const USB_FD_INTERFACE_DESCRIPTOR *iface) = 0; - virtual void EndpointXtract(uint8_t conf __attribute__((unused)), uint8_t iface __attribute__((unused)), uint8_t alt __attribute__((unused)), uint8_t proto __attribute__((unused)), const USB_ENDPOINT_DESCRIPTOR *ep __attribute__((unused))) { + virtual void EndpointXtract(uint8_t conf __attribute__((unused)), uint8_t iface __attribute__((unused)), uint8_t alt __attribute__((unused)), uint8_t proto __attribute__((unused)), const USB_FD_ENDPOINT_DESCRIPTOR *ep __attribute__((unused))) { } }; @@ -50,7 +50,7 @@ class ConfigDescParser : public USBReadParser { MultiValueBuffer theBuffer; MultiByteValueParser valParser; ByteSkipper theSkipper; - uint8_t varBuffer[16 /*sizeof(USB_CONFIGURATION_DESCRIPTOR)*/]; + uint8_t varBuffer[16 /*sizeof(USB_FD_CONFIGURATION_DESCRIPTOR)*/]; uint8_t stateParseDescr; // ParseDescriptor state @@ -97,8 +97,8 @@ void ConfigDescParser::Parse(const uin compare masks for them. When the match is found, calls EndpointXtract passing buffer containing endpoint descriptor */ template bool ConfigDescParser::ParseDescriptor(uint8_t **pp, uint16_t *pcntdn) { - USB_CONFIGURATION_DESCRIPTOR* ucd = reinterpret_cast(varBuffer); - USB_INTERFACE_DESCRIPTOR* uid = reinterpret_cast(varBuffer); + USB_FD_CONFIGURATION_DESCRIPTOR* ucd = reinterpret_cast(varBuffer); + USB_FD_INTERFACE_DESCRIPTOR* uid = reinterpret_cast(varBuffer); switch (stateParseDescr) { case 0: theBuffer.valueSize = 2; @@ -155,7 +155,7 @@ bool ConfigDescParser::ParseDescriptor case USB_DESCRIPTOR_ENDPOINT: if (!valParser.Parse(pp, pcntdn)) return false; if (isGoodInterface && theXtractor) - theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*)varBuffer); + theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_FD_ENDPOINT_DESCRIPTOR*)varBuffer); break; //case HID_DESCRIPTOR_HID: // if (!valParser.Parse(pp, pcntdn)) return false; diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/hexdump.h b/Marlin/src/sd/usb_flashdrive/lib-uhs2/hexdump.h index 59c3b48f67b5..c948e5aba022 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/hexdump.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/hexdump.h @@ -19,7 +19,7 @@ * ------------------- * * Circuits At Home, LTD - * Web : http://www.circuitsathome.com + * Web : https://www.circuitsathome.com * e-mail : support@circuitsathome.com */ #pragma once diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/macros.h b/Marlin/src/sd/usb_flashdrive/lib-uhs2/macros.h index 0fb5c02ff112..8cb5b6bf37e8 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/macros.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/macros.h @@ -19,7 +19,7 @@ * ------------------- * * Circuits At Home, LTD - * Web : http://www.circuitsathome.com + * Web : https://www.circuitsathome.com * e-mail : support@circuitsathome.com */ #pragma once @@ -52,16 +52,16 @@ #define BGRAB7(__usi__) (((uint8_t *)&(__usi__))[7]) #else // Note: The cast alone to uint8_t is actually enough. -// GCC throws out the "& 0xff", and the size is no different. +// GCC throws out the "& 0xFF", and the size is no different. // Some compilers need it. -#define BGRAB0(__usi__) ((uint8_t)((__usi__) & 0xff )) -#define BGRAB1(__usi__) ((uint8_t)(((__usi__) >> 8) & 0xff)) -#define BGRAB2(__usi__) ((uint8_t)(((__usi__) >> 16) & 0xff)) -#define BGRAB3(__usi__) ((uint8_t)(((__usi__) >> 24) & 0xff)) -#define BGRAB4(__usi__) ((uint8_t)(((__usi__) >> 32) & 0xff)) -#define BGRAB5(__usi__) ((uint8_t)(((__usi__) >> 40) & 0xff)) -#define BGRAB6(__usi__) ((uint8_t)(((__usi__) >> 48) & 0xff)) -#define BGRAB7(__usi__) ((uint8_t)(((__usi__) >> 56) & 0xff)) +#define BGRAB0(__usi__) ((uint8_t)((__usi__) & 0xFF )) +#define BGRAB1(__usi__) ((uint8_t)(((__usi__) >> 8) & 0xFF)) +#define BGRAB2(__usi__) ((uint8_t)(((__usi__) >> 16) & 0xFF)) +#define BGRAB3(__usi__) ((uint8_t)(((__usi__) >> 24) & 0xFF)) +#define BGRAB4(__usi__) ((uint8_t)(((__usi__) >> 32) & 0xFF)) +#define BGRAB5(__usi__) ((uint8_t)(((__usi__) >> 40) & 0xFF)) +#define BGRAB6(__usi__) ((uint8_t)(((__usi__) >> 48) & 0xFF)) +#define BGRAB7(__usi__) ((uint8_t)(((__usi__) >> 56) & 0xFF)) #endif #define BOVER1(__usi__) ((uint16_t)(__usi__) << 8) #define BOVER2(__usi__) ((uint32_t)(__usi__) << 16) diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/masstorage.cpp b/Marlin/src/sd/usb_flashdrive/lib-uhs2/masstorage.cpp index a57245f78a70..a84a68320413 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/masstorage.cpp +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/masstorage.cpp @@ -19,7 +19,7 @@ * ------------------- * * Circuits At Home, LTD - * Web : http://www.circuitsathome.com + * Web : https://www.circuitsathome.com * e-mail : support@circuitsathome.com */ @@ -250,10 +250,10 @@ bLastUsbError(0) { */ uint8_t BulkOnly::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) { - const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR); + const uint8_t constBufSize = sizeof (USB_FD_DEVICE_DESCRIPTOR); uint8_t buf[constBufSize]; - USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf); + USB_FD_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf); uint8_t rcode; UsbDevice *p = nullptr; EpInfo *oldep_ptr = nullptr; @@ -439,7 +439,7 @@ uint8_t BulkOnly::Init(uint8_t parent __attribute__((unused)), uint8_t port __at printf(" standards.\r\n"); #endif - uint8_t tries = 0xf0; + uint8_t tries = 0xF0; while ((rcode = TestUnitReady(lun))) { if (rcode == 0x08) break; // break on no media, this is OK to do. // try to lock media and spin up @@ -529,7 +529,7 @@ uint8_t BulkOnly::Init(uint8_t parent __attribute__((unused)), uint8_t port __at * @param proto * @param pep */ -void BulkOnly::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto __attribute__((unused)), const USB_ENDPOINT_DESCRIPTOR * pep) { +void BulkOnly::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto __attribute__((unused)), const USB_FD_ENDPOINT_DESCRIPTOR * pep) { ErrorMessage (PSTR("Conf.Val"), conf); ErrorMessage (PSTR("Iface Num"), iface); ErrorMessage (PSTR("Alt.Set"), alt); @@ -765,7 +765,7 @@ uint8_t BulkOnly::Page3F(uint8_t lun) { #ifdef SKIP_WRITE_PROTECT return 0; #endif - uint8_t rc = ModeSense6(lun, 0, 0x3f, 0, 192, buf); + uint8_t rc = ModeSense6(lun, 0, 0x3F, 0, 192, buf); if (!rc) { WriteOk[lun] = ((buf[2] & 0x80) == 0); Notify(PSTR("Mode Sense: "), 0x80); @@ -828,7 +828,6 @@ uint8_t BulkOnly::ClearEpHalt(uint8_t index) { /** * For driver use only. - * */ void BulkOnly::Reset() { while (pUsb->ctrlReq(bAddress, 0, bmREQ_MASSOUT, MASS_REQ_BOMSR, 0, 0, bIface, 0, 0, nullptr, nullptr) == 0x01) delay(6); @@ -1163,10 +1162,9 @@ uint8_t BulkOnly::HandleSCSIError(uint8_t status) { //////////////////////////////////////////////////////////////////////////////// /** - * * @param ep_ptr */ -void BulkOnly::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR * ep_ptr) { +void BulkOnly::PrintEndpointDescriptor(const USB_FD_ENDPOINT_DESCRIPTOR * ep_ptr) { Notify(PSTR("Endpoint descriptor:"), 0x80); Notify(PSTR("\r\nLength:\t\t"), 0x80); D_PrintHex (ep_ptr->bLength, 0x80); @@ -1205,10 +1203,10 @@ uint8_t BulkOnly::Read(uint8_t lun __attribute__((unused)), uint32_t addr __attr cbw.CBWCB[0] = SCSI_CMD_READ_10; cbw.CBWCB[8] = blocks; - cbw.CBWCB[2] = ((addr >> 24) & 0xff); - cbw.CBWCB[3] = ((addr >> 16) & 0xff); - cbw.CBWCB[4] = ((addr >> 8) & 0xff); - cbw.CBWCB[5] = (addr & 0xff); + cbw.CBWCB[2] = ((addr >> 24) & 0xFF); + cbw.CBWCB[3] = ((addr >> 16) & 0xFF); + cbw.CBWCB[4] = ((addr >> 8) & 0xFF); + cbw.CBWCB[5] = (addr & 0xFF); return HandleSCSIError(Transaction(&cbw, bsize, prs, 1)); #else diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/masstorage.h b/Marlin/src/sd/usb_flashdrive/lib-uhs2/masstorage.h index 09b82fdb92d4..25df006e513d 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/masstorage.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/masstorage.h @@ -19,7 +19,7 @@ * ------------------- * * Circuits At Home, LTD - * Web : http://www.circuitsathome.com + * Web : https://www.circuitsathome.com * e-mail : support@circuitsathome.com */ @@ -67,7 +67,7 @@ #define MASS_CMD_DIR_IN 0x80 //(1 << 7) /* - * Reference documents from T10 (http://www.t10.org) + * Reference documents from T10 (https://www.t10.org) * SCSI Primary Commands - 3 (SPC-3) * SCSI Block Commands - 2 (SBC-2) * Multi-Media Commands - 5 (MMC-5) @@ -214,7 +214,7 @@ struct CDB6 { public: CDB6(uint8_t _Opcode, uint8_t _LUN, uint32_t LBA, uint8_t _AllocationLength, uint8_t _Control) : - Opcode(_Opcode), LBAMSB(BGRAB2(LBA) & 0x1f), LUN(_LUN), LBAHB(BGRAB1(LBA)), LBALB(BGRAB0(LBA)), + Opcode(_Opcode), LBAMSB(BGRAB2(LBA) & 0x1F), LUN(_LUN), LBAHB(BGRAB1(LBA)), LBALB(BGRAB0(LBA)), AllocationLength(_AllocationLength), Control(_Control) { } @@ -491,7 +491,7 @@ class BulkOnly : public USBDeviceConfig, public UsbConfigXtracter { uint16_t CurrentSectorSize[MASS_MAX_SUPPORTED_LUN]; // Sector size, clipped to 16 bits bool LUNOk[MASS_MAX_SUPPORTED_LUN]; // use this to check for media changes. bool WriteOk[MASS_MAX_SUPPORTED_LUN]; - void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr); + void PrintEndpointDescriptor(const USB_FD_ENDPOINT_DESCRIPTOR* ep_ptr); // Additional Initialization Method for Subclasses @@ -526,7 +526,7 @@ class BulkOnly : public USBDeviceConfig, public UsbConfigXtracter { virtual uint8_t GetAddress() { return bAddress; } // UsbConfigXtracter implementation - void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep); + void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_FD_ENDPOINT_DESCRIPTOR *ep); virtual bool DEVCLASSOK(uint8_t klass) { return klass == USB_CLASS_MASS_STORAGE; } diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/max3421e.h b/Marlin/src/sd/usb_flashdrive/lib-uhs2/max3421e.h index 39845fb730b2..6cad39d0df59 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/max3421e.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/max3421e.h @@ -19,7 +19,7 @@ * ------------------- * * Circuits At Home, LTD - * Web : http://www.circuitsathome.com + * Web : https://www.circuitsathome.com * e-mail : support@circuitsathome.com */ #pragma once @@ -86,7 +86,7 @@ #define rREVISION 0x90 //18<<3 -#define rIOPINS1 0xa0 //20<<3 +#define rIOPINS1 0xA0 //20<<3 /* IOPINS1 Bits */ #define bmGPOUT0 0x01 @@ -98,7 +98,7 @@ #define bmGPIN2 0x40 #define bmGPIN3 0x80 -#define rIOPINS2 0xa8 //21<<3 +#define rIOPINS2 0xA8 //21<<3 /* IOPINS2 Bits */ #define bmGPOUT4 0x01 #define bmGPOUT5 0x02 @@ -109,7 +109,7 @@ #define bmGPIN6 0x40 #define bmGPIN7 0x80 -#define rGPINIRQ 0xb0 //22<<3 +#define rGPINIRQ 0xB0 //22<<3 /* GPINIRQ Bits */ #define bmGPINIRQ0 0x01 #define bmGPINIRQ1 0x02 @@ -120,7 +120,7 @@ #define bmGPINIRQ6 0x40 #define bmGPINIRQ7 0x80 -#define rGPINIEN 0xb8 //23<<3 +#define rGPINIEN 0xB8 //23<<3 /* GPINIEN Bits */ #define bmGPINIEN0 0x01 #define bmGPINIEN1 0x02 @@ -131,7 +131,7 @@ #define bmGPINIEN6 0x40 #define bmGPINIEN7 0x80 -#define rGPINPOL 0xc0 //24<<3 +#define rGPINPOL 0xC0 //24<<3 /* GPINPOL Bits */ #define bmGPINPOL0 0x01 #define bmGPINPOL1 0x02 @@ -142,7 +142,7 @@ #define bmGPINPOL6 0x40 #define bmGPINPOL7 0x80 -#define rHIRQ 0xc8 //25<<3 +#define rHIRQ 0xC8 //25<<3 /* HIRQ Bits */ #define bmBUSEVENTIRQ 0x01 // indicates BUS Reset Done or BUS Resume #define bmRWUIRQ 0x02 @@ -153,7 +153,7 @@ #define bmFRAMEIRQ 0x40 #define bmHXFRDNIRQ 0x80 -#define rHIEN 0xd0 //26<<3 +#define rHIEN 0xD0 //26<<3 /* HIEN Bits */ #define bmBUSEVENTIE 0x01 @@ -165,7 +165,7 @@ #define bmFRAMEIE 0x40 #define bmHXFRDNIE 0x80 -#define rMODE 0xd8 //27<<3 +#define rMODE 0xD8 //27<<3 /* MODE Bits */ #define bmHOST 0x01 @@ -177,9 +177,9 @@ #define bmDMPULLDN 0x40 #define bmDPPULLDN 0x80 -#define rPERADDR 0xe0 //28<<3 +#define rPERADDR 0xE0 //28<<3 -#define rHCTL 0xe8 //29<<3 +#define rHCTL 0xE8 //29<<3 /* HCTL Bits */ #define bmBUSRST 0x01 #define bmFRMRST 0x02 @@ -190,7 +190,7 @@ #define bmSNDTOG0 0x40 #define bmSNDTOG1 0x80 -#define rHXFR 0xf0 //30<<3 +#define rHXFR 0xF0 //30<<3 #undef tokSETUP #undef tokIN @@ -210,7 +210,7 @@ #define tokISOIN 0x40 // HS=0, ISO=1, OUTNIN=0, SETUP=0 #define tokISOOUT 0x60 // HS=0, ISO=1, OUTNIN=1, SETUP=0 -#define rHRSL 0xf8 //31<<3 +#define rHRSL 0xF8 //31<<3 /* HRSL Bits */ #define bmRCVTOGRD 0x10 @@ -218,7 +218,7 @@ #define bmKSTATUS 0x40 #define bmJSTATUS 0x80 #define bmSE0 0x00 //SE0 - disconnect state -#define bmSE1 0xc0 //SE1 - illegal state +#define bmSE1 0xC0 //SE1 - illegal state /* Host error result codes, the 4 LSB's in the HRSL register */ #define hrSUCCESS 0x00 diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/message.cpp b/Marlin/src/sd/usb_flashdrive/lib-uhs2/message.cpp index 78a9ba1fd71d..dcc309025a69 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/message.cpp +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/message.cpp @@ -19,7 +19,7 @@ * ------------------- * * Circuits At Home, LTD - * Web : http://www.circuitsathome.com + * Web : https://www.circuitsathome.com * e-mail : support@circuitsathome.com */ @@ -37,7 +37,7 @@ int UsbDEBUGlvl = 0x80; void E_Notifyc(char c, int lvl) { if (UsbDEBUGlvl < lvl) return; USB_HOST_SERIAL.print(c - #if !defined(ARDUINO) || ARDUINO < 100 + #if !defined(ARDUINO) && !defined(ARDUINO_ARCH_LPC176X) , BYTE #endif ); diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/message.h b/Marlin/src/sd/usb_flashdrive/lib-uhs2/message.h index 960120d18d2c..12195dcf62a9 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/message.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/message.h @@ -19,7 +19,7 @@ * ------------------- * * Circuits At Home, LTD - * Web : http://www.circuitsathome.com + * Web : https://www.circuitsathome.com * e-mail : support@circuitsathome.com */ #pragma once diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/parsetools.cpp b/Marlin/src/sd/usb_flashdrive/lib-uhs2/parsetools.cpp index 0c7061b77c30..5d25576c40c6 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/parsetools.cpp +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/parsetools.cpp @@ -19,7 +19,7 @@ * ------------------- * * Circuits At Home, LTD - * Web : http://www.circuitsathome.com + * Web : https://www.circuitsathome.com * e-mail : support@circuitsathome.com */ diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/parsetools.h b/Marlin/src/sd/usb_flashdrive/lib-uhs2/parsetools.h index 28a28414463e..403766da8ff1 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/parsetools.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/parsetools.h @@ -19,7 +19,7 @@ * ------------------- * * Circuits At Home, LTD - * Web : http://www.circuitsathome.com + * Web : https://www.circuitsathome.com * e-mail : support@circuitsathome.com */ #pragma once diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/printhex.h b/Marlin/src/sd/usb_flashdrive/lib-uhs2/printhex.h index 2cde3fc34148..319cd9c4c87d 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/printhex.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/printhex.h @@ -19,7 +19,7 @@ * ------------------- * * Circuits At Home, LTD - * Web : http://www.circuitsathome.com + * Web : https://www.circuitsathome.com * e-mail : support@circuitsathome.com */ #pragma once @@ -34,7 +34,7 @@ template void PrintHex(T val, int lvl) { int num_nibbles = sizeof (T) * 2; do { - char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f); + char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0F); if (v > 57) v += 7; E_Notifyc(v, lvl); } while (--num_nibbles); @@ -50,7 +50,7 @@ template void SerialPrintHex(T val) { int num_nibbles = sizeof (T) * 2; do { - char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f); + char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0F); if (v > 57) v += 7; USB_HOST_SERIAL.print(v); } while (--num_nibbles); diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/settings.h b/Marlin/src/sd/usb_flashdrive/lib-uhs2/settings.h index 41821173d36b..2de0d465e8f3 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/settings.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/settings.h @@ -19,7 +19,7 @@ * ------------------- * * Circuits At Home, LTD - * Web : http://www.circuitsathome.com + * Web : https://www.circuitsathome.com * e-mail : support@circuitsathome.com */ @@ -132,7 +132,7 @@ #if GCC_VERSION < 40602 // Test for GCC < 4.6.2 #ifdef PROGMEM #undef PROGMEM - #define PROGMEM __attribute__((section(".progmem.data"))) // Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734#c4 + #define PROGMEM __attribute__((section(".progmem.data"))) // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734#c4 #ifdef PSTR #undef PSTR #define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];})) // Copied from pgmspace.h in avr-libc source diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/usb_ch9.h b/Marlin/src/sd/usb_flashdrive/lib-uhs2/usb_ch9.h index 039215b1bbcf..99c628f888d3 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/usb_ch9.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/usb_ch9.h @@ -19,7 +19,7 @@ * ------------------- * * Circuits At Home, LTD - * Web : http://www.circuitsathome.com + * Web : https://www.circuitsathome.com * e-mail : support@circuitsathome.com */ @@ -116,7 +116,7 @@ typedef struct { uint8_t iProduct; // Index of String Descriptor describing the product. uint8_t iSerialNumber; // Index of String Descriptor with the device's serial number. uint8_t bNumConfigurations; // Number of possible configurations. -} __attribute__((packed)) USB_DEVICE_DESCRIPTOR; +} __attribute__((packed)) USB_FD_DEVICE_DESCRIPTOR; /* Configuration descriptor structure */ typedef struct { @@ -128,7 +128,7 @@ typedef struct { uint8_t iConfiguration; // Index of String Descriptor describing the configuration. uint8_t bmAttributes; // Configuration characteristics. uint8_t bMaxPower; // Maximum power consumed by this configuration. -} __attribute__((packed)) USB_CONFIGURATION_DESCRIPTOR; +} __attribute__((packed)) USB_FD_CONFIGURATION_DESCRIPTOR; /* Interface descriptor structure */ typedef struct { @@ -141,7 +141,7 @@ typedef struct { uint8_t bInterfaceSubClass; // Subclass code (assigned by the USB-IF). uint8_t bInterfaceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific. uint8_t iInterface; // Index of String Descriptor describing the interface. -} __attribute__((packed)) USB_INTERFACE_DESCRIPTOR; +} __attribute__((packed)) USB_FD_INTERFACE_DESCRIPTOR; /* Endpoint descriptor structure */ typedef struct { @@ -151,7 +151,7 @@ typedef struct { uint8_t bmAttributes; // Endpoint transfer type. uint16_t wMaxPacketSize; // Maximum packet size. uint8_t bInterval; // Polling interval in frames. -} __attribute__((packed)) USB_ENDPOINT_DESCRIPTOR; +} __attribute__((packed)) USB_FD_ENDPOINT_DESCRIPTOR; /* HID descriptor */ typedef struct { diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/usbhost.cpp b/Marlin/src/sd/usb_flashdrive/lib-uhs2/usbhost.cpp index 16051b34c345..6d2182cb8bbd 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/usbhost.cpp +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/usbhost.cpp @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ /* What follows is a modified version of the MAX3421e originally defined in @@ -90,7 +90,7 @@ uint8_t* MAX3421e::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* data_p) { // GPIN pins are in high nybbles of IOPINS1, IOPINS2 uint8_t MAX3421e::gpioRd() { - return (regRd(rIOPINS2) & 0xf0) | // pins 4-7, clean lower nybble + return (regRd(rIOPINS2) & 0xF0) | // pins 4-7, clean lower nybble (regRd(rIOPINS1) >> 4); // shift low bits and OR with upper from previous operation. } diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/usbhost.h b/Marlin/src/sd/usb_flashdrive/lib-uhs2/usbhost.h index 8fdad47ac2ec..07ca811a4def 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/usbhost.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/usbhost.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * - * location: . * + * location: . * ****************************************************************************/ #pragma once diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_BULK_STORAGE.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_BULK_STORAGE.h index 6ad9cb5c8dc3..b35e53686e8a 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_BULK_STORAGE.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_BULK_STORAGE.h @@ -20,7 +20,7 @@ Contact information ------------------- Circuits At Home, LTD -Web : http://www.circuitsathome.com +Web : https://www.circuitsathome.com e-mail : support@circuitsathome.com */ @@ -174,7 +174,7 @@ class UHS_Bulk_Storage : public UHS_USBInterface { volatile uint16_t CurrentSectorSize[MASS_MAX_SUPPORTED_LUN]; // Sector size, clipped to 16 bits volatile bool LUNOk[MASS_MAX_SUPPORTED_LUN]; // use this to check for media changes. volatile bool WriteOk[MASS_MAX_SUPPORTED_LUN]; - void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr); + void PrintEndpointDescriptor(const USB_FD_ENDPOINT_DESCRIPTOR* ep_ptr); public: UHS_Bulk_Storage(UHS_USB_HOST_BASE *p); diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_BULK_STORAGE_INLINE.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_BULK_STORAGE_INLINE.h index a171b13818ca..37ba681c5c7b 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_BULK_STORAGE_INLINE.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_BULK_STORAGE_INLINE.h @@ -20,7 +20,7 @@ Contact information ------------------- Circuits At Home, LTD -Web : http://www.circuitsathome.com +Web : https://www.circuitsathome.com e-mail : support@circuitsathome.com */ @@ -318,7 +318,6 @@ UHS_NI UHS_Bulk_Storage::UHS_Bulk_Storage(UHS_USB_HOST_BASE *p) { } /** - * * @param ei Enumeration information * @return true if this interface driver can handle this interface description */ @@ -375,7 +374,6 @@ uint8_t UHS_NI UHS_Bulk_Storage::SetInterface(ENUMERATION_INFO *ei) { }; /** - * * @return 0 for success */ uint8_t UHS_NI UHS_Bulk_Storage::Start() { @@ -455,9 +453,9 @@ uint8_t UHS_NI UHS_Bulk_Storage::Start() { for(uint8_t lun = 0; lun <= bMaxLUN; lun++) { if(!UHS_SLEEP_MS(3)) goto FailUnPlug; #ifndef USB_NO_TEST_UNIT_READY - uint8_t tries = 0xf0; + uint8_t tries = 0xF0; while((rcode = TestUnitReady(lun))) { - BS_HOST_DEBUG("\r\nTry %2.2x TestUnitReady %2.2x\r\n", tries - 0xf0, rcode); + BS_HOST_DEBUG("\r\nTry %2.2x TestUnitReady %2.2x\r\n", tries - 0xF0, rcode); if(rcode == 0x08) break; // break on no media, this is OK to do. if(rcode == UHS_BULK_ERR_DEVICE_DISCONNECTED) goto FailUnPlug; if(rcode == UHS_BULK_ERR_INVALID_CSW) goto Fail; @@ -477,7 +475,7 @@ uint8_t UHS_NI UHS_Bulk_Storage::Start() { if(!UHS_SLEEP_MS(3)) goto FailUnPlug; if(MediaCTL(lun, 1) == UHS_BULK_ERR_DEVICE_DISCONNECTED) goto FailUnPlug; // I actually have a USB stick that needs this! } - BS_HOST_DEBUG("\r\nTry %2.2x TestUnitReady %2.2x\r\n", tries - 0xf0, rcode); + BS_HOST_DEBUG("\r\nTry %2.2x TestUnitReady %2.2x\r\n", tries - 0xF0, rcode); if(!rcode) { if(!UHS_SLEEP_MS(3)) goto FailUnPlug; BS_HOST_DEBUG("CheckLUN...\r\n"); @@ -581,7 +579,7 @@ bool UHS_NI UHS_Bulk_Storage::CheckLUN(uint8_t lun) { CurrentCapacity[lun] = UHS_BYTES_TO_UINT32(capacity.data[0], capacity.data[1], capacity.data[2], capacity.data[3]) + 1; if(CurrentCapacity[lun] == /*0xffffffffLU */ 0x01LU || CurrentCapacity[lun] == 0x00LU) { - // Buggy firmware will report 0xffffffff or 0 for no media + // Buggy firmware will report 0xFFFFFFFF or 0 for no media #ifdef DEBUG_USB_HOST if(CurrentCapacity[lun]) ErrorMessage (PSTR(">>>>>>>>>>>>>>>>BUGGY FIRMWARE. CAPACITY FAIL ON LUN"), lun); @@ -628,7 +626,6 @@ void UHS_NI UHS_Bulk_Storage::CheckMedia() { /** * For driver use only. - * */ void UHS_NI UHS_Bulk_Storage::Poll() { if((long)(millis() - qNextPollTime) >= 0L) { @@ -759,7 +756,7 @@ uint8_t UHS_NI UHS_Bulk_Storage::Page3F(uint8_t lun) { buf[i] = 0x00; } WriteOk[lun] = true; - uint8_t rc = ModeSense6(lun, 0, 0x3f, 0, 192, buf); + uint8_t rc = ModeSense6(lun, 0, 0x3F, 0, 192, buf); if(!rc) { WriteOk[lun] = ((buf[2] & 0x80) == 0); #ifdef DEBUG_USB_HOST @@ -839,7 +836,6 @@ uint8_t UHS_NI UHS_Bulk_Storage::ClearEpHalt(uint8_t index) { /** * For driver use only. - * */ void UHS_NI UHS_Bulk_Storage::Reset() { if(!bAddress) return; @@ -1185,10 +1181,9 @@ uint8_t UHS_NI UHS_Bulk_Storage::HandleSCSIError(uint8_t status) { //////////////////////////////////////////////////////////////////////////////// /** - * * @param ep_ptr */ -void UHS_NI UHS_Bulk_Storage::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR * ep_ptr) { +void UHS_NI UHS_Bulk_Storage::PrintEndpointDescriptor(const USB_FD_ENDPOINT_DESCRIPTOR * ep_ptr) { Notify(PSTR("Endpoint descriptor:"), 0x80); Notify(PSTR("\r\nLength:\t\t"), 0x80); D_PrintHex (ep_ptr->bLength, 0x80); diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_SCSI.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_SCSI.h index 1050d70c74e2..bead520bf2e3 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_SCSI.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_SCSI.h @@ -20,7 +20,7 @@ Contact information ------------------- Circuits At Home, LTD -Web : http://www.circuitsathome.com +Web : https://www.circuitsathome.com e-mail : support@circuitsathome.com */ @@ -28,7 +28,7 @@ e-mail : support@circuitsathome.com #define UHS_SCSI_H /* - * Reference documents from T10 (http://www.t10.org) + * Reference documents from T10 (https://www.t10.org) * SCSI Primary Commands - 3 (SPC-3) * SCSI Block Commands - 2 (SBC-2) * Multi-Media Commands - 5 (MMC-5) @@ -146,7 +146,7 @@ struct SCSI_CDB6 { public: SCSI_CDB6(uint8_t _Opcode, uint8_t _LUN, uint32_t LBA, uint8_t _AllocationLength, uint8_t _Control) : - Opcode(_Opcode), LBAMSB(UHS_UINT8_BYTE2(LBA) & 0x1f), LUN(_LUN), LBAHB(UHS_UINT8_BYTE1(LBA)), LBALB(UHS_UINT8_BYTE0(LBA)), + Opcode(_Opcode), LBAMSB(UHS_UINT8_BYTE2(LBA) & 0x1F), LUN(_LUN), LBAHB(UHS_UINT8_BYTE1(LBA)), LBALB(UHS_UINT8_BYTE0(LBA)), AllocationLength(_AllocationLength), Control(_Control) { } diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_UNOFFICIAL_IDs.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_UNOFFICIAL_IDs.h index 5c60f2d1839a..6442bcc4b713 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_UNOFFICIAL_IDs.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_UNOFFICIAL_IDs.h @@ -20,7 +20,7 @@ Contact information ------------------- Circuits At Home, LTD -Web : http://www.circuitsathome.com +Web : https://www.circuitsathome.com e-mail : support@circuitsathome.com */ #ifndef _UHS_UNOFFICIAL_IDs_h diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_UsbCore.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_UsbCore.h index 190077d17c86..1591f3b74b8a 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_UsbCore.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_UsbCore.h @@ -20,7 +20,7 @@ Contact information ------------------- Circuits At Home, LTD -Web : http://www.circuitsathome.com +Web : https://www.circuitsathome.com e-mail : support@circuitsathome.com */ @@ -189,8 +189,8 @@ e-mail : support@circuitsathome.com #define UHS_USB_HOST_STATE_INITIALIZE 0x10U // Looks like "I"nit // Host SE result codes. -// Common SE results are stored in the low nybble, all interface drivers understand these plus 0x1f. -// Extended SE results are 0x10-0x1e. SE code only understands these internal to the hardware. +// Common SE results are stored in the low nybble, all interface drivers understand these plus 0x1F. +// Extended SE results are 0x10-0x1E. SE code only understands these internal to the hardware. // Values > 0x1F are driver or other internal error conditions. // Return these result codes from your host controller driver to match the error condition // ALL Non-zero values are errors. diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_address.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_address.h index 1c8b79191037..4d9d35bd6da0 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_address.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_address.h @@ -20,7 +20,7 @@ Contact information ------------------- Circuits At Home, LTD -Web : http://www.circuitsathome.com +Web : https://www.circuitsathome.com e-mail : support@circuitsathome.com */ diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_hexdump.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_hexdump.h index bc111f7b616e..945512cfccbb 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_hexdump.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_hexdump.h @@ -20,7 +20,7 @@ Contact information ------------------- Circuits At Home, LTD -Web : http://www.circuitsathome.com +Web : https://www.circuitsathome.com e-mail : support@circuitsathome.com */ #if !defined(_usb_h_) || defined(__HEXDUMP_H__) diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_host.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_host.h index 7f7d18116c9a..5d711c1f7439 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_host.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_host.h @@ -20,7 +20,7 @@ Contact information ------------------- Circuits At Home, LTD -Web : http://www.circuitsathome.com +Web : https://www.circuitsathome.com e-mail : support@circuitsathome.com */ /* USB functions */ diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_host_INLINE.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_host_INLINE.h index 908391a157f1..9c7b5001c090 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_host_INLINE.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_host_INLINE.h @@ -20,7 +20,7 @@ Contact information ------------------- Circuits At Home, LTD -Web : http://www.circuitsathome.com +Web : https://www.circuitsathome.com e-mail : support@circuitsathome.com */ @@ -101,7 +101,6 @@ uint8_t UHS_USB_HOST_BASE::setEpInfoEntry(uint8_t addr, uint8_t iface, uint8_t e * * @param maxep How many endpoints to initialize * @param device pointer to the device driver instance (this) - * */ void UHS_USB_HOST_BASE::DeviceDefaults(uint8_t maxep, UHS_USBInterface *interface) { @@ -206,8 +205,7 @@ uint8_t UHS_USB_HOST_BASE::doSoftReset(uint8_t parent, uint8_t port, uint8_t add * will not enumerate without it. For devices that do not * need it, the additional reset is harmless. Here is an * example of one of these documents, see page Five: - * http://www.ftdichip.com/Support/Documents/TechnicalNotes/TN_113_Simplified%20Description%20of%20USB%20Device%20Enumeration.pdf - * + * https://www.ftdichip.com/Support/Documents/TechnicalNotes/TN_113_Simplified%20Description%20of%20USB%20Device%20Enumeration.pdf * */ @@ -239,12 +237,12 @@ uint8_t UHS_USB_HOST_BASE::Configuring(uint8_t parent, uint8_t port, uint8_t spe // wrap in {} to throw away the 64 byte buffer when we are done with it { uint8_t buf[biggest]; - USB_DEVICE_DESCRIPTOR *udd = reinterpret_cast(buf); + USB_FD_DEVICE_DESCRIPTOR *udd = reinterpret_cast(buf); #else const uint8_t biggest = 18; uint8_t buf[biggest]; - USB_DEVICE_DESCRIPTOR *udd = reinterpret_cast(buf); - USB_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast(buf); + USB_FD_DEVICE_DESCRIPTOR *udd = reinterpret_cast(buf); + USB_FD_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast(buf); #endif //for(devConfigIndex = 0; devConfigIndex < UHS_HOST_MAX_INTERFACE_DRIVERS; devConfigIndex++) { @@ -309,7 +307,7 @@ uint8_t UHS_USB_HOST_BASE::Configuring(uint8_t parent, uint8_t port, uint8_t spe sof_delay(200); goto again; } - HOST_DEBUG("Configuring error: 0x%2.2x Can't get USB_DEVICE_DESCRIPTOR\r\n", rcode); + HOST_DEBUG("Configuring error: 0x%2.2x Can't get USB_FD_DEVICE_DESCRIPTOR\r\n", rcode); return rcode; } @@ -378,7 +376,7 @@ uint8_t UHS_USB_HOST_BASE::Configuring(uint8_t parent, uint8_t port, uint8_t spe } // unwrapped, old large buf now invalid and discarded. uint8_t buf[18]; - USB_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast(buf); + USB_FD_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast(buf); #endif ei.address = addrPool.AllocAddress(parent, IsHub(ei.klass), port); @@ -415,9 +413,9 @@ uint8_t UHS_USB_HOST_BASE::Configuring(uint8_t parent, uint8_t port, uint8_t spe HOST_DEBUG("configs: %i\r\n", configs); for(uint8_t conf = 0; (!rcode) && (conf < configs); conf++) { // read the config descriptor into a buffer. - rcode = getConfDescr(ei.address, sizeof (USB_CONFIGURATION_DESCRIPTOR), conf, buf); + rcode = getConfDescr(ei.address, sizeof (USB_FD_CONFIGURATION_DESCRIPTOR), conf, buf); if(rcode) { - HOST_DEBUG("Configuring error: %2.2x Can't get USB_INTERFACE_DESCRIPTOR\r\n", rcode); + HOST_DEBUG("Configuring error: %2.2x Can't get USB_FD_INTERFACE_DESCRIPTOR\r\n", rcode); rcode = UHS_HOST_ERROR_FailGetConfDescr; continue; } @@ -438,7 +436,7 @@ uint8_t UHS_USB_HOST_BASE::Configuring(uint8_t parent, uint8_t port, uint8_t spe uint8_t offset; rcode = initDescrStream(&ei, ucd, pep, data, &left, &read, &offset); if(rcode) { - HOST_DEBUG("Configuring error: %2.2x Can't get USB_INTERFACE_DESCRIPTOR stream.\r\n", rcode); + HOST_DEBUG("Configuring error: %2.2x Can't get USB_FD_INTERFACE_DESCRIPTOR stream.\r\n", rcode); break; } for(; (numinf) && (!rcode); inf++) { @@ -451,7 +449,7 @@ uint8_t UHS_USB_HOST_BASE::Configuring(uint8_t parent, uint8_t port, uint8_t spe break; } if(rcode) { - HOST_DEBUG("Configuring error: %2.2x Can't close USB_INTERFACE_DESCRIPTOR stream.\r\n", rcode); + HOST_DEBUG("Configuring error: %2.2x Can't close USB_FD_INTERFACE_DESCRIPTOR stream.\r\n", rcode); continue; } rcode = TestInterface(&ei); @@ -471,9 +469,9 @@ uint8_t UHS_USB_HOST_BASE::Configuring(uint8_t parent, uint8_t port, uint8_t spe if(!bestsuccess) rcode = UHS_HOST_ERROR_DEVICE_NOT_SUPPORTED; } if(!rcode) { - rcode = getConfDescr(ei.address, sizeof (USB_CONFIGURATION_DESCRIPTOR), bestconf, buf); + rcode = getConfDescr(ei.address, sizeof (USB_FD_CONFIGURATION_DESCRIPTOR), bestconf, buf); if(rcode) { - HOST_DEBUG("Configuring error: %2.2x Can't get USB_INTERFACE_DESCRIPTOR\r\n", rcode); + HOST_DEBUG("Configuring error: %2.2x Can't get USB_FD_INTERFACE_DESCRIPTOR\r\n", rcode); rcode = UHS_HOST_ERROR_FailGetConfDescr; } } @@ -497,7 +495,7 @@ uint8_t UHS_USB_HOST_BASE::Configuring(uint8_t parent, uint8_t port, uint8_t spe uint8_t offset; rcode = initDescrStream(&ei, ucd, pep, data, &left, &read, &offset); if(rcode) { - HOST_DEBUG("Configuring error: %2.2x Can't get USB_INTERFACE_DESCRIPTOR stream.\r\n", rcode); + HOST_DEBUG("Configuring error: %2.2x Can't get USB_FD_INTERFACE_DESCRIPTOR stream.\r\n", rcode); } else { for(; (numinf) && (!rcode); inf++) { // iterate for each interface on this config @@ -508,7 +506,7 @@ uint8_t UHS_USB_HOST_BASE::Configuring(uint8_t parent, uint8_t port, uint8_t spe break; } if(rcode) { - HOST_DEBUG("Configuring error: %2.2x Can't close USB_INTERFACE_DESCRIPTOR stream.\r\n", rcode); + HOST_DEBUG("Configuring error: %2.2x Can't close USB_FD_INTERFACE_DESCRIPTOR stream.\r\n", rcode); continue; } @@ -721,7 +719,7 @@ uint8_t UHS_USB_HOST_BASE::inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytes * @param offset * @return zero for success or error code */ -uint8_t UHS_USB_HOST_BASE::initDescrStream(ENUMERATION_INFO *ei, USB_CONFIGURATION_DESCRIPTOR *ucd, UHS_EpInfo *pep, uint8_t *data, uint16_t *left, uint16_t *read, uint8_t *offset) { +uint8_t UHS_USB_HOST_BASE::initDescrStream(ENUMERATION_INFO *ei, USB_FD_CONFIGURATION_DESCRIPTOR *ucd, UHS_EpInfo *pep, uint8_t *data, uint16_t *left, uint16_t *read, uint8_t *offset) { if(!ei || !ucd) return UHS_HOST_ERROR_BAD_ARGUMENT; if(!pep) return UHS_HOST_ERROR_NULL_EPINFO; *left = ucd->wTotalLength; @@ -837,7 +835,7 @@ uint8_t UHS_USB_HOST_BASE::getNextInterface(ENUMERATION_INFO *ei, UHS_EpInfo *pe return rcode; } -uint8_t UHS_USB_HOST_BASE::seekInterface(ENUMERATION_INFO *ei, uint16_t inf, USB_CONFIGURATION_DESCRIPTOR *ucd) { +uint8_t UHS_USB_HOST_BASE::seekInterface(ENUMERATION_INFO *ei, uint16_t inf, USB_FD_CONFIGURATION_DESCRIPTOR *ucd) { if(!ei || !ucd) return UHS_HOST_ERROR_BAD_ARGUMENT; uint8_t data[ei->bMaxPacketSize0]; UHS_EpInfo *pep; @@ -1007,7 +1005,7 @@ uint8_t UHS_USB_HOST_BASE::ctrlReq(uint8_t addr, uint64_t Request, uint16_t nbyt rcode = ctrlReqRead(pep, &left, &read, nbytes, dataptr); #if UHS_DEVICE_WINDOWS_USB_SPEC_VIOLATION_DESCRIPTOR_DEVICE - HOST_DEBUG("RESULT: 0x%2.2x 0x%2.2x 0x%2.2x 0x%8.8lx%8.8lx\r\n", rcode, addr, read, (uint32_t)((Request>>32)&0xfffffffflu), (uint32_t)(Request&0xfffffffflu)); + HOST_DEBUG("RESULT: 0x%2.2x 0x%2.2x 0x%2.2x 0x%8.8lx%8.8lx\r\n", rcode, addr, read, (uint32_t)((Request>>32)&0xFFFFFFFFLU), (uint32_t)(Request&0xFFFFFFFFLU)); // Should only be used for GET_DESCRIPTOR USB_DESCRIPTOR_DEVICE constexpr uint32_t req_match = ((uint32_t)USB_DESCRIPTOR_DEVICE << 24) | ((uint32_t)USB_REQUEST_GET_DESCRIPTOR << 8); diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_macros.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_macros.h index 9c94e4d0ee6d..c5458208d2da 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_macros.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_macros.h @@ -20,7 +20,7 @@ Contact information ------------------- Circuits At Home, LTD -Web : http://www.circuitsathome.com +Web : https://www.circuitsathome.com e-mail : support@circuitsathome.com */ @@ -343,16 +343,16 @@ e-mail : support@circuitsathome.com #define UHS_UINT8_BYTE7(__usi__) (((uint8_t *)&(__usi__))[7]) #else // Note: The cast alone to uint8_t is actually enough. -// GCC throws out the "& 0xff", and the size is no different. +// GCC throws out the "& 0xFF", and the size is no different. // Some compilers need it. -#define UHS_UINT8_BYTE0(__usi__) ((uint8_t)((__usi__) & 0xff )) -#define UHS_UINT8_BYTE1(__usi__) ((uint8_t)(((__usi__) >> 8) & 0xff)) -#define UHS_UINT8_BYTE2(__usi__) ((uint8_t)(((__usi__) >> 16) & 0xff)) -#define UHS_UINT8_BYTE3(__usi__) ((uint8_t)(((__usi__) >> 24) & 0xff)) -#define UHS_UINT8_BYTE4(__usi__) ((uint8_t)(((__usi__) >> 32) & 0xff)) -#define UHS_UINT8_BYTE5(__usi__) ((uint8_t)(((__usi__) >> 40) & 0xff)) -#define UHS_UINT8_BYTE6(__usi__) ((uint8_t)(((__usi__) >> 48) & 0xff)) -#define UHS_UINT8_BYTE7(__usi__) ((uint8_t)(((__usi__) >> 56) & 0xff)) +#define UHS_UINT8_BYTE0(__usi__) ((uint8_t)((__usi__) & 0xFF )) +#define UHS_UINT8_BYTE1(__usi__) ((uint8_t)(((__usi__) >> 8) & 0xFF)) +#define UHS_UINT8_BYTE2(__usi__) ((uint8_t)(((__usi__) >> 16) & 0xFF)) +#define UHS_UINT8_BYTE3(__usi__) ((uint8_t)(((__usi__) >> 24) & 0xFF)) +#define UHS_UINT8_BYTE4(__usi__) ((uint8_t)(((__usi__) >> 32) & 0xFF)) +#define UHS_UINT8_BYTE5(__usi__) ((uint8_t)(((__usi__) >> 40) & 0xFF)) +#define UHS_UINT8_BYTE6(__usi__) ((uint8_t)(((__usi__) >> 48) & 0xFF)) +#define UHS_UINT8_BYTE7(__usi__) ((uint8_t)(((__usi__) >> 56) & 0xFF)) #endif #define UHS_UINT16_SET_BYTE1(__usi__) ((uint16_t)(__usi__) << 8) #define UHS_UINT32_SET_BYTE1(__usi__) ((uint32_t)(__usi__) << 8) diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_message.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_message.h index f5ed3d8b4075..c0cc78d15f97 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_message.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_message.h @@ -20,7 +20,7 @@ Contact information ------------------- Circuits At Home, LTD -Web : http://www.circuitsathome.com +Web : https://www.circuitsathome.com e-mail : support@circuitsathome.com */ #if !defined(_UHS_host_h_) || defined(__MESSAGE_H__) diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_printf_HELPER.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_printf_HELPER.h index 4b8d387d270f..4fc9b94079ab 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_printf_HELPER.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_printf_HELPER.h @@ -20,7 +20,7 @@ Contact information ------------------- Circuits At Home, LTD -Web : http://www.circuitsathome.com +Web : https://www.circuitsathome.com e-mail : support@circuitsathome.com */ diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_printhex.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_printhex.h index 09e336510771..bfa052b8f7e3 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_printhex.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_printhex.h @@ -20,7 +20,7 @@ Contact information ------------------- Circuits At Home, LTD -Web : http://www.circuitsathome.com +Web : https://www.circuitsathome.com e-mail : support@circuitsathome.com */ @@ -36,7 +36,7 @@ void PrintHex(T val, int lvl) { int num_nibbles = sizeof (T) * 2; do { - char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f); + char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0F); if(v > 57) v += 7; E_Notifyc(v, lvl); } while(--num_nibbles); @@ -56,7 +56,7 @@ void SerialPrintHex(T val) { int num_nibbles = sizeof (T) * 2; do { - char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f); + char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0F); if(v > 57) v += 7; USB_HOST_SERIAL.print(v); } while(--num_nibbles); diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_settings.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_settings.h index a401c2851647..c516599d6b3f 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_settings.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_settings.h @@ -20,7 +20,7 @@ Contact information ------------------- Circuits At Home, LTD -Web : http://www.circuitsathome.com +Web : https://www.circuitsathome.com e-mail : support@circuitsathome.com */ @@ -115,7 +115,7 @@ e-mail : support@circuitsathome.com #if GCC_VERSION < 40602 // Test for GCC < 4.6.2 #ifdef PROGMEM #undef PROGMEM -#define PROGMEM __attribute__((section(".progmem.data"))) // Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734#c4 +#define PROGMEM __attribute__((section(".progmem.data"))) // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734#c4 #ifdef PSTR #undef PSTR #define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];})) // Copied from pgmspace.h in avr-libc source diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_usb_ch9.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_usb_ch9.h index 34b8ad72e7ef..6486482d961a 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_usb_ch9.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_usb_ch9.h @@ -20,7 +20,7 @@ Contact information ------------------- Circuits At Home, LTD -Web : http://www.circuitsathome.com +Web : https://www.circuitsathome.com e-mail : support@circuitsathome.com */ @@ -108,12 +108,12 @@ e-mail : support@circuitsathome.com #define USB_DESCRIPTOR_OTHER_SPEED 0x07 // bDescriptorType for a Other Speed Configuration. #define USB_DESCRIPTOR_INTERFACE_POWER 0x08 // bDescriptorType for Interface Power. #define USB_DESCRIPTOR_OTG 0x09 // bDescriptorType for an OTG Descriptor. -#define USB_DESCRIPTOR_DEBUG 0x0a -#define USB_DESCRIPTOR_INTERFACE_ASSOCIATION 0x0b -#define USB_DESCRIPTOR_SECURITY 0x0c -#define USB_DESCRIPTOR_KEY 0x0d -#define USB_DESCRIPTOR_ENCRYPTION_TYPE 0x0e -#define USB_DESCRIPTOR_BOS 0x0f +#define USB_DESCRIPTOR_DEBUG 0x0A +#define USB_DESCRIPTOR_INTERFACE_ASSOCIATION 0x0B +#define USB_DESCRIPTOR_SECURITY 0x0C +#define USB_DESCRIPTOR_KEY 0x0D +#define USB_DESCRIPTOR_ENCRYPTION_TYPE 0x0E +#define USB_DESCRIPTOR_BOS 0x0F #define USB_DESCRIPTOR_DEVICE_CAPABILITY 0x10 #define USB_DESCRIPTOR_WIRELESS_ENDPOINT_COMP 0x11 #define USB_DESCRIPTOR_WIRE_ADAPTER 0x21 @@ -164,7 +164,7 @@ typedef struct { uint8_t iProduct; // Index of String Descriptor describing the product. uint8_t iSerialNumber; // Index of String Descriptor with the device's serial number. uint8_t bNumConfigurations; // Number of possible configurations. -} __attribute__((packed)) USB_DEVICE_DESCRIPTOR; +} __attribute__((packed)) USB_FD_DEVICE_DESCRIPTOR; /* Configuration descriptor structure */ typedef struct { @@ -176,7 +176,7 @@ typedef struct { uint8_t iConfiguration; // Index of String Descriptor describing the configuration. uint8_t bmAttributes; // Configuration characteristics. uint8_t bMaxPower; // Maximum power consumed by this configuration. -} __attribute__((packed)) USB_CONFIGURATION_DESCRIPTOR; +} __attribute__((packed)) USB_FD_CONFIGURATION_DESCRIPTOR; /* Interface descriptor structure */ typedef struct { @@ -189,7 +189,7 @@ typedef struct { uint8_t bInterfaceSubClass; // Subclass code (assigned by the USB-IF). uint8_t bInterfaceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific. uint8_t iInterface; // Index of String Descriptor describing the interface. -} __attribute__((packed)) USB_INTERFACE_DESCRIPTOR; +} __attribute__((packed)) USB_FD_INTERFACE_DESCRIPTOR; /* Endpoint descriptor structure */ typedef struct { @@ -199,7 +199,7 @@ typedef struct { uint8_t bmAttributes; // Endpoint transfer type. uint16_t wMaxPacketSize; // Maximum packet size. uint8_t bInterval; // Polling interval in frames. -} __attribute__((packed)) USB_ENDPOINT_DESCRIPTOR; +} __attribute__((packed)) USB_FD_ENDPOINT_DESCRIPTOR; /* HID descriptor */ /* diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_usbhost.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_usbhost.h index 9a6b110a156b..b289a896efea 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_usbhost.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_usbhost.h @@ -20,7 +20,7 @@ Contact information ------------------- Circuits At Home, LTD -Web : http://www.circuitsathome.com +Web : https://www.circuitsathome.com e-mail : support@circuitsathome.com */ @@ -207,7 +207,7 @@ class UHS_USB_HOST_BASE { interrupts(); } - uint8_t UHS_NI seekInterface(ENUMERATION_INFO *ei, uint16_t inf, USB_CONFIGURATION_DESCRIPTOR *ucd); + uint8_t UHS_NI seekInterface(ENUMERATION_INFO *ei, uint16_t inf, USB_FD_CONFIGURATION_DESCRIPTOR *ucd); uint8_t UHS_NI setEpInfoEntry(uint8_t addr, uint8_t iface, uint8_t epcount, volatile UHS_EpInfo* eprecord_ptr); @@ -261,7 +261,7 @@ class UHS_USB_HOST_BASE { uint8_t TestInterface(ENUMERATION_INFO *ei); uint8_t enumerateInterface(ENUMERATION_INFO *ei); uint8_t getNextInterface(ENUMERATION_INFO *ei, UHS_EpInfo *pep, uint8_t data[], uint16_t *left, uint16_t *read, uint8_t *offset); - uint8_t initDescrStream(ENUMERATION_INFO *ei, USB_CONFIGURATION_DESCRIPTOR *ucd, UHS_EpInfo *pep, uint8_t *data, uint16_t *left, uint16_t *read, uint8_t *offset); + uint8_t initDescrStream(ENUMERATION_INFO *ei, USB_FD_CONFIGURATION_DESCRIPTOR *ucd, UHS_EpInfo *pep, uint8_t *data, uint16_t *left, uint16_t *read, uint8_t *offset); uint8_t outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* data); uint8_t inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t* data); uint8_t doSoftReset(uint8_t parent, uint8_t port, uint8_t address); @@ -350,7 +350,6 @@ class UHS_USBInterface { /** * Executed before anything else in Release(). - * */ virtual void OnRelease() { return; @@ -403,7 +402,6 @@ class UHS_USBInterface { #if 0 /** - * * @return true if this interface is Vendor Specific. */ virtual bool IsVSI() { @@ -414,7 +412,6 @@ class UHS_USBInterface { #if 0 /** - * * Vendor Specific interface class. * This is used by a partner interface. * It can also be used to force-enumerate an interface that diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_util_INLINE.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_util_INLINE.h index 4f53443fb0db..52015b59877a 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_util_INLINE.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_util_INLINE.h @@ -20,7 +20,7 @@ Contact information ------------------- Circuits At Home, LTD -Web : http://www.circuitsathome.com +Web : https://www.circuitsathome.com e-mail : support@circuitsathome.com */ diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/USB_HOST_SHIELD/UHS_max3421e.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/USB_HOST_SHIELD/UHS_max3421e.h index f42a806d7038..8ecafd4ad895 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/USB_HOST_SHIELD/UHS_max3421e.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/USB_HOST_SHIELD/UHS_max3421e.h @@ -13,7 +13,7 @@ Contact information ------------------- Circuits At Home, LTD -Web : http://www.circuitsathome.com +Web : https://www.circuitsathome.com e-mail : support@circuitsathome.com */ #if !defined(USB_HOST_SHIELD_H) || defined(_max3421e_h_) @@ -90,7 +90,7 @@ e-mail : support@circuitsathome.com #define rREVISION 0x90 //18<<3 // (IOPINS1) -#define rIOPINS1 0xa0 //20<<3 +#define rIOPINS1 0xA0 //20<<3 #define bmGPOUT0 0x01 // #define bmGPOUT1 0x02 // #define bmGPOUT2 0x04 // @@ -101,7 +101,7 @@ e-mail : support@circuitsathome.com #define bmGPIN3 0x80 // // (IOPINS2) -#define rIOPINS2 0xa8 //21<<3 +#define rIOPINS2 0xA8 //21<<3 #define bmGPOUT4 0x01 // #define bmGPOUT5 0x02 // #define bmGPOUT6 0x04 // @@ -112,7 +112,7 @@ e-mail : support@circuitsathome.com #define bmGPIN7 0x80 // // (GPINIRQ) -#define rGPINIRQ 0xb0 //22<<3 +#define rGPINIRQ 0xB0 //22<<3 #define bmGPINIRQ0 0x01 // #define bmGPINIRQ1 0x02 // #define bmGPINIRQ2 0x04 // @@ -123,7 +123,7 @@ e-mail : support@circuitsathome.com #define bmGPINIRQ7 0x80 // // (GPINIEN) -#define rGPINIEN 0xb8 //23<<3 +#define rGPINIEN 0xB8 //23<<3 #define bmGPINIEN0 0x01 // #define bmGPINIEN1 0x02 // #define bmGPINIEN2 0x04 // @@ -134,7 +134,7 @@ e-mail : support@circuitsathome.com #define bmGPINIEN7 0x80 // // (GPINPOL) -#define rGPINPOL 0xc0 //24<<3 +#define rGPINPOL 0xC0 //24<<3 #define bmGPINPOL0 0x01 // #define bmGPINPOL1 0x02 // #define bmGPINPOL2 0x04 // @@ -151,7 +151,7 @@ e-mail : support@circuitsathome.com // The CPU should never directly clear the SNDBAVIRQ bit. // Host Interrupt Request Status (HIRQ) -#define rHIRQ 0xc8 // Host Interrupt Request Register +#define rHIRQ 0xC8 // Host Interrupt Request Register #define bmBUSEVENTIRQ 0x01 // BUS Reset Done or BUS Resume Interrupt Request #define bmRWUIRQ 0x02 // Remote Wakeup Interrupt Request #define bmRCVDAVIRQ 0x04 // Receive FIFO Data Available Interrupt Request @@ -165,7 +165,7 @@ e-mail : support@circuitsathome.com #define ICLRALLBITS (bmBUSEVENTIRQ | bmRWUIRQ | bmRCVDAVIRQ | bmSUSDNIRQ | bmCONDETIRQ | bmFRAMEIRQ | bmHXFRDNIRQ) // Host Interrupt Request Control (HIEN) -#define rHIEN 0xd0 // +#define rHIEN 0xD0 // #define bmBUSEVENTIE bmBUSEVENTIRQ // BUS Reset Done or BUS Resume Interrupt Request Enable #define bmRWUIE bmRWUIRQ // Remote Wakeup Interrupt Request Enable #define bmRCVDAVIE bmRCVDAVIRQ // Receive FIFO Data Available Interrupt Request Enable @@ -176,7 +176,7 @@ e-mail : support@circuitsathome.com #define bmHXFRDNIE bmHXFRDNIRQ // Host Transfer Done Interrupt Request Enable // (MODE)) -#define rMODE 0xd8 //27<<3 +#define rMODE 0xD8 //27<<3 #define bmHOST 0x01 // #define bmLOWSPEED 0x02 // #define bmHUBPRE 0x04 // @@ -186,10 +186,10 @@ e-mail : support@circuitsathome.com #define bmDMPULLDN 0x40 // #define bmDPPULLDN 0x80 // -#define rPERADDR 0xe0 //28<<3 +#define rPERADDR 0xE0 //28<<3 // (HCTL) -#define rHCTL 0xe8 //29<<3 +#define rHCTL 0xE8 //29<<3 #define bmBUSRST 0x01 // #define bmFRMRST 0x02 // #define bmSAMPLEBUS 0x04 // @@ -200,7 +200,7 @@ e-mail : support@circuitsathome.com #define bmSNDTOG1 0x80 // // Host transfer (HXFR) -#define rHXFR 0xf0 //30<<3 +#define rHXFR 0xF0 //30<<3 /* Host transfer token values for writing the HXFR register (R30) */ /* OR this bit field with the endpoint number in bits 3:0 */ #define MAX3421E_tokSETUP 0x10 // HS=0, ISO=0, OUTNIN=0, SETUP=1 @@ -212,13 +212,13 @@ e-mail : support@circuitsathome.com #define MAX3421E_tokISOOUT 0x60 // HS=0, ISO=1, OUTNIN=1, SETUP=0 // (HRSL) -#define rHRSL 0xf8 //31<<3 +#define rHRSL 0xF8 //31<<3 #define bmRCVTOGRD 0x10 // #define bmSNDTOGRD 0x20 // #define bmKSTATUS 0x40 // #define bmJSTATUS 0x80 // #define bmSE0 0x00 //SE0 - disconnect state -#define bmSE1 0xc0 //SE1 - illegal state +#define bmSE1 0xC0 //SE1 - illegal state #define MODE_FS_HOST (bmDPPULLDN|bmDMPULLDN|bmHOST|bmSOFKAENAB) #define MODE_LS_HOST (bmDPPULLDN|bmDMPULLDN|bmHOST|bmLOWSPEED|bmSOFKAENAB) diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/USB_HOST_SHIELD/USB_HOST_SHIELD.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/USB_HOST_SHIELD/USB_HOST_SHIELD.h index f0cdae2b6bab..56d6400979f9 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/USB_HOST_SHIELD/USB_HOST_SHIELD.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/USB_HOST_SHIELD/USB_HOST_SHIELD.h @@ -13,7 +13,7 @@ Contact information ------------------- Circuits At Home, LTD -Web : http://www.circuitsathome.com +Web : https://www.circuitsathome.com e-mail : support@circuitsathome.com */ diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/USB_HOST_SHIELD/USB_HOST_SHIELD_INLINE.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/USB_HOST_SHIELD/USB_HOST_SHIELD_INLINE.h index ef2dfe013782..f7dd315a0490 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/USB_HOST_SHIELD/USB_HOST_SHIELD_INLINE.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/USB_HOST_SHIELD/USB_HOST_SHIELD_INLINE.h @@ -13,7 +13,7 @@ Contact information ------------------- Circuits At Home, LTD -Web : http://www.circuitsathome.com +Web : https://www.circuitsathome.com e-mail : support@circuitsathome.com */ @@ -136,7 +136,7 @@ uint8_t* UHS_NI MAX3421E_HOST::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* dat uint8_t UHS_NI MAX3421E_HOST::gpioRd() { uint8_t gpin = 0; gpin = regRd(rIOPINS2); //pins 4-7 - gpin &= 0xf0; //clean lower nibble + gpin &= 0xF0; //clean lower nibble gpin |= (regRd(rIOPINS1) >> 4); //shift low bits and OR with upper from previous operation. return ( gpin); } @@ -504,7 +504,7 @@ uint8_t UHS_NI MAX3421E_HOST::InTransfer(UHS_EpInfo *pep, uint16_t nak_limit, ui /* the only case when absence of RCVDAVIRQ makes sense is when toggle error occurred. Need to add handling for that */ if((regRd(rHIRQ) & bmRCVDAVIRQ) == 0) { //MAX_HOST_DEBUG(PSTR(">>>>>>>> Problem! NO RCVDAVIRQ!\r\n")); - rcode = 0xf0; //receive error + rcode = 0xF0; //receive error break; } pktsize = regRd(rRCVBC); //number of received bytes @@ -576,7 +576,7 @@ uint8_t UHS_NI MAX3421E_HOST::OutTransfer(UHS_EpInfo *pep, uint16_t nak_limit, u regWr(rHXFR, (MAX3421E_tokOUT | pep->epAddr)); //dispatch packet while(!(regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ - rcode = (regRd(rHRSL) & 0x0f); + rcode = (regRd(rHRSL) & 0x0F); while(rcode && ((long)(millis() - timeout) < 0L)) { switch(rcode) { @@ -606,7 +606,7 @@ uint8_t UHS_NI MAX3421E_HOST::OutTransfer(UHS_EpInfo *pep, uint16_t nak_limit, u regWr(rHXFR, (MAX3421E_tokOUT | pep->epAddr)); //dispatch packet while(!(regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ - rcode = (regRd(rHRSL) & 0x0f); + rcode = (regRd(rHRSL) & 0x0F); SYSTEM_OR_SPECIAL_YIELD(); }//while( rcode && .... bytes_left -= bytes_tosend; @@ -631,7 +631,7 @@ uint8_t UHS_NI MAX3421E_HOST::OutTransfer(UHS_EpInfo *pep, uint16_t nak_limit, u /* If nak_limit == 0, do not count NAKs, exit after timeout */ /* If bus timeout, re-sends up to USB_RETRY_LIMIT times */ -/* return codes 0x00-0x0f are HRSLT( 0x00 being success ), 0xff means timeout */ +/* return codes 0x00-0x0F are HRSLT( 0x00 being success ), 0xFF means timeout */ uint8_t UHS_NI MAX3421E_HOST::dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit) { unsigned long timeout = millis() + UHS_HOST_TRANSFER_MAX_MS; uint8_t tmpdata; @@ -654,7 +654,7 @@ uint8_t UHS_NI MAX3421E_HOST::dispatchPkt(uint8_t token, uint8_t ep, uint16_t na }//while ( millis() < timeout - rcode = (regRd(rHRSL) & 0x0f); //analyze transfer result + rcode = (regRd(rHRSL) & 0x0F); //analyze transfer result switch(rcode) { case UHS_HOST_ERROR_NAK: diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/macro_logic.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/macro_logic.h index 114064044d17..0ac90f0df3a6 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/macro_logic.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/macro_logic.h @@ -6,7 +6,6 @@ * * To test: * gcc -DAJK_TEST_MACRO_LOGIC -E macro_logic.h - * */ #ifndef MACRO_LOGIC_H diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/dyn_SWI/SWI_INLINE.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/dyn_SWI/SWI_INLINE.h index 5408a94ade70..f86054cad8a4 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/dyn_SWI/SWI_INLINE.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/dyn_SWI/SWI_INLINE.h @@ -165,7 +165,6 @@ static void Init_dyn_SWI() { } /** - * * @param klass class that extends dyn_SWI * @return 0 on queue full, else returns queue position (ones based) */ @@ -219,7 +218,6 @@ static void Init_dyn_SWI() { } /** - * * @param klass class that extends dyn_SWI * @return 0 on queue full, else returns queue position (ones based) */ diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/dyn_SWI/dyn_SWI.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/dyn_SWI/dyn_SWI.h index 0fdb3ee3db95..07f4ae054dcf 100644 --- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/dyn_SWI/dyn_SWI.h +++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/dyn_SWI/dyn_SWI.h @@ -75,7 +75,7 @@ extern "C" #define NVIC_NUM_INTERRUPTS ((int)PERIPH_COUNT_IRQn) #endif #define VECTORTABLE_SIZE (NVIC_NUM_INTERRUPTS+16) -#define VECTORTABLE_ALIGNMENT (0x100ul) +#define VECTORTABLE_ALIGNMENT (0x100UL) #define NVIC_GET_ACTIVE(n) NVIC_GetActive((IRQn_Type)n) #define NVIC_GET_PENDING(n) NVIC_GetPendingIRQ((IRQn_Type)n) #define NVIC_SET_PENDING(n) NVIC_SetPendingIRQ((IRQn_Type)n) diff --git a/README.md b/README.md index 5ec9452ddb26..1e78528b7a88 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,8 @@ -Additional documentation can be found at the [Marlin Home Page](http://marlinfw.org/). -Please let us know if Marlin misbehaves in any way. Volunteers are standing by! +Additional documentation can be found at the [Marlin Home Page](https://marlinfw.org/). +Please test this firmware and let us know if it misbehaves in any way. Volunteers are standing by! ## Marlin 2.0 @@ -38,11 +38,12 @@ To build Marlin 2.0 you'll need [Arduino IDE 1.8.8 or newer](https://www.arduino [SAMD51P20A](https://www.adafruit.com/product/4064)|ARM® Cortex-M4|Adafruit Grand Central M4 [Teensy 3.5](https://www.pjrc.com/store/teensy35.html)|ARM® Cortex-M4| [Teensy 3.6](https://www.pjrc.com/store/teensy36.html)|ARM® Cortex-M4| + [Teensy 4.0](https://www.pjrc.com/store/teensy40.html)|ARM® Cortex-M7| + [Teensy 4.1](https://www.pjrc.com/store/teensy41.html)|ARM® Cortex-M7| ## Submitting Changes - Submit **Bug Fixes** as Pull Requests to the ([bugfix-2.0.x](https://github.com/MarlinFirmware/Marlin/tree/bugfix-2.0.x)) branch. -- Submit **New Features** to the ([dev-2.1.x](https://github.com/MarlinFirmware/Marlin/tree/dev-2.1.x)) branch. - Follow the [Coding Standards](http://marlinfw.org/docs/development/coding_standards.html) to gain points with the maintainers. - Please submit your questions and concerns to the [Issue Queue](https://github.com/MarlinFirmware/Marlin/issues). @@ -54,7 +55,7 @@ For best results getting help with configuration and troubleshooting, please use - [Marlin Discord](https://discord.gg/n5NJ59y) - Discuss issues with Marlin users and developers - Facebook Group ["Marlin Firmware"](https://www.facebook.com/groups/1049718498464482/) - RepRap.org [Marlin Forum](http://forums.reprap.org/list.php?415) -- [Tom's 3D Forums](https://discuss.toms3d.org/) +- [Tom's 3D Forums](https://forum.toms3d.org/) - Facebook Group ["Marlin Firmware for 3D Printers"](https://www.facebook.com/groups/3Dtechtalk/) - [Marlin Configuration](https://www.youtube.com/results?search_query=marlin+configuration) on YouTube @@ -62,12 +63,11 @@ For best results getting help with configuration and troubleshooting, please use The current Marlin dev team consists of: - - Scott Lahteine [[@thinkyhead](https://github.com/thinkyhead)] - USA   [Donate](http://www.thinkyhead.com/donate-to-marlin) / Flattr: [![Flattr Scott](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=thinkyhead&url=https://github.com/MarlinFirmware/Marlin&title=Marlin&language=&tags=github&category=software) + - Scott Lahteine [[@thinkyhead](https://github.com/thinkyhead)] - USA   [Donate](http://www.thinkyhead.com/donate-to-marlin) - Roxanne Neufeld [[@Roxy-3D](https://github.com/Roxy-3D)] - USA - Chris Pepper [[@p3p](https://github.com/p3p)] - UK - Bob Kuhn [[@Bob-the-Kuhn](https://github.com/Bob-the-Kuhn)] - USA - - João Brazio [[@jbrazio](https://github.com/jbrazio)] - Portugal - - Erik van der Zalm [[@ErikZalm](https://github.com/ErikZalm)] - Netherlands   [![Flattr Erik](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=ErikZalm&url=https://github.com/MarlinFirmware/Marlin&title=Marlin&language=&tags=github&category=software) + - Erik van der Zalm [[@ErikZalm](https://github.com/ErikZalm)] - Netherlands   [![Flattr Erik](https://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=ErikZalm&url=https://github.com/MarlinFirmware/Marlin&title=Marlin&language=&tags=github&category=software) ## License diff --git a/buildroot/bin/.gitattributes b/buildroot/bin/.gitattributes new file mode 100644 index 000000000000..6313b56c5784 --- /dev/null +++ b/buildroot/bin/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/buildroot/bin/format_code b/buildroot/bin/format_code new file mode 100755 index 000000000000..8ae04b1b6e8a --- /dev/null +++ b/buildroot/bin/format_code @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# +# format_code [dir/file...] +# + +HERE=`dirname $0` + +while [[ $# -gt 0 ]]; do + + val="$1" + + if [ -d "$val" ]; then + + find $val -name *.cpp -exec "$HERE/uncrust" '{}' \; + + elif [ -d "./Marlin/src/$val" ]; then + + find "./Marlin/src/$val" -name *.cpp -exec "$HERE/uncrust" '{}' \; + + elif [ -f "./Marlin/src/$val" ]; then + + uncrust "./Marlin/src/$val" + + elif [ -f "$val" ]; then + + uncrust "$val" + + fi + +done diff --git a/buildroot/bin/generate_version b/buildroot/bin/generate_version index 70efe824a7c3..b88e3de918b7 100755 --- a/buildroot/bin/generate_version +++ b/buildroot/bin/generate_version @@ -63,7 +63,7 @@ cat > "${DIR}/Version.h" <. + * along with this program. If not, see . * */ #pragma once diff --git a/buildroot/bin/opt_add b/buildroot/bin/opt_add index 2c1eb3000822..2306ebdaa1b8 100755 --- a/buildroot/bin/opt_add +++ b/buildroot/bin/opt_add @@ -1,3 +1,3 @@ #!/usr/bin/env bash -eval "echo '#define ${@}' >>Marlin/Configuration_adv.h" +eval "echo '#define ${@}' | cat - Marlin/Configuration.h > temp && mv temp Marlin/Configuration.h" diff --git a/buildroot/bin/opt_set b/buildroot/bin/opt_set index f23a1d3d0764..a646e09ae789 100755 --- a/buildroot/bin/opt_set +++ b/buildroot/bin/opt_set @@ -6,7 +6,7 @@ set -e SED=$(which gsed || which sed) # Logic for returning nonzero based on answer here: https://stackoverflow.com/a/15966279/104648 -eval "${SED} -i '/\(\/\/\)*\([[:blank:]]*\)\(#define \b${1}\b\).*$/{s//\2\3 ${2}/;h};\${x;/./{x;q0};x;q9}' Marlin/Configuration.h" || -eval "${SED} -i '/\(\/\/\)*\([[:blank:]]*\)\(#define \b${1}\b\).*$/{s//\2\3 ${2}/;h};\${x;/./{x;q0};x;q9}' Marlin/Configuration_adv.h" || +eval "${SED} -i '/\(\/\/\)*\([[:blank:]]*\)\(#define\s\+\b${1}\b\).*$/{s//\2\3 ${2}/;h};\${x;/./{x;q0};x;q9}' Marlin/Configuration.h" || +eval "${SED} -i '/\(\/\/\)*\([[:blank:]]*\)\(#define\s\+\b${1}\b\).*$/{s//\2\3 ${2}/;h};\${x;/./{x;q0};x;q9}' Marlin/Configuration_adv.h" || eval "echo '#define ${@}' >>Marlin/Configuration_adv.h" || (echo "ERROR: opt_set Can't set or add ${1}" >&2 && exit 9) diff --git a/buildroot/bin/uncrust b/buildroot/bin/uncrust new file mode 100755 index 000000000000..9893b5c380e6 --- /dev/null +++ b/buildroot/bin/uncrust @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +# +# Run uncrustify for a file in-place +# + +TMPDIR=`mktemp -d` + +# Reformat a single file to tmp/ +uncrustify -l CPP -c ./buildroot/share/extras/uncrustify.cfg -f "$1" >$TMPDIR/uncrustify.out + +# Replace the original file +cp "$TMPDIR/uncrustify.out" "$1" + +# Clean up, deliberately +rm "$TMPDIR/uncrustify.out" +rmdir "$TMPDIR" diff --git a/buildroot/bin/use_example_configs b/buildroot/bin/use_example_configs index 4510f689f2b0..83c0f5485d2c 100755 --- a/buildroot/bin/use_example_configs +++ b/buildroot/bin/use_example_configs @@ -1,15 +1,21 @@ #!/usr/bin/env bash -restore_configs +IFS=: read -r PART1 PART2 <<< "$@" +[ -n "${PART2}" ] && { REPO="$PART1" ; RDIR="${PART2// /%20}" ; } \ + || { REPO=bugfix-2.0.x ; RDIR="${PART1// /%20}" ; } +EXAMPLES="https://raw.githubusercontent.com/MarlinFirmware/Configurations/$REPO/config/examples" + +which curl >/dev/null && TOOL='curl -L -s -S -f -o wgot' +which wget >/dev/null && TOOL='wget -q -O wgot' -EXAMPLES="https://raw.githubusercontent.com/MarlinFirmware/Configurations/bugfix-2.0.x/config/examples" +restore_configs cd Marlin -wget -q "$EXAMPLES/$@/Configuration.h" -O wgot && mv wgot Configuration.h -wget -q "$EXAMPLES/$@/Configuration_adv.h" -O wgot && mv wgot Configuration_adv.h -wget -q "$EXAMPLES/$@/_Bootscreen.h" -O wgot && mv wgot _Bootscreen.h -wget -q "$EXAMPLES/$@/_Statusscreen.h" -O wgot && mv wgot _Statusscreen.h -rm -f wgot +$TOOL "$EXAMPLES/$RDIR/Configuration.h" >/dev/null 2>&1 && mv wgot Configuration.h +$TOOL "$EXAMPLES/$RDIR/Configuration_adv.h" >/dev/null 2>&1 && mv wgot Configuration_adv.h +$TOOL "$EXAMPLES/$RDIR/_Bootscreen.h" >/dev/null 2>&1 && mv wgot _Bootscreen.h +$TOOL "$EXAMPLES/$RDIR/_Statusscreen.h" >/dev/null 2>&1 && mv wgot _Statusscreen.h +rm -f wgot cd - >/dev/null diff --git a/buildroot/etc/udev/rules.d/99-platformio-udev.rules b/buildroot/etc/udev/rules.d/99-platformio-udev.rules index 6daaf922bff5..3c829882d1cd 100644 --- a/buildroot/etc/udev/rules.d/99-platformio-udev.rules +++ b/buildroot/etc/udev/rules.d/99-platformio-udev.rules @@ -4,7 +4,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, @@ -16,7 +16,7 @@ # # INSTALLATION # -# Please visit > http://docs.platformio.org/en/latest/faq.html#platformio-udev-rules +# Please visit > https://docs.platformio.org/en/latest/faq.html#platformio-udev-rules # ##################################################################################### diff --git a/buildroot/share/PlatformIO/boards/BigTree_Btt002.json b/buildroot/share/PlatformIO/boards/BigTree_Btt002.json index 2fbf5ae8ac38..d0d092f1eaba 100644 --- a/buildroot/share/PlatformIO/boards/BigTree_Btt002.json +++ b/buildroot/share/PlatformIO/boards/BigTree_Btt002.json @@ -14,33 +14,33 @@ "0x3748" ] ], - "ldscript": "stm32f407xg.ld", - "mcu": "stm32f407vet6", + "mcu": "stm32f407vgt6", "variant": "BIGTREE_BTT002" }, "debug": { - "jlink_device": "STM32F407VE", + "jlink_device": "STM32F407VG", "openocd_target": "stm32f4x", "svd_path": "STM32F40x.svd" }, "frameworks": [ "arduino" ], - "name": "STM32F407VE (192k RAM. 512k Flash)", + "name": "STM32F407VG (192k RAM. 1024k Flash)", "upload": { "disable_flushing": false, "maximum_ram_size": 131072, - "maximum_size": 524288, + "maximum_size": 1048576, "protocol": "stlink", "protocols": [ "stlink", "dfu", "jlink" ], + "offset_address": "0x8008000", "require_upload_port": true, "use_1200bps_touch": false, "wait_for_upload_port": false }, - "url": "http://www.st.com/en/microcontrollers/stm32f407ve.html", + "url": "https://www.st.com/en/microcontrollers-microprocessors/stm32f407vg.html", "vendor": "Generic" } diff --git a/buildroot/share/PlatformIO/boards/BigTree_GTR_v1.json b/buildroot/share/PlatformIO/boards/BigTree_GTR_v1.json new file mode 100644 index 000000000000..32236301c347 --- /dev/null +++ b/buildroot/share/PlatformIO/boards/BigTree_GTR_v1.json @@ -0,0 +1,46 @@ +{ + "build": { + "core": "stm32", + "cpu": "cortex-m4", + "extra_flags": "-DSTM32F4 -DSTM32F407xx -DSTM32F40_41xxx", + "f_cpu": "168000000L", + "hwids": [ + [ + "0x1EAF", + "0x0003" + ], + [ + "0x0483", + "0x3748" + ] + ], + "mcu": "stm32f407zgt6", + "variant": "BIGTREE_GTR_V1" + }, + "debug": { + "jlink_device": "STM32F407ZG", + "openocd_target": "stm32f4x", + "svd_path": "STM32F40x.svd" + }, + "frameworks": [ + "arduino" + ], + "name": "STM32F407ZG (192k RAM. 1024k Flash)", + "upload": { + "disable_flushing": false, + "maximum_ram_size": 196608, + "maximum_size": 1048576, + "protocol": "stlink", + "protocols": [ + "stlink", + "dfu", + "jlink" + ], + "offset_address": "0x8008000", + "require_upload_port": true, + "use_1200bps_touch": false, + "wait_for_upload_port": false + }, + "url": "https://www.st.com/en/microcontrollers-microprocessors/stm32f407zg.html", + "vendor": "Generic" +} diff --git a/buildroot/share/PlatformIO/boards/BigTree_SKR_Pro.json b/buildroot/share/PlatformIO/boards/BigTree_SKR_Pro.json index a949e00a350d..211ceacdca0b 100644 --- a/buildroot/share/PlatformIO/boards/BigTree_SKR_Pro.json +++ b/buildroot/share/PlatformIO/boards/BigTree_SKR_Pro.json @@ -14,7 +14,6 @@ "0x3748" ] ], - "ldscript": "stm32f407xg.ld", "mcu": "stm32f407zgt6", "variant": "BIGTREE_SKR_PRO_1v1" }, @@ -37,10 +36,11 @@ "dfu", "jlink" ], + "offset_address": "0x8008000", "require_upload_port": true, "use_1200bps_touch": false, "wait_for_upload_port": false }, - "url": "http://www.st.com/en/microcontrollers/stm32f407zg.html", + "url": "https://www.st.com/en/microcontrollers-microprocessors/stm32f407zg.html", "vendor": "Generic" } diff --git a/buildroot/share/PlatformIO/boards/CHITU_F103.json b/buildroot/share/PlatformIO/boards/CHITU_F103.json new file mode 100644 index 000000000000..ecf7bff66c87 --- /dev/null +++ b/buildroot/share/PlatformIO/boards/CHITU_F103.json @@ -0,0 +1,48 @@ +{ + "build": { + "core": "maple", + "cpu": "cortex-m3", + "extra_flags": "-DSTM32F103xE -DSTM32F1", + "f_cpu": "72000000L", + "hwids": [ + [ + "0x1EAF", + "0x0003" + ], + [ + "0x1EAF", + "0x0004" + ] + ], + "mcu": "stm32f103zet6", + "variant": "CHITU_F103", + "ldscript": "chitu_f103.ld" + }, + "debug": { + "jlink_device": "STM32F103ZE", + "openocd_target": "stm32f1x", + "svd_path": "STM32F103xx.svd" + }, + "frameworks": [ + "arduino" + ], + "name": "CHITU STM32F103Z (64k RAM. 512k Flash)", + "upload": { + "disable_flushing": false, + "maximum_ram_size": 60536, + "maximum_size": 480288, + "protocol": "stlink", + "protocols": [ + "jlink", + "stlink", + "blackmagic", + "serial", + "dfu" + ], + "require_upload_port": true, + "use_1200bps_touch": false, + "wait_for_upload_port": false + }, + "url": "https://www.st.com/en/microcontrollers-microprocessors/stm32f103ze.html", + "vendor": "Generic" +} diff --git a/buildroot/share/PlatformIO/boards/FLYF407ZG.json b/buildroot/share/PlatformIO/boards/FLYF407ZG.json index 944dc7a9d8fa..7e585c5057ca 100644 --- a/buildroot/share/PlatformIO/boards/FLYF407ZG.json +++ b/buildroot/share/PlatformIO/boards/FLYF407ZG.json @@ -14,7 +14,6 @@ "0x3748" ] ], - "ldscript": "stm32f407xg.ld", "mcu": "stm32f407zgt6", "variant": "FLY_F407ZG" }, @@ -60,6 +59,6 @@ "use_1200bps_touch": false, "wait_for_upload_port": false }, - "url": "http://www.st.com/en/microcontrollers/stm32f407ZG.html", + "url": "https://www.st.com/en/microcontrollers-microprocessors/stm32f407ZG.html", "vendor": "Generic" } diff --git a/buildroot/share/PlatformIO/boards/LERDGE.json b/buildroot/share/PlatformIO/boards/LERDGE.json new file mode 100644 index 000000000000..011814a13361 --- /dev/null +++ b/buildroot/share/PlatformIO/boards/LERDGE.json @@ -0,0 +1,65 @@ +{ + "build": { + "core": "stm32", + "cpu": "cortex-m4", + "extra_flags": "-DSTM32F407xx", + "f_cpu": "168000000L", + "hwids": [ + [ + "0x1EAF", + "0x0003" + ], + [ + "0x0483", + "0x3748" + ] + ], + "mcu": "stm32f407zgt6", + "variant": "LERDGE", + "ldscript": "LERDGE.ld" + }, + "debug": { + "jlink_device": "STM32F407ZG", + "openocd_target": "stm32f4x", + "svd_path": "STM32F40x.svd", + "tools": { + "stlink": { + "server": { + "arguments": [ + "-f", + "scripts/interface/stlink.cfg", + "-c", + "transport select hla_swd", + "-f", + "scripts/target/stm32f4x.cfg", + "-c", + "reset_config none" + ], + "executable": "bin/openocd", + "package": "tool-openocd" + } + } + } + }, + "frameworks": [ + "arduino", + "stm32cube" + ], + "name": "STM32F407ZGT6(192k RAM. 1024k Flash)", + "upload": { + "disable_flushing": false, + "maximum_ram_size": 196608, + "maximum_size": 1048576, + "protocol": "stlink", + "protocols": [ + "stlink", + "dfu", + "jlink" + ], + "require_upload_port": true, + "use_1200bps_touch": false, + "wait_for_upload_port": false + }, + "url": "https://www.st.com/en/microcontrollers-microprocessors/stm32f407ZG.html", + "vendor": "Generic" +} diff --git a/buildroot/share/PlatformIO/boards/MEEB_3DP.json b/buildroot/share/PlatformIO/boards/MEEB_3DP.json new file mode 100644 index 000000000000..870648b32572 --- /dev/null +++ b/buildroot/share/PlatformIO/boards/MEEB_3DP.json @@ -0,0 +1,53 @@ +{ + "build": { + "core": "maple", + "cpu": "cortex-m3", + "extra_flags": "-DSTM32F103xE -DSTM32F1", + "f_cpu": "72000000L", + "hwids": [ + [ + "0x1EAF", + "0x0003" + ], + [ + "0x1EAF", + "0x0004" + ] + ], + "libopencm3": { + "ldscript": "stm32f103xc.ld" + }, + "mcu": "stm32f103rct6", + "variant": "MEEB_3DP" + }, + "debug": { + "jlink_device": "STM32F103RC", + "openocd_target": "stm32f1x", + "svd_path": "STM32F103xx.svd" + }, + "frameworks": [ + "arduino", + "cmsis", + "libopencm3", + "stm32cube" + ], + "name": "3D Printer control board for MEEB with 512k flash/rs422 bus/tmc2208 drivers", + "upload": { + "disable_flushing": false, + "maximum_ram_size": 49152, + "maximum_size": 524288, + "protocol": "dfu", + "protocols": [ + "jlink", + "stlink", + "blackmagic", + "serial", + "dfu" + ], + "require_upload_port": true, + "use_1200bps_touch": false, + "wait_for_upload_port": false + }, + "url": "https://github.com/ccrobot-online/MEEB_3DP", + "vendor": "CCROBOT-ONLINE" +} diff --git a/buildroot/share/PlatformIO/boards/archim.json b/buildroot/share/PlatformIO/boards/archim.json new file mode 100644 index 000000000000..60035197f2f3 --- /dev/null +++ b/buildroot/share/PlatformIO/boards/archim.json @@ -0,0 +1,59 @@ +{ + "build": { + "core": "arduino", + "cpu": "cortex-m3", + "extra_flags": "-D__SAM3X8E__ -DARDUINO_ARCH_SAM -DARDUINO_SAM_DUE", + "f_cpu": "84000000L", + "hwids": [ + [ + "0x27B1", + "0x0001" + ], + [ + "0x2341", + "0x003E" + ], + [ + "0x2341", + "0x003D" + ] + ], + "ldscript": "linker_scripts/gcc/flash.ld", + "mcu": "at91sam3x8e", + "usb_product": "Archim", + "variant": "archim" + }, + "connectivity": [ + "can" + ], + "debug": { + "jlink_device": "ATSAM3X8E", + "openocd_chipname": "at91sam3X8E", + "openocd_target": "at91sam3XXX", + "svd_path": "ATSAM3X8E.svd" + }, + "frameworks": [ + "arduino", + "simba" + ], + "name": "Archim", + "upload": { + "disable_flushing": true, + "maximum_ram_size": 98304, + "maximum_size": 524288, + "native_usb": true, + "protocol": "sam-ba", + "protocols": [ + "sam-ba", + "jlink", + "blackmagic", + "atmel-ice", + "stlink" + ], + "require_upload_port": true, + "use_1200bps_touch": true, + "wait_for_upload_port": true + }, + "url": "https://ultimachine.com", + "vendor": "UltiMachine" +} diff --git a/buildroot/share/PlatformIO/boards/blackSTM32F407VET6.json b/buildroot/share/PlatformIO/boards/blackSTM32F407VET6.json index c55d7cc80ace..176563408602 100644 --- a/buildroot/share/PlatformIO/boards/blackSTM32F407VET6.json +++ b/buildroot/share/PlatformIO/boards/blackSTM32F407VET6.json @@ -14,7 +14,6 @@ "0x3748" ] ], - "ldscript": "stm32f407xe.ld", "mcu": "stm32f407vet6", "variant": "MARLIN_F407VE" }, @@ -60,6 +59,6 @@ "use_1200bps_touch": false, "wait_for_upload_port": false }, - "url": "http://www.st.com/en/microcontrollers/stm32f407ve.html", + "url": "https://www.st.com/en/microcontrollers-microprocessors/stm32f407ve.html", "vendor": "Generic" } diff --git a/buildroot/share/PlatformIO/boards/malyanM200.json b/buildroot/share/PlatformIO/boards/malyanM200.json index dc0cf51f9eef..4dbf76077404 100644 --- a/buildroot/share/PlatformIO/boards/malyanM200.json +++ b/buildroot/share/PlatformIO/boards/malyanM200.json @@ -11,7 +11,6 @@ "ldscript": "jtagOffset.ld", "mcu": "stm32f103cb", "variant": "malyanM200", - "genericvariant" : "MALYAN_M200_V1", "vec_tab_addr": "0x8002000" }, "debug": { @@ -31,6 +30,6 @@ "use_1200bps_touch": false, "wait_for_upload_port": false }, - "url": "http://www.st.com/content/st_com/en/products/microcontrollers/stm32-32-bit-arm-cortex-mcus/stm32f1-series/stm32f103/stm32f103cb.html", + "url": "https://www.st.com/content/st_com/en/products/microcontrollers/stm32-32-bit-arm-cortex-mcus/stm32f1-series/stm32f103/stm32f103cb.html", "vendor": "Generic" } diff --git a/buildroot/share/PlatformIO/boards/malyanM200v2.json b/buildroot/share/PlatformIO/boards/malyanM200v2.json index 0d2090a93b24..765a0c0a0006 100644 --- a/buildroot/share/PlatformIO/boards/malyanM200v2.json +++ b/buildroot/share/PlatformIO/boards/malyanM200v2.json @@ -4,7 +4,7 @@ "extra_flags": "-DSTM32F070xB", "f_cpu": "48000000L", "mcu": "stm32f070rbt6", - "genericvariant" : "MALYAN_M200_V2", + "variant": "MALYANMx00_F070CB", "vec_tab_addr": "0x8002000" }, "debug": { diff --git a/buildroot/share/PlatformIO/boards/fysetc_s6.json b/buildroot/share/PlatformIO/boards/marlin_fysetc_s6.json similarity index 94% rename from buildroot/share/PlatformIO/boards/fysetc_s6.json rename to buildroot/share/PlatformIO/boards/marlin_fysetc_s6.json index 489a15b9efe0..286e46ffbd20 100644 --- a/buildroot/share/PlatformIO/boards/fysetc_s6.json +++ b/buildroot/share/PlatformIO/boards/marlin_fysetc_s6.json @@ -4,7 +4,7 @@ "extra_flags": "-DSTM32F446xx", "f_cpu": "180000000L", "mcu": "stm32f446ret6", - "variant": "FYSETC_S6" + "variant": "MARLIN_FYSETC_S6" }, "connectivity": [ "can" @@ -32,4 +32,4 @@ }, "url": "https://www.st.com/en/microcontrollers-microprocessors/stm32f446.html", "vendor": "FYSETC" -} \ No newline at end of file +} diff --git a/buildroot/share/PlatformIO/ldscripts/STM32F103RC_MEEB_3DP.ld b/buildroot/share/PlatformIO/ldscripts/STM32F103RC_MEEB_3DP.ld new file mode 100644 index 000000000000..01609b9b2cea --- /dev/null +++ b/buildroot/share/PlatformIO/ldscripts/STM32F103RC_MEEB_3DP.ld @@ -0,0 +1,14 @@ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K - 40 + rom (rx) : ORIGIN = 0x08002000, LENGTH = 512K - 8K - 4K +} + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/buildroot/share/PlatformIO/ldscripts/chitu_f103.ld b/buildroot/share/PlatformIO/ldscripts/chitu_f103.ld index cc581236369e..0938e8e5e94b 100644 --- a/buildroot/share/PlatformIO/ldscripts/chitu_f103.ld +++ b/buildroot/share/PlatformIO/ldscripts/chitu_f103.ld @@ -1,7 +1,7 @@ MEMORY { - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K - rom (rx) : ORIGIN = 0x08008800, LENGTH = 512K - 32K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 60K + rom (rx) : ORIGIN = 0x08008800, LENGTH = 512K - 34K } /* Provide memory region aliases for common.inc */ diff --git a/buildroot/share/PlatformIO/ldscripts/creality.ld b/buildroot/share/PlatformIO/ldscripts/creality.ld new file mode 100644 index 000000000000..785345543c0c --- /dev/null +++ b/buildroot/share/PlatformIO/ldscripts/creality.ld @@ -0,0 +1,14 @@ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K - 40 + rom (rx) : ORIGIN = 0x08007000, LENGTH = 512K - 28K +} + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/buildroot/share/PlatformIO/ldscripts/fly_mini.ld b/buildroot/share/PlatformIO/ldscripts/fly_mini.ld new file mode 100644 index 000000000000..2404e7cac9bc --- /dev/null +++ b/buildroot/share/PlatformIO/ldscripts/fly_mini.ld @@ -0,0 +1,14 @@ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K - 40 + rom (rx) : ORIGIN = 0x08005000, LENGTH = 256K - 20K - 4K +} + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/buildroot/share/PlatformIO/ldscripts/fysetc_aio_ii.ld b/buildroot/share/PlatformIO/ldscripts/fysetc_stm32f103rc.ld similarity index 88% rename from buildroot/share/PlatformIO/ldscripts/fysetc_aio_ii.ld rename to buildroot/share/PlatformIO/ldscripts/fysetc_stm32f103rc.ld index f279347ee5fa..6777e5918262 100644 --- a/buildroot/share/PlatformIO/ldscripts/fysetc_aio_ii.ld +++ b/buildroot/share/PlatformIO/ldscripts/fysetc_stm32f103rc.ld @@ -5,7 +5,7 @@ MEMORY { ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K - rom (rx) : ORIGIN = 0x08010000, LENGTH = 256K - 40K - 4K + rom (rx) : ORIGIN = 0x08008000, LENGTH = 256K - 32K } /* Provide memory region aliases for common.inc */ diff --git a/buildroot/share/PlatformIO/ldscripts/lerdge.ld b/buildroot/share/PlatformIO/ldscripts/lerdge.ld new file mode 100644 index 000000000000..aa0b1dd9cb36 --- /dev/null +++ b/buildroot/share/PlatformIO/ldscripts/lerdge.ld @@ -0,0 +1,186 @@ +/* +***************************************************************************** +** +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32F407VGTx Device with +** 1024KByte FLASH, 128KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20010000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200;; /* required amount of heap */ +_Min_Stack_Size = 0x400;; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x8000000 + LD_FLASH_OFFSET, LENGTH = LD_MAX_SIZE - LD_FLASH_OFFSET +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = LD_MAX_DATA_SIZE +CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text ALIGN(4): + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata ALIGN(4): + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + _siccmram = LOADADDR(.ccmram); + + /* CCM-RAM section + * + * IMPORTANT NOTE! + * If initialized variables will be placed in this section, + * the startup code needs to be modified to copy the init-values. + */ + .ccmram : + { + . = ALIGN(4); + _sccmram = .; /* create a global symbol at ccmram start */ + *(.ccmram) + *(.ccmram*) + + . = ALIGN(4); + _eccmram = .; /* create a global symbol at ccmram end */ + } >CCMRAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(4); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(4); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/buildroot/share/PlatformIO/ldscripts/mks_robin_e3.ld b/buildroot/share/PlatformIO/ldscripts/mks_robin_e3.ld new file mode 100644 index 000000000000..2404e7cac9bc --- /dev/null +++ b/buildroot/share/PlatformIO/ldscripts/mks_robin_e3.ld @@ -0,0 +1,14 @@ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K - 40 + rom (rx) : ORIGIN = 0x08005000, LENGTH = 256K - 20K - 4K +} + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/buildroot/share/PlatformIO/ldscripts/mks_robin_e3p.ld b/buildroot/share/PlatformIO/ldscripts/mks_robin_e3p.ld new file mode 100644 index 000000000000..d8a138ca2e25 --- /dev/null +++ b/buildroot/share/PlatformIO/ldscripts/mks_robin_e3p.ld @@ -0,0 +1,14 @@ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K - 40 + rom (rx) : ORIGIN = 0x08007000, LENGTH = 512K - 28K - 4K +} + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/buildroot/share/PlatformIO/ldscripts/mks_robin_nano.ld b/buildroot/share/PlatformIO/ldscripts/mks_robin_nano.ld index 785345543c0c..d8a138ca2e25 100755 --- a/buildroot/share/PlatformIO/ldscripts/mks_robin_nano.ld +++ b/buildroot/share/PlatformIO/ldscripts/mks_robin_nano.ld @@ -1,7 +1,7 @@ MEMORY { ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K - 40 - rom (rx) : ORIGIN = 0x08007000, LENGTH = 512K - 28K + rom (rx) : ORIGIN = 0x08007000, LENGTH = 512K - 28K - 4K } /* Provide memory region aliases for common.inc */ diff --git a/buildroot/share/PlatformIO/scripts/STEVAL__F401XX.py b/buildroot/share/PlatformIO/scripts/STEVAL__F401XX.py index e132ff3af65a..580529c9c1a8 100644 --- a/buildroot/share/PlatformIO/scripts/STEVAL__F401XX.py +++ b/buildroot/share/PlatformIO/scripts/STEVAL__F401XX.py @@ -7,5 +7,3 @@ env["LINKFLAGS"][i] = "-Wl,-T" + custom_ld_script elif flag == "-T": env["LINKFLAGS"][i + 1] = custom_ld_script - - diff --git a/buildroot/share/PlatformIO/scripts/STM32F103RC_MEEB_3DP.py b/buildroot/share/PlatformIO/scripts/STM32F103RC_MEEB_3DP.py new file mode 100644 index 000000000000..547d80ace51c --- /dev/null +++ b/buildroot/share/PlatformIO/scripts/STM32F103RC_MEEB_3DP.py @@ -0,0 +1,59 @@ +try: + import configparser +except ImportError: + import ConfigParser as configparser + +import os +Import("env", "projenv") +# access to global build environment +print(env) +# access to project build environment (is used source files in "src" folder) +print(projenv) + +config = configparser.ConfigParser() +config.read("platformio.ini") + +#com_port = config.get("env:STM32F103RC_meeb", "upload_port") +#print('Use the {0:s} to reboot the board to dfu mode.'.format(com_port)) + +# +# Upload actions +# + +def before_upload(source, target, env): + print("before_upload") + # do some actions + # use com_port + # + env.Execute("pwd") + +def after_upload(source, target, env): + print("after_upload") + # do some actions + # + # + env.Execute("pwd") + +print("Current build targets", map(str, BUILD_TARGETS)) + +env.AddPreAction("upload", before_upload) +env.AddPostAction("upload", after_upload) + +flash_size = 0 +vect_tab_addr = 0 + +for define in env['CPPDEFINES']: + if define[0] == "VECT_TAB_ADDR": + vect_tab_addr = define[1] + if define[0] == "STM32_FLASH_SIZE": + flash_size = define[1] + +print('Use the {0:s} address as the marlin app entry point.'.format(vect_tab_addr)) +print('Use the {0:d}KB flash version of stm32f103rct6 chip.'.format(flash_size)) + +custom_ld_script = os.path.abspath("buildroot/share/PlatformIO/ldscripts/STM32F103RC_MEEB_3DP.ld") +for i, flag in enumerate(env["LINKFLAGS"]): + if "-Wl,-T" in flag: + env["LINKFLAGS"][i] = "-Wl,-T" + custom_ld_script + elif flag == "-T": + env["LINKFLAGS"][i + 1] = custom_ld_script diff --git a/buildroot/share/PlatformIO/scripts/STM32F103RC_fysetc.py b/buildroot/share/PlatformIO/scripts/STM32F103RC_fysetc.py index 1aeaa4d700d2..b69f62578bd4 100644 --- a/buildroot/share/PlatformIO/scripts/STM32F103RC_fysetc.py +++ b/buildroot/share/PlatformIO/scripts/STM32F103RC_fysetc.py @@ -1,10 +1,20 @@ +import os from os.path import join from os.path import expandvars -Import("env", "projenv") +Import("env") -# Relocate firmware from 0x08000000 to 0x08002000 -#env['CPPDEFINES'].remove(("VECT_TAB_ADDR", 134217728)) -#env['CPPDEFINES'].append(("VECT_TAB_ADDR", "0x08010000")) +# Relocate firmware from 0x08000000 to 0x08008000 +#for define in env['CPPDEFINES']: +# if define[0] == "VECT_TAB_ADDR": +# env['CPPDEFINES'].remove(define) +#env['CPPDEFINES'].append(("VECT_TAB_ADDR", "0x08008000")) + +#custom_ld_script = os.path.abspath("buildroot/share/PlatformIO/ldscripts/fysetc_stm32f103rc.ld") +#for i, flag in enumerate(env["LINKFLAGS"]): +# if "-Wl,-T" in flag: +# env["LINKFLAGS"][i] = "-Wl,-T" + custom_ld_script +# elif flag == "-T": +# env["LINKFLAGS"][i + 1] = custom_ld_script # Custom HEX from ELF env.AddPostAction( @@ -14,14 +24,6 @@ "\"" + join("$BUILD_DIR","${PROGNAME}.hex") + "\"", # Note: $BUILD_DIR is a full path ]), "Building $TARGET")) -# please keep $SOURCE variable, it will be replaced with a path to firmware - -# Generic -#env.Replace( -# UPLOADER="serial_upload.bat" -# UPLOADCMD="$UPLOADER stm32loader.py $SOURCE" -#) - # In-line command with arguments UPLOAD_TOOL="stm32flash" platform = env.PioPlatform() @@ -30,14 +32,5 @@ env.Replace( UPLOADER=UPLOAD_TOOL, - UPLOADCMD=expandvars(UPLOAD_TOOL + " -v -i rts,-dtr,dtr $UPLOAD_PORT -R -w \"" + join("$BUILD_DIR","${PROGNAME}.hex")+"\"") + UPLOADCMD=expandvars(UPLOAD_TOOL + " -v -i rts,-dtr,dtr -R -b 115200 -g 0x8000000 -w \"" + join("$BUILD_DIR","${PROGNAME}.hex")+"\"" + " $UPLOAD_PORT") ) - -# Python callback -#def on_upload(source, target, env): -# print source, target -# firmware_path = str(source[0]) -# # do something -# env.Execute(".\serial_upload.bat") - -#env.Replace(UPLOADCMD=on_upload) diff --git a/buildroot/share/PlatformIO/scripts/STM32F103RE_SKR_E3_DIP.py b/buildroot/share/PlatformIO/scripts/STM32F103RE_SKR_E3_DIP.py index af4c66cd21e4..ecdd57f594e8 100644 --- a/buildroot/share/PlatformIO/scripts/STM32F103RE_SKR_E3_DIP.py +++ b/buildroot/share/PlatformIO/scripts/STM32F103RE_SKR_E3_DIP.py @@ -1,6 +1,10 @@ import os Import("env") +for define in env['CPPDEFINES']: + if define[0] == "VECT_TAB_ADDR": + env['CPPDEFINES'].remove(define) + # Relocate firmware from 0x08000000 to 0x08007000 env['CPPDEFINES'].append(("VECT_TAB_ADDR", "0x08007000")) diff --git a/buildroot/share/PlatformIO/scripts/STM32F1_create_variant.py b/buildroot/share/PlatformIO/scripts/STM32F1_create_variant.py new file mode 100644 index 000000000000..4849f59ceb03 --- /dev/null +++ b/buildroot/share/PlatformIO/scripts/STM32F1_create_variant.py @@ -0,0 +1,34 @@ +import os,shutil +from SCons.Script import DefaultEnvironment +from platformio import util + +def copytree(src, dst, symlinks=False, ignore=None): + for item in os.listdir(src): + s = os.path.join(src, item) + d = os.path.join(dst, item) + if os.path.isdir(s): + shutil.copytree(s, d, symlinks, ignore) + else: + shutil.copy2(s, d) + +env = DefaultEnvironment() +platform = env.PioPlatform() +board = env.BoardConfig() + +FRAMEWORK_DIR = platform.get_package_dir("framework-arduinoststm32-maple") +assert os.path.isdir(FRAMEWORK_DIR) +assert os.path.isdir("buildroot/share/PlatformIO/variants") + +variant = board.get("build.variant") +variant_dir = os.path.join(FRAMEWORK_DIR, "STM32F1", "variants", variant) + +source_dir = os.path.join("buildroot/share/PlatformIO/variants", variant) +assert os.path.isdir(source_dir) + +if os.path.isdir(variant_dir): + shutil.rmtree(variant_dir) + +if not os.path.isdir(variant_dir): + os.mkdir(variant_dir) + +copytree(source_dir, variant_dir) diff --git a/buildroot/share/PlatformIO/scripts/chitu_crypt.py b/buildroot/share/PlatformIO/scripts/chitu_crypt.py index d706665e907b..aa675878e70e 100644 --- a/buildroot/share/PlatformIO/scripts/chitu_crypt.py +++ b/buildroot/share/PlatformIO/scripts/chitu_crypt.py @@ -1,12 +1,12 @@ +Import("env") import os +import random import struct -Import("env") +import uuid # Relocate firmware from 0x08000000 to 0x08008800 -for define in env['CPPDEFINES']: - if define[0] == "VECT_TAB_ADDR": - env['CPPDEFINES'].remove(define) -env['CPPDEFINES'].append(("VECT_TAB_ADDR", "0x8008800")) +env['CPPDEFINES'].remove(("VECT_TAB_ADDR", "0x8000000")) +env['CPPDEFINES'].append(("VECT_TAB_ADDR", "0x08008800")) custom_ld_script = os.path.abspath("buildroot/share/PlatformIO/ldscripts/chitu_f103.ld") for i, flag in enumerate(env["LINKFLAGS"]): @@ -32,7 +32,7 @@ def xor_block(r0, r1, block_number, block_size, file_key): key_length = 0x18 # This is an initial seed - xor_seed = 0x4bad + xor_seed = 0x4BAD # This is the block counter block_number = xor_seed * block_number @@ -73,9 +73,11 @@ def encrypt_file(input, output_file, file_length): input_file = bytearray(input.read()) block_size = 0x800 key_length = 0x18 - file_key = 0xDAB27F94 - xor_crc = 0xef3d4323; + uid_value = uuid.uuid4() + file_key = int(uid_value.hex[0:8], 16) + + xor_crc = 0xEF3D4323; # the input file is exepcted to be in chunks of 0x800 # so round the size @@ -87,11 +89,11 @@ def encrypt_file(input, output_file, file_length): # encrypt the contents using a known file header key # write the file_key - output_file.write(struct.pack(">I", 0x947FB2DA)) + output_file.write(struct.pack(". + * + */ + +/** + * The purpose of this file is just include Marlin Configuration files, + * to discover which FEATURES are enabled, without any HAL include. + * Used by common-dependencies.py + */ + +#define NUM_SERIAL 1 // Normally provided by HAL/HAL.h + +#include "../../../../Marlin/src/inc/MarlinConfig.h" + +// +// Conditionals only used for [features] +// +#if ENABLED(SR_LCD_3W_NL) + // Feature checks for SR_LCD_3W_NL +#elif EITHER(LCD_I2C_TYPE_MCP23017, LCD_I2C_TYPE_MCP23008) + #define USES_LIQUIDTWI2 +#elif ANY(HAS_MARLINUI_HD44780, LCD_I2C_TYPE_PCF8575, LCD_I2C_TYPE_PCA8574, SR_LCD_2W_NL, LCM1602) + #define USES_LIQUIDCRYSTAL +#endif + +#if SAVED_POSITIONS + #define HAS_SAVED_POSITIONS +#endif + +#if ENABLED(HOST_PROMPT_SUPPORT) && DISABLED(EMERGENCY_PARSER) + #define HAS_GCODE_M876 +#endif + +#if EXTRUDERS + #define HAS_EXTRUDERS +#endif + +#if ENABLED(DUET_SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD) + #define HAS_SMART_EFF_MOD +#endif + +#if HAS_LCD_MENU + #if ENABLED(BACKLASH_GCODE) + #define HAS_MENU_BACKLASH + #endif + #if ENABLED(LEVEL_BED_CORNERS) + #define HAS_MENU_BED_CORNERS + #endif + #if ENABLED(CANCEL_OBJECTS) + #define HAS_MENU_CANCELOBJECT + #endif + #if ENABLED(CUSTOM_USER_MENUS) + #define HAS_MENU_CUSTOM + #endif + #if EITHER(DELTA_CALIBRATION_MENU, DELTA_AUTO_CALIBRATION) + #define HAS_MENU_DELTA_CALIBRATE + #endif + #if EITHER(LED_CONTROL_MENU, CASE_LIGHT_MENU) + #define HAS_MENU_LED + #endif + #if ENABLED(ADVANCED_PAUSE_FEATURE) + #define HAS_MENU_FILAMENT + #endif + #if ENABLED(SDSUPPORT) + #define HAS_MENU_MEDIA + #endif + #if ENABLED(MIXING_EXTRUDER) + #define HAS_MENU_MIXER + #endif + #if ENABLED(POWER_LOSS_RECOVERY) + #define HAS_MENU_JOB_RECOVERY + #endif + #if HAS_POWER_MONITOR + #define HAS_MENU_POWER_MONITOR + #endif + #if HAS_CUTTER + #define HAS_MENU_CUTTER + #endif + #if HAS_TEMPERATURE + #define HAS_MENU_TEMPERATURE + #endif + #if ENABLED(MMU2_MENUS) + #define HAS_MENU_MMU2 + #endif + #if ENABLED(PASSWORD_FEATURE) + #define HAS_MENU_PASSWORD + #endif + #if HAS_TRINAMIC_CONFIG + #define HAS_MENU_TMC + #endif + #if ENABLED(TOUCH_SCREEN_CALIBRATION) + #define HAS_MENU_TOUCH_SCREEN + #endif + #if ENABLED(AUTO_BED_LEVELING_UBL) + #define HAS_MENU_UBL + #endif +#endif diff --git a/buildroot/share/PlatformIO/scripts/common-dependencies.py b/buildroot/share/PlatformIO/scripts/common-dependencies.py new file mode 100644 index 000000000000..4b4bba625874 --- /dev/null +++ b/buildroot/share/PlatformIO/scripts/common-dependencies.py @@ -0,0 +1,287 @@ +# +# common-dependencies.py +# Convenience script to check dependencies and add libs and sources for Marlin Enabled Features +# +import subprocess +import os +import re +try: + import configparser +except ImportError: + import ConfigParser as configparser +try: + # PIO < 4.4 + from platformio.managers.package import PackageManager +except ImportError: + # PIO >= 4.4 + from platformio.package.meta import PackageSpec as PackageManager + +Import("env") + +#print(env.Dump()) + +try: + verbose = int(env.GetProjectOption('custom_verbose')) +except: + verbose = 0 + +def blab(str): + if verbose: + print(str) + +def parse_pkg_uri(spec): + if PackageManager.__name__ == 'PackageSpec': + return PackageManager(spec).name + else: + name, _, _ = PackageManager.parse_pkg_uri(spec) + return name + +FEATURE_CONFIG = {} + +def add_to_feat_cnf(feature, flines): + + try: + feat = FEATURE_CONFIG[feature] + except: + FEATURE_CONFIG[feature] = {} + + feat = FEATURE_CONFIG[feature] + atoms = re.sub(',\\s*', '\n', flines).strip().split('\n') + for dep in atoms: + parts = dep.split('=') + name = parts.pop(0) + rest = '='.join(parts) + if name in ['extra_scripts', 'src_filter', 'lib_ignore']: + feat[name] = rest + else: + feat['lib_deps'] += [dep] + +def load_config(): + config = configparser.ConfigParser() + config.read("platformio.ini") + items = config.items('features') + for key in items: + feature = key[0].upper() + if not feature in FEATURE_CONFIG: + FEATURE_CONFIG[feature] = { 'lib_deps': [] } + add_to_feat_cnf(feature, key[1]) + + # Add options matching custom_marlin.MY_OPTION to the pile + all_opts = env.GetProjectOptions() + for n in all_opts: + mat = re.match(r'custom_marlin\.(.+)', n[0]) + if mat: + try: + val = env.GetProjectOption(n[0]) + except: + val = None + if val: + add_to_feat_cnf(mat.group(1).upper(), val) + +def get_all_known_libs(): + known_libs = [] + for feature in FEATURE_CONFIG: + feat = FEATURE_CONFIG[feature] + if not 'lib_deps' in feat: + continue + for dep in feat['lib_deps']: + name = parse_pkg_uri(dep) + known_libs.append(name) + return known_libs + +def get_all_env_libs(): + env_libs = [] + lib_deps = env.GetProjectOption('lib_deps') + for dep in lib_deps: + name = parse_pkg_uri(dep) + env_libs.append(name) + return env_libs + +def set_env_field(field, value): + proj = env.GetProjectConfig() + proj.set("env:" + env['PIOENV'], field, value) + +# All unused libs should be ignored so that if a library +# exists in .pio/lib_deps it will not break compilation. +def force_ignore_unused_libs(): + env_libs = get_all_env_libs() + known_libs = get_all_known_libs() + diff = (list(set(known_libs) - set(env_libs))) + lib_ignore = env.GetProjectOption('lib_ignore') + diff + if verbose: + print("Ignore libraries:", lib_ignore) + set_env_field('lib_ignore', lib_ignore) + +def apply_features_config(): + load_config() + for feature in FEATURE_CONFIG: + if not env.MarlinFeatureIsEnabled(feature): + continue + + feat = FEATURE_CONFIG[feature] + + if 'lib_deps' in feat and len(feat['lib_deps']): + blab("Adding lib_deps for %s... " % feature) + + # feat to add + deps_to_add = {} + for dep in feat['lib_deps']: + name = parse_pkg_uri(dep) + deps_to_add[name] = dep + + # Does the env already have the dependency? + deps = env.GetProjectOption('lib_deps') + for dep in deps: + name = parse_pkg_uri(dep) + if name in deps_to_add: + del deps_to_add[name] + + # Are there any libraries that should be ignored? + lib_ignore = env.GetProjectOption('lib_ignore') + for dep in deps: + name = parse_pkg_uri(dep) + if name in deps_to_add: + del deps_to_add[name] + + # Is there anything left? + if len(deps_to_add) > 0: + # Only add the missing dependencies + set_env_field('lib_deps', deps + list(deps_to_add.values())) + + if 'extra_scripts' in feat: + blab("Running extra_scripts for %s... " % feature) + env.SConscript(feat['extra_scripts'], exports="env") + + if 'src_filter' in feat: + blab("Adding src_filter for %s... " % feature) + src_filter = ' '.join(env.GetProjectOption('src_filter')) + # first we need to remove the references to the same folder + my_srcs = re.findall( r'[+-](<.*?>)', feat['src_filter']) + cur_srcs = re.findall( r'[+-](<.*?>)', src_filter) + for d in my_srcs: + if d in cur_srcs: + src_filter = re.sub(r'[+-]' + d, '', src_filter) + + src_filter = feat['src_filter'] + ' ' + src_filter + set_env_field('src_filter', [src_filter]) + env.Replace(SRC_FILTER=src_filter) + + if 'lib_ignore' in feat: + blab("Adding lib_ignore for %s... " % feature) + lib_ignore = env.GetProjectOption('lib_ignore') + [feat['lib_ignore']] + set_env_field('lib_ignore', lib_ignore) + +# +# Find a compiler, considering the OS +# +ENV_BUILD_PATH = os.path.join(env.Dictionary('PROJECT_BUILD_DIR'), env['PIOENV']) +GCC_PATH_CACHE = os.path.join(ENV_BUILD_PATH, ".gcc_path") +def search_compiler(): + try: + filepath = env.GetProjectOption('custom_gcc') + blab('Getting compiler from env') + return filepath + except: + pass + + if os.path.exists(GCC_PATH_CACHE): + blab('Getting g++ path from cache') + with open(GCC_PATH_CACHE, 'r') as f: + return f.read() + + # Find the current platform compiler by searching the $PATH + # which will be in a platformio toolchain bin folder + path_regex = re.escape(env['PROJECT_PACKAGES_DIR']) + gcc = "g++" + if env['PLATFORM'] == 'win32': + path_separator = ';' + path_regex += r'.*\\bin' + gcc += ".exe" + else: + path_separator = ':' + path_regex += r'/.+/bin' + + # Search for the compiler + for pathdir in env['ENV']['PATH'].split(path_separator): + if not re.search(path_regex, pathdir, re.IGNORECASE): + continue + for filepath in os.listdir(pathdir): + if not filepath.endswith(gcc): + continue + + # Cache the g++ path to no search always + if os.path.exists(ENV_BUILD_PATH): + blab('Caching g++ for current env') + with open(GCC_PATH_CACHE, 'w+') as f: + f.write(filepath) + + return filepath + + filepath = env.get('CXX') + blab("Couldn't find a compiler! Fallback to %s" % filepath) + return filepath + +# +# Use the compiler to get a list of all enabled features +# +def load_marlin_features(): + if 'MARLIN_FEATURES' in env: + return + + # Process defines + build_flags = env.get('BUILD_FLAGS') + build_flags = env.ParseFlagsExtended(build_flags) + + cxx = search_compiler() + cmd = [cxx] + + # Build flags from board.json + #if 'BOARD' in env: + # cmd += [env.BoardConfig().get("build.extra_flags")] + for s in build_flags['CPPDEFINES']: + if isinstance(s, tuple): + cmd += ['-D' + s[0] + '=' + str(s[1])] + else: + cmd += ['-D' + s] + + cmd += ['-D__MARLIN_DEPS__ -w -dM -E -x c++ buildroot/share/PlatformIO/scripts/common-dependencies.h'] + cmd = ' '.join(cmd) + blab(cmd) + define_list = subprocess.check_output(cmd, shell=True).splitlines() + marlin_features = {} + for define in define_list: + feature = define[8:].strip().decode().split(' ') + feature, definition = feature[0], ' '.join(feature[1:]) + marlin_features[feature] = definition + env['MARLIN_FEATURES'] = marlin_features + +# +# Return True if a matching feature is enabled +# +def MarlinFeatureIsEnabled(env, feature): + load_marlin_features() + r = re.compile('^' + feature + '$') + found = list(filter(r.match, env['MARLIN_FEATURES'])) + + # Defines could still be 'false' or '0', so check + some_on = False + if len(found): + for f in found: + val = env['MARLIN_FEATURES'][f] + if val in [ '', '1', 'true' ]: + some_on = True + elif val in env['MARLIN_FEATURES']: + some_on = env.MarlinFeatureIsEnabled(val) + + return some_on + +# +# Add a method for other PIO scripts to query enabled features +# +env.AddMethod(MarlinFeatureIsEnabled) + +# +# Add dependencies for enabled Marlin features +# +apply_features_config() +force_ignore_unused_libs() diff --git a/buildroot/share/PlatformIO/scripts/copy_marlin_variant_to_framework.py b/buildroot/share/PlatformIO/scripts/copy_marlin_variant_to_framework.py new file mode 100644 index 000000000000..f7d3f0d03ab7 --- /dev/null +++ b/buildroot/share/PlatformIO/scripts/copy_marlin_variant_to_framework.py @@ -0,0 +1,58 @@ +import os,shutil +from SCons.Script import DefaultEnvironment +from platformio import util +try: + # PIO < 4.4 + from platformio.managers.package import PackageManager +except ImportError: + # PIO >= 4.4 + from platformio.package.meta import PackageSpec as PackageManager + +def parse_pkg_uri(spec): + if PackageManager.__name__ == 'PackageSpec': + return PackageManager(spec).name + else: + name, _, _ = PackageManager.parse_pkg_uri(spec) + return name + +def copytree(src, dst, symlinks=False, ignore=None): + for item in os.listdir(src): + s = os.path.join(src, item) + d = os.path.join(dst, item) + if os.path.isdir(s): + shutil.copytree(s, d, symlinks, ignore) + else: + shutil.copy2(s, d) + +env = DefaultEnvironment() +platform = env.PioPlatform() +board = env.BoardConfig() +variant = board.get("build.variant") + +platform_packages = env.GetProjectOption('platform_packages') +# if there's no framework defined, take it from the class name of platform +framewords = { + "Ststm32Platform": "framework-arduinoststm32", + "AtmelavrPlatform": "framework-arduino-avr" +} +if len(platform_packages) == 0: + platform_name = framewords[platform.__class__.__name__] +else: + platform_name = parse_pkg_uri(platform_packages[0]) + +FRAMEWORK_DIR = platform.get_package_dir(platform_name) +assert os.path.isdir(FRAMEWORK_DIR) +assert os.path.isdir("buildroot/share/PlatformIO/variants") + +variant_dir = os.path.join(FRAMEWORK_DIR, "variants", variant) + +source_dir = os.path.join("buildroot/share/PlatformIO/variants", variant) +assert os.path.isdir(source_dir) + +if os.path.isdir(variant_dir): + shutil.rmtree(variant_dir) + +if not os.path.isdir(variant_dir): + os.mkdir(variant_dir) + +copytree(source_dir, variant_dir) diff --git a/buildroot/share/PlatformIO/scripts/creality.py b/buildroot/share/PlatformIO/scripts/creality.py new file mode 100644 index 000000000000..b9d7d7039bb4 --- /dev/null +++ b/buildroot/share/PlatformIO/scripts/creality.py @@ -0,0 +1,17 @@ +import os +Import("env") + +# Relocate firmware from 0x08000000 to 0x08007000 +for define in env['CPPDEFINES']: + if define[0] == "VECT_TAB_ADDR": + env['CPPDEFINES'].remove(define) + +env['CPPDEFINES'].append(("VECT_TAB_ADDR", "0x08007000")) + +custom_ld_script = os.path.abspath("buildroot/share/PlatformIO/ldscripts/creality.ld") + +for i, flag in enumerate(env['LINKFLAGS']): + if "-Wl,-T" in flag: + env['LINKFLAGS'][i] = "-Wl,-T" + custom_ld_script + elif flag == "-T": + env['LINKFLAGS'][i + 1] = custom_ld_script diff --git a/buildroot/share/PlatformIO/scripts/download_mks_assets.py b/buildroot/share/PlatformIO/scripts/download_mks_assets.py new file mode 100644 index 000000000000..ae2ce467e84a --- /dev/null +++ b/buildroot/share/PlatformIO/scripts/download_mks_assets.py @@ -0,0 +1,46 @@ +Import("env") +import os +import requests +import zipfile +import tempfile +import shutil + +url = "https://github.com/makerbase-mks/Mks-Robin-Nano-Marlin2.0-Firmware/archive/master.zip" +zip_path = os.path.join(env.Dictionary("PROJECT_LIBDEPS_DIR"), "mks-assets.zip") +assets_path = os.path.join(env.Dictionary("PROJECT_BUILD_DIR"), env.Dictionary("PIOENV"), "assets") + +def download_mks_assets(): + print("Downloading MKS Assets") + r = requests.get(url, stream=True) + # the user may have a very clean workspace, + # so create the PROJECT_LIBDEPS_DIR directory if not exits + if os.path.exists(env.Dictionary("PROJECT_LIBDEPS_DIR")) == False: + os.mkdir(env.Dictionary("PROJECT_LIBDEPS_DIR")) + with open(zip_path, 'wb') as fd: + for chunk in r.iter_content(chunk_size=128): + fd.write(chunk) + +def copy_mks_assets(): + print("Copying MKS Assets") + output_path = tempfile.mkdtemp() + zip_obj = zipfile.ZipFile(zip_path, 'r') + zip_obj.extractall(output_path) + zip_obj.close() + if os.path.exists(assets_path) == True and os.path.isdir(assets_path) == False: + os.unlink(assets_path) + if os.path.exists(assets_path) == False: + os.mkdir(assets_path) + base_path = '' + for filename in os.listdir(output_path): + base_path = filename + for filename in os.listdir(os.path.join(output_path, base_path, 'Firmware', 'mks_font')): + shutil.copy(os.path.join(output_path, base_path, 'Firmware', 'mks_font', filename), assets_path) + for filename in os.listdir(os.path.join(output_path, base_path, 'Firmware', 'mks_pic')): + shutil.copy(os.path.join(output_path, base_path, 'Firmware', 'mks_pic', filename), assets_path) + shutil.rmtree(output_path, ignore_errors=True) + +if os.path.exists(zip_path) == False: + download_mks_assets() + +if os.path.exists(assets_path) == False: + copy_mks_assets() diff --git a/buildroot/share/PlatformIO/scripts/fly_mini.py b/buildroot/share/PlatformIO/scripts/fly_mini.py new file mode 100644 index 000000000000..34d132958d6a --- /dev/null +++ b/buildroot/share/PlatformIO/scripts/fly_mini.py @@ -0,0 +1,16 @@ +import os +Import("env") + +# Relocate firmware from 0x08000000 to 0x08005000 +for define in env['CPPDEFINES']: + if define[0] == "VECT_TAB_ADDR": + env['CPPDEFINES'].remove(define) +env['CPPDEFINES'].append(("VECT_TAB_ADDR", "0x08005000")) + +custom_ld_script = os.path.abspath("buildroot/share/PlatformIO/ldscripts/fly_mini.ld") +for i, flag in enumerate(env["LINKFLAGS"]): + if "-Wl,-T" in flag: + env["LINKFLAGS"][i] = "-Wl,-T" + custom_ld_script + elif flag == "-T": + env["LINKFLAGS"][i + 1] = custom_ld_script + diff --git a/buildroot/share/PlatformIO/scripts/fysetc_STM32S6.py b/buildroot/share/PlatformIO/scripts/fysetc_STM32S6.py deleted file mode 100644 index be010b10fe33..000000000000 --- a/buildroot/share/PlatformIO/scripts/fysetc_STM32S6.py +++ /dev/null @@ -1,55 +0,0 @@ -from os.path import join -Import("env") - -import os,shutil -from SCons.Script import DefaultEnvironment -from platformio import util - -env = DefaultEnvironment() -platform = env.PioPlatform() -board = env.BoardConfig() - -FRAMEWORK_DIR = platform.get_package_dir("framework-arduinoststm32") -#FRAMEWORK_DIR = platform.get_package_dir("framework-arduinoststm32@3.10500.190327") -CMSIS_DIR = os.path.join(FRAMEWORK_DIR, "CMSIS", "CMSIS") -assert os.path.isdir(FRAMEWORK_DIR) -assert os.path.isdir(CMSIS_DIR) -assert os.path.isdir("buildroot/share/PlatformIO/variants") - -mcu_type = board.get("build.mcu")[:-2] -variant = board.get("build.variant") -series = mcu_type[:7].upper() + "xx" -variant_dir = os.path.join(FRAMEWORK_DIR, "variants", variant) - -source_dir = os.path.join("buildroot/share/PlatformIO/variants", variant) -assert os.path.isdir(source_dir) - -if not os.path.isdir(variant_dir): - os.mkdir(variant_dir) - -for file_name in os.listdir(source_dir): - full_file_name = os.path.join(source_dir, file_name) - if os.path.isfile(full_file_name): - shutil.copy(full_file_name, variant_dir) - -# Relocate firmware from 0x08000000 to 0x08002000 -#env['CPPDEFINES'].remove(("VECT_TAB_ADDR", 134217728)) -#env['CPPDEFINES'].append(("VECT_TAB_ADDR", "0x08010000")) -#env.Replace(LDSCRIPT_PATH="buildroot/share/PlatformIO/ldscripts/fysetc_aio_ii.ld") - -# Custom HEX from ELF -env.AddPostAction( - "$BUILD_DIR/${PROGNAME}.elf", - env.VerboseAction(" ".join([ - "$OBJCOPY", - "-O", - "ihex", - "$BUILD_DIR/${PROGNAME}.elf", - "$BUILD_DIR/${PROGNAME}.hex" - ]), "Building $TARGET")) - -# In-line command with arguments -env.Replace( - UPLOADER=platform.get_package_dir("tool-stm32duino") + '/stm32flash/stm32flash', - UPLOADCMD='"${UPLOADER}" -v -i rts,-dtr,dtr,-rts -R -b 115200 -g 0x8000000 -w "${BUILD_DIR}/${PROGNAME}.hex" ${UPLOAD_PORT}' -) diff --git a/buildroot/share/PlatformIO/scripts/lerdge.py b/buildroot/share/PlatformIO/scripts/lerdge.py new file mode 100644 index 000000000000..fd934a127866 --- /dev/null +++ b/buildroot/share/PlatformIO/scripts/lerdge.py @@ -0,0 +1,46 @@ +import os,sys +Import("env") + +from SCons.Script import DefaultEnvironment +board = DefaultEnvironment().BoardConfig() + +custom_ld_script = os.path.abspath("buildroot/share/PlatformIO/ldscripts/lerdge.ld") +for i, flag in enumerate(env["LINKFLAGS"]): + if "-Wl,-T" in flag: + env["LINKFLAGS"][i] = "-Wl,-T" + custom_ld_script + elif flag == "-T": + env["LINKFLAGS"][i + 1] = custom_ld_script + +def encryptByte(byte): + byte = 0xFF & ((byte << 6) | (byte >> 2)) + i = 0x58 + byte + j = 0x05 + byte + (i >> 8) + byte = (0xF8 & i) | (0x07 & j) + return byte + +def encrypt_file(input, output_file, file_length): + input_file = bytearray(input.read()) + for i in range(len(input_file)): + result = encryptByte(input_file[i]) + input_file[i] = result + + output_file.write(input_file) + return + +# Encrypt ${PROGNAME}.bin and save it as build.firmware +def encrypt(source, target, env): + print("Encrypting to:", board.get("build.firmware")) + firmware = open(target[0].path, "rb") + result = open(target[0].dir.path + "/" + board.get("build.firmware"), "wb") + length = os.path.getsize(target[0].path) + + encrypt_file(firmware, result, length) + + firmware.close() + result.close() + +if 'firmware' in board.get("build").keys(): + env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", encrypt); +else: + print("You need to define output file via board_build.firmware = 'filename' parameter") + exit(1); diff --git a/buildroot/share/PlatformIO/scripts/mks_encrypt.py b/buildroot/share/PlatformIO/scripts/mks_encrypt.py new file mode 100644 index 000000000000..0d53cdfbe934 --- /dev/null +++ b/buildroot/share/PlatformIO/scripts/mks_encrypt.py @@ -0,0 +1,32 @@ +import os,sys +Import("env") + +from SCons.Script import DefaultEnvironment +board = DefaultEnvironment().BoardConfig() + +# Encrypt ${PROGNAME}.bin and save it as build.firmware ('Robin.bin') +def encrypt(source, target, env): + key = [0xA3, 0xBD, 0xAD, 0x0D, 0x41, 0x11, 0xBB, 0x8D, 0xDC, 0x80, 0x2D, 0xD0, 0xD2, 0xC4, 0x9B, 0x1E, 0x26, 0xEB, 0xE3, 0x33, 0x4A, 0x15, 0xE4, 0x0A, 0xB3, 0xB1, 0x3C, 0x93, 0xBB, 0xAF, 0xF7, 0x3E] + + firmware = open(target[0].path, "rb") + robin = open(target[0].dir.path +'/'+ board.get("build.firmware"), "wb") + length = os.path.getsize(target[0].path) + position = 0 + try: + while position < length: + byte = firmware.read(1) + if position >= 320 and position < 31040: + byte = chr(ord(byte) ^ key[position & 31]) + if sys.version_info[0] > 2: + byte = bytes(byte, 'latin1') + robin.write(byte) + position += 1 + finally: + firmware.close() + robin.close() + +if 'firmware' in board.get("build").keys(): + env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", encrypt); +else: + print("You need to define output file via board_build.firmware = 'filename' parameter", file=sys.stderr) + exit(1); diff --git a/buildroot/share/PlatformIO/scripts/mks_robin_e3.py b/buildroot/share/PlatformIO/scripts/mks_robin_e3.py new file mode 100644 index 000000000000..3af623cce0d7 --- /dev/null +++ b/buildroot/share/PlatformIO/scripts/mks_robin_e3.py @@ -0,0 +1,40 @@ +import os +Import("env") + +# Relocate firmware from 0x08000000 to 0x08005000 +for define in env['CPPDEFINES']: + if define[0] == "VECT_TAB_ADDR": + env['CPPDEFINES'].remove(define) +env['CPPDEFINES'].append(("VECT_TAB_ADDR", "0x08005000")) + +custom_ld_script = os.path.abspath("buildroot/share/PlatformIO/ldscripts/mks_robin_e3.ld") +for i, flag in enumerate(env["LINKFLAGS"]): + if "-Wl,-T" in flag: + env["LINKFLAGS"][i] = "-Wl,-T" + custom_ld_script + elif flag == "-T": + env["LINKFLAGS"][i + 1] = custom_ld_script + + +# Encrypt ${PROGNAME}.bin and save it as 'mksLite.bin' +def encrypt(source, target, env): + import sys + + key = [0xA3, 0xBD, 0xAD, 0x0D, 0x41, 0x11, 0xBB, 0x8D, 0xDC, 0x80, 0x2D, 0xD0, 0xD2, 0xC4, 0x9B, 0x1E, 0x26, 0xEB, 0xE3, 0x33, 0x4A, 0x15, 0xE4, 0x0A, 0xB3, 0xB1, 0x3C, 0x93, 0xBB, 0xAF, 0xF7, 0x3E] + + firmware = open(target[0].path, "rb") + robin = open(target[0].dir.path +'/Robin_e3.bin', "wb") + length = os.path.getsize(target[0].path) + position = 0 + try: + while position < length: + byte = firmware.read(1) + if position >= 320 and position < 31040: + byte = chr(ord(byte) ^ key[position & 31]) + if sys.version_info[0] > 2: + byte = bytes(byte, 'latin1') + robin.write(byte) + position += 1 + finally: + firmware.close() + robin.close() +env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", encrypt); diff --git a/buildroot/share/PlatformIO/scripts/mks_robin_e3p.py b/buildroot/share/PlatformIO/scripts/mks_robin_e3p.py new file mode 100644 index 000000000000..2aab14bab788 --- /dev/null +++ b/buildroot/share/PlatformIO/scripts/mks_robin_e3p.py @@ -0,0 +1,40 @@ +import os +Import("env") + +# Relocate firmware from 0x08000000 to 0x08007000 +for define in env['CPPDEFINES']: + if define[0] == "VECT_TAB_ADDR": + env['CPPDEFINES'].remove(define) +env['CPPDEFINES'].append(("VECT_TAB_ADDR", "0x08007000")) + +custom_ld_script = os.path.abspath("buildroot/share/PlatformIO/ldscripts/mks_robin_e3p.ld") +for i, flag in enumerate(env["LINKFLAGS"]): + if "-Wl,-T" in flag: + env["LINKFLAGS"][i] = "-Wl,-T" + custom_ld_script + elif flag == "-T": + env["LINKFLAGS"][i + 1] = custom_ld_script + + +# Encrypt ${PROGNAME}.bin and save it as 'mks_robin_e3p.bin' +def encrypt(source, target, env): + import sys + + key = [0xA3, 0xBD, 0xAD, 0x0D, 0x41, 0x11, 0xBB, 0x8D, 0xDC, 0x80, 0x2D, 0xD0, 0xD2, 0xC4, 0x9B, 0x1E, 0x26, 0xEB, 0xE3, 0x33, 0x4A, 0x15, 0xE4, 0x0A, 0xB3, 0xB1, 0x3C, 0x93, 0xBB, 0xAF, 0xF7, 0x3E] + + firmware = open(target[0].path, "rb") + robin = open(target[0].dir.path +'/Robin_e3p.bin', "wb") + length = os.path.getsize(target[0].path) + position = 0 + try: + while position < length: + byte = firmware.read(1) + if position >= 320 and position < 31040: + byte = chr(ord(byte) ^ key[position & 31]) + if sys.version_info[0] > 2: + byte = bytes(byte, 'latin1') + robin.write(byte) + position += 1 + finally: + firmware.close() + robin.close() +env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", encrypt); diff --git a/buildroot/share/PlatformIO/scripts/mks_robin_nano35.py b/buildroot/share/PlatformIO/scripts/mks_robin_nano35.py new file mode 100644 index 000000000000..0047289adfd0 --- /dev/null +++ b/buildroot/share/PlatformIO/scripts/mks_robin_nano35.py @@ -0,0 +1,40 @@ +import os +Import("env") + +# Relocate firmware from 0x08000000 to 0x08007000 +for define in env['CPPDEFINES']: + if define[0] == "VECT_TAB_ADDR": + env['CPPDEFINES'].remove(define) +env['CPPDEFINES'].append(("VECT_TAB_ADDR", "0x08007000")) + +custom_ld_script = os.path.abspath("buildroot/share/PlatformIO/ldscripts/mks_robin_nano.ld") +for i, flag in enumerate(env["LINKFLAGS"]): + if "-Wl,-T" in flag: + env["LINKFLAGS"][i] = "-Wl,-T" + custom_ld_script + elif flag == "-T": + env["LINKFLAGS"][i + 1] = custom_ld_script + + +# Encrypt ${PROGNAME}.bin and save it as 'Robin_nano35.bin' +def encrypt(source, target, env): + import sys + + key = [0xA3, 0xBD, 0xAD, 0x0D, 0x41, 0x11, 0xBB, 0x8D, 0xDC, 0x80, 0x2D, 0xD0, 0xD2, 0xC4, 0x9B, 0x1E, 0x26, 0xEB, 0xE3, 0x33, 0x4A, 0x15, 0xE4, 0x0A, 0xB3, 0xB1, 0x3C, 0x93, 0xBB, 0xAF, 0xF7, 0x3E] + + firmware = open(target[0].path, "rb") + robin = open(target[0].dir.path +'/Robin_nano35.bin', "wb") + length = os.path.getsize(target[0].path) + position = 0 + try: + while position < length: + byte = firmware.read(1) + if position >= 320 and position < 31040: + byte = chr(ord(byte) ^ key[position & 31]) + if sys.version_info[0] > 2: + byte = bytes(byte, 'latin1') + robin.write(byte) + position += 1 + finally: + firmware.close() + robin.close() +env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", encrypt); diff --git a/buildroot/share/PlatformIO/scripts/random-bin.py b/buildroot/share/PlatformIO/scripts/random-bin.py new file mode 100644 index 000000000000..4d7ca5dc09b7 --- /dev/null +++ b/buildroot/share/PlatformIO/scripts/random-bin.py @@ -0,0 +1,5 @@ +Import("env") + +from datetime import datetime + +env['PROGNAME'] = datetime.now().strftime("firmware-%Y%m%d-%H%M%S") diff --git a/buildroot/share/PlatformIO/scripts/stm32_bootloader.py b/buildroot/share/PlatformIO/scripts/stm32_bootloader.py new file mode 100644 index 000000000000..d517f1c8d1aa --- /dev/null +++ b/buildroot/share/PlatformIO/scripts/stm32_bootloader.py @@ -0,0 +1,30 @@ +import os,sys,shutil +Import("env") + +from SCons.Script import DefaultEnvironment +board = DefaultEnvironment().BoardConfig() + +def noencrypt(source, target, env): + firmware = os.path.join(target[0].dir.path, board.get("build.firmware")) + # do not overwrite encrypted firmware if present + if not os.path.isfile(firmware): + shutil.copy(target[0].path, firmware) + +if 'offset' in board.get("build").keys(): + LD_FLASH_OFFSET = board.get("build.offset") + + for define in env['CPPDEFINES']: + if define[0] == "VECT_TAB_OFFSET": + env['CPPDEFINES'].remove(define) + env['CPPDEFINES'].append(("VECT_TAB_OFFSET", LD_FLASH_OFFSET)) + + maximum_ram_size = board.get("upload.maximum_ram_size") + + for i, flag in enumerate(env["LINKFLAGS"]): + if "-Wl,--defsym=LD_FLASH_OFFSET" in flag: + env["LINKFLAGS"][i] = "-Wl,--defsym=LD_FLASH_OFFSET=" + LD_FLASH_OFFSET + if "-Wl,--defsym=LD_MAX_DATA_SIZE" in flag: + env["LINKFLAGS"][i] = "-Wl,--defsym=LD_MAX_DATA_SIZE=" + str(maximum_ram_size - 40) + + if 'firmware' in board.get("build").keys(): + env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", noencrypt); diff --git a/buildroot/share/PlatformIO/variants/BIGTREE_BTT002/PeripheralPins.c b/buildroot/share/PlatformIO/variants/BIGTREE_BTT002/PeripheralPins.c index 3f639f092c60..cff269db0b90 100644 --- a/buildroot/share/PlatformIO/variants/BIGTREE_BTT002/PeripheralPins.c +++ b/buildroot/share/PlatformIO/variants/BIGTREE_BTT002/PeripheralPins.c @@ -123,12 +123,18 @@ const PinMap PinMap_PWM[] = { {PE_6, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 2, 0)}, // TIM9_CH2 FAN2 {PC_9, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 4, 0)}, // TIM8_CH4 EXTENSION1-4 - //probably unused on SKR-Pro. confirmation needed, please. + /** + * Unused by specifications on BTT002. (PLEASE CONFIRM) + * Uncomment the corresponding line if you want to have HardwarePWM on some pins. + * WARNING: check timers' usage first to avoid conflicts. + * If you don't know what you're doing leave things as they are or you WILL break something (including hardware) + * If you alter this section DO NOT report bugs to Marlin team since they are most likely caused by you. Thank you. + */ //{PA_0, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1 //{PA_0, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 1, 0)}, // TIM5_CH1 - //{PA_1, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 2, 0)}, // TIM2_CH2 is bltouch analog? + //{PA_1, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 2, 0)}, // TIM2_CH2 BLTOUCH is a "servo" //{PA_1, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 2, 0)}, // TIM5_CH2 - //{PA_2, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3 is bltouch analog? + //{PA_2, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3 BLTOUCH is a "servo" //{PA_2, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 3, 0)}, // TIM5_CH3 //{PA_2, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 1, 0)}, // TIM9_CH1 //{PA_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 4, 0)}, // TIM2_CH4 @@ -323,7 +329,7 @@ const PinMap PinMap_USB_OTG_HS[] = { /* {PB_14, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_DM {PB_15, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_DP #else - #error "USB in HS mode isn't supported by the board" + #error "USB in HS mode isn't supported by the board" {PA_3, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D0 {PB_0, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D1 {PB_1, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D2 @@ -334,7 +340,8 @@ const PinMap PinMap_USB_OTG_HS[] = { /* {PC_0, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_STP {PC_2, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_DIR {PC_3, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_NXT - #endif /* USE_USB_HS_IN_FS */ + #endif // USE_USB_HS_IN_FS + */ {NC, NP, 0} }; #endif diff --git a/buildroot/share/PlatformIO/variants/BIGTREE_BTT002/PinNamesVar.h b/buildroot/share/PlatformIO/variants/BIGTREE_BTT002/PinNamesVar.h index 24248859373b..b4bb9d45f8ac 100644 --- a/buildroot/share/PlatformIO/variants/BIGTREE_BTT002/PinNamesVar.h +++ b/buildroot/share/PlatformIO/variants/BIGTREE_BTT002/PinNamesVar.h @@ -25,25 +25,25 @@ #endif /* USB */ #ifdef USBCON - USB_OTG_FS_SOF = PA_8, - USB_OTG_FS_VBUS = PA_9, - USB_OTG_FS_ID = PA_10, - USB_OTG_FS_DM = PA_11, - USB_OTG_FS_DP = PA_12, - USB_OTG_HS_ULPI_D0 = PA_3, - USB_OTG_HS_SOF = PA_4, - USB_OTG_HS_ULPI_CK = PA_5, - USB_OTG_HS_ULPI_D1 = PB_0, - USB_OTG_HS_ULPI_D2 = PB_1, - USB_OTG_HS_ULPI_D7 = PB_5, - USB_OTG_HS_ULPI_D3 = PB_10, - USB_OTG_HS_ULPI_D4 = PB_11, - USB_OTG_HS_ID = PB_12, - USB_OTG_HS_ULPI_D5 = PB_12, - USB_OTG_HS_ULPI_D6 = PB_13, - USB_OTG_HS_VBUS = PB_13, - USB_OTG_HS_DM = PB_14, - USB_OTG_HS_DP = PB_15, + USB_OTG_FS_SOF = PA_8, + USB_OTG_FS_VBUS = PA_9, + USB_OTG_FS_ID = PA_10, + USB_OTG_FS_DM = PA_11, + USB_OTG_FS_DP = PA_12, + USB_OTG_HS_ULPI_D0 = PA_3, + USB_OTG_HS_SOF = PA_4, + USB_OTG_HS_ULPI_CK = PA_5, + USB_OTG_HS_ULPI_D1 = PB_0, + USB_OTG_HS_ULPI_D2 = PB_1, + USB_OTG_HS_ULPI_D7 = PB_5, + USB_OTG_HS_ULPI_D3 = PB_10, + USB_OTG_HS_ULPI_D4 = PB_11, + USB_OTG_HS_ID = PB_12, + USB_OTG_HS_ULPI_D5 = PB_12, + USB_OTG_HS_ULPI_D6 = PB_13, + USB_OTG_HS_VBUS = PB_13, + USB_OTG_HS_DM = PB_14, + USB_OTG_HS_DP = PB_15, USB_OTG_HS_ULPI_STP = PC_0, USB_OTG_HS_ULPI_DIR = PC_2, USB_OTG_HS_ULPI_NXT = PC_3, diff --git a/buildroot/share/PlatformIO/variants/BIGTREE_BTT002/variant.h b/buildroot/share/PlatformIO/variants/BIGTREE_BTT002/variant.h index ca56b5f456ee..ecc319f47ce0 100644 --- a/buildroot/share/PlatformIO/variants/BIGTREE_BTT002/variant.h +++ b/buildroot/share/PlatformIO/variants/BIGTREE_BTT002/variant.h @@ -245,11 +245,9 @@ extern "C" { // Timer Definitions //Do not use timer used by PWM pins when possible. See PinMap_PWM in PeripheralPins.c -#define TIMER_TONE TIM6 -#define TIMER_SERIAL TIM7 - -// Do not use basic timer: OC is required -#define TIMER_SERVO TIM2 //TODO: advanced-control timers don't work +#define TIMER_TONE TIM7 +#define TIMER_SERVO TIM5 +#define TIMER_SERIAL TIM2 // UART Definitions // Define here Serial instance number to map on Serial generic name diff --git a/buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/PeripheralPins.c b/buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/PeripheralPins.c new file mode 100644 index 000000000000..db0a439562a6 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/PeripheralPins.c @@ -0,0 +1,380 @@ +/* + ******************************************************************************* + * Copyright (c) 2019, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + * Automatically generated from STM32F407Z(E-G)Tx.xml + */ +#include +#include + +/* ===== + * Note: Commented lines are alternative possibilities which are not used by default. + * If you change them, you should know what you're doing first. + * ===== + */ + +//*** ADC *** + +#ifdef HAL_ADC_MODULE_ENABLED +const PinMap PinMap_ADC[] = { + {PA_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC1_IN0 E0_DIR + {PA_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC1_IN1 BLTOUCH_2 + {PA_2, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC1_IN2 BLTOUCH_4 + {PA_3, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC1_IN3 E1_EN + {PA_4, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC1_IN4 TF_SS + {PA_5, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC1_IN5 TF_SCLK + {PA_6, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC1_IN6 TF_MISO + {PA_7, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC1_IN7 LED + {PB_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC1_IN8 HEATER2 + {PB_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC1_IN9 HEATER0 + {PC_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC1_IN10 Z_EN + {PC_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC1_IN11 EXP_14 + {PC_2, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC1_IN12 Z_DIR + {PC_3, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC1_IN13 E0_EN + {PC_4, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 14, 0)}, // ADC1_IN14 EXP_8 + {PC_5, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 15, 0)}, // ADC1_IN15 EXP_7 + + #if STM32F4X_PIN_NUM >= 144 //144 pins mcu, 114 gpio, 24 ADC + {PF_3, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC3_IN9 TH_0 + {PF_4, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 14, 0)}, // ADC3_IN14 TH_1 + {PF_5, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 15, 0)}, // ADC3_IN15 TH_2 + {PF_6, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC3_IN4 TH_3 + {PF_7, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC3_IN5 EXP_13 + {PF_8, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC3_IN6 EXP_3 + {PF_9, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC3_IN7 EXP_6 + {PF_10, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC3_IN8 EXP_5 + #endif + {NC, NP, 0} +}; +#endif + +//*** DAC *** + +#ifdef HAL_DAC_MODULE_ENABLED +const PinMap PinMap_DAC[] = { + {PA_4, DAC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // DAC_OUT1 + {PA_5, DAC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // DAC_OUT2 + {NC, NP, 0} +}; +#endif + +//*** I2C *** + +#ifdef HAL_I2C_MODULE_ENABLED +const PinMap PinMap_I2C_SDA[] = { + {PB_7, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)}, + {PB_9, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)}, + {PB_11, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, + {PC_9, I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)}, + #if STM32F4X_PIN_NUM >= 144 // 144 pins mcu, 114 gpio + #if STM32F4X_PIN_NUM >= 176 + {PH_5, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, + {PH_8, I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)}, + #else + {PF_0, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, + #endif + #endif + {NC, NP, 0} +}; +#endif + +#ifdef HAL_I2C_MODULE_ENABLED +const PinMap PinMap_I2C_SCL[] = { + {PA_8, I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)}, + {PB_6, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)}, + {PB_8, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)}, + {PB_10, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, + #if STM32F4X_PIN_NUM >= 144 // 144 pins mcu, 114 gpio + #if STM32F4X_PIN_NUM >= 176 + //{PF_1, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, + {PH_4, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, + {PH_7, I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)}, + #else + {PF_1, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, + #endif + #endif + {NC, NP, 0} +}; +#endif + +//*** PWM *** + +#ifdef HAL_TIM_MODULE_ENABLED +const PinMap PinMap_PWM[] = { + + // Some pins can perform PWM from more than one timer. These were selected to utilize as many channels as + // possible from timers which were already dedicated to PWM output. + // TIM1 = [FAN4, FAN5, HEATER6, FAN7] + // TIM2 = [, HEATER1, BED, ] + // TIM3 = [, , HEATER2, HEATER0] + // TIM4 = [HEATER5, HEATER4, , HEATER3] + // TIM8 = [FAN3, HEATER7, FAN2, FAN6] + // TIM9 = [FAN0, FAN1, , ] + + {PB_1, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 4, 0)}, // TIM3_CH4 HEATER0 + {PA_1, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 2, 0)}, // TIM2_CH2 HEATER1 + {PB_0, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 3, 0)}, // TIM3_CH3 HEATER2 + {PD_15, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 4, 0)}, // TIM4_CH4 HEATER3 + {PD_13, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 2, 0)}, // TIM4_CH2 HEATER4 + {PD_12, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 1, 0)}, // TIM4_CH1 HEATER5 + {PE_13, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 0)}, // TIM1_CH3 HEATER6 + {PI_6, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 2, 0)}, // TIM8_CH2 HEATER7 + {PA_2, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3 BED + + {PE_5, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 1, 0)}, // TIM9_CH1 FAN0 + {PE_6, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 2, 0)}, // TIM9_CH2 FAN1 + {PC_8, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 3, 0)}, // TIM8_CH3 FAN2 + {PI_5, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 1, 0)}, // TIM8_CH1 FAN3 + {PE_9, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 0)}, // TIM1_CH1 FAN4 + {PE_11, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 0)}, // TIM1_CH2 FAN5 + {PC_9, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 4, 0)}, // TIM8_CH4 FAN6 + {PE_14, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 4, 0)}, // TIM1_CH4 FAN7 + + + // Alternate timer assignments for pins commonly using PWM + //{PB_1, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 1)}, // TIM1_CH3N HEATER0 + //{PB_1, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 3, 1)}, // TIM8_CH3N HEATER0 + //{PA_1, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 2, 0)}, // TIM5_CH2 HEATER1 + //{PB_0, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 1)}, // TIM1_CH2N HEATER2 + //{PB_0, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 2, 1)}, // TIM8_CH2N HEATER2 + //{PA_2, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 3, 0)}, // TIM5_CH3 BED + //{PA_2, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 1, 0)}, // TIM9_CH1 BED + //{PC_8, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 3, 0)}, // TIM3_CH3 FAN2 + //{PC_9, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 4, 0)}, // TIM3_CH4 FAN6 + + // Pins with an available timer channel, on a timer already allocated for PWM. + // These can be freely used for purposes requiring PWM, without creating new timer conflicts. + // This pins are very likely already used for other purposes and enabling PWM on them won't be useful. + {PB_11, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 4, 0)}, // TIM2_CH4 BLTouch / Probe Output + {PC_6, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 1, 0)}, // TIM3_CH1 ESP8266 connector. Available if 8266 isn't used + {PC_7, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 2, 0)}, // TIM3_CH2 ESP8266 connector. Available if 8266 isn't used + + /* + * Pins not utilizing hardware PWM on the GTR. + * Uncomment the corresponding line if you want to have HardwarePWM on some pins. + * WARNING: check timers' usage first to avoid conflicts. + * If you don't know what you're doing leave things as they are or you WILL break something (including hardware) + */ + //{PA_0, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1 + //{PA_0, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 1, 0)}, // TIM5_CH1 + //{PA_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 4, 0)}, // TIM2_CH4 + //{PA_3, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 4, 0)}, // TIM5_CH4 + //{PA_3, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 2, 0)}, // TIM9_CH2 + //{PA_5, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1 + //{PA_5, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 1, 1)}, // TIM8_CH1N + //{PA_6, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 1, 0)}, // TIM3_CH1 + //{PA_6, TIM13, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM13, 1, 0)}, // TIM13_CH1 + //{PA_7, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 1)}, // TIM1_CH1N + //{PA_7, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 2, 0)}, // TIM3_CH2 + //{PA_7, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 1, 1)}, // TIM8_CH1N + //{PA_7, TIM14, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM14, 1, 0)}, // TIM14_CH1 + //{PA_8, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 0)}, // TIM1_CH1 + //{PA_9, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 0)}, // TIM1_CH2 + //{PA_10, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 0)}, // TIM1_CH3 + //{PA_11, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 4, 0)}, // TIM1_CH4 + //{PA_15, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1 + //{PB_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 2, 0)}, // TIM2_CH2 + //{PB_4, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 1, 0)}, // TIM3_CH1 + //{PB_5, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 2, 0)}, // TIM3_CH2 + //{PB_6, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 1, 0)}, // TIM4_CH1 + //{PB_7, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 2, 0)}, // TIM4_CH2 + //{PB_8, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 3, 0)}, // TIM4_CH3 + //{PB_8, TIM10, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM10, 1, 0)}, // TIM10_CH1 + //{PB_9, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 4, 0)}, // TIM4_CH4 + //{PB_9, TIM11, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM11, 1, 0)}, // TIM11_CH1 + //{PB_10, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3 + //{PB_13, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 1)}, // TIM1_CH1N + //{PB_14, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 1)}, // TIM1_CH2N + //{PB_14, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 2, 1)}, // TIM8_CH2N + //{PB_14, TIM12, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM12, 1, 0)}, // TIM12_CH1 + //{PB_15, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 1)}, // TIM1_CH3N + //{PB_15, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 3, 1)}, // TIM8_CH3N + //{PB_15, TIM12, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM12, 2, 0)}, // TIM12_CH2 + //{PC_6, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 1, 0)}, // TIM8_CH1 + //{PC_7, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 2, 0)}, // TIM3_CH2 + //{PC_7, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 2, 0)}, // TIM8_CH2 + //{PD_14, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 3, 0)}, // TIM4_CH3 + //{PE_8, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 1)}, // TIM1_CH1N + //{PE_10, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 1)}, // TIM1_CH2N + //{PE_12, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 1)}, // TIM1_CH3N + //{PF_6, TIM10, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM10, 1, 0)}, // TIM10_CH1 + //{PF_7, TIM11, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM11, 1, 0)}, // TIM11_CH1 + //{PF_8, TIM13, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM13, 1, 0)}, // TIM13_CH1 + //{PF_9, TIM14, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM14, 1, 0)}, // TIM14_CH1 + //{PH_10, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 1, 0)}, // TIM5_CH1 + //{PH_6, TIM12, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM12, 1, 0)}, // TIM12_CH1 + //{PH_11, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 2, 0)}, // TIM5_CH2 + {NC, NP, 0} +}; +#endif + +//*** SERIAL *** + +#ifdef HAL_UART_MODULE_ENABLED +const PinMap PinMap_UART_TX[] = { + {PA_9, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, + {PD_8, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + {PC_6, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, + #if STM32F4X_PIN_NUM >= 144 //144 pins mcu, 114 gpio + //{PG_14, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, + #endif + //{PB_6, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, + //{PA_2, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + //{PD_5, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + //{PB_10, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + //{PC_10, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + //{PA_0, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, + //{PC_10, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, + //{PC_12, UART5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)}, + {NC, NP, 0} +}; + +const PinMap PinMap_UART_RX[] = { + {PA_10, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, + {PD_9, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + {PC_7, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, + //{PA_1, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, + //{PA_3, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + //{PB_7, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, + //{PB_11, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + //{PC_11, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, + //{PC_11, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + //{PD_2, UART5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)}, + //{PD_6, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + #if STM32F4X_PIN_NUM >= 144 //144 pins mcu, 114 gpio + //{PG_9, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, + #endif + {NC, NP, 0} +}; + +const PinMap PinMap_UART_RTS[] = { + //{PA_1, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + //{PA_12, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, + //{PB_14, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + //{PD_4, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + //{PD_12, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + #if STM32F4X_PIN_NUM >= 144 //144 pins mcu, 114 gpio + //{PG_8, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, + //{PG_12, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, + #endif + {NC, NP, 0} +}; + +const PinMap PinMap_UART_CTS[] = { + //{PA_0, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + //{PA_11, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, + //{PB_13, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + //{PD_3, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + //{PD_11, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + #if STM32F4X_PIN_NUM >= 144 //144 pins mcu, 114 gpio + //{PG_13, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, + //{PG_15, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, + #endif + {NC, NP, 0} +}; +#endif + +//*** SPI *** + +#ifdef HAL_SPI_MODULE_ENABLED +const PinMap PinMap_SPI_MOSI[] = { + //{PB_5, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI1)}, + {PA_7, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI1)}, + {PB_15, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + {PC_12, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + {NC, NP, 0} +}; + +const PinMap PinMap_SPI_MISO[] = { + {PA_6, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI1)}, + {PB_14, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + {PC_11, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + {NC, NP, 0} +}; + +const PinMap PinMap_SPI_SCLK[] = { + {PA_5, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI1)}, + {PB_13, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + {PC_10, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + {NC, NP, 0} +}; + +const PinMap PinMap_SPI_SSEL[] = { + {PA_4, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI1)}, + {PB_12, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + {PA_15, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + {NC, NP, 0} +}; +#endif + +//*** CAN *** + +#ifdef HAL_CAN_MODULE_ENABLED +#error "CAN bus isn't available on this board. Driver should be disabled." +#endif + +//*** ETHERNET *** +#ifdef HAL_ETH_MODULE_ENABLED +#error "Ethernet port isn't available on this board. Driver should be disabled." +#endif + +//*** No QUADSPI *** + +//*** USB *** +#ifdef HAL_PCD_MODULE_ENABLED +const PinMap PinMap_USB_OTG_FS[] = { + //{PA_8, USB_OTG_FS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_FS)}, // USB_OTG_FS_SOF used by LCD + //{PA_9, USB_OTG_FS, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF_NONE)}, // USB_OTG_FS_VBUS available on wifi port, if empty + //{PA_10, USB_OTG_FS, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_PULLUP, GPIO_AF10_OTG_FS)}, // USB_OTG_FS_ID available on UART1_RX if not used + {PA_11, USB_OTG_FS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_FS)}, // USB_OTG_FS_DM + {PA_12, USB_OTG_FS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_FS)}, // USB_OTG_FS_DP + {NC, NP, 0} +}; + +const PinMap PinMap_USB_OTG_HS[] = { /* + #ifdef USE_USB_HS_IN_FS + {PB_12, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_ID + {PB_13, USB_OTG_HS, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF_NONE)}, // USB_OTG_HS_VBUS + {PB_14, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_DM + {PB_15, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_DP + #else + #error "USB in HS mode isn't supported by the board" + {PA_3, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D0 + {PB_0, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D1 + {PB_1, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D2 + {PB_5, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D7 + {PB_10, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D3 + {PB_12, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D5 + {PB_13, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D6 + {PC_0, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_STP + {PC_2, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_DIR + {PC_3, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_NXT + #endif // USE_USB_HS_IN_FS + */ + {NC, NP, 0} +}; +#endif diff --git a/buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/PinNamesVar.h b/buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/PinNamesVar.h new file mode 100644 index 000000000000..b4bb9d45f8ac --- /dev/null +++ b/buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/PinNamesVar.h @@ -0,0 +1,50 @@ +/* SYS_WKUP */ +#ifdef PWR_WAKEUP_PIN1 + SYS_WKUP1 = PA_0, +#endif +#ifdef PWR_WAKEUP_PIN2 + SYS_WKUP2 = NC, +#endif +#ifdef PWR_WAKEUP_PIN3 + SYS_WKUP3 = NC, +#endif +#ifdef PWR_WAKEUP_PIN4 + SYS_WKUP4 = NC, +#endif +#ifdef PWR_WAKEUP_PIN5 + SYS_WKUP5 = NC, +#endif +#ifdef PWR_WAKEUP_PIN6 + SYS_WKUP6 = NC, +#endif +#ifdef PWR_WAKEUP_PIN7 + SYS_WKUP7 = NC, +#endif +#ifdef PWR_WAKEUP_PIN8 + SYS_WKUP8 = NC, +#endif +/* USB */ +#ifdef USBCON + USB_OTG_FS_SOF = PA_8, + USB_OTG_FS_VBUS = PA_9, + USB_OTG_FS_ID = PA_10, + USB_OTG_FS_DM = PA_11, + USB_OTG_FS_DP = PA_12, + USB_OTG_HS_ULPI_D0 = PA_3, + USB_OTG_HS_SOF = PA_4, + USB_OTG_HS_ULPI_CK = PA_5, + USB_OTG_HS_ULPI_D1 = PB_0, + USB_OTG_HS_ULPI_D2 = PB_1, + USB_OTG_HS_ULPI_D7 = PB_5, + USB_OTG_HS_ULPI_D3 = PB_10, + USB_OTG_HS_ULPI_D4 = PB_11, + USB_OTG_HS_ID = PB_12, + USB_OTG_HS_ULPI_D5 = PB_12, + USB_OTG_HS_ULPI_D6 = PB_13, + USB_OTG_HS_VBUS = PB_13, + USB_OTG_HS_DM = PB_14, + USB_OTG_HS_DP = PB_15, + USB_OTG_HS_ULPI_STP = PC_0, + USB_OTG_HS_ULPI_DIR = PC_2, + USB_OTG_HS_ULPI_NXT = PC_3, +#endif diff --git a/buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/hal_conf_extra.h b/buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/hal_conf_extra.h new file mode 100644 index 000000000000..e0e8239aac08 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/hal_conf_extra.h @@ -0,0 +1,52 @@ +#pragma once + +#define HAL_MODULE_ENABLED +#define HAL_ADC_MODULE_ENABLED +#define HAL_CRC_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +//#define HAL_RTC_MODULE_ENABLED Real Time Clock...do we use it? +#define HAL_SPI_MODULE_ENABLED +#define HAL_TIM_MODULE_ENABLED +#define HAL_USART_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED +//#define HAL_UART_MODULE_ENABLED // by default +//#define HAL_PCD_MODULE_ENABLED // Since STM32 v3.10700.191028 this is automatically added if any type of USB is enabled (as in Arduino IDE) + +#undef HAL_SD_MODULE_ENABLED +#undef HAL_DAC_MODULE_ENABLED +#undef HAL_FLASH_MODULE_ENABLED +#undef HAL_CAN_MODULE_ENABLED +#undef HAL_CAN_LEGACY_MODULE_ENABLED +#undef HAL_CEC_MODULE_ENABLED +#undef HAL_CRYP_MODULE_ENABLED +#undef HAL_DCMI_MODULE_ENABLED +#undef HAL_DMA2D_MODULE_ENABLED +#undef HAL_ETH_MODULE_ENABLED +#undef HAL_NAND_MODULE_ENABLED +#undef HAL_NOR_MODULE_ENABLED +#undef HAL_PCCARD_MODULE_ENABLED +#undef HAL_SRAM_MODULE_ENABLED +#undef HAL_SDRAM_MODULE_ENABLED +#undef HAL_HASH_MODULE_ENABLED +#undef HAL_EXTI_MODULE_ENABLED +#undef HAL_SMBUS_MODULE_ENABLED +#undef HAL_I2S_MODULE_ENABLED +#undef HAL_IWDG_MODULE_ENABLED +#undef HAL_LTDC_MODULE_ENABLED +#undef HAL_DSI_MODULE_ENABLED +#undef HAL_QSPI_MODULE_ENABLED +#undef HAL_RNG_MODULE_ENABLED +#undef HAL_SAI_MODULE_ENABLED +#undef HAL_IRDA_MODULE_ENABLED +#undef HAL_SMARTCARD_MODULE_ENABLED +#undef HAL_WWDG_MODULE_ENABLED +#undef HAL_HCD_MODULE_ENABLED +#undef HAL_FMPI2C_MODULE_ENABLED +#undef HAL_SPDIFRX_MODULE_ENABLED +#undef HAL_DFSDM_MODULE_ENABLED +#undef HAL_LPTIM_MODULE_ENABLED +#undef HAL_MMC_MODULE_ENABLED diff --git a/buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/ldscript.ld b/buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/ldscript.ld new file mode 100644 index 000000000000..0c060d175180 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/ldscript.ld @@ -0,0 +1,204 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32F407ZGTx Device with +** 1024KByte FLASH, 128KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +**

© COPYRIGHT(c) 2014 Ac6

+** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** 1. Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** 3. Neither the name of Ac6 nor the names of its contributors +** may be used to endorse or promote products derived from this software +** without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20020000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200;; /* required amount of heap */ +_Min_Stack_Size = 0x400;; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x8008000, LENGTH = 1024K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K +CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text ALIGN(4): + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata ALIGN(4): + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + _siccmram = LOADADDR(.ccmram); + + /* CCM-RAM section + * + * IMPORTANT NOTE! + * If initialized variables will be placed in this section, + * the startup code needs to be modified to copy the init-values. + */ + .ccmram : + { + . = ALIGN(4); + _sccmram = .; /* create a global symbol at ccmram start */ + *(.ccmram) + *(.ccmram*) + + . = ALIGN(4); + _eccmram = .; /* create a global symbol at ccmram end */ + } >CCMRAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(4); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(4); + } >RAM + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/variant.cpp b/buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/variant.cpp new file mode 100644 index 000000000000..1486b21830a1 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/variant.cpp @@ -0,0 +1,260 @@ +/* + ******************************************************************************* + * Copyright (c) 2017, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ + +#include "pins_arduino.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Pin number +// This array allows to wrap Arduino pin number(Dx or x) +// to STM32 PinName (PX_n) +const PinName digitalPin[] = { +#if STM32F4X_PIN_NUM >= 64 //64 pins mcu, 51 gpio + PC_13, //D0 + PC_14, //D1 - OSC32_IN + PC_15, //D2 - OSC32_OUT + PH_0, //D3 - OSC_IN + PH_1, //D4 - OSC_OUT + PB_2, //D5 - BOOT1 + PB_10, //D6 - 1:SPI2_SCK / I2C2_SCL / USART3_TX / TIM2_CH3 + PB_11, //D7 - 1:I2C2_SDA / USART3_RX / TIM2_CH4 + PB_12, //D8 - 1:SPI2_NSS / OTG_HS_ID + PB_13, //D9 - 1:SPI2_SCK 2:OTG_HS_VBUS + PB_14, //D10 - 1:SPI2_MISO / TIM12_CH1 / OTG_HS_DM + PB_15, //D11 - SPI2_MOSI / TIM12_CH2 / OTG_HS_DP + PC_6, //D12 - 1:TIM8_CH1 / SDIO_D6 / USART6_TX / TIM3_CH1 + PC_7, //D13 - 1:TIM8_CH2 / SDIO_D7 / USART6_RX / TIM3_CH2 + PC_8, //D14 - 1:TIM8_CH3 / SDIO_D0 / TIM3_CH3 + PC_9, //D15 - 1:TIM8_CH4 / SDIO_D1 / TIM3_CH4 + PA_8, //D16 - 1:TIM1_CH1 / I2C3_SCL / OTG_FS_SOF + PA_9, //D17 - 1:USART1_TX / TIM1_CH2 2:OTG_FS_VBUS + PA_10, //D18 - 1:USART1_RX / TIM1_CH3 / OTG_FS_ID + PA_11, //D19 - 1:TIM1_CH4 / OTG_FS_DM + PA_12, //D20 - 1:OTG_FS_DP + PA_13, //D21 - 0:JTMS-SWDIO + PA_14, //D22 - 0:JTCK-SWCLK + PA_15, //D23 - 0:JTDI 1:SPI3_NSS / SPI1_NSS + PC_10, //D24 - 1:UART4_TX / SPI3_SCK / SDIO_D2 / USART3_TX + PC_11, //D25 - 1:UART4_RX / SPI3_MISO / SDIO_D3 / USART3_RX + PC_12, //D26 - 1:UART5_TX / SPI3_MOSI / SDIO_CK + PD_2, //D27 - 1:UART5_RX / SDIO_CMD + PB_3, //D28 - 0:JTDO 1:SPI3_SCK / TIM2_CH2 / SPI1_SCK + PB_4, //D29 - 0:NJTRST 1:SPI3_MISO / TIM3_CH1 / SPI1_MISO + PB_5, //D30 - 1:TIM3_CH2 / SPI1_MOSI / SPI3_MOSI + PB_6, //D31 - 1:I2C1_SCL / TIM4_CH1 / USART1_TX + PB_7, //D32 - 1:I2C1_SDA / TIM4_CH2 / USART1_RX + PB_8, //D33 - 1:I2C1_SCL / TIM4_CH3 / SDIO_D4 / TIM10_CH1 + PB_9, //D34 - 1:I2C1_SDA / TIM4_CH4 / SDIO_D5 / TIM11_CH1 / SPI2_NSS + PA_0, //D35/A0 - 1:UART4_TX / TIM5_CH1 2:ADC123_IN0 + PA_1, //D36/A1 - 1:UART4_RX / TIM5_CH2 / TIM2_CH2 2:ADC123_IN1 + PA_2, //D37/A2 - 1:USART2_TX /TIM5_CH3 / TIM9_CH1 / TIM2_CH3 2:ADC123_IN2 + PA_3, //D38/A3 - 1:USART2_RX /TIM5_CH4 / TIM9_CH2 / TIM2_CH4 2:ADC123_IN3 + PA_4, //D39/A4 - NOT FT 1:SPI1_NSS / SPI3_NSS / USART2_CK 2:ADC12_IN4 / DAC_OUT1 + PA_5, //D40/A5 - NOT FT 1:SPI1_SCK 2:ADC12_IN5 / DAC_OUT2 + PA_6, //D41/A6 - 1:SPI1_MISO / TIM13_CH1 / TIM3_CH1 2:ADC12_IN6 + PA_7, //D42/A7 - 1:SPI1_MOSI / TIM14_CH1 / TIM3_CH2 2:ADC12_IN7 + PB_0, //D43/A8 - 1:TIM3_CH3 2:ADC12_IN8 + PB_1, //D44/A9 - 1:TIM3_CH4 2:ADC12_IN9 + PC_0, //D45/A10 - 1: 2:ADC123_IN10 + PC_1, //D46/A11 - 1: 2:ADC123_IN11 + PC_2, //D47/A12 - 1:SPI2_MISO 2:ADC123_IN12 + PC_3, //D48/A13 - 1:SPI2_MOSI 2:ADC123_IN13 + PC_4, //D49/A14 - 1: 2:ADC12_IN14 + PC_5, //D50/A15 - 1: 2:ADC12_IN15 + #if STM32F4X_PIN_NUM >= 144 + PF_3, //D51/A16 - 1:FSMC_A3 2:ADC3_IN9 + PF_4, //D52/A17 - 1:FSMC_A4 2:ADC3_IN14 + PF_5, //D53/A18 - 1:FSMC_A5 2:ADC3_IN15 + PF_6, //D54/A19 - 1:TIM10_CH1 2:ADC3_IN4 + PF_7, //D55/A20 - 1:TIM11_CH1 2:ADC3_IN5 + PF_8, //D56/A21 - 1:TIM13_CH1 2:ADC3_IN6 + PF_9, //D57/A22 - 1;TIM14_CH1 2:ADC3_IN7 + PF_10, //D58/A23 - 2:ADC3_IN8 + #endif +#endif +#if STM32F4X_PIN_NUM >= 100 //100 pins mcu, 82 gpio + PE_2, //D59 - 1:FSMC_A23 + PE_3, //D60 - 1:FSMC_A19 + PE_4, //D61 - 1:FSMC_A20 + PE_5, //D62 - 1:FSMC_A21 + PE_6, //D63 - 1:FSMC_A22 + PE_7, //D64 - 1:FSMC_D4 + PE_8, //D65 - 1:FSMC_D5 + PE_9, //D66 - 1:FSMC_D6 / TIM1_CH1 + PE_10, //D67 - 1:FSMC_D7 + PE_11, //D68 - 1:FSMC_D8 / TIM1_CH2 + PE_12, //D69 - 1:FSMC_D9 + PE_13, //D70 - 1:FSMC_D10 / TIM1_CH3 + PE_14, //D71 - 1:FSMC_D11 / TIM1_CH4 + PE_15, //D72 - 1:FSMC_D12 + PD_8, //D73 - 1:FSMC_D13 / USART3_TX + PD_9, //D74 - 1:FSMC_D14 / USART3_RX + PD_10, //D75 - 1:FSMC_D15 + PD_11, //D76 - 1:FSMC_A16 + PD_12, //D77 - 1:FSMC_A17 / TIM4_CH1 + PD_13, //D78 - 1:FSMC_A18 / TIM4_CH2 + PD_14, //D79 - 1:FSMC_D0 / TIM4_CH3 + PD_15, //D80 - 1:FSMC_D1 / TIM4_CH4 + PD_0, //D81 - 1:FSMC_D2 + PD_1, //D82 - 1:FSMC_D3 + PD_3, //D83 - 1:FSMC_CLK + PD_4, //D84 - 1:FSMC_NOE + PD_5, //D85 - 1:USART2_TX + PD_6, //D86 - 1:USART2_RX + PD_7, //D87 + PE_0, //D88 + PE_1, //D89 +#endif +#if STM32F4X_PIN_NUM >= 144 //144 pins mcu, 114 gpio + PF_0, //D90 - 1:FSMC_A0 / I2C2_SDA + PF_1, //D91 - 1:FSMC_A1 / I2C2_SCL + PF_2, //D92 - 1:FSMC_A2 + PF_11, //D93 + PF_12, //D94 - 1:FSMC_A6 + PF_13, //D95 - 1:FSMC_A7 + PF_14, //D96 - 1:FSMC_A8 + PF_15, //D97 - 1:FSMC_A9 + PG_0, //D98 - 1:FSMC_A10 + PG_1, //D99 - 1:FSMC_A11 + PG_2, //D100 - 1:FSMC_A12 + PG_3, //D101 - 1:FSMC_A13 + PG_4, //D102 - 1:FSMC_A14 + PG_5, //D103 - 1:FSMC_A15 + PG_6, //D104 + PG_7, //D105 + PG_8, //D106 + PG_9, //D107 - 1:USART6_RX + PG_10, //D108 - 1:FSMC_NE3 + PG_11, //D109 + PG_12, //D110 - 1:FSMC_NE4 + PG_13, //D111 - 1:FSMC_A24 + PG_14, //D112 - 1:FSMC_A25 / USART6_TX + PG_15, //D113 +#endif +#if STM32F4X_PIN_NUM >= 176 //176 pins mcu, 140 gpio + PI_8, //D114 + PI_9, //D115 + PI_10, //D116 + PI_11, //D117 + PH_2, //D118 + PH_3, //D119 + PH_4, //D120 - 1:I2C2_SCL + PH_5, //D121 - 1:I2C2_SDA + PH_6, //D122 - 1:TIM12_CH1 + PH_7, //D123 - 1:I2C3_SCL + PH_8, //D124 - 1:I2C3_SDA + PH_9, //D125 - 1:TIM12_CH2 + PH_10, //D126 - 1:TIM5_CH1 + PH_11, //D127 - 1:TIM5_CH2 + PH_12, //D128 - 1:TIM5_CH3 + PH_13, //D129 + PH_14, //D130 + PH_15, //D131 + PI_0, //D132 - 1:TIM5_CH4 / SPI2_NSS + PI_1, //D133 - 1:SPI2_SCK + PI_2, //D134 - 1:TIM8_CH4 /SPI2_MISO + PI_3, //D135 - 1:SPI2_MOS + PI_4, //D136 + PI_5, //D137 - 1:TIM8_CH1 + PI_6, //D138 - 1:TIM8_CH2 + PI_7, //D139 - 1:TIM8_CH3 +#endif +}; + +#ifdef __cplusplus +} +#endif + +// ------------------------ + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * @brief System Clock Configuration + * @param None + * @retval None + */ +WEAK void SystemClock_Config() { + + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_ClkInitTypeDef RCC_ClkInitStruct; + + /**Configure the main internal regulator output voltage + */ + __HAL_RCC_PWR_CLK_ENABLE(); + + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + /**Initializes the CPU, AHB and APB busses clocks + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = 8; + RCC_OscInitStruct.PLL.PLLN = 336; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 7; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { + _Error_Handler(__FILE__, __LINE__); + } + + /**Initializes the CPU, AHB and APB busses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK + | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) { + _Error_Handler(__FILE__, __LINE__); + } + + /**Configure the Systick interrupt time + */ + HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000); + + /**Configure the Systick + */ + HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); + + /* SysTick_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); +} + +#ifdef __cplusplus +} +#endif diff --git a/buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/variant.h b/buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/variant.h new file mode 100644 index 000000000000..2da195c6cff0 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/BIGTREE_GTR_V1/variant.h @@ -0,0 +1,322 @@ +/* + ******************************************************************************* + * Copyright (c) 2017, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +#ifdef STM32F405RX + #define STM32F4X_PIN_NUM 64 //64 pins mcu, 51 gpio + #define STM32F4X_GPIO_NUM 51 + #define STM32F4X_ADC_NUM 16 +#elif defined(STM32F407_5VX) + #define STM32F4X_PIN_NUM 100 //100 pins mcu, 82 gpio + #define STM32F4X_GPIO_NUM 82 + #define STM32F4X_ADC_NUM 16 +#elif defined(STM32F407_5ZX) + #define STM32F4X_PIN_NUM 144 //144 pins mcu, 114 gpio + #define STM32F4X_GPIO_NUM 114 + #define STM32F4X_ADC_NUM 24 +#elif defined(STM32F407IX) + #define STM32F4X_PIN_NUM 176 //176 pins mcu, 140 gpio + #define STM32F4X_GPIO_NUM 140 + #define STM32F4X_ADC_NUM 24 +#else + #error "no match MCU defined" +#endif + +#if STM32F4X_PIN_NUM >= 64 //64 pins mcu, 51 gpio + #define PC13 0 + #define PC14 1 //OSC32_IN + #define PC15 2 //OSC32_OUT + #define PH0 3 //OSC_IN + #define PH1 4 //OSC_OUT + #define PB2 5 //BOOT1 + #define PB10 6 //1:SPI2_SCK / I2C2_SCL / USART3_TX / TIM2_CH3 + #define PB11 7 //1:I2C2_SDA / USART3_RX / TIM2_CH4 + #define PB12 8 //1:SPI2_NSS / OTG_HS_ID + #define PB13 9 //1:SPI2_SCK 2:OTG_HS_VBUS + #define PB14 10 //1:SPI2_MISO / TIM12_CH1 / OTG_HS_DM + #define PB15 11 //SPI2_MOSI / TIM12_CH2 / OTG_HS_DP + #define PC6 12 //1:TIM8_CH1 / SDIO_D6 / USART6_TX / TIM3_CH1 + #define PC7 13 //1:TIM8_CH2 / SDIO_D7 / USART6_RX / TIM3_CH2 + #define PC8 14 //1:TIM8_CH3 / SDIO_D0 / TIM3_CH3 + #define PC9 15 //1:TIM8_CH4 / SDIO_D1 / TIM3_CH4 + #define PA8 16 //1:TIM1_CH1 / I2C3_SCL / OTG_FS_SOF + #define PA9 17 //1:USART1_TX / TIM1_CH2 2:OTG_FS_VBUS + #define PA10 18 //1:USART1_RX / TIM1_CH3 / OTG_FS_ID + #define PA11 19 //1:TIM1_CH4 / OTG_FS_DM + #define PA12 20 //1:OTG_FS_DP + #define PA13 21 //0:JTMS-SWDIO + #define PA14 22 //0:JTCK-SWCLK + #define PA15 23 //0:JTDI 1:SPI3_NSS / SPI1_NSS + #define PC10 24 //1:UART4_TX / SPI3_SCK / SDIO_D2 / USART3_TX + #define PC11 25 //1:UART4_RX / SPI3_MISO / SDIO_D3 / USART3_RX + #define PC12 26 //1:UART5_TX / SPI3_MOSI / SDIO_CK + #define PD2 27 //1:UART5_RX / SDIO_CMD + #define PB3 28 //0:JTDO 1:SPI3_SCK / TIM2_CH2 / SPI1_SCK + #define PB4 29 //0:NJTRST 1:SPI3_MISO / TIM3_CH1 / SPI1_MISO + #define PB5 30 //1:TIM3_CH2 / SPI1_MOSI / SPI3_MOSI + #define PB6 31 //1:I2C1_SCL / TIM4_CH1 / USART1_TX + #define PB7 32 //1:I2C1_SDA / TIM4_CH2 / USART1_RX + #define PB8 33 //1:I2C1_SCL / TIM4_CH3 / SDIO_D4 / TIM10_CH1 + #define PB9 34 //1:I2C1_SDA / TIM4_CH4 / SDIO_D5 / TIM11_CH1 / SPI2_NSS + #define PA0 35 //1:UART4_TX / TIM5_CH1 2:ADC123_IN0 + #define PA1 36 //1:UART4_RX / TIM5_CH2 / TIM2_CH2 2:ADC123_IN1 + #define PA2 37 //1:USART2_TX /TIM5_CH3 / TIM9_CH1 / TIM2_CH3 2:ADC123_IN2 + #define PA3 38 //1:USART2_RX /TIM5_CH4 / TIM9_CH2 / TIM2_CH4 2:ADC123_IN3 + #define PA4 39 //NOT FT 1:SPI1_NSS / SPI3_NSS / USART2_CK 2:ADC12_IN4 / DAC_OUT1 + #define PA5 40 //NOT FT 1:SPI1_SCK 2:ADC12_IN5 / DAC_OUT2 + #define PA6 41 //1:SPI1_MISO / TIM13_CH1 / TIM3_CH1 2:ADC12_IN6 + #define PA7 42 //1:SPI1_MOSI / TIM14_CH1 / TIM3_CH2 2:ADC12_IN7 + #define PB0 43 //1:TIM3_CH3 2:ADC12_IN8 + #define PB1 44 //1:TIM3_CH4 2:ADC12_IN9 + #define PC0 45 //1: 2:ADC123_IN10 + #define PC1 46 //1: 2:ADC123_IN11 + #define PC2 47 //1:SPI2_MISO 2:ADC123_IN12 + #define PC3 48 //1:SPI2_MOSI 2:ADC123_IN13 + #define PC4 49 //1: 2:ADC12_IN14 + #define PC5 50 //1: 2:ADC12_IN15 + #if STM32F4X_PIN_NUM >= 144 + #define PF3 51 //1:FSMC_A3 2:ADC3_IN9 + #define PF4 52 //1:FSMC_A4 2:ADC3_IN14 + #define PF5 53 //1:FSMC_A5 2:ADC3_IN15 + #define PF6 54 //1:TIM10_CH1 2:ADC3_IN4 + #define PF7 55 //1:TIM11_CH1 2:ADC3_IN5 + #define PF8 56 //1:TIM13_CH1 2:ADC3_IN6 + #define PF9 57 //1;TIM14_CH1 2:ADC3_IN7 + #define PF10 58 //2:ADC3_IN8 + #endif +#endif +#if STM32F4X_PIN_NUM >= 100 //100 pins mcu, 82 gpio + #define PE2 (35+STM32F4X_ADC_NUM) //1:FSMC_A23 + #define PE3 (36+STM32F4X_ADC_NUM) //1:FSMC_A19 + #define PE4 (37+STM32F4X_ADC_NUM) //1:FSMC_A20 + #define PE5 (38+STM32F4X_ADC_NUM) //1:FSMC_A21 + #define PE6 (39+STM32F4X_ADC_NUM) //1:FSMC_A22 + #define PE7 (40+STM32F4X_ADC_NUM) //1:FSMC_D4 + #define PE8 (41+STM32F4X_ADC_NUM) //1:FSMC_D5 + #define PE9 (42+STM32F4X_ADC_NUM) //1:FSMC_D6 / TIM1_CH1 + #define PE10 (43+STM32F4X_ADC_NUM) //1:FSMC_D7 + #define PE11 (44+STM32F4X_ADC_NUM) //1:FSMC_D8 / TIM1_CH2 + #define PE12 (45+STM32F4X_ADC_NUM) //1:FSMC_D9 + #define PE13 (46+STM32F4X_ADC_NUM) //1:FSMC_D10 / TIM1_CH3 + #define PE14 (47+STM32F4X_ADC_NUM) //1:FSMC_D11 / TIM1_CH4 + #define PE15 (48+STM32F4X_ADC_NUM) //1:FSMC_D12 + #define PD8 (49+STM32F4X_ADC_NUM) //1:FSMC_D13 / USART3_TX + #define PD9 (50+STM32F4X_ADC_NUM) //1:FSMC_D14 / USART3_RX + #define PD10 (51+STM32F4X_ADC_NUM) //1:FSMC_D15 + #define PD11 (52+STM32F4X_ADC_NUM) //1:FSMC_A16 + #define PD12 (53+STM32F4X_ADC_NUM) //1:FSMC_A17 / TIM4_CH1 + #define PD13 (54+STM32F4X_ADC_NUM) //1:FSMC_A18 / TIM4_CH2 + #define PD14 (55+STM32F4X_ADC_NUM) //1:FSMC_D0 / TIM4_CH3 + #define PD15 (56+STM32F4X_ADC_NUM) //1:FSMC_D1 / TIM4_CH4 + #define PD0 (57+STM32F4X_ADC_NUM) //1:FSMC_D2 + #define PD1 (58+STM32F4X_ADC_NUM) //1:FSMC_D3 + #define PD3 (59+STM32F4X_ADC_NUM) //1:FSMC_CLK + #define PD4 (60+STM32F4X_ADC_NUM) //1:FSMC_NOE + #define PD5 (61+STM32F4X_ADC_NUM) //1:USART2_TX + #define PD6 (62+STM32F4X_ADC_NUM) //1:USART2_RX + #define PD7 (63+STM32F4X_ADC_NUM) + #define PE0 (64+STM32F4X_ADC_NUM) + #define PE1 (65+STM32F4X_ADC_NUM) +#endif +#if STM32F4X_PIN_NUM >= 144 //144 pins mcu, 114 gpio + #define PF0 (66+STM32F4X_ADC_NUM) //1:FSMC_A0 / I2C2_SDA + #define PF1 (67+STM32F4X_ADC_NUM) //1:FSMC_A1 / I2C2_SCL + #define PF2 (68+STM32F4X_ADC_NUM) //1:FSMC_A2 + #define PF11 (69+STM32F4X_ADC_NUM) + #define PF12 (70+STM32F4X_ADC_NUM) //1:FSMC_A6 + #define PF13 (71+STM32F4X_ADC_NUM) //1:FSMC_A7 + #define PF14 (72+STM32F4X_ADC_NUM) //1:FSMC_A8 + #define PF15 (73+STM32F4X_ADC_NUM) //1:FSMC_A9 + #define PG0 (74+STM32F4X_ADC_NUM) //1:FSMC_A10 + #define PG1 (75+STM32F4X_ADC_NUM) //1:FSMC_A11 + #define PG2 (76+STM32F4X_ADC_NUM) //1:FSMC_A12 + #define PG3 (77+STM32F4X_ADC_NUM) //1:FSMC_A13 + #define PG4 (78+STM32F4X_ADC_NUM) //1:FSMC_A14 + #define PG5 (79+STM32F4X_ADC_NUM) //1:FSMC_A15 + #define PG6 (80+STM32F4X_ADC_NUM) + #define PG7 (81+STM32F4X_ADC_NUM) + #define PG8 (82+STM32F4X_ADC_NUM) + #define PG9 (83+STM32F4X_ADC_NUM) //1:USART6_RX + #define PG10 (84+STM32F4X_ADC_NUM) //1:FSMC_NE3 + #define PG11 (85+STM32F4X_ADC_NUM) + #define PG12 (86+STM32F4X_ADC_NUM) //1:FSMC_NE4 + #define PG13 (87+STM32F4X_ADC_NUM) //1:FSMC_A24 + #define PG14 (88+STM32F4X_ADC_NUM) //1:FSMC_A25 / USART6_TX + #define PG15 (89+STM32F4X_ADC_NUM) +#endif +#if STM32F4X_PIN_NUM >= 176 //176 pins mcu, 140 gpio + #define PI8 (90+STM32F4X_ADC_NUM) + #define PI9 (91+STM32F4X_ADC_NUM) + #define PI10 (92+STM32F4X_ADC_NUM) + #define PI11 (93+STM32F4X_ADC_NUM) + #define PH2 (94+STM32F4X_ADC_NUM) + #define PH3 (95+STM32F4X_ADC_NUM) + #define PH4 (96+STM32F4X_ADC_NUM) //1:I2C2_SCL + #define PH5 (97+STM32F4X_ADC_NUM) //1:I2C2_SDA + #define PH6 (98+STM32F4X_ADC_NUM) //1:TIM12_CH1 + #define PH7 (99+STM32F4X_ADC_NUM) //1:I2C3_SCL + #define PH8 (100+STM32F4X_ADC_NUM) //1:I2C3_SDA + #define PH9 (101+STM32F4X_ADC_NUM) //1:TIM12_CH2 + #define PH10 (102+STM32F4X_ADC_NUM) //1:TIM5_CH1 + #define PH11 (103+STM32F4X_ADC_NUM) //1:TIM5_CH2 + #define PH12 (104+STM32F4X_ADC_NUM) //1:TIM5_CH3 + #define PH13 (105+STM32F4X_ADC_NUM) + #define PH14 (106+STM32F4X_ADC_NUM) + #define PH15 (107+STM32F4X_ADC_NUM) + #define PI0 (108+STM32F4X_ADC_NUM) //1:TIM5_CH4 / SPI2_NSS + #define PI1 (109+STM32F4X_ADC_NUM) //1:SPI2_SCK + #define PI2 (110+STM32F4X_ADC_NUM) //1:TIM8_CH4 /SPI2_MISO + #define PI3 (111+STM32F4X_ADC_NUM) //1:SPI2_MOS + #define PI4 (112+STM32F4X_ADC_NUM) + #define PI5 (113+STM32F4X_ADC_NUM) //1:TIM8_CH1 + #define PI6 (114+STM32F4X_ADC_NUM) //1:TIM8_CH2 + #define PI7 (115+STM32F4X_ADC_NUM) //1:TIM8_CH3 +#endif + + +// This must be a literal +#define NUM_DIGITAL_PINS (STM32F4X_GPIO_NUM) +// This must be a literal with a value less than or equal to MAX_ANALOG_INPUTS +#define NUM_ANALOG_INPUTS (STM32F4X_ADC_NUM) +#define NUM_ANALOG_FIRST 35 + +// Below ADC, DAC and PWM definitions already done in the core +// Could be redefined here if needed +// ADC resolution is 12bits +//#define ADC_RESOLUTION 12 +//#define DACC_RESOLUTION 12 + +// PWM resolution +/* + * BEWARE: + * Changing this value from the default (1000) will affect the PWM output value of analogWrite (to a PWM pin) + * Since the pin is toggled on capture, if you change the frequency of the timer you have to adapt the compare value (analogWrite thinks you did) + */ +//#define PWM_FREQUENCY 20000 +//The bottom values are the default and don't need to be redefined +//#define PWM_RESOLUTION 8 +//#define PWM_MAX_DUTY_CYCLE 255 + +// On-board LED pin number +#define LED_BUILTIN PA7 +#define LED_GREEN LED_BUILTIN + +// Below SPI and I2C definitions already done in the core +// Could be redefined here if differs from the default one +// SPI Definitions +#define PIN_SPI_MOSI PB15 +#define PIN_SPI_MISO PB14 +#define PIN_SPI_SCK PB13 +#define PIN_SPI_SS PB12 + +// I2C Definitions +#if STM32F4X_PIN_NUM >= 176 + #define PIN_WIRE_SDA PH5 + #define PIN_WIRE_SCL PH4 +#else + #define PIN_WIRE_SDA PB7 + #define PIN_WIRE_SCL PB6 +#endif + +// Timer Definitions +//Do not use timer used by PWM pins when possible. See PinMap_PWM in PeripheralPins.c +#define TIMER_TONE TIM10 +#define TIMER_SERVO TIM5 +#define TIMER_SERIAL TIM7 + +// UART Definitions +//#define ENABLE_HWSERIAL1 done automatically by the #define SERIAL_UART_INSTANCE below +#define ENABLE_HWSERIAL3 +#define ENABLE_HWSERIAL6 + +// Define here Serial instance number to map on Serial generic name (if not already used by SerialUSB) +#define SERIAL_UART_INSTANCE 1 //1 for Serial = Serial1 (USART1) + +// DEBUG_UART could be redefined to print on another instance than 'Serial' +//#define DEBUG_UART ((USART_TypeDef *) U(S)ARTX) // ex: USART3 +// DEBUG_UART baudrate, default: 9600 if not defined +//#define DEBUG_UART_BAUDRATE x +// DEBUG_UART Tx pin name, default: the first one found in PinMap_UART_TX for DEBUG_UART +//#define DEBUG_PINNAME_TX PX_n // PinName used for TX + +// Default pin used for 'Serial' instance (ex: ST-Link) +// Mandatory for Firmata +#define PIN_SERIAL_RX PA10 +#define PIN_SERIAL_TX PA9 + +// Optional PIN_SERIALn_RX and PIN_SERIALn_TX where 'n' is the U(S)ART number +// Used when user instanciate a hardware Serial using its peripheral name. +// Example: HardwareSerial mySerial(USART3); +// will use PIN_SERIAL3_RX and PIN_SERIAL3_TX if defined. +#define PIN_SERIAL1_RX PA10 +#define PIN_SERIAL1_TX PA9 +#define PIN_SERIAL3_RX PD9 +#define PIN_SERIAL3_TX PD8 +#define PIN_SERIAL6_RX PC7 +#define PIN_SERIAL6_TX PC6 +//#define PIN_SERIALLP1_RX x // For LPUART1 RX +//#define PIN_SERIALLP1_TX x // For LPUART1 TX + +#ifdef __cplusplus +} // extern "C" +#endif +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_MONITOR Serial +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial3 +#define SERIAL_PORT_HARDWARE_OPEN1 Serial6 +#endif diff --git a/buildroot/share/PlatformIO/variants/BIGTREE_SKR_PRO_1v1/PeripheralPins.c b/buildroot/share/PlatformIO/variants/BIGTREE_SKR_PRO_1v1/PeripheralPins.c index fd1f29645957..6dc8b05158b3 100644 --- a/buildroot/share/PlatformIO/variants/BIGTREE_SKR_PRO_1v1/PeripheralPins.c +++ b/buildroot/share/PlatformIO/variants/BIGTREE_SKR_PRO_1v1/PeripheralPins.c @@ -94,7 +94,7 @@ const PinMap PinMap_I2C_SDA[] = { #if STM32F4X_PIN_NUM >= 176 {PH_5, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, {PH_8, I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)}, - #else + #else {PF_0, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, #endif #endif @@ -113,7 +113,7 @@ const PinMap PinMap_I2C_SCL[] = { //{PF_1, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, {PH_4, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, {PH_7, I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)}, - #else + #else {PF_1, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, #endif #endif @@ -152,8 +152,8 @@ const PinMap PinMap_PWM[] = { */ //{PA_0, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1 //{PA_0, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 1, 0)}, // TIM5_CH1 - {PA_1, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 2, 0)}, // TIM2_CH2 is bltouch analog? - {PA_2, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3 is bltouch analog? + //{PA_1, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 2, 0)}, // TIM2_CH2 BLTOUCH is a "servo" + //{PA_2, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3 BLTOUCH is a "servo" //{PA_1, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 2, 0)}, // TIM5_CH2 //{PA_2, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 3, 0)}, // TIM5_CH3 //{PA_2, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 1, 0)}, // TIM9_CH1 @@ -186,7 +186,7 @@ const PinMap PinMap_PWM[] = { //{PB_9, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 4, 0)}, // TIM4_CH4 //{PB_9, TIM11, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM11, 1, 0)}, // TIM11_CH1 //{PB_10, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3 - {PB_11, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 4, 0)}, // TIM2_CH4 + //{PB_11, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 4, 0)}, // TIM2_CH4 //{PB_13, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 1)}, // TIM1_CH1N //{PB_14, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 1)}, // TIM1_CH2N //{PB_14, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 2, 1)}, // TIM8_CH2N @@ -199,15 +199,15 @@ const PinMap PinMap_PWM[] = { //{PC_7, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 2, 0)}, // TIM8_CH2 //{PC_8, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 3, 0)}, // TIM3_CH3 //{PC_9, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 4, 0)}, // TIM3_CH4 - {PD_13, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 2, 0)}, // TIM4_CH2 - {PD_15, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 4, 0)}, // TIM4_CH4 + //{PD_13, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 2, 0)}, // TIM4_CH2 + //{PD_15, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 4, 0)}, // TIM4_CH4 //{PE_8, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 1)}, // TIM1_CH1N - {PE_9, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 0)}, // TIM1_CH1 + //{PE_9, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 0)}, // TIM1_CH1 //{PE_10, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 1)}, // TIM1_CH2N - {PE_11, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 0)}, // TIM1_CH2 + //{PE_11, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 0)}, // TIM1_CH2 //{PE_12, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 1)}, // TIM1_CH3N - {PE_13, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 0)}, // TIM1_CH3 - {PE_14, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 4, 0)}, // TIM1_CH4 + //{PE_13, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 0)}, // TIM1_CH3 + //{PE_14, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 4, 0)}, // TIM1_CH4 #if STM32F4X_PIN_NUM >= 144 //144 pins mcu, 114 gpio //{PF_6, TIM10, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM10, 1, 0)}, // TIM10_CH1 //{PF_7, TIM11, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM11, 1, 0)}, // TIM11_CH1 @@ -295,8 +295,7 @@ const PinMap PinMap_UART_CTS[] = { #ifdef HAL_SPI_MODULE_ENABLED const PinMap PinMap_SPI_MOSI[] = { - //{PB_5, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI1)}, - {PA_7, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI1)}, + {PB_5, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI1)}, {PB_15, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, {PC_12, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, {NC, NP, 0} @@ -355,7 +354,7 @@ const PinMap PinMap_USB_OTG_HS[] = { /* {PB_14, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_DM {PB_15, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_DP #else - #error "USB in HS mode isn't supported by the board" + #error "USB in HS mode isn't supported by the board" {PA_3, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D0 {PB_0, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D1 {PB_1, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D2 @@ -366,7 +365,8 @@ const PinMap PinMap_USB_OTG_HS[] = { /* {PC_0, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_STP {PC_2, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_DIR {PC_3, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_NXT - #endif /* USE_USB_HS_IN_FS */ + #endif // USE_USB_HS_IN_FS + */ {NC, NP, 0} }; #endif diff --git a/buildroot/share/PlatformIO/variants/BIGTREE_SKR_PRO_1v1/PinNamesVar.h b/buildroot/share/PlatformIO/variants/BIGTREE_SKR_PRO_1v1/PinNamesVar.h index 24248859373b..b4bb9d45f8ac 100644 --- a/buildroot/share/PlatformIO/variants/BIGTREE_SKR_PRO_1v1/PinNamesVar.h +++ b/buildroot/share/PlatformIO/variants/BIGTREE_SKR_PRO_1v1/PinNamesVar.h @@ -25,25 +25,25 @@ #endif /* USB */ #ifdef USBCON - USB_OTG_FS_SOF = PA_8, - USB_OTG_FS_VBUS = PA_9, - USB_OTG_FS_ID = PA_10, - USB_OTG_FS_DM = PA_11, - USB_OTG_FS_DP = PA_12, - USB_OTG_HS_ULPI_D0 = PA_3, - USB_OTG_HS_SOF = PA_4, - USB_OTG_HS_ULPI_CK = PA_5, - USB_OTG_HS_ULPI_D1 = PB_0, - USB_OTG_HS_ULPI_D2 = PB_1, - USB_OTG_HS_ULPI_D7 = PB_5, - USB_OTG_HS_ULPI_D3 = PB_10, - USB_OTG_HS_ULPI_D4 = PB_11, - USB_OTG_HS_ID = PB_12, - USB_OTG_HS_ULPI_D5 = PB_12, - USB_OTG_HS_ULPI_D6 = PB_13, - USB_OTG_HS_VBUS = PB_13, - USB_OTG_HS_DM = PB_14, - USB_OTG_HS_DP = PB_15, + USB_OTG_FS_SOF = PA_8, + USB_OTG_FS_VBUS = PA_9, + USB_OTG_FS_ID = PA_10, + USB_OTG_FS_DM = PA_11, + USB_OTG_FS_DP = PA_12, + USB_OTG_HS_ULPI_D0 = PA_3, + USB_OTG_HS_SOF = PA_4, + USB_OTG_HS_ULPI_CK = PA_5, + USB_OTG_HS_ULPI_D1 = PB_0, + USB_OTG_HS_ULPI_D2 = PB_1, + USB_OTG_HS_ULPI_D7 = PB_5, + USB_OTG_HS_ULPI_D3 = PB_10, + USB_OTG_HS_ULPI_D4 = PB_11, + USB_OTG_HS_ID = PB_12, + USB_OTG_HS_ULPI_D5 = PB_12, + USB_OTG_HS_ULPI_D6 = PB_13, + USB_OTG_HS_VBUS = PB_13, + USB_OTG_HS_DM = PB_14, + USB_OTG_HS_DP = PB_15, USB_OTG_HS_ULPI_STP = PC_0, USB_OTG_HS_ULPI_DIR = PC_2, USB_OTG_HS_ULPI_NXT = PC_3, diff --git a/buildroot/share/PlatformIO/variants/BIGTREE_SKR_PRO_1v1/variant.h b/buildroot/share/PlatformIO/variants/BIGTREE_SKR_PRO_1v1/variant.h index 5ff2ea57689f..1ba0a18d6af6 100644 --- a/buildroot/share/PlatformIO/variants/BIGTREE_SKR_PRO_1v1/variant.h +++ b/buildroot/share/PlatformIO/variants/BIGTREE_SKR_PRO_1v1/variant.h @@ -234,7 +234,7 @@ extern "C" { // On-board LED pin number #define LED_BUILTIN PA7 -//#define LED_GREEN LED_BUILTIN should be defined here but omitted to avoid redefinition in SailfishRGB_LED +#define LED_GREEN LED_BUILTIN // Below SPI and I2C definitions already done in the core // Could be redefined here if differs from the default one @@ -245,8 +245,13 @@ extern "C" { #define PIN_SPI_SS PB12 // I2C Definitions -#define PIN_WIRE_SDA PB7 -#define PIN_WIRE_SCL PB6 +#if STM32F4X_PIN_NUM >= 176 + #define PIN_WIRE_SDA PH5 + #define PIN_WIRE_SCL PH4 +#else + #define PIN_WIRE_SDA PB7 + #define PIN_WIRE_SCL PB6 +#endif // Timer Definitions //Do not use timer used by PWM pins when possible. See PinMap_PWM in PeripheralPins.c diff --git a/buildroot/share/PlatformIO/variants/CHITU_F103/board.cpp b/buildroot/share/PlatformIO/variants/CHITU_F103/board.cpp new file mode 100755 index 000000000000..6083664b9408 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/CHITU_F103/board.cpp @@ -0,0 +1,233 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * 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. + *****************************************************************************/ + +/** + * @file wirish/boards/maple/board.cpp + * @author Marti Bolivar + * @brief Maple board file. + */ + +#include // For this board's header file + +/* Roger Clark. Added next to includes for changes to Serial */ +#include +#include + +#include // For stm32_pin_info and its contents + // (these go into PIN_MAP). + +#include "boards_private.h" // For PMAP_ROW(), which makes + // PIN_MAP easier to read. + +// boardInit(): nothing special to do for Maple. +// +// When defining your own board.cpp, you can put extra code in this +// function if you have anything you want done on reset, before main() +// or setup() are called. +// +// If there's nothing special you need done, feel free to leave this +// function out, as we do here. +/* +void boardInit(void) { +} +*/ + +// Pin map: this lets the basic I/O functions (digitalWrite(), +// analogRead(), pwmWrite()) translate from pin numbers to STM32 +// peripherals. +// +// PMAP_ROW() lets us specify a row (really a struct stm32_pin_info) +// in the pin map. Its arguments are: +// +// - GPIO device for the pin (&gpioa, etc.) +// - GPIO bit for the pin (0 through 15) +// - Timer device, or NULL if none +// - Timer channel (1 to 4, for PWM), or 0 if none +// - ADC device, or NULL if none +// - ADC channel, or ADCx if none + +extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { + /* + gpio_dev *gpio_device; GPIO device + timer_dev *timer_device; Pin's timer device, if any. + const adc_dev *adc_device; ADC device, if any. + uint8 gpio_bit; Pin's GPIO port bit. + uint8 timer_channel; Timer channel, or 0 if none. + uint8 adc_channel; Pin ADC channel, or ADCx if none. + */ + + {&gpioa, &timer2, &adc1, 0, 1, 0}, /* PA0 */ + {&gpioa, &timer2, &adc1, 1, 2, 1}, /* PA1 */ + {&gpioa, &timer2, &adc1, 2, 3, 2}, /* PA2 */ + {&gpioa, &timer2, &adc1, 3, 4, 3}, /* PA3 */ + {&gpioa, NULL, &adc1, 4, 0, 4}, /* PA4 */ + {&gpioa, NULL, &adc1, 5, 0, 5}, /* PA5 */ + {&gpioa, &timer3, &adc1, 6, 1, 6}, /* PA6 */ + {&gpioa, &timer3, &adc1, 7, 2, 7}, /* PA7 */ + {&gpioa, &timer1, NULL, 8, 1, ADCx}, /* PA8 */ + {&gpioa, &timer1, NULL, 9, 2, ADCx}, /* PA9 */ + {&gpioa, &timer1, NULL, 10, 3, ADCx}, /* PA10 */ + {&gpioa, NULL, NULL, 11, 0, ADCx}, /* PA11 */ + {&gpioa, NULL, NULL, 12, 0, ADCx}, /* PA12 */ + {&gpioa, NULL, NULL, 13, 0, ADCx}, /* PA13 */ + {&gpioa, NULL, NULL, 14, 0, ADCx}, /* PA14 */ + {&gpioa, NULL, NULL, 15, 0, ADCx}, /* PA15 */ + + {&gpiob, &timer3, &adc1, 0, 3, 8}, /* PB0 */ + {&gpiob, &timer3, &adc1, 1, 4, 9}, /* PB1 */ + {&gpiob, &timer3, &adc1, 2, 4, 9}, /* PB2 */ + {&gpiob, NULL, NULL, 3, 0, ADCx}, /* PB3 */ + {&gpiob, NULL, NULL, 4, 0, ADCx}, /* PB4 */ + {&gpiob, NULL, NULL, 5, 0, ADCx}, /* PB5 */ + {&gpiob, &timer4, NULL, 6, 1, ADCx}, /* PB6 */ + {&gpiob, &timer4, NULL, 7, 2, ADCx}, /* PB7 */ + {&gpiob, &timer4, NULL, 8, 3, ADCx}, /* PB8 */ + {&gpiob, &timer4, NULL, 9, 4, ADCx}, /* PB9 */ + {&gpiob, NULL, NULL, 10, 0, ADCx}, /* PB10 */ + {&gpiob, NULL, NULL, 11, 0, ADCx}, /* PB11 */ + {&gpiob, NULL, NULL, 12, 0, ADCx}, /* PB12 */ + {&gpiob, NULL, NULL, 13, 0, ADCx}, /* PB13 */ + {&gpiob, NULL, NULL, 14, 0, ADCx}, /* PB14 */ + {&gpiob, NULL, NULL, 15, 0, ADCx}, /* PB15 */ + + + {&gpioc, NULL, &adc1, 0, 0, 10}, /* PC0 */ + {&gpioc, NULL, &adc1, 1, 0, 11}, /* PC1 */ + {&gpioc, NULL, &adc1, 2, 0, 12}, /* PC2 */ + {&gpioc, NULL, &adc1, 3, 0, 13}, /* PC3 */ + {&gpioc, NULL, &adc1, 4, 0, 14}, /* PC4 */ + {&gpioc, NULL, &adc1, 5, 0, 15}, /* PC5 */ + {&gpioc, &timer8, NULL, 6, 1, ADCx}, /* PC6 */ + {&gpioc, &timer8, NULL, 7, 2, ADCx}, /* PC7 */ + {&gpioc, &timer8, NULL, 8, 3, ADCx}, /* PC8 */ + {&gpioc, &timer8, NULL, 9, 4, ADCx}, /* PC9 */ + {&gpioc, NULL, NULL, 10, 0, ADCx}, /* PC10 UART4_TX/SDIO_D2 */ + {&gpioc, NULL, NULL, 11, 0, ADCx}, /* PC11 UART4_RX/SDIO_D3 */ + {&gpioc, NULL, NULL, 12, 0, ADCx}, /* PC12 UART5_TX/SDIO_CK */ + {&gpioc, NULL, NULL, 13, 0, ADCx}, /* PC13 TAMPER-RTC */ + {&gpioc, NULL, NULL, 14, 0, ADCx}, /* PC14 OSC32_IN */ + {&gpioc, NULL, NULL, 15, 0, ADCx}, /* PC15 OSC32_OUT */ + + {&gpiod, NULL, NULL, 0, 0, ADCx} , /* PD0 OSC_IN */ + {&gpiod, NULL, NULL, 1, 0, ADCx} , /* PD1 OSC_OUT */ + {&gpiod, NULL, NULL, 2, 0, ADCx} , /* PD2 TIM3_ETR/UART5_RX SDIO_CMD */ + + {&gpiod, NULL, NULL, 3, 0, ADCx} , /* PD3 FSMC_CLK */ + {&gpiod, NULL, NULL, 4, 0, ADCx} , /* PD4 FSMC_NOE */ + {&gpiod, NULL, NULL, 5, 0, ADCx} , /* PD5 FSMC_NWE */ + {&gpiod, NULL, NULL, 6, 0, ADCx} , /* PD6 FSMC_NWAIT */ + {&gpiod, NULL, NULL, 7, 0, ADCx} , /* PD7 FSMC_NE1/FSMC_NCE2 */ + {&gpiod, NULL, NULL, 8, 0, ADCx} , /* PD8 FSMC_D13 */ + {&gpiod, NULL, NULL, 9, 0, ADCx} , /* PD9 FSMC_D14 */ + {&gpiod, NULL, NULL, 10, 0, ADCx} , /* PD10 FSMC_D15 */ + {&gpiod, NULL, NULL, 11, 0, ADCx} , /* PD11 FSMC_A16 */ + {&gpiod, NULL, NULL, 12, 0, ADCx} , /* PD12 FSMC_A17 */ + {&gpiod, NULL, NULL, 13, 0, ADCx} , /* PD13 FSMC_A18 */ + {&gpiod, NULL, NULL, 14, 0, ADCx} , /* PD14 FSMC_D0 */ + {&gpiod, NULL, NULL, 15, 0, ADCx} , /* PD15 FSMC_D1 */ + + {&gpioe, NULL, NULL, 0, 0, ADCx} , /* PE0 */ + {&gpioe, NULL, NULL, 1, 0, ADCx} , /* PE1 */ + {&gpioe, NULL, NULL, 2, 0, ADCx} , /* PE2 */ + {&gpioe, NULL, NULL, 3, 0, ADCx} , /* PE3 */ + {&gpioe, NULL, NULL, 4, 0, ADCx} , /* PE4 */ + {&gpioe, NULL, NULL, 5, 0, ADCx} , /* PE5 */ + {&gpioe, NULL, NULL, 6, 0, ADCx} , /* PE6 */ + {&gpioe, NULL, NULL, 7, 0, ADCx} , /* PE7 */ + {&gpioe, NULL, NULL, 8, 0, ADCx} , /* PE8 */ + {&gpioe, NULL, NULL, 9, 0, ADCx} , /* PE9 */ + {&gpioe, NULL, NULL, 10, 0, ADCx} , /* PE10 */ + {&gpioe, NULL, NULL, 11, 0, ADCx} , /* PE11 */ + {&gpioe, NULL, NULL, 12, 0, ADCx} , /* PE12 */ + {&gpioe, NULL, NULL, 13, 0, ADCx} , /* PE13 */ + {&gpioe, NULL, NULL, 14, 0, ADCx} , /* PE14 */ + {&gpioe, NULL, NULL, 15, 0, ADCx} , /* PE15 */ + + {&gpiof, NULL, NULL, 0, 0, ADCx} , /* PF0 */ + {&gpiof, NULL, NULL, 1, 0, ADCx} , /* PF1 */ + {&gpiof, NULL, NULL, 2, 0, ADCx} , /* PF2 */ + {&gpiof, NULL, NULL, 3, 0, ADCx} , /* PF3 */ + {&gpiof, NULL, NULL, 4, 0, ADCx} , /* PF4 */ + {&gpiof, NULL, NULL, 5, 0, ADCx} , /* PF5 */ + {&gpiof, NULL, NULL, 6, 0, ADCx} , /* PF6 */ + {&gpiof, NULL, NULL, 7, 0, ADCx} , /* PF7 */ + {&gpiof, NULL, NULL, 8, 0, ADCx} , /* PF8 */ + {&gpiof, NULL, NULL, 9, 0, ADCx} , /* PF9 */ + {&gpiof, NULL, NULL, 10, 0, ADCx} , /* PF10 */ + {&gpiof, NULL, NULL, 11, 0, ADCx} , /* PF11 */ + {&gpiof, NULL, NULL, 12, 0, ADCx} , /* PF12 */ + {&gpiof, NULL, NULL, 13, 0, ADCx} , /* PF13 */ + {&gpiof, NULL, NULL, 14, 0, ADCx} , /* PF14 */ + {&gpiof, NULL, NULL, 15, 0, ADCx} , /* PF15 */ + + {&gpiog, NULL, NULL, 0, 0, ADCx} , /* PG0 */ + {&gpiog, NULL, NULL, 1, 0, ADCx} , /* PG1 */ + {&gpiog, NULL, NULL, 2, 0, ADCx} , /* PG2 */ + {&gpiog, NULL, NULL, 3, 0, ADCx} , /* PG3 */ + {&gpiog, NULL, NULL, 4, 0, ADCx} , /* PG4 */ + {&gpiog, NULL, NULL, 5, 0, ADCx} , /* PG5 */ + {&gpiog, NULL, NULL, 6, 0, ADCx} , /* PG6 */ + {&gpiog, NULL, NULL, 7, 0, ADCx} , /* PG7 */ + {&gpiog, NULL, NULL, 8, 0, ADCx} , /* PG8 */ + {&gpiog, NULL, NULL, 9, 0, ADCx} , /* PG9 */ + {&gpiog, NULL, NULL, 10, 0, ADCx} , /* PG10 */ + {&gpiog, NULL, NULL, 11, 0, ADCx} , /* PG11 */ + {&gpiog, NULL, NULL, 12, 0, ADCx} , /* PG12 */ + {&gpiog, NULL, NULL, 13, 0, ADCx} , /* PG13 */ + {&gpiog, NULL, NULL, 14, 0, ADCx} , /* PG14 */ + {&gpiog, NULL, NULL, 15, 0, ADCx} /* PG15 */ +}; + +/* Basically everything that is defined as having a timer us PWM */ +extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { + PA0,PA1,PA2,PA3,PA6,PA7,PA8,PA9,PA10,PB0,PB1,PB6,PB7,PB8,PB9,PC6,PC7,PC8,PC9 +}; + +/* Basically everything that is defined having ADC */ +extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = { + PA0,PA1,PA2,PA3,PA4,PA5,PA6,PA7,PB0,PB1,PC0,PC1,PC2,PC3,PC4,PC5 +}; + +/* not sure what this us used for */ +extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { + BOARD_JTMS_SWDIO_PIN, + BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN +}; + + +#ifdef SERIAL_USB + DEFINE_HWSERIAL(Serial1, 1); + DEFINE_HWSERIAL(Serial2, 2); + DEFINE_HWSERIAL(Serial3, 3); + DEFINE_HWSERIAL_UART(Serial4, 4); + DEFINE_HWSERIAL_UART(Serial5, 5); +#else + DEFINE_HWSERIAL(Serial, 1); + DEFINE_HWSERIAL(Serial1, 2); + DEFINE_HWSERIAL(Serial2, 3); + DEFINE_HWSERIAL_UART(Serial3, 4); + DEFINE_HWSERIAL_UART(Serial4, 5); +#endif diff --git a/buildroot/share/PlatformIO/variants/CHITU_F103/board/board.h b/buildroot/share/PlatformIO/variants/CHITU_F103/board/board.h new file mode 100755 index 000000000000..20fd9d379f19 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/CHITU_F103/board/board.h @@ -0,0 +1,240 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * 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. + *****************************************************************************/ + +/** + * @file maple_RET6.h + * @author Marti Bolivar + * @brief Private include file for Maple RET6 Edition in boards.h + * + * See maple.h for more information on these definitions. + */ + +#ifndef _BOARDS_GENERIC_STM32F103Z_H_ +#define _BOARDS_GENERIC_STM32F103Z_H_ + +/* A few of these values will seem strange given that it's a + * high-density board. */ + +#define CYCLES_PER_MICROSECOND 72 +#define SYSTICK_RELOAD_VAL (F_CPU/1000) - 1 /* takes a cycle to reload */ + +// USARTS +#define BOARD_NR_USARTS 5 +#define BOARD_USART1_TX_PIN PA9 +#define BOARD_USART1_RX_PIN PA10 + +#define BOARD_USART2_TX_PIN PA2 +#define BOARD_USART2_RX_PIN PA3 + +#define BOARD_USART3_TX_PIN PB10 +#define BOARD_USART3_RX_PIN PB11 + +#define BOARD_USART4_TX_PIN PC10 +#define BOARD_USART4_RX_PIN PC11 + +#define BOARD_USART5_TX_PIN PC12 +#define BOARD_USART5_RX_PIN PD2 + +/* Note: + * + * SPI3 is unusable due to pin 43 (PB4) and NRST tie-together :(, but + * leave the definitions so as not to clutter things up. This is only + * OK since RET6 Ed. is specifically advertised as a beta board. */ +#define BOARD_NR_SPI 3 +#define BOARD_SPI1_NSS_PIN PA4 +#define BOARD_SPI1_SCK_PIN PA5 +#define BOARD_SPI1_MISO_PIN PA6 +#define BOARD_SPI1_MOSI_PIN PA7 + + + +#define BOARD_SPI2_NSS_PIN PB12 +#define BOARD_SPI2_SCK_PIN PB13 +#define BOARD_SPI2_MISO_PIN PB14 +#define BOARD_SPI2_MOSI_PIN PB15 + + +#define BOARD_SPI3_NSS_PIN PA15 +#define BOARD_SPI3_SCK_PIN PB3 +#define BOARD_SPI3_MISO_PIN PB4 +#define BOARD_SPI3_MOSI_PIN PB5 + + +/* GPIO A to E = 5 * 16 - BOOT1 not used = 79*/ +#define BOARD_NR_GPIO_PINS 112 +/* Note: NOT 19. The missing one is D38 a.k.a. BOARD_BUTTON_PIN, which + * isn't broken out to a header and is thus unusable for PWM. */ +#define BOARD_NR_PWM_PINS 19 +#define BOARD_NR_ADC_PINS 16 +#define BOARD_NR_USED_PINS 7 + +#define BOARD_JTMS_SWDIO_PIN 39 +#define BOARD_JTCK_SWCLK_PIN 40 +#define BOARD_JTDI_PIN 41 +#define BOARD_JTDO_PIN 42 +#define BOARD_NJTRST_PIN 43 + +/* USB configuration. BOARD_USB_DISC_DEV is the GPIO port containing + * the USB_DISC pin, and BOARD_USB_DISC_BIT is that pin's bit. */ +#define BOARD_USB_DISC_DEV GPIOC +#define BOARD_USB_DISC_BIT 12 + +/* + * SDIO Pins + */ +#define BOARD_SDIO_D0 PC8 +#define BOARD_SDIO_D1 PC9 +#define BOARD_SDIO_D2 PC10 +#define BOARD_SDIO_D3 PC11 +#define BOARD_SDIO_CLK PC12 +#define BOARD_SDIO_CMD PD2 + +/* Pin aliases: these give the GPIO port/bit for each pin as an + * enum. These are optional, but recommended. They make it easier to + * write code using low-level GPIO functionality. */ +enum { +PA0,PA1,PA2,PA3,PA4,PA5,PA6,PA7,PA8,PA9,PA10,PA11,PA12,PA13,PA14,PA15, +PB0,PB1,PB2,PB3,PB4,PB5,PB6,PB7,PB8,PB9,PB10,PB11,PB12,PB13,PB14,PB15, +PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PC8,PC9,PC10,PC11,PC12,PC13,PC14,PC15, +PD0,PD1,PD2,PD3,PD4,PD5,PD6,PD7,PD8,PD9,PD10,PD11,PD12,PD13,PD14,PD15, +PE0,PE1,PE2,PE3,PE4,PE5,PE6,PE7,PE8,PE9,PE10,PE11,PE12,PE13,PE14,PE15, +PF0,PF1,PF2,PF3,PF4,PF5,PF6,PF7,PF8,PF9,PF10,PF11,PF12,PF13,PF14,PF15, +PG0,PG1,PG2,PG3,PG4,PG5,PG6,PG7,PG8,PG9,PG10,PG11,PG12,PG13,PG14,PG15 +};/* Note PB2 is skipped as this is Boot1 and is not going to be much use as its likely to be pulled permanently low */ +/* +#define PA0 0 +#define PA1 1 +#define PA2 2 +#define PA3 3 +#define PA4 4 +#define PA5 5 +#define PA6 6 +#define PA7 7 +#define PA8 8 +#define PA9 9 +#define PA10 10 +#define PA11 11 +#define PA12 12 +#define PA13 13 +#define PA14 14 +#define PA15 15 +#define PB0 16 +#define PB1 17 +#define PB2 18 +#define PB3 19 +#define PB4 20 +#define PB5 21 +#define PB6 22 +#define PB7 23 +#define PB8 24 +#define PB9 25 +#define PB10 26 +#define PB11 27 +#define PB12 28 +#define PB13 29 +#define PB14 30 +#define PB15 31 +#define PC0 32 +#define PC1 33 +#define PC2 34 +#define PC3 35 +#define PC4 36 +#define PC5 37 +#define PC6 38 +#define PC7 39 +#define PC8 40 +#define PC9 41 +#define PC10 42 +#define PC11 43 +#define PC12 44 +#define PC13 45 +#define PC14 46 +#define PC15 47 +#define PD0 48 +#define PD1 49 +#define PD2 50 +#define PD3 51 +#define PD4 52 +#define PD5 53 +#define PD6 54 +#define PD7 55 +#define PD8 56 +#define PD9 57 +#define PD10 58 +#define PD11 59 +#define PD12 60 +#define PD13 61 +#define PD14 62 +#define PD15 63 +#define PE0 64 +#define PE1 65 +#define PE2 66 +#define PE3 67 +#define PE4 68 +#define PE5 69 +#define PE6 70 +#define PE7 71 +#define PE8 72 +#define PE9 73 +#define PE10 74 +#define PE11 75 +#define PE12 76 +#define PE13 77 +#define PE14 78 +#define PE15 79 +#define PF0 80 +#define PF1 81 +#define PF2 82 +#define PF3 83 +#define PF4 84 +#define PF5 85 +#define PF6 86 +#define PF7 87 +#define PF8 88 +#define PF9 89 +#define PF10 90 +#define PF11 91 +#define PF12 92 +#define PF13 93 +#define PF14 94 +#define PF15 95 +#define PG0 96 +#define PG1 97 +#define PG2 98 +#define PG3 99 +#define PG4 100 +#define PG5 101 +#define PG6 102 +#define PG7 103 +#define PG8 104 +#define PG9 105 +#define PG10 106 +#define PG11 107 +#define PG12 108 +#define PG13 109 +#define PG14 110 +#define PG15 111 */ +#endif diff --git a/buildroot/share/PlatformIO/variants/CHITU_F103/ld/common.inc b/buildroot/share/PlatformIO/variants/CHITU_F103/ld/common.inc new file mode 100755 index 000000000000..e086a58bca9e --- /dev/null +++ b/buildroot/share/PlatformIO/variants/CHITU_F103/ld/common.inc @@ -0,0 +1,220 @@ +/* + * Linker script for libmaple. + * + * Original author "lanchon" from ST forums, with modifications by LeafLabs. + */ + +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +/* + * Configure other libraries we want in the link. + * + * libgcc, libc, and libm are common across supported toolchains. + * However, some toolchains require additional archives which aren't + * present everywhere (e.g. ARM's gcc-arm-embedded releases). + * + * To hack around this, we let the build system specify additional + * archives by putting the right extra_libs.inc (in a directory under + * toolchains/) in our search path. + */ +GROUP(libgcc.a libc.a libm.a) +INCLUDE extra_libs.inc + +/* + * These force the linker to search for vector table symbols. + * + * These symbols vary by STM32 family (and also within families). + * It's up to the build system to configure the link's search path + * properly for the target MCU. + */ +INCLUDE vector_symbols.inc + +/* STM32 vector table. */ +EXTERN(__stm32_vector_table) + +/* C runtime initialization function. */ +EXTERN(start_c) + +/* main entry point */ +EXTERN(main) + +/* Initial stack pointer value. */ +EXTERN(__msp_init) +PROVIDE(__msp_init = ORIGIN(ram) + LENGTH(ram)); + +/* Reset vector and chip reset entry point */ +EXTERN(__start__) +ENTRY(__start__) +PROVIDE(__exc_reset = __start__); + +/* Heap boundaries, for libmaple */ +EXTERN(_lm_heap_start); +EXTERN(_lm_heap_end); + +SECTIONS +{ + .text : + { + __text_start__ = .; + /* + * STM32 vector table. Leave this here. Yes, really. + */ + *(.stm32.interrupt_vector) + + /* + * Program code and vague linking + */ + *(.text .text.* .gnu.linkonce.t.*) + *(.plt) + *(.gnu.warning) + *(.glue_7t) *(.glue_7) *(.vfp11_veneer) + + *(.ARM.extab* .gnu.linkonce.armextab.*) + *(.gcc_except_table) + *(.eh_frame_hdr) + *(.eh_frame) + + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(0x4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > REGION_TEXT + + /* + * End of text + */ + .text.align : + { + . = ALIGN(8); + __text_end__ = .; + } > REGION_TEXT + + /* + * .ARM.exidx exception unwinding; mandated by ARM's C++ ABI + */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > REGION_RODATA + __exidx_end = .; + + /* + * .data + */ + .data : + { + __data_start__ = .; + LONG(0) + . = ALIGN(8); + + *(.got.plt) *(.got) + *(.data .data.* .gnu.linkonce.d.*) + + . = ALIGN(8); + __data_end__ = .; + } > REGION_DATA AT> REGION_RODATA + + /* + * Read-only data + */ + .rodata : + { + *(.rodata .rodata.* .gnu.linkonce.r.*) + /* .USER_FLASH: We allow users to allocate into Flash here */ + *(.USER_FLASH) + /* ROM image configuration; for C startup */ + . = ALIGN(4); + _lm_rom_img_cfgp = .; + LONG(LOADADDR(.data)); + /* + * Heap: Linker scripts may choose a custom heap by overriding + * _lm_heap_start and _lm_heap_end. Otherwise, the heap is in + * internal SRAM, beginning after .bss, and growing towards + * the stack. + * + * I'm shoving these here naively; there's probably a cleaner way + * to go about this. [mbolivar] + */ + _lm_heap_start = DEFINED(_lm_heap_start) ? _lm_heap_start : _end; + _lm_heap_end = DEFINED(_lm_heap_end) ? _lm_heap_end : __msp_init; + } > REGION_RODATA + + /* + * .bss + */ + .bss : + { + . = ALIGN(8); + __bss_start__ = .; + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + __bss_end__ = .; + _end = __bss_end__; + } > REGION_BSS + + /* + * Debugging sections + */ + .stab 0 (NOLOAD) : { *(.stab) } + .stabstr 0 (NOLOAD) : { *(.stabstr) } + /* DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) } +} diff --git a/buildroot/share/PlatformIO/variants/CHITU_F103/ld/extra_libs.inc b/buildroot/share/PlatformIO/variants/CHITU_F103/ld/extra_libs.inc new file mode 100755 index 000000000000..dd2c84fa45ea --- /dev/null +++ b/buildroot/share/PlatformIO/variants/CHITU_F103/ld/extra_libs.inc @@ -0,0 +1,7 @@ +/* + * Extra archives needed by ARM's GCC ARM Embedded arm-none-eabi- + * releases (https://launchpad.net/gcc-arm-embedded/). + */ + +/* This is for the provided newlib. */ +GROUP(libnosys.a) diff --git a/buildroot/share/PlatformIO/variants/CHITU_F103/ld/stm32f103z_dfu.ld b/buildroot/share/PlatformIO/variants/CHITU_F103/ld/stm32f103z_dfu.ld new file mode 100755 index 000000000000..81eaa8b06b37 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/CHITU_F103/ld/stm32f103z_dfu.ld @@ -0,0 +1,29 @@ +/* + * libmaple linker script + * + * This build puts .text (and .rodata) in Flash, and + * .data/.bss/heap (of course) in SRAM, but links starting at the + * Flash and SRAM starting addresses (0x08000000 and 0x20000000 + * respectively). This will wipe out a Maple bootloader if there's one + * on the board, so only use this if you know what you're doing. + * + * This build is perfectly usable for upload over SWD, + * the system memory bootloader, etc. The name is just a historical + * artifact. + */ + + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + rom (rx) : ORIGIN = 0x08002000, LENGTH = 504K +} + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/buildroot/share/PlatformIO/variants/CHITU_F103/ld/stm32f103zc.ld b/buildroot/share/PlatformIO/variants/CHITU_F103/ld/stm32f103zc.ld new file mode 100755 index 000000000000..37bc3da0dc04 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/CHITU_F103/ld/stm32f103zc.ld @@ -0,0 +1,27 @@ +/* + * libmaple linker script + * + * This build puts .text (and .rodata) in Flash, and + * .data/.bss/heap (of course) in SRAM, but links starting at the + * Flash and SRAM starting addresses (0x08000000 and 0x20000000 + * respectively). This will wipe out a Maple bootloader if there's one + * on the board, so only use this if you know what you're doing. + * + * This build is perfectly usable for upload over SWD, + * the system memory bootloader, etc. The name is just a historical + * artifact. + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K +} + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/buildroot/share/PlatformIO/variants/CHITU_F103/ld/stm32f103zd.ld b/buildroot/share/PlatformIO/variants/CHITU_F103/ld/stm32f103zd.ld new file mode 100755 index 000000000000..f3f218059f7c --- /dev/null +++ b/buildroot/share/PlatformIO/variants/CHITU_F103/ld/stm32f103zd.ld @@ -0,0 +1,27 @@ +/* + * libmaple linker script + * + * This build puts .text (and .rodata) in Flash, and + * .data/.bss/heap (of course) in SRAM, but links starting at the + * Flash and SRAM starting addresses (0x08000000 and 0x20000000 + * respectively). This will wipe out a Maple bootloader if there's one + * on the board, so only use this if you know what you're doing. + * + * This build is perfectly usable for upload over SWD, + * the system memory bootloader, etc. The name is just a historical + * artifact. + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K +} + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/buildroot/share/PlatformIO/variants/CHITU_F103/ld/stm32f103ze.ld b/buildroot/share/PlatformIO/variants/CHITU_F103/ld/stm32f103ze.ld new file mode 100755 index 000000000000..2f86c3f071a1 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/CHITU_F103/ld/stm32f103ze.ld @@ -0,0 +1,29 @@ +/* + * libmaple linker script + * + * This build puts .text (and .rodata) in Flash, and + * .data/.bss/heap (of course) in SRAM, but links starting at the + * Flash and SRAM starting addresses (0x08000000 and 0x20000000 + * respectively). This will wipe out a Maple bootloader if there's one + * on the board, so only use this if you know what you're doing. + * + * This build is perfectly usable for upload over SWD, + * the system memory bootloader, etc. The name is just a historical + * artifact. + */ + + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K +} + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/buildroot/share/PlatformIO/variants/CHITU_F103/ld/vector_symbols.inc b/buildroot/share/PlatformIO/variants/CHITU_F103/ld/vector_symbols.inc new file mode 100755 index 000000000000..f8519bba440b --- /dev/null +++ b/buildroot/share/PlatformIO/variants/CHITU_F103/ld/vector_symbols.inc @@ -0,0 +1,78 @@ +EXTERN(__msp_init) +EXTERN(__exc_reset) +EXTERN(__exc_nmi) +EXTERN(__exc_hardfault) +EXTERN(__exc_memmanage) +EXTERN(__exc_busfault) +EXTERN(__exc_usagefault) +EXTERN(__stm32reservedexception7) +EXTERN(__stm32reservedexception8) +EXTERN(__stm32reservedexception9) +EXTERN(__stm32reservedexception10) +EXTERN(__exc_svc) +EXTERN(__exc_debug_monitor) +EXTERN(__stm32reservedexception13) +EXTERN(__exc_pendsv) +EXTERN(__exc_systick) + +EXTERN(__irq_wwdg) +EXTERN(__irq_pvd) +EXTERN(__irq_tamper) +EXTERN(__irq_rtc) +EXTERN(__irq_flash) +EXTERN(__irq_rcc) +EXTERN(__irq_exti0) +EXTERN(__irq_exti1) +EXTERN(__irq_exti2) +EXTERN(__irq_exti3) +EXTERN(__irq_exti4) +EXTERN(__irq_dma1_channel1) +EXTERN(__irq_dma1_channel2) +EXTERN(__irq_dma1_channel3) +EXTERN(__irq_dma1_channel4) +EXTERN(__irq_dma1_channel5) +EXTERN(__irq_dma1_channel6) +EXTERN(__irq_dma1_channel7) +EXTERN(__irq_adc) +EXTERN(__irq_usb_hp_can_tx) +EXTERN(__irq_usb_lp_can_rx0) +EXTERN(__irq_can_rx1) +EXTERN(__irq_can_sce) +EXTERN(__irq_exti9_5) +EXTERN(__irq_tim1_brk) +EXTERN(__irq_tim1_up) +EXTERN(__irq_tim1_trg_com) +EXTERN(__irq_tim1_cc) +EXTERN(__irq_tim2) +EXTERN(__irq_tim3) +EXTERN(__irq_tim4) +EXTERN(__irq_i2c1_ev) +EXTERN(__irq_i2c1_er) +EXTERN(__irq_i2c2_ev) +EXTERN(__irq_i2c2_er) +EXTERN(__irq_spi1) +EXTERN(__irq_spi2) +EXTERN(__irq_usart1) +EXTERN(__irq_usart2) +EXTERN(__irq_usart3) +EXTERN(__irq_exti15_10) +EXTERN(__irq_rtcalarm) +EXTERN(__irq_usbwakeup) + +EXTERN(__irq_tim8_brk) +EXTERN(__irq_tim8_up) +EXTERN(__irq_tim8_trg_com) +EXTERN(__irq_tim8_cc) +EXTERN(__irq_adc3) +EXTERN(__irq_fsmc) +EXTERN(__irq_sdio) +EXTERN(__irq_tim5) +EXTERN(__irq_spi3) +EXTERN(__irq_uart4) +EXTERN(__irq_uart5) +EXTERN(__irq_tim6) +EXTERN(__irq_tim7) +EXTERN(__irq_dma2_channel1) +EXTERN(__irq_dma2_channel2) +EXTERN(__irq_dma2_channel3) +EXTERN(__irq_dma2_channel4_5) diff --git a/buildroot/share/PlatformIO/variants/CHITU_F103/pins_arduino.h b/buildroot/share/PlatformIO/variants/CHITU_F103/pins_arduino.h new file mode 100755 index 000000000000..d5dce114d504 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/CHITU_F103/pins_arduino.h @@ -0,0 +1,2 @@ +// API compatibility +#include "variant.h" diff --git a/buildroot/share/PlatformIO/variants/CHITU_F103/variant.h b/buildroot/share/PlatformIO/variants/CHITU_F103/variant.h new file mode 100755 index 000000000000..cd10bb3c07f2 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/CHITU_F103/variant.h @@ -0,0 +1,17 @@ +#pragma once + +#define digitalPinToPort(P) ( PIN_MAP[P].gpio_device ) +#define digitalPinToBitMask(P) ( BIT(PIN_MAP[P].gpio_bit) ) +#define portOutputRegister(port) ( &(port->regs->ODR) ) +#define portInputRegister(port) ( &(port->regs->IDR) ) + +#define portSetRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->BSRR) ) +#define portClearRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->BRR) ) + +#define portConfigRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->CRL) ) + +static const uint8_t SS = BOARD_SPI1_NSS_PIN; +static const uint8_t SS1 = BOARD_SPI2_NSS_PIN; +static const uint8_t MOSI = BOARD_SPI1_MOSI_PIN; +static const uint8_t MISO = BOARD_SPI1_MISO_PIN; +static const uint8_t SCK = BOARD_SPI1_SCK_PIN; diff --git a/buildroot/share/PlatformIO/variants/CHITU_F103/wirish/boards.cpp b/buildroot/share/PlatformIO/variants/CHITU_F103/wirish/boards.cpp new file mode 100755 index 000000000000..2210e9844c53 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/CHITU_F103/wirish/boards.cpp @@ -0,0 +1,225 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * Copyright (c) 2011, 2012 LeafLabs, LLC. + * + * 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. + *****************************************************************************/ + +/** + * @file wirish/boards.cpp + * @brief init() and board routines. + * + * This file is mostly interesting for the init() function, which + * configures Flash, the core clocks, and a variety of other available + * peripherals on the board so the rest of Wirish doesn't have to turn + * things on before using them. + * + * Prior to returning, init() calls boardInit(), which allows boards + * to perform any initialization they need to. This file includes a + * weak no-op definition of boardInit(), so boards that don't need any + * special initialization don't have to define their own. + * + * How init() works is chip-specific. See the boards_setup.cpp files + * under e.g. wirish/stm32f1/, wirish/stmf32f2 for the details, but be + * advised: their contents are unstable, and can/will change without + * notice. + */ + +#include +#include +#include +#include +#include +#include "boards_private.h" + +static void setup_flash(void); +static void setup_clocks(void); +static void setup_nvic(void); +static void setup_adcs(void); +static void setup_timers(void); + +/* + * Exported functions + */ + +void init(void) { + setup_flash(); + setup_clocks(); + setup_nvic(); + systick_init(SYSTICK_RELOAD_VAL); + wirish::priv::board_setup_gpio(); + setup_adcs(); + setup_timers(); + wirish::priv::board_setup_usb(); + wirish::priv::series_init(); + boardInit(); +} + +/* Provide a default no-op boardInit(). */ +__weak void boardInit(void) { +} + +/* You could farm this out to the files in boards/ if e.g. it takes + * too long to test on boards with lots of pins. */ +bool boardUsesPin(uint8 pin) { + for (int i = 0; i < BOARD_NR_USED_PINS; i++) { + if (pin == boardUsedPins[i]) { + return true; + } + } + return false; +} + +/* + * Auxiliary routines + */ + +static void setup_flash(void) { + // Turn on as many Flash "go faster" features as + // possible. flash_enable_features() just ignores any flags it + // can't support. + flash_enable_features(FLASH_PREFETCH | FLASH_ICACHE | FLASH_DCACHE); + // Configure the wait states, assuming we're operating at "close + // enough" to 3.3V. + flash_set_latency(FLASH_SAFE_WAIT_STATES); +} + +static void setup_clocks(void) { + // Turn on HSI. We'll switch to and run off of this while we're + // setting up the main PLL. + rcc_turn_on_clk(RCC_CLK_HSI); + + // Turn off and reset the clock subsystems we'll be using, as well + // as the clock security subsystem (CSS). Note that resetting CFGR + // to its default value of 0 implies a switch to HSI for SYSCLK. + RCC_BASE->CFGR = 0x00000000; + rcc_disable_css(); + rcc_turn_off_clk(RCC_CLK_PLL); + rcc_turn_off_clk(RCC_CLK_HSE); + wirish::priv::board_reset_pll(); + // Clear clock readiness interrupt flags and turn off clock + // readiness interrupts. + RCC_BASE->CIR = 0x00000000; +#if !USE_HSI_CLOCK + // Enable HSE, and wait until it's ready. + rcc_turn_on_clk(RCC_CLK_HSE); + while(!rcc_is_clk_ready(RCC_CLK_HSE)) + ; +#endif + // Configure AHBx, APBx, etc. prescalers and the main PLL. + wirish::priv::board_setup_clock_prescalers(); + rcc_configure_pll(&wirish::priv::w_board_pll_cfg); + + // Enable the PLL, and wait until it's ready. + rcc_turn_on_clk(RCC_CLK_PLL); + while(!rcc_is_clk_ready(RCC_CLK_PLL)) + ; + + // Finally, switch to the now-ready PLL as the main clock source. + rcc_switch_sysclk(RCC_CLKSRC_PLL); +} + +/* + * These addresses are where usercode starts when a bootloader is + * present. If no bootloader is present, the user NVIC usually starts + * at the Flash base address, 0x08000000. + */ +#if defined(BOOTLOADER_maple) + #define USER_ADDR_ROM 0x08005000 +#else + #define USER_ADDR_ROM 0x08000000 +#endif +#define USER_ADDR_RAM 0x20000C00 +extern char __text_start__; + +static void setup_nvic(void) { + +nvic_init((uint32)VECT_TAB_ADDR, 0); + +/* Roger Clark. We now control nvic vector table in boards.txt using the build.vect paramater +#ifdef VECT_TAB_FLASH + nvic_init(USER_ADDR_ROM, 0); +#elif defined VECT_TAB_RAM + nvic_init(USER_ADDR_RAM, 0); +#elif defined VECT_TAB_BASE + nvic_init((uint32)0x08000000, 0); +#elif defined VECT_TAB_ADDR + // A numerically supplied value + nvic_init((uint32)VECT_TAB_ADDR, 0); +#else + // Use the __text_start__ value from the linker script; this + // should be the start of the vector table. + nvic_init((uint32)&__text_start__, 0); +#endif + +*/ +} + +static void adc_default_config(adc_dev *dev) { + adc_enable_single_swstart(dev); + adc_set_sample_rate(dev, wirish::priv::w_adc_smp); +} + +static void setup_adcs(void) { + adc_set_prescaler(wirish::priv::w_adc_pre); + adc_foreach(adc_default_config); +} + +static void timer_default_config(timer_dev *dev) { + timer_adv_reg_map *regs = (dev->regs).adv; + const uint16 full_overflow = 0xFFFF; + const uint16 half_duty = 0x8FFF; + + timer_init(dev); + timer_pause(dev); + + regs->CR1 = TIMER_CR1_ARPE; + regs->PSC = 1; + regs->SR = 0; + regs->DIER = 0; + regs->EGR = TIMER_EGR_UG; + switch (dev->type) { + case TIMER_ADVANCED: + regs->BDTR = TIMER_BDTR_MOE | TIMER_BDTR_LOCK_OFF; + // fall-through + case TIMER_GENERAL: + timer_set_reload(dev, full_overflow); + for (uint8 channel = 1; channel <= 4; channel++) { + if (timer_has_cc_channel(dev, channel)) { + timer_set_compare(dev, channel, half_duty); + timer_oc_set_mode(dev, channel, TIMER_OC_MODE_PWM_1, + TIMER_OC_PE); + } + } + // fall-through + case TIMER_BASIC: + break; + } + + timer_generate_update(dev); + timer_resume(dev); +} + +static void setup_timers(void) { + timer_foreach(timer_default_config); +} diff --git a/buildroot/share/PlatformIO/variants/CHITU_F103/wirish/boards_setup.cpp b/buildroot/share/PlatformIO/variants/CHITU_F103/wirish/boards_setup.cpp new file mode 100755 index 000000000000..c3f524720d70 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/CHITU_F103/wirish/boards_setup.cpp @@ -0,0 +1,128 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2012 LeafLabs, LLC. + * + * 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. +*****************************************************************************/ + +/** + * @file wirish/stm32f1/boards_setup.cpp + * @author Marti Bolivar + * @brief STM32F1 chip setup. + * + * This file controls how init() behaves on the STM32F1. Be very + * careful when changing anything here. Many of these values depend + * upon each other. + */ + +#include "boards_private.h" + +#include +#include + +#include +#include + +// Allow boards to provide a PLL multiplier. This is useful for +// e.g. STM32F100 value line MCUs, which use slower multipliers. +// (We're leaving the default to RCC_PLLMUL_9 for now, since that +// works for F103 performance line MCUs, which is all that LeafLabs +// currently officially supports). +#ifndef BOARD_RCC_PLLMUL + #if !USE_HSI_CLOCK + #if F_CPU==128000000 + #define BOARD_RCC_PLLMUL RCC_PLLMUL_16 + #elif F_CPU==72000000 + #define BOARD_RCC_PLLMUL RCC_PLLMUL_9 + #elif F_CPU==48000000 + #define BOARD_RCC_PLLMUL RCC_PLLMUL_6 + #elif F_CPU==16000000 + #define BOARD_RCC_PLLMUL RCC_PLLMUL_2 + #endif + #else + #define BOARD_RCC_PLLMUL RCC_PLLMUL_16 + #endif +#endif + +namespace wirish { + namespace priv { + + static stm32f1_rcc_pll_data pll_data = {BOARD_RCC_PLLMUL}; +#if !USE_HSI_CLOCK + __weak rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSE, &pll_data}; +#else + __weak rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSI_DIV_2, &pll_data}; +#endif + __weak adc_prescaler w_adc_pre = ADC_PRE_PCLK2_DIV_6; + __weak adc_smp_rate w_adc_smp = ADC_SMPR_55_5; + + __weak void board_reset_pll(void) { + // TODO + } + + __weak void board_setup_clock_prescalers(void) { + rcc_set_prescaler(RCC_PRESCALER_AHB, RCC_AHB_SYSCLK_DIV_1); + rcc_set_prescaler(RCC_PRESCALER_APB1, RCC_APB1_HCLK_DIV_2); + rcc_set_prescaler(RCC_PRESCALER_APB2, RCC_APB2_HCLK_DIV_1); + rcc_clk_disable(RCC_USB); +#if F_CPU == 72000000 + rcc_set_prescaler(RCC_PRESCALER_USB, RCC_USB_SYSCLK_DIV_1_5); +#elif F_CPU == 48000000 + rcc_set_prescaler(RCC_PRESCALER_USB, RCC_USB_SYSCLK_DIV_1); +#endif + } + + __weak void board_setup_gpio(void) { + /** + * PA14 is a pull up pin. But, some V5 boards it start with LOW state! And just behave properly when the Z- PROBE is actived at least once. + * So, if the sensor isnt actived, the PA14 pin will be forever in LOW state, telling Marlin the probe IS ALWAYS ACTIVE, that isnt the case! + * Chitu original firmware seems to start with every pullup PIN with HIGH to workaround this. + * So we are doing the same here. + * This hack only works if applied *before* the GPIO Init, it's the reason I did it here. + */ + #ifdef CHITU_V5_Z_MIN_BUGFIX + GPIOA->regs->BSRR = (1U << PA14); + #endif + gpio_init_all(); + } + + __weak void board_setup_usb(void) { +#ifdef SERIAL_USB +#ifdef GENERIC_BOOTLOADER + // Reset the USB interface on generic boards - developed by Victor PV + gpio_set_mode(PIN_MAP[PA12].gpio_device, PIN_MAP[PA12].gpio_bit, GPIO_OUTPUT_PP); + gpio_write_bit(PIN_MAP[PA12].gpio_device, PIN_MAP[PA12].gpio_bit,0); + + for (volatile unsigned int i = 0; i < 512; i++); // Only small delay seems to be needed, and USB pins will get configured in Serial.begin + gpio_set_mode(PIN_MAP[PA12].gpio_device, PIN_MAP[PA12].gpio_bit, GPIO_INPUT_FLOATING); +#endif + Serial.begin(); // Roger Clark. Changed SerialUSB to Serial for Arduino sketch compatibility +#endif + } + + __weak void series_init(void) { + // Initialize AFIO here, too, so peripheral remaps and external + // interrupts work out of the box. + afio_init(); + } + } +} diff --git a/buildroot/share/PlatformIO/variants/CHITU_F103/wirish/start.S b/buildroot/share/PlatformIO/variants/CHITU_F103/wirish/start.S new file mode 100755 index 000000000000..8b181aa99313 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/CHITU_F103/wirish/start.S @@ -0,0 +1,57 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * 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. + *****************************************************************************/ + +/* + * This file is a modified version of a file obtained from + * CodeSourcery Inc. (now part of Mentor Graphics Corp.), in which the + * following text appeared: + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + + .text + .code 16 + .thumb_func + + .globl __start__ + .type __start__, %function +__start__: + .fnstart + ldr r1,=__msp_init + mov sp,r1 + ldr r1,=start_c + bx r1 + .pool + .cantunwind + .fnend diff --git a/buildroot/share/PlatformIO/variants/CHITU_F103/wirish/start_c.c b/buildroot/share/PlatformIO/variants/CHITU_F103/wirish/start_c.c new file mode 100755 index 000000000000..d305e6d5b920 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/CHITU_F103/wirish/start_c.c @@ -0,0 +1,144 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * 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. + *****************************************************************************/ + +/* + * This file is a modified version of a file obtained from + * CodeSourcery Inc. (now part of Mentor Graphics Corp.), in which the + * following text appeared: + * + * Copyright (c) 2006, 2007 CodeSourcery Inc + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include + +#include +#include +#include + +#include "rcc_private.h" + +#include +#include +#include "usart_private.h" + +#include +#include + +extern void __libc_init_array(void); + +extern int main(int, char**, char**); + +extern void exit(int) __attribute__((noreturn, weak)); + +/* The linker must ensure that these are at least 4-byte aligned. */ +extern char __data_start__, __data_end__; +extern char __bss_start__, __bss_end__; + +struct rom_img_cfg { + int *img_start; +}; + +extern char _lm_rom_img_cfgp; +extern void __lm_error(); +extern void timer_disable_all(); + + /* Turn off ADC */ +extern void adc_disable_all(); + + /* Turn off all USARTs */ +extern void usart_disable_all(); +extern void DisableEverything(); + +void __attribute__((noreturn)) start_c(void) { + struct rom_img_cfg *img_cfg = (struct rom_img_cfg*)&_lm_rom_img_cfgp; + int *src = img_cfg->img_start; + int *dst = (int*)&__data_start__; + int exit_code; + + asm("CPSID I"); + /* Reset the RCC clock configuration to the default reset state(for debug purpose) */ + /* Set HSION bit */ + RCC_BASE->CR |= 0x00000001U; + + /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */ + RCC_BASE->CFGR &= 0xF0FF0000U; + + /* Reset HSEON, CSSON and PLLON bits */ + RCC_BASE->CR &= 0xFEF6FFFFU; + + /* Reset HSEBYP bit */ + RCC_BASE->CR &= 0xFFFBFFFFU; + + /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */ + RCC_BASE->CFGR &= 0xFF80FFFFU; + + /* Disable all interrupts and clear pending bits */ + RCC_BASE->CIR = 0x009F0000U; + + USART1_BASE->CR1 = 0; + USART1_BASE->CR2 = 0; + USART1_BASE->CR3 = 0; + + memset(SDIO_BASE, 0, sizeof(sdio_reg_map)); + asm("CPSIE I"); + + /* Initialize .data, if necessary. */ + if (src != dst) { + int *end = (int*)&__data_end__; + while (dst < end) { + *dst++ = *src++; + } + } + + /* Zero .bss. */ + dst = (int*)&__bss_start__; + while (dst < (int*)&__bss_end__) { + *dst++ = 0; + } + + /* Run initializers. */ + __libc_init_array(); + + /* Jump to main. */ + exit_code = main(0, 0, 0); + if (exit) { + exit(exit_code); + } + + /* If exit is NULL, make sure we don't return. */ + for (;;) + continue; +} diff --git a/buildroot/share/PlatformIO/variants/CHITU_F103/wirish/syscalls.c b/buildroot/share/PlatformIO/variants/CHITU_F103/wirish/syscalls.c new file mode 100755 index 000000000000..ec1c34dbade4 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/CHITU_F103/wirish/syscalls.c @@ -0,0 +1,176 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * Copyright (c) 2011, 2012 LeafLabs, LLC. + * + * 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. + *****************************************************************************/ + +/** + * @file wirish/syscalls.c + * @brief newlib stubs + * + * Low level system routines used by newlib for basic I/O and memory + * allocation. You can override most of these. + */ + +#include + +#include +#include +#include + +/* If CONFIG_HEAP_START (or CONFIG_HEAP_END) isn't defined, then + * assume _lm_heap_start (resp. _lm_heap_end) is appropriately set by + * the linker */ +#ifndef CONFIG_HEAP_START +extern char _lm_heap_start; +#define CONFIG_HEAP_START ((void *)&_lm_heap_start) +#endif +#ifndef CONFIG_HEAP_END +extern char _lm_heap_end; +#define CONFIG_HEAP_END ((void *)&_lm_heap_end) +#endif + +/* + * _sbrk -- Increment the program break. + * + * Get incr bytes more RAM (for use by the heap). malloc() and + * friends call this function behind the scenes. + */ +void *_sbrk(int incr) { + static void * pbreak = NULL; /* current program break */ + void * ret; + + if (pbreak == NULL) { + pbreak = CONFIG_HEAP_START; + } + + if ((CONFIG_HEAP_END - pbreak < incr) || + (pbreak - CONFIG_HEAP_START < -incr)) { + errno = ENOMEM; + return (void *)-1; + } + + ret = pbreak; + pbreak += incr; + return ret; +} + +__weak int _open(const char *path __attribute__((unused)), int flags __attribute__((unused)), ...) { + return 1; +} + +__weak int _close(int fd __attribute__((unused))) { + return 0; +} + +__weak int _fstat(int fd __attribute__((unused)), struct stat *st) { + st->st_mode = S_IFCHR; + return 0; +} + +__weak int _isatty(int fd __attribute__((unused))) { + return 1; +} + +__weak int isatty(int fd __attribute__((unused))) { + return 1; +} + +__weak int _lseek(int fd __attribute__((unused)), off_t pos __attribute__((unused)), int whence __attribute__((unused))) { + return -1; +} + +__weak unsigned char getch(void) { + return 0; +} + + +__weak int _read(int fd __attribute__((unused)), char *buf, size_t cnt __attribute__((unused))) { + *buf = getch(); + + return 1; +} + +__weak void putch(unsigned char c __attribute__((unused))) { +} + +__weak void cgets(char *s, int bufsize) { + char *p; + int c; + int i; + + for (i = 0; i < bufsize; i++) { + *(s+i) = 0; + } +// memset(s, 0, bufsize); + + p = s; + + for (p = s; p < s + bufsize-1;) { + c = getch(); + switch (c) { + case '\r' : + case '\n' : + putch('\r'); + putch('\n'); + *p = '\n'; + return; + + case '\b' : + if (p > s) { + *p-- = 0; + putch('\b'); + putch(' '); + putch('\b'); + } + break; + + default : + putch(c); + *p++ = c; + break; + } + } + return; +} + +__weak int _write(int fd __attribute__((unused)), const char *buf, size_t cnt) { + int i; + + for (i = 0; i < cnt; i++) + putch(buf[i]); + + return cnt; +} + +/* Override fgets() in newlib with a version that does line editing */ +__weak char *fgets(char *s, int bufsize, void *f __attribute__((unused))) { + cgets(s, bufsize); + return s; +} + +__weak void _exit(int exitcode __attribute__((unused))) { + while (1) + ; +} diff --git a/buildroot/share/PlatformIO/variants/FLY_F407ZG/PeripheralPins.c b/buildroot/share/PlatformIO/variants/FLY_F407ZG/PeripheralPins.c index 5cce88b175a0..f0f2c4b80c43 100644 --- a/buildroot/share/PlatformIO/variants/FLY_F407ZG/PeripheralPins.c +++ b/buildroot/share/PlatformIO/variants/FLY_F407ZG/PeripheralPins.c @@ -31,7 +31,6 @@ #include #include - /* ===== * Note: Commented lines are alternative possibilities which are not used per default. * If you change them, you will have to know what you do @@ -41,54 +40,54 @@ //*** ADC *** #ifdef HAL_ADC_MODULE_ENABLED -const PinMap PinMap_ADC[] = { +WEAK const PinMap PinMap_ADC[] = { {PA_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC1_IN0 - // {PA_0, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC2_IN0 - // {PA_0, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC3_IN0 - {PA_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC1_IN1 - // {PA_1, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC2_IN1 - // {PA_1, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC3_IN1 - // {PA_2, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC1_IN2 - {PA_2, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC2_IN2 - // {PA_2, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC3_IN2 - // {PA_3, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC1_IN3 - // {PA_3, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC2_IN3 - {PA_3, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC3_IN3 - {PA_4, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC1_IN4 - // {PA_4, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC2_IN4 - // {PA_5, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC1_IN5 - {PA_5, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC2_IN5 - {PA_6, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC1_IN6 - // {PA_6, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC2_IN6 - {PA_7, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC1_IN7 - // {PA_7, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC2_IN7 - // {PB_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC1_IN8 - {PB_0, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC2_IN8 - {PB_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC1_IN9 - // {PB_1, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC2_IN9 - // {PC_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC1_IN10 - // {PC_0, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC2_IN10 + //{PA_0, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC2_IN0 + //{PA_0, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC3_IN0 + //{PA_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC1_IN1 + //{PA_1, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC2_IN1 + //{PA_1, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC3_IN1 + //{PA_2, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC1_IN2 + //{PA_2, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC2_IN2 + //{PA_2, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC3_IN2 + //{PA_3, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC1_IN3 + //{PA_3, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC2_IN3 + //{PA_3, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC3_IN3 + //{PA_4, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC1_IN4 + //{PA_4, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC2_IN4 + //{PA_5, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC1_IN5 + //{PA_5, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC2_IN5 + //{PA_6, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC1_IN6 + //{PA_6, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC2_IN6 + //{PA_7, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC1_IN7 + //{PA_7, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC2_IN7 + //{PB_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC1_IN8 + //{PB_0, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC2_IN8 + //{PB_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC1_IN9 + //{PB_1, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC2_IN9 + //{PC_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC1_IN10 + //{PC_0, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC2_IN10 {PC_0, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC3_IN10 {PC_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC1_IN11 - // {PC_1, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC2_IN11 - // {PC_1, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC3_IN11 - // {PC_2, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC1_IN12 - {PC_2, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC2_IN12 - // {PC_2, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC3_IN12 - // {PC_3, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC1_IN13 - // {PC_3, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC2_IN13 - {PC_3, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC3_IN13 - // {PC_4, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 14, 0)}, // ADC1_IN14 - {PC_4, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 14, 0)}, // ADC2_IN14 - // {PC_5, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 15, 0)}, // ADC1_IN15 - {PC_5, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 15, 0)}, // ADC2_IN15 + //{PC_1, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC2_IN11 + //{PC_1, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC3_IN11 + //{PC_2, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC1_IN12 + //{PC_2, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC2_IN12 + //{PC_2, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC3_IN12 + //{PC_3, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC1_IN13 + //{PC_3, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC2_IN13 + //{PC_3, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC3_IN13 + //{PC_4, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 14, 0)}, // ADC1_IN14 + //{PC_4, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 14, 0)}, // ADC2_IN14 + //{PC_5, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 15, 0)}, // ADC1_IN15 + //{PC_5, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 15, 0)}, // ADC2_IN15 {PF_3, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC3_IN9 {PF_4, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 14, 0)}, // ADC3_IN14 {PF_5, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 15, 0)}, // ADC3_IN15 - {PF_6, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC3_IN4 - {PF_7, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC3_IN5 - {PF_8, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC3_IN6 - // {PF_9, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC3_IN7 + //{PF_6, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC3_IN4 + //{PF_7, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC3_IN5 + //{PF_8, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC3_IN6 + //{PF_9, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC3_IN7 {PF_10, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC3_IN8 {NC, NP, 0} }; @@ -97,9 +96,9 @@ const PinMap PinMap_ADC[] = { //*** DAC *** #ifdef HAL_DAC_MODULE_ENABLED -const PinMap PinMap_DAC[] = { - {PA_4, DAC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // DAC_OUT1 - {PA_5, DAC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // DAC_OUT2 +WEAK const PinMap PinMap_DAC[] = { + //{PA_4, DAC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // DAC_OUT1 + //{PA_5, DAC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // DAC_OUT2 {NC, NP, 0} }; #endif @@ -107,23 +106,21 @@ const PinMap PinMap_DAC[] = { //*** I2C *** #ifdef HAL_I2C_MODULE_ENABLED -const PinMap PinMap_I2C_SDA[] = { +WEAK const PinMap PinMap_I2C_SDA[] = { {PB_7, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)}, - {PB_9, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)}, - {PB_11, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, - {PC_9, I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)}, - {PF_0, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, + //{PB_9, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)}, + //{PB_11, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, + //{PC_9, I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)}, + //{PF_0, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, {NC, NP, 0} }; -#endif -#ifdef HAL_I2C_MODULE_ENABLED -const PinMap PinMap_I2C_SCL[] = { - {PA_8, I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)}, +WEAK const PinMap PinMap_I2C_SCL[] = { + //{PA_8, I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)}, {PB_6, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)}, - {PB_8, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)}, - {PB_10, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, - {PF_1, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, + //{PB_8, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)}, + //{PB_10, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, + //{PF_1, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, {NC, NP, 0} }; #endif @@ -131,79 +128,79 @@ const PinMap PinMap_I2C_SCL[] = { //*** PWM *** #ifdef HAL_TIM_MODULE_ENABLED -const PinMap PinMap_PWM[] = { - {PA_0, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1 - // {PA_0, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 1, 0)}, // TIM5_CH1 +WEAK const PinMap PinMap_PWM[] = { {PA_1, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 2, 0)}, // TIM2_CH2 - // {PA_1, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 2, 0)}, // TIM5_CH2 {PA_2, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3 - // {PA_2, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 3, 0)}, // TIM5_CH3 - // {PA_2, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 1, 0)}, // TIM9_CH1 - {PA_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 4, 0)}, // TIM2_CH4 - // {PA_3, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 4, 0)}, // TIM5_CH4 - // {PA_3, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 2, 0)}, // TIM9_CH2 - {PA_5, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1 - // {PA_5, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 1, 1)}, // TIM8_CH1N - {PA_6, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 1, 0)}, // TIM3_CH1 - // {PA_6, TIM13, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM13, 1, 0)}, // TIM13_CH1 - // {PA_7, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 1)}, // TIM1_CH1N - {PA_7, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 2, 0)}, // TIM3_CH2 - // {PA_7, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 1, 1)}, // TIM8_CH1N - // {PA_7, TIM14, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM14, 1, 0)}, // TIM14_CH1 {PA_8, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 0)}, // TIM1_CH1 - {PA_9, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 0)}, // TIM1_CH2 - {PA_10, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 0)}, // TIM1_CH3 - {PA_11, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 4, 0)}, // TIM1_CH4 - // {PA_15, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1 - // {PB_0, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 1)}, // TIM1_CH2N - {PB_0, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 3, 0)}, // TIM3_CH3 - // {PB_0, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 2, 1)}, // TIM8_CH2N - // {PB_1, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 1)}, // TIM1_CH3N - {PB_1, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 4, 0)}, // TIM3_CH4 - // {PB_1, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 3, 1)}, // TIM8_CH3N - // {PB_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 2, 0)}, // TIM2_CH2 - {PB_4, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 1, 0)}, // TIM3_CH1 - {PB_5, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 2, 0)}, // TIM3_CH2 - {PB_6, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 1, 0)}, // TIM4_CH1 - {PB_7, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 2, 0)}, // TIM4_CH2 {PB_8, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 3, 0)}, // TIM4_CH3 - {PB_8, TIM10, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM10, 1, 0)}, // TIM10_CH1 {PB_9, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 4, 0)}, // TIM4_CH4 - {PB_9, TIM11, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM11, 1, 0)}, // TIM11_CH1 - {PB_10, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3 {PB_11, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 4, 0)}, // TIM2_CH4 - {PB_13, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 1)}, // TIM1_CH1N - {PB_14, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 1)}, // TIM1_CH2N - {PB_14, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 2, 1)}, // TIM8_CH2N - {PB_14, TIM12, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM12, 1, 0)}, // TIM12_CH1 - {PB_15, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 1)}, // TIM1_CH3N - {PB_15, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 3, 1)}, // TIM8_CH3N - {PB_15, TIM12, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM12, 2, 0)}, // TIM12_CH2 {PC_6, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 1, 0)}, // TIM3_CH1 - {PC_6, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 1, 0)}, // TIM8_CH1 {PC_7, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 2, 0)}, // TIM3_CH2 - {PC_7, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 2, 0)}, // TIM8_CH2 - {PC_8, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 3, 0)}, // TIM3_CH3 - {PC_8, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 3, 0)}, // TIM8_CH3 - {PC_9, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 4, 0)}, // TIM3_CH4 - {PC_9, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 4, 0)}, // TIM8_CH4 {PD_12, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 1, 0)}, // TIM4_CH1 {PD_13, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 2, 0)}, // TIM4_CH2 {PD_14, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 3, 0)}, // TIM4_CH3 {PD_15, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 4, 0)}, // TIM4_CH4 {PE_5, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 1, 0)}, // TIM9_CH1 {PE_6, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 2, 0)}, // TIM9_CH2 - {PE_8, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 1)}, // TIM1_CH1N - {PE_9, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 0)}, // TIM1_CH1 - {PE_10, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 1)}, // TIM1_CH2N - {PE_11, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 0)}, // TIM1_CH2 - {PE_12, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 1)}, // TIM1_CH3N - {PE_13, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 0)}, // TIM1_CH3 - {PE_14, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 4, 0)}, // TIM1_CH4 + //{PE_11, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 0)}, // TIM1_CH2 + //{PE_13, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 0)}, // TIM1_CH3 {PF_6, TIM10, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM10, 1, 0)}, // TIM10_CH1 {PF_7, TIM11, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM11, 1, 0)}, // TIM11_CH1 {PF_8, TIM13, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM13, 1, 0)}, // TIM13_CH1 {PF_9, TIM14, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM14, 1, 0)}, // TIM14_CH1 + //{PA_0, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1 + //{PA_0, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 1, 0)}, // TIM5_CH1 + //{PA_1, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 2, 0)}, // TIM5_CH2 + //{PA_2, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 3, 0)}, // TIM5_CH3 + //{PA_2, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 1, 0)}, // TIM9_CH1 + //{PA_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 4, 0)}, // TIM2_CH4 + //{PA_3, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 4, 0)}, // TIM5_CH4 + //{PA_3, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 2, 0)}, // TIM9_CH2 + //{PA_5, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1 + //{PA_5, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 1, 1)}, // TIM8_CH1N + //{PA_6, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 1, 0)}, // TIM3_CH1 + //{PA_6, TIM13, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM13, 1, 0)}, // TIM13_CH1 + //{PA_7, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 1)}, // TIM1_CH1N + //{PA_7, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 2, 0)}, // TIM3_CH2 + //{PA_7, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 1, 1)}, // TIM8_CH1N + //{PA_7, TIM14, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM14, 1, 0)}, // TIM14_CH1 + //{PA_9, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 0)}, // TIM1_CH2 + //{PA_10, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 0)}, // TIM1_CH3 + //{PA_11, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 4, 0)}, // TIM1_CH4 + //{PA_15, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1 + //{PB_0, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 1)}, // TIM1_CH2N + //{PB_0, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 3, 0)}, // TIM3_CH3 + //{PB_0, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 2, 1)}, // TIM8_CH2N + //{PB_1, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 1)}, // TIM1_CH3N + //{PB_1, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 4, 0)}, // TIM3_CH4 + //{PB_1, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 3, 1)}, // TIM8_CH3N + //{PB_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 2, 0)}, // TIM2_CH2 + //{PB_4, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 1, 0)}, // TIM3_CH1 + //{PB_5, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 2, 0)}, // TIM3_CH2 + //{PB_6, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 1, 0)}, // TIM4_CH1 + //{PB_7, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 2, 0)}, // TIM4_CH2 + //{PB_8, TIM10, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM10, 1, 0)}, // TIM10_CH1 + //{PB_9, TIM11, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM11, 1, 0)}, // TIM11_CH1 + //{PB_10, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3 + //{PB_13, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 1)}, // TIM1_CH1N + //{PB_14, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 1)}, // TIM1_CH2N + //{PB_14, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 2, 1)}, // TIM8_CH2N + //{PB_14, TIM12, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM12, 1, 0)}, // TIM12_CH1 + //{PB_15, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 1)}, // TIM1_CH3N + //{PB_15, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 3, 1)}, // TIM8_CH3N + //{PB_15, TIM12, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM12, 2, 0)}, // TIM12_CH2 + //{PC_6, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 1, 0)}, // TIM8_CH1 + //{PC_7, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 2, 0)}, // TIM8_CH2 + //{PC_8, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 3, 0)}, // TIM3_CH3 + //{PC_8, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 3, 0)}, // TIM8_CH3 + //{PC_9, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 4, 0)}, // TIM3_CH4 + //{PC_9, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 4, 0)}, // TIM8_CH4 + //{PE_8, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 1)}, // TIM1_CH1N + //{PE_9, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 0)}, // TIM1_CH1 + //{PE_10, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 1)}, // TIM1_CH2N + //{PE_12, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 1)}, // TIM1_CH3N + //{PE_14, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 4, 0)}, // TIM1_CH4 {NC, NP, 0} }; #endif @@ -211,63 +208,57 @@ const PinMap PinMap_PWM[] = { //*** SERIAL *** #ifdef HAL_UART_MODULE_ENABLED -const PinMap PinMap_UART_TX[] = { - {PA_0, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, - {PA_2, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, +WEAK const PinMap PinMap_UART_TX[] = { + //{PA_0, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, + //{PA_2, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, {PA_9, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, - {PB_6, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, - {PB_10, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, - {PC_6, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, - // {PC_10, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, - {PC_10, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, - {PC_12, UART5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)}, - {PD_5, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, - {PD_8, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + //{PB_6, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, + //{PB_10, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + //{PC_6, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, + //{PC_10, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, + //{PC_10, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + //{PC_12, UART5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)}, + //{PD_5, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + //{PD_8, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, {PG_14, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, {NC, NP, 0} }; -#endif -#ifdef HAL_UART_MODULE_ENABLED -const PinMap PinMap_UART_RX[] = { - {PA_1, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, - {PA_3, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, +WEAK const PinMap PinMap_UART_RX[] = { + //{PA_1, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, + //{PA_3, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, {PA_10, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, - {PB_7, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, - {PB_11, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, - {PC_7, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, - // {PC_11, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, - {PC_11, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, - {PD_2, UART5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)}, - {PD_6, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, - {PD_9, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + //{PB_7, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, + //{PB_11, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + //{PC_7, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, + //{PC_11, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, + //{PC_11, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + //{PD_2, UART5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)}, + //{PD_6, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + //{PD_9, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, {PG_9, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, {NC, NP, 0} }; -#endif -#ifdef HAL_UART_MODULE_ENABLED -const PinMap PinMap_UART_RTS[] = { - {PA_1, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, - {PA_12, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, - {PB_14, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, - {PD_4, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, - {PD_12, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, - {PG_8, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, - {PG_12, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, +WEAK const PinMap PinMap_UART_RTS[] = { + //{PA_1, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + //{PA_12, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, + //{PB_14, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + //{PD_4, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + //{PD_12, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + //{PG_8, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, + //{PG_12, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, {NC, NP, 0} }; -#endif -#ifdef HAL_UART_MODULE_ENABLED -const PinMap PinMap_UART_CTS[] = { - {PA_0, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, - {PA_11, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, - {PB_13, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, - {PD_3, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, - {PD_11, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, - {PG_13, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, - {PG_15, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, +WEAK const PinMap PinMap_UART_CTS[] = { + //{PA_0, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + //{PA_11, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, + //{PB_13, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + //{PD_3, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + //{PD_11, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + //{PG_13, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, + //{PG_15, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, {NC, NP, 0} }; #endif @@ -275,49 +266,43 @@ const PinMap PinMap_UART_CTS[] = { //*** SPI *** #ifdef HAL_SPI_MODULE_ENABLED -const PinMap PinMap_SPI_MOSI[] = { +WEAK const PinMap PinMap_SPI_MOSI[] = { {PA_7, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, - {PB_5, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, + //{PB_5, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, {PB_5, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, {PB_15, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, - {PC_3, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, - {PC_12, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + //{PC_3, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + //{PC_12, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, {NC, NP, 0} }; -#endif -#ifdef HAL_SPI_MODULE_ENABLED -const PinMap PinMap_SPI_MISO[] = { +WEAK const PinMap PinMap_SPI_MISO[] = { {PA_6, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, - {PB_4, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, + //{PB_4, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, {PB_4, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, {PB_14, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, - {PC_2, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, - {PC_11, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + //{PC_2, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + //{PC_11, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, {NC, NP, 0} }; -#endif -#ifdef HAL_SPI_MODULE_ENABLED -const PinMap PinMap_SPI_SCLK[] = { +WEAK const PinMap PinMap_SPI_SCLK[] = { {PA_5, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, - {PB_3, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, + //{PB_3, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, {PB_3, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, - {PB_10, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + //{PB_10, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, {PB_13, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, - {PC_10, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + //{PC_10, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, {NC, NP, 0} }; -#endif -#ifdef HAL_SPI_MODULE_ENABLED -const PinMap PinMap_SPI_SSEL[] = { +WEAK const PinMap PinMap_SPI_SSEL[] = { {PA_4, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, - {PA_4, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, - {PA_15, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, - {PA_15, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, - {PB_9, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, - {PB_12, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + //{PA_4, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + //{PA_15, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, + //{PA_15, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + //{PB_9, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + //{PB_12, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, {NC, NP, 0} }; #endif @@ -325,23 +310,21 @@ const PinMap PinMap_SPI_SSEL[] = { //*** CAN *** #ifdef HAL_CAN_MODULE_ENABLED -const PinMap PinMap_CAN_RD[] = { - {PA_11, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, - {PB_5, CAN2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)}, - {PB_8, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, - {PB_12, CAN2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)}, - {PD_0, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, +WEAK const PinMap PinMap_CAN_RD[] = { + //{PA_11, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, + //{PB_5, CAN2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)}, + //{PB_8, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, + //{PB_12, CAN2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)}, + //{PD_0, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, {NC, NP, 0} }; -#endif -#ifdef HAL_CAN_MODULE_ENABLED -const PinMap PinMap_CAN_TD[] = { - {PA_12, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, - {PB_6, CAN2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)}, - {PB_9, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, - {PB_13, CAN2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)}, - {PD_1, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, +WEAK const PinMap PinMap_CAN_TD[] = { + //{PA_12, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, + //{PB_6, CAN2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)}, + //{PB_9, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, + //{PB_13, CAN2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)}, + //{PD_1, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, {NC, NP, 0} }; #endif @@ -349,7 +332,8 @@ const PinMap PinMap_CAN_TD[] = { //*** ETHERNET *** #ifdef HAL_ETH_MODULE_ENABLED -const PinMap PinMap_Ethernet[] = { +WEAK const PinMap PinMap_Ethernet[] = { + /* {PA_0, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_CRS {PA_1, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_REF_CLK|ETH_RX_CLK {PA_2, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_MDIO @@ -374,6 +358,7 @@ const PinMap PinMap_Ethernet[] = { {PG_13, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TXD0 {PG_14, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TXD1 {NC, NP, 0} + */ }; #endif @@ -382,38 +367,38 @@ const PinMap PinMap_Ethernet[] = { //*** USB *** #ifdef HAL_PCD_MODULE_ENABLED -const PinMap PinMap_USB_OTG_FS[] = { - // {PA_8, USB_OTG_FS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_FS)}, // USB_OTG_FS_SOF - // {PA_9, USB_OTG_FS, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF_NONE)}, // USB_OTG_FS_VBUS - // {PA_10, USB_OTG_FS, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_PULLUP, GPIO_AF10_OTG_FS)}, // USB_OTG_FS_ID +WEAK const PinMap PinMap_USB_OTG_FS[] = { + //{PA_8, USB_OTG_FS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_FS)}, // USB_OTG_FS_SOF + //{PA_9, USB_OTG_FS, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF_NONE)}, // USB_OTG_FS_VBUS + //{PA_10, USB_OTG_FS, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_PULLUP, GPIO_AF10_OTG_FS)}, // USB_OTG_FS_ID {PA_11, USB_OTG_FS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_FS)}, // USB_OTG_FS_DM {PA_12, USB_OTG_FS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_FS)}, // USB_OTG_FS_DP {NC, NP, 0} }; -#endif -#ifdef HAL_PCD_MODULE_ENABLED -const PinMap PinMap_USB_OTG_HS[] = { -#ifdef USE_USB_HS_IN_FS - {PA_4, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_SOF - {PB_12, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_ID - {PB_13, USB_OTG_HS, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF_NONE)}, // USB_OTG_HS_VBUS - {PB_14, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_DM - {PB_15, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_DP -#else - {PA_3, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D0 - {PA_5, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_CK - {PB_0, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D1 - {PB_1, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D2 - {PB_5, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D7 - {PB_10, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D3 - {PB_11, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D4 - {PB_12, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D5 - {PB_13, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D6 - {PC_0, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_STP - {PC_2, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_DIR - {PC_3, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_NXT -#endif /* USE_USB_HS_IN_FS */ +WEAK const PinMap PinMap_USB_OTG_HS[] = { + /* + #ifdef USE_USB_HS_IN_FS + {PA_4, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_SOF + {PB_12, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_ID + {PB_13, USB_OTG_HS, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF_NONE)}, // USB_OTG_HS_VBUS + {PB_14, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_DM + {PB_15, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_DP + #else + {PA_3, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D0 + {PA_5, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_CK + {PB_0, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D1 + {PB_1, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D2 + {PB_5, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D7 + {PB_10, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D3 + {PB_11, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D4 + {PB_12, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D5 + {PB_13, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D6 + {PC_0, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_STP + {PC_2, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_DIR + {PC_3, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_NXT + #endif // USE_USB_HS_IN_FS + */ {NC, NP, 0} }; #endif diff --git a/buildroot/share/PlatformIO/variants/FLY_F407ZG/PinNamesVar.h b/buildroot/share/PlatformIO/variants/FLY_F407ZG/PinNamesVar.h index f3c4f0ee0762..b4bb9d45f8ac 100644 --- a/buildroot/share/PlatformIO/variants/FLY_F407ZG/PinNamesVar.h +++ b/buildroot/share/PlatformIO/variants/FLY_F407ZG/PinNamesVar.h @@ -1,50 +1,50 @@ /* SYS_WKUP */ #ifdef PWR_WAKEUP_PIN1 -SYS_WKUP1 = PA_0, + SYS_WKUP1 = PA_0, #endif #ifdef PWR_WAKEUP_PIN2 -SYS_WKUP2 = NC, + SYS_WKUP2 = NC, #endif #ifdef PWR_WAKEUP_PIN3 -SYS_WKUP3 = NC, + SYS_WKUP3 = NC, #endif #ifdef PWR_WAKEUP_PIN4 -SYS_WKUP4 = NC, + SYS_WKUP4 = NC, #endif #ifdef PWR_WAKEUP_PIN5 -SYS_WKUP5 = NC, + SYS_WKUP5 = NC, #endif #ifdef PWR_WAKEUP_PIN6 -SYS_WKUP6 = NC, + SYS_WKUP6 = NC, #endif #ifdef PWR_WAKEUP_PIN7 -SYS_WKUP7 = NC, + SYS_WKUP7 = NC, #endif #ifdef PWR_WAKEUP_PIN8 -SYS_WKUP8 = NC, + SYS_WKUP8 = NC, #endif /* USB */ #ifdef USBCON -USB_OTG_FS_SOF = PA_8, -USB_OTG_FS_VBUS = PA_9, -USB_OTG_FS_ID = PA_10, -USB_OTG_FS_DM = PA_11, -USB_OTG_FS_DP = PA_12, -USB_OTG_HS_ULPI_D0 = PA_3, -USB_OTG_HS_SOF = PA_4, -USB_OTG_HS_ULPI_CK = PA_5, -USB_OTG_HS_ULPI_D1 = PB_0, -USB_OTG_HS_ULPI_D2 = PB_1, -USB_OTG_HS_ULPI_D7 = PB_5, -USB_OTG_HS_ULPI_D3 = PB_10, -USB_OTG_HS_ULPI_D4 = PB_11, -USB_OTG_HS_ID = PB_12, -USB_OTG_HS_ULPI_D5 = PB_12, -USB_OTG_HS_ULPI_D6 = PB_13, -USB_OTG_HS_VBUS = PB_13, -USB_OTG_HS_DM = PB_14, -USB_OTG_HS_DP = PB_15, -USB_OTG_HS_ULPI_STP = PC_0, -USB_OTG_HS_ULPI_DIR = PC_2, -USB_OTG_HS_ULPI_NXT = PC_3, + USB_OTG_FS_SOF = PA_8, + USB_OTG_FS_VBUS = PA_9, + USB_OTG_FS_ID = PA_10, + USB_OTG_FS_DM = PA_11, + USB_OTG_FS_DP = PA_12, + USB_OTG_HS_ULPI_D0 = PA_3, + USB_OTG_HS_SOF = PA_4, + USB_OTG_HS_ULPI_CK = PA_5, + USB_OTG_HS_ULPI_D1 = PB_0, + USB_OTG_HS_ULPI_D2 = PB_1, + USB_OTG_HS_ULPI_D7 = PB_5, + USB_OTG_HS_ULPI_D3 = PB_10, + USB_OTG_HS_ULPI_D4 = PB_11, + USB_OTG_HS_ID = PB_12, + USB_OTG_HS_ULPI_D5 = PB_12, + USB_OTG_HS_ULPI_D6 = PB_13, + USB_OTG_HS_VBUS = PB_13, + USB_OTG_HS_DM = PB_14, + USB_OTG_HS_DP = PB_15, + USB_OTG_HS_ULPI_STP = PC_0, + USB_OTG_HS_ULPI_DIR = PC_2, + USB_OTG_HS_ULPI_NXT = PC_3, #endif diff --git a/buildroot/share/PlatformIO/variants/FLY_F407ZG/variant.cpp b/buildroot/share/PlatformIO/variants/FLY_F407ZG/variant.cpp index 82cfc573dce2..1c7aedd9ac9c 100644 --- a/buildroot/share/PlatformIO/variants/FLY_F407ZG/variant.cpp +++ b/buildroot/share/PlatformIO/variants/FLY_F407ZG/variant.cpp @@ -36,118 +36,120 @@ extern "C" { const PinName digitalPin[] = { - PB_12, - PB_13, - PB_14, - PB_15, - PD_8, - PD_9, - PD_10, - PD_11, - PD_12, - PD_13, - PD_14, - PD_15, - PG_2, - PG_3, - PG_4, - PG_5, - PG_6, - PG_7, - PG_8, - PC_6, - PC_7, - PC_8, - PC_9, - PA_8, - PA_9, - PA_10, - PA_11, - PA_12, - PA_13, - PA_14, - PA_15, - PC_10, - PC_11, - PC_12, - PD_0, - PD_1, - PD_2, - PD_3, - PD_4, - PD_5, - PD_6, - PD_7, - PG_9, - PG_10, - PG_11, - PG_12, - PG_13, - PG_14, - PG_15, - PB_3, - PB_4, - PB_5, - PB_6, - PB_7, - PB_8, - PB_9, - PB_10, - PB_11, - PE_14, - PE_15, - PE_12, - PE_13, - PE_10, - PE_11, - PE_8, - PE_9, - PG_1, - PE_7, - PF_15, - PG_0, - PF_13, - PF_14, - PF_11, - PF_12, - PB_2, - PB_1, - PC_5, - PB_0, - PA_7, - PC_4, - PA_5, - PA_6, - PA_3, - PA_4, - PA_1, - PA_2, - PC_3, - PA_0, - PC_1, - PC_2, - PC_0, - PF_8, - PF_6, - PF_7, - PF_9, - PF_10, - PF_4, - PF_5, - PF_2, - PF_3, - PF_0, - PF_1, - PE_6, - PC_13, - PE_4, - PE_5, - PE_2, - PE_3, - PE_0, - PE_1, - PC_14, - PC_15, +PA_1, +PA_2, +PA_3, +PA_4, +PA_5, +PA_6, +PA_7, +PA_8, +PA_9, +PA_10, +PA_11, +PA_12, +PA_13, +PA_14, +PA_15, +PB_0, +PB_1, +PB_2, +PB_3, +PB_4, +PB_5, +PB_6, +PB_7, +PB_8, +PB_9, +PB_10, +PB_11, +PB_12, +PB_13, +PB_14, +PB_15, +PC_2, +PC_3, +PC_4, +PC_5, +PC_6, +PC_7, +PC_8, +PC_9, +PC_10, +PC_11, +PC_12, +PC_13, +PC_14, +PC_15, +PD_0, +PD_1, +PD_2, +PD_3, +PD_4, +PD_5, +PD_6, +PD_7, +PD_8, +PD_9, +PD_10, +PD_11, +PD_12, +PD_13, +PD_14, +PD_15, +PE_0, +PE_1, +PE_11, +PE_3, +PE_4, +PE_5, +PE_6, +PE_7, +PE_8, +PE_9, +PE_10, +PE_2, +PE_12, +PE_13, +PE_14, +PE_15, +PF_0, +PF_1, +PF_2, +PF_6, +PF_7, +PF_8, +PF_9, +PF_11, +PF_12, +PF_13, +PF_14, +PF_15, +PG_0, +PG_1, +PG_2, +PG_3, +PG_4, +PG_5, +PG_6, +PG_7, +PG_8, +PG_9, +PG_10, +PG_11, +PG_12, +PG_13, +PG_14, +PG_15, +PH_0, +PH_1, +PA_0, +PC_1, +PC_0, +PF_10, +PF_5, +PF_4, +PF_3, }; #ifdef __cplusplus diff --git a/buildroot/share/PlatformIO/variants/FLY_F407ZG/variant.h b/buildroot/share/PlatformIO/variants/FLY_F407ZG/variant.h index 87033a68e5f6..ae973c89c527 100644 --- a/buildroot/share/PlatformIO/variants/FLY_F407ZG/variant.h +++ b/buildroot/share/PlatformIO/variants/FLY_F407ZG/variant.h @@ -38,126 +38,127 @@ extern "C" { * Pins *----------------------------------------------------------------------------*/ -// Left Side -#define PB12 0 -#define PB13 1 -#define PB14 2 -#define PB15 3 -#define PD8 4 -#define PD9 5 -#define PD10 6 -#define PD11 7 -#define PD12 8 -#define PD13 9 -#define PD14 10 -#define PD15 11 -#define PG2 12 -#define PG3 13 -#define PG4 14 -#define PG5 15 -#define PG6 16 -#define PG7 17 -#define PG8 18 -#define PC6 19 -#define PC7 20 -#define PC8 21 -#define PC9 22 -#define PA8 23 -#define PA9 24 -#define PA10 25 -#define PA11 26 // USB_DM -#define PA12 27 // USB_DP -#define PA13 28 -#define PA14 29 -#define PA15 30 -#define PC10 31 -#define PC11 32 -#define PC12 33 -#define PD0 34 -#define PD1 35 -#define PD2 36 -#define PD3 37 -#define PD4 38 -#define PD5 39 -#define PD6 40 -#define PD7 41 -#define PG9 42 -#define PG10 43 -#define PG11 44 -#define PG12 45 -#define PG13 46 -#define PG14 47 -#define PG15 48 -#define PB3 49 -#define PB4 50 -#define PB5 51 -#define PB6 52 -#define PB7 53 -#define PB8 54 -#define PB9 55 - -// Right Side -#define PB10 56 -#define PB11 57 -#define PE14 58 -#define PE15 59 -#define PE12 60 -#define PE13 61 -#define PE10 62 -#define PE11 63 -#define PE8 64 -#define PE9 65 -#define PG1 66 -#define PE7 67 -#define PF15 68 -#define PG0 69 -#define PF13 70 -#define PF14 71 -#define PF11 72 -#define PF12 73 -#define PB2 74 -#define PB1 75 // A0 -#define PC5 76 // A1 -#define PB0 77 // A2 -#define PA7 78 // A3 -#define PC4 79 // A4 -#define PA5 80 // A5 -#define PA6 81 // A6 -#define PA3 82 // A7 -#define PA4 83 // A8 -#define PA1 84 // A9 -#define PA2 85 // A10 -#define PC3 86 // A11 -#define PA0 87 // A12/PA_0(WK_UP): BUT K_UP) -#define PC1 88 // A13 -#define PC2 89 // A14 -#define PC0 90 // A15 -#define PF8 91 // A16 -#define PF6 92 // A17 -#define PF7 93 // A18 -#define PF9 94 // LED D1 (active low) -#define PF10 95 // LED D2 (active low) -#define PF4 96 -#define PF5 97 -#define PF2 98 -#define PF3 99 -#define PF0 100 -#define PF1 101 -#define PE6 102 -#define PC13 103 -#define PE4 104 // BUT K0 -#define PE5 105 // BUT K1 -#define PE2 106 -#define PE3 107 -#define PE0 108 -#define PE1 109 -#define PC14 110 -#define PC15 111 + +#define PA1 0 +#define PA2 1 +#define PA3 2 +#define PA4 3 +#define PA5 4 +#define PA6 5 +#define PA7 6 +#define PA8 7 +#define PA9 8 +#define PA10 9 +#define PA11 10 +#define PA12 11 +#define PA13 12 +#define PA14 13 +#define PA15 14 +#define PB0 15 +#define PB1 16 +#define PB2 17 +#define PB3 18 +#define PB4 19 +#define PB5 20 +#define PB6 21 +#define PB7 22 +#define PB8 23 +#define PB9 24 +#define PB10 25 +#define PB11 26 +#define PB12 27 +#define PB13 28 +#define PB14 29 +#define PB15 30 +#define PC2 31 +#define PC3 32 +#define PC4 33 +#define PC5 34 +#define PC6 35 +#define PC7 36 +#define PC8 37 +#define PC9 38 +#define PC10 39 +#define PC11 40 +#define PC12 41 +#define PC13 42 +#define PC14 43 +#define PC15 44 +#define PD0 45 +#define PD1 46 +#define PD2 47 +#define PD3 48 +#define PD4 49 +#define PD5 50 +#define PD6 51 +#define PD7 52 +#define PD8 53 +#define PD9 54 +#define PD10 55 +#define PD11 56 +#define PD12 57 +#define PD13 58 +#define PD14 59 +#define PD15 60 +#define PE0 61 +#define PE1 62 +#define PE11 63 +#define PE3 64 +#define PE4 65 +#define PE5 66 +#define PE6 67 +#define PE7 68 +#define PE8 69 +#define PE9 70 +#define PE10 71 +#define PE2 72 +#define PE12 73 +#define PE13 74 +#define PE14 75 +#define PE15 76 +#define PF0 77 +#define PF1 78 +#define PF2 79 +#define PF6 80 +#define PF7 81 +#define PF8 82 +#define PF9 83 +#define PF11 84 +#define PF12 85 +#define PF13 86 +#define PF14 87 +#define PF15 88 +#define PG0 89 +#define PG1 90 +#define PG2 91 +#define PG3 92 +#define PG4 93 +#define PG5 94 +#define PG6 95 +#define PG7 96 +#define PG8 97 +#define PG9 98 +#define PG10 99 +#define PG11 100 +#define PG12 101 +#define PG13 102 +#define PG14 103 +#define PG15 104 +#define PH0 105 +#define PH1 106 +#define PA0 107 +#define PC1 108 +#define PC0 109 +#define PF10 110 +#define PF5 111 +#define PF4 112 +#define PF3 113 + // This must be a literal -#define NUM_DIGITAL_PINS 112 +#define NUM_DIGITAL_PINS 114 // This must be a literal with a value less than or equal to MAX_ANALOG_INPUTS -#define NUM_ANALOG_INPUTS 23 -#define NUM_ANALOG_FIRST 75 +#define NUM_ANALOG_INPUTS 7 +#define NUM_ANALOG_FIRST 107 // Below SPI and I2C definitions already done in the core diff --git a/buildroot/share/PlatformIO/variants/LERDGE/PeripheralPins.c b/buildroot/share/PlatformIO/variants/LERDGE/PeripheralPins.c new file mode 100644 index 000000000000..8cb0776ffad1 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/LERDGE/PeripheralPins.c @@ -0,0 +1,418 @@ +/* + ******************************************************************************* + * Copyright (c) 2019, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + * Automatically generated from STM32F407Z(E-G)Tx.xml + */ +#include +#include + +/* ===== + * Note: Commented lines are alternative possibilities which are not used per default. + * If you change them, you will have to know what you do + * ===== + */ + +//*** ADC *** + +#ifdef HAL_ADC_MODULE_ENABLED +const PinMap PinMap_ADC[] = { + {PA_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC1_IN0 + //{PA_0, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC2_IN0 + //{PA_0, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC3_IN0 + {PA_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC1_IN1 + //{PA_1, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC2_IN1 + //{PA_1, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC3_IN1 + //{PA_2, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC1_IN2 + {PA_2, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC2_IN2 + //{PA_2, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC3_IN2 + //{PA_3, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC1_IN3 + //{PA_3, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC2_IN3 + {PA_3, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC3_IN3 + {PA_4, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC1_IN4 + //{PA_4, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC2_IN4 + //{PA_5, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC1_IN5 + {PA_5, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC2_IN5 + {PA_6, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC1_IN6 + //{PA_6, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC2_IN6 + {PA_7, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC1_IN7 + //{PA_7, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC2_IN7 + //{PB_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC1_IN8 + {PB_0, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC2_IN8 + {PB_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC1_IN9 + //{PB_1, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC2_IN9 + //{PC_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC1_IN10 + //{PC_0, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC2_IN10 + {PC_0, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC3_IN10 + {PC_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC1_IN11 + //{PC_1, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC2_IN11 + //{PC_1, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC3_IN11 + //{PC_2, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC1_IN12 + {PC_2, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC2_IN12 + //{PC_2, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC3_IN12 + //{PC_3, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC1_IN13 + //{PC_3, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC2_IN13 + {PC_3, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC3_IN13 + //{PC_4, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 14, 0)}, // ADC1_IN14 + {PC_4, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 14, 0)}, // ADC2_IN14 + //{PC_5, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 15, 0)}, // ADC1_IN15 + {PC_5, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 15, 0)}, // ADC2_IN15 + {PF_3, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC3_IN9 + {PF_4, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 14, 0)}, // ADC3_IN14 + {PF_5, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 15, 0)}, // ADC3_IN15 + {PF_6, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC3_IN4 + {PF_7, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC3_IN5 + {PF_8, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC3_IN6 + //{PF_9, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC3_IN7 + {PF_10, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC3_IN8 + {NC, NP, 0} +}; +#endif + +//*** DAC *** + +#ifdef HAL_DAC_MODULE_ENABLED +const PinMap PinMap_DAC[] = { + {PA_4, DAC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // DAC_OUT1 + {PA_5, DAC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // DAC_OUT2 + {NC, NP, 0} +}; +#endif + +//*** I2C *** + +#ifdef HAL_I2C_MODULE_ENABLED +const PinMap PinMap_I2C_SDA[] = { + {PB_7, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)}, + {PB_9, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)}, + {PB_11, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, + {PC_9, I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)}, + {PF_0, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_I2C_MODULE_ENABLED +const PinMap PinMap_I2C_SCL[] = { + {PA_8, I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)}, + {PB_6, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)}, + {PB_8, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)}, + {PB_10, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, + {PF_1, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, + {NC, NP, 0} +}; +#endif + +//*** PWM *** + +#ifdef HAL_TIM_MODULE_ENABLED +const PinMap PinMap_PWM[] = { + {PA_0, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1 + //{PA_0, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 1, 0)}, // TIM5_CH1 + {PA_1, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 2, 0)}, // TIM2_CH2 + //{PA_1, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 2, 0)}, // TIM5_CH2 + {PA_2, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3 + //{PA_2, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 3, 0)}, // TIM5_CH3 + //{PA_2, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 1, 0)}, // TIM9_CH1 + {PA_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 4, 0)}, // TIM2_CH4 + //{PA_3, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 4, 0)}, // TIM5_CH4 + //{PA_3, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 2, 0)}, // TIM9_CH2 + {PA_5, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1 + //{PA_5, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 1, 1)}, // TIM8_CH1N + {PA_6, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 1, 0)}, // TIM3_CH1 + //{PA_6, TIM13, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM13, 1, 0)}, // TIM13_CH1 + //{PA_7, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 1)}, // TIM1_CH1N + {PA_7, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 2, 0)}, // TIM3_CH2 + //{PA_7, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 1, 1)}, // TIM8_CH1N + //{PA_7, TIM14, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM14, 1, 0)}, // TIM14_CH1 + {PA_8, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 0)}, // TIM1_CH1 + {PA_9, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 0)}, // TIM1_CH2 + {PA_10, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 0)}, // TIM1_CH3 + {PA_11, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 4, 0)}, // TIM1_CH4 + //{PA_15, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1 + //{PB_0, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 1)}, // TIM1_CH2N + {PB_0, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 3, 0)}, // TIM3_CH3 + //{PB_0, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 2, 1)}, // TIM8_CH2N + //{PB_1, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 1)}, // TIM1_CH3N + {PB_1, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 4, 0)}, // TIM3_CH4 + //{PB_1, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 3, 1)}, // TIM8_CH3N + //{PB_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 2, 0)}, // TIM2_CH2 + {PB_4, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 1, 0)}, // TIM3_CH1 + {PB_5, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 2, 0)}, // TIM3_CH2 + {PB_6, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 1, 0)}, // TIM4_CH1 + {PB_7, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 2, 0)}, // TIM4_CH2 + {PB_8, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 3, 0)}, // TIM4_CH3 + {PB_8, TIM10, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM10, 1, 0)}, // TIM10_CH1 + {PB_9, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 4, 0)}, // TIM4_CH4 + {PB_9, TIM11, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM11, 1, 0)}, // TIM11_CH1 + {PB_10, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3 + {PB_11, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 4, 0)}, // TIM2_CH4 + {PB_13, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 1)}, // TIM1_CH1N + {PB_14, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 1)}, // TIM1_CH2N + {PB_14, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 2, 1)}, // TIM8_CH2N + {PB_14, TIM12, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM12, 1, 0)}, // TIM12_CH1 + {PB_15, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 1)}, // TIM1_CH3N + {PB_15, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 3, 1)}, // TIM8_CH3N + {PB_15, TIM12, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM12, 2, 0)}, // TIM12_CH2 + {PC_6, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 1, 0)}, // TIM3_CH1 + {PC_6, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 1, 0)}, // TIM8_CH1 + {PC_7, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 2, 0)}, // TIM3_CH2 + {PC_7, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 2, 0)}, // TIM8_CH2 + {PC_8, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 3, 0)}, // TIM3_CH3 + {PC_8, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 3, 0)}, // TIM8_CH3 + {PC_9, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 4, 0)}, // TIM3_CH4 + {PC_9, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 4, 0)}, // TIM8_CH4 + {PD_12, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 1, 0)}, // TIM4_CH1 + {PD_13, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 2, 0)}, // TIM4_CH2 + {PD_14, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 3, 0)}, // TIM4_CH3 + {PD_15, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 4, 0)}, // TIM4_CH4 + {PE_5, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 1, 0)}, // TIM9_CH1 + {PE_6, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 2, 0)}, // TIM9_CH2 + {PE_8, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 1)}, // TIM1_CH1N + {PE_9, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 0)}, // TIM1_CH1 + {PE_10, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 1)}, // TIM1_CH2N + {PE_11, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 0)}, // TIM1_CH2 + {PE_12, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 1)}, // TIM1_CH3N + {PE_13, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 0)}, // TIM1_CH3 + {PE_14, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 4, 0)}, // TIM1_CH4 + {PF_6, TIM10, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM10, 1, 0)}, // TIM10_CH1 + {PF_7, TIM11, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM11, 1, 0)}, // TIM11_CH1 + {PF_8, TIM13, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM13, 1, 0)}, // TIM13_CH1 + {PF_9, TIM14, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM14, 1, 0)}, // TIM14_CH1 + {NC, NP, 0} +}; +#endif + +//*** SERIAL *** + +#ifdef HAL_UART_MODULE_ENABLED +const PinMap PinMap_UART_TX[] = { + {PA_0, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, + {PA_2, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + {PA_9, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, + {PB_6, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, + {PB_10, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + {PC_6, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, + //{PC_10, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, + {PC_10, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + {PC_12, UART5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)}, + {PD_5, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + {PD_8, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + {PG_14, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_UART_MODULE_ENABLED +const PinMap PinMap_UART_RX[] = { + {PA_1, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, + {PA_3, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + {PA_10, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, + {PB_7, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, + {PB_11, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + {PC_7, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, + //{PC_11, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, + {PC_11, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + {PD_2, UART5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)}, + {PD_6, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + {PD_9, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + {PG_9, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_UART_MODULE_ENABLED +const PinMap PinMap_UART_RTS[] = { + {PA_1, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + {PA_12, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, + {PB_14, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + {PD_4, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + {PD_12, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + {PG_8, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, + {PG_12, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_UART_MODULE_ENABLED +const PinMap PinMap_UART_CTS[] = { + {PA_0, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + {PA_11, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, + {PB_13, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + {PD_3, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + {PD_11, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + {PG_13, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, + {PG_15, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, + {NC, NP, 0} +}; +#endif + +//*** SPI *** + +#ifdef HAL_SPI_MODULE_ENABLED +const PinMap PinMap_SPI_MOSI[] = { + {PA_7, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, + {PB_5, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, + {PB_5, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + {PB_15, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + {PC_3, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + {PC_12, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_SPI_MODULE_ENABLED +const PinMap PinMap_SPI_MISO[] = { + {PA_6, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, + {PB_4, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, + {PB_4, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + {PB_14, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + {PC_2, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + {PC_11, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_SPI_MODULE_ENABLED +const PinMap PinMap_SPI_SCLK[] = { + {PA_5, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, + {PB_3, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, + {PB_3, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + {PB_10, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + {PB_13, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + {PC_10, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_SPI_MODULE_ENABLED +const PinMap PinMap_SPI_SSEL[] = { + {PA_4, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, + {PA_4, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + {PA_15, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, + {PA_15, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + {PB_9, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + {PB_12, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + {NC, NP, 0} +}; +#endif + +//*** CAN *** + +#ifdef HAL_CAN_MODULE_ENABLED +const PinMap PinMap_CAN_RD[] = { + {PA_11, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, + {PB_5, CAN2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)}, + {PB_8, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, + {PB_12, CAN2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)}, + {PD_0, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_CAN_MODULE_ENABLED +const PinMap PinMap_CAN_TD[] = { + {PA_12, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, + {PB_6, CAN2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)}, + {PB_9, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, + {PB_13, CAN2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)}, + {PD_1, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, + {NC, NP, 0} +}; +#endif + +//*** ETHERNET *** + +#ifdef HAL_ETH_MODULE_ENABLED +const PinMap PinMap_Ethernet[] = { + {PA_0, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_CRS + {PA_1, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_REF_CLK|ETH_RX_CLK + {PA_2, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_MDIO + {PA_3, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_COL + {PA_7, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_CRS_DV|ETH_RX_DV + {PB_0, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_RXD2 + {PB_1, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_RXD3 + {PB_5, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_PPS_OUT + {PB_8, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TXD3 + {PB_10, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_RX_ER + {PB_11, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TX_EN + {PB_12, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TXD0 + {PB_13, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TXD1 + {PC_1, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_MDC + {PC_2, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TXD2 + {PC_3, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TX_CLK + {PC_4, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_RXD0 + {PC_5, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_RXD1 + {PE_2, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TXD3 + {PG_8, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_PPS_OUT + {PG_11, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TX_EN + {PG_13, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TXD0 + {PG_14, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TXD1 + {NC, NP, 0} +}; +#endif + +//*** No QUADSPI *** + +//*** USB *** + +#ifdef HAL_PCD_MODULE_ENABLED +const PinMap PinMap_USB_OTG_FS[] = { + //{PA_8, USB_OTG_FS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_FS)}, // USB_OTG_FS_SOF + //{PA_9, USB_OTG_FS, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF_NONE)}, // USB_OTG_FS_VBUS + //{PA_10, USB_OTG_FS, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_PULLUP, GPIO_AF10_OTG_FS)}, // USB_OTG_FS_ID + {PA_11, USB_OTG_FS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_FS)}, // USB_OTG_FS_DM + {PA_12, USB_OTG_FS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_FS)}, // USB_OTG_FS_DP + {NC, NP, 0} +}; +#endif + +#ifdef HAL_PCD_MODULE_ENABLED +const PinMap PinMap_USB_OTG_HS[] = { +#ifdef USE_USB_HS_IN_FS + {PA_4, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_SOF + {PB_12, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_ID + {PB_13, USB_OTG_HS, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF_NONE)}, // USB_OTG_HS_VBUS + {PB_14, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_DM + {PB_15, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_DP +#else + {PA_3, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D0 + {PA_5, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_CK + {PB_0, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D1 + {PB_1, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D2 + {PB_5, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D7 + {PB_10, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D3 + {PB_11, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D4 + {PB_12, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D5 + {PB_13, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D6 + {PC_0, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_STP + {PC_2, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_DIR + {PC_3, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_NXT +#endif /* USE_USB_HS_IN_FS */ + {NC, NP, 0} +}; +#endif diff --git a/buildroot/share/PlatformIO/variants/LERDGE/PinNamesVar.h b/buildroot/share/PlatformIO/variants/LERDGE/PinNamesVar.h new file mode 100644 index 000000000000..b4bb9d45f8ac --- /dev/null +++ b/buildroot/share/PlatformIO/variants/LERDGE/PinNamesVar.h @@ -0,0 +1,50 @@ +/* SYS_WKUP */ +#ifdef PWR_WAKEUP_PIN1 + SYS_WKUP1 = PA_0, +#endif +#ifdef PWR_WAKEUP_PIN2 + SYS_WKUP2 = NC, +#endif +#ifdef PWR_WAKEUP_PIN3 + SYS_WKUP3 = NC, +#endif +#ifdef PWR_WAKEUP_PIN4 + SYS_WKUP4 = NC, +#endif +#ifdef PWR_WAKEUP_PIN5 + SYS_WKUP5 = NC, +#endif +#ifdef PWR_WAKEUP_PIN6 + SYS_WKUP6 = NC, +#endif +#ifdef PWR_WAKEUP_PIN7 + SYS_WKUP7 = NC, +#endif +#ifdef PWR_WAKEUP_PIN8 + SYS_WKUP8 = NC, +#endif +/* USB */ +#ifdef USBCON + USB_OTG_FS_SOF = PA_8, + USB_OTG_FS_VBUS = PA_9, + USB_OTG_FS_ID = PA_10, + USB_OTG_FS_DM = PA_11, + USB_OTG_FS_DP = PA_12, + USB_OTG_HS_ULPI_D0 = PA_3, + USB_OTG_HS_SOF = PA_4, + USB_OTG_HS_ULPI_CK = PA_5, + USB_OTG_HS_ULPI_D1 = PB_0, + USB_OTG_HS_ULPI_D2 = PB_1, + USB_OTG_HS_ULPI_D7 = PB_5, + USB_OTG_HS_ULPI_D3 = PB_10, + USB_OTG_HS_ULPI_D4 = PB_11, + USB_OTG_HS_ID = PB_12, + USB_OTG_HS_ULPI_D5 = PB_12, + USB_OTG_HS_ULPI_D6 = PB_13, + USB_OTG_HS_VBUS = PB_13, + USB_OTG_HS_DM = PB_14, + USB_OTG_HS_DP = PB_15, + USB_OTG_HS_ULPI_STP = PC_0, + USB_OTG_HS_ULPI_DIR = PC_2, + USB_OTG_HS_ULPI_NXT = PC_3, +#endif diff --git a/buildroot/share/PlatformIO/variants/LERDGE/variant.cpp b/buildroot/share/PlatformIO/variants/LERDGE/variant.cpp new file mode 100644 index 000000000000..ebc1922eb856 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/LERDGE/variant.cpp @@ -0,0 +1,297 @@ +/* + ******************************************************************************* + * Copyright (c) 2017, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ + +#include "pins_arduino.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +const PinName digitalPin[] = { + PB_12, + PB_13, + PB_14, + PB_15, + PD_8, + PD_9, + PD_10, + PD_11, + PD_12, + PD_13, + PD_14, + PD_15, + PG_2, + PG_3, + PG_4, + PG_5, + PG_6, + PG_7, + PG_8, + PC_6, + PC_7, + PC_8, + PC_9, + PA_8, + PA_9, + PA_10, + PA_11, + PA_12, + PA_13, + PA_14, + PA_15, + PC_10, + PC_11, + PC_12, + PD_0, + PD_1, + PD_2, + PD_3, + PD_4, + PD_5, + PD_6, + PD_7, + PG_9, + PG_10, + PG_11, + PG_12, + PG_13, + PG_14, + PG_15, + PB_3, + PB_4, + PB_5, + PB_6, + PB_7, + PB_8, + PB_9, + PB_10, + PB_11, + PE_14, + PE_15, + PE_12, + PE_13, + PE_10, + PE_11, + PE_8, + PE_9, + PG_1, + PE_7, + PF_15, + PG_0, + PF_13, + PF_14, + PF_11, + PF_12, + PB_2, + PB_1, + PC_5, + PB_0, + PA_7, + PC_4, + PA_5, + PA_6, + PA_3, + PA_4, + PA_1, + PA_2, + PC_3, + PA_0, + PC_1, + PC_2, + PC_0, + PF_8, + PF_6, + PF_7, + PF_9, + PF_10, + PF_4, + PF_5, + PF_2, + PF_3, + PF_0, + PF_1, + PE_6, + PC_13, + PE_4, + PE_5, + PE_2, + PE_3, + PE_0, + PE_1, + PC_14, + PC_15, +}; + +#ifdef __cplusplus +} +#endif + +// ---------------------------------------------------------------------------- + +#ifdef __cplusplus +extern "C" { +#endif + +#define __fatal_error(X) + + +/** + * @brief System Clock Configuration + * + * The system Clock is configured for F4/F7 as follows: + * System Clock source = PLL (HSE) + * SYSCLK(Hz) = 168000000 + * HCLK(Hz) = 168000000 + * AHB Prescaler = 1 + * APB1 Prescaler = 4 + * APB2 Prescaler = 2 + * HSE Frequency(Hz) = HSE_VALUE + * PLL_M = HSE_VALUE/1000000 + * PLL_N = 336 + * PLL_P = 2 + * PLL_Q = 7 + * VDD(V) = 3.3 + * Main regulator output voltage = Scale1 mode + * Flash Latency(WS) = 5 + * + * The system Clock is configured for L4 as follows: + * System Clock source = PLL (MSI) + * SYSCLK(Hz) = 80000000 + * HCLK(Hz) = 80000000 + * AHB Prescaler = 1 + * APB1 Prescaler = 1 + * APB2 Prescaler = 1 + * MSI Frequency(Hz) = MSI_VALUE (4000000) + * LSE Frequency(Hz) = 32768 + * PLL_M = 1 + * PLL_N = 40 + * PLL_P = 7 + * PLL_Q = 2 + * PLL_R = 2 <= This is the source for SysClk, not as on F4/7 PLL_P + * Flash Latency(WS) = 4 + * @param None + * @retval None + * + * PLL is configured as follows: + * + * VCO_IN + * F4/F7 = HSE / M + * L4 = MSI / M + * VCO_OUT + * F4/F7 = HSE / M * N + * L4 = MSI / M * N + * PLLCLK + * F4/F7 = HSE / M * N / P + * L4 = MSI / M * N / R + * PLL48CK + * F4/F7 = HSE / M * N / Q + * L4 = MSI / M * N / Q USB Clock is obtained over PLLSAI1 + * + * SYSCLK = PLLCLK + * HCLK = SYSCLK / AHB_PRESC + * PCLKx = HCLK / APBx_PRESC + * + * Constraints on parameters: + * + * VCO_IN between 1MHz and 2MHz (2MHz recommended) + * VCO_OUT between 192MHz and 432MHz + * HSE = 8MHz + * M = 2 .. 63 (inclusive) + * N = 192 ... 432 (inclusive) + * P = 2, 4, 6, 8 + * Q = 2 .. 15 (inclusive) + * + * AHB_PRESC=1,2,4,8,16,64,128,256,512 + * APBx_PRESC=1,2,4,8,16 + * + * Output clocks: + * + * CPU SYSCLK max 168MHz + * USB,RNG,SDIO PLL48CK must be 48MHz for USB + * AHB HCLK max 168MHz + * APB1 PCLK1 max 42MHz + * APB2 PCLK2 max 84MHz + * + * Timers run from APBx if APBx_PRESC=1, else 2x APBx + */ +void SystemClock_Config(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + __PWR_CLK_ENABLE(); + + /* The voltage scaling allows optimizing the power consumption when the device is + clocked below the maximum system frequency, to update the voltage scaling value + regarding system frequency refer to product datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSIState = RCC_HSI_OFF; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + + RCC_OscInitStruct.PLL.PLLM = 25; + RCC_OscInitStruct.PLL.PLLN = 336; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 7; + + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + + if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { + __fatal_error("HAL_RCC_OscConfig"); + } + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) + { + __fatal_error("HAL_RCC_ClockConfig"); + } + + /**Configure the Systick interrupt time */ + HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000); + + /**Configure the Systick */ + HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); + + /* SysTick_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); +} + +#ifdef __cplusplus +} +#endif diff --git a/buildroot/share/PlatformIO/variants/LERDGE/variant.h b/buildroot/share/PlatformIO/variants/LERDGE/variant.h new file mode 100644 index 000000000000..87033a68e5f6 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/LERDGE/variant.h @@ -0,0 +1,238 @@ +/* + ******************************************************************************* + * Copyright (c) 2017, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Left Side +#define PB12 0 +#define PB13 1 +#define PB14 2 +#define PB15 3 +#define PD8 4 +#define PD9 5 +#define PD10 6 +#define PD11 7 +#define PD12 8 +#define PD13 9 +#define PD14 10 +#define PD15 11 +#define PG2 12 +#define PG3 13 +#define PG4 14 +#define PG5 15 +#define PG6 16 +#define PG7 17 +#define PG8 18 +#define PC6 19 +#define PC7 20 +#define PC8 21 +#define PC9 22 +#define PA8 23 +#define PA9 24 +#define PA10 25 +#define PA11 26 // USB_DM +#define PA12 27 // USB_DP +#define PA13 28 +#define PA14 29 +#define PA15 30 +#define PC10 31 +#define PC11 32 +#define PC12 33 +#define PD0 34 +#define PD1 35 +#define PD2 36 +#define PD3 37 +#define PD4 38 +#define PD5 39 +#define PD6 40 +#define PD7 41 +#define PG9 42 +#define PG10 43 +#define PG11 44 +#define PG12 45 +#define PG13 46 +#define PG14 47 +#define PG15 48 +#define PB3 49 +#define PB4 50 +#define PB5 51 +#define PB6 52 +#define PB7 53 +#define PB8 54 +#define PB9 55 + +// Right Side +#define PB10 56 +#define PB11 57 +#define PE14 58 +#define PE15 59 +#define PE12 60 +#define PE13 61 +#define PE10 62 +#define PE11 63 +#define PE8 64 +#define PE9 65 +#define PG1 66 +#define PE7 67 +#define PF15 68 +#define PG0 69 +#define PF13 70 +#define PF14 71 +#define PF11 72 +#define PF12 73 +#define PB2 74 +#define PB1 75 // A0 +#define PC5 76 // A1 +#define PB0 77 // A2 +#define PA7 78 // A3 +#define PC4 79 // A4 +#define PA5 80 // A5 +#define PA6 81 // A6 +#define PA3 82 // A7 +#define PA4 83 // A8 +#define PA1 84 // A9 +#define PA2 85 // A10 +#define PC3 86 // A11 +#define PA0 87 // A12/PA_0(WK_UP): BUT K_UP) +#define PC1 88 // A13 +#define PC2 89 // A14 +#define PC0 90 // A15 +#define PF8 91 // A16 +#define PF6 92 // A17 +#define PF7 93 // A18 +#define PF9 94 // LED D1 (active low) +#define PF10 95 // LED D2 (active low) +#define PF4 96 +#define PF5 97 +#define PF2 98 +#define PF3 99 +#define PF0 100 +#define PF1 101 +#define PE6 102 +#define PC13 103 +#define PE4 104 // BUT K0 +#define PE5 105 // BUT K1 +#define PE2 106 +#define PE3 107 +#define PE0 108 +#define PE1 109 +#define PC14 110 +#define PC15 111 +// This must be a literal +#define NUM_DIGITAL_PINS 112 +// This must be a literal with a value less than or equal to MAX_ANALOG_INPUTS +#define NUM_ANALOG_INPUTS 23 +#define NUM_ANALOG_FIRST 75 + + +// Below SPI and I2C definitions already done in the core +// Could be redefined here if differs from the default one +// SPI Definitions +#define PIN_SPI_SS PF11 +#define PIN_SPI_MOSI PB15 +#define PIN_SPI_MISO PB14 +#define PIN_SPI_SCK PB13 + + + +//max6675 +//#define PIN_SPI_SS PA4 +//#define PIN_SPI_SCK PA5 +//#define PIN_SPI_MISO PA6 +//#define PIN_SPI_MOSI PA7 + + + + +// I2C Definitions +#define PIN_WIRE_SDA PB7 +#define PIN_WIRE_SCL PB6 + +// Timer Definitions +//Do not use timer used by PWM pins when possible. See PinMap_PWM in PeripheralPins.c +#define TIMER_TONE TIM6 + +// Do not use basic timer: OC is required +#define TIMER_SERVO TIM1 //TODO: advanced-control timers don't work + +// UART Definitions +// Define here Serial instance number to map on Serial generic name +#define SERIAL_UART_INSTANCE 1 //ex: 2 for Serial2 (USART2) +// DEBUG_UART could be redefined to print on another instance than 'Serial' +//#define DEBUG_UART ((USART_TypeDef *) U(S)ARTX) // ex: USART3 +// DEBUG_UART baudrate, default: 9600 if not defined +//#define DEBUG_UART_BAUDRATE x +// DEBUG_UART Tx pin name, default: the first one found in PinMap_UART_TX for DEBUG_UART +//#define DEBUG_PINNAME_TX PX_n // PinName used for TX + +// Default pin used for 'Serial' instance (ex: ST-Link) +// Mandatory for Firmata +#define PIN_SERIAL_RX PA10 +#define PIN_SERIAL_TX PA9 + +/* Extra HAL modules */ +//#define HAL_DAC_MODULE_ENABLED +#define HAL_SD_MODULE_ENABLED + +#ifdef __cplusplus +} // extern "C" +#endif +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_MONITOR Serial +#define SERIAL_PORT_HARDWARE Serial1 +#endif + diff --git a/buildroot/share/PlatformIO/variants/MARLIN_F103Vx/PeripheralPins.c b/buildroot/share/PlatformIO/variants/MARLIN_F103Vx/PeripheralPins.c new file mode 100644 index 000000000000..c9d2bb88b87a --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MARLIN_F103Vx/PeripheralPins.c @@ -0,0 +1,425 @@ +/* + ******************************************************************************* + * Copyright (c) 2020, STMicroelectronics + * All rights reserved. + * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + * Automatically generated from STM32F103V(F-G)Tx.xml + */ +#include "Arduino.h" +#include "PeripheralPins.h" + +/* ===== + * Note: Commented lines are alternative possibilities which are not used per default. + * If you change them, you will have to know what you do + * ===== + */ + +//*** ADC *** + +#ifdef HAL_ADC_MODULE_ENABLED +WEAK const PinMap PinMap_ADC[] = { + {PA_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC1_IN0 + // {PA_0, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC2_IN0 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PA_0, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC3_IN0 +#endif + {PA_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC1_IN1 + // {PA_1, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC2_IN1 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PA_1, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC3_IN1 +#endif + {PA_2, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC1_IN2 + // {PA_2, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC2_IN2 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PA_2, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC3_IN2 +#endif + {PA_3, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC1_IN3 + // {PA_3, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC2_IN3 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PA_3, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC3_IN3 +#endif + {PA_4, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC1_IN4 + // {PA_4, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC2_IN4 + {PA_5, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC1_IN5 + // {PA_5, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC2_IN5 + {PA_6, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC1_IN6 + // {PA_6, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC2_IN6 + {PA_7, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC1_IN7 + // {PA_7, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC2_IN7 + {PB_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC1_IN8 + // {PB_0, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC2_IN8 + {PB_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC1_IN9 + // {PB_1, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC2_IN9 + {PC_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC1_IN10 + // {PC_0, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC2_IN10 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PC_0, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC3_IN10 +#endif + {PC_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC1_IN11 + // {PC_1, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC2_IN11 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PC_1, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC3_IN11 +#endif + {PC_2, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC1_IN12 + // {PC_2, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC2_IN12 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PC_2, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC3_IN12 +#endif + {PC_3, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC1_IN13 + // {PC_3, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC2_IN13 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PC_3, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC3_IN13 +#endif + {PC_4, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 14, 0)}, // ADC1_IN14 + // {PC_4, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 14, 0)}, // ADC2_IN14 + {PC_5, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 15, 0)}, // ADC1_IN15 + // {PC_5, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 15, 0)}, // ADC2_IN15 + {NC, NP, 0} +}; +#endif + +//*** DAC *** + +#if defined(STM32F103xE) || defined(STM32F103xG) +#ifdef HAL_DAC_MODULE_ENABLED +WEAK const PinMap PinMap_DAC[] = { + {PA_4, DAC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // DAC_OUT1 + {PA_5, DAC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // DAC_OUT2 + {NC, NP, 0} +}; +#endif +#endif + +//*** I2C *** + +#ifdef HAL_I2C_MODULE_ENABLED +WEAK const PinMap PinMap_I2C_SDA[] = { + {PB_7, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, AFIO_NONE)}, + {PB_9, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, AFIO_I2C1_ENABLE)}, + {PB_11, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, AFIO_NONE)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_I2C_MODULE_ENABLED +WEAK const PinMap PinMap_I2C_SCL[] = { + {PB_6, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, AFIO_NONE)}, + {PB_8, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, AFIO_I2C1_ENABLE)}, + {PB_10, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, AFIO_NONE)}, + {NC, NP, 0} +}; +#endif + +//*** PWM *** + +#ifdef HAL_TIM_MODULE_ENABLED +WEAK const PinMap PinMap_PWM[] = { + {PA_0, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM2_CH1 + // {PA_0, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_2, 1, 0)}, // TIM2_CH1 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PA_0, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM5_CH1 +#endif + {PA_1, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM2_CH2 + // {PA_1, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_2, 2, 0)}, // TIM2_CH2 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PA_1, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM5_CH2 +#endif + {PA_2, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 0)}, // TIM2_CH3 + // {PA_2, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_1, 3, 0)}, // TIM2_CH3 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PA_2, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 0)}, // TIM5_CH3 +#endif +#ifdef STM32F103xG + // {PA_2, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM9_CH1 +#endif + // {PA_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_1, 4, 0)}, // TIM2_CH4 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PA_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 4, 0)}, // TIM2_CH4 + {PA_3, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 4, 0)}, // TIM5_CH4 +#else + {PA_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 4, 0)}, // TIM2_CH4 +#endif +#if defined(STM32F103xG) + // {PA_3, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM9_CH2 +#endif + {PA_6, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM3_CH1 +#if defined(STM32F103xG) + // {PA_6, TIM13, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM13_CH1 +#endif + {PA_7, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_PARTIAL, 1, 1)}, // TIM1_CH1N + // {PA_7, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM3_CH2 + // {PA_7, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 1)}, // TIM8_CH1N +#if defined(STM32F103xG) + // {PA_7, TIM14, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM14_CH1 +#endif + {PA_8, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM1_CH1 + // {PA_8, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_PARTIAL, 1, 0)}, // TIM1_CH1 + {PA_9, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM1_CH2 + // {PA_9, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_PARTIAL, 2, 0)}, // TIM1_CH2 + {PA_10, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 0)}, // TIM1_CH3 + // {PA_10, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_PARTIAL, 3, 0)}, // TIM1_CH3 + {PA_11, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 4, 0)}, // TIM1_CH4 + // {PA_11, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_PARTIAL, 4, 0)}, // TIM1_CH4 + {PA_15, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_1, 1, 0)}, // TIM2_CH1 + // {PA_15, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_ENABLE, 1, 0)}, // TIM2_CH1 + // {PB_0, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_PARTIAL, 2, 1)}, // TIM1_CH2N + {PB_0, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 0)}, // TIM3_CH3 + // {PB_0, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_PARTIAL, 3, 0)}, // TIM3_CH3 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PB_0, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 1)}, // TIM8_CH2N +#endif + {PB_1, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_PARTIAL, 3, 1)}, // TIM1_CH3N + // {PB_1, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 4, 0)}, // TIM3_CH4 + // {PB_1, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_PARTIAL, 4, 0)}, // TIM3_CH4 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PB_1, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 1)}, // TIM8_CH3N +#endif + {PB_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_1, 2, 0)}, // TIM2_CH2 + // {PB_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_ENABLE, 2, 0)}, // TIM2_CH2 + {PB_4, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_PARTIAL, 1, 0)}, // TIM3_CH1 + {PB_5, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_PARTIAL, 2, 0)}, // TIM3_CH2 + {PB_6, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM4_CH1 + {PB_7, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM4_CH2 + {PB_8, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 0)}, // TIM4_CH3 +#if defined(STM32F103xG) + // {PB_8, TIM10, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM10_CH1 +#endif + {PB_9, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 4, 0)}, // TIM4_CH4 +#if defined(STM32F103xG) + // {PB_9, TIM11, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM11_CH1 +#endif + {PB_10, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_2, 3, 0)}, // TIM2_CH3 + // {PB_10, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_ENABLE, 3, 0)}, // TIM2_CH3 + {PB_11, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_2, 4, 0)}, // TIM2_CH4 + // {PB_11, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_ENABLE, 4, 0)}, // TIM2_CH4 + {PB_13, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 1)}, // TIM1_CH1N + {PB_14, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 1)}, // TIM1_CH2N +#if defined(STM32F103xG) + // {PB_14, TIM12, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM12_CH1 +#endif + {PB_15, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 1)}, // TIM1_CH3N +#if defined(STM32F103xG) + // {PB_15, TIM12, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM12_CH2 +#endif + {PC_6, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_ENABLE, 1, 0)}, // TIM3_CH1 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PC_6, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM8_CH1 +#endif + {PC_7, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_ENABLE, 2, 0)}, // TIM3_CH2 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PC_7, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM8_CH2 +#endif + {PC_8, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_ENABLE, 3, 0)}, // TIM3_CH3 + // {PC_8, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 0)}, // TIM8_CH3 + {PC_9, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_ENABLE, 4, 0)}, // TIM3_CH4 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PC_9, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 4, 0)}, // TIM8_CH4 +#endif + {PD_12, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM4_ENABLE, 1, 0)}, // TIM4_CH1 + {PD_13, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM4_ENABLE, 2, 0)}, // TIM4_CH2 + {PD_14, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM4_ENABLE, 3, 0)}, // TIM4_CH3 + {PD_15, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM4_ENABLE, 4, 0)}, // TIM4_CH4 +#if defined(STM32F103xG) + {PE_5, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM9_ENABLE, 1, 0)}, // TIM9_CH1 + {PE_6, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM9_ENABLE, 2, 0)}, // TIM9_CH2 +#endif + {PE_8, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_ENABLE, 1, 1)}, // TIM1_CH1N + {PE_9, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_ENABLE, 1, 0)}, // TIM1_CH1 + {PE_10, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_ENABLE, 2, 1)}, // TIM1_CH2N + {PE_11, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_ENABLE, 2, 0)}, // TIM1_CH2 + {PE_12, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_ENABLE, 3, 1)}, // TIM1_CH3N + {PE_13, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_ENABLE, 3, 0)}, // TIM1_CH3 + {PE_14, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_ENABLE, 4, 0)}, // TIM1_CH4 + {NC, NP, 0} +}; +#endif + +//*** SERIAL *** + +#ifdef HAL_UART_MODULE_ENABLED +WEAK const PinMap PinMap_UART_TX[] = { + {PA_2, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PA_9, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PB_6, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART1_ENABLE)}, + {PB_10, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PC_10, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART3_PARTIAL)}, + {PC_10, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#else + {PC_10, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART3_PARTIAL)}, +#endif +#if defined(STM32F103xE) || defined(STM32F103xG) + {PC_12, UART5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#endif + {PD_5, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART2_ENABLE)}, + {PD_8, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART3_ENABLE)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_UART_MODULE_ENABLED +WEAK const PinMap PinMap_UART_RX[] = { + {PA_3, USART2, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)}, + {PA_10, USART1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)}, + {PB_7, USART1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART1_ENABLE)}, + {PB_11, USART3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)}, +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PC_11, USART3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART3_PARTIAL)}, + {PC_11, UART4, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)}, +#else + {PC_11, USART3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART3_PARTIAL)}, +#endif +#if defined(STM32F103xE) || defined(STM32F103xG) + {PD_2, UART5, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)}, +#endif + {PD_6, USART2, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART2_ENABLE)}, + {PD_9, USART3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART3_ENABLE)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_UART_MODULE_ENABLED +WEAK const PinMap PinMap_UART_RTS[] = { + {PA_1, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PA_12, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PB_14, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + // {PB_14, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART3_PARTIAL)}, + {PD_4, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART2_ENABLE)}, + {PD_12, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART3_ENABLE)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_UART_MODULE_ENABLED +WEAK const PinMap PinMap_UART_CTS[] = { + {PA_0, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PA_11, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PB_13, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + // {PB_13, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART3_PARTIAL)}, + {PD_3, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART2_ENABLE)}, + {PD_11, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART3_ENABLE)}, + {NC, NP, 0} +}; +#endif + +//*** SPI *** + +#ifdef HAL_SPI_MODULE_ENABLED +WEAK const PinMap PinMap_SPI_MOSI[] = { + {PA_7, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PB_5, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_SPI1_ENABLE)}, + {PB_5, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#else + {PB_5, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_SPI1_ENABLE)}, +#endif + {PB_15, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_SPI_MODULE_ENABLED +WEAK const PinMap PinMap_SPI_MISO[] = { + {PA_6, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PB_4, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_SPI1_ENABLE)}, + {PB_4, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#else + {PB_4, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_SPI1_ENABLE)}, +#endif + {PB_14, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_SPI_MODULE_ENABLED +WEAK const PinMap PinMap_SPI_SCLK[] = { + {PA_5, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PB_3, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_SPI1_ENABLE)}, + {PB_3, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#else + {PB_3, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_SPI1_ENABLE)}, +#endif + {PB_13, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_SPI_MODULE_ENABLED +WEAK const PinMap PinMap_SPI_SSEL[] = { + {PA_4, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PA_15, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_SPI1_ENABLE)}, + {PA_15, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#else + {PA_15, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_SPI1_ENABLE)}, +#endif + {PB_12, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {NC, NP, 0} +}; +#endif + +//*** CAN *** + +#ifdef HAL_CAN_MODULE_ENABLED +WEAK const PinMap PinMap_CAN_RD[] = { + {PA_11, CAN1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, AFIO_NONE)}, + {PB_8, CAN1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, AFIO_CAN1_2)}, + {PD_0, CAN1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, AFIO_CAN1_3)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_CAN_MODULE_ENABLED +WEAK const PinMap PinMap_CAN_TD[] = { + {PA_12, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, AFIO_NONE)}, + {PB_9, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, AFIO_CAN1_2)}, + {PD_1, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, AFIO_CAN1_3)}, + {NC, NP, 0} +}; +#endif + +//*** No ETHERNET *** + +//*** No QUADSPI *** + +//*** USB *** + +#ifdef HAL_PCD_MODULE_ENABLED +WEAK const PinMap PinMap_USB[] = { + {PA_11, USB, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, AFIO_NONE)}, // USB_DM + {PA_12, USB, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, AFIO_NONE)}, // USB_DP + {NC, NP, 0} +}; +#endif + +//*** No USB_OTG_FS *** + +//*** No USB_OTG_HS *** + +//*** SD *** + +#if defined(STM32F103xE) || defined(STM32F103xG) +#ifdef HAL_SD_MODULE_ENABLED +WEAK const PinMap PinMap_SD[] = { + {PB_8, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D4 + {PB_9, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D5 + {PC_6, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D6 + {PC_7, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D7 + {PC_8, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D0 + {PC_9, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D1 + {PC_10, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D2 + {PC_11, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D3 + {PC_12, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, AFIO_NONE)}, // SDIO_CK + {PD_2, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, AFIO_NONE)}, // SDIO_CMD + {NC, NP, 0} +}; +#endif +#endif diff --git a/buildroot/share/PlatformIO/variants/FYSETC_S6/PinNamesVar.h b/buildroot/share/PlatformIO/variants/MARLIN_F103Vx/PinNamesVar.h similarity index 59% rename from buildroot/share/PlatformIO/variants/FYSETC_S6/PinNamesVar.h rename to buildroot/share/PlatformIO/variants/MARLIN_F103Vx/PinNamesVar.h index 77f1689b3d76..d9076b4dfb59 100644 --- a/buildroot/share/PlatformIO/variants/FYSETC_S6/PinNamesVar.h +++ b/buildroot/share/PlatformIO/variants/MARLIN_F103Vx/PinNamesVar.h @@ -1,30 +1,30 @@ /* SYS_WKUP */ #ifdef PWR_WAKEUP_PIN1 -SYS_WKUP1 = PA_0, /* SYS_WKUP0 */ + SYS_WKUP1 = PA_0, #endif #ifdef PWR_WAKEUP_PIN2 -SYS_WKUP2 = NC, + SYS_WKUP2 = NC, #endif #ifdef PWR_WAKEUP_PIN3 -SYS_WKUP3 = NC, + SYS_WKUP3 = NC, #endif #ifdef PWR_WAKEUP_PIN4 -SYS_WKUP4 = NC, + SYS_WKUP4 = NC, #endif #ifdef PWR_WAKEUP_PIN5 -SYS_WKUP5 = NC, + SYS_WKUP5 = NC, #endif #ifdef PWR_WAKEUP_PIN6 -SYS_WKUP6 = NC, + SYS_WKUP6 = NC, #endif #ifdef PWR_WAKEUP_PIN7 -SYS_WKUP7 = NC, + SYS_WKUP7 = NC, #endif #ifdef PWR_WAKEUP_PIN8 -SYS_WKUP8 = NC, + SYS_WKUP8 = NC, #endif /* USB */ #ifdef USBCON -USB_OTG_FS_DM = PA_11, -USB_OTG_FS_DP = PA_12, + USB_DM = PA_11, + USB_DP = PA_12, #endif diff --git a/buildroot/share/PlatformIO/variants/MARLIN_F103Vx/ldscript.ld b/buildroot/share/PlatformIO/variants/MARLIN_F103Vx/ldscript.ld new file mode 100644 index 000000000000..c9197c8b451a --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MARLIN_F103Vx/ldscript.ld @@ -0,0 +1,200 @@ +/* +****************************************************************************** +** + +** File : LinkerScript.ld +** +** Author : Auto-generated by STM32CubeIDE +** +** Abstract : Linker script for STM32F103V(8/B/C/E/F/GTx Device from STM32F1 series +** 64/128/256/512/768/1024Kbytes FLASH +** 20/20/48/64/64/96/96Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +**

© COPYRIGHT(c) 2019 STMicroelectronics

+** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** 1. Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** 3. Neither the name of STMicroelectronics nor the names of its contributors +** may be used to endorse or promote products derived from this software +** without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20000000 + LD_MAX_DATA_SIZE; /* end of "RAM" Ram type memory */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = LD_MAX_DATA_SIZE + FLASH (rx) : ORIGIN = 0x8000000 + LD_FLASH_OFFSET, LENGTH = LD_MAX_SIZE - LD_FLASH_OFFSET +} + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + .ARM : { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + .init_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + .fini_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + diff --git a/buildroot/share/PlatformIO/variants/MARLIN_F103Vx/variant.cpp b/buildroot/share/PlatformIO/variants/MARLIN_F103Vx/variant.cpp new file mode 100644 index 000000000000..25b4b511458b --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MARLIN_F103Vx/variant.cpp @@ -0,0 +1,235 @@ +/* + ******************************************************************************* + * Copyright (c) 2019, STMicroelectronics + * All rights reserved. + * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +#include "pins_arduino.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Digital PinName array +const PinName digitalPin[] = { + PA_0, //D0 + PA_1, //D1 + PA_2, //D2 + PA_3, //D3 + PA_4, //D4 + PA_5, //D5 + PA_6, //D6 + PA_7, //D7 + PA_8, //D8 + PA_9, //D9 + PA_10, //D10 + PA_11, //D11 + PA_12, //D12 + PA_13, //D13 + PA_14, //D14 + PA_15, //D15 + + PB_0, //D16 + PB_1, //D17 + PB_2, //D18 + PB_3, //D19 + PB_4, //D20 + PB_5, //D21 + PB_6, //D22 + PB_7, //D23 + PB_8, //D24 + PB_9, //D25 + PB_10, //D26 + PB_11, //D27 + PB_12, //D28 + PB_13, //D29 + PB_14, //D30 + PB_15, //D31 + + PC_0, //D32 + PC_1, //D33 + PC_2, //D34 + PC_3, //D35 + PC_4, //D36 + PC_5, //D37 + PC_6, //D38 + PC_7, //D39 + PC_8, //D40 + PC_9, //D41 + PC_10, //D42 + PC_11, //D43 + PC_12, //D44 + PC_13, //D45 + PC_14, //D46 + PC_15, //D47 + + PD_0, //D48 + PD_1, //D49 + PD_2, //D50 + PD_3, //D51 + PD_4, //D52 + PD_5, //D53 + PD_6, //D54 + PD_7, //D55 + PD_8, //D56 + PD_9, //D57 + PD_10, //D58 + PD_11, //D59 + PD_12, //D60 + PD_13, //D61 + PD_14, //D62 + PD_15, //D63 + + PE_0, //D64 + PE_1, //D65 + PE_2, //D66 + PE_3, //D67 + PE_4, //D68 + PE_5, //D69 + PE_6, //D70 + PE_7, //D71 + PE_8, //D72 + PE_9, //D73 + PE_10, //D74 + PE_11, //D75 + PE_12, //D76 + PE_13, //D77 + PE_14, //D78 + PE_15, //D79 +}; + +// Analog (Ax) pin number array +const uint32_t analogInputPin[] = { + 0, // A0, PA0 + 1, // A1, PA1 + 2, // A2, PA2 + 3, // A3, PA3 + 4, // A4, PA4 + 5, // A5, PA5 + 6, // A6, PA6 + 7, // A7, PA7 + 16, // A8, PB0 + 17, // A9, PB1 + 32, // A10, PC0 + 33, // A11, PC1 + 34, // A12, PC2 + 35, // A13, PC3 + 36, // A14, PC4 + 37, // A15, PC5 +}; + +/******************************************************************************/ +/* PLL (clocked by HSE) used as System clock source */ +/******************************************************************************/ +static bool SetSysClock_PLL_HSE(bool bypass) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {}; + bool ret = false; + + /* Initializes the CPU, AHB and APB busses clocks */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + if (bypass == false) { + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + } else { + RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; + } + RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) == HAL_OK) { + /* Initializes the CPU, AHB and APB busses clocks */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK + | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) == HAL_OK) { + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_USB; + PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6; + PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) == HAL_OK) { + ret = true; + } + } + } + return ret; +} + +/******************************************************************************/ +/* PLL (clocked by HSI) used as System clock source */ +/******************************************************************************/ +bool SetSysClock_PLL_HSI(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {}; + bool ret = false; + + /* Initializes the CPU, AHB and APB busses clocks */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSEState = RCC_HSE_OFF; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) == HAL_OK) { + /* Initializes the CPU, AHB and APB busses clocks */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK + | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) == HAL_OK) { + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_USB; + PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV4; + PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) == HAL_OK) { + ret = true; + } + } + } + return ret; +} + +WEAK void SystemClock_Config(void) +{ + /* + * If HSE_VALUE is not 8MHz and you want use it, then: + * - Redefine HSE_VALUE to the correct HSE_VALUE + * - Redefine SystemClock_Config() with the correct settings + */ +#if HSE_VALUE == 8000000U + /* 1- Try to start with HSE and external 8MHz xtal */ + if (SetSysClock_PLL_HSE(false) == false) { + /* 2- If fail try to start with HSE and external clock */ + if (SetSysClock_PLL_HSE(true) == false) { +#endif + /* 3- If fail start with HSI clock */ + if (SetSysClock_PLL_HSI() == false) { + Error_Handler(); + } +#if HSE_VALUE == 8000000U + } + } +#endif +} + +#ifdef __cplusplus +} +#endif diff --git a/buildroot/share/PlatformIO/variants/MARLIN_F103Vx/variant.h b/buildroot/share/PlatformIO/variants/MARLIN_F103Vx/variant.h new file mode 100644 index 000000000000..b622b39376b9 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MARLIN_F103Vx/variant.h @@ -0,0 +1,181 @@ +/* + ******************************************************************************* + * Copyright (c) 2019, STMicroelectronics + * All rights reserved. + * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +#ifndef _VARIANT_ARDUINO_STM32_ +#define _VARIANT_ARDUINO_STM32_ + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ +#define PA0 0 +#define PA1 1 +#define PA2 2 +#define PA3 3 +#define PA4 4 +#define PA5 5 +#define PA6 6 +#define PA7 7 +#define PA8 8 +#define PA9 9 +#define PA10 10 +#define PA11 11 +#define PA12 12 +#define PA13 13 +#define PA14 14 +#define PA15 15 + +#define PB0 16 +#define PB1 17 +#define PB2 18 +#define PB3 19 +#define PB4 20 +#define PB5 21 +#define PB6 22 +#define PB7 23 +#define PB8 24 +#define PB9 25 +#define PB10 26 +#define PB11 27 +#define PB12 28 +#define PB13 29 +#define PB14 30 +#define PB15 31 + +#define PC0 32 +#define PC1 33 +#define PC2 34 +#define PC3 35 +#define PC4 36 +#define PC5 37 +#define PC6 38 +#define PC7 39 +#define PC8 40 +#define PC9 41 +#define PC10 42 +#define PC11 43 +#define PC12 44 +#define PC13 45 +#define PC14 46 +#define PC15 47 + +#define PD0 48 +#define PD1 49 +#define PD2 50 +#define PD3 51 +#define PD4 52 +#define PD5 53 +#define PD6 54 +#define PD7 55 +#define PD8 56 +#define PD9 57 +#define PD10 58 +#define PD11 59 +#define PD12 60 +#define PD13 61 +#define PD14 62 +#define PD15 63 + +#define PE0 64 +#define PE1 65 +#define PE2 66 +#define PE3 67 +#define PE4 68 +#define PE5 69 +#define PE6 70 +#define PE7 71 +#define PE8 72 +#define PE9 73 +#define PE10 74 +#define PE11 75 +#define PE12 76 +#define PE13 77 +#define PE14 78 +#define PE15 79 + +// This must be a literal +#define NUM_DIGITAL_PINS 80 +#define NUM_ANALOG_INPUTS 16 + +// On-board LED pin number +#ifndef LED_BUILTIN +#define LED_BUILTIN PB11 +#endif + +// On-board user button +#ifndef USER_BTN +#define USER_BTN PC13 +#endif + +// SPI Definitions +#define PIN_SPI_SS PC4 +#define PIN_SPI_MOSI PA7 +#define PIN_SPI_MISO PA6 +#define PIN_SPI_SCK PA5 + +// I2C Definitions +#define PIN_WIRE_SDA PB7 +#define PIN_WIRE_SCL PB6 + +// Timer Definitions (optional) +// Use TIM6/TIM7 when possible as servo and tone don't need GPIO output pin +#define TIMER_TONE TIM3 +#define TIMER_SERVO TIM2 + +// UART Definitions +// Define here Serial instance number to map on Serial generic name +#define SERIAL_UART_INSTANCE 1 + +// Extra HAL modules +#if defined(STM32F103xE) || defined(STM32F103xG) +#define HAL_DAC_MODULE_ENABLED +#define HAL_SD_MODULE_ENABLED +#define HAL_SRAM_MODULE_ENABLED +#endif + +// Default pin used for 'Serial' instance (ex: ST-Link) +// Mandatory for Firmata +#define PIN_SERIAL_RX PA10 +#define PIN_SERIAL_TX PA9 + +#ifdef __cplusplus +} // extern "C" +#endif +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + // These serial port names are intended to allow libraries and architecture-neutral + // sketches to automatically default to the correct port name for a particular type + // of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, + // the first hardware serial port whose RX/TX pins are not dedicated to another use. + // + // SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor + // + // SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial + // + // SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library + // + // SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. + // + // SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX + // pins are NOT connected to anything by default. + #define SERIAL_PORT_MONITOR Serial + #define SERIAL_PORT_HARDWARE Serial1 +#endif + +#endif /* _VARIANT_ARDUINO_STM32_ */ diff --git a/buildroot/share/PlatformIO/variants/MARLIN_F103Zx/PeripheralPins.c b/buildroot/share/PlatformIO/variants/MARLIN_F103Zx/PeripheralPins.c new file mode 100644 index 000000000000..5736e5206e09 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MARLIN_F103Zx/PeripheralPins.c @@ -0,0 +1,368 @@ +/* + ******************************************************************************* + * Copyright (c) 2019, STMicroelectronics + * All rights reserved. + * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + * Automatically generated from STM32F103Z(C-D-E|F-G))Tx.xml + */ +#include "Arduino.h" +#include "PeripheralPins.h" + +/* ===== + * Note: Commented lines are alternative possibilities which are not used per default. + * If you change them, you will have to know what you do + * ===== + */ + +//*** ADC *** + +#ifdef HAL_ADC_MODULE_ENABLED +WEAK const PinMap PinMap_ADC[] = { + {PA_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC1_IN0 + // {PA_0, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC2_IN0 + // {PA_0, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC3_IN0 + {PA_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC1_IN1 + // {PA_1, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC2_IN1 + // {PA_1, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC3_IN1 + // {PA_2, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC1_IN2 + {PA_2, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC2_IN2 + // {PA_2, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC3_IN2 + {PA_3, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC1_IN3 + // {PA_3, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC2_IN3 + // {PA_3, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC3_IN3 + // {PA_4, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC1_IN4 + {PA_4, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC2_IN4 + {PA_5, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC1_IN5 + // {PA_5, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC2_IN5 + // {PA_6, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC1_IN6 + {PA_6, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC2_IN6 + {PA_7, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC1_IN7 + // {PA_7, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC2_IN7 + // {PB_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC1_IN8 + {PB_0, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC2_IN8 + {PB_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC1_IN9 + // {PB_1, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC2_IN9 + // {PC_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC1_IN10 + {PC_0, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC2_IN10 + // {PC_0, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC3_IN10 + {PC_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC1_IN11 + // {PC_1, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC2_IN11 + // {PC_1, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC3_IN11 + // {PC_2, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC1_IN12 + {PC_2, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC2_IN12 + // {PC_2, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC3_IN12 + {PC_3, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC1_IN13 + // {PC_3, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC2_IN13 + // {PC_3, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC3_IN13 + // {PC_4, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 14, 0)}, // ADC1_IN14 + {PC_4, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 14, 0)}, // ADC2_IN14 + {PC_5, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 15, 0)}, // ADC1_IN15 + // {PC_5, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 15, 0)}, // ADC2_IN15 + {PF_6, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC3_IN4 + {PF_7, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC3_IN5 + {PF_8, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC3_IN6 + {PF_9, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC3_IN7 + {PF_10, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC3_IN8 + {NC, NP, 0} +}; +#endif + +//*** DAC *** + +#ifdef HAL_DAC_MODULE_ENABLED +WEAK const PinMap PinMap_DAC[] = { + {PA_4, DAC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // DAC_OUT1 + {PA_5, DAC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // DAC_OUT2 + {NC, NP, 0} +}; +#endif + +//*** I2C *** + +#ifdef HAL_I2C_MODULE_ENABLED +WEAK const PinMap PinMap_I2C_SDA[] = { + {PB_7, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, AFIO_NONE)}, + {PB_9, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, AFIO_I2C1_ENABLE)}, + {PB_11, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, AFIO_NONE)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_I2C_MODULE_ENABLED +WEAK const PinMap PinMap_I2C_SCL[] = { + {PB_6, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, AFIO_NONE)}, + {PB_8, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, AFIO_I2C1_ENABLE)}, + {PB_10, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, AFIO_NONE)}, + {NC, NP, 0} +}; +#endif + +//*** PWM *** + +#ifdef HAL_TIM_MODULE_ENABLED +WEAK const PinMap PinMap_PWM[] = { + {PA_0, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM2_CH1 + // {PA_0, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_2, 1, 0)}, // TIM2_CH1 + // {PA_0, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM5_CH1 + // {PA_1, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM2_CH2 + // {PA_1, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_2, 2, 0)}, // TIM2_CH2 + {PA_1, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM5_CH2 + {PA_2, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 0)}, // TIM2_CH3 + // {PA_2, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_1, 3, 0)}, // TIM2_CH3 + // {PA_2, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 0)}, // TIM5_CH3 +#ifdef STM32F103xG + // {PA_2, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM9_CH1 +#endif + // {PA_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 4, 0)}, // TIM2_CH4 + // {PA_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_1, 4, 0)}, // TIM2_CH4 + {PA_3, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 4, 0)}, // TIM5_CH4 +#ifdef STM32F103xG + // {PA_3, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM9_CH2 +#endif + {PA_6, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM3_CH1 +#ifdef STM32F103xG + // {PA_6, TIM13, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM13_CH1 +#endif + // {PA_7, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_PARTIAL, 1, 1)}, // TIM1_CH1N + // {PA_7, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM3_CH2 + {PA_7, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 1)}, // TIM8_CH1N +#ifdef STM32F103xG + // {PA_7, TIM14, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM14_CH1 +#endif + {PA_8, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM1_CH1 + // {PA_8, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_PARTIAL, 1, 0)}, // TIM1_CH1 + {PA_9, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM1_CH2 + // {PA_9, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_PARTIAL, 2, 0)}, // TIM1_CH2 + {PA_10, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 0)}, // TIM1_CH3 + // {PA_10, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_PARTIAL, 3, 0)}, // TIM1_CH3 + {PA_11, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 4, 0)}, // TIM1_CH4 + // {PA_11, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_PARTIAL, 4, 0)}, // TIM1_CH4 + {PA_15, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_1, 1, 0)}, // TIM2_CH1 + // {PA_15, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_ENABLE, 1, 0)}, // TIM2_CH1 + // {PB_0, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_PARTIAL, 2, 1)}, // TIM1_CH2N + {PB_0, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 0)}, // TIM3_CH3 + // {PB_0, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_PARTIAL, 3, 0)}, // TIM3_CH3 + {PB_0, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 1)}, // TIM8_CH2N + {PB_1, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_PARTIAL, 3, 1)}, // TIM1_CH3N + // {PB_1, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 4, 0)}, // TIM3_CH4 + // {PB_1, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_PARTIAL, 4, 0)}, // TIM3_CH4 + // {PB_1, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 1)}, // TIM8_CH3N + {PB_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_1, 2, 0)}, // TIM2_CH2 + // {PB_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_ENABLE, 2, 0)}, // TIM2_CH2 + {PB_4, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_PARTIAL, 1, 0)}, // TIM3_CH1 + {PB_5, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_PARTIAL, 2, 0)}, // TIM3_CH2 + {PB_6, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM4_CH1 + {PB_7, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM4_CH2 + {PB_8, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 0)}, // TIM4_CH3 +#ifdef STM32F103xG + // {PB_8, TIM10, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM10_CH1 +#endif + {PB_9, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 4, 0)}, // TIM4_CH4 +#ifdef STM32F103xG + // {PB_9, TIM11, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM11_CH1 +#endif + // {PB_10, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_2, 3, 0)}, // TIM2_CH3 + {PB_10, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_ENABLE, 3, 0)}, // TIM2_CH3 + // {PB_11, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_2, 4, 0)}, // TIM2_CH4 + {PB_11, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_ENABLE, 4, 0)}, // TIM2_CH4 + {PB_13, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 1)}, // TIM1_CH1N + {PB_14, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 1)}, // TIM1_CH2N +#ifdef STM32F103xG + // {PB_14, TIM12, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM12_CH1 +#endif + {PB_15, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 1)}, // TIM1_CH3N +#ifdef STM32F103xG + // {PB_15, TIM12, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM12_CH2 +#endif + // {PC_6, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_ENABLE, 1, 0)}, // TIM3_CH1 + {PC_6, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM8_CH1 + // {PC_7, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_ENABLE, 2, 0)}, // TIM3_CH2 + {PC_7, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM8_CH2 + {PC_8, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_ENABLE, 3, 0)}, // TIM3_CH3 + // {PC_8, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 0)}, // TIM8_CH3 + {PC_9, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_ENABLE, 4, 0)}, // TIM3_CH4 + // {PC_9, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 4, 0)}, // TIM8_CH4 + {PD_12, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM4_ENABLE, 1, 0)}, // TIM4_CH1 + {PD_13, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM4_ENABLE, 2, 0)}, // TIM4_CH2 + {PD_14, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM4_ENABLE, 3, 0)}, // TIM4_CH3 + {PD_15, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM4_ENABLE, 4, 0)}, // TIM4_CH4 +#ifdef STM32F103xG + {PE_5, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM9_ENABLE, 1, 0)}, // TIM9_CH1 + {PE_6, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM9_ENABLE, 2, 0)}, // TIM9_CH2 +#endif + {PE_8, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_ENABLE, 1, 1)}, // TIM1_CH1N + {PE_9, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_ENABLE, 1, 0)}, // TIM1_CH1 + {PE_10, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_ENABLE, 2, 1)}, // TIM1_CH2N + {PE_11, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_ENABLE, 2, 0)}, // TIM1_CH2 + {PE_12, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_ENABLE, 3, 1)}, // TIM1_CH3N + {PE_13, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_ENABLE, 3, 0)}, // TIM1_CH3 + {PE_14, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_ENABLE, 4, 0)}, // TIM1_CH4 +#ifdef STM32F103xG + {PF_6, TIM10, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM10_ENABLE, 1, 0)}, // TIM10_CH1 + {PF_7, TIM11, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM11_ENABLE, 1, 0)}, // TIM11_CH1 + {PF_8, TIM13, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM13_ENABLE, 1, 0)}, // TIM13_CH1 + {PF_9, TIM14, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM14_ENABLE, 1, 0)}, // TIM14_CH1 +#endif + {NC, NP, 0} +}; +#endif + +//*** SERIAL *** + +#ifdef HAL_UART_MODULE_ENABLED +WEAK const PinMap PinMap_UART_TX[] = { + {PA_2, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PA_9, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PB_6, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART1_ENABLE)}, + {PB_10, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PC_10, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + // {PC_10, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART3_PARTIAL)}, + {PC_12, UART5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PD_5, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART2_ENABLE)}, + {PD_8, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART3_ENABLE)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_UART_MODULE_ENABLED +WEAK const PinMap PinMap_UART_RX[] = { + {PA_3, USART2, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)}, + {PA_10, USART1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)}, + {PB_7, USART1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART1_ENABLE)}, + {PB_11, USART3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)}, + {PC_11, UART4, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)}, + // {PC_11, USART3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART3_PARTIAL)}, + {PD_2, UART5, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)}, + {PD_6, USART2, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART2_ENABLE)}, + {PD_9, USART3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART3_ENABLE)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_UART_MODULE_ENABLED +WEAK const PinMap PinMap_UART_RTS[] = { + {PA_1, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PA_12, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PB_14, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + // {PB_14, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART3_PARTIAL)}, + {PD_4, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART2_ENABLE)}, + {PD_12, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART3_ENABLE)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_UART_MODULE_ENABLED +WEAK const PinMap PinMap_UART_CTS[] = { + {PA_0, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PA_11, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PB_13, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + // {PB_13, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART3_PARTIAL)}, + {PD_3, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART2_ENABLE)}, + {PD_11, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART3_ENABLE)}, + {NC, NP, 0} +}; +#endif + +//*** SPI *** + +#ifdef HAL_SPI_MODULE_ENABLED +WEAK const PinMap PinMap_SPI_MOSI[] = { + {PA_7, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + // {PB_5, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_SPI1_ENABLE)}, + {PB_5, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PB_15, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_SPI_MODULE_ENABLED +WEAK const PinMap PinMap_SPI_MISO[] = { + {PA_6, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + // {PB_4, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_SPI1_ENABLE)}, + {PB_4, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PB_14, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_SPI_MODULE_ENABLED +WEAK const PinMap PinMap_SPI_SCLK[] = { + {PA_5, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + // {PB_3, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_SPI1_ENABLE)}, + {PB_3, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PB_13, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_SPI_MODULE_ENABLED +WEAK const PinMap PinMap_SPI_SSEL[] = { + {PA_4, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + // {PA_15, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_SPI1_ENABLE)}, + {PA_15, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PB_12, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {NC, NP, 0} +}; +#endif + +//*** CAN *** + +#ifdef HAL_CAN_MODULE_ENABLED +WEAK const PinMap PinMap_CAN_RD[] = { + {PA_11, CAN1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, AFIO_NONE)}, + {PB_8, CAN1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, AFIO_CAN1_2)}, + {PD_0, CAN1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, AFIO_CAN1_3)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_CAN_MODULE_ENABLED +WEAK const PinMap PinMap_CAN_TD[] = { + {PA_12, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, AFIO_NONE)}, + {PB_9, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, AFIO_CAN1_2)}, + {PD_1, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, AFIO_CAN1_3)}, + {NC, NP, 0} +}; +#endif + +//*** No ETHERNET *** + +//*** No QUADSPI *** + +//*** USB *** + +#ifdef HAL_PCD_MODULE_ENABLED +WEAK const PinMap PinMap_USB[] = { + {PA_11, USB, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, AFIO_NONE)}, // USB_DM + {PA_12, USB, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, AFIO_NONE)}, // USB_DP + {NC, NP, 0} +}; +#endif + +//*** No USB_OTG_FS *** + +//*** No USB_OTG_HS *** + +//*** SD *** + +#ifdef HAL_SD_MODULE_ENABLED +WEAK const PinMap PinMap_SD[] = { + // {PB_8, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D4 + // {PB_9, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D5 + // {PC_6, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D6 + // {PC_7, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D7 + {PC_8, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D0 + {PC_9, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D1 + {PC_10, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D2 + {PC_11, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D3 + {PC_12, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, AFIO_NONE)}, // SDIO_CK + {PD_2, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, AFIO_NONE)}, // SDIO_CMD + {NC, NP, 0} +}; +#endif diff --git a/buildroot/share/PlatformIO/variants/MARLIN_F103Zx/PinNamesVar.h b/buildroot/share/PlatformIO/variants/MARLIN_F103Zx/PinNamesVar.h new file mode 100644 index 000000000000..d9076b4dfb59 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MARLIN_F103Zx/PinNamesVar.h @@ -0,0 +1,30 @@ +/* SYS_WKUP */ +#ifdef PWR_WAKEUP_PIN1 + SYS_WKUP1 = PA_0, +#endif +#ifdef PWR_WAKEUP_PIN2 + SYS_WKUP2 = NC, +#endif +#ifdef PWR_WAKEUP_PIN3 + SYS_WKUP3 = NC, +#endif +#ifdef PWR_WAKEUP_PIN4 + SYS_WKUP4 = NC, +#endif +#ifdef PWR_WAKEUP_PIN5 + SYS_WKUP5 = NC, +#endif +#ifdef PWR_WAKEUP_PIN6 + SYS_WKUP6 = NC, +#endif +#ifdef PWR_WAKEUP_PIN7 + SYS_WKUP7 = NC, +#endif +#ifdef PWR_WAKEUP_PIN8 + SYS_WKUP8 = NC, +#endif +/* USB */ +#ifdef USBCON + USB_DM = PA_11, + USB_DP = PA_12, +#endif diff --git a/buildroot/share/PlatformIO/variants/MARLIN_F103Zx/hal_conf_custom.h b/buildroot/share/PlatformIO/variants/MARLIN_F103Zx/hal_conf_custom.h new file mode 100644 index 000000000000..014943f311ed --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MARLIN_F103Zx/hal_conf_custom.h @@ -0,0 +1,412 @@ +/** + ****************************************************************************** + * @file stm32f1xx_hal_conf_default.h + * @brief HAL default configuration file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F1xx_HAL_CONF_DEFAULT_H +#define __STM32F1xx_HAL_CONF_DEFAULT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief Include the default list of modules to be used in the HAL driver + * and manage module deactivation + */ +#include "stm32yyxx_hal_conf.h" +#if 0 +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +#define HAL_ADC_MODULE_ENABLED +#define HAL_CAN_MODULE_ENABLED +/*#define HAL_CAN_LEGACY_MODULE_ENABLED*/ +#define HAL_CEC_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED +#define HAL_CRC_MODULE_ENABLED +#define HAL_DAC_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_ETH_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_HCD_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED +#define HAL_I2S_MODULE_ENABLED +#define HAL_IRDA_MODULE_ENABLED +#define HAL_IWDG_MODULE_ENABLED +#define HAL_NAND_MODULE_ENABLED +#define HAL_NOR_MODULE_ENABLED +#define HAL_PCCARD_MODULE_ENABLED +#define HAL_PCD_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_RTC_MODULE_ENABLED +#define HAL_SD_MODULE_ENABLED +#define HAL_SMARTCARD_MODULE_ENABLED +#define HAL_SPI_MODULE_ENABLED +#define HAL_SRAM_MODULE_ENABLED +#define HAL_TIM_MODULE_ENABLED +#define HAL_UART_MODULE_ENABLED +#define HAL_USART_MODULE_ENABLED +#define HAL_WWDG_MODULE_ENABLED +#define HAL_MMC_MODULE_ENABLED +#endif + +/* ########################## Oscillator Values adaptation ####################*/ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) +#if defined(USE_STM3210C_EVAL) +#define HSE_VALUE 25000000U /*!< Value of the External oscillator in Hz */ +#else +#define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */ +#endif +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) +#define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) +#define HSI_VALUE 8000000U /*!< Value of the Internal oscillator in Hz */ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) +#define LSI_VALUE 40000U /*!< LSI Typical Value in Hz */ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined (LSE_VALUE) +#define LSE_VALUE 32768U /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) +#define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#if !defined(VDD_VALUE) +#define VDD_VALUE 3300U /*!< Value of VDD in mv */ +#endif +#if !defined (TICK_INT_PRIORITY) +#define TICK_INT_PRIORITY 0x00U /*!< tick interrupt priority */ +#endif +#if !defined (USE_RTOS) +#define USE_RTOS 0U +#endif +#if !defined (PREFETCH_ENABLE) +#define PREFETCH_ENABLE 1U +#endif + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## Ethernet peripheral configuration ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB 8U /* 8 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* DP83848 PHY Address*/ +#define DP83848_PHY_ADDRESS 0x01U +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY 0x000000FFU +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY 0x00000FFFU + +#define PHY_READ_TO 0x0000FFFFU +#define PHY_WRITE_TO 0x0000FFFFU + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x0000) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x0001) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ + +#define PHY_SR ((uint16_t)0x0010) /*!< PHY status register Offset */ +#define PHY_MICR ((uint16_t)0x0011) /*!< MII Interrupt Control Register */ +#define PHY_MISR ((uint16_t)0x0012) /*!< MII Interrupt Status and Misc. Control Register */ + +#define PHY_LINK_STATUS ((uint16_t)0x0001) /*!< PHY Link mask */ +#define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< PHY Duplex mask */ + +#define PHY_MICR_INT_EN ((uint16_t)0x0002) /*!< PHY Enable interrupts */ +#define PHY_MICR_INT_OE ((uint16_t)0x0001) /*!< PHY Enable output interrupt events */ + +#define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020) /*!< Enable Interrupt on change of link status */ +#define PHY_LINK_INTERRUPT ((uint16_t)0x2000) /*!< PHY link status interrupt mask */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ +#if !defined (USE_SPI_CRC) +#define USE_SPI_CRC 0U +#endif + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED +#include "stm32f1xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED +#include "stm32f1xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED +#include "stm32f1xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED +#include "stm32f1xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED +#include "stm32f1xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED +#include "stm32f1xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CAN_LEGACY_MODULE_ENABLED + #include "Legacy/stm32f1xx_hal_can_legacy.h" +#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED +#include "stm32f1xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED +#include "stm32f1xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED +#include "stm32f1xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED +#include "stm32f1xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED +#include "stm32f1xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED +#include "stm32f1xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED +#include "stm32f1xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED +#include "stm32f1xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED +#include "stm32f1xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED +#include "stm32f1xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED +#include "stm32f1xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED +#include "stm32f1xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED +#include "stm32f1xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_PCCARD_MODULE_ENABLED +#include "stm32f1xx_hal_pccard.h" +#endif /* HAL_PCCARD_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED +#include "stm32f1xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED +#include "stm32f1xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED +#include "stm32f1xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED +#include "stm32f1xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED +#include "stm32f1xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED +#include "stm32f1xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED +#include "stm32f1xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED +#include "stm32f1xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED +#include "stm32f1xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED +#include "stm32f1xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED +#include "stm32f1xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED +#include "stm32f1xx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ +#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ +void assert_failed(uint8_t *file, uint32_t line); +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F1xx_HAL_CONF_DEFAULT_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/buildroot/share/PlatformIO/variants/MARLIN_F103Zx/ldscript.ld b/buildroot/share/PlatformIO/variants/MARLIN_F103Zx/ldscript.ld new file mode 100644 index 000000000000..09088b622c87 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MARLIN_F103Zx/ldscript.ld @@ -0,0 +1,197 @@ +/* +****************************************************************************** +** + +** File : LinkerScript.ld +** +** Author : Auto-generated by STM32CubeIDE +** +** Abstract : Linker script for STM32F103Z(C/D/E/G/GTx Device from STM32F1 series +** 256/386/512K/786/1024bytes FLASH +** 48/64/96Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +**

© COPYRIGHT(c) 2019 STMicroelectronics

+** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** 1. Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** 3. Neither the name of STMicroelectronics nor the names of its contributors +** may be used to endorse or promote products derived from this software +** without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20000000 + LD_MAX_DATA_SIZE; /* end of "RAM" Ram type memory */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = LD_MAX_DATA_SIZE + FLASH (rx) : ORIGIN = 0x8000000 + LD_FLASH_OFFSET, LENGTH = LD_MAX_SIZE - LD_FLASH_OFFSET +} + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + .ARM : { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + .init_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + .fini_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/buildroot/share/PlatformIO/variants/MARLIN_F103Zx/variant.cpp b/buildroot/share/PlatformIO/variants/MARLIN_F103Zx/variant.cpp new file mode 100644 index 000000000000..ff7ab771c02b --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MARLIN_F103Zx/variant.cpp @@ -0,0 +1,222 @@ +/* + ******************************************************************************* + * Copyright (c) 2019, STMicroelectronics + * All rights reserved. + * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +#include "pins_arduino.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Digital PinName array +const PinName digitalPin[] = { + PA_0, //D0 + PA_1, //D1 + PA_2, //D2 + PA_3, //D3 + PA_4, //D4 + PA_5, //D5 + PA_6, //D6 + PA_7, //D7 + PA_8, //D8 + PA_9, //D9 + PA_10, //D10 + PA_11, //D11 + PA_12, //D12 + PA_13, //D13 + PA_14, //D14 + PA_15, //D15 + + PB_0, //D16 + PB_1, //D17 + PB_2, //D18 + PB_3, //D19 + PB_4, //D20 + PB_5, //D21 + PB_6, //D22 + PB_7, //D23 + PB_8, //D24 + PB_9, //D25 + PB_10, //D26 + PB_11, //D27 + PB_12, //D28 + PB_13, //D29 + PB_14, //D30 + PB_15, //D31 + + PC_0, //D32 + PC_1, //D33 + PC_2, //D34 + PC_3, //D35 + PC_4, //D36 + PC_5, //D37 + PC_6, //D38 + PC_7, //D39 + PC_8, //D40 + PC_9, //D41 + PC_10, //D42 + PC_11, //D43 + PC_12, //D44 + PC_13, //D45 + PC_14, //D46 + PC_15, //D47 + + PD_0, //D48 + PD_1, //D49 + PD_2, //D50 + PD_3, //D51 + PD_4, //D52 + PD_5, //D53 + PD_6, //D54 + PD_7, //D55 + PD_8, //D56 + PD_9, //D57 + PD_10, //D58 + PD_11, //D59 + PD_12, //D60 + PD_13, //D61 + PD_14, //D62 + PD_15, //D63 + + PE_0, //D64 + PE_1, //D65 + PE_2, //D66 + PE_3, //D67 + PE_4, //D68 + PE_5, //D69 + PE_6, //D70 + PE_7, //D71 + PE_8, //D72 + PE_9, //D73 + PE_10, //D74 + PE_11, //D75 + PE_12, //D76 + PE_13, //D77 + PE_14, //D78 + PE_15, //D79 + + PF_0, //D80 + PF_1, //D81 + PF_2, //D82 + PF_3, //D83 + PF_4, //D84 + PF_5, //D85 + PF_6, //D86 + PF_7, //D87 + PF_8, //D88 + PF_9, //D89 + PF_10, //D90 + PF_11, //D91 + PF_12, //D92 + PF_13, //D93 + PF_14, //D94 + PF_15, //D95 + + PG_0, //D96 + PG_1, //D97 + PG_2, //D98 + PG_3, //D99 + PG_4, //D100 + PG_5, //D101 + PG_6, //D102 + PG_7, //D103 + PG_8, //D104 + PG_9, //D105 + PG_10, //D106 + PG_11, //D107 + PG_12, //D108 + PG_13, //D109 + PG_14, //D110 + PG_15 //D111 +}; + +// Analog (Ax) pin number array +const uint32_t analogInputPin[] = { + 0, // A0, PA0 + 1, // A1, PA1 + 2, // A2, PA2 + 3, // A3, PA3 + 4, // A4, PA4 + 5, // A5, PA5 + 6, // A6, PA6 + 7, // A7, PA7 + 16, // A8, PB0 + 17, // A9, PB1 + 32, // A10, PC0 + 33, // A11, PC1 + 34, // A12, PC2 + 35, // A13, PC3 + 36, // A14, PC4 + 37, // A15, PC5 + 86, // A16, PF6 + 87, // A17, PF7 + 88, // A18, PF8 + 89, // A19, PF9 + 90 // A20, PF10 +}; + +#ifdef __cplusplus +} +#endif + +// ---------------------------------------------------------------------------- + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief System Clock Configuration + * @param None + * @retval None + */ +WEAK void SystemClock_Config(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {}; + + /* Initializes the CPU, AHB and APB busses clocks */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { + Error_Handler(); + } + /* Initializes the CPU, AHB and APB busses clocks */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK + | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { + Error_Handler(); + } + + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_USB; + PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6; + PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { + Error_Handler(); + } +} + + +#ifdef __cplusplus +} +#endif diff --git a/buildroot/share/PlatformIO/variants/MARLIN_F103Zx/variant.h b/buildroot/share/PlatformIO/variants/MARLIN_F103Zx/variant.h new file mode 100644 index 000000000000..fb878f8b78f3 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MARLIN_F103Zx/variant.h @@ -0,0 +1,232 @@ +/* + ******************************************************************************* + * Copyright (c) 2019, STMicroelectronics + * All rights reserved. + * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +#ifndef _VARIANT_ARDUINO_STM32_ +#define _VARIANT_ARDUINO_STM32_ + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ +#define PA0 0 +#define PA1 1 +#define PA2 2 +#define PA3 3 +#define PA4 4 +#define PA5 5 +#define PA6 6 +#define PA7 7 +#define PA8 8 +#define PA9 9 +#define PA10 10 +#define PA11 11 +#define PA12 12 +#define PA13 13 +#define PA14 14 +#define PA15 15 + +#define PB0 16 +#define PB1 17 +#define PB2 18 +#define PB3 19 +#define PB4 20 +#define PB5 21 +#define PB6 22 +#define PB7 23 +#define PB8 24 +#define PB9 25 +#define PB10 26 +#define PB11 27 +#define PB12 28 +#define PB13 29 +#define PB14 30 +#define PB15 31 + +#define PC0 32 +#define PC1 33 +#define PC2 34 +#define PC3 35 +#define PC4 36 +#define PC5 37 +#define PC6 38 +#define PC7 39 +#define PC8 40 +#define PC9 41 +#define PC10 42 +#define PC11 43 +#define PC12 44 +#define PC13 45 +#define PC14 46 +#define PC15 47 + +#define PD0 48 +#define PD1 49 +#define PD2 50 +#define PD3 51 +#define PD4 52 +#define PD5 53 +#define PD6 54 +#define PD7 55 +#define PD8 56 +#define PD9 57 +#define PD10 58 +#define PD11 59 +#define PD12 60 +#define PD13 61 +#define PD14 62 +#define PD15 63 + +#define PE0 64 +#define PE1 65 +#define PE2 66 +#define PE3 67 +#define PE4 68 +#define PE5 69 +#define PE6 70 +#define PE7 71 +#define PE8 72 +#define PE9 73 +#define PE10 74 +#define PE11 75 +#define PE12 76 +#define PE13 77 +#define PE14 78 +#define PE15 79 + +#define PF0 80 +#define PF1 81 +#define PF2 82 +#define PF3 83 +#define PF4 84 +#define PF5 85 +#define PF6 86 +#define PF7 87 +#define PF8 88 +#define PF9 89 +#define PF10 90 +#define PF11 91 +#define PF12 92 +#define PF13 93 +#define PF14 94 +#define PF15 95 + +#define PG0 96 +#define PG1 97 +#define PG2 98 +#define PG3 99 +#define PG4 100 +#define PG5 101 +#define PG6 102 +#define PG7 103 +#define PG8 104 +#define PG9 105 +#define PG10 106 +#define PG11 107 +#define PG12 108 +#define PG13 109 +#define PG14 110 +#define PG15 111 + +// This must be a literal +#define NUM_DIGITAL_PINS 112 +#define NUM_ANALOG_INPUTS 21 + +// On-board LED pin number +#ifdef ARDUINO_VCCGND_F103ZET6_MINI +#define LED_BUILTIN PG15 +#elif defined(ARDUINO_VCCGND_F103ZET6) +#define LED_BUILTIN PC13 +#elif !defined(LED_BUILTIN) +#define LED_BUILTIN PC13 +#endif + +// On-board user button +#ifndef USER_BTN +#define USER_BTN PB1 +#endif + +// SPI Definitions +#ifdef ARDUINO_VCCGND_F103ZET6 +#define PIN_SPI_SS PA15 +#define PIN_SPI_MOSI PB5 +#define PIN_SPI_MISO PB4 +#define PIN_SPI_SCK PB3 +#else +#define PIN_SPI_SS PC4 +#define PIN_SPI_MOSI PA7 +#define PIN_SPI_MISO PA6 +#define PIN_SPI_SCK PA5 +#endif + +// I2C Definitions +#define PIN_WIRE_SDA PB7 +#define PIN_WIRE_SCL PB6 + +// Timer Definitions (optional) +// Use TIM6/TIM7 when possible as servo and tone don't need GPIO output pin +#define TIMER_TONE TIM6 +#define TIMER_SERVO TIM7 + +// UART Definitions +// Define here Serial instance number to map on Serial generic name +#define SERIAL_UART_INSTANCE 1 + +// Default pin used for 'Serial' instance (ex: ST-Link) +// Mandatory for Firmata +#define PIN_SERIAL_RX PA10 +#define PIN_SERIAL_TX PA9 + +// Default pin used for 'Serial2' instance +#define PIN_SERIAL2_RX PA3 +#define PIN_SERIAL2_TX PA2 + +// Default pin used for 'Serial3' instance +#define PIN_SERIAL3_RX PB11 +#define PIN_SERIAL3_TX PB10 + +/* Extra HAL modules */ +#define HAL_DAC_MODULE_ENABLED +#define HAL_SD_MODULE_ENABLED +#define HAL_SRAM_MODULE_ENABLED + +#ifdef __cplusplus +} // extern "C" +#endif +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + // These serial port names are intended to allow libraries and architecture-neutral + // sketches to automatically default to the correct port name for a particular type + // of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, + // the first hardware serial port whose RX/TX pins are not dedicated to another use. + // + // SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor + // + // SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial + // + // SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library + // + // SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. + // + // SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX + // pins are NOT connected to anything by default. + #define SERIAL_PORT_MONITOR Serial + #define SERIAL_PORT_HARDWARE Serial1 +#endif + +#endif /* _VARIANT_ARDUINO_STM32_ */ diff --git a/buildroot/share/PlatformIO/variants/MARLIN_F407VE/PeripheralPins.c b/buildroot/share/PlatformIO/variants/MARLIN_F407VE/PeripheralPins.c index 6b6cfdbcb0b8..d3c76713bf53 100644 --- a/buildroot/share/PlatformIO/variants/MARLIN_F407VE/PeripheralPins.c +++ b/buildroot/share/PlatformIO/variants/MARLIN_F407VE/PeripheralPins.c @@ -122,9 +122,7 @@ WEAK const PinMap PinMap_I2C_SDA[] = { #endif {NC, NP, 0} }; -#endif -#ifdef HAL_I2C_MODULE_ENABLED WEAK const PinMap PinMap_I2C_SCL[] = { {PA_8, I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)}, {PB_6, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)}, @@ -239,9 +237,7 @@ WEAK const PinMap PinMap_UART_TX[] = { #endif {NC, NP, 0} }; -#endif -#ifdef HAL_UART_MODULE_ENABLED WEAK const PinMap PinMap_UART_RX[] = { {PA_1, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, {PA_3, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, @@ -259,9 +255,7 @@ WEAK const PinMap PinMap_UART_RX[] = { #endif {NC, NP, 0} }; -#endif -#ifdef HAL_UART_MODULE_ENABLED WEAK const PinMap PinMap_UART_RTS[] = { {PA_1, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, {PA_12, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, @@ -274,9 +268,7 @@ WEAK const PinMap PinMap_UART_RTS[] = { #endif {NC, NP, 0} }; -#endif -#ifdef HAL_UART_MODULE_ENABLED WEAK const PinMap PinMap_UART_CTS[] = { {PA_0, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, {PA_11, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, @@ -303,9 +295,7 @@ WEAK const PinMap PinMap_SPI_MOSI[] = { {PC_12, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, {NC, NP, 0} }; -#endif -#ifdef HAL_SPI_MODULE_ENABLED WEAK const PinMap PinMap_SPI_MISO[] = { {PA_6, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, //{PB_4, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, @@ -315,9 +305,7 @@ WEAK const PinMap PinMap_SPI_MISO[] = { {PC_11, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, {NC, NP, 0} }; -#endif -#ifdef HAL_SPI_MODULE_ENABLED WEAK const PinMap PinMap_SPI_SCLK[] = { {PA_5, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, //{PB_3, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, @@ -327,9 +315,7 @@ WEAK const PinMap PinMap_SPI_SCLK[] = { {PC_10, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, {NC, NP, 0} }; -#endif -#ifdef HAL_SPI_MODULE_ENABLED WEAK const PinMap PinMap_SPI_SSEL[] = { {PA_4, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, //{PA_4, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, @@ -352,9 +338,7 @@ WEAK const PinMap PinMap_CAN_RD[] = { {PD_0, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, {NC, NP, 0} }; -#endif -#ifdef HAL_CAN_MODULE_ENABLED WEAK const PinMap PinMap_CAN_TD[] = { {PA_12, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, {PB_6, CAN2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)}, @@ -388,12 +372,12 @@ WEAK const PinMap PinMap_Ethernet[] = { {PC_4, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_RXD0 {PC_5, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_RXD1 {PE_2, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TXD3 -#if defined(ARDUINO_BLACK_F407ZE) || defined(ARDUINO_BLACK_F407ZG) - {PG_8, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_PPS_OUT - {PG_11, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TX_EN - {PG_13, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TXD0 - {PG_14, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TXD1 -#endif + #if defined(ARDUINO_BLACK_F407ZE) || defined(ARDUINO_BLACK_F407ZG) + {PG_8, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_PPS_OUT + {PG_11, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TX_EN + {PG_13, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TXD0 + {PG_14, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TXD1 + #endif {NC, NP, 0} }; #endif @@ -411,9 +395,7 @@ WEAK const PinMap PinMap_USB_OTG_FS[] = { {PA_12, USB_OTG_FS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_FS)}, // USB_OTG_FS_DP {NC, NP, 0} }; -#endif -#ifdef HAL_PCD_MODULE_ENABLED WEAK const PinMap PinMap_USB_OTG_HS[] = { #ifdef USE_USB_HS_IN_FS {PA_4, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_SOF diff --git a/buildroot/share/PlatformIO/variants/MARLIN_F407VE/PinNamesVar.h b/buildroot/share/PlatformIO/variants/MARLIN_F407VE/PinNamesVar.h index f3c4f0ee0762..b4bb9d45f8ac 100644 --- a/buildroot/share/PlatformIO/variants/MARLIN_F407VE/PinNamesVar.h +++ b/buildroot/share/PlatformIO/variants/MARLIN_F407VE/PinNamesVar.h @@ -1,50 +1,50 @@ /* SYS_WKUP */ #ifdef PWR_WAKEUP_PIN1 -SYS_WKUP1 = PA_0, + SYS_WKUP1 = PA_0, #endif #ifdef PWR_WAKEUP_PIN2 -SYS_WKUP2 = NC, + SYS_WKUP2 = NC, #endif #ifdef PWR_WAKEUP_PIN3 -SYS_WKUP3 = NC, + SYS_WKUP3 = NC, #endif #ifdef PWR_WAKEUP_PIN4 -SYS_WKUP4 = NC, + SYS_WKUP4 = NC, #endif #ifdef PWR_WAKEUP_PIN5 -SYS_WKUP5 = NC, + SYS_WKUP5 = NC, #endif #ifdef PWR_WAKEUP_PIN6 -SYS_WKUP6 = NC, + SYS_WKUP6 = NC, #endif #ifdef PWR_WAKEUP_PIN7 -SYS_WKUP7 = NC, + SYS_WKUP7 = NC, #endif #ifdef PWR_WAKEUP_PIN8 -SYS_WKUP8 = NC, + SYS_WKUP8 = NC, #endif /* USB */ #ifdef USBCON -USB_OTG_FS_SOF = PA_8, -USB_OTG_FS_VBUS = PA_9, -USB_OTG_FS_ID = PA_10, -USB_OTG_FS_DM = PA_11, -USB_OTG_FS_DP = PA_12, -USB_OTG_HS_ULPI_D0 = PA_3, -USB_OTG_HS_SOF = PA_4, -USB_OTG_HS_ULPI_CK = PA_5, -USB_OTG_HS_ULPI_D1 = PB_0, -USB_OTG_HS_ULPI_D2 = PB_1, -USB_OTG_HS_ULPI_D7 = PB_5, -USB_OTG_HS_ULPI_D3 = PB_10, -USB_OTG_HS_ULPI_D4 = PB_11, -USB_OTG_HS_ID = PB_12, -USB_OTG_HS_ULPI_D5 = PB_12, -USB_OTG_HS_ULPI_D6 = PB_13, -USB_OTG_HS_VBUS = PB_13, -USB_OTG_HS_DM = PB_14, -USB_OTG_HS_DP = PB_15, -USB_OTG_HS_ULPI_STP = PC_0, -USB_OTG_HS_ULPI_DIR = PC_2, -USB_OTG_HS_ULPI_NXT = PC_3, + USB_OTG_FS_SOF = PA_8, + USB_OTG_FS_VBUS = PA_9, + USB_OTG_FS_ID = PA_10, + USB_OTG_FS_DM = PA_11, + USB_OTG_FS_DP = PA_12, + USB_OTG_HS_ULPI_D0 = PA_3, + USB_OTG_HS_SOF = PA_4, + USB_OTG_HS_ULPI_CK = PA_5, + USB_OTG_HS_ULPI_D1 = PB_0, + USB_OTG_HS_ULPI_D2 = PB_1, + USB_OTG_HS_ULPI_D7 = PB_5, + USB_OTG_HS_ULPI_D3 = PB_10, + USB_OTG_HS_ULPI_D4 = PB_11, + USB_OTG_HS_ID = PB_12, + USB_OTG_HS_ULPI_D5 = PB_12, + USB_OTG_HS_ULPI_D6 = PB_13, + USB_OTG_HS_VBUS = PB_13, + USB_OTG_HS_DM = PB_14, + USB_OTG_HS_DP = PB_15, + USB_OTG_HS_ULPI_STP = PC_0, + USB_OTG_HS_ULPI_DIR = PC_2, + USB_OTG_HS_ULPI_NXT = PC_3, #endif diff --git a/buildroot/share/PlatformIO/variants/FYSETC_S6/PeripheralPins.c b/buildroot/share/PlatformIO/variants/MARLIN_FYSETC_S6/PeripheralPins.c similarity index 100% rename from buildroot/share/PlatformIO/variants/FYSETC_S6/PeripheralPins.c rename to buildroot/share/PlatformIO/variants/MARLIN_FYSETC_S6/PeripheralPins.c diff --git a/buildroot/share/PlatformIO/variants/MARLIN_FYSETC_S6/PinNamesVar.h b/buildroot/share/PlatformIO/variants/MARLIN_FYSETC_S6/PinNamesVar.h new file mode 100644 index 000000000000..bff3f2134987 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MARLIN_FYSETC_S6/PinNamesVar.h @@ -0,0 +1,30 @@ +/* SYS_WKUP */ +#ifdef PWR_WAKEUP_PIN1 + SYS_WKUP1 = PA_0, /* SYS_WKUP0 */ +#endif +#ifdef PWR_WAKEUP_PIN2 + SYS_WKUP2 = NC, +#endif +#ifdef PWR_WAKEUP_PIN3 + SYS_WKUP3 = NC, +#endif +#ifdef PWR_WAKEUP_PIN4 + SYS_WKUP4 = NC, +#endif +#ifdef PWR_WAKEUP_PIN5 + SYS_WKUP5 = NC, +#endif +#ifdef PWR_WAKEUP_PIN6 + SYS_WKUP6 = NC, +#endif +#ifdef PWR_WAKEUP_PIN7 + SYS_WKUP7 = NC, +#endif +#ifdef PWR_WAKEUP_PIN8 + SYS_WKUP8 = NC, +#endif +/* USB */ +#ifdef USBCON + USB_OTG_FS_DM = PA_11, + USB_OTG_FS_DP = PA_12, +#endif diff --git a/buildroot/share/PlatformIO/variants/FYSETC_S6/ldscript.ld b/buildroot/share/PlatformIO/variants/MARLIN_FYSETC_S6/ldscript.ld similarity index 100% rename from buildroot/share/PlatformIO/variants/FYSETC_S6/ldscript.ld rename to buildroot/share/PlatformIO/variants/MARLIN_FYSETC_S6/ldscript.ld diff --git a/buildroot/share/PlatformIO/variants/FYSETC_S6/variant.cpp b/buildroot/share/PlatformIO/variants/MARLIN_FYSETC_S6/variant.cpp similarity index 100% rename from buildroot/share/PlatformIO/variants/FYSETC_S6/variant.cpp rename to buildroot/share/PlatformIO/variants/MARLIN_FYSETC_S6/variant.cpp diff --git a/buildroot/share/PlatformIO/variants/FYSETC_S6/variant.h b/buildroot/share/PlatformIO/variants/MARLIN_FYSETC_S6/variant.h similarity index 98% rename from buildroot/share/PlatformIO/variants/FYSETC_S6/variant.h rename to buildroot/share/PlatformIO/variants/MARLIN_FYSETC_S6/variant.h index be04ef6b86c3..ee4b1ef29608 100644 --- a/buildroot/share/PlatformIO/variants/FYSETC_S6/variant.h +++ b/buildroot/share/PlatformIO/variants/MARLIN_FYSETC_S6/variant.h @@ -115,7 +115,7 @@ extern "C" { #define NUM_ANALOG_FIRST 80 // PWM resolution -#define PWM_RESOLUTION 8 +// #define PWM_RESOLUTION 12 #define PWM_FREQUENCY 20000 // >= 20 Khz => inaudible noise for fans #define PWM_MAX_DUTY_CYCLE 255 @@ -132,7 +132,7 @@ extern "C" { // Timer Definitions // Do not use timer used by PWM pin. See PinMap_PWM. #define TIMER_TONE TIM6 -#define TIMER_SERVO TIM2 +#define TIMER_SERVO TIM5 #define TIMER_SERIAL TIM7 // UART Definitions diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/board.cpp b/buildroot/share/PlatformIO/variants/MEEB_3DP/board.cpp new file mode 100644 index 000000000000..5ddeb1f1d9ef --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/board.cpp @@ -0,0 +1,161 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * 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. + *****************************************************************************/ + +/** + * @file wirish/boards/maple/board.cpp + * @author Marti Bolivar + * @brief Maple board file. + */ + +#include // For this board's header file + + +/* Roger Clark. Added next to includes for changes to Serial */ +#include +#include + +#include // For stm32_pin_info and its contents + // (these go into PIN_MAP). + +#include "boards_private.h" // For PMAP_ROW(), which makes + // PIN_MAP easier to read. + +// boardInit(): nothing special to do for Maple. +// +// When defining your own board.cpp, you can put extra code in this +// function if you have anything you want done on reset, before main() +// or setup() are called. +// +// If there's nothing special you need done, feel free to leave this +// function out, as we do here. + +void boardInit(void) { + // afio_remap(AFIO_REMAP_I2C1); +} + +// Pin map: this lets the basic I/O functions (digitalWrite(), +// analogRead(), pwmWrite()) translate from pin numbers to STM32 +// peripherals. +// +// PMAP_ROW() lets us specify a row (really a struct stm32_pin_info) +// in the pin map. Its arguments are: +// +// - GPIO device for the pin (&gpioa, etc.) +// - GPIO bit for the pin (0 through 15) +// - Timer device, or NULL if none +// - Timer channel (1 to 4, for PWM), or 0 if none +// - ADC device, or NULL if none +// - ADC channel, or ADCx if none + +extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { + /* + gpio_dev *gpio_device; GPIO device + timer_dev *timer_device; Pin's timer device, if any. + const adc_dev *adc_device; ADC device, if any. + uint8 gpio_bit; Pin's GPIO port bit. + uint8 timer_channel; Timer channel, or 0 if none. + uint8 adc_channel; Pin ADC channel, or ADCx if none. + */ + + {&gpioa, &timer2, &adc1, 0, 1, 0}, /* PA0 */ + {&gpioa, &timer2, &adc1, 1, 2, 1}, /* PA1 */ + {&gpioa, &timer2, &adc1, 2, 3, 2}, /* PA2 */ + {&gpioa, &timer2, &adc1, 3, 4, 3}, /* PA3 */ + {&gpioa, NULL, &adc1, 4, 0, 4}, /* PA4 */ + {&gpioa, NULL, &adc1, 5, 0, 5}, /* PA5 */ + {&gpioa, &timer3, &adc1, 6, 1, 6}, /* PA6 */ + {&gpioa, &timer3, &adc1, 7, 2, 7}, /* PA7 */ + {&gpioa, &timer1, NULL, 8, 1, ADCx}, /* PA8 */ + {&gpioa, &timer1, NULL, 9, 2, ADCx}, /* PA9 */ + {&gpioa, &timer1, NULL, 10, 3, ADCx}, /* PA10 */ + {&gpioa, NULL, NULL, 11, 0, ADCx}, /* PA11 */ + {&gpioa, NULL, NULL, 12, 0, ADCx}, /* PA12 */ + {&gpioa, NULL, NULL, 13, 0, ADCx}, /* PA13 */ + {&gpioa, NULL, NULL, 14, 0, ADCx}, /* PA14 */ + {&gpioa, NULL, NULL, 15, 0, ADCx}, /* PA15 */ + + {&gpiob, &timer3, &adc1, 0, 3, 8}, /* PB0 */ + {&gpiob, &timer3, &adc1, 1, 4, 9}, /* PB1 */ + {&gpiob, NULL, NULL, 2, 0, ADCx}, /* PB2 */ + {&gpiob, NULL, NULL, 3, 0, ADCx}, /* PB3 */ + {&gpiob, NULL, NULL, 4, 0, ADCx}, /* PB4 */ + {&gpiob, NULL, NULL, 5, 0, ADCx}, /* PB5 */ + {&gpiob, &timer4, NULL, 6, 1, ADCx}, /* PB6 */ + {&gpiob, &timer4, NULL, 7, 2, ADCx}, /* PB7 */ + {&gpiob, &timer4, NULL, 8, 3, ADCx}, /* PB8 */ + {&gpiob, NULL, NULL, 9, 0, ADCx}, /* PB9 */ + {&gpiob, NULL, NULL, 10, 0, ADCx}, /* PB10 */ + {&gpiob, NULL, NULL, 11, 0, ADCx}, /* PB11 */ + {&gpiob, NULL, NULL, 12, 0, ADCx}, /* PB12 */ + {&gpiob, NULL, NULL, 13, 0, ADCx}, /* PB13 */ + {&gpiob, NULL, NULL, 14, 0, ADCx}, /* PB14 */ + {&gpiob, NULL, NULL, 15, 0, ADCx}, /* PB15 */ + + + {&gpioc, NULL, &adc1, 0, 0, 10}, /* PC0 */ + {&gpioc, NULL, &adc1, 1, 0, 11}, /* PC1 */ + {&gpioc, NULL, &adc1, 2, 0, 12}, /* PC2 */ + {&gpioc, NULL, &adc1, 3, 0, 13}, /* PC3 */ + {&gpioc, NULL, &adc1, 4, 0, 14}, /* PC4 */ + {&gpioc, NULL, &adc1, 5, 0, 15}, /* PC5 */ + {&gpioc, &timer8, NULL, 6, 1, ADCx}, /* PC6 */ + {&gpioc, &timer8, NULL, 7, 2, ADCx}, /* PC7 */ + {&gpioc, &timer8, NULL, 8, 3, ADCx}, /* PC8 */ + {&gpioc, &timer8, NULL, 9, 4, ADCx}, /* PC9 */ + {&gpioc, NULL, NULL, 10, 0, ADCx}, /* PC10 UART4_TX/SDIO_D2 */ + {&gpioc, NULL, NULL, 11, 0, ADCx}, /* PC11 UART4_RX/SDIO_D3 */ + {&gpioc, NULL, NULL, 12, 0, ADCx}, /* PC12 UART5_TX/SDIO_CK */ + {&gpioc, NULL, NULL, 13, 0, ADCx}, /* PC13 TAMPER-RTC */ + {&gpioc, NULL, NULL, 14, 0, ADCx}, /* PC14 OSC32_IN */ + {&gpioc, NULL, NULL, 15, 0, ADCx}, /* PC15 OSC32_OUT */ + + {&gpiod, NULL, NULL, 0, 0, ADCx} , /* PD0 OSC_IN */ + {&gpiod, NULL, NULL, 1, 0, ADCx} , /* PD1 OSC_OUT */ + {&gpiod, NULL, NULL, 2, 0, ADCx} , /* PD2 TIM3_ETR/UART5_RX SDIO_CMD */ +}; + +/* Basically everything that is defined as having a timer us PWM */ +extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { + PA0,PA1,PA2,PA3,PA6,PA7,PA8,PA9,PA10,PB0,PB1,PB6,PB7,PB8,PB9,PC6,PC7,PC8,PC9 +}; + +/* Basically everything that is defined having ADC */ +extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = { + PA0,PA1,PA2,PA3,PA4,PA5,PA6,PA7,PB0,PB1,PC0,PC1,PC2,PC3,PC4,PC5 +}; + +/* not sure what this us used for */ +extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { + BOARD_JTMS_SWDIO_PIN, + BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN +}; + +DEFINE_HWSERIAL(Serial1, 1); +DEFINE_HWSERIAL(Serial2, 2); +DEFINE_HWSERIAL(Serial3, 3); +DEFINE_HWSERIAL_UART(Serial4, 4); +DEFINE_HWSERIAL_UART(Serial5, 5); + diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/board/board.h b/buildroot/share/PlatformIO/variants/MEEB_3DP/board/board.h new file mode 100644 index 000000000000..da9ffd893f87 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/board/board.h @@ -0,0 +1,125 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * 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. + *****************************************************************************/ + +/** + * @file maple_RET6.h + * @author Marti Bolivar + * @brief Private include file for Maple RET6 Edition in boards.h + * + * See maple.h for more information on these definitions. + */ + +#ifndef _BOARDS_GENERIC_STM32F103R_H_ +#define _BOARDS_GENERIC_STM32F103R_H_ + +/* A few of these values will seem strange given that it's a + * high-density board. */ + +#define CYCLES_PER_MICROSECOND 72 +#define SYSTICK_RELOAD_VAL (F_CPU/1000) - 1 /* takes a cycle to reload */ + +// USARTS +#define BOARD_NR_USARTS 5 +#define BOARD_USART1_TX_PIN PA9 +#define BOARD_USART1_RX_PIN PA10 + +#define BOARD_USART2_TX_PIN PA2 +#define BOARD_USART2_RX_PIN PA3 + +#define BOARD_USART3_TX_PIN PB10 +#define BOARD_USART3_RX_PIN PB11 + +#define BOARD_USART4_TX_PIN PC10 +#define BOARD_USART4_RX_PIN PC11 + +#define BOARD_USART5_TX_PIN PC12 +#define BOARD_USART5_RX_PIN PD2 + +/* Note: + * + * SPI3 is unusable due to pin 43 (PB4) and NRST tie-together :(, but + * leave the definitions so as not to clutter things up. This is only + * OK since RET6 Ed. is specifically advertised as a beta board. */ +#define BOARD_NR_SPI 3 +#define BOARD_SPI1_NSS_PIN PA4 +#define BOARD_SPI1_SCK_PIN PA5 +#define BOARD_SPI1_MISO_PIN PA6 +#define BOARD_SPI1_MOSI_PIN PA7 + + + +#define BOARD_SPI2_NSS_PIN PB12 +#define BOARD_SPI2_SCK_PIN PB13 +#define BOARD_SPI2_MISO_PIN PB14 +#define BOARD_SPI2_MOSI_PIN PB15 + + +#define BOARD_SPI3_NSS_PIN PA15 +#define BOARD_SPI3_SCK_PIN PB3 +#define BOARD_SPI3_MISO_PIN PB4 +#define BOARD_SPI3_MOSI_PIN PB5 + + +/* GPIO A to E = 5 * 16 - BOOT1 not used = 79*/ +#define BOARD_NR_GPIO_PINS 51 +/* Note: NOT 19. The missing one is D38 a.k.a. BOARD_BUTTON_PIN, which + * isn't broken out to a header and is thus unusable for PWM. */ +#define BOARD_NR_PWM_PINS 19 +#define BOARD_NR_ADC_PINS 16 +#define BOARD_NR_USED_PINS 7 + +#define BOARD_JTMS_SWDIO_PIN 39 +#define BOARD_JTCK_SWCLK_PIN 40 +#define BOARD_JTDI_PIN 41 +#define BOARD_JTDO_PIN 42 +#define BOARD_NJTRST_PIN 43 + +/* USB configuration. BOARD_USB_DISC_DEV is the GPIO port containing + * the USB_DISC pin, and BOARD_USB_DISC_BIT is that pin's bit. */ +#define BOARD_USB_DISC_DEV GPIOC +#define BOARD_USB_DISC_BIT 12 + +/* + * SDIO Pins + */ +#define BOARD_SDIO_D0 PC8 +#define BOARD_SDIO_D1 PC9 +#define BOARD_SDIO_D2 PC10 +#define BOARD_SDIO_D3 PC11 +#define BOARD_SDIO_CLK PC12 +#define BOARD_SDIO_CMD PD2 + +/* Pin aliases: these give the GPIO port/bit for each pin as an + * enum. These are optional, but recommended. They make it easier to + * write code using low-level GPIO functionality. */ +enum { +PA0,PA1,PA2,PA3,PA4,PA5,PA6,PA7,PA8,PA9,PA10,PA11,PA12,PA13,PA14,PA15, +PB0,PB1,PB2,PB3,PB4,PB5,PB6,PB7,PB8,PB9,PB10,PB11,PB12,PB13,PB14,PB15, +PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PC8,PC9,PC10,PC11,PC12,PC13,PC14,PC15, +PD0,PD1,PD2 +};/* Note PB2 is skipped as this is Boot1 and is not going to be much use as its likely to be pulled permanently low */ + +#endif diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/bootloader.ld b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/bootloader.ld new file mode 100644 index 000000000000..ca56532fdd02 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/bootloader.ld @@ -0,0 +1,18 @@ +/* + * Linker script for Generic STM32F103RE boards, using the generic bootloader (which takes the lower 8k of memory) + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + rom (rx) : ORIGIN = 0x08002000, LENGTH = 504K +} + + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/common.inc b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/common.inc new file mode 100644 index 000000000000..e086a58bca9e --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/common.inc @@ -0,0 +1,220 @@ +/* + * Linker script for libmaple. + * + * Original author "lanchon" from ST forums, with modifications by LeafLabs. + */ + +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +/* + * Configure other libraries we want in the link. + * + * libgcc, libc, and libm are common across supported toolchains. + * However, some toolchains require additional archives which aren't + * present everywhere (e.g. ARM's gcc-arm-embedded releases). + * + * To hack around this, we let the build system specify additional + * archives by putting the right extra_libs.inc (in a directory under + * toolchains/) in our search path. + */ +GROUP(libgcc.a libc.a libm.a) +INCLUDE extra_libs.inc + +/* + * These force the linker to search for vector table symbols. + * + * These symbols vary by STM32 family (and also within families). + * It's up to the build system to configure the link's search path + * properly for the target MCU. + */ +INCLUDE vector_symbols.inc + +/* STM32 vector table. */ +EXTERN(__stm32_vector_table) + +/* C runtime initialization function. */ +EXTERN(start_c) + +/* main entry point */ +EXTERN(main) + +/* Initial stack pointer value. */ +EXTERN(__msp_init) +PROVIDE(__msp_init = ORIGIN(ram) + LENGTH(ram)); + +/* Reset vector and chip reset entry point */ +EXTERN(__start__) +ENTRY(__start__) +PROVIDE(__exc_reset = __start__); + +/* Heap boundaries, for libmaple */ +EXTERN(_lm_heap_start); +EXTERN(_lm_heap_end); + +SECTIONS +{ + .text : + { + __text_start__ = .; + /* + * STM32 vector table. Leave this here. Yes, really. + */ + *(.stm32.interrupt_vector) + + /* + * Program code and vague linking + */ + *(.text .text.* .gnu.linkonce.t.*) + *(.plt) + *(.gnu.warning) + *(.glue_7t) *(.glue_7) *(.vfp11_veneer) + + *(.ARM.extab* .gnu.linkonce.armextab.*) + *(.gcc_except_table) + *(.eh_frame_hdr) + *(.eh_frame) + + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(0x4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > REGION_TEXT + + /* + * End of text + */ + .text.align : + { + . = ALIGN(8); + __text_end__ = .; + } > REGION_TEXT + + /* + * .ARM.exidx exception unwinding; mandated by ARM's C++ ABI + */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > REGION_RODATA + __exidx_end = .; + + /* + * .data + */ + .data : + { + __data_start__ = .; + LONG(0) + . = ALIGN(8); + + *(.got.plt) *(.got) + *(.data .data.* .gnu.linkonce.d.*) + + . = ALIGN(8); + __data_end__ = .; + } > REGION_DATA AT> REGION_RODATA + + /* + * Read-only data + */ + .rodata : + { + *(.rodata .rodata.* .gnu.linkonce.r.*) + /* .USER_FLASH: We allow users to allocate into Flash here */ + *(.USER_FLASH) + /* ROM image configuration; for C startup */ + . = ALIGN(4); + _lm_rom_img_cfgp = .; + LONG(LOADADDR(.data)); + /* + * Heap: Linker scripts may choose a custom heap by overriding + * _lm_heap_start and _lm_heap_end. Otherwise, the heap is in + * internal SRAM, beginning after .bss, and growing towards + * the stack. + * + * I'm shoving these here naively; there's probably a cleaner way + * to go about this. [mbolivar] + */ + _lm_heap_start = DEFINED(_lm_heap_start) ? _lm_heap_start : _end; + _lm_heap_end = DEFINED(_lm_heap_end) ? _lm_heap_end : __msp_init; + } > REGION_RODATA + + /* + * .bss + */ + .bss : + { + . = ALIGN(8); + __bss_start__ = .; + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + __bss_end__ = .; + _end = __bss_end__; + } > REGION_BSS + + /* + * Debugging sections + */ + .stab 0 (NOLOAD) : { *(.stab) } + .stabstr 0 (NOLOAD) : { *(.stabstr) } + /* DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) } +} diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/extra_libs.inc b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/extra_libs.inc new file mode 100644 index 000000000000..dd2c84fa45ea --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/extra_libs.inc @@ -0,0 +1,7 @@ +/* + * Extra archives needed by ARM's GCC ARM Embedded arm-none-eabi- + * releases (https://launchpad.net/gcc-arm-embedded/). + */ + +/* This is for the provided newlib. */ +GROUP(libnosys.a) diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/flash.ld b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/flash.ld new file mode 100644 index 000000000000..9e250cd7478d --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/flash.ld @@ -0,0 +1,26 @@ +/* + * libmaple linker script for "Flash" builds. + * + * A Flash build puts .text (and .rodata) in Flash, and + * .data/.bss/heap (of course) in SRAM, but offsets the sections by + * enough space to store the Maple bootloader, which lives in low + * Flash and uses low memory. + */ + +/* + * This pulls in the appropriate MEMORY declaration from the right + * subdirectory of stm32/mem/ (the environment must call ld with the + * right include directory flags to make this happen). Boards can also + * use this file to use any of libmaple's memory-related hooks (like + * where the heap should live). + */ +INCLUDE mem-flash.inc + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/jtag.ld b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/jtag.ld new file mode 100644 index 000000000000..0612f9586202 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/jtag.ld @@ -0,0 +1,31 @@ +/* + * libmaple linker script for "JTAG" builds. + * + * A "JTAG" build puts .text (and .rodata) in Flash, and + * .data/.bss/heap (of course) in SRAM, but links starting at the + * Flash and SRAM starting addresses (0x08000000 and 0x20000000 + * respectively). This will wipe out a Maple bootloader if there's one + * on the board, so only use this if you know what you're doing. + * + * Of course, a "JTAG" build is perfectly usable for upload over SWD, + * the system memory bootloader, etc. The name is just a historical + * artifact. + */ + +/* + * This pulls in the appropriate MEMORY declaration from the right + * subdirectory of stm32/mem/ (the environment must call ld with the + * right include directory flags to make this happen). Boards can also + * use this file to use any of libmaple's memory-related hooks (like + * where the heap should live). + */ +INCLUDE mem-jtag.inc + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/mem-flash.inc b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/mem-flash.inc new file mode 100644 index 000000000000..ddb8876fa5d2 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/mem-flash.inc @@ -0,0 +1,5 @@ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K + rom (rx) : ORIGIN = 0x08005000, LENGTH = 492K +} diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/mem-jtag.inc b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/mem-jtag.inc new file mode 100644 index 000000000000..d3ed992481cf --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/mem-jtag.inc @@ -0,0 +1,5 @@ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K +} diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/mem-ram.inc b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/mem-ram.inc new file mode 100644 index 000000000000..360beafe9df3 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/mem-ram.inc @@ -0,0 +1,5 @@ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K + rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K +} diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/ram.ld b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/ram.ld new file mode 100644 index 000000000000..34b468e0a078 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/ram.ld @@ -0,0 +1,25 @@ +/* + * libmaple linker script for RAM builds. + * + * A Flash build puts .text, .rodata, and .data/.bss/heap (of course) + * in SRAM, but offsets the sections by enough space to store the + * Maple bootloader, which uses low memory. + */ + +/* + * This pulls in the appropriate MEMORY declaration from the right + * subdirectory of stm32/mem/ (the environment must call ld with the + * right include directory flags to make this happen). Boards can also + * use this file to use any of libmaple's memory-related hooks (like + * where the heap should live). + */ +INCLUDE mem-ram.inc + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", ram); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", ram); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rb.ld b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rb.ld new file mode 100644 index 000000000000..094f2d292801 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rb.ld @@ -0,0 +1,18 @@ +/* + * Linker script for Generic STM32F103RB boards. + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K +} + + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rb_bootloader.ld b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rb_bootloader.ld new file mode 100644 index 000000000000..d045db9f4bb7 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rb_bootloader.ld @@ -0,0 +1,17 @@ +/* + * Linker script for Generic STM32F103RB boards, using the generic bootloader (which takes the lower 8k of memory) + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K + rom (rx) : ORIGIN = 0x08002000, LENGTH = 120K +} + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rc.ld b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rc.ld new file mode 100644 index 000000000000..c890d69f6d51 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rc.ld @@ -0,0 +1,18 @@ +/* + * Linker script for Generic STM32F103RC boards. + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K +} + + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rc_bootloader.ld b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rc_bootloader.ld new file mode 100644 index 000000000000..00b811b0e624 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rc_bootloader.ld @@ -0,0 +1,18 @@ +/* + * Linker script for Generic STM32F103RC boards, using the generic bootloader (which takes the lower 8k of memory) + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K + rom (rx) : ORIGIN = 0x08002000, LENGTH = 248K +} + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103re.ld b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103re.ld new file mode 100644 index 000000000000..9f74fd529261 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103re.ld @@ -0,0 +1,18 @@ +/* + * Linker script for Generic STM32F103RE boards. + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K +} + + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/vector_symbols.inc b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/vector_symbols.inc new file mode 100644 index 000000000000..f8519bba440b --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/vector_symbols.inc @@ -0,0 +1,78 @@ +EXTERN(__msp_init) +EXTERN(__exc_reset) +EXTERN(__exc_nmi) +EXTERN(__exc_hardfault) +EXTERN(__exc_memmanage) +EXTERN(__exc_busfault) +EXTERN(__exc_usagefault) +EXTERN(__stm32reservedexception7) +EXTERN(__stm32reservedexception8) +EXTERN(__stm32reservedexception9) +EXTERN(__stm32reservedexception10) +EXTERN(__exc_svc) +EXTERN(__exc_debug_monitor) +EXTERN(__stm32reservedexception13) +EXTERN(__exc_pendsv) +EXTERN(__exc_systick) + +EXTERN(__irq_wwdg) +EXTERN(__irq_pvd) +EXTERN(__irq_tamper) +EXTERN(__irq_rtc) +EXTERN(__irq_flash) +EXTERN(__irq_rcc) +EXTERN(__irq_exti0) +EXTERN(__irq_exti1) +EXTERN(__irq_exti2) +EXTERN(__irq_exti3) +EXTERN(__irq_exti4) +EXTERN(__irq_dma1_channel1) +EXTERN(__irq_dma1_channel2) +EXTERN(__irq_dma1_channel3) +EXTERN(__irq_dma1_channel4) +EXTERN(__irq_dma1_channel5) +EXTERN(__irq_dma1_channel6) +EXTERN(__irq_dma1_channel7) +EXTERN(__irq_adc) +EXTERN(__irq_usb_hp_can_tx) +EXTERN(__irq_usb_lp_can_rx0) +EXTERN(__irq_can_rx1) +EXTERN(__irq_can_sce) +EXTERN(__irq_exti9_5) +EXTERN(__irq_tim1_brk) +EXTERN(__irq_tim1_up) +EXTERN(__irq_tim1_trg_com) +EXTERN(__irq_tim1_cc) +EXTERN(__irq_tim2) +EXTERN(__irq_tim3) +EXTERN(__irq_tim4) +EXTERN(__irq_i2c1_ev) +EXTERN(__irq_i2c1_er) +EXTERN(__irq_i2c2_ev) +EXTERN(__irq_i2c2_er) +EXTERN(__irq_spi1) +EXTERN(__irq_spi2) +EXTERN(__irq_usart1) +EXTERN(__irq_usart2) +EXTERN(__irq_usart3) +EXTERN(__irq_exti15_10) +EXTERN(__irq_rtcalarm) +EXTERN(__irq_usbwakeup) + +EXTERN(__irq_tim8_brk) +EXTERN(__irq_tim8_up) +EXTERN(__irq_tim8_trg_com) +EXTERN(__irq_tim8_cc) +EXTERN(__irq_adc3) +EXTERN(__irq_fsmc) +EXTERN(__irq_sdio) +EXTERN(__irq_tim5) +EXTERN(__irq_spi3) +EXTERN(__irq_uart4) +EXTERN(__irq_uart5) +EXTERN(__irq_tim6) +EXTERN(__irq_tim7) +EXTERN(__irq_dma2_channel1) +EXTERN(__irq_dma2_channel2) +EXTERN(__irq_dma2_channel3) +EXTERN(__irq_dma2_channel4_5) diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/pins_arduino.h b/buildroot/share/PlatformIO/variants/MEEB_3DP/pins_arduino.h new file mode 100644 index 000000000000..d5dce114d504 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/pins_arduino.h @@ -0,0 +1,2 @@ +// API compatibility +#include "variant.h" diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/variant.h b/buildroot/share/PlatformIO/variants/MEEB_3DP/variant.h new file mode 100644 index 000000000000..cd10bb3c07f2 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/variant.h @@ -0,0 +1,17 @@ +#pragma once + +#define digitalPinToPort(P) ( PIN_MAP[P].gpio_device ) +#define digitalPinToBitMask(P) ( BIT(PIN_MAP[P].gpio_bit) ) +#define portOutputRegister(port) ( &(port->regs->ODR) ) +#define portInputRegister(port) ( &(port->regs->IDR) ) + +#define portSetRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->BSRR) ) +#define portClearRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->BRR) ) + +#define portConfigRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->CRL) ) + +static const uint8_t SS = BOARD_SPI1_NSS_PIN; +static const uint8_t SS1 = BOARD_SPI2_NSS_PIN; +static const uint8_t MOSI = BOARD_SPI1_MOSI_PIN; +static const uint8_t MISO = BOARD_SPI1_MISO_PIN; +static const uint8_t SCK = BOARD_SPI1_SCK_PIN; diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/boards.cpp b/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/boards.cpp new file mode 100644 index 000000000000..12321229defb --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/boards.cpp @@ -0,0 +1,225 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * Copyright (c) 2011, 2012 LeafLabs, LLC. + * + * 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. + *****************************************************************************/ + +/** + * @file wirish/boards.cpp + * @brief init() and board routines. + * + * This file is mostly interesting for the init() function, which + * configures Flash, the core clocks, and a variety of other available + * peripherals on the board so the rest of Wirish doesn't have to turn + * things on before using them. + * + * Prior to returning, init() calls boardInit(), which allows boards + * to perform any initialization they need to. This file includes a + * weak no-op definition of boardInit(), so boards that don't need any + * special initialization don't have to define their own. + * + * How init() works is chip-specific. See the boards_setup.cpp files + * under e.g. wirish/stm32f1/, wirish/stmf32f2 for the details, but be + * advised: their contents are unstable, and can/will change without + * notice. + */ + +#include +#include +#include +#include +#include +#include "boards_private.h" + +static void setup_flash(void); +static void setup_clocks(void); +static void setup_nvic(void); +static void setup_adcs(void); +static void setup_timers(void); + +/* + * Exported functions + */ + +void init(void) { + setup_flash(); + setup_clocks(); + setup_nvic(); + systick_init(SYSTICK_RELOAD_VAL); + wirish::priv::board_setup_gpio(); + setup_adcs(); + setup_timers(); + wirish::priv::board_setup_usb(); + wirish::priv::series_init(); + boardInit(); +} + +/* Provide a default no-op boardInit(). */ +__weak void boardInit(void) { +} + +/* You could farm this out to the files in boards/ if e.g. it takes + * too long to test on boards with lots of pins. */ +bool boardUsesPin(uint8 pin) { + for (int i = 0; i < BOARD_NR_USED_PINS; i++) { + if (pin == boardUsedPins[i]) { + return true; + } + } + return false; +} + +/* + * Auxiliary routines + */ + +static void setup_flash(void) { + // Turn on as many Flash "go faster" features as + // possible. flash_enable_features() just ignores any flags it + // can't support. + flash_enable_features(FLASH_PREFETCH | FLASH_ICACHE | FLASH_DCACHE); + // Configure the wait states, assuming we're operating at "close + // enough" to 3.3V. + flash_set_latency(FLASH_SAFE_WAIT_STATES); +} + +static void setup_clocks(void) { + // Turn on HSI. We'll switch to and run off of this while we're + // setting up the main PLL. + rcc_turn_on_clk(RCC_CLK_HSI); + + // Turn off and reset the clock subsystems we'll be using, as well + // as the clock security subsystem (CSS). Note that resetting CFGR + // to its default value of 0 implies a switch to HSI for SYSCLK. + RCC_BASE->CFGR = 0x00000000; + rcc_disable_css(); + rcc_turn_off_clk(RCC_CLK_PLL); + rcc_turn_off_clk(RCC_CLK_HSE); + wirish::priv::board_reset_pll(); + // Clear clock readiness interrupt flags and turn off clock + // readiness interrupts. + RCC_BASE->CIR = 0x00000000; +#if !USE_HSI_CLOCK + // Enable HSE, and wait until it's ready. + rcc_turn_on_clk(RCC_CLK_HSE); + while (!rcc_is_clk_ready(RCC_CLK_HSE)) + ; +#endif + // Configure AHBx, APBx, etc. prescalers and the main PLL. + wirish::priv::board_setup_clock_prescalers(); + rcc_configure_pll(&wirish::priv::w_board_pll_cfg); + + // Enable the PLL, and wait until it's ready. + rcc_turn_on_clk(RCC_CLK_PLL); + while(!rcc_is_clk_ready(RCC_CLK_PLL)) + ; + + // Finally, switch to the now-ready PLL as the main clock source. + rcc_switch_sysclk(RCC_CLKSRC_PLL); +} + +/* + * These addresses are where usercode starts when a bootloader is + * present. If no bootloader is present, the user NVIC usually starts + * at the Flash base address, 0x08000000. + */ +#if defined(BOOTLOADER_maple) + #define USER_ADDR_ROM 0x08002000 +#else + #define USER_ADDR_ROM 0x08000000 +#endif +#define USER_ADDR_RAM 0x20000C00 +extern char __text_start__; + +static void setup_nvic(void) { + +nvic_init((uint32)VECT_TAB_ADDR, 0); + +/* Roger Clark. We now control nvic vector table in boards.txt using the build.vect paramater +#ifdef VECT_TAB_FLASH + nvic_init(USER_ADDR_ROM, 0); +#elif defined VECT_TAB_RAM + nvic_init(USER_ADDR_RAM, 0); +#elif defined VECT_TAB_BASE + nvic_init((uint32)0x08000000, 0); +#elif defined VECT_TAB_ADDR + // A numerically supplied value + nvic_init((uint32)VECT_TAB_ADDR, 0); +#else + // Use the __text_start__ value from the linker script; this + // should be the start of the vector table. + nvic_init((uint32)&__text_start__, 0); +#endif + +*/ +} + +static void adc_default_config(adc_dev *dev) { + adc_enable_single_swstart(dev); + adc_set_sample_rate(dev, wirish::priv::w_adc_smp); +} + +static void setup_adcs(void) { + adc_set_prescaler(wirish::priv::w_adc_pre); + adc_foreach(adc_default_config); +} + +static void timer_default_config(timer_dev *dev) { + timer_adv_reg_map *regs = (dev->regs).adv; + const uint16 full_overflow = 0xFFFF; + const uint16 half_duty = 0x8FFF; + + timer_init(dev); + timer_pause(dev); + + regs->CR1 = TIMER_CR1_ARPE; + regs->PSC = 1; + regs->SR = 0; + regs->DIER = 0; + regs->EGR = TIMER_EGR_UG; + switch (dev->type) { + case TIMER_ADVANCED: + regs->BDTR = TIMER_BDTR_MOE | TIMER_BDTR_LOCK_OFF; + // fall-through + case TIMER_GENERAL: + timer_set_reload(dev, full_overflow); + for (uint8 channel = 1; channel <= 4; channel++) { + if (timer_has_cc_channel(dev, channel)) { + timer_set_compare(dev, channel, half_duty); + timer_oc_set_mode(dev, channel, TIMER_OC_MODE_PWM_1, + TIMER_OC_PE); + } + } + // fall-through + case TIMER_BASIC: + break; + } + + timer_generate_update(dev); + timer_resume(dev); +} + +static void setup_timers(void) { + timer_foreach(timer_default_config); +} diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/boards_setup.cpp b/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/boards_setup.cpp new file mode 100644 index 000000000000..44418a52a475 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/boards_setup.cpp @@ -0,0 +1,106 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2012 LeafLabs, LLC. + * + * 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. +*****************************************************************************/ + +/** + * @file wirish/stm32f1/boards_setup.cpp + * @author Marti Bolivar + * @brief STM32F1 chip setup. + * + * This file controls how init() behaves on the STM32F1. Be very + * careful when changing anything here. Many of these values depend + * upon each other. + */ + +#include "boards_private.h" + +#include +#include + +#include +#include + +// Allow boards to provide a PLL multiplier. This is useful for +// e.g. STM32F100 value line MCUs, which use slower multipliers. +// (We're leaving the default to RCC_PLLMUL_9 for now, since that +// works for F103 performance line MCUs, which is all that LeafLabs +// currently officially supports). + +namespace wirish { + namespace priv { + + static stm32f1_rcc_pll_data pll_data = {RCC_PLLMUL_6}; +#if !USE_HSI_CLOCK + __weak rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSE, &pll_data}; +#else + __weak rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSI_DIV_2, &pll_data}; +#endif + __weak adc_prescaler w_adc_pre = ADC_PRE_PCLK2_DIV_6; + __weak adc_smp_rate w_adc_smp = ADC_SMPR_55_5; + + __weak void board_reset_pll(void) { + // TODO + } + + __weak void board_setup_clock_prescalers(void) { + rcc_set_prescaler(RCC_PRESCALER_AHB, RCC_AHB_SYSCLK_DIV_1); + rcc_set_prescaler(RCC_PRESCALER_APB1, RCC_APB1_HCLK_DIV_2); + rcc_set_prescaler(RCC_PRESCALER_APB2, RCC_APB2_HCLK_DIV_1); + rcc_clk_disable(RCC_USB); + #if F_CPU == 72000000 + rcc_set_prescaler(RCC_PRESCALER_USB, RCC_USB_SYSCLK_DIV_1_5); + #elif F_CPU == 48000000 + rcc_set_prescaler(RCC_PRESCALER_USB, RCC_USB_SYSCLK_DIV_1); + #endif + } + + __weak void board_setup_gpio(void) { + gpio_init_all(); + } + + __weak void board_setup_usb(void) { +#ifdef SERIAL_USB + +#ifdef GENERIC_BOOTLOADER + //Reset the USB interface on generic boards - developed by Victor PV + gpio_set_mode(PIN_MAP[PA12].gpio_device, PIN_MAP[PA12].gpio_bit, GPIO_OUTPUT_PP); + gpio_write_bit(PIN_MAP[PA12].gpio_device, PIN_MAP[PA12].gpio_bit,0); + + for(volatile unsigned int i=0;i<512;i++);// Only small delay seems to be needed, and USB pins will get configured in Serial.begin + gpio_set_mode(PIN_MAP[PA12].gpio_device, PIN_MAP[PA12].gpio_bit, GPIO_INPUT_FLOATING); +#endif + + Serial.begin();// Roger Clark. Changed SerialUSB to Serial for Arduino sketch compatibility +#endif + } + + __weak void series_init(void) { + // Initialize AFIO here, too, so peripheral remaps and external + // interrupts work out of the box. + afio_init(); + } + + } +} diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/start.S b/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/start.S new file mode 100644 index 000000000000..8b181aa99313 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/start.S @@ -0,0 +1,57 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * 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. + *****************************************************************************/ + +/* + * This file is a modified version of a file obtained from + * CodeSourcery Inc. (now part of Mentor Graphics Corp.), in which the + * following text appeared: + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + + .text + .code 16 + .thumb_func + + .globl __start__ + .type __start__, %function +__start__: + .fnstart + ldr r1,=__msp_init + mov sp,r1 + ldr r1,=start_c + bx r1 + .pool + .cantunwind + .fnend diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/start_c.c b/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/start_c.c new file mode 100644 index 000000000000..655fefb884bd --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/start_c.c @@ -0,0 +1,95 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * 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. + *****************************************************************************/ + +/* + * This file is a modified version of a file obtained from + * CodeSourcery Inc. (now part of Mentor Graphics Corp.), in which the + * following text appeared: + * + * Copyright (c) 2006, 2007 CodeSourcery Inc + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include + +extern void __libc_init_array(void); + +extern int main(int, char**, char**); + +extern void exit(int) __attribute__((noreturn, weak)); + +/* The linker must ensure that these are at least 4-byte aligned. */ +extern char __data_start__, __data_end__; +extern char __bss_start__, __bss_end__; + +struct rom_img_cfg { + int *img_start; +}; + +extern char _lm_rom_img_cfgp; + +void __attribute__((noreturn)) start_c(void) { + struct rom_img_cfg *img_cfg = (struct rom_img_cfg*)&_lm_rom_img_cfgp; + int *src = img_cfg->img_start; + int *dst = (int*)&__data_start__; + int exit_code; + + /* Initialize .data, if necessary. */ + if (src != dst) { + int *end = (int*)&__data_end__; + while (dst < end) { + *dst++ = *src++; + } + } + + /* Zero .bss. */ + dst = (int*)&__bss_start__; + while (dst < (int*)&__bss_end__) { + *dst++ = 0; + } + + /* Run initializers. */ + __libc_init_array(); + + /* Jump to main. */ + exit_code = main(0, 0, 0); + if (exit) { + exit(exit_code); + } + + /* If exit is NULL, make sure we don't return. */ + for (;;) + continue; +} diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/syscalls.c b/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/syscalls.c new file mode 100644 index 000000000000..d5f2d9fac319 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/syscalls.c @@ -0,0 +1,176 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * Copyright (c) 2011, 2012 LeafLabs, LLC. + * + * 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. + *****************************************************************************/ + +/** + * @file wirish/syscalls.c + * @brief newlib stubs + * + * Low level system routines used by newlib for basic I/O and memory + * allocation. You can override most of these. + */ + +#include + +#include +#include +#include + +/* If CONFIG_HEAP_START (or CONFIG_HEAP_END) isn't defined, then + * assume _lm_heap_start (resp. _lm_heap_end) is appropriately set by + * the linker */ +#ifndef CONFIG_HEAP_START +extern char _lm_heap_start; +#define CONFIG_HEAP_START ((void *)&_lm_heap_start) +#endif +#ifndef CONFIG_HEAP_END +extern char _lm_heap_end; +#define CONFIG_HEAP_END ((void *)&_lm_heap_end) +#endif + +/* + * _sbrk -- Increment the program break. + * + * Get incr bytes more RAM (for use by the heap). malloc() and + * friends call this function behind the scenes. + */ +void *_sbrk(int incr) { + static void * pbreak = NULL; /* current program break */ + void * ret; + + if (pbreak == NULL) { + pbreak = CONFIG_HEAP_START; + } + + if ((CONFIG_HEAP_END - pbreak < incr) || + (pbreak - CONFIG_HEAP_START < -incr)) { + errno = ENOMEM; + return (void *)-1; + } + + ret = pbreak; + pbreak += incr; + return ret; +} + +__weak int _open(const char *path, int flags, ...) { + return 1; +} + +__weak int _close(int fd) { + return 0; +} + +__weak int _fstat(int fd, struct stat *st) { + st->st_mode = S_IFCHR; + return 0; +} + +__weak int _isatty(int fd) { + return 1; +} + +__weak int isatty(int fd) { + return 1; +} + +__weak int _lseek(int fd, off_t pos, int whence) { + return -1; +} + +__weak unsigned char getch(void) { + return 0; +} + + +__weak int _read(int fd, char *buf, size_t cnt) { + *buf = getch(); + + return 1; +} + +__weak void putch(unsigned char c) { +} + +__weak void cgets(char *s, int bufsize) { + char *p; + int c; + int i; + + for (i = 0; i < bufsize; i++) { + *(s+i) = 0; + } +// memset(s, 0, bufsize); + + p = s; + + for (p = s; p < s + bufsize-1;) { + c = getch(); + switch (c) { + case '\r' : + case '\n' : + putch('\r'); + putch('\n'); + *p = '\n'; + return; + + case '\b' : + if (p > s) { + *p-- = 0; + putch('\b'); + putch(' '); + putch('\b'); + } + break; + + default : + putch(c); + *p++ = c; + break; + } + } + return; +} + +__weak int _write(int fd, const char *buf, size_t cnt) { + int i; + + for (i = 0; i < cnt; i++) + putch(buf[i]); + + return cnt; +} + +/* Override fgets() in newlib with a version that does line editing */ +__weak char *fgets(char *s, int bufsize, void *f) { + cgets(s, bufsize); + return s; +} + +__weak void _exit(int exitcode) { + while (1) + ; +} diff --git a/buildroot/share/PlatformIO/variants/STEVAL_F401VE/PinNamesVar.h b/buildroot/share/PlatformIO/variants/STEVAL_F401VE/PinNamesVar.h index 3082f8842ab3..6a1eb9b887f4 100644 --- a/buildroot/share/PlatformIO/variants/STEVAL_F401VE/PinNamesVar.h +++ b/buildroot/share/PlatformIO/variants/STEVAL_F401VE/PinNamesVar.h @@ -1,33 +1,33 @@ /* SYS_WKUP */ #ifdef PWR_WAKEUP_PIN1 -SYS_WKUP1 = PA_0, + SYS_WKUP1 = PA_0, #endif #ifdef PWR_WAKEUP_PIN2 -SYS_WKUP2 = NC, + SYS_WKUP2 = NC, #endif #ifdef PWR_WAKEUP_PIN3 -SYS_WKUP3 = NC, + SYS_WKUP3 = NC, #endif #ifdef PWR_WAKEUP_PIN4 -SYS_WKUP4 = NC, + SYS_WKUP4 = NC, #endif #ifdef PWR_WAKEUP_PIN5 -SYS_WKUP5 = NC, + SYS_WKUP5 = NC, #endif #ifdef PWR_WAKEUP_PIN6 -SYS_WKUP6 = NC, + SYS_WKUP6 = NC, #endif #ifdef PWR_WAKEUP_PIN7 -SYS_WKUP7 = NC, + SYS_WKUP7 = NC, #endif #ifdef PWR_WAKEUP_PIN8 -SYS_WKUP8 = NC, + SYS_WKUP8 = NC, #endif /* USB */ #ifdef USBCON -USB_OTG_FS_SOF = PA_8, -USB_OTG_FS_VBUS = PA_9, -USB_OTG_FS_ID = PA_10, -USB_OTG_FS_DM = PA_11, -USB_OTG_FS_DP = PA_12, + USB_OTG_FS_SOF = PA_8, + USB_OTG_FS_VBUS = PA_9, + USB_OTG_FS_ID = PA_10, + USB_OTG_FS_DM = PA_11, + USB_OTG_FS_DP = PA_12, #endif diff --git a/buildroot/share/PlatformIO/variants/STEVAL_F401VE/variant.cpp b/buildroot/share/PlatformIO/variants/STEVAL_F401VE/variant.cpp index a53a92c48c29..4ecbff0ecc5c 100644 --- a/buildroot/share/PlatformIO/variants/STEVAL_F401VE/variant.cpp +++ b/buildroot/share/PlatformIO/variants/STEVAL_F401VE/variant.cpp @@ -34,7 +34,7 @@ extern "C" { #endif -#if defined(ARDUINO_STEVAL) +#ifdef ARDUINO_STEVAL // Pin number // This array allows to wrap Arduino pin number(Dx or x) // to STM32 PinName (PX_n) diff --git a/buildroot/share/PlatformIO/variants/STEVAL_F401VE/variant.h b/buildroot/share/PlatformIO/variants/STEVAL_F401VE/variant.h index ffdb81a636ed..df7295ab17e8 100644 --- a/buildroot/share/PlatformIO/variants/STEVAL_F401VE/variant.h +++ b/buildroot/share/PlatformIO/variants/STEVAL_F401VE/variant.h @@ -41,7 +41,7 @@ extern "C" { /*---------------------------------------------------------------------------- * Pins *----------------------------------------------------------------------------*/ -#if defined(ARDUINO_STEVAL) +#ifdef ARDUINO_STEVAL /*---------------------------------------------------------------------------- @@ -195,7 +195,7 @@ extern "C" { #define PIN_SERIAL2_RX PD6 #define PIN_SERIAL2_TX PD5 #else - #error'Invalid setting for SERIAL_UART_INSTANCE' + #error "Invalid setting for SERIAL_UART_INSTANCE." #endif // Timer Definitions diff --git a/buildroot/share/PlatformIO/variants/archim/.gitignore b/buildroot/share/PlatformIO/variants/archim/.gitignore new file mode 100644 index 000000000000..2827c7d4f023 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/archim/.gitignore @@ -0,0 +1,2 @@ +# Exception for libsam +!libsam_sam3x8e_gcc_rel.a diff --git a/buildroot/share/PlatformIO/variants/archim/build_gcc/Makefile b/buildroot/share/PlatformIO/variants/archim/build_gcc/Makefile new file mode 100644 index 000000000000..4332f3608004 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/archim/build_gcc/Makefile @@ -0,0 +1,42 @@ +# +# Copyright (c) 2011 Arduino. All right reserved. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + +SUBMAKE_OPTIONS=--no-builtin-rules --no-builtin-variables --no-print-directory + +#------------------------------------------------------------------------------- +# Rules +#------------------------------------------------------------------------------- + +all: arduino_due_x + +.PHONY: arduino_due_x +arduino_due_x: + @echo ------------------------------------------------------------------------------------ + @echo --- Making variant arduino_due_x + @$(MAKE) DEBUG=1 $(SUBMAKE_OPTIONS) -f libvariant_arduino_due_x.mk +# @$(MAKE) $(SUBMAKE_OPTIONS) -f libvariant_arduino_due_x.mk + @echo ------------------------------------------------------------------------------------ + +.PHONY: clean +clean: + @echo ------------------------------------------------------------------------------------ + @echo --- Cleaning variant arduino_due_x + @$(MAKE) DEBUG=1 $(SUBMAKE_OPTIONS) -f libvariant_arduino_due_x.mk $@ +# @$(MAKE) $(SUBMAKE_OPTIONS) -f libvariant_arduino_due_x.mk $@ + @echo ------------------------------------------------------------------------------------ + diff --git a/buildroot/share/PlatformIO/variants/archim/build_gcc/debug.mk b/buildroot/share/PlatformIO/variants/archim/build_gcc/debug.mk new file mode 100644 index 000000000000..a3cc2337a876 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/archim/build_gcc/debug.mk @@ -0,0 +1,25 @@ +# +# Copyright (c) 2011 Arduino. All right reserved. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + +# Optimization level +# -O1 Optimize +# -O2 Optimize even more +# -O3 Optimize yet more +# -O0 Reduce compilation time and make debugging produce the expected results +# -Os Optimize for size +OPTIMIZATION = -g -O0 -DDEBUG diff --git a/buildroot/share/PlatformIO/variants/archim/build_gcc/gcc.mk b/buildroot/share/PlatformIO/variants/archim/build_gcc/gcc.mk new file mode 100644 index 000000000000..32f35d264c66 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/archim/build_gcc/gcc.mk @@ -0,0 +1,82 @@ +# +# Copyright (c) 2011 Arduino. All right reserved. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + +# Tool suffix when cross-compiling +CROSS_COMPILE = $(ARM_GCC_TOOLCHAIN)/arm-none-eabi- + +# Compilation tools +AR = $(CROSS_COMPILE)ar +CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ +AS = $(CROSS_COMPILE)as +NM = $(CROSS_COMPILE)nm +ifeq ($(OS),Windows_NT) +RM=cs-rm -Rf +else +RM=rm -Rf +endif + +SEP=\\ + +# --------------------------------------------------------------------------------------- +# C Flags + +CFLAGS += -Wall -Wchar-subscripts -Wcomment -Wformat=2 -Wimplicit-int +CFLAGS += -Werror-implicit-function-declaration -Wmain -Wparentheses +CFLAGS += -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused +CFLAGS += -Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef +CFLAGS += -Wshadow -Wpointer-arith -Wbad-function-cast -Wwrite-strings +CFLAGS += -Wsign-compare -Waggregate-return -Wstrict-prototypes +CFLAGS += -Wmissing-prototypes -Wmissing-declarations +CFLAGS += -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations +CFLAGS += -Wpacked -Wredundant-decls -Wnested-externs -Winline -Wlong-long +CFLAGS += -Wunreachable-code +CFLAGS += -Wcast-align +#CFLAGS += -Wmissing-noreturn +#CFLAGS += -Wconversion + +CFLAGS += --param max-inline-insns-single=500 -mcpu=cortex-m3 -mthumb -mlong-calls -ffunction-sections -fdata-sections -nostdlib -std=c99 +CFLAGS += $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -D$(VARIANT) + +# To reduce application size use only integer printf function. +CFLAGS += -Dprintf=iprintf + +# --------------------------------------------------------------------------------------- +# CPP Flags + +CPPFLAGS += -Wall -Wchar-subscripts -Wcomment -Wformat=2 +CPPFLAGS += -Wmain -Wparentheses -Wcast-align -Wunreachable-code +CPPFLAGS += -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused +CPPFLAGS += -Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef +CPPFLAGS += -Wshadow -Wpointer-arith -Wwrite-strings +CPPFLAGS += -Wsign-compare -Waggregate-return -Wmissing-declarations +CPPFLAGS += -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations +CPPFLAGS += -Wpacked -Wredundant-decls -Winline -Wlong-long +#CPPFLAGS += -Wmissing-noreturn +#CPPFLAGS += -Wconversion + +CPPFLAGS += --param max-inline-insns-single=500 -mcpu=cortex-m3 -mthumb -mlong-calls -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -std=c++98 +CPPFLAGS += $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) + +# To reduce application size use only integer printf function. +CPPFLAGS += -Dprintf=iprintf + +# --------------------------------------------------------------------------------------- +# ASM Flags + +ASFLAGS = -mcpu=cortex-m3 -mthumb -Wall -g $(OPTIMIZATION) $(INCLUDES) diff --git a/buildroot/share/PlatformIO/variants/archim/build_gcc/libvariant_arduino_due_x.mk b/buildroot/share/PlatformIO/variants/archim/build_gcc/libvariant_arduino_due_x.mk new file mode 100644 index 000000000000..3f8b1b7603cb --- /dev/null +++ b/buildroot/share/PlatformIO/variants/archim/build_gcc/libvariant_arduino_due_x.mk @@ -0,0 +1,184 @@ +# +# Copyright (c) 2012 Arduino. All right reserved. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + +# Makefile for compiling libArduino +.SUFFIXES: .o .a .c .s + +CHIP=__SAM3X8E__ +VARIANT=arduino_due_x +LIBNAME=libvariant_$(VARIANT) +TOOLCHAIN=gcc + +#------------------------------------------------------------------------------- +# Path +#------------------------------------------------------------------------------- + +# Output directories +OUTPUT_BIN = ../../../cores/arduino + +# Libraries +PROJECT_BASE_PATH = .. +SYSTEM_PATH = ../../../system +CMSIS_ROOT_PATH = $(SYSTEM_PATH)/CMSIS +CMSIS_ARM_PATH=$(CMSIS_ROOT_PATH)/CMSIS/Include +CMSIS_ATMEL_PATH=$(CMSIS_ROOT_PATH)/Device/ATMEL +#CMSIS_CHIP_PATH=$(CMSIS_ROOT_PATH)/Device/ATMEL/$(CHIP_SERIE) + +ARDUINO_PATH = ../../../cores/arduino +VARIANT_BASE_PATH = ../../../variants +VARIANT_PATH = ../../../variants/$(VARIANT) + +#------------------------------------------------------------------------------- +# Files +#------------------------------------------------------------------------------- + +#vpath %.h $(PROJECT_BASE_PATH) $(SYSTEM_PATH) $(VARIANT_PATH) +vpath %.cpp $(PROJECT_BASE_PATH) + +VPATH+=$(PROJECT_BASE_PATH) + +INCLUDES = +#INCLUDES += -I$(PROJECT_BASE_PATH) +INCLUDES += -I$(ARDUINO_PATH) +INCLUDES += -I$(ARDUINO_PATH)/USB +INCLUDES += -I$(SYSTEM_PATH) +INCLUDES += -I$(SYSTEM_PATH)/libsam +INCLUDES += -I$(SYSTEM_PATH)/USBHost +INCLUDES += -I$(VARIANT_BASE_PATH) +INCLUDES += -I$(VARIANT_PATH) +INCLUDES += -I$(CMSIS_ARM_PATH) +INCLUDES += -I$(CMSIS_ATMEL_PATH) + +#------------------------------------------------------------------------------- +ifdef DEBUG +include debug.mk +else +include release.mk +endif + +#------------------------------------------------------------------------------- +# Tools +#------------------------------------------------------------------------------- + +include $(TOOLCHAIN).mk + +#------------------------------------------------------------------------------- +ifdef DEBUG +OUTPUT_OBJ=debug +OUTPUT_LIB_POSTFIX=dbg +else +OUTPUT_OBJ=release +OUTPUT_LIB_POSTFIX=rel +endif + +OUTPUT_LIB=$(LIBNAME)_$(TOOLCHAIN)_$(OUTPUT_LIB_POSTFIX).a +OUTPUT_PATH=$(OUTPUT_OBJ)_$(VARIANT) + +#------------------------------------------------------------------------------- +# C source files and objects +#------------------------------------------------------------------------------- +C_SRC=$(wildcard $(PROJECT_BASE_PATH)/*.c) + +C_OBJ_TEMP = $(patsubst %.c, %.o, $(notdir $(C_SRC))) + +# during development, remove some files +C_OBJ_FILTER= + +C_OBJ=$(filter-out $(C_OBJ_FILTER), $(C_OBJ_TEMP)) + +#------------------------------------------------------------------------------- +# CPP source files and objects +#------------------------------------------------------------------------------- +CPP_SRC=$(wildcard $(PROJECT_BASE_PATH)/*.cpp) + +CPP_OBJ_TEMP = $(patsubst %.cpp, %.o, $(notdir $(CPP_SRC))) + +# during development, remove some files +CPP_OBJ_FILTER= + +CPP_OBJ=$(filter-out $(CPP_OBJ_FILTER), $(CPP_OBJ_TEMP)) + +#------------------------------------------------------------------------------- +# Assembler source files and objects +#------------------------------------------------------------------------------- +A_SRC=$(wildcard $(PROJECT_BASE_PATH)/*.s) + +A_OBJ_TEMP=$(patsubst %.s, %.o, $(notdir $(A_SRC))) + +# during development, remove some files +A_OBJ_FILTER= + +A_OBJ=$(filter-out $(A_OBJ_FILTER), $(A_OBJ_TEMP)) + +#------------------------------------------------------------------------------- +# Rules +#------------------------------------------------------------------------------- +all: $(VARIANT) + +$(VARIANT): create_output $(OUTPUT_LIB) + +.PHONY: create_output +create_output: + @echo ------------------------------------------------------------------------------------ + @echo ------------------------- + @echo --- Preparing variant $(VARIANT) files in $(OUTPUT_PATH) $(OUTPUT_BIN) + @echo ------------------------- +# @echo *$(INCLUDES) +# @echo ------------------------- +# @echo *$(C_SRC) +# @echo ------------------------- +# @echo *$(C_OBJ) +# @echo ------------------------- +# @echo *$(addprefix $(OUTPUT_PATH)/, $(C_OBJ)) +# @echo ------------------------- +# @echo *$(CPP_SRC) +# @echo ------------------------- +# @echo *$(CPP_OBJ) +# @echo ------------------------- +# @echo *$(addprefix $(OUTPUT_PATH)/, $(CPP_OBJ)) +# @echo ------------------------- +# @echo *$(A_SRC) +# @echo ------------------------- + + -@mkdir $(OUTPUT_PATH) 1>NUL 2>&1 + @echo ------------------------------------------------------------------------------------ + +$(addprefix $(OUTPUT_PATH)/,$(C_OBJ)): $(OUTPUT_PATH)/%.o: %.c +# @"$(CC)" -v -c $(CFLAGS) $< -o $@ + @"$(CC)" -c $(CFLAGS) $< -o $@ + +$(addprefix $(OUTPUT_PATH)/,$(CPP_OBJ)): $(OUTPUT_PATH)/%.o: %.cpp +# @"$(CC)" -c $(CPPFLAGS) $< -o $@ + @"$(CC)" -xc++ -c $(CPPFLAGS) $< -o $@ + +$(addprefix $(OUTPUT_PATH)/,$(A_OBJ)): $(OUTPUT_PATH)/%.o: %.s + @"$(AS)" -c $(ASFLAGS) $< -o $@ + +$(OUTPUT_LIB): $(addprefix $(OUTPUT_PATH)/, $(C_OBJ)) $(addprefix $(OUTPUT_PATH)/, $(CPP_OBJ)) $(addprefix $(OUTPUT_PATH)/, $(A_OBJ)) + @"$(AR)" -v -r "$(OUTPUT_BIN)/$@" $^ + @"$(NM)" "$(OUTPUT_BIN)/$@" > "$(OUTPUT_BIN)/$@.txt" + + +.PHONY: clean +clean: + @echo ------------------------------------------------------------------------------------ + @echo --- Cleaning $(VARIANT) files [$(OUTPUT_PATH)$(SEP)*.o] + -@$(RM) $(OUTPUT_PATH) 1>NUL 2>&1 + -@$(RM) $(OUTPUT_BIN)/$(OUTPUT_LIB) 1>NUL 2>&1 + @echo ------------------------------------------------------------------------------------ + diff --git a/buildroot/share/PlatformIO/variants/archim/build_gcc/release.mk b/buildroot/share/PlatformIO/variants/archim/build_gcc/release.mk new file mode 100644 index 000000000000..2659255bffd7 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/archim/build_gcc/release.mk @@ -0,0 +1,25 @@ +# +# Copyright (c) 2011 Arduino. All right reserved. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + +# Optimization level +# -O1 Optimize +# -O2 Optimize even more +# -O3 Optimize yet more +# -O0 Reduce compilation time and make debugging produce the expected results +# -Os Optimize for size +OPTIMIZATION = -Os diff --git a/buildroot/share/PlatformIO/variants/archim/debug_scripts/gcc/arduino_due_x_flash.gdb b/buildroot/share/PlatformIO/variants/archim/debug_scripts/gcc/arduino_due_x_flash.gdb new file mode 100644 index 000000000000..4e8375b5f162 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/archim/debug_scripts/gcc/arduino_due_x_flash.gdb @@ -0,0 +1,37 @@ +#******************************************************* +# +# Connect to J-Link and debug application in flash on SAM3X. +# + +# Define 'reset' command +define reset + +# Connect to the J-Link gdb server +target remote localhost:2331 + +# Reset the chip to get to a known state +monitor reset + +# Select flash device +monitor flash device = AT91SAM3X8E + +# Enable flash download and flash breakpoints +monitor flash download = 1 + +# Load the program +load + +# Reset peripheral (RSTC_CR) +set *0x400e1a00 = 0xA5000004 + +# Initialize PC and stack pointer +mon reg sp=(0x80000) +#set *0x80004 = *0x80004 & 0xFFFFFFFE +mon reg pc=(0x80004) + +info reg + +break main + +# End of 'reset' command +end diff --git a/buildroot/share/PlatformIO/variants/archim/debug_scripts/gcc/arduino_due_x_sram.gdb b/buildroot/share/PlatformIO/variants/archim/debug_scripts/gcc/arduino_due_x_sram.gdb new file mode 100644 index 000000000000..15a1792a9129 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/archim/debug_scripts/gcc/arduino_due_x_sram.gdb @@ -0,0 +1,37 @@ +#******************************************************* +# +# Connect to J-Link and debug application in sram on SAM3X. +# + +# Define 'reset' command +define reset + +# Connect to the J-Link gdb server +target remote localhost:2331 + +# Reset the chip to get to a known state +monitor reset + +# Select flash device +monitor flash device = AT91SAM3X8E + +# Enable flash download and flash breakpoints +monitor flash download = 1 + +# Load the program +load + +# Reset peripheral (RSTC_CR) +set *0x400e1a00 = 0xA5000004 + +# Initialize PC and stack pointer +mon reg sp=(0x20000000) +#set *0x20000004 = *0x20000004 & 0xFFFFFFFE +mon reg pc=(0x20000004) + +info reg + +break main + +# End of 'reset' command +end diff --git a/buildroot/share/PlatformIO/variants/archim/debug_scripts/iar/arduino_due_flash.mac b/buildroot/share/PlatformIO/variants/archim/debug_scripts/iar/arduino_due_flash.mac new file mode 100644 index 000000000000..959583582c43 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/archim/debug_scripts/iar/arduino_due_flash.mac @@ -0,0 +1,44 @@ +// --------------------------------------------------------- +// ATMEL Microcontroller Software Support - ROUSSET - +// --------------------------------------------------------- +// The software is delivered "AS IS" without warranty or +// condition of any kind, either express, implied or +// statutory. This includes without limitation any warranty +// or condition with respect to merchantability or fitness +// for any particular purpose, or against the infringements of +// intellectual property rights of others. +// --------------------------------------------------------- +// File: at91sam3u-ek-flash.mac +// User setup file for CSPY debugger. +// --------------------------------------------------------- +__var __mac_i; +__var __mac_pt; + +/********************************************************************* +* +* execUserReset() +*/ +execUserReset() +{ + __message "------------------------------ execUserReset ---------------------------------"; + __message "-------------------------------Set PC Reset ----------------------------------"; + + __hwReset(0); + + // perpheral reset RSTC_CR + __writeMemory32(0xA5000004,0x400e1200,"Memory"); +} + +/********************************************************************* +* +* execUserPreload() +*/ +execUserPreload() +{ + __message "------------------------------ execUserPreload ---------------------------------"; + + __hwReset(0); //* Hardware Reset: CPU is automatically halted after the reset + + // perpheral reset RSTC_CR + __writeMemory32(0xA5000004,0x400e1200,"Memory"); +} diff --git a/buildroot/share/PlatformIO/variants/archim/debug_scripts/iar/arduino_due_sram.mac b/buildroot/share/PlatformIO/variants/archim/debug_scripts/iar/arduino_due_sram.mac new file mode 100644 index 000000000000..d97a4ab6bb8a --- /dev/null +++ b/buildroot/share/PlatformIO/variants/archim/debug_scripts/iar/arduino_due_sram.mac @@ -0,0 +1,44 @@ +// --------------------------------------------------------- +// ATMEL Microcontroller Software Support - ROUSSET - +// --------------------------------------------------------- +// The software is delivered "AS IS" without warranty or +// condition of any kind, either express, implied or +// statutory. This includes without limitation any warranty +// or condition with respect to merchantability or fitness +// for any particular purpose, or against the infringements of +// intellectual property rights of others. +// --------------------------------------------------------- +// File: at91sam3u-ek-sram.mac +// User setup file for CSPY debugger. +// --------------------------------------------------------- +__var __mac_i; +__var __mac_pt; + +/********************************************************************* +* +* execUserReset() +*/ +execUserReset() +{ + __message "------------------------------ execUserReset ---------------------------------"; + __message "-------------------------------Set PC Reset ----------------------------------"; + + //__hwReset(50); + + // perpheral reset RSTC_CR + __writeMemory32(0xA5000004,0x400e1200,"Memory"); +} + +/********************************************************************* +* +* execUserPreload() +*/ +execUserPreload() +{ + __message "------------------------------ execUserPreload ---------------------------------"; + + __hwReset(0); //* Hardware Reset: CPU is automatically halted after the reset + + // perpheral reset RSTC_CR + __writeMemory32(0xA5000004,0x400e1200,"Memory"); +} diff --git a/buildroot/share/PlatformIO/variants/archim/libsam_sam3x8e_gcc_rel.a b/buildroot/share/PlatformIO/variants/archim/libsam_sam3x8e_gcc_rel.a new file mode 100644 index 0000000000000000000000000000000000000000..3e25e6cabd1e3367a2031f76fbb34cc4a1e43d44 GIT binary patch literal 117430 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 rom + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > rom + PROVIDE_HIDDEN (__exidx_end = .); + + . = ALIGN(4); + _etext = .; + + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _erelocate = .; + } > ram + + /* .bss section which is used for uninitialized data */ + .bss ALIGN(4) (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + } > ram + + . = ALIGN(4); + _end = . ; + + /* .stack_dummy section doesn't contains any symbols. It is only + used for linker to calculate size of stack sections, and assign + values to stack symbols later */ + .stack_dummy : + { + *(.stack*) + } > ram + + /* Set stack top to end of ram, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(ram) + LENGTH(ram); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(_sstack = __StackLimit); + PROVIDE(_estack = __StackTop); +} diff --git a/buildroot/share/PlatformIO/variants/archim/linker_scripts/gcc/sram.ld b/buildroot/share/PlatformIO/variants/archim/linker_scripts/gcc/sram.ld new file mode 100644 index 000000000000..2a0d54e179ad --- /dev/null +++ b/buildroot/share/PlatformIO/variants/archim/linker_scripts/gcc/sram.ld @@ -0,0 +1,145 @@ +/* ---------------------------------------------------------------------------- + * SAM Software Package License + * ---------------------------------------------------------------------------- + * Copyright (c) 2012, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following condition is met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +SEARCH_DIR(.) + +/* Memory Spaces Definitions */ +MEMORY +{ + rom (rx) : ORIGIN = 0x00080000, LENGTH = 0x00080000 /* Flash, 512K */ + sram0 (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00010000 /* sram0, 64K */ + sram1 (rwx) : ORIGIN = 0x20080000, LENGTH = 0x00008000 /* sram1, 32K */ + ram (rwx) : ORIGIN = 0x20070000, LENGTH = 0x00018000 /* sram, 96K */ +} + +/* The stack size used by the application. NOTE: you need to adjust */ +STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : 0x2000 ; + +/* Section Definitions */ +SECTIONS +{ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors .vectors.*)) + *(.text .text.* .gnu.linkonce.t.*) + *(.glue_7t) *(.glue_7) + *(.rodata .rodata* .gnu.linkonce.r.*) + *(.ARM.extab* .gnu.linkonce.armextab.*) + + /* Support C constructors, and C destructors in both user code + and the C library. This also provides support for C++ code. */ + . = ALIGN(4); + KEEP(*(.init)) + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(0x4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + + . = ALIGN(4); + _efixed = .; /* End of text section */ + } > ram + + . = ALIGN(4); + _etext = .; + + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _erelocate = .; + } > ram + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + } > ram + + /* stack section */ + .stack (NOLOAD): + { + . = ALIGN(8); + _sstack = .; + . = . + STACK_SIZE; + . = ALIGN(8); + _estack = .; + } > ram + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > ram + PROVIDE_HIDDEN (__exidx_end = .); + + . = ALIGN(4); + _end = . ; +} + diff --git a/buildroot/share/PlatformIO/variants/archim/linker_scripts/iar/flash.icf b/buildroot/share/PlatformIO/variants/archim/linker_scripts/iar/flash.icf new file mode 100644 index 000000000000..956230fbd354 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/archim/linker_scripts/iar/flash.icf @@ -0,0 +1,49 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */ +/*-Vector table start*/ +define symbol __ICFEDIT_vector_start__ = 0x00080000; /*Add for CMSIS*/ +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_RAM0_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM0_end__ = 0x20007FFF; +define symbol __ICFEDIT_region_RAM1_start__ = 0x20080000; +define symbol __ICFEDIT_region_RAM1_end__ = 0x20083FFF; +define symbol __ICFEDIT_region_ROM0_start__ = 0x00080000; +define symbol __ICFEDIT_region_ROM0_end__ = 0x0009FFFF; +define symbol __ICFEDIT_region_ROM1_start__ = 0x00100000; +define symbol __ICFEDIT_region_ROM1_end__ = 0x0011FFFF; +/*-Sizes-*/ +/*define symbol __ICFEDIT_size_cstack__ = 0x1000;*//*for nandflash*/ +define symbol __ICFEDIT_size_cstack__ = 0x2000; +define symbol __ICFEDIT_size_heap__ = 0x200; +/*-Specials-*/ +/*define symbol __ICFEDIT_region_RAM_VECT_start__ = __ICFEDIT_region_RAM0_start__;*/ /*Referenced for CMSIS*/ +/*define symbol __ICFEDIT_size_vectors__ = 0x100;*/ /*Referenced for CMSIS*/ +/*-Exports-*/ +/*export symbol __ICFEDIT_region_RAM_VECT_start__;*/ +export symbol __ICFEDIT_vector_start__; /*Add for CMSIS*/ +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +/*define region RAM_VECT_region = mem:[from __ICFEDIT_region_RAM_VECT_start__ size __ICFEDIT_size_vectors__];*/ /*Referenced for CMSIS*/ +/*define region RAM0_region = mem:[from __ICFEDIT_region_RAM0_start__+__ICFEDIT_size_vectors__ to __ICFEDIT_region_RAM0_end__];*/ /*Referenced for CMSIS*/ +define region RAM0_region = mem:[from __ICFEDIT_region_RAM0_start__ to __ICFEDIT_region_RAM0_end__]; +define region RAM1_region = mem:[from __ICFEDIT_region_RAM1_start__ to __ICFEDIT_region_RAM1_end__]; +/*define region RAM_region = mem:[from __ICFEDIT_region_RAM0_start__+__ICFEDIT_size_vectors__ to __ICFEDIT_region_RAM0_end__] | + mem:[from __ICFEDIT_region_RAM1_start__ to __ICFEDIT_region_RAM1_end__];*/ /*Referenced for CMSIS*/ +define region ROM0_region = mem:[from __ICFEDIT_region_ROM0_start__ to __ICFEDIT_region_ROM0_end__]; +define region ROM1_region = mem:[from __ICFEDIT_region_ROM1_start__ to __ICFEDIT_region_ROM1_end__]; + +/*define block RamVect with alignment = 8, size = __ICFEDIT_size_vectors__ { };*/ +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +/*place at start of ROM0_region { readonly section .vectors };*/ /*Referenced for CMSIS*/ +place at address mem:__ICFEDIT_vector_start__ { readonly section .intvec }; /*Add for CMSIS*/ +place in ROM0_region { readonly }; +place in RAM0_region { readwrite, block HEAP }; +place in RAM1_region { block CSTACK }; /* for nandflash*/ +/*place in RAM_VECT_region { block RamVect };*/ /*Referenced for CMSIS*/ \ No newline at end of file diff --git a/buildroot/share/PlatformIO/variants/archim/linker_scripts/iar/sram.icf b/buildroot/share/PlatformIO/variants/archim/linker_scripts/iar/sram.icf new file mode 100644 index 000000000000..d7d33537ac46 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/archim/linker_scripts/iar/sram.icf @@ -0,0 +1,33 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */ +/*-Vector table start*/ +define symbol __ICFEDIT_vector_start__ = 0x20000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_RAM0_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM0_end__ = 0x20007FFF; +define symbol __ICFEDIT_region_RAM1_start__ = 0x20080000; +define symbol __ICFEDIT_region_RAM1_end__ = 0x20083FFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x900; +define symbol __ICFEDIT_size_heap__ = 0x200; +/*-Exports-*/ +export symbol __ICFEDIT_vector_start__; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define region RAM0_region = mem:[from __ICFEDIT_region_RAM0_start__ to __ICFEDIT_region_RAM0_end__]; +define region RAM1_region = mem:[from __ICFEDIT_region_RAM1_start__ to __ICFEDIT_region_RAM1_end__]; +/*define region RAM_region = mem:[from __ICFEDIT_region_RAM0_start__+__ICFEDIT_size_vectors__ to __ICFEDIT_region_RAM0_end__] | + mem:[from __ICFEDIT_region_RAM1_start__ to __ICFEDIT_region_RAM1_end__];*/ + +/* define block RamVect with alignment = 8, size = __ICFEDIT_size_vectors__ { }; */ +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_vector_start__ { readonly section .intvec }; +place in RAM0_region { readonly }; +place in RAM1_region { readwrite, block CSTACK, block HEAP }; diff --git a/buildroot/share/PlatformIO/variants/archim/pins_arduino.h b/buildroot/share/PlatformIO/variants/archim/pins_arduino.h new file mode 100644 index 000000000000..4e279aa7bedb --- /dev/null +++ b/buildroot/share/PlatformIO/variants/archim/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// API compatibility +#include "variant.h" + diff --git a/buildroot/share/PlatformIO/variants/archim/variant.cpp b/buildroot/share/PlatformIO/variants/archim/variant.cpp new file mode 100644 index 000000000000..72ad45ef4602 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/archim/variant.cpp @@ -0,0 +1,485 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "variant.h" + +/* + * DUE Board pin | PORT | Label + * ----------------+--------+------- + * 0 | PA8 | "RX0" + * 1 | PA9 | "TX0" + * 2 TIOA0 | PB25 | + * 3 TIOA7 | PC28 | + * 4 NPCS1 | PA29 | + * TIOB6 | PC26 | + * 5 TIOA6 | PC25 | + * 6 PWML7 | PC24 | + * 7 PWML6 | PC23 | + * 8 PWML5 | PC22 | + * 9 PWML4 | PC21 | + * 10 NPCS0 | PA28 | + * TIOB7 | PC29 | + * 11 TIOA8 | PD7 | + * 12 TIOB8 | PD8 | + * 13 TIOB0 | PB27 | LED AMBER "L" + * 14 TXD3 | PD4 | "TX3" + * 15 RXD3 | PD5 | "RX3" + * 16 TXD1 | PA13 | "TX2" + * 17 RXD1 | PA12 | "RX2" + * 18 TXD0 | PA11 | "TX1" + * 19 RXD0 | PA10 | "RX1" + * 20 | PB12 | "SDA" + * 21 | PB13 | "SCL" + * 22 | PB26 | + * 23 | PA14 | + * 24 | PA15 | + * 25 | PD0 | + * 26 | PD1 | + * 27 | PD2 | + * 28 | PD3 | + * 29 | PD6 | + * 30 | PD9 | + * 31 | PA7 | + * 32 | PD10 | + * 33 | PC1 | + * 34 | PC2 | + * 35 | PC3 | + * 36 | PC4 | + * 37 | PC5 | + * 38 | PC6 | + * 39 | PC7 | + * 40 | PC8 | + * 41 | PC9 | + * 42 | PA19 | + * 43 | PA20 | + * 44 | PC19 | + * 45 | PC18 | + * 46 | PC17 | + * 47 | PC16 | + * 48 | PC15 | + * 49 | PC14 | + * 50 | PC13 | + * 51 | PC12 | + * 52 NPCS2 | PB21 | + * 53 | PB14 | + * 54 | PA16 | "A0" + * 55 | PA24 | "A1" + * 56 | PA23 | "A2" + * 57 | PA22 | "A3" + * 58 TIOB2 | PA6 | "A4" + * 69 | PA4 | "A5" + * 60 TIOB1 | PA3 | "A6" + * 61 TIOA1 | PA2 | "A7" + * 62 | PB17 | "A8" + * 63 | PB18 | "A9" + * 64 | PB19 | "A10" + * 65 | PB20 | "A11" + * 66 | PB15 | "DAC0" + * 67 | PB16 | "DAC1" + * 68 | PA1 | "CANRX" + * 69 | PA0 | "CANTX" + * 70 | PA17 | "SDA1" + * 71 | PA18 | "SCL1" + * 72 | PC30 | LED AMBER "RX" + * 73 | PA21 | LED AMBER "TX" + * 74 MISO | PA25 | + * 75 MOSI | PA26 | + * 76 SCLK | PA27 | + * 77 NPCS0 | PA28 | + * 78 NPCS3 | PB23 | unconnected! + * + * USB pin | PORT + * ----------------+-------- + * ID | PB11 + * VBOF | PB10 + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Pins descriptions + */ +extern const PinDescription g_APinDescription[]= +{ + // 0 .. 53 - Digital pins + // ---------------------- + // 0/1 - UART (Serial) + { PIOA, PIO_PA8A_URXD, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // URXD + { PIOA, PIO_PA9A_UTXD, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // UTXD + + // 2 + { PIOB, PIO_PB25B_TIOA0, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC0_CHA0 }, // TIOA0 + { PIOC, PIO_PC28B_TIOA7, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHA7 }, // TIOA7 + { PIOC, PIO_PC26B_TIOB6, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHB6 }, // TIOB6 + + // 5 + { PIOC, PIO_PC25B_TIOA6, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHA6 }, // TIOA6 + { PIOC, PIO_PC24B_PWML7, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH7, NOT_ON_TIMER }, // PWML7 + { PIOC, PIO_PC23B_PWML6, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH6, NOT_ON_TIMER }, // PWML6 + { PIOC, PIO_PC22B_PWML5, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH5, NOT_ON_TIMER }, // PWML5 + { PIOC, PIO_PC21B_PWML4, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH4, NOT_ON_TIMER }, // PWML4 + // 10 + { PIOC, PIO_PC29B_TIOB7, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHB7 }, // TIOB7 + { PIOD, PIO_PD7B_TIOA8, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHA8 }, // TIOA8 + { PIOD, PIO_PD8B_TIOB8, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHB8 }, // TIOB8 + + // 13 - AMBER LED + { PIOB, PIO_PB27B_TIOB0, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC0_CHB0 }, // TIOB0 + + // 14/15 - USART3 (Serial3) + { PIOD, PIO_PD4B_TXD3, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TXD3 + { PIOD, PIO_PD5B_RXD3, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // RXD3 + + // 16/17 - USART1 (Serial2) + { PIOA, PIO_PA13A_TXD1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TXD1 + { PIOA, PIO_PA12A_RXD1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // RXD1 + + // 18/19 - USART0 (Serial1) + { PIOA, PIO_PA11A_TXD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TXD0 + { PIOA, PIO_PA10A_RXD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // RXD0 + + // 20/21 - TWI1 + { PIOB, PIO_PB12A_TWD1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWD1 - SDA0 + { PIOB, PIO_PB13A_TWCK1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWCK1 - SCL0 + + // 22 + { PIOB, PIO_PB26, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 22 + { PIOA, PIO_PA14, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 23 + { PIOA, PIO_PA15, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 24 + { PIOD, PIO_PD0, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 25 + + // 26 + { PIOD, PIO_PD1, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 26 + { PIOD, PIO_PD2, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 27 + { PIOD, PIO_PD3, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 28 + { PIOD, PIO_PD6, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 29 + + // 30 + { PIOD, PIO_PD9, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 30 + { PIOA, PIO_PA7, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 31 + { PIOD, PIO_PD10, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 32 + { PIOC, PIO_PC1, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 33 + + // 34 + { PIOC, PIO_PC2, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 34 + { PIOC, PIO_PC3, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 35 +//{ PIOC, PIO_PC3B_PWMH0, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH0, NOT_ON_TIMER }, // PWMH0 PIN 35 + { PIOC, PIO_PC4, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 36 + { PIOC, PIO_PC5, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 37 +//{ PIOC, PIO_PC5B_PWMH1, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH1, NOT_ON_TIMER }, // PWMH1 PIN 37 + + // 38 + { PIOC, PIO_PC6, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 38 + { PIOC, PIO_PC7, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 39 +//{ PIOC, PIO_PC7B_PWMH2, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH2, NOT_ON_TIMER }, // PWMH2 PIN 39 + { PIOC, PIO_PC8, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 40 +//{ PIOC, PIO_PC8B_PWML3, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH3, NOT_ON_TIMER }, // PWML3 PIN 40 + { PIOC, PIO_PC9, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 41 + + // 42 + { PIOA, PIO_PA19, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 42 + { PIOA, PIO_PA20, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 43 + { PIOC, PIO_PC19, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 44 +//{ PIOC, PIO_PC19B_PWMH5, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH5, NOT_ON_TIMER }, // PWMH5 PIN 44 + { PIOC, PIO_PC18, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 45 + + // 46 + { PIOC, PIO_PC17, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 46 + { PIOC, PIO_PC16, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 47 + { PIOC, PIO_PC15, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 48 + { PIOC, PIO_PC14, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 49 + + // 50 + { PIOC, PIO_PC13, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 50 + { PIOC, PIO_PC12, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 51 + { PIOB, PIO_PB21, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 52 + { PIOB, PIO_PB14, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 53 + + + // 54 .. 65 - Analog pins + // ---------------------- + { PIOA, PIO_PA16X1_AD7, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC0, ADC7, NOT_ON_PWM, NOT_ON_TIMER }, // AD0 + { PIOA, PIO_PA24X1_AD6, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC1, ADC6, NOT_ON_PWM, NOT_ON_TIMER }, // AD1 + { PIOA, PIO_PA23X1_AD5, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC2, ADC5, NOT_ON_PWM, NOT_ON_TIMER }, // AD2 + { PIOA, PIO_PA22X1_AD4, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC3, ADC4, NOT_ON_PWM, NOT_ON_TIMER }, // AD3 + // 58 +//{ PIOA, PIO_PA6X1_AD3, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC4, ADC3, NOT_ON_PWM, TC0_CHB2 }, // AD4 + { PIOA, PIO_PA6A_TIOB2, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_TIMER|PIN_ATTR_DIGITAL), ADC4, ADC3, NOT_ON_PWM, TC0_CHB2 }, // TIOB2 + { PIOA, PIO_PA4X1_AD2, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC5, ADC2, NOT_ON_PWM, NOT_ON_TIMER }, // AD5 + { PIOA, PIO_PA3X1_AD1, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC6, ADC1, NOT_ON_PWM, TC0_CHB1 }, // AD6 + { PIOA, PIO_PA2X1_AD0, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC7, ADC0, NOT_ON_PWM, TC0_CHA1 }, // AD7 + // 62 + { PIOB, PIO_PB17X1_AD10, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC8, ADC10, NOT_ON_PWM, NOT_ON_TIMER }, // AD8 + { PIOB, PIO_PB18X1_AD11, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC9, ADC11, NOT_ON_PWM, NOT_ON_TIMER }, // AD9 + { PIOB, PIO_PB19X1_AD12, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC10, ADC12, NOT_ON_PWM, NOT_ON_TIMER }, // AD10 + { PIOB, PIO_PB20X1_AD13, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC11, ADC13, NOT_ON_PWM, NOT_ON_TIMER }, // AD11 + + // 66/67 - DAC0/DAC1 + { PIOB, PIO_PB15X1_DAC0, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC12, DA0, NOT_ON_PWM, NOT_ON_TIMER }, // DAC0 + { PIOB, PIO_PB16X1_DAC1, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC13, DA1, NOT_ON_PWM, NOT_ON_TIMER }, // DAC1 + + // 68/69 - CANRX0/CANTX0 + { PIOA, PIO_PA1A_CANRX0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, ADC14, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANRX + { PIOA, PIO_PA0A_CANTX0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, ADC15, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANTX + + // 70/71 - TWI0 + { PIOA, PIO_PA17A_TWD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWD0 - SDA1 + { PIOA, PIO_PA18A_TWCK0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWCK0 - SCL1 + + // 72/73 - LEDs + { PIOC, PIO_PC30, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // LED AMBER RXL + { PIOA, PIO_PA21, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // LED AMBER TXL + + // 74/75/76 - SPI + { PIOA, PIO_PA25A_SPI0_MISO,ID_PIOA,PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // MISO + { PIOA, PIO_PA26A_SPI0_MOSI,ID_PIOA,PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // MOSI + { PIOA, PIO_PA27A_SPI0_SPCK,ID_PIOA,PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // SPCK + + // 77 - SPI CS0 + { PIOA, PIO_PA28A_SPI0_NPCS0,ID_PIOA,PIO_PERIPH_A,PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS0 + + // 78 - SPI CS3 (unconnected) + { PIOB, PIO_PB23B_SPI0_NPCS3,ID_PIOB,PIO_PERIPH_B,PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS3 + + // 79 .. 84 - "All pins" masks + + // 79 - TWI0 all pins + { PIOA, PIO_PA17A_TWD0|PIO_PA18A_TWCK0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + // 80 - TWI1 all pins + { PIOB, PIO_PB12A_TWD1|PIO_PB13A_TWCK1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + // 81 - UART (Serial) all pins + { PIOA, PIO_PA8A_URXD|PIO_PA9A_UTXD, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + // 82 - USART0 (Serial1) all pins + { PIOA, PIO_PA11A_TXD0|PIO_PA10A_RXD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + // 83 - USART1 (Serial2) all pins + { PIOA, PIO_PA13A_TXD1|PIO_PA12A_RXD1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + // 84 - USART3 (Serial3) all pins + { PIOD, PIO_PD4B_TXD3|PIO_PD5B_RXD3, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + + // 85 - USB +//{ PIOB, PIO_PB11A_UOTGID|PIO_PB10A_UOTGVBOF, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL,NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ID - VBOF + // 85 - PB11 only + { PIOB, PIO_PB11A_UOTGID, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL,NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ID - VBOF + + // 86 - SPI CS2 + { PIOB, PIO_PB21B_SPI0_NPCS2, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS2 + + // 87 - SPI CS1 + { PIOA, PIO_PA29A_SPI0_NPCS1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS1 + + // 88/89 - CANRX1/CANTX1 (same physical pin for 66/53) + { PIOB, PIO_PB15A_CANRX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANRX1 + { PIOB, PIO_PB14A_CANTX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANTX1 + + // 90 .. 91 - "All CAN pins" masks + // 90 - CAN0 all pins + { PIOA, PIO_PA1A_CANRX0|PIO_PA0A_CANTX0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + // 91 - CAN1 all pins + { PIOB, PIO_PB15A_CANRX1|PIO_PB14A_CANTX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + + // 92 - Extra AMBIT Pins + { PIOC, PIO_PC11, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // DIO PIN 92 + { PIOB, PIO_PB2, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // DIO PIN 93 + { PIOB, PIO_PB1, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // DIO PIN 94 + { PIOB, PIO_PB0, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // DIO PIN 95 + { PIOC, PIO_PC10, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // DIO PIN 96 + { PIOB, PIO_PB24, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // DIO PIN 97 + { PIOB, PIO_PB7, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // DIO PIN 98 + { PIOB, PIO_PB6, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // DIO PIN 99 + { PIOB, PIO_PB8, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // DIO PIN 100 + { PIOB, PIO_PB5, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // DIO PIN 101 + { PIOB, PIO_PB4, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // DIO PIN 102 + { PIOB, PIO_PB3, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // DIO PIN 103 + { PIOC, PIO_PC20, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // DIO PIN 104 + { PIOB, PIO_PB22, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // DIO PIN 105 + { PIOC, PIO_PC27, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // DIO PIN 106 + { PIOB, PIO_PB10B_A18, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // DIO PIN 107 + { PIOB, PIO_PB9, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // DIO PIN 108 + { PIOA, PIO_PA5, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // DIO PIN 109 + + // END + { NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER } +} ; + + +uint8_t g_pinStatus[PINS_COUNT] = {0}; + +#ifdef __cplusplus +} +#endif + +/* + * UART objects + */ +RingBuffer rx_buffer1; +RingBuffer tx_buffer1; + +UARTClass Serial(UART, UART_IRQn, ID_UART, &rx_buffer1, &tx_buffer1); +void serialEvent() __attribute__((weak)); +void serialEvent() { } + +// IT handlers +void UART_Handler(void) +{ + Serial.IrqHandler(); +} + +// ---------------------------------------------------------------------------- +/* + * USART objects + */ +RingBuffer rx_buffer2; +RingBuffer rx_buffer3; +RingBuffer rx_buffer4; +RingBuffer tx_buffer2; +RingBuffer tx_buffer3; +RingBuffer tx_buffer4; + +USARTClass Serial1(USART0, USART0_IRQn, ID_USART0, &rx_buffer2, &tx_buffer2); +void serialEvent1() __attribute__((weak)); +void serialEvent1() { } +USARTClass Serial2(USART1, USART1_IRQn, ID_USART1, &rx_buffer3, &tx_buffer3); +void serialEvent2() __attribute__((weak)); +void serialEvent2() { } +USARTClass Serial3(USART3, USART3_IRQn, ID_USART3, &rx_buffer4, &tx_buffer4); +void serialEvent3() __attribute__((weak)); +void serialEvent3() { } + +// IT handlers +void USART0_Handler(void) +{ + Serial1.IrqHandler(); +} + +void USART1_Handler(void) +{ + Serial2.IrqHandler(); +} + +void USART3_Handler(void) +{ + Serial3.IrqHandler(); +} + +// ---------------------------------------------------------------------------- + +void serialEventRun(void) +{ + if (Serial.available()) serialEvent(); + if (Serial1.available()) serialEvent1(); + if (Serial2.available()) serialEvent2(); + if (Serial3.available()) serialEvent3(); +} + +// ---------------------------------------------------------------------------- + +#ifdef __cplusplus +extern "C" { +#endif + +void __libc_init_array(void); + +void init( void ) +{ + SystemInit(); + + // Set Systick to 1ms interval, common to all SAM3 variants + if (SysTick_Config(SystemCoreClock / 1000)) + { + // Capture error + while (true); + } + + // Initialize C library + __libc_init_array(); + + // Disable pull-up on every pin + for (unsigned i = 0; i < PINS_COUNT; i++) + digitalWrite(i, LOW); + + // Enable parallel access on PIO output data registers + PIOA->PIO_OWER = 0xFFFFFFFF; + PIOB->PIO_OWER = 0xFFFFFFFF; + PIOC->PIO_OWER = 0xFFFFFFFF; + PIOD->PIO_OWER = 0xFFFFFFFF; + + // Set USB Full Speed for Archim + udd_low_speed_disable(); + udd_high_speed_disable(); + + // Initialize Serial port U(S)ART pins + PIO_Configure( + g_APinDescription[PINS_UART].pPort, + g_APinDescription[PINS_UART].ulPinType, + g_APinDescription[PINS_UART].ulPin, + g_APinDescription[PINS_UART].ulPinConfiguration); + digitalWrite(0, HIGH); // Enable pullup for RX0 + PIO_Configure( + g_APinDescription[PINS_USART0].pPort, + g_APinDescription[PINS_USART0].ulPinType, + g_APinDescription[PINS_USART0].ulPin, + g_APinDescription[PINS_USART0].ulPinConfiguration); + PIO_Configure( + g_APinDescription[PINS_USART1].pPort, + g_APinDescription[PINS_USART1].ulPinType, + g_APinDescription[PINS_USART1].ulPin, + g_APinDescription[PINS_USART1].ulPinConfiguration); + PIO_Configure( + g_APinDescription[PINS_USART3].pPort, + g_APinDescription[PINS_USART3].ulPinType, + g_APinDescription[PINS_USART3].ulPin, + g_APinDescription[PINS_USART3].ulPinConfiguration); + + // Initialize USB pins + PIO_Configure( + g_APinDescription[PINS_USB].pPort, + g_APinDescription[PINS_USB].ulPinType, + g_APinDescription[PINS_USB].ulPin, + g_APinDescription[PINS_USB].ulPinConfiguration); + + // Initialize CAN pins + PIO_Configure( + g_APinDescription[PINS_CAN0].pPort, + g_APinDescription[PINS_CAN0].ulPinType, + g_APinDescription[PINS_CAN0].ulPin, + g_APinDescription[PINS_CAN0].ulPinConfiguration); + PIO_Configure( + g_APinDescription[PINS_CAN1].pPort, + g_APinDescription[PINS_CAN1].ulPinType, + g_APinDescription[PINS_CAN1].ulPin, + g_APinDescription[PINS_CAN1].ulPinConfiguration); + + // Initialize Analog Controller + pmc_enable_periph_clk(ID_ADC); + adc_init(ADC, SystemCoreClock, ADC_FREQ_MAX, ADC_STARTUP_FAST); + adc_configure_timing(ADC, 0, ADC_SETTLING_TIME_3, 1); + adc_configure_trigger(ADC, ADC_TRIG_SW, 0); // Disable hardware trigger. + adc_disable_interrupt(ADC, 0xFFFFFFFF); // Disable all ADC interrupts. + adc_disable_all_channel(ADC); + + // Initialize analogOutput module + analogOutputInit(); +} + +#ifdef __cplusplus +} +#endif + diff --git a/buildroot/share/PlatformIO/variants/archim/variant.h b/buildroot/share/PlatformIO/variants/archim/variant.h new file mode 100644 index 000000000000..179a13735376 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/archim/variant.h @@ -0,0 +1,284 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _VARIANT_ARDUINO_DUE_X_ +#define _VARIANT_ARDUINO_DUE_X_ + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC 12000000 + +/** Master clock frequency */ +#define VARIANT_MCK 84000000 + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "Arduino.h" +#ifdef __cplusplus +#include "UARTClass.h" +#include "USARTClass.h" +#endif + +#ifdef __cplusplus +extern "C"{ +#endif // __cplusplus + +/** + * Libc porting layers + */ +#if defined ( __GNUC__ ) /* GCC CS3 */ +# include /** RedHat Newlib minimal stub */ +#endif + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (79U) +#define NUM_DIGITAL_PINS (66U) +#define NUM_ANALOG_INPUTS (12U) +#define analogInputToDigitalPin(p) ((p < 12U) ? (p) + 54U : -1) + +#define digitalPinToPort(P) ( g_APinDescription[P].pPort ) +#define digitalPinToBitMask(P) ( g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->PIO_ODSR) ) +#define portInputRegister(port) ( &(port->PIO_PDSR) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * portModeRegister(..) should return a register to set pin mode + * INPUT or OUTPUT by setting the corresponding bit to 0 or 1. + * Unfortunately on SAM architecture the PIO_OSR register is + * read-only and can be set only through the enable/disable registers + * pair PIO_OER/PIO_ODR. + */ +// #define portModeRegister(port) ( &(port->PIO_OSR) ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAM + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// Interrupts +#define digitalPinToInterrupt(p) ((p) < NUM_DIGITAL_PINS ? (p) : -1) + +// LEDs +#define PIN_LED_13 (13U) +#define PIN_LED_RXL (72U) +#define PIN_LED_TXL (73U) +#define PIN_LED PIN_LED_13 +#define PIN_LED2 PIN_LED_RXL +#define PIN_LED3 PIN_LED_TXL +#define LED_BUILTIN 13 + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 1 + +#define SPI_INTERFACE SPI0 +#define SPI_INTERFACE_ID ID_SPI0 +#define SPI_CHANNELS_NUM 4 +#define PIN_SPI_SS0 (77U) +#define PIN_SPI_SS1 (87U) +#define PIN_SPI_SS2 (86U) +#define PIN_SPI_SS3 (78U) +#define PIN_SPI_MOSI (75U) +#define PIN_SPI_MISO (74U) +#define PIN_SPI_SCK (76U) +#define BOARD_SPI_SS0 (77U) //(10U) +#define BOARD_SPI_SS1 (4U) +#define BOARD_SPI_SS2 (52U) +#define BOARD_SPI_SS3 PIN_SPI_SS3 +#define BOARD_SPI_DEFAULT_SS BOARD_SPI_SS3 + +#define BOARD_PIN_TO_SPI_PIN(x) \ + (x==BOARD_SPI_SS0 ? PIN_SPI_SS0 : \ + (x==BOARD_SPI_SS1 ? PIN_SPI_SS1 : \ + (x==BOARD_SPI_SS2 ? PIN_SPI_SS2 : PIN_SPI_SS3 ))) +#define BOARD_PIN_TO_SPI_CHANNEL(x) \ + (x==BOARD_SPI_SS0 ? 0 : \ + (x==BOARD_SPI_SS1 ? 1 : \ + (x==BOARD_SPI_SS2 ? 2 : 3))) + +static const uint8_t SS = BOARD_SPI_SS0; +static const uint8_t SS1 = BOARD_SPI_SS1; +static const uint8_t SS2 = BOARD_SPI_SS2; +static const uint8_t SS3 = BOARD_SPI_SS3; +static const uint8_t MOSI = PIN_SPI_MOSI; +static const uint8_t MISO = PIN_SPI_MISO; +static const uint8_t SCK = PIN_SPI_SCK; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 2 + +#define PIN_WIRE_SDA (20U) +#define PIN_WIRE_SCL (21U) +#define WIRE_INTERFACE TWI1 +#define WIRE_INTERFACE_ID ID_TWI1 +#define WIRE_ISR_HANDLER TWI1_Handler +#define WIRE_ISR_ID TWI1_IRQn + +#define PIN_WIRE1_SDA (70U) +#define PIN_WIRE1_SCL (71U) +#define WIRE1_INTERFACE TWI0 +#define WIRE1_INTERFACE_ID ID_TWI0 +#define WIRE1_ISR_HANDLER TWI0_Handler +#define WIRE1_ISR_ID TWI0_IRQn + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; +static const uint8_t SDA1 = PIN_WIRE1_SDA; +static const uint8_t SCL1 = PIN_WIRE1_SCL; + +/* + * UART/USART Interfaces + */ +// Serial +#define PINS_UART (81U) +// Serial1 +#define PINS_USART0 (82U) +// Serial2 +#define PINS_USART1 (83U) +// Serial3 +#define PINS_USART3 (84U) + +/* + * USB Interfaces + */ +#define PINS_USB (85U) + +/* + * Analog pins + */ +static const uint8_t A0 = 54; +static const uint8_t A1 = 55; +static const uint8_t A2 = 56; +static const uint8_t A3 = 57; +static const uint8_t A4 = 58; +static const uint8_t A5 = 59; +static const uint8_t A6 = 60; +static const uint8_t A7 = 61; +static const uint8_t A8 = 62; +static const uint8_t A9 = 63; +static const uint8_t A10 = 64; +static const uint8_t A11 = 65; +static const uint8_t DAC0 = 66; +static const uint8_t DAC1 = 67; +static const uint8_t CANRX = 68; +static const uint8_t CANTX = 69; +#define ADC_RESOLUTION 12 + +/* + * Complementary CAN pins + */ +static const uint8_t CAN1RX = 88; +static const uint8_t CAN1TX = 89; + +// CAN0 +#define PINS_CAN0 (90U) +// CAN1 +#define PINS_CAN1 (91U) + + +/* + * DACC + */ +#define DACC_INTERFACE DACC +#define DACC_INTERFACE_ID ID_DACC +#define DACC_RESOLUTION 12 +#define DACC_ISR_HANDLER DACC_Handler +#define DACC_ISR_ID DACC_IRQn + +/* + * PWM + */ +#define PWM_INTERFACE PWM +#define PWM_INTERFACE_ID ID_PWM +#define PWM_FREQUENCY 31000 +#define PWM_MAX_DUTY_CYCLE 255 +#define PWM_MIN_DUTY_CYCLE 0 +#define PWM_RESOLUTION 8 + +/* + * TC + */ +#define TC_INTERFACE TC0 +#define TC_INTERFACE_ID ID_TC0 +#define TC_FREQUENCY 100000 +#define TC_MAX_DUTY_CYCLE 255 +#define TC_MIN_DUTY_CYCLE 0 +#define TC_RESOLUTION 8 + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +extern UARTClass Serial; +extern USARTClass Serial1; +extern USARTClass Serial2; +extern USARTClass Serial3; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_MONITOR Serial +#define SERIAL_PORT_USBVIRTUAL SerialUSB +#define SERIAL_PORT_HARDWARE_OPEN Serial1 +#define SERIAL_PORT_HARDWARE_OPEN1 Serial2 +#define SERIAL_PORT_HARDWARE_OPEN2 Serial3 +#define SERIAL_PORT_HARDWARE Serial +#define SERIAL_PORT_HARDWARE1 Serial1 +#define SERIAL_PORT_HARDWARE2 Serial2 +#define SERIAL_PORT_HARDWARE3 Serial3 + +#endif /* _VARIANT_ARDUINO_DUE_X_ */ + diff --git a/buildroot/share/PlatformIO/variants/megaextendedpins/pins_arduino.h b/buildroot/share/PlatformIO/variants/megaextendedpins/pins_arduino.h new file mode 100755 index 000000000000..81f2ae3e19a1 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/megaextendedpins/pins_arduino.h @@ -0,0 +1,461 @@ +/* + pins_arduino.h - Pin definition functions for Arduino + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2007 David A. Mellis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +#define NUM_DIGITAL_PINS 86 +#define NUM_ANALOG_INPUTS 16 +#define analogInputToDigitalPin(p) ((p < 16) ? (p) + 54 : -1) +#define digitalPinHasPWM(p) (((p) >= 2 && (p) <= 13) || ((p) >= 44 && (p)<= 46)) + +#define PIN_SPI_SS (53) +#define PIN_SPI_MOSI (51) +#define PIN_SPI_MISO (50) +#define PIN_SPI_SCK (52) + +static const uint8_t SS = PIN_SPI_SS; +static const uint8_t MOSI = PIN_SPI_MOSI; +static const uint8_t MISO = PIN_SPI_MISO; +static const uint8_t SCK = PIN_SPI_SCK; + +#define PIN_WIRE_SDA (20) +#define PIN_WIRE_SCL (21) + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +#define LED_BUILTIN 13 + +#define PIN_A0 (54) +#define PIN_A1 (55) +#define PIN_A2 (56) +#define PIN_A3 (57) +#define PIN_A4 (58) +#define PIN_A5 (59) +#define PIN_A6 (60) +#define PIN_A7 (61) +#define PIN_A8 (62) +#define PIN_A9 (63) +#define PIN_A10 (64) +#define PIN_A11 (65) +#define PIN_A12 (66) +#define PIN_A13 (67) +#define PIN_A14 (68) +#define PIN_A15 (69) + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6; +static const uint8_t A7 = PIN_A7; +static const uint8_t A8 = PIN_A8; +static const uint8_t A9 = PIN_A9; +static const uint8_t A10 = PIN_A10; +static const uint8_t A11 = PIN_A11; +static const uint8_t A12 = PIN_A12; +static const uint8_t A13 = PIN_A13; +static const uint8_t A14 = PIN_A14; +static const uint8_t A15 = PIN_A15; + +// A majority of the pins are NOT PCINTs, SO BE WARNED (i.e. you cannot use them as receive pins) +// Only pins available for RECEIVE (TRANSMIT can be on any pin): +// (I've deliberately left out pin mapping to the Hardware USARTs - seems senseless to me) +// Pins: 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69 + +#define digitalPinToPCICR(p) ( (((p) >= 10) && ((p) <= 13)) || \ + (((p) >= 50) && ((p) <= 53)) || \ + (((p) >= 62) && ((p) <= 69)) ? (&PCICR) : ((uint8_t *)0) ) + +#define digitalPinToPCICRbit(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? 0 : \ + ( (((p) >= 62) && ((p) <= 69)) ? 2 : \ + 0 ) ) + +#define digitalPinToPCMSK(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? (&PCMSK0) : \ + ( (((p) >= 62) && ((p) <= 69)) ? (&PCMSK2) : \ + ((uint8_t *)0) ) ) + +#define digitalPinToPCMSKbit(p) ( (((p) >= 10) && ((p) <= 13)) ? ((p) - 6) : \ + ( ((p) == 50) ? 3 : \ + ( ((p) == 51) ? 2 : \ + ( ((p) == 52) ? 1 : \ + ( ((p) == 53) ? 0 : \ + ( (((p) >= 62) && ((p) <= 69)) ? ((p) - 62) : \ + 0 ) ) ) ) ) ) + +#define digitalPinToInterrupt(p) ((p) == 2 ? 0 : ((p) == 3 ? 1 : ((p) >= 18 && (p) <= 21 ? 23 - (p) : NOT_AN_INTERRUPT))) + +#ifdef ARDUINO_MAIN + +const uint16_t PROGMEM port_to_mode_PGM[] = { + NOT_A_PORT, + (uint16_t) &DDRA, + (uint16_t) &DDRB, + (uint16_t) &DDRC, + (uint16_t) &DDRD, + (uint16_t) &DDRE, + (uint16_t) &DDRF, + (uint16_t) &DDRG, + (uint16_t) &DDRH, + NOT_A_PORT, + (uint16_t) &DDRJ, + (uint16_t) &DDRK, + (uint16_t) &DDRL, +}; + +const uint16_t PROGMEM port_to_output_PGM[] = { + NOT_A_PORT, + (uint16_t) &PORTA, + (uint16_t) &PORTB, + (uint16_t) &PORTC, + (uint16_t) &PORTD, + (uint16_t) &PORTE, + (uint16_t) &PORTF, + (uint16_t) &PORTG, + (uint16_t) &PORTH, + NOT_A_PORT, + (uint16_t) &PORTJ, + (uint16_t) &PORTK, + (uint16_t) &PORTL, +}; + +const uint16_t PROGMEM port_to_input_PGM[] = { + NOT_A_PIN, + (uint16_t) &PINA, + (uint16_t) &PINB, + (uint16_t) &PINC, + (uint16_t) &PIND, + (uint16_t) &PINE, + (uint16_t) &PINF, + (uint16_t) &PING, + (uint16_t) &PINH, + NOT_A_PIN, + (uint16_t) &PINJ, + (uint16_t) &PINK, + (uint16_t) &PINL, +}; + +const uint8_t PROGMEM digital_pin_to_port_PGM[] = { + // PORTLIST + // ------------------------------------------- + PE , // PE 0 ** 0 ** USART0_RX + PE , // PE 1 ** 1 ** USART0_TX + PE , // PE 4 ** 2 ** PWM2 + PE , // PE 5 ** 3 ** PWM3 + PG , // PG 5 ** 4 ** PWM4 + PE , // PE 3 ** 5 ** PWM5 + PH , // PH 3 ** 6 ** PWM6 + PH , // PH 4 ** 7 ** PWM7 + PH , // PH 5 ** 8 ** PWM8 + PH , // PH 6 ** 9 ** PWM9 + PB , // PB 4 ** 10 ** PWM10 + PB , // PB 5 ** 11 ** PWM11 + PB , // PB 6 ** 12 ** PWM12 + PB , // PB 7 ** 13 ** PWM13 + PJ , // PJ 1 ** 14 ** USART3_TX + PJ , // PJ 0 ** 15 ** USART3_RX + PH , // PH 1 ** 16 ** USART2_TX + PH , // PH 0 ** 17 ** USART2_RX + PD , // PD 3 ** 18 ** USART1_TX + PD , // PD 2 ** 19 ** USART1_RX + PD , // PD 1 ** 20 ** I2C_SDA + PD , // PD 0 ** 21 ** I2C_SCL + PA , // PA 0 ** 22 ** D22 + PA , // PA 1 ** 23 ** D23 + PA , // PA 2 ** 24 ** D24 + PA , // PA 3 ** 25 ** D25 + PA , // PA 4 ** 26 ** D26 + PA , // PA 5 ** 27 ** D27 + PA , // PA 6 ** 28 ** D28 + PA , // PA 7 ** 29 ** D29 + PC , // PC 7 ** 30 ** D30 + PC , // PC 6 ** 31 ** D31 + PC , // PC 5 ** 32 ** D32 + PC , // PC 4 ** 33 ** D33 + PC , // PC 3 ** 34 ** D34 + PC , // PC 2 ** 35 ** D35 + PC , // PC 1 ** 36 ** D36 + PC , // PC 0 ** 37 ** D37 + PD , // PD 7 ** 38 ** D38 + PG , // PG 2 ** 39 ** D39 + PG , // PG 1 ** 40 ** D40 + PG , // PG 0 ** 41 ** D41 + PL , // PL 7 ** 42 ** D42 + PL , // PL 6 ** 43 ** D43 + PL , // PL 5 ** 44 ** D44 + PL , // PL 4 ** 45 ** D45 + PL , // PL 3 ** 46 ** D46 + PL , // PL 2 ** 47 ** D47 + PL , // PL 1 ** 48 ** D48 + PL , // PL 0 ** 49 ** D49 + PB , // PB 3 ** 50 ** SPI_MISO + PB , // PB 2 ** 51 ** SPI_MOSI + PB , // PB 1 ** 52 ** SPI_SCK + PB , // PB 0 ** 53 ** SPI_SS + PF , // PF 0 ** 54 ** A0 + PF , // PF 1 ** 55 ** A1 + PF , // PF 2 ** 56 ** A2 + PF , // PF 3 ** 57 ** A3 + PF , // PF 4 ** 58 ** A4 + PF , // PF 5 ** 59 ** A5 + PF , // PF 6 ** 60 ** A6 + PF , // PF 7 ** 61 ** A7 + PK , // PK 0 ** 62 ** A8 + PK , // PK 1 ** 63 ** A9 + PK , // PK 2 ** 64 ** A10 + PK , // PK 3 ** 65 ** A11 + PK , // PK 4 ** 66 ** A12 + PK , // PK 5 ** 67 ** A13 + PK , // PK 6 ** 68 ** A14 + PK , // PK 7 ** 69 ** A15 + PG , // PG 4 ** 70 ** D70 + PG , // PG 3 ** 71 ** D71 + PJ , // PJ 2 ** 72 ** D72 + PJ , // PJ 3 ** 73 ** D73 + PJ , // PJ 7 ** 74 ** D74 + PJ , // PJ 4 ** 75 ** D75 + PJ , // PJ 5 ** 76 ** D76 + PJ , // PJ 6 ** 77 ** D77 + PE , // PE 2 ** 78 ** D78 + PE , // PE 6 ** 79 ** D79 + PE , // PE 7 ** 80 ** D80 + PD , // PD 4 ** 81 ** D81 + PD , // PD 5 ** 82 ** D82 + PD , // PD 6 ** 83 ** D83 + PH , // PH 2 ** 84 ** D84 + PH , // PH 7 ** 85 ** D85 +}; + +const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { + // PIN IN PORT + // ------------------------------------------- + _BV( 0 ) , // PE 0 ** 0 ** USART0_RX + _BV( 1 ) , // PE 1 ** 1 ** USART0_TX + _BV( 4 ) , // PE 4 ** 2 ** PWM2 + _BV( 5 ) , // PE 5 ** 3 ** PWM3 + _BV( 5 ) , // PG 5 ** 4 ** PWM4 + _BV( 3 ) , // PE 3 ** 5 ** PWM5 + _BV( 3 ) , // PH 3 ** 6 ** PWM6 + _BV( 4 ) , // PH 4 ** 7 ** PWM7 + _BV( 5 ) , // PH 5 ** 8 ** PWM8 + _BV( 6 ) , // PH 6 ** 9 ** PWM9 + _BV( 4 ) , // PB 4 ** 10 ** PWM10 + _BV( 5 ) , // PB 5 ** 11 ** PWM11 + _BV( 6 ) , // PB 6 ** 12 ** PWM12 + _BV( 7 ) , // PB 7 ** 13 ** PWM13 + _BV( 1 ) , // PJ 1 ** 14 ** USART3_TX + _BV( 0 ) , // PJ 0 ** 15 ** USART3_RX + _BV( 1 ) , // PH 1 ** 16 ** USART2_TX + _BV( 0 ) , // PH 0 ** 17 ** USART2_RX + _BV( 3 ) , // PD 3 ** 18 ** USART1_TX + _BV( 2 ) , // PD 2 ** 19 ** USART1_RX + _BV( 1 ) , // PD 1 ** 20 ** I2C_SDA + _BV( 0 ) , // PD 0 ** 21 ** I2C_SCL + _BV( 0 ) , // PA 0 ** 22 ** D22 + _BV( 1 ) , // PA 1 ** 23 ** D23 + _BV( 2 ) , // PA 2 ** 24 ** D24 + _BV( 3 ) , // PA 3 ** 25 ** D25 + _BV( 4 ) , // PA 4 ** 26 ** D26 + _BV( 5 ) , // PA 5 ** 27 ** D27 + _BV( 6 ) , // PA 6 ** 28 ** D28 + _BV( 7 ) , // PA 7 ** 29 ** D29 + _BV( 7 ) , // PC 7 ** 30 ** D30 + _BV( 6 ) , // PC 6 ** 31 ** D31 + _BV( 5 ) , // PC 5 ** 32 ** D32 + _BV( 4 ) , // PC 4 ** 33 ** D33 + _BV( 3 ) , // PC 3 ** 34 ** D34 + _BV( 2 ) , // PC 2 ** 35 ** D35 + _BV( 1 ) , // PC 1 ** 36 ** D36 + _BV( 0 ) , // PC 0 ** 37 ** D37 + _BV( 7 ) , // PD 7 ** 38 ** D38 + _BV( 2 ) , // PG 2 ** 39 ** D39 + _BV( 1 ) , // PG 1 ** 40 ** D40 + _BV( 0 ) , // PG 0 ** 41 ** D41 + _BV( 7 ) , // PL 7 ** 42 ** D42 + _BV( 6 ) , // PL 6 ** 43 ** D43 + _BV( 5 ) , // PL 5 ** 44 ** D44 + _BV( 4 ) , // PL 4 ** 45 ** D45 + _BV( 3 ) , // PL 3 ** 46 ** D46 + _BV( 2 ) , // PL 2 ** 47 ** D47 + _BV( 1 ) , // PL 1 ** 48 ** D48 + _BV( 0 ) , // PL 0 ** 49 ** D49 + _BV( 3 ) , // PB 3 ** 50 ** SPI_MISO + _BV( 2 ) , // PB 2 ** 51 ** SPI_MOSI + _BV( 1 ) , // PB 1 ** 52 ** SPI_SCK + _BV( 0 ) , // PB 0 ** 53 ** SPI_SS + _BV( 0 ) , // PF 0 ** 54 ** A0 + _BV( 1 ) , // PF 1 ** 55 ** A1 + _BV( 2 ) , // PF 2 ** 56 ** A2 + _BV( 3 ) , // PF 3 ** 57 ** A3 + _BV( 4 ) , // PF 4 ** 58 ** A4 + _BV( 5 ) , // PF 5 ** 59 ** A5 + _BV( 6 ) , // PF 6 ** 60 ** A6 + _BV( 7 ) , // PF 7 ** 61 ** A7 + _BV( 0 ) , // PK 0 ** 62 ** A8 + _BV( 1 ) , // PK 1 ** 63 ** A9 + _BV( 2 ) , // PK 2 ** 64 ** A10 + _BV( 3 ) , // PK 3 ** 65 ** A11 + _BV( 4 ) , // PK 4 ** 66 ** A12 + _BV( 5 ) , // PK 5 ** 67 ** A13 + _BV( 6 ) , // PK 6 ** 68 ** A14 + _BV( 7 ) , // PK 7 ** 69 ** A15 + _BV( 4 ) , // PG 4 ** 70 ** D70 + _BV( 3 ) , // PG 3 ** 71 ** D71 + _BV( 2 ) , // PJ 2 ** 72 ** D72 + _BV( 3 ) , // PJ 3 ** 73 ** D73 + _BV( 7 ) , // PJ 7 ** 74 ** D74 + _BV( 4 ) , // PJ 4 ** 75 ** D75 + _BV( 5 ) , // PJ 5 ** 76 ** D76 + _BV( 6 ) , // PJ 6 ** 77 ** D77 + _BV( 2 ) , // PE 2 ** 78 ** D78 + _BV( 6 ) , // PE 6 ** 79 ** D79 + _BV( 7 ) , // PE 7 ** 80 ** D80 + _BV( 4 ) , // PD 4 ** 81 ** D81 + _BV( 5 ) , // PD 5 ** 82 ** D82 + _BV( 6 ) , // PD 6 ** 83 ** D83 + _BV( 2 ) , // PH 2 ** 84 ** D84 + _BV( 7 ) , // PH 7 ** 85 ** D85 +}; + +const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { + // TIMERS + // ------------------------------------------- + NOT_ON_TIMER , // PE 0 ** 0 ** USART0_RX + NOT_ON_TIMER , // PE 1 ** 1 ** USART0_TX + TIMER3B , // PE 4 ** 2 ** PWM2 + TIMER3C , // PE 5 ** 3 ** PWM3 + TIMER0B , // PG 5 ** 4 ** PWM4 + TIMER3A , // PE 3 ** 5 ** PWM5 + TIMER4A , // PH 3 ** 6 ** PWM6 + TIMER4B , // PH 4 ** 7 ** PWM7 + TIMER4C , // PH 5 ** 8 ** PWM8 + TIMER2B , // PH 6 ** 9 ** PWM9 + TIMER2A , // PB 4 ** 10 ** PWM10 + TIMER1A , // PB 5 ** 11 ** PWM11 + TIMER1B , // PB 6 ** 12 ** PWM12 + TIMER0A , // PB 7 ** 13 ** PWM13 + NOT_ON_TIMER , // PJ 1 ** 14 ** USART3_TX + NOT_ON_TIMER , // PJ 0 ** 15 ** USART3_RX + NOT_ON_TIMER , // PH 1 ** 16 ** USART2_TX + NOT_ON_TIMER , // PH 0 ** 17 ** USART2_RX + NOT_ON_TIMER , // PD 3 ** 18 ** USART1_TX + NOT_ON_TIMER , // PD 2 ** 19 ** USART1_RX + NOT_ON_TIMER , // PD 1 ** 20 ** I2C_SDA + NOT_ON_TIMER , // PD 0 ** 21 ** I2C_SCL + NOT_ON_TIMER , // PA 0 ** 22 ** D22 + NOT_ON_TIMER , // PA 1 ** 23 ** D23 + NOT_ON_TIMER , // PA 2 ** 24 ** D24 + NOT_ON_TIMER , // PA 3 ** 25 ** D25 + NOT_ON_TIMER , // PA 4 ** 26 ** D26 + NOT_ON_TIMER , // PA 5 ** 27 ** D27 + NOT_ON_TIMER , // PA 6 ** 28 ** D28 + NOT_ON_TIMER , // PA 7 ** 29 ** D29 + NOT_ON_TIMER , // PC 7 ** 30 ** D30 + NOT_ON_TIMER , // PC 6 ** 31 ** D31 + NOT_ON_TIMER , // PC 5 ** 32 ** D32 + NOT_ON_TIMER , // PC 4 ** 33 ** D33 + NOT_ON_TIMER , // PC 3 ** 34 ** D34 + NOT_ON_TIMER , // PC 2 ** 35 ** D35 + NOT_ON_TIMER , // PC 1 ** 36 ** D36 + NOT_ON_TIMER , // PC 0 ** 37 ** D37 + NOT_ON_TIMER , // PD 7 ** 38 ** D38 + NOT_ON_TIMER , // PG 2 ** 39 ** D39 + NOT_ON_TIMER , // PG 1 ** 40 ** D40 + NOT_ON_TIMER , // PG 0 ** 41 ** D41 + NOT_ON_TIMER , // PL 7 ** 42 ** D42 + NOT_ON_TIMER , // PL 6 ** 43 ** D43 + TIMER5C , // PL 5 ** 44 ** D44 + TIMER5B , // PL 4 ** 45 ** D45 + TIMER5A , // PL 3 ** 46 ** D46 + NOT_ON_TIMER , // PL 2 ** 47 ** D47 + NOT_ON_TIMER , // PL 1 ** 48 ** D48 + NOT_ON_TIMER , // PL 0 ** 49 ** D49 + NOT_ON_TIMER , // PB 3 ** 50 ** SPI_MISO + NOT_ON_TIMER , // PB 2 ** 51 ** SPI_MOSI + NOT_ON_TIMER , // PB 1 ** 52 ** SPI_SCK + NOT_ON_TIMER , // PB 0 ** 53 ** SPI_SS + NOT_ON_TIMER , // PF 0 ** 54 ** A0 + NOT_ON_TIMER , // PF 1 ** 55 ** A1 + NOT_ON_TIMER , // PF 2 ** 56 ** A2 + NOT_ON_TIMER , // PF 3 ** 57 ** A3 + NOT_ON_TIMER , // PF 4 ** 58 ** A4 + NOT_ON_TIMER , // PF 5 ** 59 ** A5 + NOT_ON_TIMER , // PF 6 ** 60 ** A6 + NOT_ON_TIMER , // PF 7 ** 61 ** A7 + NOT_ON_TIMER , // PK 0 ** 62 ** A8 + NOT_ON_TIMER , // PK 1 ** 63 ** A9 + NOT_ON_TIMER , // PK 2 ** 64 ** A10 + NOT_ON_TIMER , // PK 3 ** 65 ** A11 + NOT_ON_TIMER , // PK 4 ** 66 ** A12 + NOT_ON_TIMER , // PK 5 ** 67 ** A13 + NOT_ON_TIMER , // PK 6 ** 68 ** A14 + NOT_ON_TIMER , // PK 7 ** 69 ** A15 + NOT_ON_TIMER , // PG 4 ** 70 ** D70 + NOT_ON_TIMER , // PG 3 ** 71 ** D71 + NOT_ON_TIMER , // PJ 2 ** 72 ** D72 + NOT_ON_TIMER , // PJ 3 ** 73 ** D73 + NOT_ON_TIMER , // PJ 7 ** 74 ** D74 + NOT_ON_TIMER , // PJ 4 ** 75 ** D75 + NOT_ON_TIMER , // PJ 5 ** 76 ** D76 + NOT_ON_TIMER , // PJ 6 ** 77 ** D77 + NOT_ON_TIMER , // PE 2 ** 78 ** D78 + NOT_ON_TIMER , // PE 6 ** 79 ** D79 + NOT_ON_TIMER , // PE 7 ** 80 ** D80 + NOT_ON_TIMER , // PD 4 ** 81 ** D81 + NOT_ON_TIMER , // PD 5 ** 82 ** D82 + NOT_ON_TIMER , // PD 6 ** 83 ** D83 + NOT_ON_TIMER , // PH 2 ** 84 ** D84 + NOT_ON_TIMER , // PH 7 ** 85 ** D85 +}; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_MONITOR Serial +#define SERIAL_PORT_HARDWARE Serial +#define SERIAL_PORT_HARDWARE1 Serial1 +#define SERIAL_PORT_HARDWARE2 Serial2 +#define SERIAL_PORT_HARDWARE3 Serial3 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 +#define SERIAL_PORT_HARDWARE_OPEN1 Serial2 +#define SERIAL_PORT_HARDWARE_OPEN2 Serial3 + +#endif diff --git a/buildroot/share/cmake/CMakeLists.txt b/buildroot/share/cmake/CMakeLists.txt index 1308f8bf9753..9d3f24f990aa 100644 --- a/buildroot/share/cmake/CMakeLists.txt +++ b/buildroot/share/cmake/CMakeLists.txt @@ -47,8 +47,8 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/marlin-cma # cmake .. -DARDUINO_SDK_PATH="/path/to/arduino-1.x.x" # #====================================================================# #set(ARDUINO_SDK_PATH ${CMAKE_CURRENT_LIST_DIR}/arduino-1.6.8) -#set(ARDUINO_SDK_PATH /home/tom/git/BigBox-Dual-Marlin/ArduinoAddons/Arduino_1.6.x) -#set(ARDUINO_SDK_PATH /home/tom/test/arduino-1.6.11) +#set(ARDUINO_SDK_PATH /Applications/Arduino.app/Contents/Java) +#set(ARDUINO_SDK_PATH $HOME/ArduinoAddons/Arduino_1.6.x) #====================================================================# # Set included cmake files # #====================================================================# @@ -96,8 +96,8 @@ setup_motherboard(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}/../../../Marlin) # Include Marlin.ino to compile libs not included in *.cpp files # #====================================================================# -file(GLOB SOURCES "../../../src/*.cpp") -set(${PROJECT_NAME}_SRCS "${SOURCES};../../../src/Marlin.ino") +file(GLOB_RECURSE SOURCES "../../../Marlin/*.cpp") +set(${PROJECT_NAME}_SRCS "${SOURCES};../../../Marlin/Marlin.ino") #====================================================================# # Define the port for uploading code to the Arduino # diff --git a/Marlin/src/HAL/HAL_AVR/inc/Conditionals_LCD.h b/buildroot/share/extras/header.h similarity index 88% rename from Marlin/src/HAL/HAL_AVR/inc/Conditionals_LCD.h rename to buildroot/share/extras/header.h index 0285c52ee365..5d2c73dfbeef 100644 --- a/Marlin/src/HAL/HAL_AVR/inc/Conditionals_LCD.h +++ b/buildroot/share/extras/header.h @@ -16,7 +16,11 @@ * 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 . + * along with this program. If not, see . * */ -#pragma once + +/** + * $(filename) + */ + diff --git a/buildroot/share/extras/uncrustify.cfg b/buildroot/share/extras/uncrustify.cfg new file mode 100644 index 000000000000..06661203f09c --- /dev/null +++ b/buildroot/share/extras/uncrustify.cfg @@ -0,0 +1,84 @@ +# +# Uncrustify Configuration File +# File Created With UncrustifyX 0.4.3 (252) +# +align_assign_span = 1 +cmt_cpp_to_c = false +cmt_indent_multi = false +cmt_insert_file_header = "./header.h" +cmt_reflow_mode = 1 +cmt_sp_after_star_cont = 1 +cmt_sp_before_star_cont = 1 +cmt_star_cont = true +eat_blanks_after_open_brace = false +eat_blanks_before_close_brace = false +indent_align_assign = false +indent_case_brace = 0 +indent_columns = 2 +indent_cpp_lambda_body = false +indent_func_call_param = true +indent_func_def_param = true +indent_switch_case = 2 +indent_with_tabs = 0 +input_tab_size = 2 +mod_add_long_ifdef_else_comment = 40 +mod_add_long_ifdef_endif_comment = 40 +mod_full_brace_do = false +mod_full_brace_for = false +mod_full_brace_if = false +mod_full_brace_if_chain = true +mod_full_brace_while = false +mod_remove_extra_semicolon = true +newlines = lf +nl_after_brace_close = true +nl_after_brace_open = true +nl_assign_leave_one_liners = true +nl_brace_else = add +nl_class_leave_one_liners = true +nl_create_for_one_liner = true +nl_create_if_one_liner = false +nl_create_while_one_liner = true +nl_else_brace = remove +nl_end_of_file = add +nl_enum_brace = remove +nl_enum_leave_one_liners = true +nl_fdef_brace = remove +nl_for_brace = remove +nl_func_leave_one_liners = true +nl_getset_leave_one_liners = true +nl_if_brace = remove +nl_if_leave_one_liners = true +nl_multi_line_sparen_close = add +nl_squeeze_ifdef = false +nl_struct_brace = remove +nl_switch_brace = remove +nl_union_brace = remove +pp_define_at_level = true +pp_if_indent_code = true +pp_indent = add +pp_indent_at_level = true +pp_indent_count = 2 +pp_indent_if = 0 +sp_after_comma = add +sp_after_semi = add +sp_after_sparen = add +sp_arith = add +sp_assign = add +sp_assign_default = remove +sp_before_comma = remove +sp_before_sparen = add +sp_bool = add +sp_brace_else = add +sp_cmt_cpp_start = add +sp_compare = add +sp_cond_colon = add +sp_cond_question = add +sp_else_brace = add +sp_endif_cmt = true +sp_fparen_brace = add +sp_func_call_paren = remove +sp_func_proto_paren = remove +sp_inside_sparen = remove +sp_inside_square = remove +sp_paren_brace = add +sp_paren_paren = remove diff --git a/buildroot/share/fonts/README.md b/buildroot/share/fonts/README.md index 4e6f6f9b1528..b80de8e26e13 100644 --- a/buildroot/share/fonts/README.md +++ b/buildroot/share/fonts/README.md @@ -1,11 +1,10 @@ # Marlin fonts - ## Author and license The original author of the following font files is [A. Hardtung](https://github.com/AnHardt). Any copyright is dedicated to the Public Domain. -http://creativecommons.org/publicdomain/zero/1.0/ +https://creativecommons.org/publicdomain/zero/1.0/ - HD44780_C.fon ([fe2bd23](https://github.com/MarlinFirmware/Marlin/commit/fe2bd237d556439499dfdee852c1550c7a16430a)) - HD44780_J.fon ([fe2bd23](https://github.com/MarlinFirmware/Marlin/commit/fe2bd237d556439499dfdee852c1550c7a16430a)) @@ -16,8 +15,7 @@ http://creativecommons.org/publicdomain/zero/1.0/ - ISO10646_Kana.fon ([fe2bd23](https://github.com/MarlinFirmware/Marlin/commit/fe2bd237d556439499dfdee852c1550c7a16430a)) - Marlin_symbols.fon ([fe2bd23](https://github.com/MarlinFirmware/Marlin/commit/fe2bd237d556439499dfdee852c1550c7a16430a)) -Additional changes to the original font files distributed with Marlin are copyrighted under the terms of the [GPLv3](http://www.gnu.org/licenses/gpl-3.0.txt) license. - +Additional changes to the original font files distributed with Marlin are copyrighted under the terms of the [GPLv3](https://www.gnu.org/licenses/gpl-3.0.txt) license. ## Documentation -For detailed information about [adding new fonts](http://www.marlinfw.org/docs/development/fonts.html) to Marlin visit our documentation website. +For detailed information about adding new fonts to Marlin [see this article](https://marlinfw.org/docs/development/fonts.html). diff --git a/buildroot/share/fonts/genallfont.sh b/buildroot/share/fonts/genallfont.sh index 7d4b551776a4..66f8e2c84f78 100755 --- a/buildroot/share/fonts/genallfont.sh +++ b/buildroot/share/fonts/genallfont.sh @@ -62,7 +62,7 @@ OLDWD=`pwd` # # By default loop through all languages # -LANGS_DEFAULT="an bg ca cz da de el el_gr en es eu fi fr gl hr it jp_kana ko_KR nl pl pt pt_br ru sk tr uk vi zh_CN zh_TW test" +LANGS_DEFAULT="an bg ca cz da de el el_gr en es eu fi fr gl hr hu it jp_kana ko_KR nl pl pt pt_br ro ru sk tr uk vi zh_CN zh_TW test" # # Generate data for language list MARLIN_LANGS or all if not provided @@ -116,7 +116,7 @@ if [ 1 = 1 ]; then * 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 . + * along with this program. If not, see . * */ #include diff --git a/buildroot/share/fonts/marlin-6x12-3.bdf b/buildroot/share/fonts/marlin-6x12-3.bdf index ef90656eba1b..bc7a8827c037 100644 --- a/buildroot/share/fonts/marlin-6x12-3.bdf +++ b/buildroot/share/fonts/marlin-6x12-3.bdf @@ -106,16 +106,15 @@ B8 ENDCHAR STARTCHAR uni0006 ENCODING 6 -SWIDTH 545 0 -DWIDTH 6 0 -BBX 5 6 0 1 +SWIDTH 504 0 +DWIDTH 7 0 +BBX 8 5 0 1 BITMAP -E0 -8C -EA -8C -8A -0A +D8 +6C +36 +6C +D8 ENDCHAR STARTCHAR uni0007 ENCODING 7 diff --git a/buildroot/share/fonts/marlin-6x9.bdf b/buildroot/share/fonts/marlin-6x9.bdf new file mode 100644 index 000000000000..0b2683471082 --- /dev/null +++ b/buildroot/share/fonts/marlin-6x9.bdf @@ -0,0 +1,16606 @@ +STARTFONT 2.1 +FONT -Misc-Fixed-Medium-R-Normal--9-90-75-75-C-60-ISO10646-1 +SIZE 9 75 75 +FONTBOUNDINGBOX 6 9 0 -2 +COMMENT "Generated by fontforge, http://fontforge.sourceforge.net" +STARTPROPERTIES 24 +FONTNAME_REGISTRY "" +FOUNDRY "Misc" +FAMILY_NAME "Fixed" +WEIGHT_NAME "Medium" +SLANT "R" +SETWIDTH_NAME "Normal" +ADD_STYLE_NAME "" +PIXEL_SIZE 9 +POINT_SIZE 90 +RESOLUTION_X 75 +RESOLUTION_Y 75 +SPACING "C" +AVERAGE_WIDTH 60 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" +COPYRIGHT "Public domain font. Share and enjoy." +_XMBDFED_INFO "Edited with xmbdfed 4.5." +CAP_HEIGHT 6 +X_HEIGHT 4 +WEIGHT 10 +QUAD_WIDTH 6 +DEFAULT_CHAR 0 +FONT_DESCENT 2 +FONT_ASCENT 7 +ENDPROPERTIES +CHARS 1305 +STARTCHAR char0 +ENCODING 0 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +50 +80 +10 +80 +10 +A0 +ENDCHAR +STARTCHAR uni0001 +ENCODING 1 +SWIDTH 1000 0 +DWIDTH 0 0 +BBX 5 7 0 0 +BITMAP +40 +F0 +C8 +88 +98 +78 +10 +ENDCHAR +STARTCHAR uni0002 +ENCODING 2 +SWIDTH 1000 0 +DWIDTH 0 0 +BBX 5 7 0 0 +BITMAP +C0 +F8 +88 +88 +88 +88 +F8 +ENDCHAR +STARTCHAR uni0003 +ENCODING 3 +SWIDTH 1000 0 +DWIDTH 0 0 +BBX 5 5 0 1 +BITMAP +20 +30 +F8 +30 +20 +ENDCHAR +STARTCHAR uni0004 +ENCODING 4 +SWIDTH 1000 0 +DWIDTH 0 0 +BBX 5 7 0 0 +BITMAP +20 +70 +F8 +20 +20 +20 +E0 +ENDCHAR +STARTCHAR uni0005 +ENCODING 5 +SWIDTH 1000 0 +DWIDTH 0 0 +BBX 5 7 0 0 +BITMAP +20 +70 +A8 +B8 +88 +70 +20 +ENDCHAR +STARTCHAR uni0006 +ENCODING 6 +SWIDTH 1000 0 +DWIDTH 0 0 +BBX 6 5 0 0 +BITMAP +B0 +D8 +6C +D8 +B0 +ENDCHAR +STARTCHAR uni0007 +ENCODING 7 +SWIDTH 1000 0 +DWIDTH 0 0 +BBX 5 8 0 -1 +BITMAP +F8 +A8 +88 +88 +88 +88 +A8 +F8 +ENDCHAR +STARTCHAR uni0008 +ENCODING 8 +SWIDTH 1000 0 +DWIDTH 0 0 +BBX 5 9 0 -2 +BITMAP +20 +50 +50 +50 +50 +88 +A8 +88 +70 +ENDCHAR +STARTCHAR uni0009 +ENCODING 9 +SWIDTH 1000 0 +DWIDTH 0 0 +BBX 3 3 0 3 +BITMAP +40 +A0 +40 +ENDCHAR +STARTCHAR space +ENCODING 32 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 1 5 -2 +BITMAP +00 +ENDCHAR +STARTCHAR exclam +ENCODING 33 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 6 2 0 +BITMAP +80 +80 +80 +80 +00 +80 +ENDCHAR +STARTCHAR quotedbl +ENCODING 34 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 3 +BITMAP +A0 +A0 +A0 +ENDCHAR +STARTCHAR numbersign +ENCODING 35 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +50 +50 +F8 +50 +F8 +50 +50 +ENDCHAR +STARTCHAR dollar +ENCODING 36 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 9 0 -2 +BITMAP +20 +70 +A8 +A0 +70 +28 +A8 +70 +20 +ENDCHAR +STARTCHAR percent +ENCODING 37 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 8 0 -1 +BITMAP +40 +A8 +48 +10 +20 +48 +54 +08 +ENDCHAR +STARTCHAR ampersand +ENCODING 38 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +60 +98 +90 +68 +ENDCHAR +STARTCHAR quotesingle +ENCODING 39 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 3 2 3 +BITMAP +80 +80 +80 +ENDCHAR +STARTCHAR parenleft +ENCODING 40 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 7 2 -1 +BITMAP +40 +80 +80 +80 +80 +80 +40 +ENDCHAR +STARTCHAR parenright +ENCODING 41 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 7 2 -1 +BITMAP +80 +40 +40 +40 +40 +40 +80 +ENDCHAR +STARTCHAR asterisk +ENCODING 42 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +88 +50 +F8 +50 +88 +ENDCHAR +STARTCHAR plus +ENCODING 43 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +20 +20 +F8 +20 +20 +ENDCHAR +STARTCHAR comma +ENCODING 44 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 4 2 -2 +BITMAP +C0 +40 +40 +80 +ENDCHAR +STARTCHAR hyphen +ENCODING 45 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 1 0 2 +BITMAP +F8 +ENDCHAR +STARTCHAR period +ENCODING 46 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 2 2 0 +BITMAP +C0 +C0 +ENDCHAR +STARTCHAR slash +ENCODING 47 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +10 +10 +20 +40 +80 +80 +ENDCHAR +STARTCHAR zero +ENCODING 48 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +60 +90 +90 +90 +90 +60 +ENDCHAR +STARTCHAR one +ENCODING 49 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 1 0 +BITMAP +40 +C0 +40 +40 +40 +E0 +ENDCHAR +STARTCHAR two +ENCODING 50 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +60 +90 +10 +20 +40 +F0 +ENDCHAR +STARTCHAR three +ENCODING 51 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +F0 +20 +60 +10 +10 +E0 +ENDCHAR +STARTCHAR four +ENCODING 52 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +10 +30 +50 +90 +F8 +10 +ENDCHAR +STARTCHAR five +ENCODING 53 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +F0 +80 +E0 +10 +10 +E0 +ENDCHAR +STARTCHAR six +ENCODING 54 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +60 +80 +E0 +90 +90 +60 +ENDCHAR +STARTCHAR seven +ENCODING 55 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +F0 +10 +10 +20 +40 +40 +ENDCHAR +STARTCHAR eight +ENCODING 56 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +60 +90 +60 +90 +90 +60 +ENDCHAR +STARTCHAR nine +ENCODING 57 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +60 +90 +90 +70 +10 +60 +ENDCHAR +STARTCHAR colon +ENCODING 58 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 5 2 0 +BITMAP +C0 +C0 +00 +C0 +C0 +ENDCHAR +STARTCHAR semicolon +ENCODING 59 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 7 2 -2 +BITMAP +C0 +C0 +00 +C0 +40 +40 +80 +ENDCHAR +STARTCHAR less +ENCODING 60 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +18 +60 +80 +60 +18 +ENDCHAR +STARTCHAR equal +ENCODING 61 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 3 0 1 +BITMAP +F8 +00 +F8 +ENDCHAR +STARTCHAR greater +ENCODING 62 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +C0 +30 +08 +30 +C0 +ENDCHAR +STARTCHAR question +ENCODING 63 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +60 +90 +10 +60 +40 +00 +40 +ENDCHAR +STARTCHAR at +ENCODING 64 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +90 +A8 +B0 +80 +70 +ENDCHAR +STARTCHAR A +ENCODING 65 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +20 +50 +88 +F8 +88 +88 +ENDCHAR +STARTCHAR B +ENCODING 66 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +F0 +88 +F0 +88 +88 +F0 +ENDCHAR +STARTCHAR C +ENCODING 67 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +60 +90 +80 +80 +90 +60 +ENDCHAR +STARTCHAR D +ENCODING 68 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +E0 +90 +90 +90 +90 +E0 +ENDCHAR +STARTCHAR E +ENCODING 69 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +F0 +80 +E0 +80 +80 +F0 +ENDCHAR +STARTCHAR F +ENCODING 70 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +F0 +80 +E0 +80 +80 +80 +ENDCHAR +STARTCHAR G +ENCODING 71 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +60 +90 +80 +B0 +90 +60 +ENDCHAR +STARTCHAR H +ENCODING 72 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +90 +90 +F0 +90 +90 +90 +ENDCHAR +STARTCHAR I +ENCODING 73 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 1 0 +BITMAP +E0 +40 +40 +40 +40 +E0 +ENDCHAR +STARTCHAR J +ENCODING 74 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +38 +10 +10 +10 +90 +60 +ENDCHAR +STARTCHAR K +ENCODING 75 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +90 +A0 +C0 +A0 +90 +90 +ENDCHAR +STARTCHAR L +ENCODING 76 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +80 +80 +80 +80 +80 +F0 +ENDCHAR +STARTCHAR M +ENCODING 77 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +88 +D8 +A8 +A8 +88 +88 +ENDCHAR +STARTCHAR N +ENCODING 78 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +90 +D0 +B0 +90 +90 +90 +ENDCHAR +STARTCHAR O +ENCODING 79 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR P +ENCODING 80 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +E0 +90 +90 +E0 +80 +80 +ENDCHAR +STARTCHAR Q +ENCODING 81 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 -1 +BITMAP +60 +90 +90 +D0 +B0 +60 +10 +ENDCHAR +STARTCHAR R +ENCODING 82 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +E0 +90 +90 +E0 +90 +90 +ENDCHAR +STARTCHAR S +ENCODING 83 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +60 +90 +40 +20 +90 +60 +ENDCHAR +STARTCHAR T +ENCODING 84 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +F8 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR U +ENCODING 85 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +90 +90 +90 +90 +90 +60 +ENDCHAR +STARTCHAR V +ENCODING 86 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +90 +90 +90 +F0 +60 +60 +ENDCHAR +STARTCHAR W +ENCODING 87 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +88 +88 +A8 +A8 +D8 +88 +ENDCHAR +STARTCHAR X +ENCODING 88 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +88 +50 +20 +20 +50 +88 +ENDCHAR +STARTCHAR Y +ENCODING 89 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +88 +88 +50 +20 +20 +20 +ENDCHAR +STARTCHAR Z +ENCODING 90 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +F0 +10 +20 +40 +80 +F0 +ENDCHAR +STARTCHAR bracketleft +ENCODING 91 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 1 0 +BITMAP +E0 +80 +80 +80 +80 +E0 +ENDCHAR +STARTCHAR backslash +ENCODING 92 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +80 +80 +40 +20 +10 +10 +ENDCHAR +STARTCHAR bracketright +ENCODING 93 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 1 0 +BITMAP +E0 +20 +20 +20 +20 +E0 +ENDCHAR +STARTCHAR asciicircum +ENCODING 94 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 3 0 3 +BITMAP +20 +50 +88 +ENDCHAR +STARTCHAR underscore +ENCODING 95 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 1 0 -2 +BITMAP +F8 +ENDCHAR +STARTCHAR grave +ENCODING 96 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 2 2 4 +BITMAP +80 +40 +ENDCHAR +STARTCHAR a +ENCODING 97 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +70 +90 +90 +70 +ENDCHAR +STARTCHAR b +ENCODING 98 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +80 +80 +E0 +90 +90 +E0 +ENDCHAR +STARTCHAR c +ENCODING 99 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +70 +80 +80 +70 +ENDCHAR +STARTCHAR d +ENCODING 100 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +10 +10 +70 +90 +90 +70 +ENDCHAR +STARTCHAR e +ENCODING 101 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +60 +B0 +C0 +70 +ENDCHAR +STARTCHAR f +ENCODING 102 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +20 +50 +40 +E0 +40 +40 +ENDCHAR +STARTCHAR g +ENCODING 103 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 -2 +BITMAP +60 +90 +90 +70 +10 +60 +ENDCHAR +STARTCHAR h +ENCODING 104 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +80 +80 +E0 +90 +90 +90 +ENDCHAR +STARTCHAR i +ENCODING 105 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 1 0 +BITMAP +40 +00 +C0 +40 +40 +E0 +ENDCHAR +STARTCHAR j +ENCODING 106 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 8 1 -2 +BITMAP +20 +00 +60 +20 +20 +20 +A0 +40 +ENDCHAR +STARTCHAR k +ENCODING 107 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +80 +80 +A0 +C0 +A0 +90 +ENDCHAR +STARTCHAR l +ENCODING 108 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 1 0 +BITMAP +C0 +40 +40 +40 +40 +E0 +ENDCHAR +STARTCHAR m +ENCODING 109 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +D0 +A8 +A8 +88 +ENDCHAR +STARTCHAR n +ENCODING 110 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +E0 +90 +90 +90 +ENDCHAR +STARTCHAR o +ENCODING 111 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +60 +90 +90 +60 +ENDCHAR +STARTCHAR p +ENCODING 112 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 -2 +BITMAP +E0 +90 +90 +E0 +80 +80 +ENDCHAR +STARTCHAR q +ENCODING 113 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 -2 +BITMAP +70 +90 +90 +70 +10 +10 +ENDCHAR +STARTCHAR r +ENCODING 114 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +A0 +D0 +80 +80 +ENDCHAR +STARTCHAR s +ENCODING 115 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +70 +C0 +30 +E0 +ENDCHAR +STARTCHAR t +ENCODING 116 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +40 +40 +E0 +40 +50 +20 +ENDCHAR +STARTCHAR u +ENCODING 117 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +90 +90 +90 +70 +ENDCHAR +STARTCHAR v +ENCODING 118 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +90 +90 +60 +60 +ENDCHAR +STARTCHAR w +ENCODING 119 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +88 +A8 +A8 +50 +ENDCHAR +STARTCHAR x +ENCODING 120 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +90 +60 +60 +90 +ENDCHAR +STARTCHAR y +ENCODING 121 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 -2 +BITMAP +90 +90 +90 +70 +90 +60 +ENDCHAR +STARTCHAR z +ENCODING 122 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +F0 +20 +40 +F0 +ENDCHAR +STARTCHAR braceleft +ENCODING 123 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 0 +BITMAP +20 +40 +40 +80 +40 +40 +20 +ENDCHAR +STARTCHAR bar +ENCODING 124 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 7 2 -1 +BITMAP +80 +80 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR braceright +ENCODING 125 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 0 +BITMAP +80 +40 +40 +20 +40 +40 +80 +ENDCHAR +STARTCHAR asciitilde +ENCODING 126 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 2 1 3 +BITMAP +50 +A0 +ENDCHAR +STARTCHAR space +ENCODING 160 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 1 5 -2 +BITMAP +00 +ENDCHAR +STARTCHAR exclamdown +ENCODING 161 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 6 2 0 +BITMAP +80 +00 +80 +80 +80 +80 +ENDCHAR +STARTCHAR cent +ENCODING 162 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 -1 +BITMAP +20 +70 +A0 +A0 +70 +20 +ENDCHAR +STARTCHAR sterling +ENCODING 163 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +30 +48 +40 +F0 +40 +40 +F8 +ENDCHAR +STARTCHAR currency +ENCODING 164 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +A8 +50 +88 +50 +A8 +ENDCHAR +STARTCHAR yen +ENCODING 165 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +88 +50 +F8 +20 +F8 +20 +ENDCHAR +STARTCHAR brokenbar +ENCODING 166 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 7 2 -1 +BITMAP +80 +80 +80 +00 +80 +80 +80 +ENDCHAR +STARTCHAR section +ENCODING 167 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 -1 +BITMAP +70 +80 +60 +90 +60 +10 +E0 +ENDCHAR +STARTCHAR dieresis +ENCODING 168 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 1 1 5 +BITMAP +A0 +ENDCHAR +STARTCHAR copyright +ENCODING 169 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 7 0 0 +BITMAP +78 +84 +94 +A4 +94 +84 +78 +ENDCHAR +STARTCHAR ordfeminine +ENCODING 170 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +60 +A0 +60 +00 +E0 +ENDCHAR +STARTCHAR guillemotleft +ENCODING 171 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +28 +50 +A0 +50 +28 +ENDCHAR +STARTCHAR logicalnot +ENCODING 172 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 3 1 0 +BITMAP +F0 +10 +10 +ENDCHAR +STARTCHAR hyphen +ENCODING 173 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 1 1 2 +BITMAP +F0 +ENDCHAR +STARTCHAR registered +ENCODING 174 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 7 0 0 +BITMAP +78 +84 +B4 +A4 +A4 +84 +78 +ENDCHAR +STARTCHAR macron +ENCODING 175 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 1 1 5 +BITMAP +F0 +ENDCHAR +STARTCHAR degree +ENCODING 176 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 3 1 2 +BITMAP +60 +90 +60 +ENDCHAR +STARTCHAR plusminus +ENCODING 177 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +20 +20 +F8 +20 +20 +00 +F8 +ENDCHAR +STARTCHAR twosuperior +ENCODING 178 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +40 +A0 +20 +40 +E0 +ENDCHAR +STARTCHAR threesuperior +ENCODING 179 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +C0 +20 +40 +20 +C0 +ENDCHAR +STARTCHAR acute +ENCODING 180 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 2 2 4 +BITMAP +40 +80 +ENDCHAR +STARTCHAR mu +ENCODING 181 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 5 1 -1 +BITMAP +90 +90 +B0 +D0 +80 +ENDCHAR +STARTCHAR paragraph +ENCODING 182 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +78 +E8 +E8 +68 +28 +28 +ENDCHAR +STARTCHAR periodcentered +ENCODING 183 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 1 2 2 +BITMAP +80 +ENDCHAR +STARTCHAR cedilla +ENCODING 184 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 2 2 -2 +BITMAP +40 +80 +ENDCHAR +STARTCHAR onesuperior +ENCODING 185 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +40 +C0 +40 +40 +E0 +ENDCHAR +STARTCHAR ordmasculine +ENCODING 186 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +40 +A0 +40 +00 +E0 +ENDCHAR +STARTCHAR guillemotright +ENCODING 187 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +A0 +50 +28 +50 +A0 +ENDCHAR +STARTCHAR onequarter +ENCODING 188 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -1 +BITMAP +40 +C0 +40 +50 +70 +30 +78 +10 +ENDCHAR +STARTCHAR onehalf +ENCODING 189 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -1 +BITMAP +40 +C0 +40 +50 +68 +08 +10 +38 +ENDCHAR +STARTCHAR threequarters +ENCODING 190 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -1 +BITMAP +C0 +20 +40 +30 +F0 +30 +78 +10 +ENDCHAR +STARTCHAR questiondown +ENCODING 191 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +00 +20 +60 +80 +90 +60 +ENDCHAR +STARTCHAR Agrave +ENCODING 192 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +40 +20 +20 +50 +70 +88 +88 +ENDCHAR +STARTCHAR Aacute +ENCODING 193 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +10 +20 +20 +50 +70 +88 +88 +ENDCHAR +STARTCHAR Acircumflex +ENCODING 194 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +20 +50 +20 +50 +70 +88 +88 +ENDCHAR +STARTCHAR Atilde +ENCODING 195 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +28 +50 +20 +50 +70 +88 +88 +ENDCHAR +STARTCHAR Adieresis +ENCODING 196 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +50 +00 +20 +50 +70 +88 +88 +ENDCHAR +STARTCHAR Aring +ENCODING 197 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +20 +50 +20 +50 +70 +88 +88 +ENDCHAR +STARTCHAR AE +ENCODING 198 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +78 +A0 +F0 +A0 +A0 +B8 +ENDCHAR +STARTCHAR Ccedilla +ENCODING 199 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -2 +BITMAP +60 +90 +80 +80 +90 +60 +20 +40 +ENDCHAR +STARTCHAR Egrave +ENCODING 200 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +40 +20 +F0 +80 +E0 +80 +F0 +ENDCHAR +STARTCHAR Eacute +ENCODING 201 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +40 +F0 +80 +E0 +80 +F0 +ENDCHAR +STARTCHAR Ecircumflex +ENCODING 202 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +50 +F0 +80 +E0 +80 +F0 +ENDCHAR +STARTCHAR Edieresis +ENCODING 203 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +00 +F0 +80 +E0 +80 +F0 +ENDCHAR +STARTCHAR Igrave +ENCODING 204 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 0 +BITMAP +80 +40 +E0 +40 +40 +40 +E0 +ENDCHAR +STARTCHAR Iacute +ENCODING 205 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 0 +BITMAP +20 +40 +E0 +40 +40 +40 +E0 +ENDCHAR +STARTCHAR Icircumflex +ENCODING 206 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 0 +BITMAP +40 +A0 +E0 +40 +40 +40 +E0 +ENDCHAR +STARTCHAR Idieresis +ENCODING 207 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 0 +BITMAP +A0 +00 +E0 +40 +40 +40 +E0 +ENDCHAR +STARTCHAR Eth +ENCODING 208 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +48 +E8 +48 +48 +70 +ENDCHAR +STARTCHAR Ntilde +ENCODING 209 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +A0 +90 +D0 +B0 +90 +90 +ENDCHAR +STARTCHAR Ograve +ENCODING 210 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +40 +20 +60 +90 +90 +90 +60 +ENDCHAR +STARTCHAR Oacute +ENCODING 211 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +40 +60 +90 +90 +90 +60 +ENDCHAR +STARTCHAR Ocircumflex +ENCODING 212 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +50 +60 +90 +90 +90 +60 +ENDCHAR +STARTCHAR Otilde +ENCODING 213 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +A0 +60 +90 +90 +90 +60 +ENDCHAR +STARTCHAR Odieresis +ENCODING 214 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +00 +60 +90 +90 +90 +60 +ENDCHAR +STARTCHAR multiply +ENCODING 215 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +88 +50 +20 +50 +88 +ENDCHAR +STARTCHAR Oslash +ENCODING 216 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -1 +BITMAP +10 +70 +B0 +B0 +D0 +D0 +E0 +80 +ENDCHAR +STARTCHAR Ugrave +ENCODING 217 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +40 +20 +90 +90 +90 +90 +60 +ENDCHAR +STARTCHAR Uacute +ENCODING 218 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +40 +90 +90 +90 +90 +60 +ENDCHAR +STARTCHAR Ucircumflex +ENCODING 219 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +50 +90 +90 +90 +90 +60 +ENDCHAR +STARTCHAR Udieresis +ENCODING 220 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +00 +90 +90 +90 +90 +60 +ENDCHAR +STARTCHAR Yacute +ENCODING 221 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +10 +20 +88 +50 +20 +20 +20 +ENDCHAR +STARTCHAR Thorn +ENCODING 222 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +80 +E0 +90 +90 +E0 +80 +ENDCHAR +STARTCHAR germandbls +ENCODING 223 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +60 +90 +A0 +A0 +90 +A0 +ENDCHAR +STARTCHAR agrave +ENCODING 224 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +40 +20 +00 +70 +90 +90 +70 +ENDCHAR +STARTCHAR aacute +ENCODING 225 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +40 +00 +70 +90 +90 +70 +ENDCHAR +STARTCHAR acircumflex +ENCODING 226 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +50 +00 +70 +90 +90 +70 +ENDCHAR +STARTCHAR atilde +ENCODING 227 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +A0 +00 +70 +90 +90 +70 +ENDCHAR +STARTCHAR adieresis +ENCODING 228 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +50 +00 +70 +90 +90 +70 +ENDCHAR +STARTCHAR aring +ENCODING 229 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +50 +20 +70 +90 +90 +70 +ENDCHAR +STARTCHAR ae +ENCODING 230 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +70 +A8 +B0 +78 +ENDCHAR +STARTCHAR ccedilla +ENCODING 231 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 -2 +BITMAP +70 +80 +80 +70 +20 +40 +ENDCHAR +STARTCHAR egrave +ENCODING 232 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +40 +20 +00 +60 +B0 +C0 +70 +ENDCHAR +STARTCHAR eacute +ENCODING 233 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +40 +00 +60 +B0 +C0 +70 +ENDCHAR +STARTCHAR ecircumflex +ENCODING 234 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +50 +00 +60 +B0 +C0 +70 +ENDCHAR +STARTCHAR edieresis +ENCODING 235 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +50 +00 +60 +B0 +C0 +70 +ENDCHAR +STARTCHAR igrave +ENCODING 236 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 0 +BITMAP +80 +40 +00 +C0 +40 +40 +E0 +ENDCHAR +STARTCHAR iacute +ENCODING 237 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 0 +BITMAP +20 +40 +00 +C0 +40 +40 +E0 +ENDCHAR +STARTCHAR icircumflex +ENCODING 238 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 0 +BITMAP +40 +A0 +00 +C0 +40 +40 +E0 +ENDCHAR +STARTCHAR idieresis +ENCODING 239 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 1 0 +BITMAP +A0 +00 +C0 +40 +40 +E0 +ENDCHAR +STARTCHAR eth +ENCODING 240 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +30 +60 +10 +70 +90 +90 +60 +ENDCHAR +STARTCHAR ntilde +ENCODING 241 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +A0 +00 +E0 +90 +90 +90 +ENDCHAR +STARTCHAR ograve +ENCODING 242 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +40 +20 +00 +60 +90 +90 +60 +ENDCHAR +STARTCHAR oacute +ENCODING 243 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +40 +00 +60 +90 +90 +60 +ENDCHAR +STARTCHAR ocircumflex +ENCODING 244 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +50 +00 +60 +90 +90 +60 +ENDCHAR +STARTCHAR otilde +ENCODING 245 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +A0 +00 +60 +90 +90 +60 +ENDCHAR +STARTCHAR odieresis +ENCODING 246 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +50 +00 +60 +90 +90 +60 +ENDCHAR +STARTCHAR divide +ENCODING 247 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +20 +00 +F8 +00 +20 +ENDCHAR +STARTCHAR oslash +ENCODING 248 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +70 +B0 +D0 +E0 +ENDCHAR +STARTCHAR ugrave +ENCODING 249 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +40 +20 +00 +90 +90 +90 +70 +ENDCHAR +STARTCHAR uacute +ENCODING 250 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +40 +00 +90 +90 +90 +70 +ENDCHAR +STARTCHAR ucircumflex +ENCODING 251 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +50 +00 +90 +90 +90 +70 +ENDCHAR +STARTCHAR udieresis +ENCODING 252 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +50 +00 +90 +90 +90 +70 +ENDCHAR +STARTCHAR yacute +ENCODING 253 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 9 1 -2 +BITMAP +20 +40 +00 +90 +90 +90 +70 +90 +60 +ENDCHAR +STARTCHAR thorn +ENCODING 254 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -2 +BITMAP +80 +80 +E0 +90 +90 +E0 +80 +80 +ENDCHAR +STARTCHAR ydieresis +ENCODING 255 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -2 +BITMAP +50 +00 +90 +90 +90 +70 +90 +60 +ENDCHAR +STARTCHAR Amacron +ENCODING 256 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +70 +00 +20 +50 +70 +88 +88 +ENDCHAR +STARTCHAR amacron +ENCODING 257 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +70 +00 +70 +90 +90 +70 +ENDCHAR +STARTCHAR Abreve +ENCODING 258 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +90 +60 +20 +50 +70 +88 +88 +ENDCHAR +STARTCHAR abreve +ENCODING 259 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +90 +60 +00 +70 +90 +90 +70 +ENDCHAR +STARTCHAR Aogonek +ENCODING 260 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -2 +BITMAP +20 +50 +88 +F8 +88 +88 +10 +08 +ENDCHAR +STARTCHAR aogonek +ENCODING 261 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 -2 +BITMAP +70 +90 +90 +70 +20 +10 +ENDCHAR +STARTCHAR Cacute +ENCODING 262 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +40 +60 +90 +80 +90 +60 +ENDCHAR +STARTCHAR cacute +ENCODING 263 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +40 +00 +70 +80 +80 +70 +ENDCHAR +STARTCHAR Ccircumflex +ENCODING 264 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +50 +60 +90 +80 +90 +60 +ENDCHAR +STARTCHAR ccircumflex +ENCODING 265 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +50 +00 +70 +80 +80 +70 +ENDCHAR +STARTCHAR Cdotaccent +ENCODING 266 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +00 +60 +90 +80 +90 +60 +ENDCHAR +STARTCHAR cdotaccent +ENCODING 267 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +20 +00 +70 +80 +80 +70 +ENDCHAR +STARTCHAR Ccaron +ENCODING 268 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +20 +60 +90 +80 +90 +60 +ENDCHAR +STARTCHAR ccaron +ENCODING 269 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +20 +00 +70 +80 +80 +70 +ENDCHAR +STARTCHAR Dcaron +ENCODING 270 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +20 +E0 +90 +90 +90 +E0 +ENDCHAR +STARTCHAR dcaron +ENCODING 271 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +A0 +50 +10 +70 +90 +90 +70 +ENDCHAR +STARTCHAR Dcroat +ENCODING 272 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +48 +E8 +48 +48 +70 +ENDCHAR +STARTCHAR dcroat +ENCODING 273 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +10 +38 +70 +90 +90 +70 +ENDCHAR +STARTCHAR Emacron +ENCODING 274 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +F0 +00 +F0 +80 +E0 +80 +F0 +ENDCHAR +STARTCHAR emacron +ENCODING 275 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +F0 +00 +60 +B0 +C0 +70 +ENDCHAR +STARTCHAR Ebreve +ENCODING 276 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +90 +60 +F0 +80 +E0 +80 +F0 +ENDCHAR +STARTCHAR ebreve +ENCODING 277 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +90 +60 +00 +60 +B0 +C0 +70 +ENDCHAR +STARTCHAR Edotaccent +ENCODING 278 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +40 +00 +F0 +80 +E0 +80 +F0 +ENDCHAR +STARTCHAR edotaccent +ENCODING 279 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +40 +00 +60 +B0 +C0 +70 +ENDCHAR +STARTCHAR Eogonek +ENCODING 280 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -2 +BITMAP +F0 +80 +E0 +80 +80 +F0 +40 +20 +ENDCHAR +STARTCHAR eogonek +ENCODING 281 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 -2 +BITMAP +60 +B0 +C0 +70 +40 +20 +ENDCHAR +STARTCHAR Ecaron +ENCODING 282 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +20 +F0 +80 +E0 +80 +F0 +ENDCHAR +STARTCHAR ecaron +ENCODING 283 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +20 +00 +60 +B0 +C0 +70 +ENDCHAR +STARTCHAR Gcircumflex +ENCODING 284 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +50 +70 +80 +B0 +90 +60 +ENDCHAR +STARTCHAR gcircumflex +ENCODING 285 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 9 1 -2 +BITMAP +20 +50 +00 +60 +90 +90 +70 +10 +60 +ENDCHAR +STARTCHAR Gbreve +ENCODING 286 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +90 +60 +70 +80 +B0 +90 +60 +ENDCHAR +STARTCHAR gbreve +ENCODING 287 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 9 1 -2 +BITMAP +90 +60 +00 +60 +90 +90 +70 +10 +60 +ENDCHAR +STARTCHAR Gdotaccent +ENCODING 288 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +00 +70 +80 +B0 +90 +60 +ENDCHAR +STARTCHAR gdotaccent +ENCODING 289 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -2 +BITMAP +20 +00 +60 +90 +90 +70 +10 +60 +ENDCHAR +STARTCHAR Gcommaaccent +ENCODING 290 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -2 +BITMAP +60 +90 +80 +B0 +90 +60 +20 +40 +ENDCHAR +STARTCHAR gcommaaccent +ENCODING 291 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -2 +BITMAP +20 +40 +60 +90 +90 +70 +10 +60 +ENDCHAR +STARTCHAR Hcircumflex +ENCODING 292 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +50 +00 +90 +F0 +90 +90 +ENDCHAR +STARTCHAR hcircumflex +ENCODING 293 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +10 +A8 +80 +E0 +90 +90 +90 +ENDCHAR +STARTCHAR Hbar +ENCODING 294 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +50 +F8 +50 +70 +50 +50 +ENDCHAR +STARTCHAR hbar +ENCODING 295 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +40 +E0 +70 +48 +48 +48 +ENDCHAR +STARTCHAR Itilde +ENCODING 296 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +A0 +70 +20 +20 +20 +70 +ENDCHAR +STARTCHAR itilde +ENCODING 297 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +A0 +00 +60 +20 +20 +70 +ENDCHAR +STARTCHAR Imacron +ENCODING 298 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 0 +BITMAP +E0 +00 +E0 +40 +40 +40 +E0 +ENDCHAR +STARTCHAR imacron +ENCODING 299 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 1 0 +BITMAP +E0 +00 +C0 +40 +40 +E0 +ENDCHAR +STARTCHAR Ibreve +ENCODING 300 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +90 +60 +00 +70 +20 +20 +70 +ENDCHAR +STARTCHAR ibreve +ENCODING 301 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +90 +60 +00 +60 +20 +20 +70 +ENDCHAR +STARTCHAR Iogonek +ENCODING 302 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 8 1 -2 +BITMAP +E0 +40 +40 +40 +40 +E0 +40 +20 +ENDCHAR +STARTCHAR iogonek +ENCODING 303 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 8 1 -2 +BITMAP +40 +00 +C0 +40 +40 +E0 +40 +20 +ENDCHAR +STARTCHAR Idotaccent +ENCODING 304 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 0 +BITMAP +40 +00 +E0 +40 +40 +40 +E0 +ENDCHAR +STARTCHAR dotlessi +ENCODING 305 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 4 1 0 +BITMAP +C0 +40 +40 +E0 +ENDCHAR +STARTCHAR IJ +ENCODING 306 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +B8 +88 +88 +88 +A8 +90 +ENDCHAR +STARTCHAR ij +ENCODING 307 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -2 +BITMAP +88 +00 +98 +88 +88 +88 +28 +10 +ENDCHAR +STARTCHAR Jcircumflex +ENCODING 308 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +10 +28 +38 +10 +10 +90 +60 +ENDCHAR +STARTCHAR jcircumflex +ENCODING 309 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 9 1 -2 +BITMAP +20 +50 +00 +60 +20 +20 +20 +A0 +40 +ENDCHAR +STARTCHAR Kcommaaccent +ENCODING 310 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -2 +BITMAP +90 +A0 +C0 +A0 +90 +90 +40 +80 +ENDCHAR +STARTCHAR kcommaaccent +ENCODING 311 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -2 +BITMAP +80 +80 +A0 +C0 +A0 +90 +40 +80 +ENDCHAR +STARTCHAR kgreenlandic +ENCODING 312 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +B0 +C0 +A0 +90 +ENDCHAR +STARTCHAR Lacute +ENCODING 313 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +10 +20 +80 +80 +80 +80 +F0 +ENDCHAR +STARTCHAR lacute +ENCODING 314 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 0 +BITMAP +40 +80 +C0 +40 +40 +40 +E0 +ENDCHAR +STARTCHAR Lcommaaccent +ENCODING 315 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -2 +BITMAP +80 +80 +80 +80 +80 +F0 +20 +40 +ENDCHAR +STARTCHAR lcommaaccent +ENCODING 316 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 8 1 -2 +BITMAP +C0 +40 +40 +40 +40 +E0 +40 +80 +ENDCHAR +STARTCHAR Lcaron +ENCODING 317 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +20 +80 +80 +80 +80 +F0 +ENDCHAR +STARTCHAR lcaron +ENCODING 318 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 0 +BITMAP +A0 +40 +C0 +40 +40 +40 +E0 +ENDCHAR +STARTCHAR Ldot +ENCODING 319 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +80 +80 +A0 +80 +80 +F0 +ENDCHAR +STARTCHAR ldot +ENCODING 320 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +C0 +40 +50 +40 +40 +E0 +ENDCHAR +STARTCHAR Lslash +ENCODING 321 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +40 +40 +60 +C0 +40 +78 +ENDCHAR +STARTCHAR lslash +ENCODING 322 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 1 0 +BITMAP +C0 +40 +60 +C0 +40 +E0 +ENDCHAR +STARTCHAR Nacute +ENCODING 323 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +40 +90 +D0 +B0 +90 +90 +ENDCHAR +STARTCHAR nacute +ENCODING 324 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +40 +00 +E0 +90 +90 +90 +ENDCHAR +STARTCHAR Ncommaaccent +ENCODING 325 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -2 +BITMAP +90 +D0 +B0 +90 +90 +90 +40 +80 +ENDCHAR +STARTCHAR ncommaaccent +ENCODING 326 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 -2 +BITMAP +E0 +90 +90 +90 +40 +80 +ENDCHAR +STARTCHAR Ncaron +ENCODING 327 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +20 +90 +D0 +B0 +90 +90 +ENDCHAR +STARTCHAR ncaron +ENCODING 328 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +A0 +40 +00 +E0 +90 +90 +90 +ENDCHAR +STARTCHAR napostrophe +ENCODING 329 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +C0 +40 +B0 +28 +28 +28 +ENDCHAR +STARTCHAR Eng +ENCODING 330 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -2 +BITMAP +90 +D0 +B0 +90 +90 +90 +10 +20 +ENDCHAR +STARTCHAR eng +ENCODING 331 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 -2 +BITMAP +E0 +90 +90 +90 +10 +20 +ENDCHAR +STARTCHAR Omacron +ENCODING 332 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +F8 +00 +70 +88 +88 +88 +70 +ENDCHAR +STARTCHAR omacron +ENCODING 333 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +F0 +00 +60 +90 +90 +60 +ENDCHAR +STARTCHAR Obreve +ENCODING 334 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +88 +70 +70 +88 +88 +88 +70 +ENDCHAR +STARTCHAR obreve +ENCODING 335 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +90 +60 +00 +60 +90 +90 +60 +ENDCHAR +STARTCHAR Ohungarumlaut +ENCODING 336 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +48 +90 +70 +88 +88 +88 +70 +ENDCHAR +STARTCHAR ohungarumlaut +ENCODING 337 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +48 +90 +00 +60 +90 +90 +60 +ENDCHAR +STARTCHAR OE +ENCODING 338 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +78 +A0 +B0 +A0 +A0 +78 +ENDCHAR +STARTCHAR oe +ENCODING 339 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +50 +A8 +B0 +58 +ENDCHAR +STARTCHAR Racute +ENCODING 340 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +40 +E0 +90 +E0 +A0 +90 +ENDCHAR +STARTCHAR racute +ENCODING 341 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +40 +00 +A0 +D0 +80 +80 +ENDCHAR +STARTCHAR Rcommaaccent +ENCODING 342 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -2 +BITMAP +E0 +90 +90 +E0 +90 +90 +40 +80 +ENDCHAR +STARTCHAR rcommaaccent +ENCODING 343 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 -2 +BITMAP +A0 +D0 +80 +80 +40 +80 +ENDCHAR +STARTCHAR Rcaron +ENCODING 344 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +A0 +40 +E0 +90 +E0 +A0 +90 +ENDCHAR +STARTCHAR rcaron +ENCODING 345 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +A0 +40 +00 +A0 +D0 +80 +80 +ENDCHAR +STARTCHAR Sacute +ENCODING 346 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +40 +70 +80 +60 +10 +E0 +ENDCHAR +STARTCHAR sacute +ENCODING 347 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +40 +00 +70 +C0 +30 +E0 +ENDCHAR +STARTCHAR Scircumflex +ENCODING 348 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +50 +70 +80 +60 +10 +E0 +ENDCHAR +STARTCHAR scircumflex +ENCODING 349 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +50 +00 +70 +C0 +30 +E0 +ENDCHAR +STARTCHAR Scedilla +ENCODING 350 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -2 +BITMAP +60 +90 +40 +20 +90 +60 +20 +40 +ENDCHAR +STARTCHAR scedilla +ENCODING 351 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 -2 +BITMAP +70 +C0 +30 +E0 +20 +40 +ENDCHAR +STARTCHAR Scaron +ENCODING 352 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +20 +70 +80 +60 +10 +E0 +ENDCHAR +STARTCHAR scaron +ENCODING 353 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +20 +00 +70 +C0 +30 +E0 +ENDCHAR +STARTCHAR Tcommaaccent +ENCODING 354 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -2 +BITMAP +F8 +20 +20 +20 +20 +20 +10 +20 +ENDCHAR +STARTCHAR tcommaaccent +ENCODING 355 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -2 +BITMAP +40 +40 +E0 +40 +50 +20 +20 +40 +ENDCHAR +STARTCHAR Tcaron +ENCODING 356 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +50 +20 +F8 +20 +20 +20 +20 +ENDCHAR +STARTCHAR tcaron +ENCODING 357 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +20 +40 +E0 +40 +50 +20 +ENDCHAR +STARTCHAR Tbar +ENCODING 358 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +F8 +20 +20 +70 +20 +20 +ENDCHAR +STARTCHAR tbar +ENCODING 359 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +40 +40 +E0 +E0 +50 +20 +ENDCHAR +STARTCHAR Utilde +ENCODING 360 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +A0 +00 +90 +90 +90 +60 +ENDCHAR +STARTCHAR utilde +ENCODING 361 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +A0 +00 +90 +90 +90 +70 +ENDCHAR +STARTCHAR Umacron +ENCODING 362 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +F0 +00 +90 +90 +90 +90 +60 +ENDCHAR +STARTCHAR umacron +ENCODING 363 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +F0 +00 +90 +90 +90 +70 +ENDCHAR +STARTCHAR Ubreve +ENCODING 364 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +90 +60 +00 +90 +90 +90 +60 +ENDCHAR +STARTCHAR ubreve +ENCODING 365 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +90 +60 +00 +90 +90 +90 +70 +ENDCHAR +STARTCHAR Uring +ENCODING 366 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +60 +90 +60 +90 +90 +90 +60 +ENDCHAR +STARTCHAR uring +ENCODING 367 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +60 +90 +60 +90 +90 +90 +70 +ENDCHAR +STARTCHAR Uhungarumlaut +ENCODING 368 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +48 +90 +00 +90 +90 +90 +60 +ENDCHAR +STARTCHAR uhungarumlaut +ENCODING 369 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +48 +90 +00 +90 +90 +90 +70 +ENDCHAR +STARTCHAR Uogonek +ENCODING 370 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -2 +BITMAP +90 +90 +90 +90 +90 +60 +40 +20 +ENDCHAR +STARTCHAR uogonek +ENCODING 371 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 -2 +BITMAP +90 +90 +90 +70 +40 +20 +ENDCHAR +STARTCHAR Wcircumflex +ENCODING 372 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +20 +50 +00 +88 +A8 +D8 +88 +ENDCHAR +STARTCHAR wcircumflex +ENCODING 373 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +20 +50 +00 +88 +A8 +A8 +50 +ENDCHAR +STARTCHAR Ycircumflex +ENCODING 374 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +20 +50 +00 +88 +50 +20 +20 +ENDCHAR +STARTCHAR ycircumflex +ENCODING 375 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 9 1 -2 +BITMAP +20 +50 +00 +90 +90 +90 +70 +90 +60 +ENDCHAR +STARTCHAR Ydieresis +ENCODING 376 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +50 +00 +88 +50 +20 +20 +20 +ENDCHAR +STARTCHAR Zacute +ENCODING 377 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +40 +F0 +20 +40 +80 +F0 +ENDCHAR +STARTCHAR zacute +ENCODING 378 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +40 +00 +F0 +20 +40 +F0 +ENDCHAR +STARTCHAR Zdotaccent +ENCODING 379 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +00 +F0 +20 +40 +80 +F0 +ENDCHAR +STARTCHAR zdotaccent +ENCODING 380 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +20 +00 +F0 +20 +40 +F0 +ENDCHAR +STARTCHAR Zcaron +ENCODING 381 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +20 +F0 +20 +40 +80 +F0 +ENDCHAR +STARTCHAR zcaron +ENCODING 382 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +20 +00 +F0 +20 +40 +F0 +ENDCHAR +STARTCHAR longs +ENCODING 383 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +20 +50 +C0 +40 +40 +40 +ENDCHAR +STARTCHAR uni018F +ENCODING 399 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +60 +90 +10 +F0 +90 +60 +ENDCHAR +STARTCHAR florin +ENCODING 402 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -2 +BITMAP +20 +50 +40 +E0 +40 +40 +40 +80 +ENDCHAR +STARTCHAR Ohorn +ENCODING 416 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 6 0 0 +BITMAP +64 +94 +98 +90 +90 +60 +ENDCHAR +STARTCHAR ohorn +ENCODING 417 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 1 0 +BITMAP +68 +90 +90 +60 +ENDCHAR +STARTCHAR Uhorn +ENCODING 431 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 1 0 +BITMAP +A8 +A8 +B0 +A0 +A0 +40 +ENDCHAR +STARTCHAR uhorn +ENCODING 432 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 1 0 +BITMAP +A8 +B0 +A0 +60 +ENDCHAR +STARTCHAR uni01B5 +ENCODING 437 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +F0 +10 +F0 +40 +80 +F0 +ENDCHAR +STARTCHAR uni01B6 +ENCODING 438 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +F0 +F0 +40 +F0 +ENDCHAR +STARTCHAR uni01D1 +ENCODING 465 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +20 +60 +90 +90 +90 +60 +ENDCHAR +STARTCHAR uni01D2 +ENCODING 466 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +20 +00 +60 +90 +90 +60 +ENDCHAR +STARTCHAR Gcaron +ENCODING 486 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +20 +70 +80 +B0 +90 +60 +ENDCHAR +STARTCHAR gcaron +ENCODING 487 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 9 1 -2 +BITMAP +50 +20 +00 +60 +90 +90 +70 +10 +60 +ENDCHAR +STARTCHAR Aringacute +ENCODING 506 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 0 +BITMAP +20 +40 +A0 +40 +A0 +E0 +A0 +ENDCHAR +STARTCHAR aringacute +ENCODING 507 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +10 +20 +50 +70 +90 +90 +70 +ENDCHAR +STARTCHAR AEacute +ENCODING 508 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +10 +20 +78 +A0 +F0 +A0 +B8 +ENDCHAR +STARTCHAR aeacute +ENCODING 509 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +10 +20 +00 +70 +A8 +B0 +78 +ENDCHAR +STARTCHAR Oslashacute +ENCODING 510 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +10 +20 +70 +B0 +D0 +D0 +E0 +ENDCHAR +STARTCHAR oslashacute +ENCODING 511 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +40 +00 +70 +B0 +D0 +E0 +ENDCHAR +STARTCHAR Scommaaccent +ENCODING 536 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -2 +BITMAP +60 +90 +40 +20 +90 +60 +20 +40 +ENDCHAR +STARTCHAR scommaaccent +ENCODING 537 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 -2 +BITMAP +70 +C0 +30 +E0 +20 +40 +ENDCHAR +STARTCHAR Tcommaaccent +ENCODING 538 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -2 +BITMAP +F8 +20 +20 +20 +20 +20 +10 +20 +ENDCHAR +STARTCHAR tcommaaccent +ENCODING 539 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -2 +BITMAP +40 +40 +E0 +40 +50 +20 +20 +40 +ENDCHAR +STARTCHAR uni0258 +ENCODING 600 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +60 +D0 +30 +E0 +ENDCHAR +STARTCHAR uni0259 +ENCODING 601 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +E0 +30 +D0 +60 +ENDCHAR +STARTCHAR uni02BB +ENCODING 699 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 3 2 3 +BITMAP +40 +80 +C0 +ENDCHAR +STARTCHAR afii57929 +ENCODING 700 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 3 2 3 +BITMAP +C0 +40 +80 +ENDCHAR +STARTCHAR afii64937 +ENCODING 701 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 3 2 3 +BITMAP +C0 +80 +40 +ENDCHAR +STARTCHAR circumflex +ENCODING 710 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 2 1 5 +BITMAP +40 +A0 +ENDCHAR +STARTCHAR caron +ENCODING 711 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 2 1 5 +BITMAP +A0 +40 +ENDCHAR +STARTCHAR macron +ENCODING 713 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 1 1 5 +BITMAP +E0 +ENDCHAR +STARTCHAR breve +ENCODING 728 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 2 1 5 +BITMAP +90 +60 +ENDCHAR +STARTCHAR dotaccent +ENCODING 729 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 1 2 5 +BITMAP +80 +ENDCHAR +STARTCHAR ring +ENCODING 730 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 4 +BITMAP +40 +A0 +40 +ENDCHAR +STARTCHAR ogonek +ENCODING 731 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 2 2 -2 +BITMAP +80 +40 +ENDCHAR +STARTCHAR tilde +ENCODING 732 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 2 1 5 +BITMAP +50 +A0 +ENDCHAR +STARTCHAR hungarumlaut +ENCODING 733 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 2 0 5 +BITMAP +48 +90 +ENDCHAR +STARTCHAR gravecomb +ENCODING 768 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 2 1 5 +BITMAP +80 +40 +ENDCHAR +STARTCHAR acutecomb +ENCODING 769 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 2 2 5 +BITMAP +40 +80 +ENDCHAR +STARTCHAR uni0302 +ENCODING 770 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 2 1 5 +BITMAP +40 +A0 +ENDCHAR +STARTCHAR tildecomb +ENCODING 771 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 2 1 5 +BITMAP +50 +A0 +ENDCHAR +STARTCHAR uni0304 +ENCODING 772 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 1 1 6 +BITMAP +E0 +ENDCHAR +STARTCHAR uni0305 +ENCODING 773 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 1 0 6 +BITMAP +F8 +ENDCHAR +STARTCHAR uni0306 +ENCODING 774 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 2 0 5 +BITMAP +88 +70 +ENDCHAR +STARTCHAR uni0307 +ENCODING 775 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 1 2 6 +BITMAP +80 +ENDCHAR +STARTCHAR uni0308 +ENCODING 776 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 1 1 6 +BITMAP +A0 +ENDCHAR +STARTCHAR hookabovecomb +ENCODING 777 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 4 +BITMAP +C0 +20 +40 +ENDCHAR +STARTCHAR uni030A +ENCODING 778 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 4 +BITMAP +40 +A0 +40 +ENDCHAR +STARTCHAR uni030B +ENCODING 779 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 2 0 5 +BITMAP +48 +90 +ENDCHAR +STARTCHAR uni030C +ENCODING 780 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 2 1 5 +BITMAP +A0 +40 +ENDCHAR +STARTCHAR uni030D +ENCODING 781 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 2 2 5 +BITMAP +80 +80 +ENDCHAR +STARTCHAR uni030E +ENCODING 782 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 2 1 5 +BITMAP +A0 +A0 +ENDCHAR +STARTCHAR uni030F +ENCODING 783 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 2 0 5 +BITMAP +90 +48 +ENDCHAR +STARTCHAR uni0310 +ENCODING 784 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 2 0 5 +BITMAP +A8 +70 +ENDCHAR +STARTCHAR uni0311 +ENCODING 785 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 2 0 5 +BITMAP +70 +88 +ENDCHAR +STARTCHAR uni0312 +ENCODING 786 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 3 2 4 +BITMAP +40 +80 +C0 +ENDCHAR +STARTCHAR uni0313 +ENCODING 787 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 3 2 4 +BITMAP +C0 +40 +80 +ENDCHAR +STARTCHAR uni0314 +ENCODING 788 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 3 2 4 +BITMAP +C0 +80 +40 +ENDCHAR +STARTCHAR dotbelowcomb +ENCODING 803 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 1 2 -2 +BITMAP +80 +ENDCHAR +STARTCHAR uni0324 +ENCODING 804 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 1 1 -2 +BITMAP +A0 +ENDCHAR +STARTCHAR uni0374 +ENCODING 884 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 2 2 5 +BITMAP +40 +80 +ENDCHAR +STARTCHAR uni0375 +ENCODING 885 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 2 2 -2 +BITMAP +40 +80 +ENDCHAR +STARTCHAR uni037A +ENCODING 890 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 2 2 -2 +BITMAP +80 +C0 +ENDCHAR +STARTCHAR uni037E +ENCODING 894 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 7 2 -2 +BITMAP +C0 +C0 +00 +C0 +40 +40 +80 +ENDCHAR +STARTCHAR tonos +ENCODING 900 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 2 2 5 +BITMAP +80 +80 +ENDCHAR +STARTCHAR dieresistonos +ENCODING 901 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 2 0 5 +BITMAP +20 +A8 +ENDCHAR +STARTCHAR Alphatonos +ENCODING 902 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +80 +B0 +48 +48 +78 +48 +48 +ENDCHAR +STARTCHAR anoteleia +ENCODING 903 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 1 2 2 +BITMAP +80 +ENDCHAR +STARTCHAR Epsilontonos +ENCODING 904 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +80 +B8 +20 +30 +20 +20 +38 +ENDCHAR +STARTCHAR Etatonos +ENCODING 905 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +80 +A8 +28 +38 +28 +28 +28 +ENDCHAR +STARTCHAR Iotatonos +ENCODING 906 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +80 +B8 +10 +10 +10 +10 +38 +ENDCHAR +STARTCHAR Omicrontonos +ENCODING 908 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +80 +B0 +48 +48 +48 +48 +30 +ENDCHAR +STARTCHAR Upsilontonos +ENCODING 910 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +80 +A8 +28 +28 +10 +10 +10 +ENDCHAR +STARTCHAR Omegatonos +ENCODING 911 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +80 +B0 +48 +48 +48 +30 +78 +ENDCHAR +STARTCHAR iotadieresistonos +ENCODING 912 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +20 +A8 +00 +20 +20 +20 +10 +ENDCHAR +STARTCHAR Alpha +ENCODING 913 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +20 +50 +88 +F8 +88 +88 +ENDCHAR +STARTCHAR Beta +ENCODING 914 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +F0 +88 +F0 +88 +88 +F0 +ENDCHAR +STARTCHAR Gamma +ENCODING 915 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +F0 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR Delta +ENCODING 916 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +20 +20 +50 +50 +88 +F8 +ENDCHAR +STARTCHAR Epsilon +ENCODING 917 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +F0 +80 +E0 +80 +80 +F0 +ENDCHAR +STARTCHAR Zeta +ENCODING 918 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +F0 +10 +20 +40 +80 +F0 +ENDCHAR +STARTCHAR Eta +ENCODING 919 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +90 +90 +F0 +90 +90 +90 +ENDCHAR +STARTCHAR Theta +ENCODING 920 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +88 +F8 +88 +88 +70 +ENDCHAR +STARTCHAR Iota +ENCODING 921 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 1 0 +BITMAP +E0 +40 +40 +40 +40 +E0 +ENDCHAR +STARTCHAR Kappa +ENCODING 922 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +90 +A0 +C0 +A0 +90 +90 +ENDCHAR +STARTCHAR Lambda +ENCODING 923 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +20 +20 +50 +50 +88 +88 +ENDCHAR +STARTCHAR Mu +ENCODING 924 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +88 +D8 +A8 +A8 +88 +88 +ENDCHAR +STARTCHAR Nu +ENCODING 925 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +90 +D0 +B0 +90 +90 +90 +ENDCHAR +STARTCHAR Xi +ENCODING 926 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +F0 +00 +60 +00 +00 +F0 +ENDCHAR +STARTCHAR Omicron +ENCODING 927 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR Pi +ENCODING 928 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +F0 +90 +90 +90 +90 +90 +ENDCHAR +STARTCHAR Rho +ENCODING 929 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +E0 +90 +90 +E0 +80 +80 +ENDCHAR +STARTCHAR Sigma +ENCODING 931 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +F0 +80 +40 +40 +80 +F0 +ENDCHAR +STARTCHAR Tau +ENCODING 932 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +F8 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR Upsilon +ENCODING 933 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +88 +88 +50 +20 +20 +20 +ENDCHAR +STARTCHAR Phi +ENCODING 934 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +20 +70 +A8 +A8 +70 +20 +ENDCHAR +STARTCHAR Chi +ENCODING 935 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +88 +50 +20 +20 +50 +88 +ENDCHAR +STARTCHAR Psi +ENCODING 936 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +A8 +A8 +A8 +70 +20 +20 +ENDCHAR +STARTCHAR Omega +ENCODING 937 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +88 +88 +88 +50 +D8 +ENDCHAR +STARTCHAR Iotadieresis +ENCODING 938 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 0 +BITMAP +A0 +00 +E0 +40 +40 +40 +E0 +ENDCHAR +STARTCHAR Upsilondieresis +ENCODING 939 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +50 +00 +88 +50 +20 +20 +20 +ENDCHAR +STARTCHAR alphatonos +ENCODING 940 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +10 +20 +00 +70 +90 +90 +70 +ENDCHAR +STARTCHAR epsilontonos +ENCODING 941 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +10 +20 +00 +60 +B0 +C0 +70 +ENDCHAR +STARTCHAR etatonos +ENCODING 942 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 9 0 -2 +BITMAP +10 +20 +00 +B0 +C8 +88 +88 +08 +08 +ENDCHAR +STARTCHAR iotatonos +ENCODING 943 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 0 +BITMAP +40 +80 +00 +80 +80 +A0 +40 +ENDCHAR +STARTCHAR upsilondieresistonos +ENCODING 944 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +20 +A8 +00 +88 +88 +88 +70 +ENDCHAR +STARTCHAR alpha +ENCODING 945 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +70 +90 +90 +70 +ENDCHAR +STARTCHAR beta +ENCODING 946 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -2 +BITMAP +60 +90 +E0 +90 +90 +E0 +80 +80 +ENDCHAR +STARTCHAR gamma +ENCODING 947 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 -2 +BITMAP +88 +88 +50 +50 +20 +20 +ENDCHAR +STARTCHAR delta +ENCODING 948 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +80 +70 +88 +88 +70 +ENDCHAR +STARTCHAR epsilon +ENCODING 949 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +60 +B0 +C0 +70 +ENDCHAR +STARTCHAR zeta +ENCODING 950 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +F8 +20 +40 +40 +30 +08 +30 +ENDCHAR +STARTCHAR eta +ENCODING 951 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 -2 +BITMAP +B0 +C8 +88 +88 +08 +08 +ENDCHAR +STARTCHAR theta +ENCODING 952 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +60 +90 +F0 +90 +90 +60 +ENDCHAR +STARTCHAR iota +ENCODING 953 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 4 1 0 +BITMAP +80 +80 +A0 +40 +ENDCHAR +STARTCHAR kappa +ENCODING 954 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +90 +A0 +C0 +B0 +ENDCHAR +STARTCHAR lambda +ENCODING 955 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +88 +08 +68 +98 +88 +ENDCHAR +STARTCHAR mu +ENCODING 956 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 -2 +BITMAP +88 +88 +98 +E8 +80 +80 +ENDCHAR +STARTCHAR nu +ENCODING 957 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +88 +88 +50 +20 +ENDCHAR +STARTCHAR xi +ENCODING 958 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -2 +BITMAP +F8 +20 +40 +70 +80 +70 +08 +10 +ENDCHAR +STARTCHAR omicron +ENCODING 959 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +60 +90 +90 +60 +ENDCHAR +STARTCHAR pi +ENCODING 960 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +F8 +50 +50 +50 +ENDCHAR +STARTCHAR rho +ENCODING 961 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 -2 +BITMAP +70 +88 +88 +F0 +80 +80 +ENDCHAR +STARTCHAR sigma1 +ENCODING 962 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 -2 +BITMAP +70 +88 +80 +70 +08 +30 +ENDCHAR +STARTCHAR sigma +ENCODING 963 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +78 +90 +88 +70 +ENDCHAR +STARTCHAR tau +ENCODING 964 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +F0 +40 +50 +20 +ENDCHAR +STARTCHAR upsilon +ENCODING 965 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +88 +88 +88 +70 +ENDCHAR +STARTCHAR phi +ENCODING 966 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 -2 +BITMAP +90 +A8 +A8 +70 +20 +20 +ENDCHAR +STARTCHAR chi +ENCODING 967 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 -2 +BITMAP +88 +50 +20 +50 +88 +88 +ENDCHAR +STARTCHAR psi +ENCODING 968 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 -2 +BITMAP +A8 +A8 +A8 +70 +20 +20 +ENDCHAR +STARTCHAR omega +ENCODING 969 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +50 +88 +A8 +50 +ENDCHAR +STARTCHAR iotadieresis +ENCODING 970 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +A0 +00 +40 +40 +50 +20 +ENDCHAR +STARTCHAR upsilondieresis +ENCODING 971 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +50 +00 +88 +88 +88 +70 +ENDCHAR +STARTCHAR omicrontonos +ENCODING 972 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +10 +20 +00 +70 +88 +88 +70 +ENDCHAR +STARTCHAR upsilontonos +ENCODING 973 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +10 +20 +00 +88 +88 +88 +70 +ENDCHAR +STARTCHAR omegatonos +ENCODING 974 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +10 +20 +00 +50 +88 +A8 +50 +ENDCHAR +STARTCHAR uni03D0 +ENCODING 976 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +60 +90 +90 +F0 +88 +70 +ENDCHAR +STARTCHAR theta1 +ENCODING 977 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +20 +50 +38 +D0 +50 +20 +ENDCHAR +STARTCHAR Upsilon1 +ENCODING 978 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +90 +A8 +40 +40 +40 +40 +ENDCHAR +STARTCHAR uni03D3 +ENCODING 979 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +D0 +28 +60 +A0 +20 +20 +ENDCHAR +STARTCHAR uni03D4 +ENCODING 980 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +A0 +00 +90 +A8 +40 +40 +40 +ENDCHAR +STARTCHAR phi1 +ENCODING 981 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -2 +BITMAP +20 +20 +70 +A8 +A8 +70 +20 +20 +ENDCHAR +STARTCHAR omega1 +ENCODING 982 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +F8 +88 +A8 +50 +ENDCHAR +STARTCHAR uni03D7 +ENCODING 983 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 9 0 -2 +BITMAP +10 +20 +00 +88 +48 +70 +88 +08 +30 +ENDCHAR +STARTCHAR uni03DA +ENCODING 986 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -2 +BITMAP +30 +48 +80 +80 +80 +70 +08 +10 +ENDCHAR +STARTCHAR uni03DB +ENCODING 987 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -2 +BITMAP +08 +70 +80 +80 +70 +08 +30 +ENDCHAR +STARTCHAR uni03DC +ENCODING 988 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +F8 +80 +80 +E0 +80 +80 +ENDCHAR +STARTCHAR uni03DD +ENCODING 989 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 -2 +BITMAP +F0 +80 +80 +E0 +80 +80 +ENDCHAR +STARTCHAR uni03DE +ENCODING 990 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +80 +88 +98 +A8 +C8 +08 +ENDCHAR +STARTCHAR uni03DF +ENCODING 991 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -2 +BITMAP +20 +40 +80 +F8 +08 +10 +20 +20 +ENDCHAR +STARTCHAR uni03E0 +ENCODING 992 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +20 +50 +50 +98 +A8 +A8 +ENDCHAR +STARTCHAR uni03E1 +ENCODING 993 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -2 +BITMAP +E0 +10 +30 +48 +18 +28 +08 +08 +ENDCHAR +STARTCHAR uni03E2 +ENCODING 994 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +A8 +A8 +A8 +A8 +78 +08 +F0 +ENDCHAR +STARTCHAR uni03E3 +ENCODING 995 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 -1 +BITMAP +A8 +A8 +78 +08 +F0 +ENDCHAR +STARTCHAR uni03E4 +ENCODING 996 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +48 +A8 +88 +78 +08 +08 +ENDCHAR +STARTCHAR uni03E5 +ENCODING 997 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +50 +90 +70 +10 +ENDCHAR +STARTCHAR uni03E6 +ENCODING 998 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +80 +80 +B0 +C8 +88 +08 +F0 +ENDCHAR +STARTCHAR uni03E7 +ENCODING 999 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +20 +70 +A8 +48 +08 +F0 +ENDCHAR +STARTCHAR uni03E8 +ENCODING 1000 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +88 +08 +70 +80 +78 +ENDCHAR +STARTCHAR uni03E9 +ENCODING 1001 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +70 +88 +70 +80 +78 +ENDCHAR +STARTCHAR uni03EA +ENCODING 1002 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +50 +A8 +20 +50 +88 +F8 +ENDCHAR +STARTCHAR uni03EB +ENCODING 1003 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +50 +A8 +20 +50 +70 +ENDCHAR +STARTCHAR uni03EC +ENCODING 1004 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +08 +70 +80 +F0 +88 +70 +ENDCHAR +STARTCHAR uni03ED +ENCODING 1005 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +08 +70 +80 +D8 +70 +ENDCHAR +STARTCHAR uni03EE +ENCODING 1006 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +20 +F8 +A8 +20 +70 +ENDCHAR +STARTCHAR uni03EF +ENCODING 1007 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -2 +BITMAP +20 +30 +20 +F8 +A0 +20 +60 +20 +ENDCHAR +STARTCHAR uni03F0 +ENCODING 1008 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +88 +48 +70 +88 +ENDCHAR +STARTCHAR uni03F1 +ENCODING 1009 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 -2 +BITMAP +70 +88 +88 +F0 +80 +78 +ENDCHAR +STARTCHAR uni03F2 +ENCODING 1010 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +70 +88 +80 +78 +ENDCHAR +STARTCHAR uni03F3 +ENCODING 1011 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -2 +BITMAP +10 +00 +30 +10 +10 +90 +90 +60 +ENDCHAR +STARTCHAR uni03F4 +ENCODING 1012 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +88 +F8 +88 +88 +70 +ENDCHAR +STARTCHAR uni03F5 +ENCODING 1013 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +70 +E0 +80 +70 +ENDCHAR +STARTCHAR uni0400 +ENCODING 1024 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +40 +20 +F0 +80 +E0 +80 +F0 +ENDCHAR +STARTCHAR afii10023 +ENCODING 1025 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +50 +00 +F0 +80 +E0 +80 +F0 +ENDCHAR +STARTCHAR afii10051 +ENCODING 1026 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -2 +BITMAP +F8 +20 +30 +28 +28 +28 +08 +10 +ENDCHAR +STARTCHAR afii10052 +ENCODING 1027 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +40 +F0 +80 +80 +80 +80 +ENDCHAR +STARTCHAR afii10053 +ENCODING 1028 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +88 +E0 +80 +88 +70 +ENDCHAR +STARTCHAR afii10054 +ENCODING 1029 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +60 +90 +40 +20 +90 +60 +ENDCHAR +STARTCHAR afii10055 +ENCODING 1030 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 1 0 +BITMAP +E0 +40 +40 +40 +40 +E0 +ENDCHAR +STARTCHAR afii10056 +ENCODING 1031 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 0 +BITMAP +A0 +00 +E0 +40 +40 +40 +E0 +ENDCHAR +STARTCHAR afii10057 +ENCODING 1032 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +38 +10 +10 +10 +90 +60 +ENDCHAR +STARTCHAR afii10058 +ENCODING 1033 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +60 +A0 +B0 +A8 +A8 +B0 +ENDCHAR +STARTCHAR afii10059 +ENCODING 1034 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +A0 +A0 +F0 +A8 +A8 +B0 +ENDCHAR +STARTCHAR afii10060 +ENCODING 1035 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +F8 +20 +30 +28 +28 +28 +ENDCHAR +STARTCHAR afii10061 +ENCODING 1036 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +10 +20 +90 +A0 +C0 +A0 +90 +ENDCHAR +STARTCHAR uni040D +ENCODING 1037 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +40 +20 +88 +98 +A8 +C8 +88 +ENDCHAR +STARTCHAR afii10062 +ENCODING 1038 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +48 +30 +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR afii10145 +ENCODING 1039 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -2 +BITMAP +88 +88 +88 +88 +88 +F8 +20 +20 +ENDCHAR +STARTCHAR afii10017 +ENCODING 1040 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +20 +50 +88 +F8 +88 +88 +ENDCHAR +STARTCHAR afii10018 +ENCODING 1041 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +F0 +80 +F0 +88 +88 +F0 +ENDCHAR +STARTCHAR afii10019 +ENCODING 1042 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +F0 +88 +F0 +88 +88 +F0 +ENDCHAR +STARTCHAR afii10020 +ENCODING 1043 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +F0 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR afii10021 +ENCODING 1044 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +30 +50 +50 +50 +50 +F8 +88 +ENDCHAR +STARTCHAR afii10022 +ENCODING 1045 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +F0 +80 +E0 +80 +80 +F0 +ENDCHAR +STARTCHAR afii10024 +ENCODING 1046 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +A8 +A8 +70 +A8 +A8 +A8 +ENDCHAR +STARTCHAR afii10025 +ENCODING 1047 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +88 +30 +08 +88 +70 +ENDCHAR +STARTCHAR afii10026 +ENCODING 1048 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +90 +B0 +D0 +90 +90 +90 +ENDCHAR +STARTCHAR afii10027 +ENCODING 1049 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +90 +60 +90 +B0 +D0 +90 +90 +ENDCHAR +STARTCHAR afii10028 +ENCODING 1050 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +90 +A0 +C0 +A0 +90 +90 +ENDCHAR +STARTCHAR afii10029 +ENCODING 1051 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +38 +48 +48 +48 +48 +88 +ENDCHAR +STARTCHAR afii10030 +ENCODING 1052 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +88 +D8 +A8 +A8 +88 +88 +ENDCHAR +STARTCHAR afii10031 +ENCODING 1053 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +90 +90 +F0 +90 +90 +90 +ENDCHAR +STARTCHAR afii10032 +ENCODING 1054 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR afii10033 +ENCODING 1055 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +F8 +88 +88 +88 +88 +88 +ENDCHAR +STARTCHAR afii10034 +ENCODING 1056 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +E0 +90 +90 +E0 +80 +80 +ENDCHAR +STARTCHAR afii10035 +ENCODING 1057 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +60 +90 +80 +80 +90 +60 +ENDCHAR +STARTCHAR afii10036 +ENCODING 1058 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +F8 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR afii10037 +ENCODING 1059 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +88 +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR afii10038 +ENCODING 1060 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +20 +70 +A8 +A8 +70 +20 +ENDCHAR +STARTCHAR afii10039 +ENCODING 1061 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +88 +50 +20 +20 +50 +88 +ENDCHAR +STARTCHAR afii10040 +ENCODING 1062 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -2 +BITMAP +90 +90 +90 +90 +90 +F8 +08 +10 +ENDCHAR +STARTCHAR afii10041 +ENCODING 1063 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +88 +88 +88 +78 +08 +08 +ENDCHAR +STARTCHAR afii10042 +ENCODING 1064 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +A8 +A8 +A8 +A8 +A8 +F8 +ENDCHAR +STARTCHAR afii10043 +ENCODING 1065 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -2 +BITMAP +A8 +A8 +A8 +A8 +A8 +F8 +08 +10 +ENDCHAR +STARTCHAR afii10044 +ENCODING 1066 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +C0 +40 +70 +48 +48 +70 +ENDCHAR +STARTCHAR afii10045 +ENCODING 1067 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +88 +88 +E8 +98 +98 +E8 +ENDCHAR +STARTCHAR afii10046 +ENCODING 1068 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +80 +80 +E0 +90 +90 +E0 +ENDCHAR +STARTCHAR afii10047 +ENCODING 1069 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +88 +38 +08 +88 +70 +ENDCHAR +STARTCHAR afii10048 +ENCODING 1070 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +90 +A8 +E8 +E8 +A8 +90 +ENDCHAR +STARTCHAR afii10049 +ENCODING 1071 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +70 +90 +90 +70 +90 +90 +ENDCHAR +STARTCHAR afii10065 +ENCODING 1072 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +70 +90 +90 +78 +ENDCHAR +STARTCHAR afii10066 +ENCODING 1073 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +10 +60 +80 +E0 +90 +90 +60 +ENDCHAR +STARTCHAR afii10067 +ENCODING 1074 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +C0 +A0 +D0 +E0 +ENDCHAR +STARTCHAR afii10068 +ENCODING 1075 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +F0 +80 +80 +80 +ENDCHAR +STARTCHAR afii10069 +ENCODING 1076 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 -1 +BITMAP +30 +50 +50 +F8 +88 +ENDCHAR +STARTCHAR afii10070 +ENCODING 1077 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 0 0 +BITMAP +60 +90 +E0 +70 +ENDCHAR +STARTCHAR afii10072 +ENCODING 1078 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +A8 +70 +70 +A8 +ENDCHAR +STARTCHAR afii10073 +ENCODING 1079 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +60 +50 +30 +E0 +ENDCHAR +STARTCHAR afii10074 +ENCODING 1080 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +88 +98 +A8 +C8 +ENDCHAR +STARTCHAR afii10075 +ENCODING 1081 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +88 +70 +00 +88 +98 +A8 +C8 +ENDCHAR +STARTCHAR afii10076 +ENCODING 1082 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +90 +A0 +E0 +90 +ENDCHAR +STARTCHAR afii10077 +ENCODING 1083 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +38 +48 +48 +88 +ENDCHAR +STARTCHAR afii10078 +ENCODING 1084 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +88 +D8 +A8 +88 +ENDCHAR +STARTCHAR afii10079 +ENCODING 1085 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +88 +F8 +88 +88 +ENDCHAR +STARTCHAR afii10080 +ENCODING 1086 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +70 +88 +88 +70 +ENDCHAR +STARTCHAR afii10081 +ENCODING 1087 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +F8 +88 +88 +88 +ENDCHAR +STARTCHAR afii10082 +ENCODING 1088 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 -2 +BITMAP +F0 +88 +88 +F0 +80 +80 +ENDCHAR +STARTCHAR afii10083 +ENCODING 1089 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +70 +88 +80 +78 +ENDCHAR +STARTCHAR afii10084 +ENCODING 1090 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +F8 +20 +20 +20 +ENDCHAR +STARTCHAR afii10085 +ENCODING 1091 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 -2 +BITMAP +88 +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR afii10086 +ENCODING 1092 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -2 +BITMAP +20 +20 +70 +A8 +A8 +70 +20 +20 +ENDCHAR +STARTCHAR afii10087 +ENCODING 1093 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +90 +60 +60 +90 +ENDCHAR +STARTCHAR afii10088 +ENCODING 1094 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 -2 +BITMAP +90 +90 +90 +F8 +08 +10 +ENDCHAR +STARTCHAR afii10089 +ENCODING 1095 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +88 +88 +78 +08 +ENDCHAR +STARTCHAR afii10090 +ENCODING 1096 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +A8 +A8 +A8 +F8 +ENDCHAR +STARTCHAR afii10091 +ENCODING 1097 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 -2 +BITMAP +A8 +A8 +A8 +F8 +08 +10 +ENDCHAR +STARTCHAR afii10092 +ENCODING 1098 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +C0 +70 +48 +70 +ENDCHAR +STARTCHAR afii10093 +ENCODING 1099 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +88 +E8 +98 +E8 +ENDCHAR +STARTCHAR afii10094 +ENCODING 1100 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +80 +E0 +90 +E0 +ENDCHAR +STARTCHAR afii10095 +ENCODING 1101 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 0 0 +BITMAP +E0 +50 +30 +E0 +ENDCHAR +STARTCHAR afii10096 +ENCODING 1102 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +90 +E8 +E8 +90 +ENDCHAR +STARTCHAR afii10097 +ENCODING 1103 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 0 0 +BITMAP +70 +90 +70 +90 +ENDCHAR +STARTCHAR uni0450 +ENCODING 1104 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +40 +20 +00 +60 +90 +E0 +70 +ENDCHAR +STARTCHAR afii10071 +ENCODING 1105 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +A0 +00 +60 +90 +E0 +70 +ENDCHAR +STARTCHAR afii10099 +ENCODING 1106 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -2 +BITMAP +40 +E0 +40 +70 +48 +48 +08 +10 +ENDCHAR +STARTCHAR afii10100 +ENCODING 1107 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +40 +00 +F0 +80 +80 +80 +ENDCHAR +STARTCHAR afii10101 +ENCODING 1108 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +70 +A0 +C0 +70 +ENDCHAR +STARTCHAR afii10102 +ENCODING 1109 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +70 +C0 +30 +E0 +ENDCHAR +STARTCHAR afii10103 +ENCODING 1110 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 1 0 +BITMAP +40 +00 +C0 +40 +40 +E0 +ENDCHAR +STARTCHAR afii10104 +ENCODING 1111 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 1 0 +BITMAP +A0 +00 +C0 +40 +40 +E0 +ENDCHAR +STARTCHAR afii10105 +ENCODING 1112 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -2 +BITMAP +10 +00 +30 +10 +10 +10 +90 +60 +ENDCHAR +STARTCHAR afii10106 +ENCODING 1113 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +60 +B0 +A8 +B0 +ENDCHAR +STARTCHAR afii10107 +ENCODING 1114 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +A0 +F0 +A8 +B0 +ENDCHAR +STARTCHAR afii10108 +ENCODING 1115 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +40 +E0 +40 +70 +48 +48 +ENDCHAR +STARTCHAR afii10109 +ENCODING 1116 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +40 +00 +90 +A0 +E0 +90 +ENDCHAR +STARTCHAR uni045D +ENCODING 1117 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +40 +20 +00 +88 +98 +A8 +C8 +ENDCHAR +STARTCHAR afii10110 +ENCODING 1118 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -2 +BITMAP +48 +30 +00 +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR afii10193 +ENCODING 1119 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 -2 +BITMAP +88 +88 +88 +F8 +20 +20 +ENDCHAR +STARTCHAR afii10146 +ENCODING 1122 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +40 +E0 +40 +70 +48 +48 +70 +ENDCHAR +STARTCHAR afii10194 +ENCODING 1123 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +40 +40 +E0 +70 +48 +70 +ENDCHAR +STARTCHAR uni0470 +ENCODING 1136 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +A8 +A8 +A8 +70 +20 +20 +ENDCHAR +STARTCHAR uni0471 +ENCODING 1137 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +A8 +A8 +70 +20 +ENDCHAR +STARTCHAR afii10147 +ENCODING 1138 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +88 +F8 +88 +88 +70 +ENDCHAR +STARTCHAR afii10195 +ENCODING 1139 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +70 +A8 +D8 +70 +ENDCHAR +STARTCHAR afii10148 +ENCODING 1140 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +80 +90 +B0 +E0 +40 +40 +ENDCHAR +STARTCHAR afii10196 +ENCODING 1141 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +80 +B0 +60 +40 +ENDCHAR +STARTCHAR afii10050 +ENCODING 1168 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +10 +F0 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR afii10098 +ENCODING 1169 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 5 1 0 +BITMAP +10 +F0 +80 +80 +80 +ENDCHAR +STARTCHAR uni0492 +ENCODING 1170 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +78 +40 +F0 +40 +40 +40 +ENDCHAR +STARTCHAR uni0493 +ENCODING 1171 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +78 +40 +E0 +40 +ENDCHAR +STARTCHAR uni0496 +ENCODING 1174 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 8 0 -2 +BITMAP +A8 +A8 +70 +A8 +A8 +AC +04 +04 +ENDCHAR +STARTCHAR uni0497 +ENCODING 1175 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 6 0 -2 +BITMAP +A8 +70 +70 +A8 +04 +04 +ENDCHAR +STARTCHAR uni049A +ENCODING 1178 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 1 -2 +BITMAP +90 +A0 +C0 +A0 +90 +90 +08 +08 +ENDCHAR +STARTCHAR uni049B +ENCODING 1179 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 1 -2 +BITMAP +90 +A0 +E0 +90 +08 +08 +ENDCHAR +STARTCHAR uni04AE +ENCODING 1198 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +88 +88 +50 +20 +20 +20 +ENDCHAR +STARTCHAR uni04AF +ENCODING 1199 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 -2 +BITMAP +88 +88 +50 +20 +20 +20 +ENDCHAR +STARTCHAR uni04B0 +ENCODING 1200 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +88 +88 +50 +F8 +20 +20 +ENDCHAR +STARTCHAR uni04B1 +ENCODING 1201 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 -2 +BITMAP +88 +88 +50 +F8 +20 +20 +ENDCHAR +STARTCHAR uni04B2 +ENCODING 1202 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 8 0 -2 +BITMAP +88 +50 +20 +20 +50 +88 +04 +04 +ENDCHAR +STARTCHAR uni04B3 +ENCODING 1203 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 1 -2 +BITMAP +90 +60 +60 +90 +08 +08 +ENDCHAR +STARTCHAR uni04BA +ENCODING 1210 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +80 +80 +F0 +88 +88 +88 +ENDCHAR +STARTCHAR uni04BB +ENCODING 1211 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +80 +80 +E0 +90 +90 +90 +ENDCHAR +STARTCHAR uni04D8 +ENCODING 1240 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +60 +90 +10 +F0 +90 +60 +ENDCHAR +STARTCHAR afii10846 +ENCODING 1241 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +E0 +30 +D0 +60 +ENDCHAR +STARTCHAR uni04E2 +ENCODING 1250 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 0 +BITMAP +E0 +00 +E0 +40 +40 +40 +E0 +ENDCHAR +STARTCHAR uni04E3 +ENCODING 1251 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 1 0 +BITMAP +E0 +00 +C0 +40 +40 +E0 +ENDCHAR +STARTCHAR uni04E8 +ENCODING 1256 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +88 +F8 +88 +88 +70 +ENDCHAR +STARTCHAR uni04E9 +ENCODING 1257 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +60 +F0 +90 +60 +ENDCHAR +STARTCHAR uni04EE +ENCODING 1262 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +F0 +00 +90 +90 +90 +90 +60 +ENDCHAR +STARTCHAR uni04EF +ENCODING 1263 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +F0 +00 +90 +90 +90 +70 +ENDCHAR +STARTCHAR afii57664 +ENCODING 1488 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +90 +48 +B0 +88 +ENDCHAR +STARTCHAR afii57665 +ENCODING 1489 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +F0 +10 +10 +F8 +ENDCHAR +STARTCHAR afii57666 +ENCODING 1490 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 4 1 0 +BITMAP +80 +40 +60 +A0 +ENDCHAR +STARTCHAR afii57667 +ENCODING 1491 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +F8 +10 +10 +10 +ENDCHAR +STARTCHAR afii57668 +ENCODING 1492 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +F8 +08 +88 +88 +ENDCHAR +STARTCHAR afii57669 +ENCODING 1493 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 4 2 0 +BITMAP +C0 +40 +40 +40 +ENDCHAR +STARTCHAR afii57670 +ENCODING 1494 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +F8 +20 +10 +10 +ENDCHAR +STARTCHAR afii57671 +ENCODING 1495 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +F8 +48 +48 +48 +ENDCHAR +STARTCHAR afii57672 +ENCODING 1496 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +98 +A8 +88 +F8 +ENDCHAR +STARTCHAR afii57673 +ENCODING 1497 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 2 2 2 +BITMAP +C0 +40 +ENDCHAR +STARTCHAR afii57674 +ENCODING 1498 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 -2 +BITMAP +F8 +08 +08 +08 +08 +08 +ENDCHAR +STARTCHAR afii57675 +ENCODING 1499 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +F8 +08 +08 +F0 +ENDCHAR +STARTCHAR afii57676 +ENCODING 1500 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +80 +80 +F8 +08 +10 +60 +ENDCHAR +STARTCHAR afii57677 +ENCODING 1501 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +F8 +48 +48 +78 +ENDCHAR +STARTCHAR afii57678 +ENCODING 1502 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +90 +A8 +48 +98 +ENDCHAR +STARTCHAR afii57679 +ENCODING 1503 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 6 2 -2 +BITMAP +C0 +40 +40 +40 +40 +40 +ENDCHAR +STARTCHAR afii57680 +ENCODING 1504 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +30 +10 +10 +F0 +ENDCHAR +STARTCHAR afii57681 +ENCODING 1505 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +F0 +50 +50 +60 +ENDCHAR +STARTCHAR afii57682 +ENCODING 1506 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +D8 +48 +50 +E0 +ENDCHAR +STARTCHAR afii57683 +ENCODING 1507 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 -2 +BITMAP +F8 +48 +48 +08 +08 +08 +ENDCHAR +STARTCHAR afii57684 +ENCODING 1508 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +F8 +48 +08 +F0 +ENDCHAR +STARTCHAR afii57685 +ENCODING 1509 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 -2 +BITMAP +90 +48 +50 +60 +40 +40 +ENDCHAR +STARTCHAR afii57686 +ENCODING 1510 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +90 +48 +30 +F8 +ENDCHAR +STARTCHAR afii57687 +ENCODING 1511 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 -2 +BITMAP +F8 +08 +88 +B0 +80 +80 +ENDCHAR +STARTCHAR afii57688 +ENCODING 1512 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +F0 +08 +08 +08 +ENDCHAR +STARTCHAR afii57689 +ENCODING 1513 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +A8 +E8 +88 +F0 +ENDCHAR +STARTCHAR afii57690 +ENCODING 1514 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +F8 +48 +48 +C8 +ENDCHAR +STARTCHAR afii57716 +ENCODING 1520 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +D8 +48 +48 +48 +ENDCHAR +STARTCHAR afii57717 +ENCODING 1521 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +D8 +48 +08 +08 +ENDCHAR +STARTCHAR afii57718 +ENCODING 1522 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 2 0 2 +BITMAP +D8 +48 +ENDCHAR +STARTCHAR uni05F3 +ENCODING 1523 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 2 2 2 +BITMAP +40 +80 +ENDCHAR +STARTCHAR uni05F4 +ENCODING 1524 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 2 0 2 +BITMAP +48 +90 +ENDCHAR +STARTCHAR uni1E02 +ENCODING 7682 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +20 +00 +F0 +88 +F0 +88 +F0 +ENDCHAR +STARTCHAR uni1E03 +ENCODING 7683 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +80 +80 +E0 +90 +90 +E0 +ENDCHAR +STARTCHAR uni1E0A +ENCODING 7690 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +40 +00 +E0 +90 +90 +90 +E0 +ENDCHAR +STARTCHAR uni1E0B +ENCODING 7691 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +40 +10 +10 +70 +90 +90 +70 +ENDCHAR +STARTCHAR uni1E1E +ENCODING 7710 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +40 +00 +F0 +80 +E0 +80 +80 +ENDCHAR +STARTCHAR uni1E1F +ENCODING 7711 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +40 +00 +20 +50 +E0 +40 +40 +ENDCHAR +STARTCHAR uni1E40 +ENCODING 7744 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +20 +88 +D8 +A8 +A8 +88 +88 +ENDCHAR +STARTCHAR uni1E41 +ENCODING 7745 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +20 +00 +D0 +A8 +A8 +88 +ENDCHAR +STARTCHAR uni1E56 +ENCODING 7766 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +40 +00 +E0 +90 +E0 +80 +80 +ENDCHAR +STARTCHAR uni1E57 +ENCODING 7767 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -2 +BITMAP +40 +00 +E0 +90 +90 +E0 +80 +80 +ENDCHAR +STARTCHAR uni1E60 +ENCODING 7776 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +20 +00 +70 +80 +60 +10 +E0 +ENDCHAR +STARTCHAR uni1E61 +ENCODING 7777 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +20 +00 +70 +C0 +30 +E0 +ENDCHAR +STARTCHAR uni1E6A +ENCODING 7786 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +20 +00 +F8 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni1E6B +ENCODING 7787 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +40 +00 +40 +E0 +40 +50 +20 +ENDCHAR +STARTCHAR Wgrave +ENCODING 7808 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +40 +20 +88 +88 +A8 +D8 +88 +ENDCHAR +STARTCHAR wgrave +ENCODING 7809 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +40 +20 +00 +88 +A8 +A8 +50 +ENDCHAR +STARTCHAR Wacute +ENCODING 7810 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +10 +20 +88 +88 +A8 +D8 +88 +ENDCHAR +STARTCHAR wacute +ENCODING 7811 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +10 +20 +00 +88 +A8 +A8 +50 +ENDCHAR +STARTCHAR Wdieresis +ENCODING 7812 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +50 +00 +88 +88 +A8 +D8 +88 +ENDCHAR +STARTCHAR wdieresis +ENCODING 7813 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +50 +00 +88 +A8 +A8 +50 +ENDCHAR +STARTCHAR Ygrave +ENCODING 7922 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +40 +20 +88 +50 +20 +20 +20 +ENDCHAR +STARTCHAR ygrave +ENCODING 7923 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 9 1 -2 +BITMAP +40 +20 +00 +90 +90 +90 +70 +90 +60 +ENDCHAR +STARTCHAR uni2010 +ENCODING 8208 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 1 1 2 +BITMAP +F0 +ENDCHAR +STARTCHAR uni2011 +ENCODING 8209 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 1 1 2 +BITMAP +F0 +ENDCHAR +STARTCHAR figuredash +ENCODING 8210 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 1 0 2 +BITMAP +F8 +ENDCHAR +STARTCHAR endash +ENCODING 8211 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 1 0 2 +BITMAP +F8 +ENDCHAR +STARTCHAR emdash +ENCODING 8212 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 1 0 2 +BITMAP +FC +ENDCHAR +STARTCHAR afii00208 +ENCODING 8213 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 1 0 2 +BITMAP +FC +ENDCHAR +STARTCHAR uni2016 +ENCODING 8214 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 1 0 +BITMAP +A0 +A0 +A0 +A0 +A0 +A0 +ENDCHAR +STARTCHAR underscoredbl +ENCODING 8215 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 3 0 -2 +BITMAP +FC +00 +FC +ENDCHAR +STARTCHAR quoteleft +ENCODING 8216 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 3 2 3 +BITMAP +40 +80 +C0 +ENDCHAR +STARTCHAR quoteright +ENCODING 8217 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 3 2 3 +BITMAP +C0 +40 +80 +ENDCHAR +STARTCHAR quotesinglbase +ENCODING 8218 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 3 2 -2 +BITMAP +C0 +40 +80 +ENDCHAR +STARTCHAR quotereversed +ENCODING 8219 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 3 2 3 +BITMAP +C0 +80 +40 +ENDCHAR +STARTCHAR quotedblleft +ENCODING 8220 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 3 0 3 +BITMAP +48 +90 +D8 +ENDCHAR +STARTCHAR quotedblright +ENCODING 8221 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 3 0 3 +BITMAP +D8 +48 +90 +ENDCHAR +STARTCHAR quotedblbase +ENCODING 8222 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 3 0 -2 +BITMAP +D8 +48 +90 +ENDCHAR +STARTCHAR uni201F +ENCODING 8223 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 3 0 3 +BITMAP +D8 +90 +48 +ENDCHAR +STARTCHAR dagger +ENCODING 8224 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +20 +20 +F8 +20 +20 +20 +20 +ENDCHAR +STARTCHAR daggerdbl +ENCODING 8225 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +20 +20 +F8 +20 +F8 +20 +20 +ENDCHAR +STARTCHAR bullet +ENCODING 8226 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 1 +BITMAP +60 +F0 +F0 +60 +ENDCHAR +STARTCHAR uni2023 +ENCODING 8227 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 0 +BITMAP +80 +C0 +E0 +C0 +80 +ENDCHAR +STARTCHAR onedotenleader +ENCODING 8228 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 1 2 0 +BITMAP +80 +ENDCHAR +STARTCHAR twodotenleader +ENCODING 8229 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 1 1 0 +BITMAP +A0 +ENDCHAR +STARTCHAR ellipsis +ENCODING 8230 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 1 0 0 +BITMAP +A8 +ENDCHAR +STARTCHAR uni2027 +ENCODING 8231 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 1 2 2 +BITMAP +C0 +ENDCHAR +STARTCHAR perthousand +ENCODING 8240 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 8 0 -1 +BITMAP +40 +A8 +48 +10 +20 +68 +D4 +28 +ENDCHAR +STARTCHAR minute +ENCODING 8242 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 3 2 3 +BITMAP +40 +40 +80 +ENDCHAR +STARTCHAR second +ENCODING 8243 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 3 0 3 +BITMAP +48 +48 +90 +ENDCHAR +STARTCHAR uni2034 +ENCODING 8244 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 3 0 3 +BITMAP +54 +54 +A8 +ENDCHAR +STARTCHAR uni2035 +ENCODING 8245 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 3 2 3 +BITMAP +80 +80 +40 +ENDCHAR +STARTCHAR uni2036 +ENCODING 8246 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 3 0 3 +BITMAP +90 +90 +48 +ENDCHAR +STARTCHAR uni2037 +ENCODING 8247 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 3 0 3 +BITMAP +A8 +A8 +54 +ENDCHAR +STARTCHAR guilsinglleft +ENCODING 8249 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 0 +BITMAP +20 +40 +80 +40 +20 +ENDCHAR +STARTCHAR guilsinglright +ENCODING 8250 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 0 +BITMAP +80 +40 +20 +40 +80 +ENDCHAR +STARTCHAR exclamdbl +ENCODING 8252 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 1 0 +BITMAP +A0 +A0 +A0 +A0 +00 +A0 +ENDCHAR +STARTCHAR uni203E +ENCODING 8254 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 1 0 5 +BITMAP +FC +ENDCHAR +STARTCHAR fraction +ENCODING 8260 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +10 +10 +20 +40 +80 +80 +ENDCHAR +STARTCHAR zerosuperior +ENCODING 8304 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +40 +A0 +A0 +A0 +40 +ENDCHAR +STARTCHAR uni2071 +ENCODING 8305 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +40 +00 +C0 +40 +E0 +ENDCHAR +STARTCHAR foursuperior +ENCODING 8308 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +A0 +A0 +E0 +20 +20 +ENDCHAR +STARTCHAR fivesuperior +ENCODING 8309 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +E0 +80 +C0 +20 +C0 +ENDCHAR +STARTCHAR sixsuperior +ENCODING 8310 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +40 +80 +C0 +A0 +40 +ENDCHAR +STARTCHAR sevensuperior +ENCODING 8311 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +E0 +20 +40 +40 +40 +ENDCHAR +STARTCHAR eightsuperior +ENCODING 8312 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +40 +A0 +40 +A0 +40 +ENDCHAR +STARTCHAR ninesuperior +ENCODING 8313 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +40 +A0 +60 +20 +40 +ENDCHAR +STARTCHAR uni207A +ENCODING 8314 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 1 +BITMAP +40 +E0 +40 +ENDCHAR +STARTCHAR uni207B +ENCODING 8315 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 1 1 2 +BITMAP +E0 +ENDCHAR +STARTCHAR uni207C +ENCODING 8316 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 1 +BITMAP +E0 +00 +E0 +ENDCHAR +STARTCHAR parenleftsuperior +ENCODING 8317 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 5 1 1 +BITMAP +40 +80 +80 +80 +40 +ENDCHAR +STARTCHAR parenrightsuperior +ENCODING 8318 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 5 2 1 +BITMAP +80 +40 +40 +40 +80 +ENDCHAR +STARTCHAR nsuperior +ENCODING 8319 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 4 1 1 +BITMAP +C0 +A0 +A0 +A0 +ENDCHAR +STARTCHAR zeroinferior +ENCODING 8320 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -2 +BITMAP +40 +A0 +A0 +A0 +40 +ENDCHAR +STARTCHAR oneinferior +ENCODING 8321 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -2 +BITMAP +40 +C0 +40 +40 +E0 +ENDCHAR +STARTCHAR twoinferior +ENCODING 8322 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -2 +BITMAP +40 +A0 +20 +40 +E0 +ENDCHAR +STARTCHAR threeinferior +ENCODING 8323 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -2 +BITMAP +C0 +20 +40 +20 +C0 +ENDCHAR +STARTCHAR fourinferior +ENCODING 8324 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -2 +BITMAP +A0 +A0 +E0 +20 +20 +ENDCHAR +STARTCHAR fiveinferior +ENCODING 8325 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -2 +BITMAP +E0 +80 +C0 +20 +C0 +ENDCHAR +STARTCHAR sixinferior +ENCODING 8326 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -2 +BITMAP +40 +80 +C0 +A0 +40 +ENDCHAR +STARTCHAR seveninferior +ENCODING 8327 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -2 +BITMAP +E0 +20 +40 +40 +40 +ENDCHAR +STARTCHAR eightinferior +ENCODING 8328 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -2 +BITMAP +40 +A0 +40 +A0 +40 +ENDCHAR +STARTCHAR nineinferior +ENCODING 8329 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -2 +BITMAP +40 +A0 +60 +20 +40 +ENDCHAR +STARTCHAR uni208A +ENCODING 8330 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 -2 +BITMAP +40 +E0 +40 +ENDCHAR +STARTCHAR uni208B +ENCODING 8331 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 1 1 -1 +BITMAP +E0 +ENDCHAR +STARTCHAR uni208C +ENCODING 8332 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 -2 +BITMAP +E0 +00 +E0 +ENDCHAR +STARTCHAR parenleftinferior +ENCODING 8333 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 5 1 -2 +BITMAP +40 +80 +80 +80 +40 +ENDCHAR +STARTCHAR parenrightinferior +ENCODING 8334 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 5 2 -2 +BITMAP +80 +40 +40 +40 +80 +ENDCHAR +STARTCHAR franc +ENCODING 8355 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +F8 +80 +E8 +B0 +A0 +A0 +ENDCHAR +STARTCHAR lira +ENCODING 8356 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +30 +48 +E0 +40 +E0 +40 +F8 +ENDCHAR +STARTCHAR peseta +ENCODING 8359 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +60 +50 +F8 +50 +60 +40 +ENDCHAR +STARTCHAR dong +ENCODING 8363 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 1 -2 +BITMAP +10 +38 +70 +90 +90 +70 +00 +F0 +ENDCHAR +STARTCHAR Euro +ENCODING 8364 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +38 +40 +F0 +F0 +40 +38 +ENDCHAR +STARTCHAR uni20AF +ENCODING 8367 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +40 +E0 +50 +48 +48 +E8 +D0 +ENDCHAR +STARTCHAR uni20D0 +ENCODING 8400 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 2 0 5 +BITMAP +40 +F8 +ENDCHAR +STARTCHAR uni20D1 +ENCODING 8401 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 2 0 5 +BITMAP +10 +F8 +ENDCHAR +STARTCHAR uni20D2 +ENCODING 8402 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 9 2 -2 +BITMAP +80 +80 +80 +80 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR uni20D3 +ENCODING 8403 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 6 2 -1 +BITMAP +80 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR uni20D4 +ENCODING 8404 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 3 0 4 +BITMAP +B0 +C8 +E0 +ENDCHAR +STARTCHAR uni20D5 +ENCODING 8405 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 3 0 4 +BITMAP +68 +98 +38 +ENDCHAR +STARTCHAR uni20D6 +ENCODING 8406 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 3 0 4 +BITMAP +40 +F8 +40 +ENDCHAR +STARTCHAR uni20D7 +ENCODING 8407 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 3 0 4 +BITMAP +10 +F8 +10 +ENDCHAR +STARTCHAR uni2102 +ENCODING 8450 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +A8 +A0 +A0 +A8 +70 +ENDCHAR +STARTCHAR afii61248 +ENCODING 8453 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +40 +80 +40 +10 +28 +10 +ENDCHAR +STARTCHAR afii61289 +ENCODING 8467 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +20 +50 +50 +60 +40 +B0 +ENDCHAR +STARTCHAR uni2115 +ENCODING 8469 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +C8 +E8 +E8 +D8 +D8 +C8 +ENDCHAR +STARTCHAR afii61352 +ENCODING 8470 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 6 0 0 +BITMAP +90 +D0 +D0 +B8 +B4 +98 +ENDCHAR +STARTCHAR uni211A +ENCODING 8474 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +70 +A8 +A8 +A8 +A8 +70 +18 +ENDCHAR +STARTCHAR uni211D +ENCODING 8477 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +F0 +A8 +A8 +B0 +A8 +A8 +ENDCHAR +STARTCHAR trademark +ENCODING 8482 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 3 0 3 +BITMAP +FC +5C +54 +ENDCHAR +STARTCHAR uni2124 +ENCODING 8484 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +F8 +28 +50 +50 +A0 +F8 +ENDCHAR +STARTCHAR Omega +ENCODING 8486 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +88 +88 +88 +50 +D8 +ENDCHAR +STARTCHAR estimated +ENCODING 8494 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +70 +D8 +F8 +C0 +70 +ENDCHAR +STARTCHAR oneeighth +ENCODING 8539 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -1 +BITMAP +40 +C0 +40 +50 +68 +10 +28 +10 +ENDCHAR +STARTCHAR threeeighths +ENCODING 8540 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -1 +BITMAP +C0 +20 +40 +30 +E8 +10 +28 +10 +ENDCHAR +STARTCHAR fiveeighths +ENCODING 8541 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -1 +BITMAP +E0 +80 +C0 +30 +E8 +10 +28 +10 +ENDCHAR +STARTCHAR seveneighths +ENCODING 8542 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -1 +BITMAP +E0 +20 +40 +50 +68 +10 +28 +10 +ENDCHAR +STARTCHAR arrowleft +ENCODING 8592 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +20 +40 +F8 +40 +20 +ENDCHAR +STARTCHAR arrowup +ENCODING 8593 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +20 +70 +A8 +20 +20 +20 +ENDCHAR +STARTCHAR arrowright +ENCODING 8594 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +20 +10 +F8 +10 +20 +ENDCHAR +STARTCHAR arrowdown +ENCODING 8595 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +20 +20 +20 +A8 +70 +20 +ENDCHAR +STARTCHAR arrowboth +ENCODING 8596 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 3 0 1 +BITMAP +48 +FC +48 +ENDCHAR +STARTCHAR arrowupdn +ENCODING 8597 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +20 +70 +A8 +20 +A8 +70 +20 +ENDCHAR +STARTCHAR uni21A4 +ENCODING 8612 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +20 +48 +F8 +48 +20 +ENDCHAR +STARTCHAR uni21A5 +ENCODING 8613 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +20 +70 +A8 +20 +20 +70 +ENDCHAR +STARTCHAR uni21A6 +ENCODING 8614 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +20 +90 +F8 +90 +20 +ENDCHAR +STARTCHAR uni21A7 +ENCODING 8615 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +20 +20 +A8 +70 +20 +ENDCHAR +STARTCHAR arrowupdnbse +ENCODING 8616 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -1 +BITMAP +20 +70 +A8 +20 +A8 +70 +20 +F8 +ENDCHAR +STARTCHAR arrowdblleft +ENCODING 8656 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +20 +78 +80 +78 +20 +ENDCHAR +STARTCHAR arrowdblup +ENCODING 8657 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +20 +50 +D8 +50 +50 +50 +ENDCHAR +STARTCHAR arrowdblright +ENCODING 8658 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +20 +F0 +08 +F0 +20 +ENDCHAR +STARTCHAR arrowdbldown +ENCODING 8659 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +50 +50 +50 +D8 +70 +20 +ENDCHAR +STARTCHAR arrowdblboth +ENCODING 8660 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 5 0 0 +BITMAP +30 +78 +84 +78 +30 +ENDCHAR +STARTCHAR uni21D5 +ENCODING 8661 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +20 +70 +D8 +50 +D8 +70 +20 +ENDCHAR +STARTCHAR universal +ENCODING 8704 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +88 +88 +F8 +88 +50 +20 +ENDCHAR +STARTCHAR uni2201 +ENCODING 8705 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +40 +A0 +80 +80 +80 +A0 +40 +ENDCHAR +STARTCHAR partialdiff +ENCODING 8706 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +60 +10 +70 +90 +90 +60 +ENDCHAR +STARTCHAR existential +ENCODING 8707 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +F0 +10 +70 +10 +10 +F0 +ENDCHAR +STARTCHAR uni2204 +ENCODING 8708 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -1 +BITMAP +40 +F0 +50 +70 +50 +50 +F0 +40 +ENDCHAR +STARTCHAR emptyset +ENCODING 8709 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +78 +98 +A8 +A8 +C8 +F0 +ENDCHAR +STARTCHAR Delta +ENCODING 8710 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +20 +20 +50 +50 +88 +F8 +ENDCHAR +STARTCHAR gradient +ENCODING 8711 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +F8 +88 +50 +50 +20 +20 +ENDCHAR +STARTCHAR element +ENCODING 8712 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 5 1 0 +BITMAP +70 +80 +F0 +80 +70 +ENDCHAR +STARTCHAR notelement +ENCODING 8713 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 -1 +BITMAP +20 +70 +A0 +F0 +A0 +70 +20 +ENDCHAR +STARTCHAR suchthat +ENCODING 8715 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 5 1 0 +BITMAP +E0 +10 +F0 +10 +E0 +ENDCHAR +STARTCHAR uni220C +ENCODING 8716 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 -1 +BITMAP +40 +E0 +50 +F0 +50 +E0 +40 +ENDCHAR +STARTCHAR product +ENCODING 8719 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -1 +BITMAP +F8 +50 +50 +50 +50 +50 +50 +50 +ENDCHAR +STARTCHAR uni2210 +ENCODING 8720 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -1 +BITMAP +50 +50 +50 +50 +50 +50 +50 +F8 +ENDCHAR +STARTCHAR summation +ENCODING 8721 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +F8 +40 +20 +20 +40 +F8 +ENDCHAR +STARTCHAR minus +ENCODING 8722 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 1 0 2 +BITMAP +F8 +ENDCHAR +STARTCHAR uni2213 +ENCODING 8723 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +F8 +00 +20 +20 +F8 +20 +20 +ENDCHAR +STARTCHAR fraction +ENCODING 8725 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +10 +10 +20 +40 +80 +80 +ENDCHAR +STARTCHAR uni2218 +ENCODING 8728 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 1 +BITMAP +40 +A0 +40 +ENDCHAR +STARTCHAR periodcentered +ENCODING 8729 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 1 +BITMAP +40 +E0 +40 +ENDCHAR +STARTCHAR radical +ENCODING 8730 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 9 0 -2 +BITMAP +0C +08 +08 +08 +10 +D0 +30 +30 +10 +ENDCHAR +STARTCHAR proportional +ENCODING 8733 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 1 +BITMAP +50 +A0 +A0 +50 +ENDCHAR +STARTCHAR infinity +ENCODING 8734 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 1 +BITMAP +50 +A8 +A8 +50 +ENDCHAR +STARTCHAR orthogonal +ENCODING 8735 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +80 +80 +80 +80 +F8 +ENDCHAR +STARTCHAR uni2221 +ENCODING 8737 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 -1 +BITMAP +50 +20 +50 +90 +F8 +10 +ENDCHAR +STARTCHAR uni2224 +ENCODING 8740 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 1 0 +BITMAP +40 +40 +60 +C0 +40 +40 +ENDCHAR +STARTCHAR uni2225 +ENCODING 8741 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 1 0 +BITMAP +A0 +A0 +A0 +A0 +A0 +A0 +ENDCHAR +STARTCHAR uni2226 +ENCODING 8742 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +50 +58 +70 +D0 +50 +50 +ENDCHAR +STARTCHAR logicaland +ENCODING 8743 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +20 +50 +50 +88 +ENDCHAR +STARTCHAR logicalor +ENCODING 8744 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +88 +50 +50 +20 +ENDCHAR +STARTCHAR intersection +ENCODING 8745 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +70 +88 +88 +88 +ENDCHAR +STARTCHAR union +ENCODING 8746 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 0 +BITMAP +88 +88 +88 +70 +ENDCHAR +STARTCHAR integral +ENCODING 8747 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 9 0 -2 +BITMAP +10 +28 +20 +20 +20 +20 +20 +A0 +40 +ENDCHAR +STARTCHAR uni222E +ENCODING 8750 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 9 0 -2 +BITMAP +10 +28 +20 +70 +A8 +70 +20 +A0 +40 +ENDCHAR +STARTCHAR therefore +ENCODING 8756 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 1 +BITMAP +20 +00 +00 +88 +ENDCHAR +STARTCHAR uni2235 +ENCODING 8757 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 4 0 1 +BITMAP +88 +00 +00 +20 +ENDCHAR +STARTCHAR uni2236 +ENCODING 8758 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 4 2 1 +BITMAP +80 +00 +00 +80 +ENDCHAR +STARTCHAR uni2237 +ENCODING 8759 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 1 +BITMAP +90 +00 +00 +90 +ENDCHAR +STARTCHAR uni2238 +ENCODING 8760 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 3 0 2 +BITMAP +20 +00 +F8 +ENDCHAR +STARTCHAR uni2239 +ENCODING 8761 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +08 +00 +E0 +00 +08 +ENDCHAR +STARTCHAR uni223A +ENCODING 8762 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +88 +00 +F8 +00 +88 +ENDCHAR +STARTCHAR uni223B +ENCODING 8763 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 -1 +BITMAP +20 +00 +50 +A0 +00 +40 +ENDCHAR +STARTCHAR similar +ENCODING 8764 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 2 1 1 +BITMAP +50 +A0 +ENDCHAR +STARTCHAR uni223D +ENCODING 8765 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 2 1 1 +BITMAP +A0 +50 +ENDCHAR +STARTCHAR uni2243 +ENCODING 8771 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 0 +BITMAP +50 +A0 +00 +F0 +ENDCHAR +STARTCHAR congruent +ENCODING 8773 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 -1 +BITMAP +50 +A0 +00 +F0 +00 +F0 +ENDCHAR +STARTCHAR approxequal +ENCODING 8776 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +40 +A8 +50 +A8 +10 +ENDCHAR +STARTCHAR uni2249 +ENCODING 8777 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +10 +50 +A8 +70 +A8 +50 +40 +ENDCHAR +STARTCHAR uni2259 +ENCODING 8793 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 1 +BITMAP +20 +50 +00 +F8 +00 +F8 +ENDCHAR +STARTCHAR uni225F +ENCODING 8799 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 9 0 -2 +BITMAP +60 +10 +20 +00 +20 +00 +F8 +00 +F8 +ENDCHAR +STARTCHAR notequal +ENCODING 8800 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +10 +F8 +20 +F8 +40 +ENDCHAR +STARTCHAR equivalence +ENCODING 8801 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +F8 +00 +F8 +00 +F8 +ENDCHAR +STARTCHAR uni2262 +ENCODING 8802 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +10 +F8 +20 +F8 +20 +F8 +40 +ENDCHAR +STARTCHAR uni2263 +ENCODING 8803 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +F8 +00 +F8 +00 +F8 +00 +F8 +ENDCHAR +STARTCHAR lessequal +ENCODING 8804 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +18 +60 +80 +60 +98 +60 +18 +ENDCHAR +STARTCHAR greaterequal +ENCODING 8805 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +C0 +30 +08 +30 +C8 +30 +C0 +ENDCHAR +STARTCHAR uni226A +ENCODING 8810 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +28 +50 +A0 +50 +28 +ENDCHAR +STARTCHAR uni226B +ENCODING 8811 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +A0 +50 +28 +50 +A0 +ENDCHAR +STARTCHAR propersubset +ENCODING 8834 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 1 +BITMAP +70 +80 +80 +70 +ENDCHAR +STARTCHAR propersuperset +ENCODING 8835 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 1 +BITMAP +E0 +10 +10 +E0 +ENDCHAR +STARTCHAR notsubset +ENCODING 8836 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +20 +70 +A0 +A0 +70 +20 +ENDCHAR +STARTCHAR uni2285 +ENCODING 8837 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +40 +E0 +50 +50 +E0 +40 +ENDCHAR +STARTCHAR reflexsubset +ENCODING 8838 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +70 +80 +80 +70 +00 +F0 +ENDCHAR +STARTCHAR reflexsuperset +ENCODING 8839 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +E0 +10 +10 +E0 +00 +F0 +ENDCHAR +STARTCHAR uni2288 +ENCODING 8840 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -1 +BITMAP +20 +70 +A0 +A0 +70 +20 +F0 +20 +ENDCHAR +STARTCHAR uni2289 +ENCODING 8841 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 8 1 -1 +BITMAP +40 +E0 +50 +50 +E0 +40 +F0 +40 +ENDCHAR +STARTCHAR uni228A +ENCODING 8842 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 -1 +BITMAP +70 +80 +80 +70 +20 +F0 +40 +ENDCHAR +STARTCHAR uni228B +ENCODING 8843 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 7 1 -1 +BITMAP +E0 +10 +10 +E0 +20 +F0 +40 +ENDCHAR +STARTCHAR circleplus +ENCODING 8853 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +70 +A8 +F8 +A8 +70 +ENDCHAR +STARTCHAR uni2296 +ENCODING 8854 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +70 +88 +F8 +88 +70 +ENDCHAR +STARTCHAR circlemultiply +ENCODING 8855 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +70 +D8 +A8 +D8 +70 +ENDCHAR +STARTCHAR uni2298 +ENCODING 8856 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +70 +98 +A8 +C8 +70 +ENDCHAR +STARTCHAR uni2299 +ENCODING 8857 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +70 +88 +A8 +88 +70 +ENDCHAR +STARTCHAR uni22A2 +ENCODING 8866 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +80 +80 +F8 +80 +80 +ENDCHAR +STARTCHAR uni22A3 +ENCODING 8867 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +08 +08 +F8 +08 +08 +ENDCHAR +STARTCHAR uni22A4 +ENCODING 8868 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +F8 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR perpendicular +ENCODING 8869 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +20 +20 +20 +20 +20 +F8 +ENDCHAR +STARTCHAR uni22A6 +ENCODING 8870 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 0 +BITMAP +80 +80 +E0 +80 +80 +ENDCHAR +STARTCHAR uni22A7 +ENCODING 8871 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 0 +BITMAP +80 +E0 +80 +E0 +80 +ENDCHAR +STARTCHAR uni22A8 +ENCODING 8872 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +80 +F8 +80 +F8 +80 +ENDCHAR +STARTCHAR uni22C0 +ENCODING 8896 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +50 +50 +50 +88 +88 +88 +ENDCHAR +STARTCHAR uni22C1 +ENCODING 8897 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -1 +BITMAP +88 +88 +88 +50 +50 +50 +20 +20 +ENDCHAR +STARTCHAR uni22C2 +ENCODING 8898 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -1 +BITMAP +70 +88 +88 +88 +88 +88 +88 +88 +ENDCHAR +STARTCHAR uni22C3 +ENCODING 8899 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -1 +BITMAP +88 +88 +88 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR dotmath +ENCODING 8901 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 1 2 2 +BITMAP +80 +ENDCHAR +STARTCHAR uni22EE +ENCODING 8942 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 7 2 -1 +BITMAP +80 +00 +00 +80 +00 +00 +80 +ENDCHAR +STARTCHAR uni22EF +ENCODING 8943 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 1 0 2 +BITMAP +A8 +ENDCHAR +STARTCHAR uni22F0 +ENCODING 8944 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +08 +00 +00 +20 +00 +00 +80 +ENDCHAR +STARTCHAR uni22F1 +ENCODING 8945 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +80 +00 +00 +20 +00 +00 +08 +ENDCHAR +STARTCHAR uni2300 +ENCODING 8960 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +78 +98 +A8 +C8 +F0 +ENDCHAR +STARTCHAR house +ENCODING 8962 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +20 +50 +88 +88 +88 +F8 +ENDCHAR +STARTCHAR uni2308 +ENCODING 8968 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 1 0 +BITMAP +E0 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR uni2309 +ENCODING 8969 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 1 0 +BITMAP +E0 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni230A +ENCODING 8970 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 1 0 +BITMAP +80 +80 +80 +80 +80 +E0 +ENDCHAR +STARTCHAR uni230B +ENCODING 8971 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 1 0 +BITMAP +20 +20 +20 +20 +20 +E0 +ENDCHAR +STARTCHAR revlogicalnot +ENCODING 8976 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 3 1 0 +BITMAP +F0 +80 +80 +ENDCHAR +STARTCHAR integraltp +ENCODING 8992 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 8 3 -2 +BITMAP +40 +A0 +80 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR integralbt +ENCODING 8993 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 8 1 -1 +BITMAP +20 +20 +20 +20 +20 +20 +A0 +40 +ENDCHAR +STARTCHAR uni23BA +ENCODING 9146 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 1 0 6 +BITMAP +FC +ENDCHAR +STARTCHAR uni23BB +ENCODING 9147 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 1 0 4 +BITMAP +FC +ENDCHAR +STARTCHAR uni23BC +ENCODING 9148 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 1 0 0 +BITMAP +FC +ENDCHAR +STARTCHAR uni23BD +ENCODING 9149 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 1 0 -2 +BITMAP +FC +ENDCHAR +STARTCHAR uni2409 +ENCODING 9225 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +A0 +E0 +A0 +00 +38 +10 +10 +ENDCHAR +STARTCHAR uni240A +ENCODING 9226 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -2 +BITMAP +80 +80 +80 +C0 +38 +20 +30 +20 +ENDCHAR +STARTCHAR uni240B +ENCODING 9227 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -2 +BITMAP +A0 +A0 +40 +40 +38 +10 +10 +10 +ENDCHAR +STARTCHAR uni240C +ENCODING 9228 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -2 +BITMAP +E0 +80 +C0 +80 +38 +20 +30 +20 +ENDCHAR +STARTCHAR uni240D +ENCODING 9229 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -2 +BITMAP +60 +80 +60 +00 +30 +28 +30 +28 +ENDCHAR +STARTCHAR uni2424 +ENCODING 9252 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -2 +BITMAP +90 +D0 +B0 +90 +20 +20 +20 +38 +ENDCHAR +STARTCHAR SF100000 +ENCODING 9472 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 1 0 2 +BITMAP +FC +ENDCHAR +STARTCHAR uni2501 +ENCODING 9473 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 2 0 2 +BITMAP +FC +FC +ENDCHAR +STARTCHAR SF110000 +ENCODING 9474 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 9 3 -2 +BITMAP +80 +80 +80 +80 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR uni2503 +ENCODING 9475 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 9 2 -2 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR SF010000 +ENCODING 9484 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 3 -2 +BITMAP +E0 +80 +80 +80 +80 +ENDCHAR +STARTCHAR SF030000 +ENCODING 9488 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 5 0 -2 +BITMAP +F0 +10 +10 +10 +10 +ENDCHAR +STARTCHAR SF020000 +ENCODING 9492 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 3 2 +BITMAP +80 +80 +80 +80 +E0 +ENDCHAR +STARTCHAR SF040000 +ENCODING 9496 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 5 0 2 +BITMAP +10 +10 +10 +10 +F0 +ENDCHAR +STARTCHAR SF080000 +ENCODING 9500 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 9 3 -2 +BITMAP +80 +80 +80 +80 +E0 +80 +80 +80 +80 +ENDCHAR +STARTCHAR SF090000 +ENCODING 9508 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 9 0 -2 +BITMAP +10 +10 +10 +10 +F0 +10 +10 +10 +10 +ENDCHAR +STARTCHAR SF060000 +ENCODING 9516 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 5 0 -2 +BITMAP +FC +10 +10 +10 +10 +ENDCHAR +STARTCHAR SF070000 +ENCODING 9524 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 5 0 2 +BITMAP +10 +10 +10 +10 +FC +ENDCHAR +STARTCHAR SF050000 +ENCODING 9532 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 9 0 -2 +BITMAP +10 +10 +10 +10 +FC +10 +10 +10 +10 +ENDCHAR +STARTCHAR uni254C +ENCODING 9548 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 1 0 2 +BITMAP +D8 +ENDCHAR +STARTCHAR uni254D +ENCODING 9549 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 2 0 2 +BITMAP +D8 +D8 +ENDCHAR +STARTCHAR uni254E +ENCODING 9550 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 8 3 -1 +BITMAP +80 +80 +80 +80 +00 +80 +80 +80 +ENDCHAR +STARTCHAR uni254F +ENCODING 9551 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 8 2 -1 +BITMAP +C0 +C0 +C0 +C0 +00 +C0 +C0 +C0 +ENDCHAR +STARTCHAR SF430000 +ENCODING 9552 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 3 0 1 +BITMAP +FC +00 +FC +ENDCHAR +STARTCHAR SF240000 +ENCODING 9553 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 9 2 -2 +BITMAP +A0 +A0 +A0 +A0 +A0 +A0 +A0 +A0 +A0 +ENDCHAR +STARTCHAR SF510000 +ENCODING 9554 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 3 -2 +BITMAP +E0 +80 +E0 +80 +80 +80 +ENDCHAR +STARTCHAR SF520000 +ENCODING 9555 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 5 2 -2 +BITMAP +F0 +A0 +A0 +A0 +A0 +ENDCHAR +STARTCHAR SF390000 +ENCODING 9556 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 2 -2 +BITMAP +F0 +80 +B0 +A0 +A0 +A0 +ENDCHAR +STARTCHAR SF220000 +ENCODING 9557 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 0 -2 +BITMAP +F0 +10 +F0 +10 +10 +10 +ENDCHAR +STARTCHAR SF210000 +ENCODING 9558 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 -2 +BITMAP +F8 +28 +28 +28 +28 +ENDCHAR +STARTCHAR SF250000 +ENCODING 9559 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 -2 +BITMAP +F8 +08 +E8 +28 +28 +28 +ENDCHAR +STARTCHAR SF500000 +ENCODING 9560 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 3 1 +BITMAP +80 +80 +80 +E0 +80 +E0 +ENDCHAR +STARTCHAR SF490000 +ENCODING 9561 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 5 2 2 +BITMAP +A0 +A0 +A0 +A0 +F0 +ENDCHAR +STARTCHAR SF380000 +ENCODING 9562 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 2 1 +BITMAP +A0 +A0 +A0 +B0 +80 +F0 +ENDCHAR +STARTCHAR SF280000 +ENCODING 9563 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 0 1 +BITMAP +10 +10 +10 +F0 +10 +F0 +ENDCHAR +STARTCHAR SF270000 +ENCODING 9564 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 2 +BITMAP +28 +28 +28 +28 +F8 +ENDCHAR +STARTCHAR SF260000 +ENCODING 9565 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 1 +BITMAP +28 +28 +28 +E8 +08 +F8 +ENDCHAR +STARTCHAR SF360000 +ENCODING 9566 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 9 3 -2 +BITMAP +80 +80 +80 +E0 +80 +E0 +80 +80 +80 +ENDCHAR +STARTCHAR SF370000 +ENCODING 9567 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 9 2 -2 +BITMAP +A0 +A0 +A0 +A0 +B0 +A0 +A0 +A0 +A0 +ENDCHAR +STARTCHAR SF420000 +ENCODING 9568 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 9 2 -2 +BITMAP +A0 +A0 +A0 +B0 +80 +B0 +A0 +A0 +A0 +ENDCHAR +STARTCHAR SF190000 +ENCODING 9569 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 9 0 -2 +BITMAP +10 +10 +10 +F0 +10 +F0 +10 +10 +10 +ENDCHAR +STARTCHAR SF200000 +ENCODING 9570 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 9 0 -2 +BITMAP +28 +28 +28 +28 +E8 +28 +28 +28 +28 +ENDCHAR +STARTCHAR SF230000 +ENCODING 9571 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 9 0 -2 +BITMAP +28 +28 +28 +E8 +08 +E8 +28 +28 +28 +ENDCHAR +STARTCHAR SF470000 +ENCODING 9572 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 6 0 -2 +BITMAP +FC +00 +FC +10 +10 +10 +ENDCHAR +STARTCHAR SF480000 +ENCODING 9573 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 5 0 -2 +BITMAP +FC +28 +28 +28 +28 +ENDCHAR +STARTCHAR SF410000 +ENCODING 9574 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 6 0 -2 +BITMAP +FC +00 +EC +28 +28 +28 +ENDCHAR +STARTCHAR SF450000 +ENCODING 9575 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 6 0 1 +BITMAP +10 +10 +10 +FC +00 +FC +ENDCHAR +STARTCHAR SF460000 +ENCODING 9576 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 5 0 2 +BITMAP +28 +28 +28 +28 +FC +ENDCHAR +STARTCHAR SF400000 +ENCODING 9577 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 6 0 1 +BITMAP +28 +28 +28 +EC +00 +FC +ENDCHAR +STARTCHAR SF540000 +ENCODING 9578 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 9 0 -2 +BITMAP +10 +10 +10 +FC +10 +FC +10 +10 +10 +ENDCHAR +STARTCHAR SF530000 +ENCODING 9579 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 9 0 -2 +BITMAP +28 +28 +28 +28 +FC +28 +28 +28 +28 +ENDCHAR +STARTCHAR SF440000 +ENCODING 9580 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 9 0 -2 +BITMAP +28 +28 +28 +EC +00 +EC +28 +28 +28 +ENDCHAR +STARTCHAR uni256D +ENCODING 9581 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 3 -2 +BITMAP +20 +40 +80 +80 +80 +ENDCHAR +STARTCHAR uni256E +ENCODING 9582 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 5 0 -2 +BITMAP +C0 +20 +10 +10 +10 +ENDCHAR +STARTCHAR uni256F +ENCODING 9583 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 5 0 2 +BITMAP +10 +10 +10 +20 +C0 +ENDCHAR +STARTCHAR uni2570 +ENCODING 9584 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 3 2 +BITMAP +80 +80 +80 +40 +20 +ENDCHAR +STARTCHAR uni2571 +ENCODING 9585 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 9 0 -2 +BITMAP +04 +04 +08 +10 +10 +20 +40 +40 +80 +ENDCHAR +STARTCHAR uni2572 +ENCODING 9586 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 9 0 -2 +BITMAP +80 +80 +40 +20 +20 +10 +08 +08 +04 +ENDCHAR +STARTCHAR uni2573 +ENCODING 9587 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 9 0 -2 +BITMAP +84 +84 +48 +30 +30 +30 +48 +48 +84 +ENDCHAR +STARTCHAR upblock +ENCODING 9600 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 4 0 3 +BITMAP +FC +FC +FC +FC +ENDCHAR +STARTCHAR uni2581 +ENCODING 9601 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 1 0 -2 +BITMAP +FC +ENDCHAR +STARTCHAR uni2582 +ENCODING 9602 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 2 0 -2 +BITMAP +FC +FC +ENDCHAR +STARTCHAR uni2583 +ENCODING 9603 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 4 0 -2 +BITMAP +FC +FC +FC +FC +ENDCHAR +STARTCHAR dnblock +ENCODING 9604 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 5 0 -2 +BITMAP +FC +FC +FC +FC +FC +ENDCHAR +STARTCHAR uni2585 +ENCODING 9605 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 6 0 -2 +BITMAP +FC +FC +FC +FC +FC +FC +ENDCHAR +STARTCHAR uni2586 +ENCODING 9606 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 7 0 -2 +BITMAP +FC +FC +FC +FC +FC +FC +FC +ENDCHAR +STARTCHAR uni2587 +ENCODING 9607 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 8 0 -2 +BITMAP +FC +FC +FC +FC +FC +FC +FC +FC +ENDCHAR +STARTCHAR block +ENCODING 9608 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 9 0 -2 +BITMAP +FC +FC +FC +FC +FC +FC +FC +FC +FC +ENDCHAR +STARTCHAR uni2589 +ENCODING 9609 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 9 0 -2 +BITMAP +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +ENDCHAR +STARTCHAR uni258A +ENCODING 9610 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 9 0 -2 +BITMAP +F0 +F0 +F0 +F0 +F0 +F0 +F0 +F0 +F0 +ENDCHAR +STARTCHAR uni258B +ENCODING 9611 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 9 0 -2 +BITMAP +F0 +F0 +F0 +F0 +F0 +F0 +F0 +F0 +F0 +ENDCHAR +STARTCHAR lfblock +ENCODING 9612 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 9 0 -2 +BITMAP +E0 +E0 +E0 +E0 +E0 +E0 +E0 +E0 +E0 +ENDCHAR +STARTCHAR uni258D +ENCODING 9613 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 9 0 -2 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR uni258E +ENCODING 9614 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 9 0 -2 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR uni258F +ENCODING 9615 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 9 0 -2 +BITMAP +80 +80 +80 +80 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR rtblock +ENCODING 9616 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 9 3 -2 +BITMAP +E0 +E0 +E0 +E0 +E0 +E0 +E0 +E0 +E0 +ENDCHAR +STARTCHAR ltshade +ENCODING 9617 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 9 0 -2 +BITMAP +A8 +00 +54 +00 +A8 +00 +54 +00 +A8 +ENDCHAR +STARTCHAR shade +ENCODING 9618 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 9 0 -2 +BITMAP +54 +A8 +54 +A8 +54 +A8 +54 +A8 +54 +ENDCHAR +STARTCHAR dkshade +ENCODING 9619 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 9 0 -2 +BITMAP +FC +A8 +FC +54 +FC +A8 +FC +54 +FC +ENDCHAR +STARTCHAR uni2594 +ENCODING 9620 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 1 0 6 +BITMAP +FC +ENDCHAR +STARTCHAR uni2595 +ENCODING 9621 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 9 5 -2 +BITMAP +80 +80 +80 +80 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR uni2596 +ENCODING 9622 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 0 -2 +BITMAP +E0 +E0 +E0 +E0 +E0 +ENDCHAR +STARTCHAR uni2597 +ENCODING 9623 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 3 -2 +BITMAP +E0 +E0 +E0 +E0 +E0 +ENDCHAR +STARTCHAR uni2598 +ENCODING 9624 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 4 0 3 +BITMAP +E0 +E0 +E0 +E0 +ENDCHAR +STARTCHAR uni2599 +ENCODING 9625 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 9 0 -2 +BITMAP +E0 +E0 +E0 +E0 +FC +FC +FC +FC +FC +ENDCHAR +STARTCHAR uni259A +ENCODING 9626 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 9 0 -2 +BITMAP +E0 +E0 +E0 +E0 +1C +1C +1C +1C +1C +ENDCHAR +STARTCHAR uni259B +ENCODING 9627 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 9 0 -2 +BITMAP +FC +FC +FC +FC +E0 +E0 +E0 +E0 +E0 +ENDCHAR +STARTCHAR uni259C +ENCODING 9628 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 9 0 -2 +BITMAP +FC +FC +FC +FC +1C +1C +1C +1C +1C +ENDCHAR +STARTCHAR uni259D +ENCODING 9629 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 4 3 3 +BITMAP +E0 +E0 +E0 +E0 +ENDCHAR +STARTCHAR uni259E +ENCODING 9630 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 9 0 -2 +BITMAP +1C +1C +1C +1C +E0 +E0 +E0 +E0 +E0 +ENDCHAR +STARTCHAR uni259F +ENCODING 9631 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 9 0 -2 +BITMAP +1C +1C +1C +1C +FC +FC +FC +FC +FC +ENDCHAR +STARTCHAR filledbox +ENCODING 9632 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +F8 +F8 +F8 +F8 +F8 +ENDCHAR +STARTCHAR H22073 +ENCODING 9633 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +F8 +88 +88 +88 +F8 +ENDCHAR +STARTCHAR uni25A2 +ENCODING 9634 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +70 +88 +88 +88 +70 +ENDCHAR +STARTCHAR uni25A3 +ENCODING 9635 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +F8 +88 +A8 +88 +F8 +ENDCHAR +STARTCHAR H18543 +ENCODING 9642 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 1 +BITMAP +E0 +E0 +E0 +ENDCHAR +STARTCHAR H18551 +ENCODING 9643 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 1 +BITMAP +E0 +A0 +E0 +ENDCHAR +STARTCHAR filledrect +ENCODING 9644 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 3 0 1 +BITMAP +F8 +F8 +F8 +ENDCHAR +STARTCHAR uni25AD +ENCODING 9645 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 3 0 1 +BITMAP +F8 +88 +F8 +ENDCHAR +STARTCHAR uni25AE +ENCODING 9646 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +F0 +F0 +F0 +F0 +F0 +F0 +ENDCHAR +STARTCHAR uni25AF +ENCODING 9647 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +F0 +90 +90 +90 +90 +F0 +ENDCHAR +STARTCHAR uni25B0 +ENCODING 9648 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 3 0 1 +BITMAP +78 +F8 +F0 +ENDCHAR +STARTCHAR uni25B1 +ENCODING 9649 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 3 0 1 +BITMAP +78 +88 +F0 +ENDCHAR +STARTCHAR triagup +ENCODING 9650 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +20 +20 +70 +70 +F8 +F8 +ENDCHAR +STARTCHAR uni25B3 +ENCODING 9651 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +20 +20 +50 +50 +88 +F8 +ENDCHAR +STARTCHAR uni25B4 +ENCODING 9652 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 4 1 1 +BITMAP +40 +40 +E0 +E0 +ENDCHAR +STARTCHAR uni25B5 +ENCODING 9653 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 4 1 1 +BITMAP +40 +40 +A0 +E0 +ENDCHAR +STARTCHAR uni25B6 +ENCODING 9654 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +C0 +F0 +F8 +F0 +C0 +ENDCHAR +STARTCHAR uni25B7 +ENCODING 9655 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +C0 +B0 +88 +B0 +C0 +ENDCHAR +STARTCHAR uni25B8 +ENCODING 9656 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 3 1 1 +BITMAP +C0 +F0 +C0 +ENDCHAR +STARTCHAR uni25B9 +ENCODING 9657 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 3 1 1 +BITMAP +C0 +B0 +C0 +ENDCHAR +STARTCHAR triagrt +ENCODING 9658 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 3 0 1 +BITMAP +E0 +F8 +E0 +ENDCHAR +STARTCHAR uni25BB +ENCODING 9659 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 3 0 1 +BITMAP +E0 +98 +E0 +ENDCHAR +STARTCHAR triagdn +ENCODING 9660 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +F8 +F8 +70 +70 +20 +20 +ENDCHAR +STARTCHAR uni25BD +ENCODING 9661 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +F8 +88 +50 +50 +20 +20 +ENDCHAR +STARTCHAR uni25BE +ENCODING 9662 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 4 1 1 +BITMAP +E0 +E0 +40 +40 +ENDCHAR +STARTCHAR uni25BF +ENCODING 9663 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 4 1 1 +BITMAP +E0 +A0 +40 +40 +ENDCHAR +STARTCHAR uni25C0 +ENCODING 9664 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +18 +78 +F8 +78 +18 +ENDCHAR +STARTCHAR uni25C1 +ENCODING 9665 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +18 +68 +88 +68 +18 +ENDCHAR +STARTCHAR uni25C2 +ENCODING 9666 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 3 1 1 +BITMAP +30 +F0 +30 +ENDCHAR +STARTCHAR uni25C3 +ENCODING 9667 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 3 1 1 +BITMAP +30 +D0 +30 +ENDCHAR +STARTCHAR triaglf +ENCODING 9668 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 3 0 1 +BITMAP +38 +F8 +38 +ENDCHAR +STARTCHAR uni25C5 +ENCODING 9669 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 3 0 1 +BITMAP +38 +C8 +38 +ENDCHAR +STARTCHAR uni25C6 +ENCODING 9670 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 5 0 0 +BITMAP +30 +78 +FC +78 +30 +ENDCHAR +STARTCHAR lozenge +ENCODING 9674 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +20 +50 +50 +88 +50 +50 +20 +ENDCHAR +STARTCHAR circle +ENCODING 9675 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +70 +88 +88 +88 +70 +ENDCHAR +STARTCHAR H18533 +ENCODING 9679 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +70 +F8 +F8 +F8 +70 +ENDCHAR +STARTCHAR invbullet +ENCODING 9688 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 9 0 -2 +BITMAP +FC +FC +CC +84 +84 +CC +FC +FC +FC +ENDCHAR +STARTCHAR invcircle +ENCODING 9689 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 9 0 -2 +BITMAP +FC +FC +CC +B4 +B4 +CC +FC +FC +FC +ENDCHAR +STARTCHAR openbullet +ENCODING 9702 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 4 1 1 +BITMAP +60 +90 +90 +60 +ENDCHAR +STARTCHAR uni2600 +ENCODING 9728 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +20 +A8 +70 +F8 +70 +A8 +20 +ENDCHAR +STARTCHAR uni2639 +ENCODING 9785 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 8 0 -1 +BITMAP +78 +84 +CC +84 +B4 +CC +84 +78 +ENDCHAR +STARTCHAR smileface +ENCODING 9786 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 8 0 -1 +BITMAP +78 +84 +CC +84 +CC +B4 +84 +78 +ENDCHAR +STARTCHAR invsmileface +ENCODING 9787 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 8 0 -1 +BITMAP +78 +FC +B4 +FC +B4 +CC +FC +78 +ENDCHAR +STARTCHAR sun +ENCODING 9788 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +20 +A8 +70 +D8 +70 +A8 +20 +ENDCHAR +STARTCHAR uni263F +ENCODING 9791 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 8 0 -1 +BITMAP +88 +70 +88 +88 +70 +20 +F8 +20 +ENDCHAR +STARTCHAR female +ENCODING 9792 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +70 +88 +88 +70 +20 +F8 +20 +ENDCHAR +STARTCHAR uni2641 +ENCODING 9793 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +20 +F8 +20 +70 +88 +88 +70 +ENDCHAR +STARTCHAR male +ENCODING 9794 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 6 7 0 -1 +BITMAP +1C +0C +14 +70 +88 +88 +70 +ENDCHAR +STARTCHAR spade +ENCODING 9824 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +20 +70 +F8 +F8 +20 +70 +ENDCHAR +STARTCHAR uni2661 +ENCODING 9825 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +50 +A8 +88 +88 +50 +20 +ENDCHAR +STARTCHAR uni2662 +ENCODING 9826 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +20 +50 +88 +50 +20 +ENDCHAR +STARTCHAR club +ENCODING 9827 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +20 +70 +A8 +F8 +A8 +20 +70 +ENDCHAR +STARTCHAR uni2664 +ENCODING 9828 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +20 +50 +88 +F8 +20 +70 +ENDCHAR +STARTCHAR heart +ENCODING 9829 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +50 +F8 +F8 +F8 +70 +20 +ENDCHAR +STARTCHAR diamond +ENCODING 9830 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +20 +70 +F8 +70 +20 +ENDCHAR +STARTCHAR uni2669 +ENCODING 9833 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 6 1 0 +BITMAP +20 +20 +20 +20 +E0 +C0 +ENDCHAR +STARTCHAR musicalnote +ENCODING 9834 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +30 +28 +20 +20 +E0 +C0 +ENDCHAR +STARTCHAR musicalnotedbl +ENCODING 9835 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +60 +58 +48 +C8 +D8 +18 +ENDCHAR +STARTCHAR uni27E8 +ENCODING 10216 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 7 2 -1 +BITMAP +40 +40 +80 +80 +80 +40 +40 +ENDCHAR +STARTCHAR uni27E9 +ENCODING 10217 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 2 7 2 -1 +BITMAP +80 +80 +40 +40 +40 +80 +80 +ENDCHAR +STARTCHAR uni2800 +ENCODING 10240 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 1 5 -2 +BITMAP +00 +ENDCHAR +STARTCHAR uni2801 +ENCODING 10241 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 1 1 5 +BITMAP +80 +ENDCHAR +STARTCHAR uni2802 +ENCODING 10242 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 1 1 3 +BITMAP +80 +ENDCHAR +STARTCHAR uni2803 +ENCODING 10243 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 3 1 3 +BITMAP +80 +00 +80 +ENDCHAR +STARTCHAR uni2804 +ENCODING 10244 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 1 1 1 +BITMAP +80 +ENDCHAR +STARTCHAR uni2805 +ENCODING 10245 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 5 1 1 +BITMAP +80 +00 +00 +00 +80 +ENDCHAR +STARTCHAR uni2806 +ENCODING 10246 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 3 1 1 +BITMAP +80 +00 +80 +ENDCHAR +STARTCHAR uni2807 +ENCODING 10247 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 5 1 1 +BITMAP +80 +00 +80 +00 +80 +ENDCHAR +STARTCHAR uni2808 +ENCODING 10248 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 1 3 5 +BITMAP +80 +ENDCHAR +STARTCHAR uni2809 +ENCODING 10249 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 1 1 5 +BITMAP +A0 +ENDCHAR +STARTCHAR uni280A +ENCODING 10250 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 3 +BITMAP +20 +00 +80 +ENDCHAR +STARTCHAR uni280B +ENCODING 10251 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 3 +BITMAP +A0 +00 +80 +ENDCHAR +STARTCHAR uni280C +ENCODING 10252 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +20 +00 +00 +00 +80 +ENDCHAR +STARTCHAR uni280D +ENCODING 10253 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +A0 +00 +00 +00 +80 +ENDCHAR +STARTCHAR uni280E +ENCODING 10254 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +20 +00 +80 +00 +80 +ENDCHAR +STARTCHAR uni280F +ENCODING 10255 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +A0 +00 +80 +00 +80 +ENDCHAR +STARTCHAR uni2810 +ENCODING 10256 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 1 3 3 +BITMAP +80 +ENDCHAR +STARTCHAR uni2811 +ENCODING 10257 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 3 +BITMAP +80 +00 +20 +ENDCHAR +STARTCHAR uni2812 +ENCODING 10258 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 1 1 3 +BITMAP +A0 +ENDCHAR +STARTCHAR uni2813 +ENCODING 10259 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 3 +BITMAP +80 +00 +A0 +ENDCHAR +STARTCHAR uni2814 +ENCODING 10260 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 1 +BITMAP +20 +00 +80 +ENDCHAR +STARTCHAR uni2815 +ENCODING 10261 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +80 +00 +20 +00 +80 +ENDCHAR +STARTCHAR uni2816 +ENCODING 10262 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 1 +BITMAP +A0 +00 +80 +ENDCHAR +STARTCHAR uni2817 +ENCODING 10263 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +80 +00 +A0 +00 +80 +ENDCHAR +STARTCHAR uni2818 +ENCODING 10264 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 3 3 3 +BITMAP +80 +00 +80 +ENDCHAR +STARTCHAR uni2819 +ENCODING 10265 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 3 +BITMAP +A0 +00 +20 +ENDCHAR +STARTCHAR uni281A +ENCODING 10266 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 3 +BITMAP +20 +00 +A0 +ENDCHAR +STARTCHAR uni281B +ENCODING 10267 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 3 +BITMAP +A0 +00 +A0 +ENDCHAR +STARTCHAR uni281C +ENCODING 10268 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +20 +00 +20 +00 +80 +ENDCHAR +STARTCHAR uni281D +ENCODING 10269 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +A0 +00 +20 +00 +80 +ENDCHAR +STARTCHAR uni281E +ENCODING 10270 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +20 +00 +A0 +00 +80 +ENDCHAR +STARTCHAR uni281F +ENCODING 10271 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +A0 +00 +A0 +00 +80 +ENDCHAR +STARTCHAR uni2820 +ENCODING 10272 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 1 3 1 +BITMAP +80 +ENDCHAR +STARTCHAR uni2821 +ENCODING 10273 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +80 +00 +00 +00 +20 +ENDCHAR +STARTCHAR uni2822 +ENCODING 10274 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 1 +BITMAP +80 +00 +20 +ENDCHAR +STARTCHAR uni2823 +ENCODING 10275 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +80 +00 +80 +00 +20 +ENDCHAR +STARTCHAR uni2824 +ENCODING 10276 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 1 1 1 +BITMAP +A0 +ENDCHAR +STARTCHAR uni2825 +ENCODING 10277 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +80 +00 +00 +00 +A0 +ENDCHAR +STARTCHAR uni2826 +ENCODING 10278 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 1 +BITMAP +80 +00 +A0 +ENDCHAR +STARTCHAR uni2827 +ENCODING 10279 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +80 +00 +80 +00 +A0 +ENDCHAR +STARTCHAR uni2828 +ENCODING 10280 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 5 3 1 +BITMAP +80 +00 +00 +00 +80 +ENDCHAR +STARTCHAR uni2829 +ENCODING 10281 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +A0 +00 +00 +00 +20 +ENDCHAR +STARTCHAR uni282A +ENCODING 10282 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +20 +00 +80 +00 +20 +ENDCHAR +STARTCHAR uni282B +ENCODING 10283 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +A0 +00 +80 +00 +20 +ENDCHAR +STARTCHAR uni282C +ENCODING 10284 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +20 +00 +00 +00 +A0 +ENDCHAR +STARTCHAR uni282D +ENCODING 10285 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +A0 +00 +00 +00 +A0 +ENDCHAR +STARTCHAR uni282E +ENCODING 10286 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +20 +00 +80 +00 +A0 +ENDCHAR +STARTCHAR uni282F +ENCODING 10287 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +A0 +00 +80 +00 +A0 +ENDCHAR +STARTCHAR uni2830 +ENCODING 10288 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 3 3 1 +BITMAP +80 +00 +80 +ENDCHAR +STARTCHAR uni2831 +ENCODING 10289 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +80 +00 +20 +00 +20 +ENDCHAR +STARTCHAR uni2832 +ENCODING 10290 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 1 +BITMAP +A0 +00 +20 +ENDCHAR +STARTCHAR uni2833 +ENCODING 10291 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +80 +00 +A0 +00 +20 +ENDCHAR +STARTCHAR uni2834 +ENCODING 10292 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 1 +BITMAP +20 +00 +A0 +ENDCHAR +STARTCHAR uni2835 +ENCODING 10293 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +80 +00 +20 +00 +A0 +ENDCHAR +STARTCHAR uni2836 +ENCODING 10294 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 1 +BITMAP +A0 +00 +A0 +ENDCHAR +STARTCHAR uni2837 +ENCODING 10295 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +80 +00 +A0 +00 +A0 +ENDCHAR +STARTCHAR uni2838 +ENCODING 10296 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 5 3 1 +BITMAP +80 +00 +80 +00 +80 +ENDCHAR +STARTCHAR uni2839 +ENCODING 10297 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +A0 +00 +20 +00 +20 +ENDCHAR +STARTCHAR uni283A +ENCODING 10298 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +20 +00 +A0 +00 +20 +ENDCHAR +STARTCHAR uni283B +ENCODING 10299 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +A0 +00 +A0 +00 +20 +ENDCHAR +STARTCHAR uni283C +ENCODING 10300 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +20 +00 +20 +00 +A0 +ENDCHAR +STARTCHAR uni283D +ENCODING 10301 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +A0 +00 +20 +00 +A0 +ENDCHAR +STARTCHAR uni283E +ENCODING 10302 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +20 +00 +A0 +00 +A0 +ENDCHAR +STARTCHAR uni283F +ENCODING 10303 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 1 +BITMAP +A0 +00 +A0 +00 +A0 +ENDCHAR +STARTCHAR uni2840 +ENCODING 10304 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 1 1 -1 +BITMAP +80 +ENDCHAR +STARTCHAR uni2841 +ENCODING 10305 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 7 1 -1 +BITMAP +80 +00 +00 +00 +00 +00 +80 +ENDCHAR +STARTCHAR uni2842 +ENCODING 10306 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 5 1 -1 +BITMAP +80 +00 +00 +00 +80 +ENDCHAR +STARTCHAR uni2843 +ENCODING 10307 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 7 1 -1 +BITMAP +80 +00 +80 +00 +00 +00 +80 +ENDCHAR +STARTCHAR uni2844 +ENCODING 10308 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 3 1 -1 +BITMAP +80 +00 +80 +ENDCHAR +STARTCHAR uni2845 +ENCODING 10309 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 7 1 -1 +BITMAP +80 +00 +00 +00 +80 +00 +80 +ENDCHAR +STARTCHAR uni2846 +ENCODING 10310 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 5 1 -1 +BITMAP +80 +00 +80 +00 +80 +ENDCHAR +STARTCHAR uni2847 +ENCODING 10311 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 7 1 -1 +BITMAP +80 +00 +80 +00 +80 +00 +80 +ENDCHAR +STARTCHAR uni2848 +ENCODING 10312 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +00 +00 +00 +00 +80 +ENDCHAR +STARTCHAR uni2849 +ENCODING 10313 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +00 +00 +00 +00 +80 +ENDCHAR +STARTCHAR uni284A +ENCODING 10314 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +80 +00 +00 +00 +80 +ENDCHAR +STARTCHAR uni284B +ENCODING 10315 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +80 +00 +00 +00 +80 +ENDCHAR +STARTCHAR uni284C +ENCODING 10316 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +00 +00 +80 +00 +80 +ENDCHAR +STARTCHAR uni284D +ENCODING 10317 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +00 +00 +80 +00 +80 +ENDCHAR +STARTCHAR uni284E +ENCODING 10318 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +80 +00 +80 +00 +80 +ENDCHAR +STARTCHAR uni284F +ENCODING 10319 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +80 +00 +80 +00 +80 +ENDCHAR +STARTCHAR uni2850 +ENCODING 10320 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +20 +00 +00 +00 +80 +ENDCHAR +STARTCHAR uni2851 +ENCODING 10321 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +20 +00 +00 +00 +80 +ENDCHAR +STARTCHAR uni2852 +ENCODING 10322 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +A0 +00 +00 +00 +80 +ENDCHAR +STARTCHAR uni2853 +ENCODING 10323 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +A0 +00 +00 +00 +80 +ENDCHAR +STARTCHAR uni2854 +ENCODING 10324 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +20 +00 +80 +00 +80 +ENDCHAR +STARTCHAR uni2855 +ENCODING 10325 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +20 +00 +80 +00 +80 +ENDCHAR +STARTCHAR uni2856 +ENCODING 10326 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +A0 +00 +80 +00 +80 +ENDCHAR +STARTCHAR uni2857 +ENCODING 10327 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +A0 +00 +80 +00 +80 +ENDCHAR +STARTCHAR uni2858 +ENCODING 10328 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +20 +00 +00 +00 +80 +ENDCHAR +STARTCHAR uni2859 +ENCODING 10329 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +20 +00 +00 +00 +80 +ENDCHAR +STARTCHAR uni285A +ENCODING 10330 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +A0 +00 +00 +00 +80 +ENDCHAR +STARTCHAR uni285B +ENCODING 10331 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +A0 +00 +00 +00 +80 +ENDCHAR +STARTCHAR uni285C +ENCODING 10332 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +20 +00 +80 +00 +80 +ENDCHAR +STARTCHAR uni285D +ENCODING 10333 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +20 +00 +80 +00 +80 +ENDCHAR +STARTCHAR uni285E +ENCODING 10334 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +A0 +00 +80 +00 +80 +ENDCHAR +STARTCHAR uni285F +ENCODING 10335 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +A0 +00 +80 +00 +80 +ENDCHAR +STARTCHAR uni2860 +ENCODING 10336 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 -1 +BITMAP +20 +00 +80 +ENDCHAR +STARTCHAR uni2861 +ENCODING 10337 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +00 +00 +20 +00 +80 +ENDCHAR +STARTCHAR uni2862 +ENCODING 10338 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +80 +00 +20 +00 +80 +ENDCHAR +STARTCHAR uni2863 +ENCODING 10339 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +80 +00 +20 +00 +80 +ENDCHAR +STARTCHAR uni2864 +ENCODING 10340 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 -1 +BITMAP +A0 +00 +80 +ENDCHAR +STARTCHAR uni2865 +ENCODING 10341 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +00 +00 +A0 +00 +80 +ENDCHAR +STARTCHAR uni2866 +ENCODING 10342 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +80 +00 +A0 +00 +80 +ENDCHAR +STARTCHAR uni2867 +ENCODING 10343 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +80 +00 +A0 +00 +80 +ENDCHAR +STARTCHAR uni2868 +ENCODING 10344 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +00 +00 +20 +00 +80 +ENDCHAR +STARTCHAR uni2869 +ENCODING 10345 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +00 +00 +20 +00 +80 +ENDCHAR +STARTCHAR uni286A +ENCODING 10346 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +80 +00 +20 +00 +80 +ENDCHAR +STARTCHAR uni286B +ENCODING 10347 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +80 +00 +20 +00 +80 +ENDCHAR +STARTCHAR uni286C +ENCODING 10348 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +00 +00 +A0 +00 +80 +ENDCHAR +STARTCHAR uni286D +ENCODING 10349 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +00 +00 +A0 +00 +80 +ENDCHAR +STARTCHAR uni286E +ENCODING 10350 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +80 +00 +A0 +00 +80 +ENDCHAR +STARTCHAR uni286F +ENCODING 10351 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +80 +00 +A0 +00 +80 +ENDCHAR +STARTCHAR uni2870 +ENCODING 10352 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +20 +00 +20 +00 +80 +ENDCHAR +STARTCHAR uni2871 +ENCODING 10353 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +20 +00 +20 +00 +80 +ENDCHAR +STARTCHAR uni2872 +ENCODING 10354 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +A0 +00 +20 +00 +80 +ENDCHAR +STARTCHAR uni2873 +ENCODING 10355 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +A0 +00 +20 +00 +80 +ENDCHAR +STARTCHAR uni2874 +ENCODING 10356 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +20 +00 +A0 +00 +80 +ENDCHAR +STARTCHAR uni2875 +ENCODING 10357 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +20 +00 +A0 +00 +80 +ENDCHAR +STARTCHAR uni2876 +ENCODING 10358 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +A0 +00 +A0 +00 +80 +ENDCHAR +STARTCHAR uni2877 +ENCODING 10359 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +A0 +00 +A0 +00 +80 +ENDCHAR +STARTCHAR uni2878 +ENCODING 10360 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +20 +00 +20 +00 +80 +ENDCHAR +STARTCHAR uni2879 +ENCODING 10361 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +20 +00 +20 +00 +80 +ENDCHAR +STARTCHAR uni287A +ENCODING 10362 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +A0 +00 +20 +00 +80 +ENDCHAR +STARTCHAR uni287B +ENCODING 10363 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +A0 +00 +20 +00 +80 +ENDCHAR +STARTCHAR uni287C +ENCODING 10364 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +20 +00 +A0 +00 +80 +ENDCHAR +STARTCHAR uni287D +ENCODING 10365 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +20 +00 +A0 +00 +80 +ENDCHAR +STARTCHAR uni287E +ENCODING 10366 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +A0 +00 +A0 +00 +80 +ENDCHAR +STARTCHAR uni287F +ENCODING 10367 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +A0 +00 +A0 +00 +80 +ENDCHAR +STARTCHAR uni2880 +ENCODING 10368 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 1 3 -1 +BITMAP +80 +ENDCHAR +STARTCHAR uni2881 +ENCODING 10369 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +00 +00 +00 +00 +20 +ENDCHAR +STARTCHAR uni2882 +ENCODING 10370 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +80 +00 +00 +00 +20 +ENDCHAR +STARTCHAR uni2883 +ENCODING 10371 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +80 +00 +00 +00 +20 +ENDCHAR +STARTCHAR uni2884 +ENCODING 10372 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 -1 +BITMAP +80 +00 +20 +ENDCHAR +STARTCHAR uni2885 +ENCODING 10373 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +00 +00 +80 +00 +20 +ENDCHAR +STARTCHAR uni2886 +ENCODING 10374 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +80 +00 +80 +00 +20 +ENDCHAR +STARTCHAR uni2887 +ENCODING 10375 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +80 +00 +80 +00 +20 +ENDCHAR +STARTCHAR uni2888 +ENCODING 10376 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 7 3 -1 +BITMAP +80 +00 +00 +00 +00 +00 +80 +ENDCHAR +STARTCHAR uni2889 +ENCODING 10377 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +00 +00 +00 +00 +20 +ENDCHAR +STARTCHAR uni288A +ENCODING 10378 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +80 +00 +00 +00 +20 +ENDCHAR +STARTCHAR uni288B +ENCODING 10379 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +80 +00 +00 +00 +20 +ENDCHAR +STARTCHAR uni288C +ENCODING 10380 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +00 +00 +80 +00 +20 +ENDCHAR +STARTCHAR uni288D +ENCODING 10381 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +00 +00 +80 +00 +20 +ENDCHAR +STARTCHAR uni288E +ENCODING 10382 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +80 +00 +80 +00 +20 +ENDCHAR +STARTCHAR uni288F +ENCODING 10383 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +80 +00 +80 +00 +20 +ENDCHAR +STARTCHAR uni2890 +ENCODING 10384 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 5 3 -1 +BITMAP +80 +00 +00 +00 +80 +ENDCHAR +STARTCHAR uni2891 +ENCODING 10385 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +20 +00 +00 +00 +20 +ENDCHAR +STARTCHAR uni2892 +ENCODING 10386 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +A0 +00 +00 +00 +20 +ENDCHAR +STARTCHAR uni2893 +ENCODING 10387 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +A0 +00 +00 +00 +20 +ENDCHAR +STARTCHAR uni2894 +ENCODING 10388 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +20 +00 +80 +00 +20 +ENDCHAR +STARTCHAR uni2895 +ENCODING 10389 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +20 +00 +80 +00 +20 +ENDCHAR +STARTCHAR uni2896 +ENCODING 10390 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +A0 +00 +80 +00 +20 +ENDCHAR +STARTCHAR uni2897 +ENCODING 10391 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +A0 +00 +80 +00 +20 +ENDCHAR +STARTCHAR uni2898 +ENCODING 10392 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 7 3 -1 +BITMAP +80 +00 +80 +00 +00 +00 +80 +ENDCHAR +STARTCHAR uni2899 +ENCODING 10393 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +20 +00 +00 +00 +20 +ENDCHAR +STARTCHAR uni289A +ENCODING 10394 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +A0 +00 +00 +00 +20 +ENDCHAR +STARTCHAR uni289B +ENCODING 10395 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +A0 +00 +00 +00 +20 +ENDCHAR +STARTCHAR uni289C +ENCODING 10396 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +20 +00 +80 +00 +20 +ENDCHAR +STARTCHAR uni289D +ENCODING 10397 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +20 +00 +80 +00 +20 +ENDCHAR +STARTCHAR uni289E +ENCODING 10398 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +A0 +00 +80 +00 +20 +ENDCHAR +STARTCHAR uni289F +ENCODING 10399 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +A0 +00 +80 +00 +20 +ENDCHAR +STARTCHAR uni28A0 +ENCODING 10400 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 3 3 -1 +BITMAP +80 +00 +80 +ENDCHAR +STARTCHAR uni28A1 +ENCODING 10401 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +00 +00 +20 +00 +20 +ENDCHAR +STARTCHAR uni28A2 +ENCODING 10402 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +80 +00 +20 +00 +20 +ENDCHAR +STARTCHAR uni28A3 +ENCODING 10403 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +80 +00 +20 +00 +20 +ENDCHAR +STARTCHAR uni28A4 +ENCODING 10404 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 -1 +BITMAP +A0 +00 +20 +ENDCHAR +STARTCHAR uni28A5 +ENCODING 10405 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +00 +00 +A0 +00 +20 +ENDCHAR +STARTCHAR uni28A6 +ENCODING 10406 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +80 +00 +A0 +00 +20 +ENDCHAR +STARTCHAR uni28A7 +ENCODING 10407 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +80 +00 +A0 +00 +20 +ENDCHAR +STARTCHAR uni28A8 +ENCODING 10408 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 7 3 -1 +BITMAP +80 +00 +00 +00 +80 +00 +80 +ENDCHAR +STARTCHAR uni28A9 +ENCODING 10409 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +00 +00 +20 +00 +20 +ENDCHAR +STARTCHAR uni28AA +ENCODING 10410 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +80 +00 +20 +00 +20 +ENDCHAR +STARTCHAR uni28AB +ENCODING 10411 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +80 +00 +20 +00 +20 +ENDCHAR +STARTCHAR uni28AC +ENCODING 10412 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +00 +00 +A0 +00 +20 +ENDCHAR +STARTCHAR uni28AD +ENCODING 10413 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +00 +00 +A0 +00 +20 +ENDCHAR +STARTCHAR uni28AE +ENCODING 10414 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +80 +00 +A0 +00 +20 +ENDCHAR +STARTCHAR uni28AF +ENCODING 10415 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +80 +00 +A0 +00 +20 +ENDCHAR +STARTCHAR uni28B0 +ENCODING 10416 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 5 3 -1 +BITMAP +80 +00 +80 +00 +80 +ENDCHAR +STARTCHAR uni28B1 +ENCODING 10417 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +20 +00 +20 +00 +20 +ENDCHAR +STARTCHAR uni28B2 +ENCODING 10418 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +A0 +00 +20 +00 +20 +ENDCHAR +STARTCHAR uni28B3 +ENCODING 10419 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +A0 +00 +20 +00 +20 +ENDCHAR +STARTCHAR uni28B4 +ENCODING 10420 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +20 +00 +A0 +00 +20 +ENDCHAR +STARTCHAR uni28B5 +ENCODING 10421 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +20 +00 +A0 +00 +20 +ENDCHAR +STARTCHAR uni28B6 +ENCODING 10422 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +A0 +00 +A0 +00 +20 +ENDCHAR +STARTCHAR uni28B7 +ENCODING 10423 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +A0 +00 +A0 +00 +20 +ENDCHAR +STARTCHAR uni28B8 +ENCODING 10424 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 1 7 3 -1 +BITMAP +80 +00 +80 +00 +80 +00 +80 +ENDCHAR +STARTCHAR uni28B9 +ENCODING 10425 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +20 +00 +20 +00 +20 +ENDCHAR +STARTCHAR uni28BA +ENCODING 10426 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +A0 +00 +20 +00 +20 +ENDCHAR +STARTCHAR uni28BB +ENCODING 10427 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +A0 +00 +20 +00 +20 +ENDCHAR +STARTCHAR uni28BC +ENCODING 10428 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +20 +00 +A0 +00 +20 +ENDCHAR +STARTCHAR uni28BD +ENCODING 10429 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +20 +00 +A0 +00 +20 +ENDCHAR +STARTCHAR uni28BE +ENCODING 10430 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +A0 +00 +A0 +00 +20 +ENDCHAR +STARTCHAR uni28BF +ENCODING 10431 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +A0 +00 +A0 +00 +20 +ENDCHAR +STARTCHAR uni28C0 +ENCODING 10432 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 1 1 -1 +BITMAP +A0 +ENDCHAR +STARTCHAR uni28C1 +ENCODING 10433 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +00 +00 +00 +00 +A0 +ENDCHAR +STARTCHAR uni28C2 +ENCODING 10434 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +80 +00 +00 +00 +A0 +ENDCHAR +STARTCHAR uni28C3 +ENCODING 10435 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +80 +00 +00 +00 +A0 +ENDCHAR +STARTCHAR uni28C4 +ENCODING 10436 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 -1 +BITMAP +80 +00 +A0 +ENDCHAR +STARTCHAR uni28C5 +ENCODING 10437 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +00 +00 +80 +00 +A0 +ENDCHAR +STARTCHAR uni28C6 +ENCODING 10438 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +80 +00 +80 +00 +A0 +ENDCHAR +STARTCHAR uni28C7 +ENCODING 10439 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +80 +00 +80 +00 +A0 +ENDCHAR +STARTCHAR uni28C8 +ENCODING 10440 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +00 +00 +00 +00 +A0 +ENDCHAR +STARTCHAR uni28C9 +ENCODING 10441 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +00 +00 +00 +00 +A0 +ENDCHAR +STARTCHAR uni28CA +ENCODING 10442 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +80 +00 +00 +00 +A0 +ENDCHAR +STARTCHAR uni28CB +ENCODING 10443 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +80 +00 +00 +00 +A0 +ENDCHAR +STARTCHAR uni28CC +ENCODING 10444 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +00 +00 +80 +00 +A0 +ENDCHAR +STARTCHAR uni28CD +ENCODING 10445 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +00 +00 +80 +00 +A0 +ENDCHAR +STARTCHAR uni28CE +ENCODING 10446 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +80 +00 +80 +00 +A0 +ENDCHAR +STARTCHAR uni28CF +ENCODING 10447 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +80 +00 +80 +00 +A0 +ENDCHAR +STARTCHAR uni28D0 +ENCODING 10448 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +20 +00 +00 +00 +A0 +ENDCHAR +STARTCHAR uni28D1 +ENCODING 10449 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +20 +00 +00 +00 +A0 +ENDCHAR +STARTCHAR uni28D2 +ENCODING 10450 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +A0 +00 +00 +00 +A0 +ENDCHAR +STARTCHAR uni28D3 +ENCODING 10451 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +A0 +00 +00 +00 +A0 +ENDCHAR +STARTCHAR uni28D4 +ENCODING 10452 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +20 +00 +80 +00 +A0 +ENDCHAR +STARTCHAR uni28D5 +ENCODING 10453 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +20 +00 +80 +00 +A0 +ENDCHAR +STARTCHAR uni28D6 +ENCODING 10454 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +A0 +00 +80 +00 +A0 +ENDCHAR +STARTCHAR uni28D7 +ENCODING 10455 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +A0 +00 +80 +00 +A0 +ENDCHAR +STARTCHAR uni28D8 +ENCODING 10456 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +20 +00 +00 +00 +A0 +ENDCHAR +STARTCHAR uni28D9 +ENCODING 10457 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +20 +00 +00 +00 +A0 +ENDCHAR +STARTCHAR uni28DA +ENCODING 10458 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +A0 +00 +00 +00 +A0 +ENDCHAR +STARTCHAR uni28DB +ENCODING 10459 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +A0 +00 +00 +00 +A0 +ENDCHAR +STARTCHAR uni28DC +ENCODING 10460 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +20 +00 +80 +00 +A0 +ENDCHAR +STARTCHAR uni28DD +ENCODING 10461 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +20 +00 +80 +00 +A0 +ENDCHAR +STARTCHAR uni28DE +ENCODING 10462 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +A0 +00 +80 +00 +A0 +ENDCHAR +STARTCHAR uni28DF +ENCODING 10463 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +A0 +00 +80 +00 +A0 +ENDCHAR +STARTCHAR uni28E0 +ENCODING 10464 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 -1 +BITMAP +20 +00 +A0 +ENDCHAR +STARTCHAR uni28E1 +ENCODING 10465 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +00 +00 +20 +00 +A0 +ENDCHAR +STARTCHAR uni28E2 +ENCODING 10466 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +80 +00 +20 +00 +A0 +ENDCHAR +STARTCHAR uni28E3 +ENCODING 10467 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +80 +00 +20 +00 +A0 +ENDCHAR +STARTCHAR uni28E4 +ENCODING 10468 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 3 1 -1 +BITMAP +A0 +00 +A0 +ENDCHAR +STARTCHAR uni28E5 +ENCODING 10469 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +00 +00 +A0 +00 +A0 +ENDCHAR +STARTCHAR uni28E6 +ENCODING 10470 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +80 +00 +A0 +00 +A0 +ENDCHAR +STARTCHAR uni28E7 +ENCODING 10471 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +80 +00 +A0 +00 +A0 +ENDCHAR +STARTCHAR uni28E8 +ENCODING 10472 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +00 +00 +20 +00 +A0 +ENDCHAR +STARTCHAR uni28E9 +ENCODING 10473 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +00 +00 +20 +00 +A0 +ENDCHAR +STARTCHAR uni28EA +ENCODING 10474 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +80 +00 +20 +00 +A0 +ENDCHAR +STARTCHAR uni28EB +ENCODING 10475 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +80 +00 +20 +00 +A0 +ENDCHAR +STARTCHAR uni28EC +ENCODING 10476 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +00 +00 +A0 +00 +A0 +ENDCHAR +STARTCHAR uni28ED +ENCODING 10477 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +00 +00 +A0 +00 +A0 +ENDCHAR +STARTCHAR uni28EE +ENCODING 10478 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +80 +00 +A0 +00 +A0 +ENDCHAR +STARTCHAR uni28EF +ENCODING 10479 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +80 +00 +A0 +00 +A0 +ENDCHAR +STARTCHAR uni28F0 +ENCODING 10480 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +20 +00 +20 +00 +A0 +ENDCHAR +STARTCHAR uni28F1 +ENCODING 10481 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +20 +00 +20 +00 +A0 +ENDCHAR +STARTCHAR uni28F2 +ENCODING 10482 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +A0 +00 +20 +00 +A0 +ENDCHAR +STARTCHAR uni28F3 +ENCODING 10483 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +A0 +00 +20 +00 +A0 +ENDCHAR +STARTCHAR uni28F4 +ENCODING 10484 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +20 +00 +A0 +00 +A0 +ENDCHAR +STARTCHAR uni28F5 +ENCODING 10485 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +20 +00 +A0 +00 +A0 +ENDCHAR +STARTCHAR uni28F6 +ENCODING 10486 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 5 1 -1 +BITMAP +A0 +00 +A0 +00 +A0 +ENDCHAR +STARTCHAR uni28F7 +ENCODING 10487 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +80 +00 +A0 +00 +A0 +00 +A0 +ENDCHAR +STARTCHAR uni28F8 +ENCODING 10488 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +20 +00 +20 +00 +A0 +ENDCHAR +STARTCHAR uni28F9 +ENCODING 10489 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +20 +00 +20 +00 +A0 +ENDCHAR +STARTCHAR uni28FA +ENCODING 10490 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +A0 +00 +20 +00 +A0 +ENDCHAR +STARTCHAR uni28FB +ENCODING 10491 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +A0 +00 +20 +00 +A0 +ENDCHAR +STARTCHAR uni28FC +ENCODING 10492 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +20 +00 +A0 +00 +A0 +ENDCHAR +STARTCHAR uni28FD +ENCODING 10493 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +20 +00 +A0 +00 +A0 +ENDCHAR +STARTCHAR uni28FE +ENCODING 10494 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +20 +00 +A0 +00 +A0 +00 +A0 +ENDCHAR +STARTCHAR uni28FF +ENCODING 10495 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 3 7 1 -1 +BITMAP +A0 +00 +A0 +00 +A0 +00 +A0 +ENDCHAR +STARTCHAR fi +ENCODING 64257 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +20 +50 +40 +F0 +50 +50 +ENDCHAR +STARTCHAR fl +ENCODING 64258 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 4 6 1 0 +BITMAP +30 +50 +50 +F0 +50 +50 +ENDCHAR +STARTCHAR uniFFFD +ENCODING 65533 +SWIDTH 640 0 +DWIDTH 6 0 +BBX 5 9 0 -2 +BITMAP +70 +D8 +A8 +E8 +D8 +D8 +F8 +D8 +70 +ENDCHAR +ENDFONT diff --git a/buildroot/share/fonts/uxggenpages.md b/buildroot/share/fonts/uxggenpages.md index 314b5d5c06c3..5e40c392f7f6 100644 --- a/buildroot/share/fonts/uxggenpages.md +++ b/buildroot/share/fonts/uxggenpages.md @@ -99,12 +99,12 @@ At this time, the font file `marlin-6x12-3.bdf` is used to generate the font dat - [WQY](http://wenq.org/) - [WQY 9pt bitmap font](http://wenq.org/daily/wqy-bitmapfont-bdf-gb18030-nightly_build.tar.gz) -- [unifont (16x8 or 16x16)](http://unifoundry.com/unifont.html) +- [unifont (16x8 or 16x16)](https://unifoundry.com/unifont.html) Documents related to the old version of the language engine: -- [Marlin Fonts Documentation](http://www.marlinfw.org/docs/development/fonts.html) -- [Marlin LCD Language](http://marlinfw.org/docs/development/lcd_language.html) +- [Marlin Fonts Documentation](https://www.marlinfw.org/docs/development/fonts.html) +- [Marlin LCD Language](https://marlinfw.org/docs/development/lcd_language.html) - [U8GLIB](https://github.com/olikraus/u8glib.git) - [UTF-8 for U8GLIB](https://github.com/yhfudev/u8glib-fontutf8.git) - [Standalone test project for the Marlin UTF-8 language engine](https://github.com/yhfudev/marlin-fontutf8.git) diff --git a/buildroot/share/fonts/uxggenpages.sh b/buildroot/share/fonts/uxggenpages.sh index 9207835148f6..a99fd9902463 100755 --- a/buildroot/share/fonts/uxggenpages.sh +++ b/buildroot/share/fonts/uxggenpages.sh @@ -139,11 +139,13 @@ BEGIN { } EOF +AWK=$(which gawk || which awk) + grep -Hrn _UxGT . | grep '"' \ | sed 's/_UxGT("/\n&/g;s/[^\n]*\n_UxGT("\([^"]*\)[^\n]*/\1 /g;s/.$//' \ | ${EXEC_GENPAGES} \ | sort -k 1n -k 2n | uniq \ - | gawk -v EXEC_PREFIX=${DN_EXEC} -f "proc.awk" \ + | "$AWK" -v EXEC_PREFIX=${DN_EXEC} -f "proc.awk" \ | while read PAGE BEGIN END UTF8BEGIN UTF8END; do \ if [ ! -f ${DN_DATA}/fontpage_${PAGE}_${BEGIN}_${END}.h ]; then \ ${EXEC_BDF2U8G} -u ${PAGE} -b ${BEGIN} -e ${END} ${FN_FONT} fontpage_${PAGE}_${BEGIN}_${END} ${DN_DATA}/fontpage_${PAGE}_${BEGIN}_${END}.h > /dev/null 2>&1 ; diff --git a/buildroot/share/git/firstpush b/buildroot/share/git/firstpush index 132795b617d6..9a68fc5afde8 100755 --- a/buildroot/share/git/firstpush +++ b/buildroot/share/git/firstpush @@ -14,11 +14,9 @@ FORK=${INFO[1]} REPO=${INFO[2]} BRANCH=${INFO[5]} -git push --set-upstream origin $BRANCH +git push --set-upstream origin HEAD:$BRANCH -which xdg-open >/dev/null && TOOL=xdg-open -which gnome-open >/dev/null && TOOL=gnome-open -which open >/dev/null && TOOL=open +OPEN=$(echo $(which gnome-open xdg-open open) | awk '{ print $1 }') URL="https://github.com/$FORK/$REPO/commits/$BRANCH" if [ -z "$OPEN" ]; then diff --git a/buildroot/share/git/ghtp b/buildroot/share/git/ghtp index f7a6263012cd..14afd8a27b7d 100755 --- a/buildroot/share/git/ghtp +++ b/buildroot/share/git/ghtp @@ -5,29 +5,35 @@ # Set all remotes in the current repo to HTTPS or SSH connection. # Useful when switching environments, using public wifi, etc. # +# Optionally, specify a particular remote to change. +# GH_SSH="git@github\.com:" GH_HTTPS="https:\/\/github\.com\/" case "$1" in - -[Hh]) TYPE=HTTPS ; MATCH="git@" ; FORMULA="$GH_SSH/$GH_HTTPS" ;; - -[Ss]) TYPE=SSH ; MATCH="https:" ; FORMULA="$GH_HTTPS/$GH_SSH" ;; + -[Hh]) TYPE=HTTPS ; MATCH="git@" ; REPLACE="$GH_SSH/$GH_HTTPS" ;; + -[Ss]) TYPE=SSH ; MATCH="https:" ; REPLACE="$GH_HTTPS/$GH_SSH" ;; *) - echo "usage: `basename $0` -h | -s" 1>&2 + echo "Usage: `basename $0` -h | -s" 1>&2 echo -e " \e[0;92m-h\e[0m to switch to HTTPS" 1>&2 echo -e " \e[0;92m-s\e[0m to switch to SSH" 1>&2 exit 1 ;; esac -REMOTES=$(git remote -v | egrep "\t$MATCH" | gawk '{print $1 " " $2}' | sort -u | sed "s/$FORMULA/") +AWK=$(which gawk || which awk) + +# Match all or specified remotes of the other type +REGEX="\t$MATCH" ; [[ $# > 1 ]] && REGEX="^$2$REGEX" + +REMOTES=$(git remote -v | egrep "$REGEX" | "$AWK" '{print $1 " " $2}' | sort -u | sed "s/$REPLACE/") -if [[ -z $REMOTES ]]; then - echo "Nothing to do." ; exit -fi +[[ -z $REMOTES ]] && { echo "Nothing to do." ; exit ; } +# Update a remote for each results pair echo "$REMOTES" | xargs -n2 git remote set-url echo -n "Remotes set to $TYPE: " -echo "$REMOTES" | gawk '{printf "%s ", $1}' +echo "$REMOTES" | "$AWK" '{printf "%s ", $1}' echo diff --git a/buildroot/share/git/mfclean b/buildroot/share/git/mfclean index f38997405bc8..fd131c42630c 100755 --- a/buildroot/share/git/mfclean +++ b/buildroot/share/git/mfclean @@ -6,6 +6,8 @@ # Great way to clean up your branches after messing around a lot # +AWK=$(which gawk || which awk) + KEEP="RC|RCBugFix|dev|master|bugfix-1|bugfix-2" echo "Fetching latest upstream and origin..." @@ -18,7 +20,7 @@ git branch --merged | egrep -v "^\*|$KEEP" | xargs -n 1 git branch -d echo echo "Pruning Remotely-deleted Branches..." -git branch -vv | egrep -v "^\*|$KEEP" | grep ': gone]' | gawk '{print $1}' | xargs -n 1 git branch -D +git branch -vv | egrep -v "^\*|$KEEP" | grep ': gone]' | "$AWK" '{print $1}' | xargs -n 1 git branch -D echo # List fork branches that don't match local branches diff --git a/buildroot/share/git/mfinfo b/buildroot/share/git/mfinfo index c7bf04fb1471..e17138e45626 100755 --- a/buildroot/share/git/mfinfo +++ b/buildroot/share/git/mfinfo @@ -49,7 +49,8 @@ while [[ $# -gt 0 ]]; do done case "$REPO" in - Marlin ) TARG=bugfix-1.1.x ; [[ $INDEX == 2 ]] && TARG=bugfix-2.0.x ; [[ $INDEX == 3 ]] && TARG=dev-2.1.x ;; + Marlin ) TARG=bugfix-2.0.x ; [[ $INDEX == 1 ]] && TARG=bugfix-1.1.x ; [[ $INDEX == 3 ]] && TARG=dev-2.1.x ;; + Configurations ) TARG=import-2.0.x ;; MarlinDocumentation ) TARG=master ;; esac diff --git a/buildroot/share/git/mfpr b/buildroot/share/git/mfpr index bff9834bc18f..b853c6929e44 100755 --- a/buildroot/share/git/mfpr +++ b/buildroot/share/git/mfpr @@ -23,9 +23,7 @@ OLDBRANCH=${INFO[5]} # See if it's been pushed yet if [ -z "$(git branch -vv | grep ^\* | grep \\[origin)" ]; then firstpush; fi -which xdg-open >/dev/null && TOOL=xdg-open -which gnome-open >/dev/null && TOOL=gnome-open -which open >/dev/null && TOOL=open +OPEN=$(echo $(which gnome-open xdg-open open) | awk '{ print $1 }') URL="https://github.com/$ORG/$REPO/compare/$TARG...$FORK:$BRANCH?expand=1" if [ -z "$OPEN" ]; then diff --git a/buildroot/share/git/mfpub b/buildroot/share/git/mfpub index 8ec28ad489a1..6a912e5515b0 100755 --- a/buildroot/share/git/mfpub +++ b/buildroot/share/git/mfpub @@ -67,11 +67,11 @@ if [[ $BRANCH == $TARG ]]; then # Allow working directly with the main fork echo echo -n "Pushing to origin/$TARG... " - git push -f origin + git push origin HEAD:$TARG echo echo -n "Pushing to upstream/$TARG... " - git push -f upstream + git push upstream HEAD:$TARG else @@ -126,7 +126,7 @@ git push -f origin git push -f upstream | { while IFS= read -r line do - [[ $line =~ "gh-pages -> gh-pages" ]] && opensite "http://marlinfw.org/" + [[ $line =~ "gh-pages -> gh-pages" ]] && opensite "https://marlinfw.org/" echo "$line" done } @@ -135,4 +135,4 @@ git push -f upstream | { rm -rf ${TMPFOLDER} # Go back to the branch we started from -[[ $BRANCH != $CURR ]] && git checkout $BRANCH && [[ $HAS_STASH == 1 ]] && git stash pop +git checkout $CURR && [[ $HAS_STASH == 1 ]] && git stash pop diff --git a/buildroot/share/git/mfrb b/buildroot/share/git/mfrb index 1edc99bbe928..071b0b3d5989 100755 --- a/buildroot/share/git/mfrb +++ b/buildroot/share/git/mfrb @@ -23,8 +23,5 @@ done [[ $USAGE == 1 ]] && { echo "usage: `basename $0` [1|2|3]" 1>&2 ; exit 1 ; } -# If the branch isn't currently the PR target -if [[ $TARG != $CURR ]]; then - [[ $QUICK ]] || git fetch upstream - git rebase upstream/$TARG && git rebase -i upstream/$TARG -fi +[[ $QUICK ]] || git fetch upstream +git rebase upstream/$TARG && git rebase -i upstream/$TARG diff --git a/buildroot/share/git/mftest b/buildroot/share/git/mftest index 0b2d9ef78f55..cfb5dd05f357 100755 --- a/buildroot/share/git/mftest +++ b/buildroot/share/git/mftest @@ -9,7 +9,8 @@ MFINFO=$(mfinfo) || exit 1 [[ -d Marlin/src ]] || { echo "Please 'cd' up to repo root." ; exit 1 ; } -TESTPATH=buildroot/share/tests +TESTPATH=buildroot/tests + STATE_FILE=$( echo ./.pio/.mftestrc ) SED=$(which gsed || which sed) @@ -34,9 +35,9 @@ case $TESTENV in lin*) TESTENV='linux_native' ;; lpc?(8)) TESTENV='LPC1768' ;; lpc9) TESTENV='LPC1769' ;; - m128) TESTENV='megaatmega1280' ;; - m256) TESTENV='megaatmega2560' ;; - mega) TESTENV='megaatmega2560' ;; + m128) TESTENV='mega1280' ;; + m256) TESTENV='mega2560' ;; + mega) TESTENV='mega2560' ;; stm) TESTENV='STM32F103RE' ;; f1) TESTENV='STM32F103RE' ;; f4) TESTENV='STM32F4' ;; @@ -47,6 +48,8 @@ case $TESTENV in t32) TESTENV='teensy31' ;; t35) TESTENV='teensy35' ;; t36) TESTENV='teensy35' ;; + t40) TESTENV='teensy41' ;; + t41) TESTENV='teensy41' ;; -h|--help) echo -e "$(basename $0) : Marlin Firmware test, build, and upload\n" echo "Usage: $(basename $0) ................. Select env and test to apply / run" @@ -55,7 +58,7 @@ case $TESTENV in echo " $(basename $0) -b [variant] .... Auto-build the specified variant" echo " $(basename $0) -u [variant] .... Auto-build and upload the specified variant" echo - echo "env shortcuts: tree due esp lin lpc|lpc8 lpc9 m128 m256|mega stm|f1 f4 f7 s6 teensy|t31|t32 t35|t36" + echo "env shortcuts: tree due esp lin lpc|lpc8 lpc9 m128 m256|mega stm|f1 f4 f7 s6 teensy|t31|t32 t35|t36 t40|t41" exit ;; @@ -215,6 +218,9 @@ echo "$OUT" | { done } +# Make clear it's a TEST +opt_set CUSTOM_MACHINE_NAME "\"$TESTENV-tests ($CHOICE)\"" + # Get a -y parameter the lazy way [[ "$2" == "-y" || "$3" == "-y" ]] && BUILD_YES='Y' diff --git a/buildroot/share/scripts/MarlinMesh.scad b/buildroot/share/scripts/MarlinMesh.scad index 7616ded699a0..6d78bb96492d 100644 --- a/buildroot/share/scripts/MarlinMesh.scad +++ b/buildroot/share/scripts/MarlinMesh.scad @@ -10,17 +10,13 @@ * * \**************************************/ -//$t = 0.15; // comment out during animation +$t = 0.15; // comment out during animation! +X = 0; Y = 1; +L = 0; R = 1; F = 2; B = 3; // -// Mesh info and points +// Sample Mesh - Replace with your own // - -mesh_width = 200; // X Size in mm of the probed area -mesh_height = 200; // Y Size... -zprobe_offset = 0; // Added to the points -NAN = 0; // Z to use for un-measured points - measured_z = [ [ -1.20, -1.13, -1.09, -1.03, -1.19 ], [ -1.16, -1.25, -1.27, -1.25, -1.08 ], @@ -29,6 +25,28 @@ measured_z = [ [ -1.13, -0.99, -1.03, -1.06, -1.32 ] ]; +// +// An offset to add to all points in the mesh +// +zadjust = 0; + +// +// Mesh characteristics +// +bed_size = [ 200, 200 ]; + +mesh_inset = [ 10, 10, 10, 10 ]; // L, F, R, B + +mesh_bounds = [ + [ mesh_inset[L], mesh_inset[F] ], + [ bed_size[X] - mesh_inset[R], bed_size[Y] - mesh_inset[B] ] +]; + +mesh_size = mesh_bounds[1] - mesh_bounds[0]; + + // NOTE: Marlin meshes already subtract the probe offset +NAN = 0; // Z to use for un-measured points + // // Geometry // @@ -45,6 +63,7 @@ alternation = 2; // direction change modulus (try it) show_plane = true; show_labels = true; +show_coords = true; arrow_length = 5; label_font_lg = "Arial"; @@ -62,8 +81,8 @@ mean_value = (big_z + lil_z) / 2.0; mesh_points_y = len(measured_z); mesh_points_x = len(measured_z[0]); -xspace = mesh_width / (mesh_points_x - 1); -yspace = mesh_height / (mesh_points_y - 1); +xspace = mesh_size[X] / (mesh_points_x - 1); +yspace = mesh_size[Y] / (mesh_points_y - 1); // At $t=0 and $t=1 scale will be 100% z_scale_factor = min_z_scale + (($t > 0.5) ? 1.0 - $t : $t) * (max_z_scale - min_z_scale) * 2; @@ -72,6 +91,8 @@ z_scale_factor = min_z_scale + (($t > 0.5) ? 1.0 - $t : $t) * (max_z_scale - min // Min and max recursive functions for 1D and 2D arrays // Return the smallest or largest value in the array // +function some_1D(b,i) = (i//" +# ... or similar path leading to this file. +# +# Warning: The program modifies files in place, so be sure to back them up first if needed. +# Can be run multiple times if needed. Only modifies files which don't have +# correct #define CONFIG_EXAMPLES_DIR line. +# +# Invocation: +#------------- +# 1. Change directory to your MarlinFirmware/Configurations working copy +# 2. python3 config-labels.py +# +#----------------------------------- +# 2020-05-10 GMW original +# 2020-06-05 SRL style tweaks +#----------------------------------- +# +import sys +import os +from pathlib import Path +from distutils.dir_util import copy_tree # for copy_tree, because shutil.copytree can't handle existing files, dirs + +# Modify input_examples_dir and output_examples_dir for your installation +# No trailing slash +# Setting output_examples_dir = input_examples_dir causes the program to insert into the existing files. + +input_examples_dir = r'config/examples' +# output_examples_dir = input_examples_dir +output_examples_dir = r'config/examples' + +#------------------------------------- + +files_to_mod = ['Configuration.h', 'Configuration_adv.h', '_Bootscreen.h', '_Statusscreen.h'] + +macro_name = 'CONFIG_EXAMPLES_DIR' +def_macro_name = '#define ' + macro_name + +filenum = 0 +different_out_dir = not (output_examples_dir == input_examples_dir) + +#---------------------------------------------- +def process_file(subdir: str, filename: str): +#---------------------------------------------- + global filenum + filenum += 1 + + print(str(filenum) + ' ' + filename + ': ' + subdir) + + def_line = (def_macro_name + ' "' + subdir.replace('\\', '/') + '"') + + #------------------------ + # Read file + #------------------------ + lines = [] + infilepath = os.path.join(input_examples_dir, subdir, filename) + try: + # UTF-8 because some files contain unicode chars + with open(infilepath, 'rt', encoding="utf-8") as infile: + lines = infile.readlines() + + except Exception as e: + print('Failed to read file: ' + str(e) ) + raise Exception + + lines = [line.rstrip('\r\n') for line in lines] + + #------------------------ + # Process lines + #------------------------ + file_modified = False + + # region state machine + # -1 = before pragma once; + # 0 = region to place define; + # 1 = past region to place define + region = -1 + + outlines = [] + for line in lines: + outline = line + + if (region == -1) and (def_macro_name in line): + outline = None + file_modified = True + + elif (region == -1) and ('pragma once' in line): + region = 0 + + elif (region == 0): + if (line.strip() == ''): + pass + elif (def_macro_name in line): + region = 1 + if line == def_line: # leave it as is + pass + else: + outline = def_line + file_modified = True + else: # some other string + outlines.append(def_line) + outlines.append('') + region = 1 + file_modified = True + + elif (region == 1): + if (def_macro_name in line): + outline = None + file_modified = True + else: + pass + + # end if + if outline is not None: + outlines.append(outline) + # end for + + #------------------------- + # Output file + #------------------------- + outdir = os.path.join(output_examples_dir, subdir) + outfilepath = os.path.join(outdir, filename) + + if file_modified: + # Note: no need to create output dirs, as the initial copy_tree + # will do that. + + print(' writing ' + str(outfilepath)) + try: + # Preserve unicode chars; Avoid CR-LF on Windows. + with open(outfilepath, "w", encoding="utf-8", newline='\n') as outfile: + outfile.write("\n".join(outlines)) + outfile.write("\n") + + except Exception as e: + print('Failed to write file: ' + str(e) ) + raise Exception + else: + print(' no change for ' + str(outfilepath)) + +#---------- +def main(): +#---------- + global filenum + global input_examples_dir + global output_examples_dir + filenum = 0 + + #-------------------------------- + # Check for requirements + #-------------------------------- + input_examples_dir = input_examples_dir.strip() + input_examples_dir = input_examples_dir.rstrip('\\/') + output_examples_dir = output_examples_dir.strip() + output_examples_dir = output_examples_dir.rstrip('\\/') + + for dir in [input_examples_dir, output_examples_dir]: + if not (os.path.exists(dir)): + print('Directory not found: ' + dir) + sys.exit(1) + + #-------------------------------- + # Copy tree if necessary. + #-------------------------------- + # This includes files that are not otherwise included in the + # insertion of the define statement. + # + if different_out_dir: + print('Copying files to new directory: ' + output_examples_dir) + try: + copy_tree(input_examples_dir, output_examples_dir) + except Exception as e: + print('Failed to copy directory: ' + str(e) ) + raise Exception + + #----------------------------- + # Find and process files + #----------------------------- + len_input_examples_dir = len(input_examples_dir); + len_input_examples_dir += 1 + + for filename in files_to_mod: + input_path = Path(input_examples_dir) + filepathlist = input_path.rglob(filename) + + for filepath in filepathlist: + fulldirpath = str(filepath.parent) + subdir = fulldirpath[len_input_examples_dir:] + + process_file(subdir, filename) + +#============== +print('--- Starting config-labels ---') +main() +print('--- Done ---') diff --git a/buildroot/share/scripts/createTemperatureLookupMarlin.py b/buildroot/share/scripts/createTemperatureLookupMarlin.py index 03450bc0e0be..b2d8964f556c 100755 --- a/buildroot/share/scripts/createTemperatureLookupMarlin.py +++ b/buildroot/share/scripts/createTemperatureLookupMarlin.py @@ -2,10 +2,10 @@ """Thermistor Value Lookup Table Generator Generates lookup to temperature values for use in a microcontroller in C format based on: -http://en.wikipedia.org/wiki/Steinhart-Hart_equation +https://en.wikipedia.org/wiki/Steinhart-Hart_equation The main use is for Arduino programs that read data from the circuit board described here: -http://reprap.org/wiki/Temperature_Sensor_v2.0 +https://reprap.org/wiki/Temperature_Sensor_v2.0 Usage: python createTemperatureLookupMarlin.py [options] diff --git a/buildroot/share/scripts/pinsformat.js b/buildroot/share/scripts/pinsformat.js new file mode 100755 index 000000000000..a82c2f2659f0 --- /dev/null +++ b/buildroot/share/scripts/pinsformat.js @@ -0,0 +1,170 @@ +#!/usr/bin/env node + +// +// Formatter script for pins_MYPINS.h files +// +// Usage: mffmt [infile] [outfile] +// +// With no parameters convert STDIN to STDOUT +// + +const fs = require("fs"); + +// String lpad / rpad +String.prototype.lpad = function(len, chr) { + if (!len) return this; + if (chr === undefined) chr = ' '; + var s = this+'', need = len - s.length; + if (need > 0) s = new Array(need+1).join(chr) + s; + return s; +}; + +String.prototype.rpad = function(len, chr) { + if (!len) return this; + if (chr === undefined) chr = ' '; + var s = this+'', need = len - s.length; + if (need > 0) s += new Array(need+1).join(chr); + return s; +}; + +const mpatt = [ '-?\\d+', 'P[A-I]\\d+', 'P\\d_\\d+' ], + definePatt = new RegExp(`^\\s*(//)?#define\\s+[A-Z_][A-Z0-9_]+\\s+(${mpatt[0]}|${mpatt[1]}|${mpatt[2]})\\s*(//.*)?$`, 'gm'), + ppad = [ 3, 4, 5 ], + col_comment = 50, + col_value_rj = col_comment - 3; + +var mexpr = []; +for (let m of mpatt) mexpr.push(new RegExp('^' + m + '$')); + +const argv = process.argv.slice(2), argc = argv.length; + +var src_file = 0, src_name = 'STDIN', dst_file, do_log = false; +if (argc > 0) { + let ind = 0; + if (argv[0] == '-v') { do_log = true; ind++; } + dst_file = src_file = src_name = argv[ind++]; + if (ind < argc) dst_file = argv[ind]; +} + +// Read from file or STDIN until it terminates +const filtered = process_text(fs.readFileSync(src_file).toString()); +if (dst_file) + fs.writeFileSync(dst_file, filtered); +else + console.log(filtered); + +// Find the pin pattern so non-pin defines can be skipped +function get_pin_pattern(txt) { + var r, m = 0, match_count = [ 0, 0, 0 ]; + definePatt.lastIndex = 0; + while ((r = definePatt.exec(txt)) !== null) { + let ind = -1; + if (mexpr.some((p) => { + ind++; + const didmatch = r[2].match(p); + return r[2].match(p); + }) ) { + const m = ++match_count[ind]; + if (m >= 10) { + return { match: mpatt[ind], pad:ppad[ind] }; + } + } + } + return null; +} + +function process_text(txt) { + if (!txt.length) return '(no text)'; + const patt = get_pin_pattern(txt); + if (!patt) return txt; + const pindefPatt = new RegExp(`^(\\s*(//)?#define)\\s+([A-Z_][A-Z0-9_]+)\\s+(${patt.match})\\s*(//.*)?$`), + noPinPatt = new RegExp(`^(\\s*(//)?#define)\\s+([A-Z_][A-Z0-9_]+)\\s+(-1)\\s*(//.*)?$`), + skipPatt = new RegExp('^(\\s*(//)?#define)\\s+(AT90USB|USBCON|BOARD_.+|.+_MACHINE_NAME|.+_SERIAL)\\s+(.+)\\s*(//.*)?$'), + aliasPatt = new RegExp('^(\\s*(//)?#define)\\s+([A-Z_][A-Z0-9_]+)\\s+([A-Z_][A-Z0-9_()]+)\\s*(//.*)?$'), + switchPatt = new RegExp('^(\\s*(//)?#define)\\s+([A-Z_][A-Z0-9_]+)\\s*(//.*)?$'), + undefPatt = new RegExp('^(\\s*(//)?#undef)\\s+([A-Z_][A-Z0-9_]+)\\s*(//.*)?$'), + defPatt = new RegExp('^(\\s*(//)?#define)\\s+([A-Z_][A-Z0-9_]+)\\s+([-_\\w]+)\\s*(//.*)?$'), + condPatt = new RegExp('^(\\s*(//)?#(if|ifn?def|else|elif)(\\s+\\S+)*)\\s+(//.*)$'), + commPatt = new RegExp('^\\s{20,}(//.*)?$'); + const col_value_lj = col_comment - patt.pad - 2; + var r, out = '', check_comment_next = false; + txt.split('\n').forEach((line) => { + if (check_comment_next) + check_comment_next = ((r = commPatt.exec(line)) !== null); + + if (check_comment_next) + // Comments in column 45 + line = ''.rpad(col_comment) + r[1]; + + else if ((r = pindefPatt.exec(line)) !== null) { + // + // #define MY_PIN [pin] + // + if (do_log) console.log("pin:", line); + const pinnum = r[4].charAt(0) == 'P' ? r[4] : r[4].lpad(patt.pad); + line = r[1] + ' ' + r[3]; + line = line.rpad(col_value_lj) + pinnum; + if (r[5]) line = line.rpad(col_comment) + r[5]; + } + else if ((r = noPinPatt.exec(line)) !== null) { + // + // #define MY_PIN -1 + // + if (do_log) console.log("pin -1:", line); + line = r[1] + ' ' + r[3]; + line = line.rpad(col_value_lj) + '-1'; + if (r[5]) line = line.rpad(col_comment) + r[5]; + } + else if ((r = skipPatt.exec(line)) !== null) { + // + // #define SKIP_ME + // + if (do_log) console.log("skip:", line); + } + else if ((r = aliasPatt.exec(line)) !== null) { + // + // #define ALIAS OTHER + // + if (do_log) console.log("alias:", line); + line = r[1] + ' ' + r[3]; + line += r[4].lpad(col_value_rj + 1 - line.length); + if (r[5]) line = line.rpad(col_comment) + r[5]; + } + else if ((r = switchPatt.exec(line)) !== null) { + // + // #define SWITCH + // + if (do_log) console.log("switch:", line); + line = r[1] + ' ' + r[3]; + if (r[4]) line = line.rpad(col_comment) + r[4]; + check_comment_next = true; + } + else if ((r = defPatt.exec(line)) !== null) { + // + // #define ... + // + if (do_log) console.log("def:", line); + line = r[1] + ' ' + r[3] + ' '; + line += r[4].lpad(col_value_rj + 1 - line.length); + if (r[5]) line = line.rpad(col_comment - 1) + ' ' + r[5]; + } + else if ((r = undefPatt.exec(line)) !== null) { + // + // #undef ... + // + if (do_log) console.log("undef:", line); + line = r[1] + ' ' + r[3]; + if (r[4]) line = line.rpad(col_comment) + r[4]; + } + else if ((r = condPatt.exec(line)) !== null) { + // + // #if ... + // + if (do_log) console.log("cond:", line); + line = r[1].rpad(col_comment) + r[5]; + check_comment_next = true; + } + out += line + '\n'; + }); + return out.replace(/\n\n+/g, '\n\n').replace(/\n\n$/g, '\n'); +} diff --git a/buildroot/share/sublime/MarlinFirmware.sublime-project b/buildroot/share/sublime/MarlinFirmware.sublime-project index e437369ec243..9b5234f7a13c 100644 --- a/buildroot/share/sublime/MarlinFirmware.sublime-project +++ b/buildroot/share/sublime/MarlinFirmware.sublime-project @@ -8,7 +8,6 @@ "MarlinFirmware/lib", "Marlin/lib", "datatmp", - "Marlin/*/src", ".vscode" ], "binary_file_patterns": diff --git a/buildroot/share/sublime/RepRapTools/syntax_test_G-code.gcode b/buildroot/share/sublime/RepRapTools/syntax_test_G-code.gcode index 2d3a4738eba6..643f271f1e80 100644 --- a/buildroot/share/sublime/RepRapTools/syntax_test_G-code.gcode +++ b/buildroot/share/sublime/RepRapTools/syntax_test_G-code.gcode @@ -93,7 +93,7 @@ N234 G1 X-5 Y+2 *64 error ; ^constant.numeric.checksum.gcode ; ^invalid.error.syntax.gcode -N234 M107 *64 +N234 M107 *64 ; ^-invalid.error.syntax.gcode M92 E304.5:304.5:420:420:420:420 ; EOL Comment diff --git a/buildroot/share/tests/BIGTREE_SKR_PRO-tests b/buildroot/share/tests/BIGTREE_SKR_PRO-tests deleted file mode 100644 index 094e01d9c73a..000000000000 --- a/buildroot/share/tests/BIGTREE_SKR_PRO-tests +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env bash -# -# Build tests for STM32F407ZG BigTreeTech SKR Pro -# - -# exit on first failure -set -e - -# -# Build with the default configurations -# -restore_configs -opt_set MOTHERBOARD BOARD_BTT_SKR_PRO_V1_1 -opt_set SERIAL_PORT 1 -exec_test $1 $2 "BigTreeTech SKR Pro Default Configuration" - -# clean up -restore_configs diff --git a/buildroot/share/tests/SAMD51_grandcentral_m4-tests b/buildroot/share/tests/SAMD51_grandcentral_m4-tests deleted file mode 100644 index f7157b1ed8b1..000000000000 --- a/buildroot/share/tests/SAMD51_grandcentral_m4-tests +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash -# -# Build tests for Adafruit Grand Central M4 (ATMEL ARM Cortex-M4) -# - -# exit on first failure -set -e - -# -# Build with the default configurations -# -restore_configs -opt_set MOTHERBOARD BOARD_AGCM4_RAMPS_144 -exec_test $1 $2 "Build Grand Central M4 Default Configuration" - -# clean up -restore_configs diff --git a/buildroot/share/tests/STM32F103RC_bigtree-tests b/buildroot/share/tests/STM32F103RC_bigtree-tests deleted file mode 100644 index 8805c748af69..000000000000 --- a/buildroot/share/tests/STM32F103RC_bigtree-tests +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash -# -# Build tests for STM32F103RC BigTreeTech (SKR Mini E3) -# - -# exit on first failure -set -e - -# -# Build with the default configurations -# -restore_configs -opt_set MOTHERBOARD BOARD_BTT_SKR_MINI_E3_V1_0 -opt_set SERIAL_PORT 1 -opt_set SERIAL_PORT_2 -1 -exec_test $1 $2 "BigTreeTech SKR Mini E3 - Basic Configuration" - -# clean up -restore_configs diff --git a/buildroot/share/tests/megaatmega1280-tests b/buildroot/share/tests/megaatmega1280-tests deleted file mode 100644 index 4e5ad253552f..000000000000 --- a/buildroot/share/tests/megaatmega1280-tests +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash -# -# Build tests for AVR ATmega1280 -# - -# exit on first failure -set -e - -# -# Build with the default configurations -# -#restore_configs -#exec_test $1 $2 "Default Configuration" - -# -# Test MESH_BED_LEVELING feature, with LCD -# -restore_configs -opt_set LCD_LANGUAGE an -opt_enable SPINDLE_FEATURE ULTIMAKERCONTROLLER LCD_BED_LEVELING \ - MESH_BED_LEVELING ENABLE_LEVELING_FADE_HEIGHT MESH_G28_REST_ORIGIN \ - G26_MESH_VALIDATION MESH_EDIT_MENU GCODE_QUOTED_STRINGS -exec_test $1 $2 "Spindle, MESH_BED_LEVELING, and LCD" - - -# clean up -restore_configs diff --git a/buildroot/share/tests/mks_robin_nano-tests b/buildroot/share/tests/mks_robin_nano-tests deleted file mode 100644 index 809fd6e6f503..000000000000 --- a/buildroot/share/tests/mks_robin_nano-tests +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -# -# Build tests for STM32F1 genericSTM32F103VE -# - -# exit on first failure -set -e - -use_example_configs Mks/Robin -opt_set MOTHERBOARD BOARD_MKS_ROBIN_NANO -exec_test $1 $2 "Default Configuration" - -# cleanup -restore_configs diff --git a/buildroot/share/tests/rambo-tests b/buildroot/share/tests/rambo-tests deleted file mode 100644 index 3f741fcba6b3..000000000000 --- a/buildroot/share/tests/rambo-tests +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env bash -# -# Build tests for AVR ATmega2560 RAMBo -# - -# exit on first failure -set -e - -# -# Build with the default configurations -# -restore_configs -opt_set MOTHERBOARD BOARD_EINSY_RAMBO -opt_set X_DRIVER_TYPE TMC2130 -opt_set Y_DRIVER_TYPE TMC2130 -opt_set Z_DRIVER_TYPE TMC2130 -opt_set E0_DRIVER_TYPE TMC2130 -exec_test $1 $2 "Default Configuration" - -# -# Full size Rambo Dual Endstop CNC -# -restore_configs -opt_set MOTHERBOARD BOARD_RAMBO -opt_set EXTRUDERS 0 -opt_set TEMP_SENSOR_0 999 -opt_set DUMMY_THERMISTOR_999_VALUE 170 -opt_set DIGIPOT_MOTOR_CURRENT '{ 120, 120, 120, 120, 120 }' -opt_enable USE_XMAX_PLUG USE_YMAX_PLUG USE_ZMAX_PLUG \ - REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER REVERSE_ENCODER_DIRECTION SDSUPPORT EEPROM_SETTINGS \ - S_CURVE_ACCELERATION X_DUAL_STEPPER_DRIVERS X_DUAL_ENDSTOPS Y_DUAL_STEPPER_DRIVERS Y_DUAL_ENDSTOPS \ - ADAPTIVE_STEP_SMOOTHING CNC_COORDINATE_SYSTEMS GCODE_MOTION_MODES -opt_disable MIN_SOFTWARE_ENDSTOP_Z MAX_SOFTWARE_ENDSTOPS -exec_test $1 $2 "Rambo CNC Configuration" - -# clean up -restore_configs diff --git a/buildroot/share/vscode/auto_build.py b/buildroot/share/vscode/auto_build.py index f9258846a57b..5dd2d0d8a3fc 100644 --- a/buildroot/share/vscode/auto_build.py +++ b/buildroot/share/vscode/auto_build.py @@ -18,7 +18,7 @@ # 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 . +# along with this program. If not, see . # ####################################### @@ -600,13 +600,13 @@ def invalid_board(): target_env = 'DUE_USB' else: target_env = 'DUE' - elif env_A == 'STM32F103RC_bigtree' or env_A == 'STM32F103RE_bigtree': - if env_A == 'STM32F103RE_bigtree': + elif env_A == 'STM32F103RC_btt' or env_A == 'STM32F103RE_btt': + if env_A == 'STM32F103RE_btt': get_answer(board_name, 'MCU Type?', 'STM32F103RC', 'STM32F103RE') if 1 == get_answer_val: - env_A = 'STM32F103RC_bigtree' + env_A = 'STM32F103RC_btt' target_env = env_A - if env_A == 'STM32F103RC_bigtree': + if env_A == 'STM32F103RC_btt': get_answer(board_name, 'RCT6 Flash Size?', '512K', '256K') if 1 == get_answer_val: target_env += '_512K' diff --git a/buildroot/share/vscode/avrdude.conf b/buildroot/share/vscode/avrdude.conf index 1194847f775d..991d255750f5 100644 --- a/buildroot/share/vscode/avrdude.conf +++ b/buildroot/share/vscode/avrdude.conf @@ -145,13 +145,13 @@ # VCC pins are not defined for the programmer, a message # indicating that the device needs a power-cycle is printed out. # This flag was added to work around a problem with the -# at90s4433/2333's; see the at90s4433 errata at: +# at90s4433/2333's; see the at90s4433 errata page 2 at: # -# http://www.atmel.com/atmel/acrobat/doc1280.pdf +# https://ww1.microchip.com/downloads/en/AppNotes/doc2574.pdf # # INSTRUCTION FORMATS # -# Instruction formats are specified as a comma seperated list of +# Instruction formats are specified as a comma separated list of # string values containing information (bit specifiers) about each # of the 32 bits of the instruction. Bit specifiers may be one of # the following formats: @@ -416,13 +416,13 @@ programmer programmer id = "usbasp"; - desc = "USBasp, http://www.fischl.de/usbasp/"; + desc = "USBasp, https://www.fischl.de/usbasp/"; type = usbasp; ; programmer id = "usbtiny"; - desc = "USBtiny simple USB programmer, http://www.ladyada.net/make/usbtinyisp/"; + desc = "USBtiny simple USB programmer, https://learn.adafruit.com/usbtinyisp"; type = usbtiny; ; @@ -596,7 +596,7 @@ programmer programmer id = "bsd"; - desc = "Brian Dean's Programmer, http://www.bsdhome.com/avrdude/"; + desc = "Brian Dean's Programmer, https://savannah.nongnu.org/projects/avrdude"; type = par; vcc = 2, 3, 4, 5; reset = 7; @@ -743,7 +743,7 @@ programmer programmer id = "atisp"; - desc = "AT-ISP V1.1 programming cable for AVR-SDK1 from micro-research.co.th"; + desc = "AT-ISP V1.1 programming cable for AVR-SDK1 from micro-research.co.th"; type = par; reset = ~6; sck = ~8; @@ -753,7 +753,7 @@ programmer programmer id = "ere-isp-avr"; - desc = "ERE ISP-AVR "; + desc = "ERE ISP-AVR "; type = par; reset = ~4; sck = 3; @@ -773,7 +773,7 @@ programmer ; # It is almost same as pony-stk200, except vcc on pin 5 to auto -# disconnect port (download on http://electropol.free.fr) +# disconnect port download on http://www.electropol.fr programmer id = "frank-stk200"; desc = "Frank STK200"; @@ -787,7 +787,7 @@ programmer ; # The AT98ISP Cable is a simple parallel dongle for AT89 family. -# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2877 +# https://www.microchip.com/wwwAppNotes/AppNotes.aspx?appnote=en592141 programmer id = "89isp"; desc = "Atmel at89isp cable"; diff --git a/buildroot/share/vscode/avrdude_linux.conf b/buildroot/share/vscode/avrdude_linux.conf index 46e7ace34b21..ff429a028cca 100644 --- a/buildroot/share/vscode/avrdude_linux.conf +++ b/buildroot/share/vscode/avrdude_linux.conf @@ -145,13 +145,13 @@ # VCC pins are not defined for the programmer, a message # indicating that the device needs a power-cycle is printed out. # This flag was added to work around a problem with the -# at90s4433/2333's; see the at90s4433 errata at: +# at90s4433/2333's; see the at90s4433 errata page 2 at: # -# http://www.atmel.com/atmel/acrobat/doc1280.pdf +# https://ww1.microchip.com/downloads/en/AppNotes/doc2574.pdf # # INSTRUCTION FORMATS # -# Instruction formats are specified as a comma seperated list of +# Instruction formats are specified as a comma separated list of # string values containing information (bit specifiers) about each # of the 32 bits of the instruction. Bit specifiers may be one of # the following formats: @@ -416,13 +416,13 @@ programmer programmer id = "usbasp"; - desc = "USBasp, http://www.fischl.de/usbasp/"; + desc = "USBasp, https://www.fischl.de/usbasp/"; type = usbasp; ; programmer id = "usbtiny"; - desc = "USBtiny simple USB programmer, http://www.ladyada.net/make/usbtinyisp/"; + desc = "USBtiny simple USB programmer, https://learn.adafruit.com/usbtinyisp"; type = usbtiny; ; @@ -596,7 +596,7 @@ programmer programmer id = "bsd"; - desc = "Brian Dean's Programmer, http://www.bsdhome.com/avrdude/"; + desc = "Brian Dean's Programmer, https://savannah.nongnu.org/projects/avrdude"; type = par; vcc = 2, 3, 4, 5; reset = 7; @@ -743,7 +743,7 @@ programmer programmer id = "atisp"; - desc = "AT-ISP V1.1 programming cable for AVR-SDK1 from micro-research.co.th"; + desc = "AT-ISP V1.1 programming cable for AVR-SDK1 from micro-research.co.th"; type = par; reset = ~6; sck = ~8; @@ -753,7 +753,7 @@ programmer programmer id = "ere-isp-avr"; - desc = "ERE ISP-AVR "; + desc = "ERE ISP-AVR "; type = par; reset = ~4; sck = 3; @@ -773,7 +773,7 @@ programmer ; # It is almost same as pony-stk200, except vcc on pin 5 to auto -# disconnect port (download on http://electropol.free.fr) +# disconnect port download on http://www.electropol.fr programmer id = "frank-stk200"; desc = "Frank STK200"; @@ -787,7 +787,7 @@ programmer ; # The AT98ISP Cable is a simple parallel dongle for AT89 family. -# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2877 +# https://www.microchip.com/wwwAppNotes/AppNotes.aspx?appnote=en592141 programmer id = "89isp"; desc = "Atmel at89isp cable"; diff --git a/buildroot/share/vscode/avrdude_macOS.conf b/buildroot/share/vscode/avrdude_macOS.conf index d933567452fc..6147a2259ac9 100644 --- a/buildroot/share/vscode/avrdude_macOS.conf +++ b/buildroot/share/vscode/avrdude_macOS.conf @@ -145,13 +145,13 @@ # VCC pins are not defined for the programmer, a message # indicating that the device needs a power-cycle is printed out. # This flag was added to work around a problem with the -# at90s4433/2333's; see the at90s4433 errata at: +# at90s4433/2333's; see the at90s4433 errata page 2 at: # -# http://www.atmel.com/atmel/acrobat/doc1280.pdf +# https://ww1.microchip.com/downloads/en/AppNotes/doc2574.pdf # # INSTRUCTION FORMATS # -# Instruction formats are specified as a comma seperated list of +# Instruction formats are specified as a comma separated list of # string values containing information (bit specifiers) about each # of the 32 bits of the instruction. Bit specifiers may be one of # the following formats: @@ -416,13 +416,13 @@ programmer programmer id = "usbasp"; - desc = "USBasp, http://www.fischl.de/usbasp/"; + desc = "USBasp, https://www.fischl.de/usbasp/"; type = usbasp; ; programmer id = "usbtiny"; - desc = "USBtiny simple USB programmer, http://www.ladyada.net/make/usbtinyisp/"; + desc = "USBtiny simple USB programmer, https://learn.adafruit.com/usbtinyisp"; type = usbtiny; ; diff --git a/buildroot/tests/.gitattributes b/buildroot/tests/.gitattributes new file mode 100644 index 000000000000..6313b56c5784 --- /dev/null +++ b/buildroot/tests/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/buildroot/share/tests/ARMED-tests b/buildroot/tests/ARMED-tests similarity index 56% rename from buildroot/share/tests/ARMED-tests rename to buildroot/tests/ARMED-tests index 44af749a4827..e5959a4383a7 100644 --- a/buildroot/share/tests/ARMED-tests +++ b/buildroot/tests/ARMED-tests @@ -9,8 +9,11 @@ set -e # # Build with the default configurations # +restore_configs use_example_configs ArmEd -exec_test $1 $2 "ArmEd Example Configuration" +opt_set X_DRIVER_TYPE TMC2130 +opt_set Y_DRIVER_TYPE TMC2208 +exec_test $1 $2 "ArmEd Example Configuration with mixed TMC Drivers" # clean up restore_configs diff --git a/buildroot/tests/BIGTREE_BTT002-tests b/buildroot/tests/BIGTREE_BTT002-tests new file mode 100644 index 000000000000..64e6322ecad4 --- /dev/null +++ b/buildroot/tests/BIGTREE_BTT002-tests @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +# +# Build tests for STM32F407VGT6 BigTreeTech BTT002 V1.0 +# + +# exit on first failure +set -e + +# +# Build with the default configurations +# +restore_configs +opt_set MOTHERBOARD BOARD_BTT_BTT002_V1_0 +opt_set SERIAL_PORT 1 +opt_set X_DRIVER_TYPE TMC2209 +opt_set Y_DRIVER_TYPE TMC2130 +exec_test $1 $2 "BigTreeTech BTT002 Default Configuration plus TMC steppers" + +# clean up +restore_configs diff --git a/buildroot/tests/BIGTREE_GTR_V1_0-tests b/buildroot/tests/BIGTREE_GTR_V1_0-tests new file mode 100644 index 000000000000..e8d47562aa61 --- /dev/null +++ b/buildroot/tests/BIGTREE_GTR_V1_0-tests @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# +# Build tests for BigTreeTech GTR 1.0 +# + +# exit on first failure +set -e + +restore_configs +opt_set MOTHERBOARD BOARD_BTT_GTR_V1_0 +opt_set SERIAL_PORT -1 +opt_set EXTRUDERS 8 +opt_set TEMP_SENSOR_1 1 +opt_set TEMP_SENSOR_2 1 +opt_set TEMP_SENSOR_3 1 +opt_set TEMP_SENSOR_4 1 +opt_set TEMP_SENSOR_5 1 +opt_set TEMP_SENSOR_6 1 +opt_set TEMP_SENSOR_7 1 +# Not necessary to enable auto-fan for all extruders to hit problematic code paths +opt_set E0_AUTO_FAN_PIN PC10 +opt_set E1_AUTO_FAN_PIN PC11 +opt_set E2_AUTO_FAN_PIN PC12 +opt_set X_DRIVER_TYPE TMC2208 +opt_set Y_DRIVER_TYPE TMC2130 +opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER +exec_test $1 $2 "BigTreeTech GTR 8 Extruders with Auto-Fan and Mixed TMC Drivers" + +restore_configs +opt_set MOTHERBOARD BOARD_BTT_GTR_V1_0 +opt_set SERIAL_PORT -1 +opt_set EXTRUDERS 6 +opt_set TEMP_SENSOR_1 1 +opt_set TEMP_SENSOR_2 1 +opt_set TEMP_SENSOR_3 1 +opt_set TEMP_SENSOR_4 1 +opt_set TEMP_SENSOR_5 1 +opt_set NUM_Z_STEPPER_DRIVERS 3 +opt_set DEFAULT_Kp_LIST "{ 22.2, 20.0, 21.0, 19.0, 18.0, 17.0 }" +opt_set DEFAULT_Ki_LIST "{ 1.08 }" +opt_set DEFAULT_Kd_LIST "{ 114.0, 112.0, 110.0, 108.0 }" +opt_enable TOOLCHANGE_FILAMENT_SWAP TOOLCHANGE_MIGRATION_FEATURE TOOLCHANGE_FS_INIT_BEFORE_SWAP TOOLCHANGE_FS_PRIME_FIRST_USED PID_PARAMS_PER_HOTEND +exec_test $1 $2 "BigTreeTech GTR 6 Extruders Triple Z" + +# clean up +restore_configs diff --git a/buildroot/tests/BIGTREE_SKR_PRO-tests b/buildroot/tests/BIGTREE_SKR_PRO-tests new file mode 100644 index 000000000000..1295f5858c7e --- /dev/null +++ b/buildroot/tests/BIGTREE_SKR_PRO-tests @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# +# Build tests for STM32F407ZG BigTreeTech SKR Pro +# + +# exit on first failure +set -e + +# +# Build with the default configurations +# +restore_configs +opt_set MOTHERBOARD BOARD_BTT_SKR_PRO_V1_1 +opt_set SERIAL_PORT 1 +exec_test $1 $2 "BigTreeTech SKR Pro Default Configuration" + +restore_configs +opt_set MOTHERBOARD BOARD_BTT_SKR_PRO_V1_1 +opt_set SERIAL_PORT -1 +opt_set EXTRUDERS 3 +opt_set TEMP_SENSOR_1 1 +opt_set TEMP_SENSOR_2 1 +opt_set E0_AUTO_FAN_PIN PC10 +opt_set E1_AUTO_FAN_PIN PC11 +opt_set E2_AUTO_FAN_PIN PC12 +opt_set X_DRIVER_TYPE TMC2209 +opt_set Y_DRIVER_TYPE TMC2130 +opt_enable BLTOUCH EEPROM_SETTINGS AUTO_BED_LEVELING_3POINT Z_SAFE_HOMING +exec_test $1 $2 "BigTreeTech SKR Pro 3 Extruders, Auto-Fan, BLTOUCH, mixed TMC drivers" + +# clean up +restore_configs diff --git a/buildroot/share/tests/DUE-tests b/buildroot/tests/DUE-tests similarity index 85% rename from buildroot/share/tests/DUE-tests rename to buildroot/tests/DUE-tests index cfce93a92eeb..7f488f6126cb 100755 --- a/buildroot/share/tests/DUE-tests +++ b/buildroot/tests/DUE-tests @@ -14,9 +14,9 @@ opt_set TEMP_SENSOR_BED 2 opt_set GRID_MAX_POINTS_X 16 opt_set FANMUX0_PIN 53 opt_enable S_CURVE_ACCELERATION EEPROM_SETTINGS GCODE_MACROS \ - PIDTEMPBED FIX_MOUNTED_PROBE Z_SAFE_HOMING CODEPENDENT_XY_HOMING \ + FIX_MOUNTED_PROBE Z_SAFE_HOMING CODEPENDENT_XY_HOMING ASSISTED_TRAMMING \ EEPROM_SETTINGS SDSUPPORT BINARY_FILE_TRANSFER \ - BLINKM PCA9632 RGB_LED RGB_LED_R_PIN RGB_LED_G_PIN RGB_LED_B_PIN LED_CONTROL_MENU \ + BLINKM PCA9533 PCA9632 RGB_LED RGB_LED_R_PIN RGB_LED_G_PIN RGB_LED_B_PIN LED_CONTROL_MENU \ NEOPIXEL_LED CASE_LIGHT_ENABLE CASE_LIGHT_USE_NEOPIXEL CASE_LIGHT_MENU \ NOZZLE_PARK_FEATURE ADVANCED_PAUSE_FEATURE FILAMENT_RUNOUT_DISTANCE_MM FILAMENT_RUNOUT_SENSOR \ AUTO_BED_LEVELING_BILINEAR Z_MIN_PROBE_REPEATABILITY_TEST DEBUG_LEVELING_FEATURE \ @@ -24,15 +24,16 @@ opt_enable S_CURVE_ACCELERATION EEPROM_SETTINGS GCODE_MACROS \ BACKLASH_COMPENSATION BACKLASH_GCODE BAUD_RATE_GCODE BEZIER_CURVE_SUPPORT \ FWRETRACT ARC_SUPPORT ARC_P_CIRCLES CNC_WORKSPACE_PLANES CNC_COORDINATE_SYSTEMS \ PSU_CONTROL AUTO_POWER_CONTROL \ - SLOW_PWM_HEATERS THERMAL_PROTECTION_CHAMBER \ + PIDTEMPBED SLOW_PWM_HEATERS THERMAL_PROTECTION_CHAMBER \ PINS_DEBUGGING MAX7219_DEBUG M114_DETAIL \ EXTENSIBLE_UI opt_add EXTUI_EXAMPLE opt_set E0_AUTO_FAN_PIN 8 opt_set EXTRUDER_AUTO_FAN_SPEED 100 opt_set TEMP_SENSOR_CHAMBER 3 +opt_add TEMP_CHAMBER_PIN 6 opt_set HEATER_CHAMBER_PIN 45 -exec_test $1 $2 "RAMPS4DUE_EFB with ABL (Bilinear), EXTENSIBLE_UI, S-Curve, many options." +exec_test $1 $2 "RAMPS4DUE_EFB with ABL (Bilinear), ExtUI, S-Curve, many options." restore_configs opt_set MOTHERBOARD BOARD_RADDS diff --git a/buildroot/tests/FLYF407ZG-tests b/buildroot/tests/FLYF407ZG-tests new file mode 100644 index 000000000000..f1a65da6cbb3 --- /dev/null +++ b/buildroot/tests/FLYF407ZG-tests @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# +# Build tests for FLYF407ZG +# + +# exit on first failure +set -e + +# Build examples +restore_configs +opt_set MOTHERBOARD BOARD_FLYF407ZG +opt_set SERIAL_PORT -1 +opt_set X_DRIVER_TYPE TMC2208 +opt_set Y_DRIVER_TYPE TMC2130 +exec_test $1 $2 "FLYF407ZG Default Config with mixed TMC Drivers" + +# cleanup +restore_configs diff --git a/buildroot/share/tests/FYSETC_F6_13-tests b/buildroot/tests/FYSETC_F6_13-tests similarity index 75% rename from buildroot/share/tests/FYSETC_F6_13-tests rename to buildroot/tests/FYSETC_F6_13-tests index 5ddbac554e73..631a11778502 100644 --- a/buildroot/share/tests/FYSETC_F6_13-tests +++ b/buildroot/tests/FYSETC_F6_13-tests @@ -11,7 +11,8 @@ set -e # restore_configs opt_set MOTHERBOARD BOARD_FYSETC_F6_13 -exec_test $1 $2 "Default Configuration" +opt_enable DGUS_LCD_UI_FYSETC +exec_test $1 $2 "FYSETC F6 1.3 with DGUS" # clean up restore_configs diff --git a/buildroot/share/tests/FYSETC_S6-tests b/buildroot/tests/FYSETC_S6-tests similarity index 77% rename from buildroot/share/tests/FYSETC_S6-tests rename to buildroot/tests/FYSETC_S6-tests index a9e0331acdb5..c75629156b08 100644 --- a/buildroot/share/tests/FYSETC_S6-tests +++ b/buildroot/tests/FYSETC_S6-tests @@ -9,6 +9,8 @@ set -e # Build examples restore_configs use_example_configs FYSETC/S6 +opt_set Y_DRIVER_TYPE TMC2209 +opt_set Z_DRIVER_TYPE TMC2130 exec_test $1 $2 "FYSETC S6 Example" # cleanup diff --git a/buildroot/share/tests/BIGTREE_BTT002-tests b/buildroot/tests/LERDGEX-tests similarity index 52% rename from buildroot/share/tests/BIGTREE_BTT002-tests rename to buildroot/tests/LERDGEX-tests index 858957154def..c2d72e0d77e6 100644 --- a/buildroot/share/tests/BIGTREE_BTT002-tests +++ b/buildroot/tests/LERDGEX-tests @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# Build tests for STM32F407VET6 BigTreeTech BTT002 +# Build tests for LERDGEX environment # # exit on first failure @@ -10,9 +10,9 @@ set -e # Build with the default configurations # restore_configs -opt_set MOTHERBOARD BOARD_BTT_BTT002_V1_0 +opt_set MOTHERBOARD BOARD_LERDGE_X opt_set SERIAL_PORT 1 -exec_test $1 $2 "BigTreeTech BTT002 Default Configuration" +exec_test $1 $2 "LERDGE X with Default Configuration" # clean up restore_configs diff --git a/buildroot/share/tests/LPC1768-tests b/buildroot/tests/LPC1768-tests similarity index 91% rename from buildroot/share/tests/LPC1768-tests rename to buildroot/tests/LPC1768-tests index 566cbd27a643..2f206f02f2e6 100755 --- a/buildroot/share/tests/LPC1768-tests +++ b/buildroot/tests/LPC1768-tests @@ -15,7 +15,7 @@ set -e restore_configs opt_set MOTHERBOARD BOARD_RAMPS_14_RE_ARM_EFB -opt_enable VIKI2 SDSUPPORT SERIAL_PORT_2 NEOPIXEL_LED +opt_enable VIKI2 SDSUPPORT SDCARD_READONLY SERIAL_PORT_2 NEOPIXEL_LED opt_set NEOPIXEL_PIN P1_16 exec_test $1 $2 "ReARM EFB VIKI2, SDSUPPORT, 2 Serial ports (USB CDC + UART0), NeoPixel" @@ -43,7 +43,8 @@ opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER SDSUPPORT ADAPTIVE_FAN_ BABYSTEPPING BABYSTEP_XY BABYSTEP_ZPROBE_OFFSET BABYSTEP_ZPROBE_GFX_OVERLAY \ PRINTCOUNTER NOZZLE_PARK_FEATURE NOZZLE_CLEAN_FEATURE SLOW_PWM_HEATERS PIDTEMPBED EEPROM_SETTINGS INCH_MODE_SUPPORT TEMPERATURE_UNITS_SUPPORT \ Z_SAFE_HOMING ADVANCED_PAUSE_FEATURE PARK_HEAD_ON_PAUSE \ - LCD_INFO_MENU ARC_SUPPORT BEZIER_CURVE_SUPPORT EXTENDED_CAPABILITIES_REPORT AUTO_REPORT_TEMPERATURES SDCARD_SORT_ALPHA + HOST_KEEPALIVE_FEATURE HOST_ACTION_COMMANDS HOST_PROMPT_SUPPORT \ + LCD_INFO_MENU ARC_SUPPORT BEZIER_CURVE_SUPPORT EXTENDED_CAPABILITIES_REPORT AUTO_REPORT_TEMPERATURES SDCARD_SORT_ALPHA EMERGENCY_PARSER opt_set GRID_MAX_POINTS_X 16 opt_set NOZZLE_TO_PROBE_OFFSET "{ 0, 0, 0 }" exec_test $1 $2 "Re-ARM with NOZZLE_AS_PROBE and many features." diff --git a/buildroot/share/tests/LPC1769-tests b/buildroot/tests/LPC1769-tests similarity index 69% rename from buildroot/share/tests/LPC1769-tests rename to buildroot/tests/LPC1769-tests index 0cdb2f313b55..4314b0d5ff8d 100755 --- a/buildroot/share/tests/LPC1769-tests +++ b/buildroot/tests/LPC1769-tests @@ -22,10 +22,24 @@ opt_enable VIKI2 SDSUPPORT ADAPTIVE_FAN_SLOWING NO_FAN_SLOWING_IN_PID_TUNING \ BABYSTEPPING BABYSTEP_XY BABYSTEP_ZPROBE_OFFSET BABYSTEP_ZPROBE_GFX_OVERLAY \ PRINTCOUNTER NOZZLE_PARK_FEATURE NOZZLE_CLEAN_FEATURE SLOW_PWM_HEATERS PIDTEMPBED EEPROM_SETTINGS INCH_MODE_SUPPORT TEMPERATURE_UNITS_SUPPORT \ Z_SAFE_HOMING ADVANCED_PAUSE_FEATURE PARK_HEAD_ON_PAUSE \ - LCD_INFO_MENU ARC_SUPPORT BEZIER_CURVE_SUPPORT EXTENDED_CAPABILITIES_REPORT AUTO_REPORT_TEMPERATURES SDCARD_SORT_ALPHA + LCD_INFO_MENU ARC_SUPPORT BEZIER_CURVE_SUPPORT EXTENDED_CAPABILITIES_REPORT AUTO_REPORT_TEMPERATURES SDCARD_SORT_ALPHA EMERGENCY_PARSER opt_set GRID_MAX_POINTS_X 16 exec_test $1 $2 "Smoothieboard with many features" +restore_configs +opt_set MOTHERBOARD BOARD_SMOOTHIEBOARD +opt_set EXTRUDERS 2 +opt_set TEMP_SENSOR_1 -1 +opt_set TEMP_SENSOR_BED 5 +opt_enable TFTGLCD_PANEL_SPI SDSUPPORT ADAPTIVE_FAN_SLOWING NO_FAN_SLOWING_IN_PID_TUNING \ + FIX_MOUNTED_PROBE AUTO_BED_LEVELING_BILINEAR G29_RETRY_AND_RECOVER Z_MIN_PROBE_REPEATABILITY_TEST DEBUG_LEVELING_FEATURE \ + BABYSTEPPING BABYSTEP_XY BABYSTEP_ZPROBE_OFFSET \ + PRINTCOUNTER NOZZLE_PARK_FEATURE NOZZLE_CLEAN_FEATURE SLOW_PWM_HEATERS PIDTEMPBED EEPROM_SETTINGS INCH_MODE_SUPPORT TEMPERATURE_UNITS_SUPPORT \ + Z_SAFE_HOMING ADVANCED_PAUSE_FEATURE PARK_HEAD_ON_PAUSE \ + LCD_INFO_MENU ARC_SUPPORT BEZIER_CURVE_SUPPORT EXTENDED_CAPABILITIES_REPORT AUTO_REPORT_TEMPERATURES SDCARD_SORT_ALPHA EMERGENCY_PARSER +opt_set GRID_MAX_POINTS_X 16 +exec_test $1 $2 "Smoothieboard with TFTGLCD_PANEL_SPI" + #restore_configs #opt_set MOTHERBOARD BOARD_AZTEEG_X5_MINI_WIFI #opt_enable COREYX USE_XMAX_PLUG DAC_MOTOR_CURRENT_DEFAULT \ @@ -47,10 +61,11 @@ opt_set MOTHERBOARD BOARD_COHESION3D_REMIX opt_set X_DRIVER_TYPE TMC2130 opt_set Y_DRIVER_TYPE TMC2130 opt_set Z_DRIVER_TYPE TMC2130 -opt_enable AUTO_BED_LEVELING_BILINEAR EEPROM_SETTINGS EEPROM_CHITCHAT \ +opt_enable AUTO_BED_LEVELING_BILINEAR EEPROM_SETTINGS EEPROM_CHITCHAT MECHANICAL_GANTRY_CALIBRATION \ TMC_USE_SW_SPI MONITOR_DRIVER_STATUS STEALTHCHOP_XY STEALTHCHOP_Z HYBRID_THRESHOLD \ - SENSORLESS_PROBING Z_SAFE_HOMING X_STALL_SENSITIVITY Y_STALL_SENSITIVITY Z_STALL_SENSITIVITY TMC_DEBUG -opt_disable Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN PSU_CONTROL + SENSORLESS_PROBING Z_SAFE_HOMING X_STALL_SENSITIVITY Y_STALL_SENSITIVITY Z_STALL_SENSITIVITY TMC_DEBUG \ + EXPERIMENTAL_I2CBUS +opt_disable PSU_CONTROL exec_test $1 $2 "Cohesion3D Remix DELTA + ABL Bilinear + EEPROM + SENSORLESS_PROBING" # clean up diff --git a/buildroot/tests/SAMD51_grandcentral_m4-tests b/buildroot/tests/SAMD51_grandcentral_m4-tests new file mode 100644 index 000000000000..fbaf5fb7e55b --- /dev/null +++ b/buildroot/tests/SAMD51_grandcentral_m4-tests @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# +# Build tests for Adafruit Grand Central M4 (ATMEL ARM Cortex-M4) +# + +# exit on first failure +set -e + +# +# Build with the default configurations +# +restore_configs +opt_set SERIAL_PORT -1 +opt_set MOTHERBOARD BOARD_AGCM4_RAMPS_144 +opt_set TEMP_SENSOR_0 11 +opt_set TEMP_SENSOR_BED 11 +opt_set X_DRIVER_TYPE TMC2209 +opt_set Y_DRIVER_TYPE TMC2209 +opt_set Z_DRIVER_TYPE TMC2209 +opt_set Z2_DRIVER_TYPE TMC2209 +opt_set E0_DRIVER_TYPE TMC2209 +opt_set RESTORE_LEVELING_AFTER_G28 false +opt_set LCD_LANGUAGE it +opt_set NUM_Z_STEPPER_DRIVERS 2 +opt_set HOMING_BUMP_MM "{ 0, 0, 0 }" +opt_set SDCARD_CONNECTION LCD +opt_enable ENDSTOP_INTERRUPTS_FEATURE S_CURVE_ACCELERATION BLTOUCH Z_MIN_PROBE_REPEATABILITY_TEST \ + FILAMENT_RUNOUT_SENSOR G26_MESH_VALIDATION MESH_EDIT_GFX_OVERLAY Z_SAFE_HOMING \ + EEPROM_SETTINGS NOZZLE_PARK_FEATURE SDSUPPORT SD_CHECK_AND_RETRY \ + REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER Z_STEPPER_AUTO_ALIGN ADAPTIVE_STEP_SMOOTHING \ + STATUS_MESSAGE_SCROLLING LCD_SET_PROGRESS_MANUALLY SHOW_REMAINING_TIME USE_M73_REMAINING_TIME \ + LONG_FILENAME_HOST_SUPPORT SCROLL_LONG_FILENAMES BABYSTEPPING DOUBLECLICK_FOR_Z_BABYSTEPPING \ + MOVE_Z_WHEN_IDLE BABYSTEP_ZPROBE_OFFSET BABYSTEP_ZPROBE_GFX_OVERLAY \ + LIN_ADVANCE ADVANCED_PAUSE_FEATURE PARK_HEAD_ON_PAUSE MONITOR_DRIVER_STATUS SENSORLESS_HOMING \ + SQUARE_WAVE_STEPPING TMC_DEBUG EXPERIMENTAL_SCURVE +exec_test $1 $2 "Build Grand Central M4 Default Configuration" + +# clean up +restore_configs diff --git a/buildroot/tests/STM32F070CB_malyan-tests b/buildroot/tests/STM32F070CB_malyan-tests new file mode 100644 index 000000000000..20bd111fa9c0 --- /dev/null +++ b/buildroot/tests/STM32F070CB_malyan-tests @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +# +# Build tests for STM32F070CB Malyan M200 v2 +# + +# exit on first failure +set -e + +restore_configs +opt_set MOTHERBOARD BOARD_MALYAN_M200_V2 +opt_set SERIAL_PORT -1 +exec_test $1 $2 "Malyan M200 v2 Default Config" + +# cleanup +restore_configs diff --git a/buildroot/tests/STM32F070RB_malyan-tests b/buildroot/tests/STM32F070RB_malyan-tests new file mode 100644 index 000000000000..58237a70eb5f --- /dev/null +++ b/buildroot/tests/STM32F070RB_malyan-tests @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +# +# Build tests for STM32F070RB Malyan M200 v2 +# + +# exit on first failure +set -e + +restore_configs +opt_set MOTHERBOARD BOARD_MALYAN_M200_V2 +opt_set SERIAL_PORT -1 +exec_test $1 $2 "Malyan M200 v2 Default Config" + +# cleanup +restore_configs diff --git a/buildroot/share/tests/STM32F103CB_malyan-tests b/buildroot/tests/STM32F103CB_malyan-tests similarity index 79% rename from buildroot/share/tests/STM32F103CB_malyan-tests rename to buildroot/tests/STM32F103CB_malyan-tests index fced4d5d2404..e594cb43dbae 100644 --- a/buildroot/share/tests/STM32F103CB_malyan-tests +++ b/buildroot/tests/STM32F103CB_malyan-tests @@ -7,7 +7,7 @@ set -e use_example_configs Malyan/M200 -exec_test $1 $2 "Default Configuration" +exec_test $1 $2 "Malyan M200" # cleanup restore_configs diff --git a/buildroot/tests/STM32F103RC_btt-tests b/buildroot/tests/STM32F103RC_btt-tests new file mode 100644 index 000000000000..ad15ee723767 --- /dev/null +++ b/buildroot/tests/STM32F103RC_btt-tests @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# +# Build tests for STM32F103RC BigTreeTech (SKR Mini E3) +# + +# exit on first failure +set -e + +# +# Build with the default configurations +# +restore_configs +opt_set MOTHERBOARD BOARD_BTT_SKR_MINI_E3_V1_0 +opt_set SERIAL_PORT 1 +opt_set SERIAL_PORT_2 -1 +opt_set X_DRIVER_TYPE TMC2209 +opt_set Y_DRIVER_TYPE TMC2209 +opt_set Z_DRIVER_TYPE TMC2209 +opt_set E0_DRIVER_TYPE TMC2209 +opt_set X_SLAVE_ADDRESS 0 +opt_set Y_SLAVE_ADDRESS 1 +opt_set Z_SLAVE_ADDRESS 2 +opt_set E0_SLAVE_ADDRESS 3 + +exec_test $1 $2 "BigTreeTech SKR Mini E3 1.0 - Basic Config with TMC2209 HW Serial" + +# clean up +restore_configs diff --git a/buildroot/share/tests/STM32F103RC_bigtree_USB-tests b/buildroot/tests/STM32F103RC_btt_USB-tests similarity index 100% rename from buildroot/share/tests/STM32F103RC_bigtree_USB-tests rename to buildroot/tests/STM32F103RC_btt_USB-tests diff --git a/buildroot/share/tests/STM32F103RC_fysetc-tests b/buildroot/tests/STM32F103RC_fysetc-tests similarity index 76% rename from buildroot/share/tests/STM32F103RC_fysetc-tests rename to buildroot/tests/STM32F103RC_fysetc-tests index 7d08fb7c5862..dfa85d9bb616 100644 --- a/buildroot/share/tests/STM32F103RC_fysetc-tests +++ b/buildroot/tests/STM32F103RC_fysetc-tests @@ -9,7 +9,7 @@ set -e # # Build with the default configurations # -use_example_configs "FYSETC/Cheetah 1.2/base" +use_example_configs "Creality/Ender-3/FYSETC Cheetah 1.2/base" exec_test $1 $2 "Cheetah 1.2 Configuration" # clean up diff --git a/buildroot/tests/STM32F103RC_meeb-tests b/buildroot/tests/STM32F103RC_meeb-tests new file mode 100644 index 000000000000..74e770d3c895 --- /dev/null +++ b/buildroot/tests/STM32F103RC_meeb-tests @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +# +# Build tests for STM32F103RC MEEB_3DP (ccrobot-online.com) +# + +# exit on first failure +set -e + +# +# Build with the default configurations +# +restore_configs +opt_set MOTHERBOARD BOARD_CCROBOT_MEEB_3DP +opt_set SERIAL_PORT 1 +opt_set SERIAL_PORT_2 -1 +opt_set X_DRIVER_TYPE TMC2208 +opt_set Y_DRIVER_TYPE TMC2208 +opt_set Z_DRIVER_TYPE TMC2208 +opt_set E0_DRIVER_TYPE TMC2208 +exec_test $1 $2 "MEEB_3DP - Basic Config with TMC2208 SW Serial" + +# clean up +restore_configs diff --git a/buildroot/share/tests/STM32F103RE-tests b/buildroot/tests/STM32F103RE-tests similarity index 100% rename from buildroot/share/tests/STM32F103RE-tests rename to buildroot/tests/STM32F103RE-tests diff --git a/buildroot/tests/STM32F103RET6_creality-tests b/buildroot/tests/STM32F103RET6_creality-tests new file mode 100644 index 000000000000..ca723c7aa229 --- /dev/null +++ b/buildroot/tests/STM32F103RET6_creality-tests @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +# +# Build tests for STM32F103RET6_creality +# + +# exit on first failure +set -e + +# +# Build with configs included in the PR +# +use_example_configs "Creality/Ender-3 V2" +opt_enable MARLIN_DEV_MODE +exec_test $1 $2 "Ender 3 v2" + +restore_configs diff --git a/buildroot/share/tests/STM32F103RE_bigtree_USB-tests b/buildroot/tests/STM32F103RE_btt-tests similarity index 67% rename from buildroot/share/tests/STM32F103RE_bigtree_USB-tests rename to buildroot/tests/STM32F103RE_btt-tests index 77751d776e9c..9a829a553efe 100644 --- a/buildroot/share/tests/STM32F103RE_bigtree_USB-tests +++ b/buildroot/tests/STM32F103RE_btt-tests @@ -13,7 +13,9 @@ restore_configs opt_set MOTHERBOARD BOARD_BTT_SKR_E3_DIP opt_set SERIAL_PORT 1 opt_set SERIAL_PORT_2 -1 -exec_test $1 $2 "BigTreeTech SKR E3 DIP v1.0 - Basic Configuration" +opt_set X_DRIVER_TYPE TMC2209 +opt_set Y_DRIVER_TYPE TMC2130 +exec_test $1 $2 "BigTreeTech SKR E3 DIP v1.0 - Basic Config with mixed TMC Drivers" # clean up restore_configs diff --git a/buildroot/share/tests/STM32F103RE_bigtree-tests b/buildroot/tests/STM32F103RE_btt_USB-tests similarity index 100% rename from buildroot/share/tests/STM32F103RE_bigtree-tests rename to buildroot/tests/STM32F103RE_btt_USB-tests diff --git a/buildroot/share/tests/STM32F103VE_longer-tests b/buildroot/tests/STM32F103VE_longer-tests similarity index 100% rename from buildroot/share/tests/STM32F103VE_longer-tests rename to buildroot/tests/STM32F103VE_longer-tests diff --git a/buildroot/share/tests/STM32F4-tests b/buildroot/tests/STM32F4-tests similarity index 100% rename from buildroot/share/tests/STM32F4-tests rename to buildroot/tests/STM32F4-tests diff --git a/buildroot/tests/STM32F401VE_STEVAL-tests b/buildroot/tests/STM32F401VE_STEVAL-tests new file mode 100644 index 000000000000..2811014c13b2 --- /dev/null +++ b/buildroot/tests/STM32F401VE_STEVAL-tests @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +# +# Build tests for STM32F401VE_STEVAL +# + +# exit on first failure +set -e + +# Build examples +restore_configs +opt_set MOTHERBOARD BOARD_STEVAL_3DP001V1 +opt_set SERIAL_PORT -1 +exec_test $1 $2 "STM32F401VE_STEVAL Default Config" + +# cleanup +restore_configs diff --git a/buildroot/share/tests/STM32F407VE_black-tests b/buildroot/tests/STM32F407VE_black-tests similarity index 94% rename from buildroot/share/tests/STM32F407VE_black-tests rename to buildroot/tests/STM32F407VE_black-tests index c35b279b0f58..908382ec2a04 100755 --- a/buildroot/share/tests/STM32F407VE_black-tests +++ b/buildroot/tests/STM32F407VE_black-tests @@ -6,6 +6,7 @@ # exit on first failure set -e +restore_configs use_example_configs STM32/Black_STM32F407VET6 opt_enable BAUD_RATE_GCODE exec_test $1 $2 "Full-featured Sample Black STM32F407VET6 config" diff --git a/buildroot/share/tests/STM32F7-tests b/buildroot/tests/STM32F7-tests similarity index 100% rename from buildroot/share/tests/STM32F7-tests rename to buildroot/tests/STM32F7-tests diff --git a/buildroot/share/tests/at90usb1286_cdc-tests b/buildroot/tests/at90usb1286_cdc-tests similarity index 100% rename from buildroot/share/tests/at90usb1286_cdc-tests rename to buildroot/tests/at90usb1286_cdc-tests diff --git a/buildroot/share/tests/at90usb1286_dfu-tests b/buildroot/tests/at90usb1286_dfu-tests similarity index 100% rename from buildroot/share/tests/at90usb1286_dfu-tests rename to buildroot/tests/at90usb1286_dfu-tests diff --git a/buildroot/share/tests/esp32-tests b/buildroot/tests/esp32-tests similarity index 71% rename from buildroot/share/tests/esp32-tests rename to buildroot/tests/esp32-tests index 18abab8b065f..204e7aa708eb 100755 --- a/buildroot/share/tests/esp32-tests +++ b/buildroot/tests/esp32-tests @@ -11,11 +11,10 @@ set -e # restore_configs opt_set MOTHERBOARD BOARD_ESPRESSIF_ESP32 -opt_enable WIFISUPPORT GCODE_MACROS BAUD_RATE_GCODE +opt_enable WIFISUPPORT WEBSUPPORT GCODE_MACROS BAUD_RATE_GCODE M115_GEOMETRY_REPORT REPETIER_GCODE_M360 opt_add WIFI_SSID "\"ssid\"" opt_add WIFI_PWD "\"password\"" opt_set TX_BUFFER_SIZE 64 -opt_add WEBSUPPORT exec_test $1 $2 "ESP32 with WIFISUPPORT and WEBSUPPORT" # @@ -31,7 +30,12 @@ opt_set X_HARDWARE_SERIAL Serial1 opt_set Y_HARDWARE_SERIAL Serial1 opt_set Z_HARDWARE_SERIAL Serial1 opt_set E0_HARDWARE_SERIAL Serial1 -exec_test $1 $2 "ESP32 with TMC Hardware Serial" +opt_set X_SLAVE_ADDRESS 0 +opt_set Y_SLAVE_ADDRESS 1 +opt_set Z_SLAVE_ADDRESS 2 +opt_set E0_SLAVE_ADDRESS 3 +opt_enable HOTEND_IDLE_TIMEOUT +exec_test $1 $2 "ESP32, TMC HW Serial, Hotend Idle" # cleanup restore_configs diff --git a/buildroot/share/tests/jgaurora_a5s_a1-tests b/buildroot/tests/jgaurora_a5s_a1-tests similarity index 100% rename from buildroot/share/tests/jgaurora_a5s_a1-tests rename to buildroot/tests/jgaurora_a5s_a1-tests diff --git a/buildroot/share/tests/linux_native-tests b/buildroot/tests/linux_native-tests similarity index 100% rename from buildroot/share/tests/linux_native-tests rename to buildroot/tests/linux_native-tests diff --git a/buildroot/tests/malyan_M300-tests b/buildroot/tests/malyan_M300-tests new file mode 100755 index 000000000000..1955accaa5f6 --- /dev/null +++ b/buildroot/tests/malyan_M300-tests @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +# +# Build tests for STM32F070CB Malyan M300 +# + +# exit on first failure +set -e + +restore_configs +use_example_configs "delta/Malyan M300" +opt_disable AUTO_BED_LEVELING_3POINT +opt_set LCD_SERIAL_PORT 1 +exec_test $1 $2 "Malyan M300 (delta)" + +# cleanup +restore_configs diff --git a/buildroot/tests/mega1280-tests b/buildroot/tests/mega1280-tests new file mode 100644 index 000000000000..ce13d4a6e8bb --- /dev/null +++ b/buildroot/tests/mega1280-tests @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +# +# Build tests for AVR ATmega1280 +# + +# exit on first failure +set -e + +# +# Build with the default configurations +# +#restore_configs +#exec_test $1 $2 "Default Configuration" + +# +# Test MESH_BED_LEVELING feature, with LCD +# +restore_configs +opt_set LCD_LANGUAGE an +opt_enable SPINDLE_FEATURE ULTIMAKERCONTROLLER LCD_BED_LEVELING \ + EEPROM_SETTINGS EEPROM_BOOT_SILENT EEPROM_AUTO_INIT \ + SENSORLESS_BACKOFF_MM HOMING_BACKOFF_POST_MM HOME_Y_BEFORE_X CODEPENDENT_XY_HOMING \ + MESH_BED_LEVELING ENABLE_LEVELING_FADE_HEIGHT MESH_G28_REST_ORIGIN \ + G26_MESH_VALIDATION MESH_EDIT_MENU GCODE_QUOTED_STRINGS \ + EXTERNAL_CLOSED_LOOP_CONTROLLER POWER_MONITOR_CURRENT POWER_MONITOR_VOLTAGE +opt_set POWER_MONITOR_CURRENT_PIN 14 +opt_set POWER_MONITOR_VOLTAGE_PIN 15 +opt_set CLOSED_LOOP_ENABLE_PIN 44 +opt_set CLOSED_LOOP_MOVE_COMPLETE_PIN 45 +exec_test $1 $2 "Spindle, MESH_BED_LEVELING, closed loop, Power Monitor, and LCD" + +# +# Test DUAL_X_CARRIAGE +# +restore_configs +opt_set MOTHERBOARD BOARD_TT_OSCAR +opt_set LCD_LANGUAGE pt +opt_set EXTRUDERS 2 +opt_set TEMP_SENSOR_1 1 +opt_enable USE_XMAX_PLUG DUAL_X_CARRIAGE REPRAPWORLD_KEYPAD +opt_set REPRAPWORLD_KEYPAD_MOVE_STEP 10.0 +exec_test $1 $2 "TT Oscar | DUAL_X_CARRIAGE" + +# +# Delta Config (generic) + Probeless +# +use_example_configs delta/generic +opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER DELTA_AUTO_CALIBRATION DELTA_CALIBRATION_MENU +exec_test $1 $2 "RAMPS | DELTA | RRD LCD | DELTA_AUTO_CALIBRATION | DELTA_CALIBRATION_MENU" + +# +# Delta Config (generic) + ABL bilinear + BLTOUCH +use_example_configs delta/generic +opt_set LCD_LANGUAGE cz +opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER DELTA_CALIBRATION_MENU AUTO_BED_LEVELING_BILINEAR BLTOUCH +exec_test $1 $2 "DELTA | RRD LCD | ABL Bilinear | BLTOUCH" + +# clean up +restore_configs diff --git a/buildroot/share/tests/megaatmega2560-tests b/buildroot/tests/mega2560-tests similarity index 68% rename from buildroot/share/tests/megaatmega2560-tests rename to buildroot/tests/mega2560-tests index a49536529f9e..d3fd5c0192b9 100755 --- a/buildroot/share/tests/megaatmega2560-tests +++ b/buildroot/tests/mega2560-tests @@ -12,43 +12,6 @@ set -e #restore_configs #exec_test $1 $2 "Default Configuration" -# -# Test 2 extruders (one MAX6675) and heated bed on basic RAMPS 1.4 -# Test a "Fix Mounted" Probe with Safe Homing, some arc options, -# linear bed leveling, M48, leveling debug, and firmware retraction. -# -restore_configs -opt_set MOTHERBOARD BOARD_RAMPS_14_EEB -opt_set EXTRUDERS 2 -opt_set TEMP_SENSOR_0 -2 -opt_set TEMP_SENSOR_1 1 -opt_set TEMP_SENSOR_BED 2 -opt_set TEMP_SENSOR_PROBE 1 -opt_add TEMP_PROBE_PIN 12 -opt_set TEMP_SENSOR_CHAMBER 3 -opt_add HEATER_CHAMBER_PIN 45 -opt_set GRID_MAX_POINTS_X 16 -opt_set FANMUX0_PIN 53 -opt_disable USE_WATCHDOG -opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER LCD_PROGRESS_BAR LCD_PROGRESS_BAR_TEST \ - FIX_MOUNTED_PROBE Z_SAFE_HOMING CODEPENDENT_XY_HOMING PIDTEMPBED \ - PROBING_HEATERS_OFF PROBING_FANS_OFF PROBING_STEPPERS_OFF WAIT_FOR_BED_HEATER \ - EEPROM_SETTINGS SDSUPPORT SD_REPRINT_LAST_SELECTED_FILE BINARY_FILE_TRANSFER \ - BLINKM PCA9632 RGB_LED RGB_LED_R_PIN RGB_LED_G_PIN RGB_LED_B_PIN LED_CONTROL_MENU \ - NEOPIXEL_LED CASE_LIGHT_ENABLE CASE_LIGHT_USE_NEOPIXEL CASE_LIGHT_MENU \ - PID_PARAMS_PER_HOTEND PID_AUTOTUNE_MENU PID_EDIT_MENU LCD_SHOW_E_TOTAL \ - PRINTCOUNTER SERVICE_NAME_1 SERVICE_INTERVAL_1 LEVEL_BED_CORNERS \ - NOZZLE_PARK_FEATURE FILAMENT_RUNOUT_SENSOR FILAMENT_RUNOUT_DISTANCE_MM \ - ADVANCED_PAUSE_FEATURE FILAMENT_LOAD_UNLOAD_GCODES FILAMENT_UNLOAD_ALL_EXTRUDERS \ - AUTO_BED_LEVELING_BILINEAR Z_MIN_PROBE_REPEATABILITY_TEST DISTINCT_E_FACTORS \ - SKEW_CORRECTION SKEW_CORRECTION_FOR_Z SKEW_CORRECTION_GCODE \ - BACKLASH_COMPENSATION BACKLASH_GCODE BAUD_RATE_GCODE BEZIER_CURVE_SUPPORT \ - FWRETRACT ARC_P_CIRCLES CNC_WORKSPACE_PLANES CNC_COORDINATE_SYSTEMS \ - PSU_CONTROL AUTO_POWER_CONTROL POWER_LOSS_RECOVERY POWER_LOSS_PIN POWER_LOSS_STATE \ - SLOW_PWM_HEATERS THERMAL_PROTECTION_CHAMBER LIN_ADVANCE \ - HOST_ACTION_COMMANDS HOST_PROMPT_SUPPORT PINS_DEBUGGING MAX7219_DEBUG M114_DETAIL -exec_test $1 $2 "RAMPS | EXTRUDERS 2 | CHAR LCD + SD | FIX Probe | ABL-Linear | Advanced Pause | PLR | LEDs ..." - # # Test a probeless build of AUTO_BED_LEVELING_UBL, with lots of extruders # @@ -66,7 +29,7 @@ opt_enable AUTO_BED_LEVELING_UBL RESTORE_LEVELING_AFTER_G28 DEBUG_LEVELING_FEATU REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER LIGHTWEIGHT_UI STATUS_MESSAGE_SCROLLING BOOT_MARLIN_LOGO_SMALL \ SDSUPPORT SDCARD_SORT_ALPHA USB_FLASH_DRIVE_SUPPORT SCROLL_LONG_FILENAMES CANCEL_OBJECTS \ EEPROM_SETTINGS EEPROM_CHITCHAT GCODE_MACROS CUSTOM_USER_MENUS \ - MULTI_NOZZLE_DUPLICATION CLASSIC_JERK LIN_ADVANCE QUICK_HOME \ + MULTI_NOZZLE_DUPLICATION CLASSIC_JERK LIN_ADVANCE EXTRA_LIN_ADVANCE_K QUICK_HOME \ LCD_SET_PROGRESS_MANUALLY PRINT_PROGRESS_SHOW_DECIMALS SHOW_REMAINING_TIME \ BABYSTEPPING BABYSTEP_XY NANODLP_Z_SYNC I2C_POSITION_ENCODERS M114_DETAIL exec_test $1 $2 "Azteeg X3 Pro | EXTRUDERS 5 | RRDFGSC | UBL | LIN_ADVANCE ..." @@ -108,50 +71,43 @@ opt_set NUM_SERVOS 1 opt_enable ZONESTAR_LCD Z_PROBE_SERVO_NR Z_SERVO_ANGLES DEACTIVATE_SERVOS_AFTER_MOVE BOOT_MARLIN_LOGO_ANIMATED \ AUTO_BED_LEVELING_3POINT DEBUG_LEVELING_FEATURE EEPROM_SETTINGS EEPROM_CHITCHAT M114_DETAIL \ NO_VOLUMETRICS EXTENDED_CAPABILITIES_REPORT AUTO_REPORT_TEMPERATURES AUTOTEMP G38_PROBE_TARGET JOYSTICK \ - PRUSA_MMU2 MMU2_MENUS NOZZLE_PARK_FEATURE ADVANCED_PAUSE_FEATURE Z_SAFE_HOMING -exec_test $1 $2 "RAMPS | ZONESTAR_LCD | MMU2 | Servo Probe | ABL 3-Pt | Debug Leveling | EEPROM | G38 ..." + PRUSA_MMU2 MMU2_MENUS PRUSA_MMU2_S_MODE DIRECT_STEPPING DETECT_BROKEN_ENDSTOP \ + FILAMENT_RUNOUT_SENSOR NOZZLE_PARK_FEATURE ADVANCED_PAUSE_FEATURE Z_SAFE_HOMING +exec_test $1 $2 "RAMPS | ZONESTAR + Chinese | MMU2 | Servo | 3-Point + Debug | G38 ..." # # Test MINIRAMBO with PWM_MOTOR_CURRENT and many features # restore_configs -opt_set MOTHERBOARD BOARD_MINIRAMBO +opt_set MOTHERBOARD BOARD_MEGACONTROLLER opt_set LCD_LANGUAGE de opt_enable EEPROM_SETTINGS EEPROM_CHITCHAT \ - ULTIMAKERCONTROLLER SDSUPPORT PCA9632 LCD_INFO_MENU \ + MINIPANEL SDSUPPORT PCA9632 LCD_INFO_MENU \ AUTO_BED_LEVELING_BILINEAR PROBE_MANUALLY LCD_BED_LEVELING G26_MESH_VALIDATION MESH_EDIT_MENU \ - M100_FREE_MEMORY_WATCHER \ - INCH_MODE_SUPPORT TEMPERATURE_UNITS_SUPPORT EXPERIMENTAL_I2CBUS \ + LIN_ADVANCE EXTRA_LIN_ADVANCE_K \ + INCH_MODE_SUPPORT TEMPERATURE_UNITS_SUPPORT EXPERIMENTAL_I2CBUS M100_FREE_MEMORY_WATCHER \ NOZZLE_PARK_FEATURE NOZZLE_CLEAN_FEATURE \ ADVANCED_PAUSE_FEATURE PARK_HEAD_ON_PAUSE ADVANCED_PAUSE_CONTINUOUS_PURGE FILAMENT_LOAD_UNLOAD_GCODES \ - PRINTCOUNTER SERVICE_NAME_1 SERVICE_INTERVAL_1 M114_DETAIL + PRINTCOUNTER SERVICE_NAME_1 SERVICE_INTERVAL_1 M114_DETAIL \ + USE_CONTROLLER_FAN CONTROLLER_FAN_EDITABLE +opt_set CONTROLLERFAN_SPEED_IDLE 128 opt_add M100_FREE_MEMORY_DUMPER opt_add M100_FREE_MEMORY_CORRUPTOR opt_set PWM_MOTOR_CURRENT "{ 1300, 1300, 1250 }" opt_set I2C_SLAVE_ADDRESS 63 -exec_test $1 $2 "MINIRAMBO | Ultimaker LCD | M100 | PWM_MOTOR_CURRENT | PRINTCOUNTER | Advanced Pause ..." +exec_test $1 $2 "MEGACONTROLLER | Minipanel | M100 | PWM_MOTOR_CURRENT | PRINTCOUNTER | Advanced Pause ..." # -# Mixing Extruder with 5 steppers, Cyrillic +# Mixing Extruder with 5 steppers, Greek # restore_configs opt_set MOTHERBOARD BOARD_AZTEEG_X3_PRO opt_set LCD_LANGUAGE el_gr -opt_enable MIXING_EXTRUDER GRADIENT_MIX GRADIENT_VTOOL CR10_STOCKDISPLAY +opt_enable MIXING_EXTRUDER GRADIENT_MIX GRADIENT_VTOOL CR10_STOCKDISPLAY \ + USE_CONTROLLER_FAN CONTROLLER_FAN_EDITABLE CONTROLLER_FAN_IGNORE_Z opt_set MIXING_STEPPERS 5 opt_set LCD_LANGUAGE ru -exec_test $1 $2 "Azteeg X3 | Mixing Extruder (x5) | Gradient Mix | Cyrillic" - -# -# Test DUAL_X_CARRIAGE -# -restore_configs -opt_set MOTHERBOARD BOARD_RUMBA -opt_set LCD_LANGUAGE pt -opt_set EXTRUDERS 2 -opt_set TEMP_SENSOR_1 1 -opt_enable USE_XMAX_PLUG DUAL_X_CARRIAGE -exec_test $1 $2 "Rumba | DUAL_X_CARRIAGE" +exec_test $1 $2 "Azteeg X3 | Mixing Extruder (x5) | Gradient Mix | Greek" # # Test SPEAKER with BOARD_BQ_ZUM_MEGA_3D and BQ_LCD_SMART_CONTROLLER @@ -173,23 +129,26 @@ exec_test $1 $2 "Rumba | DUAL_X_CARRIAGE" # Test many less common options # restore_configs -opt_set MOTHERBOARD BOARD_MEGATRONICS_32 +opt_set MOTHERBOARD BOARD_MIGHTYBOARD_REVE +opt_set TEMP_SENSOR_0 -2 +opt_set DIGIPOT_I2C_NUM_CHANNELS 5 opt_set LCD_LANGUAGE it opt_set MIXING_STEPPERS 2 opt_set SERVO_DELAY "{ 300, 300, 300 }" opt_enable COREYX USE_XMAX_PLUG MIXING_EXTRUDER GRADIENT_MIX \ BABYSTEPPING BABYSTEP_DISPLAY_TOTAL FILAMENT_LCD_DISPLAY \ - REPRAP_DISCOUNT_SMART_CONTROLLER MENU_ADDAUTOSTART SDSUPPORT SDCARD_SORT_ALPHA \ + REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER MENU_ADDAUTOSTART SDSUPPORT SDCARD_SORT_ALPHA \ ENDSTOP_NOISE_THRESHOLD FAN_SOFT_PWM \ - FIX_MOUNTED_PROBE AUTO_BED_LEVELING_LINEAR DEBUG_LEVELING_FEATURE FILAMENT_WIDTH_SENSOR \ + FIX_MOUNTED_PROBE AUTO_BED_LEVELING_LINEAR DEBUG_LEVELING_FEATURE FILAMENT_WIDTH_SENSOR PROBE_OFFSET_WIZARD \ Z_SAFE_HOMING SHOW_TEMP_ADC_VALUES HOME_Y_BEFORE_X EMERGENCY_PARSER \ SD_ABORT_ON_ENDSTOP_HIT HOST_ACTION_COMMANDS HOST_PROMPT_SUPPORT ADVANCED_OK M114_DETAIL \ - VOLUMETRIC_DEFAULT_ON NO_WORKSPACE_OFFSETS EXTRA_FAN_SPEED FWRETRACT + VOLUMETRIC_DEFAULT_ON NO_WORKSPACE_OFFSETS EXTRA_FAN_SPEED FWRETRACT \ + USE_CONTROLLER_FAN CONTROLLER_FAN_EDITABLE CONTROLLER_FAN_USE_Z_ONLY opt_set FAN_MIN_PWM 50 opt_set FAN_KICKSTART_TIME 100 opt_set XY_FREQUENCY_LIMIT 15 opt_add FILWIDTH_PIN 5 -exec_test $1 $2 "Megatronics 3.2 | Gradient Mix | Endstop Int. | Home Y > X | FW Retract ..." +exec_test $1 $2 "Mightyboard Rev. E | CoreXY, Gradient Mix | Endstop Int. | Home Y > X | FW Retract ..." ######## Other Standard LCD/Panels ############## # @@ -277,11 +236,11 @@ exec_test $1 $2 "Megatronics 3.2 | Gradient Mix | Endstop Int. | Home Y > X | FW # #restore_configs #opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER SDSUPPORT -#for lang in an bg ca cz da de el el_gr en es eu fi fr gl hr it jp_kana nl pl pt pt_br ru sk tr uk vi zh_CN zh_TW test; do opt_set LCD_LANGUAGE $lang; echo "compile with language $lang ..."; exec_test $1 $2 "Stuff"; done +#for lang in an bg ca cz da de el el_gr en es eu fi fr gl hr hu it jp_kana nl pl pt pt_br ro ru sk tr uk vi zh_CN zh_TW test; do opt_set LCD_LANGUAGE $lang; echo "compile with language $lang ..."; exec_test $1 $2 "Stuff"; done # #restore_configs #opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER SDSUPPORT -#for lang in an bg ca cz da de el el_gr en es eu fi fr gl hr it jp_kana nl pl pt pt_br ru sk tr uk vi zh_CN zh_TW test; do opt_set LCD_LANGUAGE $lang; echo "compile with language $lang ..."; exec_test $1 $2 "Stuff"; done +#for lang in an bg ca cz da de el el_gr en es eu fi fr gl hr hu it jp_kana nl pl pt pt_br ro ru sk tr uk vi zh_CN zh_TW test; do opt_set LCD_LANGUAGE $lang; echo "compile with language $lang ..."; exec_test $1 $2 "Stuff"; done ######## Example Configurations ############## # @@ -297,9 +256,13 @@ exec_test $1 $2 "Full-featured CR-10S config" #exec_test $1 $2 "Stuff" # -# Delta Config (generic) + ABL bilinear + BLTOUCH +# Delta Config (generic) + UBL + ALLEN_KEY + EEPROM_SETTINGS + OLED_PANEL_TINYBOY2 +# use_example_configs delta/generic -opt_set LCD_LANGUAGE cz +opt_enable RESTORE_LEVELING_AFTER_G28 EEPROM_SETTINGS EEPROM_CHITCHAT \ + Z_PROBE_ALLEN_KEY AUTO_BED_LEVELING_UBL \ + OLED_PANEL_TINYBOY2 MESH_EDIT_GFX_OVERLAY DELTA_CALIBRATION_MENU +opt_set LCD_LANGUAGE ko_KR opt_set X_DRIVER_TYPE L6470 opt_set Y_DRIVER_TYPE L6470 opt_set Z_DRIVER_TYPE L6470 @@ -308,24 +271,7 @@ opt_add L6470_CHAIN_MISO_PIN 49 opt_add L6470_CHAIN_MOSI_PIN 40 opt_add L6470_CHAIN_SS_PIN 42 opt_add "ENABLE_RESET_L64XX_CHIPS(V) NOOP" -opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER DELTA_CALIBRATION_MENU AUTO_BED_LEVELING_BILINEAR BLTOUCH -exec_test $1 $2 "DELTA | L6470 | RRD LCD | ABL Bilinear | BLTOUCH" - -# -# Delta Config (generic) + UBL + ALLEN_KEY + OLED_PANEL_TINYBOY2 + EEPROM_SETTINGS -# -use_example_configs delta/generic -opt_set LCD_LANGUAGE ko_KR -opt_enable AUTO_BED_LEVELING_UBL RESTORE_LEVELING_AFTER_G28 Z_PROBE_ALLEN_KEY EEPROM_SETTINGS EEPROM_CHITCHAT \ - OLED_PANEL_TINYBOY2 MESH_EDIT_GFX_OVERLAY -exec_test $1 $2 "RAMPS | DELTA | OLED_PANEL_TINYBOY2 | UBL | Allen Key | EEPROM" - -# -# Delta Config (generic) + Probeless -# -use_example_configs delta/generic -opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER DELTA_AUTO_CALIBRATION DELTA_CALIBRATION_MENU -exec_test $1 $2 "RAMPS | DELTA | RRD LCD | DELTA_AUTO_CALIBRATION | DELTA_CALIBRATION_MENU" +exec_test $1 $2 "DELTA, RAMPS, L6470, UBL, Allen Key, EEPROM, OLED_PANEL_TINYBOY2..." # # Delta Config (FLSUN AC because it's complex) diff --git a/buildroot/tests/mks_robin-tests b/buildroot/tests/mks_robin-tests new file mode 100644 index 000000000000..d6350622052c --- /dev/null +++ b/buildroot/tests/mks_robin-tests @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +# +# Build tests for MKS Robin +# (STM32F1 genericSTM32F103ZE) +# + +# exit on first failure +set -e + +use_example_configs Mks/Robin +opt_disable TFT_320x240 +opt_enable FSMC_GRAPHICAL_TFT +exec_test $1 $2 "MKS Robin base configuration" + +# cleanup +restore_configs diff --git a/buildroot/share/tests/mks_robin_lite-tests b/buildroot/tests/mks_robin_lite-tests similarity index 52% rename from buildroot/share/tests/mks_robin_lite-tests rename to buildroot/tests/mks_robin_lite-tests index a50d7347f5b7..34809641eca9 100644 --- a/buildroot/share/tests/mks_robin_lite-tests +++ b/buildroot/tests/mks_robin_lite-tests @@ -6,12 +6,12 @@ # exit on first failure set -e -use_example_configs Mks/Robin +restore_configs opt_set MOTHERBOARD BOARD_MKS_ROBIN_LITE -opt_set EXTRUDERS 1 -opt_set TEMP_SENSOR_1 0 -opt_disable FSMC_GRAPHICAL_TFT -exec_test $1 $2 "Default Configuration" +opt_set SERIAL_PORT -1 +opt_enable EEPROM_SETTINGS +opt_enable SDSUPPORT +exec_test $1 $2 "Default Configuration with Fallback SD EEPROM" # cleanup restore_configs diff --git a/buildroot/share/tests/mks_robin_mini-tests b/buildroot/tests/mks_robin_mini-tests similarity index 67% rename from buildroot/share/tests/mks_robin_mini-tests rename to buildroot/tests/mks_robin_mini-tests index c8ba5a5a4870..1c40ea453554 100644 --- a/buildroot/share/tests/mks_robin_mini-tests +++ b/buildroot/tests/mks_robin_mini-tests @@ -1,6 +1,7 @@ #!/usr/bin/env bash # -# Build tests for STM32F1 genericSTM32F103VE +# Build tests for MKS Robin mini +# (STM32F1 genericSTM32F103VE) # # exit on first failure @@ -10,7 +11,7 @@ use_example_configs Mks/Robin opt_set MOTHERBOARD BOARD_MKS_ROBIN_MINI opt_set EXTRUDERS 1 opt_set TEMP_SENSOR_1 0 -exec_test $1 $2 "Default Configuration" +exec_test $1 $2 "MKS Robin mini" # cleanup restore_configs diff --git a/buildroot/tests/mks_robin_nano35-tests b/buildroot/tests/mks_robin_nano35-tests new file mode 100644 index 000000000000..92c97be756cd --- /dev/null +++ b/buildroot/tests/mks_robin_nano35-tests @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# +# Build tests for MKS Robin nano +# (STM32F1 genericSTM32F103VE) +# + +# exit on first failure +set -e + +use_example_configs Mks/Robin +opt_set MOTHERBOARD BOARD_MKS_ROBIN_NANO +opt_disable TFT_320x240 +opt_enable TOUCH_SCREEN +opt_enable FSMC_GRAPHICAL_TFT +exec_test $1 $2 "MKS Robin nano v1.2 Emulated DOGM FSMC" + +use_example_configs Mks/Robin +opt_set MOTHERBOARD BOARD_MKS_ROBIN_NANO_V2 +opt_disable TFT_320x240 +opt_enable TOUCH_SCREEN +opt_enable SPI_GRAPHICAL_TFT +exec_test $1 $2 "MKS Robin v2 nano Emulated DOGM SPI" + +use_example_configs Mks/Robin +opt_set MOTHERBOARD BOARD_MKS_ROBIN_NANO +opt_disable TFT_320x240 +opt_disable TOUCH_SCREEN +opt_enable TFT_LVGL_UI_FSMC +exec_test $1 $2 "MKS Robin nano v1.2 LVGL FSMC" + +use_example_configs Mks/Robin +opt_set MOTHERBOARD BOARD_MKS_ROBIN_NANO_V2 +opt_disable TFT_320x240 +opt_disable TOUCH_SCREEN +opt_enable TFT_LVGL_UI_SPI +exec_test $1 $2 "MKS Robin v2 nano LVGL SPI" + +use_example_configs Mks/Robin +opt_set MOTHERBOARD BOARD_MKS_ROBIN_NANO_V2 +opt_disable TFT_320x240 +opt_enable TOUCH_SCREEN +opt_enable TFT_480x320_SPI +exec_test $1 $2 "MKS Robin v2 nano New Color UI 480x320 SPI" + +# cleanup +restore_configs diff --git a/buildroot/tests/mks_robin_pro-tests b/buildroot/tests/mks_robin_pro-tests new file mode 100644 index 000000000000..7ae4670fedac --- /dev/null +++ b/buildroot/tests/mks_robin_pro-tests @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +# +# Build tests for MKS Robin Pro +# + +# exit on first failure +set -e + +use_example_configs Mks/Robin_Pro +opt_enable EMERGENCY_PARSER +opt_set SDCARD_CONNECTION LCD +opt_set X_DRIVER_TYPE TMC2209 +opt_set Y_DRIVER_TYPE TMC2130 +opt_set TEMP_SENSOR_BED 1 +opt_disable THERMAL_PROTECTION_HOTENDS +exec_test $1 $2 "MKS Robin Pro with TMC Drivers, hotend thermal protection disabled" + +# cleanup +#restore_configs diff --git a/buildroot/share/tests/mks_robin-tests b/buildroot/tests/mks_robin_stm32-tests similarity index 56% rename from buildroot/share/tests/mks_robin-tests rename to buildroot/tests/mks_robin_stm32-tests index 99d41ef4ad56..4aa146fa5288 100644 --- a/buildroot/share/tests/mks_robin-tests +++ b/buildroot/tests/mks_robin_stm32-tests @@ -1,13 +1,13 @@ #!/usr/bin/env bash # -# Build tests for STM32F1 genericSTM32F103ZE +# Build tests for MKS Robin (HAL/STM32) # # exit on first failure set -e use_example_configs Mks/Robin -exec_test $1 $2 "Default Configuration" +exec_test $1 $2 "MKS Robin base configuration" # cleanup restore_configs diff --git a/buildroot/tests/rambo-tests b/buildroot/tests/rambo-tests new file mode 100644 index 000000000000..ec8af16c23b4 --- /dev/null +++ b/buildroot/tests/rambo-tests @@ -0,0 +1,75 @@ +#!/usr/bin/env bash +# +# Build tests for AVR ATmega2560 RAMBo +# + +# exit on first failure +set -e + +# +# Lots of options - Formerly the first Mega2560 test +# +restore_configs +opt_set MOTHERBOARD BOARD_RAMBO +opt_set EXTRUDERS 2 +opt_set TEMP_SENSOR_0 -2 +opt_set TEMP_SENSOR_1 1 +opt_set TEMP_SENSOR_BED 2 +opt_set TEMP_SENSOR_PROBE 1 +opt_add TEMP_PROBE_PIN 12 +opt_set TEMP_SENSOR_CHAMBER 3 +opt_add TEMP_CHAMBER_PIN 3 +opt_add HEATER_CHAMBER_PIN 45 +opt_set GRID_MAX_POINTS_X 16 +opt_set FANMUX0_PIN 53 +opt_disable USE_WATCHDOG +opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER LCD_PROGRESS_BAR LCD_PROGRESS_BAR_TEST \ + FIX_MOUNTED_PROBE Z_SAFE_HOMING CODEPENDENT_XY_HOMING PIDTEMPBED PROBE_TEMP_COMPENSATION \ + PROBING_HEATERS_OFF PROBING_FANS_OFF PROBING_STEPPERS_OFF WAIT_FOR_BED_HEATER \ + EEPROM_SETTINGS SDSUPPORT SD_REPRINT_LAST_SELECTED_FILE BINARY_FILE_TRANSFER \ + BLINKM PCA9533 PCA9632 RGB_LED RGB_LED_R_PIN RGB_LED_G_PIN RGB_LED_B_PIN LED_CONTROL_MENU \ + NEOPIXEL_LED CASE_LIGHT_ENABLE CASE_LIGHT_USE_NEOPIXEL CASE_LIGHT_MENU \ + PID_PARAMS_PER_HOTEND PID_AUTOTUNE_MENU PID_EDIT_MENU LCD_SHOW_E_TOTAL \ + PRINTCOUNTER SERVICE_NAME_1 SERVICE_INTERVAL_1 LEVEL_BED_CORNERS \ + NOZZLE_PARK_FEATURE FILAMENT_RUNOUT_SENSOR FILAMENT_RUNOUT_DISTANCE_MM \ + ADVANCED_PAUSE_FEATURE FILAMENT_LOAD_UNLOAD_GCODES FILAMENT_UNLOAD_ALL_EXTRUDERS \ + PASSWORD_FEATURE PASSWORD_ON_STARTUP PASSWORD_ON_SD_PRINT_MENU PASSWORD_AFTER_SD_PRINT_END PASSWORD_AFTER_SD_PRINT_ABORT \ + AUTO_BED_LEVELING_BILINEAR Z_MIN_PROBE_REPEATABILITY_TEST DISTINCT_E_FACTORS \ + SKEW_CORRECTION SKEW_CORRECTION_FOR_Z SKEW_CORRECTION_GCODE \ + BACKLASH_COMPENSATION BACKLASH_GCODE BAUD_RATE_GCODE BEZIER_CURVE_SUPPORT \ + FWRETRACT ARC_P_CIRCLES CNC_WORKSPACE_PLANES CNC_COORDINATE_SYSTEMS \ + PSU_CONTROL AUTO_POWER_CONTROL POWER_LOSS_RECOVERY POWER_LOSS_PIN POWER_LOSS_STATE \ + SLOW_PWM_HEATERS THERMAL_PROTECTION_CHAMBER LIN_ADVANCE EXTRA_LIN_ADVANCE_K \ + HOST_ACTION_COMMANDS HOST_PROMPT_SUPPORT PINS_DEBUGGING MAX7219_DEBUG M114_DETAIL +opt_add DEBUG_POWER_LOSS_RECOVERY +exec_test $1 $2 "RAMBO | EXTRUDERS 2 | CHAR LCD + SD | FIX Probe | ABL-Linear | Advanced Pause | PLR | LEDs ..." + +# +# Full size Rambo Dual Endstop CNC +# +restore_configs +opt_set MOTHERBOARD BOARD_RAMBO +opt_set EXTRUDERS 0 +opt_set TEMP_SENSOR_0 999 +opt_set DUMMY_THERMISTOR_999_VALUE 170 +opt_set DIGIPOT_MOTOR_CURRENT '{ 120, 120, 120, 120, 120 }' +opt_enable USE_XMAX_PLUG USE_YMAX_PLUG USE_ZMAX_PLUG \ + REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER REVERSE_ENCODER_DIRECTION SDSUPPORT EEPROM_SETTINGS \ + S_CURVE_ACCELERATION X_DUAL_STEPPER_DRIVERS X_DUAL_ENDSTOPS Y_DUAL_STEPPER_DRIVERS Y_DUAL_ENDSTOPS \ + ADAPTIVE_STEP_SMOOTHING CNC_COORDINATE_SYSTEMS GCODE_MOTION_MODES +opt_disable MIN_SOFTWARE_ENDSTOP_Z MAX_SOFTWARE_ENDSTOPS +exec_test $1 $2 "Rambo CNC Configuration" + +# +# Build with the default configurations +# +restore_configs +opt_set MOTHERBOARD BOARD_EINSY_RAMBO +opt_set X_DRIVER_TYPE TMC2130 +opt_set Y_DRIVER_TYPE TMC2130 +opt_set Z_DRIVER_TYPE TMC2130 +opt_set E0_DRIVER_TYPE TMC2130 +exec_test $1 $2 "Einsy RAMBo with TMC2130" + +# clean up +restore_configs diff --git a/buildroot/tests/rumba32-tests b/buildroot/tests/rumba32-tests new file mode 100644 index 000000000000..42f9beb9afde --- /dev/null +++ b/buildroot/tests/rumba32-tests @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# +# Build tests for rumba32 +# + +# exit on first failure +set -e + +# Build examples +restore_configs +opt_set MOTHERBOARD BOARD_RUMBA32_V1_0 +opt_set SERIAL_PORT -1 +opt_disable PIDTEMP +opt_enable PIDTEMPBED +opt_set TEMP_SENSOR_BED 1 +opt_disable THERMAL_PROTECTION_BED +opt_set X_DRIVER_TYPE TMC2130 +exec_test $1 $2 "RUMBA32 V1.0 with TMC2130, PID Bed, and bed thermal protection disabled" + +# Build examples +restore_configs +opt_set MOTHERBOARD BOARD_RUMBA32_V1_1 +opt_set SERIAL_PORT -1 +opt_enable PIDTEMPBED EEPROM_SETTINGS EEPROM_CHITCHAT REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER +opt_set TEMP_SENSOR_BED 1 +opt_set X_DRIVER_TYPE TMC2130 +opt_set Y_DRIVER_TYPE TMC2208 +exec_test $1 $2 "RUMBA32 V1.1 with TMC2130, TMC2208, PID Bed, EEPROM settings, and graphic LCD controller" + +# Build examples +restore_configs +opt_set MOTHERBOARD BOARD_RUMBA32_MKS +opt_set SERIAL_PORT -1 +opt_set X_DRIVER_TYPE TMC2130 +opt_set Y_DRIVER_TYPE TMC2208 +exec_test $1 $2 "RUMBA32 MKS Default Config with Mixed TMC Drivers" + +# cleanup +restore_configs diff --git a/buildroot/share/tests/run_tests b/buildroot/tests/run_tests similarity index 100% rename from buildroot/share/tests/run_tests rename to buildroot/tests/run_tests diff --git a/buildroot/share/tests/sanguino_atmega1284p-tests b/buildroot/tests/sanguino1284p-tests similarity index 100% rename from buildroot/share/tests/sanguino_atmega1284p-tests rename to buildroot/tests/sanguino1284p-tests diff --git a/buildroot/share/tests/sanguino_atmega644p-tests b/buildroot/tests/sanguino644p-tests similarity index 100% rename from buildroot/share/tests/sanguino_atmega644p-tests rename to buildroot/tests/sanguino644p-tests diff --git a/buildroot/share/tests/teensy31-tests b/buildroot/tests/teensy31-tests similarity index 100% rename from buildroot/share/tests/teensy31-tests rename to buildroot/tests/teensy31-tests diff --git a/buildroot/share/tests/teensy35-tests b/buildroot/tests/teensy35-tests similarity index 92% rename from buildroot/share/tests/teensy35-tests rename to buildroot/tests/teensy35-tests index f2a098e7cd1c..c729f212a427 100755 --- a/buildroot/share/tests/teensy35-tests +++ b/buildroot/tests/teensy35-tests @@ -83,13 +83,21 @@ exec_test $1 $2 "Mixing Extruder" # opt_set NUM_SERVOS 1 # opt_enable SWITCHING_EXTRUDER ULTIMAKERCONTROLLER # exec_test $1 $2 "SWITCHING_EXTRUDER" + # # Enable COREXY # restore_configs opt_set MOTHERBOARD BOARD_TEENSY35_36 opt_enable COREXY -exec_test $1 $2 "COREXY" +opt_set X_DRIVER_TYPE TMC5160 +opt_set Y_DRIVER_TYPE TMC5160 +opt_set X_MIN_ENDSTOP_INVERTING true +opt_set Y_MIN_ENDSTOP_INVERTING true +opt_add X_CS_PIN 46 +opt_add Y_CS_PIN 47 +opt_enable USE_ZMIN_PLUG MONITOR_DRIVER_STATUS SENSORLESS_HOMING +exec_test $1 $2 "Teensy 3.5/3.6 COREXY" # # Enable COREXZ @@ -97,7 +105,7 @@ exec_test $1 $2 "COREXY" restore_configs opt_set MOTHERBOARD BOARD_TEENSY35_36 opt_enable COREXZ -exec_test $1 $2 "COREXZ" +exec_test $1 $2 "Teensy 3.5/3.6 COREXZ" # # Enable Dual Z with Dual Z endstops diff --git a/buildroot/tests/teensy41-tests b/buildroot/tests/teensy41-tests new file mode 100644 index 000000000000..8d32d131e91c --- /dev/null +++ b/buildroot/tests/teensy41-tests @@ -0,0 +1,124 @@ +#!/usr/bin/env bash +# +# Build tests for Teensy 4.0/4.1 (ARM Cortex-M7) +# + +# exit on first failure +set -e + +restore_configs +opt_set MOTHERBOARD BOARD_TEENSY41 +exec_test $1 $2 "Teensy4.1 with default config" + +# +# Test as many features together as possible +# +restore_configs +opt_set MOTHERBOARD BOARD_TEENSY41 +opt_set EXTRUDERS 2 +opt_set TEMP_SENSOR_0 1 +opt_set TEMP_SENSOR_1 5 +opt_set TEMP_SENSOR_BED 1 +opt_enable EXTENSIBLE_UI LCD_INFO_MENU SDSUPPORT SDCARD_SORT_ALPHA \ + FILAMENT_LCD_DISPLAY CALIBRATION_GCODE BAUD_RATE_GCODE \ + FIX_MOUNTED_PROBE Z_SAFE_HOMING AUTO_BED_LEVELING_BILINEAR Z_MIN_PROBE_REPEATABILITY_TEST DEBUG_LEVELING_FEATURE \ + BABYSTEPPING BABYSTEP_XY BABYSTEP_ZPROBE_OFFSET \ + PRINTCOUNTER NOZZLE_PARK_FEATURE NOZZLE_CLEAN_FEATURE SLOW_PWM_HEATERS PIDTEMPBED EEPROM_SETTINGS INCH_MODE_SUPPORT TEMPERATURE_UNITS_SUPPORT \ + ADVANCED_PAUSE_FEATURE ARC_SUPPORT BEZIER_CURVE_SUPPORT EXPERIMENTAL_I2CBUS EXTENDED_CAPABILITIES_REPORT AUTO_REPORT_TEMPERATURES PARK_HEAD_ON_PAUSE \ + PHOTO_GCODE PHOTO_POSITION PHOTO_SWITCH_POSITION PHOTO_SWITCH_MS PHOTO_DELAY_MS PHOTO_RETRACT_MM \ + HOST_ACTION_COMMANDS HOST_PROMPT_SUPPORT +opt_add EXTUI_EXAMPLE +opt_set I2C_SLAVE_ADDRESS 63 +opt_set GRID_MAX_POINTS_X 16 +exec_test $1 $2 "Teensy4.1 with many features" + +# +# Test a Sled Z Probe with Linear leveling +# +restore_configs +opt_set MOTHERBOARD BOARD_TEENSY41 +opt_enable EEPROM_SETTINGS Z_PROBE_SLED Z_SAFE_HOMING AUTO_BED_LEVELING_LINEAR DEBUG_LEVELING_FEATURE GCODE_MACROS +exec_test $1 $2 "Sled Z Probe with Linear leveling" + +# +# Test a Servo Probe +# +# restore_configs +# opt_set MOTHERBOARD BOARD_TEENSY41 +# opt_enable Z_PROBE_SERVO_NR Z_SERVO_ANGLES DEACTIVATE_SERVOS_AFTER_MOVE \ +# AUTO_BED_LEVELING_3POINT DEBUG_LEVELING_FEATURE EEPROM_SETTINGS +# opt_set NUM_SERVOS 1 +# exec_test $1 $2 "Servo Probe" +# +# ...with AUTO_BED_LEVELING_3POINT, DEBUG_LEVELING_FEATURE, EEPROM_SETTINGS, EEPROM_CHITCHAT, EXTENDED_CAPABILITIES_REPORT, and AUTO_REPORT_TEMPERATURES +# +# opt_enable AUTO_BED_LEVELING_3POINT DEBUG_LEVELING_FEATURE EEPROM_SETTINGS \ +# EXTENDED_CAPABILITIES_REPORT AUTO_REPORT_TEMPERATURES +# exec_test $1 $2 "...with AUTO_BED_LEVELING_3POINT, DEBUG_LEVELING_FEATURE, EEPROM_SETTINGS, EEPROM_CHITCHAT, EXTENDED_CAPABILITIES_REPORT, and AUTO_REPORT_TEMPERATURES" + +# +# Test MAGNETIC_PARKING_EXTRUDER with LCD +# +restore_configs +opt_set MOTHERBOARD BOARD_TEENSY41 +opt_set EXTRUDERS 2 +opt_set TEMP_SENSOR_1 1 +opt_enable MAGNETIC_PARKING_EXTRUDER +exec_test $1 $2 "MAGNETIC_PARKING_EXTRUDER with LCD" + +# +# Mixing Extruder +# +restore_configs +opt_set MOTHERBOARD BOARD_TEENSY41 +opt_enable MIXING_EXTRUDER DIRECT_MIXING_IN_G1 GRADIENT_MIX GRADIENT_VTOOL +opt_set MIXING_STEPPERS 2 +exec_test $1 $2 "Mixing Extruder" + +# +# Test SWITCHING_EXTRUDER +# +# restore_configs +# opt_set MOTHERBOARD BOARD_TEENSY41 +# opt_set EXTRUDERS 2 +# opt_set NUM_SERVOS 1 +# opt_enable SWITCHING_EXTRUDER ULTIMAKERCONTROLLER +# exec_test $1 $2 "SWITCHING_EXTRUDER" + +# +# Enable COREXY +# +restore_configs +opt_set MOTHERBOARD BOARD_TEENSY41 +opt_enable COREXY +opt_set X_DRIVER_TYPE TMC5160 +opt_set Y_DRIVER_TYPE TMC5160 +opt_set X_MIN_ENDSTOP_INVERTING true +opt_set Y_MIN_ENDSTOP_INVERTING true +opt_add X_CS_PIN 46 +opt_add Y_CS_PIN 47 +opt_enable USE_ZMIN_PLUG MONITOR_DRIVER_STATUS SENSORLESS_HOMING +exec_test $1 $2 "Teensy 4.0/4.1 COREXY" + +# +# Enable COREXZ +# +restore_configs +opt_set MOTHERBOARD BOARD_TEENSY41 +opt_enable COREXZ +exec_test $1 $2 "Teensy 4.0/4.1 COREXZ" + +# +# Enable Dual Z with Dual Z endstops +# +restore_configs +opt_set MOTHERBOARD BOARD_TEENSY41 +opt_enable Z_MULTI_ENDSTOPS +opt_set NUM_Z_STEPPER_DRIVERS 2 +pins_set ramps/RAMPS X_MAX_PIN -1 +opt_add Z2_MAX_PIN 2 +opt_enable USE_XMAX_PLUG +exec_test $1 $2 "Dual Z with Dual Z endstops" + +# Clean up +restore_configs diff --git a/config/README.md b/config/README.md index 3db488e8e9b3..68cbe1a78607 100644 --- a/config/README.md +++ b/config/README.md @@ -1,3 +1,3 @@ # Where have all the configurations gone? -## https://github.com/MarlinFirmware/Configurations/archive/release-2.0.4.zip +## https://github.com/MarlinFirmware/Configurations/archive/release-2.0.7.2.zip diff --git a/platformio.ini b/platformio.ini index c67f5c2b8a06..0abb4ac38810 100644 --- a/platformio.ini +++ b/platformio.ini @@ -4,11 +4,11 @@ # # For detailed documentation with EXAMPLES: # -# http://docs.platformio.org/en/latest/projectconf.html +# https://docs.platformio.org/en/latest/projectconf/index.html # # Automatic targets - enable auto-uploading -# targets = upload +#targets = upload # # By default platformio build will abort after 5 errors. @@ -18,31 +18,392 @@ [platformio] src_dir = Marlin boards_dir = buildroot/share/PlatformIO/boards -default_envs = megaatmega2560 +default_envs = mega2560 +include_dir = Marlin +# +# The 'common' values are used for most Marlin builds +# [common] default_src_filter = + - - + -extra_scripts = pre:buildroot/share/PlatformIO/scripts/common-cxxflags.py -build_flags = -fmax-errors=5 -g -D__MARLIN_FIRMWARE__ -fmerge-all-constants -lib_deps = - LiquidCrystal - TMCStepper@>=0.6.2,<1.0.0 - Adafruit NeoPixel - U8glib-HAL=https://github.com/MarlinFirmware/U8glib-HAL/archive/bugfix.zip - Adafruit_MAX31865=https://github.com/adafruit/Adafruit_MAX31865/archive/master.zip - LiquidTWI2=https://github.com/lincomatic/LiquidTWI2/archive/master.zip - Arduino-L6470=https://github.com/ameyer/Arduino-L6470/archive/0.8.0.zip - SailfishLCD=https://github.com/mikeshub/SailfishLCD/archive/master.zip - SailfishRGB_LED=https://github.com/mikeshub/SailfishRGB_LED/archive/master.zip - SlowSoftI2CMaster=https://github.com/mikeshub/SlowSoftI2CMaster/archive/master.zip - -# Globally defined properties -# inherited by all environments + - - - - - - + - - + - + - - - + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + - + - + - + - - + - - + - + - + - + - + - + - + - - + - - + - - + - - + - - + - + - - + - - + - + - - + - - + - - + - + - + - + - - + - - + - + - + - + - + - + - + - + - + - + - + - + - + - - + - - + - + - + - - + - - + - + - - + - + - - + - - + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + - - + - + - + - - + - + - + - + - + - - + - +extra_scripts = + pre:buildroot/share/PlatformIO/scripts/common-dependencies.py + pre:buildroot/share/PlatformIO/scripts/common-cxxflags.py + post:buildroot/share/PlatformIO/scripts/common-dependencies-post.py +build_flags = -fmax-errors=5 -g -D__MARLIN_FIRMWARE__ -fmerge-all-constants +lib_deps = + +# +# Feature Dependencies +# +[features] +HAS_TFT_LVGL_UI = lvgl=https://github.com/makerbase-mks/LVGL-6.1.1-MKS/archive/master.zip + src_filter=+ + extra_scripts=download_mks_assets.py +HAS_TRINAMIC_CONFIG = TMCStepper@~0.7.1 + src_filter=+ + + + + +HAS_STEALTHCHOP = src_filter=+ +SR_LCD_3W_NL = SailfishLCD=https://github.com/mikeshub/SailfishLCD/archive/master.zip +HAS_MOTOR_CURRENT_I2C = SlowSoftI2CMaster + src_filter=+ +HAS_TMC26X = TMC26XStepper=https://github.com/trinamic/TMC26XStepper/archive/master.zip + src_filter=+ +HAS_L64XX = Arduino-L6470@0.8.0 + src_filter=+ + + +NEOPIXEL_LED = Adafruit NeoPixel@1.5.0 + src_filter=+ +MAX6675_IS_MAX31865 = Adafruit MAX31865 library@~1.1.0 +USES_LIQUIDCRYSTAL = LiquidCrystal@1.5.0 +USES_LIQUIDTWI2 = LiquidTWI2@1.2.7 +HAS_WIRED_LCD = src_filter=+ +HAS_MARLINUI_HD44780 = src_filter=+ +HAS_MARLINUI_U8GLIB = U8glib-HAL@~0.4.1 + src_filter=+ +HAS_(FSMC|SPI)_TFT = src_filter=+ + + +HAS_FSMC_TFT = src_filter=+ + +HAS_SPI_TFT = src_filter=+ + +HAS_GRAPHICAL_TFT = src_filter=+ +DWIN_CREALITY_LCD = src_filter=+ +IS_TFTGLCD_PANEL = src_filter=+ +HAS_TOUCH_XPT2046 = src_filter=+ +HAS_LCD_MENU = src_filter=+ +HAS_GAMES = src_filter=+ +MARLIN_BRICKOUT = src_filter=+ +MARLIN_INVADERS = src_filter=+ +MARLIN_MAZE = src_filter=+ +MARLIN_SNAKE = src_filter=+ +HAS_MENU_BACKLASH = src_filter=+ +HAS_MENU_BED_CORNERS = src_filter=+ +LCD_BED_LEVELING = src_filter=+ +HAS_MENU_CANCELOBJECT = src_filter=+ +HAS_MENU_DELTA_CALIBRATE = src_filter=+ +HAS_MENU_FILAMENT = src_filter=+ +LCD_INFO_MENU = src_filter=+ +HAS_MENU_JOB_RECOVERY = src_filter=+ +HAS_MENU_LED = src_filter=+ +HAS_MENU_MEDIA = src_filter=+ +HAS_MENU_MIXER = src_filter=+ +HAS_MENU_MMU2 = src_filter=+ +HAS_MENU_PASSWORD = src_filter=+ +HAS_MENU_POWER_MONITOR = src_filter=+ +HAS_MENU_CUTTER = src_filter=+ +HAS_MENU_TEMPERATURE = src_filter=+ +HAS_MENU_TMC = src_filter=+ +HAS_MENU_TOUCH_SCREEN = src_filter=+ +HAS_MENU_UBL = src_filter=+ +ANYCUBIC_LCD_CHIRON = src_filter=+ + +ANYCUBIC_LCD_I3MEGA = src_filter=+ + +HAS_DGUS_LCD = src_filter=+ + +TOUCH_UI_FTDI_EVE = src_filter=+ +EXTUI_EXAMPLE = src_filter=+ +MALYAN_LCD = src_filter=+ +USB_FLASH_DRIVE_SUPPORT = src_filter=+ +AUTO_BED_LEVELING_BILINEAR = src_filter=+ +AUTO_BED_LEVELING_(3POINT|(BI)?LINEAR) = src_filter=+ +MESH_BED_LEVELING = src_filter=+ + +AUTO_BED_LEVELING_UBL = src_filter=+ + +BACKLASH_COMPENSATION = src_filter=+ +BARICUDA = src_filter=+ + +BINARY_FILE_TRANSFER = src_filter=+ + +BLTOUCH = src_filter=+ +CANCEL_OBJECTS = src_filter=+ + +CASE_LIGHT_ENABLE = src_filter=+ + +EXTERNAL_CLOSED_LOOP_CONTROLLER = src_filter=+ + +USE_CONTROLLER_FAN = src_filter=+ +HAS_MOTOR_CURRENT_DAC = src_filter=+ +DIRECT_STEPPING = src_filter=+ + +EMERGENCY_PARSER = src_filter=+ - +I2C_POSITION_ENCODERS = src_filter=+ +IIC_BL24CXX_EEPROM = src_filter=+ +HAS_SPI_FLASH = src_filter=+ +HAS_FANMUX = src_filter=+ +FILAMENT_WIDTH_SENSOR = src_filter=+ + +FWRETRACT = src_filter=+ + +HOST_ACTION_COMMANDS = src_filter=+ +HOTEND_IDLE_TIMEOUT = src_filter=+ +JOYSTICK = src_filter=+ +BLINKM = src_filter=+ +HAS_COLOR_LEDS = src_filter=+ + +PCA9533 = src_filter=+ +PCA9632 = src_filter=+ +PRINTER_EVENT_LEDS = src_filter=+ +TEMP_STAT_LEDS = src_filter=+ +MAX7219_DEBUG = src_filter=+ + +MIXING_EXTRUDER = src_filter=+ + +PRUSA_MMU2 = src_filter=+ + +PASSWORD_FEATURE = src_filter=+ + +ADVANCED_PAUSE_FEATURE = src_filter=+ + + +AUTO_POWER_CONTROL = src_filter=+ +HAS_POWER_MONITOR = src_filter=+ + +POWER_LOSS_RECOVERY = src_filter=+ + +PROBE_TEMP_COMPENSATION = src_filter=+ + +HAS_FILAMENT_SENSOR = src_filter=+ + +MK2_MULTIPLEXER = src_filter=+ +EXT_SOLENOID|MANUAL_SOLENOID_CONTROL = src_filter=+ + +HAS_CUTTER = src_filter=+ + +EXPERIMENTAL_I2CBUS = src_filter=+ + +MECHANICAL_GANTRY_CAL.+ = src_filter=+ +Z_STEPPER_AUTO_ALIGN = src_filter=+ + +G26_MESH_VALIDATION = src_filter=+ +ASSISTED_TRAMMING = src_filter=+ +HAS_MESH = src_filter=+ +HAS_LEVELING = src_filter=+ +DELTA_AUTO_CALIBRATION = src_filter=+ +CALIBRATION_GCODE = src_filter=+ +Z_MIN_PROBE_REPEATABILITY_TEST = src_filter=+ +M100_FREE_MEMORY_WATCHER = src_filter=+ +BACKLASH_GCODE = src_filter=+ +IS_KINEMATIC = src_filter=+ +HAS_EXTRA_ENDSTOPS = src_filter=+ +SKEW_CORRECTION_GCODE = src_filter=+ +DIRECT_PIN_CONTROL = src_filter=+ + +PINS_DEBUGGING = src_filter=+ +NO_VOLUMETRICS = src_filter=- +HAS_MULTI_EXTRUDER = src_filter=+ +HAS_HOTEND_OFFSET = src_filter=+ +EDITABLE_SERVO_ANGLES = src_filter=+ +PIDTEMP = src_filter=+ +PREVENT_COLD_EXTRUSION = src_filter=+ +PIDTEMPBED = src_filter=+ +HAS_USER_THERMISTORS = src_filter=+ +SD_ABORT_ON_ENDSTOP_HIT = src_filter=+ +BAUD_RATE_GCODE = src_filter=+ +HAS_SMART_EFF_MOD = src_filter=+ +COOLANT_CONTROL = src_filter=+ +HAS_SOFTWARE_ENDSTOPS = src_filter=+ +HAS_DUPLICATION_MODE = src_filter=+ +LIN_ADVANCE = src_filter=+ +PHOTO_GCODE = src_filter=+ +CONTROLLER_FAN_EDITABLE = src_filter=+ +GCODE_MACROS = src_filter=+ +GRADIENT_MIX = src_filter=+ +HAS_SAVED_POSITIONS = src_filter=+ + +PARK_HEAD_ON_PAUSE = src_filter=+ +FILAMENT_LOAD_UNLOAD_GCODES = src_filter=+ +CNC_WORKSPACE_PLANES = src_filter=+ +CNC_COORDINATE_SYSTEMS = src_filter=+ +HAS_M206_COMMAND = src_filter=+ +EXPECTED_PRINTER_CHECK = src_filter=+ +HOST_KEEPALIVE_FEATURE = src_filter=+ +REPETIER_GCODE_M360 = src_filter=+ +HAS_GCODE_M876 = src_filter=+ +HAS_RESUME_CONTINUE = src_filter=+ +HAS_LCD_CONTRAST = src_filter=+ +LCD_SET_PROGRESS_MANUALLY = src_filter=+ +TOUCH_SCREEN_CALIBRATION = src_filter=+ +ARC_SUPPORT = src_filter=+ +GCODE_MOTION_MODES = src_filter=+ +BABYSTEPPING = src_filter=+ + +Z_PROBE_SLED = src_filter=+ +G38_PROBE_TARGET = src_filter=+ +MAGNETIC_PARKING_EXTRUDER = src_filter=+ +SDSUPPORT = src_filter=+ +HAS_EXTRUDERS = src_filter=+ + +AUTO_REPORT_TEMPERATURES = src_filter=+ +INCH_MODE_SUPPORT = src_filter=+ +TEMPERATURE_UNITS_SUPPORT = src_filter=+ +NEED_HEX_PRINT = src_filter=+ +NEED_LSF = src_filter=+ +NOZZLE_PARK_FEATURE = src_filter=+ + +NOZZLE_CLEAN_FEATURE = src_filter=+ + +DELTA = src_filter=+ + +BEZIER_CURVE_SUPPORT = src_filter=+ + +PRINTCOUNTER = src_filter=+ +HAS_BED_PROBE = src_filter=+ + + + +IS_SCARA = src_filter=+ +MORGAN_SCARA = src_filter=+ +(ESP3D_)?WIFISUPPORT = AsyncTCP, ESP Async WebServer + ESP3DLib=https://github.com/luc-github/ESP3DLib.git + arduinoWebSockets=https://github.com/Links2004/arduinoWebSockets.git + ESP32SSDP=https://github.com/luc-github/ESP32SSDP.git + lib_ignore=ESPAsyncTCP + +# +# Default values apply to all 'env:' prefixed environments +# [env] framework = arduino +extra_scripts = ${common.extra_scripts} build_flags = ${common.build_flags} lib_deps = ${common.lib_deps} monitor_speed = 250000 +monitor_flags = + --quiet + --echo + --eol + LF + --filter + colorize + --filter + time ################################# # # @@ -54,105 +415,139 @@ monitor_speed = 250000 # # ################################# +################################# +# # +# AVR Architecture # +# # +################################# + # -# ATmega2560 +# AVR (8-bit) Common Environment values # -[env:megaatmega2560] -platform = atmelavr -board = megaatmega2560 +[common_avr8] board_build.f_cpu = 16000000L -lib_deps = ${common.lib_deps} - TMC26XStepper=https://github.com/trinamic/TMC26XStepper/archive/master.zip -src_filter = ${common.default_src_filter} + +src_filter = ${common.default_src_filter} + + +# +# ATmega2560 +# +[env:mega2560] +platform = atmelavr +extends = common_avr8 +board = megaatmega2560 + +# +# ATmega2560 with extended pins 70-85 defined +# BOARD_BQ_ZUM_MEGA_3D +# BOARD_ULTIMAIN_2 +# BOARD_MIGHTYBOARD_REVE +# BOARD_EINSTART_S +# +[env:mega2560ext] +platform = atmelavr +extends = env:mega2560 +board = megaatmega2560 +board_build.variant = megaextendedpins +extra_scripts = ${common.extra_scripts} + pre:buildroot/share/PlatformIO/scripts/copy_marlin_variant_to_framework.py # # ATmega1280 # -[env:megaatmega1280] -platform = atmelavr -board = megaatmega1280 -board_build.f_cpu = 16000000L -lib_deps = ${common.lib_deps} - TMC26XStepper=https://github.com/trinamic/TMC26XStepper/archive/master.zip -src_filter = ${common.default_src_filter} + +[env:mega1280] +platform = atmelavr +extends = common_avr8 +board = megaatmega1280 + +# +# MightyBoard ATmega2560 (MegaCore 100 pin boards variants) +# +[env:MightyBoard1280] +platform = atmelavr +extends = common_avr8 +board = ATmega1280 +upload_speed = 57600 + +# +# MightyBoard ATmega2560 (MegaCore 100 pin boards variants) +# +[env:MightyBoard2560] +platform = atmelavr +extends = common_avr8 +board = ATmega2560 +upload_protocol = wiring +upload_speed = 57600 +board_upload.maximum_size = 253952 # # RAMBo # [env:rambo] -platform = atmelavr -board = reprap_rambo -board_build.f_cpu = 16000000L -lib_deps = ${common.lib_deps} - TMC26XStepper=https://github.com/trinamic/TMC26XStepper/archive/master.zip -src_filter = ${common.default_src_filter} + +platform = atmelavr +extends = common_avr8 +board = reprap_rambo # # FYSETC F6 V1.3 # [env:FYSETC_F6_13] -platform = atmelavr -board = fysetc_f6_13 -board_build.f_cpu = 16000000L -lib_deps = ${common.lib_deps} - TMC26XStepper=https://github.com/trinamic/TMC26XStepper/archive/master.zip -src_filter = ${common.default_src_filter} + +platform = atmelavr +extends = common_avr8 +board = fysetc_f6_13 # # FYSETC F6 V1.4 # [env:FYSETC_F6_14] -platform = atmelavr -board = fysetc_f6_14 -board_build.f_cpu = 16000000L -lib_deps = ${common.lib_deps} - TMC26XStepper=https://github.com/trinamic/TMC26XStepper/archive/master.zip -src_filter = ${common.default_src_filter} + +platform = atmelavr +extends = common_avr8 +board = fysetc_f6_14 # # Sanguinololu (ATmega644p) # -[env:sanguino_atmega644p] +[env:sanguino644p] platform = atmelavr +extends = common_avr8 board = sanguino_atmega644p -lib_deps = ${common.lib_deps} - TMC26XStepper=https://github.com/trinamic/TMC26XStepper/archive/master.zip -src_filter = ${common.default_src_filter} + # # Sanguinololu (ATmega1284p) # -[env:sanguino_atmega1284p] +[env:sanguino1284p] platform = atmelavr +extends = common_avr8 board = sanguino_atmega1284p -lib_deps = ${common.lib_deps} - TMC26XStepper=https://github.com/trinamic/TMC26XStepper/archive/master.zip -src_filter = ${common.default_src_filter} + +board_upload.maximum_size = 126976 # # Melzi and clones (ATmega1284p) # [env:melzi] platform = atmelavr +extends = common_avr8 board = sanguino_atmega1284p -lib_deps = ${common.lib_deps} - TMC26XStepper=https://github.com/trinamic/TMC26XStepper/archive/master.zip -src_filter = ${common.default_src_filter} + -lib_ignore = TMCStepper upload_speed = 57600 +board_upload.maximum_size = 126976 # # Melzi and clones (Optiboot bootloader) # [env:melzi_optiboot] platform = atmelavr +extends = common_avr8 board = sanguino_atmega1284p -lib_deps = ${common.lib_deps} - TMC26XStepper=https://github.com/trinamic/TMC26XStepper/archive/master.zip -src_filter = ${common.default_src_filter} + -lib_ignore = TMCStepper upload_speed = 115200 +# +# Melzi and clones (Zonestar Melzi2 with tuned flags) +# +[env:melzi_optimized] +platform = atmelavr +extends = env:melzi_optiboot +build_flags = ${common.build_flags} -fno-tree-scev-cprop -fno-split-wide-types -Wl,--relax -mcall-prologues +build_unflags = -g -ggdb + # # AT90USB1286 boards using CDC bootloader # - BRAINWAVE @@ -162,11 +557,9 @@ upload_speed = 115200 # [env:at90usb1286_cdc] platform = teensy +extends = common_avr8 board = at90usb1286 -lib_deps = ${common.lib_deps} - TMC26XStepper=https://github.com/trinamic/TMC26XStepper/archive/master.zip -lib_ignore = TMCStepper -src_filter = ${common.default_src_filter} + +lib_ignore = ${env:common_avr8.lib_ignore} Teensy_ADC # # AT90USB1286 boards using DFU bootloader @@ -176,10 +569,13 @@ src_filter = ${common.default_src_filter} + # [env:at90usb1286_dfu] platform = teensy -board = at90usb1286 -lib_deps = ${common.lib_deps} -lib_ignore = TMCStepper -src_filter = ${common.default_src_filter} + +extends = env:at90usb1286_cdc + +################################# +# # +# DUE Architecture # +# # +################################# # # Due (Atmel SAM3X8E ARM Cortex-M3) @@ -190,93 +586,181 @@ src_filter = ${common.default_src_filter} + [env:DUE] platform = atmelsam board = due -src_filter = ${common.default_src_filter} + +src_filter = ${common.default_src_filter} + + [env:DUE_USB] platform = atmelsam +extends = env:DUE board = dueUSB -src_filter = ${common.default_src_filter} + [env:DUE_debug] # Used when WATCHDOG_RESET_MANUAL is enabled platform = atmelsam -board = due -src_filter = ${common.default_src_filter} + +extends = env:DUE build_flags = ${common.build_flags} -funwind-tables -mpoke-function-name +# +# Archim SAM +# +[common_DUE_archim] +platform = atmelsam +extends = env:DUE +board = archim +build_flags = ${common.build_flags} + -DARDUINO_SAM_ARCHIM -DARDUINO_ARCH_SAM -D__SAM3X8E__ -DUSBCON +board_build.variants_dir = buildroot/share/PlatformIO/variants/ +extra_scripts = ${common.extra_scripts} + Marlin/src/HAL/DUE/upload_extra_script.py + +[env:DUE_archim] +platform = ${common_DUE_archim.platform} +extends = common_DUE_archim + +# Used when WATCHDOG_RESET_MANUAL is enabled +[env:DUE_archim_debug] +platform = ${common_DUE_archim.platform} +extends = common_DUE_archim +build_flags = ${common_DUE_archim.build_flags} -funwind-tables -mpoke-function-name + +################################# +# # +# SAMD51 Architecture # +# # +################################# + +# +# Adafruit Grand Central M4 (Atmel SAMD51P20A ARM Cortex-M4) +# +[env:SAMD51_grandcentral_m4] +platform = atmelsam +board = adafruit_grandcentral_m4 +build_flags = ${common.build_flags} -std=gnu++17 +build_unflags = -std=gnu++11 +src_filter = ${common.default_src_filter} + +lib_deps = ${common.lib_deps} + SoftwareSerialM + Adafruit SPIFlash +custom_marlin.SDSUPPORT = SdFat - Adafruit Fork +debug_tool = jlink + +################################# +# # +# LPC176x Architecture # +# # +################################# + # # NXP LPC176x ARM Cortex-M3 # -[env:LPC1768] -platform = https://github.com/p3p/pio-nxplpc-arduino-lpc176x/archive/0.1.2.zip +[common_LPC] +platform = https://github.com/p3p/pio-nxplpc-arduino-lpc176x/archive/0.1.3.zip +platform_packages = framework-arduino-lpc176x@^0.2.5 board = nxp_lpc1768 -build_flags = -DU8G_HAL_LINKS -IMarlin/src/HAL/HAL_LPC1768/include -IMarlin/src/HAL/HAL_LPC1768/u8g ${common.build_flags} -# debug options for backtrace -# -funwind-tables -# -mpoke-function-name lib_ldf_mode = off lib_compat_mode = strict -extra_scripts = Marlin/src/HAL/HAL_LPC1768/upload_extra_script.py -src_filter = ${common.default_src_filter} + -lib_deps = Servo - LiquidCrystal - U8glib-HAL=https://github.com/MarlinFirmware/U8glib-HAL/archive/bugfix.zip - TMCStepper@>=0.6.1,<1.0.0 - Adafruit NeoPixel=https://github.com/p3p/Adafruit_NeoPixel/archive/release.zip - SailfishLCD=https://github.com/mikeshub/SailfishLCD/archive/master.zip +extra_scripts = ${common.extra_scripts} + Marlin/src/HAL/LPC1768/upload_extra_script.py +src_filter = ${common.default_src_filter} + + +lib_deps = ${common.lib_deps} + Servo +custom_marlin.USES_LIQUIDCRYSTAL = LiquidCrystal@1.0.0 +custom_marlin.NEOPIXEL_LED = Adafruit NeoPixel=https://github.com/p3p/Adafruit_NeoPixel/archive/1.5.0.zip +build_flags = ${common.build_flags} -DU8G_HAL_LINKS -IMarlin/src/HAL/LPC1768/include -IMarlin/src/HAL/LPC1768/u8g + # debug options for backtrace + #-funwind-tables + #-mpoke-function-name + +# +# NXP LPC176x ARM Cortex-M3 +# +[env:LPC1768] +platform = ${common_LPC.platform} +extends = common_LPC +board = nxp_lpc1768 [env:LPC1769] -platform = https://github.com/p3p/pio-nxplpc-arduino-lpc176x/archive/0.1.2.zip -board = nxp_lpc1769 -build_flags = -DU8G_HAL_LINKS -IMarlin/src/HAL/HAL_LPC1768/include -IMarlin/src/HAL/HAL_LPC1768/u8g ${common.build_flags} -# debug options for backtrace -# -funwind-tables -# -mpoke-function-name -lib_ldf_mode = off -lib_compat_mode = strict -extra_scripts = Marlin/src/HAL/HAL_LPC1768/upload_extra_script.py -src_filter = ${common.default_src_filter} + -lib_deps = Servo - LiquidCrystal - U8glib-HAL=https://github.com/MarlinFirmware/U8glib-HAL/archive/bugfix.zip - TMCStepper@>=0.6.1,<1.0.0 - Adafruit NeoPixel=https://github.com/p3p/Adafruit_NeoPixel/archive/release.zip - SailfishLCD=https://github.com/mikeshub/SailfishLCD/archive/master.zip +platform = ${common_LPC.platform} +extends = common_LPC +board = nxp_lpc1769 + +################################# +# # +# STM32 Architecture # +# # +################################# + +# +# HAL/STM32 Base Environment values +# +[common_stm32] +platform = ststm32@~8.0 +build_flags = ${common.build_flags} + -std=gnu++14 + -DUSBCON -DUSBD_USE_CDC + -DTIM_IRQ_PRIO=13 +build_unflags = -std=gnu++11 +src_filter = ${common.default_src_filter} + + + +# +# HAL/STM32F1 Common Environment values +# +[common_stm32f1] +platform = ststm32@~6.1 +build_flags = !python Marlin/src/HAL/STM32F1/build_flags.py + ${common.build_flags} -std=gnu++14 -DHAVE_SW_SERIAL +build_unflags = -std=gnu11 -std=gnu++11 +src_filter = ${common.default_src_filter} + +lib_ignore = SPI +lib_deps = ${common.lib_deps} + SoftwareSerialM # # STM32F103RC # [env:STM32F103RC] -platform = ststm32 +platform = ${common_stm32f1.platform} +extends = common_stm32f1 board = genericSTM32F103RC platform_packages = tool-stm32duino -build_flags = !python Marlin/src/HAL/HAL_STM32F1/build_flags.py - ${common.build_flags} -std=gnu++14 -build_unflags = -std=gnu++11 -src_filter = ${common.default_src_filter} + -lib_deps = ${common.lib_deps} - SoftwareSerialM=https://github.com/FYSETC/SoftwareSerialM/archive/master.zip -lib_ignore = Adafruit NeoPixel, SPI monitor_speed = 115200 # -# STM32F103RC_fysetc +# MEEB_3DP (STM32F103RCT6 with 512K) # -[env:STM32F103RC_fysetc] -platform = ststm32 -board = genericSTM32F103RC -#board_build.core = maple +[env:STM32F103RC_meeb] +platform = ${common_stm32f1.platform} +extends = common_stm32f1 +board = MEEB_3DP platform_packages = tool-stm32duino -build_flags = !python Marlin/src/HAL/HAL_STM32F1/build_flags.py - ${common.build_flags} -std=gnu++14 -DDEBUG_LEVEL=0 -DHAVE_SW_SERIAL -build_unflags = -std=gnu++11 -extra_scripts = buildroot/share/PlatformIO/scripts/STM32F103RC_fysetc.py -src_filter = ${common.default_src_filter} + +build_flags = ${common_stm32f1.build_flags} + -DDEBUG_LEVEL=0 + -DSS_TIMER=4 + -DSTM32_FLASH_SIZE=512 + -DHSE_VALUE=12000000U + -DUSE_USB_COMPOSITE + -DVECT_TAB_OFFSET=0x2000 + -DGENERIC_BOOTLOADER +extra_scripts = ${common.extra_scripts} + pre:buildroot/share/PlatformIO/scripts/STM32F1_create_variant.py + buildroot/share/PlatformIO/scripts/STM32F103RC_MEEB_3DP.py lib_deps = ${common.lib_deps} - SoftwareSerialM=https://github.com/FYSETC/SoftwareSerialM/archive/master.zip -lib_ignore = Adafruit NeoPixel, SPI + SoftwareSerialM + USBComposite for STM32F1@0.91 +custom_marlin.NEOPIXEL_LED = Adafruit NeoPixel=https://github.com/ccccmagicboy/Adafruit_NeoPixel#meeb_3dp_use +debug_tool = stlink +upload_protocol = dfu + +# +# STM32F103RC_fysetc +# +[env:STM32F103RC_fysetc] +platform = ${common_stm32f1.platform} +extends = env:STM32F103RC +extra_scripts = ${common.extra_scripts} + buildroot/share/PlatformIO/scripts/STM32F103RC_fysetc.py +build_flags = ${common_stm32f1.build_flags} -DDEBUG_LEVEL=0 lib_ldf_mode = chain debug_tool = stlink upload_protocol = serial @@ -284,392 +768,455 @@ upload_protocol = serial # # BigTree SKR Mini V1.1 / SKR mini E3 / SKR E3 DIP (STM32F103RCT6 ARM Cortex-M3) # -# STM32F103RC_bigtree ............. RCT6 with 256K -# STM32F103RC_bigtree_USB ......... RCT6 with 256K (USB mass storage) -# STM32F103RC_bigtree_512K ........ RCT6 with 512K -# STM32F103RC_bigtree_512K_USB .... RCT6 with 512K (USB mass storage) +# STM32F103RC_btt ............. RCT6 with 256K +# STM32F103RC_btt_USB ......... RCT6 with 256K (USB mass storage) +# STM32F103RC_btt_512K ........ RCT6 with 512K +# STM32F103RC_btt_512K_USB .... RCT6 with 512K (USB mass storage) +# +# WARNING! If you have an SKR Mini v1.1 or an SKR Mini E3 1.0 / 1.2 / 2.0 / DIP +# and experience a printer freeze, re-flash Marlin using the regular (non-512K) +# build option. 256K chips may be re-branded 512K chips, but this means the +# upper 256K is sketchy, and failure is very likely. # -[env:STM32F103RC_bigtree] -platform = ststm32 -board = genericSTM32F103RC -platform_packages = tool-stm32duino -build_flags = !python Marlin/src/HAL/HAL_STM32F1/build_flags.py - ${common.build_flags} -DDEBUG_LEVEL=0 -std=gnu++14 -DHAVE_SW_SERIAL -DSS_TIMER=4 -build_unflags = -std=gnu++11 -extra_scripts = buildroot/share/PlatformIO/scripts/STM32F103RC_SKR_MINI.py -src_filter = ${common.default_src_filter} + -lib_deps = ${common.lib_deps} - SoftwareSerialM=https://github.com/FYSETC/SoftwareSerialM/archive/master.zip -lib_ignore = Adafruit NeoPixel, SPI +[env:STM32F103RC_btt] +platform = ${common_stm32f1.platform} +extends = env:STM32F103RC +extra_scripts = ${common.extra_scripts} + buildroot/share/PlatformIO/scripts/STM32F103RC_SKR_MINI.py +build_flags = ${common_stm32f1.build_flags} + -DDEBUG_LEVEL=0 -DSS_TIMER=4 monitor_speed = 115200 -[env:STM32F103RC_bigtree_USB] -platform = ststm32 -board = genericSTM32F103RC -platform_packages = tool-stm32duino -build_flags = !python Marlin/src/HAL/HAL_STM32F1/build_flags.py - ${common.build_flags} -DDEBUG_LEVEL=0 -std=gnu++14 -DHAVE_SW_SERIAL -DSS_TIMER=4 -DUSE_USB_COMPOSITE -build_unflags = -std=gnu++11 -extra_scripts = buildroot/share/PlatformIO/scripts/STM32F103RC_SKR_MINI.py -src_filter = ${common.default_src_filter} + -lib_deps = ${common.lib_deps} - SoftwareSerialM=https://github.com/FYSETC/SoftwareSerialM/archive/master.zip -lib_ignore = Adafruit NeoPixel, SPI -monitor_speed = 115200 +[env:STM32F103RC_btt_USB] +platform = ${common_stm32f1.platform} +extends = env:STM32F103RC_btt +build_flags = ${env:STM32F103RC_btt.build_flags} -DUSE_USB_COMPOSITE +lib_deps = ${env:STM32F103RC_btt.lib_deps} + USBComposite for STM32F1@0.91 -[env:STM32F103RC_bigtree_512K] -platform = ststm32 -board = genericSTM32F103RC +[env:STM32F103RC_btt_512K] +platform = ${common_stm32f1.platform} +extends = env:STM32F103RC_btt board_upload.maximum_size=524288 -platform_packages = tool-stm32duino -build_flags = !python Marlin/src/HAL/HAL_STM32F1/build_flags.py - ${common.build_flags} -DDEBUG_LEVEL=0 -std=gnu++14 -DHAVE_SW_SERIAL -DSS_TIMER=4 -DSTM32_FLASH_SIZE=512 -build_unflags = -std=gnu++11 -extra_scripts = buildroot/share/PlatformIO/scripts/STM32F103RC_SKR_MINI.py -src_filter = ${common.default_src_filter} + -lib_deps = ${common.lib_deps} - SoftwareSerialM=https://github.com/FYSETC/SoftwareSerialM/archive/master.zip -lib_ignore = Adafruit NeoPixel, SPI -monitor_speed = 115200 +build_flags = ${env:STM32F103RC_btt.build_flags} -DSTM32_FLASH_SIZE=512 -[env:STM32F103RC_bigtree_512K_USB] -platform = ststm32 -board = genericSTM32F103RC -board_upload.maximum_size=524288 -platform_packages = tool-stm32duino -build_flags = !python Marlin/src/HAL/HAL_STM32F1/build_flags.py - ${common.build_flags} -DDEBUG_LEVEL=0 -std=gnu++14 -DHAVE_SW_SERIAL -DSS_TIMER=4 -DSTM32_FLASH_SIZE=512 -DUSE_USB_COMPOSITE -build_unflags = -std=gnu++11 -extra_scripts = buildroot/share/PlatformIO/scripts/STM32F103RC_SKR_MINI.py -src_filter = ${common.default_src_filter} + -lib_deps = ${common.lib_deps} - SoftwareSerialM=https://github.com/FYSETC/SoftwareSerialM/archive/master.zip -lib_ignore = Adafruit NeoPixel, SPI -monitor_speed = 115200 +[env:STM32F103RC_btt_512K_USB] +platform = ${common_stm32f1.platform} +extends = env:STM32F103RC_btt_512K +build_flags = ${env:STM32F103RC_btt_512K.build_flags} -DUSE_USB_COMPOSITE +lib_deps = ${env:STM32F103RC_btt_512K.lib_deps} + USBComposite for STM32F1@0.91 # # STM32F103RE # [env:STM32F103RE] -platform = ststm32 +platform = ${common_stm32f1.platform} +extends = common_stm32f1 board = genericSTM32F103RE platform_packages = tool-stm32duino -build_flags = !python Marlin/src/HAL/HAL_STM32F1/build_flags.py - ${common.build_flags} -std=gnu++14 -build_unflags = -std=gnu++11 -src_filter = ${common.default_src_filter} + -lib_deps = ${common.lib_deps} - SoftwareSerialM=https://github.com/FYSETC/SoftwareSerialM/archive/master.zip -lib_ignore = Adafruit NeoPixel, SPI monitor_speed = 115200 # -# STM32F103RE_bigtree ............. RET6 -# STM32F103RE_bigtree_USB ......... RET6 (USB mass storage) +# STM32F103RE_btt ............. RET6 +# STM32F103RE_btt_USB ......... RET6 (USB mass storage) # -[env:STM32F103RE_bigtree] -platform = ststm32 -board = genericSTM32F103RE -platform_packages = tool-stm32duino -build_flags = !python Marlin/src/HAL/HAL_STM32F1/build_flags.py - ${common.build_flags} -DDEBUG_LEVEL=0 -std=gnu++14 -DHAVE_SW_SERIAL -DSS_TIMER=4 -build_unflags = -std=gnu++11 -extra_scripts = buildroot/share/PlatformIO/scripts/STM32F103RE_SKR_E3_DIP.py -src_filter = ${common.default_src_filter} + -lib_deps = ${common.lib_deps} - SoftwareSerialM=https://github.com/FYSETC/SoftwareSerialM/archive/master.zip -lib_ignore = Adafruit NeoPixel, SPI +[env:STM32F103RE_btt] +platform = ${common_stm32f1.platform} +extends = env:STM32F103RE +extra_scripts = ${common.extra_scripts} + buildroot/share/PlatformIO/scripts/STM32F103RE_SKR_E3_DIP.py +build_flags = ${common_stm32f1.build_flags} -DDEBUG_LEVEL=0 -DSS_TIMER=4 debug_tool = stlink upload_protocol = stlink -monitor_speed = 115200 -[env:STM32F103RE_bigtree_USB] -platform = ststm32 -board = genericSTM32F103RE -platform_packages = tool-stm32duino -build_flags = !python Marlin/src/HAL/HAL_STM32F1/build_flags.py - ${common.build_flags} -DDEBUG_LEVEL=0 -std=gnu++14 -DHAVE_SW_SERIAL -DSS_TIMER=4 -DUSE_USB_COMPOSITE -build_unflags = -std=gnu++11 -extra_scripts = buildroot/share/PlatformIO/scripts/STM32F103RE_SKR_E3_DIP.py -src_filter = ${common.default_src_filter} + -lib_deps = ${common.lib_deps} - SoftwareSerialM=https://github.com/FYSETC/SoftwareSerialM/archive/master.zip -lib_ignore = Adafruit NeoPixel, SPI -debug_tool = stlink -upload_protocol = stlink -monitor_speed = 115200 +[env:STM32F103RE_btt_USB] +platform = ${common_stm32f1.platform} +extends = env:STM32F103RE_btt +build_flags = ${env:STM32F103RE_btt.build_flags} -DUSE_USB_COMPOSITE +lib_deps = ${common_stm32f1.lib_deps} + USBComposite for STM32F1@0.91 # # STM32F4 with STM32GENERIC # [env:STM32F4] -platform = ststm32 +platform = ${common_stm32.platform} board = disco_f407vg build_flags = ${common.build_flags} -DUSE_STM32GENERIC -DSTM32GENERIC -DSTM32F4 -DMENU_USB_SERIAL -DMENU_SERIAL=SerialUSB -DHAL_IWDG_MODULE_ENABLED -lib_ignore = Adafruit NeoPixel, TMCStepper -src_filter = ${common.default_src_filter} + - +src_filter = ${common.default_src_filter} + - # # STM32F7 with STM32GENERIC # [env:STM32F7] -platform = ststm32 +platform = ${common_stm32.platform} board = remram_v1 build_flags = ${common.build_flags} -DUSE_STM32GENERIC -DSTM32GENERIC -DSTM32F7 -DMENU_USB_SERIAL -DMENU_SERIAL=SerialUSB -DHAL_IWDG_MODULE_ENABLED -lib_ignore = Adafruit NeoPixel, TMCStepper -src_filter = ${common.default_src_filter} + - +src_filter = ${common.default_src_filter} + - + +# +# ST NUCLEO-F767ZI Development Board +# This environment is for testing purposes prior to control boards +# being readily available based on STM32F7 MCUs +# +[env:NUCLEO_F767ZI] +platform = ${common_stm32.platform} +extends = common_stm32 +board = nucleo_f767zi +build_flags = ${common_stm32.build_flags} -DTIMER_SERIAL=TIM9 # # ARMED (STM32) # [env:ARMED] -platform = ststm32 +platform = ${common_stm32.platform} +extends = common_stm32 board = armed_v1 -build_flags = ${common.build_flags} - -DUSBCON -DUSBD_VID=0x0483 '-DUSB_MANUFACTURER="Unknown"' '-DUSB_PRODUCT="ARMED_V1"' -DUSBD_USE_CDC - -O2 -ffreestanding -fsigned-char -fno-move-loop-invariants -fno-strict-aliasing -std=gnu11 -std=gnu++11 - -IMarlin/src/HAL/HAL_STM32 -lib_ignore = Adafruit NeoPixel, SoftwareSerial -src_filter = ${common.default_src_filter} + +build_flags = ${common_stm32.build_flags} + -O2 -ffreestanding -fsigned-char -fno-move-loop-invariants -fno-strict-aliasing # # Geeetech GTM32 (STM32F103VET6) # [env:STM32F103VE_GTM32] -platform = ststm32 -board = genericSTM32F103VE -build_flags = !python Marlin/src/HAL/HAL_STM32F1/build_flags.py - ${common.build_flags} -DDEBUG_LEVEL=DEBUG_NONE -std=gnu++14 -MMD -ffunction-sections -fdata-sections -nostdlib - -DBOARD_generic_stm32f103v -DARDUINO_GENERIC_STM32F103V -DARDUINO_ARCH_STM32F1 - -DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG=1 -DVECT_TAB_ADDR=0x8000000 -DERROR_LED_PORT=GPIOE -DERROR_LED_PIN=6 -build_unflags = -std=gnu++11 -src_filter = ${common.default_src_filter} + -lib_ignore = Adafruit NeoPixel, SPI -upload_protocol = serial +platform = ${common_stm32f1.platform} +extends = common_stm32f1 +board = genericSTM32F103VE +build_flags = ${common_stm32f1.build_flags} + -ffunction-sections -fdata-sections -nostdlib -MMD + -DMCU_STM32F103VE -DARDUINO_GENERIC_STM32F103V -DARDUINO_ARCH_STM32F1 -DBOARD_generic_stm32f103v + -DDEBUG_LEVEL=DEBUG_NONE -DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG=1 -DVECT_TAB_ADDR=0x8000000 + -DERROR_LED_PORT=GPIOE -DERROR_LED_PIN=6 +upload_protocol = serial # # Longer 3D board in Alfawise U20 (STM32F103VET6) # [env:STM32F103VE_longer] -platform = ststm32 +platform = ${common_stm32f1.platform} +extends = common_stm32f1 board = genericSTM32F103VE -build_flags = !python Marlin/src/HAL/HAL_STM32F1/build_flags.py - ${common.build_flags} -std=gnu++14 -USERIAL_USB - -DSTM32F1xx -DU20 -DTS_V12 -build_unflags = -std=gnu++11 -DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG=1 -DERROR_LED_PORT=GPIOE -DERROR_LED_PIN=6 -extra_scripts = buildroot/share/PlatformIO/scripts/STM32F103VE_longer.py -src_filter = ${common.default_src_filter} + -lib_ignore = Adafruit NeoPixel, LiquidTWI2, SPI +extra_scripts = ${common.extra_scripts} + buildroot/share/PlatformIO/scripts/STM32F103VE_longer.py +build_flags = ${common_stm32f1.build_flags} + -DMCU_STM32F103VE -DSTM32F1xx -USERIAL_USB -DU20 -DTS_V12 +build_unflags = ${common_stm32f1.build_unflags} + -DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG=1 -DERROR_LED_PORT=GPIOE -DERROR_LED_PIN=6 +lib_ignore = ${common_stm32f1.lib_ignore} # # MKS Robin Mini (STM32F103VET6) # [env:mks_robin_mini] -platform = ststm32 +platform = ${common_stm32f1.platform} +extends = common_stm32f1 board = genericSTM32F103VE -build_flags = !python Marlin/src/HAL/HAL_STM32F1/build_flags.py - ${common.build_flags} -std=gnu++14 -build_unflags = -std=gnu++11 -extra_scripts = buildroot/share/PlatformIO/scripts/mks_robin_mini.py -src_filter = ${common.default_src_filter} + -lib_ignore = Adafruit NeoPixel, SPI +extra_scripts = ${common.extra_scripts} + buildroot/share/PlatformIO/scripts/mks_robin_mini.py +build_flags = ${common_stm32f1.build_flags} + -DMCU_STM32F103VE # # MKS Robin Nano (STM32F103VET6) # -[env:mks_robin_nano] -platform = ststm32 -board = genericSTM32F103VE +[env:mks_robin_nano35] +platform = ${common_stm32f1.platform} +extends = common_stm32f1 +board = genericSTM32F103VE platform_packages = tool-stm32duino -build_flags = !python Marlin/src/HAL/HAL_STM32F1/build_flags.py - ${common.build_flags} -std=gnu++14 -DHAVE_SW_SERIAL -DSS_TIMER=4 -build_unflags = -std=gnu++11 -extra_scripts = buildroot/share/PlatformIO/scripts/mks_robin_nano.py -src_filter = ${common.default_src_filter} + -lib_deps = ${common.lib_deps} - SoftwareSerialM=https://github.com/FYSETC/SoftwareSerialM/archive/master.zip -lib_ignore = Adafruit NeoPixel, SPI +extra_scripts = ${common.extra_scripts} + buildroot/share/PlatformIO/scripts/mks_robin_nano35.py +build_flags = ${common_stm32f1.build_flags} + -DMCU_STM32F103VE -DSS_TIMER=4 +debug_tool = jlink +upload_protocol = jlink # # MKS Robin (STM32F103ZET6) # [env:mks_robin] -platform = ststm32 +platform = ${common_stm32f1.platform} +extends = common_stm32f1 board = genericSTM32F103ZE -build_flags = !python Marlin/src/HAL/HAL_STM32F1/build_flags.py - ${common.build_flags} -std=gnu++14 -DSTM32_XL_DENSITY -build_unflags = -std=gnu++11 -extra_scripts = buildroot/share/PlatformIO/scripts/mks_robin.py -src_filter = ${common.default_src_filter} + -lib_ignore = Adafruit NeoPixel, SPI +extra_scripts = ${common.extra_scripts} + buildroot/share/PlatformIO/scripts/mks_robin.py +build_flags = ${common_stm32f1.build_flags} + -DSS_TIMER=4 -DSTM32_XL_DENSITY + +# MKS Robin (STM32F103ZET6) +# Uses HAL STM32 to support Marlin UI for TFT screen with optional touch panel +# +[env:mks_robin_stm32] +platform = ${common_stm32.platform} +extends = common_stm32 +board = genericSTM32F103ZE +board_build.core = stm32 +board_build.variant = MARLIN_F103Zx +board_build.ldscript = ldscript.ld +board_build.offset = 0x7000 +board_build.firmware = Robin.bin +build_flags = ${common_stm32.build_flags} + -DENABLE_HWSERIAL3 -DTRANSFER_CLOCK_DIV=8 +build_unflags = ${common_stm32.build_unflags} + -DUSBCON -DUSBD_USE_CDC +extra_scripts = ${common.extra_scripts} + pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py + buildroot/share/PlatformIO/scripts/stm32_bootloader.py + buildroot/share/PlatformIO/scripts/mks_encrypt.py +lib_deps = # # MKS Robin Pro (STM32F103ZET6) # [env:mks_robin_pro] -platform = ststm32 -board = genericSTM32F103ZE -extra_scripts = buildroot/share/PlatformIO/scripts/mks_robin_pro.py -build_flags = !python Marlin/src/HAL/HAL_STM32F1/build_flags.py - ${common.build_flags} -std=gnu++14 -DSTM32_XL_DENSITY -build_unflags = -std=gnu++11 -src_filter = ${common.default_src_filter} + -lib_deps = ${common.lib_deps} -lib_ignore = Adafruit NeoPixel, SPI, TMCStepper +platform = ${common_stm32f1.platform} +extends = env:mks_robin +extra_scripts = ${common.extra_scripts} + buildroot/share/PlatformIO/scripts/mks_robin_pro.py + + +# +# TRIGORILLA PRO (STM32F103ZET6) +# +[env:trigorilla_pro] +platform = ${common_stm32f1.platform} +extends = env:mks_robin +extra_scripts = ${common.extra_scripts} + +# +# MKS Robin E3D (STM32F103RCT6) and +# MKS Robin E3 with TMC2209 +# +[env:mks_robin_e3] +platform = ${common_stm32f1.platform} +extends = common_stm32f1 +board = genericSTM32F103RC +platform_packages = tool-stm32duino +extra_scripts = ${common.extra_scripts} + buildroot/share/PlatformIO/scripts/mks_robin_e3.py +build_flags = ${common_stm32f1.build_flags} + -DDEBUG_LEVEL=0 -DSS_TIMER=4 + +# +# MKS Robin E3p (STM32F103VET6) +# - LVGL UI +# +[env:mks_robin_e3p] +platform = ${common_stm32f1.platform} +extends = common_stm32f1 +board = genericSTM32F103VE +platform_packages = tool-stm32duino +extra_scripts = ${common.extra_scripts} + buildroot/share/PlatformIO/scripts/mks_robin_e3p.py +build_flags = ${common_stm32f1.build_flags} + -DMCU_STM32F103VE -DSS_TIMER=4 +debug_tool = jlink +upload_protocol = jlink # # MKS Robin Lite/Lite2 (STM32F103RCT6) # [env:mks_robin_lite] -platform = ststm32 +platform = ${common_stm32f1.platform} +extends = common_stm32f1 board = genericSTM32F103RC -build_flags = !python Marlin/src/HAL/HAL_STM32F1/build_flags.py - ${common.build_flags} -std=gnu++14 -build_unflags = -std=gnu++11 -extra_scripts = buildroot/share/PlatformIO/scripts/mks_robin_lite.py -src_filter = ${common.default_src_filter} + -lib_ignore = Adafruit NeoPixel, SPI +extra_scripts = ${common.extra_scripts} + buildroot/share/PlatformIO/scripts/mks_robin_lite.py + # # MKS ROBIN LITE3 (STM32F103RCT6) # [env:mks_robin_lite3] -platform = ststm32 +platform = ${common_stm32f1.platform} +extends = common_stm32f1 board = genericSTM32F103RC -extra_scripts = buildroot/share/PlatformIO/scripts/mks_robin_lite3.py -build_flags = !python Marlin/src/HAL/HAL_STM32F1/build_flags.py - ${common.build_flags} -std=gnu++14 -build_unflags = -std=gnu++11 -src_filter = ${common.default_src_filter} + -lib_deps = ${common.lib_deps} -lib_ignore = Adafruit NeoPixel, SPI +extra_scripts = ${common.extra_scripts} + buildroot/share/PlatformIO/scripts/mks_robin_lite3.py # # JGAurora A5S A1 (STM32F103ZET6) # [env:jgaurora_a5s_a1] -platform = ststm32 +platform = ${common_stm32f1.platform} +extends = common_stm32f1 board = genericSTM32F103ZE -build_flags = !python Marlin/src/HAL/HAL_STM32F1/build_flags.py - ${common.build_flags} -DSTM32F1xx -std=gnu++14 -DSTM32_XL_DENSITY -build_unflags = -std=gnu++11 -extra_scripts = buildroot/share/PlatformIO/scripts/jgaurora_a5s_a1_with_bootloader.py -src_filter = ${common.default_src_filter} + -lib_ignore = Adafruit NeoPixel, SPI +extra_scripts = ${common.extra_scripts} + buildroot/share/PlatformIO/scripts/jgaurora_a5s_a1_with_bootloader.py +build_flags = ${common_stm32f1.build_flags} + -DSTM32F1xx -DSTM32_XL_DENSITY # # Malyan M200 (STM32F103CB) # [env:STM32F103CB_malyan] -platform = ststm32 -board = malyanM200 -build_flags = !python Marlin/src/HAL/HAL_STM32F1/build_flags.py -DMCU_STM32F103CB -D __STM32F1__=1 -std=c++1y -D MOTHERBOARD="BOARD_MALYAN_M200" -DSERIAL_USB -ffunction-sections -fdata-sections -Wl,--gc-sections - -DDEBUG_LEVEL=0 -D__MARLIN_FIRMWARE__ -src_filter = ${common.default_src_filter} + -lib_ignore = Adafruit NeoPixel, LiquidCrystal, LiquidTWI2, TMCStepper, U8glib-HAL, SPI +platform = ${common_stm32f1.platform} +extends = common_stm32f1 +board = malyanM200 +build_flags = ${common_stm32f1.build_flags} + -DMCU_STM32F103CB -D__STM32F1__=1 -std=c++1y -DSERIAL_USB -ffunction-sections -fdata-sections + -Wl,--gc-sections -DDEBUG_LEVEL=0 -D__MARLIN_FIRMWARE__ +lib_ignore = ${common_stm32f1.lib_ignore} + SoftwareSerialM + +# +# Malyan M200 v2 (STM32F070RB) +# +[env:STM32F070RB_malyan] +platform = ${common_stm32.platform} +extends = common_stm32 +board = malyanM200v2 +build_flags = ${common_stm32.build_flags} -DHAL_PCD_MODULE_ENABLED + -O2 -ffreestanding -fsigned-char -fno-move-loop-invariants -fno-strict-aliasing + -DCUSTOM_STARTUP_FILE + +# +# Malyan M200 v2 (STM32F070CB) +# +[env:STM32F070CB_malyan] +platform = ${common_stm32.platform} +extends = common_stm32 +board = malyanm200_f070cb +build_flags = ${common_stm32.build_flags} + -DHAL_PCD_MODULE_ENABLED -DDISABLE_GENERIC_SERIALUSB -DHAL_UART_MODULE_ENABLED -DCUSTOM_STARTUP_FILE + +# +# Malyan M300 (STM32F070CB) +# +[env:malyan_M300] +platform = ${common_stm32.platform} +extends = common_stm32 +board = malyanm300_f070cb +build_flags = ${common_stm32.build_flags} + -DHAL_PCD_MODULE_ENABLED -DDISABLE_GENERIC_SERIALUSB -DHAL_UART_MODULE_ENABLED +src_filter = ${common.default_src_filter} + # # Chitu boards like Tronxy X5s (STM32F103ZET6) # [env:chitu_f103] -platform = ststm32 -board = genericSTM32F103ZE -build_flags = !python Marlin/src/HAL/HAL_STM32F1/build_flags.py - ${common.build_flags} -DSTM32F1xx -std=gnu++14 -DSTM32_XL_DENSITY -build_unflags = -std=gnu++11 -DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG= -DERROR_LED_PORT=GPIOE -DERROR_LED_PIN=6 -extra_scripts = buildroot/share/PlatformIO/scripts/chitu_crypt.py -src_filter = ${common.default_src_filter} + -lib_ignore = Adafruit NeoPixel +platform = ${common_stm32f1.platform} +extends = common_stm32f1 +board = CHITU_F103 +extra_scripts = pre:buildroot/share/PlatformIO/scripts/common-dependencies.py + pre:buildroot/share/PlatformIO/scripts/STM32F1_create_variant.py + buildroot/share/PlatformIO/scripts/chitu_crypt.py +build_flags = ${common_stm32f1.build_flags} + -DSTM32F1xx -DSTM32_XL_DENSITY +build_unflags = ${common_stm32f1.build_unflags} + -DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG= -DERROR_LED_PORT=GPIOE -DERROR_LED_PIN=6 + +# +# Some Chitu V5 boards have a problem with GPIO init. +# Use this target if G28 or G29 are always failing. +# +[env:chitu_v5_gpio_init] +platform = ${common_stm32f1.platform} +extends = env:chitu_f103 +build_flags = ${env:chitu_f103.build_flags} -DCHITU_V5_Z_MIN_BUGFIX + +# +# Creality (STM32F103RET6) +# +[env:STM32F103RET6_creality] +platform = ${common_stm32f1.platform} +extends = common_stm32f1 +board = genericSTM32F103RE +build_flags = !python Marlin/src/HAL/STM32F1/build_flags.py + ${common.build_flags} -std=gnu++14 -DSTM32_XL_DENSITY -DTEMP_TIMER_CHAN=4 +extra_scripts = ${common.extra_scripts} + pre:buildroot/share/PlatformIO/scripts/random-bin.py + buildroot/share/PlatformIO/scripts/creality.py +lib_ignore = ${common_stm32f1.lib_ignore} +debug_tool = jlink +upload_protocol = jlink +monitor_speed = 115200 # # STM32F401VE # 'STEVAL-3DP001V1' STM32F401VE board - https://www.st.com/en/evaluation-tools/steval-3dp001v1.html # [env:STM32F401VE_STEVAL] -platform = ststm32 +platform = ${common_stm32.platform} +extends = common_stm32 board = STEVAL_STM32F401VE -platform_packages = framework-arduinoststm32@>=3.107,<4 -build_flags = ${common.build_flags} - -DTARGET_STM32F4 -DARDUINO_STEVAL -DSTM32F401xE - -DUSBCON -DUSBD_USE_CDC -DUSBD_VID=0x0483 -DUSB_PRODUCT=\"STEVAL_F401VE\" - -DDISABLE_GENERIC_SERIALUSB - -IMarlin/src/HAL/HAL_STM32 -build_unflags = -std=gnu++11 -extra_scripts = pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py +build_flags = ${common_stm32.build_flags} + -DARDUINO_STEVAL -DSTM32F401xE + -DDISABLE_GENERIC_SERIALUSB -DUSBD_USE_CDC_COMPOSITE -DUSE_USB_FS +extra_scripts = ${common.extra_scripts} + pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py buildroot/share/PlatformIO/scripts/STEVAL__F401XX.py -lib_ignore = Adafruit NeoPixel, TMCStepper, SailfishLCD, SailfishRGB_LED, SlowSoftI2CMaster, SoftwareSerial -src_filter = ${common.default_src_filter} + # # FLYF407ZG # [env:FLYF407ZG] -platform = ststm32 +platform = ${common_stm32.platform} +extends = common_stm32 board = FLYF407ZG -platform_packages = framework-arduinoststm32@>=3.107,<4 -build_flags = ${common.build_flags} - -DSTM32F4 -DUSBCON -DUSBD_USE_CDC -DUSBD_VID=0x0483 -DUSB_PRODUCT=\"STM32F407ZG\" - -DTARGET_STM32F4 -DVECT_TAB_OFFSET=0x8000 - -IMarlin/src/HAL/HAL_STM32 -build_unflags = -std=gnu++11 -extra_scripts = pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py -lib_ignore = Adafruit NeoPixel, TMCStepper, SailfishLCD, SailfishRGB_LED, SlowSoftI2CMaster, SoftwareSerial -src_filter = ${common.default_src_filter} + +build_flags = ${common_stm32.build_flags} + -DVECT_TAB_OFFSET=0x8000 +extra_scripts = ${common.extra_scripts} + pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py +# +# FLY MINI(stm32f103rct6) +# +[env:FLY_MINI] +platform = ${common_stm32f1.platform} +extends = common_stm32f1 +board = genericSTM32F103RC +platform_packages = tool-stm32duino +extra_scripts = ${common.extra_scripts} + buildroot/share/PlatformIO/scripts/fly_mini.py +build_flags = ${common_stm32f1.build_flags} + -DDEBUG_LEVEL=0 -DSS_TIMER=4 # # FYSETC S6 (STM32F446VET6 ARM Cortex-M4) # [env:FYSETC_S6] -platform = ststm32 -board = fysetc_s6 +platform = ${common_stm32.platform} +extends = common_stm32 platform_packages = tool-stm32duino -build_flags = ${common.build_flags} - -DTARGET_STM32F4 -std=gnu++14 +board = marlin_fysetc_s6 +build_flags = ${common_stm32.build_flags} -DVECT_TAB_OFFSET=0x10000 - -DUSBCON -DUSBD_USE_CDC -DHAL_PCD_MODULE_ENABLED -DUSBD_VID=0x0483 '-DUSB_PRODUCT="FYSETC_S6"' -build_unflags = -std=gnu++11 -extra_scripts = pre:buildroot/share/PlatformIO/scripts/fysetc_STM32S6.py -src_filter = ${common.default_src_filter} + -lib_ignore = Arduino-L6470 + -DHAL_PCD_MODULE_ENABLED +extra_scripts = ${common.extra_scripts} + pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py debug_tool = stlink -#upload_protocol = stlink -upload_protocol = serial +upload_protocol = dfu +upload_command = dfu-util -a 0 -s 0x08010000:leave -D "$SOURCE" # # STM32F407VET6 with RAMPS-like shield -# 'Black' STM32F407VET6 board - http://wiki.stm32duino.com/index.php?title=STM32F407 +# 'Black' STM32F407VET6 board - https://wiki.stm32duino.com/index.php?title=STM32F407 # Shield - https://github.com/jmz52/Hardware # [env:STM32F407VE_black] -platform = ststm32 +platform = ${common_stm32.platform} +extends = common_stm32 board = blackSTM32F407VET6 -platform_packages = framework-arduinoststm32@>=3.107,<4 -build_flags = ${common.build_flags} - -DTARGET_STM32F4 -DARDUINO_BLACK_F407VE - -DUSBCON -DUSBD_USE_CDC -DUSBD_VID=0x0483 -DUSB_PRODUCT=\"BLACK_F407VE\" - -IMarlin/src/HAL/HAL_STM32 -build_unflags = -std=gnu++11 -extra_scripts = pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py -lib_ignore = Adafruit NeoPixel, TMCStepper, SailfishLCD, SailfishRGB_LED, SlowSoftI2CMaster, SoftwareSerial -src_filter = ${common.default_src_filter} + +build_flags = ${common_stm32.build_flags} + -DARDUINO_BLACK_F407VE + -DUSBD_USE_CDC_COMPOSITE -DUSE_USB_FS +extra_scripts = ${common.extra_scripts} + pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py # # BigTreeTech SKR Pro (STM32F407ZGT6 ARM Cortex-M4) # [env:BIGTREE_SKR_PRO] -platform = ststm32 +platform = ${common_stm32.platform} +extends = common_stm32 board = BigTree_SKR_Pro -platform_packages = framework-arduinoststm32@>=3.107,<4 -build_flags = ${common.build_flags} - -DUSBCON -DUSBD_USE_CDC -DUSBD_VID=0x0483 -DUSB_PRODUCT=\"STM32F407ZG\" - -DTARGET_STM32F4 -DSTM32F407_5ZX -DVECT_TAB_OFFSET=0x8000 - -IMarlin/src/HAL/HAL_STM32 -build_unflags = -std=gnu++11 -extra_scripts = pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py -lib_ignore = SoftwareSerial, SoftwareSerialM -src_filter = ${common.default_src_filter} + +build_flags = ${common_stm32.build_flags} + -DSTM32F407_5ZX -DVECT_TAB_OFFSET=0x8000 +extra_scripts = ${common.extra_scripts} + pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py #upload_protocol = stlink #upload_command = "$PROJECT_PACKAGES_DIR/tool-stm32duino/stlink/ST-LINK_CLI.exe" -c SWD -P "$BUILD_DIR/firmware.bin" 0x8008000 -Rst -Run debug_tool = stlink @@ -679,67 +1226,92 @@ debug_init_break = # Bigtreetech GTR V1.0 (STM32F407IGT6 ARM Cortex-M4) # [env:BIGTREE_GTR_V1_0] -platform = ststm32@>=5.7.0 -framework = arduino -platform_packages = framework-arduinoststm32@>=3.10700.191028 -board = BigTree_SKR_Pro -extra_scripts = pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py -build_flags = ${common.build_flags} - -DUSBCON -DUSBD_USE_CDC -DUSBD_VID=0x0483 -DUSB_PRODUCT=\"STM32F407IG\" - -DTARGET_STM32F4 -DSTM32F407IX -DVECT_TAB_OFFSET=0x8000 - - -IMarlin/src/HAL/HAL_STM32 -lib_deps = - U8glib-HAL=https://github.com/MarlinFirmware/U8glib-HAL/archive/bugfix.zip - LiquidCrystal - TMCStepper@>=0.5.2,<1.0.0 - Adafruit NeoPixel - LiquidTWI2=https://github.com/lincomatic/LiquidTWI2/archive/master.zip - Arduino-L6470=https://github.com/ameyer/Arduino-L6470/archive/0.7.0.zip -lib_ignore = SoftwareSerial, SoftwareSerialM -src_filter = ${common.default_src_filter} + -monitor_speed = 250000 - -# -# BigTreeTech BTT002 (STM32F407VET6 ARM Cortex-M4) +platform = ${common_stm32.platform} +extends = common_stm32 +board = BigTree_GTR_v1 +extra_scripts = ${common.extra_scripts} + pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py +build_flags = ${common_stm32.build_flags} + -DSTM32F407IX -DVECT_TAB_OFFSET=0x8000 + +# +# BigTreeTech BTT002 V1.0 (STM32F407VGT6 ARM Cortex-M4) # [env:BIGTREE_BTT002] -platform = ststm32@5.6.0 +platform = ${common_stm32.platform} +extends = common_stm32 board = BigTree_Btt002 -platform_packages = framework-arduinoststm32@>=3.107,<4 -build_flags = ${common.build_flags} - -DUSBCON -DUSBD_USE_CDC -DUSBD_VID=0x0483 -DUSB_PRODUCT=\"STM32F407VE\" - -DTARGET_STM32F4 -DSTM32F407_5VX -DVECT_TAB_OFFSET=0x8000 +build_flags = ${common_stm32.build_flags} + -DSTM32F407_5VX -DVECT_TAB_OFFSET=0x8000 -DHAVE_HWSERIAL2 -DHAVE_HWSERIAL3 -DPIN_SERIAL2_RX=PD_6 -DPIN_SERIAL2_TX=PD_5 -build_unflags = -std=gnu++11 -extra_scripts = pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py -lib_ignore = Adafruit NeoPixel, SailfishLCD, SailfishRGB_LED, SlowSoftI2CMaster -src_filter = ${common.default_src_filter} + +extra_scripts = ${common.extra_scripts} + pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py # -# Teensy 3.1 / 3.2 (ARM Cortex-M4) +# Lerdge base +# +[lerdge_common] +platform = ${common_stm32.platform} +extends = common_stm32 +board = LERDGE +board_build.offset = 0x10000 +extra_scripts = ${common.extra_scripts} + pre:buildroot/share/PlatformIO/scripts/copy_marlin_variant_to_framework.py + buildroot/share/PlatformIO/scripts/stm32_bootloader.py + buildroot/share/PlatformIO/scripts/lerdge.py +build_flags = ${common_stm32.build_flags} + -DSTM32F4 -DSTM32F4xx -DTARGET_STM32F4 + -DDISABLE_GENERIC_SERIALUSB -DARDUINO_ARCH_STM32 -DARDUINO_LERDGE + -DTRANSFER_CLOCK_DIV=8 -DHAL_SRAM_MODULE_ENABLED +build_unflags = ${common_stm32.build_unflags} -DUSBCON -DUSBD_USE_CDC -DUSBD_VID=0x0483 + # -[env:teensy31] -platform = teensy -board = teensy31 -lib_deps = ${common.lib_deps} - TMC26XStepper=https://github.com/trinamic/TMC26XStepper/archive/master.zip -lib_ignore = Adafruit NeoPixel -src_filter = ${common.default_src_filter} + +# Lerdge X +# +[env:LERDGEX] +extends = lerdge_common +board_build.firmware = Lerdge_X_firmware_force.bin # -# Teensy 3.5 / 3.6 (ARM Cortex-M4) +# Lerdge S # -[env:teensy35] -platform = teensy -board = teensy35 -lib_deps = ${common.lib_deps} - TMC26XStepper=https://github.com/trinamic/TMC26XStepper/archive/master.zip -lib_ignore = Adafruit NeoPixel -src_filter = ${common.default_src_filter} + +[env:LERDGES] +extends = lerdge_common +board_build.firmware = Lerdge_firmware_force.bin + +# +# Lerdge K +# +[env:LERDGEK] +extends = lerdge_common +board_build.firmware = Lerdge_K_firmware_force.bin +build_flags = ${lerdge_common.build_flags} + -DLERDGEK + +# +# RUMBA32 +# +[env:rumba32] +platform = ${common_stm32.platform} +extends = common_stm32 +build_flags = ${common_stm32.build_flags} + -Os + -DHAL_PCD_MODULE_ENABLED + -DDISABLE_GENERIC_SERIALUSB + -DHAL_UART_MODULE_ENABLED + -DTIMER_SERIAL=TIM9 +board = rumba32_f446ve +upload_protocol = dfu +monitor_speed = 500000 + +################################# +# # +# Other Architectures # +# # +################################# # # Espressif ESP32 @@ -748,90 +1320,53 @@ src_filter = ${common.default_src_filter} + platform = espressif32@1.11.2 board = esp32dev build_flags = ${common.build_flags} -DCORE_DEBUG_LEVEL=0 -lib_deps = ${common.lib_deps} - AsyncTCP=https://github.com/me-no-dev/AsyncTCP/archive/master.zip - ESPAsyncWebServer=https://github.com/me-no-dev/ESPAsyncWebServer/archive/master.zip - ESP3DLib=https://github.com/luc-github/ESP3DLib.git - arduinoWebSockets=https://github.com/Links2004/arduinoWebSockets.git - ESP32SSDP=https://github.com/luc-github/ESP32SSDP.git -lib_ignore = LiquidCrystal, LiquidTWI2, SailfishLCD, SailfishRGB_LED, ESPAsyncTCP -src_filter = ${common.default_src_filter} + +src_filter = ${common.default_src_filter} + upload_speed = 115200 #upload_port = marlinesp.local #board_build.flash_mode = qio # -# Native -# No supported Arduino libraries, base Marlin only +# Teensy 3.1 / 3.2 (ARM Cortex-M4) # -[env:linux_native] -platform = native -framework = -build_flags = -D__PLAT_LINUX__ -std=gnu++17 -ggdb -g -lrt -lpthread -D__MARLIN_FIRMWARE__ -Wno-expansion-to-defined -src_build_flags = -Wall -IMarlin/src/HAL/HAL_LINUX/include -build_unflags = -Wall -lib_ldf_mode = off -lib_deps = -extra_scripts = -src_filter = ${common.default_src_filter} + +[env:teensy31] +platform = teensy +board = teensy31 +src_filter = ${common.default_src_filter} + # -# Adafruit Grand Central M4 (Atmel SAMD51P20A ARM Cortex-M4) +# Teensy 3.5 / 3.6 (ARM Cortex-M4) # -[env:SAMD51_grandcentral_m4] -platform = atmelsam -board = adafruit_grandcentral_m4 -build_flags = ${common.build_flags} -std=gnu++17 -extra_scripts = ${common.extra_scripts} -build_unflags = -std=gnu++11 -src_filter = ${common.default_src_filter} + -debug_tool = jlink +[env:teensy35] +platform = teensy +board = teensy35 +src_filter = ${common.default_src_filter} + + +[env:teensy36] +platform = teensy +board = teensy36 +src_filter = ${common.default_src_filter} + # -# RUMBA32 +# Teensy 4.0 / 4.1 (ARM Cortex-M7) # -[env:rumba32_f446ve] -platform = ststm32 -board = rumba32_f446ve -build_flags = ${common.build_flags} - -DSTM32F4xx - -DARDUINO_RUMBA32_F446VE - -DARDUINO_ARCH_STM32 - "-DBOARD_NAME=\"RUMBA32_F446VE\"" - -DSTM32F446xx - -DUSBCON - -DUSBD_VID=0x0483 - "-DUSB_MANUFACTURER=\"Unknown\"" - "-DUSB_PRODUCT=\"RUMBA32_F446VE\"" - -DHAL_PCD_MODULE_ENABLED - -DUSBD_USE_CDC - -DDISABLE_GENERIC_SERIALUSB - -DHAL_UART_MODULE_ENABLED - -Os -lib_ignore = Adafruit NeoPixel -src_filter = ${common.default_src_filter} + -monitor_speed = 500000 -upload_protocol = dfu +[env:teensy41] +platform = teensy +board = teensy41 +src_filter = ${common.default_src_filter} + # -# MKS RUMBA32 (adds TMC2208/2209 UART interface and AUX-1) +# Native +# No supported Arduino libraries, base Marlin only # -[env:rumba32_mks] -platform = ststm32 -board = rumba32_f446ve -build_flags = ${common.build_flags} - -DSTM32F4xx -DARDUINO_RUMBA32_F446VE -DARDUINO_ARCH_STM32 "-DBOARD_NAME=\"RUMBA32_F446VE\"" - -DSTM32F446xx -DUSBCON -DUSBD_VID=0x8000 - "-DUSB_MANUFACTURER=\"Unknown\"" - "-DUSB_PRODUCT=\"RUMBA32_F446VE\"" - -DHAL_PCD_MODULE_ENABLED - -DUSBD_USE_CDC - -DDISABLE_GENERIC_SERIALUSB - -DHAL_UART_MODULE_ENABLED - -Os -lib_ignore = Adafruit NeoPixel -src_filter = ${common.default_src_filter} + + - -upload_protocol = dfu +[env:linux_native] +platform = native +framework = +build_flags = -D__PLAT_LINUX__ -std=gnu++17 -ggdb -g -lrt -lpthread -D__MARLIN_FIRMWARE__ -Wno-expansion-to-defined +src_build_flags = -Wall -IMarlin/src/HAL/LINUX/include +build_unflags = -Wall +lib_ldf_mode = off +lib_deps = +src_filter = ${common.default_src_filter} + # # Just print the dependency tree @@ -840,6 +1375,4 @@ upload_protocol = dfu platform = atmelavr board = megaatmega2560 build_flags = -c -H -std=gnu++11 -Wall -Os -D__MARLIN_FIRMWARE__ -lib_deps = ${common.lib_deps} - TMC26XStepper=https://github.com/trinamic/TMC26XStepper/archive/master.zip -src_filter = + +src_filter = +

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